From c1f8078921b980299192852ce2876864459b9ed1 Mon Sep 17 00:00:00 2001 From: lzh Date: Thu, 9 Feb 2023 17:43:05 +0800 Subject: [PATCH] release version update --- .gitattributes | 3 + Kconfig | 6 +- README.md | 70 +- docs/ChangeLog.md | 154 +- drivers/Kconfig | 38 +- drivers/adc/fadc_os.c | 108 +- drivers/adc/fadc_os.h | 44 +- drivers/can/fcan_os.c | 59 +- drivers/can/fcan_os.h | 42 +- drivers/dma/fddma/fddma_os.c | 110 +- drivers/dma/fddma/fddma_os.h | 43 +- drivers/dma/fgdma/fgdma_os.c | 116 +- drivers/dma/fgdma/fgdma_os.h | 43 +- drivers/drivers.mk | 20 + drivers/eth/gmac/fgmac_os.c | 641 + .../eth/gmac/fgmac_os.h | 130 +- drivers/eth/xmac/ft_os_xmac.c | 1341 -- drivers/eth/xmac/fxmac_os.c | 1383 ++ drivers/eth/xmac/{ft_os_xmac.h => fxmac_os.h} | 94 +- drivers/gpio/fgpio/fgpio_os.c | 132 +- drivers/gpio/fgpio/fgpio_os.h | 41 +- drivers/i2c/fi2c_os.c | 384 + drivers/i2c/fi2c_os.h | 119 + drivers/mmc/fsdio/fsdio_os.c | 633 - drivers/mmc/fsdio/fsdio_os.h | 115 - drivers/pwm/fpwm_os.c | 61 +- drivers/pwm/fpwm_os.h | 41 +- drivers/qspi/fqspi_os.c | 91 +- drivers/qspi/fqspi_os.h | 45 +- drivers/serial/fpl011/fpl011_os.c | 58 +- drivers/serial/fpl011/fpl011_os.h | 43 +- drivers/spi/fspim/fspim_os.c | 114 +- drivers/spi/fspim/fspim_os.h | 43 +- drivers/timer/ftimer_tacho_os.c | 486 + .../timer/ftimer_tacho_os.h | 155 +- drivers/wdt/fwdt_os.c | 67 +- drivers/wdt/fwdt_os.h | 40 +- .../core0/configs/d2000_aarch32_eg_configs | 123 +- .../core0/configs/d2000_aarch64_eg_configs | 123 +- .../core0/configs/ft2004_aarch32_eg_configs | 123 +- .../core0/configs/ft2004_aarch64_eg_configs | 123 +- example/amp/openamp/core0/main.c | 39 +- example/amp/openamp/core0/rpmsg-echo_os.c | 219 +- example/amp/openamp/core0/sdkconfig | 123 +- example/amp/openamp/core0/sdkconfig.h | 106 +- .../core1/configs/d2000_aarch32_eg_configs | 122 +- .../core1/configs/d2000_aarch64_eg_configs | 122 +- .../core1/configs/ft2004_aarch32_eg_configs | 122 +- .../core1/configs/ft2004_aarch64_eg_configs | 122 +- example/amp/openamp/core1/main.c | 34 +- example/amp/openamp/core1/rpmsg-ping_os.c | 349 +- example/amp/openamp/core1/sdkconfig | 122 +- example/amp/openamp/core1/sdkconfig.h | 106 +- .../configs/d2000_aarch32_eg_configs | 64 +- .../configs/d2000_aarch64_eg_configs | 64 +- .../configs/e2000d_aarch32_eg_configs | 64 +- .../configs/e2000d_aarch64_eg_configs | 64 +- .../configs/e2000q_aarch32_eg_configs | 64 +- .../configs/e2000q_aarch64_eg_configs | 64 +- .../configs/ft2004_aarch32_eg_configs | 64 +- .../configs/ft2004_aarch64_eg_configs | 64 +- .../eventgroup/inc/feature_eventgroup.h | 40 +- example/freertos_feature/eventgroup/main.c | 37 +- example/freertos_feature/eventgroup/sdkconfig | 64 +- .../freertos_feature/eventgroup/sdkconfig.h | 56 +- .../eventgroup/src/eventgroup_cmd.c | 55 +- .../eventgroup/src/management.c | 308 +- .../eventgroup/src/synchronization.c | 190 +- .../configs/d2000_aarch32_eg_configs | 64 +- .../configs/d2000_aarch64_eg_configs | 64 +- .../configs/e2000d_aarch32_eg_configs | 74 +- .../configs/e2000d_aarch64_eg_configs | 74 +- .../configs/e2000q_aarch32_eg_configs | 64 +- .../configs/e2000q_aarch64_eg_configs | 64 +- .../configs/ft2004_aarch32_eg_configs | 64 +- .../configs/ft2004_aarch64_eg_configs | 64 +- .../interrupt/inc/feature_interrupt.h | 36 +- example/freertos_feature/interrupt/main.c | 37 +- example/freertos_feature/interrupt/sdkconfig | 64 +- .../freertos_feature/interrupt/sdkconfig.h | 56 +- .../interrupt/src/binary_semaphore.c | 82 +- .../interrupt/src/counting_semaphore.c | 81 +- .../interrupt/src/interrupt_cmd.c | 77 +- .../interrupt/src/queue_from_interrupt.c | 126 +- example/freertos_feature/queue/README.md | 4 +- .../queue/configs/d2000_aarch32_eg_configs | 64 +- .../queue/configs/d2000_aarch64_eg_configs | 64 +- .../queue/configs/e2000d_aarch32_eg_configs | 64 +- .../queue/configs/e2000d_aarch64_eg_configs | 64 +- .../queue/configs/e2000q_aarch32_eg_configs | 64 +- .../queue/configs/e2000q_aarch64_eg_configs | 64 +- .../queue/configs/ft2004_aarch32_eg_configs | 64 +- .../queue/configs/ft2004_aarch64_eg_configs | 64 +- .../queue/inc/feature_queue.h | 40 +- example/freertos_feature/queue/main.c | 37 +- example/freertos_feature/queue/sdkconfig | 64 +- example/freertos_feature/queue/sdkconfig.h | 56 +- .../freertos_feature/queue/src/queue_cmd.c | 77 +- .../queue/src/queue_int_send_recv.c | 218 +- .../freertos_feature/queue/src/queue_set.c | 186 +- .../queue/src/queue_struct_send_recv.c | 225 +- .../resource/configs/d2000_aarch32_eg_configs | 64 +- .../resource/configs/d2000_aarch64_eg_configs | 64 +- .../configs/e2000d_aarch32_eg_configs | 64 +- .../configs/e2000d_aarch64_eg_configs | 64 +- .../configs/e2000q_aarch32_eg_configs | 64 +- .../configs/e2000q_aarch64_eg_configs | 64 +- .../configs/ft2004_aarch32_eg_configs | 64 +- .../configs/ft2004_aarch64_eg_configs | 64 +- .../resource/inc/feature_resource.h | 37 +- example/freertos_feature/resource/main.c | 41 +- example/freertos_feature/resource/sdkconfig | 64 +- example/freertos_feature/resource/sdkconfig.h | 56 +- .../resource/src/gatekeeper.c | 94 +- example/freertos_feature/resource/src/mutex.c | 52 +- .../resource/src/resource_cmd.c | 65 +- .../configs/d2000_aarch32_eg_configs | 64 +- .../configs/d2000_aarch64_eg_configs | 64 +- .../configs/e2000d_aarch32_eg_configs | 64 +- .../configs/e2000d_aarch64_eg_configs | 64 +- .../configs/e2000q_aarch32_eg_configs | 64 +- .../configs/e2000q_aarch64_eg_configs | 64 +- .../configs/ft2004_aarch32_eg_configs | 64 +- .../configs/ft2004_aarch64_eg_configs | 64 +- .../inc/feature_software_timer.h | 40 +- .../freertos_feature/software_timer/main.c | 41 +- .../freertos_feature/software_timer/sdkconfig | 64 +- .../software_timer/sdkconfig.h | 56 +- .../software_timer/src/create_start.c | 160 +- .../software_timer/src/software_timer_cmd.c | 63 +- .../software_timer/src/timer_id_and_reset.c | 210 +- .../task/configs/d2000_aarch32_eg_configs | 64 +- .../task/configs/d2000_aarch64_eg_configs | 64 +- .../task/configs/e2000d_aarch32_eg_configs | 64 +- .../task/configs/e2000d_aarch64_eg_configs | 64 +- .../task/configs/e2000q_aarch32_eg_configs | 66 +- .../task/configs/e2000q_aarch64_eg_configs | 66 +- .../task/configs/ft2004_aarch32_eg_configs | 64 +- .../task/configs/ft2004_aarch64_eg_configs | 64 +- .../freertos_feature/task/inc/feature_task.h | 40 +- example/freertos_feature/task/main.c | 41 +- example/freertos_feature/task/sdkconfig | 66 +- example/freertos_feature/task/sdkconfig.h | 58 +- .../freertos_feature/task/src/block_state.c | 66 +- .../task/src/change_priority.c | 146 +- .../task/src/creating_tasks.c | 100 +- .../task/src/idle_task_hook.c | 64 +- .../freertos_feature/task/src/priority_task.c | 60 +- example/freertos_feature/task/src/task_cmd.c | 159 +- .../task_combining_blocking_non_blocking.c | 94 +- .../task/src/task_delay_until.c | 64 +- .../task/src/using_task_parameter.c | 82 +- .../configs/d2000_aarch32_eg_configs | 64 +- .../configs/d2000_aarch64_eg_configs | 64 +- .../configs/e2000d_aarch32_eg_configs | 64 +- .../configs/e2000d_aarch64_eg_configs | 64 +- .../configs/e2000q_aarch32_eg_configs | 64 +- .../configs/e2000q_aarch64_eg_configs | 64 +- .../configs/ft2004_aarch32_eg_configs | 64 +- .../configs/ft2004_aarch64_eg_configs | 64 +- .../task_notify/inc/feature_task_notify.h | 40 +- example/freertos_feature/task_notify/main.c | 41 +- .../freertos_feature/task_notify/sdkconfig | 64 +- .../freertos_feature/task_notify/sdkconfig.h | 56 +- .../task_notify/src/notify_take_false.c | 228 +- .../task_notify/src/notify_take_true.c | 230 +- .../task_notify/src/task_notify_cmd.c | 63 +- example/makefile | 18 - example/network/gmac_lwip_test/Kconfig | 41 - .../configs/d2000_aarch32_eg_configs | 411 - .../configs/d2000_aarch64_eg_configs | 407 - .../configs/ft2004_aarch32_eg_configs | 411 - .../configs/ft2004_aarch64_eg_configs | 407 - .../pic/gmac_dhcp_menuconfig.png | Bin 16955 -> 0 bytes .../pic/gmac_ipv4_menuconfig.png | Bin 16316 -> 0 bytes .../pic/gmac_ipv6_menuconfig.png | Bin 16610 -> 0 bytes .../network/gmac_lwip_test/pic/gmac_probe.png | Bin 19492 -> 0 bytes .../gmac_lwip_test/pic/gmac_probe_dhcp0.png | Bin 28043 -> 0 bytes .../gmac_lwip_test/pic/gmac_probe_dhcp1.png | Bin 5149 -> 0 bytes .../gmac_lwip_test/pic/gmac_probe_ipv6.png | Bin 20252 -> 0 bytes .../network/gmac_lwip_test/pic/ping_ipv6.png | Bin 29639 -> 0 bytes example/network/gmac_lwip_test/sdkconfig | 407 - .../network/gmac_lwip_test/src/lwip_test.c | 293 - .../{xmac_lwip_test => lwip_startup}/Kconfig | 6 +- .../README.md | 139 +- .../configs/d2000_aarch32_eg_configs | 505 + .../configs/d2000_aarch64_eg_configs | 501 + .../configs/e2000d_aarch32_eg_configs | 274 +- .../configs/e2000d_aarch64_eg_configs | 274 +- .../configs/e2000q_aarch32_eg_configs | 274 +- .../configs/e2000q_aarch64_eg_configs | 274 +- .../configs/ft2004_aarch32_eg_configs | 505 + .../configs/ft2004_aarch64_eg_configs | 501 + .../{xmac_lwip_test => lwip_startup}/main.c | 38 +- .../{xmac_lwip_test => lwip_startup}/makefile | 0 .../network/lwip_startup/pic/dhcp_test.png | Bin 0 -> 160713 bytes ...o\346\235\277\345\205\250\350\262\214.jpg" | Bin .../network/lwip_startup/pic/ipv4_test.png | Bin 0 -> 299337 bytes .../network/lwip_startup/pic/ipv6_test.png | Bin 0 -> 254646 bytes .../network/lwip_startup/pic/lwip_probe.png | Bin 0 -> 147084 bytes .../lwip_startup/pic/network_demo_config.png | Bin 0 -> 21801 bytes .../pic/ping.png | Bin .../pic/ping_ipv6.png | Bin .../pic/select_demo.png | Bin .../pic/xmac_dhcp_menuconfig.png | Bin .../pic/xmac_ipv4_menuconfig.png | Bin .../pic/xmac_ipv6_menuconfig.png | Bin .../sdkconfig | 274 +- .../sdkconfig.h | 250 +- .../src/Kconfig | 46 +- .../lwip_startup/src/e2000_gpio_config.c | 159 + example/network/lwip_startup/src/lwip_test.c | 310 + example/network/sockets/udp_multicast/Kconfig | 3 +- .../network/sockets/udp_multicast/README.md | 67 +- .../configs/d2000_aarch32_eg_configs | 514 + .../configs/d2000_aarch64_eg_configs | 510 + .../configs/e2000d_aarch32_eg_configs | 263 +- .../configs/e2000d_aarch64_eg_configs | 251 +- .../configs/e2000q_aarch32_eg_configs | 258 +- .../configs/e2000q_aarch64_eg_configs | 251 +- .../configs/ft2004_aarch32_eg_configs | 514 + .../configs/ft2004_aarch64_eg_configs | 510 + example/network/sockets/udp_multicast/main.c | 39 +- .../udp_multicast/pic/ipv4_ipv6_config.png | Bin 0 -> 34094 bytes .../sockets/udp_multicast/pic/lwip_probe.png | Bin 0 -> 147084 bytes .../sockets/udp_multicast/pic/xmac_probe.png | Bin 47686 -> 0 bytes .../udp_multicast/pic/xmac_probe_ipv4.png | Bin 27042 -> 0 bytes .../udp_multicast/pic/xmac_probe_ipv4_2.png | Bin 37810 -> 0 bytes .../udp_multicast/pic/xmac_probe_ipv6.png | Bin 38370 -> 0 bytes .../udp_multicast/pic/xmac_probe_ipv6_2.png | Bin 82644 -> 0 bytes .../network/sockets/udp_multicast/sdkconfig | 251 +- .../network/sockets/udp_multicast/sdkconfig.h | 227 +- .../network/sockets/udp_multicast/src/Kconfig | 24 +- .../sockets/udp_multicast/src/e2000_board.c | 160 + .../sockets/udp_multicast/src/lwip_test.c | 466 +- .../sockets/udp_multicast/src/multicast.c | 352 +- .../test/multicast_server_ipv4.c | 67 +- .../test/multicast_server_ipv6.c | 53 +- example/network/xmac_lwip_test/pic/ping.png | Bin 29540 -> 0 bytes .../network/xmac_lwip_test/pic/xmac_probe.png | Bin 47686 -> 0 bytes .../xmac_lwip_test/pic/xmac_probe_dhcp0.png | Bin 42854 -> 0 bytes .../xmac_lwip_test/pic/xmac_probe_dhcp1.png | Bin 29815 -> 0 bytes .../xmac_lwip_test/pic/xmac_probe_ipv4.png | Bin 27042 -> 0 bytes .../xmac_lwip_test/pic/xmac_probe_ipv6.png | Bin 154990 -> 0 bytes .../network/xmac_lwip_test/src/lwip_test.c | 416 - .../adc/configs/e2000d_aarch32_eg_configs | 64 +- .../adc/configs/e2000d_aarch64_eg_configs | 64 +- example/peripheral/adc/inc/adc_example.h | 41 +- example/peripheral/adc/main.c | 45 +- example/peripheral/adc/sdkconfig | 64 +- example/peripheral/adc/sdkconfig.h | 56 +- example/peripheral/adc/src/adc_example.c | 310 +- .../can/configs/d2000_aarch32_eg_configs | 64 +- .../can/configs/d2000_aarch64_eg_configs | 64 +- .../can/configs/e2000d_aarch32_eg_configs | 64 +- .../can/configs/e2000d_aarch64_eg_configs | 64 +- .../can/configs/e2000q_aarch32_eg_configs | 64 +- .../can/configs/e2000q_aarch64_eg_configs | 64 +- .../can/configs/ft2004_aarch32_eg_configs | 64 +- .../can/configs/ft2004_aarch64_eg_configs | 64 +- example/peripheral/can/inc/can_example.h | 41 +- example/peripheral/can/main.c | 45 +- example/peripheral/can/sdkconfig | 64 +- example/peripheral/can/sdkconfig.h | 56 +- example/peripheral/can/src/can_example.c | 723 +- .../ddma/configs/e2000d_aarch32_eg_configs | 64 +- .../ddma/configs/e2000d_aarch64_eg_configs | 64 +- .../ddma/configs/e2000q_aarch32_eg_configs | 64 +- .../ddma/configs/e2000q_aarch64_eg_configs | 64 +- .../dma/ddma/inc/ddma_spi_loopback.h | 33 +- example/peripheral/dma/ddma/main.c | 41 +- example/peripheral/dma/ddma/sdkconfig | 70 +- example/peripheral/dma/ddma/sdkconfig.h | 62 +- example/peripheral/dma/ddma/src/cmd_ddma.c | 27 +- .../dma/ddma/src/ddma_spi_loopback.c | 101 +- .../gdma/configs/e2000d_aarch32_eg_configs | 64 +- .../gdma/configs/e2000d_aarch64_eg_configs | 64 +- .../gdma/configs/e2000q_aarch32_eg_configs | 64 +- .../gdma/configs/e2000q_aarch64_eg_configs | 64 +- example/peripheral/dma/gdma/inc/gdma_memcpy.h | 31 +- example/peripheral/dma/gdma/main.c | 36 +- example/peripheral/dma/gdma/sdkconfig | 70 +- example/peripheral/dma/gdma/sdkconfig.h | 62 +- example/peripheral/dma/gdma/src/cmd_gdma.c | 27 +- example/peripheral/dma/gdma/src/gdma_memcpy.c | 123 +- .../gpio/configs/e2000d_aarch32_eg_configs | 64 +- .../gpio/configs/e2000d_aarch64_eg_configs | 64 +- .../gpio/configs/e2000q_aarch32_eg_configs | 64 +- .../gpio/configs/e2000q_aarch64_eg_configs | 64 +- example/peripheral/gpio/inc/gpio_io_irq.h | 31 +- example/peripheral/gpio/main.c | 41 +- example/peripheral/gpio/sdkconfig | 70 +- example/peripheral/gpio/sdkconfig.h | 62 +- example/peripheral/gpio/src/cmd_gpio.c | 61 +- example/peripheral/gpio/src/gpio_io_irq.c | 151 +- .../sata_fatfs => peripheral/i2c}/Kconfig | 0 .../i2c}/README.md | 146 +- .../i2c}/configs/d2000_aarch32_eg_configs | 103 +- .../i2c}/configs/d2000_aarch64_eg_configs | 103 +- .../i2c}/configs/e2000d_aarch32_eg_configs | 100 +- .../i2c}/configs/e2000d_aarch64_eg_configs | 100 +- .../i2c}/configs/e2000q_aarch32_eg_configs | 100 +- .../i2c}/configs/e2000q_aarch64_eg_configs | 100 +- example/peripheral/i2c/figs/E2000_1339.png | Bin 0 -> 475606 bytes example/peripheral/i2c/figs/E2000_rtc.png | Bin 0 -> 10924 bytes example/peripheral/i2c/figs/board.png | Bin 0 -> 573070 bytes example/peripheral/i2c/figs/d2000_eeprom.png | Bin 0 -> 14941 bytes .../i2c/figs/d2000_master_slave.png | Bin 0 -> 32794 bytes example/peripheral/i2c/inc/i2c_example.h | 52 + .../sata_fatfs => peripheral/i2c}/main.c | 59 +- .../sata_fatfs => peripheral/i2c}/makefile | 4 +- .../sata_fatfs => peripheral/i2c}/sdkconfig | 100 +- .../sata_fatfs => peripheral/i2c}/sdkconfig.h | 88 +- example/peripheral/i2c/src/i2c_example.c | 578 + .../pwm/configs/e2000d_aarch32_eg_configs | 64 +- .../pwm/configs/e2000d_aarch64_eg_configs | 64 +- .../pwm/configs/e2000q_aarch32_eg_configs | 64 +- .../pwm/configs/e2000q_aarch64_eg_configs | 64 +- example/peripheral/pwm/inc/pwm_example.h | 41 +- example/peripheral/pwm/main.c | 45 +- example/peripheral/pwm/sdkconfig | 64 +- example/peripheral/pwm/sdkconfig.h | 56 +- example/peripheral/pwm/src/pwm_example.c | 319 +- .../qspi/configs/d2000_aarch32_eg_configs | 64 +- .../qspi/configs/d2000_aarch64_eg_configs | 64 +- .../qspi/configs/e2000d_aarch32_eg_configs | 64 +- .../qspi/configs/e2000d_aarch64_eg_configs | 64 +- .../qspi/configs/e2000q_aarch32_eg_configs | 64 +- .../qspi/configs/e2000q_aarch64_eg_configs | 64 +- .../qspi/configs/ft2004_aarch32_eg_configs | 64 +- .../qspi/configs/ft2004_aarch64_eg_configs | 64 +- example/peripheral/qspi/inc/qspi_example.h | 40 +- example/peripheral/qspi/main.c | 45 +- example/peripheral/qspi/sdkconfig | 64 +- example/peripheral/qspi/sdkconfig.h | 56 +- example/peripheral/qspi/src/qspi_example.c | 402 +- example/peripheral/sdio/README.md | 4 - .../sdio/configs/e2000d_aarch32_eg_configs | 68 +- .../sdio/configs/e2000d_aarch64_eg_configs | 72 +- .../sdio/configs/e2000q_aarch32_eg_configs | 68 +- .../sdio/configs/e2000q_aarch64_eg_configs | 72 +- example/peripheral/sdio/inc/sd_read_write.h | 31 +- example/peripheral/sdio/main.c | 50 +- example/peripheral/sdio/sdkconfig | 74 +- example/peripheral/sdio/sdkconfig.h | 66 +- example/peripheral/sdio/src/cmd_sd.c | 49 +- example/peripheral/sdio/src/sd_read_write.c | 286 +- example/peripheral/spi/README.md | 2 +- .../spi/configs/e2000d_aarch32_eg_configs | 66 +- .../spi/configs/e2000d_aarch64_eg_configs | 64 +- example/peripheral/spi/figs/wr_rd.png | Bin 20837 -> 19290 bytes example/peripheral/spi/inc/sfud_read_write.h | 31 +- example/peripheral/spi/main.c | 47 +- example/peripheral/spi/sdkconfig | 64 +- example/peripheral/spi/sdkconfig.h | 56 +- example/peripheral/spi/src/cmd_sf.c | 55 +- example/peripheral/spi/src/sfud_read_write.c | 135 +- .../timer_tacho}/Kconfig | 0 .../timer_tacho}/README.md | 102 +- .../configs/e2000d_aarch32_eg_configs | 112 +- .../configs/e2000d_aarch64_eg_configs | 261 + .../configs/e2000q_aarch32_eg_configs} | 114 +- .../configs/e2000q_aarch64_eg_configs | 261 + .../peripheral/timer_tacho/figs/tacho_hdw.png | Bin 0 -> 1144514 bytes .../timer_tacho/figs/timer_capture.png | Bin 0 -> 39549 bytes .../timer_tacho/figs/timer_tacho.png | Bin 0 -> 43535 bytes .../timer_tacho/inc/timer_tacho_example.h | 48 + .../timer_tacho}/main.c | 61 +- .../timer_tacho}/makefile | 4 +- example/peripheral/timer_tacho/sdkconfig | 261 + .../timer_tacho}/sdkconfig.h | 107 +- .../timer_tacho/src/timer_tacho_example.c | 387 + .../configs/e2000d_aarch32_eg_configs | 64 +- .../configs/e2000d_aarch64_eg_configs | 64 +- .../configs/e2000s_aarch32_eg_configs | 64 +- .../configs/e2000s_aarch64_eg_configs | 64 +- .../usb/cherryusb_host/inc/usb_host.h | 31 +- example/peripheral/usb/cherryusb_host/main.c | 41 +- .../peripheral/usb/cherryusb_host/sdkconfig | 64 +- .../peripheral/usb/cherryusb_host/sdkconfig.h | 56 +- .../usb/cherryusb_host/src/cmd_usb.c | 26 +- .../usb/cherryusb_host/src/usb_disk.c | 63 +- .../usb/cherryusb_host/src/usb_host.c | 62 +- .../usb/cherryusb_host/src/usb_input.c | 62 +- .../wdt/configs/d2000_aarch32_eg_configs | 64 +- .../wdt/configs/d2000_aarch64_eg_configs | 64 +- .../wdt/configs/e2000d_aarch32_eg_configs | 64 +- .../wdt/configs/e2000d_aarch64_eg_configs | 64 +- .../wdt/configs/e2000q_aarch32_eg_configs | 64 +- .../wdt/configs/e2000q_aarch64_eg_configs | 64 +- .../wdt/configs/ft2004_aarch32_eg_configs | 64 +- .../wdt/configs/ft2004_aarch64_eg_configs | 64 +- example/peripheral/wdt/inc/wdt_example.h | 41 +- example/peripheral/wdt/main.c | 45 +- example/peripheral/wdt/sdkconfig | 72 +- example/peripheral/wdt/sdkconfig.h | 64 +- example/peripheral/wdt/src/wdt_example.c | 452 +- example/storage/fatfs/Kconfig | 25 + example/storage/fatfs/READEME.md | 118 + .../fatfs/configs/e2000d_aarch32_eg_configs | 327 + .../configs/e2000d_aarch64_eg_configs | 171 +- .../fatfs/configs/e2000q_aarch32_eg_configs | 327 + .../fatfs/configs/e2000q_aarch64_eg_configs | 323 + example/storage/fatfs/figures/config.png | Bin 0 -> 12944 bytes example/storage/fatfs/figures/hardware.png | Bin 0 -> 702896 bytes example/storage/fatfs/figures/test_1.png | Bin 0 -> 43656 bytes example/storage/fatfs/figures/test_2.png | Bin 0 -> 38075 bytes example/storage/fatfs/figures/test_3.png | Bin 0 -> 27642 bytes example/storage/fatfs/figures/test_4.png | Bin 0 -> 26619 bytes example/storage/fatfs/figures/test_5.png | Bin 0 -> 423064 bytes example/storage/fatfs/figures/test_item.png | Bin 0 -> 6186 bytes .../inc/fatfs_examples.h} | 62 +- example/storage/{spim_spiffs => fatfs}/main.c | 59 +- .../gmac_lwip_test => storage/fatfs}/makefile | 8 +- example/storage/fatfs/sdkconfig | 323 + .../fatfs}/sdkconfig.h | 303 +- example/storage/fatfs/src/fatfs_examples.c | 431 + example/storage/qspi_spiffs/README.md | 7 +- .../configs/d2000_aarch32_eg_configs | 64 +- .../configs/d2000_aarch64_eg_configs | 64 +- .../configs/e2000d_aarch32_eg_configs | 64 +- .../configs/e2000d_aarch64_eg_configs | 64 +- .../configs/e2000q_aarch32_eg_configs | 64 +- .../configs/e2000q_aarch64_eg_configs | 64 +- .../configs/ft2004_aarch32_eg_configs | 64 +- .../configs/ft2004_aarch64_eg_configs | 64 +- example/storage/qspi_spiffs/figs/delete.png | Bin 41471 -> 23080 bytes example/storage/qspi_spiffs/figs/init.png | Bin 24680 -> 30941 bytes example/storage/qspi_spiffs/figs/wr.png | Bin 44533 -> 31283 bytes .../qspi_spiffs/inc/qspi_spiffs_example.h | 41 +- example/storage/qspi_spiffs/main.c | 45 +- example/storage/qspi_spiffs/sdkconfig | 64 +- example/storage/qspi_spiffs/sdkconfig.h | 56 +- .../qspi_spiffs/src/qspi_spiffs_example.c | 446 +- .../configs/ft2004_aarch64_eg_configs | 233 - example/storage/sata_fatfs/figs/delete.png | Bin 26235 -> 0 bytes example/storage/sata_fatfs/figs/hardware.png | Bin 882786 -> 0 bytes example/storage/sata_fatfs/figs/init.png | Bin 40282 -> 0 bytes .../storage/sata_fatfs/figs/menuconfig.png | Bin 11688 -> 0 bytes example/storage/sata_fatfs/figs/wr.png | Bin 41755 -> 0 bytes .../sata_fatfs/src/sata_fatfs_example.c | 484 - example/storage/spim_spiffs/README.md | 135 - example/storage/spim_spiffs/figs/delete.png | Bin 41471 -> 0 bytes example/storage/spim_spiffs/figs/hardware.jpg | Bin 294515 -> 0 bytes example/storage/spim_spiffs/figs/init.png | Bin 24680 -> 0 bytes example/storage/spim_spiffs/figs/wr.png | Bin 44533 -> 0 bytes .../spim_spiffs/inc/spim_spiffs_example.h | 30 - example/storage/spim_spiffs/sdkconfig | 236 - .../spim_spiffs/src/spim_spiffs_example.c | 620 - example/template/{READEME.md => README.md} | 2 +- .../template/configs/d2000_aarch32_eg_configs | 64 +- .../template/configs/d2000_aarch64_eg_configs | 64 +- .../configs/e2000d_aarch32_eg_configs | 64 +- .../configs/e2000d_aarch64_eg_configs | 64 +- .../configs/e2000q_aarch32_eg_configs | 64 +- .../configs/e2000q_aarch64_eg_configs | 64 +- .../configs/ft2004_aarch32_eg_configs | 64 +- .../configs/ft2004_aarch64_eg_configs | 64 +- example/template/main.c | 121 +- example/template/sdkconfig | 68 +- example/template/sdkconfig.h | 60 +- install.py | 10 +- make/Kconfig | 24 + make/complier.mk | 7 +- third-party/Kconfig | 11 +- .../cherryusb-0.6.0/port/xhci/usb_config.h | 76 +- .../cherryusb-0.6.0/port/xhci/usb_hc_xhci.c | 757 +- .../cherryusb-0.6.0/port/xhci/usb_hc_xhci.h | 76 +- .../cherryusb-0.6.0/port/xhci/xhci_reg.h | 395 +- third-party/fatfs-0.1.3/Kconfig | 34 - third-party/fatfs-0.1.3/ff.c | 6533 ------- third-party/fatfs-0.1.3/ff.h | 380 - third-party/fatfs-0.1.3/ffconf.h | 293 - third-party/fatfs-0.1.3/ffunicode.c | 15597 ---------------- third-party/fatfs-0.1.3/integer.h | 38 - .../port/fsata_controller/diskio.h | 80 - .../fatfs-0.1.3/port/fsata_pcie/diskio.h | 80 - third-party/fatfs-0.1.4/Kconfig | 1 + third-party/fatfs-0.1.4/fatfs.mk | 24 + .../osal}/ffsystem.c | 115 +- .../diskio_sata_controller.c} | 330 +- .../port/fsata_pcie/diskio_sata_pcie.c} | 464 +- .../fatfs-0.1.4/port/fusb/diskio_usb.c | 342 + third-party/freertos/Kconfig | 198 + .../{aarch32 => }/FreeRTOSConfig.h | 151 +- .../portable/GCC/ft_platform/aarch32/port.c | 591 +- .../GCC/ft_platform/aarch32/portASM.S | 1 + .../GCC/ft_platform/aarch32/portmacro.h | 78 +- .../GCC/ft_platform/aarch64/FreeRTOSConfig.h | 201 - .../portable/GCC/ft_platform/aarch64/port.c | 657 +- .../GCC/ft_platform/aarch64/portASM.S | 44 +- .../GCC/ft_platform/aarch64/portAsm_debug.c | 36 +- .../GCC/ft_platform/aarch64/portmacro.h | 102 +- .../freertos/portable/freertos_configs.c | 197 +- .../letter-shell-3.1/port/cmd/cmd_bootelf.c | 133 +- .../port/cmd/cmd_codeloader.c | 130 +- .../letter-shell-3.1/port/cmd/cmd_echo.c | 39 +- .../letter-shell-3.1/port/cmd/cmd_md.c | 251 +- .../letter-shell-3.1/port/cmd/cmd_mw.c | 211 +- .../port/cmd/{cmd_os_stats.c => cmd_ps.c} | 43 +- .../letter-shell-3.1/port/cmd/cmd_reboot.c | 29 +- .../letter-shell-3.1/port/cmd/cmd_rw.c | 235 +- .../letter-shell-3.1/port/cmd/cmd_sleep.c | 41 +- .../letter-shell-3.1/port/cmd/cmd_version.c | 29 +- .../port/pl011/fpl011_os_port.c | 46 +- .../letter-shell-3.1/port/shell_port.c | 57 +- .../letter-shell-3.1/port/shell_port.h | 40 +- third-party/lwip-2.1.2/FILES | 15 - third-party/lwip-2.1.2/Kconfig | 1033 +- third-party/lwip-2.1.2/api/api_lib.c | 1367 -- third-party/lwip-2.1.2/api/api_msg.c | 2173 --- third-party/lwip-2.1.2/api/err.c | 115 - third-party/lwip-2.1.2/api/if_api.c | 102 - third-party/lwip-2.1.2/api/netbuf.c | 250 - third-party/lwip-2.1.2/api/netdb.c | 414 - third-party/lwip-2.1.2/api/netifapi.c | 380 - third-party/lwip-2.1.2/api/sockets.c | 4160 ----- third-party/lwip-2.1.2/api/tcpip.c | 661 - third-party/lwip-2.1.2/apps/ping/ping.c | 482 - third-party/lwip-2.1.2/apps/ping/ping.h | 21 - third-party/lwip-2.1.2/apps/tftp/tftp.c | 614 - .../lwip-2.1.2/apps/tftp/tftp_client.h | 72 - .../lwip-2.1.2/apps/tftp/tftp_common.h | 108 - third-party/lwip-2.1.2/apps/tftp/tftp_opts.h | 106 - .../lwip-2.1.2/apps/tftp/tftp_server.h | 42 - third-party/lwip-2.1.2/core/altcp.c | 681 - third-party/lwip-2.1.2/core/altcp_alloc.c | 87 - third-party/lwip-2.1.2/core/altcp_tcp.c | 543 - third-party/lwip-2.1.2/core/def.c | 240 - third-party/lwip-2.1.2/core/dns.c | 1631 -- third-party/lwip-2.1.2/core/inet_chksum.c | 608 - third-party/lwip-2.1.2/core/init.c | 381 - third-party/lwip-2.1.2/core/ip.c | 167 - third-party/lwip-2.1.2/core/ipv4/autoip.c | 527 - third-party/lwip-2.1.2/core/ipv4/dhcp.c | 1990 -- third-party/lwip-2.1.2/core/ipv4/etharp.c | 1204 -- third-party/lwip-2.1.2/core/ipv4/icmp.c | 404 - third-party/lwip-2.1.2/core/ipv4/igmp.c | 801 - third-party/lwip-2.1.2/core/ipv4/ip4.c | 1132 -- third-party/lwip-2.1.2/core/ipv4/ip4_addr.c | 321 - third-party/lwip-2.1.2/core/ipv4/ip4_frag.c | 894 - third-party/lwip-2.1.2/core/ipv6/dhcp6.c | 812 - third-party/lwip-2.1.2/core/ipv6/ethip6.c | 123 - third-party/lwip-2.1.2/core/ipv6/icmp6.c | 425 - third-party/lwip-2.1.2/core/ipv6/inet6.c | 53 - third-party/lwip-2.1.2/core/ipv6/ip6.c | 1492 -- third-party/lwip-2.1.2/core/ipv6/ip6_addr.c | 343 - third-party/lwip-2.1.2/core/ipv6/ip6_frag.c | 862 - third-party/lwip-2.1.2/core/ipv6/mld6.c | 626 - third-party/lwip-2.1.2/core/ipv6/nd6.c | 2434 --- third-party/lwip-2.1.2/core/mem.c | 1017 - third-party/lwip-2.1.2/core/memp.c | 447 - third-party/lwip-2.1.2/core/netif.c | 1803 -- third-party/lwip-2.1.2/core/pbuf.c | 1514 -- third-party/lwip-2.1.2/core/raw.c | 671 - third-party/lwip-2.1.2/core/stats.c | 169 - third-party/lwip-2.1.2/core/sys.c | 148 - third-party/lwip-2.1.2/core/tcp.c | 2686 --- third-party/lwip-2.1.2/core/tcp_in.c | 2178 --- third-party/lwip-2.1.2/core/tcp_out.c | 2190 --- third-party/lwip-2.1.2/core/timeouts.c | 451 - third-party/lwip-2.1.2/core/udp.c | 1314 -- .../include/compat/posix/arpa/inet.h | 33 - .../lwip-2.1.2/include/compat/posix/net/if.h | 36 - .../lwip-2.1.2/include/compat/posix/netdb.h | 33 - .../include/compat/posix/sys/socket.h | 33 - .../lwip-2.1.2/include/compat/stdc/errno.h | 33 - third-party/lwip-2.1.2/include/lwip/altcp.h | 201 - .../lwip-2.1.2/include/lwip/altcp_tcp.h | 72 - .../lwip-2.1.2/include/lwip/altcp_tls.h | 117 - third-party/lwip-2.1.2/include/lwip/api.h | 431 - third-party/lwip-2.1.2/include/lwip/arch.h | 395 - third-party/lwip-2.1.2/include/lwip/autoip.h | 99 - third-party/lwip-2.1.2/include/lwip/debug.h | 161 - third-party/lwip-2.1.2/include/lwip/def.h | 152 - third-party/lwip-2.1.2/include/lwip/dhcp.h | 139 - third-party/lwip-2.1.2/include/lwip/dhcp6.h | 104 - third-party/lwip-2.1.2/include/lwip/dns.h | 131 - third-party/lwip-2.1.2/include/lwip/err.h | 117 - third-party/lwip-2.1.2/include/lwip/errno.h | 198 - third-party/lwip-2.1.2/include/lwip/etharp.h | 105 - third-party/lwip-2.1.2/include/lwip/ethip6.h | 68 - third-party/lwip-2.1.2/include/lwip/icmp.h | 110 - third-party/lwip-2.1.2/include/lwip/icmp6.h | 72 - third-party/lwip-2.1.2/include/lwip/if_api.h | 68 - third-party/lwip-2.1.2/include/lwip/igmp.h | 115 - third-party/lwip-2.1.2/include/lwip/inet.h | 169 - .../lwip-2.1.2/include/lwip/inet_chksum.h | 105 - third-party/lwip-2.1.2/include/lwip/init.h | 100 - .../lwip-2.1.2/include/lwip/init.h.cmake.in | 100 - third-party/lwip-2.1.2/include/lwip/ip.h | 330 - third-party/lwip-2.1.2/include/lwip/ip4.h | 111 - .../lwip-2.1.2/include/lwip/ip4_addr.h | 216 - .../lwip-2.1.2/include/lwip/ip4_frag.h | 100 - third-party/lwip-2.1.2/include/lwip/ip6.h | 93 - .../lwip-2.1.2/include/lwip/ip6_addr.h | 352 - .../lwip-2.1.2/include/lwip/ip6_frag.h | 144 - .../lwip-2.1.2/include/lwip/ip6_zone.h | 304 - third-party/lwip-2.1.2/include/lwip/ip_addr.h | 438 - third-party/lwip-2.1.2/include/lwip/mem.h | 82 - third-party/lwip-2.1.2/include/lwip/memp.h | 155 - third-party/lwip-2.1.2/include/lwip/mld6.h | 99 - third-party/lwip-2.1.2/include/lwip/nd6.h | 90 - third-party/lwip-2.1.2/include/lwip/netbuf.h | 116 - third-party/lwip-2.1.2/include/lwip/netdb.h | 150 - third-party/lwip-2.1.2/include/lwip/netif.h | 669 - .../lwip-2.1.2/include/lwip/netifapi.h | 161 - third-party/lwip-2.1.2/include/lwip/opt.h | 3519 ---- third-party/lwip-2.1.2/include/lwip/pbuf.h | 322 - .../lwip-2.1.2/include/lwip/priv/altcp_priv.h | 146 - .../lwip-2.1.2/include/lwip/priv/api_msg.h | 272 - .../lwip-2.1.2/include/lwip/priv/mem_priv.h | 84 - .../lwip-2.1.2/include/lwip/priv/memp_priv.h | 161 - .../lwip-2.1.2/include/lwip/priv/memp_std.h | 153 - .../lwip-2.1.2/include/lwip/priv/nd6_priv.h | 142 - .../lwip-2.1.2/include/lwip/priv/raw_priv.h | 69 - .../include/lwip/priv/sockets_priv.h | 175 - .../lwip-2.1.2/include/lwip/priv/tcp_priv.h | 523 - .../lwip-2.1.2/include/lwip/priv/tcpip_priv.h | 170 - .../lwip-2.1.2/include/lwip/prot/autoip.h | 78 - .../lwip-2.1.2/include/lwip/prot/dhcp.h | 178 - .../lwip-2.1.2/include/lwip/prot/dhcp6.h | 138 - .../lwip-2.1.2/include/lwip/prot/dns.h | 140 - .../lwip-2.1.2/include/lwip/prot/etharp.h | 114 - .../lwip-2.1.2/include/lwip/prot/ethernet.h | 125 - .../lwip-2.1.2/include/lwip/prot/iana.h | 97 - .../lwip-2.1.2/include/lwip/prot/icmp.h | 91 - .../lwip-2.1.2/include/lwip/prot/icmp6.h | 170 - .../lwip-2.1.2/include/lwip/prot/ieee.h | 91 - .../lwip-2.1.2/include/lwip/prot/igmp.h | 90 - third-party/lwip-2.1.2/include/lwip/prot/ip.h | 59 - .../lwip-2.1.2/include/lwip/prot/ip4.h | 131 - .../lwip-2.1.2/include/lwip/prot/ip6.h | 233 - .../lwip-2.1.2/include/lwip/prot/mld6.h | 71 - .../lwip-2.1.2/include/lwip/prot/nd6.h | 274 - .../lwip-2.1.2/include/lwip/prot/tcp.h | 100 - .../lwip-2.1.2/include/lwip/prot/udp.h | 68 - third-party/lwip-2.1.2/include/lwip/raw.h | 143 - third-party/lwip-2.1.2/include/lwip/sio.h | 142 - third-party/lwip-2.1.2/include/lwip/snmp.h | 213 - third-party/lwip-2.1.2/include/lwip/sockets.h | 688 - third-party/lwip-2.1.2/include/lwip/stats.h | 491 - third-party/lwip-2.1.2/include/lwip/sys.h | 560 - third-party/lwip-2.1.2/include/lwip/tcp.h | 500 - third-party/lwip-2.1.2/include/lwip/tcpbase.h | 88 - third-party/lwip-2.1.2/include/lwip/tcpip.h | 113 - .../lwip-2.1.2/include/lwip/timeouts.h | 128 - third-party/lwip-2.1.2/include/lwip/udp.h | 195 - .../lwip-2.1.2/include/netif/bridgeif.h | 127 - .../lwip-2.1.2/include/netif/bridgeif_opts.h | 90 - third-party/lwip-2.1.2/include/netif/etharp.h | 3 - .../lwip-2.1.2/include/netif/ethernet.h | 77 - .../lwip-2.1.2/include/netif/ieee802154.h | 112 - .../lwip-2.1.2/include/netif/lowpan6.h | 89 - .../lwip-2.1.2/include/netif/lowpan6_ble.h | 78 - .../lwip-2.1.2/include/netif/lowpan6_common.h | 82 - .../lwip-2.1.2/include/netif/lowpan6_opts.h | 122 - .../lwip-2.1.2/include/netif/ppp/ccp.h | 164 - .../lwip-2.1.2/include/netif/ppp/chap-md5.h | 36 - .../lwip-2.1.2/include/netif/ppp/chap-new.h | 200 - .../lwip-2.1.2/include/netif/ppp/chap_ms.h | 44 - .../lwip-2.1.2/include/netif/ppp/eap.h | 169 - .../lwip-2.1.2/include/netif/ppp/ecp.h | 62 - .../lwip-2.1.2/include/netif/ppp/eui64.h | 102 - .../lwip-2.1.2/include/netif/ppp/fsm.h | 182 - .../lwip-2.1.2/include/netif/ppp/ipcp.h | 134 - .../lwip-2.1.2/include/netif/ppp/ipv6cp.h | 191 - .../lwip-2.1.2/include/netif/ppp/lcp.h | 179 - .../lwip-2.1.2/include/netif/ppp/magic.h | 130 - .../lwip-2.1.2/include/netif/ppp/mppe.h | 181 - .../include/netif/ppp/polarssl/arc4.h | 81 - .../include/netif/ppp/polarssl/des.h | 92 - .../include/netif/ppp/polarssl/md4.h | 97 - .../include/netif/ppp/polarssl/md5.h | 96 - .../include/netif/ppp/polarssl/sha1.h | 96 - .../lwip-2.1.2/include/netif/ppp/ppp.h | 698 - .../lwip-2.1.2/include/netif/ppp/ppp_impl.h | 722 - .../lwip-2.1.2/include/netif/ppp/ppp_opts.h | 610 - .../lwip-2.1.2/include/netif/ppp/pppapi.h | 137 - .../lwip-2.1.2/include/netif/ppp/pppcrypt.h | 144 - .../lwip-2.1.2/include/netif/ppp/pppdebug.h | 88 - .../lwip-2.1.2/include/netif/ppp/pppoe.h | 187 - .../lwip-2.1.2/include/netif/ppp/pppol2tp.h | 209 - .../lwip-2.1.2/include/netif/ppp/pppos.h | 126 - .../lwip-2.1.2/include/netif/ppp/upap.h | 131 - third-party/lwip-2.1.2/include/netif/ppp/vj.h | 169 - third-party/lwip-2.1.2/include/netif/slipif.h | 87 - third-party/lwip-2.1.2/include/netif/zepif.h | 81 - third-party/lwip-2.1.2/lwip_freertos.mk | 25 + third-party/lwip-2.1.2/netif/FILES | 23 - third-party/lwip-2.1.2/netif/bridgeif.c | 563 - third-party/lwip-2.1.2/netif/bridgeif_fdb.c | 212 - third-party/lwip-2.1.2/netif/ethernet.c | 321 - third-party/lwip-2.1.2/netif/lowpan6.c | 920 - third-party/lwip-2.1.2/netif/lowpan6_ble.c | 447 - third-party/lwip-2.1.2/netif/lowpan6_common.c | 841 - .../lwip-2.1.2/netif/ppp/PPPD_FOLLOWUP | 473 - third-party/lwip-2.1.2/netif/ppp/auth.c | 2510 --- third-party/lwip-2.1.2/netif/ppp/ccp.c | 1740 -- third-party/lwip-2.1.2/netif/ppp/chap-md5.c | 126 - third-party/lwip-2.1.2/netif/ppp/chap-new.c | 677 - third-party/lwip-2.1.2/netif/ppp/chap_ms.c | 962 - third-party/lwip-2.1.2/netif/ppp/demand.c | 465 - third-party/lwip-2.1.2/netif/ppp/eap.c | 2423 --- third-party/lwip-2.1.2/netif/ppp/ecp.c | 191 - third-party/lwip-2.1.2/netif/ppp/eui64.c | 56 - third-party/lwip-2.1.2/netif/ppp/fsm.c | 799 - third-party/lwip-2.1.2/netif/ppp/ipcp.c | 2418 --- third-party/lwip-2.1.2/netif/ppp/ipv6cp.c | 1533 -- third-party/lwip-2.1.2/netif/ppp/lcp.c | 2790 --- third-party/lwip-2.1.2/netif/ppp/magic.c | 294 - third-party/lwip-2.1.2/netif/ppp/mppe.c | 412 - third-party/lwip-2.1.2/netif/ppp/multilink.c | 609 - .../lwip-2.1.2/netif/ppp/polarssl/README | 22 - .../lwip-2.1.2/netif/ppp/polarssl/arc4.c | 101 - .../lwip-2.1.2/netif/ppp/polarssl/des.c | 422 - .../lwip-2.1.2/netif/ppp/polarssl/md4.c | 281 - .../lwip-2.1.2/netif/ppp/polarssl/md5.c | 300 - .../lwip-2.1.2/netif/ppp/polarssl/sha1.c | 335 - third-party/lwip-2.1.2/netif/ppp/ppp.c | 1628 -- third-party/lwip-2.1.2/netif/ppp/pppapi.c | 427 - third-party/lwip-2.1.2/netif/ppp/pppcrypt.c | 66 - third-party/lwip-2.1.2/netif/ppp/pppoe.c | 1201 -- third-party/lwip-2.1.2/netif/ppp/pppol2tp.c | 1159 -- third-party/lwip-2.1.2/netif/ppp/pppos.c | 895 - third-party/lwip-2.1.2/netif/ppp/upap.c | 677 - third-party/lwip-2.1.2/netif/ppp/utils.c | 957 - third-party/lwip-2.1.2/netif/ppp/vj.c | 685 - third-party/lwip-2.1.2/netif/slipif.c_o | 558 - third-party/lwip-2.1.2/netif/zepif.c | 300 - third-party/lwip-2.1.2/ports/Kconfig | 22 - .../lwip-2.1.2/ports/{fxmac => }/arch/cc.h | 57 +- .../ports/{fxmac => }/arch/sys_arch.c | 932 +- .../ports/{fxmac => }/arch/sys_arch.h | 59 +- third-party/lwip-2.1.2/ports/fgmac/arch/cc.h | 121 - .../lwip-2.1.2/ports/fgmac/arch/sys_arch.h | 74 - .../lwip-2.1.2/ports/fgmac/ethernetif.c | 824 +- .../lwip-2.1.2/ports/fgmac/ethernetif.h | 55 - .../lwip-2.1.2/ports/fgmac/ft_os_gmac.c | 445 - .../lwip-2.1.2/ports/fgmac/lwip_port.c | 369 - .../lwip-2.1.2/ports/fgmac/lwip_port.h | 79 - third-party/lwip-2.1.2/ports/fgmac/lwipopts.h | 278 - third-party/lwip-2.1.2/ports/fgmac/sys_arch.c | 499 - .../lwip-2.1.2/ports/fxmac/ethernetif.c | 198 +- .../lwip-2.1.2/ports/fxmac/ethernetif.h | 50 - .../lwip-2.1.2/ports/fxmac/lwip_port.c | 249 - .../lwip-2.1.2/ports/fxmac/lwip_port.h | 104 - third-party/lwip-2.1.2/ports/lwipopts.h | 1236 -- third-party/lwip-2.1.2/ports/lwippools.h | 29 - third-party/lwip-2.1.2/ports/sockets_ext.c | 109 - third-party/lwip-2.1.2/ports/sockets_ext.h | 24 - third-party/openamp/ports/helper.c | 93 +- third-party/openamp/ports/phytium_os_rproc.c | 260 +- third-party/openamp/ports/platform_info.c | 403 +- third-party/openamp/ports/platform_info.h | 183 +- third-party/openamp/ports/rsc_table.c | 137 +- third-party/openamp/ports/rsc_table.h | 66 +- third-party/sdmmc-1.0/Kconfig | 13 +- third-party/sdmmc-1.0/inc/sdmmc_cmd.h | 312 - third-party/sdmmc-1.0/inc/sdmmc_common.h | 177 - third-party/sdmmc-1.0/inc/sdmmc_defs.h | 492 - third-party/sdmmc-1.0/inc/sdmmc_types.h | 212 - third-party/sdmmc-1.0/osal/sdmmc_system.c | 95 + .../sdmmc_port.h => osal/sdmmc_system.h} | 82 +- third-party/sdmmc-1.0/port/fsdio/fsdio_port.c | 735 + .../port/fsdio/fsdio_port.h} | 71 +- third-party/sdmmc-1.0/port/sdmmc_host_os.h | 186 + third-party/sdmmc-1.0/sdmmc.mk | 20 + third-party/sdmmc-1.0/src/sdmmc_cmd.c | 676 - third-party/sdmmc-1.0/src/sdmmc_common.c | 400 - third-party/sdmmc-1.0/src/sdmmc_init.c | 262 - third-party/sdmmc-1.0/src/sdmmc_io.c | 725 - third-party/sdmmc-1.0/src/sdmmc_mmc.c | 299 - third-party/sdmmc-1.0/src/sdmmc_sd.c | 408 - .../sfud-1.1.0/ports/fqspi/fqspi_sfud_core.c | 121 +- .../sfud-1.1.0/ports/fqspi/fqspi_sfud_core.h | 42 +- .../sfud-1.1.0/ports/fspim/fspim_sfud_core.c | 58 +- .../sfud-1.1.0/ports/fspim/fspim_sfud_core.h | 40 +- third-party/sfud-1.1.0/ports/sfud_port.c | 18 +- third-party/spiffs-0.3.7/config.md | 4 +- third-party/spiffs-0.3.7/inc/spiffs.h | 3 +- .../ports/fqspi/fqspi_spiffs_port.c | 227 +- .../ports/fqspi/fqspi_spiffs_port.h | 36 +- .../ports/fspim/fspim_spiffs_port.c | 217 +- .../ports/fspim/fspim_spiffs_port.h | 27 +- .../spiffs-0.3.7/ports/spiffs_config.h | 191 +- third-party/spiffs-0.3.7/ports/spiffs_port.c | 33 +- third-party/spiffs-0.3.7/ports/spiffs_port.h | 43 +- third-party/third-party.mk | 122 +- third-party/tlsf-3.1.0/port/fmemory_pool.c | 108 +- third-party/tlsf-3.1.0/port/fmemory_pool.h | 40 +- third-party/tlsf-3.1.0/port/fslink_list.h | 54 +- 792 files changed, 38679 insertions(+), 154417 deletions(-) create mode 100644 drivers/eth/gmac/fgmac_os.c rename third-party/lwip-2.1.2/ports/fgmac/ft_os_gmac.h => drivers/eth/gmac/fgmac_os.h (37%) delete mode 100644 drivers/eth/xmac/ft_os_xmac.c create mode 100644 drivers/eth/xmac/fxmac_os.c rename drivers/eth/xmac/{ft_os_xmac.h => fxmac_os.h} (63%) create mode 100644 drivers/i2c/fi2c_os.c create mode 100644 drivers/i2c/fi2c_os.h delete mode 100644 drivers/mmc/fsdio/fsdio_os.c delete mode 100644 drivers/mmc/fsdio/fsdio_os.h create mode 100644 drivers/timer/ftimer_tacho_os.c rename third-party/sdmmc-1.0/port/fsdio/sdmmc_port.c => drivers/timer/ftimer_tacho_os.h (31%) delete mode 100644 example/makefile delete mode 100644 example/network/gmac_lwip_test/Kconfig delete mode 100644 example/network/gmac_lwip_test/configs/d2000_aarch32_eg_configs delete mode 100644 example/network/gmac_lwip_test/configs/d2000_aarch64_eg_configs delete mode 100644 example/network/gmac_lwip_test/configs/ft2004_aarch32_eg_configs delete mode 100644 example/network/gmac_lwip_test/configs/ft2004_aarch64_eg_configs delete mode 100644 example/network/gmac_lwip_test/pic/gmac_dhcp_menuconfig.png delete mode 100644 example/network/gmac_lwip_test/pic/gmac_ipv4_menuconfig.png delete mode 100644 example/network/gmac_lwip_test/pic/gmac_ipv6_menuconfig.png delete mode 100644 example/network/gmac_lwip_test/pic/gmac_probe.png delete mode 100644 example/network/gmac_lwip_test/pic/gmac_probe_dhcp0.png delete mode 100644 example/network/gmac_lwip_test/pic/gmac_probe_dhcp1.png delete mode 100644 example/network/gmac_lwip_test/pic/gmac_probe_ipv6.png delete mode 100644 example/network/gmac_lwip_test/pic/ping_ipv6.png delete mode 100644 example/network/gmac_lwip_test/sdkconfig delete mode 100644 example/network/gmac_lwip_test/src/lwip_test.c rename example/network/{xmac_lwip_test => lwip_startup}/Kconfig (81%) rename example/network/{xmac_lwip_test => lwip_startup}/README.md (53%) create mode 100644 example/network/lwip_startup/configs/d2000_aarch32_eg_configs create mode 100644 example/network/lwip_startup/configs/d2000_aarch64_eg_configs rename example/network/{xmac_lwip_test => lwip_startup}/configs/e2000d_aarch32_eg_configs (71%) rename example/network/{xmac_lwip_test => lwip_startup}/configs/e2000d_aarch64_eg_configs (70%) rename example/network/{xmac_lwip_test => lwip_startup}/configs/e2000q_aarch32_eg_configs (71%) rename example/network/{xmac_lwip_test => lwip_startup}/configs/e2000q_aarch64_eg_configs (70%) create mode 100644 example/network/lwip_startup/configs/ft2004_aarch32_eg_configs create mode 100644 example/network/lwip_startup/configs/ft2004_aarch64_eg_configs rename example/network/{xmac_lwip_test => lwip_startup}/main.c (70%) rename example/network/{xmac_lwip_test => lwip_startup}/makefile (100%) create mode 100644 example/network/lwip_startup/pic/dhcp_test.png rename "example/network/xmac_lwip_test/pic/e2000demo\346\235\277\345\205\250\350\262\214.jpg" => "example/network/lwip_startup/pic/e2000demo\346\235\277\345\205\250\350\262\214.jpg" (100%) create mode 100644 example/network/lwip_startup/pic/ipv4_test.png create mode 100644 example/network/lwip_startup/pic/ipv6_test.png create mode 100644 example/network/lwip_startup/pic/lwip_probe.png create mode 100644 example/network/lwip_startup/pic/network_demo_config.png rename example/network/{gmac_lwip_test => lwip_startup}/pic/ping.png (100%) rename example/network/{xmac_lwip_test => lwip_startup}/pic/ping_ipv6.png (100%) rename example/network/{xmac_lwip_test => lwip_startup}/pic/select_demo.png (100%) rename example/network/{xmac_lwip_test => lwip_startup}/pic/xmac_dhcp_menuconfig.png (100%) rename example/network/{xmac_lwip_test => lwip_startup}/pic/xmac_ipv4_menuconfig.png (100%) rename example/network/{xmac_lwip_test => lwip_startup}/pic/xmac_ipv6_menuconfig.png (100%) rename example/network/{xmac_lwip_test => lwip_startup}/sdkconfig (70%) rename example/network/{xmac_lwip_test => lwip_startup}/sdkconfig.h (70%) rename example/network/{xmac_lwip_test => lwip_startup}/src/Kconfig (38%) create mode 100644 example/network/lwip_startup/src/e2000_gpio_config.c create mode 100644 example/network/lwip_startup/src/lwip_test.c create mode 100644 example/network/sockets/udp_multicast/configs/d2000_aarch32_eg_configs create mode 100644 example/network/sockets/udp_multicast/configs/d2000_aarch64_eg_configs create mode 100644 example/network/sockets/udp_multicast/configs/ft2004_aarch32_eg_configs create mode 100644 example/network/sockets/udp_multicast/configs/ft2004_aarch64_eg_configs create mode 100644 example/network/sockets/udp_multicast/pic/ipv4_ipv6_config.png create mode 100644 example/network/sockets/udp_multicast/pic/lwip_probe.png delete mode 100644 example/network/sockets/udp_multicast/pic/xmac_probe.png delete mode 100644 example/network/sockets/udp_multicast/pic/xmac_probe_ipv4.png delete mode 100644 example/network/sockets/udp_multicast/pic/xmac_probe_ipv4_2.png delete mode 100644 example/network/sockets/udp_multicast/pic/xmac_probe_ipv6.png delete mode 100644 example/network/sockets/udp_multicast/pic/xmac_probe_ipv6_2.png create mode 100644 example/network/sockets/udp_multicast/src/e2000_board.c delete mode 100644 example/network/xmac_lwip_test/pic/ping.png delete mode 100644 example/network/xmac_lwip_test/pic/xmac_probe.png delete mode 100644 example/network/xmac_lwip_test/pic/xmac_probe_dhcp0.png delete mode 100644 example/network/xmac_lwip_test/pic/xmac_probe_dhcp1.png delete mode 100644 example/network/xmac_lwip_test/pic/xmac_probe_ipv4.png delete mode 100644 example/network/xmac_lwip_test/pic/xmac_probe_ipv6.png delete mode 100644 example/network/xmac_lwip_test/src/lwip_test.c rename example/{storage/sata_fatfs => peripheral/i2c}/Kconfig (100%) rename example/{network/gmac_lwip_test => peripheral/i2c}/README.md (50%) rename example/{storage/sata_fatfs => peripheral/i2c}/configs/d2000_aarch32_eg_configs (69%) rename example/{storage/sata_fatfs => peripheral/i2c}/configs/d2000_aarch64_eg_configs (69%) rename example/{storage/sata_fatfs => peripheral/i2c}/configs/e2000d_aarch32_eg_configs (70%) rename example/{storage/sata_fatfs => peripheral/i2c}/configs/e2000d_aarch64_eg_configs (70%) rename example/{storage/sata_fatfs => peripheral/i2c}/configs/e2000q_aarch32_eg_configs (70%) rename example/{storage/sata_fatfs => peripheral/i2c}/configs/e2000q_aarch64_eg_configs (70%) create mode 100644 example/peripheral/i2c/figs/E2000_1339.png create mode 100644 example/peripheral/i2c/figs/E2000_rtc.png create mode 100644 example/peripheral/i2c/figs/board.png create mode 100644 example/peripheral/i2c/figs/d2000_eeprom.png create mode 100644 example/peripheral/i2c/figs/d2000_master_slave.png create mode 100644 example/peripheral/i2c/inc/i2c_example.h rename example/{storage/sata_fatfs => peripheral/i2c}/main.c (42%) rename example/{storage/sata_fatfs => peripheral/i2c}/makefile (89%) rename example/{storage/sata_fatfs => peripheral/i2c}/sdkconfig (70%) rename example/{storage/sata_fatfs => peripheral/i2c}/sdkconfig.h (69%) create mode 100644 example/peripheral/i2c/src/i2c_example.c rename example/{storage/spim_spiffs => peripheral/timer_tacho}/Kconfig (100%) rename example/{storage/sata_fatfs => peripheral/timer_tacho}/README.md (38%) rename example/{storage/spim_spiffs => peripheral/timer_tacho}/configs/e2000d_aarch32_eg_configs (67%) create mode 100644 example/peripheral/timer_tacho/configs/e2000d_aarch64_eg_configs rename example/{storage/sata_fatfs/configs/ft2004_aarch32_eg_configs => peripheral/timer_tacho/configs/e2000q_aarch32_eg_configs} (67%) create mode 100644 example/peripheral/timer_tacho/configs/e2000q_aarch64_eg_configs create mode 100644 example/peripheral/timer_tacho/figs/tacho_hdw.png create mode 100644 example/peripheral/timer_tacho/figs/timer_capture.png create mode 100644 example/peripheral/timer_tacho/figs/timer_tacho.png create mode 100644 example/peripheral/timer_tacho/inc/timer_tacho_example.h rename example/{network/gmac_lwip_test => peripheral/timer_tacho}/main.c (53%) rename example/{storage/spim_spiffs => peripheral/timer_tacho}/makefile (89%) create mode 100644 example/peripheral/timer_tacho/sdkconfig rename example/{storage/spim_spiffs => peripheral/timer_tacho}/sdkconfig.h (65%) create mode 100644 example/peripheral/timer_tacho/src/timer_tacho_example.c create mode 100644 example/storage/fatfs/Kconfig create mode 100644 example/storage/fatfs/READEME.md create mode 100644 example/storage/fatfs/configs/e2000d_aarch32_eg_configs rename example/storage/{spim_spiffs => fatfs}/configs/e2000d_aarch64_eg_configs (51%) create mode 100644 example/storage/fatfs/configs/e2000q_aarch32_eg_configs create mode 100644 example/storage/fatfs/configs/e2000q_aarch64_eg_configs create mode 100644 example/storage/fatfs/figures/config.png create mode 100644 example/storage/fatfs/figures/hardware.png create mode 100644 example/storage/fatfs/figures/test_1.png create mode 100644 example/storage/fatfs/figures/test_2.png create mode 100644 example/storage/fatfs/figures/test_3.png create mode 100644 example/storage/fatfs/figures/test_4.png create mode 100644 example/storage/fatfs/figures/test_5.png create mode 100644 example/storage/fatfs/figures/test_item.png rename example/storage/{sata_fatfs/inc/sata_fatfs_example.h => fatfs/inc/fatfs_examples.h} (32%) rename example/storage/{spim_spiffs => fatfs}/main.c (45%) rename example/{network/gmac_lwip_test => storage/fatfs}/makefile (71%) create mode 100644 example/storage/fatfs/sdkconfig rename example/{network/gmac_lwip_test => storage/fatfs}/sdkconfig.h (45%) create mode 100644 example/storage/fatfs/src/fatfs_examples.c delete mode 100644 example/storage/sata_fatfs/configs/ft2004_aarch64_eg_configs delete mode 100644 example/storage/sata_fatfs/figs/delete.png delete mode 100644 example/storage/sata_fatfs/figs/hardware.png delete mode 100644 example/storage/sata_fatfs/figs/init.png delete mode 100644 example/storage/sata_fatfs/figs/menuconfig.png delete mode 100644 example/storage/sata_fatfs/figs/wr.png delete mode 100644 example/storage/sata_fatfs/src/sata_fatfs_example.c delete mode 100644 example/storage/spim_spiffs/README.md delete mode 100644 example/storage/spim_spiffs/figs/delete.png delete mode 100644 example/storage/spim_spiffs/figs/hardware.jpg delete mode 100644 example/storage/spim_spiffs/figs/init.png delete mode 100644 example/storage/spim_spiffs/figs/wr.png delete mode 100644 example/storage/spim_spiffs/inc/spim_spiffs_example.h delete mode 100644 example/storage/spim_spiffs/sdkconfig delete mode 100644 example/storage/spim_spiffs/src/spim_spiffs_example.c rename example/template/{READEME.md => README.md} (99%) delete mode 100644 third-party/fatfs-0.1.3/Kconfig delete mode 100644 third-party/fatfs-0.1.3/ff.c delete mode 100644 third-party/fatfs-0.1.3/ff.h delete mode 100644 third-party/fatfs-0.1.3/ffconf.h delete mode 100644 third-party/fatfs-0.1.3/ffunicode.c delete mode 100644 third-party/fatfs-0.1.3/integer.h delete mode 100644 third-party/fatfs-0.1.3/port/fsata_controller/diskio.h delete mode 100644 third-party/fatfs-0.1.3/port/fsata_pcie/diskio.h create mode 100644 third-party/fatfs-0.1.4/Kconfig create mode 100644 third-party/fatfs-0.1.4/fatfs.mk rename third-party/{fatfs-0.1.3 => fatfs-0.1.4/osal}/ffsystem.c (55%) rename third-party/{fatfs-0.1.3/port/fsata_controller/diskio.c => fatfs-0.1.4/port/fsata_controller/diskio_sata_controller.c} (38%) rename third-party/{fatfs-0.1.3/port/fsata_pcie/diskio.c => fatfs-0.1.4/port/fsata_pcie/diskio_sata_pcie.c} (33%) create mode 100644 third-party/fatfs-0.1.4/port/fusb/diskio_usb.c create mode 100644 third-party/freertos/Kconfig rename third-party/freertos/portable/GCC/ft_platform/{aarch32 => }/FreeRTOSConfig.h (62%) delete mode 100644 third-party/freertos/portable/GCC/ft_platform/aarch64/FreeRTOSConfig.h rename third-party/letter-shell-3.1/port/cmd/{cmd_os_stats.c => cmd_ps.c} (71%) delete mode 100644 third-party/lwip-2.1.2/FILES delete mode 100644 third-party/lwip-2.1.2/api/api_lib.c delete mode 100644 third-party/lwip-2.1.2/api/api_msg.c delete mode 100644 third-party/lwip-2.1.2/api/err.c delete mode 100644 third-party/lwip-2.1.2/api/if_api.c delete mode 100644 third-party/lwip-2.1.2/api/netbuf.c delete mode 100644 third-party/lwip-2.1.2/api/netdb.c delete mode 100644 third-party/lwip-2.1.2/api/netifapi.c delete mode 100644 third-party/lwip-2.1.2/api/sockets.c delete mode 100644 third-party/lwip-2.1.2/api/tcpip.c delete mode 100644 third-party/lwip-2.1.2/apps/ping/ping.c delete mode 100644 third-party/lwip-2.1.2/apps/ping/ping.h delete mode 100644 third-party/lwip-2.1.2/apps/tftp/tftp.c delete mode 100644 third-party/lwip-2.1.2/apps/tftp/tftp_client.h delete mode 100644 third-party/lwip-2.1.2/apps/tftp/tftp_common.h delete mode 100644 third-party/lwip-2.1.2/apps/tftp/tftp_opts.h delete mode 100644 third-party/lwip-2.1.2/apps/tftp/tftp_server.h delete mode 100644 third-party/lwip-2.1.2/core/altcp.c delete mode 100644 third-party/lwip-2.1.2/core/altcp_alloc.c delete mode 100644 third-party/lwip-2.1.2/core/altcp_tcp.c delete mode 100644 third-party/lwip-2.1.2/core/def.c delete mode 100644 third-party/lwip-2.1.2/core/dns.c delete mode 100644 third-party/lwip-2.1.2/core/inet_chksum.c delete mode 100644 third-party/lwip-2.1.2/core/init.c delete mode 100644 third-party/lwip-2.1.2/core/ip.c delete mode 100644 third-party/lwip-2.1.2/core/ipv4/autoip.c delete mode 100644 third-party/lwip-2.1.2/core/ipv4/dhcp.c delete mode 100644 third-party/lwip-2.1.2/core/ipv4/etharp.c delete mode 100644 third-party/lwip-2.1.2/core/ipv4/icmp.c delete mode 100644 third-party/lwip-2.1.2/core/ipv4/igmp.c delete mode 100644 third-party/lwip-2.1.2/core/ipv4/ip4.c delete mode 100644 third-party/lwip-2.1.2/core/ipv4/ip4_addr.c delete mode 100644 third-party/lwip-2.1.2/core/ipv4/ip4_frag.c delete mode 100644 third-party/lwip-2.1.2/core/ipv6/dhcp6.c delete mode 100644 third-party/lwip-2.1.2/core/ipv6/ethip6.c delete mode 100644 third-party/lwip-2.1.2/core/ipv6/icmp6.c delete mode 100644 third-party/lwip-2.1.2/core/ipv6/inet6.c delete mode 100644 third-party/lwip-2.1.2/core/ipv6/ip6.c delete mode 100644 third-party/lwip-2.1.2/core/ipv6/ip6_addr.c delete mode 100644 third-party/lwip-2.1.2/core/ipv6/ip6_frag.c delete mode 100644 third-party/lwip-2.1.2/core/ipv6/mld6.c delete mode 100644 third-party/lwip-2.1.2/core/ipv6/nd6.c delete mode 100644 third-party/lwip-2.1.2/core/mem.c delete mode 100644 third-party/lwip-2.1.2/core/memp.c delete mode 100644 third-party/lwip-2.1.2/core/netif.c delete mode 100644 third-party/lwip-2.1.2/core/pbuf.c delete mode 100644 third-party/lwip-2.1.2/core/raw.c delete mode 100644 third-party/lwip-2.1.2/core/stats.c delete mode 100644 third-party/lwip-2.1.2/core/sys.c delete mode 100644 third-party/lwip-2.1.2/core/tcp.c delete mode 100644 third-party/lwip-2.1.2/core/tcp_in.c delete mode 100644 third-party/lwip-2.1.2/core/tcp_out.c delete mode 100644 third-party/lwip-2.1.2/core/timeouts.c delete mode 100644 third-party/lwip-2.1.2/core/udp.c delete mode 100644 third-party/lwip-2.1.2/include/compat/posix/arpa/inet.h delete mode 100644 third-party/lwip-2.1.2/include/compat/posix/net/if.h delete mode 100644 third-party/lwip-2.1.2/include/compat/posix/netdb.h delete mode 100644 third-party/lwip-2.1.2/include/compat/posix/sys/socket.h delete mode 100644 third-party/lwip-2.1.2/include/compat/stdc/errno.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/altcp.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/altcp_tcp.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/altcp_tls.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/api.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/arch.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/autoip.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/debug.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/def.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/dhcp.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/dhcp6.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/dns.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/err.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/errno.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/etharp.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/ethip6.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/icmp.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/icmp6.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/if_api.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/igmp.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/inet.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/inet_chksum.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/init.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/init.h.cmake.in delete mode 100644 third-party/lwip-2.1.2/include/lwip/ip.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/ip4.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/ip4_addr.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/ip4_frag.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/ip6.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/ip6_addr.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/ip6_frag.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/ip6_zone.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/ip_addr.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/mem.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/memp.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/mld6.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/nd6.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/netbuf.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/netdb.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/netif.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/netifapi.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/opt.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/pbuf.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/priv/altcp_priv.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/priv/api_msg.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/priv/mem_priv.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/priv/memp_priv.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/priv/memp_std.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/priv/nd6_priv.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/priv/raw_priv.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/priv/sockets_priv.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/priv/tcp_priv.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/priv/tcpip_priv.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/prot/autoip.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/prot/dhcp.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/prot/dhcp6.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/prot/dns.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/prot/etharp.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/prot/ethernet.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/prot/iana.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/prot/icmp.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/prot/icmp6.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/prot/ieee.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/prot/igmp.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/prot/ip.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/prot/ip4.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/prot/ip6.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/prot/mld6.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/prot/nd6.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/prot/tcp.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/prot/udp.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/raw.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/sio.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/snmp.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/sockets.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/stats.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/sys.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/tcp.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/tcpbase.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/tcpip.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/timeouts.h delete mode 100644 third-party/lwip-2.1.2/include/lwip/udp.h delete mode 100644 third-party/lwip-2.1.2/include/netif/bridgeif.h delete mode 100644 third-party/lwip-2.1.2/include/netif/bridgeif_opts.h delete mode 100644 third-party/lwip-2.1.2/include/netif/etharp.h delete mode 100644 third-party/lwip-2.1.2/include/netif/ethernet.h delete mode 100644 third-party/lwip-2.1.2/include/netif/ieee802154.h delete mode 100644 third-party/lwip-2.1.2/include/netif/lowpan6.h delete mode 100644 third-party/lwip-2.1.2/include/netif/lowpan6_ble.h delete mode 100644 third-party/lwip-2.1.2/include/netif/lowpan6_common.h delete mode 100644 third-party/lwip-2.1.2/include/netif/lowpan6_opts.h delete mode 100644 third-party/lwip-2.1.2/include/netif/ppp/ccp.h delete mode 100644 third-party/lwip-2.1.2/include/netif/ppp/chap-md5.h delete mode 100644 third-party/lwip-2.1.2/include/netif/ppp/chap-new.h delete mode 100644 third-party/lwip-2.1.2/include/netif/ppp/chap_ms.h delete mode 100644 third-party/lwip-2.1.2/include/netif/ppp/eap.h delete mode 100644 third-party/lwip-2.1.2/include/netif/ppp/ecp.h delete mode 100644 third-party/lwip-2.1.2/include/netif/ppp/eui64.h delete mode 100644 third-party/lwip-2.1.2/include/netif/ppp/fsm.h delete mode 100644 third-party/lwip-2.1.2/include/netif/ppp/ipcp.h delete mode 100644 third-party/lwip-2.1.2/include/netif/ppp/ipv6cp.h delete mode 100644 third-party/lwip-2.1.2/include/netif/ppp/lcp.h delete mode 100644 third-party/lwip-2.1.2/include/netif/ppp/magic.h delete mode 100644 third-party/lwip-2.1.2/include/netif/ppp/mppe.h delete mode 100644 third-party/lwip-2.1.2/include/netif/ppp/polarssl/arc4.h delete mode 100644 third-party/lwip-2.1.2/include/netif/ppp/polarssl/des.h delete mode 100644 third-party/lwip-2.1.2/include/netif/ppp/polarssl/md4.h delete mode 100644 third-party/lwip-2.1.2/include/netif/ppp/polarssl/md5.h delete mode 100644 third-party/lwip-2.1.2/include/netif/ppp/polarssl/sha1.h delete mode 100644 third-party/lwip-2.1.2/include/netif/ppp/ppp.h delete mode 100644 third-party/lwip-2.1.2/include/netif/ppp/ppp_impl.h delete mode 100644 third-party/lwip-2.1.2/include/netif/ppp/ppp_opts.h delete mode 100644 third-party/lwip-2.1.2/include/netif/ppp/pppapi.h delete mode 100644 third-party/lwip-2.1.2/include/netif/ppp/pppcrypt.h delete mode 100644 third-party/lwip-2.1.2/include/netif/ppp/pppdebug.h delete mode 100644 third-party/lwip-2.1.2/include/netif/ppp/pppoe.h delete mode 100644 third-party/lwip-2.1.2/include/netif/ppp/pppol2tp.h delete mode 100644 third-party/lwip-2.1.2/include/netif/ppp/pppos.h delete mode 100644 third-party/lwip-2.1.2/include/netif/ppp/upap.h delete mode 100644 third-party/lwip-2.1.2/include/netif/ppp/vj.h delete mode 100644 third-party/lwip-2.1.2/include/netif/slipif.h delete mode 100644 third-party/lwip-2.1.2/include/netif/zepif.h create mode 100644 third-party/lwip-2.1.2/lwip_freertos.mk delete mode 100644 third-party/lwip-2.1.2/netif/FILES delete mode 100644 third-party/lwip-2.1.2/netif/bridgeif.c delete mode 100644 third-party/lwip-2.1.2/netif/bridgeif_fdb.c delete mode 100644 third-party/lwip-2.1.2/netif/ethernet.c delete mode 100644 third-party/lwip-2.1.2/netif/lowpan6.c delete mode 100644 third-party/lwip-2.1.2/netif/lowpan6_ble.c delete mode 100644 third-party/lwip-2.1.2/netif/lowpan6_common.c delete mode 100644 third-party/lwip-2.1.2/netif/ppp/PPPD_FOLLOWUP delete mode 100644 third-party/lwip-2.1.2/netif/ppp/auth.c delete mode 100644 third-party/lwip-2.1.2/netif/ppp/ccp.c delete mode 100644 third-party/lwip-2.1.2/netif/ppp/chap-md5.c delete mode 100644 third-party/lwip-2.1.2/netif/ppp/chap-new.c delete mode 100644 third-party/lwip-2.1.2/netif/ppp/chap_ms.c delete mode 100644 third-party/lwip-2.1.2/netif/ppp/demand.c delete mode 100644 third-party/lwip-2.1.2/netif/ppp/eap.c delete mode 100644 third-party/lwip-2.1.2/netif/ppp/ecp.c delete mode 100644 third-party/lwip-2.1.2/netif/ppp/eui64.c delete mode 100644 third-party/lwip-2.1.2/netif/ppp/fsm.c delete mode 100644 third-party/lwip-2.1.2/netif/ppp/ipcp.c delete mode 100644 third-party/lwip-2.1.2/netif/ppp/ipv6cp.c delete mode 100644 third-party/lwip-2.1.2/netif/ppp/lcp.c delete mode 100644 third-party/lwip-2.1.2/netif/ppp/magic.c delete mode 100644 third-party/lwip-2.1.2/netif/ppp/mppe.c delete mode 100644 third-party/lwip-2.1.2/netif/ppp/multilink.c delete mode 100644 third-party/lwip-2.1.2/netif/ppp/polarssl/README delete mode 100644 third-party/lwip-2.1.2/netif/ppp/polarssl/arc4.c delete mode 100644 third-party/lwip-2.1.2/netif/ppp/polarssl/des.c delete mode 100644 third-party/lwip-2.1.2/netif/ppp/polarssl/md4.c delete mode 100644 third-party/lwip-2.1.2/netif/ppp/polarssl/md5.c delete mode 100644 third-party/lwip-2.1.2/netif/ppp/polarssl/sha1.c delete mode 100644 third-party/lwip-2.1.2/netif/ppp/ppp.c delete mode 100644 third-party/lwip-2.1.2/netif/ppp/pppapi.c delete mode 100644 third-party/lwip-2.1.2/netif/ppp/pppcrypt.c delete mode 100644 third-party/lwip-2.1.2/netif/ppp/pppoe.c delete mode 100644 third-party/lwip-2.1.2/netif/ppp/pppol2tp.c delete mode 100644 third-party/lwip-2.1.2/netif/ppp/pppos.c delete mode 100644 third-party/lwip-2.1.2/netif/ppp/upap.c delete mode 100644 third-party/lwip-2.1.2/netif/ppp/utils.c delete mode 100644 third-party/lwip-2.1.2/netif/ppp/vj.c delete mode 100644 third-party/lwip-2.1.2/netif/slipif.c_o delete mode 100644 third-party/lwip-2.1.2/netif/zepif.c delete mode 100644 third-party/lwip-2.1.2/ports/Kconfig rename third-party/lwip-2.1.2/ports/{fxmac => }/arch/cc.h (76%) rename third-party/lwip-2.1.2/ports/{fxmac => }/arch/sys_arch.c (42%) rename third-party/lwip-2.1.2/ports/{fxmac => }/arch/sys_arch.h (56%) delete mode 100644 third-party/lwip-2.1.2/ports/fgmac/arch/cc.h delete mode 100644 third-party/lwip-2.1.2/ports/fgmac/arch/sys_arch.h delete mode 100644 third-party/lwip-2.1.2/ports/fgmac/ethernetif.h delete mode 100644 third-party/lwip-2.1.2/ports/fgmac/ft_os_gmac.c delete mode 100644 third-party/lwip-2.1.2/ports/fgmac/lwip_port.c delete mode 100644 third-party/lwip-2.1.2/ports/fgmac/lwip_port.h delete mode 100644 third-party/lwip-2.1.2/ports/fgmac/lwipopts.h delete mode 100644 third-party/lwip-2.1.2/ports/fgmac/sys_arch.c delete mode 100644 third-party/lwip-2.1.2/ports/fxmac/ethernetif.h delete mode 100644 third-party/lwip-2.1.2/ports/fxmac/lwip_port.c delete mode 100644 third-party/lwip-2.1.2/ports/fxmac/lwip_port.h delete mode 100644 third-party/lwip-2.1.2/ports/lwipopts.h delete mode 100644 third-party/lwip-2.1.2/ports/lwippools.h delete mode 100644 third-party/lwip-2.1.2/ports/sockets_ext.c delete mode 100644 third-party/lwip-2.1.2/ports/sockets_ext.h delete mode 100644 third-party/sdmmc-1.0/inc/sdmmc_cmd.h delete mode 100644 third-party/sdmmc-1.0/inc/sdmmc_common.h delete mode 100644 third-party/sdmmc-1.0/inc/sdmmc_defs.h delete mode 100644 third-party/sdmmc-1.0/inc/sdmmc_types.h create mode 100644 third-party/sdmmc-1.0/osal/sdmmc_system.c rename third-party/sdmmc-1.0/{port/fsdio/sdmmc_port.h => osal/sdmmc_system.h} (53%) create mode 100644 third-party/sdmmc-1.0/port/fsdio/fsdio_port.c rename third-party/{lwip-2.1.2/README.md => sdmmc-1.0/port/fsdio/fsdio_port.h} (42%) create mode 100644 third-party/sdmmc-1.0/port/sdmmc_host_os.h create mode 100644 third-party/sdmmc-1.0/sdmmc.mk delete mode 100644 third-party/sdmmc-1.0/src/sdmmc_cmd.c delete mode 100644 third-party/sdmmc-1.0/src/sdmmc_common.c delete mode 100644 third-party/sdmmc-1.0/src/sdmmc_init.c delete mode 100644 third-party/sdmmc-1.0/src/sdmmc_io.c delete mode 100644 third-party/sdmmc-1.0/src/sdmmc_mmc.c delete mode 100644 third-party/sdmmc-1.0/src/sdmmc_sd.c diff --git a/.gitattributes b/.gitattributes index 1e33416f..b13a7ebe 100644 --- a/.gitattributes +++ b/.gitattributes @@ -7,8 +7,11 @@ *.h text # Declare files that will always have CRLF line endings on checkout. +*.c text eol=lf +*.h text eol=lf *.py text eol=lf + # Denote all files that are truly binary and should not be modified. *.png binary *.jpg binary \ No newline at end of file diff --git a/Kconfig b/Kconfig index 1ea89052..e9a6a158 100644 --- a/Kconfig +++ b/Kconfig @@ -27,6 +27,10 @@ menu "Component Configuration" source "$(FREERTOS_SDK_ROOT)/drivers/Kconfig" endmenu -menu "FreeRTOS Setting" +menu "Third-Party Configuration" source "$(FREERTOS_SDK_ROOT)/third-party/Kconfig" +endmenu + +menu "Kernel Configuration" + source "$(FREERTOS_SDK_ROOT)/third-party/freertos/Kconfig" endmenu \ No newline at end of file diff --git a/README.md b/README.md index 9d887122..0ca96c38 100644 --- a/README.md +++ b/README.md @@ -66,9 +66,8 @@ FT-2000/4 是一款面向桌面应用的高性能通用 4 核处理器。每 2 - 集成 34 Lane PCIE3.0 接口:2 个 X16(每个可拆分成 2 个 X8),2 个 X1 - 集成 2 个 GMAC,RGMII 接口,支持 10/100/1000 自适应 - 集成 1 个 SD 卡控制器,兼容 SD 2.0 规范 -- 集成 1 个 HDAudio,支持音频输出,可同时支持最多 4 个 Codec -- 集成 SM2、SM3、SM4 模块 -- 集成 4 个 UART,1 个 LPC,32 个 GPIO,4 个 I2C,1 个 QSPI,2 个通 用 SPI,2 个 WDT,16 个外部中断(和 GPIO 共用 IO) +- 集成 加密计算单元 +- 集成 4 个 UART,32 个 GPIO,4 个 I2C,1 个 QSPI,2 个通 用 SPI,2 个 WDT,16 个外部中断(和 GPIO 共用 IO) - 集成温度传感器 ### 3.2 D2000 @@ -84,38 +83,55 @@ D2000 是一款面向桌面应用的高性能通用 8 核处理器。每 2 个 - 集成 1 个 SD 卡控制器,兼容 SD 2.0 规范 - 集成 1 个 HDAudio,支持音频输出,可同时支持最多 4 个 Codec - 集成 SM2、SM3、SM4、SM9 模块 -- 集成 4 个 UART,1 个 LPC,32 个 GPIO,4 个 I2C,1 个 QSPI,2 个通用 SPI,2 个 WDT,16 个外部中断(和 GPIO 共用 IO) +- 集成 4 个 UART,32 个 GPIO,4 个 I2C,1 个 QSPI,2 个通用 SPI,2 个 WDT,16 个外部中断(和 GPIO 共用 IO) - 集成 2 个温度传感器 -### 3.3 E2000D +### 3.3 E2000Q -- E2000D 1个cluster有2个cpu,共两核。主要技术特征如下: +- E2000Q 集成2个FTC664核和2个FTC310核。主要技术特征如下: - 兼容ARM v8 64 位指令系统,兼容32 位指令 +- 集成 1 路 16 通道 General DMA 和 1 路 8 通道 Device DMA - 支持单精度、双精度浮点运算指令 -- L1有32KB,L2有256KB -- 集成1个DDR4 通道,可对DDR 存储数据进行实时加密 +- 两个 FTC664 核各包含 1MB 私有 L2 Cache,由两个 FTC310 核组成的Cluster 内含 256KB 共享的 L2 Cache +- 集成1个DDR4 通道 +- 集成6Lane PCIE3.0 接口(X4+2*X1 、X2+4*X2、6*X1) +- 集成4个1000M以太网控制器,支持2路SGMII接口和2路SGMII/RGMII接口 +- 集成3路USB2.0(OTG)和2路USB3.0(兼容 2.0) +- 集成2路SATA3.0模块 +- 2路 DisplayPort1.4 接口 +- 集成常用低速接口:WDT、QSPI、PWM、Nand、SD/SDIO/eMMC 、SPI_M、UART、I2C、I2S、MIO、CAN-FD、GPIO、LocalBus、Timer + +### 3.4 E2000D + +- E2000D 集成 2 个 FTC310 核。主要技术特征如下: + +- 兼容ARM v8 64 位指令系统,兼容32 位指令 +- 集成 1 路 16 通道 General DMA 和 1 路 8 通道 Device DMA +- 支持单精度、双精度浮点运算指令 +- L2 Cache 有256KB +- 集成1个DDR4 通道 - 集成4 Lane PCIE3.0 接口(4X1) -- 集成网络接口4x1000M SGMII,1路支持RGMII/RMII,支持1路TSN -- 集成2个USB2.0(OTG)接口 -- 集成1个HDAudio,支持音频输出;2路DP显示接口 +- 集成4个1000M以太网控制器,支持 2 路 SGMII 接口和 2 路 SGMII/RGMII 接口 +- 集成3路USB2.0(OTG)和2路USB3.0(兼容 2.0) - 集成2路SATA3.0模块 -- 集成常用低速接口:WDT,DMAC,QSPI,PWM,Nand,SD/SDIO/eMMC ,SPI_M,UART,I2C,MIO,CAN, LPC_M_S,GPIO,LBC,Timer +- 2路 DisplayPort1.4 接口 +- 集成常用低速接口:WDT,QSPI,PWM,Nand,SD/SDIO/eMMC ,SPI_M,UART,I2C,MIO,CAN-FD,GPIO,LocalBus,Timer -### 3.4 E2000S +### 3.5 E2000S -- E2000S 1个cluster有1个cpu,单核结构。主要技术特征如下: +- E2000S 集成 1 个 FTC310 核,单核结构。主要技术特征如下: - 兼容ARM v8 64 位指令系统,兼容32 位指令 +- 集成 1 路 16 通道 General DMA 和 1 路 8 通道 Device DMA - 支持单精度、双精度浮点运算指令 -- L1有32KB,L2有256KB -- 集成1个DDR4 通道,可对DDR 存储数据进行实时加密 +- L2 Cache 有256KB +- 集成1个DDR4 通道 - 集成2 Lane PCIE3.0 接口(2X1) -- 集成网络接口2x1000M SGMII/RGMII/RMII,支持2路NCSI -- 集成2个USB2.0(OTG)接口 -- 集成1个HDAudio,支持音频输出;2路DP显示接口 -- 集成JPEG Encoder模块 -- 集成常用低速接口:WDT,DMAC,PWM,QSPI,SD/SDIO/eMMC,SPI_M,UART,I2C,MIO,I3C,PMBUS, LPC_M_S,GPIO,oneWire,Timer +- 集成3个1000M以太网控制器,支持1路SGMII接口和2路RGMII/RMII接口 +- 集成1路USB2.0(Device)和2路USB2.0(OTG) +- 2路 DisplayPort1.4 接口 +- 集成常用低速接口:WDT、DMAC、PWM、QSPI、SD/SDIO/eMMC、SPI Master、UART、I2C、MIO、I3C、PMBUS、GPIO、SGPIO、One-Wire、Timer、One-Wire --- @@ -141,12 +157,12 @@ D2000 是一款面向桌面应用的高性能通用 8 核处理器。每 2 个 | LWIP 2.1.2 | FT2000/4
D2000
E2000 | | lwip-2.1.2 | | Letter shell 3.1 | FT2000/4
D2000
E2000 | | letter-shell-3.1 | | Sfud 1.1.0 | FT2000/4
D2000
E2000 | | sfud-1.1.0 | -| Fatfs (RAMSATA) | FT2000/4
D2000
E2000 | | fatfs-0.1.3 | +| Fatfs (RAMSATA) | FT2000/4
D2000
E2000 | | fatfs-0.1.4 | | OpenAMP | FT2000/4
D2000
E2000 | | openamp | | SPIFFS-0.3.7 | FT2000/4
D2000
E2000 | | spiffs-0.3.7 | | TLSF-3.1.0 | FT2000/4
D2000
E2000 | | tlsf-3.1.0 | | Sdmmc-1.0 | E2000 | | sdmmc-1.0 | -| CherryUSB-0.6.0 | E2000 | | cherryusb-0.5.2 | +| CherryUSB-0.6.0 | E2000 | | cherryusb-0.6.0 | --- ## 5. 参考资料 @@ -166,6 +182,14 @@ wangxiaodong1030@phytium.com.cn liushengming1118@phytium.com.cn +wangzongqiang1322@phytium.com.cn + +liqiaozhong1404@phytium.com.cn + +liuzhihong1235@phytium.com.cn + +zhangyan1491@phytium.com.cn + --- ## 7. 许可协议 diff --git a/docs/ChangeLog.md b/docs/ChangeLog.md index 7a59ee87..72023227 100644 --- a/docs/ChangeLog.md +++ b/docs/ChangeLog.md @@ -1,4 +1,156 @@ -# Phytium FreeRTOS SDK 2022-11-11 ChangeLog +# Phytium FreeRTOS SDK 2023-2-9 0.4.0 ChangeLog + +Change Log sinc 2023-2-6 + +## example +- freertos_feature/queue readme update +- peripheral/spi readme update +- peripheral/spi e2000d_aarch32_eg_configs update(CONFIG_SFUD_CTRL_FSPIM=y) + +# Phytium FreeRTOS SDK 2023-2-8 ChangeLog + +Change Log sinc 2023-2-5 + +## example +- modify qspi_spiffs example +- modify qspi example + +## driver +- modify can example + +# Phytium FreeRTOS SDK 2023-2-6 ChangeLog + +Change Log sinc 2023-1-30 + +## driver +- add developer information in file header +- add file description in file header +- all .c .h file format update +- print interface check +- print statement syntax checking and punctuation supplementation +## example +- all example xxxx_eg_configs update +- all example sdkconfig sdkconfig.h update +- add developer information in file header +- add file description in file header +- all .c .h file format update +- print interface check +- print statement syntax checking and punctuation supplementation +## third-party +- add developer information in file header +- add file description in file header +- all .c .h file format update +- third-party/lwip-2.1.2/ports/arch/cc.h modified +- print interface check +- print statement syntax checking and punctuation supplementation +## install.py +- modefiy the standalone_sdk_v、standalone_branche、standalone_remote value +- add script statements which can delete standalone/third-party/lwip-2.1.2/ports/arch dir +# Phytium FreeRTOS SDK 2023-1-6 ChangeLog + +Change Log sinc 2023-1-5 + +## third-party + +add lvgl and modify the third-party.mk and the Kconfig + +## example +## driver + +add the media example and driver,modify the corresponding config + +# Phytium FreeRTOS SDK 2023-1-5 ChangeLog + +Change Log sinc 2023-1-3 + +## example +- network part adjust. add new example lwip_startup +- delete xmac_lwip_test. +- delete gmac_lwip_test. + +## third-party +- lwip-2.1.2 ports part adjust. +- delete lwip-2.1.2/api. +- delete lwip-2.1.2/apps. +- delete lwip-2.1.2/core. + +## drivers +- add fgmac_os. +- add fxmac_os. + +# Phytium FreeRTOS SDK 2023-1-3 ChangeLog + +Change Log sinc 2022-12-28 + +## third-party + +- Fix freertos interrupt priority get and mask function in port.c + +# Phytium FreeRTOS SDK 2022-12-28 ChangeLog + +- add sata fatfs_0.1.4 port +- delete fatfs_0.1.3 content +- delete storage/sata_fatfs content + +# Phytium FreeRTOS SDK 2022-12-7 ChangeLog + +Change Log sinc 2022-12-6 + +## third-party + +- Add FPU support by configUSE_TASK_FPU_SUPPORT in kernel configuration + +# Phytium FreeRTOS SDK 2022-12-6 ChangeLog + +Change Log sinc 2022-12-6 + +## example +## driver + +- Adapt fparameters.h in standalone sdk + +# Phytium FreeRTOS SDK 2022-11-28 ChangeLog + +Change Log since 2022-11-25 + +## example + +- add fatfs tests (usb/sdio) + +## driver + +- remove mmc driver, its implementation has been moved to sdmmc ports + +## third-party + +- add fatfs 0.1.4 freertos port +- add sdmmc 1.0 freertos port + +# Phytium FreeRTOS SDK 2022-11-25 ChangeLog + +Change Log sinc 2022-11-17 + +## example + +- add i2c example +- add timer_tacho example + +## driver + +- add i2c os driver +- add timer_tacho driver + +# Phytium FreeRTOS SDK 2022-11-17 ChangeLog + +Change Log sinc 2022-11-16 + +## third-party + +- Add kernel configuration in menuconfig +- Rename the "FreeRTOS Setting" to "Third-Party Configuration" in menuconfig +- Rename cmd_os_stats.c to cmd_ps.c + +# Phytium FreeRTOS SDK 2022-11-11 0.3.0 ChangeLog Change Log sinc 2022-11-11 diff --git a/drivers/Kconfig b/drivers/Kconfig index b7b47d22..01d83bad 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -34,9 +34,16 @@ endmenu menu "Freertos Eth Drivers" config FREERTOS_USE_XMAC + select ENABLE_FXMAC bool prompt "Use Freertos xmac driver" default n + + config FREERTOS_USE_GMAC + select ENABLE_FGMAC + bool + prompt "Use Freertos gmac driver" + default n endmenu menu "Freertos Gpio Drivers" @@ -67,13 +74,6 @@ menu "Freertos DMA Drivers" default n endmenu -menu "Freertos MMC Drivers" - config FREERTOS_USE_FSDIO - bool - prompt "Use Freertos sdio driver" - default n -endmenu - menu "Freertos Adc Drivers" config FREERTOS_USE_ADC bool @@ -90,4 +90,26 @@ menu "Freertos Can Drivers" default n select USE_CAN select USE_FCAN -endmenu \ No newline at end of file +endmenu + +menu "Freertos I2c Drivers" + config FREERTOS_USE_I2C + bool + prompt "Use Freertos i2c driver" + default n +endmenu + +menu "Freertos Mio Drivers" + config FREERTOS_USE_MIO + bool + prompt "Use Freertos mio driver" + default n +endmenu + +menu "Freertos Timer Drivers" + config FREERTOS_USE_TIMER + bool + prompt "Use Freertos timer driver" + default n +endmenu + diff --git a/drivers/adc/fadc_os.c b/drivers/adc/fadc_os.c index 4678a9fe..5c1e7217 100644 --- a/drivers/adc/fadc_os.c +++ b/drivers/adc/fadc_os.c @@ -1,24 +1,26 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: fadc_os.c * Date: 2022-08-24 16:50:19 * LastEditTime: 2022-08-26 16:59:51 - * Description:  This file is for - * - * Modify History: + * Description:  This file is for required function implementations of adc driver used in FreeRTOS. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/08/31 first commit + * 1.1 wangxiaodong 2022/11/01 file name adaptation */ #include #include @@ -50,7 +52,7 @@ #define FREERTOS_ADC_CTRL_INTR_ENABLE (8) /* enable adc interrupt */ #define FREERTOS_ADC_CTRL_INTR_DISABLE (9) /* disable adc interrupt */ -static FFreeRTOSAdc os_adc[FADC_INSTANCE_NUM] = {0}; +static FFreeRTOSAdc os_adc[FADC_NUM] = {0}; /** * @name: FFreeRTOSAdcControl @@ -64,16 +66,16 @@ static FError FFreeRTOSAdcControl(FFreeRTOSAdc *os_adc_p, int cmd, void *arg) { FError ret = FADC_SUCCESS; FFreeRTOSAdcConfig *configuration = (FFreeRTOSAdcConfig *)arg; - + /* New contrl can be performed only after current one is finished */ if (pdFALSE == xSemaphoreTake(os_adc_p->adc_semaphore, portMAX_DELAY)) { - FADC_ERROR("Adc xSemaphoreTake failed\r\n"); + FADC_ERROR("Adc xSemaphoreTake failed."); /* We could not take the semaphore, exit with 0 data received */ return FREERTOS_ADC_SEM_ERROR; } - switch (cmd) + switch (cmd) { case FREERTOS_ADC_CTRL_SET: ret = FAdcVariableConfig(&os_adc_p->adc_ctrl, &configuration->convert_config); @@ -102,7 +104,7 @@ static FError FFreeRTOSAdcControl(FFreeRTOSAdc *os_adc_p, int cmd, void *arg) case FREERTOS_ADC_CTRL_READ: ret = FAdcReadConvertResult(&os_adc_p->adc_ctrl, configuration->channel, &configuration->value); break; - + case FREERTOS_ADC_CTRL_INTR_ENABLE: ret = FAdcInterruptEnable(&os_adc_p->adc_ctrl, configuration->channel, configuration->event_type); break; @@ -112,7 +114,7 @@ static FError FFreeRTOSAdcControl(FFreeRTOSAdc *os_adc_p, int cmd, void *arg) break; default: - FADC_ERROR("invalid cmd."); + FADC_ERROR("Invalid cmd."); ret = FADC_ERR_NOT_SUPPORT; break; } @@ -121,7 +123,7 @@ static FError FFreeRTOSAdcControl(FFreeRTOSAdc *os_adc_p, int cmd, void *arg) if (pdFALSE == xSemaphoreGive(os_adc_p->adc_semaphore)) { /* We could not post the semaphore, exit with error */ - FADC_ERROR("Adc xSemaphoreGive failed\r\n"); + FADC_ERROR("Adc xSemaphoreGive failed."); return FREERTOS_ADC_SEM_ERROR; } @@ -163,7 +165,7 @@ static FError FFreeRTOSAdcConvertStart(FFreeRTOSAdc *os_adc_p, boolean state) FASSERT(os_adc_p->adc_semaphore != NULL); FError ret = FADC_SUCCESS; - if (state==TRUE) + if (state == TRUE) { ret = FFreeRTOSAdcControl(os_adc_p, FREERTOS_ADC_CTRL_START, NULL); } @@ -195,7 +197,7 @@ static FError FFreeRTOSAdcChannelThresholdSet(FFreeRTOSAdc *os_adc_p, FAdcChanne configuration.threshold_config = *threshold_config_p; ret = FFreeRTOSAdcControl(os_adc_p, FREERTOS_ADC_CTRL_CHANNEL_THRESHOLD_SET, &configuration); - + return ret; } @@ -218,7 +220,7 @@ static FError FFreeRTOSAdcChannelEnable(FFreeRTOSAdc *os_adc_p, FAdcChannel chan memset(&configuration, 0, sizeof(configuration)); configuration.channel = channel; - if (state==TRUE) + if (state == TRUE) { ret = FFreeRTOSAdcControl(os_adc_p, FREERTOS_ADC_CTRL_CHANNEL_ENABLE, &configuration); } @@ -226,7 +228,7 @@ static FError FFreeRTOSAdcChannelEnable(FFreeRTOSAdc *os_adc_p, FAdcChannel chan { ret = FFreeRTOSAdcControl(os_adc_p, FREERTOS_ADC_CTRL_CHANNEL_DISABLE, &configuration); } - + return ret; } @@ -251,7 +253,7 @@ static FError FFreeRTOSAdcInterruptEnable(FFreeRTOSAdc *os_adc_p, FAdcChannel ch configuration.channel = channel; configuration.event_type = event_type; - if (state==TRUE) + if (state == TRUE) { ret = FFreeRTOSAdcControl(os_adc_p, FREERTOS_ADC_CTRL_INTR_ENABLE, &configuration); } @@ -271,7 +273,7 @@ static FError FFreeRTOSAdcInterruptEnable(FFreeRTOSAdc *os_adc_p, FAdcChannel ch */ FFreeRTOSAdc *FFreeRTOSAdcInit(u32 instance_id) { - FASSERT(instance_id < FADC_INSTANCE_NUM); + FASSERT(instance_id < FADC_NUM); FASSERT(FT_COMPONENT_IS_READY != os_adc[instance_id].adc_ctrl.is_ready); FAdcConfig pconfig; @@ -280,7 +282,7 @@ FFreeRTOSAdc *FFreeRTOSAdcInit(u32 instance_id) FASSERT(FAdcCfgInitialize(&os_adc[instance_id].adc_ctrl, &pconfig) == FT_SUCCESS); FASSERT((os_adc[instance_id].adc_semaphore = xSemaphoreCreateMutex()) != NULL); - + return (&os_adc[instance_id]); } @@ -296,12 +298,12 @@ FError FFreeRTOSAdcDeinit(FFreeRTOSAdc *os_adc_p) FASSERT(os_adc_p->adc_semaphore != NULL); /* stop adc convert */ - FFreeRTOSAdcConvertStart(os_adc_p, FALSE); + FFreeRTOSAdcConvertStart(os_adc_p, FALSE); FAdcDeInitialize(&os_adc_p->adc_ctrl); vSemaphoreDelete(os_adc_p->adc_semaphore); memset(os_adc_p, 0, sizeof(*os_adc_p)); - + return FADC_SUCCESS; } @@ -325,7 +327,7 @@ FError FFreeRTOSAdcRead(FFreeRTOSAdc *os_adc_p, FAdcChannel channel, u16 *val) configuration.channel = channel; ret = FFreeRTOSAdcControl(os_adc_p, FREERTOS_ADC_CTRL_READ, &configuration); - if(ret == FADC_SUCCESS) + if (ret == FADC_SUCCESS) { *val = configuration.value; } @@ -349,42 +351,42 @@ FError FFreeRTOSAdcSet(FFreeRTOSAdc *os_adc_p, FFreeRTOSAdcConfig *adc_cfg_p) FASSERT(channel < FADC_CHANNEL_NUM); ret = FFreeRTOSAdcControllerSet(os_adc_p, &adc_cfg_p->convert_config); - if (FADC_SUCCESS != ret) - { - FADC_ERROR("FFreeRTOSAdcControllerSet failed\n"); - return FADC_ERR_CMD_FAILED; - } + if (FADC_SUCCESS != ret) + { + FADC_ERROR("FFreeRTOSAdcControllerSet failed."); + return FADC_ERR_CMD_FAILED; + } ret = FFreeRTOSAdcChannelThresholdSet(os_adc_p, channel, &adc_cfg_p->threshold_config); - if (FADC_SUCCESS != ret) - { - FADC_ERROR("FAdcChannelThresholdSet failed\n"); + if (FADC_SUCCESS != ret) + { + FADC_ERROR("FAdcChannelThresholdSet failed."); return FADC_ERR_CMD_FAILED; - } + } /* enable adc channel */ - ret = FFreeRTOSAdcChannelEnable(os_adc_p, channel, TRUE); + ret = FFreeRTOSAdcChannelEnable(os_adc_p, channel, TRUE); if (FADC_SUCCESS != ret) - { - FADC_ERROR("FFreeRTOSAdcChannelEnable failed\n"); + { + FADC_ERROR("FFreeRTOSAdcChannelEnable failed."); return FADC_ERR_CMD_FAILED; - } + } - /* enable adc convert finish interrupt to know whether the convert is completed */ - ret = FFreeRTOSAdcInterruptEnable(os_adc_p, channel, adc_cfg_p->event_type, TRUE); + /* enable adc convert finish interrupt to know whether the convert is completed */ + ret = FFreeRTOSAdcInterruptEnable(os_adc_p, channel, adc_cfg_p->event_type, TRUE); if (FADC_SUCCESS != ret) - { - FADC_ERROR("FFreeRTOSAdcInterruptEnable failed\n"); + { + FADC_ERROR("FFreeRTOSAdcInterruptEnable failed."); return FADC_ERR_CMD_FAILED; - } + } - /* start adc convert */ + /* start adc convert */ ret = FFreeRTOSAdcConvertStart(os_adc_p, TRUE); if (FADC_SUCCESS != ret) - { - FADC_ERROR("FFreeRTOSAdcConvertStart failed\n"); + { + FADC_ERROR("FFreeRTOSAdcConvertStart failed."); return FADC_ERR_CMD_FAILED; - } - + } + return ret; } \ No newline at end of file diff --git a/drivers/adc/fadc_os.h b/drivers/adc/fadc_os.h index c3c98e9e..37f6a28a 100644 --- a/drivers/adc/fadc_os.h +++ b/drivers/adc/fadc_os.h @@ -1,28 +1,30 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: fadc_os.h * Date: 2022-08-24 16:42:19 * LastEditTime: 2022-08-26 17:59:12 - * Description:  This file is for - * - * Modify History: + * Description:  This file is for providing function related definitions of adc driver used in FreeRTOS. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/08/31 first commit + * 1.1 wangxiaodong 2022/11/01 file name adaptation */ -#ifndef DRIVERS_FADC_OS_H -#define DRIVERS_FADC_OS_H +#ifndef FADC_OS_H +#define FADC_OS_H #include #include @@ -31,6 +33,11 @@ #include "ftypes.h" #include "fparameters.h" +#ifdef __cplusplus +extern "C" +{ +#endif + /* freertos adc error */ #define FREERTOS_ADC_SEM_ERROR FT_CODE_ERR(ErrModBsp, ErrBspAdc, 10) @@ -39,12 +46,12 @@ typedef struct { - FAdcChannel channel; + FAdcChannel channel; u16 value; FAdcConvertConfig convert_config; /* adc convert config */ FAdcThresholdConfig threshold_config; /* adc channel threshold config */ FAdcIntrEventType event_type; /* adc interrupt event type */ -}FFreeRTOSAdcConfig; +} FFreeRTOSAdcConfig; typedef struct { @@ -64,5 +71,8 @@ FError FFreeRTOSAdcSet(FFreeRTOSAdc *os_adc_p, FFreeRTOSAdcConfig *adc_cfg_p); /* adc channel convert result read */ FError FFreeRTOSAdcRead(FFreeRTOSAdc *os_adc_p, FAdcChannel channel, u16 *val); +#ifdef __cplusplus +} +#endif #endif // ! diff --git a/drivers/can/fcan_os.c b/drivers/can/fcan_os.c index 79ccc47d..ef068d21 100644 --- a/drivers/can/fcan_os.c +++ b/drivers/can/fcan_os.c @@ -1,24 +1,27 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: fcan_os.c * Date: 2022-09-15 14:20:19 * LastEditTime: 2022-09-21 16:59:51 - * Description:  This file is for - * - * Modify History: + * Description:  This file is for required function implementations of can driver used in FreeRTOS. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/09/23 first commit + * 1.1 wangxiaodong 2022/11/01 file name adaptation + * 1.2 zhangyan 2023/2/7 improve functions */ #include #include @@ -39,7 +42,7 @@ #define FCAN_INFO(format, ...) FT_DEBUG_PRINT_I(FCAN_DEBUG_TAG, format, ##__VA_ARGS__) #define FCAN_DEBUG(format, ...) FT_DEBUG_PRINT_D(FCAN_DEBUG_TAG, format, ##__VA_ARGS__) -static FFreeRTOSCan os_can[FCAN_INSTANCE_NUM] = {0}; +static FFreeRTOSCan os_can[FCAN_NUM] = {0}; /** * @name: FFreeRTOSCanInit @@ -49,7 +52,7 @@ static FFreeRTOSCan os_can[FCAN_INSTANCE_NUM] = {0}; */ FFreeRTOSCan *FFreeRTOSCanInit(u32 instance_id) { - FASSERT(instance_id < FCAN_INSTANCE_NUM); + FASSERT(instance_id < FCAN_NUM); FASSERT(FT_COMPONENT_IS_READY != os_can[instance_id].can_ctrl.is_ready); FCanConfig pconfig; @@ -96,16 +99,17 @@ FError FFreeRTOSCanControl(FFreeRTOSCan *os_can_p, int cmd, void *arg) FCanIdMaskConfig *id_mask_p; FCanIntrEventConfig *intr_event_p; boolean use_canfd; + u32 *tran_mode; /* New contrl can be performed only after current one is finished */ if (pdFALSE == xSemaphoreTake(os_can_p->can_semaphore, portMAX_DELAY)) { - FCAN_ERROR("Can xSemaphoreTake failed\r\n"); + FCAN_ERROR("Can xSemaphoreTake failed."); /* We could not take the semaphore, exit with 0 data received */ return FREERTOS_CAN_SEM_ERROR; } - switch (cmd) + switch (cmd) { case FREERTOS_CAN_CTRL_ENABLE: FCanEnable(&os_can_p->can_ctrl, TRUE); @@ -133,6 +137,11 @@ FError FFreeRTOSCanControl(FFreeRTOSCan *os_can_p, int cmd, void *arg) case FREERTOS_CAN_CTRL_ID_MASK_ENABLE: FCanIdMaskFilterEnable(&os_can_p->can_ctrl); break; + + case FREERTOS_CAN_CTRL_MODE_SET: + tran_mode = (u32*)arg; + FCanSetMode(&os_can_p->can_ctrl, *tran_mode); + break; case FREERTOS_CAN_CTRL_INTR_SET: intr_event_p = (FCanIntrEventConfig *)arg; @@ -145,7 +154,7 @@ FError FFreeRTOSCanControl(FFreeRTOSCan *os_can_p, int cmd, void *arg) FCanFdEnable(&os_can_p->can_ctrl, use_canfd); break; default: - FCAN_ERROR("invalid cmd."); + FCAN_ERROR("Invalid cmd."); ret = FCAN_INVAL_PARAM; break; } @@ -154,7 +163,7 @@ FError FFreeRTOSCanControl(FFreeRTOSCan *os_can_p, int cmd, void *arg) if (pdFALSE == xSemaphoreGive(os_can_p->can_semaphore)) { /* We could not post the semaphore, exit with error */ - FCAN_ERROR("Can xSemaphoreGive failed\r\n"); + FCAN_ERROR("Can xSemaphoreGive failed."); return FREERTOS_CAN_SEM_ERROR; } @@ -180,7 +189,7 @@ FError FFreeRTOSCanSend(FFreeRTOSCan *os_can_p, FCanFrame *frame_p) /* New contrl can be performed only after current one is finished */ if (pdFALSE == xSemaphoreTake(os_can_p->can_semaphore, portMAX_DELAY)) { - FCAN_ERROR("Can xSemaphoreTake failed\r\n"); + FCAN_ERROR("Can xSemaphoreTake failed."); /* We could not take the semaphore, exit with 0 data received */ return FREERTOS_CAN_SEM_ERROR; } @@ -188,14 +197,14 @@ FError FFreeRTOSCanSend(FFreeRTOSCan *os_can_p, FCanFrame *frame_p) ret = FCanSend(&os_can_p->can_ctrl, frame_p); if (ret != FCAN_SUCCESS) { - FCAN_ERROR("Can send failed\r\n"); + FCAN_ERROR("Can send failed."); } /* Enable next contrl. Current one is finished */ if (pdFALSE == xSemaphoreGive(os_can_p->can_semaphore)) { /* We could not post the semaphore, exit with error */ - FCAN_ERROR("Can xSemaphoreGive failed\r\n"); + FCAN_ERROR("Can xSemaphoreGive failed."); return FREERTOS_CAN_SEM_ERROR; } @@ -221,7 +230,7 @@ FError FFreeRTOSCanRecv(FFreeRTOSCan *os_can_p, FCanFrame *frame_p) /* New contrl can be performed only after current one is finished */ if (pdFALSE == xSemaphoreTake(os_can_p->can_semaphore, portMAX_DELAY)) { - FCAN_ERROR("Can xSemaphoreTake failed\r\n"); + FCAN_ERROR("Can xSemaphoreTake failed."); /* We could not take the semaphore, exit with 0 data received */ return FREERTOS_CAN_SEM_ERROR; } @@ -229,14 +238,14 @@ FError FFreeRTOSCanRecv(FFreeRTOSCan *os_can_p, FCanFrame *frame_p) ret = FCanRecv(&os_can_p->can_ctrl, frame_p); if (ret != FCAN_SUCCESS) { - FCAN_ERROR("Can recv failed\r\n"); + FCAN_ERROR("Can recv failed."); } /* Enable next contrl. Current one is finished */ if (pdFALSE == xSemaphoreGive(os_can_p->can_semaphore)) { /* We could not post the semaphore, exit with error */ - FCAN_ERROR("Can xSemaphoreGive failed\r\n"); + FCAN_ERROR("Can xSemaphoreGive failed."); return FREERTOS_CAN_SEM_ERROR; } diff --git a/drivers/can/fcan_os.h b/drivers/can/fcan_os.h index 19d85a00..c829e89f 100644 --- a/drivers/can/fcan_os.h +++ b/drivers/can/fcan_os.h @@ -1,28 +1,31 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: fcan_os.h * Date: 2022-09-16 11:40:19 * LastEditTime: 2022-09-21 16:59:58 - * Description:  This file is for - * - * Modify History: + * Description:  This file is for providing function related definitions of can driver used in FreeRTOS. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/09/23 first commit + * 1.1 wangxiaodong 2022/11/01 file name adaptation + * 1.2 zhangyan 2023/2/7 improve functions */ -#ifndef DRIVERS_FCAN_OS_H -#define DRIVERS_FCAN_OS_H +#ifndef FCAN_OS_H +#define FCAN_OS_H #include #include @@ -30,6 +33,11 @@ #include "fcan.h" #include "ftypes.h" +#ifdef __cplusplus +extern "C" +{ +#endif + /* freertos can error */ #define FREERTOS_CAN_OK FT_SUCCESS #define FREERTOS_CAN_SEM_ERROR FT_CODE_ERR(ErrModBsp, ErrBspCan, 10) @@ -49,6 +57,7 @@ enum FREERTOS_CAN_CTRL_INTR_SET, /* set can interrupt handler */ FREERTOS_CAN_CTRL_INTR_ENABLE, /* enable can interrupt */ FREERTOS_CAN_CTRL_FD_ENABLE, /* set can fd enable */ + FREERTOS_CAN_CTRL_MODE_SET, /* set can transmit mode */ FREERTOS_CAN_CTRL_NUM }; @@ -73,5 +82,8 @@ FError FFreeRTOSCanSend(FFreeRTOSCan *os_can_p, FCanFrame *frame_p); /* can receive frame */ FError FFreeRTOSCanRecv(FFreeRTOSCan *os_can_p, FCanFrame *frame_p); +#ifdef __cplusplus +} +#endif #endif // ! diff --git a/drivers/dma/fddma/fddma_os.c b/drivers/dma/fddma/fddma_os.c index a25648b5..2f1ef000 100644 --- a/drivers/dma/fddma/fddma_os.c +++ b/drivers/dma/fddma/fddma_os.c @@ -1,22 +1,22 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: fddma_os.c * Date: 2022-07-18 08:51:25 * LastEditTime: 2022-07-18 08:51:25 - * Description:  This files is for - * - * Modify History: + * Description:  This file is for required function implementations of ddma driver used in FreeRTOS. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- * 1.0 zhugengyu 2022/7/27 init commit @@ -50,10 +50,10 @@ static FFreeRTOSDdma ddma[FDDMA_INSTANCE_NUM]; /************************** Function Prototypes ******************************/ static inline FError FDdmaOsTakeSema(SemaphoreHandle_t locker) { - FASSERT_MSG((NULL != locker), "locker not exists"); + FASSERT_MSG((NULL != locker), "Locker not exists."); if (pdFALSE == xSemaphoreTake(locker, portMAX_DELAY)) { - FDDMA_ERROR("failed to give locker !!!"); + FDDMA_ERROR("Failed to give locker!!!"); return FFREERTOS_DDMA_SEMA_ERR; } @@ -62,10 +62,10 @@ static inline FError FDdmaOsTakeSema(SemaphoreHandle_t locker) static inline void FDdmaOsGiveSema(SemaphoreHandle_t locker) { - FASSERT_MSG((NULL != locker), "locker not exists"); + FASSERT_MSG((NULL != locker), "Locker not exists."); if (pdFALSE == xSemaphoreGive(locker)) { - FDDMA_ERROR("failed to give locker !!!"); + FDDMA_ERROR("Failed to give locker!!!"); } return; @@ -74,7 +74,7 @@ static inline void FDdmaOsGiveSema(SemaphoreHandle_t locker) /*****************************************************************************/ static void FDdmaOsSetupInterrupt(FDdma *const instance) { - FASSERT(instance); + FASSERT(instance); FDdmaConfig *config = &instance->config; uintptr base_addr = config->base_addr; u32 cpu_id = 0; @@ -85,15 +85,15 @@ static void FDdmaOsSetupInterrupt(FDdma *const instance) InterruptSetPriority(config->irq_num, config->irq_prority); /* register intr callback */ - InterruptInstall(config->irq_num, - FDdmaIrqHandler, - instance, + InterruptInstall(config->irq_num, + FDdmaIrqHandler, + instance, NULL); /* enable ddma0 irq */ InterruptUmask(config->irq_num); - FDDMA_INFO("ddma interrupt setup done !!!"); + FDDMA_INFO("ddma interrupt setup done!!!"); return; } @@ -127,12 +127,12 @@ FFreeRTOSDdma *FFreeRTOSDdmaInit(u32 id, const FFreeRTOSDdmaConfig *input_config err = FDdmaCfgInitialization(ctrl, &config); if (FDDMA_SUCCESS != err) { - FDDMA_ERROR("init ddma-%d failed, err: 0x%x !!!", id, err); + FDDMA_ERROR("Init ddma-%d failed, err: 0x%x!!!", id, err); goto err_exit; } - FASSERT_MSG(NULL == instance->locker, "locker exists !!!"); - FASSERT_MSG((instance->locker = xSemaphoreCreateMutex()) != NULL, "create mutex failed !!!"); + FASSERT_MSG(NULL == instance->locker, "Locker exists!!!"); + FASSERT_MSG((instance->locker = xSemaphoreCreateMutex()) != NULL, "Create mutex failed!!!"); FDdmaOsSetupInterrupt(ctrl); @@ -156,14 +156,14 @@ FError FFreeRTOSDdmaDeinit(FFreeRTOSDdma *const instance) if (FT_COMPONENT_IS_READY != ctrl->is_ready) { - FDDMA_ERROR("ddma-%d not yet init !!!", ctrl->config.id); + FDDMA_ERROR("ddma-%d not yet init!!!", ctrl->config.id); return FFREERTOS_DDMA_NOT_INIT; } /* no scheduler during deinit */ - taskENTER_CRITICAL(); + taskENTER_CRITICAL(); - FASSERT_MSG(NULL != instance->locker, "locker not exists !!!"); + FASSERT_MSG(NULL != instance->locker, "Locker not exists!!!"); /* disable ddma irq */ FDdmaStop(ctrl); @@ -199,31 +199,33 @@ FError FFreeRTOSDdmaSetupChannel(FFreeRTOSDdma *const instance, u32 chan_id, con err = FDdmaOsTakeSema(instance->locker); if (FFREERTOS_DDMA_OK != err) + { return err; + } /* parpare channel configs */ chan_config->id = chan_id; chan_config->slave_id = request->slave_id; - FASSERT_MSG((0 != request->mem_addr), "invaild memory address"); + FASSERT_MSG((0 != request->mem_addr), "Invaild memory address."); chan_config->ddr_addr = request->mem_addr; chan_config->dev_addr = request->dev_addr; chan_config->req_mode = request->is_rx ? FDDMA_CHAN_REQ_RX : FDDMA_CHAN_REQ_TX; chan_config->timeout = 0xffff; - chan_config->trans_len = request->trans_len; + chan_config->trans_len = request->trans_len; FDDMA_INFO("channel: %d, slave id: %d, ddr: 0x%x, dev: 0x%x, req mode: %s, trans len: %d", - chan_config->id, - chan_config->slave_id, - chan_config->ddr_addr, - chan_config->dev_addr, - (FDDMA_CHAN_REQ_TX == chan_config->req_mode) ? "mem=>dev" : "dev=>mem", - chan_config->trans_len); + chan_config->id, + chan_config->slave_id, + chan_config->ddr_addr, + chan_config->dev_addr, + (FDDMA_CHAN_REQ_TX == chan_config->req_mode) ? "mem=>dev" : "dev=>mem", + chan_config->trans_len); /* allocate channel */ err = FDdmaAllocateChan(ctrl, chan, chan_config); if (FDDMA_SUCCESS != err) { - FDDMA_ERROR("channel bind failed: 0x%x", err); + FDDMA_ERROR("Channel bind failed: 0x%x", err); goto err_exit; } @@ -252,25 +254,27 @@ FError FFreeRTOSDdmaRevokeChannel(FFreeRTOSDdma *const instance, u32 chan_id) err = FDdmaOsTakeSema(instance->locker); if (FFREERTOS_DDMA_OK != err) + { return err; + } err = FDdmaDeactiveChan(chan); /* deactive channel in use */ if (FDDMA_SUCCESS != err) { - FDDMA_ERROR("channel deactive failed: 0x%x", err); + FDDMA_ERROR("Channel deactive failed: 0x%x", err); goto err_exit; } err = FDdmaDellocateChan(chan); /* free channel resource */ if (FDDMA_SUCCESS != err) { - FDDMA_ERROR("channel deallocate failed: 0x%x", err); + FDDMA_ERROR("Channel deallocate failed: 0x%x", err); goto err_exit; } err_exit: FDdmaOsGiveSema(instance->locker); - return err; + return err; } /** @@ -289,7 +293,9 @@ FError FFreeRTOSDdmaStartChannel(FFreeRTOSDdma *const instance, u32 chan_id) err = FDdmaOsTakeSema(instance->locker); if (FFREERTOS_DDMA_OK != err) + { return err; + } /* active all channel allocated */ chan = ctrl->chan[chan_id]; @@ -298,21 +304,21 @@ FError FFreeRTOSDdmaStartChannel(FFreeRTOSDdma *const instance, u32 chan_id) err = FDdmaActiveChan(chan); /* active channel if in use */ if (FDDMA_SUCCESS != err) { - FDDMA_ERROR("channel start failed: 0x%x", err); + FDDMA_ERROR("Channel start failed: 0x%x", err); goto err_exit; - } + } } err = FDdmaStart(ctrl); /* start ddma controller */ if (FDDMA_SUCCESS != err) { - FDDMA_ERROR("start ddma failed: 0x%x", err); + FDDMA_ERROR("Start ddma failed: 0x%x", err); goto err_exit; - } + } err_exit: FDdmaOsGiveSema(instance->locker); - return err; + return err; } FError FFreeRTOSDdmaStopChannel(FFreeRTOSDdma *const instance, u32 chan_id) @@ -325,7 +331,9 @@ FError FFreeRTOSDdmaStopChannel(FFreeRTOSDdma *const instance, u32 chan_id) err = FDdmaOsTakeSema(instance->locker); if (FFREERTOS_DDMA_OK != err) + { return err; + } /* deactive all channel allocated */ chan = ctrl->chan[chan_id]; @@ -334,14 +342,14 @@ FError FFreeRTOSDdmaStopChannel(FFreeRTOSDdma *const instance, u32 chan_id) err = FDdmaDeactiveChan(chan); /* deactive channel if in use */ if (FDDMA_SUCCESS != err) { - FDDMA_ERROR("channel start failed: 0x%x", err); + FDDMA_ERROR("Channel start failed: 0x%x", err); goto err_exit; - } + } } err_exit: FDdmaOsGiveSema(instance->locker); - return err; + return err; } /** @@ -361,16 +369,18 @@ FError FFreeRTOSDdmaStop(FFreeRTOSDdma *const instance) err = FDdmaOsTakeSema(instance->locker); if (FFREERTOS_DDMA_OK != err) + { return err; + } err = FDdmaStop(ctrl); /* stop ddma controller */ if (FDDMA_SUCCESS != err) { - FDDMA_ERROR("stop ddma failed: 0x%x", err); + FDDMA_ERROR("Stop ddma failed: 0x%x", err); goto err_exit; } err_exit: FDdmaOsGiveSema(instance->locker); - return err; + return err; } \ No newline at end of file diff --git a/drivers/dma/fddma/fddma_os.h b/drivers/dma/fddma/fddma_os.h index c6595646..5334e86f 100644 --- a/drivers/dma/fddma/fddma_os.h +++ b/drivers/dma/fddma/fddma_os.h @@ -1,34 +1,29 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: fddma_os.h * Date: 2022-07-20 09:15:37 * LastEditTime: 2022-07-20 09:15:38 - * Description:  This files is for - * - * Modify History: + * Description:  This files is for providing function related definitions of ddma driver used in FreeRTOS. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- * 1.0 zhugengyu 2022/7/27 init commit */ -#ifndef DRIVERS_FDDMA_OS_H -#define DRIVERS_FDDMA_OS_H - -#ifdef __cplusplus -extern "C" -{ -#endif +#ifndef FDDMA_OS_H +#define FDDMA_OS_H /***************************** Include Files *********************************/ #include #include @@ -36,8 +31,12 @@ extern "C" #include "fparameters.h" #include "fddma.h" - /************************** Constant Definitions *****************************/ +#ifdef __cplusplus +extern "C" +{ +#endif + #define FFREERTOS_DDMA_OK FT_SUCCESS #define FFREERTOS_DDMA_NOT_INIT FT_CODE_ERR(ErrModPort, ErrDdma, 0) #define FFREERTOS_DDMA_SEMA_ERR FT_CODE_ERR(ErrModPort, ErrDdma, 1) @@ -50,7 +49,7 @@ extern "C" typedef struct { - + } FFreeRTOSDdmaConfig; /* freertos ddma config, reserved for future use */ typedef struct diff --git a/drivers/dma/fgdma/fgdma_os.c b/drivers/dma/fgdma/fgdma_os.c index 99c2f92e..8a14cbf3 100644 --- a/drivers/dma/fgdma/fgdma_os.c +++ b/drivers/dma/fgdma/fgdma_os.c @@ -1,22 +1,22 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: fgdma_os.c * Date: 2022-07-20 10:54:31 * LastEditTime: 2022-07-20 10:54:31 - * Description:  This files is for - * - * Modify History: + * Description:  This file is for required function implementations of gdma driver used in FreeRTOS. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- * 1.0 zhugengyu 2022/7/27 init commit @@ -56,10 +56,10 @@ static FFreeRTOSGdma gdma[FGDMA_INSTANCE_NUM]; /*****************************************************************************/ static inline FError FGdmaOsTakeSema(SemaphoreHandle_t locker) { - FASSERT_MSG((NULL != locker), "locker not exists"); + FASSERT_MSG((NULL != locker), "Locker not exists."); if (pdFALSE == xSemaphoreTake(locker, portMAX_DELAY)) { - FGDMA_ERROR("failed to take locker !!!"); + FGDMA_ERROR("Failed to take locker!!!"); return FFREERTOS_GDMA_SEMA_ERR; } @@ -68,10 +68,10 @@ static inline FError FGdmaOsTakeSema(SemaphoreHandle_t locker) static inline void FGdmaOsGiveSema(SemaphoreHandle_t locker) { - FASSERT_MSG((NULL != locker), "locker not exists"); + FASSERT_MSG((NULL != locker), "Locker not exists."); if (pdFALSE == xSemaphoreGive(locker)) { - FGDMA_ERROR("failed to give locker !!!"); + FGDMA_ERROR("Failed to give locker!!!"); } return; @@ -79,7 +79,7 @@ static inline void FGdmaOsGiveSema(SemaphoreHandle_t locker) static void FGdmaOsSetupInterrupt(FGdma *const ctrl) { - FASSERT(ctrl); + FASSERT(ctrl); FGdmaConfig *config = &ctrl->config; uintptr base_addr = config->base_addr; u32 cpu_id = 0; @@ -92,21 +92,21 @@ static void FGdmaOsSetupInterrupt(FGdma *const ctrl) InterruptSetPriority(config->irq_num, config->irq_prority); /* register intr callback */ - InterruptInstall(config->irq_num, - FGdmaIrqHandler, - ctrl, + InterruptInstall(config->irq_num, + FGdmaIrqHandler, + ctrl, NULL); /* enable gdma irq */ InterruptUmask(config->irq_num); - FGDMA_INFO("gdma interrupt setup done !!!"); - return; + FGDMA_INFO("gdma interrupt setup done!!!"); + return; } FFreeRTOSGdma *FFreeRTOSGdmaInit(u32 id) { - FASSERT_MSG(id < FGDMA_INSTANCE_NUM, "invalid gdma id"); + FASSERT_MSG(id < FGDMA_INSTANCE_NUM, "Invalid gdma id."); FFreeRTOSGdma *instance = &gdma[id]; FGdma *const ctrl = &instance->ctrl; FGdmaConfig config; @@ -117,40 +117,40 @@ FFreeRTOSGdma *FFreeRTOSGdmaInit(u32 id) if (FT_COMPONENT_IS_READY == ctrl->is_ready) { - FGDMA_WARN("gdma ctrl %d already inited !!!", id); + FGDMA_WARN("gdma ctrl %d already inited!!!", id); return instance; } /* no scheduler during init */ - taskENTER_CRITICAL(); + taskENTER_CRITICAL(); config = *FGdmaLookupConfig(id); config.irq_prority = FFREERTOS_GDMA_IRQ_PRIORITY; err = FGdmaCfgInitialize(ctrl, &config); if (FGDMA_SUCCESS != err) - { - FGDMA_ERROR("init gdma-%d failed, 0x%x", id, err); + { + FGDMA_ERROR("Init gdma-%d failed, 0x%x", id, err); goto err_exit; } FGdmaOsSetupInterrupt(ctrl); - + err = FMempInit(memp, memp_buf_beg, memp_buf_end); - if (FMEMP_SUCCESS != err) - { - FGDMA_ERROR("init memp failed, 0x%x", err); + if (FMEMP_SUCCESS != err) + { + FGDMA_ERROR("Init memp failed, 0x%x", err); goto err_exit; - } + } - FASSERT_MSG(NULL == instance->locker, "locker exists !!!"); - FASSERT_MSG((instance->locker = xSemaphoreCreateMutex()) != NULL, "create mutex failed !!!"); + FASSERT_MSG(NULL == instance->locker, "Locker exists!!!"); + FASSERT_MSG((instance->locker = xSemaphoreCreateMutex()) != NULL, "Create mutex failed!!!"); /* start gdma first, then config gdma channel */ - err = FGdmaStart(ctrl); + err = FGdmaStart(ctrl); err_exit: taskEXIT_CRITICAL(); /* allow schedule after init */ - return (FT_SUCCESS == err) ? instance : NULL; /* exit with NULL if failed */ + return (FT_SUCCESS == err) ? instance : NULL; /* exit with NULL if failed */ } FError FFreeRTOSGdmaDeInit(FFreeRTOSGdma *const instance) @@ -163,7 +163,7 @@ FError FFreeRTOSGdmaDeInit(FFreeRTOSGdma *const instance) if (FT_COMPONENT_IS_READY != ctrl->is_ready) { - FGDMA_ERROR("gdma ctrl %d not yet init !!!", ctrl->config.instance_id); + FGDMA_ERROR("Gdma ctrl %d not yet init!!!", ctrl->config.instance_id); return FFREERTOS_GDMA_NOT_INIT; } @@ -171,13 +171,13 @@ FError FFreeRTOSGdmaDeInit(FFreeRTOSGdma *const instance) err = FGdmaStop(ctrl); FMempDeinit(memp); - FGdmaDeInitialize(ctrl); + FGdmaDeInitialize(ctrl); - vSemaphoreDelete(instance->locker); + vSemaphoreDelete(instance->locker); instance->locker = NULL; taskEXIT_CRITICAL(); /* allow schedule after deinit */ - return err; + return err; } FError FFreeRTOSGdmaSetupChannel(FFreeRTOSGdma *const instance, u32 chan_id, const FFreeRTOSGdmaRequest *req) @@ -193,14 +193,16 @@ FError FFreeRTOSGdmaSetupChannel(FFreeRTOSGdma *const instance, u32 chan_id, con err = FGdmaOsTakeSema(instance->locker); if (FFREERTOS_GDMA_OK != err) + { return err; + } chan_os->bdl_list = FMempMallocAlign(memp, sizeof(FGdmaBdlDesc) * req->valid_trans_num, FGDMA_ADDR_ALIGMENT); if (NULL == chan_os->bdl_list) { - FGDMA_ERROR("allocate buffer failed !!!"); + FGDMA_ERROR("Allocate buffer failed!!!"); err = FFREERTOS_GDMA_ALLOCATE_FAIL; - goto err_exit; + goto err_exit; } chan_config = &chan_os->chan.config; @@ -208,7 +210,7 @@ FError FFreeRTOSGdmaSetupChannel(FFreeRTOSGdma *const instance, u32 chan_id, con err = FGdmaAllocateChan(ctrl, &chan_os->chan, chan_config); if (FGDMA_SUCCESS != err) { - FGDMA_ERROR("allocate chan failed !!!"); + FGDMA_ERROR("Allocate chan failed!!!"); goto err_exit; } @@ -223,18 +225,18 @@ FError FFreeRTOSGdmaSetupChannel(FFreeRTOSGdma *const instance, u32 chan_id, con trans = &req->trans[buf_idx]; /* append bdl entry */ - err = FGdmaAppendBDLEntry(&chan_os->chan, (uintptr)trans->src_buf, - (uintptr)trans->dst_buf, trans->data_len); + err = FGdmaAppendBDLEntry(&chan_os->chan, (uintptr)trans->src_buf, + (uintptr)trans->dst_buf, trans->data_len); if (FGDMA_SUCCESS != err) { - FGDMA_ERROR("setup bdl entry failed !!!"); + FGDMA_ERROR("Setup bdl entry failed!!!"); goto err_exit; - } + } } err_exit: FGdmaOsGiveSema(instance->locker); - return err; + return err; } FError FFreeRTOSGdmaRevokeChannel(FFreeRTOSGdma *const instance, u32 chan_id) @@ -248,25 +250,27 @@ FError FFreeRTOSGdmaRevokeChannel(FFreeRTOSGdma *const instance, u32 chan_id) err = FGdmaOsTakeSema(instance->locker); if (FFREERTOS_GDMA_OK != err) + { return err; + } /* free dynamic memroy allocated for bdl */ if (chan_os->bdl_list) { FMempFree(memp, chan_os->bdl_list); chan_os->bdl_list = NULL; - } + } /* deallocate channel */ err = FGdmaDellocateChan(&chan_os->chan); if (FGDMA_SUCCESS != err) { - FGDMA_ERROR("dellocate chan %d failed", chan_id); + FGDMA_ERROR("Dellocate chan %d failed.", chan_id); } err_exit: FGdmaOsGiveSema(instance->locker); - return err; + return err; } FError FFreeRTOSGdmaStart(FFreeRTOSGdma *const instance, u32 chan_id) @@ -278,15 +282,17 @@ FError FFreeRTOSGdmaStart(FFreeRTOSGdma *const instance, u32 chan_id) err = FGdmaOsTakeSema(instance->locker); if (FFREERTOS_GDMA_OK != err) + { return err; - + } + err = FGdmaBDLTransfer(&chan_os->chan); /* start transfer of each channel */ if (FGDMA_SUCCESS != err) { goto err_exit; - } + } - /* you may wait memcpy end in other task */ + /* you may wait memcpy end in other task */ err_exit: FGdmaOsGiveSema(instance->locker); diff --git a/drivers/dma/fgdma/fgdma_os.h b/drivers/dma/fgdma/fgdma_os.h index ad8a246b..cd5e7b39 100644 --- a/drivers/dma/fgdma/fgdma_os.h +++ b/drivers/dma/fgdma/fgdma_os.h @@ -1,34 +1,28 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: fgdma_os.h * Date: 2022-07-20 10:54:37 * LastEditTime: 2022-07-20 10:54:37 - * Description:  This files is for - * - * Modify History: + * Description:  This file is for providing function related definitions of gdma driver used in FreeRTOS. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- * 1.0 zhugengyu 2022/7/27 init commit */ -#ifndef DRIVERS_FGDMA_OS_H -#define DRIVERS_FGDMA_OS_H - -#ifdef __cplusplus -extern "C" -{ -#endif - +#ifndef FGDMA_OS_H +#define FGDMA_OS_H /***************************** Include Files *********************************/ #include #include @@ -38,6 +32,11 @@ extern "C" #include "fgdma.h" #include "fmemory_pool.h" /************************** Constant Definitions *****************************/ +#ifdef __cplusplus +extern "C" +{ +#endif + #define FFREERTOS_GDMA_OK FT_SUCCESS #define FFREERTOS_GDMA_NOT_INIT FT_CODE_ERR(ErrModPort, ErrGdma, 0) #define FFREERTOS_GDMA_SEMA_ERR FT_CODE_ERR(ErrModPort, ErrGdma, 1) @@ -51,7 +50,7 @@ extern "C" typedef struct { FGdmaChan chan; - FGdmaBdlDesc *bdl_list; /* descriptor of every chan, dynamic allocated */ + FGdmaBdlDesc *bdl_list; /* descriptor of every chan, dynamic allocated */ } FFreeRTOSGdmaChan; /* instance of gdma channel in FreeRTOS */ typedef struct diff --git a/drivers/drivers.mk b/drivers/drivers.mk index b169cfe0..d5080f21 100644 --- a/drivers/drivers.mk +++ b/drivers/drivers.mk @@ -25,6 +25,26 @@ ifdef CONFIG_FREERTOS_USE_XMAC INC_DIR += $(OS_DRIVER_CUR_DIR)/eth/xmac endif +ifdef CONFIG_FREERTOS_USE_GMAC + SRC_DIR += $(OS_DRIVER_CUR_DIR)/eth/gmac + INC_DIR += $(OS_DRIVER_CUR_DIR)/eth/gmac +endif + +ifdef CONFIG_FREERTOS_USE_I2C + SRC_DIR += $(OS_DRIVER_CUR_DIR)/i2c + INC_DIR += $(OS_DRIVER_CUR_DIR)/i2c +endif + +ifdef CONFIG_FREERTOS_USE_MIO + SRC_DIR += $(OS_DRIVER_CUR_DIR)/mio + INC_DIR += $(OS_DRIVER_CUR_DIR)/mio +endif + +ifdef CONFIG_FREERTOS_USE_TIMER + SRC_DIR += $(OS_DRIVER_CUR_DIR)/timer + INC_DIR += $(OS_DRIVER_CUR_DIR)/timer +endif + ifdef CONFIG_FREERTOS_USE_GPIO SRC_DIR += $(OS_DRIVER_CUR_DIR)/gpio/fgpio INC_DIR += $(OS_DRIVER_CUR_DIR)/gpio/fgpio diff --git a/drivers/eth/gmac/fgmac_os.c b/drivers/eth/gmac/fgmac_os.c new file mode 100644 index 00000000..baa24fa4 --- /dev/null +++ b/drivers/eth/gmac/fgmac_os.c @@ -0,0 +1,641 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fgmac_os.c + * Date: 2022-02-24 13:42:19 + * LastEditTime: 2022-03-25 09:16:57 + * Description:  This file is for gmac driver.Functions in this file are the minimum required functions for drivers. + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 huanghe 2022/11/15 first release + */ + + +#include +#include +#include +#include +#include +#include "fgmac_os.h" +#include "fgmac_os.h" +#include "fassert.h" +#include "fio.h" +#include "fassert.h" +#include "finterrupt.h" +#include "list.h" +#include "fcpu_info.h" +#include "sys_arch.h" +#include "fdebug.h" +#include "lwip_port.h" +#include "fparameters.h" + +#define OS_MAC_DEBUG_TAG "OS_MAC" +#define OS_MAC_DEBUG_D(format, ...) FT_DEBUG_PRINT_D(OS_MAC_DEBUG_TAG, format, ##__VA_ARGS__) +#define OS_MAC_DEBUG_I(format, ...) FT_DEBUG_PRINT_I(OS_MAC_DEBUG_TAG, format, ##__VA_ARGS__) +#define OS_MAC_DEBUG_E(format, ...) FT_DEBUG_PRINT_E(OS_MAC_DEBUG_TAG, format, ##__VA_ARGS__) +#define OS_MAC_DEBUG_W(format, ...) FT_DEBUG_PRINT_W(OS_MAC_DEBUG_TAG, format, ##__VA_ARGS__) + +extern void sys_sem_signal(sys_sem_t *sem); +static FGmacOs fgmac_os_instace[FGMAC_NUM] = {0}; + +static void EthLinkPhyStatusChecker(void *param) +{ + FASSERT(param != NULL); + FGmac *instance_p = (FGmac *)param; + uintptr base_addr = instance_p->config.base_addr; + + u32 status = FGMAC_READ_REG32(base_addr, FGMAC_MAC_PHY_STATUS); + + if (FGMAC_RGSMIIIS_LNKSTS_UP == (FGMAC_RGSMIIIS_LNKSTS & status)) + { + FGmacPhyCfgInitialize(instance_p); + OS_MAC_DEBUG_I("Link is up."); + } + else + { + OS_MAC_DEBUG_I("Link is down."); + } + + return; +} + +static void EthLinkDmaErrChecker(void *param) +{ + FASSERT(param != NULL); + FGmac *instance_p = (FGmac *)param; + uintptr base_addr = instance_p->config.base_addr; + + u32 reg_val = FGMAC_READ_REG32(base_addr, FGMAC_DMA_INTR_OFFSET); + u32 status = FGMAC_READ_REG32(base_addr, FGMAC_DMA_STATUS_OFFSET); + + if ((FGMAC_DMA_STATUS_TPS & status) && (FGMAC_DMA_INTR_ENA_TSE & reg_val)) + { + OS_MAC_DEBUG_E("Transmit process stopped."); + } + + if ((FGMAC_DMA_STATUS_TU & status) && (FGMAC_DMA_INTR_ENA_TUE & reg_val)) + { + OS_MAC_DEBUG_E("Transmit buffer unavailable."); + } + + if ((FGMAC_DMA_STATUS_TJT & status) && (FGMAC_DMA_INTR_ENA_THE & reg_val)) + { + OS_MAC_DEBUG_E("Transmit jabber timeout."); + } + + if ((FGMAC_DMA_STATUS_OVF & status) && (FGMAC_DMA_INTR_ENA_OVE & reg_val)) + { + OS_MAC_DEBUG_E("Receive overflow."); + } + + if ((FGMAC_DMA_STATUS_UNF & status) && (FGMAC_DMA_INTR_ENA_UNE & reg_val)) + { + OS_MAC_DEBUG_E("Transmit underflow."); + } + + if ((FGMAC_DMA_STATUS_RU & status) && (FGMAC_DMA_INTR_ENA_RUE & reg_val)) + { + OS_MAC_DEBUG_E("Receive buffer unavailable."); + } + + if ((FGMAC_DMA_STATUS_RPS & status) && (FGMAC_DMA_INTR_ENA_RSE & reg_val)) + { + OS_MAC_DEBUG_E("Receive process stopped."); + } + + if ((FGMAC_DMA_STATUS_RWT & status) && (FGMAC_DMA_INTR_ENA_RWE & reg_val)) + { + OS_MAC_DEBUG_E("Receive watchdog timeout."); + } + + if ((FGMAC_DMA_STATUS_ETI & status) && (FGMAC_DMA_INTR_ENA_ETE & reg_val)) + { + OS_MAC_DEBUG_E("Early transmit interrupt."); + } + + if ((FGMAC_DMA_STATUS_FBI & status) && (FGMAC_DMA_INTR_ENA_FBE & reg_val)) + { + OS_MAC_DEBUG_E("Fatal bus error."); + } + + return; +} + +static void EthLinkStatusChecker(void *param) +{ + FASSERT(param); + FGmac *instance_p = (FGmac *)param; + uintptr base_addr = instance_p->config.base_addr; + u32 status = FGMAC_READ_REG32(base_addr, FGMAC_MAC_PHY_STATUS); + u32 speed_status, duplex_status; + u32 speed, duplex; + + /* Check the link status */ + if (FGMAC_RGSMIIIS_LNKSTS_UP == (FGMAC_RGSMIIIS_LNKSTS & status)) + { + speed_status = FGMAC_RGSMIIIS_SPEED & status; + duplex_status = FGMAC_RGSMIIIS_LNKMODE & status; + + if (FGMAC_RGSMIIIS_SPEED_125MHZ == speed_status) + { + speed = FGMAC_PHY_SPEED_1000; + } + else if (FGMAC_RGSMIIIS_SPEED_25MHZ == speed_status) + { + speed = FGMAC_PHY_SPEED_100; + } + else + { + speed = FGMAC_PHY_SPEED_10; + } + + if (FGMAC_RGSMIIIS_LNKMODE_HALF == duplex_status) + { + duplex = FGMAC_PHY_MODE_HALFDUPLEX; + } + else + { + duplex = FGMAC_PHY_MODE_FULLDUPLEX; + } + + OS_MAC_DEBUG_I("Link is up --- %d/%s", + speed, (FGMAC_PHY_MODE_FULLDUPLEX == duplex) ? "full" : "half"); + } + else + { + OS_MAC_DEBUG_I("Link is down ---"); + } +} + +static void EthLinkTransDoneCallback(void *param) +{ + FASSERT(param); + FGmac *instance_p = (FGmac *)param; + + FGmacResumeDmaSend(instance_p->config.base_addr); + OS_MAC_DEBUG_I("Resume trans."); + return; +} + +static void GmacReceiveCallBack(void *args) +{ + LWIP_ASSERT("args != NULL", (args != NULL)); + struct LwipPort *gmac_netif_p; + FGmacOs *instance_p = (FGmacOs *)args; + gmac_netif_p = (struct LwipPort *)instance_p->stack_pointer; + sys_sem_signal(&gmac_netif_p->sem_rx_data_available); +} + + +static int FGmacSetupIsr(FGmac *gmac_p) +{ + LWIP_ASSERT("gmac_p != NULL", (gmac_p != NULL)); + FGmacConfig *config_p = &gmac_p->config; + u32 irq_num = config_p->irq_num; + u32 cpu_id; + + u32 irq_priority = IRQ_PRIORITY_VALUE_12 ; + + /* gic initialize */ + GetCpuId(&cpu_id); + InterruptSetTargetCpus(irq_num, cpu_id); + + /* disable all gmac & dma intr */ + FGmacSetInterruptMask(gmac_p, FGMAC_CTRL_INTR, FGMAC_ISR_MASK_ALL_BITS); + FGmacSetInterruptMask(gmac_p, FGMAC_DMA_INTR, FGMAC_DMA_INTR_ENA_ALL_MASK); + + InterruptSetPriority(irq_num, irq_priority); + InterruptInstall(irq_num, FGmacInterruptHandler, gmac_p, "GMAC-IRQ"); + + /* register intr callback */ + FGmacRegisterEvtHandler(gmac_p, FGMAC_PHY_STATUS_EVT, EthLinkPhyStatusChecker); + FGmacRegisterEvtHandler(gmac_p, FGMAC_DMA_ERR_EVT, EthLinkDmaErrChecker); + FGmacRegisterEvtHandler(gmac_p, FGMAC_LINK_STATUS_EVT, EthLinkStatusChecker); + FGmacRegisterEvtHandler(gmac_p, FGMAC_TX_COMPLETE_EVT, EthLinkTransDoneCallback); + /* Set Receive Callback */ + FGmacRegisterEvtHandler(gmac_p, FGMAC_RX_COMPLETE_EVT, GmacReceiveCallBack); + + + /* enable some interrupts */ + FGmacSetInterruptUmask(gmac_p, FGMAC_CTRL_INTR, FGMAC_ISR_MASK_RSIM); + FGmacSetInterruptUmask(gmac_p, FGMAC_DMA_INTR, + FGMAC_DMA_INTR_ENA_NIE | FGMAC_DMA_INTR_ENA_RIE | FGMAC_DMA_INTR_ENA_AIE); + + /* umask intr */ + InterruptUmask(irq_num); + + OS_MAC_DEBUG_I("Gmac interrupt setup done."); + return 0; +} + +/* step 1: initialize instance */ +/* step 2: depend on config set some options : JUMBO / IGMP */ +/* step 3: FGmacSelectClk */ +/* step 4: FGmacInitInterface */ +/* step 5: initialize phy */ +/* step 6: initialize dma */ +/* step 7: initialize interrupt */ +/* step 8: start mac */ + +/* step1 :get driver config */ +/* step2 :depend on config set some options :phy */ +/* step3 :FGmacCfgInitialize*/ +/* step4 :initialize dma */ +/* step5 :initialize interrupt */ +/* step6 :start mac */ +FError FGmacOsInit(FGmacOs *instance_p) +{ + FGmacConfig mac_config; + const FGmacConfig *mac_config_p; + FGmac *gmac_p ; + FError status; + + gmac_p = &instance_p->instance; + OS_MAC_DEBUG_I("instance_id IS %d", instance_p->mac_config.instance_id); + mac_config_p = FGmacLookupConfig(instance_p->mac_config.instance_id); + if (mac_config_p == NULL) + { + OS_MAC_DEBUG_E("FGmacLookupConfig is error , instance_id is %d", instance_p->mac_config.instance_id); + return FREERTOS_GMAC_INIT_ERROR; + } + mac_config = *mac_config_p; + + if (instance_p->mac_config.autonegotiation) + { + mac_config.en_auto_negtiation = 1; + } + else + { + mac_config.en_auto_negtiation = 0; + } + + switch (instance_p->mac_config.phy_speed) + { + case FGMAC_PHY_SPEED_10M: + mac_config.speed = 10; + break; + case FGMAC_PHY_SPEED_100M: + mac_config.speed = 100; + break; + case FGMAC_PHY_SPEED_1000M: + mac_config.speed = 1000; + break; + default: + OS_MAC_DEBUG_E("Setting speed is not valid , speed is %d", instance_p->mac_config.phy_speed); + return FREERTOS_GMAC_INIT_ERROR; + } + + switch (instance_p->mac_config.phy_duplex) + { + case FGMAC_PHY_HALF_DUPLEX: + mac_config.duplex_mode = 0 ; + break; + case FGMAC_PHY_FULL_DUPLEX: + mac_config.duplex_mode = 1 ; + break; + } + + status = FGmacCfgInitialize(gmac_p, &mac_config); + if (status != FGMAC_SUCCESS) + { + OS_MAC_DEBUG_W("In %s:EmacPs Configuration Failed....", __func__); + } + + FGmacSetMacAddr(instance_p->instance.config.base_addr, (void *)(instance_p->hwaddr)); + + /* initialize phy */ + status = FGmacPhyCfgInitialize(gmac_p); + if (status != FGMAC_SUCCESS) + { + OS_MAC_DEBUG_W("FGmacPhyCfgInitialize: init phy failed."); + } + + /* Initialize Rx Description list : ring Mode */ + status = FGmacSetupRxDescRing(gmac_p, (FGmacDmaDesc *)(instance_p->rx_desc), instance_p->rx_buf, FGMAC_MAX_PACKET_SIZE, GMAC_RX_DESCNUM); + if (FT_SUCCESS != status) + { + OS_MAC_DEBUG_E("Gmac setup rx return err code %d", status); + FASSERT(FT_SUCCESS == status); + } + + /* Initialize Tx Description list : ring Mode */ + status = FGmacSetupTxDescRing(gmac_p, (FGmacDmaDesc *)(instance_p->tx_desc), instance_p->tx_buf, FGMAC_MAX_PACKET_SIZE, GMAC_TX_DESCNUM); + if (FT_SUCCESS != status) + { + OS_MAC_DEBUG_E("Gmac setup tx return err code %d", status); + FASSERT(FT_SUCCESS == status); + } + + /* initialize interrupt */ + FGmacSetupIsr(gmac_p); + + + + return FT_SUCCESS ; +} + + +FGmacOs *FGmacOsGetInstancePointer(FtOsGmacPhyControl *config_p) +{ + FGmacOs *instance_p; + FASSERT(config_p != NULL); + FASSERT(config_p->instance_id < FGMAC_NUM); + FASSERT_MSG(config_p->autonegotiation <= 1, "config_p->autonegotiation %d is over 1", config_p->autonegotiation); + FASSERT_MSG(config_p->phy_speed <= FGMAC_PHY_SPEED_1000M, "config_p->phy_speed %d is over 1000", config_p->phy_speed); + FASSERT_MSG(config_p->phy_duplex <= FGMAC_PHY_FULL_DUPLEX, "config_p->phy_duplex %d is over FGMAC_PHY_FULL_DUPLEX", config_p->phy_duplex); + + instance_p = &fgmac_os_instace[config_p->instance_id]; + memcpy(&instance_p->mac_config, config_p, sizeof(FtOsGmacPhyControl)); + return instance_p; +} + + + +FError FGmacOsConfig(FGmacOs *instance_p, int cmd, void *arg) +{ + return FT_SUCCESS; +} + + +void *FGmacOsRx(FGmacOs *instance_p) +{ + struct pbuf *p = NULL; + struct pbuf *q = NULL; + u16 length = 0; + u8 *buffer; + volatile FGmacDmaDesc *dma_rx_desc; + u32 buffer_offset = 0; + u32 pay_load_offset = 0; + u32 bytes_left_to_copy = 0; + + u32 desc_buffer_index; /* For Current Desc buffer buf position */ + FGmacOs *os_gmac; + FGmac *gmac_p; + + gmac_p = &instance_p->instance; + + /* get received frame */ + if (FGmacRecvFrame(gmac_p) != FT_SUCCESS) + { + return NULL; + } + + desc_buffer_index = gmac_p->rx_ring.desc_buf_idx; + length = (gmac_p->rx_desc[desc_buffer_index].status & FGMAC_DMA_RDES0_FRAME_LEN_MASK) >> FGMAC_DMA_RDES0_FRAME_LEN_SHIFT; + buffer = (u8 *)(intptr)(gmac_p->rx_desc[desc_buffer_index].buf_addr); + +#if ETH_PAD_SIZE + length += ETH_PAD_SIZE; /* allow room for Ethernet padding */ +#endif + + if (length > 0) + { + /* We allocate a pbuf chain of pbufs from the Lwip buffer pool */ + p = pbuf_alloc(PBUF_RAW, length, PBUF_POOL); + } + +#ifdef RAW_DATA_PRINT + dump_hex(Buffer, (u32)length); +#endif + if (p != NULL) + { +#if ETH_PAD_SIZE + pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ +#endif + dma_rx_desc = &gmac_p->rx_desc[desc_buffer_index]; + buffer_offset = 0; + for (q = p; q != NULL; q = q->next) + { + bytes_left_to_copy = q->len; + pay_load_offset = 0; + /* Check if the length of bytes to copy in current pbuf is bigger than Rx buffer size*/ + while ((bytes_left_to_copy + buffer_offset) > FGMAC_MAX_PACKET_SIZE) + { + /* Copy data to pbuf */ + memcpy((u8 *)((u8 *)q->payload + pay_load_offset), (u8 *)((u8 *)buffer + buffer_offset), (FGMAC_MAX_PACKET_SIZE - buffer_offset)); + + /* Point to next descriptor */ + FGMAC_DMA_INC_DESC(desc_buffer_index, gmac_p->rx_ring.desc_max_num); + if (desc_buffer_index == gmac_p->rx_ring.desc_idx) + { + break; + } + + dma_rx_desc = &gmac_p->rx_desc[desc_buffer_index]; + buffer = (u8 *)(intptr)(dma_rx_desc->buf_addr); + + bytes_left_to_copy = bytes_left_to_copy - (FGMAC_MAX_PACKET_SIZE - buffer_offset); + pay_load_offset = pay_load_offset + (FGMAC_MAX_PACKET_SIZE - buffer_offset); + buffer_offset = 0; + } + /* Copy remaining data in pbuf */ + memcpy((u8 *)((u8 *)q->payload + pay_load_offset), (u8 *)((u8 *)buffer + buffer_offset), bytes_left_to_copy); + buffer_offset = buffer_offset + bytes_left_to_copy; + } + +#if ETH_PAD_SIZE + pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ +#endif + } + else + { + OS_MAC_DEBUG_E("Error malloc is %d", length); + } + + /* Release descriptors to DMA */ + /* Point to first descriptor */ + dma_rx_desc = &gmac_p->rx_desc[desc_buffer_index]; + /* Set Own bit in Rx descriptors: gives the buffers back to DMA */ + for (desc_buffer_index = gmac_p->rx_ring.desc_buf_idx; desc_buffer_index != gmac_p->rx_ring.desc_idx; FGMAC_DMA_INC_DESC(desc_buffer_index, gmac_p->rx_ring.desc_max_num)) + { + dma_rx_desc->status |= FGMAC_DMA_RDES0_OWN; + dma_rx_desc = &gmac_p->rx_desc[desc_buffer_index]; + } + + /* Sync index */ + gmac_p->rx_ring.desc_buf_idx = gmac_p->rx_ring.desc_idx; + + FGmacResumeDmaRecv(gmac_p->config.base_addr); + + return p; + +} + +FError FGmacOsTx(FGmacOs *instance_p, void *tx_buf) +{ + FASSERT(instance_p != NULL); + FASSERT(tx_buf != NULL); + err_t errval = ERR_OK; + struct pbuf *q; + struct pbuf *p = tx_buf; + FError ret; + u8 *buffer = NULL; + volatile FGmacDmaDesc *dma_tx_desc; + u32 frame_length = 0; + u32 buffer_offset = 0; + u32 bytes_left_to_copy = 0; + u32 pay_load_offset = 0; + FGmac *gmac_p; + + gmac_p = &instance_p->instance; + dma_tx_desc = &gmac_p->tx_desc[gmac_p->tx_ring.desc_buf_idx]; + buffer = (u8 *)(intptr)(dma_tx_desc->buf_addr); + + if (buffer == NULL) + { + OS_MAC_DEBUG_I("Error buffer is 0."); + return ERR_VAL; + } + +#if ETH_PAD_SIZE + pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ +#endif + + for (q = p; q != NULL; q = q->next) + { + /* Is this buffer available? If not, goto error */ + if ((dma_tx_desc->status & FGMAC_DMA_TDES0_OWN) != 0) + { + errval = ERR_USE; + OS_MAC_DEBUG_I("Error errval = ERR_USE;"); + goto error; + } + + /* Get bytes in current lwIP buffer */ + bytes_left_to_copy = q->len; + pay_load_offset = 0; + + /* Check if the length of data to copy is bigger than Tx buffer size*/ + while ((bytes_left_to_copy + buffer_offset) > FGMAC_MAX_PACKET_SIZE) + { + /* Copy data to Tx buffer*/ + memcpy((u8 *)((u8 *)buffer + buffer_offset), (u8 *)((u8 *)q->payload + pay_load_offset), (FGMAC_MAX_PACKET_SIZE - buffer_offset)); + FGMAC_DMA_INC_DESC(gmac_p->tx_ring.desc_buf_idx, gmac_p->tx_ring.desc_max_num); + /* Point to next descriptor */ + dma_tx_desc = &gmac_p->tx_desc[gmac_p->tx_ring.desc_buf_idx]; + + /* Check if the Bufferis available */ + if ((dma_tx_desc->status & FGMAC_DMA_TDES0_OWN) != (u32)0) + { + errval = ERR_USE; + OS_MAC_DEBUG_I("Check if the Bufferis available."); + goto error; + } + + buffer = (u8 *)(intptr)(dma_tx_desc->buf_addr); + bytes_left_to_copy = bytes_left_to_copy - (FGMAC_MAX_PACKET_SIZE - buffer_offset); + pay_load_offset = pay_load_offset + (FGMAC_MAX_PACKET_SIZE - buffer_offset); + frame_length = frame_length + (FGMAC_MAX_PACKET_SIZE - buffer_offset); + buffer_offset = 0; + + if (buffer == NULL) + { + OS_MAC_DEBUG_I("Error Buffer is 0."); + return ERR_VAL; + } + } + + /* Copy the remaining bytes */ + memcpy((u8 *)((u8 *)buffer + buffer_offset), (u8 *)((u8 *)q->payload + pay_load_offset), bytes_left_to_copy); + buffer_offset = buffer_offset + bytes_left_to_copy; + frame_length = frame_length + bytes_left_to_copy; + } + + FGMAC_DMA_INC_DESC(gmac_p->tx_ring.desc_buf_idx, gmac_p->tx_ring.desc_max_num); + +#if ETH_PAD_SIZE + pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ +#endif + + ret = FGmacSendFrame(gmac_p, frame_length); + + if (ret != FGMAC_SUCCESS) + { + errval = ERR_USE; + OS_MAC_DEBUG_I("Error errval = ERR_USE; FGmacSendFrame."); + goto error; + } + +error: + FGmacResmuDmaUnderflow(gmac_p->config.base_addr); + + return errval; +} + + +static u32 FGmacPhyLinkDetect(FGmac *instance_p, u32 phy_addr) +{ + u16 status; + + /* Read Phy Status register twice to get the confirmation of the current + * link status. + */ + FGmacReadPhyReg(instance_p, instance_p->phy_addr, FGMAC_PHY_MII_STATUS_REG, &status); + + if (status & FGMAC_PHY_MII_SR_LSTATUS) + { + return 1; + } + return 0; +} + + + +enum lwip_port_link_status FGmacPhyStatus(struct LwipPort *gmac_netif_p) +{ + FGmac *gmac_p; + FGmacOs *instance_p; + u32 phy_link_status; + FASSERT(gmac_netif_p != NULL); + FASSERT(gmac_netif_p->state != NULL); + + instance_p = (FGmacOs *)(gmac_netif_p->state); + + gmac_p = &instance_p->instance; + + if (gmac_p->is_ready != FT_COMPONENT_IS_READY) + { + OS_MAC_DEBUG_E("instance_p is not ready."); + return ETH_LINK_DOWN; + } + + /* read gmac phy link status */ + phy_link_status = FGmacPhyLinkDetect(gmac_p, gmac_p->phy_addr); + + if (phy_link_status) + { + return ETH_LINK_UP; + } + else + { + return ETH_LINK_DOWN; + } +} + +void FGmacOsStart(FGmacOs *instance_p) +{ + FASSERT(instance_p != NULL); + + /* start mac */ + FGmacStartTrans(&instance_p->instance); +} + + +void FGmacOsStop(FGmacOs *instance_p) +{ + FASSERT(instance_p != NULL); + /* step 1 close mac controler */ + FGmacStopTrans(&instance_p->instance); +} diff --git a/third-party/lwip-2.1.2/ports/fgmac/ft_os_gmac.h b/drivers/eth/gmac/fgmac_os.h similarity index 37% rename from third-party/lwip-2.1.2/ports/fgmac/ft_os_gmac.h rename to drivers/eth/gmac/fgmac_os.h index cb54b88f..120e7a38 100644 --- a/third-party/lwip-2.1.2/ports/fgmac/ft_os_gmac.h +++ b/drivers/eth/gmac/fgmac_os.h @@ -1,29 +1,29 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * - * FilePath: ft_os_gmac.h + * See the Phytium Public License for more details. + * + * + * FilePath: fgmac_os.h * Date: 2022-02-24 13:42:19 * LastEditTime: 2022-03-25 09:16:53 - * Description:  This file is for - * - * Modify History: - * Ver   Who        Date         Changes - * ----- ------     --------    -------------------------------------- + * Description:  This file is for gmac driver.Functions in this file are the minimum required functions for drivers. + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 huanghe 2022/11/15 first release */ - -#ifndef FT_OS_GMAC_H -#define FT_OS_GMAC_H +#ifndef FGMAC_OS_H +#define FGMAC_OS_H #include #include @@ -34,10 +34,22 @@ #include "fgmac_phy.h" #include "fparameters.h" #include "lwip/netif.h" -#include "ethernetif.h" -#define FT_OS_GMAC0_ID GMAC_INSTANCE_0 -#define FT_OS_GMAC1_ID GMAC_INSTANCE_1 +#ifdef __cplusplus +extern "C" +{ +#endif + +/* error code */ + +#define FREERTOS_GMAC_INIT_ERROR FT_CODE_ERR(ErrModPort, 0, 0x1) +#define FREERTOS_GMAC_PARAM_ERROR FT_CODE_ERR(ErrModPort, 0, 0x2) +#define FREERTOS_GMAC_NO_VALID_SPACE FT_CODE_ERR(ErrModPort, 0, 0x3) + +#define FGMAX_MAX_HARDWARE_ADDRESS_LENGTH 6 + +#define FT_OS_GMAC0_ID FGMAC0_ID +#define FT_OS_GMAC1_ID FGMAC1_ID #define FT_NETIF_LINKUP 0x1U #define FT_NETIF_DOWN 0x2U @@ -54,47 +66,57 @@ #define PHY_INTERRUPT_ENABLE_OFFSET ((u16)0x12) #define PHY_INTERRUPT_ENABLE_LINK_FAIL BIT(11) /* Link fail interrupt, 0 Interrupt disable , 1 Interrupt enable */ -struct Ipv4Address -{ - u8 ip_address[4]; - u8 netmask_address[4]; - u8 gateWay_address[4]; -}; -struct GmacThread -{ - const char *thread_name; - u16 stack_depth; /* The number of words the stack */ - u32 priority; /* Defines the priority at which the task will execute. */ - TaskHandle_t thread_handle; -}; +/* Phy */ +#define FGMAC_PHY_SPEED_10M 10 +#define FGMAC_PHY_SPEED_100M 100 +#define FGMAC_PHY_SPEED_1000M 1000 + +#define FGMAC_PHY_HALF_DUPLEX 0 +#define FGMAC_PHY_FULL_DUPLEX 1 + + +/* dma */ + +#define GMAC_RX_DESCNUM 128 +#define GMAC_TX_DESCNUM 128 typedef struct { - u32 gmac_instance; /* select Gmac global object */ - u32 isr_priority; /* irq Priority */ - struct Ipv4Address address; - /* Gmac input thread */ - struct GmacThread mac_input_thread; -} FtOsGmacConfig; + u32 instance_id; + u32 autonegotiation; /* 1 is autonegotiation ,0 is manually set */ + u32 phy_speed; /* FXMAC_PHY_SPEED_XXX */ + u32 phy_duplex; /* FXMAC_PHY_XXX_DUPLEX */ +} FtOsGmacPhyControl; typedef struct { - FGmac gmac; - struct netif netif_object; - FtOsGmacConfig config; - u8 *rx_buffer; /* Buffer for RxDesc */ - u8 *tx_buffer; /* Buffer for TxDesc */ + FGmac instance; + FtOsGmacPhyControl mac_config; + + u8 tx_buf[GMAC_TX_DESCNUM * FGMAC_MAX_PACKET_SIZE] __aligned(FGMAC_DMA_MIN_ALIGN); + u8 rx_buf[GMAC_RX_DESCNUM * FGMAC_MAX_PACKET_SIZE] __aligned(FGMAC_DMA_MIN_ALIGN); + u8 tx_desc[GMAC_TX_DESCNUM * sizeof(FGmacDmaDesc)] __aligned(FGMAC_DMA_MIN_ALIGN); + u8 rx_desc[GMAC_RX_DESCNUM * sizeof(FGmacDmaDesc)] __aligned(FGMAC_DMA_MIN_ALIGN); + u8 is_ready; /* Ft_Os_Gmac Object first need Init use Ft_Os_GmacObjec_Init */ SemaphoreHandle_t s_semaphore; /* Semaphore to signal incoming packets */ EventGroupHandle_t s_status_event; /* Event Group to show netif's status ,follow FT_NETIF_XX*/ -} FtOsGmac; - - -void FtOsGmacObjectInit(FtOsGmac *os_gmac, FtOsGmacConfig *config); -FError FtOsGmacInit(FtOsGmac *os_gmac, netif_config *netif_config_p); -void FtOsGmacStart(FtOsGmac *os_gmac); -void FtOsGmacStop(FtOsGmac *os_gmac); -int FtOsGmacSetupInterrupt(FGmac *instance_p); + struct LwipPort *stack_pointer; /* Docking data stack data structure */ + u8 hwaddr[FGMAX_MAX_HARDWARE_ADDRESS_LENGTH]; +} FGmacOs; + + +FError FGmacOsInit(FGmacOs *instance_p); +FGmacOs *FGmacOsGetInstancePointer(FtOsGmacPhyControl *config_p); +FError FGmacOsConfig(FGmacOs *instance_p, int cmd, void *arg); +void *FGmacOsRx(FGmacOs *instance_p); +FError FGmacOsTx(FGmacOs *instance_p, void *tx_buf); +enum lwip_port_link_status FGmacPhyStatus(struct LwipPort *gmac_netif_p); +void FGmacOsStart(FGmacOs *instance_p); + +#ifdef __cplusplus +} +#endif #endif // ! FT_OS_GMAC_H diff --git a/drivers/eth/xmac/ft_os_xmac.c b/drivers/eth/xmac/ft_os_xmac.c deleted file mode 100644 index 8f3f5c11..00000000 --- a/drivers/eth/xmac/ft_os_xmac.c +++ /dev/null @@ -1,1341 +0,0 @@ -/* - * Copyright : (C) 2022 Phytium Information Technology, Inc. - * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * - * FilePath: ft_os_xmac.c - * Date: 2022-07-15 16:33:13 - * LastEditTime: 2022-07-15 16:33:13 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- - */ - - -#include "fparameters.h" -#include "fassert.h" -#include "ft_os_xmac.h" -#include "fxmac.h" -#include "fcache.h" -#include "fxmac_bdring.h" -#include "lwip_port.h" -#include "eth_ieee_reg.h" -#include "fcpu_info.h" - -#ifdef __aarch64__ -#include "faarch64.h" -#else -#include "fcp15.h" -#endif - -#include "FreeRTOS.h" -#include "semphr.h" - -#include "fdebug.h" - -#define FXMAC_OS_XMAC_DEBUG_TAG "FXMAC_OS_XMAC" -#define FXMAC_OS_XMAC_PRINT_E(format, ...) FT_DEBUG_PRINT_E(FXMAC_OS_XMAC_DEBUG_TAG, format, ##__VA_ARGS__) -#define FXMAC_OS_XMAC_PRINT_I(format, ...) FT_DEBUG_PRINT_I(FXMAC_OS_XMAC_DEBUG_TAG, format, ##__VA_ARGS__) -#define FXMAC_OS_XMAC_PRINT_D(format, ...) FT_DEBUG_PRINT_D(FXMAC_OS_XMAC_DEBUG_TAG, format, ##__VA_ARGS__) -#define FXMAC_OS_XMAC_PRINT_W(format, ...) FT_DEBUG_PRINT_W(FXMAC_OS_XMAC_DEBUG_TAG, format, ##__VA_ARGS__) - -#define FXMAC_BD_TO_INDEX(ringptr, bdptr) \ - (((uintptr)bdptr - (uintptr)(ringptr)->base_bd_addr) / (ringptr)->separation) - -static void FXmacInitOnError(FXmacOs *instance_p); -static void FXmacSetupIsr(FXmacOs *instance_p); -extern void sys_sem_signal(sys_sem_t *sem); -static FXmacOs fxmac_os_instace[FT_XMAC_NUM] = - { - [FT_XMAC0_ID] = { - .config =( 0) - }, - [FT_XMAC1_ID] = { - .config =( 0) - }, - [FT_XMAC2_ID] = { - .config =( 0) - }, - [FT_XMAC3_ID] = { - .config =( 0 ) - }, -}; - -int isr_calling_flg = 0; - -/* queue */ - -void FXmacQueueInit(PqQueue *q) -{ - FASSERT(q != NULL); - q->head = q->tail = q->len = 0; -} - -int FXmacPqEnqueue(PqQueue *q, void *p) -{ - if (q->len == PQ_QUEUE_SIZE) - return -1; - - q->data[q->head] = (uintptr)p; - q->head = (q->head + 1)%PQ_QUEUE_SIZE; - q->len++; - - return 0; -} - -void* FXmacPqDequeue(PqQueue *q) -{ - int ptail; - - if (q->len == 0) - return NULL; - - ptail = q->tail; - q->tail = (q->tail + 1)%PQ_QUEUE_SIZE; - q->len--; - - return (void* )q->data[ptail]; -} - -int FXmacPqQlength(PqQueue *q) -{ - return q->len; -} - -/* dma */ - -/** - * @name: IsTxSpaceAvailable - * @msg: 获取当前bdring 剩余计数 - * @param {ethernetif} *ethernetif_p - * @return {*} 返回 - */ -static u32 IsTxSpaceAvailable(FXmacOs *instance_p) -{ - FXmacBdRing *txring; - u32 freecnt = 0; - FASSERT(instance_p != NULL); - - txring = &(FXMAC_GET_TXRING(instance_p->instance)); - - /* tx space is available as long as there are valid BD's */ - freecnt = FXMAC_BD_RING_GET_FREE_CNT(txring); - return freecnt; -} - -/** - * @name: FXmacProcessSentBds - * @msg: 释放发送队列q参数 - * @return {*} - * @param {ethernetif} *ethernetif_p - * @param {FXmacBdRing} *txring - */ -void FXmacProcessSentBds(FXmacOs *instance_p, FXmacBdRing *txring) -{ - FXmacBd *txbdset; - FXmacBd *curbdpntr; - u32 n_bds; - FError status; - u32 n_pbufs_freed = 0; - u32 bdindex; - struct pbuf *p; - u32 *temp; - - while (1) - { - /* obtain processed BD's */ - n_bds = FXmacBdRingFromHwTx(txring, FXMAX_TX_PBUFS_LENGTH, &txbdset); - if (n_bds == 0) - { - return; - } - /* free the processed BD's */ - n_pbufs_freed = n_bds; - curbdpntr = txbdset; - while (n_pbufs_freed > 0) - { - bdindex = FXMAC_BD_TO_INDEX(txring, curbdpntr); - temp = (u32 *)curbdpntr; - *temp = 0; /* Word 0 */ - temp++; - if (bdindex == (FXMAX_TX_PBUFS_LENGTH - 1)) - { - *temp = 0xC0000000; /* Word 1 ,used/Wrap – marks last descriptor in transmit buffer descriptor list.*/ - } - else - { - *temp = 0x80000000; /* Word 1 , Used – must be zero for GEM to read data to the transmit buffer.*/ - } - DSB(); - - p = (struct pbuf *)instance_p->buffer.tx_pbufs_storage[bdindex]; - - if (p != NULL) - { - pbuf_free(p); - } - - instance_p->buffer.tx_pbufs_storage[bdindex] = (uintptr)NULL; - curbdpntr = FXMAC_BD_RING_NEXT(txring, curbdpntr); - n_pbufs_freed--; - DSB(); - } - - status = FXmacBdRingFree(txring, n_bds, txbdset); - if (status != FT_SUCCESS) - { - FXMAC_OS_XMAC_PRINT_I("Failure while freeing in Tx Done ISR\r\n"); - } - } - return; -} - - -void FXmacSendHandler(void *arg) -{ - FXmacOs *instance_p; - FXmacBdRing *txringptr; - u32 regval; - - instance_p = (FXmacOs *)arg; - txringptr = &(FXMAC_GET_TXRING(instance_p->instance)); - regval = FXMAC_READREG32(instance_p->instance.config.base_address, FXMAC_TXSR_OFFSET); - FXMAC_WRITEREG32(instance_p->instance.config.base_address,FXMAC_TXSR_OFFSET, regval); /* 清除中断状态位来停止中断 */ - - /* If Transmit done interrupt is asserted, process completed BD's */ - FXmacProcessSentBds(instance_p, txringptr); -} - -FError FXmacSgsend(FXmacOs *instance_p, struct pbuf *p) -{ - struct pbuf *q; - u32 n_pbufs; - FXmacBd *txbdset, *txbd, *last_txbd = NULL; - FXmacBd *temp_txbd; - FError status; - FXmacBdRing *txring; - u32 bdindex; - u32 lev; - u32 max_fr_size; - - lev = MFCPSR(); - MTCPSR(lev | 0xC0); /* Mask IRQ and FIQ interrupts in cpsr */ - - txring = &(FXMAC_GET_TXRING(instance_p->instance)); - - /* first count the number of pbufs */ - for (q = p, n_pbufs = 0; q != NULL; q = q->next) - n_pbufs++; - - /* obtain as many BD's */ - status = FXmacBdRingAlloc(txring, n_pbufs, &txbdset); - if (status != FT_SUCCESS) - { - MTCPSR(lev); - FXMAC_OS_XMAC_PRINT_I("sgsend: Error allocating TxBD\r\n"); - return ERR_GENERAL; - } - - for(q = p, txbd = txbdset; q != NULL; q = q->next) - { - bdindex = FXMAC_BD_TO_INDEX(txring, txbd); - - if(instance_p->buffer.tx_pbufs_storage[bdindex]) - { - MTCPSR(lev); - FXMAC_OS_XMAC_PRINT_I("PBUFS not available\r\n"); - return ERR_GENERAL; - } - - /* Send the data from the pbuf to the interface, one pbuf at a - time. The size of the data in each pbuf is kept in the ->len - variable. */ - FCacheDCacheFlushRange((uintptr)q->payload, (uintptr)q->len); - FXMAC_BD_SET_ADDRESS_TX(txbd, (uintptr)q->payload); - - if(instance_p->config & FXMAC_OS_CONFIG_JUMBO) - { - max_fr_size = FXMAC_MAX_FRAME_SIZE_JUMBO - 18; - } - else - { - max_fr_size = FXMAC_MAX_FRAME_SIZE - 18; - } - - if (q->len > max_fr_size) - FXMAC_BD_SET_LENGTH(txbd, max_fr_size & 0x3FFF); - else - FXMAC_BD_SET_LENGTH(txbd, q->len & 0x3FFF); - - instance_p->buffer.tx_pbufs_storage[bdindex] = (uintptr)q; - - pbuf_ref(q); - last_txbd = txbd; - FXMAC_BD_CLEAR_LAST(txbd); - txbd = FXMAC_BD_RING_NEXT(txring, txbd); - } - FXMAC_BD_SET_LAST(last_txbd); - /* For fragmented packets, remember the 1st BD allocated for the 1st - packet fragment. The used bit for this BD should be cleared at the end - after clearing out used bits for other fragments. For packets without - just remember the allocated BD. */ - temp_txbd = txbdset; - txbd = txbdset; - txbd = FXMAC_BD_RING_NEXT(txring, txbd); - q = p->next; - for(; q != NULL; q = q->next) - { - FXMAC_BD_CLEAR_TX_USED(txbd); - DSB(); - txbd = FXMAC_BD_RING_NEXT(txring, txbd); - } - FXMAC_BD_CLEAR_TX_USED(temp_txbd); - DSB(); - - status = FXmacBdRingToHw(txring, n_pbufs, txbdset); - if (status != FT_SUCCESS) - { - MTCPSR(lev); - FXMAC_OS_XMAC_PRINT_I("sgsend: Error submitting TxBD\r\n"); - return ERR_GENERAL; - } - /* Start transmit */ - FXMAC_WRITEREG32((instance_p->instance).config.base_address, - FXMAC_NWCTRL_OFFSET, - (FXMAC_READREG32(instance_p->instance.config.base_address, - FXMAC_NWCTRL_OFFSET) | FXMAC_NWCTRL_STARTTX_MASK)); - - MTCPSR(lev); - - return status; -} - - -void SetupRxBds(FXmacOs *instance_p, FXmacBdRing *rxring) -{ - FXmacBd *rxbd; - FError status; - struct pbuf *p; - u32 freebds; - u32 bdindex; - u32 *temp; - freebds = FXMAC_BD_RING_GET_FREE_CNT(rxring); - while (freebds > 0) - { - freebds--; - - if(instance_p->config & FXMAC_OS_CONFIG_JUMBO) - { - p = pbuf_alloc(PBUF_RAW, FXMAC_MAX_FRAME_SIZE_JUMBO, PBUF_POOL); - } - else - { - p = pbuf_alloc(PBUF_RAW, FXMAC_MAX_FRAME_SIZE, PBUF_POOL); - } - - if (!p) - { -#if LINK_STATS - lwip_stats.link.memerr++; - lwip_stats.link.drop++; -#endif - FXMAC_OS_XMAC_PRINT_I("unable to alloc pbuf in recv_handler\r\n"); - return; - } - status = FXmacBdRingAlloc(rxring, 1, &rxbd); - if (status != FT_SUCCESS) - { - FXMAC_OS_XMAC_PRINT_I("SetupRxBds: Error allocating RxBD\r\n"); - pbuf_free(p); - return; - } - status = FXmacBdRingToHw(rxring, 1, rxbd); - if (status != FT_SUCCESS) - { - FXMAC_OS_XMAC_PRINT_I("Error committing RxBD to hardware: "); - if (status == FXMAC_ERR_SG_LIST) - { - FXMAC_OS_XMAC_PRINT_I("XST_DMA_SG_LIST_ERROR: this function was called out of sequence with FXmacBdRingAlloc()\r\n"); - } - else - { - FXMAC_OS_XMAC_PRINT_I("set of BDs was rejected because the first BD did not have its start-of-packet bit set, or the last BD did not have its end-of-packet bit set, or any one of the BD set has 0 as length value\r\n"); - } - - pbuf_free(p); - FXmacBdRingUnAlloc(rxring, 1, rxbd); - return; - } - - if(instance_p->config & FXMAC_OS_CONFIG_JUMBO) - { - FCacheDCacheInvalidateRange((uintptr)p->payload, (uintptr)MAX_FRAME_SIZE_JUMBO); - } - else - { - FCacheDCacheInvalidateRange((uintptr)p->payload, (uintptr)FXMAC_MAX_FRAME_SIZE); - } - - - bdindex = FXMAC_BD_TO_INDEX(rxring, rxbd); - temp = (u32 *)rxbd; - if (bdindex == (FXMAX_RX_PBUFS_LENGTH - 1)) - { - *temp = 0x00000002; - } - else - { - *temp = 0; - } - temp++; - *temp = 0; - DSB(); - - FXMAC_BD_SET_ADDRESS_RX(rxbd, (uintptr)p->payload); - instance_p->buffer.rx_pbufs_storage[bdindex] = (uintptr)p; - } -} - - - -void FXmacRecvHandler(void *arg) -{ - struct pbuf *p; - FXmacBd *rxbdset, *curbdptr; - struct LwipPort *xmac_netif_p; - FXmacBdRing *rxring; - volatile u32 bd_processed; - u32 rx_bytes, k; - u32 bdindex; - u32 regval; - u32 index; - u32 gigeversion; - FXmacOs *instance_p; - FASSERT(arg != NULL); - - instance_p = (FXmacOs *)arg ; - xmac_netif_p = (struct LwipPort *)instance_p->stack_pointer; - rxring = &FXMAC_GET_RXRING(instance_p->instance); - - /* If Reception done interrupt is asserted, call RX call back function - to handle the processed BDs and then raise the according flag.*/ - regval = FXMAC_READREG32(instance_p->instance.config.base_address, FXMAC_RXSR_OFFSET); - FXMAC_WRITEREG32(instance_p->instance.config.base_address, FXMAC_RXSR_OFFSET, regval); - - while(1) - { - bd_processed = FXmacBdRingFromHwRx(rxring, FXMAX_RX_PBUFS_LENGTH, &rxbdset); - if (bd_processed <= 0) - { - break; - } - - for (k = 0, curbdptr=rxbdset; k < bd_processed; k++) - { - - bdindex = FXMAC_BD_TO_INDEX(rxring, curbdptr); - p = (struct pbuf *)instance_p->buffer.rx_pbufs_storage[bdindex]; - /* - * Adjust the buffer size to the actual number of bytes received. - */ - if(instance_p->config & FXMAC_OS_CONFIG_JUMBO) - { - rx_bytes = FXMAC_GET_RX_FRAME_SIZE(&(instance_p->instance), curbdptr); - } - else - { - rx_bytes = FXMAC_BD_GET_LENGTH(curbdptr); - } - pbuf_realloc(p, rx_bytes); - - /* Invalidate RX frame before queuing to handle - * L1 cache prefetch conditions on any architecture. - */ - FCacheDCacheInvalidateRange((uintptr)p->payload, rx_bytes); - - /* store it in the receive queue, - * where it'll be processed by a different handler - */ - if (FXmacPqEnqueue(&instance_p->recv_q, (void*)p) < 0) - { -#if LINK_STATS - lwip_stats.link.memerr++; - lwip_stats.link.drop++; -#endif - pbuf_free(p); - } - curbdptr = FXMAC_BD_RING_NEXT( rxring, curbdptr); - } - - /* free up the BD's */ - FXmacBdRingFree(rxring, bd_processed, rxbdset); - SetupRxBds(instance_p, rxring); -#if !NO_SYS - sys_sem_signal(&xmac_netif_p->sem_rx_data_available); -#endif - } - - return; -} - -void CleanDmaTxdescs(FXmacOs *instance_p) -{ - FXmacBd bdtemplate; - FXmacBdRing *txringptr; - - txringptr = &FXMAC_GET_TXRING((instance_p->instance)); - FXMAC_BD_CLEAR(&bdtemplate); - FXMAC_BD_SET_STATUS(&bdtemplate, FXMAC_TXBUF_USED_MASK); - - FXmacBdRingCreate(txringptr, (uintptr) instance_p->buffer.tx_bdspace, - (uintptr) instance_p->buffer.tx_bdspace, BD_ALIGNMENT, - sizeof(instance_p->buffer.tx_bdspace)); - - FXmacBdRingClone(txringptr, &bdtemplate, FXMAC_SEND); -} - - - -FError FXmacInitDma(FXmacOs *instance_p) -{ - FXmacBd bdtemplate; - FXmacBdRing *rxringptr, *txringptr; - FXmacBd *rxbd; - struct pbuf *p; - FError status; - int i; - u32 bdindex; - volatile uintptr tempaddress; - u32 gigeversion; - FXmacBd *bdtxterminate; - FXmacBd *bdrxterminate; - u32 *temp; - - /* - * The BDs need to be allocated in uncached memory. Hence the 1 MB - * address range allocated for Bd_Space is made uncached - * by setting appropriate attributes in the translation table. - * The Bd_Space is aligned to 1MB and has a size of 1 MB. This ensures - * a reserved uncached area used only for BDs. - */ - - rxringptr = &FXMAC_GET_RXRING(instance_p->instance); - txringptr = &FXMAC_GET_TXRING(instance_p->instance); - FXMAC_OS_XMAC_PRINT_I( "rxringptr: 0x%08x\r\n", rxringptr); - FXMAC_OS_XMAC_PRINT_I( "txringptr: 0x%08x\r\n", txringptr); - - FXMAC_OS_XMAC_PRINT_I("rx_bdspace: %p \r\n", instance_p->buffer.rx_bdspace); - FXMAC_OS_XMAC_PRINT_I("tx_bdspace: %p \r\n", instance_p->buffer.tx_bdspace); - - /* Setup RxBD space. */ - FXMAC_BD_CLEAR(&bdtemplate); - - /* Create the RxBD ring */ - status = FXmacBdRingCreate(rxringptr, (uintptr) instance_p->buffer.rx_bdspace, - (uintptr) instance_p->buffer.rx_bdspace, BD_ALIGNMENT, - FXMAX_RX_PBUFS_LENGTH); - - if(status != FT_SUCCESS) - { - FXMAC_OS_XMAC_PRINT_I("Error setting up RxBD space\r\n"); - return ERR_IF; - } - - status = FXmacBdRingClone(rxringptr, &bdtemplate, FXMAC_RECV); - if(status != FT_SUCCESS) - { - FXMAC_OS_XMAC_PRINT_I("Error initializing RxBD space\r\n"); - return ERR_IF; - } - - FXMAC_BD_CLEAR(&bdtemplate); - FXMAC_BD_SET_STATUS(&bdtemplate, FXMAC_TXBUF_USED_MASK); - - /* Create the TxBD ring */ - status = FXmacBdRingCreate(txringptr, (uintptr) instance_p->buffer.tx_bdspace, - (uintptr) instance_p->buffer.tx_bdspace, BD_ALIGNMENT, - FXMAX_TX_PBUFS_LENGTH); - - if (status != FT_SUCCESS) - { - return ERR_IF; - } - - /* We reuse the bd template, as the same one will work for both rx and tx. */ - status = FXmacBdRingClone(txringptr, &bdtemplate, FXMAC_SEND); - if (status != FT_SUCCESS) - { - return ERR_IF; - } - - /* - * Allocate RX descriptors, 1 RxBD at a time. - */ - printf("Allocate RX descriptors, 1 RxBD at a time. \r\n"); - for (i = 0; i < FXMAX_RX_PBUFS_LENGTH; i++) - { - if(instance_p->config & FXMAC_OS_CONFIG_JUMBO) - { - p = pbuf_alloc(PBUF_RAW, FXMAC_MAX_FRAME_SIZE_JUMBO, PBUF_POOL); - } - else - { - p = pbuf_alloc(PBUF_RAW, FXMAC_MAX_FRAME_SIZE, PBUF_POOL); - } - - if (!p) - { -#if LINK_STATS - lwip_stats.link.memerr++; - lwip_stats.link.drop++; -#endif - FXMAC_OS_XMAC_PRINT_E("unable to alloc pbuf in InitDma\r\n"); - return ERR_IF; - } - status = FXmacBdRingAlloc(rxringptr, 1, &rxbd); - if (status != FT_SUCCESS) - { - FXMAC_OS_XMAC_PRINT_E("InitDma: Error allocating RxBD\r\n"); - pbuf_free(p); - return ERR_IF; - } - /* Enqueue to HW */ - status = FXmacBdRingToHw(rxringptr, 1, rxbd); - if (status != FT_SUCCESS) - { - FXMAC_OS_XMAC_PRINT_E("Error: committing RxBD to HW\r\n"); - pbuf_free(p); - FXmacBdRingUnAlloc(rxringptr, 1, rxbd); - return ERR_IF; - } - - bdindex = FXMAC_BD_TO_INDEX(rxringptr, rxbd); - temp = (u32 *)rxbd; - *temp = 0; - if (bdindex == (FXMAX_RX_PBUFS_LENGTH - 1)) - { - *temp = 0x00000002; - } - temp++; - *temp = 0; - DSB(); - - - if(instance_p->config & FXMAC_OS_CONFIG_JUMBO) - { - FCacheDCacheInvalidateRange((uintptr)p->payload, (uintptr)MAX_FRAME_SIZE_JUMBO); - } - else - { - FCacheDCacheInvalidateRange((uintptr)p->payload, (uintptr)FXMAC_MAX_FRAME_SIZE); - } - FXMAC_BD_SET_ADDRESS_RX(rxbd, (uintptr)p->payload); - - instance_p->buffer.rx_pbufs_storage[bdindex] = (uintptr)p; - } - - FXmacSetQueuePtr(&(instance_p->instance), instance_p->instance.tx_bd_queue.bdring.base_bd_addr, 0, (u16)FXMAC_SEND); - FXmacSetQueuePtr(&(instance_p->instance), instance_p->instance.rx_bd_queue.bdring.base_bd_addr, 0, (u16)FXMAC_RECV); - - return 0; -} - - -static void FreeTxRxPbufs(FXmacOs *instance_p) -{ - u32 index; - struct pbuf *p; - - for (index = 0; index < (0 + sizeof(instance_p->buffer.tx_pbufs_storage)); index++) - { - if(instance_p->buffer.tx_pbufs_storage[index] != 0) - { - p = (struct pbuf *)instance_p->buffer.tx_pbufs_storage[index]; - pbuf_free(p); - instance_p->buffer.tx_pbufs_storage[index] = 0; - } - } - - for (index = 0; index < (0 + sizeof(instance_p->buffer.rx_pbufs_storage)); index++) - { - p = (struct pbuf *)instance_p->buffer.rx_pbufs_storage[index]; - pbuf_free(p); - } -} - -static void FreeOnlyTxPbufs(FXmacOs *instance_p) -{ - u32 index; - u32 index1; - struct pbuf *p; - - for (index = 0; index < (0 + sizeof(instance_p->buffer.tx_pbufs_storage)); index++) - { - if(instance_p->buffer.tx_pbufs_storage[index] != 0) - { - p = (struct pbuf *)instance_p->buffer.tx_pbufs_storage[index]; - pbuf_free(p); - instance_p->buffer.tx_pbufs_storage[index] = 0; - } - } -} - -static void ResetDma(FXmacOs *instance_p) -{ - u8 txqueuenum; - u32 gigeversion; - - FXmacBdRing *txringptr = &FXMAC_GET_TXRING(instance_p->instance); - FXmacBdRing *rxringptr = &FXMAC_GET_RXRING(instance_p->instance); - - FXmacBdringPtrReset(txringptr, instance_p->buffer.tx_bdspace); - FXmacBdringPtrReset(rxringptr, instance_p->buffer.rx_bdspace); - - FXmacSetQueuePtr(&(instance_p->instance), instance_p->instance.tx_bd_queue.bdring.base_bd_addr, 0, (u16)FXMAC_SEND); - FXmacSetQueuePtr(&(instance_p->instance), instance_p->instance.rx_bd_queue.bdring.base_bd_addr, 0, (u16)FXMAC_RECV); - -} - - -/* interrupt */ -static void FXmacHandleDmaTxError(FXmacOs *instance_p) -{ - s32_t status = FT_SUCCESS; - u32 dmacrreg; - - FreeTxRxPbufs(instance_p); - status = FXmacCfgInitialize(&instance_p->instance, &instance_p->instance.config); - - if (status != FT_SUCCESS) - { - FXMAC_OS_XMAC_PRINT_E("In %s:EmacPs Configuration Failed....\r\n", __func__); - } - - /* initialize the mac */ - FXmacInitOnError(instance_p); /* need to set mac filter address */ - dmacrreg = FXMAC_READREG32(instance_p->instance.config.base_address, FXMAC_DMACR_OFFSET); - dmacrreg = dmacrreg | (FXMAC_DMACR_ORCE_DISCARD_ON_ERR_MASK); /* force_discard_on_err */ - FXMAC_WRITEREG32(instance_p->instance.config.base_address, FXMAC_DMACR_OFFSET, dmacrreg); - FXmacSetupIsr(instance_p); - FXmacInitDma(instance_p); - - FXmacStart(&instance_p->instance); -} - - -void FXmacHandleTxErrors(FXmacOs *instance_p) -{ - u32 netctrlreg; - - netctrlreg = FXMAC_READREG32(instance_p->instance.config.base_address, - FXMAC_NWCTRL_OFFSET); - netctrlreg = netctrlreg & (~FXMAC_NWCTRL_TXEN_MASK); - FXMAC_WRITEREG32(instance_p->instance.config.base_address, - FXMAC_NWCTRL_OFFSET, netctrlreg); - FreeOnlyTxPbufs(instance_p); - - CleanDmaTxdescs(instance_p); - netctrlreg = FXMAC_READREG32(instance_p->instance.config.base_address, FXMAC_NWCTRL_OFFSET); - netctrlreg = netctrlreg | (FXMAC_NWCTRL_TXEN_MASK); - FXMAC_WRITEREG32(instance_p->instance.config.base_address, FXMAC_NWCTRL_OFFSET, netctrlreg); - -} - -void FXmacErrorHandler(void *arg,u8 direction, u32 error_word) -{ - FXmacBdRing *rxring; - FXmacBdRing *txring; - FXmacOs *instance_p; - - instance_p = (FXmacOs *)(arg); - rxring = &FXMAC_GET_RXRING((instance_p->instance)); - txring = &FXMAC_GET_TXRING((instance_p->instance)); - - if (error_word != 0) - { - switch (direction) - { - case FXMAC_RECV: - if (error_word & FXMAC_RXSR_HRESPNOK_MASK) - { - FXMAC_OS_XMAC_PRINT_I("Receive DMA error\r\n"); - FXmacHandleDmaTxError(instance_p); - } - if (error_word & FXMAC_RXSR_RXOVR_MASK) - { - FXMAC_OS_XMAC_PRINT_I("Receive over run\r\n"); - FXmacRecvHandler(instance_p); - SetupRxBds(instance_p, rxring); - } - if (error_word & FXMAC_RXSR_BUFFNA_MASK) - { - FXMAC_OS_XMAC_PRINT_I("Receive buffer not available\r\n"); - FXmacRecvHandler(arg); - SetupRxBds(instance_p, rxring); - } - break; - case FXMAC_SEND: - if (error_word & FXMAC_TXSR_HRESPNOK_MASK) - { - FXMAC_OS_XMAC_PRINT_I("Transmit DMA error\r\n"); - FXmacHandleDmaTxError(instance_p); - } - if (error_word & FXMAC_TXSR_URUN_MASK) - { - FXMAC_OS_XMAC_PRINT_I("Transmit under run\r\n"); - FXmacHandleTxErrors(instance_p); - } - if (error_word & FXMAC_TXSR_BUFEXH_MASK) - { - FXMAC_OS_XMAC_PRINT_I("Transmit buffer exhausted\r\n"); - FXmacHandleTxErrors(instance_p); - } - if (error_word & FXMAC_TXSR_RXOVR_MASK) - { - FXMAC_OS_XMAC_PRINT_I("Transmit retry excessed limits\r\n"); - FXmacHandleTxErrors(instance_p); - } - if (error_word & FXMAC_TXSR_FRAMERX_MASK) - { - FXMAC_OS_XMAC_PRINT_I("Transmit collision\r\n"); - FXmacProcessSentBds(instance_p, txring); - } - break; - } - } -} - - - -void FXmacLinkChange(void *args) -{ - u32 ctrl; - u32 link,link_status; - u32 speed; - u32 speed_bit; - u32 duplex; - u32 status = FT_SUCCESS; - - FXmac *xmac_p; - FXmacOs *instance_p; - - instance_p = (FXmacOs *)args; - xmac_p = &instance_p->instance; - - if(xmac_p->config.interface == FXMAC_PHY_INTERFACE_MODE_SGMII) - { - FXMAC_OS_XMAC_PRINT_I("xmac_p->config.base_address is %p \r\n",xmac_p->config.base_address); - ctrl = FXMAC_READREG32(xmac_p->config.base_address, FXMAC_PCS_AN_LP_OFFSET); - link = (ctrl & FXMAC_PCS_LINK_PARTNER_NEXT_PAGE_STATUS) >> 15 ; - FXMAC_OS_XMAC_PRINT_I("link status is 0x%x\r\n", link); - - switch(link) - { - case 0: - link_status = FXMAC_LINKDOWN; - break; - case 1: - link_status = FXMAC_LINKUP; - break; - default: - FXMAC_OS_XMAC_PRINT_E("link status is error 0x%x \r\n",link); - return; - } - - if (xmac_p->config.auto_neg == 0) - { - if(link_status == FXMAC_LINKUP) - { - FXMAC_OS_XMAC_PRINT_I("No neg link up (%d/%s)\r\n",xmac_p->config.speed ,xmac_p->config.duplex == 1 ?"FULL":"Half"); - xmac_p->link_status = FXMAC_NEGOTIATING; - } - else - { - FXMAC_OS_XMAC_PRINT_I("No neg link down \r\n"); - xmac_p->link_status = FXMAC_LINKDOWN; - } - } - - /* read sgmii reg to get status */ - ctrl = FXMAC_READREG32(xmac_p->config.base_address, FXMAC_PCS_AN_LP_OFFSET); - speed_bit =(ctrl&FXMAC_PCS_AN_LP_SPEED)>> FXMAC_PCS_AN_LP_SPEED_OFFSET ; - duplex =(ctrl&FXMAC_PCS_AN_LP_DUPLEX)>> FXMAC_PCS_AN_LP_DUPLEX_OFFSET ; - - if(speed_bit == 2) - { - speed = FXMAC_SPEED_1000; - } - else if(speed_bit == 1) - { - speed = FXMAC_SPEED_100; - } - else - { - speed = FXMAC_SPEED_10; - } - - if(link_status != xmac_p->link_status) - { - FXMAC_OS_XMAC_PRINT_I("sgmii link_status has changed \r\n"); - } - - /* add erase NCFGR config */ - if((speed != xmac_p->config.speed) || (duplex != xmac_p->config.duplex) ) - { - FXMAC_OS_XMAC_PRINT_I("sgmii link_status has changed \r\n"); - FXMAC_OS_XMAC_PRINT_I("new speed is %d, duplex is %d\r\n", speed, duplex); - } - - if(link_status == FXMAC_LINKUP) - { - if(link_status != xmac_p->link_status) - { - xmac_p->link_status = FXMAC_NEGOTIATING; - FXMAC_OS_XMAC_PRINT_I("need NEGOTIATING"); - } - } - else - { - xmac_p->link_status = link_status; - FXMAC_OS_XMAC_PRINT_I("change status is 0x%x",link_status); - } - } -} - - -/* phy */ - -/** - * @name: phy_link_detect - * @msg: 获取当前link status - * @note: - * @param {FXmac} *fxmac_p - * @param {u32} phy_addr - * @return {*} 1 is link up , 0 is link down - */ -static u32 phy_link_detect(FXmac *xmac_p, u32 phy_addr) -{ - u16 status; - - /* Read Phy Status register twice to get the confirmation of the current - * link status. - */ - - FXmacPhyRead(xmac_p, phy_addr, PHY_STATUS_REG_OFFSET, &status); - - if (status & PHY_STAT_LINK_STATUS) - return 1; - return 0; -} - -static u32 phy_autoneg_status(FXmac *xmac_p, u32 phy_addr) -{ - u16 status; - - /* Read Phy Status register twice to get the confirmation of the current - * link status. - */ - FXmacPhyRead(xmac_p, phy_addr, PHY_STATUS_REG_OFFSET, &status); - - if (status & PHY_STATUS_AUTONEGOTIATE_COMPLETE) - return 1; - return 0; -} - -enum ethernet_link_status FXmacLwipPortLinkDetect(FXmacOs *instance_p) -{ - u32 link_speed, phy_link_status; - FXmac *xmac_p = &instance_p->instance; - - if (xmac_p->is_ready != (u32)FT_COMPONENT_IS_READY) - { - return ETH_LINK_UNDEFINED; - } - - phy_link_status = phy_link_detect(xmac_p, xmac_p->phy_address); - - if ((xmac_p->link_status == FXMAC_LINKUP) && (!phy_link_status)) - xmac_p->link_status = FXMAC_LINKDOWN; - - switch (xmac_p->link_status) - { - case FXMAC_LINKUP: - return ETH_LINK_UP; - case FXMAC_LINKDOWN: - xmac_p->link_status = FXMAC_NEGOTIATING; - FXMAC_OS_XMAC_PRINT_D("Ethernet Link down"); - return ETH_LINK_DOWN; - case FXMAC_NEGOTIATING: - if ((phy_link_status == FXMAC_LINKUP) && phy_autoneg_status(xmac_p, xmac_p->phy_address)) - { - err_t phy_ret; - phy_ret = FXmacPhyInit(xmac_p,xmac_p->config.speed,xmac_p->config.duplex,xmac_p->config.auto_neg); - - if (phy_ret != FT_SUCCESS) - { - FXMAC_OS_XMAC_PRINT_E("FXmacPhyInit is error \r\n"); - return ETH_LINK_DOWN; - } - FXmacSelectClk(xmac_p); - FXmacInitInterface(xmac_p); - - /* Initiate Phy setup to get link speed */ - xmac_p->link_status = FXMAC_LINKUP; - FXMAC_OS_XMAC_PRINT_D("Ethernet Link up"); - return ETH_LINK_UP; - } - return ETH_LINK_DOWN; - default: - return ETH_LINK_DOWN; - - } -} - -enum ethernet_link_status FXmacPhyReconnect(struct LwipPort *xmac_netif_p) -{ - FXmac *xmac_p; - FXmacOs *instance_p; - // ethernetif *ethernetif_p; - FASSERT(xmac_netif_p != NULL); - FASSERT(xmac_netif_p->state != NULL); - - instance_p = (FXmacOs *)(xmac_netif_p->state); - - xmac_p = &instance_p->instance; - - if(xmac_p->config.interface == FXMAC_PHY_INTERFACE_MODE_SGMII) - { - InterruptMask(xmac_p->config.queue_irq_num[0]); - if(xmac_p->link_status == FXMAC_NEGOTIATING ) - { - /* 重新自协商 */ - err_t phy_ret; - phy_ret = FXmacPhyInit(xmac_p,xmac_p->config.speed,xmac_p->config.duplex,xmac_p->config.auto_neg); - if (phy_ret != FT_SUCCESS) - { - FXMAC_OS_XMAC_PRINT_I("FXmacPhyInit is error \r\n"); - InterruptUmask(xmac_p->config.queue_irq_num[0]); - return ETH_LINK_DOWN; - } - FXmacSelectClk(xmac_p); - FXmacInitInterface(xmac_p); - xmac_p->link_status = FXMAC_LINKUP; - } - - InterruptUmask(xmac_p->config.queue_irq_num[0]); - - switch (xmac_p->link_status) - { - case FXMAC_LINKDOWN: - return ETH_LINK_DOWN; - case FXMAC_LINKUP: - return ETH_LINK_UP; - default: - return ETH_LINK_DOWN; - } - } - else if((xmac_p->config.interface == FXMAC_PHY_INTERFACE_MODE_RMII)||(xmac_p->config.interface == FXMAC_PHY_INTERFACE_MODE_RGMII )) - { - return FXmacLwipPortLinkDetect(instance_p); - } - else - { - switch (xmac_p->link_status) - { - case FXMAC_LINKDOWN: - return ETH_LINK_DOWN; - case FXMAC_LINKUP: - return ETH_LINK_UP; - default: - return ETH_LINK_DOWN; - } - } -} - -static void FxmacOsIntrHandler(s32 vector, void *args) -{ - isr_calling_flg++; - FXmacIntrHandler(vector,args); - isr_calling_flg--; -} - - -static void FXmacSetupIsr(FXmacOs *instance_p) -{ - u32 cpu_id; - GetCpuId(&cpu_id); - InterruptSetTargetCpus(instance_p->instance.config.queue_irq_num[0],cpu_id); - /* Setup callbacks */ - FXmacSetHandler(&instance_p->instance, FXMAC_HANDLER_DMASEND, FXmacSendHandler, instance_p); - FXmacSetHandler(&instance_p->instance, FXMAC_HANDLER_DMARECV, FXmacRecvHandler, instance_p); - FXmacSetHandler(&instance_p->instance, FXMAC_HANDLER_ERROR, FXmacErrorHandler, instance_p); - FXmacSetHandler(&instance_p->instance, FXMAC_HANDLER_LINKCHANGE, FXmacLinkChange, instance_p); - - InterruptSetPriority(instance_p->instance.config.queue_irq_num[0], IRQ_PRIORITY_VALUE_12); - InterruptInstall(instance_p->instance.config.queue_irq_num[0], FxmacOsIntrHandler, &instance_p->instance, "fxmac"); - InterruptUmask(instance_p->instance.config.queue_irq_num[0]); -} - -/* init fxmac instance */ - -static void FXmacInitOnError(FXmacOs *instance_p) -{ - FXmac *xmac_p; - u32 status = FT_SUCCESS; - xmac_p = &instance_p->instance; - - /* set mac address */ - status = FXmacSetMacAddress(xmac_p, (void*)(instance_p->hwaddr), 1); - if (status != FT_SUCCESS) - { - FXMAC_OS_XMAC_PRINT_E("In %s:Emac Mac Address set failed...\r\n",__func__); - } -} - - - -/* step 1: initialize instance */ -/* step 2: depend on config set some options : JUMBO / IGMP */ -/* step 3: FXmacSelectClk */ -/* step 4: FXmacInitInterface */ -/* step 5: initialize phy */ -/* step 6: initialize dma */ -/* step 7: initialize interrupt */ -/* step 8: start mac */ - -FError FXmacOsInit(FXmacOs *instance_p) -{ - FXmacConfig mac_config; - const FXmacConfig *mac_config_p; - FXmacPhyInterface interface = FXMAC_PHY_INTERFACE_MODE_SGMII; - FXmac *xmac_p; - u32 dmacrreg; - FError status; - FASSERT(instance_p != NULL); - FASSERT( instance_p->mac_config.instance_id < FT_XMAC_NUM); - - xmac_p = &instance_p->instance; - FXMAC_OS_XMAC_PRINT_I("instance_id IS %d \r\n",instance_p->mac_config.instance_id); - mac_config_p = FXmacLookupConfig(instance_p->mac_config.instance_id); - if(mac_config_p == NULL) - { - FXMAC_OS_XMAC_PRINT_E("FXmacLookupConfig is error , instance_id is %d",instance_p->mac_config.instance_id); - return FREERTOS_XMAC_INIT_ERROR; - } - mac_config = *mac_config_p; - switch (instance_p->mac_config.interface) - { - case FXMAC_OS_INTERFACE_SGMII: - interface = FXMAC_PHY_INTERFACE_MODE_SGMII; - FXMAC_OS_XMAC_PRINT_I("SGMII select"); - break; - case FXMAC_OS_INTERFACE_RMII: - interface = FXMAC_PHY_INTERFACE_MODE_RMII; - FXMAC_OS_XMAC_PRINT_I("RMII select"); - break; - case FXMAC_OS_INTERFACE_RGMII: - FXMAC_OS_XMAC_PRINT_I("RGMII select"); - interface = FXMAC_PHY_INTERFACE_MODE_RGMII; - break; - default: - FXMAC_OS_XMAC_PRINT_E("update interface is error , interface is %d",instance_p->mac_config.instance_id); - return FREERTOS_XMAC_INIT_ERROR; - } - mac_config.interface = interface; - - if(instance_p->mac_config.autonegotiation) - { - mac_config.auto_neg = 1; - } - else - { - mac_config.auto_neg = 0; - } - - switch (instance_p->mac_config.phy_speed) - { - case FXMAC_PHY_SPEED_10M: - mac_config.speed = FXMAC_SPEED_10; - break; - case FXMAC_PHY_SPEED_100M: - mac_config.speed = FXMAC_SPEED_100; - break; - case FXMAC_PHY_SPEED_1000M: - mac_config.speed = FXMAC_SPEED_1000; - break; - default: - FXMAC_OS_XMAC_PRINT_E("setting speed is not valid , speed is %d",instance_p->mac_config.phy_speed); - return FREERTOS_XMAC_INIT_ERROR; - } - - status = FXmacCfgInitialize(xmac_p, &mac_config); - if (status != FT_SUCCESS) - { - FXMAC_OS_XMAC_PRINT_E("In %s:EmacPs Configuration Failed....\r\n", __func__); - } - - if(instance_p->config & FXMAC_OS_CONFIG_JUMBO) - { - printf("FXMAC_JUMBO_ENABLE_OPTION is ok \r\n"); - FXmacSetOptions(xmac_p, FXMAC_JUMBO_ENABLE_OPTION, 0); - } - - if(instance_p->config & FXMAC_OS_CONFIG_MULTICAST_ADDRESS_FILITER) - { - FXmacSetOptions(xmac_p, FXMAC_MULTICAST_OPTION,0); - } - - /* enable copy all frames */ - if(instance_p->config & FXMAC_OS_CONFIG_COPY_ALL_FRAMES) - { - FXmacSetOptions(xmac_p, FXMAC_PROMISC_OPTION,0); - } - - status = FXmacSetMacAddress(xmac_p, (void*)(instance_p->hwaddr), 0); - if (status != FT_SUCCESS) - { - FXMAC_OS_XMAC_PRINT_E("In %s:Emac Mac Address set failed...\r\n",__func__); - } - - /* close fcs check */ - if(instance_p->config & FXMAC_OS_CONFIG_CLOSE_FCS_CHECK) - { - FXmacSetOptions(xmac_p, FXMAC_FCS_STRIP_OPTION,0); - } - - /* initialize phy */ - status = FXmacPhyInit(xmac_p,xmac_p->config.speed,xmac_p->config.duplex,xmac_p->config.auto_neg); - if (status != FT_SUCCESS) - { - FXMAC_OS_XMAC_PRINT_W("FXmacPhyInit is error \r\n"); - } - - FXmacSelectClk(xmac_p); - FXmacInitInterface(xmac_p); - - /* initialize dma */ - dmacrreg = FXMAC_READREG32(xmac_p->config.base_address, FXMAC_DMACR_OFFSET); - dmacrreg & ~(FXMAC_DMACR_BLENGTH_MASK); - dmacrreg = dmacrreg | FXMAC_DMACR_INCR16_AHB_AXI_BURST; /* Attempt to use bursts of up to 16. */ - FXMAC_WRITEREG32(xmac_p->config.base_address, FXMAC_DMACR_OFFSET, dmacrreg); - FXmacInitDma(instance_p); - - /* initialize interrupt */ - FXmacSetupIsr(instance_p); - - /* start mac */ - FXmacStart(&instance_p->instance); - return FT_SUCCESS; -} - - -FError FXmacOsConfig(FXmacOs *instance_p,int cmd ,void *arg) -{ - return FT_SUCCESS; -} - -/** - * @name: FXmacOsRx - * @msg: void *FXmacOsRx(FXmacOs *instance_p) - * @note: - * @param {FXmacOs} *instance_p - * @return {*} - */ -void *FXmacOsRx(FXmacOs *instance_p) -{ - FASSERT(instance_p != NULL); - struct pbuf *p; - - /* see if there is data to process */ - if (FXmacPqQlength(&instance_p->recv_q) == 0) - return NULL; - /* return one packet from receive q */ - p = (struct pbuf *)FXmacPqDequeue(&instance_p->recv_q); - - return p; -} - -static FError FXmacOsOutput(FXmacOs *instance_p, struct pbuf *p) -{ - FError status = 0; - status = FXmacSgsend(instance_p, p); - if (status != FT_SUCCESS) - { -#if LINK_STATS - lwip_stats.link.drop++; -#endif - } - - -#if LINK_STATS - lwip_stats.link.xmit++; -#endif /* LINK_STATS */ - - return status; -} - -FError FXmacOsTx(FXmacOs *instance_p,void *tx_buf) -{ - u32 freecnt; - FXmacBdRing *txring; - FError ret = FT_SUCCESS; - struct pbuf *p; - FASSERT(instance_p != NULL); - if(tx_buf == NULL) - { - FXMAC_OS_XMAC_PRINT_E("tx_buf is null \r\n"); - return FREERTOS_XMAC_PARAM_ERROR; - } - - p = tx_buf; - - /* check if space is available to send */ - freecnt = IsTxSpaceAvailable(instance_p); - - if (freecnt <= 5) - { - txring = &(FXMAC_GET_TXRING(instance_p->instance)); - FXmacProcessSentBds(instance_p, txring); - } - - if (IsTxSpaceAvailable(instance_p)) - { - FXmacOsOutput(instance_p, p); - ret = FT_SUCCESS; - } - else - { -#if LINK_STATS - lwip_stats.link.drop++; -#endif - FXMAC_OS_XMAC_PRINT_E("pack dropped, no space\r\n"); - ret = FREERTOS_XMAC_NO_VALID_SPACE; - } - - return ret ; -} - -FXmacOs *FXmacOsGetInstancePointer(FXmacOsControl *config_p) -{ - FXmacOs *instance_p; - FASSERT(config_p != NULL); - FASSERT(config_p->instance_id < FT_XMAC_NUM); - FASSERT_MSG(config_p->interface < FXMAC_OS_INTERFACE_LENGTH ,"config_p->interface %d is over %d",config_p->interface ,FXMAC_OS_INTERFACE_LENGTH); - FASSERT_MSG(config_p->autonegotiation <= 1 ,"config_p->autonegotiation %d is over 1",config_p->autonegotiation ); - FASSERT_MSG(config_p->phy_speed <= FXMAC_PHY_SPEED_1000M ,"config_p->phy_speed %d is over 1000",config_p->phy_speed ); - FASSERT_MSG(config_p->phy_duplex <= FXMAC_PHY_FULL_DUPLEX ,"config_p->phy_duplex %d is over FXMAC_PHY_FULL_DUPLEX",config_p->phy_duplex ); - - instance_p = &fxmac_os_instace[config_p->instance_id]; - memcpy(&instance_p->mac_config,config_p,sizeof(FXmacOsControl)); - return instance_p; -} \ No newline at end of file diff --git a/drivers/eth/xmac/fxmac_os.c b/drivers/eth/xmac/fxmac_os.c new file mode 100644 index 00000000..817a0fe7 --- /dev/null +++ b/drivers/eth/xmac/fxmac_os.c @@ -0,0 +1,1383 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fxmac_os.c + * Date: 2022-07-15 16:33:13 + * LastEditTime: 2022-07-15 16:33:13 + * Description: This file is for xmac driver.Functions in this file are the minimum required functions for drivers. + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 huanghe 2022/11/15 first release + */ + +#include "fparameters.h" +#include "fassert.h" +#include "fxmac_os.h" +#include "fxmac.h" +#include "fcache.h" +#include "fxmac_bdring.h" +#include "lwip_port.h" +#include "eth_ieee_reg.h" +#include "fcpu_info.h" + +#ifdef __aarch64__ + #include "faarch64.h" +#else + #include "fcp15.h" +#endif + +#include "FreeRTOS.h" +#include "semphr.h" + +#include "fdebug.h" + +#define FXMAC_OS_XMAC_DEBUG_TAG "FXMAC_OS_XMAC" +#define FXMAC_OS_XMAC_PRINT_E(format, ...) FT_DEBUG_PRINT_E(FXMAC_OS_XMAC_DEBUG_TAG, format, ##__VA_ARGS__) +#define FXMAC_OS_XMAC_PRINT_I(format, ...) FT_DEBUG_PRINT_I(FXMAC_OS_XMAC_DEBUG_TAG, format, ##__VA_ARGS__) +#define FXMAC_OS_XMAC_PRINT_D(format, ...) FT_DEBUG_PRINT_D(FXMAC_OS_XMAC_DEBUG_TAG, format, ##__VA_ARGS__) +#define FXMAC_OS_XMAC_PRINT_W(format, ...) FT_DEBUG_PRINT_W(FXMAC_OS_XMAC_DEBUG_TAG, format, ##__VA_ARGS__) + +#define FXMAC_BD_TO_INDEX(ringptr, bdptr) \ + (((uintptr)bdptr - (uintptr)(ringptr)->base_bd_addr) / (ringptr)->separation) + +static void FXmacInitOnError(FXmacOs *instance_p); +static void FXmacSetupIsr(FXmacOs *instance_p); +extern void sys_sem_signal(sys_sem_t *sem); +static FXmacOs fxmac_os_instace[FXMAC_NUM] = +{ + [FXMAC0_ID] = {.config = (0)}, + [FXMAC1_ID] = {.config = (0)}, + [FXMAC2_ID] = {.config = (0)}, + [FXMAC3_ID] = {.config = (0)}, +}; + +int isr_calling_flg = 0; + +/* queue */ + +void FXmacQueueInit(PqQueue *q) +{ + FASSERT(q != NULL); + q->head = q->tail = q->len = 0; +} + +int FXmacPqEnqueue(PqQueue *q, void *p) +{ + if (q->len == PQ_QUEUE_SIZE) + { + return -1; + } + + q->data[q->head] = (uintptr)p; + q->head = (q->head + 1) % PQ_QUEUE_SIZE; + q->len++; + + return 0; +} + +void *FXmacPqDequeue(PqQueue *q) +{ + int ptail; + + if (q->len == 0) + { + return NULL; + } + + ptail = q->tail; + q->tail = (q->tail + 1) % PQ_QUEUE_SIZE; + q->len--; + + return (void *)q->data[ptail]; +} + +int FXmacPqQlength(PqQueue *q) +{ + return q->len; +} + +/* dma */ + +/** + * @name: IsTxSpaceAvailable + * @msg: 获取当前bdring 剩余计数 + * @param {ethernetif} *ethernetif_p + * @return {*} 返回 + */ +static u32 IsTxSpaceAvailable(FXmacOs *instance_p) +{ + FXmacBdRing *txring; + u32 freecnt = 0; + FASSERT(instance_p != NULL); + + txring = &(FXMAC_GET_TXRING(instance_p->instance)); + + /* tx space is available as long as there are valid BD's */ + freecnt = FXMAC_BD_RING_GET_FREE_CNT(txring); + return freecnt; +} + +/** + * @name: FXmacProcessSentBds + * @msg: 释放发送队列q参数 + * @return {*} + * @param {ethernetif} *ethernetif_p + * @param {FXmacBdRing} *txring + */ +void FXmacProcessSentBds(FXmacOs *instance_p, FXmacBdRing *txring) +{ + FXmacBd *txbdset; + FXmacBd *curbdpntr; + u32 n_bds; + FError status; + u32 n_pbufs_freed = 0; + u32 bdindex; + struct pbuf *p; + u32 *temp; + + while (1) + { + /* obtain processed BD's */ + n_bds = FXmacBdRingFromHwTx(txring, FXMAX_TX_PBUFS_LENGTH, &txbdset); + if (n_bds == 0) + { + return; + } + /* free the processed BD's */ + n_pbufs_freed = n_bds; + curbdpntr = txbdset; + while (n_pbufs_freed > 0) + { + bdindex = FXMAC_BD_TO_INDEX(txring, curbdpntr); + temp = (u32 *)curbdpntr; + *temp = 0; /* Word 0 */ + temp++; + if (bdindex == (FXMAX_TX_PBUFS_LENGTH - 1)) + { + *temp = 0xC0000000; /* Word 1 ,used/Wrap – marks last descriptor in transmit buffer descriptor list.*/ + } + else + { + *temp = 0x80000000; /* Word 1 , Used – must be zero for GEM to read data to the transmit buffer.*/ + } + DSB(); + + p = (struct pbuf *)instance_p->buffer.tx_pbufs_storage[bdindex]; + + if (p != NULL) + { + pbuf_free(p); + } + instance_p->buffer.tx_pbufs_storage[bdindex] = (uintptr)NULL; + curbdpntr = FXMAC_BD_RING_NEXT(txring, curbdpntr); + n_pbufs_freed--; + DSB(); + } + + status = FXmacBdRingFree(txring, n_bds, txbdset); + if (status != FT_SUCCESS) + { + FXMAC_OS_XMAC_PRINT_I("Failure while freeing in Tx Done ISR."); + } + } + return; +} + +void FXmacSendHandler(void *arg) +{ + FXmacOs *instance_p; + FXmacBdRing *txringptr; + u32 regval; + + instance_p = (FXmacOs *)arg; + txringptr = &(FXMAC_GET_TXRING(instance_p->instance)); + regval = FXMAC_READREG32(instance_p->instance.config.base_address, FXMAC_TXSR_OFFSET); + FXMAC_WRITEREG32(instance_p->instance.config.base_address, FXMAC_TXSR_OFFSET, regval); /* 清除中断状态位来停止中断 */ + + /* If Transmit done interrupt is asserted, process completed BD's */ + FXmacProcessSentBds(instance_p, txringptr); +} + +FError FXmacSgsend(FXmacOs *instance_p, struct pbuf *p) +{ + struct pbuf *q; + u32 n_pbufs; + FXmacBd *txbdset, *txbd, *last_txbd = NULL; + FXmacBd *temp_txbd; + FError status; + FXmacBdRing *txring; + u32 bdindex; + u32 lev; + u32 max_fr_size; + + lev = MFCPSR(); + MTCPSR(lev | 0xC0); /* Mask IRQ and FIQ interrupts in cpsr */ + + txring = &(FXMAC_GET_TXRING(instance_p->instance)); + + /* first count the number of pbufs */ + for (q = p, n_pbufs = 0; q != NULL; q = q->next) + { + n_pbufs++; + } + + /* obtain as many BD's */ + status = FXmacBdRingAlloc(txring, n_pbufs, &txbdset); + if (status != FT_SUCCESS) + { + MTCPSR(lev); + FXMAC_OS_XMAC_PRINT_I("sgsend: Error allocating TxBD."); + return ERR_GENERAL; + } + + for (q = p, txbd = txbdset; q != NULL; q = q->next) + { + bdindex = FXMAC_BD_TO_INDEX(txring, txbd); + + if (instance_p->buffer.tx_pbufs_storage[bdindex]) + { + MTCPSR(lev); + FXMAC_OS_XMAC_PRINT_I("txbd %p, txring->base_bd_addr %p", txbd, txring->base_bd_addr); + FXMAC_OS_XMAC_PRINT_I("PBUFS not available bdindex is %d ", bdindex); + FXMAC_OS_XMAC_PRINT_I("instance_p->buffer.tx_pbufs_storage[bdindex] %p ", instance_p->buffer.tx_pbufs_storage[bdindex]); + return ERR_GENERAL; + } + + /* Send the data from the pbuf to the interface, one pbuf at a + time. The size of the data in each pbuf is kept in the ->len + variable. */ + FCacheDCacheFlushRange((uintptr)q->payload, (uintptr)q->len); + FXMAC_BD_SET_ADDRESS_TX(txbd, (uintptr)q->payload); + + if (instance_p->config & FXMAC_OS_CONFIG_JUMBO) + { + max_fr_size = FXMAC_MAX_FRAME_SIZE_JUMBO - 18; + } + else + { + max_fr_size = FXMAC_MAX_FRAME_SIZE - 18; + } + + if (q->len > max_fr_size) + { + FXMAC_BD_SET_LENGTH(txbd, max_fr_size & 0x3FFF); + } + else + { + FXMAC_BD_SET_LENGTH(txbd, q->len & 0x3FFF); + } + + instance_p->buffer.tx_pbufs_storage[bdindex] = (uintptr)q; + + pbuf_ref(q); + last_txbd = txbd; + FXMAC_BD_CLEAR_LAST(txbd); + txbd = FXMAC_BD_RING_NEXT(txring, txbd); + } + FXMAC_BD_SET_LAST(last_txbd); + /* For fragmented packets, remember the 1st BD allocated for the 1st + packet fragment. The used bit for this BD should be cleared at the end + after clearing out used bits for other fragments. For packets without + just remember the allocated BD. */ + temp_txbd = txbdset; + txbd = txbdset; + txbd = FXMAC_BD_RING_NEXT(txring, txbd); + q = p->next; + for (; q != NULL; q = q->next) + { + FXMAC_BD_CLEAR_TX_USED(txbd); + DSB(); + txbd = FXMAC_BD_RING_NEXT(txring, txbd); + } + FXMAC_BD_CLEAR_TX_USED(temp_txbd); + DSB(); + + status = FXmacBdRingToHw(txring, n_pbufs, txbdset); + if (status != FT_SUCCESS) + { + MTCPSR(lev); + FXMAC_OS_XMAC_PRINT_I("sgsend: Error submitting TxBD."); + return ERR_GENERAL; + } + /* Start transmit */ + FXMAC_WRITEREG32((instance_p->instance).config.base_address, + FXMAC_NWCTRL_OFFSET, + (FXMAC_READREG32(instance_p->instance.config.base_address, + FXMAC_NWCTRL_OFFSET) | + FXMAC_NWCTRL_STARTTX_MASK)); + + MTCPSR(lev); + + return status; +} + +void SetupRxBds(FXmacOs *instance_p, FXmacBdRing *rxring) +{ + FXmacBd *rxbd; + FError status; + struct pbuf *p; + u32 freebds; + u32 bdindex; + u32 *temp; + freebds = FXMAC_BD_RING_GET_FREE_CNT(rxring); + while (freebds > 0) + { + freebds--; + + if (instance_p->config & FXMAC_OS_CONFIG_JUMBO) + { + p = pbuf_alloc(PBUF_RAW, FXMAC_MAX_FRAME_SIZE_JUMBO, PBUF_POOL); + } + else + { + p = pbuf_alloc(PBUF_RAW, FXMAC_MAX_FRAME_SIZE, PBUF_POOL); + } + + if (!p) + { +#if LINK_STATS + lwip_stats.link.memerr++; + lwip_stats.link.drop++; +#endif + FXMAC_OS_XMAC_PRINT_I("Unable to alloc pbuf in recv_handler."); + return; + } + status = FXmacBdRingAlloc(rxring, 1, &rxbd); + if (status != FT_SUCCESS) + { + FXMAC_OS_XMAC_PRINT_I("SetupRxBds: Error allocating RxBD."); + pbuf_free(p); + return; + } + status = FXmacBdRingToHw(rxring, 1, rxbd); + if (status != FT_SUCCESS) + { + FXMAC_OS_XMAC_PRINT_I("Error committing RxBD to hardware: "); + if (status == FXMAC_ERR_SG_LIST) + { + FXMAC_OS_XMAC_PRINT_I("XST_DMA_SG_LIST_ERROR: this function was called out of sequence with FXmacBdRingAlloc()."); + } + else + { + FXMAC_OS_XMAC_PRINT_I("Set of BDs was rejected because the first BD did not have its start-of-packet bit set, or the last BD did not have its end-of-packet bit set, or any one of the BD set has 0 as length value."); + } + + pbuf_free(p); + FXmacBdRingUnAlloc(rxring, 1, rxbd); + return; + } + + if (instance_p->config & FXMAC_OS_CONFIG_JUMBO) + { + FCacheDCacheInvalidateRange((uintptr)p->payload, (uintptr)MAX_FRAME_SIZE_JUMBO); + } + else + { + FCacheDCacheInvalidateRange((uintptr)p->payload, (uintptr)FXMAC_MAX_FRAME_SIZE); + } + + bdindex = FXMAC_BD_TO_INDEX(rxring, rxbd); + temp = (u32 *)rxbd; + if (bdindex == (FXMAX_RX_PBUFS_LENGTH - 1)) + { + *temp = 0x00000002; + } + else + { + *temp = 0; + } + temp++; + *temp = 0; + DSB(); + + FXMAC_BD_SET_ADDRESS_RX(rxbd, (uintptr)p->payload); + instance_p->buffer.rx_pbufs_storage[bdindex] = (uintptr)p; + } +} + +void FXmacRecvHandler(void *arg) +{ + struct pbuf *p; + FXmacBd *rxbdset, *curbdptr; + struct LwipPort *xmac_netif_p; + FXmacBdRing *rxring; + volatile u32 bd_processed; + u32 rx_bytes, k; + u32 bdindex; + u32 regval; + u32 index; + u32 gigeversion; + FXmacOs *instance_p; + FASSERT(arg != NULL); + + instance_p = (FXmacOs *)arg; + xmac_netif_p = (struct LwipPort *)instance_p->stack_pointer; + rxring = &FXMAC_GET_RXRING(instance_p->instance); + + /* If Reception done interrupt is asserted, call RX call back function + to handle the processed BDs and then raise the according flag.*/ + regval = FXMAC_READREG32(instance_p->instance.config.base_address, FXMAC_RXSR_OFFSET); + FXMAC_WRITEREG32(instance_p->instance.config.base_address, FXMAC_RXSR_OFFSET, regval); + + while (1) + { + bd_processed = FXmacBdRingFromHwRx(rxring, FXMAX_RX_PBUFS_LENGTH, &rxbdset); + if (bd_processed <= 0) + { + break; + } + + for (k = 0, curbdptr = rxbdset; k < bd_processed; k++) + { + + bdindex = FXMAC_BD_TO_INDEX(rxring, curbdptr); + p = (struct pbuf *)instance_p->buffer.rx_pbufs_storage[bdindex]; + /* + * Adjust the buffer size to the actual number of bytes received. + */ + if (instance_p->config & FXMAC_OS_CONFIG_JUMBO) + { + rx_bytes = FXMAC_GET_RX_FRAME_SIZE(&(instance_p->instance), curbdptr); + } + else + { + rx_bytes = FXMAC_BD_GET_LENGTH(curbdptr); + } + pbuf_realloc(p, rx_bytes); + + /* Invalidate RX frame before queuing to handle + * L1 cache prefetch conditions on any architecture. + */ + FCacheDCacheInvalidateRange((uintptr)p->payload, rx_bytes); + + /* store it in the receive queue, + * where it'll be processed by a different handler + */ + if (FXmacPqEnqueue(&instance_p->recv_q, (void *)p) < 0) + { +#if LINK_STATS + lwip_stats.link.memerr++; + lwip_stats.link.drop++; +#endif + pbuf_free(p); + } + instance_p->buffer.rx_pbufs_storage[bdindex] = (uintptr)NULL; + curbdptr = FXMAC_BD_RING_NEXT(rxring, curbdptr); + } + + /* free up the BD's */ + FXmacBdRingFree(rxring, bd_processed, rxbdset); + SetupRxBds(instance_p, rxring); +#if !NO_SYS + sys_sem_signal(&xmac_netif_p->sem_rx_data_available); +#endif + } + + return; +} + +void CleanDmaTxdescs(FXmacOs *instance_p) +{ + FXmacBd bdtemplate; + FXmacBdRing *txringptr; + + txringptr = &FXMAC_GET_TXRING((instance_p->instance)); + FXMAC_BD_CLEAR(&bdtemplate); + FXMAC_BD_SET_STATUS(&bdtemplate, FXMAC_TXBUF_USED_MASK); + + FXmacBdRingCreate(txringptr, (uintptr)instance_p->buffer.tx_bdspace, + (uintptr)instance_p->buffer.tx_bdspace, BD_ALIGNMENT, + sizeof(instance_p->buffer.tx_bdspace)); + + FXmacBdRingClone(txringptr, &bdtemplate, FXMAC_SEND); +} + +FError FXmacInitDma(FXmacOs *instance_p) +{ + FXmacBd bdtemplate; + FXmacBdRing *rxringptr, *txringptr; + FXmacBd *rxbd; + struct pbuf *p; + FError status; + int i; + u32 bdindex; + volatile uintptr tempaddress; + u32 gigeversion; + FXmacBd *bdtxterminate; + FXmacBd *bdrxterminate; + u32 *temp; + + + /* + * The BDs need to be allocated in uncached memory. Hence the 1 MB + * address range allocated for Bd_Space is made uncached + * by setting appropriate attributes in the translation table. + * The Bd_Space is aligned to 1MB and has a size of 1 MB. This ensures + * a reserved uncached area used only for BDs. + */ + + rxringptr = &FXMAC_GET_RXRING(instance_p->instance); + txringptr = &FXMAC_GET_TXRING(instance_p->instance); + FXMAC_OS_XMAC_PRINT_I("rxringptr: 0x%08x", rxringptr); + FXMAC_OS_XMAC_PRINT_I("txringptr: 0x%08x", txringptr); + + FXMAC_OS_XMAC_PRINT_I("rx_bdspace: %p ", instance_p->buffer.rx_bdspace); + FXMAC_OS_XMAC_PRINT_I("tx_bdspace: %p ", instance_p->buffer.tx_bdspace); + + /* Setup RxBD space. */ + FXMAC_BD_CLEAR(&bdtemplate); + + /* Create the RxBD ring */ + status = FXmacBdRingCreate(rxringptr, (uintptr)instance_p->buffer.rx_bdspace, + (uintptr)instance_p->buffer.rx_bdspace, BD_ALIGNMENT, + FXMAX_RX_PBUFS_LENGTH); + + if (status != FT_SUCCESS) + { + FXMAC_OS_XMAC_PRINT_I("Error setting up RxBD space."); + return ERR_IF; + } + + status = FXmacBdRingClone(rxringptr, &bdtemplate, FXMAC_RECV); + if (status != FT_SUCCESS) + { + FXMAC_OS_XMAC_PRINT_I("Error initializing RxBD space."); + return ERR_IF; + } + + FXMAC_BD_CLEAR(&bdtemplate); + FXMAC_BD_SET_STATUS(&bdtemplate, FXMAC_TXBUF_USED_MASK); + + /* Create the TxBD ring */ + status = FXmacBdRingCreate(txringptr, (uintptr)instance_p->buffer.tx_bdspace, + (uintptr)instance_p->buffer.tx_bdspace, BD_ALIGNMENT, + FXMAX_TX_PBUFS_LENGTH); + + if (status != FT_SUCCESS) + { + return ERR_IF; + } + + /* We reuse the bd template, as the same one will work for both rx and tx. */ + status = FXmacBdRingClone(txringptr, &bdtemplate, FXMAC_SEND); + if (status != FT_SUCCESS) + { + return ERR_IF; + } + + /* + * Allocate RX descriptors, 1 RxBD at a time. + */ + for (i = 0; i < FXMAX_RX_PBUFS_LENGTH; i++) + { + if (instance_p->config & FXMAC_OS_CONFIG_JUMBO) + { + p = pbuf_alloc(PBUF_RAW, FXMAC_MAX_FRAME_SIZE_JUMBO, PBUF_POOL); + } + else + { + p = pbuf_alloc(PBUF_RAW, FXMAC_MAX_FRAME_SIZE, PBUF_POOL); + } + + if (!p) + { +#if LINK_STATS + lwip_stats.link.memerr++; + lwip_stats.link.drop++; +#endif + FXMAC_OS_XMAC_PRINT_E("Unable to alloc pbuf in InitDma."); + return ERR_IF; + } + status = FXmacBdRingAlloc(rxringptr, 1, &rxbd); + if (status != FT_SUCCESS) + { + FXMAC_OS_XMAC_PRINT_E("InitDma: Error allocating RxBD."); + pbuf_free(p); + return ERR_IF; + } + /* Enqueue to HW */ + status = FXmacBdRingToHw(rxringptr, 1, rxbd); + if (status != FT_SUCCESS) + { + FXMAC_OS_XMAC_PRINT_E("Error: committing RxBD to HW."); + pbuf_free(p); + FXmacBdRingUnAlloc(rxringptr, 1, rxbd); + return ERR_IF; + } + + bdindex = FXMAC_BD_TO_INDEX(rxringptr, rxbd); + temp = (u32 *)rxbd; + *temp = 0; + if (bdindex == (FXMAX_RX_PBUFS_LENGTH - 1)) + { + *temp = 0x00000002; + } + temp++; + *temp = 0; + DSB(); + + if (instance_p->config & FXMAC_OS_CONFIG_JUMBO) + { + FCacheDCacheInvalidateRange((uintptr)p->payload, (uintptr)MAX_FRAME_SIZE_JUMBO); + } + else + { + FCacheDCacheInvalidateRange((uintptr)p->payload, (uintptr)FXMAC_MAX_FRAME_SIZE); + } + FXMAC_BD_SET_ADDRESS_RX(rxbd, (uintptr)p->payload); + + instance_p->buffer.rx_pbufs_storage[bdindex] = (uintptr)p; + } + + FXmacSetQueuePtr(&(instance_p->instance), instance_p->instance.tx_bd_queue.bdring.base_bd_addr, 0, (u16)FXMAC_SEND); + FXmacSetQueuePtr(&(instance_p->instance), instance_p->instance.rx_bd_queue.bdring.base_bd_addr, 0, (u16)FXMAC_RECV); + + return 0; +} + +static void FreeOnlyTxPbufs(FXmacOs *instance_p) +{ + u32 index; + struct pbuf *p; + + for (index = 0; index < (FXMAX_TX_PBUFS_LENGTH); index++) + { + if (instance_p->buffer.tx_pbufs_storage[index] != 0) + { + p = (struct pbuf *)instance_p->buffer.tx_pbufs_storage[index]; + pbuf_free(p); + instance_p->buffer.tx_pbufs_storage[index] = (uintptr)NULL; + } + instance_p->buffer.tx_pbufs_storage[index] = (uintptr)0; + } +} + + +static void FreeOnlyRxPbufs(FXmacOs *instance_p) +{ + u32 index; + struct pbuf *p; + + for (index = 0; index < (FXMAX_RX_PBUFS_LENGTH); index++) + { + if (instance_p->buffer.rx_pbufs_storage[index] != 0) + { + p = (struct pbuf *)instance_p->buffer.rx_pbufs_storage[index]; + pbuf_free(p); + instance_p->buffer.rx_pbufs_storage[index] = (uintptr)0; + } + } +} + + +static void FreeTxRxPbufs(FXmacOs *instance_p) +{ + u32 rx_queue_len = 0; + struct pbuf *p; + /* first :free PqQueue data */ + rx_queue_len = FXmacPqQlength(&instance_p->recv_q); + + while (rx_queue_len) + { + /* return one packet from receive q */ + p = (struct pbuf *)FXmacPqDequeue(&instance_p->recv_q); + pbuf_free(p); + FXMAC_OS_XMAC_PRINT_E("Delete queue %p", p); + rx_queue_len--; + } + FreeOnlyTxPbufs(instance_p); + FreeOnlyRxPbufs(instance_p); + +} + + + +static void ResetDma(FXmacOs *instance_p) +{ + u8 txqueuenum; + u32 gigeversion; + + FXmacBdRing *txringptr = &FXMAC_GET_TXRING(instance_p->instance); + FXmacBdRing *rxringptr = &FXMAC_GET_RXRING(instance_p->instance); + + FXmacBdringPtrReset(txringptr, instance_p->buffer.tx_bdspace); + FXmacBdringPtrReset(rxringptr, instance_p->buffer.rx_bdspace); + + FXmacSetQueuePtr(&(instance_p->instance), instance_p->instance.tx_bd_queue.bdring.base_bd_addr, 0, (u16)FXMAC_SEND); + FXmacSetQueuePtr(&(instance_p->instance), instance_p->instance.rx_bd_queue.bdring.base_bd_addr, 0, (u16)FXMAC_RECV); +} + +/* interrupt */ +static void FXmacHandleDmaTxError(FXmacOs *instance_p) +{ + s32_t status = FT_SUCCESS; + u32 dmacrreg; + + FreeTxRxPbufs(instance_p); + status = FXmacCfgInitialize(&instance_p->instance, &instance_p->instance.config); + + if (status != FT_SUCCESS) + { + FXMAC_OS_XMAC_PRINT_E("In %s:EmacPs Configuration Failed....", __func__); + } + + /* initialize the mac */ + FXmacInitOnError(instance_p); /* need to set mac filter address */ + dmacrreg = FXMAC_READREG32(instance_p->instance.config.base_address, FXMAC_DMACR_OFFSET); + dmacrreg = dmacrreg | (FXMAC_DMACR_ORCE_DISCARD_ON_ERR_MASK); /* force_discard_on_err */ + FXMAC_WRITEREG32(instance_p->instance.config.base_address, FXMAC_DMACR_OFFSET, dmacrreg); + FXmacSetupIsr(instance_p); + FXmacInitDma(instance_p); + + FXmacStart(&instance_p->instance); +} + +void FXmacHandleTxErrors(FXmacOs *instance_p) +{ + u32 netctrlreg; + + netctrlreg = FXMAC_READREG32(instance_p->instance.config.base_address, + FXMAC_NWCTRL_OFFSET); + netctrlreg = netctrlreg & (~FXMAC_NWCTRL_TXEN_MASK); + FXMAC_WRITEREG32(instance_p->instance.config.base_address, + FXMAC_NWCTRL_OFFSET, netctrlreg); + FreeOnlyTxPbufs(instance_p); + + CleanDmaTxdescs(instance_p); + netctrlreg = FXMAC_READREG32(instance_p->instance.config.base_address, FXMAC_NWCTRL_OFFSET); + netctrlreg = netctrlreg | (FXMAC_NWCTRL_TXEN_MASK); + FXMAC_WRITEREG32(instance_p->instance.config.base_address, FXMAC_NWCTRL_OFFSET, netctrlreg); +} + +void FXmacErrorHandler(void *arg, u8 direction, u32 error_word) +{ + FXmacBdRing *rxring; + FXmacBdRing *txring; + FXmacOs *instance_p; + + instance_p = (FXmacOs *)(arg); + rxring = &FXMAC_GET_RXRING(instance_p->instance); + txring = &FXMAC_GET_TXRING(instance_p->instance); + + if (error_word != 0) + { + switch (direction) + { + case FXMAC_RECV: + if (error_word & FXMAC_RXSR_HRESPNOK_MASK) + { + FXMAC_OS_XMAC_PRINT_I("Receive DMA error."); + FXmacHandleDmaTxError(instance_p); + } + if (error_word & FXMAC_RXSR_RXOVR_MASK) + { + FXMAC_OS_XMAC_PRINT_I("Receive over run."); + FXmacRecvHandler(instance_p); + SetupRxBds(instance_p, rxring); + } + if (error_word & FXMAC_RXSR_BUFFNA_MASK) + { + FXMAC_OS_XMAC_PRINT_I("Receive buffer not available."); + FXmacRecvHandler(arg); + SetupRxBds(instance_p, rxring); + } + break; + case FXMAC_SEND: + if (error_word & FXMAC_TXSR_HRESPNOK_MASK) + { + FXMAC_OS_XMAC_PRINT_I("Transmit DMA error."); + FXmacHandleDmaTxError(instance_p); + } + if (error_word & FXMAC_TXSR_URUN_MASK) + { + FXMAC_OS_XMAC_PRINT_I("Transmit under run."); + FXmacHandleTxErrors(instance_p); + } + if (error_word & FXMAC_TXSR_BUFEXH_MASK) + { + FXMAC_OS_XMAC_PRINT_I("Transmit buffer exhausted."); + FXmacHandleTxErrors(instance_p); + } + if (error_word & FXMAC_TXSR_RXOVR_MASK) + { + FXMAC_OS_XMAC_PRINT_I("Transmit retry excessed limits."); + FXmacHandleTxErrors(instance_p); + } + if (error_word & FXMAC_TXSR_FRAMERX_MASK) + { + FXMAC_OS_XMAC_PRINT_I("Transmit collision."); + FXmacProcessSentBds(instance_p, txring); + } + break; + } + } +} + +void FXmacLinkChange(void *args) +{ + u32 ctrl; + u32 link, link_status; + u32 speed; + u32 speed_bit; + u32 duplex; + u32 status = FT_SUCCESS; + + FXmac *xmac_p; + FXmacOs *instance_p; + + instance_p = (FXmacOs *)args; + xmac_p = &instance_p->instance; + + if (xmac_p->config.interface == FXMAC_PHY_INTERFACE_MODE_SGMII) + { + FXMAC_OS_XMAC_PRINT_I("xmac_p->config.base_address is %p", xmac_p->config.base_address); + ctrl = FXMAC_READREG32(xmac_p->config.base_address, FXMAC_PCS_AN_LP_OFFSET); + link = (ctrl & FXMAC_PCS_LINK_PARTNER_NEXT_PAGE_STATUS) >> 15; + FXMAC_OS_XMAC_PRINT_I("Link status is 0x%x", link); + + switch (link) + { + case 0: + link_status = FXMAC_LINKDOWN; + break; + case 1: + link_status = FXMAC_LINKUP; + break; + default: + FXMAC_OS_XMAC_PRINT_E("Link status is error 0x%x ", link); + return; + } + + if (xmac_p->config.auto_neg == 0) + { + if (link_status == FXMAC_LINKUP) + { + FXMAC_OS_XMAC_PRINT_I("No neg link up (%d/%s)", xmac_p->config.speed, xmac_p->config.duplex == 1 ? "FULL" : "Half"); + xmac_p->link_status = FXMAC_NEGOTIATING; + } + else + { + FXMAC_OS_XMAC_PRINT_I("No neg link down."); + xmac_p->link_status = FXMAC_LINKDOWN; + } + } + + /* read sgmii reg to get status */ + ctrl = FXMAC_READREG32(xmac_p->config.base_address, FXMAC_PCS_AN_LP_OFFSET); + speed_bit = (ctrl & FXMAC_PCS_AN_LP_SPEED) >> FXMAC_PCS_AN_LP_SPEED_OFFSET; + duplex = (ctrl & FXMAC_PCS_AN_LP_DUPLEX) >> FXMAC_PCS_AN_LP_DUPLEX_OFFSET; + + if (speed_bit == 2) + { + speed = FXMAC_SPEED_1000; + } + else if (speed_bit == 1) + { + speed = FXMAC_SPEED_100; + } + else + { + speed = FXMAC_SPEED_10; + } + + if (link_status != xmac_p->link_status) + { + FXMAC_OS_XMAC_PRINT_I("Sgmii link_status has changed."); + } + + /* add erase NCFGR config */ + if ((speed != xmac_p->config.speed) || (duplex != xmac_p->config.duplex)) + { + FXMAC_OS_XMAC_PRINT_I("Sgmii link_status has changed."); + FXMAC_OS_XMAC_PRINT_I("New speed is %d, duplex is %d", speed, duplex); + } + + if (link_status == FXMAC_LINKUP) + { + if (link_status != xmac_p->link_status) + { + xmac_p->link_status = FXMAC_NEGOTIATING; + FXMAC_OS_XMAC_PRINT_I("Need NEGOTIATING."); + } + } + else + { + xmac_p->link_status = link_status; + FXMAC_OS_XMAC_PRINT_I("Change status is 0x%x", link_status); + } + } +} + +/* phy */ + +/** + * @name: FXmacPhyLinkDetect + * @msg: 获取当前link status + * @note: + * @param {FXmac} *fxmac_p + * @param {u32} phy_addr + * @return {*} 1 is link up , 0 is link down + */ +static u32 FXmacPhyLinkDetect(FXmac *xmac_p, u32 phy_addr) +{ + u16 status; + + /* Read Phy Status register twice to get the confirmation of the current + * link status. + */ + + FXmacPhyRead(xmac_p, phy_addr, PHY_STATUS_REG_OFFSET, &status); + + if (status & PHY_STAT_LINK_STATUS) + { + return 1; + } + return 0; +} + +static u32 FXmacPhyAutonegStatus(FXmac *xmac_p, u32 phy_addr) +{ + u16 status; + + /* Read Phy Status register twice to get the confirmation of the current + * link status. + */ + FXmacPhyRead(xmac_p, phy_addr, PHY_STATUS_REG_OFFSET, &status); + + if (status & PHY_STATUS_AUTONEGOTIATE_COMPLETE) + { + return 1; + } + return 0; +} + +enum lwip_port_link_status FXmacLwipPortLinkDetect(FXmacOs *instance_p) +{ + u32 link_speed, phy_link_status; + FXmac *xmac_p = &instance_p->instance; + + if (xmac_p->is_ready != (u32)FT_COMPONENT_IS_READY) + { + return ETH_LINK_UNDEFINED; + } + + phy_link_status = FXmacPhyLinkDetect(xmac_p, xmac_p->phy_address); + + if ((xmac_p->link_status == FXMAC_LINKUP) && (!phy_link_status)) + { + xmac_p->link_status = FXMAC_LINKDOWN; + } + + switch (xmac_p->link_status) + { + case FXMAC_LINKUP: + return ETH_LINK_UP; + case FXMAC_LINKDOWN: + xmac_p->link_status = FXMAC_NEGOTIATING; + FXMAC_OS_XMAC_PRINT_D("Ethernet Link down."); + return ETH_LINK_DOWN; + case FXMAC_NEGOTIATING: + if ((phy_link_status == FXMAC_LINKUP) && FXmacPhyAutonegStatus(xmac_p, xmac_p->phy_address)) + { + err_t phy_ret; + phy_ret = FXmacPhyInit(xmac_p, xmac_p->config.speed, xmac_p->config.duplex, xmac_p->config.auto_neg); + + if (phy_ret != FT_SUCCESS) + { + FXMAC_OS_XMAC_PRINT_E("FXmacPhyInit is error."); + return ETH_LINK_DOWN; + } + FXmacSelectClk(xmac_p); + FXmacInitInterface(xmac_p); + + /* Initiate Phy setup to get link speed */ + xmac_p->link_status = FXMAC_LINKUP; + FXMAC_OS_XMAC_PRINT_D("Ethernet Link up."); + return ETH_LINK_UP; + } + return ETH_LINK_DOWN; + default: + return ETH_LINK_DOWN; + } +} + +enum lwip_port_link_status FXmacPhyReconnect(struct LwipPort *xmac_netif_p) +{ + FXmac *xmac_p; + FXmacOs *instance_p; + + FASSERT(xmac_netif_p != NULL); + FASSERT(xmac_netif_p->state != NULL); + + instance_p = (FXmacOs *)(xmac_netif_p->state); + + xmac_p = &instance_p->instance; + + if (xmac_p->config.interface == FXMAC_PHY_INTERFACE_MODE_SGMII) + { + InterruptMask(xmac_p->config.queue_irq_num[0]); + if (xmac_p->link_status == FXMAC_NEGOTIATING) + { + /* 重新自协商 */ + err_t phy_ret; + phy_ret = FXmacPhyInit(xmac_p, xmac_p->config.speed, xmac_p->config.duplex, xmac_p->config.auto_neg); + if (phy_ret != FT_SUCCESS) + { + FXMAC_OS_XMAC_PRINT_I("FXmacPhyInit is error."); + InterruptUmask(xmac_p->config.queue_irq_num[0]); + return ETH_LINK_DOWN; + } + FXmacSelectClk(xmac_p); + FXmacInitInterface(xmac_p); + xmac_p->link_status = FXMAC_LINKUP; + } + + InterruptUmask(xmac_p->config.queue_irq_num[0]); + + switch (xmac_p->link_status) + { + case FXMAC_LINKDOWN: + return ETH_LINK_DOWN; + case FXMAC_LINKUP: + return ETH_LINK_UP; + default: + return ETH_LINK_DOWN; + } + } + else if ((xmac_p->config.interface == FXMAC_PHY_INTERFACE_MODE_RMII) || (xmac_p->config.interface == FXMAC_PHY_INTERFACE_MODE_RGMII)) + { + return FXmacLwipPortLinkDetect(instance_p); + } + else + { + switch (xmac_p->link_status) + { + case FXMAC_LINKDOWN: + return ETH_LINK_DOWN; + case FXMAC_LINKUP: + return ETH_LINK_UP; + default: + return ETH_LINK_DOWN; + } + } +} + +static void FxmacOsIntrHandler(s32 vector, void *args) +{ + isr_calling_flg++; + FXmacIntrHandler(vector, args); + isr_calling_flg--; +} + +static void FXmacDeinitIsr(FXmacOs *instance_p) +{ + InterruptMask(instance_p->instance.config.queue_irq_num[0]); +} + +static void FXmacSetupIsr(FXmacOs *instance_p) +{ + u32 cpu_id; + GetCpuId(&cpu_id); + InterruptSetTargetCpus(instance_p->instance.config.queue_irq_num[0], cpu_id); + /* Setup callbacks */ + FXmacSetHandler(&instance_p->instance, FXMAC_HANDLER_DMASEND, FXmacSendHandler, instance_p); + FXmacSetHandler(&instance_p->instance, FXMAC_HANDLER_DMARECV, FXmacRecvHandler, instance_p); + FXmacSetHandler(&instance_p->instance, FXMAC_HANDLER_ERROR, FXmacErrorHandler, instance_p); + FXmacSetHandler(&instance_p->instance, FXMAC_HANDLER_LINKCHANGE, FXmacLinkChange, instance_p); + + InterruptSetPriority(instance_p->instance.config.queue_irq_num[0], IRQ_PRIORITY_VALUE_12); + InterruptInstall(instance_p->instance.config.queue_irq_num[0], FxmacOsIntrHandler, &instance_p->instance, "fxmac"); + InterruptUmask(instance_p->instance.config.queue_irq_num[0]); +} + +/* init fxmac instance */ + +static void FXmacInitOnError(FXmacOs *instance_p) +{ + FXmac *xmac_p; + u32 status = FT_SUCCESS; + xmac_p = &instance_p->instance; + + /* set mac address */ + status = FXmacSetMacAddress(xmac_p, (void *)(instance_p->hwaddr), 1); + if (status != FT_SUCCESS) + { + FXMAC_OS_XMAC_PRINT_E("In %s:Emac Mac Address set failed...", __func__); + } +} + +/* step 1: initialize instance */ +/* step 2: depend on config set some options : JUMBO / IGMP */ +/* step 3: FXmacSelectClk */ +/* step 4: FXmacInitInterface */ +/* step 5: initialize phy */ +/* step 6: initialize dma */ +/* step 7: initialize interrupt */ +/* step 8: start mac */ + +FError FXmacOsInit(FXmacOs *instance_p) +{ + FXmacConfig mac_config; + const FXmacConfig *mac_config_p; + FXmacPhyInterface interface = FXMAC_PHY_INTERFACE_MODE_SGMII; + FXmac *xmac_p; + u32 dmacrreg; + FError status; + FASSERT(instance_p != NULL); + FASSERT(instance_p->mac_config.instance_id < FXMAC_NUM); + + xmac_p = &instance_p->instance; + FXMAC_OS_XMAC_PRINT_I("instance_id IS %d", instance_p->mac_config.instance_id); + mac_config_p = FXmacLookupConfig(instance_p->mac_config.instance_id); + if (mac_config_p == NULL) + { + FXMAC_OS_XMAC_PRINT_E("FXmacLookupConfig is error , instance_id is %d", instance_p->mac_config.instance_id); + return FREERTOS_XMAC_INIT_ERROR; + } + mac_config = *mac_config_p; + switch (instance_p->mac_config.interface) + { + case FXMAC_OS_INTERFACE_SGMII: + interface = FXMAC_PHY_INTERFACE_MODE_SGMII; + FXMAC_OS_XMAC_PRINT_I("SGMII select."); + break; + case FXMAC_OS_INTERFACE_RMII: + interface = FXMAC_PHY_INTERFACE_MODE_RMII; + FXMAC_OS_XMAC_PRINT_I("RMII select."); + break; + case FXMAC_OS_INTERFACE_RGMII: + FXMAC_OS_XMAC_PRINT_I("RGMII select."); + interface = FXMAC_PHY_INTERFACE_MODE_RGMII; + break; + default: + FXMAC_OS_XMAC_PRINT_E("Update interface is error , interface is %d", instance_p->mac_config.instance_id); + return FREERTOS_XMAC_INIT_ERROR; + } + mac_config.interface = interface; + + if (instance_p->mac_config.autonegotiation) + { + mac_config.auto_neg = 1; + } + else + { + mac_config.auto_neg = 0; + } + + switch (instance_p->mac_config.phy_speed) + { + case FXMAC_PHY_SPEED_10M: + mac_config.speed = FXMAC_SPEED_10; + break; + case FXMAC_PHY_SPEED_100M: + mac_config.speed = FXMAC_SPEED_100; + break; + case FXMAC_PHY_SPEED_1000M: + mac_config.speed = FXMAC_SPEED_1000; + break; + default: + FXMAC_OS_XMAC_PRINT_E("Setting speed is not valid , speed is %d", instance_p->mac_config.phy_speed); + return FREERTOS_XMAC_INIT_ERROR; + } + + switch (instance_p->mac_config.phy_duplex) + { + case FXMAC_PHY_HALF_DUPLEX: + mac_config.duplex = 0; + break; + case FXMAC_PHY_FULL_DUPLEX: + mac_config.duplex = 1; + break; + } + + status = FXmacCfgInitialize(xmac_p, &mac_config); + if (status != FT_SUCCESS) + { + FXMAC_OS_XMAC_PRINT_E("In %s:EmacPs Configuration Failed....", __func__); + } + + if (instance_p->config & FXMAC_OS_CONFIG_JUMBO) + { + FXmacSetOptions(xmac_p, FXMAC_JUMBO_ENABLE_OPTION, 0); + } + + if (instance_p->config & FXMAC_OS_CONFIG_MULTICAST_ADDRESS_FILITER) + { + FXmacSetOptions(xmac_p, FXMAC_MULTICAST_OPTION, 0); + } + + /* enable copy all frames */ + if (instance_p->config & FXMAC_OS_CONFIG_COPY_ALL_FRAMES) + { + FXmacSetOptions(xmac_p, FXMAC_PROMISC_OPTION, 0); + } + + status = FXmacSetMacAddress(xmac_p, (void *)(instance_p->hwaddr), 0); + if (status != FT_SUCCESS) + { + FXMAC_OS_XMAC_PRINT_E("In %s:Emac Mac Address set failed...", __func__); + } + + /* close fcs check */ + if (instance_p->config & FXMAC_OS_CONFIG_CLOSE_FCS_CHECK) + { + FXmacSetOptions(xmac_p, FXMAC_FCS_STRIP_OPTION, 0); + } + + /* initialize phy */ + status = FXmacPhyInit(xmac_p, xmac_p->config.speed, xmac_p->config.duplex, xmac_p->config.auto_neg); + if (status != FT_SUCCESS) + { + FXMAC_OS_XMAC_PRINT_W("FXmacPhyInit is error."); + } + + FXmacSelectClk(xmac_p); + FXmacInitInterface(xmac_p); + + /* initialize dma */ + dmacrreg = FXMAC_READREG32(xmac_p->config.base_address, FXMAC_DMACR_OFFSET); + dmacrreg & ~(FXMAC_DMACR_BLENGTH_MASK); + dmacrreg = dmacrreg | FXMAC_DMACR_INCR16_AHB_AXI_BURST; /* Attempt to use bursts of up to 16. */ + FXMAC_WRITEREG32(xmac_p->config.base_address, FXMAC_DMACR_OFFSET, dmacrreg); + FXmacInitDma(instance_p); + + + /* initialize interrupt */ + FXmacSetupIsr(instance_p); + + return FT_SUCCESS; +} + +FError FXmacOsConfig(FXmacOs *instance_p, int cmd, void *arg) +{ + return FT_SUCCESS; +} + +/** + * @name: FXmacOsRx + * @msg: void *FXmacOsRx(FXmacOs *instance_p) + * @note: + * @param {FXmacOs} *instance_p + * @return {*} + */ +void *FXmacOsRx(FXmacOs *instance_p) +{ + FASSERT(instance_p != NULL); + struct pbuf *p; + + /* see if there is data to process */ + if (FXmacPqQlength(&instance_p->recv_q) == 0) + { + return NULL; + } + /* return one packet from receive q */ + p = (struct pbuf *)FXmacPqDequeue(&instance_p->recv_q); + + return p; +} + +static FError FXmacOsOutput(FXmacOs *instance_p, struct pbuf *p) +{ + FError status = 0; + status = FXmacSgsend(instance_p, p); + if (status != FT_SUCCESS) + { +#if LINK_STATS + lwip_stats.link.drop++; +#endif + } + +#if LINK_STATS + lwip_stats.link.xmit++; +#endif /* LINK_STATS */ + + return status; +} + +FError FXmacOsTx(FXmacOs *instance_p, void *tx_buf) +{ + u32 freecnt; + FXmacBdRing *txring; + FError ret = FT_SUCCESS; + struct pbuf *p; + FASSERT(instance_p != NULL); + if (tx_buf == NULL) + { + FXMAC_OS_XMAC_PRINT_E("tx_buf is null."); + return FREERTOS_XMAC_PARAM_ERROR; + } + + p = tx_buf; + + /* check if space is available to send */ + freecnt = IsTxSpaceAvailable(instance_p); + + if (freecnt <= 5) + { + txring = &(FXMAC_GET_TXRING(instance_p->instance)); + FXmacProcessSentBds(instance_p, txring); + } + + if (IsTxSpaceAvailable(instance_p)) + { + FXmacOsOutput(instance_p, p); + ret = FT_SUCCESS; + } + else + { +#if LINK_STATS + lwip_stats.link.drop++; +#endif + FXMAC_OS_XMAC_PRINT_E("Pack dropped, no space."); + ret = FREERTOS_XMAC_NO_VALID_SPACE; + } + + return ret; +} + +FXmacOs *FXmacOsGetInstancePointer(FXmacOsControl *config_p) +{ + FXmacOs *instance_p; + FASSERT(config_p != NULL); + FASSERT(config_p->instance_id < FXMAC_NUM); + FASSERT_MSG(config_p->interface < FXMAC_OS_INTERFACE_LENGTH, "config_p->interface %d is over %d", config_p->interface, FXMAC_OS_INTERFACE_LENGTH); + FASSERT_MSG(config_p->autonegotiation <= 1, "config_p->autonegotiation %d is over 1", config_p->autonegotiation); + FASSERT_MSG(config_p->phy_speed <= FXMAC_PHY_SPEED_1000M, "config_p->phy_speed %d is over 1000", config_p->phy_speed); + FASSERT_MSG(config_p->phy_duplex <= FXMAC_PHY_FULL_DUPLEX, "config_p->phy_duplex %d is over FXMAC_PHY_FULL_DUPLEX", config_p->phy_duplex); + + instance_p = &fxmac_os_instace[config_p->instance_id]; + memcpy(&instance_p->mac_config, config_p, sizeof(FXmacOsControl)); + return instance_p; +} + + +void FXmacOsStop(FXmacOs *instance_p) +{ + FASSERT(instance_p != NULL); + /* step 1 close interrupt */ + FXmacDeinitIsr(instance_p); + /* step 2 close mac controler */ + FXmacStop(&instance_p->instance); + /* step 3 free all pbuf */ + FreeTxRxPbufs(instance_p); +} + +void FXmacOsStart(FXmacOs *instance_p) +{ + FASSERT(instance_p != NULL); + + /* start mac */ + FXmacStart(&instance_p->instance); +} \ No newline at end of file diff --git a/drivers/eth/xmac/ft_os_xmac.h b/drivers/eth/xmac/fxmac_os.h similarity index 63% rename from drivers/eth/xmac/ft_os_xmac.h rename to drivers/eth/xmac/fxmac_os.h index 9a1b357e..82fda055 100644 --- a/drivers/eth/xmac/ft_os_xmac.h +++ b/drivers/eth/xmac/fxmac_os.h @@ -1,30 +1,29 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * - * FilePath: ft_os_xmac.h + * See the Phytium Public License for more details. + * + * + * FilePath: fxmac_os.h * Date: 2022-07-15 16:33:19 * LastEditTime: 2022-07-15 16:33:19 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for xmac driver.Functions in this file are the minimum required functions for drivers. + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 huanghe 2022/11/15 first release */ - - -#ifndef DRIVERS_OS_XMAC_H -#define DRIVERS_OS_XMAC_H +#ifndef FXMAC_OS_H +#define FXMAC_OS_H #include #include @@ -33,15 +32,13 @@ #include "fkernel.h" #include "ferror_code.h" -#define FREERTOS_XMAC_INIT_ERROR FT_CODE_ERR(ErrModPort, 0, 0x1) -#define FREERTOS_XMAC_PARAM_ERROR FT_CODE_ERR(ErrModPort, 0, 0x2) -#define FREERTOS_XMAC_NO_VALID_SPACE FT_CODE_ERR(ErrModPort, 0, 0x3) - - #ifdef __cplusplus extern "C" { #endif +#define FREERTOS_XMAC_INIT_ERROR FT_CODE_ERR(ErrModPort, 0, 0x1) +#define FREERTOS_XMAC_PARAM_ERROR FT_CODE_ERR(ErrModPort, 0, 0x2) +#define FREERTOS_XMAC_NO_VALID_SPACE FT_CODE_ERR(ErrModPort, 0, 0x3) #define FXMAX_RX_BDSPACE_LENGTH 0x20000 /* default set 64KB*/ #define FXMAX_TX_BDSPACE_LENGTH 0x20000 /* default set 64KB*/ @@ -73,29 +70,29 @@ extern "C" { /* frame queue */ #define PQ_QUEUE_SIZE 4096 - typedef struct - { - uintptr data[PQ_QUEUE_SIZE]; - int head, tail, len; - } PqQueue; +typedef struct +{ + uintptr data[PQ_QUEUE_SIZE]; + int head, tail, len; +} PqQueue; - typedef enum - { - FXMAC_OS_INTERFACE_SGMII = 0 , - FXMAC_OS_INTERFACE_RMII , - FXMAC_OS_INTERFACE_RGMII , - FXMAC_OS_INTERFACE_LENGTH - }FXmacFreeRtosInterface; +typedef enum +{ + FXMAC_OS_INTERFACE_SGMII = 0, + FXMAC_OS_INTERFACE_RMII, + FXMAC_OS_INTERFACE_RGMII, + FXMAC_OS_INTERFACE_LENGTH +} FXmacFreeRtosInterface; typedef struct { - u8 rx_bdspace[FXMAX_RX_BDSPACE_LENGTH] __attribute__((aligned(128))); /* 接收bd 缓冲区 */ - u8 tx_bdspace[FXMAX_RX_BDSPACE_LENGTH] __attribute__((aligned(128))); /* 发送bd 缓冲区 */ + u8 rx_bdspace[FXMAX_RX_BDSPACE_LENGTH] __attribute__((aligned(128))); /* 接收bd 缓冲区 */ + u8 tx_bdspace[FXMAX_RX_BDSPACE_LENGTH] __attribute__((aligned(128))); /* 发送bd 缓冲区 */ + + uintptr rx_pbufs_storage[FXMAX_RX_PBUFS_LENGTH]; + uintptr tx_pbufs_storage[FXMAX_TX_PBUFS_LENGTH]; - uintptr rx_pbufs_storage[FXMAX_RX_PBUFS_LENGTH]; - uintptr tx_pbufs_storage[FXMAX_TX_PBUFS_LENGTH]; - } FXmacNetifBuffer; typedef struct @@ -115,21 +112,24 @@ typedef struct FXmacNetifBuffer buffer; /* queue to store overflow packets */ - PqQueue recv_q; - PqQueue send_q; + PqQueue recv_q; + PqQueue send_q; /* configuration */ u32 config; struct LwipPort *stack_pointer; /* Docking data stack data structure */ u8 hwaddr[FXMAX_MAX_HARDWARE_ADDRESS_LENGTH]; -}FXmacOs; +} FXmacOs; FXmacOs *FXmacOsGetInstancePointer(FXmacOsControl *config_p); FError FXmacOsInit(FXmacOs *instance_p); -FError FXmacOsConfig(FXmacOs *instance_p,int cmd ,void *arg); +FError FXmacOsConfig(FXmacOs *instance_p, int cmd, void *arg); void *FXmacOsRx(FXmacOs *instance_p); -FError FXmacOsTx(FXmacOs *instance_p,void *tx_buf); +FError FXmacOsTx(FXmacOs *instance_p, void *tx_buf); +void FXmacOsStop(FXmacOs *instance_p); +void FXmacOsStart(FXmacOs *instance_p); +enum lwip_port_link_status FXmacPhyReconnect(struct LwipPort *xmac_netif_p); #ifdef __cplusplus } diff --git a/drivers/gpio/fgpio/fgpio_os.c b/drivers/gpio/fgpio/fgpio_os.c index 292546f2..a6f4a1ca 100644 --- a/drivers/gpio/fgpio/fgpio_os.c +++ b/drivers/gpio/fgpio/fgpio_os.c @@ -1,22 +1,22 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: fgpio_os.c * Date: 2022-07-22 11:33:51 * LastEditTime: 2022-07-22 11:33:51 - * Description:  This files is for - * - * Modify History: + * Description:  This file is for required function implementations of gpio driver used in FreeRTOS. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- * 1.0 zhugengyu 2022/7/27 init commit @@ -52,10 +52,10 @@ static FFreeRTOSFGpio gpio[FGPIO_NUM]; /* instance of all gpio ctrl */ /*****************************************************************************/ static inline FError FGpioOsTakeSema(SemaphoreHandle_t locker) { - FASSERT_MSG((NULL != locker), "locker not exists"); + FASSERT_MSG((NULL != locker), "Locker not exists."); if (pdFALSE == xSemaphoreTake(locker, portMAX_DELAY)) { - FGPIO_ERROR("failed to give locker !!!"); + FGPIO_ERROR("Failed to give locker!!!"); return FFREERTOS_GPIO_SEMA_ERR; } @@ -64,10 +64,10 @@ static inline FError FGpioOsTakeSema(SemaphoreHandle_t locker) static inline void FGpioOsGiveSema(SemaphoreHandle_t locker) { - FASSERT_MSG((NULL != locker), "locker not exists"); + FASSERT_MSG((NULL != locker), "Locker not exists."); if (pdFALSE == xSemaphoreGive(locker)) { - FGPIO_ERROR("failed to give locker !!!"); + FGPIO_ERROR("Failed to give locker!!!"); } return; @@ -81,7 +81,7 @@ static inline void FGpioOsGetId(u32 pin_idx, FGpioPinId *pin_id) pin_id->ctrl = FFREERTOS_GPIO_PIN_CTRL_ID(pin_idx); pin_id->port = FFREERTOS_GPIO_PIN_PORT_ID(pin_idx); pin_id->pin = FFREERTOS_GPIO_PIN_ID(pin_idx); - FGPIO_INFO("pin index = 0x%x", pin_idx); + FGPIO_INFO("Pin index = 0x%x", pin_idx); FGPIO_INFO("is gpio-%d-%d-%d", pin_id->ctrl, pin_id->port, pin_id->pin); } @@ -94,18 +94,18 @@ static void FGpioOsSetupCtrlIRQ(FFreeRTOSFGpio *const instance) GetCpuId(&cpu_id); FGPIO_INFO("cpu_id is cpu_id %d", cpu_id); - InterruptSetTargetCpus(irq_num, cpu_id); + InterruptSetTargetCpus(irq_num, cpu_id); - /* setup interrupt */ - InterruptSetPriority(irq_num, FFREERTOS_GPIO_IRQ_PRIORITY); + /* setup interrupt */ + InterruptSetPriority(irq_num, FFREERTOS_GPIO_IRQ_PRIORITY); - /* register intr handler */ - InterruptInstall(irq_num, - FGpioInterruptHandler, - ctrl, - NULL); + /* register intr handler */ + InterruptInstall(irq_num, + FGpioInterruptHandler, + ctrl, + NULL); - InterruptUmask(irq_num); + InterruptUmask(irq_num); return; } @@ -119,7 +119,7 @@ static void FGpioOsSetupCtrlIRQ(FFreeRTOSFGpio *const instance) */ FFreeRTOSFGpio *FFreeRTOSGpioInit(u32 id, const FFreeRTOSGpioConfig *input_config) { - FASSERT_MSG(id < FGPIO_NUM, "invalid gpio id"); + FASSERT_MSG(id < FGPIO_NUM, "Invalid gpio id."); FFreeRTOSFGpio *instance = &gpio[id]; FGpio *ctrl = &instance->ctrl; FGpioConfig *config = &ctrl->config; @@ -127,7 +127,7 @@ FFreeRTOSFGpio *FFreeRTOSGpioInit(u32 id, const FFreeRTOSGpioConfig *input_confi if (FT_COMPONENT_IS_READY == ctrl->is_ready) { - FGPIO_WARN("gpio-%d already init", config->instance_id); + FGPIO_WARN("gpio-%d already init.", config->instance_id); return instance; } @@ -136,8 +136,8 @@ FFreeRTOSFGpio *FFreeRTOSGpioInit(u32 id, const FFreeRTOSGpioConfig *input_confi *config = *FGpioLookupConfig(id); err = FGpioCfgInitialize(ctrl, config); - if (FGPIO_SUCCESS != err) - { + if (FGPIO_SUCCESS != err) + { goto err_exit; } @@ -153,12 +153,12 @@ FFreeRTOSFGpio *FFreeRTOSGpioInit(u32 id, const FFreeRTOSGpioConfig *input_confi FGpioOsSetupCtrlIRQ(instance); } - FASSERT_MSG(NULL == instance->locker, "locker exists !!!"); - FASSERT_MSG((instance->locker = xSemaphoreCreateMutex()) != NULL, "create mutex failed !!!"); + FASSERT_MSG(NULL == instance->locker, "Locker exists!!!"); + FASSERT_MSG((instance->locker = xSemaphoreCreateMutex()) != NULL, "Create mutex failed!!!"); err_exit: taskEXIT_CRITICAL(); /* allow schedule after init */ - return (FT_SUCCESS == err) ? instance : NULL; /* exit with NULL if failed */ + return (FT_SUCCESS == err) ? instance : NULL; /* exit with NULL if failed */ } /** @@ -175,7 +175,7 @@ FError FFreeRTOSGpioDeInit(FFreeRTOSFGpio *const instance) if (FT_COMPONENT_IS_READY != ctrl->is_ready) { - FGPIO_WARN("gpio-%d not yet init", ctrl->config.instance_id); + FGPIO_WARN("gpio-%d not yet init.", ctrl->config.instance_id); return FFREERTOS_GPIO_NOT_INIT; } @@ -184,12 +184,12 @@ FError FFreeRTOSGpioDeInit(FFreeRTOSFGpio *const instance) FGpioDeInitialize(ctrl); - FASSERT_MSG(NULL != instance->locker, "locker not exists !!!"); + FASSERT_MSG(NULL != instance->locker, "Locker not exists!!!"); vSemaphoreDelete(instance->locker); instance->locker = NULL; taskEXIT_CRITICAL(); /* allow schedule after init */ - return err; + return err; } /* setup gpio pin interrupt */ @@ -204,11 +204,11 @@ static void FGpioOSSetupPinIRQ(FFreeRTOSFGpio *const instance, FGpioPin *const p InterruptSetTargetCpus(irq_num, cpu_id); - /* setup interrupt */ - InterruptSetPriority(irq_num, FFREERTOS_GPIO_IRQ_PRIORITY); + /* setup interrupt */ + InterruptSetPriority(irq_num, FFREERTOS_GPIO_IRQ_PRIORITY); - /* register intr handler */ - InterruptInstall(irq_num, config->irq_handler, config->irq_args, NULL); + /* register intr handler */ + InterruptInstall(irq_num, config->irq_handler, config->irq_args, NULL); InterruptUmask(irq_num); @@ -229,14 +229,16 @@ FError FFreeRTOSSetupPin(FFreeRTOSFGpio *const instance, const FFreeRTOSGpioPinC FGpioPinId pin_id; FGpioOsGetId(config->pin_idx, &pin_id); /* convert pin id */ u32 ctrl_id = ctrl->config.instance_id; - FASSERT_MSG((ctrl_id == pin_id.ctrl), "invalid instance for pin"); + FASSERT_MSG((ctrl_id == pin_id.ctrl), "Invalid instance for pin."); FGpioPin *const pin = &instance->pins[pin_id.port][pin_id.pin]; FError err = FT_SUCCESS; boolean irq_one_time = TRUE; err = FGpioOsTakeSema(instance->locker); if (FFREERTOS_GPIO_OK != err) + { return err; + } /* set io pad */ FIOPadSetGpioMux(ctrl_id, pin_id.pin); @@ -249,22 +251,22 @@ FError FFreeRTOSSetupPin(FFreeRTOSFGpio *const instance, const FFreeRTOSGpioPinC /* init pin */ err = FGpioPinInitialize(ctrl, pin, pin_id); - if (FGPIO_SUCCESS != err) - { - FGPIO_ERROR("init pin %d-%d failed, err: 0x%x", - pin_id.port, - pin_id.pin, - err); + if (FGPIO_SUCCESS != err) + { + FGPIO_ERROR("Init pin %d-%d failed, err: 0x%x", + pin_id.port, + pin_id.pin, + err); goto err_exit; - } + } /* setup pin direction */ FGpioSetDirection(pin, config->mode); - FGPIO_INFO("Set GPIO-%d-%c-%d direction %s", - pin_id.ctrl, - (FGPIO_PORT_A == pin_id.port) ? 'a' : 'b', - pin_id.pin, - (FGPIO_DIR_INPUT == config->mode) ? "IN" : "OUT"); + FGPIO_INFO("Set GPIO-%d-%c-%d direction %s", + pin_id.ctrl, + (FGPIO_PORT_A == pin_id.port) ? 'a' : 'b', + pin_id.pin, + (FGPIO_DIR_INPUT == config->mode) ? "IN" : "OUT"); /* setup input-pin irq */ if (TRUE == config->en_irq) @@ -280,7 +282,7 @@ FError FFreeRTOSSetupPin(FFreeRTOSFGpio *const instance, const FFreeRTOSGpioPinC err_exit: FGpioOsGiveSema(instance->locker); - return err; + return err; } /** @@ -298,18 +300,20 @@ FError FFreeRTOSSetIRQ(FFreeRTOSFGpio *const instance, u32 pin_idx, boolean en_i FGpioOsGetId(pin_idx, &pin_id); /* convert pin id */ FGpio *ctrl = &instance->ctrl; u32 ctrl_id = ctrl->config.instance_id; - FASSERT_MSG((ctrl_id == pin_id.ctrl), "invalid instance for pin"); + FASSERT_MSG((ctrl_id == pin_id.ctrl), "Invalid instance for pin."); FGpioPin *const pin = &instance->pins[pin_id.port][pin_id.pin]; FError err = FT_SUCCESS; err = FGpioOsTakeSema(instance->locker); if (FFREERTOS_GPIO_OK != err) + { return err; + } FGpioSetInterruptMask(pin, en_irq); FGpioOsGiveSema(instance->locker); - return err; + return err; } /** @@ -327,24 +331,26 @@ FError FFreeRTOSPinWrite(FFreeRTOSFGpio *const instance, u32 pin_idx, u32 value) FGpioOsGetId(pin_idx, &pin_id); /* convert pin id */ FGpio *ctrl = &instance->ctrl; u32 ctrl_id = ctrl->config.instance_id; - FASSERT_MSG((ctrl_id == pin_id.ctrl), "invalid instance for pin"); + FASSERT_MSG((ctrl_id == pin_id.ctrl), "Invalid instance for pin."); FGpioPin *const pin = &instance->pins[pin_id.port][pin_id.pin]; FError err = FT_SUCCESS; err = FGpioOsTakeSema(instance->locker); if (FFREERTOS_GPIO_OK != err) + { return err; + } err = FGpioSetOutputValue(pin, (FGpioPinVal)value); FGpioOsGiveSema(instance->locker); - return err; + return err; } /** * @name: FFreeRTOSPinRead * @msg: get input pin value - * @return {u32} level input by pin + * @return {u32} level input by pin * @param {FFreeRTOSFGpio} *instance, freertos gpio instance * @param {u32} pin_idx, index of gpio pin */ @@ -355,17 +361,19 @@ u32 FFreeRTOSPinRead(FFreeRTOSFGpio *const instance, u32 pin_idx) FGpioPinId pin_id; FGpioOsGetId(pin_idx, &pin_id); /* convert pin id */ u32 ctrl_id = ctrl->config.instance_id; - FASSERT_MSG((ctrl_id == pin_id.ctrl), "invalid instance for pin"); + FASSERT_MSG((ctrl_id == pin_id.ctrl), "Invalid instance for pin."); FGpioPin *const pin = &instance->pins[pin_id.port][pin_id.pin]; FError err = FT_SUCCESS; FGpioPinVal val = FGPIO_PIN_LOW; err = FGpioOsTakeSema(instance->locker); if (FFREERTOS_GPIO_OK != err) + { return val; + } val = FGpioGetInputValue(pin); FGpioOsGiveSema(instance->locker); - return val; + return val; } \ No newline at end of file diff --git a/drivers/gpio/fgpio/fgpio_os.h b/drivers/gpio/fgpio/fgpio_os.h index 9fd6e0b5..0db068c6 100644 --- a/drivers/gpio/fgpio/fgpio_os.h +++ b/drivers/gpio/fgpio/fgpio_os.h @@ -1,34 +1,29 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: fgpio_os.h * Date: 2022-07-22 11:33:45 * LastEditTime: 2022-07-22 11:33:45 - * Description:  This files is for - * - * Modify History: + * Description:  This file is for providing function related definitions of gpio driver used in FreeRTOS. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- * 1.0 zhugengyu 2022/7/27 init commit */ -#ifndef DRIVERS_FGPIO_OS_H -#define DRIVERS_FGPIO_OS_H - -#ifdef __cplusplus -extern "C" -{ -#endif +#ifndef FGPIO_OS_H +#define FGPIO_OS_H /***************************** Include Files *********************************/ #include #include @@ -37,8 +32,12 @@ extern "C" #include "fkernel.h" #include "fparameters.h" #include "fgpio.h" - /************************** Constant Definitions *****************************/ +#ifdef __cplusplus +extern "C" +{ +#endif + #define FFREERTOS_GPIO_OK FT_SUCCESS #define FFREERTOS_GPIO_NOT_INIT FT_CODE_ERR(ErrModPort, ErrBspGpio, 0) #define FFREERTOS_GPIO_SEMA_ERR FT_CODE_ERR(ErrModPort, ErrBspGpio, 1) diff --git a/drivers/i2c/fi2c_os.c b/drivers/i2c/fi2c_os.c new file mode 100644 index 00000000..da03c593 --- /dev/null +++ b/drivers/i2c/fi2c_os.c @@ -0,0 +1,384 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fi2c_os.c + * Date: 2022-07-15 10:43:29 + * LastEditTime: 2022-07-15 10:43:29 + * Description:  This file is for required function implementations of i2c driver used in FreeRTOS. + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 liushengming 2022/11/25 first commit + */ + +#include +#include +#include "fi2c_os.h" +#include "finterrupt.h" +#include "ftypes.h" +#include "sdkconfig.h" +#include "fcpu_info.h" +#include "fparameters.h" +#include "fi2c.h" +#include "fi2c_hw.h" +#include "fdebug.h" +#include "fpinctrl.h" +#if defined(CONFIG_TARGET_E2000) + #include "fmio_hw.h" + #include "fmio.h" + #include "fiopad.h" +#endif + +#if defined(CONFIG_TARGET_E2000) +static FMioCtrl i2c_master; +static FMioCtrl i2c_slave; +static FFreeRTOSI2c os_i2c[FMIO_NUM] = {0}; +#endif + +#if defined(CONFIG_TARGET_D2000) || defined(CONFIG_TARGET_F2000_4) +static FFreeRTOSI2c os_i2c[FI2C_NUM] = {0}; +#endif +/* virtual eeprom memory */ + + +static void FI2cMasterSlaveSetIoMux(u32 instance_id) +{ + /* D2000 use */ +#if defined(CONFIG_TARGET_D2000) + switch (instance_id) + { + case FI2C0_ID: + FPinSetFunc(FIOCTRL_I2C0_SCL_PAD, FPIN_FUNC0); + FPinSetFunc(FIOCTRL_I2C0_SDA_PAD, FPIN_FUNC0); + break; + case FI2C1_ID: + FPinSetFunc(FIOCTRL_ALL_PLL_LOCK_PAD, FPIN_FUNC2); + FPinSetFunc(FIOCTRL_CRU_CLK_OBV_PAD, FPIN_FUNC2); + break; + case FI2C2_ID: + FPinSetFunc(FIOCTRL_SWDO_SWJ_PAD, FPIN_FUNC2); + FPinSetFunc(FIOCTRL_TDO_SWJ_IN_PAD, FPIN_FUNC2); + break; + case FI2C3_ID: + FPinSetFunc(FIOCTRL_HDT_MB_DONE_STATE_PAD, FPIN_FUNC2); + FPinSetFunc(FIOCTRL_HDT_MB_FAIL_STATE_PAD, FPIN_FUNC2); + break; + default: + FASSERT(0); + break; + } +#endif +#if defined(CONFIG_TARGET_F2000_4) + FPinIndex sclpad_off, sdapad_off; + FPinFunc scl_fun, sda_fun; + switch (instance_id) + { + case FI2C0_ID: + sclpad_off = FIOCTRL_I2C0_SCL_PAD; /* i2c0-scl: func 0 */ + sdapad_off = FIOCTRL_I2C0_SDA_PAD; /* i2c0-sda: func 0 */ + scl_fun = FPIN_FUNC0; + sda_fun = FPIN_FUNC0; + break; + case FI2C1_ID: + sclpad_off = FIOCTRL_ALL_PLL_LOCK_PAD; /* i2c1-scl: func 2 */ + sdapad_off = FIOCTRL_CRU_CLK_OBV_PAD; /* i2c1-sda: func 2 */ + scl_fun = FPIN_FUNC2; + sda_fun = FPIN_FUNC2; + break; + case FI2C2_ID: + sclpad_off = FIOCTRL_SWDO_SWJ_PAD; /* i2c2-scl: func 2 */ + sdapad_off = FIOCTRL_TDO_SWJ_IN_PAD; /* i2c2-sda: func 2 */ + scl_fun = FPIN_FUNC2; + sda_fun = FPIN_FUNC2; + break; + case FI2C3_ID: + sclpad_off = FIOCTRL_HDT_MB_DONE_STATE_PAD; /* i2c3-scl: func 2 */ + sdapad_off = FIOCTRL_HDT_MB_FAIL_STATE_PAD; /* i2c3-sda: func 2 */ + scl_fun = FPIN_FUNC2; + sda_fun = FPIN_FUNC2; + break; + default: + FASSERT(0); + break; + } + FPinSetFunc(sclpad_off, scl_fun); + FPinSetFunc(sdapad_off, sda_fun); +#endif +} + + +/** + * @name: FI2cOsSetupInterrupt + * @msg: 设置i2c中断 + * @return {*} + * @param {FI2c} *pctrl + */ +static void FI2cOsSetupInterrupt(FI2c *pctrl) +{ + FASSERT(pctrl); + FI2cConfig *pconfig = &pctrl->config; + u32 cpu_id; + FError err = FREERTOS_I2C_SUCCESS; + + GetCpuId(&cpu_id); + vPrintf("cpu_id is %d \r\n", cpu_id); + InterruptSetTargetCpus(pconfig->irq_num, cpu_id); + + /* interrupt init */ + /* umask i2c irq */ + InterruptSetPriority(pconfig->irq_num, pconfig->irq_prority); + /* enable irq */ + InterruptUmask(pconfig->irq_num); +} + +static void FI2cOsResetInterrupt(FI2c *pctrl) +{ + FASSERT(pctrl); + /* disable irq */ + InterruptMask(pctrl->config.irq_num); +} + +/** + * @name: FFreeRTOSI2cInit + * @msg: init freeRTOS i2c instance + * @return {FFreeRTOSI2c *}pointer to os i2c instance + * @param {u32} instance_id,i2c instance_id + */ +FFreeRTOSI2c *FFreeRTOSI2cInit(u32 instance_id, u32 work_mode, u32 slave_address, u32 speed_rate) +{ + FASSERT((os_i2c[instance_id].wr_semaphore = xSemaphoreCreateMutex()) != NULL); + FASSERT((os_i2c[instance_id].trx_event = xEventGroupCreate()) != NULL); + + FError err = FREERTOS_I2C_SUCCESS; + + FI2cConfig i2c_config; + + /* E2000 use MIO -> I2C */ +#if defined(CONFIG_TARGET_E2000) + FASSERT(instance_id < FMIO_NUM); + + if (FT_COMPONENT_IS_READY == os_i2c[instance_id].i2c_device.is_ready) + { + vPrintf("I2c device %d is already initialized.\r\n", instance_id); + return NULL; + } + + const FMioConfig *mio_config_p ; + FMioCtrl *pctrl; + if (work_mode == FI2C_MASTER) + { + pctrl = &i2c_master; + } + else + { + pctrl = &i2c_slave; + } + + i2c_config = *FI2cLookupConfig(0); + /* Setup iomux */ + mio_config_p = FMioLookupConfig(instance_id); + if (NULL == mio_config_p) + { + vPrintf("Config of mio_i2c instance %d non found.\r\n", instance_id); + return NULL; + } + + + pctrl->config = *mio_config_p; + + err = FMioFuncInit(pctrl, FMIO_FUNC_SET_I2C); + if (err != FREERTOS_I2C_SUCCESS) + { + vPrintf("Mio I2c initialize is error.\r\n "); + return NULL; + } + + /* Modify configuration */ + i2c_config.work_mode = work_mode; + i2c_config.slave_addr = slave_address; + i2c_config.speed_rate = speed_rate; + + if (work_mode == FI2C_MASTER)/* 主机中断优先级低于从机接收 */ + { + i2c_config.instance_id = i2c_master.config.instance_id; + i2c_config.base_addr = i2c_master.config.func_base_addr; + i2c_config.irq_num = i2c_master.config.irq_num; + i2c_config.irq_prority = I2C_MASTER_IRQ_PRORITY; + } + else + { + i2c_config.instance_id = i2c_slave.config.instance_id; + i2c_config.base_addr = i2c_slave.config.func_base_addr; + i2c_config.irq_num = i2c_slave.config.irq_num; + i2c_config.irq_prority = I2C_SLAVE_IRQ_PRORITY; + } + FIOPadSetMioMux(i2c_config.instance_id); +#endif +#if defined(CONFIG_TARGET_D2000) + FASSERT(instance_id < FI2C_NUM); + + if (FT_COMPONENT_IS_READY == os_i2c[instance_id].i2c_device.is_ready) + { + vPrintf("I2c device %d is already initialized.\r\n", instance_id); + return NULL; + } + + i2c_config = *FI2cLookupConfig(instance_id); + if (work_mode == FI2C_MASTER) /* 主机中断优先级低于从机接收 */ + { + i2c_config.irq_prority = I2C_MASTER_IRQ_PRORITY; + } + else + { + i2c_config.irq_prority = I2C_SLAVE_IRQ_PRORITY; + } + /* Modify configuration */ + i2c_config.work_mode = work_mode; + i2c_config.slave_addr = slave_address; + i2c_config.speed_rate = speed_rate; + /* Setup iomux */ + FI2cMasterSlaveSetIoMux(instance_id); +#endif + err = FI2cCfgInitialize(&os_i2c[instance_id].i2c_device, &i2c_config); + if (err != FREERTOS_I2C_SUCCESS) + { + vPrintf("I2c Init failed.\r\n"); + return NULL; + } + /* 从机模式,开中断接收数据 */ + if (work_mode == FI2C_SLAVE) + { + FI2cOsSetupInterrupt(&os_i2c[instance_id].i2c_device); + } + return (&os_i2c[instance_id]); +} + +/** + * @name: FFreeRTOSI2cDeinit + * @msg: deinit freeRTOS i2c instance, include deinit i2c and delete mutex semaphore + * @return {*}无 + * @param {FFreeRTOSI2c} *os_i2c_p,pointer to os i2c instance + */ +void FFreeRTOSI2cDeinit(FFreeRTOSI2c *os_i2c_p) +{ + FASSERT(os_i2c_p); + FASSERT(os_i2c_p->wr_semaphore != NULL); +#if defined(CONFIG_TARGET_E2000) + FMioCtrl *pctrl = &i2c_master; + FMioFuncDeinit(pctrl); +#endif + /* 避免没有关闭中断,存在触发 */ + InterruptMask(os_i2c_p->i2c_device.config.irq_num); + FI2cDeInitialize(&os_i2c_p->i2c_device); + + FASSERT_MSG(NULL != os_i2c_p->wr_semaphore, "Semaphore not exists!!!"); + vSemaphoreDelete(os_i2c_p->wr_semaphore); + os_i2c_p->wr_semaphore = NULL; + + FASSERT_MSG(NULL != os_i2c_p->trx_event, "Event group not exists!!!"); + vEventGroupDelete(os_i2c_p->trx_event); + os_i2c_p->trx_event = NULL; +} + +/** + * @name: FFreeRTOSI2cTransfer + * @msg: tranfer i2c mesage + * @return {*} + * @param {u32} instance_id + * @param {FFreeRTOSI2cMessage} *message + * @param {u8} mode + */ +FError FFreeRTOSI2cTransfer(FFreeRTOSI2c *os_i2c_p, FFreeRTOSI2cMessage *message) +{ + FASSERT(os_i2c_p); + FASSERT(message); + FASSERT(os_i2c_p->wr_semaphore != NULL); + FASSERT(message->mode < FI2C_READ_DATA_MODE_NUM); + + if (pdFALSE == xSemaphoreTake(os_i2c_p->wr_semaphore, portMAX_DELAY)) + { + vPrintf("I2c xSemaphoreTake failed.\r\n"); + return FREERTOS_I2C_MESG_ERROR; + } + + FError ret = FREERTOS_I2C_SUCCESS; + FI2c *instance_p = &os_i2c_p->i2c_device; + EventBits_t ev; + + /* Judge whether the slave address has changed */ + if (instance_p->config.slave_addr != message->slave_addr) + { + instance_p->config.slave_addr = message->slave_addr; + } + + if (message->mode == FI2C_READ_DATA_POLL) + { + memset(message->buf, 0, message->buf_length); + ret = FI2cMasterReadPoll(instance_p, message->mem_addr, message->mem_byte_len, message->buf, message->buf_length); + } + else if (message->mode == FI2C_READ_DATA_INTR) + { + FI2cOsSetupInterrupt(instance_p); + memset(message->buf, 0, message->buf_length); + ret = FI2cMasterReadIntr(instance_p, message->mem_addr, message->mem_byte_len, message->buf, message->buf_length); + ev = xEventGroupWaitBits(os_i2c_p->trx_event, RTOS_I2C_TRANS_ABORTED | RTOS_I2C_READ_DONE, pdTRUE, pdFALSE, portMAX_DELAY); + if (ev & RTOS_I2C_TRANS_ABORTED) + { + vPrintf("RTOS_I2C_TRANS_ABORTED "); + ret = FREERTOS_I2C_TASK_ERROR; + } + else if (ev & RTOS_I2C_READ_DONE) + { + vPrintf("RTOS_I2C_READ_DONE,data_lenth:0d%d.\r\n", message->buf_length); + } + FI2cOsResetInterrupt(instance_p); + } + else if (message->mode == FI2C_WRITE_DATA_POLL) + { + ret = FI2cMasterWritePoll(instance_p, message->mem_addr, message->mem_byte_len, message->buf, message->buf_length); + } + else if (message->mode == FI2C_WRITE_DATA_INTR) + { + FI2cOsSetupInterrupt(instance_p); + ret = FI2cMasterWriteIntr(instance_p, message->mem_addr, message->mem_byte_len, message->buf, message->buf_length); + /* wait intr is finish */ + ev = xEventGroupWaitBits(os_i2c_p->trx_event, RTOS_I2C_TRANS_ABORTED | RTOS_I2C_WRITE_DONE, pdTRUE, pdFALSE, portMAX_DELAY); + if (ev & RTOS_I2C_TRANS_ABORTED) + { + vPrintf("RTOS_I2C_TRANS_ABORTED "); + ret = FREERTOS_I2C_TASK_ERROR; + } + else if (ev & RTOS_I2C_WRITE_DONE) + { + vPrintf("RTOS_I2C_WRITE_DONE,data_lenth:0d%d.\r\n", message->buf_length); + } + FI2cOsResetInterrupt(instance_p); + } + + /* Enable next transfer. Current one is finished */ + if (pdFALSE == xSemaphoreGive(os_i2c_p->wr_semaphore)) + { + /* We could not post the semaphore, exit with error */ + vPrintf("FFreeRTOSI2cTransfer function xSemaphoreGive failed.\r\n"); + return FREERTOS_I2C_MESG_ERROR; + } + + if (ret != FREERTOS_I2C_SUCCESS) + { + vPrintf("FFreeRTOSI2cTransfer error,id:%d.\r\n", instance_p->config.instance_id); + return FREERTOS_I2C_TASK_ERROR; + } + return ret; +} + diff --git a/drivers/i2c/fi2c_os.h b/drivers/i2c/fi2c_os.h new file mode 100644 index 00000000..58a32087 --- /dev/null +++ b/drivers/i2c/fi2c_os.h @@ -0,0 +1,119 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fi2c_os.h + * Date: 2022-07-15 10:43:51 + * LastEditTime: 2022-07-15 10:43:51 + * Description:  This file is for providing function related definitions of i2c driver used in FreeRTOS. + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 liushengming 2022/07/15 init + */ + +#ifndef FI2C_OS_H +#define FI2C_OS_H +/***************************** Include Files *********************************/ +#include +#include +#include +#include "ferror_code.h" +#include "fi2c.h" +#include "fi2c_hw.h" +#include "ftypes.h" +/************************** Constant Definitions *****************************/ +#ifdef __cplusplus +extern "C" +{ +#endif + +/*Error code from standalone i2c driver*/ +#define FREERTOS_I2C_SUCCESS FI2C_SUCCESS +#define FREERTOS_I2C_INVAILD_PARAM_ERROR FI2C_ERR_INVAL_PARM +#define FREERTOS_I2C_NOT_READY_ERROR FI2C_ERR_NOT_READY +#define FREERTOS_I2C_TIMEOUT_ERROR FI2C_ERR_TIMEOUT +#define FREERTOS_I2C_NOT_SUPPORT_ERROR FI2C_ERR_NOT_SUPPORT +#define FREERTOS_I2C_INVAL_STATE_ERROR FI2C_ERR_INVAL_STATE + +/*Error code depend on OS standard*/ +#define FREERTOS_I2C_TASK_ERROR FT_CODE_ERR(ErrModPort, ErrBspI2c, 0x1) +#define FREERTOS_I2C_MESG_ERROR FT_CODE_ERR(ErrModPort, ErrBspI2c, 0x2) +#define FREERTOS_I2C_TIME_ERROR FT_CODE_ERR(ErrModPort, ErrBspI2c, 0x3) +#define FREERTOS_I2C_MEMY_ERROR FT_CODE_ERR(ErrModPort, ErrBspI2c, 0x4) + +/*! +* @cond RTOS_PRIVATE +* @name I2C FreeRTOS handler +* +* These are the only valid states for txEvent and rxEvent +*/ +/*@{*/ +/*! @brief Event flag - transfer complete. */ +#define RTOS_I2C_READ_DONE 0x1 +/*! @brief Event flag - hardware buffer overrun. */ +#define RTOS_I2C_WRITE_DONE 0x2 +/*! @brief Event flag Receive is error */ +#define RTOS_I2C_TRANS_ABORTED 0x4 + +#define I2C_MASTER_IRQ_PRORITY 0xc +#define I2C_SLAVE_IRQ_PRORITY 0xb + +#define IO_BUF_LEN 256 + +/************************** Variable Definitions *****************************/ +/** + * iic message structure + */ +typedef struct +{ + void *buf; /* i2c read or write buffer */ + size_t buf_length; /* i2c read or write buffer length */ + u32 slave_addr; /* i2c slave addr,you can change slave_addr to send different device in the bus*/ + u32 mem_addr; /* i2c slave address offset to read or write */ + u8 mem_byte_len; /* sizeof slave address */ + volatile u8 mode; /* transport mode */ +} FFreeRTOSI2cMessage; + +typedef struct +{ + FI2c i2c_device; + SemaphoreHandle_t wr_semaphore; /* i2c read and write semaphore for resource sharing */ + EventGroupHandle_t trx_event; /* i2c TX/RX completion event */ +} FFreeRTOSI2c; + +enum /*选择操作I2C的方式*/ +{ + FI2C_READ_DATA_POLL, + FI2C_READ_DATA_INTR, + FI2C_WRITE_DATA_POLL, + FI2C_WRITE_DATA_INTR, + + FI2C_READ_DATA_MODE_NUM +}; + +/************************** Function Prototypes ******************************/ +/* init freeRTOS i2c instance */ +FFreeRTOSI2c *FFreeRTOSI2cInit(u32 instance_id, u32 work_mode, u32 slave_address, u32 speed_rate); + +/* deinit freeRTOS i2c instance */ +void FFreeRTOSI2cDeinit(FFreeRTOSI2c *os_i2c_p); + +/* tranfer i2c mesage */ +FError FFreeRTOSI2cTransfer(FFreeRTOSI2c *os_i2c_p, FFreeRTOSI2cMessage *message); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/drivers/mmc/fsdio/fsdio_os.c b/drivers/mmc/fsdio/fsdio_os.c deleted file mode 100644 index 762aa7a9..00000000 --- a/drivers/mmc/fsdio/fsdio_os.c +++ /dev/null @@ -1,633 +0,0 @@ -/* - * Copyright : (C) 2022 Phytium Information Technology, Inc. - * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * - * FilePath: fsdio_os.c - * Date: 2022-07-25 09:14:40 - * LastEditTime: 2022-07-25 09:14:40 - * Description:  This files is for - * - * Modify History: - * Ver   Who        Date         Changes - * ----- ------     --------    -------------------------------------- - * 1.0 zhugengyu 2022/7/27 init commit - */ - -/***************************** Include Files *********************************/ -#include -#include -#include - -#include "finterrupt.h" -#include "fparameters.h" -#include "fdebug.h" -#include "fassert.h" -#include "fsleep.h" -#include "fcpu_info.h" -#include "fiopad.h" - -#include "fsdio_os.h" -#include "fsdio_hw.h" -#include "sdmmc_cmd.h" -#include "sdmmc_defs.h" - -/************************** Constant Definitions *****************************/ - -/**************************** Type Definitions *******************************/ -typedef struct -{ - sdmmc_card_t card; /* instance of card in sdmmc */ - sdmmc_host_t host; /* instance of host in sdmmc */ -} FSdioOSHost; /* instance to support sdmmc commands */ - -/************************** Variable Definitions *****************************/ -static FFreeRTOSSdio sdio[FSDIO_HOST_INSTANCE_NUM]; -static FSdioOSHost sdmmc_host[FSDIO_HOST_INSTANCE_NUM]; - -/***************** Macros (Inline Functions) Definitions *********************/ -#define FSDIO_DEBUG_TAG "FSDIO-OS" -#define FSDIO_ERROR(format, ...) FT_DEBUG_PRINT_E(FSDIO_DEBUG_TAG, format, ##__VA_ARGS__) -#define FSDIO_WARN(format, ...) FT_DEBUG_PRINT_W(FSDIO_DEBUG_TAG, format, ##__VA_ARGS__) -#define FSDIO_INFO(format, ...) FT_DEBUG_PRINT_I(FSDIO_DEBUG_TAG, format, ##__VA_ARGS__) -#define FSDIO_DEBUG(format, ...) FT_DEBUG_PRINT_D(FSDIO_DEBUG_TAG, format, ##__VA_ARGS__) - -/************************** Function Prototypes ******************************/ - -/*****************************************************************************/ -static inline FError FSdioOsTakeSema(SemaphoreHandle_t locker) -{ - FASSERT_MSG((NULL != locker), "locker not exists"); - if (pdFALSE == xSemaphoreTake(locker, portMAX_DELAY)) - { - FSDIO_ERROR("failed to give locker !!!"); - return FFREERTOS_SDIO_SEMA_ERR; - } - - return FFREERTOS_SDIO_OK; -} - -static inline void FSdioOsGiveSema(SemaphoreHandle_t locker) -{ - FASSERT_MSG((NULL != locker), "locker not exists"); - if (pdFALSE == xSemaphoreGive(locker)) - { - FSDIO_ERROR("failed to give locker !!!"); - } - - return; -} - -static void FSdioOSSetupInterrupt(FSdio *ctrl) -{ - uintptr base_addr = ctrl->config.base_addr; - u32 cpu_id = 0; - - GetCpuId(&cpu_id); - FSDIO_INFO("cpu_id is cpu_id %d", cpu_id); - InterruptSetTargetCpus(ctrl->config.irq_num, cpu_id); - InterruptSetPriority(ctrl->config.irq_num, FFREERTOS_SDIO_IRQ_PRIORITY); - - /* register intr callback */ - InterruptInstall(ctrl->config.irq_num, - FSdioInterruptHandler, - ctrl, - NULL); - - /* enable sdio irq */ - InterruptUmask(ctrl->config.irq_num); - - FSDIO_INFO("sdio interrupt setup done !!!"); - return; -} - -/* init sdmmc host */ -static sdmmc_err_t FSdioOsHostInit(int slot) -{ - FASSERT((slot >= 0) && (slot < FSDIO_HOST_INSTANCE_NUM)); - return SDMMC_OK; -} - -/* sdmmc host set bus width */ -static sdmmc_err_t FSdioOsHostSetBusWidth(int slot, size_t width) -{ - FASSERT((slot >= 0) && (slot < FSDIO_HOST_INSTANCE_NUM)); - FFreeRTOSSdio *instance = &sdio[slot]; - FSdio *ctrl = &instance->ctrl; - uintptr base_addr = ctrl->config.base_addr; - FSDIO_INFO("set bus width as %d", width); - FSdioSetBusWidth(base_addr, width); - return SDMMC_OK; -} - -/* sdmmc host get bus width */ -static size_t FSdioOsHostGetBusWidth(int slot) -{ - FASSERT((slot >= 0) && (slot < FSDIO_HOST_INSTANCE_NUM)); - FFreeRTOSSdio *instance = &sdio[slot]; - FSdio *ctrl = &instance->ctrl; - uintptr base_addr = ctrl->config.base_addr; - size_t bus_width = (size_t)FSdioGetBusWidth(base_addr); - FSDIO_INFO("get bus width as %d", bus_width); - return bus_width; -} - -/* sdmmc host set ddr mode */ -static sdmmc_err_t FSdioOsHostSetDDRMode(int slot, bool ddr_enabled) -{ - FASSERT((slot >= 0) && (slot < FSDIO_HOST_INSTANCE_NUM)); - FSDIO_ERROR("sdio_host_set_bus_ddr_mode not supported !!!"); - return SDMMC_OK; -} - -/* sdmmc host change card clock freq */ -static sdmmc_err_t FSdioOsHostSetCardClock(int slot, u32 freq_khz) -{ - FASSERT((slot >= 0) && (slot < FSDIO_HOST_INSTANCE_NUM)); - FFreeRTOSSdio *instance = &sdio[slot]; - FSdio *ctrl = &instance->ctrl; - FSDIO_INFO("set clk rate as %dKHz", freq_khz); - FError err = FSdioSetClkFreq(ctrl, freq_khz * 1000); - return (FSDIO_SUCCESS == err) ? SDMMC_OK : SDMMC_FAIL; -} - -/* convert command info from sdmmc_command_t to FSdioCmdData */ -static void FSdioOsConvertCmdInfo(sdmmc_command_t *cmdinfo, FSdioCmdData *cmd_data) -{ - if (MMC_GO_IDLE_STATE == cmdinfo->opcode) - { - cmd_data->flag |= FSDIO_CMD_FLAG_NEED_INIT; - } - - if (SCF_RSP_CRC & cmdinfo->flags) - { - cmd_data->flag |= FSDIO_CMD_FLAG_NEED_RESP_CRC; - } - - if (SCF_RSP_PRESENT & cmdinfo->flags) - { - cmd_data->flag |= FSDIO_CMD_FLAG_EXP_RESP; - - if (SCF_RSP_136 & cmdinfo->flags) - { - cmd_data->flag |= FSDIO_CMD_FLAG_EXP_LONG_RESP; - } - } - - if (cmdinfo->data) - { - FASSERT_MSG(cmd_data->data_p, "data buffer shall be assigned"); - cmd_data->flag |= FSDIO_CMD_FLAG_EXP_DATA; - - if (SCF_CMD_READ & cmdinfo->flags) - { - cmd_data->flag |= FSDIO_CMD_FLAG_READ_DATA; - } - else - { - cmd_data->flag |= FSDIO_CMD_FLAG_WRITE_DATA; - } - - cmd_data->data_p->buf = cmdinfo->data; - cmd_data->data_p->blksz = cmdinfo->blklen; - cmd_data->data_p->datalen = cmdinfo->datalen; - FSDIO_INFO("buf@%p, blksz: %d, datalen: %d", - cmd_data->data_p->buf, - cmd_data->data_p->blksz, - cmd_data->data_p->datalen); - } - - cmd_data->cmdidx = cmdinfo->opcode; - cmd_data->cmdarg = cmdinfo->arg; - - return; -} - -/* send signal sdio error from interrupt */ -static void FSdioOsHandleError(FSdio *const ctrl, void *args) -{ - FASSERT(ctrl); - FSDIO_ERROR("sdio error occur ..."); - - FFreeRTOSSdio *instance = (FFreeRTOSSdio *)args; - BaseType_t xhigher_priority_task_woken = pdFALSE; - BaseType_t x_result = pdFALSE; - - FASSERT(instance->evt); - x_result = xEventGroupSetBitsFromISR(instance->evt, FFREERTOS_SDIO_ERROR_OCCURRED, - &xhigher_priority_task_woken); -} - -/* send signal sdio command done from interrupt */ -static void FSdioOsAckCmdDone(FSdio *const ctrl, void *args) -{ - FASSERT(args); - FFreeRTOSSdio *instance = (FFreeRTOSSdio *)args; - BaseType_t xhigher_priority_task_woken = pdFALSE; - BaseType_t x_result = pdFALSE; - - FSDIO_DEBUG("ack cmd and data trans done"); - FASSERT(instance->evt); - x_result = xEventGroupSetBitsFromISR(instance->evt, FFREERTOS_SDIO_CMD_TRANS_DONE, - &xhigher_priority_task_woken); - - return; -} - -/* send signal sdio data over from interrupt */ -static void FSdioOsAckDataDone(FSdio *const ctrl, void *args) -{ - FASSERT(args); - FFreeRTOSSdio *instance = (FFreeRTOSSdio *)args; - BaseType_t xhigher_priority_task_woken = pdFALSE; - BaseType_t x_result = pdFALSE; - - FSDIO_DEBUG("ack cmd and data trans done"); - FASSERT(instance->evt); - x_result = xEventGroupSetBitsFromISR(instance->evt, FFREERTOS_SDIO_DAT_TRANS_DONE, - &xhigher_priority_task_woken); - - return; -} - -/* wait sdio command done / data over / error occurred from task */ -static FError FSdioOsWaitCmdDataDone(FFreeRTOSSdio *const instance) -{ - const TickType_t wait_delay = pdMS_TO_TICKS(FFREERTOS_SDIO_CMD_TIMEOUT); /* wait for 5000 ms */ - EventBits_t ev; - FError err = FFREERTOS_SDIO_OK; - u32 evt_bits = FFREERTOS_SDIO_CMD_TRANS_DONE; /* command done */ - u32 err_bits = FFREERTOS_SDIO_ERROR_OCCURRED; /* error occurred */ - FSdioCmdData *cmd_data = &instance->cmd_data; - FSdio *ctrl = &instance->ctrl; - - if (cmd_data->data_p) - { - evt_bits |= FFREERTOS_SDIO_DAT_TRANS_DONE; /* need to wait data over */ - } - - /* block task to wait finish signal */ - FASSERT_MSG(instance->evt, "evt not exists"); - ev = xEventGroupWaitBits(instance->evt, evt_bits, - pdTRUE, pdTRUE, wait_delay); /* wait for cmd/data done */ - if (ev & evt_bits == evt_bits) - { - FSDIO_DEBUG("trans done"); - err = FSdioGetCmdResponse(ctrl, cmd_data); /* check for response data */ - } - else if (ev & err_bits) - { - /* restart controller in interrupt is not a good idea */ - FSdioDumpRegister(ctrl->config.base_addr); - FSDIO_WARN("restart controller from error state !!!"); - err = FSdioRestart(ctrl); /* update clock otherwise next command will also fail */ - } - else - { - FSDIO_ERROR("trans timeout, ev: 0x%x != 0x%x", ev, evt_bits); - err = FFREERTOS_SDIO_EVT_ERR; - } - - return err; -} - -/* sdmmc do cmd and data transaction */ -static sdmmc_err_t FSdioOsHostDoTransaction(int slot, sdmmc_command_t *cmdinfo) -{ - FASSERT((slot >= 0) && (slot < FSDIO_HOST_INSTANCE_NUM)); - FFreeRTOSSdio *instance = &sdio[slot]; - FSdio *ctrl = &instance->ctrl; - sdmmc_err_t ret = SDMMC_OK; - FSdioCmdData *cmd_data = &instance->cmd_data; - FSdioData *trans_data = &instance->trans_data; - FError err = FSDIO_SUCCESS; - - /* use static structure attached at instance to forward command & data */ - memset(cmd_data, 0, sizeof(*cmd_data)); - if (cmdinfo->data) - { - memset(trans_data, 0, sizeof(*trans_data)); - cmd_data->data_p = trans_data; - } - - FSdioOsConvertCmdInfo(cmdinfo, cmd_data); /* prepare command data */ - - if (instance->config.en_dma) /* DMA mode */ - { - err = FSdioDMATransfer(ctrl, cmd_data); - if (FSDIO_SUCCESS != err) - { - ret = SDMMC_FAIL; - goto err_exit; - } - } - else /* non-DMA, PIO mode */ - { - err = FSdioPIOTransfer(ctrl, cmd_data); - if (FSDIO_SUCCESS != err) - { - ret = SDMMC_FAIL; - goto err_exit; - } - } - - /* wait command / data over signal */ - err = FSdioOsWaitCmdDataDone(instance); - if (FSDIO_SUCCESS != err) - { - ret = SDMMC_FAIL; - goto err_exit; - } - - /* success, copy response out */ - if (SCF_RSP_PRESENT & cmdinfo->flags) - { - cmdinfo->response[0] = cmd_data->response[0]; - - if (SCF_RSP_136 & cmdinfo->flags) - { - cmdinfo->response[1] = cmd_data->response[1]; - cmdinfo->response[2] = cmd_data->response[2]; - cmdinfo->response[3] = cmd_data->response[3]; - } - } - -err_exit: - return ret; -} - -/* sdmmc host deinit */ -static sdmmc_err_t FSdioOsHostDeinit(void) -{ - sdmmc_err_t err = SDMMC_OK; - return err; -} - -static sdmmc_err_t FSdioOsHostEnableIOInt(int slot) -{ - FASSERT((slot >= 0) && (slot < FSDIO_HOST_INSTANCE_NUM)); - FSDIO_ERROR("sdio_host_io_int_enable not supported !!!"); - return SDMMC_OK; -} - -static sdmmc_err_t FSdioOsHostWaitIOInt(int slot, TickType_t timeout_ticks) -{ - FASSERT((slot >= 0) && (slot < FSDIO_HOST_INSTANCE_NUM)); - FSDIO_ERROR("sdio_host_io_int_wait not supported !!!"); - return SDMMC_OK; -} - -/* setup sdmmc host */ -static FError FSdioOsSetupHost(FFreeRTOSSdio *const instance) -{ - FSdio *ctrl = &instance->ctrl; - int slot = (int)ctrl->config.instance_id; - FSdioOSHost *const sdmmc = &sdmmc_host[slot]; - sdmmc_host_t *host_p = &sdmmc->host; /* host */ - sdmmc_card_t *card_p = &sdmmc->card; /* card */ - sdmmc_err_t sd_err = SDMMC_OK; - static boolean sdmmc_inited = FALSE; - - if (TRUE != sdmmc_inited) - { - /* init sdmmc, which is shared by all instance, and init only one time */ - sd_err = sdmmc_port_init(); - if (SDMMC_OK != sd_err) - goto err_exit; - - sdmmc_inited = TRUE; - } - - instance->host_data = sdmmc; - - /* set sdmmc host parameters */ - host_p->slot = slot; - host_p->flags |= SDMMC_HOST_FLAG_4BIT; /* bus width = 4 bit */ - host_p->flags &= ~SDMMC_HOST_FLAG_DDR; /* not support DDR mode */ - host_p->flags &= ~SDMMC_HOST_FLAG_SPI; /* not support SPI mode */ - host_p->max_freq_khz = SDMMC_FREQ_50M; /* max freq 50MHz */ - host_p->io_voltage = 3.3f; /* 3.3v */ - host_p->command_timeout_ms = FFREERTOS_SDIO_CMD_TIMEOUT; /* 5000ms timeout */ - - FSDIO_INFO("slot: %d, flags: 0x%x, freq: %dkHz", - host_p->slot, host_p->flags, host_p->max_freq_khz); - - /* register host ops */ - host_p->init = FSdioOsHostInit; - host_p->set_bus_width = FSdioOsHostSetBusWidth; - host_p->get_bus_width = FSdioOsHostGetBusWidth; - host_p->set_bus_ddr_mode = FSdioOsHostSetDDRMode; - host_p->set_card_clk = FSdioOsHostSetCardClock; - host_p->do_transaction = FSdioOsHostDoTransaction; - host_p->deinit = FSdioOsHostDeinit; - host_p->io_int_enable = FSdioOsHostEnableIOInt; - host_p->io_int_wait = FSdioOsHostWaitIOInt; - - /* set clock as 400kHz to probe card */ - sd_err = FSdioOsHostSetCardClock(slot, SDMMC_FREQ_PROBING); - if (SDMMC_OK != sd_err) - { - FSDIO_ERROR("sdio ctrl setup 400kHz clock failed"); - goto err_exit; - } - - /* probe eMMC or tf card */ - if (FFREERTOS_SDIO_MEDIUM_EMMC == instance->config.medium_type) - { - sd_err = sdmmc_init_emmc(host_p, card_p); - } - else if (FFREERTOS_SDIO_MEDIUM_TF == instance->config.medium_type) - { - sd_err = sdmmc_init_tf_card(host_p, card_p); - } - - if (SDMMC_OK == sd_err) - { - sdmmc_card_print_info(stdout, card_p); /* print card info is success */ - } - else - { - FSDIO_ERROR("card init failed: 0x%x", sd_err); - } - -err_exit: - return (SDMMC_OK != sd_err) ? FFREERTOS_SDIO_HOST_ERR : FFREERTOS_SDIO_OK; -} - -/** - * @name: FFreeRTOSSdioInit - * @msg: init and get sdio instance - * @return {FFreeRTOSSdio *} NULL if failed - * @param {u32} id, instance id of sdio - * @param {FFreeRTOSSdioConifg} *input_config, input config of sdio - */ -FFreeRTOSSdio *FFreeRTOSSdioInit(u32 id, const FFreeRTOSSdioConifg *input_config) -{ - FASSERT(input_config); - FASSERT_MSG(id < FSDIO_HOST_INSTANCE_NUM, "invalid sdio id"); - FFreeRTOSSdio *instance = &sdio[id]; - FSdio *ctrl = &instance->ctrl; - FSdioConfig sdio_config; - FError err = FFREERTOS_SDIO_OK; - sdmmc_err_t sd_err = SDMMC_OK; - - if (FT_COMPONENT_IS_READY == ctrl->is_ready) - { - FSDIO_ERROR("sdio-%d already init", id); - return instance; - } - - taskENTER_CRITICAL(); /* no scheduler during init */ - - instance->config = *input_config; - sdio_config = *FSdioLookupConfig(id); - sdio_config.trans_mode = (instance->config.en_dma) ? FSDIO_IDMA_TRANS_MODE : FSDIO_PIO_TRANS_MODE; - if (FFREERTOS_SDIO_MEDIUM_EMMC == instance->config.medium_type) - sdio_config.non_removable = TRUE; - else - sdio_config.non_removable = FALSE; - - err = FSdioCfgInitialize(ctrl, &sdio_config); - if (FSDIO_SUCCESS != err) - { - FSDIO_ERROR("init sdio-%d failed, err: 0x%x !!!", id, err); - taskEXIT_CRITICAL(); /* allow schedule after init */ - return NULL; - } - - if (instance->config.en_dma) - { - /* setup dma list */ - err = FSdioSetIDMAList(ctrl, instance->rw_desc, FFREERTOS_SDIO_MAX_TRANS_BLOCK); - if (FSDIO_SUCCESS != err) - { - FSDIO_ERROR("set sdio-%d dma list, err: 0x%x !!!", id, err); - taskEXIT_CRITICAL(); /* allow schedule after init */ - return NULL; - } - } - - FSdioOSSetupInterrupt(ctrl); - - if (instance->config.card_detect_handler) - { - FSdioRegisterEvtHandler(ctrl, FSDIO_EVT_CARD_DETECTED, - instance->config.card_detect_handler, - instance->config.card_detect_args); - } - - /* restart controller if error */ - FSdioRegisterEvtHandler(ctrl, FSDIO_EVT_ERR_OCCURE, FSdioOsHandleError, instance); - - /* transfer may end up with cmd over or cmd and data over */ - FSdioRegisterEvtHandler(ctrl, FSDIO_EVT_CMD_DONE, FSdioOsAckCmdDone, instance); - FSdioRegisterEvtHandler(ctrl, FSDIO_EVT_DATA_DONE, FSdioOsAckDataDone, instance); - - FASSERT_MSG(NULL == instance->locker, "locker exists !!!"); - FASSERT_MSG((instance->locker = xSemaphoreCreateMutex()) != NULL, "create mutex failed !!!"); - - FASSERT_MSG(NULL == instance->evt, "event group exists !!!"); - FASSERT_MSG((instance->evt = xEventGroupCreate()) != NULL, "create event group failed !!!"); - - taskEXIT_CRITICAL(); /* allow schedule after init */ - - /* take locker to protect instead disable scheduler, - since card probe is time-consuming */ - err = FSdioOsTakeSema(instance->locker); - if (FFREERTOS_SDIO_OK != err) - return NULL; - - /* including card probe process, which could be time consuming */ - err = FSdioOsSetupHost(instance); - -err_exit: - FSdioOsGiveSema(instance->locker); - return (FFREERTOS_SDIO_OK == err) ? instance : NULL; /* exit with NULL if failed */ -} - -/** - * @name: FFreeRTOSSdioDeInit - * @msg: deinit sdio instance - * @return {FError} FFREERTOS_SDIO_OK if success - * @param {FFreeRTOSSdio} *instance, freertos sdio instance - */ -FError FFreeRTOSSdioDeInit(FFreeRTOSSdio *const instance) -{ - FASSERT(instance); - FSdio *ctrl = &instance->ctrl; - FError err = FFREERTOS_SDIO_OK; - - /* no scheduler during deinit */ - taskENTER_CRITICAL(); - - /* disable sdio irq */ - InterruptMask(ctrl->config.irq_num); - - FSdioDeInitialize(ctrl); - - instance->host_data = NULL; - - FASSERT_MSG(NULL != instance->locker, "locker not exists !!!"); - vSemaphoreDelete(instance->locker); - instance->locker = NULL; - - FASSERT_MSG(NULL != instance->evt, "event group not exists !!!"); - vEventGroupDelete(instance->evt); - instance->evt = NULL; - - taskEXIT_CRITICAL(); /* allow schedule after deinit */ - - return err; -} - -/** - * @name: FFreeRTOSSdioTransfer - * @msg: start sdio transfer and wait transfer done in this function - * @return {FError} FFREERTOS_SDIO_OK if transfer success - * @param {FFreeRTOSSdio} *instance, freertos sdio instance - * @param {FFreeRTOSSdioMessage} *message, sdio transfer message - */ -FError FFreeRTOSSdioTransfer(FFreeRTOSSdio *const instance, const FFreeRTOSSdioMessage *message) -{ - FASSERT(instance); - FSdio *ctrl = &instance->ctrl; - sdmmc_err_t sd_err = SDMMC_OK; - FError err = FFREERTOS_SDIO_OK; - FSdioOSHost *sdmmc = (FSdioOSHost *)instance->host_data; - - err = FSdioOsTakeSema(instance->locker); - if (FFREERTOS_SDIO_OK != err) - return err; - - FASSERT_MSG(message->buf_len >= message->block_num * FSDIO_DEFAULT_BLOCK_SZ, "buffer not enough !!!"); - if (FFREERTOS_SDIO_TRANS_READ == message->trans_type) - { - sd_err = sdmmc_read_sectors(&sdmmc->card, (void *)message->buf, - message->start_block, message->block_num); - if (SDMMC_OK != sd_err) - { - err = FFREERTOS_SDIO_READ_ERR; - } - } - else - { - sd_err = sdmmc_write_sectors(&sdmmc->card, (const void *)message->buf, - message->start_block, message->block_num); - if (SDMMC_OK != sd_err) - { - err = FFREERTOS_SDIO_WRITE_ERR; - } - } - -err_exit: - FSdioOsGiveSema(instance->locker); - return err; -} \ No newline at end of file diff --git a/drivers/mmc/fsdio/fsdio_os.h b/drivers/mmc/fsdio/fsdio_os.h deleted file mode 100644 index 52836e70..00000000 --- a/drivers/mmc/fsdio/fsdio_os.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright : (C) 2022 Phytium Information Technology, Inc. - * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * - * FilePath: fsdio_os.h - * Date: 2022-07-25 09:14:34 - * LastEditTime: 2022-07-25 09:14:34 - * Description:  This files is for - * - * Modify History: - * Ver   Who        Date         Changes - * ----- ------     --------    -------------------------------------- - * 1.0 zhugengyu 2022/7/27 init commit - */ -#ifndef DRIVERS_FSDIO_OS_H -#define DRIVERS_FSDIO_OS_H - -#ifdef __cplusplus -extern "C" -{ -#endif - -/***************************** Include Files *********************************/ -#include -#include -#include - -#include "fkernel.h" -#include "fparameters.h" -#include "fsdio.h" - -/************************** Constant Definitions *****************************/ -#define FFREERTOS_SDIO_OK FT_SUCCESS -#define FFREERTOS_SDIO_SEMA_ERR FT_CODE_ERR(ErrModPort, ErrBspMmc, 1) -#define FFREERTOS_SDIO_HOST_ERR FT_CODE_ERR(ErrModPort, ErrBspMmc, 2) -#define FFREERTOS_SDIO_EVT_ERR FT_CODE_ERR(ErrModPort, ErrBspMmc, 3) -#define FFREERTOS_SDIO_READ_ERR FT_CODE_ERR(ErrModPort, ErrBspMmc, 4) -#define FFREERTOS_SDIO_WRITE_ERR FT_CODE_ERR(ErrModPort, ErrBspMmc, 5) - -#define FFREERTOS_SDIO_IRQ_PRIORITY IRQ_PRIORITY_VALUE_12 - -#define FFREERTOS_SDIO_MEDIUM_TF 0U /* sdio medium is tf card */ -#define FFREERTOS_SDIO_MEDIUM_EMMC 1U /* sdio medium is emmc */ - -#define FFREERTOS_SDIO_TRANS_READ 0U /* sdio trans direction is read */ -#define FFREERTOS_SDIO_TRANS_WRITE 1U /* sdio trans direction is write */ - -#define FFREERTOS_SDIO_MAX_TRANS_BLOCK 64U /* max num of block involved in one transfer */ -#define FFREERTOS_SDIO_BLOCK_SIZE FSDIO_DEFAULT_BLOCK_SZ - -#define FFREERTOS_SDIO_CMD_TIMEOUT 5000U -/**************************** Type Definitions *******************************/ -typedef struct -{ - boolean en_dma; /* TRUE: data transfer in DMA mode, FALSE: PIO mode */ - u32 medium_type; /* use FFREERTOS_SDIO_MEDIUM_* */ - FSdioEvtHandler card_detect_handler; /* callback for card detect status change */ - void *card_detect_args; -} FFreeRTOSSdioConifg; /* freertos sdio config */ - -typedef struct -{ - FSdio ctrl; - FFreeRTOSSdioConifg config; - SemaphoreHandle_t locker; - EventGroupHandle_t evt; -#define FFREERTOS_SDIO_CMD_TRANS_DONE (0x1 << 0) /* evt bit when command / data finished */ -#define FFREERTOS_SDIO_DAT_TRANS_DONE (0x1 << 1) -#define FFREERTOS_SDIO_ERROR_OCCURRED (0x1 << 2) /* evt bit when ctrl in error occurred */ - void *host_data; /* store private data of card and host */ - volatile FSdioIDmaDesc rw_desc[FFREERTOS_SDIO_MAX_TRANS_BLOCK]; /* dma descriptor entry */ - FSdioCmdData cmd_data; /* command information */ - FSdioData trans_data; /* data information */ -} FFreeRTOSSdio; /* freertos sdio instance */ - -typedef struct -{ - uintptr start_block; /* block to start read/write */ - fsize_t block_num; /* num of block to read/write */ - u8 *buf; /* buffer read from / write to */ - fsize_t buf_len; /* bytes of buffer contents */ - u32 trans_type; /* use FFREERTOS_SDIO_TRANS_* */ -} FFreeRTOSSdioMessage; /* freertos sdio transfer message */ - -/************************** Variable Definitions *****************************/ - -/***************** Macros (Inline Functions) Definitions *********************/ - -/************************** Function Prototypes ******************************/ - -/*****************************************************************************/ -/* init and get sdio instance */ -FFreeRTOSSdio *FFreeRTOSSdioInit(u32 instance_id, const FFreeRTOSSdioConifg *config); - -/* deinit sdio instance */ -FError FFreeRTOSSdioDeInit(FFreeRTOSSdio *const instance); - -/* start sdio transfer and wait transfer done in this function */ -FError FFreeRTOSSdioTransfer(FFreeRTOSSdio *const instance, const FFreeRTOSSdioMessage *message); - - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/drivers/pwm/fpwm_os.c b/drivers/pwm/fpwm_os.c index 37f42fef..84da8c4e 100644 --- a/drivers/pwm/fpwm_os.c +++ b/drivers/pwm/fpwm_os.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: fpwm_os.c * Date: 2022-08-15 14:20:19 * LastEditTime: 2022-08-25 16:59:51 - * Description:  This file is for - * - * Modify History: + * Description:  This file is for required function implementations of pwm driver used in FreeRTOS. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/08/26 first commit */ #include #include @@ -39,7 +40,7 @@ #define FPWM_INFO(format, ...) FT_DEBUG_PRINT_I(FPWM_DEBUG_TAG, format, ##__VA_ARGS__) #define FPWM_DEBUG(format, ...) FT_DEBUG_PRINT_D(FPWM_DEBUG_TAG, format, ##__VA_ARGS__) -static FFreeRTOSPwm os_pwm[FPWM_INSTANCE_NUM] = {0}; +static FFreeRTOSPwm os_pwm[FPWM_NUM] = {0}; /** * @name: FFreeRTOSPwmInit @@ -49,7 +50,7 @@ static FFreeRTOSPwm os_pwm[FPWM_INSTANCE_NUM] = {0}; */ FFreeRTOSPwm *FFreeRTOSPwmInit(u32 instance_id) { - FASSERT(instance_id < FPWM_INSTANCE_NUM); + FASSERT(instance_id < FPWM_NUM); FASSERT(FT_COMPONENT_IS_READY != os_pwm[instance_id].pwm_ctrl.is_ready); FPwmConfig pconfig; @@ -59,7 +60,7 @@ FFreeRTOSPwm *FFreeRTOSPwmInit(u32 instance_id) FASSERT(FPwmCfgInitialize(&os_pwm[instance_id].pwm_ctrl, &pconfig) == FT_SUCCESS); FASSERT((os_pwm[instance_id].pwm_semaphore = xSemaphoreCreateMutex()) != NULL); - + return (&os_pwm[instance_id]); } @@ -73,11 +74,11 @@ FError FFreeRTOSPwmDeinit(FFreeRTOSPwm *os_pwm_p) { FASSERT(os_pwm_p); FASSERT(os_pwm_p->pwm_semaphore != NULL); - + FPwmDeInitialize(&os_pwm_p->pwm_ctrl); vSemaphoreDelete(os_pwm_p->pwm_semaphore); memset(os_pwm_p, 0, sizeof(*os_pwm_p)); - + return FPWM_SUCCESS; } @@ -97,12 +98,12 @@ static FError FFreeRTOSPwmControl(FFreeRTOSPwm *os_pwm_p, int cmd, void *arg) /* New contrl can be performed only after current one is finished */ if (pdFALSE == xSemaphoreTake(os_pwm_p->pwm_semaphore, portMAX_DELAY)) { - FPWM_ERROR("Pwm xSemaphoreTake failed\r\n"); + FPWM_ERROR("Pwm xSemaphoreTake failed."); /* We could not take the semaphore, exit with 0 data received */ return FREERTOS_PWM_SEM_ERROR; } - switch (cmd) + switch (cmd) { case FREERTOS_PWM_CTRL_SET: ret = FPwmVariableSet(&os_pwm_p->pwm_ctrl, configuration->channel, &configuration->pwm_cfg); @@ -133,7 +134,7 @@ static FError FFreeRTOSPwmControl(FFreeRTOSPwm *os_pwm_p, int cmd, void *arg) break; default: - FPWM_ERROR("invalid cmd."); + FPWM_ERROR("Invalid cmd."); ret = FPWM_ERR_NOT_SUPPORT; break; } @@ -142,7 +143,7 @@ static FError FFreeRTOSPwmControl(FFreeRTOSPwm *os_pwm_p, int cmd, void *arg) if (pdFALSE == xSemaphoreGive(os_pwm_p->pwm_semaphore)) { /* We could not post the semaphore, exit with error */ - FPWM_ERROR("Pwm xSemaphoreGive failed\r\n"); + FPWM_ERROR("Pwm xSemaphoreGive failed."); return FREERTOS_PWM_SEM_ERROR; } @@ -188,9 +189,9 @@ FError FFreeRTOSPwmGet(FFreeRTOSPwm *os_pwm_p, FPwmChannel channel, FPwmVariable FError ret = FPWM_SUCCESS; FFreeRTOSPwmConfig configuration = {0}; configuration.channel = channel; - + ret = FFreeRTOSPwmControl(os_pwm_p, FREERTOS_PWM_CTRL_GET, &configuration); - if(ret == FPWM_SUCCESS) + if (ret == FPWM_SUCCESS) { *pwm_cfg_p = configuration.pwm_cfg; } @@ -210,12 +211,12 @@ FError FFreeRTOSPwmEnable(FFreeRTOSPwm *os_pwm_p, FPwmChannel channel, boolean s FASSERT(os_pwm_p); FASSERT(os_pwm_p->pwm_semaphore != NULL); FASSERT(channel < FPWM_CHANNEL_NUM); - + FError ret = FPWM_SUCCESS; FFreeRTOSPwmConfig configuration = {0}; configuration.channel = channel; - if (state==TRUE) + if (state == TRUE) { ret = FFreeRTOSPwmControl(os_pwm_p, FREERTOS_PWM_CTRL_ENABLE, &configuration); } @@ -223,7 +224,7 @@ FError FFreeRTOSPwmEnable(FFreeRTOSPwm *os_pwm_p, FPwmChannel channel, boolean s { ret = FFreeRTOSPwmControl(os_pwm_p, FREERTOS_PWM_CTRL_DISABLE, &configuration); } - + return ret; } @@ -250,7 +251,7 @@ FError FFreeRTOSPwmDbSet(FFreeRTOSPwm *os_pwm_p, FPwmDbVariableConfig *db_cfg_p) * @name: FFreeRTOSPwmDbGet * @msg: get pwm db config, include polarity, input source, delay time. * @param {FFreeRTOSPwm} *os_pwm_p, pointer to os pwm instance - * @param {FPwmDbVariableConfig} db_cfg_p, pwm db config parameters + * @param {FPwmDbVariableConfig} db_cfg_p, pwm db config parameters * @return err code information, FPWM_SUCCESS indicates success,others indicates failed */ FError FFreeRTOSPwmDbGet(FFreeRTOSPwm *os_pwm_p, FPwmDbVariableConfig *db_cfg_p) @@ -260,9 +261,9 @@ FError FFreeRTOSPwmDbGet(FFreeRTOSPwm *os_pwm_p, FPwmDbVariableConfig *db_cfg_p) FASSERT(db_cfg_p != NULL); FError ret = FPWM_SUCCESS; FFreeRTOSPwmConfig configuration = {0}; - + ret = FFreeRTOSPwmControl(os_pwm_p, FREERTOS_PWM_CTRL_DB_GET, &configuration); - if(ret == FPWM_SUCCESS) + if (ret == FPWM_SUCCESS) { *db_cfg_p = configuration.db_cfg; } diff --git a/drivers/pwm/fpwm_os.h b/drivers/pwm/fpwm_os.h index 18054a23..0344d17e 100644 --- a/drivers/pwm/fpwm_os.h +++ b/drivers/pwm/fpwm_os.h @@ -1,28 +1,29 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: fpwm_os.h * Date: 2022-02-24 13:42:19 * LastEditTime: 2022-03-21 16:59:58 - * Description:  This file is for - * - * Modify History: + * Description:  This file is for providing function related definitions of pwm driver used in FreeRTOS. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/08/26 first commit */ -#ifndef DRIVERS_FPWM_OS_H -#define DRIVERS_FPWM_OS_H +#ifndef FPWM_OS_H +#define FPWM_OS_H #include #include @@ -30,6 +31,11 @@ #include "fpwm.h" #include "ftypes.h" +#ifdef __cplusplus +extern "C" +{ +#endif + /* freertos pwm error */ #define FREERTOS_PWM_SEM_ERROR FT_CODE_ERR(ErrModBsp, ErrBspPwm, 10) @@ -50,7 +56,7 @@ typedef struct u32 channel; /* 0-1 */ FPwmVariableConfig pwm_cfg; FPwmDbVariableConfig db_cfg; -}FFreeRTOSPwmConfig; +} FFreeRTOSPwmConfig; typedef struct { @@ -82,5 +88,8 @@ FError FFreeRTOSPwmDbGet(FFreeRTOSPwm *os_pwm_p, FPwmDbVariableConfig *db_cfg_p) /* set pwm channel pulse */ FError FFreeRTOSPwmPulseSet(FFreeRTOSPwm *os_pwm_p, FPwmChannel channel, u16 pulse); +#ifdef __cplusplus +} +#endif #endif // ! diff --git a/drivers/qspi/fqspi_os.c b/drivers/qspi/fqspi_os.c index 25b97b86..a05198a6 100644 --- a/drivers/qspi/fqspi_os.c +++ b/drivers/qspi/fqspi_os.c @@ -1,24 +1,26 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: fqspi_os.c * Date: 2022-02-24 13:42:19 * LastEditTime: 2022-03-21 16:59:51 - * Description:  This file is for - * - * Modify History: + * Description:  This file is for required function implementations of qspi driver used in FreeRTOS. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/08/09 first commit + * 1.1 wangxiaodong 2022/11/09 qspi sfud perfection */ #include #include @@ -26,23 +28,30 @@ #include #include "task.h" #include "ftypes.h" +#include "fdebug.h" #include "fassert.h" #include "fqspi_os.h" #include "fqspi.h" #include "fqspi_hw.h" #include "fqspi_flash.h" -static FFreeRTOSQspi os_qspi[FQSPI_INSTANCE_NUM] = {0}; +#define FQSPI_DEBUG_TAG "FFreeRTOSQspi" +#define FQSPI_ERROR(format, ...) FT_DEBUG_PRINT_E(FQSPI_DEBUG_TAG, format, ##__VA_ARGS__) +#define FQSPI_WARN(format, ...) FT_DEBUG_PRINT_W(FQSPI_DEBUG_TAG, format, ##__VA_ARGS__) +#define FQSPI_INFO(format, ...) FT_DEBUG_PRINT_I(FQSPI_DEBUG_TAG, format, ##__VA_ARGS__) +#define FQSPI_DEBUG(format, ...) FT_DEBUG_PRINT_D(FQSPI_DEBUG_TAG, format, ##__VA_ARGS__) + +static FFreeRTOSQspi os_qspi[FQSPI_NUM] = {0}; /** * @name: FFreeRTOSQspiInit * @msg: init freertos qspi instance, include init qspi and create mutex - * @param {u32} instance_id, qspi instance id, such as FQSPI_INSTANCE_0 + * @param {u32} instance_id, qspi instance id, such as FQSPI0_ID * @return {FFreeRTOSQspi *} pointer to os qspi instance */ FFreeRTOSQspi *FFreeRTOSQspiInit(u32 instance_id) { - FASSERT(instance_id < FQSPI_INSTANCE_NUM); + FASSERT(instance_id < FQSPI_NUM); FASSERT(FT_COMPONENT_IS_READY != os_qspi[instance_id].qspi_ctrl.is_ready); /* qspi initialize */ @@ -50,11 +59,11 @@ FFreeRTOSQspi *FFreeRTOSQspiInit(u32 instance_id) qspi_config = *FQspiLookupConfig(instance_id); FASSERT(FQspiCfgInitialize(&os_qspi[instance_id].qspi_ctrl, &qspi_config) == FT_SUCCESS); /* detect connected flash infomation */ - FASSERT_MSG(FQspiFlashDetect(&os_qspi[instance_id].qspi_ctrl) == FT_SUCCESS, "flash detect failed."); + FASSERT_MSG(FQspiFlashDetect(&os_qspi[instance_id].qspi_ctrl) == FT_SUCCESS, "Flash detect failed."); /* qspi wr_semaphore initialize */ FASSERT((os_qspi[instance_id].wr_semaphore = xSemaphoreCreateMutex()) != NULL); - + return (&os_qspi[instance_id]); } @@ -94,7 +103,7 @@ FError FFreeRTOSQspiTransfer(FFreeRTOSQspi *os_qspi_p, FFreeRTOSQspiMessage *mes u8 cmd = message->cmd; u8 cs = message->cs; FASSERT(cs < FQSPI_CS_NUM); - + static u8 cs_bak = 0; static u8 read_cmd_bak = 0; size_t read_len = 0; @@ -102,17 +111,17 @@ FError FFreeRTOSQspiTransfer(FFreeRTOSQspi *os_qspi_p, FFreeRTOSQspiMessage *mes /* New transfer can be performed only after current one is finished */ if (pdFALSE == xSemaphoreTake(os_qspi_p->wr_semaphore, portMAX_DELAY)) { - printf("Qspi xSemaphoreTake failed\r\n"); + FQSPI_ERROR("Qspi xSemaphoreTake failed."); /* We could not take the semaphore, exit with 0 data received */ return FREERTOS_QSPI_SEM_ERROR; } /* set qspi cs number if the value is changed */ - if(cs != cs_bak) + if (cs != cs_bak) { FQspiChannelSet(pctrl, cs); cs_bak = cs; } - switch(cmd) + switch (cmd) { case FQSPI_FLASH_CMD_PP: { @@ -122,13 +131,13 @@ FError FFreeRTOSQspiTransfer(FFreeRTOSQspi *os_qspi_p, FFreeRTOSQspiMessage *mes ret = FQspiFlashWriteData(pctrl, cmd, flash_addr, write_buf, length); if (FQSPI_SUCCESS != ret) { - printf("Qspi failed to write mem, result 0x%x\r\n", ret); + FQSPI_ERROR("Qspi failed to write mem, result 0x%x", ret); goto transfer_exit; } } else { - printf("Qspi Transfer cmd %x write_buf is null\r\n", cmd); + FQSPI_ERROR("Qspi Transfer cmd %x write_buf is null.", cmd); ret = FQSPI_INVAL_PARAM; goto transfer_exit; } @@ -136,20 +145,20 @@ FError FFreeRTOSQspiTransfer(FFreeRTOSQspi *os_qspi_p, FFreeRTOSQspiMessage *mes break; case FQSPI_FLASH_CMD_READ: - case FQSPI_FLASH_CMD_DUAL_READ: - case FQSPI_FLASH_CMD_QIOR: + case FQSPI_FLASH_CMD_DUAL_READ: + case FQSPI_FLASH_CMD_QIOR: case FQSPI_FLASH_CMD_4QIOR: { if (NULL != read_buf) { /* read norflash data */ - if(cmd != read_cmd_bak) + if (cmd != read_cmd_bak) { ret |= FQspiFlashReadDataConfig(pctrl, cmd); read_cmd_bak = cmd; if (FQSPI_SUCCESS != ret) { - printf("Qspi read config failed\r\n"); + FQSPI_ERROR("Qspi read config failed."); goto transfer_exit; } } @@ -157,15 +166,15 @@ FError FFreeRTOSQspiTransfer(FFreeRTOSQspi *os_qspi_p, FFreeRTOSQspiMessage *mes read_len = FQspiFlashReadData(pctrl, flash_addr, read_buf, length); if (read_len != length) { - printf("Qspi failed to read mem, read len = %d\r\n", read_len); + FQSPI_ERROR("Qspi failed to read mem, read len = %d", read_len); ret = FQSPI_NOT_SUPPORT; goto transfer_exit; } - + } else { - printf("Qspi Transfer cmd %x read_buf is null\r\n", cmd); + FQSPI_ERROR("Qspi Transfer cmd %x read_buf is null.", cmd); ret = FQSPI_INVAL_PARAM; goto transfer_exit; } @@ -175,38 +184,38 @@ FError FFreeRTOSQspiTransfer(FFreeRTOSQspi *os_qspi_p, FFreeRTOSQspiMessage *mes case FQSPI_FLASH_CMD_RDID: case FQSPI_FLASH_CMD_RDSR1: ret = FQspiFlashSpecialInstruction(pctrl, cmd, read_buf, length); - break; + break; case FQSPI_FLASH_CMD_SFDP: ret = FQspiFlashReadSfdp(pctrl, flash_addr, read_buf, length); - break; + break; case FQSPI_CMD_ENABLE_RESET: case FQSPI_CMD_RESET: case FQSPI_FLASH_CMD_WRR: ret = FQspiFlashWriteReg(pctrl, cmd, NULL, 0); - break; + break; case FQSPI_FLASH_CMD_WREN: ret = FQspiFlashEnableWrite(pctrl); - break; + break; case FQSPI_FLASH_CMD_WRDI: ret = FQspiFlashDisableWrite(pctrl); - break; + break; - case FQSPI_FLASH_CMD_SE: + case FQSPI_FLASH_CMD_SE: case FQSPI_FLASH_CMD_4SE: case FQSPI_FLASH_CMD_4BE: case FQSPI_FLASH_CMD_P4E: ret = FQspiFlashErase(pctrl, cmd, flash_addr); - break; + break; default: - printf("Qspi Transfer cmd invalid\r\n"); + FQSPI_ERROR("Qspi Transfer cmd invalid."); ret = FQSPI_INVAL_PARAM; goto transfer_exit; - + } transfer_exit: @@ -214,7 +223,7 @@ transfer_exit: if (pdFALSE == xSemaphoreGive(os_qspi_p->wr_semaphore)) { /* We could not post the semaphore, exit with error */ - printf("Qspi xSemaphoreGive failed\r\n"); + FQSPI_ERROR("Qspi xSemaphoreGive failed."); ret |= FREERTOS_QSPI_SEM_ERROR; } diff --git a/drivers/qspi/fqspi_os.h b/drivers/qspi/fqspi_os.h index 8c59a75d..fb0b596c 100644 --- a/drivers/qspi/fqspi_os.h +++ b/drivers/qspi/fqspi_os.h @@ -1,28 +1,30 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: fqspi_os.h * Date: 2022-02-24 13:42:19 * LastEditTime: 2022-03-21 16:59:58 - * Description:  This file is for - * - * Modify History: + * Description:  This file is for providing function related definitions of qspi driver used in FreeRTOS. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/08/09 first commit + * 1.1 wangxiaodong 2022/11/09 qspi sfud perfection */ -#ifndef DRIVERS_FQSPI_OS_H -#define DRIVERS_FQSPI_OS_H +#ifndef FQSPI_OS_H +#define FQSPI_OS_H #include #include @@ -31,12 +33,17 @@ #include "fqspi_hw.h" #include "ftypes.h" +#ifdef __cplusplus +extern "C" +{ +#endif + #define FREERTOS_QSPI_SEM_ERROR FT_CODE_ERR(ErrModBsp, ErrBspQSpi, 10) /** * QSPI message structure */ -typedef struct +typedef struct { const void *write_buf; /* qspi write buffer */ void *read_buf; /* qspi read buffer */ @@ -44,7 +51,7 @@ typedef struct u32 addr; /* qspi flash address to read or write */ u8 cmd; /* qspi operate command */ u8 cs; /* qspi cs channel */ -}FFreeRTOSQspiMessage; +} FFreeRTOSQspiMessage; typedef struct { @@ -61,4 +68,8 @@ void FFreeRTOSQspiDeinit(FFreeRTOSQspi *os_qspi_p); /* tranfer qspi mesage */ FError FFreeRTOSQspiTransfer(FFreeRTOSQspi *os_qspi_p, FFreeRTOSQspiMessage *message); +#ifdef __cplusplus +} +#endif + #endif // ! diff --git a/drivers/serial/fpl011/fpl011_os.c b/drivers/serial/fpl011/fpl011_os.c index 3d231df9..bf25ebd4 100644 --- a/drivers/serial/fpl011/fpl011_os.c +++ b/drivers/serial/fpl011/fpl011_os.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: fpl011_os.c * Date: 2022-02-24 13:42:19 * LastEditTime: 2022-03-21 16:59:51 - * Description:  This file is for - * - * Modify History: + * Description:  This file is for required function implementations of pl011 driver used in FreeRTOS. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/04/21 first commit */ #include "fpl011_os.h" @@ -27,10 +28,17 @@ #include "finterrupt.h" #include "ftypes.h" #include "fassert.h" +#include "fdebug.h" #include "sdkconfig.h" #include "fcpu_info.h" #include +#define FPL011_DEBUG_TAG "FFreeRTOSPl001" +#define FPL011_ERROR(format, ...) FT_DEBUG_PRINT_E(FPL011_DEBUG_TAG, format, ##__VA_ARGS__) +#define FPL011_WARN(format, ...) FT_DEBUG_PRINT_W(FPL011_DEBUG_TAG, format, ##__VA_ARGS__) +#define FPL011_INFO(format, ...) FT_DEBUG_PRINT_I(FPL011_DEBUG_TAG, format, ##__VA_ARGS__) +#define FPL011_DEBUG(format, ...) FT_DEBUG_PRINT_D(FPL011_DEBUG_TAG, format, ##__VA_ARGS__) + /* Callback events */ static void FPl011IrqClearReciveTimeOut(FPl011 *uart_p) { @@ -101,7 +109,7 @@ void FtFreertosUartInit(FtFreertosUart *uart_p, FtFreertosUartConfig *config_p) bsp_uart_p = &uart_p->bsp_uart; uart_p->config = *config_p; driver_config = *FPl011LookupConfig(config_p->uart_instance); - + driver_config.baudrate = config_p->uart_baudrate; ret = FPl011CfgInitialize(bsp_uart_p, &driver_config); FASSERT(FT_SUCCESS == ret); @@ -115,10 +123,10 @@ void FtFreertosUartInit(FtFreertosUart *uart_p, FtFreertosUartConfig *config_p) GetCpuId(&cpu_id); InterruptSetTargetCpus(bsp_uart_p->config.irq_num, cpu_id); - FPl011SetRxFifoThreadhold(bsp_uart_p,FPL011IFLS_RXIFLSEL_1_4); - FPl011SetTxFifoThreadHold(bsp_uart_p,FPL011IFLS_TXIFLSEL_1_2); + FPl011SetRxFifoThreadhold(bsp_uart_p, FPL011IFLS_RXIFLSEL_1_4); + FPl011SetTxFifoThreadHold(bsp_uart_p, FPL011IFLS_TXIFLSEL_1_2); intr_mask = config_p->isr_event_mask; - FPl011SetInterruptMask(bsp_uart_p,intr_mask); + FPl011SetInterruptMask(bsp_uart_p, intr_mask); FPl011SetOptions(bsp_uart_p, FPL011_OPTION_UARTEN | FPL011_OPTION_RXEN | FPL011_OPTION_TXEN | FPL011_OPTION_FIFOEN); InterruptSetPriority(bsp_uart_p->config.irq_num, config_p->isr_priority); @@ -136,7 +144,7 @@ FError FtFreertosUartReceiveBuffer(FtFreertosUart *uart_p, u8 *buffer, u32 lengt FASSERT(NULL != buffer); bsp_uart_p = &uart_p->bsp_uart; - if(length == 0) + if (length == 0) { *received_length = 0; return FT_SUCCESS; @@ -151,7 +159,7 @@ FError FtFreertosUartReceiveBuffer(FtFreertosUart *uart_p, u8 *buffer, u32 lengt - if(uart_p->config.isr_event_mask & (RTOS_UART_ISR_RTIM_MASK|RTOS_UART_ISR_RXIM_MASK) ) + if (uart_p->config.isr_event_mask & (RTOS_UART_ISR_RTIM_MASK | RTOS_UART_ISR_RXIM_MASK)) { get_length = FPl011Receive(bsp_uart_p, buffer, length); if (get_length > 0) @@ -164,8 +172,8 @@ FError FtFreertosUartReceiveBuffer(FtFreertosUart *uart_p, u8 *buffer, u32 lengt FPl011IrqEnableReciveTimeOut(bsp_uart_p); ev = xEventGroupWaitBits(uart_p->rx_event, - RTOS_UART_COMPLETE | RTOS_UART_HARDWARE_BUFFER_OVERRUN | RTOS_UART_RECV_ERROR, - pdTRUE, pdFALSE, portMAX_DELAY); + RTOS_UART_COMPLETE | RTOS_UART_HARDWARE_BUFFER_OVERRUN | RTOS_UART_RECV_ERROR, + pdTRUE, pdFALSE, portMAX_DELAY); if (ev & RTOS_UART_HARDWARE_BUFFER_OVERRUN) { @@ -200,7 +208,7 @@ FError FtFreertosUartReceiveBuffer(FtFreertosUart *uart_p, u8 *buffer, u32 lengt if (pdFALSE == xSemaphoreGive(uart_p->rx_semaphore)) { /* We could not post the semaphore, exit with error */ - printf("FST_FAILURE xSemaphoreGive \r\n"); + FPL011_ERROR("FST_FAILURE xSemaphoreGive."); ret = FREERTOS_UART_RECV_ERROR; } @@ -222,10 +230,10 @@ FError FtFreertosUartBlcokingSend(FtFreertosUart *uart_p, u8 *buffer, u32 length return FREERTOS_UART_SEM_ERROR; } - if(uart_p->config.isr_event_mask & RTOS_UART_ISR_TXIM_MASK) + if (uart_p->config.isr_event_mask & RTOS_UART_ISR_TXIM_MASK) { send_length = FPl011Send(bsp_uart_p, buffer, length); - if(send_length != length) + if (send_length != length) { ev = xEventGroupWaitBits(uart_p->tx_event, RTOS_UART_COMPLETE, pdTRUE, pdFALSE, portMAX_DELAY); if (!(ev & RTOS_UART_COMPLETE)) @@ -236,7 +244,7 @@ FError FtFreertosUartBlcokingSend(FtFreertosUart *uart_p, u8 *buffer, u32 length } else { - FPl011BlockSend(bsp_uart_p,buffer,length); + FPl011BlockSend(bsp_uart_p, buffer, length); } if (pdFALSE == xSemaphoreGive(uart_p->tx_semaphore)) diff --git a/drivers/serial/fpl011/fpl011_os.h b/drivers/serial/fpl011/fpl011_os.h index f6826f4a..27b57954 100644 --- a/drivers/serial/fpl011/fpl011_os.h +++ b/drivers/serial/fpl011/fpl011_os.h @@ -1,29 +1,29 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: fpl011_os.h * Date: 2022-02-24 13:42:19 * LastEditTime: 2022-03-21 16:59:58 - * Description:  This file is for - * - * Modify History: + * Description:  This file is for providing function related definitions of pl011 driver used in FreeRTOS. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/04/21 first commit */ - -#ifndef DRIVERS_SERIAL_FPL011_H -#define DRIVERS_SERIAL_FPL011_H +#ifndef FPL011_OS_H +#define FPL011_OS_H #include #include @@ -33,6 +33,11 @@ #include "ftypes.h" #include "ferror_code.h" +#ifdef __cplusplus +extern "C" +{ +#endif + #define FREERTOS_UART_SEM_ERROR FT_CODE_ERR(ErrModPort, 0, 0x1) #define FREERTOS_UART_EVENT_ERROR FT_CODE_ERR(ErrModPort, 0, 0x2) #define FREERTOS_UART_FIFO_ERROR FT_CODE_ERR(ErrModPort, 0, 0x3) @@ -48,7 +53,7 @@ * @cond RTOS_PRIVATE * @name UART FreeRTOS handler * -* These are the only valid states for txEvent and rxEvent +* These are the only valid states for txEvent and rxEvent */ /*@{*/ /*! @brief Event flag - transfer complete. */ @@ -91,4 +96,8 @@ void FtFreertosUartInit(FtFreertosUart *uart_p, FtFreertosUartConfig *config_p); FError FtFreertosUartBlcokingSend(FtFreertosUart *uart_p, u8 *buffer, u32 length); FError FtFreertosUartReceiveBuffer(FtFreertosUart *uart_p, u8 *buffer, u32 length, u32 *received_length); +#ifdef __cplusplus +} +#endif + #endif // ! diff --git a/drivers/spi/fspim/fspim_os.c b/drivers/spi/fspim/fspim_os.c index e5bd91b3..bc5e0288 100644 --- a/drivers/spi/fspim/fspim_os.c +++ b/drivers/spi/fspim/fspim_os.c @@ -1,22 +1,22 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: fspim_os.c * Date: 2022-07-18 09:05:53 * LastEditTime: 2022-07-18 09:05:53 - * Description:  This files is for - * - * Modify History: + * Description:  This file is for required function implementations of spi master driver used in FreeRTOS. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- * 1.0 zhugengyu 2022/7/27 init commit @@ -42,7 +42,7 @@ /**************************** Type Definitions *******************************/ /************************** Variable Definitions *****************************/ -static FFreeRTOSSpim spim[FSPI_DEVICE_NUM]; +static FFreeRTOSSpim spim[FSPI_NUM]; /***************** Macros (Inline Functions) Definitions *********************/ #define FSPIM_DEBUG_TAG "FSPIM-OS" @@ -58,10 +58,10 @@ static void FSpimOsAckTransDone(void *instance_p, void *param); static inline FError FSpimOsTakeSema(SemaphoreHandle_t locker) { - FASSERT_MSG((NULL != locker), "locker not exists"); + FASSERT_MSG((NULL != locker), "Locker not exists."); if (pdFALSE == xSemaphoreTake(locker, portMAX_DELAY)) { - FSPIM_ERROR("failed to give locker !!!"); + FSPIM_ERROR("Failed to give locker!!!"); return FFREERTOS_SPIM_SEMA_ERR; } @@ -70,10 +70,10 @@ static inline FError FSpimOsTakeSema(SemaphoreHandle_t locker) static inline void FSpimOsGiveSema(SemaphoreHandle_t locker) { - FASSERT_MSG((NULL != locker), "locker not exists"); + FASSERT_MSG((NULL != locker), "Locker not exists."); if (pdFALSE == xSemaphoreGive(locker)) { - FSPIM_ERROR("failed to give locker !!!"); + FSPIM_ERROR("Failed to give locker!!!"); } return; @@ -94,9 +94,9 @@ static void FSpimOSSetupInterrupt(FSpim *ctrl) InterruptSetPriority(config_p->irq_num, config_p->irq_prority); /* register intr callback */ - InterruptInstall(config_p->irq_num, - FSpimInterruptHandler, - ctrl, + InterruptInstall(config_p->irq_num, + FSpimInterruptHandler, + ctrl, NULL); /* disable spi irq */ @@ -111,14 +111,14 @@ static void FSpimOSSetupInterrupt(FSpim *ctrl) /** * @name: FFreeRTOSSpimInit * @msg: init and get spi instance - * @return {FFreeRTOSSpim *} return + * @return {FFreeRTOSSpim *} return * @param {u32} id, spim instance id * @param {FFreeRTOSSpimConifg} *input_config, freertos spim config */ FFreeRTOSSpim *FFreeRTOSSpimInit(u32 id, const FFreeRTOSSpimConifg *input_config) { FASSERT(input_config); - FASSERT_MSG(id < FSPI_DEVICE_NUM, "invalid spim id"); + FASSERT_MSG(id < FSPI_NUM, "Invalid spim id."); FFreeRTOSSpim *instance = &spim[id]; FSpim *ctrl = &instance->ctrl; FSpimConfig config; @@ -126,7 +126,7 @@ FFreeRTOSSpim *FFreeRTOSSpimInit(u32 id, const FFreeRTOSSpimConifg *input_config if (FT_COMPONENT_IS_READY == ctrl->is_ready) { - FSPIM_ERROR("spi-%d already init", id); + FSPIM_ERROR("spi-%d already init.", id); return instance; } @@ -136,7 +136,7 @@ FFreeRTOSSpim *FFreeRTOSSpimInit(u32 id, const FFreeRTOSSpimConifg *input_config instance->config = *input_config; config = *FSpimLookupConfig(id); config.slave_dev_id = FSPIM_SLAVE_DEV_0; - + if (FFREERTOS_SPIM_MODE_0 == instance->config.spi_mode) /* mode 0 */ { config.cpha = FSPIM_CPHA_1_EDGE; @@ -145,7 +145,7 @@ FFreeRTOSSpim *FFreeRTOSSpimInit(u32 id, const FFreeRTOSSpimConifg *input_config else if (FFREERTOS_SPIM_MODE_1 == instance->config.spi_mode) /* mode 1 */ { config.cpha = FSPIM_CPHA_2_EDGE; - config.cpol = FSPIM_CPOL_LOW; + config.cpol = FSPIM_CPOL_LOW; } else if (FFREERTOS_SPIM_MODE_2 == instance->config.spi_mode) /* mode 2 */ { @@ -156,34 +156,34 @@ FFreeRTOSSpim *FFreeRTOSSpimInit(u32 id, const FFreeRTOSSpimConifg *input_config { config.cpha = FSPIM_CPHA_2_EDGE; config.cpol = FSPIM_CPOL_HIGH; - } + } config.n_bytes = FSPIM_1_BYTE; config.en_test = instance->config.inner_loopback; config.en_dma = instance->config.en_dma; config.irq_prority = FFREERTOS_SPIM_IRQ_PRIORITY; - config.max_freq_hz = FSPIM_OS_MAX_SPEED; + config.max_freq_hz = FSPIM_OS_MAX_SPEED; FIOPadSetSpimMux(id); FSPIM_INFO("init spi-%d @ 0x%x", config.instance_id, config.base_addr); err = FSpimCfgInitialize(ctrl, &config); if (FSPIM_SUCCESS != err) - { - FSPIM_ERROR("init spim-%d failed, err: 0x%x !!!", id, err); + { + FSPIM_ERROR("Init spim-%d failed, err: 0x%x!!!", id, err); goto err_exit; - } + } - FASSERT_MSG(NULL == instance->locker, "locker exists !!!"); - FASSERT_MSG((instance->locker = xSemaphoreCreateMutex()) != NULL, "create mutex failed !!!"); + FASSERT_MSG(NULL == instance->locker, "Locker exists!!!"); + FASSERT_MSG((instance->locker = xSemaphoreCreateMutex()) != NULL, "Create mutex failed!!!"); - FASSERT_MSG(NULL == instance->evt, "event group exists !!!"); - FASSERT_MSG((instance->evt = xEventGroupCreate()) != NULL, "create event group failed !!!"); + FASSERT_MSG(NULL == instance->evt, "Event group exists!!!"); + FASSERT_MSG((instance->evt = xEventGroupCreate()) != NULL, "Create event group failed!!!"); FSpimOSSetupInterrupt(ctrl); FSpimRegisterIntrruptHandler(ctrl, FSPIM_INTR_EVT_RX_DONE, FSpimOsAckTransDone, instance); - FSPIM_INFO("init spi-%d success !!!", id); + FSPIM_INFO("Init spi-%d success!!!", id); err_exit: taskEXIT_CRITICAL(); /* allow schedule after init */ @@ -204,20 +204,20 @@ FError FFreeRTOSSpimDeInit(FFreeRTOSSpim *const instance) if (FT_COMPONENT_IS_READY != ctrl->is_ready) { - FSPIM_ERROR("ddma-%d already init"); + FSPIM_ERROR("ddma-%d already init."); return FFREERTOS_SPIM_NOT_INIT; } /* no scheduler during deinit */ - taskENTER_CRITICAL(); + taskENTER_CRITICAL(); FSpimDeInitialize(ctrl); - FASSERT_MSG(NULL != instance->locker, "locker not exists !!!"); + FASSERT_MSG(NULL != instance->locker, "Locker not exists!!!"); vSemaphoreDelete(instance->locker); instance->locker = NULL; - FASSERT_MSG(NULL != instance->evt, "event group not exists !!!"); + FASSERT_MSG(NULL != instance->evt, "Event group not exists!!!"); vEventGroupDelete(instance->evt); instance->evt = NULL; @@ -227,7 +227,7 @@ FError FFreeRTOSSpimDeInit(FFreeRTOSSpim *const instance) } /* ack transfer finish from interrupt */ -static void FSpimOsAckTransDone(void *instance_p, void *param) +static void FSpimOsAckTransDone(void *instance_p, void *param) { FASSERT(param); FFreeRTOSSpim *instance = (FFreeRTOSSpim *)param; @@ -243,23 +243,23 @@ static void FSpimOsAckTransDone(void *instance_p, void *param) } /* wait transfer finish ack from task */ -static FError FSpimOsWaitTransDone(FFreeRTOSSpim *const instance) +static FError FSpimOsWaitTransDone(FFreeRTOSSpim *const instance) { const TickType_t wait_delay = pdMS_TO_TICKS(5000UL); /* wait for 5 seconds */ EventBits_t ev; FError err = FFREERTOS_SPIM_OK; /* block task to wait finish signal */ - FASSERT_MSG(instance->evt, "evt not exists"); + FASSERT_MSG(instance->evt, "Evt not exists."); ev = xEventGroupWaitBits(instance->evt, FFREERTOS_TRANS_DONE, pdTRUE, pdFALSE, wait_delay); /* wait for trans done */ - if ((ev & FFREERTOS_TRANS_DONE)) - { - FSPIM_DEBUG("trans done"); - } - else + if ((ev & FFREERTOS_TRANS_DONE)) { - FSPIM_ERROR("trans timeout"); + FSPIM_DEBUG("Trans done."); + } + else + { + FSPIM_ERROR("Trans timeout."); err = FFREERTOS_SPIM_WAIT_EVT_TIMOUT; } @@ -275,7 +275,7 @@ static FError FSpimOsTx(FFreeRTOSSpim *const instance, const u8 *tx_buf, fsize_t err = FSpimTransferByInterrupt(ctrl, tx_buf, NULL, tx_len); /* start transfer */ if (FSPIM_SUCCESS != err) { - FSPIM_ERROR("spim transfer failed: 0x%x", err); + FSPIM_ERROR("Spim transfer failed: 0x%x", err); } else { @@ -295,7 +295,7 @@ static FError FSpimOsRx(FFreeRTOSSpim *const instance, u8 *rx_buf, fsize_t rx_le err = FSpimTransferByInterrupt(ctrl, NULL, rx_buf, rx_len); /* start transfer */ if (FSPIM_SUCCESS != err) { - FSPIM_ERROR("spim transfer failed: 0x%x", err); + FSPIM_ERROR("Spim transfer failed: 0x%x", err); } else { @@ -322,19 +322,21 @@ FError FFreeRTOSSpimTransfer(FFreeRTOSSpim *const instance, const FFreeRTOSSpiMe err = FSpimOsTakeSema(instance->locker); /* in case other tasks try to do transfer */ if (FFREERTOS_SPIM_OK != err) + { return err; + } FSpimSetChipSelection(ctrl, TRUE); /* toggle on chip selection */ - FSPIM_INFO("tx_buf@%p, len: %d, rx_buf@%p, len: %d", - message->tx_buf, message->tx_len, message->rx_buf, message->rx_len); + FSPIM_INFO("tx_buf@%p, len: %d, rx_buf@%p, len: %d", + message->tx_buf, message->tx_len, message->rx_buf, message->rx_len); if (instance->config.en_dma) /* dma-mode */ { - FSPIM_INFO("start DMA tx: %d, rx: %d", message->tx_len, message->rx_len); + FSPIM_INFO("Start DMA tx: %d, rx: %d", message->tx_len, message->rx_len); err = FSpimTransferDMA(ctrl, (0U != message->tx_len), (0U != message->rx_len)); if (FSPIM_SUCCESS != err) { - FSPIM_ERROR("spim DMA transfer failed: 0x%x", err); + FSPIM_ERROR("Spim DMA transfer failed: 0x%x", err); } } @@ -358,5 +360,5 @@ FError FFreeRTOSSpimTransfer(FFreeRTOSSpim *const instance, const FFreeRTOSSpiMe err_exit: FSpimOsGiveSema(instance->locker); - return err; + return err; } \ No newline at end of file diff --git a/drivers/spi/fspim/fspim_os.h b/drivers/spi/fspim/fspim_os.h index 31b974e9..951f6340 100644 --- a/drivers/spi/fspim/fspim_os.h +++ b/drivers/spi/fspim/fspim_os.h @@ -1,34 +1,29 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: fspim_os.h * Date: 2022-07-18 09:05:48 * LastEditTime: 2022-07-18 09:05:48 - * Description:  This files is for - * - * Modify History: + * Description:  This file is for providing function related definitions of spi master driver used in FreeRTOS. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- * 1.0 zhugengyu 2022/7/27 init commit */ -#ifndef DRIVERS_FSPIM_OS_H -#define DRIVERS_FSPIM_OS_H - -#ifdef __cplusplus -extern "C" -{ -#endif +#ifndef FSPIM_OS_H +#define FSPIM_OS_H /***************************** Include Files *********************************/ #include #include @@ -37,6 +32,10 @@ extern "C" #include "fparameters.h" #include "fspim.h" +#ifdef __cplusplus +extern "C" +{ +#endif /************************** Constant Definitions *****************************/ #define FFREERTOS_SPIM_OK FT_SUCCESS #define FFREERTOS_SPIM_NOT_INIT FT_CODE_ERR(ErrModPort, ErrBspSpi, 0) @@ -49,7 +48,7 @@ extern "C" #define FFREERTOS_SPIM_MODE_0 0U /* CPOL = 0, CPHA = 0 */ #define FFREERTOS_SPIM_MODE_1 1U /* CPOL = 1, CPHA = 0 */ -#define FFREERTOS_SPIM_MODE_2 1U /* CPOL = 0, CPHA = 1 */ +#define FFREERTOS_SPIM_MODE_2 2U /* CPOL = 0, CPHA = 1 */ #define FFREERTOS_SPIM_MODE_3 3U /* CPOL = 1, CPHA = 1 */ /**************************** Type Definitions *******************************/ @@ -90,7 +89,7 @@ FFreeRTOSSpim *FFreeRTOSSpimInit(u32 instance_id, const FFreeRTOSSpimConifg *con /* deinit spi instance */ FError FFreeRTOSSpimDeInit(FFreeRTOSSpim *const instance); -/* for NON-DMA transfer, start spi transfer and wait transfer done in this function, +/* for NON-DMA transfer, start spi transfer and wait transfer done in this function, for DMA transfer, start DMA channel first, then call this function and wait DMA channel end later */ FError FFreeRTOSSpimTransfer(FFreeRTOSSpim *const instance, const FFreeRTOSSpiMessage *message); diff --git a/drivers/timer/ftimer_tacho_os.c b/drivers/timer/ftimer_tacho_os.c new file mode 100644 index 00000000..fd86589e --- /dev/null +++ b/drivers/timer/ftimer_tacho_os.c @@ -0,0 +1,486 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: ftimer_tacho_os.c + * Date: 2022-08-23 17:20:51 + * LastEditTime: 2022-08-23 17:20:51 + * Description:  This file is for required function implementations of timer tacho driver used in FreeRTOS. + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 liushengming 2022/11/25 first commit + */ + +#include +#include "fkernel.h" +#include "ftimer_tacho.h" +#include "ftimer_tacho_os.h" +#include "fparameters.h" +#include "finterrupt.h" +#include "fsleep.h" +#include "fassert.h" +#include "fpinctrl.h" +#include "fpinctrl.h" + +#define FTACHO_OS_DEBUG_TAG "FFreeRTOSTacho" +#define FTACHO_OS_ERROR(format, ...) FT_DEBUG_PRINT_E(FTACHO_OS_DEBUG_TAG, format, ##__VA_ARGS__) +#define FTACHO_OS_WARN(format, ...) FT_DEBUG_PRINT_W(FTACHO_OS_DEBUG_TAG, format, ##__VA_ARGS__) +#define FTACHO_OS_INFO(format, ...) FT_DEBUG_PRINT_I(FTACHO_OS_DEBUG_TAG, format, ##__VA_ARGS__) +#define FTACHO_OS_DEBUG(format, ...) FT_DEBUG_PRINT_D(FTACHO_OS_DEBUG_TAG, format, ##__VA_ARGS__) + +#define FTIMER_OS_DEBUG_TAG "FFreeRTOSTimer" +#define FTIMER_OS_ERROR(format, ...) FT_DEBUG_PRINT_E(FTIMER_OS_DEBUG_TAG, format, ##__VA_ARGS__) +#define FTIMER_OS_WARN(format, ...) FT_DEBUG_PRINT_W(FTIMER_OS_DEBUG_TAG, format, ##__VA_ARGS__) +#define FTIMER_OS_INFO(format, ...) FT_DEBUG_PRINT_I(FTIMER_OS_DEBUG_TAG, format, ##__VA_ARGS__) +#define FTIMER_OS_DEBUG(format, ...) FT_DEBUG_PRINT_D(FTIMER_OS_DEBUG_TAG, format, ##__VA_ARGS__) + +/************************** Constant Definitions *****************************/ +/*Notice:timer are 38U,tacho nums only FTACHO_NUM = 16U,but they use the same controller num 0~15. */ +static FFreeRTOSTimerTacho os_timer_tacho[38] = {0}; + +#define MAX_32_VAL GENMASK(31, 0) +#define MAX_64_VAL GENMASK_ULL(63, 0) +#define TACHO_MAX 10000 +#define TACHO_MIN 10 +#define TACHO_PERIOD 1000000 /* 1000000/50000000 = 0.02s 20ms ticks period at 50Mhz pclk*/ + +#define US2TICKS(us) ((FTIMER_CLK_FREQ_HZ * (us) / 1000000ULL ) + 1ULL) +#define MS2TICKS(ms) (US2TICKS(1000ULL) * (ms)) + +/************************** Variable Definitions *****************************/ + +typedef struct +{ + u32 id; /* id of tacho */ + boolean work_mode; /*tacho or capture*/ + boolean bits32; /*otherwise 64 bit*/ + boolean restart_mode; /*otherwise free-run*/ + u8 edge_mode; /* rising falling or double edge*/ + u8 jitter_level; /* anti_jitter_number 0~3 */ + u32 plus_num; /* plus_num of period to calculate rpm */ +} FFreeRTOSTachoConfigs; + +typedef struct +{ + u32 id; /* id of timer */ + boolean bits32; /*otherwise 64 bit*/ + boolean restartmode; /*otherwise free-run*/ + boolean cyc_cmp; /*otherwise once cmp*/ + boolean clear_cnt; /*otherwise not clear*/ + boolean forceload; /*otherwise not force-load*/ + u32 startcnt; /*start cnt num*/ + u32 cmptick32; /*32bit cnt num*/ + u64 cmptick64; /*64bit cnt num*/ +} FFreeRTOSTimerConfigs; + +static FFreeRTOSTimerConfigs timercfg; +static FFreeRTOSTachoConfigs tachocfg; + +/************************** Function Prototypes ******************************/ + +/** + * @name: FTimerCfgInit + * @msg: 加载转换后配置项,并完成初始化操作,定时器处于就绪状态 + * @return {FError} 驱动初始化的错误码信息,FTIMER_TACHO_SUCCESS 表示初始化成功,其它返回值表示初始化失败 + * @param {TimerTestConfigs} *timercfg_p 可操作的配置参数结构体 + */ +static FError FTimerCfgInit(const FFreeRTOSTimerConfigs *timercfg_p, FTimerTachoCtrl *timer) +{ + FASSERT(timercfg_p); + FASSERT(timer); + FError ret = FREERTOS_TIMER_TACHO_SUCCESS; + + FTimerTachoConfig *pconfig = &timer->config; + + FTimerGetDefConfig(timercfg_p->id, pconfig); + + if (timercfg_p->restartmode) + { + pconfig->timer_mode = FTIMER_RESTART; + } + else + { + pconfig->timer_mode = FTIMER_FREE_RUN; + } + + if (timercfg_p->bits32) + { + pconfig->timer_bits = FTIMER_32_BITS; + } + else + { + pconfig->timer_bits = FTIMER_64_BITS; + } + + if (timercfg_p->cyc_cmp) + { + pconfig->cmp_type = FTIMER_CYC_CMP; + } + else + { + pconfig->cmp_type = FTIMER_ONCE_CMP; + } + + ret = FTimerInit(timer, pconfig); + if (FREERTOS_TIMER_TACHO_SUCCESS != ret) + { + return ret; + } + + /*将时间参数us装换成计时器的ticks,我们设置StartTick,将CmpTick设置为最大*/ + ret = FTimerSetStartVal(timer, timercfg.startcnt); + if (FREERTOS_TIMER_TACHO_SUCCESS != ret) + { + return ret; + } + + if (timercfg_p->bits32) + { + ret |= FTimerSetPeriod32(timer, timercfg.cmptick32); + } + else + { + ret |= FTimerSetPeriod64(timer, timercfg.cmptick64); + } + + FTIMER_OS_INFO("Timer Init finished."); + + return ret; +} + +/** + * @name: FTimerFunctionInit + * @msg: timer init. + * @param {u8}id :use 0~37 timer + * @param {boolean}timer_mode:单次定时还是循环定时 + * @param {u64}times:定时时间,单位us + * @return {FFreeRTOSSpim *} return + */ +FFreeRTOSTimerTacho *FFreeRTOSTimerInit(u32 id, boolean timer_mode, u64 times) +{ + FASSERT_MSG(id < FTIMER_NUM, "Invalid timer id."); + FASSERT_MSG(FT_COMPONENT_IS_READY != os_timer_tacho[id].ctrl.isready, "timer_tacho ready."); + FFreeRTOSTimerTacho *instance = &os_timer_tacho[id]; + + FASSERT(FT_COMPONENT_IS_READY != os_timer_tacho[id].ctrl.isready); + FASSERT((instance->locker = xSemaphoreCreateMutex()) != NULL); + + u64 cnttick = 0; + FTimerTachoCtrl *timer = &instance->ctrl; + timercfg.id = id; + timercfg.cyc_cmp = timer_mode; + cnttick = US2TICKS(times); + FTIMER_OS_INFO("\n***cnttick:%llu.", cnttick); + if (cnttick > 0xffffffff) + { + timercfg.bits32 = FALSE; + timercfg.startcnt = MAX_64_VAL - cnttick; + } + else + { + timercfg.bits32 = TRUE; + timercfg.startcnt = MAX_32_VAL - cnttick; + } + /* Set CmpTick max value ,that we can easy to trigger RolloverIntr. */ + timercfg.cmptick32 = MAX_32_VAL; + timercfg.cmptick64 = MAX_64_VAL; + + if (FREERTOS_TIMER_TACHO_SUCCESS != FTimerCfgInit(&timercfg, timer)) + { + FTIMER_OS_ERROR("Timer config init failed."); + return NULL; + } + return (&os_timer_tacho[id]); +} + +/** + * @name: FFTimerStartTest + * @msg: start timer. + * @param {u64 times,boolean forceLoad} + * @return {FError} + */ +FError FFreeRTOSTimerStart(FFreeRTOSTimerTacho *os_timer_p) +{ + FASSERT(NULL != os_timer_p->locker); + FError ret = FREERTOS_TIMER_TACHO_SUCCESS; + + FTimerTachoCtrl *timer = &os_timer_p->ctrl; + + if (pdFALSE == xSemaphoreTake(os_timer_p->locker, portMAX_DELAY)) + { + FTIMER_OS_ERROR("Timer xSemaphoreTake failed."); + /* We could not take the semaphore, exit with 0 data received */ + return FREERTOS_TIMER_TACHO_SEMA_ERROR; + } + + ret = FTimerStart(timer); + if (FREERTOS_TIMER_TACHO_SUCCESS != ret) + { + return ret; + } + return ret; +} + + +/** + * @name: FFreeRTOSTimerStop + * @msg: + * @return {*} + * @param {FFreeRTOSTimerTacho} *os_timer_p + */ +FError FFreeRTOSTimerStop(FFreeRTOSTimerTacho *os_timer_p) +{ + FASSERT(NULL != os_timer_p->locker); + + if (pdFALSE == xSemaphoreGive(os_timer_p->locker)) + { + /* We could not post the semaphore, exit with error */ + FTIMER_OS_ERROR("Timer xSemaphoreGive failed."); + return FREERTOS_TIMER_TACHO_SEMA_ERROR; + } + FTimerTachoCtrl *timer = &os_timer_p->ctrl; + + return FTimerStop(timer); +} + + +/** + * @name: FFreeRTOSTimerDeinit + * @msg: + * @return {*} void + * @param {FFreeRTOSTimerTacho} *os_timer_p + */ +void FFreeRTOSTimerDeinit(FFreeRTOSTimerTacho *os_timer_p) +{ + FASSERT(NULL != os_timer_p->locker); + + FTimerDeInit(&os_timer_p->ctrl); + vSemaphoreDelete(os_timer_p->locker); + memset(os_timer_p, 0, sizeof(*os_timer_p)); + return; +} + + +/** + * @name: FFreeRTOSTimerDebug + * @msg: Dump timer reg message + * @return {*} + * @param {FFreeRTOSTimerTacho} *os_timer_p + */ +void FFreeRTOSTimerDebug(FFreeRTOSTimerTacho *os_timer_p) +{ + FASSERT(NULL != os_timer_p); + FTimeSettingDump(&os_timer_p->ctrl); + return; +} + + + +/**********************************************************************************************************/ +/***********************************************tacho******************************************************/ +/**********************************************************************************************************/ + +/** + * @name: FTachoCfgInit + * @msg: 添加配置 + * @return {*} + * @param {FFreeRTOSTachoConfigs} *tachocfg_p + * @param {FTimerTachoCtrl} *tacho + */ +static FError FTachoCfgInit(const FFreeRTOSTachoConfigs *tachocfg_p, FTimerTachoCtrl *tacho) +{ + FASSERT(tachocfg_p); + FASSERT(tacho); + FError ret = FREERTOS_TIMER_TACHO_SUCCESS; + + FTimerTachoConfig *pconfig = &tacho->config; + memset(tacho, 0, sizeof(tacho)); + /* tacho */ + FTachoGetDefConfig(tachocfg_p->id, pconfig); + + if (tachocfg_p->work_mode == FTIMER_WORK_MODE_TACHO) + { + pconfig->work_mode = FTIMER_WORK_MODE_TACHO; + + if (tachocfg_p->bits32 == FTIMER_32_BITS) + { + pconfig->timer_bits = FTIMER_32_BITS; + } + else + { + pconfig->timer_bits = FTIMER_64_BITS; + } + + if (tachocfg_p->restart_mode) + { + pconfig->timer_mode = FTIMER_RESTART; + } + else + { + pconfig->timer_mode = FTIMER_FREE_RUN; + } + } + else + { + pconfig->work_mode = FTIMER_WORK_MODE_CAPTURE; + pconfig->captue_cnt = 0x7f;/* 边沿检测计数默认值 */ + } + + if (tachocfg_p->edge_mode == FTACHO_RISING_EDGE) + { + pconfig->edge_mode = FTACHO_RISING_EDGE; + } + else if (tachocfg_p->edge_mode == FTACHO_FALLING_EDGE) + { + pconfig->edge_mode = FTACHO_FALLING_EDGE; + } + else + { + pconfig->edge_mode = FTACHO_DOUBLE_EDGE; + } + + switch (tachocfg_p->jitter_level) + { + case FTACHO_JITTER_LEVEL0: + pconfig->jitter_level = FTACHO_JITTER_LEVEL0; + break; + case FTACHO_JITTER_LEVEL1: + pconfig->jitter_level = FTACHO_JITTER_LEVEL1; + break; + case FTACHO_JITTER_LEVEL2: + pconfig->jitter_level = FTACHO_JITTER_LEVEL2; + break; + case FTACHO_JITTER_LEVEL3: + pconfig->jitter_level = FTACHO_JITTER_LEVEL3; + break; + default: + pconfig->jitter_level = FTACHO_JITTER_LEVEL0; + break; + } + + if (tachocfg_p->plus_num != 0) + { + pconfig->plus_num = tachocfg_p->plus_num; + } + + ret = FTachoInit(tacho, pconfig); +} + +/** + * @name: FFreeRTOSTachoInit + * @msg: tacho or capture init function + * @return {*} + * @param {u32} id + * @param {boolean} tacho_mode + */ +FFreeRTOSTimerTacho *FFreeRTOSTachoInit(u32 id, boolean tacho_mode) +{ + FASSERT_MSG(id < FTACHO_NUM, "Invalid timer id."); + FASSERT_MSG(FT_COMPONENT_IS_READY != os_timer_tacho[id].ctrl.isready, "timer_tacho ready."); + + FFreeRTOSTimerTacho *instance = &os_timer_tacho[id]; + FTimerTachoCtrl *tacho = &os_timer_tacho[id].ctrl; + + FASSERT((instance->locker = xSemaphoreCreateMutex()) != NULL); + + FError ret = FREERTOS_TIMER_TACHO_SUCCESS; + tachocfg.id = id; + tachocfg.edge_mode = FTACHO_RISING_EDGE;/* Not open operation interface for cmd */ + tachocfg.jitter_level = FTACHO_JITTER_LEVEL0;/* Not open operation interface for cmd */ + tachocfg.bits32 = FTIMER_32_BITS;/* Use capture mode, Not open operation interface for cmd.*/ + tachocfg.restart_mode = FTIMER_RESTART;/* Use capture mode, Not open operation interface for cmd.*/ + tachocfg.plus_num = TACHO_PERIOD; + if (tacho_mode == FTIMER_WORK_MODE_TACHO) + { + tachocfg.work_mode = FTIMER_WORK_MODE_TACHO; + } + else + { + tachocfg.work_mode = FTIMER_WORK_MODE_CAPTURE; + } + + FIOPadSetTachoMux(tachocfg.id); + + ret = FTachoCfgInit(&tachocfg, tacho); + if (ret != FREERTOS_TIMER_TACHO_SUCCESS) + { + FTACHO_OS_ERROR("Tacho config init failed."); + return NULL; + } + + if (tacho_mode == FTIMER_WORK_MODE_TACHO) + { + /* Not open operation interface for cmd */ + FTachoSetOverLimit(tacho, TACHO_MAX); + FTachoSetUnderLimit(tacho, TACHO_MIN); + } + + return (&os_timer_tacho[id]); +} + +/** + * @name: FFreeRTOSTachoGetRPM + * @msg: get tacho RPM + * @return {*} + * @param {FFreeRTOSTimerTacho} *os_tacho_p + * @param {u32} *rpm + */ +FError FFreeRTOSTachoGetRPM(FFreeRTOSTimerTacho *os_tacho_p, u32 *rpm) +{ + FASSERT(NULL != os_tacho_p->locker); + FError ret = FREERTOS_TIMER_TACHO_SUCCESS; + + FTimerTachoCtrl *tacho = &os_tacho_p->ctrl; + + + ret = FTachoGetFanRPM(tacho, rpm); + if (ret != FREERTOS_TIMER_TACHO_SUCCESS) + { + FTIMER_OS_ERROR("Tachometer get error,please check init."); + return ret; + } + return ret; +} + +/** + * @name: FFreeRTOSTachoGetCNT + * @msg: get capture value + * @return {*} + * @param {FFreeRTOSTimerTacho} *os_tacho_p + */ +u32 FFreeRTOSTachoGetCNT(FFreeRTOSTimerTacho *os_tacho_p) +{ + FASSERT(NULL != os_tacho_p->locker); + + FTimerTachoCtrl *tacho = &os_tacho_p->ctrl; + + return FTachoGetCaptureCnt(tacho); +} + +/** + * @name: FFreeRTOSTachoDeinit + * @msg: deinit tacho or capture + * @return {*} + * @param {FFreeRTOSTimerTacho} *os_tacho_p + */ +void FFreeRTOSTachoDeinit(FFreeRTOSTimerTacho *os_tacho_p) +{ + FASSERT(NULL != os_tacho_p->locker); + + FTachoDeInit(&os_tacho_p->ctrl); + vSemaphoreDelete(os_tacho_p->locker); + memset(os_tacho_p, 0, sizeof(*os_tacho_p)); + return; +} + diff --git a/third-party/sdmmc-1.0/port/fsdio/sdmmc_port.c b/drivers/timer/ftimer_tacho_os.h similarity index 31% rename from third-party/sdmmc-1.0/port/fsdio/sdmmc_port.c rename to drivers/timer/ftimer_tacho_os.h index 82056595..6414b99f 100644 --- a/third-party/sdmmc-1.0/port/fsdio/sdmmc_port.c +++ b/drivers/timer/ftimer_tacho_os.h @@ -1,117 +1,86 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * - * FilePath: sdmmc_port.c - * Date: 2022-07-25 09:58:29 - * LastEditTime: 2022-07-25 09:58:30 - * Description:  This files is for - * - * Modify History: + * See the Phytium Public License for more details. + * + * + * FilePath: ftimer_tacho_os.h + * Date: 2022-08-23 17:20:58 + * LastEditTime: 2022-08-23 17:20:58 + * Description:  This file is for providing function related definitions of timer tacho driver used in FreeRTOS. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 liushengming 2022/08/24 init */ +#ifndef FTIMER_TACHO_OS_H +#define FTIMER_TACHO_OS_H /***************************** Include Files *********************************/ #include #include #include -#include "fmemory_pool.h" #include "fparameters.h" - -#include "sdmmc_port.h" -#include "sdmmc_cmd.h" -#include "sdmmc_defs.h" - +#include "ftimer_tacho.h" +#include "ftimer_tacho_hw.h" +#include "ftypes.h" /************************** Constant Definitions *****************************/ -#define SDMMC_ALIGNMENT 32U -#define SDMMC_DMA_BUF_SIZE 512U - -/* reserve more bytes for 64-bit */ -#if defined(__aarch64__) -#define SDMMC_MEM_BUF_SIZE 8192U * 2U -#else -#define SDMMC_MEM_BUF_SIZE 8192U +#ifdef __cplusplus +extern "C" +{ #endif -/**************************** Type Definitions *******************************/ + +/*Error code from standalone tacho driver*/ +#define FREERTOS_TIMER_TACHO_SUCCESS FTIMER_TACHO_SUCCESS +#define FREERTOS_TIMER_TACHO_INVAILD_PARAM_ERROR FTIMER_TACHO_ERR_INVAL_PARM +#define FREERTOS_TIMER_TACHO_NOT_READY_ERROR FTIMER_TACHO_ERR_NOT_READY +#define FREERTOS_TIMER_TACHO_TIMEOUT_ERROR FTIMER_TACHO_ERR_INIT_FAILED +#define FREERTOS_TIMER_TACHO_NOT_SUPPORT_ERROR FTIMER_TACHO_ERR_NOT_SUPPORT +#define FREERTOS_TIMER_TACHO_IS_READ_ERROR FTIMER_TACHO_ERR_IS_READ +#define FREERTOS_TIMER_TACHO_ABORT_ERROR FTIMER_TACHO_ERR_ABORT +#define FREERTOS_TIMER_TACHO_FAILED_ERROR FTIMER_TACHO_ERR_FAILED + +/*Error code depend on OS standard*/ +#define FREERTOS_TIMER_TACHO_TASK_ERROR FT_CODE_ERR(ErrModPort, ErrBspTimer, 0x1) +#define FREERTOS_TIMER_TACHO_MESG_ERROR FT_CODE_ERR(ErrModPort, ErrBspTimer, 0x2) +#define FREERTOS_TIMER_TACHO_TIME_ERROR FT_CODE_ERR(ErrModPort, ErrBspTimer, 0x3) +#define FREERTOS_TIMER_TACHO_MEMY_ERROR FT_CODE_ERR(ErrModPort, ErrBspTimer, 0x4) +#define FREERTOS_TIMER_TACHO_SEMA_ERROR FT_CODE_ERR(ErrModPort, ErrBspTimer, 0x5) /************************** Variable Definitions *****************************/ -static FMemp sdmmc_mem_pool; -static u8 mem_buf[SDMMC_MEM_BUF_SIZE]; +typedef struct +{ + FTimerTachoCtrl ctrl; + SemaphoreHandle_t locker; +} FFreeRTOSTimerTacho; + /***************** Macros (Inline Functions) Definitions *********************/ /************************** Function Prototypes ******************************/ +/*timer*/ +FFreeRTOSTimerTacho *FFreeRTOSTimerInit(u32 id, boolean timer_mode, u64 times); +FError FFreeRTOSTimerStart(FFreeRTOSTimerTacho *os_timer_p); +FError FFreeRTOSTimerStop(FFreeRTOSTimerTacho *os_timer_p); +void FFreeRTOSTimerDeinit(FFreeRTOSTimerTacho *os_timer_p); +void FFreeRTOSTimerDebug(FFreeRTOSTimerTacho *os_timer_p); +/*tacho*/ +FFreeRTOSTimerTacho *FFreeRTOSTachoInit(u32 id, boolean tacho_mode); +FError FFreeRTOSTachoGetRPM(FFreeRTOSTimerTacho *os_timer_p, u32 *rpm); +u32 FFreeRTOSTachoGetCNT(FFreeRTOSTimerTacho *os_timer_p); +void FFreeRTOSTachoDeinit(FFreeRTOSTimerTacho *os_timer_p); /*****************************************************************************/ -sdmmc_err_t sdmmc_port_init(void) -{ - FError err = FT_SUCCESS; - if (FT_COMPONENT_IS_READY == sdmmc_mem_pool.is_ready) - return err; - - taskENTER_CRITICAL(); /* no schedule when init */ - - err = FMempInit(&sdmmc_mem_pool, mem_buf, mem_buf + sizeof(mem_buf)); /* init memory pool */; - - taskEXIT_CRITICAL(); /* allow schedule after init */ - - return (FT_SUCCESS == err) ? SDMMC_OK : SDMMC_FAIL; -} - -sdmmc_err_t sdmmc_port_deinit(void) -{ - FError err = FT_SUCCESS; - if (FT_COMPONENT_IS_READY != sdmmc_mem_pool.is_ready) - return err; - - taskENTER_CRITICAL(); /* no schedule when deinit */ - - FMempDeinit(&sdmmc_mem_pool); /* remove memroy pool */ - - taskEXIT_CRITICAL(); /* allow schedule after deinit */ - - return (FT_SUCCESS == err) ? SDMMC_OK : SDMMC_FAIL; -} - -void *sdmmc_port_align_malloc(size_t want_size, boolean dma_capable) -{ - void *pv = NULL; - FASSERT(FT_COMPONENT_IS_READY == sdmmc_mem_pool.is_ready); - - if (dma_capable) - { - if (want_size < SDMMC_DMA_BUF_SIZE) /* if allocated memory is needed by DMA, allocate at leaset 512 bytes */ - { - want_size = SDMMC_DMA_BUF_SIZE; - } - else if (want_size % SDMMC_DMA_BUF_SIZE) /* round up size to 512 */ - { - want_size = roundup(want_size, (size_t)SDMMC_DMA_BUF_SIZE); - } - } - - pv = FMempMallocAlign(&sdmmc_mem_pool, want_size, SDMMC_ALIGNMENT); /* allocate aligned memory */ - return pv; -} - -void sdmmc_port_align_free(void *pv) -{ - FASSERT(FT_COMPONENT_IS_READY == sdmmc_mem_pool.is_ready); - - FMempFree(&sdmmc_mem_pool, pv); +#ifdef __cplusplus } +#endif -boolean sdmmc_port_is_aligned_memory(const void *buf_p) -{ - return ((uintptr)buf_p % SDMMC_ALIGNMENT == 0); -} \ No newline at end of file +#endif \ No newline at end of file diff --git a/drivers/wdt/fwdt_os.c b/drivers/wdt/fwdt_os.c index 906d7f6e..b17ac8cc 100644 --- a/drivers/wdt/fwdt_os.c +++ b/drivers/wdt/fwdt_os.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: fwdt_os.c * Date: 2022-07-14 13:42:19 * LastEditTime: 2022-07-25 16:59:51 - * Description:  This file is for - * - * Modify History: + * Description:  This file is for required function implementations of wdt driver used in FreeRTOS. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/08/09 first commit */ #include #include @@ -40,7 +41,7 @@ #define FWDT_INFO(format, ...) FT_DEBUG_PRINT_I(FWDT_DEBUG_TAG, format, ##__VA_ARGS__) #define FWDT_DEBUG(format, ...) FT_DEBUG_PRINT_D(FWDT_DEBUG_TAG, format, ##__VA_ARGS__) -static FFreeRTOSWdt os_wdt[FWDT_INSTANCE_NUM] = {0}; +static FFreeRTOSWdt os_wdt[FWDT_NUM] = {0}; /** * @name: FFreeRTOSWdtInit @@ -50,7 +51,7 @@ static FFreeRTOSWdt os_wdt[FWDT_INSTANCE_NUM] = {0}; */ FFreeRTOSWdt *FFreeRTOSWdtInit(u32 instance_id) { - FASSERT(instance_id < FWDT_INSTANCE_NUM); + FASSERT(instance_id < FWDT_NUM); FASSERT(FT_COMPONENT_IS_READY != os_wdt[instance_id].wdt_ctrl.is_ready); FWdtConfig pconfig; @@ -59,7 +60,7 @@ FFreeRTOSWdt *FFreeRTOSWdtInit(u32 instance_id) FASSERT(FWdtCfgInitialize(&os_wdt[instance_id].wdt_ctrl, &pconfig) == FT_SUCCESS); FASSERT((os_wdt[instance_id].wdt_semaphore = xSemaphoreCreateMutex()) != NULL); - + return (&os_wdt[instance_id]); } @@ -73,11 +74,11 @@ FError FFreeRTOSWdtDeinit(FFreeRTOSWdt *os_wdt_p) { FASSERT(os_wdt_p); FASSERT(os_wdt_p->wdt_semaphore != NULL); - + FWdtDeInitialize(&os_wdt_p->wdt_ctrl); vSemaphoreDelete(os_wdt_p->wdt_semaphore); memset(os_wdt_p, 0, sizeof(*os_wdt_p)); - + return FWDT_SUCCESS; } @@ -101,40 +102,40 @@ FError FFreeRTOSWdtControl(FFreeRTOSWdt *os_wdt_p, int cmd, void *args) /* New contrl can be performed only after current one is finished */ if (pdFALSE == xSemaphoreTake(os_wdt_p->wdt_semaphore, portMAX_DELAY)) { - FWDT_ERROR("Wdt xSemaphoreTake failed\r\n"); + FWDT_ERROR("Wdt xSemaphoreTake failed."); /* We could not take the semaphore, exit with 0 data received */ return FREERTOS_WDT_SEM_ERROR; } - - switch(cmd) + + switch (cmd) { case FREERTOS_WDT_CTRL_GET_TIMEOUT: - *((u32*)args) = os_wdt_p->timeout_value; + *((u32 *)args) = os_wdt_p->timeout_value; break; case FREERTOS_WDT_CTRL_SET_TIMEOUT: - os_wdt_p->timeout_value = *((u32*)args); - if(os_wdt_p->timeout_value >= FWDT_MAX_TIMEOUT) + os_wdt_p->timeout_value = *((u32 *)args); + if (os_wdt_p->timeout_value >= FWDT_MAX_TIMEOUT) { goto control_exit; } ret = FWdtSetTimeout(pctrl, os_wdt_p->timeout_value); if (FWDT_SUCCESS != ret) { - FWDT_ERROR("FFreeRTOSWdtControl FWdtSetTimeout failed\n"); + FWDT_ERROR("FFreeRTOSWdtControl FWdtSetTimeout failed."); goto control_exit; } break; - + case FREERTOS_WDT_CTRL_GET_TIMELEFT: - *((u32*)args) = FWdtGetTimeleft(pctrl); + *((u32 *)args) = FWdtGetTimeleft(pctrl); break; case FREERTOS_WDT_CTRL_KEEPALIVE: ret = FWdtRefresh(pctrl); if (FWDT_SUCCESS != ret) { - FWDT_ERROR("FFreeRTOSWdtControl FWdtRefresh failed\n"); + FWDT_ERROR("FFreeRTOSWdtControl FWdtRefresh failed."); goto control_exit; } break; @@ -143,22 +144,22 @@ FError FFreeRTOSWdtControl(FFreeRTOSWdt *os_wdt_p, int cmd, void *args) ret = FWdtStart(pctrl); if (FWDT_SUCCESS != ret) { - FWDT_ERROR("FFreeRTOSWdtControl FWdtStart failed\n"); + FWDT_ERROR("FFreeRTOSWdtControl FWdtStart failed."); goto control_exit; } break; - + case FREERTOS_WDT_CTRL_STOP: ret = FWdtStop(pctrl); if (FWDT_SUCCESS != ret) { - FWDT_ERROR("FFreeRTOSWdtControl FWdtStop failed\n"); + FWDT_ERROR("FFreeRTOSWdtControl FWdtStop failed."); goto control_exit; } break; default: - FWDT_ERROR("control cmd is invalid \r\n"); + FWDT_ERROR("Control cmd is invalid."); break; } @@ -168,7 +169,7 @@ control_exit: if (pdFALSE == xSemaphoreGive(os_wdt_p->wdt_semaphore)) { /* We could not post the semaphore, exit with error */ - FWDT_ERROR("Wdt xSemaphoreGive failed\r\n"); + FWDT_ERROR("Wdt xSemaphoreGive failed."); return FREERTOS_WDT_SEM_ERROR; } diff --git a/drivers/wdt/fwdt_os.h b/drivers/wdt/fwdt_os.h index 826d4ba6..dd281199 100644 --- a/drivers/wdt/fwdt_os.h +++ b/drivers/wdt/fwdt_os.h @@ -1,28 +1,29 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: fwdt_os.h * Date: 2022-02-24 13:42:19 * LastEditTime: 2022-03-21 16:59:58 - * Description:  This file is for - * - * Modify History: + * Description:  This file is for providing function related definitions of wdt driver used in FreeRTOS. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/08/09 first commit */ -#ifndef DRIVERS_FWDT_OS_H -#define DRIVERS_FWDT_OS_H +#ifndef FWDT_OS_H +#define FWDT_OS_H #include #include @@ -30,6 +31,11 @@ #include "fwdt.h" #include "ftypes.h" +#ifdef __cplusplus +extern "C" +{ +#endif + /* freertos wdt error */ #define FREERTOS_WDT_SEM_ERROR FT_CODE_ERR(ErrModBsp, ErrBspWdt, 10) @@ -59,4 +65,8 @@ FError FFreeRTOSWdtDeinit(FFreeRTOSWdt *os_wdt_p); /* control freertos wdt instance */ FError FFreeRTOSWdtControl(FFreeRTOSWdt *os_wdt_p, int cmd, void *args); +#ifdef __cplusplus +} +#endif + #endif // ! diff --git a/example/amp/openamp/core0/configs/d2000_aarch32_eg_configs b/example/amp/openamp/core0/configs/d2000_aarch32_eg_configs index f834bd72..9d801308 100644 --- a/example/amp/openamp/core0/configs/d2000_aarch32_eg_configs +++ b/example/amp/openamp/core0/configs/d2000_aarch32_eg_configs @@ -72,6 +72,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_CAN is not set # CONFIG_USE_I2C is not set # CONFIG_USE_TIMER is not set +# CONFIG_USE_MIO is not set # CONFIG_USE_SDMMC is not set # CONFIG_USE_PCIE is not set # CONFIG_USE_WDT is not set @@ -83,6 +84,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -127,6 +129,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + # CONFIG_OUTPUT_BINARY is not set # end of Compiler Options # end of Building Option @@ -136,17 +147,94 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # -# Freertos Drivers +# Freertos Uart Drivers # CONFIG_FREERTOS_USE_UART=y -# end of Freertos Drivers +# end of Freertos Uart Drivers + +# +# Freertos Pwm Drivers +# +# CONFIG_FREERTOS_USE_PWM is not set +# end of Freertos Pwm Drivers + +# +# Freertos Qspi Drivers +# +# CONFIG_FREERTOS_USE_QSPI is not set +# end of Freertos Qspi Drivers + +# +# Freertos Wdt Drivers +# +# CONFIG_FREERTOS_USE_WDT is not set +# end of Freertos Wdt Drivers + +# +# Freertos Eth Drivers +# +# CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set +# end of Freertos Eth Drivers + +# +# Freertos Gpio Drivers +# +# CONFIG_FREERTOS_USE_GPIO is not set +# end of Freertos Gpio Drivers + +# +# Freertos Spim Drivers +# +# CONFIG_FREERTOS_USE_FSPIM is not set +# end of Freertos Spim Drivers + +# +# Freertos DMA Drivers +# +# CONFIG_FREERTOS_USE_FDDMA is not set +# CONFIG_FREERTOS_USE_FGDMA is not set +# end of Freertos DMA Drivers + +# +# Freertos Adc Drivers +# +# CONFIG_FREERTOS_USE_ADC is not set +# end of Freertos Adc Drivers + +# +# Freertos Can Drivers +# +# CONFIG_FREERTOS_USE_CAN is not set +# end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y +# CONFIG_USE_FATFS_0_1_4 is not set +# CONFIG_USE_SFUD is not set +# CONFIG_USE_SPIFFS is not set CONFIG_USE_AMP=y CONFIG_USE_LIBMETAL=y @@ -182,4 +270,31 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_DEFAULT_LETTER_SHELL_USE_UART0 is not set # CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set # end of Letter Shell Configuration -# end of FreeRTOS Setting + +# CONFIG_USE_TLSF is not set +# CONFIG_USE_SDMMC_CMD is not set +# CONFIG_USE_CHERRY_USB is not set +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/amp/openamp/core0/configs/d2000_aarch64_eg_configs b/example/amp/openamp/core0/configs/d2000_aarch64_eg_configs index c8b7f68b..773eab98 100644 --- a/example/amp/openamp/core0/configs/d2000_aarch64_eg_configs +++ b/example/amp/openamp/core0/configs/d2000_aarch64_eg_configs @@ -72,6 +72,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_CAN is not set # CONFIG_USE_I2C is not set # CONFIG_USE_TIMER is not set +# CONFIG_USE_MIO is not set # CONFIG_USE_SDMMC is not set # CONFIG_USE_PCIE is not set # CONFIG_USE_WDT is not set @@ -83,6 +84,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -123,6 +125,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + # CONFIG_OUTPUT_BINARY is not set # end of Compiler Options # end of Building Option @@ -132,17 +143,94 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # -# Freertos Drivers +# Freertos Uart Drivers # CONFIG_FREERTOS_USE_UART=y -# end of Freertos Drivers +# end of Freertos Uart Drivers + +# +# Freertos Pwm Drivers +# +# CONFIG_FREERTOS_USE_PWM is not set +# end of Freertos Pwm Drivers + +# +# Freertos Qspi Drivers +# +# CONFIG_FREERTOS_USE_QSPI is not set +# end of Freertos Qspi Drivers + +# +# Freertos Wdt Drivers +# +# CONFIG_FREERTOS_USE_WDT is not set +# end of Freertos Wdt Drivers + +# +# Freertos Eth Drivers +# +# CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set +# end of Freertos Eth Drivers + +# +# Freertos Gpio Drivers +# +# CONFIG_FREERTOS_USE_GPIO is not set +# end of Freertos Gpio Drivers + +# +# Freertos Spim Drivers +# +# CONFIG_FREERTOS_USE_FSPIM is not set +# end of Freertos Spim Drivers + +# +# Freertos DMA Drivers +# +# CONFIG_FREERTOS_USE_FDDMA is not set +# CONFIG_FREERTOS_USE_FGDMA is not set +# end of Freertos DMA Drivers + +# +# Freertos Adc Drivers +# +# CONFIG_FREERTOS_USE_ADC is not set +# end of Freertos Adc Drivers + +# +# Freertos Can Drivers +# +# CONFIG_FREERTOS_USE_CAN is not set +# end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y +# CONFIG_USE_FATFS_0_1_4 is not set +# CONFIG_USE_SFUD is not set +# CONFIG_USE_SPIFFS is not set CONFIG_USE_AMP=y CONFIG_USE_LIBMETAL=y @@ -178,4 +266,31 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_DEFAULT_LETTER_SHELL_USE_UART0 is not set # CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set # end of Letter Shell Configuration -# end of FreeRTOS Setting + +# CONFIG_USE_TLSF is not set +# CONFIG_USE_SDMMC_CMD is not set +# CONFIG_USE_CHERRY_USB is not set +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/amp/openamp/core0/configs/ft2004_aarch32_eg_configs b/example/amp/openamp/core0/configs/ft2004_aarch32_eg_configs index 43563802..5c260bfe 100644 --- a/example/amp/openamp/core0/configs/ft2004_aarch32_eg_configs +++ b/example/amp/openamp/core0/configs/ft2004_aarch32_eg_configs @@ -72,6 +72,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_CAN is not set # CONFIG_USE_I2C is not set # CONFIG_USE_TIMER is not set +# CONFIG_USE_MIO is not set # CONFIG_USE_SDMMC is not set # CONFIG_USE_PCIE is not set # CONFIG_USE_WDT is not set @@ -83,6 +84,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -127,6 +129,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + # CONFIG_OUTPUT_BINARY is not set # end of Compiler Options # end of Building Option @@ -136,17 +147,94 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # -# Freertos Drivers +# Freertos Uart Drivers # CONFIG_FREERTOS_USE_UART=y -# end of Freertos Drivers +# end of Freertos Uart Drivers + +# +# Freertos Pwm Drivers +# +# CONFIG_FREERTOS_USE_PWM is not set +# end of Freertos Pwm Drivers + +# +# Freertos Qspi Drivers +# +# CONFIG_FREERTOS_USE_QSPI is not set +# end of Freertos Qspi Drivers + +# +# Freertos Wdt Drivers +# +# CONFIG_FREERTOS_USE_WDT is not set +# end of Freertos Wdt Drivers + +# +# Freertos Eth Drivers +# +# CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set +# end of Freertos Eth Drivers + +# +# Freertos Gpio Drivers +# +# CONFIG_FREERTOS_USE_GPIO is not set +# end of Freertos Gpio Drivers + +# +# Freertos Spim Drivers +# +# CONFIG_FREERTOS_USE_FSPIM is not set +# end of Freertos Spim Drivers + +# +# Freertos DMA Drivers +# +# CONFIG_FREERTOS_USE_FDDMA is not set +# CONFIG_FREERTOS_USE_FGDMA is not set +# end of Freertos DMA Drivers + +# +# Freertos Adc Drivers +# +# CONFIG_FREERTOS_USE_ADC is not set +# end of Freertos Adc Drivers + +# +# Freertos Can Drivers +# +# CONFIG_FREERTOS_USE_CAN is not set +# end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y +# CONFIG_USE_FATFS_0_1_4 is not set +# CONFIG_USE_SFUD is not set +# CONFIG_USE_SPIFFS is not set CONFIG_USE_AMP=y CONFIG_USE_LIBMETAL=y @@ -182,4 +270,31 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_DEFAULT_LETTER_SHELL_USE_UART0 is not set # CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set # end of Letter Shell Configuration -# end of FreeRTOS Setting + +# CONFIG_USE_TLSF is not set +# CONFIG_USE_SDMMC_CMD is not set +# CONFIG_USE_CHERRY_USB is not set +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/amp/openamp/core0/configs/ft2004_aarch64_eg_configs b/example/amp/openamp/core0/configs/ft2004_aarch64_eg_configs index 92d97b67..86647827 100644 --- a/example/amp/openamp/core0/configs/ft2004_aarch64_eg_configs +++ b/example/amp/openamp/core0/configs/ft2004_aarch64_eg_configs @@ -72,6 +72,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_CAN is not set # CONFIG_USE_I2C is not set # CONFIG_USE_TIMER is not set +# CONFIG_USE_MIO is not set # CONFIG_USE_SDMMC is not set # CONFIG_USE_PCIE is not set # CONFIG_USE_WDT is not set @@ -83,6 +84,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -123,6 +125,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + # CONFIG_OUTPUT_BINARY is not set # end of Compiler Options # end of Building Option @@ -132,17 +143,94 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # -# Freertos Drivers +# Freertos Uart Drivers # CONFIG_FREERTOS_USE_UART=y -# end of Freertos Drivers +# end of Freertos Uart Drivers + +# +# Freertos Pwm Drivers +# +# CONFIG_FREERTOS_USE_PWM is not set +# end of Freertos Pwm Drivers + +# +# Freertos Qspi Drivers +# +# CONFIG_FREERTOS_USE_QSPI is not set +# end of Freertos Qspi Drivers + +# +# Freertos Wdt Drivers +# +# CONFIG_FREERTOS_USE_WDT is not set +# end of Freertos Wdt Drivers + +# +# Freertos Eth Drivers +# +# CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set +# end of Freertos Eth Drivers + +# +# Freertos Gpio Drivers +# +# CONFIG_FREERTOS_USE_GPIO is not set +# end of Freertos Gpio Drivers + +# +# Freertos Spim Drivers +# +# CONFIG_FREERTOS_USE_FSPIM is not set +# end of Freertos Spim Drivers + +# +# Freertos DMA Drivers +# +# CONFIG_FREERTOS_USE_FDDMA is not set +# CONFIG_FREERTOS_USE_FGDMA is not set +# end of Freertos DMA Drivers + +# +# Freertos Adc Drivers +# +# CONFIG_FREERTOS_USE_ADC is not set +# end of Freertos Adc Drivers + +# +# Freertos Can Drivers +# +# CONFIG_FREERTOS_USE_CAN is not set +# end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y +# CONFIG_USE_FATFS_0_1_4 is not set +# CONFIG_USE_SFUD is not set +# CONFIG_USE_SPIFFS is not set CONFIG_USE_AMP=y CONFIG_USE_LIBMETAL=y @@ -178,4 +266,31 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_DEFAULT_LETTER_SHELL_USE_UART0 is not set # CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set # end of Letter Shell Configuration -# end of FreeRTOS Setting + +# CONFIG_USE_TLSF is not set +# CONFIG_USE_SDMMC_CMD is not set +# CONFIG_USE_CHERRY_USB is not set +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/amp/openamp/core0/main.c b/example/amp/openamp/core0/main.c index 54f9f899..1428fc6b 100644 --- a/example/amp/openamp/core0/main.c +++ b/example/amp/openamp/core0/main.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: main.c * Date: 2022-02-24 16:56:46 * LastEditTime: 2022-03-21 17:00:56 - * Description:  This file is for - * - * Modify History: + * Description:  This file is for AMP example that running rpmsg_echo_task and open scheduler + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/03/25 first commit */ @@ -46,14 +47,16 @@ int main(void) BaseType_t ret; ret = LSUserShellTask() ; - if(ret != pdPASS) + if (ret != pdPASS) + { goto FAIL_EXIT; + } - vTaskStartScheduler(); /* 启动任务,开启调度 */ + vTaskStartScheduler(); /* 启动任务,开启调度 */ while (1); /* 正常不会执行到这里 */ FAIL_EXIT: - printf("failed 0x%x \r\n", ret); + printf("Failed 0x%x \r\n", ret); return 0; } @@ -65,14 +68,14 @@ extern int rpmsg_echo_task(int argc, char *argv[]); int main(void) { BaseType_t ret; - f_printk("freertos %s ,%s \r\n",__DATE__, __TIME__) ; + f_printk("Freertos %s ,%s \r\n", __DATE__, __TIME__) ; rpmsg_echo_task(0, NULL); vTaskStartScheduler(); /* 启动任务,开启调度 */ while (1); /* 正常不会执行到这里 */ FAIL_EXIT: - printf("failed 0x%x \r\n", ret); + printf("Failed 0x%x. \r\n", ret); return 0; } diff --git a/example/amp/openamp/core0/rpmsg-echo_os.c b/example/amp/openamp/core0/rpmsg-echo_os.c index 6888eba3..ae8e7624 100644 --- a/example/amp/openamp/core0/rpmsg-echo_os.c +++ b/example/amp/openamp/core0/rpmsg-echo_os.c @@ -1,27 +1,6 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. - * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * - * FilePath: rpmsg-echo_os.c - * Date: 2022-02-25 09:12:07 - * LastEditTime: 2022-02-25 09:12:19 - * Description:  This file is for - * - * Modify History: - * Ver   Who        Date         Changes - * ----- ------     --------    -------------------------------------- + * SPDX-License-Identifier: BSD-3-Clause */ - - /* This is a sample demonstration application that showcases usage of rpmsg This application is meant to run on the remote CPU running baremetal code. This application echoes back data that was sent to it by the master core. */ @@ -45,18 +24,10 @@ This application echoes back data that was sent to it by the master core. */ #include "fpsci.h" -/************************** Constant Definitions *****************************/ - -/**************************** Type Definitions *******************************/ - -/************************** Variable Definitions *****************************/ +#define SHUTDOWN_MSG 0xEF56A55A -/***************** Macros (Inline Functions) Definitions *********************/ - -#define SHUTDOWN_MSG 0xEF56A55A - -#define LPRINTF(format, ...) printf(format, ##__VA_ARGS__) -#define LPERROR(format, ...) LPRINTF("ERROR: " format, ##__VA_ARGS__) +#define LPRINTF(format, ...) printf(format, ##__VA_ARGS__) +#define LPERROR(format, ...) LPRINTF("ERROR: " format, ##__VA_ARGS__) static struct rpmsg_endpoint lept; static int shutdown_req = 0; @@ -68,31 +39,34 @@ static int shutdown_req = 0; *-----------------------------------------------------------------------------*/ static int rpmsg_endpoint_cb(struct rpmsg_endpoint *ept, void *data, size_t len, uint32_t src, void *priv) { - (void)priv; - (void)src; - /* On reception of a shutdown we signal the application to terminate */ - if ((*(unsigned int *)data) == SHUTDOWN_MSG) { - LPRINTF("shutdown message is received.\r\n"); - shutdown_req = 1; - return RPMSG_SUCCESS; - } + (void)priv; + (void)src; + /* On reception of a shutdown we signal the application to terminate */ + if ((*(unsigned int *)data) == SHUTDOWN_MSG) + { + LPRINTF("Shutdown message is received.\r\n"); + shutdown_req = 1; + return RPMSG_SUCCESS; + } #ifdef CONFIG_MEM_NORMAL - FCacheDCacheInvalidateRange((intptr)data, len); + FCacheDCacheInvalidateRange((intptr)data, len); #endif - - /* Send data back to master */ - if (rpmsg_send(ept, data, len) < 0) - LPERROR("rpmsg_send failed\r\n"); - return RPMSG_SUCCESS; + /* Send data back to master */ + if (rpmsg_send(ept, data, len) < 0) + { + LPERROR("Rpmsg_send failed.\r\n"); + } + + return RPMSG_SUCCESS; } static void rpmsg_service_unbind(struct rpmsg_endpoint *ept) { - (void)ept; - LPRINTF("unexpected Remote endpoint destroy\r\n"); - shutdown_req = 1; + (void)ept; + LPRINTF("Unexpected Remote endpoint destroy.\r\n"); + shutdown_req = 1; } /*-----------------------------------------------------------------------------* @@ -100,30 +74,33 @@ static void rpmsg_service_unbind(struct rpmsg_endpoint *ept) *-----------------------------------------------------------------------------*/ int app(struct rpmsg_device *rdev, void *priv) { - int ret; + int ret; - /* Initialize RPMSG framework */ - LPRINTF("Try to create rpmsg endpoint.\r\n"); + /* Initialize RPMSG framework */ + LPRINTF("Try to create rpmsg endpoint.\r\n"); - ret = rpmsg_create_ept(&lept, rdev, RPMSG_SERVICE_NAME, 0, RPMSG_ADDR_ANY, rpmsg_endpoint_cb, rpmsg_service_unbind); - if (ret) { - LPERROR("Failed to create endpoint. %d \r\n", ret); - return -1; - } + ret = rpmsg_create_ept(&lept, rdev, RPMSG_SERVICE_NAME, 0, RPMSG_ADDR_ANY, rpmsg_endpoint_cb, rpmsg_service_unbind); + if (ret) + { + LPERROR("Failed to create endpoint. %d \r\n", ret); + return -1; + } - LPRINTF("Successfully created rpmsg endpoint.\r\n"); + LPRINTF("Successfully created rpmsg endpoint.\r\n"); - while (1) - { - platform_poll(priv); + while (1) + { + platform_poll(priv); /* we got a shutdown request, exit */ if (shutdown_req) - break; - } + { + break; + } + } - rpmsg_destroy_ept(&lept); + rpmsg_destroy_ept(&lept); - return 0; + return 0; } @@ -133,52 +110,58 @@ int app(struct rpmsg_device *rdev, void *priv) *-----------------------------------------------------------------------------*/ int rpmsg_echo(int argc, char *argv[]) { - void *platform; - struct rpmsg_device *rpdev; - int ret; - - LPRINTF("openamp lib version: %s (", openamp_version()); - LPRINTF("Major: %d, ", openamp_version_major()); - LPRINTF("Minor: %d, ", openamp_version_minor()); - LPRINTF("Patch: %d)\r\n", openamp_version_patch()); - - LPRINTF("libmetal lib version: %s (", metal_ver()); - LPRINTF("Major: %d, ", metal_ver_major()); - LPRINTF("Minor: %d, ", metal_ver_minor()); - LPRINTF("Patch: %d)\r\n", metal_ver_patch()); - - LPRINTF("Starting application...\r\n"); - - /* Initialize platform */ - ret = platform_init(argc, argv, &platform); - if (ret) { - LPERROR("Failed to initialize platform.\r\n"); - ret = -1; - } else { - #ifdef CONFIG_DEBUG_CODE - LPERROR("CONFIG_TARGET_CPU_ID is %x \r\n",CONFIG_TARGET_CPU_ID); - PsciCpuOn(CONFIG_TARGET_CPU_ID,(uintptr_t)0xe0100000) ; - #endif - rpdev = platform_create_rpmsg_vdev(platform, 0, VIRTIO_DEV_SLAVE, NULL, NULL); - if (!rpdev) { - LPERROR("Failed to create rpmsg virtio device.\r\n"); - ret = -1; - } else { - app(rpdev, platform); - - platform_release_rpmsg_vdev(rpdev, platform); - ret = 0; - } - } - - LPRINTF("Stopping application...\r\n"); - platform_cleanup(platform); + void *platform; + struct rpmsg_device *rpdev; + int ret; + + LPRINTF("openamp lib version: %s (", openamp_version()); + LPRINTF("Major: %d, ", openamp_version_major()); + LPRINTF("Minor: %d, ", openamp_version_minor()); + LPRINTF("Patch: %d).\r\n", openamp_version_patch()); + + LPRINTF("libmetal lib version: %s (", metal_ver()); + LPRINTF("Major: %d, ", metal_ver_major()); + LPRINTF("Minor: %d, ", metal_ver_minor()); + LPRINTF("Patch: %d).\r\n", metal_ver_patch()); + + LPRINTF("Starting application...\r\n"); + + /* Initialize platform */ + ret = platform_init(argc, argv, &platform); + if (ret) + { + LPERROR("Failed to initialize platform.\r\n"); + ret = -1; + } + else + { +#ifdef CONFIG_DEBUG_CODE + LPERROR("CONFIG_TARGET_CPU_ID is %x \r\n", CONFIG_TARGET_CPU_ID); + PsciCpuOn(CONFIG_TARGET_CPU_ID, (uintptr_t)0xe0100000) ; +#endif + rpdev = platform_create_rpmsg_vdev(platform, 0, VIRTIO_DEV_SLAVE, NULL, NULL); + if (!rpdev) + { + LPERROR("Failed to create rpmsg virtio device.\r\n"); + ret = -1; + } + else + { + app(rpdev, platform); + + platform_release_rpmsg_vdev(rpdev, platform); + ret = 0; + } + } + + LPRINTF("Stopping application...\r\n"); + platform_cleanup(platform); return ret; } -void RpmsgEchoTask( void * args ) +void RpmsgEchoTask(void *args) { rpmsg_echo(0, NULL); vTaskDelete(NULL); @@ -186,19 +169,19 @@ void RpmsgEchoTask( void * args ) int rpmsg_echo_task(int argc, char *argv[]) { - BaseType_t ret; - - ret = xTaskCreate((TaskFunction_t )RpmsgEchoTask, /* 任务入口函数 */ - (const char* )"RpmsgEchoTask",/* 任务名字 */ - (uint16_t )4096, /* 任务栈大小 */ - (void* )NULL,/* 任务入口函数参数 */ - (UBaseType_t )1, /* 任务的优先级 */ - NULL); /* 任务控制块指针 */ - - if(ret != pdPASS) + BaseType_t ret; + + ret = xTaskCreate((TaskFunction_t)RpmsgEchoTask, /* 任务入口函数 */ + (const char *)"RpmsgEchoTask",/* 任务名字 */ + (uint16_t)4096, /* 任务栈大小 */ + (void *)NULL,/* 任务入口函数参数 */ + (UBaseType_t)1, /* 任务的优先级 */ + NULL); /* 任务控制块指针 */ + + if (ret != pdPASS) { // task_is_valid = 0; - LPERROR("Failed to create a rpmsg_echo task "); + LPERROR("Failed to create a rpmsg_echo task.\r\n"); return -1; } diff --git a/example/amp/openamp/core0/sdkconfig b/example/amp/openamp/core0/sdkconfig index 43563802..5c260bfe 100644 --- a/example/amp/openamp/core0/sdkconfig +++ b/example/amp/openamp/core0/sdkconfig @@ -72,6 +72,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_CAN is not set # CONFIG_USE_I2C is not set # CONFIG_USE_TIMER is not set +# CONFIG_USE_MIO is not set # CONFIG_USE_SDMMC is not set # CONFIG_USE_PCIE is not set # CONFIG_USE_WDT is not set @@ -83,6 +84,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -127,6 +129,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + # CONFIG_OUTPUT_BINARY is not set # end of Compiler Options # end of Building Option @@ -136,17 +147,94 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # -# Freertos Drivers +# Freertos Uart Drivers # CONFIG_FREERTOS_USE_UART=y -# end of Freertos Drivers +# end of Freertos Uart Drivers + +# +# Freertos Pwm Drivers +# +# CONFIG_FREERTOS_USE_PWM is not set +# end of Freertos Pwm Drivers + +# +# Freertos Qspi Drivers +# +# CONFIG_FREERTOS_USE_QSPI is not set +# end of Freertos Qspi Drivers + +# +# Freertos Wdt Drivers +# +# CONFIG_FREERTOS_USE_WDT is not set +# end of Freertos Wdt Drivers + +# +# Freertos Eth Drivers +# +# CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set +# end of Freertos Eth Drivers + +# +# Freertos Gpio Drivers +# +# CONFIG_FREERTOS_USE_GPIO is not set +# end of Freertos Gpio Drivers + +# +# Freertos Spim Drivers +# +# CONFIG_FREERTOS_USE_FSPIM is not set +# end of Freertos Spim Drivers + +# +# Freertos DMA Drivers +# +# CONFIG_FREERTOS_USE_FDDMA is not set +# CONFIG_FREERTOS_USE_FGDMA is not set +# end of Freertos DMA Drivers + +# +# Freertos Adc Drivers +# +# CONFIG_FREERTOS_USE_ADC is not set +# end of Freertos Adc Drivers + +# +# Freertos Can Drivers +# +# CONFIG_FREERTOS_USE_CAN is not set +# end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y +# CONFIG_USE_FATFS_0_1_4 is not set +# CONFIG_USE_SFUD is not set +# CONFIG_USE_SPIFFS is not set CONFIG_USE_AMP=y CONFIG_USE_LIBMETAL=y @@ -182,4 +270,31 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_DEFAULT_LETTER_SHELL_USE_UART0 is not set # CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set # end of Letter Shell Configuration -# end of FreeRTOS Setting + +# CONFIG_USE_TLSF is not set +# CONFIG_USE_SDMMC_CMD is not set +# CONFIG_USE_CHERRY_USB is not set +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/amp/openamp/core0/sdkconfig.h b/example/amp/openamp/core0/sdkconfig.h index 3734019c..3c8cd8c5 100644 --- a/example/amp/openamp/core0/sdkconfig.h +++ b/example/amp/openamp/core0/sdkconfig.h @@ -64,6 +64,7 @@ /* CONFIG_USE_CAN is not set */ /* CONFIG_USE_I2C is not set */ /* CONFIG_USE_TIMER is not set */ +/* CONFIG_USE_MIO is not set */ /* CONFIG_USE_SDMMC is not set */ /* CONFIG_USE_PCIE is not set */ /* CONFIG_USE_WDT is not set */ @@ -75,6 +76,7 @@ /* CONFIG_USE_ADC is not set */ /* CONFIG_USE_PWM is not set */ /* CONFIG_USE_IPC is not set */ +/* CONFIG_USE_MEDIA is not set */ /* end of Components Configuration */ #define CONFIG_USE_NEW_LIBC /* end of Standalone Setting */ @@ -115,22 +117,93 @@ /* Compiler Options */ +/* Cross-Compiler Setting */ + +#define CONFIG_GCC_OPTIMIZE_LEVEL 0 +/* CONFIG_USE_EXT_COMPILER is not set */ +/* CONFIG_USE_KLIN_SYS is not set */ +/* end of Cross-Compiler Setting */ /* CONFIG_OUTPUT_BINARY is not set */ /* end of Compiler Options */ /* end of Building Option */ /* Component Configuration */ -/* Freertos Drivers */ +/* Freertos Uart Drivers */ #define CONFIG_FREERTOS_USE_UART -/* end of Freertos Drivers */ +/* end of Freertos Uart Drivers */ + +/* Freertos Pwm Drivers */ + +/* CONFIG_FREERTOS_USE_PWM is not set */ +/* end of Freertos Pwm Drivers */ + +/* Freertos Qspi Drivers */ + +/* CONFIG_FREERTOS_USE_QSPI is not set */ +/* end of Freertos Qspi Drivers */ + +/* Freertos Wdt Drivers */ + +/* CONFIG_FREERTOS_USE_WDT is not set */ +/* end of Freertos Wdt Drivers */ + +/* Freertos Eth Drivers */ + +/* CONFIG_FREERTOS_USE_XMAC is not set */ +/* CONFIG_FREERTOS_USE_GMAC is not set */ +/* end of Freertos Eth Drivers */ + +/* Freertos Gpio Drivers */ + +/* CONFIG_FREERTOS_USE_GPIO is not set */ +/* end of Freertos Gpio Drivers */ + +/* Freertos Spim Drivers */ + +/* CONFIG_FREERTOS_USE_FSPIM is not set */ +/* end of Freertos Spim Drivers */ + +/* Freertos DMA Drivers */ + +/* CONFIG_FREERTOS_USE_FDDMA is not set */ +/* CONFIG_FREERTOS_USE_FGDMA is not set */ +/* end of Freertos DMA Drivers */ + +/* Freertos Adc Drivers */ + +/* CONFIG_FREERTOS_USE_ADC is not set */ +/* end of Freertos Adc Drivers */ + +/* Freertos Can Drivers */ + +/* CONFIG_FREERTOS_USE_CAN is not set */ +/* end of Freertos Can Drivers */ + +/* Freertos I2c Drivers */ + +/* CONFIG_FREERTOS_USE_I2C is not set */ +/* end of Freertos I2c Drivers */ + +/* Freertos Mio Drivers */ + +/* CONFIG_FREERTOS_USE_MIO is not set */ +/* end of Freertos Mio Drivers */ + +/* Freertos Timer Drivers */ + +/* CONFIG_FREERTOS_USE_TIMER is not set */ +/* end of Freertos Timer Drivers */ /* end of Component Configuration */ -/* FreeRTOS Setting */ +/* Third-Party Configuration */ /* CONFIG_USE_LWIP is not set */ #define CONFIG_USE_BACKTRACE +/* CONFIG_USE_FATFS_0_1_4 is not set */ +/* CONFIG_USE_SFUD is not set */ +/* CONFIG_USE_SPIFFS is not set */ #define CONFIG_USE_AMP #define CONFIG_USE_LIBMETAL @@ -162,6 +235,31 @@ /* CONFIG_DEFAULT_LETTER_SHELL_USE_UART0 is not set */ /* CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set */ /* end of Letter Shell Configuration */ -/* end of FreeRTOS Setting */ +/* CONFIG_USE_TLSF is not set */ +/* CONFIG_USE_SDMMC_CMD is not set */ +/* CONFIG_USE_CHERRY_USB is not set */ +/* end of Third-Party Configuration */ + +/* Kernel Configuration */ + +#define CONFIG_FREERTOS_OPTIMIZED_SCHEDULER +#define CONFIG_FREERTOS_HZ 1000 +#define CONFIG_FREERTOS_MAX_PRIORITIES 32 +#define CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES 13 +#define CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES 11 +#define CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS 1 +#define CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE 1024 +#define CONFIG_FREERTOS_MAX_TASK_NAME_LEN 32 +#define CONFIG_FREERTOS_TIMER_TASK_PRIORITY 1 +#define CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH 2048 +#define CONFIG_FREERTOS_TIMER_QUEUE_LENGTH 10 +#define CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE 0 +#define CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS +#define CONFIG_FREERTOS_USE_TRACE_FACILITY +#define CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS +/* CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set */ +#define CONFIG_FREERTOS_TOTAL_HEAP_SIZE 10240 +#define CONFIG_FREERTOS_TASK_FPU_SUPPORT 1 +/* end of Kernel Configuration */ #endif diff --git a/example/amp/openamp/core1/configs/d2000_aarch32_eg_configs b/example/amp/openamp/core1/configs/d2000_aarch32_eg_configs index 3797f2dc..2a16392b 100644 --- a/example/amp/openamp/core1/configs/d2000_aarch32_eg_configs +++ b/example/amp/openamp/core1/configs/d2000_aarch32_eg_configs @@ -71,6 +71,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_CAN is not set # CONFIG_USE_I2C is not set # CONFIG_USE_TIMER is not set +# CONFIG_USE_MIO is not set # CONFIG_USE_SDMMC is not set # CONFIG_USE_PCIE is not set # CONFIG_USE_WDT is not set @@ -82,6 +83,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -126,6 +128,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + # CONFIG_OUTPUT_BINARY is not set # end of Compiler Options # end of Building Option @@ -135,17 +146,94 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # -# Freertos Drivers +# Freertos Uart Drivers # CONFIG_FREERTOS_USE_UART=y -# end of Freertos Drivers +# end of Freertos Uart Drivers + +# +# Freertos Pwm Drivers +# +# CONFIG_FREERTOS_USE_PWM is not set +# end of Freertos Pwm Drivers + +# +# Freertos Qspi Drivers +# +# CONFIG_FREERTOS_USE_QSPI is not set +# end of Freertos Qspi Drivers + +# +# Freertos Wdt Drivers +# +# CONFIG_FREERTOS_USE_WDT is not set +# end of Freertos Wdt Drivers + +# +# Freertos Eth Drivers +# +# CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set +# end of Freertos Eth Drivers + +# +# Freertos Gpio Drivers +# +# CONFIG_FREERTOS_USE_GPIO is not set +# end of Freertos Gpio Drivers + +# +# Freertos Spim Drivers +# +# CONFIG_FREERTOS_USE_FSPIM is not set +# end of Freertos Spim Drivers + +# +# Freertos DMA Drivers +# +# CONFIG_FREERTOS_USE_FDDMA is not set +# CONFIG_FREERTOS_USE_FGDMA is not set +# end of Freertos DMA Drivers + +# +# Freertos Adc Drivers +# +# CONFIG_FREERTOS_USE_ADC is not set +# end of Freertos Adc Drivers + +# +# Freertos Can Drivers +# +# CONFIG_FREERTOS_USE_CAN is not set +# end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y +# CONFIG_USE_FATFS_0_1_4 is not set +# CONFIG_USE_SFUD is not set +# CONFIG_USE_SPIFFS is not set CONFIG_USE_AMP=y CONFIG_USE_LIBMETAL=y @@ -172,4 +260,30 @@ CONFIG_MEM_NO_CACHE=y # end of OpenAmp # CONFIG_USE_LETTER_SHELL is not set -# end of FreeRTOS Setting +# CONFIG_USE_TLSF is not set +# CONFIG_USE_SDMMC_CMD is not set +# CONFIG_USE_CHERRY_USB is not set +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/amp/openamp/core1/configs/d2000_aarch64_eg_configs b/example/amp/openamp/core1/configs/d2000_aarch64_eg_configs index 8892fb44..bffa9a71 100644 --- a/example/amp/openamp/core1/configs/d2000_aarch64_eg_configs +++ b/example/amp/openamp/core1/configs/d2000_aarch64_eg_configs @@ -71,6 +71,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_CAN is not set # CONFIG_USE_I2C is not set # CONFIG_USE_TIMER is not set +# CONFIG_USE_MIO is not set # CONFIG_USE_SDMMC is not set # CONFIG_USE_PCIE is not set # CONFIG_USE_WDT is not set @@ -82,6 +83,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -122,6 +124,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + # CONFIG_OUTPUT_BINARY is not set # end of Compiler Options # end of Building Option @@ -131,17 +142,94 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # -# Freertos Drivers +# Freertos Uart Drivers # CONFIG_FREERTOS_USE_UART=y -# end of Freertos Drivers +# end of Freertos Uart Drivers + +# +# Freertos Pwm Drivers +# +# CONFIG_FREERTOS_USE_PWM is not set +# end of Freertos Pwm Drivers + +# +# Freertos Qspi Drivers +# +# CONFIG_FREERTOS_USE_QSPI is not set +# end of Freertos Qspi Drivers + +# +# Freertos Wdt Drivers +# +# CONFIG_FREERTOS_USE_WDT is not set +# end of Freertos Wdt Drivers + +# +# Freertos Eth Drivers +# +# CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set +# end of Freertos Eth Drivers + +# +# Freertos Gpio Drivers +# +# CONFIG_FREERTOS_USE_GPIO is not set +# end of Freertos Gpio Drivers + +# +# Freertos Spim Drivers +# +# CONFIG_FREERTOS_USE_FSPIM is not set +# end of Freertos Spim Drivers + +# +# Freertos DMA Drivers +# +# CONFIG_FREERTOS_USE_FDDMA is not set +# CONFIG_FREERTOS_USE_FGDMA is not set +# end of Freertos DMA Drivers + +# +# Freertos Adc Drivers +# +# CONFIG_FREERTOS_USE_ADC is not set +# end of Freertos Adc Drivers + +# +# Freertos Can Drivers +# +# CONFIG_FREERTOS_USE_CAN is not set +# end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y +# CONFIG_USE_FATFS_0_1_4 is not set +# CONFIG_USE_SFUD is not set +# CONFIG_USE_SPIFFS is not set CONFIG_USE_AMP=y CONFIG_USE_LIBMETAL=y @@ -168,4 +256,30 @@ CONFIG_MEM_NO_CACHE=y # end of OpenAmp # CONFIG_USE_LETTER_SHELL is not set -# end of FreeRTOS Setting +# CONFIG_USE_TLSF is not set +# CONFIG_USE_SDMMC_CMD is not set +# CONFIG_USE_CHERRY_USB is not set +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/amp/openamp/core1/configs/ft2004_aarch32_eg_configs b/example/amp/openamp/core1/configs/ft2004_aarch32_eg_configs index 4bd8309b..e8ec985a 100644 --- a/example/amp/openamp/core1/configs/ft2004_aarch32_eg_configs +++ b/example/amp/openamp/core1/configs/ft2004_aarch32_eg_configs @@ -71,6 +71,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_CAN is not set # CONFIG_USE_I2C is not set # CONFIG_USE_TIMER is not set +# CONFIG_USE_MIO is not set # CONFIG_USE_SDMMC is not set # CONFIG_USE_PCIE is not set # CONFIG_USE_WDT is not set @@ -82,6 +83,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -126,6 +128,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + # CONFIG_OUTPUT_BINARY is not set # end of Compiler Options # end of Building Option @@ -135,17 +146,94 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # -# Freertos Drivers +# Freertos Uart Drivers # CONFIG_FREERTOS_USE_UART=y -# end of Freertos Drivers +# end of Freertos Uart Drivers + +# +# Freertos Pwm Drivers +# +# CONFIG_FREERTOS_USE_PWM is not set +# end of Freertos Pwm Drivers + +# +# Freertos Qspi Drivers +# +# CONFIG_FREERTOS_USE_QSPI is not set +# end of Freertos Qspi Drivers + +# +# Freertos Wdt Drivers +# +# CONFIG_FREERTOS_USE_WDT is not set +# end of Freertos Wdt Drivers + +# +# Freertos Eth Drivers +# +# CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set +# end of Freertos Eth Drivers + +# +# Freertos Gpio Drivers +# +# CONFIG_FREERTOS_USE_GPIO is not set +# end of Freertos Gpio Drivers + +# +# Freertos Spim Drivers +# +# CONFIG_FREERTOS_USE_FSPIM is not set +# end of Freertos Spim Drivers + +# +# Freertos DMA Drivers +# +# CONFIG_FREERTOS_USE_FDDMA is not set +# CONFIG_FREERTOS_USE_FGDMA is not set +# end of Freertos DMA Drivers + +# +# Freertos Adc Drivers +# +# CONFIG_FREERTOS_USE_ADC is not set +# end of Freertos Adc Drivers + +# +# Freertos Can Drivers +# +# CONFIG_FREERTOS_USE_CAN is not set +# end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y +# CONFIG_USE_FATFS_0_1_4 is not set +# CONFIG_USE_SFUD is not set +# CONFIG_USE_SPIFFS is not set CONFIG_USE_AMP=y CONFIG_USE_LIBMETAL=y @@ -172,4 +260,30 @@ CONFIG_MEM_NO_CACHE=y # end of OpenAmp # CONFIG_USE_LETTER_SHELL is not set -# end of FreeRTOS Setting +# CONFIG_USE_TLSF is not set +# CONFIG_USE_SDMMC_CMD is not set +# CONFIG_USE_CHERRY_USB is not set +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/amp/openamp/core1/configs/ft2004_aarch64_eg_configs b/example/amp/openamp/core1/configs/ft2004_aarch64_eg_configs index e4c5ab4b..cf0752a3 100644 --- a/example/amp/openamp/core1/configs/ft2004_aarch64_eg_configs +++ b/example/amp/openamp/core1/configs/ft2004_aarch64_eg_configs @@ -71,6 +71,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_CAN is not set # CONFIG_USE_I2C is not set # CONFIG_USE_TIMER is not set +# CONFIG_USE_MIO is not set # CONFIG_USE_SDMMC is not set # CONFIG_USE_PCIE is not set # CONFIG_USE_WDT is not set @@ -82,6 +83,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -122,6 +124,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + # CONFIG_OUTPUT_BINARY is not set # end of Compiler Options # end of Building Option @@ -131,17 +142,94 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # -# Freertos Drivers +# Freertos Uart Drivers # CONFIG_FREERTOS_USE_UART=y -# end of Freertos Drivers +# end of Freertos Uart Drivers + +# +# Freertos Pwm Drivers +# +# CONFIG_FREERTOS_USE_PWM is not set +# end of Freertos Pwm Drivers + +# +# Freertos Qspi Drivers +# +# CONFIG_FREERTOS_USE_QSPI is not set +# end of Freertos Qspi Drivers + +# +# Freertos Wdt Drivers +# +# CONFIG_FREERTOS_USE_WDT is not set +# end of Freertos Wdt Drivers + +# +# Freertos Eth Drivers +# +# CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set +# end of Freertos Eth Drivers + +# +# Freertos Gpio Drivers +# +# CONFIG_FREERTOS_USE_GPIO is not set +# end of Freertos Gpio Drivers + +# +# Freertos Spim Drivers +# +# CONFIG_FREERTOS_USE_FSPIM is not set +# end of Freertos Spim Drivers + +# +# Freertos DMA Drivers +# +# CONFIG_FREERTOS_USE_FDDMA is not set +# CONFIG_FREERTOS_USE_FGDMA is not set +# end of Freertos DMA Drivers + +# +# Freertos Adc Drivers +# +# CONFIG_FREERTOS_USE_ADC is not set +# end of Freertos Adc Drivers + +# +# Freertos Can Drivers +# +# CONFIG_FREERTOS_USE_CAN is not set +# end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y +# CONFIG_USE_FATFS_0_1_4 is not set +# CONFIG_USE_SFUD is not set +# CONFIG_USE_SPIFFS is not set CONFIG_USE_AMP=y CONFIG_USE_LIBMETAL=y @@ -168,4 +256,30 @@ CONFIG_MEM_NO_CACHE=y # end of OpenAmp # CONFIG_USE_LETTER_SHELL is not set -# end of FreeRTOS Setting +# CONFIG_USE_TLSF is not set +# CONFIG_USE_SDMMC_CMD is not set +# CONFIG_USE_CHERRY_USB is not set +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/amp/openamp/core1/main.c b/example/amp/openamp/core1/main.c index ad9278e2..eef13269 100644 --- a/example/amp/openamp/core1/main.c +++ b/example/amp/openamp/core1/main.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: main.c * Date: 2022-02-25 13:25:14 * LastEditTime: 2022-03-21 17:01:03 - * Description:  This file is for - * - * Modify History: + * Description:  This file is for AMP example that running rpmsg_echo_task and open scheduler + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/03/25 first commit */ @@ -43,16 +44,13 @@ int main(void) { BaseType_t ret; - // ret = LSUserShellTask() ; - // if(ret != pdPASS) - // goto FAIL_EXIT; rpmsg_echo_task(); - vTaskStartScheduler(); /* 启动任务,开启调度 */ + vTaskStartScheduler(); /* 启动任务,开启调度 */ while (1); /* 正常不会执行到这里 */ FAIL_EXIT: - printf("failed 0x%x \r\n", ret); + printf("Failed 0x%x. \r\n", ret); return 0; } diff --git a/example/amp/openamp/core1/rpmsg-ping_os.c b/example/amp/openamp/core1/rpmsg-ping_os.c index f6f9964e..44ce93c0 100644 --- a/example/amp/openamp/core1/rpmsg-ping_os.c +++ b/example/amp/openamp/core1/rpmsg-ping_os.c @@ -1,13 +1,29 @@ /* - * SPDX-License-Identifier: BSD-3-Clause + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: rpmsg-ping_os.c + * Date: 2022-02-25 09:12:07 + * LastEditTime: 2022-02-25 09:12:19 + * Description: This file is for a sample demonstration application that showcases usage of rpmsg. + * This application is meant to run on the remote CPU running baremetal code. + * This application echoes back data that was sent to it by the master core. + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/03/25 first commit */ -/* This is a sample demonstration application that showcases usage of rpmsg -This application is meant to run on the remote CPU running baremetal code. -This application echoes back data that was sent to it by the master core. */ - -/***************************** Include Files *********************************/ - #include #include #include @@ -27,16 +43,17 @@ This application echoes back data that was sent to it by the master core. */ /**************************** Type Definitions *******************************/ -struct _payload { - unsigned long num; - unsigned long size; - unsigned char data[]; +struct _payload +{ + unsigned long num; + unsigned long size; + unsigned char data[]; }; static int err_cnt; static char flg_cnt; -#define PAYLOAD_MIN_SIZE 1 +#define PAYLOAD_MIN_SIZE 1 /************************** Variable Definitions *****************************/ @@ -54,166 +71,182 @@ static int ept_deleted = 0; * RPMSG endpoint callbacks *-----------------------------------------------------------------------------*/ static int rpmsg_endpoint_cb(struct rpmsg_endpoint *ept, void *data, size_t len, - uint32_t src, void *priv) + uint32_t src, void *priv) { - int i; - struct _payload *r_payload = (struct _payload *)data; + int i; + struct _payload *r_payload = (struct _payload *)data; - (void)ept; - (void)src; - (void)priv; + (void)ept; + (void)src; + (void)priv; #ifdef CONFIG_MEM_NORMAL - FCacheDCacheInvalidateRange((intptr)data, len); + FCacheDCacheInvalidateRange((intptr)data, len); #endif - if (r_payload->size == 0) { - LPERROR(" Invalid size of package is received.\r\n"); - err_cnt++; - return RPMSG_SUCCESS; - } - /* Validate data buffer integrity. */ - for (i = 0; i < (int)r_payload->size; i++) { - if (r_payload->data[i] != flg_cnt) { - LPRINTF("Data corruption at index %d\r\n", i); - LPRINTF("Want data is %d\r\n", flg_cnt); - LPRINTF("Get data is %d\r\n", r_payload->data[i]); - err_cnt++; - break; - } - } - rnum = r_payload->num + 1; - return RPMSG_SUCCESS; + if (r_payload->size == 0) + { + LPERROR(" Invalid size of package is received.\r\n"); + err_cnt++; + return RPMSG_SUCCESS; + } + /* Validate data buffer integrity. */ + for (i = 0; i < (int)r_payload->size; i++) + { + if (r_payload->data[i] != flg_cnt) + { + LPRINTF("Data corruption at index %d.\r\n", i); + LPRINTF("Want data is %d.\r\n", flg_cnt); + LPRINTF("Get data is %d.\r\n", r_payload->data[i]); + err_cnt++; + break; + } + } + rnum = r_payload->num + 1; + return RPMSG_SUCCESS; } static void rpmsg_service_unbind(struct rpmsg_endpoint *ept) { - (void)ept; - rpmsg_destroy_ept(&lept); - LPRINTF("echo test: service is destroyed\r\n"); - ept_deleted = 1; + (void)ept; + rpmsg_destroy_ept(&lept); + LPRINTF("Echo test: service is destroyed.\r\n"); + ept_deleted = 1; } static void rpmsg_name_service_bind_cb(struct rpmsg_device *rdev, - const char *name, uint32_t dest) + const char *name, uint32_t dest) { - LPRINTF("new endpoint notification is received.\r\n"); - if (strcmp(name, RPMSG_SERVICE_NAME)) - LPERROR("Unexpected name service %s.\r\n", name); - else - (void)rpmsg_create_ept(&lept, rdev, RPMSG_SERVICE_NAME, - RPMSG_ADDR_ANY, dest, - rpmsg_endpoint_cb, - rpmsg_service_unbind); + LPRINTF("New endpoint notification is received.\r\n"); + if (strcmp(name, RPMSG_SERVICE_NAME)) + { + LPERROR("Unexpected name service %s.\r\n", name); + } + else + (void)rpmsg_create_ept(&lept, rdev, RPMSG_SERVICE_NAME, + RPMSG_ADDR_ANY, dest, + rpmsg_endpoint_cb, + rpmsg_service_unbind); } /*-----------------------------------------------------------------------------* * Application *-----------------------------------------------------------------------------*/ -int app (struct rpmsg_device *rdev, void *priv) +int app(struct rpmsg_device *rdev, void *priv) { - int ret; - int i; - int size, max_size, num_payloads; - int expect_rnum = 0; - - LPRINTF(" 1 - Send data to remote core, retrieve the echo"); - LPRINTF(" and validate its integrity ..\r\n"); - - max_size = rpmsg_virtio_get_buffer_size(rdev); - if (max_size < 0) { - LPERROR("No avaiable buffer size.\r\n"); - return -1; - } - max_size -= sizeof(struct _payload); - num_payloads = max_size - PAYLOAD_MIN_SIZE + 1; - i_payload = - (struct _payload *)metal_allocate_memory(2 * sizeof(unsigned long) + - max_size); - - if (!i_payload) { - LPERROR("memory allocation failed.\r\n"); - return -1; - } - - /* Create RPMsg endpoint */ - ret = rpmsg_create_ept(&lept, rdev, RPMSG_SERVICE_NAME, - RPMSG_ADDR_ANY, RPMSG_ADDR_ANY, - rpmsg_endpoint_cb, rpmsg_service_unbind); - - if (ret) { - LPERROR("Failed to create RPMsg endpoint.\r\n"); - metal_free_memory(i_payload); - return ret; - } - while (!is_rpmsg_ept_ready(&lept)) - platform_poll(priv); - - LPRINTF("RPMSG endpoint is binded with remote.\r\n"); - for (i = 0, size = PAYLOAD_MIN_SIZE; i < num_payloads; i++, size++) { - i_payload->num = i; - i_payload->size = size; - flg_cnt++; - /* Mark the data buffer. */ - memset(&(i_payload->data[0]), flg_cnt, size); - - ret = rpmsg_send(&lept, i_payload, - (2 * sizeof(unsigned long)) + size); - - if (ret < 0) { - LPERROR("Failed to send data...\r\n"); - break; - } - - expect_rnum++; - do { - platform_poll(priv); - } while ((rnum < expect_rnum) && !err_cnt && !ept_deleted); - - } - - LPRINTF("**********************************\r\n"); - LPRINTF(" Test Results: Error count = %d \r\n", err_cnt); - LPRINTF("**********************************\r\n"); - /* Destroy the RPMsg endpoint */ - rpmsg_destroy_ept(&lept); - LPRINTF("Quitting application .. Echo test end\r\n"); - - metal_free_memory(i_payload); - return 0; + int ret; + int i; + int size, max_size, num_payloads; + int expect_rnum = 0; + + LPRINTF(" 1 - Send data to remote core, retrieve the echo"); + LPRINTF(" and validate its integrity ..\r\n"); + + max_size = rpmsg_virtio_get_buffer_size(rdev); + if (max_size < 0) + { + LPERROR("No avaiable buffer size.\r\n"); + return -1; + } + max_size -= sizeof(struct _payload); + num_payloads = max_size - PAYLOAD_MIN_SIZE + 1; + i_payload = + (struct _payload *)metal_allocate_memory(2 * sizeof(unsigned long) + + max_size); + + if (!i_payload) + { + LPERROR("Memory allocation failed.\r\n"); + return -1; + } + + /* Create RPMsg endpoint */ + ret = rpmsg_create_ept(&lept, rdev, RPMSG_SERVICE_NAME, + RPMSG_ADDR_ANY, RPMSG_ADDR_ANY, + rpmsg_endpoint_cb, rpmsg_service_unbind); + + if (ret) + { + LPERROR("Failed to create RPMsg endpoint.\r\n"); + metal_free_memory(i_payload); + return ret; + } + while (!is_rpmsg_ept_ready(&lept)) + { + platform_poll(priv); + } + + LPRINTF("RPMSG endpoint is binded with remote.\r\n"); + for (i = 0, size = PAYLOAD_MIN_SIZE; i < num_payloads; i++, size++) + { + i_payload->num = i; + i_payload->size = size; + flg_cnt++; + /* Mark the data buffer. */ + memset(&(i_payload->data[0]), flg_cnt, size); + + ret = rpmsg_send(&lept, i_payload, + (2 * sizeof(unsigned long)) + size); + + if (ret < 0) + { + LPERROR("Failed to send data...\r\n"); + break; + } + + expect_rnum++; + do + { + platform_poll(priv); + } + while ((rnum < expect_rnum) && !err_cnt && !ept_deleted); + + } + + LPRINTF("**********************************\r\n"); + LPRINTF(" Test Results: Error count = %d. \r\n", err_cnt); + LPRINTF("**********************************\r\n"); + /* Destroy the RPMsg endpoint */ + rpmsg_destroy_ept(&lept); + LPRINTF("Quitting application .. Echo test end.\r\n"); + + metal_free_memory(i_payload); + return 0; } static void rpmsg_ping(void *args) { - void *platform; - struct rpmsg_device *rpdev; - int ret = 0; - /* Initialize platform */ - ret = platform_init(0, NULL, &platform); - if (ret) { - LPERROR("Failed to initialize platform.\r\n"); - } - else - { - rpdev = platform_create_rpmsg_vdev(platform, 0, - VIRTIO_DEV_MASTER, - NULL, - rpmsg_name_service_bind_cb); - if (!rpdev) { - LPERROR("Failed to create platform_create_rpmsg_vdev\r\n"); - } - else - { - app(rpdev, platform); - platform_release_rpmsg_vdev(rpdev, platform); - } - } - - LPRINTF("Stopping application...\r\n"); - platform_cleanup(platform); - // PsciCpuOff(); - vTaskDelete(NULL); + void *platform; + struct rpmsg_device *rpdev; + int ret = 0; + /* Initialize platform */ + ret = platform_init(0, NULL, &platform); + if (ret) + { + LPERROR("Failed to initialize platform.\r\n"); + } + else + { + rpdev = platform_create_rpmsg_vdev(platform, 0, + VIRTIO_DEV_MASTER, + NULL, + rpmsg_name_service_bind_cb); + if (!rpdev) + { + LPERROR("Failed to create platform_create_rpmsg_vdev.\r\n"); + } + else + { + app(rpdev, platform); + platform_release_rpmsg_vdev(rpdev, platform); + } + } + + LPRINTF("Stopping application...\r\n"); + platform_cleanup(platform); + // PsciCpuOff(); + vTaskDelete(NULL); } @@ -221,18 +254,18 @@ static void rpmsg_ping(void *args) int rpmsg_echo_task(void) { - BaseType_t ret; - - ret = xTaskCreate((TaskFunction_t )rpmsg_ping, /* 任务入口函数 */ - (const char* )"rpmsg_ping",/* 任务名字 */ - (uint16_t )4096, /* 任务栈大小 */ - (void* )NULL,/* 任务入口函数参数 */ - (UBaseType_t )1, /* 任务的优先级 */ - NULL); /* 任务控制块指针 */ - - if(ret != pdPASS) + BaseType_t ret; + + ret = xTaskCreate((TaskFunction_t)rpmsg_ping, /* 任务入口函数 */ + (const char *)"rpmsg_ping",/* 任务名字 */ + (uint16_t)4096, /* 任务栈大小 */ + (void *)NULL,/* 任务入口函数参数 */ + (UBaseType_t)1, /* 任务的优先级 */ + NULL); /* 任务控制块指针 */ + + if (ret != pdPASS) { - LPERROR("Failed to create a rpmsg_echo task "); + LPERROR("Failed to create a rpmsg_echo task. \r\n"); return -1; } diff --git a/example/amp/openamp/core1/sdkconfig b/example/amp/openamp/core1/sdkconfig index 4bd8309b..e8ec985a 100644 --- a/example/amp/openamp/core1/sdkconfig +++ b/example/amp/openamp/core1/sdkconfig @@ -71,6 +71,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_CAN is not set # CONFIG_USE_I2C is not set # CONFIG_USE_TIMER is not set +# CONFIG_USE_MIO is not set # CONFIG_USE_SDMMC is not set # CONFIG_USE_PCIE is not set # CONFIG_USE_WDT is not set @@ -82,6 +83,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -126,6 +128,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + # CONFIG_OUTPUT_BINARY is not set # end of Compiler Options # end of Building Option @@ -135,17 +146,94 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # -# Freertos Drivers +# Freertos Uart Drivers # CONFIG_FREERTOS_USE_UART=y -# end of Freertos Drivers +# end of Freertos Uart Drivers + +# +# Freertos Pwm Drivers +# +# CONFIG_FREERTOS_USE_PWM is not set +# end of Freertos Pwm Drivers + +# +# Freertos Qspi Drivers +# +# CONFIG_FREERTOS_USE_QSPI is not set +# end of Freertos Qspi Drivers + +# +# Freertos Wdt Drivers +# +# CONFIG_FREERTOS_USE_WDT is not set +# end of Freertos Wdt Drivers + +# +# Freertos Eth Drivers +# +# CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set +# end of Freertos Eth Drivers + +# +# Freertos Gpio Drivers +# +# CONFIG_FREERTOS_USE_GPIO is not set +# end of Freertos Gpio Drivers + +# +# Freertos Spim Drivers +# +# CONFIG_FREERTOS_USE_FSPIM is not set +# end of Freertos Spim Drivers + +# +# Freertos DMA Drivers +# +# CONFIG_FREERTOS_USE_FDDMA is not set +# CONFIG_FREERTOS_USE_FGDMA is not set +# end of Freertos DMA Drivers + +# +# Freertos Adc Drivers +# +# CONFIG_FREERTOS_USE_ADC is not set +# end of Freertos Adc Drivers + +# +# Freertos Can Drivers +# +# CONFIG_FREERTOS_USE_CAN is not set +# end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y +# CONFIG_USE_FATFS_0_1_4 is not set +# CONFIG_USE_SFUD is not set +# CONFIG_USE_SPIFFS is not set CONFIG_USE_AMP=y CONFIG_USE_LIBMETAL=y @@ -172,4 +260,30 @@ CONFIG_MEM_NO_CACHE=y # end of OpenAmp # CONFIG_USE_LETTER_SHELL is not set -# end of FreeRTOS Setting +# CONFIG_USE_TLSF is not set +# CONFIG_USE_SDMMC_CMD is not set +# CONFIG_USE_CHERRY_USB is not set +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/amp/openamp/core1/sdkconfig.h b/example/amp/openamp/core1/sdkconfig.h index 08fe8d08..0d2a25e2 100644 --- a/example/amp/openamp/core1/sdkconfig.h +++ b/example/amp/openamp/core1/sdkconfig.h @@ -63,6 +63,7 @@ /* CONFIG_USE_CAN is not set */ /* CONFIG_USE_I2C is not set */ /* CONFIG_USE_TIMER is not set */ +/* CONFIG_USE_MIO is not set */ /* CONFIG_USE_SDMMC is not set */ /* CONFIG_USE_PCIE is not set */ /* CONFIG_USE_WDT is not set */ @@ -74,6 +75,7 @@ /* CONFIG_USE_ADC is not set */ /* CONFIG_USE_PWM is not set */ /* CONFIG_USE_IPC is not set */ +/* CONFIG_USE_MEDIA is not set */ /* end of Components Configuration */ #define CONFIG_USE_NEW_LIBC /* end of Standalone Setting */ @@ -114,22 +116,93 @@ /* Compiler Options */ +/* Cross-Compiler Setting */ + +#define CONFIG_GCC_OPTIMIZE_LEVEL 0 +/* CONFIG_USE_EXT_COMPILER is not set */ +/* CONFIG_USE_KLIN_SYS is not set */ +/* end of Cross-Compiler Setting */ /* CONFIG_OUTPUT_BINARY is not set */ /* end of Compiler Options */ /* end of Building Option */ /* Component Configuration */ -/* Freertos Drivers */ +/* Freertos Uart Drivers */ #define CONFIG_FREERTOS_USE_UART -/* end of Freertos Drivers */ +/* end of Freertos Uart Drivers */ + +/* Freertos Pwm Drivers */ + +/* CONFIG_FREERTOS_USE_PWM is not set */ +/* end of Freertos Pwm Drivers */ + +/* Freertos Qspi Drivers */ + +/* CONFIG_FREERTOS_USE_QSPI is not set */ +/* end of Freertos Qspi Drivers */ + +/* Freertos Wdt Drivers */ + +/* CONFIG_FREERTOS_USE_WDT is not set */ +/* end of Freertos Wdt Drivers */ + +/* Freertos Eth Drivers */ + +/* CONFIG_FREERTOS_USE_XMAC is not set */ +/* CONFIG_FREERTOS_USE_GMAC is not set */ +/* end of Freertos Eth Drivers */ + +/* Freertos Gpio Drivers */ + +/* CONFIG_FREERTOS_USE_GPIO is not set */ +/* end of Freertos Gpio Drivers */ + +/* Freertos Spim Drivers */ + +/* CONFIG_FREERTOS_USE_FSPIM is not set */ +/* end of Freertos Spim Drivers */ + +/* Freertos DMA Drivers */ + +/* CONFIG_FREERTOS_USE_FDDMA is not set */ +/* CONFIG_FREERTOS_USE_FGDMA is not set */ +/* end of Freertos DMA Drivers */ + +/* Freertos Adc Drivers */ + +/* CONFIG_FREERTOS_USE_ADC is not set */ +/* end of Freertos Adc Drivers */ + +/* Freertos Can Drivers */ + +/* CONFIG_FREERTOS_USE_CAN is not set */ +/* end of Freertos Can Drivers */ + +/* Freertos I2c Drivers */ + +/* CONFIG_FREERTOS_USE_I2C is not set */ +/* end of Freertos I2c Drivers */ + +/* Freertos Mio Drivers */ + +/* CONFIG_FREERTOS_USE_MIO is not set */ +/* end of Freertos Mio Drivers */ + +/* Freertos Timer Drivers */ + +/* CONFIG_FREERTOS_USE_TIMER is not set */ +/* end of Freertos Timer Drivers */ /* end of Component Configuration */ -/* FreeRTOS Setting */ +/* Third-Party Configuration */ /* CONFIG_USE_LWIP is not set */ #define CONFIG_USE_BACKTRACE +/* CONFIG_USE_FATFS_0_1_4 is not set */ +/* CONFIG_USE_SFUD is not set */ +/* CONFIG_USE_SPIFFS is not set */ #define CONFIG_USE_AMP #define CONFIG_USE_LIBMETAL @@ -153,6 +226,31 @@ /* end of Baremetal config */ /* end of OpenAmp */ /* CONFIG_USE_LETTER_SHELL is not set */ -/* end of FreeRTOS Setting */ +/* CONFIG_USE_TLSF is not set */ +/* CONFIG_USE_SDMMC_CMD is not set */ +/* CONFIG_USE_CHERRY_USB is not set */ +/* end of Third-Party Configuration */ + +/* Kernel Configuration */ + +#define CONFIG_FREERTOS_OPTIMIZED_SCHEDULER +#define CONFIG_FREERTOS_HZ 1000 +#define CONFIG_FREERTOS_MAX_PRIORITIES 32 +#define CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES 13 +#define CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES 11 +#define CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS 1 +#define CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE 1024 +#define CONFIG_FREERTOS_MAX_TASK_NAME_LEN 32 +#define CONFIG_FREERTOS_TIMER_TASK_PRIORITY 1 +#define CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH 2048 +#define CONFIG_FREERTOS_TIMER_QUEUE_LENGTH 10 +#define CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE 0 +#define CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS +#define CONFIG_FREERTOS_USE_TRACE_FACILITY +#define CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS +/* CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set */ +#define CONFIG_FREERTOS_TOTAL_HEAP_SIZE 10240 +#define CONFIG_FREERTOS_TASK_FPU_SUPPORT 1 +/* end of Kernel Configuration */ #endif diff --git a/example/freertos_feature/eventgroup/configs/d2000_aarch32_eg_configs b/example/freertos_feature/eventgroup/configs/d2000_aarch32_eg_configs index 464a31af..a16785ad 100644 --- a/example/freertos_feature/eventgroup/configs/d2000_aarch32_eg_configs +++ b/example/freertos_feature/eventgroup/configs/d2000_aarch32_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -111,6 +112,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -147,6 +157,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -168,12 +179,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -185,14 +190,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -210,4 +233,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/eventgroup/configs/d2000_aarch64_eg_configs b/example/freertos_feature/eventgroup/configs/d2000_aarch64_eg_configs index 64e6b4b7..4731ef2f 100644 --- a/example/freertos_feature/eventgroup/configs/d2000_aarch64_eg_configs +++ b/example/freertos_feature/eventgroup/configs/d2000_aarch64_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/eventgroup/configs/e2000d_aarch32_eg_configs b/example/freertos_feature/eventgroup/configs/e2000d_aarch32_eg_configs index fc31cd0b..22902270 100644 --- a/example/freertos_feature/eventgroup/configs/e2000d_aarch32_eg_configs +++ b/example/freertos_feature/eventgroup/configs/e2000d_aarch32_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -111,6 +112,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -147,6 +157,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -168,12 +179,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -185,14 +190,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -210,4 +233,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/eventgroup/configs/e2000d_aarch64_eg_configs b/example/freertos_feature/eventgroup/configs/e2000d_aarch64_eg_configs index 7e2efa4f..f3181d35 100644 --- a/example/freertos_feature/eventgroup/configs/e2000d_aarch64_eg_configs +++ b/example/freertos_feature/eventgroup/configs/e2000d_aarch64_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/eventgroup/configs/e2000q_aarch32_eg_configs b/example/freertos_feature/eventgroup/configs/e2000q_aarch32_eg_configs index 1b53ed91..eea9646f 100644 --- a/example/freertos_feature/eventgroup/configs/e2000q_aarch32_eg_configs +++ b/example/freertos_feature/eventgroup/configs/e2000q_aarch32_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -111,6 +112,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -147,6 +157,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -168,12 +179,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -185,14 +190,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -210,4 +233,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/eventgroup/configs/e2000q_aarch64_eg_configs b/example/freertos_feature/eventgroup/configs/e2000q_aarch64_eg_configs index 506efc21..d1584130 100644 --- a/example/freertos_feature/eventgroup/configs/e2000q_aarch64_eg_configs +++ b/example/freertos_feature/eventgroup/configs/e2000q_aarch64_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/eventgroup/configs/ft2004_aarch32_eg_configs b/example/freertos_feature/eventgroup/configs/ft2004_aarch32_eg_configs index 4c5b2c49..f0510b59 100644 --- a/example/freertos_feature/eventgroup/configs/ft2004_aarch32_eg_configs +++ b/example/freertos_feature/eventgroup/configs/ft2004_aarch32_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -111,6 +112,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -147,6 +157,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -168,12 +179,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -185,14 +190,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -210,4 +233,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/eventgroup/configs/ft2004_aarch64_eg_configs b/example/freertos_feature/eventgroup/configs/ft2004_aarch64_eg_configs index da9c1f81..d99e8ace 100644 --- a/example/freertos_feature/eventgroup/configs/ft2004_aarch64_eg_configs +++ b/example/freertos_feature/eventgroup/configs/ft2004_aarch64_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/eventgroup/inc/feature_eventgroup.h b/example/freertos_feature/eventgroup/inc/feature_eventgroup.h index 323a5163..300d1dc2 100644 --- a/example/freertos_feature/eventgroup/inc/feature_eventgroup.h +++ b/example/freertos_feature/eventgroup/inc/feature_eventgroup.h @@ -1,30 +1,36 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: feature_eventgroup.h * Date: 2022-06-17 10:42:40 * LastEditTime: 2022-06-17 10:42:40 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for task function define + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 wangxiaodong 2022/08/09 first commit */ #ifndef FEATURE_EVENTGROUP_H #define FEATURE_EVENTGROUP_H +#ifdef __cplusplus +extern "C" +{ +#endif + /* event group Management task */ void CreateManagementTasks(void); void DeleteManagementTasks(void); @@ -33,6 +39,8 @@ void DeleteManagementTasks(void); void CreateSyncTasks(void); void DeleteSyncTasks(void); - +#ifdef __cplusplus +} +#endif #endif // ! \ No newline at end of file diff --git a/example/freertos_feature/eventgroup/main.c b/example/freertos_feature/eventgroup/main.c index f376d838..fa9cccdf 100644 --- a/example/freertos_feature/eventgroup/main.c +++ b/example/freertos_feature/eventgroup/main.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: main.c * Date: 2022-06-17 08:17:59 * LastEditTime: 2022-06-17 08:17:59 - * Description: This file is for - * - * Modify History: + * Description: This file is for eventgroup example that running shell task and open scheduler + * + * Modify History: * Ver Who Date Changes * ----- ------ -------- -------------------------------------- + * 1.0 wangxiaodong 2022/08/09 first commit */ #include "shell.h" @@ -30,13 +31,15 @@ int main(void) BaseType_t ret; ret = LSUserShellTask() ; - if(ret != pdPASS) + if (ret != pdPASS) + { goto FAIL_EXIT; + } - vTaskStartScheduler(); /* 启动任务,开启调度 */ + vTaskStartScheduler(); /* 启动任务,开启调度 */ while (1); /* 正常不会执行到这里 */ - + FAIL_EXIT: - printf("failed 0x%x \r\n", ret); + printf("Failed 0x%x. \r\n", ret); return 0; } diff --git a/example/freertos_feature/eventgroup/sdkconfig b/example/freertos_feature/eventgroup/sdkconfig index 506efc21..d1584130 100644 --- a/example/freertos_feature/eventgroup/sdkconfig +++ b/example/freertos_feature/eventgroup/sdkconfig @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/eventgroup/sdkconfig.h b/example/freertos_feature/eventgroup/sdkconfig.h index 2ccaa536..e5bce452 100644 --- a/example/freertos_feature/eventgroup/sdkconfig.h +++ b/example/freertos_feature/eventgroup/sdkconfig.h @@ -62,6 +62,7 @@ /* CONFIG_USE_ADC is not set */ /* CONFIG_USE_PWM is not set */ /* CONFIG_USE_IPC is not set */ +/* CONFIG_USE_MEDIA is not set */ /* end of Components Configuration */ #define CONFIG_USE_NEW_LIBC /* end of Standalone Setting */ @@ -98,6 +99,12 @@ /* Compiler Options */ +/* Cross-Compiler Setting */ + +#define CONFIG_GCC_OPTIMIZE_LEVEL 0 +/* CONFIG_USE_EXT_COMPILER is not set */ +/* CONFIG_USE_KLIN_SYS is not set */ +/* end of Cross-Compiler Setting */ #define CONFIG_OUTPUT_BINARY /* end of Compiler Options */ /* end of Building Option */ @@ -127,6 +134,7 @@ /* Freertos Eth Drivers */ /* CONFIG_FREERTOS_USE_XMAC is not set */ +/* CONFIG_FREERTOS_USE_GMAC is not set */ /* end of Freertos Eth Drivers */ /* Freertos Gpio Drivers */ @@ -145,11 +153,6 @@ /* CONFIG_FREERTOS_USE_FGDMA is not set */ /* end of Freertos DMA Drivers */ -/* Freertos MMC Drivers */ - -/* CONFIG_FREERTOS_USE_FSDIO is not set */ -/* end of Freertos MMC Drivers */ - /* Freertos Adc Drivers */ /* CONFIG_FREERTOS_USE_ADC is not set */ @@ -159,13 +162,28 @@ /* CONFIG_FREERTOS_USE_CAN is not set */ /* end of Freertos Can Drivers */ + +/* Freertos I2c Drivers */ + +/* CONFIG_FREERTOS_USE_I2C is not set */ +/* end of Freertos I2c Drivers */ + +/* Freertos Mio Drivers */ + +/* CONFIG_FREERTOS_USE_MIO is not set */ +/* end of Freertos Mio Drivers */ + +/* Freertos Timer Drivers */ + +/* CONFIG_FREERTOS_USE_TIMER is not set */ +/* end of Freertos Timer Drivers */ /* end of Component Configuration */ -/* FreeRTOS Setting */ +/* Third-Party Configuration */ /* CONFIG_USE_LWIP is not set */ #define CONFIG_USE_BACKTRACE -/* CONFIG_USE_FATFS is not set */ +/* CONFIG_USE_FATFS_0_1_4 is not set */ /* CONFIG_USE_SFUD is not set */ /* CONFIG_USE_SPIFFS is not set */ /* CONFIG_USE_AMP is not set */ @@ -181,6 +199,28 @@ #define CONFIG_USE_TLSF /* CONFIG_USE_SDMMC_CMD is not set */ /* CONFIG_USE_CHERRY_USB is not set */ -/* end of FreeRTOS Setting */ +/* end of Third-Party Configuration */ + +/* Kernel Configuration */ + +#define CONFIG_FREERTOS_OPTIMIZED_SCHEDULER +#define CONFIG_FREERTOS_HZ 1000 +#define CONFIG_FREERTOS_MAX_PRIORITIES 32 +#define CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES 13 +#define CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES 11 +#define CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS 1 +#define CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE 1024 +#define CONFIG_FREERTOS_MAX_TASK_NAME_LEN 32 +#define CONFIG_FREERTOS_TIMER_TASK_PRIORITY 1 +#define CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH 2048 +#define CONFIG_FREERTOS_TIMER_QUEUE_LENGTH 10 +#define CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE 0 +#define CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS +#define CONFIG_FREERTOS_USE_TRACE_FACILITY +#define CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS +/* CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set */ +#define CONFIG_FREERTOS_TOTAL_HEAP_SIZE 10240 +#define CONFIG_FREERTOS_TASK_FPU_SUPPORT 1 +/* end of Kernel Configuration */ #endif diff --git a/example/freertos_feature/eventgroup/src/eventgroup_cmd.c b/example/freertos_feature/eventgroup/src/eventgroup_cmd.c index 68a7e3bd..173ee67b 100644 --- a/example/freertos_feature/eventgroup/src/eventgroup_cmd.c +++ b/example/freertos_feature/eventgroup/src/eventgroup_cmd.c @@ -1,3 +1,26 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: eventgroup_cmd.c + * Date: 2022-06-17 10:42:40 + * LastEditTime: 2022-06-17 10:42:40 + * Description: This file is for eventgroup command interface + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 wangxiaodong 2022/08/09 first commit + */ #include "shell.h" #include @@ -13,15 +36,15 @@ typedef enum static void EventTasksCmdUsage(void) { - printf("usage:\r\n"); + printf("Usage:\r\n"); printf(" event manage_cre \r\n"); - printf(" -- create manage tasks now\r\n"); + printf(" -- Create manage tasks now.\r\n"); printf(" event manage_del \r\n"); - printf(" -- del manage tasks now\r\n"); + printf(" -- Del manage tasks now.\r\n"); printf(" event sync_cre \r\n"); - printf(" -- create sync tasks now\r\n"); + printf(" -- Create sync tasks now.\r\n"); printf(" event sync_del \r\n"); - printf(" -- del sync tasks now\r\n"); + printf(" -- Del sync tasks now.\r\n"); } @@ -37,55 +60,55 @@ int CreateEventCmd(int argc, char *argv[]) if (!strcmp(argv[1], "manage_cre")) { - if(create_flg[MANAGE_TASK_INDEX] == 0) + if (create_flg[MANAGE_TASK_INDEX] == 0) { CreateManagementTasks(); create_flg[MANAGE_TASK_INDEX] = 1; } else { - printf("Please use manage_del cmd first \r\n"); + printf("Please use manage_del cmd first. \r\n"); } } else if (!strcmp(argv[1], "manage_del")) { - if(create_flg[MANAGE_TASK_INDEX] == 1) + if (create_flg[MANAGE_TASK_INDEX] == 1) { DeleteManagementTasks(); create_flg[MANAGE_TASK_INDEX] = 0; - } + } else { - printf("Please use manage_cre cmd first \r\n"); + printf("Please use manage_cre cmd first. \r\n"); } } else if (!strcmp(argv[1], "sync_cre")) { - if(create_flg[SYNC_TASK_INDEX] == 0) + if (create_flg[SYNC_TASK_INDEX] == 0) { CreateSyncTasks(); create_flg[SYNC_TASK_INDEX] = 1; } else { - printf("Please use sync_del cmd first \r\n"); + printf("Please use sync_del cmd first. \r\n"); } } else if (!strcmp(argv[1], "sync_del")) { - if(create_flg[SYNC_TASK_INDEX] == 1) + if (create_flg[SYNC_TASK_INDEX] == 1) { DeleteSyncTasks(); create_flg[SYNC_TASK_INDEX] = 0; - } + } else { - printf("Please use sync_cre cmd first \r\n"); + printf("Please use sync_cre cmd first. \r\n"); } } else { - printf("Error: Invalid arguments \r\n"); + printf("Error: Invalid arguments. \r\n"); EventTasksCmdUsage(); } return 0; diff --git a/example/freertos_feature/eventgroup/src/management.c b/example/freertos_feature/eventgroup/src/management.c index 422a1a8b..0c4491ef 100644 --- a/example/freertos_feature/eventgroup/src/management.c +++ b/example/freertos_feature/eventgroup/src/management.c @@ -1,9 +1,9 @@ /* -This example demonstrates how to: - Create an event group. - Set bits in an event group from an interrupt service routine. - Set bits in an event group from a task. - Block on an event group. +This example demonstrates how to: + Create an event group. + Set bits in an event group from an interrupt service routine. + Set bits in an event group from a task. + Block on an event group. */ #include "FreeRTOS.h" #include "task.h" @@ -16,31 +16,31 @@ static xTaskHandle xtask1_handle; static xTaskHandle xtask2_handle; static xTaskHandle xtask3_handle; -#define TASK_STACK_SIZE 1024 +#define TASK_STACK_SIZE 1024 /* The interrupt number to use for the software interrupt generation. This could be any unused number. In this case the first chip level (non system) interrupt is used */ -#define INTERRUPT_ID 0 +#define INTERRUPT_ID 0 /* The priority of the software interrupt. The interrupt service routine uses an (interrupt safe) FreeRTOS API function, so the priority of the interrupt must be equal to or lower than the priority set by configMAX_SYSCALL_INTERRUPT_PRIORITY. */ -#define INTERRUPT_PRIORITY IRQ_PRIORITY_VALUE_12 +#define INTERRUPT_PRIORITY IRQ_PRIORITY_VALUE_12 /* Definitions for the event bits in the event group. */ -#define FIRST_TASK_BIT ( 1UL << 0UL ) /* Event bit 0, which is set by a task. */ -#define SECOND_TASK_BIT ( 1UL << 1UL ) /* Event bit 1, which is set by a task. */ -#define ISR_BIT ( 1UL << 2UL ) /* Event bit 2, which is set by an ISR. */ +#define FIRST_TASK_BIT ( 1UL << 0UL ) /* Event bit 0, which is set by a task. */ +#define SECOND_TASK_BIT ( 1UL << 1UL ) /* Event bit 1, which is set by a task. */ +#define ISR_BIT ( 1UL << 2UL ) /* Event bit 2, which is set by an ISR. */ /* The tasks to be created. */ -static void vIntegerGenerator( void *pvParameters ); -static void vEventBitSettingTask( void *pvParameters ); -static void vEventBitReadingTask( void *pvParameters ); +static void vIntegerGenerator(void *pvParameters); +static void vEventBitSettingTask(void *pvParameters); +static void vEventBitReadingTask(void *pvParameters); /* A function that can be deferred to run in the RTOS daemon task. The function prints out the string passed to it using the pvParameter1 parameter. */ -void vPrintStringFromDaemonTask( void *pvParameter1, uint32_t ulParameter2 ); +void vPrintStringFromDaemonTask(void *pvParameter1, uint32_t ulParameter2); /* The service routine for the (simulated) interrupt. This is the interrupt that sets an event bit in the event group. */ @@ -56,205 +56,205 @@ static u32 cpu_id = 0; /* Declare the event group in which bits are set from both a task and an ISR. */ static EventGroupHandle_t xEventGroup; -void CreateManagementTasks( void ) +void CreateManagementTasks(void) { - /* Before an event group can be used it must first be created. */ - xEventGroup = xEventGroupCreate(); - vSetupSoftwareInterrupt(); + /* Before an event group can be used it must first be created. */ + xEventGroup = xEventGroupCreate(); + vSetupSoftwareInterrupt(); - /* Create the task that sets event bits in the event group. */ - xTaskCreate( vEventBitSettingTask, "Manage BitSetter", TASK_STACK_SIZE, NULL, 1, &xtask1_handle ); + /* Create the task that sets event bits in the event group. */ + xTaskCreate(vEventBitSettingTask, "Manage BitSetter", TASK_STACK_SIZE, NULL, 1, &xtask1_handle); - /* Create the task that waits for event bits to get set in the event - group. */ - xTaskCreate( vEventBitReadingTask, "Manage BitReader", TASK_STACK_SIZE, NULL, 2, &xtask2_handle ); + /* Create the task that waits for event bits to get set in the event + group. */ + xTaskCreate(vEventBitReadingTask, "Manage BitReader", TASK_STACK_SIZE, NULL, 2, &xtask2_handle); - /* Create the task that is used to periodically generate a software - interrupt. */ - xTaskCreate( vIntegerGenerator, "Manage IntGen", TASK_STACK_SIZE, NULL, 3, &xtask3_handle ); + /* Create the task that is used to periodically generate a software + interrupt. */ + xTaskCreate(vIntegerGenerator, "Manage IntGen", TASK_STACK_SIZE, NULL, 3, &xtask3_handle); - /* Install the handler for the software interrupt. The syntax necessary - to do this is dependent on the FreeRTOS port being used. */ + /* Install the handler for the software interrupt. The syntax necessary + to do this is dependent on the FreeRTOS port being used. */ } void DeleteManagementTasks(void) { - if(xtask1_handle) + if (xtask1_handle) { vTaskDelete(xtask1_handle); vPrintString("Eventgroup management BitSetter deletion"); } - if(xtask2_handle) + if (xtask2_handle) { vTaskDelete(xtask2_handle); vPrintString("Eventgroup management BitReader deletion"); } - if(xtask3_handle) + if (xtask3_handle) { vTaskDelete(xtask3_handle); vPrintString("Eventgroup management IntGen deletion"); } - + } /*-----------------------------------------------------------*/ -static void vEventBitSettingTask( void *pvParameters ) +static void vEventBitSettingTask(void *pvParameters) { - const TickType_t xDelay = pdMS_TO_TICKS( 5000UL ), xDontBlock = 0; - - for( ;; ) - { - /* Delay for a short while before starting the next loop. */ - vTaskDelay( xDelay ); - - /* Print out a message to say event bit 0 is about to be set by the - task, then set event bit 0. */ - vPrintString( "Manage Bit setting task -\t about to set bit 0." ); - xEventGroupSetBits( xEventGroup, FIRST_TASK_BIT ); - - /* Delay for a short while before setting the other bit set within this - task. */ - vTaskDelay( xDelay ); - - /* Print out a message to say event bit 1 is about to be set by the - task, then set event bit 1. */ - vPrintString( "Manage Bit setting task -\t about to set bit 1." ); - xEventGroupSetBits( xEventGroup, SECOND_TASK_BIT ); - } + const TickType_t xDelay = pdMS_TO_TICKS(5000UL), xDontBlock = 0; + + for (;;) + { + /* Delay for a short while before starting the next loop. */ + vTaskDelay(xDelay); + + /* Print out a message to say event bit 0 is about to be set by the + task, then set event bit 0. */ + vPrintString("Manage Bit setting task -\t about to set bit 0."); + xEventGroupSetBits(xEventGroup, FIRST_TASK_BIT); + + /* Delay for a short while before setting the other bit set within this + task. */ + vTaskDelay(xDelay); + + /* Print out a message to say event bit 1 is about to be set by the + task, then set event bit 1. */ + vPrintString("Manage Bit setting task -\t about to set bit 1."); + xEventGroupSetBits(xEventGroup, SECOND_TASK_BIT); + } } /*-----------------------------------------------------------*/ static void ulEventBitSettingISR(s32 vector, void *param) { - BaseType_t xHigherPriorityTaskWoken; - /* The string is not printed within the interrupt service, but is instead - sent to the RTOS daemon task for printing. It is therefore declared static to - ensure the compiler does not allocate the string on the stack of the ISR (as the - ISR's stack frame will not exist when the string is printed from the daemon - task. */ - static const char *pcString = "Manage Bit setting ISR -\t about to set bit 2."; - - /* As always, xHigherPriorityTaskWoken is initialized to pdFALSE. */ - xHigherPriorityTaskWoken = pdFALSE; - - /* Print out a message to say bit 2 is about to be set. Messages cannot be - printed from an ISR, so defer the actual output to the RTOS daemon task by - pending a function call to run in the context of the RTOS daemon task. */ - xTimerPendFunctionCallFromISR( vPrintStringFromDaemonTask, ( void * ) pcString, 0, &xHigherPriorityTaskWoken ); - - /* Set bit 2 in the event group. */ - xEventGroupSetBitsFromISR( xEventGroup, ISR_BIT, &xHigherPriorityTaskWoken ); - - /* xEventGroupSetBitsFromISR() writes to the timer command queue. If - writing to the timer command queue results in the RTOS daemon task leaving - the Blocked state, and if the priority of the RTOS daemon task is higher - than the priority of the currently executing task (the task this interrupt - interrupted) then xHigherPriorityTaskWoken will have been set to pdTRUE - inside xEventGroupSetBitsFromISR(). - - xHigherPriorityTaskWoken is used as the parameter to portYIELD_FROM_ISR(). - If xHigherPriorityTaskWoken equals pdTRUE then calling portYIELD_FROM_ISR() + BaseType_t xHigherPriorityTaskWoken; + /* The string is not printed within the interrupt service, but is instead + sent to the RTOS daemon task for printing. It is therefore declared static to + ensure the compiler does not allocate the string on the stack of the ISR (as the + ISR's stack frame will not exist when the string is printed from the daemon + task. */ + static const char *pcString = "Manage Bit setting ISR -\t about to set bit 2."; + + /* As always, xHigherPriorityTaskWoken is initialized to pdFALSE. */ + xHigherPriorityTaskWoken = pdFALSE; + + /* Print out a message to say bit 2 is about to be set. Messages cannot be + printed from an ISR, so defer the actual output to the RTOS daemon task by + pending a function call to run in the context of the RTOS daemon task. */ + xTimerPendFunctionCallFromISR(vPrintStringFromDaemonTask, (void *) pcString, 0, &xHigherPriorityTaskWoken); + + /* Set bit 2 in the event group. */ + xEventGroupSetBitsFromISR(xEventGroup, ISR_BIT, &xHigherPriorityTaskWoken); + + /* xEventGroupSetBitsFromISR() writes to the timer command queue. If + writing to the timer command queue results in the RTOS daemon task leaving + the Blocked state, and if the priority of the RTOS daemon task is higher + than the priority of the currently executing task (the task this interrupt + interrupted) then xHigherPriorityTaskWoken will have been set to pdTRUE + inside xEventGroupSetBitsFromISR(). + + xHigherPriorityTaskWoken is used as the parameter to portYIELD_FROM_ISR(). + If xHigherPriorityTaskWoken equals pdTRUE then calling portYIELD_FROM_ISR() will request a context switch. If xHigherPriorityTaskWoken is still pdFALSE - then calling portYIELD_FROM_ISR() will have no effect. + then calling portYIELD_FROM_ISR() will have no effect. - The implementation of portYIELD_FROM_ISR() used by the Windows port includes - a return statement, which is why this function does not explicitly return a - value. */ - portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); + The implementation of portYIELD_FROM_ISR() used by the Windows port includes + a return statement, which is why this function does not explicitly return a + value. */ + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } /*-----------------------------------------------------------*/ -static void vEventBitReadingTask( void *pvParameters ) +static void vEventBitReadingTask(void *pvParameters) { - const EventBits_t xBitsToWaitFor = ( FIRST_TASK_BIT | SECOND_TASK_BIT | ISR_BIT ); - EventBits_t xEventGroupValue; - - for( ;; ) - { - /* Block to wait for event bits to become set within the event group. */ - xEventGroupValue = xEventGroupWaitBits( /* The event group to read. */ - xEventGroup, - - /* Bits to test. */ - xBitsToWaitFor, - - /* Clear bits on exit if the - unblock condition is met. */ - pdTRUE, - - /* Don't wait for all bits. */ - pdFALSE, - - /* Don't time out. */ - portMAX_DELAY ); - - /* Print a message for each bit that was set. */ - if( ( xEventGroupValue & FIRST_TASK_BIT ) != 0 ) - { - vPrintString( "Manage Bit reading task -\t event bit 0 was set" ); - } - - if( ( xEventGroupValue & SECOND_TASK_BIT ) != 0 ) - { - vPrintString( "Manage Bit reading task -\t event bit 1 was set" ); - } - - if( ( xEventGroupValue & ISR_BIT ) != 0 ) - { - vPrintString( "Manage Bit reading task -\t event bit 2 was set" ); - } - } + const EventBits_t xBitsToWaitFor = (FIRST_TASK_BIT | SECOND_TASK_BIT | ISR_BIT); + EventBits_t xEventGroupValue; + + for (;;) + { + /* Block to wait for event bits to become set within the event group. */ + xEventGroupValue = xEventGroupWaitBits( /* The event group to read. */ + xEventGroup, + + /* Bits to test. */ + xBitsToWaitFor, + + /* Clear bits on exit if the + unblock condition is met. */ + pdTRUE, + + /* Don't wait for all bits. */ + pdFALSE, + + /* Don't time out. */ + portMAX_DELAY); + + /* Print a message for each bit that was set. */ + if ((xEventGroupValue & FIRST_TASK_BIT) != 0) + { + vPrintString("Manage Bit reading task -\t event bit 0 was set"); + } + + if ((xEventGroupValue & SECOND_TASK_BIT) != 0) + { + vPrintString("Manage Bit reading task -\t event bit 1 was set"); + } + + if ((xEventGroupValue & ISR_BIT) != 0) + { + vPrintString("Manage Bit reading task -\t event bit 2 was set"); + } + } } /*-----------------------------------------------------------*/ -void vPrintStringFromDaemonTask( void *pvParameter1, uint32_t ulParameter2 ) +void vPrintStringFromDaemonTask(void *pvParameter1, uint32_t ulParameter2) { - /* The string to print is passed into this function using the pvParameter1 - parameter. */ - vPrintString( ( const char * ) pvParameter1 ); + /* The string to print is passed into this function using the pvParameter1 + parameter. */ + vPrintString((const char *) pvParameter1); } /*-----------------------------------------------------------*/ -static void vIntegerGenerator( void *pvParameters ) +static void vIntegerGenerator(void *pvParameters) { - TickType_t xLastExecutionTime; - const TickType_t xDelay = pdMS_TO_TICKS( 5000UL ); + TickType_t xLastExecutionTime; + const TickType_t xDelay = pdMS_TO_TICKS(5000UL); - /* Initialize the variable used by the call to vTaskDelayUntil(). */ - xLastExecutionTime = xTaskGetTickCount(); + /* Initialize the variable used by the call to vTaskDelayUntil(). */ + xLastExecutionTime = xTaskGetTickCount(); - for( ;; ) - { - /* This is a periodic task. Block until it is time to run again. - The task will execute every 500ms. */ - vTaskDelayUntil( &xLastExecutionTime, xDelay ); + for (;;) + { + /* This is a periodic task. Block until it is time to run again. + The task will execute every 500ms. */ + vTaskDelayUntil(&xLastExecutionTime, xDelay); - /* Generate the interrupt that will set a bit in the event group. */ - vTriggerInterrupt(); - } + /* Generate the interrupt that will set a bit in the event group. */ + vTriggerInterrupt(); + } } static void vSetupSoftwareInterrupt(void) { - - GetCpuId(&cpu_id); + + GetCpuId(&cpu_id); vPrintf("cpu_id is %d \r\n", cpu_id); - /* The interrupt service routine uses an (interrupt safe) FreeRTOS API - function so the interrupt priority must be at or below the priority defined - by configSYSCALL_INTERRUPT_PRIORITY. */ - InterruptSetPriority(INTERRUPT_ID, INTERRUPT_PRIORITY ); + /* The interrupt service routine uses an (interrupt safe) FreeRTOS API + function so the interrupt priority must be at or below the priority defined + by configSYSCALL_INTERRUPT_PRIORITY. */ + InterruptSetPriority(INTERRUPT_ID, INTERRUPT_PRIORITY); - InterruptInstall(INTERRUPT_ID, ulEventBitSettingISR, NULL, NULL); + InterruptInstall(INTERRUPT_ID, ulEventBitSettingISR, NULL, NULL); - /* Enable the interrupt. */ - InterruptUmask( INTERRUPT_ID ); + /* Enable the interrupt. */ + InterruptUmask(INTERRUPT_ID); } /* Macro to force an interrupt. */ static void vTriggerInterrupt(void) { - InterruptCoreInterSend(INTERRUPT_ID, (1 << cpu_id)); + InterruptCoreInterSend(INTERRUPT_ID, (1 << cpu_id)); } diff --git a/example/freertos_feature/eventgroup/src/synchronization.c b/example/freertos_feature/eventgroup/src/synchronization.c index 4ed91ec9..6d2afbac 100644 --- a/example/freertos_feature/eventgroup/src/synchronization.c +++ b/example/freertos_feature/eventgroup/src/synchronization.c @@ -1,7 +1,7 @@ /* This example demonstrates how to: -uses xEventGroupSync() to synchronize three instances of a single task implementation. -The task parameter is used to pass into each instance the event bit the task will +uses xEventGroupSync() to synchronize three instances of a single task implementation. +The task parameter is used to pass into each instance the event bit the task will set when it calls xEventGroupSync(). */ #include @@ -13,20 +13,20 @@ static xTaskHandle xtask1_handle; static xTaskHandle xtask2_handle; static xTaskHandle xtask3_handle; -#define TASK_STACK_SIZE 1024 +#define TASK_STACK_SIZE 1024 /* Definitions for the event bits in the event group. */ -#define FIRST_TASK_BIT ( 1UL << 0UL ) /* Event bit 0, which is set by the first task. */ -#define SECOND_TASK_BIT ( 1UL << 1UL ) /* Event bit 1, which is set by the second task. */ -#define THIRD_TASK_BIT ( 1UL << 2UL ) /* Event bit 2, which is set by the third task. */ +#define FIRST_TASK_BIT ( 1UL << 0UL ) /* Event bit 0, which is set by the first task. */ +#define SECOND_TASK_BIT ( 1UL << 1UL ) /* Event bit 1, which is set by the second task. */ +#define THIRD_TASK_BIT ( 1UL << 2UL ) /* Event bit 2, which is set by the third task. */ /* Pseudo random number generation functions - implemented in this file as the MSVC rand() function has unexpected consequences. */ -static uint32_t prvRand( void ); -static void prvSRand( uint32_t ulSeed ); +static uint32_t prvRand(void); +static void prvSRand(uint32_t ulSeed); /* Three instances of this task are created. */ -static void vSyncingTask( void *pvParameters ); +static void vSyncingTask(void *pvParameters); /*-----------------------------------------------------------*/ @@ -36,123 +36,123 @@ static uint32_t ulNextRand; /* Declare the event group used to synchronize the three tasks. */ static EventGroupHandle_t xEventGroup; -void CreateSyncTasks( void ) +void CreateSyncTasks(void) { - /* The tasks created in this example block for a random time. The block - time is generated using rand() - seed the random number generator. */ - prvSRand( ( uint32_t ) time( NULL ) ); - - /* Before an event group can be used it must first be created. */ - xEventGroup = xEventGroupCreate(); - - /* Create three instances of the task. Each task is given a different name, - which is later printed out to give a visual indication of which task is - executing. The event bit to use when the task reaches its synchronization - point is passed into the task using the task parameter. */ - xTaskCreate( vSyncingTask, "Sync Task 1", TASK_STACK_SIZE, ( void * ) FIRST_TASK_BIT, 1, &xtask1_handle ); - xTaskCreate( vSyncingTask, "Sync Task 2", TASK_STACK_SIZE, ( void * ) SECOND_TASK_BIT, 1, &xtask2_handle ); - xTaskCreate( vSyncingTask, "Sync Task 3", TASK_STACK_SIZE, ( void * ) THIRD_TASK_BIT, 1, &xtask3_handle ); + /* The tasks created in this example block for a random time. The block + time is generated using rand() - seed the random number generator. */ + prvSRand((uint32_t) time(NULL)); + + /* Before an event group can be used it must first be created. */ + xEventGroup = xEventGroupCreate(); + + /* Create three instances of the task. Each task is given a different name, + which is later printed out to give a visual indication of which task is + executing. The event bit to use when the task reaches its synchronization + point is passed into the task using the task parameter. */ + xTaskCreate(vSyncingTask, "Sync Task 1", TASK_STACK_SIZE, (void *) FIRST_TASK_BIT, 1, &xtask1_handle); + xTaskCreate(vSyncingTask, "Sync Task 2", TASK_STACK_SIZE, (void *) SECOND_TASK_BIT, 1, &xtask2_handle); + xTaskCreate(vSyncingTask, "Sync Task 3", TASK_STACK_SIZE, (void *) THIRD_TASK_BIT, 1, &xtask3_handle); } void DeleteSyncTasks(void) { - if(xtask1_handle) + if (xtask1_handle) { vTaskDelete(xtask1_handle); vPrintString("Eventgroup Sync Task 1 deletion \r\n"); } - if(xtask2_handle) + if (xtask2_handle) { vTaskDelete(xtask2_handle); vPrintString("Eventgroup Sync Task 2 deletion \r\n"); } - if(xtask3_handle) + if (xtask3_handle) { vTaskDelete(xtask3_handle); vPrintString("Eventgroup Sync Task 3 deletion \r\n"); } - + } /*-----------------------------------------------------------*/ -static void vSyncingTask( void *pvParameters ) +static void vSyncingTask(void *pvParameters) { - const EventBits_t uxAllSyncBits = ( FIRST_TASK_BIT | SECOND_TASK_BIT | THIRD_TASK_BIT ); - const TickType_t xMaxDelay = pdMS_TO_TICKS( 500UL ); - const TickType_t xMinDelay = pdMS_TO_TICKS( 4000UL ); - TickType_t xDelayTime; - EventBits_t uxThisTasksSyncBit; - - /* Three instances of this task are created - each task uses a different - event bit in the synchronization. The event bit to use by this task - instance is passed into the task using the task's parameter. Store it in - the uxThisTasksSyncBit variable. */ - uxThisTasksSyncBit = ( EventBits_t ) pvParameters; - - for( ;; ) - { - /* Simulate this task taking some time to perform an action by delaying - for a pseudo random time. This prevents all three instances of this - task from reaching the synchronization point at the same time, and - allows the example's behavior to be observed more easily. */ - xDelayTime = ( prvRand() % xMaxDelay ) + xMinDelay; - vTaskDelay( xDelayTime ); - - /* Print out a message to show this task has reached its synchronization - point. pcTaskGetTaskName() is an API function that returns the name - assigned to the task when the task was created. */ - vPrintString( pcTaskGetTaskName( NULL ) ); - vPrintString( " reached sync point\n"); - - /* Wait for all the tasks to have reached their respective - synchronization points. */ - xEventGroupSync( /* The event group used to synchronize. */ - xEventGroup, - - /* The bit set by this task to indicate it has reached - the synchronization point. */ - uxThisTasksSyncBit, - - /* The bits to wait for, one bit for each task taking - part in the synchronization. */ - uxAllSyncBits, - - /* Wait indefinitely for all three tasks to reach the - synchronization point. */ - portMAX_DELAY ); - - /* Print out a message to show this task has passed its synchronization - point. As an indefinite delay was used the following line will only be - reached after all the tasks reached their respective synchronization - points. */ - vPrintString( pcTaskGetTaskName( NULL ) ); - vPrintString( " exited sync point\n"); - - } + const EventBits_t uxAllSyncBits = (FIRST_TASK_BIT | SECOND_TASK_BIT | THIRD_TASK_BIT); + const TickType_t xMaxDelay = pdMS_TO_TICKS(500UL); + const TickType_t xMinDelay = pdMS_TO_TICKS(4000UL); + TickType_t xDelayTime; + EventBits_t uxThisTasksSyncBit; + + /* Three instances of this task are created - each task uses a different + event bit in the synchronization. The event bit to use by this task + instance is passed into the task using the task's parameter. Store it in + the uxThisTasksSyncBit variable. */ + uxThisTasksSyncBit = (EventBits_t) pvParameters; + + for (;;) + { + /* Simulate this task taking some time to perform an action by delaying + for a pseudo random time. This prevents all three instances of this + task from reaching the synchronization point at the same time, and + allows the example's behavior to be observed more easily. */ + xDelayTime = (prvRand() % xMaxDelay) + xMinDelay; + vTaskDelay(xDelayTime); + + /* Print out a message to show this task has reached its synchronization + point. pcTaskGetTaskName() is an API function that returns the name + assigned to the task when the task was created. */ + vPrintString(pcTaskGetTaskName(NULL)); + vPrintString(" reached sync point\n"); + + /* Wait for all the tasks to have reached their respective + synchronization points. */ + xEventGroupSync( /* The event group used to synchronize. */ + xEventGroup, + + /* The bit set by this task to indicate it has reached + the synchronization point. */ + uxThisTasksSyncBit, + + /* The bits to wait for, one bit for each task taking + part in the synchronization. */ + uxAllSyncBits, + + /* Wait indefinitely for all three tasks to reach the + synchronization point. */ + portMAX_DELAY); + + /* Print out a message to show this task has passed its synchronization + point. As an indefinite delay was used the following line will only be + reached after all the tasks reached their respective synchronization + points. */ + vPrintString(pcTaskGetTaskName(NULL)); + vPrintString(" exited sync point\n"); + + } } /*-----------------------------------------------------------*/ -static uint32_t prvRand( void ) +static uint32_t prvRand(void) { - const uint32_t ulMultiplier = 0x015a4e35UL, ulIncrement = 1UL; - uint32_t ulReturn; - - /* Utility function to generate a pseudo random number as the MSVC rand() - function has unexpected consequences. */ - taskENTER_CRITICAL(); - ulNextRand = ( ulMultiplier * ulNextRand ) + ulIncrement; - ulReturn = ( ulNextRand >> 16UL ) & 0x7fffUL; - taskEXIT_CRITICAL(); - return ulReturn; + const uint32_t ulMultiplier = 0x015a4e35UL, ulIncrement = 1UL; + uint32_t ulReturn; + + /* Utility function to generate a pseudo random number as the MSVC rand() + function has unexpected consequences. */ + taskENTER_CRITICAL(); + ulNextRand = (ulMultiplier * ulNextRand) + ulIncrement; + ulReturn = (ulNextRand >> 16UL) & 0x7fffUL; + taskEXIT_CRITICAL(); + return ulReturn; } /*-----------------------------------------------------------*/ -static void prvSRand( uint32_t ulSeed ) +static void prvSRand(uint32_t ulSeed) { - /* Utility function to seed the pseudo random number generator. */ - ulNextRand = ulSeed; + /* Utility function to seed the pseudo random number generator. */ + ulNextRand = ulSeed; } /*-----------------------------------------------------------*/ diff --git a/example/freertos_feature/interrupt/configs/d2000_aarch32_eg_configs b/example/freertos_feature/interrupt/configs/d2000_aarch32_eg_configs index 464a31af..a16785ad 100644 --- a/example/freertos_feature/interrupt/configs/d2000_aarch32_eg_configs +++ b/example/freertos_feature/interrupt/configs/d2000_aarch32_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -111,6 +112,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -147,6 +157,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -168,12 +179,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -185,14 +190,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -210,4 +233,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/interrupt/configs/d2000_aarch64_eg_configs b/example/freertos_feature/interrupt/configs/d2000_aarch64_eg_configs index 64e6b4b7..4731ef2f 100644 --- a/example/freertos_feature/interrupt/configs/d2000_aarch64_eg_configs +++ b/example/freertos_feature/interrupt/configs/d2000_aarch64_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/interrupt/configs/e2000d_aarch32_eg_configs b/example/freertos_feature/interrupt/configs/e2000d_aarch32_eg_configs index fc31cd0b..22df4f8b 100644 --- a/example/freertos_feature/interrupt/configs/e2000d_aarch32_eg_configs +++ b/example/freertos_feature/interrupt/configs/e2000d_aarch32_eg_configs @@ -17,7 +17,7 @@ CONFIG_TARGET_ARMV8_AARCH32=y # CONFIG_TARGET_ARMV8_AARCH64 is not set CONFIG_USE_CACHE=y CONFIG_USE_MMU=y -# CONFIG_USE_SYS_TICK is not set +CONFIG_USE_SYS_TICK=y CONFIG_USE_AARCH64_L1_TO_AARCH32=y # end of Arch Configuration @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -77,9 +78,9 @@ CONFIG_USE_NEW_LIBC=y # # CONFIG_LOG_VERBOS is not set # CONFIG_LOG_DEBUG is not set -# CONFIG_LOG_INFO is not set +CONFIG_LOG_INFO=y # CONFIG_LOG_WARN is not set -CONFIG_LOG_ERROR=y +# CONFIG_LOG_ERROR is not set # CONFIG_LOG_NONE is not set CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y CONFIG_INTERRUPT_ROLE_MASTER=y @@ -95,7 +96,7 @@ CONFIG_AARCH32_RAM_LD=y # CONFIG_USER_DEFINED_LD is not set CONFIG_LINK_SCRIPT_ROM=y CONFIG_ROM_START_UP_ADDR=0x80100000 -CONFIG_ROM_SIZE_MB=2 +CONFIG_ROM_SIZE_MB=1 CONFIG_LINK_SCRIPT_RAM=y CONFIG_RAM_START_UP_ADDR=0x81000000 CONFIG_RAM_SIZE_MB=64 @@ -111,6 +112,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -147,6 +157,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -168,12 +179,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -185,14 +190,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -207,7 +230,30 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set # end of Letter Shell Configuration -CONFIG_USE_TLSF=y +# CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=12 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/interrupt/configs/e2000d_aarch64_eg_configs b/example/freertos_feature/interrupt/configs/e2000d_aarch64_eg_configs index 7e2efa4f..a4715cf0 100644 --- a/example/freertos_feature/interrupt/configs/e2000d_aarch64_eg_configs +++ b/example/freertos_feature/interrupt/configs/e2000d_aarch64_eg_configs @@ -17,7 +17,7 @@ CONFIG_USE_FREERTOS=y CONFIG_TARGET_ARMV8_AARCH64=y CONFIG_USE_CACHE=y CONFIG_USE_MMU=y -# CONFIG_USE_SYS_TICK is not set +CONFIG_USE_SYS_TICK=y # CONFIG_MMU_DEBUG_PRINTS is not set # end of Arch Configuration @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -77,9 +78,9 @@ CONFIG_USE_NEW_LIBC=y # # CONFIG_LOG_VERBOS is not set # CONFIG_LOG_DEBUG is not set -# CONFIG_LOG_INFO is not set +CONFIG_LOG_INFO=y # CONFIG_LOG_WARN is not set -CONFIG_LOG_ERROR=y +# CONFIG_LOG_ERROR is not set # CONFIG_LOG_NONE is not set CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y CONFIG_INTERRUPT_ROLE_MASTER=y @@ -95,7 +96,7 @@ CONFIG_AARCH64_RAM_LD=y # CONFIG_USER_DEFINED_LD is not set CONFIG_LINK_SCRIPT_ROM=y CONFIG_ROM_START_UP_ADDR=0x80100000 -CONFIG_ROM_SIZE_MB=2 +CONFIG_ROM_SIZE_MB=1 CONFIG_LINK_SCRIPT_RAM=y CONFIG_RAM_START_UP_ADDR=0x81000000 CONFIG_RAM_SIZE_MB=64 @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -203,7 +226,30 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set # end of Letter Shell Configuration -CONFIG_USE_TLSF=y +# CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=12 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/interrupt/configs/e2000q_aarch32_eg_configs b/example/freertos_feature/interrupt/configs/e2000q_aarch32_eg_configs index 2fe965a5..a786509e 100644 --- a/example/freertos_feature/interrupt/configs/e2000q_aarch32_eg_configs +++ b/example/freertos_feature/interrupt/configs/e2000q_aarch32_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -111,6 +112,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -147,6 +157,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -168,12 +179,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -185,14 +190,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -210,4 +233,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/interrupt/configs/e2000q_aarch64_eg_configs b/example/freertos_feature/interrupt/configs/e2000q_aarch64_eg_configs index 9c50f2b0..9183d77b 100644 --- a/example/freertos_feature/interrupt/configs/e2000q_aarch64_eg_configs +++ b/example/freertos_feature/interrupt/configs/e2000q_aarch64_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/interrupt/configs/ft2004_aarch32_eg_configs b/example/freertos_feature/interrupt/configs/ft2004_aarch32_eg_configs index 4c5b2c49..f0510b59 100644 --- a/example/freertos_feature/interrupt/configs/ft2004_aarch32_eg_configs +++ b/example/freertos_feature/interrupt/configs/ft2004_aarch32_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -111,6 +112,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -147,6 +157,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -168,12 +179,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -185,14 +190,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -210,4 +233,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/interrupt/configs/ft2004_aarch64_eg_configs b/example/freertos_feature/interrupt/configs/ft2004_aarch64_eg_configs index da9c1f81..d99e8ace 100644 --- a/example/freertos_feature/interrupt/configs/ft2004_aarch64_eg_configs +++ b/example/freertos_feature/interrupt/configs/ft2004_aarch64_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/interrupt/inc/feature_interrupt.h b/example/freertos_feature/interrupt/inc/feature_interrupt.h index 5e275bb8..a9da3688 100644 --- a/example/freertos_feature/interrupt/inc/feature_interrupt.h +++ b/example/freertos_feature/interrupt/inc/feature_interrupt.h @@ -1,30 +1,36 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: feature_interrupt.h * Date: 2022-06-17 10:42:40 * LastEditTime: 2022-06-17 10:42:40 - * Description: This file is for - * - * Modify History: + * Description: This file is for task function define + * + * Modify History: * Ver Who Date Changes * ----- ------ -------- -------------------------------------- + * 1.0 wangxiaodong 2022/08/09 first commit */ #ifndef FEATURE_INTERRUPT_H #define FEATURE_INTERRUPT_H +#ifdef __cplusplus +extern "C" +{ +#endif + /* interrupt task */ void CreateBinarySemTasks(void); void DeleteBinarySemTasks(void); @@ -35,4 +41,8 @@ void DeleteCountSemTasks(void); void CreateQueueTasks(void); void DeleteQueueTasks(void); +#ifdef __cplusplus +} +#endif + #endif // ! \ No newline at end of file diff --git a/example/freertos_feature/interrupt/main.c b/example/freertos_feature/interrupt/main.c index f376d838..481070c3 100644 --- a/example/freertos_feature/interrupt/main.c +++ b/example/freertos_feature/interrupt/main.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: main.c * Date: 2022-06-17 08:17:59 * LastEditTime: 2022-06-17 08:17:59 - * Description: This file is for - * - * Modify History: + * Description: This file is for interrupt example that running shell task and open scheduler + * + * Modify History: * Ver Who Date Changes * ----- ------ -------- -------------------------------------- + * */ #include "shell.h" @@ -30,13 +31,15 @@ int main(void) BaseType_t ret; ret = LSUserShellTask() ; - if(ret != pdPASS) + if (ret != pdPASS) + { goto FAIL_EXIT; + } - vTaskStartScheduler(); /* 启动任务,开启调度 */ + vTaskStartScheduler(); /* 启动任务,开启调度 */ while (1); /* 正常不会执行到这里 */ - + FAIL_EXIT: - printf("failed 0x%x \r\n", ret); + printf("Failed 0x%x. \r\n", ret); return 0; } diff --git a/example/freertos_feature/interrupt/sdkconfig b/example/freertos_feature/interrupt/sdkconfig index 9c50f2b0..9183d77b 100644 --- a/example/freertos_feature/interrupt/sdkconfig +++ b/example/freertos_feature/interrupt/sdkconfig @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/interrupt/sdkconfig.h b/example/freertos_feature/interrupt/sdkconfig.h index 2e55f772..80305bac 100644 --- a/example/freertos_feature/interrupt/sdkconfig.h +++ b/example/freertos_feature/interrupt/sdkconfig.h @@ -62,6 +62,7 @@ /* CONFIG_USE_ADC is not set */ /* CONFIG_USE_PWM is not set */ /* CONFIG_USE_IPC is not set */ +/* CONFIG_USE_MEDIA is not set */ /* end of Components Configuration */ #define CONFIG_USE_NEW_LIBC /* end of Standalone Setting */ @@ -98,6 +99,12 @@ /* Compiler Options */ +/* Cross-Compiler Setting */ + +#define CONFIG_GCC_OPTIMIZE_LEVEL 0 +/* CONFIG_USE_EXT_COMPILER is not set */ +/* CONFIG_USE_KLIN_SYS is not set */ +/* end of Cross-Compiler Setting */ #define CONFIG_OUTPUT_BINARY /* end of Compiler Options */ /* end of Building Option */ @@ -127,6 +134,7 @@ /* Freertos Eth Drivers */ /* CONFIG_FREERTOS_USE_XMAC is not set */ +/* CONFIG_FREERTOS_USE_GMAC is not set */ /* end of Freertos Eth Drivers */ /* Freertos Gpio Drivers */ @@ -145,11 +153,6 @@ /* CONFIG_FREERTOS_USE_FGDMA is not set */ /* end of Freertos DMA Drivers */ -/* Freertos MMC Drivers */ - -/* CONFIG_FREERTOS_USE_FSDIO is not set */ -/* end of Freertos MMC Drivers */ - /* Freertos Adc Drivers */ /* CONFIG_FREERTOS_USE_ADC is not set */ @@ -159,13 +162,28 @@ /* CONFIG_FREERTOS_USE_CAN is not set */ /* end of Freertos Can Drivers */ + +/* Freertos I2c Drivers */ + +/* CONFIG_FREERTOS_USE_I2C is not set */ +/* end of Freertos I2c Drivers */ + +/* Freertos Mio Drivers */ + +/* CONFIG_FREERTOS_USE_MIO is not set */ +/* end of Freertos Mio Drivers */ + +/* Freertos Timer Drivers */ + +/* CONFIG_FREERTOS_USE_TIMER is not set */ +/* end of Freertos Timer Drivers */ /* end of Component Configuration */ -/* FreeRTOS Setting */ +/* Third-Party Configuration */ /* CONFIG_USE_LWIP is not set */ #define CONFIG_USE_BACKTRACE -/* CONFIG_USE_FATFS is not set */ +/* CONFIG_USE_FATFS_0_1_4 is not set */ /* CONFIG_USE_SFUD is not set */ /* CONFIG_USE_SPIFFS is not set */ /* CONFIG_USE_AMP is not set */ @@ -181,6 +199,28 @@ /* CONFIG_USE_TLSF is not set */ /* CONFIG_USE_SDMMC_CMD is not set */ /* CONFIG_USE_CHERRY_USB is not set */ -/* end of FreeRTOS Setting */ +/* end of Third-Party Configuration */ + +/* Kernel Configuration */ + +#define CONFIG_FREERTOS_OPTIMIZED_SCHEDULER +#define CONFIG_FREERTOS_HZ 1000 +#define CONFIG_FREERTOS_MAX_PRIORITIES 32 +#define CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES 13 +#define CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES 11 +#define CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS 1 +#define CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE 1024 +#define CONFIG_FREERTOS_MAX_TASK_NAME_LEN 32 +#define CONFIG_FREERTOS_TIMER_TASK_PRIORITY 1 +#define CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH 2048 +#define CONFIG_FREERTOS_TIMER_QUEUE_LENGTH 10 +#define CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE 0 +#define CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS +#define CONFIG_FREERTOS_USE_TRACE_FACILITY +#define CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS +/* CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set */ +#define CONFIG_FREERTOS_TOTAL_HEAP_SIZE 10240 +#define CONFIG_FREERTOS_TASK_FPU_SUPPORT 1 +/* end of Kernel Configuration */ #endif diff --git a/example/freertos_feature/interrupt/src/binary_semaphore.c b/example/freertos_feature/interrupt/src/binary_semaphore.c index 6752e0ee..51ba4897 100644 --- a/example/freertos_feature/interrupt/src/binary_semaphore.c +++ b/example/freertos_feature/interrupt/src/binary_semaphore.c @@ -11,12 +11,12 @@ static xTaskHandle xtask1_handle; static xTaskHandle xtask2_handle; -#define TASK_STACK_SIZE 1024 +#define TASK_STACK_SIZE 1024 /* The interrupt number to use for the software interrupt generation. This could be any unused number. In this case the first chip level (non system) interrupt is used */ -#define INTERRUPT_ID 0 +#define INTERRUPT_ID 0 /* The priority of the software interrupt. The interrupt service routine uses an (interrupt safe) FreeRTOS API function, so the priority of the interrupt must @@ -24,7 +24,7 @@ be equal to or lower than the priority set by configMAX_SYSCALL_INTERRUPT_PRIORITY - remembering that on the Cortex M3 high numeric values represent low priority values, which can be confusing as it is counter intuitive. */ -#define INTERRUPT_PRIORITY IRQ_PRIORITY_VALUE_12 +#define INTERRUPT_PRIORITY IRQ_PRIORITY_VALUE_12 /* Macro to force an interrupt. */ static void vTriggerInterrupt(void); @@ -35,82 +35,82 @@ xSemaphoreHandle xBinarySemaphore; void vPeriodicTask(void *pvParameters) { - for (;;) - { - vTaskDelay(5000 / portTICK_RATE_MS); - printf("Bin Periodic task - Generate an interrupt.\n"); - vTriggerInterrupt(); - } + for (;;) + { + vTaskDelay(5000 / portTICK_RATE_MS); + printf("Bin Periodic task - Generate an interrupt.\n"); + vTriggerInterrupt(); + } } void vSemTakeTask(void *pvParameters) { - xSemaphoreTake(xBinarySemaphore, 0); - for (;;) - { - xSemaphoreTake(xBinarySemaphore, portMAX_DELAY); - printf("Bin Handler task - Processing event.\n"); - } + xSemaphoreTake(xBinarySemaphore, 0); + for (;;) + { + xSemaphoreTake(xBinarySemaphore, portMAX_DELAY); + printf("Bin Handler task - Processing event.\n"); + } } static void vInterruptHandler(s32 vector, void *param) { - portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; - - xSemaphoreGiveFromISR(xBinarySemaphore, &xHigherPriorityTaskWoken); + portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; + + xSemaphoreGiveFromISR(xBinarySemaphore, &xHigherPriorityTaskWoken); - /* never call taskYIELD() form ISR! */ - portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); + /* never call taskYIELD() form ISR! */ + portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); } static void prvSetupSoftwareInterrupt() { - GetCpuId(&cpu_id); + GetCpuId(&cpu_id); vPrintf("cpu_id is %d \r\n", cpu_id); - /* The interrupt service routine uses an (interrupt safe) FreeRTOS API - function so the interrupt priority must be at or below the priority defined - by configSYSCALL_INTERRUPT_PRIORITY. */ - InterruptSetPriority(INTERRUPT_ID, INTERRUPT_PRIORITY ); + /* The interrupt service routine uses an (interrupt safe) FreeRTOS API + function so the interrupt priority must be at or below the priority defined + by configSYSCALL_INTERRUPT_PRIORITY. */ + InterruptSetPriority(INTERRUPT_ID, INTERRUPT_PRIORITY); - InterruptInstall(INTERRUPT_ID, vInterruptHandler, NULL, NULL); + InterruptInstall(INTERRUPT_ID, vInterruptHandler, NULL, NULL); - /* Enable the interrupt. */ - InterruptUmask(INTERRUPT_ID ); + /* Enable the interrupt. */ + InterruptUmask(INTERRUPT_ID); } /* Macro to force an interrupt. */ static void vTriggerInterrupt(void) { - InterruptCoreInterSend(INTERRUPT_ID, (1 << cpu_id)); + InterruptCoreInterSend(INTERRUPT_ID, (1 << cpu_id)); } void CreateBinarySemTasks(void) { - vSemaphoreCreateBinary(xBinarySemaphore); - - if (xBinarySemaphore != NULL) - { - prvSetupSoftwareInterrupt(); - xTaskCreate(vSemTakeTask, "BinHandler", TASK_STACK_SIZE, NULL, 3, &xtask1_handle); - xTaskCreate(vPeriodicTask, "BinPeriodic", TASK_STACK_SIZE, NULL, 1, &xtask2_handle); - } - + vSemaphoreCreateBinary(xBinarySemaphore); + + if (xBinarySemaphore != NULL) + { + prvSetupSoftwareInterrupt(); + xTaskCreate(vSemTakeTask, "BinHandler", TASK_STACK_SIZE, NULL, 3, &xtask1_handle); + xTaskCreate(vPeriodicTask, "BinPeriodic", TASK_STACK_SIZE, NULL, 1, &xtask2_handle); + } + } void DeleteBinarySemTasks(void) { - if(xtask1_handle) + if (xtask1_handle) { vTaskDelete(xtask1_handle); printf("Bin Handler deletion \r\n"); } - if(xtask2_handle) + if (xtask2_handle) { vTaskDelete(xtask2_handle); printf("Bin Periodic deletion \r\n"); } - + } \ No newline at end of file diff --git a/example/freertos_feature/interrupt/src/counting_semaphore.c b/example/freertos_feature/interrupt/src/counting_semaphore.c index 38a9c61d..30bf69b1 100644 --- a/example/freertos_feature/interrupt/src/counting_semaphore.c +++ b/example/freertos_feature/interrupt/src/counting_semaphore.c @@ -1,4 +1,3 @@ - #include #include "FreeRTOSConfig.h" #include "FreeRTOS.h" @@ -12,12 +11,12 @@ static xTaskHandle xtask1_handle; static xTaskHandle xtask2_handle; -#define TASK_STACK_SIZE 1024 +#define TASK_STACK_SIZE 1024 /* The interrupt number to use for the software interrupt generation. This could be any unused number. In this case the first chip level (non system) interrupt is used */ -#define INTERRUPT_ID 0 +#define INTERRUPT_ID 0 /* The priority of the software interrupt. The interrupt service routine uses an (interrupt safe) FreeRTOS API function, so the priority of the interrupt must @@ -25,7 +24,7 @@ be equal to or lower than the priority set by configMAX_SYSCALL_INTERRUPT_PRIORITY - remembering that on the Cortex M3 high numeric values represent low priority values, which can be confusing as it is counter intuitive. */ -#define INTERRUPT_PRIORITY IRQ_PRIORITY_VALUE_12 +#define INTERRUPT_PRIORITY IRQ_PRIORITY_VALUE_12 /* Macro to force an interrupt. */ static void vTriggerInterrupt(void); @@ -36,85 +35,85 @@ xSemaphoreHandle xCountingSemaphore; static void vPeriodicTask(void *pvParameters) { - for (;;) - { - vTaskDelay(5000 / portTICK_RATE_MS); - printf("Count Periodic task - About to generate an interrupt.\n"); - vTriggerInterrupt(); - printf("Count Periodic task - Interrupt generated.\n\n"); + for (;;) + { + vTaskDelay(5000 / portTICK_RATE_MS); + printf("Count Periodic task - About to generate an interrupt.\n"); + vTriggerInterrupt(); + printf("Count Periodic task - Interrupt generated.\n\n"); } } static void vSemTakeTask(void *pvParameters) { - xSemaphoreTake(xCountingSemaphore, 0); + xSemaphoreTake(xCountingSemaphore, 0); - for (;;) - { - xSemaphoreTake(xCountingSemaphore, portMAX_DELAY); - printf("Count Handler task - Processing event, sem_count: %d\n", uxSemaphoreGetCount(xCountingSemaphore)); - } + for (;;) + { + xSemaphoreTake(xCountingSemaphore, portMAX_DELAY); + printf("Count Handler task - Processing event, sem_count: %d\n", uxSemaphoreGetCount(xCountingSemaphore)); + } } -static void vInterruptHandler(s32 vector, void *param) +static void vInterruptHandler(s32 vector, void *param) { - portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; + portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; - /* simulating multiple interrupts */ - xSemaphoreGiveFromISR(xCountingSemaphore, &xHigherPriorityTaskWoken); - xSemaphoreGiveFromISR(xCountingSemaphore, &xHigherPriorityTaskWoken); - xSemaphoreGiveFromISR(xCountingSemaphore, &xHigherPriorityTaskWoken); + /* simulating multiple interrupts */ + xSemaphoreGiveFromISR(xCountingSemaphore, &xHigherPriorityTaskWoken); + xSemaphoreGiveFromISR(xCountingSemaphore, &xHigherPriorityTaskWoken); + xSemaphoreGiveFromISR(xCountingSemaphore, &xHigherPriorityTaskWoken); - /* never call taskYIELD() form ISR! */ - portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); + /* never call taskYIELD() form ISR! */ + portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); } static void prvSetupSoftwareInterrupt(void) { - GetCpuId(&cpu_id); + GetCpuId(&cpu_id); vPrintf("cpu_id is %d \r\n", cpu_id); - - InterruptSetPriority(INTERRUPT_ID, INTERRUPT_PRIORITY ); - InterruptInstall(INTERRUPT_ID, vInterruptHandler, NULL, NULL); + InterruptSetPriority(INTERRUPT_ID, INTERRUPT_PRIORITY); - /* Enable the interrupt. */ - InterruptUmask( INTERRUPT_ID ); + InterruptInstall(INTERRUPT_ID, vInterruptHandler, NULL, NULL); + + /* Enable the interrupt. */ + InterruptUmask(INTERRUPT_ID); } /* Macro to force an interrupt. */ static void vTriggerInterrupt(void) { - InterruptCoreInterSend(INTERRUPT_ID, (1 << cpu_id)); + InterruptCoreInterSend(INTERRUPT_ID, (1 << cpu_id)); } void CreateCountSemTasks(void) { - xCountingSemaphore = xSemaphoreCreateCounting(10, 0); + xCountingSemaphore = xSemaphoreCreateCounting(10, 0); - if (xCountingSemaphore != NULL) - { - prvSetupSoftwareInterrupt(); + if (xCountingSemaphore != NULL) + { + prvSetupSoftwareInterrupt(); - xTaskCreate(vSemTakeTask, "CountHandler", TASK_STACK_SIZE, NULL, 3, &xtask1_handle); - xTaskCreate(vPeriodicTask, "CountPeriodic", TASK_STACK_SIZE, NULL, 1, &xtask2_handle); - } + xTaskCreate(vSemTakeTask, "CountHandler", TASK_STACK_SIZE, NULL, 3, &xtask1_handle); + xTaskCreate(vPeriodicTask, "CountPeriodic", TASK_STACK_SIZE, NULL, 1, &xtask2_handle); + } } void DeleteCountSemTasks(void) { - if(xtask1_handle) + if (xtask1_handle) { vTaskDelete(xtask1_handle); printf("Count Handler deletion \r\n"); } - if(xtask2_handle) + if (xtask2_handle) { vTaskDelete(xtask2_handle); printf("Count Periodic deletion \r\n"); } - + } diff --git a/example/freertos_feature/interrupt/src/interrupt_cmd.c b/example/freertos_feature/interrupt/src/interrupt_cmd.c index 8916b292..3eef59ac 100644 --- a/example/freertos_feature/interrupt/src/interrupt_cmd.c +++ b/example/freertos_feature/interrupt/src/interrupt_cmd.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: interrupt_cmd.c * Date: 2022-06-17 10:41:45 * LastEditTime: 2022-06-17 10:41:45 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for interrupt command interface + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 wangxiaodong 2022/08/09 first commit */ #include "shell.h" #include @@ -35,19 +36,19 @@ typedef enum static void CreateIntrCmdUsage(void) { - printf("usage:\r\n"); + printf("Usage:\r\n"); printf(" intr bin_cre \r\n"); - printf(" -- create intr binary sem tasks now\r\n"); + printf(" -- Create intr binary sem tasks now.\r\n"); printf(" intr bin_del \r\n"); - printf(" -- del intr binary sem tasks now\r\n"); + printf(" -- Del intr binary sem tasks now.\r\n"); printf(" intr count_cre \r\n"); - printf(" -- create counting sem tasks now\r\n"); + printf(" -- Create counting sem tasks now.\r\n"); printf(" intr count_del \r\n"); - printf(" -- del counting sem tasks now\r\n"); + printf(" -- Del counting sem tasks now.\r\n"); printf(" intr queue_cre \r\n"); - printf(" -- create queue tasks now\r\n"); + printf(" -- Create queue tasks now.\r\n"); printf(" intr queue_del \r\n"); - printf(" -- del queue tasks now\r\n"); + printf(" -- Del queue tasks now.\r\n"); } int CreateIntrCmd(int argc, char *argv[]) @@ -62,79 +63,79 @@ int CreateIntrCmd(int argc, char *argv[]) if (!strcmp(argv[1], "bin_cre")) { - if(create_flg[BINARY_SEM_TASK_INDEX] == 0) + if (create_flg[BINARY_SEM_TASK_INDEX] == 0) { CreateBinarySemTasks(); create_flg[BINARY_SEM_TASK_INDEX] = 1; } else { - printf("Please use bin_del cmd first \r\n"); + printf("Please use bin_del cmd first. \r\n"); } } else if (!strcmp(argv[1], "bin_del")) { - if(create_flg[BINARY_SEM_TASK_INDEX] == 1) + if (create_flg[BINARY_SEM_TASK_INDEX] == 1) { DeleteBinarySemTasks(); create_flg[BINARY_SEM_TASK_INDEX] = 0; - } + } else { - printf("Please use bin_cre cmd first \r\n"); + printf("Please use bin_cre cmd first. \r\n"); } } else if (!strcmp(argv[1], "count_cre")) { - if(create_flg[COUNT_SEM_TASK_INDEX] == 0) + if (create_flg[COUNT_SEM_TASK_INDEX] == 0) { CreateCountSemTasks(); create_flg[COUNT_SEM_TASK_INDEX] = 1; } else { - printf("Please use count_del cmd first \r\n"); + printf("Please use count_del cmd first. \r\n"); } } else if (!strcmp(argv[1], "count_del")) { - if(create_flg[COUNT_SEM_TASK_INDEX] == 1) + if (create_flg[COUNT_SEM_TASK_INDEX] == 1) { DeleteCountSemTasks(); create_flg[COUNT_SEM_TASK_INDEX] = 0; - } + } else { - printf("Please use count_cre cmd first \r\n"); + printf("Please use count_cre cmd first. \r\n"); } } else if (!strcmp(argv[1], "queue_cre")) { - if(create_flg[QUEUE_TASK_INDEX] == 0) + if (create_flg[QUEUE_TASK_INDEX] == 0) { CreateQueueTasks(); create_flg[QUEUE_TASK_INDEX] = 1; } else { - printf("Please use queue_del cmd first \r\n"); + printf("Please use queue_del cmd first. \r\n"); } } else if (!strcmp(argv[1], "queue_del")) { - if(create_flg[QUEUE_TASK_INDEX] == 1) + if (create_flg[QUEUE_TASK_INDEX] == 1) { DeleteQueueTasks(); create_flg[QUEUE_TASK_INDEX] = 0; - } + } else { - printf("Please use queue_cre cmd first \r\n"); + printf("Please use queue_cre cmd first. \r\n"); } } else { - printf("Error: Invalid arguments \r\n"); + printf("Error: Invalid arguments. \r\n"); CreateIntrCmdUsage(); } return 0; diff --git a/example/freertos_feature/interrupt/src/queue_from_interrupt.c b/example/freertos_feature/interrupt/src/queue_from_interrupt.c index c504a690..079f48f1 100644 --- a/example/freertos_feature/interrupt/src/queue_from_interrupt.c +++ b/example/freertos_feature/interrupt/src/queue_from_interrupt.c @@ -11,12 +11,12 @@ static xTaskHandle xtask1_handle; static xTaskHandle xtask2_handle; -#define TASK_STACK_SIZE 1024 +#define TASK_STACK_SIZE 1024 /* The interrupt number to use for the software interrupt generation. This could be any unused number. In this case the first chip level (non system) interrupt is used */ -#define INTERRUPT_ID 0 +#define INTERRUPT_ID 0 /* The priority of the software interrupt. The interrupt service routine uses an (interrupt safe) FreeRTOS API function, so the priority of the interrupt must @@ -24,7 +24,7 @@ be equal to or lower than the priority set by configMAX_SYSCALL_INTERRUPT_PRIORITY - remembering that on the Cortex M3 high numeric values represent low priority values, which can be confusing as it is counter intuitive. */ -#define INTERRUPT_PRIORITY IRQ_PRIORITY_VALUE_12 +#define INTERRUPT_PRIORITY IRQ_PRIORITY_VALUE_12 /* Macro to force an interrupt. */ static void vTriggerInterrupt(void); @@ -36,106 +36,106 @@ static xQueueHandle xStringQueue; static void vIntegerGenerator(void *pvParameters) { - portTickType xLastExecutionTime; - unsigned long ulValueToSend = 0; - int i; + portTickType xLastExecutionTime; + unsigned long ulValueToSend = 0; + int i; - xLastExecutionTime = xTaskGetTickCount(); + xLastExecutionTime = xTaskGetTickCount(); - for (;;) - { - vTaskDelayUntil(&xLastExecutionTime, 5000 / portTICK_RATE_MS); + for (;;) + { + vTaskDelayUntil(&xLastExecutionTime, 5000 / portTICK_RATE_MS); - for (i = 0; i < 5; ++i) - { - xQueueSendToBack(xIntegerQueue, &ulValueToSend, 0); - ++ulValueToSend; - } + for (i = 0; i < 5; ++i) + { + xQueueSendToBack(xIntegerQueue, &ulValueToSend, 0); + ++ulValueToSend; + } - vPrintf("Queue Periodic task - About to generate an interrupt.\n"); - vTriggerInterrupt(); - vPrintf("Queue Periodic task - Interrupt generated.\n\n"); + vPrintf("Queue Periodic task - About to generate an interrupt.\n"); + vTriggerInterrupt(); + vPrintf("Queue Periodic task - Interrupt generated.\n\n"); } } -static void vInterruptHandler(s32 vector, void *param) +static void vInterruptHandler(s32 vector, void *param) { - portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; - static unsigned long ulReceivedNumber; - - static const char* pcStrings[] = - { - "String 0\n", - "String 1\n", - "String 2\n", - "String 3\n" - }; - - while (xQueueReceiveFromISR(xIntegerQueue, &ulReceivedNumber, - &xHigherPriorityTaskWoken) != errQUEUE_EMPTY) - { - - // last 2 bits: values 0-3 - ulReceivedNumber &= 0x03; - xQueueSendToBackFromISR(xStringQueue, &pcStrings[ulReceivedNumber], - &xHigherPriorityTaskWoken); - } - - // never call taskYIELD() form ISR! - portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); + portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; + static unsigned long ulReceivedNumber; + + static const char *pcStrings[] = + { + "String 0\n", + "String 1\n", + "String 2\n", + "String 3\n" + }; + + while (xQueueReceiveFromISR(xIntegerQueue, &ulReceivedNumber, + &xHigherPriorityTaskWoken) != errQUEUE_EMPTY) + { + + // last 2 bits: values 0-3 + ulReceivedNumber &= 0x03; + xQueueSendToBackFromISR(xStringQueue, &pcStrings[ulReceivedNumber], + &xHigherPriorityTaskWoken); + } + + // never call taskYIELD() form ISR! + portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); } -static void vStringPrinter(void * pvParameters) +static void vStringPrinter(void *pvParameters) { - char *pcString; + char *pcString; - for (;;) - { - xQueueReceive(xStringQueue, &pcString, portMAX_DELAY); - vPrintf("pcString = %s\n", pcString); - } + for (;;) + { + xQueueReceive(xStringQueue, &pcString, portMAX_DELAY); + vPrintf("pcString = %s\n", pcString); + } } static void prvSetupSoftwareInterrupt(void) { - GetCpuId(&cpu_id); + GetCpuId(&cpu_id); vPrintf("cpu_id is %d \r\n", cpu_id); - - InterruptSetPriority(INTERRUPT_ID, INTERRUPT_PRIORITY ); - InterruptInstall(INTERRUPT_ID, vInterruptHandler, NULL, NULL); + InterruptSetPriority(INTERRUPT_ID, INTERRUPT_PRIORITY); + + InterruptInstall(INTERRUPT_ID, vInterruptHandler, NULL, NULL); - /* Enable the interrupt. */ - InterruptUmask( INTERRUPT_ID ); + /* Enable the interrupt. */ + InterruptUmask(INTERRUPT_ID); } /* Macro to force an interrupt. */ static void vTriggerInterrupt(void) { - InterruptCoreInterSend(INTERRUPT_ID, (1 << cpu_id)); + InterruptCoreInterSend(INTERRUPT_ID, (1 << cpu_id)); } void CreateQueueTasks(void) { - xIntegerQueue = xQueueCreate(10, sizeof(unsigned long)); - xStringQueue = xQueueCreate(10, sizeof(char*)); + xIntegerQueue = xQueueCreate(10, sizeof(unsigned long)); + xStringQueue = xQueueCreate(10, sizeof(char *)); - prvSetupSoftwareInterrupt(); + prvSetupSoftwareInterrupt(); - xTaskCreate(vIntegerGenerator, "QueueIntGen", TASK_STACK_SIZE, NULL, 1, &xtask1_handle); - xTaskCreate(vStringPrinter, "QueueString", TASK_STACK_SIZE, NULL, 2, &xtask2_handle); + xTaskCreate(vIntegerGenerator, "QueueIntGen", TASK_STACK_SIZE, NULL, 1, &xtask1_handle); + xTaskCreate(vStringPrinter, "QueueString", TASK_STACK_SIZE, NULL, 2, &xtask2_handle); } void DeleteQueueTasks(void) { - if(xtask1_handle) + if (xtask1_handle) { vTaskDelete(xtask1_handle); printf("Queue IntGen deletion \r\n"); } - if(xtask2_handle) + if (xtask2_handle) { vTaskDelete(xtask2_handle); printf("Queue String deletion \r\n"); diff --git a/example/freertos_feature/queue/README.md b/example/freertos_feature/queue/README.md index ecbfe7c2..318ce632 100644 --- a/example/freertos_feature/queue/README.md +++ b/example/freertos_feature/queue/README.md @@ -133,12 +133,12 @@ bootelf -p 0x90100000 - 输入```queue struct_cre```,启动queue的struct类型数据的收发任务测试 - 输入```queue struct_del```,删除queue的struct类型数据的收发任务测试 -![struct](./figs/queue_set.png) +![struct](./figs/queue_struct.png) - 输入```queue set_cre```,启动queue的set函数使用,收发任务测试 - 输入```queue set_del```,删除queue的set函数使用,收发任务测试 -![set](./figs/queue_struct.png) +![set](./figs/queue_set.png) - 测试任务能够能正常创建和删除,输入```ps```查看任务状态正常,即测试正常 diff --git a/example/freertos_feature/queue/configs/d2000_aarch32_eg_configs b/example/freertos_feature/queue/configs/d2000_aarch32_eg_configs index 464a31af..a16785ad 100644 --- a/example/freertos_feature/queue/configs/d2000_aarch32_eg_configs +++ b/example/freertos_feature/queue/configs/d2000_aarch32_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -111,6 +112,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -147,6 +157,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -168,12 +179,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -185,14 +190,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -210,4 +233,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/queue/configs/d2000_aarch64_eg_configs b/example/freertos_feature/queue/configs/d2000_aarch64_eg_configs index 64e6b4b7..4731ef2f 100644 --- a/example/freertos_feature/queue/configs/d2000_aarch64_eg_configs +++ b/example/freertos_feature/queue/configs/d2000_aarch64_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/queue/configs/e2000d_aarch32_eg_configs b/example/freertos_feature/queue/configs/e2000d_aarch32_eg_configs index fc31cd0b..22902270 100644 --- a/example/freertos_feature/queue/configs/e2000d_aarch32_eg_configs +++ b/example/freertos_feature/queue/configs/e2000d_aarch32_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -111,6 +112,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -147,6 +157,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -168,12 +179,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -185,14 +190,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -210,4 +233,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/queue/configs/e2000d_aarch64_eg_configs b/example/freertos_feature/queue/configs/e2000d_aarch64_eg_configs index 7e2efa4f..f3181d35 100644 --- a/example/freertos_feature/queue/configs/e2000d_aarch64_eg_configs +++ b/example/freertos_feature/queue/configs/e2000d_aarch64_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/queue/configs/e2000q_aarch32_eg_configs b/example/freertos_feature/queue/configs/e2000q_aarch32_eg_configs index 2fe965a5..a786509e 100644 --- a/example/freertos_feature/queue/configs/e2000q_aarch32_eg_configs +++ b/example/freertos_feature/queue/configs/e2000q_aarch32_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -111,6 +112,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -147,6 +157,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -168,12 +179,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -185,14 +190,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -210,4 +233,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/queue/configs/e2000q_aarch64_eg_configs b/example/freertos_feature/queue/configs/e2000q_aarch64_eg_configs index 9c50f2b0..9183d77b 100644 --- a/example/freertos_feature/queue/configs/e2000q_aarch64_eg_configs +++ b/example/freertos_feature/queue/configs/e2000q_aarch64_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/queue/configs/ft2004_aarch32_eg_configs b/example/freertos_feature/queue/configs/ft2004_aarch32_eg_configs index 4c5b2c49..f0510b59 100644 --- a/example/freertos_feature/queue/configs/ft2004_aarch32_eg_configs +++ b/example/freertos_feature/queue/configs/ft2004_aarch32_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -111,6 +112,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -147,6 +157,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -168,12 +179,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -185,14 +190,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -210,4 +233,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/queue/configs/ft2004_aarch64_eg_configs b/example/freertos_feature/queue/configs/ft2004_aarch64_eg_configs index da9c1f81..d99e8ace 100644 --- a/example/freertos_feature/queue/configs/ft2004_aarch64_eg_configs +++ b/example/freertos_feature/queue/configs/ft2004_aarch64_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/queue/inc/feature_queue.h b/example/freertos_feature/queue/inc/feature_queue.h index 378f9cca..7eb5872c 100644 --- a/example/freertos_feature/queue/inc/feature_queue.h +++ b/example/freertos_feature/queue/inc/feature_queue.h @@ -1,30 +1,36 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: feature_queue.h * Date: 2022-06-17 10:42:40 * LastEditTime: 2022-06-17 10:42:40 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for task function define + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 wangxiaodong 2022/08/09 first commit */ #ifndef FEATURE_QUEUE_H #define FEATURE_QUEUE_H +#ifdef __cplusplus +extern "C" +{ +#endif + /* queue task */ void CreateIntTasks(void); void DeleteIntTasks(void); @@ -35,4 +41,8 @@ void DeleteStructTasks(void); void CreateQueueSetTasks(void); void DeleteQueueSetTasks(void); +#ifdef __cplusplus +} +#endif + #endif // ! \ No newline at end of file diff --git a/example/freertos_feature/queue/main.c b/example/freertos_feature/queue/main.c index f376d838..7e219b2e 100644 --- a/example/freertos_feature/queue/main.c +++ b/example/freertos_feature/queue/main.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: main.c * Date: 2022-06-17 08:17:59 * LastEditTime: 2022-06-17 08:17:59 - * Description: This file is for - * - * Modify History: + * Description: This file is for queue example that running shell task and open scheduler + * + * Modify History: * Ver Who Date Changes * ----- ------ -------- -------------------------------------- + * 1.0 wangxiaodong 2022/06/20 first commit */ #include "shell.h" @@ -30,13 +31,15 @@ int main(void) BaseType_t ret; ret = LSUserShellTask() ; - if(ret != pdPASS) + if (ret != pdPASS) + { goto FAIL_EXIT; + } - vTaskStartScheduler(); /* 启动任务,开启调度 */ + vTaskStartScheduler(); /* 启动任务,开启调度 */ while (1); /* 正常不会执行到这里 */ - + FAIL_EXIT: - printf("failed 0x%x \r\n", ret); + printf("Failed 0x%x. \r\n", ret); return 0; } diff --git a/example/freertos_feature/queue/sdkconfig b/example/freertos_feature/queue/sdkconfig index 9c50f2b0..9183d77b 100644 --- a/example/freertos_feature/queue/sdkconfig +++ b/example/freertos_feature/queue/sdkconfig @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/queue/sdkconfig.h b/example/freertos_feature/queue/sdkconfig.h index 2e55f772..80305bac 100644 --- a/example/freertos_feature/queue/sdkconfig.h +++ b/example/freertos_feature/queue/sdkconfig.h @@ -62,6 +62,7 @@ /* CONFIG_USE_ADC is not set */ /* CONFIG_USE_PWM is not set */ /* CONFIG_USE_IPC is not set */ +/* CONFIG_USE_MEDIA is not set */ /* end of Components Configuration */ #define CONFIG_USE_NEW_LIBC /* end of Standalone Setting */ @@ -98,6 +99,12 @@ /* Compiler Options */ +/* Cross-Compiler Setting */ + +#define CONFIG_GCC_OPTIMIZE_LEVEL 0 +/* CONFIG_USE_EXT_COMPILER is not set */ +/* CONFIG_USE_KLIN_SYS is not set */ +/* end of Cross-Compiler Setting */ #define CONFIG_OUTPUT_BINARY /* end of Compiler Options */ /* end of Building Option */ @@ -127,6 +134,7 @@ /* Freertos Eth Drivers */ /* CONFIG_FREERTOS_USE_XMAC is not set */ +/* CONFIG_FREERTOS_USE_GMAC is not set */ /* end of Freertos Eth Drivers */ /* Freertos Gpio Drivers */ @@ -145,11 +153,6 @@ /* CONFIG_FREERTOS_USE_FGDMA is not set */ /* end of Freertos DMA Drivers */ -/* Freertos MMC Drivers */ - -/* CONFIG_FREERTOS_USE_FSDIO is not set */ -/* end of Freertos MMC Drivers */ - /* Freertos Adc Drivers */ /* CONFIG_FREERTOS_USE_ADC is not set */ @@ -159,13 +162,28 @@ /* CONFIG_FREERTOS_USE_CAN is not set */ /* end of Freertos Can Drivers */ + +/* Freertos I2c Drivers */ + +/* CONFIG_FREERTOS_USE_I2C is not set */ +/* end of Freertos I2c Drivers */ + +/* Freertos Mio Drivers */ + +/* CONFIG_FREERTOS_USE_MIO is not set */ +/* end of Freertos Mio Drivers */ + +/* Freertos Timer Drivers */ + +/* CONFIG_FREERTOS_USE_TIMER is not set */ +/* end of Freertos Timer Drivers */ /* end of Component Configuration */ -/* FreeRTOS Setting */ +/* Third-Party Configuration */ /* CONFIG_USE_LWIP is not set */ #define CONFIG_USE_BACKTRACE -/* CONFIG_USE_FATFS is not set */ +/* CONFIG_USE_FATFS_0_1_4 is not set */ /* CONFIG_USE_SFUD is not set */ /* CONFIG_USE_SPIFFS is not set */ /* CONFIG_USE_AMP is not set */ @@ -181,6 +199,28 @@ /* CONFIG_USE_TLSF is not set */ /* CONFIG_USE_SDMMC_CMD is not set */ /* CONFIG_USE_CHERRY_USB is not set */ -/* end of FreeRTOS Setting */ +/* end of Third-Party Configuration */ + +/* Kernel Configuration */ + +#define CONFIG_FREERTOS_OPTIMIZED_SCHEDULER +#define CONFIG_FREERTOS_HZ 1000 +#define CONFIG_FREERTOS_MAX_PRIORITIES 32 +#define CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES 13 +#define CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES 11 +#define CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS 1 +#define CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE 1024 +#define CONFIG_FREERTOS_MAX_TASK_NAME_LEN 32 +#define CONFIG_FREERTOS_TIMER_TASK_PRIORITY 1 +#define CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH 2048 +#define CONFIG_FREERTOS_TIMER_QUEUE_LENGTH 10 +#define CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE 0 +#define CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS +#define CONFIG_FREERTOS_USE_TRACE_FACILITY +#define CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS +/* CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set */ +#define CONFIG_FREERTOS_TOTAL_HEAP_SIZE 10240 +#define CONFIG_FREERTOS_TASK_FPU_SUPPORT 1 +/* end of Kernel Configuration */ #endif diff --git a/example/freertos_feature/queue/src/queue_cmd.c b/example/freertos_feature/queue/src/queue_cmd.c index c796edcd..e9472532 100644 --- a/example/freertos_feature/queue/src/queue_cmd.c +++ b/example/freertos_feature/queue/src/queue_cmd.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: queue_cmd.c * Date: 2022-06-17 10:41:45 * LastEditTime: 2022-06-17 10:41:45 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for queue command interface + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 wangxiaodong 2022/08/09 first commit */ #include "shell.h" #include @@ -35,19 +36,19 @@ typedef enum static void CreateQueueCmdUsage(void) { - printf("usage:\r\n"); + printf("Usage:\r\n"); printf(" queue int_cre \r\n"); - printf(" -- create int queue send and receive tasks now\r\n"); + printf(" -- Create int queue send and receive tasks now.\r\n"); printf(" queue int_del \r\n"); - printf(" -- del int queue send and receive tasks now\r\n"); + printf(" -- Del int queue send and receive tasks now.\r\n"); printf(" queue struct_cre \r\n"); - printf(" -- create struct queue send and receive tasks now\r\n"); + printf(" -- Create struct queue send and receive tasks now.\r\n"); printf(" queue struct_del \r\n"); - printf(" -- del struct queue send and receive tasks now\r\n"); + printf(" -- Cel struct queue send and receive tasks now.\r\n"); printf(" queue set_cre \r\n"); - printf(" -- use queue set function, create send and receive tasks now\r\n"); + printf(" -- Use queue set function, create send and receive tasks now.\r\n"); printf(" queue set_del \r\n"); - printf(" -- del queue set, send and receive tasks now\r\n"); + printf(" -- Del queue set, send and receive tasks now.\r\n"); } int CreateQueueCmd(int argc, char *argv[]) @@ -62,79 +63,79 @@ int CreateQueueCmd(int argc, char *argv[]) if (!strcmp(argv[1], "int_cre")) { - if(create_flg[INT_TASK_INDEX] == 0) + if (create_flg[INT_TASK_INDEX] == 0) { CreateIntTasks(); create_flg[INT_TASK_INDEX] = 1; } else { - printf("Please use int_del cmd first \r\n"); + printf("Please use int_del cmd first. \r\n"); } } else if (!strcmp(argv[1], "int_del")) { - if(create_flg[INT_TASK_INDEX] == 1) + if (create_flg[INT_TASK_INDEX] == 1) { DeleteIntTasks(); create_flg[INT_TASK_INDEX] = 0; - } + } else { - printf("Please use int_cre cmd first \r\n"); + printf("Please use int_cre cmd first. \r\n"); } } else if (!strcmp(argv[1], "struct_cre")) { - if(create_flg[STRUCT_TASK_INDEX] == 0) + if (create_flg[STRUCT_TASK_INDEX] == 0) { CreateStructTasks(); create_flg[STRUCT_TASK_INDEX] = 1; } else { - printf("Please use struct_del cmd first \r\n"); + printf("Please use struct_del cmd first. \r\n"); } } else if (!strcmp(argv[1], "struct_del")) { - if(create_flg[STRUCT_TASK_INDEX] == 1) + if (create_flg[STRUCT_TASK_INDEX] == 1) { DeleteStructTasks(); create_flg[STRUCT_TASK_INDEX] = 0; - } + } else { - printf("Please use struct_cre cmd first \r\n"); + printf("Please use struct_cre cmd first. \r\n"); } } else if (!strcmp(argv[1], "set_cre")) { - if(create_flg[SET_TASK_INDEX] == 0) + if (create_flg[SET_TASK_INDEX] == 0) { CreateQueueSetTasks(); create_flg[SET_TASK_INDEX] = 1; } else { - printf("Please use set_del cmd first \r\n"); + printf("Please use set_del cmd first. \r\n"); } } else if (!strcmp(argv[1], "set_del")) { - if(create_flg[SET_TASK_INDEX] == 1) + if (create_flg[SET_TASK_INDEX] == 1) { DeleteQueueSetTasks(); create_flg[SET_TASK_INDEX] = 0; - } + } else { - printf("Please use set_cre cmd first \r\n"); + printf("Please use set_cre cmd first. \r\n"); } } else { - printf("Error: Invalid arguments \r\n"); + printf("Error: Invalid arguments. \r\n"); CreateQueueCmdUsage(); } return 0; diff --git a/example/freertos_feature/queue/src/queue_int_send_recv.c b/example/freertos_feature/queue/src/queue_int_send_recv.c index a4d19569..a51206b7 100644 --- a/example/freertos_feature/queue/src/queue_int_send_recv.c +++ b/example/freertos_feature/queue/src/queue_int_send_recv.c @@ -1,7 +1,7 @@ /* -This example demonstrates a queue being created, data being sent to the queue from multiple -tasks, and data being received from the queue. The queue is created to hold data items of -type int. The tasks that send to the queue do not specify a block time, whereas the task +This example demonstrates a queue being created, data being sent to the queue from multiple +tasks, and data being received from the queue. The queue is created to hold data items of +type int. The tasks that send to the queue do not specify a block time, whereas the task that receives from the queue does. */ #include "FreeRTOSConfig.h" @@ -9,7 +9,7 @@ that receives from the queue does. #include "task.h" #include "queue.h" -#define TASK_STACK_SIZE 2048 +#define TASK_STACK_SIZE 2048 static xTaskHandle xtask1_handle; static xTaskHandle xtask2_handle; @@ -17,8 +17,8 @@ static xTaskHandle xtask3_handle; /* The tasks to be created. Two instances are created of the sender task while only a single instance is created of the receiver task. */ -static void vSenderTask( void *pvParameters ); -static void vReceiverTask( void *pvParameters ); +static void vSenderTask(void *pvParameters); +static void vReceiverTask(void *pvParameters); /*-----------------------------------------------------------*/ @@ -29,45 +29,45 @@ static QueueHandle_t xQueue; void CreateIntTasks(void) { /* The queue is created to hold a maximum of 5 int values. */ - xQueue = xQueueCreate( 5, sizeof( int ) ); - - if( xQueue != NULL ) - { - /* Create two instances of the task that will write to the queue. The - parameter is used to pass the value that the task should write to the queue, - so one task will continuously write 100 to the queue while the other task - will continuously write 200 to the queue. Both tasks are created at - priority 1. */ - xTaskCreate( vSenderTask, "Queue Sender1", TASK_STACK_SIZE, ( void * ) 100, 2, &xtask1_handle ); - xTaskCreate( vSenderTask, "Queue Sender2", TASK_STACK_SIZE, ( void * ) 200, 2, &xtask2_handle ); - - /* Create the task that will read from the queue. The task is created with - priority 2, so above the priority of the sender tasks. */ - xTaskCreate( vReceiverTask, "Queue Receiver", TASK_STACK_SIZE, NULL, 3, &xtask3_handle ); - - } - else - { - /* The queue could not be created. */ - } + xQueue = xQueueCreate(5, sizeof(int)); + + if (xQueue != NULL) + { + /* Create two instances of the task that will write to the queue. The + parameter is used to pass the value that the task should write to the queue, + so one task will continuously write 100 to the queue while the other task + will continuously write 200 to the queue. Both tasks are created at + priority 1. */ + xTaskCreate(vSenderTask, "Queue Sender1", TASK_STACK_SIZE, (void *) 100, 2, &xtask1_handle); + xTaskCreate(vSenderTask, "Queue Sender2", TASK_STACK_SIZE, (void *) 200, 2, &xtask2_handle); + + /* Create the task that will read from the queue. The task is created with + priority 2, so above the priority of the sender tasks. */ + xTaskCreate(vReceiverTask, "Queue Receiver", TASK_STACK_SIZE, NULL, 3, &xtask3_handle); + + } + else + { + /* The queue could not be created. */ + } } void DeleteIntTasks(void) { - if(xtask1_handle) + if (xtask1_handle) { vTaskDelete(xtask1_handle); - vPrintString("Int Sender 1 deletion \r\n"); + vPrintString("Int Sender 1 deletion \r\n"); } - if(xtask2_handle) + if (xtask2_handle) { vTaskDelete(xtask2_handle); vPrintString("Int Sender 2 deletion \r\n"); } - if(xtask3_handle) + if (xtask3_handle) { vTaskDelete(xtask3_handle); vPrintString("Int Receiver deletion \r\n"); @@ -75,87 +75,87 @@ void DeleteIntTasks(void) } /*-----------------------------------------------------------*/ -static void vSenderTask( void *pvParameters ) +static void vSenderTask(void *pvParameters) { - int lValueToSend; - BaseType_t xStatus; - - /* Two instances are created of this task so the value that is sent to the - queue is passed in via the task parameter rather than be hard coded. This way - each instance can use a different value. Cast the parameter to the required - type. */ - lValueToSend = (int)(uintptr)pvParameters; - - /* As per most tasks, this task is implemented within an infinite loop. */ - for( ;; ) - { - /* The first parameter is the queue to which data is being sent. The - queue was created before the scheduler was started, so before this task - started to execute. - - The second parameter is the address of the data to be sent. - - The third parameter is the Block time – the time the task should be kept - in the Blocked state to wait for space to become available on the queue - should the queue already be full. In this case we don’t specify a block - time because there should always be space in the queue. */ - xStatus = xQueueSendToBack( xQueue, &lValueToSend, 0 ); - - if( xStatus != pdPASS ) - { - /* We could not write to the queue because it was full – this must - be an error as the queue should never contain more than one item! */ - vPrintString( "Could not send to the queue.\r\n" ); - } - - vTaskDelay(3000); - } + int lValueToSend; + BaseType_t xStatus; + + /* Two instances are created of this task so the value that is sent to the + queue is passed in via the task parameter rather than be hard coded. This way + each instance can use a different value. Cast the parameter to the required + type. */ + lValueToSend = (int)(uintptr)pvParameters; + + /* As per most tasks, this task is implemented within an infinite loop. */ + for (;;) + { + /* The first parameter is the queue to which data is being sent. The + queue was created before the scheduler was started, so before this task + started to execute. + + The second parameter is the address of the data to be sent. + + The third parameter is the Block time – the time the task should be kept + in the Blocked state to wait for space to become available on the queue + should the queue already be full. In this case we don’t specify a block + time because there should always be space in the queue. */ + xStatus = xQueueSendToBack(xQueue, &lValueToSend, 0); + + if (xStatus != pdPASS) + { + /* We could not write to the queue because it was full – this must + be an error as the queue should never contain more than one item! */ + vPrintString("Could not send to the queue.\r\n"); + } + + vTaskDelay(3000); + } } /*-----------------------------------------------------------*/ -static void vReceiverTask( void *pvParameters ) +static void vReceiverTask(void *pvParameters) { - /* Declare the variable that will hold the values received from the queue. */ - int32_t lReceivedValue; - BaseType_t xStatus; - const TickType_t xTicksToWait = pdMS_TO_TICKS( 5000UL ); - - /* This task is also defined within an infinite loop. */ - for( ;; ) - { - /* As this task unblocks immediately that data is written to the queue this - call should always find the queue empty. */ - if( uxQueueMessagesWaiting( xQueue ) != 0 ) - { - vPrintString( "Queue should have been empty!\r\n" ); - } - - /* The first parameter is the queue from which data is to be received. The - queue is created before the scheduler is started, and therefore before this - task runs for the first time. - - The second parameter is the buffer into which the received data will be - placed. In this case the buffer is simply the address of a variable that - has the required size to hold the received data. - - the last parameter is the block time – the maximum amount of time that the - task should remain in the Blocked state to wait for data to be available should - the queue already be empty. */ - xStatus = xQueueReceive( xQueue, &lReceivedValue, xTicksToWait ); - - if( xStatus == pdPASS ) - { - /* Data was successfully received from the queue, print out the received - value. */ - vPrintStringAndNumber( "Received = ", lReceivedValue ); - } - else - { - /* We did not receive anything from the queue even after waiting for 100ms. - This must be an error as the sending tasks are free running and will be - continuously writing to the queue. */ - vPrintString( "Could not receive from the queue.\r\n" ); - } - - } + /* Declare the variable that will hold the values received from the queue. */ + int32_t lReceivedValue; + BaseType_t xStatus; + const TickType_t xTicksToWait = pdMS_TO_TICKS(5000UL); + + /* This task is also defined within an infinite loop. */ + for (;;) + { + /* As this task unblocks immediately that data is written to the queue this + call should always find the queue empty. */ + if (uxQueueMessagesWaiting(xQueue) != 0) + { + vPrintString("Queue should have been empty!\r\n"); + } + + /* The first parameter is the queue from which data is to be received. The + queue is created before the scheduler is started, and therefore before this + task runs for the first time. + + The second parameter is the buffer into which the received data will be + placed. In this case the buffer is simply the address of a variable that + has the required size to hold the received data. + + the last parameter is the block time – the maximum amount of time that the + task should remain in the Blocked state to wait for data to be available should + the queue already be empty. */ + xStatus = xQueueReceive(xQueue, &lReceivedValue, xTicksToWait); + + if (xStatus == pdPASS) + { + /* Data was successfully received from the queue, print out the received + value. */ + vPrintStringAndNumber("Received = ", lReceivedValue); + } + else + { + /* We did not receive anything from the queue even after waiting for 100ms. + This must be an error as the sending tasks are free running and will be + continuously writing to the queue. */ + vPrintString("Could not receive from the queue.\r\n"); + } + + } } \ No newline at end of file diff --git a/example/freertos_feature/queue/src/queue_set.c b/example/freertos_feature/queue/src/queue_set.c index 6f390e1a..1ef8af79 100644 --- a/example/freertos_feature/queue/src/queue_set.c +++ b/example/freertos_feature/queue/src/queue_set.c @@ -1,14 +1,14 @@ /* -This example creates two sending tasks and one receiving task. The sending tasks send data -to the receiving task on two separate queues, one queue for each task. The two queues are -added to a queue set, and the receiving task reads from the queue set to determine which of +This example creates two sending tasks and one receiving task. The sending tasks send data +to the receiving task on two separate queues, one queue for each task. The two queues are +added to a queue set, and the receiving task reads from the queue set to determine which of the two queues contain data. */ #include "FreeRTOS.h" #include "task.h" #include "queue.h" -#define TASK_STACK_SIZE 2048 +#define TASK_STACK_SIZE 2048 static xTaskHandle xtask1_handle; static xTaskHandle xtask2_handle; @@ -16,12 +16,12 @@ static xTaskHandle xtask3_handle; /* The three sender task. */ -static void vSenderTask1( void *pvParameters ); -static void vSenderTask2( void *pvParameters ); +static void vSenderTask1(void *pvParameters); +static void vSenderTask2(void *pvParameters); /* The receiver task. The receiver blocks on the queue set to received data from both sender task. */ -static void vReceiverTask( void *pvParameters ); +static void vReceiverTask(void *pvParameters); /*-----------------------------------------------------------*/ @@ -33,47 +33,47 @@ static QueueHandle_t xQueue1 = NULL, xQueue2 = NULL; the two queues are added. */ static QueueSetHandle_t xQueueSet = NULL; -void CreateQueueSetTasks( void ) +void CreateQueueSetTasks(void) { - /* Create the two queues. Each queue sends character pointers. The - priority of the receiving task is above the priority of the sending tasks so - the queues will never have more than one item in them at any one time. */ - xQueue1 = xQueueCreate( 1, sizeof( char * ) ); - xQueue2 = xQueueCreate( 1, sizeof( char * ) ); + /* Create the two queues. Each queue sends character pointers. The + priority of the receiving task is above the priority of the sending tasks so + the queues will never have more than one item in them at any one time. */ + xQueue1 = xQueueCreate(1, sizeof(char *)); + xQueue2 = xQueueCreate(1, sizeof(char *)); - /* Create the queue set. There are two queues both of which can contain - 1 item, so the maximum number of queue handle the queue set will ever have - to hold is 2 (1 item multiplied by 2 sets). */ - xQueueSet = xQueueCreateSet( 1 * 2 ); + /* Create the queue set. There are two queues both of which can contain + 1 item, so the maximum number of queue handle the queue set will ever have + to hold is 2 (1 item multiplied by 2 sets). */ + xQueueSet = xQueueCreateSet(1 * 2); - /* Add the two queues to the set. */ - xQueueAddToSet( xQueue1, xQueueSet ); - xQueueAddToSet( xQueue2, xQueueSet ); + /* Add the two queues to the set. */ + xQueueAddToSet(xQueue1, xQueueSet); + xQueueAddToSet(xQueue2, xQueueSet); - /* Create the tasks that send to the queues. */ - xTaskCreate( vSenderTask1, "QueueSet Sender1", TASK_STACK_SIZE, NULL, 2, &xtask1_handle ); - xTaskCreate( vSenderTask2, "QueueSet Sender2", TASK_STACK_SIZE, NULL, 2, &xtask2_handle ); + /* Create the tasks that send to the queues. */ + xTaskCreate(vSenderTask1, "QueueSet Sender1", TASK_STACK_SIZE, NULL, 2, &xtask1_handle); + xTaskCreate(vSenderTask2, "QueueSet Sender2", TASK_STACK_SIZE, NULL, 2, &xtask2_handle); - /* Create the receiver task. */ - xTaskCreate( vReceiverTask, "QueueSet Receiver", TASK_STACK_SIZE, NULL, 3, &xtask3_handle ); + /* Create the receiver task. */ + xTaskCreate(vReceiverTask, "QueueSet Receiver", TASK_STACK_SIZE, NULL, 3, &xtask3_handle); } void DeleteQueueSetTasks(void) { - if(xtask1_handle) + if (xtask1_handle) { - vTaskDelete(xtask1_handle); - vPrintString("QueueSet Sender 1 deletion \r\n"); + vTaskDelete(xtask1_handle); + vPrintString("QueueSet Sender 1 deletion \r\n"); } - if(xtask2_handle) + if (xtask2_handle) { vTaskDelete(xtask2_handle); vPrintString("QueueSet Sender 2 deletion \r\n"); } - if(xtask3_handle) + if (xtask3_handle) { vTaskDelete(xtask3_handle); vPrintString("QueueSet Receiver deletion \r\n"); @@ -81,77 +81,77 @@ void DeleteQueueSetTasks(void) } /*-----------------------------------------------------------*/ -static void vSenderTask1( void *pvParameters ) +static void vSenderTask1(void *pvParameters) { - const TickType_t xBlockTime = pdMS_TO_TICKS( 5000 ); - const char * const pcMessage = "Message from vSenderTask1\r\n"; - - /* As per most tasks, this task is implemented within an infinite loop. */ - for( ;; ) - { - /* Block for 100ms. */ - vTaskDelay( xBlockTime ); - - /* Send this task's string to xQueue1. It is not necessary to use a - block time, even though the queue can only hold one item. This is - because the priority of the task that reads from the queue is higher - than the priority of this task; as soon as this task writes to the queue - it will be pre-empted by the task that reads from the queue, so the - queue will already be empty again by the time the call to xQueueSend() - returns. The block time is set to 0. */ - xQueueSend( xQueue1, &pcMessage, 0 ); - } + const TickType_t xBlockTime = pdMS_TO_TICKS(5000); + const char *const pcMessage = "Message from vSenderTask1\r\n"; + + /* As per most tasks, this task is implemented within an infinite loop. */ + for (;;) + { + /* Block for 100ms. */ + vTaskDelay(xBlockTime); + + /* Send this task's string to xQueue1. It is not necessary to use a + block time, even though the queue can only hold one item. This is + because the priority of the task that reads from the queue is higher + than the priority of this task; as soon as this task writes to the queue + it will be pre-empted by the task that reads from the queue, so the + queue will already be empty again by the time the call to xQueueSend() + returns. The block time is set to 0. */ + xQueueSend(xQueue1, &pcMessage, 0); + } } /*-----------------------------------------------------------*/ -static void vSenderTask2( void *pvParameters ) +static void vSenderTask2(void *pvParameters) { - const TickType_t xBlockTime = pdMS_TO_TICKS( 5000 ); - const char * const pcMessage = "Message from vSenderTask2\r\n"; - - /* As per most tasks, this task is implemented within an infinite loop. */ - for( ;; ) - { - /* Block for 200ms. */ - vTaskDelay( xBlockTime ); - - /* Send this task's string to xQueue1. It is not necessary to use a - block time, even though the queue can only hold one item. This is - because the priority of the task that reads from the queue is higher - than the priority of this task; as soon as this task writes to the queue - it will be pre-empted by the task that reads from the queue, so the - queue will already be empty again by the time the call to xQueueSend() - returns. The block time is set to 0. */ - xQueueSend( xQueue2, &pcMessage, 0 ); - } + const TickType_t xBlockTime = pdMS_TO_TICKS(5000); + const char *const pcMessage = "Message from vSenderTask2\r\n"; + + /* As per most tasks, this task is implemented within an infinite loop. */ + for (;;) + { + /* Block for 200ms. */ + vTaskDelay(xBlockTime); + + /* Send this task's string to xQueue1. It is not necessary to use a + block time, even though the queue can only hold one item. This is + because the priority of the task that reads from the queue is higher + than the priority of this task; as soon as this task writes to the queue + it will be pre-empted by the task that reads from the queue, so the + queue will already be empty again by the time the call to xQueueSend() + returns. The block time is set to 0. */ + xQueueSend(xQueue2, &pcMessage, 0); + } } /*-----------------------------------------------------------*/ -static void vReceiverTask( void *pvParameters ) +static void vReceiverTask(void *pvParameters) { - QueueHandle_t xQueueThatContainsData; - char *pcReceivedString; - - /* As per most tasks, this task is implemented within an infinite loop. */ - for( ;; ) - { - /* Block on the queue set to wait for one of the queues in the set to - contain data. Cast the QueueSetMemberHandle_t values returned from - xQueueSelectFromSet() to a QueueHandle_t as it is known that all the - items in the set are queues (as opposed to semaphores, which can also be - members of a queue set). */ - xQueueThatContainsData = ( QueueHandle_t ) xQueueSelectFromSet( xQueueSet, portMAX_DELAY ); - - /* An indefinite block time was used when reading from the set so - xQueueSelectFromSet() will not have returned unless one of the queues in - the set contained data, and xQueueThatContansData must be valid. Read - from the queue. It is not necessary to specify a block time because it - is known that the queue contains data. The block time is set to 0. */ - xQueueReceive( xQueueThatContainsData, &pcReceivedString, 0 ); - - /* Print the string received from the queue. */ - vPrintString( pcReceivedString ); - - } + QueueHandle_t xQueueThatContainsData; + char *pcReceivedString; + + /* As per most tasks, this task is implemented within an infinite loop. */ + for (;;) + { + /* Block on the queue set to wait for one of the queues in the set to + contain data. Cast the QueueSetMemberHandle_t values returned from + xQueueSelectFromSet() to a QueueHandle_t as it is known that all the + items in the set are queues (as opposed to semaphores, which can also be + members of a queue set). */ + xQueueThatContainsData = (QueueHandle_t) xQueueSelectFromSet(xQueueSet, portMAX_DELAY); + + /* An indefinite block time was used when reading from the set so + xQueueSelectFromSet() will not have returned unless one of the queues in + the set contained data, and xQueueThatContansData must be valid. Read + from the queue. It is not necessary to specify a block time because it + is known that the queue contains data. The block time is set to 0. */ + xQueueReceive(xQueueThatContainsData, &pcReceivedString, 0); + + /* Print the string received from the queue. */ + vPrintString(pcReceivedString); + + } } diff --git a/example/freertos_feature/queue/src/queue_struct_send_recv.c b/example/freertos_feature/queue/src/queue_struct_send_recv.c index 2457b90f..77a9c30a 100644 --- a/example/freertos_feature/queue/src/queue_struct_send_recv.c +++ b/example/freertos_feature/queue/src/queue_struct_send_recv.c @@ -1,5 +1,5 @@ /* -This example is similar to queue_int_send_recv, but the task priorities are reversed, so the receiving task +This example is similar to queue_int_send_recv, but the task priorities are reversed, so the receiving task has a lower priority than the sending tasks. Also, the queue is used to pass structures, rather than integers. */ #include "FreeRTOSConfig.h" @@ -7,7 +7,7 @@ has a lower priority than the sending tasks. Also, the queue is used to pass str #include "task.h" #include "queue.h" -#define TASK_STACK_SIZE 2048 +#define TASK_STACK_SIZE 2048 #define mainSENDER_1 0 #define mainSENDER_2 1 @@ -16,15 +16,16 @@ static xTaskHandle xtask1_handle; static xTaskHandle xtask2_handle; static xTaskHandle xtask3_handle; -typedef struct { - unsigned char ucValue; - unsigned char ucSource; +typedef struct +{ + unsigned char ucValue; + unsigned char ucSource; } xData; -static const xData xStructsToSend[2] = +static const xData xStructsToSend[2] = { - {1, mainSENDER_1},/* Used by Sender1. */ - {2, mainSENDER_2} /* Used by Sender2. */ + {1, mainSENDER_1},/* Used by Sender1. */ + {2, mainSENDER_2} /* Used by Sender2. */ }; /* Declare a variable of type QueueHandle_t. This is used to store the queue @@ -33,137 +34,137 @@ static QueueHandle_t xQueue; static void vSenderTask(void *pvParameters) { - portBASE_TYPE xStatus; - const portTickType xTicksToWait = 100 / portTICK_RATE_MS; - - /* As per most tasks, this task is implemented within an infinite loop. */ + portBASE_TYPE xStatus; + const portTickType xTicksToWait = 100 / portTICK_RATE_MS; + + /* As per most tasks, this task is implemented within an infinite loop. */ for (;;) { - /* The first parameter is the queue to which data is being sent. The - queue was created before the scheduler was started, so before this task - started to execute. - - The second parameter is the address of the structure being sent. The - address is passed in as the task parameter. - - The third parameter is the Block time - the time the task should be kept - in the Blocked state to wait for space to become available on the queue - should the queue already be full. A block time is specified as the queue - will become full. Items will only be removed from the queue when both - sending tasks are in the Blocked state.. */ - xStatus = xQueueSendToBack(xQueue, pvParameters, xTicksToWait); - - /* We could not write to the queue because it was full - this must - be an error as the receiving task should make space in the queue - as soon as both sending tasks are in the Blocked state. */ - if (xStatus != pdPASS) - { - vPrintString("Could not send to the queue!\n"); - } - - vTaskDelay(5000); + /* The first parameter is the queue to which data is being sent. The + queue was created before the scheduler was started, so before this task + started to execute. + + The second parameter is the address of the structure being sent. The + address is passed in as the task parameter. + + The third parameter is the Block time - the time the task should be kept + in the Blocked state to wait for space to become available on the queue + should the queue already be full. A block time is specified as the queue + will become full. Items will only be removed from the queue when both + sending tasks are in the Blocked state.. */ + xStatus = xQueueSendToBack(xQueue, pvParameters, xTicksToWait); + + /* We could not write to the queue because it was full - this must + be an error as the receiving task should make space in the queue + as soon as both sending tasks are in the Blocked state. */ + if (xStatus != pdPASS) + { + vPrintString("Could not send to the queue!\n"); + } + + vTaskDelay(5000); } } static void vReceiverTask(void *pvParameters) { - /* Declare the structure that will hold the values received from the queue. */ - xData xReceivedStructure; - portBASE_TYPE xStatus; - - /* This task is also defined within an infinite loop. */ - for (;;) - { - /* As this task only runs when the sending tasks are in the Blocked state, - and the sending tasks only block when the queue is full, this task should - always find the queue to be full. 3 is the queue length. */ - if (uxQueueMessagesWaiting(xQueue) == 3) - { - vPrintString("Queue should is full!\n"); - } - - /* The first parameter is the queue from which data is to be received. The - queue is created before the scheduler is started, and therefore before this - task runs for the first time. - - The second parameter is the buffer into which the received data will be - placed. In this case the buffer is simply the address of a variable that - has the required size to hold the received structure. - - The last parameter is the block time - the maximum amount of time that the - task should remain in the Blocked state to wait for data to be available - should the queue already be empty. A block time is not necessary as this - task will only run when the queue is full so data will always be available. */ - xStatus = xQueueReceive(xQueue, &xReceivedStructure, /*0*/portMAX_DELAY); - - /* Data was successfully received from the queue, print out the received - value and the source of the value. */ - if (xStatus == pdPASS) - { - if (xReceivedStructure.ucSource == mainSENDER_1) - { - vPrintStringAndNumber("Received From Sender 1 = ", xReceivedStructure.ucValue); - } - else - { - vPrintStringAndNumber("Received From Sender 2 = ", xReceivedStructure.ucValue); - } - } - else - { - /* We did not receive anything from the queue. This must be an error - as this task should only run when the queue is full. */ - vPrintString("Could not receive from the queue!\n"); - } - } + /* Declare the structure that will hold the values received from the queue. */ + xData xReceivedStructure; + portBASE_TYPE xStatus; + + /* This task is also defined within an infinite loop. */ + for (;;) + { + /* As this task only runs when the sending tasks are in the Blocked state, + and the sending tasks only block when the queue is full, this task should + always find the queue to be full. 3 is the queue length. */ + if (uxQueueMessagesWaiting(xQueue) == 3) + { + vPrintString("Queue should is full!\n"); + } + + /* The first parameter is the queue from which data is to be received. The + queue is created before the scheduler is started, and therefore before this + task runs for the first time. + + The second parameter is the buffer into which the received data will be + placed. In this case the buffer is simply the address of a variable that + has the required size to hold the received structure. + + The last parameter is the block time - the maximum amount of time that the + task should remain in the Blocked state to wait for data to be available + should the queue already be empty. A block time is not necessary as this + task will only run when the queue is full so data will always be available. */ + xStatus = xQueueReceive(xQueue, &xReceivedStructure, /*0*/portMAX_DELAY); + + /* Data was successfully received from the queue, print out the received + value and the source of the value. */ + if (xStatus == pdPASS) + { + if (xReceivedStructure.ucSource == mainSENDER_1) + { + vPrintStringAndNumber("Received From Sender 1 = ", xReceivedStructure.ucValue); + } + else + { + vPrintStringAndNumber("Received From Sender 2 = ", xReceivedStructure.ucValue); + } + } + else + { + /* We did not receive anything from the queue. This must be an error + as this task should only run when the queue is full. */ + vPrintString("Could not receive from the queue!\n"); + } + } } void CreateStructTasks(void) { BaseType_t ret; - /* The queue is created to hold a maximum of 3 structures of type xData. */ - xQueue = xQueueCreate(3, sizeof(xData)); - if (xQueue != NULL) - { - ret = xTaskCreate(vReceiverTask, "Struct Receiver", TASK_STACK_SIZE, NULL, 2, &xtask1_handle); - if(ret != pdPASS) - { - xtask1_handle = NULL; - vPrintStringAndNumber("Receiver creation failed: ", ret); - } - - ret = xTaskCreate(vSenderTask, "Struct Sender 1", TASK_STACK_SIZE, (void*)&(xStructsToSend[0]), 2, &xtask2_handle); - if(ret != pdPASS) - { - xtask2_handle = NULL; - vPrintStringAndNumber("Sender 1 creation failed: ", ret); - } - - ret = xTaskCreate(vSenderTask, "Struct Sender 2", TASK_STACK_SIZE, (void*)&(xStructsToSend[1]), 2, &xtask3_handle); - if(ret != pdPASS) - { - xtask3_handle = NULL; - vPrintStringAndNumber("Sender 2 creation failed: ", ret); - } - } + /* The queue is created to hold a maximum of 3 structures of type xData. */ + xQueue = xQueueCreate(3, sizeof(xData)); + if (xQueue != NULL) + { + ret = xTaskCreate(vReceiverTask, "Struct Receiver", TASK_STACK_SIZE, NULL, 2, &xtask1_handle); + if (ret != pdPASS) + { + xtask1_handle = NULL; + vPrintStringAndNumber("Receiver creation failed: ", ret); + } + + ret = xTaskCreate(vSenderTask, "Struct Sender 1", TASK_STACK_SIZE, (void *) & (xStructsToSend[0]), 2, &xtask2_handle); + if (ret != pdPASS) + { + xtask2_handle = NULL; + vPrintStringAndNumber("Sender 1 creation failed: ", ret); + } + + ret = xTaskCreate(vSenderTask, "Struct Sender 2", TASK_STACK_SIZE, (void *) & (xStructsToSend[1]), 2, &xtask3_handle); + if (ret != pdPASS) + { + xtask3_handle = NULL; + vPrintStringAndNumber("Sender 2 creation failed: ", ret); + } + } } void DeleteStructTasks(void) { - if(xtask1_handle) + if (xtask1_handle) { vTaskDelete(xtask1_handle); vPrintString("Struct Receiver deletion \r\n"); } - if(xtask2_handle) + if (xtask2_handle) { vTaskDelete(xtask2_handle); vPrintString("Struct Sender 1 deletion \r\n"); } - if(xtask3_handle) + if (xtask3_handle) { vTaskDelete(xtask3_handle); vPrintString("Struct Sender 2 deletion \r\n"); diff --git a/example/freertos_feature/resource/configs/d2000_aarch32_eg_configs b/example/freertos_feature/resource/configs/d2000_aarch32_eg_configs index 464a31af..a16785ad 100644 --- a/example/freertos_feature/resource/configs/d2000_aarch32_eg_configs +++ b/example/freertos_feature/resource/configs/d2000_aarch32_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -111,6 +112,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -147,6 +157,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -168,12 +179,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -185,14 +190,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -210,4 +233,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/resource/configs/d2000_aarch64_eg_configs b/example/freertos_feature/resource/configs/d2000_aarch64_eg_configs index 64e6b4b7..4731ef2f 100644 --- a/example/freertos_feature/resource/configs/d2000_aarch64_eg_configs +++ b/example/freertos_feature/resource/configs/d2000_aarch64_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/resource/configs/e2000d_aarch32_eg_configs b/example/freertos_feature/resource/configs/e2000d_aarch32_eg_configs index fc31cd0b..22902270 100644 --- a/example/freertos_feature/resource/configs/e2000d_aarch32_eg_configs +++ b/example/freertos_feature/resource/configs/e2000d_aarch32_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -111,6 +112,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -147,6 +157,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -168,12 +179,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -185,14 +190,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -210,4 +233,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/resource/configs/e2000d_aarch64_eg_configs b/example/freertos_feature/resource/configs/e2000d_aarch64_eg_configs index 7e2efa4f..f3181d35 100644 --- a/example/freertos_feature/resource/configs/e2000d_aarch64_eg_configs +++ b/example/freertos_feature/resource/configs/e2000d_aarch64_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/resource/configs/e2000q_aarch32_eg_configs b/example/freertos_feature/resource/configs/e2000q_aarch32_eg_configs index 2fe965a5..a786509e 100644 --- a/example/freertos_feature/resource/configs/e2000q_aarch32_eg_configs +++ b/example/freertos_feature/resource/configs/e2000q_aarch32_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -111,6 +112,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -147,6 +157,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -168,12 +179,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -185,14 +190,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -210,4 +233,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/resource/configs/e2000q_aarch64_eg_configs b/example/freertos_feature/resource/configs/e2000q_aarch64_eg_configs index 9c50f2b0..9183d77b 100644 --- a/example/freertos_feature/resource/configs/e2000q_aarch64_eg_configs +++ b/example/freertos_feature/resource/configs/e2000q_aarch64_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/resource/configs/ft2004_aarch32_eg_configs b/example/freertos_feature/resource/configs/ft2004_aarch32_eg_configs index 4c5b2c49..f0510b59 100644 --- a/example/freertos_feature/resource/configs/ft2004_aarch32_eg_configs +++ b/example/freertos_feature/resource/configs/ft2004_aarch32_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -111,6 +112,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -147,6 +157,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -168,12 +179,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -185,14 +190,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -210,4 +233,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/resource/configs/ft2004_aarch64_eg_configs b/example/freertos_feature/resource/configs/ft2004_aarch64_eg_configs index da9c1f81..d99e8ace 100644 --- a/example/freertos_feature/resource/configs/ft2004_aarch64_eg_configs +++ b/example/freertos_feature/resource/configs/ft2004_aarch64_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/resource/inc/feature_resource.h b/example/freertos_feature/resource/inc/feature_resource.h index f90c3ef2..83d14088 100644 --- a/example/freertos_feature/resource/inc/feature_resource.h +++ b/example/freertos_feature/resource/inc/feature_resource.h @@ -1,30 +1,35 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: feature_resource.h * Date: 2022-06-17 10:42:40 * LastEditTime: 2022-06-17 10:42:40 - * Description: This file is for - * - * Modify History: + * Description: This file is for task function define + * + * Modify History: * Ver Who Date Changes * ----- ------ -------- -------------------------------------- + * 1.0 wangxiaodong 2022/08/09 first commit */ - #ifndef FEATURE_RESOURCE_H #define FEATURE_RESOURCE_H +#ifdef __cplusplus +extern "C" +{ +#endif + /* mutex task */ void CreateResourceTasks(void); void DeleteResourceTasks(void); @@ -33,4 +38,8 @@ void DeleteResourceTasks(void); void CreateGatekeeperTasks(void); void DeleteGatekeeperTasks(void); +#ifdef __cplusplus +} +#endif + #endif // ! \ No newline at end of file diff --git a/example/freertos_feature/resource/main.c b/example/freertos_feature/resource/main.c index f376d838..9c8c87a2 100644 --- a/example/freertos_feature/resource/main.c +++ b/example/freertos_feature/resource/main.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: main.c * Date: 2022-06-17 08:17:59 * LastEditTime: 2022-06-17 08:17:59 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for resource example that running shell task and open scheduler + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 wangxiaodong 2022/08/09 first commit */ #include "shell.h" @@ -30,13 +31,15 @@ int main(void) BaseType_t ret; ret = LSUserShellTask() ; - if(ret != pdPASS) + if (ret != pdPASS) + { goto FAIL_EXIT; + } - vTaskStartScheduler(); /* 启动任务,开启调度 */ + vTaskStartScheduler(); /* 启动任务,开启调度 */ while (1); /* 正常不会执行到这里 */ - + FAIL_EXIT: - printf("failed 0x%x \r\n", ret); + printf("failed 0x%x. \r\n", ret); return 0; } diff --git a/example/freertos_feature/resource/sdkconfig b/example/freertos_feature/resource/sdkconfig index 9c50f2b0..9183d77b 100644 --- a/example/freertos_feature/resource/sdkconfig +++ b/example/freertos_feature/resource/sdkconfig @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/resource/sdkconfig.h b/example/freertos_feature/resource/sdkconfig.h index 2e55f772..80305bac 100644 --- a/example/freertos_feature/resource/sdkconfig.h +++ b/example/freertos_feature/resource/sdkconfig.h @@ -62,6 +62,7 @@ /* CONFIG_USE_ADC is not set */ /* CONFIG_USE_PWM is not set */ /* CONFIG_USE_IPC is not set */ +/* CONFIG_USE_MEDIA is not set */ /* end of Components Configuration */ #define CONFIG_USE_NEW_LIBC /* end of Standalone Setting */ @@ -98,6 +99,12 @@ /* Compiler Options */ +/* Cross-Compiler Setting */ + +#define CONFIG_GCC_OPTIMIZE_LEVEL 0 +/* CONFIG_USE_EXT_COMPILER is not set */ +/* CONFIG_USE_KLIN_SYS is not set */ +/* end of Cross-Compiler Setting */ #define CONFIG_OUTPUT_BINARY /* end of Compiler Options */ /* end of Building Option */ @@ -127,6 +134,7 @@ /* Freertos Eth Drivers */ /* CONFIG_FREERTOS_USE_XMAC is not set */ +/* CONFIG_FREERTOS_USE_GMAC is not set */ /* end of Freertos Eth Drivers */ /* Freertos Gpio Drivers */ @@ -145,11 +153,6 @@ /* CONFIG_FREERTOS_USE_FGDMA is not set */ /* end of Freertos DMA Drivers */ -/* Freertos MMC Drivers */ - -/* CONFIG_FREERTOS_USE_FSDIO is not set */ -/* end of Freertos MMC Drivers */ - /* Freertos Adc Drivers */ /* CONFIG_FREERTOS_USE_ADC is not set */ @@ -159,13 +162,28 @@ /* CONFIG_FREERTOS_USE_CAN is not set */ /* end of Freertos Can Drivers */ + +/* Freertos I2c Drivers */ + +/* CONFIG_FREERTOS_USE_I2C is not set */ +/* end of Freertos I2c Drivers */ + +/* Freertos Mio Drivers */ + +/* CONFIG_FREERTOS_USE_MIO is not set */ +/* end of Freertos Mio Drivers */ + +/* Freertos Timer Drivers */ + +/* CONFIG_FREERTOS_USE_TIMER is not set */ +/* end of Freertos Timer Drivers */ /* end of Component Configuration */ -/* FreeRTOS Setting */ +/* Third-Party Configuration */ /* CONFIG_USE_LWIP is not set */ #define CONFIG_USE_BACKTRACE -/* CONFIG_USE_FATFS is not set */ +/* CONFIG_USE_FATFS_0_1_4 is not set */ /* CONFIG_USE_SFUD is not set */ /* CONFIG_USE_SPIFFS is not set */ /* CONFIG_USE_AMP is not set */ @@ -181,6 +199,28 @@ /* CONFIG_USE_TLSF is not set */ /* CONFIG_USE_SDMMC_CMD is not set */ /* CONFIG_USE_CHERRY_USB is not set */ -/* end of FreeRTOS Setting */ +/* end of Third-Party Configuration */ + +/* Kernel Configuration */ + +#define CONFIG_FREERTOS_OPTIMIZED_SCHEDULER +#define CONFIG_FREERTOS_HZ 1000 +#define CONFIG_FREERTOS_MAX_PRIORITIES 32 +#define CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES 13 +#define CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES 11 +#define CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS 1 +#define CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE 1024 +#define CONFIG_FREERTOS_MAX_TASK_NAME_LEN 32 +#define CONFIG_FREERTOS_TIMER_TASK_PRIORITY 1 +#define CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH 2048 +#define CONFIG_FREERTOS_TIMER_QUEUE_LENGTH 10 +#define CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE 0 +#define CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS +#define CONFIG_FREERTOS_USE_TRACE_FACILITY +#define CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS +/* CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set */ +#define CONFIG_FREERTOS_TOTAL_HEAP_SIZE 10240 +#define CONFIG_FREERTOS_TASK_FPU_SUPPORT 1 +/* end of Kernel Configuration */ #endif diff --git a/example/freertos_feature/resource/src/gatekeeper.c b/example/freertos_feature/resource/src/gatekeeper.c index 238b39f6..befeb2a9 100644 --- a/example/freertos_feature/resource/src/gatekeeper.c +++ b/example/freertos_feature/resource/src/gatekeeper.c @@ -1,5 +1,5 @@ /* -This example demonstrates: +This example demonstrates: Re-writing vPrintString() to use a gatekeeper task. */ #include @@ -10,7 +10,7 @@ Re-writing vPrintString() to use a gatekeeper task. #include "task.h" #include "queue.h" -#define TASK_STACK_SIZE 1024 +#define TASK_STACK_SIZE 1024 static xTaskHandle xtask1_handle; static xTaskHandle xtask2_handle; @@ -18,85 +18,85 @@ static xTaskHandle xtask3_handle; #define MAX_MSG_LEN 100 -static char *pcStringsToPrint[] = +static char *pcStringsToPrint[] = { - "Gatekeeper Task 1 *********************************\n", - "Gatekeeper Task 2 =================================\n" - "Gatekeep Message printed from the tick hook #####\n" + "Gatekeeper Task 1 *********************************\n", + "Gatekeeper Task 2 =================================\n" + "Gatekeep Message printed from the tick hook #####\n" }; xQueueHandle xPrintQueue; -static void prvStdioGatekeeperTask(void* pvParameters) +static void prvStdioGatekeeperTask(void *pvParameters) { - char* pcMessageToPrint; - static char cBuffer[MAX_MSG_LEN]; - - for (;;) - { - xQueueReceive(xPrintQueue, &pcMessageToPrint, portMAX_DELAY); - strncpy(cBuffer, pcMessageToPrint, MAX_MSG_LEN); - vPrintString(cBuffer); - } + char *pcMessageToPrint; + static char cBuffer[MAX_MSG_LEN]; + + for (;;) + { + xQueueReceive(xPrintQueue, &pcMessageToPrint, portMAX_DELAY); + strncpy(cBuffer, pcMessageToPrint, MAX_MSG_LEN); + vPrintString(cBuffer); + } } -static void prvPrintTask(void *pvParameters) +static void prvPrintTask(void *pvParameters) { - int iIndexToString; - iIndexToString = (int)(uintptr)pvParameters; + int iIndexToString; + iIndexToString = (int)(uintptr)pvParameters; - for (;;) - { - xQueueSendToBack(xPrintQueue, &(pcStringsToPrint[iIndexToString]), 0); + for (;;) + { + xQueueSendToBack(xPrintQueue, &(pcStringsToPrint[iIndexToString]), 0); - vTaskDelay(5000); - } + vTaskDelay(5000); + } } -static void vApplicationTickHook(void) +static void vApplicationTickHook(void) { - static int iCount = 0; - portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; - - iCount++; - if (iCount >= 2000) - { - xQueueSendToFrontFromISR(xPrintQueue, - &(pcStringsToPrint[2]), - &xHigherPriorityTaskWoken); // not needed - iCount = 0; - } + static int iCount = 0; + portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; + + iCount++; + if (iCount >= 2000) + { + xQueueSendToFrontFromISR(xPrintQueue, + &(pcStringsToPrint[2]), + &xHigherPriorityTaskWoken); // not needed + iCount = 0; + } } void CreateGatekeeperTasks(void) { - xPrintQueue = xQueueCreate(5, sizeof(char*)); + xPrintQueue = xQueueCreate(5, sizeof(char *)); - srand(0x42); + srand(0x42); - if (xPrintQueue != NULL) - { - xTaskCreate(prvPrintTask, "Gatekeeper Print1", TASK_STACK_SIZE, (void*)0, 1, &xtask1_handle); - xTaskCreate(prvPrintTask, "Gatekeeper Print2", TASK_STACK_SIZE, (void*)1, 2, &xtask2_handle); - xTaskCreate(prvStdioGatekeeperTask, "Gatekeeper", TASK_STACK_SIZE, NULL, 0, &xtask3_handle); - } + if (xPrintQueue != NULL) + { + xTaskCreate(prvPrintTask, "Gatekeeper Print1", TASK_STACK_SIZE, (void *)0, 1, &xtask1_handle); + xTaskCreate(prvPrintTask, "Gatekeeper Print2", TASK_STACK_SIZE, (void *)1, 2, &xtask2_handle); + xTaskCreate(prvStdioGatekeeperTask, "Gatekeeper", TASK_STACK_SIZE, NULL, 0, &xtask3_handle); + } } void DeleteGatekeeperTasks(void) { - if(xtask1_handle) + if (xtask1_handle) { vTaskDelete(xtask1_handle); vPrintString("Gatekeeper Print1 deletion \r\n"); } - if(xtask2_handle) + if (xtask2_handle) { vTaskDelete(xtask2_handle); vPrintString("Gatekeeper Print2 deletion \r\n"); } - if(xtask3_handle) + if (xtask3_handle) { vTaskDelete(xtask3_handle); vPrintString("Gatekeeper deletion \r\n"); diff --git a/example/freertos_feature/resource/src/mutex.c b/example/freertos_feature/resource/src/mutex.c index 754c3e82..fc5dc5b3 100644 --- a/example/freertos_feature/resource/src/mutex.c +++ b/example/freertos_feature/resource/src/mutex.c @@ -1,5 +1,5 @@ /* -This example demonstrates: +This example demonstrates: Rewriting vPrintString() to use a mutex semaphore. */ #include @@ -11,60 +11,60 @@ Rewriting vPrintString() to use a mutex semaphore. #include "semphr.h" #include "croutine.h" -#define TASK_STACK_SIZE 1024 +#define TASK_STACK_SIZE 1024 static xTaskHandle xtask1_handle; static xTaskHandle xtask2_handle; static xSemaphoreHandle xMutex; -static void prvNewPrintString(const char* pcString) +static void prvNewPrintString(const char *pcString) { - xSemaphoreTake(xMutex, portMAX_DELAY); - printf("Mutex pcString = %s\n", pcString); - xSemaphoreGive(xMutex); + xSemaphoreTake(xMutex, portMAX_DELAY); + printf("Mutex pcString = %s\n", pcString); + xSemaphoreGive(xMutex); } -static void prvPrintTask(void *pvParameters) +static void prvPrintTask(void *pvParameters) { - char *pcStringToPrint; - pcStringToPrint = (char*)pvParameters; + char *pcStringToPrint; + pcStringToPrint = (char *)pvParameters; - for (;;) - { - prvNewPrintString(pcStringToPrint); + for (;;) + { + prvNewPrintString(pcStringToPrint); - /* Just delay with random time, - Don't use rand() in secure applications. It's not reentrant!*/ - vTaskDelay(/*rand() & 0x3FF*/5000); - } + /* Just delay with random time, + Don't use rand() in secure applications. It's not reentrant!*/ + vTaskDelay(/*rand() & 0x3FF*/5000); + } } void CreateResourceTasks(void) { - xMutex = xSemaphoreCreateMutex(); + xMutex = xSemaphoreCreateMutex(); - if (xMutex != NULL) - { + if (xMutex != NULL) + { - xTaskCreate(prvPrintTask, "Mutex Print1", TASK_STACK_SIZE, - "Task 1 ******************************\n", 1, &xtask1_handle); - xTaskCreate(prvPrintTask, "Mutex Print2", TASK_STACK_SIZE, - "Task 2 ==============================\n", 2, &xtask2_handle); - } + xTaskCreate(prvPrintTask, "Mutex Print1", TASK_STACK_SIZE, + "Task 1 ******************************\n", 1, &xtask1_handle); + xTaskCreate(prvPrintTask, "Mutex Print2", TASK_STACK_SIZE, + "Task 2 ==============================\n", 2, &xtask2_handle); + } } void DeleteResourceTasks(void) { - if(xtask1_handle) + if (xtask1_handle) { vTaskDelete(xtask1_handle); printf("Resource Task1 deletion \r\n"); } - if(xtask2_handle) + if (xtask2_handle) { vTaskDelete(xtask2_handle); printf("Resource Task2 deletion \r\n"); diff --git a/example/freertos_feature/resource/src/resource_cmd.c b/example/freertos_feature/resource/src/resource_cmd.c index 92628788..0d2e009a 100644 --- a/example/freertos_feature/resource/src/resource_cmd.c +++ b/example/freertos_feature/resource/src/resource_cmd.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: resource_cmd.c * Date: 2022-06-17 10:41:45 * LastEditTime: 2022-06-17 10:41:45 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for resource command interface + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 wangxiaodong 2022/08/09 first commit */ #include "shell.h" #include "feature_resource.h" @@ -34,16 +35,16 @@ typedef enum static void ResourceTasksCmdUsage(void) { - printf("usage:\r\n"); + printf("Usage:\r\n"); printf(" resource mutex_cre \r\n"); - printf(" -- create mutex tasks now \r\n"); + printf(" -- Create mutex tasks now. \r\n"); printf(" resource mutex_del \r\n"); - printf(" -- del mutex tasks now \r\n"); + printf(" -- Del mutex tasks now. \r\n"); printf(" resource gate_cre \r\n"); - printf(" -- create gatekeeper tasks now \r\n"); + printf(" -- Create gatekeeper tasks now. \r\n"); printf(" resource gate_del \r\n"); - printf(" -- del gatekeeper tasks now \r\n"); - + printf(" -- Del gatekeeper tasks now. \r\n"); + } int ResourceTasksCmd(int argc, char *argv[]) @@ -58,55 +59,55 @@ int ResourceTasksCmd(int argc, char *argv[]) if (!strcmp(argv[1], "mutex_cre")) { - if(create_flg[MUTEX_TASK_INDEX] == 0) + if (create_flg[MUTEX_TASK_INDEX] == 0) { CreateResourceTasks(); create_flg[MUTEX_TASK_INDEX] = 1; } else { - printf("Please use mutex_del cmd first \r\n"); + printf("Please use mutex_del cmd first. \r\n"); } } else if (!strcmp(argv[1], "mutex_del")) { - if(create_flg[MUTEX_TASK_INDEX] == 1) + if (create_flg[MUTEX_TASK_INDEX] == 1) { DeleteResourceTasks(); create_flg[MUTEX_TASK_INDEX] = 0; - } + } else { - printf("Please use mutex_cre cmd first \r\n"); + printf("Please use mutex_cre cmd first. \r\n"); } } else if (!strcmp(argv[1], "gate_cre")) { - if(create_flg[GATEKEEPER_TEST_INDEX] == 0) + if (create_flg[GATEKEEPER_TEST_INDEX] == 0) { CreateGatekeeperTasks(); create_flg[GATEKEEPER_TEST_INDEX] = 1; } else { - printf("Please use gate_del cmd first \r\n"); + printf("Please use gate_del cmd first. \r\n"); } } else if (!strcmp(argv[1], "gate_del")) { - if(create_flg[GATEKEEPER_TEST_INDEX] == 1) + if (create_flg[GATEKEEPER_TEST_INDEX] == 1) { DeleteGatekeeperTasks(); create_flg[GATEKEEPER_TEST_INDEX] = 0; - } + } else { - printf("Please use gate_cre cmd first \r\n"); + printf("Please use gate_cre cmd first. \r\n"); } } else { - printf("Error: Invalid arguments \r\n"); + printf("Error: Invalid arguments. \r\n"); ResourceTasksCmdUsage(); } return 0; diff --git a/example/freertos_feature/software_timer/configs/d2000_aarch32_eg_configs b/example/freertos_feature/software_timer/configs/d2000_aarch32_eg_configs index 464a31af..a16785ad 100644 --- a/example/freertos_feature/software_timer/configs/d2000_aarch32_eg_configs +++ b/example/freertos_feature/software_timer/configs/d2000_aarch32_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -111,6 +112,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -147,6 +157,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -168,12 +179,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -185,14 +190,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -210,4 +233,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/software_timer/configs/d2000_aarch64_eg_configs b/example/freertos_feature/software_timer/configs/d2000_aarch64_eg_configs index 64e6b4b7..4731ef2f 100644 --- a/example/freertos_feature/software_timer/configs/d2000_aarch64_eg_configs +++ b/example/freertos_feature/software_timer/configs/d2000_aarch64_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/software_timer/configs/e2000d_aarch32_eg_configs b/example/freertos_feature/software_timer/configs/e2000d_aarch32_eg_configs index fc31cd0b..22902270 100644 --- a/example/freertos_feature/software_timer/configs/e2000d_aarch32_eg_configs +++ b/example/freertos_feature/software_timer/configs/e2000d_aarch32_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -111,6 +112,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -147,6 +157,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -168,12 +179,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -185,14 +190,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -210,4 +233,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/software_timer/configs/e2000d_aarch64_eg_configs b/example/freertos_feature/software_timer/configs/e2000d_aarch64_eg_configs index 7e2efa4f..f3181d35 100644 --- a/example/freertos_feature/software_timer/configs/e2000d_aarch64_eg_configs +++ b/example/freertos_feature/software_timer/configs/e2000d_aarch64_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/software_timer/configs/e2000q_aarch32_eg_configs b/example/freertos_feature/software_timer/configs/e2000q_aarch32_eg_configs index 2fe965a5..a786509e 100644 --- a/example/freertos_feature/software_timer/configs/e2000q_aarch32_eg_configs +++ b/example/freertos_feature/software_timer/configs/e2000q_aarch32_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -111,6 +112,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -147,6 +157,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -168,12 +179,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -185,14 +190,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -210,4 +233,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/software_timer/configs/e2000q_aarch64_eg_configs b/example/freertos_feature/software_timer/configs/e2000q_aarch64_eg_configs index 9c50f2b0..9183d77b 100644 --- a/example/freertos_feature/software_timer/configs/e2000q_aarch64_eg_configs +++ b/example/freertos_feature/software_timer/configs/e2000q_aarch64_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/software_timer/configs/ft2004_aarch32_eg_configs b/example/freertos_feature/software_timer/configs/ft2004_aarch32_eg_configs index 4c5b2c49..f0510b59 100644 --- a/example/freertos_feature/software_timer/configs/ft2004_aarch32_eg_configs +++ b/example/freertos_feature/software_timer/configs/ft2004_aarch32_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -111,6 +112,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -147,6 +157,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -168,12 +179,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -185,14 +190,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -210,4 +233,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/software_timer/configs/ft2004_aarch64_eg_configs b/example/freertos_feature/software_timer/configs/ft2004_aarch64_eg_configs index da9c1f81..d99e8ace 100644 --- a/example/freertos_feature/software_timer/configs/ft2004_aarch64_eg_configs +++ b/example/freertos_feature/software_timer/configs/ft2004_aarch64_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/software_timer/inc/feature_software_timer.h b/example/freertos_feature/software_timer/inc/feature_software_timer.h index b0ed31b9..2dfd3f03 100644 --- a/example/freertos_feature/software_timer/inc/feature_software_timer.h +++ b/example/freertos_feature/software_timer/inc/feature_software_timer.h @@ -1,30 +1,36 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: feature_software_timer.h * Date: 2022-06-17 10:42:40 * LastEditTime: 2022-06-17 10:42:40 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for task function define + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 wangxiaodong 2022/08/09 first commit */ #ifndef FEATURE_SOFTWARE_TIMER_H #define FEATURE_SOFTWARE_TIMER_H +#ifdef __cplusplus +extern "C" +{ +#endif + /* software timer create and start */ void CreateTimerTasks(void); void DeleteTimerTasks(void); @@ -32,4 +38,8 @@ void DeleteTimerTasks(void); void CreateTimerResetTasks(void); void DeleteTimerResetTasks(void); +#ifdef __cplusplus +} +#endif + #endif // ! \ No newline at end of file diff --git a/example/freertos_feature/software_timer/main.c b/example/freertos_feature/software_timer/main.c index f376d838..c1ab62ef 100644 --- a/example/freertos_feature/software_timer/main.c +++ b/example/freertos_feature/software_timer/main.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: main.c * Date: 2022-06-17 08:17:59 * LastEditTime: 2022-06-17 08:17:59 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for software_timer example that running shell task and open scheduler + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 wangxiaodong 2022/08/09 first commit */ #include "shell.h" @@ -30,13 +31,15 @@ int main(void) BaseType_t ret; ret = LSUserShellTask() ; - if(ret != pdPASS) + if (ret != pdPASS) + { goto FAIL_EXIT; + } - vTaskStartScheduler(); /* 启动任务,开启调度 */ + vTaskStartScheduler(); /* 启动任务,开启调度 */ while (1); /* 正常不会执行到这里 */ - + FAIL_EXIT: - printf("failed 0x%x \r\n", ret); + printf("failed 0x%x. \r\n", ret); return 0; } diff --git a/example/freertos_feature/software_timer/sdkconfig b/example/freertos_feature/software_timer/sdkconfig index 9c50f2b0..9183d77b 100644 --- a/example/freertos_feature/software_timer/sdkconfig +++ b/example/freertos_feature/software_timer/sdkconfig @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/software_timer/sdkconfig.h b/example/freertos_feature/software_timer/sdkconfig.h index 2e55f772..80305bac 100644 --- a/example/freertos_feature/software_timer/sdkconfig.h +++ b/example/freertos_feature/software_timer/sdkconfig.h @@ -62,6 +62,7 @@ /* CONFIG_USE_ADC is not set */ /* CONFIG_USE_PWM is not set */ /* CONFIG_USE_IPC is not set */ +/* CONFIG_USE_MEDIA is not set */ /* end of Components Configuration */ #define CONFIG_USE_NEW_LIBC /* end of Standalone Setting */ @@ -98,6 +99,12 @@ /* Compiler Options */ +/* Cross-Compiler Setting */ + +#define CONFIG_GCC_OPTIMIZE_LEVEL 0 +/* CONFIG_USE_EXT_COMPILER is not set */ +/* CONFIG_USE_KLIN_SYS is not set */ +/* end of Cross-Compiler Setting */ #define CONFIG_OUTPUT_BINARY /* end of Compiler Options */ /* end of Building Option */ @@ -127,6 +134,7 @@ /* Freertos Eth Drivers */ /* CONFIG_FREERTOS_USE_XMAC is not set */ +/* CONFIG_FREERTOS_USE_GMAC is not set */ /* end of Freertos Eth Drivers */ /* Freertos Gpio Drivers */ @@ -145,11 +153,6 @@ /* CONFIG_FREERTOS_USE_FGDMA is not set */ /* end of Freertos DMA Drivers */ -/* Freertos MMC Drivers */ - -/* CONFIG_FREERTOS_USE_FSDIO is not set */ -/* end of Freertos MMC Drivers */ - /* Freertos Adc Drivers */ /* CONFIG_FREERTOS_USE_ADC is not set */ @@ -159,13 +162,28 @@ /* CONFIG_FREERTOS_USE_CAN is not set */ /* end of Freertos Can Drivers */ + +/* Freertos I2c Drivers */ + +/* CONFIG_FREERTOS_USE_I2C is not set */ +/* end of Freertos I2c Drivers */ + +/* Freertos Mio Drivers */ + +/* CONFIG_FREERTOS_USE_MIO is not set */ +/* end of Freertos Mio Drivers */ + +/* Freertos Timer Drivers */ + +/* CONFIG_FREERTOS_USE_TIMER is not set */ +/* end of Freertos Timer Drivers */ /* end of Component Configuration */ -/* FreeRTOS Setting */ +/* Third-Party Configuration */ /* CONFIG_USE_LWIP is not set */ #define CONFIG_USE_BACKTRACE -/* CONFIG_USE_FATFS is not set */ +/* CONFIG_USE_FATFS_0_1_4 is not set */ /* CONFIG_USE_SFUD is not set */ /* CONFIG_USE_SPIFFS is not set */ /* CONFIG_USE_AMP is not set */ @@ -181,6 +199,28 @@ /* CONFIG_USE_TLSF is not set */ /* CONFIG_USE_SDMMC_CMD is not set */ /* CONFIG_USE_CHERRY_USB is not set */ -/* end of FreeRTOS Setting */ +/* end of Third-Party Configuration */ + +/* Kernel Configuration */ + +#define CONFIG_FREERTOS_OPTIMIZED_SCHEDULER +#define CONFIG_FREERTOS_HZ 1000 +#define CONFIG_FREERTOS_MAX_PRIORITIES 32 +#define CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES 13 +#define CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES 11 +#define CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS 1 +#define CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE 1024 +#define CONFIG_FREERTOS_MAX_TASK_NAME_LEN 32 +#define CONFIG_FREERTOS_TIMER_TASK_PRIORITY 1 +#define CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH 2048 +#define CONFIG_FREERTOS_TIMER_QUEUE_LENGTH 10 +#define CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE 0 +#define CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS +#define CONFIG_FREERTOS_USE_TRACE_FACILITY +#define CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS +/* CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set */ +#define CONFIG_FREERTOS_TOTAL_HEAP_SIZE 10240 +#define CONFIG_FREERTOS_TASK_FPU_SUPPORT 1 +/* end of Kernel Configuration */ #endif diff --git a/example/freertos_feature/software_timer/src/create_start.c b/example/freertos_feature/software_timer/src/create_start.c index b00d5017..ffccee03 100644 --- a/example/freertos_feature/software_timer/src/create_start.c +++ b/example/freertos_feature/software_timer/src/create_start.c @@ -1,5 +1,5 @@ /* -This example demonstrates: +This example demonstrates: creates and starts a one-shot timer and an auto-reload timer in diffirent period. */ #include "FreeRTOS.h" @@ -7,8 +7,8 @@ creates and starts a one-shot timer and an auto-reload timer in diffirent period #include "timers.h" /* The periods assigned to the one-shot and auto-reload timers respectively. */ -#define ONE_SHOT_TIMER_PERIOD ( pdMS_TO_TICKS( 3000UL ) ) -#define AUTO_RELOAD_TIMER_PERIOD ( pdMS_TO_TICKS( 3000UL ) ) +#define ONE_SHOT_TIMER_PERIOD ( pdMS_TO_TICKS( 3000UL ) ) +#define AUTO_RELOAD_TIMER_PERIOD ( pdMS_TO_TICKS( 3000UL ) ) /*-----------------------------------------------------------*/ @@ -16,108 +16,108 @@ creates and starts a one-shot timer and an auto-reload timer in diffirent period * The callback functions used by the one-shot and auto-reload timers * respectively. */ -static void prvOneShotTimerCallback( TimerHandle_t xTimer ); -static void prvAutoReloadTimerCallback( TimerHandle_t xTimer ); +static void prvOneShotTimerCallback(TimerHandle_t xTimer); +static void prvAutoReloadTimerCallback(TimerHandle_t xTimer); /*-----------------------------------------------------------*/ static TimerHandle_t xAutoReloadTimer, xOneShotTimer; -void CreateTimerTasks( void ) +void CreateTimerTasks(void) { - BaseType_t xTimer1Started, xTimer2Started; - - /* Create the one shot software timer, storing the handle to the created - software timer in xOneShotTimer. */ - xOneShotTimer = xTimerCreate( "Create OneShot", /* Text name for the software timer - not used by FreeRTOS. */ - ONE_SHOT_TIMER_PERIOD, /* The software timer's period in ticks. */ - pdFALSE, /* Setting uxAutoRealod to pdFALSE creates a one-shot software timer. */ - 0, /* This example does not use the timer id. */ - prvOneShotTimerCallback ); /* The callback function to be used by the software timer being created. */ - - /* Create the auto-reload software timer, storing the handle to the created - software timer in xAutoReloadTimer. */ - xAutoReloadTimer = xTimerCreate( "Create AutoReload", /* Text name for the software timer - not used by FreeRTOS. */ - AUTO_RELOAD_TIMER_PERIOD, /* The software timer's period in ticks. */ - pdTRUE, /* Set uxAutoRealod to pdTRUE to create an auto-reload software timer. */ - 0, /* This example does not use the timer id. */ - prvAutoReloadTimerCallback ); /* The callback function to be used by the software timer being created. */ - - /* Check the timers were created. */ - if( ( xOneShotTimer != NULL ) && ( xAutoReloadTimer != NULL ) ) - { - /* Start the software timers, using a block time of 0 (no block time). - The scheduler has not been started yet so any block time specified here - would be ignored anyway. */ - xTimer1Started = xTimerStart( xOneShotTimer, 0 ); - xTimer2Started = xTimerStart( xAutoReloadTimer, 0 ); - - /* The implementation of xTimerStart() uses the timer command queue, and - xTimerStart() will fail if the timer command queue gets full. The timer - service task does not get created until the scheduler is started, so all - commands sent to the command queue will stay in the queue until after - the scheduler has been started. Check both calls to xTimerStart() - passed. */ - if( ( xTimer1Started != pdPASS ) || ( xTimer2Started != pdPASS ) ) - { - vPrintf("CreateSoftwareTimerTasks xTimerStart failed \r\n"); - } - } - else - { - vPrintf("CreateSoftwareTimerTasks xTimerCreate failed \r\n"); - } + BaseType_t xTimer1Started, xTimer2Started; + + /* Create the one shot software timer, storing the handle to the created + software timer in xOneShotTimer. */ + xOneShotTimer = xTimerCreate("Create OneShot", /* Text name for the software timer - not used by FreeRTOS. */ + ONE_SHOT_TIMER_PERIOD, /* The software timer's period in ticks. */ + pdFALSE, /* Setting uxAutoRealod to pdFALSE creates a one-shot software timer. */ + 0, /* This example does not use the timer id. */ + prvOneShotTimerCallback); /* The callback function to be used by the software timer being created. */ + + /* Create the auto-reload software timer, storing the handle to the created + software timer in xAutoReloadTimer. */ + xAutoReloadTimer = xTimerCreate("Create AutoReload", /* Text name for the software timer - not used by FreeRTOS. */ + AUTO_RELOAD_TIMER_PERIOD, /* The software timer's period in ticks. */ + pdTRUE, /* Set uxAutoRealod to pdTRUE to create an auto-reload software timer. */ + 0, /* This example does not use the timer id. */ + prvAutoReloadTimerCallback); /* The callback function to be used by the software timer being created. */ + + /* Check the timers were created. */ + if ((xOneShotTimer != NULL) && (xAutoReloadTimer != NULL)) + { + /* Start the software timers, using a block time of 0 (no block time). + The scheduler has not been started yet so any block time specified here + would be ignored anyway. */ + xTimer1Started = xTimerStart(xOneShotTimer, 0); + xTimer2Started = xTimerStart(xAutoReloadTimer, 0); + + /* The implementation of xTimerStart() uses the timer command queue, and + xTimerStart() will fail if the timer command queue gets full. The timer + service task does not get created until the scheduler is started, so all + commands sent to the command queue will stay in the queue until after + the scheduler has been started. Check both calls to xTimerStart() + passed. */ + if ((xTimer1Started != pdPASS) || (xTimer2Started != pdPASS)) + { + vPrintf("CreateSoftwareTimerTasks xTimerStart failed \r\n"); + } + } + else + { + vPrintf("CreateSoftwareTimerTasks xTimerCreate failed \r\n"); + } } void DeleteTimerTasks(void) { - BaseType_t xReturn = pdFAIL; - xReturn = xTimerDelete(xOneShotTimer, 0); - if(xReturn != pdPASS) - { - vPrintf("DeleteSoftwareTimerTasks xTimerDelete OneShot failed.\r\n"); - } - else - { - vPrintf("DeleteSoftwareTimerTasks xTimerDelete OneShot success.\r\n"); - } - - xReturn = xTimerDelete(xAutoReloadTimer, 0); - if(xReturn != pdPASS) - { - vPrintf("DeleteSoftwareTimerTasks xTimerDelete AutoReload failed.\r\n"); - } - else - { - vPrintf("DeleteSoftwareTimerTasks xTimerDelete AutoReload success.\r\n"); - } + BaseType_t xReturn = pdFAIL; + xReturn = xTimerDelete(xOneShotTimer, 0); + if (xReturn != pdPASS) + { + vPrintf("DeleteSoftwareTimerTasks xTimerDelete OneShot failed.\r\n"); + } + else + { + vPrintf("DeleteSoftwareTimerTasks xTimerDelete OneShot success.\r\n"); + } + + xReturn = xTimerDelete(xAutoReloadTimer, 0); + if (xReturn != pdPASS) + { + vPrintf("DeleteSoftwareTimerTasks xTimerDelete AutoReload failed.\r\n"); + } + else + { + vPrintf("DeleteSoftwareTimerTasks xTimerDelete AutoReload success.\r\n"); + } } /*-----------------------------------------------------------*/ -static void prvOneShotTimerCallback( TimerHandle_t xTimer ) +static void prvOneShotTimerCallback(TimerHandle_t xTimer) { - static TickType_t xTimeNow; + static TickType_t xTimeNow; - /* Obtain the current tick count. */ - xTimeNow = xTaskGetTickCount(); + /* Obtain the current tick count. */ + xTimeNow = xTaskGetTickCount(); - /* Output a string to show the time at which the callback was executed. */ - vPrintf( "One-shot timer callback executing %d ticks.\r\n", xTimeNow ); + /* Output a string to show the time at which the callback was executed. */ + vPrintf("One-shot timer callback executing %d ticks.\r\n", xTimeNow); } /*-----------------------------------------------------------*/ -static void prvAutoReloadTimerCallback( TimerHandle_t xTimer ) +static void prvAutoReloadTimerCallback(TimerHandle_t xTimer) { - static TickType_t xTimeNow; + static TickType_t xTimeNow; - /* Obtain the current tick count. */ - xTimeNow = xTaskGetTickCount(); + /* Obtain the current tick count. */ + xTimeNow = xTaskGetTickCount(); - /* Output a string to show the time at which the callback was executed. */ - vPrintf( "Auto-reload timer callback executing %d ticks.\r\n", xTimeNow ); + /* Output a string to show the time at which the callback was executed. */ + vPrintf("Auto-reload timer callback executing %d ticks.\r\n", xTimeNow); } /*-----------------------------------------------------------*/ diff --git a/example/freertos_feature/software_timer/src/software_timer_cmd.c b/example/freertos_feature/software_timer/src/software_timer_cmd.c index dbd12cba..c5e0904a 100644 --- a/example/freertos_feature/software_timer/src/software_timer_cmd.c +++ b/example/freertos_feature/software_timer/src/software_timer_cmd.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: software_timer_cmd.c * Date: 2022-06-17 10:41:45 * LastEditTime: 2022-06-17 10:41:45 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for software timer command interface + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 wangxiaodong 2022/08/09 first commit */ #include "shell.h" #include @@ -34,15 +35,15 @@ typedef enum static void SoftwareTimerCmdUsage(void) { - printf("usage:\r\n"); + printf("Usage:\r\n"); printf(" timer cre \r\n"); - printf(" -- create and starts a one-shot timer and an auto-reload timer\r\n"); + printf(" -- Create and starts a one-shot timer and an auto-reload timer.\r\n"); printf(" timer del \r\n"); - printf(" -- delete and starts a one-shot timer and an auto-reload timer\r\n"); + printf(" -- Delete and starts a one-shot timer and an auto-reload timer.\r\n"); printf(" timer reset_cre \r\n"); - printf(" -- create software timer use timer id and reset timer\r\n"); + printf(" -- Create software timer use timer id and reset timer.\r\n"); printf(" timer reset_del \r\n"); - printf(" -- del software timer use timer id and reset timer\r\n"); + printf(" -- Del software timer use timer id and reset timer.\r\n"); } @@ -58,55 +59,55 @@ int SoftwareTimerCmd(int argc, char *argv[]) if (!strcmp(argv[1], "cre")) { - if(create_flg[CREATE_START_TASK_INDEX] == 0) + if (create_flg[CREATE_START_TASK_INDEX] == 0) { CreateTimerTasks(); create_flg[CREATE_START_TASK_INDEX] = 1; } else { - printf("Please use del cmd first \r\n"); + printf("Please use del cmd first. \r\n"); } } else if (!strcmp(argv[1], "del")) { - if(create_flg[CREATE_START_TASK_INDEX] == 1) + if (create_flg[CREATE_START_TASK_INDEX] == 1) { DeleteTimerTasks(); create_flg[CREATE_START_TASK_INDEX] = 0; - } + } else { - printf("Please use cre cmd first \r\n"); + printf("Please use cre cmd first. \r\n"); } } else if (!strcmp(argv[1], "reset_cre")) { - if(create_flg[TIMER_ID_TASK_INDEX] == 0) + if (create_flg[TIMER_ID_TASK_INDEX] == 0) { CreateTimerResetTasks(); create_flg[TIMER_ID_TASK_INDEX] = 1; } else { - printf("Please use reset_del cmd first \r\n"); + printf("Please use reset_del cmd first. \r\n"); } } else if (!strcmp(argv[1], "reset_del")) { - if(create_flg[TIMER_ID_TASK_INDEX] == 1) + if (create_flg[TIMER_ID_TASK_INDEX] == 1) { DeleteTimerResetTasks(); create_flg[TIMER_ID_TASK_INDEX] = 0; - } + } else { - printf("Please use reset_cre cmd first \r\n"); + printf("Please use reset_cre cmd first. \r\n"); } } else { - printf("Error: Invalid arguments \r\n"); + printf("Error: Invalid arguments. \r\n"); SoftwareTimerCmdUsage(); } return 0; diff --git a/example/freertos_feature/software_timer/src/timer_id_and_reset.c b/example/freertos_feature/software_timer/src/timer_id_and_reset.c index f52c5120..bbd32f44 100644 --- a/example/freertos_feature/software_timer/src/timer_id_and_reset.c +++ b/example/freertos_feature/software_timer/src/timer_id_and_reset.c @@ -1,8 +1,8 @@ /* -This example demonstrates: +This example demonstrates: how to use the software timer ID as timer specific storage; each software timer keeps a count of the number of times it has expired in its own ID; -Auto reload timer will stop after it has executed 5 times which period is 1000, +Auto reload timer will stop after it has executed 5 times which period is 1000, when the one shot timer is run after 9333 ticks, it will reset auto reload timer. */ #include "FreeRTOS.h" @@ -10,15 +10,15 @@ when the one shot timer is run after 9333 ticks, it will reset auto reload timer #include "timers.h" /* The periods assigned to the one-shot and auto-reload timers respectively. */ -#define ONE_SHOT_TIMER_PERIOD ( pdMS_TO_TICKS( 12000UL ) ) -#define AUTO_RELOAD_TIMER_PERIOD ( pdMS_TO_TICKS( 3000UL ) ) +#define ONE_SHOT_TIMER_PERIOD ( pdMS_TO_TICKS( 12000UL ) ) +#define AUTO_RELOAD_TIMER_PERIOD ( pdMS_TO_TICKS( 3000UL ) ) /*-----------------------------------------------------------*/ /* * The callback function that is used by both timers. */ -static void prvTimerCallback( TimerHandle_t xTimer ); +static void prvTimerCallback(TimerHandle_t xTimer); /*-----------------------------------------------------------*/ @@ -26,122 +26,122 @@ static void prvTimerCallback( TimerHandle_t xTimer ); given file scope. */ static TimerHandle_t xAutoReloadTimer, xOneShotTimer; -void CreateTimerResetTasks( void ) +void CreateTimerResetTasks(void) { -BaseType_t xTimer1Started, xTimer2Started; - - /* Create the one shot timer, storing the handle to the created timer in - xOneShotTimer. */ - xOneShotTimer = xTimerCreate( "Reset OneShot", /* Text name for the timer - not used by FreeRTOS. */ - ONE_SHOT_TIMER_PERIOD, /* The timer's period in ticks. */ - pdFALSE, /* Set uxAutoRealod to pdFALSE to create a one-shot timer. */ - 0, /* The timer ID is initialised to 0. */ - prvTimerCallback ); /* The callback function to be used by the timer being created. */ - - /* Create the auto-reload, storing the handle to the created timer in - xAutoReloadTimer. */ - xAutoReloadTimer = xTimerCreate( "Reset AutoReload", /* Text name for the timer - not used by FreeRTOS. */ - AUTO_RELOAD_TIMER_PERIOD, /* The timer's period in ticks. */ - pdTRUE, /* Set uxAutoRealod to pdTRUE to create an auto-reload timer. */ - 0, /* The timer ID is initialised to 0. */ - prvTimerCallback ); /* The callback function to be used by the timer being created. */ - - /* Check the timers were created. */ - if( ( xOneShotTimer != NULL ) && ( xAutoReloadTimer != NULL ) ) - { - /* Start the timers, using a block time of 0 (no block time). The - scheduler has not been started yet so any block time specified here - would be ignored anyway. */ - xTimer1Started = xTimerStart( xOneShotTimer, 0 ); - xTimer2Started = xTimerStart( xAutoReloadTimer, 0 ); - - /* The implementation of xTimerStart() uses the timer command queue, and - xTimerStart() will fail if the timer command queue gets full. The timer - service task does not get created until the scheduler is started, so all - commands sent to the command queue will stay in the queue until after - the scheduler has been started. Check both calls to xTimerStart() - passed. */ - if( ( xTimer1Started != pdPASS ) || ( xTimer2Started != pdPASS ) ) - { - vPrintString("CreateSoftwareTimerTasks xTimerStart failed \r\n"); - } - } - else - { - vPrintString("CreateSoftwareTimerTasks xTimerCreate failed \r\n"); - } + BaseType_t xTimer1Started, xTimer2Started; + + /* Create the one shot timer, storing the handle to the created timer in + xOneShotTimer. */ + xOneShotTimer = xTimerCreate("Reset OneShot", /* Text name for the timer - not used by FreeRTOS. */ + ONE_SHOT_TIMER_PERIOD, /* The timer's period in ticks. */ + pdFALSE, /* Set uxAutoRealod to pdFALSE to create a one-shot timer. */ + 0, /* The timer ID is initialised to 0. */ + prvTimerCallback); /* The callback function to be used by the timer being created. */ + + /* Create the auto-reload, storing the handle to the created timer in + xAutoReloadTimer. */ + xAutoReloadTimer = xTimerCreate("Reset AutoReload", /* Text name for the timer - not used by FreeRTOS. */ + AUTO_RELOAD_TIMER_PERIOD, /* The timer's period in ticks. */ + pdTRUE, /* Set uxAutoRealod to pdTRUE to create an auto-reload timer. */ + 0, /* The timer ID is initialised to 0. */ + prvTimerCallback); /* The callback function to be used by the timer being created. */ + + /* Check the timers were created. */ + if ((xOneShotTimer != NULL) && (xAutoReloadTimer != NULL)) + { + /* Start the timers, using a block time of 0 (no block time). The + scheduler has not been started yet so any block time specified here + would be ignored anyway. */ + xTimer1Started = xTimerStart(xOneShotTimer, 0); + xTimer2Started = xTimerStart(xAutoReloadTimer, 0); + + /* The implementation of xTimerStart() uses the timer command queue, and + xTimerStart() will fail if the timer command queue gets full. The timer + service task does not get created until the scheduler is started, so all + commands sent to the command queue will stay in the queue until after + the scheduler has been started. Check both calls to xTimerStart() + passed. */ + if ((xTimer1Started != pdPASS) || (xTimer2Started != pdPASS)) + { + vPrintString("CreateSoftwareTimerTasks xTimerStart failed \r\n"); + } + } + else + { + vPrintString("CreateSoftwareTimerTasks xTimerCreate failed \r\n"); + } } void DeleteTimerResetTasks(void) { - BaseType_t xReturn = pdFAIL; - xReturn = xTimerDelete(xOneShotTimer, 0); - if(xReturn != pdPASS) - { - vPrintString("DeleteTimerResetTasks xTimerDelete OneShot failed.\r\n"); - } - else - { - vPrintString("DeleteTimerResetTasks xTimerDelete OneShot success.\r\n"); - } - - xReturn = xTimerDelete(xAutoReloadTimer, 0); - if(xReturn != pdPASS) - { - vPrintString("DeleteTimerResetTasks xTimerDelete AutoReload failed.\r\n"); - } - else - { - vPrintString("DeleteTimerResetTasks xTimerDelete AutoReload success.\r\n"); - } + BaseType_t xReturn = pdFAIL; + xReturn = xTimerDelete(xOneShotTimer, 0); + if (xReturn != pdPASS) + { + vPrintString("DeleteTimerResetTasks xTimerDelete OneShot failed.\r\n"); + } + else + { + vPrintString("DeleteTimerResetTasks xTimerDelete OneShot success.\r\n"); + } + + xReturn = xTimerDelete(xAutoReloadTimer, 0); + if (xReturn != pdPASS) + { + vPrintString("DeleteTimerResetTasks xTimerDelete AutoReload failed.\r\n"); + } + else + { + vPrintString("DeleteTimerResetTasks xTimerDelete AutoReload success.\r\n"); + } } /*-----------------------------------------------------------*/ -static void prvTimerCallback( TimerHandle_t xTimer ) +static void prvTimerCallback(TimerHandle_t xTimer) { - TickType_t xTimeNow; - uint32_t ulExecutionCount; + TickType_t xTimeNow; + uint32_t ulExecutionCount; - /* The count of the number of times this software timer has expired is - stored in the timer's ID. Obtain the ID, increment it, then save it as the - new ID value. The ID is a void pointer, so is cast to a uint32_t. */ - ulExecutionCount = ( uint32_t )(uintptr) pvTimerGetTimerID( xTimer ); - vPrintStringAndNumber( "pvTimerGetTimerID = ", ulExecutionCount ); - ulExecutionCount++; - vTimerSetTimerID( xTimer, ( void * )(uintptr)ulExecutionCount ); + /* The count of the number of times this software timer has expired is + stored in the timer's ID. Obtain the ID, increment it, then save it as the + new ID value. The ID is a void pointer, so is cast to a uint32_t. */ + ulExecutionCount = (uint32_t)(uintptr) pvTimerGetTimerID(xTimer); + vPrintStringAndNumber("pvTimerGetTimerID = ", ulExecutionCount); + ulExecutionCount++; + vTimerSetTimerID(xTimer, (void *)(uintptr)ulExecutionCount); - /* Obtain the current tick count. */ - xTimeNow = xTaskGetTickCount(); + /* Obtain the current tick count. */ + xTimeNow = xTaskGetTickCount(); /* The handle of the one-shot timer was stored in xOneShotTimer when the - timer was created. Compare the handle passed into this function with - xOneShotTimer to determine if it was the one-shot or auto-reload timer that - expired, then output a string to show the time at which the callback was - executed. */ - if( xTimer == xOneShotTimer ) - { - vPrintStringAndNumber( "One-shot timer callback executing", xTimeNow ); - vPrintString( "One-shot timer reset Auto-reload timer "); - xTimerReset( xAutoReloadTimer, 0 ); - } - else - { + timer was created. Compare the handle passed into this function with + xOneShotTimer to determine if it was the one-shot or auto-reload timer that + expired, then output a string to show the time at which the callback was + executed. */ + if (xTimer == xOneShotTimer) + { + vPrintStringAndNumber("One-shot timer callback executing", xTimeNow); + vPrintString("One-shot timer reset Auto-reload timer "); + xTimerReset(xAutoReloadTimer, 0); + } + else + { /* xTimer did not equal xOneShotTimer, so it must be the auto-reload - timer that expired. */ - vPrintStringAndNumber( "Auto-reload timer callback executing", xTimeNow ); - - if( ulExecutionCount == 3 ) - { - /* Stop the auto-reload timer after it has executed 5 times. This - callback function executes in the context of the RTOS daemon task so - must not call any functions that might place the daemon task into - the Blocked state. Therefore a block time of 0 is used. */ - xTimerStop( xTimer, 0 ); - vPrintString( "Auto-reload timer stopped!!! "); - } - } + timer that expired. */ + vPrintStringAndNumber("Auto-reload timer callback executing", xTimeNow); + + if (ulExecutionCount == 3) + { + /* Stop the auto-reload timer after it has executed 5 times. This + callback function executes in the context of the RTOS daemon task so + must not call any functions that might place the daemon task into + the Blocked state. Therefore a block time of 0 is used. */ + xTimerStop(xTimer, 0); + vPrintString("Auto-reload timer stopped!!! "); + } + } } /*-----------------------------------------------------------*/ diff --git a/example/freertos_feature/task/configs/d2000_aarch32_eg_configs b/example/freertos_feature/task/configs/d2000_aarch32_eg_configs index 464a31af..a16785ad 100644 --- a/example/freertos_feature/task/configs/d2000_aarch32_eg_configs +++ b/example/freertos_feature/task/configs/d2000_aarch32_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -111,6 +112,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -147,6 +157,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -168,12 +179,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -185,14 +190,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -210,4 +233,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/task/configs/d2000_aarch64_eg_configs b/example/freertos_feature/task/configs/d2000_aarch64_eg_configs index 64e6b4b7..4731ef2f 100644 --- a/example/freertos_feature/task/configs/d2000_aarch64_eg_configs +++ b/example/freertos_feature/task/configs/d2000_aarch64_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/task/configs/e2000d_aarch32_eg_configs b/example/freertos_feature/task/configs/e2000d_aarch32_eg_configs index fc31cd0b..22902270 100644 --- a/example/freertos_feature/task/configs/e2000d_aarch32_eg_configs +++ b/example/freertos_feature/task/configs/e2000d_aarch32_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -111,6 +112,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -147,6 +157,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -168,12 +179,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -185,14 +190,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -210,4 +233,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/task/configs/e2000d_aarch64_eg_configs b/example/freertos_feature/task/configs/e2000d_aarch64_eg_configs index 7e2efa4f..f3181d35 100644 --- a/example/freertos_feature/task/configs/e2000d_aarch64_eg_configs +++ b/example/freertos_feature/task/configs/e2000d_aarch64_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/task/configs/e2000q_aarch32_eg_configs b/example/freertos_feature/task/configs/e2000q_aarch32_eg_configs index 1b53ed91..17921f8f 100644 --- a/example/freertos_feature/task/configs/e2000q_aarch32_eg_configs +++ b/example/freertos_feature/task/configs/e2000q_aarch32_eg_configs @@ -2,7 +2,7 @@ # # Freertos Configuration # -CONFIG_TARGET_NAME="e2000d_freertos_a32" +CONFIG_TARGET_NAME="e2000q_freertos_a32" # end of Freertos Configuration # @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -111,6 +112,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -147,6 +157,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -168,12 +179,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -185,14 +190,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -210,4 +233,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/task/configs/e2000q_aarch64_eg_configs b/example/freertos_feature/task/configs/e2000q_aarch64_eg_configs index 506efc21..b76f48ee 100644 --- a/example/freertos_feature/task/configs/e2000q_aarch64_eg_configs +++ b/example/freertos_feature/task/configs/e2000q_aarch64_eg_configs @@ -2,7 +2,7 @@ # # Freertos Configuration # -CONFIG_TARGET_NAME="e2000d_freertos_a64" +CONFIG_TARGET_NAME="e2000q_freertos_a64" # end of Freertos Configuration # @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/task/configs/ft2004_aarch32_eg_configs b/example/freertos_feature/task/configs/ft2004_aarch32_eg_configs index 4c5b2c49..f0510b59 100644 --- a/example/freertos_feature/task/configs/ft2004_aarch32_eg_configs +++ b/example/freertos_feature/task/configs/ft2004_aarch32_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -111,6 +112,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -147,6 +157,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -168,12 +179,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -185,14 +190,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -210,4 +233,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/task/configs/ft2004_aarch64_eg_configs b/example/freertos_feature/task/configs/ft2004_aarch64_eg_configs index da9c1f81..d99e8ace 100644 --- a/example/freertos_feature/task/configs/ft2004_aarch64_eg_configs +++ b/example/freertos_feature/task/configs/ft2004_aarch64_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/task/inc/feature_task.h b/example/freertos_feature/task/inc/feature_task.h index 71ee9dd9..764ad760 100644 --- a/example/freertos_feature/task/inc/feature_task.h +++ b/example/freertos_feature/task/inc/feature_task.h @@ -1,30 +1,36 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: feature_task.h * Date: 2022-06-17 10:42:40 * LastEditTime: 2022-06-17 10:42:40 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for task function define + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 wangxiaodong 2022/08/09 first commit */ #ifndef FEATURE_TASK_H #define FEATURE_TASK_H +#ifdef __cplusplus +extern "C" +{ +#endif + /* creating task */ void CreateTasks(void); void DeleteTasks(void); @@ -60,4 +66,8 @@ void DeleteTasksForForIdleTask(void); void CreateTasksForChangePriorityTest(void); void DeleteTasksForChangePriorityTest(void); +#ifdef __cplusplus +} +#endif + #endif // ! \ No newline at end of file diff --git a/example/freertos_feature/task/main.c b/example/freertos_feature/task/main.c index f376d838..f065deb7 100644 --- a/example/freertos_feature/task/main.c +++ b/example/freertos_feature/task/main.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: main.c * Date: 2022-06-17 08:17:59 * LastEditTime: 2022-06-17 08:17:59 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for task example that running shell task and open scheduler + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 wangxiaodong 2022/08/09 first commit */ #include "shell.h" @@ -30,13 +31,15 @@ int main(void) BaseType_t ret; ret = LSUserShellTask() ; - if(ret != pdPASS) + if (ret != pdPASS) + { goto FAIL_EXIT; + } - vTaskStartScheduler(); /* 启动任务,开启调度 */ + vTaskStartScheduler(); /* 启动任务,开启调度 */ while (1); /* 正常不会执行到这里 */ - + FAIL_EXIT: - printf("failed 0x%x \r\n", ret); + printf("failed 0x%x. \r\n", ret); return 0; } diff --git a/example/freertos_feature/task/sdkconfig b/example/freertos_feature/task/sdkconfig index 506efc21..b76f48ee 100644 --- a/example/freertos_feature/task/sdkconfig +++ b/example/freertos_feature/task/sdkconfig @@ -2,7 +2,7 @@ # # Freertos Configuration # -CONFIG_TARGET_NAME="e2000d_freertos_a64" +CONFIG_TARGET_NAME="e2000q_freertos_a64" # end of Freertos Configuration # @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/task/sdkconfig.h b/example/freertos_feature/task/sdkconfig.h index 2ccaa536..0bbbb892 100644 --- a/example/freertos_feature/task/sdkconfig.h +++ b/example/freertos_feature/task/sdkconfig.h @@ -3,7 +3,7 @@ /* Freertos Configuration */ -#define CONFIG_TARGET_NAME "e2000d_freertos_a64" +#define CONFIG_TARGET_NAME "e2000q_freertos_a64" /* end of Freertos Configuration */ /* Standalone Setting */ @@ -62,6 +62,7 @@ /* CONFIG_USE_ADC is not set */ /* CONFIG_USE_PWM is not set */ /* CONFIG_USE_IPC is not set */ +/* CONFIG_USE_MEDIA is not set */ /* end of Components Configuration */ #define CONFIG_USE_NEW_LIBC /* end of Standalone Setting */ @@ -98,6 +99,12 @@ /* Compiler Options */ +/* Cross-Compiler Setting */ + +#define CONFIG_GCC_OPTIMIZE_LEVEL 0 +/* CONFIG_USE_EXT_COMPILER is not set */ +/* CONFIG_USE_KLIN_SYS is not set */ +/* end of Cross-Compiler Setting */ #define CONFIG_OUTPUT_BINARY /* end of Compiler Options */ /* end of Building Option */ @@ -127,6 +134,7 @@ /* Freertos Eth Drivers */ /* CONFIG_FREERTOS_USE_XMAC is not set */ +/* CONFIG_FREERTOS_USE_GMAC is not set */ /* end of Freertos Eth Drivers */ /* Freertos Gpio Drivers */ @@ -145,11 +153,6 @@ /* CONFIG_FREERTOS_USE_FGDMA is not set */ /* end of Freertos DMA Drivers */ -/* Freertos MMC Drivers */ - -/* CONFIG_FREERTOS_USE_FSDIO is not set */ -/* end of Freertos MMC Drivers */ - /* Freertos Adc Drivers */ /* CONFIG_FREERTOS_USE_ADC is not set */ @@ -159,13 +162,28 @@ /* CONFIG_FREERTOS_USE_CAN is not set */ /* end of Freertos Can Drivers */ + +/* Freertos I2c Drivers */ + +/* CONFIG_FREERTOS_USE_I2C is not set */ +/* end of Freertos I2c Drivers */ + +/* Freertos Mio Drivers */ + +/* CONFIG_FREERTOS_USE_MIO is not set */ +/* end of Freertos Mio Drivers */ + +/* Freertos Timer Drivers */ + +/* CONFIG_FREERTOS_USE_TIMER is not set */ +/* end of Freertos Timer Drivers */ /* end of Component Configuration */ -/* FreeRTOS Setting */ +/* Third-Party Configuration */ /* CONFIG_USE_LWIP is not set */ #define CONFIG_USE_BACKTRACE -/* CONFIG_USE_FATFS is not set */ +/* CONFIG_USE_FATFS_0_1_4 is not set */ /* CONFIG_USE_SFUD is not set */ /* CONFIG_USE_SPIFFS is not set */ /* CONFIG_USE_AMP is not set */ @@ -181,6 +199,28 @@ #define CONFIG_USE_TLSF /* CONFIG_USE_SDMMC_CMD is not set */ /* CONFIG_USE_CHERRY_USB is not set */ -/* end of FreeRTOS Setting */ +/* end of Third-Party Configuration */ + +/* Kernel Configuration */ + +#define CONFIG_FREERTOS_OPTIMIZED_SCHEDULER +#define CONFIG_FREERTOS_HZ 1000 +#define CONFIG_FREERTOS_MAX_PRIORITIES 32 +#define CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES 13 +#define CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES 11 +#define CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS 1 +#define CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE 1024 +#define CONFIG_FREERTOS_MAX_TASK_NAME_LEN 32 +#define CONFIG_FREERTOS_TIMER_TASK_PRIORITY 1 +#define CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH 2048 +#define CONFIG_FREERTOS_TIMER_QUEUE_LENGTH 10 +#define CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE 0 +#define CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS +#define CONFIG_FREERTOS_USE_TRACE_FACILITY +#define CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS +/* CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set */ +#define CONFIG_FREERTOS_TOTAL_HEAP_SIZE 10240 +#define CONFIG_FREERTOS_TASK_FPU_SUPPORT 1 +/* end of Kernel Configuration */ #endif diff --git a/example/freertos_feature/task/src/block_state.c b/example/freertos_feature/task/src/block_state.c index 5c243172..0b9ccb24 100644 --- a/example/freertos_feature/task/src/block_state.c +++ b/example/freertos_feature/task/src/block_state.c @@ -1,18 +1,18 @@ /* -This example demonstrates: +This example demonstrates: how to make task block state; */ #include "FreeRTOSConfig.h" #include "FreeRTOS.h" #include "task.h" -#define TASK_STACK_SIZE 1024 +#define TASK_STACK_SIZE 1024 static xTaskHandle xtask1_handle; static xTaskHandle xtask2_handle; /* The task function. */ -static void vTaskFunction( void *pvParameters ); +static void vTaskFunction(void *pvParameters); /* Define the strings that will be passed in as the task parameters. These are defined const and off the stack to ensure they remain valid when the tasks are @@ -22,28 +22,28 @@ static const char *pcTextForTask2 = "Block Task 2 is running\r\n"; /*-----------------------------------------------------------*/ -void CreateTasksForBlockTest( void ) +void CreateTasksForBlockTest(void) { - /* Create the first task at priority 1... */ - xTaskCreate( vTaskFunction, "Block Task 1", TASK_STACK_SIZE, (void*)pcTextForTask1, 1, &xtask1_handle ); + /* Create the first task at priority 1... */ + xTaskCreate(vTaskFunction, "Block Task 1", TASK_STACK_SIZE, (void *)pcTextForTask1, 1, &xtask1_handle); + + /* ... and the second task at priority 2. The priority is the second to + last parameter. */ + xTaskCreate(vTaskFunction, "Block Task 2", TASK_STACK_SIZE, (void *)pcTextForTask2, 2, &xtask2_handle); - /* ... and the second task at priority 2. The priority is the second to - last parameter. */ - xTaskCreate( vTaskFunction, "Block Task 2", TASK_STACK_SIZE, (void*)pcTextForTask2, 2, &xtask2_handle ); - } void DeleteTasksForBlockTest(void) { - if(xtask1_handle) + if (xtask1_handle) { vTaskDelete(xtask1_handle); vPrintString("DeleteTasksForBlockTest Task parameter 1 deletion \r\n"); } - if(xtask2_handle) + if (xtask2_handle) { vTaskDelete(xtask2_handle); vPrintString("DeleteTasksForBlockTest Task parameter 2 deletion \r\n"); @@ -52,27 +52,27 @@ void DeleteTasksForBlockTest(void) /*-----------------------------------------------------------*/ -static void vTaskFunction( void *pvParameters ) +static void vTaskFunction(void *pvParameters) { char *pcTaskName; - const TickType_t xDelay = pdMS_TO_TICKS( 3000UL ); - - /* The string to print out is passed in via the parameter. Cast this to a - character pointer. */ - pcTaskName = ( char * ) pvParameters; - - /* As per most tasks, this task is implemented in an infinite loop. */ - for( ;; ) - { - /* Print out the name of this task. */ - vPrintString( pcTaskName ); - - /* Delay for a period. This time a call to vTaskDelay() is used which - places the task into the Blocked state until the delay period has - expired. The parameter takes a time specified in 'ticks', and the - pdMS_TO_TICKS() macro is used (where the xDelay constant is - declared) to convert 3000 milliseconds into an equivalent time in - ticks. */ - vTaskDelay( xDelay); - } + const TickType_t xDelay = pdMS_TO_TICKS(3000UL); + + /* The string to print out is passed in via the parameter. Cast this to a + character pointer. */ + pcTaskName = (char *) pvParameters; + + /* As per most tasks, this task is implemented in an infinite loop. */ + for (;;) + { + /* Print out the name of this task. */ + vPrintString(pcTaskName); + + /* Delay for a period. This time a call to vTaskDelay() is used which + places the task into the Blocked state until the delay period has + expired. The parameter takes a time specified in 'ticks', and the + pdMS_TO_TICKS() macro is used (where the xDelay constant is + declared) to convert 3000 milliseconds into an equivalent time in + ticks. */ + vTaskDelay(xDelay); + } } diff --git a/example/freertos_feature/task/src/change_priority.c b/example/freertos_feature/task/src/change_priority.c index cf86ab80..d62ead9d 100644 --- a/example/freertos_feature/task/src/change_priority.c +++ b/example/freertos_feature/task/src/change_priority.c @@ -1,15 +1,15 @@ /* -This example demonstrates: +This example demonstrates: how to change task priority; */ #include "FreeRTOS.h" #include "task.h" -#define TASK_STACK_SIZE 1024 +#define TASK_STACK_SIZE 1024 /* The two task functions. */ -static void vTask1( void *pvParameters ); -static void vTask2( void *pvParameters ); +static void vTask1(void *pvParameters); +static void vTask2(void *pvParameters); /* Used to hold the handle. */ TaskHandle_t xtask1_handle; @@ -17,32 +17,32 @@ TaskHandle_t xtask2_handle; /*-----------------------------------------------------------*/ -void CreateTasksForChangePriorityTest( void ) +void CreateTasksForChangePriorityTest(void) { - /* Create the first task at priority 2. This time the task parameter is - not used and is set to NULL. The task handle is also not used so likewise - is also set to NULL. */ - xTaskCreate( vTask1, "ChangePriority Task 1", TASK_STACK_SIZE, NULL, 2, &xtask1_handle ); - /* The task is created at priority 2 ^. */ - - /* Create the second task at priority 1 - which is lower than the priority - given to Task1. Again the task parameter is not used so is set to NULL - - BUT this time we want to obtain a handle to the task so pass in the address - of the xtask2_handle variable. */ - xTaskCreate( vTask2, "ChangePriority Task 2", TASK_STACK_SIZE, NULL, 1, &xtask2_handle ); - /* The task handle is the last parameter ^^^^^^^^^^^^^ */ + /* Create the first task at priority 2. This time the task parameter is + not used and is set to NULL. The task handle is also not used so likewise + is also set to NULL. */ + xTaskCreate(vTask1, "ChangePriority Task 1", TASK_STACK_SIZE, NULL, 2, &xtask1_handle); + /* The task is created at priority 2 ^. */ + + /* Create the second task at priority 1 - which is lower than the priority + given to Task1. Again the task parameter is not used so is set to NULL - + BUT this time we want to obtain a handle to the task so pass in the address + of the xtask2_handle variable. */ + xTaskCreate(vTask2, "ChangePriority Task 2", TASK_STACK_SIZE, NULL, 1, &xtask2_handle); + /* The task handle is the last parameter ^^^^^^^^^^^^^ */ } void DeleteTasksForChangePriorityTest(void) { - if(xtask1_handle) + if (xtask1_handle) { vTaskDelete(xtask1_handle); vPrintString("ChangePriority Task1 deletion \r\n"); } - if(xtask2_handle) + if (xtask2_handle) { vTaskDelete(xtask2_handle); vPrintString("ChangePriority Task2 deletion \r\n"); @@ -50,66 +50,66 @@ void DeleteTasksForChangePriorityTest(void) } /*-----------------------------------------------------------*/ -void vTask1( void *pvParameters ) +void vTask1(void *pvParameters) { - UBaseType_t uxPriority; - - /* This task will always run before Task2 as it has the higher priority. - Neither Task1 nor Task2 ever block so both will always be in either the - Running or the Ready state. - - Query the priority at which this task is running - passing in NULL means - "return our own priority". */ - uxPriority = uxTaskPriorityGet( NULL ); - - for( ;; ) - { - /* Print out the name of this task. */ - vPrintf( "ChangePriority Task1 is running, Task1 Priority=%d\r\n", uxPriority ); - - /* Setting the Task2 priority above the Task1 priority will cause - Task2 to immediately start running (as then Task2 will have the higher - priority of the two created tasks). */ - vPrintString( "ChangePriority About to raise the Task2 priority\r\n" ); - vTaskPrioritySet( xtask2_handle, ( uxPriority + 1 ) ); - - /* Task1 will only run when it has a priority higher than Task2. - Therefore, for this task to reach this point Task2 must already have - executed and set its priority back down to 0. */ - vTaskDelay(3000); - } + UBaseType_t uxPriority; + + /* This task will always run before Task2 as it has the higher priority. + Neither Task1 nor Task2 ever block so both will always be in either the + Running or the Ready state. + + Query the priority at which this task is running - passing in NULL means + "return our own priority". */ + uxPriority = uxTaskPriorityGet(NULL); + + for (;;) + { + /* Print out the name of this task. */ + vPrintf("ChangePriority Task1 is running, Task1 Priority=%d\r\n", uxPriority); + + /* Setting the Task2 priority above the Task1 priority will cause + Task2 to immediately start running (as then Task2 will have the higher + priority of the two created tasks). */ + vPrintString("ChangePriority About to raise the Task2 priority\r\n"); + vTaskPrioritySet(xtask2_handle, (uxPriority + 1)); + + /* Task1 will only run when it has a priority higher than Task2. + Therefore, for this task to reach this point Task2 must already have + executed and set its priority back down to 0. */ + vTaskDelay(3000); + } } /*-----------------------------------------------------------*/ -void vTask2( void *pvParameters ) +void vTask2(void *pvParameters) { - UBaseType_t uxPriority; - - /* Task1 will always run before this task as Task1 has the higher priority. - Neither Task1 nor Task2 ever block so will always be in either the - Running or the Ready state. - - Query the priority at which this task is running - passing in NULL means - "return our own priority". */ - uxPriority = uxTaskPriorityGet( NULL ); - - for( ;; ) - { - /* For this task to reach this point Task1 must have already run and - set the priority of this task higher than its own. - - Print out the name of this task. */ - vPrintf( "ChangePriority Task2 is running, Task2 Priority=%d\r\n", uxPriority); - - /* Set our priority back down to its original value. Passing in NULL - as the task handle means "change our own priority". Setting the - priority below that of Task1 will cause Task1 to immediately start - running again. */ - vPrintString( "ChangePriority About to lower the Task2 priority\r\n" ); - vTaskPrioritySet( NULL, ( uxPriority - 2 ) ); - vTaskDelay(3000); - } + UBaseType_t uxPriority; + + /* Task1 will always run before this task as Task1 has the higher priority. + Neither Task1 nor Task2 ever block so will always be in either the + Running or the Ready state. + + Query the priority at which this task is running - passing in NULL means + "return our own priority". */ + uxPriority = uxTaskPriorityGet(NULL); + + for (;;) + { + /* For this task to reach this point Task1 must have already run and + set the priority of this task higher than its own. + + Print out the name of this task. */ + vPrintf("ChangePriority Task2 is running, Task2 Priority=%d\r\n", uxPriority); + + /* Set our priority back down to its original value. Passing in NULL + as the task handle means "change our own priority". Setting the + priority below that of Task1 will cause Task1 to immediately start + running again. */ + vPrintString("ChangePriority About to lower the Task2 priority\r\n"); + vTaskPrioritySet(NULL, (uxPriority - 2)); + vTaskDelay(3000); + } } /*-----------------------------------------------------------*/ diff --git a/example/freertos_feature/task/src/creating_tasks.c b/example/freertos_feature/task/src/creating_tasks.c index c1d9d1c8..a3866869 100644 --- a/example/freertos_feature/task/src/creating_tasks.c +++ b/example/freertos_feature/task/src/creating_tasks.c @@ -1,47 +1,47 @@ /* -This example demonstrates: +This example demonstrates: how to create and delete tasks; */ #include "FreeRTOSConfig.h" #include "FreeRTOS.h" #include "task.h" -#define DELAY_LOOP_COUNT ( 0x1fffffff ) -#define TASK_STACK_SIZE 1024 +#define DELAY_LOOP_COUNT ( 0x1fffffff ) +#define TASK_STACK_SIZE 1024 static xTaskHandle xtask1_handle; static xTaskHandle xtask2_handle; /* The task functions. */ -static void vTask1( void *pvParameters ); -static void vTask2( void *pvParameters ); +static void vTask1(void *pvParameters); +static void vTask2(void *pvParameters); /*-----------------------------------------------------------*/ -void CreateTasks( void ) +void CreateTasks(void) { - /* Create one of the two tasks. */ - xTaskCreate( vTask1, /* Pointer to the function that implements the task. */ - "Create Task 1", /* Text name for the task. This is to facilitate debugging only. */ - TASK_STACK_SIZE, /* Stack depth - most small microcontrollers will use much less stack than this. */ - NULL, /* We are not using the task parameter. */ - 1, /* This task will run at priority 1. */ - &xtask1_handle ); /* We are using the task handle to delete this task. */ + /* Create one of the two tasks. */ + xTaskCreate(vTask1, /* Pointer to the function that implements the task. */ + "Create Task 1", /* Text name for the task. This is to facilitate debugging only. */ + TASK_STACK_SIZE, /* Stack depth - most small microcontrollers will use much less stack than this. */ + NULL, /* We are not using the task parameter. */ + 1, /* This task will run at priority 1. */ + &xtask1_handle); /* We are using the task handle to delete this task. */ - /* Create the other task in exactly the same way. */ - xTaskCreate( vTask2, "Create Task 2", TASK_STACK_SIZE, NULL, 1, &xtask2_handle ); + /* Create the other task in exactly the same way. */ + xTaskCreate(vTask2, "Create Task 2", TASK_STACK_SIZE, NULL, 1, &xtask2_handle); } void DeleteTasks(void) { - if(xtask1_handle) + if (xtask1_handle) { vTaskDelete(xtask1_handle); vPrintString("DeleteTasks Task1 deletion \r\n"); } - if(xtask2_handle) + if (xtask2_handle) { vTaskDelete(xtask2_handle); vPrintString("DeleteTasks Task2 deletion \r\n"); @@ -50,45 +50,45 @@ void DeleteTasks(void) /*-----------------------------------------------------------*/ -static void vTask1( void *pvParameters ) +static void vTask1(void *pvParameters) { - const char *pcTaskName = "Create Task 1 is running\r\n"; - volatile uint32_t ul; - - /* As per most tasks, this task is implemented in an infinite loop. */ - for( ;; ) - { - /* Print out the name of this task. */ - vPrintString( pcTaskName ); - - /* Delay for a period. */ - for( ul = 0; ul < DELAY_LOOP_COUNT; ul++ ) - { - /* This loop is just a very crude delay implementation. There is - nothing to do in here. Later exercises will replace this crude - loop with a proper delay/sleep function. */ - } - } + const char *pcTaskName = "Create Task 1 is running\r\n"; + volatile uint32_t ul; + + /* As per most tasks, this task is implemented in an infinite loop. */ + for (;;) + { + /* Print out the name of this task. */ + vPrintString(pcTaskName); + + /* Delay for a period. */ + for (ul = 0; ul < DELAY_LOOP_COUNT; ul++) + { + /* This loop is just a very crude delay implementation. There is + nothing to do in here. Later exercises will replace this crude + loop with a proper delay/sleep function. */ + } + } } /*-----------------------------------------------------------*/ -static void vTask2( void *pvParameters ) +static void vTask2(void *pvParameters) { const char *pcTaskName = "Create Task 2 is running\r\n"; volatile uint32_t ul; - /* As per most tasks, this task is implemented in an infinite loop. */ - for( ;; ) - { - /* Print out the name of this task. */ - vPrintString( pcTaskName ); - - /* Delay for a period. */ - for( ul = 0; ul < DELAY_LOOP_COUNT; ul++ ) - { - /* This loop is just a very crude delay implementation. There is - nothing to do in here. Later exercises will replace this crude - loop with a proper delay/sleep function. */ - } - } + /* As per most tasks, this task is implemented in an infinite loop. */ + for (;;) + { + /* Print out the name of this task. */ + vPrintString(pcTaskName); + + /* Delay for a period. */ + for (ul = 0; ul < DELAY_LOOP_COUNT; ul++) + { + /* This loop is just a very crude delay implementation. There is + nothing to do in here. Later exercises will replace this crude + loop with a proper delay/sleep function. */ + } + } } \ No newline at end of file diff --git a/example/freertos_feature/task/src/idle_task_hook.c b/example/freertos_feature/task/src/idle_task_hook.c index 27b1bdc6..01f9e5ba 100644 --- a/example/freertos_feature/task/src/idle_task_hook.c +++ b/example/freertos_feature/task/src/idle_task_hook.c @@ -2,13 +2,13 @@ #include "FreeRTOS.h" #include "task.h" -#define TASK_STACK_SIZE 1024 +#define TASK_STACK_SIZE 1024 static xTaskHandle xtask1_handle; static xTaskHandle xtask2_handle; /* The task function. */ -static void vTaskFunction( void *pvParameters ); +static void vTaskFunction(void *pvParameters); /* A variable that is incremented by the idle task hook function. */ static uint32_t ulIdleCycleCount = 0UL; @@ -25,35 +25,35 @@ void CreateTasksForIdleTask(void) { BaseType_t ret; - /* Create the first task at priority 1... */ - ret = xTaskCreate( vTaskFunction, "Idle Task 1", - TASK_STACK_SIZE, (void*)pcTextForTask1, 1, &xtask1_handle ); - if(ret != pdPASS) + /* Create the first task at priority 1... */ + ret = xTaskCreate(vTaskFunction, "Idle Task 1", + TASK_STACK_SIZE, (void *)pcTextForTask1, 1, &xtask1_handle); + if (ret != pdPASS) { xtask1_handle = NULL; vPrintStringAndNumber("Idle Task 1 create failed: ", ret); } - /* ... and the second task at priority 2. The priority is the second to - last parameter. */ - ret = xTaskCreate( vTaskFunction, "Idle Task 2", - TASK_STACK_SIZE, (void*)pcTextForTask2, 2, &xtask2_handle ); - if(ret != pdPASS) + /* ... and the second task at priority 2. The priority is the second to + last parameter. */ + ret = xTaskCreate(vTaskFunction, "Idle Task 2", + TASK_STACK_SIZE, (void *)pcTextForTask2, 2, &xtask2_handle); + if (ret != pdPASS) { xtask1_handle = NULL; vPrintStringAndNumber("Idle Task 2 create failed: ", ret); } - + } void DeleteTasksForForIdleTask(void) { - if(xtask1_handle) + if (xtask1_handle) { vTaskDelete(xtask1_handle); vPrintString("Idle Task 1 deletion \r\n"); } - if(xtask2_handle) + if (xtask2_handle) { vTaskDelete(xtask2_handle); vPrintString("Idle Task 2 deletion \r\n"); @@ -62,34 +62,34 @@ void DeleteTasksForForIdleTask(void) /*-----------------------------------------------------------*/ -static void vTaskFunction( void *pvParameters ) +static void vTaskFunction(void *pvParameters) { char *pcTaskName; - const TickType_t xDelay = pdMS_TO_TICKS( 5000UL ); + const TickType_t xDelay = pdMS_TO_TICKS(5000UL); - /* The string to print out is passed in via the parameter. Cast this to a - character pointer. */ - pcTaskName = ( char * ) pvParameters; + /* The string to print out is passed in via the parameter. Cast this to a + character pointer. */ + pcTaskName = (char *) pvParameters; - /* As per most tasks, this task is implemented in an infinite loop. */ - for( ;; ) - { - /* Print out the name of this task AND the number of times ulIdleCycleCount + /* As per most tasks, this task is implemented in an infinite loop. */ + for (;;) + { + /* Print out the name of this task AND the number of times ulIdleCycleCount has been incremented. */ - vPrintf( "%s, count: %lu\n", pcTaskName, ulIdleCycleCount); + vPrintf("%s, count: %lu\n", pcTaskName, ulIdleCycleCount); - /* Delay for a period. This time we use a call to vTaskDelay() which - puts the task into the Blocked state until the delay period has expired. - The delay period is specified in 'ticks'. */ - vTaskDelay( xDelay ); - } + /* Delay for a period. This time we use a call to vTaskDelay() which + puts the task into the Blocked state until the delay period has expired. + The delay period is specified in 'ticks'. */ + vTaskDelay(xDelay); + } } /*-----------------------------------------------------------*/ /* Idle hook functions MUST be called vApplicationIdleHook(), take no parameters, and return void. */ -void vApplicationIdleHook( void ) +void vApplicationIdleHook(void) { - /* This hook function does nothing but increment a counter. */ - ulIdleCycleCount++; + /* This hook function does nothing but increment a counter. */ + ulIdleCycleCount++; } diff --git a/example/freertos_feature/task/src/priority_task.c b/example/freertos_feature/task/src/priority_task.c index 37b79caa..c9a5d42c 100644 --- a/example/freertos_feature/task/src/priority_task.c +++ b/example/freertos_feature/task/src/priority_task.c @@ -1,5 +1,5 @@ /* -This example demonstrates: +This example demonstrates: how to create and delete tasks use priority; */ #include "FreeRTOSConfig.h" @@ -7,15 +7,15 @@ how to create and delete tasks use priority; #include "task.h" /* Used as a loop counter to create a very crude delay. */ -#define DELAY_LOOP_COUNT ( 0x1fffffff ) +#define DELAY_LOOP_COUNT ( 0x1fffffff ) -#define TASK_STACK_SIZE 1024 +#define TASK_STACK_SIZE 1024 static xTaskHandle xtask1_handle; static xTaskHandle xtask2_handle; /* The task function. */ -static void vTaskFunction( void *pvParameters ); +static void vTaskFunction(void *pvParameters); /* Define the strings that will be passed in as the task parameters. These are defined const and off the stack to ensure they remain valid when the tasks are @@ -27,23 +27,23 @@ static const char *pcTextForTask2 = "Priority Task 2 is running\r\n"; void CreateTasksForPriorityTest(void) { - /* Create the first task at priority 1... */ - xTaskCreate( vTaskFunction, "Priority Task 1", TASK_STACK_SIZE, (void*)pcTextForTask1, 1, &xtask1_handle ); + /* Create the first task at priority 1... */ + xTaskCreate(vTaskFunction, "Priority Task 1", TASK_STACK_SIZE, (void *)pcTextForTask1, 1, &xtask1_handle); - /* ... and the second task at priority 2. The priority is the second to - last parameter. */ - xTaskCreate( vTaskFunction, "Priority Task 2", TASK_STACK_SIZE, (void*)pcTextForTask2, 2, &xtask2_handle ); + /* ... and the second task at priority 2. The priority is the second to + last parameter. */ + xTaskCreate(vTaskFunction, "Priority Task 2", TASK_STACK_SIZE, (void *)pcTextForTask2, 2, &xtask2_handle); } void DeleteTasksForPriorityTest(void) { - if(xtask1_handle) + if (xtask1_handle) { vTaskDelete(xtask1_handle); vPrintString("DeleteTasksForPriorityTest Task priority 1 deletion \r\n"); } - if(xtask2_handle) + if (xtask2_handle) { vTaskDelete(xtask2_handle); vPrintString("DeleteTasksForPriorityTest Task priority 2 deletion \r\n"); @@ -52,27 +52,27 @@ void DeleteTasksForPriorityTest(void) } /*-----------------------------------------------------------*/ -static void vTaskFunction( void *pvParameters ) +static void vTaskFunction(void *pvParameters) { - char *pcTaskName; - volatile uint32_t ul; + char *pcTaskName; + volatile uint32_t ul; - /* The string to print out is passed in via the parameter. Cast this to a - character pointer. */ - pcTaskName = ( char * ) pvParameters; + /* The string to print out is passed in via the parameter. Cast this to a + character pointer. */ + pcTaskName = (char *) pvParameters; - /* As per most tasks, this task is implemented in an infinite loop. */ - for( ;; ) - { - /* Print out the name of this task. */ - vPrintString( pcTaskName ); + /* As per most tasks, this task is implemented in an infinite loop. */ + for (;;) + { + /* Print out the name of this task. */ + vPrintString(pcTaskName); - /* Delay for a period. */ - for( ul = 0; ul < DELAY_LOOP_COUNT; ul++ ) - { - /* This loop is just a very crude delay implementation. There is - nothing to do in here. Later exercises will replace this crude - loop with a proper delay/sleep function. */ - } - } + /* Delay for a period. */ + for (ul = 0; ul < DELAY_LOOP_COUNT; ul++) + { + /* This loop is just a very crude delay implementation. There is + nothing to do in here. Later exercises will replace this crude + loop with a proper delay/sleep function. */ + } + } } diff --git a/example/freertos_feature/task/src/task_cmd.c b/example/freertos_feature/task/src/task_cmd.c index 7a0256a8..f943b688 100644 --- a/example/freertos_feature/task/src/task_cmd.c +++ b/example/freertos_feature/task/src/task_cmd.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: task_cmd.c * Date: 2022-06-17 10:41:45 * LastEditTime: 2022-06-17 10:41:45 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for task example command interface + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 wangxiaodong 2022/08/09 first commit */ #include "shell.h" #include "feature_task.h" @@ -28,51 +29,51 @@ typedef enum { CREATING_TASK_INDEX = 0, - PARAMETERS_TEST_INDEX = 1 , - PRIORITY_TEST_INDEX , - BLOCK_STATE_TEST_INDEX , - DELAY_UNTIL_TEST_INDEX , + PARAMETERS_TEST_INDEX = 1, + PRIORITY_TEST_INDEX, + BLOCK_STATE_TEST_INDEX, + DELAY_UNTIL_TEST_INDEX, BLOCKING_NON_BLOCKING_INDEX, - IDLE_TEST_INDEX , - CHANGE_PRIORITY_TEST_INDEX , + IDLE_TEST_INDEX, + CHANGE_PRIORITY_TEST_INDEX, TASK_FEATURE_LENGTH } FreeRtosTaskFeatureSelect; static void CreateTasksCmdUsage(void) { - printf("usage:\r\n"); + printf("Usage:\r\n"); printf(" task cre \r\n"); - printf(" -- create tasks now \r\n"); + printf(" -- Create tasks now. \r\n"); printf(" task del \r\n"); - printf(" -- del tasks now \r\n"); + printf(" -- Del tasks now. \r\n"); printf(" task para_cre \r\n"); - printf(" -- create parameter test tasks now \r\n"); + printf(" -- Create parameter test tasks now. \r\n"); printf(" task para_del \r\n"); - printf(" -- del parameter test tasks now \r\n"); + printf(" -- Del parameter test tasks now. \r\n"); printf(" task pri_cre \r\n"); - printf(" -- create priority test tasks now \r\n"); + printf(" -- Create priority test tasks now. \r\n"); printf(" task pri_del \r\n"); - printf(" -- del priority test tasks now \r\n"); + printf(" -- Del priority test tasks now. \r\n"); printf(" task blo_cre \r\n"); - printf(" -- create block state test tasks now \r\n"); + printf(" -- Create block state test tasks now. \r\n"); printf(" task blo_del \r\n"); - printf(" -- del block state test tasks now \r\n"); + printf(" -- Del block state test tasks now. \r\n"); printf(" task dn_cre \r\n"); - printf(" -- create task until test tasks now \r\n"); + printf(" -- Create task until test tasks now. \r\n"); printf(" task dn_del \r\n"); - printf(" -- del task until test tasks now \r\n"); + printf(" -- Del task until test tasks now. \r\n"); printf(" task bn_cre \r\n"); - printf(" -- create task combining blocking non blocking tasks now \r\n"); + printf(" -- Create task combining blocking non blocking tasks now. \r\n"); printf(" task bn_del \r\n"); - printf(" -- del task combining blocking non blocking tasks now \r\n"); + printf(" -- Del task combining blocking non blocking tasks now. \r\n"); printf(" task idle_cre \r\n"); - printf(" -- create task idle tasks now \r\n"); + printf(" -- Create task idle tasks now. \r\n"); printf(" task idle_del \r\n"); - printf(" -- del task idle tasks now \r\n"); + printf(" -- Del task idle tasks now \r\n"); printf(" task cha_cre \r\n"); - printf(" -- create task change priority tasks now \r\n"); + printf(" -- Create task change priority tasks now. \r\n"); printf(" task cha_del \r\n"); - printf(" -- del task change priority tasks now \r\n"); + printf(" -- Del task change priority tasks now. \r\n"); } @@ -88,199 +89,199 @@ int CreateTasksCmd(int argc, char *argv[]) if (!strcmp(argv[1], "cre")) { - if(create_flg[CREATING_TASK_INDEX] == 0) + if (create_flg[CREATING_TASK_INDEX] == 0) { CreateTasks(); create_flg[CREATING_TASK_INDEX] = 1; } else { - printf("Please use del cmd first \r\n"); + printf("Please use del cmd first. \r\n"); } } else if (!strcmp(argv[1], "del")) { - if(create_flg[CREATING_TASK_INDEX] == 1) + if (create_flg[CREATING_TASK_INDEX] == 1) { DeleteTasks(); create_flg[CREATING_TASK_INDEX] = 0; - } + } else { - printf("Please use cre cmd first \r\n"); + printf("Please use cre cmd first. \r\n"); } } else if (!strcmp(argv[1], "para_cre")) { - if(create_flg[PARAMETERS_TEST_INDEX] == 0) + if (create_flg[PARAMETERS_TEST_INDEX] == 0) { CreateTasksForParamterTest(); create_flg[PARAMETERS_TEST_INDEX] = 1; } else { - printf("Please use task para_del cmd first \r\n"); + printf("Please use task para_del cmd first. \r\n"); } } else if (!strcmp(argv[1], "para_del")) { - if(create_flg[PARAMETERS_TEST_INDEX] == 1) + if (create_flg[PARAMETERS_TEST_INDEX] == 1) { DeleteTasksForParamterTest(); create_flg[PARAMETERS_TEST_INDEX] = 0; - } + } else { - printf("Please use task para_cre cmd first \r\n"); + printf("Please use task para_cre cmd first. \r\n"); } } else if (!strcmp(argv[1], "pri_cre")) { - if(create_flg[PRIORITY_TEST_INDEX] == 0) + if (create_flg[PRIORITY_TEST_INDEX] == 0) { CreateTasksForPriorityTest(); create_flg[PRIORITY_TEST_INDEX] = 1; } else { - printf("Please use task pri_del cmd first \r\n"); + printf("Please use task pri_del cmd first. \r\n"); } } else if (!strcmp(argv[1], "pri_del")) { - if(create_flg[PRIORITY_TEST_INDEX] == 1) + if (create_flg[PRIORITY_TEST_INDEX] == 1) { DeleteTasksForPriorityTest(); create_flg[PRIORITY_TEST_INDEX] = 0; - } + } else { - printf("Please use task pri_cre cmd first \r\n"); + printf("Please use task pri_cre cmd first. \r\n"); } } else if (!strcmp(argv[1], "blo_cre")) { - if(create_flg[BLOCK_STATE_TEST_INDEX] == 0) + if (create_flg[BLOCK_STATE_TEST_INDEX] == 0) { CreateTasksForBlockTest(); create_flg[BLOCK_STATE_TEST_INDEX] = 1; } else { - printf("Please use task blo_del cmd first \r\n"); + printf("Please use task blo_del cmd first. \r\n"); } } else if (!strcmp(argv[1], "blo_del")) { - if(create_flg[BLOCK_STATE_TEST_INDEX] == 1) + if (create_flg[BLOCK_STATE_TEST_INDEX] == 1) { DeleteTasksForBlockTest(); create_flg[BLOCK_STATE_TEST_INDEX] = 0; - } + } else { - printf("Please use task blo_cre cmd first \r\n"); + printf("Please use task blo_cre cmd first. \r\n"); } } else if (!strcmp(argv[1], "dn_cre")) { - if(create_flg[DELAY_UNTIL_TEST_INDEX] == 0) + if (create_flg[DELAY_UNTIL_TEST_INDEX] == 0) { CreateTasksForDelayUntilTest(); create_flg[DELAY_UNTIL_TEST_INDEX] = 1; } else { - printf("Please use task dn_del cmd first \r\n"); + printf("Please use task dn_del cmd first. \r\n"); } } else if (!strcmp(argv[1], "dn_del")) { - if(create_flg[DELAY_UNTIL_TEST_INDEX] == 1) + if (create_flg[DELAY_UNTIL_TEST_INDEX] == 1) { DeleteTasksForDelayUntilTest(); create_flg[DELAY_UNTIL_TEST_INDEX] = 0; - } + } else { - printf("Please use task dn_cre cmd first \r\n"); + printf("Please use task dn_cre cmd first. \r\n"); } } else if (!strcmp(argv[1], "bn_cre")) { - if(create_flg[BLOCKING_NON_BLOCKING_INDEX] == 0) + if (create_flg[BLOCKING_NON_BLOCKING_INDEX] == 0) { CreateTasksForBlockingOrNone(); create_flg[BLOCKING_NON_BLOCKING_INDEX] = 1; } else { - printf("Please use task bn_del cmd first \r\n"); + printf("Please use task bn_del cmd first. \r\n"); } } else if (!strcmp(argv[1], "bn_del")) { - if(create_flg[BLOCKING_NON_BLOCKING_INDEX] == 1) + if (create_flg[BLOCKING_NON_BLOCKING_INDEX] == 1) { DeleteTasksForBlockingOrNone(); create_flg[BLOCKING_NON_BLOCKING_INDEX] = 0; - } + } else { - printf("Please use task bn_cre cmd first \r\n"); + printf("Please use task bn_cre cmd first. \r\n"); } } else if (!strcmp(argv[1], "idle_cre")) { - if(create_flg[IDLE_TEST_INDEX] == 0) + if (create_flg[IDLE_TEST_INDEX] == 0) { CreateTasksForIdleTask(); create_flg[IDLE_TEST_INDEX] = 1; } else { - printf("Please use task idle_del cmd first \r\n"); + printf("Please use task idle_del cmd first. \r\n"); } } else if (!strcmp(argv[1], "idle_del")) { - if(create_flg[IDLE_TEST_INDEX] == 1) + if (create_flg[IDLE_TEST_INDEX] == 1) { DeleteTasksForForIdleTask(); create_flg[IDLE_TEST_INDEX] = 0; - } + } else { - printf("Please use task idle_cre cmd first \r\n"); + printf("Please use task idle_cre cmd first. \r\n"); } } else if (!strcmp(argv[1], "cha_cre")) { - if(create_flg[CHANGE_PRIORITY_TEST_INDEX] == 0) + if (create_flg[CHANGE_PRIORITY_TEST_INDEX] == 0) { CreateTasksForChangePriorityTest(); create_flg[CHANGE_PRIORITY_TEST_INDEX] = 1; } else { - printf("Please use task cha_del cmd first \r\n"); + printf("Please use task cha_del cmd first. \r\n"); } } else if (!strcmp(argv[1], "cha_del")) { - if(create_flg[CHANGE_PRIORITY_TEST_INDEX] == 1) + if (create_flg[CHANGE_PRIORITY_TEST_INDEX] == 1) { DeleteTasksForChangePriorityTest(); create_flg[CHANGE_PRIORITY_TEST_INDEX] = 0; - } + } else { - printf("Please use task cha_cre cmd first \r\n"); + printf("Please use task cha_cre cmd first. \r\n"); } } else { - printf("Error: Invalid arguments \r\n"); + printf("Error: Invalid arguments. \r\n"); CreateTasksCmdUsage(); } return 0; diff --git a/example/freertos_feature/task/src/task_combining_blocking_non_blocking.c b/example/freertos_feature/task/src/task_combining_blocking_non_blocking.c index 4618c7ec..d17cbab9 100644 --- a/example/freertos_feature/task/src/task_combining_blocking_non_blocking.c +++ b/example/freertos_feature/task/src/task_combining_blocking_non_blocking.c @@ -2,11 +2,11 @@ #include "FreeRTOS.h" #include "task.h" -#define TASK_STACK_SIZE 1024 +#define TASK_STACK_SIZE 1024 /* The task functions. */ -static void vContinuousProcessingTask( void *pvParameters ); -static void vPeriodicTask( void *pvParameters ); +static void vContinuousProcessingTask(void *pvParameters); +static void vPeriodicTask(void *pvParameters); static xTaskHandle xtask1_handle; static xTaskHandle xtask2_handle; @@ -22,33 +22,33 @@ static const char *pcTextForPeriodicTask = "BlockingOrNone Periodic task is runn /*-----------------------------------------------------------*/ void CreateTasksForBlockingOrNone(void) { - /* Create two instances of the continuous processing task, both at priority 1. */ - xTaskCreate( vContinuousProcessingTask, "BlockingOrNone Task 1", - TASK_STACK_SIZE, (void*)pcTextForTask1, 1, &xtask1_handle ); + /* Create two instances of the continuous processing task, both at priority 1. */ + xTaskCreate(vContinuousProcessingTask, "BlockingOrNone Task 1", + TASK_STACK_SIZE, (void *)pcTextForTask1, 1, &xtask1_handle); - xTaskCreate( vContinuousProcessingTask, "BlockingOrNone Task 2", - TASK_STACK_SIZE, (void*)pcTextForTask2, 1, &xtask2_handle ); + xTaskCreate(vContinuousProcessingTask, "BlockingOrNone Task 2", + TASK_STACK_SIZE, (void *)pcTextForTask2, 1, &xtask2_handle); - /* Create one instance of the periodic task at priority 2. */ - xTaskCreate( vPeriodicTask, "BlockingOrNone Task 3", - TASK_STACK_SIZE, (void*)pcTextForPeriodicTask, 2, &xtask3_handle ); + /* Create one instance of the periodic task at priority 2. */ + xTaskCreate(vPeriodicTask, "BlockingOrNone Task 3", + TASK_STACK_SIZE, (void *)pcTextForPeriodicTask, 2, &xtask3_handle); } void DeleteTasksForBlockingOrNone(void) { - if(xtask1_handle) + if (xtask1_handle) { vTaskDelete(xtask1_handle); vPrintString("BlockingOrNone Task 1 deletion \r\n"); } - if(xtask2_handle) + if (xtask2_handle) { vTaskDelete(xtask2_handle); vPrintString("BlockingOrNone Task 2 deletion \r\n"); } - if(xtask3_handle) + if (xtask3_handle) { vTaskDelete(xtask3_handle); vPrintString("BlockingOrNone Task 3 deletion \r\n"); @@ -56,43 +56,43 @@ void DeleteTasksForBlockingOrNone(void) } /*-----------------------------------------------------------*/ -void vContinuousProcessingTask( void *pvParameters ) +void vContinuousProcessingTask(void *pvParameters) { - char *pcTaskName; - /* The string to print out is passed in via the parameter. Cast this to a - character pointer. */ - pcTaskName = ( char * ) pvParameters; - - /* As per most tasks, this task is implemented in an infinite loop. */ - for( ;; ) - { - /* Print out the name of this task. This task just does this repeatedly - without ever blocking or delaying. */ - vPrintString( pcTaskName ); - vTaskDelay(5000); - - } + char *pcTaskName; + /* The string to print out is passed in via the parameter. Cast this to a + character pointer. */ + pcTaskName = (char *) pvParameters; + + /* As per most tasks, this task is implemented in an infinite loop. */ + for (;;) + { + /* Print out the name of this task. This task just does this repeatedly + without ever blocking or delaying. */ + vPrintString(pcTaskName); + vTaskDelay(5000); + + } } /*-----------------------------------------------------------*/ -void vPeriodicTask( void *pvParameters ) +void vPeriodicTask(void *pvParameters) { TickType_t xLastWakeTime; - const TickType_t xDelay = pdMS_TO_TICKS( 5000UL ); - - /* The xLastWakeTime variable needs to be initialized with the current tick - count. Note that this is the only time we access this variable. From this - point on xLastWakeTime is managed automatically by the vTaskDelayUntil() - API function. */ - xLastWakeTime = xTaskGetTickCount(); - - /* As per most tasks, this task is implemented in an infinite loop. */ - for( ;; ) - { - /* Print out the name of this task. */ - vPrintString( "Periodic task is running\r\n" ); - - /* We want this task to execute exactly every 100 milliseconds. */ - vTaskDelayUntil( &xLastWakeTime, xDelay ); - } + const TickType_t xDelay = pdMS_TO_TICKS(5000UL); + + /* The xLastWakeTime variable needs to be initialized with the current tick + count. Note that this is the only time we access this variable. From this + point on xLastWakeTime is managed automatically by the vTaskDelayUntil() + API function. */ + xLastWakeTime = xTaskGetTickCount(); + + /* As per most tasks, this task is implemented in an infinite loop. */ + for (;;) + { + /* Print out the name of this task. */ + vPrintString("Periodic task is running\r\n"); + + /* We want this task to execute exactly every 100 milliseconds. */ + vTaskDelayUntil(&xLastWakeTime, xDelay); + } } \ No newline at end of file diff --git a/example/freertos_feature/task/src/task_delay_until.c b/example/freertos_feature/task/src/task_delay_until.c index 82335047..dacba9eb 100644 --- a/example/freertos_feature/task/src/task_delay_until.c +++ b/example/freertos_feature/task/src/task_delay_until.c @@ -1,18 +1,18 @@ /* -This example demonstrates: +This example demonstrates: how to use delay until in tasks; */ #include "FreeRTOSConfig.h" #include "FreeRTOS.h" #include "task.h" -#define TASK_STACK_SIZE 1024 +#define TASK_STACK_SIZE 1024 static xTaskHandle xtask1_handle; static xTaskHandle xtask2_handle; /* The task function. */ -static void vTaskFunction( void *pvParameters ); +static void vTaskFunction(void *pvParameters); /* Define the strings that will be passed in as the task parameters. These are defined const and off the stack to ensure they remain valid when the tasks are @@ -25,23 +25,23 @@ static const char *pcTextForTask2 = "Delay Until Task 2 is running\r\n"; void CreateTasksForDelayUntilTest(void) { - /* Create the first task at priority 1... */ - xTaskCreate( vTaskFunction, "Delay Until Task 1", TASK_STACK_SIZE, (void*)pcTextForTask1, 1, &xtask1_handle ); + /* Create the first task at priority 1... */ + xTaskCreate(vTaskFunction, "Delay Until Task 1", TASK_STACK_SIZE, (void *)pcTextForTask1, 1, &xtask1_handle); - /* ... and the second task at priority 2. The priority is the second to - last parameter. */ - xTaskCreate( vTaskFunction, "Delay Until Task 2", TASK_STACK_SIZE, (void*)pcTextForTask2, 2, &xtask2_handle ); + /* ... and the second task at priority 2. The priority is the second to + last parameter. */ + xTaskCreate(vTaskFunction, "Delay Until Task 2", TASK_STACK_SIZE, (void *)pcTextForTask2, 2, &xtask2_handle); } void DeleteTasksForDelayUntilTest(void) { - if(xtask1_handle) + if (xtask1_handle) { vTaskDelete(xtask1_handle); vPrintString("Delay Until Task parameter 1 deletion \r\n"); } - if(xtask2_handle) + if (xtask2_handle) { vTaskDelete(xtask2_handle); vPrintString("Delay Until Task parameter 2 deletion \r\n"); @@ -49,33 +49,33 @@ void DeleteTasksForDelayUntilTest(void) } /*-----------------------------------------------------------*/ -static void vTaskFunction( void *pvParameters ) +static void vTaskFunction(void *pvParameters) { char *pcTaskName; TickType_t xLastWakeTime; - const TickType_t xDelay = pdMS_TO_TICKS( 3000UL ); + const TickType_t xDelay = pdMS_TO_TICKS(3000UL); - /* The string to print out is passed in via the parameter. Cast this to a - character pointer. */ - pcTaskName = ( char * ) pvParameters; + /* The string to print out is passed in via the parameter. Cast this to a + character pointer. */ + pcTaskName = (char *) pvParameters; - /* The xLastWakeTime variable needs to be initialized with the current tick - count. Note that this is the only time we access this variable. From this - point on xLastWakeTime is managed automatically by the vTaskDelayUntil() - API function. */ - xLastWakeTime = xTaskGetTickCount(); + /* The xLastWakeTime variable needs to be initialized with the current tick + count. Note that this is the only time we access this variable. From this + point on xLastWakeTime is managed automatically by the vTaskDelayUntil() + API function. */ + xLastWakeTime = xTaskGetTickCount(); - /* As per most tasks, this task is implemented in an infinite loop. */ - for( ;; ) - { - /* Print out the name of this task. */ - vPrintString( pcTaskName ); + /* As per most tasks, this task is implemented in an infinite loop. */ + for (;;) + { + /* Print out the name of this task. */ + vPrintString(pcTaskName); - /* We want this task to execute exactly every 1000 milliseconds. As per - the vTaskDelay() function, time is measured in ticks, and the - pdMS_TO_TICKS() macro is used to convert this to milliseconds. - xLastWakeTime is automatically updated within vTaskDelayUntil() so does not - have to be updated by this task code. */ - vTaskDelayUntil( &xLastWakeTime, xDelay ); - } + /* We want this task to execute exactly every 1000 milliseconds. As per + the vTaskDelay() function, time is measured in ticks, and the + pdMS_TO_TICKS() macro is used to convert this to milliseconds. + xLastWakeTime is automatically updated within vTaskDelayUntil() so does not + have to be updated by this task code. */ + vTaskDelayUntil(&xLastWakeTime, xDelay); + } } diff --git a/example/freertos_feature/task/src/using_task_parameter.c b/example/freertos_feature/task/src/using_task_parameter.c index 43762ba7..10847638 100644 --- a/example/freertos_feature/task/src/using_task_parameter.c +++ b/example/freertos_feature/task/src/using_task_parameter.c @@ -1,5 +1,5 @@ /* -This example demonstrates: +This example demonstrates: how to create and delete tasks use parameters; */ @@ -8,17 +8,17 @@ how to create and delete tasks use parameters; #include "task.h" /* Used as a loop counter to create a very crude delay. */ -#define DELAY_LOOP_COUNT ( 0x1fffffff ) +#define DELAY_LOOP_COUNT ( 0x1fffffff ) /* task stack size set. */ -#define TASK_STACK_SIZE 1024 +#define TASK_STACK_SIZE 1024 static xTaskHandle xtask1_handle; static xTaskHandle xtask2_handle; /* The task function. */ -static void vTaskFunction( void *pvParameters ); +static void vTaskFunction(void *pvParameters); /* Define the strings that will be passed in as the task parameters. These are defined const and off the stack to ensure they remain valid when the tasks are @@ -28,32 +28,32 @@ const char *pcTextForTask2 = "Parameter Task 2 is running\r\n"; /*-----------------------------------------------------------*/ -void CreateTasksForParamterTest( void ) +void CreateTasksForParamterTest(void) { - /* Create one of the two tasks. */ - xTaskCreate( vTaskFunction, /* Pointer to the function that implements the task. */ - "Parameter Task 1", /* Text name for the task. This is to facilitate debugging only. */ - TASK_STACK_SIZE, /* Stack depth - most small microcontrollers will use much less stack than this. */ - (void*)pcTextForTask1, /* Pass the text to be printed in as the task parameter. */ - 1, /* This task will run at priority 1. */ - &xtask1_handle ); /* We are not using the task handle. */ - - /* Create the other task in exactly the same way. Note this time that we - are creating the SAME task, but passing in a different parameter. We are - creating two instances of a single task implementation. */ - xTaskCreate( vTaskFunction, "Parameter Task 2", TASK_STACK_SIZE, (void*)pcTextForTask2, 1, &xtask2_handle ); + /* Create one of the two tasks. */ + xTaskCreate(vTaskFunction, /* Pointer to the function that implements the task. */ + "Parameter Task 1", /* Text name for the task. This is to facilitate debugging only. */ + TASK_STACK_SIZE, /* Stack depth - most small microcontrollers will use much less stack than this. */ + (void *)pcTextForTask1, /* Pass the text to be printed in as the task parameter. */ + 1, /* This task will run at priority 1. */ + &xtask1_handle); /* We are not using the task handle. */ + + /* Create the other task in exactly the same way. Note this time that we + are creating the SAME task, but passing in a different parameter. We are + creating two instances of a single task implementation. */ + xTaskCreate(vTaskFunction, "Parameter Task 2", TASK_STACK_SIZE, (void *)pcTextForTask2, 1, &xtask2_handle); } void DeleteTasksForParamterTest(void) { - if(xtask1_handle) + if (xtask1_handle) { vTaskDelete(xtask1_handle); vPrintString("DeleteTasksForParamterTest Task parameter 1 deletion \r\n"); } - if(xtask2_handle) + if (xtask2_handle) { vTaskDelete(xtask2_handle); vPrintString("DeleteTasksForParamterTest Task parameter 2 deletion \r\n"); @@ -62,27 +62,27 @@ void DeleteTasksForParamterTest(void) } /*-----------------------------------------------------------*/ -static void vTaskFunction( void *pvParameters ) +static void vTaskFunction(void *pvParameters) { - char *pcTaskName; - volatile uint32_t ul; - - /* The string to print out is passed in via the parameter. Cast this to a - character pointer. */ - pcTaskName = ( char * ) pvParameters; - - /* As per most tasks, this task is implemented in an infinite loop. */ - for( ;; ) - { - /* Print out the name of this task. */ - vPrintString( pcTaskName ); - - /* Delay for a period. */ - for( ul = 0; ul < DELAY_LOOP_COUNT; ul++ ) - { - /* This loop is just a very crude delay implementation. There is - nothing to do in here. Later exercises will replace this crude - loop with a proper delay/sleep function. */ - } - } + char *pcTaskName; + volatile uint32_t ul; + + /* The string to print out is passed in via the parameter. Cast this to a + character pointer. */ + pcTaskName = (char *) pvParameters; + + /* As per most tasks, this task is implemented in an infinite loop. */ + for (;;) + { + /* Print out the name of this task. */ + vPrintString(pcTaskName); + + /* Delay for a period. */ + for (ul = 0; ul < DELAY_LOOP_COUNT; ul++) + { + /* This loop is just a very crude delay implementation. There is + nothing to do in here. Later exercises will replace this crude + loop with a proper delay/sleep function. */ + } + } } \ No newline at end of file diff --git a/example/freertos_feature/task_notify/configs/d2000_aarch32_eg_configs b/example/freertos_feature/task_notify/configs/d2000_aarch32_eg_configs index 464a31af..a16785ad 100644 --- a/example/freertos_feature/task_notify/configs/d2000_aarch32_eg_configs +++ b/example/freertos_feature/task_notify/configs/d2000_aarch32_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -111,6 +112,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -147,6 +157,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -168,12 +179,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -185,14 +190,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -210,4 +233,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/task_notify/configs/d2000_aarch64_eg_configs b/example/freertos_feature/task_notify/configs/d2000_aarch64_eg_configs index 64e6b4b7..4731ef2f 100644 --- a/example/freertos_feature/task_notify/configs/d2000_aarch64_eg_configs +++ b/example/freertos_feature/task_notify/configs/d2000_aarch64_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/task_notify/configs/e2000d_aarch32_eg_configs b/example/freertos_feature/task_notify/configs/e2000d_aarch32_eg_configs index fc31cd0b..22902270 100644 --- a/example/freertos_feature/task_notify/configs/e2000d_aarch32_eg_configs +++ b/example/freertos_feature/task_notify/configs/e2000d_aarch32_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -111,6 +112,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -147,6 +157,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -168,12 +179,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -185,14 +190,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -210,4 +233,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/task_notify/configs/e2000d_aarch64_eg_configs b/example/freertos_feature/task_notify/configs/e2000d_aarch64_eg_configs index 7e2efa4f..f3181d35 100644 --- a/example/freertos_feature/task_notify/configs/e2000d_aarch64_eg_configs +++ b/example/freertos_feature/task_notify/configs/e2000d_aarch64_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/task_notify/configs/e2000q_aarch32_eg_configs b/example/freertos_feature/task_notify/configs/e2000q_aarch32_eg_configs index 1b53ed91..eea9646f 100644 --- a/example/freertos_feature/task_notify/configs/e2000q_aarch32_eg_configs +++ b/example/freertos_feature/task_notify/configs/e2000q_aarch32_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -111,6 +112,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -147,6 +157,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -168,12 +179,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -185,14 +190,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -210,4 +233,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/task_notify/configs/e2000q_aarch64_eg_configs b/example/freertos_feature/task_notify/configs/e2000q_aarch64_eg_configs index 9c50f2b0..9183d77b 100644 --- a/example/freertos_feature/task_notify/configs/e2000q_aarch64_eg_configs +++ b/example/freertos_feature/task_notify/configs/e2000q_aarch64_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/task_notify/configs/ft2004_aarch32_eg_configs b/example/freertos_feature/task_notify/configs/ft2004_aarch32_eg_configs index 4c5b2c49..f0510b59 100644 --- a/example/freertos_feature/task_notify/configs/ft2004_aarch32_eg_configs +++ b/example/freertos_feature/task_notify/configs/ft2004_aarch32_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -111,6 +112,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -147,6 +157,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -168,12 +179,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -185,14 +190,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -210,4 +233,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/task_notify/configs/ft2004_aarch64_eg_configs b/example/freertos_feature/task_notify/configs/ft2004_aarch64_eg_configs index da9c1f81..d99e8ace 100644 --- a/example/freertos_feature/task_notify/configs/ft2004_aarch64_eg_configs +++ b/example/freertos_feature/task_notify/configs/ft2004_aarch64_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/task_notify/inc/feature_task_notify.h b/example/freertos_feature/task_notify/inc/feature_task_notify.h index b5d06d4d..9e349693 100644 --- a/example/freertos_feature/task_notify/inc/feature_task_notify.h +++ b/example/freertos_feature/task_notify/inc/feature_task_notify.h @@ -1,30 +1,36 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: feature_task_notify.h * Date: 2022-06-17 10:42:40 * LastEditTime: 2022-06-17 10:42:40 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for task function define + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 wangxiaodong 2022/08/09 first commit */ #ifndef FEATURE_EVENTGROUP_H #define FEATURE_EVENTGROUP_H +#ifdef __cplusplus +extern "C" +{ +#endif + /* task notify use true */ void CreateNotifyTakeTrueTasks(void); void DeleteNotifyTakeTrueTasks(void); @@ -33,4 +39,8 @@ void DeleteNotifyTakeTrueTasks(void); void CreateNotifyTakeFalseTasks(void); void DeleteNotifyTakeFalseTasks(void); +#ifdef __cplusplus +} +#endif + #endif // ! \ No newline at end of file diff --git a/example/freertos_feature/task_notify/main.c b/example/freertos_feature/task_notify/main.c index f376d838..b20740a5 100644 --- a/example/freertos_feature/task_notify/main.c +++ b/example/freertos_feature/task_notify/main.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: main.c * Date: 2022-06-17 08:17:59 * LastEditTime: 2022-06-17 08:17:59 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for task_notify example that running shell task and open scheduler + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 wangxiaodong 2022/08/09 first commit */ #include "shell.h" @@ -30,13 +31,15 @@ int main(void) BaseType_t ret; ret = LSUserShellTask() ; - if(ret != pdPASS) + if (ret != pdPASS) + { goto FAIL_EXIT; + } - vTaskStartScheduler(); /* 启动任务,开启调度 */ + vTaskStartScheduler(); /* 启动任务,开启调度 */ while (1); /* 正常不会执行到这里 */ - + FAIL_EXIT: - printf("failed 0x%x \r\n", ret); + printf("failed 0x%x. \r\n", ret); return 0; } diff --git a/example/freertos_feature/task_notify/sdkconfig b/example/freertos_feature/task_notify/sdkconfig index 9c50f2b0..9183d77b 100644 --- a/example/freertos_feature/task_notify/sdkconfig +++ b/example/freertos_feature/task_notify/sdkconfig @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/freertos_feature/task_notify/sdkconfig.h b/example/freertos_feature/task_notify/sdkconfig.h index 2e55f772..80305bac 100644 --- a/example/freertos_feature/task_notify/sdkconfig.h +++ b/example/freertos_feature/task_notify/sdkconfig.h @@ -62,6 +62,7 @@ /* CONFIG_USE_ADC is not set */ /* CONFIG_USE_PWM is not set */ /* CONFIG_USE_IPC is not set */ +/* CONFIG_USE_MEDIA is not set */ /* end of Components Configuration */ #define CONFIG_USE_NEW_LIBC /* end of Standalone Setting */ @@ -98,6 +99,12 @@ /* Compiler Options */ +/* Cross-Compiler Setting */ + +#define CONFIG_GCC_OPTIMIZE_LEVEL 0 +/* CONFIG_USE_EXT_COMPILER is not set */ +/* CONFIG_USE_KLIN_SYS is not set */ +/* end of Cross-Compiler Setting */ #define CONFIG_OUTPUT_BINARY /* end of Compiler Options */ /* end of Building Option */ @@ -127,6 +134,7 @@ /* Freertos Eth Drivers */ /* CONFIG_FREERTOS_USE_XMAC is not set */ +/* CONFIG_FREERTOS_USE_GMAC is not set */ /* end of Freertos Eth Drivers */ /* Freertos Gpio Drivers */ @@ -145,11 +153,6 @@ /* CONFIG_FREERTOS_USE_FGDMA is not set */ /* end of Freertos DMA Drivers */ -/* Freertos MMC Drivers */ - -/* CONFIG_FREERTOS_USE_FSDIO is not set */ -/* end of Freertos MMC Drivers */ - /* Freertos Adc Drivers */ /* CONFIG_FREERTOS_USE_ADC is not set */ @@ -159,13 +162,28 @@ /* CONFIG_FREERTOS_USE_CAN is not set */ /* end of Freertos Can Drivers */ + +/* Freertos I2c Drivers */ + +/* CONFIG_FREERTOS_USE_I2C is not set */ +/* end of Freertos I2c Drivers */ + +/* Freertos Mio Drivers */ + +/* CONFIG_FREERTOS_USE_MIO is not set */ +/* end of Freertos Mio Drivers */ + +/* Freertos Timer Drivers */ + +/* CONFIG_FREERTOS_USE_TIMER is not set */ +/* end of Freertos Timer Drivers */ /* end of Component Configuration */ -/* FreeRTOS Setting */ +/* Third-Party Configuration */ /* CONFIG_USE_LWIP is not set */ #define CONFIG_USE_BACKTRACE -/* CONFIG_USE_FATFS is not set */ +/* CONFIG_USE_FATFS_0_1_4 is not set */ /* CONFIG_USE_SFUD is not set */ /* CONFIG_USE_SPIFFS is not set */ /* CONFIG_USE_AMP is not set */ @@ -181,6 +199,28 @@ /* CONFIG_USE_TLSF is not set */ /* CONFIG_USE_SDMMC_CMD is not set */ /* CONFIG_USE_CHERRY_USB is not set */ -/* end of FreeRTOS Setting */ +/* end of Third-Party Configuration */ + +/* Kernel Configuration */ + +#define CONFIG_FREERTOS_OPTIMIZED_SCHEDULER +#define CONFIG_FREERTOS_HZ 1000 +#define CONFIG_FREERTOS_MAX_PRIORITIES 32 +#define CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES 13 +#define CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES 11 +#define CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS 1 +#define CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE 1024 +#define CONFIG_FREERTOS_MAX_TASK_NAME_LEN 32 +#define CONFIG_FREERTOS_TIMER_TASK_PRIORITY 1 +#define CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH 2048 +#define CONFIG_FREERTOS_TIMER_QUEUE_LENGTH 10 +#define CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE 0 +#define CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS +#define CONFIG_FREERTOS_USE_TRACE_FACILITY +#define CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS +/* CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set */ +#define CONFIG_FREERTOS_TOTAL_HEAP_SIZE 10240 +#define CONFIG_FREERTOS_TASK_FPU_SUPPORT 1 +/* end of Kernel Configuration */ #endif diff --git a/example/freertos_feature/task_notify/src/notify_take_false.c b/example/freertos_feature/task_notify/src/notify_take_false.c index a5b1d60a..1c5dd259 100644 --- a/example/freertos_feature/task_notify/src/notify_take_false.c +++ b/example/freertos_feature/task_notify/src/notify_take_false.c @@ -1,9 +1,9 @@ /* -This example demonstrates: +This example demonstrates: the ulTaskNotifyTake() xClearOnExit parameter was set to pdFALSE. -When xClearOnExit is pdFALSE, calling ulTaskNotifyTake() will only decrement -(reduce by one) the calling task’s notification value, instead of clearing it to zero. -The notification count is therefore the difference between the number of events +When xClearOnExit is pdFALSE, calling ulTaskNotifyTake() will only decrement +(reduce by one) the calling task’s notification value, instead of clearing it to zero. +The notification count is therefore the difference between the number of events that have occurred, and the number of events that have been processed. */ #include @@ -13,12 +13,12 @@ that have occurred, and the number of events that have been processed. #include "finterrupt.h" #include "fcpu_info.h" -#define TASK_STACK_SIZE 1024 +#define TASK_STACK_SIZE 1024 /* The interrupt number to use for the software interrupt generation. This could be any unused number. In this case the first chip level (non system) interrupt is used */ -#define INTERRUPT_ID 0 +#define INTERRUPT_ID 0 /* The priority of the software interrupt. The interrupt service routine uses an (interrupt safe) FreeRTOS API function, so the priority of the interrupt must @@ -26,21 +26,21 @@ be equal to or lower than the priority set by configMAX_SYSCALL_INTERRUPT_PRIORITY - remembering that on the Cortex M3 high numeric values represent low priority values, which can be confusing as it is counter intuitive. */ -#define INTERRUPT_PRIORITY IRQ_PRIORITY_VALUE_12 +#define INTERRUPT_PRIORITY IRQ_PRIORITY_VALUE_12 /* Macro to force an interrupt. */ static void vTriggerInterrupt(void); /* The tasks to be created. */ -static void vHandlerTask( void *pvParameters ); -static void vPeriodicTask( void *pvParameters ); +static void vHandlerTask(void *pvParameters); +static void vPeriodicTask(void *pvParameters); /* The service routine for the (simulated) interrupt. This is the interrupt that the task will be synchronized with. */ static void vSetupSoftwareInterrupt(void); /* The rate at which the periodic task generates software interrupts. */ -static const TickType_t xInterruptFrequency = pdMS_TO_TICKS( 5000UL ); +static const TickType_t xInterruptFrequency = pdMS_TO_TICKS(5000UL); /* Stores the handle of the task to which interrupt processing is deferred. */ static xTaskHandle xtask1_handle = NULL; @@ -50,38 +50,38 @@ static u32 cpu_id = 0; /*-----------------------------------------------------------*/ -void CreateNotifyTakeFalseTasks( void ) +void CreateNotifyTakeFalseTasks(void) { - /* Install the handler for the software interrupt. The syntax necessary - to do this is dependent on the FreeRTOS port being used. The syntax - shown here can only be used with the FreeRTOS Windows port, where such - interrupts are only simulated. */ - vSetupSoftwareInterrupt( ); - - /* Create the 'handler' task, which is the task to which interrupt - processing is deferred, and so is the task that will be synchronized - with the interrupt. The handler task is created with a high priority to - ensure it runs immediately after the interrupt exits. In this case a - priority of 3 is chosen. The handle of the task is saved for use by the - ISR. */ - xTaskCreate( vHandlerTask, "Notify False Handler", TASK_STACK_SIZE, NULL, 3, &xtask1_handle ); - - /* Create the task that will periodically generate a software interrupt. - This is created with a priority below the handler task to ensure it will - get preempted each time the handler task exits the Blocked state. */ - xTaskCreate( vPeriodicTask, "Notify False Periodic", TASK_STACK_SIZE, NULL, 1, &xtask2_handle ); + /* Install the handler for the software interrupt. The syntax necessary + to do this is dependent on the FreeRTOS port being used. The syntax + shown here can only be used with the FreeRTOS Windows port, where such + interrupts are only simulated. */ + vSetupSoftwareInterrupt(); + + /* Create the 'handler' task, which is the task to which interrupt + processing is deferred, and so is the task that will be synchronized + with the interrupt. The handler task is created with a high priority to + ensure it runs immediately after the interrupt exits. In this case a + priority of 3 is chosen. The handle of the task is saved for use by the + ISR. */ + xTaskCreate(vHandlerTask, "Notify False Handler", TASK_STACK_SIZE, NULL, 3, &xtask1_handle); + + /* Create the task that will periodically generate a software interrupt. + This is created with a priority below the handler task to ensure it will + get preempted each time the handler task exits the Blocked state. */ + xTaskCreate(vPeriodicTask, "Notify False Periodic", TASK_STACK_SIZE, NULL, 1, &xtask2_handle); } void DeleteNotifyTakeFalseTasks(void) { - if(xtask1_handle) + if (xtask1_handle) { vTaskDelete(xtask1_handle); vPrintString("Task notify false Handler deletion"); } - if(xtask2_handle) + if (xtask2_handle) { vTaskDelete(xtask2_handle); vPrintString("Task notify false Periodic deletion"); @@ -89,111 +89,111 @@ void DeleteNotifyTakeFalseTasks(void) } /*-----------------------------------------------------------*/ -static void vHandlerTask( void *pvParameters ) +static void vHandlerTask(void *pvParameters) { - /* xMaxExpectedBlockTime is set to be a little longer than the maximum expected - time between events. */ - const TickType_t xMaxExpectedBlockTime = xInterruptFrequency + pdMS_TO_TICKS( 10 ); - uint32_t ulNotificationValue = 0; - - /* As per most tasks, this task is implemented within an infinite loop. */ - for( ;; ) - { - /* Wait to receive a notification sent directly to this task from the - interrupt handler. The xClearCountOnExit parameter is now pdFALSE, so - the task's notification will be decremented when ulTaskNotifyTake() - returns having received a notification. */ - ulNotificationValue = ulTaskNotifyTake(pdFALSE, xMaxExpectedBlockTime); - if( ulNotificationValue != 0 ) - { - /* To get here the event must have occurred. Process the event (in - this case just print out a message). */ - vPrintString( "Task Notify False Handler task - Processing event.\r\n" ); - vPrintStringAndNumber("Task Notify False ulNotificationValue= ", ulNotificationValue); - } - else - { - /* If this part of the function is reached then an interrupt did not - arrive within the expected time, and (in a real application) it may - be necessary to perform some error recovery operations. */ - } - } + /* xMaxExpectedBlockTime is set to be a little longer than the maximum expected + time between events. */ + const TickType_t xMaxExpectedBlockTime = xInterruptFrequency + pdMS_TO_TICKS(10); + uint32_t ulNotificationValue = 0; + + /* As per most tasks, this task is implemented within an infinite loop. */ + for (;;) + { + /* Wait to receive a notification sent directly to this task from the + interrupt handler. The xClearCountOnExit parameter is now pdFALSE, so + the task's notification will be decremented when ulTaskNotifyTake() + returns having received a notification. */ + ulNotificationValue = ulTaskNotifyTake(pdFALSE, xMaxExpectedBlockTime); + if (ulNotificationValue != 0) + { + /* To get here the event must have occurred. Process the event (in + this case just print out a message). */ + vPrintString("Task Notify False Handler task - Processing event.\r\n"); + vPrintStringAndNumber("Task Notify False ulNotificationValue= ", ulNotificationValue); + } + else + { + /* If this part of the function is reached then an interrupt did not + arrive within the expected time, and (in a real application) it may + be necessary to perform some error recovery operations. */ + } + } } /*-----------------------------------------------------------*/ static void ulExampleInterruptHandler(s32 vector, void *param) { - BaseType_t xHigherPriorityTaskWoken; - - /* The xHigherPriorityTaskWoken parameter must be initialized to pdFALSE as - it will get set to pdTRUE inside the interrupt safe API function if a - context switch is required. */ - xHigherPriorityTaskWoken = pdFALSE; - - /* Send a notification to the handler task multiple times. The first will - unblock the task, the following 'gives' are to demonstrate that the - receiving task's notification value is being used to latch events - allowing - the task to process the events in turn. */ - vTaskNotifyGiveFromISR( xtask1_handle, &xHigherPriorityTaskWoken ); - vTaskNotifyGiveFromISR( xtask1_handle, &xHigherPriorityTaskWoken ); - vTaskNotifyGiveFromISR( xtask1_handle, &xHigherPriorityTaskWoken ); - - /* Pass the xHigherPriorityTaskWoken value into portYIELD_FROM_ISR(). If - xHigherPriorityTaskWoken was set to pdTRUE inside vTaskNotifyGiveFromISR() - then calling portYIELD_FROM_ISR() will request a context switch. If - xHigherPriorityTaskWoken is still pdFALSE then calling - portYIELD_FROM_ISR() will have no effect. The implementation of - portYIELD_FROM_ISR() used by the Windows port includes a return statement, - which is why this function does not explicitly return a value. */ - portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); + BaseType_t xHigherPriorityTaskWoken; + + /* The xHigherPriorityTaskWoken parameter must be initialized to pdFALSE as + it will get set to pdTRUE inside the interrupt safe API function if a + context switch is required. */ + xHigherPriorityTaskWoken = pdFALSE; + + /* Send a notification to the handler task multiple times. The first will + unblock the task, the following 'gives' are to demonstrate that the + receiving task's notification value is being used to latch events - allowing + the task to process the events in turn. */ + vTaskNotifyGiveFromISR(xtask1_handle, &xHigherPriorityTaskWoken); + vTaskNotifyGiveFromISR(xtask1_handle, &xHigherPriorityTaskWoken); + vTaskNotifyGiveFromISR(xtask1_handle, &xHigherPriorityTaskWoken); + + /* Pass the xHigherPriorityTaskWoken value into portYIELD_FROM_ISR(). If + xHigherPriorityTaskWoken was set to pdTRUE inside vTaskNotifyGiveFromISR() + then calling portYIELD_FROM_ISR() will request a context switch. If + xHigherPriorityTaskWoken is still pdFALSE then calling + portYIELD_FROM_ISR() will have no effect. The implementation of + portYIELD_FROM_ISR() used by the Windows port includes a return statement, + which is why this function does not explicitly return a value. */ + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } /*-----------------------------------------------------------*/ -static void vPeriodicTask( void *pvParameters ) +static void vPeriodicTask(void *pvParameters) { - /* As per most tasks, this task is implemented within an infinite loop. */ - for( ;; ) - { - /* This task is just used to 'simulate' an interrupt. This is done by - periodically generating a simulated software interrupt. Block until it - is time to generate the software interrupt again. */ - vTaskDelay( xInterruptFrequency ); - - /* Generate the interrupt, printing a message both before and after - the interrupt has been generated so the sequence of execution is evident - from the output. - - The syntax used to generate a software interrupt is dependent on the - FreeRTOS port being used. The syntax used below can only be used with - the FreeRTOS Windows port, in which such interrupts are only - simulated. */ - vPrintString( "Task Notify False Periodic task - About to generate an interrupt." ); - vTriggerInterrupt(); - vPrintString( "Task Notify False Periodic task - Interrupt generated." ); - - - } + /* As per most tasks, this task is implemented within an infinite loop. */ + for (;;) + { + /* This task is just used to 'simulate' an interrupt. This is done by + periodically generating a simulated software interrupt. Block until it + is time to generate the software interrupt again. */ + vTaskDelay(xInterruptFrequency); + + /* Generate the interrupt, printing a message both before and after + the interrupt has been generated so the sequence of execution is evident + from the output. + + The syntax used to generate a software interrupt is dependent on the + FreeRTOS port being used. The syntax used below can only be used with + the FreeRTOS Windows port, in which such interrupts are only + simulated. */ + vPrintString("Task Notify False Periodic task - About to generate an interrupt."); + vTriggerInterrupt(); + vPrintString("Task Notify False Periodic task - Interrupt generated."); + + + } } static void vSetupSoftwareInterrupt(void) { - GetCpuId(&cpu_id); + GetCpuId(&cpu_id); vPrintf("cpu_id is %d \r\n", cpu_id); - /* The interrupt service routine uses an (interrupt safe) FreeRTOS API - function so the interrupt priority must be at or below the priority defined - by configSYSCALL_INTERRUPT_PRIORITY. */ - InterruptSetPriority(INTERRUPT_ID, INTERRUPT_PRIORITY ); + /* The interrupt service routine uses an (interrupt safe) FreeRTOS API + function so the interrupt priority must be at or below the priority defined + by configSYSCALL_INTERRUPT_PRIORITY. */ + InterruptSetPriority(INTERRUPT_ID, INTERRUPT_PRIORITY); - InterruptInstall(INTERRUPT_ID, ulExampleInterruptHandler, NULL, NULL); + InterruptInstall(INTERRUPT_ID, ulExampleInterruptHandler, NULL, NULL); - /* Enable the interrupt. */ - InterruptUmask(INTERRUPT_ID ); + /* Enable the interrupt. */ + InterruptUmask(INTERRUPT_ID); } /* Macro to force an interrupt. */ static void vTriggerInterrupt(void) { - InterruptCoreInterSend(INTERRUPT_ID, (1 << cpu_id)); + InterruptCoreInterSend(INTERRUPT_ID, (1 << cpu_id)); } diff --git a/example/freertos_feature/task_notify/src/notify_take_true.c b/example/freertos_feature/task_notify/src/notify_take_true.c index 3e931a79..dbd5c43f 100644 --- a/example/freertos_feature/task_notify/src/notify_take_true.c +++ b/example/freertos_feature/task_notify/src/notify_take_true.c @@ -1,7 +1,7 @@ /* -This example demonstrates: -uses task notification to unblock a task from within an interrupt -service routine—effectively synchronizing the task with the interrupt. +This example demonstrates: +uses task notification to unblock a task from within an interrupt +service routine—effectively synchronizing the task with the interrupt. the ulTaskNotifyTake() xClearOnExit parameter was set to pdTRUE. */ @@ -14,12 +14,12 @@ the ulTaskNotifyTake() xClearOnExit parameter was set to pdTRUE. static xTaskHandle xtask1_handle = NULL; static xTaskHandle xtask2_handle = NULL; -#define TASK_STACK_SIZE 1024 +#define TASK_STACK_SIZE 1024 /* The interrupt number to use for the software interrupt generation. This could be any unused number. In this case the first chip level (non system) interrupt is used */ -#define INTERRUPT_ID 0 +#define INTERRUPT_ID 0 /* The priority of the software interrupt. The interrupt service routine uses an (interrupt safe) FreeRTOS API function, so the priority of the interrupt must @@ -27,58 +27,58 @@ be equal to or lower than the priority set by configMAX_SYSCALL_INTERRUPT_PRIORITY - remembering that on the Cortex M3 high numeric values represent low priority values, which can be confusing as it is counter intuitive. */ -#define INTERRUPT_PRIORITY IRQ_PRIORITY_VALUE_12 +#define INTERRUPT_PRIORITY IRQ_PRIORITY_VALUE_12 /* Macro to force an interrupt. */ static void vTriggerInterrupt(void); /* The tasks to be created. */ -static void vHandlerTask( void *pvParameters ); -static void vPeriodicTask( void *pvParameters ); +static void vHandlerTask(void *pvParameters); +static void vPeriodicTask(void *pvParameters); /* The service routine for the (simulated) interrupt. This is the interrupt that sets an event bit in the event group. */ static void vSetupSoftwareInterrupt(void); /* The rate at which the periodic task generates software interrupts. */ -static const TickType_t xInterruptFrequency = pdMS_TO_TICKS( 5000UL ); +static const TickType_t xInterruptFrequency = pdMS_TO_TICKS(5000UL); static u32 cpu_id = 0; /*-----------------------------------------------------------*/ -void CreateNotifyTakeTrueTasks( void ) +void CreateNotifyTakeTrueTasks(void) { - /* Install the handler for the software interrupt. The syntax necessary - to do this is dependent on the FreeRTOS port being used. The syntax - shown here can only be used with the FreeRTOS Windows port, where such - interrupts are only simulated. */ - vSetupSoftwareInterrupt(); - - /* Create the 'handler' task, which is the task to which interrupt - processing is deferred, and so is the task that will be synchronized - with the interrupt. The handler task is created with a high priority to - ensure it runs immediately after the interrupt exits. In this case a - priority of 3 is chosen. The handle of the task is saved for use by the - ISR. */ - xTaskCreate( vHandlerTask, "Notify True Handler", TASK_STACK_SIZE, NULL, 3, &xtask1_handle ); - - /* Create the task that will periodically generate a software interrupt. - This is created with a priority below the handler task to ensure it will - get preempted each time the handler task exits the Blocked state. */ - xTaskCreate( vPeriodicTask, "Notify True Periodic", TASK_STACK_SIZE, NULL, 1, &xtask2_handle ); + /* Install the handler for the software interrupt. The syntax necessary + to do this is dependent on the FreeRTOS port being used. The syntax + shown here can only be used with the FreeRTOS Windows port, where such + interrupts are only simulated. */ + vSetupSoftwareInterrupt(); + + /* Create the 'handler' task, which is the task to which interrupt + processing is deferred, and so is the task that will be synchronized + with the interrupt. The handler task is created with a high priority to + ensure it runs immediately after the interrupt exits. In this case a + priority of 3 is chosen. The handle of the task is saved for use by the + ISR. */ + xTaskCreate(vHandlerTask, "Notify True Handler", TASK_STACK_SIZE, NULL, 3, &xtask1_handle); + + /* Create the task that will periodically generate a software interrupt. + This is created with a priority below the handler task to ensure it will + get preempted each time the handler task exits the Blocked state. */ + xTaskCreate(vPeriodicTask, "Notify True Periodic", TASK_STACK_SIZE, NULL, 1, &xtask2_handle); } void DeleteNotifyTakeTrueTasks(void) { - if(xtask1_handle) + if (xtask1_handle) { vTaskDelete(xtask1_handle); vPrintString("Task notify True Handler deletion \r\n"); } - if(xtask2_handle) + if (xtask2_handle) { vTaskDelete(xtask2_handle); vPrintString("Task notify True Periodic deletion \r\n"); @@ -86,114 +86,114 @@ void DeleteNotifyTakeTrueTasks(void) } /*-----------------------------------------------------------*/ -static void vHandlerTask( void *pvParameters ) +static void vHandlerTask(void *pvParameters) { - /* xMaxExpectedBlockTime is set to be a little longer than the maximum expected - time between events. */ - const TickType_t xMaxExpectedBlockTime = xInterruptFrequency + pdMS_TO_TICKS( 10 ); - uint32_t ulEventsToProcess; - - /* As per most tasks, this task is implemented within an infinite loop. */ - for( ;; ) - { - /* Wait to receive a notification sent directly to this task from the - interrupt handler. */ - ulEventsToProcess = ulTaskNotifyTake( pdTRUE, xMaxExpectedBlockTime ); - if( ulEventsToProcess != 0 ) - { - /* To get here at least one event must have occurred. Loop here - until all the pending events have been processed (in this case, just - print out a message for each event). */ - while( ulEventsToProcess > 0 ) - { - vPrintString( "Task notify True Handler task - Processing event." ); - ulEventsToProcess--; - } - } - else - { - /* If this part of the function is reached then an interrupt did not - arrive within the expected time, and (in a real application) it may - be necessary to perform some error recovery operations. */ - } - } + /* xMaxExpectedBlockTime is set to be a little longer than the maximum expected + time between events. */ + const TickType_t xMaxExpectedBlockTime = xInterruptFrequency + pdMS_TO_TICKS(10); + uint32_t ulEventsToProcess; + + /* As per most tasks, this task is implemented within an infinite loop. */ + for (;;) + { + /* Wait to receive a notification sent directly to this task from the + interrupt handler. */ + ulEventsToProcess = ulTaskNotifyTake(pdTRUE, xMaxExpectedBlockTime); + if (ulEventsToProcess != 0) + { + /* To get here at least one event must have occurred. Loop here + until all the pending events have been processed (in this case, just + print out a message for each event). */ + while (ulEventsToProcess > 0) + { + vPrintString("Task notify True Handler task - Processing event."); + ulEventsToProcess--; + } + } + else + { + /* If this part of the function is reached then an interrupt did not + arrive within the expected time, and (in a real application) it may + be necessary to perform some error recovery operations. */ + } + } } /*-----------------------------------------------------------*/ static void ulExampleInterruptHandler(s32 vector, void *param) { - BaseType_t xHigherPriorityTaskWoken; - - /* The xHigherPriorityTaskWoken parameter must be initialized to pdFALSE as - it will get set to pdTRUE inside the interrupt safe API function if a - context switch is required. */ - xHigherPriorityTaskWoken = pdFALSE; - - /* Send a notification directly to the handler task. */ - vTaskNotifyGiveFromISR( /* The handle of the task to which the notification - is being sent. The handle was saved when the task - was created. */ - xtask1_handle, - - /* xHigherPriorityTaskWoken is used in the usual - way. */ - &xHigherPriorityTaskWoken ); - - /* Pass the xHigherPriorityTaskWoken value into portYIELD_FROM_ISR(). If - xHigherPriorityTaskWoken was set to pdTRUE inside vTaskNotifyGiveFromISR() - then calling portYIELD_FROM_ISR() will request a context switch. If - xHigherPriorityTaskWoken is still pdFALSE then calling - portYIELD_FROM_ISR() will have no effect. The implementation of - portYIELD_FROM_ISR() used by the Windows port includes a return statement, - which is why this function does not explicitly return a value. */ - portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); + BaseType_t xHigherPriorityTaskWoken; + + /* The xHigherPriorityTaskWoken parameter must be initialized to pdFALSE as + it will get set to pdTRUE inside the interrupt safe API function if a + context switch is required. */ + xHigherPriorityTaskWoken = pdFALSE; + + /* Send a notification directly to the handler task. */ + vTaskNotifyGiveFromISR(/* The handle of the task to which the notification + is being sent. The handle was saved when the task + was created. */ + xtask1_handle, + + /* xHigherPriorityTaskWoken is used in the usual + way. */ + &xHigherPriorityTaskWoken); + + /* Pass the xHigherPriorityTaskWoken value into portYIELD_FROM_ISR(). If + xHigherPriorityTaskWoken was set to pdTRUE inside vTaskNotifyGiveFromISR() + then calling portYIELD_FROM_ISR() will request a context switch. If + xHigherPriorityTaskWoken is still pdFALSE then calling + portYIELD_FROM_ISR() will have no effect. The implementation of + portYIELD_FROM_ISR() used by the Windows port includes a return statement, + which is why this function does not explicitly return a value. */ + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } /*-----------------------------------------------------------*/ -static void vPeriodicTask( void *pvParameters ) +static void vPeriodicTask(void *pvParameters) { - /* As per most tasks, this task is implemented within an infinite loop. */ - for( ;; ) - { - /* This task is just used to 'simulate' an interrupt. This is done by - periodically generating a simulated software interrupt. Block until it - is time to generate the software interrupt again. */ - vTaskDelay( xInterruptFrequency ); - - /* Generate the interrupt, printing a message both before and after - the interrupt has been generated so the sequence of execution is evident - from the output. - - The syntax used to generate a software interrupt is dependent on the - FreeRTOS port being used. The syntax used below can only be used with - the FreeRTOS Windows port, in which such interrupts are only - simulated. */ - vPrintString( "Task Notify True Periodic task - About to generate an interrupt." ); - vTriggerInterrupt(); - vPrintString( "Task Notify True Periodic task - Interrupt generated." ); - } + /* As per most tasks, this task is implemented within an infinite loop. */ + for (;;) + { + /* This task is just used to 'simulate' an interrupt. This is done by + periodically generating a simulated software interrupt. Block until it + is time to generate the software interrupt again. */ + vTaskDelay(xInterruptFrequency); + + /* Generate the interrupt, printing a message both before and after + the interrupt has been generated so the sequence of execution is evident + from the output. + + The syntax used to generate a software interrupt is dependent on the + FreeRTOS port being used. The syntax used below can only be used with + the FreeRTOS Windows port, in which such interrupts are only + simulated. */ + vPrintString("Task Notify True Periodic task - About to generate an interrupt."); + vTriggerInterrupt(); + vPrintString("Task Notify True Periodic task - Interrupt generated."); + } } static void vSetupSoftwareInterrupt(void) { - GetCpuId(&cpu_id); + GetCpuId(&cpu_id); vPrintf("cpu_id is %d \r\n", cpu_id); - /* The interrupt service routine uses an (interrupt safe) FreeRTOS API - function so the interrupt priority must be at or below the priority defined - by configSYSCALL_INTERRUPT_PRIORITY. */ - InterruptSetPriority(INTERRUPT_ID, INTERRUPT_PRIORITY ); + /* The interrupt service routine uses an (interrupt safe) FreeRTOS API + function so the interrupt priority must be at or below the priority defined + by configSYSCALL_INTERRUPT_PRIORITY. */ + InterruptSetPriority(INTERRUPT_ID, INTERRUPT_PRIORITY); - InterruptInstall(INTERRUPT_ID, ulExampleInterruptHandler, NULL, NULL); + InterruptInstall(INTERRUPT_ID, ulExampleInterruptHandler, NULL, NULL); - /* Enable the interrupt. */ - InterruptUmask(INTERRUPT_ID ); + /* Enable the interrupt. */ + InterruptUmask(INTERRUPT_ID); } /* Macro to force an interrupt. */ static void vTriggerInterrupt(void) { - InterruptCoreInterSend(INTERRUPT_ID, (1 << cpu_id)); + InterruptCoreInterSend(INTERRUPT_ID, (1 << cpu_id)); } diff --git a/example/freertos_feature/task_notify/src/task_notify_cmd.c b/example/freertos_feature/task_notify/src/task_notify_cmd.c index fe601ba3..820e8baf 100644 --- a/example/freertos_feature/task_notify/src/task_notify_cmd.c +++ b/example/freertos_feature/task_notify/src/task_notify_cmd.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: task_notify_cmd.c * Date: 2022-06-17 10:41:45 * LastEditTime: 2022-06-17 10:41:45 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for task notifiy command interface + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 wangxiaodong 2022/08/09 first commit */ #include "shell.h" #include @@ -34,15 +35,15 @@ typedef enum static void TaskNotifyCmdUsage(void) { - printf("usage:\r\n"); + printf("Usage:\r\n"); printf(" notify true_cre \r\n"); - printf(" -- create task notify test now, use notify take true\r\n"); + printf(" -- Create task notify test now, use notify take true.\r\n"); printf(" notify true_del \r\n"); - printf(" -- del notify take true tasks now\r\n"); + printf(" -- Del notify take true tasks now.\r\n"); printf(" notify false_cre \r\n"); - printf(" -- create task notify test now, use notify take false\r\n"); + printf(" -- Create task notify test now, use notify take false.\r\n"); printf(" notify false_del \r\n"); - printf(" -- del notify take false tasks now\r\n"); + printf(" -- Del notify take false tasks now.\r\n"); } @@ -58,55 +59,55 @@ int TaskNotifyCmd(int argc, char *argv[]) if (!strcmp(argv[1], "true_cre")) { - if(create_flg[NOTIFY_TAKE_TRUE_TASK_INDEX] == 0) + if (create_flg[NOTIFY_TAKE_TRUE_TASK_INDEX] == 0) { CreateNotifyTakeTrueTasks(); create_flg[NOTIFY_TAKE_TRUE_TASK_INDEX] = 1; } else { - printf("Please use true_del cmd first \r\n"); + printf("Please use true_del cmd first. \r\n"); } } else if (!strcmp(argv[1], "true_del")) { - if(create_flg[NOTIFY_TAKE_TRUE_TASK_INDEX] == 1) + if (create_flg[NOTIFY_TAKE_TRUE_TASK_INDEX] == 1) { DeleteNotifyTakeTrueTasks(); create_flg[NOTIFY_TAKE_TRUE_TASK_INDEX] = 0; - } + } else { - printf("Please use true_cre cmd first \r\n"); + printf("Please use true_cre cmd first. \r\n"); } } else if (!strcmp(argv[1], "false_cre")) { - if(create_flg[NOTIFY_TAKE_FALSE_TASK_INDEX] == 0) + if (create_flg[NOTIFY_TAKE_FALSE_TASK_INDEX] == 0) { CreateNotifyTakeFalseTasks(); create_flg[NOTIFY_TAKE_FALSE_TASK_INDEX] = 1; } else { - printf("Please use false_del cmd first \r\n"); + printf("Please use false_del cmd first. \r\n"); } } else if (!strcmp(argv[1], "false_del")) { - if(create_flg[NOTIFY_TAKE_FALSE_TASK_INDEX] == 1) + if (create_flg[NOTIFY_TAKE_FALSE_TASK_INDEX] == 1) { DeleteNotifyTakeFalseTasks(); create_flg[NOTIFY_TAKE_FALSE_TASK_INDEX] = 0; - } + } else { - printf("Please use false_cre cmd first \r\n"); + printf("Please use false_cre cmd first. \r\n"); } } else { - printf("Error: Invalid arguments \r\n"); + printf("Error: Invalid arguments. \r\n"); TaskNotifyCmdUsage(); } return 0; diff --git a/example/makefile b/example/makefile deleted file mode 100644 index 84072e28..00000000 --- a/example/makefile +++ /dev/null @@ -1,18 +0,0 @@ -# Compiling all examples -TOPTARGETS := all clean - -#SUBDIRS := $(wildcard */.) -SUBDIRS := freertos_feature \ - hello_world \ - start_up \ - lwip_test \ - template - -$(TOPTARGETS): $(SUBDIRS) - @for i in $(SUBDIRS); do \ - echo -e "\033[44;37;1m +++ Compiling $$i...\033[0m"; \ - $(MAKE) -C $$i $(MAKECMDGOALS) > /dev/null || exit $$?; \ - echo -e "\033[44;37;1m +++ Compiled OK $$i...\033[0m"; \ - done - -.PHONY: $(TOPTARGETS) $(SUBDIRS) \ No newline at end of file diff --git a/example/network/gmac_lwip_test/Kconfig b/example/network/gmac_lwip_test/Kconfig deleted file mode 100644 index 836a5a31..00000000 --- a/example/network/gmac_lwip_test/Kconfig +++ /dev/null @@ -1,41 +0,0 @@ -mainmenu "Phytium FreeRTOS Configuration" - - menu "Project Configuration" - - config TARGET_NAME - string "Build Target Name" - default "freertos" - help - Build Target name for the demo - - choice - prompt "choice lwip config" - default LWIP_IPV4_TEST - config LWIP_IPV4_TEST - bool "test lwip ipv4" - config LWIP_IPV4_DHCP_TEST - bool "test lwip ipv4 and dhcp" - config LWIP_IPV6_TEST - bool "test lwip ipv6" - endchoice - - config GMAC_RX_DESCNUM - int "receive description number" - default "16" - help - receive description number for the demo - - config GMAC_TX_DESCNUM - int "transmit description number" - default "16" - help - transmit description number for the demo - - config GMAC_IRQ_PRIORITY - int "gmac irq priority, 0~15" - default "12" - help - gmac irq priority for the demo - endmenu - -source "$(FREERTOS_SDK_ROOT)/Kconfig" diff --git a/example/network/gmac_lwip_test/configs/d2000_aarch32_eg_configs b/example/network/gmac_lwip_test/configs/d2000_aarch32_eg_configs deleted file mode 100644 index a0b4722f..00000000 --- a/example/network/gmac_lwip_test/configs/d2000_aarch32_eg_configs +++ /dev/null @@ -1,411 +0,0 @@ - -# -# Project Configuration -# -CONFIG_TARGET_NAME="d2000_freertos_a32" -CONFIG_LWIP_IPV4_TEST=y -# CONFIG_LWIP_IPV4_DHCP_TEST is not set -# CONFIG_LWIP_IPV6_TEST is not set -CONFIG_GMAC_RX_DESCNUM=16 -CONFIG_GMAC_TX_DESCNUM=16 -CONFIG_GMAC_IRQ_PRIORITY=12 -# end of Project Configuration - -# -# Standalone Setting -# -CONFIG_USE_FREERTOS=y - -# -# Arch Configuration -# -CONFIG_TARGET_ARMV8_AARCH32=y -# CONFIG_TARGET_ARMV8_AARCH64 is not set -CONFIG_USE_CACHE=y -CONFIG_USE_L3CACHE=y -CONFIG_USE_MMU=y -CONFIG_USE_SYS_TICK=y -CONFIG_USE_AARCH64_L1_TO_AARCH32=y -# end of Arch Configuration - -# -# Board Configuration -# -# CONFIG_TARGET_F2000_4 is not set -CONFIG_TARGET_D2000=y -# CONFIG_TARGET_E2000Q is not set -# CONFIG_TARGET_E2000D is not set -# CONFIG_TARGET_E2000S is not set -CONFIG_DEFAULT_DEBUG_PRINT_UART1=y -# CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set -# CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set -# end of Board Configuration - -# -# Components Configuration -# -# CONFIG_USE_SPI is not set -# CONFIG_USE_QSPI is not set -CONFIG_USE_GIC=y -CONFIG_ENABLE_GICV3=y -CONFIG_USE_SERIAL=y - -# -# Usart Configuration -# -CONFIG_ENABLE_Pl011_UART=y -# end of Usart Configuration - -# CONFIG_USE_GPIO is not set -CONFIG_USE_ETH=y - -# -# Eth Configuration -# -# CONFIG_ENABLE_FXMAC is not set -CONFIG_ENABLE_FGMAC=y -CONFIG_FGMAC_PHY_COMMON=y -# CONFIG_FGMAC_PHY_AR803X is not set -# end of Eth Configuration - -# CONFIG_USE_CAN is not set -# CONFIG_USE_I2C is not set -# CONFIG_USE_TIMER is not set -# CONFIG_USE_MIO is not set -# CONFIG_USE_SDMMC is not set -# CONFIG_USE_PCIE is not set -# CONFIG_USE_WDT is not set -# CONFIG_USE_DMA is not set -# CONFIG_USE_NAND is not set -# CONFIG_USE_RTC is not set -# CONFIG_USE_SATA is not set -# CONFIG_USE_USB is not set -# CONFIG_USE_ADC is not set -# CONFIG_USE_PWM is not set -# CONFIG_USE_IPC is not set -# end of Components Configuration - -CONFIG_USE_NEW_LIBC=y -# end of Standalone Setting - -# -# Building Option -# -# CONFIG_LOG_VERBOS is not set -# CONFIG_LOG_DEBUG is not set -CONFIG_LOG_INFO=y -# CONFIG_LOG_WARN is not set -# CONFIG_LOG_ERROR is not set -# CONFIG_LOG_NONE is not set -CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y -CONFIG_INTERRUPT_ROLE_MASTER=y -# CONFIG_INTERRUPT_ROLE_SLAVE is not set -# CONFIG_LOG_EXTRA_INFO is not set -# CONFIG_BOOTUP_DEBUG_PRINTS is not set - -# -# Linker Options -# -CONFIG_AARCH32_RAM_LD=y -# CONFIG_AARCH64_RAM_LD is not set -# CONFIG_USER_DEFINED_LD is not set -CONFIG_LINK_SCRIPT_ROM=y -CONFIG_ROM_START_UP_ADDR=0x80100000 -CONFIG_ROM_SIZE_MB=1 -CONFIG_LINK_SCRIPT_RAM=y -CONFIG_RAM_START_UP_ADDR=0x81000000 -CONFIG_RAM_SIZE_MB=64 -CONFIG_HEAP_SIZE=1 -CONFIG_SVC_STACK_SIZE=0x1000 -CONFIG_SYS_STACK_SIZE=0x1000 -CONFIG_IRQ_STACK_SIZE=0x1000 -CONFIG_ABORT_STACK_SIZE=0x1000 -CONFIG_FIQ_STACK_SIZE=0x1000 -CONFIG_UNDEF_STACK_SIZE=0x1000 -# end of Linker Options - -# -# Compiler Options -# -# CONFIG_OUTPUT_BINARY is not set -# end of Compiler Options -# end of Building Option - -# -# Component Configuration -# - -# -# Freertos Uart Drivers -# -CONFIG_FREERTOS_USE_UART=y -# end of Freertos Uart Drivers - -# -# Freertos Pwm Drivers -# -# CONFIG_FREERTOS_USE_PWM is not set -# end of Freertos Pwm Drivers - -# -# Freertos Qspi Drivers -# -# CONFIG_FREERTOS_USE_QSPI is not set -# end of Freertos Qspi Drivers - -# -# Freertos Wdt Drivers -# -# CONFIG_FREERTOS_USE_WDT is not set -# end of Freertos Wdt Drivers - -# -# Freertos Eth Drivers -# -# CONFIG_FREERTOS_USE_XMAC is not set -# end of Freertos Eth Drivers - -# -# Freertos Gpio Drivers -# -# CONFIG_FREERTOS_USE_GPIO is not set -# end of Freertos Gpio Drivers - -# -# Freertos Spim Drivers -# -# CONFIG_FREERTOS_USE_FSPIM is not set -# end of Freertos Spim Drivers - -# -# Freertos DMA Drivers -# -# CONFIG_FREERTOS_USE_FDDMA is not set -# CONFIG_FREERTOS_USE_FGDMA is not set -# end of Freertos DMA Drivers - -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - -# -# Freertos Adc Drivers -# -# CONFIG_FREERTOS_USE_ADC is not set -# end of Freertos Adc Drivers - -# -# Freertos Can Drivers -# -# CONFIG_FREERTOS_USE_CAN is not set -# end of Freertos Can Drivers -# end of Component Configuration - -# -# FreeRTOS Setting -# -CONFIG_USE_LWIP=y - -# -# LWIP Configuration -# - -# -# LWIP Port Configuration -# -CONFIG_LWIP_FGMAC=y -# CONFIG_LWIP_FXMAC is not set -# end of LWIP Port Configuration - -CONFIG_LWIP_LOCAL_HOSTNAME="phytium" - -# -# memory configuration -# -CONFIG_LWIP_USE_MEM_POOL=y -# CONFIG_LWIP_USE_MEM_HEAP is not set -CONFIG_MEMP_NUM_PBUF=64 -CONFIG_MEM_ALIGNMENT=64 -# end of memory configuration - -# -# NETWORK_INTERFACE_OPTIONS -# -# CONFIG_LWIP_NETIF_API is not set -# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set -# end of NETWORK_INTERFACE_OPTIONS - -# -# LOOPIF -# -CONFIG_LWIP_NETIF_LOOPBACK=y -CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 -# end of LOOPIF - -# -# SLIPIF -# -# CONFIG_LWIP_SLIP_SUPPORT is not set -# end of SLIPIF - -# -# Pbuf options -# -CONFIG_PBUF_POOL_BUFSIZE=2 -# end of Pbuf options - -# -# Internal Memory Pool Sizes -# -CONFIG_PBUF_POOL_SIZE=1 -# end of Internal Memory Pool Sizes - -CONFIG_LWIP_MAX_SOCKETS=10 - -# -# LWIP RAW API -# -CONFIG_LWIP_MAX_RAW_PCBS=16 -# end of LWIP RAW API - -# -# TCP -# -CONFIG_LWIP_MAX_ACTIVE_TCP=16 -CONFIG_LWIP_MAX_LISTENING_TCP=16 -CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y -CONFIG_LWIP_TCP_MAXRTX=12 -CONFIG_LWIP_TCP_SYNMAXRTX=12 -CONFIG_LWIP_TCP_MSS=1440 -CONFIG_LWIP_TCP_TMR_INTERVAL=250 -CONFIG_LWIP_TCP_MSL=60000 -CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 -CONFIG_LWIP_TCP_WND_DEFAULT=5744 -CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 -CONFIG_LWIP_TCP_QUEUE_OOSEQ=y -# CONFIG_LWIP_TCP_SACK_OUT is not set -CONFIG_LWIP_TCP_OVERSIZE_MSS=y -# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set -# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set -# end of TCP - -# -# UDP -# -CONFIG_LWIP_MAX_UDP_PCBS=16 -CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 -# CONFIG_LWIP_NETBUF_RECVINFO is not set -# end of UDP - -# -# IPv4 -# -# CONFIG_USE_IPV4_ONLY is not set -# CONFIG_LWIP_IP4_REASSEMBLY is not set -CONFIG_LWIP_IP4_FRAG=y -# CONFIG_LWIP_IP_FORWARD is not set -CONFIG_IP_REASS_MAX_PBUFS=16 -# end of IPv4 - -# -# ICMP -# -CONFIG_LWIP_ICMP=y -# CONFIG_LWIP_MULTICAST_PING is not set -# CONFIG_LWIP_BROADCAST_PING is not set -# end of ICMP - -# -# DHCP -# -# CONFIG_LWIP_DHCP_ENABLE is not set -CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y -# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set -# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set -# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set -CONFIG_LWIP_DHCP_OPTIONS_LEN=68 -CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y -# end of DHCP - -# -# AUTOIP -# -# CONFIG_LWIP_AUTOIP is not set -# end of AUTOIP - -# -# DNS -# -CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y -# end of DNS - -# -# TCP options -# -CONFIG_LWIP_TCP_RTO_TIME=1500 -# end of TCP options - -# CONFIG_LWIP_TCPIP_CORE_LOCKING is not set - -# -# socket -# -# CONFIG_LWIP_SO_LINGER is not set -CONFIG_LWIP_SO_REUSE=y -CONFIG_LWIP_SO_REUSE_RXTOALL=y -# end of socket - -# CONFIG_LWIP_STATS is not set - -# -# PPP -# -# CONFIG_LWIP_PPP_SUPPORT is not set -CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 -CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 -# end of PPP - -# -# Checksums -# -# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set -# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set -CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y -# end of Checksums - -# -# ipv6 -# -CONFIG_LWIP_IPV6=y -# CONFIG_LWIP_IPV6_AUTOCONFIG is not set -CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 -# CONFIG_LWIP_IPV6_FORWARD is not set -CONFIG_LWIP_IP6_FRAG=y -# CONFIG_LWIP_IP6_REASSEMBLY is not set -# end of ipv6 - -# CONFIG_LWIP_DEBUG is not set -# end of LWIP Configuration - -CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set -# CONFIG_USE_SFUD is not set -# CONFIG_USE_SPIFFS is not set -# CONFIG_USE_AMP is not set -CONFIG_USE_LETTER_SHELL=y - -# -# Letter Shell Configuration -# -CONFIG_LS_PL011_UART=y -CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y -# CONFIG_DEFAULT_LETTER_SHELL_USE_UART0 is not set -# CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set -# end of Letter Shell Configuration - -CONFIG_USE_TLSF=y -# CONFIG_USE_SDMMC_CMD is not set -# CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting diff --git a/example/network/gmac_lwip_test/configs/d2000_aarch64_eg_configs b/example/network/gmac_lwip_test/configs/d2000_aarch64_eg_configs deleted file mode 100644 index b4dd0538..00000000 --- a/example/network/gmac_lwip_test/configs/d2000_aarch64_eg_configs +++ /dev/null @@ -1,407 +0,0 @@ - -# -# Project Configuration -# -CONFIG_TARGET_NAME="d2000_freertos_a64" -CONFIG_LWIP_IPV4_TEST=y -# CONFIG_LWIP_IPV4_DHCP_TEST is not set -# CONFIG_LWIP_IPV6_TEST is not set -CONFIG_GMAC_RX_DESCNUM=16 -CONFIG_GMAC_TX_DESCNUM=16 -CONFIG_GMAC_IRQ_PRIORITY=12 -# end of Project Configuration - -# -# Standalone Setting -# -CONFIG_USE_FREERTOS=y - -# -# Arch Configuration -# -# CONFIG_TARGET_ARMV8_AARCH32 is not set -CONFIG_TARGET_ARMV8_AARCH64=y -CONFIG_USE_CACHE=y -CONFIG_USE_L3CACHE=y -CONFIG_USE_MMU=y -CONFIG_USE_SYS_TICK=y -# CONFIG_MMU_DEBUG_PRINTS is not set -# end of Arch Configuration - -# -# Board Configuration -# -# CONFIG_TARGET_F2000_4 is not set -CONFIG_TARGET_D2000=y -# CONFIG_TARGET_E2000Q is not set -# CONFIG_TARGET_E2000D is not set -# CONFIG_TARGET_E2000S is not set -CONFIG_DEFAULT_DEBUG_PRINT_UART1=y -# CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set -# CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set -# end of Board Configuration - -# -# Components Configuration -# -# CONFIG_USE_SPI is not set -# CONFIG_USE_QSPI is not set -CONFIG_USE_GIC=y -CONFIG_ENABLE_GICV3=y -CONFIG_USE_SERIAL=y - -# -# Usart Configuration -# -CONFIG_ENABLE_Pl011_UART=y -# end of Usart Configuration - -# CONFIG_USE_GPIO is not set -CONFIG_USE_ETH=y - -# -# Eth Configuration -# -# CONFIG_ENABLE_FXMAC is not set -CONFIG_ENABLE_FGMAC=y -CONFIG_FGMAC_PHY_COMMON=y -# CONFIG_FGMAC_PHY_AR803X is not set -# end of Eth Configuration - -# CONFIG_USE_CAN is not set -# CONFIG_USE_I2C is not set -# CONFIG_USE_TIMER is not set -# CONFIG_USE_MIO is not set -# CONFIG_USE_SDMMC is not set -# CONFIG_USE_PCIE is not set -# CONFIG_USE_WDT is not set -# CONFIG_USE_DMA is not set -# CONFIG_USE_NAND is not set -# CONFIG_USE_RTC is not set -# CONFIG_USE_SATA is not set -# CONFIG_USE_USB is not set -# CONFIG_USE_ADC is not set -# CONFIG_USE_PWM is not set -# CONFIG_USE_IPC is not set -# end of Components Configuration - -CONFIG_USE_NEW_LIBC=y -# end of Standalone Setting - -# -# Building Option -# -# CONFIG_LOG_VERBOS is not set -# CONFIG_LOG_DEBUG is not set -CONFIG_LOG_INFO=y -# CONFIG_LOG_WARN is not set -# CONFIG_LOG_ERROR is not set -# CONFIG_LOG_NONE is not set -CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y -CONFIG_INTERRUPT_ROLE_MASTER=y -# CONFIG_INTERRUPT_ROLE_SLAVE is not set -# CONFIG_LOG_EXTRA_INFO is not set -# CONFIG_BOOTUP_DEBUG_PRINTS is not set - -# -# Linker Options -# -# CONFIG_AARCH32_RAM_LD is not set -CONFIG_AARCH64_RAM_LD=y -# CONFIG_USER_DEFINED_LD is not set -CONFIG_LINK_SCRIPT_ROM=y -CONFIG_ROM_START_UP_ADDR=0x80100000 -CONFIG_ROM_SIZE_MB=1 -CONFIG_LINK_SCRIPT_RAM=y -CONFIG_RAM_START_UP_ADDR=0x81000000 -CONFIG_RAM_SIZE_MB=64 -CONFIG_HEAP_SIZE=1 -CONFIG_STACK_SIZE=0x100000 -CONFIG_FPU_STACK_SIZE=0x1000 -# end of Linker Options - -# -# Compiler Options -# -# CONFIG_OUTPUT_BINARY is not set -# end of Compiler Options -# end of Building Option - -# -# Component Configuration -# - -# -# Freertos Uart Drivers -# -CONFIG_FREERTOS_USE_UART=y -# end of Freertos Uart Drivers - -# -# Freertos Pwm Drivers -# -# CONFIG_FREERTOS_USE_PWM is not set -# end of Freertos Pwm Drivers - -# -# Freertos Qspi Drivers -# -# CONFIG_FREERTOS_USE_QSPI is not set -# end of Freertos Qspi Drivers - -# -# Freertos Wdt Drivers -# -# CONFIG_FREERTOS_USE_WDT is not set -# end of Freertos Wdt Drivers - -# -# Freertos Eth Drivers -# -# CONFIG_FREERTOS_USE_XMAC is not set -# end of Freertos Eth Drivers - -# -# Freertos Gpio Drivers -# -# CONFIG_FREERTOS_USE_GPIO is not set -# end of Freertos Gpio Drivers - -# -# Freertos Spim Drivers -# -# CONFIG_FREERTOS_USE_FSPIM is not set -# end of Freertos Spim Drivers - -# -# Freertos DMA Drivers -# -# CONFIG_FREERTOS_USE_FDDMA is not set -# CONFIG_FREERTOS_USE_FGDMA is not set -# end of Freertos DMA Drivers - -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - -# -# Freertos Adc Drivers -# -# CONFIG_FREERTOS_USE_ADC is not set -# end of Freertos Adc Drivers - -# -# Freertos Can Drivers -# -# CONFIG_FREERTOS_USE_CAN is not set -# end of Freertos Can Drivers -# end of Component Configuration - -# -# FreeRTOS Setting -# -CONFIG_USE_LWIP=y - -# -# LWIP Configuration -# - -# -# LWIP Port Configuration -# -CONFIG_LWIP_FGMAC=y -# CONFIG_LWIP_FXMAC is not set -# end of LWIP Port Configuration - -CONFIG_LWIP_LOCAL_HOSTNAME="phytium" - -# -# memory configuration -# -CONFIG_LWIP_USE_MEM_POOL=y -# CONFIG_LWIP_USE_MEM_HEAP is not set -CONFIG_MEMP_NUM_PBUF=64 -CONFIG_MEM_ALIGNMENT=64 -# end of memory configuration - -# -# NETWORK_INTERFACE_OPTIONS -# -# CONFIG_LWIP_NETIF_API is not set -# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set -# end of NETWORK_INTERFACE_OPTIONS - -# -# LOOPIF -# -CONFIG_LWIP_NETIF_LOOPBACK=y -CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 -# end of LOOPIF - -# -# SLIPIF -# -# CONFIG_LWIP_SLIP_SUPPORT is not set -# end of SLIPIF - -# -# Pbuf options -# -CONFIG_PBUF_POOL_BUFSIZE=2 -# end of Pbuf options - -# -# Internal Memory Pool Sizes -# -CONFIG_PBUF_POOL_SIZE=1 -# end of Internal Memory Pool Sizes - -CONFIG_LWIP_MAX_SOCKETS=10 - -# -# LWIP RAW API -# -CONFIG_LWIP_MAX_RAW_PCBS=16 -# end of LWIP RAW API - -# -# TCP -# -CONFIG_LWIP_MAX_ACTIVE_TCP=16 -CONFIG_LWIP_MAX_LISTENING_TCP=16 -CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y -CONFIG_LWIP_TCP_MAXRTX=12 -CONFIG_LWIP_TCP_SYNMAXRTX=12 -CONFIG_LWIP_TCP_MSS=1440 -CONFIG_LWIP_TCP_TMR_INTERVAL=250 -CONFIG_LWIP_TCP_MSL=60000 -CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 -CONFIG_LWIP_TCP_WND_DEFAULT=5744 -CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 -CONFIG_LWIP_TCP_QUEUE_OOSEQ=y -# CONFIG_LWIP_TCP_SACK_OUT is not set -CONFIG_LWIP_TCP_OVERSIZE_MSS=y -# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set -# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set -# end of TCP - -# -# UDP -# -CONFIG_LWIP_MAX_UDP_PCBS=16 -CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 -# CONFIG_LWIP_NETBUF_RECVINFO is not set -# end of UDP - -# -# IPv4 -# -# CONFIG_USE_IPV4_ONLY is not set -# CONFIG_LWIP_IP4_REASSEMBLY is not set -CONFIG_LWIP_IP4_FRAG=y -# CONFIG_LWIP_IP_FORWARD is not set -CONFIG_IP_REASS_MAX_PBUFS=16 -# end of IPv4 - -# -# ICMP -# -CONFIG_LWIP_ICMP=y -# CONFIG_LWIP_MULTICAST_PING is not set -# CONFIG_LWIP_BROADCAST_PING is not set -# end of ICMP - -# -# DHCP -# -# CONFIG_LWIP_DHCP_ENABLE is not set -CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y -# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set -# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set -# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set -CONFIG_LWIP_DHCP_OPTIONS_LEN=68 -CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y -# end of DHCP - -# -# AUTOIP -# -# CONFIG_LWIP_AUTOIP is not set -# end of AUTOIP - -# -# DNS -# -CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y -# end of DNS - -# -# TCP options -# -CONFIG_LWIP_TCP_RTO_TIME=1500 -# end of TCP options - -# CONFIG_LWIP_TCPIP_CORE_LOCKING is not set - -# -# socket -# -# CONFIG_LWIP_SO_LINGER is not set -CONFIG_LWIP_SO_REUSE=y -CONFIG_LWIP_SO_REUSE_RXTOALL=y -# end of socket - -# CONFIG_LWIP_STATS is not set - -# -# PPP -# -# CONFIG_LWIP_PPP_SUPPORT is not set -CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 -CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 -# end of PPP - -# -# Checksums -# -# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set -# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set -CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y -# end of Checksums - -# -# ipv6 -# -CONFIG_LWIP_IPV6=y -# CONFIG_LWIP_IPV6_AUTOCONFIG is not set -CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 -# CONFIG_LWIP_IPV6_FORWARD is not set -CONFIG_LWIP_IP6_FRAG=y -# CONFIG_LWIP_IP6_REASSEMBLY is not set -# end of ipv6 - -# CONFIG_LWIP_DEBUG is not set -# end of LWIP Configuration - -CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set -# CONFIG_USE_SFUD is not set -# CONFIG_USE_SPIFFS is not set -# CONFIG_USE_AMP is not set -CONFIG_USE_LETTER_SHELL=y - -# -# Letter Shell Configuration -# -CONFIG_LS_PL011_UART=y -CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y -# CONFIG_DEFAULT_LETTER_SHELL_USE_UART0 is not set -# CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set -# end of Letter Shell Configuration - -CONFIG_USE_TLSF=y -# CONFIG_USE_SDMMC_CMD is not set -# CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting diff --git a/example/network/gmac_lwip_test/configs/ft2004_aarch32_eg_configs b/example/network/gmac_lwip_test/configs/ft2004_aarch32_eg_configs deleted file mode 100644 index 366e33e6..00000000 --- a/example/network/gmac_lwip_test/configs/ft2004_aarch32_eg_configs +++ /dev/null @@ -1,411 +0,0 @@ - -# -# Project Configuration -# -CONFIG_TARGET_NAME="ft2004_freertos_a32" -CONFIG_LWIP_IPV4_TEST=y -# CONFIG_LWIP_IPV4_DHCP_TEST is not set -# CONFIG_LWIP_IPV6_TEST is not set -CONFIG_GMAC_RX_DESCNUM=256 -CONFIG_GMAC_TX_DESCNUM=256 -CONFIG_GMAC_IRQ_PRIORITY=12 -# end of Project Configuration - -# -# Standalone Setting -# -CONFIG_USE_FREERTOS=y - -# -# Arch Configuration -# -CONFIG_TARGET_ARMV8_AARCH32=y -# CONFIG_TARGET_ARMV8_AARCH64 is not set -CONFIG_USE_CACHE=y -CONFIG_USE_L3CACHE=y -CONFIG_USE_MMU=y -CONFIG_USE_SYS_TICK=y -CONFIG_USE_AARCH64_L1_TO_AARCH32=y -# end of Arch Configuration - -# -# Board Configuration -# -CONFIG_TARGET_F2000_4=y -# CONFIG_TARGET_D2000 is not set -# CONFIG_TARGET_E2000Q is not set -# CONFIG_TARGET_E2000D is not set -# CONFIG_TARGET_E2000S is not set -CONFIG_DEFAULT_DEBUG_PRINT_UART1=y -# CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set -# CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set -# end of Board Configuration - -# -# Components Configuration -# -# CONFIG_USE_SPI is not set -# CONFIG_USE_QSPI is not set -CONFIG_USE_GIC=y -CONFIG_ENABLE_GICV3=y -CONFIG_USE_SERIAL=y - -# -# Usart Configuration -# -CONFIG_ENABLE_Pl011_UART=y -# end of Usart Configuration - -# CONFIG_USE_GPIO is not set -CONFIG_USE_ETH=y - -# -# Eth Configuration -# -# CONFIG_ENABLE_FXMAC is not set -CONFIG_ENABLE_FGMAC=y -CONFIG_FGMAC_PHY_COMMON=y -# CONFIG_FGMAC_PHY_AR803X is not set -# end of Eth Configuration - -# CONFIG_USE_CAN is not set -# CONFIG_USE_I2C is not set -# CONFIG_USE_TIMER is not set -# CONFIG_USE_MIO is not set -# CONFIG_USE_SDMMC is not set -# CONFIG_USE_PCIE is not set -# CONFIG_USE_WDT is not set -# CONFIG_USE_DMA is not set -# CONFIG_USE_NAND is not set -# CONFIG_USE_RTC is not set -# CONFIG_USE_SATA is not set -# CONFIG_USE_USB is not set -# CONFIG_USE_ADC is not set -# CONFIG_USE_PWM is not set -# CONFIG_USE_IPC is not set -# end of Components Configuration - -CONFIG_USE_NEW_LIBC=y -# end of Standalone Setting - -# -# Building Option -# -# CONFIG_LOG_VERBOS is not set -CONFIG_LOG_DEBUG=y -# CONFIG_LOG_INFO is not set -# CONFIG_LOG_WARN is not set -# CONFIG_LOG_ERROR is not set -# CONFIG_LOG_NONE is not set -CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y -CONFIG_INTERRUPT_ROLE_MASTER=y -# CONFIG_INTERRUPT_ROLE_SLAVE is not set -# CONFIG_LOG_EXTRA_INFO is not set -# CONFIG_BOOTUP_DEBUG_PRINTS is not set - -# -# Linker Options -# -CONFIG_AARCH32_RAM_LD=y -# CONFIG_AARCH64_RAM_LD is not set -# CONFIG_USER_DEFINED_LD is not set -CONFIG_LINK_SCRIPT_ROM=y -CONFIG_ROM_START_UP_ADDR=0xa0100000 -CONFIG_ROM_SIZE_MB=1 -CONFIG_LINK_SCRIPT_RAM=y -CONFIG_RAM_START_UP_ADDR=0xa1000000 -CONFIG_RAM_SIZE_MB=64 -CONFIG_HEAP_SIZE=1 -CONFIG_SVC_STACK_SIZE=0x1000 -CONFIG_SYS_STACK_SIZE=0x1000 -CONFIG_IRQ_STACK_SIZE=0x1000 -CONFIG_ABORT_STACK_SIZE=0x1000 -CONFIG_FIQ_STACK_SIZE=0x1000 -CONFIG_UNDEF_STACK_SIZE=0x1000 -# end of Linker Options - -# -# Compiler Options -# -# CONFIG_OUTPUT_BINARY is not set -# end of Compiler Options -# end of Building Option - -# -# Component Configuration -# - -# -# Freertos Uart Drivers -# -CONFIG_FREERTOS_USE_UART=y -# end of Freertos Uart Drivers - -# -# Freertos Pwm Drivers -# -# CONFIG_FREERTOS_USE_PWM is not set -# end of Freertos Pwm Drivers - -# -# Freertos Qspi Drivers -# -# CONFIG_FREERTOS_USE_QSPI is not set -# end of Freertos Qspi Drivers - -# -# Freertos Wdt Drivers -# -# CONFIG_FREERTOS_USE_WDT is not set -# end of Freertos Wdt Drivers - -# -# Freertos Eth Drivers -# -# CONFIG_FREERTOS_USE_XMAC is not set -# end of Freertos Eth Drivers - -# -# Freertos Gpio Drivers -# -# CONFIG_FREERTOS_USE_GPIO is not set -# end of Freertos Gpio Drivers - -# -# Freertos Spim Drivers -# -# CONFIG_FREERTOS_USE_FSPIM is not set -# end of Freertos Spim Drivers - -# -# Freertos DMA Drivers -# -# CONFIG_FREERTOS_USE_FDDMA is not set -# CONFIG_FREERTOS_USE_FGDMA is not set -# end of Freertos DMA Drivers - -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - -# -# Freertos Adc Drivers -# -# CONFIG_FREERTOS_USE_ADC is not set -# end of Freertos Adc Drivers - -# -# Freertos Can Drivers -# -# CONFIG_FREERTOS_USE_CAN is not set -# end of Freertos Can Drivers -# end of Component Configuration - -# -# FreeRTOS Setting -# -CONFIG_USE_LWIP=y - -# -# LWIP Configuration -# - -# -# LWIP Port Configuration -# -CONFIG_LWIP_FGMAC=y -# CONFIG_LWIP_FXMAC is not set -# end of LWIP Port Configuration - -CONFIG_LWIP_LOCAL_HOSTNAME="phytium" - -# -# memory configuration -# -CONFIG_LWIP_USE_MEM_POOL=y -# CONFIG_LWIP_USE_MEM_HEAP is not set -CONFIG_MEMP_NUM_PBUF=64 -CONFIG_MEM_ALIGNMENT=64 -# end of memory configuration - -# -# NETWORK_INTERFACE_OPTIONS -# -# CONFIG_LWIP_NETIF_API is not set -# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set -# end of NETWORK_INTERFACE_OPTIONS - -# -# LOOPIF -# -CONFIG_LWIP_NETIF_LOOPBACK=y -CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 -# end of LOOPIF - -# -# SLIPIF -# -# CONFIG_LWIP_SLIP_SUPPORT is not set -# end of SLIPIF - -# -# Pbuf options -# -CONFIG_PBUF_POOL_BUFSIZE=2 -# end of Pbuf options - -# -# Internal Memory Pool Sizes -# -CONFIG_PBUF_POOL_SIZE=1 -# end of Internal Memory Pool Sizes - -CONFIG_LWIP_MAX_SOCKETS=10 - -# -# LWIP RAW API -# -CONFIG_LWIP_MAX_RAW_PCBS=16 -# end of LWIP RAW API - -# -# TCP -# -CONFIG_LWIP_MAX_ACTIVE_TCP=16 -CONFIG_LWIP_MAX_LISTENING_TCP=16 -CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y -CONFIG_LWIP_TCP_MAXRTX=12 -CONFIG_LWIP_TCP_SYNMAXRTX=12 -CONFIG_LWIP_TCP_MSS=1440 -CONFIG_LWIP_TCP_TMR_INTERVAL=250 -CONFIG_LWIP_TCP_MSL=60000 -CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 -CONFIG_LWIP_TCP_WND_DEFAULT=5744 -CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 -CONFIG_LWIP_TCP_QUEUE_OOSEQ=y -# CONFIG_LWIP_TCP_SACK_OUT is not set -CONFIG_LWIP_TCP_OVERSIZE_MSS=y -# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set -# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set -# end of TCP - -# -# UDP -# -CONFIG_LWIP_MAX_UDP_PCBS=16 -CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 -# CONFIG_LWIP_NETBUF_RECVINFO is not set -# end of UDP - -# -# IPv4 -# -# CONFIG_USE_IPV4_ONLY is not set -# CONFIG_LWIP_IP4_REASSEMBLY is not set -CONFIG_LWIP_IP4_FRAG=y -# CONFIG_LWIP_IP_FORWARD is not set -CONFIG_IP_REASS_MAX_PBUFS=16 -# end of IPv4 - -# -# ICMP -# -CONFIG_LWIP_ICMP=y -# CONFIG_LWIP_MULTICAST_PING is not set -# CONFIG_LWIP_BROADCAST_PING is not set -# end of ICMP - -# -# DHCP -# -# CONFIG_LWIP_DHCP_ENABLE is not set -CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y -# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set -# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set -# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set -CONFIG_LWIP_DHCP_OPTIONS_LEN=68 -CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y -# end of DHCP - -# -# AUTOIP -# -# CONFIG_LWIP_AUTOIP is not set -# end of AUTOIP - -# -# DNS -# -CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y -# end of DNS - -# -# TCP options -# -CONFIG_LWIP_TCP_RTO_TIME=1500 -# end of TCP options - -# CONFIG_LWIP_TCPIP_CORE_LOCKING is not set - -# -# socket -# -# CONFIG_LWIP_SO_LINGER is not set -CONFIG_LWIP_SO_REUSE=y -CONFIG_LWIP_SO_REUSE_RXTOALL=y -# end of socket - -# CONFIG_LWIP_STATS is not set - -# -# PPP -# -# CONFIG_LWIP_PPP_SUPPORT is not set -CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 -CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 -# end of PPP - -# -# Checksums -# -# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set -# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set -CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y -# end of Checksums - -# -# ipv6 -# -CONFIG_LWIP_IPV6=y -# CONFIG_LWIP_IPV6_AUTOCONFIG is not set -CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 -# CONFIG_LWIP_IPV6_FORWARD is not set -CONFIG_LWIP_IP6_FRAG=y -# CONFIG_LWIP_IP6_REASSEMBLY is not set -# end of ipv6 - -# CONFIG_LWIP_DEBUG is not set -# end of LWIP Configuration - -CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set -# CONFIG_USE_SFUD is not set -# CONFIG_USE_SPIFFS is not set -# CONFIG_USE_AMP is not set -CONFIG_USE_LETTER_SHELL=y - -# -# Letter Shell Configuration -# -CONFIG_LS_PL011_UART=y -CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y -# CONFIG_DEFAULT_LETTER_SHELL_USE_UART0 is not set -# CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set -# end of Letter Shell Configuration - -CONFIG_USE_TLSF=y -# CONFIG_USE_SDMMC_CMD is not set -# CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting diff --git a/example/network/gmac_lwip_test/configs/ft2004_aarch64_eg_configs b/example/network/gmac_lwip_test/configs/ft2004_aarch64_eg_configs deleted file mode 100644 index da6f3c91..00000000 --- a/example/network/gmac_lwip_test/configs/ft2004_aarch64_eg_configs +++ /dev/null @@ -1,407 +0,0 @@ - -# -# Project Configuration -# -CONFIG_TARGET_NAME="ft2004_freertos_a64" -CONFIG_LWIP_IPV4_TEST=y -# CONFIG_LWIP_IPV4_DHCP_TEST is not set -# CONFIG_LWIP_IPV6_TEST is not set -CONFIG_GMAC_RX_DESCNUM=256 -CONFIG_GMAC_TX_DESCNUM=256 -CONFIG_GMAC_IRQ_PRIORITY=12 -# end of Project Configuration - -# -# Standalone Setting -# -CONFIG_USE_FREERTOS=y - -# -# Arch Configuration -# -# CONFIG_TARGET_ARMV8_AARCH32 is not set -CONFIG_TARGET_ARMV8_AARCH64=y -CONFIG_USE_CACHE=y -# CONFIG_USE_L3CACHE is not set -CONFIG_USE_MMU=y -CONFIG_USE_SYS_TICK=y -# CONFIG_MMU_DEBUG_PRINTS is not set -# end of Arch Configuration - -# -# Board Configuration -# -CONFIG_TARGET_F2000_4=y -# CONFIG_TARGET_D2000 is not set -# CONFIG_TARGET_E2000Q is not set -# CONFIG_TARGET_E2000D is not set -# CONFIG_TARGET_E2000S is not set -CONFIG_DEFAULT_DEBUG_PRINT_UART1=y -# CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set -# CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set -# end of Board Configuration - -# -# Components Configuration -# -# CONFIG_USE_SPI is not set -# CONFIG_USE_QSPI is not set -CONFIG_USE_GIC=y -CONFIG_ENABLE_GICV3=y -CONFIG_USE_SERIAL=y - -# -# Usart Configuration -# -CONFIG_ENABLE_Pl011_UART=y -# end of Usart Configuration - -# CONFIG_USE_GPIO is not set -CONFIG_USE_ETH=y - -# -# Eth Configuration -# -# CONFIG_ENABLE_FXMAC is not set -CONFIG_ENABLE_FGMAC=y -CONFIG_FGMAC_PHY_COMMON=y -# CONFIG_FGMAC_PHY_AR803X is not set -# end of Eth Configuration - -# CONFIG_USE_CAN is not set -# CONFIG_USE_I2C is not set -# CONFIG_USE_TIMER is not set -# CONFIG_USE_MIO is not set -# CONFIG_USE_SDMMC is not set -# CONFIG_USE_PCIE is not set -# CONFIG_USE_WDT is not set -# CONFIG_USE_DMA is not set -# CONFIG_USE_NAND is not set -# CONFIG_USE_RTC is not set -# CONFIG_USE_SATA is not set -# CONFIG_USE_USB is not set -# CONFIG_USE_ADC is not set -# CONFIG_USE_PWM is not set -# CONFIG_USE_IPC is not set -# end of Components Configuration - -CONFIG_USE_NEW_LIBC=y -# end of Standalone Setting - -# -# Building Option -# -# CONFIG_LOG_VERBOS is not set -CONFIG_LOG_DEBUG=y -# CONFIG_LOG_INFO is not set -# CONFIG_LOG_WARN is not set -# CONFIG_LOG_ERROR is not set -# CONFIG_LOG_NONE is not set -CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y -CONFIG_INTERRUPT_ROLE_MASTER=y -# CONFIG_INTERRUPT_ROLE_SLAVE is not set -# CONFIG_LOG_EXTRA_INFO is not set -# CONFIG_BOOTUP_DEBUG_PRINTS is not set - -# -# Linker Options -# -# CONFIG_AARCH32_RAM_LD is not set -CONFIG_AARCH64_RAM_LD=y -# CONFIG_USER_DEFINED_LD is not set -CONFIG_LINK_SCRIPT_ROM=y -CONFIG_ROM_START_UP_ADDR=0xa0100000 -CONFIG_ROM_SIZE_MB=1 -CONFIG_LINK_SCRIPT_RAM=y -CONFIG_RAM_START_UP_ADDR=0xa1000000 -CONFIG_RAM_SIZE_MB=64 -CONFIG_HEAP_SIZE=1 -CONFIG_STACK_SIZE=0x100000 -CONFIG_FPU_STACK_SIZE=0x1000 -# end of Linker Options - -# -# Compiler Options -# -# CONFIG_OUTPUT_BINARY is not set -# end of Compiler Options -# end of Building Option - -# -# Component Configuration -# - -# -# Freertos Uart Drivers -# -CONFIG_FREERTOS_USE_UART=y -# end of Freertos Uart Drivers - -# -# Freertos Pwm Drivers -# -# CONFIG_FREERTOS_USE_PWM is not set -# end of Freertos Pwm Drivers - -# -# Freertos Qspi Drivers -# -# CONFIG_FREERTOS_USE_QSPI is not set -# end of Freertos Qspi Drivers - -# -# Freertos Wdt Drivers -# -# CONFIG_FREERTOS_USE_WDT is not set -# end of Freertos Wdt Drivers - -# -# Freertos Eth Drivers -# -# CONFIG_FREERTOS_USE_XMAC is not set -# end of Freertos Eth Drivers - -# -# Freertos Gpio Drivers -# -# CONFIG_FREERTOS_USE_GPIO is not set -# end of Freertos Gpio Drivers - -# -# Freertos Spim Drivers -# -# CONFIG_FREERTOS_USE_FSPIM is not set -# end of Freertos Spim Drivers - -# -# Freertos DMA Drivers -# -# CONFIG_FREERTOS_USE_FDDMA is not set -# CONFIG_FREERTOS_USE_FGDMA is not set -# end of Freertos DMA Drivers - -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - -# -# Freertos Adc Drivers -# -# CONFIG_FREERTOS_USE_ADC is not set -# end of Freertos Adc Drivers - -# -# Freertos Can Drivers -# -# CONFIG_FREERTOS_USE_CAN is not set -# end of Freertos Can Drivers -# end of Component Configuration - -# -# FreeRTOS Setting -# -CONFIG_USE_LWIP=y - -# -# LWIP Configuration -# - -# -# LWIP Port Configuration -# -CONFIG_LWIP_FGMAC=y -# CONFIG_LWIP_FXMAC is not set -# end of LWIP Port Configuration - -CONFIG_LWIP_LOCAL_HOSTNAME="phytium" - -# -# memory configuration -# -CONFIG_LWIP_USE_MEM_POOL=y -# CONFIG_LWIP_USE_MEM_HEAP is not set -CONFIG_MEMP_NUM_PBUF=64 -CONFIG_MEM_ALIGNMENT=64 -# end of memory configuration - -# -# NETWORK_INTERFACE_OPTIONS -# -# CONFIG_LWIP_NETIF_API is not set -# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set -# end of NETWORK_INTERFACE_OPTIONS - -# -# LOOPIF -# -CONFIG_LWIP_NETIF_LOOPBACK=y -CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 -# end of LOOPIF - -# -# SLIPIF -# -# CONFIG_LWIP_SLIP_SUPPORT is not set -# end of SLIPIF - -# -# Pbuf options -# -CONFIG_PBUF_POOL_BUFSIZE=2 -# end of Pbuf options - -# -# Internal Memory Pool Sizes -# -CONFIG_PBUF_POOL_SIZE=1 -# end of Internal Memory Pool Sizes - -CONFIG_LWIP_MAX_SOCKETS=10 - -# -# LWIP RAW API -# -CONFIG_LWIP_MAX_RAW_PCBS=16 -# end of LWIP RAW API - -# -# TCP -# -CONFIG_LWIP_MAX_ACTIVE_TCP=16 -CONFIG_LWIP_MAX_LISTENING_TCP=16 -CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y -CONFIG_LWIP_TCP_MAXRTX=12 -CONFIG_LWIP_TCP_SYNMAXRTX=12 -CONFIG_LWIP_TCP_MSS=1440 -CONFIG_LWIP_TCP_TMR_INTERVAL=250 -CONFIG_LWIP_TCP_MSL=60000 -CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 -CONFIG_LWIP_TCP_WND_DEFAULT=5744 -CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 -CONFIG_LWIP_TCP_QUEUE_OOSEQ=y -# CONFIG_LWIP_TCP_SACK_OUT is not set -CONFIG_LWIP_TCP_OVERSIZE_MSS=y -# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set -# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set -# end of TCP - -# -# UDP -# -CONFIG_LWIP_MAX_UDP_PCBS=16 -CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 -# CONFIG_LWIP_NETBUF_RECVINFO is not set -# end of UDP - -# -# IPv4 -# -# CONFIG_USE_IPV4_ONLY is not set -# CONFIG_LWIP_IP4_REASSEMBLY is not set -CONFIG_LWIP_IP4_FRAG=y -# CONFIG_LWIP_IP_FORWARD is not set -CONFIG_IP_REASS_MAX_PBUFS=16 -# end of IPv4 - -# -# ICMP -# -CONFIG_LWIP_ICMP=y -# CONFIG_LWIP_MULTICAST_PING is not set -# CONFIG_LWIP_BROADCAST_PING is not set -# end of ICMP - -# -# DHCP -# -# CONFIG_LWIP_DHCP_ENABLE is not set -CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y -# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set -# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set -# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set -CONFIG_LWIP_DHCP_OPTIONS_LEN=68 -CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y -# end of DHCP - -# -# AUTOIP -# -# CONFIG_LWIP_AUTOIP is not set -# end of AUTOIP - -# -# DNS -# -CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y -# end of DNS - -# -# TCP options -# -CONFIG_LWIP_TCP_RTO_TIME=1500 -# end of TCP options - -# CONFIG_LWIP_TCPIP_CORE_LOCKING is not set - -# -# socket -# -# CONFIG_LWIP_SO_LINGER is not set -CONFIG_LWIP_SO_REUSE=y -CONFIG_LWIP_SO_REUSE_RXTOALL=y -# end of socket - -# CONFIG_LWIP_STATS is not set - -# -# PPP -# -# CONFIG_LWIP_PPP_SUPPORT is not set -CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 -CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 -# end of PPP - -# -# Checksums -# -# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set -# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set -CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y -# end of Checksums - -# -# ipv6 -# -CONFIG_LWIP_IPV6=y -# CONFIG_LWIP_IPV6_AUTOCONFIG is not set -CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 -# CONFIG_LWIP_IPV6_FORWARD is not set -CONFIG_LWIP_IP6_FRAG=y -# CONFIG_LWIP_IP6_REASSEMBLY is not set -# end of ipv6 - -# CONFIG_LWIP_DEBUG is not set -# end of LWIP Configuration - -CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set -# CONFIG_USE_SFUD is not set -# CONFIG_USE_SPIFFS is not set -# CONFIG_USE_AMP is not set -CONFIG_USE_LETTER_SHELL=y - -# -# Letter Shell Configuration -# -CONFIG_LS_PL011_UART=y -CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y -# CONFIG_DEFAULT_LETTER_SHELL_USE_UART0 is not set -# CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set -# end of Letter Shell Configuration - -CONFIG_USE_TLSF=y -# CONFIG_USE_SDMMC_CMD is not set -# CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting diff --git a/example/network/gmac_lwip_test/pic/gmac_dhcp_menuconfig.png b/example/network/gmac_lwip_test/pic/gmac_dhcp_menuconfig.png deleted file mode 100644 index e55d4680896c8e3b4dc20b143ddd0f4ca260e492..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16955 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 diff --git a/example/network/gmac_lwip_test/pic/gmac_ipv4_menuconfig.png b/example/network/gmac_lwip_test/pic/gmac_ipv4_menuconfig.png deleted file mode 100644 index 1a50ea64e91afb611dcdcb345a5d9954447d6478..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16316 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 diff --git a/example/network/gmac_lwip_test/pic/gmac_ipv6_menuconfig.png b/example/network/gmac_lwip_test/pic/gmac_ipv6_menuconfig.png deleted file mode 100644 index 18defa998a975736c4323d5d930c958a5b5ccaec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16610 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 M?|8N5vUk#d0VxoiFaQ7m diff --git a/example/network/gmac_lwip_test/pic/gmac_probe_dhcp0.png b/example/network/gmac_lwip_test/pic/gmac_probe_dhcp0.png deleted file mode 100644 index daba5719bb78d4b64dd37570ddefdcb40a2ef329..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28043 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 ZK$geGMsj)HKivLNt?Re1WnVFW^*?g&<4gbm diff --git a/example/network/gmac_lwip_test/pic/gmac_probe_dhcp1.png b/example/network/gmac_lwip_test/pic/gmac_probe_dhcp1.png deleted file mode 100644 index 85564c5066bb6f8a3a2e6b89cd2c3b79b4e00b00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5149 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 HROJ5v226$S diff --git a/example/network/gmac_lwip_test/pic/gmac_probe_ipv6.png b/example/network/gmac_lwip_test/pic/gmac_probe_ipv6.png deleted file mode 100644 index 25296e3ff182234eeea10312039a493b07915c0b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20252 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 OS2=v=e74foFaBR?4-ioR diff --git a/example/network/gmac_lwip_test/pic/ping_ipv6.png b/example/network/gmac_lwip_test/pic/ping_ipv6.png deleted file mode 100644 index fd893dd34d44a2d6582de5bb436c1f9f076a5a33..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29639 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 diff --git a/example/network/gmac_lwip_test/sdkconfig b/example/network/gmac_lwip_test/sdkconfig deleted file mode 100644 index b4dd0538..00000000 --- a/example/network/gmac_lwip_test/sdkconfig +++ /dev/null @@ -1,407 +0,0 @@ - -# -# Project Configuration -# -CONFIG_TARGET_NAME="d2000_freertos_a64" -CONFIG_LWIP_IPV4_TEST=y -# CONFIG_LWIP_IPV4_DHCP_TEST is not set -# CONFIG_LWIP_IPV6_TEST is not set -CONFIG_GMAC_RX_DESCNUM=16 -CONFIG_GMAC_TX_DESCNUM=16 -CONFIG_GMAC_IRQ_PRIORITY=12 -# end of Project Configuration - -# -# Standalone Setting -# -CONFIG_USE_FREERTOS=y - -# -# Arch Configuration -# -# CONFIG_TARGET_ARMV8_AARCH32 is not set -CONFIG_TARGET_ARMV8_AARCH64=y -CONFIG_USE_CACHE=y -CONFIG_USE_L3CACHE=y -CONFIG_USE_MMU=y -CONFIG_USE_SYS_TICK=y -# CONFIG_MMU_DEBUG_PRINTS is not set -# end of Arch Configuration - -# -# Board Configuration -# -# CONFIG_TARGET_F2000_4 is not set -CONFIG_TARGET_D2000=y -# CONFIG_TARGET_E2000Q is not set -# CONFIG_TARGET_E2000D is not set -# CONFIG_TARGET_E2000S is not set -CONFIG_DEFAULT_DEBUG_PRINT_UART1=y -# CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set -# CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set -# end of Board Configuration - -# -# Components Configuration -# -# CONFIG_USE_SPI is not set -# CONFIG_USE_QSPI is not set -CONFIG_USE_GIC=y -CONFIG_ENABLE_GICV3=y -CONFIG_USE_SERIAL=y - -# -# Usart Configuration -# -CONFIG_ENABLE_Pl011_UART=y -# end of Usart Configuration - -# CONFIG_USE_GPIO is not set -CONFIG_USE_ETH=y - -# -# Eth Configuration -# -# CONFIG_ENABLE_FXMAC is not set -CONFIG_ENABLE_FGMAC=y -CONFIG_FGMAC_PHY_COMMON=y -# CONFIG_FGMAC_PHY_AR803X is not set -# end of Eth Configuration - -# CONFIG_USE_CAN is not set -# CONFIG_USE_I2C is not set -# CONFIG_USE_TIMER is not set -# CONFIG_USE_MIO is not set -# CONFIG_USE_SDMMC is not set -# CONFIG_USE_PCIE is not set -# CONFIG_USE_WDT is not set -# CONFIG_USE_DMA is not set -# CONFIG_USE_NAND is not set -# CONFIG_USE_RTC is not set -# CONFIG_USE_SATA is not set -# CONFIG_USE_USB is not set -# CONFIG_USE_ADC is not set -# CONFIG_USE_PWM is not set -# CONFIG_USE_IPC is not set -# end of Components Configuration - -CONFIG_USE_NEW_LIBC=y -# end of Standalone Setting - -# -# Building Option -# -# CONFIG_LOG_VERBOS is not set -# CONFIG_LOG_DEBUG is not set -CONFIG_LOG_INFO=y -# CONFIG_LOG_WARN is not set -# CONFIG_LOG_ERROR is not set -# CONFIG_LOG_NONE is not set -CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y -CONFIG_INTERRUPT_ROLE_MASTER=y -# CONFIG_INTERRUPT_ROLE_SLAVE is not set -# CONFIG_LOG_EXTRA_INFO is not set -# CONFIG_BOOTUP_DEBUG_PRINTS is not set - -# -# Linker Options -# -# CONFIG_AARCH32_RAM_LD is not set -CONFIG_AARCH64_RAM_LD=y -# CONFIG_USER_DEFINED_LD is not set -CONFIG_LINK_SCRIPT_ROM=y -CONFIG_ROM_START_UP_ADDR=0x80100000 -CONFIG_ROM_SIZE_MB=1 -CONFIG_LINK_SCRIPT_RAM=y -CONFIG_RAM_START_UP_ADDR=0x81000000 -CONFIG_RAM_SIZE_MB=64 -CONFIG_HEAP_SIZE=1 -CONFIG_STACK_SIZE=0x100000 -CONFIG_FPU_STACK_SIZE=0x1000 -# end of Linker Options - -# -# Compiler Options -# -# CONFIG_OUTPUT_BINARY is not set -# end of Compiler Options -# end of Building Option - -# -# Component Configuration -# - -# -# Freertos Uart Drivers -# -CONFIG_FREERTOS_USE_UART=y -# end of Freertos Uart Drivers - -# -# Freertos Pwm Drivers -# -# CONFIG_FREERTOS_USE_PWM is not set -# end of Freertos Pwm Drivers - -# -# Freertos Qspi Drivers -# -# CONFIG_FREERTOS_USE_QSPI is not set -# end of Freertos Qspi Drivers - -# -# Freertos Wdt Drivers -# -# CONFIG_FREERTOS_USE_WDT is not set -# end of Freertos Wdt Drivers - -# -# Freertos Eth Drivers -# -# CONFIG_FREERTOS_USE_XMAC is not set -# end of Freertos Eth Drivers - -# -# Freertos Gpio Drivers -# -# CONFIG_FREERTOS_USE_GPIO is not set -# end of Freertos Gpio Drivers - -# -# Freertos Spim Drivers -# -# CONFIG_FREERTOS_USE_FSPIM is not set -# end of Freertos Spim Drivers - -# -# Freertos DMA Drivers -# -# CONFIG_FREERTOS_USE_FDDMA is not set -# CONFIG_FREERTOS_USE_FGDMA is not set -# end of Freertos DMA Drivers - -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - -# -# Freertos Adc Drivers -# -# CONFIG_FREERTOS_USE_ADC is not set -# end of Freertos Adc Drivers - -# -# Freertos Can Drivers -# -# CONFIG_FREERTOS_USE_CAN is not set -# end of Freertos Can Drivers -# end of Component Configuration - -# -# FreeRTOS Setting -# -CONFIG_USE_LWIP=y - -# -# LWIP Configuration -# - -# -# LWIP Port Configuration -# -CONFIG_LWIP_FGMAC=y -# CONFIG_LWIP_FXMAC is not set -# end of LWIP Port Configuration - -CONFIG_LWIP_LOCAL_HOSTNAME="phytium" - -# -# memory configuration -# -CONFIG_LWIP_USE_MEM_POOL=y -# CONFIG_LWIP_USE_MEM_HEAP is not set -CONFIG_MEMP_NUM_PBUF=64 -CONFIG_MEM_ALIGNMENT=64 -# end of memory configuration - -# -# NETWORK_INTERFACE_OPTIONS -# -# CONFIG_LWIP_NETIF_API is not set -# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set -# end of NETWORK_INTERFACE_OPTIONS - -# -# LOOPIF -# -CONFIG_LWIP_NETIF_LOOPBACK=y -CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 -# end of LOOPIF - -# -# SLIPIF -# -# CONFIG_LWIP_SLIP_SUPPORT is not set -# end of SLIPIF - -# -# Pbuf options -# -CONFIG_PBUF_POOL_BUFSIZE=2 -# end of Pbuf options - -# -# Internal Memory Pool Sizes -# -CONFIG_PBUF_POOL_SIZE=1 -# end of Internal Memory Pool Sizes - -CONFIG_LWIP_MAX_SOCKETS=10 - -# -# LWIP RAW API -# -CONFIG_LWIP_MAX_RAW_PCBS=16 -# end of LWIP RAW API - -# -# TCP -# -CONFIG_LWIP_MAX_ACTIVE_TCP=16 -CONFIG_LWIP_MAX_LISTENING_TCP=16 -CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y -CONFIG_LWIP_TCP_MAXRTX=12 -CONFIG_LWIP_TCP_SYNMAXRTX=12 -CONFIG_LWIP_TCP_MSS=1440 -CONFIG_LWIP_TCP_TMR_INTERVAL=250 -CONFIG_LWIP_TCP_MSL=60000 -CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 -CONFIG_LWIP_TCP_WND_DEFAULT=5744 -CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 -CONFIG_LWIP_TCP_QUEUE_OOSEQ=y -# CONFIG_LWIP_TCP_SACK_OUT is not set -CONFIG_LWIP_TCP_OVERSIZE_MSS=y -# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set -# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set -# end of TCP - -# -# UDP -# -CONFIG_LWIP_MAX_UDP_PCBS=16 -CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 -# CONFIG_LWIP_NETBUF_RECVINFO is not set -# end of UDP - -# -# IPv4 -# -# CONFIG_USE_IPV4_ONLY is not set -# CONFIG_LWIP_IP4_REASSEMBLY is not set -CONFIG_LWIP_IP4_FRAG=y -# CONFIG_LWIP_IP_FORWARD is not set -CONFIG_IP_REASS_MAX_PBUFS=16 -# end of IPv4 - -# -# ICMP -# -CONFIG_LWIP_ICMP=y -# CONFIG_LWIP_MULTICAST_PING is not set -# CONFIG_LWIP_BROADCAST_PING is not set -# end of ICMP - -# -# DHCP -# -# CONFIG_LWIP_DHCP_ENABLE is not set -CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y -# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set -# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set -# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set -CONFIG_LWIP_DHCP_OPTIONS_LEN=68 -CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y -# end of DHCP - -# -# AUTOIP -# -# CONFIG_LWIP_AUTOIP is not set -# end of AUTOIP - -# -# DNS -# -CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y -# end of DNS - -# -# TCP options -# -CONFIG_LWIP_TCP_RTO_TIME=1500 -# end of TCP options - -# CONFIG_LWIP_TCPIP_CORE_LOCKING is not set - -# -# socket -# -# CONFIG_LWIP_SO_LINGER is not set -CONFIG_LWIP_SO_REUSE=y -CONFIG_LWIP_SO_REUSE_RXTOALL=y -# end of socket - -# CONFIG_LWIP_STATS is not set - -# -# PPP -# -# CONFIG_LWIP_PPP_SUPPORT is not set -CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 -CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 -# end of PPP - -# -# Checksums -# -# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set -# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set -CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y -# end of Checksums - -# -# ipv6 -# -CONFIG_LWIP_IPV6=y -# CONFIG_LWIP_IPV6_AUTOCONFIG is not set -CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 -# CONFIG_LWIP_IPV6_FORWARD is not set -CONFIG_LWIP_IP6_FRAG=y -# CONFIG_LWIP_IP6_REASSEMBLY is not set -# end of ipv6 - -# CONFIG_LWIP_DEBUG is not set -# end of LWIP Configuration - -CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set -# CONFIG_USE_SFUD is not set -# CONFIG_USE_SPIFFS is not set -# CONFIG_USE_AMP is not set -CONFIG_USE_LETTER_SHELL=y - -# -# Letter Shell Configuration -# -CONFIG_LS_PL011_UART=y -CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y -# CONFIG_DEFAULT_LETTER_SHELL_USE_UART0 is not set -# CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set -# end of Letter Shell Configuration - -CONFIG_USE_TLSF=y -# CONFIG_USE_SDMMC_CMD is not set -# CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting diff --git a/example/network/gmac_lwip_test/src/lwip_test.c b/example/network/gmac_lwip_test/src/lwip_test.c deleted file mode 100644 index fa4bbc18..00000000 --- a/example/network/gmac_lwip_test/src/lwip_test.c +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright : (C) 2022 Phytium Information Technology, Inc. - * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * - * FilePath: lwip_test.c - * Date: 2022-06-06 22:57:08 - * LastEditTime: 2022-06-06 22:57:08 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- - */ - -#include -#include -#include "strto.h" -#include "sdkconfig.h" -#include "FreeRTOS.h" -#include "task.h" -#include "ftypes.h" -#include "fparameters.h" - -#ifndef SDK_CONFIG_H__ - #error "Please include sdkconfig.h first" -#endif - - - -#include "lwip_port.h" -#include "lwip/ip4_addr.h" -#include "lwip/init.h" -#include "netif/ethernet.h" -#include "ethernetif.h" -#include "lwip/netif.h" -#include "lwip/tcpip.h" -#include "../src/shell.h" - - - -#if LWIP_IPV6 -#include "lwip/ip.h" -#include "lwip/ip6_addr.h" -#else -#if LWIP_DHCP -#include "lwip/dhcp.h" -#endif -#endif - -#if defined(CONFIG_ENABLE_FGMAC) -#include "ft_os_gmac.h" - -static FtOsGmac os_gmac[GMAC_INSTANCE_NUM] = {0}; -static u32 gmac_id = FT_OS_GMAC0_ID; - -/* the mac address of the board. this should be unique per board */ - unsigned char mac_ethernet_address[GMAC_INSTANCE_NUM][NETIF_MAX_HWADDR_LEN] = { - {0x0, 0x0, 0x1, 0x11, 0x1, 0x21}, - {0x0, 0x0, 0x2, 0x22, 0x2, 0x23} - }; - -#if !LWIP_IPV6 -ip4_addr_t ipaddr[GMAC_INSTANCE_NUM], netmask[GMAC_INSTANCE_NUM], gw[GMAC_INSTANCE_NUM]; -#if LWIP_DHCP -static TaskHandle_t appTaskCreateHandle = NULL; -void LwipDhcpTest(FtOsGmac *os_gmac) -{ - int mscnt = 0; - dhcp_start(&(os_gmac->netif_object)); - printf("LwipDhcpTest is start \r\n"); - while (1) - { - vTaskDelay(DHCP_FINE_TIMER_MSECS / portTICK_RATE_MS); - dhcp_fine_tmr(); - mscnt += DHCP_FINE_TIMER_MSECS; - if (mscnt >= DHCP_COARSE_TIMER_SECS*1000) - { - dhcp_coarse_tmr(); - mscnt = 0; - } - } -} -#endif -#endif - -void LwipRawInit(FtOsGmac *os_gmac) -{ - BaseType_t ret = pdPASS;/* 定义一个创建信息返回值,默认为 pdPASS */ - static boolean init_flag = FALSE; - -#if !LWIP_IPV6 - - memset(&ipaddr[gmac_id], 0, sizeof(ip4_addr_t)); - memset(&netmask[gmac_id], 0, sizeof(ip4_addr_t)); - memset(&gw[gmac_id], 0, sizeof(ip4_addr_t)); - -#if LWIP_DHCP - ipaddr[gmac_id].addr = 0; - gw[gmac_id].addr = 0; - netmask[gmac_id].addr = 0; -#else - /* initialize IP addresses to be used */ - IP4_ADDR(&ipaddr[gmac_id], - os_gmac->config.address.ip_address[0], - os_gmac->config.address.ip_address[1], - os_gmac->config.address.ip_address[2], - os_gmac->config.address.ip_address[3]); - IP4_ADDR(&netmask[gmac_id], - os_gmac->config.address.netmask_address[0], - os_gmac->config.address.netmask_address[1], - os_gmac->config.address.netmask_address[2], - os_gmac->config.address.netmask_address[3]); - IP4_ADDR(&gw[gmac_id], - os_gmac->config.address.netmask_address[0], - os_gmac->config.address.netmask_address[1], - os_gmac->config.address.netmask_address[2], - os_gmac->config.address.netmask_address[3]); -#endif - -#endif - - /* 初始化LwIP堆 */ - if(init_flag == FALSE) - { - tcpip_init(NULL, NULL); - init_flag = TRUE; - } - - /* 添加网络接口 (IPv4/IPv6) */ - -#if !LWIP_IPV6 - /* Add network interface to the netif_list, and set it as default */ - if (!lwip_port_add(&os_gmac->netif_object, &ipaddr[gmac_id], &netmask[gmac_id], &gw[gmac_id], - mac_ethernet_address[gmac_id], gmac_id)) - { - printf("Error adding N/W interface\n\r"); - return ; - } - printf("lwip_port_add is over \n\r"); -#else - - if (!lwip_port_add(&os_gmac->netif_object, NULL, NULL, NULL, mac_ethernet_address[gmac_id], gmac_id)) - { - printf("Error adding N/W interface\n\r"); - return ; - } - - os_gmac->netif_object.ip6_autoconfig_enabled = 1; - - netif_create_ip6_linklocal_address(&os_gmac->netif_object, 1); - netif_ip6_addr_set_state(&os_gmac->netif_object, 0, IP6_ADDR_VALID); - - printf("Board IPv6 address %x:%x:%x:%x:%x:%x:%x:%x\n\r", - IP6_ADDR_BLOCK1(&os_gmac->netif_object.ip6_addr[0]), - IP6_ADDR_BLOCK2(&os_gmac->netif_object.ip6_addr[0]), - IP6_ADDR_BLOCK3(&os_gmac->netif_object.ip6_addr[0]), - IP6_ADDR_BLOCK4(&os_gmac->netif_object.ip6_addr[0]), - IP6_ADDR_BLOCK5(&os_gmac->netif_object.ip6_addr[0]), - IP6_ADDR_BLOCK6(&os_gmac->netif_object.ip6_addr[0]), - IP6_ADDR_BLOCK7(&os_gmac->netif_object.ip6_addr[0]), - IP6_ADDR_BLOCK8(&os_gmac->netif_object.ip6_addr[0])); - -#endif - - - /* 注册默认网络接口 */ - netif_set_default(&os_gmac->netif_object); - - if (netif_is_link_up(&os_gmac->netif_object)) - { - /* 当netif完全配置好时,必须调用该函数 */ - netif_set_up(&os_gmac->netif_object); - } - else - { - /* 当netif链接关闭时,必须调用该函数 */ - netif_set_down(&os_gmac->netif_object); - } - -#if LWIP_DHCP && LWIP_IPV4 - /* Create a new DHCP client for this interface. - * Note: you must call dhcp_fine_tmr() and dhcp_coarse_tmr() at - * the predefined regular intervals after starting the client. - */ - printf("dhcp_start...\r\n"); - - ret = xTaskCreate((TaskFunction_t )LwipDhcpTest, /* 任务入口函数 */ - (const char* )"LwipDhcpTest",/* 任务名字 */ - (uint16_t )4096, /* 任务栈大小 */ - (void* )(os_gmac),/* 任务入口函数参数 */ - (UBaseType_t )configMAX_PRIORITIES-1, /* 任务的优先级 */ - (TaskHandle_t* )&appTaskCreateHandle); /* 任务控制 */ - if (pdPASS == ret) - { - printf("create lwip dhcp task success!\r\n"); - } - -#endif - -} - - -void LwipTestCreate(void * args) -{ - FtOsGmacConfig os_config[GMAC_INSTANCE_NUM] = - { - { - .gmac_instance = 0, - .isr_priority = 0, /* irq Priority */ - .address = - { - {192, 168, 4, 10}, - {255, 255, 255, 0}, - {192, 168, 4, 1} - }, - .mac_input_thread = - { - .thread_name = "gmac0", - .stack_depth = 4096, /* The number of words the stack */ - .priority = configMAX_PRIORITIES-1, /* Defines the priority at which the task will execute. */ - .thread_handle = NULL, - }, /* Gmac input thread */ - }, - { - .gmac_instance = 1, - .isr_priority = 0, /* irq Priority */ - .address = - { - {192, 168, 4, 20}, - {255, 255, 255, 0}, - {192, 168, 4, 1} - }, - .mac_input_thread = - { - .thread_name = "gmac1", - .stack_depth = 4096, /* The number of words the stack */ - .priority = configMAX_PRIORITIES-1, /* Defines the priority at which the task will execute. */ - .thread_handle = NULL, - }, /* Gmac input thread */ - }, - }; - - /* !!! make sure eth in-place before init gmac */ - FtOsGmacObjectInit(&os_gmac[gmac_id], &os_config[gmac_id]); - - LwipRawInit(&os_gmac[gmac_id]); - - vTaskDelete(NULL); -} - -void LwipTest(void) -{ - BaseType_t ret; - ret = xTaskCreate((TaskFunction_t)LwipTestCreate, /* 任务入口函数 */ - (const char *)"LwipTestCreate", /* 任务名字 */ - (uint16_t)2048, /* 任务栈大小 */ - (void *)NULL, /* 任务入口函数参数 */ - (UBaseType_t)configMAX_PRIORITIES-1,/* 任务的优先级 */ - NULL); /* 任务控制块指针 */ - - FASSERT_MSG(ret == pdPASS,"LwipTestCreate Task create is failed"); - -} - -static int GmacIdSet(int argc, char *argv[]) -{ - - if (!strcmp(argv[1], "probe")) - { - if (argc >= 3) - { - gmac_id = (u32)simple_strtoul(argv[2], NULL, 10); - } - else - { - gmac_id = FT_OS_GMAC0_ID; - } - LwipTest(); - } - - return 0; -} -SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), gmac, GmacIdSet, set the gmac id); -#endif \ No newline at end of file diff --git a/example/network/xmac_lwip_test/Kconfig b/example/network/lwip_startup/Kconfig similarity index 81% rename from example/network/xmac_lwip_test/Kconfig rename to example/network/lwip_startup/Kconfig index 8e44e63b..8f6fa712 100644 --- a/example/network/xmac_lwip_test/Kconfig +++ b/example/network/lwip_startup/Kconfig @@ -8,10 +8,8 @@ mainmenu "Phytium FreeRTOS Configuration" help Build Target name for the demo - if TARGET_E2000 - source "./src/Kconfig" - endif - + source "./src/Kconfig" + endmenu source "$(FREERTOS_SDK_ROOT)/Kconfig" diff --git a/example/network/xmac_lwip_test/README.md b/example/network/lwip_startup/README.md similarity index 53% rename from example/network/xmac_lwip_test/README.md rename to example/network/lwip_startup/README.md index 6de84887..934b0d4b 100644 --- a/example/network/xmac_lwip_test/README.md +++ b/example/network/lwip_startup/README.md @@ -26,13 +26,13 @@ ## 1. 例程介绍 -本例程示范了freertos环境下的lwip移植。 -本例程目前支持在freertos下,移植lwip,使网络能够ping通,shell能够正常运行。 +- 本例程示范了freertos环境下的lwip移植。 +- 并且介绍了开发者如何在我方sdk下如何正常初始化网络控制器 ## 2. 如何使用例程 本例程需要用到 -- Phytium开发板(E2000) +- Phytium开发板(E2000/D2000/FT2004) - [Phytium freeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) - [Phytium standalone SDK](https://gitee.com/phytium_embedded/phytium-standalone-sdk) ### 2.1 硬件配置方法 @@ -40,11 +40,15 @@ 本例程支持的硬件平台包括 - E2000D/Q +- FT2004 +- D2000 对应的配置项是, - CONFIG_TARGET_E2000D - CONFIG_TARGET_E2000Q +- CONFIG_TARGET_F2000_4 +- CONFIG_TARGET_D2000 ### 2.2 SDK配置方法 @@ -65,6 +69,10 @@ - make load_e2000d_aarch32 将预设32bit e2000d 下的配置加载至工程中 - make load_e2000q_aarch64 将预设64bit e2000q 下的配置加载至工程中 - make load_e2000q_aarch32 将预设32bit e2000q 下的配置加载至工程中 +- make load_d2000_aarch64 将预设64bit d2000 下的配置加载至工程中 +- make load_d2000_aarch32 将预设32bit d2000 下的配置加载至工程中 +- make load_ft2004_aarch64 将预设64bit ft2004 下的配置加载至工程中 +- make load_ft2004_aarch32 将预设32bit ft2004 下的配置加载至工程中 - make menuconfig 配置目录下的参数变量 - make backup_kconfig 将目录下的sdkconfig 备份到./configs下 @@ -119,129 +127,62 @@ bootelf -p 0x90100000 - 启动进入后,根据连接的xmac口,输入指令完成网口初始化 -#### 2.4.1 ipv4下的probe +### 2.4.1 如何配置demo 程序 -- 输入以下命令 +- 本程序默认支持ipv4,开发者使用"make menuconfig"在以下配置选项中打开 -``` -make menuconfig -``` - -- 将此项选择上 - -![ipv4_select](./pic/xmac_ipv4_menuconfig.png) - -- 输入以下命令,初始化LWIP网络协议栈, 依次配置ip地址,子网掩码,网关地址和退出时间,运行完成退出后LWIP协议栈会被暂时去使能 - -``` -xmac probe [device id] [interface id] -``` - -- 其中device id 为控制器id -- interface id ,0 为rgmii ,1 为sgmii - -![xmac_probe_ipv4](./pic/xmac_probe.png "xmac_probe.png") - -![ping](./pic/ping.png "ping.png") +![](./pic/network_demo_config.png) +- 如上图所示,开发者可以通过勾选 Enable IPv6 开启IPv6 的功能,通过勾选Enable DHCP 开启 dhcp client 功能 -#### 2.4.2 ipv6下的probe +### 2.4.2 如何进行实验 -- 先将配置恢复到初始配置状态,以E2000D 为例 +- 当开发者配置好程序之后,通过2.3.1/2.3.2的方式将编译好的镜像文件拷贝至开发板中。 +- 以E2000D/Q demo 板为例,开发者输入以下命令则可以初始化网卡: -```shell - make load_e2000d_aarch32 ``` - -- 输入以下命令 - -``` -make menuconfig +lwip probe 0 1 1 192.168.4.10 192.168.4.1 255.255.255.0 ``` -- 将此项选择上 - -![ipv6_select](./pic/xmac_ipv6_menuconfig.png) - -- 输入以下命令,初始化LWIP网络协议栈, 依次配置ip地址,子网掩码,网关地址和退出时间,运行完成退出后LWIP协议栈会被暂时去使能 - -``` -xmac probe [device id] [interface id] -``` - -- 其中device id 为控制器id -- interface id ,0 为rgmii ,1 为sgmii - -![xmac_probe](./pic/xmac_probe.png "xmac_probe.png") +- 命令定义为:"lwip probe " +- 为mac控制器 +- 为gmii 控制器类型,0 is rgmii ,1 is sgmii +- 1为使能dhcp 功能,0为关闭dhcp 功能 +- 为ipv4 地址,示例为: 192.168.4.10 +- 为网关 ,示例为: 192.168.4.1 +- 为子网掩码,示例为255.255.255.0 -![ping](./pic/ping_ipv6.png "ping_ipv6.png") +- 效果图如下 -#### 2.4.3 ipv4 dhcp +![](./pic/lwip_probe.png) -- 先将配置恢复到初始配置状态,以E2000D 为例 -```shell - make load_e2000d_aarch32 -``` - -- 输入以下命令 - -``` -make menuconfig -``` +### 2.4.3 ipv4 实验效果 -- 将此项选择上 +- 在ipv4 工作模式下,可以使用ping 的方式测试当前程序是否正常工作,如下图所示: + +![](./pic/ipv4_test.png) -![dhcp_select](./pic/xmac_dhcp_menuconfig.png) +### 2.4.4 ipv6 实验效果 -- 输入以下命令,初始化LWIP网络协议栈, 并且会默认打开dhcp 线程 +- 在ipv6 工作模式下,可以使用ping 的方式测试当前程序是否正常工作,如下图所示: + +![](./pic/ipv6_test.png) -``` -xmac probe [device id] [interface id] -``` -- 其中device id 为控制器id -- interface id ,0 为rgmii ,1 为sgmii +### 2.4.4 dhcp 实验效果 -![xmac_probe_dhcp0](./pic/xmac_probe.png "xmac_probe.png") +- 打开dhcp功能之后,如下图所示: + +![](./pic/dhcp_test.png) -![xmac_probe_dhcp1](./pic/xmac_probe_dhcp1.png "xmac_probe_dhcp1.png") #### 2.4.2 提供 ## 3. 如何解决问题 -Q: 程序运行过程中queue.c的debug信息报错 - -A: 考虑自身任务创建时分配的栈空间大小,考虑tcpip_thread任务的栈空间大小TCPIP_THREAD_STACKSIZE - -Q: 程序运行过程中ping大包异常 - -A: 考虑以下两个宏的大小:PBUF_POOL_SIZE定义缓冲池的个数,PBUF_POOL_BUFSIZE定义单个缓冲区的大小 - -Q: 如何选择demo板的配置 - -A: 开发者在编译终端下使用以下命令 -```shell - make menuconfig -``` - -![](./pic/select_demo.png) - - -Q: 如果开发者使用E2000 demo板应该如何进行实验: - -A: 开发者在串口终端上输入以下命令对控制器进行初始化 - -![](./pic/e2000demo板全貌.jpg) - - -```shell - xmac probe 0 1 -``` - ## 4. 修改历史记录 v0.2.0 重构lwip diff --git a/example/network/lwip_startup/configs/d2000_aarch32_eg_configs b/example/network/lwip_startup/configs/d2000_aarch32_eg_configs new file mode 100644 index 00000000..807857de --- /dev/null +++ b/example/network/lwip_startup/configs/d2000_aarch32_eg_configs @@ -0,0 +1,505 @@ + +# +# Project Configuration +# +CONFIG_TARGET_NAME="d2000_freertos_a32" + +# +# Lwip startup test configuration +# +CONFIG_LWIP_IPV6_TEST=y +CONFIG_LWIP_DHCP_TEST=y +# end of Lwip startup test configuration +# end of Project Configuration + +# +# Standalone Setting +# +CONFIG_USE_FREERTOS=y + +# +# Arch Configuration +# +CONFIG_TARGET_ARMV8_AARCH32=y +# CONFIG_TARGET_ARMV8_AARCH64 is not set +CONFIG_USE_CACHE=y +# CONFIG_USE_L3CACHE is not set +CONFIG_USE_MMU=y +CONFIG_USE_SYS_TICK=y +CONFIG_USE_AARCH64_L1_TO_AARCH32=y +# end of Arch Configuration + +# +# Board Configuration +# +# CONFIG_TARGET_F2000_4 is not set +CONFIG_TARGET_D2000=y +# CONFIG_TARGET_E2000Q is not set +# CONFIG_TARGET_E2000D is not set +# CONFIG_TARGET_E2000S is not set +CONFIG_DEFAULT_DEBUG_PRINT_UART1=y +# CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set +# CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set +# end of Board Configuration + +# +# Components Configuration +# +# CONFIG_USE_SPI is not set +# CONFIG_USE_QSPI is not set +CONFIG_USE_GIC=y +CONFIG_ENABLE_GICV3=y +CONFIG_USE_SERIAL=y + +# +# Usart Configuration +# +CONFIG_ENABLE_Pl011_UART=y +# end of Usart Configuration + +# CONFIG_USE_GPIO is not set +CONFIG_USE_ETH=y + +# +# Eth Configuration +# +# CONFIG_ENABLE_FXMAC is not set +CONFIG_ENABLE_FGMAC=y +CONFIG_FGMAC_PHY_COMMON=y +# CONFIG_FGMAC_PHY_AR803X is not set +# end of Eth Configuration + +# CONFIG_USE_CAN is not set +# CONFIG_USE_I2C is not set +# CONFIG_USE_TIMER is not set +# CONFIG_USE_MIO is not set +# CONFIG_USE_SDMMC is not set +# CONFIG_USE_PCIE is not set +# CONFIG_USE_WDT is not set +# CONFIG_USE_DMA is not set +# CONFIG_USE_NAND is not set +# CONFIG_USE_RTC is not set +# CONFIG_USE_SATA is not set +# CONFIG_USE_USB is not set +# CONFIG_USE_ADC is not set +# CONFIG_USE_PWM is not set +# CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set +# end of Components Configuration + +CONFIG_USE_NEW_LIBC=y +# end of Standalone Setting + +# +# Building Option +# +# CONFIG_LOG_VERBOS is not set +# CONFIG_LOG_DEBUG is not set +# CONFIG_LOG_INFO is not set +# CONFIG_LOG_WARN is not set +CONFIG_LOG_ERROR=y +# CONFIG_LOG_NONE is not set +CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y +CONFIG_INTERRUPT_ROLE_MASTER=y +# CONFIG_INTERRUPT_ROLE_SLAVE is not set +# CONFIG_LOG_EXTRA_INFO is not set +# CONFIG_BOOTUP_DEBUG_PRINTS is not set + +# +# Linker Options +# +CONFIG_AARCH32_RAM_LD=y +# CONFIG_AARCH64_RAM_LD is not set +# CONFIG_USER_DEFINED_LD is not set +CONFIG_LINK_SCRIPT_ROM=y +CONFIG_ROM_START_UP_ADDR=0x80100000 +CONFIG_ROM_SIZE_MB=1 +CONFIG_LINK_SCRIPT_RAM=y +CONFIG_RAM_START_UP_ADDR=0x80500000 +CONFIG_RAM_SIZE_MB=64 +CONFIG_HEAP_SIZE=1 +CONFIG_SVC_STACK_SIZE=0x1000 +CONFIG_SYS_STACK_SIZE=0x1000 +CONFIG_IRQ_STACK_SIZE=0x1000 +CONFIG_ABORT_STACK_SIZE=0x1000 +CONFIG_FIQ_STACK_SIZE=0x1000 +CONFIG_UNDEF_STACK_SIZE=0x1000 +# end of Linker Options + +# +# Compiler Options +# + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + +CONFIG_OUTPUT_BINARY=y +# end of Compiler Options +# end of Building Option + +# +# Component Configuration +# + +# +# Freertos Uart Drivers +# +CONFIG_FREERTOS_USE_UART=y +# end of Freertos Uart Drivers + +# +# Freertos Pwm Drivers +# +# CONFIG_FREERTOS_USE_PWM is not set +# end of Freertos Pwm Drivers + +# +# Freertos Qspi Drivers +# +# CONFIG_FREERTOS_USE_QSPI is not set +# end of Freertos Qspi Drivers + +# +# Freertos Wdt Drivers +# +# CONFIG_FREERTOS_USE_WDT is not set +# end of Freertos Wdt Drivers + +# +# Freertos Eth Drivers +# +# CONFIG_FREERTOS_USE_XMAC is not set +CONFIG_FREERTOS_USE_GMAC=y +# end of Freertos Eth Drivers + +# +# Freertos Gpio Drivers +# +# CONFIG_FREERTOS_USE_GPIO is not set +# end of Freertos Gpio Drivers + +# +# Freertos Spim Drivers +# +# CONFIG_FREERTOS_USE_FSPIM is not set +# end of Freertos Spim Drivers + +# +# Freertos DMA Drivers +# +# CONFIG_FREERTOS_USE_FDDMA is not set +# CONFIG_FREERTOS_USE_FGDMA is not set +# end of Freertos DMA Drivers + +# +# Freertos Adc Drivers +# +# CONFIG_FREERTOS_USE_ADC is not set +# end of Freertos Adc Drivers + +# +# Freertos Can Drivers +# +# CONFIG_FREERTOS_USE_CAN is not set +# end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers +# end of Component Configuration + +# +# Third-Party Configuration +# +CONFIG_USE_LWIP=y + +# +# LWIP Freertos Port Configuration +# +# CONFIG_LWIP_FXMAC is not set +CONFIG_LWIP_FGMAC=y + +# +# LWIP Configuration +# + +# +# LWIP Port Configuration +# +# CONFIG_LWIP_PORT_DEBUG_EN is not set +# end of LWIP Port Configuration + +# CONFIG_LWIP_NO_SYS is not set +CONFIG_LWIP_LOCAL_HOSTNAME="phytium" + +# +# Memory configuration +# +# CONFIG_LWIP_USE_MEM_POOL is not set +CONFIG_LWIP_USE_MEM_HEAP=y +CONFIG_MEM_SIZE=2 +CONFIG_MEM_ALIGNMENT=64 +# end of Memory configuration + +# +# Pbuf options +# +CONFIG_PBUF_POOL_BUFSIZE=2 +CONFIG_PBUF_POOL_SIZE=1 +# end of Pbuf options + +# +# ARP +# +CONFIG_ARP_QUEUEING_EN=y +# end of ARP + +# +# IPV4 +# +# CONFIG_USE_IPV4_ONLY is not set +CONFIG_LWIP_IP4_REASSEMBLY=y +CONFIG_LWIP_IP4_FRAG=y +# CONFIG_LWIP_IP_FORWARD is not set +CONFIG_IP_REASS_MAX_PBUFS=16 +# end of IPV4 + +# +# ICMP +# +CONFIG_LWIP_ICMP=y +CONFIG_LWIP_MULTICAST_PING=y +CONFIG_LWIP_BROADCAST_PING=y +# end of ICMP + +# +# LWIP RAW API +# +CONFIG_LWIP_RAW_API_EN=y +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + +# +# DHCP +# +CONFIG_LWIP_DHCP_ENABLE=y +# CONFIG_LWIP_DHCP_DOES_ARP_CHECK is not set +# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set +# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set +# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set +CONFIG_LWIP_DHCP_OPTIONS_LEN=68 +CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y +# end of DHCP + +# +# AUTOIP +# +# CONFIG_LWIP_AUTOIP is not set +# end of AUTOIP + +# +# IGMP +# +CONFIG_LWIP_IGMP_EN=y +# end of IGMP + +# +# DNS +# +CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y +# end of DNS + +# +# UDP +# +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# CONFIG_LWIP_NETBUF_RECVINFO is not set +# end of UDP + +# +# TCP +# +CONFIG_LWIP_TCP_WND_DEFAULT=5744 +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +# CONFIG_LWIP_TCP_SACK_OUT is not set +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 +CONFIG_LWIP_TCP_RTO_TIME=1500 +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +# end of TCP + +# +# Network_Interface +# +# CONFIG_LWIP_NETIF_API is not set +# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set +# end of Network_Interface + +# +# LOOPIF +# +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 +# end of LOOPIF + +# +# SLIPIF +# +# CONFIG_LWIP_SLIP_SUPPORT is not set +# end of SLIPIF + +CONFIG_LWIP_TCPIP_CORE_LOCKING=y + +# +# Socket +# +CONFIG_LWIP_MAX_SOCKETS=10 +# CONFIG_LWIP_SO_LINGER is not set +CONFIG_LWIP_SO_REUSE=y +CONFIG_LWIP_SO_REUSE_RXTOALL=y +# end of Socket + +# CONFIG_LWIP_STATS is not set + +# +# PPP +# +# CONFIG_LWIP_PPP_SUPPORT is not set +CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 +CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 +# end of PPP + +# +# Checksums +# +# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set +# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set +CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y +# end of Checksums + +# +# IPV6 +# +CONFIG_LWIP_IPV6=y +# CONFIG_LWIP_IPV6_AUTOCONFIG is not set +CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 +# CONFIG_LWIP_IPV6_FORWARD is not set +CONFIG_LWIP_IP6_FRAG=y +# CONFIG_LWIP_IP6_REASSEMBLY is not set +# end of IPV6 + +CONFIG_LWIP_DEBUG=y +# CONFIG_LWIP_DEBUG_ESP_LOG is not set +CONFIG_LWIP_NETIF_DEBUG=y +# CONFIG_LWIP_PBUF_DEBUG is not set +# CONFIG_LWIP_ETHARP_DEBUG is not set +# CONFIG_LWIP_API_LIB_DEBUG is not set +# CONFIG_LWIP_SOCKETS_DEBUG is not set +# CONFIG_LWIP_IP_DEBUG is not set +# CONFIG_LWIP_ICMP_DEBUG is not set +# CONFIG_LWIP_DHCP_STATE_DEBUG is not set +# CONFIG_LWIP_DHCP_DEBUG is not set +# CONFIG_LWIP_IP6_DEBUG is not set +# CONFIG_LWIP_ICMP6_DEBUG is not set +# CONFIG_LWIP_TCP_DEBUG is not set +# CONFIG_LWIP_UDP_DEBUG is not set +# CONFIG_LWIP_SNTP_DEBUG is not set +# CONFIG_LWIP_DNS_DEBUG is not set +# end of LWIP Configuration + +# +# Tcp/ip task resource configuration +# +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_PRIO=6 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +# end of Tcp/ip task resource configuration + +# +# lwip port thread Configuration +# +CONFIG_LWIP_PORT_USE_RECEIVE_THREAD=y +CONFIG_LWIP_PORT_RECEIVE_THREAD_STACKSIZE=1024 +CONFIG_LWIP_PORT_RECEIVE_THREAD_PRIORITY=5 +CONFIG_LWIP_PORT_USE_LINK_DETECT_THREAD=y +CONFIG_LWIP_PORT_LINK_DETECT_STACKSIZE=1024 +CONFIG_LWIP_PORT_LINK_DETECT_PRIORITY=5 +CONFIG_LWIP_PORT_DHCP_THREAD=y +CONFIG_LWIP_PORT_DHCP_STACKSIZE=2048 +CONFIG_LWIP_PORT_DHCP_PRIORITY=5 +# end of lwip port thread Configuration +# end of LWIP Freertos Port Configuration + +CONFIG_USE_BACKTRACE=y +# CONFIG_USE_FATFS_0_1_4 is not set +# CONFIG_USE_SFUD is not set +# CONFIG_USE_SPIFFS is not set +# CONFIG_USE_AMP is not set +CONFIG_USE_LETTER_SHELL=y + +# +# Letter Shell Configuration +# +CONFIG_LS_PL011_UART=y +CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y +# CONFIG_DEFAULT_LETTER_SHELL_USE_UART0 is not set +# CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set +# end of Letter Shell Configuration + +CONFIG_USE_TLSF=y +# CONFIG_USE_SDMMC_CMD is not set +# CONFIG_USE_CHERRY_USB is not set +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/network/lwip_startup/configs/d2000_aarch64_eg_configs b/example/network/lwip_startup/configs/d2000_aarch64_eg_configs new file mode 100644 index 00000000..7cc036af --- /dev/null +++ b/example/network/lwip_startup/configs/d2000_aarch64_eg_configs @@ -0,0 +1,501 @@ + +# +# Project Configuration +# +CONFIG_TARGET_NAME="d2000_freertos_a64" + +# +# Lwip startup test configuration +# +CONFIG_LWIP_IPV6_TEST=y +CONFIG_LWIP_DHCP_TEST=y +# end of Lwip startup test configuration +# end of Project Configuration + +# +# Standalone Setting +# +CONFIG_USE_FREERTOS=y + +# +# Arch Configuration +# +# CONFIG_TARGET_ARMV8_AARCH32 is not set +CONFIG_TARGET_ARMV8_AARCH64=y +CONFIG_USE_CACHE=y +# CONFIG_USE_L3CACHE is not set +CONFIG_USE_MMU=y +CONFIG_USE_SYS_TICK=y +# CONFIG_MMU_DEBUG_PRINTS is not set +# end of Arch Configuration + +# +# Board Configuration +# +# CONFIG_TARGET_F2000_4 is not set +CONFIG_TARGET_D2000=y +# CONFIG_TARGET_E2000Q is not set +# CONFIG_TARGET_E2000D is not set +# CONFIG_TARGET_E2000S is not set +CONFIG_DEFAULT_DEBUG_PRINT_UART1=y +# CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set +# CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set +# end of Board Configuration + +# +# Components Configuration +# +# CONFIG_USE_SPI is not set +# CONFIG_USE_QSPI is not set +CONFIG_USE_GIC=y +CONFIG_ENABLE_GICV3=y +CONFIG_USE_SERIAL=y + +# +# Usart Configuration +# +CONFIG_ENABLE_Pl011_UART=y +# end of Usart Configuration + +# CONFIG_USE_GPIO is not set +CONFIG_USE_ETH=y + +# +# Eth Configuration +# +# CONFIG_ENABLE_FXMAC is not set +CONFIG_ENABLE_FGMAC=y +CONFIG_FGMAC_PHY_COMMON=y +# CONFIG_FGMAC_PHY_AR803X is not set +# end of Eth Configuration + +# CONFIG_USE_CAN is not set +# CONFIG_USE_I2C is not set +# CONFIG_USE_TIMER is not set +# CONFIG_USE_MIO is not set +# CONFIG_USE_SDMMC is not set +# CONFIG_USE_PCIE is not set +# CONFIG_USE_WDT is not set +# CONFIG_USE_DMA is not set +# CONFIG_USE_NAND is not set +# CONFIG_USE_RTC is not set +# CONFIG_USE_SATA is not set +# CONFIG_USE_USB is not set +# CONFIG_USE_ADC is not set +# CONFIG_USE_PWM is not set +# CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set +# end of Components Configuration + +CONFIG_USE_NEW_LIBC=y +# end of Standalone Setting + +# +# Building Option +# +# CONFIG_LOG_VERBOS is not set +# CONFIG_LOG_DEBUG is not set +# CONFIG_LOG_INFO is not set +# CONFIG_LOG_WARN is not set +CONFIG_LOG_ERROR=y +# CONFIG_LOG_NONE is not set +CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y +CONFIG_INTERRUPT_ROLE_MASTER=y +# CONFIG_INTERRUPT_ROLE_SLAVE is not set +# CONFIG_LOG_EXTRA_INFO is not set +# CONFIG_BOOTUP_DEBUG_PRINTS is not set + +# +# Linker Options +# +# CONFIG_AARCH32_RAM_LD is not set +CONFIG_AARCH64_RAM_LD=y +# CONFIG_USER_DEFINED_LD is not set +CONFIG_LINK_SCRIPT_ROM=y +CONFIG_ROM_START_UP_ADDR=0x80100000 +CONFIG_ROM_SIZE_MB=1 +CONFIG_LINK_SCRIPT_RAM=y +CONFIG_RAM_START_UP_ADDR=0x80500000 +CONFIG_RAM_SIZE_MB=64 +CONFIG_HEAP_SIZE=1 +CONFIG_STACK_SIZE=0x100000 +CONFIG_FPU_STACK_SIZE=0x1000 +# end of Linker Options + +# +# Compiler Options +# + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + +CONFIG_OUTPUT_BINARY=y +# end of Compiler Options +# end of Building Option + +# +# Component Configuration +# + +# +# Freertos Uart Drivers +# +CONFIG_FREERTOS_USE_UART=y +# end of Freertos Uart Drivers + +# +# Freertos Pwm Drivers +# +# CONFIG_FREERTOS_USE_PWM is not set +# end of Freertos Pwm Drivers + +# +# Freertos Qspi Drivers +# +# CONFIG_FREERTOS_USE_QSPI is not set +# end of Freertos Qspi Drivers + +# +# Freertos Wdt Drivers +# +# CONFIG_FREERTOS_USE_WDT is not set +# end of Freertos Wdt Drivers + +# +# Freertos Eth Drivers +# +# CONFIG_FREERTOS_USE_XMAC is not set +CONFIG_FREERTOS_USE_GMAC=y +# end of Freertos Eth Drivers + +# +# Freertos Gpio Drivers +# +# CONFIG_FREERTOS_USE_GPIO is not set +# end of Freertos Gpio Drivers + +# +# Freertos Spim Drivers +# +# CONFIG_FREERTOS_USE_FSPIM is not set +# end of Freertos Spim Drivers + +# +# Freertos DMA Drivers +# +# CONFIG_FREERTOS_USE_FDDMA is not set +# CONFIG_FREERTOS_USE_FGDMA is not set +# end of Freertos DMA Drivers + +# +# Freertos Adc Drivers +# +# CONFIG_FREERTOS_USE_ADC is not set +# end of Freertos Adc Drivers + +# +# Freertos Can Drivers +# +# CONFIG_FREERTOS_USE_CAN is not set +# end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers +# end of Component Configuration + +# +# Third-Party Configuration +# +CONFIG_USE_LWIP=y + +# +# LWIP Freertos Port Configuration +# +# CONFIG_LWIP_FXMAC is not set +CONFIG_LWIP_FGMAC=y + +# +# LWIP Configuration +# + +# +# LWIP Port Configuration +# +# CONFIG_LWIP_PORT_DEBUG_EN is not set +# end of LWIP Port Configuration + +# CONFIG_LWIP_NO_SYS is not set +CONFIG_LWIP_LOCAL_HOSTNAME="phytium" + +# +# Memory configuration +# +# CONFIG_LWIP_USE_MEM_POOL is not set +CONFIG_LWIP_USE_MEM_HEAP=y +CONFIG_MEM_SIZE=2 +CONFIG_MEM_ALIGNMENT=64 +# end of Memory configuration + +# +# Pbuf options +# +CONFIG_PBUF_POOL_BUFSIZE=2 +CONFIG_PBUF_POOL_SIZE=1 +# end of Pbuf options + +# +# ARP +# +CONFIG_ARP_QUEUEING_EN=y +# end of ARP + +# +# IPV4 +# +# CONFIG_USE_IPV4_ONLY is not set +CONFIG_LWIP_IP4_REASSEMBLY=y +CONFIG_LWIP_IP4_FRAG=y +# CONFIG_LWIP_IP_FORWARD is not set +CONFIG_IP_REASS_MAX_PBUFS=16 +# end of IPV4 + +# +# ICMP +# +CONFIG_LWIP_ICMP=y +CONFIG_LWIP_MULTICAST_PING=y +CONFIG_LWIP_BROADCAST_PING=y +# end of ICMP + +# +# LWIP RAW API +# +CONFIG_LWIP_RAW_API_EN=y +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + +# +# DHCP +# +CONFIG_LWIP_DHCP_ENABLE=y +# CONFIG_LWIP_DHCP_DOES_ARP_CHECK is not set +# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set +# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set +# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set +CONFIG_LWIP_DHCP_OPTIONS_LEN=68 +CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y +# end of DHCP + +# +# AUTOIP +# +# CONFIG_LWIP_AUTOIP is not set +# end of AUTOIP + +# +# IGMP +# +CONFIG_LWIP_IGMP_EN=y +# end of IGMP + +# +# DNS +# +CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y +# end of DNS + +# +# UDP +# +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# CONFIG_LWIP_NETBUF_RECVINFO is not set +# end of UDP + +# +# TCP +# +CONFIG_LWIP_TCP_WND_DEFAULT=5744 +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +# CONFIG_LWIP_TCP_SACK_OUT is not set +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 +CONFIG_LWIP_TCP_RTO_TIME=1500 +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +# end of TCP + +# +# Network_Interface +# +# CONFIG_LWIP_NETIF_API is not set +# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set +# end of Network_Interface + +# +# LOOPIF +# +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 +# end of LOOPIF + +# +# SLIPIF +# +# CONFIG_LWIP_SLIP_SUPPORT is not set +# end of SLIPIF + +CONFIG_LWIP_TCPIP_CORE_LOCKING=y + +# +# Socket +# +CONFIG_LWIP_MAX_SOCKETS=10 +# CONFIG_LWIP_SO_LINGER is not set +CONFIG_LWIP_SO_REUSE=y +CONFIG_LWIP_SO_REUSE_RXTOALL=y +# end of Socket + +# CONFIG_LWIP_STATS is not set + +# +# PPP +# +# CONFIG_LWIP_PPP_SUPPORT is not set +CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 +CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 +# end of PPP + +# +# Checksums +# +# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set +# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set +CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y +# end of Checksums + +# +# IPV6 +# +CONFIG_LWIP_IPV6=y +# CONFIG_LWIP_IPV6_AUTOCONFIG is not set +CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 +# CONFIG_LWIP_IPV6_FORWARD is not set +CONFIG_LWIP_IP6_FRAG=y +# CONFIG_LWIP_IP6_REASSEMBLY is not set +# end of IPV6 + +CONFIG_LWIP_DEBUG=y +# CONFIG_LWIP_DEBUG_ESP_LOG is not set +CONFIG_LWIP_NETIF_DEBUG=y +# CONFIG_LWIP_PBUF_DEBUG is not set +# CONFIG_LWIP_ETHARP_DEBUG is not set +# CONFIG_LWIP_API_LIB_DEBUG is not set +# CONFIG_LWIP_SOCKETS_DEBUG is not set +# CONFIG_LWIP_IP_DEBUG is not set +# CONFIG_LWIP_ICMP_DEBUG is not set +# CONFIG_LWIP_DHCP_STATE_DEBUG is not set +# CONFIG_LWIP_DHCP_DEBUG is not set +# CONFIG_LWIP_IP6_DEBUG is not set +# CONFIG_LWIP_ICMP6_DEBUG is not set +# CONFIG_LWIP_TCP_DEBUG is not set +# CONFIG_LWIP_UDP_DEBUG is not set +# CONFIG_LWIP_SNTP_DEBUG is not set +# CONFIG_LWIP_DNS_DEBUG is not set +# end of LWIP Configuration + +# +# Tcp/ip task resource configuration +# +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_PRIO=6 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +# end of Tcp/ip task resource configuration + +# +# lwip port thread Configuration +# +CONFIG_LWIP_PORT_USE_RECEIVE_THREAD=y +CONFIG_LWIP_PORT_RECEIVE_THREAD_STACKSIZE=1024 +CONFIG_LWIP_PORT_RECEIVE_THREAD_PRIORITY=5 +CONFIG_LWIP_PORT_USE_LINK_DETECT_THREAD=y +CONFIG_LWIP_PORT_LINK_DETECT_STACKSIZE=1024 +CONFIG_LWIP_PORT_LINK_DETECT_PRIORITY=5 +CONFIG_LWIP_PORT_DHCP_THREAD=y +CONFIG_LWIP_PORT_DHCP_STACKSIZE=2048 +CONFIG_LWIP_PORT_DHCP_PRIORITY=5 +# end of lwip port thread Configuration +# end of LWIP Freertos Port Configuration + +CONFIG_USE_BACKTRACE=y +# CONFIG_USE_FATFS_0_1_4 is not set +# CONFIG_USE_SFUD is not set +# CONFIG_USE_SPIFFS is not set +# CONFIG_USE_AMP is not set +CONFIG_USE_LETTER_SHELL=y + +# +# Letter Shell Configuration +# +CONFIG_LS_PL011_UART=y +CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y +# CONFIG_DEFAULT_LETTER_SHELL_USE_UART0 is not set +# CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set +# end of Letter Shell Configuration + +CONFIG_USE_TLSF=y +# CONFIG_USE_SDMMC_CMD is not set +# CONFIG_USE_CHERRY_USB is not set +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/network/xmac_lwip_test/configs/e2000d_aarch32_eg_configs b/example/network/lwip_startup/configs/e2000d_aarch32_eg_configs similarity index 71% rename from example/network/xmac_lwip_test/configs/e2000d_aarch32_eg_configs rename to example/network/lwip_startup/configs/e2000d_aarch32_eg_configs index c11555f1..c49acffb 100644 --- a/example/network/xmac_lwip_test/configs/e2000d_aarch32_eg_configs +++ b/example/network/lwip_startup/configs/e2000d_aarch32_eg_configs @@ -2,19 +2,18 @@ # # Project Configuration # -CONFIG_TARGET_NAME="e2000d_lwip_echo" +CONFIG_TARGET_NAME="e2000d_freertos_a32" # -# E2000 board Configuration +# Lwip startup test configuration # -CONFIG_LWIP_IPV4_TEST=y -# CONFIG_LWIP_IPV4_DHCP_TEST is not set # CONFIG_LWIP_IPV6_TEST is not set +# CONFIG_LWIP_DHCP_TEST is not set # CONFIG_BOARD_TYPE_B is not set # CONFIG_BOARD_TYPE_C is not set # CONFIG_BOARD_TYPE_A is not set CONFIG_BOARD_TYPE_DEMO=y -# end of E2000 board Configuration +# end of Lwip startup test configuration # end of Project Configuration # @@ -89,6 +88,7 @@ CONFIG_FXMAC_PHY_COMMON=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -98,9 +98,9 @@ CONFIG_USE_NEW_LIBC=y # Building Option # # CONFIG_LOG_VERBOS is not set -# CONFIG_LOG_DEBUG is not set +CONFIG_LOG_DEBUG=y # CONFIG_LOG_INFO is not set -CONFIG_LOG_WARN=y +# CONFIG_LOG_WARN is not set # CONFIG_LOG_ERROR is not set # CONFIG_LOG_NONE is not set CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y @@ -133,6 +133,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -169,6 +178,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # CONFIG_FREERTOS_USE_XMAC=y +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -190,12 +200,6 @@ CONFIG_FREERTOS_USE_XMAC=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -207,113 +211,81 @@ CONFIG_FREERTOS_USE_XMAC=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers -# end of Component Configuration # -# FreeRTOS Setting +# Freertos I2c Drivers # -CONFIG_USE_LWIP=y +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers # -# LWIP Configuration +# Freertos Mio Drivers # +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers # -# LWIP Port Configuration -# -# CONFIG_LWIP_FGMAC is not set -CONFIG_LWIP_FXMAC=y -# end of LWIP Port Configuration - -CONFIG_LWIP_LOCAL_HOSTNAME="phytium" - +# Freertos Timer Drivers # -# memory configuration -# -# CONFIG_LWIP_USE_MEM_POOL is not set -CONFIG_LWIP_USE_MEM_HEAP=y -CONFIG_MEM_SIZE=1 -CONFIG_MEM_ALIGNMENT=64 -# end of memory configuration - -# -# NETWORK_INTERFACE_OPTIONS -# -# CONFIG_LWIP_NETIF_API is not set -# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set -# end of NETWORK_INTERFACE_OPTIONS +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers +# end of Component Configuration # -# LOOPIF +# Third-Party Configuration # -CONFIG_LWIP_NETIF_LOOPBACK=y -CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 -# end of LOOPIF +CONFIG_USE_LWIP=y # -# SLIPIF +# LWIP Freertos Port Configuration # -# CONFIG_LWIP_SLIP_SUPPORT is not set -# end of SLIPIF +CONFIG_LWIP_FXMAC=y +# CONFIG_LWIP_FGMAC is not set # -# Pbuf options +# LWIP Configuration # -CONFIG_PBUF_POOL_BUFSIZE=2 -# end of Pbuf options # -# Internal Memory Pool Sizes +# LWIP Port Configuration # -CONFIG_PBUF_POOL_SIZE=1 -# end of Internal Memory Pool Sizes +# CONFIG_LWIP_PORT_DEBUG_EN is not set +# end of LWIP Port Configuration -CONFIG_LWIP_MAX_SOCKETS=10 +# CONFIG_LWIP_NO_SYS is not set +CONFIG_LWIP_LOCAL_HOSTNAME="phytium" # -# LWIP RAW API +# Memory configuration # -CONFIG_LWIP_MAX_RAW_PCBS=16 -# end of LWIP RAW API +# CONFIG_LWIP_USE_MEM_POOL is not set +CONFIG_LWIP_USE_MEM_HEAP=y +CONFIG_MEM_SIZE=2 +CONFIG_MEM_ALIGNMENT=64 +# end of Memory configuration # -# TCP +# Pbuf options # -CONFIG_LWIP_MAX_ACTIVE_TCP=16 -CONFIG_LWIP_MAX_LISTENING_TCP=16 -CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y -CONFIG_LWIP_TCP_MAXRTX=12 -CONFIG_LWIP_TCP_SYNMAXRTX=12 -CONFIG_LWIP_TCP_MSS=1440 -CONFIG_LWIP_TCP_TMR_INTERVAL=250 -CONFIG_LWIP_TCP_MSL=60000 -CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 -CONFIG_LWIP_TCP_WND_DEFAULT=5744 -CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 -CONFIG_LWIP_TCP_QUEUE_OOSEQ=y -# CONFIG_LWIP_TCP_SACK_OUT is not set -CONFIG_LWIP_TCP_OVERSIZE_MSS=y -# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set -# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set -# end of TCP +CONFIG_PBUF_POOL_BUFSIZE=2 +CONFIG_PBUF_POOL_SIZE=1 +# end of Pbuf options # -# UDP +# ARP # -CONFIG_LWIP_MAX_UDP_PCBS=16 -CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 -# CONFIG_LWIP_NETBUF_RECVINFO is not set -# end of UDP +CONFIG_ARP_QUEUEING_EN=y +# end of ARP # -# IPv4 +# IPV4 # -CONFIG_USE_IPV4_ONLY=y +# CONFIG_USE_IPV4_ONLY is not set CONFIG_LWIP_IP4_REASSEMBLY=y CONFIG_LWIP_IP4_FRAG=y # CONFIG_LWIP_IP_FORWARD is not set CONFIG_IP_REASS_MAX_PBUFS=16 -# end of IPv4 +# end of IPV4 # # ICMP @@ -323,16 +295,17 @@ CONFIG_LWIP_MULTICAST_PING=y CONFIG_LWIP_BROADCAST_PING=y # end of ICMP +# +# LWIP RAW API +# +CONFIG_LWIP_RAW_API_EN=y +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + # # DHCP # # CONFIG_LWIP_DHCP_ENABLE is not set -# CONFIG_LWIP_DHCP_DOES_ARP_CHECK is not set -# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set -# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set -# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set -CONFIG_LWIP_DHCP_OPTIONS_LEN=68 -CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y # end of DHCP # @@ -341,6 +314,12 @@ CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y # CONFIG_LWIP_AUTOIP is not set # end of AUTOIP +# +# IGMP +# +CONFIG_LWIP_IGMP_EN=y +# end of IGMP + # # DNS # @@ -348,20 +327,65 @@ CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y # end of DNS # -# TCP options +# UDP # +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# CONFIG_LWIP_NETBUF_RECVINFO is not set +# end of UDP + +# +# TCP +# +CONFIG_LWIP_TCP_WND_DEFAULT=5744 +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +# CONFIG_LWIP_TCP_SACK_OUT is not set +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 CONFIG_LWIP_TCP_RTO_TIME=1500 -# end of TCP options +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +# end of TCP + +# +# Network_Interface +# +# CONFIG_LWIP_NETIF_API is not set +# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set +# end of Network_Interface + +# +# LOOPIF +# +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 +# end of LOOPIF + +# +# SLIPIF +# +# CONFIG_LWIP_SLIP_SUPPORT is not set +# end of SLIPIF CONFIG_LWIP_TCPIP_CORE_LOCKING=y # -# socket +# Socket # +CONFIG_LWIP_MAX_SOCKETS=10 # CONFIG_LWIP_SO_LINGER is not set CONFIG_LWIP_SO_REUSE=y CONFIG_LWIP_SO_REUSE_RXTOALL=y -# end of socket +# end of Socket # CONFIG_LWIP_STATS is not set @@ -369,8 +393,6 @@ CONFIG_LWIP_SO_REUSE_RXTOALL=y # PPP # # CONFIG_LWIP_PPP_SUPPORT is not set -CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 -CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 # end of PPP # @@ -382,17 +404,13 @@ CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y # end of Checksums # -# ipv6 +# IPV6 # -CONFIG_LWIP_IPV6=y -# CONFIG_LWIP_IPV6_AUTOCONFIG is not set -CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 -# CONFIG_LWIP_IPV6_FORWARD is not set -CONFIG_LWIP_IP6_FRAG=y -# CONFIG_LWIP_IP6_REASSEMBLY is not set -# end of ipv6 +# CONFIG_LWIP_IPV6 is not set +# end of IPV6 CONFIG_LWIP_DEBUG=y +# CONFIG_LWIP_DEBUG_ESP_LOG is not set CONFIG_LWIP_NETIF_DEBUG=y # CONFIG_LWIP_PBUF_DEBUG is not set # CONFIG_LWIP_ETHARP_DEBUG is not set @@ -400,16 +418,41 @@ CONFIG_LWIP_NETIF_DEBUG=y # CONFIG_LWIP_SOCKETS_DEBUG is not set # CONFIG_LWIP_IP_DEBUG is not set # CONFIG_LWIP_ICMP_DEBUG is not set +# CONFIG_LWIP_DHCP_STATE_DEBUG is not set # CONFIG_LWIP_DHCP_DEBUG is not set # CONFIG_LWIP_IP6_DEBUG is not set # CONFIG_LWIP_ICMP6_DEBUG is not set # CONFIG_LWIP_TCP_DEBUG is not set +# CONFIG_LWIP_UDP_DEBUG is not set # CONFIG_LWIP_SNTP_DEBUG is not set # CONFIG_LWIP_DNS_DEBUG is not set # end of LWIP Configuration +# +# Tcp/ip task resource configuration +# +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_PRIO=6 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +# end of Tcp/ip task resource configuration + +# +# lwip port thread Configuration +# +CONFIG_LWIP_PORT_USE_RECEIVE_THREAD=y +CONFIG_LWIP_PORT_RECEIVE_THREAD_STACKSIZE=1024 +CONFIG_LWIP_PORT_RECEIVE_THREAD_PRIORITY=5 +CONFIG_LWIP_PORT_USE_LINK_DETECT_THREAD=y +CONFIG_LWIP_PORT_LINK_DETECT_STACKSIZE=1024 +CONFIG_LWIP_PORT_LINK_DETECT_PRIORITY=5 +CONFIG_LWIP_PORT_DHCP_THREAD=y +CONFIG_LWIP_PORT_DHCP_STACKSIZE=2048 +CONFIG_LWIP_PORT_DHCP_PRIORITY=5 +# end of lwip port thread Configuration +# end of LWIP Freertos Port Configuration + CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -427,4 +470,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/network/xmac_lwip_test/configs/e2000d_aarch64_eg_configs b/example/network/lwip_startup/configs/e2000d_aarch64_eg_configs similarity index 70% rename from example/network/xmac_lwip_test/configs/e2000d_aarch64_eg_configs rename to example/network/lwip_startup/configs/e2000d_aarch64_eg_configs index 31ac52cb..c1d1d456 100644 --- a/example/network/xmac_lwip_test/configs/e2000d_aarch64_eg_configs +++ b/example/network/lwip_startup/configs/e2000d_aarch64_eg_configs @@ -2,19 +2,18 @@ # # Project Configuration # -CONFIG_TARGET_NAME="e2000d_freertos_a32" +CONFIG_TARGET_NAME="e2000d_freertos_a64" # -# E2000 board Configuration +# Lwip startup test configuration # -CONFIG_LWIP_IPV4_TEST=y -# CONFIG_LWIP_IPV4_DHCP_TEST is not set # CONFIG_LWIP_IPV6_TEST is not set +# CONFIG_LWIP_DHCP_TEST is not set # CONFIG_BOARD_TYPE_B is not set # CONFIG_BOARD_TYPE_C is not set # CONFIG_BOARD_TYPE_A is not set CONFIG_BOARD_TYPE_DEMO=y -# end of E2000 board Configuration +# end of Lwip startup test configuration # end of Project Configuration # @@ -89,6 +88,7 @@ CONFIG_FXMAC_PHY_COMMON=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -98,9 +98,9 @@ CONFIG_USE_NEW_LIBC=y # Building Option # # CONFIG_LOG_VERBOS is not set -# CONFIG_LOG_DEBUG is not set +CONFIG_LOG_DEBUG=y # CONFIG_LOG_INFO is not set -CONFIG_LOG_WARN=y +# CONFIG_LOG_WARN is not set # CONFIG_LOG_ERROR is not set # CONFIG_LOG_NONE is not set CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y @@ -129,6 +129,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -165,6 +174,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # CONFIG_FREERTOS_USE_XMAC=y +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -186,12 +196,6 @@ CONFIG_FREERTOS_USE_XMAC=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -203,113 +207,81 @@ CONFIG_FREERTOS_USE_XMAC=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers -# end of Component Configuration # -# FreeRTOS Setting +# Freertos I2c Drivers # -CONFIG_USE_LWIP=y +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers # -# LWIP Configuration +# Freertos Mio Drivers # +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers # -# LWIP Port Configuration -# -# CONFIG_LWIP_FGMAC is not set -CONFIG_LWIP_FXMAC=y -# end of LWIP Port Configuration - -CONFIG_LWIP_LOCAL_HOSTNAME="phytium" - +# Freertos Timer Drivers # -# memory configuration -# -# CONFIG_LWIP_USE_MEM_POOL is not set -CONFIG_LWIP_USE_MEM_HEAP=y -CONFIG_MEM_SIZE=1 -CONFIG_MEM_ALIGNMENT=64 -# end of memory configuration - -# -# NETWORK_INTERFACE_OPTIONS -# -# CONFIG_LWIP_NETIF_API is not set -# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set -# end of NETWORK_INTERFACE_OPTIONS +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers +# end of Component Configuration # -# LOOPIF +# Third-Party Configuration # -CONFIG_LWIP_NETIF_LOOPBACK=y -CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 -# end of LOOPIF +CONFIG_USE_LWIP=y # -# SLIPIF +# LWIP Freertos Port Configuration # -# CONFIG_LWIP_SLIP_SUPPORT is not set -# end of SLIPIF +CONFIG_LWIP_FXMAC=y +# CONFIG_LWIP_FGMAC is not set # -# Pbuf options +# LWIP Configuration # -CONFIG_PBUF_POOL_BUFSIZE=2 -# end of Pbuf options # -# Internal Memory Pool Sizes +# LWIP Port Configuration # -CONFIG_PBUF_POOL_SIZE=1 -# end of Internal Memory Pool Sizes +# CONFIG_LWIP_PORT_DEBUG_EN is not set +# end of LWIP Port Configuration -CONFIG_LWIP_MAX_SOCKETS=10 +# CONFIG_LWIP_NO_SYS is not set +CONFIG_LWIP_LOCAL_HOSTNAME="phytium" # -# LWIP RAW API +# Memory configuration # -CONFIG_LWIP_MAX_RAW_PCBS=16 -# end of LWIP RAW API +# CONFIG_LWIP_USE_MEM_POOL is not set +CONFIG_LWIP_USE_MEM_HEAP=y +CONFIG_MEM_SIZE=2 +CONFIG_MEM_ALIGNMENT=64 +# end of Memory configuration # -# TCP +# Pbuf options # -CONFIG_LWIP_MAX_ACTIVE_TCP=16 -CONFIG_LWIP_MAX_LISTENING_TCP=16 -CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y -CONFIG_LWIP_TCP_MAXRTX=12 -CONFIG_LWIP_TCP_SYNMAXRTX=12 -CONFIG_LWIP_TCP_MSS=1440 -CONFIG_LWIP_TCP_TMR_INTERVAL=250 -CONFIG_LWIP_TCP_MSL=60000 -CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 -CONFIG_LWIP_TCP_WND_DEFAULT=5744 -CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 -CONFIG_LWIP_TCP_QUEUE_OOSEQ=y -# CONFIG_LWIP_TCP_SACK_OUT is not set -CONFIG_LWIP_TCP_OVERSIZE_MSS=y -# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set -# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set -# end of TCP +CONFIG_PBUF_POOL_BUFSIZE=2 +CONFIG_PBUF_POOL_SIZE=1 +# end of Pbuf options # -# UDP +# ARP # -CONFIG_LWIP_MAX_UDP_PCBS=16 -CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 -# CONFIG_LWIP_NETBUF_RECVINFO is not set -# end of UDP +CONFIG_ARP_QUEUEING_EN=y +# end of ARP # -# IPv4 +# IPV4 # -CONFIG_USE_IPV4_ONLY=y +# CONFIG_USE_IPV4_ONLY is not set CONFIG_LWIP_IP4_REASSEMBLY=y CONFIG_LWIP_IP4_FRAG=y # CONFIG_LWIP_IP_FORWARD is not set CONFIG_IP_REASS_MAX_PBUFS=16 -# end of IPv4 +# end of IPV4 # # ICMP @@ -319,16 +291,17 @@ CONFIG_LWIP_MULTICAST_PING=y CONFIG_LWIP_BROADCAST_PING=y # end of ICMP +# +# LWIP RAW API +# +CONFIG_LWIP_RAW_API_EN=y +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + # # DHCP # # CONFIG_LWIP_DHCP_ENABLE is not set -# CONFIG_LWIP_DHCP_DOES_ARP_CHECK is not set -# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set -# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set -# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set -CONFIG_LWIP_DHCP_OPTIONS_LEN=68 -CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y # end of DHCP # @@ -337,6 +310,12 @@ CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y # CONFIG_LWIP_AUTOIP is not set # end of AUTOIP +# +# IGMP +# +CONFIG_LWIP_IGMP_EN=y +# end of IGMP + # # DNS # @@ -344,20 +323,65 @@ CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y # end of DNS # -# TCP options +# UDP # +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# CONFIG_LWIP_NETBUF_RECVINFO is not set +# end of UDP + +# +# TCP +# +CONFIG_LWIP_TCP_WND_DEFAULT=5744 +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +# CONFIG_LWIP_TCP_SACK_OUT is not set +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 CONFIG_LWIP_TCP_RTO_TIME=1500 -# end of TCP options +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +# end of TCP + +# +# Network_Interface +# +# CONFIG_LWIP_NETIF_API is not set +# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set +# end of Network_Interface + +# +# LOOPIF +# +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 +# end of LOOPIF + +# +# SLIPIF +# +# CONFIG_LWIP_SLIP_SUPPORT is not set +# end of SLIPIF CONFIG_LWIP_TCPIP_CORE_LOCKING=y # -# socket +# Socket # +CONFIG_LWIP_MAX_SOCKETS=10 # CONFIG_LWIP_SO_LINGER is not set CONFIG_LWIP_SO_REUSE=y CONFIG_LWIP_SO_REUSE_RXTOALL=y -# end of socket +# end of Socket # CONFIG_LWIP_STATS is not set @@ -365,8 +389,6 @@ CONFIG_LWIP_SO_REUSE_RXTOALL=y # PPP # # CONFIG_LWIP_PPP_SUPPORT is not set -CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 -CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 # end of PPP # @@ -378,17 +400,13 @@ CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y # end of Checksums # -# ipv6 +# IPV6 # -CONFIG_LWIP_IPV6=y -# CONFIG_LWIP_IPV6_AUTOCONFIG is not set -CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 -# CONFIG_LWIP_IPV6_FORWARD is not set -CONFIG_LWIP_IP6_FRAG=y -# CONFIG_LWIP_IP6_REASSEMBLY is not set -# end of ipv6 +# CONFIG_LWIP_IPV6 is not set +# end of IPV6 CONFIG_LWIP_DEBUG=y +# CONFIG_LWIP_DEBUG_ESP_LOG is not set CONFIG_LWIP_NETIF_DEBUG=y # CONFIG_LWIP_PBUF_DEBUG is not set # CONFIG_LWIP_ETHARP_DEBUG is not set @@ -396,16 +414,41 @@ CONFIG_LWIP_NETIF_DEBUG=y # CONFIG_LWIP_SOCKETS_DEBUG is not set # CONFIG_LWIP_IP_DEBUG is not set # CONFIG_LWIP_ICMP_DEBUG is not set +# CONFIG_LWIP_DHCP_STATE_DEBUG is not set # CONFIG_LWIP_DHCP_DEBUG is not set # CONFIG_LWIP_IP6_DEBUG is not set # CONFIG_LWIP_ICMP6_DEBUG is not set # CONFIG_LWIP_TCP_DEBUG is not set +# CONFIG_LWIP_UDP_DEBUG is not set # CONFIG_LWIP_SNTP_DEBUG is not set # CONFIG_LWIP_DNS_DEBUG is not set # end of LWIP Configuration +# +# Tcp/ip task resource configuration +# +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_PRIO=6 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +# end of Tcp/ip task resource configuration + +# +# lwip port thread Configuration +# +CONFIG_LWIP_PORT_USE_RECEIVE_THREAD=y +CONFIG_LWIP_PORT_RECEIVE_THREAD_STACKSIZE=1024 +CONFIG_LWIP_PORT_RECEIVE_THREAD_PRIORITY=5 +CONFIG_LWIP_PORT_USE_LINK_DETECT_THREAD=y +CONFIG_LWIP_PORT_LINK_DETECT_STACKSIZE=1024 +CONFIG_LWIP_PORT_LINK_DETECT_PRIORITY=5 +CONFIG_LWIP_PORT_DHCP_THREAD=y +CONFIG_LWIP_PORT_DHCP_STACKSIZE=2048 +CONFIG_LWIP_PORT_DHCP_PRIORITY=5 +# end of lwip port thread Configuration +# end of LWIP Freertos Port Configuration + CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -423,4 +466,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/network/xmac_lwip_test/configs/e2000q_aarch32_eg_configs b/example/network/lwip_startup/configs/e2000q_aarch32_eg_configs similarity index 71% rename from example/network/xmac_lwip_test/configs/e2000q_aarch32_eg_configs rename to example/network/lwip_startup/configs/e2000q_aarch32_eg_configs index 04aefcdc..601c5045 100644 --- a/example/network/xmac_lwip_test/configs/e2000q_aarch32_eg_configs +++ b/example/network/lwip_startup/configs/e2000q_aarch32_eg_configs @@ -2,19 +2,18 @@ # # Project Configuration # -CONFIG_TARGET_NAME="e2000d_lwip_echo" +CONFIG_TARGET_NAME="e2000q_freertos_a32" # -# E2000 board Configuration +# Lwip startup test configuration # -CONFIG_LWIP_IPV4_TEST=y -# CONFIG_LWIP_IPV4_DHCP_TEST is not set # CONFIG_LWIP_IPV6_TEST is not set +# CONFIG_LWIP_DHCP_TEST is not set # CONFIG_BOARD_TYPE_B is not set # CONFIG_BOARD_TYPE_C is not set # CONFIG_BOARD_TYPE_A is not set CONFIG_BOARD_TYPE_DEMO=y -# end of E2000 board Configuration +# end of Lwip startup test configuration # end of Project Configuration # @@ -89,6 +88,7 @@ CONFIG_FXMAC_PHY_COMMON=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -98,9 +98,9 @@ CONFIG_USE_NEW_LIBC=y # Building Option # # CONFIG_LOG_VERBOS is not set -# CONFIG_LOG_DEBUG is not set +CONFIG_LOG_DEBUG=y # CONFIG_LOG_INFO is not set -CONFIG_LOG_WARN=y +# CONFIG_LOG_WARN is not set # CONFIG_LOG_ERROR is not set # CONFIG_LOG_NONE is not set CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y @@ -133,6 +133,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -169,6 +178,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # CONFIG_FREERTOS_USE_XMAC=y +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -190,12 +200,6 @@ CONFIG_FREERTOS_USE_XMAC=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -207,113 +211,81 @@ CONFIG_FREERTOS_USE_XMAC=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers -# end of Component Configuration # -# FreeRTOS Setting +# Freertos I2c Drivers # -CONFIG_USE_LWIP=y +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers # -# LWIP Configuration +# Freertos Mio Drivers # +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers # -# LWIP Port Configuration -# -# CONFIG_LWIP_FGMAC is not set -CONFIG_LWIP_FXMAC=y -# end of LWIP Port Configuration - -CONFIG_LWIP_LOCAL_HOSTNAME="phytium" - +# Freertos Timer Drivers # -# memory configuration -# -# CONFIG_LWIP_USE_MEM_POOL is not set -CONFIG_LWIP_USE_MEM_HEAP=y -CONFIG_MEM_SIZE=1 -CONFIG_MEM_ALIGNMENT=64 -# end of memory configuration - -# -# NETWORK_INTERFACE_OPTIONS -# -# CONFIG_LWIP_NETIF_API is not set -# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set -# end of NETWORK_INTERFACE_OPTIONS +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers +# end of Component Configuration # -# LOOPIF +# Third-Party Configuration # -CONFIG_LWIP_NETIF_LOOPBACK=y -CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 -# end of LOOPIF +CONFIG_USE_LWIP=y # -# SLIPIF +# LWIP Freertos Port Configuration # -# CONFIG_LWIP_SLIP_SUPPORT is not set -# end of SLIPIF +CONFIG_LWIP_FXMAC=y +# CONFIG_LWIP_FGMAC is not set # -# Pbuf options +# LWIP Configuration # -CONFIG_PBUF_POOL_BUFSIZE=2 -# end of Pbuf options # -# Internal Memory Pool Sizes +# LWIP Port Configuration # -CONFIG_PBUF_POOL_SIZE=1 -# end of Internal Memory Pool Sizes +# CONFIG_LWIP_PORT_DEBUG_EN is not set +# end of LWIP Port Configuration -CONFIG_LWIP_MAX_SOCKETS=10 +# CONFIG_LWIP_NO_SYS is not set +CONFIG_LWIP_LOCAL_HOSTNAME="phytium" # -# LWIP RAW API +# Memory configuration # -CONFIG_LWIP_MAX_RAW_PCBS=16 -# end of LWIP RAW API +# CONFIG_LWIP_USE_MEM_POOL is not set +CONFIG_LWIP_USE_MEM_HEAP=y +CONFIG_MEM_SIZE=2 +CONFIG_MEM_ALIGNMENT=64 +# end of Memory configuration # -# TCP +# Pbuf options # -CONFIG_LWIP_MAX_ACTIVE_TCP=16 -CONFIG_LWIP_MAX_LISTENING_TCP=16 -CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y -CONFIG_LWIP_TCP_MAXRTX=12 -CONFIG_LWIP_TCP_SYNMAXRTX=12 -CONFIG_LWIP_TCP_MSS=1440 -CONFIG_LWIP_TCP_TMR_INTERVAL=250 -CONFIG_LWIP_TCP_MSL=60000 -CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 -CONFIG_LWIP_TCP_WND_DEFAULT=5744 -CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 -CONFIG_LWIP_TCP_QUEUE_OOSEQ=y -# CONFIG_LWIP_TCP_SACK_OUT is not set -CONFIG_LWIP_TCP_OVERSIZE_MSS=y -# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set -# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set -# end of TCP +CONFIG_PBUF_POOL_BUFSIZE=2 +CONFIG_PBUF_POOL_SIZE=1 +# end of Pbuf options # -# UDP +# ARP # -CONFIG_LWIP_MAX_UDP_PCBS=16 -CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 -# CONFIG_LWIP_NETBUF_RECVINFO is not set -# end of UDP +CONFIG_ARP_QUEUEING_EN=y +# end of ARP # -# IPv4 +# IPV4 # -CONFIG_USE_IPV4_ONLY=y +# CONFIG_USE_IPV4_ONLY is not set CONFIG_LWIP_IP4_REASSEMBLY=y CONFIG_LWIP_IP4_FRAG=y # CONFIG_LWIP_IP_FORWARD is not set CONFIG_IP_REASS_MAX_PBUFS=16 -# end of IPv4 +# end of IPV4 # # ICMP @@ -323,16 +295,17 @@ CONFIG_LWIP_MULTICAST_PING=y CONFIG_LWIP_BROADCAST_PING=y # end of ICMP +# +# LWIP RAW API +# +CONFIG_LWIP_RAW_API_EN=y +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + # # DHCP # # CONFIG_LWIP_DHCP_ENABLE is not set -# CONFIG_LWIP_DHCP_DOES_ARP_CHECK is not set -# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set -# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set -# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set -CONFIG_LWIP_DHCP_OPTIONS_LEN=68 -CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y # end of DHCP # @@ -341,6 +314,12 @@ CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y # CONFIG_LWIP_AUTOIP is not set # end of AUTOIP +# +# IGMP +# +CONFIG_LWIP_IGMP_EN=y +# end of IGMP + # # DNS # @@ -348,20 +327,65 @@ CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y # end of DNS # -# TCP options +# UDP # +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# CONFIG_LWIP_NETBUF_RECVINFO is not set +# end of UDP + +# +# TCP +# +CONFIG_LWIP_TCP_WND_DEFAULT=5744 +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +# CONFIG_LWIP_TCP_SACK_OUT is not set +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 CONFIG_LWIP_TCP_RTO_TIME=1500 -# end of TCP options +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +# end of TCP + +# +# Network_Interface +# +# CONFIG_LWIP_NETIF_API is not set +# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set +# end of Network_Interface + +# +# LOOPIF +# +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 +# end of LOOPIF + +# +# SLIPIF +# +# CONFIG_LWIP_SLIP_SUPPORT is not set +# end of SLIPIF CONFIG_LWIP_TCPIP_CORE_LOCKING=y # -# socket +# Socket # +CONFIG_LWIP_MAX_SOCKETS=10 # CONFIG_LWIP_SO_LINGER is not set CONFIG_LWIP_SO_REUSE=y CONFIG_LWIP_SO_REUSE_RXTOALL=y -# end of socket +# end of Socket # CONFIG_LWIP_STATS is not set @@ -369,8 +393,6 @@ CONFIG_LWIP_SO_REUSE_RXTOALL=y # PPP # # CONFIG_LWIP_PPP_SUPPORT is not set -CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 -CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 # end of PPP # @@ -382,17 +404,13 @@ CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y # end of Checksums # -# ipv6 +# IPV6 # -CONFIG_LWIP_IPV6=y -# CONFIG_LWIP_IPV6_AUTOCONFIG is not set -CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 -# CONFIG_LWIP_IPV6_FORWARD is not set -CONFIG_LWIP_IP6_FRAG=y -# CONFIG_LWIP_IP6_REASSEMBLY is not set -# end of ipv6 +# CONFIG_LWIP_IPV6 is not set +# end of IPV6 CONFIG_LWIP_DEBUG=y +# CONFIG_LWIP_DEBUG_ESP_LOG is not set CONFIG_LWIP_NETIF_DEBUG=y # CONFIG_LWIP_PBUF_DEBUG is not set # CONFIG_LWIP_ETHARP_DEBUG is not set @@ -400,16 +418,41 @@ CONFIG_LWIP_NETIF_DEBUG=y # CONFIG_LWIP_SOCKETS_DEBUG is not set # CONFIG_LWIP_IP_DEBUG is not set # CONFIG_LWIP_ICMP_DEBUG is not set +# CONFIG_LWIP_DHCP_STATE_DEBUG is not set # CONFIG_LWIP_DHCP_DEBUG is not set # CONFIG_LWIP_IP6_DEBUG is not set # CONFIG_LWIP_ICMP6_DEBUG is not set # CONFIG_LWIP_TCP_DEBUG is not set +# CONFIG_LWIP_UDP_DEBUG is not set # CONFIG_LWIP_SNTP_DEBUG is not set # CONFIG_LWIP_DNS_DEBUG is not set # end of LWIP Configuration +# +# Tcp/ip task resource configuration +# +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_PRIO=6 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +# end of Tcp/ip task resource configuration + +# +# lwip port thread Configuration +# +CONFIG_LWIP_PORT_USE_RECEIVE_THREAD=y +CONFIG_LWIP_PORT_RECEIVE_THREAD_STACKSIZE=1024 +CONFIG_LWIP_PORT_RECEIVE_THREAD_PRIORITY=5 +CONFIG_LWIP_PORT_USE_LINK_DETECT_THREAD=y +CONFIG_LWIP_PORT_LINK_DETECT_STACKSIZE=1024 +CONFIG_LWIP_PORT_LINK_DETECT_PRIORITY=5 +CONFIG_LWIP_PORT_DHCP_THREAD=y +CONFIG_LWIP_PORT_DHCP_STACKSIZE=2048 +CONFIG_LWIP_PORT_DHCP_PRIORITY=5 +# end of lwip port thread Configuration +# end of LWIP Freertos Port Configuration + CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -427,4 +470,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/network/xmac_lwip_test/configs/e2000q_aarch64_eg_configs b/example/network/lwip_startup/configs/e2000q_aarch64_eg_configs similarity index 70% rename from example/network/xmac_lwip_test/configs/e2000q_aarch64_eg_configs rename to example/network/lwip_startup/configs/e2000q_aarch64_eg_configs index 9ee6c500..02d46549 100644 --- a/example/network/xmac_lwip_test/configs/e2000q_aarch64_eg_configs +++ b/example/network/lwip_startup/configs/e2000q_aarch64_eg_configs @@ -2,19 +2,18 @@ # # Project Configuration # -CONFIG_TARGET_NAME="e2000d_lwip_echo" +CONFIG_TARGET_NAME="e2000q_freertos_a64" # -# E2000 board Configuration +# Lwip startup test configuration # -CONFIG_LWIP_IPV4_TEST=y -# CONFIG_LWIP_IPV4_DHCP_TEST is not set # CONFIG_LWIP_IPV6_TEST is not set +# CONFIG_LWIP_DHCP_TEST is not set # CONFIG_BOARD_TYPE_B is not set # CONFIG_BOARD_TYPE_C is not set # CONFIG_BOARD_TYPE_A is not set CONFIG_BOARD_TYPE_DEMO=y -# end of E2000 board Configuration +# end of Lwip startup test configuration # end of Project Configuration # @@ -89,6 +88,7 @@ CONFIG_FXMAC_PHY_COMMON=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -98,9 +98,9 @@ CONFIG_USE_NEW_LIBC=y # Building Option # # CONFIG_LOG_VERBOS is not set -# CONFIG_LOG_DEBUG is not set +CONFIG_LOG_DEBUG=y # CONFIG_LOG_INFO is not set -CONFIG_LOG_WARN=y +# CONFIG_LOG_WARN is not set # CONFIG_LOG_ERROR is not set # CONFIG_LOG_NONE is not set CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y @@ -129,6 +129,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -165,6 +174,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # CONFIG_FREERTOS_USE_XMAC=y +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -186,12 +196,6 @@ CONFIG_FREERTOS_USE_XMAC=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -203,113 +207,81 @@ CONFIG_FREERTOS_USE_XMAC=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers -# end of Component Configuration # -# FreeRTOS Setting +# Freertos I2c Drivers # -CONFIG_USE_LWIP=y +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers # -# LWIP Configuration +# Freertos Mio Drivers # +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers # -# LWIP Port Configuration -# -# CONFIG_LWIP_FGMAC is not set -CONFIG_LWIP_FXMAC=y -# end of LWIP Port Configuration - -CONFIG_LWIP_LOCAL_HOSTNAME="phytium" - +# Freertos Timer Drivers # -# memory configuration -# -# CONFIG_LWIP_USE_MEM_POOL is not set -CONFIG_LWIP_USE_MEM_HEAP=y -CONFIG_MEM_SIZE=1 -CONFIG_MEM_ALIGNMENT=64 -# end of memory configuration - -# -# NETWORK_INTERFACE_OPTIONS -# -# CONFIG_LWIP_NETIF_API is not set -# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set -# end of NETWORK_INTERFACE_OPTIONS +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers +# end of Component Configuration # -# LOOPIF +# Third-Party Configuration # -CONFIG_LWIP_NETIF_LOOPBACK=y -CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 -# end of LOOPIF +CONFIG_USE_LWIP=y # -# SLIPIF +# LWIP Freertos Port Configuration # -# CONFIG_LWIP_SLIP_SUPPORT is not set -# end of SLIPIF +CONFIG_LWIP_FXMAC=y +# CONFIG_LWIP_FGMAC is not set # -# Pbuf options +# LWIP Configuration # -CONFIG_PBUF_POOL_BUFSIZE=2 -# end of Pbuf options # -# Internal Memory Pool Sizes +# LWIP Port Configuration # -CONFIG_PBUF_POOL_SIZE=1 -# end of Internal Memory Pool Sizes +# CONFIG_LWIP_PORT_DEBUG_EN is not set +# end of LWIP Port Configuration -CONFIG_LWIP_MAX_SOCKETS=10 +# CONFIG_LWIP_NO_SYS is not set +CONFIG_LWIP_LOCAL_HOSTNAME="phytium" # -# LWIP RAW API +# Memory configuration # -CONFIG_LWIP_MAX_RAW_PCBS=16 -# end of LWIP RAW API +# CONFIG_LWIP_USE_MEM_POOL is not set +CONFIG_LWIP_USE_MEM_HEAP=y +CONFIG_MEM_SIZE=2 +CONFIG_MEM_ALIGNMENT=64 +# end of Memory configuration # -# TCP +# Pbuf options # -CONFIG_LWIP_MAX_ACTIVE_TCP=16 -CONFIG_LWIP_MAX_LISTENING_TCP=16 -CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y -CONFIG_LWIP_TCP_MAXRTX=12 -CONFIG_LWIP_TCP_SYNMAXRTX=12 -CONFIG_LWIP_TCP_MSS=1440 -CONFIG_LWIP_TCP_TMR_INTERVAL=250 -CONFIG_LWIP_TCP_MSL=60000 -CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 -CONFIG_LWIP_TCP_WND_DEFAULT=5744 -CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 -CONFIG_LWIP_TCP_QUEUE_OOSEQ=y -# CONFIG_LWIP_TCP_SACK_OUT is not set -CONFIG_LWIP_TCP_OVERSIZE_MSS=y -# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set -# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set -# end of TCP +CONFIG_PBUF_POOL_BUFSIZE=2 +CONFIG_PBUF_POOL_SIZE=1 +# end of Pbuf options # -# UDP +# ARP # -CONFIG_LWIP_MAX_UDP_PCBS=16 -CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 -# CONFIG_LWIP_NETBUF_RECVINFO is not set -# end of UDP +CONFIG_ARP_QUEUEING_EN=y +# end of ARP # -# IPv4 +# IPV4 # -CONFIG_USE_IPV4_ONLY=y +# CONFIG_USE_IPV4_ONLY is not set CONFIG_LWIP_IP4_REASSEMBLY=y CONFIG_LWIP_IP4_FRAG=y # CONFIG_LWIP_IP_FORWARD is not set CONFIG_IP_REASS_MAX_PBUFS=16 -# end of IPv4 +# end of IPV4 # # ICMP @@ -319,16 +291,17 @@ CONFIG_LWIP_MULTICAST_PING=y CONFIG_LWIP_BROADCAST_PING=y # end of ICMP +# +# LWIP RAW API +# +CONFIG_LWIP_RAW_API_EN=y +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + # # DHCP # # CONFIG_LWIP_DHCP_ENABLE is not set -# CONFIG_LWIP_DHCP_DOES_ARP_CHECK is not set -# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set -# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set -# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set -CONFIG_LWIP_DHCP_OPTIONS_LEN=68 -CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y # end of DHCP # @@ -337,6 +310,12 @@ CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y # CONFIG_LWIP_AUTOIP is not set # end of AUTOIP +# +# IGMP +# +CONFIG_LWIP_IGMP_EN=y +# end of IGMP + # # DNS # @@ -344,20 +323,65 @@ CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y # end of DNS # -# TCP options +# UDP # +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# CONFIG_LWIP_NETBUF_RECVINFO is not set +# end of UDP + +# +# TCP +# +CONFIG_LWIP_TCP_WND_DEFAULT=5744 +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +# CONFIG_LWIP_TCP_SACK_OUT is not set +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 CONFIG_LWIP_TCP_RTO_TIME=1500 -# end of TCP options +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +# end of TCP + +# +# Network_Interface +# +# CONFIG_LWIP_NETIF_API is not set +# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set +# end of Network_Interface + +# +# LOOPIF +# +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 +# end of LOOPIF + +# +# SLIPIF +# +# CONFIG_LWIP_SLIP_SUPPORT is not set +# end of SLIPIF CONFIG_LWIP_TCPIP_CORE_LOCKING=y # -# socket +# Socket # +CONFIG_LWIP_MAX_SOCKETS=10 # CONFIG_LWIP_SO_LINGER is not set CONFIG_LWIP_SO_REUSE=y CONFIG_LWIP_SO_REUSE_RXTOALL=y -# end of socket +# end of Socket # CONFIG_LWIP_STATS is not set @@ -365,8 +389,6 @@ CONFIG_LWIP_SO_REUSE_RXTOALL=y # PPP # # CONFIG_LWIP_PPP_SUPPORT is not set -CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 -CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 # end of PPP # @@ -378,17 +400,13 @@ CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y # end of Checksums # -# ipv6 +# IPV6 # -CONFIG_LWIP_IPV6=y -# CONFIG_LWIP_IPV6_AUTOCONFIG is not set -CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 -# CONFIG_LWIP_IPV6_FORWARD is not set -CONFIG_LWIP_IP6_FRAG=y -# CONFIG_LWIP_IP6_REASSEMBLY is not set -# end of ipv6 +# CONFIG_LWIP_IPV6 is not set +# end of IPV6 CONFIG_LWIP_DEBUG=y +# CONFIG_LWIP_DEBUG_ESP_LOG is not set CONFIG_LWIP_NETIF_DEBUG=y # CONFIG_LWIP_PBUF_DEBUG is not set # CONFIG_LWIP_ETHARP_DEBUG is not set @@ -396,16 +414,41 @@ CONFIG_LWIP_NETIF_DEBUG=y # CONFIG_LWIP_SOCKETS_DEBUG is not set # CONFIG_LWIP_IP_DEBUG is not set # CONFIG_LWIP_ICMP_DEBUG is not set +# CONFIG_LWIP_DHCP_STATE_DEBUG is not set # CONFIG_LWIP_DHCP_DEBUG is not set # CONFIG_LWIP_IP6_DEBUG is not set # CONFIG_LWIP_ICMP6_DEBUG is not set # CONFIG_LWIP_TCP_DEBUG is not set +# CONFIG_LWIP_UDP_DEBUG is not set # CONFIG_LWIP_SNTP_DEBUG is not set # CONFIG_LWIP_DNS_DEBUG is not set # end of LWIP Configuration +# +# Tcp/ip task resource configuration +# +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_PRIO=6 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +# end of Tcp/ip task resource configuration + +# +# lwip port thread Configuration +# +CONFIG_LWIP_PORT_USE_RECEIVE_THREAD=y +CONFIG_LWIP_PORT_RECEIVE_THREAD_STACKSIZE=1024 +CONFIG_LWIP_PORT_RECEIVE_THREAD_PRIORITY=5 +CONFIG_LWIP_PORT_USE_LINK_DETECT_THREAD=y +CONFIG_LWIP_PORT_LINK_DETECT_STACKSIZE=1024 +CONFIG_LWIP_PORT_LINK_DETECT_PRIORITY=5 +CONFIG_LWIP_PORT_DHCP_THREAD=y +CONFIG_LWIP_PORT_DHCP_STACKSIZE=2048 +CONFIG_LWIP_PORT_DHCP_PRIORITY=5 +# end of lwip port thread Configuration +# end of LWIP Freertos Port Configuration + CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -423,4 +466,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/network/lwip_startup/configs/ft2004_aarch32_eg_configs b/example/network/lwip_startup/configs/ft2004_aarch32_eg_configs new file mode 100644 index 00000000..e0fd8720 --- /dev/null +++ b/example/network/lwip_startup/configs/ft2004_aarch32_eg_configs @@ -0,0 +1,505 @@ + +# +# Project Configuration +# +CONFIG_TARGET_NAME="ft2004_freertos_a32" + +# +# Lwip startup test configuration +# +CONFIG_LWIP_IPV6_TEST=y +CONFIG_LWIP_DHCP_TEST=y +# end of Lwip startup test configuration +# end of Project Configuration + +# +# Standalone Setting +# +CONFIG_USE_FREERTOS=y + +# +# Arch Configuration +# +CONFIG_TARGET_ARMV8_AARCH32=y +# CONFIG_TARGET_ARMV8_AARCH64 is not set +CONFIG_USE_CACHE=y +# CONFIG_USE_L3CACHE is not set +CONFIG_USE_MMU=y +CONFIG_USE_SYS_TICK=y +CONFIG_USE_AARCH64_L1_TO_AARCH32=y +# end of Arch Configuration + +# +# Board Configuration +# +CONFIG_TARGET_F2000_4=y +# CONFIG_TARGET_D2000 is not set +# CONFIG_TARGET_E2000Q is not set +# CONFIG_TARGET_E2000D is not set +# CONFIG_TARGET_E2000S is not set +CONFIG_DEFAULT_DEBUG_PRINT_UART1=y +# CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set +# CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set +# end of Board Configuration + +# +# Components Configuration +# +# CONFIG_USE_SPI is not set +# CONFIG_USE_QSPI is not set +CONFIG_USE_GIC=y +CONFIG_ENABLE_GICV3=y +CONFIG_USE_SERIAL=y + +# +# Usart Configuration +# +CONFIG_ENABLE_Pl011_UART=y +# end of Usart Configuration + +# CONFIG_USE_GPIO is not set +CONFIG_USE_ETH=y + +# +# Eth Configuration +# +# CONFIG_ENABLE_FXMAC is not set +CONFIG_ENABLE_FGMAC=y +CONFIG_FGMAC_PHY_COMMON=y +# CONFIG_FGMAC_PHY_AR803X is not set +# end of Eth Configuration + +# CONFIG_USE_CAN is not set +# CONFIG_USE_I2C is not set +# CONFIG_USE_TIMER is not set +# CONFIG_USE_MIO is not set +# CONFIG_USE_SDMMC is not set +# CONFIG_USE_PCIE is not set +# CONFIG_USE_WDT is not set +# CONFIG_USE_DMA is not set +# CONFIG_USE_NAND is not set +# CONFIG_USE_RTC is not set +# CONFIG_USE_SATA is not set +# CONFIG_USE_USB is not set +# CONFIG_USE_ADC is not set +# CONFIG_USE_PWM is not set +# CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set +# end of Components Configuration + +CONFIG_USE_NEW_LIBC=y +# end of Standalone Setting + +# +# Building Option +# +# CONFIG_LOG_VERBOS is not set +# CONFIG_LOG_DEBUG is not set +# CONFIG_LOG_INFO is not set +# CONFIG_LOG_WARN is not set +CONFIG_LOG_ERROR=y +# CONFIG_LOG_NONE is not set +CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y +CONFIG_INTERRUPT_ROLE_MASTER=y +# CONFIG_INTERRUPT_ROLE_SLAVE is not set +# CONFIG_LOG_EXTRA_INFO is not set +# CONFIG_BOOTUP_DEBUG_PRINTS is not set + +# +# Linker Options +# +CONFIG_AARCH32_RAM_LD=y +# CONFIG_AARCH64_RAM_LD is not set +# CONFIG_USER_DEFINED_LD is not set +CONFIG_LINK_SCRIPT_ROM=y +CONFIG_ROM_START_UP_ADDR=0x80100000 +CONFIG_ROM_SIZE_MB=1 +CONFIG_LINK_SCRIPT_RAM=y +CONFIG_RAM_START_UP_ADDR=0x80500000 +CONFIG_RAM_SIZE_MB=64 +CONFIG_HEAP_SIZE=1 +CONFIG_SVC_STACK_SIZE=0x1000 +CONFIG_SYS_STACK_SIZE=0x1000 +CONFIG_IRQ_STACK_SIZE=0x1000 +CONFIG_ABORT_STACK_SIZE=0x1000 +CONFIG_FIQ_STACK_SIZE=0x1000 +CONFIG_UNDEF_STACK_SIZE=0x1000 +# end of Linker Options + +# +# Compiler Options +# + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + +CONFIG_OUTPUT_BINARY=y +# end of Compiler Options +# end of Building Option + +# +# Component Configuration +# + +# +# Freertos Uart Drivers +# +CONFIG_FREERTOS_USE_UART=y +# end of Freertos Uart Drivers + +# +# Freertos Pwm Drivers +# +# CONFIG_FREERTOS_USE_PWM is not set +# end of Freertos Pwm Drivers + +# +# Freertos Qspi Drivers +# +# CONFIG_FREERTOS_USE_QSPI is not set +# end of Freertos Qspi Drivers + +# +# Freertos Wdt Drivers +# +# CONFIG_FREERTOS_USE_WDT is not set +# end of Freertos Wdt Drivers + +# +# Freertos Eth Drivers +# +# CONFIG_FREERTOS_USE_XMAC is not set +CONFIG_FREERTOS_USE_GMAC=y +# end of Freertos Eth Drivers + +# +# Freertos Gpio Drivers +# +# CONFIG_FREERTOS_USE_GPIO is not set +# end of Freertos Gpio Drivers + +# +# Freertos Spim Drivers +# +# CONFIG_FREERTOS_USE_FSPIM is not set +# end of Freertos Spim Drivers + +# +# Freertos DMA Drivers +# +# CONFIG_FREERTOS_USE_FDDMA is not set +# CONFIG_FREERTOS_USE_FGDMA is not set +# end of Freertos DMA Drivers + +# +# Freertos Adc Drivers +# +# CONFIG_FREERTOS_USE_ADC is not set +# end of Freertos Adc Drivers + +# +# Freertos Can Drivers +# +# CONFIG_FREERTOS_USE_CAN is not set +# end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers +# end of Component Configuration + +# +# Third-Party Configuration +# +CONFIG_USE_LWIP=y + +# +# LWIP Freertos Port Configuration +# +# CONFIG_LWIP_FXMAC is not set +CONFIG_LWIP_FGMAC=y + +# +# LWIP Configuration +# + +# +# LWIP Port Configuration +# +# CONFIG_LWIP_PORT_DEBUG_EN is not set +# end of LWIP Port Configuration + +# CONFIG_LWIP_NO_SYS is not set +CONFIG_LWIP_LOCAL_HOSTNAME="phytium" + +# +# Memory configuration +# +# CONFIG_LWIP_USE_MEM_POOL is not set +CONFIG_LWIP_USE_MEM_HEAP=y +CONFIG_MEM_SIZE=2 +CONFIG_MEM_ALIGNMENT=64 +# end of Memory configuration + +# +# Pbuf options +# +CONFIG_PBUF_POOL_BUFSIZE=2 +CONFIG_PBUF_POOL_SIZE=1 +# end of Pbuf options + +# +# ARP +# +CONFIG_ARP_QUEUEING_EN=y +# end of ARP + +# +# IPV4 +# +# CONFIG_USE_IPV4_ONLY is not set +CONFIG_LWIP_IP4_REASSEMBLY=y +CONFIG_LWIP_IP4_FRAG=y +# CONFIG_LWIP_IP_FORWARD is not set +CONFIG_IP_REASS_MAX_PBUFS=16 +# end of IPV4 + +# +# ICMP +# +CONFIG_LWIP_ICMP=y +CONFIG_LWIP_MULTICAST_PING=y +CONFIG_LWIP_BROADCAST_PING=y +# end of ICMP + +# +# LWIP RAW API +# +CONFIG_LWIP_RAW_API_EN=y +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + +# +# DHCP +# +CONFIG_LWIP_DHCP_ENABLE=y +# CONFIG_LWIP_DHCP_DOES_ARP_CHECK is not set +# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set +# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set +# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set +CONFIG_LWIP_DHCP_OPTIONS_LEN=68 +CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y +# end of DHCP + +# +# AUTOIP +# +# CONFIG_LWIP_AUTOIP is not set +# end of AUTOIP + +# +# IGMP +# +CONFIG_LWIP_IGMP_EN=y +# end of IGMP + +# +# DNS +# +CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y +# end of DNS + +# +# UDP +# +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# CONFIG_LWIP_NETBUF_RECVINFO is not set +# end of UDP + +# +# TCP +# +CONFIG_LWIP_TCP_WND_DEFAULT=5744 +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +# CONFIG_LWIP_TCP_SACK_OUT is not set +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 +CONFIG_LWIP_TCP_RTO_TIME=1500 +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +# end of TCP + +# +# Network_Interface +# +# CONFIG_LWIP_NETIF_API is not set +# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set +# end of Network_Interface + +# +# LOOPIF +# +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 +# end of LOOPIF + +# +# SLIPIF +# +# CONFIG_LWIP_SLIP_SUPPORT is not set +# end of SLIPIF + +CONFIG_LWIP_TCPIP_CORE_LOCKING=y + +# +# Socket +# +CONFIG_LWIP_MAX_SOCKETS=10 +# CONFIG_LWIP_SO_LINGER is not set +CONFIG_LWIP_SO_REUSE=y +CONFIG_LWIP_SO_REUSE_RXTOALL=y +# end of Socket + +# CONFIG_LWIP_STATS is not set + +# +# PPP +# +# CONFIG_LWIP_PPP_SUPPORT is not set +CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 +CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 +# end of PPP + +# +# Checksums +# +# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set +# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set +CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y +# end of Checksums + +# +# IPV6 +# +CONFIG_LWIP_IPV6=y +# CONFIG_LWIP_IPV6_AUTOCONFIG is not set +CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 +# CONFIG_LWIP_IPV6_FORWARD is not set +CONFIG_LWIP_IP6_FRAG=y +# CONFIG_LWIP_IP6_REASSEMBLY is not set +# end of IPV6 + +CONFIG_LWIP_DEBUG=y +# CONFIG_LWIP_DEBUG_ESP_LOG is not set +CONFIG_LWIP_NETIF_DEBUG=y +# CONFIG_LWIP_PBUF_DEBUG is not set +# CONFIG_LWIP_ETHARP_DEBUG is not set +# CONFIG_LWIP_API_LIB_DEBUG is not set +# CONFIG_LWIP_SOCKETS_DEBUG is not set +# CONFIG_LWIP_IP_DEBUG is not set +# CONFIG_LWIP_ICMP_DEBUG is not set +# CONFIG_LWIP_DHCP_STATE_DEBUG is not set +# CONFIG_LWIP_DHCP_DEBUG is not set +# CONFIG_LWIP_IP6_DEBUG is not set +# CONFIG_LWIP_ICMP6_DEBUG is not set +# CONFIG_LWIP_TCP_DEBUG is not set +# CONFIG_LWIP_UDP_DEBUG is not set +# CONFIG_LWIP_SNTP_DEBUG is not set +# CONFIG_LWIP_DNS_DEBUG is not set +# end of LWIP Configuration + +# +# Tcp/ip task resource configuration +# +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_PRIO=6 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +# end of Tcp/ip task resource configuration + +# +# lwip port thread Configuration +# +CONFIG_LWIP_PORT_USE_RECEIVE_THREAD=y +CONFIG_LWIP_PORT_RECEIVE_THREAD_STACKSIZE=1024 +CONFIG_LWIP_PORT_RECEIVE_THREAD_PRIORITY=5 +CONFIG_LWIP_PORT_USE_LINK_DETECT_THREAD=y +CONFIG_LWIP_PORT_LINK_DETECT_STACKSIZE=1024 +CONFIG_LWIP_PORT_LINK_DETECT_PRIORITY=5 +CONFIG_LWIP_PORT_DHCP_THREAD=y +CONFIG_LWIP_PORT_DHCP_STACKSIZE=2048 +CONFIG_LWIP_PORT_DHCP_PRIORITY=5 +# end of lwip port thread Configuration +# end of LWIP Freertos Port Configuration + +CONFIG_USE_BACKTRACE=y +# CONFIG_USE_FATFS_0_1_4 is not set +# CONFIG_USE_SFUD is not set +# CONFIG_USE_SPIFFS is not set +# CONFIG_USE_AMP is not set +CONFIG_USE_LETTER_SHELL=y + +# +# Letter Shell Configuration +# +CONFIG_LS_PL011_UART=y +CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y +# CONFIG_DEFAULT_LETTER_SHELL_USE_UART0 is not set +# CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set +# end of Letter Shell Configuration + +CONFIG_USE_TLSF=y +# CONFIG_USE_SDMMC_CMD is not set +# CONFIG_USE_CHERRY_USB is not set +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/network/lwip_startup/configs/ft2004_aarch64_eg_configs b/example/network/lwip_startup/configs/ft2004_aarch64_eg_configs new file mode 100644 index 00000000..90b82d86 --- /dev/null +++ b/example/network/lwip_startup/configs/ft2004_aarch64_eg_configs @@ -0,0 +1,501 @@ + +# +# Project Configuration +# +CONFIG_TARGET_NAME="ft20004_freertos_a64" + +# +# Lwip startup test configuration +# +CONFIG_LWIP_IPV6_TEST=y +CONFIG_LWIP_DHCP_TEST=y +# end of Lwip startup test configuration +# end of Project Configuration + +# +# Standalone Setting +# +CONFIG_USE_FREERTOS=y + +# +# Arch Configuration +# +# CONFIG_TARGET_ARMV8_AARCH32 is not set +CONFIG_TARGET_ARMV8_AARCH64=y +CONFIG_USE_CACHE=y +# CONFIG_USE_L3CACHE is not set +CONFIG_USE_MMU=y +CONFIG_USE_SYS_TICK=y +# CONFIG_MMU_DEBUG_PRINTS is not set +# end of Arch Configuration + +# +# Board Configuration +# +CONFIG_TARGET_F2000_4=y +# CONFIG_TARGET_D2000 is not set +# CONFIG_TARGET_E2000Q is not set +# CONFIG_TARGET_E2000D is not set +# CONFIG_TARGET_E2000S is not set +CONFIG_DEFAULT_DEBUG_PRINT_UART1=y +# CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set +# CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set +# end of Board Configuration + +# +# Components Configuration +# +# CONFIG_USE_SPI is not set +# CONFIG_USE_QSPI is not set +CONFIG_USE_GIC=y +CONFIG_ENABLE_GICV3=y +CONFIG_USE_SERIAL=y + +# +# Usart Configuration +# +CONFIG_ENABLE_Pl011_UART=y +# end of Usart Configuration + +# CONFIG_USE_GPIO is not set +CONFIG_USE_ETH=y + +# +# Eth Configuration +# +# CONFIG_ENABLE_FXMAC is not set +CONFIG_ENABLE_FGMAC=y +CONFIG_FGMAC_PHY_COMMON=y +# CONFIG_FGMAC_PHY_AR803X is not set +# end of Eth Configuration + +# CONFIG_USE_CAN is not set +# CONFIG_USE_I2C is not set +# CONFIG_USE_TIMER is not set +# CONFIG_USE_MIO is not set +# CONFIG_USE_SDMMC is not set +# CONFIG_USE_PCIE is not set +# CONFIG_USE_WDT is not set +# CONFIG_USE_DMA is not set +# CONFIG_USE_NAND is not set +# CONFIG_USE_RTC is not set +# CONFIG_USE_SATA is not set +# CONFIG_USE_USB is not set +# CONFIG_USE_ADC is not set +# CONFIG_USE_PWM is not set +# CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set +# end of Components Configuration + +CONFIG_USE_NEW_LIBC=y +# end of Standalone Setting + +# +# Building Option +# +# CONFIG_LOG_VERBOS is not set +# CONFIG_LOG_DEBUG is not set +# CONFIG_LOG_INFO is not set +# CONFIG_LOG_WARN is not set +CONFIG_LOG_ERROR=y +# CONFIG_LOG_NONE is not set +CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y +CONFIG_INTERRUPT_ROLE_MASTER=y +# CONFIG_INTERRUPT_ROLE_SLAVE is not set +# CONFIG_LOG_EXTRA_INFO is not set +# CONFIG_BOOTUP_DEBUG_PRINTS is not set + +# +# Linker Options +# +# CONFIG_AARCH32_RAM_LD is not set +CONFIG_AARCH64_RAM_LD=y +# CONFIG_USER_DEFINED_LD is not set +CONFIG_LINK_SCRIPT_ROM=y +CONFIG_ROM_START_UP_ADDR=0x80100000 +CONFIG_ROM_SIZE_MB=1 +CONFIG_LINK_SCRIPT_RAM=y +CONFIG_RAM_START_UP_ADDR=0x80500000 +CONFIG_RAM_SIZE_MB=64 +CONFIG_HEAP_SIZE=1 +CONFIG_STACK_SIZE=0x100000 +CONFIG_FPU_STACK_SIZE=0x1000 +# end of Linker Options + +# +# Compiler Options +# + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + +CONFIG_OUTPUT_BINARY=y +# end of Compiler Options +# end of Building Option + +# +# Component Configuration +# + +# +# Freertos Uart Drivers +# +CONFIG_FREERTOS_USE_UART=y +# end of Freertos Uart Drivers + +# +# Freertos Pwm Drivers +# +# CONFIG_FREERTOS_USE_PWM is not set +# end of Freertos Pwm Drivers + +# +# Freertos Qspi Drivers +# +# CONFIG_FREERTOS_USE_QSPI is not set +# end of Freertos Qspi Drivers + +# +# Freertos Wdt Drivers +# +# CONFIG_FREERTOS_USE_WDT is not set +# end of Freertos Wdt Drivers + +# +# Freertos Eth Drivers +# +# CONFIG_FREERTOS_USE_XMAC is not set +CONFIG_FREERTOS_USE_GMAC=y +# end of Freertos Eth Drivers + +# +# Freertos Gpio Drivers +# +# CONFIG_FREERTOS_USE_GPIO is not set +# end of Freertos Gpio Drivers + +# +# Freertos Spim Drivers +# +# CONFIG_FREERTOS_USE_FSPIM is not set +# end of Freertos Spim Drivers + +# +# Freertos DMA Drivers +# +# CONFIG_FREERTOS_USE_FDDMA is not set +# CONFIG_FREERTOS_USE_FGDMA is not set +# end of Freertos DMA Drivers + +# +# Freertos Adc Drivers +# +# CONFIG_FREERTOS_USE_ADC is not set +# end of Freertos Adc Drivers + +# +# Freertos Can Drivers +# +# CONFIG_FREERTOS_USE_CAN is not set +# end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers +# end of Component Configuration + +# +# Third-Party Configuration +# +CONFIG_USE_LWIP=y + +# +# LWIP Freertos Port Configuration +# +# CONFIG_LWIP_FXMAC is not set +CONFIG_LWIP_FGMAC=y + +# +# LWIP Configuration +# + +# +# LWIP Port Configuration +# +# CONFIG_LWIP_PORT_DEBUG_EN is not set +# end of LWIP Port Configuration + +# CONFIG_LWIP_NO_SYS is not set +CONFIG_LWIP_LOCAL_HOSTNAME="phytium" + +# +# Memory configuration +# +# CONFIG_LWIP_USE_MEM_POOL is not set +CONFIG_LWIP_USE_MEM_HEAP=y +CONFIG_MEM_SIZE=2 +CONFIG_MEM_ALIGNMENT=64 +# end of Memory configuration + +# +# Pbuf options +# +CONFIG_PBUF_POOL_BUFSIZE=2 +CONFIG_PBUF_POOL_SIZE=1 +# end of Pbuf options + +# +# ARP +# +CONFIG_ARP_QUEUEING_EN=y +# end of ARP + +# +# IPV4 +# +# CONFIG_USE_IPV4_ONLY is not set +CONFIG_LWIP_IP4_REASSEMBLY=y +CONFIG_LWIP_IP4_FRAG=y +# CONFIG_LWIP_IP_FORWARD is not set +CONFIG_IP_REASS_MAX_PBUFS=16 +# end of IPV4 + +# +# ICMP +# +CONFIG_LWIP_ICMP=y +CONFIG_LWIP_MULTICAST_PING=y +CONFIG_LWIP_BROADCAST_PING=y +# end of ICMP + +# +# LWIP RAW API +# +CONFIG_LWIP_RAW_API_EN=y +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + +# +# DHCP +# +CONFIG_LWIP_DHCP_ENABLE=y +# CONFIG_LWIP_DHCP_DOES_ARP_CHECK is not set +# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set +# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set +# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set +CONFIG_LWIP_DHCP_OPTIONS_LEN=68 +CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y +# end of DHCP + +# +# AUTOIP +# +# CONFIG_LWIP_AUTOIP is not set +# end of AUTOIP + +# +# IGMP +# +CONFIG_LWIP_IGMP_EN=y +# end of IGMP + +# +# DNS +# +CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y +# end of DNS + +# +# UDP +# +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# CONFIG_LWIP_NETBUF_RECVINFO is not set +# end of UDP + +# +# TCP +# +CONFIG_LWIP_TCP_WND_DEFAULT=5744 +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +# CONFIG_LWIP_TCP_SACK_OUT is not set +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 +CONFIG_LWIP_TCP_RTO_TIME=1500 +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +# end of TCP + +# +# Network_Interface +# +# CONFIG_LWIP_NETIF_API is not set +# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set +# end of Network_Interface + +# +# LOOPIF +# +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 +# end of LOOPIF + +# +# SLIPIF +# +# CONFIG_LWIP_SLIP_SUPPORT is not set +# end of SLIPIF + +CONFIG_LWIP_TCPIP_CORE_LOCKING=y + +# +# Socket +# +CONFIG_LWIP_MAX_SOCKETS=10 +# CONFIG_LWIP_SO_LINGER is not set +CONFIG_LWIP_SO_REUSE=y +CONFIG_LWIP_SO_REUSE_RXTOALL=y +# end of Socket + +# CONFIG_LWIP_STATS is not set + +# +# PPP +# +# CONFIG_LWIP_PPP_SUPPORT is not set +CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 +CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 +# end of PPP + +# +# Checksums +# +# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set +# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set +CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y +# end of Checksums + +# +# IPV6 +# +CONFIG_LWIP_IPV6=y +# CONFIG_LWIP_IPV6_AUTOCONFIG is not set +CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 +# CONFIG_LWIP_IPV6_FORWARD is not set +CONFIG_LWIP_IP6_FRAG=y +# CONFIG_LWIP_IP6_REASSEMBLY is not set +# end of IPV6 + +CONFIG_LWIP_DEBUG=y +# CONFIG_LWIP_DEBUG_ESP_LOG is not set +CONFIG_LWIP_NETIF_DEBUG=y +# CONFIG_LWIP_PBUF_DEBUG is not set +# CONFIG_LWIP_ETHARP_DEBUG is not set +# CONFIG_LWIP_API_LIB_DEBUG is not set +# CONFIG_LWIP_SOCKETS_DEBUG is not set +# CONFIG_LWIP_IP_DEBUG is not set +# CONFIG_LWIP_ICMP_DEBUG is not set +# CONFIG_LWIP_DHCP_STATE_DEBUG is not set +# CONFIG_LWIP_DHCP_DEBUG is not set +# CONFIG_LWIP_IP6_DEBUG is not set +# CONFIG_LWIP_ICMP6_DEBUG is not set +# CONFIG_LWIP_TCP_DEBUG is not set +# CONFIG_LWIP_UDP_DEBUG is not set +# CONFIG_LWIP_SNTP_DEBUG is not set +# CONFIG_LWIP_DNS_DEBUG is not set +# end of LWIP Configuration + +# +# Tcp/ip task resource configuration +# +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_PRIO=6 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +# end of Tcp/ip task resource configuration + +# +# lwip port thread Configuration +# +CONFIG_LWIP_PORT_USE_RECEIVE_THREAD=y +CONFIG_LWIP_PORT_RECEIVE_THREAD_STACKSIZE=1024 +CONFIG_LWIP_PORT_RECEIVE_THREAD_PRIORITY=5 +CONFIG_LWIP_PORT_USE_LINK_DETECT_THREAD=y +CONFIG_LWIP_PORT_LINK_DETECT_STACKSIZE=1024 +CONFIG_LWIP_PORT_LINK_DETECT_PRIORITY=5 +CONFIG_LWIP_PORT_DHCP_THREAD=y +CONFIG_LWIP_PORT_DHCP_STACKSIZE=2048 +CONFIG_LWIP_PORT_DHCP_PRIORITY=5 +# end of lwip port thread Configuration +# end of LWIP Freertos Port Configuration + +CONFIG_USE_BACKTRACE=y +# CONFIG_USE_FATFS_0_1_4 is not set +# CONFIG_USE_SFUD is not set +# CONFIG_USE_SPIFFS is not set +# CONFIG_USE_AMP is not set +CONFIG_USE_LETTER_SHELL=y + +# +# Letter Shell Configuration +# +CONFIG_LS_PL011_UART=y +CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y +# CONFIG_DEFAULT_LETTER_SHELL_USE_UART0 is not set +# CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set +# end of Letter Shell Configuration + +CONFIG_USE_TLSF=y +# CONFIG_USE_SDMMC_CMD is not set +# CONFIG_USE_CHERRY_USB is not set +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/network/xmac_lwip_test/main.c b/example/network/lwip_startup/main.c similarity index 70% rename from example/network/xmac_lwip_test/main.c rename to example/network/lwip_startup/main.c index c9b71b6c..663fae27 100644 --- a/example/network/xmac_lwip_test/main.c +++ b/example/network/lwip_startup/main.c @@ -1,22 +1,22 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: main.c * Date: 2022-02-24 13:42:19 * LastEditTime: 2022-03-21 17:01:57 - * Description:  This file is for - * - * Modify History: + * Description:  This file is for running shell and open OS task schedule + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- */ @@ -30,14 +30,16 @@ int main() BaseType_t ret = pdPASS; ret = LSUserShellTask(); - if(ret != pdPASS) + if (ret != pdPASS) + { goto FAIL_EXIT; - - vTaskStartScheduler(); /* 启动任务,开启调度 */ + } + + vTaskStartScheduler(); /* 启动任务,开启调度 */ while (1); /* 正常不会执行到这里 */ - + FAIL_EXIT: - printf("failed 0x%x \r\n", ret); + printf("Failed 0x%x.\r\n", ret); return 0; } \ No newline at end of file diff --git a/example/network/xmac_lwip_test/makefile b/example/network/lwip_startup/makefile similarity index 100% rename from example/network/xmac_lwip_test/makefile rename to example/network/lwip_startup/makefile diff --git a/example/network/lwip_startup/pic/dhcp_test.png b/example/network/lwip_startup/pic/dhcp_test.png new file mode 100644 index 0000000000000000000000000000000000000000..1c0daf1f46c587e1c117dbc5fb524aa25a2df1ea GIT binary patch literal 160713 zcmdqJXE>Z~_y3zlv_y|i^yowobrQW3j1pynAbRv}Qq)8j(OZ;Zlp%Ug5G^`mbQ#^~ z!C)}6C%NzE+530w|GWKrwO^RynrjXh)_JaVuJu{pC0bus?G6be$+c_O?r5kh8(h0~ z6M6004I~jE{*LHy5&p)t>s|(Giq|TKnYZw7ZaF;Fd3x z!93?-(`&icHs`S~wC5q>kqT$xKVF=>c2kLEU^IyBMafNVYeEWs#D!VVHL?3oV!{&a zz&L+P^^7`%RnTso+C^7++dA%OPu6{O!D<*Q_K`x7h&}AjOB@F=@;}$zB#9KlfA8X7 z$|?Roe_%ZIO8kOFCU8!%v?4kWvG^va-Sa0jeIZURFjFDFetDnfv+l(;!#XzCn?BQO z>vMYo0}J0moo`tVF~x^msC{5)h_G?He51MFUNNm6kQ~PziMlwiH~$3N*mm{}4gd4& zcOx>wURQs$NZDc2NA|rId5a{sMhRKJ`16ApPhW@v(>Ews&Tmc;gr@pj$9>*=6z z$r4QH;x66F_Bkda8}!$9hjl#c7Uku(RGmXRKJbU*xe;};*R|B{f9_EmgJ6jPwBzI4 zVQdk;MPWG@2T_zR=k$T(3>*q-F~T`D*KBUXUQ8DKA0Aq-&EA^f5%h39BfdmVl-B$1 z{#GfPdHx=NzpTBmUPleq)wwse)jUhX`953r6%-T2qxDc{NVY`e;!P4tf42D}18|MU zeWwj=Uh`hFhO)tMF0@%V7GVU>P$}+h8KQfrUA($)*bARxA#~5rfitD^uISJhwPE`xNes|vQqLsgQ-J8aj`)Bq&O7i zOGazU_6S*Jk3@yuw*Bl!Bvpf0__kR^++dmFXErSx5~>P!9_CkNk$4RE*gauR^*iUE zA10iaq#n-asEeoC=}L)toFU)QIPIt3Lc^vwt6(Bd9j9rb#Qm7i0p(YQ;k`Qvn8=|t zzatF6T$K1;qUyHLWxg`5u})08m&1#_`2o3{6?Z1?$%3G{^RYX=M!y(^Gn_6IcR|on zFI4%nUTDweFGfu-5gx%`ykQJVe6B}Mb5$~n0V4>5Vc4kxEl8;jw)WS1!%Uz4WbN!) zap$d9O`lLSbiV=)KJP;^1{FT^H~0C)X@m93ivi<&z-aj z$!8fb#j`2!x_HL~(a=Q}>M5z)ZnE{ZZh4(ll>nM%s(bNi6bbUZmr^6}%6!4~7Izl( z#!2Z8QAc8yG3UKV69zT@yGH_>$-`V+Xc@(0TwbAc*1d`amTFT*zp-gX9ZUBdCtPCq z!ORu4deBi2&9(^F!*k(FuliAi63n+=ip7mV`^J@ zRdLaI-I*E!p-ClN`xI8+qI_6>IHo254~TzQ-cv1Bm|0lSM>ZT%#uUM*%i^4;y(|{j za=FSpSj-}{qBP{*XIF1ji=V&>jl!S7diqNwb=T{MA`>KMSt5##VTIf|YOjv9ugsvK zAEDp|2sRyENN=UKR5H6W8n;w-rRpfHRvpz@f^h$TU3?USG>g_ZXxl-Qk56 zV7K_kn_~rohyV{B3BQ1mMD7hs@eMa8eT(`ST}oEe8X}vmGm=!?lHtA5YgF=WlXXVL z61kx4hU2?V$y-W+^*eU;fnx8@ufuEUte$*A8eBfi;Z_Vk$d_iHcf}^ucX|;?%Bj5W zT;uA_(lFJa04|8<61KD;MxX!Y_3g3Hez~6cNy0&V^Oc=N&_czHvbKywq$eSKgm`z~ za877J@oJ(wOep>P?`?IB=RYuwsii29u60`?HvN;Bxui|OmWIivi*bn#q%@&)9K&z(AH0rJ3-T)FN(Xg&-2ob4n~6B z)?W7Z4Yn|4BN@LK>E9U&{?LtjgxNWg3#v7LL zZn0gCWiKm57>ey+5;Q!me?OMM1d8p5xPQg;DHHC`AozWuCj9pxsro3O_6bfTe6}Y? z!(r%W8VMT@=Y{S=Bcesxz~LJkTG^*a^}!;kWDe@pCNBzKWe)_GlK55Y4ue&Wc$3M^kSoF4A;=u2h6k43h1!2j3@ z%rz7W=R1DvmUZ#TDX*!vlXG|tz_$qk=qPipq*H{XQ9ip7a_Zp+8&RhnWJ-%O-82eH zjeOzQd=f#QeS>1$&2Wi$3iD%Z7KMT|O9NytK=arkuS`PU6hl&k$^FW{2K>4`o;F&1 z9#=PRa!PaFzvK`yE4wPmSX>X%B|RP~Ne`)K?qS;F5ci?o{*u!<3F)jcIqxgHtpOG4 z9G8_C@_Q1waLEzC(13*9Fzxrg=4Dc|gyBws;%+E`bzfNvuI(ls`?M-LO>!5mh3KaE zI1zp?uMdC;hA7BVV^ssd=}ukqp6#OIGHKccNUkp{xbCTA5yxt$vX{;sG(^1?{tO<8 zbX8V$9h*c-XZ3kYRT`&KnsdNR`3`R)qZ8bR#;~Jx@bMF`zJ#g%u%Rd5nOu$NjyHD_ zM+|14Ls2HX)pRe)nlfr@osF*cM@99&N7WCNV*zF-U@p5m=96dbnNmhI}#DyI;iq{;7G_s*!s`^Imy)BM>yy;QMV{2b5_-$>RTT%r1TM zWY|O(pW$TJw1vI?C&iKQBvWcc?>Gq9){6@2#8a`IGu204G2m)Dp4m&jsB0)eI4Jtt z9QdR;?Xyd7Tz_Yio7a35;;AD-nRe6UgU+$o(zGXITK@BsrUN6kWHD@_U9F1%0U>=Wq4j4 zQWrrC`#t9u5-(xxuuSK}BU>N=sTN<3EI$P#$KF;fhiVaEt|~ptW5HdYuv+!1^J?nz zc7;W_xNn1C{pnXPx-ZP;Z`StStW7EMAu}D{+U4usa>@)|$5zq)+PU~NpGF;}8xR%t z94_248$XL^r{uI{5lPGq6_6#rr239XkTg_~I}D|ABH3axaP@UQp)0}UvV*|VvYqZ6 z5ZB>?+Zjp`wa@3LUO-PECDmS}-+N4(D`t=8?*YLK)SpxN2Ah*D6ZH)C&WoaF?TvA{ zM{B9onz$S3eH5eNc; z95<#$=t9YLR+F86I3aE=Ifs6$Y^b3gN7<(3YF?50gq9u{*rA^tiRJL_gH+J8a40VeNZ^( zZ1?-{EsH4>#>2JTTYdz18~coo%8*)b#S@KVS87BYpM2@a7x7P?UxqvoZPWEQ=iz7c z@jfvL3iPl{*<2Z-~|vb$yX)kWSB=so$)dGVWWnS zbjhaK$`en-sZpxnC2u0~j`-h;^aEvV9I}|D83tdfxp5FjC4V%svO#o+1SvidEq=tx z)%f^B+@9RddznC41#S`Ktxkiz1Hl*ebp!^W;A|2qfX&<_FH)`j;h6>L$%x1dy|2V| zhB7{=?pyWM8UhrVqEd zUf_@`*-Othwl54<0%k=HKepXba%Q)*I@$Ls5}m)2GDyNj3SoI`*pG$3%6b~<1G4IF z-Fw|fvG*hA{lukM6N3ZZ-KnpOX`fP+sd$FY{gY9KJ8l5IKzVnN!WbdU9 zw8<~?mM@)moN=sF0D-TXxR(=7NKd;VOdoq=9X~VB_ME%>>N+Igww+w0me$>oL%U zs3r1-7G;Q6ZkNJeQ?lf|=DvPzUg92`!8kIJw6!(dv;N9%unar4CsCV@?Tc$Xl4qBD zfhcw9$Gl5I-+*D_6GYhO7dlzh80y=NFtZB9rN_opo%m{DmUNR*t4gn8d9P)S7Rp8!_T7 zHhXz_bqVY1dX9o;LUUar_vN*~V)o1jr=sT(y zX4f1AX11tq3mBn) z^j3mhJwa*s`9_U>_B<{ZGRhyaYBXT{mQPoT#gMjMADl1!7*I|E-Dct7Ms zn2bR#X*#}v0`SI8AweZQ6>N+{y;MG$i-H>;mFfxR| zGr46m;z$x?y|!vg{kSQe>U-(;y6{EziiHJAZ$xX1@FiXMHcq#4=AGA=M#UIHtgM){>{Q1A9`v_;NT`~K77loq zwt7351lctNdzKnRcxXpFX<7@MYHLWpeAxm)i+NJ(y{N$&l4OjhRc$f2gyw$9GAD}0 zu*`7|zie?(`MtzXN1b&d+$^&@p-+sAEFLbXd6S5Cm<(ur^Q|NoNq5Cm&ugLj3S&t_ zv-H$r`HodtLD_G#i>i}5JIIg6{5`lou4ICE*gx#n3ZUdsmWp-{%TdI^K^2HP%TpX# zy+Oqs!q{Rn@(pkpI4&SLE@#@C7L=1tszu~@G4G^3`*o`#h|~}huB?2SVMz(msn7@W z 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 L=ke;J=TrU$RnGso literal 0 HcmV?d00001 diff --git "a/example/network/xmac_lwip_test/pic/e2000demo\346\235\277\345\205\250\350\262\214.jpg" "b/example/network/lwip_startup/pic/e2000demo\346\235\277\345\205\250\350\262\214.jpg" similarity index 100% rename from "example/network/xmac_lwip_test/pic/e2000demo\346\235\277\345\205\250\350\262\214.jpg" rename to "example/network/lwip_startup/pic/e2000demo\346\235\277\345\205\250\350\262\214.jpg" diff --git a/example/network/lwip_startup/pic/ipv4_test.png b/example/network/lwip_startup/pic/ipv4_test.png new file mode 100644 index 0000000000000000000000000000000000000000..813c88d5dd7c450b5a896325bc48023272cf0a4b GIT binary patch literal 299337 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 XV6x@zI8zPs6TQPtS*ZNx(uJ%i6wyOo`Jk> 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%0D&~zzUQwi8S>4j`g;4NAO7X7LmCBr88 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%0A&Yjsa*Hm&DO_oF1d!0;|G$Y;*FB@OzlX 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 literal 0 HcmV?d00001 diff --git a/example/network/lwip_startup/pic/ipv6_test.png b/example/network/lwip_startup/pic/ipv6_test.png new file mode 100644 index 0000000000000000000000000000000000000000..a1373011a0c9d6ca1192f219dd49c997547a317c GIT binary patch literal 254646 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

(eY=tW6 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

L3l%VD69~6NhfnfWf~)A_lu3?ecw%I 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

6x=#+Mj+vByMm41qo;?i@deJ260|5=DaF(C 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 B=Uo5* literal 0 HcmV?d00001 diff --git a/example/network/lwip_startup/pic/lwip_probe.png b/example/network/lwip_startup/pic/lwip_probe.png new file mode 100644 index 0000000000000000000000000000000000000000..161a2bd48fa544932252825ec705056b83d75734 GIT binary patch literal 147084 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�k)GEQW#yi=VNIen&I7P=CHD zo(JTvJGF7?=&7SeQNdLNm6N8l#{Ap}KiCpU zBN~MeYt&a=5xp2+4Ba%X3(G&{)muC$ZAxXVtV&v380Y=(b4W)DaxV7W9P^ZB8PMnN zlQf3{scfz};H20&qFUeXGYJJqV34a*itz19gMv1B`K%0|&J|6D26b*HoaqDHmQ~FR z@MSKY+Ui-ly!02ZTPo35Jk8f>jU29Q^ky_{>OzY?&%L+x{m9vHlh`;r?`{(z%1ibZ zV{q!MbtMUH?;A|MdCYESI>4=-)plrMZmQal-OM9tj#A&lGD6L4Lgs)Zc{^N}yD75I z!ivLFGj!I}A^6z%*bOD-%B5=5TGSWwcnZGoO!7j9J00n*=n@bwzoY?Ny3dUE7NQ~X zXGCu|20Yxv>nzo0F`w;6P~n-r`yKO zGV*?0YjouK&OAMDgS=@oK2yokaIPU0F2pxyTx7ate}A9+3sduXmySycFK3nTy{CR& z*ks_Ffe@@%IyT#VGH&XD!AZ6uU)Q#ngc8Z1ON~Gf?T)l~w)wAl$~v(j{G+q4s!BTZ zy5D=gULNn*HhbcypZhD|pGj31A?84=uZ476>0wW}b1j4#vZng%xnMSQGCD>fE>Zbt**+h5S!0Z~3%t zy5GbYBFkGiub0`a+s3lx`!MAXq)pk3f$_)WVSQqa<*%MA?+TN}qN#_lTN{sto_Xa5 zukeJQI<}#ghH4J9+5Cd|ykJUn=wZj-}OZ5`!jEdRXOP@8i{t0cv&M8YIV#YMK8A1$7xn~ z_Oo@HObQ-HbvGyO!3%HmPcW19S>IMiB;8Qf2ZEM#!RX8zklTPO8G$(wt`7f!vD|DI zY*VidQ&5IE@(oQEiB!FXq!4Eraw977Yhqh#b1IT-y9Nizd$JX-oMrg@kCax;!SiDw z^mSi)4{_JurXHX&rMXD|2t@tz2{|j2RLhzKb&ZiLIY^-kwKN=kW}a&nPfP5DSFXuL zYEKA3$rp`ylVrCImS=Zv|4UCC;L1yTtoxS7bhQKhaI*(+cizzYT@>x>GY=E@W%q%G}57bJ?GU&U?EP=4yT5yRWBs8a;y#Ys^!s z!5?C@6hury#+G1Rp5F4rkP|HiBcty^t4RQ?>XT`PRsQJRy?m8d0PSr`0L>$r@U||T zlp*&YhCW;$^U_L5z6MN$BNMdbf=Vuctc72xP03M8bYSGS-IiA8_TSw$m6IUJqSeI0 zix%dkmVyGeJBYq`ji$Kf7?@@EN@&*u=9Fr|quUe#TF5ig8Hzf~X>J~>IH<F$X5JyDFP{L0Y^DWKXo{7k7UL%e0)1be+F6jPj{41FR`&| zP(jimE#FDlfDef{jtG2q=h=?@L1z+p>q9kd`l4CAT##d{t3VJQV9a2bT(%49^A0$v ztOfy!ekW<5FR0$p$f5DJ1$3y#9*1NN9<*NSpjDX+*LGzvEK*p71r!oL2+1wfNMX05 z=@~^xS$uLAdQ*I0u>QrVpFMk8iMLSg%g#u|Z9ngW2ilm)kQ2^`H^}LmCW|(!ciMZl zv`dFH6ofPuY!V-Q=e_i5kcv-knIXuo6y1 z9j6*xZU&?JPq=W=1yG2cYAnD19@{iU*Dm`=s;t32bSU?Xb9D9_!;ip$Mm$>4j#8?< ztT4ubx-r9D4N$#|(q)Y+nu2N1h9T+liWYKS#syzPogx_Z!2)x~{R=pbuG3^dy%!0X z2r0g2$C04>L!YLWzB`xruEo(fjzV_u3Bjt{9PT;bOMHj!<6HlE!U~Ce>OFsQcRkMB z!gtZ|pkb#`)%}Ek{iJNpf(GZvFM;JMM{d?Ttom66I2V?8U*+>I(_;2U|Au?2-&NIR z`KL|mua|x}6N>h^>}C9N%;aEAZh4`7-t9nO#J5dmpiYS)3)6XaAtLf4=2=0|_sl6= zbow?5#vP19ENCYCBz=VdhZ{o(Kn>gF5*-6?vh1e>rG1sdM5+`D$O}&$J}1eo1`ZV5 zup7;v&|lQSV{Zy8qLbRVi|jG*mRRMWVC- z@Uq>WQ6TW7hn5oEezIRWdQC@j9WZk{)w=lT(mH38H2M=3sLM~bxN+HXgLjhR)jVvWQ{+`LFC)ZwN2roWU( zN<(>fMi-;D|IQlr#=N>Kg<&4yk-}glks!e%GodAk-P)wc?QXVpjoY9tB>EYi$?J&Q zPAE)$Cg#Hd0`gfBSG6EqgDn!I9TOKF=G{cAulPxcG9fZId}YN6QrqI6&xLU^Z7PjH z(t@*fJxYg7a49ceIz;xE_h`@7kjsuK3u4O^)D32sHo^gQ34s*yJU+;gg*|=KC$FI< zLrS%p8*Qb?H)P0^3vsOruM%!<=Y+{{Ke3qWtu^Z&8t6yf*pO^T`zG}jK;DiPkx$TX zi$^+~Qpq8-^vb;E6{YoP`yn~(GGs3F^bO^>nAzPM2u>Uo#1b=2Juby`bnV;~P!{iE zS)`Te@=hTh_5OV^gmnF)4#^d+I|@C5!>k;LMq^QWUYx-i}z4SWCJ(HJ88hb;ntkST;hf~+bZu` z<}CTHo6_XUKb~pPa$e$-tL_}Za>U3Ri(7I!=U2FdV$7K|L(%+O%`^T?(U#2%(b$63 z-~Z>4@?bAft8r5)%a!)E{k8T#L2yn4S%sEB83RG<5BkNHBx1? zhsQq}?>`Iti6)b$dV+agTY)w7CE^A3Vt`&G(bJ$dufLW7V= zwUhR=8*XkXAD3bNaCtCkS}A5hgX7Onhp7APN7&~-LVh(P$^ivv=)QlJshBqxAlua< z*Z|~TqK>FAVkH{M3vx*J1Cglb#`iV5Fe^@Fmw)xhx4bYN7dk8BbI_ayz_|ZL@MKl( z#a}E;6IKh24X25r>FOXA@*YljXrf!B$t+M@6OT+{V0GDlr@!+Wi+cH+D|`7f=xnC! zk;MIRHvqDu|6(DP2>JNn*5XTAG5BVk7e>|dp_`~Utf2l-fOci-#OlR_haa*pEMg{P3xz0+W5az-aHaz~y3gPeytmH@8xh^-CwE1#I4qDO< zxIP~|lO<~XV)t+E?#ijXld{e<%6xSrFN6=g8LLG;v6nHN<7IfiqcX32T7PULxlNGP z?gL{`$8e`32d_8>F{KJ#Fk-Luu7&MsY08)7Vle!~eS_boR=gW&HHql=B31=0ML$Xm zC7+T&j^$XrNW{Sb(?*@%LzNrmj@M}MEBNw*bpnD-lR9Bqr>@1-iy>Us6MezQFnE+2gup}g7? zo~^#GebJrIo89NKKgBWAdb~6slCsf5B$aqdbD1`HxnV*D-QyGbAEU9@ z*u$jiq^3WSRxDAyg*p2t?_5H}UWFp*C8VeJmG%Yl!ux&6@i>)9? z$s2u5Q}veq*+NO28wcB5nKMR+u!ZD6YU~C6Z5lAoK{GZuJZFrywpKsUbemzfo-Ti1 zP!V0k#@)2hGC^dX7kd)5G8@~6_B(^&dBPsbrR-T(ySQZJ<+avJFl`{QE;v;ioVs&G zR|yFs$`Dd|_^OL`EYnFURbmwpG1KXgdtVdkkdW+1gp-$--In?xGF zAVeDT5*$Am5D`8E9o+DPOx~XmKDC^nE^Pt_A%?Hy0`#8fOhELwJ&8?+GtRXowVo$y z9LssVO0}3nkJN>zC#LefXKfGD#vGZA_cF`Xl4GVn=qMdyvVK}$c=>wl2<1{19wo0v zKOQ98mI?pm_{t`rNukX$nhS;MuEi!@Kt}6IM_Dme`7Z2!?Kr1hf#T!^s(g(?P2Pfq z_(sMykqNA9Ss_KgY^G81I3OB1O1iY&-BnW0-0SFGi(5@k3 zSvvJ2VG%R^)&=%A92~1z%aNUUJgo>hw|EAV>`o6B<@BE^lO5`XqGeU?csyP6-IOtK zD-9g650tH4%X0Z-DItx@^%}poE^x=_b)5bpsR?-bF z--RDWdViPVp5DjMxVqF6TTL1Je#w@PR=!%nvadQn!mSXL zVd8RilJ&;q9MsHd6xEU(eMj@P=pz*^fPPK7dGq!rwZtP<_KB!d6RV<@p$X-j%R_$^KO+uko;9o?3t& zAw$@CJ7q@y%jp)2@eiS$6f2`bZuHjJ8(4lFf zQk(CcrpOCeM6*+s;ZixVVJx!y-z-@@;V%TYjMeoLe%$MTrsjS6&iPx8ukSS4&+?o6 zxH5!n?4_LX(aSZ&tshptO`VVttSG_5DyAbbkZg&Ul5!~5W&$IhL~t3>M$+Z6$Czgv zYN3nKwJGGpO)xX$eS)0zL)RsYqxt(Bu|4Je!58wJs0SXc!lPO)AbEZMb=J*=+s|j` zf%uBqH#jpeNOd{UrOvdUuZp$t?Z^M_+ayn(k-Cb$UHy?Pl`jg%+0yy_B-X$=iZPPa z6pe;gfgJ9R_U||&-3Zr9p1^}th56iazKP6gG+I(3IX>$?wwxy(%MrSp^RfZngCYA% zLN3Dw3t{|IB+0tI4N)n)6_1P3hr_4GhAoi_&Gz@ zNCxF~pWPRECQyR{unaQn+Cto~OdDQ-&}3*Y6elz7I4A9=kn#)jGf)UQ32Wt`(l6`AiCKiw%7%Z#JdmWEdmiXn7pSVio#X3N-5b0Pw<^_x)}17@$P z)q9j3uA4y&;u`aA{49-xsH&Mm z>-wNJAf10jKW>@u=y<@wvU!utvJs*QdFxo3F$2~fNG}qVUHvBvG-Uo|bAtb0HYetP zu{mE*|6_AP8LUD#Zn=+F^8u%=fK-sRc8~}+Pdl!zn#7n6>)1w;8Bbtz@D(wRlyf7> z(hQPI*oq%K3?R~fRL@!> zlBd@v9q&k7Q~cT!qkF>-`0)YrV{f=}h(*TZW=ogcZ3fr(7qrrF@|iR^`&U&vtDb@K zTlNvLVe^<|B)R}-XcBy+q_k>Vp11Xan_0PCH7N+7!AP!Tczmxsg9pEJl-B$zL9EXpJp{3 z%)B*j<*}jbmrvoTiC7i*s%P^0-RFDotX)%BI`Q?ZD zzS_V(i6on)=kd2*q`N1ot{ohx{P`=J;hz=kAFE$ z-@3(uSI?tt!zu0B1K+g=wWtzHqPSz~)K=4Y4T0g+0-JfAM$F!e<3&1gsZ&}=2`Khc zR8Alg>2=4NFB}my-_c|ib&JdOlq%uiMR1zcIz}!&3D1|_wDMfyfBy=H?^fn4P1_8s zJ4}JL;!Le`Yss?|A)L^0h&|kevl^9rYHwHc0m&NQVMr^PwOMnW1MlGeSN-k38=cL@ zE0m=k24`h0`N+EuR}fasod{BoK4%Soxda)kZf zKB0cZ-;WD{yVwHQu_10wcf<5ui_V7-RYrL=MP7-fQ2 z?#lPRVEoQ>W>Qyjk{@Y8$UrmZ`p^>hxKwRw)st^2E%>(Y91*R(x))0*R$)gBjTNJR zo3vwT4?uCOCoLG;>PPO$4U3#3>!ydL?L*4HK5>$HWvNy4q4ZWYLUzJ`VoE6Gp}7gKY})KQY4+}|yQDB0Zjlwaoqz)uLsI9f6P1FvEJzrgDjPuqee zrxN5R{P3Wutvx6YDt3=a^yL}1I{Z9!&Q}pPS4nZ{O{GUF<%oWEs%4G<>16OK4r`A1@E?OOAIJt&^rmN4y$bS<#})t?~LFTM6mT{z1LIe&P6 zgseP}$z87%a5+UR)+0Yxau&3Fm+!rkA8`yYzXpX%_S3yjQ{C3) z@P?@vF=5g^8`xisay><$VJ6n>rydjo_9tI9cu%4WyFdnop?$AG*Otx8VcPCkd95(G z|%S{VFB5ka9mUb1>(n*9Q@9CSzfFcsX|Nx8YV46`hP%+f4Uyv z>Zav~Q(a5Z_KV1Y_w+)Z>~3_P*vhCz3UK4`&?C3rLoVI^(KSj%Y4u<9Mf;NlPDh~f z;)JN-wx6`C=ZfP@0=eeF%QsGL$8ekXJw;#UgY;kO%`-63YG}jcF#9_Zwp%Ag`USnh zD1~9|oFBG#_p9;pRR=d6#PB-4Gdg%1c_d+Y&4=jn=1oj;+gDqy8!BuX?3sxAT6jx5 z`I5kx!AT_|o{ditklXJO^PNc+DQeqsRy}gT@mC!)Umiw%6Z@XO?gB#{_!2cIqO*{` ze)J`@ozF<&tiC4aMi2?k3d}1o;?PpP7V^N+c|9V!BHf&*6l0A#(IiwfpH#UoP~z8{HJ$E(<@U?H}9mDl8(L5+VnxPtN(I38see9SSpOARUdXx zo#(6W&T5svu$9|dmkUT`IzqU9b5ZB(&_eN%(R48sA7!*JH$U0{A}yTb1NXWA2OoXL z`HPRND0wQltvvkk-2dUDau6C{q2m=r9U+D(p@lvEEHi#=7Pt1O3kO&x0>Y6%lP{po zcA1r$92EXU7M4D_#CBy_Zz@AYLpyWj1a>KWs^Hh5EM<_&{88(X9&LRBmGG24KE63_ z{TldziBM!$CjW>)Im2osL#lkqAn%w6Qf6dR>2TPBobC+-ANKyV`{JHgl$#}%(Ng%~ z^0S&4i!AeJd-z?U_`picn6&P%YvGx|TfxwF7zo`0Z?Q~@IN{ZIQvw{7xRV{)o_=3= zItBcd>JG$5J{=-CVeWXk6x9TpJe~qg3z0Xn4g=NFmDb{O(kG8tNlDaS@k#F>s>@-$JuHWW{PeI-6 z61nM{UVDFoUsDVTsGr?`_~B~c|8K1E{}aMY`Y4n6Fc!7W;kiaV=SIgg{`*SsFgl@j z?%9`0QY|5R&APSd(&fiT4#t z8MwK5XK$L=(QLw|LyG{U1{FevI1Xh!=@StmpNa{no!$?6u6Nv&VXGS@9t?_i&kg*T zdpyHzD)XtbunuWz5yAWi9wJe)x0-#QH0eWQB3qLVB2jVK_VTG;RXxXmU!K%Hzpm1} z@>RY*KN0R4xSN+sZR=!Ga^9wjt7(fYlP2YtF==O1bmF*ek}d~<&C$_{4A7%nf{;)x z``mM^@-xW)rTl=WhFIXz;eR-AzU|X;_3Mco_K75l)Z3S$3LuDKQ8`UODm@h6sb>jK z&Dd1Rmnzzm`CIlm4=1o3* zWXjaCth;&Yk53h`=#Xi8q;5;3@JU*YQvI|6UgU70M`Yiyj7=5)6i$i#uo<=_^={jg z7uBnzlw}&gDw1U-;DlidbH@!62YU;Gn#u6$cS&h*enuLO)fSGnn`M$`YX$dX2TLj> zmDfc6&vkxelsK4Y+bO`et&7dXwmE$GfqxE3{prmDWB5S~(J33-i3WS=QJ<_gP9{30 zVjC*gha{<@R!N%mx!bu4v8t)B3_+ztT5JdlcBSvP4X>y&zR(y?)5_B{ELbT;v(6{} zdx6jXhO~cCM834O1YF!54bFvmD8q{tp?lrQv_41gws=^hD@k@Tvj5s}?a>Pc$}oC% zCui{?C}L*DxYqwcqvC_cg>%^GJ@&(dtpZZp49mJCZ6~@77#|Lv_>i7;v(L&nu&q43 zJtWr$k!;2d>4IX1hOvO#R5sH+GdfxSoOu+ABEqG*7|iPbLlFf32Sr%W*O3O_1&^G- zmZ$5rT52UngY!E=gds~QK*}pquA;m&>XSfHiZQJ=QMD!ZG)4b!p#f%Yfr)OzLg6Sj z+8@Q0Q^h*gRYPTY^9gQ#tYh{(dok(MNEWT2d-Nxw8LqNIVS-DPMw4I4*BE0=(NmTCZVw3pCDRcv& zcs9L5Jz-X+d=2KuGn_?T@SrAvw)=n`9p*rhUk=0igu21q0F|IwgG-q8lSGl)i_ou! z-_bez1#0y${&(-cjl&|XG)vY5Vq0dj|1V|K=gsDKJ<%wBjsCb$AZ2Hz7Z(G%0-j1a zV>N&kgaL&Fntvg|RPPRjjHqR1$4C0Zxbo5N$0t(NbrniLFAzm>3dv#N&+K;Gs8^vX zq$*?AG>+reWq=Km`ztHO-SIHlmhjSxl%nF>N1wokW!^|p|?3R ziiW&9r;AEqUE?y=EiikQM@y{fLmmm5X)XndkRO^pL(eZ>2Yyu@%+O&#gjaa-D^1Oo^v_c*Dzt{a}!HH{bM2k5o6ohm{^lQa#$tGkM`QQj%?PCSFQOCBMTAFvJO& z<%`<;$iP-gjYkgOgc|9i(aVYOl>Bp6Z%Sd|P`#BU$7`D+SD1PA!}&;2^!%c^$6I z51nlh%vJP=gt8qloeh%falpL(a)b2nf|PZll=;+xrQ(oGGe)1Wk5TjC8V&BMiVLBJ z3acYp+lmvf^3L4zL|SkuK|xV9bcYKkPr_WGt?KK$4(UcHZ52of5qQp|@5@ld=pz-d zC>pryCz{hicSr*U8oZz^7`l?=4Q1{MUT<)2p1Vkb?h(+&_>*ftV1l|t<(a0EsKYU6 zwOZrLf#i7Y39S{P@IEq0?j~W(^^9NEl*qjye7`ao`m&PNr3M=*2v#_!%i7>rW2({~ zTZlfp43-BA{OZQ#LTtwxKeX=@aTB|D3-Lo}_r~zsvo! z?uzCN2n`I#VvauGcNEYkdN;(87U9EP=}XA68&{hO0t}#M+FvI4=S9pv;SbT|M|%B@ zyOlHBz}wyV@pm6vbwD~V+Br})gpbyS=6K!5^+OOb1iu?`ek51_%d1gOXK*v#J^oLG z1EL$fQ-8vsdLP-#MyANglbT1; z7LT(Vih(o9Bv%ARCIHDCqizm7PfI5eu3pYNJ=9H?dG*lls1hq zs5CGe?_EY)f>kHs#XXTGbV#XStNCH;TUpC?IFh@pN|N+W{sO*t&_CF56?C~1dKeI; z(yxnyrMFpk5+1?T1j!Xdpo}SS6biAQ8K(Yq0+(yos{SK|Dw9j1kaDsZ5bD++F-j6} ze(;PK^+oBJ8{MQ*f)umvisI*%8{Sm|69@8I$uPkcmqb-Kgtmtb@#T#s^tFbJo8gDX zim7u)is1II2du8vP92-aIU*WAZOHJ9Q!KX*iu-UhfC9>QpU!*;@_4$j!oGTN{w%sp zf`9zngwuA(Bqc=uApyVJ^BHSZi1UzC9*s2ynfa2K*`Z~tQ>bVs*B{;>cVj4a?wyni?jAKO+C`4Bc77E~b_HViUkS;C7H3vx zrl{nF4f)})T%pg8iKlo_L_{TQ7qwy!)mz3v2&$u?1xFRA=Y}l+YeCmnm><9Lx)6Xn zZ$%T6{_wekb680=Qf>V=V`6AX!-r=_Fxh)3gwS!v+rN1fPBNoUXi*X7ib|`%Fsw1E zxEXi!2aPOryn`aK6)h_sZemBkm81ud#?T#;O^Vx34A)6mh#p_8U()kXMWSq7O@-YZ zp6LoZI*0|Ji4Q7lJ76qah!gF&!WO8063eb6PR+_eLcHshgt|9{l{ff|a=)$|Dabt9 z&-TRHo%3iC-%g6h8Vk@+_DJ4(oJaY;M|xNr*GZpOxz7#wbDke6!WSzuiEw+`c`z$@ z$<07<+G2aQgnKt-GPEVnHy7u-Llzi>UFC&gwAN!luyChG?N?ypQ`rd6 zssdPd>v-T)WakKMak!9HSqVUhi-Gnc)=NqJ?I2;&&&iZB`Ej~DiI&iIYlke9yV7SA z4%%G`Cfu>S zX&DgwoUiJZKR@-^?Kn*>p}OOjwTw{?SJ7&u;d~9w5n%)P5$iq9WDEB66RNWTeJvxz zS?2F+&ipq8?|C`ghnhP`7IzNcO3U494lqBrq=CONT<*w;wyK7Gc|2G=9kx58itSinkJl9cL1oR#P85X9o4Ga7`bWDih17hyzds0)P=48^Hc@ z9Smw~sbW_GgdtE-2e`&9_>US9I_W0824PcA>}K98p#Xi4OwxhYh-g>z=Pv3%godpe zx2n4u*J>bnWSB4x_17o)X_gA?+OAmYgV)}by!@8OKiJT^gotC;)= zw5((i($75w6cAAIcz&2n7e4sgW5GF@6x%CuV`UHZD==X^Hp2|*V=_9W-0p@)k=%PS z?i5cvjw$Q;D_e8zXR*kNXY|o`f@0V3@lNJfe>}=hRWm7TdcOWldGbtrBntjOFyofw z?F-%}qj_%kVT&{%DenBpUY%1tux`IZ_ZL(L<3O|8kX@vU)=}_dD$VXuLf;Fis5(5L zc9CLlpFw{m;RQSyv6MToE>0q3FWy}zbjhb)Bc7A;n`w8$EdJ3`_`=!myoO%2$G42` z(wocMzbzD7d+V3E?N0aQOz`8Z>0`Q^m51W}JMTu_WqO~M(?M6~Xbl?IeE}#bfA|&n2>)D>xkzAG7~N9fl@_1V{Y+twTJ2b_j3KQ}dO<)KXRO`h zQy~0p_c^GvNQOQLC-hE*D4sXuLx8zY5XULV`%Tjbqk5Z5@6H*3Z7~Y(hMF^1dhCXO zXK_G%O(JBa4qLjt;at{p>)8SlFw&Fy^w@!gPVq_Cjpz=4WzsF_h|ZchU)OufbAHCyw^9KOZ$NU0r1mW@2l0I2$Nol8v5P zf{jF1{;l|5loD^CT{&s_{S|MEYlT6 zDwKURVlaO`$mKvqs%b4T`6D_9al2WgGvQs0G3Nu_d1NhS=t~AsYKnN~Dg9dlE5FkKs2o{{iU8X|*d+&4ZoSD03 zty%XaubS0W)%E*4UwOV_A)OI~6qNbcf2gJoAR_G7XJ-`6zaJ-;+90n!K`<_KZkE|t zFLpjLYhjf6*$GR#;VnPc%Z+8jZ%9o#9U!g#9{RS6K>iz5^{!Z$;e$TDyP6cij3j-z zI#V{-paw_#kPsBN&)!sFEIaSr2l(=$2}&OFA3ZQM46l;naoBd}(NvPQ$k%9rsa~)~eXaG{>d$C%Y^6NOsDE$+_j2|wo zF%rQzvy^+Eep+0U>uen__x66JiJKPY+s}ja;Ux8Hds@?0G{5ge>I)rV<83c@=ir*C z4Aqld%s#^$v7La8~IuK=bxl+6|dC&#KC)<#HKv7`!AJ~<``tF$j#=F zl}Wy@UVkI+zL@8{8W|rPsrGs;N5AS(eHpxs(?g>gP#Cn@2n~O7| zSz?>BeAHDOf-QWJ2V&uWMJxsO`aol@y$IQnMNwp+o4K3tj+5BGhLb2u-iebO>D;_$ zY0(nmu((HfJNOpmooesc0C*rzgp_Bs-T7Ui13Badf29j2YAPOTD}_N26VV78N7J7u z(inX!e-X9)hU$8_GvtP^GrZz~!7aWmbg`BPf9jElRS{?aG>Xr>U^tIy4;AgVwFpQ( zFz)#wp+2VRkSqQ`;y?Y^fO(QE+#+efL57mJpT~H}f0Qp;;zv~v{Wi)^|MseB?hJci zTIg4`L*U?P)y~l!&-`vY;u)H*6v!gm+LQ75Ixz#&Wiut}=4hwTRQb1%0EV^?J5oPf z0sm_6185u1od`*!* z(V}&g5tzNl8+2P7F;lMTM=duje>A0Nez_H<4}?{X!7+a zaI^(haX;0=!Rr*F3rHO4^v2<%wP`jkpblL!Ux}YpqMO4b&{Ko#;C6iCVq-xWxQ`7Q3A~XF zlPgIg-t&rod1}gvpI0!aV*VoVd~LjeYqRbB840W zSCoxE@w^$rMavwJup|Ak3dTa+qYGH)fBwXX|0nCw|5grorhgz#`M-5E`QL)eFnjD~ zqK9p;r&jN5mGVRIuu%ERc-Y?3&TaP(GBhIc(b_tUuzWq36IM%k>Rqn{{f@t{&78l( zvq~ee@>2ad^gYMsJMdD??8E@TXI(mmc8vaLiOK_VHGg^1+)#&g;&b@>0C{`B+9lg@ z)}dDyH#mzcfc0#AVM*)}A%!JfHI^y|DbEO3;4!ObMXmUsyq$KipONp9;<{9nuWXd} z@Iphqt@uL+-K%W+r|^D1?72CFrYRKj&zRkAuBHb=D+s?-wd3?ABP5fhwYWt2cv%1+ zJi>f0y+sdo*<8BF@AuE&*%_4u4tONEv<0aYu;WY;!Q7QfGSkT9a|fDn1>)AX_R`KJ z5zP0PwZePu2~H;oenlb$j8&ecDxv;rsi1V5?}NDwp1YZfdmRBke|H;blY7Em{2H8q z{}Qn&9T!k6tUO0APn{LK;)0eKv2OH*Q48J1?H`_?FwR*Ih~sWgW2vNG28P6^$!7V zK^yuB=FFfOR}>G(yO5q)M4tQ_R*)9_T3j6YM`Af1J}6@Yc%5VRr4>}Cfvusph3WFy zp;KU`s?94gKwSmtXLS`792!MHE-gc`=_XQ~dQKwZpY1>?C zGvMKGEYgx$8DSM zD17up@b-(8)8MtB!Z66|Y8<4B!2gSONiCsbD^u-DqyP3HH+5Vg1;d(hTE0Sn=Z6el#tF32DLT9;Skv`oM}or}(X(md zbjEWk9Am;Ohx#YXyZUrhaMUs;Hx-c}QuvVw|GJHZ;zo&;ns~u`Xy{&QgsskgC-rD` z=VrCP559MWkvcG`UGT-ASQC__hEn7qqE(`bAPhj?-61qcgh-Iv%Tc?*d5ldZ4Ex7w zY{3n=wdT#VLw5#nP@lCh)KJa;6e&wnWZ+gmh_jBUME>K8egN}La_H24y86f`N7-2 zdsJGC-r@?6z$hCgEjM%=p}AKmOW92Hnr+r8h4eC4-6r#}A1}3HcC&-~ zoC&(83;gNgpH&hvwsPZBF0#N$A5<^U>l<18*vq7!sQ6lBQWRdKiZ@CL;XH?y5@|;= zO&3oDy?|O!*om5aBqd#8i&6c^ReAY{l;-^e2QUWOGh=)K7z2F*$s7TXD*c_TbNJ+n z%7Dj{%uZdk_0>oDI1~`|VUb8Y-1n47m>E?3l*L~^MU=pMuqZ7vPPF0bBP4y*>j;tX z3`e~8hlX}<_Puorfk})F2nVb(ErulzK4L)GTLDfMnA)Jo_7>=A|Cl&2dU@TukQ-QQ z7@iB;^mWqgcp zp`7Cl`d7N2X6HzhAHFyt_#x1ZQ?l9(MwpVx*5`Ct_>(2}3G~$>-IfN<-V36H@u<(O zgweR+^C_$bt$$Q>>{bO?jsjTe0=C*%<@0E~g%>$9Qtbbgz z$Ws`{g(|;2(OS{HOpP>(#DY0ZOMazO+eDZflt$a`Jw=OJX06x_gfhBd_RlyRT=a^Lw{v%*1DR^xv(e* zLE)yU z={)TpdHoB_0t0^znKRW$5;#4|Q$czftN!wD1;+ga)mh)Dml6OS5+)f7HJxE}wg(a^ z(T5b@c$d?eTR03+Cyl4h@wn>WO+xDRptz8$a`GAuKED3)!|$nLEV!Bd!|&G&>J>=+ z`ImKe0*Pi{H@lqOE0kpcMK87}}$ZFgOoZhKEw*Zb%M)o%vG7 z2!_X2;}maP^9MZEW*&yDv?2;CyV3-tJn;5ZkUuklHlab&KXAX*4)ZWc(Y});r!vX! z{=l4{{zZsAxjC@H3B?HLoWM|_A0<6y$QakShTcw$nb%MvKX!#3GM<@wOHzL;MSU{W`VeZx77c zZqn2G+ohe`hdjM8tUvB0?8tNlWZWAC<=m!Q_)&{p9lB+~>mIAXeOjJ--`Lpmk<*$qO;6nZV{CrIhtyo=r1MR z<5Z$Q>12L508h3+rw$1vjG#;Ay(i+GQrdCd{iXVGg5DrZ;zoG0Wo!bb;~m6kEbWcR z_6F~~!_T``MVXC1%G-7%u=GibL|o(nR`XJ-`aK&tCK2Vq5M66RG+U*AccQ-A=EF3$3V;XNkHzeLuX)Ih1FmCx~X)Rw!&mC{ZozD*!Y z%_39h-M$yRBCM%0pcsWo|!smz6u$hf-5yIPj0Mzy;u3I#901ut)Q4Xp_a z9~_3KNK0pXY@IF(;PGl$6=;HGT&39?7Y!+mxA`e|>N-xkCjq9tk?xOUtaqHa-h1ck zXXlFyHx1fIXO2QH({3RWSY_o8J9n{#Gr)rZbSn zRIXu)DI^08l&~>W6prES5Ndd*FTecYra~gVa6(to)_W|?MnUp~BGsbgw0M<|>yN&1 z$-3j~BAtwz!gLNPde@3KYhlv*1_EKkiTx9!$)p1q1;@uu5-4OiNQApgj_AL|RC=R6 zjGC7y3{&?OD`js?UH?jg4R9UV|8*UyVnv$rt^Y>dAzFEnbw~YUOCrP`B3bNU>|Md9f76y}VvF&ONwgxjk=XHxreY{7rO? zoNc*b+si!T%V{;hz12L;cL!CECj;^~ni0fLhNGTyG0aESyYXoH0wI@}U7I-FXZJI@ zzm3VlgW!!CQ;(~`d#lu=fvAfr3MTZRs{q~iXplgHf=I!a~SJ@TA6^DTdFLJ+51L}+%{&MzV+Qi(#s zu6PQRme&*!*CD5`;N7pweXVh3Dq$KBe&78e;J4JKFruc)5{# zCSOT|^lzXHU`1TaPSWbg?Ue82=MDnN?ZDDC1d2C$y6$RI(#?2CcdY4|`c9@PkvSU5 zxTpx_Mm-b9oxi}RIO#jC{y>cZw#TGpR=+R2bJ}fZkj*tq4B9tLU6DO=j15K71Grlj^Ah%&WbU$QfF4WYe6{ z9VV_vEcbIUhUk1mQx5|Q%C~iz=I*L?wAzq9nuH8{V>^Ie+WFRD+1|BRo%|h1PO^aibi^i?j2+@}D!IFycQpt-+6XN&+fG zv{BGbwkuuf7O1zDkRD>bDdT&*ci;eA*_mSaGaMEYVaK<(%@noKO@}4pP8~ zhAp(Auasc(Wb8ngb9RuoH9mV^vXmE#bRQ)Nhvgy}Lx|H(y-lnLd;lpIeaACfCg+wa z<6yQslZQNuy7ex8htDu@fGg0=8|6k3L*r`O2?#geHW7CByx<%j&*LEpz%kMAVER)%Wcz1$4* z%;RvB&apvv`+b4n{q*9aADMCxsq|~T!U&hr-lMXHYA<-ug~QI$Y+{k`XNH{Am8@Ck zd^@-W^k3f!!`77WIW&w-7w;MgbV7E^a4(ivsDB_?qzu7q08XH&SUOf1DZE=_d%?EwNmXx6Ux%Zw(q6H29gJF0wN#(d~u{WWST+->m8(?X(p`&Kw z{0vfA80=KP#3ofECdZfX&=7~5-#?J59!*;%94T^dSPm+Kk3V3gTSp7=y=7FKMrt1_ zMxz2P#c8VNWjHe-dpsshqIkBEWKj~%`PiNcS&*4C{+{WM z`nFEy08=j6dCsDB*g54Yvo7<%j|O!Vjo{Ne)ZYD55JP+6!$A=;@p0F9_I)i_NhO+t`*)o^J1M2 zx{sLY+-S1+aAmuKKBLS%PQS?Wj*f!SCCe?ukS*=^!qmlU%USfTsfbSWx-E=vqk|gL z@Ud2LkB2Ce0+;(&Y1!{$^c4t4e>ta@HYmax7Wee_E2aE0knMGSvHpF*W_A)u*!C!h$+@{mg6 zpoZd^A;FDgPH!QXK;z>I_z8LDZfFD;-B~yz_2p^g629*xjH8inilG#kB6Gv|SjH?I z14{)mJ6QXE*ihFgoqa4#=SVD8s2Ta-s4Gf45`K7ex^@IpUjWpU2*pH&Wc##D*@K7(BJdN+L7HJocK_C| zw;pb$o=Mwp_-fndg1bQC5W);`^g&dJBaT(05CJPXpnNpLu(X+CR!kUU=_4s@qSAcA z%J&jv7}qsJ8J0|NF&9nUoQfdK5=tc#=j09KPgGP)$nQu|qU9d-w%EW9UjL0;AYWYB z4OyP`@_p?>o&0>YPO-}a2AxY;AhT^bZQ8=)QRuHV8{gFI7g8N~*J$|g{^ljTYc6W} zSO(f^!`#~1px+A~s8fCN038qyJ``CIZU|{%5pI6EVJO@cv}aSPwN+L-p|&8}nX95U zRGNe-7hCjd5~lqFciAa`&wo|OE~ysqP@y!s3w;Zz8MEq}Jq{a8WTCUJ#S*#-{}x|l zyy~7UHgmG|99Dt)KN40cgT(M3srGRQQFt6EkQ<*xkm&P^UfrE;h{0%&Je_#`+L}XO zb6)&A!{P_x^M)E1zf`+p^d!W~8C~vcOsXt73SP}n7;>7I4U4jgs@7x(PAdvVZN2e0 z2=D4W4G`9oj%}(NY5>JAW67%;3w%iRYQYm}(#U zo3nf)LpyZShTQ>+;n-ap1R&#LXfu_+YRi*xjeE4G{>PG6?zSpsduGBKQ*@&lja@ET zQ}V!klU;~^*o1}M_?tEdC2HQnLoh%zd{-7B`P^&9lN;&P*L*9?2=4@z2;us0 z>-{3M0x5AC=bCf%+ae3KTj3CVQAyF4bQ(;qPpK52I4Ke$&GIpGu=w5Kk1W{8nTUf2 zF zKwTu^6loK4VL>4Zz2u^9(l+>Pww-kR$yP~>z^;_d4_gZ&C@-wn^eXyb+W*7Cca{JS zvhzBEtU9)cjwmWQy%D1EC_?&?_9 zje#{+*I>62=M0O64CObIa*gil8&R0MtOM7EP@2}zCf7>>4^|SaizkGex|ZcDw)J3* zJxQ9{m#=PU={Lu_ZF~{^She-bEPX0;?YI4E(~HXU50~HlWW#*=^V_yo0sa$>c{x30 zEWX8$5`6^)s-ftK^Q}dmpF^|$lJ?6zM@E((+I|Qo_yKFqT`c^^e60L2QrY7;JMSfd zUG_`OGHuPaoG!b2eCQ8#@+l(LI4zSgzDUvgNZ=lR8yaLF8uO)hIhN*zScd=o3!DD% z3EP#h-Umcx>ZMm&G=y8O6Z+pNtZz^(A@CDkVVDX^lNCmeS5!&rW@Qe8cBjZNOX0b0 zDEZom5rY=h!lCG*a1XDA0`$& zDX<@)!b(VLz-V9e_@Fd5($8K`UVcyy7yMg#fb>t?#vx3)F`2eLIbskFLoJbgvl78NCh=&&i}!?cI*}#Fy*&9@@D-u)20A1}wl$}3#mY&>LmanBu_mTz(P`abj~uE4OTFnGR3%KmIp1GADA5hIthUOu64gy>eqi(Uhy-#R2g;uAdI+RC~+q3e)DYeuYdc zl=!*JNbp42n2J%GL(G&f;bML_l5-qTirpn*bbu9}NC!6AOx14)!$=;ELlvyuW0=-E zr5-(rkfyo9b3Z)2lrpbUw@2&AcA+%JI+4(nyuk*MsFn z_G&`|8028)J9AI+w~Rre8XCP@)u{uxM*qsFb%g(fd+b9prBmsg;IcO{Tr7!HE)}sW z#0GQiP~(`sQ|KR)Gx?%M-!hyl8HXA)yyRV8RNv+8V)2c7zsvshXRnjZs^s)JlnPi7 z|BKu&?T#0o67iY3_ghO?ns@T*hXBX+IQcYNu~f7aPZqC2huYIAe`jf8ACaD=*OP(n zDZ}I7z8`PO^(COa%{1PulSqlcp<4|t5&^3CzM{siv*6>9b$>C04mt?77mEBqiN$B9 z;6N8u1C(bip%!ejk4&Od)Gvk6Excn$KFJlgL6B2OsSIX)OWs{Q^puQHMvPb%#KOK% zNwJDRl>@APTSn_XmIHG7J@V_?5q8}P_b-%BQJMO1&c-o@i+xG7Oqpaqs#Rf!0#c2g zSAFjf)3||YiaP;KOq%}shJ8B|_e)YKN>9w&?#}LC&t-ej)j#;X1sggqk2(IllF_y~ z-aL>nKCtc(TP2Wlq|z^H*e|ea5C`g?2@X)(PO$ml{ca*)eUbqw+nQ)TpnxvmmVRb| z|3-o$u5*Ac#qW9KT?mYeRgUbc}?xx{7X;f5~Oenf+rB#mC4=cU9!7anJGx~wzD_)9hqh& zP==>)eO=Y4T^cJH&0IteQ zgPM5X%Uq)*^3QibmtR0UYrppUXk2Q+1~T94^uIxbbYPOw-ymrwifC(sFq4$pmlCKb z5oLGHUU9imttT4R+km)Hxv%~vzU!?)eBd@u`U4&LmAna`19-Fz4tHNqz8)g=_C37K z6x?~)rKB8|-NYS=#pMG#ybq?*yF}U%%SJ!|ZOHWwhnaEMk^gGJkn?WDN@i`cdd8uz@r=DV`f!`5pzupAeM0YD8gSp#0x(@?5H{dR0CvJ~nMrdZGLnmenVE2r zka7OU4X62t_G;q}p*AbgtOIhAOa3vYj%Lz|-9`kl9fBeJXx}8@|H5MyM>*Aj9A_1& z=n-`(#V&Nv6FL-J)O#f3tikEEDMw*XhdHvI94aDMzeLP;?0hM_ma= zj5lqO+PBP5abpv^MquS9v~w_2;)KS@rD?%G8ku%4Bg~Au=0=Xm^p84=W=4n*TKpc) z`-M>}b8auvzLGsZ6eeB?$EONEyl9r9`VqL0!>WnGC*iPRQp4)Tw6z`IRoXe1R(AID zRRwI}c%ui7nElSrh@Pfi)~23w_h=jq$jq0BvL675A(iVnMLKte?l-w1F7TbJ?B>Xr zE;T&jx_#i6JuJHem%Z&;W*@c3QY~Yp&@osOGN3MriYuPrxuk8`8h;(fJiC89=b5+X z16v>pE&S2a+1C3T@ZQ|zUC#hQ&Uh;aeLbwLmJc?N2J;iP$>wi^G^a8-T!R|54@k3s z|6QrieVEKiwib_;s2_*E@?I?Q;i>22(NoBNFkA0tJEKu!BqpePki9lxvAsj%dviNJ z$*q*nLCTT2dWP;N!-%leKBp%~r@HMbC%@~?_32|Y{PyT^!#Mdzw+HTZNUxm$0@lpD ztUHm3`~KJSc_Ydt>4$uS9q;PcPVh^*nGXX;Mp?U8Nq1fbe1_qX^Zg4}(toAiI>kR& zM)Ro*sW}t5US?D)Sq95yS7Vw`LivZZ;4(XTnl|~Tq`Z__6R`bgvBw`OJ1wBMC>ly? zZw4ev!h`#Kl++fukJl=NpjU-;dYg672siOv7QX0ulFPrP%*g&A*%aeHNXDK>BvVRQ zh|f%hwIwA`tKbJ-(1;=2${fApSdJOHVv)z)uo3 zL$fgOjD1iW3n}##O9H~S5z=P(l9J(^(fWB!r9>8;ND@s^()XPAD}L+l$SabqZ@1)2MTo9n%YHB9OUQ1#_FrAAxMA?v{rFk(_&7f24aJcJs!ht>K=(XT7^PoQ*w{wh#i*m6DAudGSjrQj=QJJ;NNon1;XfzbeVL z!~g%NFZ-W8gg}M8S6`e6qU+;Z89&xOJ(C)HuSGFD*PDp#zswO Gq9R7SeQkgmam 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

y#6Z`ZiXwUCpNfr=-41`=B> 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�eXyP)U{q&0}Ra@=ZS=aUP}z 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 literal 0 HcmV?d00001 diff --git a/example/network/lwip_startup/pic/network_demo_config.png b/example/network/lwip_startup/pic/network_demo_config.png new file mode 100644 index 0000000000000000000000000000000000000000..3d0898f038d215446cb9c262f13e711f652908f4 GIT binary patch literal 21801 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 +#include +#include "strto.h" +#include "sdkconfig.h" +#include "FreeRTOS.h" +#include "task.h" +#include "ftypes.h" +#include "fassert.h" +#include "fparameters.h" +#ifndef SDK_CONFIG_H__ + #error "Please include sdkconfig.h first" +#endif + + +#include "lwipopts.h" +#include "lwip_port.h" +#include "lwip/ip4_addr.h" +#include "lwip/init.h" +#include "netif/ethernet.h" +#include "lwip/netif.h" +#include "lwip/tcpip.h" +#include "lwip/inet.h" +#include "../src/shell.h" + + +#if defined(CONFIG_TARGET_E2000) + extern int FXmacPhyGpioInit(u32 instance_id, u32 interface_type); +#endif + +#if LWIP_IPV6 + #include "lwip/ip.h" + #include "lwip/ip6_addr.h" +#else + #if LWIP_DHCP + #include "lwip/dhcp.h" + #endif +#endif + +typedef struct +{ + const char *ipaddr; + const char *gateway; + const char *netmask; +} InputAddress; + +typedef struct +{ + UserConfig lwip_mac_config; + InputAddress input_address; + u32 dhcp_en; +} InputConfig; + +static InputConfig input_config = {0}; + +#if !LWIP_IPV6 +#if LWIP_DHCP +static TaskHandle_t appTaskCreateHandle = NULL; +void LwipDhcpTest(struct netif *echo_netif) +{ + int mscnt = 0; + dhcp_start(echo_netif); + printf("LwipDhcpTest is start.\r\n"); + while (1) + { + vTaskDelay(DHCP_FINE_TIMER_MSECS / portTICK_RATE_MS); + dhcp_fine_tmr(); + mscnt += DHCP_FINE_TIMER_MSECS; + if (mscnt >= DHCP_COARSE_TIMER_SECS * 1000) + { + dhcp_coarse_tmr(); + mscnt = 0; + } + } +} +#endif +#endif + +void LwipTestCreate(void *args) +{ + FASSERT(args != NULL); + struct netif *netif_p = NULL; + static boolean init_flag = FALSE; + InputConfig *input_conf = (InputConfig *)args; + ip_addr_t ipaddr = {0}, netmask = {0}, gw = {0}; + BaseType_t ret = pdPASS; + /* the mac address of the board. this should be unique per board */ + unsigned char mac_address[6] = + {0x98, 0x0e, 0x24, 0x00, 0x11, 0}; + + netif_p = pvPortMalloc(sizeof(struct netif)); /* 暂未回收内存 */ + if (netif_p == NULL) + { + printf("Malloc netif is error.\r\n"); + goto exit; + } + printf("netif_p is %p.\r\n", netif_p); + mac_address[5] = input_conf->lwip_mac_config.mac_instance; + + + /* convert string to a binary address */ + if (input_conf->input_address.ipaddr) + { + if (inet_aton(input_conf->input_address.ipaddr, &ipaddr) == 0) + { + goto failed; + } + } + + if (input_conf->input_address.gateway) + { + if (inet_aton(input_conf->input_address.gateway, &gw) == 0) + { + goto failed; + } + } + + if (input_conf->input_address.netmask) + { + if (inet_aton(input_conf->input_address.netmask, &netmask) == 0) + { + goto failed; + } + } + if (LwipPortGetByName(input_conf->lwip_mac_config.name)) + { + printf("Netif already exists!\r\n"); + goto failed; + } + /* 初始化LwIP堆 */ + if (init_flag == FALSE) + { + tcpip_init(NULL, NULL); + init_flag = TRUE; + } + + /* Add network interface to the netif_list, and set it as default */ + if (!LwipPortAdd(netif_p, &ipaddr, &netmask, + &gw, mac_address, + (UserConfig *)args, 0)) + { + printf("Error adding N/W interface.\n\r"); + return ; + } + printf("LwipPortAdd is over.\n\r"); + +#if (LWIP_IPV6) + netif_p->ip6_autoconfig_enabled = 1; + netif_create_ip6_linklocal_address(netif_p, 1); + netif_ip6_addr_set_state(netif_p, 0, IP6_ADDR_VALID); +#endif + + netif_set_default(netif_p); + + if (netif_is_link_up(netif_p)) + { + /* 当netif完全配置好时,必须调用该函数 */ + netif_set_up(netif_p); + if (input_conf->dhcp_en) + { + LwipPortDhcpSet(netif_p, TRUE); + } + } + else + { + /* 当netif链接关闭时,必须调用该函数 */ + netif_set_down(netif_p); + } + + printf("Network setup complete.\r\n"); + + goto exit ; +failed: + vPortFree(netif_p); +exit: + vTaskDelete(NULL); +} + +void LwipTest(void *args) +{ + BaseType_t ret; + ret = xTaskCreate((TaskFunction_t)LwipTestCreate, /* 任务入口函数 */ + (const char *)"LwipTestCreate", /* 任务名字 */ + (uint16_t)2048, /* 任务栈大小 */ + (void *)args, /* 任务入口函数参数 */ + (UBaseType_t)configMAX_PRIORITIES - 1, /* 任务的优先级 */ + NULL); /* 任务控制块指针 */ + + FASSERT_MSG(ret == pdPASS, "LwipTestCreate Task create is failed"); +} + + + +static int LwipDeviceSet(int argc, char *argv[]) +{ + u32 id = 0, type = 0; + const char *ipaddr = NULL; + const char *gateway = NULL; + const char *netmask = NULL; + memset(&input_config, 0, sizeof(input_config)); + LWIP_PORT_CONFIG_DEFAULT_INIT(input_config.lwip_mac_config); + + if (!strcmp(argv[1], "probe")) + { + switch (argc) + { + case 8: + netmask = argv[7]; + case 7: + gateway = argv[6]; + case 6: + ipaddr = argv[5]; + input_config.input_address.ipaddr = ipaddr; + input_config.input_address.gateway = gateway; + input_config.input_address.netmask = netmask; + case 5: + input_config.dhcp_en = (u32)simple_strtoul(argv[4], NULL, 10); + case 4: + type = (u32)simple_strtoul(argv[3], NULL, 10); + case 3: + id = (u32)simple_strtoul(argv[2], NULL, 10); + break; + default: + break; + } + printf("types %d.\r\n", type); + printf("id %d.\r\n", id); + +#if defined(CONFIG_TARGET_E2000) + FXmacPhyGpioInit(id, type); +#endif + input_config.lwip_mac_config.mac_instance = id; + input_config.lwip_mac_config.name[0] = 'e'; + itoa(id, &input_config.lwip_mac_config.name[1], 10); + if (type == 0) + { + input_config.lwip_mac_config.mii_interface = LWIP_PORT_INTERFACE_RGMII; + } + else + { + input_config.lwip_mac_config.mii_interface = LWIP_PORT_INTERFACE_SGMII; + } + + LwipTest(&input_config); + } + else if (!strcmp(argv[1], "deinit")) + { + if (argc <= 1) + { + printf("Please enter lwip deinit \r\n") ; + printf(" -- use name to deinit neitf object \r\n"); + printf(" -- is netif name \r\n"); + return -1; + } + struct netif *netif_p = NULL; + netif_p = LwipPortGetByName(argv[2]); + if (netif_p == NULL) + { + printf("netif %s is not invalid.\r\n", argv[2]); + return -1; + } + + /* close rx thread */ + vPortEnterCritical(); + LwipPortStop(netif_p); + vPortFree(netif_p); + vPortExitCritical(); + } + else + { + printf("Please enter lwip probe \r\n") ; + printf(" -- device id is mac instance number \r\n"); + printf(" -- interface id is media independent interface , 0 is rgmii ,1 is sgmii \r\n"); + printf(" -- dhcp_en is dhcp function set ,1 is enable ,0 is disable .But this depends on whether the protocol stack supports it "); + printf(" -- Ip address of netif \r\n"); + printf(" -- Gateway of netif \r\n"); + printf(" -- Netmask of netif \r\n"); + printf("Please enter lwip deinit \r\n") ; + printf(" -- use name to deinit neitf object \r\n"); + printf(" -- is netif name \r\n"); + } + return 0; +} + +SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), lwip, LwipDeviceSet, Setup LWIP device test); + diff --git a/example/network/sockets/udp_multicast/Kconfig b/example/network/sockets/udp_multicast/Kconfig index efe6358f..ddcb0b6c 100644 --- a/example/network/sockets/udp_multicast/Kconfig +++ b/example/network/sockets/udp_multicast/Kconfig @@ -9,9 +9,8 @@ mainmenu "Phytium FreeRTOS Configuration" Build Target name for the demo - if TARGET_E2000 + source "./src/Kconfig" - endif endmenu diff --git a/example/network/sockets/udp_multicast/README.md b/example/network/sockets/udp_multicast/README.md index 9853b9bd..09856eee 100644 --- a/example/network/sockets/udp_multicast/README.md +++ b/example/network/sockets/udp_multicast/README.md @@ -123,73 +123,64 @@ bootelf -p 0x90100000 - 启动进入后,根据连接的xmac口,输入指令完成网口初始化 +### 2.4.1 如何进行实验 +- 当开发者配置好程序之后,通过2.3.1/2.3.2的方式将编译好的镜像文件拷贝至开发板中。 +- 以E2000D/Q demo 板为例,开发者输入以下命令则可以初始化网卡: -#### 2.4.1 基于IPv4下初始化 - -- 输入以下命令 - ``` -make menuconfig +lwip probe 0 1 1 192.168.4.10 192.168.4.1 255.255.255.0 ``` -- 需将Multicast IP type 选为 IPV4 - -![](./pic/ipv4_config.png) +- 命令定义为:"lwip probe " +- 为mac控制器 +- 为gmii 控制器类型,0 is rgmii ,1 is sgmii +- 1为使能dhcp 功能,0为关闭dhcp 功能 +- 为ipv4 地址,示例为: 192.168.4.10 +- 为网关 ,示例为: 192.168.4.1 +- 为子网掩码,示例为255.255.255.0 -- 输入以下命令,初始化LWIP网络协议栈, 依次配置ip地址,子网掩码,网关地址和退出时间,运行完成退出后LWIP协议栈会被暂时去使能 +- 效果图如下 -- 关闭IPv6 选项 -![](./pic/ipv4_config2.png) +![](./pic/lwip_probe.png) -``` -xmac probe [device id] [interface id] -``` - -- 其中device id 为控制器id -- interface id ,0 为rgmii ,1 为sgmii -![xmac_probe_ipv4](./pic/xmac_probe.png "xmac_probe.png") - -![ping](./pic/ping.png "ping.png") - -#### 2.4.2 IPv6下初始化 +#### 2.4.2 基于IPv4下初始化 - 输入以下命令 - + ``` make menuconfig ``` -- 需将Multicast IP type 选为 IPV6 +- 需将Multicast IP type 选为 IPV4 -![](./pic/ipv6_config.png) +![](./pic/ipv4_config.png) -- 关闭仅仅使用IPv4 选项 - -![](./pic/DisableNotusingIPV4attheaSametime.png) +#### 2.4.3 IPv4$IPv6 共存的模式 -- 输入以下命令,初始化LWIP网络协议栈, 依次配置ip地址,子网掩码,网关地址和退出时间,运行完成退出后LWIP协议栈会被暂时去使能 +- 输入以下命令 ``` -xmac probe [device id] [interface id] +make menuconfig ``` -- 其中device id 为控制器id -- interface id ,0 为rgmii ,1 为sgmii +- 需将Multicast IP type 选为 IPV4 & IPV6 + +![](./pic/ipv4_ipv6_config.png) -![xmac_probe](./pic/xmac_probe.png "xmac_probe.png") -![xmac_probe2](./pic/xmac_probe_ipv6_2.png "xmac_probe_ipv6_2.png") -![ping](./pic/ping_ipv6.png "ping_ipv6.png") +- 关闭仅仅使用IPv4 选项 + +![](./pic/DisableNotusingIPV4attheaSametime.png) -#### 2.4.3 进行multicast 测试 +#### 2.4.4 进行multicast 测试 -- 完成2.4.1 / 2.4.2 之后 ,可以进行multcast 的相关实验 ,以下以ipv6 的实验为例 +- 完成2.4.1 / 2.4.2 /2.4.3 之后 ,可以进行multcast 的相关实验 ,以下以ipv6 的实验为例 - 在串口终端上输入以下指令 ``` multicast @@ -227,7 +218,7 @@ multicast - 开发者在串口终端上请输入以下命令对控制器进行初始化 ```shell - xmac probe 0 1 + lwip probe 0 1 1 192.168.4.10 192.168.4.1 255.255.255.0 ``` ## 4. 修改历史记录 diff --git a/example/network/sockets/udp_multicast/configs/d2000_aarch32_eg_configs b/example/network/sockets/udp_multicast/configs/d2000_aarch32_eg_configs new file mode 100644 index 00000000..1f34331a --- /dev/null +++ b/example/network/sockets/udp_multicast/configs/d2000_aarch32_eg_configs @@ -0,0 +1,514 @@ + +# +# Project Configuration +# +CONFIG_TARGET_NAME="d2000_freertos_a32" + +# +# Example Configuration +# +CONFIG_EXAMPLE_IPV4_V6=y +# CONFIG_EXAMPLE_IPV4_ONLY is not set +CONFIG_EXAMPLE_IPV4=y +CONFIG_EXAMPLE_IPV6=y +CONFIG_EXAMPLE_MULTICAST_IPV4_ADDR="232.10.12.10" +CONFIG_EXAMPLE_MULTICAST_IPV6_ADDR="FF02::FD" +CONFIG_EXAMPLE_PORT=6750 +# CONFIG_EXAMPLE_LOOPBACK is not set +CONFIG_EXAMPLE_MULTICAST_TTL=1 +# CONFIG_EXAMPLE_MULTICAST_LISTEN_ALL_IF is not set +CONFIG_EXAMPLE_MULTICAST_LISTEN_DEFAULT_IF=y +# end of Example Configuration +# end of Project Configuration + +# +# Standalone Setting +# +CONFIG_USE_FREERTOS=y + +# +# Arch Configuration +# +CONFIG_TARGET_ARMV8_AARCH32=y +# CONFIG_TARGET_ARMV8_AARCH64 is not set +CONFIG_USE_CACHE=y +# CONFIG_USE_L3CACHE is not set +CONFIG_USE_MMU=y +CONFIG_USE_SYS_TICK=y +CONFIG_USE_AARCH64_L1_TO_AARCH32=y +# end of Arch Configuration + +# +# Board Configuration +# +# CONFIG_TARGET_F2000_4 is not set +CONFIG_TARGET_D2000=y +# CONFIG_TARGET_E2000Q is not set +# CONFIG_TARGET_E2000D is not set +# CONFIG_TARGET_E2000S is not set +CONFIG_DEFAULT_DEBUG_PRINT_UART1=y +# CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set +# CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set +# end of Board Configuration + +# +# Components Configuration +# +# CONFIG_USE_SPI is not set +# CONFIG_USE_QSPI is not set +CONFIG_USE_GIC=y +CONFIG_ENABLE_GICV3=y +CONFIG_USE_SERIAL=y + +# +# Usart Configuration +# +CONFIG_ENABLE_Pl011_UART=y +# end of Usart Configuration + +# CONFIG_USE_GPIO is not set +CONFIG_USE_ETH=y + +# +# Eth Configuration +# +# CONFIG_ENABLE_FXMAC is not set +CONFIG_ENABLE_FGMAC=y +CONFIG_FGMAC_PHY_COMMON=y +# CONFIG_FGMAC_PHY_AR803X is not set +# end of Eth Configuration + +# CONFIG_USE_CAN is not set +# CONFIG_USE_I2C is not set +# CONFIG_USE_TIMER is not set +# CONFIG_USE_MIO is not set +# CONFIG_USE_SDMMC is not set +# CONFIG_USE_PCIE is not set +# CONFIG_USE_WDT is not set +# CONFIG_USE_DMA is not set +# CONFIG_USE_NAND is not set +# CONFIG_USE_RTC is not set +# CONFIG_USE_SATA is not set +# CONFIG_USE_USB is not set +# CONFIG_USE_ADC is not set +# CONFIG_USE_PWM is not set +# CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set +# end of Components Configuration + +CONFIG_USE_NEW_LIBC=y +# end of Standalone Setting + +# +# Building Option +# +# CONFIG_LOG_VERBOS is not set +# CONFIG_LOG_DEBUG is not set +# CONFIG_LOG_INFO is not set +# CONFIG_LOG_WARN is not set +CONFIG_LOG_ERROR=y +# CONFIG_LOG_NONE is not set +CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y +CONFIG_INTERRUPT_ROLE_MASTER=y +# CONFIG_INTERRUPT_ROLE_SLAVE is not set +# CONFIG_LOG_EXTRA_INFO is not set +# CONFIG_BOOTUP_DEBUG_PRINTS is not set + +# +# Linker Options +# +CONFIG_AARCH32_RAM_LD=y +# CONFIG_AARCH64_RAM_LD is not set +# CONFIG_USER_DEFINED_LD is not set +CONFIG_LINK_SCRIPT_ROM=y +CONFIG_ROM_START_UP_ADDR=0x80100000 +CONFIG_ROM_SIZE_MB=1 +CONFIG_LINK_SCRIPT_RAM=y +CONFIG_RAM_START_UP_ADDR=0x80500000 +CONFIG_RAM_SIZE_MB=64 +CONFIG_HEAP_SIZE=1 +CONFIG_SVC_STACK_SIZE=0x1000 +CONFIG_SYS_STACK_SIZE=0x1000 +CONFIG_IRQ_STACK_SIZE=0x1000 +CONFIG_ABORT_STACK_SIZE=0x1000 +CONFIG_FIQ_STACK_SIZE=0x1000 +CONFIG_UNDEF_STACK_SIZE=0x1000 +# end of Linker Options + +# +# Compiler Options +# + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + +CONFIG_OUTPUT_BINARY=y +# end of Compiler Options +# end of Building Option + +# +# Component Configuration +# + +# +# Freertos Uart Drivers +# +CONFIG_FREERTOS_USE_UART=y +# end of Freertos Uart Drivers + +# +# Freertos Pwm Drivers +# +# CONFIG_FREERTOS_USE_PWM is not set +# end of Freertos Pwm Drivers + +# +# Freertos Qspi Drivers +# +# CONFIG_FREERTOS_USE_QSPI is not set +# end of Freertos Qspi Drivers + +# +# Freertos Wdt Drivers +# +# CONFIG_FREERTOS_USE_WDT is not set +# end of Freertos Wdt Drivers + +# +# Freertos Eth Drivers +# +# CONFIG_FREERTOS_USE_XMAC is not set +CONFIG_FREERTOS_USE_GMAC=y +# end of Freertos Eth Drivers + +# +# Freertos Gpio Drivers +# +# CONFIG_FREERTOS_USE_GPIO is not set +# end of Freertos Gpio Drivers + +# +# Freertos Spim Drivers +# +# CONFIG_FREERTOS_USE_FSPIM is not set +# end of Freertos Spim Drivers + +# +# Freertos DMA Drivers +# +# CONFIG_FREERTOS_USE_FDDMA is not set +# CONFIG_FREERTOS_USE_FGDMA is not set +# end of Freertos DMA Drivers + +# +# Freertos Adc Drivers +# +# CONFIG_FREERTOS_USE_ADC is not set +# end of Freertos Adc Drivers + +# +# Freertos Can Drivers +# +# CONFIG_FREERTOS_USE_CAN is not set +# end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers +# end of Component Configuration + +# +# Third-Party Configuration +# +CONFIG_USE_LWIP=y + +# +# LWIP Freertos Port Configuration +# +# CONFIG_LWIP_FXMAC is not set +CONFIG_LWIP_FGMAC=y + +# +# LWIP Configuration +# + +# +# LWIP Port Configuration +# +# CONFIG_LWIP_PORT_DEBUG_EN is not set +# end of LWIP Port Configuration + +# CONFIG_LWIP_NO_SYS is not set +CONFIG_LWIP_LOCAL_HOSTNAME="phytium" + +# +# Memory configuration +# +# CONFIG_LWIP_USE_MEM_POOL is not set +CONFIG_LWIP_USE_MEM_HEAP=y +CONFIG_MEM_SIZE=2 +CONFIG_MEM_ALIGNMENT=64 +# end of Memory configuration + +# +# Pbuf options +# +CONFIG_PBUF_POOL_BUFSIZE=2 +CONFIG_PBUF_POOL_SIZE=1 +# end of Pbuf options + +# +# ARP +# +CONFIG_ARP_QUEUEING_EN=y +# end of ARP + +# +# IPV4 +# +# CONFIG_USE_IPV4_ONLY is not set +CONFIG_LWIP_IP4_REASSEMBLY=y +CONFIG_LWIP_IP4_FRAG=y +# CONFIG_LWIP_IP_FORWARD is not set +CONFIG_IP_REASS_MAX_PBUFS=16 +# end of IPV4 + +# +# ICMP +# +CONFIG_LWIP_ICMP=y +CONFIG_LWIP_MULTICAST_PING=y +CONFIG_LWIP_BROADCAST_PING=y +# end of ICMP + +# +# LWIP RAW API +# +CONFIG_LWIP_RAW_API_EN=y +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + +# +# DHCP +# +CONFIG_LWIP_DHCP_ENABLE=y +# CONFIG_LWIP_DHCP_DOES_ARP_CHECK is not set +# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set +# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set +# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set +CONFIG_LWIP_DHCP_OPTIONS_LEN=68 +CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y +# end of DHCP + +# +# AUTOIP +# +# CONFIG_LWIP_AUTOIP is not set +# end of AUTOIP + +# +# IGMP +# +CONFIG_LWIP_IGMP_EN=y +# end of IGMP + +# +# DNS +# +CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y +# end of DNS + +# +# UDP +# +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# CONFIG_LWIP_NETBUF_RECVINFO is not set +# end of UDP + +# +# TCP +# +CONFIG_LWIP_TCP_WND_DEFAULT=5744 +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +# CONFIG_LWIP_TCP_SACK_OUT is not set +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 +CONFIG_LWIP_TCP_RTO_TIME=1500 +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +# end of TCP + +# +# Network_Interface +# +# CONFIG_LWIP_NETIF_API is not set +# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set +# end of Network_Interface + +# +# LOOPIF +# +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 +# end of LOOPIF + +# +# SLIPIF +# +# CONFIG_LWIP_SLIP_SUPPORT is not set +# end of SLIPIF + +CONFIG_LWIP_TCPIP_CORE_LOCKING=y + +# +# Socket +# +CONFIG_LWIP_MAX_SOCKETS=10 +# CONFIG_LWIP_SO_LINGER is not set +CONFIG_LWIP_SO_REUSE=y +CONFIG_LWIP_SO_REUSE_RXTOALL=y +# end of Socket + +# CONFIG_LWIP_STATS is not set + +# +# PPP +# +# CONFIG_LWIP_PPP_SUPPORT is not set +CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 +CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 +# end of PPP + +# +# Checksums +# +# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set +# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set +CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y +# end of Checksums + +# +# IPV6 +# +CONFIG_LWIP_IPV6=y +# CONFIG_LWIP_IPV6_AUTOCONFIG is not set +CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 +# CONFIG_LWIP_IPV6_FORWARD is not set +CONFIG_LWIP_IP6_FRAG=y +# CONFIG_LWIP_IP6_REASSEMBLY is not set +# end of IPV6 + +CONFIG_LWIP_DEBUG=y +# CONFIG_LWIP_DEBUG_ESP_LOG is not set +CONFIG_LWIP_NETIF_DEBUG=y +# CONFIG_LWIP_PBUF_DEBUG is not set +# CONFIG_LWIP_ETHARP_DEBUG is not set +# CONFIG_LWIP_API_LIB_DEBUG is not set +# CONFIG_LWIP_SOCKETS_DEBUG is not set +# CONFIG_LWIP_IP_DEBUG is not set +# CONFIG_LWIP_ICMP_DEBUG is not set +# CONFIG_LWIP_DHCP_STATE_DEBUG is not set +# CONFIG_LWIP_DHCP_DEBUG is not set +# CONFIG_LWIP_IP6_DEBUG is not set +# CONFIG_LWIP_ICMP6_DEBUG is not set +# CONFIG_LWIP_TCP_DEBUG is not set +# CONFIG_LWIP_UDP_DEBUG is not set +# CONFIG_LWIP_SNTP_DEBUG is not set +# CONFIG_LWIP_DNS_DEBUG is not set +# end of LWIP Configuration + +# +# Tcp/ip task resource configuration +# +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_PRIO=6 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +# end of Tcp/ip task resource configuration + +# +# lwip port thread Configuration +# +CONFIG_LWIP_PORT_USE_RECEIVE_THREAD=y +CONFIG_LWIP_PORT_RECEIVE_THREAD_STACKSIZE=1024 +CONFIG_LWIP_PORT_RECEIVE_THREAD_PRIORITY=5 +CONFIG_LWIP_PORT_USE_LINK_DETECT_THREAD=y +CONFIG_LWIP_PORT_LINK_DETECT_STACKSIZE=1024 +CONFIG_LWIP_PORT_LINK_DETECT_PRIORITY=5 +CONFIG_LWIP_PORT_DHCP_THREAD=y +CONFIG_LWIP_PORT_DHCP_STACKSIZE=2048 +CONFIG_LWIP_PORT_DHCP_PRIORITY=5 +# end of lwip port thread Configuration +# end of LWIP Freertos Port Configuration + +CONFIG_USE_BACKTRACE=y +# CONFIG_USE_FATFS_0_1_4 is not set +# CONFIG_USE_SFUD is not set +# CONFIG_USE_SPIFFS is not set +# CONFIG_USE_AMP is not set +CONFIG_USE_LETTER_SHELL=y + +# +# Letter Shell Configuration +# +CONFIG_LS_PL011_UART=y +CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y +# CONFIG_DEFAULT_LETTER_SHELL_USE_UART0 is not set +# CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set +# end of Letter Shell Configuration + +CONFIG_USE_TLSF=y +# CONFIG_USE_SDMMC_CMD is not set +# CONFIG_USE_CHERRY_USB is not set +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/network/sockets/udp_multicast/configs/d2000_aarch64_eg_configs b/example/network/sockets/udp_multicast/configs/d2000_aarch64_eg_configs new file mode 100644 index 00000000..df0279b9 --- /dev/null +++ b/example/network/sockets/udp_multicast/configs/d2000_aarch64_eg_configs @@ -0,0 +1,510 @@ + +# +# Project Configuration +# +CONFIG_TARGET_NAME="d2000_freertos_a64" + +# +# Example Configuration +# +CONFIG_EXAMPLE_IPV4_V6=y +# CONFIG_EXAMPLE_IPV4_ONLY is not set +CONFIG_EXAMPLE_IPV4=y +CONFIG_EXAMPLE_IPV6=y +CONFIG_EXAMPLE_MULTICAST_IPV4_ADDR="232.10.12.10" +CONFIG_EXAMPLE_MULTICAST_IPV6_ADDR="FF02::FD" +CONFIG_EXAMPLE_PORT=6750 +# CONFIG_EXAMPLE_LOOPBACK is not set +CONFIG_EXAMPLE_MULTICAST_TTL=1 +# CONFIG_EXAMPLE_MULTICAST_LISTEN_ALL_IF is not set +CONFIG_EXAMPLE_MULTICAST_LISTEN_DEFAULT_IF=y +# end of Example Configuration +# end of Project Configuration + +# +# Standalone Setting +# +CONFIG_USE_FREERTOS=y + +# +# Arch Configuration +# +# CONFIG_TARGET_ARMV8_AARCH32 is not set +CONFIG_TARGET_ARMV8_AARCH64=y +CONFIG_USE_CACHE=y +# CONFIG_USE_L3CACHE is not set +CONFIG_USE_MMU=y +CONFIG_USE_SYS_TICK=y +# CONFIG_MMU_DEBUG_PRINTS is not set +# end of Arch Configuration + +# +# Board Configuration +# +# CONFIG_TARGET_F2000_4 is not set +CONFIG_TARGET_D2000=y +# CONFIG_TARGET_E2000Q is not set +# CONFIG_TARGET_E2000D is not set +# CONFIG_TARGET_E2000S is not set +CONFIG_DEFAULT_DEBUG_PRINT_UART1=y +# CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set +# CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set +# end of Board Configuration + +# +# Components Configuration +# +# CONFIG_USE_SPI is not set +# CONFIG_USE_QSPI is not set +CONFIG_USE_GIC=y +CONFIG_ENABLE_GICV3=y +CONFIG_USE_SERIAL=y + +# +# Usart Configuration +# +CONFIG_ENABLE_Pl011_UART=y +# end of Usart Configuration + +# CONFIG_USE_GPIO is not set +CONFIG_USE_ETH=y + +# +# Eth Configuration +# +# CONFIG_ENABLE_FXMAC is not set +CONFIG_ENABLE_FGMAC=y +CONFIG_FGMAC_PHY_COMMON=y +# CONFIG_FGMAC_PHY_AR803X is not set +# end of Eth Configuration + +# CONFIG_USE_CAN is not set +# CONFIG_USE_I2C is not set +# CONFIG_USE_TIMER is not set +# CONFIG_USE_MIO is not set +# CONFIG_USE_SDMMC is not set +# CONFIG_USE_PCIE is not set +# CONFIG_USE_WDT is not set +# CONFIG_USE_DMA is not set +# CONFIG_USE_NAND is not set +# CONFIG_USE_RTC is not set +# CONFIG_USE_SATA is not set +# CONFIG_USE_USB is not set +# CONFIG_USE_ADC is not set +# CONFIG_USE_PWM is not set +# CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set +# end of Components Configuration + +CONFIG_USE_NEW_LIBC=y +# end of Standalone Setting + +# +# Building Option +# +# CONFIG_LOG_VERBOS is not set +# CONFIG_LOG_DEBUG is not set +# CONFIG_LOG_INFO is not set +# CONFIG_LOG_WARN is not set +CONFIG_LOG_ERROR=y +# CONFIG_LOG_NONE is not set +CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y +CONFIG_INTERRUPT_ROLE_MASTER=y +# CONFIG_INTERRUPT_ROLE_SLAVE is not set +# CONFIG_LOG_EXTRA_INFO is not set +# CONFIG_BOOTUP_DEBUG_PRINTS is not set + +# +# Linker Options +# +# CONFIG_AARCH32_RAM_LD is not set +CONFIG_AARCH64_RAM_LD=y +# CONFIG_USER_DEFINED_LD is not set +CONFIG_LINK_SCRIPT_ROM=y +CONFIG_ROM_START_UP_ADDR=0x80100000 +CONFIG_ROM_SIZE_MB=1 +CONFIG_LINK_SCRIPT_RAM=y +CONFIG_RAM_START_UP_ADDR=0x80500000 +CONFIG_RAM_SIZE_MB=64 +CONFIG_HEAP_SIZE=1 +CONFIG_STACK_SIZE=0x100000 +CONFIG_FPU_STACK_SIZE=0x1000 +# end of Linker Options + +# +# Compiler Options +# + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + +CONFIG_OUTPUT_BINARY=y +# end of Compiler Options +# end of Building Option + +# +# Component Configuration +# + +# +# Freertos Uart Drivers +# +CONFIG_FREERTOS_USE_UART=y +# end of Freertos Uart Drivers + +# +# Freertos Pwm Drivers +# +# CONFIG_FREERTOS_USE_PWM is not set +# end of Freertos Pwm Drivers + +# +# Freertos Qspi Drivers +# +# CONFIG_FREERTOS_USE_QSPI is not set +# end of Freertos Qspi Drivers + +# +# Freertos Wdt Drivers +# +# CONFIG_FREERTOS_USE_WDT is not set +# end of Freertos Wdt Drivers + +# +# Freertos Eth Drivers +# +# CONFIG_FREERTOS_USE_XMAC is not set +CONFIG_FREERTOS_USE_GMAC=y +# end of Freertos Eth Drivers + +# +# Freertos Gpio Drivers +# +# CONFIG_FREERTOS_USE_GPIO is not set +# end of Freertos Gpio Drivers + +# +# Freertos Spim Drivers +# +# CONFIG_FREERTOS_USE_FSPIM is not set +# end of Freertos Spim Drivers + +# +# Freertos DMA Drivers +# +# CONFIG_FREERTOS_USE_FDDMA is not set +# CONFIG_FREERTOS_USE_FGDMA is not set +# end of Freertos DMA Drivers + +# +# Freertos Adc Drivers +# +# CONFIG_FREERTOS_USE_ADC is not set +# end of Freertos Adc Drivers + +# +# Freertos Can Drivers +# +# CONFIG_FREERTOS_USE_CAN is not set +# end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers +# end of Component Configuration + +# +# Third-Party Configuration +# +CONFIG_USE_LWIP=y + +# +# LWIP Freertos Port Configuration +# +# CONFIG_LWIP_FXMAC is not set +CONFIG_LWIP_FGMAC=y + +# +# LWIP Configuration +# + +# +# LWIP Port Configuration +# +# CONFIG_LWIP_PORT_DEBUG_EN is not set +# end of LWIP Port Configuration + +# CONFIG_LWIP_NO_SYS is not set +CONFIG_LWIP_LOCAL_HOSTNAME="phytium" + +# +# Memory configuration +# +# CONFIG_LWIP_USE_MEM_POOL is not set +CONFIG_LWIP_USE_MEM_HEAP=y +CONFIG_MEM_SIZE=2 +CONFIG_MEM_ALIGNMENT=64 +# end of Memory configuration + +# +# Pbuf options +# +CONFIG_PBUF_POOL_BUFSIZE=2 +CONFIG_PBUF_POOL_SIZE=1 +# end of Pbuf options + +# +# ARP +# +CONFIG_ARP_QUEUEING_EN=y +# end of ARP + +# +# IPV4 +# +# CONFIG_USE_IPV4_ONLY is not set +CONFIG_LWIP_IP4_REASSEMBLY=y +CONFIG_LWIP_IP4_FRAG=y +# CONFIG_LWIP_IP_FORWARD is not set +CONFIG_IP_REASS_MAX_PBUFS=16 +# end of IPV4 + +# +# ICMP +# +CONFIG_LWIP_ICMP=y +CONFIG_LWIP_MULTICAST_PING=y +CONFIG_LWIP_BROADCAST_PING=y +# end of ICMP + +# +# LWIP RAW API +# +CONFIG_LWIP_RAW_API_EN=y +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + +# +# DHCP +# +CONFIG_LWIP_DHCP_ENABLE=y +# CONFIG_LWIP_DHCP_DOES_ARP_CHECK is not set +# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set +# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set +# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set +CONFIG_LWIP_DHCP_OPTIONS_LEN=68 +CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y +# end of DHCP + +# +# AUTOIP +# +# CONFIG_LWIP_AUTOIP is not set +# end of AUTOIP + +# +# IGMP +# +CONFIG_LWIP_IGMP_EN=y +# end of IGMP + +# +# DNS +# +CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y +# end of DNS + +# +# UDP +# +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# CONFIG_LWIP_NETBUF_RECVINFO is not set +# end of UDP + +# +# TCP +# +CONFIG_LWIP_TCP_WND_DEFAULT=5744 +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +# CONFIG_LWIP_TCP_SACK_OUT is not set +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 +CONFIG_LWIP_TCP_RTO_TIME=1500 +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +# end of TCP + +# +# Network_Interface +# +# CONFIG_LWIP_NETIF_API is not set +# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set +# end of Network_Interface + +# +# LOOPIF +# +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 +# end of LOOPIF + +# +# SLIPIF +# +# CONFIG_LWIP_SLIP_SUPPORT is not set +# end of SLIPIF + +CONFIG_LWIP_TCPIP_CORE_LOCKING=y + +# +# Socket +# +CONFIG_LWIP_MAX_SOCKETS=10 +# CONFIG_LWIP_SO_LINGER is not set +CONFIG_LWIP_SO_REUSE=y +CONFIG_LWIP_SO_REUSE_RXTOALL=y +# end of Socket + +# CONFIG_LWIP_STATS is not set + +# +# PPP +# +# CONFIG_LWIP_PPP_SUPPORT is not set +CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 +CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 +# end of PPP + +# +# Checksums +# +# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set +# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set +CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y +# end of Checksums + +# +# IPV6 +# +CONFIG_LWIP_IPV6=y +# CONFIG_LWIP_IPV6_AUTOCONFIG is not set +CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 +# CONFIG_LWIP_IPV6_FORWARD is not set +CONFIG_LWIP_IP6_FRAG=y +# CONFIG_LWIP_IP6_REASSEMBLY is not set +# end of IPV6 + +CONFIG_LWIP_DEBUG=y +# CONFIG_LWIP_DEBUG_ESP_LOG is not set +CONFIG_LWIP_NETIF_DEBUG=y +# CONFIG_LWIP_PBUF_DEBUG is not set +# CONFIG_LWIP_ETHARP_DEBUG is not set +# CONFIG_LWIP_API_LIB_DEBUG is not set +# CONFIG_LWIP_SOCKETS_DEBUG is not set +# CONFIG_LWIP_IP_DEBUG is not set +# CONFIG_LWIP_ICMP_DEBUG is not set +# CONFIG_LWIP_DHCP_STATE_DEBUG is not set +# CONFIG_LWIP_DHCP_DEBUG is not set +# CONFIG_LWIP_IP6_DEBUG is not set +# CONFIG_LWIP_ICMP6_DEBUG is not set +# CONFIG_LWIP_TCP_DEBUG is not set +# CONFIG_LWIP_UDP_DEBUG is not set +# CONFIG_LWIP_SNTP_DEBUG is not set +# CONFIG_LWIP_DNS_DEBUG is not set +# end of LWIP Configuration + +# +# Tcp/ip task resource configuration +# +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_PRIO=6 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +# end of Tcp/ip task resource configuration + +# +# lwip port thread Configuration +# +CONFIG_LWIP_PORT_USE_RECEIVE_THREAD=y +CONFIG_LWIP_PORT_RECEIVE_THREAD_STACKSIZE=1024 +CONFIG_LWIP_PORT_RECEIVE_THREAD_PRIORITY=5 +CONFIG_LWIP_PORT_USE_LINK_DETECT_THREAD=y +CONFIG_LWIP_PORT_LINK_DETECT_STACKSIZE=1024 +CONFIG_LWIP_PORT_LINK_DETECT_PRIORITY=5 +CONFIG_LWIP_PORT_DHCP_THREAD=y +CONFIG_LWIP_PORT_DHCP_STACKSIZE=2048 +CONFIG_LWIP_PORT_DHCP_PRIORITY=5 +# end of lwip port thread Configuration +# end of LWIP Freertos Port Configuration + +CONFIG_USE_BACKTRACE=y +# CONFIG_USE_FATFS_0_1_4 is not set +# CONFIG_USE_SFUD is not set +# CONFIG_USE_SPIFFS is not set +# CONFIG_USE_AMP is not set +CONFIG_USE_LETTER_SHELL=y + +# +# Letter Shell Configuration +# +CONFIG_LS_PL011_UART=y +CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y +# CONFIG_DEFAULT_LETTER_SHELL_USE_UART0 is not set +# CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set +# end of Letter Shell Configuration + +CONFIG_USE_TLSF=y +# CONFIG_USE_SDMMC_CMD is not set +# CONFIG_USE_CHERRY_USB is not set +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/network/sockets/udp_multicast/configs/e2000d_aarch32_eg_configs b/example/network/sockets/udp_multicast/configs/e2000d_aarch32_eg_configs index 6417f2c5..b353d2aa 100644 --- a/example/network/sockets/udp_multicast/configs/e2000d_aarch32_eg_configs +++ b/example/network/sockets/udp_multicast/configs/e2000d_aarch32_eg_configs @@ -2,15 +2,17 @@ # # Project Configuration # -CONFIG_TARGET_NAME="e2000_lwip_multicast" +CONFIG_TARGET_NAME="e2000d_freertos_a32" # # Example Configuration # -CONFIG_EXAMPLE_IPV4_ONLY=y -# CONFIG_EXAMPLE_IPV6_ONLY is not set +CONFIG_EXAMPLE_IPV4_V6=y +# CONFIG_EXAMPLE_IPV4_ONLY is not set CONFIG_EXAMPLE_IPV4=y +CONFIG_EXAMPLE_IPV6=y CONFIG_EXAMPLE_MULTICAST_IPV4_ADDR="232.10.12.10" +CONFIG_EXAMPLE_MULTICAST_IPV6_ADDR="FF02::FD" CONFIG_EXAMPLE_PORT=6750 # CONFIG_EXAMPLE_LOOPBACK is not set CONFIG_EXAMPLE_MULTICAST_TTL=255 @@ -100,6 +102,7 @@ CONFIG_FXMAC_PHY_COMMON=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -144,6 +147,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -180,6 +192,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # CONFIG_FREERTOS_USE_XMAC=y +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -201,12 +214,6 @@ CONFIG_FREERTOS_USE_XMAC=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -218,13 +225,37 @@ CONFIG_FREERTOS_USE_XMAC=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # CONFIG_USE_LWIP=y +# +# LWIP Freertos Port Configuration +# +CONFIG_LWIP_FXMAC=y +# CONFIG_LWIP_FGMAC is not set + # # LWIP Configuration # @@ -232,99 +263,43 @@ CONFIG_USE_LWIP=y # # LWIP Port Configuration # -# CONFIG_LWIP_FGMAC is not set -CONFIG_LWIP_FXMAC=y +# CONFIG_LWIP_PORT_DEBUG_EN is not set # end of LWIP Port Configuration +# CONFIG_LWIP_NO_SYS is not set CONFIG_LWIP_LOCAL_HOSTNAME="phytium" # -# memory configuration +# Memory configuration # # CONFIG_LWIP_USE_MEM_POOL is not set CONFIG_LWIP_USE_MEM_HEAP=y CONFIG_MEM_SIZE=1 CONFIG_MEM_ALIGNMENT=64 -# end of memory configuration - -# -# NETWORK_INTERFACE_OPTIONS -# -# CONFIG_LWIP_NETIF_API is not set -# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set -# end of NETWORK_INTERFACE_OPTIONS - -# -# LOOPIF -# -CONFIG_LWIP_NETIF_LOOPBACK=y -CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 -# end of LOOPIF - -# -# SLIPIF -# -# CONFIG_LWIP_SLIP_SUPPORT is not set -# end of SLIPIF +# end of Memory configuration # # Pbuf options # CONFIG_PBUF_POOL_BUFSIZE=2 -# end of Pbuf options - -# -# Internal Memory Pool Sizes -# CONFIG_PBUF_POOL_SIZE=1 -# end of Internal Memory Pool Sizes - -CONFIG_LWIP_MAX_SOCKETS=10 - -# -# LWIP RAW API -# -CONFIG_LWIP_MAX_RAW_PCBS=16 -# end of LWIP RAW API - -# -# TCP -# -CONFIG_LWIP_MAX_ACTIVE_TCP=16 -CONFIG_LWIP_MAX_LISTENING_TCP=16 -CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y -CONFIG_LWIP_TCP_MAXRTX=12 -CONFIG_LWIP_TCP_SYNMAXRTX=12 -CONFIG_LWIP_TCP_MSS=1440 -CONFIG_LWIP_TCP_TMR_INTERVAL=250 -CONFIG_LWIP_TCP_MSL=60000 -CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 -CONFIG_LWIP_TCP_WND_DEFAULT=5744 -CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 -CONFIG_LWIP_TCP_QUEUE_OOSEQ=y -# CONFIG_LWIP_TCP_SACK_OUT is not set -CONFIG_LWIP_TCP_OVERSIZE_MSS=y -# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set -# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set -# end of TCP +# end of Pbuf options # -# UDP +# ARP # -CONFIG_LWIP_MAX_UDP_PCBS=16 -CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 -# CONFIG_LWIP_NETBUF_RECVINFO is not set -# end of UDP +CONFIG_ARP_QUEUEING_EN=y +# end of ARP # -# IPv4 +# IPV4 # -CONFIG_USE_IPV4_ONLY=y +# CONFIG_USE_IPV4_ONLY is not set CONFIG_LWIP_IP4_REASSEMBLY=y CONFIG_LWIP_IP4_FRAG=y # CONFIG_LWIP_IP_FORWARD is not set CONFIG_IP_REASS_MAX_PBUFS=45 -# end of IPv4 +# end of IPV4 # # ICMP @@ -334,10 +309,17 @@ CONFIG_LWIP_MULTICAST_PING=y # CONFIG_LWIP_BROADCAST_PING is not set # end of ICMP +# +# LWIP RAW API +# +CONFIG_LWIP_RAW_API_EN=y +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + # # DHCP # -# CONFIG_LWIP_DHCP_ENABLE is not set +CONFIG_LWIP_DHCP_ENABLE=y # CONFIG_LWIP_DHCP_DOES_ARP_CHECK is not set # CONFIG_LWIP_DHCP_GET_NTP_SRV is not set # CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set @@ -352,6 +334,12 @@ CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y # CONFIG_LWIP_AUTOIP is not set # end of AUTOIP +# +# IGMP +# +CONFIG_LWIP_IGMP_EN=y +# end of IGMP + # # DNS # @@ -359,20 +347,65 @@ CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y # end of DNS # -# TCP options +# UDP # +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# CONFIG_LWIP_NETBUF_RECVINFO is not set +# end of UDP + +# +# TCP +# +CONFIG_LWIP_TCP_WND_DEFAULT=5744 +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +# CONFIG_LWIP_TCP_SACK_OUT is not set +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 CONFIG_LWIP_TCP_RTO_TIME=1500 -# end of TCP options +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +# end of TCP + +# +# Network_Interface +# +# CONFIG_LWIP_NETIF_API is not set +# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set +# end of Network_Interface + +# +# LOOPIF +# +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 +# end of LOOPIF + +# +# SLIPIF +# +# CONFIG_LWIP_SLIP_SUPPORT is not set +# end of SLIPIF CONFIG_LWIP_TCPIP_CORE_LOCKING=y # -# socket +# Socket # +CONFIG_LWIP_MAX_SOCKETS=10 # CONFIG_LWIP_SO_LINGER is not set CONFIG_LWIP_SO_REUSE=y CONFIG_LWIP_SO_REUSE_RXTOALL=y -# end of socket +# end of Socket # CONFIG_LWIP_STATS is not set @@ -380,6 +413,8 @@ CONFIG_LWIP_SO_REUSE_RXTOALL=y # PPP # # CONFIG_LWIP_PPP_SUPPORT is not set +CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 +CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 # end of PPP # @@ -391,12 +426,18 @@ CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y # end of Checksums # -# ipv6 +# IPV6 # -# CONFIG_LWIP_IPV6 is not set -# end of ipv6 +CONFIG_LWIP_IPV6=y +# CONFIG_LWIP_IPV6_AUTOCONFIG is not set +CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 +# CONFIG_LWIP_IPV6_FORWARD is not set +CONFIG_LWIP_IP6_FRAG=y +# CONFIG_LWIP_IP6_REASSEMBLY is not set +# end of IPV6 CONFIG_LWIP_DEBUG=y +# CONFIG_LWIP_DEBUG_ESP_LOG is not set CONFIG_LWIP_NETIF_DEBUG=y # CONFIG_LWIP_PBUF_DEBUG is not set # CONFIG_LWIP_ETHARP_DEBUG is not set @@ -404,16 +445,41 @@ CONFIG_LWIP_NETIF_DEBUG=y # CONFIG_LWIP_SOCKETS_DEBUG is not set # CONFIG_LWIP_IP_DEBUG is not set # CONFIG_LWIP_ICMP_DEBUG is not set +# CONFIG_LWIP_DHCP_STATE_DEBUG is not set # CONFIG_LWIP_DHCP_DEBUG is not set # CONFIG_LWIP_IP6_DEBUG is not set # CONFIG_LWIP_ICMP6_DEBUG is not set # CONFIG_LWIP_TCP_DEBUG is not set +# CONFIG_LWIP_UDP_DEBUG is not set # CONFIG_LWIP_SNTP_DEBUG is not set # CONFIG_LWIP_DNS_DEBUG is not set # end of LWIP Configuration +# +# Tcp/ip task resource configuration +# +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_PRIO=6 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +# end of Tcp/ip task resource configuration + +# +# lwip port thread Configuration +# +CONFIG_LWIP_PORT_USE_RECEIVE_THREAD=y +CONFIG_LWIP_PORT_RECEIVE_THREAD_STACKSIZE=1024 +CONFIG_LWIP_PORT_RECEIVE_THREAD_PRIORITY=5 +CONFIG_LWIP_PORT_USE_LINK_DETECT_THREAD=y +CONFIG_LWIP_PORT_LINK_DETECT_STACKSIZE=1024 +CONFIG_LWIP_PORT_LINK_DETECT_PRIORITY=5 +CONFIG_LWIP_PORT_DHCP_THREAD=y +CONFIG_LWIP_PORT_DHCP_STACKSIZE=2048 +CONFIG_LWIP_PORT_DHCP_PRIORITY=5 +# end of lwip port thread Configuration +# end of LWIP Freertos Port Configuration + CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -431,4 +497,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/network/sockets/udp_multicast/configs/e2000d_aarch64_eg_configs b/example/network/sockets/udp_multicast/configs/e2000d_aarch64_eg_configs index beb1c22b..001c0d97 100644 --- a/example/network/sockets/udp_multicast/configs/e2000d_aarch64_eg_configs +++ b/example/network/sockets/udp_multicast/configs/e2000d_aarch64_eg_configs @@ -2,18 +2,21 @@ # # Project Configuration # -CONFIG_TARGET_NAME="e2000_lwip_multicast" +CONFIG_TARGET_NAME="e2000d_freertos_a64" # # Example Configuration # +CONFIG_EXAMPLE_IPV4_V6=y # CONFIG_EXAMPLE_IPV4_ONLY is not set -CONFIG_EXAMPLE_IPV6_ONLY=y +CONFIG_EXAMPLE_IPV4=y CONFIG_EXAMPLE_IPV6=y +CONFIG_EXAMPLE_MULTICAST_IPV4_ADDR="232.10.12.10" CONFIG_EXAMPLE_MULTICAST_IPV6_ADDR="FF02::FD" CONFIG_EXAMPLE_PORT=6750 # CONFIG_EXAMPLE_LOOPBACK is not set CONFIG_EXAMPLE_MULTICAST_TTL=255 +# CONFIG_EXAMPLE_MULTICAST_LISTEN_ALL_IF is not set CONFIG_EXAMPLE_MULTICAST_LISTEN_DEFAULT_IF=y # end of Example Configuration @@ -99,6 +102,7 @@ CONFIG_FXMAC_PHY_COMMON=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -139,6 +143,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -175,6 +188,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # CONFIG_FREERTOS_USE_XMAC=y +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -196,12 +210,6 @@ CONFIG_FREERTOS_USE_XMAC=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -213,13 +221,37 @@ CONFIG_FREERTOS_USE_XMAC=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # CONFIG_USE_LWIP=y +# +# LWIP Freertos Port Configuration +# +CONFIG_LWIP_FXMAC=y +# CONFIG_LWIP_FGMAC is not set + # # LWIP Configuration # @@ -227,99 +259,43 @@ CONFIG_USE_LWIP=y # # LWIP Port Configuration # -# CONFIG_LWIP_FGMAC is not set -CONFIG_LWIP_FXMAC=y +# CONFIG_LWIP_PORT_DEBUG_EN is not set # end of LWIP Port Configuration +# CONFIG_LWIP_NO_SYS is not set CONFIG_LWIP_LOCAL_HOSTNAME="phytium" # -# memory configuration +# Memory configuration # # CONFIG_LWIP_USE_MEM_POOL is not set CONFIG_LWIP_USE_MEM_HEAP=y CONFIG_MEM_SIZE=1 CONFIG_MEM_ALIGNMENT=64 -# end of memory configuration - -# -# NETWORK_INTERFACE_OPTIONS -# -# CONFIG_LWIP_NETIF_API is not set -# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set -# end of NETWORK_INTERFACE_OPTIONS - -# -# LOOPIF -# -CONFIG_LWIP_NETIF_LOOPBACK=y -CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 -# end of LOOPIF - -# -# SLIPIF -# -# CONFIG_LWIP_SLIP_SUPPORT is not set -# end of SLIPIF +# end of Memory configuration # # Pbuf options # CONFIG_PBUF_POOL_BUFSIZE=2 -# end of Pbuf options - -# -# Internal Memory Pool Sizes -# CONFIG_PBUF_POOL_SIZE=1 -# end of Internal Memory Pool Sizes - -CONFIG_LWIP_MAX_SOCKETS=10 - -# -# LWIP RAW API -# -CONFIG_LWIP_MAX_RAW_PCBS=16 -# end of LWIP RAW API - -# -# TCP -# -CONFIG_LWIP_MAX_ACTIVE_TCP=16 -CONFIG_LWIP_MAX_LISTENING_TCP=16 -CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y -CONFIG_LWIP_TCP_MAXRTX=12 -CONFIG_LWIP_TCP_SYNMAXRTX=12 -CONFIG_LWIP_TCP_MSS=1440 -CONFIG_LWIP_TCP_TMR_INTERVAL=250 -CONFIG_LWIP_TCP_MSL=60000 -CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 -CONFIG_LWIP_TCP_WND_DEFAULT=5744 -CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 -CONFIG_LWIP_TCP_QUEUE_OOSEQ=y -# CONFIG_LWIP_TCP_SACK_OUT is not set -CONFIG_LWIP_TCP_OVERSIZE_MSS=y -# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set -# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set -# end of TCP +# end of Pbuf options # -# UDP +# ARP # -CONFIG_LWIP_MAX_UDP_PCBS=16 -CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 -# CONFIG_LWIP_NETBUF_RECVINFO is not set -# end of UDP +CONFIG_ARP_QUEUEING_EN=y +# end of ARP # -# IPv4 +# IPV4 # # CONFIG_USE_IPV4_ONLY is not set CONFIG_LWIP_IP4_REASSEMBLY=y CONFIG_LWIP_IP4_FRAG=y # CONFIG_LWIP_IP_FORWARD is not set CONFIG_IP_REASS_MAX_PBUFS=45 -# end of IPv4 +# end of IPV4 # # ICMP @@ -329,10 +305,17 @@ CONFIG_LWIP_MULTICAST_PING=y # CONFIG_LWIP_BROADCAST_PING is not set # end of ICMP +# +# LWIP RAW API +# +CONFIG_LWIP_RAW_API_EN=y +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + # # DHCP # -# CONFIG_LWIP_DHCP_ENABLE is not set +CONFIG_LWIP_DHCP_ENABLE=y # CONFIG_LWIP_DHCP_DOES_ARP_CHECK is not set # CONFIG_LWIP_DHCP_GET_NTP_SRV is not set # CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set @@ -347,6 +330,12 @@ CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y # CONFIG_LWIP_AUTOIP is not set # end of AUTOIP +# +# IGMP +# +CONFIG_LWIP_IGMP_EN=y +# end of IGMP + # # DNS # @@ -354,20 +343,65 @@ CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y # end of DNS # -# TCP options +# UDP # +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# CONFIG_LWIP_NETBUF_RECVINFO is not set +# end of UDP + +# +# TCP +# +CONFIG_LWIP_TCP_WND_DEFAULT=5744 +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +# CONFIG_LWIP_TCP_SACK_OUT is not set +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 CONFIG_LWIP_TCP_RTO_TIME=1500 -# end of TCP options +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +# end of TCP + +# +# Network_Interface +# +# CONFIG_LWIP_NETIF_API is not set +# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set +# end of Network_Interface + +# +# LOOPIF +# +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 +# end of LOOPIF + +# +# SLIPIF +# +# CONFIG_LWIP_SLIP_SUPPORT is not set +# end of SLIPIF CONFIG_LWIP_TCPIP_CORE_LOCKING=y # -# socket +# Socket # +CONFIG_LWIP_MAX_SOCKETS=10 # CONFIG_LWIP_SO_LINGER is not set CONFIG_LWIP_SO_REUSE=y CONFIG_LWIP_SO_REUSE_RXTOALL=y -# end of socket +# end of Socket # CONFIG_LWIP_STATS is not set @@ -388,7 +422,7 @@ CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y # end of Checksums # -# ipv6 +# IPV6 # CONFIG_LWIP_IPV6=y # CONFIG_LWIP_IPV6_AUTOCONFIG is not set @@ -396,9 +430,10 @@ CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 # CONFIG_LWIP_IPV6_FORWARD is not set CONFIG_LWIP_IP6_FRAG=y CONFIG_LWIP_IP6_REASSEMBLY=y -# end of ipv6 +# end of IPV6 CONFIG_LWIP_DEBUG=y +# CONFIG_LWIP_DEBUG_ESP_LOG is not set CONFIG_LWIP_NETIF_DEBUG=y # CONFIG_LWIP_PBUF_DEBUG is not set # CONFIG_LWIP_ETHARP_DEBUG is not set @@ -406,16 +441,41 @@ CONFIG_LWIP_NETIF_DEBUG=y # CONFIG_LWIP_SOCKETS_DEBUG is not set # CONFIG_LWIP_IP_DEBUG is not set # CONFIG_LWIP_ICMP_DEBUG is not set +# CONFIG_LWIP_DHCP_STATE_DEBUG is not set # CONFIG_LWIP_DHCP_DEBUG is not set # CONFIG_LWIP_IP6_DEBUG is not set # CONFIG_LWIP_ICMP6_DEBUG is not set # CONFIG_LWIP_TCP_DEBUG is not set +# CONFIG_LWIP_UDP_DEBUG is not set # CONFIG_LWIP_SNTP_DEBUG is not set # CONFIG_LWIP_DNS_DEBUG is not set # end of LWIP Configuration +# +# Tcp/ip task resource configuration +# +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_PRIO=6 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +# end of Tcp/ip task resource configuration + +# +# lwip port thread Configuration +# +CONFIG_LWIP_PORT_USE_RECEIVE_THREAD=y +CONFIG_LWIP_PORT_RECEIVE_THREAD_STACKSIZE=2048 +CONFIG_LWIP_PORT_RECEIVE_THREAD_PRIORITY=5 +CONFIG_LWIP_PORT_USE_LINK_DETECT_THREAD=y +CONFIG_LWIP_PORT_LINK_DETECT_STACKSIZE=2048 +CONFIG_LWIP_PORT_LINK_DETECT_PRIORITY=5 +CONFIG_LWIP_PORT_DHCP_THREAD=y +CONFIG_LWIP_PORT_DHCP_STACKSIZE=4096 +CONFIG_LWIP_PORT_DHCP_PRIORITY=5 +# end of lwip port thread Configuration +# end of LWIP Freertos Port Configuration + CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -433,4 +493,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/network/sockets/udp_multicast/configs/e2000q_aarch32_eg_configs b/example/network/sockets/udp_multicast/configs/e2000q_aarch32_eg_configs index c82eb6f4..8af9bc78 100644 --- a/example/network/sockets/udp_multicast/configs/e2000q_aarch32_eg_configs +++ b/example/network/sockets/udp_multicast/configs/e2000q_aarch32_eg_configs @@ -2,20 +2,22 @@ # # Project Configuration # -CONFIG_TARGET_NAME="e2000_lwip_multicast" +CONFIG_TARGET_NAME="e2000q_freertos_a32" # # Example Configuration # -CONFIG_EXAMPLE_IPV4_ONLY=y -# CONFIG_EXAMPLE_IPV6_ONLY is not set +CONFIG_EXAMPLE_IPV4_V6=y +# CONFIG_EXAMPLE_IPV4_ONLY is not set CONFIG_EXAMPLE_IPV4=y +CONFIG_EXAMPLE_IPV6=y CONFIG_EXAMPLE_MULTICAST_IPV4_ADDR="232.10.12.10" +CONFIG_EXAMPLE_MULTICAST_IPV6_ADDR="FF02::FD" CONFIG_EXAMPLE_PORT=6750 # CONFIG_EXAMPLE_LOOPBACK is not set CONFIG_EXAMPLE_MULTICAST_TTL=255 -CONFIG_EXAMPLE_MULTICAST_LISTEN_ALL_IF=y -# CONFIG_EXAMPLE_MULTICAST_LISTEN_DEFAULT_IF is not set +# CONFIG_EXAMPLE_MULTICAST_LISTEN_ALL_IF is not set +CONFIG_EXAMPLE_MULTICAST_LISTEN_DEFAULT_IF=y # end of Example Configuration # @@ -100,6 +102,7 @@ CONFIG_FXMAC_PHY_COMMON=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -144,6 +147,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -180,6 +192,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # CONFIG_FREERTOS_USE_XMAC=y +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -201,12 +214,6 @@ CONFIG_FREERTOS_USE_XMAC=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -218,13 +225,37 @@ CONFIG_FREERTOS_USE_XMAC=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # CONFIG_USE_LWIP=y +# +# LWIP Freertos Port Configuration +# +CONFIG_LWIP_FXMAC=y +# CONFIG_LWIP_FGMAC is not set + # # LWIP Configuration # @@ -232,99 +263,43 @@ CONFIG_USE_LWIP=y # # LWIP Port Configuration # -# CONFIG_LWIP_FGMAC is not set -CONFIG_LWIP_FXMAC=y +# CONFIG_LWIP_PORT_DEBUG_EN is not set # end of LWIP Port Configuration +# CONFIG_LWIP_NO_SYS is not set CONFIG_LWIP_LOCAL_HOSTNAME="phytium" # -# memory configuration +# Memory configuration # # CONFIG_LWIP_USE_MEM_POOL is not set CONFIG_LWIP_USE_MEM_HEAP=y CONFIG_MEM_SIZE=1 CONFIG_MEM_ALIGNMENT=64 -# end of memory configuration - -# -# NETWORK_INTERFACE_OPTIONS -# -# CONFIG_LWIP_NETIF_API is not set -# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set -# end of NETWORK_INTERFACE_OPTIONS - -# -# LOOPIF -# -CONFIG_LWIP_NETIF_LOOPBACK=y -CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 -# end of LOOPIF - -# -# SLIPIF -# -# CONFIG_LWIP_SLIP_SUPPORT is not set -# end of SLIPIF +# end of Memory configuration # # Pbuf options # CONFIG_PBUF_POOL_BUFSIZE=2 -# end of Pbuf options - -# -# Internal Memory Pool Sizes -# CONFIG_PBUF_POOL_SIZE=1 -# end of Internal Memory Pool Sizes - -CONFIG_LWIP_MAX_SOCKETS=10 - -# -# LWIP RAW API -# -CONFIG_LWIP_MAX_RAW_PCBS=16 -# end of LWIP RAW API - -# -# TCP -# -CONFIG_LWIP_MAX_ACTIVE_TCP=16 -CONFIG_LWIP_MAX_LISTENING_TCP=16 -CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y -CONFIG_LWIP_TCP_MAXRTX=12 -CONFIG_LWIP_TCP_SYNMAXRTX=12 -CONFIG_LWIP_TCP_MSS=1440 -CONFIG_LWIP_TCP_TMR_INTERVAL=250 -CONFIG_LWIP_TCP_MSL=60000 -CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 -CONFIG_LWIP_TCP_WND_DEFAULT=5744 -CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 -CONFIG_LWIP_TCP_QUEUE_OOSEQ=y -# CONFIG_LWIP_TCP_SACK_OUT is not set -CONFIG_LWIP_TCP_OVERSIZE_MSS=y -# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set -# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set -# end of TCP +# end of Pbuf options # -# UDP +# ARP # -CONFIG_LWIP_MAX_UDP_PCBS=16 -CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 -# CONFIG_LWIP_NETBUF_RECVINFO is not set -# end of UDP +CONFIG_ARP_QUEUEING_EN=y +# end of ARP # -# IPv4 +# IPV4 # -CONFIG_USE_IPV4_ONLY=y +# CONFIG_USE_IPV4_ONLY is not set CONFIG_LWIP_IP4_REASSEMBLY=y CONFIG_LWIP_IP4_FRAG=y # CONFIG_LWIP_IP_FORWARD is not set CONFIG_IP_REASS_MAX_PBUFS=45 -# end of IPv4 +# end of IPV4 # # ICMP @@ -334,10 +309,17 @@ CONFIG_LWIP_MULTICAST_PING=y # CONFIG_LWIP_BROADCAST_PING is not set # end of ICMP +# +# LWIP RAW API +# +CONFIG_LWIP_RAW_API_EN=y +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + # # DHCP # -# CONFIG_LWIP_DHCP_ENABLE is not set +CONFIG_LWIP_DHCP_ENABLE=y # CONFIG_LWIP_DHCP_DOES_ARP_CHECK is not set # CONFIG_LWIP_DHCP_GET_NTP_SRV is not set # CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set @@ -352,6 +334,12 @@ CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y # CONFIG_LWIP_AUTOIP is not set # end of AUTOIP +# +# IGMP +# +CONFIG_LWIP_IGMP_EN=y +# end of IGMP + # # DNS # @@ -359,20 +347,65 @@ CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y # end of DNS # -# TCP options +# UDP # +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# CONFIG_LWIP_NETBUF_RECVINFO is not set +# end of UDP + +# +# TCP +# +CONFIG_LWIP_TCP_WND_DEFAULT=5744 +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +# CONFIG_LWIP_TCP_SACK_OUT is not set +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 CONFIG_LWIP_TCP_RTO_TIME=1500 -# end of TCP options +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +# end of TCP + +# +# Network_Interface +# +# CONFIG_LWIP_NETIF_API is not set +# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set +# end of Network_Interface + +# +# LOOPIF +# +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 +# end of LOOPIF + +# +# SLIPIF +# +# CONFIG_LWIP_SLIP_SUPPORT is not set +# end of SLIPIF CONFIG_LWIP_TCPIP_CORE_LOCKING=y # -# socket +# Socket # +CONFIG_LWIP_MAX_SOCKETS=10 # CONFIG_LWIP_SO_LINGER is not set CONFIG_LWIP_SO_REUSE=y CONFIG_LWIP_SO_REUSE_RXTOALL=y -# end of socket +# end of Socket # CONFIG_LWIP_STATS is not set @@ -393,7 +426,7 @@ CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y # end of Checksums # -# ipv6 +# IPV6 # CONFIG_LWIP_IPV6=y # CONFIG_LWIP_IPV6_AUTOCONFIG is not set @@ -401,9 +434,10 @@ CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 # CONFIG_LWIP_IPV6_FORWARD is not set CONFIG_LWIP_IP6_FRAG=y # CONFIG_LWIP_IP6_REASSEMBLY is not set -# end of ipv6 +# end of IPV6 CONFIG_LWIP_DEBUG=y +# CONFIG_LWIP_DEBUG_ESP_LOG is not set CONFIG_LWIP_NETIF_DEBUG=y # CONFIG_LWIP_PBUF_DEBUG is not set # CONFIG_LWIP_ETHARP_DEBUG is not set @@ -411,16 +445,41 @@ CONFIG_LWIP_NETIF_DEBUG=y # CONFIG_LWIP_SOCKETS_DEBUG is not set # CONFIG_LWIP_IP_DEBUG is not set # CONFIG_LWIP_ICMP_DEBUG is not set +# CONFIG_LWIP_DHCP_STATE_DEBUG is not set # CONFIG_LWIP_DHCP_DEBUG is not set # CONFIG_LWIP_IP6_DEBUG is not set # CONFIG_LWIP_ICMP6_DEBUG is not set # CONFIG_LWIP_TCP_DEBUG is not set +# CONFIG_LWIP_UDP_DEBUG is not set # CONFIG_LWIP_SNTP_DEBUG is not set # CONFIG_LWIP_DNS_DEBUG is not set # end of LWIP Configuration +# +# Tcp/ip task resource configuration +# +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_PRIO=6 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +# end of Tcp/ip task resource configuration + +# +# lwip port thread Configuration +# +CONFIG_LWIP_PORT_USE_RECEIVE_THREAD=y +CONFIG_LWIP_PORT_RECEIVE_THREAD_STACKSIZE=1024 +CONFIG_LWIP_PORT_RECEIVE_THREAD_PRIORITY=5 +CONFIG_LWIP_PORT_USE_LINK_DETECT_THREAD=y +CONFIG_LWIP_PORT_LINK_DETECT_STACKSIZE=1024 +CONFIG_LWIP_PORT_LINK_DETECT_PRIORITY=5 +CONFIG_LWIP_PORT_DHCP_THREAD=y +CONFIG_LWIP_PORT_DHCP_STACKSIZE=2048 +CONFIG_LWIP_PORT_DHCP_PRIORITY=5 +# end of lwip port thread Configuration +# end of LWIP Freertos Port Configuration + CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -438,4 +497,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/network/sockets/udp_multicast/configs/e2000q_aarch64_eg_configs b/example/network/sockets/udp_multicast/configs/e2000q_aarch64_eg_configs index 553b290d..f19c54f7 100644 --- a/example/network/sockets/udp_multicast/configs/e2000q_aarch64_eg_configs +++ b/example/network/sockets/udp_multicast/configs/e2000q_aarch64_eg_configs @@ -2,18 +2,21 @@ # # Project Configuration # -CONFIG_TARGET_NAME="e2000_lwip_multicast" +CONFIG_TARGET_NAME="e2000q_freertos_a64" # # Example Configuration # +CONFIG_EXAMPLE_IPV4_V6=y # CONFIG_EXAMPLE_IPV4_ONLY is not set -CONFIG_EXAMPLE_IPV6_ONLY=y +CONFIG_EXAMPLE_IPV4=y CONFIG_EXAMPLE_IPV6=y +CONFIG_EXAMPLE_MULTICAST_IPV4_ADDR="232.10.12.10" CONFIG_EXAMPLE_MULTICAST_IPV6_ADDR="FF02::FD" CONFIG_EXAMPLE_PORT=6750 # CONFIG_EXAMPLE_LOOPBACK is not set CONFIG_EXAMPLE_MULTICAST_TTL=255 +# CONFIG_EXAMPLE_MULTICAST_LISTEN_ALL_IF is not set CONFIG_EXAMPLE_MULTICAST_LISTEN_DEFAULT_IF=y # end of Example Configuration @@ -99,6 +102,7 @@ CONFIG_FXMAC_PHY_COMMON=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -139,6 +143,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -175,6 +188,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # CONFIG_FREERTOS_USE_XMAC=y +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -196,12 +210,6 @@ CONFIG_FREERTOS_USE_XMAC=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -213,13 +221,37 @@ CONFIG_FREERTOS_USE_XMAC=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # CONFIG_USE_LWIP=y +# +# LWIP Freertos Port Configuration +# +CONFIG_LWIP_FXMAC=y +# CONFIG_LWIP_FGMAC is not set + # # LWIP Configuration # @@ -227,99 +259,43 @@ CONFIG_USE_LWIP=y # # LWIP Port Configuration # -# CONFIG_LWIP_FGMAC is not set -CONFIG_LWIP_FXMAC=y +# CONFIG_LWIP_PORT_DEBUG_EN is not set # end of LWIP Port Configuration +# CONFIG_LWIP_NO_SYS is not set CONFIG_LWIP_LOCAL_HOSTNAME="phytium" # -# memory configuration +# Memory configuration # # CONFIG_LWIP_USE_MEM_POOL is not set CONFIG_LWIP_USE_MEM_HEAP=y CONFIG_MEM_SIZE=1 CONFIG_MEM_ALIGNMENT=64 -# end of memory configuration - -# -# NETWORK_INTERFACE_OPTIONS -# -# CONFIG_LWIP_NETIF_API is not set -# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set -# end of NETWORK_INTERFACE_OPTIONS - -# -# LOOPIF -# -CONFIG_LWIP_NETIF_LOOPBACK=y -CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 -# end of LOOPIF - -# -# SLIPIF -# -# CONFIG_LWIP_SLIP_SUPPORT is not set -# end of SLIPIF +# end of Memory configuration # # Pbuf options # CONFIG_PBUF_POOL_BUFSIZE=2 -# end of Pbuf options - -# -# Internal Memory Pool Sizes -# CONFIG_PBUF_POOL_SIZE=1 -# end of Internal Memory Pool Sizes - -CONFIG_LWIP_MAX_SOCKETS=10 - -# -# LWIP RAW API -# -CONFIG_LWIP_MAX_RAW_PCBS=16 -# end of LWIP RAW API - -# -# TCP -# -CONFIG_LWIP_MAX_ACTIVE_TCP=16 -CONFIG_LWIP_MAX_LISTENING_TCP=16 -CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y -CONFIG_LWIP_TCP_MAXRTX=12 -CONFIG_LWIP_TCP_SYNMAXRTX=12 -CONFIG_LWIP_TCP_MSS=1440 -CONFIG_LWIP_TCP_TMR_INTERVAL=250 -CONFIG_LWIP_TCP_MSL=60000 -CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 -CONFIG_LWIP_TCP_WND_DEFAULT=5744 -CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 -CONFIG_LWIP_TCP_QUEUE_OOSEQ=y -# CONFIG_LWIP_TCP_SACK_OUT is not set -CONFIG_LWIP_TCP_OVERSIZE_MSS=y -# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set -# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set -# end of TCP +# end of Pbuf options # -# UDP +# ARP # -CONFIG_LWIP_MAX_UDP_PCBS=16 -CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 -# CONFIG_LWIP_NETBUF_RECVINFO is not set -# end of UDP +CONFIG_ARP_QUEUEING_EN=y +# end of ARP # -# IPv4 +# IPV4 # # CONFIG_USE_IPV4_ONLY is not set CONFIG_LWIP_IP4_REASSEMBLY=y CONFIG_LWIP_IP4_FRAG=y # CONFIG_LWIP_IP_FORWARD is not set CONFIG_IP_REASS_MAX_PBUFS=45 -# end of IPv4 +# end of IPV4 # # ICMP @@ -329,10 +305,17 @@ CONFIG_LWIP_MULTICAST_PING=y # CONFIG_LWIP_BROADCAST_PING is not set # end of ICMP +# +# LWIP RAW API +# +CONFIG_LWIP_RAW_API_EN=y +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + # # DHCP # -# CONFIG_LWIP_DHCP_ENABLE is not set +CONFIG_LWIP_DHCP_ENABLE=y # CONFIG_LWIP_DHCP_DOES_ARP_CHECK is not set # CONFIG_LWIP_DHCP_GET_NTP_SRV is not set # CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set @@ -347,6 +330,12 @@ CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y # CONFIG_LWIP_AUTOIP is not set # end of AUTOIP +# +# IGMP +# +CONFIG_LWIP_IGMP_EN=y +# end of IGMP + # # DNS # @@ -354,20 +343,65 @@ CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y # end of DNS # -# TCP options +# UDP # +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# CONFIG_LWIP_NETBUF_RECVINFO is not set +# end of UDP + +# +# TCP +# +CONFIG_LWIP_TCP_WND_DEFAULT=5744 +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +# CONFIG_LWIP_TCP_SACK_OUT is not set +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 CONFIG_LWIP_TCP_RTO_TIME=1500 -# end of TCP options +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +# end of TCP + +# +# Network_Interface +# +# CONFIG_LWIP_NETIF_API is not set +# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set +# end of Network_Interface + +# +# LOOPIF +# +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 +# end of LOOPIF + +# +# SLIPIF +# +# CONFIG_LWIP_SLIP_SUPPORT is not set +# end of SLIPIF CONFIG_LWIP_TCPIP_CORE_LOCKING=y # -# socket +# Socket # +CONFIG_LWIP_MAX_SOCKETS=10 # CONFIG_LWIP_SO_LINGER is not set CONFIG_LWIP_SO_REUSE=y CONFIG_LWIP_SO_REUSE_RXTOALL=y -# end of socket +# end of Socket # CONFIG_LWIP_STATS is not set @@ -388,7 +422,7 @@ CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y # end of Checksums # -# ipv6 +# IPV6 # CONFIG_LWIP_IPV6=y # CONFIG_LWIP_IPV6_AUTOCONFIG is not set @@ -396,9 +430,10 @@ CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 # CONFIG_LWIP_IPV6_FORWARD is not set CONFIG_LWIP_IP6_FRAG=y CONFIG_LWIP_IP6_REASSEMBLY=y -# end of ipv6 +# end of IPV6 CONFIG_LWIP_DEBUG=y +# CONFIG_LWIP_DEBUG_ESP_LOG is not set CONFIG_LWIP_NETIF_DEBUG=y # CONFIG_LWIP_PBUF_DEBUG is not set # CONFIG_LWIP_ETHARP_DEBUG is not set @@ -406,16 +441,41 @@ CONFIG_LWIP_NETIF_DEBUG=y # CONFIG_LWIP_SOCKETS_DEBUG is not set # CONFIG_LWIP_IP_DEBUG is not set # CONFIG_LWIP_ICMP_DEBUG is not set +# CONFIG_LWIP_DHCP_STATE_DEBUG is not set # CONFIG_LWIP_DHCP_DEBUG is not set # CONFIG_LWIP_IP6_DEBUG is not set # CONFIG_LWIP_ICMP6_DEBUG is not set # CONFIG_LWIP_TCP_DEBUG is not set +# CONFIG_LWIP_UDP_DEBUG is not set # CONFIG_LWIP_SNTP_DEBUG is not set # CONFIG_LWIP_DNS_DEBUG is not set # end of LWIP Configuration +# +# Tcp/ip task resource configuration +# +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_PRIO=6 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +# end of Tcp/ip task resource configuration + +# +# lwip port thread Configuration +# +CONFIG_LWIP_PORT_USE_RECEIVE_THREAD=y +CONFIG_LWIP_PORT_RECEIVE_THREAD_STACKSIZE=2048 +CONFIG_LWIP_PORT_RECEIVE_THREAD_PRIORITY=5 +CONFIG_LWIP_PORT_USE_LINK_DETECT_THREAD=y +CONFIG_LWIP_PORT_LINK_DETECT_STACKSIZE=2048 +CONFIG_LWIP_PORT_LINK_DETECT_PRIORITY=5 +CONFIG_LWIP_PORT_DHCP_THREAD=y +CONFIG_LWIP_PORT_DHCP_STACKSIZE=4096 +CONFIG_LWIP_PORT_DHCP_PRIORITY=5 +# end of lwip port thread Configuration +# end of LWIP Freertos Port Configuration + CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -433,4 +493,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/network/sockets/udp_multicast/configs/ft2004_aarch32_eg_configs b/example/network/sockets/udp_multicast/configs/ft2004_aarch32_eg_configs new file mode 100644 index 00000000..d68e3ccd --- /dev/null +++ b/example/network/sockets/udp_multicast/configs/ft2004_aarch32_eg_configs @@ -0,0 +1,514 @@ + +# +# Project Configuration +# +CONFIG_TARGET_NAME="ft2004_freertos_a32" + +# +# Example Configuration +# +CONFIG_EXAMPLE_IPV4_V6=y +# CONFIG_EXAMPLE_IPV4_ONLY is not set +CONFIG_EXAMPLE_IPV4=y +CONFIG_EXAMPLE_IPV6=y +CONFIG_EXAMPLE_MULTICAST_IPV4_ADDR="232.10.12.10" +CONFIG_EXAMPLE_MULTICAST_IPV6_ADDR="FF02::FD" +CONFIG_EXAMPLE_PORT=6750 +# CONFIG_EXAMPLE_LOOPBACK is not set +CONFIG_EXAMPLE_MULTICAST_TTL=1 +# CONFIG_EXAMPLE_MULTICAST_LISTEN_ALL_IF is not set +CONFIG_EXAMPLE_MULTICAST_LISTEN_DEFAULT_IF=y +# end of Example Configuration +# end of Project Configuration + +# +# Standalone Setting +# +CONFIG_USE_FREERTOS=y + +# +# Arch Configuration +# +CONFIG_TARGET_ARMV8_AARCH32=y +# CONFIG_TARGET_ARMV8_AARCH64 is not set +CONFIG_USE_CACHE=y +# CONFIG_USE_L3CACHE is not set +CONFIG_USE_MMU=y +CONFIG_USE_SYS_TICK=y +CONFIG_USE_AARCH64_L1_TO_AARCH32=y +# end of Arch Configuration + +# +# Board Configuration +# +CONFIG_TARGET_F2000_4=y +# CONFIG_TARGET_D2000 is not set +# CONFIG_TARGET_E2000Q is not set +# CONFIG_TARGET_E2000D is not set +# CONFIG_TARGET_E2000S is not set +CONFIG_DEFAULT_DEBUG_PRINT_UART1=y +# CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set +# CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set +# end of Board Configuration + +# +# Components Configuration +# +# CONFIG_USE_SPI is not set +# CONFIG_USE_QSPI is not set +CONFIG_USE_GIC=y +CONFIG_ENABLE_GICV3=y +CONFIG_USE_SERIAL=y + +# +# Usart Configuration +# +CONFIG_ENABLE_Pl011_UART=y +# end of Usart Configuration + +# CONFIG_USE_GPIO is not set +CONFIG_USE_ETH=y + +# +# Eth Configuration +# +# CONFIG_ENABLE_FXMAC is not set +CONFIG_ENABLE_FGMAC=y +CONFIG_FGMAC_PHY_COMMON=y +# CONFIG_FGMAC_PHY_AR803X is not set +# end of Eth Configuration + +# CONFIG_USE_CAN is not set +# CONFIG_USE_I2C is not set +# CONFIG_USE_TIMER is not set +# CONFIG_USE_MIO is not set +# CONFIG_USE_SDMMC is not set +# CONFIG_USE_PCIE is not set +# CONFIG_USE_WDT is not set +# CONFIG_USE_DMA is not set +# CONFIG_USE_NAND is not set +# CONFIG_USE_RTC is not set +# CONFIG_USE_SATA is not set +# CONFIG_USE_USB is not set +# CONFIG_USE_ADC is not set +# CONFIG_USE_PWM is not set +# CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set +# end of Components Configuration + +CONFIG_USE_NEW_LIBC=y +# end of Standalone Setting + +# +# Building Option +# +# CONFIG_LOG_VERBOS is not set +# CONFIG_LOG_DEBUG is not set +# CONFIG_LOG_INFO is not set +# CONFIG_LOG_WARN is not set +CONFIG_LOG_ERROR=y +# CONFIG_LOG_NONE is not set +CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y +CONFIG_INTERRUPT_ROLE_MASTER=y +# CONFIG_INTERRUPT_ROLE_SLAVE is not set +# CONFIG_LOG_EXTRA_INFO is not set +# CONFIG_BOOTUP_DEBUG_PRINTS is not set + +# +# Linker Options +# +CONFIG_AARCH32_RAM_LD=y +# CONFIG_AARCH64_RAM_LD is not set +# CONFIG_USER_DEFINED_LD is not set +CONFIG_LINK_SCRIPT_ROM=y +CONFIG_ROM_START_UP_ADDR=0x80100000 +CONFIG_ROM_SIZE_MB=1 +CONFIG_LINK_SCRIPT_RAM=y +CONFIG_RAM_START_UP_ADDR=0x80500000 +CONFIG_RAM_SIZE_MB=64 +CONFIG_HEAP_SIZE=1 +CONFIG_SVC_STACK_SIZE=0x1000 +CONFIG_SYS_STACK_SIZE=0x1000 +CONFIG_IRQ_STACK_SIZE=0x1000 +CONFIG_ABORT_STACK_SIZE=0x1000 +CONFIG_FIQ_STACK_SIZE=0x1000 +CONFIG_UNDEF_STACK_SIZE=0x1000 +# end of Linker Options + +# +# Compiler Options +# + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + +CONFIG_OUTPUT_BINARY=y +# end of Compiler Options +# end of Building Option + +# +# Component Configuration +# + +# +# Freertos Uart Drivers +# +CONFIG_FREERTOS_USE_UART=y +# end of Freertos Uart Drivers + +# +# Freertos Pwm Drivers +# +# CONFIG_FREERTOS_USE_PWM is not set +# end of Freertos Pwm Drivers + +# +# Freertos Qspi Drivers +# +# CONFIG_FREERTOS_USE_QSPI is not set +# end of Freertos Qspi Drivers + +# +# Freertos Wdt Drivers +# +# CONFIG_FREERTOS_USE_WDT is not set +# end of Freertos Wdt Drivers + +# +# Freertos Eth Drivers +# +# CONFIG_FREERTOS_USE_XMAC is not set +CONFIG_FREERTOS_USE_GMAC=y +# end of Freertos Eth Drivers + +# +# Freertos Gpio Drivers +# +# CONFIG_FREERTOS_USE_GPIO is not set +# end of Freertos Gpio Drivers + +# +# Freertos Spim Drivers +# +# CONFIG_FREERTOS_USE_FSPIM is not set +# end of Freertos Spim Drivers + +# +# Freertos DMA Drivers +# +# CONFIG_FREERTOS_USE_FDDMA is not set +# CONFIG_FREERTOS_USE_FGDMA is not set +# end of Freertos DMA Drivers + +# +# Freertos Adc Drivers +# +# CONFIG_FREERTOS_USE_ADC is not set +# end of Freertos Adc Drivers + +# +# Freertos Can Drivers +# +# CONFIG_FREERTOS_USE_CAN is not set +# end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers +# end of Component Configuration + +# +# Third-Party Configuration +# +CONFIG_USE_LWIP=y + +# +# LWIP Freertos Port Configuration +# +# CONFIG_LWIP_FXMAC is not set +CONFIG_LWIP_FGMAC=y + +# +# LWIP Configuration +# + +# +# LWIP Port Configuration +# +# CONFIG_LWIP_PORT_DEBUG_EN is not set +# end of LWIP Port Configuration + +# CONFIG_LWIP_NO_SYS is not set +CONFIG_LWIP_LOCAL_HOSTNAME="phytium" + +# +# Memory configuration +# +# CONFIG_LWIP_USE_MEM_POOL is not set +CONFIG_LWIP_USE_MEM_HEAP=y +CONFIG_MEM_SIZE=2 +CONFIG_MEM_ALIGNMENT=64 +# end of Memory configuration + +# +# Pbuf options +# +CONFIG_PBUF_POOL_BUFSIZE=2 +CONFIG_PBUF_POOL_SIZE=1 +# end of Pbuf options + +# +# ARP +# +CONFIG_ARP_QUEUEING_EN=y +# end of ARP + +# +# IPV4 +# +# CONFIG_USE_IPV4_ONLY is not set +CONFIG_LWIP_IP4_REASSEMBLY=y +CONFIG_LWIP_IP4_FRAG=y +# CONFIG_LWIP_IP_FORWARD is not set +CONFIG_IP_REASS_MAX_PBUFS=16 +# end of IPV4 + +# +# ICMP +# +CONFIG_LWIP_ICMP=y +CONFIG_LWIP_MULTICAST_PING=y +CONFIG_LWIP_BROADCAST_PING=y +# end of ICMP + +# +# LWIP RAW API +# +CONFIG_LWIP_RAW_API_EN=y +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + +# +# DHCP +# +CONFIG_LWIP_DHCP_ENABLE=y +# CONFIG_LWIP_DHCP_DOES_ARP_CHECK is not set +# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set +# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set +# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set +CONFIG_LWIP_DHCP_OPTIONS_LEN=68 +CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y +# end of DHCP + +# +# AUTOIP +# +# CONFIG_LWIP_AUTOIP is not set +# end of AUTOIP + +# +# IGMP +# +CONFIG_LWIP_IGMP_EN=y +# end of IGMP + +# +# DNS +# +CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y +# end of DNS + +# +# UDP +# +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# CONFIG_LWIP_NETBUF_RECVINFO is not set +# end of UDP + +# +# TCP +# +CONFIG_LWIP_TCP_WND_DEFAULT=5744 +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +# CONFIG_LWIP_TCP_SACK_OUT is not set +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 +CONFIG_LWIP_TCP_RTO_TIME=1500 +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +# end of TCP + +# +# Network_Interface +# +# CONFIG_LWIP_NETIF_API is not set +# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set +# end of Network_Interface + +# +# LOOPIF +# +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 +# end of LOOPIF + +# +# SLIPIF +# +# CONFIG_LWIP_SLIP_SUPPORT is not set +# end of SLIPIF + +CONFIG_LWIP_TCPIP_CORE_LOCKING=y + +# +# Socket +# +CONFIG_LWIP_MAX_SOCKETS=10 +# CONFIG_LWIP_SO_LINGER is not set +CONFIG_LWIP_SO_REUSE=y +CONFIG_LWIP_SO_REUSE_RXTOALL=y +# end of Socket + +# CONFIG_LWIP_STATS is not set + +# +# PPP +# +# CONFIG_LWIP_PPP_SUPPORT is not set +CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 +CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 +# end of PPP + +# +# Checksums +# +# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set +# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set +CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y +# end of Checksums + +# +# IPV6 +# +CONFIG_LWIP_IPV6=y +# CONFIG_LWIP_IPV6_AUTOCONFIG is not set +CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 +# CONFIG_LWIP_IPV6_FORWARD is not set +CONFIG_LWIP_IP6_FRAG=y +# CONFIG_LWIP_IP6_REASSEMBLY is not set +# end of IPV6 + +CONFIG_LWIP_DEBUG=y +# CONFIG_LWIP_DEBUG_ESP_LOG is not set +CONFIG_LWIP_NETIF_DEBUG=y +# CONFIG_LWIP_PBUF_DEBUG is not set +# CONFIG_LWIP_ETHARP_DEBUG is not set +# CONFIG_LWIP_API_LIB_DEBUG is not set +# CONFIG_LWIP_SOCKETS_DEBUG is not set +# CONFIG_LWIP_IP_DEBUG is not set +# CONFIG_LWIP_ICMP_DEBUG is not set +# CONFIG_LWIP_DHCP_STATE_DEBUG is not set +# CONFIG_LWIP_DHCP_DEBUG is not set +# CONFIG_LWIP_IP6_DEBUG is not set +# CONFIG_LWIP_ICMP6_DEBUG is not set +# CONFIG_LWIP_TCP_DEBUG is not set +# CONFIG_LWIP_UDP_DEBUG is not set +# CONFIG_LWIP_SNTP_DEBUG is not set +# CONFIG_LWIP_DNS_DEBUG is not set +# end of LWIP Configuration + +# +# Tcp/ip task resource configuration +# +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_PRIO=6 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +# end of Tcp/ip task resource configuration + +# +# lwip port thread Configuration +# +CONFIG_LWIP_PORT_USE_RECEIVE_THREAD=y +CONFIG_LWIP_PORT_RECEIVE_THREAD_STACKSIZE=1024 +CONFIG_LWIP_PORT_RECEIVE_THREAD_PRIORITY=5 +CONFIG_LWIP_PORT_USE_LINK_DETECT_THREAD=y +CONFIG_LWIP_PORT_LINK_DETECT_STACKSIZE=1024 +CONFIG_LWIP_PORT_LINK_DETECT_PRIORITY=5 +CONFIG_LWIP_PORT_DHCP_THREAD=y +CONFIG_LWIP_PORT_DHCP_STACKSIZE=2048 +CONFIG_LWIP_PORT_DHCP_PRIORITY=5 +# end of lwip port thread Configuration +# end of LWIP Freertos Port Configuration + +CONFIG_USE_BACKTRACE=y +# CONFIG_USE_FATFS_0_1_4 is not set +# CONFIG_USE_SFUD is not set +# CONFIG_USE_SPIFFS is not set +# CONFIG_USE_AMP is not set +CONFIG_USE_LETTER_SHELL=y + +# +# Letter Shell Configuration +# +CONFIG_LS_PL011_UART=y +CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y +# CONFIG_DEFAULT_LETTER_SHELL_USE_UART0 is not set +# CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set +# end of Letter Shell Configuration + +CONFIG_USE_TLSF=y +# CONFIG_USE_SDMMC_CMD is not set +# CONFIG_USE_CHERRY_USB is not set +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/network/sockets/udp_multicast/configs/ft2004_aarch64_eg_configs b/example/network/sockets/udp_multicast/configs/ft2004_aarch64_eg_configs new file mode 100644 index 00000000..2d641271 --- /dev/null +++ b/example/network/sockets/udp_multicast/configs/ft2004_aarch64_eg_configs @@ -0,0 +1,510 @@ + +# +# Project Configuration +# +CONFIG_TARGET_NAME="ft20004_freertos_a64" + +# +# Example Configuration +# +CONFIG_EXAMPLE_IPV4_V6=y +# CONFIG_EXAMPLE_IPV4_ONLY is not set +CONFIG_EXAMPLE_IPV4=y +CONFIG_EXAMPLE_IPV6=y +CONFIG_EXAMPLE_MULTICAST_IPV4_ADDR="232.10.12.10" +CONFIG_EXAMPLE_MULTICAST_IPV6_ADDR="FF02::FD" +CONFIG_EXAMPLE_PORT=6750 +# CONFIG_EXAMPLE_LOOPBACK is not set +CONFIG_EXAMPLE_MULTICAST_TTL=1 +# CONFIG_EXAMPLE_MULTICAST_LISTEN_ALL_IF is not set +CONFIG_EXAMPLE_MULTICAST_LISTEN_DEFAULT_IF=y +# end of Example Configuration +# end of Project Configuration + +# +# Standalone Setting +# +CONFIG_USE_FREERTOS=y + +# +# Arch Configuration +# +# CONFIG_TARGET_ARMV8_AARCH32 is not set +CONFIG_TARGET_ARMV8_AARCH64=y +CONFIG_USE_CACHE=y +# CONFIG_USE_L3CACHE is not set +CONFIG_USE_MMU=y +CONFIG_USE_SYS_TICK=y +# CONFIG_MMU_DEBUG_PRINTS is not set +# end of Arch Configuration + +# +# Board Configuration +# +CONFIG_TARGET_F2000_4=y +# CONFIG_TARGET_D2000 is not set +# CONFIG_TARGET_E2000Q is not set +# CONFIG_TARGET_E2000D is not set +# CONFIG_TARGET_E2000S is not set +CONFIG_DEFAULT_DEBUG_PRINT_UART1=y +# CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set +# CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set +# end of Board Configuration + +# +# Components Configuration +# +# CONFIG_USE_SPI is not set +# CONFIG_USE_QSPI is not set +CONFIG_USE_GIC=y +CONFIG_ENABLE_GICV3=y +CONFIG_USE_SERIAL=y + +# +# Usart Configuration +# +CONFIG_ENABLE_Pl011_UART=y +# end of Usart Configuration + +# CONFIG_USE_GPIO is not set +CONFIG_USE_ETH=y + +# +# Eth Configuration +# +# CONFIG_ENABLE_FXMAC is not set +CONFIG_ENABLE_FGMAC=y +CONFIG_FGMAC_PHY_COMMON=y +# CONFIG_FGMAC_PHY_AR803X is not set +# end of Eth Configuration + +# CONFIG_USE_CAN is not set +# CONFIG_USE_I2C is not set +# CONFIG_USE_TIMER is not set +# CONFIG_USE_MIO is not set +# CONFIG_USE_SDMMC is not set +# CONFIG_USE_PCIE is not set +# CONFIG_USE_WDT is not set +# CONFIG_USE_DMA is not set +# CONFIG_USE_NAND is not set +# CONFIG_USE_RTC is not set +# CONFIG_USE_SATA is not set +# CONFIG_USE_USB is not set +# CONFIG_USE_ADC is not set +# CONFIG_USE_PWM is not set +# CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set +# end of Components Configuration + +CONFIG_USE_NEW_LIBC=y +# end of Standalone Setting + +# +# Building Option +# +# CONFIG_LOG_VERBOS is not set +# CONFIG_LOG_DEBUG is not set +# CONFIG_LOG_INFO is not set +# CONFIG_LOG_WARN is not set +CONFIG_LOG_ERROR=y +# CONFIG_LOG_NONE is not set +CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y +CONFIG_INTERRUPT_ROLE_MASTER=y +# CONFIG_INTERRUPT_ROLE_SLAVE is not set +# CONFIG_LOG_EXTRA_INFO is not set +# CONFIG_BOOTUP_DEBUG_PRINTS is not set + +# +# Linker Options +# +# CONFIG_AARCH32_RAM_LD is not set +CONFIG_AARCH64_RAM_LD=y +# CONFIG_USER_DEFINED_LD is not set +CONFIG_LINK_SCRIPT_ROM=y +CONFIG_ROM_START_UP_ADDR=0x80100000 +CONFIG_ROM_SIZE_MB=1 +CONFIG_LINK_SCRIPT_RAM=y +CONFIG_RAM_START_UP_ADDR=0x80500000 +CONFIG_RAM_SIZE_MB=64 +CONFIG_HEAP_SIZE=1 +CONFIG_STACK_SIZE=0x100000 +CONFIG_FPU_STACK_SIZE=0x1000 +# end of Linker Options + +# +# Compiler Options +# + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + +CONFIG_OUTPUT_BINARY=y +# end of Compiler Options +# end of Building Option + +# +# Component Configuration +# + +# +# Freertos Uart Drivers +# +CONFIG_FREERTOS_USE_UART=y +# end of Freertos Uart Drivers + +# +# Freertos Pwm Drivers +# +# CONFIG_FREERTOS_USE_PWM is not set +# end of Freertos Pwm Drivers + +# +# Freertos Qspi Drivers +# +# CONFIG_FREERTOS_USE_QSPI is not set +# end of Freertos Qspi Drivers + +# +# Freertos Wdt Drivers +# +# CONFIG_FREERTOS_USE_WDT is not set +# end of Freertos Wdt Drivers + +# +# Freertos Eth Drivers +# +# CONFIG_FREERTOS_USE_XMAC is not set +CONFIG_FREERTOS_USE_GMAC=y +# end of Freertos Eth Drivers + +# +# Freertos Gpio Drivers +# +# CONFIG_FREERTOS_USE_GPIO is not set +# end of Freertos Gpio Drivers + +# +# Freertos Spim Drivers +# +# CONFIG_FREERTOS_USE_FSPIM is not set +# end of Freertos Spim Drivers + +# +# Freertos DMA Drivers +# +# CONFIG_FREERTOS_USE_FDDMA is not set +# CONFIG_FREERTOS_USE_FGDMA is not set +# end of Freertos DMA Drivers + +# +# Freertos Adc Drivers +# +# CONFIG_FREERTOS_USE_ADC is not set +# end of Freertos Adc Drivers + +# +# Freertos Can Drivers +# +# CONFIG_FREERTOS_USE_CAN is not set +# end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers +# end of Component Configuration + +# +# Third-Party Configuration +# +CONFIG_USE_LWIP=y + +# +# LWIP Freertos Port Configuration +# +# CONFIG_LWIP_FXMAC is not set +CONFIG_LWIP_FGMAC=y + +# +# LWIP Configuration +# + +# +# LWIP Port Configuration +# +# CONFIG_LWIP_PORT_DEBUG_EN is not set +# end of LWIP Port Configuration + +# CONFIG_LWIP_NO_SYS is not set +CONFIG_LWIP_LOCAL_HOSTNAME="phytium" + +# +# Memory configuration +# +# CONFIG_LWIP_USE_MEM_POOL is not set +CONFIG_LWIP_USE_MEM_HEAP=y +CONFIG_MEM_SIZE=2 +CONFIG_MEM_ALIGNMENT=64 +# end of Memory configuration + +# +# Pbuf options +# +CONFIG_PBUF_POOL_BUFSIZE=2 +CONFIG_PBUF_POOL_SIZE=1 +# end of Pbuf options + +# +# ARP +# +CONFIG_ARP_QUEUEING_EN=y +# end of ARP + +# +# IPV4 +# +# CONFIG_USE_IPV4_ONLY is not set +CONFIG_LWIP_IP4_REASSEMBLY=y +CONFIG_LWIP_IP4_FRAG=y +# CONFIG_LWIP_IP_FORWARD is not set +CONFIG_IP_REASS_MAX_PBUFS=16 +# end of IPV4 + +# +# ICMP +# +CONFIG_LWIP_ICMP=y +CONFIG_LWIP_MULTICAST_PING=y +CONFIG_LWIP_BROADCAST_PING=y +# end of ICMP + +# +# LWIP RAW API +# +CONFIG_LWIP_RAW_API_EN=y +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + +# +# DHCP +# +CONFIG_LWIP_DHCP_ENABLE=y +# CONFIG_LWIP_DHCP_DOES_ARP_CHECK is not set +# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set +# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set +# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set +CONFIG_LWIP_DHCP_OPTIONS_LEN=68 +CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y +# end of DHCP + +# +# AUTOIP +# +# CONFIG_LWIP_AUTOIP is not set +# end of AUTOIP + +# +# IGMP +# +CONFIG_LWIP_IGMP_EN=y +# end of IGMP + +# +# DNS +# +CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y +# end of DNS + +# +# UDP +# +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# CONFIG_LWIP_NETBUF_RECVINFO is not set +# end of UDP + +# +# TCP +# +CONFIG_LWIP_TCP_WND_DEFAULT=5744 +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +# CONFIG_LWIP_TCP_SACK_OUT is not set +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 +CONFIG_LWIP_TCP_RTO_TIME=1500 +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +# end of TCP + +# +# Network_Interface +# +# CONFIG_LWIP_NETIF_API is not set +# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set +# end of Network_Interface + +# +# LOOPIF +# +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 +# end of LOOPIF + +# +# SLIPIF +# +# CONFIG_LWIP_SLIP_SUPPORT is not set +# end of SLIPIF + +CONFIG_LWIP_TCPIP_CORE_LOCKING=y + +# +# Socket +# +CONFIG_LWIP_MAX_SOCKETS=10 +# CONFIG_LWIP_SO_LINGER is not set +CONFIG_LWIP_SO_REUSE=y +CONFIG_LWIP_SO_REUSE_RXTOALL=y +# end of Socket + +# CONFIG_LWIP_STATS is not set + +# +# PPP +# +# CONFIG_LWIP_PPP_SUPPORT is not set +CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 +CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 +# end of PPP + +# +# Checksums +# +# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set +# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set +CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y +# end of Checksums + +# +# IPV6 +# +CONFIG_LWIP_IPV6=y +# CONFIG_LWIP_IPV6_AUTOCONFIG is not set +CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 +# CONFIG_LWIP_IPV6_FORWARD is not set +CONFIG_LWIP_IP6_FRAG=y +# CONFIG_LWIP_IP6_REASSEMBLY is not set +# end of IPV6 + +CONFIG_LWIP_DEBUG=y +# CONFIG_LWIP_DEBUG_ESP_LOG is not set +CONFIG_LWIP_NETIF_DEBUG=y +# CONFIG_LWIP_PBUF_DEBUG is not set +# CONFIG_LWIP_ETHARP_DEBUG is not set +# CONFIG_LWIP_API_LIB_DEBUG is not set +# CONFIG_LWIP_SOCKETS_DEBUG is not set +# CONFIG_LWIP_IP_DEBUG is not set +# CONFIG_LWIP_ICMP_DEBUG is not set +# CONFIG_LWIP_DHCP_STATE_DEBUG is not set +# CONFIG_LWIP_DHCP_DEBUG is not set +# CONFIG_LWIP_IP6_DEBUG is not set +# CONFIG_LWIP_ICMP6_DEBUG is not set +# CONFIG_LWIP_TCP_DEBUG is not set +# CONFIG_LWIP_UDP_DEBUG is not set +# CONFIG_LWIP_SNTP_DEBUG is not set +# CONFIG_LWIP_DNS_DEBUG is not set +# end of LWIP Configuration + +# +# Tcp/ip task resource configuration +# +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_PRIO=6 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +# end of Tcp/ip task resource configuration + +# +# lwip port thread Configuration +# +CONFIG_LWIP_PORT_USE_RECEIVE_THREAD=y +CONFIG_LWIP_PORT_RECEIVE_THREAD_STACKSIZE=1024 +CONFIG_LWIP_PORT_RECEIVE_THREAD_PRIORITY=5 +CONFIG_LWIP_PORT_USE_LINK_DETECT_THREAD=y +CONFIG_LWIP_PORT_LINK_DETECT_STACKSIZE=1024 +CONFIG_LWIP_PORT_LINK_DETECT_PRIORITY=5 +CONFIG_LWIP_PORT_DHCP_THREAD=y +CONFIG_LWIP_PORT_DHCP_STACKSIZE=2048 +CONFIG_LWIP_PORT_DHCP_PRIORITY=5 +# end of lwip port thread Configuration +# end of LWIP Freertos Port Configuration + +CONFIG_USE_BACKTRACE=y +# CONFIG_USE_FATFS_0_1_4 is not set +# CONFIG_USE_SFUD is not set +# CONFIG_USE_SPIFFS is not set +# CONFIG_USE_AMP is not set +CONFIG_USE_LETTER_SHELL=y + +# +# Letter Shell Configuration +# +CONFIG_LS_PL011_UART=y +CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y +# CONFIG_DEFAULT_LETTER_SHELL_USE_UART0 is not set +# CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set +# end of Letter Shell Configuration + +CONFIG_USE_TLSF=y +# CONFIG_USE_SDMMC_CMD is not set +# CONFIG_USE_CHERRY_USB is not set +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/network/sockets/udp_multicast/main.c b/example/network/sockets/udp_multicast/main.c index c9b71b6c..a4837f6e 100644 --- a/example/network/sockets/udp_multicast/main.c +++ b/example/network/sockets/udp_multicast/main.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: main.c * Date: 2022-02-24 13:42:19 * LastEditTime: 2022-03-21 17:01:57 - * Description:  This file is for - * - * Modify History: + * Description:  This file is for running shell and open OS task schedule + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/10/21 init */ #include #include "FreeRTOS.h" @@ -30,14 +31,16 @@ int main() BaseType_t ret = pdPASS; ret = LSUserShellTask(); - if(ret != pdPASS) + if (ret != pdPASS) + { goto FAIL_EXIT; - - vTaskStartScheduler(); /* 启动任务,开启调度 */ + } + + vTaskStartScheduler(); /* 启动任务,开启调度 */ while (1); /* 正常不会执行到这里 */ - + FAIL_EXIT: - printf("failed 0x%x \r\n", ret); + printf("Failed 0x%x.\r\n", ret); return 0; } \ No newline at end of file diff --git a/example/network/sockets/udp_multicast/pic/ipv4_ipv6_config.png b/example/network/sockets/udp_multicast/pic/ipv4_ipv6_config.png new file mode 100644 index 0000000000000000000000000000000000000000..f978edf22c490f78addc90c8253b4dcf47d7a25c GIT binary patch literal 34094 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

+pb<>oSaQiIjf-9(EhCQUP|P|=(0Lxwb^;O{gG zaFu2wAJGnUJLAx+;Gfoj=Q_$4Li9s*Syyx;ys4g~wPEE4h#FKvlu8N`ILhZn9z zeR92-vqJDOs6U8S zq6)bmGLBrRCRIQ>i28jUy%y5Y4#nyMmL30vh(KT`DIXb6Dqh%lJ<;Yen_t1ic^{x6 zGOpMiL(PGREMr`6IxkqlFfEZ5U|x}RA|Ngfds+ZuZIY5P*m~k>Wxy$zlOfn!c(K3f z8E_>38ho(?8!;uTr!i4}RJQ;)jU}&rf0Y1Y2U!gxA@6zy;p*hmaU;Jdw~3sivZp(v zP84!4Zaay^+VHK0TQqN?z>pW8B30EebGRZK?7En9Op zDM43BA6s^w55G5z$DMfr89nLN1zpM~B!A5Et{b=yxni%{|H6tjvS^Bq2lr{@c(8qW z{k$@u`P<7wybP>v*PK|J6z*}=U-u6A$UNon1Jvopjm=!AbCgvvg=*kWAu@U;Uzk7B$ZM1>Wrx z1{)7e^PlWYXkri+%3lM84^O^Pv22$}-7!e)U#@IX!*}sOO?`EO$L;P=D*`#C!I!*j zTIL^#EC;CBP`xh%E5=YwY!G*s``Gi#2>J~#7v!H;0gI^bKh-X9)7arnieQqk+Sj#b z(LU1|s$Jnaoe7Ogsmy?~l7exDzR+wcgHV#@mfT19zKmy{Mu4bBrM}|?-OKJVX3Ald z)97vib2Lv|Czwt3ZSO@e03ly*JN%(2Y(XOsY~Qx7@VohjKHEg(U8O5ukKOY_iFw?P zjf`KR(vjc#AB_0%bILmO$=w9#O~EeVOuE780>WHHKy_>3r{xD8NsFp!Ngl;rAP@4Q z`j0V@sL!f#hCMMezNSdiC#wN zf^GZe$DLmbQ*i0vN;5U{GJP;m#S+^4L+wZiYdn%MPG!$+%8U|0V#I>-NqTql!FZfoc1 zyDj5&Q|PBRpBjPsI!N80S7)|yVM_@^ZW;K?Gj0^s%n5C-#N}7d?97#^tUr|fQypXW z1pOXdxu2ipd=a~NJxd2ybrbxtf)djcL2Hs++PpZu%yy%wQ`ngo@JDVY?ba;5!z};K zSXIN7DR=n}`ttReOH&+uX!FD7>rEFeso6VMzh2{aU8@iRs$T?rAIyxEx(%S2uCDr- zy_;i%8h~@-Sl+UA!F!K^;fTR1pD36IYJ$r!Rp;()RNa4NLRRa4{e?G#$mSqQDyS-I zbt}IXr9=wl7Slkk{8Y;;bHxoA#A*>DAD|JRARVfr&#-L0Vc2%E%(1b&$j1!RkX1XMy(zqzcnaK-7pZ*mUgjoz3^!>+~OBwIdFV)@GldqJ1|nD>>J?n{~~ zbJ&#s)SmH%I-o2bC8-^&cdu?_fVxX*NXioepZHK;s5tR@d?*roA77g_J4c(N-SnzY9+WBI5)u0 elSxwL(jI*UXR%-xId*OTBlY___sZ_tJo|58{9P#k literal 0 HcmV?d00001 diff --git a/example/network/sockets/udp_multicast/pic/lwip_probe.png b/example/network/sockets/udp_multicast/pic/lwip_probe.png new file mode 100644 index 0000000000000000000000000000000000000000..161a2bd48fa544932252825ec705056b83d75734 GIT binary patch literal 147084 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�k)GEQW#yi=VNIen&I7P=CHD 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 Gq9R7SeQkgmam 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

y#6Z`ZiXwUCpNfr=-41`=B> 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�eXyP)U{q&0}Ra@=ZS=aUP}z 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 literal 0 HcmV?d00001 diff --git a/example/network/sockets/udp_multicast/pic/xmac_probe.png b/example/network/sockets/udp_multicast/pic/xmac_probe.png deleted file mode 100644 index 59f8c2f556710120cfcd0a7943a34054665da3ba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47686 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 diff --git a/example/network/sockets/udp_multicast/pic/xmac_probe_ipv4.png b/example/network/sockets/udp_multicast/pic/xmac_probe_ipv4.png deleted file mode 100644 index 584686e115481cc7156df9172e83256fde15088a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27042 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 diff --git a/example/network/sockets/udp_multicast/pic/xmac_probe_ipv4_2.png b/example/network/sockets/udp_multicast/pic/xmac_probe_ipv4_2.png deleted file mode 100644 index 0e8fd18bc82ef2a5b2474492133fb47d8fbe2086..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37810 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 Q_C-^36C2}t!$?H+H3Fq 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 Cg?Hb0ywxkwWy;-B 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 diff --git a/example/network/sockets/udp_multicast/pic/xmac_probe_ipv6_2.png b/example/network/sockets/udp_multicast/pic/xmac_probe_ipv6_2.png deleted file mode 100644 index 7dca5c3e883fbde10d9818d8854e3b1ed344d56e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 82644 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 z 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

BK4y1zY`WnXnQ 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 AcK`qY diff --git a/example/network/sockets/udp_multicast/sdkconfig b/example/network/sockets/udp_multicast/sdkconfig index 553b290d..f19c54f7 100644 --- a/example/network/sockets/udp_multicast/sdkconfig +++ b/example/network/sockets/udp_multicast/sdkconfig @@ -2,18 +2,21 @@ # # Project Configuration # -CONFIG_TARGET_NAME="e2000_lwip_multicast" +CONFIG_TARGET_NAME="e2000q_freertos_a64" # # Example Configuration # +CONFIG_EXAMPLE_IPV4_V6=y # CONFIG_EXAMPLE_IPV4_ONLY is not set -CONFIG_EXAMPLE_IPV6_ONLY=y +CONFIG_EXAMPLE_IPV4=y CONFIG_EXAMPLE_IPV6=y +CONFIG_EXAMPLE_MULTICAST_IPV4_ADDR="232.10.12.10" CONFIG_EXAMPLE_MULTICAST_IPV6_ADDR="FF02::FD" CONFIG_EXAMPLE_PORT=6750 # CONFIG_EXAMPLE_LOOPBACK is not set CONFIG_EXAMPLE_MULTICAST_TTL=255 +# CONFIG_EXAMPLE_MULTICAST_LISTEN_ALL_IF is not set CONFIG_EXAMPLE_MULTICAST_LISTEN_DEFAULT_IF=y # end of Example Configuration @@ -99,6 +102,7 @@ CONFIG_FXMAC_PHY_COMMON=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -139,6 +143,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -175,6 +188,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # CONFIG_FREERTOS_USE_XMAC=y +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -196,12 +210,6 @@ CONFIG_FREERTOS_USE_XMAC=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -213,13 +221,37 @@ CONFIG_FREERTOS_USE_XMAC=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # CONFIG_USE_LWIP=y +# +# LWIP Freertos Port Configuration +# +CONFIG_LWIP_FXMAC=y +# CONFIG_LWIP_FGMAC is not set + # # LWIP Configuration # @@ -227,99 +259,43 @@ CONFIG_USE_LWIP=y # # LWIP Port Configuration # -# CONFIG_LWIP_FGMAC is not set -CONFIG_LWIP_FXMAC=y +# CONFIG_LWIP_PORT_DEBUG_EN is not set # end of LWIP Port Configuration +# CONFIG_LWIP_NO_SYS is not set CONFIG_LWIP_LOCAL_HOSTNAME="phytium" # -# memory configuration +# Memory configuration # # CONFIG_LWIP_USE_MEM_POOL is not set CONFIG_LWIP_USE_MEM_HEAP=y CONFIG_MEM_SIZE=1 CONFIG_MEM_ALIGNMENT=64 -# end of memory configuration - -# -# NETWORK_INTERFACE_OPTIONS -# -# CONFIG_LWIP_NETIF_API is not set -# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set -# end of NETWORK_INTERFACE_OPTIONS - -# -# LOOPIF -# -CONFIG_LWIP_NETIF_LOOPBACK=y -CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 -# end of LOOPIF - -# -# SLIPIF -# -# CONFIG_LWIP_SLIP_SUPPORT is not set -# end of SLIPIF +# end of Memory configuration # # Pbuf options # CONFIG_PBUF_POOL_BUFSIZE=2 -# end of Pbuf options - -# -# Internal Memory Pool Sizes -# CONFIG_PBUF_POOL_SIZE=1 -# end of Internal Memory Pool Sizes - -CONFIG_LWIP_MAX_SOCKETS=10 - -# -# LWIP RAW API -# -CONFIG_LWIP_MAX_RAW_PCBS=16 -# end of LWIP RAW API - -# -# TCP -# -CONFIG_LWIP_MAX_ACTIVE_TCP=16 -CONFIG_LWIP_MAX_LISTENING_TCP=16 -CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y -CONFIG_LWIP_TCP_MAXRTX=12 -CONFIG_LWIP_TCP_SYNMAXRTX=12 -CONFIG_LWIP_TCP_MSS=1440 -CONFIG_LWIP_TCP_TMR_INTERVAL=250 -CONFIG_LWIP_TCP_MSL=60000 -CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 -CONFIG_LWIP_TCP_WND_DEFAULT=5744 -CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 -CONFIG_LWIP_TCP_QUEUE_OOSEQ=y -# CONFIG_LWIP_TCP_SACK_OUT is not set -CONFIG_LWIP_TCP_OVERSIZE_MSS=y -# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set -# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set -# end of TCP +# end of Pbuf options # -# UDP +# ARP # -CONFIG_LWIP_MAX_UDP_PCBS=16 -CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 -# CONFIG_LWIP_NETBUF_RECVINFO is not set -# end of UDP +CONFIG_ARP_QUEUEING_EN=y +# end of ARP # -# IPv4 +# IPV4 # # CONFIG_USE_IPV4_ONLY is not set CONFIG_LWIP_IP4_REASSEMBLY=y CONFIG_LWIP_IP4_FRAG=y # CONFIG_LWIP_IP_FORWARD is not set CONFIG_IP_REASS_MAX_PBUFS=45 -# end of IPv4 +# end of IPV4 # # ICMP @@ -329,10 +305,17 @@ CONFIG_LWIP_MULTICAST_PING=y # CONFIG_LWIP_BROADCAST_PING is not set # end of ICMP +# +# LWIP RAW API +# +CONFIG_LWIP_RAW_API_EN=y +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + # # DHCP # -# CONFIG_LWIP_DHCP_ENABLE is not set +CONFIG_LWIP_DHCP_ENABLE=y # CONFIG_LWIP_DHCP_DOES_ARP_CHECK is not set # CONFIG_LWIP_DHCP_GET_NTP_SRV is not set # CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set @@ -347,6 +330,12 @@ CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y # CONFIG_LWIP_AUTOIP is not set # end of AUTOIP +# +# IGMP +# +CONFIG_LWIP_IGMP_EN=y +# end of IGMP + # # DNS # @@ -354,20 +343,65 @@ CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y # end of DNS # -# TCP options +# UDP # +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# CONFIG_LWIP_NETBUF_RECVINFO is not set +# end of UDP + +# +# TCP +# +CONFIG_LWIP_TCP_WND_DEFAULT=5744 +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +# CONFIG_LWIP_TCP_SACK_OUT is not set +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 CONFIG_LWIP_TCP_RTO_TIME=1500 -# end of TCP options +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +# end of TCP + +# +# Network_Interface +# +# CONFIG_LWIP_NETIF_API is not set +# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set +# end of Network_Interface + +# +# LOOPIF +# +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 +# end of LOOPIF + +# +# SLIPIF +# +# CONFIG_LWIP_SLIP_SUPPORT is not set +# end of SLIPIF CONFIG_LWIP_TCPIP_CORE_LOCKING=y # -# socket +# Socket # +CONFIG_LWIP_MAX_SOCKETS=10 # CONFIG_LWIP_SO_LINGER is not set CONFIG_LWIP_SO_REUSE=y CONFIG_LWIP_SO_REUSE_RXTOALL=y -# end of socket +# end of Socket # CONFIG_LWIP_STATS is not set @@ -388,7 +422,7 @@ CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y # end of Checksums # -# ipv6 +# IPV6 # CONFIG_LWIP_IPV6=y # CONFIG_LWIP_IPV6_AUTOCONFIG is not set @@ -396,9 +430,10 @@ CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 # CONFIG_LWIP_IPV6_FORWARD is not set CONFIG_LWIP_IP6_FRAG=y CONFIG_LWIP_IP6_REASSEMBLY=y -# end of ipv6 +# end of IPV6 CONFIG_LWIP_DEBUG=y +# CONFIG_LWIP_DEBUG_ESP_LOG is not set CONFIG_LWIP_NETIF_DEBUG=y # CONFIG_LWIP_PBUF_DEBUG is not set # CONFIG_LWIP_ETHARP_DEBUG is not set @@ -406,16 +441,41 @@ CONFIG_LWIP_NETIF_DEBUG=y # CONFIG_LWIP_SOCKETS_DEBUG is not set # CONFIG_LWIP_IP_DEBUG is not set # CONFIG_LWIP_ICMP_DEBUG is not set +# CONFIG_LWIP_DHCP_STATE_DEBUG is not set # CONFIG_LWIP_DHCP_DEBUG is not set # CONFIG_LWIP_IP6_DEBUG is not set # CONFIG_LWIP_ICMP6_DEBUG is not set # CONFIG_LWIP_TCP_DEBUG is not set +# CONFIG_LWIP_UDP_DEBUG is not set # CONFIG_LWIP_SNTP_DEBUG is not set # CONFIG_LWIP_DNS_DEBUG is not set # end of LWIP Configuration +# +# Tcp/ip task resource configuration +# +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_PRIO=6 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +# end of Tcp/ip task resource configuration + +# +# lwip port thread Configuration +# +CONFIG_LWIP_PORT_USE_RECEIVE_THREAD=y +CONFIG_LWIP_PORT_RECEIVE_THREAD_STACKSIZE=2048 +CONFIG_LWIP_PORT_RECEIVE_THREAD_PRIORITY=5 +CONFIG_LWIP_PORT_USE_LINK_DETECT_THREAD=y +CONFIG_LWIP_PORT_LINK_DETECT_STACKSIZE=2048 +CONFIG_LWIP_PORT_LINK_DETECT_PRIORITY=5 +CONFIG_LWIP_PORT_DHCP_THREAD=y +CONFIG_LWIP_PORT_DHCP_STACKSIZE=4096 +CONFIG_LWIP_PORT_DHCP_PRIORITY=5 +# end of lwip port thread Configuration +# end of LWIP Freertos Port Configuration + CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -433,4 +493,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/network/sockets/udp_multicast/sdkconfig.h b/example/network/sockets/udp_multicast/sdkconfig.h index be413436..6872aa07 100644 --- a/example/network/sockets/udp_multicast/sdkconfig.h +++ b/example/network/sockets/udp_multicast/sdkconfig.h @@ -3,17 +3,20 @@ /* Project Configuration */ -#define CONFIG_TARGET_NAME "e2000_lwip_multicast" +#define CONFIG_TARGET_NAME "e2000q_freertos_a64" /* Example Configuration */ +#define CONFIG_EXAMPLE_IPV4_V6 /* CONFIG_EXAMPLE_IPV4_ONLY is not set */ -#define CONFIG_EXAMPLE_IPV6_ONLY +#define CONFIG_EXAMPLE_IPV4 #define CONFIG_EXAMPLE_IPV6 +#define CONFIG_EXAMPLE_MULTICAST_IPV4_ADDR "232.10.12.10" #define CONFIG_EXAMPLE_MULTICAST_IPV6_ADDR "FF02::FD" #define CONFIG_EXAMPLE_PORT 6750 /* CONFIG_EXAMPLE_LOOPBACK is not set */ #define CONFIG_EXAMPLE_MULTICAST_TTL 255 +/* CONFIG_EXAMPLE_MULTICAST_LISTEN_ALL_IF is not set */ #define CONFIG_EXAMPLE_MULTICAST_LISTEN_DEFAULT_IF /* end of Example Configuration */ @@ -90,6 +93,7 @@ /* CONFIG_USE_ADC is not set */ /* CONFIG_USE_PWM is not set */ /* CONFIG_USE_IPC is not set */ +/* CONFIG_USE_MEDIA is not set */ /* end of Components Configuration */ #define CONFIG_USE_NEW_LIBC /* end of Standalone Setting */ @@ -126,6 +130,12 @@ /* Compiler Options */ +/* Cross-Compiler Setting */ + +#define CONFIG_GCC_OPTIMIZE_LEVEL 0 +/* CONFIG_USE_EXT_COMPILER is not set */ +/* CONFIG_USE_KLIN_SYS is not set */ +/* end of Cross-Compiler Setting */ #define CONFIG_OUTPUT_BINARY /* end of Compiler Options */ /* end of Building Option */ @@ -155,6 +165,7 @@ /* Freertos Eth Drivers */ #define CONFIG_FREERTOS_USE_XMAC +/* CONFIG_FREERTOS_USE_GMAC is not set */ /* end of Freertos Eth Drivers */ /* Freertos Gpio Drivers */ @@ -173,11 +184,6 @@ /* CONFIG_FREERTOS_USE_FGDMA is not set */ /* end of Freertos DMA Drivers */ -/* Freertos MMC Drivers */ - -/* CONFIG_FREERTOS_USE_FSDIO is not set */ -/* end of Freertos MMC Drivers */ - /* Freertos Adc Drivers */ /* CONFIG_FREERTOS_USE_ADC is not set */ @@ -187,97 +193,68 @@ /* CONFIG_FREERTOS_USE_CAN is not set */ /* end of Freertos Can Drivers */ + +/* Freertos I2c Drivers */ + +/* CONFIG_FREERTOS_USE_I2C is not set */ +/* end of Freertos I2c Drivers */ + +/* Freertos Mio Drivers */ + +/* CONFIG_FREERTOS_USE_MIO is not set */ +/* end of Freertos Mio Drivers */ + +/* Freertos Timer Drivers */ + +/* CONFIG_FREERTOS_USE_TIMER is not set */ +/* end of Freertos Timer Drivers */ /* end of Component Configuration */ -/* FreeRTOS Setting */ +/* Third-Party Configuration */ #define CONFIG_USE_LWIP +/* LWIP Freertos Port Configuration */ + +#define CONFIG_LWIP_FXMAC +/* CONFIG_LWIP_FGMAC is not set */ + /* LWIP Configuration */ /* LWIP Port Configuration */ -/* CONFIG_LWIP_FGMAC is not set */ -#define CONFIG_LWIP_FXMAC +/* CONFIG_LWIP_PORT_DEBUG_EN is not set */ /* end of LWIP Port Configuration */ +/* CONFIG_LWIP_NO_SYS is not set */ #define CONFIG_LWIP_LOCAL_HOSTNAME "phytium" -/* memory configuration */ +/* Memory configuration */ /* CONFIG_LWIP_USE_MEM_POOL is not set */ #define CONFIG_LWIP_USE_MEM_HEAP #define CONFIG_MEM_SIZE 1 #define CONFIG_MEM_ALIGNMENT 64 -/* end of memory configuration */ - -/* NETWORK_INTERFACE_OPTIONS */ - -/* CONFIG_LWIP_NETIF_API is not set */ -/* CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set */ -/* end of NETWORK_INTERFACE_OPTIONS */ - -/* LOOPIF */ - -#define CONFIG_LWIP_NETIF_LOOPBACK -#define CONFIG_LWIP_LOOPBACK_MAX_PBUFS 8 -/* end of LOOPIF */ - -/* SLIPIF */ - -/* CONFIG_LWIP_SLIP_SUPPORT is not set */ -/* end of SLIPIF */ +/* end of Memory configuration */ /* Pbuf options */ #define CONFIG_PBUF_POOL_BUFSIZE 2 -/* end of Pbuf options */ - -/* Internal Memory Pool Sizes */ - #define CONFIG_PBUF_POOL_SIZE 1 -/* end of Internal Memory Pool Sizes */ -#define CONFIG_LWIP_MAX_SOCKETS 10 - -/* LWIP RAW API */ - -#define CONFIG_LWIP_MAX_RAW_PCBS 16 -/* end of LWIP RAW API */ - -/* TCP */ - -#define CONFIG_LWIP_MAX_ACTIVE_TCP 16 -#define CONFIG_LWIP_MAX_LISTENING_TCP 16 -#define CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION -#define CONFIG_LWIP_TCP_MAXRTX 12 -#define CONFIG_LWIP_TCP_SYNMAXRTX 12 -#define CONFIG_LWIP_TCP_MSS 1440 -#define CONFIG_LWIP_TCP_TMR_INTERVAL 250 -#define CONFIG_LWIP_TCP_MSL 60000 -#define CONFIG_LWIP_TCP_SND_BUF_DEFAULT 5744 -#define CONFIG_LWIP_TCP_WND_DEFAULT 5744 -#define CONFIG_LWIP_TCP_RECVMBOX_SIZE 6 -#define CONFIG_LWIP_TCP_QUEUE_OOSEQ -/* CONFIG_LWIP_TCP_SACK_OUT is not set */ -#define CONFIG_LWIP_TCP_OVERSIZE_MSS -/* CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set */ -/* CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set */ -/* end of TCP */ +/* end of Pbuf options */ -/* UDP */ +/* ARP */ -#define CONFIG_LWIP_MAX_UDP_PCBS 16 -#define CONFIG_LWIP_UDP_RECVMBOX_SIZE 6 -/* CONFIG_LWIP_NETBUF_RECVINFO is not set */ -/* end of UDP */ +#define CONFIG_ARP_QUEUEING_EN +/* end of ARP */ -/* IPv4 */ +/* IPV4 */ /* CONFIG_USE_IPV4_ONLY is not set */ #define CONFIG_LWIP_IP4_REASSEMBLY #define CONFIG_LWIP_IP4_FRAG /* CONFIG_LWIP_IP_FORWARD is not set */ #define CONFIG_IP_REASS_MAX_PBUFS 45 -/* end of IPv4 */ +/* end of IPV4 */ /* ICMP */ @@ -286,9 +263,15 @@ /* CONFIG_LWIP_BROADCAST_PING is not set */ /* end of ICMP */ +/* LWIP RAW API */ + +#define CONFIG_LWIP_RAW_API_EN +#define CONFIG_LWIP_MAX_RAW_PCBS 16 +/* end of LWIP RAW API */ + /* DHCP */ -/* CONFIG_LWIP_DHCP_ENABLE is not set */ +#define CONFIG_LWIP_DHCP_ENABLE /* CONFIG_LWIP_DHCP_DOES_ARP_CHECK is not set */ /* CONFIG_LWIP_DHCP_GET_NTP_SRV is not set */ /* CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set */ @@ -302,23 +285,69 @@ /* CONFIG_LWIP_AUTOIP is not set */ /* end of AUTOIP */ +/* IGMP */ + +#define CONFIG_LWIP_IGMP_EN +/* end of IGMP */ + /* DNS */ #define CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES /* end of DNS */ -/* TCP options */ +/* UDP */ + +#define CONFIG_LWIP_MAX_UDP_PCBS 16 +#define CONFIG_LWIP_UDP_RECVMBOX_SIZE 6 +/* CONFIG_LWIP_NETBUF_RECVINFO is not set */ +/* end of UDP */ + +/* TCP */ +#define CONFIG_LWIP_TCP_WND_DEFAULT 5744 +#define CONFIG_LWIP_TCP_MAXRTX 12 +#define CONFIG_LWIP_TCP_SYNMAXRTX 12 +#define CONFIG_LWIP_TCP_QUEUE_OOSEQ +/* CONFIG_LWIP_TCP_SACK_OUT is not set */ +#define CONFIG_LWIP_TCP_MSS 1440 +#define CONFIG_LWIP_TCP_SND_BUF_DEFAULT 5744 +#define CONFIG_LWIP_TCP_OVERSIZE_MSS +/* CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set */ +/* CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set */ +#define CONFIG_LWIP_TCP_TMR_INTERVAL 250 +#define CONFIG_LWIP_TCP_MSL 60000 #define CONFIG_LWIP_TCP_RTO_TIME 1500 -/* end of TCP options */ +#define CONFIG_LWIP_MAX_ACTIVE_TCP 16 +#define CONFIG_LWIP_MAX_LISTENING_TCP 16 +#define CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION +#define CONFIG_LWIP_TCP_RECVMBOX_SIZE 6 +/* end of TCP */ + +/* Network_Interface */ + +/* CONFIG_LWIP_NETIF_API is not set */ +/* CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set */ +/* end of Network_Interface */ + +/* LOOPIF */ + +#define CONFIG_LWIP_NETIF_LOOPBACK +#define CONFIG_LWIP_LOOPBACK_MAX_PBUFS 8 +/* end of LOOPIF */ + +/* SLIPIF */ + +/* CONFIG_LWIP_SLIP_SUPPORT is not set */ +/* end of SLIPIF */ #define CONFIG_LWIP_TCPIP_CORE_LOCKING -/* socket */ +/* Socket */ +#define CONFIG_LWIP_MAX_SOCKETS 10 /* CONFIG_LWIP_SO_LINGER is not set */ #define CONFIG_LWIP_SO_REUSE #define CONFIG_LWIP_SO_REUSE_RXTOALL -/* end of socket */ +/* end of Socket */ /* CONFIG_LWIP_STATS is not set */ /* PPP */ @@ -335,7 +364,7 @@ #define CONFIG_LWIP_CHECKSUM_CHECK_ICMP /* end of Checksums */ -/* ipv6 */ +/* IPV6 */ #define CONFIG_LWIP_IPV6 /* CONFIG_LWIP_IPV6_AUTOCONFIG is not set */ @@ -343,8 +372,9 @@ /* CONFIG_LWIP_IPV6_FORWARD is not set */ #define CONFIG_LWIP_IP6_FRAG #define CONFIG_LWIP_IP6_REASSEMBLY -/* end of ipv6 */ +/* end of IPV6 */ #define CONFIG_LWIP_DEBUG +/* CONFIG_LWIP_DEBUG_ESP_LOG is not set */ #define CONFIG_LWIP_NETIF_DEBUG /* CONFIG_LWIP_PBUF_DEBUG is not set */ /* CONFIG_LWIP_ETHARP_DEBUG is not set */ @@ -352,15 +382,38 @@ /* CONFIG_LWIP_SOCKETS_DEBUG is not set */ /* CONFIG_LWIP_IP_DEBUG is not set */ /* CONFIG_LWIP_ICMP_DEBUG is not set */ +/* CONFIG_LWIP_DHCP_STATE_DEBUG is not set */ /* CONFIG_LWIP_DHCP_DEBUG is not set */ /* CONFIG_LWIP_IP6_DEBUG is not set */ /* CONFIG_LWIP_ICMP6_DEBUG is not set */ /* CONFIG_LWIP_TCP_DEBUG is not set */ +/* CONFIG_LWIP_UDP_DEBUG is not set */ /* CONFIG_LWIP_SNTP_DEBUG is not set */ /* CONFIG_LWIP_DNS_DEBUG is not set */ /* end of LWIP Configuration */ + +/* Tcp/ip task resource configuration */ + +#define CONFIG_LWIP_TCPIP_TASK_STACK_SIZE 3072 +#define CONFIG_LWIP_TCPIP_TASK_PRIO 6 +#define CONFIG_LWIP_TCPIP_RECVMBOX_SIZE 32 +/* end of Tcp/ip task resource configuration */ + +/* lwip port thread Configuration */ + +#define CONFIG_LWIP_PORT_USE_RECEIVE_THREAD +#define CONFIG_LWIP_PORT_RECEIVE_THREAD_STACKSIZE 2048 +#define CONFIG_LWIP_PORT_RECEIVE_THREAD_PRIORITY 5 +#define CONFIG_LWIP_PORT_USE_LINK_DETECT_THREAD +#define CONFIG_LWIP_PORT_LINK_DETECT_STACKSIZE 2048 +#define CONFIG_LWIP_PORT_LINK_DETECT_PRIORITY 5 +#define CONFIG_LWIP_PORT_DHCP_THREAD +#define CONFIG_LWIP_PORT_DHCP_STACKSIZE 4096 +#define CONFIG_LWIP_PORT_DHCP_PRIORITY 5 +/* end of lwip port thread Configuration */ +/* end of LWIP Freertos Port Configuration */ #define CONFIG_USE_BACKTRACE -/* CONFIG_USE_FATFS is not set */ +/* CONFIG_USE_FATFS_0_1_4 is not set */ /* CONFIG_USE_SFUD is not set */ /* CONFIG_USE_SPIFFS is not set */ /* CONFIG_USE_AMP is not set */ @@ -376,6 +429,28 @@ #define CONFIG_USE_TLSF /* CONFIG_USE_SDMMC_CMD is not set */ /* CONFIG_USE_CHERRY_USB is not set */ -/* end of FreeRTOS Setting */ +/* end of Third-Party Configuration */ + +/* Kernel Configuration */ + +#define CONFIG_FREERTOS_OPTIMIZED_SCHEDULER +#define CONFIG_FREERTOS_HZ 1000 +#define CONFIG_FREERTOS_MAX_PRIORITIES 32 +#define CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES 11 +#define CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES 11 +#define CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS 1 +#define CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE 1024 +#define CONFIG_FREERTOS_MAX_TASK_NAME_LEN 32 +#define CONFIG_FREERTOS_TIMER_TASK_PRIORITY 1 +#define CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH 2048 +#define CONFIG_FREERTOS_TIMER_QUEUE_LENGTH 10 +#define CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE 0 +#define CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS +#define CONFIG_FREERTOS_USE_TRACE_FACILITY +#define CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS +/* CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set */ +#define CONFIG_FREERTOS_TOTAL_HEAP_SIZE 10240 +#define CONFIG_FREERTOS_TASK_FPU_SUPPORT 1 +/* end of Kernel Configuration */ #endif diff --git a/example/network/sockets/udp_multicast/src/Kconfig b/example/network/sockets/udp_multicast/src/Kconfig index d9d1bde0..d7f26723 100644 --- a/example/network/sockets/udp_multicast/src/Kconfig +++ b/example/network/sockets/udp_multicast/src/Kconfig @@ -2,28 +2,30 @@ menu "Example Configuration" choice EXAMPLE_IP_MODE prompt "Multicast IP type" + default EXAMPLE_IPV4_V6 help Example can multicast IPV4, IPV6, or both. + config EXAMPLE_IPV4_V6 + bool "IPV4 & IPV6" + select EXAMPLE_IPV4 + select EXAMPLE_IPV6 + config EXAMPLE_IPV4_ONLY bool "IPV4" select EXAMPLE_IPV4 select USE_IPV4_ONLY - - config EXAMPLE_IPV6_ONLY - bool "IPV6" - select EXAMPLE_IPV6 - endchoice - + config EXAMPLE_IPV4 bool select LWIP_ICMP - + default n config EXAMPLE_IPV6 bool select LWIP_IPV6 - + default n + config EXAMPLE_MULTICAST_IPV4_ADDR string "Multicast IPV4 Address (send & receive)" default "232.10.12.10" @@ -71,7 +73,7 @@ menu "Example Configuration" config EXAMPLE_MULTICAST_LISTEN_ALL_IF bool "All interfaces (IPV4 only)" - depends on !EXAMPLE_IPV6_ONLY + config EXAMPLE_MULTICAST_LISTEN_DEFAULT_IF bool "Default interface" @@ -80,7 +82,7 @@ menu "Example Configuration" endmenu - +if TARGET_E2000 menu "E2000 board Configuration" config TARGET_NAME string "Build Target Name" @@ -104,4 +106,4 @@ menu "E2000 board Configuration" endchoice # BUILD_TARGET_ARCH_TYPE endmenu - +endif diff --git a/example/network/sockets/udp_multicast/src/e2000_board.c b/example/network/sockets/udp_multicast/src/e2000_board.c new file mode 100644 index 00000000..70262245 --- /dev/null +++ b/example/network/sockets/udp_multicast/src/e2000_board.c @@ -0,0 +1,160 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: e2000_board.c + * Date: 2022-11-07 09:04:21 + * LastEditTime: 2022-11-07 09:04:21 + * Description: This file is for lwip e2000 board pin define + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 wangxiaodong 2022/10/21 init + * 1.1 liuzhihong 2023/01/12 driver and application restructure + */ + +#include "ftypes.h" +#include "fpinctrl.h" +#include "fparameters.h" + +int FXmacPhyGpioInit(u32 instance_id, u32 interface_type) +{ +#if defined(CONFIG_TARGET_E2000Q) +#if defined(CONFIG_BOARD_TYPE_B) + if (instance_id == 3) + { + if (interface_type == PHY_INTERRUPTFACE_RGMII) + { + FPinSetConfig(FIOPAD_J37, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_rgmii_txd1_0 + */ + FPinSetConfig(FIOPAD_J39, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_rgmii_txd1_1 + */ + FPinSetConfig(FIOPAD_G41, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_rgmii_rxd1_0 + */ + FPinSetConfig(FIOPAD_E43, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_rgmii_rxd1_1 + */ + FPinSetConfig(FIOPAD_L43, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_rgmii_tx_ctl1 */ + FPinSetConfig(FIOPAD_C43, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_rgmii_rxd1_2 */ + FPinSetConfig(FIOPAD_E41, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_rgmii_rxd1_3 */ + FPinSetConfig(FIOPAD_L45, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_rgmii_rx_clk1 */ + FPinSetConfig(FIOPAD_J43, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_rgmii_rx_ctl1 */ + FPinSetConfig(FIOPAD_J41, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_rgmii_tx_clk1 */ + FPinSetDelay(FIOPAD_J41_DELAY, FPIN_OUTPUT_DELAY, FPIN_DELAY_FINE_TUNING, FPIN_DELAY_7); + FPinSetDelay(FIOPAD_J41_DELAY, FPIN_OUTPUT_DELAY, FPIN_DELAY_COARSE_TUNING, FPIN_DELAY_5); + FPinSetDelayEn(FIOPAD_J41_DELAY, FPIN_OUTPUT_DELAY, 1); + + FPinSetConfig(FIOPAD_L39, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_rgmii_txd1_2 */ + FPinSetConfig(FIOPAD_E37, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_rgmii_txd1_3 */ + FPinSetConfig(FIOPAD_E35, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_mdc_mac3 */ + FPinSetConfig(FIOPAD_G35, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_mdio_mac3 */ + } + else if (interface_type == PHY_INTERRUPTFACE_SGMII) + { + FPinSetConfig(FIOPAD_E35, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_mdc_mac3 */ + FPinSetConfig(FIOPAD_G35, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_mdio_mac3 */ + } + else + { + printf("Interface_type 0x%x is not support.\r\n"); + return -1; + } + } +#elif defined(CONFIG_BOARD_TYPE_C) + if (instance_id == 1) + { + FPinSetConfig(FIOPAD_AJ53, FPIN_FUNC3, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_mdc_mac1 */ + FPinSetConfig(FIOPAD_AL49, FPIN_FUNC3, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_mdio_mac1 */ + } + else if (instance_id == 2) + { + FPinSetConfig(FIOPAD_E29, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_mdc_mac2 */ + FPinSetConfig(FIOPAD_G29, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_mdio_mac2 */ + } + else if (instance_id == 3) + { + FPinSetConfig(FIOPAD_E35, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_mdc_mac3 */ + FPinSetConfig(FIOPAD_G35, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_mdio_mac3 */ + } + else + { + printf("Interface_type 0x%x is not support.\r\n"); + return -1; + } +#endif +#elif defined(CONFIG_TARGET_E2000D) || defined(CONFIG_TARGET_E2000S) + +#if defined(CONFIG_BOARD_TYPE_B) + if (instance_id == 3) + { + if (interface_type == PHY_INTERRUPTFACE_RGMII) + { + FPinSetConfig(FIOPAD_J33, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_rgmii_txd1_0 + */ + FPinSetConfig(FIOPAD_J35, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_rgmii_txd1_1 + */ + FPinSetConfig(FIOPAD_G37, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_rgmii_rxd1_0 + */ + FPinSetConfig(FIOPAD_E39, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_rgmii_rxd1_1 + */ + FPinSetConfig(FIOPAD_L39, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_rgmii_tx_ctl1 */ + FPinSetConfig(FIOPAD_C39, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_rgmii_rxd1_2 */ + FPinSetConfig(FIOPAD_E37, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_rgmii_rxd1_3 */ + FPinSetConfig(FIOPAD_L41, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_rgmii_rx_clk1 */ + FPinSetConfig(FIOPAD_J39, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_rgmii_rx_ctl1 */ + FPinSetConfig(FIOPAD_J37, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_rgmii_tx_clk1 */ + FPinSetDelay(FIOPAD_J37_DELAY, FPIN_OUTPUT_DELAY, FPIN_DELAY_COARSE_TUNING, FPIN_DELAY_5); + FPinSetDelay(FIOPAD_J37_DELAY, FPIN_OUTPUT_DELAY, FPIN_DELAY_FINE_TUNING, FPIN_DELAY_7); + FPinSetDelayEn(FIOPAD_J37_DELAY, FPIN_OUTPUT_DELAY, 1); + FPinSetConfig(FIOPAD_L35, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_rgmii_txd1_2 */ + FPinSetConfig(FIOPAD_E33, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_rgmii_txd1_3 */ + FPinSetConfig(FIOPAD_E31, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_mdc_mac3 */ + FPinSetConfig(FIOPAD_G31, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_mdio_mac3 */ + } + else if (interface_type == PHY_INTERRUPTFACE_SGMII) + { + FPinSetConfig(FIOPAD_E31, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_mdc_mac3 */ + FPinSetConfig(FIOPAD_G31, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_mdio_mac3 */ + } + else + { + printf("Interface_type 0x%x is not support.\r\n"); + return -1; + } + } +#elif defined(CONFIG_BOARD_TYPE_C) + if (instance_id == 1) + { + FPinSetConfig(FIOPAD_AJ49, FPIN_FUNC3, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_mdc_mac1 */ + FPinSetConfig(FIOPAD_AL45, FPIN_FUNC3, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_mdio_mac1 */ + } + else if (instance_id == 2) + { + FPinSetConfig(FIOPAD_E25, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_mdc_mac2 */ + FPinSetConfig(FIOPAD_G25, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_mdio_mac2 */ + } + else if (instance_id == 3) + { + FPinSetConfig(FIOPAD_E31, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_mdc_mac3 */ + FPinSetConfig(FIOPAD_G31, FPIN_FUNC1, FPIN_PULL_NONE, FPIN_DRV4); /* gsd_gmu_mdio_mac3 */ + } + else + { + printf("Interface_type 0x%x is not support.\r\n"); + return -1; + } +#endif + +#endif + + +} \ No newline at end of file diff --git a/example/network/sockets/udp_multicast/src/lwip_test.c b/example/network/sockets/udp_multicast/src/lwip_test.c index 80206a37..dc88a184 100644 --- a/example/network/sockets/udp_multicast/src/lwip_test.c +++ b/example/network/sockets/udp_multicast/src/lwip_test.c @@ -1,27 +1,28 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: lwip_test.c - * Date: 2022-09-15 10:24:38 - * LastEditTime: 2022-09-15 10:24:38 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Date: 2022-06-06 22:57:08 + * LastEditTime: 2022-06-06 22:57:08 + * Description: This file is for lwip test example + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 huanghe 2022/10/21 init + * 1.1 liuzhihong 2023/01/12 driver and application restructure */ - #include #include #include "strto.h" @@ -29,41 +30,52 @@ #include "FreeRTOS.h" #include "task.h" #include "ftypes.h" -#include "fpinctrl.h" +#include "fassert.h" +#include "fparameters.h" #ifndef SDK_CONFIG_H__ - #error "Please include sdkconfig.h first" + #error "Please include sdkconfig.h first" #endif + #include "lwipopts.h" #include "lwip_port.h" #include "lwip/ip4_addr.h" #include "lwip/init.h" #include "netif/ethernet.h" -#include "ethernetif.h" #include "lwip/netif.h" #include "lwip/tcpip.h" +#include "lwip/inet.h" #include "../src/shell.h" #if defined(CONFIG_TARGET_E2000) -#define PHY_INTERRUPTFACE_RGMII 0 -#define PHY_INTERRUPTFACE_SGMII 1 + extern int FXmacPhyGpioInit(u32 instance_id, u32 interface_type); #endif - #if LWIP_IPV6 -#include "lwip/ip.h" -#include "lwip/ip6_addr.h" + #include "lwip/ip.h" + #include "lwip/ip6_addr.h" #else -#if LWIP_DHCP -#include "lwip/dhcp.h" + #if LWIP_DHCP + #include "lwip/dhcp.h" + #endif #endif -#endif - +typedef struct +{ + const char *ipaddr; + const char *gateway; + const char *netmask; +} InputAddress; -user_config lwip_mac_config = {0}; +typedef struct +{ + UserConfig lwip_mac_config; + InputAddress input_address; + u32 dhcp_en; +} InputConfig; +static InputConfig input_config = {0}; #if !LWIP_IPV6 #if LWIP_DHCP @@ -72,140 +84,114 @@ void LwipDhcpTest(struct netif *echo_netif) { int mscnt = 0; dhcp_start(echo_netif); - printf("LwipDhcpTest is start \r\n"); + printf("LwipDhcpTest is start.\r\n"); while (1) { - vTaskDelay(DHCP_FINE_TIMER_MSECS / portTICK_RATE_MS); - dhcp_fine_tmr(); - mscnt += DHCP_FINE_TIMER_MSECS; - if (mscnt >= DHCP_COARSE_TIMER_SECS*1000) + vTaskDelay(DHCP_FINE_TIMER_MSECS / portTICK_RATE_MS); + dhcp_fine_tmr(); + mscnt += DHCP_FINE_TIMER_MSECS; + if (mscnt >= DHCP_COARSE_TIMER_SECS * 1000) { - dhcp_coarse_tmr(); - mscnt = 0; - } - } + dhcp_coarse_tmr(); + mscnt = 0; + } + } } #endif #endif -void LwipTestCreate(void * args) +void LwipTestCreate(void *args) { - struct netif *echo_netif; + FASSERT(args != NULL); + struct netif *netif_p = NULL; static boolean init_flag = FALSE; + InputConfig *input_conf = (InputConfig *)args; + ip_addr_t ipaddr = {0}, netmask = {0}, gw = {0}; BaseType_t ret = pdPASS; /* the mac address of the board. this should be unique per board */ - unsigned char mac_ethernet_address[] = - {0x98, 0x0e, 0x24, 0x00, 0x11, 0x22}; + unsigned char mac_address[6] = + {0x98, 0x0e, 0x24, 0x00, 0x11, 0}; - echo_netif = pvPortMalloc(sizeof(struct netif)); - if(echo_netif == NULL) + netif_p = pvPortMalloc(sizeof(struct netif)); /* 暂未回收内存 */ + if (netif_p == NULL) { - printf("malloc netif is error \r\n"); + printf("Malloc netif is error.\r\n"); goto exit; } + printf("netif_p is %p .\r\n", netif_p); + mac_address[5] = input_conf->lwip_mac_config.mac_instance; -#if !LWIP_IPV6 - ip_addr_t ipaddr, netmask, gw; -#if LWIP_DHCP - ipaddr.addr = 0; - gw.addr = 0; - netmask.addr = 0; -#else - /* initialize IP addresses to be used */ - IP4_ADDR(&ipaddr, 192, 168, 4, 10); - IP4_ADDR(&netmask, 255, 255, 255, 0); - IP4_ADDR(&gw, 192, 168, 4, 1); -#endif -#endif + + /* convert string to a binary address */ + if (input_conf->input_address.ipaddr) + { + if (inet_aton(input_conf->input_address.ipaddr, &ipaddr) == 0) + { + goto failed; + } + } + + if (input_conf->input_address.gateway) + { + if (inet_aton(input_conf->input_address.gateway, &gw) == 0) + { + goto failed; + } + } + + if (input_conf->input_address.netmask) + { + if (inet_aton(input_conf->input_address.netmask, &netmask) == 0) + { + goto failed; + } + } /* 初始化LwIP堆 */ - if(init_flag == FALSE) + if (init_flag == FALSE) { tcpip_init(NULL, NULL); init_flag = TRUE; } -#if !LWIP_IPV6 - /* Add network interface to the netif_list, and set it as default */ - if (!lwip_port_add(echo_netif, &ipaddr, &netmask, - &gw, mac_ethernet_address, - (user_config *)args)) - { - printf("Error adding N/W interface\n\r"); - return ; - } - printf("lwip_port_add is over \n\r"); -#else - /* Add network interface to the netif_list, and set it as default */ - if (!lwip_port_add(echo_netif, NULL, NULL, NULL, mac_ethernet_address, (user_config *)args)) - { - printf("Error adding N/W interface\n\r"); - return ; - } - echo_netif->ip6_autoconfig_enabled = 1; - - netif_create_ip6_linklocal_address(echo_netif, 1); - netif_ip6_addr_set_state(echo_netif, 0, IP6_ADDR_VALID); - - printf("Board IPv6 address %x:%x:%x:%x:%x:%x:%x:%x\n\r", - IP6_ADDR_BLOCK1(&echo_netif->ip6_addr[0].u_addr.ip6), - IP6_ADDR_BLOCK2(&echo_netif->ip6_addr[0].u_addr.ip6), - IP6_ADDR_BLOCK3(&echo_netif->ip6_addr[0].u_addr.ip6), - IP6_ADDR_BLOCK4(&echo_netif->ip6_addr[0].u_addr.ip6), - IP6_ADDR_BLOCK5(&echo_netif->ip6_addr[0].u_addr.ip6), - IP6_ADDR_BLOCK6(&echo_netif->ip6_addr[0].u_addr.ip6), - IP6_ADDR_BLOCK7(&echo_netif->ip6_addr[0].u_addr.ip6), - IP6_ADDR_BLOCK8(&echo_netif->ip6_addr[0].u_addr.ip6)); + /* Add network interface to the netif_list, and set it as default */ + if (!LwipPortAdd(netif_p, &ipaddr, &netmask, + &gw, mac_address, + (UserConfig *)args, 0)) + { + printf("Error adding N/W interface.\r\n"); + return ; + } + printf("LwipPortAdd is over.\r\n"); +#if (LWIP_IPV6 == 1) + netif_p->ip6_autoconfig_enabled = 1; + netif_create_ip6_linklocal_address(netif_p, 1); + netif_ip6_addr_set_state(netif_p, 0, IP6_ADDR_VALID); #endif - netif_set_default(echo_netif); + netif_set_default(netif_p); - if (netif_is_link_up(echo_netif)) + if (netif_is_link_up(netif_p)) { /* 当netif完全配置好时,必须调用该函数 */ - netif_set_up(echo_netif); + netif_set_up(netif_p); + if (input_conf->dhcp_en) + { + LwipPortDhcpSet(netif_p, TRUE); + } } else { /* 当netif链接关闭时,必须调用该函数 */ - netif_set_down(echo_netif); + netif_set_down(netif_p); } - printf("neftwork setup complete\n"); - - if (xTaskCreate((TaskFunction_t )lwip_port_input_thread, - "recv_echo", - 8192, - echo_netif, - 4, - NULL) != pdPASS) - { - printf("xTaskCreate is Error %s\r\n", "recv_echo"); - FASSERT(0); - } - -#if LWIP_DHCP && LWIP_IPV4 - /* Create a new DHCP client for this interface. - * Note: you must call dhcp_fine_tmr() and dhcp_coarse_tmr() at - * the predefined regular intervals after starting the client. - */ - printf("dhcp_start...\r\n"); - - ret = xTaskCreate((TaskFunction_t )LwipDhcpTest, /* 任务入口函数 */ - (const char* )"LwipDhcpTest",/* 任务名字 */ - (uint16_t )4096, /* 任务栈大小 */ - (void* )(echo_netif),/* 任务入口函数参数 */ - (UBaseType_t )configMAX_PRIORITIES-1, /* 任务的优先级 */ - (TaskHandle_t* )&appTaskCreateHandle); /* 任务控制 */ - - if (pdPASS == ret) - { - printf("create lwip dhcp task success!\r\n"); - } - -#endif + printf("Network setup complete.\r\n"); + goto exit ; +failed: + vPortFree(netif_p); exit: vTaskDelete(NULL); } @@ -217,169 +203,40 @@ void LwipTest(void *args) (const char *)"LwipTestCreate", /* 任务名字 */ (uint16_t)2048, /* 任务栈大小 */ (void *)args, /* 任务入口函数参数 */ - (UBaseType_t)configMAX_PRIORITIES-1,/* 任务的优先级 */ + (UBaseType_t)configMAX_PRIORITIES - 1, /* 任务的优先级 */ NULL); /* 任务控制块指针 */ - FASSERT_MSG(ret == pdPASS,"LwipTestCreate Task create is failed"); - + FASSERT_MSG(ret == pdPASS, "LwipTestCreate Task create is failed"); } -int FXmacPhyGpioInit(u32 instance_id,u32 interface_type) -{ -#if defined(CONFIG_TARGET_E2000Q) -#if defined(CONFIG_BOARD_TYPE_B) - if(instance_id == 3) - { - if(interface_type == PHY_INTERRUPTFACE_RGMII) - { - FPinSetConfig(FIOPAD_J37,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_txd1_0 - */ - FPinSetConfig(FIOPAD_J39,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_txd1_1 - */ - FPinSetConfig(FIOPAD_G41,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_rxd1_0 - */ - FPinSetConfig(FIOPAD_E43,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_rxd1_1 - */ - FPinSetConfig(FIOPAD_L43,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_tx_ctl1 */ - FPinSetConfig(FIOPAD_C43,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_rxd1_2 */ - FPinSetConfig(FIOPAD_E41,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_rxd1_3 */ - FPinSetConfig(FIOPAD_L45,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_rx_clk1 */ - FPinSetConfig(FIOPAD_J43,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_rx_ctl1 */ - FPinSetConfig(FIOPAD_J41,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_tx_clk1 */ - FPinSetDelay(FIOPAD_J41_DELAY,FPIN_OUTPUT_DELAY,FPIN_DELAY_FINE_TUNING,FPIN_DELAY_7); - FPinSetDelay(FIOPAD_J41_DELAY,FPIN_OUTPUT_DELAY,FPIN_DELAY_COARSE_TUNING,FPIN_DELAY_5); - FPinSetDelayEn(FIOPAD_J41_DELAY,FPIN_OUTPUT_DELAY,1); - - FPinSetConfig(FIOPAD_L39,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_txd1_2 */ - FPinSetConfig(FIOPAD_E37,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_txd1_3 */ - FPinSetConfig(FIOPAD_E35,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdc_mac3 */ - FPinSetConfig(FIOPAD_G35,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdio_mac3 */ - } - else if(interface_type == PHY_INTERRUPTFACE_SGMII) - { - FPinSetConfig(FIOPAD_E35,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdc_mac3 */ - FPinSetConfig(FIOPAD_G35,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdio_mac3 */ - } - else - { - printf("interface_type 0x%x is not support \r\n"); - return -1; - } - } -#elif defined(CONFIG_BOARD_TYPE_C) - if(instance_id == 1) - { - FPinSetConfig(FIOPAD_AJ53,FPIN_FUNC3,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdc_mac1 */ - FPinSetConfig(FIOPAD_AL49,FPIN_FUNC3,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdio_mac1 */ - } - else if(instance_id == 2) - { - FPinSetConfig(FIOPAD_E29,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdc_mac2 */ - FPinSetConfig(FIOPAD_G29,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdio_mac2 */ - } - else if(instance_id == 3) - { - FPinSetConfig(FIOPAD_E35,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdc_mac3 */ - FPinSetConfig(FIOPAD_G35,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdio_mac3 */ - } - else - { - printf("interface_type 0x%x is not support \r\n"); - return -1; - } -#endif -#elif defined(CONFIG_TARGET_E2000D) || defined(CONFIG_TARGET_E2000S) - -#if defined(CONFIG_BOARD_TYPE_B) - if(instance_id == 3) - { - if(interface_type == PHY_INTERRUPTFACE_RGMII) - { - FPinSetConfig(FIOPAD_J33,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_txd1_0 - */ - FPinSetConfig(FIOPAD_J35,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_txd1_1 - */ - FPinSetConfig(FIOPAD_G37,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_rxd1_0 - */ - FPinSetConfig(FIOPAD_E39,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_rxd1_1 - */ - FPinSetConfig(FIOPAD_L39,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_tx_ctl1 */ - FPinSetConfig(FIOPAD_C39,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_rxd1_2 */ - FPinSetConfig(FIOPAD_E37,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_rxd1_3 */ - FPinSetConfig(FIOPAD_L41,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_rx_clk1 */ - FPinSetConfig(FIOPAD_J39,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_rx_ctl1 */ - FPinSetConfig(FIOPAD_J37,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_tx_clk1 */ - FPinSetDelay(FIOPAD_J37_DELAY,FPIN_OUTPUT_DELAY,FPIN_DELAY_COARSE_TUNING,FPIN_DELAY_5); - FPinSetDelay(FIOPAD_J37_DELAY,FPIN_OUTPUT_DELAY,FPIN_DELAY_FINE_TUNING,FPIN_DELAY_7); - FPinSetDelayEn(FIOPAD_J37_DELAY,FPIN_OUTPUT_DELAY,1); - FPinSetConfig(FIOPAD_L35,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_txd1_2 */ - FPinSetConfig(FIOPAD_E33,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_txd1_3 */ - FPinSetConfig(FIOPAD_E31,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdc_mac3 */ - FPinSetConfig(FIOPAD_G31,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdio_mac3 */ - } - else if(interface_type == PHY_INTERRUPTFACE_SGMII) - { - FPinSetConfig(FIOPAD_E31,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdc_mac3 */ - FPinSetConfig(FIOPAD_G31,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdio_mac3 */ - } - else - { - printf("interface_type 0x%x is not support \r\n"); - return -1; - } - } -#elif defined(CONFIG_BOARD_TYPE_C) - if(instance_id == 1) - { - FPinSetConfig(FIOPAD_AJ49,FPIN_FUNC3,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdc_mac1 */ - FPinSetConfig(FIOPAD_AL45,FPIN_FUNC3,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdio_mac1 */ - } - else if(instance_id == 2) - { - FPinSetConfig(FIOPAD_E25,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdc_mac2 */ - FPinSetConfig(FIOPAD_G25,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdio_mac2 */ - } - else if(instance_id == 3) - { - FPinSetConfig(FIOPAD_E31,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdc_mac3 */ - FPinSetConfig(FIOPAD_G31,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdio_mac3 */ - } - else - { - printf("interface_type 0x%x is not support \r\n"); - return -1; - } - -#endif - -#endif - -} - - static int LwipDeviceSet(int argc, char *argv[]) { - u32 id = 0,type = 0; - - static int probe_flg = 0; - LWIP_PORT_CONFIG_DEFAULT_INIT(lwip_mac_config); + u32 id = 0, type = 0; + const char *ipaddr = NULL; + const char *gateway = NULL; + const char *netmask = NULL; + memset(&input_config, 0, sizeof(input_config)); + LWIP_PORT_CONFIG_DEFAULT_INIT(input_config.lwip_mac_config); if (!strcmp(argv[1], "probe")) { - if(probe_flg == 1) - { - printf("The initialization of the instance is complete. Do not repeat this process \r\n") ; - return -1; - } - - switch(argc) + switch (argc) { + case 8: + netmask = argv[7]; + case 7: + gateway = argv[6]; + case 6: + ipaddr = argv[5]; + input_config.input_address.ipaddr = ipaddr; + input_config.input_address.gateway = gateway; + input_config.input_address.netmask = netmask; + case 5: + input_config.dhcp_en = (u32)simple_strtoul(argv[4], NULL, 10); case 4: type = (u32)simple_strtoul(argv[3], NULL, 10); - id = (u32)simple_strtoul(argv[2], NULL, 10); - break; case 3: id = (u32)simple_strtoul(argv[2], NULL, 10); break; @@ -388,29 +245,62 @@ static int LwipDeviceSet(int argc, char *argv[]) } printf("types %d\n", type); printf("id %d\n", id); - FXmacPhyGpioInit(id,type); - lwip_mac_config.mac_instance = id; - if(type == 0) + +#if defined(CONFIG_TARGET_E2000) + FXmacPhyGpioInit(id, type); +#endif + input_config.lwip_mac_config.mac_instance = id; + input_config.lwip_mac_config.name[0] = 'e'; + itoa(id, &input_config.lwip_mac_config.name[1], 10); + if (type == 0) { - lwip_mac_config.mii_interface = LWIP_PORT_INTERFACE_RGMII; + input_config.lwip_mac_config.mii_interface = LWIP_PORT_INTERFACE_RGMII; } else { - lwip_mac_config.mii_interface = LWIP_PORT_INTERFACE_SGMII; + input_config.lwip_mac_config.mii_interface = LWIP_PORT_INTERFACE_SGMII; + } + + LwipTest(&input_config); + } + else if (!strcmp(argv[1], "deinit")) + { + if (argc <= 1) + { + printf("Please enter lwip deinit \r\n") ; + printf(" -- use name to deinit neitf object \r\n"); + printf(" -- is netif name \r\n"); + return -1; + } + struct netif *netif_p = NULL; + netif_p = LwipPortGetByName(argv[2]); + if (netif_p == NULL) + { + printf("Netif %s is not invalid \r\n", argv[2]); + return -1; } - LwipTest(&lwip_mac_config); - probe_flg = 1; + /* close rx thread */ + vPortEnterCritical(); + LwipPortStop(netif_p); + vPortFree(netif_p); + vPortExitCritical(); } else { - printf("Please enter xmac probe \r\n") ; + printf("Please enter lwip probe \r\n") ; printf(" -- device id is mac instance number \r\n"); printf(" -- interface id is media independent interface , 0 is rgmii ,1 is sgmii \r\n"); + printf(" -- dhcp_en is dhcp function set ,1 is enable ,0 is disable .But this depends on whether the protocol stack supports it "); + printf(" -- Ip address of netif \r\n"); + printf(" -- Gateway of netif \r\n"); + printf(" -- Netmask of netif \r\n"); + printf("Please enter lwip deinit \r\n") ; + printf(" -- use name to deinit neitf object \r\n"); + printf(" -- is netif name \r\n"); } - return 0; } -SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), xmac, LwipDeviceSet, Setup LWIP device test); +SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), lwip, LwipDeviceSet, Setup LWIP device test); diff --git a/example/network/sockets/udp_multicast/src/multicast.c b/example/network/sockets/udp_multicast/src/multicast.c index 809fa1c7..9822bc02 100644 --- a/example/network/sockets/udp_multicast/src/multicast.c +++ b/example/network/sockets/udp_multicast/src/multicast.c @@ -1,24 +1,26 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: multicast.c * Date: 2022-09-15 10:19:11 * LastEditTime: 2022-09-15 10:19:11 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for running multicast example task + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 huanghe 2022/10/21 init + * 1.1 liuzhihong 2023/01/12 driver and application restructure */ #include @@ -27,14 +29,15 @@ #include "task.h" #include "event_groups.h" #include "err.h" + +#include "netif.h" #include "sockets.h" #include "sockets_ext.h" -#include "sys.h" -#include "netif.h" #include +#include "lwip_port.h" + #include "ftypes.h" #include "shell.h" - #include "fdebug.h" #define MULTICAST_DEBUG_TAG "MULTICAST" @@ -60,9 +63,9 @@ #define UDP_PORT CONFIG_EXAMPLE_PORT #if defined(CONFIG_EXAMPLE_LOOPBACK) -#define MULTICAST_LOOPBACK 1 + #define MULTICAST_LOOPBACK 1 #else -#define MULTICAST_LOOPBACK 0 + #define MULTICAST_LOOPBACK 0 #endif #define MULTICAST_TTL CONFIG_EXAMPLE_MULTICAST_TTL @@ -71,12 +74,15 @@ #define MULTICAST_IPV6_ADDR CONFIG_EXAMPLE_MULTICAST_IPV6_ADDR #if defined(EXAMPLE_MULTICAST_LISTEN_ALL_IF) -#define LISTEN_ALL_IF 1 + #define LISTEN_ALL_IF 1 #else -#define LISTEN_ALL_IF 0 + #define LISTEN_ALL_IF 0 #endif - +char eth_name[2] = {0}; +static int multicast_sock = 0; +TaskHandle_t multicast_handle = NULL; +static struct netif *netif_p = NULL; #ifdef CONFIG_EXAMPLE_IPV4 /* Add a socket, either IPV4-only or IPV6 dual mode, to the IPV4 @@ -94,53 +100,58 @@ static int socket_add_ipv4_multicast_group(int sock, boolean assign_source_if) ip_addr_t ipaddr; /* use default netif */ - extern struct netif *netif_default; - if(netif_default == NULL) + extern struct netif *netif_default; + if (netif_default == NULL) { - printf("default netif not set \n"); + printf("default netif not set.\r\n"); goto err; } + inet_addr_from_ip4addr(&iaddr, netif_ip4_addr(netif_default)); - + #endif /* LISTEN_ALL_IF */ /* Configure multicast address to listen to */ err = inet_aton(MULTICAST_IPV4_ADDR, &imreq.imr_multiaddr.s_addr); - if (err != 1) { + if (err != 1) + { IPV4_PRINT_E("Configured IPV4 multicast address '%s' is invalid.", MULTICAST_IPV4_ADDR); - // Errors in the return value have to be negative err = -1; goto err; } - MULTICAST_PRINT_I( "Configured IPV4 Multicast address %s", inet_ntoa(imreq.imr_multiaddr.s_addr)); - if (!IP_MULTICAST(ntohl(imreq.imr_multiaddr.s_addr))) { - IPV4_PRINT_W( "Configured IPV4 multicast address '%s' is not a valid multicast address. This will probably not work.", MULTICAST_IPV4_ADDR); + MULTICAST_PRINT_I("Configured IPV4 Multicast address %s", inet_ntoa(imreq.imr_multiaddr.s_addr)); + if (!IP_MULTICAST(ntohl(imreq.imr_multiaddr.s_addr))) + { + IPV4_PRINT_W("Configured IPV4 multicast address '%s' is not a valid multicast address. This will probably not work.", MULTICAST_IPV4_ADDR); } - if (assign_source_if) { + if (assign_source_if) + { /* Assign the IPv4 multicast source interface, via its IP (only necessary if this socket is IPV4 only) */ err = setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, &iaddr, sizeof(struct in_addr)); - if (err < 0) { + if (err < 0) + { IPV4_PRINT_E("Failed to set IP_MULTICAST_IF. Error %d", errno); goto err; } } err = setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, - &imreq, sizeof(struct ip_mreq)); - if (err < 0) { + &imreq, sizeof(struct ip_mreq)); + if (err < 0) + { IPV4_PRINT_E("Failed to set IP_ADD_MEMBERSHIP. Error %d", errno); goto err; } - err: +err: return err; } #endif /* CONFIG_EXAMPLE_IPV4 */ #ifdef CONFIG_EXAMPLE_IPV6 -static int create_multicast_ipv6_socket(void) +static int create_multicast_ipv6_socket(struct netif *netif_test) { struct sockaddr_in6 saddr = { 0 }; int netif_index; @@ -151,8 +162,9 @@ static int create_multicast_ipv6_socket(void) int err = 0; sock = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IPV6); - if (sock < 0) { - IPV6_PRINT_E( "Failed to create socket. Error %d", errno); + if (sock < 0) + { + IPV6_PRINT_E("Failed to create socket. Error %d", errno); return -1; } @@ -161,8 +173,9 @@ static int create_multicast_ipv6_socket(void) saddr.sin6_port = htons(UDP_PORT); bzero(&saddr.sin6_addr.un, sizeof(saddr.sin6_addr.un)); err = bind(sock, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in6)); - if (err < 0) { - IPV6_PRINT_E( "Failed to bind socket. Error %d", errno); + if (err < 0) + { + IPV6_PRINT_E("Failed to bind socket. Error %d", errno); goto err; } @@ -174,39 +187,36 @@ static int create_multicast_ipv6_socket(void) /* Read interface adapter link-local address and use it to bind the multicast IF to this socket.*/ - extern struct netif *netif_default; - if(netif_default == NULL) - { - printf("default netif not set \n"); - goto err; - } - memcpy(&if_ipaddr, &netif_default->ip6_addr[0], sizeof(ip6_addr_t)); + memcpy(&if_ipaddr, &netif_test->ip6_addr[0], sizeof(ip6_addr_t)); inet6_addr_from_ip6addr(&if_inaddr, &if_ipaddr); - inet6_ntoa_r(if_inaddr, addrbuf, sizeof(addrbuf)-1); - printf("addrbuf is %s \r\n",addrbuf); + inet6_ntoa_r(if_inaddr, addrbuf, sizeof(addrbuf) - 1); + printf("addrbuf is %s .\r\n", addrbuf); #endif /* LISTEN_ALL_IF */ /* search for netif index */ - netif_index = netif_get_index(netif_default); - if(netif_index < 0) { - IPV6_PRINT_E( "Failed to get netif index"); + netif_index = netif_get_index(netif_test); + if (netif_index < 0) + { + IPV6_PRINT_E("Failed to get netif index"); goto err; } - + /* Assign the multicast source interface, via its IP */ - err = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, &netif_index,sizeof(uint8_t)); - if (err < 0) { - IPV6_PRINT_E( "Failed to set IPV6_MULTICAST_IF. Error %d", errno); + err = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, &netif_index, sizeof(uint8_t)); + if (err < 0) + { + IPV6_PRINT_E("Failed to set IPV6_MULTICAST_IF. Error %d", errno); goto err; } /* Assign multicast TTL (set separately from normal interface TTL) */ uint8_t ttl = MULTICAST_TTL; setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl, sizeof(uint8_t)); - if (err < 0) { - IPV6_PRINT_E( "Failed to set IPV6_MULTICAST_HOPS. Error %d", errno); + if (err < 0) + { + IPV6_PRINT_E("Failed to set IPV6_MULTICAST_HOPS. Error %d", errno); goto err; } @@ -216,8 +226,9 @@ static int create_multicast_ipv6_socket(void) uint8_t loopback_val = MULTICAST_LOOPBACK; err = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &loopback_val, sizeof(uint8_t)); - if (err < 0) { - IPV6_PRINT_E( "Failed to set IPV6_MULTICAST_LOOP. Error %d", errno); + if (err < 0) + { + IPV6_PRINT_E("Failed to set IPV6_MULTICAST_LOOP. Error %d", errno); goto err; } #endif @@ -227,22 +238,25 @@ static int create_multicast_ipv6_socket(void) #ifdef CONFIG_EXAMPLE_IPV6 /* Configure multicast address to listen to */ err = inet6_aton(MULTICAST_IPV6_ADDR, &v6imreq.ipv6mr_multiaddr); - if (err != 1) { - IPV6_PRINT_E( "Configured IPV6 multicast address '%s' is invalid.", MULTICAST_IPV6_ADDR); + if (err != 1) + { + IPV6_PRINT_E("Configured IPV6 multicast address '%s' is invalid.", MULTICAST_IPV6_ADDR); goto err; } - MULTICAST_PRINT_I( "Configured IPV6 Multicast address %s", inet6_ntoa(v6imreq.ipv6mr_multiaddr)); + MULTICAST_PRINT_I("Configured IPV6 Multicast address %s", inet6_ntoa(v6imreq.ipv6mr_multiaddr)); ip6_addr_t multi_addr; inet6_addr_to_ip6addr(&multi_addr, &v6imreq.ipv6mr_multiaddr); - if (!ip6_addr_ismulticast(&multi_addr)) { - MULTICAST_PRINT_W( "Configured IPV6 multicast address '%s' is not a valid multicast address. This will probably not work.", MULTICAST_IPV6_ADDR); + if (!ip6_addr_ismulticast(&multi_addr)) + { + MULTICAST_PRINT_W("Configured IPV6 multicast address '%s' is not a valid multicast address. This will probably not work.", MULTICAST_IPV6_ADDR); } /* Configure source interface */ v6imreq.ipv6mr_interface = (unsigned int)netif_index; err = setsockopt(sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &v6imreq, sizeof(struct ipv6_mreq)); - if (err < 0) { - IPV6_PRINT_E( "Failed to set IPV6_ADD_MEMBERSHIP. Error %d", errno); + if (err < 0) + { + IPV6_PRINT_E("Failed to set IPV6_ADD_MEMBERSHIP. Error %d", errno); goto err; } #endif @@ -250,11 +264,11 @@ static int create_multicast_ipv6_socket(void) int only = 1; /* IPV6-only socket */ err = setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &only, sizeof(int)); - if (err < 0) { - IPV6_PRINT_E( "Failed to set IPV6_V6ONLY. Error %d", errno); + if (err < 0) + { + IPV6_PRINT_E("Failed to set IPV6_V6ONLY. Error %d", errno); goto err; } - MULTICAST_PRINT_I( "Socket set IPV6-only"); /* All set, socket is configured for sending and receiving */ return sock; @@ -273,7 +287,8 @@ static int create_multicast_ipv4_socket(void) int err = 0; sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); - if (sock < 0) { + if (sock < 0) + { IPV4_PRINT_E("Failed to create socket. Error %d", errno); return -1; } @@ -283,7 +298,8 @@ static int create_multicast_ipv4_socket(void) saddr.sin_port = htons(UDP_PORT); saddr.sin_addr.s_addr = htonl(INADDR_ANY); err = bind(sock, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in)); - if (err < 0) { + if (err < 0) + { IPV4_PRINT_E("Failed to bind socket. Error %d", errno); goto err; } @@ -292,7 +308,8 @@ static int create_multicast_ipv4_socket(void) /* Assign multicast TTL (set separately from normal interface TTL) */ uint8_t ttl = MULTICAST_TTL; setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(uint8_t)); - if (err < 0) { + if (err < 0) + { IPV4_PRINT_E("Failed to set IP_MULTICAST_TTL. Error %d", errno); goto err; } @@ -303,7 +320,8 @@ static int create_multicast_ipv4_socket(void) uint8_t loopback_val = MULTICAST_LOOPBACK; err = setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, &loopback_val, sizeof(uint8_t)); - if (err < 0) { + if (err < 0) + { IPV4_PRINT_E("Failed to set IP_MULTICAST_LOOP. Error %d", errno); goto err; } @@ -312,7 +330,8 @@ static int create_multicast_ipv4_socket(void) /* this is also a listening socket, so add it to the multicast group for listening... */ err = socket_add_ipv4_multicast_group(sock, TRUE); - if (err < 0) { + if (err < 0) + { goto err; } @@ -325,31 +344,37 @@ err: } #endif /* CONFIG_EXAMPLE_IPV4_ONLY */ -static void MulticastExampleTask(void *pvParameters) +static void MulticastExampleTask(void *args) { - while (1) { - int sock; + struct netif *netif_test = (struct netif *)args; + while (1) + { + int multicast_sock; #ifdef CONFIG_EXAMPLE_IPV4_ONLY - sock = create_multicast_ipv4_socket(); - if (sock < 0) { - MULTICAST_PRINT_E( "Failed to create IPv4 multicast socket"); + multicast_sock = create_multicast_ipv4_socket(); + if (multicast_sock < 0) + { + MULTICAST_PRINT_E("Failed to create IPv4 multicast socket"); } #else - sock = create_multicast_ipv6_socket(); - if (sock < 0) { - MULTICAST_PRINT_E( "Failed to create IPv6 multicast socket"); + multicast_sock = create_multicast_ipv6_socket(netif_test); + if (multicast_sock < 0) + { + MULTICAST_PRINT_E("Failed to create IPv6 multicast socket"); } #endif - if (sock < 0) { + if (multicast_sock < 0) + { vTaskDelay(5 / portTICK_PERIOD_MS); continue; } #ifdef CONFIG_EXAMPLE_IPV4 /* set destination multicast addresses for sending from these sockets */ - struct sockaddr_in sdestv4 = { + struct sockaddr_in sdestv4 = + { .sin_family = PF_INET, .sin_port = htons(UDP_PORT), }; @@ -358,7 +383,8 @@ static void MulticastExampleTask(void *pvParameters) #endif #ifdef CONFIG_EXAMPLE_IPV6 - struct sockaddr_in6 sdestv6 = { + struct sockaddr_in6 sdestv6 = + { .sin6_family = PF_INET6, .sin6_port = htons(UDP_PORT), }; @@ -369,70 +395,81 @@ static void MulticastExampleTask(void *pvParameters) /* Loop waiting for UDP received, and sending UDP packets if we don't see any. */ int err = 1; - while (err > 0) { - struct timeval tv = { + while (err > 0) + { + struct timeval tv = + { .tv_sec = 2, .tv_usec = 0, }; fd_set rfds; FD_ZERO(&rfds); - FD_SET(sock, &rfds); + FD_SET(multicast_sock, &rfds); /* 等待数据接收事件 */ - int s = select(sock + 1, &rfds, NULL, NULL, &tv); - if (s < 0) { - MULTICAST_PRINT_E( "Select failed: errno %d", errno); + int s = select(multicast_sock + 1, &rfds, NULL, NULL, &tv); + if (s < 0) + { + MULTICAST_PRINT_E("Select failed: errno %d", errno); err = -1; break; } - else if (s > 0) { - if (FD_ISSET(sock, &rfds)) { + else if (s > 0) + { + if (FD_ISSET(multicast_sock, &rfds)) + { /* Incoming datagram received */ char recvbuf[48]; char raddr_name[32] = { 0 }; struct sockaddr_storage raddr; /* Large enough for both IPv4 or IPv6 */ socklen_t socklen = sizeof(raddr); - int len = recvfrom(sock, recvbuf, sizeof(recvbuf)-1, 0, + int len = recvfrom(multicast_sock, recvbuf, sizeof(recvbuf) - 1, 0, (struct sockaddr *)&raddr, &socklen); - if (len < 0) { - MULTICAST_PRINT_E( "multicast recvfrom failed: errno %d", errno); + if (len < 0) + { + MULTICAST_PRINT_E("multicast recvfrom failed: errno %d", errno); err = -1; break; } /* Get the sender's address as a string */ #ifdef CONFIG_EXAMPLE_IPV4 - if (raddr.ss_family == PF_INET) { + if (raddr.ss_family == PF_INET) + { inet_ntoa_r(((struct sockaddr_in *)&raddr)->sin_addr, - raddr_name, sizeof(raddr_name)-1); + raddr_name, sizeof(raddr_name) - 1); } #endif #ifdef CONFIG_EXAMPLE_IPV6 - if (raddr.ss_family== PF_INET6) { - inet6_ntoa_r(((struct sockaddr_in6 *)&raddr)->sin6_addr, raddr_name, sizeof(raddr_name)-1); + if (raddr.ss_family == PF_INET6) + { + inet6_ntoa_r(((struct sockaddr_in6 *)&raddr)->sin6_addr, raddr_name, sizeof(raddr_name) - 1); } #endif - MULTICAST_PRINT_I( "received %d bytes from %s:", len, raddr_name); + MULTICAST_PRINT_I("received %d bytes from %s:", len, raddr_name); recvbuf[len] = 0; /* Null-terminate whatever we received and treat like a string... */ - MULTICAST_PRINT_I( "%s", recvbuf); + MULTICAST_PRINT_I("%s", recvbuf); } } - else { /* s == 0 */ + else /* s == 0 */ + { /* Timeout passed with no incoming data, so send something! */ static int send_count; const char sendfmt[] = "Multicast #%d sent by Phytium\n"; char sendbuf[48]; char addrbuf[32] = { 0 }; size_t len = snprintf(sendbuf, sizeof(sendbuf), sendfmt, send_count++); - if (len > sizeof(sendbuf)) { - MULTICAST_PRINT_E( "Overflowed multicast sendfmt buffer!!"); + if (len > sizeof(sendbuf)) + { + MULTICAST_PRINT_E("Overflowed multicast sendfmt buffer!!"); send_count = 0; err = -1; break; } - struct addrinfo hints = { + struct addrinfo hints = + { .ai_flags = AI_PASSIVE, .ai_socktype = SOCK_DGRAM, }; @@ -447,27 +484,30 @@ static void MulticastExampleTask(void *pvParameters) NULL, &hints, &res); - if (err < 0) { - MULTICAST_PRINT_E( "getaddrinfo() failed for IPV4 destination address. error: %d", err); + if (err < 0) + { + MULTICAST_PRINT_E("getaddrinfo() failed for IPV4 destination address. error: %d", err); break; } - if (res == 0) { - MULTICAST_PRINT_E( "getaddrinfo() did not return any addresses"); + if (res == 0) + { + MULTICAST_PRINT_E("getaddrinfo() did not return any addresses"); break; } #ifdef CONFIG_EXAMPLE_IPV4_ONLY ((struct sockaddr_in *)res->ai_addr)->sin_port = htons(UDP_PORT); - inet_ntoa_r(((struct sockaddr_in *)res->ai_addr)->sin_addr, addrbuf, sizeof(addrbuf)-1); - MULTICAST_PRINT_I( "Sending to IPV4 multicast address %s:%d...", addrbuf, UDP_PORT); + inet_ntoa_r(((struct sockaddr_in *)res->ai_addr)->sin_addr, addrbuf, sizeof(addrbuf) - 1); + MULTICAST_PRINT_I("Sending to IPV4 multicast address %s:%d...", addrbuf, UDP_PORT); #else ((struct sockaddr_in6 *)res->ai_addr)->sin6_port = htons(UDP_PORT); - inet6_ntoa_r(((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, addrbuf, sizeof(addrbuf)-1); - MULTICAST_PRINT_I( "Sending to IPV6 (V4 mapped) multicast address %s port %d (%s)...", addrbuf, UDP_PORT, CONFIG_EXAMPLE_MULTICAST_IPV4_ADDR); + inet6_ntoa_r(((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, addrbuf, sizeof(addrbuf) - 1); + MULTICAST_PRINT_I("Sending to IPV6 (V4 mapped) multicast address %s port %d (%s)...", addrbuf, UDP_PORT, CONFIG_EXAMPLE_MULTICAST_IPV4_ADDR); #endif - err = sendto(sock, sendbuf, len, 0, res->ai_addr, res->ai_addrlen); + err = sendto(multicast_sock, sendbuf, len, 0, res->ai_addr, res->ai_addrlen); freeaddrinfo(res); - if (err < 0) { - MULTICAST_PRINT_E( "IPV4 sendto failed. errno: %d", errno); + if (err < 0) + { + MULTICAST_PRINT_E("IPV4 sendto failed. errno: %d", errno); break; } #endif @@ -478,55 +518,73 @@ static void MulticastExampleTask(void *pvParameters) NULL, &hints, &res); - if (err < 0) { - MULTICAST_PRINT_E( "getaddrinfo() failed for IPV6 destination address. error: %d", err); + if (err < 0) + { + MULTICAST_PRINT_E("getaddrinfo() failed for IPV6 destination address. error: %d", err); break; } struct sockaddr_in6 *s6addr = (struct sockaddr_in6 *)res->ai_addr; s6addr->sin6_port = htons(UDP_PORT); - inet6_ntoa_r(s6addr->sin6_addr, addrbuf, sizeof(addrbuf)-1); - MULTICAST_PRINT_I( "Sending to IPV6 multicast address %s port %d...", addrbuf, UDP_PORT); - err = sendto(sock, sendbuf, len, 0, res->ai_addr, res->ai_addrlen); + inet6_ntoa_r(s6addr->sin6_addr, addrbuf, sizeof(addrbuf) - 1); + MULTICAST_PRINT_I("Sending to IPV6 multicast address %s port %d...", addrbuf, UDP_PORT); + err = sendto(multicast_sock, sendbuf, len, 0, res->ai_addr, res->ai_addrlen); freeaddrinfo(res); - if (err < 0) { - MULTICAST_PRINT_E( "IPV6 sendto failed. errno: %d", errno); + if (err < 0) + { + MULTICAST_PRINT_E("IPV6 sendto failed. errno: %d", errno); break; } #endif } } - MULTICAST_PRINT_E( "Shutting down socket and restarting..."); - shutdown(sock, 0); - close(sock); + MULTICAST_PRINT_E("Shutting down socket and restarting..."); + shutdown(multicast_sock, 0); + close(multicast_sock); } - + vTaskDelete(NULL); } - static int MulticastMain(int argc, char *argv[]) { static int create_flg = 0; BaseType_t task_ret; - if(create_flg == 0) - { - create_flg++; - } - else + + /* prase multicast */ + + if (argc > 1) { - MULTICAST_PRINT_E( "The multicast task has been created. Do not create it again "); - return -1; - } + /* first find netif */ + netif_p = LwipPortGetByName(argv[1]); + if (netif_p == NULL) + { + printf("netif %s is not invalid.\r\n", argv[1]); + return -1; + } - /* step 1: Create multicast task */ - task_ret = xTaskCreate(&MulticastExampleTask, "mcast_task", 4096, NULL, 5, NULL); + if (create_flg == 0) + { + /* step 1: Create multicast task */ + task_ret = xTaskCreate(&MulticastExampleTask, "mcast_task", 4096, netif_p, 5, &multicast_handle); - if(task_ret != pdPASS) + if (task_ret != pdPASS) + { + create_flg = 0; + MULTICAST_PRINT_E("Failed to create multicast task "); + return -1; + } + create_flg++; + } + else + { + printf("Multicast task is already created,do not repeat the creation \r\n"); + } + } + else { - create_flg = 0; - MULTICAST_PRINT_E("Failed to create multicast task "); - return -1; + printf("Please enter multicast \r\n") ; + printf(" -- netif_name is netif name \r\n"); } return 0; diff --git a/example/network/sockets/udp_multicast/test/multicast_server_ipv4.c b/example/network/sockets/udp_multicast/test/multicast_server_ipv4.c index 5357787f..c4e22104 100644 --- a/example/network/sockets/udp_multicast/test/multicast_server_ipv4.c +++ b/example/network/sockets/udp_multicast/test/multicast_server_ipv4.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: multicast_server_ipv4.c * Date: 2022-09-16 09:15:47 * LastEditTime: 2022-09-16 09:15:47 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for multicast ipv4 server + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 huanghe 2022/10/21 init */ #include @@ -32,7 +33,7 @@ -#if defined(CONFIG_EXAMPLE_IPV4_ONLY) +#if defined(CONFIG_EXAMPLE_IPV4_ONLY) || defined(CONFIG_EXAMPLE_IPV4_V6) #define GROUP_IP CONFIG_EXAMPLE_MULTICAST_IPV4_ADDR #define TEST_PORT CONFIG_EXAMPLE_PORT @@ -42,47 +43,47 @@ int main() { // 1. 创建通信的套接字 int fd = socket(AF_INET, SOCK_DGRAM, 0); - if(fd == -1) + if (fd == -1) { perror("socket"); exit(0); } - printf("addr is %s \r\n",GROUP_IP); - printf("TEST_PORT is %d \r\n",TEST_PORT); + printf("addr is %s \r\n", GROUP_IP); + printf("TEST_PORT is %d \r\n", TEST_PORT); // 2. 通信的套接字和本地的IP与端口绑定 struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(TEST_PORT); // 大端 addr.sin_addr.s_addr = htonl(INADDR_ANY); // 0.0.0.0 - int ret = bind(fd, (struct sockaddr*)&addr, sizeof(addr)); - if(ret == -1) + int ret = bind(fd, (struct sockaddr *)&addr, sizeof(addr)); + if (ret == -1) { perror("bind"); exit(0); } printf("加入到多播组 \r\n"); // 3. 加入到多播组 - struct ip_mreq mreq; // 多播地址结构体 - mreq.imr_multiaddr.s_addr=inet_addr(GROUP_IP); - mreq.imr_interface.s_addr = htonl(INADDR_ANY); - ret=setsockopt(fd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq)); + struct ip_mreq mreq; // 多播地址结构体 + mreq.imr_multiaddr.s_addr = inet_addr(GROUP_IP); + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)); char buf[1024]; - char sendaddrbuf[64]; - socklen_t len = sizeof(struct sockaddr_in); - struct sockaddr_in sendaddr; - printf("通信 \r\n"); + char sendaddrbuf[64]; + socklen_t len = sizeof(struct sockaddr_in); + struct sockaddr_in sendaddr; + printf("通信 \r\n"); // 3. 通信 - while(1) + while (1) { // 接收广播消息 memset(buf, 0, sizeof(buf)); // 阻塞等待数据达到 - + recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&sendaddr, &len); - printf("sendaddr:%s, port:%d\n", inet_ntop(AF_INET, &sendaddr.sin_addr.s_addr, sendaddrbuf, sizeof(sendaddrbuf)), sendaddr.sin_port); + printf("sendaddr:%s, port:%d\n", inet_ntop(AF_INET, &sendaddr.sin_addr.s_addr, sendaddrbuf, sizeof(sendaddrbuf)), sendaddr.sin_port); printf("接收到的组播消息: %s\n", buf); - sendto(fd, buf, strlen(buf)+1, 0, (struct sockaddr *)&sendaddr, len); + sendto(fd, buf, strlen(buf) + 1, 0, (struct sockaddr *)&sendaddr, len); } close(fd); return 0; diff --git a/example/network/sockets/udp_multicast/test/multicast_server_ipv6.c b/example/network/sockets/udp_multicast/test/multicast_server_ipv6.c index 6f474dcf..aac314d2 100644 --- a/example/network/sockets/udp_multicast/test/multicast_server_ipv6.c +++ b/example/network/sockets/udp_multicast/test/multicast_server_ipv6.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: multicast_server_ipv6.c * Date: 2022-09-23 14:28:25 * LastEditTime: 2022-09-23 14:28:25 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for multicast ipv4 server + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 huanghe 2022/10/21 init */ @@ -29,40 +30,40 @@ #include #include "../sdkconfig.h" -#if defined(CONFIG_EXAMPLE_IPV6_ONLY) +#if defined(CONFIG_EXAMPLE_IPV4_V6) int main() { //创建套接字 int fd = socket(AF_INET6, SOCK_DGRAM, 0); - printf("multicast address is %s ,port is %d \r\n",CONFIG_EXAMPLE_MULTICAST_IPV6_ADDR,CONFIG_EXAMPLE_PORT); + printf("multicast address is %s ,port is %d \r\n", CONFIG_EXAMPLE_MULTICAST_IPV6_ADDR, CONFIG_EXAMPLE_PORT); //绑定本地网络信息 struct sockaddr_in6 address = {AF_INET6, htons(CONFIG_EXAMPLE_PORT)}; - bind(fd, (struct sockaddr*)&address, sizeof address); + bind(fd, (struct sockaddr *)&address, sizeof address); //ipv6_mreq结构提供了用于IPv6地址的多播组的信息。 struct ipv6_mreq group; //将接口索引指定为0,则使用默认的多播接口。 - group.ipv6mr_interface = 0; + group.ipv6mr_interface = 0; //IPv6组播组的地址。 - inet_pton(AF_INET6, CONFIG_EXAMPLE_MULTICAST_IPV6_ADDR, &group.ipv6mr_multiaddr); + inet_pton(AF_INET6, CONFIG_EXAMPLE_MULTICAST_IPV6_ADDR, &group.ipv6mr_multiaddr); //将套接字加入到指定接口上提供的多播组。此选项仅对数据报和原始套接字有效(套接字类>型必须为SOCK_DGRAM或SOCK_RAW)。 setsockopt(fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &group, sizeof(group)); char buf[1024]; - char sendaddrbuf[64]; - socklen_t len = sizeof(struct sockaddr_in); - struct sockaddr_in sendaddr; + char sendaddrbuf[64]; + socklen_t len = sizeof(struct sockaddr_in); + struct sockaddr_in sendaddr; // 3. 通信 - while(1) + while (1) { // 接收广播消息 memset(buf, 0, sizeof(buf)); // 阻塞等待数据达到 recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&sendaddr, &len); - printf("sendaddr:%s, port:%d\n", inet_ntop(AF_INET6, &sendaddr.sin_addr.s_addr, sendaddrbuf, sizeof(sendaddrbuf)), sendaddr.sin_port); + printf("sendaddr:%s, port:%d\n", inet_ntop(AF_INET6, &sendaddr.sin_addr.s_addr, sendaddrbuf, sizeof(sendaddrbuf)), sendaddr.sin_port); printf("接收到的组播消息: %s\n", buf); - sendto(fd, buf, strlen(buf)+1, 0, (struct sockaddr *)&sendaddr, len); + sendto(fd, buf, strlen(buf) + 1, 0, (struct sockaddr *)&sendaddr, len); } close(fd); return 0; diff --git a/example/network/xmac_lwip_test/pic/ping.png b/example/network/xmac_lwip_test/pic/ping.png deleted file mode 100644 index 4df451934d172b9bd0870228ad29d0d6c45937eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29540 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 U7FRVlpI)yz9yp$}_t|@|&t7Z2SC1~)TPkea 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 diff --git a/example/network/xmac_lwip_test/pic/xmac_probe_dhcp0.png b/example/network/xmac_lwip_test/pic/xmac_probe_dhcp0.png deleted file mode 100644 index c85d0fe369663cf9086edc18fd9e094553d2f6da..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 42854 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 Ys%StyRuOLe)5=Vqb*AMj&t>;M1& diff --git a/example/network/xmac_lwip_test/pic/xmac_probe_ipv4.png b/example/network/xmac_lwip_test/pic/xmac_probe_ipv4.png deleted file mode 100644 index 584686e115481cc7156df9172e83256fde15088a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27042 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 diff --git a/example/network/xmac_lwip_test/pic/xmac_probe_ipv6.png b/example/network/xmac_lwip_test/pic/xmac_probe_ipv6.png deleted file mode 100644 index 43c8fe8eb1663750a2322b469b8ff289e9380e5e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 154990 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 z

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
+>zf&Kg(8`N_bl1$1UU}5J_YvQkNJFLR)v}G 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 -#include -#include "strto.h" -#include "sdkconfig.h" -#include "FreeRTOS.h" -#include "task.h" -#include "ftypes.h" -#include "fpinctrl.h" -#ifndef SDK_CONFIG_H__ - #error "Please include sdkconfig.h first" -#endif - -#include "lwipopts.h" -#include "lwip_port.h" -#include "lwip/ip4_addr.h" -#include "lwip/init.h" -#include "netif/ethernet.h" -#include "ethernetif.h" -#include "lwip/netif.h" -#include "lwip/tcpip.h" -#include "../src/shell.h" - - -#if defined(CONFIG_TARGET_E2000) -#define PHY_INTERRUPTFACE_RGMII 0 -#define PHY_INTERRUPTFACE_SGMII 1 -#endif - - -#if LWIP_IPV6 -#include "lwip/ip.h" -#include "lwip/ip6_addr.h" -#else -#if LWIP_DHCP -#include "lwip/dhcp.h" -#endif -#endif - - - -user_config lwip_mac_config = {0}; - - -#if !LWIP_IPV6 -#if LWIP_DHCP -static TaskHandle_t appTaskCreateHandle = NULL; -void LwipDhcpTest(struct netif *echo_netif) -{ - int mscnt = 0; - dhcp_start(echo_netif); - printf("LwipDhcpTest is start \r\n"); - while (1) - { - vTaskDelay(DHCP_FINE_TIMER_MSECS / portTICK_RATE_MS); - dhcp_fine_tmr(); - mscnt += DHCP_FINE_TIMER_MSECS; - if (mscnt >= DHCP_COARSE_TIMER_SECS*1000) - { - dhcp_coarse_tmr(); - mscnt = 0; - } - } -} -#endif -#endif - -void LwipTestCreate(void * args) -{ - struct netif *echo_netif; - static boolean init_flag = FALSE; - BaseType_t ret = pdPASS; - /* the mac address of the board. this should be unique per board */ - unsigned char mac_ethernet_address[] = - {0x98, 0x0e, 0x24, 0x00, 0x11, 0x22}; - - echo_netif = pvPortMalloc(sizeof(struct netif)); - if(echo_netif == NULL) - { - printf("malloc netif is error \r\n"); - goto exit; - } - -#if !LWIP_IPV6 - ip_addr_t ipaddr, netmask, gw; -#if LWIP_DHCP - ipaddr.addr = 0; - gw.addr = 0; - netmask.addr = 0; -#else - /* initialize IP addresses to be used */ - IP4_ADDR(&ipaddr, 192, 168, 4, 10); - IP4_ADDR(&netmask, 255, 255, 255, 0); - IP4_ADDR(&gw, 192, 168, 4, 1); -#endif -#endif - - /* 初始化LwIP堆 */ - if(init_flag == FALSE) - { - tcpip_init(NULL, NULL); - init_flag = TRUE; - } - -#if !LWIP_IPV6 - /* Add network interface to the netif_list, and set it as default */ - if (!lwip_port_add(echo_netif, &ipaddr, &netmask, - &gw, mac_ethernet_address, - (user_config *)args)) - { - printf("Error adding N/W interface\n\r"); - return ; - } - printf("lwip_port_add is over \n\r"); -#else - /* Add network interface to the netif_list, and set it as default */ - if (!lwip_port_add(echo_netif, NULL, NULL, NULL, mac_ethernet_address, (user_config *)args)) - { - printf("Error adding N/W interface\n\r"); - return ; - } - echo_netif->ip6_autoconfig_enabled = 1; - - netif_create_ip6_linklocal_address(echo_netif, 1); - netif_ip6_addr_set_state(echo_netif, 0, IP6_ADDR_VALID); - - printf("Board IPv6 address %x:%x:%x:%x:%x:%x:%x:%x\n\r", - IP6_ADDR_BLOCK1(&echo_netif->ip6_addr[0].u_addr.ip6), - IP6_ADDR_BLOCK2(&echo_netif->ip6_addr[0].u_addr.ip6), - IP6_ADDR_BLOCK3(&echo_netif->ip6_addr[0].u_addr.ip6), - IP6_ADDR_BLOCK4(&echo_netif->ip6_addr[0].u_addr.ip6), - IP6_ADDR_BLOCK5(&echo_netif->ip6_addr[0].u_addr.ip6), - IP6_ADDR_BLOCK6(&echo_netif->ip6_addr[0].u_addr.ip6), - IP6_ADDR_BLOCK7(&echo_netif->ip6_addr[0].u_addr.ip6), - IP6_ADDR_BLOCK8(&echo_netif->ip6_addr[0].u_addr.ip6)); - - -#endif - - netif_set_default(echo_netif); - - if (netif_is_link_up(echo_netif)) - { - /* 当netif完全配置好时,必须调用该函数 */ - netif_set_up(echo_netif); - } - else - { - /* 当netif链接关闭时,必须调用该函数 */ - netif_set_down(echo_netif); - } - - printf("network setup complete\n"); - - if (xTaskCreate((TaskFunction_t )lwip_port_input_thread, - "recv_echo", - 8192, - echo_netif, - 4, - NULL) != pdPASS) - { - printf("xTaskCreate is Error %s\r\n", "recv_echo"); - FASSERT(0); - } - -#if LWIP_DHCP && LWIP_IPV4 - /* Create a new DHCP client for this interface. - * Note: you must call dhcp_fine_tmr() and dhcp_coarse_tmr() at - * the predefined regular intervals after starting the client. - */ - printf("dhcp_start...\r\n"); - - ret = xTaskCreate((TaskFunction_t )LwipDhcpTest, /* 任务入口函数 */ - (const char* )"LwipDhcpTest",/* 任务名字 */ - (uint16_t )8192, /* 任务栈大小 */ - (void* )(echo_netif),/* 任务入口函数参数 */ - (UBaseType_t )configMAX_PRIORITIES-1, /* 任务的优先级 */ - (TaskHandle_t* )&appTaskCreateHandle); /* 任务控制 */ - - if (pdPASS == ret) - { - printf("create lwip dhcp task success!\r\n"); - } - -#endif - -exit: - vTaskDelete(NULL); -} - -void LwipTest(void *args) -{ - BaseType_t ret; - ret = xTaskCreate((TaskFunction_t)LwipTestCreate, /* 任务入口函数 */ - (const char *)"LwipTestCreate", /* 任务名字 */ - (uint16_t)2048, /* 任务栈大小 */ - (void *)args, /* 任务入口函数参数 */ - (UBaseType_t)configMAX_PRIORITIES-1,/* 任务的优先级 */ - NULL); /* 任务控制块指针 */ - - FASSERT_MSG(ret == pdPASS,"LwipTestCreate Task create is failed"); - -} - - - -int FXmacPhyGpioInit(u32 instance_id,u32 interface_type) -{ -#if defined(CONFIG_TARGET_E2000Q) -#if defined(CONFIG_BOARD_TYPE_B) - if(instance_id == 3) - { - if(interface_type == PHY_INTERRUPTFACE_RGMII) - { - FPinSetConfig(FIOPAD_J37,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_txd1_0 - */ - FPinSetConfig(FIOPAD_J39,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_txd1_1 - */ - FPinSetConfig(FIOPAD_G41,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_rxd1_0 - */ - FPinSetConfig(FIOPAD_E43,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_rxd1_1 - */ - FPinSetConfig(FIOPAD_L43,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_tx_ctl1 */ - FPinSetConfig(FIOPAD_C43,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_rxd1_2 */ - FPinSetConfig(FIOPAD_E41,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_rxd1_3 */ - FPinSetConfig(FIOPAD_L45,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_rx_clk1 */ - FPinSetConfig(FIOPAD_J43,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_rx_ctl1 */ - FPinSetConfig(FIOPAD_J41,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_tx_clk1 */ - FPinSetDelay(FIOPAD_J41_DELAY,FPIN_OUTPUT_DELAY,FPIN_DELAY_FINE_TUNING,FPIN_DELAY_7); - FPinSetDelay(FIOPAD_J41_DELAY,FPIN_OUTPUT_DELAY,FPIN_DELAY_COARSE_TUNING,FPIN_DELAY_5); - FPinSetDelayEn(FIOPAD_J41_DELAY,FPIN_OUTPUT_DELAY,1); - - FPinSetConfig(FIOPAD_L39,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_txd1_2 */ - FPinSetConfig(FIOPAD_E37,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_txd1_3 */ - FPinSetConfig(FIOPAD_E35,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdc_mac3 */ - FPinSetConfig(FIOPAD_G35,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdio_mac3 */ - } - else if(interface_type == PHY_INTERRUPTFACE_SGMII) - { - FPinSetConfig(FIOPAD_E35,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdc_mac3 */ - FPinSetConfig(FIOPAD_G35,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdio_mac3 */ - } - else - { - printf("interface_type 0x%x is not support \r\n"); - return -1; - } - } -#elif defined(CONFIG_BOARD_TYPE_C) - if(instance_id == 1) - { - FPinSetConfig(FIOPAD_AJ53,FPIN_FUNC3,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdc_mac1 */ - FPinSetConfig(FIOPAD_AL49,FPIN_FUNC3,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdio_mac1 */ - } - else if(instance_id == 2) - { - FPinSetConfig(FIOPAD_E29,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdc_mac2 */ - FPinSetConfig(FIOPAD_G29,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdio_mac2 */ - } - else if(instance_id == 3) - { - FPinSetConfig(FIOPAD_E35,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdc_mac3 */ - FPinSetConfig(FIOPAD_G35,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdio_mac3 */ - } - else - { - printf("interface_type 0x%x is not support \r\n"); - return -1; - } -#endif -#elif defined(CONFIG_TARGET_E2000D) || defined(CONFIG_TARGET_E2000S) - -#if defined(CONFIG_BOARD_TYPE_B) - if(instance_id == 3) - { - if(interface_type == PHY_INTERRUPTFACE_RGMII) - { - FPinSetConfig(FIOPAD_J33,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_txd1_0 - */ - FPinSetConfig(FIOPAD_J35,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_txd1_1 - */ - FPinSetConfig(FIOPAD_G37,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_rxd1_0 - */ - FPinSetConfig(FIOPAD_E39,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_rxd1_1 - */ - FPinSetConfig(FIOPAD_L39,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_tx_ctl1 */ - FPinSetConfig(FIOPAD_C39,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_rxd1_2 */ - FPinSetConfig(FIOPAD_E37,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_rxd1_3 */ - FPinSetConfig(FIOPAD_L41,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_rx_clk1 */ - FPinSetConfig(FIOPAD_J39,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_rx_ctl1 */ - FPinSetConfig(FIOPAD_J37,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_tx_clk1 */ - FPinSetDelay(FIOPAD_J37_DELAY,FPIN_OUTPUT_DELAY,FPIN_DELAY_COARSE_TUNING,FPIN_DELAY_5); - FPinSetDelay(FIOPAD_J37_DELAY,FPIN_OUTPUT_DELAY,FPIN_DELAY_FINE_TUNING,FPIN_DELAY_7); - FPinSetDelayEn(FIOPAD_J37_DELAY,FPIN_OUTPUT_DELAY,1); - FPinSetConfig(FIOPAD_L35,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_txd1_2 */ - FPinSetConfig(FIOPAD_E33,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_rgmii_txd1_3 */ - FPinSetConfig(FIOPAD_E31,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdc_mac3 */ - FPinSetConfig(FIOPAD_G31,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdio_mac3 */ - } - else if(interface_type == PHY_INTERRUPTFACE_SGMII) - { - FPinSetConfig(FIOPAD_E31,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdc_mac3 */ - FPinSetConfig(FIOPAD_G31,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdio_mac3 */ - } - else - { - printf("interface_type 0x%x is not support \r\n"); - return -1; - } - } -#elif defined(CONFIG_BOARD_TYPE_C) - if(instance_id == 1) - { - FPinSetConfig(FIOPAD_AJ49,FPIN_FUNC3,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdc_mac1 */ - FPinSetConfig(FIOPAD_AL45,FPIN_FUNC3,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdio_mac1 */ - } - else if(instance_id == 2) - { - FPinSetConfig(FIOPAD_E25,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdc_mac2 */ - FPinSetConfig(FIOPAD_G25,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdio_mac2 */ - } - else if(instance_id == 3) - { - FPinSetConfig(FIOPAD_E31,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdc_mac3 */ - FPinSetConfig(FIOPAD_G31,FPIN_FUNC1,FPIN_PULL_NONE,FPIN_DRV4); /* gsd_gmu_mdio_mac3 */ - } - else - { - printf("interface_type 0x%x is not support \r\n"); - return -1; - } -#endif - -#endif - - -} - - -static int LwipDeviceSet(int argc, char *argv[]) -{ - u32 id = 0,type = 0; - - static int probe_flg = 0; - LWIP_PORT_CONFIG_DEFAULT_INIT(lwip_mac_config); - - if (!strcmp(argv[1], "probe")) - { - if(probe_flg == 1) - { - printf("The initialization of the instance is complete. Do not repeat this process \r\n") ; - return -1; - } - - switch(argc) - { - case 4: - type = (u32)simple_strtoul(argv[3], NULL, 10); - id = (u32)simple_strtoul(argv[2], NULL, 10); - break; - case 3: - id = (u32)simple_strtoul(argv[2], NULL, 10); - break; - default: - break; - } - printf("types %d\n", type); - printf("id %d\n", id); - FXmacPhyGpioInit(id,type); - lwip_mac_config.mac_instance = id; - if(type == 0) - { - lwip_mac_config.mii_interface = LWIP_PORT_INTERFACE_RGMII; - } - else - { - lwip_mac_config.mii_interface = LWIP_PORT_INTERFACE_SGMII; - } - - LwipTest(&lwip_mac_config); - probe_flg = 1; - } - else - { - printf("Please enter xmac probe \r\n") ; - printf(" -- device id is mac instance number \r\n"); - printf(" -- interface id is media independent interface , 0 is rgmii ,1 is sgmii \r\n"); - } - - return 0; -} - -SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), xmac, LwipDeviceSet, Setup LWIP device test); - diff --git a/example/peripheral/adc/configs/e2000d_aarch32_eg_configs b/example/peripheral/adc/configs/e2000d_aarch32_eg_configs index f0bf9f4a..5b7f0581 100644 --- a/example/peripheral/adc/configs/e2000d_aarch32_eg_configs +++ b/example/peripheral/adc/configs/e2000d_aarch32_eg_configs @@ -74,6 +74,7 @@ CONFIG_USE_FADC=y # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -118,6 +119,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -154,6 +164,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -175,12 +186,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -192,14 +197,32 @@ CONFIG_FREERTOS_USE_ADC=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -217,4 +240,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/adc/configs/e2000d_aarch64_eg_configs b/example/peripheral/adc/configs/e2000d_aarch64_eg_configs index 4e2e0dfe..b3f9414f 100644 --- a/example/peripheral/adc/configs/e2000d_aarch64_eg_configs +++ b/example/peripheral/adc/configs/e2000d_aarch64_eg_configs @@ -74,6 +74,7 @@ CONFIG_USE_FADC=y # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -114,6 +115,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -150,6 +160,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -171,12 +182,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -188,14 +193,32 @@ CONFIG_FREERTOS_USE_ADC=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -213,4 +236,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/adc/inc/adc_example.h b/example/peripheral/adc/inc/adc_example.h index a62aa6cc..2bd61f42 100644 --- a/example/peripheral/adc/inc/adc_example.h +++ b/example/peripheral/adc/inc/adc_example.h @@ -1,30 +1,41 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: adc_example.h * Date: 2022-08-25 16:22:40 * LastEditTime: 2022-08-26 15:40:40 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for task create function define + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 wangxiaodong 2022/08/31 first commit */ #ifndef ADC_EXAMPLE_H #define ADC_EXAMPLE_H +#ifdef __cplusplus +extern "C" +{ +#endif + /* adc test */ BaseType_t FFreeRTOSAdcCreate(u32 id); + +#ifdef __cplusplus +} +#endif + #endif // ! \ No newline at end of file diff --git a/example/peripheral/adc/main.c b/example/peripheral/adc/main.c index 44eb439e..e7371c5b 100644 --- a/example/peripheral/adc/main.c +++ b/example/peripheral/adc/main.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: main.c * Date: 2022-06-17 08:17:59 * LastEditTime: 2022-06-17 08:17:59 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for adc example that running ADC task、shell task and open scheduler + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 wangxiaodong 2022/08/31 first commit */ #include "shell.h" @@ -32,17 +33,21 @@ int main(void) /* test adc 0 */ ret = FFreeRTOSAdcCreate(0); - if(ret != pdPASS) + if (ret != pdPASS) + { goto FAIL_EXIT; + } ret = LSUserShellTask() ; - if(ret != pdPASS) + if (ret != pdPASS) + { goto FAIL_EXIT; + } - vTaskStartScheduler(); /* 启动任务,开启调度 */ + vTaskStartScheduler(); /* 启动任务,开启调度 */ while (1); /* 正常不会执行到这里 */ - + FAIL_EXIT: - printf("failed 0x%x \r\n", ret); + printf("failed 0x%x. \r\n", ret); return 0; } diff --git a/example/peripheral/adc/sdkconfig b/example/peripheral/adc/sdkconfig index 4e2e0dfe..b3f9414f 100644 --- a/example/peripheral/adc/sdkconfig +++ b/example/peripheral/adc/sdkconfig @@ -74,6 +74,7 @@ CONFIG_USE_FADC=y # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -114,6 +115,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -150,6 +160,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -171,12 +182,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -188,14 +193,32 @@ CONFIG_FREERTOS_USE_ADC=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -213,4 +236,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/adc/sdkconfig.h b/example/peripheral/adc/sdkconfig.h index 5a057cb7..116eb47a 100644 --- a/example/peripheral/adc/sdkconfig.h +++ b/example/peripheral/adc/sdkconfig.h @@ -67,6 +67,7 @@ /* end of ADC Configuration */ /* CONFIG_USE_PWM is not set */ /* CONFIG_USE_IPC is not set */ +/* CONFIG_USE_MEDIA is not set */ /* end of Components Configuration */ #define CONFIG_USE_NEW_LIBC /* end of Standalone Setting */ @@ -103,6 +104,12 @@ /* Compiler Options */ +/* Cross-Compiler Setting */ + +#define CONFIG_GCC_OPTIMIZE_LEVEL 0 +/* CONFIG_USE_EXT_COMPILER is not set */ +/* CONFIG_USE_KLIN_SYS is not set */ +/* end of Cross-Compiler Setting */ #define CONFIG_OUTPUT_BINARY /* end of Compiler Options */ /* end of Building Option */ @@ -132,6 +139,7 @@ /* Freertos Eth Drivers */ /* CONFIG_FREERTOS_USE_XMAC is not set */ +/* CONFIG_FREERTOS_USE_GMAC is not set */ /* end of Freertos Eth Drivers */ /* Freertos Gpio Drivers */ @@ -150,11 +158,6 @@ /* CONFIG_FREERTOS_USE_FGDMA is not set */ /* end of Freertos DMA Drivers */ -/* Freertos MMC Drivers */ - -/* CONFIG_FREERTOS_USE_FSDIO is not set */ -/* end of Freertos MMC Drivers */ - /* Freertos Adc Drivers */ #define CONFIG_FREERTOS_USE_ADC @@ -164,13 +167,28 @@ /* CONFIG_FREERTOS_USE_CAN is not set */ /* end of Freertos Can Drivers */ + +/* Freertos I2c Drivers */ + +/* CONFIG_FREERTOS_USE_I2C is not set */ +/* end of Freertos I2c Drivers */ + +/* Freertos Mio Drivers */ + +/* CONFIG_FREERTOS_USE_MIO is not set */ +/* end of Freertos Mio Drivers */ + +/* Freertos Timer Drivers */ + +/* CONFIG_FREERTOS_USE_TIMER is not set */ +/* end of Freertos Timer Drivers */ /* end of Component Configuration */ -/* FreeRTOS Setting */ +/* Third-Party Configuration */ /* CONFIG_USE_LWIP is not set */ #define CONFIG_USE_BACKTRACE -/* CONFIG_USE_FATFS is not set */ +/* CONFIG_USE_FATFS_0_1_4 is not set */ /* CONFIG_USE_SFUD is not set */ /* CONFIG_USE_SPIFFS is not set */ /* CONFIG_USE_AMP is not set */ @@ -186,6 +204,28 @@ /* CONFIG_USE_TLSF is not set */ /* CONFIG_USE_SDMMC_CMD is not set */ /* CONFIG_USE_CHERRY_USB is not set */ -/* end of FreeRTOS Setting */ +/* end of Third-Party Configuration */ + +/* Kernel Configuration */ + +#define CONFIG_FREERTOS_OPTIMIZED_SCHEDULER +#define CONFIG_FREERTOS_HZ 1000 +#define CONFIG_FREERTOS_MAX_PRIORITIES 32 +#define CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES 13 +#define CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES 11 +#define CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS 1 +#define CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE 1024 +#define CONFIG_FREERTOS_MAX_TASK_NAME_LEN 32 +#define CONFIG_FREERTOS_TIMER_TASK_PRIORITY 1 +#define CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH 2048 +#define CONFIG_FREERTOS_TIMER_QUEUE_LENGTH 10 +#define CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE 0 +#define CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS +#define CONFIG_FREERTOS_USE_TRACE_FACILITY +#define CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS +/* CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set */ +#define CONFIG_FREERTOS_TOTAL_HEAP_SIZE 10240 +#define CONFIG_FREERTOS_TASK_FPU_SUPPORT 1 +/* end of Kernel Configuration */ #endif diff --git a/example/peripheral/adc/src/adc_example.c b/example/peripheral/adc/src/adc_example.c index 6387d65c..0dcfdffd 100644 --- a/example/peripheral/adc/src/adc_example.c +++ b/example/peripheral/adc/src/adc_example.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: adc_example.c * Date: 2022-07-11 11:32:48 * LastEditTime: 2022-07-11 11:32:48 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes + * Description: This file is for ADC task implementations + * + * Modify History: + * Ver Who Date Changes * ----- ------ -------- -------------------------------------- + * 1.0 wangxiaodong 2022/08/31 first commit */ #include #include "FreeRTOSConfig.h" @@ -32,13 +33,13 @@ #include "fassert.h" /* The periods assigned to the one-shot timers. */ -#define ONE_SHOT_TIMER_PERIOD ( pdMS_TO_TICKS( 60000UL )) +#define ONE_SHOT_TIMER_PERIOD ( pdMS_TO_TICKS( 60000UL )) /* adc read period */ -#define ADC_READ_PERIOD ( pdMS_TO_TICKS( 2000UL )) +#define ADC_READ_PERIOD ( pdMS_TO_TICKS( 2000UL )) /* adc channel use, 0/1 */ -#define ADC_CHANNEL_USE FADC_CHANNEL_0 +#define ADC_CHANNEL_USE FADC_CHANNEL_0 /* TESTC board, ADC_VREF = 1.25V */ #define REF_VOL 1.25 @@ -59,9 +60,8 @@ static void FFreeRTOSAdcIntrSet(FFreeRTOSAdc *os_adc_p) { u32 cpu_id; GetCpuId(&cpu_id); - printf("cpu_id is %d \r\n",cpu_id); - FAdcCtrl *instance_p = &os_adc_p->adc_ctrl; + FAdcCtrl *instance_p = &os_adc_p->adc_ctrl; InterruptSetTargetCpus(instance_p->config.irq_num, cpu_id); InterruptSetPriority(instance_p->config.irq_num, instance_p->config.irq_prority); InterruptInstall(instance_p->config.irq_num, FAdcIntrHandler, instance_p, "adc"); @@ -70,196 +70,196 @@ static void FFreeRTOSAdcIntrSet(FFreeRTOSAdc *os_adc_p) static void FFreeRTOSAdcInitTask(void *pvParameters) { - /* The adc_id to use is passed in via the parameter. - Cast this to a adc_id pointer. */ - u32 adc_id = (u32)(uintptr)pvParameters; + /* The adc_id to use is passed in via the parameter. + Cast this to a adc_id pointer. */ + u32 adc_id = (u32)(uintptr)pvParameters; - FError ret = FADC_SUCCESS; + FError ret = FADC_SUCCESS; - /* set channel 0 and 1 iopad*/ + /* set channel 0 and 1 iopad*/ #if defined(CONFIG_TARGET_E2000) FIOPadSetAdcMux(adc_id, ADC_CHANNEL_USE); #endif - /* init adc controller */ - os_adc_ctrl_p = FFreeRTOSAdcInit(adc_id); - if(os_adc_ctrl_p == NULL) - { - printf("FFreeRTOSAdcInit failed!!!\n"); - goto adc_init_exit; - } + /* init adc controller */ + os_adc_ctrl_p = FFreeRTOSAdcInit(adc_id); + if (os_adc_ctrl_p == NULL) + { + printf("FFreeRTOSAdcInit failed!!!\n"); + goto adc_init_exit; + } - /* init adc interrupt handler */ - FFreeRTOSAdcIntrSet(os_adc_ctrl_p); + /* init adc interrupt handler */ + FFreeRTOSAdcIntrSet(os_adc_ctrl_p); - /* adc config */ - FFreeRTOSAdcConfig adc_config; - memset(&adc_config, 0, sizeof(adc_config)); + /* adc config */ + FFreeRTOSAdcConfig adc_config; + memset(&adc_config, 0, sizeof(adc_config)); - adc_config.channel = ADC_CHANNEL_USE; + adc_config.channel = ADC_CHANNEL_USE; - /* adc controller configuration*/ - adc_config.convert_config.convert_mode = FADC_SINGLE_CONVERT; + /* adc controller configuration*/ + adc_config.convert_config.convert_mode = FADC_SINGLE_CONVERT; adc_config.convert_config.channel_mode = FADC_MULTI_CHANNEL; adc_config.convert_config.convert_interval = 10; adc_config.convert_config.clk_div = 8; - /* adc channel threshold configuration*/ - adc_config.threshold_config.high_threshold = 1000; + /* adc channel threshold configuration*/ + adc_config.threshold_config.high_threshold = 1000; adc_config.threshold_config.low_threshold = 0; - /* adc channel interrupt configuration*/ - adc_config.event_type = FADC_INTR_EVENT_COVFIN; + /* adc channel interrupt configuration*/ + adc_config.event_type = FADC_INTR_EVENT_COVFIN; - ret = FFreeRTOSAdcSet(os_adc_ctrl_p, &adc_config); - if (FADC_SUCCESS != ret) - { - printf("FFreeRTOSAdcSet failed\n"); - goto adc_init_exit; - } + ret = FFreeRTOSAdcSet(os_adc_ctrl_p, &adc_config); + if (FADC_SUCCESS != ret) + { + printf("FFreeRTOSAdcSet failed !!!\n"); + goto adc_init_exit; + } - printf("FFreeRTOSAdcInitTask execute success !!!\r\n"); + printf("FFreeRTOSAdcInitTask execute success !!!\r\n"); for (int i = 0; i < TEST_TASK_NUM; i++) { xSemaphoreGive(xCountingSemaphore); } -adc_init_exit: +adc_init_exit: vTaskDelete(NULL); } static void FFreeRTOSAdcReadTask(void *pvParameters) { - xSemaphoreTake(xCountingSemaphore, portMAX_DELAY); - - FError ret = FADC_SUCCESS; - float val = 0.0; - u16 adc_val = 0; - u16 count = 0; - - /* As per most tasks, this task is implemented in an infinite loop. */ - for (;;) - { - ret = FFreeRTOSAdcRead(os_adc_ctrl_p, ADC_CHANNEL_USE, &adc_val); - if(ret == FADC_SUCCESS) + xSemaphoreTake(xCountingSemaphore, portMAX_DELAY); + + FError ret = FADC_SUCCESS; + float val = 0.0; + u16 adc_val = 0; + u16 count = 0; + + /* As per most tasks, this task is implemented in an infinite loop. */ + for (;;) + { + ret = FFreeRTOSAdcRead(os_adc_ctrl_p, ADC_CHANNEL_USE, &adc_val); + if (ret == FADC_SUCCESS) { val = (float)adc_val; val = val * REF_VOL / 1024; /* 2^10 */ - printf("adc read success, count=%d, reg_value=%d, value=%f\n", count, adc_val, val); - } + printf("adc read success, count=%d, reg_value=%d, value=%f.\r\n", count, adc_val, val); + } else { - printf("adc read failed.\n"); + printf("adc read failed.\r\n"); } - count++; - - vTaskDelay(ADC_READ_PERIOD); - } + count++; + + vTaskDelay(ADC_READ_PERIOD); + } } -static void prvOneShotTimerCallback( TimerHandle_t xTimer ) +static void prvOneShotTimerCallback(TimerHandle_t xTimer) { - /* Output a string to show the time at which the callback was executed. */ - printf("One-shot timer callback executing, will delete FFreeRTOSAdcReadTask.\r\n" ); + /* Output a string to show the time at which the callback was executed. */ + printf("One-shot timer callback executing, will delete FFreeRTOSAdcReadTask.\r\n"); - FFreeRTOSAdcDelete(os_adc_ctrl_p); + FFreeRTOSAdcDelete(os_adc_ctrl_p); } /* create adc test, id is adc module number */ BaseType_t FFreeRTOSAdcCreate(u32 id) { - FASSERT(id < FADC_INSTANCE_NUM); + FASSERT(id < FADC_NUM); BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为 pdPASS */ - BaseType_t timer_started = pdPASS; - - xCountingSemaphore = xSemaphoreCreateCounting(TEST_TASK_NUM, 0); - if (xCountingSemaphore == NULL) - { - printf("FFreeRTOSAdcCreate xCountingSemaphore create failed.\r\n" ); - return pdFAIL; - } - /* enter critical region */ - taskENTER_CRITICAL(); - /* adc init task */ - xReturn = xTaskCreate((TaskFunction_t )FFreeRTOSAdcInitTask, /* 任务入口函数 */ - (const char* )"FFreeRTOSAdcInitTask",/* 任务名字 */ - (uint16_t )1024, /* 任务栈大小 */ - (void* )(uintptr)id,/* 任务入口函数参数 */ - (UBaseType_t )1, /* 任务的优先级 */ - NULL); /* 任务控制 */ - - /* 读adc任务 */ - xReturn = xTaskCreate((TaskFunction_t )FFreeRTOSAdcReadTask, /* 任务入口函数 */ - (const char* )"FFreeRTOSAdcReadTask",/* 任务名字 */ - (uint16_t )1024, /* 任务栈大小 */ - NULL,/* 任务入口函数参数 */ - (UBaseType_t )configMAX_PRIORITIES-1, /* 任务的优先级 */ - (TaskHandle_t* )&read_handle); /* 任务控制 */ - - /* Create the one shot software timer, storing the handle to the created - software timer in xOneShotTimer. */ - xOneShotTimer = xTimerCreate( "OneShot Software Timer", /* Text name for the software timer - not used by FreeRTOS. */ - ONE_SHOT_TIMER_PERIOD, /* The software timer's period in ticks. */ - pdFALSE, /* Setting uxAutoRealod to pdFALSE creates a one-shot software timer. */ - 0, /* This example use the timer id. */ - prvOneShotTimerCallback ); /* The callback function to be used by the software timer being created. */ - - /* Check the timers were created. */ - if( xOneShotTimer != NULL ) - { - /* Start the software timers, using a block time of 0 (no block time). - The scheduler has not been started yet so any block time specified here - would be ignored anyway. */ - timer_started = xTimerStart( xOneShotTimer, 0 ); - - /* The implementation of xTimerStart() uses the timer command queue, and - xTimerStart() will fail if the timer command queue gets full. The timer - service task does not get created until the scheduler is started, so all - commands sent to the command queue will stay in the queue until after - the scheduler has been started. Check both calls to xTimerStart() - passed. */ - if(timer_started != pdPASS) - { - vPrintf("CreateSoftwareTimerTasks xTimerStart failed \r\n"); - } - } - else - { - vPrintf("CreateSoftwareTimerTasks xTimerCreate failed \r\n"); - } - - /* exit critical region */ - taskEXIT_CRITICAL(); - + BaseType_t timer_started = pdPASS; + + xCountingSemaphore = xSemaphoreCreateCounting(TEST_TASK_NUM, 0); + if (xCountingSemaphore == NULL) + { + printf("FFreeRTOSAdcCreate xCountingSemaphore create failed.\r\n"); + return pdFAIL; + } + /* enter critical region */ + taskENTER_CRITICAL(); + /* adc init task */ + xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSAdcInitTask, /* 任务入口函数 */ + (const char *)"FFreeRTOSAdcInitTask",/* 任务名字 */ + (uint16_t)1024, /* 任务栈大小 */ + (void *)(uintptr)id,/* 任务入口函数参数 */ + (UBaseType_t)1, /* 任务的优先级 */ + NULL); /* 任务控制 */ + + /* 读adc任务 */ + xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSAdcReadTask, /* 任务入口函数 */ + (const char *)"FFreeRTOSAdcReadTask",/* 任务名字 */ + (uint16_t)1024, /* 任务栈大小 */ + NULL,/* 任务入口函数参数 */ + (UBaseType_t)configMAX_PRIORITIES - 1, /* 任务的优先级 */ + (TaskHandle_t *)&read_handle); /* 任务控制 */ + + /* Create the one shot software timer, storing the handle to the created + software timer in xOneShotTimer. */ + xOneShotTimer = xTimerCreate("OneShot Software Timer", /* Text name for the software timer - not used by FreeRTOS. */ + ONE_SHOT_TIMER_PERIOD, /* The software timer's period in ticks. */ + pdFALSE, /* Setting uxAutoRealod to pdFALSE creates a one-shot software timer. */ + 0, /* This example use the timer id. */ + prvOneShotTimerCallback); /* The callback function to be used by the software timer being created. */ + + /* Check the timers were created. */ + if (xOneShotTimer != NULL) + { + /* Start the software timers, using a block time of 0 (no block time). + The scheduler has not been started yet so any block time specified here + would be ignored anyway. */ + timer_started = xTimerStart(xOneShotTimer, 0); + + /* The implementation of xTimerStart() uses the timer command queue, and + xTimerStart() will fail if the timer command queue gets full. The timer + service task does not get created until the scheduler is started, so all + commands sent to the command queue will stay in the queue until after + the scheduler has been started. Check both calls to xTimerStart() + passed. */ + if (timer_started != pdPASS) + { + vPrintf("CreateSoftwareTimerTasks xTimerStart failed. \r\n"); + } + } + else + { + vPrintf("CreateSoftwareTimerTasks xTimerCreate failed. \r\n"); + } + + /* exit critical region */ + taskEXIT_CRITICAL(); + return xReturn; } static void FFreeRTOSAdcDelete(FFreeRTOSAdc *os_adc_p) { - BaseType_t xReturn = pdPASS; + BaseType_t xReturn = pdPASS; - /* deinit adc controller */ - FFreeRTOSAdcDeinit(os_adc_p); - - if(read_handle) + /* deinit adc controller */ + FFreeRTOSAdcDeinit(os_adc_p); + + if (read_handle) { vTaskDelete(read_handle); - vPrintf("Delete FFreeRTOSAdcReadTask success\r\n"); + vPrintf("Delete FFreeRTOSAdcReadTask success.\r\n"); } - /* delete count sem */ - vSemaphoreDelete(xCountingSemaphore); - - /* delete timer */ - xReturn = xTimerDelete(xOneShotTimer, 0); - if(xReturn != pdPASS) - { - vPrintf("Delete OneShot Software Timer failed.\r\n"); - } - else - { - vPrintf("Delete OneShot Software Timer success.\r\n"); - } + /* delete count sem */ + vSemaphoreDelete(xCountingSemaphore); + + /* delete timer */ + xReturn = xTimerDelete(xOneShotTimer, 0); + if (xReturn != pdPASS) + { + vPrintf("Delete OneShot Software Timer failed.\r\n"); + } + else + { + vPrintf("Delete OneShot Software Timer success.\r\n"); + } } \ No newline at end of file diff --git a/example/peripheral/can/configs/d2000_aarch32_eg_configs b/example/peripheral/can/configs/d2000_aarch32_eg_configs index 21df1565..1924d2d0 100644 --- a/example/peripheral/can/configs/d2000_aarch32_eg_configs +++ b/example/peripheral/can/configs/d2000_aarch32_eg_configs @@ -74,6 +74,7 @@ CONFIG_USE_FCAN=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -118,6 +119,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -154,6 +164,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -175,12 +186,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -192,14 +197,32 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_CAN=y # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -217,4 +240,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/can/configs/d2000_aarch64_eg_configs b/example/peripheral/can/configs/d2000_aarch64_eg_configs index 4f6cc9f8..324b036b 100644 --- a/example/peripheral/can/configs/d2000_aarch64_eg_configs +++ b/example/peripheral/can/configs/d2000_aarch64_eg_configs @@ -74,6 +74,7 @@ CONFIG_USE_FCAN=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -114,6 +115,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -150,6 +160,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -171,12 +182,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -188,14 +193,32 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_CAN=y # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -213,4 +236,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/can/configs/e2000d_aarch32_eg_configs b/example/peripheral/can/configs/e2000d_aarch32_eg_configs index 3cd7acf3..87bbc467 100644 --- a/example/peripheral/can/configs/e2000d_aarch32_eg_configs +++ b/example/peripheral/can/configs/e2000d_aarch32_eg_configs @@ -75,6 +75,7 @@ CONFIG_USE_FCAN=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -119,6 +120,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -155,6 +165,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -176,12 +187,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -193,14 +198,32 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_CAN=y # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -218,4 +241,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/can/configs/e2000d_aarch64_eg_configs b/example/peripheral/can/configs/e2000d_aarch64_eg_configs index 6a693a60..640ce2b4 100644 --- a/example/peripheral/can/configs/e2000d_aarch64_eg_configs +++ b/example/peripheral/can/configs/e2000d_aarch64_eg_configs @@ -75,6 +75,7 @@ CONFIG_USE_FCAN=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -115,6 +116,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -151,6 +161,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -172,12 +183,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -189,14 +194,32 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_CAN=y # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -214,4 +237,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/can/configs/e2000q_aarch32_eg_configs b/example/peripheral/can/configs/e2000q_aarch32_eg_configs index 8594079b..06db6845 100644 --- a/example/peripheral/can/configs/e2000q_aarch32_eg_configs +++ b/example/peripheral/can/configs/e2000q_aarch32_eg_configs @@ -75,6 +75,7 @@ CONFIG_USE_FCAN=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -119,6 +120,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -155,6 +165,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -176,12 +187,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -193,14 +198,32 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_CAN=y # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -218,4 +241,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/can/configs/e2000q_aarch64_eg_configs b/example/peripheral/can/configs/e2000q_aarch64_eg_configs index d4e4e1f6..e9333d80 100644 --- a/example/peripheral/can/configs/e2000q_aarch64_eg_configs +++ b/example/peripheral/can/configs/e2000q_aarch64_eg_configs @@ -75,6 +75,7 @@ CONFIG_USE_FCAN=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -115,6 +116,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -151,6 +161,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -172,12 +183,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -189,14 +194,32 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_CAN=y # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -214,4 +237,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/can/configs/ft2004_aarch32_eg_configs b/example/peripheral/can/configs/ft2004_aarch32_eg_configs index db34ea5b..288cecd8 100644 --- a/example/peripheral/can/configs/ft2004_aarch32_eg_configs +++ b/example/peripheral/can/configs/ft2004_aarch32_eg_configs @@ -74,6 +74,7 @@ CONFIG_USE_FCAN=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -118,6 +119,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -154,6 +164,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -175,12 +186,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -192,14 +197,32 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_CAN=y # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -217,4 +240,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/can/configs/ft2004_aarch64_eg_configs b/example/peripheral/can/configs/ft2004_aarch64_eg_configs index 405c6b73..5ce7b18d 100644 --- a/example/peripheral/can/configs/ft2004_aarch64_eg_configs +++ b/example/peripheral/can/configs/ft2004_aarch64_eg_configs @@ -74,6 +74,7 @@ CONFIG_USE_FCAN=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -114,6 +115,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -150,6 +160,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -171,12 +182,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -188,14 +193,32 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_CAN=y # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -213,4 +236,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/can/inc/can_example.h b/example/peripheral/can/inc/can_example.h index 27231abb..04e1b616 100644 --- a/example/peripheral/can/inc/can_example.h +++ b/example/peripheral/can/inc/can_example.h @@ -1,30 +1,41 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: can_example.h * Date: 2022-08-25 16:22:40 * LastEditTime: 2022-08-26 15:40:40 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for task create function define + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 wangxiaodong 2022/09/23 first commit */ #ifndef CAN_EXAMPLE_H #define CAN_EXAMPLE_H +#ifdef __cplusplus +extern "C" +{ +#endif + /* adc test */ BaseType_t FFreeRTOSCanCreate(void); + +#ifdef __cplusplus +} +#endif + #endif // ! \ No newline at end of file diff --git a/example/peripheral/can/main.c b/example/peripheral/can/main.c index 0cc8fe44..40b4c136 100644 --- a/example/peripheral/can/main.c +++ b/example/peripheral/can/main.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: main.c * Date: 2022-06-17 08:17:59 * LastEditTime: 2022-06-17 08:17:59 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for CAN example that running CAN task、shell task and open scheduler + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 wangxiaodong 2022/09/23 first commit */ #include "shell.h" @@ -32,17 +33,21 @@ int main(void) /* test can 0 and can 1, loopback */ ret = FFreeRTOSCanCreate(); - if(ret != pdPASS) + if (ret != pdPASS) + { goto FAIL_EXIT; + } ret = LSUserShellTask() ; - if(ret != pdPASS) + if (ret != pdPASS) + { goto FAIL_EXIT; + } - vTaskStartScheduler(); /* 启动任务,开启调度 */ + vTaskStartScheduler(); /* 启动任务,开启调度 */ while (1); /* 正常不会执行到这里 */ - + FAIL_EXIT: - printf("failed 0x%x \r\n", ret); + printf("failed 0x%x. \r\n", ret); return 0; } diff --git a/example/peripheral/can/sdkconfig b/example/peripheral/can/sdkconfig index d4e4e1f6..e9333d80 100644 --- a/example/peripheral/can/sdkconfig +++ b/example/peripheral/can/sdkconfig @@ -75,6 +75,7 @@ CONFIG_USE_FCAN=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -115,6 +116,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -151,6 +161,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -172,12 +183,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -189,14 +194,32 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_CAN=y # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -214,4 +237,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/can/sdkconfig.h b/example/peripheral/can/sdkconfig.h index 75a30b3b..1eaaf3cf 100644 --- a/example/peripheral/can/sdkconfig.h +++ b/example/peripheral/can/sdkconfig.h @@ -68,6 +68,7 @@ /* CONFIG_USE_ADC is not set */ /* CONFIG_USE_PWM is not set */ /* CONFIG_USE_IPC is not set */ +/* CONFIG_USE_MEDIA is not set */ /* end of Components Configuration */ #define CONFIG_USE_NEW_LIBC /* end of Standalone Setting */ @@ -104,6 +105,12 @@ /* Compiler Options */ +/* Cross-Compiler Setting */ + +#define CONFIG_GCC_OPTIMIZE_LEVEL 0 +/* CONFIG_USE_EXT_COMPILER is not set */ +/* CONFIG_USE_KLIN_SYS is not set */ +/* end of Cross-Compiler Setting */ #define CONFIG_OUTPUT_BINARY /* end of Compiler Options */ /* end of Building Option */ @@ -133,6 +140,7 @@ /* Freertos Eth Drivers */ /* CONFIG_FREERTOS_USE_XMAC is not set */ +/* CONFIG_FREERTOS_USE_GMAC is not set */ /* end of Freertos Eth Drivers */ /* Freertos Gpio Drivers */ @@ -151,11 +159,6 @@ /* CONFIG_FREERTOS_USE_FGDMA is not set */ /* end of Freertos DMA Drivers */ -/* Freertos MMC Drivers */ - -/* CONFIG_FREERTOS_USE_FSDIO is not set */ -/* end of Freertos MMC Drivers */ - /* Freertos Adc Drivers */ /* CONFIG_FREERTOS_USE_ADC is not set */ @@ -165,13 +168,28 @@ #define CONFIG_FREERTOS_USE_CAN /* end of Freertos Can Drivers */ + +/* Freertos I2c Drivers */ + +/* CONFIG_FREERTOS_USE_I2C is not set */ +/* end of Freertos I2c Drivers */ + +/* Freertos Mio Drivers */ + +/* CONFIG_FREERTOS_USE_MIO is not set */ +/* end of Freertos Mio Drivers */ + +/* Freertos Timer Drivers */ + +/* CONFIG_FREERTOS_USE_TIMER is not set */ +/* end of Freertos Timer Drivers */ /* end of Component Configuration */ -/* FreeRTOS Setting */ +/* Third-Party Configuration */ /* CONFIG_USE_LWIP is not set */ #define CONFIG_USE_BACKTRACE -/* CONFIG_USE_FATFS is not set */ +/* CONFIG_USE_FATFS_0_1_4 is not set */ /* CONFIG_USE_SFUD is not set */ /* CONFIG_USE_SPIFFS is not set */ /* CONFIG_USE_AMP is not set */ @@ -187,6 +205,28 @@ /* CONFIG_USE_TLSF is not set */ /* CONFIG_USE_SDMMC_CMD is not set */ /* CONFIG_USE_CHERRY_USB is not set */ -/* end of FreeRTOS Setting */ +/* end of Third-Party Configuration */ + +/* Kernel Configuration */ + +#define CONFIG_FREERTOS_OPTIMIZED_SCHEDULER +#define CONFIG_FREERTOS_HZ 1000 +#define CONFIG_FREERTOS_MAX_PRIORITIES 32 +#define CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES 13 +#define CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES 11 +#define CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS 1 +#define CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE 1024 +#define CONFIG_FREERTOS_MAX_TASK_NAME_LEN 32 +#define CONFIG_FREERTOS_TIMER_TASK_PRIORITY 1 +#define CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH 2048 +#define CONFIG_FREERTOS_TIMER_QUEUE_LENGTH 10 +#define CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE 0 +#define CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS +#define CONFIG_FREERTOS_USE_TRACE_FACILITY +#define CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS +/* CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set */ +#define CONFIG_FREERTOS_TOTAL_HEAP_SIZE 10240 +#define CONFIG_FREERTOS_TASK_FPU_SUPPORT 1 +/* end of Kernel Configuration */ #endif diff --git a/example/peripheral/can/src/can_example.c b/example/peripheral/can/src/can_example.c index fa2fb3cb..da22ee3a 100644 --- a/example/peripheral/can/src/can_example.c +++ b/example/peripheral/can/src/can_example.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: can_example.c * Date: 2022-07-11 11:32:48 * LastEditTime: 2022-07-11 11:32:48 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes + * Description: This file is for CAN task implementations + * + * Modify History: + * Ver Who Date Changes * ----- ------ -------- -------------------------------------- + * 1.0 wangxiaodong 2022/09/23 first commit */ #include #include @@ -40,19 +41,19 @@ #define FCAN_TEST_ERROR(format, ...) FT_DEBUG_PRINT_E(FCAN_TEST_DEBUG_TAG, format, ##__VA_ARGS__) /* The periods assigned to the one-shot timers. */ -#define ONE_SHOT_TIMER_PERIOD ( pdMS_TO_TICKS( 20000UL )) +#define ONE_SHOT_TIMER_PERIOD ( pdMS_TO_TICKS( 20000UL )) /* can send period */ -#define CAN_SEND_PERIOD ( pdMS_TO_TICKS( 1000UL )) +#define CAN_SEND_PERIOD ( pdMS_TO_TICKS( 1000UL )) /* can baudrate */ #define ARB_BAUD_RATE 1000000 #define DATA_BAUD_RATE 1000000 -typedef struct +typedef struct { - u32 count; - FFreeRTOSCan *os_can_p; + u32 count; + FFreeRTOSCan *os_can_p; } FCanQueueData; /* Declare a variable of type QueueHandle_t. This is used to store the queue @@ -64,10 +65,10 @@ static xTaskHandle recv_handle; static TimerHandle_t xOneShotTimer; -static FFreeRTOSCan *os_can_ctrl_p[FCAN_INSTANCE_NUM]; +static FFreeRTOSCan *os_can_ctrl_p[FCAN_NUM]; -static FCanFrame send_frame[FCAN_INSTANCE_NUM]; -static FCanFrame recv_frame[FCAN_INSTANCE_NUM]; +static FCanFrame send_frame[FCAN_NUM]; +static FCanFrame recv_frame[FCAN_NUM]; static void FFreeRTOSCanSendTask(void *pvParameters); static void FFreeRTOSCanRecvTask(void *pvParameters); @@ -76,230 +77,240 @@ static void FFreeRTOSCanDelete(void); static void FCanTxIrqCallback(void *args) { FFreeRTOSCan *os_can_p = (FFreeRTOSCan *)args; - FCAN_TEST_DEBUG("Can%d irq send frame is ok", os_can_p->can_ctrl.config.instance_id); + FCAN_TEST_DEBUG("Can%d irq send frame is ok.", os_can_p->can_ctrl.config.instance_id); } static void FCanRxIrqCallback(void *args) { - FFreeRTOSCan *os_can_p = (FFreeRTOSCan *)args; - FCAN_TEST_DEBUG("Can%d irq recv frame callback", os_can_p->can_ctrl.config.instance_id); - - static FCanQueueData xSendStructure; - xSendStructure.os_can_p = os_can_p; + FFreeRTOSCan *os_can_p = (FFreeRTOSCan *)args; + FCAN_TEST_DEBUG("Can%d irq recv frame callback.", os_can_p->can_ctrl.config.instance_id); + + static FCanQueueData xSendStructure; + xSendStructure.os_can_p = os_can_p; - portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; + portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; - xQueueSendToBackFromISR(xQueue, &xSendStructure, &xHigherPriorityTaskWoken); + xQueueSendToBackFromISR(xQueue, &xSendStructure, &xHigherPriorityTaskWoken); - /* never call taskYIELD() form ISR! */ - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + /* never call taskYIELD() form ISR! */ + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } static FError FFreeRTOSCanIntrSet(FFreeRTOSCan *os_can_p) { - FError ret = FCAN_SUCCESS; - - FCanIntrEventConfig intr_event; - memset(&intr_event, 0, sizeof(intr_event)); - - intr_event.type = FCAN_INTR_EVENT_SEND; - intr_event.handler = FCanTxIrqCallback; - intr_event.param = (void *)os_can_p; - ret = FFreeRTOSCanControl(os_can_p, FREERTOS_CAN_CTRL_INTR_SET, &intr_event); - if (FCAN_SUCCESS != ret) - { - FCAN_TEST_ERROR("FFreeRTOSCanControl FCAN_INTR_EVENT_SEND failed\n"); - return ret; - } - - intr_event.type = FCAN_INTR_EVENT_RECV; - intr_event.handler = FCanRxIrqCallback; - intr_event.param = (void *)os_can_p; - ret = FFreeRTOSCanControl(os_can_p, FREERTOS_CAN_CTRL_INTR_SET, &intr_event); - if (FCAN_SUCCESS != ret) - { - FCAN_TEST_ERROR("FFreeRTOSCanControl FCAN_INTR_EVENT_RECV failed\n"); - return ret; - } - - u32 cpu_id; + FError ret = FCAN_SUCCESS; + + FCanIntrEventConfig intr_event; + memset(&intr_event, 0, sizeof(intr_event)); + + intr_event.type = FCAN_INTR_EVENT_SEND; + intr_event.handler = FCanTxIrqCallback; + intr_event.param = (void *)os_can_p; + ret = FFreeRTOSCanControl(os_can_p, FREERTOS_CAN_CTRL_INTR_SET, &intr_event); + if (FCAN_SUCCESS != ret) + { + FCAN_TEST_ERROR("FFreeRTOSCanControl FCAN_INTR_EVENT_SEND failed."); + return ret; + } + + intr_event.type = FCAN_INTR_EVENT_RECV; + intr_event.handler = FCanRxIrqCallback; + intr_event.param = (void *)os_can_p; + ret = FFreeRTOSCanControl(os_can_p, FREERTOS_CAN_CTRL_INTR_SET, &intr_event); + if (FCAN_SUCCESS != ret) + { + FCAN_TEST_ERROR("FFreeRTOSCanControl FCAN_INTR_EVENT_RECV failed."); + return ret; + } + + u32 cpu_id; GetCpuId(&cpu_id); - FCanCtrl *instance_p = &os_can_p->can_ctrl; + FCanCtrl *instance_p = &os_can_p->can_ctrl; InterruptSetTargetCpus(instance_p->config.irq_num, cpu_id); InterruptSetPriority(instance_p->config.irq_num, instance_p->config.irq_prority); InterruptInstall(instance_p->config.irq_num, FCanIntrHandler, instance_p, "can"); InterruptUmask(instance_p->config.irq_num); - return ret; + return ret; } static FError FFreeRTOSCanBaudrateSet(FFreeRTOSCan *os_can_p) { - FError ret = FCAN_SUCCESS; - - FCanIntrEventConfig intr_event; - memset(&intr_event, 0, sizeof(intr_event)); - - FCanBaudrateConfig arb_segment_config; - FCanBaudrateConfig data_segment_config; - memset(&arb_segment_config, 0, sizeof(arb_segment_config)); - memset(&data_segment_config, 0, sizeof(data_segment_config)); - arb_segment_config.baudrate = ARB_BAUD_RATE; - arb_segment_config.auto_calc = TRUE; - arb_segment_config.segment = FCAN_ARB_SEGMENT; - - data_segment_config.baudrate = DATA_BAUD_RATE; - data_segment_config.auto_calc = TRUE; - data_segment_config.segment = FCAN_DATA_SEGMENT; - - ret = FFreeRTOSCanControl(os_can_p, FREERTOS_CAN_CTRL_BAUDRATE_SET, &arb_segment_config); - if (FCAN_SUCCESS != ret) - { - FCAN_TEST_ERROR("FFreeRTOSCanControl arb_segment_config failed\n"); - return ret; - } - - ret = FFreeRTOSCanControl(os_can_p, FREERTOS_CAN_CTRL_BAUDRATE_SET, &data_segment_config); - if (FCAN_SUCCESS != ret) - { - FCAN_TEST_ERROR("FFreeRTOSCanControl data_segment_config failed\n"); - return ret; - } - return ret; + FError ret = FCAN_SUCCESS; + + FCanIntrEventConfig intr_event; + memset(&intr_event, 0, sizeof(intr_event)); + + FCanBaudrateConfig arb_segment_config; + FCanBaudrateConfig data_segment_config; + memset(&arb_segment_config, 0, sizeof(arb_segment_config)); + memset(&data_segment_config, 0, sizeof(data_segment_config)); + arb_segment_config.baudrate = ARB_BAUD_RATE; + arb_segment_config.auto_calc = TRUE; + arb_segment_config.segment = FCAN_ARB_SEGMENT; + + data_segment_config.baudrate = DATA_BAUD_RATE; + data_segment_config.auto_calc = TRUE; + data_segment_config.segment = FCAN_DATA_SEGMENT; + + ret = FFreeRTOSCanControl(os_can_p, FREERTOS_CAN_CTRL_BAUDRATE_SET, &arb_segment_config); + if (FCAN_SUCCESS != ret) + { + FCAN_TEST_ERROR("FFreeRTOSCanControl arb_segment_config failed."); + return ret; + } + + ret = FFreeRTOSCanControl(os_can_p, FREERTOS_CAN_CTRL_BAUDRATE_SET, &data_segment_config); + if (FCAN_SUCCESS != ret) + { + FCAN_TEST_ERROR("FFreeRTOSCanControl data_segment_config failed."); + return ret; + } + return ret; } static FError FFreeRTOSCanIdMaskSet(FFreeRTOSCan *os_can_p) { - FError ret = FCAN_SUCCESS; - - FCanIdMaskConfig id_mask; - memset(&id_mask, 0, sizeof(id_mask)); - for (int i = 0; i < FCAN_ACC_ID_REG_NUM; i++) - { - id_mask.filter_index = i; - id_mask.id = 0; - id_mask.mask = FCAN_ACC_IDN_MASK; - ret = FFreeRTOSCanControl(os_can_p, FREERTOS_CAN_CTRL_ID_MASK_SET, &id_mask); - if (FCAN_SUCCESS != ret) - { - FCAN_TEST_ERROR("FFreeRTOSCanControl FREERTOS_CAN_CTRL_ID_MASK_SET %d failed\n", i); - return ret; - } - } - - return ret; + FError ret = FCAN_SUCCESS; + + FCanIdMaskConfig id_mask; + memset(&id_mask, 0, sizeof(id_mask)); + for (int i = 0; i < FCAN_ACC_ID_REG_NUM; i++) + { + id_mask.filter_index = i; + id_mask.id = 0; + id_mask.mask = FCAN_ACC_IDN_MASK; + ret = FFreeRTOSCanControl(os_can_p, FREERTOS_CAN_CTRL_ID_MASK_SET, &id_mask); + if (FCAN_SUCCESS != ret) + { + FCAN_TEST_ERROR("FFreeRTOSCanControl FREERTOS_CAN_CTRL_ID_MASK_SET %d failed.", i); + return ret; + } + } + + return ret; } static void FFreeRTOSCanInitTask(void *pvParameters) { - FError ret = FCAN_SUCCESS; - BaseType_t xReturn = pdPASS; - FCanInstance can_id = FCAN_INSTANCE_0; - - for(can_id = FCAN_INSTANCE_0; can_id < FCAN_INSTANCE_NUM; can_id++) - { - #if defined(CONFIG_TARGET_F2000_4) || defined(CONFIG_TARGET_D2000) - if(can_id == FCAN_INSTANCE_0) - { - FPinSetFunc(FIOCTRL_TJTAG_TDI_PAD, FPIN_FUNC1); /* can0-tx: func 1 */ - FPinSetFunc(FIOCTRL_SWDITMS_SWJ_PAD, FPIN_FUNC1); /* can0-rx: func 1 */ - } - else if(can_id == FCAN_INSTANCE_1) - { - FPinSetFunc(FIOCTRL_NTRST_SWJ_PAD, FPIN_FUNC1); /* can1-tx: func 1 */ - FPinSetFunc(FIOCTRL_SWDO_SWJ_PAD, FPIN_FUNC1); /* can1-rx: func 1 */ - } - else if(can_id == FCAN_INSTANCE_2) - { - - } - else - { - FCAN_TEST_ERROR("can id is error"); - goto can_init_exit; - } - #elif defined(CONFIG_TARGET_E2000) - FIOPadSetCanMux(can_id); - #endif - - /* init can controller */ - os_can_ctrl_p[can_id] = FFreeRTOSCanInit(can_id); - if(os_can_ctrl_p[can_id] == NULL) - { - printf("FFreeRTOSCanInit %d failed!!!\n", can_id); - goto can_init_exit; - } - - /* set can baudrate */ - ret = FFreeRTOSCanBaudrateSet(os_can_ctrl_p[can_id]); - if (FCAN_SUCCESS != ret) - { - printf("FFreeRTOSCanInit FFreeRTOSCanBaudrateSet failed!!!\n"); - goto can_init_exit; - } - - /* set can id mask */ - ret = FFreeRTOSCanIdMaskSet(os_can_ctrl_p[can_id]); - if (FCAN_SUCCESS != ret) - { - printf("FFreeRTOSCanInit FFreeRTOSCanIdMaskSet failed!!!\n"); - goto can_init_exit; - } - - /* Identifier mask enable */ - ret = FFreeRTOSCanControl(os_can_ctrl_p[can_id], FREERTOS_CAN_CTRL_ID_MASK_ENABLE, NULL); - if (FCAN_SUCCESS != ret) - { - FCAN_TEST_ERROR("FFreeRTOSCanControl FREERTOS_CAN_CTRL_ID_MASK_ENABLE failed\n"); - goto can_init_exit; - } - - /* init can interrupt handler */ - ret = FFreeRTOSCanIntrSet(os_can_ctrl_p[can_id]); - if (FCAN_SUCCESS != ret) - { - FCAN_TEST_ERROR("FFreeRTOSCanInit FFreeRTOSCanIntrSet failed!!!\n"); - goto can_init_exit; - } - - /* enable can transfer */ - ret = FFreeRTOSCanControl(os_can_ctrl_p[can_id], FREERTOS_CAN_CTRL_ENABLE, NULL); - if (FCAN_SUCCESS != ret) - { - FCAN_TEST_ERROR("FFreeRTOSCanControl FREERTOS_CAN_CTRL_ENABLE failed\n"); - goto can_init_exit; - } - } - - printf("FFreeRTOSCanInitTask execute success !!!\r\n"); - - /* can send task */ - xReturn = xTaskCreate((TaskFunction_t )FFreeRTOSCanSendTask, /* 任务入口函数 */ - (const char* )"FFreeRTOSCanSendTask",/* 任务名字 */ - (uint16_t )1024, /* 任务栈大小 */ - NULL,/* 任务入口函数参数 */ - (UBaseType_t )configMAX_PRIORITIES-5, /* 任务的优先级 */ - (TaskHandle_t* )&send_handle); /* 任务控制 */ - if(xReturn != pdPASS) - { - printf("Create FFreeRTOSCanSendTask failed.\r\n"); - goto can_init_exit; - } - - /* can recv task */ - xReturn = xTaskCreate((TaskFunction_t )FFreeRTOSCanRecvTask, /* 任务入口函数 */ - (const char* )"FFreeRTOSCanRecvTask",/* 任务名字 */ - (uint16_t )1024, /* 任务栈大小 */ - NULL,/* 任务入口函数参数 */ - (UBaseType_t )configMAX_PRIORITIES-5, /* 任务的优先级 */ - (TaskHandle_t* )&recv_handle); /* 任务控制 */ - if(xReturn != pdPASS) - { - printf("Create FFreeRTOSCanRecvTask failed.\r\n"); - goto can_init_exit; - } + FError ret = FCAN_SUCCESS; + BaseType_t xReturn = pdPASS; + u32 can_id = FCAN0_ID; + u32 tran_mode = FCAN_PROBE_NORMAL_MODE; + + for (can_id = FCAN0_ID; can_id < FCAN_NUM; can_id++) + { +#if defined(CONFIG_TARGET_F2000_4) || defined(CONFIG_TARGET_D2000) + if (can_id == FCAN0_ID) + { + FPinSetFunc(FIOCTRL_TJTAG_TDI_PAD, FPIN_FUNC1); /* can0-tx: func 1 */ + FPinSetFunc(FIOCTRL_SWDITMS_SWJ_PAD, FPIN_FUNC1); /* can0-rx: func 1 */ + } + else if (can_id == FCAN1_ID) + { + FPinSetFunc(FIOCTRL_NTRST_SWJ_PAD, FPIN_FUNC1); /* can1-tx: func 1 */ + FPinSetFunc(FIOCTRL_SWDO_SWJ_PAD, FPIN_FUNC1); /* can1-rx: func 1 */ + } + else if (can_id == FCAN2_ID) + { + + } + else + { + FCAN_TEST_ERROR("can id is error"); + goto can_init_exit; + } +#elif defined(CONFIG_TARGET_E2000) + FIOPadSetCanMux(can_id); +#endif + + /* init can controller */ + os_can_ctrl_p[can_id] = FFreeRTOSCanInit(can_id); + if (os_can_ctrl_p[can_id] == NULL) + { + printf("FFreeRTOSCanInit %d failed!!!\r\n", can_id); + goto can_init_exit; + } + + /* set can baudrate */ + ret = FFreeRTOSCanBaudrateSet(os_can_ctrl_p[can_id]); + if (FCAN_SUCCESS != ret) + { + printf("FFreeRTOSCanInit FFreeRTOSCanBaudrateSet failed!!!\r\n"); + goto can_init_exit; + } + + /* set can id mask */ + ret = FFreeRTOSCanIdMaskSet(os_can_ctrl_p[can_id]); + if (FCAN_SUCCESS != ret) + { + printf("FFreeRTOSCanInit FFreeRTOSCanIdMaskSet failed!!!\r\n"); + goto can_init_exit; + } + + /* Identifier mask enable */ + ret = FFreeRTOSCanControl(os_can_ctrl_p[can_id], FREERTOS_CAN_CTRL_ID_MASK_ENABLE, NULL); + if (FCAN_SUCCESS != ret) + { + FCAN_TEST_ERROR("FFreeRTOSCanControl FREERTOS_CAN_CTRL_ID_MASK_ENABLE failed."); + goto can_init_exit; + } + + /* init can interrupt handler */ + ret = FFreeRTOSCanIntrSet(os_can_ctrl_p[can_id]); + if (FCAN_SUCCESS != ret) + { + FCAN_TEST_ERROR("FFreeRTOSCanInit FFreeRTOSCanIntrSet failed!!!"); + goto can_init_exit; + } + + /* set can transfer mode */ + ret = FFreeRTOSCanControl(os_can_ctrl_p[can_id], FREERTOS_CAN_CTRL_MODE_SET, &tran_mode); + if (FCAN_SUCCESS != ret) + { + FCAN_TEST_ERROR("FFreeRTOSCanControl FREERTOS_CAN_CTRL_MODE_SET failed."); + goto can_init_exit; + } + + /* enable can transfer */ + ret = FFreeRTOSCanControl(os_can_ctrl_p[can_id], FREERTOS_CAN_CTRL_ENABLE, NULL); + if (FCAN_SUCCESS != ret) + { + FCAN_TEST_ERROR("FFreeRTOSCanControl FREERTOS_CAN_CTRL_ENABLE failed."); + goto can_init_exit; + } + + } + + printf("FFreeRTOSCanInitTask execute success !!!\r\n"); + + /* can send task */ + xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSCanSendTask, /* 任务入口函数 */ + (const char *)"FFreeRTOSCanSendTask",/* 任务名字 */ + (uint16_t)1024, /* 任务栈大小 */ + NULL,/* 任务入口函数参数 */ + (UBaseType_t)configMAX_PRIORITIES - 5, /* 任务的优先级 */ + (TaskHandle_t *)&send_handle); /* 任务控制 */ + if (xReturn != pdPASS) + { + printf("Create FFreeRTOSCanSendTask failed.\r\n"); + goto can_init_exit; + } + + /* can recv task */ + xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSCanRecvTask, /* 任务入口函数 */ + (const char *)"FFreeRTOSCanRecvTask",/* 任务名字 */ + (uint16_t)1024, /* 任务栈大小 */ + NULL,/* 任务入口函数参数 */ + (UBaseType_t)configMAX_PRIORITIES - 5, /* 任务的优先级 */ + (TaskHandle_t *)&recv_handle); /* 任务控制 */ + if (xReturn != pdPASS) + { + printf("Create FFreeRTOSCanRecvTask failed.\r\n"); + goto can_init_exit; + } can_init_exit: vTaskDelete(NULL); @@ -307,173 +318,173 @@ can_init_exit: static void FFreeRTOSCanRecvTask(void *pvParameters) { - FError ret = FCAN_SUCCESS; - u8 count[FCAN_INSTANCE_NUM]= {0}; - int i = 0; - static FCanQueueData xReceiveStructure; - FFreeRTOSCan *os_can_p; - u32 instance_id = 0; - /* As per most tasks, this task is implemented in an infinite loop. */ - for (;;) - { - /* wait recv interrupt give semphore */ - xQueueReceive(xQueue, &xReceiveStructure, portMAX_DELAY); - os_can_p = xReceiveStructure.os_can_p; - instance_id = os_can_p->can_ctrl.config.instance_id; - memset(&recv_frame, 0, sizeof(FCanFrame)); - ret = FFreeRTOSCanRecv(os_can_p, &recv_frame[instance_id]); - if (FCAN_SUCCESS == ret) - { - printf("\r\ncan 0 recv id is %#x\r\n", recv_frame[instance_id].canid); - printf("can 0 recv dlc is %d\r\n", recv_frame[instance_id].candlc); - printf("can 0 recv data is "); - for (i = 0; i < recv_frame[instance_id].candlc; i++) - { - printf("%#x ", recv_frame[instance_id].data[i]); - if(recv_frame[instance_id].data[i] != send_frame[FCAN_INSTANCE_1-instance_id].data[i]) - { - FCAN_TEST_ERROR("\ncount=%d: can %d recv is equal to can%d send!!!\r\n", count[instance_id], instance_id, FCAN_INSTANCE_1-instance_id); - } - } - printf("\ncount=%d: can %d recv is equal to can%d send!!!\r\n", count[instance_id], instance_id, FCAN_INSTANCE_1-instance_id); - - count[instance_id]++; - } - - } + FError ret = FCAN_SUCCESS; + u8 count[FCAN_NUM] = {0}; + int i = 0; + static FCanQueueData xReceiveStructure; + FFreeRTOSCan *os_can_p; + u32 instance_id = 0; + /* As per most tasks, this task is implemented in an infinite loop. */ + for (;;) + { + /* wait recv interrupt give semphore */ + xQueueReceive(xQueue, &xReceiveStructure, portMAX_DELAY); + os_can_p = xReceiveStructure.os_can_p; + instance_id = os_can_p->can_ctrl.config.instance_id; + memset(&recv_frame, 0, sizeof(FCanFrame)); + ret = FFreeRTOSCanRecv(os_can_p, &recv_frame[instance_id]); + if (FCAN_SUCCESS == ret) + { + printf("\r\ncan 0 recv id is %#x.\r\n", recv_frame[instance_id].canid); + printf("can 0 recv dlc is %d.\r\n", recv_frame[instance_id].candlc); + printf("can 0 recv data is "); + for (i = 0; i < recv_frame[instance_id].candlc; i++) + { + printf("%#x ", recv_frame[instance_id].data[i]); + if (recv_frame[instance_id].data[i] != send_frame[FCAN1_ID - instance_id].data[i]) + { + FCAN_TEST_ERROR("\ncount=%d: can %d recv is equal to can%d send!!!\r\n", count[instance_id], instance_id, FCAN1_ID - instance_id); + } + } + printf("\ncount=%d: can %d recv is equal to can%d send!!!\r\n", count[instance_id], instance_id, FCAN1_ID - instance_id); + + count[instance_id]++; + } + + } } static void FFreeRTOSCanSendTask(void *pvParameters) { - #define FCAN_SEND_ID 0x23 - #define FCAN_SEND_LENGTH 8 - - FError ret = FCAN_SUCCESS; - FCanInstance can_id = FCAN_INSTANCE_0; - - u8 count[FCAN_INSTANCE_NUM]= {0}; - int i = 0; - - /* As per most tasks, this task is implemented in an infinite loop. */ - for (;;) - { - printf("\r\ncan send task running\r\n"); - for(can_id = FCAN_INSTANCE_0; can_id <= FCAN_INSTANCE_1; can_id++) - { - send_frame[can_id].canid = FCAN_SEND_ID+(can_id<<8); - send_frame[can_id].canid &= CAN_SFF_MASK; - send_frame[can_id].candlc = FCAN_SEND_LENGTH; - for (i = 0; i < send_frame[can_id].candlc; i++) - { - send_frame[can_id].data[i] = i+(can_id<<4); - } - ret = FFreeRTOSCanSend(os_can_ctrl_p[can_id], &send_frame[can_id]); - if(ret != FCAN_SUCCESS) - { - printf("can%d send failed.\n", can_id); - } - count[can_id]++; - } - vTaskDelay(CAN_SEND_PERIOD); - } +#define FCAN_SEND_ID 0x23 +#define FCAN_SEND_LENGTH 8 + + FError ret = FCAN_SUCCESS; + u32 can_id = FCAN0_ID; + + u8 count[FCAN_NUM] = {0}; + int i = 0; + + /* As per most tasks, this task is implemented in an infinite loop. */ + for (;;) + { + printf("\r\ncan send task running.\r\n"); + for (can_id = FCAN0_ID; can_id <= FCAN1_ID; can_id++) + { + send_frame[can_id].canid = FCAN_SEND_ID + (can_id << 8); + send_frame[can_id].canid &= CAN_SFF_MASK; + send_frame[can_id].candlc = FCAN_SEND_LENGTH; + for (i = 0; i < send_frame[can_id].candlc; i++) + { + send_frame[can_id].data[i] = i + (can_id << 4); + } + ret = FFreeRTOSCanSend(os_can_ctrl_p[can_id], &send_frame[can_id]); + if (ret != FCAN_SUCCESS) + { + printf("can%d send failed.\n", can_id); + } + count[can_id]++; + } + vTaskDelay(CAN_SEND_PERIOD); + } } -static void prvOneShotTimerCallback( TimerHandle_t xTimer ) +static void prvOneShotTimerCallback(TimerHandle_t xTimer) { - /* Output a string to show the time at which the callback was executed. */ - printf("One-shot timer callback executing, will delete FFreeRTOSCanReadTask.\r\n" ); + /* Output a string to show the time at which the callback was executed. */ + printf("One-shot timer callback executing, will delete FFreeRTOSCanReadTask.\r\n"); - FFreeRTOSCanDelete(); + FFreeRTOSCanDelete(); } /* create can test, can0 and can1 loopback */ BaseType_t FFreeRTOSCanCreate(void) { BaseType_t xReturn = pdPASS; - BaseType_t timer_started = pdPASS; - - /* The queue is created to hold a maximum of 32 structures of type xData. */ - xQueue = xQueueCreate(32, sizeof(FCanQueueData)); - if (xQueue == NULL) - { - printf("FFreeRTOSCanCreate FCanQueueData create failed.\r\n" ); - return pdFAIL; - } - - /* can init task */ - xReturn = xTaskCreate((TaskFunction_t )FFreeRTOSCanInitTask, /* 任务入口函数 */ - (const char* )"FFreeRTOSCanInitTask",/* 任务名字 */ - (uint16_t )1024, /* 任务栈大小 */ - NULL,/* 任务入口函数参数 */ - (UBaseType_t )1, /* 任务的优先级 */ - NULL); /* 任务控制 */ - - /* Create the one shot software timer, storing the handle to the created - software timer in xOneShotTimer. */ - xOneShotTimer = xTimerCreate( "OneShot Software Timer", /* Text name for the software timer - not used by FreeRTOS. */ - ONE_SHOT_TIMER_PERIOD, /* The software timer's period in ticks. */ - pdFALSE, /* Setting uxAutoRealod to pdFALSE creates a one-shot software timer. */ - 0, /* This example use the timer id. */ - prvOneShotTimerCallback ); /* The callback function to be used by the software timer being created. */ - - /* Check the timers were created. */ - if( xOneShotTimer != NULL ) - { - /* Start the software timers, using a block time of 0 (no block time). - The scheduler has not been started yet so any block time specified here - would be ignored anyway. */ - timer_started = xTimerStart( xOneShotTimer, 0 ); - - /* The implementation of xTimerStart() uses the timer command queue, and - xTimerStart() will fail if the timer command queue gets full. The timer - service task does not get created until the scheduler is started, so all - commands sent to the command queue will stay in the queue until after - the scheduler has been started. Check both calls to xTimerStart() - passed. */ - if(timer_started != pdPASS) - { - vPrintf("CreateSoftwareTimerTasks xTimerStart failed \r\n"); - } - } - else - { - vPrintf("CreateSoftwareTimerTasks xTimerCreate failed \r\n"); - } - + BaseType_t timer_started = pdPASS; + + /* The queue is created to hold a maximum of 32 structures of type xData. */ + xQueue = xQueueCreate(32, sizeof(FCanQueueData)); + if (xQueue == NULL) + { + printf("FFreeRTOSCanCreate FCanQueueData create failed.\r\n"); + return pdFAIL; + } + + /* can init task */ + xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSCanInitTask, /* 任务入口函数 */ + (const char *)"FFreeRTOSCanInitTask",/* 任务名字 */ + (uint16_t)1024, /* 任务栈大小 */ + NULL,/* 任务入口函数参数 */ + (UBaseType_t)1, /* 任务的优先级 */ + NULL); /* 任务控制 */ + + /* Create the one shot software timer, storing the handle to the created + software timer in xOneShotTimer. */ + xOneShotTimer = xTimerCreate("OneShot Software Timer", /* Text name for the software timer - not used by FreeRTOS. */ + ONE_SHOT_TIMER_PERIOD, /* The software timer's period in ticks. */ + pdFALSE, /* Setting uxAutoRealod to pdFALSE creates a one-shot software timer. */ + 0, /* This example use the timer id. */ + prvOneShotTimerCallback); /* The callback function to be used by the software timer being created. */ + + /* Check the timers were created. */ + if (xOneShotTimer != NULL) + { + /* Start the software timers, using a block time of 0 (no block time). + The scheduler has not been started yet so any block time specified here + would be ignored anyway. */ + timer_started = xTimerStart(xOneShotTimer, 0); + + /* The implementation of xTimerStart() uses the timer command queue, and + xTimerStart() will fail if the timer command queue gets full. The timer + service task does not get created until the scheduler is started, so all + commands sent to the command queue will stay in the queue until after + the scheduler has been started. Check both calls to xTimerStart() + passed. */ + if (timer_started != pdPASS) + { + vPrintf("CreateSoftwareTimerTasks xTimerStart failed. \r\n"); + } + } + else + { + vPrintf("CreateSoftwareTimerTasks xTimerCreate failed. \r\n"); + } + return xReturn; } static void FFreeRTOSCanDelete(void) { - BaseType_t xReturn = pdPASS; + BaseType_t xReturn = pdPASS; - if(send_handle) + if (send_handle) { vTaskDelete(send_handle); - vPrintf("Delete FFreeRTOSCanSendTask success\r\n"); + vPrintf("Delete FFreeRTOSCanSendTask success.\r\n"); } - if(recv_handle) + if (recv_handle) { vTaskDelete(recv_handle); - vPrintf("Delete FFreeRTOSCanRecvTask success\r\n"); + vPrintf("Delete FFreeRTOSCanRecvTask success.\r\n"); } - /* deinit can os instance */ - FFreeRTOSCanDeinit(os_can_ctrl_p[FCAN_INSTANCE_0]); - FFreeRTOSCanDeinit(os_can_ctrl_p[FCAN_INSTANCE_1]); - - /* delete queue */ - vQueueDelete(xQueue); - - /* delete timer */ - xReturn = xTimerDelete(xOneShotTimer, 0); - if(xReturn != pdPASS) - { - vPrintf("Delete OneShot Software Timer failed.\r\n"); - } - else - { - vPrintf("Delete OneShot Software Timer success.\r\n"); - } + /* deinit can os instance */ + FFreeRTOSCanDeinit(os_can_ctrl_p[FCAN0_ID]); + FFreeRTOSCanDeinit(os_can_ctrl_p[FCAN1_ID]); + + /* delete queue */ + vQueueDelete(xQueue); + + /* delete timer */ + xReturn = xTimerDelete(xOneShotTimer, 0); + if (xReturn != pdPASS) + { + vPrintf("Delete OneShot Software Timer failed.\r\n"); + } + else + { + vPrintf("Delete OneShot Software Timer success.\r\n"); + } } \ No newline at end of file diff --git a/example/peripheral/dma/ddma/configs/e2000d_aarch32_eg_configs b/example/peripheral/dma/ddma/configs/e2000d_aarch32_eg_configs index ba85580b..1f03d3d1 100644 --- a/example/peripheral/dma/ddma/configs/e2000d_aarch32_eg_configs +++ b/example/peripheral/dma/ddma/configs/e2000d_aarch32_eg_configs @@ -70,6 +70,7 @@ CONFIG_ENABLE_FDDMA=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -114,6 +115,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -150,6 +160,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -171,12 +182,6 @@ CONFIG_FREERTOS_USE_FDDMA=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -188,14 +193,32 @@ CONFIG_FREERTOS_USE_FDDMA=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -213,4 +236,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/dma/ddma/configs/e2000d_aarch64_eg_configs b/example/peripheral/dma/ddma/configs/e2000d_aarch64_eg_configs index 0857033f..7975b415 100644 --- a/example/peripheral/dma/ddma/configs/e2000d_aarch64_eg_configs +++ b/example/peripheral/dma/ddma/configs/e2000d_aarch64_eg_configs @@ -70,6 +70,7 @@ CONFIG_ENABLE_FDDMA=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -110,6 +111,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -146,6 +156,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -167,12 +178,6 @@ CONFIG_FREERTOS_USE_FDDMA=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -184,14 +189,32 @@ CONFIG_FREERTOS_USE_FDDMA=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -209,4 +232,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/dma/ddma/configs/e2000q_aarch32_eg_configs b/example/peripheral/dma/ddma/configs/e2000q_aarch32_eg_configs index dfdb709f..0551ca56 100644 --- a/example/peripheral/dma/ddma/configs/e2000q_aarch32_eg_configs +++ b/example/peripheral/dma/ddma/configs/e2000q_aarch32_eg_configs @@ -70,6 +70,7 @@ CONFIG_ENABLE_FDDMA=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -114,6 +115,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -150,6 +160,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -171,12 +182,6 @@ CONFIG_FREERTOS_USE_FDDMA=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -188,14 +193,32 @@ CONFIG_FREERTOS_USE_FDDMA=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -213,4 +236,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/dma/ddma/configs/e2000q_aarch64_eg_configs b/example/peripheral/dma/ddma/configs/e2000q_aarch64_eg_configs index dc348827..6caceb1c 100644 --- a/example/peripheral/dma/ddma/configs/e2000q_aarch64_eg_configs +++ b/example/peripheral/dma/ddma/configs/e2000q_aarch64_eg_configs @@ -70,6 +70,7 @@ CONFIG_ENABLE_FDDMA=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -110,6 +111,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -146,6 +156,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -167,12 +178,6 @@ CONFIG_FREERTOS_USE_FDDMA=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -184,14 +189,32 @@ CONFIG_FREERTOS_USE_FDDMA=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -209,4 +232,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/dma/ddma/inc/ddma_spi_loopback.h b/example/peripheral/dma/ddma/inc/ddma_spi_loopback.h index 64a4e5d5..5b89d370 100644 --- a/example/peripheral/dma/ddma/inc/ddma_spi_loopback.h +++ b/example/peripheral/dma/ddma/inc/ddma_spi_loopback.h @@ -1,27 +1,28 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: ddma_spi_loopback.h * Date: 2022-07-18 11:01:37 * LastEditTime: 2022-07-18 11:01:37 - * Description:  This files is for - * - * Modify History: - * Ver   Who        Date         Changes + * Description:  This file is for task create function define + * + * Modify History: + * Ver   Who       Date        Changes * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2022/08/26 first commit */ -#ifndef EXAMPLE_DDMA_SPI_LOOPBACK_H -#define EXAMPLE_DDMA_SPI_LOOPBACK_H +#ifndef DDMA_SPI_LOOPBACK_H +#define DDMA_SPI_LOOPBACK_H #ifdef __cplusplus extern "C" diff --git a/example/peripheral/dma/ddma/main.c b/example/peripheral/dma/ddma/main.c index f97dc17a..c2c2cf2d 100644 --- a/example/peripheral/dma/ddma/main.c +++ b/example/peripheral/dma/ddma/main.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: main.c * Date: 2022-06-17 08:17:59 * LastEditTime: 2022-06-17 08:17:59 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for ddma example that running shell task and open scheduler + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 zhugengyu 2022/08/26 first commit */ #include "shell.h" @@ -30,15 +31,17 @@ int main(void) BaseType_t ret; ret = LSUserShellTask() ; - if(ret != pdPASS) + if (ret != pdPASS) + { goto FAIL_EXIT; + } /* ret = FFreeRTOSRunDDMASpiLoopback(2U, 32U); */ - vTaskStartScheduler(); /* 启动任务,开启调度 */ + vTaskStartScheduler(); /* 启动任务,开启调度 */ while (1); /* 正常不会执行到这里 */ - + FAIL_EXIT: - printf("failed 0x%x \r\n", ret); + printf("failed 0x%x \r\n", ret); return 0; } diff --git a/example/peripheral/dma/ddma/sdkconfig b/example/peripheral/dma/ddma/sdkconfig index 0857033f..6caceb1c 100644 --- a/example/peripheral/dma/ddma/sdkconfig +++ b/example/peripheral/dma/ddma/sdkconfig @@ -2,7 +2,7 @@ # # Freertos Configuration # -CONFIG_TARGET_NAME="e2000d_freertos_a64" +CONFIG_TARGET_NAME="e2000q_freertos_a64" # end of Freertos Configuration # @@ -26,8 +26,8 @@ CONFIG_USE_SYS_TICK=y # # CONFIG_TARGET_F2000_4 is not set # CONFIG_TARGET_D2000 is not set -# CONFIG_TARGET_E2000Q is not set -CONFIG_TARGET_E2000D=y +CONFIG_TARGET_E2000Q=y +# CONFIG_TARGET_E2000D is not set # CONFIG_TARGET_E2000S is not set CONFIG_TARGET_E2000=y CONFIG_DEFAULT_DEBUG_PRINT_UART1=y @@ -70,6 +70,7 @@ CONFIG_ENABLE_FDDMA=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -110,6 +111,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -146,6 +156,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -167,12 +178,6 @@ CONFIG_FREERTOS_USE_FDDMA=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -184,14 +189,32 @@ CONFIG_FREERTOS_USE_FDDMA=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -209,4 +232,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/dma/ddma/sdkconfig.h b/example/peripheral/dma/ddma/sdkconfig.h index e392df88..9aa43168 100644 --- a/example/peripheral/dma/ddma/sdkconfig.h +++ b/example/peripheral/dma/ddma/sdkconfig.h @@ -3,7 +3,7 @@ /* Freertos Configuration */ -#define CONFIG_TARGET_NAME "e2000d_freertos_a64" +#define CONFIG_TARGET_NAME "e2000q_freertos_a64" /* end of Freertos Configuration */ /* Standalone Setting */ @@ -24,8 +24,8 @@ /* CONFIG_TARGET_F2000_4 is not set */ /* CONFIG_TARGET_D2000 is not set */ -/* CONFIG_TARGET_E2000Q is not set */ -#define CONFIG_TARGET_E2000D +#define CONFIG_TARGET_E2000Q +/* CONFIG_TARGET_E2000D is not set */ /* CONFIG_TARGET_E2000S is not set */ #define CONFIG_TARGET_E2000 #define CONFIG_DEFAULT_DEBUG_PRINT_UART1 @@ -65,6 +65,7 @@ /* CONFIG_USE_ADC is not set */ /* CONFIG_USE_PWM is not set */ /* CONFIG_USE_IPC is not set */ +/* CONFIG_USE_MEDIA is not set */ /* end of Components Configuration */ #define CONFIG_USE_NEW_LIBC /* end of Standalone Setting */ @@ -101,6 +102,12 @@ /* Compiler Options */ +/* Cross-Compiler Setting */ + +#define CONFIG_GCC_OPTIMIZE_LEVEL 0 +/* CONFIG_USE_EXT_COMPILER is not set */ +/* CONFIG_USE_KLIN_SYS is not set */ +/* end of Cross-Compiler Setting */ #define CONFIG_OUTPUT_BINARY /* end of Compiler Options */ /* end of Building Option */ @@ -130,6 +137,7 @@ /* Freertos Eth Drivers */ /* CONFIG_FREERTOS_USE_XMAC is not set */ +/* CONFIG_FREERTOS_USE_GMAC is not set */ /* end of Freertos Eth Drivers */ /* Freertos Gpio Drivers */ @@ -148,11 +156,6 @@ /* CONFIG_FREERTOS_USE_FGDMA is not set */ /* end of Freertos DMA Drivers */ -/* Freertos MMC Drivers */ - -/* CONFIG_FREERTOS_USE_FSDIO is not set */ -/* end of Freertos MMC Drivers */ - /* Freertos Adc Drivers */ /* CONFIG_FREERTOS_USE_ADC is not set */ @@ -162,13 +165,28 @@ /* CONFIG_FREERTOS_USE_CAN is not set */ /* end of Freertos Can Drivers */ + +/* Freertos I2c Drivers */ + +/* CONFIG_FREERTOS_USE_I2C is not set */ +/* end of Freertos I2c Drivers */ + +/* Freertos Mio Drivers */ + +/* CONFIG_FREERTOS_USE_MIO is not set */ +/* end of Freertos Mio Drivers */ + +/* Freertos Timer Drivers */ + +/* CONFIG_FREERTOS_USE_TIMER is not set */ +/* end of Freertos Timer Drivers */ /* end of Component Configuration */ -/* FreeRTOS Setting */ +/* Third-Party Configuration */ /* CONFIG_USE_LWIP is not set */ #define CONFIG_USE_BACKTRACE -/* CONFIG_USE_FATFS is not set */ +/* CONFIG_USE_FATFS_0_1_4 is not set */ /* CONFIG_USE_SFUD is not set */ /* CONFIG_USE_SPIFFS is not set */ /* CONFIG_USE_AMP is not set */ @@ -184,6 +202,28 @@ #define CONFIG_USE_TLSF /* CONFIG_USE_SDMMC_CMD is not set */ /* CONFIG_USE_CHERRY_USB is not set */ -/* end of FreeRTOS Setting */ +/* end of Third-Party Configuration */ + +/* Kernel Configuration */ + +#define CONFIG_FREERTOS_OPTIMIZED_SCHEDULER +#define CONFIG_FREERTOS_HZ 1000 +#define CONFIG_FREERTOS_MAX_PRIORITIES 32 +#define CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES 13 +#define CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES 11 +#define CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS 1 +#define CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE 1024 +#define CONFIG_FREERTOS_MAX_TASK_NAME_LEN 32 +#define CONFIG_FREERTOS_TIMER_TASK_PRIORITY 1 +#define CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH 2048 +#define CONFIG_FREERTOS_TIMER_QUEUE_LENGTH 10 +#define CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE 0 +#define CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS +#define CONFIG_FREERTOS_USE_TRACE_FACILITY +#define CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS +/* CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set */ +#define CONFIG_FREERTOS_TOTAL_HEAP_SIZE 10240 +#define CONFIG_FREERTOS_TASK_FPU_SUPPORT 1 +/* end of Kernel Configuration */ #endif diff --git a/example/peripheral/dma/ddma/src/cmd_ddma.c b/example/peripheral/dma/ddma/src/cmd_ddma.c index d844e329..99eac603 100644 --- a/example/peripheral/dma/ddma/src/cmd_ddma.c +++ b/example/peripheral/dma/ddma/src/cmd_ddma.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: cmd_ddma.c * Date: 2022-07-14 14:06:43 * LastEditTime: 2022-07-14 14:06:43 - * Description:  This files is for - * - * Modify History: + * Description:  This file is for ddma command interface + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2022/08/26 first commit */ /***************************** Include Files *********************************/ #include diff --git a/example/peripheral/dma/ddma/src/ddma_spi_loopback.c b/example/peripheral/dma/ddma/src/ddma_spi_loopback.c index a3612171..6e6e2258 100644 --- a/example/peripheral/dma/ddma/src/ddma_spi_loopback.c +++ b/example/peripheral/dma/ddma/src/ddma_spi_loopback.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: ddma_spi_loopback.c * Date: 2022-07-20 09:24:39 * LastEditTime: 2022-07-20 09:24:39 - * Description:  This files is for - * - * Modify History: + * Description:  This file is for DDMA task implementations + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2022/08/26 first commit */ /***************************** Include Files *********************************/ #include @@ -76,7 +77,7 @@ static TimerHandle_t exit_timer = NULL; static u32 loopback_times = 3U; static boolean is_running = FALSE; -static const u32 spim_rx_slave_id[FSPI_DEVICE_NUM] = +static const u32 spim_rx_slave_id[FSPI_NUM] = { [FSPI0_ID] = FDDMA0_SPIM0_RX_SLAVE_ID, [FSPI1_ID] = FDDMA0_SPIM1_RX_SLAVE_ID, @@ -84,7 +85,7 @@ static const u32 spim_rx_slave_id[FSPI_DEVICE_NUM] = [FSPI3_ID] = FDDMA0_SPIM3_RX_SLAVE_ID }; -static const u32 spim_tx_slave_id[FSPI_DEVICE_NUM] = +static const u32 spim_tx_slave_id[FSPI_NUM] = { [FSPI0_ID] = FDDMA0_SPIM0_TX_SLAVE_ID, [FSPI1_ID] = FDDMA0_SPIM1_TX_SLAVE_ID, @@ -104,7 +105,7 @@ static const u32 spim_tx_slave_id[FSPI_DEVICE_NUM] = static void DdmaSpiLoopbackExitCallback(TimerHandle_t timer) { FError err = FT_SUCCESS; - printf("exiting....."); + printf("exiting.....\r\n"); if (send_task) /* stop and delete send task */ { @@ -168,8 +169,8 @@ static void DdmaSpiLoopbackAckDMADone(FDdmaChan *const dma_chan, void *arg) BaseType_t xhigher_priority_task_woken = pdFALSE; BaseType_t x_result = pdFALSE; - FDDMA_INFO("ack chan-%d %s done for ddma", dma_chan->config.id, - (dma_chan->config.id == rx_chan_id) ? "rx" : "tx"); + FDDMA_INFO("ack chan-%d %s done for ddma.", dma_chan->config.id, + (dma_chan->config.id == rx_chan_id) ? "rx" : "tx"); FASSERT_MSG(chan_evt, "rx event group not exists !!!"); x_result = xEventGroupSetBitsFromISR(chan_evt, CHAN_REQ_DONE(dma_chan->config.id), @@ -186,8 +187,8 @@ static boolean DdmaSpiLoopbackWaitDmaEnd(void) u32 wait_bits = CHAN_REQ_DONE(rx_chan_id) | CHAN_REQ_DONE(tx_chan_id); ev = xEventGroupWaitBits(chan_evt, - wait_bits, - pdTRUE, pdTRUE, wait_delay); + wait_bits, + pdTRUE, pdTRUE, wait_delay); if ((ev & wait_bits) == wait_bits) { FDDMA_INFO("ddma transfer success !!!"); @@ -252,7 +253,7 @@ static void DdmaInitTask(void *args) FASSERT_MSG(spim, "init spim failed"); ddma = FFreeRTOSDdmaInit(ddma_id, &ddma_config); /* deinit ddma */ - FASSERT_MSG(ddma, "init ddma failed"); + FASSERT_MSG(ddma, "init ddma failed"); spi_base = spim->ctrl.config.base_addr; @@ -278,7 +279,7 @@ static void DdmaInitTask(void *args) DdmaSpiLoopbackGiveSync(); /* give sync and allow sending */ - vTaskDelete(NULL); + vTaskDelete(NULL); } static void DdmaSpiLoopbackSendTask(void *args) @@ -315,7 +316,7 @@ static void DdmaSpiLoopbackSendTask(void *args) spi_msg.tx_buf = tx_buf; spi_msg.tx_len = trans_len; - if ((FFREERTOS_DDMA_OK != FFreeRTOSDdmaStartChannel(ddma, rx_chan_id)) || + if ((FFREERTOS_DDMA_OK != FFreeRTOSDdmaStartChannel(ddma, rx_chan_id)) || (FFREERTOS_DDMA_OK != FFreeRTOSDdmaStartChannel(ddma, tx_chan_id))) { FDDMA_ERROR("start dma failed !!!"); @@ -332,7 +333,9 @@ static void DdmaSpiLoopbackSendTask(void *args) } if (times++ > loopback_times) + { break; + } vTaskDelay(wait_delay); } @@ -350,7 +353,7 @@ static void DdmaSpiLoopbackRecvTask(void *args) for (;;) { FDDMA_INFO("waiting recv data..."); - + /* block recv task until rx done */ if (!DdmaSpiLoopbackWaitDmaEnd()) { @@ -383,7 +386,9 @@ static void DdmaSpiLoopbackRecvTask(void *args) } if (times++ > loopback_times) + { break; + } DdmaSpiLoopbackGiveSync(); /* recv finished, give send sync and allow sending */ } @@ -397,7 +402,7 @@ BaseType_t FFreeRTOSRunDDMASpiLoopback(u32 spi_id, u32 bytes) { BaseType_t ret = pdPASS; const TickType_t total_run_time = pdMS_TO_TICKS(30000UL); /* loopback run for 10 secs deadline */ - + if (is_running) { FDDMA_ERROR("task is running !!!!"); @@ -416,38 +421,38 @@ BaseType_t FFreeRTOSRunDDMASpiLoopback(u32 spi_id, u32 bytes) taskENTER_CRITICAL(); /* no schedule when create task */ - ret = xTaskCreate((TaskFunction_t )DdmaInitTask, /* task entry */ - (const char* )"DdmaInitTask",/* task name */ - (uint16_t )4096, /* task stack size in words */ - NULL, /* task params */ - (UBaseType_t )configMAX_PRIORITIES - 1, /* task priority */ - NULL); /* task handler */ + ret = xTaskCreate((TaskFunction_t)DdmaInitTask, /* task entry */ + (const char *)"DdmaInitTask",/* task name */ + (uint16_t)4096, /* task stack size in words */ + NULL, /* task params */ + (UBaseType_t)configMAX_PRIORITIES - 1, /* task priority */ + NULL); /* task handler */ FASSERT_MSG(pdPASS == ret, "create task failed"); - ret = xTaskCreate((TaskFunction_t )DdmaSpiLoopbackSendTask, /* task entry */ - (const char* )"DdmaSpiLoopbackSendTask",/* task name */ - (uint16_t )4096, /* task stack size in words */ - NULL, /* task params */ - (UBaseType_t )configMAX_PRIORITIES - 2, /* task priority */ - (TaskHandle_t* )&send_task); /* task handler */ + ret = xTaskCreate((TaskFunction_t)DdmaSpiLoopbackSendTask, /* task entry */ + (const char *)"DdmaSpiLoopbackSendTask",/* task name */ + (uint16_t)4096, /* task stack size in words */ + NULL, /* task params */ + (UBaseType_t)configMAX_PRIORITIES - 2, /* task priority */ + (TaskHandle_t *)&send_task); /* task handler */ FASSERT_MSG(pdPASS == ret, "create task failed"); - ret = xTaskCreate((TaskFunction_t )DdmaSpiLoopbackRecvTask, /* task entry */ - (const char* )"DdmaSpiLoopbackRecvTask",/* task name */ - (uint16_t )4096, /* task stack size in words */ - NULL, /* task params */ - (UBaseType_t )configMAX_PRIORITIES - 1, /* task priority */ - (TaskHandle_t* )&recv_task); /* task handler */ + ret = xTaskCreate((TaskFunction_t)DdmaSpiLoopbackRecvTask, /* task entry */ + (const char *)"DdmaSpiLoopbackRecvTask",/* task name */ + (uint16_t)4096, /* task stack size in words */ + NULL, /* task params */ + (UBaseType_t)configMAX_PRIORITIES - 1, /* task priority */ + (TaskHandle_t *)&recv_task); /* task handler */ FASSERT_MSG(pdPASS == ret, "create task failed"); - exit_timer = xTimerCreate("Exit-Timer", /* Text name for the software timer - not used by FreeRTOS. */ - total_run_time, /* The software timer's period in ticks. */ - pdFALSE, /* Setting uxAutoRealod to pdFALSE creates a one-shot software timer. */ - NULL, /* use timer id to pass task data for reference. */ - DdmaSpiLoopbackExitCallback); /* The callback function to be used by the software timer being created. */ + exit_timer = xTimerCreate("Exit-Timer", /* Text name for the software timer - not used by FreeRTOS. */ + total_run_time, /* The software timer's period in ticks. */ + pdFALSE, /* Setting uxAutoRealod to pdFALSE creates a one-shot software timer. */ + NULL, /* use timer id to pass task data for reference. */ + DdmaSpiLoopbackExitCallback); /* The callback function to be used by the software timer being created. */ FASSERT_MSG(NULL != exit_timer, "create exit timer failed"); diff --git a/example/peripheral/dma/gdma/configs/e2000d_aarch32_eg_configs b/example/peripheral/dma/gdma/configs/e2000d_aarch32_eg_configs index 1ecbf2fd..95001d31 100644 --- a/example/peripheral/dma/gdma/configs/e2000d_aarch32_eg_configs +++ b/example/peripheral/dma/gdma/configs/e2000d_aarch32_eg_configs @@ -69,6 +69,7 @@ CONFIG_ENABLE_FGDMA=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -113,6 +114,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -149,6 +159,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -170,12 +181,6 @@ CONFIG_FREERTOS_USE_UART=y CONFIG_FREERTOS_USE_FGDMA=y # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -187,14 +192,32 @@ CONFIG_FREERTOS_USE_FGDMA=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -212,4 +235,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/dma/gdma/configs/e2000d_aarch64_eg_configs b/example/peripheral/dma/gdma/configs/e2000d_aarch64_eg_configs index 1486603c..a096cae7 100644 --- a/example/peripheral/dma/gdma/configs/e2000d_aarch64_eg_configs +++ b/example/peripheral/dma/gdma/configs/e2000d_aarch64_eg_configs @@ -69,6 +69,7 @@ CONFIG_ENABLE_FGDMA=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -109,6 +110,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -145,6 +155,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -166,12 +177,6 @@ CONFIG_FREERTOS_USE_UART=y CONFIG_FREERTOS_USE_FGDMA=y # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -183,14 +188,32 @@ CONFIG_FREERTOS_USE_FGDMA=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -208,4 +231,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/dma/gdma/configs/e2000q_aarch32_eg_configs b/example/peripheral/dma/gdma/configs/e2000q_aarch32_eg_configs index 1e0eacf0..a78c5824 100644 --- a/example/peripheral/dma/gdma/configs/e2000q_aarch32_eg_configs +++ b/example/peripheral/dma/gdma/configs/e2000q_aarch32_eg_configs @@ -69,6 +69,7 @@ CONFIG_ENABLE_FGDMA=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -113,6 +114,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -149,6 +159,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -170,12 +181,6 @@ CONFIG_FREERTOS_USE_UART=y CONFIG_FREERTOS_USE_FGDMA=y # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -187,14 +192,32 @@ CONFIG_FREERTOS_USE_FGDMA=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -212,4 +235,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/dma/gdma/configs/e2000q_aarch64_eg_configs b/example/peripheral/dma/gdma/configs/e2000q_aarch64_eg_configs index dd163314..f253199b 100644 --- a/example/peripheral/dma/gdma/configs/e2000q_aarch64_eg_configs +++ b/example/peripheral/dma/gdma/configs/e2000q_aarch64_eg_configs @@ -69,6 +69,7 @@ CONFIG_ENABLE_FGDMA=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -109,6 +110,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -145,6 +155,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -166,12 +177,6 @@ CONFIG_FREERTOS_USE_UART=y CONFIG_FREERTOS_USE_FGDMA=y # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -183,14 +188,32 @@ CONFIG_FREERTOS_USE_FGDMA=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -208,4 +231,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/dma/gdma/inc/gdma_memcpy.h b/example/peripheral/dma/gdma/inc/gdma_memcpy.h index 7acbc277..90ffb99e 100644 --- a/example/peripheral/dma/gdma/inc/gdma_memcpy.h +++ b/example/peripheral/dma/gdma/inc/gdma_memcpy.h @@ -1,27 +1,28 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: gdma_memcpy.h * Date: 2022-07-18 16:43:35 * LastEditTime: 2022-07-18 16:43:35 - * Description:  This files is for - * - * Modify History: + * Description:  This file is for task create function define + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2022/08/26 first commit */ -#ifndef EXAMPLE_GDMA_MEMCPY_H -#define EXAMPLE_GDMA_MEMCPY_H +#ifndef GDMA_MEMCPY_H +#define GDMA_MEMCPY_H #ifdef __cplusplus extern "C" diff --git a/example/peripheral/dma/gdma/main.c b/example/peripheral/dma/gdma/main.c index c4ae2b0f..add4a08b 100644 --- a/example/peripheral/dma/gdma/main.c +++ b/example/peripheral/dma/gdma/main.c @@ -1,22 +1,22 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: main.c * Date: 2022-06-17 08:17:59 * LastEditTime: 2022-06-17 08:17:59 - * Description: This file is for - * - * Modify History: + * Description: This file is for gdma example that running shell task and open scheduler + * + * Modify History: * Ver Who Date Changes * ----- ------ -------- -------------------------------------- */ @@ -30,15 +30,17 @@ int main(void) BaseType_t ret; ret = LSUserShellTask() ; - if(ret != pdPASS) + if (ret != pdPASS) + { goto FAIL_EXIT; + } /* ret = FFreeRTOSRunGdmaMemcpy(); */ - vTaskStartScheduler(); /* 启动任务,开启调度 */ + vTaskStartScheduler(); /* 启动任务,开启调度 */ while (1); /* 正常不会执行到这里 */ - + FAIL_EXIT: - printf("failed 0x%x \r\n", ret); + printf("failed 0x%x \r\n", ret); return 0; } diff --git a/example/peripheral/dma/gdma/sdkconfig b/example/peripheral/dma/gdma/sdkconfig index 1486603c..f253199b 100644 --- a/example/peripheral/dma/gdma/sdkconfig +++ b/example/peripheral/dma/gdma/sdkconfig @@ -2,7 +2,7 @@ # # Freertos Configuration # -CONFIG_TARGET_NAME="e2000d_freertos_a64" +CONFIG_TARGET_NAME="e2000q_freertos_a64" # end of Freertos Configuration # @@ -26,8 +26,8 @@ CONFIG_USE_SYS_TICK=y # # CONFIG_TARGET_F2000_4 is not set # CONFIG_TARGET_D2000 is not set -# CONFIG_TARGET_E2000Q is not set -CONFIG_TARGET_E2000D=y +CONFIG_TARGET_E2000Q=y +# CONFIG_TARGET_E2000D is not set # CONFIG_TARGET_E2000S is not set CONFIG_TARGET_E2000=y CONFIG_DEFAULT_DEBUG_PRINT_UART1=y @@ -69,6 +69,7 @@ CONFIG_ENABLE_FGDMA=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -109,6 +110,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -145,6 +155,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -166,12 +177,6 @@ CONFIG_FREERTOS_USE_UART=y CONFIG_FREERTOS_USE_FGDMA=y # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -183,14 +188,32 @@ CONFIG_FREERTOS_USE_FGDMA=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -208,4 +231,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/dma/gdma/sdkconfig.h b/example/peripheral/dma/gdma/sdkconfig.h index d2e79f1c..cc1db429 100644 --- a/example/peripheral/dma/gdma/sdkconfig.h +++ b/example/peripheral/dma/gdma/sdkconfig.h @@ -3,7 +3,7 @@ /* Freertos Configuration */ -#define CONFIG_TARGET_NAME "e2000d_freertos_a64" +#define CONFIG_TARGET_NAME "e2000q_freertos_a64" /* end of Freertos Configuration */ /* Standalone Setting */ @@ -24,8 +24,8 @@ /* CONFIG_TARGET_F2000_4 is not set */ /* CONFIG_TARGET_D2000 is not set */ -/* CONFIG_TARGET_E2000Q is not set */ -#define CONFIG_TARGET_E2000D +#define CONFIG_TARGET_E2000Q +/* CONFIG_TARGET_E2000D is not set */ /* CONFIG_TARGET_E2000S is not set */ #define CONFIG_TARGET_E2000 #define CONFIG_DEFAULT_DEBUG_PRINT_UART1 @@ -64,6 +64,7 @@ /* CONFIG_USE_ADC is not set */ /* CONFIG_USE_PWM is not set */ /* CONFIG_USE_IPC is not set */ +/* CONFIG_USE_MEDIA is not set */ /* end of Components Configuration */ #define CONFIG_USE_NEW_LIBC /* end of Standalone Setting */ @@ -100,6 +101,12 @@ /* Compiler Options */ +/* Cross-Compiler Setting */ + +#define CONFIG_GCC_OPTIMIZE_LEVEL 0 +/* CONFIG_USE_EXT_COMPILER is not set */ +/* CONFIG_USE_KLIN_SYS is not set */ +/* end of Cross-Compiler Setting */ #define CONFIG_OUTPUT_BINARY /* end of Compiler Options */ /* end of Building Option */ @@ -129,6 +136,7 @@ /* Freertos Eth Drivers */ /* CONFIG_FREERTOS_USE_XMAC is not set */ +/* CONFIG_FREERTOS_USE_GMAC is not set */ /* end of Freertos Eth Drivers */ /* Freertos Gpio Drivers */ @@ -147,11 +155,6 @@ #define CONFIG_FREERTOS_USE_FGDMA /* end of Freertos DMA Drivers */ -/* Freertos MMC Drivers */ - -/* CONFIG_FREERTOS_USE_FSDIO is not set */ -/* end of Freertos MMC Drivers */ - /* Freertos Adc Drivers */ /* CONFIG_FREERTOS_USE_ADC is not set */ @@ -161,13 +164,28 @@ /* CONFIG_FREERTOS_USE_CAN is not set */ /* end of Freertos Can Drivers */ + +/* Freertos I2c Drivers */ + +/* CONFIG_FREERTOS_USE_I2C is not set */ +/* end of Freertos I2c Drivers */ + +/* Freertos Mio Drivers */ + +/* CONFIG_FREERTOS_USE_MIO is not set */ +/* end of Freertos Mio Drivers */ + +/* Freertos Timer Drivers */ + +/* CONFIG_FREERTOS_USE_TIMER is not set */ +/* end of Freertos Timer Drivers */ /* end of Component Configuration */ -/* FreeRTOS Setting */ +/* Third-Party Configuration */ /* CONFIG_USE_LWIP is not set */ #define CONFIG_USE_BACKTRACE -/* CONFIG_USE_FATFS is not set */ +/* CONFIG_USE_FATFS_0_1_4 is not set */ /* CONFIG_USE_SFUD is not set */ /* CONFIG_USE_SPIFFS is not set */ /* CONFIG_USE_AMP is not set */ @@ -183,6 +201,28 @@ #define CONFIG_USE_TLSF /* CONFIG_USE_SDMMC_CMD is not set */ /* CONFIG_USE_CHERRY_USB is not set */ -/* end of FreeRTOS Setting */ +/* end of Third-Party Configuration */ + +/* Kernel Configuration */ + +#define CONFIG_FREERTOS_OPTIMIZED_SCHEDULER +#define CONFIG_FREERTOS_HZ 1000 +#define CONFIG_FREERTOS_MAX_PRIORITIES 32 +#define CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES 13 +#define CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES 11 +#define CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS 1 +#define CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE 1024 +#define CONFIG_FREERTOS_MAX_TASK_NAME_LEN 32 +#define CONFIG_FREERTOS_TIMER_TASK_PRIORITY 1 +#define CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH 2048 +#define CONFIG_FREERTOS_TIMER_QUEUE_LENGTH 10 +#define CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE 0 +#define CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS +#define CONFIG_FREERTOS_USE_TRACE_FACILITY +#define CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS +/* CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set */ +#define CONFIG_FREERTOS_TOTAL_HEAP_SIZE 10240 +#define CONFIG_FREERTOS_TASK_FPU_SUPPORT 1 +/* end of Kernel Configuration */ #endif diff --git a/example/peripheral/dma/gdma/src/cmd_gdma.c b/example/peripheral/dma/gdma/src/cmd_gdma.c index 84ea8c1f..0883c621 100644 --- a/example/peripheral/dma/gdma/src/cmd_gdma.c +++ b/example/peripheral/dma/gdma/src/cmd_gdma.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: cmd_gdma.c * Date: 2022-07-14 14:06:43 * LastEditTime: 2022-07-14 14:06:43 - * Description:  This files is for - * - * Modify History: + * Description:  This files is for gdma command interface + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2022/08/26 first commit */ /***************************** Include Files *********************************/ #include diff --git a/example/peripheral/dma/gdma/src/gdma_memcpy.c b/example/peripheral/dma/gdma/src/gdma_memcpy.c index d57fda7f..0a00fd08 100644 --- a/example/peripheral/dma/gdma/src/gdma_memcpy.c +++ b/example/peripheral/dma/gdma/src/gdma_memcpy.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: gdma_memcpy.c * Date: 2022-07-20 11:07:42 * LastEditTime: 2022-07-20 11:16:57 - * Description:  This files is for - * - * Modify History: + * Description:  This files is for GDMA task implementations + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2022/08/26 first commit */ /***************************** Include Files *********************************/ #include @@ -133,8 +134,8 @@ static FFreeRTOSGdmaRequest *GdmaPrepareRequest(u8 *src, u8 *dst, fsize_t buf_le req->trans[loop].src_buf = src + pre_buf_len * loop; req->trans[loop].dst_buf = dst + pre_buf_len * loop; req->trans[loop].data_len = pre_buf_len; - FGDMA_INFO("src: %p, dst: %p, len: %d", req->trans[loop].src_buf, req->trans[loop].dst_buf, - req->trans[loop].data_len); + FGDMA_INFO("src: %p, dst: %p, len: %d.", req->trans[loop].src_buf, req->trans[loop].dst_buf, + req->trans[loop].data_len); req->valid_trans_num++; } @@ -149,8 +150,8 @@ static void GdmaMemcpyAckChanXEnd(FGdmaChan *const chan, void *args) BaseType_t xhigher_priority_task_woken = pdFALSE; BaseType_t x_result = pdFALSE; - FGDMA_INFO("ack gdma chan %d", chan_id); - x_result = xEventGroupSetBitsFromISR(chan_evt, GDMA_CHAN_TRANS_END(chan_id), + FGDMA_INFO("ack gdma chan %d.", chan_id); + x_result = xEventGroupSetBitsFromISR(chan_evt, GDMA_CHAN_TRANS_END(chan_id), &xhigher_priority_task_woken); return; @@ -167,12 +168,12 @@ static boolean GdmaMemcpyWaitChanXEnd(u32 chan_id) pdTRUE, pdTRUE, wait_delay); /* wait for all bits */ if ((ev & GDMA_CHAN_TRANS_END(chan_id))) /* wait until channel finished memcpy */ { - FGDMA_INFO("memcpy finished !! chan bits: 0x%x", chan_evt_bits); + FGDMA_INFO("memcpy finished !! chan bits: 0x%x.", chan_evt_bits); ok = TRUE; } else { - FGDMA_ERROR("wait memcpy timeout !!! 0x%x != 0x%x", ev, chan_evt_bits); + FGDMA_ERROR("wait memcpy timeout !!! 0x%x != 0x%x.", ev, chan_evt_bits); ok = FALSE; } @@ -213,7 +214,7 @@ static void GdmaMemcpyTaskA(void *args) err = FFreeRTOSGdmaSetupChannel(gdma, chan_id, req_a); if (FT_SUCCESS != err) { - FGDMA_ERROR("setup chan-%d failed", chan_id); + FGDMA_ERROR("setup chan-%d failed.", chan_id); goto task_err; } @@ -227,7 +228,7 @@ static void GdmaMemcpyTaskA(void *args) memset(src_a, ch, GDMA_BUF_A_LEN); memset(dst_a, 0, GDMA_BUF_A_LEN); - FCacheDCacheInvalidateRange((uintptr)src_a, GDMA_BUF_A_LEN); + FCacheDCacheInvalidateRange((uintptr)src_a, GDMA_BUF_A_LEN); FCacheDCacheInvalidateRange((uintptr)dst_a, GDMA_BUF_A_LEN); if (FT_SUCCESS != FFreeRTOSGdmaStart(gdma, chan_id)) @@ -239,7 +240,7 @@ static void GdmaMemcpyTaskA(void *args) if (!GdmaMemcpyWaitChanXEnd(chan_id)) { goto task_err; - } + } FCacheDCacheInvalidateRange((uintptr)src_a, GDMA_BUF_A_LEN); FCacheDCacheInvalidateRange((uintptr)dst_a, GDMA_BUF_A_LEN); @@ -262,9 +263,11 @@ static void GdmaMemcpyTaskA(void *args) } if (times++ > memcpy_times) + { break; + } - vTaskDelay(wait_delay); + vTaskDelay(wait_delay); } task_err: @@ -291,7 +294,7 @@ static void GdmaMemcpyTaskB(void *args) err = FFreeRTOSGdmaSetupChannel(gdma, chan_id, req_b); if (FT_SUCCESS != err) { - FGDMA_ERROR("setup chan-%d failed", chan_id); + FGDMA_ERROR("setup chan-%d failed.", chan_id); goto task_err; } @@ -305,7 +308,7 @@ static void GdmaMemcpyTaskB(void *args) memset(src_b, ch, GDMA_BUF_B_LEN); memset(dst_b, 0, GDMA_BUF_B_LEN); - FCacheDCacheInvalidateRange((uintptr)src_b, GDMA_BUF_B_LEN); + FCacheDCacheInvalidateRange((uintptr)src_b, GDMA_BUF_B_LEN); FCacheDCacheInvalidateRange((uintptr)dst_b, GDMA_BUF_B_LEN); if (FT_SUCCESS != FFreeRTOSGdmaStart(gdma, chan_id)) @@ -317,7 +320,7 @@ static void GdmaMemcpyTaskB(void *args) if (!GdmaMemcpyWaitChanXEnd(chan_id)) { goto task_err; - } + } /* compare if memcpy success */ if (0 == memcmp(src_b, dst_b, GDMA_BUF_B_LEN)) @@ -337,9 +340,11 @@ static void GdmaMemcpyTaskB(void *args) } if (times++ > memcpy_times) + { break; + } - vTaskDelay(wait_delay); + vTaskDelay(wait_delay); } task_err: @@ -369,38 +374,38 @@ BaseType_t FFreeRTOSRunGdmaMemcpy(void) taskENTER_CRITICAL(); /* no schedule when create task */ - ret = xTaskCreate((TaskFunction_t )GdmaInitTask, /* task entry */ - (const char* )"GdmaInitTask",/* task name */ - (uint16_t )1024, /* task stack size in words */ - NULL, /* task params */ - (UBaseType_t )configMAX_PRIORITIES - 1, /* task priority */ - NULL); /* task handler */ - - FASSERT_MSG(pdPASS == ret, "create task failed"); - - ret = xTaskCreate((TaskFunction_t )GdmaMemcpyTaskA, /* task entry */ - (const char* )"GdmaMemcpyTaskA",/* task name */ - (uint16_t )4096, /* task stack size in words */ - NULL, /* task params */ - (UBaseType_t )configMAX_PRIORITIES - 1, /* task priority */ - (TaskHandle_t* )&task_a); /* task handler */ - - FASSERT_MSG(pdPASS == ret, "create task failed"); - - ret = xTaskCreate((TaskFunction_t )GdmaMemcpyTaskB, /* task entry */ - (const char* )"GdmaMemcpyTaskB",/* task name */ - (uint16_t )4096, /* task stack size in words */ - NULL, /* task params */ - (UBaseType_t )configMAX_PRIORITIES - 2, /* task priority */ - (TaskHandle_t* )&task_b); /* task handler */ - - FASSERT_MSG(pdPASS == ret, "create task failed"); - - exit_timer = xTimerCreate("Exit-Timer", /* Text name for the software timer - not used by FreeRTOS. */ - total_run_time, /* The software timer's period in ticks. */ - pdFALSE, /* Setting uxAutoRealod to pdFALSE creates a one-shot software timer. */ - NULL, /* use timer id to pass task data for reference. */ - GdmaMemcpyExitCallback); /* The callback function to be used by the software timer being created. */ + ret = xTaskCreate((TaskFunction_t)GdmaInitTask, /* task entry */ + (const char *)"GdmaInitTask",/* task name */ + (uint16_t)1024, /* task stack size in words */ + NULL, /* task params */ + (UBaseType_t)configMAX_PRIORITIES - 1, /* task priority */ + NULL); /* task handler */ + + FASSERT_MSG(pdPASS == ret, "create task failed"); + + ret = xTaskCreate((TaskFunction_t)GdmaMemcpyTaskA, /* task entry */ + (const char *)"GdmaMemcpyTaskA",/* task name */ + (uint16_t)4096, /* task stack size in words */ + NULL, /* task params */ + (UBaseType_t)configMAX_PRIORITIES - 1, /* task priority */ + (TaskHandle_t *)&task_a); /* task handler */ + + FASSERT_MSG(pdPASS == ret, "create task failed"); + + ret = xTaskCreate((TaskFunction_t)GdmaMemcpyTaskB, /* task entry */ + (const char *)"GdmaMemcpyTaskB",/* task name */ + (uint16_t)4096, /* task stack size in words */ + NULL, /* task params */ + (UBaseType_t)configMAX_PRIORITIES - 2, /* task priority */ + (TaskHandle_t *)&task_b); /* task handler */ + + FASSERT_MSG(pdPASS == ret, "create task failed"); + + exit_timer = xTimerCreate("Exit-Timer", /* Text name for the software timer - not used by FreeRTOS. */ + total_run_time, /* The software timer's period in ticks. */ + pdFALSE, /* Setting uxAutoRealod to pdFALSE creates a one-shot software timer. */ + NULL, /* use timer id to pass task data for reference. */ + GdmaMemcpyExitCallback); /* The callback function to be used by the software timer being created. */ FASSERT_MSG(NULL != exit_timer, "create exit timer failed"); diff --git a/example/peripheral/gpio/configs/e2000d_aarch32_eg_configs b/example/peripheral/gpio/configs/e2000d_aarch32_eg_configs index b3297007..fe40a10b 100644 --- a/example/peripheral/gpio/configs/e2000d_aarch32_eg_configs +++ b/example/peripheral/gpio/configs/e2000d_aarch32_eg_configs @@ -68,6 +68,7 @@ CONFIG_ENABLE_FGPIO=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -112,6 +113,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -148,6 +158,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -169,12 +180,6 @@ CONFIG_FREERTOS_USE_GPIO=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -186,14 +191,32 @@ CONFIG_FREERTOS_USE_GPIO=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -211,4 +234,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/gpio/configs/e2000d_aarch64_eg_configs b/example/peripheral/gpio/configs/e2000d_aarch64_eg_configs index c73f2c12..f00aff81 100644 --- a/example/peripheral/gpio/configs/e2000d_aarch64_eg_configs +++ b/example/peripheral/gpio/configs/e2000d_aarch64_eg_configs @@ -68,6 +68,7 @@ CONFIG_ENABLE_FGPIO=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -108,6 +109,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -144,6 +154,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -165,12 +176,6 @@ CONFIG_FREERTOS_USE_GPIO=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -182,14 +187,32 @@ CONFIG_FREERTOS_USE_GPIO=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -207,4 +230,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/gpio/configs/e2000q_aarch32_eg_configs b/example/peripheral/gpio/configs/e2000q_aarch32_eg_configs index b83d2304..63752a83 100644 --- a/example/peripheral/gpio/configs/e2000q_aarch32_eg_configs +++ b/example/peripheral/gpio/configs/e2000q_aarch32_eg_configs @@ -68,6 +68,7 @@ CONFIG_ENABLE_FGPIO=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -112,6 +113,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -148,6 +158,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -169,12 +180,6 @@ CONFIG_FREERTOS_USE_GPIO=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -186,14 +191,32 @@ CONFIG_FREERTOS_USE_GPIO=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -211,4 +234,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/gpio/configs/e2000q_aarch64_eg_configs b/example/peripheral/gpio/configs/e2000q_aarch64_eg_configs index 7e0ec826..8d3d4aeb 100644 --- a/example/peripheral/gpio/configs/e2000q_aarch64_eg_configs +++ b/example/peripheral/gpio/configs/e2000q_aarch64_eg_configs @@ -68,6 +68,7 @@ CONFIG_ENABLE_FGPIO=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -108,6 +109,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -144,6 +154,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -165,12 +176,6 @@ CONFIG_FREERTOS_USE_GPIO=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -182,14 +187,32 @@ CONFIG_FREERTOS_USE_GPIO=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -207,4 +230,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/gpio/inc/gpio_io_irq.h b/example/peripheral/gpio/inc/gpio_io_irq.h index 096956d2..b2f35e3b 100644 --- a/example/peripheral/gpio/inc/gpio_io_irq.h +++ b/example/peripheral/gpio/inc/gpio_io_irq.h @@ -1,27 +1,28 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: gpio_io_irq.h * Date: 2022-07-19 09:26:25 * LastEditTime: 2022-07-19 09:26:25 - * Description:  This files is for - * - * Modify History: + * Description:  This file is for gpio io irq function declarations. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2022/8/26 init commit */ -#ifndef EXAMPLE_GPIO_IRQ_H -#define EXAMPLE_GPIO_IRQ_H +#ifndef GPIO_IO_IRQ_H +#define GPIO_IO_IRQ_H #ifdef __cplusplus extern "C" diff --git a/example/peripheral/gpio/main.c b/example/peripheral/gpio/main.c index 478f1a3b..7abccdf8 100644 --- a/example/peripheral/gpio/main.c +++ b/example/peripheral/gpio/main.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: main.c * Date: 2022-06-17 08:17:59 * LastEditTime: 2022-06-17 08:17:59 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for gpio main entry. + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2022/8/26 init commit */ #include "shell.h" @@ -30,15 +31,17 @@ int main(void) BaseType_t ret; ret = LSUserShellTask() ; - if(ret != pdPASS) + if (ret != pdPASS) + { goto FAIL_EXIT; + } /* ret = FFreeRTOSRunGpioIOIrq("3-a-4", "3-a-5"); */ - vTaskStartScheduler(); /* 启动任务,开启调度 */ + vTaskStartScheduler(); /* 启动任务,开启调度 */ while (1); /* 正常不会执行到这里 */ - + FAIL_EXIT: - printf("failed 0x%x \r\n", ret); + printf("Failed,the ret value is 0x%x. \r\n", ret); return 0; } diff --git a/example/peripheral/gpio/sdkconfig b/example/peripheral/gpio/sdkconfig index c73f2c12..8d3d4aeb 100644 --- a/example/peripheral/gpio/sdkconfig +++ b/example/peripheral/gpio/sdkconfig @@ -2,7 +2,7 @@ # # Freertos Configuration # -CONFIG_TARGET_NAME="e2000d_freertos_a64" +CONFIG_TARGET_NAME="e2000q_freertos_a64" # end of Freertos Configuration # @@ -26,8 +26,8 @@ CONFIG_USE_SYS_TICK=y # # CONFIG_TARGET_F2000_4 is not set # CONFIG_TARGET_D2000 is not set -# CONFIG_TARGET_E2000Q is not set -CONFIG_TARGET_E2000D=y +CONFIG_TARGET_E2000Q=y +# CONFIG_TARGET_E2000D is not set # CONFIG_TARGET_E2000S is not set CONFIG_TARGET_E2000=y CONFIG_DEFAULT_DEBUG_PRINT_UART1=y @@ -68,6 +68,7 @@ CONFIG_ENABLE_FGPIO=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -108,6 +109,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -144,6 +154,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -165,12 +176,6 @@ CONFIG_FREERTOS_USE_GPIO=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -182,14 +187,32 @@ CONFIG_FREERTOS_USE_GPIO=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -207,4 +230,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/gpio/sdkconfig.h b/example/peripheral/gpio/sdkconfig.h index 6e502857..7675c972 100644 --- a/example/peripheral/gpio/sdkconfig.h +++ b/example/peripheral/gpio/sdkconfig.h @@ -3,7 +3,7 @@ /* Freertos Configuration */ -#define CONFIG_TARGET_NAME "e2000d_freertos_a64" +#define CONFIG_TARGET_NAME "e2000q_freertos_a64" /* end of Freertos Configuration */ /* Standalone Setting */ @@ -24,8 +24,8 @@ /* CONFIG_TARGET_F2000_4 is not set */ /* CONFIG_TARGET_D2000 is not set */ -/* CONFIG_TARGET_E2000Q is not set */ -#define CONFIG_TARGET_E2000D +#define CONFIG_TARGET_E2000Q +/* CONFIG_TARGET_E2000D is not set */ /* CONFIG_TARGET_E2000S is not set */ #define CONFIG_TARGET_E2000 #define CONFIG_DEFAULT_DEBUG_PRINT_UART1 @@ -63,6 +63,7 @@ /* CONFIG_USE_ADC is not set */ /* CONFIG_USE_PWM is not set */ /* CONFIG_USE_IPC is not set */ +/* CONFIG_USE_MEDIA is not set */ /* end of Components Configuration */ #define CONFIG_USE_NEW_LIBC /* end of Standalone Setting */ @@ -99,6 +100,12 @@ /* Compiler Options */ +/* Cross-Compiler Setting */ + +#define CONFIG_GCC_OPTIMIZE_LEVEL 0 +/* CONFIG_USE_EXT_COMPILER is not set */ +/* CONFIG_USE_KLIN_SYS is not set */ +/* end of Cross-Compiler Setting */ #define CONFIG_OUTPUT_BINARY /* end of Compiler Options */ /* end of Building Option */ @@ -128,6 +135,7 @@ /* Freertos Eth Drivers */ /* CONFIG_FREERTOS_USE_XMAC is not set */ +/* CONFIG_FREERTOS_USE_GMAC is not set */ /* end of Freertos Eth Drivers */ /* Freertos Gpio Drivers */ @@ -146,11 +154,6 @@ /* CONFIG_FREERTOS_USE_FGDMA is not set */ /* end of Freertos DMA Drivers */ -/* Freertos MMC Drivers */ - -/* CONFIG_FREERTOS_USE_FSDIO is not set */ -/* end of Freertos MMC Drivers */ - /* Freertos Adc Drivers */ /* CONFIG_FREERTOS_USE_ADC is not set */ @@ -160,13 +163,28 @@ /* CONFIG_FREERTOS_USE_CAN is not set */ /* end of Freertos Can Drivers */ + +/* Freertos I2c Drivers */ + +/* CONFIG_FREERTOS_USE_I2C is not set */ +/* end of Freertos I2c Drivers */ + +/* Freertos Mio Drivers */ + +/* CONFIG_FREERTOS_USE_MIO is not set */ +/* end of Freertos Mio Drivers */ + +/* Freertos Timer Drivers */ + +/* CONFIG_FREERTOS_USE_TIMER is not set */ +/* end of Freertos Timer Drivers */ /* end of Component Configuration */ -/* FreeRTOS Setting */ +/* Third-Party Configuration */ /* CONFIG_USE_LWIP is not set */ #define CONFIG_USE_BACKTRACE -/* CONFIG_USE_FATFS is not set */ +/* CONFIG_USE_FATFS_0_1_4 is not set */ /* CONFIG_USE_SFUD is not set */ /* CONFIG_USE_SPIFFS is not set */ /* CONFIG_USE_AMP is not set */ @@ -182,6 +200,28 @@ #define CONFIG_USE_TLSF /* CONFIG_USE_SDMMC_CMD is not set */ /* CONFIG_USE_CHERRY_USB is not set */ -/* end of FreeRTOS Setting */ +/* end of Third-Party Configuration */ + +/* Kernel Configuration */ + +#define CONFIG_FREERTOS_OPTIMIZED_SCHEDULER +#define CONFIG_FREERTOS_HZ 1000 +#define CONFIG_FREERTOS_MAX_PRIORITIES 32 +#define CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES 13 +#define CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES 11 +#define CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS 1 +#define CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE 1024 +#define CONFIG_FREERTOS_MAX_TASK_NAME_LEN 32 +#define CONFIG_FREERTOS_TIMER_TASK_PRIORITY 1 +#define CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH 2048 +#define CONFIG_FREERTOS_TIMER_QUEUE_LENGTH 10 +#define CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE 0 +#define CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS +#define CONFIG_FREERTOS_USE_TRACE_FACILITY +#define CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS +/* CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set */ +#define CONFIG_FREERTOS_TOTAL_HEAP_SIZE 10240 +#define CONFIG_FREERTOS_TASK_FPU_SUPPORT 1 +/* end of Kernel Configuration */ #endif diff --git a/example/peripheral/gpio/src/cmd_gpio.c b/example/peripheral/gpio/src/cmd_gpio.c index d81896f2..7c4c8391 100644 --- a/example/peripheral/gpio/src/cmd_gpio.c +++ b/example/peripheral/gpio/src/cmd_gpio.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: cmd_gpio.c * Date: 2022-06-28 14:42:53 * LastEditTime: 2022-06-28 14:42:53 - * Description:  This files is for - * - * Modify History: + * Description:  This file is for gpio shell command implmentation. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2022/8/26 init commit */ /***************************** Include Files *********************************/ #include @@ -42,25 +43,25 @@ /*****************************************************************************/ static boolean GpioParseIndex(const char *str, u32 *pin) { - FASSERT(str && pin); - u32 id_num = 0; - char port = 'a'; - u32 pin_num = 0; + FASSERT(str && pin); + u32 id_num = 0; + char port = 'a'; + u32 pin_num = 0; u32 port_num = 0; if (3 != sscanf(str, "%d-%c-%d", &id_num, &port, &pin_num)) - { - printf("Parse as %d-%c-%d", id_num, port, pin_num); - return FALSE; - } - - if ((id_num >= FGPIO_NUM) || - ((port != 'a') && (port != 'b')) || - ( pin_num >= FGPIO_PIN_NUM)) - { - printf("Wrong pin index"); - return FALSE; - } + { + printf("Parse as %d-%c-%d", id_num, port, pin_num); + return FALSE; + } + + if ((id_num >= FGPIO_NUM) || + ((port != 'a') && (port != 'b')) || + (pin_num >= FGPIO_PIN_NUM)) + { + printf("Wrong pin index."); + return FALSE; + } port_num = (('a' == port) ? 0 : 1); /* 0 = port-a, 1 = port-b */ *pin = FFREERTOS_GPIO_PIN_INDEX(id_num, port_num, pin_num); @@ -88,7 +89,7 @@ static int GpioCmdEntry(int argc, char *argv[]) in_pin_str = argv[3]; } - if ((FALSE == GpioParseIndex(out_pin_str, &out_pin)) || + if ((FALSE == GpioParseIndex(out_pin_str, &out_pin)) || (FALSE == GpioParseIndex(in_pin_str, &in_pin))) { return -2; diff --git a/example/peripheral/gpio/src/gpio_io_irq.c b/example/peripheral/gpio/src/gpio_io_irq.c index 54640297..db64523c 100644 --- a/example/peripheral/gpio/src/gpio_io_irq.c +++ b/example/peripheral/gpio/src/gpio_io_irq.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: gpio_io_irq.c * Date: 2022-07-22 13:57:42 - * LastEditTime: 2022-07-22 13:57:43 - * Description:  This files is for - * - * Modify History: + * LastEditTime: 2022-07-22 13:57:43 + * Description:  This file is for gpio io irq implementation. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2022/8/26 init commit */ /***************************** Include Files *********************************/ #include @@ -45,7 +46,7 @@ static FFreeRTOSGpioConfig out_gpio_cfg; static xSemaphoreHandle init_locker = NULL; static u32 in_pin = FFREERTOS_GPIO_PIN_INDEX(3, 0, 5); /* GPIO 3-A-5 */ static u32 out_pin = FFREERTOS_GPIO_PIN_INDEX(3, 0, 4); /* GPIO 3-A-4 */ -static FFreeRTOSGpioPinConfig in_pin_config = +static FFreeRTOSGpioPinConfig in_pin_config = { .pin_idx = FFREERTOS_GPIO_PIN_INDEX(3, 0, 5), /* GPIO 3-A-5 */ .mode = FGPIO_DIR_INPUT, @@ -54,7 +55,7 @@ static FFreeRTOSGpioPinConfig in_pin_config = .irq_handler = NULL, .irq_args = NULL }; -static FFreeRTOSGpioPinConfig out_pin_config = +static FFreeRTOSGpioPinConfig out_pin_config = { .pin_idx = FFREERTOS_GPIO_PIN_INDEX(3, 0, 4), /* GPIO 3-A-4 */ .mode = FGPIO_DIR_OUTPUT, @@ -78,7 +79,7 @@ static boolean is_running = FALSE; /*****************************************************************************/ static void GpioIOIrqExitCallback(TimerHandle_t timer) { - printf("exiting...\r\n"); + printf("Exiting...\r\n"); if (output_task) /* stop and delete send task */ { @@ -94,7 +95,7 @@ static void GpioIOIrqExitCallback(TimerHandle_t timer) if (FT_SUCCESS != FFreeRTOSGpioDeInit(in_gpio)) { - FGPIO_ERROR("delete gpio failed !!!"); + FGPIO_ERROR("Delete gpio failed."); } in_gpio = NULL; @@ -102,8 +103,8 @@ static void GpioIOIrqExitCallback(TimerHandle_t timer) { if (FT_SUCCESS != FFreeRTOSGpioDeInit(out_gpio)) { - FGPIO_ERROR("delete gpio failed !!!"); - } + FGPIO_ERROR("Delete gpio failed."); + } } out_gpio = NULL; @@ -123,7 +124,7 @@ static void GpioIOIrqExitCallback(TimerHandle_t timer) { if (pdPASS != xTimerDelete(exit_timer, 0)) { - FGPIO_ERROR("delete exit timer failed !!!"); + FGPIO_ERROR("Delete exit timer failed."); } exit_timer = NULL; } @@ -136,8 +137,8 @@ static void GpioIOAckPinIrq(s32 vector, void *param) BaseType_t xhigher_priority_task_woken = pdFALSE; BaseType_t x_result = pdFALSE; - FGPIO_INFO("ack pin irq"); - x_result = xEventGroupSetBitsFromISR(event, PIN_IRQ_OCCURED, + FGPIO_INFO("Ack pin irq."); + x_result = xEventGroupSetBitsFromISR(event, PIN_IRQ_OCCURED, &xhigher_priority_task_woken); } @@ -161,22 +162,22 @@ static void GdmaInitTask(void *args) /* init output/input pin */ out_pin_config.pin_idx = out_pin; err = FFreeRTOSSetupPin(out_gpio, &out_pin_config); - FASSERT_MSG(FT_SUCCESS == err, "init output gpio pin failed !!!"); + FASSERT_MSG(FT_SUCCESS == err, "Init output gpio pin failed."); in_pin_config.pin_idx = in_pin; in_pin_config.irq_handler = GpioIOAckPinIrq; in_pin_config.irq_args = NULL; - printf("config input pin interrupt type as %s\r\n", irq_type_str[in_pin_config.irq_type]); + printf("Config input pin interrupt type as %s\r\n", irq_type_str[in_pin_config.irq_type]); err = FFreeRTOSSetupPin(in_gpio, &in_pin_config); - FASSERT_MSG(FT_SUCCESS == err, "init input gpio pin failed !!!"); + FASSERT_MSG(FT_SUCCESS == err, "Init input gpio pin failed."); - FASSERT_MSG(init_locker, "init locker NULL"); + FASSERT_MSG(init_locker, "Init locker NULL"); for (u32 loop = 0U; loop < GPIO_WORK_TASK_NUM; loop++) { xSemaphoreGive(init_locker); } - vTaskDelete(NULL); + vTaskDelete(NULL); } static void GpioIOIrqOutputTask(void *args) @@ -187,15 +188,15 @@ static void GpioIOIrqOutputTask(void *args) const TickType_t toggle_delay = pdMS_TO_TICKS(500UL); /* toggle every 500 ms */ FGpioPinVal out_val = FGPIO_PIN_LOW; - printf("gpio ouptut task started \r\n"); + printf("Gpio ouptut task started. \r\n"); for (;;) { printf(" ==> Set GPIO-%d-%c-%d as %s\r\n", - FFREERTOS_GPIO_PIN_CTRL_ID(out_pin), - (FGPIO_PORT_A == FFREERTOS_GPIO_PIN_PORT_ID(out_pin)) ? 'a' : 'b', - FFREERTOS_GPIO_PIN_ID(out_pin), - (out_val == FGPIO_PIN_LOW) ? "low" : "high"); + FFREERTOS_GPIO_PIN_CTRL_ID(out_pin), + (FGPIO_PORT_A == FFREERTOS_GPIO_PIN_PORT_ID(out_pin)) ? 'a' : 'b', + FFREERTOS_GPIO_PIN_ID(out_pin), + (out_val == FGPIO_PIN_LOW) ? "low" : "high"); FFreeRTOSPinWrite(out_gpio, out_pin, out_val); /* start with low level */ vTaskDelay(toggle_delay); @@ -208,8 +209,8 @@ static boolean GpioIOWaitIrqOccurr(void) const TickType_t wait_delay = pdMS_TO_TICKS(2000U); /* just check 2sec wait */ boolean ok = FALSE; EventBits_t ev = xEventGroupWaitBits(event, - PIN_IRQ_OCCURED, - pdTRUE, pdFALSE, wait_delay); + PIN_IRQ_OCCURED, + pdTRUE, pdFALSE, wait_delay); if ((ev & PIN_IRQ_OCCURED)) { @@ -228,7 +229,7 @@ static void GpioIOIrqInputTask(void *args) FError err = FT_SUCCESS; const TickType_t input_delay = pdMS_TO_TICKS(100UL); /* input every 500 ms */ - printf("gpio input task started \r\n"); + printf("Gpio input task started. \r\n"); (void)FFreeRTOSSetIRQ(in_gpio, in_pin, TRUE); for (;;) @@ -243,20 +244,20 @@ static void GpioIOIrqInputTask(void *args) /* check for interrupt event */ if (GpioIOWaitIrqOccurr()) { - printf("GPIO-%d-%c-%d, Interrrupt Asserted !!! \r\n", - FFREERTOS_GPIO_PIN_CTRL_ID(in_pin), - (FGPIO_PORT_A == FFREERTOS_GPIO_PIN_PORT_ID(in_pin)) ? 'a' : 'b', - FFREERTOS_GPIO_PIN_ID(in_pin)); + printf("GPIO-%d-%c-%d, Interrrupt Asserted. \r\n", + FFREERTOS_GPIO_PIN_CTRL_ID(in_pin), + (FGPIO_PORT_A == FFREERTOS_GPIO_PIN_PORT_ID(in_pin)) ? 'a' : 'b', + FFREERTOS_GPIO_PIN_ID(in_pin)); (void)FFreeRTOSSetIRQ(in_gpio, in_pin, TRUE); /* enable irq to recv next one */ } else { - printf("None Interrupt Assert\r\n"); + printf("None Interrupt Assert.\r\n"); continue; } - vTaskDelay(input_delay); + vTaskDelay(input_delay); } } @@ -267,63 +268,63 @@ BaseType_t FFreeRTOSRunGpioIOIrq(u32 out_pin_idx, u32 in_pin_idx) if (is_running) { - FGPIO_ERROR("task is running !!!!"); + FGPIO_ERROR("The task is running."); return pdPASS; } is_running = TRUE; - FASSERT_MSG(NULL == event, "event group exists !!!"); - FASSERT_MSG((event = xEventGroupCreate()) != NULL, "create event group failed !!!"); + FASSERT_MSG(NULL == event, "Event group exists."); + FASSERT_MSG((event = xEventGroupCreate()) != NULL, "Create event group failed."); - FASSERT_MSG(NULL == init_locker, "init locker exists !!!"); - FASSERT_MSG((init_locker = xSemaphoreCreateCounting(GPIO_WORK_TASK_NUM, 0U)) != NULL, "create event group failed !!!"); + FASSERT_MSG(NULL == init_locker, "Init locker exists."); + FASSERT_MSG((init_locker = xSemaphoreCreateCounting(GPIO_WORK_TASK_NUM, 0U)) != NULL, "Create event group failed."); out_pin = out_pin_idx; in_pin = in_pin_idx; taskENTER_CRITICAL(); /* no schedule when create task */ - ret = xTaskCreate((TaskFunction_t )GdmaInitTask, /* task entry */ - (const char* )"GdmaInitTask",/* task name */ - (uint16_t )1024, /* task stack size in words */ - NULL, /* task params */ - (UBaseType_t )configMAX_PRIORITIES - 1, /* task priority */ - NULL); /* task handler */ + ret = xTaskCreate((TaskFunction_t)GdmaInitTask, /* task entry */ + (const char *)"GdmaInitTask",/* task name */ + (uint16_t)1024, /* task stack size in words */ + NULL, /* task params */ + (UBaseType_t)configMAX_PRIORITIES - 1, /* task priority */ + NULL); /* task handler */ - FASSERT_MSG(pdPASS == ret, "create task failed"); + FASSERT_MSG(pdPASS == ret, "Create task failed."); - ret = xTaskCreate((TaskFunction_t )GpioIOIrqOutputTask, /* task entry */ - (const char* )"GpioIOIrqOutputTask",/* task name */ - (uint16_t )1024, /* task stack size in words */ - NULL, /* task params */ - (UBaseType_t )configMAX_PRIORITIES - 1, /* task priority */ - (TaskHandle_t* )&output_task); /* task handler */ + ret = xTaskCreate((TaskFunction_t)GpioIOIrqOutputTask, /* task entry */ + (const char *)"GpioIOIrqOutputTask",/* task name */ + (uint16_t)1024, /* task stack size in words */ + NULL, /* task params */ + (UBaseType_t)configMAX_PRIORITIES - 1, /* task priority */ + (TaskHandle_t *)&output_task); /* task handler */ - FASSERT_MSG(pdPASS == ret, "create task failed"); + FASSERT_MSG(pdPASS == ret, "Create task failed."); - ret = xTaskCreate((TaskFunction_t )GpioIOIrqInputTask, /* task entry */ - (const char* )"GpioIOIrqInputTask",/* task name */ - (uint16_t )1024, /* task stack size in words */ - NULL, /* task params */ - (UBaseType_t )configMAX_PRIORITIES - 2, /* task priority */ - (TaskHandle_t* )&input_task); /* task handler */ + ret = xTaskCreate((TaskFunction_t)GpioIOIrqInputTask, /* task entry */ + (const char *)"GpioIOIrqInputTask",/* task name */ + (uint16_t)1024, /* task stack size in words */ + NULL, /* task params */ + (UBaseType_t)configMAX_PRIORITIES - 2, /* task priority */ + (TaskHandle_t *)&input_task); /* task handler */ - FASSERT_MSG(pdPASS == ret, "create task failed"); + FASSERT_MSG(pdPASS == ret, "Create task failed."); - exit_timer = xTimerCreate("Exit-Timer", /* Text name for the software timer - not used by FreeRTOS. */ - total_run_time, /* The software timer's period in ticks. */ - pdFALSE, /* Setting uxAutoRealod to pdFALSE creates a one-shot software timer. */ - NULL, /* use timer id to pass task data for reference. */ - GpioIOIrqExitCallback); /* The callback function to be used by the software timer being created. */ + exit_timer = xTimerCreate("Exit-Timer", /* Text name for the software timer - not used by FreeRTOS. */ + total_run_time, /* The software timer's period in ticks. */ + pdFALSE, /* Setting uxAutoRealod to pdFALSE creates a one-shot software timer. */ + NULL, /* use timer id to pass task data for reference. */ + GpioIOIrqExitCallback); /* The callback function to be used by the software timer being created. */ - FASSERT_MSG(NULL != exit_timer, "create exit timer failed"); + FASSERT_MSG(NULL != exit_timer, "Create exit timer failed."); taskEXIT_CRITICAL(); /* allow schedule since task created */ ret = xTimerStart(exit_timer, 0); /* start */ - FASSERT_MSG(pdPASS == ret, "start exit timer failed"); + FASSERT_MSG(pdPASS == ret, "Start exit timer failed."); return ret; } diff --git a/example/storage/sata_fatfs/Kconfig b/example/peripheral/i2c/Kconfig similarity index 100% rename from example/storage/sata_fatfs/Kconfig rename to example/peripheral/i2c/Kconfig diff --git a/example/network/gmac_lwip_test/README.md b/example/peripheral/i2c/README.md similarity index 50% rename from example/network/gmac_lwip_test/README.md rename to example/peripheral/i2c/README.md index 9d3ae3b5..3af26431 100644 --- a/example/network/gmac_lwip_test/README.md +++ b/example/peripheral/i2c/README.md @@ -12,52 +12,66 @@ * * * FilePath: README.md - * Date: 2022-02-24 13:42:19 - * LastEditTime: 2022-03-21 17:02:02 - * Description:  This file is for + * Date: 2022-08-23 11:15:06 + * LastEditTime: 2022-08-23 11:15:06 + * Description:  This file is for i2c * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 0.1.0 liushengming 2022.08.23 init --> -# lwip base on freertos +# i2c base on freertos ## 1. 例程介绍 -本例程示范了freertos环境下的lwip移植。 -本例程目前支持在freertos下,移植lwip,使网络能够ping通,shell能够正常运行。 +本例程示范了freertos环境下的i2c的读写使用,包括i2c的初始化、写、读和去初始化操作; +程序启动后,创建i2c的初始化、写任务和读任务; +例程在D2000上使用i2c-0与i2c-2回环测试,也可进行eeprom读取(更改从机地址,取消slave任务初始化即可)(注意i2c-0本身连接的eeprom芯片,虚拟从机地址不要与其重合,不然会引起总线冲突); +例程也可以作为ft2004的例程参考,只需自行解决从机地址替换,本例程没有直接演示。 +E2000D上使用的demo板上的 RTC 进行iic测试,从机亦可参考D2000进行; +本例程目前仅仅适配了主机poll发送,从机中断接收的方式。 ## 2. 如何使用例程 本例程需要用到 -- Phytium开发板(FT2000-4/D2000/E2000D) +- Phytium开发板(D2000/E2000DQS of TestB板) - [Phytium freeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) - [Phytium standalone SDK](https://gitee.com/phytium_embedded/phytium-standalone-sdk) ### 2.1 硬件配置方法 本例程支持的硬件平台包括 +- D2000、E2000DQS demo开发板 + +对应的配置项是 +- CONFIG_TARGET_D2000 +- CONFIG_TARGET_E2000D、 CONFIG_TARGET_E2000Q + +### 2.1.1 硬件连线 -- FT2000-4 - D2000 -- E2000D -对应的配置项是, +![hardware_d2000](./figs/board.png) -- CONFIG_TARGET_F2000_4 -- CONFIG_TARGET_D2000 -- CONFIG_TARGET_E2000D +- E2000 + +![hardware_e2000](./figs/E2000_1339.png) ### 2.2 SDK配置方法 本例程需要, -- 使能LWIP +- 使能Shell +- 使能I2C +- 如果是E2000系列,使能MIO 对应的配置项是, -- CONFIG_USE_LWIP - CONFIG_USE_LETTER_SHELL +- CONFIG_FREERTOS_USE_I2C +如果是E2000系列 +- CONFIG_FREERTOS_USE_MIO 本例子已经提供好具体的编译指令,以下进行介绍: - make 将目录下的工程进行编译 @@ -65,10 +79,10 @@ - make boot 将目录下的工程进行编译,并将生成的elf 复制到目标地址 - make load_d2000_aarch64 将预设64bit d2000 下的配置加载至工程中 - make load_d2000_aarch32 将预设32bit d2000 下的配置加载至工程中 -- make load_ft2004_aarch64 将预设64bit ft2004 下的配置加载至工程中 -- make load_ft2004_aarch32 将预设32bit ft2004 下的配置加载至工程中 - make load_e2000d_aarch64 将预设64bit e2000d 下的配置加载至工程中 - make load_e2000d_aarch32 将预设32bit e2000d 下的配置加载至工程中 +- make load_e2000q_aarch64 将预设64bit e2000q 下的配置加载至工程中 +- make load_e2000q_aarch32 将预设32bit e2000q 下的配置加载至工程中 - make menuconfig 配置目录下的参数变量 - make backup_kconfig 将目录下的sdkconfig 备份到./configs下 @@ -81,11 +95,11 @@ #### 2.3.1 构建过程 - 在host侧完成配置 ->配置成ft2004,对于其它平台,使用对于的默认配置,如D2000 `make load_d2000_aarch32` +>配置成d2000,对于其它平台,使用对应的默认配置,如E2000D `make load_e2000d_aarch32` - 选择目标平台 ``` -make load_ft2004_aarch32 +make load_d2000_aarch32 ``` - 选择例程需要的配置 @@ -112,7 +126,7 @@ sudo service tftpd-hpa restart - 开发板侧使用bootelf命令跳转 ``` -setenv ipaddr 192.168.4.20 +setenv ipaddr 192.168.4.20 setenv serverip 192.168.4.50 setenv gatewayip 192.168.4.1 tftpboot 0x90100000 freertos.elf @@ -121,101 +135,27 @@ bootelf -p 0x90100000 ### 2.4 输出与实验现象 -- 启动进入后,根据连接的gmac口,输入指令完成网口初始化 - -#### 2.4.1 ipv4下的probe - -- 输入以下命令 - -``` -make menuconfig -``` - -- 将此项选择上 - -![ipv4_select](./pic/gmac_ipv4_menuconfig.png) - -- 输入以下命令,初始化LWIP网络协议栈, 依次配置ip地址,子网掩码,网关地址和退出时间,运行完成退出后LWIP协议栈会被暂时去使能 - -``` -gmac probe [instance num] -``` - -- 其中instance num 为控制器id - -![gmac_probe](./pic/gmac_probe.png "gmac_probe.png") - -![ping](./pic/ping.png "ping.png") - - -#### 2.4.2 ipv6下的probe - - -- 输入以下命令 - -``` -make menuconfig -``` - -- 将此项选择上 - -![ipv6_select](./pic/gmac_ipv6_menuconfig.png) - -- 输入以下命令,初始化LWIP网络协议栈, 依次配置ip地址,子网掩码,网关地址和退出时间,运行完成退出后LWIP协议栈会被暂时去使能 - -``` -gmac probe [instance num] -``` - -- 其中instance num 为控制器id - -![gmac_probe](./pic/gmac_probe_ipv6.png "gmac_probe_ipv6.png") - -![ping](./pic/ping_ipv6.png "ping_ipv6.png") - - -#### 2.4.3 ipv4 dhcp - -- 输入以下命令 - -``` -make menuconfig -``` - -- 将此项选择上 - - -![dhcp_select](./pic/gmac_dhcp_menuconfig.png) - - +- 系统进入后,创建i2c初始化任务,创建i2c从机中断初始化,注册中断服务函数,创建i2c主机的读写任务函数。 +- D2000 -- 输入以下命令,初始化LWIP网络协议栈, 并且会默认打开dhcp 线程 +![d2000](./figs/d2000_master_slave.png) -``` -gmac probe [instance num] -``` +![d2000](./figs/d2000_eeprom.png) -- 其中instance num 为控制器id +- E2000 -![gmac_probe_dhcp0](./pic/gmac_probe_dhcp0.png "gmac_probe_dhcp0.png") +![e2000d](./figs/E2000_1339.png) -![gmac_probe_dhcp1](./pic/gmac_probe_dhcp1.png "gmac_probe_dhcp1.png") - -#### 2.4.2 提供 ## 3. 如何解决问题 -Q: 程序运行过程中queue.c的debug信息报错 +- 若出现读写异常,需确认连接是否正确; -A: 考虑自身任务创建时分配的栈空间大小,考虑tcpip_thread任务的栈空间大小TCPIP_THREAD_STACKSIZE +- 由于D2000开发板上的自带eeprom,因此不建议使用特殊地址0x57进行I2C-2模拟的从设备地址,因为这可能导致总线抢占,无法正常传输; -Q: 程序运行过程中ping大包异常 +## 4. 修改历史记录 -A: 考虑以下两个宏的大小:PBUF_POOL_SIZE定义缓冲池的个数,PBUF_POOL_BUFSIZE定义单个缓冲区的大小 -## 4. 修改历史记录 -v0.0.4 初次合入lwip -v0.1.0 重构lwip diff --git a/example/storage/sata_fatfs/configs/d2000_aarch32_eg_configs b/example/peripheral/i2c/configs/d2000_aarch32_eg_configs similarity index 69% rename from example/storage/sata_fatfs/configs/d2000_aarch32_eg_configs rename to example/peripheral/i2c/configs/d2000_aarch32_eg_configs index ada6a28a..944fdcd3 100644 --- a/example/storage/sata_fatfs/configs/d2000_aarch32_eg_configs +++ b/example/peripheral/i2c/configs/d2000_aarch32_eg_configs @@ -16,7 +16,7 @@ CONFIG_USE_FREERTOS=y CONFIG_TARGET_ARMV8_AARCH32=y # CONFIG_TARGET_ARMV8_AARCH64 is not set CONFIG_USE_CACHE=y -CONFIG_USE_L3CACHE=y +# CONFIG_USE_L3CACHE is not set CONFIG_USE_MMU=y CONFIG_USE_SYS_TICK=y CONFIG_USE_AARCH64_L1_TO_AARCH32=y @@ -53,34 +53,28 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_GPIO is not set # CONFIG_USE_ETH is not set # CONFIG_USE_CAN is not set -# CONFIG_USE_I2C is not set +CONFIG_USE_I2C=y +CONFIG_USE_FI2C=y # CONFIG_USE_TIMER is not set -# CONFIG_USE_MIO is not set -# CONFIG_USE_SDMMC is not set -CONFIG_USE_PCIE=y +CONFIG_USE_MIO=y # -# Pcie Configuration +# Hardware Mio Configuration # -CONFIG_ENABLE_F_PCIE=y -# end of Pcie Configuration +# end of Hardware Mio Configuration +# CONFIG_USE_SDMMC is not set +# CONFIG_USE_PCIE is not set # CONFIG_USE_WDT is not set # CONFIG_USE_DMA is not set # CONFIG_USE_NAND is not set # CONFIG_USE_RTC is not set -CONFIG_USE_SATA=y - -# -# FSATA Configuration -# -CONFIG_ENABLE_FSATA=y -# end of FSATA Configuration - +# CONFIG_USE_SATA is not set # CONFIG_USE_USB is not set # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -91,9 +85,9 @@ CONFIG_USE_NEW_LIBC=y # # CONFIG_LOG_VERBOS is not set # CONFIG_LOG_DEBUG is not set -CONFIG_LOG_INFO=y +# CONFIG_LOG_INFO is not set # CONFIG_LOG_WARN is not set -# CONFIG_LOG_ERROR is not set +CONFIG_LOG_ERROR=y # CONFIG_LOG_NONE is not set CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y CONFIG_INTERRUPT_ROLE_MASTER=y @@ -125,6 +119,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -161,6 +164,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -182,12 +186,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -199,24 +197,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers -# end of Component Configuration # -# FreeRTOS Setting +# Freertos I2c Drivers # -# CONFIG_USE_LWIP is not set -CONFIG_USE_BACKTRACE=y -CONFIG_USE_FATFS=y +CONFIG_FREERTOS_USE_I2C=y +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers # -# FATFS Configuration +# Freertos Timer Drivers # -# CONFIG_SELECT_FATFS_RAM_DISK is not set -# CONFIG_SELECT_FATFS_FSDMMC is not set -CONFIG_SELECT_FATFS_FSATA_PCIE=y -# CONFIG_SELECT_FATFS_USB is not set -# end of FATFS Configuration +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers +# end of Component Configuration +# +# Third-Party Configuration +# +# CONFIG_USE_LWIP is not set +CONFIG_USE_BACKTRACE=y +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -231,7 +237,30 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set # end of Letter Shell Configuration -CONFIG_USE_TLSF=y +# CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/storage/sata_fatfs/configs/d2000_aarch64_eg_configs b/example/peripheral/i2c/configs/d2000_aarch64_eg_configs similarity index 69% rename from example/storage/sata_fatfs/configs/d2000_aarch64_eg_configs rename to example/peripheral/i2c/configs/d2000_aarch64_eg_configs index 887b52f0..efcc8e0e 100644 --- a/example/storage/sata_fatfs/configs/d2000_aarch64_eg_configs +++ b/example/peripheral/i2c/configs/d2000_aarch64_eg_configs @@ -16,7 +16,7 @@ CONFIG_USE_FREERTOS=y # CONFIG_TARGET_ARMV8_AARCH32 is not set CONFIG_TARGET_ARMV8_AARCH64=y CONFIG_USE_CACHE=y -CONFIG_USE_L3CACHE=y +# CONFIG_USE_L3CACHE is not set CONFIG_USE_MMU=y CONFIG_USE_SYS_TICK=y # CONFIG_MMU_DEBUG_PRINTS is not set @@ -53,34 +53,28 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_GPIO is not set # CONFIG_USE_ETH is not set # CONFIG_USE_CAN is not set -# CONFIG_USE_I2C is not set +CONFIG_USE_I2C=y +CONFIG_USE_FI2C=y # CONFIG_USE_TIMER is not set -# CONFIG_USE_MIO is not set -# CONFIG_USE_SDMMC is not set -CONFIG_USE_PCIE=y +CONFIG_USE_MIO=y # -# Pcie Configuration +# Hardware Mio Configuration # -CONFIG_ENABLE_F_PCIE=y -# end of Pcie Configuration +# end of Hardware Mio Configuration +# CONFIG_USE_SDMMC is not set +# CONFIG_USE_PCIE is not set # CONFIG_USE_WDT is not set # CONFIG_USE_DMA is not set # CONFIG_USE_NAND is not set # CONFIG_USE_RTC is not set -CONFIG_USE_SATA=y - -# -# FSATA Configuration -# -CONFIG_ENABLE_FSATA=y -# end of FSATA Configuration - +# CONFIG_USE_SATA is not set # CONFIG_USE_USB is not set # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -91,9 +85,9 @@ CONFIG_USE_NEW_LIBC=y # # CONFIG_LOG_VERBOS is not set # CONFIG_LOG_DEBUG is not set -CONFIG_LOG_INFO=y +# CONFIG_LOG_INFO is not set # CONFIG_LOG_WARN is not set -# CONFIG_LOG_ERROR is not set +CONFIG_LOG_ERROR=y # CONFIG_LOG_NONE is not set CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y CONFIG_INTERRUPT_ROLE_MASTER=y @@ -121,6 +115,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -157,6 +160,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -178,12 +182,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -195,24 +193,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers -# end of Component Configuration # -# FreeRTOS Setting +# Freertos I2c Drivers # -# CONFIG_USE_LWIP is not set -CONFIG_USE_BACKTRACE=y -CONFIG_USE_FATFS=y +CONFIG_FREERTOS_USE_I2C=y +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers # -# FATFS Configuration +# Freertos Timer Drivers # -# CONFIG_SELECT_FATFS_RAM_DISK is not set -# CONFIG_SELECT_FATFS_FSDMMC is not set -CONFIG_SELECT_FATFS_FSATA_PCIE=y -# CONFIG_SELECT_FATFS_USB is not set -# end of FATFS Configuration +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers +# end of Component Configuration +# +# Third-Party Configuration +# +# CONFIG_USE_LWIP is not set +CONFIG_USE_BACKTRACE=y +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -227,7 +233,30 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set # end of Letter Shell Configuration -CONFIG_USE_TLSF=y +# CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/storage/sata_fatfs/configs/e2000d_aarch32_eg_configs b/example/peripheral/i2c/configs/e2000d_aarch32_eg_configs similarity index 70% rename from example/storage/sata_fatfs/configs/e2000d_aarch32_eg_configs rename to example/peripheral/i2c/configs/e2000d_aarch32_eg_configs index e641de06..fec861bc 100644 --- a/example/storage/sata_fatfs/configs/e2000d_aarch32_eg_configs +++ b/example/peripheral/i2c/configs/e2000d_aarch32_eg_configs @@ -53,27 +53,29 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_GPIO is not set # CONFIG_USE_ETH is not set # CONFIG_USE_CAN is not set -# CONFIG_USE_I2C is not set +CONFIG_USE_I2C=y +CONFIG_USE_FI2C=y # CONFIG_USE_TIMER is not set -# CONFIG_USE_MIO is not set +CONFIG_USE_MIO=y + +# +# Hardware Mio Configuration +# +CONFIG_ENABLE_MIO=y +# end of Hardware Mio Configuration + # CONFIG_USE_SDMMC is not set # CONFIG_USE_PCIE is not set # CONFIG_USE_WDT is not set # CONFIG_USE_DMA is not set # CONFIG_USE_NAND is not set # CONFIG_USE_RTC is not set -CONFIG_USE_SATA=y - -# -# FSATA Configuration -# -CONFIG_ENABLE_FSATA=y -# end of FSATA Configuration - +# CONFIG_USE_SATA is not set # CONFIG_USE_USB is not set # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -84,9 +86,9 @@ CONFIG_USE_NEW_LIBC=y # # CONFIG_LOG_VERBOS is not set # CONFIG_LOG_DEBUG is not set -CONFIG_LOG_INFO=y +# CONFIG_LOG_INFO is not set # CONFIG_LOG_WARN is not set -# CONFIG_LOG_ERROR is not set +CONFIG_LOG_ERROR=y # CONFIG_LOG_NONE is not set CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y CONFIG_INTERRUPT_ROLE_MASTER=y @@ -118,6 +120,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -154,6 +165,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -175,12 +187,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -192,25 +198,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers -# end of Component Configuration # -# FreeRTOS Setting +# Freertos I2c Drivers # -# CONFIG_USE_LWIP is not set -CONFIG_USE_BACKTRACE=y -CONFIG_USE_FATFS=y +CONFIG_FREERTOS_USE_I2C=y +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +CONFIG_FREERTOS_USE_MIO=y +# end of Freertos Mio Drivers # -# FATFS Configuration +# Freertos Timer Drivers # -# CONFIG_SELECT_FATFS_RAM_DISK is not set -# CONFIG_SELECT_FATFS_FSDMMC is not set -# CONFIG_SELECT_FATFS_FSATA_PCIE is not set -CONFIG_SELECT_FATFS_FSATA_CONTROLLER=y -# CONFIG_SELECT_FATFS_USB is not set -# end of FATFS Configuration +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers +# end of Component Configuration +# +# Third-Party Configuration +# +# CONFIG_USE_LWIP is not set +CONFIG_USE_BACKTRACE=y +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -225,7 +238,30 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set # end of Letter Shell Configuration -CONFIG_USE_TLSF=y +# CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/storage/sata_fatfs/configs/e2000d_aarch64_eg_configs b/example/peripheral/i2c/configs/e2000d_aarch64_eg_configs similarity index 70% rename from example/storage/sata_fatfs/configs/e2000d_aarch64_eg_configs rename to example/peripheral/i2c/configs/e2000d_aarch64_eg_configs index 1b5ead15..e84ed0b0 100644 --- a/example/storage/sata_fatfs/configs/e2000d_aarch64_eg_configs +++ b/example/peripheral/i2c/configs/e2000d_aarch64_eg_configs @@ -53,27 +53,29 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_GPIO is not set # CONFIG_USE_ETH is not set # CONFIG_USE_CAN is not set -# CONFIG_USE_I2C is not set +CONFIG_USE_I2C=y +CONFIG_USE_FI2C=y # CONFIG_USE_TIMER is not set -# CONFIG_USE_MIO is not set +CONFIG_USE_MIO=y + +# +# Hardware Mio Configuration +# +CONFIG_ENABLE_MIO=y +# end of Hardware Mio Configuration + # CONFIG_USE_SDMMC is not set # CONFIG_USE_PCIE is not set # CONFIG_USE_WDT is not set # CONFIG_USE_DMA is not set # CONFIG_USE_NAND is not set # CONFIG_USE_RTC is not set -CONFIG_USE_SATA=y - -# -# FSATA Configuration -# -CONFIG_ENABLE_FSATA=y -# end of FSATA Configuration - +# CONFIG_USE_SATA is not set # CONFIG_USE_USB is not set # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -84,9 +86,9 @@ CONFIG_USE_NEW_LIBC=y # # CONFIG_LOG_VERBOS is not set # CONFIG_LOG_DEBUG is not set -CONFIG_LOG_INFO=y +# CONFIG_LOG_INFO is not set # CONFIG_LOG_WARN is not set -# CONFIG_LOG_ERROR is not set +CONFIG_LOG_ERROR=y # CONFIG_LOG_NONE is not set CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y CONFIG_INTERRUPT_ROLE_MASTER=y @@ -114,6 +116,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -150,6 +161,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -171,12 +183,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -188,25 +194,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers -# end of Component Configuration # -# FreeRTOS Setting +# Freertos I2c Drivers # -# CONFIG_USE_LWIP is not set -CONFIG_USE_BACKTRACE=y -CONFIG_USE_FATFS=y +CONFIG_FREERTOS_USE_I2C=y +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +CONFIG_FREERTOS_USE_MIO=y +# end of Freertos Mio Drivers # -# FATFS Configuration +# Freertos Timer Drivers # -# CONFIG_SELECT_FATFS_RAM_DISK is not set -# CONFIG_SELECT_FATFS_FSDMMC is not set -# CONFIG_SELECT_FATFS_FSATA_PCIE is not set -CONFIG_SELECT_FATFS_FSATA_CONTROLLER=y -# CONFIG_SELECT_FATFS_USB is not set -# end of FATFS Configuration +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers +# end of Component Configuration +# +# Third-Party Configuration +# +# CONFIG_USE_LWIP is not set +CONFIG_USE_BACKTRACE=y +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -221,7 +234,30 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set # end of Letter Shell Configuration -CONFIG_USE_TLSF=y +# CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/storage/sata_fatfs/configs/e2000q_aarch32_eg_configs b/example/peripheral/i2c/configs/e2000q_aarch32_eg_configs similarity index 70% rename from example/storage/sata_fatfs/configs/e2000q_aarch32_eg_configs rename to example/peripheral/i2c/configs/e2000q_aarch32_eg_configs index 776a5de1..71713740 100644 --- a/example/storage/sata_fatfs/configs/e2000q_aarch32_eg_configs +++ b/example/peripheral/i2c/configs/e2000q_aarch32_eg_configs @@ -53,27 +53,29 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_GPIO is not set # CONFIG_USE_ETH is not set # CONFIG_USE_CAN is not set -# CONFIG_USE_I2C is not set +CONFIG_USE_I2C=y +CONFIG_USE_FI2C=y # CONFIG_USE_TIMER is not set -# CONFIG_USE_MIO is not set +CONFIG_USE_MIO=y + +# +# Hardware Mio Configuration +# +CONFIG_ENABLE_MIO=y +# end of Hardware Mio Configuration + # CONFIG_USE_SDMMC is not set # CONFIG_USE_PCIE is not set # CONFIG_USE_WDT is not set # CONFIG_USE_DMA is not set # CONFIG_USE_NAND is not set # CONFIG_USE_RTC is not set -CONFIG_USE_SATA=y - -# -# FSATA Configuration -# -CONFIG_ENABLE_FSATA=y -# end of FSATA Configuration - +# CONFIG_USE_SATA is not set # CONFIG_USE_USB is not set # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -84,9 +86,9 @@ CONFIG_USE_NEW_LIBC=y # # CONFIG_LOG_VERBOS is not set # CONFIG_LOG_DEBUG is not set -CONFIG_LOG_INFO=y +# CONFIG_LOG_INFO is not set # CONFIG_LOG_WARN is not set -# CONFIG_LOG_ERROR is not set +CONFIG_LOG_ERROR=y # CONFIG_LOG_NONE is not set CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y CONFIG_INTERRUPT_ROLE_MASTER=y @@ -118,6 +120,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -154,6 +165,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -175,12 +187,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -192,25 +198,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers -# end of Component Configuration # -# FreeRTOS Setting +# Freertos I2c Drivers # -# CONFIG_USE_LWIP is not set -CONFIG_USE_BACKTRACE=y -CONFIG_USE_FATFS=y +CONFIG_FREERTOS_USE_I2C=y +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +CONFIG_FREERTOS_USE_MIO=y +# end of Freertos Mio Drivers # -# FATFS Configuration +# Freertos Timer Drivers # -# CONFIG_SELECT_FATFS_RAM_DISK is not set -# CONFIG_SELECT_FATFS_FSDMMC is not set -# CONFIG_SELECT_FATFS_FSATA_PCIE is not set -CONFIG_SELECT_FATFS_FSATA_CONTROLLER=y -# CONFIG_SELECT_FATFS_USB is not set -# end of FATFS Configuration +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers +# end of Component Configuration +# +# Third-Party Configuration +# +# CONFIG_USE_LWIP is not set +CONFIG_USE_BACKTRACE=y +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -225,7 +238,30 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set # end of Letter Shell Configuration -CONFIG_USE_TLSF=y +# CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/storage/sata_fatfs/configs/e2000q_aarch64_eg_configs b/example/peripheral/i2c/configs/e2000q_aarch64_eg_configs similarity index 70% rename from example/storage/sata_fatfs/configs/e2000q_aarch64_eg_configs rename to example/peripheral/i2c/configs/e2000q_aarch64_eg_configs index 6b410bdb..f08739ee 100644 --- a/example/storage/sata_fatfs/configs/e2000q_aarch64_eg_configs +++ b/example/peripheral/i2c/configs/e2000q_aarch64_eg_configs @@ -53,27 +53,29 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_GPIO is not set # CONFIG_USE_ETH is not set # CONFIG_USE_CAN is not set -# CONFIG_USE_I2C is not set +CONFIG_USE_I2C=y +CONFIG_USE_FI2C=y # CONFIG_USE_TIMER is not set -# CONFIG_USE_MIO is not set +CONFIG_USE_MIO=y + +# +# Hardware Mio Configuration +# +CONFIG_ENABLE_MIO=y +# end of Hardware Mio Configuration + # CONFIG_USE_SDMMC is not set # CONFIG_USE_PCIE is not set # CONFIG_USE_WDT is not set # CONFIG_USE_DMA is not set # CONFIG_USE_NAND is not set # CONFIG_USE_RTC is not set -CONFIG_USE_SATA=y - -# -# FSATA Configuration -# -CONFIG_ENABLE_FSATA=y -# end of FSATA Configuration - +# CONFIG_USE_SATA is not set # CONFIG_USE_USB is not set # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -84,9 +86,9 @@ CONFIG_USE_NEW_LIBC=y # # CONFIG_LOG_VERBOS is not set # CONFIG_LOG_DEBUG is not set -CONFIG_LOG_INFO=y +# CONFIG_LOG_INFO is not set # CONFIG_LOG_WARN is not set -# CONFIG_LOG_ERROR is not set +CONFIG_LOG_ERROR=y # CONFIG_LOG_NONE is not set CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y CONFIG_INTERRUPT_ROLE_MASTER=y @@ -114,6 +116,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -150,6 +161,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -171,12 +183,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -188,25 +194,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers -# end of Component Configuration # -# FreeRTOS Setting +# Freertos I2c Drivers # -# CONFIG_USE_LWIP is not set -CONFIG_USE_BACKTRACE=y -CONFIG_USE_FATFS=y +CONFIG_FREERTOS_USE_I2C=y +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +CONFIG_FREERTOS_USE_MIO=y +# end of Freertos Mio Drivers # -# FATFS Configuration +# Freertos Timer Drivers # -# CONFIG_SELECT_FATFS_RAM_DISK is not set -# CONFIG_SELECT_FATFS_FSDMMC is not set -# CONFIG_SELECT_FATFS_FSATA_PCIE is not set -CONFIG_SELECT_FATFS_FSATA_CONTROLLER=y -# CONFIG_SELECT_FATFS_USB is not set -# end of FATFS Configuration +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers +# end of Component Configuration +# +# Third-Party Configuration +# +# CONFIG_USE_LWIP is not set +CONFIG_USE_BACKTRACE=y +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -221,7 +234,30 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set # end of Letter Shell Configuration -CONFIG_USE_TLSF=y +# CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/i2c/figs/E2000_1339.png b/example/peripheral/i2c/figs/E2000_1339.png new file mode 100644 index 0000000000000000000000000000000000000000..9574b8a4d13dc3cb61450c81164f874aadbc3870 GIT binary patch literal 475606 zcmV)YK&-!sP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D|D{PpK~#8NeEs=X zRZE)gkM6(VjyrBQ#yxfFTUA+^mCf$m_I-y9f&u~xf&!v~G%6x0VvC4~4JrzXVh@Uf z()WGe_agS&-Dg%-)~Twjs#A5&dG7PXB$UkW`Q9I5%(dp4YppqBMtt7qedCRoALSNQ z;lbk?Qj3Sh^~fu#Gexh9D%(+B*NuwWPL$VlqO_`mr5(i;ttc#OMnQ1{9zL$c zlhP)XRd=AIq7C_l^~iZxftz=WkaaU3xsR%lUsTU+14W~&0of{9CMbg#@uCVFn@(77P@+4#=@2O zV)hbzHFp`N&Rfp+u9&^Voy83^7q7z1MXStbpG;kVkH4DF-j82Ul*F<5!=}F~|MvS5xtKpUz}mEWwQVD=?k^Ic?4| zOqsQm-&??IT!h*4S7P2GH~i|8>G<1Ue}-Rv_67fY3a@E8kDG~)r%u8D@yox%fBnVJ z@n8P-XZVYs|1JLVZ(084XJ-3Xf5Y@F*=O2HJ=&hU4T$zub zUUuW#u~xhqsK;nWIZFk`dus5auO2UY>oL|@g}%l@bk`POu)YvO4UbTCH4z6ky25wy z6nyoI|AN2#fBoO^7yqCCC;sC9`xp4HfB84~a_TJXj6Hz6_Y2v+Zeo#(hq(?nj}16> z;yen9Y7rc^6F>X)m%RS3cuiCBi%+IFLg=;~_49EnAIP) z;z{le6zAPWMZrDPmp{T#S0jG^{Rsa1KYfF*U%p0Ucr5nCo5bEo@ap_V9+S(fN z=FKy_dNGKxkxuk>)SR&s?0LmPrsav*>hL0ulvE(BLE9l z`C{(MwV0#(?6L;4mU>{$vbC5;F3fiE!qkQAH*;2)KJyv-_Gj$lpMS;QHDwlmf5!Xr z#aA;X{%00ntIlVbd#}1yoqqAvY;z7%XUxO&S>(jr1(-2sKDjU#v*s>BP;eO9+Iuke z>?JZX(sA$Jb^Q3_OZ?-1dxt;#?ls=L=)>EW{rL9vAclJC(8@O5QdfYEmST(!)#Kfp ze*EztzQw=%;Tv>!G$S-L4BNt@QCHuAr_bKv-u--R*ti*a`6U=08RvbiLQd{o{PuU> z;9vguBYyu6Z}89m_y)iG;VIs|?#D3uQGZ7@UOnx`yXXCQIogHs!FGJ~h@dZcQiI2Z zwYc}71UK#!AoIopT)v)*^sF3YT+2lUx0f>SBJDypQqNq$iIeF#ns^TT4;r=Ylei`I6uJlwkg1)?x$4U$LQlJawMA;Zt@DF=k7!e?DU|rVy5&&vN1ZrTCJsznrt2=i-9j ze8qE`O^7da!&eJjF^i3G@#+n5TNjG8n3_AT#c94^eNx}n$Z5`Co>4D8TjR=bMUJ#=3(~YHCV918(x0f z;1jqV9_zQTLwNFhmh$tt_>_iV#sW99f3;5t*6>^wF89V!9KZO* zFYudR{TiQt@(E%hwxGMI6u*BrfPeaK1pn}LAHI3ojMsyN#!xff3^oz|4H)mP!)SXI zM%v3U+){+6ZN(_Pa}JR{OW;2DGtBt-XZY*?^8d!){N;b4QTZ$U*T4EZeDcK{Y>kY? z?Yt6Px|Rd4b(;~u_PBlL0mSS*hLfi+W6t80_&Fi}D|X;tf5Cbqct0j|Ret@+Gy;C= zL=kMKvy;!JfuDorZeG|CbAZ6Sfjf5|qlo?FNpTHwAC#JM`(7dLwb{-OroWeT) z&8A)Z`USz$djkQ%`(?nP;y_!)f?oe6L*N*LY5eR1gajYK-hsS6(|I{XhTzMov(4{M zn@K@pw)3#Y!v|^SFQK`m3tip)IDIyi{W}LQUJT(i%kV%un(E6?RbGIKl1C_hoP!F2 zzp?5u`r2#o!<%9JumAo%{?~u}4uAZ^f5WkZsW@`@JX+gE3Fm&?&CA2r?_S}b|M@5U z@t?oP58sX9`O^+OA8E%+ZeNXcVzjRrBQzMVhCA^uzkQ4U`N!YlKmX;o7$5CHNN^Am z4jx5o=YRoyX4YMv`$E=(fJz_>_7Y7rS}I==)L&9Csn0KBJ6=iS?Xi9{JlQwA0>iPE z#U~&VenC6oAG`}2LSitN{cPq!chmQ$&XMrpZ?P{=Q9qwf@kO9JVAp>-ApeS=P2n*g zU@s%!z+d}S$1})`nfyI%Ro~NREks!OE*jK9jE}#><;-+sWnaK|KRv_0vJU^@_b>2r zyc0isJB)w+{VO~hZ9zK$-_crvuJ#HH_1AG<8@_+{6hD6Z43(w%h>nUv{Qg5|XlTRO z*egQ)A%a7;;lZO~4350OpfDBk({;)Rp=Xv4;Brg8fEg}}>aBUY_hj}>kN&Pp#Vb6v~ggO%><;KuzcwO?wK zic{d7Jx@S(;l(e*94gkuE~~MW>RHg9Ng!KTt4t?!ZIK24iXc{*LSU-sCaZiwtE;W{ z={Wtz0;*d9ej2}PKtE#%KKo(;8~*})Im3mJS6PB7G!S3RraC34KchO;jaK<38Gkc8;nhp=t~e}~?{XY2q|d7WQS;R|lR`AlBL zZ2X1*|AZ?3v*}B)Xw^FS^S9#@FCg{8Z5r%+B%aPfz?N8g4fGTid0>@S2m(W6aU>-Z z7qarq=MlS)U_Z-_Zou}KJxDrr2I0}W@K?Y5wNdty z%U}Qe7x>vP{tiDU`~~@6{pwfv&2N5#DPMevn5gaOYO2J4`{5=2?eE{<58sU9-P1OL zzJZ_@>>CaA$GWO8*iwS-`U3Pd6=Jlr63xZ85gq78(0`8Uzxf;dAAj-xz|Vg6m-xl6 z`Jcb|6f@?nL}=6=+<8=n#MH~Yjwqa>r+D?|Bb?8;h0|$Q*zsNPOTtp1|9A@90==>? z*&e=NTlQ`)*l z@#skM`@tWqJy3O-~avZ@jw3iAMoQh&+v4x4I}+6 zRDaEAqY|$!Cg`gRFhDT8d(nk|`=^)qpa1z={OdpdBT`SKBk6cL+B=`3rL!MJ6&3i0 zfBJj;@!x)r|Nb9;kAMHypQt8Z;JY_Ncr)IE7h~P%ZmZ&N)#BZ=9{l0Eas2x~yu%;= z{vBQncOyJJ3}?<>Kv&e{x0ZG=7AWYeG3+^rZL}#qbDySE%O%A zDL^xC<|FHN39jBMp*StVwL4|FlUIZ2Jtt_`Jt(vYclPzq2y+QM^?MbkULClr2-+$Z z^plGG&FbMaN-HX#O*`Wu3gw1wiO$L1F_D}8|(djD6ZE~bO&P3-rd+4vjYJ^ z!B`)-2_MZR@aEBlpHEkQ{-PD8!OS4^1XYDC{&%3Z@0}Z?o1zM$0^&`Xe7t=<`S?FC zsytg9@XO-PHbuWJ>p7c1ejiF9c&AdGe)2ih^pqu-Ie#^Q?2SdP>#2f6jD`2`--=~) z@#a(6&Z7r0n`(7B73#0Qq#LLXPOCnh21;R?m8-ptL7TZ?Ig1NisNmLZ2sLG;`+Cfw z8#qfL6?zp4wR|~?#)12$^Yv63xB1IF;j<|c!BGdWi|XglsZ1P5&cN}sn@Bo;3)^-l z66QOwDdGSUPG;iFl?OO=IR|I2=HcRv$7Xxv^fi9>3?lcPz}bu(+@+UQUf+fCx(?(Q z)gmXalsES@?+H6K|68z^q8I2t;r7$7sPw1PbC|OVOWgx-;P^!pl((V2V+;+Q&rnM> zc0H#Qu4_Z!=^u^_p}TSZ>H}0Z4Wg<0xjC-9z7OXz?&56vZFCL1WQT5{;@`;YUI`DM z4cHp71DCUIptPzE2aX)a-+ufle)jQi{si=YL&*Q^?|zA&^Yt%({VN0dj|uuOzW5C5 zeLQgM>Uj)x)#CY3E1D`Fq3FRCl-$3Hs)C!SExd!mdzX=yeGa)W*>>^qKn0=akS zwE=KVLpMUU@1n7$K~(#qXC}ig1Fm)@s0;Kqw4&GAH-pE`qG;H*Z8z@RBS^9z(v>bn zc~u)ad!M0y_%+I^TFvY3{^zJ`>Nb#{rO+VDocT+PSMcRDf_;h<`G;_fwv&OPaEt}H zfMbE8A{ePZ=sW5kQttX(eN~X3w{SUO>A?=al?pQ&mo8_avvU~TJwsIYr>X2~@sD)z z@t?oP|M-_5@DJZVBhY&=+Ea%CdQZL0VkJeEb|z zPF_YI+eC9m9}3GV@sI!f-|!#*`LFn2|Lc$V;~#&A@4gwQI&DK&TP@XUH7ZIUptH3M z&xc#_dbGm;U+O;hdOG6v#NtZUE%XkI8_=g`+{9XXuL>9bIU6kGb&r;=@*&V4qP>3{ z-6OBiJNg#ggKy9|@D}|~e?V9NJ9H0xgZ_~pP*UBEWvl&ozsV+ww=W3!ueep2Hv2=p z+A+?c2KxQ z?>~W$rcIlNS%m3aHp~Tt-Mod%s6tf9AFQ1km4K^a8=yW@qqEjgF3?v5sI5F5_rEK) zV)b1o4)>=;pV{Bg|7ojEGlPKFO;hKby+EOyHCVLF4<75bu~PRTD10xr?K+5fD$%`1 z&tP-ZeyrcT18X;KcS=AQtvd|_6}eR0j5#g_@aqG%Ab878M8_P2Utk#DhaqA|0^;J6 zap3T2`18AS=us?PwU#d7YD}Sln4`Gh5_iJh70cK7Q-SZp{-lezm0yj5st)87HK3@j z7qx`!t^8W-rMixePr+5fwq9WEeu1XGS7;e{gXaF%=Jkz-)kwSckWd~&E1}Uj_!6CL z)a~6*(a|%83zu(TsjG*HKhK)C!l-(Ma6aSpIH9W*JU?1>dIT9aAETyq1mz9=D6Z*7 zUU3tW&R)m5pdD;r@i>>6i|UqPV*pBdo@Io*jxVk4#^dr9^p3nkYtJ*By>x?y&llbs zHskoob4Jm1^bRB8=n4G%*Pr6&pL~kH`qeMrgWf>?SHC9Ye~n-L=GR8efAYyERK{Pz zb=gwHQ(@e`auL~=&fwa`R9sCviOh2+aQXCcQ!b_)!TIEarlg%nz}e&RIC*#v4#kDz z=>BM|UdDFwn_uAPKl?v0W9DqE_M(SL0Ic!ZOf~ly`K686y*~*@PFz4k+YsyT1sVx_ zK{)C3Mf^%?cmndX7E;)_@E*>iH^@#buv_3ep#zEm9y@)yfVv!R9{%tR+=jp{(MY{` z4LyWZYtK_E%nQiQd4jINaa1*SQalj!^OjJYP$&`d0{o|6PT}?|0}l%kZ3S%gAH8*sCw@m(K&`eqQX#{1D+Uyr!m2lyLV z=pSNTw)Gfe-`vrOH}Ag2`13K8lojGq`gtTA*h`4V;6TDYmN*>deM?F@fFlRvaD?xV zAE9E6i^Yi(DY$*_5e5irl{D7n(q$B4>{kM(A_2Boaj3pOpM5a(+*Q=H^rDg8N>lGB zI)`3jaQp}KjebJ`(v61JQ4Br%p7-Us3GYmqv)Cy5uL$?4WRLOWXRF9~aQ}M_*?Xe8 z7lRzGIpZV(y^OI0r~`W$AQheCj+g}W_CLdmmv2y2TZgnuS8*sQ1&5Oo5r5)1;*K4~ z?jr}W>reu=#O%Zts_>l&2a%k98RxTaBQ-ONT)2-%mDQ-}>_y+xml$~Z3VkClOn*C^ zc!~ym8_uL%!m}6eF!r3rY>>=o8ANee8}gqtAcx$!^RNon?-kRtd5p_93UEEQ3^|1j z$ggTgNkcC_n#BuOnKPFShzdk1L<5$JXH6lv)#wa(WeF#WDoI7|(3fhMY|zuWU&Y43 zzLFJXMOsU0-6j>YpT$(R{ft}1&S$cd%-{`DXIa38K7;#oKC{`Vr*oe`KWCvEmb-3% zkAD=c*M4lo^SROe7wvbxOD0yE}Trl zId+QFV}}X#1SBQwMIv3;69@L-^x?hSzYmECF*uyC2SEXTnEC|`%wPQtygdAI^3)}| z#aHP*AEc{Xj_O8wCFwVD?&1y9Huj>SWdM(!)EGs7G$jq6v0ZAcMQv!ovej@~yTNP~ zBCxSx!CoEOs7ba-dAG(Z6;zkG!QF2YF5SLQ$h=@3_ag4_NnE}22t(|E#Z^sgv#Z!X zmzjaOsWa!Wo%8pm(!hK*-2g?!0$pJpfkhB^LNOndyi~tbdU)h+tn&{xVn?4TMl7(e zbX$v{&D+g5z+x9yqvj7CK8~1}c-+f*h~B7>y%`qHyXY>pUf%`{J=THWoXgVzF~qJg(n-fPNabw!RS>wlwUF zqxZ@ZwQ~>r1B2kb&L3+$)?)P6Tr$HP;Q)?HR+q>BQ+EG*AL=UizP_9C0Wi2Xd z8tD0TP`r(rI_MpIjxP4AZh8gsaQcQ{p^@$CCfn4lI|Z!c{cvF$-Lxr;p3pt?kT1`k z|A5i4?=U$0H3o*>(gS}^@8$(M_#2%xI^BHV_w+3W#=k-L@EZ!ZxA;g6$EpIkfU_64 zV8&cp!b$Fq0IZ_@0pFVd5<}C5RQa3;2$y~ith(;PI!COkbd+42copRxpF#@gh zAhPZjWA*w_dO8sX_&TnQ-bG#8Fq*rcp^FBmjg9K=qjKELEks){8*t~4Q5g|C$_9a#QXHFRBH=p1azxfouq{{yl%O{_GijP121fPBO1!fU=(cw`jxR;Bfy!$vq zu%{&x@W+qfG+owHhYuoQ*AB#N3&qYYn-RS^7&}6PabV|mB<|mZ;|KR3eqRj2wr$3Y zufD*vFTX;>_C2_9DC?uxV?Qap9c- zcN$0*DS9b;bzD0>B-q>7u)>!Dkjk|AD=?Gldg)q!>^*)Og|%(SFhwYrOri zglhF1cJEC@bnGF7Zr_b9k+Ikm8igQwJDbCIVLOdO6hDhSkc5Q9GdOkrib?RuEvP^x z>uq4<4Mv`QgNEiF1P4c8`b;YLNuXEKg&?ow42=h>-|I7Zva`sT*(=?!nnvU<#ZdR? zOFSs5q`-;geRzn$=U=0_XPDmWHr}%(m^zn?F`!>$m@}Q=mtYj5#1_LMiBof5W}7@Us^fqvC(| z>TA6G`Ukvz_anw%zQe%qOLWn5?x2U#(msGn3cst@?qeJ4)XOIj-oC+Dywtj;b0O41Tx0i{5L`5PJGYY23#!M8?PiQ#7EVr61+hZTQFzDiLJ0&qDprx3hUe7B5=^H$rHI`&tLa6QI}c+26Fq8VqfxYs=3~#q;-6 zWHbbM{nqNWe&+XdGxR?)By-p?1$y_@o3JZ335SlSBP}D>#F#sVUZbJwDGFI(6;yZi zog*lz>!2G`j4oQXvbs)8<9ENDxfpYoxMQt<2okB5iz=FVL%v08=TlVHb2dbM%hB z!_B-ho=XD;U;JP^99L!7L{c%IzKSw>A&ni+jH0h(-6@3A)HTNMK0_@%kdo?Ff~?Kd z%a-js@axZ};Mbo|!QT<&7WRKfh5t*w{`IGy;ZyGa?DH@21);oX;Znry-iwN&Qq)$^ zyE%LqsfkB%Ht7h`Q<8B0#4&l@`cP0*X9kpa?KzBqpzWrOIc~h% z`9&sGR#{k|PLYbEm|&Sa_$RO^oG@qpDlAyE8VgzPi#_~I*%U#wn{XW4Vh$i^dn|6y zkaV%r-pMO5pr6N%Id_o&uHSOPFgE@x=&Q_Mv<$0O`K#fds&P5<3eKe| zr8%AOK7&JvClP=21Y+Y4BYICf4)Aqi>IEdRT*$nE>^o18_oRV+s>ifNwb|j9-(mFi zkLVd@`>pGy2i%0ac@?-$QE~TS88U9@ZyIp|$1y#r|u15*QmBMK41X_3h z3o6(bW^ALma~S98tuElTPnk++vR?|Krrud>a)$|N&eeO^NC0XuzHjU;>f47XU^ZhqL9e3wK8^R>VGp@PZdqfjeKN8(T&6l#-D+z* z3D)s~#Vd_r)jiU=seR~N!os8IwVcM~tn0|jFQS64L1AeHYMWZo zKk^L2yeGrsUt{$78w@{vMJ4~#WILX_kVS(YPlFqY6|TPK+V!7;{DLK``5&u!{mV_F z%c3P~%rVMh^!5qD#*JYJ-LjqcK9+|5Br+~%;qjAF)Q}~m74;}6tfUw91Ru>`A{U9E zWur7!Y(hc5SKC%au!7Zija$ms>NvCbTJHsB3wps=6=f=k#|iZMO}&2qUVx`UnZX-2 zlMQ~>VnWxP)dE&fb^7UtiyS$4CI%41|l-TjurS%4T{w&+(wR7P*Dh7<&0V_Y;uO`>-?qIE_$&F^KYj)Nv}BdidQN$S;L|Us8mM`C`y>9~ zF;vrSefaPpjvhRKb0?FKeJKsO*%`QT`5YDg5ggkegZN$BP1(OQ%!F{#QjQ=qJp~8% z$0A^Z7v{{KhQ*7QApXD+6tTXpQ?>8fe;g_2uc4}?&oN4b%l-Uv+e}Os_yGl`3xTURb@x8%K{No6yZm zg8mtmWcR=@n%cWi-`0t`=5~siCY04S;&GYg&QzeFw3hGNP5bW|dW8;pasyA_VU&Vk z`1!Z&6XR&<9_98q`k%f>hVMSa`*X;IC9mFogn{w5DCf1v^OeDs2$g4M1S#)}jHw{1(3gzpJTYj( za9XgdhjV#O*CtnpfBjBv{7^Qfq4LKh8O@7UL- zZ^(dOgoh^prKjm=7CjfJh5Z< zZhE=*P|NFYrDt2$)JtR2f}y8h>Pocs(B_)emcQ!EF9kp(7Je4gee5{ELpn= zgJ4uTx3dZF1ytU;Xy?K;pi9+ED>R3dG@BKqqVFq?FW4*QK9@#eA&tax8i-Xi6w6n8 z!_&tPZXUk8QLC^mG6tLJa%)g(;S%0>TC`Q}e(>-P#^$j72J~4}AFYIu%8^r-;l6IO zDL$Jb2(oybIGcqBg>|MeW?a9||D%<3@xT&SFKh_ejpU zwJH{U(11RC=RO=behTY0ZHF6SyV{TcL2D}T2X5Vkl#H9muconi`UbUB?NasaRCs-K zbql#ag%H1;SHwoIaL6cb-hYDY_a5P3(iv=^nvaS*NP~49l}%k}?|()Qfh(d>*T&r#{qJ-m6p7>7@u zM_yqS8e01h9=!)2e>n}GOkp9+Khf(ir<-E(y}#f-7L!3TV=iGCgcGUfQQO#xd-rk> zzjqJLBq!qW{aYx0bO#S^U%}1HbGVXr5*JS$GtfVCJOSyaPvAyo8js7y!<-v55PPs> z(LDJ0_~P{Gbkx*$8#R55*Zr`xp5D+H-S(&G8GVCx-p7`KA+!t*A^Ac&-FT|xS@VoQ zna%d8)JheTwo8D1HO*1+a>bXg@@D((7G=(q0Jhut)!QG1V2oFrn${zM~E_VND2Ctfs}W|yf*xx;(%7O&s^gi0C$i6MpR)Mj*!_B{38 z*{8N5gX1uEF1-qw04joaD`ai2Twfqd>B5J~Ej#n>I%qknW-TeevpTl-IQx&^LAr80cG7|G2CU zp%J@H*kp6$ZZnea>b;Tw6ODi^JB+H|v@Hfn1bIng7rF_00rtw>d{njeI~Kg5(}Z8{ zJuK!8r>be|!{zJuke+qNcoQ1jiaVHu#8YWh@gr#M88R_Xfn9^IE8Tqw9$zeTr^mF~ zpZmNqXAzaj5>G63_2&%^gc}W?-{vS}Qqgp=qsl8#k#`}5-ZAvT0DRYhm)^#fsC@{H+>3~q1a_c2+CJe z$6pcfQ>WvzX){=6ni<2&S^n%RrG3sYMP8wA;1<^NO|*6OA^YY{f<6{Gx3bV&Q-apI z5>yu5H!#o7xrW@EmkIZ?xOy=KcduVUMPV+wTPyKmtOxZ~#qe}@MPNV>va@pxjBezX znCsT{<~*swZ7S;qy2Netnrb_`(A3w5n~xsRTO@QBX*`K-N#jWq%1Ir{q!Uw33iMLq zj-q#ium4tD$jm`)3-3$+YgDujp|SS`jRzI%({EXCUz@hqN5#}f#hP&RG}|=A$ZBWa ziGEA5UE6VOSVF~yDfGGEZk78y_Kmso993@;B>36^x?>RL&tGP;*Z(#toP@Q*>nu7gNEbH#X84-0EiSl(>P<5K>f zX2R3M)Z7gBwVSZajdenmu27?jU_XcTthyG^1$V{krRo*Rnaj_m_TAa%j-{sKPJS86 z*q>^tg3H<8)Q;;qMp4`L6gAC5yqBk5XXW!z}9Q+ zm+PoTsIt^W%3I1_lboD5(`3-=z4=Z4zB-%2Gd})7*buZ8`wr4V?>WHA@nuKxHpj`r z$u-e;)!-J=N-uHogv)Xt1aH~H8+sLw%iGMrt3ZDs={zlclG!Gm%fiKL_f3pis#KuA zO}BCX!IMa)0#t)e&%BMR*|}(F=|w+PZVnahskBT3{K03+&wY)o+j&$Jo><}OPfsD( zDEhU5GA5DcwIG<9b`6a!0~i{8htqt0=)`%WFa=Q!VrCFZ_a2o{F@0^)@D!Hm9(ry{ z&+rRlP%d1#W!@`{wAyEbnXEOJ^|frJuL)DFT^|m=P0=hn;JYCT>jQTpG(3Tx%>k2M z8p89~eK47-yb+CbvlXh5+Eh43*$I(xhq27Vj}2@KPF~2O%5O6J9~9T%eAZnvL2GT` zR>U4kMp(=NERZ5y;R!c(6t}g3Ce2dDW)T~Y#yFIVK9!LAitw36@JwS{_=2FC%KP>e z+lunrRTNjs{0BEJr zEU#@uM|VGN5^}EYUU2vDG48aNPXN_ifPt~RL=zXE7z|YBnloP_WG#Xy9PT_Qr-%1F z4fhBhls2QHWe7!eeW>pqM?qCP>#yF7V<<#%Bq_}p5UF{21{UtlZz^Ulw_p889qQ~uyDk9!0l^5}8i81PlBdq5BlYYhZm-}76<}O^62fWRJtsm5x_^SO zvb|hZdYi4nB7*%=S6_Io55>X6b0%D-Fit;>pOpRJ*f-|A)P8P$B?33^Fpyus{=0~E zJCnaTlgfTRJtzI142b%+?t{WMg1okK7Py*3hzzRqmcB9G=U2x2)K)^J@7cHL8~c{t z`1crj`2(JR^Y_RvslhUOWj=l(2%uQ8VKjkWVGkP$(QAR;h*k;`MJ6ogEc4!nuKC(R zTqT9EkXZ|{bJZ;O*!9} z!EoA!&Qa~iIbTO48-B7_!EB7fg2hX2i)G+lsI!3T|ToS^X@6A4iYY2IF zul3jzx*cIV_F(U!<8%`*(aI_YrFgvChvWJErG$=@mTs0B#QF^pI7&tTu(-j1Udk$; zO5z$}t_eqaT}uU4)zpv1_F>~%R@2pg__!Ly7E4+M0?}xB&t}jD%c>!w63Q%A91nte`=;^4%=uivZ zzUs#JJU(t`4C3MrpoSibjQ3@F8QJ%X&_DhS>e>dWYC4UfYiAwz_6}o+%0BtTX}GTP zz*<3mt)GFOyT>{+8(g!(rR)S1J0Lo5p{qIXEfIThzn})aqu-&RvI9p>Uqx1KDS_XL zwxPGU^SBlnx9Gjm$SVeY;BYEt(@0pCTb)&)w+d2QtJbW_G@lXJg1q&lO}K`zmzS)* zq&}wp<+6 z^k@n)GjF1pV61EEF_XWf?6Ys@8<$_6q#$n~yj)=r&6w8&Lm#YK;}18ljo3z&dYOW% zxpUNnaUK=b;cgz4H^tQuA*?vR!a0|+a?SB`HO59`F@pdX>=!Qgq*0+4PtSO@COJ~+ zYYw*x# z_N_>O>RMYfph>{%-q`yz8Pa+!NULa{Rr=zWpsLq8PM?X1Vxjg6{x%g;ul2bYb}92Z z#-6{$0ENhz%eUbZ9EHX7%;S!v(i7>&^Vi>@tg_As5RGS9FHc2~_oFa#<+V8N#{s>8 zJB^XfQLm-y7cN_di&ruzPM@KP?O)?_zCn@nnA}ahf24*Wi!ax285`4*<#YwvpagN1 zC4`OCx8Q8cLKhkZ!FrV^)=+_O-4=-;S|l|{mF0xB8l@VT%ZfFok?902v|VUeR<2rW z@`Lv#9HYydjG!$MRHxCbILBgHt(UXJ#Ty}8<8bcM9lC5oCLOSQ zgldANhswHh_^rtWzyG8b)s4MQ+_9eun~kxL&>y7o=u-M16=6vQjRIZ4z~JpzMd&G{ zlUG>DN_%NweBxXN4kVt%(bP*wpz1l2auF#Puj4Sc2dU!ZC7evTglIPU<;%QzWBho7 z!l;b);_$IEJkK529u);o-+0?0WyBDvd zY9f$){kI|hU>b_bJJ^}nuse7SoiEYKZF|>Cv~|BC)Lzm39>B5F8SwBAHE!V=zs)8) zNJS7AdE%xtE@vB8n1gMRU{$*k@TIye z=+&8=!7n$0emyo)(cgPmNw4c0ls5F^a4J==GL)Kz(DU>=qwsG%qz9qNS%WVTwdE@uMfzboqBvZF{iq zu{{vZDtfJPA`OzR3k=7}vsY2o&|`$ujeCVgxv%mJ#HKB~%rX?pxEXo=y;1zW>=SAe znu{_+NfC=25#i$(iaq;}oAEa#TbM!ERqI%1WDV86#?o%(6&eLEz#mLbGviBoFQa~l z0&Q1(BFbp|pT7D5dBs&!^lP!&YlBhsiUiD>0KFiuI#=e5?zLbl#V=?I(iWf=s(NpE zWQ~AT?Aj-u{W<6bc?ZDD=uw2Cs;1ElywPY$>U9hb~&p8@VQ=a+lwIT;7Phq8dD8sch;-OYaz}ntM>) z(24u}JYdr{W4tuW&y{M>jaJ)*D#(R(sPoqKdGdPwH*O&i_Tgw!DguMH@>=AjxU;Tl z{8(SAb9pZsL~s?**Px9myr`rxEKLq)H%w`l&X1xvgs*M%ZwkjmjlXZt6;3xbpua z=ndsQETXD;hFf=Tqo6P!|M?$(#DDzzKjDA;$3NhAKfc5p!hB?~8H4>zRPb#W;`aHo zZhZT06uNXzr#L_5w%fxdeyrHhJ3hRP;(=)r6)U@keM} z_rQZ5hT@yE%|NC?BT~w2i|kknsEk$j3Q^3Mt+^x;8T3Zk!89PN&`r)G8T@Yv^I@F6 ze3u?$DO&noqjTgPntGIxL@$l^qn@Ap2Su2H#X0jFfUC1w(A$g&{l4BCz!UVwxX>+M zNJF%M=e1B-Z1RTLS2T8}ek9Nf;)1#cVHKa(@fP+1y%fI0mDy*m&FO0jS;&5Ix z?rS%gF`+vIXM5jM<6$c6rn0UBw{r?nS=(ViuS|_|mu{Lky}&NW&nI-}F4lY*)sHW) zHxilIc_!0F>RoFK3Gxch*szX1S2#!6TR~wl6M$!Zv+ifn6Inn3rwNI^RIZCA(h1eK z-Kp-S=H*HF@Uur{b!J>i$qh$OUBo4N$VyXIJo-$=P2QUuXy~L-dHKEZkQY%bX?)9_ z!p$03-2+F#FDH~2n7UU8Py5W63B4l$+=*JS{#dtysn{ikS;(u1Wlq19hu{q83i2w} z5a<{U$VTtlOHQ<5AC&pfhDU5Tf%-RiyD%wmJcB&6`_W?ionzF8ECO_Ny(dr#^2Wa zr3&w`QK|vDt?@Dcum9HZHswsm>3F@@dAO}vXIvOrV8uY?S}Q9;4bgvNxKUGk4eWIri{J#7Eg++;pOAcI${TqS3_WH0k{=xz#0*kfn2%T z3vQl1SmRBouJt4I6(jbYsE^g=wY)1CUN^$Y!+R6F*Kg*vh2g;AlgPYw&$!f=uin9h z%eRnvF3ZdS&7d*6lyx7cFJxoa-bAwmfCj&!b{{sO2dUDH+je4enBwn>!VHF11*EA4&A?vP5S*~g8H{)Q6-OIoWZp!yR zpLx^V11-)dgRQ!@ptp6e`>im}matvycm4*Z+9%^I{-`JC*gc|8%w*EQ)FeNX4Gc)2Tl0s~N3S&hE2R~UN!9h8ibcIBQk7;8Z<;20~# zj_pbSuJWKF<94Mx)w3Hfo}gdq=9DFq0H%f{XbaXd4CePH)T#E_;s9{1Io5*SWrefK z-+ML7bFjzS%p3ilJ3*rxA~!}^4O(SWu9+2xbui^=V7eoZ@cri^Kc{qrDC!L ze1i?>y{N#~1%#M2dE|!bynG2|yGGAmf-d#KHC*J)RHu@vO23+8;-<=YIB@ignWk?# z$K8Coz{MusshPJ?afji;y7Ug*itW1-aG5GeanAaVK`PV%dNO6$vG1ty1a{E#(d4qb zd8Ksmht2H9*7i=+R6apL!F}XE%0Y2SEqZ$C{`WpZU*9+?s#_5ey%(_wiKwV;M&IyL zJji=Qm-P$*k&6cpbC7*A14oa=BkA}dWM^lfy!;7n-nxp@r%xg|IT;U zVbdi_rr`CeAF0hLe4{qDlJ{C;L7M!gG|FZgMvXr$pa-cG#^tNmQ>AY=;Y=y|!O^$I zkSb2EVnFOdF-Qn&t$$_Q2=K$>-mYW`=Nb$FP7+j8`VsB>T`wjyw`2yej4ow(A!Xqg|P*>vS4(K9iWxk zmZ;EYD(csYSd>;ZP%ykf6Tz#H@zB^$Xz6^3q||F>(LhavvqnPc=N9zVE1W*VnU!ln zuWPVgq0U+3nk!a&AS5gdH}2<}h0%IOU!Z^dotfA0kyY+S(VOs$hf%bGyox45sjPIT zsuS#2Q*lp}6@;Y*RCT)G9w0;H9DkzZI)I&2cIg?5b#GM(B9G zUh5mk_km`WI{{tpmSAX$ep8Bn4Z*Ks|I1|X5aufGo?bKzire{26oFn74LtZ8-URA8 zc>3^nJY*2OO-M>AJ$P#*qId5%arTgHQP>)>3tOXhoAgZo;BahUqw?|&gr^t(pX$kd zwR7#Os8EzWq)8bvG%_e&zJ7$YAnwOwoI0`N7`lGPgR+J~v)}wpo$6Yg-*hIWslGk< zpPJBh;BX2`*>Rt}{hi5j(14iSWIKUHscr@34QQw8)~bJ+IjE`ZT9m82p%cN|cbkl& zgru|R7-R#aY8qhU7#RE7Y#)`@86|%x=^XACRA7v-d)o6H<&TR{a_1sia!#Q!Hw^{X zPnwyo85b_0Mj#m&Gv#Pv8ja0qw08|s@ekukQ6bJ{TtM=L(*$H9_8-=|DKXd{6@l=G z?TCzy!p_(|*d4deEYfxOa57R-E+9Sq8gg=;pscLP%qSe;b(B>$u@fCK3u9H#5cdr{ zH;b5QAW+vg@azp?Uw~Eg+~k28p~5yU1tq|n@gD+EV?Vajr~?VU^2p>VT)2GOsMfr~ zI^+~oBQ5hDB4dx5HHDPB9e?Z`-ybq_90d6}i(Lst2juF2QkME{^O{==eL+TEg9M4d zt%29csg#aNcYoimY}Sn(cy&?8j|Ra&pYLT9luK{IHwpt0q7o8P^lF0=Py*_18eM^M z@cB0=scmE31pbL7Zn*)yjEfl)Smk3x zi9$7s%M17eJbw+wD&114mMYm4V)9%~!T{@7AyC!7psstXI@f)%_dxZpdm?aJk52p5 z_rxECu$`E=Gx#bsZ$U4SAlNHYN3rwCptk}-{d!mI0o=*ShgSYnCSQGXAFAp)*&m*< z&VEE|$0!aQO62iM^L0W#`VR;83LQCVzdFA^2ffZ!*CRuv{|XG+g0#z*>3MdcsjJ5* z`+ENG*qfj5k)R?_D(_Z6a`W)UYC=v$5LcK%Matf&e9eF*Xf(M=Yp*CA;Yu(n1R_v5 zu+o5}U@LFI*=nYkeXpX%=fKW^yo`Z>CPk}3+6^1G7^|xAia_tPKG=ZXdtH#(dUBug z?#=np7%1G~KB4esn6%HGpm*o_x$~ObJ)I)RuUYHMMkSBHhrpzwUB7_}c@rTlgQDM3 zoyc(c^1n8ihe)j75W;iV$YW`6sH(mA+Si1HBAoN#e+$YE;2p2SF+k3>>c91$`fvOD z7W7VWRKEtq^Q$nse9pW$rODQ7axnilFzwrFyg2EmlOtEuRvb?pZ9 z0(%jGsI^N3eYv`cr!QeC8@6CBsOOi}<8ei!8QhfOt8VQ#lcmz=4tMpB;qB-+TJr9p z=Jp}HEIoqni;v-(lEe7AG#QQeQgQNN9L^EE4J~~b9({$(tM}*`9YS?YBZjEx`}+G) z-c*ZQ^a5@_x{qu3a*%%Q1|e}7C(m5K8E#LrT+X_U+XQ=QMKhIqznMYU+dGEg;a3=a z_6}`?Rr0Beh}(b6ERv;g(GcO@);YpXHG)1(fE#~7m%f{T2{c(ua%}~CjV}rIQn^c& zaYo1q?&>h=JR10yC#41Nlv^(EMRDl-l18(Xb5PhGYzWnq`)aiGjGN9B8XaT85CXjv zy?#eh4~UaQV8D0~-+YiNk6eszBp&eN)_8mp1A-?VKf9u?PO^!c|& z(JQB3pcmwANJXI=Wy=WW@)#v3Br=p)qk%sSx`u9#!;U>iapvL;oK3%ph?s*WWHW;h zoJ9jWM{1d#hti0ZWv1i zFEEJ8JOut5gUx5w3(z?V^or*T^a{IZRlYU+eNFO;p~{Hae-u7EALSi;=zIu#x7Dgk zc{k3rThPm>*pQK{Jf!!KS8*V33cVb~7Mio7{2|NpEC=?G*I-6lU9(iwC+F}j+mNKtY{5MA$ zgRfb#`6YEGoMHw@31O*g4Z>>a0)=qaZ`@9gEcJcXjY5Y~`AMl6X0nvjzQ&Lej-AE2 zjp4?S2=WH>EUGI3Uj5c%-6qzPqvG{{%3ji7to~Q2oZDj(Oq{-vZB{B?vt!qXM3^K4 z!9AFLA?aMEnFFHhSjwXNpt@I`TO%$&syJ}e*xaAOU!R$f35zw%0;>T2=c--B&WP3L z7WOuDBYtSPo#JE!9XyhRtn0Tad|D}XdU5J}1|FByvY(IQBQ13*plUHBtGG>Ek4jj; z6x0<%T1y41Fosqx3=Q95;>LoVuir)kLn#j%x{&&?kXKPQj`piDtKsQ$4c@8|uO-;s z-Kng#LL=3xK(A#FE?l~1Dkvg)k8z`H*hawD0ITBFIyVb-1N^l#9uwsQr1{--{(k~_ zUw^4`e*<2@Uaz&!*Pqw9ZbH$ssM3Ab1<=C?Lcpdi2-+NGZi=A4ea9XoCZ}Qlk(2NV z2*p~~g*hKDf75v#HLq~YM41>LkawXljyj+9eq{VqFLsbxt9B}crYYP@HEyBze67JH zsX!?;eOKq9CxmG&eZ}OZ;5Fza1?970n~9-j=M)-Oz4z%`6Q4hqd5iEXMP*Z`QFJHR zIRyGmgz+I>Pa}b<0WA&4Rn>Q6fWKE*+JM^n4h#^~4FxyxtoQ<7`4Q$_xcbd96E&?w;$k9K@swbN>JC_VM04Yqu-)` z@GTme2GQ0&j^@@8lvQ@1u4#bq??v8|3Y@)o#kjzJ{vm85%FJK~Wk;1~qh(@`P}#|# z6qnZ{DdnO`3k(X4#)i#Xux?Wj7P=@7OxK;TpTA_8d9OIVvLzIUo!sH|S_W32KS^&# z-ogmIB&`6b`c>|JRZ}lw5>jyPat_-1X{=soW_BG7ik?|aW5M5?40?rf&E`2T)c73x ziDph~kXV4%|H*ThoX#ngpUie@;_%~N8_;VOw`O^V(5n^f)2`kzp&W&Gw0@K_Zgd|M z0rA@#?T1B3NIH!GwoRoXpQD$&EAA+n;ETEQmtyLyc{Iqb*tvV3VX$3)Oy^+E zW8z$Ojw&BO?--pm6ys4l;>?3d%Bx$kJN_8_=?Q6UR!N(mvjeCFmVPsy(#+I-h{C_HW-w-p{Y7{*oZxz1c_0B-8ybHTk2uLw@ zgL0_K3*6n+cNzhBt zD^_~!WV)FRC(ujXxAnaspx&XmbId$>Nh=Ua(aD96+H=G#pRnsdl3AdusHznsuYRDC z@1`nmGmnsaK;_!kJA&s!{iw=G!{FmH__00>Ka?lpr}EA2ydQ??w?|xPHuCsnaHx4s(c5}F?y#{E@j+B_RV~RN3dn6}B&OPeM1jJ8E-RH-;Ldu}Sda$3`Ta%g%v8MU7*bu18g{3Gb`-bV zeGOXr1vv}e)zceN*462Y**Kkk!z_0&@a#KWzgL74XRc5&HKK3m1@fsjbV2K$h^`}SZ$^^9~Zk4=VD{Q05k%7UHCNW@$0z?z0QZ8hflu9k@ArDpF zsFDpvUVV?zm*1NKXIEZ>jHtk_!BoY-on@h=)HT`3F@!eeuB~8iRlQzYz^Z7!j#C<> z9!#RaQyZJNMUdADnAQ+%BHN^{hsIv9p2tiA$Hl96u{kmhXRh2u+sJE^MYNg1S)PHO zkE^sv@k5NzZ>UWgFGHZG!I=zr^#@aUj}-D*N2W$Z?V}fQ7FTXOLfDS|WYSgyZH>i8 z8-v44p69mhROyNZDr`eo+0cpym9k>fQt%r?!p%y6i6_tEc*;4W?4>Gwsb&RLLDrMS zTXA(|kLY(;1b7uSXsLODT|k#Rs-h0Cem#u_0igYwrY+c;j=|q@24@woR}6jQ`=a+I z^M;MiogRUXQ;}C7HLe)HK(8zp4Xk>4^ZcmnEz~E+>s17Kz1P<6QxWVH!Y-5!HYp^@<7xoc8~CVeTqqq@`BgDU|ph+ELB*uiOmUN=)QTC3`nC1l`E^==o& zveW5Jy#BqScZy&y<+3fp0evMExH^{}r>6lisjDYtP3V964z1necvRG2W-jIx*5W)B zkQRyx<~69}JgI6z=B)?Ze;W^qstB+KlvOpOxTFC$Zau=lz$nHBdy#+rG#;Ig#oO9+ z{7`omZ_7{NdC3`!7G6Zbg|kT5wFl?UUq?+t7yA2Ont2Lqyf&JpRhQ7+w+3pZo5oK9 z%){gT=zaKVZG4|#V-VE2=MubX#8$yrS6f@{w~bx5hhKqxogM_OlyHR8O64~aST2G!DQj& zJ*h!$OTUTXYv!{&4GVhZwJY;w0sm(XJMogGuBQD9_!?Lh#1&>yoL#Wjd+oQ1UI5qD z#Nn6A5D`AJ7dwNr^7?qJV)}OBvjsF>>gL=Thy*c5U58)ftsg}xc!ZT9Z&LFMcTNN*3A;oXQH+oip9zrts^re}zpe0qhhhF01 zwR=cR%Rdd!tL zd;T_(PG*?OECGdO1Z!<=NJov_0luSN^jgQP=YQ)vQuN;5&UdVeQE@y2y(Xx6jEV=9 zzdEzhEtO{J#KUzCPL_(!Tj3sccIEiXh{f!QC$t^FD^z1aZ)5ki7!^-rsT)eX|17=^P{5QL__FD10^FPMQ^f~{x`69RJ}ki;MrsJ znUig!j1O&9q-ZCv%QCrG&~FKkMMhSxQBvw)Qd-JoR*YUV5;Zt0<)!_avAA}_R^z67 z_yr+8@f50>yQqfVp|PtUk4meM`=s2&^@piM+B*7h<=SmDG__%5a0mtWZs5$pD3sq! z#9-+KJgvNn-r^g0a3L8->E#_dn23A%B?O@!qTS2-*lIeffG&Wq^V@>JO%d44^9ZBs zzb$+ZwuZ%0(I=RF0UNiQ$!2rsPrynrV3`d0$?mJ(s~&W$JRNOiESIhHYyudAh>%Bg=sg@=m zo{%<6BhWk03|~7@N`TkmXC|hv{WLPVMnOs8A}RXCydEvdt%2BitV1b!E$pXtZSo#h z^8B?l_j9vUhqiUC{m8!e7-2j2o3vXgdkt<1@R}`cK`-d5eaVY#?H)q`1%VX3V)7ce zR-03{lCo};<)ul6ny5E@9wE=V*76u;Sq;|xqUBDW{@g_x%;tSwM(=B4Oh9?`T41e! z!b5rV56kM2a`756?mR*#!70yF$p-iG%Z%qGqkJ^^oC&?Ty8D>>JZm03p@pnFmldXu z2L^}I`%=oNK+VF>?iV13hUGZrx zy0c;9W*UVcCzqR$Q(WAJcm#PBL0YgDz!ig+D%U>2U70;*Wj!`wi{9KzAHsOSmmsb?>mH769KS1dkwi=GWj?}f@;1EV%Z?-&683D5@^ zU_15V?2|Fv8Xj$m{mh+)z>U}M3>Z5ek?LVG;6IcPF?%U^ts||_jlBmdx-Q*76sMR@Hk!Uuc?ZZe)$Sx@4lzn>&4lNml3=FAaWlSVPJ@0>*&SROBZl1X+N%{ z?#J!Rr*P`XVI10%fMbVGm?v^owe+HcM&bIcJ3K!?S_n8P+2gz>DNwC* z~AV-LrD#a zMceui?3F>JYck57^^pSID0VY$(a>W&91|L(*w9kN_8}z7@VZ}EWekQ?ynf4O`Y4Pe z*sGWnPI-N<^j_EanSofXtE05b40=q;nQ!fXWn#*;)EEmF?c(T${t*vlKy;HeaSSj0{PamCs< zZ`;nsu)}292=s!y_6z<}^fpd!Gi9{zeYTF2zB;Ll(8TpR;jK-^7#R3#4#NKi@~S6W zY>xeV(DT2Xl*S+0-%ZYxd987P)RLSs+kWC9!^C8 zVbClXPzetZ2x^3rOFtWECjsiYcH{d7Zo#e2X5l`${P}TqYXHY$vS3&Qd=fFXftgG23J`DNMGG224$@uYu0l(Ky#`^m&t%-NXuTVOUPeRS zz$&&IdEM%}wqE4j*lSkW=YplHjrVu+?qh=BrO6~x(IYbzLmwV{hw)cGV(j&gyw7iu zl6Lid2uF~&#fEb9P!_c>sdvTXZLD5{vjV(4NG)@nntt8n!8=PItTb_X84&%B_9s9)bpDHTc@pJ%S#>UJp%?H}ddtmC5qb z(j)S2bT6c?6}HphyIxDx&snh8fZiFqQAUmfd9|C#ZA(S_ZBaY>5Vv>2Whycj`adTE z;zT||wnQ4x_YOTn{LvKiko_w+X|RT0n1qLp(RXNNdp~si%tR=N_mlTZ-n+P_|CYhA z=V9Bpw#qgO*%EDzSKm_jva+Vtq!V z_7B`_K(F|-AZJ55`g}6L46s-Pa;bHNZ4{mn=#^C?HLd|yGx#dy%kN0t8--7JE9*w8 z#uUDmQJ4&R72_H3cyla^JOn3>{b5F`g{Kq3;W=(*SGQuk^EQu?~NDl!VIy#lD}qp&mXn3;`eRtQ|8*ylzQr;B8xSnV5Z9+sk+ zi(1icK95m+)SDh!7+uV$m_67@u&aczZURGjzxkh=Hbo#ZVn2>1UO?LAd&n6CzNHfU0d3qibv#33=O}JHD5PrIPoQaFZ885#*&m)J9aNx~%INAFH?SF^ z8f@oxO3Ip0-`I=3ftMH^`-X~T_j@I!A}FhoTUBElzwH3F6WHS?gI-1ZCWm(fbyH~U z7OE3d)f;b#=c&5aBP4h3KZ1;#xzIC6D;v7Zlz*iPO1V~0$!feK>&8QqYpwxA$4hVq zMFnMn*s5}cZWLqJR&6~naEl35Dr-iDz^pdO{dzB>pqRYAC(vua*sg(NL9g^mYfNMu zTvvG-u!Kd#nCsK^8V`^~s@^mVBa_N3ZvuSn*E9;EAwVC z+m~Q0C@XBE!B~ZGr0C`0XdFoOA#YM48;Oc5tdm{)60tRUKQ?aNWxgW=q2E$yW~B!O z7ZvxKb-@PmW@!Zt!cL@CY79YMYQ&CsdeK|h|F$56ZAW?ZkIL#%(b#3?dnk)cvH3H4 zfc}{bMD0p2&zjKvQ<%jGV=0w#rSWzoN(Fqy)-|9i74D4LXz*3w{*Z>L_M$oLun_Mf*Gz($V+%-b>1wa97zt#o^D3*MO_k zjEsR*>5AR2;%~25xyGc4Em!K5Vyjf`ZmbA*0i0XCU+L=M0DgsBU4=57t=83Fp$pVG zQsKDs|2+v|Z~m83*w&e`2xaj2BXHAZ1chufYji7z)nn~C9!o>yL!;y+Lm>}m9oF;s z4S`hq8}C@QZ+VQC57=dE-}*-_Ym1W>7t?K}3H2XyFp07~0zBjleH*CX}p72Ld2fI_|& z_=DMDE!5Sp1uk_m19laKTU7XZo|XodD(B}54FuWv*#Q<2Af_W2Rjlk9L6gc}5aj-4 z%jgjiEDQKMiqWgXXfSpq@7IQqFq3xpxS}3Cqp!?@cH5{>FJ8Ter>}m(vp3F6WI<9P zkPre*%Ny(e)X}A~weXlGE(zp%Er4s4Nwwc~6i{o}HuUfi4cw}|D|J-I&6>T?4B{?z zaq{D}z?s&z(Rwx({91)m-hj%Am8;E4mGW@acU4#F+;$*eus18BPI!NscX2O-jS&?Xg(x!?r{?OVtbXg1h4EQuBJf#wXZ#G|HFPGR1|7Xyv&8bcovps2{LJMFS6B!5bM`LXgX<9da%Cvb# z#Kj*>#O}BR#IP*oy%FfYoVCb2wJtC;65j0d3(2gha~AXeK8O?j{_MF<+qcUgsOa1T zbnRF2!H$@Cwpkf#`x3M43E|M>%EMV2|-PG7WSNVoW>%yg+(D`Gl5O7$9gf^I$n{*rwrbgcp2sYl&)=Q^ zy_u9op%An!3OA|7TKh&#SU_P6jd5tKLtza~OjBy2)`U@TqQ z@GHzRhc3EatNqA3)jq*mp&PY#c>p#RZ({ZYv{m?0`zA|>#f86ZAukVix#{F<*y)|R zlEJZ|J%L^^`ngi11gMsFIDYaX+d-uEt>)hj+PWv}{Cs;`WpW@BrfhKsxb7Y`GnS-z6qsH-o5%RWxtXz6ji zR?(8tTCP~YU$xqw{a_!GPG3fKQ;(^8jUgz!^zxhEUAEPE`&++k=@w&HJcgmd#+1N2mdG1Nd1> zOy0bT^SDcec0SDFbvz1Z*#r#&3+(b%mMqur&;Tt`mX4Dlq%r||DSAO@9aZWEmH?{S zjeM^evi?|07fbGt8nKxXYvTA$2*QRWR1}|9_(H{G;}G;Vl~MrIqz{39oJ#UbOyowXbaok#41Y`l)#PJDfS2jwgd@uwitTWLG1oHRa=XKgnWjl)fFLh3x zj|P&h5wb<#HilxtKX%mXensEJAK9%=D18A)vsZLVU+G7R&bl-9uu*3jSMISB z^rC~n(Yok&9+sI$9Lm++5E_MJr!Sg?%G3$f0ks~#9>Q{phT-DnZ1fN4Asv0FtE)z1 zLk+4bOHo-?hLZfpD9bNE{=FPL%Ds=)rgl_UR-mq?6pb~HQB`~wIX5ri?yW4Gq&IN% zcnYpwzl-j^5e$z#$DaN1n9Ghfn~K!UCjgOq5=_4H!;)H)yRG$BwEnr4aFDv!17S2# zOW=E{|84eXZ?ehaC_)nUzC z1-75y?K{jdUbb9WRyi^a7K- zDS>_o+k@iYx(=y#O#)MWD~u*%rtpo{V$pKmf~zLdDNLiHWvsO>j$P(jtDR~gJwaU) zqon3FFsmgv6tC|ddS%+1(tR~xs)hBGO{44@qw1;L1#>+zP}x{|*vMqiYpX$gW!=b# z>ba-Zs4DcN?eo_^8IMGsi3XCjP}{|fn-rtYYPbr^%$m25;FA$&T`ghzS+LlQlbEOJ zX{iXR`I$53VFBxR74MzEZQGhuwCdA_Qzjb#`&#uZPRc;&Sb<(3RszM{+yYeAG~@35 z$7WKe)VV-EeI5-A@1-DbGot45_cVB}$y#OxtY9uBFGbH{*SfLm-PlF=^x6&t3-Zb= z()Fs$p0Am;%JH9%k2J-3B`vD6hWZAq_Si_s2eUzJhU;ota01?ojbjBno&i0ryTIkZ zUa5xx#wAzL(@-=(5KOpeLX&`~kd2hBiiKiW*iN&4eMICgvy~baD5Z!6dkbN0)j3?* zDNF{?`i(pZp2eiy1)X{|WTAnDGXsgt87~v}DM%74QXm84f3OPe4M()Aoj;bqq?jFZH=|)Y%W84-2*g~UPXC9CazvSjjdZl z>0N9?%IOQv0%r6GHf;{Ytodw+RGD79?sJ(p%;1?ie&^5&v-XabI?y1XI~4J{?CACCpN`V>jJxly58G;f};hc+J^*y+Jr#AbcvRqU>jlkUdA@% zzj?cP(wGL$v}SvH<{h(yuT-!dyu6)TWM1o>l>#_V28OCm%PQ#JFXL9AcVO4DsBZD0myCzAr%{^ccB>4 z0H>C_))K@DI|-EXssu_IUF{P@Z{$2N%T}umDLY1Sb`=ezO3^Fz@>XuKnfWT%D-%hB z(|WCag%!;vnN>kA|p0U7(I#%!fx)uiC8>E$6Tda(yP*wwzSHpU_Wc- ze9WikPi6DtM#GB)>;=8dU<|y6!WJJXt!p1E-u*xfd)|GB4Z}v)h z0h*ws8LOLuqp@Y%9)yGv2+;?zW7kpa-g6wWamNYp7{YxMmGFiMHN4J*Iri>7Y*r;q zN;-q26Q_}K>Ksm=xqy=?XAz%p)BxWoo(TYJfHNdK8lh1;5wty$4KN(*3&jG>Tp{k;|%Ec z965n&_wteZxC;5j^=NJz#mLj|@G!3e`TX6H;iq`=Bp*-mb20w32Y>(5D}4KM5JmU1 zad3AyHV1g&(Ei=1tti2>k#2nRvJ2mg*WJuHAfy-FuG_O3JHtvSXAj zW0VdXw2Dz#bN{bk?|@!KK%5MEy;fX)1=Xz)A8fn2e`^T#IkT4Xb1j?g48-bOSMzgC zWNGRgG!tE<>NUBjt#=Haz0b@!E8HZ=O9gKXi6F%2;u8uQm{Z$bN|*=+g0WP()VGQz zPYLn@w?HpNuj5tJCIx%7OSMI{Hx0VZod^Nxdse(Sz<1|9eMjM%4@PlvOjq@&^YUb0 zJe`(>I(mOn!BX-H+uXWGga5b^#e}Fpuazs6SHI^_vRU0!>fO$Y)y!EbdX4+sc~EN9 zy9Qvja;4HKHAzY#9L*TMOR>>Fk3lP@9!@@Q?yKOfM+92X>)Eh^y&edz_g3i};L|AR zJ9`hDFy|#fpmrkAE6k@gkz|~-Pu`%8scY)ybq2Byq{f#za3|>JE|@3;{X81YWeR<< z=pijq^@9Hr-aiX;)#2p$ydAK$Gifz&s<4UPOU!BD)ft?1(jWzU4F-#oc0g2MHmaPE z7U*sGM!=uVwktz0ouBEL88e;mj1AxDe(L+$XZwPVbIy;jUrZyz>zqA*Aw?1auh;Zk z6v~r#^U<=^!Ej%@)p_`I;7$Z@*@x{rj^beAd0e=1$1G^2C(VRK(UtQQ?CE0CS}E;s zV@M>TcOGUrLdYLN+&;SRi5HP};Wn~wJ;8-bx4AEgs(%yKPziVuh+DTt;>ZymcQl3W zei|~V^6uq4M1Dar3X957@T45s*>@36*V!myLRqtScO5v0==}$fl71Nv%PMg4{AEP$ z-cOa4P9p;6X-S3>hQ4?^Ju-1u{Y@M9moB=GCX)# zj}rABV*svllU411yx4TkB*EZ??EogOAGMbyQlcKfB7E& z^t+dM^Rx>`_w7KydM_M4xF1c8H5lw|!a!#^hT0!vu>B!g>mTqpt|4S=Fam=^%nEv) zJ%fbE09DLd^Mv}@1g+=#AhQ6Rl%3WsIdl02jZcADR7*xH>C`3YK_SYzuxp%52EFZk zYVeAuTfqORqIbYPS<&mYV*pl~W99X2*%F1|V0v8yx|IFQ=~`OAd3dyG+cb`z1buk) zUR+|m_tOIzd`iX3t%|%Uh0Qcbc;Zw#jvPN@yxsR{oJ*bfxmJ@j85sh)l$BBUA3O_t zjtWgGv|~YUGilW3)Rs&yc8KA)nP!; zc9VW6?@2{Zl+yT)CQ$hYM<8b3G4lWy885}cl@=+;YaN{R6j6e_23GY1G8HYaAx}~< zdQFbfK&;e!FO7)2wiZ3RcVOHse;pH_Xu>dN_UpVAM#ZZL^fPAB8{t+;UXy<`!EW|k zUIXE;Mb1>u3Rg)e$0UtQm27Mqi?()#%_wpsvBj|A1ihSO&(;PpEp3mvt~PRR+vTi#Cij|7Y6RU_ZIl-Ba=aI6}>_^2KM}(4cn;b{FJF9qvI^9 z#?NNYr^hhQJS^NS^|6qKhhB@GVD*uUXE4^R3rE0at+9R>JL0G$j}o3)4@{VwMeM%gh(B}+XD?*q(UTez`|Tj8hO}7K&^PS#FH9_W4Lt%S z_(w#?;&}2|97{Tl>o;>v46CiP55rGi5I`@fG+$wKl#Qgd3o*O*nFcM_==hm5T)uS& z70s>a8-I?Q_w&s%47UgiJ#1UC)Tf$=P~TxDORQZRXkzkG?oOOu17sgmdsOsp#2+|f z#tJO-E#L)nbs`nL*1pN$*YWa9jN%gLeViG+w&)mvUY~2L|I~FTdr5N=`I{pKdN{@L&q85(wARr@R4-krvP~OmPI!{948A3DB0AC&Q%FR5p zl3+kcG>#@;bS6m+zd>5YEqHI(LiM%HOn%9udQ;Bx==gWMH*Zi>REI)(3**mTA^Un3 zswy7icR#$q|NM{N;XnTM8~n>3zQ)O;2jIJQExoWkxR-ki=TZ*i=-vp#ZQp?1Ve4=( zZadDOKaK5?(d>|0k#;eYp2{#nfIV~K&~`Ny%s<%Oa)o(mtvO(pslxJ%{2NJ zv{Ll?OrTdvnqS}+UJE^27KI{HPG7=pwzE4qkImXWq1$$vu%_H`dAK@Hbx577K);j< z-D!84p*t}~#P%a4u7m-p@TJPkVUc>bZB(FFyj|*F0M|Yh3v(OtQBlT@#)Bj<%=cN8 z^``%mnzSJtU6Xyk&Oa2Tl`TdY3z8ad*dDD+t~mDny=K5!@p-9ag$T9aozfx&coivn z4XRp&uT?4~D(nO)LEa9)YQ1<3nhNw1B=RihO3f48Gv@F<&Rvd~vk6ZEUR#Cg6xP@p zzKi`m!rW&)HcwEK(UmkM&T3eIw$L4 zsObL%_$kw7n}yM|mXldURYHT;IE&Z#(JF;&Hbx^h{uGWRYw67ExOKk@m34z?>3WXt z!PjQ6MMdsjMph2=_&z_X%{>Vx3|Qo{6;q9NQH?gXkD64wo}ssdipm=^MOwMWn%ybT zpS_rY%U80^IuLz>W2hy-o)lN1qPhvK9lhN56r+UCgGYtXOx)nm2pS$|LeJm}!r|#N zT)al;T+SvSx-m5VwV83It*rVks(QKRPRgby3p<-qB3ElRt}=o2oZJ1#$h?jnJNFnE zs|e5*=Gt0CrQ#S1$1@PzwKk8wqhn+wtg%q&#=h48w2DBlj;;`tj8^K|ODL;qG@#e= zx`UcN}FA7dpTe0ch>s_V#`)7 z+PBq=+eGi!jlKI45EQ({v_mQOr7kN?(SO<)zRuY>A7|`H`*f@gGislJuXe4rrg0$w zUn#x{AvlAOylxsCDS8zfua{BE$hu2a{0z@terHs$!ZxaNJ#$y_?2&G`kE7McSwB)tgXGMJ{?&OsiPc8RJrFkr+dAJD;hK!+L zCt%rUpXz?%l#BeyZ0V3=UB#eFJW-)PCk4zYn%d7Ipqfq zC9@ua3~U8p0a*Z67L(e56uh9mV4>z8Eag6m5UPB|vUMM{N~pYVL0sS0Izsvl<55v@ z%Rt!QR9n;Q*>m(PVkeWzWK~IBOKD5hPhV&RguF<3R=RfG4-M?9ecMbP-5VJIsdh)9 ze^_V7da_z)$7%m6JbxM{4Z^CPrp=l|uVFU6oH?8Ki*-svH;-Q50#`50fkk@Rs{KwVkq9W2@lCn=Uqg9|^NiRqf zMYQNxZCk%lzIw8i)~V5RU#&u~Z5}Xj%Ol6raN|}1np=m^(l&(j%eT#1?RkaexRQOB z3Xb*5j``?uh4CQDX`J={gG0}7;lg=B{Ty!JzKZPZ3w)n~3m4B|-@bha4i3hlLx+%d z_B4VvtVd{oAN)Pt;OFIr*qxEc%)E@VY3JC6PSK5iXyWrlF`-+uXdeYmoeOP)uwG7=)47g%^R^xAP6RchX5~72qGGP5NtFFPR|w? zq$l-KPbE{v3YD@vLxpqt`CbNBo|l#>n9cj3B@k3JaY~S%!@3jjx9_5Om25Kvy>E7#eg*=o6sK;z7 zwOA>;@}e}@tZSB$lh>>ej8Z051YSXV5$~}SyyEeKyNX~hg|E21?#0$^5oVlCV7H*x z_f_`>_Bx+QMFv3+oEPj(yW=qy^fP8Gz|^VpjjA{4zC1_W2j@JURcQrz?YE%Uz52f@ z#;ag^cj|*}o%i0>)AZT%OxQ;CsV8^Mrx01Xn*5-!Uba>x03RJlN`rsMP9#(PJu0a; zDSCtBKj3C=IrbhphxjAsk#;!;w{lBS-O$U%@D5k5KfwCHFdROShIOZXK%hkZA%vw$UVN-`rt2-eJ>w5`K9zCo};R+-J~{2 zg{cFmtaN2ZV29LmU9F<`@%1yW^|?Bl234ij)+m#Rptb{H>TLR49bfM)+|}9inT`|G zt&&&K=K{MLjh14zAtHf3oW|wq_1kD{>Bh4c-_o$7hJm0M;YwvR5XvJz?=yV1^VD~;=kl#58@{n2{r ztzG@*K?Fr*)dYVhI(u}?AnxTBqmIy3dS!b0B`Vkh=Gm=@i3gByFdi|xcd_w@V^_=` zq|*z#a`_5&Mnq!k#z1WH@y3=wf9&70o1o9c$&^&2XI`P=s>JB?mnbNy!g8esE@$Tp z2*sh~a|ZBjG{iUV7n-&s4EK3>`cM$iKvUW8k3Yor;ctY8fUnO5birHK zBiO6W*`n)FJC$-*`?ARjx^5LINli8s=q%_JDp1jDfkLkZ6on167EJc-hiK^-LYoGd zyGGeYMvXU_|D=Zf{-l{8^%Yg679bPg?eYb)SuZmPrPYM_k>v9zpUCN-6C{fae z9y7R>2IXAFEo9z&fM~*huIifSAtf(pOSw8Z-UKQ^sfEFm3aRu*n<=9urZtm2hz3)6 z@H%!O0k@d-yoC2+p~4@$UxJ`SfyOAz^93|HipR{OdRLyj23iIA<;!?)*k%?l(Smbq zOT14~^A`5HUt)y}wLaHAsebL(J+Sp{+m!JZcr7z#I?7)~#$|?`NBa}cV0}mwPMp1hqN;X0ef>Lh4ZXqnD>>MI^ehsNUqE7NCP80j zLNa}WZ*k((Wm?oQ9OaGHG;oc)Yu#zBka+U!Riw~pT%nWi-PJwmVa%)W-|#$ z>pgT0>QP$X652gRjbFNUm&WC>S+luAZs71Z(k^8|5Az5N+G-v?QQgpn@z>v)l(!l} zqjylx2<a4Z5w$lS z_X>(J^5PpjeepG((+CcZyr3b;F|p;N$IqCD5EK*e3W-%zH<+y^Hf3hr!A0Jami9gj z4UeI;tQ?P@Ji?PFdB`t#fP%+`EJe7J^AJVF6{xJJL-CVR+`Dlb*_Seqekv8`Q<8D= z_%Y<>=HkZ9+w?}tcn|t8GXBb}*5~RKh-G?MJB^dB!(^m z`5Q`8v`Yc2*j#)k#N&7finB}6A3k!Nu6`7Mdyy#?9)g6FqTUN6f`nAQ+MtAm+MFQo zwN~Dryh0zN-UW2Q$^O4hx70qJztp?hp4yo_M72#_tFBwutC_VL40O^8sp<%38^W=G zQPDoZ#XfU5I_7|RxVmOsYg)bL%(%GuVj3YM&}+3xL0*fGt?*or)$9E+pOEnm2*H!` zdfv|$CiPd(CDz0|Df;l8@dyduO_8T1vfr9e;Yzo4ycf;{AA3(ftm&?YdCW7QSD89< zj!~(CSwPTc#M7v19V)FhDab7mh*dAVe*K;XCG~q!xeB8xM7nNWpnL8s{~< zZvwsUi#5m=@+KRHueDFGU*o}J`C9kW0lzayt}+?+4(NIAybkLH%+fWoO*!L7n)~2* zkSa2`b}cJ`-iC1O{rYprJNHfAtP1Zp;cg~@aVuk}Wm^3GLlLqq(xf&gk>lyN3sG3p zg0hx26jU`Jue1gqZ48Tn&!%wfJ9Zj*B@O5w{|+NBe?nPZH?G|+M8=Ig+{>>-eftR2 z^E-CtMr_)=13rFR5D}ArE4Ln@z5hAAfN#xcyH>B$lX#S7)xrJBmsWf^D(;|(E$itv z35lu5FR3xGSLj7sEeC5R1W~y*b`0Pem4McF*D9F-!P~Gm;TS!M9Fsn!c)XswsMi{N zIejq;7cy_+_{sCo!zVPLCO2Ez41%}~*{EYFY$MR?wQi=MAz(`>SwIWk7WDEAWHjWu ztMdu=QtbMU4dK|L_fnfWM!#WUuiw&ZJ!D0zfbQ9MkWjCun(n~yE^3uw^U4s4BDX<|4nS4EOR1O#EMC z8k@K7Fu#4}+8vf#{QXmAspi`2=)S* zz-B@>1fl>fMXt_g!6(S;m_JcrlR$43y&a$xT-7mE>}$pTrSeszu=QSsMPUIcd&S0m z*KOc`XpmHDUU72`s4CRr#D6Epg7vxDo!Xq*qSU>gzn19!kh&|VO9|?~1bG!*r_Nsn zOKnVTPepCfi4iX}*SdnB*Rsn_JrOVyir$8Bv`?WEYXtO}AR~1tm9OJ$>{t_zP4;bX-zXl+)ERq*VD=36Hl8pfs`b$bMH}eUzH`J;=6t` zq3ncg1TNi2#h5MVRc6j5ES06jB4w|l+;FWurPU_&T46F70KFFYCbtj0*P8PRqb+CM z3G{;eiskMG^sC4N?UO-Pkug@W_ettraMx!tz*f}@{Ccl(7u`eK&U8;SJ|xHs@G80= z@(i7nUU`NN;8m6{S6Zw*LO;VOtL9~lbw8|8wxGAhS#{+YaL3RI@Twctmlk8(pKu)M zSvSbhXY|hBp}T{EiM+0>Yeo+Fd@YlTevRK|TItOQ+_noT7q6RzcG~GecMQCuEB)G( zzNg=yp<~o2_L#V1@LnHEMG$0WZyrCLNkdS9+SUQI^o*Gm>@)(eZBa#wdHA%R%q}(W z9Tkx3)4FCht9s#ujN&|B!LGwB8i@{>WY{R+ic$XnH|*XmUIOe$ZXHxsQ` zw8n@!mK2zNUxq^eA;@d1{n`rbR^bc!`c0`Zt#GL)&+Mn+(jy$T>ZK-_9Xfi-Ji6}e zg=^Tg@0eLBahbax)==4NP%Lc6UaI_!yiZ}gPw7a{zJZYKk?`Hf-}L8ihHk^=un03N zSvkE5c?syJ&s{ca=>UY z=5qCIJlAw4cCyK!x60ja9Yy~^<*UQE37_1D0B}@UZE9dM(%sGCEGjSg5Ed!%2`= znZ}|}&9u48DeU&rGrxp&yx0CATj-J1qkUiuS$Fd(IO2`hE)Pv}4YVMd(z7-5R^u*O z(!$B4Sz@5&EI9T-k!z8$X|v{H#vH1&J+yg+wZEe2|;@VvDSodx$$apfF7a;I_>=-qsS;1#eHkp${V!sf>P5~J$ddS9At zg7Ufp!?D_HBY!*`UcMo87h({1C>3Wi?ikpY)^@yC^csjgmXdBJTPf#u16Ae*EzlLd z3sF=Chm%j^a`s*1m)4@PvD1WbN^4tj?N%OQ;}cChf2GHI_|Y&NOgx42m$Oks_fW?* zcMTiE(8SW&KWe;y!Lhe!Z0R+Vrv!QvYFRB%J1R)3+K0v4XM=ffA+Mr+a`pTPc?){& zS4yOf-3#&`7L;sRHO)S+(adVa*_BIQtnZ?xjTUzU99k&5AS{n&6Ev_aI zYj&{~KT>9q#ub9ML?LqLejK1O(yEiIeS)Zl{obz{C}X)kBow<39!C7JI**45$l_$Zza_u$n?4~Dy&k(YbRq+a^0UysPxIF!(3l=r85 z?!tOl!uzn4=f1+j-#mjtIu;$HahTN8Y1kYZW%9{; zbYLQIODM<#6(r;}2BH-0)~M& zA!1>#qGRlSZB>*VGgY9UqZqx`XIW}OI187#BbZ`h1r@eWKnNa})zF(CGh;3a{c1LL zBRw{S-%6@mO;%V{eW#g}wZhGJl95r`r@|GEAs6iRWG01dEaU|;8>WzY7u@w)ptF$I zBq2LkFA(ar_G^${22kFRw#u~8c#hP)7kQxe9T~L?F}wGg%qYQJfR}o=F?+q&eUc$i zs7-)Z*3_<;IBbvDVZ1Hf1Fa$|;7ir3n6|?E=dw%_=2#5m-LcHo3rpGeOzJNC#-D@U z0$us|T7*n(--H+`Ds;?ZZZ#Q8*E*MNTy-&z?bAOngr0m6M#kS^;OR^BR+gdt?gb2$ zX5jmV8~CX{13y-#;UmF)17U1KI05X8+hY$QCgB85U%rj>YY%WR=>oj`w_&L(6(K>d zu#Hr`)|)u0;nI09<%62uSo_ZfY%cg6k!Hv!^3wQ7;AkXXX)ql zaOdl_Qus863CB+(G%6OWyaP-I!z!PRG{hnB4WhBw#?J4v4olhi1&XCC3wh(0t#mVr zUCTvyQQ>JpH3#q$i(9c_Sr=V#LZ#!$(8zsvC6K*o6x>#8u_73rXl`!7 ztsB?SR9A-HHg@p(5;RpkK~>pf97{X|PhVf`K5&ShU9WkXkRC|9dfi5|`k@{op|aLL z6v?MAJ5$%`&X-rUU<U8Sdx=(iUl;CNUIYD42EZHRlwDsTM70rXB*hB~~8VBjb`W&1d>f1QJ)>Kt{a z&jbbmVsaQjYG1-aYF?lh;5A6AW1Rs&XK8M=C!L!X<8#KAJPgDIb}4+lmY1k=RobYo zS@%idNgcC-_gaR?$s}^ZH7Yh_V<67gDpplXS)l??Ejeb;#ih>FrIl|HMdDalJensk;>)=W_+R3YQ7)fTlC zsl8vO(C`cN z%76;o7-F`{iqd`7y;ZTXdfk8BH>v+^VUeaEY}~ZjWK1b!H~DwfZfuO+2m`h`&CZv% zE@8Kka97yXj{?A(eDNS}wCb#RD9i-p=hMqn&bwwfD{3I)ux1T;<++LHr)42n?~BBr z)y4oUVtuMVYkaS#{{_ZgeuK8g1~lEhgwdij0{$|7Uv&<@t6{07q7RPPLlu97Fi*o- zy3V@~CS%Kv{fORo90!vx;&l2gWaktkK0lMJmuo?mCG5hf{GouhcvhU+%i5 zJ2!VfHF@)T#F}#Nl@(%V*hTF*h|~*L&C}4Ex`!}8NNey_aoKy1icr(sX@LFg%?~sZ zP3AeQ3iF)3kY&I={QRAP{DmvG@Tj=jyjNUb1AkTY3i^j%n!#ADedFa7KtMYan*JR0 zDn{W;akH#9kf%GkfuJXRrSNSiMx9GV9aB(OM|GjwypkPJ9a3dEA@8zct(n!QXP$1L z#}g77g^-X)Yz^OO^7^B8#+k*;^vJy3aR(5)_Xr|b_d!A1jiC{gJ$X(F!KhKh9ZWLD zPU)1f2NJROa56SW?uIYD0w20-^Cpy{3me=ro{t)y2B-vfsdg!44fqJ+Y7jR5sv_v? zGcVswX31lPyEK5U*uIR9dDbcc|6aUk@&)pGEf7bEqkMfR?%^Xss{C z@IVJHrk|sc^2FXl$7$^Q%naWB$5OG6MqO*AxUCH|gUjyT8_lYT8bI$KdV$`7aa7c_ zV$c5LG?MEuop2HCr5?YSssXwW3pv@MS%)(T1a&G6giQ{)D6d`}&k3hEv2}q@@Kmw! zcC()fSsheLPfJ)R<}SGEcjgNi?C1i#?zdpAt?ERbU-hp4v1)&EG3{dl8Ul!lfG%%I zpb+q7Km~mV@>=G@$;{C?={I!lIu`?f0^Yt>h*2Ryg>Phx1bTf(P*Z!=j9CZt&H(dF zg51EHV7DND5A+Gx3%pvRO6^0y(LRA*6Ph%!Y0AXJ9s8sz#q+hK#WJ>$9dQXJNnnuu zP!H13oCsx5)zj0~jMe()9y6|{bXloV`@}T;zrZZe8zn#SoK=PAlwBfKE>Bg@iIBHC z8S=K+_xhfGM}W5>A$iCexR$uGKo*GY8aGn(x*sYEr^z6z{;h|l*ShEWOveiH+Uj$K zdz{Q1XR@0Nu2MF&UXBd^JSuW|`{5L87cONZC+7+7vS^I$p3s$KGaCh^wMMB|HguQ_9YHRgUO`!HE0u$u#-C*#$)ynbbKhGhM9#2TAoIc%~*_23Hh%k!Ch0xCxc#j$^!jtc5(}OflX__3w(BfUH3{*|8vj_?&|ykwZb2o zET!Z1J!jBWo`E2)l_mvV!QO#^1+-xN0q)M=u(tY4u#hoO5yS-y!QST6?}>{yAp^bF zXFA3j6L|*uO@UqG05&GCb92IpJ_axfGwGUjtjQXq7|~dgAftV%6AkQI1uvM)p|@l~ zZ`Hoqhm5}6&Wga~s-fL^DWpq{dHcX@YCWu>uF3(;m*)q@? zJl8%MX(#OFELWj0(Hwf1G9+3KVFBAf5c~1XJ9#FQJS^`<9?w&HIxpzuuyj$(-pzYr z#?Vx!TDjAM{Uj(Tj0*jj=?i*7S8jeaN~*eW^+pl)A3TqcZShza5RD}(v|1*`<#KQH zApRF`zQNnkr)YVYgYhTn_(Rnh{I~K`_(SC>{C$neX?&z`&7tJ;sA%X$_vjl8zW5F; zw8k}UL+BiSgSNgG=pXymJo#P&v>{<}aP`=TgNbS8Nite3ap?JXIF+7_uo$Y<11FGt z?yAY5SDaoGdNc)Ed9}L}j^onxduEc%*xR4XLS1_ZZK+p1xm`w}pu7fyMO|9L?FR8+TV<)j(VF1EL z05OV?UWGb|X*eua#jAr&E>iL;>U6q>bsIv>RR6$W=ZR9zb8r2P%eo<8lgSmodpF0d zZh7u(GL9dLMe6Z*WS&2X8<`i8aq&D75)NTo_zonVN<&d)6S8xkP|>F#IBX}@`ccLD z1ew(xwKT3)7Zl|6IKt|>cJvKC#{k=d6uwr5)T861>J_@N;TjA2$)OtoT7zItsKrsR z8blRrttTecWk5`&G+E6nW-nN(m=w&3@99|mo|8|nY4KENE2OSzFc-?5Uu5cAo!_QI z+E9^I-uiq)K#-Yyqt^n69rP1O>oIM(j*)xAeNL`i2a!?uS{=XhJY7ps`-z>222G(wv_`3el05-{9%n@6q}6CA!95 zVdxD#pXYBe^x`edmgXd#OudBS;%a)k-DvL_!pJjcBAezd4L-L$BUWSv@DwRqsc#dq}{2D*U->4j6S*>TI}e~qf%VFb{AJ} zJ)jz_qS_y)7x2=|d|kguDV+OpEG5mv?v*dDhwLgdBYfvR?2e~u*mKZ;UTS}Uo`Pal zo}L>__(p@Va(7isn8qgn{#5LtTXteQ6?YU>$Ib)ErfiQrg0Ni&u|7BwUVdAsN)8}= z$6+dyRK&%fGuzOuaWov8c(XV0+z9l@{fIey28U9vV1H6N!uKT7bBTjy8^`iD&t1NW zhXo~Q?dnB4K`#Z|UU?t&g_)?%PeX0NIn))LNA2Sbw3gpPdtDLob8evU@k7+sRHC7w z-o(c93kvb@Q6Va->e&!F(c06G{fCZ0k4IF`fcVjd6Z>Fl(q#VKM=&|D{EG$M%O%*PjPeIb* zIHa9CitFj;k)C=6#}6OJKHk?uhfm>F?qjs|JjK07WxRix^hB_t9)qvrZd}7;{XfznP#M}<#+hMbCt>A#MlLO z3;N0bsgy~9{9aC;nH(j9VHLhqyWk>)XfwaGwF*+NmEECGf$CowTRJa$4JziLJo4NW zs?dKE^fGiN9Hs0a9xL#eYoy_qC!+_TtKL+9lR+TrtZPEF|caEkbw; z^3I^3V(iW$TQg^A-4zWAI@uxGS_7c($V-s8ke403D;{CnW6cV)3g1YGXuwfQTmz5_ z*J!J7hQgg1KeDNp%ES@eRcshXMFzkz5_<544O==zBFK$KQT;<9SJj=pUo&UT!&g&h z^0hMtW48+7=zi&5=|0=MdcD>?(!JAXQu>bZrkC&H%x0FFpT*w^-4TPb##ZQI`-(W! zcMaeuz4yoiN3i!qDz391_dF-WS(>|?vB*o;bI932_KlYq9eaks!9nzN_oA!42P4DJ zF+#SDjD2lFV{OB)a5yEC^%I1}i#)Mw*CD(nf4_PC9XguYQF!YL-qt?A-#6yqySmHx zt~L|jRNul!9#pf6$KT1XL~Z-9$)JfzIEnDxhpEsHVc)T{I6(Ctw(}rXdTzu5s#+B< z0$-D(>RN`3+V7#|sc7vtp`RMM;#z~ntiy8miBa<^notp+cp7&L%2Czc4=sGu!cMP; zVrYuLp3T|PJA`ZZ@=Sp5hBr_0ORM}`^)@!uHEY*$%Yc;v%*pC4V3x8HY}s$C=BwafQa}CXL#?!dl#TP>OxW&tv2EeKbnP zvG>S%WZfyFif%_m{SY1%H6!KJHEiCz2fOwqBkfuqy^n!B zkd=8J4{~qQ%0DqGf8YKCxNwoz$=}nWVO6zFW_jl$M@|^9oJvhY5*yM9dPXNxFCh8U zdG1fgIo6FSX&Fc(d@o+iLMFYS>-30j-F|?ZH}B*A{U^xDDKM|KlIUI5|Ml!U$i8tK z_a8h&MTI6zmEht1n<#p87msO-s-6^}sj?c)bNX_2Y! zzGuj%2snHGD%xq_1$7kxUdq0AV2sC%qL-zyv6J`axXD&nvC?@svIV`i0*qiHxC!ur zvVj~su>*R?MHj#w<>tU&p9_E%nCkG$2?Gt7X@116UHi;(7y`Y1SBhRLZ}yx8?A!|1 z&`VmPyy=A#Q1}q8(eLX&^_zmS;=boET*jr#S55Yfz+l~d3v{Ja$}5n;5IihE1bT&a zjvP%gp&da=#zX(3qW{$SDx=IiW>EVHa@B{nx;70G>ztf(BXp&j>80pVd8$WaC?`N~ z!#Ao^3w;A|7A>}=eELPpspJWF4a5ra0=Nbcb)5Yz6Dnk}zo%loFa4+9>pL#X^jwKR zdW_C9EcANUq< zEroy7?{!~vk8F{e7wmN}ZB~>3@3bFzhEDFh?wLF>8E73RgKdq1K6ma5jU?-SF1?1? zGz(AU+{fhzkB!G18EY?JtPTu;e|R)5-noy?XRj!9pW#yWJv2)IQRNQ| zKSOJC9dhs7K<3%gNKZ+@O}3-Qd5_W5(1y|RHyHc+wcv+(+M|EL301z(;GTOasIBU~l3%96EIwF^5heVs9e067r$Z z@z@v^3!jYc@U z*n8kOLc@1pg*)9yx~OiR%23&8CR9l!D88)5qbFb~Bfy=XE2G2=wo>`}Q)z{Sgkvwg zixYHrlu;z(*4+EdOcEQ=s(UQGPrt*3tUT<9JBbGbd+*a9F!uTn7=8Xb8m{lr(fyp? z*CYEf@VK%S?Spi$p8tr>q1Wgbd4slr=eT{p71B+!KgQR?P3WjAM$U~(xN<2KmoKIw?c8Yu2ZvzmmhHHd zeg&QM4*Ca%(9=7Bs_I%46g7e@y1u8va$*_)%B>YZA4{NEy^pZ zQCe1s;*xT6tU0cX2Dhr3YP}xS)pZ1VHOkAXxWAIGD^XHbilV|I0eBIXE=*oWDf_O_ip>DGkJS zbdTV1Q6=K&MMOr%Qo-)Twrx=e;Jvg^7RY8Qb~}@bZer%4LN=~ zDv;XuR;k&dj&0#8_zJ38mOvd@omxfT)9>q;$-k}NvRexP6&ZUI!Aq`EDgou z6$%hMqy}}IV#GR66@6b&k)lr~ER^Y?&+T}_D(E{Ykt@vjlAYOW2UexjZR~!wmNQ^cN~RtYxR~uj%N@u# zD0g0QePyrdAwQ}kscm^(ZmW2H3uzeUurAn^v|6Q-7j!Sw26X>*Zw2=S#t=B5S4=)C zI>y{5-80>DtL!cO^}RVfR)%V>GPQU<@rkFsw~01>@*Z!KY_+OiRig^3bohH;>MX|q#QnioClBa z?9ESj{`R-Xy7`Fb709~xL<~LZk*Ck`_U&7|9D9zw#x~SG%0uCeEacp}iQ6}C<0HQ< zyRePwU2u<%KVd*G;Gem259hLSjiUDriZqa)v%~{S-Tbh^BhbX7SFH`g`k*Lm+mV1B zdygYBHW6_L&tUK2v)H*W37&qTGz>mw!i>+xZP-c39y)meN$0L0`+kv`oK-_FKpued z?@OxM%!4QrlBi0l0JVOG(kC@pNK>};I4(VVQO~Vi*B(}?!|K^m}! zxP3Phy*)Mf-K%E2Xt{;X!V~B#InHeo`YZl_g#G7#R?Bjzi}Ht@yY21lWiPKd133r~ z2qlzrjtEIeARz%lfDi%%h#(L-ikx%KIfFptIP+Szx9>T7pU-vcsqvP0C!Y5GP`@!o zj~+epQ`Obo)gAKs`gZxT_q_c1%^i7h?}F^!vPyPrT_syLcFOXli&Q}s$b<*h)KhPiTd z&r;o9C2N;1SBs-d_HA7+hj(<#;axkVd((PZGJn3zY@VYvhMm%*R?4Bnr_9P?)H1yU z82CnPezP{QK!@rNqY(e<%YpKT-+wJ%el-_X=vqZ4S@w)?jxBf^cjlnkb z+yL@`pL4Q~bq{nXlf1yabLASD)6y2Q`~#~LSC0GVfx3<1u$oB#db)~Y*#mlNH2Ca! zzSc;nAf$1YQNYCV$I=Go0N%k5!*K@W_92!JOqN&$!ie*U+Dl4@(?!R>>1pM8#} z92d6zIPdj^TPF}T8r2%7Ar-&}P*-KGFvmgZRq*4(Cm-o31>7~BpDva7^>G1V z2=Hup4h)d;*`xqI%VcFooxTtH#Pk0AI|A_G-x1HB+8DJo(s`e}V?U1kfSz-XjEt5s z%B99R^W~me^Dn>oQ4XEGEGhY=GH{I6T=Y7IsgaslRwesRUyvJ5wB~zHYrehjbMv2frD;}+wNt+T?mw*idSOw$ z3>l`1KSA%OX^!;1eJ`&+ew5em)bfAvTprxNFHd`)%l*esrC&x#txP1Q{JiC|P_5kc zyVNSYa7V5_d@Z*Xf|u_;m)*xMNx_7vGHB#@v*>e5CQDU)i^ag1IHg&#i)*E@qCqAp z>>HaG%j~vQ77a7MY_bg1s$X=neyD_fU9e2%EnOqKj+~P#_ns+SX^sA1Q{X*Q!PP^M zD@NL_Siju@VBrQx&Z1pFtJ!L;1Ntcak>lulo*Y2ktAqIdh;9e$Q3T_y8)c?-v&zXW zw%}oHi`U4WBNq+u*YzH$jZAN)ZDE-Tk`n+ZRvS% zCy@Jh+zXua-NoAD~e0ui|h=u-r8H%no@6Gf>Au=Uw48LmBvc1J;BbFP$*i2Hnwxm%JR~ ziX*%{6o4xW6bSi%KL0Hf@lf-|bpyl!I>KN=dZp0amre%W^%9_u*MA#}-XYJRtKqth zB4C|R5VYF>e8M02$XH)aYiyRCJNC)q#mntI@eT3bUCHzQ_+D57cHSG`6Z?2ixJqef zF&EGPttIfi==TtvlqxmTo8{_*9(nQc2f6;JS0>M#E2GA1?T)#&GxR&qbMMuf^98N# zo>gYte)2}{+@xYcGad5(oLVCP-!m)Z-*4=ZeXHh4Nm;qY z1?zqDgH6xaIIUgpb-WCsM^vm{=Y&bJX3I7;Os^@cdZp*tOL_kKgVq*aNx!lwvt-ty z)v{stadW*~dGJc^sb$;y@!#di`+t=OuYNE&b>)Gi=1vs+^iyUmkcG=P*$Bu(XRa$C zyJU9zDp|C0ldRsdTMnMQXno}A3!hV3E#s0hWy0iX(mcOIb{##VaDT6meIeVm>c3{& zK5LMrdls>*X`nrO?Y_aDU}(qA-;mhkT!~`Pl0qG89?-|?4}&!i>=~p)3qL}iaG=i& zSV^j2g27Ns-d!z?O>MGj;~rHqugqPuQI%R@Wuv4QGGJ_qWS7)QM&V@1Dy);7!g{Hw zog>TF?hGbWc=4?~C2snYx3YEHLD|0hnB0Ew!se{J^XQd4fAhTs7Q6rSrChuBQ1iZ) zy$26S+kzI^t`_>Kqub@u@r`nP`vTdtq*^vDER*$Z#j2?*WlKlBY+W`>)-7(9&iONC z>4F)uebZ98cKN8>yL(X!K7S~0dLPJ}C-+TWKfN#So;{TJ&mUPj+pl`=ny~+^ruqI4FCNRs7fZ27_CdGoT-z?|moAVa+q>lS-t}^F?*=({ ze7~$&x>U+b%jLxJQ}R?T7up2)0Re;!$kA%N$=Aa|^L464r7!~W$Uv;n5TJlN61Z*x z0rEf^af{wT$xr7%4!6z`_K}}-wkhX}F9)dd7-VTc-^-(n@E@Ob-v$ouhH=Ov?02h> z^OKJyN(8_Ib(S9IhFXXF>nRIG;l}_LAOqkL;O%V>*6>PK!bmLpSOq#Yi#UmhV4zko zS{C;X`2f8S%O{c|aen&uXOLOYhaT(NEN}%gOBaK+z9S%yPzzuQq!HHLN(b`f_k6f( z06qDDJnd%0UgF>M<2eq+PcIwXF1TQ@(1AKjfKG_=`o>w-<(PqhSj~hGp;r!LMhFSO zcNK2&vm8R(gzm!)=x`^-%~-Xp+0Mx>l&)3lr9iE1o+ua<>f8)Q}Y zPT75&fR9gX#pn^my}P6sv(<-`HX!&lh%dsnNYm`Zcz8ScBv_ zh5U`4ce1+skStdiZrXd&1Q*8@wOVm&G|XD8S}R|s&FPRWyHBWA`6xYaev)(7pUTP0 z_vQ4pyQ-<~%HuchO{*qHpJ(eeLe~|qrFUhQhD`e*UWzwou zdE#O)Y?>fwz@9)}1i2!7EubeHLY#sfcTG}yt|Y5=WE~d`R=k5As~$^%s%2VwzICT$ z%0C)mXU|(IyANNGhp+!+pl@EVQgX}dtSzFnrb%k1wQ1FBxwI@?FUwc&l3DXsNtasg z%<5#*uf6ZEelcy9d0w_1{QTUc zaSVA`cWa+*mgK|AW}W<=4wL~h=LHDi%7Aqg0RqIsfsQKx!CI$lCC~u!2reJW&+J>o>A{6VydN68-Q@zT zt(K(_2K3>O4;RnF`hS&&bn;Oy${j1-yJwQlxkzW*-8J~RvFL$3!aC5$vY%YvWUfA3 zHsup1+dBK{f6sRW+=H&gfs)|9>6K+|6(iI#SI7f+M#Z|%K0B*G3Jc22wFB%O?7Ult zJ?|E`4ecf@c^`ZOZfNkXIgW24LXR086EAhmbL2Py0dGH&YY(3o?9bk~qgMV?xzqbv zt})Tl-A8i$@v|W6?6Y^Wd*c?_yL6iT`BIns`?>k@CzXFYw?JXvD&L=&C*PdhBuCaP zlf1lqS=zNpo+;#?ynQFlbJ}F6UM~tWJFnQni5C`CX>GAem0^WNFQD5ral-mFFIpu# zk6x6XcYl`4_g_j&$2xQ4;HPg54Vt=i=b1HBE?BnFeDjm1&zEg`PwC12WPR`NKUYgv z_xHT{)@Fd}0rc;`(;Iy(Gujr)Nd3U`CsfPwb(`g;R%f2R`%w;`y(WuRZ8D*sJ%enR z$(`ZTSoHgjU$DORSo>+YCFdu`|&&L3*XtXRJN{KB}aGd z)@7#xy;i1HRY={0VyP}KkcQeynLlTi%%0gK%a>@4XKS}?T(ep_7PQHt1+B7V(R^u} zH%B&aS}WJCXl>~Fd3o{hRv)C_>hhbHJqGyqSmjUEIuAko?UOrw`CL9cyKeyh`20a1 zu2$Kxa-}@D zbVmNqPp{;MSN9b5=cKKvRVGzUkxLh^$+c^@Y{W4?AwMS#a$gS$;@1Enx7M-Zaov3V z)gZI(N9a!q=-ChG-F*|da@ZbdKO8?EFb2FV`2k4-*bZjjcE~%(-SxvhwjJX9%4sh17%n__~(gD3&_Xz2}52Zj2fc-4#8VtY@x(Na$pbgvs zJ)>b+(qPLztatL^vZT8u+ty1+k0HK3<4W-31N@j6!f0qMOTkXq1c&(N)_k~-2eJJj zVf|;K`3T^Jdk4XiH^3|SsRbaw9tD6)h6Y!}eee!?lmP1h9t)p#o}$t!{kL;1FUJfW z#-u87wvTWkG{W-Tm;s?yJ)pNiQls^ms8NVjZ?jAd8ELSOk4p~rn-cwb8x7wS?=Vp4 zLC9#Hr?q+LIe4zF*a<^2WYid$v#3MvK6@iQufNgdtDw91bKQQcQ2+R&+%#b>GVAL;Y^$So64Whw&?mo`R>d{>0a2Z##6cMJ$Oob zUf~gWWMfxGF$#CmRO#B#Eqe}}klpkk+<8K_bsv_EoA=44ZTsY?8rA)#wW*bR{Ia=e z@X0S)-7WK$Z#2lSRBM*d#WYsZzn%uyh;eCBG_g@Sy1Ff@<%JuMW%I713hE=WWzRuX z3_E3Q_YQ^k4k@2fFOm8Ik5Ee`Rkh;GwncLK$}Q_dkKB0lQZC$BuC0q4bZCJlW_V1%1^|&0_cS!bb-y>T$Zjv>tx@7mx zU2^)=ak+o{np{7BLf-V;HaLF*xI$Y2|4~5?$Q|IXAK$XPzW(CD^}cNbyXIs2)uWs8 z=J9P6g?^77i#tc53Ze;rYTdUL9MVWmv732^H=O=>GQ$rPc=Y)ZsMBYR^W&H3WzJrzxZQ+ zTLSvP0H;7$zd{Gx0qji~48;0oRO~1JJU<#1FhKPm6>ziPp&t%&_9LzU05?B1OaE#4 z!TH%eFZn17;W*0TT%4D@EIE!etUm4+m;(r|3wQ(ZaEsn8c$Vx#5s(iTfk(9@-Q6}= z>A=QZI3a63Iy%voOp4GTvKT2YWOsnuuQ=^e*$T7TMzCCJD-rI@qkmGOXSa|bp6~?`R@EGxxIan%qh>61@q?%Gw3~1#c|-oDgAcn zN}6b0q8~qgA#c=Jf2&69i#IMT9aN_ED2dTl9Zcol9-z- z(Wz>U#3#tGajFsHlB95AjkI^JlcVQv$oZR(PVE`?_{6WZo2oKv{|#B=)-#W?7g*gW6keBcFxYn z1R$)F#z3yy51z|)t*Y%(MYn48203*2guH+Et-Mm}{??T%a_z!-xp4f1oY;3z_HEfI zyEbf-?)6(`-|ho)^7t9Kas9SjxpY---?%CFZrzYum#?U0d|mEdy(zb^Uz5AHZp(wa zcjeagOLFDRF$MH}1+-iB3U`G((8eu;rA|7E;NkUi^618Sd3xuvNzbi|^8Eg_KFE`Y z?Web|%Cmb{O%c3&a7$i2yeqF1`tNl4{^=um_u_$k|K`4e{;0fA3*-A+%jL0tjJrB# z%AxgZrT6M3`P1u1@*f|c$-^rbq;6uhw9aai>(}ndsgvgoc7Tv2JxBO~05LxbmOJhm zx8_+Nq%a?)Rc)+ReyRZU#I{k3QsEH%XrFq|09q6S+b;a9h(p?8|9Lv)P=A8{ zr;`_dEXT3Ue$NZ6{Tcv0X)I9!Sn4#~;gfd-0K^gYu>|rCd-Br%9$?wCQj6XC$PZW0 z>+>MQ0co+Z!9@1-v&V`h9hU`-uEcU;uocPy(31}63Ehp7@R_q%;=-{YXbN7A^|^I% z@6c$=(yV5%lR-1xzhQzZK%keg(y9Oc&4;~mLlwaNCvW71 z8nnlD?~=XCTjbJ~HhH*jiS!;`D);s+lVj@^%KW-2SvYH^96xzZjq6u(=gD)K+%UtG z+fcoRwuQ^(&i&`o`}|vZ()->f6FPe0oNV89z~aA;l}98AFEZdNY&0`^uy3J zKtFoCYH$Vph?qEurmJH?nG{zyNR6Iz%FH&IHg~ZNqN3k?QAM4UYBi*8<~#%ZlCI4* zGZAr9c4(Ca@Do1a@vCp;^>_cK7WjAiuzIDes$Ry0hVD%wH-q=PZyZb<=DR69X7NzW+`xoxLchj~Xe9xr=Je zw@H2FB$--OBdyJ|W$nt9a`Egbxv7A>c;0G)@R;ldi z-YlmN?=hIacyKM`a(Q5&Ck?@(Cml=u!L_p{y?3wlfgYHX2Lbp1{>iN?wgmdm@7)MM z|3H<+L#-`5?U6Un?#cIR(SNwHPc8a(d3tJ=oZC5Bt{hk>=k~0TYe#m-pI_aRA70#- zdl%2j#KID3Z(AZaZ#=Nx4S>{v?A9#6B#l1Jz#YiD0R7==)d3}Xmju0Y^e59F%EJ@5 zb#7%SU|9lqx6Z?X?ofBIBS0IW3_pf+uF*m7WwW1SsYy_#Tk~$Qb5G<$fICa}VX@=e zr9lsPW6?X@Sps$%X2X5;ECcrqwSY9U*Z~SwIR1Db53q5~xbL1NR;NP<|2)<|kjL^g z<*0yme?IZiX_WQ&{0NZed1KLg&m3TmIQRpY>wDDN0BNpx5RT;<*>CSlg>z72z!yJK z^AMVwD6Px{MU=|HDALiYWL1K22E!Dv0pI~_VoH|54A7$tfG-fn4QP4Pc*M0ufI$l? zrp5r4I-tiV5A1=vgPwGUJ^Nf4utZrB71Y`~#_0V->b*q~tT1p3@eGN9dmfJng&2_^lS!Tf_0OQ#!w`_paF|F;cP^0hCt;h24 zkuvx6RXMn2yKL-emkmo=Woy?e*}i#??AUokj+_XlSAC+#wJqtiu|l5|V!WhhmP&Ey zWE&bb5hgPnc}LuUF_cEnFdu^EzZg{T!kD<*?{f zgZwB3DHF{`rRHfBCEuosV?e;D_(bW?j4#ppLdK0V85E^2Ic~g+)e}Y~r`mE%LaM}R zRWz%lO0vtUBq6&{V$*XioGlHu_~9At3P=koYAyQVoc0ywuLtf-HMjTJdFx+Kw7jQp ze~@SIf0BbIF35N-0~ZdUci1OrH8nrKT#Ab;?PE;Rn#h!f7MV7yUD_Bax@NOU$LdYC z&0vQK4A-uoEen>eRSmpD*64#Kt`0(+9eV#nYq@E;r8Y_z*w0msx>%2|o!lTxIy!A; zrk=;oqP8Vdtb=Y zH}B=)^H=gv0p0uN8}k4V?USI5q;1~0Uy7?H%Yx1>>ze(PxM7dq$<6Ec<<^b+a`)Z~ zx&QbZx&QP#bCVMtpmW_8>uJa{;CWEXq0yUX934xKLp5@fF?y2~^jhOnVY}aO`rGP< z6Q$PgxU_tU$taXawT1yY%aIDq;jyVQI7+P%CaNf^l;na6NiVLFl)MR&QaDj!GmB)X zS`lB5j+C!PN66QaS}hx;*4LOQgM3*V0mSq42 z12GKtD)hR^$SAOnJvKH?rZ%?9-1(grN|!0nh@DRO1=iht#CZ;$xMb7bUBB0BQy21* z2%^@|+-6}Hu;^#DE;jekMNPkPg#Es|R|@5`eHPh``Y4RZ9*Zn=N=f;@YC zL!PUpyn696$xzF#EH_8mTW8COBfI6TTEj1TZ^)H%2c%=cbhY}YOV^@>Qe9jiRVqc9 z8B$$RB6~J(RM77rt$t{c)> ze{mmw{atzUNFo229y(7n|2_Hc=@of>akD%*K3krgo+Vcm_AhRzlG3zC7Z1vJdOff2 zUy(;wFG{IagFBb5(U10}bgkZ?KM*kf)F&MfA_NMCklx9p&NHy_fA4I>I{p0l6<7?BsRD;Mc~sACHwyqbSF@>xMjT%_CUqEXm6f__Gec z5y0)P8Guf0AUmhP0-QPI$&a8s5Uf?i!HLpCfM-$?A-K~GKDc*yMp&ZW7z>cF@_`pZ z8x?>LK#m(H+AMUI0Nky06aeeM9Cs&aKz{7lM9Yhqg|3jtdM_)hmG<_PdQAy^`Ec3r zuSJd1`%&;CTr<$5|2tsEf(P^fKfk!_XVU~SA$VM3ih({u4M7@T8SM(#1M4-2(h7i4 zX29A(&JqFQ;h@KgCm#*6>~qkQm;LMm-qebyA;A#lbHI}Ko;+s7lP_d^V9n#Nw+U}B zLiGB$w)u-!nExHi`^JOEa_H1q*>&)^S@F1UaP>aueJ#5WpRgJ65|vH3yc_1UXd3x$ z%C$Q^a{bN|xuNWVKg`f|=Hgx1bM&mVwlA}G3TjDAL_*sa?k&2aHqC02sncdjedA1< zu5`-OnNn3VRch;|OTXgUX;M%<)g-^FUP=^Tv1(Bdh>VwkV^s5o+%>GHmsFeO-_W{5 zR&PHbt;^R*rGm4ub-7HRzf8vHNBiZ-k@DrJ5rO+AQnh+wvJ_TLlA0MarEBYU*?HuI z%wDuimaf|@r?1_SrE51yq*^4AacY$)s97dv7Fg8Ec^#|d(CJI66+hUVlmtdgU?wKL z21d?q*m2Mra%r?Bz!?LoqVy$UJw)ksBS4=IoiM{GDS1*)gY4#grab7?LoXj{3zUJ< z0Qg&XAC)_gU#k}W-eR`gSIGM$CrpS;KsAJF7)s{#$3IKYlef~)FiRHci@2|v_rd)h zS<|^%&YnIfPaY{Gdv7aD??~r@B?kKPygX@bnkJ`@?2~Wb_Q?0|^kp91A+0lOWYyxi zvU1@(nO#3wYRdFu&&rTVr6sbzdyAYue$XHd=vnrGKGX>7mOAV1j-j#D!Oqg%Hhv6X zXC2p%m5D3p$s_sjl&+c2cR$jb-qpBURx|TkIa@s8|viR(Jpy;>x6v! z^oCmf_tc_4FO@}QvU&Y>d90vsZ(pi#z>*Ju?3Op{fEv&PczWHi?hUelo(3>1tg7lM zGN)y}{a6-LB-FjlLGLgJ(3I^IkW3}U&@ic%B)KLsr^SEpPJ$XId8)&VOQDN;?GVlbhK_hJ7i#9in=EM3o(Bp>& zb_yaO2;_rjrZp-B6g|*@F2Ker$Jz$k03BD&S6}I~9iZ?HqKtFge3M8m4j8foH!w7ff5W2$LNTGma2v)p99{7(Mt7R+bS)vfqm~cOf z`4W=NuMc#A{1Ck+%0jULZGerhoyOLf=mcAjjY%}XW9_rVnrF^fVDHMo6#@JB&VW46 z4So>Q9_8dcfUx!fJ%C49ny4W{{CTe}A=$YlvU1I4+0?y9R&Us5Va7LZ+b!$2?vf3f zw)em`mbtuVIqj_9>hBZ=;VkEHgFTJot3MwW^ab=y9=yzXMTPKyuE0m^UcQ#g_Z~{?Qa$GEMO}X+i@Vkt=tt{| zG0^Ke?w#VQI-8^fx6HjKZ=|TQ-lo$Vqcx0Fy^h-Hb7k$eeezJ@%j726xM%bw69)%P zOw}tYCYU`ZIyAv|T6&?hwylr@htJE?*WbzY`@QC?CvxWMO}k{hmbXrY?vzgy{`mh7 zsD*$0>{Sbcj8#wYvQyv$CXV%4FHTZmqoTVPMl;*|DKhTBc2sc};a{`7e}xTQaX3+!a;US0uC_1U>*BpS(?WkEI*}eXKqYEKr07Swa*8Az%a40T#z&sRAV| z`jq5s>vaXboI$T3n~+D96z3kK7B9V}tfqmhB|;UETJ8iSV;!h7`8N}dFefZ&EQv)A^zqT- znxb3+mEkidSR408d4X$6YgNh*Ku^DTmJ=&#EDeymh3|u>+->8QKIv}FBPbID#lrcl z7D2Bu{SMt-V{lhR%LrV0?{NPk^x317v82~;-l6b4FV}88l)DdmZFDN*YzRS&wSI@% z?&j?>CO$>RD5EfJ8)vtv%$K_9v!!P0bg7&&O(xH1krria=ellr^7b*RB`OczY-n{cj?&4YIit>r@dCtKp5buihe)n&zo;xFwX6T~R5&8#>gi z`q4>AGA>0ek)#yKoiI@ruI!R?H*c#ozr@@(^H+44Z@ge)t&CT#9ibm8JIK*A|cp3>> z-Ob2QZQIo?XD-~a0Z=C|-nNEbf~YZVUv62oEMB!yHRnAW3`Ldc_~~nMnz?YVJ~00p z6J_KSR9M68#_jv%hQ74d3VK5DHa5HQy_@Z{CxR#Y^Sf$zyW$!U@^8Ym;;? zZkLkm0!fLEk<9U0ZB0v+X;oFSZdr$PuUjRH=Qc@8L#?b>s2Y0DHo0{2h}^k+PPVV_ zlJzSV$%W$w%;yfgUp~AM09qk$-69pxZm|P(1bE|)xpL}YpLLH5C%j?S{PHSh*=u=} z!MYE$`l#}z_olq>IVmqLcgd^E3*_~+m2zeOd|BRGNvPYUJ<{SYLsq45)!SzIoP%4H>Sm87&!UnNpZvBtzB8>;KgN88kpG zdX<6w2gwkomK!*vFCDOB?IUI->JrO}e&hUbqxHuGI{bum-@_^!tzbZ*MCi|%lAIy= zdBrjw14DmcX6Zthz-25z38it3C;%Yu%77(#fH{^p);wvhY)~GghYO%59}ve41pEO# z>nI9Wa!8E+2XV29wnU;7Je&`BMJx1>IQ>s@a|%uQd9M+yRTQFGrwT685!M}WqZM57 zYV;&0=E#U)YRL}*QarN&^jPfpd+GB||964~0)O^lwPV3k1HgI*bndeTwk&}!!1Q(C z$h%=bP)68?b?y^=1NyRw)zaKDPh!R=S%gZr>W8bPkK%ODa`}qcf|F3V>jt2OzxXypy&d{ieT|0 z#bs5p_rP(B%KG@}YX$BH>3#9u)&naW@IRAhYDjjh+Mot*vSbxj$kyEl)ri!6Jul?e z<7aYN*U#U$YoS#bu!)D^>DzDR<;U-&p?OZ90vfH?R$DhsPM^DM5p6GDyRGMYtA^)u z*|YzMw9fC4^_zA`zq!lS$ok!fWrA9xrS(nHv2nXJwk?tVk#Xjik5CJm#@7*XY39aB z$SsqKhS}z-nJ{&h$@KY4)zY6LUymLmzaKVC298y$C_$@GiE5o^WJ&(SDw#CBNvayB zn;R!bExtTrZdcSwDIsF(XP6ZqfL=A6e!zq%?pVFSK>zZae>Gn^4W)VIwYJ1hzj^l& zIj1!VtZS-14*Cdv>41I=R*=D7uOlH{va`!%?fTsY`e(0xkjKxzF+V@Pd3yLT3)T_^ z{qYMo<=NXG<S0w$mwH;<>ZllvT5ydS<${gs!PfxEjCUiR*Et*WkO!A%&MOvi{{RjInyRf z=Ykg5yLFvhK6O|g-?}PCc6ZC{hRL#K=>oZW=BR-hm}8N+wd{}>t-_}!ry1yhx=T3l5lc6)Bf(E=&{r!9@VG^bu#WE(0fNI6I3pDj05x5| zH$ciZ0^G+?eGduSefvTUtcbg8u=0Tr);-od_r|*SxB==2>j=kSsbl3MSnyc#qych( z4&Yf27p`TT{>&&P6av=_>{F664QdW_6ala!&Ee;OcLDU#`cK4ZP1h{>;ei{5wktpm z=xtz=T8fOe#7G*X7Q8pYB7sj|pSeD7o;}b-(Q)6wa|&EafSH;G`^krREdzH0et5Uy zQ!{hS{g7K&VwOIT$A6EdkNb;BWGIV)cfcL@3-?Ul zP)Bawc`Th>8>MC5VySCrw#I1U_snRXCoS`r*hD{rRms4T)0b|larvFR{GhD)@Vx~` z?0NmsmQP-NC(o5fL>hSW!%qf!YC4432J~a~*$}ytc8z%pmRPuB+&9yj=GZwocfYja zN=a34rK(n8$##53p$s2KpLx}!bfrwqmm&J%@zn$REQM`O#S|%>(j;|r+Rc5_ym+}3 zOsbWkG5V0=RNJVQ5Urj_Pk;vv>vrgI&g*;%j1~L_XT(|VF%COM*0h!O!XO{}9>!ZzTcS{+ooon!UcU^$1 zTl5@5nnNDJ1r$I{!54Bt0eQr&e(u$eaqwf=W5r|519@r%=GM{g7U8-a?%~%)8cM)H z&$Y7z-oOm7^PB-5qd(aOhU_1y03%*HGDeNJu?noQkqKte4oz}69c3? zbitsoK~x?T%^}CL2Zr3IyRTf?0cP3`u!wm-SoOdVPy>8=($MP$-#qRbUuTjL_t~QW z@(W4~>bP0b({iM^Xo92?<4W(BD3pY@=6>0aaNpj;#zBt)^mNj=rYKbkz?*NyfzP+X zwhQ;hHB)=QZAKoHoLln_dGeBv``v%&gjw*n?)Dha;m#N}LUAX5aw#+IXo~gH8K&=q z`88UXth8?2JN6&74jy#(Ue~?HV%scRy;Tk#y&x~%e=pD8eUzH|MpKpsdR^jXqSlIq zUpk@2Y7q~VL9^$!Tlfg(r?AG@Dg{(i+ftdgq)X;4?y^t;4KwFU$;5hz(Q4i()%ZiB z^y2hmNYd&YfTt_wf>oPj&&i8&K`pmyTHQE*_rArirmbvZA%$gseFRrR?hIDS|wyMkJJ5LPu z46H)1;%`2BX?^OMtb|EQ0R2e)p&ayM^n)6s4-~&WG3D}AHfQ*bkjJu@W{R~|q8furZFdsFY5?_{nj92#R+uI~=| zw-S8q#08l%XQAv>xIKFKT=wlD&dn0JcI}e%^xT)1FQ3WTGiPOa#|l|EuU)1$Oq1nm z@vmIcA=@`@l#Q!b%8a@iX`4AsTBg;@lW;Dv8InAVe+-xHN9KZwn`&ZAHBDi#7zghVR$6(o$hkYmnR{#j*QO1*7r{uwf zZF0K1Nu^FsZ<{X1HaE+Gb#tYzFhj-0-l+cfTn|(sz6Hp(b${tIehS|KLQUg2|JzWIN{iXK=q>*`Q6gJPCYp~}&vEtq5j#W<{ z_sJuqJM>xdT(}0V1&8&E+pkk{`!$gk%N13hjY=DxUi<(9JL zqny2PT_#jcu|{2HeWMo-Qyk)1h}HWcNE_{m!&TV~)pHF}P>+a8kg@Sv(}_bFES z#Q&;8i@k?^(@Oe3O=$tJ(6@*c0)sKiyvBp>$W@~1)$u_mHuQG$siw_F< zmvZ^RQ@Q){t(?4mOS-o2lChz|Qn+q#*#P;M-~Av@-hGhg-~1rYK7McUAc&8{9Ewy+ zPG7nqDcOapf`1mJT+OCv5k)oEvFv= zE*zG~XnmkXdhIK_w#m)A&(%WzR_YpC^@GZgG0|!IFw>==q*mIOt(Th*UP#Z&Z)MlP zQ?hgKG1+^Vmh#iq5PMA(&Wu?LEF1%ku>>=_uVBA&<&Lafx7h{=^*((i-P?A_ie<}X zgF<}w-aT^sq?WPwpe$aZpl@F)YgVt9&6~DJ*NRTr(6w6DcXi5&MGIx^(j_LFS9L1f zH<=vVzD-W<-z)pJZk7}K_Q=f(r&UhM-Aii0EBNnUQA_=rTH`9LKe&2c?p;1>+qW;A zvOFx2%O?)$QsI8?gyp?{=9t_#d)(GJhP-z#pOzcvj>?r&hvodyJ#uQ_W;xou%%W^= zS~5vCcTAQ&YntTHmIcySQ6N!62TH=|F%myIQj%4lo_49l_2S536J&ji&;F8El&y|wm3MncqH<)47W5K%H zX2ftH2=oHbvjp-(2agFXdxia%Uk(#O7chDicLKdYJQfXe&H^;tH@J2HK41fMC|B+u zCC2@t+*tQM{RUIb6SSd37+_JtKA*4kTG8iD?;9+6Ec=;rT4nLFPN|>PB!#6DBrm^M z5);zw-T?R{tu5x~mDqi9f83{A^MIZ_!F@-Xs|NA53(7E;mns^->}@&$y!Cq3BKAga zx9G`duBT8f#-OfZiY|04%7OdAb#v_Gd2`z^Iu*AK<7=4h4foBw1xuw}E%){%ooabc zGWW7g*+^M5w2x0$>pt7Y>BMO*D>gC1VtEm?v9W2s+<)>)?ml@Yg%wp2q2C&_anZff zBX16ucU0bf_)%WJ`(9osV*!7^%MYGO&)Xm5^>_a+?>_#!d{FuB+y9UszyE*a zPe1)1xqauETqz%Nj@*u2^re>G8+ozF~AMOB!P7|9i08fA!8I-F_fV zbLLBVm0s7fE=#*l4Emmz((~k{oIZ0=4rtZuiKZPpqRMmcK2?^7;*Y-__&-tenO5OJRsXPtd*^+yJY?HWeR(>_S+ZOlwun@m&>X} z?XqIQeCb@cK)TniHn+}}Rm)}P`qi>$(>mF`ajh+PZCE3FH?NoNYgbA4nw7F~MTczY z?2t{XmdVDIOKqLynx*Zse%WH#ymFc4qa4ax+o9)~ueG(AjWWHqN@~gqq^3Aq>Pj=E zu`E-XDs!ZvG)?M@$4gyFniQocOImESq>hW0#IaG5q|0=*#HLhFmKwD@5*VW zBq>R$CJFJ03h_h*xi%>C2$K(|q#4*U>zv5|&Lhb7RYN6uh<)@IQUi!gT$7JXa$5(V2V13o@_%D}1y zyyH+JdOv=DSnWWbCDuJwzNg`j_jCjW$g}b(8c{@EF8Ad3UR$=YK7LAtk()lWC6K2VlsDYY(Hh6ShtK56Ga5u+TBEElA1SDN)hd7W_FK7g|A|bRJk923NJ`6> zCgmy<@+|G#AWN37Q&}&I)X;5RxKuinft$7+uzvMK|4q*?3Ob!A(}=^*61NSt1-f3= z*3FO&n|GSB!G&}A+Fj{)LqU03tx^Db>)}gl-K7EY$@6dI>W#Bz&@!+pKD$_|XSB%5t-IvH-Nzux6aDrwHL(6N`bC^DWA*`$5$4b|-rp=fyXD-~9V_JKO9G9XWndTd* zFLt#4lxp3VS2e2jepaF06Ik#HdM5EbclEYGzNoB9vh{ooO)auTt#`ENc3p1Xvcm=k zZQ9r^w^bqBzI9)2UcV`~Z{Lyg7cR-!bC+zs*Q?iV$q|MAw&TcOnw4Se6Z9Nq zdai=BRLM(ClJwZIk{&%uvg5``enPb5#YaijxZ#qc%S;7sMr^F4L}}GEYMfd1sS4Z_ zwc0b1QY1;O`9y^<08UO!F=0I+9$@SKaDXc?)6}|U8_@fDrotmfVUm@aX~I4vS&sqm zfE`IrM3QVB=u=a$_5u9?fh6E|OBtY&hGicPdAH~du()b8pDT+#>smn#*nqYB+5tUQ zElab~H675C#}xqOp#TupvFNdgvFHK4H^y>q)@gv{TDfL-*RY+TaLrU$0d;rN06vGG zZ#(1>EZxB3Re&j^MhuTqtC+z|^uLd_9yNpwnONOmp!axD)P#eO2EY!BUd!eG3|X-N zll$j>xJT|O=xLPL2U7C6b!-;0TE{eM+F&D|za9(ZWAuHF)8|328@96*Xn|44hp@Y8yw?r)YCUTd@?OKC=HoR0^5JuLCB*e{o!)iT{r0AaLM|se4>h4ME1r7* z`blb#PMI>p!k?f(l2Wr}=Ir^_r`@e-p#SvwJM*2B_CnKobsI|`g*tIkqg=RrM-{{i z>3Q}(Bp>8a?`wIW%HcuJYwH-&qujlyTuI2tHl_{N>x6f(4d4I5#ho@qXUFn2`X1}e zUr$$022=GTT<}EI;uEGcNhM1KDpFoMT~cz(WNbpF42x0=OsjOW7Oj%42T#deJt18z zCpONpe)i*YN_2g;v@BgE2Tq^2_{;IkV6Pfxd}hAnX*H#0+H9Gx7qD^X0Xd_Jg^9tB zUAU>B-!41ULcgNgYWMXUFtt#bq@zOkdtGeOS15hU(8TQZ1zM zDLD#reL&M&gi)|lRJm18nI`!q6YM22@d2&dg~b!BKkL+nChJ*3EE9&gGxI;wz|CxK zv5B4=8k=nClRh`knk#iv8f9rmr<^@=UT$2wDcd$}mW~Arq^-G0rq@(Ub#b8rJzI)1 zGptt*KrU8*hl_*1EGJt<;jH-(6hV*{C<%mh(m19lBi#U=pPC|hX~|NMo@(2it5`u_ z!f{$&aaOiMK25R}oEh=sB`qda(xPJ|BPK>Nbv>PBT)fJ7$r_(vlA)G%Iz1(H8NQyX zOF)i=&N78%Vwzg_fz^%xb@l;u;BI+UDWqx*Ae%-xwe0d#^0V@!AiF@<^A-Bpl98IB zk|~*KD(P90m6anI8Cj-Ku=)ebpMf%g6%X9qN(Sf=`V)IP;@ug6YPh&^0Jt2_v7YV_ zCLJZ<{p5i@67I8SKQMHQpV|OWPf(?Y1y6Zaj+W<*uB5X>*v}HE0Wz$5w`AFN(9?(9 zt=n+W`#M5CmZV{oGOCrBQ1ryXO#|?V?}9}O6oGWm02{b%xHorYaX+L3d}8#(GbRSb z$n(;rfnLi4l0XztQd3|Xe>nTxWx^mYpbmh6a*FHqTw{Jg^8)`jU z4>K)~z-_q&rPdfat7V~$Se@21*OqM0p1V+MPSXv}KpMr$;HKAae^Q0;!Q|P?Z{)Tz z@#1AQ2JgR=58wTV`RJL{C{h0h3|I_XTsQdX6H_wfk>fLD=-347rw-JS;i2Wo*i;!6mnIoSmD0X)lbpPAS9;$6B=;5644f)fg}{i~ zNlmTNsh0V0DTCPN^9GjRaiE8baO`fhm@0Q~iZ_1rs;?;jIcYEL2EK?T=W1u(o zP;YF3R#Cpzsv_r&Qi~#5mB_dRwJg#KB&)beDpVQOOlvVkM6ffuMc#V+QnHIC$kz&b z0ME^T0=;T?{fUR^!?13b`cMh3M635;UZPfaXb@qaS^fMhF=|D{r%GCGvGs3_dWMwz$1m}X?;?V zmST`c3KjSW;LlG>S49BilNI1e3VF5A)jAF&#>N34X1T}ERdl?hs^y-hP<2VwG+(Cc zv&&E*WGWES5q(}6Ng0xvtj|i5pEZ@GRD6U!Gqg z<%K0uoLe9TS-C2z1oRmf>T@m1D>Nz4^=yTHT8dizA>ccxfv5|x4u?Mi@Wc)f10FR{# z$lNzi8r%5pX`prZ19=C%yF6I>Iu<&E3Ka*dRxNd-tVq%-;#LRUJj%se6Cof;Um$&b}mH7*n1m&44CE5UsOU15}#@3LFg?-!$ z`)!PeD!6Lp=v*~kSFh`qa~E$}m+j5l_DT7~I+@^Xuf#mro4IogEhqBCOUlVtTfMAVDbC=?KyT{#;L^&Us}_L%)U`*luxqm{TC+vEy7$SsTMy;Y>yH+5d4Rs~5o$pf=!G&* z?4>(TY<|RZYLV|ca#jwVxhl7`N2V5C-Gbav5Ql-DXz=0}m!3Wko7CoR3!2k1o!8S4&O|K8%`rhkLLeQYR z;tDCNuCqzW*+-)YvBC2TN^DL~01n`-SAYsXFxCxl=Z9b){#=AKeg=+VS*VI)&g^+| z@%$yZfBTM{J$_s+pE@lEy0@9@23P}PmS$=9!8+|{OMo6&>{#o7|C9JJo-att_zd^~ z013wR{)0t+@P+&%FugHXBo2OKey>qU9_3jAEj$prWe64Ljf#)n(PfYMzxz%v}~z?*c3KSEl# zLICo9Y|W%PDbedH(CaJKnjgv@@Bu@&a@pov0E~PmY-7>eK7~DS$5n$%2F1bkQ9job zSnzRX`Ew7!zFUefiD(V_V6-I@jR?&3kP=qZQ&Skr)uKJ{4iSgiP~ zX`lq?#L2IoG{vqN*yEC7oo^jwMFTWlO{uwXe->3zuNjyI01ez7K-8^i(%BDO0XxDv zX$YXFCkuXO{Les=hDVlT#w7%>4}sYv)W_Xw3HsbPKdvR~2e0?o*I*kuuS4D%TWKrM z^LxB`z)x8y4a#%jxiFDYdV0QvgPuKmzC3&W#$ewzf3fb@Z-X8?dW{}F!IxY+Lj3(; z>cn6h1wcpxgn2af9Xus3UVo=n`CglXkxAOScO91J@6imZv{tEy>IayZT_Tgz0&iQk*4#7ewjVH8 z&0)CbmI zU(5h~fI#~b&;hxAMEdasORY9q`X|_juaD55j)w=-)3WoWsJvRz^&TSiql(uLmjN4m z@L1lZJ}xueIVd;MCet58@dbaAV& z1k%75u=~;>?*Mnud)nvwK6l+X>;u53*tv3(lT;EF@(Bj|oTOw0Jd!H8dQaJU?|?Ux zdkF)1mV(PAJ8blm0rNbqfjaB~ILorqO0(?UY6tc# z&4SlF98WoP(M$=2^QKQd0nLaHh1Ciuxpuzol2Wy-^90IfZ&sq98Owph` z^cnd5<0|rQlvwB-gOcdqp9yW4^Ec>W1L!FWaaWBW3+%D%=cvW}wD*=FFArlA$h69M)QK@GIvRrEbQE1 zGJp9xo6ohdvR;OV+&MtIeDVy-$1yt(pOvHMZ^}6ZFIN76QM| z90NHnqHX(6$ZiETT{*GnQ5pwNU$L~MYqv=ZBXG4AfWoP2m@PBrbyyFZi#H!jk7_vY zV(9_M2#fHAzKpN+VF7t8`p;nw_}$W{s)LY@mF|G|W2_}xh2UtoYR1JU8T7I6ldS4W zOnbFBL(m59{^4WYxZ4J}^AnR!9xQp30~Q?vW+s$Z$?C3ka^uQ1S=rGc6@~d`VP_{M z7<7Sf;7`Y@4`A((c6SZnM)1i8k}VVRa{8nqKhI=hL4IFaIPBeZ<4Of<9@umKYy~~O z`5XmrUTTKqrlddatGsR9OEd$w679rib92V}iTI{Ot;I_5pVw zpOdEN(|m>5xh6$9dLL@3SC>~9$S3N0WnrPhzEG`uEc_CKJ61l+nzD*M*qfA;O1b7K zQstVXkfduO&;+1B9?Kl4I>=pstOK8Yz@2o5Jc6aozHk@=Mfb-eynoy@d=G4U?GJ0; zT|1P6rH&Hv23XDy(A`}_9+Ut^0?Gy7JU)0}4X7Cr>Mjb0n!9wuEqFl3e&1$EIYGC= zAj|>o8$gf63W)tX=KDo4vCaK(?YL{)W#erT{0kUG{4WmQU>*VD0sY)B4v<;8D+TMD z?w7f$Jc-MLD~5RQHo93Y<3U45TNqWI=2F9Gn!e9)E(6m6gaqkXq zhrEyUMF70-ccp;}gnKz#3g#H*DT5ujmO$3@tUD?>%}c4|I9A=cO!Oxmps{P{R8Ft4b;+$$`Ts z%x!}u58SchuUx-p?i(6`U%mZK`q2oATLphPQ~TX~{7UYqm5z1JK41@g^DCyvjK~z}o zx-n?$%S3=Uy>V!$1?*$h;z97myD#5s0BrN%=#t6)vHYC+(~>^{!0W?hkVC9~?CBxU zd)1rjxm!J0ZQ(xzKRMmaaQC1T_|XCV=8aqA@csibxw6utQvzS048)P3VKv+Q^+7M2 zyii&Ic5i(B1oR*uOUkJ#DwJxqe37c60_(X$I^xHa=W98ka!s*hD*RQs;G?G@HeaDz zl&Q4^g>j);*QDj9=ufD^z^FW3<|&+A^7Y<-Ns1KgWjXmK<@y7cA^FATZ!gO)l;Ug! zetMRk14TsRGx>1UV7Y6puylgdmQR#geTFr3?K!f2%rYISk@>6fa_qV3nZ=?(%5!|fFhs_gS;+1(3&-} zhT3iTPI&k3&S5{0^t5Qc9fcR?;Myn`xMSt}wQ*io27W#)cz_Swap3@Z!~yP0xBLM* z@Mno4@cpagX7e=^WbTbYBd9K?tyFNzPNS=JNLpm-#h922PgrodITr}QUL50 zJU|Ed4tIbIq}fL;fJs*>Ce~OD1JDD>z_%S^(8R|L+(JoE z_TXiR(6Uohp%UZfgi;v01`p%zWgt~`B$3*Hn+Ui{Qg+;tsSf7>iuWd z(`NIYqkYgvu<&UkU_a9eMyKRTLRPWNZts+?EqnUrlO^yNap=uYKf7I+FdX1Ne({YI z=(&LW0DUO~^<_~l;sKhr)R!_yU-ZDCT6G+$AG(DtPBG2N2*5#ljCI50rK$|q4`74} z4;|kZ5~V+0d}6vaXwah0M?*I%EEakM@R0&~egHs^#m>?#9)18Ud|W#G1o-Rg>KkNx z_YUb=xyoD%6-7k`d!QRY7>MU6ob#;*P5|lv&=d1?zk+$9u2*B(D!5rr(lSgG>@_9D zGFd@5rL3$^*sduqHmNNwv9$UL6Ku(G6}h=mmX#&N8R;R(kh1J-P1kegQ!B``8bN86 z!Z?$B)C{t8JxD84>zm#>^Z;_PZ9Tp`4<%D9l|>5Y;_^UBCIm|bHEtMOFcb307r14r z)N*IvIqeIh2Q+iE~h! z3A&Wh8)uX-zbw|SD-Kr-k-B6*H6N~(=fZWc&AlRA56^=U$~-^T-93aNq0I0uj)2(* zD*;o08#($@H%$I1!X#76FbM1UhjFcXED)z=;DGmIMq@o|c?^6CmO+~UKpvlvZsl%bVpk$Vh*-UZm>!im=RwsylddHzPh`t*gxfj4gG{bDSR z()%5$_b^Or7mR)#tgNBy_;B5ZJLXM5iRm>G5+PYR%j8KBW8)>WpiCBbu9f2#uF9IN zJEdk?v!v&hm|=>?fpgG(oU$j?&yWL0P8;CgeEd=FJ$^3R_Z*U?E7nR|`%-CJ*dhHo z)@(J`3K1*m34)5iI7P;GPR-7Xuqu{N^T~egb#z!6! zwkMT@S=gbxCLv3EvRc_wDypQuqFSa-RA8$#RMr@{!@&&1No$-`BhzaqOVgA(nKiY+ zWOjqr5Oq1Tu3lzLp3*1NYHBS%ihw2Cp5}_7M$4Y4*8=QwwFW`7OnT(Rsig|Q0I5s3 z6%BBKD_{loz|#HqzRxXu8f3`>7{kjWA20`!D1DSaH9Hz+@#}NUG=)Uxiq*1s(K4y6 zsW)G|_rO88mhkfimVMC0(m@WGJ^l-6Snu8#OTTii1=mj{*0O%flmqYyF2_Dsc3#tQ zfCF=s0@uKGac=ejd%qr6LLASw)e=+$Vaj zaOt2_v<7@_aRLC@Hr5n~e-_VKn(cmspKD#2kR$0;xJW%c^4 za^U!R3wB0u$B}w$Mxp-eO>?An`Yg$xP;G%9hv~Za3;+OBJ! zFY9+4k_RuokrS8h*g6w^19}=@Y1~B_0PH7kf3SvF+&@4Z*A2A@+&Y|_ngbJt4`Gy; zf}V7?Y2f9!X)TMa0hX9I^E=kaJZcGQ(KC8=;-u*Yc^Wc+wtp0K*(WZhq<>Gjgm*r0i)TKaTVHcVZJOq--iB2@lNt|LsmoTkaD zBx)6^nzv6vfSs=5*EmBz{u#A;ACvVwQxw+q(`3%n>C)0LL*_O%$(%;r4wIH?(`D}T z88WYFrp#}iB@1TFHd#1(jtT2+Gn;LH>x?GLj{<1cd-mt`OV4epUQ4Y)f1)a#q7dwf zmKhuKDa-)ya+rn-Km%j|7l@IMbifDLXgnp2-ZB%_N(?O80D^#&GO={&odeLR_2Kg_ z(jR$l%Y2z!JJt5BSl%V)&R&w^$4<-ob(>{Y^IQWnH3QDgHEl|K7EBi@g5u zgD{_K#iS_`r?vUCoFYk8MkHYvWaLYF!366bo?BL9^J*|AXk0?3DuN_yGbHfXo%_A= z?Ctk*_R1ZbPBksBOt$SiDmNZJlWX^%T5w0A3nVIo2J3SK@`F(ndjEhP1(2lgn;7;3 zRl$-6x6vq+U{tL1YgxR?x;ElU0m!&h5G-zb#{ha$V2j>sp)0%$;Da8K7=`Qu)wS#^}w{KNZL`P-=9PR-qK;fE|mT z08Y4YfIJN#r1?JFJ9Os)_<){(M8uE)^fb6s>rcr!_~`t@!5@#6=3OZHk+Jge*W=1z zoisqde0ir?^z-JlNQ=S@Sva><=FU`jH8-2gn>9BHrO$*A3$z#TpW#m@@EFDxV_B$Ob1eU&yK%;jRmEow%bKo6n}eP-hq%K# z9N?sd*9f=<%5X(M9#;gcqeSqtS5(!>#cOwD_km+Ffx(h(i)GvHgL3Hf1vz&9n(R1u zLiV4yAO}xfw&_c0S0v;*#wybYMvRHG7&wfEeWpfq_uiwb1Tv(ora|sJc_j~Dyq8|B zF%TE*R?kaWsPA>8-uG~Q&(s=_;mRSb{DJyh2k3L8%@X)iW3cY!BO|3B-4>6Wy=Jfl z^xhzgD`$LWk-1aGsP+NM+Yg>H>l@!W1D$R^d8-!t8L6Ey&#e0AAOBTa6vQ;%ax6Z2 zde;E@;_3$LrU}eZ99ZrZbu-O!N6FCmO8CV)>P2x;ExO*){*s*g)Z zGteV^bglE+WnSAN`>5O^pj96?4Iro2jlu zq_bnGEM3?xD;6)7W$o=IzP@zfLRs9_CW~5I4YrF~<{AW-FIXrmI3^^(5CF0tarnC; zAno)0p6&uf0V-vO3+1m|v{+W_b-J+4IXQ-7ITuULv9xWWESvX9mbNOWRhGB4OXq^c zvZ}qq=Fj!A)+}8nYnLszB|_RNeJ%*+>D1@s5`M4Yut!Nb@KHK0Y&TDxCNri?l_^z| zq@twE23Qe7!J=b^z|InwxfKqyuv~!{0^CR=uLGa`Sn>{VK$b2W${m%rLUmoILZY0;UK3^ ze_R~1dudHV%XNseBoBfTpbI7CaEu)n0=?(;{_&|<$}?(DWmR(K;&plZ?Vseyn~w%( zKuwQ90x+`defOh0RnA^jhL$VLqsOPo%GH~#-#noXY8z*pyC=7_T6x!NW!&q1Bex#E zkZ13IkW057nd^tBmw_nI_4#APn*e`}qE|OD9=lEp8!V;L}?tLV=u|t5w=1U9$K11-mXHRuYScIbtW&Ot(f^ z`qvXxbJ)nZKG0hus(v))7uS#4toD%G2H!l}fSz^2vI2AIjk!$FBSz!6}|v6KODHxN}*W&QFM!MdJrbJuD+-?p{uWUF2;+ng6L8;mJu zA#euX1V~$90?@k_Ej3}Cw2dpeWV2R9H?8WjGAXZn-Fg$sr)=(Pou2=f6ae?ZeW6%T zWYj=@sdnNul$L2tYUNLphDo*7O|vjJ&*JPvD(D?zEZstN5CUxg3)sj5q{D^%_|n6z zc!#?KpL76Cn%5Y}1dI>Dj_^6cmOxGu!c4Y;{Z(ztgfhhZPr$@RK>hx3xx?+sy_eSqE-S#bY63u-
2v)&Z+&MR?|ylojKt5&zm0F7v|nnF1@ge&yKd7Bd;ON3a`@zVIeF=( z#mQpIKst?Fz4KIdt5JOF;%&9ue~`P%(CYe`cFeks+vV+tpXBPzM^aTg-R9R|y3+GE z?i=V2oV;MJn`iI8Q}{nIchHc?*ghGo_iYw^80c}`(7OlF4~i=q0#GeWg+qSVh)P$=kuHoa$X*UVeG*5E#0Eo&@!fFBW)YL+=*FVl<0 zMZ+4h=tme*0&ej~=sqAH6CWr50y^QY0r13& zV1Pz}TI00Tv!q&CqE%|Dg@XovnzNL~Hmr9Bmk{~@i=GBrMocnLhB!9|4jht$`wz*^ z?K@=e&Rud~&tBQB>)jhS%a(N;Og5|4k8E7M)@0qvE>i;Qmnm=+kUQ3Gl0BQY$*v7s zq}Ogl&%D`jMR*1KGWKOP}o8v{|;V z*LzY0fFeMd0DOl&iVo%EpvS8BnhO#Re3uri`uav`teGs6CQOv#`~pcyNHmKc*oA}M zLF@nou((!$7}h>Z_94Iy$h%twPy$Dmo`j{mKye3gPGrIS#jzp*dR`PPM zTr=C`VZR^8wjb+?2^SO3i{pU2i@R&MF0;55^kWoIOoHOE@`15i_gL}FSqs>KDqwfW zBUsse5Z7x%@X-T$uhAQbL)N)lB1o^f-q-iiiK(Y6hG~ z?}2p6BM*?rPtRz2{NZ$;gc-!%Dk!g!S#2G1{@Md;OYB^`L&~bA$;$OR1mha(9ni*f0BzpHt|6kjr-;DkqC&ke&}2sETrs z-UFZ?6te0E>o%Yd#tG@Y>HYP?Ql?>(sE}x$yFG8L@$)N%BNjatIQ`*0i~-#*aofm78|iF>AZ`Tky2$3Txm^PaC>%QbPdx^wFpH z5Bb(?+h=)j6)|#lo7Nn5>^~{py4-#EtWDm%cFSIgNy?D{Ljs7?i0U5-FOWeOfSsN+ z`0#2~=FXE7Cr-)!-Fpo3NA~TLqx<*E!QH!M@AmDo zbITUlu~|X4X_IVSzusi?T41l%^U9TdmOLN?h&!ke=r({}rx3*A#qtG+h*`i`>p)!r z>HEWld_a`40V~!t7B=Ow?rCgeZ9AM1u7kYfS+`=DLV3A?nfxxBRtCxfK}os7*tveQ z>`}1q-Lln|$Zox-oqA8*dLGW_wUuztW6}Q-=-n0Nuy>2z8*FKuZJ0D!YA04nac;gO z$En2~IZk4LynZ*M0kHlgV*o}-fEu7jX^#LX2C<-b305qScON$Zbw%MYM@R$wxHJ&b z0$2xrZI0tZpkO#Rt{2J*6bB8XC@IDU1TGtZOMZ^! z7+gf0i|gWAIo5mPxUxbixiwE-&f$IgJs*mI?wa0k%s#FSn7hk{9ycf)Y8bR9aBW;; zP{UAIDnQ9c%pd;Y@SbgE^>e?P&VP*nYPJD8zIkBnkoPxeP6_svhz*0EM5HMGcv zZ3pGS(+_gv!E-6EtTz|&6b1fch5XAmL7(|Mk6x%Ucq8|oyp}VUZb{vYxw5!(oy}Rj z`_L(i?8_8{gH*{30`zXptD>?VhA3A}M~D%`1TOuUt%(K#!VBDa{92yB|4HsXeJg4C z6U?8EMURC|11h~`=yijzjz9m@mAmG%$9IpPAIqQP@W11J0p<+GqR|)dQ)?ja(|12w zS54Xl7#&M(fd*jw@{E3^A(lKQdcIfR{Hx6!i{Q$6`Qgv{pc>4g$8BT5%Je7jmrb>7 zRLFw&u9LWEaNp1X>!2sy{qxiS9Qe3);u4qsY#6PMth0`*!V?gM0VM@q-5q^oREBk^MV&%I2mG#(;@GZbx@#yL^js&33O5mM zCw%mP-60S3eVc}7hrIjj1JKt>O+}@FJ}E9<#*GfZ4&+DaJ7hgdzaiicRLyFQQVV!I zJwq6XqX5@5V2Mv1-~&AX2V`A1&c$Kx@CUXW16&c-Nq4w&4EgC>-!x;k#h-7P($4`3Z4()c*^npoXg!Mfi)lGp?uB>oUz17LrCMEd>e%Z>{;hLeqEfy&&@ed1i+s2 z@(f%Nxo@7n{`3HvT0g_)cdeOJZ?F&A3j$@tdS7is6$Jk-J!>%5{GWCsjwSycu9v_U zPtO`)9CW#K1whCJK#ZT=6$26|0xeT(6p?!VnAjvc-g@aNEQ7xKfM1~=0zb=N0zGL_ z!s`>AWDkg{eYP^o7UD2jIl0Vc-)zZrG1fphpcBJ8mJs?{KG9z<&DWlLxqyhA$rQqZF{}x9Af0 z%`rVU(+57&>jU(3tsFHrDP)l|aA~Z)nBax0MWN6J>IeYG_m0KxmOcX9y)o7lfTmF% zX}EB(?s4NVrzTx2nW}5W%C&O%$Vs#Asn(h3g9Y|{6!ep(QMPf~Oxe5dkWDs%g`Zzg zBJ0*~lv5{8%bp!O4fMwj9FW6%_sW4?yJSyycb_%CZ3FHbg)BRmcN)ALj2PLIEKH2pzl*JD|xrY3y^W*`XPLFlZMD&xg{W zCk)*lfiB%I=>|zdEJ5&=FI#2hJB?c{!I`@Z=8^gMuOi zZqgj?;rqkS#W`4_5U8nmxireUMbCM$t3qPI-aV|EZk-kmJf>NjPNK zV*ht2jdOCoSXCsY6RNGfZb?U{T)B4J0*m#&d@m25ypwBpdll?z)xZ9+PkLT_Creju zHV*?HgSdnY$<8a6IrBQCd*>lJeeSwNvCL3KKsRt0Wo%-p;-DX*_lG~;L67UkM%{)$ zk2{Hhp2WlHM>yh9sx9c>N$i+is#$0N#eL$vWIU)Dt`{tG`qyK5<7S~NB(MkmxM+xp zLt`q9thimCefX30prOH){`pw(z@Gi|$N}y&{xU+Ayu{1FU(fmIzn?c@vSb!kS`CAE z`K{Cv?mW?I&0EPSsI*=;0i**z8ZU&GM`Nsmo(F}H?{m-tb<(i(O<{xt>z{N4*kj?l zpn)r^CY#U~m{E5$@_1xEguzkx=7~*@;Lf3OcKwD;a^}=o^U347!IIy%V~1JtKpwzj z#ha^Um0GhZK%Pd~&Lu%3B(MW~K+qr$41ubqS)-`t0notJ0qKpfe!L6Yp2jiM3Mj{+ z+P6=)5%!S>#ey%N^P*tbhkIycs63bO2H#I*={Y(A#egz!g@m|raq;Wmcn7>&^6ryI z9Qf|G!IB5=Sn=MUo<9ClCRSTxY<_08#7Ao_FCtP#D5MZz59r4!5D+YPhdYh!SoSP| zzJng{Iaq#!fe=g%lx&e1Y=f!wuZ0XvtTTWlRYu5aw8$Am7Es~U0sQgi7qkI{s{Dn8xJ1}Hm!YXS|1n?@( zE7lowMHfuEP!7=N_Vv(61$~rtuM8SsKUwv~W!2Ws*l(nsh&c4cYKa5-Eqjj21FbqR z(24NGG_10uM-1S_{c_^cZG$o{8zN8wc`S2!$_#h=(lg#DmzsGJQn=tE*ikTYN^6=nOf*7E0(m& zk_GfNZT&{L{_#hRIrnGp>0#cZ*ZMZ)|0FKTI3 zSOe@&{p7uOkoS>CeEstVS3vFqrjXCa4LIZ-?mlWZ2!~K%LDC4E2Ixl7FfS{CI*j=&s2CPOHxLO z)HckO#^!dJGHss3Cglk;+YKKT-`5EwGFq9W&jyR#B^>ZRdY>iTD)G~^#F8g6fP)^$ zhl4&Q9=0V&zhMeGV!uyn)E{ZZdh^#a7zx)2koVBRtke6Zc1Ej(GoXJvBUkauKm^&&BJyLJ&tN2P}jT;Zk9Y$Cffzt;qZ5mkI@HiLx)uvkl)jz zqEqZx)}!N6Bwl|8J`e^`+2jan*{7xDnPrdfk87cuCx9UE6B8h0X64AD#T^Rz)3RyZ zdRebf-?V0pS?y~()go5`@Ibv|VVf*!n=9?}T1?vJ%#^v!)1|FxhRK52Go`&{mMoe( zTR}ZXI$B#y7R{X{3+FVOkY}MD*WSYROqoBsN#@U*Aq!_U$%5t?(mHdR%$?Do(kSzE zeSxO8>oJS9+zvhG;uZz-Y&~|CmJ^Z%%}sXx*6Gts=FONc^Jh|?mOYben{H_>(}Iz% z9=gDVH20gc^zM(J59VU~b3eQL+I=t-qhDEupThwU*a>~$@oorwR$cNbUVT=Y8Us;U zRVSSAz@ai|zz`WRI6_9Lg%9K-73K~&4`snP2-;oB$|@~AT*&JXXC2r9YWk!DREMGO z4+p&qfXAvw$cvRsUK%-9cCImhefatOJV2i`&O;f1-OB{jK%4!5lso_&nEQ1FmVe-? zLD|qIz>;ms_8JLFfU>wR%JXw`9pTqSx;F&7f^lCwOVYfC0pOYX4;ib^hW#i28feYJ z*RlXI|26*<5cVaYr4s}K;Q1fDe|<3dNvZ*xy!i3~ci@T%qFs`gP8ES+s1`N%qyp4A z2H!mjgyTG&W9iQ6Zd&~Lq;q|+V9lCMa_!nZ+0wmNa`P)CIlV}l=Ps3v-G}7p>Fcs} z*D;w`)6{3AjvS-U2=0u-qY!u=+;FwPj9UJX5o0atq@S?1M;|UfIO3n1A1II zfkhvl1kMhp#`%p>tQIW@f8IE9fE_h?JHu84B-~j@7d5;3+wCc_qg#-PE*|QaNp= zG_)>|sjB^AQgbZS@Mwi+bV{~$?PO#vE+AY+14l(mW=W;wmQ9kviIXL(xYDl2uWc9> z|7gIh8eAok$q4iTjMN9_aCgwtpn-TFdh2H&f<2ZxBVhqO0fQX$t^~05$I^p=KFL@Z zXew6nD*P*&f)xPc|svI~UU@ezB}vyhxU+ zMckoQ^`bd*6uJty845TBW~(mS7!j**ojaYd281}MQ=m-=gpdTfoTcfrr%jbP3hvo6 zrpoN;3c%@_cY2*|v)(*Sk89NY$kfTwR9`DIrc9Cx zR%C`M1U)w)6FB$GDM9!H!X~hsq1!X-2-`pi1gz(3nOYSOV;Oe>Fgc z4;dySM~sxwBk2lAd>gg4#;OIS?{DPjkX5f1JrD$F4s8I(I$%UtCk@B~Rp3ZIVCqZu zyXDQ&A&O$4e8kIPoj5wUQGhpTemrFXRm2R$JP5Y9=O`^AAQ zY3y@1i^r@XAJ|>oWDFdjpK1S2%q2sjy zQvxBV0{hYU{k0qdhtbPrw4RSi|LOJ!m@&9;p#WZ%SnCG)kYIozC<2rPiok0MyxSlG zXRwd|mv%mP2Ze)v@DR1~b(`xNp%6wPpfqY~r^>}k*KJN%LIqdX&XDTKGv(N+Yx4Nn zH}d?=Px9o|cXHwSBkO7zF$Q-{Fm@+kQ2=-!h&5E7JCl?E>%sbtES9|je+c_vpu!!u z4X_`q>x1#_}f(pFZ=* zW|uIvU!&B`Zk3dxQi)I{FeW)$Mr!`F;wqV_Rh3zbyJYqD1G3}jS=oB>``j}I?G%GKt{ZpXAViTv831|8;RTS+ z#_P{#3ra!p!b}fZT;%;+n1JB*^8&EC4;Cu;2EGVC@7FsD_2NI z`$7eIW1oc%s1ah(062F!G!m#wr2%*Ww~7fC+^nXw#3m3Y3^D5#xv{cB8YWc*@p2|B z_(IF6)e72Bz_ck7CzwpGD3{s^T26VX3ESjptf>ybt;!=@NaK3yCMs;h&tLjUhz(EV zNup4e=Mic+-_{YLQ?kz|3<10jU*GniXb8d39MbIf=$2ltmmNg9B$V-|V-eCg?(^#* znr2CMj)hr{iBzj`;2;??aEJ`-KTxgtkuq+qT9A=rRawVNN(wWGCEGg$1X%X&ngD9< zVgaH6k0tO0u0Rn>oNa{sz?eJ^X9qO<0DNglg>~fw?DUzZF_!Y#Pa6A}7@XrMgJZGA zeF>x~$GcjR&#w!xBDh7|Wdd9Qw!;`OJM>ux%B*vY1DbFO_}IzM@eXV9xsVq{!8+wp zmXFZodVxTyZd(dZq zRZTv?%{s!mLmFif06)m%H3Q#f>7b|Q4@v=x9?-K7p)r;bx+oIz0eW0J7=84{d(!*b zV#4n~blL(gu3EcY?mm1icOSo%>vx|^&#UjH_w7&8z2}4skHne}3{Gnw)cdjlSXyQ< z`;^vLB1S8)M=9V{Y{C*fzdk2GK6u1913eZ!mcCi=;h;w;s2J#Rh2Sc|eS@{0pceJ$ zxKvAHP!fP82oH^+SlynNS^&}23My+PqqtmR)AJPeX);_PnLDvgrp;R}drw{oO*{CF z+{Fnn5Cof)ImR-jIoOMG0c8_-q!ftrNi?;~Qd=xyeEy{}kR zWTZLhvGj>%>3wBKqWRU*8#zYTRR~fA4Di`EG^#b;x==cnuC!_)eqDOtWas4B#MOX) zR&$d~RSUQd3m0ow#Q|lJA46hk3P6t*IUx*G#aY=>n2~A1Iw66>!51zLJS3QrDS)N} zkR@s41+G}jKp%1Im^1^Zmc@0H>NWTz;w=4|3eq!7Y~EQF+h+R0%q$b~AfMlZ?{{H8 z$h!4f%Yw8V^yR$*|^cmsWObYSgK zGo$wn&~(ck0j{J4mTfRu2!JPyfd@Eq%iKZlkmndr!&;|z4VF9kX^^G&jUUH(P#~1& za7VZX%3(AsN`PY=^pr~;6cTX8S_am@6{rGhhrch~QfD1lvjor{PX~yT7l^YYKTFbq zHS3&%ZT4ZUb8dRu6c@}4maP6C9$9`R}TqNr(W z9$@XjCjaN#EZJrq<-syMoh2?HU>`mx3*SEb5budYw@s{mz>gxpb$jXZ4SD(Uy+S_>0?r0(MK!06y{os z1o960Aqsjddjq$=H+Rigcy_G$UjV&NZZcfoXFs3~?6Hus+RZ;sgQTVxDzKT(uX+A5 zgKX)fsRn*VrUqey+hlIX3R%>(PF8Q*BZbusGDI!miH&olW8F@<^ZcVtGkECybzMGF z(7%=|kDkcY$B*Ui%UAO1&wrLv*Kg^0<0VI};2CX;&Hs--p8-{bTEM@*xND2`xS>Z7 zaUzI)L&NMK1v#*%`V*noPUue>DS$VP99ZgD?{1aTdj_E62MbpMK%Kc^$0z4XTtb#@ zBi>UdnwL5r%^PPAeE2A>$|~R^BGsbM^{5zC0QztN{>G= zIms%_M~i5l@X1Tq@A+9~jA!oI1Y7qqy}a3?Ct*M~;#)qa!6MiXrd{_>nZMQ>9lhtKdKPm^45ZpaN!KivW7UTrdI}E1Yet zdxU&$jXUTa`qUK23zUI5V0Q(OE>4@&4+J zF==Y)kSn*ITK7u)^^qaaV^AW2BKx@|9}fDVO!T7HX9_`|50<^b{=c#4tt^#((aG6n zod>QEJsFJx#9~j(l=7NsHcFQ82nCc0nw83g*#YQ)8!)qpxkDiIeL%^fj-sDtV95spk)NYx(oS({fP?AWXVfQRaj<7k>)#ButNUpFTaujU-vi5e)!N~3c=AbcC6Oe6!gP}jZ_!}K5G2aSnN|K zH&~;k1JzwRfEDW;UpYzvaARpR;Rm25FOYWFyVXrPLLRog`zGt0gLIZ0Hox(2)`1^|r!VH5!S9QGxDux380VV zd8^=3af=3#M_ z9x0=4+v)4b!vaW3k`Bdf9ryhVbz6MtNC&2r1 z(6ER;&~xuJ+%h<7sD5|91bR~f3VM9}gY};J#VY8De>_YfKLkxNR;v)>^utiFRn$(C z_7&^o((T9QGI>lRLvIiO?a|ARD(~gl$M5CkcR#5W{@wzi5!7tbw7Ifj=TUj}TRCvWAe!@{SuU)HfyiglTqFy5e+76KeFWIZuzoFt5mGGRSj#*Z0m0;J;9^7QSbanV6p z05eWO85h$ht`x$>VQN6ta~g~lehx*4DN6@&N^G~YTbf^sKKR~|x;}`PP7hjrXKWxZQ z1-C+WOq2=01+;*jsE)WtaI*kb@4W(avA|IVz!lg6dDc-3Q|qT2{K@N32jU26t zl=HbFK)mMQ>Ex%cJLPg7%5g=3<&Std4qU{+jR078$vE^G+{8NjSpr@J@B(qtT{+;R z2hM;!yj<2fCftV)&=FT8ZrM|&uY0*%Pm)^y0M;#QfHg?Zh1E+9J14(PTIMa5+=4PS z$n=@%y&LdRbh;jHi6dCxqY&2PVRfnN`h{$G7<7X8q{L)4-lE~7{5dx(jXoSZzf$N@M@Tq8gpxMC?|K|5UC zx(2|2+^u}9?Mc;Btg+Sixj4vyI7$O>lZRu&l>up#?E{lIj)qqh4@<5Au=_raXWa#B z8@CBy4~H@03c%q`!zn-pzz%pI42&K6h(p?DjM6-m1*oYRuw*}=r%d)!zMqG(yfJss zz~M4@&vB?Vfc;!e~UwM5-+~eTkBaJU+!7Jnu=Eud-$LEfc zquuZm=sD)+p#S8f56bLE%;F*XLM%Xz3O#FB4jvsNF)7(n-_#6O*3U^tf!IQ?!a)S#N>Pn7OLw?MLZ(_fD=od?eFa z=gV+?$utggjma6Bx3tnUd_lnkg=vj`AgMMo7GMKwpbhNZN=GY3M{8AF@1u6|RGBbw zqGV)h6}zz9K#vl@jf3*=2g^ssgGPq%B1Y;*p>Q7-^4UB1@!JO$zkV+|N=n0Rx! z0CR^eV4Xdy)m%8F0cXI9U{M2OlmOuMbcAh=r7X$`x9kxV0>@EHAg?P4&cQb2axS;h zy%vB!9zhW~I?%4wf1S_;o)^HgA7J~s zD--wKlb7;*o$^_CCBSh$wV6qG@4mw1Uv z%#ie=GO228(q)B>W{pcPlY62`ph9vgYNWWfK?*0;OF>P&Oqo4j z*6cW7Zk{iPMM+F*zJ)p7dHAeMnK@sEFc>N(Rf?+{EiA&3^Ot4+>C;lv)FhGPldMf) zl)^VAIa?A^vt`nh>C!xBfz;GAN?l!(B&x+9sULErK42j4edpbxx7nj&(`=^sY13y) z=c<)5ea1{FDXSFX&yS6!frnAB`0jJnY9Rap4JV%(OqjU^AAO`+@3?5ZFRlf@GV31y zz5aM=xw1b#AxU!c^m*1dNKtN{M1|mNkX8T#YzMkSedNGF5@ay;WK}*2$V}2W9EnZVQICYRgVpwQaX-+vPh4~GN_MWIC8x7*K?6hU;32%VoAu(m8g_dwdU1QAD=D> z8CpY7P>YPZ|BV^=4z@g8*f~yAR;0d6Jn~D0TIX za`5mWId=S{?A?Dv>KkWS{P}oQWHiDuF?hEA+!jkXzyzG`7GViI!>wnaj(Y~n8%0388o&!^9lqpaA3bq^wx_Z5^89$LdD2)%05mY? zSjuIc^RWc<0l)*Wv(5GRIXFM%vX64zr4zVcq80MAJ5(6V-IarN4#07zU~#i=?pgiF3>Et87D+rbVpESB)dgHG*sA3%#(B)MBALekT zDqCcs^vLQKXk165&D1uJXStSda?}C8yTnv(YiZexLW)w zgBA3HRFe%-3-+rKqvdNo2_cP3CQXy_$xX877<0vbFZZ5(uuutipS_XWy|1O`{rB?l z&37h5s!Yr-HETXzp-n^X@Nvl|BV#kPybOs-%2Cjl$hedYiHMC?#iAdrK2UlJCF(Kw z=xHdetZ9%L&2#0*(Nos?O^=r}g>_5}E|&oI!CbJJGEOb~B!zrdZmDGHOCbi$vgMt! zVBsQ*HQ(IaCUfR2l)}OaNmM0QUq4f={#jB!q1py;P&WO0@yW5yizMcJS$U-Z@jwp0 z%xIczT`UPpOphCS;gpt5)MGVoahWt|?PtrDZ8E=gzJVSX0cIdSIt1Ntun+s{YZ?0G zS2E;_FHKlC`Ra>6bba{O{ePwi9PX|ZJ{R(ZAM=ZfK!xjaV7m41Vh{}zY6%AF5QqW3 zxk_Tj8RS#rq9r#qN%GTEBr73aQliyD9u?#V!k?G#wGLMzE^NDmZv%6#_w#%AZSIHs zz#ip8djy~d{4~fC`-W)-7qqm>k_GM3Fr`j1(lV`w3x06`?@=8ctPW}5OM|OJ9QO~qiqcU&=k9M(GG zc@WmgOBYOl-~a0&HX;^ln2COJ3W{W`D(8$GHT0AL3{=E@1I(#u$Ls$OpiycOFb|;tUtvz*oB>)OpbugzjFUlnbNKRys5Lum9F~2Og-OUN znI!oYb+UEeDYxfCo|IE2MO6*v&KatjZ-jmFYYnkkIcVHG1$K!|F2TTurkO4JB6dkv*CulXty#NS zHg4*csSQmA`-aAuHVSU_nvGIFb%xBEJ``|x*A%p(#M-$dfzW75Rq3v)b!13V{4t3T& zpXVh#9E$&~kWYmg0TPKaP_Y_G7^s0N?v*43dP?j#$w-Wm@`5a>nZQU@x^C(_i=yFq zq~&*o;u5ZG+#)BRTj(z2^%@M<=Zfr?o&ot$EWjPe1ACw!J7$d3PpXmm&2xm=yf&}f zAk5`Ep{$}0ia-(=15zwzhpNLFxHEDU*9*OJ@Q42r=t=XMfWzJ)>@eq?41fyH%aU~V z)BA_>k%n-7j^%p7(*QhHKf<=}r(EuZ{WQF0W)QqA!(a>KSz^Vr5AZsO-S-a6-8F-d z$I~3#Y_pD{aAko2eac0_gewS+#f8MRSmUlSryoDFz8=eC7TVIe7Y#EL*!p)^zW&AZW}{J1RC^5;BWz zW~%K6Ps^EW4`g=xN|`#lT@IhUE{D!svp{JCI2)oL3JM6{d=S)3U!uZ$oK{V6v(R`$ zD?NTPh9qNYQ;lLhT91iR;4|tq7#zh6Qkjwwf;?6|phr1y45M3tGXSUC)bts%Z5>5` zB4M3y2b?dN*dY4TAnYgH0TWeFoeKi2jkkdxd4*-NVN18%zVkp9Em$NYLvR98fO43E z7a;Y)JWL$)$iUzKK?eTecY&}TlJGp?@=Ilf=l@wvAxr@{AX$>;if71|LH=R753q(q z+1G(G)-w&WSo2xQaSHhYX>OP#4b_Aw&>B@@oGOH%R^!JxtR2{1K4rT&-2Hs6gvc9y zy)IlcY2DRj~+jh*KfX&)vLG4ST$fHl$m|58(rtRaXEc* z%>-6^xP*h=t^fZD^rqwh{g`Nlr9Mz1o(&$U){BCFgg%7f`oaj3Ge|QtMOA-&QT?^R zuXXvgE(e&Xl~2H@Sk<26(=0^s*rZ%ZFRYTH%0_8y>5z5X56Y=4_vE2!xPzxJ%i^w$ zvTnydwdh~T?jvW_LQj_Q3VPsv;Z~2_?R{?}VQ0=?Zefd$UASpJ`cZ1R59PYldLU%N zXa)VSP%Il_(~MJy$I%$9`Nr$DAW2D?l9g2`xw$23+2=`Av{oDAGbARC`0{Gy7^D^U zYI*b0J(3+C80i3?Kt;ft7fBE#_VZDA91WJtiW40jq_K}i8LS2eeL_OI`5Y7U*aeH0 z%B73fWW(BxYS9lf0Aa~H;DNov*aavL_}%XVpex)5{0{kz^#85OZ+;_RtMvcvZ$s&U z4E#O$f2YTP0(v;)`~Oz+sSMO|2Wwg%#6$8qC=rey_(wgSGITju)42X$su4KsV@Hpa zAQtd{z!VkyZ{3vpzG0(h{D7!cGrMub4kb70AHaS1O!TwF1b z$FG-b4HweLOU(cU1n3#JK%e^j%q*EUrCt`d&X?WWw#&Yqdt~;EW+}{PaF0S--{p9N zVwwRIs~UI$XyD6|Mpj@7L;)?rI{RE4v<_&N4r8_*{+<`O`!?$l`g5~HNJ9~@AMjHK zE+(!AB}2n6=l7Zc$M`zOlArUVAROGl7Z(nGa-a@$aTWbsK?I|AfiY!z+3fS{LI5~r z0(#2ACB(6a!`^-RfSxq21I0tySiQF4dOs0*yp2pA6QworMA^1;r<}QXQETMsGDwx- zP*ox{o{ms3MyTOAOd&l~j~k)z#bpzLlG1Y$562p0N9(g!g~q>%QHQZctszn0>u3~% z9vAMb{{;3xSjWl_CLkGOzJG$6p*%49%(%=hGNUs^Yb_=zL6qCZ##wUj-V=HC>RVZ{ zV!ezRL+IpSuoPB(#7KRn24;PiqXD-2+Vz}zUi#5nC=X?m|^;ZG*u0&iJI2gl0=?cP?1mfG|1+c#aX1amKj2#`ex0VsLidHR4`tx) z8+rl(dO}MSW#^iIe)jYx+0eB{RxDXAwUsrJo2@lO0@x|U;`H4mD&T>=1K+K0mh_Rw zs&@<8!432PDoY17`w)jMfCiMFk36KY^s;~}=W(|Y``qeh+kp$X8MRA;Fz2IOY5^#K z{$Fd&QP1h;CqHmSfH7{9`nu^-F=3MK4;oAXu%83r-l@6x@tlJ)5w^(_KtHGjP=?n6 z5Xz&rfEx&90My<3_x)^B%iuVx4R8)MK><#TPMPGP{jR2_!TxK~U_ihSWg+2M zcxL*XSi*+N$~w7z{l2_V9xhq3+T1pPexw4vPk3&;GkxZa&$0gWD%>wM81Gl_VrhDf z06nneBTWI4My&ub(9_@42OALhKIm{CC4*HXd^vD9-)>nK(!s+ zJ()HOr4kjZ8b3;_J;PNg4bzvY4=XZKtqiRS0elBNzWMRv)2$0-aWNqX$}J56&K71= z#o^5hm`!0zc z8)d)+^uQbez7F^QBxbz_a0l$j7ytAt`Qxwt(S&uxfsdF{;2a^~0Y4xZUao`N!RUEh z0wwdy*F_rn0jvYx0d4UA`b!1*KuH)kQVKE?W!mHlncGySps$v){45z4FyUSs4j`w-fS(?qlMZw}zbh9M4f&}F zj8ymnznED4$H(E~2;3QFtx~Q+HM~E3;8F?t%DXR~CEKGkA2o<6lZi#dc!zlVr`bOO z3s{f;B!Ok`(EmC7M_XIowd;3e&)!335W*3RyfF$^>$<7$$=d}GM#rvS-z_(9K9Z`c z2E88TZaCykf|>`%nl&E+eK3FuOa15K?i&X^;fx*h-V+JwNB>knj{tfsdSH(g56t@y z(SvmRzXH8YNUMrr7}`*+Z2HX~ICVu{fA{Yeqh`VKb<(bu`;LRBYzjf94!rUBxlJPe z$03pO)o{9YDo7RV-oqv}zrrkfCM9PO7C!nf^ju#JWAv{6EHOa{;bB8mDGkz>p=I#U z(2!Jz9QIiFF{(gVPfIJ1ii*h=FP^SWyj&hWFN~KAkg>jjJ1@*3Pnv%SZn={Nym9XY z#{`gfxT9QHXPPlr3W@qr;U1#5&YIO5W#{(YGIr!>`R(8Tg97{4@`qpjll<|Yfb+k| z7rKpnsq5jwJ_r0CfAtUYhkyKgli!DyE?@l9KlbG_;D>-54(*?n8`>W(q=n}}{JOYK zuGg=Tybk-%Ax-*#-~U!d4ER#w#*C2sj3lWpE076=*^(4JRz@1+|JVm;j^R2f)2}Oh zJ^VZl`0#UvU%MaY$CB5rdh30oRy`wSb5qi6vT$HuJF!aQqO_*Q2;TTagZ=n8H30Oz zJM3}eVBG`urAt;wwt{uI{#>NdPzrE?E#L-{4p@gF>p(Mbfdp*|s8^Sumbs)k01u!)ij4}m?y8v>|rWyUGE^-G`+&W#&Jj|&66_mK}5hdrRjbpz;0 zCk^liKK?P%Z!`ms^kL${VZx0leL3Ng(SSMD{eJ~|_K|Oh<{zY%H{B(tD#Vws>z2tg zS|z7+l0}|m@^R9bFnrzi12S*v8k;@pk3+^tcBxjA%N4?9wNlkEM;5KxEE{(nvAJZK zSC-MUb+hNopvYMHQWel(y(uQm9W*FX`uE3Q#)IKS1AG0L)v_PQ=vM_i(8uCuSzKHt zWo0#zmse(h=Ed+L!a>i{t$ScjwGJ&!8u{4|uz@@+?X1VC^@Al3>}}dHwJ@kQvQ2)< z$;>Lyb63mE=DF4%`Otx*GG46{K>z!H_(%C&nEd`9e`O$b`2P(025_wS0QA5A$G?-` zA^-4qVX*&)KI`7{e+E6o%X4`5mH$~f!Zn18Uz-bg9HxNS6$)u~yj}zC1tSK0B{8E$ z7~mODHN5{e^UT6=0hg)( zDJ!XvDE*J3G>v_c3P4;y`H(%Ku@>?V$lOd{lLpMGWrSZ7<&tJfpbxZxRd28kt&@&W9){qu>pmjlGth^@{&UE?IMjhXpm!_Z8)Oai zL{1w-SDKEiB`z&raulkBIR^5CI$pMR zn@wtR{lRmKo5O_RxMl{a6%OF(f8W%$O!l9=ERSD*FFkL5u$c5Ozx_9J`P_Q^%4!D# z_2mxG2Q`Q;p2Nn;;Gw}o<00|l0WD!j0W)w%(4IWd7Ak0fc(8Rnv zmK^IAJs%NE-v;ae9-)sf4LV4UT0rR;xq2Rbf%ef+D@d>pkz?`;%Cx#xZ&58TUA(Ta zKO`yf3G$o2`+NDV3d?Xo0fa*zU>U^BO{0+i)!!P_0lb0!Kf(U*Eg#l>I55M(`QM2{ z9pM^WxR&s3uFv1G2;U_PD+N2 zk_Glm8Xl!TGd}xhz7yRB^eov<)$giA!J4DrM1=lq=?cpf1tp;8xCH$kaQh%Bn%DgQ z`dztoj0MgTcmh}NT?3@CsvWSbW5EM=@&aHieUt^j1@u6dZQM!j{sHp97RX}FVo3v8 zfbMC)761mI4ctkT!#Nz}T#rMZJX}ADg*@!1RzPjRyKTC)?gCgjkJlnd^KAt9a!ni; zM>JjC$Mx}l)=q9T!-;5d2&J#e1{X%Q-Z|D4kykC=-^_c@@+?@U1f zxWEfoK=*1ufA4;e6zRLbIOG~=)b;a+3)f=Tqh$bj_da~G=7SNth}Rs3Ip}GS{Uyv1TWY&VYX?>u;o^@azZq0{_gFb-0UW`7>5qd1KaG0p1 zMlEyV*str}FGo&aR#3l?J5OH8wfj$H^X?;(tClr0TSdlaNNLS<>vePF+zom3>N~l7 zx7XIO=7~#xO_jsrm*3ee>O`v?%mYzy+caF!srJBlA=UtbH67CK~l-rs))Kxj~ef`3Fv`4>r~z7a!KP3H30ItlHfzk z)t_nFv^h3t;?C`dvaF+1%GHAW_22xh{L}yZE0bTT{NrE#Px+_6`fK^;zy2Hfm%shH zK1exa`#^4>|JxAg)v{Npn}osMLGO?Z7t)YEXrolZB?R$b0;i|@K41T%)-=AL{U8Kk zgme7iSIDomO!i^D|5nrgMUVNXpB?Yz+qtz?;`_p{#o=$yLdExymuuviAv{;a*IAMm z#eiSmK~MMudf=qTCrVaInknC50|rafsIih1n;;X4%Oy22RfY{2Zc_{bW&~)DRxki} zTsAD3YZlnfZJBTG5?~7?vBXKI7Jy$LR}a4Z31yY0Fx=vH*drXvHXsF@xMCc#2yP!> z%hEyX?E=7-G%Rqo!$C~BKn=GDK5{H))&VK$fDgE`4xodyz*^^6cSUgxem$HIA)j0Q zlpFNgDd___LYeL^A)RaB99a3jAJDT-x?ht685rBx82zvOU-f^t?>|;U&tVU+Ifg#+ zY-6>1%zJ>(l5^Wq1y`>3pC>$zviRFyzWN|HZ{4>^haB{gk%7?(Z~DL; zX3-OS2d_g?QjT#c9Q5>-0r1`);On0^!v0J&A20{>ZqXyaKWLyGEB$bR3>-rE&tQjZ z0jdnH8Cd?j1AibKV_hs&Nf0U_DZ5CfsP*2pWv?7Lb6w8gxNq^}uiopG;}>q)gL3o13whA1K{QIG6;%9Us*l^dvN-|Q3mwJVdN}e#=6HU2go$6 zhJznLgHsmZCNCcv1F{I7hTng}gc=)61^8)f<$RRKk_H(3^{ltdT_9Jl-Im+8AIr>{ zbESDkvw`Oy|KfkhKmXPLlwbYTU&=rH<^M3)JMbM+Kn(fa-z%{GLBSppApaW`10lS?XheO^W>Y#PNehyE+hR?0@~3)}ZQ z=sCvsu_VnEgYVIIFX8gen3`4&jJ0^4uc78h+|GnO;^0Kb3Su!(=4e;zEPXPB{7A*Mx1o>g% zJ!}Adz-?F##{oUk@2de3ec%o>0DhfMPW}M&$j>3~GH7_<%Ar4dT5hQgh`MyUM_#=9 zvpjqMqnx|`Kvr$qW&V1iUNYb8NUe%7v3LIw`oiKeq@{h8b;HDELzm3-{E3pBTW(z| zr_Np|8@3;m^Ox_*Lj`?aex*bx=xt^eJtxs6i9|VEubYPvIYwWqR=a^Vy=^iw3Jm55 z8kb;0ym-XhCmpuA^GX)`*@KA*aAOw=YFjK!r0H34Z3;y@|x@pojuifT~#R_-O zlb>~9>M$pbeQvD-ThHTe9?s!#58n@j=`T-kGJp?U-C{<7sRI`%V*PRst`Qdya7P^c zEFJWIO`O9OhC`WcKNs)^*pzRu);uT!@;m6+2Jn7t__eX_@OP*>;4#ejZ%G5P?s{R# zF?L)C{4PKpz=m7U!MZ*-1u(}3zz%%>h=cy^yYCG2{OjSaU$0>Vzz``#|p!4t(JC>%aah1O0FR?r(nvdaQTcHV)h0x*||EZHglwGJi+YX(F>-rq> zcD*VNdbT+RB|_Ukcvnl}^29J@;II)UL;DYuVFL!q$e|Gic^YN`{osK^Btn10s4?TL zLDm~q-NHBjxmy3@#wnaFf+-y<6nuqYEYebD#=n4VnrhK`1YnFDRs9oTNsJFHo{$BD zPhc6AL+3fe3KJu^HZHc&!^2X6zHuoUzI;055; zDK4I9);^7^ycon^6dIa+G^PS=*U}Drtb4*F&?qxSEi%gB99|pnkB#FfgWAJ}joak* zorluf`${gIzaXv6%`*6l-z#(#UJCDjR*(buzx)6E50jq*|1T9@f7u87KFeNV@1Vz$ zrz{kKD+33*1N1i`VLjXu4hOS?`e)$Oe81Ln8t7Gk{y+UykRG1zb76ltn1B6Ox*iht z`FX7CoVg5g-rjiBTV^Kh-Fz z#{-7Q!2W~GS0AZA7QS{MkAEJw4FaI!;*<1!(;yEV^#4(1F;tJImI)NS0TZj+*MU5M z29iJ+K$F+4_@)`NWpeFQ1zX@I0kXc2^}&ONn*yL5U`*L42Fjs)KulipIE>x31NdAV z>Jgz9p+Lmre57C-FfVZA%E5daV0@!j_$3@;muj-^2szk2}oUjjY8`fz_e zZk{+@j+X&L$1Av1bEOo>_}mGSSw2N3H@DkVf;*0$GmHJ|{pWK3`A4(bne&yn_QaJR z9h)Y#Gv=9Z|K#Pna{t*!bK@WvZuZFPO?ze1lvxs~mi)khs?nqL#ikco*kL9T!F5BN z>Snc=iC_uD6O+;mwpQiR7sWdLZ2>gkMF>&M1Oa>;K)cV~qQ|?0H>$bzkunQT)l z0OY)2jv?KvZLFi|DceITtXaEBE?&B-HGw@+QBo)ae*YW!;@7`2|2FUj>fxaGPl7)~q!j_Uvcp*;T32C3p9G*UX2#GBYwVGEbg}Cw{R5^5rL=P=)%G zD%)oa(2+UC2nhJv}R#ozw)%& zle+&Dt(f4v-GWX%P~;& z%7hkyS5BmZ0eQer1;;+|06uX5Gaa(7X)xjddsIH*fSl1l;mRlcoWOtb zq#45SP0AtViK*gWS71+tL6}z#+=om@X5>6BoZ7l3wFW6EE|zXx<0R(&cWe!t4_<#= zVf~T;%ApmudqA(S1?Vkf<|D%{^*9XsHzMwoXjo!lSh`spg`tDd!`bJY!`Rd0oP*Wj z>S4Z*`TgAjH&u|nU)ypnxOaFzY@VjS7q1kbd-So$d%E{o!p8NqaNJMtOCogd+SS}P zT~tN2fA@Xq@ZJXs_|9g)zHXB17fDm9?b2pk~i;O6@Sd~62Ty+N@l*@|)j>-1qz<$bfq6u0>M%T4s_CF8?+EoY@9ul zvbaxJ{d1l^1V-$5=cxmlE$LA)u%%T1FezV@Im$L=jgpQ|^a13-r;Umy7Fy>pg}gAUqYu^e~r&`jW5nxynBmHe{4(r@@wS-$yG*?#bZ z96WtR4yhX7cl^BUJ9^e;$+AeHT}?52OW>D_!+^eDrk<1MKsEEIXXblY0pN_D;g8GHGz$vLZJ%>MnhJngoAv1l=eSz` z@WzJzmN^UZN}4mOe?^~8ubiwxsVJ+J+Uf>d5wN&OTMlXZdsDQAj_DvB6!z`jdcz?7 z@>4*}-8O6k!*%oWQ%{Oo{yTN( zWEOPFCfbn7qJk1hQ+OvS%xxr&<|_le!iH95rshFlkMADHvu_`aS0FJ26NuxR2g+RM zl?6~|GF0FO36?MB8V4_sr6TYNP{iR{hd6OL_U9oS5c@vo+{F`sKJd|#E)WeYsC4|E zjQpWLfNOCPaeu&0JklmSfPA3Z0X^8Nb_vGQTC*EE2$twXQR*hTM& z^2Oio{`^FJmY#rI<9eEjR2&*VS?}3XTM+J6rR*cR5LdW$nAF(ZLeO#_fITpqchilT z@^pwMw+i~8BNhu3J-&8Y3_zO-hN0D;9XKL4Z+$D@|L_O7a^;q6-MY&@41V;>({k(9 zck;uJe>B)HTD)AJHAjCR9me_$YNX4&0K5;hBnk>kW#OWwwvAC?VQ@D$PS8;sm_D0= zo(|f0{atbTOc;=d>t(&_Wzf*kl962)46p3SSHxAFx9^lF?K&ptwq>{_vOiG#fSs9G zS`+F6vMex*<+SUREUD>5Qrl;w%w4)k&ffS@u73L`x%Sf@xUO!0s44ELSH+>>A z7c7^AZkpNEaN}UzQ}sm`^wMY0LZz7|UzIhr*rchmWZLvOrp~F=$qdx=tXEH1kcnEx z$Fs$NIezykdObBYOBV3Q(2+WI+H70jg8k_;=9=;OvoWJ5%BGDU%i@L0q<^2mGO*uJ z88dQ%j2t#r`e+3(iEAg#l+`QN%d{!8Y&PZiu@j`Cyi9U3v~b47NZWVbkhfmJKMjNx z>S`}M_NYAn=)>~jCnEdLLS(6 zlo(t(ab231NMIrretWYdCJPlBqyb^R!UiRe!Uyy~o-O@IR0R0+9n@~X7c)1I=2P4- zT@*Gz6hnz)02L5Bz?&->gLQ^M*j+e;Q)zH7fXsRB0qnUhoVK?lJRaAg_^V#SQQ=)H-2o0W`k$=9##99c2^&)=l>VFG7-*?_dmjiiSnILV>@x z4zT8ZjYGKx_PAl`H*>cR=W$PkJ7{sAq{9w9&pq5-6L#B#)xTedP~=|Dk+I_@o04Z8 z`U@9s*vE@}U37h`el@F{=*~xN1=IDEnml4k4952dyO1vP-4^u!*vC z-43~Q=MOg7Y4Mt^^3m=Ca_sC?Ieg;0EM2on)@u!S@y54u`qC|#_u)DP|Ie~=!w&m^ zNLp^WWENCP&zw@*?@8y1D&PSlC)w~!Dv2elHrRx&1g#jFKlH82o@I)YQnSn_#TVdn zRc%a|Jj0qv4144c4>CxG6)ud9TKl|T7QNzGssQMS%~2IV?c7iQxJj~o$8OuMS-VkT zzf6`bUoFd5tg)|1&7HT%j>jta=`35jW}_@$x=Lm#{AXx|uwdR|nXZ*Z-=+aJF^25~ z%?x8SZn;)81Nse+%3c+cm8JzMAznUs_YHaFSyjzXDc}_9K>oQ$9%?p@3CDFqhb(Fx zm;?N`RNV*Lh`UD58Q`fH)PQ9en9V?aTq}}@c^KzCKGqyJ1YfqeNuGT~pHa77SpZmv zeb`z9Fz|H%Kda%EM(BB-=N&}d+pV>Yjqj?hG|e+T6iR2&ftI zOMY{Z16LsKt{7k(R@uN72s`9~C!hzYoJUQQ4(A-?4s+sgEr2GBYdzeRKK%q-?=a^+ z#Nk;8=R9!<=a@7|i!?}==WbF3JABw^OOI#cdg8YHj-Ue;00Vb`?ml~9+p$BO^#$OI zr&SCz0VB%=<7z-m#;MX}pamf1JW!+@n-4zZv*#XeQ~;cJ_beg~l$=0lVriNbq4yQ zCoagwk9Nz~-~YRwJ0YVc&X%!L=E$(IQ&iY=brFS!*6& zdV#9`UNUgdFyWJcq(c*mFHy1OykAG5u%Ty~NefiHF)q4PD;A&PPV=5wl#I}z(~d>4 zm|;otzpx-*(o?lyc2AOb-+WD8dEps(@yP)4D0u+??86T>!`?xUq1MfXqfieU;Zy{) z2)rc_hU5!R;L->KwZ%9et_Y%`?!YyuKm3Rp;cgD#usL}D8hoG8-}|f@&%yQuz1HuA z@eFQZpnJN$@5fI(^iZqDIj(*2>8It5mtKP4Bqa8wx;Nl z61y7gJ9TWY|5;2k=;J!aNlG^@pbB>fJ;N@uvT~%1r4)Kq8I&EMz6GGJrcv000nsol zIZvJfs2qn?IoF3(IM-o>DkZMxIr%;OF0KdYD0z36aO`dzVC&(;0eZj?k>+2A!WGN6PU%AgVAgr5zn^#j z-1`;6>9J)Z815nZ$WZC7yiv!vk}$ho({W|b))qpGZ|RWzdq5A&Y3T#;4I8%FT3QBf z4d-6;?cpidxaniLar0{xke^z`Lxtq&FyDp|INXQIhkI}@_B(Xw5_zWkgB~^CJUS@C zXM}GdE@kMRzV*GFxqMqIgqw2a%5^z+ zgCUk*%b9D}<>Ku-wvS!Bc}GU7x=zml=&W9;nZ0|C!Mz%sRrz$h=O zklJ2#Ql@__a0do-)G^i?&=b}(RSSDcPbn%Wl$?xobKiXM&YSY;3(v|6Pby49pm%c@ zj=ObS*`wUUMmX`Fe^ep-FxM(P4VHkq1?sJt_X{{&+4o}r%Rcbu7|1{U(8KotKN`S) z3wS*a*8%(I9@F&n_dcuFSmhB(KWwd~M_AZA{P71LGz-V!UbvE8fAK|m_x0B$u2V+? zeRg`9!ah9!eYX@P>H$2)J{5RsYEM;j`I3{9C*AbF2ZBJ= zAqiYvDHF~XFcOdR7?B4*F>mymZ0U?21$cx8bxnTq$>hOe8Tj)Up5T9YJEtMXO#U=5tMTAMIt zJ}}MH5r}%nXI^oo)HDs2vD4tML}lxA^HD_6~Zt)*$cZO89w9m2$I1!(J-_V9&W{6~5jH{G5hA2OM?ZT|lJg z;B`eG4fil~9k^k0_=c~0#^6o`qCnP)q&0JhyEWfOf9vB9X}Y?7?7`p3qrbx*kcWT! zTY2<>2jnq5=Dx(mrS#ehFUUKuy(XR7wUusNyGmA1g=`NkWD5EY?c1BX2LC+DzGH`W z(y@I9bL+&%#wqM$ZA?9Yci?wR>aMCj)m%E+*{a4B`l(u>qjUj1sv9UeWHDFh4t zfC`|2s{`22xe|Anv(L3u3=VFu1c=N1nLq{XIq#JX``p)`CH#yYhjgh#NYB${OFZt) zc~8eHCXOAx_~m`llaG1<&Ojd(ZmL{CX$qIhP%Vena6!2ls?^-aA*ecFG4A7rTIXK4 zgXoI`qQn9Ar0?tc;3DFfbZ996?*NW}33=?7K#$QnpjE=KO8oGsc7|56fFbT!-42^G?~Z|A?Hrd`B+b{?YvIa~7|W z3Df4vvXvWT;gVHy_~=*i<%x50>H1w+uT7Y_3qF)N^Owqp%h$_A;SDMd! z>WsOTF5~GJFJCP)XU{h%f3$Uno#(^d_}eE>nIZEREHUH!$J;)U)oV7$+I5@E7r%JP za`VL>Jap8;KR@y!GI70XtezaH4HUb)U7 zPX{cWveTx_w925Vp-F11v@$FN@|w9-*~fM4C~v&@l0iERc87b|fI4O!v=P`79{BcE z4J+)PQRoG#p0L24RWP#!`l#n<*c0ZeIvnP16&pztQuPM`M=zqA}75gPJ&`>*-+* zZdd=r!?+IPUf#ms{{CE~#j)>u<-zD6(&8R|A1V*ddqv>CfomB7;{XJ-?lZTrNCg1k z*$4b6bK-Iy|2&|l1CaqA$=&Fa)AaN_aom4xkS8nxc`6Pn6F`qIp3!qCYT|lJz&mi= ztwS1w1J>ZnRDkpE2R%mR!Q`lI%0yH>W9xxE-76vh?LhbY zu;rP2KXA+ZCFBF^8gc8iJS#@U<@;?qs)~Rq}0{h#E*jql{h=__*d)D<~!_@sQqy6bxn$QEt3T)*{= zT+mwW#Hn+#YxiD->PCg>YFV~?g+g>$m8$ICjncQ@ z0EP5eY3kF@CLu5`wW7L4s%z?`O5;>kR@=mc{NfT-?ZuLtSD>oCR{yv{%`6P7WTso0 zX4DMH*5){2efss+bb9L_#&>Entf^j6)=Mf?+2f}#(}KaGRTyFQsxIh&WxO@#3GW;E zR2@EHMtUT5QDqntW3B`n5~<)eklzFLdto140dV}B0vSl(V+u~U)}Zg;cMHeC9ORsP zK>;7_zQNpe6Akxh&^zGW{5*gU$Hly2a5c{M5mo1pL?8~df62m-H_%6}LFscJSM?vf z^S1fv=`YFXp+HkbZ$OXfXlfp7*Y02KE~xJ3Yzfi+tPJ@HA~0q-E@dd|5yq#era zyZLi@>%l7)K<`T>dt9Cc*A4gJ{{C#i=l%jsNpNe05->f*M02( z8Cao?fi&k)yugknOPK4zC>fthwcRjE##Hb)ioTG_mPuWZ@5U-o@|T=pF}DxV!Zs=z-gdldFGTlRf+NY-xL zEcpd|nMu=2)}~?49#Y<`LMkeI8D!H`*`{aeAEhccFf&yhyA6je-W9CI$ITe5W1YkTUs%-kHwFD#J4;vy+3 zDYoORoNTip!-h(>9&;bkV@vv}T8J~VHREf1uCp+0p3_V(SI`4s>8Qjdmx zINag>yI=px>>k)_8r*|tMb*Fm_FD$}RLyU|-u??FOT~3oP{i66(7*rgdsYFoz`j#t z@>HV2jtO|Vrrx`EPqq9_e(9dl!$bmk9Y_MiXs`oR_5nYBZazE$q#0w6%LT{+VfUF6 zkNE5ZXm`_)KENkF6S7E~N`Y(H=NiAKU+?h72q$gglLkgSo|U+y#W7&_J_L{Bl>~zs z=)VGhcn5$yqdpit1Jr;bkOQ6;NAC-S0kEre6gLYEvTsUOp#|KT+{mi4_^>&)4$lbW zNyF1|h3{cr8HA5*?7mhA-a$-X0SnIo$uQ)xzXp0LB_PfuDFD$xF2BAwb?f%GHq;V# z4IQ*7d}hev(&7A?wVO=U`}^Q`GJ%S89rV!_Jj=a+ce^)EV|SLd$CSLd(F zi8GhvtJ9a{%M+*Nkb?e;Bgf^;*^ByvZ)+|0g{kDkByE-?bd~t7T@1oN-GK_6**d&| zeb>Z<7Fg?fwp0p)5s&K$C#+|Bn!&ifp|_=(tZ_57vfv!xCSF%flWn?&QDLO%d9KUN z&yztz2HW-QQ(;gU`F%+vuOQzl2`Ug&Tv1Vp!d(@VW_&tb0Xb`*Fv14IM~}(}{KN@5 zWEBX>DUzNND0;?lcTu=>`rrdwl#KE6*h^2Ts&`Y+JK%vj=KJ{NF?ZV-@D=jUa;zZ6 z49XEOM}s{8dCPv_=a0B%2vZOTuAUaqdnYYh^W8uFv~_Yu52^IgH_>n>oOoV20N-fU zZeYgc5;BMO-(o=ifnWV=vvK^erb#8jJ$dH0Uwu`&c8-yrnwK*5zfSI|`BMK2AWvs3 zTR@NN1|{!`9=DDA>G99!sZhz+mLRGg$OHQx3VvFC27S#F4t5OSJ4gYg!UHs-Od3a?p9`U_w~~JqKuAebAxGIl?f2%4}4x zC@eezZ*u`f_QPR79GIit!^$3W_3sn1;=)QEf4y0Ys=goSalPYgE`uQ_w<*L$L@_27{~s+?6*lyRfSqwYjDR^ z!^j)p-ZP`nDggJ_C#s@nKUrT4Yb$h9HJYJnwMS-w)b$-A3zx2y6X&kV$Gbn5Ma$RA zveg@9>GIXGaM2Q*%Da5oYW=ZiW$VW~%rycu0ja5CEnKdk0VxnIC@QotU<$;E!#S=2 z*6e$wz&VU-Q2ewIO3O-R=#ZgOQ_UBG@+3PWQ+n6bN=adnBXo^5eyiPY59+C70gEen)9``l;n&>_;$(4b1AP>KqQP0=%~5_b)LTGTtB zXEYA(8m7w=hb3wQE0(@=5?9qqy*_8YwifujV8?gflGj)zQtj1e7+c?>?!#(641EVZ z=9PelduOZzKMZ zKWmgY?2C%&$S*U<0!85Iz;zGqmUvVGR0bS-XDI2R z@LlP1PvFmaDhtvhjJVv>l|6BQHTT2_cO}nxuEBVAp3_0^@iD@>Yl}ZVQQ^qYQ%0Ss zn8DAEP-FrWN*qPbN|V_+jC2czJh~eLkoz$zACM9b9GMeCe8Rjn;NW(1(4*pkIi0YW zgWj*|hcS^W_z;PLGGctJBn-}I&}05=v_$A^<$JP+4j(gRkD{j%z`euwD)?PI zKal4;8m{L5S3!S|yGf7#0`$dYb<({@t|@wE$GQs#z!Q$zPwYmoc!8??Tn*PBrZ0{m zP$R}pllcnyZJ!>LV`s0(rk(p__M(-tXxSQBvu=}oylsc<{&cT=y5}=Fb^5$)+_Xhj ztzIkRCr*&9+dh{03m3?^3FBq<+&MCO>=>Cid6JA7H&#}zUM1@{ZjfawmRlIMV9`QN zbFECCI>n6mjeVMA=^Z4_++Q--t(!98#hk2ZT(m_u3aZv)@_iwURAPa z&OBK>cfQP-Hbdr3ogs^7&6RmGXUlqx!@cMe7&c3_0&mrR*9RW@ze zY%PR_rbg-0udj?6Guobi!-fr3xCizhB$Fpjv(8qwbi4xmT2&ypZWb;0&_?Bq)|!7n zzroU=ilw@;R{GTI^A8vz<42D%*cUM@FE&p2^d75HGA{l#g+2C4Na5cP{2brw?zwkt zyu%p_hee-zPAdq9Jm9x*>zLJwB^2Kw&-ynESH$pp1O1ntdB$LlxvFOi_&G;B`Xn&a zJRmpM3}9Cny8<`+SKU`54#%$09p2%%9_D7C|0f0gKkHWai9@A8g+e9s>hsS_+qd7A zt}!v@x}kGCUj;@{Awvl9QvhaiLHtp!oT;ARjN`nCk#N@u@Jl zp0vGl*DD%_H}U;m4s4za<2gvnVQ()p!U*TsXiU z(6jnud3miZ?TybmtZ+@K^Nx5ny$?eaZB&lNAwKI$0ee92Fn3t9b$FxHF(8j}_mwgo z@a((l=RA|T*aCW+L2Ku!I068>0pu{`F`f^j6L`qbQ8t8<&RA6a?K|I@I|tYgR~GQ> z26?^C({spU4(_o1FM}T6dq#GNK|MS(mSbQK z3YjruhD@3=*(wey4d8p|&>@*IeY&h%x=gli+ARA&-6Mng^po);N6U;!Q)KG+i868Y zSeZ3tn#`F#Q|8Q`Epz70m3{;IH}@A*R#!e`y1QW`T(Gj4aA z4qs7LWgnA3wO94hRuauv&76FJs8|ah{(9Uvd8))XW}BC(>P)R9zgV)j(ZNFv7zC zZ$AGEpf^*wR$H0DIgwJO_%tP+N92`X5(SR;XIm)@433SQ8EKuIQOL3*<2$ zc@wW-2ll`nMbEZdcSd<+Sx3La5MYMgCa#7#2RPYBMKcDTeFr($hrtTGz2X4+uJC;n z7{|nQwa+!gW8XV#9rB#xxiI#DIN@yh7&(;#&+HWq`<(Y{yK6WdvH0f=_RJwrWsflt zim}{`qyhRVS}uSb>K7M{&k%Jb4+Mc#81^g~KqoE}k1$|QxC0)bJLsd;y3fc3>OLxm z@G$5(Pdvuivph24n8$HwV$q=Id3iQIE<|VRm&Z=oczGa?U!ML+TsXj#* z&yn>0e-8RC5!KFEdPdw}fITgfsmPhl6@X8qVgdty9Di0(X_btfINgRv?)mJnT+tu( z`#=Bha_QxkX8_cQa)pFMX;u3o#P&6pc9Vd4}SJam{eG&UKS2Mii$t`giK_{s~l zK-AXOOMQKV)YbKtnwmOm3Ktivaw#g(uv*E@&6TVyRazOUO1i7s$_g8$H9a!gB}G*S*QccNvb$QxZfcJn)+vk2rnFp}ikVu= zYqK7u<{iZN^UY7M&(^IQ$}8~A19n_CbjW5Yz`G@z94IR(9LUwi&pThPqcgnwC~|I*W{ z+|3m7dK{iHYwO)aR-<&_2MdBdsS3RX_MBtUG>miZ#<6kjW{=3z3izjW>wb2WIcgpC zj*vFjG7y8;gzkpA^Q|5K~sW_q24aqT^( z*XWiw9-n*R^XK>Q+@0EfAS{JYtpED}Z7KF?(mYsOt)MGakSKUNbhHjxV9!3T8&tiy zZ(_Shf`UC!0iT$}h?4G_rvMa-Yq20+X|sxUWz0TX!X2!f1MnEC-ACQ9Z@zCmPvw9M zr&>V?tO<8F56YXg@bP1u1I}CroVg!HdQ=`>0r>s>8HmF^X);%&zqUdNchIx#ra)(( znddC?0N}&Q-1_tMd;%cu5vchDfU5Vd)YgZu^cr^6u#Yn4dSAYPMFxH4SB|LwJU%c7 z(tsZSf06MI8?gO&#>D?6Mot?$Z z!UBaUouXP>ck8Z7n$NctO16SIN6(|cnVp)VnG@(TYn9_vg*n3|=~SbWwYs`i1`Qfw z&xG+zJR8ROf`TG#g7&g_4AtaX;$RH3UK|1;AH`6aG&crWU|GuwVVtKbl!wH7XJA2kcSxfS%Detb0?Zt+uB6I^F93TERr4 z94+Lrrs9EodsXx{&b}=!oc7Y550!M*JdCTRYqI7~Rg{b<)Bl;y*u1<#Tb{rH$rb<; z#xXGU3IG_pf8AX!#KEub9iUu~!Up8T@$;lfIu3rX90&v2-ilzKieiugh&X;d_xES; z`}jWb4CZHmShnx@M3yaQ703a$4oE>kfs_`PXwAwx+^XQ|0L|7vUKKeYE>-1&63DuOo25u_SUdbGGh2p4KK8? zn(8X4RjaP7l3wMNntm_}#@#54aj&myl$n~bSSuVgh0k-A{xLL%`RMbop(D**1K4SC z3>`XL1`Zr7Lxv2KVZ%nq$dRL)D~N`MCTp2c0dU->Pd^zxe58yWJKkC?v^H|mv!zH| z88sEv)+x&bDmrDc>~wwK3Z4!hyf3c;dbQVIeo5YZ)$kO{8RJ)1V5{;DgZ_y}9+t-# z)2>jovFOY^jTrF89((A)=E+JvaVc!xS&DIN*U$k==c_7fSMr#_+JOE`)&hH1_Ut>< z9qi#SJEjs)b9WA)r_y`twO1uRrjz~$1yVsPGfOMy9tt~!e24b9YTDUYdd$bsw|!sX zuiK6tVgUe zY=Jv&8n)cSD-rHZTBMH==Ih}TkCisrXUmXIS_yu=-`k%F3D(K!tIjeK zhjR{Q;xhurl`D##O2WtCQ)%#h+=kv-p(xb7W45%UQuuHQ>*DjF6CYFW?jF(~G;p|b zWI)7~qu^|I;m~RbAk956hF1ddLx+#c?AeQ~ftynjsj^_f0+}~wuB=?KOg`SaMfUFA zB|CR)lNHOC%8cn#W%I^Ovh2g9vTDUjnK*ueOr1PM7A;sPt5+?TJ)iE7jT=_W>{(M~ z)5bM&@bi7LWBW%2`OTZw>A7_Z|KT!y+7y{TZ;o8Oa!D>-JTD98&y~fC7Rdg6d*s0W z&t$>81=eB8k_4Vo z$fr%4A>+qSGX#4is?)M%Od0|*=bg9Tl-Cse zsAS;p+c#f*#eCuJKWCrLPh2KlJ9m^6ZB2df#%uEGvjOCB@wl7isfdyX$N=5Ps{6AU(bEBJ9mLN)Ywwd` zmW-)q`C`V`vqVB$S{{*3ShhZv9!2k}zEh{p(m{dWDJIrHpOzK?7SIB7{O&-ReZnz7 z4^#mu0Hy)}uwnRf4HnZW-ogPfkS9LpStlO2qw;;7cz_I~G43B8kMETY@ia;R#pGZ3F(<3Jv0sik#AT4c^|HgE4W)q zuFb^(_CTLS%kbUTXc;qMslOZ74B!OR9LFnrQ2JB?z#jDsB$@C8umL6J6R><$NaFGN zKHyqfT4hk@yAV_kD0ud5@iVP#SZR}RbN?vhX$1gv;6G~Qc$qeJwq3)!?#ln6;x~Xj z?;*w3(5FMWqM}|~Ci&))0j^#d(9*yNx7n_$viS{e4rqt+Js=0}Y6kjnc*y)ZSN$H> z(_(9`8+`P9sfk)QaLeFd3qX%?jIYfVJ&-rIjsB^rV+4?q7w ze*W{nX%ps_oV{>KjvPNBXD(dSS}zz8bLPw$xp3i}T)TQ%u3x(%S1wZ1T3VcU&b=`f;Z+?cU4bNUQfv23O6{dAv9nlM@FG($5YhGCB0dCFM#(vk`p zJb0)VNQX4gt~_|g<0PmcT=V+`W`9x5EIRHz}o0OTa#mqwOA}n6(``w{qX)< zZ<+u5tyf-=_uhD;d7mxEKt4G>UJ9}^WI#i;l;vkx2e13;pM4@2^ZxilEh;?>c!zgu z&~AolR9G0e&F2*8VHl&b-2nZs{^_6p25W(MIIa7c-Cr#Xddx=PJo$vYp{=F%@4pvR zrV4l7>AP>fCGWlUwkdf)59FCRg{p7vm~E%v@6gFWAJaKbp`$HcRl5A|7=XlW0x%uu z?1!PwG5O3@zC)f#P(Dl&Xh*AUwm{mySVh`?KPmy@kcUav<8uyUpL<^l=zHk%D&$jfhw6Doa|-mXiCW32ki>eX7b)m-g^_-} z`wW%Jnm*>%0rECfTb~={i=t?Ti{X3G-{7&zFLA*gF;wEfz;I_cejs_mmd zthdgtM%~s{S1LI1cju^*DAtUI`vt#dPyLgag_mJ2ntpv7q(_^@==IF>v+wy5ifiVh@}cj^qC9u^EFO}!ZyqHE6Q-+uqaZ7^z0c- zW6xJbT~SeKe)r4_eMi~325~xwb8__htXzHOVyUXCHMb6GpAiytvQk*^gHkY2a`XXk z4!Bd8aT)c}!qn8zPX;vgmytt8mq_N~7oU-*74D3v zdE|j#n=6GOj$yb*tMV{l|MegL;U1XYV+QTkVH=M3UjscBTpzy2{mkwaxrg@&_?AkI z7L4~VJckR5ijV#ahL67dioC7R2ky}Z>^rEc4-|czD!5==JRl_x0AB!2o&e|`#(7hU zTA+ccyIr^z1Hu@2h-)0!fZxZr6OPIU&VC)Br;;EJ$HZ|(@AqTtpr_&>4wVJQa}eLJ zVe6s?A3dN?#C3yTp4qTk<}egGik`_)cnMJRKJhXmTLn{ol~n+B4TEImnvZ1AP(F;2 zYu7N6#yTnWdE9*i#5u+{54dr~P$2+mfDFWliyH)0&o!wEXW{};wxr2*T!TsvD|p}@ zws0pc`xuqomtP)}Q>RWzb#;xkW^lIz{_hshVy@z&K_9jR+~ASlXsr=V126}0z8CgE zB@lG7hQq_=>2hr|=q-LrT5W(ls-8cichf*y$0jSc#FTvCkJm)h0!6PcMl)H^n;!hh z{J9xftO!@A5O1mx1jKzgaSgMj?LxvkfQR^sm;M=dy0IgJNq<3AtDs}~2A1a$Vsje!Mv15j7Gi``g zCQW*8#=qCd$PpuC+LWpGk&x=D8e4I4@W3H5oiX?em&%Yq!|g*NxPDmTVDP|UHoTIF zQH-JYFcvkdsp7W}vTJx2hGKG#G4*wowFdk8syeHz@bR;rdA+{7iZZP*ii#yyE2Ls( zph{N_vpl=3hBp$93kK^%vt;Rk6H4@L_MgaWRLC-zz7k+3arXUsSJJNZNrMW4^ThKC0!UMV zkcMB2xi6nM0G;!Mb6>9I*nv(QT$PN+CoSSpVR%KreXRn}eL7=tPbGCz&{K)1=rhxO zX2JH%$WxA#8R&zV_j-M1kr~6cVNQdp`d-z2OlTr3bMs0iL$3pZ02_1Q18m$esCv{s z07lURRK5l6s-7+WaXu>u=&2N3Inz0d%Lku3pm&f*n}eQ;gkvgz%E}tKa^Umf|vwnsnzT=wt!L^iBmA?sHymu*|t%f}zDmEF5p zp>l)l+PzVZAKx#>jvbJL2Y1W)^C#r16JN;c)k|f=`c<-T?=Cs=#piPP(C6mHS+aPc zESx`IA-qs_Zr>q0w(XLoOIFCN8M76J^)h$PEZMYit!&=BM$=d%6DADP{gpCv=6IPm zZ<=h~il2XtOq?**Dx)>4SIW*E+hxVFa~0sXu=3+*dX zbn3Fj_YeG8rE==z8MbmI9ldn;(kFn+h}p8?nX;&Rj;S1|6c~d~3#6)7wY5T0yKD1X zTNo&O_Pqkg$>IamRWe9hRkhW%7N;Oj3pV4I6O&D8zV+JcHp=C>r=FA-pLtSVf9ZL7 z@3oiZ{kL9I_5Zrri%&i-k0{h0`WIEW|JVZD)_@sS^sSu_o5R)Z7nQ$SGwA=(D+aFl zWorR_OQjROPhc$-0>1s<{wsY70G)|h0nB}$kv+uo5kBm59`HZ%y9ecoM;?{unIxvb z2lnpL2|!QBZD$)E2}m7~fD_ftKJWz6z!r!SMm&cupvE6h9Iit}<5mI04t3w>I^SZz znd`j*p@L|3xoCOydwV>t0p2_t%9VZMxREy3dHUR&VU#|k5@Y;4$8InJ*k)!HDqMpP zmeH;6wn;81f#Ho?fVMFH-2~eNt6*tKrLL+r4|1#V1}$ioQQhucr#q3(&HM3H9+QCS}-hA&e(s_3jo^! z@9=SOEy|tF*1$Yncf*9w1*X?&OToVu6>R~uTfiM{{v1KY5V4T^#z5~co{j~3A^OJx zb8gPQ`@H;xd9#Ca{y9F@eBZTupN*Sm%>11@U(402m*l`_`{dA}0}AlX^4Vv5((rnWy|Kus#OaV#0%uZ4;9RtmdoZj_tQq?>&3t5v!3m0x1g((#Tt4uNyh!#U(evy-kvc3APLuz2Ir^{I<$+CE}Bspb;P~+ zfC+2kBqeC(jqjpq>HBBRA>GHd!%$6JRsbF!GU2$iSUdfLcixqkpMTCe8yS-M=F2bG z1gxhXeNY~M=(oZ4f!`?Tf7J|oQ}h70H5f;!`MxpwOljKu0X2 zZcys?fL`MSzzx6|q|fgQgsr=VurT1=?gx6_M^FL6ScPvFCWA$TUjM^i06i8~=+PED z&%K?oVKdP4!oxkq{$uUsM1anZ^&jl}{9ykMD#oFA; z&~>m1~Ai(~Ojrp?^Se;HuE3E`E2Qo2}ugDSRa-Q!`_h zLb_ZtIb(VgG^6*h^Z2im61wUi$xOo}^S76mR+uZKytGV)4H;^F{j{EZVPDlnk2Hm= zW(Wl+_sPvxMU#=KYB}f(Wqom=jEe=;%@_WGJ-+{JZN)Id6*vQX&H;QTMX^F9;Kmn^ zLI>!C0d*ES3x92j307Q7xW^+s?%7!t9maFyYl{hp^YQ7^9H%m;ESXKhmty?!{o#y3Ab$z`w_3tk!Y1&Fi z)n;6hDiFpVr!sL#l|W(-NoC}Zz9c3!rE5iyk*D)OoT<`-0{;M|8>e(kAQAN+Hk*erf8B$^2nv!>5hQW^g%Rl@NGxj-8T;L7x zeRw769jF6$IyrG8(c#J1e1>dtjbHzl_hBFV+dv-%bvQkTc(nO7z8^O3MYvZ44t(Et z*uVV3i}JyH0q9Zl*az=-Fz^C(Ac}ehx~`A`X&AViV{}b2;MD(%WiBeP#T($#(269JaI+I8Pe5W4x8YGhytL7HML{;~tE!=l&c6dX_l= zN?~R1?i|7alCuL&mIod8vO7MZnrS7{T$n{{SxT?oGEtHeWVlD?-_m`e&-m4t7UTEqc7fVBZgDU76 zv$~pk88T?7%$hONhE)Ri-gOOXjZ#`J9*YLB13nCTw*ahxx<|z` zJQJt`_vfG1`#tq!Gw2!VLPZe19t)@a&;R4UNAB^r!@dRF!Lz$dCTy+84*(y1E)05( zNzc{&Q;$6^Z@u=0*qC~S{Cn@VllR|iZ^kj81)#vy{qe4t9k2kMeTM5&4gfvCCmx2X zW+WHDB_3(8&pEDjHw?$_@*!Q1gAs=?o&lxqldJrhcs{OU3_TMCz4hU4B`iCqK+AQG zK?%^iyQZh+uaeSU)@R2#X9R{IG?pkt;ROa`Y!<7kbbRn^F?Y)Zsy}e$cvvuYU0VlQ zIbhBnbG7gr_4$AxVSt{YnB2d!wvvot3VPt~W-2}!^pW*v{t}$}o^6y(0Dh0tnl;C7 z1@7LD;b4!paQv`&rNGu*Kd?EtPfJDP&l^5A(DSk}hde*j{{&tnFFPf*rRSQ&{m)|? zR0^tE(zB#jWtGfdI8XL|#$>4#vSrgs`E=J7*|>hGZ2f4BtXi=^_U-vtjvd)2hY#*D zAN;4gx5%y?8)d_~r80NU6xpzTh56&xtz9Yy4}PlGt&{1~#><>J(`=H|;zjdh(ZacU zewA$8uvSKo8ez8V!w+T7EI#EoPnIlNEFW#&B3~RnXp^xHA37jwR;||Xr7~pT2$?o{ zmMogTR0j4ND#M42mdO*Q%lI*qZ98fFG#NW;qD-GMTgHu^WXGe1kCO>wrx<`gT(m;Q zjGSO$g9Z$>kv)AI2gu+7!!6FxK_l%PX>hNm-u>+!oLew=iQNN86NmFaySA#qwmie2 z{==*y;vS9l{S5S_MOs-DR~oF-D~b@H2YmNSgjnoX4mDNS}%X7gkwOnUrY7 zSe##AlYy9U#RtjXd+T)@e);^9PukK3%n}9mKAh53Ia_zhL_@!|W8wuPSAJta2k`U} zuw{t^pKXiEry?MI2fS~?kPj?S_R$db1X7< zciuN2y@Q_ZyYKMb*{%jtSH(aTI0IdCmBeeSSB*8A`05$!CozTKchz|70hn_i_I>mXX^gfbpEoA4sm%-uRwqdKnL`+;2retnkXyR zmUN{GH_dC_uNPMJY~c#Rl948^?%@nRdcyr2?i*CQD}IMPYM1 zpFt&zzX$j%p}<&rV9zR+!LkMc`0rKpfqHi(jD^9;u>;gUEFKO10Jiwc=?o6u8(`)g zQ4#X~JS^G>zaQv%&%ASvfj#Nrrg9nt&R@iN~_{8G-J`CP7DKB8dXA(ze{l!KpbmeXJDkz3cl zk_%@K%HG{;WzUY)a_o@8c>hPTdihNGc-tzOIcu~mUNS{?f4W|_ZC@#~W{;Cai)P5i zjVooL#A_B5F_bBe-#g-o0W>GH76bTlN4Oug~$}l7$*?s?46H@Yb+_ z{Rf)z2C4uRIHH76&HxiN+^1oH0TlQGRN_{YVhjTfu47AU09Os}7IU8{WOK8$g`v>R z&d8T^CYr@2**(|?_@oWsNxw(;40BC&?%2h)JO_X#jYMsdb&X55YY8JRVJXR~x-@Rj zluSFvJ}#~#RT}gGxc{GhTtz;zr$$>jRb`b@UC~SGs;Uk6DM^|ERN4D5Ovc#*dloB0 z-TMTod+b-JT0nTO%4eTSz$*fbc%*@1N5KcnG`whT8=q|p=v~zVd#?A&!r}gp|LuR1 zfBNtLEpp7c7SKC{qrn^wcXK$qwH7z}n0ryVc(}vfk2(L~uY!(ThF`w<`dikCj*53h zj|&HXJrD()fEjQCX!>8CAPlyV3Iabm*8=IG zLq=MfD0bpw#G?`c=swzptycuZCr$kPgnQa-c}|SDgb|g08Ouy*ry^Q+`s9H(ht-=Y8%i- zOkwOm_jiPwoA>8XZ_T11j}h*bD%bMKwH4V?*DFi< z^)8X2eJiD@rbsFZ)1)Z7yX0jhOKxVeHeGY2s3cv64r{P&QAvj6=4lhOXOjNme4mvs z^DtT=RrhnGurN>RY8kWMWTR7X-OwqCA3h_Ef~9cmj!!*B7{P)MyC;(-6qdjl1DF_Y zkz%d&DOe~WI;k)^yjTDVzbIpjQ9Kkd3X7{CjJOmWwiFb?C`1%)(j*=HtoS`qP{|2e zQEFxa)>H;O6Y26SgadH)iPt?z)j$O982eNJ-L(0cpqY{tG6Vm=X3oy>y04i*)k=L; zZ+-98Qln}MtJ4f$r4>L)UXk?F_rj+PW7@WtcV2r#VgHhiwFmetSoQ?7V-?5_Vm`sg z2ewh_4s|9z*|>B)c7^LI*G8s9#-6|Y{0p{y<_T>%Jfdl<;ol|>Ta0S}sRQ<(|HnTl zlKc5^Ue9RJca?0fp*`}jU-@VnfFwtQb8V8$3dLHN8fTyP|@)YT7!2u%%M$K0O#Pk z=yT!gs4TGXb>Z`F9`0@(52sbZf7A^6;6>p}qc$z4d`m8lxoWEF_ z4{7PyrsxX_`M@?~b{Pw+ilkezq$ejxX7?mDZT59bkRFNgwoOk-vTa(oL=8)jl!UI5 znw+TM?XFPlq0nY3H|u)PiK#WbW}Y+!G;r&xFFi?Lc3KY zEIdUsi76qqU`A@5`QCAxWM>o_DD!iQO)&#_K#PK}>Q!e2hZ&53nSw%r1JE3^Tr24@ zJ)A=3O>zn&KnL^`EH7|`bKYUkHLk2EwA?pGTTHY9*m8`a-W}#v0jT2V*{PVk0^l5- zwshpuG2B%%GM}}>7@^Zm3v!i$y&3dc!PKf%msChERbHj}g_57C|CK7rj_)kwHP;=O0sP|x!5z3zh%^oy>V0F-kE!uVS*UTXvhWRg;U*VIb{ZYDg^dX^8Nddlm!b`%D{o66#hk0R#w{#dhP>{+=T&< zxld71rKx(>qd}#c@{K^cHA~gyP#Y=1d||P^TAZT%gM; znU%JlHl3Y?`K8vGivQZ(A3zm|0)6v&m)97K@n=$CC;()9n!t2W@jXw@0d&+i0H+{& zK_Lvq&syKaqu^ldbB?qqq!c7?YIA>{gU)9v8=ecpMdS*e^Mnx>wa@bto~TVlhGsGh zlcAQ$iTXbEy>iUDIjo_BdM__5m0tQ>6|^ew!RqtXl=m{&r=v0zI>`#3cJI6=ufNEW z2`|aZtZMo6vkLsD75GmWkbyBkbKn7ZckMj<0IOLte3B&uo@xd>`wn-EeT;Z0c@GEn zqybm~Z5Z|r`TvSJu)|Pq&F*)t1D)R-R`VF?63@ZU^D}wM{tJaVsvSiS^ilEv9mS54 z50>DjtZCWMW8&oG=TE)=3x$W zwhns2-NK+ZaA=+i!``-$^SC2&HID&%hY)NCgrHVpR5)5r06&Tub^v|w;`y}3ol^YiQjX^c3$ zZ?>IdskDL_vup_qr(^$D=$VLTpl?>^5y-oL-hppJiu}i^`5(u%B#5fV=!D@z(@ng}1>aH)JKRi~U<)7=KQn98UzG&Sq$j6P6YvDYH&z9@b z1%H~tjkPq=3l+=?N6jFG1-%sLL-ZOtyn;2f0kU^4q3#*dh_VNgsAv>D5JgP`dt5if zclQii3K@k9(4*wN@Bx3)XG`JoLIc!k0RVefRkQ}EKscsyppdc8HH71v2i|N^?d;QM zKx>12!cg$Iabh~e+kU3Dv~c?bLp>GNs(EJ6J&T~dCU3m-N;B|Zc7Ff%Y#DJRfuHqf^ z0NvHQ$03Z$gMANUOWFX{!RxU9UjaQ94fOD_hqY#$1L(j#x@8a@*VX^qufJh4l5y7n zbre0z7^C9d4-e$=!2@|$`zU(A&tiD2sYE^_e*j%nJVrhyPm+ItvjI6`96PYNj{HS_ zJ?sUX5^wQNQKsBgFgdx6UmM~yF8-R&h zhmkcv70CO9DGcyaz6%N}rFZW^GHTQmnK*H_RRG1s+B&W2quVN(KYy7tH1;>hyP1nd z)wro{Wffdw8-5<(-I|3vGJW5T>%3(`I^J?1?J!g^2e$7!kUcC6dCadT9$N>sUyBjX zK@a#H^x-twx`m&Kc+H^aB{|$3_CW`PW|X8BzdW@gkoO4*{Lw(38__{PqSQFJCAu*5 zM}co}*OwBjFppDp&$<_^T34cqHBr@j7gh8uk8JDfMDD>$El>r{i?w^}%OwnJehz@E zmaa;dP8NX4y753YMV}=nTNQ+!XPps-d1hq<vv-gdI}TZrzJt5bmh-=z@KYK7d1~|q98JCj=~w=S^sFQ_!9KJ zQ9+{Uc}6NADkUFE3FL9@0Dr4UwIX87J(H$T^szB<=DJDM|0G5K@Sd7M()B;e(Pzxp z_W|&Wv@$Z_>+==sy8-$YMfy8bS)%ISfAekg+XH+Q{wvSDATOx8536$rHyx_DcU;AX zm3-JI@5c2Qu;;vk-p|u20IUvBApc(lefZiioE_HpgLe3u`=YZPt99!~Q7~14JSN7z2 z@)-G!d`aFSoUN;O&(j#f#PgtEZxxA_Z8JLl6zo7AmyN@oa&MJ@<}u1Y?pwA2fT#o* zWfJ)6F<{Sf!z}6Bf51>_Y#O96uP{~bqiAsB(AgS{r4Kq?QS;-+&xj~}Tsqp?R#x>= zWzQP*fEQH{3%Dnc_WQ#M_VK0T&H>J0fJa+2;N7?m=3qb`b43qK0dClM2M%KgvqRb6 zmzzVGIBY%4(+Y=&QbU zOy@4akHe1`o21avo6)hMK*Hh^w5gYtW1kaiP$*|g7>8NS9fgi%RwjDMfPm!$6@ zJ~q(`7nKSHj6!YhD>``eT>*2R4Y0EX_PBRk{nJ6qJC4^%6=Pg~iWWjZkDngMr}5lr zS(2^y%wj(T`*N*BaN_{`DpioR6_uvy6Jz70(+BO$XaD{iZ$-ggA&x8Ou_x3N)Vh7{ z2|gA0w5{;?;%V_WPNudbR+bE#d6r>v#3+Ky`C?M_Y8fU$Xl_yS4P9pCS5M zSNfb|F*ZgUz46-X!Y2lSJgyr+5A^ZR)A7m{w+<>kQ44Jkt)!^{Y@`jdn-xy@xMi;o&oL-csKGU@w}zUwWQ}l1oPG;;RqGno5Up#lK07%w9Xk$$p=N;FCR7_ z@2z=Pn*o5>qDq6#O&||5aH9Zv7=z1Y=&;eYhI_Ckj<#MD_NaMR^cfk2y5)TUd@90x z6>OzaT8dvka4W+gSM$w^TLmi1xxg&v7b9qV)J$t2|69xltQg#Zyjt*E{dWgob+|g@ z-NL{QTQunXm~=cG3x_+%*?Kx*(0e?;wv9s^qgLc)@zQ|0!yO}@seXNt)(p!l(HCBA ze;z-Uxb~7G>9Ih+4PRooQ5*~GBq`|iA;@S7E|w)Nt*8^$uJ$ihb=FLcFAeoh<$w!_ zVNXnKU|kB_F=TRpN~Sbu>oK4-xY{Sef>ASMWa5ySsTgphpss_APP0`jHhl*7e>3!v zA(MGI!MYy~XVS(T=%h1Z_?YJO06FPXFt{&;2IbCY-f;Es9E7t^I>aN4=b(_W<@XTI zF@@GUVo~-yA5h0dW4}q?9i6e9CyWY#3WFh)%$~)K!+xOhyPFG#HShV7RhkyY3@wy- z8djhM*Z{BZ3)s_1+nW}LhEX9T$0yimoOZxo)&1MAzAkUP^qRc(!pqIRd$*UK;WLHL z$ty3sXs}1ghoQ|j+QN|c3W3VO&(ooc&pR5jSQy6979IC~77c5{T1yWL$MJ30{5;02 z;zu6%t-Si;ODc9^&1D1R-`9#0Hx6zZI$_<&Kb}`TuaMt;lnndiRq{V;w9xN_Ym)dt zJps_@f9(pLd_>;GQ1pZmk9@{C;&Ki786m?K0pj9@b36yvl9w|y&!gUxQ?*jSUE`pS z0LEbta8UmoI}cz123KGMfJco3ZQ$Rh?;v6Qc)SOIn{{kh;|61L6vsYh-e=L`;;FA6 zXca+na?q&@@Kd!6GZfs@!X-o{(Ou60=(sqoEVYFY%&`4Si2ssNIamduWz8$FmJV6n z*D%29a19%MO@8J%5j(O+7dvCb_fkA%0 zugCT4Owrqe>%+3|DxNTo>D3-Ic!WXT&#~{La%`WBq;c8D*e5-keWvlfb>JTgW=T@q zH^~YxK2-?#S>CjxwgT|qQ$aAPp>s@E&6vTL+i7j^OrD|1=)l&Sr=DQ}J&J~m?HMr` z5mc(p#K5;1fK?TP!qN>j&%`8_7a$IqoI;3-0`R1X0e2r_>Bn9P5Z?<3ik|1A5+KZ7 zImGpX$bBe;6hI0!kS9LB4}izTBpBpT@w8gl$7j#;GVb5Qs1N`HBO$%+8PO;KiRcL!usVe*T-T?S- znC~8iAGTMY4T%65RlTxfjKCLW>$_ay7%kT*R) zB1%j!sj(zEOArJ4Bn3Xu_p;^Y%HG{QaKOvGGXQfCQ5l~eJT&q_WnGdZ5vbwna#({7itaWZVvTmbExy&m??P;!zJYK2fkrQ z19(6i1~5h(e{Z};hcf5bdO94FhPMd(*wbL2_$?Ley^zN|j)5Lf^PpY>V_qxsNAO85 z_kVFr4b7NSd|reR&&@$^V^%c{;?iv6%QJu-Up(KS?G&pItd#{}`05AKj01$4`N-5P zKI9(;;9HM$zR=^1GGK%cv&%}$Dzy?CZeS%-0(@8BWO`mAFWSfXv&tsTQTh@nJOC3n z2rd!!0Vf5ILO=m&ZaL`lQ-DaD^RAq@2j>VgcTxn>#PbS=3V`!e2pm&Eu+Meehjd6g zLEja>fpCoVO>oO(rs?(h+GLN+e)SGn08fhq!-wx{?Xb97xk8(DaTsoi3#*vcSAiBF zt?=lS&DU+2#zV=6twt**pkJivWb1P!>$}5^(={emI=uIR`R+e>>mBpmqwwE)`Bi!Q zCB8fRlDx#|oTq~h+rLH4QyGLo&oSGu`EbkDK;4>!fs1jSTlDqebJ6D=^n_8-&^b)U zGp&s1j$*cMmhM0NgI@E`!f@2Mn9d4`t_FA?Q}6B@|M)!rJ$cN&N9u0Q&Iy+9fj*zG z1MsMN@+@V77O9twV9gdS^x6Wz)dQ#v(3-c%zX_VJtd*$wfi1@v=YT%p#3xUZZxJ8l zKaMF^Tw{}?QuJO5cs?DPTc9oD2&5cX#G#zw>Y6G7snRv2L0HSr~|+N&HB!wE=p(z7!zu{(96ru%}~|??zVDHU_=%2E3Lp zv*#!vZE+)oTJTYWT>IDw3W6!uWJofnD{l%888(rZ$V<~2kGMX4+cKlZVIeRekLw0- zvTr_rEqo4h3WXOO%#{ux=bm&rb6*EN1&u9nT)A^h94}NHlQ!v*28&Qp0r1RzU2}od z_d`DdZl%7B18pWPsvfxW+&~}L)4`0Ir%wXN2a~6?w%2Wz{!Tz&R#}|-g(setXP*eb{bU5_ zfZol+9O@2w2RzrYPaGeq!#;p@|F=WffgEjN=tkS$5|?m?d>Hh!EU0vRQde|Gv2TOx z|GPeKu>8X-FT5aa-*0Q57{rCc_8qM(*=KYOpQGge2iV?%?a)3>^CtO|{6=13{sno9 zyhI+N!xTuftU;EEAeP(>DvM;xQ{*#_5g51(DHE>bF%v<$C9itLz%_((%syp`{;EPv zgY|7{P_SKmknXA)CRA zkL!jX(VB6dKMe>ol^B)oUoQ9YslgA|c>3ab0roQeoW3ZAQFiQ{Xa?X>_JAK>J+Q|= zAE#+_Ap`2YfIXRod)fF~1$~RlC&RvW#rSjw=z*U+TBGU2#L>!)zW8hCZ z6h;aag^Mr>KWT7p?!`zPhFVUYG}9D5t{kAxGgA>TS_k#d?_f+lfDbQ+0O(8dOQoW? zm-JF70DZ>Sm+5Z-?5KH%J|l7R^qDjDKcLeV!;O>3*j)t_etUfO-a%_aFP~H;|5yNO z2Q(H9_%P7j{Frmz8t`zgb5$P(u|u^ra{#wyzZBQQ!s!!^dI#*lo=S%;$I-0-H%8s~ ztYIdYz4gYMsbq?flbuxDZUp%14fV_Xi8qfoOELSV~y4pT6 zbO_6ROtE}Ko+EFO&j34liM-7BWXVUIM@(=Yb0I@T-~$JE9=7B`@^ZO`H#YUR`7tHh zf;JbZ8fA!9a#eM`9a9d06XnXvou-c^QC`(tm1FD!Zxp>RUPd_kD0A!dRG1SFp0IV$ z19;96A0}YIoaBp_f7zBhpYqH zjdQ;Qdcxq8gF1YT$HhGDFzBfi!l1|Q0X-HCci;C~88u&~f4p_NDqwsV6UrT^^DRVv zEH8|6bilF&`Y|yI_|EzO`qEJIxNZPF-=|Ggc+pAAcWD`YL(73o!2NLhu%*V%&Q`Ur z>K31VS5-CM!2?Xm#GXkVv?vVEki0l|XYXZ<3$LzYclK6+Y+b zPeQ~{c333M`@hol+_2%JW!du8_N@t&JYSUaa<%i5J+gko7OAYly-TNPQ11A=pF`cj z?m%xgeNNv8?rZ_Q#{=^0dm5O>=NxdwpO3r7l{;Ja$72AV3IP8;(Enfc(K{RO0X<>O zpvM4mVDJ$(VkU+o;h1w5<6IE81=0@xXux}TI4+&SE_v5hfAcV6; zU8A_W&|wP1@eNuhs@^d2WBrA(4S=r?rpNr5{E@k;NC7|7qu5#g09OqobpSt=1n1pQ_$eom9~?A&6m=25AMnnZiB{b>C;} zAP)mQ40S9FdOweGJ*pnCI*c8{_p@kVJA}QmXwAa$F$cKsW4Mq2Jr-8=o_1iw{|5v8 zGmk%J?wbznIyQqIA3cy~Ym1lZdj-1u@2GhUkOOr0#XIQ9qYiuWs{81}amdT$E%F+9 zioAvYo-IaR;-2J7@;P~vcpQ5kC5(JbI$4@mnDM@H)jF9xWrj_Pq)b_hSj*4QVWZ@S zAO9e0)^3!V+6Jot%zYDatpH^Qv;&+iORZRkZ3yDwiU8FPGhEq+&BNdeW9%7U@9G`! zqw-PlfF6H6=87KBJDXZF&aogEbAN(;0IHyknDfwJt;Y^(_Jerrw^RgN?+k27Ke$J8 zTs6Oc*iGX=_bnE#0K!lw+~atd`|eHAhk@Q2=>13W5GZm7xf`Hoy=Uuu)p$0!O8*GV zDuI{;Q}e_H^i&k}z5CkiIPbXSK0zmIFuI1ZwzM1oJaJI)-eq zI2e<*Xe#?PqyzXd3N>5OphEDGIfVIr7=c5<^MZ_Q2njeArq( zv>m8z_!UQ=p}r>vWuUsT7MQkXLEIK=IS0gndkZfy?&0nhzuxZ&l-asM=l!}WZ+Wi2 zydPW6dmMiTkJE;S34^^g&{Iy90}-qVp0D0Kwt@Bl3<6mY6{9MziQ-b|q zz|80wz|Eh!!lj>$ai6Xu!6;SaD~y?YZ9<7J^fuyCgl z#u^;}zBychPhp^NP%wZn8J!GI0pJ(_GnSrk3KB!p*ismPH!c?n3h@Cu=`f0c^Io7S zXjBGXkl5#1SMVMW)o+t#^m%+D7z?~H1D4^FtWw!cGXm-!1s}`}P$i@9gdvxJ9>`ag zRT$*+vvX{j;;J%j`j?g&Rdcz#V||{E@3)iJUwYX_)`X#s zJsq)dSlFJ`YhHfwC0n!I0q&p&OdTK z4iHD}7Z+7%{=ik)G8%_{SNpE)=|iG*OaAkYR`NEWcEDp^0kCz@BVfqa+{Ye% zXnSxCGf+qVB>o_3a%Ru6A{}w4Bs!_O=MMzr#3KXHO!KA<6+-Z$yV-d%1Q`K{WBk$l zxwvciqdgre6XKG&Q1K3Nz|RW>^ce8>3c%bpx{n)&ih;N&luW(OVe3s?GCfKQI1@(3 zpFC-LFiESX!C>s_oA^G_io!rTgcAqYQ@}WnS|ScB~1^ znFs~wS>_<68-Dme*`wfb-7uPn^?U$5i<{N-s+5M>Is-jGFUrd|HP10B9?++!Y9a5| z-M&J_F%?2yrotmh|94fObi6*#XqYDy%)s|=Fjw-l0NTF$o=vFor4gb*A6D|wpm#&n zJB-7ib#rL@d7$emO>tjq}@o{a1Sz_Tg}aJZc^T z@*FcemOMbk?*BLD`Hwjzz#gyz@rK_0WaNl(26id}4A^6?@&P>+0~HAQ4WWR!=x`%_ z?iJi8$frC9=g8yC`{0;x;*bVqgLA~;8qy^17nfAX#7WcS-~Z$Pki%ablMy4w+42Ov zdi9p_@;WIj?4@P5$e<0Vy&|Ce!W>%vY$@lJdfy8A3AB>IXx(GBro5(!4IVO5`f4kh zZ_8qEhLtc`01enzSNF9=(QxGiOCJ~MzP7lFDy?$x7C_K(+u~liALt#NuEN6>4cV|6 z=p&Vg^OAIdw+|5U>)A4l(vR7PTT}?Gr5!fEKNfy2uQ1wpXF?e2YymR0C{X1OYJL$B zACo_{{{YhA8V59>XH5$hAi`zSp+lFzg`@Cs)y}qi_rUMwX?hxDgdsym*_s%n6Q~1) zk5(QWW5lueT3Pha49-2tB#f_bXzZt%ZLG%8nq8p|+<`jAJ{5q0UDXJXC!=yMkNXZD zVWVLB^&MoH7%-!{Ic7^nry1*tn}X`#CO#Fwgz-~k?3jsGASft=yO9QIvX7#o5}^|C ziiGqA>hIL?KZ-W`+sT5Vw^C1*ISIA7+?93eL-_%D2_3LkN z2jaMCN()sLshZDKm;-gffjqzm{!|9(DLo`s)#sZpzZ&UueO#gSw}BqOy8-yPPBG@& z55wCbAFbrwyi#C`;le>t17x5YhPqqyaRA;H*Nt0iE*OksPX{9o{&+?Zu}@g|ydQHN z=c!nNA(*KDpktQt_wT&*cJmtb?z&+KW3~xeILRkKmkQpEyukQ++&2Iph|^ii>{t}P zt9dE`AdgR~jt0$d|M*x!ytVl>zyamMzar zeB#nU%gCHblc&oc{`l{5>GBQP`N>|{v16YcJa}Bb{PMKy+kZ%Q?%Xf?_I)9re|}63 z9Qab!um4yY8U|Yb9^669O_(@Mc7OVr96EeVKHYOb_U=0*G7P3MxFk^9El>@B>53jG|2?4hFw6$5M40KI2jXzZN{1DGvvWt#HjDYK+cpCR^Vgk3k7R{&HHD0)}({9%nv17yjEt7XK936Xfg z59SZ`IBcmHxRx!(`W1ZoYs%DFdi_eN<#TuyHTFC--GF_Og3_i>Yo^W03f8jbT%9&m z`)QMtj-!414_cGbRX#2nI+B1tfX6RS=A_e>$^qc_QY8VPcWmD+A8pxg&<46RV~1(Q zgNp_r18dYf(D!CA;O0Dlo;7oxOrJKpS?vRB3JHaUxENuaLwVuuS-on#jrbvr`STWA zvzu#7Vd*{7wSoflw$^-Pc>_MCf@%lyjH71)SUwZXXn|>LC8%${lHy5XZF392?3M#(xhjI1$J7`F!Yu(^`Q05t9%6#ZMTz5W-UO^$0C`Yqq&$kZR+jqW`8#lj} zyI=nxKmGpCc5HV02f1_SN84f>H*Pn7y|>;e^WS~{v;6qepX8fwf07@6{5RYG`kNo+ z=B;ncNb~z2{vhktZ8eqN)HGO5oVciQ|3lOMyxYHUhxh&1jpOh$0eY+rfMp^BJ>I-znpHraa1=95q=k!?%dA<84A#-0C!V`d*rsX* zWMmD-5~B0wEtM%#=4dl17{5vrjcWkB-wWfI`vGu3Jx&$zXa(;41s_^G!U4Sd<%#PH zB$@9nQ&mQKzGk#)yME%N>GH|0z1Ax5YqO013VU1@?mKEf@kc9 z;T|@R8x452oJY|EX9q0M4XgSvfWzkJ!dnM3=0JDIM_)$;#XI3Q5EgBIEoo7K1j8>| zhFbEmmUrHK%Rui#D*-)<9@h=~_5~{aAITp;mMw-0rgwc`13M#Y06jw~1E2@6&&w^= zJXEPILlrIMHJV>=>jW+rZyg{k5F}y9hoR5C06BS-Jcs$Ui3$!o&oe31u_OhM`I$Ao zR{$90s&BtRvU$rkgY%iQmt^g_&2sAW1%v;^OV?!mhL2RGe=e7=+>|?azmtudwi=XN zEF$bStH|28>0>im1lO;BBWKTEl}($s$;Vnos6YVy_U(IYp)*wdiWM8=%9XF>^y#Z| z?ATekeEF`y{`~oy+JZPKCr@6JTep5M-~I5PGJnxpiSL@Bu+KE$cS*z#et*zA3x-hL4d&iHzk@fx|UD#<3^c2pwJ^ z6@$BD05|u{QZ>qm9NaZy6slA*tZ>IUmSI5Y1NtOYHz`bVN~PC506oyh3N*9#Zs=#v zJ$dphTLzWuyz|Ce1H>g$(&Pm8xNf)y>)|l^1<(R@Tr#L^7AeEMg3AS%W4K%x+6koD zr*HsmDhgTwY-#=iY>dK2;bIHu8ADGT?m;00`h2pGG;kkrU*cGWp}#Rl;{g0j`W5s& z7i1UOh#NX#fqmer(Mm<*;Lqo?ioMD!4fJ(YH8$!7_YH0vlsvEp?5KBCJ>e{qkWN29 z*F<^uwKwFc2Op8AA9^&H5C!NXu&49Yx2E7DkbV|8yG6nPHI)SW-kHmBw7U2BevN}3 z<2;Jq{p}9pXoVdOf46YFFr1@}a~>}o7nSZHXY1*P(;}RT$e+=_yv5o#d`hwH`|S+! z4tRsS9;57SRm)`7o$q4qI-m)tamftQ@&m+yJ8m14G>~_{J)?A}05E``))P?yyaRtf ziwfe-L5Lt4$a@ZR47d}|)jM&B3uJ)0gRHBzA`|HoiujfZ@2090&^zq8Pl@K=LVezG zayJY`cJZ8$$Cjj$R$cI7e z23%cDvv2QD;{~SgQPV-uhp%PdD+W)Scg+@7MZ0;Tjd0?Uwm&CnVQqjkKzCTP4_K*L z{pF*C0W7tV`_tV#4)Fmt3L`}`AkDBW&46^A@W&A^>>>j6?jquP?<~PZgWCo-49^6d zQS`WE05NItEZw>X<7pYH1?T~|n`f4aiaJ{(hctN(fX|jr9eyWq*ylV(#f0l-%;*UQ z>PZu)8H52dsvQ6WYzhG*8i4(j$urFD0`Mt7rhxR11l)uX7ex>7Ns9`>J9bg-q)EZ$ z9w;l+9M?GDsdT7Zs33?3)B!#~2kxwA!}>P9^Z}i=>@yUzq)4G&TqXmW`b%S7y}4~r z?TorX!D9d(W$&YL0??reBiQ_IEeDgl$-hKDJ?-nTkATN^luxN#E`Af}} zK0agz2Jq{mpl9XE1Puc$rZ^)N1$jQGEK;rIfh(0y@8Jo!d-o^v(Vsnc+0;0YA3bJ* ze0B1yT)Tc-rq7sTFoFY=Z8!wzX_?Q{mhquOCsc`lFJFCiL52<;Yp!5aKA=b8_t1)s z*1S)Ss;%uW3l^_7AN}1sKgyoZPDsO`3DPuVvg|%^Qf?^dm#+L+e@mABE>-gSd$2fu zr@sGa<9G8O_`MkKBWw=YumNnhu%Zte5D#C=KIyT~HVk|`4v13DMW^TgQTR9C&T5 zB|-}VMNMI1i=w8$0dNWh1rGnYD{?>$kO4YIp+pT)NQjS75Qy(v3WXP9S61v3m%>Lu zqd-ytkREYKlL`R;Ee6m5zPoFDK{F3$pGi^$d0Npb><9K4AblGen>%3f$2;iVS8t($liT z`0p{`OddgPlh1q~$UDdZEL&IkfZh%81A6ikd5-)k09}UN@R6s1xFly8!S-bWl*`;dw(xqGS_1C|bZ@>M6!G6QWkL1YF z6LRJ1O;hv(1`aiN!4O2|04;kfSFP7LU&)1w*W}8TJ96#X*JfXQaZ-*SKPNYDekW8Q z3l=U_@u|O0LEqRoNaoL9p-O(2`RlJ-zOA7Dy_`CCOIB~$C#ygDOpc$sBRB8<^UNaoD?WpQRCMYx~N; zfg`0~zoF89z;LOn>uWvnC<|Hy#CO*XaCb$|Ghu{NQ4ENTb^*3zc;JhQr+`r?CPtJYydx7{PXp-y=8E}LDH|WNh-_qJu2)S?tmVZj~mDR^?Z7;hh{#8 zRkCo|QwsT~A69$x@%t)zw`jPBEjsRh#ki-tZ-6&LBE!&a4bvNu zgmQlH(3f)O?)Mt!t^)mAxvapxapT)&xKm-Uf9A{;Yw5$Mii&zUeE2J?6!6Q_*~|9U z%^&6NH-DDf-~GE>z5TP?`u5-C;??h@s&0_PcI}}cSHY^kE1pj}wgP$Vmq71eb;yQ6 z@B41i5N3b~6{*K}rS5TkXr-qcydye|gSZ~<>G`$c=ksT419aUOA_@2d9}+(*Fb6)c zblCFIk^F)(O;{gZ<8!`ePQFz48zB8hj+Q>dMo3msg%nrRN+pXgjTkQ@$4r)CBPU2h zpTUxrkuS-b=}PpEt*U9Vb8{Cimnk#mY20yA)~il4S*f0DlxfrE%Dj0W%Cco^W#!5Z zTH9~15ji{u*3@U9EL*-tmBLo*#M!lbziivSTh_1NDzj%Vwr2+FuKqEHK1!a70N7Kx zpxVj&6f_DLpa;Gz423^Etk8ipYKFM@?*Y6Iog}V@lZHdxuLta0ivfDCFu1>~doSq3 z;ToQY^a#g*JIWoXvj#n#uN)IjSWQ)}^y|~#K;Kl~AhnfMHl`jIjgPirOJ}SPt;B7U zrWq7n0ZzcKd>A5Z7GJ9iAe9g8{O!_Y_F^GU&+9Q}VYRaiyx z4XWGRDG@-Ef9Qm*uVX?~FoPDbm*?RQAUe6;uFj|~cM6AMDR#q*iPhVEhek)&oc}`ZX+9G4dOp^;2ZYiYy zsL=jKj(&O4{Oio5ZGmU-MXHas?$iq4svJFfTIS4IVk7?W%WvAWL(ZSSZpwbooKbW04dqc)gny0^`P%U2) zQhG{U_ihs3U7!6vsvgkud|}W#wB0y%1Gdqi_jAN`Fqf37IIQVyK*z$$pRK3sY52W> ze7I8ZXJS8mAKxdu8T7bhSSZNUx@H;!xV}U{pP)*CIH-02i4T4HjJfi~krOg~<^rwJ z>3vU^JcV4-uu-yj!)E#7%z2qKYrYH^K2}z5*ea*aUXeTB{9dl#`Ce|^{Xy1m*&+P~ zj*!N_+T2>aLcThCS?+xIvwZv0pXI{U+p^%pRnn*bFc~p=k{md6T&`)&{_XdFlplZo z5BdJbKg;!7-^r}GOZ567GI!o$xq3~TX&mb5sltbFM)V;lBs;uE@CtkbA3up_AS$=Ux~U z1%_Xq>qw76&Aqq}$HXHY?n4;o>3j`bHH^3^v}4phLo4Zw9n^QA)K}LU=zG_wVk<2( zMem)lJ|mX>OfA^JzMHB}CP_W^yNBfQ2Ol=rKN(T>PnkW|tnR}wzMn+{`|mYRhYH3= z-?)$5!R)XN!}xyY*WJ(l+V$?&2ke-K;{qbwhgkx8eDr|+iH9GS4sF{t!<{Ya-hK7# zV|4XL5Osu4Dkp8&J z$_9fzgDe<80;dp}TsM5gSOxn^y>_wQudh~^g_4t3X%nbOXWY0M%C7#B(lgI|^GVwB z>5|ez;!_l!-Bl_7{{i$E@x$qmE(1cC-^2S3r^)xXx!%Jtj>Dk$xPG7Tv0Iy9Y^R=3 zSo7k7&Q@v-A_TBE*Nuj|`vw&}Qz3rs`W-oRmUClU;pq&x&6I1<-YyB-1_Dx*}ea;EL*)n&Ro21$2T?HO!qlnyJ?%u zQ6^VekIl2tYY3&1mk3m+hUJ%(RhxpGTu{)5&W z#4nE<$X!C-7XkcH5zVSzw`5!(OaTMRYym5fN7-}iD$9Y)dA7hGP>&up-u8)$3g^0! znh|LxQ)nrq6fn}q&kwvYuJzG4+>i8$hteWFKu($zcnTTe=3~|W2EgOSp)-~VR{6OF z=DHa=V2FX9;g$8(HBwhq-8{_FRlO^GJ~^1hgffNDtIxkEkNoy`^5_E(ngM)Z@9N&i z)dOO-4&%ROtwB6GEZY29?gQ*u5&^I}WZ6dh+8w@_!#8^J6!EAq+<<)eIxKt-jO!if zo|eZUoHV&l5a(YE_PA~yXEn>$UYGbdExZbJKu-rOkjL!%v1VU>fLP<06rKqPrh~c4d(fiJVyTYyoP`PJZ^=h6=nwd^k6M| zpyci(wt*?Mw5898n$Yj7RbopLWMq`ch!K;_#e#bW*9-GnYU>(JR8ki4 zwSWBar`7?>#45Oi5M>?@Yvoi|H%af_1I*nEo19UkwPnjEa^}oc8`j-ZD~QD8Y)MGY zl%5${mW%78q@qdk3M-_GzK4EYW#biY3O-hM8eemKm{E1WhltW~22)^W=0G<~5Ap=7xOeDHL*vcy0)eUZrw zY1GWX@WnZE7R%WSH{|H?^ERw0Ewf1a4;?EjHg1#i3gHvyuE_EYAIquBx8$O#?;ZQU zkX4&^$R`Jm%9pC{&tAK$aX*%$r!L6#uYWK5zc?w|wK=wP-y!+(%vU1HwvUU4DIrPO@xpM7$h5dK3a^)r)lY95;?`8RlRWfPvRO`|2*MG1y z^%)?nwns)~vJ}RP43<0yMix!^XA)yeVQj%9-zIq##qwlCt zpE;p(7kTmN=Sgrc&KH_<>Lx@X3PTLzX9|Nt;AY87X~_8(hM76el5rN>QVN- z1`c4wHG2e@o;rx51AW}h(51NboLUDbyx4B~lOo-W4y!<7JA&a=;X?h|Z( zZIu*$dX}ePts*ABv5k-IVw2$bs5`Ts@zn?ZdaaBj6Z||M4;(bigaY}8yyW=+h3=3h z-%tsVS1`iJL*ymG@u|Cbpl^vh=%5EU4tVbClMVeDQ2O|bNy`CG+H5HYRh9JyY9>Q{ z|NWl~^ei@J%Z&HPvv0oQ(z$i(2b(!NZ1@-(M1cT9%}<*?$Hv&xLSMIji+KxJLcvGb z(Ne%?ziin$E2juj%I=Dl>#Sn=;rIU`+jo7gEs!d0eH2P!cdh(#N@erMdt}=u2c)`w zfW+#%icMCy^PzU##wsZJrgdw^_pAXem79Y$8n_PI)_@CNfw`aOTGDe1r{#WoKlW?F z=IQ#er@=j<@8$Pz6C10Lj}69q28-`70w6&;cBFZkq+vV+3F#lHFPaHaefkWNxeEG| zUtKcT4jnO33QKBb%B&^w#i>hjPG9z_jXUJfiSr75{X^DmmD1Wil2ckEy|gACIcc_x zpRvH;fA!9fvUJTB$t|gto;f8_TGb%)7O#{OXD-RbYj+gvd*rfK3V?pKW|%eWcF68M zN9F4EALPQNuVul46*f%k+wXpmFOGaEpB*@;3V(}cm@4~`G>h1hIWfX%3mb(G@MD1Ao6i&& z3aS@0pD@Ed;iSbm3MtLnpjQ>3t9X<}Bb>|I@F zowE(~z0I9dT~=X>o>i)1E7v9@OBcs==q%4a`HU%dhdk>3F|{Xu7byF%qIXC;%Nq$RF&;xtQ3!;eG zu53}Ag!z_y$n_Y{g5fqAIAECh%dcL&Yrgcx#vw9r;3ySk8_kUa=no%0X_dg$t9Ru5 zg{wAi2GPZco6ip(wH7%`98du;OnS45#M#Q6?Cc_0y=Jrg@Z+E5yte3RrK9GFcjoM6 zs{l@&)$}IJl(Nc3nLK@gGz}Oj8M$S0=;#@_^X(sH)w+*O(Rb1J8Lyyc#7&ICF-FT> zYoO~eC zq^zcobkNpAJ8em%rWeTY(NkonW)S@FpYA(szI|Lb=P%xsYd3zBo40?qY0RJOIxN$t zFOrLwuE_U4{3Kt0^PT+o)6WL|iIb)n)ES<{j|J`+6Aw`NWDr0P+)?(f=27~L@}Z-a zO29j{fH+(Hk3K^Y@B@6d9uL(|9EL$s==?gA7ljX%4&-TuQ>Z8$6c`E_ZW;%i+OXI>mBrrp-0^_>LwURUoQ2vjW)zGCnLxF?*&?5s}=l>bq&(kyHVAB zZ|PlCCv}yzX4P7#`J`aycAXUD3RqR`sCpo8p#RP9ntk@>uUCcYFm`CWIkdwT4*#XN zUU`Ho5P;0=TDI7`Z@y(q6982dH!$ZpcqSmuF;E7w4tUJnG=Lqzdj~J^T#=JrYoI5N zrx}L1!yR)a@8`X8zvOEep_5 z{EW)Mb%-pjHIOJ zDco_*C?FN|ofMGw13l)TXA4xLLGKm~^>CP101kRu2-cw;sXQ=_`H%g$HS=`+nDnB< zqr=+7c8-;fofCwQ=^E7evASjCO^1$gX6-w~n#zxl)7m3BO%i%$NYmh9vSj6YIj5jM zdg_V{8Zkxo9y+Be{*sKFwoqm-Tw}wTHh#Qc5>oP{-;fCkc~$M%3cLD2GGWGI1N~uD z{Ryer(y42z#A=Hnx3E%%j+`XB_I@FkuHThidkz}tQSjGq{$xX?0R8rz2W9;D*)n(T zQmy@O%gtMNF~f0o4xFv6|`zgL(jQeD=YxHe5S=`3IjUV~W|L_-O_B3|fE<(DAWSATiVz zs-1AQKpx{9N{nk!UH;W6Q+jHE9yb8%)8m&f)!)UCOFCw2^*7+Usp?fNc{%yE_*t$N zR+cTsebdy?N0>F+SB+z=R@DSwo$C00dsXv~+xU6Z`#rFabkGtGBwcYklz+(_><;bl zG27PSdt8UShXZtu8GQqY9o}Kri9;I;13cP14(63Xc`AnmofGPldpwDn#1SrE6`(4WO^6(sET?Ez4JLF}LuZgU6*;eSaA{WsWlE8@X`h zt`wBiNXIy3otA50|4XhL%t0S^--N-6xuQlidl=^(^ccs{pbu9bt)&}nf9<@d6;7`W zO*#7lJ+)gz(bKsBSYa(lv*Y%c3a~I3;^Ec$H3%6y%)_rpF z;vHGIYK!#hJy;j9S;Ws57?jE*$%w*2&1vYD!b5sZvaMV4Mr0~r%tP&*;>{-1M$fM|M z@WEQLO|883a`D60JQ_q--2B-sfTsVLp zdqTtTl{4HjtibOF{4mrV-nd#YTrrr#-_v2=A@A3d7U!sB0I0*+feny>yzjGhBi=v$ zxBuQ8A9H|X90PY>wm2H}7~lrj?%#L7M}yuW@1PHcTL!HTMm8}q&D}P@oh`t}=%mGU z!+(tH#+5XA7@?A(|3B^;!~lRMp8#<7z2yh=-9Jr9l~4xL~P47hAr3qfDAK$0klO_MLTS@ZZx>ivs`bv!kZ) ztEw91-1#foD*wUY57YrZGh-QS;R7r_JMe`Wl>+e)Y^-^|eEE9o6JRkj6#d}g6XfHa zpUDkvH5@y0MHa5uARF|)fc}eP=S=Z;;DhWe>!PqXYX$IbsBYf>{Xow)40MNXbU4Rc z|4X3%YZkt5YvyTrdcX*eP6^!cTL)|0%m`-4YKB44^KI8IJyc~Bm&)iV zvt-}VvvTRyPjd0*kFw|RY3V&^jPw~YUN&soFXyj*C#Nplkwwcl%ixhyP1Vm+K<_(z z%G5l6!g+1p?bTYI+P3e&Q8IJEayfAHwA}gO&+@ruhIN~E%EhZ+%h(CCrKztr?M6+L zBVS&S{huF~2@__?;>D}9nfI;!>8BOug<${y|MW>jK~xRybLP&M{hxg<2M>Lrpl+}~ zhfK?s4ka=ug@q;|O+H59peRrVRBY_i0R-roKvk*g2t|)7N4ev(2lOa>+%l+m{PzR; z54AN(uupdGm0?3io3iIRj5x#v_AFA>x6dG(nMkJ^pkK3kgALzg*xb6cn{1ShgC3>E zC>(}t(uwQpi!E^gJi{q*+hDvjN zoZ~ugDMSN4Y``A)0_3nVcfg0Y_k(!&I*$EZI1bl)T0k6MJJ5E}hpjcp2Nrw;1$R+m zd>5OThWo}9JqGYGM&&T3-juTDT|^7&n!HP^lyAAx+5_~!nY`eAK!nrk1H7E0vHAk$1a8LGG@Q<&w0VP;LnIbJqQ`5t!NGKnO9A?AfngP5l zF6OI8-nj9-0{$DDNOj@DO%rN#v@)@gmh{O}=jH$T|N8&f5NTGaM75**eWgoA;!t7W z7TU03o0Vg}g)wsEL^*Tjnx0eG-~3)qoxNttoj$ zpm$cGi$#MTX!4sK$_`KmE?ala_%<94Gt((v@d=4rH+PMg%EIO&q0 zHIUZ&45_4Jqo*p>n%X9-O=&8{Xfu)VoK{njkk<4)HIob;Gex%OOS}5bALY{RpJe=u z#gbM~DWfOPli5qwnqt4CFa9f4{YOt-mP5zS%gGD3u zrK_@G;}*Gc^@jZ6kAF5_{q`NZY}gjVw@@Yc8X2!j#$_lLE*m;u>4*jDWHgNRGf?x) zpk-Jl%R1nysnd6YVgc5`AJC)FsQ~yI|A$Lf+K7WCi&xkdKR!you%OH!PkhurY4HIG z-|``e70cHu@W;x`8FOtICP1gaQgA8E`1Nu1;D2@HhEX_CXSix|6wr*g0s8Ehsq(9> zu2CKFgs7)fAbxA;=xDc<)@!BRgbTp zj#=RT*n=WkaxQ1}H!299Iq$rQ?*I;4Lw?IBn^t`u6e)l`+*tV^trKp+< zf!_V|F&#VG*m@gk3B>jPc6AMSv-H0uPXK5PXajXxiR1^)0dW9N$G!^&j!Dmrc(e?; zj(kPsKz^g+)kfOnD*UtZBsDG5I)Kexqm=-wSpq$W3#znRYS52BYXFr!d(I*``sFDF zyuw|}FR(vyS6T!3`0MKW>9ZDE-yvh|7cE*P*Hl2>{`zORrG{7Fj8-@>2FRbM zbNIk9scsk`UAm=9OuVXjT*hjh74)6slO-lDK{}~*Rw%Q;S*&h5Df@u2&rEfAhJou4 z4~Kc2u$uRCVYoY(TLW}!7JU!5a9YvUCaVVz($ywhpyqAFNw*AD4EY87U5{KK(;SjhikTw(OFlCoV{hW{C32 zM(NXkgsj`RL(X2fE*rP(v{|w&b&C6D_ow@9Dbzpx`9JMTH=iFoVj~8~pcp>JI#sP? zWIA5ykOlO9)b$ACY_v;Y`i zjByQ>gD*A9+T#8C4mP(BhFiwR&r=YAIx33-4ERxA9J_DT3v5N1Rw{Z8ps&To~tqi58P4p{Turk?Ahm=vM72~`}2=I8Fab=d0aONc^k$E z>=pEnGQtJmKl123zWT5^q{GVG4X}GSaUJfhUGGL%I6h!?n73vQYGBJY3~>j!8}a#l zR3M(NhjZ+}CoMqEKH-=H-yt71;!`<1`XHcxK-#|hj;$IB+yOn7!g@0C2@)F;P{;kiN6UKhKtaA>xu2`2`iuIal^n0PK^u z?0SVeEnv2(>8kE~B8-}>{Lr!_4W5TMfF((vJ1M27EsubRLR1xNe#9F9v{|ZP$&xiv zRn^B98Dz2(%L+4WlKD448dcAFS8xaB(DC{o|M`E(p~J^*wmTI7Zq^)H)~fy)TW@oJ z^w}|BPrBnK&X7$i4tIWfNY*MRMvR#%jRQwY!+;S|-!w!@do@T>&s^yk+s)waZkx^u z&RG2~I_dv_vCsH<7IW*Ul`y}P3JpLzJj1~CZ8T^J4=a3+(;ARl3;SEl(+j8T&*t}S zla;DJCRUYt91((vQjDW#?RbtEqY40%lG)cm-nvWX%wH-q=Pa~!=eK^m zQ#00dS-ob1eWaML((~~VGAm6{G9{UljEKU=WkV+p6Q+EaCC3=88eiy)-%j%oRgNo$ z&Q>2@38*okjoJs)tOt%;2G9d=K#%JNxVx&yjYGx3bqv?!I^s~-QrJ*f03NtI=qZc< z-4vG^=P=Zochs__K)cHZ$m5=2DTI=u5`%n6kv8i~N>%CWbN23Ipl6E#dsFlZ`VQ~4 z4cs#kzdZJcg36S92=oqnK<^`P!jQ%s(5->qeedi$xIK+iy|N#r1-_<;ySm8q`>uIMwnUSIyTwG#_Ua z*vhq;nMF1s3ZFf*T!B4)dD6g@N*PVo@JIV+AAl zMyTi^92T8+oAmC%m~BRg806y;g%5eRZy#?%Eb-gh7+ThZ zP(>e44X3qQhr}KR^D2Fz!za#?X$w}$vJE@Trp{X?!?Xe@Qkdl^$jVd+quyB#Va(K7 zHd_|>4<9#GvX}^=e{PP}^uYb2Pd<}rb3c?>3s+d@$@;CkrKqgVCO!cD?VlWwZ9DhN z$2<1Q&fWXv(|reRT^srnST_UZ(WuI_{{TKdGR^#q45#!p=Yc)oC)3cxB!l?+J;0p_ z8=S*!ldlEA$Jf*8ipvIf3t&d2qwWDTmB8RZBMk5;`zEc(06q{0<`{6V>=pR?sVJy4 zFe(UKJfuxU;LUNM4zwx26fg>_10H41dE(*Y_oWknKH+r8mMioddpFt0nudBhWUE!> z_cCL@cU`@yca}$R|2*5?)mj1R|J~_>_BO)C0I%DJeyxg>Q8&K;dQ@;2^bTbQd~2W& z13L`-a2g&SP9yB@;d#O!b~uMY56~UR4)o~$hb;!gF%M&lIp_&v z3+PewufF(#bWcn&mrb;P9?&yumZcCJE`XkVOFt8^cl8b20W`<__w@VFmxHU1JY(S2 zIKZ5|!#-WsqWqRIFYtIdgdFrgC!35ha!MNe4wLbdW^2p;ruFgR!ueb)8%E#^Q1Qt) z`k*5=7-Grq=&Tl_pzo*^FTm$_S-9@=ANYTPLJzxY!hm()hR=sV&v`dL@8;LGX3=rO z79FRx>)Is5$LOD|3PLlByKbl{d6B-j88v2it+C^~5HC^M>4hJt;_sGSA~pSn%gn{A z-GmZ_SIRN;R?L*tK(y@QFRLFfjP<^H%?_$oxM=jx&i299L}Tc9r}a=egIE;q=h0! zjRS2|I>&5*H?RlnsC~dqWdQ5}ILE->K~ESJ17OE(!+FlRJIANG<1=N*B~S<86hJ_a zVndy=59m>46lnL;a*jgG0%v`j`kC8?2~(xTB~o0-B&s5<1j-Edz};51RN%X+uh;hj z=-++)ZF%@N4;bXxnnghW$lm~Z2eJb^Yz}#cw~wm9!oUy5A>94>>@z~=wU=JD4qQh5 zgu#wExLviod3bbu%mI#t!+h)eUIDlPbRbVhtE=~D(EIU&zXA3S=sS8s65`_T0lc|v z)EJ4w2TFpqZ;}iesCra15N5xp{?GoO1AL4Y9sM|T?)!)w@(%d~I0JaLsCTZzMd)gt z3W4-E@2(lZhHrk*py4uO`W(x1R0vG4q~ZbSKoIqtz#?a==3U*hlI`Sav*r4&Z{(sX z@=I!TuCgfElqqv1TiKDS${N_C?147WXMLLd{9e+iYW(1#<8t%nH}a=H|4;e-&;Mqh z6{P&{$M;NO(f zmu?u?8Bz(zmucLyS2WJGudM?G(0}v$|1f1=)i6-z@ueAsJZs#XI(tRFJaJAlkyad9 zX>8lMR|-plHEo!9!B9y$TXDnio5&0_Ls9)GBESyJ8C`?{b^P<$8qPk~a6Q-Io&m^g z0X1$HI%QGj4r<_y%15QMq9AYw+*ASp9k3Ihc(eq3h$i6E)qZwGMl zb594en*-fpA3nyS<70pv7(3{R=WxdWd~1*o0N&E+>Tt*YGMte&zmdluen?_Fb~3;N zd+(6t7|^q1vB6%!8mFyn+$rQ+whXrl)M_2eVqjSBa<8+^HniG0NM zmLUSdefOjV_@ayLml$fHwcJpgFaOg|f zpn(4J*eSVn`#ZUM?T)Noz1jToD0>XpckQZWRrmAqD(ov!hYz2!RWO-3`=9^w|7NhK zg|K7i9us6h9xnu9?BKy;HaZ6;l$6)ok}Q1(jFby1IB(whNp|fyEC&vslsgLg{RdBI zWt5>xJ{UufFCNhIdw{xwzLT0wBvn`fc;3B_Itqh68qkFKIgjfACN61(ef@6#RnTMM z`;d;O#WBC34U1QG>7toSRXi^asN?@K(-(oN4}A67go%xp&U#T>&3x^(Hq9xolL4b9 z%T|4fr?q*sV$%*;yn2f)->_ZQZ`&&;FWr=ncYh{n3cFHOxw956m)ZK~Pn*9)maf|@ z`;MG2umgJh^bE6Pf&(LO=*0ba_vZ%pT5ZN9r{_z7s^&fehs%J$qpZ_q`zQP5l2#rk z&s>)3y1tsZ%FVx5p{;`g-OtD@(2RpJ31AP%0X$7$UzXV2HgvuMcn2=$QT8Y&+$~`k z<9~O*I}oRnmh+rL#U zYI<7*@a*GH8|cFmrQB`ffNu@-PexQdkah(ghB(GKcfEw+?QnPFIv-z89L&>W-$Bp) z0I&nuA^l4hj_c;2cQ=j4^J@UR1Dt*0MMIv-Fno;4cMHM-(Br3P2?yYgtA;IVzH_J8 zVDycaOIy)W%No!H41gYRy9nU(mh5vLU^67wVb3w(cBoS+gjGA|s0_$o90PqOS^;-p zjys4nxQ-53eDnS+jL-uj00c+^d$s^SGq*qn3>hv2pQe8##vdKqS!*(_*)fj!VSJ6eqaL@{Oz=T`vVy)whK!#ohfZCPQ@XT*#Ho_*9gTUsjK zdI9oO1YCCY{^X1>r@3~^vschTm`spv(oeIW88%rpF-lJ8-On= z3v*YCsct={pi%JH@{S$)_~%jlfS-Nt>+Tzr6a~=JpaNh^VWhw^b{^29>T~pZX1^Ba z6-m1Op3a@(<;lmNl;0|x9#GH#WMKc^oA26^2qTA#kP(Bm@>I~H=mCANk_vh5iKhY; zudw&dSRl_Ba5p+OqYc;tUcl{cmT1sBs2$?O1MFeY6Ay^L`RZ%7b=Z3afy;&&rkrOV z_(p@i1eW9MHe}<{Q#Q#S>r$^gzC2 z`%bn`7{{n^FOv>wT73B6F(%wO=*cHQnfyUq&oAT=;t)puL`)zOxP~;?XSCOZ@l#AR zP?-=$#lXF&K=|Ssd5}EEIn1Gg;`PqUjGTPgz3+frzx}n`Q7F6X=JdI%))L3Ha^v>* za`)Sxt?W*lxj-S`(~OZcOO~v)arS()#6BFNpucqKcJo^E`0R1vu%-=*n;}Li%cy)? zCgH+$nK|b}h5TswaQOxshJ9YIXLvTFaenyyf6C#bXQZbxB|aflSj-U@PMmJ>_cudR zIp=GD0a{#D7{Avm0k!}Y^XmxXy|{%T>~VoSuy+_^#AD0*#k{iRzhFxq@b~UqCd}h| z9JZvxJ#bT#F3;Kwdi(f6XMOmH#V8;;b&RuZjAk}71$_rS*FkUAHom*$R@BP4>GR~6 z{)sof`ANb3t(?1h+W>vx=C=y_W7ZM-cDv3B>TWg)2grZ@)4!Xq47UtJFH!8%XD^YP zcYiNeZvP->F5i|@7jGKyF?!73p>sG+Ybu3TQ@^3IYV8(V3x~DpGiXxk3vm~XD|mN3 z0e5QuK+Q9SJa9`n=(&b?zJM99Ws8zeNlr7UXJ_O~TB;Ttg+AM!DXOqF9Lv=B0Ns7+ z-YlkoQMlMT>@hEFe6$(0&;6)axIdK*VXW&-T(0HM_Rcp7C--Xh+q17}_0;P!7~`+c zovUF0zh}2JNr+99ciwtWLH~e({&7{@ue|uOw12OifqwX)VP=fJLDA!*XW=u(&bykA z27POQ4;vGxT#-iu{(hhj$8+P{>o31zAZMSgUkBjddE-qpfKO`!7(0B!E|>cmE*;{z zI(K;cvBx70)*9#?@)-LLdq3v62;vv%P zLDI2-WpapR^b$nb|J*^p>v&(e1X z+_@h@5XkS|`-N21_OoHx->Ra=jgzSN>a48+pBWp6kc|8$fN7wIg$l`N(7Wgb>hzo7 zApq)xagKd|FT}yv_s(4Q0Wte-gs}zi+~2MFT}NQfc?Z3l1Ktg|H#GK>Wy@FFAe2rq z@zSPqX9az16g zwOspJw+j4A3gOX{W=L05a$&iu`C41(f5!X|<;0n*=7$IJCl%u$09yV4!J9y0e^P|U2wQth;cWH4yQOmPW=c+4t z;Erl%OBm2+-$&lqYL)t|Jr&})3fhXZ|FH9$R6p98>W zYh{$7>7*uU#)?f+mDpL{cb@H5OCWtyb?w4BX0g4 z(6{EN$AEj-T$KZD_6ZBe#|U>d9}W7qUVGgP(7*roJJuR-MGjnl3G@zaDj0`)^cM3p zS_8eCL;ha1-r~ODcktf)I1KtXUU}IRJ;N$}iDK`NWyI8kaTA4)zsG9XOHvqPjHnu@ zaHoPtFfhUf7?T%(G?2&5;-IGBJN$t>uqV&p;sGFBOP+PL?v(?1)r5qW86c0MCtnlC z;S&ZGh7Wtx*oo3dE2uvG2Flj$JLS@q8}jM?gHofFOKtCd2KI`o1}Uwmv(Jm#k}63G zdKEbUA0K^jag7WeI$nW(!zNY@8Z^q>GmNumL{6_>y=CFT74~70G%bsa6r}vln!P|S zU%4e0F5R>*RMGMK>E`$2 zqbJ#Ur3U#V&6p^8I%hENjc1r7et5tS;PJ&1&PXESySnEX1rO-Ev;MwjKvaB1X|)t- zhODb@w0&3coMTHo)HJG^&QMm7WLSB(Y0ZbI~yB24f68ZX47*N}nYUngRcJfF1+(KJvx^?tllb4tgN&;P!Z2 zLmYR}gh9_f2Jlhw_~_Yw@Xouo4?qDl&j^>{f=5F(CckTW?E`Zru&Q(SUczhe1!A zFzmzd_AQl+hhsc96`#isAWwhC1Ns}EmH197v?3j{zD3cq5FJZZ#3^X7cm)rj=f565 zc9M;%0@45*5kNj5zc31G%H$c=k3;^$fCl-GiUE-T9EeNa1n^u-ej=~24@9Um+#SRm z4L+F9Il#wx2a!XE6*d7GlMtD)T2i8UsjNxn&RMM$#T2Qk9H^DWMDv^T;g5{$B1!C) zE^%E`Btcuv-L*V0hMrM4$;m9yTxhUwY8ouLxusSK&~Heb;o8DaP0f~uhJp62XwI>O zIuogw$XM|rb#GgnUN-G=vhCd}c^))l>j-ouH{mTNsu zn~ohj+Nhhv#6&fPqyoP)%3YPbtNKo=@>%PKj#wrZbkgQdCk0%-*2?2%%$BR)d?!oS zZjh9WY-v<=xO~k9xqjzc*|Kx5O^#ZTbY0 zZ0@G<8Lz~_UBh)4`?hwC!ZKAepec0)X4qvD-p7ao=zA#W`N#)q3w2G0D20Z?LSY;- zc!c>*DO>=aLPx=3q8e%*RZqt(?i(r__VL@(Dxh$Y76pz1jj{stK01f)D3WaEpdMM!4?-dEN{A0KVlNK4e2I+rQsd;vy@0S+EXh)4C&HkeA2@zRw44@T-&G06i+5LeDW^Ctq^R76bm|Q_`g3 zpaKY5oXM6~>3<^svhQGbn4o&uk`C7)u=tGM>Q&oh;ez#A@ifW60h46^zSDB*T3IxS{S@JZ;GE33|UYWmu|oitQ$`y5*CC_K|S^s-D7< z-{_!cpLf+gqUZs#gC0;jw8JXj!OnS(9rDB@EUf0;nkxhD1(WnW`g`_w?LhbAXt2AH z21a-@=uz_t2?_clyXyG1~HhbdDd+P^f3yO+>%O}prF5U z^NviII>W}KrsWmN@bQ!6__>R6==d4w-G8VI95K#@QPR;$2P`W6vI70HLtn|5@iQbd zr_^S@GVJNjH-E66aRATK2UBM*vRXG$GX*{Abxi|p_8T2LHTC^W4dALVPy;;8%z)ip zH0%R)U=HXReu)c*c<$;U4kK_F`#y8VJk9h9J5|F#9n}uh@yVm~F%RQBR-o}&F>;)$ ziIKy{$PjJn_G#>IstX|FN2Q6)J}QXDjZZj;HLob#{+c= zY1k;-R2-;0Adlgv2lg4NuCUz9Ooe%W>EF~_Vc$d2Q@cr8iYmOcG+Tdu^srIZ8H;}& z(9?+<+o5ywNE;x}_U{G#laD^u40?yV13wIUK50l8karai)H&x+ci3}`f_HZfqgL9z z_rC2r=z%;+9@w&F7A%k^JPc&atu_|j4^kZW9E0(3C=z%l94DrE%O zTy240x%{o#56Y3na^SPGa^w0RK5vZuusg@DjriolMrFYD z#0TntJ`8>!?-c~__R5*}8-}?X$8OPK>^tN!(lF4o9BOJ0Ri&xHcPa}CillGf{y8SLq?5Jb$(E48~R8xO_kI%DXgrP1uIs`vNfBf zNFi3;&|l^*UMYuo#tawHvldAv08Si>)&@os6y-wV;S~=2huvcy>;abW`}H zXh!cIQSs)tR~1b~0O;A`+5z-~wSX*Nw#HW9!=;j;u+3v6jDnq!H^3hi5A*>%3coO~ z)Lc4%e#xR`^5Np;GF6+-_)$^$6g~NvjG({|{GTC@eMtW2pXFP6n~rpmSrD`oh= zMoCRh(C1H<+>A`~$&VX3)<)hmssiK~Mc?85U{MpvQgF8tC1C zIiD|#Y2U%X@8Lk*-7-KO*gN<+Mu7u&AP?*@!g)S`4xAbJQ(0DS*U{>cjWfaf~W@q2L0bFg(+4wWSDhi81kwp1(+$Omt03o8V9EJ1+*?CCIn z{nfY3C5St)ixyfGe%H7pQ}^EakK(qxpaQ~&Sb8Tdg`RWdH!LGPTl4vF>D{}JKv0l$!qxNiR++ufV6;~VVA+MPgZUH^5|)~d*_dG=-@fo^~o{0a_MKe zdgb@BdGmhRvSp6~_*(_`_p;-Y16n>a74obe**TAiF3LCG{87IA@~nb=k$rE1 z(KTz=eq^1pSFU_*BXQ`kEh(unH*AS=fN#q(jvlyg-|?wTnL0}b4H{`5En$+?g^Sm1 z)yu70cT1915V&tJfZr(&=rcM+-!H;80(v0J?*-=WUkA*t=z%j3C(J?3)(yyajwt^G zO^5Scb)QAyurA8eaNKykpTiyVeXnr5W!4(h!|^$G<63@Co3yla`;tvklKxpq!M7?o zUi#rm8*$T7Eg99?tGDzWHeM!7pCdEpEtGkS7t7)gKa_d%=gW-gvt;~)Nit&Gco{x% zf=rk>Lq?39AR|@b4p4|pQPsa_$#Pk>dZVmZxn3quT`1FLES3qA=bEA)H(`cMpE+Ou z(3P@$)kd>vGZ)JENwaJi<*U_7KsAzsCp(vv3T3WNz-iw%bEHdtWkpt z1@{TA70gECDDZ(hTRLQcJe{?9s=R4VPtZ&?R0|4gz@z2?Fs>Yy4Q6#o)DeY+!bJh1 zFfqAm{=5&Rw4_?!<6Ki{7=@G8RZ5B$=<;6D)WlcqgHbo6L!tJ%{cgTj}9yTBh#Bsf_j{$sF@7~$!um|p)+O@ZdMjhL>Gr)5#Ti{P+;^1b> zQozhU1-@Zb?ml%u>~IFmY~6?p=-tmBKF>Kn=6cfd^gPTf04fyj7Y6;~4+n~#a4NI- zPH_f$l)Y~Oe#Z|wn4;&yGQb`s@BVtgU#);A524P1EcuFl99%byl;L9}hzjxy(5Kai zYlrdor6m=X2My+_LBA0O+72ZCg`k|NbL3!p`ReA?}z-yMDt*76-*&Rohp(CT2?K zxE>1l0P>w;88wrj%W?;Y5)?-u?)Jgx9~PrFTz9w`cw6#b)^pwZbZP76m(b-ldv_6O3geP>C} zE|Q_+X3Bvh=j80goAT{tD$4}c#xPu3e z%HF-7%cr02moE+<)8^Y@`E37T{o{|>GNXI<9<~n)e0Jcl965U2){j5%`9b;Oh@L-s zLJsLQXU<-fW5-X)iLcJc$usBWt25{1*hy^_oH{S3&s?@|L!LN&S-v`ZMeVYU)x{@A zt&R`>nr0M+cFk6h;>TxNHluCm-0=}PfS!Ht*lFn9U)4*k79bXl3TCddyaA(P+&|BV z8y|_oIQkx{{uyxt+*v)6l_Y^YooD`uKPEF#XedZDnJHitI!4&ACJu%hhr$NHIiH!C zZR?%T(#p-vw*pDQ<~&>CS|-%EWW)?yHhPa7t&DOqbEUC&r5xD3QGU37TK@O%uFIVZ zM9V^YQ8nNy8(B6(rhvO^kKg{ z=E|L|8?G4#yqo*uUDX40AfMDl6=ZCj!Jd`?@FxyND*y%Usvbx?ki&4sqT$_|c_k3O z*3*xyt9KP;7?j7$RmZRyJ(EG1TNqNko-0iRv9^_ z>|MQM?1x=2fSz!|0KJ2kv^+fk?#i5f!rUCn+>>)0v&DGl82kRd!~ca}%l7|E*#@#mvm4QdNmc%*@Qp%*@OxF*AcDnY-O?p6(u=_pT>W zA?Nt?ocq5Y)^B6(%-nm&v))*-B7$uXet+#30u8b8c2knfQWP2*sure}=ziU-X-n4_ zo0C(jQR8On^x5m?F%Rp)nR9w{>!u!FyP-Q5uj}BB{W`Sgkgi_5rhB*V>GX-yW~X#; z&wj03vP>J-Zq(Y<>$HB&Caqh&QG0jp)81Wsv}WZBty#5P8`rPa)-CJo;qBAXB?~lv z{%l(=)cUn6O$n@Y=d541%Bp>28Wf`b}ywAe%!=uu|UtY!}%fvQGfed8C0Ab?xzQYtM zzOq$Yx9rrRo2|ETkf$-0csc4F(0jm>3depjbI4$z;1JFM^gg8$$3jhleJCTG0t%iQ z7SqZBdDf|}Q*bHVC^*h@&cVQ6;A$YI=Ixqg1tsd!qedqVY|)o@FX(qqZs_ZW7uB}3 zRPmAF%FoPFZ>uE?9XLomyLMBTnoiFLG($-;C#<*se?cF-?!!01pbv(+SM`3~ANTt` z=vfk~iHV4GfJf1@3~e6b)Vy~F0F`hHz{dbDK=yFPSSNPRx>w-<{QKbN7zXfzj|VS3 z;DNb!a{hbS$GTqz!`>@=oKsS4f(zFGdJOQR>Z3v<)zrjRvnDOv`{UKTH{L7%F7RFq z9Wv6v9x=iDg&?5up7u6Wc}YntwQEsLO}}ZawLr+ueJ*+0s^?w-i(2|`K9v<)F z_h-*uHHd%WW~th^X}g$@bE>|ukWfLIQ}rmxq9SH=@9*Nx3+FG<`BUdKXWCRPoH1EP zwr|ntJ$rQQ@NU)C?o;iteY$eCR-fLzqThacUw{7f7kYf>x(@Byt~19>wIAH4V}}mv z(7ru7x_7s3UO1=CYnJK2jt!y~TB>ZRJdZlw-xTCGh>7id`j{+c;^p*C&br|Wkf zY4VJDN;e>8*^3`AQ^U5zh|Qz$^YhD9Sy|(z4g|bFo~kY(99~{BV*ou0zHL>F+PCTC z(k{Dn?4fR*d$}P8$_>(lZ~#5=dB6_vDUc|8_ETUegghvg6flNUpyt51ITT#rooNak zz^A07J%1K$+jejTk%l)49S<7Ch0>zNL1!txuf+ae8`~bzyNj-#+^etdpAUfk!9{f_ zE>%)km~s-5l%JNV^u%N($0xY4(ety(y-!n%CLwz36$7;ypbu7{|0l2y-u{00#zWkj zhdBzK?O-(zxKZq0wF7j(?i*oAt7M&h82fN4%pe6^sZju24`kpB+5R(rEJ%+k(*)-I_p3Ev5WeMY8 z)E3FHN42BinPL(p&bvTu58wk7V9z|mymw>9j8%DgsfG_9YOpk+kQHb%;$6f!@a{34 zai@XiGT-W%`%UVJBM!rQj&(X}i0b?^Syx^@3o zy7lnax^eH9x_By9 zy8#i<6RRgiPbWtIpFE&(V04NiOatJ98(ux=y~6kVSO>V=7p}qeJm|UK0GfRs#2oWL z=RW%1z~}us$2pg4aGx=M{orGq%hK;-`2uqYFW)?7YxV2bUvp;7 z(UnV=wBLYTyKkpvj2fte8yD-hk1p#!zWGG|^)J8FfByS#^sj&YM!)~nWBuxro6dgu z$t^v(c~y5VozoW&?&-;$+j@HMjvn5+q5Ib^*#6Ucc=e1vzjxW3!zDeqaY{EX9@W*e zhjin@QQf|LTz9UV(4|xRb^iDs-M(^C_pYDO-Rr0H==M2%_P{=8;QHd>W&Q56JNomN z5B2X~f1-c+;-QvIpJM8Mm3Hhs>_9(!^dy6OvGNUy#OpD}%VsFmg2GmAENoi#i5GV3 z*7v!}M$H4^E}eUtG8(A9y#}gXwShPz-^J)Llzp{12f{VLp3n_p9M%E5SMt6GD~^B( zLQvyAu8N8W?!;38I4=PTo@e6c4sG4KN}W1&ap!tPz-P$hp^&;-g#G3$a}Z^DrD|vY zar}^ex_)|}0p1k-r?+(P;$f9iI|z?ZMr4e_4U~;O`pDo^*MM8kK{K*txSBR-@_fRP zItF_WdJp?xkO$k}I_A?XgVj7R^kDa~cnozL+z9JI4#0st>x6IEM$xnMjvy*5+=X>G z50C?7zzT5rUBH)Z_IpSJ@Ba<-z?|cN*k3RB7)$?ojCIV{XguHnI{%3VX|L=#&VJV4 zdi`}%?|}wb-yq9+3ZSs{u;$_RpF*5a0QA8I=z%lgnR#;;xtb!4u+#_vI0YUE@Scnw zHC{`XE>l%?D~%mDQsc*ub!~A@8D{3V*#45mD@=i3*ByohHqf6vb5S?0-_hewKGQt| zDBwrs^BEsD2nG@B9`=-h!2?Fvcdpl#-AAq&)f+OXI1ASCfq`avs?O$f$ZO&-qauNUC@kS{WN3hH0|1VM7JM2b%US*^=t!eW=`>Q%Qhh9 z=9Rh74Kv=L>}xu7bD1!NYf#yYcQbOtI2U_dG=G_f3>@)1wUSiJR;5*{Zr#o`i~)HU zi#K=^Qw8!Y0X(_&y!>S6p!O*&zA+V0qr%wdy*-VvD0+;L4Gpse1q_uOXk0^OIEP@4 z0fo0IsDa*p{Y}?t3Mc_e%!9s;srJ8R9`61#ECHVfy${y}gFaZ*d*EZi@p(Yb?;=z~ z11m9lAGQJfVIeKtl4G3jLGHsY{BD#!zb80U<6+G@@b>$>ajw5s@P3TX`OuD6@9byY zt9EZd9@uk_IOdnwo3Fj*oGYOk)Vv2h6NjVfLz{&;*z^9NF;sW&J_9s=!D4mo+EoJw4%EVh3$2`&nz*BLQmzBIhkWg^Q*Q2J zYV%xg{=CIHar}&K-@30er!Tnpe!?@LV5|pk^KLRxkqcegyPBF)pk!0T=?2TB^lXL4 zCz%SccW8QT2X!1aHLM5oYv~#S#chhkO>Kiii(SUuIOF%jVbX6gQ#ze1)3hH++!4dYFc1WGr$hyQT422 zfSo0Zo(vtFfmi7s_$;|UlzYl8>j0VW;XMDH9^C9>o!{WW%{Bb>g3tHo`Dehozb^Jd zlofn8OmUnQAgj)hQ=e^B_+CAFt5Z!^Eu6p5s&c1v{qi{--o8Rp236^k!?X44>s$1z zJNxwQn@MaEFxwK#H8oENg)!wBU!I283FD_a_>UPmK|=?PRGZ2UF5@QOu1ENW zp%GB(0NoER2IMgcs0Y74j`=Dxg@*78Asnj3m}?xff) z1y5rw=cU_u3`bmK*Q(4f*5r|cb>Y}9bG+B}m*0G%r+3e*C?!tGp`nUx-cn%((5CeR zU~OFAKwtkOvwCXy!H0Uk&RcrtmDly=O9t#04e-n~^$P(0KQn9oPmEN@;E+u)|q?qtybdK5jNN67OKJa*PmzF_|OgOgwW`?7SSSHsRod$@=6!pNj0G0 z01~Z`1A5-EE}gnN*i%F7-lLb=weRHAWrhL1vaP+VWv$h%dv7-%!;qoFHPmeB(&Z{H zHt}PSuc~UJ4I4J-)~!3ba^;!^4<71ZL~Vf{vD6Z91UF3G6Uw3Eo`+VjB^X?Q5AR}z zDQ9Y{yyK)cryBgypABQo*!2u+?58NCeIe2Q3**?Q+WSl|S<0fHBbTtNv*-JZ9q6-7 zh>=LaKK^5Ii8%@T9+#LvS+gabBje*!U5KYe%SaQo#yGn-$tlFq4T6ju8fU8B?zzv8 z_n^mcT4devUnsL)ZF_YMU;!%Udf2)$Y@Z7Ty*G~g>#*)&?1Amid1HK05h(|qWVAv$(=j}B~Itns~z^y$&r`t-~)Jvg&U zPp|LNpT4}H2bcEg#GWGV*>bW|; zXPwR-+TubB*qMWyb!giv+qX?8_HNXHEi2sl+gH!mo()TEdzm?!)$Z8I16xd;?$f8{ z5PoaG|I^L0`orZN`qRaA`uyB>^={KfgZmHG;o6ff3#gqrtO7D(N-C|YnCUWb80|9I zfJus_?;-18pT#UZf%rTbF~q)UBxOl_-a);*je2zLC4Ag^rvqh=s*ARwbsm^p(s=F5%n7?)Rrv_tj+2fVC&U$*6>3E z@cX8`-}^vszxuk~`1voK1v>cz6e@7~TUO_9Kpqth=uz@O*oS8Td@#&|l{?`VmR_;@ z&`q#{4?d0q@Cu*n08$U~?;D^7!ax>C194yu=zWOBpXWjE0UvyfrH8yXwgEWiLC}$%EiRJtB z?e9h{Bt!vJGjam3XD)`^yg~zDz6K2%qLnLGyINvyZk~n@AFiWEkLuyWhg!aTrRz%r zs(-)14j#df_Xgx>AE1UoBQTA+Oer|pEhlO0_{kbRa;!#} zvCY(En2)>vu&L* zZk8@vW&0Lu>a-c|dYsSnhrm9O@KA&~Nh@{^Vg=I&-W6f099wW#}CxpiG#I#_E@()XTl(NKId*V2e5bJQk~wvS$EGI)Nd~z z)wgHY=-;lb*W=S$)WfQ3!v+o0;iD(Dd*5LLe1+>=#UM(69(9ms&_y{^8ffWRORqQ- zLxI7atQ#IK4X`W;;o#MMBW+QBnN#wBpH$1@!g581$2ipv=n3O6IX7XN?pB-VUWE?Bt(W4{jMfjEY0_v^qN z1LP@I)uyqSC25r&^c-j1t9q~eY5WEBfY%#f_R5`OUR48a4|}iTG4}cWemxlUUcGz8 z9t>{}b`N`RKBVP8!@0C!5V|2;g8_ULJ285e>|>xgCWFZ~rw;6K1W9(BxIOP2wZ>jO z`s&cZV+OieYSXTx3as2RWN_bsLtJM@fKT`V#amU?)@9yQR#v%pX6VqNx_I%T9zA-b znKNfQ!Qk7E=qLrW8Dr_v#cM8JPX-SF;hp6@^kKv_d$)U7&6jEa?%sK%J9qBsw$&1D z-MFipRvWl=^RDjSyJvRa9L8gFET8C()wu86ePFeTySjJpf$rYDZ_E3-fB%77V(vP( z$&(KpXFIUG4E{8^0iIoGdq4)+Uq`~4o+!P~)~{oer3 z(!>03+5Z4NU(76^6>7OG_0Ejc5S60Jt{S*TZQ`6 z6sv#dGIt&}WkfGKr-!DF>}?LAk6WKOw7YW#;|6unsD3pX)~B6D4d9xcG`e4VO&;7y zOD7M|zE#t8cmHC2c67e}aCVt)9a*K0rR6Tfvj5--ty;UuAYbi(P7hkrxH7VfRALYY z_^nN`5Vu3oQ{C%oU?x6KgRIY^2llLc__I!&9yJf>+qLQF3Z3uRLc=I39;Jn{ry-Wf zx(8YHx~+X51(Pt21G^Pe5BgXNa1wFK0O*O&qwWDbpr-%^SNmMm*pyp&d4+0fI;pVG z6kCqfD(w7a^^JjGV_%YS) z*`-|@tv0rNf#yygt?H6|HEZ~>K6>|Ey>4p$tzW$6>`jCHo6kW19QJ<$?B6%9=sn

XT2L3$Oy(96e9OJW?2R+9<>^aYeZ2-OB2K3DvHGLkR2jV~;L(yXlG{-jS zmOjiA5gMUHa|FCcyl+ehzkAnytzNT1U3>OXb^DGQJbaWEELpBG6DF%;*BAmVGF z4)XS1rkV(%)8E4fPj&g?O>Nz}UHk0aI(_u8j_=>6Lpyh9&$i9lxn+|!Z& zFJ7!gi{@#u*^1>$v|;@Qty-~KCy$@eC!ajgnKS21yk)uAd_)AHnLy)dK-I?@^i7!? z@G$@%_H6J*KRmmKx))ZIIred!b@p?Q5NoUx?g|Dp>mJ;Gp9ehvX4_jZ=vl{tLGOXh zeaHMd`}r*x>%qonaoC*q0xCW_I?Ba>F&bp)CEL8Y6{65^Ra8`JtLxrZkA zDc8cWUA1IF53QU&NShXq)%t~FwB3NaZ{q?T*tAshCJk|b9^JpjfZbIKrVMewA8(Fe z%zzq$bw|w_*Uw#V>d2lN-n)%kP9NRZ&gkKea~37{k}jo&fsm%f)OoAt!!J>!Krk@GAMSc({x+{@Iak? zKD0x24oV-@Ph8%sA_`5KsSl^xO=$pmmM$D)>+BE2;REq~UKW;^5ATo~OGA1^X)CAb zyHvH-{HbGf?)Xl9`^&r1fBi=P`LCG4{@?zfzx?)>`s1&@&=j3zSd(uX#=*%Z!kB+C zkQf+*ARrQ>1}Gv*Bi%?1M#qRzLlhJVrKP*OyQKs+q`TP|F{DG_-FqDSvTysa=eh6e zI?wZWvihCY`|bY%_+Bnnq|AyH(o}m3A)Q!%RoUf0<~=)~p21A69h5diD?-ljZC6ZA z$G~2nP$&j~f*g~`-+FZA%R#{ij0CuZ;q;(wF11ITI~BX4*%Y$wZ9@xez%V)iY-<8g zWvAWdi(A+Wf0{W{AJEl*`%cFTgEgS$;Pc}!GJ3i;MKSyOB7=a}0IatrKhGTrMJ%#V zB$t6q>XYpx>vo!|os>{0%JnAD1&BHzJ8ace;L*<4+UV=v zyZ>jm1zLV~ngpu}c%dlOdCI_cbgt*Z8(ujm(7GdipVrAgDceI7dK51mjD6wnR9?PK zb;n0ZDO4k}?GZme)?ryqCtG&IgMfQU&k;KExw4wit-|)yb9<)ZHAsXXm)~rQ+8*Vb zYxH?*0+wvr-MF>Ap*UH_$Bw6fX{s!L(H1AbR19>6M$_$o zSJ_MnZR^8S3-J*X>uV#`=7Y@JGgZCYGd0NAbLLGScT%^UyWLm!;^acD$~Ofs1U2m| z^$Yy9B6ALhaC;x9#3d(~d%hnL9gtQBdDP;rmjxWEWL8@wdvc@`SWzZ5MJumLNnGu2 zzJ0Jm$p{tizo&fxl)oq>zJreJ1dnLbnIPWXwUh_&#zQS8Kr^<2+^kD^PcEW^Y?Hj! zMSAckz&I@LVdx!|JDM&o3DY(9n<-S7z^@&2&dr zU|zEALR?|4XE|_XkGa!l<=Lk3Fu)9=0dYU_Dg%|8qm*LKff^(R9|8vhc^lj7e9LFN zGnsU>^wV^5-@u0ugo^d4nLlTR>k#90$VUAqkTa!*g~rLI{I}lg#Ua0qbc4k}ds{}9 zrj;x+$Amv?o8o@Up(Tcm*@Z9?;ZJp9gXdw8!)#OGZyg81{DrFFjrFzwS>S;7k%OhE z^K;AoJNGkN$t-OV$9ZDVEZeu>zPD-z7K?Vet-oHf#pEWYk9qdn`NgRwOJ}JfIgsEL$JindC#a3x(Z#Wws~lRCwZ^sVUFgL~ZEi zv@{n8J7_wB$+0tdLru+MNMBV!Fapl3p#R6Nz-wV+X17Y%{^-y79 z6Qj8|E8SsZ@dBAeNZ33@WQlfhf0ad_PjdbozRhQ?Osk&GVf^P~15|tTGJmR}^U>gl z?b%_}<{5FG%Gd8a$o>fTR`C`-|dAfE8N%3v&=*RZ& zWR}`}K9-prR}gHYw`NVe#x)!1QT*pCd~^0Rcw4^^5%J#7=keVxVKwEKSwYo`qo0QQ z62=7OFC^|1+Me^3q~rS!8xw?3;lHb1HlL@I=L3;PlwN5j<^@UbXgQPf-6nD23R1+#NPfI?pp>D*ix5Uy7fS+4yB;FlRTmW z;U~;zn=?vhmEP{qCl<$<2=%sZZSe+9dte~?{yF3(7l=^vk9h){*xp?t(Jf#2MD1Lq!1l(wz%uHd@bSjoq|kJf%;p-T6uqO>grn z5CJnEZ1b;r3M+NRaw)3ay3>PQ`D;8}sVoU)Ur29grrEfD$0x@CVex*5rU>5<z3q43J+ATbW`23KNn>@$nZdhQxzkjwF^sAjG;VX8^I89e zcNOr^+T851esTd%^@laGdqUF0K!kVVCs{cAM^H%?E!Viuw>1&Vt2owd5Jp|_I*d`^ zRVw^qKa3g*KmdEKlXe8ZpWWiQN;T&~ zvu!PbM=4#(oT2M4cd%d}e5QSZdVam}UxReqrf2Ut_JsW4t=Hh*!2+l(d~NwNdAws9)ct&X|vzKwKthIyMkwT!EPENINfnlva{X$F3DFqrS$&{^+XjISai7j{WW$#UWp*rHyE+-B zaqhM`K$$$%+Gn3CU8RLMcEoMKZBesHJs+t7(RWYFT{4*p6m25A-S~&g5}3obbo2HO zEWDo@*zEk1Yj9r)coUkk6(qwhl4`TdQ5+e{#HQMBxk(J?BgN`%Jb03iYg6_id;eVI z`_4V#7*$0}j?^{`Viha+EO%l5yVAZ!Nr9dPwRZD*<{hkcI zU`ksUDu^!H#L75YM&ICniezDj9DGeSlL`%_ik9>mvv}DxMN-tRe_GYQd^={%s!)_i zF1x<3fUj>H`?wZAg+ysA0yaCEoDNT^KS8@#QNx#r3--7K9^x?_Ta z9U0b^CKc`_y>7lBs?w?f&vlId%#ei)m#qcAK{DkF1!!tdse`9+8ZLWxouy;cr=iQx zgV1l%u0)}14i31-wM%9Sx~hN%kmS1g{xixZlWSh%&Rn955Ib5KZ@Ha^;I6=zq`RI@ zk}26BNyQ=a4Y1mT00LBZDmB1^CVyI$w?8hdKg8l0{bz9jOutla^aMil1fTqB`su3m zJ(-lY(kRNh&b6&+{jPg6FxT5qgstV)aNucnzp!p3&M5A0Pyz7cqz@H|DXDgkkD|K z&2sIdj12Ie_GNrr;D2HPFVgT**K{GfrsT~zhxOjfvq1BITl;Nb?M1uuP0!Ce4~GOG z?tXw&^VS7C_Bic$p&eazx^I$3)K*hlEO4XUbkIxP2J31qf%AqUMn+Rg2_P;&l$fGMr;uvDh!t2q z0Gvadg(=7Ntm4stU8&h98#d1FxAITZR7jH*720$Mm<7PX7==>$YJ5h2-;faQegPYg zq5!WlFU&Tt4riqhLaVOg5_(hcw$}HQG@nAc`<7iioP9{QbmcqqtLD|#yXj;oIx#K3 zjB^6JF%vw28cMRCAinb5UH^tABXek1TW@@nNQ21C2SNcBemPvrYh8U)z_T`TSIPcl zFPCznklv~@QMkaUkgPnv zQCSyQ6mNbYr4n(5XO{Z?CA&!{YkzM@fP#_47*^fnapP7Hfo<(axcd1KixcV3_lL4c zWjuU*+V9?d9WT-=+?;SE_OCGw4W%}2VOr5+XpjWvBRAEF0~e5ov#E4So4z=o3uetf z`eV+!%6aO=wqfm?9(TvFA4W{5OM+i=DLgHTgAroCkkL_f=di%WvER4&o>HpCxya_< zHNi9D5!sOOm-k|6gT>ce7)yV23LPsJM$7nXoVboQx`JGv6jocVJmL`y6h?G2@ajKT z=ZRI;!P9Ne!O5p#Bvcxm@#|ZhIF7!78io@r1*UOY$mS?}T72qw)RFu-XbLTwp2#4V zz6U-UjSXPGio2q-gAW9@-&BInI^W#dPwNrI0v2SY7!F#37E9M2hW|~TwVmud^=p+5 zD&O&s0JXxde%@Ex>souT%7v2{mkiIBy|mNQ`+0V>ksZYuPG}216!)% zLaWEp7l%|hVG*+Hm^54bEm&l;YefZ zlg#3oW8&=TCUM?2ts`@bvgfC`AMngjW7}TB&AE(oGiYaor6@#!B+eQIA}HbIdx5=x zi#7mcU}HMdfOX&a=@*#q=r^?MY_cKV8vhQyj)vd~f%|@CaGc zjhm2(w}YM~^XkW#1^m=`xBed<#SjLA9wcqf@=R5Unn7U*K6eIX24?>8K_UF6@MNtf z+OV!7$_#w)HRmWQCh=bGYW(wGRn{4?tp0felh5sqgiRp)#y(RBwRdD^pLsduUm=qv6gzqmn&pM_gXx zr_A&ng0F>LfdJ3$B81sVe+74SzV+sr^X`yxqWJG@w#c$Dj&SYTf)^-9gLIYR-$H4w61>S$a;JUo-2FiICXMK+F~gBC%&!N{?2o2>`GQJ=i){X*0o}ry(vJr)Um7QEmMz zkLB$&%u!CG*J@${`4Yar6!$)>J904EtPmi3KuJagV{?icc8>A^F9%}r2t>hE`Hx*OG52{)1z2BwT7xc z!ZAmCYM2pLmU&MVny~~g7%R0ecPUor{^Cpf!-rgC1nWjsU8qy2)&;TeYel-eyGO^n zy*eDF-}g55vo`yo0D5nO(p%3ao9Pt;VTHo_m(||-)0{WoXui=7<@0R<*Hj(?aCzLZ zGSKhl%$@&Hpfn}Znch5EWoEPqki>uvq`FDw`&}F4-*_Zy!7Nyon_k0KipxjKEYws~ zi`P2l(iI!zSJcU5*Z=ItzJ0IlQuN~XW3Hj&_72!fT4qV7zc_mp|)Q;^B1>vOwiMtPKXytk9< zZ07{2=j7Q{F!s!e4u_D&Ad=%7gW>%tww^e1!^C~(CrOGYIYWYzm90f(ngbw;D)qyb zm*a(p<&V2XajvwSi?Xm&+A7PsBHPIjKuNg+64zVVV&y8nNjQ<9C9_RMtheE-t_ zBUJ5HMS93e;WLU)CwF8MR2X2!_@NY>1K^@sP+qBzsfnM(A9yB9b~%1}>DyY&>W)LO zmV2?$l}VSc9P>j_Z5-DDO;gz0@)QJCBe9*MbfQ4G*NV8$PKsEJZMB3O@|Y22Z@GBw z;K2{ZiPFIJP-14i`MHhtgo0&PH*yivF79*k2>=KD6zJ4^k$wvx(EOp2c6lvl{#y}u zqV;?vGrGIXN+~olvJKacfwDtpc?<;Kc$mJp-G}Smvx;y z`SsvNW#x;}l7jbean$?LAz|WpOBiLV;axfHFxVtMtNZE1Gk#uU_9<trC_#N&nXCpy$b&Gw-<$d6(&Q&VLzd3xqo3>2q zjp_+-v2r^`3V3VdDNUaGB1J+r2+npa;05u+?2I*HlgT>y6!ws8yXd`9hVHGrKKe;p zvPuAQW-7-@i)tP6BMIpOC1@djS1enA)ma({s${#hGcffco9dT?3PoBt613j6;%jY1 zrr9`z$amb{QuJ}3%{AStUzVh&2l|cw_fQnrhIKCKIm12dthQMZfyqpDhb0=7>H=T9 z?n{;M7(&T3xNTIF7&n(B!gh$e>H4r5FfwI(bHbrJy{&_`Vy@b+ z?>6A#A)s ztJu7!EAk1IwriK9(7qAW`8rE3Vd(+pIL$+rS#*-V5&<`Do0Da&ju_Tuvcv?3SIJtJIj!eH%T7*I2V+f{@eFCL&K*eV9uMMTw_L$f6?JD9#h6@q>%GOH1d*!3 zdn(LD?ZC5D0v8!^V#ujtjQhHB-!O+Z{Q*$2U+A;agcBMRY4vp)QTAAxnwlQ0qgCy3 z6N;lRq1@u~c~fd}q80RtpgE!pC^8*Nl2SB(6DDk`BkDBLtI)}_#9$i!5j3rIJ3w6i z7r<{Ztl*eC#q~lYmGW#XW;-Rq^5YWQ`=}9?Eoyw$6OHUljsV%T;3vXgp548-nje*a zdI|R~aEvG+B5vj*dgzc7{YZg&J?`GO>c$~j-cie1-(#(JBWe$=v*kZM<;nV4pwU@n zr7vwH(ex_SWUhE0q^%nxp~%bRpSQct$`rauyr@+>1ePN({?H2QYt6ypW%6^CgMQ=c z$1)5cT+;{h&%%OV4D4^y2uub)7=4^?Bw}B3PdVXfmO4Fb%~;U@B1{0dF7C9mZc#Yh z6s17|d_ZbcEo23u0D7x(=nv~L`Mr*b$6klnDCK=#7!;xFgb`e5J-t_4MIT(cKHq}R zp7Mp8KREhVV4x-DnTdnrs8`BVf}eH>s%$4xqPv@xm>JFARX^zh4CGV0?M(h+(_N{F z+D3o!e825$V>vNZ_n~m}q{?bg+;aN-l>*;VBHa6kVU>SlI8)WoQ6pNCB_>|z%j~HJ zCsxd$!t*n9)_;r9rm`|#S9-o*yNUYC6MN%wC3*0kfe!x!T1FcACCIH*y`1{%?ZTI_ zYfo%-u|vd>7X6<&f9@+K<|Q*}=f^xf`8WESp7ou(N^JkY>8kEvlTPpvQO!8#iFb>l z)zDbSgG#NG)Z$m(h~GEgYZ}KpEHIg03BFr-Lsy-k7<+zInKL*V=nWAz?|ueC$1$<~ zASXC!YR}*0t)G8KY>e;*CR6Ob)&d}|-^X2_#@t=JW(9GIWj>c$ol@n+TqMZ@Arl7^ ziwW&Gt3GG{0jBc{4Ft_QDkSD3&;|3n!eP)h_6kb~)VjJP|!rJql&lwcdct1aAlhZk^m-(yG`B&J9K zAv6mv>PM6&`_Q4|epVuiY3A&VCFQil%KN|B7HHf2mmrdrm_tj<$gi<;)T)2&9RP$p zSh8xIZYAY4mWR&Edmt_!!&fNavfz_G>E5?&8UcoSFX$;6SPSCS!2K!S!1{?r4Jw`%hmn4L*(#PnC zepzIJQxUbFvtdPg0>oQ?`a;(Y>E(YlcrZL`e%y9K zXG+(lcZMp#Ms8ND>Tf-crixad=Rz-dg?I|?A7{L$grAG{@Hc00J`2p~ak`g>UfdaL zinz#~bQ%7b&6jDlGkdE2SP1kz0ogC516O8HN){hu^PdPv>3h>VD8Gf;Vu&X*aBeZ! zpm1&J=)FFTz>8<+;G-ReE)BB|VZ^d7d5%|LiW?YNx7-)9KcP5uKs?I9AladvB^0xXZui8RM@*UgiYF^t3 z+e*Fjer=>iN^U~`HSg4s!53OdQ8^n?-BT!}ArqZ!p|tP6{O)iT65D+S?aAnxIlw@+ z!SdT};}2Z_WJ-M7sMA(`iR@+98=}qo`PP{8DzKf5U%VI3%ji;9;urA88WI?QPpo|` zbO?%j)`whXgpRk(Uc{yO+Euddry-<|F7}NVRnMfi2AXsu^Ivz|NftjEZ4hQc9d$V; zi&ki;?ihR0odpBUf|}V6u7xJQg2^nv;>}^SlM(g{^nlY5rd$>rr6?Z#Yv-=?cf5F8 zvMZ+9gVt^&-rM5$`{bF{mpq8@_YQXSmh!Ooa_B4$$X3x`-|0r+^dGyzKMaI(2t&s2 zI0x&){zJaOfeCFVvrymmGD>Iyw1UfFd3lv4b6x$fo5i(*Ed3Xqn#O#cGTUH5qHohxqv5x23WzSi}m2TZdHWk50#QcZ$UTc5MKh3=Z@QutrdvZ5B zJAblc^Qj2XS|A3GL}t&BV4tY!^lvB;?>YP+&>$Amh`fsUD>6MB4@N zH~Ke)DrW(V@`9&SLhCBLeZKIFJi5OI(^oonsNFbZDromcv201BH;sf(cgrnRC@Q?EK04okq4@Oww?w86T=OOdN z3yNmTk$ZdtodV1hY5e_9o$zH5dYxw5l{D+T?jPc*={f41*uLksDrsrOC{`O*BddS+ zeozyfH>p5+rh0jJ#Rb64tZ0H(-{$rmZ{GrCh^Be>1CX)@~OYJ=ZXZ#g6n( zMG2uiS;KZ_-uZ&p0ma?To@WdwJ0sJyi1GR2O>(4{GOUKtt2L!~tk%F5Wus%khSii) zk0c9v>a9E5vq{u6_@R-}zw~3xImzoP4+@`}1CjlClnDZUb@#9-8K;#wQ>dVZ^cUnr zYe{1*NeriP^ex!8Jv?ZCE9#T-1 zw9WEUiYvC!SnC~gr}|=`>Ko>lTl*6ol35p7uZvvi7W$lPnw?9o;FpsA#U#hpTW{eZ z&iQixYzp|Ob8ZU?-W;vh;J06>P~?nY9-o?qpLN~2XfCX7_>A=Udn&`sq6Rn!20GKW zWfDk9Vv99mz%ELdX|8h&_QO0S?$$T@G#~|`o}(Ml+b%zBB3k#3$0}44ebS>qQ;3(5 zZa^@F5vKLwg?mci_ih>t=HgDBChZ1D-ylkFK&+6Yd4L zcc(kfkauiHi^n%pS3aS9Xr;er(-Y{z)!977>ZT-bK#Mj{&ju1#?(`}Gr`u+(=rF2; z;2$^i@E!v7pIH583;o-$Qf#U3X6HvG(-4cLksn_j633MIG5ICnUd*kT6mvnl z*T?-t^1MSt7{UraP?MM zDlZoYRF1YT`~BF^^7HeI@~7T2_s4M*j;VlyJg*KZhB6O@s|Typq}>bXR+|{Z0d&`{ z(tKC~j;`C|nkxidx+75I%k|}?!qMr_)an|;on{@9 zP)Wu0`8;&2(CW1d$U^a^lsp$GGYFTX6{B%Hz!22=r5yXrsHww}+;}X~VQEWt*egYG zDF3OkpK)96q9&&f)h^D!p2h}i&6a#Y>9TL?U&wM#@1-^Jcpv+XQkXEg6`&Z&59 zdw+1O1k6)yc4V=w+uYkv`VjZYdHOoz12k-CXE^_2bF5Of{%g2W81tmT%sB6O=vRQ- z&Z@{5R6p1Je1fo>a#y_0JO7AeSoA{{IohNSP-YO+2Am&_R8gCUy~Mj+5pCw`HOXP9 zQsRDa?crj#R?H0PUC1}oM#C{l3KuW1VyN&!mPJrRS{PkQ3><^2P#_jv2;jZZOFa$_ zD$LGHQaTH*cIZXC<9D$3;XGwoDoScInPXy=`5D6jLy>9H!E6Q(iu!?B; z54>cd!ru0_zyWu*8eQCi4G;^tIXKp`1={cQ;grk9&5d^y0^y4Y=?CJU+@6oWD{k_! zD2!EMS$81_J|Y&r5Y+Dk@5zeCB4v7BtmSkwbO{Q1w7-~Z`70B}sp1Nb^E0!jATNMc z7N7^86e%1E+Gk)5*F4`p^=c0ggX{Vdv!ywCD%+BSgOA_@UC_>~wM+!UN*V&`1$f_7 za$4c(cFb@W_%OSQZ?@|T&S{S|e@5AQwcWK9;0t|B&$vtJt8U!VfO|eRjr_kwa2v|3J$zv z@YEMli>8zkFZyBji1F#eoUf7euaw^Ttui7OM4Xyey4wZv;DJprh}ZHVMYI}~0`v3C zarNE*jxNQ%FwMRq3X_vrIv2GIIy9~nGEz-Hl5Ky#O&hEG8R%{CP3?Y7dt{NRAL~Ju zD>@CZM+!_~e{Kb5_>&~-ek+v|i1qsC_ka7CK?rnz;yPg=7!I7R=QR9g&kB8H`$e=d zSTya5fowywVl7Ap>Qx|b{7RcFPY_`-?B(d%0TZEZ=ilkt@IJ3(7}8A2?W)Q9^MJsZ z*w~U5-}45_4nC8Xt*zPmeTO2n2@m`0cQxS0@_dGMU0t{LpI9W^;?}b8{35O$XS*4+ z#yDP@*iE-lIG3nxJ2-1IU2YXHwu&We3~HP$?>vCF_-UHJC5tscl6`soCu+c5Ih5X&eE;ZuVVhoNW!;z+3!ZX>cBBkGwe)`h{d8XEAUCee?%YflO$h z&5zK;-G5t`D6%mx$H7FZlx|ErDC#!tL805`85m#2MH*eE6azG*&;D0!Joeaa>VCZF zlc{V&t7!y!C*#bBBJJ%4f zMHV(#wn#tWbv|7I|LD!Ot+*oWf4zcJ?2UGu&S!M=I!n(*_JWM=tc!FNK696>oRCjio%->Q@= zLzN~*q8WT!p>RV25O+-cqdbzwrx*Gazl_xMe518S$uO{5)SGqXt1{Dp`cWH{ka^@x!Mh1_7dSsDdn*?o0y@e6 z`<1(o$7zWvwL0)G95Ye4+nP<#gGhle=jK)HWfsz=>#Y>TEAZa@3GKoP+4v-}fc0IH z@aUpua-SuMLM@3BSd*oeLgV%n|rd^k}Qtywxw*+4A{dHvlyq$tV zQ}h114DCUEjg*}Xq}V{jME1;mY&zSu8o6_)*g!}b1mhoR38O)oVUfwRwF>y~lHqiF z8qE=L#k*8LiQ^^u->g)em*O(dVTmEN`*e=vi%D^Vk5!z?gv0oW`rO_5ihL{O#F7@c zcfQ69cd}T8P9u!3);4i(p+&`epx$nwOkqv}Cn%y{7|S~zW;_By<=LB@o3E7Ee@)V;$D5?TypSi3mJ5nkI7aLki)G8h zR5#bD0M(S2;rVBvH~_f398_tNQ_6pueUY@Ou!IZ(r;>GRj^2 z*@~8H__TQC@K-hp?S`(_9%RhQ`wl5C6BfcHW)t?d%5 zqOwzn_-o&UsqP`#`c*6`p7XfngxbWj(}M^ABZ#fc?}lLS-3Ay1IKKHdf;H80;{#R< zO7y2WOZr_M_!5iPJ!4d1X;k%-K6g^!@^buSj%iY@y?)s?&r}9Fz_6|j-Rcf2J^~zE z)H}O_yZirkGJDJU|LxF%6$xKhQe1qbqH+6o;yf5HAWIh2an-i4SzVY=$GWclkB7G$ zX6x)jt_six1gnov#~0&Fxy2On1=1D5XevF5l4JQ3G7k&yAulq1>I*w&j1Q$|jqP{a ztVH%rSAGbuDM~7;rs*z_Z!}|nQ{x1;iNhx5_hkklvEyUY)t32WpIH7hfXU77N}o3c zroZ+XxQ1KTZ}I$r_8{eS5pF0mioG4_ru~y}I#M;8)cmk}4exlji%G(sGr&wZh}~DX0pHK!9Y|sh-n# z4hGSzU!95#&X;K=CX=O&adeyQF`Z{yM-M<|E_n4rt`mdYqk1Rs%zfo- zfMA2>kK2Q>{X2u$#h)&+1C)$N7n5 zD;1$K^%mW^^IL}epQ4Y_R8?o+(dRS-42!bjqKx}=w=L!lG9Qi?tX|O{u=lIhGAg}l zqL~xL;jJWawf(=<3yUnORcOek#5T&NN7L8+L*P!TVdl@rjSK|o_ZGV5_Zz+nk-H(x zA2ad5*++NE=Tr?G=hI50(1|IPj@Qkwv=OGa_K_({cgF*mAO0W(LY>GX#X4{DX^>7D zR-`}Gb?VKO|G%O05L%lJBvqE>?S{U0u;8RfqPQu0&kPOp!I~+NlGMH(0HwIV+I>wR zr-0o!*uDBLWlfy~L-+rQFJ2m?9V-qk)xlc6k>sjfrR!kOGw8uAYZB`S5S>@)_E`T- zk0h)jgA zt-=B>LN{3wU)3MFlMJ{8 zf2M=p5C_VAr^`HJ6aRA<9!;NawfUj4V?6Bw)y%3MW(^*Pq#U=2hl%?^$Llr+6cF zrV46`L$*>Zh`4#92Cs{tO~C8=o^+}TvOlAm ze}>ClJmf!#W6WU(UHtiTx<`<__+wCu}t=VtC862;Vy6@)Hb8oKIy?b!(Y!O}TU^JaOqjR*e zUJoayY`?VlIkn$8b~h4hl7$Q<{%Lj6Jsx6pe;BXW<4#d6Y=F02ez-0R@6x2CmI z98$-KH17J{og|hw!Z{?So0ENuuFq{uyFzo4ql85l>$Gown;uj_A@Xp@!Tmj(N@{ex zjVZz@F9a_mA2y;9^A|B)v$6PR$Xb``Z2rc`t{DY7Jd-F;BUY=?x=)m1{ z2Zvl9TlraZ*DdxgA&rqB*1SvaoN47`bYAnt8&k90;|0It(>5y^FiskqM0t=i zO+7~8(;-UE+Aw@z3{O8;dG$C2)^I!3ah~h>C?zs}NLwIhr>}wHs7l8Z2QW0<42Ym& zqm8E&Vo8lR+wB3mbO`a+FI@J2%k%of4d^~ynDR(ZA;kuSYqWnyy!!%d%bfMi3)&VR z_1ltKx=smq_M%Y!LZ$>%-!_pYYd7+|;1nr~hr2$HdK2yhNFbjqYKh~|p7-*POz{|8}YM-g) zCYT)(rj5Nl?1u+zR-zq0X6fMFiPJUJv4hF!!t0vj&wdsv=0@aKwY@gAN}wYNrWm$l zv^0}3-qD~k5FZOI;Blu_o+a6pdvouuEu9dov`vhn1J>4xvaH@KDnj6|chBP)9}adJ ziUHTVR(<2IKd%gXyu0m6UJIvS(YMZl+I}=W0{$#ASb>GI&AMIMRc6GDNl&SFeC3eT z);ZlG6~`K{P$}Gv;B>e(r}JS+y+k0RIKXO~AVcH^0qgJzMEf{nJIQVL0K$sOQVg$o~;LjBme&HojNj zJ1;uq1difR(ZE7|=MdHm973{5DWZ~TJtsyoa~^e%EIR#?C>J?t9!X2cZx_y3r{$jt zbOzOjGHJroO1b%5L!=}GUQ*dSeyC!0LFs*mqxPxOAd; zI)B=pXObe)`4i(Sk4@=Stn|iiE8np$S-`O(9!WRnps-cMDmnV@xXkb z+h%z&g{T&r9gsXz*TS@+&GSIQA}@9zAw5M{Yr5GoCMTRF>$6~w&DlwSeydqf_?AJg zz+#z3(KZuObsiBVCiO)0 zjZ8v75p1z<%ParL@A-FwBrH*cLtCB2z?F0Y030`pwHq4xsR%YB_kGZM(Lq zz?ciEH(0M{@UB(}S_(w}F`|6?<#y@XOH#&dEM`#Pie+A`?8-432NFagyxte{#@}GF|U~wj4_{hZDSa7i(&zr6<6ssZnruB-r*X{*l&tHkZ(o z_jBH0L3S5)iCU5u9jZIvVb#k(OLfY}itB~)wJFGjnr>x^7ydhs?l(}zW9Y|}>@hai z0wmw`=Ah(a$mE86az?#g(xRYMHi*_WFfV;sz%*Qa&itJZmdA(IF@nfxrFs$+kP$zb zE`Kbw)9ysqpR&-FhUi+->!GA@PrB7Q0-JvixFIx_Wgpf9y`S6)u(7xw8Se|x$6N}yp;Lg{)vlSZpK~A|i*6BR^0&K8Rz&#hA~H>W z7;wsUBqrxbrDQK^4 zL4tC$*|y3z)-v$p;mVvTm&u(nK#CF5Ze?ovEuWL?go^7;l+V4Zhi-umoGtuzK_nCksx zi5ipN>q_c9dy=TaXX69vfmLqPo~Tl8brqjF7qiDP7TgV!Nkd!jG=ywBJhkFhZRQWk z6C^*RaVw5!X~pL6McxU64$EfBAHMH7x~t#n{*xn|DMu;L+sv?Tj^6co`BDM*Q_UWc z7)GhQR4ug_LGlZw2gm&ho9O2&H~zVoIfMH}@f0=?x7e-yo~fgtz<|e>q7zia zOUANa!6BmmSC&_fTW^`&3>jduGEM)H@iTw<(}^aEG_P2wUG#^l@HV{O!}u(s^l-ud z!tm-aPW8aiza`iIat?KI2&+B7JMwKrm>7+=`nk&bpArlF_WPb*oc{iOb`({4wvC88 zSn&7CX!Y?nAVV$n79{J_OyJ_V(!Rd3tyljNTI#$NOy;D`C+c#qF8A?g5&oB&Wbmc$ z1wK`3O!|sga=CpRaX3N7wM?j%5L8X(#)~V@NAtCUrdRb2U*u=MIV}2?epgwsD)}**sauCvXCSMltHphF^pv7DM|AJ z>t~G@pcVKKN0MQ+^Vz{mUkp>Lf3`9a={229-MZ5e0QR3q%KK?D0M} zY)ZMh$Mj%nap$hD1s9-R*n>=;cqSH62R{zDBFVx&+2yf(ubGv*%E`Q8~i~K#}{&PLsHMZB4loxzMH@5d63T3@7UYqp1u9O4(An%>_jG?4!$q-9* z!mDlPVnb2YeJiEmB)v)@-+oQypQ7)`KCJ&k(*~${$M!6LlN;7Pu!z^0*iIDv>7d#d zcHFTWOb}4E)p<5nQk+=jKjF@6P$sjF!2bDFiEumIv($>NeL;D@aCcYc1Zd7Ahu!k} zr_%w09(kQ=Ylwi}61tB=sm?G^3V>1D2Kajgt9jxk;BwKP78KxhtMg{bS~6vLpsknZ zIo5fg@)LH~tAxBI!uvb|xV2cY_K2q1O0-+g{G$V%3GIJWPSCsC;Pr(uF(Kreay1RU zA-_wc$RL*nLAP0$3*5RoQ#hNz9;EtvW%*y=CC(yRXD1NH;Tw?D)QMJKZ`rG}-%Mw< zjt<0De@EOUUiC@k)xS=Az=`k1g551s?F&?5HDaZBId(@tfT zMuN17x#%f9FtNKT^u@Pcy}vT+@jw0rKHsuO*(7Ic>#1`KXh~No*53;ym4f$sczA{i z4tO(1t0kJv9LYpqFK(eafqn3;>nEpV*681xh%Q2>>|?{;%+XQ45C7eHp}4&8Nd@yP zWU6>Z3Qbjm9Gh0YZ2$5jS;7OApRi#QYQU;SnziuHq@LM*Ahju>kbd2hLeenS(*k-Y ztlB61gf*;$i%im+^GND=_*de>FLYtxD)YNebZq@We+i3to;;pWC)u)h*`;voj+KRY zuX)#o;-5dX2LXTOrdP9V^;2&q8%h{Qs62z=9RGZ^cO4VQ8aI58n8Sg7r0W6@l#?(u z?S%ZqB2S6=w-3RzM_|Ufc(I$8fgbbY=Z*r)mZpa2Xvy!0sZzN5d(umq44y=^T)zFPjj6 z3?>1bn0l`vq(=&+uTHNzjs3rl_T4|MWEF4|p#ORm#dI8m`yT);LDIgB{|;|B7XN(! z9>>RT@~R$(=)yMkTY)la+^Ko{@B9Z;J+M!Vjj%_r8Cxe(u_tR%2k|>@AyjJOe!$b_O$p9LugI5E#Moz=4C>xN)OX^i0$}dh{4m z`vnHSNEMglYwXA&>d>atje^R6cnOg$)V-!k+e~#I*uF`(FPzhr+GE zmg~@#bvm+rgN_@JkL=i?!#noql+`XyA3UlP2M(zA5Fw>nojQ5iO^UK_-+rAuc~Ym( zo^x#qwZ~5B@ZqDj@3hXIIqw>aFP^`oD;Lh|(z&y`eEyuyo;=~~+^Lh=ux72R;f9)! zrJP5EnIJG_?}k=J;YUPS*|zeKmv3N>cTO%RH_!fG*>k`X!ttP|6ID!XV7LRI?V(JW zB`izX_GO%MPn#Y~$~*9-ta~_9tH*#d1`7~@T#Ms;2eksehtCB=8^Zzk?}s}WpWzq` z@+{&U*n{JFVbS6lnlW>Xx^-)7-Ysy!lA>1X*s+WD?B1cvcT? z9Mr`#8+7K_DjnK6Usq0S(5=(kbpOI`J-oD6Pj4L1?ep99;L1LIdGDmY{p_NC|I6$8 zovHoLADq+|_fP1-)dRX~=iWNMTer{c)o(t#u0NWp|KqRj=?~xBb@u1qKGYw7eNW$h zab1t^oYeVaTeNKUNJTb&OW_Ucs4%I826rme+%bJz_$D{WJhUm8egnqnih-WaQVcdm zhz8)J>WSHRs_CpzBSt$1K>Qv<=@Z%kpfq{{`gR8B&IaEiTX*m`7^A|OUX8E~@pc!o;CKOOd}X{49y%`pAsgR{&x1ns^MLp~4~BC9I8e&0>THk)^gzCI`!-e`E^~^$JlE7+cBYE#Ip-uLswg>Cg$8=| zRp+K^YM*ig{WyJca)my>v{}cu%~L^2s8jSF^bt|l#QQLqXV6#NQ6RsgX59D3E zp2pSh!Jh5cUVPF1&wB=U=9B$_e*91W=#24hFdAn4(yM*G53mD!td1#s;E$T;-Vko0 z!4%LFesL+525{dH8x_X?BYhO5A8tTTGskX%AUVas-8am-aE^T*(EE%V#=>c2_bxxT z(1Cvay3M9?BOUC4JSmpr#*H)8d_<>DpVsl?Cw1!785g6!eEEt&^{m#cU7?cF0)t-* zjTtdWtqL=hl^m_|f-D1myo$3^R9Tdzio7hV1zOD)L6x4TAziv_>d=9jHF}8aF*~qJ zdkyQ=OI@nksa0;VauV$w%*awPkS!=sxz%b4av0^6^kimlYooT+jImRpvJwMmNrk=R zRaQRRsbjm2s%hI!o!WO$zh1pXk8n~jyLPNmkzJ4b$2|=VVOVS0F-$N-7!bp)W@O+` zNlLcsSDG_uX)sK1oki&+MSLFE`!q`$V+rG=rDrPMYD+*BKvT}Ub?v3?+jd)R_gRiMeb_}oX>s)A>Yq6eXWA)A}mP& zq5lI;hIT->^1|(#XY}clYx?BzH7#GUP}!M*sqNgX^1JtG@w}Pp)2&hyM)ua=K5f<0 z;M%QYp*pq6QAexRcd5=(m&#mwxOwW+p;QC9RH%2yQuXc9O2hiL*O;MQHEM8Y4eHfS z{km0YNU!$l-Kmv&b}Z9??v<{W+=%`)8aiAxoHldfskL;|W{j1ci zra#J+LKuPvsQsPq`*l|2S-8U3tUfp|D z?;O;#o{(+q#qCnl!Jbi#8|0~`x>~J^OV!G%rRDbWR}~ei#;WEFXqJ;0uYAV5Nl#OG zMzkjMDOT;e@p^n_wVs~epo1G`D=ns(qKV5BvT4~s5ziDo2K2M+bFE4;4L(d7QrA>= zeb`sicTH_)T#QS2^#vT2Bed1jm`AKM4;8Sf?~+7zQz zy@}7aXwdk1iY1>RRuAw44YQF3I#WM!<{V7@CdQ(2W6ZgH_#Eb_ch(8Nuua(I)t7*9 zASPeuRi^qw`4i5eVfJUvNVmk^c!lr}Gf@4&{%13%$!K71G2UezPXZPEJsEN}QXmEFrA1k|UccKBT^4o77WuBbE)_P{Y$l4AlII zWZ}#c~{Tv|es zGtP~%|B_(NFeNTd8A(abQsd*5&iGd5Fe9us7;f)Ntlg8O=tTD!-kD4jIz#&pRIWjs zjI~4)3N7tDqZ|_63AgVJY1zV*zNvouPC8rCh>aLVeUBPBPREX()WZi)-0;l|=j_Ms zXZ!Z8`)){R8ow#;fEf;;@Zp1>ey~MIxC1rfk0nYT*kfMF18a@}dKkg?!wrse4B%rh zhbVzRpYLM%!pbExv~=+lEu24D0|s_CH6LgMM2Q}>hdg%FFr~$Zsx&u6#aW5=P-B&s zVJ}&Ftec81J1IgLaiIo;7D|l{QM#>XB}O>QFc`C)7TeMaZ8IyhAxh=EXO@u=rks>0 z71*_kt@_`pAVnp4i7L&DS6+IA3NoXVpJCO-+yv#NhAQNv*Y*A@|D*gwm%Kzfu(P>BsSl!O?#*4JG85DR#{QyV9j}6 z(X)*KQ4HWS4h`^U7-5!l$l_jc9@qB{#bv^n0d{UYhPR~}g{LJp@8OT}(D2$kP##uF z0{Q#_sQYk@&#nRT!RnqR=lM=F?W(HPty4!U;2qVuT{{=HsVps5RdI=0Sv9pyNwGRs zv@*D-T49TGW8W~XTdOPseZLYN-8fdaYM1E#$(1_3W1&66W>zp7n5u8!I!1ZOv&}Lq zJxZ<1vJ6Vh?DU>N-~&_ibsg+Ke2=kh-gV&#R4afd%f^GA_4GJXD^#lu?8yeG)^q?e z$a$D^%sT`2`FwhoSaMXX3bS+7rd2Cd6c?MiO*JqWJPh=4QQ>N4z#%6d1JmS$sK;bPy+`a(ZgDn7fhBn6hFvh5QpHfMD-pB9R zW7@{^6r7FzHa8})_*tScQpJin&Hq!1{v^mREzG-IaZU# z4b}vE7()jSaT8ZhoibCWPoC4LVMCNmhlr#ogROxfEnxZS@hZ=;8=7h_m>o+qMa{gV z36ag+)O4wF5rJNFX30@4%xl|zTc*W^8Sq;=%ZQI~W1(jzM7sT0W^%Y)&(4WyuFS+R zQw3rjfNxRRGu+vXuF5a9@L2s{v89tU~*F2L>$C&Lo;&TsJ!z&ioJPbkNy5R-rF_19EpwIUis`7HZ99CJdqdp^8xA1S92=dT z7<(QiPx}L^9`(*P%Dv148K5UF&ptv|K6FEjp7=Z+s+P=OtRejet4aOF_O4g!+?k7R zh+^L{vZA83LH?A^o;`2MzPoz|c`p$p{re5JGSx|adiB)VGbgoe>qd7S~+`y#`N!^g;Pgr&$`7* zGfspysBh2FRQ5B_Cr8DYP>fQNK|a|4j}u{;Vl}mtD5k>tH1u~m-^+GcXa&dcFmtNR@JR@R8^6qysTKo z$276`*lIu~I*S=9IX6?;X>_`au^LvQ>x4+|ecQHyHaf~EAV;y2dP?|)&@N@zhgrCf ztfScdL?pr4cm6p0Sz_#m2f&%n0c`fe3O*YQde%Aa_i;Yvuf;mo!8rcHXAiFG$^Fav z?BNaFzjs-mK7FifS8nLy`71hp?4;JOT5S+9g=CfyAEk^$^LkcY%S}sAVMekF%^Nad zKuJ!z3T!(u$^dTX6lA5?u@rY6GaF%it{^kn)Owgkrm7nT^SAVFm25(pu@nb6#ky^BPxoWMN zbot_S_3YkP1N#kC|2~7&t4Dv08ZpjI#y!AZ-eIIP4j+boY&2& z$8^pjEQE7#=M!(VYcVte!@{EOQU5q490^XxuLFATVEi#05U?i;hfE8GDDK>$M*VvB zP_M35K)ZKQ$F@}l`c`UPRO}jK8IQg+JIke57NjP-tedjTM0Kmo(&9+|^U8`NL zJ*y{L0Uc?DDo`845~G?cKBAf8!We7DETW02p?I~cwwg?eRgXj7H+5;M+mwF8dT;CF z58lxSZ@;Av-g?{FN957J^Pa80W$W*{;b-X(MMwsSqv+GjVF7aAILne4J;%~fxTbV* z3VuKPIF@V>%!sqkh7rmcsrAvGraQa z2716w*aqmc{-S~Z7cc%qZ@>AP-g}E-4+0^Zci*g|K0Ug-csZcQarm&!5B~n|o~wAj z^o_KHX#ly;$_WnH-~jwF)PKW|>f3Kmcd8!1(*{AKGkpYrK5(buodN7n^Qe77KI|i} zp3n^$Hw=%ke$_fRv3T=F&FvlRrSoU5Y4YT0YHm(2(#lL}X_1S~qv%ndv@7u*`kH6I zz5}(~l>Vuc$4&XKcJmR>o-##)di7BEc5TH3-xG%RSN~2`8rrj+HY}R1U8@#o;pE{O zH=v8D`5~G!ZlK2Wvsz|#p{5S+tLP^6)Z~Nr9q4)1bc6%;aiJ|8%w0!5vuvwz#qm5S)vLw*L-}19kRsz7Om8 z^SGXO1TXyNiwFAV^9TCluRqsszWrQ(`O_cu%P)TEJU_tPx^bhc+9b!CM~yMHoe=#T z-hiI&^V7$U){$L1+{D0xdv!HsRiFhkC+on@joQ9prA7|wtqm&|YufmcTDN?mh7ahW z^(z)=Xulp>IBSabY+bLFi{`lNrdpLd(;l#UkfzRfz^V3dqnkHZLsN%u{q(1L%L?6V zFaAI;|Mc(m#*2Tay05&bkR~Box?-I!T)e6q*KTRVurXRVf4P<{UZn}+r)ut;MQ*;# z1@o6^`Lfk+xK?T`H?QB(`LmZ?M-sY+Gcm*Vt-BnQsTB+#I?A1U>B3dbnKj=*9dHA2 z;P1xkKYhXFC)2|gCqRg&yLovUgm-M)tzA3zYX9Ct+PnLJX3d!EuFH@H)Ib;#ffy;E zNA2^{5W}Y<6*U8D5Y!Y{r)C1=*@r{%VH-F8OHy^lTZ~WpH&p{t(T>YtD{P7R;>WlVX8R*}5`9%kQ6n=0gDq{IS z9fePO0LqpIXH-9GA18pK|H0q?!*fNCng`qf9GDZDL9t_Od&sk7pC3Yj^=SLgsCu9c z+)?a4lZb7fWyH1{62a6wpl49KI8(>Dnb|I_a^;d0E_6d@!ahBR==|y18aZ;Lnl`Ja zX3ZNZ&cqu-6O+Yq`t&*1ut*u1H+PW>I~+YyYb-dYD8LGBrWiCax zrd63H4jZ6R{p?+Z)X`8CK+^DCDCL)cAwC z?s+>iM@D!q-u_=kT&&7+0>f#i$C?9=igM2|**Ji@XCLQe7$dR_^jRq>4)Q2_6g`kH zv07_EcDjo5$U4e#bILB9H$j MaWGhxOSfmkj!k_2kh7J-l~T_wSt2gS)goCK0)(lOfauEO-mQe z(uyUEHGRr-H_F|q6X#4Bb~B~cL{X-wlOn>LS9Pg*Ihkr(TCAbHd+E&KLppopux^|? zqfIN8X~DE9x_a)UuAM)rC3B~1(d?rb3K0asnuXkxoTK%gE?UqjBO@KK4;Eg%ckv4VFPo*TWsSb?wV(R^x%m(#%m7t zfSyKMpuTUeiS)XWYjzj-@GV16dp9{fc$zwNWKvksQWy6 z!a~#t2pL5Z%d-bee4d8bK0SJ>Pq%JnU0iylSM=ppjmV{SwBTHM|V-5jwM#O8XG_xT0v{5r07OUpusJyu>*a4cvDl7VXACp zHHGY0#YBFrns)Zv$}-iY!8>a3;XC^9-8T*Pb@b7DZyWec(ZBna3+L4T-~&^xAGw~e zMVUFOEVTa`X$8p~whPxV6oRb-bU=^NN4*333b7{59SwTYAuAZ@e5>a*U7;!y*8BLO%Ic zD+2gF-Vf{p%Kp31O)%(*!xO^t;Tz0{YFOtSKT8$rzd_xPO_c_E$i@H{7n=_>OnSJZ z;(b_$kPX{3%F<}ts-)CSyuN(VGL0HK(m9O&eTM16nVT9osK1&t`$)~LTmyUZ=$9{F zsiQ}0UEG;>oh8E}oH6(xJ$yv7XU#B3S*^+5on!-Egw-zEl$2=Rlu4RCX1F?66ez>Q zz?5OVb!f{9H;&b|l`}QGSG5Lqu28Rb#j41)cQ~}Unwf)a#BdEEfkEs5eN;26Ery4h zz_a(#zJsAU2<0S(hgta#Q&JS68x+0OR?IR@1OofC1QR*WKu^e~AS+7@gOEcuSpfsO z71+IMp=OQVQ9*8;RxF*S&!1k`KmXw~gZ-x_Y`@TFPp;{UPjBeAzka0syEoXqwAw>_ zq+(4h#N%LSIJWyAfy1RC*Bt4H;bV09(skDW%V?lGw(oI5a-j)DoB;9pwI%{rtz734 zFbLnE-l;L+1c0yyGawGmxbg9MK#zGR;34nTd+_JkX5A}%j99-v=Y_lsQ+U~FDk3&z zR#H%)ZXLV3nP?6jIA&F!GNr_uf@;y+dDN`9z=LR&m#ZG_+iBIpMY@0es&;SOpzCMP zXy?ZDx_GiymrtM2u>QT&y{1|_Hm-IsKelhTn;_umz8!ja>x#CnTcIyMd7$G5_UiM8 z_q2HS3{&&OjZ^G_TcIZZJtF#9wJt)9Oa;F6vzPRyDf(A_W}yGa|4T3Z!~aL`y!?_{ zm@2Gn-$kd+T+lIlVUrT9>KjLHDsi#EPzDUnG;Zu6fl1M2HB`AKZUL zw{PBa-vjJ%DxZJ)mHUjFD$pLdZz1R5@{oW%`%wj`e!ed}G|Iso4%1csRA!0+pKmOodxAdTI@Zm>_Xx2jcX_=}hC{|8Vsw@12b7*))&HG`C zfw~LPm=TwE!yy2Bdp~H9U$^M(x_i_m|LlI)eI$HCBQ454kcC6K zWx#xV9+=lL)lT-22YoQ)F#yl`gnF@mO&)Y%8v+4lV? zh}q-xX|GwjV3DSbpX}oHLk5l1g|k=HvsZUh^bORcNfR-_cZxYi-wBZL4GoF_YvRPo z>e;im35tAsKSK>xAuj7Dk(5tU-zm1NEX+4`U!da5MCF;&@7bnUtL9A5(&?i#ad0;c z>E2r1D)Tg^Ul)xZ*u!8Qp=R~!8|Xi_XC3}b)tjPk(b7a@AS^>X9x+L>K%#wbLPY5E z7=1>JDf-x0SL08Mv;Uo7jy)~yxw6m8v>GLIBB#Zxyf{m3DvA}_{3F$Q?Vt4Vhc78T zrKQG?>8DNW7U`R>9_Y!#t9ttAn$DcqtFJ!0qhp6m%%vx)AS2Z|l307El4EK7w3-#Q zDSO`-B#pMW{re8P##mzY%%e*v=Z2MaGH$$ajC4!Nc2g6hq(2gx@jwRffZT_F*ymF# zJrCdm`(cC!J?p_>_uH612he*5@B*>MG*dq*iB>SI8kc0AvRkL_S~P!|4%i=|(I?+- zUVNw(D)X*@g6cn@AK1N{c5PU%&+p$eCBIy^FJ91=RV#G=>SY(oAwS*$$n>1E~ zci%BJZ-vi5|JqM}q?i8j@Ab+L|IrHL%cf2u)Vh5)9Y1wJyLRnSa&o2_BT$mFo+$<< z>(_U%4j(+`R5ePQp$~}D&ofUrxh#LI?qk*hwB1!pgwl=1PvZI%sCEf4b!L2(uDC-oTDJj^XTp; znmT!gdm#QH`iJJLe(d)#{}xv5j@FNZOW^oaXR9mJagEihdxg50f@}2gTL${~T%7*n zci&cn_uqBKI)k6F-uT1!7233^6(n<9R)9&9V>_f#BZW0-=F~i(2L`BmfKTHcOY*M? z;UpN;cu#m|k_|lkM?wnac{vJe-dM?TQEvF;mIk#3b?Z81kBa}rPXZmHfd5-26kdJN zwtxO(gS~;-*6X0)4fxn=fZmRgehKjD9{}jdyz!9tjkTz94{O#v=m9&hN38>P;`2Zs zCC@(21N1&y=b!%W@7?*nmn%JGlMFb7WdJ#$8iu>@uxFdH+^VG5IiU9D;0N^St!0ZA zYV62SPL+-yHQvpo+}UdB^&8e#<3^1Q1W|7At`(-}_wCtlP}-|)Teq8npQ}pSpJVS; zq?LOh-!i0```^)43oFgeQFvpk4di4Scq5h2vXQFtQq(#pUb9B^(XweHY}r?H#`M>C zgZ!wT9W-@FFSRMmQGIjtP3qRSXBn#4X3t=6WgG{cYPE(q`!3p$fPPF!bK7oVwKZT* zoE~Qo``oCt5u(d51Ms;fT(gn`2_t3snQGsYn4I5HzwPAagQ=6--AWj|I z=c{vv5_N1>qE78g)w64rIma@)jxjDP-8JTt&Pkdlshx4rR_@FIGq7H~WQAr}?HmT| z+kaU5P1yNd`dz#CYv0~OZbEfJzLaZ52&N5gjPZeOvTXo7wRnI}LoDlF(RfDU%)Kfjyw7 zvrS1>rp62!Xz<>lC%12D^GX1JMQax?)T0~M%mJ)(9dmkj?4Z+!4(R6jvkv~3PSol` z?NOcBzt@5P@vR%$zBT~-0j5L&JcSnEQ*bHBQO!ftqW;IKYgOkrtWedls`9Hp{-J*H zgMZZP2K+ay;IuHs*R{`Jois(iZrui@XXGd=t5DflG;S2T$-NgZTH(|;4vg>$ikMIg zF>k^lE}W8Ept9E0nmBEyj-5HDoA)2;(WhVN#@z=RF?NE&O-aTW>{BwbRo$k8x^?gE zRM1MRt{pj4>p;%_Z+R@B-yec zJwYoMPS)uo8};bcVcosDMH`k6(u}cf%{eqTz&BBDs#Vd;lI$Axf`@&i7+@dK&;j1V zo|M?)96;a56n&w()Rd}m{kPS$0V$OqsG%u&;Ep-a1O2-1nWBGBEgCmgq7@!sk9tCR zv#({NKw~Qg+<|(qvL}?oK7>GqfzFM!pO)@GpJlbecIBn!Xg)9i#Os4MUw2CW-8bHF z4YI7$84B3HYzF8F*$}5ky}$gkAKN?i^XKZm4!QQWzs@VD_n+yb_unz+8W@%!I7dGK z`~PVG+`}Dk1APyEjuF~H&9hD|fEa&p_=jGysBuCsz9ST&ob=>W*CvB<_XD^w22O4! z9jB61WI_zkuUfX$YFO2-7BF?vRGmL}*~&r}HEhsG1?D7%3?8CQ8#n3fnbRgpuDEgB zuU)yS^Y-o^J$O`$<}Fn39^KWtRf$SXz4IOE@kv&$J1IBGY8A$ZE>*1*7t+8@0G=7$ zOp^xL`&V7yY(Pz!1AWiRB26CDQzLqJQIq#SP}907`aokWjk3`O^dzfg1~_B2JYx<9 zbG{FHAE$>!wBr%3OQjZ<6dwS6N`k5UIF%RVsI!6l=G9~R^{=k#;e*54v3-_?4n~aR zsHia9YAa#N&j~lB-%OclG<2JwjR|*IH@WFF@@ClkNp?@Nl8sA|3@B&ik0cG+GicZI zWgLi8CQB+$YgbIwpLOA#yO%HO_`W^5eDb(+4upL^ zxp_nF%gbD$%_83T4D|6~be?Ih=Jh_(yH@C4|EVb}2l^lB6;n{Gll~TF1z^bNi8_Dj zniefys%*QFd3j|9%PcXLe9s>J9ApWf5JwMdX$sM9pwCffoyN}MvI-3vHAW{cSk2@5 zP3^Bep#w*c>)t0%)o<7cMJJ^wjHwn))wiwb>{R`=>$i3P!DBsm_(aERPrC<HJ}mquw1-sjfS;G6v{j+>vE z?Lf~sH^HEkdo>dCz$x^rct*01QNS(DnU zvZ#gC$eJi8rKu_k<4mzzO(42~RiguH9?&PnG*fDP3pay*>ymUU5Dl%sSRu`cb)g$N zP&IAvks8*0-zj(xdt&tsOwHG?`>w*8HFMQ&U>|3N2<06?j`OoX@w3L*pE;;Ih#TmC@l&fQ z{^SRG{TEhid=|>V>X;+I8F1bQ@4Ts;jC4070r7bcdq3{Y_d)N6LcoAJ+rgn4U>~gJ zeb|R(eFGwZ=NSWhjP;!KESF`)Gbj6oSbb>o=3;0BK%Z^3={`NWI?%ICEnw#K89H<7 ztlCw!ca8t+H*Zz#sna@p_M8qKI;45?=2_Vouer157~~J>(z)|GXUC7*v5jk1YV`0S ziVh7`SzduEOzkGLY$;|bD@aXLMs!OJ=v1ZZ{1lDtTjKyfWk`3o-nVV3dRLdKU%LwR zZrfV*-+D*QKC+sD2{>wPQO#S}^KS0)<^g)lvmAXwH-YW{sp@^KJ|H?x$=i}=P2((} z&!$6GYP`Mw<#vCHb#U(nef!N#efFvSmt$-6@P4g1v>iHhV40Q6(N^mjuGP!OXx^-m zcCSnfxon#VgFGQ2-s|{4-vr|l=KFKsnh2* zaL_O@RUv~%QnrCFY+!6F%DxA3FsOqe4&;G7#yLJ5D*)>0q6s#Noqq<%!P~9rc)OsSs_cX7l822(G#cjedmE5KlxnOZ`{$Cu@kK}k>@-&fG5|M z$sVZ25&vx4rsny>LAleJ%6oktq;EvQ+(Wk|zmcT}KEIvpA8I3su?Z?*Xz9u-13lfq zyQ)u@PU_UI+JU|}+p2}8a#2e->!>EAGlr;RMX~m8Tcz8V59qUpwYqt6oz^cOpqUc^ zeW;2vnp?HFnF=yOtvcLX=?PXCqnkL;(?KddF;saOF)A-iRj0N^%1B~V#Sg8D+dwUv zeV~@jK2k{IdTRRdho*o3N9l^QW*s1EMlqia?+ zPuCvN@9Ac(M4(*|RJC^I-jg$J-SGV-rU*FfKk1y)0 z&#&w0!;5-y|DryBd_&VGk21)IxxN^Ho^nMGTm*4!T%7W)7L;o5CGq)7m#?e#ktP!jf&yVaYi!Ffc!$kF=Xh%QC%2nWm0L#i^60S)q<}ir&ZQ zxw*vNJ6BaYMUPs)c)V7%d-pi#6O$i3u)i*zIHD)FZ)(n@3C;n0{mCO|Up;#0LOs*~ z9$vR9;<2MHYv=s2S`}Gsf)E3R6lG7f97XRzPi+2GQ(Uk8%nHymMgNu+!Z%)fU6J|Iy?R|2ZrpO}{_v?Y+Om7E`VJbZB2)f=e$Il$TC#kVmMvecBS%l@=B<00J8zLn z&1o!NwA`x1R(r8)62~KrlAG>(!ubcsKGZu8m50kdmOLa>zK_ZCn=$X0=s-oc_Cy08 zp&MehfWB9^F6!I0v&*_6bW@z2Wd*^$!(iw@-?Wh_*Fto;W{{$KI{Oa0Tx>rTqTeZ#gwjM=G*$06*J+9>_BeOOGyHT`V1V z19rd<#C}MYig3yhJJUQ}NX&K7R%yP!~Mkw|WbKod?U?1M1nY|00 zw0!Xbw~zG9IWy+z_|fy)z5SR8xpP{$V3}ICZW9Pure@glE3^AgT4$VUs@tl!)egsv z7^dR~_F1j(lvXWWWMwl|)pj1`Ki|}Cbzz}eWtorwj*UOmq#?bueA*Znn_oP6m_~GO zr;_AI)qUxQs`v8G6=T2gji0`x<{vk*=MrMIHG{f6+f-u@f-)yL(fGmy_JPJ&--!zL zcmwos$eRa!MnVAg^y2~ct%~ziQIe^UIt1>z|+K zFaP{R|Mu4}^p`(CRpC>Nn8U(8<=jV9dDw@R3GMovK&{Ml*33pPZ(+q*OJtS}HSM0p(zo z4hvYq1{mQ%j}Y`uz@O{S@!K5tik@Ts90&R+D?F|xIouRcT!I_)i_iwCf)mG2Qmz#o zz)sbP8_Z2b(RZn?($vwTTu27xe(vZI7kBU2x|QoKw{PnPr{qTs=%<nAgXXhVqjkm<-YxnMUA)ixLRisy>8%pP!AjNNn4Wya8GI(pMa^00TH=UiJy z#RGjH?_%?|q>ustx_Wo1>1b-6&QhISW9)O#XJrQ(EA4*r907ewWJ`@5+*4e^}yY^H<&J%A@ZPs$}>9Nrc7;k+;uJ++n`1ADgB3IPZ2Phylg(vTK<-xNJi2l8IY zlVa%_V_$p4ApbMf`Nd17~Ud^%qY4GYkSsnIRs4 zI~}R0S)%O8#0i9Qe&$Bj96or6Gr&(Ht2ZB}30CMR{Qd|C(h9oNSoqGJ}w6mv=&zi!&Y|6i<;-Z?l8bLf! z4imbu_Pz9sO|bVWmfB)YflEKVe(kop_vxo9tK}a(XWIt#t$X&Xpr}lR#bw&KZKtk1 zc&MctHwK~r=A>g2Q(PNgq=^_{pO&5-2>BTFy$bh$_FTXjzzxT3;;P-nc zz_~9Z+Ly*e1Cl5)np?*Xom}<_jW**)k5lKi)%I{x6>Zf*ZZhd>fF6&&aQZYox^Z16 z5A4^~)2DP`+g5d|Z0*7~M|SUUjk18Bo|t6mv@XbZgKCW#G(aon&2`y1)C36W?BBZ0 z9uyi2NC z@CfznGeB!LY*y{r^G?xEpSM6=diK%g?Ys1=-~3*meENmF(&Ix+C5KsoiU?Rnq;gUt z)TS&`Gbau;hr=LT4O~t=;)?V0 zthSJE&NagQCNgfwzIp5QS6!{6XV)$+-=7gh9q138SM9;`+PHk3O3g`+?%hGtNA_{k z{O#McOvm?Z(BYjMv~tc=O&B&%gL`z<)-@}1_sS(LG4+ZAEzQbNg4Gc6tOk~3!Xbrx z^N>br_TC$+Da}@8jw#Q2Z)sS!Dzz_2QFTs|+T^Bcc#n=M&rZ|3c7Ix!Q;N0E(h)ME zNfRePNS_4a0Nlskfjj$9_8#)I5u)VbN@XFbo#y!Le5^D#Q)PLXcAt_>(dUZclvgjG zr?o5QX<(lkH%?btq6v$1yNJIDf^(=eu<4rR3~9^&37?XRP*51fchT!78t8<3u6wC-fU<4m!rl zV04_-+G7$FX5yN;x{2S%CzuMia-3jG4{%@ZS;7Wj??KNw{+MF}OfWvMjY#D4{yH#( z2*L{twVP@MhRy(KR^@Hos!~%XPIuWO1A6z>hync-8)|T{>Mwcp#OTSR2lS})$G2{} zI6GN0TUW2r^0{+#q4t>DCewz8fn(rduq?6{l-j`B#fw~R;P}41E~K+^{sPz25ye1^ zl?F8wD4=iAu)gbbLt_~k5ikA33dfKB$@OTY!R);E+i(A%YnM%RpT4BkE7q&3qMgAsN$DxHoR_M) zx<``A6_ z0(*aqC7~%OQcM()nL~a(2FN|k{W?$&j_I=x zXF$9?(75|!S7TrRwq}hQI;f-28Q6>(1xu7XM(BpD7(Po)10%cy=o!O)_Vn30u=ltQ z?Kxp0ZKlEqP5Q+q9*G0lZrm(88$ zYDu)EMKo%num&a=%(<3kq^NyKu1eGG8Add9nKx1O-%-bsbdBoOPTeYUG^kUhM)m2e zjuj;?se&xJh^EBp8$54hC1)P6!x(^$QfG;x$2gDUENLU`*QK+IHqbktcO1~Sw^|BA zsuW}!%S!Xrtz#Q~_V||m`S)MwlLr^Iealky>($=MONPDEiRKWPdpFt~X0iz;6T7jY zijQKFb|!JLG7}wPWzfuE9~iek)(uZi1MKC?H`K0US7lfYC(78lWZimQxp!YX4j$H$ zHS4su_PA^7n_%}k$^eg&XBlZ_G0NU&%uibGfe*0Z0L}y^Q1(5r;Q^q>yfff9$6$yL z|9Ylyj_1e=Oox}1nQ7376w~fG&`+AKV@HmweO0xx>}E&W13?LL)A6!^9(6up*iaW^ z2ll{y#<;OAm;Teccbx6ty2ZgA^HnS!2!kOlm^RgA+}yo<$;~p;qg_W8q?(#1Y(qn= zy-d$|wci(wm#jV;p(C^!SL|NIniiyKJ zCfXkbh>Z4_ss4S3YV4?qS}=EsHm=*M6-(D>aTecmj_gJl~J%){X!`Kp>vu_Qk4hCLuO#S37nAlpD+R#dEB-MVW) zpS}kAZtC5wlWHm}OyOj^`<@zYFH?(_=CGS6(!iUS5~4-32k89C)p~OGgg$>#t5fHu zX#eqEnmM;jZQ4btb?Ycqlt$UL!>u5+w89hi4E7Zu2(_?$<5?puum|!i0X&WXz+=<`fIMUL zaEvj006nUm>i|{M{CjUPzWjR*$^e<3q|6Ex7`r|Ic(34rdvF$xU&k7KT+dw(*!z%B zURI{dlV?!1N~@_c?hMz**%Q!tmh+ z+Bdaf@l>7OzgZV+x9Zx-ow|E|pOwemZluW-^QLOug1K5aZHn$)xvU-QH>gXSwi;x$ z#;mvmg+bEjx@uNw7jSFG{4-jCjV zLoLb2H-|)q4d6yZ0%{=dhdS`aK0uF1VH>AVQxS+10Dc;8{g5eL+M2j2$x~5oy6Y9& zv2BGO-Mg%R{=?_`-M1#n&h6J%pWo7xN0)W|;xW4)tF>_MBpuwlMRTT4QdVk`B3m{$ zMQ^ppIC>x(R87@K8SDd-w8XlB&3s3xs2!xig0iXl+V9>MlQ@R3b1RyngctF|ruxH(G!w#?VfjUdy5eo;v`8W(X!e?G! zmYEhIp>7;zW@2L4-sw}P>&StFZs^yRjT$)6bE9eDrrHF!SyF8p)T6so@k4s`RDY`` z63$t_bcu_>^DuZYoJ)0#I2s)xNXgAcc5)nmr_|Js5-|BN)7h2as&Q=KGoLJ=Gor0L?%$zYmEl8ay*GGrA`S z;%7W8@2z=Y-b-UZo>}JsK9EPjGq@SOWr@$T9TgtsvM=Zn*|%peQ!72)7&rZTc6Feq zA(n6(W4n{t5CDCBQ$j7Ya?vndJhje&{?jK1b>{LI9Xr=sGv=16ZTm=7Rz|B;xvBc% zPy@ZeJ*TBP#Fom*YN7JdI8|4ssC(B!4H{5o>OVolvcx zu*PcI;6tb8gB3k0pYd)0Jt`h3qr!nT@CN+8t%l)<0X^~g1XJ#GutL3~?oskU9b-RB zK<~{DUko^bCfPBBM*NTl>~qjJ;CtndYG>&~J5I&F|GrcDKp!VS=!SfHu7iRH@F;yk zCM=1U)031iOY_E!^wVc59`h>xMT7gxFER{r0Pq|OOhi)OIU#=Q`&OI9$dL#36{co! zGNgCnOi=Q`9EXAddOpkl<^NIJU}mo|BgSgm<~`cDYMTah>!udlPdT#j}U>AOHGm{rA8BM*sCMzt(^L_1F6K*AMm8XLt4V(M=OACHC1|r|PL`(hwVC z?_abDkie9Ku`XUuCLKeg6qQt{IV#&6UqoV(MoyZn11C?3nEjEn=QL@~Tty}ruw$)E z6DE(d^8QT46S|=j6@bSHU~mQl)bPMF!9$-V#y$^tjANvAdItbg06j}M@&dz^GR;<4 z%W#8UsvB@?^Ty5Q>9(rGUZzk}CUK?`NOuDC0ac#jR6R=?PIxffc)tYXcw0O%4=NCI zqrt=qGY`Y6THm*d{9N}r8e?fVB%Vw+>rg8oAHG8`!k7LR(En5oK5nRrHXXHl-%%}E zxXjHI(=5bl1F;#3i%ECJdTg{oInr)W1k(sI$pAMY*8aOeH$2Yv5ehMA8`z_4JHdb- zXWOg;{}?7MFpG{NX2wi2v97Tj0P+KSc5|RFq)WIJ42BB8X#)DF<_+v#M{4t$ z3A%K8y&m5=u162I>G*~II(ojl#!b#qWt%XyY8|2SvIvzFw^UIQjiBPiu z@`P^qEdS{{r}n1(_m5qY#fG&zwPD3pt06_J$$NjVsr~b{c2b$vk1x@-8EtfIc|UDj zI8<$m&Ec9-u4z@FeVYxC$B%1xzy2}q@dmiuD{Yuc1 z`P22gUq8{m{OK$G_rHB>!2eeIuixrVzk8xT{`NEV?Apd0xRpIry_K1y7*oww&IsH1 zxn-G@gidGlc3-w^wc2&);zBY}@m3>EGY+<{QboHCs_NWDtvhy7q}5DYL|LsJ*e4p$ ztp-3$9?*wJSWW&J=u!4?fwnpyc7X}7zzaa{1b{i~K7oTM0OtUD&O>ft4Ri$Ytp?XC1Dj4*%bYt9n4|cx{3@iE_=-JQ1 z`tCD<@z8l#7*50I(4*!FH8ihZ&kCDWr(gcL13d=dfj!k>vKyKr4fF<5TQ+YRWwn|pyIIi&)=0a-q&(7NIOVyr z2mYvX4{KC?PIjT4AMVZ%20iA%&S!84UdhMWi-VKkf$$)iUB-K09tsbL2gSp|W3vzA z`OwLWyng`iQ!eAJN=WZW8e#`oL1Y|y!Zv-oc2c`mWh%%>bN4;TURoErv8r-x%f@P5 z6t5i{r|a^WO?q_enC{+Pql2e9>+so58ZyGFp_QR3FAr5|iK%%yPZcz?>ZDnAGjlBA z>eC}n!v|Mr#+2@wJF|~LK3z2(QZ#3FUv=-6t*nfurt*PzxRT>ST$-hCfc20k^M=q3 zdGn}u08Q8h*aK$_==(4XvrRFAC5^D0hn3_R@a#BB9;l<{~&w<=uz3}_Rce`1K;l)mX(87 z?DH@F=tu544B5=Qw-_T^0(rta#OQs@pPIpYZ@r-gAAMj@k8?)spYJAY!}p`=`G0_( zSUh1L!c_b($_E3gk^Qr9{!*=5y+x}RuXW?WH?R96EgI8CTc@_wrYV)$F}J-=t{I?p z^9QOlGg_rq9{YCcsx^xi>(+&f8qt4%S~hItL>QTH&CN+inqzBWjyuubDaN1g)4og- z2lr4ODYy|0)w@lhvzp>e#Wky^rtiO{_g;P3g<&v2&j_{fgt?0e@%mUi4Ya6uoPbyI zsCYO8HxQl}>x6_E{dPdl&g#^zwJM5o)SuPMz{#~opyzWAYeS5ak#TMvk4JeuIap+|G$h%TQK+k?TO@>2{;3B5{)ga1KD8rN8mO1mmFq_WW?zD?_&CqiKeQVd8+nVHT}|w4SI0% zm~Px$rhUiT8tgl&&wzN9m4~RTG}P2Q)1)4megXYcdqiK`7 zs7uFGwQrZGSu=ZS_^?Xl=7gBCPghC4J@ce6Q%H@UrBr^W=-FmWdQvP=ts4!Coy zW(UM+Ol3R66g(=jBsJ!(2l;fS?=!Uv=$Y+_kQAXDLPRvW0(|}_ zfX8{gLcf7mUbA;A%4K~moVQFJ+jP(eb*$F#(LZU)gm&6It&O%#snVV~9dy<}zjkgP zr9{+IngO@6pjd56N;P-#6m@Uk!8PcUc|&h?1YkvWrrH+fs=6Rk9ZIrY&)B?#P&Iq! z7fNpNk=hrgxCYtLy*s%<&62{J>y4lN#6cdw19}Xg18h`0s-8H#Um_BLe1JKD^h?hp z1S9J#nH!^j4-+`8OI2fPzE|gV>f5co_HJLJP3z}t_Ke}m$uy9*q@lc}iHJB82I*D{ zuy-vd(cV>4%?#}k-P~$oO%+4Rxj{X_;2v+am~i{Qv9Ymk44{4c4!Qx%Zr;47a~H2G zH6uskCr@*U8H|f{@!Cz*o;s_gE7!OLjvTv>X<4~WwFC6v7(I|@oh1OLyu$*FZ43^; z3)W!;=XmhL3HA{Q@M<5>vk#}?Ku_4Fc~b@~3b&h3pn?4d>g<_Q+O&3!d#HHU^k=}v zs4fBaKzuC0by8qpp$s#Q1uOt`ruy;^DAznLd9neu9~h;M2gE}J@J`K}69GzruI%Qu zS_X3H>%C(I>!kqb3EBMcAO3IG5bHqy>T3>+qsLBl-MM@9?yts;TPnuD9%=vw>Zo{@ zsmXaNFKwqm14e7xmi^kj^O%+|-K35kdf7FiovIHBF(Ag7f=tVEgQB%<*I5Gx46~a@ zOpF_z>>$ms#}g+^)Ant9T)2p_ZT!u}vl1_(XY9-wbKOXQ;~A^Is)K{SSN?e9X3av} zM9mnT*Fr*Cx^NBuiR*D4mH?h-grV$#ybI+dr8&?K8#q*BMvOGjcX6O6Y}2~1NJUKG zV9zNT&@-k;b5ry!>Z@~gwvO#zs!Jz#=;?#wx^i`)4xQ+&9s7H!b#*fbcS1Jhrs&HG zZM`7G3Id>SYz{731Ns+h(xe(KSkOS=RdGc+`c$FSLHbcD$UJv5G7m# zNI9Qu9U5|R6r2xSIR|HfW1!KN7(42mWpIdwC7~GBQSqpC8eJJPpYvD-t9lpKF+)w4 zmzC(ly6-#47U$)<-^Ac)49v#wY*kd`+7f7o_~4y7ZrJYOeY&a9dvB_N*-JnAF2xeS z(?N=L!YwqUGTZ`+o(WM1-6X|X&D)Hguf*v|rzHCZ(363K5wCykB?J7cFX`o%U)3wG zzpW@!lAE^dbd!m^YYyzypZ~qW8~sAdr*_g>Q}kOVx6%H2U3GHpFfE_dS#izZaXqMG zt%l1eqU5}HW%e>t`2D)}aIyLjdwyXJ>nT4eS_MgwRs)DpyZlt;#x`>?`3^;?nlzw` zhIg;jFml(&3{i*jLVftgYj)ibCELAo}1$gUJwO< zEtrq%Goo(SHr1*sDbzr_&jWgP)aQ?{=~rK0(e0ZDwPF1<6Gd%QQk0;?INAsrD950m zmm1~<=Zk3hu`=zyo2*?X_Ge&Zfvjya}qVe_`#=(}65b($Wcr239IeV`Js2AfFhY ziM<6!(AwOMj&nWeK7R%0JNm^1>%hzz3t(=_A6eWWQTFccftWmb8VUo# z3w1#Wb`A2JfS4sv`F#j_p2NBr%%5i?*a>>7d#=++b3$+qgP%8xihiNWxM7Ln$%*j_ zl1x!lptliEMLZvZ-o;8EGczO5)^G@yyHDfc?X%*7?mv>CO4h|!b2?(8D=T( z%?ChKeXtqAM9qf?>@(6muw-!@Hg9Gb=NXtYClo2k&I4Y|qYbldjh7GqBzy;=P+$QX40I1-Zal>_X)>7HCS(+Ft zb!E=(rr!OGA`P2Ct59u80WZli|{QKN0Arp4mu-mREBHATEEGrUFd z@-nxcz$fULeZx==75#`IgJhkhjo%Q%;v+z}fr|sPLF`q&JPiyR`vdG4@{s3_VWc6V z=HGqiA9(A{L3nqtKwF@2i0K!p>6zBUtL0i&rlmq=~t@pF+I-uyMs|>{z!RERJVuq=&>X`JKHS5$J4zZ7XJ@ zV8a4Y@X1&`I~}`L&&KxUGq7dZbj;6Af`$HARj+E4{Kg#ZZZbiP;=~E!U5taN-UMkA zVZ{M`4&tF$Tf#=XAS(lXSQ_Z5YMFMXqO`?pVMi{*%G`FeFcU*$1{e7a=o$D6XJR8l zR0xOFE4$jx27w(ZJSkZ0x%WBFWKiI8O}1j0Uqb1`^|A#l*8MQWhe;_uu?rYO(;Whh32 zKO2v0Q0F>d!}A#x;CqoJuMrvsdh(;mj_9yhRru(1RfSl?9K-|%B0ekxu_2Ba z_v7e1cS+#eCD5%y_30+m*S4Xlu^pQ??GR&Ut6pbg)WuH8b{KxZQQU;-bWXkS222X zO9gr(BNH``Cqd8e!{d`C8mbG&YeUd8osw#v*G#vxQZ-OGs}M)T&Yw9OvvQ^i?6WW> zH5o~fQMysFVq9Itb=N@8+4>jFNW}Tpqquds9#8I{L;t0NI8{9phl;Wh9L#)eb3}$% zh?=(+RcfQQLjsHu8f=Pb(*m$|Z5p<2or;}1rz0c74M|B3n3Cy<6-yJ8q7M%f0}<(@ zGH`soEaByDA%HT2tAmvqlCI0X(Z%cudqSIFXFQu=W+S*&78VV^?Duhz@9O2JlrmMk z7V6=-x^NF`llZ*~nea6<9)vwZI|Mc1PH+?O>|mur=YE2m5GUk$jO*OTa|wJd34fl? z<65kq{R@oE(<|XXHTE&l3uS17pl4N0hMero%oXTEeO<9@-6CvTJr5y1PIz7J<3IfF zKNR4#&RBNRa;ibyXj@JiE}vPHePn150(|8D67QJ`p0Ro^*&)j%!$!Kk2u_Ip9)=Bh z5AVD)L_j|ZwsQX*Id%e*GpAsre6P0!^!DbXa6Eqrig(Px$-H@JIJ^wkTMuH-`doP0 z8H!prg1xaV!hAxI7MlcDxi7uM6Wy?MCH8IGA?iFz48eE-zCJ=dZQ3P`Yme zHZICSMuZ1e&Pl`Sc^OzdEeX@pqA+RXV7wz<%#gqT4I|!p3nS(G4U?tO__6ZYO+-nWw$B$oL#n(?R;+qdI<4RWzJe*BoXFd@# zbJKD8YA>1u?pwBRL3>9VZr;9u?K^fNEnPgHv%MmSFCjT8M?_&T+`U3DZRR|5_x20m zFCaEC1!a||aP8JzY}m40f!@{AM=h=G#lw?E*qe)3qq;Y@uuQ}hHkS;BA(dBANA z+L|FC%r)3k>2p8VnVQM-$QMmCzQ!~?{YgeDXPhN*4<9ZPU>(A?jcZYScrOaX)!e;p z1M;`6NB;H=Si3@0V@?LL(&ClXON|H9QPaKB7v+h$M%GAR{UYS+TK5W~Z7wq^yo-YiNuy@4c%g zdFHfkuM6x|9zBbi$phgeR&wq7?KoC?LZvyfgVoGTnk*TziHS2A>0+bCSiN8}dOOQ-=V}u^eR4q*${zX7vjpBTqQdp$dYY;hCCWZV zR6Uo$0fqv46ET88*t982fqvVzsYpz;M{=?wW{Lq=xhxSYmnO?^D&9b(v%Hsx08dN! z`&h$QU=SAQrE--Ccvaa_9%d?fR;?toskRAb6_*!KCr3rU0(neGmq2GSe%=g9DJ2o&p~a*H%+;?5u4X+ z#>vtOF}l72e^a>zUO2dGH}-Gaf*ENEi1Zd?>tU;AlBzhg1NCM5uw%tcq=dL()!a-h znU;bOH*0yegD`V)3amu6n~fhY2GI}}CWaU@a+vxaxj9)P5P~pc`c!0RrNi6H4W=dr z@?46lw=@y)VwTy^S%&Sq zw&UcfN?gBr9jDGztC{LfS2g2&$5kBITP6yBv3T&yQC?YxZt?Eh&tE{YFr?(fNnF2u z4_kKZRyA%2d4_Nl;3>R>TgLJX6Yy5n_PTHmpKFRZX@opsPk3{`5`6-A9;3R~)I9gG z@f^1JxMUU9F*V_2F*?}4#uB{*31=$GnKBL4)wKeoBD6Kv;`a3(4D_GJ?Hhe~eE%w* zJiMlseHU8PvCF+}=sMSc_Lgci)SLhZ9ke!{Ld~fXwSKC+2-VC80A5fAIn@GL^pxM(q+rBci%zOH?*MjYzO)-UB%I3rK*>l@9pR)3e!6f zvu4e~p+o!CjZj`*u139bFqENzsrqr*8_sgYELY0LFb?OJT(xqYilH$C#5`9jcvcWK zH8odrQD$dPRR(~Ks@>R76q=E_f;;2%+{cMXRBEN%Fsx|EnkQ4zCo9O$pE*;2KSkBL zNsWm`gnuBs1Olu$XfN)!y|}`h@O#V3TwLlpf&156@a4z7Xl>e#($bmYtpo_1^;MXL zjew7h;NU3c(CZ^mV4s`ohxO|-6zI2XnS!`D8>FN-VeYIDc|fwUYFRQuf-J?5Iv_m6 zSzc!kKW`g(AmuwcPytU;p&O2jrLs2?&@=mnF?K?lU?!jm?Zk-4S0S0mz+mzEJX9V% zLp_ANrsBEI*An^~*i~F#j0WT64E+$!Y=k`_O_1~Na!HUg4$sbEu2b3b9D<$4X$aW3 zkD%9#1|iS*J3~WS?SE#bFb$Ep=DFz^3iRWK4pVa|EX>V7$={5FT8uL*tnP@b?xWBJUmO z6NKiv7W7}}Lyo}9T)cmK0SL zEXGe5jR_OQ^V1)%n!bTp<05gWEnIVi#^wrYQ$rdwb%s@qHsXQBj zYKAcf8zb0R$#t>QS03in>`3e_Sb;OA_TaR%-ixPkx^h2UolKFL5{czY=HSY;K3weW z!j4^A#k23mojZ4tpSM>PEt{4z7d_qAF>vJ}F7@8QrM|mz&NW=TbPW}!Y7h_{p-QFP zdGHupcjhUmvzQrS?;jkdK+pB)m;@EFVF-t*mKx}_m^*>ZB^jlKXV@qxxsR~dpwIJo z4uv9(gqE7EKu>@$-pdM(OXe?@2fh`>0{U}J)wtSw7Cq-!m%0fTIva3NmRI`P(I?A? zH~Vm{?;I|)*Qs;5+iKBuwniQ6Xg;m>U%%9W2Y33>E&JQgoIqn~5vq?L6rdO5dRHqR z^mpUK8~wP~cV2+sirYP%s$J`BmDYl*=bF)2QH&4|7uXsZz(7}O3&Tz8#kc%D& zSNXv`L`kO0LwUTo6rEy`3HR+g@=#abj6I^lZRLk$5h4did5vEP=FFLk8#k}w%P&92 zr=NbV=8vR$=S8Atz|zCq{`jNM@ZGmR;ma?+6?d;w#qNy+-aLmFhN)Uq^M>NJP~Cfb zGxVez8OweXgGt6P65~POYwDis1U(11xk+R7!s%ilX658y-ppy3CXmlcPJ9)*A?WSR zEMaG2BG54uSXv=(<2>|tmgBJ~o6kPDAclD}4j;_Lj9kXI4RoLnFcr5~9_nyg9q4@w z5a_Fq%*kF@vnEwRe&fbW#K+sJ@Xez6k=V9*D%P*gKxDWb!b0p366hc*iE(=QO?<3W z2bigWZj>xly;kImz$EAyYI)W9Dv+i^W{h5iZ^RJ#%C%w!4#7_K&m|24*9rW%hzONh zN!U}-Gy5hbE>684;jM*lv~UgKO^|Cq*E(zobQ%So!~I$(E>%Cb`Fbu@?R*OhRfUs( zi=d~XXVw@?Zs(+>t7|ZZ>iYFRVD;Q-3iO+o&64ltjKBSfVVnPaHA?nhLC=hv_ul@8 zQoac>%(7uhrH=q!TzG*xl`EG_t7MFxow3ZhXEqu`H^Ya?_nByn@Tho{o~XsC)6L>t zZpVmWVz@?+lKUhU%V&yrCJKDl`nf18+JwCAOGHiE!9Y(>jC2Uvn%Z%>=aSqHA!5W# zoZxCyWn zBgl!t-~Q|0RUgE55r12^Z^4pfi{+V`g-jOX%b9}3ix*<$%H^0ndnV@2ovn^7STGOE zmMsx6wg~eV%*KL+bFgUfJS=2Qp80bzV}{)O({iw3!#Xi&Rp{&O#p)HyU@V@At%V8f zt>kl?8^~{_r&1`L#Iv=v(vxRNAI^@(vd>7CX7F&aL3BhQ8k%Y_aP<<-cb~(gQsKSTg(Qz;pkD8$yhHN;O zh4o7n&r$TQZeFiCXZhUo`6ov-n6vTkvA^!Opw|Q;x5*NUOD&wkeVUr*@-;V6s?KsS zJ|+>Xm#xCNma{0_y9eE^^|*TBEV@LkpKGi_OI-z8>ML+TfPSgH0e3E)$IZS@^oU}= zc(xX8wH0U;72i=O%C+h^+UqNE^U^uozu7CVsYY$-L7Y8VjI&hxrH663y&kuE+VFUw z2Y35A#1NE;8aOVh;FzfRBXV9b&dcAdIGhK6XDd~og&jAlRP4KNzU-uW593CUMU>pc zRj2E*D}TROc}uZm1U=mv4+Z*->v!SurCUnb+gfvou((6=qdGh2CL3XxW!{_xsH6dD`al_VEog};fjM3}s8!AQ5uuV*Kyr_H!`3~ZC$ptqQ z1!ZbzuEIFnrcvgS%AVzk3HpqbRLq?|6Z1sH%n~)vI`oN=k*_*qJsrg2n_0kC9!`4! zMu?XK4(?orOC4nb`gVMHzZ2C}8?iTkDzef=N&A`z;H^X*TMIPpL=oGm?I0gxIc9{( zX&zXyED_tb=3>q2G;tMek)7#@1@l=?C{x-L#6&tEGRzUdes%~Dbr|TwSiLpeUBu%t z9gp#&hUz9H5!f3{7^g-dGUuF1oGP7QX2>Sg*G~akft_P4oOSA6i@#IFb4jpk>6ldT z$+5BO^@Kl_HrE+j*OWSA>;ySst%Yo~Mu@Z1R)aYqPvG-BX4G)W_ux5<{d4+5#^_a+ zkAHxQ(KC^Nqk37!f#I9cOy7L-b!=I&5XX0K#G3h2v2ww5QS$$Zzx?s{c;j`>G{wfL z2YHX{${rB(2UqN0(D?qQX8y=zR%wWn43Ep^QUwA$|Sj7?ywPM?dfEXWR9#C1Fkn_ z3?_+@96gu=AK#YiJrPFodrcBgE;=RxOP4OjmaSV*P>?SmT_hr6HA+f~as2o(963^i z!otI<6&D{DfLGw;$&)yJx(ZcQCuO}-JZgH?W!ST)K)uJAGa@uETtr=69b#gl;VJiy zi+mn?D+}>@jA1R%r&r`Cjh)-fnP+ozvVpe;N5YB$wK7FoMlw#ED8-SZh1e_aot>2p zR}SWs<|5bDS)M_on-9`b zGF2@atq9reTX%8(e7D?aWlGJTZRB|`n1^!=B#HE84-(&^lU6$vQl-_vX~j;_`INmy}7xSd`>IX5lh&6dHKNK zKM+1XeoE!@f)nrz-B8_A(erv~ae5Bqa2L>LXH3Sz*>kaA)+|h)l8KCDUB(U7WvI6g z-09w%nJdscm>3~8zzxUtu0wBoi7IIJ{+)BEEMJ3NJ2H`;;v&%GoSJs8T6mzffYM4p zW-dz$F)W^HuoMSMtyrFdq<9D9WP4-Y>`)cD*|s?sEQS^t!c4Y~S z&25HX2yqSYS|i*Ebe^Zdo$H#y*VI1$2E#&((bM>FupcvS*ohp@dhxR4xDcapV_~j8 z0VfU@;7m~giuZ28!QGqi`X7IXzy9Tqc;oM{;~#IZhW#6_26O51`*qE5(s&iNVIDoh zHB6~wCoBQabwZwv(5IpwBCmaK&|thbc({Px7#Ug9ai*>XO|9nzmbFSfzN4T!7Kx%> z=T1$=!rUaZ)*i*v53kC78w~@4Nvi+qT-$loIIEeNp(!i~c`Z&vPa@r))-(pS%dN;6i? zOo<^jJ}c}?V_z0C)VQPWA}UvuJu`Y< zHqM93iIJ{jfO0;r7Y(yNEFItAP^^G{TZx8y~TNK=zsK5pE z4Fc~vQR){(i9fh<0e3HU;KAi?Ji5|@fsSTeKi`V8Ri&strVGtnXgnpVzY~|wH;8hq zLqkO&>dOv^Qa_HWqI_KKsK?WLR}|z4d&2+p(LFeIWUp!+HD%~)J%ysYb#SxP7Z-4p zxWgvm_K%mFbByZ9n&wJnzb0YIdidV=RTY|Ri`RmwzZ#EMT!_tXF)P{u=e!yiaXY)`Ym?s*opa~HtL(3 z#Cte}W#SUfna4Wx^RZ{|UT{+2wQDx2&)ZgRnD&8Btp3MuR%Muzrvld}b;)vzl<*5D6h3C_lVKJh5Utx+T}~##xjcU53r;Q;-~ICvY`YV2=p0 zQA@3b`s>OTrzg5&(YzS!+BQ>^eKL{~osgB~sbcgyx8-8Tmgxu!u|{y9jp~REdI@^Q z>Vy0p1XfmZ{dCumpdsv?1W*Jtl{X>JkO-AL)jeTNpelv`66|c+J|5Q$0!PL&bVJ~4 zu;+S0RMac56VimY7NXGftLIHc!Istd`(J*K*Z=Y-y#3Zc1kCR!z-vtl-LNy3N;EDi z{AJk2R+T>>I@c-V9>im1oR^?$-o@5<}N|g+4E>7O0s`$5!4fO>w z77Bv;OpWAxuR)xTHCV)q35?`8_v^`bHxv(mVAt25gwgVQj2}N%?sGE{ItDP2_ng3i zX=BEzu_Y8bd@cxm!k^o040RIbnmE!LpC6vj*J?&WGZ^L!uh}wN#ZrA%Hm(!y8sz!8 zxm1-ZUp7LW=W^ZM%?06MA@bbX%5%w1VN(TjS5fv3V#o=3uG0vp8T$nMG)DZqChUK6 z6_34I1c;TH4Wh%Muvy^NbovYm^LB|EKaY!Tb*QgAhUU|yvcD89)#bR^ z*MUa^7xBSBFYfks;PKUqxO%P$H@n+a%>8`rNi>!pRiT&*qU5i3H{n9-X|z|%>rWm< zcS9w*>MPJ$TaNqv9r)_;4LrOeib0Ok2-KDw5`$2v)O}}dDe^Wff`<)fqZu#C$Q)kI zwy-jm8%7ikA3$4ijaIGRAd0&c5s`6nGtk023oIG8@)k?!h4{EM?A%d+TQ~3H(@(y{ z^=o(0+S-Nlas!|5x`@J}qnMnTjmW52xgZ|$5O~QA9;e(#cEZe^J4XQQim>od95}Qe z=es*`^VR_RE?q!NOB0%!nsNBhQB``FgDKcCd-u*mw6&d64+x>pj@Y9|N(GAPa)Dfw z^=9WQZ&=>Qyiuu4cw?}GmY`=Iy`jFzD@D&GA+KfQa4u2i(X%`;6+Js*v(l20kr=Py z^8^jk{RnzHc|h&uL2)!QLP~@WP95JV#=IO)?w(hfH$?{*VC~8{#6?;QG|d#$Rr9k} z?YE#$OK_9F6@}f~=V0a1RHUZ3$xY^lSkf&i_-vB)kDtd--IM|OJu>?J1 z^9kV*hz$valR(ix;I?M|3^lc0W^52Ee;Nm|@AhG*#ho?YgCM51Jz}Ayt*+ZEZQHz+z%#3R5FvU2Pq?uUy1~ zF*GoMyLewFvfn^YA0cu*97WX=iY5YfWA?8J+zEU`&MhI(r;0Za@Duu$gsfa|_EQn& z>fV0|Y_3zyQ~Xf1^V!hWso41pF`0qqaX-)HYx!L9y;zsVS{gyDftwJvG#A*vRN(v$ zT$+m*()Mwk@aOsb9$b33GpxeUuy`|a4jW6nb1qo|-dV0amwayv@u2yc`1j3aX(!Kh zVp59mMVI5wNrV_xU=j?=ns8n1dkK0Kx_PPSRerrJwOBl_10l}FeOiYrflfuw#&vea zk|BiuYj%tg$(uxmMBw0_1E@JsA#Qy>9t>Q<(?>TI*spdrs~9|$eXGF!az_(Bym?uv z`L7<`#uN5VH&x^Qr7qmM(2oAIbt?WoaK2Gq--fR~yp8^IwP-tCjQ+M7eEwhn1Dy@H z(cP@VH+Op5aQos})w&x_3gnL{@Hdnn#Kxu5;bJiXZq|nK5LqDHU)&!%3z$qCs~#>| z)2-Wfp{~9Kp`p=ok>y7c$lKV6)pK-~o52D8{=S$#V+u-25998=0X%$k2aSzQIC$^? zmM&R@_}B=stSkUzCYI4ies}>}us2Fspy_nEJW!0ESs*ab3#n;|C^~Ww9UZN>a#hs+ znNy052O+qz(cudHBp(qn`7}>MB~A8t5w}&-gpxNtI4T&yWtA7MdZ@d5lV)fY-bL z9_M~mT-CxlTqo$M@Tv3(Y{HqK)|MK;34KlNb3Z#?xsRader*sH4S=@J*HOvyy%*1& zt3C%o?_n<+%qp-eW=+M?oK#GX5l=HE8bjZE6R-dE4|wP8H!ySv z%f{I4FJ`< z26`<-Lp9IP4fipA|J(XEJfE@q*EVn5g4xq&AvPjL9`=2xDmjjmM+@=(t$utYQ2gxi zEj+k(QElJoJ%^5lDs(m1;Fc)<4{lz;XAf@R+Yjywz#DM0ryY0uI&rn55l^o7;_D}O zQR?p9bt>H*` z3g~?W^s&J{@OH9+v8X|&w7H2jWv6N7$!b-$z=E}E?A#C>9F3%;RF&tRm6e4B3uj@? z+6Bnly&n0yHe=P|*_bso1yj;E|78f$X}x_sRUW}V9lEK3h-hAZnNW-H#gNvP*8}vdDYD-4;4YLsd+7?N62fT8^-84DfpCh`MdHx zvr?0hlb)skqk-N@ZagakLj`&_8&fQqk&NCp@y>c{@X3Q-T#zNx(9Y_orX>8v&A?X zAuNa;vDOOoD(lA6THezh{sMhlOFc{+I}{T}4_B}!YzTCQKL~rmno6E=da8S>cdBwt z@$=YkJ7IY~&*hTuL8HL)34850;mk%*GmoACX9$Pz=2AOOfYV!KWlb6ff}cuXGZbt* zkNf#L8l<#@1Qjas7SJ=DFU8@lt1&M-5qq|+#h|zU zrWF0#oTrv03*P*@3cWC7Lp9Hw_&5Ld7u9LV&R8!IBn+7_(?%<7M&NU)!Jo14ciwsj zZ@u-N8Z2e!=z;x*j-#f&6^D73lubw$*vsdqM`dkh2nS0;IN6wp$G}nA?pVBN zg@Sy?xo%adk!gh%X5vwbT4uHnRXwY9+KEyo3JR4O! zRXrP3J%LX}Z*Fcb_dny|p6cEwyaNM+71-H0)`ZW;tGKtU^E?V8u4`(az~^xSo=Y|d zF%&`aED*+oITgGg$2$m&33aM(4eUIJjmHRbf}c%Wci?ksP2(WHwYPX!^88r~(Aj*v z_?|QhcJjV_58GFtjn6ligg8U8gf&ApRPwAwOW;$jYoKS0o`9zZK-d%XggN1@b;7Ff zuWV~^cpm5b@;E`SW$8pm#pAX5+6J5~KZ)7XW})QhF_auWh}sh+3hW=>zlPiW=kZXW z{ndx}@XI%!;KMuDaILo!Ph|P+$4~I%=TGqc(?|IH(Jj1xy$_$7;QmoHzkK^3XFSlIf66PF^Z(i+sfHkJ}U)l=VxHc(#cpiKOSoqL}Bg1NUUENg^i11uyt7y^4H~J-`2&b zKUs*jE+p+hJvJc6R4?J6 z$yUx6MbGM$87axgPD@jvo7@cDV5#4Np2NrO@T0e0m+F@ z*tBtqKp_Kuo`&Kba6Va1jAEn0HX7&yeK>6282S@NsO%dZ>_@-KxFN6!ac*;+ot<22 z6)6dEs%OGm1HGp9`8uA<<66v~>)cOu&X~Jaq>LbE<9>pjDxQtt=aOol$FwjGxA}T* zb3Yqj&&(3`DR5~gz+k8>I!ITiCo?hWWic>I=#LnNEz9PkyY>VQ?_7t+H!sQWV4+GC zP|d$L=q&*~3!VJ~L*9K$0iGE*Txa-3ORePKD0aGPVCOdL?r0$#e%3+nh<7q{lo~8$ zZsR0?FA+uG2EV{Cc@9ccDj*XLHi$PmeM**ig|Vtl$w~`KY+IG6Vv3s(M16jjEnYf}X0L z_r3;3!rskI2Y3RV5a%)WYZ2s3USQ$^_i>x&&=7E&N?P**Xh70ZQWd~8s0JKkMF^yw$1ZZxJQ`4#`oqi za)rkg=u1jURE#+e)v+gUw`@e){4AeD(1?rRtx3{UM(H@Cly( z{26|d_3xhE#}}gR3Hpz3^s4rO-1Hyb?#GiGJ$QQOlC(Yr`bE={;bt)bzV-$P^RibJ z@;vR#L;;QywKEY>QE@0gd0N$l<{&6XCl689$tW#8iRPvj6dx}_@v%c_X*!99+9PPH zK8n)An{jOCG8|Yx9Y?lE+nS4m8z$q>rpdA|1$);dA#YU*4sV}{l7i(pS91i-r;eaZ zAYWOsA7#h)qP%!N=FgrYpbo^Ul}nJHw-b8`#0caUV9)M-I8bm1hvWg-$4OX@7o)AY z1&<#+!pEOHMMG1A$_ij%w7A%0akczjUNpHe#47V*F}7yF_`EE6VX3A%urTaC0)3Yd8QJLFK*{V@JHF zrimOsa)b)S*~~Nh^XL5VQ;CID4@)xL! zTh6QyTh_bL#p$W;34B(u)Ut4fygNvY#t;l2ISxZdjEAL-GfGdKlKZX=h9=hV^a;kn z!V=0$y5 zS}1TcWW(mt~fnS65eo zy?{=xI{~gKVlAvmAw;F0l9HzOQQZ^v?woW;_A^dTu<{r~JifmEYQF-mfS3T*l(#eM z#0#jk#`<4;zSwx2(B?VXYpCM6O~@1MNvuxk7pRU01q7@2;BhK^p3i;_f8PN0zBCT( zfMw#=HGBgNO=Y%!6Kx0czXc;vc&{e4CrK)G+Huv+j^b%MY z@wKH(m*b46&Bpo$)QAG+3{kzU_4xGR4Sf3OCVu_yDZc#R9zJ{j4xWGeDSrLsTm1Us zXT11D+Rs1W*-zgHz`wz-&%cLQ0o9)W_!XZ2^rbAn6sU{h|3Z|%7>Q@kKF2RVab}mN zz|T+d-KY2Q(cOOh^5y$@ChgNl19&8$r^^3Q)-N{1#@tE|6EiS%*2U;*(fcTixc~oqv=FGZeFNIw-}1k z0{N1nJd_ph6XUT5=_%20bQHxK28M`h7$8vg6h-2On5bxMTE7Zy z?G1SNNIaUy_po5WLb(X6av3a^+(%s)JGntv8bPIAO5?yPf}Y2;{Cp~Tsw$-@Ts+jM zSZ3W!%gPirmWruqDXPj~Vt9lq2&QIe5=HD{X{K6`t3CFLhtk)60uKh7@$_LIx>}DR zZ^snOo#`hk+)_YqqtrY>ALwlje*v|hySV~A!#Hu_E(-JoI~HJib_k+EY(!C8A}z^F zyn=Lj4|{mHh>{aez(-!^EsYf{S?`9;+rvs!sC+m5aRRZo6xc=%)=lB}w?F<-)oUkg zsgkucOM;$hm)eL~EwkodJ7zPIlGJgAQ?!r`x0zx|70Qr}rqBs*HVyU!IM>+-a&Bwt zo!gAZYlc7z`4IH{oIHm{z;xmyH4>Jd6jLj;8PoJeizhJX9qeAa47a;maD2~ZJiO7T zLM8+~Lo@{XU|AnMbg-_D3uE-G1tX10KG4@ojHakLYw_sJ1RmaA3iJd%X_vKDwaf8vV0B7PgJ40x&gIyji|1zSK~%bo~psN zo%x88XKRv(4NIo_$-T#t8;+uQZA5u9bVQI7?p!h}#m&_j6UL8~`&F04Ldf$t4FXj@ zJ2eS?ZWHoU^K4Z4L4p1-FfdR97X!pNQ-u@sR#v(&4S~%iLC*0ejNKFN^nl~y5>&{O z#(?{{B=o7IwbxPUbIHcp^ayY+`JK3~!I^L;*a>JFHa0$Mgf!37wt0@$c&@vvhk7qA zsqkqG_@3NH(EItYEV`fC$FVz9^7PJa1>mesK+vC=Rt$%-5z)nTGPxO0+h%ps~76K)(^UE_UkT^P=K^6lMN{v~Q)o5P<*s z;zzvr^=JJ0>vMtoGd%z0M?8Q2qil1ZY|HwyUuXcn6Ql4We*X3g{P2ya{GY$ZFVDZl zi|1dqF5gwLE z4fjQElDJ3Kq8!GL5oK$JnD|swH?&~+%Jp)gd=V3yg0k{cs5#S!DU-9Xe$`U+ceml; z&0bvZYr=!8?YMNd9B0e6pelbJPUX)=&Hj0)JvbkAhZdk(V1N4HLR1&6!0DoOa&8&k zztM%u=bO-8SB{2L$52sv02O72kPs6r7fes!%bFefFfo`2y@?Yre%yE%>Kn;1OO%%!9eK0jA1*K(0xO}A-hYl603&c_gy889B&g@vxfu0wOu{>iVc5?lfTc*Y58Mg8B z^abaNospBPI%0FPGB9oOWEC!m4-Hd_l91v2yPT%YRa8}|ry~ySTA@Jy=z1$Yeb9rJ z+WpwMH48Iy<)MkR6?j_fAn#-SFQ7M7VVr0IdCue@Y~MH&Q#05(YJ$)J3*=4>$D#$P zFViZ`RmKgc6J&?1t^|Ua0=ef9)K` z;kEtr0J!AmV0s~6$9^LAA@CTR-Y6aHX<(UkLuJoA`VsHEjZyEsg(JJSV4%GYWe0ZP z@vVLsOczcav_huYkl%&1f3j$Bpzo&X<2#1}pRP(yQ zQf9hZIYWkG_=vF>JZy}DdX+p6g#DQD`j|*h(cDgT(wcKhOM5ri$$e-o_o0n6D{Cj1 zn2Mk(O~rGY z=MwycwWj0=X~LZ#|1IpP)MKJzv48J@SJ2ju@wF?KtrTVMDbGIBoh?-3F)lTAPeVe; zD+Bq`IM~Z`OEu3vH^%5)9mGo&vF9mbFDxWdfnB9r3eYuGuVaHQ%Z82N9ST1#wKzSS z#tFWT27vvAs{c=3^IB4T8jcl};C$P8)K;BR^F!Vr=*5Qu`tQH_2;Y4rp#Sz`{Pe?T z0&ao#i=PDaKjAsS4uQP@A9(SqDFYzw#fx7=-9N*xKgsz&eJ>t>7z25&)?SD~c=7Xh zc=r95c=qk*D&#|t;k&1gaI3csm)g&u>0}{71rP*%xVwNp!WUEG!_?%~CI)&ilba$v zYX)kY&SLi5#bUjDuz0bk@W!*)C5j|6EEN0lw&C{GZhX#pA@B9#gIhhg(oun)nq8hb8>d0gpg#JTzt=sJ5E^{0=c z{!}r-M8TU)VyV^9Fd8=!7W(56z*PCnTy`B&?c9;CKjVSiY4r_k_vkI#RGof&SsO7V)UMPA9V$Q4>OwScn;zPKb!_C=9 z;BKNC0q^FlTl#uh!^_PYc9zB%IYg&o2fwW={mb^&>#yTazx$nPfBDbu0Ab6+0nKfHRCka1-imT&Drx`)lDFHlC|B zo<}85BSGNP+u+DvLSIw#guGU{QU`kZyQ1ie3wEf`O|6K9N22IQ4Sg5mMh;W;SeR=+ zdhj5O86w7oTM2S*Pn_AY)&?E%?NwO@BL`lgMwcHn=yLAoM2~T`H(eh)?w<@Ts82J=lmAa14RXcsoNc%_4wHj+ZK^6Vx;a97`~F_B>Rdu2K7G2nci<01fI~ zY90gMljpF71cl4rXF8`Ydydbu8Zadu6O%2pFb;vOV}g8Mfw`vgX#m)?I6WJMA&>EV z?Hn2c#^!k*`SDs*cpUO~?L+su3pjnE5`_i3@$h;dzWDS3e*Q_6__HtY%P(Kz=VxDv zTK^tUfd5&LP6hvqv|m;G*MDl?F9Q2#&vfni&#L{(CPv`b=W^`17zsJ&*Pnj`#2EZ4 z9>a_8Kf{xoeYnzDi`ugN2yihI&>JJn%>wCB0V+msp+82=;KR{$oLQ=_xgBYfr@+rQ z6gzkB!r8NDF-zbV84-fA;)AN*&Ib>!;_;nc3<$7qU8u&n$}OnOpMjJ4(@}F^F6xUG zE7&&_Ekxt-<)|-SgR=s_4{o$6FW^ddy_y}rtMwG>tB#?*;wS>0?O-h~x0N*Wv7=!p zu6fFrAo`Uqa_FXC& zti$z=Mx3v&P$fnNzx{VLl9h^n(kSsV-g_4##UOB;NciLY&0BQyjA{uaoH)1onWL?Jx9yx3uFvO>9(HXQG~f zT?~MQk=%oNA~Ys&4goz;@d9n}A{c|GDraa$4S;$Ha}DfN>stOi&!LJZ*#Hr@lA|s<;#qb%6XIN+D%GKah ze;Vj{oX52D2w%dTpeM|=unfV>&`VfIxCoXR$jr#XvL(xLrT;1p9XO0Y{~)9!r7EMq z_t>>#H;#y4o}m{FSv`%-@YCx3A)R zhEjh0Mu09V{@3pmPekcl>uyBVQP#OJ70{a?%F7nn389D&^nj%(XQp*IIyhq0x^1X#I)}*U zBmsMZDCHtFG&CR~J|3xwaX4Lh1n=LwjHmD4!UqEUfzBrMHkAm>*Wkpi>C!}D@127) z`{oMp=cDG}e6*H{nlE09^ELbN&HI<}@!dY$x_nNl`p)JmG@Lq)Q^ya&(@Fq5b~wz( zjS<*Sgp*kHgg`$OY+Qkc$|6)AE5NR8OXa~Cr{Zu<;v&aJM#{}`4Am@sEH0a=s42o- zg=Odl3d9L|hHNy@Yq5GZHImuV9&V1V@{oJU`$b{d!iCc2Vd0#aO3|l8$0AxFL(sD` zmVKls2>4+YJxi!&P!4iD_xy*KzDJJhu(IgEDhAUoi*3x;T8{#^LSdAOb|6Y zSRns56}ox*Z+}ybK;@FKC)EG=@Bgl#u7z6u`upGG_y7BU;}8G#Z?BGVo%`q!uwzvV zsc34SVI78X7<%D*&@gCVr$XnF@Yb3ZtLM6=>b3m@y=Dk#F!*=aA~n7yapqfwlSm{Xt zyeUSH)5C;`0&Tgk2zxHg==KX#sPqYXD+3W06HVlIVgWFF1$uS@Q;8Gcgf}5h^{#cM zQsHZWXCv?#ucskk)0H8RdnPJE84H4*uOsZ8#RyQ*Q?;{Si)x-qo^aiIav`V__$sdt5Ws1Z{ES4{JpBPm4<=mGX%71#cE{~w2oIc9_KNgQr8(1P2n>vL$IsoU4C3LMufGb& zUp&W)=W-rHI4|1^QSv&-zmRnZ_<1hR`$=FgM&*Yu@o1n2H!n7$?BF&9dVdE~BnG)+ zdTKNxedI?prOP-Ge)2GF+qEAR)y)VFjYeupHqM-`MR9SlTQ}8!Y87 zH+W)992U==C!n8;CG+NB)|9D8j*1cG9-!+8bQVv-Ms7G!l}_?tX2b=fp=v++1@s@? z?Z$&^O*ph?K6Y-+L{gkBV!~_%-gf^Ix)I2WLictvmL*dxtpuPZa*nAedkfVOn-cGV zDcPa$6k}j-Gf9ACq?T6ZV_|PSK|$WabPQ}QC%{IUx$#&S>x~xB4^i1Ay08r=^kAL% zx0JGHBkVPpQ}Hv0oob%@HDkb-zNYqR1T;^8@qL0>3-K_NLlv$W3<92T)<92y^EiR7 z?IXp|;qPxeega0k^$(mln2$@%r*SlI z6Y46C7w3 zbK)dpm~+sfku{7b3A{yY*f7?tZzu+4g22&503;9>P$wqDVZ4YO4c=VR08rUe!E2$K zv13Llp!@T4iuV&49)T$$NUR0aEE~W9MxpXtM2ZOV6=TeE2zrKV7{&<-3Y6zLT$H@O z>a1l+aeFbIPU0=ui%MrL87+iExHFbdsE3Azt85!>o6sld30(r2ad>u+>M~(ily4E5 znp)6*`6>pk-$Zv$FD}XYrOQ{)+tY{6bLWveWtw=WOp35ZLR^xXmxA@JQd2XrXwh=a zoH198qshw36_p={#KaUNC#SFHCDmN7*>XRv}hWBQ>%;qdmPLGwp&aJXuIenAKgiA1ctU$7kK*c`^=wW&vG960Kh z#(}E-wW!DhEL^w(?PohtT2zGN2ln9Uqg(jy^Y;bJ0{UNn6bSz;qWou3^}ne0>kC4h z@p!Ef*8lHDsB4X(n*VA#(Es|2oJZg@o-c|XKYs@Z=s&%GO@aPs!3G4nn#1486loFO zn4J-exIj_XLc?uuh>A~HB z1{@S)$IjS!{^1Ev&M3g9P=9HkUJ!#9l2^S5Vn5>IOEkfE3~YzXq! zEytY;tvH&`qGnt0#_N9)!)*dvxi*A4!!?Z45B|sBG4eg##3KytaIh2=JweanVUD&| zD%Fyq8%|PAwe2Q=94erHQ@o?0!$-r))>*~mL&9Uw+1-yFyZ6D|$`RJ0{w5iUS~n7S zn~1VEHh_VlF+AmdvM{p|L&A(GGr4XSVvLPpFhL)t26CSY9KGD!5h%c=3ZFB3rc&-+ zp6-}BB};&njFjX=rPQg|eSN&-nG`U(I*Vx0Lu_=68o0y(N?N#tikGT7T%hdDGQMIo zwfH=jY++$xNK0cHr9Gmeq7>{o;+>tfS~iUad4inV4DV3cr>3T>{T?1(Do)R1{JU%n zrSNl5rN_r6pr*DSeFFoydg~U>o!(iWS0_YFxT5m4Lsa^m8#F4JQaKQ9K^Zv7jW^?6?Al8R4L_WY8%kib4g8f za#oBG>veH#1PzZC_MxKZ@-^mhFJ8P#xhO~X9YEQkgKBUT74Wamz6MmM>5q8+On@w4 zX8W(cSFX#7TK>Nq!!m4q%`3R8eGJ+Bw#j}mBrksW7B9a45??&Ng=^;pKs#3HK<{iK z0QJSZj07YE$_29&l{;yIShg_iKX4o+mDPxeOTn_GYZd61E?p|tF%rub&&J(bm+;94 z90Twbo=dya--lbBHE21u9!*87(O$A%wd#F~aC*-|QTB6DSF{2hr+4Fa&uRSn^GEXe zKF1dy-^TU67IZh9Ku1FvP9NV3D*?UUnD;Po*dR0}63JIQQIkflI=;&4nHHAGb+9WFqlnkSHTkbOsB ztb;s3N@f3_|LcD#l}?Bg=mb5%ti|iKrU9QoC+yj@*AUoT=lf~L7~`iZXNn{}0=|d# z{ye6=Rx>95YDD;6gulwh88uops&~fd8L}bdHP8>0XYr>v`^6NZUFQxk#@8jAOZ zjuy~QLbP~}=Pz8whRr)wM=YDMsA5A?fw-xGfLQ{XP75E zG)%+}Qxus!W~o9bRML!bGmcI8Qf(93jL}os6ZFib_xAQyaQF1|L||YbQc_Yxv4^UT zPNrNE_yjqXI~6=TY#F{G@Tu%M%9iIaMo+-AX|N}_moHm^{()->^!W!4ASN{hfl-mL za&&;V{Jov~_u=x58))x1kJz{b`1%E?(krb3*Y z`z~L{<0qf0%C@Y7b-Dk#3Zpf)ccXXUHZID!-TgOlwyPh_9ldJ3ci=8ME?z}a%48Li zVOVF!t^!=UeGk{~+{eX%>u9@hQMHSg2XOhiyhq<YLQ`U=>FX;hRq$inx9%O8f`m_)mEDOqM@C)3s-!z7@y`c*b6yy=+|n z=ca=?;r?7;uZ3+GrqQ6!@C^-!ocoN~Io}D4zrdGIZs1BsHTG^x zVf@&MO3^3ABq&8+QE^f!5*9Pl6bNID97sjbv;GZZ_RNK)qGtt5s(FH*@kORqMudc_ z9Qvj6=VST&xmYxFmYStMO%#2|%hXC0n*oMXsJ4c>pk@f^fxb8qhRM$ ztXq|c#ApXqmYA>)57bq#4DuGxzl_ln^d3$|3iQr46A>9?k2%w#ks9v~PiH;2I!uC# z9MgqtMk~;VhcLuMl{i8gL9c6*#tp@Uk%JZJM~Z6IQY*RCt-qlls;O(jRs%R;OAvFN z@YMj#I6coHfVt#;4a{6>MnLllw8r;gNa(jP|JSDd{oj5j?enTq3S-1m(HFxkkf)+& zF*B-qPX|ZkQBmzr7(5u8mn^_Qdjk&d+<+DHXNWQTivl-0W0`$3^sRrW_`LoY_8D;U zk#`W}=dDsJElrJ-s<*ecP|BX69G$9nds)rWQ7QVj#8AHbvd+!OF?vW&n&vrbXl4XMVZsUK)bXBG^XfdN4(j1$As77-CDKb@dvyq$)FfTxP5vEa;eRP!_hVPO#p z_T10WueKtnw48Xpw(`VD^!8sy#hEjhw|p6_oW;nvyCEPl0w&@ud54Ce^+LCT{mfZ& zz-p8%IUFOxjnf9wYhs7@<$*gWJX(&dsk0Cfoq*C4XYlC#Pr$jQ1N?%qWbsN&pDmuZ zEZ2zP?GW|e*?SFJb{|06lv&ucbDskKh5lQZJ!kQ&0aM<-fykOZ6Kl6_$L<4%uqCem zXS;jQbM+eX4;5m;idAT6??Asm|9E*NlG8I4=oz}<>tEyir%RTuQUj)TZC;J?WBH<9 zZ{p`4KEuxf-yeVZS(c)T-vX{e2<^Md4dmacj2ahXxF;=@Ua&q;O&4}lVg#S7z%GY0iM3N{ssnW!tUY| zr?KbYQG|xYs+}?nhU}R-8Sy2ItB*qN}z5kFU1?&pwgQ`X#>m`Z1o|>cOR!DqIlIv%bE; zSaGw5zlljB-cz8rHPAz-mj@#JJP{G#E+F)PvB6jj7R9PRNtBYK8`2U}vA1BKDvQ8u z09H#@w7-WGAN~ zDLhJ*C-xQPMbJ}GQqi+?#OnFkXgzfZH{|#I;8r&VdaIDXV~Q$&kR0pu3iOe|EMUe_ zvJBzqR6S$$oO{#D*%(gN6X5QkhX7Ae`2u+->#+idad5WPQ}K8k%dxT?uRtFY?g?AV zNiY)+h|Sb+6ef-xqCn5i*wMpu87=R=@poD3K>zL=|4>k6(;a)`m5Qg*X4BxSfu2i3 zU4!ty0$l^S*0k4a?O*rt^;*+j!}r%b4}Kbe z(<_ZekH)$MbMT)IvlhPaLl&uyuxovD|Y;qWmWsVbWL{ayKlTvk0e7RN-vnS#+Q8!iBDG z^j*A&E0_CmsqZ4n%Sw=uo{A~inX2>wWAqeVt5>Z=aA1%qcO94+8&_&v?qlYibC6+L zO1gqM;msWOsK{uQGRfm{G4Wt#3kM@n{qwba4`#w>>wI5^fubU!)ob`Zy1(I}mh>J7 zb^@M;MO)`_#^0}Azk!{5_P{?P9A@@*Fn6$rg(!L#F``c5HPxJL#lW3AShjqnF77W% z+s?rS_D=2y2#!MY*)9y+ysrw#IlKA7Ng!QRT%kbE>b9(B!*Mf?E}jUDPQ>g*E6~!} zC+fZjaj8?}dWhf)7K72+jqA7H$F^;Gud;D$InT5hKwIH~vk1aj3zwj)w;%0YJ%~+8 zg@b&DV`8kR>Z$1G$?<@|Pz8Dwx?uwEuTLZmHrFQ6(b={!CYnS z5d6B=>kNT3f$$ICeuhsT_T%GwU1&YCA5)Wp;pbq6NKZQ~o|1%|IJw|{8~|hn3sY0X z#3tdysXA=gxkuD}6b|e^DvG{AAfF`eRW$Y;*nuAe@;^O)Dxc+RY2T{Rx;HOWp!?Jg z1$hGg_Sr(*X)8ka$!!YuU8i@TQ;fiex7&bU#2bKk8Bg!vW^XGx&Xl07`Z#v1SsugcE$z>@pOfsi(D{wd-%EA!ccECMvfSUNfY$d1)Dl~3XT>XLs{7g z0lGORPSjH>iY_OYRPz?**2(~In=yPtahtWU4Pj5vvokg%AW#)E<6N8&&1?} zWPwb$>I7uyhH6p=dJFiw*$+er%WY{vB2_Wf%Y(R}ha@;0r(Xz^yOM5$BJ6ZFiuVc3ST`cZOh{3sC+VhC8dl0au8 zoJqwX}x{4y#GsN5P48ptb4Oer;>ICYV4`mdqe)`e1vLBe_N!?H+ndj!wyGApx9!4~ z4V$rj^ET9+7Eky5d7SU)KvQEQ>S}6GURsKZ6J@BaIfJt;&1h<I;xepW zxklx+GbCD8QjSw6Ps=lQ9L2{pFe+uAD=!DXkNto zH@flN$G63ZJjOFo$j`rej32*vfS(?MX;VL}XMrwrpLCFTZ_) zXD>b#gTv9d-vU2;j=KbXsae$vd)z^)waAPoL^hoH* zgT=PDeh;S0y!Id%9#R2(DULjF3qs)v$j~6-lrU z6$PwyhO%j@UV}ZsszF@?v9?Zi|JzvmZyV3~|7sf4HNb28xa4bTT)5;p^d1O%?$bd3 z)}Q~PV(}W>S%QMl=U4_B0F$w!aV&p38p;pj%<%*86%T6^WANrC3i1qL5%g5`s#BIt zyd7rc#6*ND1+O)RZfF2_j4I#5#Yxu9F=VhVM*r5k;th-!;UM?Sg2gLv<=Smb&dP}=uajFB?wxQ-!6{@RF;zUU?N{@*U zt8GxQZfiX!Anz8BpclP8{TR4%L!}%O#(ftrt1OqE&I>r-)~TWmOm)0`>59Df6?N|Q zfm?X=;0f;BxrY``e|o4$9cQ~FO1Ho7>Z|wXxwmiL!~MID@ZjEK+`aV>_wGExom=-+ z7?sf8xN(yx`s=uOjLs}Xx-nfRIYXg`yd#>^j7&_jtX&X+< z=Wgq`pu#p+uH8k07{ZlnHmb>9I0wL$Yj;%jPnHj!oH-Q>m#)I;hO@YE^(GowZ%DpR zWo;8C=g!7@QSn`uZ=&ncb;KuSC`HaP1|D912ndZp!GXgnWYg7u1wB^=(0k&aDhigQ{hM*7a3@Y4+=Ak~)hOJy1P3=S zz`-pG)pGyFdDy!_-eb!GlqdtOdCm`Cz7*m5Bu}DC_JUtXaPUdj5vB9)Cb8xz`88hZAKyYXbPL!Wg=}`#@ z35bdg!@LF4#0@%$o43#7BQZYj-@l5F?)9s`eSGsQROK&0`Sy7@vVJMAXBlJ>&gxyoh#@nK)052&0%C9 z52QSlW=3YBrX1BIBdm*IBNxs=;K7c!$j~r>dm3^w(=jbWSNb3$K0$>H2pM;An;Eik zU^<$a34%QwakOAPu3f0X!)tB${E<9R=Zdj&%Vf-%5rEW0cf>|GOLIbevI*%*+7&&JL`-@RT{y|-BgW+b+Q*Dz-FTd7dz&) zizgro-_BwJtj(EXIbPH~Ckkgd0$px8N3Ig^!v=BMKV2Pof?tb^vr$D8tQxpAF#qNE z|J7N`B|*$k3(upfXXCckXfS@O$ay}`!JkF+N<0zoZ{#S69b&if@`Gb+~4w8F9 zPvy@uT%(H03FN&67~_WyfyKn}IB{qj4sTnIy0Stzn6Zq)2nFgfa{n-Ae(Ye~sMvAx zdyJKRgg=2!&@*(Ssdy@SzK-dP%x!m;`@zW2SV8{ncZOild&5)-1de!JwtAyd^odDn zFfulW#miXsB>Bvf^u?nTCC{+o`0?X0R*ccOapP184}%Ftur{&7y5;N9Qrm(P#g)j( zo+bv{5oz&hA~1552f1(8Zq-*5E+AsKD=D z!p`k^;`tZhV$T&d0nwpDheb8Z_en{`c`+P9Gxc%)lAAdlz*r zEtn#oKWpkV)QU&ZbFp7#-Z0yxtGn-IhwOdy_TNzbB3$wGmKFGSbo8R5`;tKV zCN5mQrDF8D4%pl1?7fOsd5_-f_fT3@55M3TU6z!Mqbe@P>Z2Dg4d9X(h#py972|bD zjMxS73OdDDc8d{Yr|j(ci&P;xcMpcn#Pe`;!)r|YX%M%lwD2G@f;_NwW()@Ew&29} znJ8L43l#$P18e4D@7j4NSThfKvc7B0eB`ZLfV}ndk-uSq+TOfu8a6D>#+v!bSUD#i z%V)%3<*ayV30ONX1?v~2VcYU4$Xh!D`RjABd1)G!PLIHrWog*3C<%*m!?18_2v*FF z$I=<`m_IcR$$r*|a-4)HQH{BQwpf)Ihz(O?;BR9H9~U>Q+^_*>np!bgesmwdP}Skl zA{QcFU`NpJ*tG%2i}#?fw*gJ{W!SxWm72(8VP-g{M!I5FybspO-&&jzidhN1$PRZw zl&3L5-3*WrXoHkcdt}78V)o>4WXA^}+{*#pb^=~=BNeV0GyH8)V)9T9AA*U)hYI`+ zM7=q{-;)!$_#rAh04AdHhYlVhO59Gx4VNrhtmcm0E|z=hl<7zlL(9Prycnu_B}d1a zal#RShn|tBDuJ|>of;%%Wo|2OzLh-qoDAAg#pqcFozn+0Y(vnq`~jyCWQ`RndM7K3 zSD=sdb5~;%u69-9(e-oq>|sC7Hy;+zXJW2^J|o2oi7_7X0J4~^-cSHp{B0NYpdX}?KvCvtFp9NU)GC-rPYet3JTI1*7XJf8Cm&~K*=Vc8Z4wz#79TQG^J#M@jw8j`cl|Adz zyW848Z{!G=PaKQmd)AAvS%J>FN?009P)3fS7yYrL)OS;WA39hWhB30uy7bJp;e4@# zJR8$11AIJHNd%@bveQ$Q*A>C==9_Qht+xkb^q2`4Gj@_1AhlxcW(A<6lYks{P2pqo_Vvi*M(kzYiXGnK=IVm(zCE}%TDx&H_=ZR_gzz9t`f!1I6hVX_3QW1*4c}rr6;lf zNI9m>U5XQDns8pu?Gj*9<#%7Xg~h8j!Pd!Jf!@X42WNyC*97bXH}2xx`HNVxa=nWG z6Y|$?KNRTS$H1+7C_YhzsJKLRtvO+N=H#g=b^En-Yd6Y|+<`;8cOomyS5$2#?lo^m zZ`lTvubYWu>t~~I?HuGUpN*Z%W@7vDS=cH|wr$dOubz*cE9YXfKKYt#R z#q~-`j>UzZv$%4p9j7V}qQAQy?e!J%w`XGAoD3|SF@q%%g_EOm95w&5hw^ zZw)_BSEM9FBO^5d=Hglt^bEUD(XUyxPE9SyNgX)(2w~5jbrrgia~K<-5%`THW~9~1tL4$U*PU7&0Q3i7t#{FRZEWZQY|sY3rW%5 zh>!FXmG3GFpPjd2aDte7Z>!21tJ$bT@dvOxu_r54vas2IHC61)%}hQ&Yu|9@eRDY5 zn+xpqR6Lq6CwPa8qE`SG;1PgqJgz@}jOw`LwuOVv? zY#ao|rg;=RUwaJ=f%ZD?V;Uv%=2;1oqidO#X=!W>8&fltL(fpz6j6u%Zte>7>=gHL za>TGV-+;fXttk0DDB8ISm)je}FpR|b5kpmn>cp4doob$-pD=8w2#BEy^oEnht1`ur zp+PG1hFLbOW=U1Al@*{WwJ^8DU;irJ&bwl?hKvwpJ_&|$FRk0SLn-=*$XMu$m#9ks zFcU?uo9T(8QW>rx=*N#Ar(2GlfKlQRB*;B_LV&VsYn}i;5?eMdLH^Fw0^a>NU3pZ^ zBVAWjjN^s-<(`j6dSWUP)-+wKJ$VaR4VP58>F+UD&m2E#l%s;q2~= z-FbU(>()crm#;czogM5&khmi+KOa|ah{C>h4J$-Q+IzUePz&~)+emi->Ev~`fbk&I=_S0g=R3S#4u5f~f+I}vh><>&1=jCqSzA|xUn z&K`cSb@73VcQBT&*@D%Zc3|$3HEP{McxLV71uF+PSlT%wSG@m%{e{?>zaMeQ8S1rc zN$FFNFCI$enFeg#wO1gYtfnC3EuJ`xe6dbLl>+9&~ zz~aS=5fU1J9Xr-x;Bp79U1`U`f{mz$^hd+W zKp-+Ht5sZN#H=mc>a3)KYV9Mwhz#*|7cfrG9SmYFr2aM?_C zfKky~o3Zm%2YPEWmOrplVH=KyOcte)m70Q?Q!X0ZYtH=iI|o^qfNQop09>H>xZ4 zi<;kt+RDRdJX0nRKBUz4&J9~pxbFZ~Em?-#%*kk~J&m&sXHb8-QXqd49cNoq?4Cj; zCo5A;c*G7@X3UkAmI|0p;AD9TTIF?>#fMN+aRfCdi{w4ZaqQr3Y~8RLA%Ow#_4P(m z>seIR*I@7A!#FGJ>({Nuk-`G`o5iR*Rfy9k_T!9v&Z^QqSiN`})-IimnYr0GUUVGS z`|n`$#_e#j=Tv~={o1);+0r$*a`iSYF~?mzgas>Cz(sy@M^8_<`-+zw5C9jsrq1pj zNY9$8;^EEhohqHtidivYG^}mxVJGirD;~Osr>}SrZmP@#VV{vT9eeg4QO(iK2X5XW zaB%mBm7^!j?c8AJ>Z>4cWa$V?2QeH1dUN?)UV&j)uyi#x?ohP?rU5pSwyZ#)Km zjusgC=ASU;z1Kxqy&(_jJJJTp12;_E=!uvhP-iEi(WEgjk)}76L+J%jL*Iqr_)+5S zS|Khf6mw_gic4*au>t@`duODGbv;>Gt$N^HRJ{&sfjsBS)Ya!UH`A3nH8n7Up(uI| zQn3(Mn^`tg^Xwd>qIY%Fb;PD7CLw2X2Ifwis*0Jh4m}~m7(L4$5cI61NccEenjtGO z9QAVJU%OC^C$~EB;AX2l5ZiI=$V|+c;VbVIg3ROqWTyBE+!jK7^~fqu4XN%*tqnYXLC zs8S1fy4b+chLg#RRq2-OoF(kW4b$3SOdL53h5|!#{YeUZ9Ardw&-rGVe@-A1-kJ*6 zLMsF`!z-*MPoQ&~g~$ka!ky=6uUW7cWWpc^mETTq5 z&qj}m*MYygnQR-68;ekHPxQ5&!G)%B92Nm`y}J#=-+o=)I}F{J>P=9yNwJt2J7y;c zqe3KNP1^arqQ{Za(^dScPcIoP#v8;T2$V#T5*DkJRrGK%!4>h!?+$d!vJrQ$pGS9l zE#~GssItuL_ohYk5g~H-uRG&E`p7LB&Rvf?w_b*E8#iN_uxO1fqk8gIN|9m}C zq5_c^9wzKMgX?{_v3cEQRcw%@2Hc%|#beon-o88NyK)a#uHQ#b{{S}U?Na&l_U>+Q za1(DTG7_HRQ5-E19$vkU>$mS=-KMRub#zggF$BDgyx+n_%W&$neBODBROlv1RJPVR z+jsdUQYPmJnB8G!Ffu6N6Se%KF|Lp_}W~Q9GQa~c^HAf?w8!^Ay zOvUM$-o`jR6}^WT38q#i2u!lm(#3#H!Hmr8SD=o#TjZ%vKcxfe?&vq(x$+<|UO&pJJ z2mciq{Ab|3zewZq|F-`lO@7lKg&lj1^ssl|A>6(9NWtFC-3QB8tyd|ST|Jjkb*2Ha zNf|1oGA(lk?45mJZSR52+xOzeohMkhVuMom1ihzk7><>l#+94*RZM59L8qhOC`vi{50`1;caVs(4)-4~DX(>EXE zM80QBSPg+|=!YsRf!S@yQz-j#Fs=HuJ==-y>~{{D5m_~t|0zj_`Y+_{WzKfaHj zKYOgE8GO{=fG=;I#gBJe@KtXGe!6xB4Tm<1q7Oz|N;WD_of8+R1lD$YYXPe@Vo zw)Xb+;*7Y6J9n(d&h4wQXXiTX-M$Wa8nPAn~d!%r(xrg9Bh!bYGF3kEuW6%3#Vey>?|Zk2V>6EOsrqM67y%zMpkBqD$tak znvVFGI00FRs@oC75qzO?A(E3Zefo54+^|WM#z{34+E1Xb>ktzaFO9A9L`{fZiB0CdVq!4|Jc#gMn6j@UR6Z%ID&ENe-sxx~s`VCMOZ}-l|Q>@Ds=fi7Jc4 z-03k2`c(QU@w!f1tr7B6_0eHYO3_D$=$3?ijHvvWP*(xH8zO^gpqPzhj{sFeM^~5L z!&wx*n;0c)Bk^RIZmH{tWax%%j6j^QHyEo^^oA41i7^m33-I*>{)9c(8RpQFa|q;# zqnWxnMyYp#oG>Qjxg^w`MbWb2B-J?~&U4s!KEckA4A0|xQLVGHm8FQ8VZ#DuRQB8^ z^woQglFuQY8$Bp?h;yJ6LC=x0?1)W{3`b4LAygFY!ku36Fbnr$@ZbLgUk@>iB3zhD zPftZ}jCd0A-Kgv*h{7lIT^(!{)CqZpZrBmaa1R^f^Ar>Te*SX*m@3c@9XcFC1@t3^ zk5+YU$}7*HwxLx`GQC7RkYE2hK>gqLf4KbxT>)OWcKtRkU%8IpkVq7loy5S6`zWiZ zMtD@Bz}*XRNm*!U=|b+zMR4&5#FicVaP`JRRMnk@vsaKZ068-jqO141>a5KZH6Iin zs}%f!q7nsoPrnds*t%O8fv(=GYGyEc6`XUHuvY`72%oZ}M=(Pa{idnWcv!y`A2w{m zM{T8e_C!Gc^Cx)z{7by}<#TDD;MW&lLDi&Jjf0^$Na{y120y5oq`v(0BmDH8oCB6c zko`Y@uPRc0`sfDUzuk*Z9$v>&@eqFf`6*uf^a+0a`hC3k;S>Dy^#}NcQx&ql&M)7| zOTWf1U)=$o4&eFSHhg)Z3}5wC;$;46#0K~wYw`@7syUCIrzN5J)FA==DLlB@jGH$rP*FV<#V4mAdx{S9RP7ll9!O1ek)^2oOkd2L8X~X{ z$CPw`q$hf+7=AiCX=B}yETE5%a1pROAR^daRJ@}=U02hdMbBcx*jyCkBZ9<0`8gq2 zn!mTGdM_5qVxcZ`__*4@#a0ZT!FW-z0{54o|E;PwnJB8|n`&NdiV5Gt--(V*2{ybw+^df5Ir8LMN1|*0oqYWBP=;W(26xwa^U>0KreVb4o)h zeQp!*GzK&h+~#@4vSiqXwT0M6!mt_BEIl2ZU?<+1!PpUE1jfsL1MJ?s6ia4j<6Qy$ zX!)+rcGjw>8SC8`i8n~#^ZQWUb35oaaOZ%jh>*ZnowHnL=*QdBL)>*Myz|Z=QSu`c z>_?3r_Y(9q3iPICR``)h{=Ws&|84)L+phxqJ9i)A*6sU9;+UW62Hbo25oXU@s%G-? z4~j_btV+aV2!I}*_acSTln$BHR;TwB5KO|>PN6(epswJdPQJt{UW-mnl zwcBWJ>qJ0kB+|2|tKw*vuir&>&dgWdo0jD9T76wT4(!=2E`KC;&xyll9eeP3TLHcl z7(9FbszCTdJb(6?Kwj5=`S}Y0`PcaAdzLIns5&^$ z1^7RHj$ghPL-Fhjd7m%vvlx&cfBXo~eiD!2#TQ~c1n{hX|D4P3<*mMzzi}VW1@u2( zZNXE4@l%0)@wSDC_4h&UlzFJGyMRTjx2o8dZ(t}EEnbS=i@oSN*NzLFXVqt=Vfy*o zPw?f3_weO|Yq;B8i~fc}T&drW%XRxOP=DZ6yV`I7*V~TbPWMTCaC*M`Io67swh3!DY{!u! zVoYw|#?#L~!==mp2#W}ZIVV=Ow$d#{RZ`L0+uN#mDJNkd=ncf>XO%yu%@OpR<%giR zVbLdRdqjsb<0e5A_hi)(`%j?v@rA#u8@!lxVY^8-#-8&;HNC)~*e`f)g<15g6yW0q;Ea2^81y3g{*qG`I=m%lc z5M2feAwPaNQ&|VYL|?od!$|_oQ3~i>67Kq<<{7^?95+_BN2(AH4S_L%FY1_K9Ri=* zBL@#speD4b;F+aEsB@ihc!HZ{hY5c+!knOI2#1ZK8!j2TA>g$z56@*xo&%)_c!EB_ z-BVo)S6lI1ob2FYXDFV;B&=OJLkxg9{_*Gkz(4-_C%o~OKjQ7b|5d4Xf}M>aDi$|$ zv$Ij4C*ZZ3H&pcu-LMh#%%}HscgNVV<1u{rNQ@jg`kz2wd8%HXm1Y==clcWn?Hl34k4&ccQL_qfqNmUoFd%HK-C#fMaZC&X_62XDEE_hT!PtWRz@8LCN+ERODx( zy<#EGR_uh2t)=?RrW5t$J38X{;iCxj@D;=7AooceJYAf{i}QfDo0EuvAne_>O_eOL zvG>5DrE75c+I?)^xd)Y1)!4putGp%@v$Nu{ZN)q+ot};;U-1e9oshR}rQD}!@b+?- z=WH3e`uea>y!ghZvp8B*gn~WWv3BJg1bNxZwQyD~z|&C-p)E2q6JTK>9+`tP>Z)6D z?eYWR$P86hVc_yrJh=N9x0t3la2I#)ekjlDJzVU&jqZy#6=eHw+(T7;BT}Yhqp0LK zZr;C(x~3LY=O#8W1(m03@TjchpMGO1dWLV(Gjr56xO4w~tX{WO&H9y+o{N^Y9^AP7 zKI)q~k&!hM+ja?uMA5gN>xFkvli~~H4Sme zlU3zQ?pwHICDJpp738&8{c9~P%{aIxPh9>8>|L6MZ~Bhl+Y5#GzP|=PJ?z8tuOA7V zp9+va!4Ka)!KWYIRUIpj?%Wdi-Nz?S9^tbOKfo6se~7O>{s^Bvd0$lh$9VR`w*u=Q z1p42I(toNZ2!Hn7$N2P#DEmj3@ySQm@Y&N_`1F$-`0ksB`2O4X1$l*J^c9bHGI+6fDc4*Kj|pJq0LJWB@fc98H>@-+=rP9R>I2B1CgkKDH7v&;xgq^=%po+&c zchyH4>+Y;yzaFLKWjNp6h0N?MSXf!AM%c5E6vI0Nz1A^Hz#AJHsYX?ADge>uq;#@# z5Ctd?i>Sur*jNSn*;CjVo1f(gX!_J=ss-8;c4i;HmC4g>PYO@apxx0!YTX*@t3j z%o^*uI6J}45Dp=)HNu?x8MaYsT_8@SPvG-7mpq3{o~J2&s(FTPnCV2|yUVp=iYpDR zmBB>$ZU*pmHN)nWb1^kF27mgG|B1i;@jvmmKmDfyzTUXeO4ZXKS;=?h_p=v|FFQR& zK^%BiPUI+Y*;h{Yv<=+a!d#&Cj_Ek#~Mt@Oi`fUxM`~b zeSvt^%`NT7-z|bQEf(1s(Fpc-6eH^@jT5stA;8}iv2kGnJ`+`QrlGbS1N{#$J$E*| zJbcs~5e2*V;%fg5+`0W2jg9B9b?Y8%*;1gEd3%nbq@o5p^7g?^KKJVN8*uyn1N0Bv zP`UGYdk&(v|C+R`^4n_t9)H2@I}dQ7ryrpav8btU!R>pGRfp{SMJusm_d#^^44|j) z1}gTqHopy})d+`9K6j+UH)Pe3G`-27Epg!T(paPz@O*txd|nbYQ|bjto~ca(x> z8JIFL%-wwhDtt3@&O(HSMd@nsXo~)9Yb*BU?MAFvSq^IY=u!nf=qkd)bH%vbS%t?p zFW|F}?&9;Ock$tqYZ$oFfxe5aDs8d<;#u@vXc5cUflECtxOl!nHSWKEyAK~ckoK?_ zPagCrMf}129t`x>%Q>fU=|T;zUv9>O+voAs)0_DIOHte(U&ogM)E~aMhZkSHj~5?a z#4op6@!h3U_@b)}ANST^+p1*<4h+Y|P!x0haC7|;Y z$cZ8FbcTyOpd6{YbonwgG&N$$vZXH-y#>rfZL|J%YHBK0$<0m3GZTVf=Nz3>_Jlr{ z1U&~+F}0E{A|ylr8;zXF>8dpG>?yfwz!YQj?2Kg|H)He!y@Q#tD12+|S~nM6O~-Ke zN*zA9cNPOT4x_$fE{<1DQ=uD%X|mG&M9I4%J%x>`-VI4H>`b+T@x*s9e$?x*wHT$+ zE2m_Lsuy*i7$dOfC|XhcuR3J^N#S!utrNoioe=8lfFK_SrRIG+Y!v7{T?O*;`3QPf zM+*V-FpL`fjtbpO7(PP9xhIVo3tRDKION`3&lr{l#;`Urkz?bPny13oW6WM)N%c+@ z&k&Bu#Bt&k3|5fmF=pu)jMu?j3(XMtRPN>{-`_pV`?;ycJt}@uqCyAja0m&ID89gOox|jPS?rfA|03FMlBDe=nf_qw-ex zIXO8-NVfd6UI-(h!LZds^?Nq-$)hKI$hJO zI%M_bH`5@`#)4q1{nFapj&m&?YDq9fSE`Ug^ij8U*O1P7!Q zuZu?M&Lo^Yu?*$=79%Y>Kn$k2`i%(s{rUS;zfo#Tyc)gD8NN8BW3U(}ewV`i1@Myd z%q(26cH=JeT)K@-0{U_>EOTeglGj8cDcl>o)-J-Dc~g-R?k65=DE8;AM{<0Ws8maA z+_(ds7p@_He+inKdIZ#mz{yKu!U7TQ=PpeInXdW%1_FoB+h0)0#4d0f79 z4^y+JgSBqloW)b}3sxlGqw6O2Pm3H|BQviBkxc^A8^>!Q&4;RT($E{kLR!`&GMk^AS3`uPEqWyY(2$ zS8ox65)4OIKh+Ktmf@-xAS(OT^OxlJ5`{0IXJabpz@10R>!_FONDqVkF&v1g%}DiH zdz)CU4I4yl`5`&N4_g=K;P~bRDBZCPr3D*sByTeg>{ySyt*fwR$!yGrk+LDYmSggH5Yv zs$ATId8<)=WCv<0_T#L;^L%qTT567>_RK-FwUnZ>t{7b>^KhYTCwc_T-6h*mp1)2M zWITdHVzGSXIy5z%$K;G$c=`p&&9WJ7ZEaY+YB^Rco`;VfUBmMqKE_YqJi!+q-ogFL zUAWoRi0+y~G#=ZCwwI7^J-QyvMQhP=WSwsP_y%;g>g}l z$Vg5=Zf1r+J_j?irmDeGNphoeb|Yqe5ISmPteFXdJnU4Ro1WHEJi5`OK;L_*0QGJ2 zu&*csQ>J=j+SCB#W(OiI*+n4lg2`zfNJ(%NgW{r8{DhHz6BxcBkQ)MbM?<6~`bqOu zqi0hR+{GXW@S|R4;Ar8T5N6&ui>i0lDS82Y@V|gwH37Y^7*J1F8yHO*jWNRpsjv;> z)P$Y6fHl;|M>Pivj`p>Ls|`~c^;8`hBY`(FR}AD_3u8l=GCzFMM3@PP#}6AWFc#>` zd$5C*ASax;u7zhb;B))8%HG@6RV}sGXbNA;y5TnA&vlk5X4cJ{fBG~2^6$UHAOF|C z;U9ne6DAHDh6zIlA=t$dt7fEQNluC=T^}9jMbZEL&%ei8fBUmQ-Wc{);%SIsb`Yb_ z*nWtQz&#=iL0+8f+!bM>;F(X)c)b>@r@Hs{@>CuCLxv1{1$ruYZ-G~BLz{vON5%dY zLM-e>xVJR5?4w|cB|#q%5P+}%Us3j+$lJ0}<*pl>I%4D2 z0s-~_w(s7LlCqOnvTz}$q{m=h4#(qUiK?HD1yfUz788I&dp2WcZWc_%d&ti}C~&-n z-Fu7C+R}%LvNM=GITLfIXCo%q2hlCDH22OpxN zvj?qbbtMosi@N{qZ=A!~rn09YCO!oz>DhSn9}X3jD`n4k{l+c% zqV`uKC^QbXj$W!WmMu0h6E)49xOnx>E8v%(7Vk?u50+6l*K-xcm9<#1asxbl0^#7O z%ediSDb7**T6fn4?Ap3btZxQ##6`?a6nMnNAU8e+b0()^>71#^5jQh3zzg1vqQ2~{ zRfJweYh&$pVJdhgei^*|;$VraCoQ!15&y2>Lln6CqH#N`$aq=001?utf zX;{C03#zMIk(8Q^z|aVkRaBs|@&pp%qp@bie0=y|0MEbw7%v3&pFO#yK!3NV6WQix4=cm5hz@ke{M;1eZCr}&YZnT9la)d>HPwf^{5Cn$IgGpc{h#FH4n6Ptd0)d#Tuc zGE*-_?I%QuF(T|4qYo92KtQi4dV=2nH=t*SthY2ThH%{Fff55cegw-H4-r*64vv;a z@}7ZMxp)Q^%$kh!gmAf+{1xb%&-mTl_jJIZ~~pjm>*C0|290Mg>tw}HP6f&t}DpPdCYJk?B9L;Z}{7P z{$4=;zww9v@jvmmfB$#<{@?!}6}q9C=L96yW-NJOpj16$ z^Zo+%tmH)b-F%f0^LBPrikK?i-`hhedv?-t-HTJ~nOWf7ci(#jdP74~rS4chH-GOT zn3`Gs6NEa>vfAVYf!;Y)NwT)O0Vf6WubKk=Nn~eD#<(GGV#%~vjmD-&qAP)+T_^01EkkbGPcv!ou1Gwho?faSu?({p8qu@iI6_lp|+nEnJD9$V3+xJ(U_^p$;FZ0b z^5UrG&6)JUfm5RDU+cTrr$(tYiQ23^Rf(F)GMqSe2t|8#;!weMxj;LSw|yhFuU{jO zTO~?l1=A*{i{hV#4J(#m$(-p}G&={2=j3AL zqS@HIW-0dV+Kj{b+p%Zc1~nRYfmq*}S*ZfXbj+BXf@x__ zXQX3#dYY=~GG*!%EMKuwP25pk(}4JtbmY#Sjnj2?ICktPLW2FVVa*bJ`k3LM$N1^1 z5AgLz_wexQ1>EdzL~p|})D?+0aC9}AidLbqaHYV0wJ7}cID32@&X#S&#fC%p{(~E; zGxqs+pNgWtrv_eJ>8Z!uX=!S3kCTPC*M{Q-Fr#2GX^eo>5$l#tL#ZhK-J4b*H7-n* zNH8`wfRCs$e(uWCr_j>grsDNRMn;%Ol_?6)T-3W3kLLu*guapNC*-Xyt(3Ya^qG@S z&~x}VD^;>$<@{;6SU7E#8Zf0mAEql&?CD^y3Ysy->nNa)^mj$c{w?ThKY>TrTk*mD zvuJMEjJmoNSi3G3vt|Wi!MsQ;m=lF5nJlO5CCx|R?W(eBd|XX2{GC5y_}hOGc#edn z;V4zA*w5WmfbNX!G+$(-cq1)|Pit@2%$11u1a^&90LR?5N zqJo0dclH(a?PABYNeh9FE(Ak3GbFb2~&<@-?a6Zm#=jSR<*(}Dg!euv-xkN<_g{_a2U z`tSZ7fBW74#Nru=ICXd%_H3Agl*l0b?ti|9*Z;%8fOZh)Yder#?l;wJLB?IC#zMfIB`mVmWoNE-^IKsv8X97Kv#V!F11zS z!PN$Q|M4|6R_=qBgBi^AC&E~Mv-pU3lpHNXkbI_som)j9T|oc&Hr%>&5g**SiT7__ zLv4Afn)}$&(pe=kuv2l*zC!HSu^VewF2(JuUHJU{0X)5T8FzZy@YR!>`1t-6VbpO| zL(19N30t@BQnBrliUu?`c46!0U80`TakZ~QJk~4t=>9c)cy9oY?_9>!OPxrH4~LVZ zuI5x{`z2hvdS3vWi1k~x;zCa^=FMNICO_f45iAYt=H{&?+1^)h2)!4tV9~;5ssg3E zn~&^|L{noM2Cm)4rp-IxC&rE8oXo7;fBKF6{li7*i4YEnR1?6QJl!B(2xt4sQxNwH zj6&AbIjSR;koWKofvZQL>ZG=J@)l_OskUnEHl_L-Te?(Uy^R=wFfkJ0acK(l%(-WX z$I?!o0a5TFp^<7rBM#hR_RVXZ=Q_~a-33k;_=0JTzkGvdKYos9KRm_H-+zi91a{wj z{S-fZ^(8)j{1`2D4LBo^ZEtFp)`W&LXHd-1Z29>(cIc35Wk-*qs;msvm6bRntwkW* z+1i4;*RSFJ&6~J);|6YAzO1&dT)c>$jt*QncMcajJJ2J`u9j9@l+V@I*@^D9Hgq;O z%MICxmX;>8oo|;fd_ml#3j+E&B&4LOVaoL_E!eVU6Cy(Wk-u{TKKtMfe)!^j{Pe{W zeEsAOo?P$6ot|b~s6LE_!gV@DFG{}Q@NxmZ4)!gg=(F>#cr#-T71D7ji2V$PI!dju}k=xVG)?TLdpw0k}BHmwr(K1)2Q9L$=MB~Z+eWhSP}@4_+_VS)01 zaZ+t(2Q`wG`S*-_TNvo64qBDnVyFijQxn)(SSZNT7*N@3shC=*hd?LT*@;WFuPwDO z4)gMZ#Mm&5H295w;P0a73Hm?$&;O0T{`TZz+@SvRORWaQyz?{(t!M z?|+9k|MDli`?tS}fZzyd6L`5gsS*!d66`54QJ9&XiMX&3)x!LIR0xOlZWzL23kwYq zzz@gZ!Gl#tEGL#Xx3Cd_laSL?zQt#vTp;LP9DO^qq`97X)o8*M?4)9xp%TreC#+9 z6JoGw!xFSLox`{`k=x>XnZ#cRgC-*Ex z%|U7VMJ4WCsFs{0oY1d3x=Jbf9|ZKjeEtMKe)F-rQNJYp6qyfSx59W=@+9HwPy; z+1SC##0(Zj?1VFhsQ_M241l4&fl~McJyR?hzM;Bzlyxsx0cU6^rlzG}@$8vcBEKOW+CLMM(;bnP>?EHl2)Wt* z@*p`VC7%+Y*S{Wv>CBuxAEN;H#KD2L{=~Rp4%ABtV`x5ibdjKF2K@xGcYGNQ@pS& z%$k~s^!R8*1o#S&-NhKX!OzVZfwE+0uC=itTx_gl+Z}cSTXx!NnLQ>G#>;Y|D0f|m zMhp88{90!%2UKN?=wQ|jLI1|@|DYhx@Xeq9_y58hqUetntiqMHa$IUHK}KvC{`kB9 zfxn2FXHA>;-uRm?HgC-dxy92Hb|^nCv{$fCj0{IoRD^LNLH1$kinXc^{cj=EA&OoDeYJqTN}feRo{gh9=`q*U zHeuzm6=K*&Di1bY?&}!8|36)C9UjHDt$VNM+R^QM84Gs^9(Q+lcXxLs2@yyFgb)HD z2^Ipu-QC?~xv%YV?m6emcjf)YJDO(0KIi^1pQ^5|u5_wr{l+`S9CJ)}WJmj9d3ie4 zv{vdMslTf&+{94Xn46-kuv|QWgGdquosx|@V$^I! zH3wtE;0|25`4C6XT*kpe$B>ngEMD76jI8g#-jQCMJFo-0Hm$`_Zzo#o%McM7fVjAL z9gMyA_+yNYAH~a;Ut?|0I^^W03onMTXLJMhj&8=`JzH_)z^E{81X)>0I!`4cEE4zb zyuh71&kz}(h~crFc>F2r+dReNCn7!{J;95|&++KN6FhnJ3@=2rzkL1)K6&}6E?^QF z5hsT5lvbkTy0BF9tcaOkP^t?5&3pXp+2^=-{|O?*%Q_~i2+aO3t9-6zlqdjg)IPt7P)&*kN(-)W`}WB1ok3m#e zn7E1wC@(HXNkIW(BO|q3D5vBz1Yu)t1t(j3d2oYJSz3nHrY3oCJ>{Gbq$ejMCnH0Q zLmLWnbH&9^MY5<;HeQsVQjkteqJO1_CC-@(~`cjO<$N27(`=T(;;p+K) z0$5+2!N~zw(>YTV^k(u9a8TB6*<4lj5dlmi^uf$2A7SBwSqSp?lFplkk&$7YG}YeT zjzqbS-mHS>>>|pBMawLtiK3VL$dC?IJ;BbZgjDlvtX0p9n_#~H#LK-ekZabLm!hGx zN-{9e`qcTRe82G@n<>QX)~W}10H&`+IUh}GMg%@fEk5%A3u=q&)3Ak0kW_<=vN zlKl?AhFd zd*}8G=r7^Z+ZS>F;t`xbG^+92=BgsBU)6%m0*|4-Zth--h$ALtG9G8mM}kY@+^)X6Gbnu zC*+Tb7~`>%^4_NYO;|ElJeyflksRTVnu0W}ZK=>PpIhe+VQ_6Ta+9OvKFx=-jRjij zn{f5Y4V0DT!_j^*s!CF@b8roAojs2G7f$2ug;Q8rU#b0`s&;T>w=Su7^6V8{yLKBD zB?U;13BcC=4qQ4qic4bTPwm}`gF82&tE~op-Y%M5vw3Kn7>Ebhx#y_nzVF((8?mvW z*fuQ2;rMRcym%Z}&mG38BV*XHWdo8EB4EQXW>hTh-+76fHyjKQ-)L4&Qfi)-O(5tGpSXa>AAhZN?N7`1c_8U>v6yBdh>^fWly+Q5!8 zI!#S=l^eppFgFjC#bxsFN6SMTfT)l#Z7Feya{WL!i;`s+!bu(s4zNaxl@0Lm)38J! zW6T0UHpZhl-CtW!unt591qI2C5=9msinN?8?Ap5rr_P?%f!OS{cw9WaUne^K=F4aJ z73=W4yo+yG80pFp?Cfj6`1)$>>#tPMAJ|Zi{rzP)Ag>Q?tP#*R;n~%3{IB19ivRZg z=lJLEKF7B&@8Q#@S8?<55djewXI=)2c~fCJYciI})@Jd1IGCA;suv&#@Co|xKrhUk zI#FC`69oEsA|o{k!^6X(>QAGnq!^*0p}L~IySShX$?(20j6={9@@#~BfS!p z^Jr9K!y`3^o&#Ogg~h1KFV#iCIrW~kZer#Bb5$ce&T+ z{OCAFHkPBlG8}%MbHqz9L6EnlGz|=vaKRfulTgi16VZqD~Fn!`rF=Nut zbh~W9RQS4y*I=_mlk~+Yr*>N zl~~u=j*_elqfkpBzl&&l!g*tu<&c$}87S+*GQVZJDo-(>rScHFtJ zAJ1=}$C<<15hA~xgZU!qFCJ)ZXu!R@x3zj~Qeq&QYO}CJ%9N0XnnImT}UB@*sKHVLy$V?1HV`-Xr0jqUox9jpupFO+_SI!-g=gAG(*;yFb zvIBP?y};16J$UluQykoP5Fx>SA|`9Gee-IZKeiWF&KwlrAH(G{M^IN)C_+j4XHqKe z-F_~he~7r0GzI_Vlh1JX>8B{H zXi(M9MQ1oJ!$r*B85!Ip3S7wV(_+ zxS=1{E?pE$If9{$o3N&XZGe`_ZsHh(Pz+5pY(1+Lc z(JGCEeOO?KydNaz`77*=fai7j+TYV#!ySPE0r2$oK}b{t3Iv*a4~i>)>?k6_gHe*7 zj*BPv8xRwmOG^h@VXf$b7eGM062k@x(Ghr?nn~Xo1i~&>LijYF zDZjv?xf3;XGjsCK;bgf)XL&N~!hF#b`Fjfm+%^JurdkTrxll>ytI1LU&e|BVF%Hg# z_z2)V?OwM4cLA%j7$;j(c-k&QRZarV>>tLbch2J1@*Di{>@L1|coh#W9n}Te*R0F5;N<>Y7~eXGEgJ>+8`fgm#y){UKXwdlkn;z{ zD6G>)W3Z~Z9-U3K((15kc_VsSo6%5Kf|`;-4V@6ijPbLn`WDZC%L%^skN==5{^x%u zApiTn#n1oCf5E$d`yY`N?~R^@98~9oV#WtQ!!Lg#YX7G{!o+ufuHy!THwR+1fZ3~f zeOy?Gf}Sd#**A>Y6ZYP2u444%o{B&Vm*;El>^Yb=b-IRaI75~-=dEp>bn*;yyz3g< zuxP2}TM)|6Ez-eQ!v3@Xogti~$4;uUC+LqKJ0r&~VE2v#aItj*XSrsl#34hx!?ajm zO_M&pf2*kG{n8f`;OFKbLcvuBk{>>}i_XqQG}afOu{s-Z@_Xl}#-KVk9km5nXeh}; zmU!=efe{!MP+t=0o<4saSFhg2`n9W3S(Jt5>H^JVThmsDUBmsTEy=~M?VFL55RKfN zJnR@9*NToi_Z-9HN1x#QsSC=0l`HB|nwN^c?hfqRIfMb}ADjEvAU|6?-oymtX6GsB zuU@??VlfOQwKdpt^a#>(b79R)H5WIyy1I)R_Jo(0{2n5BqoQKq?d=O+;SfVNeSMqp z$tPdq{DrGpbDqnZc69dq8%6)cm)~jVh6AymfAt$x?=5Ys5fB`sATKFzP{=nv~5xjiEkeO4epL_i53&g}{Xvl{(a<=U}fV&Sr)`d$F((`d&JPhX2=a$rH z8DlG3XB~`HMc>}C9G>D1veQI`g$h`M;Ns{YmeDZS!%=-I`7nVi)jq-BzI-_j?B0!Q z7cSx6t=o8b_nv@%K$jDvn$OS9(K^#y{wyvkT&@|Y*WpY)*5{xC31Mw#F&?pz5pWl` z*U64b*%rQ3>;igThj6EnpsHsWgBd4WE7i}}7e3-uM8w3Rq@q%+;2s=0d=QagL8z@P z#OXu3@cXY{;P+oW!w&+7Z=YPlCpS-Hhjh%|niOp9$i-++A;zSQcI9JRXO0}p76Xuv zoxNqad~g8&^LL-&fB)$R{N}SK3VN0}9UWdHif*yE+9t4BI1@`|Oi<9<%WHRm5<&0f zz=xAlz3nl3+9X(t8}8-liukw~^owFRCZLaqiH57(Z%0Q*u)M6J0NF-VyNxI@rU5P! z$QxtyggZkvRP)@Y;mb@;MM+*B%EW8pYDT45dEi>Hi4oD7TFDF)KeMA6O_bvFl--~C5%=O@eG5-5pBv&>`~md>B7>YtuKbcl;6cMpX;;ZCq~ zpOEL4gRwzgwg~XBmd35E7${p+^d9!+@RfU6o*9cPM|R-TTW9f`7kBaf)4TZW!DTU8 z2X*b<-W7G&(A|p7y`31{Byg9ubK_cVI|kNZ>xLdx`-gUH#`&Y-`5oAa@$G{G`PJHn z`g<_gC+BS1fUO(*Rp}G-L+jS60oXRU9@{sqm+SONTaSUBF7&PJK%aO5UG1%CZ*D}T zfS;ihhF9!Nmtn?-9|-LK9zXt1{{cVwoBxcT{HOnjcSX@>iHFlrkbuhUaLk$Xo`U}U zU;I=npt4w-tH7NF%#4udm;qz*1Uv^|spz>S?70}YyEDs3h~N=VcmCY@nnTYRJ+~$% z3q|=kYHa@6&3gir8kkzxz6BwB8iLX)oI7(7XP91j@~o)%Ga8#Wg8tO;%h!<8EkRsFU!wFoCd5E0~!*7^!$B}OA7Aw~qJ zw{Xfuo+mdH6cpjWf#bOUW{FHym60!Alr4P8$Gyt}Z-O++tW2L_3F3J8L; z2u-F?78Fz{#J~OSHyGWy2bZth#Pb)Q=`7ec@9}4!e}ik+?!rGPQh`p0-?;S@=P%vX ziBgQqfBMC*^mR&lfeywpUO&8b96qAjnTbQAU_1cwKn=f-il2>z&@NrOub^MQX*-hT zvn(TVUkpY;X*HY$^c;NWI@FwB@lJ7mo~UqfQQZunr$S)oq2;4`XZ)`qD+}>aQSxJE z>wr_SfV{1-Q7rlz&9GtCO?7E08menl&F70-Rb5`D3uDl=j1f0DQ95jTaw77w(vg#q zuCS-;$?LQE%Z;YTK;_Ty4U2ZM-a27V=re8~>>r?^3|AKyLY0V0G$UI=Ncor-c%)sL5A7a6j_po%% z6gUXz-E5YM;xR{vw12Ad3Ux5s_NZ%#dE` zB1+s=LGNj2gY}*DczErQ4#a-<@-iM?-z(}gT9lR*?3YazP*0aOOa7O+a9BE5j?IV7 zlDV*3I!~H_{?%(6dC%EuFCwFUn{x>i0 z;k)N|@Z{P_oZ2@caBsuP=1Qz?H^ANib%DFIE&XdT(kCz%h;I=!w^M+9Xy+Cj8Q(6T zA5w@D@O@qF*tk|;ziy4TegXKpmF*hF8Cbm%I|lo)e{>7>Y#S2Azfs<6!`jYPeZOy2 zr+#+0f1Q4o#$n@{RajnGj_AMuoe|6O2fq+yKjpojBGS)U)NC?}Gomnk!q4%+FMf;( z?-^>`aDCqh=@;IP_VAW{PkTFoqZKm66Abh5LWrn%e;2urzTSus!DMT(OrIA%L;j-n zr%#`*#muPaXV03C$&;tS&fXcV?L7jCN60NG#iC_z$LP(Zk2%=6psb`C`}Q8f`SYUg zr7>oI`s8`piUBxv6&KIk6vH-%(4c6ot~ztp6xq%f&)*Iap+3S7R#&xFPo%M?N*4pa zbpAXxtXqfXhC1}fy{aiMK~qg7x>vNJwXO~gRaL03sl!T9!RIer6JzucSFYd1O#yx1 z`b{Vo!&F{gEyki1%Ntk7c7>)tmX%kby1GFW^`OA<25vogfo-Gv@ZiBq?B90`sVP~y zd|pXWg_d^Uy3CpBIlAaibYvV-k}@!`elzahdm@JAHlh-eVJD(%8B3Cg;dByDm|*wz z@e{9`dFqZo5>)qN`cfPfGrC1>LE&$&4Hx43ZOhK7z9%HjT-_jq9AFg6SfAt5;n z8#iyqKmWJ?h1>U@zn%@tjGJ3`pK10Da zx#DIqG*Bv#&lKpgkQUWsPI{_9CPk;?Gd5ROQGxudOoe=Ywg9QLNcQ7(HXqe}VQ!ZG z4H^<|sr;EaK%>IN1PFMBdwe~;RL#>nprR+}IZzuN8Kw1QLgoB0#;UWjvH$2%oH%g| z8L0`VD9%TJ?@DZ5&$7ggs4q%Eeqs>fd~6WnumB-;Cer32+1CPTfi{S7Uy3NV#Rzj= zhyc4eh;Uts!~kd1WTzlADg-H^;#GJ#!^M0dEJeke&YO;9v!`O=l=rb<^7~jS`;KOd zG-SiDLzq0wRYj~#Vuu-1KUB~M1^Oa0GXs0~?ZuXDTj3}jijAxMIEy#KEz>I*zA-}H zK|B~$`O;_vxO^au9>+M!3JOqDY$$s`(Cd1!>FJtU8R_qjP;oK69A6E_3M_n`Y%#p9 z756Uh$EOcZ9Fw*Rn zErf&l0=cFkT(fxgBux6{KM2HrjQP_hXjup#y&{@OobN?aytN*F$1dHi+u47qDd~ zCm=mOM&tTU)}|r^ED#s$CHHa;KKjLvFzJJLbwO~}-(hGbTm%+Z0`n2I&Q+kDooq z^T$u{?D11Peezt(1Y8%d#>0ot zaQgfuc=`n*EH)MvVwBCr!=Q@ylIMs2BUQbpr?;*I7abjop`j7v=NH1m-A5FD7@Au; z@I=0Edq)pCJ6B`nsx^p@PkrkiGk(trQ!(*rh>S@_Q_D*1*?&T3!yY<%4r}{p1adU? z&Vg6L-CqnUl{^9O<{6}ewp8`T!CIzRviu8GKXdS%T?66d;-_JrxP)vC?YOua24Ss5 zBr-Daj*o|^tRR9k4upPITB-t=kmm|8TnCb>JV}%`XU{ULqc~HHKynHSGct8@6mxv} zK4)u|7Zxh?8AB%Mb23tO*|XF{W(P1%@2wq_f0KWYe~W*cuX6>4RP)TZp^7KqS-i^- z-}e`Tk&Ijcf4scUfy~6D6r^QjVfTRp;%**Cd`yHGoHG;UZ_T!=$Q z4r4`oo0dRuaB|dDepu_q*49?x&PLEP#gaD(F!5Rz&K0FTN4HiA{rLiY6WEHn=l>e)>7a4>=^y?Sli&R@rhoJcId`V0 zQA<_)3~AZOxn837yj?8eD?s-X_3k53XXC!FyQP4O%~~73XP^L{jiAqr4aBPYB3wT{ zhF`t7gFk%s7{CAG37*_Ig=2e%1g?!(E3Lb&4y)Vh1+Xgw_A3SMoRrt6YMg_wLsa(b zdt`sD&Xn9WvPo6_-q8`=?%F!2&>tD-RZuf_&(DqxZ^YhhTX1xI7fv47i(~u7ab(Xf z9N)hO2gkNypD6t!dw1gC?(I0Vdk2p19mk1-<9b~hgHFj z@RPsC1OffDi66XPCzp!eNBV@X0Njt6HKNqhV`GpYKn?X~B~k)N4QqxAN@r&^2NDFIeDBbuQO)^?|*Ur-pNQ%*``Eo8dk2#{DC7;*@c+R90>oHjnH=wHR3r-qJ8| z%bBxmp57wZqLRhy@P(y~i(Wq{I2;Lya?IXAL%;7Z&PNxJDxQsv`*mhM7=K4*@hed zb|Lg^MAb>hHYocDZHeMNP~97|Zj8rM1oj#79fE^{5gikU%&Z&?jtt|(>66ILN)tt& zhx&>FJh^*S9=Jhy7&pno-HX+&wW!WZL0N{VkCbSnM))CIU=<%IYRSbK_M&7>1x}Xp zrfIWUI7dSWu>tN#4f97yS^`S46Ofl4iv;=iA8`in8$M%gYRKV&mQ6F&C@t{bQEhk>o6#Wd|g+w z-uFJ)4y6+}j4V?cO5&V&@hd*tJb(fwLXnGm2yTcWFDm ze>YAY+=H`6_T%D-!?<+vi2S{SICJD6&K*09vqul%%;9}Fd1wz#AK8cF2X^Dk(fzm} z=bk%$P_NsuycVT-87R(4Luy?~(n6sg z6C8*Tc_uSN1jWj;7%pl*z|B=#kO(tBcMin5YK%T1J{CUGFD6X*NY{&{s$aNZDXeYm zL`eo?+vr{eeP~2H%q-uI(R1m*rAtk*c=1xqo4*M2<}O5DZV^tNzMzw=F2922+BN-f zadAgSM+c6cI)PK?E@I!lV>oj3l)QgOjKWo2)opZi4E=o@bV8E1hz-_`;ez-q8pdNe zTvyeaNd?aGz7L$a#;TmdxHlVX&hWeh@mj-V%Yo3+(sCq;pi4Tj2(uJGI=XrYlwC2ja~Ga}@f}8X?nh*FB2tnw4c>ux8pltZMQ})@ zX5LV}zj=>Y1BZ)_u+`KwizgI^H;bfsc?AgrJdu!)f!y3uF)RThV&$HRvZtcwwzF%! z=GHR>las14vP<+mf}Mt7RnG=ox_VE`qFdX`cNZ_sO9XRfb{4!mJaruK9Zy%*PVo}8 z==VB&!>~(6ax!AW!%>`@t4cj9B^fzshQ+5d;^P(gja5}>swhX6D1HtYaY9FWQoNj> zqA|GI$}$~%<-`uw%;uVyR%T0eYPpq}sX)veOBXJ{tZ7qqpA$b4#DGw_Qq@z*Gkg;h z5vkx03kpV%fS)ZfF%hw`@hA{A+qGsj&R#f=6|K!UerT^ebo=n|&Nck{yU)bk+=cwC zWF*CiG7@FwW@{#j)ItXk2_=RZIMb6`DpZCejBukWT{!&%xCp4C{8(PsRVVe>SucXw z5-u$L0p`eOsa!(^d=-W1TBBp@rqzfM<6yRQ0sQ^Ev{uNr?c22UL7+UiZt}1)Ttj2U z|HHz<0*=zDbat#Xg5Id`33;k}HfA(M%L72KskypFVBesiuM&4sbLg2GCilqC)sS(+ zS+Q=`rt;k#Fh0_W`&akivqxv}_4BJZJhlO;k-qTapsRr1UKG8pD00jB(_t=vUOHzQ zmd%}RXbSzA2Jp|D0Vngt@F36y_)F(Z7FGXq0si|6dWLp_y&T2Bn94nzrN)7VkSgEJ zZmACPy4o)J3-BFG;pJea!1ou}2Qh3TuxEU}Ff|;Ty6bWO`~m#-ll!khfBp1cf$wgC zdlmZEtUzCP3)&jXv8KHN1M+%w^Ev_gMp5ql+V<@j#G&zR0^~9A1V(X4Kui@*ARA%N z*T!Rq$47B|A65J~PD_6}x`zX}hPXb}Kb8Nc-fnE{?GnSXO8$NuHmq5Rv5}3c=$X+| zQ<{&QRCz9feG%a4tc%9`xQiEOwhXf-az4T@FlWX`SU8vK56{&}QI6(ja$ju_;qNQ= z)(LSUymI7Ot0z_Zpa*F2OR> zMWS|HQQJ_9{RfVqu%HwT^~=%L)}fgxPEIZ&VC={yM3N#(?Dt2yTDB5K+;7T5E>e7=bMdj=6jI z2q@jOwu_f2XU+yS)?tr}P10k0kH`2POZV~`t}cekjx>gQ_Z`BM7ccST<;S>i?HYzh zM^V3`6}IyK*oZN*69Y6fwikDve~uk{k0B;59fO;;;KhqCaqr$Utm;||H+LUxRPS%z zW9HG9mQ|y?qE;8_*ZQ&hZ*i;qITr>7q;Uw$PX&6wQFFgQASi8A-q5Dr03 z&@(pA#;_G@?QI2~eoeW3=TYC!$uAdqbJ1$MiH&^XaHADnLP+7y$u&T1>RoyXjosh^E>q zH4^pJ719}91&Rw5@Z2t#J4>^C>Z&SGl$VWUQ6!;({sK6GfPH{OvQ{z?}_XD9u^aDOc4}-a|(V~pcm2;BXtJsqL~w6GHn9p&yY4- zz&7Q5Ocn(@Yw~-TKYgOWaE5{{S&YfX-cC`Pjqr4_g{_sTs0V*k$^Ux%IwuPu>>th@?! z#pN1GqlcA9uO~1_6t$};dOJ~wW^l7vhQu&e92#ANhgZk(*~8QL>e&_S80bJkhzHy( z7r|liT-Z~sFPH_3S7Q)MXAA75Et?~+wTa4q)htYAiN`Zr$0ay%%tXAJ1#)kenM@Z0 zW2T^IzIA3oxO@*Yn3_z}*u9Iu-pOJCoGce8>|F%>gulD(QiZ*rqlJ1`2GHB0I6V?O zHni(xsW(A??bIIZAMHn%fS!v|Q_-(%u0~T;0oohNu(qQS{oO0DzN=NXZ90jH*)>}? z^$LX7>cpzi%^MWzg!jN&R#)x9=Jh@D`>n$I9uBmwK=+D9bT-#&>ymw{^#0YI@_q+a zwbWy!wEoo{^12Nzb!GB>>U5yCrM6tWT$bpK6!8;^L{alB!shScB!+S>KK#j#F#V%< zb>=kV^A6UQ@OBnuD~jGlj58-~5$xHC3G&-!Xr>JzPet!9!i=B~^zqV6IX`(en5jm% z67-WNaS1``-%HHkAduQIwjY%I&cj@3vuBCN78s0* z#zukOb=4#0Myo0iYg8hkf&?KNO}bf0a2L~>JFkTb8`v= zwuu57N6qcGu&_d6d=h%PR=-yDggPNlHSgyWAjkalIBV61Nnby93<- zgU`SER)G4I)|r3t`R5qkF^YoHN+hLcV`SGj?mqh*+jbvCa%zrFG<*KybL`x;Unfj4 zG}GSEjdgt+-@3;HJ!|3cJ!arszj0T1(1?b{Rz23z+NrVr-gN_-#ly^Ymv^ z1Rqr{75`$B1?q-mWn>~SP;Rb3GAb$xD_3>nj41lUM~{fBSB&9J8!^6nOgdT)qB#jH zG7|au`QrYipr)!C^|iHH{LIZ&I-u!dm@X5@3hb6q)tj4$TCzrLR3JLr>X8yJuyVA7 zo4vVC2FXiHMq*UBDzIhq=fGsfG;N$N&+qT=<*t)nIECKc+DhZ|>(;Hs2?2eM7`BCr z7hv&Hxd-x4q^G9o|C1(aoTUy3cS4@fHxA75e`oGIy%}!fBBBjhH^s%MFDpk`ZUORM zW!%KcgBK~D8B4=5bmM5T4Bi6X-1tBo*xrTv7kA>*`={~6qx0xrStT%WQt%SiHlpac zrD9(uYJTbL>Hlss!rpZ5Obu_bpc@rG!!#U_HD54O)ayd{xLS)4$V5W8AC`!h!~sYr z@r*de!P&!vyNlH#xQelG7X#oe9s=vy7-1jg=^&tw!0w?HxO;XFekY*+)0YJO1Kc>h zN0j;+tnXefYPuN%s|B<*#i%UGKz#*6cX|4^Yl>+Qv*kYJqN%b#yr3d9R^+3yAXCmS z)xp_q8+)Zsm&rL?JU#=Zc_MHMGEi5ZukdbbtVBa)q2_hhmK7-E8H4XwUajZ!u4+-^ z(bG<&P@{%`r56gbQjnD_B1Za5a!i=czDA zY^E_|PP@Ny^FD0sT?CYGmq1`$B{r7am^W{psQLN2P0L7!i(I=)gvs5zcd@#wTSW&4 z^-Nd_da1!c@N*m=FgBBU^R-k53-bAT`>L8R$SZ)SyQijrMudgyz-C9sO0>4N325zA z(Q`o^dmDQV<#@V_K@+7<(6e6t{kspeMm*sh5*(rN^0>G}5l1-)VqBc5ke&j2`5O%J zu#gu+K7_wf-Saa9J7MqY;;D_txn-#co>!1xg5I_Lnr3?c{$o7<o`cA5-ebajcz6_R*KXAE2y9oc-PW2o ztY6Q1Ioz^l4k7>XCtoV?Yie8IBFdj2-#D~W7Ysji>^y24J80^lgp>a!XbJ4&&mX0sdO^nmN0hn z-3hT_0a&}T6$P2eD9g{(0kGt_NUirlV0yVaY57&sNsI08eLDMAyEqiNIxH^gZ=-*8s+>9E6 zwxAF>>6w}ll%1ZTSwaQ5c_=O{LTz;o)~)Tu>C>m>$Gw3~gM)hW7c5!`YinCXiUMb8 z15fc*v^4Q66;IGJ%Z6&61GDsQ7|x=1lNcR~B2iE*V#chSB5~EyW8!o+EZdu)cM{Nh z+AKwJY6On&>chPYqxkIJX?*_Z40>9M1t4~CFq^OGqHN}($PJL6iY2qA{hPLU=G51X zuL*tv--2;wX)Fa{GW{dW5f5qM?1`%EV?(^vfUsGMF=6(So8@A7aNdC!1XqDSy$XV! zdGl-peUz^YD)VBoXJiHLogdf1*x!Hl5Z}MJjcX^yv3Gl)sPHyX>1#03-;KJ`91$mJ z0^=Oil;)y1D;Wjp3CK&0m2I3(=qbrgLTOHlzQKPF9)g?J<4AynEX$WWQrap`g4`^s7KO+eliP4A%^oF0i zBT{0+kro>v-pw3L{MnB%^}V0#N?LQL%Y7BW;AAELwCZu);^~Ro&G>w^^m+cK zQKI5msgnb=p|Z~e31+EL&2x^)j2VX1N@m@dED)8xaG4Gyo;rI)>z`ZNI2u-%dILg) zFZ&;7)e`bcS$BW&B3?MItLqQLl28Z8ck@Q_2 zH_qgyunLoY$yl+6o4Zar3JMZqm6@%nlT`9tP)Ao!6J^hMzK@r9@S^Gi{eyId>Y)RN zuy)NlRq++&HE)G!TwFLG#TfwsL7G9tYkPQjsRuxqQ?(Q5{EV&K17jG6$GHj|OA^yV z;NU7ffas`rBqpSa+U~-+^OqI!pM3E(UVQeI!2e71uHTH5^gP_U^#~t-{Iw|Yjc^nr zQdw26Swfr%`{q6V{EKgOJ?TxGw&{BW{hqytH1D3F9KI&tjWz9Q0C?Vt72R-S_KbUg z)~WyU+uw_Kc2Ki(R&=aYWzV$C`xS{gXJ!c(Fvu0fQC?hxP5tYUARRvxaZkR6os+y%C#;(2(;gT_!62aih%#Qjc9 zz^>6PICK0kUOah>n^&*n`lV}HnC;Tpi#UJk98PG}zoR&I>;z8A-#T^bjBYPnxP*%r zFXPgsD`K%9<9C1f1KK+~FnjJC9SEaB;={m)f{=W(igP81{PlVW03 z&9jIZ*NIJyiAO?cxGpxr8L@-{WAwVLo%vD)ePwnW&h6iXhnMyU=+ENQyC=|DpRZXi zEHgmBo6Vo5jgVhFbMkAL|260r%6kiDOqA^;QR-7)t9ydpSqzKKQWJfTp&X8R#0GmI z$irU$hWXs7a9lPYPNpUbcq(~9-ottc{GAMHo}g!(J~q$|wMFsRzpVpz&hFA>Ab*hd z+5IcHbc{942eEaq2M2eL;K0ryG?cS?Wh$zQvsHZ;v0f9woyPH`co7td3Ti@|Ag9{S zOo~BzLX>#0VLD*SmK+tTEnP%MdV)L?uNpz0n--^^Ef!-@QJAgI09F2qhAOP-Y*FBE z>|LpSnSzL*Z>%a2f#ZkBARkyRnul4FKE#Bd{DY|aA7l2kkHqs6Z%TeA54zf-?3pE% zCW4Dfo*~l4@-n0fcxePU(4G_#4lnU0nLxp?E9aF^But(>Srt7?6r0Rntf2Q5ke$1D zLrdc>T59ocR+u7u33<-KX4!0}`p%g%N7qSUV@8g(wY7>5_CbbD14S)bn47{hNNW(ZBl%=}Y)t*GvGo(XR zPx#ZAF_WjIxn1+(32efcDxBe4!agi4LX8JQxf~046X*neWJIjinoo#Nc@2HW@HJI3 zAXJa@Jm%mN_=w zj|uIyYX{KZKdeffWhGKlvvf9Xw)`y?LSxv5;TsOvW@P5+LL~tK5n95Ssg`5oNATUR z{;VmPjM?)Tq0e0UQ)jQCp?Q@qPx$!R$2fB0lq!09WCT6q^e!$g2GDc1D>F7Ym`XLD zCY`(>Ek)E~nzq`~d{y+U1Xx~>B`POfI(w?tm~X4Ez)k^o$MPzjYTR5~q7~-)R_5a1FZK8?df>1$w($rL|y0+}{(2cB4UzMr}n28fz*< zK{sG|eGT$5(_d9;EJJZ#w${QRgsaO-v>020eD^h7opS9pVl-N?vbjON8!K#zdtFn9 zn(8`H4=q^L*@ecsCUmXrM&G&(=DcbCLsX0Ao9LF4q_{PNtt?;X(Wk~I zDC8T;D^OQbj?}0)1w26?6&NJSPaY6A4{&j6XYo?JY)#Qvl#0toM)2(V0etoF0$$uY zh82~W3Rl~uqQnL8rmWo~%>a67v!-D2Y(q1Ed!jZf_BXeSXZ=Op6ZQ_~i($2Rt`6L? z4v?ED_eg(HYSv4!Y}O>0&6xtHWhR=hPsq~{dC55e&Q_}A`JF;NZFT&hr78`FcXr|a z`Mvnz`7MF{O?-0q63!hO#o_TG?A^H$XOHg2h2#6Ms<|2!1?j5h*-wkIQw8>^qSOr`+HbR(SPl^tGt0hK-i17?ZRzeK2Q{qL`M2QFrm1iSDJ`*LMjnS5ymY}fb zplfq&xq_b02vt5qI@~75gsK1v_7NlP>n`_ZiLP<`v;XoRF!7f^!JO$6bs%=Jz@C*f z8GmQ)e6T>AKqu^1)Yd5IIZ=vn`UHV{SfIa-srh&kiXu=H^ivh|Yz*5F_R%p3xOVft zmdBm9K<>Zk+qG_HOq-7RbLXi7C)hb=v|zykn3#xHAkADnX~LT0V}w0bJtr|b+uLK| zym<;hea*1XcHhHq|;CLpL-KtS#^F z7p$+1hQQY+Pz?ZM`#hJ5o;By`E%3E5+*46egMIssAYUNN44bXn#xyK*=k6noyFYpQ zF+Ta^8+`ux_ix=}hG}y1O2ueIVsvzmreZRt&#;;uznlCWE>1$=Tk?Czd(6GJwRJ&k zT)Hky!m7}**pT^S}%eToNKOXhb}R6^T9@nO7N)>*MYXD^nI^vy{#$ zpz$?=J`h#qMMxFzW@GmTTE&rho?f2djYyk`6{UH6$cN zT*zQVL_}y-O-4o*mN&QH*zrTyF*<@YQH8#K9@5#I#ARfsa~8E^s9Z@kPxZvc2aBMm zlHvp^#^}=%lXM_;{@`AeT1K%f}UlHT?F)u(YIA(~0x|ZkT^!|Q4yLMF9@cqrl zceDyALBD^;fT;N)1^wky2hq2xS-_j6UMH1yadw8Tn3kKGsIhT|PT1IgnGM65Ee17D zfJf^-As-hWh@{9cQPoj8*@-PJj#Kc(14xw5=&@+M28{_lU3$43nCU1Uy4C{64%E>+cZkF;US9 zd+sNSNHKb_#w`t1Z*LzqZXDDYJ;OE3xM8*p!Os>T@JkmJylu-Uii(QhCSG@LZYF|* z1L5W6B_MOw@Qs^J3vyBJy^O?c;8~hEU+eIf6_#q;lEvSsvR$2ARjC+aklyg% zN=Ne0u)KkfkNh3!d{iO@a=rAlMCpJo(&0GzFEDm?l!wSh8$&gW&lB)(g5H>U!|#v4 zBFfiQXWUZJ8$&ppoW(GXrwtXo0rFJz5#CNniSWki)?!>dx*4C}KZ8Gi^$36Z@*#eB zc^Bso@5HDGh<&3Q)u12Ww?o5!l>++O5>eB|T={=l zuo+@mV6s5NI8^8h#Jl8{eNqQw1?VPnJ_QFuj08Q6fiZl;Yj9wg;Ai-T*JHSb<5d(i zzCK?1KEE@c7s8%fj#cg2Ii`ST=!PL2Uk@Jy`354`Prx56VoJcz!CilWn7fBFa&j|} zDPBGkEd2eMkM5&|$2fD96($LJqe|yKjh|7y6Y!Q6wy(oFRPT(@^L(m&8UluPj9Y>} zz&}*W6KAC7BPl6MbKj}bsnEHEV0n4HfH_sZOZZ#&*j}z@Z||-+ppOfPG%v=yCk%hfnaUFCXK7{qwKz-~aG6{*P?` z<+oqp%V)Rn$M0X_|NPUh@!tjX|L0$Sr;CI9?&}x$?HAARXMsM;3jg-27lvB$-+!jd z0RHOpr})?3e2xG1n{V*v?>@)>{L>Hkok0DM0{TCG_Z9xvAAgNsfBFo+die-nKfH-= z9^Jr~kFVqS_!#0vUB?B5Auc!)8L`QT4hWNNA|m|+jI!_T;sNs|%sgNrF;juJj{=pY znDa8zkRcCsb3-i(1RU8}hT8aPDQU0M+BlHpA}%J~M|L(=xAXEM?7a;2GGy!dDj%4Y zD7{6EIoMlE2Xhb=;i#1@SU|MJ~4{PVX@@te=?;lh!f*fy|IJhnAB zyk|3Z4)tmAEA6*MxjGw_pyxPKq5OsfeRfK$fI2}#j@88+f65UUi)hJA(m~l`5it1~ zi5iw+h$k~4T7-|lB|aQkNz!)`rNu`G=;P#>NSDv1Xsn(Jp5p?{%wfoe<5g7o1V3}= zX#~7o?Bw?ehTXCyFqt(S=HlthocKN#natGmO4gqz=pD?>bV3x@izV<0cMiVNc(ZIW z^Xjvc5;V1v>k<&88fRa)P(eRo!bD7+G81#>EELc$(ONOL?mj|YV=K%o?WAA&z6BwI zoK-KWzzJkRm~Flo0ESoizNx&&e#neB!hNB<$Not#z~~9^v&L*2zFzWboXLG zmNzzt>h*zxqYbL7#Y30-6ChA?b92+uXbZzKxnlfuM( zkBCB~sD#w;I92uWT)0=jZf9w$s@~en3SQ#=5%g5*oIJ)lKP}6fkR|GY)6J6-tpnGcU*q-tryNOzJb#ao;BkrrX>~x2j z(O?8Ux5j*W?o-k8!RBBrWAs{QC^rwym9=Ontw2t4lBQQu(Q|bv=Fzh#mZzN+B77Xs z*HMfsqKuzh-G^_VvX=W6&1R9NJu)MPb$r;&=g-8ld4^f7Oq*n5oSsns_dx&G z%?N#}eujPcSx!E4w=y84B@9A*+y(OU@!n7V4s&!?>?{HOG_6+Y?j&xur6_*sKUDT{0Z=3VOB~)8`1N7s1TT5+$XTTDh{Qv0S^HI`xqh4zR$kLF(Ja8{f}WoLY~UrsP5TM32_?>Lx~PH8UQo#jF-$`q@~CC zc~|M<<>F<1`{gJ2@{=dHb>lLk!h^I5Wms^q#^RF_l6A24%P+sd*w`K|j+iInB_Yrc zjisd;wi?~M315Ep0%uPjM@Cu_A|rwk7UGXYG0368{^)3L!Ii5Qv3hlvJey(&MPL!w zRPN4B1`%dZ>0(F)w1hWd&yWrGsq~qB!`IyB=Tf+!H@$uVFbza{TDFFM7{+mQ;OFf{ z#V2bWdWK;LaH{b)?=drbI5t3Ufrf+Y&T{aV-^1R{MZTl67>i6D;H9yk@i0Q%+s7Zp zrA6wsFf_&Q&F|;zD-(da{9}_vjam|!WhoiG3L?J5WaI-T;EfBx8vBZ5gZvC z!f}E0X#pnTeRS6_PVL!>GxGYByypJtecN&Fz$nhjvD16E;f%P=R|LS^zjACG7Y^;j zF#+w_{oCalBREV@3*?XQ9>(!qL-KbvS zqaGdQdB}OaAK80y0P*w@!{b^##z8r@SH%!2aO>ez9#6iQc}V4 z2aV+wx`bd$bsh4>7!mZU=tcDhib3I^o|nCVUexjC)m6BAZWJ$X9mdy>&xpYs6o`m{ zQqa#KY7vW@&4Za7TR3AfOhm1lO#8QC8)GBjjoUY2&#i^1SPxrs zq(lazG%E!OA-?jrronvf6pht$yuizD3H+VSbuczRIRrz!wYYU|48MMPTNV93ee(=o zKfR8#hej|y+Kl5T%5nE$E4FPdL3LS*c$o4Vl^19ThdJ?eWw}^hT?~qub)8Ms#G?W(VqV}cP>8L5nM^-`{{G6Q?^e(m*m^XD2 z-WSl%nD`z{W>3XD@tnBeh!OPO;^jG*n<73u6e;3iGo_Nt9)^ivVd1mT0AHPq80_b# zgQNug?Afz1apGi5nm84+X3i5e&zY%qS^<)&m2sjv7cVgv_<6nsp#}5iVzI!UYu-{+ z%olY}SQFZO{bmN3as0^GN7*OYH<>iRW88X(XKT7pjKJb$;-T1z8h1mih@#180P5@O@#M)f{P4rC@#5)oJiPw^+cytmWnDe8qoXmcBI@Zfca|dl2}9 zyn`4C4_9yXSPTZhUFQ|B`X*Jpt+2)3UKG9X<(-oP&|?BwHiGyR;V$irbl?*^4a)fR z?h)Pc^;v=aIf43VD)1c}aA^Ag4vGTbGt{f?$mk}8JGZ>v{w?eEeJ<{7Y^Me8=fnt{ z6eWLLfPG?gBaRBt4-WTY-_RNy-?Cr;wbsna-p z@{}l&WBU5snX`JVv%NzHn;2WC8mDTfN+Q&CWi8!zkcY)W9~d@1SbT_B>Y3*oA0$3h zUScd*(X%i+N6R0qY+8Oq4Pcj24Im+@Os^1l&f|Kj#(oY=P! z`}b7g^36=#dXj|O_eDY1#i6k>SJNzOMUgj_=c)o<*V(9xk?auly``@MTi3C*X&c|X zRz(T>B>V0Tf?V1zfjM6v6v1#z`rwIi_UV2(wnjY7bs~sFbR61&8)puvcS?_x-s)cI zhdVb)zw2Lv#*#c_L`Ta1DqfZ-s$fxBtZ(zPzxmHv)NIz|4|HbiT)D4YK9F_j33^8x z3vGVl32@O77OCSr6oNi3G7Pa1p>TI}grD>U_6d54tXIQ{QXhRZ1=FX^#^Ob03i`FZ z8+6f;;P7aeinnSh{pn2zEm>%SS<|P%WY#P!;GnF4oLgR(eU<>Hf;R%5{gC5Q?3e7n zGywDj_#TY|pBsxMW^i+Gf$7`@2$jB=D))dTB%TW7Z(KTtXOFInx_^#9KlvMC)EaAR z@aI4L5ig&=!2O#yargRld@1{xQBeqYb3}1k9A4hNAjfXv55M{t_imiR*B{?SadsS5 z)E9|ow;E@Uj_G3HUw`@lU%a@deqs|!An^4JwlSN31tq% zGK^ykdw6x4bstOOJuqc=H}JJVXzH=hJZTJbs>_cd&O=&@(i{ z#xM^DY6*HZo^C}C;QNFW>d>;beS^gL9(}3{%D)8MH{t3`h6wFTI zd>!t;b3&B%$=#cAO4`Zs5mD`1w4FaVs#`*ujlkYF(uV_E1;`Ao$o}rZHLo5B!~1-2 zc$}}_1U>)8X;I#M&4Hmz(&fB@EZu_^oo=E>6e<3l1uZMnl)eh4;O zb8Aslp4tfc)c8acWaVIaZ9Ud?ug0bg1K6{B9HZNJpk;Y8I@;RNzM@Urik4Qa=~<25 zHER{}ndup-w)ij*>_*UYOZfAl;Q%aQ&*OZUm|98qnQ-T8Zuubb!Qul(1(%(h>+%^ugjmZ~#O>yS{ZP);o=PBqpk%=V@*a&qttA+Cv@{VRp1jwTN1W1h88&x|&{ua#tA5G7rCopxQ zsM(L?^HX5EY$5zy?X(V#$TcTg8!(zcVcWKE(zr6 z#h#SDN+YmmXdU*C3}D~z26Wa{AR{UaAp-0`XD7Lb^D*s%U*O$;_&WtXLpO`Xs4kX! z?dc+YLSXM;ZLaf2sP4VpoK?NEhE#-XgS|Zv@T&QFcu2o-)Im)v=^u0E%mYgxOrA7d zLpMvLk6W1AV0dIZuHU|^FrdEq(h{jl8 zk1*$Z3>O&zPlLdI%JbN775a;p!iOb(1@`QV96vfVz5_2F-NcP6C-CUrWqkkjbHqgl z!OhMJ%f$=+{?pI!@uSDMd*vz~-Mob#KK>Zx>8bFyGeui<7XJBHFYw?0{FOlb1|Huz zhyVK9&(Xc23LDlgm)|@c=a28k|NfU>;qw=_@bd9>eD~E;c{b}r#d~TBCLw54yu2@j zE+NmDy%F?;xj}6k!aDp6p=|^{!!|~s8b8nT33{H#b9jvDnQz`>o*xz(rLgC@%;)#< zrjc=d9lGH_EVFJH`r#n0jg5=O>Feqn5fa919UraM>*6GT*G@b``9BDGFFD8ENxr8T zAHJqXVQ1@r(9m#&J!{chS=s3RJ7@N7QxFrtMm0{AV?0h!@7lCRS7G1DbvXyR74TF& ze+_!05io+D+r6T!jYfi7K5#~W9~Q-AguHRfhmHGZ_V6Lw_8RK^42==@4>PrHL=1>{ z81y~}`%|K_PRe&@BjnGDM{-ua|M@*bxP5$&Y!aWOaxkU;Ve*35YR^lguv6z z33jHUp3SV`E*;cetZ<-*H=+VV(B8NlZB5OnEw4n+%2n9DbsL&RO*2z~X=5Ca4Gs*_ z3W98eJGVTpad~N+>||8+d`Jj(uBgQl3532ezG-xo`EVKQ-WVS=UWb`JX|D!j+v^)t z(YJ}BFU-tP&~s+25%es1>*Hjl%J}SoK0Laz3tv7wh3}tVkl$$~GUKGfTFgO4o8R7qCV@!X}r1vrVqxUg)3S;~eb!$4`Pzrg$G=V?s zsBeFfH*+YkR_F(JgQjG6S!kLT7ICv-* zO?8o|D^0}m@^q|iEyK|2W`*w&dW+JxRmeymIVRrW5mDvGMWLS^-;7HKw&R?5r>CXQ zpOkZti-$-r@t7#|W82q@2P?vXihj#l@gi4?XWOrR_xR`r-LgOK6T>jNVI{`I8yH#B ziA}3o(Nvs+w1{B%IoKjzRJp&ve$J$i@XNpdTP=ZLGIKJ_m&}*n+eDPGi^l1xkMcOfjm*L^_FKNcY=IaL zQ*+pwT4-M^%F575kx%Yj!JQjtaP!g${QA3(k(Zq$9;YSx+gtJdi|2T8?=GI+zJmt> z`#*jCHA>Tx#ZdZTePSd0C-~>zeSxn& zzJp8RWqtMeBXqIel!vn@Uk9y~!}v8}OQ=(Mb8EWHQlU=OO?Xq)^Bfug9%Fo+=MmO9 z*#)ZLc@7mh->1r_2SDS%*Sv02WZYZ#*l0xfK0lwDlBr$+W9(G*RP?E0M3{}k1;!b= zv9%RexOi*mCMiX{08bB{FW_j;OeF*8sqB4eh{Rx6(s;>h2l*SEh{ob_9F%5)2o*gu z|K4Ftol2g7C#VTyDsO_Gads+kJ}3nC*v1}hgge2_V^r~kH_tJKY}jZljMpUaji2Ld zBh=Z(_<%^GiX!;=@Gw+!hJ&_@#mfVCnBf{ZM(7`rhmTDS!j?XHpW&N+oRYtPPQLeX zx&ATvAI|R?!S%zta6?qr^&_LWc4!PWIT^4qS%k$i=D>9JLO3k7KuSam>Psq6Q&@`p zRL-c(LvvLF)^@DYdhcDW?E?8KtY~UQXKNcaZyZE%VF`i)m^&Y+lRnrSxn!3Ovldvt zg9V!W5a=H$4{U%uprR<8xLhJjGTSQj8HRDTw^MlQ10q1@;1yL7;m-$$`-D9|!}E2e zt=Kql3BmeO>Ez|rXeg`H+9$@)O(+MFMg1E=Uzie#^N0Hd^kbrkkBKrqhi&WXkRIa( zC$rhF6+QFanfLxC=neaGHG9UGiDMj?{rB4c6ZDfm(8kb@>0G9A&eBkhF`H-Jln=0A z`UhA%>myh$oCXh@MTqjXL+^@WoY^~o2j}e_>Q!Z@}&$F63Q~-tKg4Sf7BN zRmo_oPL%s0TT%5JI;$|;(auELW2EB z+G#n5?c``bF6e*F zv{x0QI5i&Lc9w_~749x-efkIQsiL3y-Y>CK)V!;BTvl9|Mu5(gNlzCC1JFg`GjzkH z1A_(lfj%Da_cDN-h|Nn*<$3)&ERZnt9{HUHrN*#vN6u#U^5C2HlD}Vgg)D%`Sa!VB00{QR*T?h zZ4DQ(3hwndoh~Itl43&i`2=ul^ZD|HxKDewI zeV;$QsdIR~`TQ|jmsbf;8Rl?PMeFEjQ1ISf0Sa)cd%~BXC!o1+1hO%vPDpd$m7hya zPDOTBo~n1o?fE%w32(yPIPlA3Z{A~`N2O20%WGz&=jge{0bRE291gf`TW z!kl1#QGrKl)VRU^5w)L*i zhh%(Hx5A#voyv=$8!Gza0(Ty#%guARJt@Xu|K>Fs(?2vK>P-F?A7X<3q8O$Vd@a|w zB*uz>zj|;KH;#^BbwdTr=gh(U$ay_GCanIitaC=PY-|(6b%Dm&xeWUapClY=x8xU zIcOBX*OruP22N6BBoe~HwQ^;sxOjmc0tE+a_&J-QFpZ$!fcqCmHAesW{Zpc%ijWrN z3P;n~qM%u0p0MZSCIj597Mi>TdIj^VlEq8s5csdsE@w`yuNN_~K^6Wn+223ZEwC4F zb!Z*7uWQq`ZLMs3SD}AJ18Va!QInU2a8Gfw%}p_P(nL&q|6N^6b|%+|T}HJ`C2S%v z_d>|4tQvP)8*Qvh&y>s%c`rb&!BQYJ1_V7POnD06nU=^2L!1@M)XE7TPR243FMQ~O z0>ZFm%MP44a~ifzb}(i9-^t-E2$?PwqhK;$;Jo;?B4-$e{f)7D4$iV)^1U|)YB@93 z%FIl>Q;HU6F%Ao)?}~U@EdSHerRpI#Scp+rv;YO^iCRtcxyuN8GP4IAv%#ZJ((F`Prt^BROcl|Iko`Nr$v@EaUNnJGYG2pBH0s{qSx9{Z3J2!&uu?g(cIc zWA4PMSTJ=amd&0II}RRM*&*E9ADOXNdhDXVbq#I?(XZH1Gp(RmT?yj0r85$CVs>(8Sh-+F}S|H$e(FcRd$5Px{ ze{XM{T}!1-b@Zm1;sZzc8&fWsal>>^X5-{%Wr><8);xNGJ})&5DJ<2lph_H0L5cTHHSYs@<}=0(!%OB326xU?+ra1VC&?D4Q>s zrOj+U2W)36{29tIHUMmvi z$AuIX3l;G1{^Q?b&XkF;l>0Du)>O@*r-Eno${?-_>*}I&Ay^%jd-0H=T-})7z=&Cw??pn)GW?^i-zN(eXHZ^f->3JPu2HQQaJG`76*bTe4Wx_&i;Z zo_&sRXFudv5YsHF>W%PcSjX5;9c(yuWLQgr&C!?mtDvuP!E8@$=OJnGapHt1N`nIxpt=7H0<#WzrID-Pv-P0+? zb4bG?ROp;38x$BW08f|C8axI<{mpyKW5$qBW=5_K+|rmBWBN2ES($knyXP@}PZwvt z=Zd)aM1+P1!-I2g#6zd5XPPDdAMU#e#HsAL$UA}0EkihLZt^|Yn7&Hb>tL)Az{U(3 z<38a`u%A1yLqX5ReFER;2^c|d4EY!bU3m>QqtP(N^0`mYQ>_!?495`OM&NUhjH>?P z!R@$mWT%4P80z7c#(*(YX6i7$dUjllj$D^uH^k?MbugB%FNj-yZU0W(JiJR3*#@j_ ztX9y^`DhAErp&;i>9etPmMB*faYF_8fv%ni^AhDG7IC0^9hO(sV+$4j)=^ZJROs?( zLj#+&qF!=hijIOCR6SF(g5V=6jEyn-xY%f{Xl=sXyXSHB+EEl0rRprmB@5S1ku4wBWESE9SQO>^k$N-J~$m~=4!1U<_j1jzZm z0u3(*bNIWNYdGWL(M@=Kb+^XoU*0;3uKG-*MKW~52}|=t)f4t}HGE?PJu_nXnlXAK z@GV}cdk)qT_Wv)?zoqQo06nkmBFd6mPO4fk%`nMo{*({p{SO58?<(j`=X?Zr3ln68 zdt+@~K8|c&iQRoo=&H^{OGygat8&pMX@(yT+ZiqP~hIzT8R#RpXxl+=Oyb}!__&dXei7JCJ^9$zAP|#DI`?`uN@4$3KXPy7RNmHy=883>SMe4Z1l)nfFLY{-RgnoE%u#OS2 zWC2qvsp?sao`bQA7n#CS`tk8oXK?7)QCQkpVWAinD;vwVAjD7$LCyYV3>UHy@boI# z7YTVb_E8!F_EB3)OF2g9FO_4n7+lteo>K|RXgpoCU2o#YM=IM-Kx$ieF?8S)# z;&q)J$CEqfWPcl?g5-YKE=Fx}25z1^gd{+!lh-Q4}|0 z;x10U0!MFz1jPu18JlNnqBmk=So$DRAxr?%C?qGPYw2Sy_nDTKg5}L(%r|cYOD!28RG74Z{1_#tXz5z%*!{1eP~>mPfx>8RavJV1VPX5;>0|9F&th# z-f(txKwxly7AIpp9}VHW3dd006ZFQ=jZxhjR`H?$_0(0p7*%+OYM$_Y6Yxghvl&&r zQS}qzM(Fc6k8x1eIM8Yg`|vg2=cpb*!33Ec5%AQ-oo{%T(soZ&t=kWbE8)L3a ztt9LTdJe)K5ko^2PtbEq&@+^C`M_4(IJ8UJPI-{K(Op}Pg_EZ#=oe0&fyGm$lg^kc zU=g(<>fUD2GPqmYYi3SWZZT?$D#Y#VMrA=c8Y&u4UsZ?v>^xmOfgu~?C^)Bady5LA znkVSP!$RbTOB7eH3ZHy>9l!hIW1N*vI*&jUrNgicvl^IH!|CKyN^E?HsGu0GF=puS zJU(;`^AzXjqprLHJ*^$+X=z8JxON0R2V#wio|C0~oE_lFDv+KQ;u@#n`l%5-y}m~$ zOR@YxdsQ-0BgCCGp9cqlyxkk1H`b>i=s9E7ShkpPdP{kjEnlg9qbfHJ(y|fs{|5HV zyH}u3R-?g5Tr?CclR)?{5YQ9$^QL~Npr@*5tlnPe$)?#COweIf{ zRc{15+rgpLs`N+22<%$lE^uFkL&M@lZd!$H;t_1=76Y-i8Qa&ksCTeMj`g=yVU-x1 z+WaKc6(plFBUZNQ0{JX-v*2G2=X5iYdT-(6Y z(N2{-LC<V`<2W@E_!h(X-b7Tq~!#0yAO;trdQ-li#WPSaD zaPjJOa6x)YYYQx1vIu6TOW%SJL2Xdx22Yaxj{6iBgg?DWCJ!*A$k#??&#(D_bq?BQjUXU8HX!V48SaVScQ zz?V<1;e`PF>lb(Mo6laNSp<7uWFFv+JlU%M`$cGaPRI~tJOGZWDK4M^Y-1)*wh49cP9lst5LG%J|WM)&n-dk z;>@tIGt8D*iogs*er}Nt$eJ!SQzg$u-!sy(@s3f=YwTR$Om%LAz7fzohmGeD<^(wv zJsTB1x5fcoBkXAqjBuyQ=lguESvUf8V;F`?oob%j!}52z&%s&7?+JY>eq(wi_t_Yq zXAZrp`5oeU$aiMwhPm?$;~1gO&<#U5RQcomt5A`Vg8Aa&&Y3s~^CwQz@C^rMsp^f5 z&^MpAP@(T+W`*hkuBatSv7r_1%U7TXj|_OC#1X);Y7bW`NS_@gE# z7KMp{$c*$xZd?FL)1y(Hn}pViTv7E5-BhBzx&X^dGtgF@jb2gneX8gyF+@Q3txz~q z)o)%|r=Z_0>V2Q6`Gdo2bdClGSqXd^0IGau*c{!~tBQWlK&O1R0o&FX48&I1u4^e1 z&!G(6jisnBOhH9foPMv`{4`W%C1Y)Kt#}(9@;XQErHTBnQ!x4cpKFbqdDAANwz3rM zElqH?wSljjGh9S%Gi>8(ZKXABD)Vy{_K|+R8nfqd2MaT}iNWymaMd!!Ecfdm?ZXd0 z!bcM(Dd^|VUj&nRi!@ez?fNYY4-LyhzgTnT&HidImht&zix#TjU}%u4o_&*`XV{Pm zp8HhuJkIm9@0yy52(cGYvIuro<{ArMvQWG~QSu7~_%uZ3@;|e%ov(`xUOv8o=l3t+ z<42cuz2AnCG_=>|qhEdtZohhZ9e@7rIezu&L;U%hFXVm}B801HIa#4z4EmEhC-K{F z9^g0MJjCz5eTwShG&ox?(1mlV3Q}<6>_PngtEc$-`EC5mZ@MPLq7q2`-VCjMQxHR#^lQo<|#ZK`0GvUJ18}ae6C=f3# zJtI{iOC!)w-=basWA#j#O8}^RkrHd$3BV%o=Th9JvrB041SXtW0|Kcv7FA%sFiD9wSa~RiW zw$3|*F9A)!Grmp`Q*|3vJKra~32q)I@CokAM|W!o$EfVN<@=m)!s{7d^V~~EcIo-N zmS*1wz?rF_Tc&Fc^x()g`5W>B8Pz@C=in>DHH16WJq-k3Q_*uEmYEcc(^I_@_5?jc zHiW%`e$Ozjh#{h~r}EE>jlw)}Z|6;!DzImKc&0pnv$S!aZT=Llpd>JswqW`Ug!%X( zB{CKnqT-us8qn9%i=IyL4m!HDg$0Icbw7JMxzPf7#_Ksa8yXUTnwk=f?(D-i-`~dL zCzp^SZXh2LYjaUYiws#cggt>yC1re|2z}$0hJXXH4Bc=5x2mvM%M-K4O+k7VvXexe z3+TCwASbB!$OB6C=xV)GAYq41t84J!@-BRO?=XJ-@-m)XJt&GZ3ejQ&Jgn!z-;oAQ z9#Vo{WA%onlbL1G9u(*^LG;1`=C5C zPLy*hI%|s*@&rB=b!~ybzcN!nzhPw!Hh0xytElj8;{LPoHC6rSx)lm|HUgbnrc&+| z(9-}Ij~(4E{Yiem!&^ms^tWlq=J-yEk#4MCQHkDGgORDtPf^I1XU2;GN|9{>ic(`y zF2FBJNrcm~#hCi;&%m_GU;N$QVETmjv94z&c8_k;EE~q>{oP$u&3o9{>VhMjQJWy1 zA{NuidzX5dl3jVK_)i z1^*_5C^~qIeT`y*py!|~bL!bI*&lg~!h^?ojA0#%Wy?hA+vu7NTnn0Q(R}FxqVVTT zpQ7^u;=@B!(Wl0Q;L8_xap&?eeEd*gfA0bsOVd%76@x4>+AWpY_~P+ZeEZ@SzW?|h z{`>E~Lsd?;dO}>FCQA(by=#Z@t1s{3yU*|7zy9tsRrH?HZ^L{XP?8mkr?<|Cp?ImV z{~v$+4qFG-AUTeUiHLXWE2=#pSVJP79{#H6g94)A=^iAY_tD01j)NV`9Js4GH)i5+ zOCbA+R~;T6hTsr?0jr!Vpy&I9I|o-i+~t@6nxN;R<8R($f}VzhG5yMlS{;xz=G}8Z zmYF)NtVyL$&=dZIJYmn3^Spe-tMKuLHOK5cn0jfipyxOOy$yoi($ZST4J^#9U@6Vl z*I&at##lbL?-1f_RPl$lQ@sxf)JFu++qE6$!pd@-irlEo32{yoA;66#4~)v)7_T>m zd}tty;U2!vFwcRJbqaa5aRL96nDsG3w{s^?dDX-S zNSim6>U5SC2Xhi@xon=e!}3F1b~?Ap_dv9XO<-q;bp)@NGd8rvpSSFK-3CyN#8AehH%d>@m8r6_2itY_z3^dZQ*U8O>$cs^-}kIw{MDMrC#^nnW#faCT!?ovL|;Z3b7>VPj{Fz_|h& z1keOM!A_u$t#5w~cO9sGrSz%t4{u$IJ)1hPV_mcK(IycZt3_}ONS|DV-sV!QsxL-Q zQ@MB&SpxbPl%&O~qA$yc7sw|eH6l=eACD+`SZNSvPWS+`KKf7QEQwG z#dJ#6xZ%oDoa{#Evupy_l4Yu_@fg*;n=}sQvyd3qVx7RXVkb}2S+T~@jbBhGuHCwW zp~1~?wYS$su)hf*X30>|Q@OLx87K1@1qY9F%YHgbo)PXdZ{A#t22(R>Bup1CP{_}n zIZgVqsfKNmL{K$Xm!rOn9%nobh)6qqcpIMIKCQ4{xx55E4okGHsLqw+XYuIT2{5el z+s~hgq0B&fWVlu_tt(B%xntXK`|<%iymdlU{S%bsB`WBt=*#osagT$%x6k3pjWb#V zarf3uNKJ?mSUSL$la085i3=x82}JF^RmJ;yhw7j#LpC06eBW0?Ibor(3R?o2v2})5 z+~oNyDJe#5TqKf`;x&th*)$x4_44$86>jlR@H1Bb<~`sHiZQ&$UE?`GqwW^~jPqran34Z;13Cvg4b zJ_WgP(3W7Q!Jq*!dISVNkJDo~yp{RztZ5?;+m;QQik8h)ej@zkfr-TSzE&{?R9kCt zK!AR1OD_(~>#_B1nl8r&jqhtVg}lCccqgtL8dcTKj2wn_&g>qPUpioNdPo`DwfWhBM%xUQ<=#zftGY~hE`%C zBC)2c8=WiKv^2urvE7=bz_P2%yx|CafWI%|qQa4o7>bI@98^^n>WV;&xzjD?!$Y;s zEtL|l%ZH6I`Zq!EAU~*^{8*v>fm)WKQrxoT6*Za?%J_Vi7?qUBNG*aDDlVqKvpc-( z1PE43kr?8Hy<0kQ_w06jcK;}TcyS3A4i2I?#TOAiR*3SoMYy-EmK<=kUJMS(8XIHv zRMxX6{zBC}>)^!5{Y#4pQ$?Q;9)LsvS&*lTC~s@nEnNsR6Bb09u7H27&|fva=3*qa z%S=T5&k)d4(Hn}Sy?LIYeTXIUw_VH^=-RPi9`*=ywm_tp12UtWZ z#_X%JV^EtLhsJ_5bk!9K+#4{^UWHzP%G#zP*%o6>VI6e#Q&Yv0n-qza!(fBU-D z*UF!bueYyjQA5$!YKZxBP?!CU*IwOFf_4@|E6hM$eufy&6a{>9SuR#`4cej{B!>kc zFDV8Yv5{ChYnI$g*8UOCM*zBD1`Ef{6A@vhVuIOH9ADvUt|h?YbetE#IT75~+0JsD zgYC{D3>c$l=!T1Ob1-(=)ESuZ2Iv!$((v%%WAsQrwGvOjoa+<|)Zc^>z+IjbmQFSk@S81|FW=Wup638; z>060IB67|M=x?0agPogJA|=8Dc1xzh*KsKhh}ZPs$`M>WxeNC$9TD+(02NtTa{ux~ z^~cHiT{y6#7bo^^!mW!3@c7OdtZXSon6DkeMaT@UZpK0JvRLTu`suxzX1Q@~JDS9Z zvS^??$IZkmcNCRu4Bs%Tg^h!rgf!oy!nU?DsC24-f}0^3hF!R*d3}8yic9hlDq@kb zass?>-GG9d=hKkz`awZ&gP!1~Q6Sh^51(q@Fk$L12B5Q}TL)?hdo?1CoU9dyyn=kK zSCf#K3>#}P)~=ip>jGPA&et(4y~r(Jb2Tom)WtP5tVNjeIHAvLX&yaiy6zhh#VlYx zv76-&wqfs3Kenyw!cb4UbmUBAiThQM6e$l^K62thQJfm1F6y?vRk(fjh{FEPxg!d5 z!kr-1DzUsrEAVOJ!|JMX3uaAKX-c9CY;%`8P|`E3g}sjXAOcq zoD}Z!UoGgpV5UH6wsc(C{|o5f$Bc;+uyFPaSS}G4SUQT6wH2m*G(i;39841c8?=CAW(i(fvl)AFRJ^XK!k*NiQDHZE}npx)7gVVHC>X*iH&NW zt}%@W)jL%cK~L}#`u5_M5%huLni2HXg~e#Cu17;@rRLCQCnmiHeHdLi7kBtNIKa!s z6dBQ8a=+K$-ns1>x?%Z)<72(ZOYoF?VJe2fS|D#I5A0$k%I#GKj)H!XA#_8?6ZTx# zJHppP++{Zn+mz;{q9Q+26ji1e0AEDea7scM^l|n#5Q%mC7|r(Oe>M&q)@e8H>F52oxqo>$V~@NkQLGoGXgdRlF(> z1h_h4=7%4MqW=)@{pd%SE8gTn@fHbtLf%~rJ_pjd@5fox(l3}n#gH69ALi?)kmq?c z20GwQ;5#~D{`>`+Udh2&)}o&?cY#)~%oLCB;ln4WC@a@kJR5=iCWP#)=vA^-jll>| zp%doD#`F0(!ky=7$We|H@XXfXdj!3i7y%jx?wiPSGk^LN@d`~)k{+*hfDZEc-6N`g z|1di13lQusUhL8thzW3#V_S4-$a9>OCW38kOCzFveG%^EiuhorS8l@jqaq@YZpZQc zBiJuSgQ=Aa+e8OCt06ePcQa1z8`5iCKYI|B#Th7+e(CIFC!n)e(AnE_aS_A9;C8ky z@{EdtcM$K?CrANJSUcDoCNMDs!%z(4?<{-3qF}|vg(xh_g@*@A6xeAfrm>+_bLi%~PG9*tJzuN|AP2c3^Jvx%^sm z2#QjqBPWC-H$F@=3+Sc}cDLg4(LK0$csK4{I4+8QR6)+L&eh|4UZ-Fhl|2msk6k(_ z9>YG?5ZQt~oBNO$THi32Y9s9vWON%D!7w`n6*_74}qJhqtX$ zSDHEX8p1g;rkOZ~0%^?LS%*u9whHh!Vq|SAyc{eQ?(@XWG^qLMSUhKzz}}$hXHA+Q zkpB?VCVl{}{9|RhSSP7C+E`-N)Ja%4XAW$oLo+^_$VHktwO!oqjFeWSrYvLbUT$K|ZN%aV+>J3%!kwTu<}O<-HC09LDL-&n zKoGK0(okDmh7~mp3VW79$W9{YBM=`Lh%k3AQN98JQS@Hc%jCBU!0A2faqs+ge0=Ai z*1Fj@+=-l6H&OnJRmrpdyN`g>*>cfq&}&JAg`zy?h%y&-%@!=mx+E(ZA>J9_fIk*Q)%v%C;JViZ<4 z7U|$C1xQC#o`x99(xQN0{`B zpJU=LexZ=JV5ZBw`G&!BX|B>2tmQW+==s{H=(*(}JB^x3r6X1N!eV#{%Q`K|J_jn%njYh$! z=Be(vfIpA(^`d#R4#__&y(G@FK`ALCnA zW7kNJ7==Nc69yDyCBRcW3L9%nRo{*d%%l+kCi`pzJ2Pb12zrKFJUv)wjB$EbolM0H z9jbjo+S}U)J*!u0dZm{go!9JvkOP&)OrY$whUsXzOT$lo$aHpcL$V$}x_3aH< zRbQs=DnmI(Mn!$^*&^T{6P14qx6T|C#eYcD{$Xv#5RY-tm6+rdKWm^iUP4R zlMa-Hx{3-kiyM~^6OGK&6mZq4!rUBPyEZ2yT@8Sjn=3qBT@>^IoWkxaR$1XM9Yh{t zZUcOLz>FG(aX1jmPz|>X*AVn<*0N7U?=C-ZREYd0X&GAbpslu1Vb8T=spyl!!&C(Y zxyav?AKuGaK4Y;2#mPZ9v)2InPwpNP(4P=btpV9FuJE!m(Y0E+rmPY2jLmC-GXXtg z^vmW>!QxpHHH5=-&64aCEk?%hOq%o$#$X#OIA)NC`jP^4HdUj&p;8P`mV76Hl)I=C zreV&Pdn|yTHSv7`yJ5*e8UQwiblwc}7(mZ9K|VJPF6Ilx7}+4y-42mH&eBJM6!h$K zOs!nkR)OxO0`#|6U|7`n?twOiJZIGIA6kW7{o>jWuM{s*`sOaq%3h@gV8^=U+IDSN zfzfr1*wRyj?Q83?v#$vw-PPFCAz)uoqB;2kTr}yY0095=Nkl`3YuE znyjF=T(npWqJ;vSDxQ@`Yl=%$!84Q-?&tqHlgdp50UP(J@;Nh>gZ>K_F4kH%jM0Di z!6cY0SfUGqGsENFy@$xj$`(Okt%I?D4SJ(0XEVm@33LUvfSmjEVtJgf=XtEpL<7Kc z_}+{uli}~>rJvW3j)0!e5<#Dv5FyY1L416VX_Xi7$%AvKDM-+;jm@IT7+KefUw?LA z2V*%%``gc-qB1)Z79tRwOy^^Hc_x1Q#eF=uaa1Qu{qa}NFtnjVyzLLLbp8YsXGPmzKRe3wIP1PGxUz z$Iy;pq7rARQsL7GXuMwT`Rdi(NY6-y7bh=?hfPJ^)VM+ve~4a-;O9(LE*<*jJ$7`Y zH(^-UcHO%5x~44$OZj=0IA)!k+L}iFo_tNv6X^baL1^n}hr2Mu-NR6jjh+cXA08T^ zOD+=jggP7dS(e2JeKx*k8aRQk6Q+*uVt)HD`r7J6U3+WCO%Cx@RbP{vrb=aPOAQWe z9ng6FhR!A}a7M^8q(kU4RynqDje?$ouGdcNRaMWyTB>=5ZHxo8EO~rT)VkIn868Ga zP>>G36eP*t%S+Z8^$f#M(H|P(ti_EwOOb=BN49gIcCA93pl1k&88{rA-MgtrCsHvJ zhb4_qirPQ3N4$u=g93zVI12n`Pn)cb%AWCghHi{;`q}a@GHgTjZn;bp&eBC%M2e7S z3E3h6dS!7jS{oY`?$H8R#@q>QDtI==Dvebsz1>AQi|a+u2l{$zsv1GhE#Kol6+I!( zTxCL@F?(aY-Uxas`h=($6zAq+d1Z}4-Wa;cOh`atSSTXBz2PsN%13^1cS}pSnlD0G zdYBlw0j&}9>AfRb{$SIpDly#Rs#?v3x1A~6Y?f+RhD!cT&>Pp0CFGe)@9$!#i_&=5 zTj-)B1?dUsZf!u%iYBbZxO+}=&n_gJ=|3p>}hs8Kj5`$x7(zY(>6a*X3g-53+&u)Vht zyEnCq=h%$h8&_iAP>;sv*SCr>t0+K6Wxn?NIDZes2Y9ML+Ol>fdRywyTv~wP)m^B} zNyD;PQ*``d)`Sl*`Io=I`#=7%7_=F$LpKb^a14mCd4jyDvPuEZbXh{3(5H&0A>i_m zJmw|hz*CGmL2qKR@O6xyihkbwMOv(D)v7gk^yrC#o~5v@mT~2>f17n<1Uf-YkQ>#! zQQ7l7LZ17CJBv9y{38{g5P|}LO58M!qwUgr5OphfBA%F)cooDr#cwB zQaq$kPfIwO&cK$w75LqkkMP4McLnlK@cqlj$^jR%CGc}H*NmKBe|8tY{_;Nl{2N0B z%lgVJ%$)cW>7SECbeQ40m$&h&&+p-jXIJs9T<4B>5ZxWiv0?pMQM(RuFRVnNM{A6n zz$e%Z3f@n%We9W5ZYAiMb;DRYbK?`@xf)iuhGMuT?b@}g(IDQdtMEYc+3j7Bn^UMt zoywfoC(HxI%YXA8dwRMn>{+U!QMkbp3a+jm@;wYi)Ch1Yda8Wp;2Q^0eZ=$MuyFuB ze&WrEqNhP%=!Vc{8YSoO5bjj)ggaF`CvS3}jiDR9=J_-PTI=TIIN`iqD^#j#7qylU zC||578y63aD~!3o2#o>b_~#FfVRS=}4vI0Hlb;x&@k%QEExn?a`d2CJjhQ*j)FI%F zb#YFPjmU$wSr-=BvAze1fq{sTe<&*^Tpr?7L;U{W4xHXOgrg(^UHNey_OcqZSW9kH<~ed!kvSz-17KL zfjkFe34c3FGXcE0Ru&}eooubdWp+h?SadEg7#$w^y3-q7UOotH)@Ek#c6CLtsBErM zMO7ay9t+hzA0m6&AEd`| zwX6^Uz1Lfy_pn@os@xb{KC<~O&{L&m$9llSdcHt@$tyK)EQ4TJZOUT7Oi|O*1@MN& z!WYe$gh)RRZ0zY2Xxpl)-_X;Jz1uhA(5~&+w`~|>n+LFC<9e)L*@lk#YIHX@V9km~ zZ0K&2?-{2Hfz+1d>N>;BKw*ZChHpgavve_mPtbGX)V#?PFn7`im^1M`olNCny%Ztt z_6YNIL~@uYp!^iHRTZMEp%i_hu@R!|bC4*<%;!$m5Z2Upe}NBw@?-q`Z~smeJ>&F?XU|b^ z6XI0%Hu8J3)O37UxOhx)3VvNJOh8YAz_1QqGhXlE%pz9KTD6jje#+$O8l#^*#{^3j zo9QH+2M-@3H#^6m))y?$v86X5WCS?-E`k0g;Ee`={n@DY`95JzLBsdh@7e$7&zhy@ zQR(w}X{cc8Z?YP?TW61m>b|W@jb1yo8+%69>O`pn@;r|Zuhq4k3Hkr=yKnHr$4^B( z)(S&<(A89qvj?}S;{U(@-*51*fBX{v`@j7L8&Jk3=H=k?GoZcRm4R1hrm|=kthGN3P468g5@B}!^A24Hv&}Z&E)jdNu9E3H7bND#| zo$zgHYC>=C8UzIyCScJ!VA%xLrr~w?IRd=1v-7Qc94Krvs(LDVhJB)=;xsmI9H=cR zuF!qLUUT0?xpOeKxur!jZG5%luqbs=`^H#2K~L4L1Fiyl9%FGuDt=>p-fWq)VV5XqiLW8g!B~cJ>;?2Trc1T1NO*uRf@JIK z?gS4fdj$D1{_X~@3}j<&Dn^0zx;f!#o+=$nc>qHE{ShYCop6r`2|`?yVOhc;KRq#=*zd49iQBas9*=Ji5GFAb%X6-8+TVjRi;z6L{Dx)T|aqagl9wveayY zn%A22vqdq@G7Ovws4V4JMqDHs%Zmg|HsVD@3gEY5_sB-<-?0UIx3Uo207eHlV6!}= z?e$e+kjmt{mSfw-by(lkhSj3-zk2=}go2vHDk_7bQP;(ubJ! z(R-Nj;m_B z*%}LzQIQ^ly4+;(beSU`t)MSWOF*ojCo-c#$$b@LPS7)S!%z(sI|pT1ZkhwJJkBr;;Z9?~%o|UmXs@k6K?+Mv7t47`Xe`SSu~37N^(!&J)xb8akv^D@ z9Jyu%*Xqqr!iM|nvBO2zw5P0m17MV+YSI02<$Mr(Lj zj4F371;}_kbKe=NVMY$ORP@~PJ%ZR>09sck9%^|hxJ)4z{tpd}KzH{VRrGGIEQ;o- zpzrSPdg~th$@5OoQ|*_QmWwJEFP}vYMaeTh&(P4?HS0B$!(*=%y?20uo}rt-pb)tR z3$rox(n$c%g-l!o=8Vr9wp#GaQJ!meZ!rdru(q_5tzl3$D^-!C4gcV zAb+!ZC7W@@DK0`n@Ux68LpL0Z?Y*DMcbf}8M@xjd*{ion4|1JApu4d|JeOG16(*p*NFY(1rXa4*OG8UZ z4%#d7UbOEu)3iP%ZoC!F(s4RRW(IgoQ(BrR?Br)*5so)I}YuYIjGN1 zLRy5c^l@**2YN_$^qcQsR>o?)jrK<=D3{qgTF{Jn=ga~(noc)l{W@Zh+Z4AR0Vb9PHw^Z-k@*MVW zex9E-^y3AXDbJJ>%OAKniZF6RxEMdqyNHtCD>lRz_3|5}L`pvrLzn;yLG-?z5QD7v zXdTNbNKMqi{M@7jc|TnCAL=9b zO^mCE%k(%oo)Cq!#5k=b#rY=;b5xYo;OLQ4ShaGsf}84{kf(BYbTH(t6a3sVy^_bN z(g}OQH!~wgAYBT75pP^4nnlh+Lc&y``}r~a!WF5wXt#@;SMt_9=D9397aSalp`j7Y zbq^Qsf@1~r7U*T{8r!QL0v9r29UUtAh=>@Bj_uS*QXb+3*omU2;^)j-8VC*&(@4;8 z5$r5vW-M^VS~o0N%mqofWjtRO9wEdD?ma_&8ipy)NYuuaaxNd)tDt9ShhS%x&85TQ z1socGoomm}j;!rKQiwMagS~X%wy`)%WB5$L)X%({Tt(3D+0?6`KfQY^c5Unv@C3?d zL*(Iz#>%=9f%8sq;SfT8|Hd^qKGLsc3^>cxSjdc^-?On>u zJ-P$ej_<^(rV7mD;ukZfD%c77S)$~*Pw*4+(>{D(+IyOP!$Bn*^JO{##6licCo6%l z=@OVOGSOx&%7wtUS+)d=BO=H$tkK3P13>C^PVVO*3C7aMEO^B5l*DknZH93ZnX zGt;;{n{o0K8}~IU$J$miZqgHz(Nf=t-i}pI3iWfHyh@wAv{z2>jYTc*wE97u9gO@YOcc;QDZ-R{v7}F zkH1ypV1&G?`d6hB-UL0B{p5Fltf2qs=l_6N6Mm)!iP;$8UQWo04Z(`ad<=;zzpB0v z71`0E^u?RZO+i&=B5K7bH5O!|wKNxN2iPw|EY@?imp zj|eg}@oqC>qXqPF0{CQ6{oZIOEmpwS78M{nK3-IP3hIiAkS|_QR(vc{#T%v($c*Eh z1b)_FBvPZokQpB-o^1@WQ{+7{v}s}tveQyfE^3}h4-93L7MJ7hork!5>ADVh67me) za1fQb@&r6XFh)hs0a>p6#H<`{6XH`usdo$9Lv*Dl#@l0JVo+04C!Y^fBSF~P+d0ay znz!yT>*P?;Q>ky=x?OYnJw3b?)-*bd?+4sQQSR$1UF9Y$N7DuIJb8PjtT7h+glJT$|gHDR#gxc{iQ==xN&R`&dT2%U*Cfh zTQ+E&dDfM`uy3p8%p2F4HLCgD8&+X#J!dtp)?*xuJw48H$m=k+X(iHPf&}94s-k}r z^fLr11if*x6vH}m1O>AtO$;xA%_Ews46B*#CvG&dDx)kz+{qVZg7#rpy*?k!4 zU#qb1Th*qZUr|?qVfh_@|Lte^^RK?r1+hz5cabt8WjD+U;HCJ_{rbm zqo4jAW>5I}t4UOji1rgDof@MvQ(4rkttwY%rxNnjS;^W6@0OBWbW|3htF{d5#ibu; zZ_;gBd4T|4?rB+`7=#Ql5UH9?!(+ALEi?$^mzU;fV}DK-<(M8BfP%y*O;QMOq}OC6 z9)=?_B11&oi&yIJrRu(^xBv}Bg<>f35b5WGWpid>!cTsppr@*5=!WrkDtpG>*_`F~ zCfs?PgRz7=j}h>MJ0WkVOzJA4!y1kh0dky*o}n97uADhzE*38_tQWgw%P7vAIsd9J z8FJ+b?>8Z2RObY@F@=(i(B`=mB;03go*^3=0tywXeS&}L#E-P`H9grWA5G9nSbp?m z1@v6&HZsTuonq+A^0O4e=`m5rOXeamrRZ*MLU~S>w(5dBJ=R)XiK4VLlw@R}I3rEZ zrP{B|%M{qh=sw|3BaxS!fUJaQSD5VY)mgM~@!I zo!bvIU!7p4YBxfi&?l(5Z*FGu8t{DWs98C#XkOkb5DrtwJBX2u7lTw$QGuwa7#-B* zc{Voo;z{+rb&pwej^{IFvaYT{OBS&7F#%23Gf)5gxyu^w=YT5*dU-C(Opou~tDt8d zJwZ>f(;(2x;NUMaeF%T98%xj=?p%z7`>an-rO!s#zr*-B(<>Qs=Oie)qKrFoDKxHs zdGpj^TsyH}K~A7wIx;T6-)DgR*`v66e4mDWc$|#}gMerJk~Kd#C7hW$g#GQahc&%& z@8CLYUDJW1+c#r%Q$6CvB}xsC5N{v|?bXFNIW~+lySL!@wn2;uOpXfZ&ySA?_=iQQ z_Y1@~;4owTqTF>sae+HkJwZ?CGql4H4?{N`h#ehRiI^ZyOn()!A>3yQO#VI4b4x|P zOaRBF-JI>LU@}u+#Dx_EcD5GF6z&8&x3(6hSZXp?Vb3g`r6wj=FnhKFosc&+4$gY9 z5+PF{-9?>ABk&1(2P-R4?^OPF`e1U#EY&B?Jow?eztrPAMrF^jCx35GQS-hC_4U%a z`n?@(SYBC#?09*wNpuMu6d$TW1antdD5i{l=+-3VFicI7rK5cg`Kf%DPgG)pKx`1G9uZ_d9D# zu(qXI)K(G-6C%}}UcaIhWnyvj zM(OCb0fG7|?B8sN%Nuj<8P1{7XBh;}jOAeL`TfJ#J=l#%e>co9D*4GD{Xap^#w?tL zb7yK=rH8Y8>?%vwr!G4Quv3Kz5aa9n0+4oi*De^u*d@n2S# zG7ieJvBZIK0TRaT8OHIG`@?u@TWuwVdV4U?-KpxH`=gusH4CS$t`fUMG*Hd|?wd~$ z>fTJ@2GIXy64gYF(NFsMKZ>ING2Z=$zr`>9{y*!Y+7o{E_j2wexZ5mM z*e3*gX&+;0j?F!-0`go{^$q#y3UcmKr87jsFb|QQ+7V$D{&%eGm~GC;~-1bpdbh%67EYRU;)PQo}G*;|4{Zh`}}83jeg| zNYobPBRj#M)(5&*$?+6X`Z?IRx()SZ>Ea!hVRLV%8h|1(8U?9I8qd#?&txaZqgpKv|#h#R@}IL7g3^=33i5Q7`kC2q^a(WaeBg^z$c6eQpUwc zN5>Ep6e6(avV@MBO|x=k7a}8KkeHCB9)O>304ggh-nz#;m!M}|`}X!uEj~uj6V$vu z2XjxIJf~Z&Xep3q_@=l>{@0-)ErCGLr>13TIwoPy&#@R9ufZ5UWAR3)GbT^qbKhtH z7{YnSknhg652wbrV?)PsY+Tu*iyX6a^C9Bo6sA)W^aME@)%k-<$F=+c0nf(Sv264J zm}^f(#D{~QC+xXjm@HO0IR>TT{<1Zf6r(05SB@u%st>^`aj}o>*o?Egx8a_66Aw-w z!=a(|qUagA;mlWYNq3Ln(8zim-?2$UImS#Ie_*7ve&E3~F6K z&%ss#p3NAeH-esVdQH8YITbGU);d{=nK}f$#Uc}!FPsnN)H{f3cGU%)Enz0dsP+w@ z7huhwk02i(>F5Cn5oO1Hs(NE6hp&C*fhPP3c>8aYz*r@DZRj_;oda8FqoiNr6oL5`s(ephkQT`0=@LWy`V%(JZ z^HlePYr1sHf!D^0B8-dS{^#F*tKpkaA3{vv@v1hCUR%_?F@&R_pZq>1|Kdji_J7m` zwORG?7k~d>@ZnGYK?i3!p)0`I8lfKcngqc9#hKdcTkBM@Q>hc`Y>dJ47}Y#gKA~Qo z7O#Nk`^?L)%udv79)^Dm1W>@;kF}yzQ)N z_Y)%`RprwN5cYgOMm%5+#&W?Cof$iEidL^&veaDN`-2CLV(<8V^$gj!2zvtjO$Zss ziU@Irb_j7cqsr&LF~Pw2+6a4se!_e2z6L!NJ!AG9q-FYLke`n(aGo3&h4$qQ=n&66 zDJmRE5n-y}8I$i?-Y8z*I#KQEsL0Jmb$&hyQ&Z7UQX>7QM`2!(n~AZZKCntCm%(hsv z#Vm`N$+Be2mYJEEnVFfHneDJ0%#fK?m6dh7y82e%+uifdXC5zwoYg(XH@+Wh?0xnD z9i6@Rv)=X2x#m*%5A0WNnQr*>)2GgsEt_}B)oZsUGAhnMA8eM4r%EJ{M!lor@$a#| zh;uM9LO}!JRjXKVggRD~1rCv19VHN4jgF49j2=3Rl$7-U1bSWz=n2Md-n`X79~0wI zE&~hohAJzSAtlreDUj{U=BX0jWbO8;12&6x z@0vvhaDuQdv&MP#%!a*nVvm6y&z{%u{Q12b%&MTC&aO4{r64U{TD`PxS~T_mo<_+7 zr{sY=**C1#-?>!_iPGLQ*xO6m>jm6hFXW!6`YxTUTr9_FAwJ&X*G-4L3VUjCW7`mf zC5OH^H&;sY^CeA(dr7f6?ABv!0X^zIN-qK+kDY^!1N8CkQTgQ01N~U-;R~{IWLW=! zGHooWl@qP>0T~)rrns=kX2vG#4F>3wLV_hRI6y~KeH83V{y$1<5Bb;`zC;eN3_H8@8t339oXx_-aQ7+)S{>CFuCz4d>}qt&+9V8 z!t%vt>r5Fr)U2HEKY3=^I=)@>ckHSo2DbXQygE?m%L96kqHiK?^jtN3_bsXS=IipV zD*Cs6`zv|#*T0Z=e*a5(|Mg#4M-buPO>*?_VX2g)C+Iac(5};^Q*`*R`_8t(rUCG- zjqD5LOH9OYZPH1Q#WTELp*4;%0v)688>NchQ*yXi29@OK2qISEd;3^kKY?LNG%&K@ zF-5#;it}X2)JZlv4N-_jDqMXOj4j`PU*7x8@1(tgxzo#vsi^ocRs2~h2(V`Yd-OD) zzMq~`K#!Worm-2av2mvC*+=bXsKSp{@HcJR+!TG|M$Ihi21O6(j~zWFdv@(J!NB#1 z;{IFEqu`x)kB<+mQR~3nSvWjq%X1F=Y_V$yzT(jXf54BOLt!(r%92#sr^H4}VMdyc z=*G%|=~JX6H(g2!Ln0F@nr1`R9@65+<6}zg8K}bSwvOkl9!$&3DJ=`Q4e(;2pp>Z-UrCcj0>{0codpW#Wj@GHLi21!=WqW)O_+UsP<0J|#TNJbLCNBnJCSbzz#E+PzX9 zUD_>QJ~*X{{<3UdJXwa7q)A+07b`9Be*(Q<2huDR0t#RUdbSSq-P$&nZf$<9Sp%Q} zKF_1n{kyeSaQW*Es2A&$2|5g)Er;}6UpjfnGIqQ=v=V6B|`Pd4xaebl>yz4`WIhnSE7_zvfBWPD9O>6@Kwok>A* zjDemO8{{R?0X-z#r;Ei4=m>`QEtX{pwGpZ=QS^Q&Vuj%czxj>4{mWlTs}CFKZ>Orc z9d(6z7__l!@Zbr$0{aow11%T}8S#Fk;=VeQYDtq9(Z1zl3^e(NEHnv7P>_rPK@LHae zrfR-Omd~3Yn^(=0J)4#*%uDROSU=c2yoW3vkDa3(09$=cenub3N==f%gNDnF9mnP7 z?T;irDMh;X@KFU$`G8PW(6KUZ{1i*Syms}LT)uQ&Zr-?Se*TRcx8%;9d-C+@GdXbJ zkPI0z%t{;tsu*K`@#3X2Ku6ZtKa2`c>AQFDe&sjzSU15IwB5aXuX**!$!P|7z)c~u z8Pn(3d)>@fUW;`zW7bTG@1vbgT!Q%c23qiz_Yjn&GvYA;*%%#l(6DTPI(pVndhCGg->_D8u39FCx2&^loNGsSo1&*wf~Q=< z3JbLEUOBfm0P9K;19m_UK$}=+NHIENQdCQovGX2wHESp1m1cK+lI=04)pl&IcaIq zS1*k0)KtkzNii!2Zyu-vcz_P<0X*v7ZD~BmXQZlvBjaZBsIf9-^f;L~Y_zKRDuX)2RwQT@B*&x(szkGP3Jh`%0zJ7E@zW?Z|teT~rY?*?>&y!jS=sosLr~d@{ zy52mX_f|OjcH+2>Z0f8i^$P4?b_7oSqw?|a``9}o7EW?>h(g|z)k9~(wpP(A z=$R=?8HDEb-&HmLTY2~OUmM(C|Mfq}AAacpJ<7h`TdzyIrVaG{ZLK^4iaIAg++su6 zENkYnkoY9anO{3+idi=<%Z5&1+0?NH`S}w^$Rr(Ujvi2|3ck#?6NgmFjL|hRO*;dW zJj$NBE#+BB27LY&fM>=oTRO{>h#;Au9mu@#qhwrll~m>ASjQWz*H8O~4PJu&m(sp* zW9ive|L67{B`PpTQlmXJZBXxko^(qxsjzI=$CJm}>7(GMQ{Z(85s}g-h8iXz26D(`14pY031aR;8E^?n`6$u2jCoMpV!c^Y=AqU=Xtig z#(};M_Dx)jWGDAgB|cH6jvXcW=_v~P3>iPXMuzk&GoYjD0ewwrv5x$Po2n-ZXVLVj zX7N-OWb13S10GN)n^w-0^-E_d;PVaiD0;xozIpZfdSFkG)~c%NC_XtpMn(=BCp&kY zkc*e^NkmM%fu0FS`0~@I&5=ispUd-SpUD@We=T2s^{ssQ<=67nSKr9D-+nJ&fBmg| z|NW2h;>9PHHIt*~CQQ#mMMb5|o;_D`a|={edrB(+-l~IeD^jl~t=(+sxRQ*mzU)WZv)|*RX#0n^-g`c>H+) zPnsog2l%z12l6O#8j9TkA9WA(0XG&6IrM;>V}Kn`p4ZYT(46&ykI#qz(4+1N^3n-# z{F)xSc66UyKYCEEAKP!wo!z%X4k`E#Z&`17`+)v3?^898sz1GpeEUtc*){m^D0_g9 zx@XHV>>3w{_3X3k;7a`tTV?*Fk>&@tRt3@$f4<>|wTiyQOUTy+edm^{VD+MAp$Bih zr~y5-aUAIV^#%a&v|f7icy&_M)2_9F9_xmc@KNkoHu;&Ewnd?%@&UL5yi@krHxBg9 zvvQVH7p2Ax$pFR-Z9X0>bLw7zp_DtP$O9%T`+DqkM8?@E;0CP&# zvh*O<4hxUC^vzn((|IWDd$eyQUE4G_&^P<=ZChUzs|K*Y{;OXY=->SHFXfHj{z^W0 zQl2mUa#N*LRbpmrsAc}3;s;EiW_cCO{Q% zH&wrl-graa{q?Vx0)aa8K#U8?4|&X!;; z&l6I&Egr;EaPVCs1Z_}ktXAZ43ym}6nCy)s%n0P%o;z!CQW%Vb^4jr z1Ly%fum|!yo-%rvP1LF?E0&7#Y6ZPA?8-d}i;9s>-L&)b!3Qsq$B#UafAsK~Y~Hk0 zX3Ur+OO`B?6)RTB^5rYdn?H5xj5U-tB@CF*G-b*(S+r=0rAlJm5Xc3*%a$#B$+o>tj!fE+qa24IeI2l#vjFlV2j zu4{mt$yB_S=dK;!uMpp@iW_T&MM}0C+_7w^dBZ5;!v1agnjN)(XNke1TUMEZr{Tq; z;DI@Qyqh3}lBYh7D^(2eS@!MRfz2{?IX8qoKEUR95RzN6m2K|VUPf0b>7)~V~y zK^VK)SZ3mP||if4UiP@zAkYn6L-znHYs_Lk14k4WM5%ailDnJlc{4Y~c`m zdWHR{mp(nPr%`4X`)2y68nb0k_taQN+4HxYq6hMH1dFuuST}!`tY0`!mQJ50aY2F7 zwYiQ^RQcBb{qN;HRrMY98U*&;TD6i$e}9P&(Hqj&GdmU!9=Bl^cn&5tQQODn>A}G?G^Mrz5Faoaw%9my z25dP-M*!?m^1$4624wK?xY398#O2X{_};sA3=7Dt8z%6nnnuwVW~NC|R=O=On3I}d zvscS3q94XC8v(AB> zeAGXXcMZ^E<4jYgWF$n&@S18FH+r({+I>pSUc4=ls*XE$?ID4xf?4zR$>SID;Qmut zy=sHPHqG+ffibXUmMZC!0|(ZaN1u?8C`n14fGKKz`}UoZnyTk4##6r@m45T)%~yV7 z6n&76!tm(nG+5^~FR#!*j}6nmYLG2p0<;OnQqKlePr2i@>(@zUc9!MQJ4H|DKv34H zc`PWv4%AWf1Y+68#sTnb$+LeA760kItMctfcjf!%_vMEd4@{w>)=}k@F>p`^%-Avb z_^5l@-@=~9G^`$1Hi7p5ezS89?~zLf_Ly~Ze8&bI=JvJfm~1J*a8_ZDl0UL}r5xJ0 z+#1#mP``b0Z>*B=dg5w^o9WXtf)g-V^j4CdV*gL^eA~Ck3SFSc?|5?0&}1a@ST$9 zG4JI${CeKoucSoA4ILrlhmDkpdI5|XJk&s6iK17~=h2CThSY*SN!9Jb$;0H{`91RD z<{|m+qYLuQM^~(_dcUlgT1EfA1AP$n(>qiDhQ*!RS~Hcd5O#2Okgu!e{}%M5U(zYm z1$|xMyUz;HPQ|w~89tuJd=8**UjIF*_tx($5bII&{~*8rhrhE1@BuyNi_}*ZIAO)A zFmGzt>;E4XV5*zRckAX&lVy{~m}LX-$)}$?hMMyuEJ45pUb#jb=tou++dfKu#q7!E z(F6DDqAas+ST~_EFU=aiAHb(`8Lgeks=3o;-h{CR`uvn6X{*A)SvT+f>Q~Z9uR*VN z?WBi}{1_4T(esRw$EG3k1|PnrqMrq2InHDJ`pkqrmP7ASEGbhQq_2Pf{dyjczCmNN zZpgYRDlC&Lmv6}InR67v3h|B}Km+c&5CZ5NqhZJJ8i4OSdYan@=5F6*=+ss8_1=BQ zo=4HgM-zLeZOo*G>Ys6NKe4HV~h|h#@O6Mv8JWWyaLGvUlHEIeq@7gvZ87 zXYS90WVw3fmVEZ<*K+pEC7YFs_YH7?J%9(gq*N|kxLCGr+hLHV6JQy?F=NIVxIK%A zFw@mjpXTb-tFQdVfIdz~W!OHGCQUJ0hR^5k@Ol;!MbrO-oYK%1ATmYIsgMb?W@PPOwps(fih)@xd~_t zZ<#gA1SnL{hD9?C{=glT?^$7rl*?n*06&e6!R6S~DFFY=3i|W=cFNhk+hpB>88RS0 zLnhW#%Iq;iEgrx!gMb~_Q}gD44%vV{AisHhx2bh38ek9PQS*5BD0tL9L0O(Zt?kl* zO~S;g!Kwl}E9l!c1N04S_N&LbX&}uN7M{`v^~}b>zX$XvbwCf`JL}Mu)}wt}@#;X9 zhyqJ*4!nAx@2#Ns?%Jsq^bD0<8YMnGP%q5RHlH2^kClVU2k0~uJzGHU3C?;(0%`g_ zItYCJu|tN*)G_02VQ^NNGV4YaeOYFfVp3;X2LJICbv zXBYL{UXTUj2T5sagv14OlL((KR*N3{A>nH(T0CQXMZr@6LRdxF) zh_P&#nV!2&s_5G{Yiz4kb#L87{5rO@{|n!qnl!T&>TBmtk;Rin znT10mpB~^()9ZQywvBcOfE^VN^nY zCyzbTL$B$&5JG*s(g+Ul4(7ny!QM5FVb8F|&OyxsdX9bY&fC^;ga@;jJ;7K+j*hPK zRS{Q|N=jU$c72-oGD`fPbYMC;6gp?@cSq$CHm<9T-L;`jW4U2|Zvz}53+F4|0 zDA>zX=?~S8xx(IOK0hgzs_NN}89YF8bu>YIY(V7@IdJg2oH%n`!eXMOho7H>E7Uiv z-69`7{Zww>dZ5a>##A=>=^+YL3Yk&6hT!PbsnccOz5}*MII5n-xGO5EWTtkcKsO{f z%F-)={+cywUipogT*bmAOt@OQbh$yiZ+Sn3FPSo-vT*()*}wOIl$DfQoq7Hq9m?!k z^JKxog|_fWUVfoOMaN5z9zN3N<)S4nho1CG6gxp!U{7No_yc`_PqSdG3$T(7iLYrx z-kB4uFd1rx*@tA#kOR+6K@baQ(?Ph*8=#L*5AdC`r!%0_0Q#tTX4kT%bOI$5R?nGg z3pUgg=UAx(>g8bB>|8O=QYy)~*}iO!**7S4)I3{&j%N?#T^)L-^f|_s+BgP!9T8Mz zrAo&pjiqh#CI)zBzFJVWX(I!DvkyP;z+O85N*JT!QR^(kj6d%{Z?j`{7)$nzvv9a! zdjfxbjCIq#WlIV4_O4a$8A(Y7cLK2h8^}AQ58SyB0X?sA3ZKe=bQGDY=6IgWouO6L zRhbHzvv-ZG8?I~8ESVjSs9CA^0M-q54eJ@>&0`DY z>*vvk2juoq<*MN4H)J31&zU${2A3C0OfLn7kC%k``I!Cp`@j1;Y5MNFwg5QS5Z73r zNUWF;Q|y2p72h|%z(CKeS(jdkg%caBBes`T4zN#Dcy!a(0C}t%YTdXJ2rM#?x&ib~?Gt=;Rt}2Y1z*{6oMS+p2I!rl=kYsl{K0IV@Zcbc4%bm> zbhy>JnKE{$%$qq`O7axwsqr?MY0Qv8GEkNJn8AZ&%9xR=>NBKJuXA7z=&^8|Vh8eM z;4p)B|CUW=<&d#M5O>YO`Ifb_e#s(J^jJQ;p3wm_ZS!KARC2k9F zD@dnLn=QkKjZ)zEm%Q9!?I40AKd(>@9z5{MZ%n1j$jB&}Jb9{(3MeJaOx-|cLF@S( zS~FNq9z8CpI&w%!@+=%e3}EJrIWlg-cu7u8k#Ra2NJ>sOFFq?H*U~2`agdmhVrm^F z?*nFn6Fw z$-68ar|K^r+AWt<+0UOa(q`dOKZMVvsM?*=2MzXnRxgy@s}{(H`BTllF_o?go-K84 zuxkj$Qu<)WvRUTOvq(7JJ-+?foeKNC8|1|1RZ^9iYQtwr5_>?;tk{>JSHJ^$8sKQ7 z>Z_YxxD2bq^~PwckDaOq^ne{z59kThauauJ+uELEiNdzcn_KM~K##v(R#0I3D0mcU>sXx%dnZ}4Y*=Q;l1oqH`lbPV)I9qHV~6)EGVgt0akg1DMX7O;6&Gfm2p&DE9*c-H zOVs|9;nh}yf8@YQiP28iubcj+e%`i{8Q;5+s$Kxk5|(sMajN(eBEzJY3Ilw46g`<# zq*nrTEE+s{CQ(KA@)R?pQ%EBA6BjRCI(4p9^nf1ghG6Wlp`$ESaQf7lk`$j{^_PIS zch6TB9zn?icp&Z+J+A}&?2}DH1Mqb_0Km=`Meouo-+KM`2KtDQUJ?}+Y~{U+vQuTI zj--|?nkoIu3#42}@42Z-QmG@Jp{nW!lordhaigVLw-vd$rs8RU9@_?}18?fzV9yY! zojYlQJ%@tlF&_PvmCMcB$L2xh(?L*XgB<=s6+^>@j+3LuuFCHHCnP8|TzUotN`S(Y z8Z{f%Z#Dbo#q-bQ?w!YS^Tq?Yas95@Iwwz@lbhG?$(>vGZ5comKlTom$+D%Zv;!G# zkY`Cjg0WedIdbaMsaJkus#mf?6}Ank9?)lHWLdcrmJO{e?B_ zBVWCGy-c1uMM}%dWU!9rduzvpLZ<Wm-AM2&gWdKF(A4sCEZ(MhRFzD10|s;CVcItQ=h=pu!*joqea|o!!Hb8ViS@8;?={#aX#BK!W34#CeXA-sFv_N`1c)10yg;4~l~*rTH< zctG!3_qLwr|F!{oAL{3j%1MWzuO;IK&^LPt`nO+Blyaaa^9In@d*@B-usw^$G`5PD zU7I(St~wfEv5(Lmoh96>tARe!r>m4J>{0a=gstgklc=oTjVk#us^U@fY!NotlZ;~V z<_Ekl`d(Q!R`t)OY_R**E`RCutx8MEoW&25f z{Nc~?(@*~>7cXA6*awrQNSEBXbC--BJw_o;nFP-|v}viC|0$0ikDeK|*f!LvM1YO}0wpoj&y*;@B300%>OHUz z>EYQ%_;%Oly;Z&TQWe|VCRPDaAa5%tX=BooDSOm;*LId|L%zLPIdx&LaI^MO<-2AU z&dbl?bsbwMw6(J(brS2wf!+eLbwJ{R=V-?#zq@_5@{@&75e;zHVA2GhzwE z&YL(=_HJ5ZGlA1cFN}_`bkX;J|66(e@Bhv~&-Df9DW#E}mMjA*%A_ze(-b|W4M?4( zv--$_PdF68M{2kf6{ebxP3X-mVzT&IDZMdrI zxeFId_26MrUQs1$H*A(Q+SYE|BCFSLlI^?q$bmyg^xKS6r7tjX|n9szr)BY zE6uZzH$mVXJNB4$la!((N$nU2#9|rwdIuQHQSA=oSUGH6K0TnP{tbY4?KNy0AP(SB z^=z?Z9Ne*705-4&)HD_v;dMZseU>1k?mX5DAa@x!j1+huHV*zgik>aS(y(vv=2^{( zEu#f0UtT@3%O*^*b?KFCPbIN&Wu}`iKC3%d7$P?ewAs^q$$V?G#S!>@|Sjqv%;+T!*-A z^jL=u25dkM#PQg%Xs}?MVs|RuSv9=gbpjlx)GNMyf*$9+1aXUWSU9MxpH!FWkoV=v zQh7-!lBE}4mR=<3QIV?DBUN2S%7CH-?T}~7qn<;Whn}p0s73yK zrtkxMJZ1-alsuMAaCdAQa>eoTeYIlyejQusNTjtY{7w?%-^1*gWh!KT&aJOBD+kDvY=EL?6w8Pe&mGW{Qi(^8 zJws5I-wY+sZ$@AiwU5m+f6^#hgk|ceVGZamOcu+$UuMj!$17J=UUNgsB2sO zKK{N^Sz4r^FPA|T{VeE;S|^8|LT7;90$!6lnxZc*R8{BgSuYk?|E;12LZX^nWk2%o_rzz#4d? z>VY{H4r!M;i3#?2)%>~E5pWz2A6o~@X2a6OrtIk~c#hZd934moonmU9T)1#g0lrhb z0|TU+{*QqQ;PI2E$f@%ePN!NQST+cxi@iV>WX3bw9dk-Fx6>HYYe0?5| z9vdb&BtVuepD(j!PnC>}Osj`OdS!7@xjcXV{FUFBU@Q}?cJAD5_3N>2(o)hSQjf8e zXw86XS-NnMSvM7BR=DRv0iwNNlXlXW$-JQ^4zp(g{H252&B8(1)39=YIS?lZ3+TzT0qoc`K;Grm zJD>ji?hSHr-xk@nXtqT8=nz^}c}oX+-3JgTdg5b9*BhX+T542z0D4q?Syqk|rlzZ^Pf*Cm*y1DkNij0GJXt%{h4SdqPWkrn zIRpLv_48$9Mb1mm2fhToufZOl-l=+2Jg^V$jtqnG1$~=l`WyXh*SP(zZ9J)w%!tLG2lOaljxp=C;d^gb)(xc(Xa;$O zJ)mz??_INP>^v&u+pD_oWXisgbkq)@gC6gq=dvg2SvwNceVBGceS&>V&12!<*8_Si z9Bdn4k8OixiB(DY0{}jG*Z@=W&W~pl1l*}{!(%*rn-!~yo-)nkaEB|%eY>hE*8kl{ ze>c8A*AdrDSb(4O?ATr^RCx~W-{0Vl9}ny)TZ~2H*R`9?js@~g(L2y*DdfqzY1+7n z**30vW&3uWB{VEb7A{z79(`tdw#|&ixCdG)iWjFZehF_NRBp^-J%Dv1huPmOvq zZzzc8a^q3(OqK%L02~z$#IbHr_SiPF#*ejqEE_6a;^#Z~W8u(g6r}5jAUj7=Q*!0< zm4~uqt@uj;kFXk=#iro)cRSf=$9>BDP?{8N>)y`o>Lw9C-RTj@$|bPpCZVh`pUG$e*aLb#lj8s$MGx$;Z2*10>=YX^WAj`;wnyQ<*%k;tyLW@F zAA4@!Mmf22jpf91?BK>FvSEP^dDbtILz|Y$v282uIbOr-&+p$Pmk)0<;BQzkLse;a z0|3e#$UEz%g@V2*pl?vmwxnBLAnzOA&@iL!q(dH62?v z7fQ=oc7(zlH4fylZLo1T2G{{SirsYxPVp0zMcvczG?JJ{QfD~xM+-ws?3ngr~pY($fHC7 zRo$8`DEml1YPWQIsqQ`5I4u==twE=$Y8@4p>PHk=WF=Z&~zx{?~-2iyfD%qm!-}&vYqE1?cC7*+`|mq=W|;&=*b^Dbt5}79KI!R~Flr zdtfdJ36n=z+T|?0H%PNA%hYoes4(;IsR}Mg+#_8eM{0epu;6)kdc2RYHU7`zy=j#!X{gR8ytNP+j9wf1Lx9eNmUFYicJozTi>1ov zxQCDEsX3GzwuIi`bbHiv#@ecNwJ!s$9L%7Ot2N3`;h%Q-!E(;9MLkIQ^2+l&%P97DfFQ6|Wop zuA+>~S-4Az<4eTddsH$5c^s$@DdaA@QLT4az5A2!N6M{NO9~gGa(But7t1Q9Rh|uN zn~&9AyEKJ|6BlJ$aRuSC3v@KhFm5C{6-%{o)Dta0I$K={>-E010ILaSp-|>h+TTQ*b zLm4=umJ^gPz51TSQ&Q#l9w^OV>b^*RdHW-(_YMTqfzk=Zugf4&8JlV)bJcD|-v|#y zY44-LD?X6Bm^n^Me8tl}{(7&BVbIKOrb%ye7f``eq69 zc&{8_N~p2VHQuh=-SijKMYnM&$K`r%0 zQeK{Ze2PO`r-K6l)zD^T^?Qc7oqgd)csNhIrq*I~e=ik$%)h~K?J>5(@KbH^gTt-S z>{T|?Pd>H_c$cX*yz3Lw-vBT94d|v`N1(fSTFF*dFVt2AOoz3Qm7oa^lToMsoV6`; zabmmp^S6Us`AecH$J-1ll)zKWaT5|_t-*=629Wo=)m~R3EEG8I_pf>g!SJ-FCBcMq zwL}9{hpksvlbV1lq)t;m_V9_NY;3^?H;dI~7fIv9YU})J<6lN%Qtd5Y$abGjf5=KU z*NKxsR2?{=3IrS3kL^RrTuUHZcKEx}I5b^~_bbV^!x9AusI9(ax`Rz_B8w%1ek#|$gn?r4ASL0 z$j3r-b8k=n0==8aMk`@mG1qvZxzTUMVbSdWSDej+n4FP^Ip{V50=s=}&u_wF?z0!) z)p&Q_K}sv+l*m>nUqUCMdV8*O$9IRD3`&}ZpHA-@wJ|YLJ~yu`GyadFrbicPc3P=# zG@~<7YJS%1-XCRneoim$maLc4X|kC%$2om{;VZLQfXIv;?=v=$w5xh=a{1p7vm8t@ zUo#aT2OGqMCuTX@I8@^5G510tF#9fja{NN+pCIpo6}@w=AdpOmiIB@Z^dnpLil`1n zusjIM1+xSLtd}FiKKi%HmjkovDXIG&huo2ojhhm*;%IB-g0|al31I$OkFy_n$wq3y z4~BBE7fk2>Hlf2g-Q^6^ZstpS))eP{UttcUbCQAomT2HN<2lk!(h;m_DLwh@AK41c zIf=XjDDG_sFSIkY(eFa1L6>fOW*P#`Pb+Oz>vvI)n-RsD#zS9w3^fxy)S14I@xTJe z@I}U?iV{RnIs^3AK1?>Vcpo2s?x@~<3B)|(+1_Wp6H8a~)Z&AjJLmAg zu9mI)Rr=)@Nx~dcY&b~1rXvB|(eiP^EV5rWi+gRYD;IpTLQd&V?%$8i9wU77 zFCnl&if26L&6mK1*r>N}M4qhWy+7G@x^lm}Oc5i=8eNwDcte$&r*4K0m3M!Sim?l; z0^_DcZC7Hg5E-DgX(0nKV@$w%Ym|u7(9pFXRY3FxkCc>G%I9vA>0g_u&^;thO;vw< zVIBe-yIM38Z)2>mX~6qPx5T+aS^@F`!|2qJogbVqIoN6Mv4<~&ZT_9HDuuDv)VJDh z9mE&2BEzw|JsAC;9Xt1o-(+TIuvR!QPJ2Sn)*3;86QlVS?8l|;e@QgU?M~~BF(@D;6d9qCo&Cply;yl9NIqh{I|rLuB=zQ+O7g?X zI8Gg%_Krx(RNAmfQ%gJHUN7%E6-H{B=bujZQktcG)GDLI4P_~d@NUW&f8}Lo|8|;x zA)I^!4ql)Zv0)xM_OY<0nI$e?$a@Vt!wF-n-6zPl;&Kxj_~;Tv+q#6o`|@<-80UZc zArP_%3haFLvWWy2OkSs;ee)5jV_{kNUY*-(5e@HB%V%9aE{T;O&+icL@A#S8p>5Br z-{|b&xIUuD0CtY-XU-CUsAfcZg=MR>FG|%K?;~Zb>nKp0wVsedNifKN{*<4(*VPc; z(YfU6fegN^sl=XHA<1|&#BiJ<_T4pT5`vZu#W2uOrn4-)=2=1vgzP? zvO)mYFf*)hF%dD^N6vCsEy!^$LK<_UZnOE)EOS^3*?OYL<7+-!7Gq_cTFL^#=)gE8 z=z&@T;X)ZC)OoP?10x<{-dQ5DSG>crV4O%MwrgTb+u-L}#iNb^{{Lnxm2JX2bIumx zeSl&wkPOj4;8|a5dB%&Ag@ZunDCF=22IcOunG!H55%j!8F<*mI2J@HdH{3Jcq;>yM zZpOoDu{4@N5eyQw8@u8Hl10iu`HR9pSZ*I(R20>a%`_g|Oj|M6aE&ePsH@8geTMn_ z2E>m5GJPYwX#t1Gro1~)NC0AdQe82iIZxMp#kQIFKjJB|LN5+Yd>9|SHS@}jgEv|E zo9Gqrd0;UxKwTWqFko#~AFVHicZu)^N8g*VlR+P97faC;T?^@$NH zz=0>v)?0Olc9c-z7FNp7j?yEd*AfI;M2K2FZeU*~^hS~yrPo&lT1C#8CB4*-PFiN0 z?}GiWR&}cU`e=H3J97|mYl(!Cfh)nb_Ic_~PEq3poYllHtZvdC-Lsv?y984(`O#47 zs3*l*J|(`C;LA|@WOutODdd5D(W9DG2kGcmTt94Ql?vq&QeM;`O3&o^xD*47zhT)0 zZ{}Z^)3kAN=BvFj^DfOk`*$QRikK1KA-==wm)}%$nEZ+Xh=pzQs_MHlL zVQ_RLIlk_yd%Ts-AFy4tT+sVt9$I4yxA)9?db#RORs4#wUQbBlA5=g~&*=%RboKzm zeGD=%E#7v0ehMu=Kl%i%1$ov%f{xdi8oXT!ya+yt^QUa(5OeGPfU}e<1#nE6%=<$3 zYP>Z)^ruE=9Cy&-PpvthkaAuB@)Q&hwbFTKAIh`xm#|slB(%Rb@geB44}E`iPjX=t zIDPtBzUV;{`m`7}O-)HUVzPYzOAq94y-y_<48CmY^dc_wi^_!3P;1=9dq71y^pn%> zNU;AlR>Mx->PI|YWwuSot1JJ(b~bqMV(9L0SoC6dfg6eovwOMtKn-!2f-77|raP~X zS_omP-IhP#wz(F@PH%p9mR~3e)Je5L1X&q3-|=I$dU)6HW!udjf3~YKys|GI@d_V5 zY!>JLj})8w!VWbV`OV;NK-{n)XJf}4bRLZCaV0;3Y+O&P?ySEfjaY2(v)LNY3w!y{ zlS8BXS2VP0uFkV8&w{|u+&W#8AwrxA~dwv%E{uP7eZ-?<`t>xf+2yoMm0sWn7 z_@@H&EBB{1*-k3yBqB)M6D0T=H{Yx zUwx(H7k86MxQI4VKSRonD0NJ4FiJnb3ACImzS8>6^04y5h`W64T+sDje|StL#7A59 z@|^NwCC%OLqL(`UNAerzwocBMeYHEAc{ONxA>1z_@Y%>JzP_0mUsnvH-@3Rrsx{!M zjL5TE_@n3F99Eyb{+!y65HISufCG>X8e$(7eS>Q})FJVUaJo zBB5wJ##qo>j+YO=dWD$rSd8EgnO3ZeekIm@Nolx@2Vc@@oQW@5^)z|?Hkh+?WDf*S zej&n(?S4*lN)sj#3|^2=>vALA#h0lg18T|nQUZ2p%)r6r7}em1`0P|B*e09mSKbN2 zw8ddO-tvoTpZ;mScgjIHGVF}Be8UZqF1Esr)jr=Fr5DxJ&(6VhMx`9eSG{jEVMTS? z@)VnsA6Vt_xJBZ|ktwM$!3(V_#zel^c72*-PgjcBHEeHslZ3pkeL>PJocE%QF*Z_! zQg}=t?_kVvqAbdVz+k1)jfYe{_a#(0q*%&fKKJFTk{=Yw-FOjU%p}5^-sNe02!R8= zq0A(?mY>`LZW*y12E}&1lBl!l5xl#*(1nosX{jZxQalz~}cEg_xgHihH7e-4iCPWd{RRfK*y5C(FAO~9aPQ{0WTTwi6 zr4wDurUUUo%>yy0mjWHr+pQPi<1PML{SJAQrIlvkHf5Q(H0eNLJou>4%f2IfL-Li) zB9GDbaWIo;X3nJAdwG<|c|{;UHci}}U3LNAem))Y!Duj}Ialf2a;1PotgWw4egWEU z@mNtFxoSIu=YywhoqW@XZz6w?2qbFOhCy(I@mA;W0lYI;{3gOG!6zp2hR0lC4nbsXm~R0X$!SmIEp|s2~`} zpUeQA6BWHF4R0IY(Xs8^jmXCacoK$1-E{?Blt3=dZMMYUqw=8fjs}*d?2`uzqNJN0 z4w-!^i-8WVy){Mg8GnAWDA0VB@wxq(n7E-4<*mQG{PYpsga+}0!YYye#@0#%0^u#; zc+~OODmA;D>%c+SMh~Y19`6p5_Oa^;jnE&jSL}_};N$%?`MSXqdbwSx5a#Sj7-y8G z;?AAiNOa^<~!5bpiA0&(tzohAM#R-bP9kn>s(`u<X`xWP1{ZW(%kx5^mD$yGMD!Yte9rbxh`5EW$lA)^GJnO-nC6H{zm&0LDVG1VHTa z3!)AKLkw8QeF<|g41C&%Dklx9M-+>b77So&J@A_OS*LQdM2gO0)`!g}zJ=bBv6NpO z+%2DtylxLwuWxHK71OLb+O5vZ+5je0l5)QdsV7*g%aet@*{Je5yj~$6m#0b^9=114 zMfS_Ffoi(R>6gj|UEiyiO`+Mn&13$4fy^BFaY&NGe^@Y$gQ*lp$y0oo(X;4#M=3_% zc4)DSV{!Ku5qN^__HD%2RYgeh1H7&}+5#nCJcI+nA}renRlj0i4EgwEW#?X5U^4|7 zPV0x5xU!By+2Q9W<}R1#m7^;=djf&QSdd{N3XAUpkQJW#+#%9!T|wY&PdtFT26=-6 z=>8w%oC=Xao$+xOva%D&M9E5Yn?J+(;O_(0A>3hk&6Y#W(!NUbiReppj}bPd@edxJ zKdE>Vi;NGfG2OHgh>V2NR%#@qmq`@!m&?8_dDE5-xbn^EDpZD3)*N_r6YLI`oKgip z*1c}HROQe_vRlAmwAkq0zV+WpCCMKWidi>bFj{;XY2ZmLadKLlOXBs|xdk=&p8S|= zg6l*+VBF_^{)&&EV@_TU)tI@qhJ{0yPSn08Nq)5N*%(N(y7;yVt$A1xaJn1ufLT`m zved3eTi7z#ko?WAZQ8v}G#wry z;?ISBd;HNzU@dpbV5X1xh@jq8dB8C)`FefF;b;@X3_y!=KRsU$GS6|$8V@E={+cNH z0g#Duygq||PUAnPOLMiPpg@!{BRI|Wa*Jl2ORe3KwFqL#J zW|(eN7~GwII-4v|u^me2R?akS(|0dkDQNvr`*@o>AoyDt^~Zxbh2xzNNfM?L@-aX1 zA&@uSQfr`p%A91iRqGBc72+Sv(?rbFEu83ZuRPen*)f?AM<@CsZ!yQl{NL6q9y4+7 z{(*QZBA*m;*MU~|63lA7w@b&S?xT?F_Z+P?iPk{^J5-T|##_paJVev9RZd%vrW?GX z(PR93y%)zvdBvaXNNG&mAPUA~(nbT{-~3q{Ldtk(2$YeP7^RA1oIA;x-7s-VR?ye^ zJdsspl2YhAoI+KsoKBq0jIK60KFv1x6)o5!Ubh-Vax)AmglnP_cT9^UB%>7`mUMQ!0CtP@D_!jh2CyDnS80_SE(5 zna20Bu_r$E`Oc%T1NAVU1%K1AUE?E;=&%x=vVx(%WtHDm8KBp}7C*+h^i3XG zZ#GFE8c?)2%+{@7=-M<14eaC!S(L;EGo9L}dz3ECIcOad3NO`^t~9>!NQm3~boVwZ z{ar9cTm7!9@CP%xTq}yC4st2q9D}WaMBVzF%2-Ibc^HNRLN%o|f8Rj0S1@-7-k7OQ zvOM~Do6;(D!ES@_;<6}v62sA4rAEs8F4Bwgai*-KWaBjoE*o8m2)(cI68YCnnxj$=O zsyGhkV@*eCh;+R4b@l@*fVfN_=wq9&o8tR0zexwb>ty6-rtIh!+so{*XD0i69ZiIuEROzLy2}#6y#-+No&r>>?F@VaTq^@s>!KdNTZzsdIN+}MxQ zxYYQRMEfXNQJzxEGf8rrn;W;z9G@=C{L@`?+3by|V|e5BCNfX^bU-^kDxFI0+k?8nhf_AQsKc!n z+~P4isyt6`ecLyB;d{|c z*o@$unpp2vq)%=JHE%Q>!EUf6^8O-W@D=aE`kD<>0dh%xr~HtsFY#nSxV6 zCr|PM=j+Ob@$vj)Y%sAr_vb87G;nYm$Q7NzX^iPs*SF@+0XfO)DbpId}CgK z=t;^U*~_`=FI)b|WGV4<^R$KV>Pvu8NBnf9@9C7}B;ufqtR{QLLY{^qbEC==4>CaH z)S#D2b0>@kiCW0VtP1joyes5)yJjNUD_p`$JAC+f+`OrAd#J_X@qOI(bA<(qjsgu8 z5QOAmH|SP-&rI!=6Em%>FX{p9l-0&yI>-18FPjvP=BIZseBRw-Kxi1Vc#(|9PlTCx zZuPv29P9pJKYgy%&w%3_txX+}Ge$FVXeMo}@!pHdgVgJ)>z%-aALrVtdWUj0Kf2<0 z81aaK!%;7bBtvn!!a6j4u0g*nbBa$oStse_xU+Xi|Ay&9v#Y(!k7Ag|R)*IfTW(-j zv+stfKdZR=$jAWX0~^%=&EAy}i|+?~cjq8~*MqFh8kHRm8kF4;%hvBH1pC&% zWT?^w$muq5XTYLR{^(%r6+W|FbZo^7iK6eeTVEOHF!C6O)1&=2lWMCzi*;%S*RExP zBpd9?+g|@MIkiu{kPE7IHNi33QLF)14i^B3Y_3-G_w+!$7S!k_&en$OU9xhtU1i|s z>VXPhUN`z`O_a}~W6wl~DA|;oeRj@^y%LfW-;p3=@CrwRrONXpp$FG~iIA%@ngG_f zgv{9+ay9+*;LE4uH~msud96x_L05M91Nt$UQ?l8Xjs~H(?}OBIK37T*dxZo`0Ee6G zh|@CFPT><}io*~&JIdZ;A^uZ*;GazBd3ZO^S`*PTJb9P2@v`LP(&%LRv&DcKQ{LS_8Ym z{vzUw3SGv?j!soY%^DtB9qp#Rw63781i6p9-!G18z{St(buygVP4xv+-z&@0h#qj; z8*$l55*6Ee%I50(@5fZlAt2p+4}=`FL{?iUq+Q`+Kq0+)-jJx?*5p zTsoWrE0ZwCfQ7^TzPJ~VuPE#O^aH7pA3yGe>9!%z{PH@>Ri6I#8bx16?!xYVHQ(5e zwZF-F)Z{OpncFMczo=23BkyQ*XVLf55f{Vrj`4mYk@I(5YI<~QfNl6oLc*C9R+~=` zYSHxKrX)L&8$xcn$5Y~K!*HLS=NZ!8almV8Hk6f*6+1qPkq`R!8*19{wv-w`DVFV$ zNgWfL08Znmx*ABNpJsf**jV<-nu_5e2iroB8+!l9_?kz6PPqsWR*B#yH)!$E@v%XIN1OMbM-2>hD?(H5>jxhtl%SF-ia#r!%cj+qh+KQ9#>$RT3XzxdMr&_ z&ITh^4|k(}#4gI-PIa@}K)T*p`dEL)2bF7Ut5!q84Y^>1pVFf6<)kB~hf*>l@*7wSnBt*f^1k*NB)igV`PJ(LLD?8;rY@lhCwSSPQY~CyT2LcIt z)T#RMRQ4!L3|UhD)PL2CChYg=3*1i0f)V5>7`xZ|3is}+ECvFmX7Ks{&2nF9b_`90 zG{8bh&qhv4AX-YO1)bMI0zT^4Q#Jhiwg~S+-7ciH8Y|!NIv-r$*3aNK8KglCjE6_{ zst=?-g5iVGsQQoPn>U-QO5+^uUR$=&C8)75sd~ZLNMK7~tzK8;j97m-`xA}- zlJzLsHtV0UI`rT^OmN3)SfM7rxIf-|038S8c3n_+hu-c|72w3s}z=mAsCf>u%W%#4N|0>=471237seadLyhuQ&N z5GVkq-$e8l6wsLJ3OWQt%M+%1Vo*T7`Q+YkLK5WfOHeKeqhMG0q~;A2Hzbp*x0+CU zs>Q@uCtQ91&AADHv}=rqjJvK|3Pb^Rjv=Pvgqn{9OrO^8`#&S+T|>TKF&qOnzwGQX;-YFz+OL2(D=tYXcGp1iIW;0c-R{Y-hLA;C=T1x--P zi&oYB`38ZlEn1iKih)GVW=5$J9A>~9=)Y&iC@_NY+CB^@#Z42_%NYRVs*=XL z*0a(^j)!}&Y+w^QurnA#YUH)aD~NBwZr1*IWqu$ZD}J-&TJmP(Jgh!ft+_tWW+z|l ze(o!Q;sh0no(6-iyvC~Xm*K=)S}UB1Zr?_;q)^P_Z^KPR3GLmjnw=D;WM=Dnsy|Vz z|1L79a{WV`D&&^#cV;4PD8}|=wzW{x#5Wwpw;q+ssF6Xh&ayP_u+0_B6U6sYKU=&% zc-JIVwB}`Tz9fVusehRvfg{XPKdbqjNp!+jP9Z|X_$}6{wYZ>s_p$`XVAA%vi3*Je?T%DuhZ z>f36>b39LoYbSH5&*@U-^5iQ z_T-nxxKxA3UQtMkK|Pbvn9Fb!wGjdSX92Ui*DH?_*o=Z^fp|-g0rZH$s@^Z!|Exf+ z$5`%~rP>~obRO<&aKQC(gF83RUKI)j&WaBovKS;iUUC$FF1eylP(f_p6$D*I=WgFf zd7N`;WaWYX@3JMSF=1yyBNA8}`R8SlB&kEo*jYH0!?@h}f6ur#|9J@K&=( zKOuD}e9O!(tU{KgoY3_{U#`h6pwt7rzgo;|cipB=6olM2esaC}jXCe?#pSXsFg175+4unqzfn)^;$1vOMoki&B z#GgUE`}~PR6cd0aL!T91*uO61f<-hLf2xZwSNbbL6yOL$+rGNgP}DX4@^9zuG%eae zT}(CSY%!7Jpw%v-cxGpFb&H~q%SaUwk3q^LXPApk{U^pRIB4`oU~nK#ax_2HLP=@3 zd^Fm%9c`NIc)X>;+>_aQw?I%g%Bd6oP*hZ?P(Mg~dp0q-C|jVGpZ7m#@r=VoEkW}# zK0Jo}-%)&g9v8b_)aavJD;P7aW$bg(SH`_%d8_L=yjQlPp?X3#CSMF~U(Wt!m8@)! zr%}@t(~bAUDMGu>EiL0wIjKKU$ce)HN+8_VufLn6X?JDXjJ?YF3ysEY=6&(3jOQnb zAl~3ENS&7O)`C8URFItUY22dr!zwYd9gRNNNp27PK)qS6>G=Wo+~Vy(`TBs>&4`e( z#D4JpkFe&x7W^eI89%ziGZPskn&C&ady{JI?q67423v)>!~N53j&_-?xkg}b{hzg| zK{ApntD(5SPNB|PScruriPst<2}D>1g8`a#N`JU=_sLK7iBeWs-fH~&0!zmt$epH{(D(s?1q&#$!6|HD}WZ{<&d{>5tjVyc(0_u4zPvEyjhgrqor9VVHiN6nKTJv?%o zvR}iT!Sw&3Hg)9?2W<_+M`-#qhlbgn59ytr*HQ~}_C!Vqli`G4 zO_-EPcbVWv)mk827f~bu=^>dl>b@pVWYlo4BXY6BQ>{dOBT|VGvB8 z&$00QYLkL?Ob;MNOvPOu>(Dyl%k>Qh7HvSHT8jA1hQEGcn!%HaVp^OpcUFPw6suD0 z`UU)Ellg6|9|~7j6oBHS9_*nrBZ3}a^-hCZyhbC%K(VPo0i+)5!=*cbzUejH_@>ll zu|~TNZN&;diBxC?d7)_`zM<7q!i3g33{q@z{wGlWB_KJ)%j!%F-^T28*f!v1@B*QN zK|b7MBpp#UCuN9*bCOa^`Y&aqr*9)>1O{XO=dGTyCT>q7q+^mMQ=#D zn=|s<41_Dg4+Q&zukJxl@qnKxJ>nRc4{5QE^7A&cz8>4$4!dYT(YybKLtQYd)WXK8 zS3Gf|cw@^ymFfh5@asLm0M2N9v>_0rM+$S8A0ujVhMb-sp^ta&cf;Bi`lX0YC1YGy z398n{&s-)ut(k{vtADpd6AET#2RIWoW}*!gJ}Q<6Y!4WW^-~A_*~qrn4b-ne>s7u? z>KoZ*`=T(gjV({GIm-LJ^|281>_R7b<@$ggy5vK39`3P1o8z@uZk zayBpcp#HRlmw#V6&NfAelrHL;i8wl~M@f5Ooq#6e;C7GOIci#ASm^l$A>ahmWs1NzXG5Xhfz{dn^C$rR*uivh_9Y4Ol`HZcQ_1eJDdM4e>dbB zGofX0dcv|3R)t$+@xIrNxO!k z3}+%4v>czCn_IN~yk@#ePw%0}$+j2KO(D=}z@cGhXV=?$yAw3*8l%Y|*X}}{{NQDK z(DkrzwQIf((y6FyIIa@uls4&R_E20n@=g1R4_*co*sK zc@xUNtCiz|-)8yZ!&l8GhR~7;KYyn)u?qkLyVw!8>Xi%l_r-1jogr@UoLTZ+yNQsy z_Q7;n=Eo7Ck8bG@+vvF0a``0l?Kf>=&bIThDnQE*5a!W6nG!}kXB536t^mQ85VcB9 z>$rzEc@E~yl_&ORb8A542iueBZgvn52I0N?FSbMK-u5(9@uqPnwx!6HGh7w+6OkLi zgAHp;%`U(i0lu2rG4TN{Hm&I_rskcYP9s6(e#RcbT(w=!^$A9<=fa?Cz590F!*|h5 zvdSHC@o$XTVS+bR+;;K>Jh^SRfs%7Ap+JZ1$aaSByCk5eKCwwA+xa^Kt0cKBj(=2A z4Z=o`7!JI1z&})z;~kD}dHK}p#}n4osA}8wHGB`puGfCP_RTJ-axXayi%HZ;;?PqI zB=G-pws=T>1=arx&k{=@I69rHwT$?xBBi3-c^MC;<7{ITV{j6@06NdqU^Ss#H9{(@ z>Egx^?z4p9st(<2jUVlYraVQ`)?6CKo5NAqW@5*C*}S8WQtvQB$PvphQhl&4s?5eo;ais&S(R`x=8@IZ)65(uA`EcmUbMp8xHK(No zJnCQ(O}jH{5TWr&EIv6=w`4m65_la4x+24^svzQDK+$fUE*}Dsp+TvJ+`5&n0M<}= zStj*tfAC-;r-ab&q+%twpOeM>TTgi4Wh*?!v0!PZNAqZJSh>|oh0)75wK;*RKwVaB zB(%QFp4^*4;dP>1&RPwdYu&fn)H)(lZhgyG_OQz&lfLmmRIY?EF&RBy--KI&FwiR; z57fxwd>N^UUYxyD_~kk7)KGrLXf$xFBbR`%^mp;XUKttPkB-qr+^$_5i#gNmL?|n8 z*}XrVBQpP-TUa=@o2t6^6WGbfY6I<_xcT<+*n@iN!sB28q^7POr#|99-Tm;5)Z5|K zAO-0}+!__p4ONe-8V$`oW+~tAO}?j<1F&mP)gz@ zMPf~X%Y5BzozXLHbH)EeBcH6@#D$(i`^`L_*Vr%8UIGt3I(eNynP4B(=6U-!4ZG9t z?Zhw_d_$yYga#aHw&o;mEE)s+*{P7(M{nFmxK4<%3w4!>B8nrwn+%72Ql11s;TAKF zD#L$0ntJlv8lQT_M4)FyoVgZYf(3<-Xs60GBgqRBf1@81@$tqNAHCf&Hp{(w9lV7c z&&keqa_G)J)H|7yV6dqgOB}Ybwe|Xj-?E>*lq3*clw@yDhb22ID$>v0&KKd=Q`di# ztLYx8;5c06_NsPHsz#S7)0E$#ZXh;Q={T1~Vch?9#c$ca5Ez<%yBZYWu>R8~c(KUe zVO3&E8fqo}V#l!A;i@`d6)HxSHXrxWC<^NIW~f3!OO&a}Q+<2O;J$$0She?Y4T+Oj+G+@)_ZB_SceTXzj}OOj(7x6o+9o#ByUz!>^`Qek`G8Y zDT6Y6^foKuMRko->J&p)@Qb2i^0=j7OOiv&a{13{hB97+lxv#?&ddLO9q3U_iFUwr zX9Zlb4NV#^mv+_WV2AU5c@t;Y;SRHeJcn3FdmGt_xSd`RlUMi8zU$f>hrTIiwU&}D zAKW{+edm(&#$0rKunB6j7d)fk-kcl?g1y@uF;gKtIcc~==EyUl#<@vxMRCcNnnZSoKMV4@mMEqL`x zr*mS82>Lf<>F2##_4~H2_|o~Zg*UnRcz1%^@5AO-tt#02e~DW8jUSFa z=e;Hf^fx~h(v@l+SsD|rc-5y5?FKmX48dLfM% zHiEB4%C;wD={k{J|CEe`X({K3+cRI*bFzKK?=93vGKSBa|qgLfFrw3JdD%FW7^G^Wx^jk`%uvYV`W=&?Da=;z^< z1d(o4NY*Ki4?VYxf6V;6;r?=b<`c(u6O@kqL$W+fzp3@X(m_ntZbqXx^zISP>y1@C zV9HgwL;5IS9O^e{tT`Qa>s@7gu)w%{h$!QW_g!@g(+2(hfQxYCQ(E@pjO$EF*xKqh zLtDb0;uZ<=*z=y&zzY7pSDMc!?>an4F%uTfmk~1}E>FW5~~@T+1ff_X_6z3>YCgxua0 z&6w~$DJd{r?Hn=9nl-sQOTKK7fnBPj2m(5BlF2HV_X`-#w(AQ#_n`ZSZ`KP@#w_8m zv$p16u6jTq@7dnb(Z$Dnv72W60AttrS});DVEyTRA+-H_S8ae2{?;`XyPeIr8Y)R? zxAohx%4=1KyIU>Uo=mPHA^_;>$vr6I{6n15^K%#~^s~{VYUFLM7OB1ny-D`VDMM^~z9A(oTMTPyP!wN5)~efd(C6C2~DwNxAVg+CA}P3V_9A~Us4T>NSNh0pet z82LR@($ThR+JHqod)l)_D$XteQNO+>U=tQL4?S%B^X$Qb3%;DjY2~-*16IA^%18OS zrTTc)@@ncv$y6zcwAe~F?F=a!BwYV(F>Zga(ycp*S<+(-KyC~Tzka2aew}$W$Dui( zF9`NeeUeo2cCX95by#oo39YzO4bL^j$bf4&1 zGvi;*D&0;>dq%4jn?a z+RzXJNl5?sT{j|_DGkpTk5-C6o;mxmnl6HzWYmOPjXb4gOE8{((fpAjfeR5E$FT^o zMal7ekQp8JZoaTZ0ZF8BPxj>K*eLeQNL0nLvON5ZyyB^&qGxzP(GT!Oe~fZ-f-%K) zswUBSMlt6+`C^?J+!K5`lI~KHzQv+r(<%Y|RD8McDF4gZm-u0#e;#g|ntt!!#zACS z^^sO{T=e!7Nps)jxmBa$f3LmcR*S9#Ji0g+`_2$ZokB58w zlwfFiEbwR@dW~!b1nZ3S_&Zvh%&bV#K7X1YL4{Pj$9D7bto!r@-jQ2$cER%SaZ}pT z2Ht@o#A#Xqc^c(3*{K@R|JeG#g|UomOnL#*0>L+BaW4()>isZarQ#wA)5@4`)gpH> zb+qO*`Q_Q^Ybpqj=SvrwiTV*oF?e-5d<@pj|8|RW!V1W0JD>_;0$x>m^Y_O2HrJmrK=>V=&(}eJG}W#uQd3UtmJSi_uNAGr zRl5Gt&H?3_0aUl^C6nyjtV;I%NE^pEzWctXyMEBcqB?7dao#%}l+NcJR;5oyeFeos zA3cuH&+G*DV#5dssByGMo6JG6WI)qOomLuqDjK9Ca;{aBO1&TH*{)9qQ%^}^Dvjuk{4@WMc+ zKp4~=r7{fUh02QHF3i9xE-Q##lU5V~j_X8c|8==5`RUnnhS5!(+0EGaFGsCG%ZW1i z|Iv{Z%KgeOzU!3iYsvcXK>2{6(nQ=%kqXt-nN>HiH+tzelZpq^7cxz#(>Q)ri#o^^ z7oX5FXEY;#E$yS}#~{=Hjot6E`bK^fx1Fs?`#SL{>*a>J=_|Bthe23wg2>h3joDE3 zLCJe8C9VDFJa;h7+75e&B}{<_dtX(VFhS`n=JO&pl{PJ#Gl??o$zx}Q@2XHA-<+); zH6!t^5Ts_B0tuYXxg*)u!K_oORJ=UaXGmZyDL-mw$(3Zdqs_;vsb$OW(d_}b(mu0pE z)}p|qjF4+J3Ca`{rT!mD=i$%h`?g_QYqmyP)aVzrDQa(8yY>o-nzd_7jG$Cod)MBZ zBDR`UP0ZMPkJ>^+Y~JVhdH;oc@;uLdpVxIBhhA2Sb=2gin0BPgvY18l4X{e+Ei~EM zKXsawJqsTZB*|`2m-OjAN|x!~ZXvWjTcnCEcH;W4C$v+Sl`*|(^4{=6v|g61Pim;_ zds@akmA?9n1b1W($(6ATq{fX`dY#KpzPG6dt}-QH)}V8=*uwP`nUy9oIDSyqtX_ATObkUlC~jQz!bZ-9sbpon;C-`yMvUtVqeqGDWBLZ!&< zxSx>r?@<4TWHwJ_?h5>0`eqP(foAPjjZVb!VT6|h^&!4494hB73EIq-X#zP*DP1=w zUg@IXuYcZLsaC#puPk%ojr6OYK^pg5_OV`W%xG^F5}xjT=pWHc za3VZw9X#K>*mag%f1$eTPMvK{^N$ml>|9JHDsWBU*19mq?GosmD@De{4;ueegH@ms zZ2nfP$0oOWZ4Uy@HFhl({2)vg4g}`bd3R+-C+ac_d=za}!wt>_(%^B-83i>znQXVY zM&(ptJ`E>vazXA*2EtDYH~UWEiP(S=D?t`rK~$|%d_{ZN9k})!x~MbIsE*MvfKLS8%imsV+pj5 z=547>B?0WW>?<*mP!oDOu`)$sa1$rLy_#P1cTkLijFg78zrZf_x-*HW;2#xh2zY;Z zS+A zixA%Wz4jgko-^0S+AitDb+Ym3(zZ2k1$$K|c=X;sE8WhK=VjD!sijyr%hHX@xk7XL zjlY!W!ePn<6cO^;N78rFHN|6suNC{ntbNM=jw>nv{+|-KuM1LkW zr<GSnn?9H?|jV%gn-6WWoMQoe)or&Y%GpcqgbHe{SJ z31kl<5aXPcPB!S(UV7l&W?R@@Lg3|kM#c5v`VvUWy<-Nn>$=ts_B4VNcVVoK_0q4%})2aHuqq;@m-fqOR#09W$ha$jyL#N+qK$06frhv zkegk$Ev_6Qul-XtzPXBlMyB56WI?Tb@t0exVG7&S$y)IQ%wx=jbed@yHa*TKCXntN z_2rnpiIgLzNljZbWWMF&PZ!HNlWBn;u0|tGTT#5T>cO|;j?{+|Hj|j{| zZ1bdyeqhBWP=T=ZwW7>>)Vd3jW>XGupm{3HAobdv<-O@^*f$wo?!%@0l&#HE*;Rx4 zY_ae*-hPNzGVMRL&Wb~Twq&M0-_sGmdwwwxahe)Mb|b8>&jw^SY6_ip!c`Wn=F@;^ zH4w=UstYV9V={3iVIDQ+-XX@m9Zuug;j#T_C`VUS%WPug1iyMJ?8vPT^EQx&*nRLU zpedst(trD^SXwETkC97Tn?JdRzdBW$zbZA-VY)wSEQpx zEze0FZ2vh8tT9C~0oz002#gDtr~aI{NO4R16ipcR%+;lcL|not8-=5ieJghAf)%|DZf{1|sY7$++JCZ!UBf;M zB4YgDcg{E%gf?<0zmSH~nsFWhD@oK}k^`G$~v2PLgmhB=^g(54|tv z8ay($#vCe5_N#|f$F5Ne?pw)LA7gBX*6RKQhJ^JWsBLX-MeA&XaZSCj=863VQE)Mwfww>uRiK`2$Tsl9I%7uRVNbO!)A&B4c4=Kv=s z5Yin4cvAII0W-Xby_pRvhIUB7Or1t(Qr28YKTT(*RioXUG@-Wf?r1|kNQ}{N%8vl+ zYU)40%*kthiSL55it|YEHjqu$JV2WekHsl}ujBm&WV|V%LKROPGEpF@n`K~JwEWJ~ zydnANmf7CiaHX*=fa4N^T)YB_`^7GHfR%FOz%Dr)!esRZ-{KfV^stBXT$Id<6Qsa! zWC^C`w$#qgAXb%B@H>!eXe2)P3XHG*o$Np)XwdHK@8vus$@%=>Nix_rdg!`pk2)R|&|-pq4~2Q$Ndx`IfUx=yMu13- zdN_{f2lLQD+itW-2dJ~-1UPMqv!h6I3D0+mMh#4yPLC!{@!I@!`by*vr*-E=U&x|k zdon4Wnw9jJxzD3W53;++58nSHuh|G(8@%UR%?{gER*^Y33OU=G+ptr&5zDOo^EJlw zgcBm^3t+ArE5rT4px#oyc)!(cLDFBN;zT!UqYA`$k)a*@;hdq}uu!9YWhv>rVP^p9 zGytEV)Q=A@r^41!dan}b)Kk7e?4>G3Uv&XZV7xt;cAh0{*S1m zCQhUI-&xUZBue#~2sMA!J6^a=;gU88$5z0)>>7(rVk*Iflzm+RPg}u9wbIk)OR|;b zqq?_=mr2Ej_2)%C8-7Jf8-8}E`C_!9%H4S~1Eu@(lx<3_!Jh2FGr#ZSUb9M&Yl83Y zlrjz^*xJ#L57F?al!BG`^4HhI(-r7SsEp8qj*@_hH^Ky>I~u@$xZyIY_^$%+pdj6NycnvThQ!kI1U+7?@TJW=R^y-CZJ zNhnxUOn+rxWw-L??Hk0+rT*5%3BDwERNC(_>A{^3lQ=`6k}K&!89u6zA^bpXHS2B) zz*($BG~!I~LHB?&07r|}mCB50G${f9VD}NA(q!t^uL&^sv8*)il})OCNlC}jI}qh! zJvjnDEK3fl&ztYi$5o;12u=-ja=R`ty)SKbevf@m-%PZe?%1J=kEXj zr&3{-Ep(g3E8A_W{k#Lv4qI(KcZ_|`!`JeipO>=;Y^o_beuw>=%m?&ECSTu8%TIaL zH@RKpFHKH%pX|;4O>J{No@N-|SrQ{NAh7cKk@!B|8Mi_}_HwqVNIj);FGtcN?73VZ zu=Lo*Wk}*8545+$TcO)cyzgNMbvjB0NfQdjMS(Pd_wgi#Clr{e;y#iyPkgC7;tN(H zgSiT$*H5Hz=_M+z5bKCSGDX|6XdbQ9ATQ$n&#d)Z^`tzTeRCk_8pU0Zg+(rk*5B0Mna^GFK}kc5Y5YKF4c6gQLD8rH5%t zv!Z0GPWM?|9|z?`?DKshL-%ZjI3}Wt2XYZ%U0qy$Pm_Ic=dITH<`u&C19Z=x@8_-L zt1LXx%SvZ~dmDfuD@N&()_H)5boYK%sY^v;@Q<~f-pWUZ zg_azj)=hR@sk7}a*XISnsP6HsX!0xNd@0h%Z5+AfV3V5BwD|KngLllg!(|bl4|_j` zoR6wDyA-c*u#4*XR%HvEau^PNr(?BU_}&T;*!$Qrc5U>Uf3dQD_;0C8cuK6vtM}`e z45x{f&Udm0b9L1Rb1f#=s&t;rRLwNn)0h3|h@@grVRMmPZ*!5?1f}g-_+yygE!7+> zu+7Cp6y#>H$eQ#eMIC05tFY9j@inYNMa&&vO2koU+>4h{P@chR2!WttW|qTe&yfMj z<>N1}|6mg=mhWIbhcD;a-ICZ|I!0EVgYxcj97eK|40&eC2c}0PW!{Gl;<5CjcT024 z$S>QvJbqZ_@n#9W{rSGtiB6K*#}@T4>x=4ew@_=qb=9AJFkim_tnYW>f4#Q-KUgabY^!(e`em1Gy^WM4^-bpuM8CukFDbMIs8<*jbNb|`Lj4kt*mn-9( zS=9y+N?!rofoD7YL#>`JrRGv~W&yYFJrAEHm6;^l{wfa)t19!&(7&Oq4b#k@TDg)RQ2Uh~;`P@R8eF53NESJu^o@Vp4WrV>PPMTQ!{VtBToqUy z%)^I?4AfjoFlyWTuos@rE8bua&je}X(G}SyW$3v<1h|Z*_|3EPuiB|HhQtWf5^H# zxiB*_umazveUOiM*e*#*WKxgxNW`!G^kDT04CcAG<^9Yd`X5k1`}jR)UNo9yal574 zrL>99?o(G_x={NYqak`eU=KVokH5NDsqnnWEQ%=Am(<}UMLDeHZ^7;cn}JGrb;AaS zZb8&?vyJn2yMH_CjO^s`5fdtdKRyICvVtv5%L`D`uudB6w@Dt85X)X@Oie zrE5FL`r9ig#BVGiGA&r{@W+1`DeA7TdMTNyIj-qqWxhbiA?S8E3GNPmf?Gmlc)0lA zP1siV^b*W>jyv-pycDUpYGPwR+_%of$y*!EKy$0YEYlpJym$AP^D2e(-#}>4HM{6b z1?5<#YL*h1Ydl#wSHiU)QY|ca1UTKgKJjX~JKCQ{rgQ`}a~BD-3(IIg2n9(~@$7R< z!t}API|Ym=SZQV+zM_lj22>2AluW=%WdP)`eNiG{D6H5mmv2r)Gv~LygXn>AoSWIJ zvkVHZ(OACfb#wnH?4B z*Prc0Opbm%&MLsX^x+8w`Kl$Pe6qi@r@k~$Py$OM8{m0a#C2uHL205AlKpu-S28f< zqJqRhhzth@!$^acr!T_+1M52N#CXe%gFhZO*buSy22Ovo+vn0=RL4cKF-m?dNmUcn z!PS&ldq{G{+<9r*TK~~ z17EilC#<$z9Xz*YGU~ys%^1$r+AYt!t-=R`r(VUH3hu>^45qeA_a4c~T6h{xo$Je^ ze(3TwpAW}Bg+I;k@wz=$H&d?_mr+y~{;zll5LyJ)U#Z%;!3?&FRqt;MoNql7$!{ny zWdTjI(zB8{%*PWt=LA(rG4%@}j50hJS-S)U!|D;wSSX)V&mpXVd~xeGMXhZVMXVZqmzdKXal-Nt@C>8<5Qs z(V{)(y?cDL&(l+35x_ND>lsFi7@ME7nfVimX$mUc0|aUBTtd^^n?9)zmL$?K@K2~r zsje(~lm4@L>=E=q;W7SR(W{dBHK~G4z*V|m!X^br|9el)AP<;yzOy4GEM-rN{j{qK z0bPiCP}pn?1H(Zk*M(ZW%{0e;UydaBulhXE1@X5UUv=5#C7%@)JPfpo^o7e)dXnXG zPx`o%oyTk^+<~gCn6)OYG`}YLLp

3Vvc1i!uk|07G;`N$-#<* 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�z=1t2% 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

UgVB`AU6awo6AU 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 brBK7_KX?_hw?UbZArQyoF2^eEe1HF6KUhs$ literal 0 HcmV?d00001 diff --git a/example/peripheral/i2c/figs/board.png b/example/peripheral/i2c/figs/board.png new file mode 100644 index 0000000000000000000000000000000000000000..3d385e2ef09f34933c34b4e29d387d110e293fd2 GIT binary patch literal 573070 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

pJcTmJk#UV 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

JYvyF2;9+gYRj21qZ4-P+_vb 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

s(|-`fqWM{L1PrMKV-^r`C-o^3UjF9J`cWRc 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

G;Mz_eDu!(>KXsc*2H^o_3`(|`eUJQc=fkP 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≻Oeq`GdvZZIzbg~bj1T}382{D~7Qa9XdeDDiF2eKeyoi8A zRX7H<{cJtf`h^Ptd|ip4f)iI|!mTY-i&Zv`FL&kWAI�j(UG#t~giU0-gwZW6tEO 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

  • VyB`D@m3diXspUciw>Wp7+5xi{woSGfFT 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

    #bH#awkv#_P*)2nn~IuM8sk0rq1 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%0DssQ%Q`3O5Rxyn&Fe4w+D?$YwNfFThq!x{PGMR% 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 literal 0 HcmV?d00001 diff --git a/example/peripheral/i2c/inc/i2c_example.h b/example/peripheral/i2c/inc/i2c_example.h new file mode 100644 index 00000000..6b48115a --- /dev/null +++ b/example/peripheral/i2c/inc/i2c_example.h @@ -0,0 +1,52 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: i2c_example.h + * Date: 2022-07-18 14:41:23 + * LastEditTime: 2022-07-18 14:41:23 + * Description:  This file is for i2c test example function declarations. + * + * Modify History: + * Ver    Who         Date          Changes + * -----  ------      --------     -------------------------------------- + * 1.0 liushengming 2022/11/25 init commit + */ +#ifndef I2C_EXAMPLE_H +#define I2C_EXAMPLE_H + +#include "fi2c_os.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/***************************** Include Files *********************************/ + +/************************** Definitions *****************************/ + +/************************** Variable Definitions *****************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ +/* i2c write and read test */ +BaseType_t FFreeRTOSI2cCreate(void); +/* dump buffer of slave */ +void FFreeRTOSI2cSlaveDump(FFreeRTOSI2c *os_i2c_p); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/example/storage/sata_fatfs/main.c b/example/peripheral/i2c/main.c similarity index 42% rename from example/storage/sata_fatfs/main.c rename to example/peripheral/i2c/main.c index 83f73cdb..4cc00aed 100644 --- a/example/storage/sata_fatfs/main.c +++ b/example/peripheral/i2c/main.c @@ -1,47 +1,52 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: main.c - * Date: 2022-06-17 08:17:59 - * LastEditTime: 2022-06-17 08:17:59 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Date: 2022-07-18 14:39:10 + * LastEditTime: 2022-07-18 14:39:10 + * Description:  This file is for i2c main entry. + * + * Modify History: + * Ver    Who         Date          Changes + * -----  ------      --------     -------------------------------------- + * 1.0 liushengming 2022/11/25 init commit */ +#include #include "shell.h" #include "shell_port.h" -#include -#include "sata_fatfs_example.h" +#include "i2c_example.h" int main(void) { BaseType_t ret; - ret = FFreeRTOSSataFatfsCreate(); - if(ret != pdPASS) + ret = FFreeRTOSI2cCreate(); + if (ret != pdPASS) + { goto FAIL_EXIT; + } - ret = LSUserShellTask() ; - if(ret != pdPASS) + ret = LSUserShellTask(); + if (ret != pdPASS) + { goto FAIL_EXIT; + } - vTaskStartScheduler(); /* 启动任务,开启调度 */ + vTaskStartScheduler(); /* 启动任务,开启调度 */ while (1); /* 正常不会执行到这里 */ - + FAIL_EXIT: - printf("failed 0x%x \r\n", ret); + printf("Failed,the ret value is 0x%x. \r\n", ret); return 0; -} +} \ No newline at end of file diff --git a/example/storage/sata_fatfs/makefile b/example/peripheral/i2c/makefile similarity index 89% rename from example/storage/sata_fatfs/makefile rename to example/peripheral/i2c/makefile index c1f632e8..d5622739 100644 --- a/example/storage/sata_fatfs/makefile +++ b/example/peripheral/i2c/makefile @@ -23,9 +23,7 @@ include $(FREERTOS_SDK_ROOT)/make/build_freertos.mk boot: make -j @cp ./$(CONFIG_TARGET_NAME).elf $(USR_BOOT_DIR)/$(BOOT_IMG_NAME).elf -ifdef CONFIG_OUTPUT_BINARY @cp ./$(CONFIG_TARGET_NAME).bin $(USR_BOOT_DIR)/$(BOOT_IMG_NAME).bin -endif - @ls $(USR_BOOT_DIR)/$(BOOT_IMG_NAME).* -l + @ls -l $(USR_BOOT_DIR)/$(BOOT_IMG_NAME).* diff --git a/example/storage/sata_fatfs/sdkconfig b/example/peripheral/i2c/sdkconfig similarity index 70% rename from example/storage/sata_fatfs/sdkconfig rename to example/peripheral/i2c/sdkconfig index 6b410bdb..f08739ee 100644 --- a/example/storage/sata_fatfs/sdkconfig +++ b/example/peripheral/i2c/sdkconfig @@ -53,27 +53,29 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_GPIO is not set # CONFIG_USE_ETH is not set # CONFIG_USE_CAN is not set -# CONFIG_USE_I2C is not set +CONFIG_USE_I2C=y +CONFIG_USE_FI2C=y # CONFIG_USE_TIMER is not set -# CONFIG_USE_MIO is not set +CONFIG_USE_MIO=y + +# +# Hardware Mio Configuration +# +CONFIG_ENABLE_MIO=y +# end of Hardware Mio Configuration + # CONFIG_USE_SDMMC is not set # CONFIG_USE_PCIE is not set # CONFIG_USE_WDT is not set # CONFIG_USE_DMA is not set # CONFIG_USE_NAND is not set # CONFIG_USE_RTC is not set -CONFIG_USE_SATA=y - -# -# FSATA Configuration -# -CONFIG_ENABLE_FSATA=y -# end of FSATA Configuration - +# CONFIG_USE_SATA is not set # CONFIG_USE_USB is not set # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -84,9 +86,9 @@ CONFIG_USE_NEW_LIBC=y # # CONFIG_LOG_VERBOS is not set # CONFIG_LOG_DEBUG is not set -CONFIG_LOG_INFO=y +# CONFIG_LOG_INFO is not set # CONFIG_LOG_WARN is not set -# CONFIG_LOG_ERROR is not set +CONFIG_LOG_ERROR=y # CONFIG_LOG_NONE is not set CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y CONFIG_INTERRUPT_ROLE_MASTER=y @@ -114,6 +116,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -150,6 +161,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -171,12 +183,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -188,25 +194,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers -# end of Component Configuration # -# FreeRTOS Setting +# Freertos I2c Drivers # -# CONFIG_USE_LWIP is not set -CONFIG_USE_BACKTRACE=y -CONFIG_USE_FATFS=y +CONFIG_FREERTOS_USE_I2C=y +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +CONFIG_FREERTOS_USE_MIO=y +# end of Freertos Mio Drivers # -# FATFS Configuration +# Freertos Timer Drivers # -# CONFIG_SELECT_FATFS_RAM_DISK is not set -# CONFIG_SELECT_FATFS_FSDMMC is not set -# CONFIG_SELECT_FATFS_FSATA_PCIE is not set -CONFIG_SELECT_FATFS_FSATA_CONTROLLER=y -# CONFIG_SELECT_FATFS_USB is not set -# end of FATFS Configuration +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers +# end of Component Configuration +# +# Third-Party Configuration +# +# CONFIG_USE_LWIP is not set +CONFIG_USE_BACKTRACE=y +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -221,7 +234,30 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set # end of Letter Shell Configuration -CONFIG_USE_TLSF=y +# CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/storage/sata_fatfs/sdkconfig.h b/example/peripheral/i2c/sdkconfig.h similarity index 69% rename from example/storage/sata_fatfs/sdkconfig.h rename to example/peripheral/i2c/sdkconfig.h index 08f529aa..d004b5c6 100644 --- a/example/storage/sata_fatfs/sdkconfig.h +++ b/example/peripheral/i2c/sdkconfig.h @@ -48,25 +48,27 @@ /* CONFIG_USE_GPIO is not set */ /* CONFIG_USE_ETH is not set */ /* CONFIG_USE_CAN is not set */ -/* CONFIG_USE_I2C is not set */ +#define CONFIG_USE_I2C +#define CONFIG_USE_FI2C /* CONFIG_USE_TIMER is not set */ -/* CONFIG_USE_MIO is not set */ +#define CONFIG_USE_MIO + +/* Hardware Mio Configuration */ + +#define CONFIG_ENABLE_MIO +/* end of Hardware Mio Configuration */ /* CONFIG_USE_SDMMC is not set */ /* CONFIG_USE_PCIE is not set */ /* CONFIG_USE_WDT is not set */ /* CONFIG_USE_DMA is not set */ /* CONFIG_USE_NAND is not set */ /* CONFIG_USE_RTC is not set */ -#define CONFIG_USE_SATA - -/* FSATA Configuration */ - -#define CONFIG_ENABLE_FSATA -/* end of FSATA Configuration */ +/* CONFIG_USE_SATA is not set */ /* CONFIG_USE_USB is not set */ /* CONFIG_USE_ADC is not set */ /* CONFIG_USE_PWM is not set */ /* CONFIG_USE_IPC is not set */ +/* CONFIG_USE_MEDIA is not set */ /* end of Components Configuration */ #define CONFIG_USE_NEW_LIBC /* end of Standalone Setting */ @@ -75,9 +77,9 @@ /* CONFIG_LOG_VERBOS is not set */ /* CONFIG_LOG_DEBUG is not set */ -#define CONFIG_LOG_INFO +/* CONFIG_LOG_INFO is not set */ /* CONFIG_LOG_WARN is not set */ -/* CONFIG_LOG_ERROR is not set */ +#define CONFIG_LOG_ERROR /* CONFIG_LOG_NONE is not set */ #define CONFIG_USE_DEFAULT_INTERRUPT_CONFIG #define CONFIG_INTERRUPT_ROLE_MASTER @@ -103,6 +105,12 @@ /* Compiler Options */ +/* Cross-Compiler Setting */ + +#define CONFIG_GCC_OPTIMIZE_LEVEL 0 +/* CONFIG_USE_EXT_COMPILER is not set */ +/* CONFIG_USE_KLIN_SYS is not set */ +/* end of Cross-Compiler Setting */ #define CONFIG_OUTPUT_BINARY /* end of Compiler Options */ /* end of Building Option */ @@ -132,6 +140,7 @@ /* Freertos Eth Drivers */ /* CONFIG_FREERTOS_USE_XMAC is not set */ +/* CONFIG_FREERTOS_USE_GMAC is not set */ /* end of Freertos Eth Drivers */ /* Freertos Gpio Drivers */ @@ -150,11 +159,6 @@ /* CONFIG_FREERTOS_USE_FGDMA is not set */ /* end of Freertos DMA Drivers */ -/* Freertos MMC Drivers */ - -/* CONFIG_FREERTOS_USE_FSDIO is not set */ -/* end of Freertos MMC Drivers */ - /* Freertos Adc Drivers */ /* CONFIG_FREERTOS_USE_ADC is not set */ @@ -164,22 +168,28 @@ /* CONFIG_FREERTOS_USE_CAN is not set */ /* end of Freertos Can Drivers */ + +/* Freertos I2c Drivers */ + +#define CONFIG_FREERTOS_USE_I2C +/* end of Freertos I2c Drivers */ + +/* Freertos Mio Drivers */ + +#define CONFIG_FREERTOS_USE_MIO +/* end of Freertos Mio Drivers */ + +/* Freertos Timer Drivers */ + +/* CONFIG_FREERTOS_USE_TIMER is not set */ +/* end of Freertos Timer Drivers */ /* end of Component Configuration */ -/* FreeRTOS Setting */ +/* Third-Party Configuration */ /* CONFIG_USE_LWIP is not set */ #define CONFIG_USE_BACKTRACE -#define CONFIG_USE_FATFS - -/* FATFS Configuration */ - -/* CONFIG_SELECT_FATFS_RAM_DISK is not set */ -/* CONFIG_SELECT_FATFS_FSDMMC is not set */ -/* CONFIG_SELECT_FATFS_FSATA_PCIE is not set */ -#define CONFIG_SELECT_FATFS_FSATA_CONTROLLER -/* CONFIG_SELECT_FATFS_USB is not set */ -/* end of FATFS Configuration */ +/* CONFIG_USE_FATFS_0_1_4 is not set */ /* CONFIG_USE_SFUD is not set */ /* CONFIG_USE_SPIFFS is not set */ /* CONFIG_USE_AMP is not set */ @@ -192,9 +202,31 @@ /* CONFIG_DEFAULT_LETTER_SHELL_USE_UART0 is not set */ /* CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set */ /* end of Letter Shell Configuration */ -#define CONFIG_USE_TLSF +/* CONFIG_USE_TLSF is not set */ /* CONFIG_USE_SDMMC_CMD is not set */ /* CONFIG_USE_CHERRY_USB is not set */ -/* end of FreeRTOS Setting */ +/* end of Third-Party Configuration */ + +/* Kernel Configuration */ + +#define CONFIG_FREERTOS_OPTIMIZED_SCHEDULER +#define CONFIG_FREERTOS_HZ 1000 +#define CONFIG_FREERTOS_MAX_PRIORITIES 32 +#define CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES 13 +#define CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES 11 +#define CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS 1 +#define CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE 1024 +#define CONFIG_FREERTOS_MAX_TASK_NAME_LEN 32 +#define CONFIG_FREERTOS_TIMER_TASK_PRIORITY 1 +#define CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH 2048 +#define CONFIG_FREERTOS_TIMER_QUEUE_LENGTH 10 +#define CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE 0 +#define CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS +#define CONFIG_FREERTOS_USE_TRACE_FACILITY +#define CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS +/* CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set */ +#define CONFIG_FREERTOS_TOTAL_HEAP_SIZE 10240 +#define CONFIG_FREERTOS_TASK_FPU_SUPPORT 1 +/* end of Kernel Configuration */ #endif diff --git a/example/peripheral/i2c/src/i2c_example.c b/example/peripheral/i2c/src/i2c_example.c new file mode 100644 index 00000000..7068b1d5 --- /dev/null +++ b/example/peripheral/i2c/src/i2c_example.c @@ -0,0 +1,578 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: i2c_example.c + * Date: 2022-11-10 11:35:23 + * LastEditTime: 2022-11-10 11:35:24 + * Description:  This file is for i2c test example functions. + * + * Modify History: + * Ver    Who         Date          Changes + * -----  ------      --------     -------------------------------------- + * 1.0 liushengming 2022/11/25 init commit + */ +#include +#include "FreeRTOSConfig.h" +#include "FreeRTOS.h" +#include "task.h" +#include "fi2c.h" +#include "fi2c_hw.h" +#include "fi2c_os.h" +#include "timers.h" +#include "fcpu_info.h" +#include "i2c_example.h" +#include "fparameters.h" +#include "fpinctrl.h" +#include "sdkconfig.h" +#include "fdebug.h" +#include "ftypes.h" +#include "finterrupt.h" +#if defined(CONFIG_TARGET_E2000) + #include "fiopad.h" + #define BCD_TO_BIN(bcd) (( ((((bcd)&0xf0)>>4)*10) + ((bcd)&0xf) ) & 0xff) + #define BIN_TO_BCD(bin) (( (((bin)/10)<<4) + ((bin)%10) ) & 0xff) +#endif + +/* write and read task delay in milliseconds */ +#define TASK_DELAY_MS 5000UL + +/* slave address */ +/* Notice! Using addresses above 0x50 may cause the loopback test to fail */ +#define MASTER_SLAVE_ADDR 0x01 +#define EEPROM_ADDR 0x57 +#define RTC_ADDR 0x68 + +#define DAT_LENGTH 15 +static char data_w[DAT_LENGTH] = {0}; +static char data_r0[DAT_LENGTH]; +static char data_r1[DAT_LENGTH]; + +static xTaskHandle init_handle; +static xTaskHandle read_handle; +static xTaskHandle write_handle; +static xTaskHandle slave_handle; + +static FFreeRTOSI2c *os_i2c_master; +static FFreeRTOSI2c *os_i2c_slave; + +typedef struct data +{ + boolean first_write;/*IIC首次写入,在初始化时置位,用来指示当前传输的首个字节数据是用户需要读写的地址偏移*/ + u32 buff_idx;/* PC 指向的地址偏移 */ + u8 buff[IO_BUF_LEN];/*虚拟内存块*/ +} FI2cSlaveData; + +/* Slave mode for virtual eeprom memory ,size: IO_BUF_LEN in fi2c_os.h*/ +static FI2cSlaveData slave; + +/** + * @name: FFreeRTOSI2cSlaveDump + * @msg: dump buffer of slave + * @return {*} + * @param {FFreeRTOSI2c} *os_i2c_p + */ +void FFreeRTOSI2cSlaveDump(FFreeRTOSI2c *os_i2c_p) +{ + FASSERT(os_i2c_p); + FASSERT(os_i2c_p->wr_semaphore != NULL); + FI2cSlaveData *slave_p = &slave; + FtDumpHexByte(slave_p->buff, IO_BUF_LEN); +} + +/** + * @name: FI2cSlaveCb + * @msg: 从机内存操作 + * @return {*},无 + * @param {void} *instance_p + * @param {void} *para + * @param {u32} evt + */ +void FI2cOsSlaveCb(void *instance_p, void *para, u32 evt) +{ + FI2cSlaveData *slave_p = &slave; + u8 *val = (u8 *)para; + /* + *Do not increment buffer_idx here,because we set maximum lenth is IO_BUF_LEN + */ + if (slave_p->buff_idx >= IO_BUF_LEN) + { + slave_p->buff_idx = slave_p->buff_idx % IO_BUF_LEN; + } + switch (evt) + { + case FI2C_EVT_SLAVE_WRITE_RECEIVED: + if (slave_p->first_write) + { + slave_p->buff_idx = *val; + slave_p->first_write = FALSE; + } + else + { + slave_p->buff[slave_p->buff_idx++] = *val; + } + + break; + case FI2C_EVT_SLAVE_READ_PROCESSED: + /* The previous byte made it to the bus, get next one */ + slave_p->buff_idx++; + /* fallthrough */ + break; + case FI2C_EVT_SLAVE_READ_REQUESTED: + *val = slave_p->buff[slave_p->buff_idx++]; + break; + case FI2C_EVT_SLAVE_STOP: + case FI2C_EVT_SLAVE_WRITE_REQUESTED: + slave_p->first_write = TRUE; + break; + default: + break; + } + + return; +} + +/** + * @name: FI2cSlaveWriteReceived + * @msg: Slave收到主机发送的数据,需要存下 + * @return {*} 无 + * @param {void} *instance_p + * @param {void} *para + */ +void FI2cOsSlaveWriteReceived(void *instance_p, void *para) +{ + FI2cOsSlaveCb(instance_p, para, FI2C_EVT_SLAVE_WRITE_RECEIVED); +} + +/** + * @name: FI2cSlaveReadProcessed + * @msg: 在Slave发送模式下,发送完数据的最后一个字节后,在规定时间内没有收到 Master 端的回应 + * @return {*} 无 + * @param {void} *instance_p + * @param {void} *para + */ +void FI2cOsSlaveReadProcessed(void *instance_p, void *para) +{ + FI2cOsSlaveCb(instance_p, para, FI2C_EVT_SLAVE_READ_PROCESSED); +} + +/** + * @name: FI2cSlaveReadRequest + * @msg: slave收到主机读取内容的请求 + * @return {*} 无 + * @param {void} *instance_p + * @param {void} *para + */ +void FI2cOsSlaveReadRequest(void *instance_p, void *para) +{ + FI2cOsSlaveCb(instance_p, para, FI2C_EVT_SLAVE_READ_REQUESTED); +} + +/** + * @name: FI2cSlaveStop + * @msg: I2C总线接口上是否产生了STOP。与控制器工作在Master模式还是 Slave 模式无关。 + * @return {*} + * @param {void} *instance_p + * @param {void} *para + */ +void FI2cOsSlaveStop(void *instance_p, void *para) +{ + FI2cOsSlaveCb(instance_p, para, FI2C_EVT_SLAVE_STOP); +} + +/** + * @name: FI2cSlaveWriteRequest + * @msg: slave收到主机发送的写请求 + * @return {*} + * @param {void} *instance_p + * @param {void} *para + */ +void FI2cOsSlaveWriteRequest(void *instance_p, void *para) +{ + FI2cOsSlaveCb(instance_p, para, FI2C_EVT_SLAVE_WRITE_REQUESTED); +} + +/* + * @name: FI2cIntrTxDone + * @msg:user transmit FIFO done interrupt callback. + * @param {void} *instance_p + */ +static void FI2cIntrTxDonecallback(void *instance, void *param) +{ + BaseType_t x_result = pdFALSE; + BaseType_t xhigher_priority_task_woken = pdFALSE; + + FI2c *instance_p = (FI2c *)instance; + x_result = xEventGroupSetBitsFromISR(os_i2c_master[instance_p->config.instance_id].trx_event, RTOS_I2C_WRITE_DONE, &xhigher_priority_task_woken); + if (x_result != pdFAIL) + { + portYIELD_FROM_ISR(xhigher_priority_task_woken); + } +} + +/* + * @name: FI2cIntrRxDonecallback + * @msg:user receive fifo level done interrupt callback. + * @param {void} *instance_p + */ +static void FI2cIntrRxDonecallback(void *instance, void *param) +{ + BaseType_t x_result = pdFALSE; + BaseType_t xhigher_priority_task_woken = pdFALSE; + + FI2c *instance_p = (FI2c *)instance; + x_result = xEventGroupSetBitsFromISR(os_i2c_master[instance_p->config.instance_id].trx_event, RTOS_I2C_READ_DONE, &xhigher_priority_task_woken); + if (x_result != pdFAIL) + { + portYIELD_FROM_ISR(xhigher_priority_task_woken); + } +} + +/* + * @name: FI2cIntrTxAbrtcallback + * @msg:user transmit abort interrupt callback. + * @param {void} *instance_p + */ +static void FI2cIntrTxAbrtcallback(void *instance, void *param) +{ + BaseType_t x_result = pdFALSE; + BaseType_t xhigher_priority_task_woken = pdFALSE; + + FI2c *instance_p = (FI2c *)instance; + x_result = xEventGroupSetBitsFromISR(os_i2c_master[instance_p->config.instance_id].trx_event, RTOS_I2C_TRANS_ABORTED, &xhigher_priority_task_woken); + if (x_result != pdFAIL) + { + portYIELD_FROM_ISR(xhigher_priority_task_woken); + } +} + + +static void I2cSlaveTask(void *pvParameters) +{ + const char *pcTaskName = "\r\n*****I2cSlaveTask is running...\r\n"; + const TickType_t xDelay = pdMS_TO_TICKS(TASK_DELAY_MS); + vTaskDelay(xDelay); + FError ret = FREERTOS_I2C_SUCCESS; + + /* The FFreeRTOSI2c to use is passed in via the parameter. + Cast this to a FFreeRTOSI2c pointer. */ + FFreeRTOSI2c *os_i2c_write_p = (FFreeRTOSI2c *) pvParameters; + + while (1) + { + vTaskDelay(xDelay); + vPrintf(pcTaskName); + /* 获取到信号,打印内存块 */ + FFreeRTOSI2cSlaveDump(os_i2c_write_p); + } +} + +static void I2cReadTask(void *pvParameters) +{ + const TickType_t xDelay = pdMS_TO_TICKS(TASK_DELAY_MS); + vTaskDelay(xDelay); + const char *pcReadTaskName = "\r\n*****I2cReadTask is running...\r\n"; + vPrintf(pcReadTaskName); + FError ret = FREERTOS_I2C_SUCCESS; + + /* Master mode for send or receive data */ + FFreeRTOSI2cMessage message; + + /* The FFreeRTOSI2c to use is passed in via the parameter. + Cast this to a FFreeRTOSI2c pointer. */ + FFreeRTOSI2c *os_i2c_read_p = (FFreeRTOSI2c *) pvParameters; + + message.slave_addr = os_i2c_read_p->i2c_device.config.slave_addr; +#if defined(CONFIG_TARGET_D2000) || defined(CONFIG_TARGET_F2000_4) + /*8位地址*/ + message.mem_byte_len = 1; + message.mem_addr = 0x1;/* 地址偏移0x1的位置poll方式读取数据 */ + message.buf_length = DAT_LENGTH; + message.buf = data_r0; + message.mode = FI2C_READ_DATA_POLL; + + ret = FFreeRTOSI2cTransfer(os_i2c_read_p, &message); + if (ret != FREERTOS_I2C_SUCCESS) + { + vPrintf("FFreeRTOSI2cTransfer read poll task error,i2c id:%d.\r\n", os_i2c_read_p->i2c_device.config.instance_id); + } + message.mem_addr = 0x31;/* 地址偏移0x35的位置poll方式读取数据 */ + message.buf = data_r1; + message.buf_length = DAT_LENGTH; + ret = FFreeRTOSI2cTransfer(os_i2c_read_p, &message); + if (ret != FREERTOS_I2C_SUCCESS) + { + vPrintf("FFreeRTOSI2cTransfer read poll task error,i2c id:%d.\r\n", os_i2c_read_p->i2c_device.config.instance_id); + } + vPrintf("data_r0:\r\n"); + FtDumpHexByte(data_r0, DAT_LENGTH); + vPrintf("data_r1:\r\n"); + FtDumpHexByte(data_r1, DAT_LENGTH); + vPrintf("\r\nI2cReadTask is over.\r\n"); +#endif +#if defined(CONFIG_TARGET_E2000) + message.mem_byte_len = 1; + message.mem_addr = 0x0;/* 地址偏移0x0的位置poll方式读取数据 */ + message.buf_length = 7; + message.buf = data_r0; + message.mode = FI2C_READ_DATA_POLL; + + ret = FFreeRTOSI2cTransfer(os_i2c_read_p, &message); + if (ret != FREERTOS_I2C_SUCCESS) + { + vPrintf("FFreeRTOSI2cTransfer read poll task error,i2c id:%d.\r\n", os_i2c_read_p->i2c_device.config.instance_id); + } + u16 year; + if (data_r0[5] & 0x80) + { + year = BCD_TO_BIN(data_r0[6]) + 2000; + } + else + { + year = BCD_TO_BIN(data_r0[6]) + 1900; + } + printf("Date_time: %d-%d-%d week:%d time:%d:%d:%d\r\n", + year, + BCD_TO_BIN(data_r0[5] & 0x1F), + BCD_TO_BIN(data_r0[4] & 0x3F), + BCD_TO_BIN((data_r0[3] - 1) & 0x7), + BCD_TO_BIN(data_r0[2] & 0x3F), + BCD_TO_BIN(data_r0[1] & 0x7F), + BCD_TO_BIN(data_r0[0] & 0x7F) + ); + vTaskDelay(xDelay); +#endif + FFreeRTOSI2cDeinit(os_i2c_read_p);/*写入再读取完成后去初始化FFreeRTOSI2c主机设置*/ + printf("I2cReadTask is over.\r\n "); + vTaskDelete(NULL); +} + +static void I2cWriteTask(void *pvParameters) +{ + const TickType_t xDelay = pdMS_TO_TICKS(TASK_DELAY_MS); + vTaskDelay(xDelay); + const char *pcWriteTaskName = "\r\n*****I2cWriteTask is running...\r\n"; + vPrintf(pcWriteTaskName); + FError ret = FREERTOS_I2C_SUCCESS; + u8 i; + /* Master mode for send or receive data */ + FFreeRTOSI2cMessage message; + + /* The FFreeRTOSI2c to use is passed in via the parameter. + Cast this to a FFreeRTOSI2c pointer. */ + FFreeRTOSI2c *os_i2c_write_p = (FFreeRTOSI2c *) pvParameters; + + message.slave_addr = os_i2c_write_p->i2c_device.config.slave_addr; +#if defined(CONFIG_TARGET_D2000) || defined(CONFIG_TARGET_F2000_4) + for (i = 0; i < DAT_LENGTH; i++) + { + data_w[i] = i ; + } + /*8位地址*/ + message.mem_byte_len = 1; + message.buf = data_w; + message.buf_length = DAT_LENGTH; + message.mem_addr = 0x01;/* 地址偏移0x1的位置poll方式写入数据 */ + message.mode = FI2C_WRITE_DATA_POLL; + ret = FFreeRTOSI2cTransfer(os_i2c_write_p, &message); + if (ret != FREERTOS_I2C_SUCCESS) + { + vPrintf("FFreeRTOSI2cTransfer write poll task error,i2c id:%d.\r\n", os_i2c_write_p->i2c_device.config.instance_id); + } + + message.mem_addr = 0x31;/* 地址偏移0x35的位置poll方式写入数据 */ + ret = FFreeRTOSI2cTransfer(os_i2c_write_p, &message); + if (ret != FREERTOS_I2C_SUCCESS) + { + vPrintf("FFreeRTOSI2cTransfer write poll task error,i2c id:%d.\r\n", os_i2c_write_p->i2c_device.config.instance_id); + } +#endif +#if defined(CONFIG_TARGET_E2000) + /*RTC*/ + data_w[0] = BIN_TO_BCD(20) ;/*second*/ + data_w[1] = BIN_TO_BCD(20) ;/*minute*/ + data_w[2] = BIN_TO_BCD(20) ;/*hour*/ + data_w[3] = BIN_TO_BCD(2 + 1) ; /*weekday2 + 1*/ + data_w[4] = BIN_TO_BCD(15) ;/*day_of_month*/ + + data_w[5] = (BIN_TO_BCD(11) | 0x80); /* 2000 -> (* | 0x80) , 1900 -> (* | 0x0) */ + data_w[6] = BIN_TO_BCD(2022 % 100) ; + /*8位地址*/ + message.mem_byte_len = 1; + message.buf = data_w; + message.buf_length = 7; + message.mem_addr = 0x0;/* 地址偏移0x0的位置poll方式写入数据 */ + message.mode = FI2C_WRITE_DATA_POLL; + ret = FFreeRTOSI2cTransfer(os_i2c_write_p, &message); + if (ret != FREERTOS_I2C_SUCCESS) + { + vPrintf("FFreeRTOSI2cTransfer write poll task error,i2c id:%d.\r\n", os_i2c_write_p->i2c_device.config.instance_id); + } +#endif + printf("I2cWriteTask is over.\r\n "); + vTaskDelete(NULL); +} + +static FError FFreeRTOSI2cInitSet(uint32_t id, uint32_t work_mode, uint32_t slave_address) +{ + FError err; + /* init i2c controller */ + if (work_mode == FI2C_MASTER) /* 主机初始化默认使用poll模式 */ + { + os_i2c_master = FFreeRTOSI2cInit(id, work_mode, slave_address, FI2C_SPEED_STANDARD_RATE); + /* register intr callback */ + InterruptInstall(os_i2c_master->i2c_device.config.irq_num, FI2cMasterIntrHandler, &os_i2c_master->i2c_device, "fi2cmaster"); + /* register intr handler func */ + FI2cMasterRegisterIntrHandler(&os_i2c_master->i2c_device, FI2C_EVT_MASTER_TRANS_ABORTED, FI2cIntrTxAbrtcallback); + FI2cMasterRegisterIntrHandler(&os_i2c_master->i2c_device, FI2C_EVT_MASTER_READ_DONE, FI2cIntrRxDonecallback); + FI2cMasterRegisterIntrHandler(&os_i2c_master->i2c_device, FI2C_EVT_MASTER_WRITE_DONE, FI2cIntrTxDonecallback); + } + else if (work_mode == FI2C_SLAVE) + { + os_i2c_slave = FFreeRTOSI2cInit(id, work_mode, slave_address, FI2C_SPEED_STANDARD_RATE); + /* register intr callback */ + InterruptInstall(os_i2c_slave->i2c_device.config.irq_num, FI2cSlaveIntrHandler, &os_i2c_slave->i2c_device, "fi2cslave"); + /* slave mode intr set,must set before master data come in. */ + err = FI2cSlaveSetupIntr(&os_i2c_slave->i2c_device); + if (err != FREERTOS_I2C_SUCCESS) + { + vPrintf("I2c slave intr init failed.\r\n"); + return FREERTOS_I2C_INVAL_STATE_ERROR; + } + FI2cSlaveData *slave_p = &slave; + memset(slave_p, 0, sizeof(*slave_p)); + slave_p->first_write = TRUE; + FI2cSlaveRegisterIntrHandler(&os_i2c_slave->i2c_device, FI2C_EVT_SLAVE_WRITE_RECEIVED, FI2cOsSlaveWriteReceived); + FI2cSlaveRegisterIntrHandler(&os_i2c_slave->i2c_device, FI2C_EVT_SLAVE_READ_PROCESSED, FI2cOsSlaveReadProcessed); + FI2cSlaveRegisterIntrHandler(&os_i2c_slave->i2c_device, FI2C_EVT_SLAVE_READ_REQUESTED, FI2cOsSlaveReadRequest); + FI2cSlaveRegisterIntrHandler(&os_i2c_slave->i2c_device, FI2C_EVT_SLAVE_STOP, FI2cOsSlaveStop); + FI2cSlaveRegisterIntrHandler(&os_i2c_slave->i2c_device, FI2C_EVT_SLAVE_WRITE_REQUESTED, FI2cOsSlaveWriteRequest); + } + return FREERTOS_I2C_SUCCESS; +} + +static void I2cInitTask(void *pvParameters) +{ + FError err; + BaseType_t xReturn = pdPASS; + + taskENTER_CRITICAL(); //进入临界区 +#if defined(CONFIG_TARGET_E2000) + err = FFreeRTOSI2cInitSet(FMIO9_ID, FI2C_MASTER, RTC_ADDR); + if (err != FREERTOS_I2C_SUCCESS) + { + vPrintf("I2c FFreeRTOSI2cInitSet failed.\r\n"); + return; + } + + xReturn = xTaskCreate((TaskFunction_t)I2cReadTask, /* 任务入口函数 */ + (const char *)"I2cReadTask",/* 任务名字 */ + (uint16_t)1024, /* 任务栈大小 */ + (void *)os_i2c_master,/* 任务入口函数参数 */ + (UBaseType_t)configMAX_PRIORITIES - 2, /* 任务的优先级 */ + (TaskHandle_t *)&read_handle); /* 任务控制 */ + FASSERT_MSG(xReturn == pdPASS, "I2cReadTask creation is failed."); + + xReturn = xTaskCreate((TaskFunction_t)I2cWriteTask, /* 任务入口函数 */ + (const char *)"I2cWriteTask",/* 任务名字 */ + (uint16_t)1024, /* 任务栈大小 */ + (void *)os_i2c_master,/* 任务入口函数参数 */ + (UBaseType_t)configMAX_PRIORITIES - 1, /* 任务的优先级 */ + (TaskHandle_t *)&write_handle); /* 任务控制 */ + FASSERT_MSG(xReturn == pdPASS, "I2cWriteTask creation is failed."); +#endif +#if defined(CONFIG_TARGET_D2000) + err = FFreeRTOSI2cInitSet(FI2C0_ID, FI2C_MASTER, MASTER_SLAVE_ADDR); + if (err != FREERTOS_I2C_SUCCESS) + { + vPrintf("I2c FFreeRTOSI2cInitSet failed.\r\n"); + return; + } + + err = FFreeRTOSI2cInitSet(FI2C2_ID, FI2C_SLAVE, MASTER_SLAVE_ADDR); + if (err != FREERTOS_I2C_SUCCESS) + { + vPrintf("I2c FFreeRTOSI2cInitSet failed.\r\n"); + return; + } + + xReturn = xTaskCreate((TaskFunction_t)I2cReadTask, /* 任务入口函数 */ + (const char *)"I2cReadTask",/* 任务名字 */ + (uint16_t)1024, /* 任务栈大小 */ + (void *)os_i2c_master,/* 任务入口函数参数 */ + (UBaseType_t)configMAX_PRIORITIES - 3, /* 任务的优先级 */ + (TaskHandle_t *)&read_handle); /* 任务控制 */ + FASSERT_MSG(xReturn == pdPASS, "I2cReadTask creation is failed."); + + xReturn = xTaskCreate((TaskFunction_t)I2cWriteTask, /* 任务入口函数 */ + (const char *)"I2cWriteTask",/* 任务名字 */ + (uint16_t)1024, /* 任务栈大小 */ + (void *)os_i2c_master,/* 任务入口函数参数 */ + (UBaseType_t)configMAX_PRIORITIES - 1, /* 任务的优先级 */ + (TaskHandle_t *)&write_handle); /* 任务控制 */ + FASSERT_MSG(xReturn == pdPASS, "I2cWriteTask creation is failed."); + + xReturn = xTaskCreate((TaskFunction_t)I2cSlaveTask, /* 任务入口函数 */ + (const char *)"I2cSlaveTask",/* 任务名字 */ + (uint16_t)1024, /* 任务栈大小 */ + (void *)os_i2c_slave,/* 任务入口函数参数 */ + (UBaseType_t)configMAX_PRIORITIES - 2, /* 任务的优先级 */ + (TaskHandle_t *)&slave_handle); /* 任务控制 */ + FASSERT_MSG(xReturn == pdPASS, "I2cSlaveTask creation is failed."); +#endif +#if defined(CONFIG_TARGET_F2000_4) + err = FFreeRTOSI2cInitSet(FI2C0_ID, FI2C_MASTER, EEPROM_ADDR); + if (err != FREERTOS_I2C_SUCCESS) + { + vPrintf("I2c FFreeRTOSI2cInitSet failed.\r\n"); + return; + } + xReturn = xTaskCreate((TaskFunction_t)I2cReadTask, /* 任务入口函数 */ + (const char *)"I2cReadTask",/* 任务名字 */ + (uint16_t)1024, /* 任务栈大小 */ + (void *)os_i2c_master,/* 任务入口函数参数 */ + (UBaseType_t)configMAX_PRIORITIES - 2, /* 任务的优先级 */ + (TaskHandle_t *)&read_handle); /* 任务控制 */ + FASSERT_MSG(xReturn == pdPASS, "I2cReadTask creation is failed."); + + xReturn = xTaskCreate((TaskFunction_t)I2cWriteTask, /* 任务入口函数 */ + (const char *)"I2cWriteTask",/* 任务名字 */ + (uint16_t)1024, /* 任务栈大小 */ + (void *)os_i2c_master,/* 任务入口函数参数 */ + (UBaseType_t)configMAX_PRIORITIES - 1, /* 任务的优先级 */ + (TaskHandle_t *)&write_handle); /* 任务控制 */ + FASSERT_MSG(xReturn == pdPASS, "I2cWriteTask creation is failed."); +#endif + taskEXIT_CRITICAL(); //退出临界区 + vTaskDelete(NULL); +} + +BaseType_t FFreeRTOSI2cCreate(void) +{ + BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为 pdPASS */ + BaseType_t xTimerStarted = pdPASS; + + taskENTER_CRITICAL(); //进入临界区 + + xReturn = xTaskCreate((TaskFunction_t)I2cInitTask, /* 任务入口函数 */ + (const char *)"I2cInitTask",/* 任务名字 */ + (uint16_t)1024, /* 任务栈大小 */ + (void *)NULL,/* 任务入口函数参数 */ + (UBaseType_t)configMAX_PRIORITIES, /* 任务的优先级 */ + (TaskHandle_t *)&init_handle); /* 任务控制 */ + FASSERT_MSG(xReturn == pdPASS, "I2cInitTask creation is failed."); + + taskEXIT_CRITICAL(); //退出临界区 + printf("I2c task is created successfully.\r\n"); + return xReturn; +} + diff --git a/example/peripheral/pwm/configs/e2000d_aarch32_eg_configs b/example/peripheral/pwm/configs/e2000d_aarch32_eg_configs index 9bd36081..b3558322 100644 --- a/example/peripheral/pwm/configs/e2000d_aarch32_eg_configs +++ b/example/peripheral/pwm/configs/e2000d_aarch32_eg_configs @@ -74,6 +74,7 @@ CONFIG_USE_FPWM=y # end of FPWM Configuration # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -118,6 +119,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -154,6 +164,7 @@ CONFIG_FREERTOS_USE_PWM=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -175,12 +186,6 @@ CONFIG_FREERTOS_USE_PWM=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -192,14 +197,32 @@ CONFIG_FREERTOS_USE_PWM=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -217,4 +240,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/pwm/configs/e2000d_aarch64_eg_configs b/example/peripheral/pwm/configs/e2000d_aarch64_eg_configs index e81dc2b5..9641b08c 100644 --- a/example/peripheral/pwm/configs/e2000d_aarch64_eg_configs +++ b/example/peripheral/pwm/configs/e2000d_aarch64_eg_configs @@ -74,6 +74,7 @@ CONFIG_USE_FPWM=y # end of FPWM Configuration # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -114,6 +115,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -150,6 +160,7 @@ CONFIG_FREERTOS_USE_PWM=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -171,12 +182,6 @@ CONFIG_FREERTOS_USE_PWM=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -188,14 +193,32 @@ CONFIG_FREERTOS_USE_PWM=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -213,4 +236,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/pwm/configs/e2000q_aarch32_eg_configs b/example/peripheral/pwm/configs/e2000q_aarch32_eg_configs index 9f79adf5..08a1967f 100644 --- a/example/peripheral/pwm/configs/e2000q_aarch32_eg_configs +++ b/example/peripheral/pwm/configs/e2000q_aarch32_eg_configs @@ -74,6 +74,7 @@ CONFIG_USE_FPWM=y # end of FPWM Configuration # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -118,6 +119,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -154,6 +164,7 @@ CONFIG_FREERTOS_USE_PWM=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -175,12 +186,6 @@ CONFIG_FREERTOS_USE_PWM=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -192,14 +197,32 @@ CONFIG_FREERTOS_USE_PWM=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -217,4 +240,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/pwm/configs/e2000q_aarch64_eg_configs b/example/peripheral/pwm/configs/e2000q_aarch64_eg_configs index ef77db98..fc1797de 100644 --- a/example/peripheral/pwm/configs/e2000q_aarch64_eg_configs +++ b/example/peripheral/pwm/configs/e2000q_aarch64_eg_configs @@ -74,6 +74,7 @@ CONFIG_USE_FPWM=y # end of FPWM Configuration # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -114,6 +115,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -150,6 +160,7 @@ CONFIG_FREERTOS_USE_PWM=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -171,12 +182,6 @@ CONFIG_FREERTOS_USE_PWM=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -188,14 +193,32 @@ CONFIG_FREERTOS_USE_PWM=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -213,4 +236,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/pwm/inc/pwm_example.h b/example/peripheral/pwm/inc/pwm_example.h index 60118a2c..c09de8b0 100644 --- a/example/peripheral/pwm/inc/pwm_example.h +++ b/example/peripheral/pwm/inc/pwm_example.h @@ -1,30 +1,41 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: pwm_example.h * Date: 2022-08-16 14:55:40 * LastEditTime: 2022-08-19 11:42:40 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for pwm test example function declarations. + * + * Modify History: + * Ver   Who         Date          Changes + * ----- ------      --------     -------------------------------------- + * 1.0 wangxiaodong 2022/8/24 first release */ #ifndef PWM_EXAMPLE_H #define PWM_EXAMPLE_H +#ifdef __cplusplus +extern "C" +{ +#endif + /* pwm test */ BaseType_t FFreeRTOSPwmCreate(u32 id); + +#ifdef __cplusplus +} +#endif + #endif // ! \ No newline at end of file diff --git a/example/peripheral/pwm/main.c b/example/peripheral/pwm/main.c index bed6f16f..85c4049c 100644 --- a/example/peripheral/pwm/main.c +++ b/example/peripheral/pwm/main.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: main.c * Date: 2022-06-17 08:17:59 * LastEditTime: 2022-06-17 08:17:59 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for pwm main entry. + * + * Modify History: + * Ver   Who         Date          Changes + * ----- ------      --------     -------------------------------------- + * 1.0 wangxiaodong 2022/8/24 first release */ #include "shell.h" @@ -31,17 +32,21 @@ int main(void) BaseType_t ret; /* test pwm module 7 */ ret = FFreeRTOSPwmCreate(7); - if(ret != pdPASS) + if (ret != pdPASS) + { goto FAIL_EXIT; + } ret = LSUserShellTask() ; - if(ret != pdPASS) + if (ret != pdPASS) + { goto FAIL_EXIT; + } - vTaskStartScheduler(); /* 启动任务,开启调度 */ + vTaskStartScheduler(); /* 启动任务,开启调度 */ while (1); /* 正常不会执行到这里 */ - + FAIL_EXIT: - printf("failed 0x%x \r\n", ret); + printf("Failed,the ret value is 0x%x. \r\n", ret); return 0; } diff --git a/example/peripheral/pwm/sdkconfig b/example/peripheral/pwm/sdkconfig index ef77db98..fc1797de 100644 --- a/example/peripheral/pwm/sdkconfig +++ b/example/peripheral/pwm/sdkconfig @@ -74,6 +74,7 @@ CONFIG_USE_FPWM=y # end of FPWM Configuration # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -114,6 +115,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -150,6 +160,7 @@ CONFIG_FREERTOS_USE_PWM=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -171,12 +182,6 @@ CONFIG_FREERTOS_USE_PWM=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -188,14 +193,32 @@ CONFIG_FREERTOS_USE_PWM=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -213,4 +236,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/pwm/sdkconfig.h b/example/peripheral/pwm/sdkconfig.h index 8aeb473b..c1455ed2 100644 --- a/example/peripheral/pwm/sdkconfig.h +++ b/example/peripheral/pwm/sdkconfig.h @@ -67,6 +67,7 @@ #define CONFIG_USE_FPWM /* end of FPWM Configuration */ /* CONFIG_USE_IPC is not set */ +/* CONFIG_USE_MEDIA is not set */ /* end of Components Configuration */ #define CONFIG_USE_NEW_LIBC /* end of Standalone Setting */ @@ -103,6 +104,12 @@ /* Compiler Options */ +/* Cross-Compiler Setting */ + +#define CONFIG_GCC_OPTIMIZE_LEVEL 0 +/* CONFIG_USE_EXT_COMPILER is not set */ +/* CONFIG_USE_KLIN_SYS is not set */ +/* end of Cross-Compiler Setting */ #define CONFIG_OUTPUT_BINARY /* end of Compiler Options */ /* end of Building Option */ @@ -132,6 +139,7 @@ /* Freertos Eth Drivers */ /* CONFIG_FREERTOS_USE_XMAC is not set */ +/* CONFIG_FREERTOS_USE_GMAC is not set */ /* end of Freertos Eth Drivers */ /* Freertos Gpio Drivers */ @@ -150,11 +158,6 @@ /* CONFIG_FREERTOS_USE_FGDMA is not set */ /* end of Freertos DMA Drivers */ -/* Freertos MMC Drivers */ - -/* CONFIG_FREERTOS_USE_FSDIO is not set */ -/* end of Freertos MMC Drivers */ - /* Freertos Adc Drivers */ /* CONFIG_FREERTOS_USE_ADC is not set */ @@ -164,13 +167,28 @@ /* CONFIG_FREERTOS_USE_CAN is not set */ /* end of Freertos Can Drivers */ + +/* Freertos I2c Drivers */ + +/* CONFIG_FREERTOS_USE_I2C is not set */ +/* end of Freertos I2c Drivers */ + +/* Freertos Mio Drivers */ + +/* CONFIG_FREERTOS_USE_MIO is not set */ +/* end of Freertos Mio Drivers */ + +/* Freertos Timer Drivers */ + +/* CONFIG_FREERTOS_USE_TIMER is not set */ +/* end of Freertos Timer Drivers */ /* end of Component Configuration */ -/* FreeRTOS Setting */ +/* Third-Party Configuration */ /* CONFIG_USE_LWIP is not set */ #define CONFIG_USE_BACKTRACE -/* CONFIG_USE_FATFS is not set */ +/* CONFIG_USE_FATFS_0_1_4 is not set */ /* CONFIG_USE_SFUD is not set */ /* CONFIG_USE_SPIFFS is not set */ /* CONFIG_USE_AMP is not set */ @@ -186,6 +204,28 @@ #define CONFIG_USE_TLSF /* CONFIG_USE_SDMMC_CMD is not set */ /* CONFIG_USE_CHERRY_USB is not set */ -/* end of FreeRTOS Setting */ +/* end of Third-Party Configuration */ + +/* Kernel Configuration */ + +#define CONFIG_FREERTOS_OPTIMIZED_SCHEDULER +#define CONFIG_FREERTOS_HZ 1000 +#define CONFIG_FREERTOS_MAX_PRIORITIES 32 +#define CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES 13 +#define CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES 11 +#define CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS 1 +#define CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE 1024 +#define CONFIG_FREERTOS_MAX_TASK_NAME_LEN 32 +#define CONFIG_FREERTOS_TIMER_TASK_PRIORITY 1 +#define CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH 2048 +#define CONFIG_FREERTOS_TIMER_QUEUE_LENGTH 10 +#define CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE 0 +#define CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS +#define CONFIG_FREERTOS_USE_TRACE_FACILITY +#define CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS +/* CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set */ +#define CONFIG_FREERTOS_TOTAL_HEAP_SIZE 10240 +#define CONFIG_FREERTOS_TASK_FPU_SUPPORT 1 +/* end of Kernel Configuration */ #endif diff --git a/example/peripheral/pwm/src/pwm_example.c b/example/peripheral/pwm/src/pwm_example.c index 49884745..c79bff90 100644 --- a/example/peripheral/pwm/src/pwm_example.c +++ b/example/peripheral/pwm/src/pwm_example.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: pwm_example.c * Date: 2022-07-11 11:32:48 * LastEditTime: 2022-07-11 11:32:48 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for pwm test example functions. + * + * Modify History: + * Ver   Who         Date          Changes + * ----- ------      --------     -------------------------------------- + * 1.0 wangxiaodong 2022/8/24 first release */ #include #include "FreeRTOSConfig.h" @@ -32,20 +33,20 @@ #include "pwm_example.h" /* The periods assigned to the one-shot timers. */ -#define ONE_SHOT_TIMER_PERIOD ( pdMS_TO_TICKS( 300000UL ) ) +#define ONE_SHOT_TIMER_PERIOD ( pdMS_TO_TICKS( 300000UL ) ) /* pwm pulse change period */ -#define PWM_CHANGE_PERIOD ( pdMS_TO_TICKS( 2000UL )) +#define PWM_CHANGE_PERIOD ( pdMS_TO_TICKS( 2000UL )) /* pwm pulse amplitude of periodic variation */ -#define PWM_PULSE_CHANGE 1000 +#define PWM_PULSE_CHANGE 1000 /* pwm channel use, 0/1 */ -#define PWM_CHANNEL_USE FPWM_CHANNEL_0 +#define PWM_CHANNEL_USE FPWM_CHANNEL_0 /* pwm primary config */ -#define PWM_DIV 500 -#define PWM_PERIOD 10000 -#define PWM_PULSE 2000 +#define PWM_DIV 500 +#define PWM_PERIOD 10000 +#define PWM_PULSE 2000 /* test task number */ #define TEST_TASK_NUM 1 @@ -60,44 +61,44 @@ static void FFreeRTOSPwmDelete(FFreeRTOSPwm *os_pwm_p); static void FFreeRTOSPwmInitTask(void *pvParameters) { - /* The pwm_id to use is passed in via the parameter. - Cast this to a pwm_id pointer. */ - u32 pwm_id = (u32)(uintptr)pvParameters; + /* The pwm_id to use is passed in via the parameter. + Cast this to a pwm_id pointer. */ + u32 pwm_id = (u32)(uintptr)pvParameters; - FError ret = FPWM_SUCCESS; + FError ret = FPWM_SUCCESS; - /* set channel 0 and 1 iopad*/ + /* set channel 0 and 1 iopad*/ #if defined(CONFIG_TARGET_E2000) - FIOPadSetPwmMux(pwm_id, 0); + FIOPadSetPwmMux(pwm_id, 0); FIOPadSetPwmMux(pwm_id, 1); #endif - /* init pwm controller */ - os_pwm_ctrl_p = FFreeRTOSPwmInit(pwm_id); - if(os_pwm_ctrl_p == NULL) - { - printf("FFreeRTOSPwmInit failed!!!\n"); - goto pwm_init_exit; - } - - /* set pwm db config */ - FPwmDbVariableConfig db_cfg; - memset(&db_cfg, 0, sizeof(db_cfg)); - db_cfg.db_rise_cycle = 500; - db_cfg.db_fall_cycle = 500; - db_cfg.db_polarity_sel = FPWM_DB_AHC; - db_cfg.db_in_mode = FPWM_DB_IN_MODE_PWM0; - db_cfg.db_out_mode = FPWM_DB_OUT_MODE_ENABLE_RISE_FALL; - ret = FFreeRTOSPwmDbSet(os_pwm_ctrl_p, &db_cfg); - if (FPWM_SUCCESS != ret) - { - printf("FFreeRTOSPwmDbSet failed\n"); - goto pwm_init_exit; - } - /* start pwm config */ - FPwmVariableConfig pwm_cfg; - memset(&pwm_cfg, 0, sizeof(pwm_cfg)); - pwm_cfg.tim_ctrl_mode = FPWM_MODULO; + /* init pwm controller */ + os_pwm_ctrl_p = FFreeRTOSPwmInit(pwm_id); + if (os_pwm_ctrl_p == NULL) + { + printf("FFreeRTOSPwmInit failed.\n"); + goto pwm_init_exit; + } + + /* set pwm db config */ + FPwmDbVariableConfig db_cfg; + memset(&db_cfg, 0, sizeof(db_cfg)); + db_cfg.db_rise_cycle = 500; + db_cfg.db_fall_cycle = 500; + db_cfg.db_polarity_sel = FPWM_DB_AHC; + db_cfg.db_in_mode = FPWM_DB_IN_MODE_PWM0; + db_cfg.db_out_mode = FPWM_DB_OUT_MODE_ENABLE_RISE_FALL; + ret = FFreeRTOSPwmDbSet(os_pwm_ctrl_p, &db_cfg); + if (FPWM_SUCCESS != ret) + { + printf("FFreeRTOSPwmDbSet failed.\n"); + goto pwm_init_exit; + } + /* start pwm config */ + FPwmVariableConfig pwm_cfg; + memset(&pwm_cfg, 0, sizeof(pwm_cfg)); + pwm_cfg.tim_ctrl_mode = FPWM_MODULO; pwm_cfg.tim_ctrl_div = PWM_DIV - 1; pwm_cfg.pwm_period = PWM_PERIOD; pwm_cfg.pwm_pulse = PWM_PULSE; @@ -105,13 +106,13 @@ static void FFreeRTOSPwmInitTask(void *pvParameters) pwm_cfg.pwm_polarity = FPWM_POLARITY_NORMAL; pwm_cfg.pwm_duty_source_mode = FPWM_DUTY_CCR; ret = FFreeRTOSPwmSet(os_pwm_ctrl_p, PWM_CHANNEL_USE, &pwm_cfg); - if (FPWM_SUCCESS != ret) - { - printf("FFreeRTOSPwmSet failed\n"); - goto pwm_init_exit; - } + if (FPWM_SUCCESS != ret) + { + printf("FFreeRTOSPwmSet failed.\n"); + goto pwm_init_exit; + } - memset(&db_cfg, 0, sizeof(db_cfg)); + memset(&db_cfg, 0, sizeof(db_cfg)); memset(&pwm_cfg, 0, sizeof(pwm_cfg)); FFreeRTOSPwmDbGet(os_pwm_ctrl_p, &db_cfg); @@ -132,135 +133,135 @@ static void FFreeRTOSPwmInitTask(void *pvParameters) printf("pwm_cfg.pwm_polarity = %d\n", pwm_cfg.pwm_polarity); printf("pwm_cfg.pwm_duty_source_mode = %d\n", pwm_cfg.pwm_duty_source_mode); - FFreeRTOSPwmEnable(os_pwm_ctrl_p, PWM_CHANNEL_USE, TRUE); + FFreeRTOSPwmEnable(os_pwm_ctrl_p, PWM_CHANNEL_USE, TRUE); - printf("FFreeRTOSPwmInitTask execute success !!!\r\n"); + printf("FFreeRTOSPwmInitTask execute successfully.\r\n"); for (int i = 0; i < TEST_TASK_NUM; i++) { xSemaphoreGive(xCountingSemaphore); } -pwm_init_exit: +pwm_init_exit: vTaskDelete(NULL); - + } static void FFreeRTOSPwmChangeTask(void *pvParameters) { - xSemaphoreTake(xCountingSemaphore, portMAX_DELAY); - u32 pwm_pulse = PWM_PULSE; - /* As per most tasks, this task is implemented in an infinite loop. */ - for (;;) - { - FFreeRTOSPwmPulseSet(os_pwm_ctrl_p, PWM_CHANNEL_USE, pwm_pulse); - - printf("FFreeRTOSPwmChangeTask run, pwm_pulse: %d\r\n", pwm_pulse); - pwm_pulse = (pwm_pulse + PWM_PULSE_CHANGE) % PWM_PERIOD; - vTaskDelay(PWM_CHANGE_PERIOD); - } + xSemaphoreTake(xCountingSemaphore, portMAX_DELAY); + u32 pwm_pulse = PWM_PULSE; + /* As per most tasks, this task is implemented in an infinite loop. */ + for (;;) + { + FFreeRTOSPwmPulseSet(os_pwm_ctrl_p, PWM_CHANNEL_USE, pwm_pulse); + + printf("FFreeRTOSPwmChangeTask run, pwm_pulse: %d\r\n", pwm_pulse); + pwm_pulse = (pwm_pulse + PWM_PULSE_CHANGE) % PWM_PERIOD; + vTaskDelay(PWM_CHANGE_PERIOD); + } } -static void prvOneShotTimerCallback( TimerHandle_t xTimer ) +static void prvOneShotTimerCallback(TimerHandle_t xTimer) { - /* Output a string to show the time at which the callback was executed. */ - printf("One-shot timer callback executing, will delete FFreeRTOSPwmChangeTask.\r\n" ); + /* Output a string to show the time at which the callback was executed. */ + printf("One-shot timer callback executing, which will delete FFreeRTOSPwmChangeTask.\r\n"); - FFreeRTOSPwmDelete(os_pwm_ctrl_p); + FFreeRTOSPwmDelete(os_pwm_ctrl_p); } /* create pwm test, id is pwm module number */ BaseType_t FFreeRTOSPwmCreate(u32 id) { - FASSERT(id < FPWM_INSTANCE_NUM); + FASSERT(id < FPWM_NUM); BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为 pdPASS */ - BaseType_t xTimerStarted = pdPASS; - - xCountingSemaphore = xSemaphoreCreateCounting(TEST_TASK_NUM, 0); - if (xCountingSemaphore == NULL) - { - printf("FFreeRTOSPwmCreate xCountingSemaphore create failed.\r\n" ); - return pdFAIL; - } - - taskENTER_CRITICAL(); //进入临界区 - /* pwm init task */ - xReturn = xTaskCreate((TaskFunction_t )FFreeRTOSPwmInitTask, /* 任务入口函数 */ - (const char* )"FFreeRTOSPwmInitTask",/* 任务名字 */ - (uint16_t )1024, /* 任务栈大小 */ - (void* )(uintptr)id,/* 任务入口函数参数 */ - (UBaseType_t )configMAX_PRIORITIES-1, /* 任务的优先级 */ - NULL); /* 任务控制 */ - - /* pwm占空比变化任务 */ - xReturn = xTaskCreate((TaskFunction_t )FFreeRTOSPwmChangeTask, /* 任务入口函数 */ - (const char* )"FFreeRTOSPwmChangeTask",/* 任务名字 */ - (uint16_t )1024, /* 任务栈大小 */ - NULL,/* 任务入口函数参数 */ - (UBaseType_t )configMAX_PRIORITIES-1, /* 任务的优先级 */ - (TaskHandle_t* )&change_handle); /* 任务控制 */ - - /* Create the one shot software timer, storing the handle to the created - software timer in xOneShotTimer. */ - xOneShotTimer = xTimerCreate( "OneShot Software Timer", /* Text name for the software timer - not used by FreeRTOS. */ - ONE_SHOT_TIMER_PERIOD, /* The software timer's period in ticks. */ - pdFALSE, /* Setting uxAutoRealod to pdFALSE creates a one-shot software timer. */ - 0, /* This example use the timer id. */ - prvOneShotTimerCallback ); /* The callback function to be used by the software timer being created. */ - - /* Check the timers were created. */ - if( xOneShotTimer != NULL ) - { - /* Start the software timers, using a block time of 0 (no block time). - The scheduler has not been started yet so any block time specified here - would be ignored anyway. */ - xTimerStarted = xTimerStart( xOneShotTimer, 0 ); - - /* The implementation of xTimerStart() uses the timer command queue, and - xTimerStart() will fail if the timer command queue gets full. The timer - service task does not get created until the scheduler is started, so all - commands sent to the command queue will stay in the queue until after - the scheduler has been started. Check both calls to xTimerStart() - passed. */ - if(xTimerStarted != pdPASS) - { - vPrintf("CreateSoftwareTimerTasks xTimerStart failed \r\n"); - } - } - else - { - vPrintf("CreateSoftwareTimerTasks xTimerCreate failed \r\n"); - } - - taskEXIT_CRITICAL(); //退出临界区 - + BaseType_t xTimerStarted = pdPASS; + + xCountingSemaphore = xSemaphoreCreateCounting(TEST_TASK_NUM, 0); + if (xCountingSemaphore == NULL) + { + printf("FFreeRTOSPwmCreate xCountingSemaphore create failed.\r\n"); + return pdFAIL; + } + + taskENTER_CRITICAL(); //进入临界区 + /* pwm init task */ + xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSPwmInitTask, /* 任务入口函数 */ + (const char *)"FFreeRTOSPwmInitTask",/* 任务名字 */ + (uint16_t)1024, /* 任务栈大小 */ + (void *)(uintptr)id,/* 任务入口函数参数 */ + (UBaseType_t)configMAX_PRIORITIES - 1, /* 任务的优先级 */ + NULL); /* 任务控制 */ + + /* pwm占空比变化任务 */ + xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSPwmChangeTask, /* 任务入口函数 */ + (const char *)"FFreeRTOSPwmChangeTask",/* 任务名字 */ + (uint16_t)1024, /* 任务栈大小 */ + NULL,/* 任务入口函数参数 */ + (UBaseType_t)configMAX_PRIORITIES - 1, /* 任务的优先级 */ + (TaskHandle_t *)&change_handle); /* 任务控制 */ + + /* Create the one shot software timer, storing the handle to the created + software timer in xOneShotTimer. */ + xOneShotTimer = xTimerCreate("OneShot Software Timer", /* Text name for the software timer - not used by FreeRTOS. */ + ONE_SHOT_TIMER_PERIOD, /* The software timer's period in ticks. */ + pdFALSE, /* Setting uxAutoRealod to pdFALSE creates a one-shot software timer. */ + 0, /* This example use the timer id. */ + prvOneShotTimerCallback); /* The callback function to be used by the software timer being created. */ + + /* Check the timers were created. */ + if (xOneShotTimer != NULL) + { + /* Start the software timers, using a block time of 0 (no block time). + The scheduler has not been started yet so any block time specified here + would be ignored anyway. */ + xTimerStarted = xTimerStart(xOneShotTimer, 0); + + /* The implementation of xTimerStart() uses the timer command queue, and + xTimerStart() will fail if the timer command queue gets full. The timer + service task does not get created until the scheduler is started, so all + commands sent to the command queue will stay in the queue until after + the scheduler has been started. Check both calls to xTimerStart() + passed. */ + if (xTimerStarted != pdPASS) + { + vPrintf("CreateSoftwareTimerTasks xTimerStart failed.\r\n"); + } + } + else + { + vPrintf("CreateSoftwareTimerTasks xTimerCreate failed.\r\n"); + } + + taskEXIT_CRITICAL(); //退出临界区 + return xReturn; } static void FFreeRTOSPwmDelete(FFreeRTOSPwm *os_pwm_p) { - BaseType_t xReturn = pdPASS; - FFreeRTOSPwmEnable(os_pwm_p, PWM_CHANNEL_USE, FALSE); - FFreeRTOSPwmDeinit(os_pwm_p); - - if(change_handle) + BaseType_t xReturn = pdPASS; + FFreeRTOSPwmEnable(os_pwm_p, PWM_CHANNEL_USE, FALSE); + FFreeRTOSPwmDeinit(os_pwm_p); + + if (change_handle) { vTaskDelete(change_handle); - vPrintf("Delete FFreeRTOSPwmChangeTask success\r\n"); + vPrintf("Delete FFreeRTOSPwmChangeTask successfully.\r\n"); } - /* delete count sem */ - vSemaphoreDelete(xCountingSemaphore); - - /* delete timer */ - xReturn = xTimerDelete(xOneShotTimer, 0); - if(xReturn != pdPASS) - { - vPrintf("Delete OneShot Software Timer failed.\r\n"); - } - else - { - vPrintf("Delete OneShot Software Timer success.\r\n"); - } + /* delete count sem */ + vSemaphoreDelete(xCountingSemaphore); + + /* delete timer */ + xReturn = xTimerDelete(xOneShotTimer, 0); + if (xReturn != pdPASS) + { + vPrintf("Delete OneShot Software Timer failed.\r\n"); + } + else + { + vPrintf("Delete OneShot Software Timer successfully.\r\n"); + } } \ No newline at end of file diff --git a/example/peripheral/qspi/configs/d2000_aarch32_eg_configs b/example/peripheral/qspi/configs/d2000_aarch32_eg_configs index 0ac4198f..c7654be8 100644 --- a/example/peripheral/qspi/configs/d2000_aarch32_eg_configs +++ b/example/peripheral/qspi/configs/d2000_aarch32_eg_configs @@ -74,6 +74,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -118,6 +119,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -154,6 +164,7 @@ CONFIG_FREERTOS_USE_QSPI=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -175,12 +186,6 @@ CONFIG_FREERTOS_USE_QSPI=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -192,14 +197,32 @@ CONFIG_FREERTOS_USE_QSPI=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -217,4 +240,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/qspi/configs/d2000_aarch64_eg_configs b/example/peripheral/qspi/configs/d2000_aarch64_eg_configs index 6faa0f1e..4c96604d 100644 --- a/example/peripheral/qspi/configs/d2000_aarch64_eg_configs +++ b/example/peripheral/qspi/configs/d2000_aarch64_eg_configs @@ -74,6 +74,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -114,6 +115,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -150,6 +160,7 @@ CONFIG_FREERTOS_USE_QSPI=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -171,12 +182,6 @@ CONFIG_FREERTOS_USE_QSPI=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -188,14 +193,32 @@ CONFIG_FREERTOS_USE_QSPI=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -213,4 +236,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/qspi/configs/e2000d_aarch32_eg_configs b/example/peripheral/qspi/configs/e2000d_aarch32_eg_configs index e7bdc8d6..c7c59264 100644 --- a/example/peripheral/qspi/configs/e2000d_aarch32_eg_configs +++ b/example/peripheral/qspi/configs/e2000d_aarch32_eg_configs @@ -74,6 +74,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -118,6 +119,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -154,6 +164,7 @@ CONFIG_FREERTOS_USE_QSPI=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -175,12 +186,6 @@ CONFIG_FREERTOS_USE_QSPI=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -192,14 +197,32 @@ CONFIG_FREERTOS_USE_QSPI=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -217,4 +240,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/qspi/configs/e2000d_aarch64_eg_configs b/example/peripheral/qspi/configs/e2000d_aarch64_eg_configs index ccbd39b3..748ff821 100644 --- a/example/peripheral/qspi/configs/e2000d_aarch64_eg_configs +++ b/example/peripheral/qspi/configs/e2000d_aarch64_eg_configs @@ -74,6 +74,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -114,6 +115,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -150,6 +160,7 @@ CONFIG_FREERTOS_USE_QSPI=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -171,12 +182,6 @@ CONFIG_FREERTOS_USE_QSPI=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -188,14 +193,32 @@ CONFIG_FREERTOS_USE_QSPI=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -213,4 +236,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/qspi/configs/e2000q_aarch32_eg_configs b/example/peripheral/qspi/configs/e2000q_aarch32_eg_configs index 3e11d715..9b66254f 100644 --- a/example/peripheral/qspi/configs/e2000q_aarch32_eg_configs +++ b/example/peripheral/qspi/configs/e2000q_aarch32_eg_configs @@ -74,6 +74,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -118,6 +119,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -154,6 +164,7 @@ CONFIG_FREERTOS_USE_QSPI=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -175,12 +186,6 @@ CONFIG_FREERTOS_USE_QSPI=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -192,14 +197,32 @@ CONFIG_FREERTOS_USE_QSPI=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -217,4 +240,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/qspi/configs/e2000q_aarch64_eg_configs b/example/peripheral/qspi/configs/e2000q_aarch64_eg_configs index 1dab65cf..855b203e 100644 --- a/example/peripheral/qspi/configs/e2000q_aarch64_eg_configs +++ b/example/peripheral/qspi/configs/e2000q_aarch64_eg_configs @@ -74,6 +74,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -114,6 +115,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -150,6 +160,7 @@ CONFIG_FREERTOS_USE_QSPI=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -171,12 +182,6 @@ CONFIG_FREERTOS_USE_QSPI=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -188,14 +193,32 @@ CONFIG_FREERTOS_USE_QSPI=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -213,4 +236,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/qspi/configs/ft2004_aarch32_eg_configs b/example/peripheral/qspi/configs/ft2004_aarch32_eg_configs index 5972fdd0..69c04290 100644 --- a/example/peripheral/qspi/configs/ft2004_aarch32_eg_configs +++ b/example/peripheral/qspi/configs/ft2004_aarch32_eg_configs @@ -74,6 +74,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -118,6 +119,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -154,6 +164,7 @@ CONFIG_FREERTOS_USE_QSPI=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -175,12 +186,6 @@ CONFIG_FREERTOS_USE_QSPI=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -192,14 +197,32 @@ CONFIG_FREERTOS_USE_QSPI=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -217,4 +240,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/qspi/configs/ft2004_aarch64_eg_configs b/example/peripheral/qspi/configs/ft2004_aarch64_eg_configs index 8bd0df26..be941bf3 100644 --- a/example/peripheral/qspi/configs/ft2004_aarch64_eg_configs +++ b/example/peripheral/qspi/configs/ft2004_aarch64_eg_configs @@ -74,6 +74,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -114,6 +115,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -150,6 +160,7 @@ CONFIG_FREERTOS_USE_QSPI=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -171,12 +182,6 @@ CONFIG_FREERTOS_USE_QSPI=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -188,14 +193,32 @@ CONFIG_FREERTOS_USE_QSPI=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -213,4 +236,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/qspi/inc/qspi_example.h b/example/peripheral/qspi/inc/qspi_example.h index d83fdfb3..4b622087 100644 --- a/example/peripheral/qspi/inc/qspi_example.h +++ b/example/peripheral/qspi/inc/qspi_example.h @@ -1,31 +1,41 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: qspi_example.h * Date: 2022-06-17 10:42:40 * LastEditTime: 2022-06-17 10:42:40 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for qspi test example function declarations. + * + * Modify History: + * Ver   Who         Date          Changes + * ----- ------      --------     -------------------------------------- + * 1.0 wangxiaodong 2022/8/9 first release */ #ifndef QSPI_EXAMPLE_H #define QSPI_EXAMPLE_H +#ifdef __cplusplus +extern "C" +{ +#endif + /* qspi read and write test */ BaseType_t FFreeRTOSQspiCreate(u32 id); +#ifdef __cplusplus +} +#endif + #endif // ! \ No newline at end of file diff --git a/example/peripheral/qspi/main.c b/example/peripheral/qspi/main.c index 0a0686a5..db1c7d65 100644 --- a/example/peripheral/qspi/main.c +++ b/example/peripheral/qspi/main.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: main.c * Date: 2022-06-17 08:17:59 * LastEditTime: 2022-06-17 08:17:59 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for qspi main entry. + * + * Modify History: + * Ver   Who         Date          Changes + * ----- ------      --------     -------------------------------------- + * 1.0 wangxiaodong 2022/8/9 first release */ #include "shell.h" @@ -31,17 +32,21 @@ int main(void) BaseType_t ret; ret = FFreeRTOSQspiCreate(0); - if(ret != pdPASS) + if (ret != pdPASS) + { goto FAIL_EXIT; + } ret = LSUserShellTask() ; - if(ret != pdPASS) + if (ret != pdPASS) + { goto FAIL_EXIT; + } - vTaskStartScheduler(); /* 启动任务,开启调度 */ + vTaskStartScheduler(); /* 启动任务,开启调度 */ while (1); /* 正常不会执行到这里 */ - + FAIL_EXIT: - printf("failed 0x%x \r\n", ret); + printf("Failed,the ret value is 0x%x. \r\n", ret); return 0; } diff --git a/example/peripheral/qspi/sdkconfig b/example/peripheral/qspi/sdkconfig index 1dab65cf..855b203e 100644 --- a/example/peripheral/qspi/sdkconfig +++ b/example/peripheral/qspi/sdkconfig @@ -74,6 +74,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -114,6 +115,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -150,6 +160,7 @@ CONFIG_FREERTOS_USE_QSPI=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -171,12 +182,6 @@ CONFIG_FREERTOS_USE_QSPI=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -188,14 +193,32 @@ CONFIG_FREERTOS_USE_QSPI=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -213,4 +236,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/qspi/sdkconfig.h b/example/peripheral/qspi/sdkconfig.h index 39b0c06c..4e01cd61 100644 --- a/example/peripheral/qspi/sdkconfig.h +++ b/example/peripheral/qspi/sdkconfig.h @@ -67,6 +67,7 @@ /* CONFIG_USE_ADC is not set */ /* CONFIG_USE_PWM is not set */ /* CONFIG_USE_IPC is not set */ +/* CONFIG_USE_MEDIA is not set */ /* end of Components Configuration */ #define CONFIG_USE_NEW_LIBC /* end of Standalone Setting */ @@ -103,6 +104,12 @@ /* Compiler Options */ +/* Cross-Compiler Setting */ + +#define CONFIG_GCC_OPTIMIZE_LEVEL 0 +/* CONFIG_USE_EXT_COMPILER is not set */ +/* CONFIG_USE_KLIN_SYS is not set */ +/* end of Cross-Compiler Setting */ #define CONFIG_OUTPUT_BINARY /* end of Compiler Options */ /* end of Building Option */ @@ -132,6 +139,7 @@ /* Freertos Eth Drivers */ /* CONFIG_FREERTOS_USE_XMAC is not set */ +/* CONFIG_FREERTOS_USE_GMAC is not set */ /* end of Freertos Eth Drivers */ /* Freertos Gpio Drivers */ @@ -150,11 +158,6 @@ /* CONFIG_FREERTOS_USE_FGDMA is not set */ /* end of Freertos DMA Drivers */ -/* Freertos MMC Drivers */ - -/* CONFIG_FREERTOS_USE_FSDIO is not set */ -/* end of Freertos MMC Drivers */ - /* Freertos Adc Drivers */ /* CONFIG_FREERTOS_USE_ADC is not set */ @@ -164,13 +167,28 @@ /* CONFIG_FREERTOS_USE_CAN is not set */ /* end of Freertos Can Drivers */ + +/* Freertos I2c Drivers */ + +/* CONFIG_FREERTOS_USE_I2C is not set */ +/* end of Freertos I2c Drivers */ + +/* Freertos Mio Drivers */ + +/* CONFIG_FREERTOS_USE_MIO is not set */ +/* end of Freertos Mio Drivers */ + +/* Freertos Timer Drivers */ + +/* CONFIG_FREERTOS_USE_TIMER is not set */ +/* end of Freertos Timer Drivers */ /* end of Component Configuration */ -/* FreeRTOS Setting */ +/* Third-Party Configuration */ /* CONFIG_USE_LWIP is not set */ #define CONFIG_USE_BACKTRACE -/* CONFIG_USE_FATFS is not set */ +/* CONFIG_USE_FATFS_0_1_4 is not set */ /* CONFIG_USE_SFUD is not set */ /* CONFIG_USE_SPIFFS is not set */ /* CONFIG_USE_AMP is not set */ @@ -186,6 +204,28 @@ /* CONFIG_USE_TLSF is not set */ /* CONFIG_USE_SDMMC_CMD is not set */ /* CONFIG_USE_CHERRY_USB is not set */ -/* end of FreeRTOS Setting */ +/* end of Third-Party Configuration */ + +/* Kernel Configuration */ + +#define CONFIG_FREERTOS_OPTIMIZED_SCHEDULER +#define CONFIG_FREERTOS_HZ 1000 +#define CONFIG_FREERTOS_MAX_PRIORITIES 32 +#define CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES 13 +#define CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES 11 +#define CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS 1 +#define CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE 1024 +#define CONFIG_FREERTOS_MAX_TASK_NAME_LEN 32 +#define CONFIG_FREERTOS_TIMER_TASK_PRIORITY 1 +#define CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH 2048 +#define CONFIG_FREERTOS_TIMER_QUEUE_LENGTH 10 +#define CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE 0 +#define CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS +#define CONFIG_FREERTOS_USE_TRACE_FACILITY +#define CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS +/* CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set */ +#define CONFIG_FREERTOS_TOTAL_HEAP_SIZE 10240 +#define CONFIG_FREERTOS_TASK_FPU_SUPPORT 1 +/* end of Kernel Configuration */ #endif diff --git a/example/peripheral/qspi/src/qspi_example.c b/example/peripheral/qspi/src/qspi_example.c index d12b1cd3..7422ab13 100644 --- a/example/peripheral/qspi/src/qspi_example.c +++ b/example/peripheral/qspi/src/qspi_example.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: qspi_example.c * Date: 2022-07-11 11:32:48 * LastEditTime: 2022-07-11 11:32:48 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for qspi test example functions. + * + * Modify History: + * Ver   Who         Date          Changes + * ----- ------      --------     -------------------------------------- + * 1.0 wangxiaodong 2022/8/9 first release */ #include #include "FreeRTOSConfig.h" @@ -33,17 +34,20 @@ #include "sdkconfig.h" /* The periods assigned to the one-shot timers. */ -#define ONE_SHOT_TIMER_PERIOD ( pdMS_TO_TICKS( 50000UL ) ) +#define ONE_SHOT_TIMER_PERIOD ( pdMS_TO_TICKS( 50000UL ) ) /* write and read task delay in milliseconds */ -#define TASK_DELAY_MS 10000UL +#define TASK_DELAY_MS 10000UL + static xTaskHandle read_handle; static xTaskHandle write_handle; static TimerHandle_t xOneShotTimer; +/* Offset 1M from flash maximum capacity*/ +#define FLASH_WR_OFFSET SZ_1M /* write and read start address */ -#define FLASH_ADDR (7 * SZ_1M) +static u32 flash_wr_start = 0 ; /* write and read cs channel */ #define QSPI_CS_CHANNEL 0 @@ -62,234 +66,234 @@ static FFreeRTOSQspiMessage message = {0}; static void FFreeRTOSQspiDelete(void); - static void QspiInitTask(void *pvParameters) { - /* The qspi_id to use is passed in via the parameter. - Cast this to a qspi_id pointer. */ - u32 qspi_id = (u32)(uintptr)pvParameters; + /* The qspi_id to use is passed in via the parameter. + Cast this to a qspi_id pointer. */ + u32 qspi_id = (u32)(uintptr)pvParameters; #if defined(CONFIG_TARGET_E2000) FIOPadSetQspiMux(qspi_id, FQSPI_CS_0); FIOPadSetQspiMux(qspi_id, FQSPI_CS_1); #endif - /* init qspi controller */ - os_qspi_ctrl_p = FFreeRTOSQspiInit(qspi_id); - if(os_qspi_ctrl_p == NULL) - { - printf("FFreeRTOSWdtInit failed!!!\n"); - goto qspi_init_exit; - } - + /* init qspi controller */ + os_qspi_ctrl_p = FFreeRTOSQspiInit(qspi_id); + flash_wr_start = os_qspi_ctrl_p->qspi_ctrl.flash_size - FLASH_WR_OFFSET; + if (os_qspi_ctrl_p == NULL) + { + printf("FFreeRTOSWdtInit failed.\n"); + goto qspi_init_exit; + } + for (int i = 0; i < READ_WRITE_TASK_NUM; i++) { xSemaphoreGive(xCountingSemaphore); } -qspi_init_exit: +qspi_init_exit: vTaskDelete(NULL); } static void QspiReadTask(void *pvParameters) { - const char *pcTaskName = "QspiReadTask is running\r\n"; - const TickType_t xDelay = pdMS_TO_TICKS(TASK_DELAY_MS); - FError ret = FQSPI_SUCCESS; - - xSemaphoreTake(xCountingSemaphore, portMAX_DELAY); - - /* As per most tasks, this task is implemented in an infinite loop. */ - for( ;; ) - { - /* Print out the name of this task. */ - printf( pcTaskName ); - - message.read_buf = rd_buf; - message.length = DAT_LENGTH; - message.addr = FLASH_ADDR; - message.cmd = FQSPI_FLASH_CMD_READ; - message.cs = QSPI_CS_CHANNEL; - ret = FFreeRTOSQspiTransfer(os_qspi_ctrl_p, &message); - if (FQSPI_SUCCESS != ret) - { - printf("QspiReadTask FFreeRTOSQspiTransfer failed, result 0x%x\r\n", ret); - } - taskENTER_CRITICAL(); //进入临界区 - FtDumpHexByte(rd_buf, DAT_LENGTH); - taskEXIT_CRITICAL(); //退出临界区 - - /* Delay for a period. This time a call to vTaskDelay() is used which - places the task into the Blocked state until the delay period has - expired. The parameter takes a time specified in 'ticks', and the - pdMS_TO_TICKS() macro is used (where the xDelay constant is - declared) to convert TASK_DELAY_MS milliseconds into an equivalent time in - ticks. */ - vTaskDelay(xDelay); - } + const char *pcTaskName = "QspiReadTask is running\r\n"; + const TickType_t xDelay = pdMS_TO_TICKS(TASK_DELAY_MS); + FError ret = FQSPI_SUCCESS; + + xSemaphoreTake(xCountingSemaphore, portMAX_DELAY); + + /* As per most tasks, this task is implemented in an infinite loop. */ + for (;;) + { + /* Print out the name of this task. */ + printf(pcTaskName); + + message.read_buf = rd_buf; + message.length = DAT_LENGTH; + message.addr = flash_wr_start; + message.cmd = FQSPI_FLASH_CMD_READ; + message.cs = QSPI_CS_CHANNEL; + ret = FFreeRTOSQspiTransfer(os_qspi_ctrl_p, &message); + if (FQSPI_SUCCESS != ret) + { + printf("QspiReadTask FFreeRTOSQspiTransfer failed, return value: 0x%x\r\n", ret); + } + taskENTER_CRITICAL(); //进入临界区 + FtDumpHexByte(rd_buf, DAT_LENGTH); + taskEXIT_CRITICAL(); //退出临界区 + + /* Delay for a period. This time a call to vTaskDelay() is used which + places the task into the Blocked state until the delay period has + expired. The parameter takes a time specified in 'ticks', and the + pdMS_TO_TICKS() macro is used (where the xDelay constant is + declared) to convert TASK_DELAY_MS milliseconds into an equivalent time in + ticks. */ + vTaskDelay(xDelay); + } } static void QspiWriteTask(void *pvParameters) { - const char *pcTaskName = "QspiWriteTask is running\r\n"; - const TickType_t xDelay = pdMS_TO_TICKS(TASK_DELAY_MS); - int i = 0; - FError ret = FQSPI_SUCCESS; + const char *pcTaskName = "QspiWriteTask is running\r\n"; + const TickType_t xDelay = pdMS_TO_TICKS(TASK_DELAY_MS); + int i = 0; + FError ret = FQSPI_SUCCESS; - xSemaphoreTake(xCountingSemaphore, portMAX_DELAY); + xSemaphoreTake(xCountingSemaphore, portMAX_DELAY); /* As per most tasks, this task is implemented in an infinite loop. */ - for( ;; ) - { - /* Print out the name of this task. */ - printf( pcTaskName ); - for (i = 0; i < DAT_LENGTH; i++) - { - wr_buf[i] = wr_buf[i] + 0x11; - } - - message.addr = FLASH_ADDR; - message.cmd = FQSPI_FLASH_CMD_SE; - message.cs = QSPI_CS_CHANNEL; - ret = FFreeRTOSQspiTransfer(os_qspi_ctrl_p, &message); - if (FQSPI_SUCCESS != ret) - { - printf("QspiWriteTask FFreeRTOSQspiTransfer failed, result 0x%x\r\n", ret); - } - - message.write_buf = wr_buf; - message.length = DAT_LENGTH; - message.addr = FLASH_ADDR; - message.cmd = FQSPI_FLASH_CMD_PP; - message.cs = QSPI_CS_CHANNEL; - - ret = FFreeRTOSQspiTransfer(os_qspi_ctrl_p, &message); - if (FQSPI_SUCCESS != ret) - { - printf("QspiWriteTask FFreeRTOSQspiTransfer failed, result 0x%x\r\n", ret); - } - - /* Delay for a period. This time a call to vTaskDelay() is used which - places the task into the Blocked state until the delay period has - expired. The parameter takes a time specified in 'ticks', and the - pdMS_TO_TICKS() macro is used (where the xDelay constant is - declared) to convert TASK_DELAY_MS milliseconds into an equivalent time in - ticks. */ - vTaskDelay(xDelay); - } + for (;;) + { + /* Print out the name of this task. */ + printf(pcTaskName); + for (i = 0; i < DAT_LENGTH; i++) + { + wr_buf[i] = wr_buf[i] + 0x11; + } + + message.addr = flash_wr_start; + message.cmd = FQSPI_FLASH_CMD_SE; + message.cs = QSPI_CS_CHANNEL; + ret = FFreeRTOSQspiTransfer(os_qspi_ctrl_p, &message); + if (FQSPI_SUCCESS != ret) + { + printf("QspiWriteTask FFreeRTOSQspiTransfer failed, return value: 0x%x\r\n", ret); + } + + message.write_buf = wr_buf; + message.length = DAT_LENGTH; + message.addr = flash_wr_start; + message.cmd = FQSPI_FLASH_CMD_PP; + message.cs = QSPI_CS_CHANNEL; + + ret = FFreeRTOSQspiTransfer(os_qspi_ctrl_p, &message); + if (FQSPI_SUCCESS != ret) + { + printf("QspiWriteTask FFreeRTOSQspiTransfer failed, return value: 0x%x\r\n", ret); + } + + /* Delay for a period. This time a call to vTaskDelay() is used which + places the task into the Blocked state until the delay period has + expired. The parameter takes a time specified in 'ticks', and the + pdMS_TO_TICKS() macro is used (where the xDelay constant is + declared) to convert TASK_DELAY_MS milliseconds into an equivalent time in + ticks. */ + vTaskDelay(xDelay); + } } -static void prvOneShotTimerCallback( TimerHandle_t xTimer ) +static void prvOneShotTimerCallback(TimerHandle_t xTimer) { - /* Output a string to show the time at which the callback was executed. */ - printf( "One-shot timer callback executing, will delete QspiReadTask and QspiWriteTask.\r\n" ); + /* Output a string to show the time at which the callback was executed. */ + printf("One-shot timer callback executing, which will delete QspiReadTask and QspiWriteTask.\r\n"); - FFreeRTOSQspiDelete(); + FFreeRTOSQspiDelete(); } BaseType_t FFreeRTOSQspiCreate(u32 id) { BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为 pdPASS */ - BaseType_t xTimerStarted = pdPASS; - - memset(&message, 0, sizeof(message)); - - xCountingSemaphore = xSemaphoreCreateCounting(READ_WRITE_TASK_NUM, 0); - if (xCountingSemaphore == NULL) - { - printf("FFreeRTOSWdtCreate xCountingSemaphore create failed.\r\n" ); - return pdFAIL; - } - - taskENTER_CRITICAL(); /*进入临界区*/ - - xReturn = xTaskCreate((TaskFunction_t )QspiInitTask, /* 任务入口函数 */ - (const char* )"QspiInitTask",/* 任务名字 */ - (uint16_t )1024, /* 任务栈大小 */ - (void* )(uintptr)id,/* 任务入口函数参数 */ - (UBaseType_t )2, /* 任务的优先级 */ - NULL); - - xReturn = xTaskCreate((TaskFunction_t )QspiReadTask, /* 任务入口函数 */ - (const char* )"QspiReadTask",/* 任务名字 */ - (uint16_t )1024, /* 任务栈大小 */ - NULL,/* 任务入口函数参数 */ - (UBaseType_t )configMAX_PRIORITIES-1, /* 任务的优先级 */ - (TaskHandle_t* )&read_handle); /* 任务控制 */ - - xReturn = xTaskCreate((TaskFunction_t )QspiWriteTask, /* 任务入口函数 */ - (const char* )"QspiWriteTask",/* 任务名字 */ - (uint16_t )1024, /* 任务栈大小 */ - NULL,/* 任务入口函数参数 */ - (UBaseType_t )configMAX_PRIORITIES-1, /* 任务的优先级 */ - (TaskHandle_t* )&write_handle); /* 任务控制 */ - - /* Create the one shot software timer, storing the handle to the created - software timer in xOneShotTimer. */ - xOneShotTimer = xTimerCreate( "OneShot Software Timer", /* Text name for the software timer - not used by FreeRTOS. */ - ONE_SHOT_TIMER_PERIOD, /* The software timer's period in ticks. */ - pdFALSE, /* Setting uxAutoRealod to pdFALSE creates a one-shot software timer. */ - 0, /* This example does not use the timer id. */ - prvOneShotTimerCallback ); /* The callback function to be used by the software timer being created. */ - - /* Check the timers were created. */ - if( xOneShotTimer != NULL ) - { - /* Start the software timers, using a block time of 0 (no block time). - The scheduler has not been started yet so any block time specified here - would be ignored anyway. */ - xTimerStarted = xTimerStart( xOneShotTimer, 0 ); - - /* The implementation of xTimerStart() uses the timer command queue, and - xTimerStart() will fail if the timer command queue gets full. The timer - service task does not get created until the scheduler is started, so all - commands sent to the command queue will stay in the queue until after - the scheduler has been started. Check both calls to xTimerStart() - passed. */ - if( xTimerStarted != pdPASS) - { - printf("CreateSoftwareTimerTasks xTimerStart failed \r\n"); - } - } - else - { - printf("CreateSoftwareTimerTasks xTimerCreate failed \r\n"); - } - - taskEXIT_CRITICAL(); - + BaseType_t xTimerStarted = pdPASS; + + memset(&message, 0, sizeof(message)); + + xCountingSemaphore = xSemaphoreCreateCounting(READ_WRITE_TASK_NUM, 0); + if (xCountingSemaphore == NULL) + { + printf("FFreeRTOSWdtCreate xCountingSemaphore create failed.\r\n"); + return pdFAIL; + } + + taskENTER_CRITICAL(); /*进入临界区*/ + + xReturn = xTaskCreate((TaskFunction_t)QspiInitTask, /* 任务入口函数 */ + (const char *)"QspiInitTask",/* 任务名字 */ + (uint16_t)1024, /* 任务栈大小 */ + (void *)(uintptr)id,/* 任务入口函数参数 */ + (UBaseType_t)2, /* 任务的优先级 */ + NULL); + + xReturn = xTaskCreate((TaskFunction_t)QspiReadTask, /* 任务入口函数 */ + (const char *)"QspiReadTask",/* 任务名字 */ + (uint16_t)1024, /* 任务栈大小 */ + NULL,/* 任务入口函数参数 */ + (UBaseType_t)configMAX_PRIORITIES - 1, /* 任务的优先级 */ + (TaskHandle_t *)&read_handle); /* 任务控制 */ + + xReturn = xTaskCreate((TaskFunction_t)QspiWriteTask, /* 任务入口函数 */ + (const char *)"QspiWriteTask",/* 任务名字 */ + (uint16_t)1024, /* 任务栈大小 */ + NULL,/* 任务入口函数参数 */ + (UBaseType_t)configMAX_PRIORITIES - 1, /* 任务的优先级 */ + (TaskHandle_t *)&write_handle); /* 任务控制 */ + + /* Create the one shot software timer, storing the handle to the created + software timer in xOneShotTimer. */ + xOneShotTimer = xTimerCreate("OneShot Software Timer", /* Text name for the software timer - not used by FreeRTOS. */ + ONE_SHOT_TIMER_PERIOD, /* The software timer's period in ticks. */ + pdFALSE, /* Setting uxAutoRealod to pdFALSE creates a one-shot software timer. */ + 0, /* This example does not use the timer id. */ + prvOneShotTimerCallback); /* The callback function to be used by the software timer being created. */ + + /* Check the timers were created. */ + if (xOneShotTimer != NULL) + { + /* Start the software timers, using a block time of 0 (no block time). + The scheduler has not been started yet so any block time specified here + would be ignored anyway. */ + xTimerStarted = xTimerStart(xOneShotTimer, 0); + + /* The implementation of xTimerStart() uses the timer command queue, and + xTimerStart() will fail if the timer command queue gets full. The timer + service task does not get created until the scheduler is started, so all + commands sent to the command queue will stay in the queue until after + the scheduler has been started. Check both calls to xTimerStart() + passed. */ + if (xTimerStarted != pdPASS) + { + printf("CreateSoftwareTimerTasks xTimerStart failed.\r\n"); + } + } + else + { + printf("CreateSoftwareTimerTasks xTimerCreate failed.\r\n"); + } + + taskEXIT_CRITICAL(); + return xReturn; } static void FFreeRTOSQspiDelete(void) { - BaseType_t xReturn = pdPASS; - FFreeRTOSQspiDeinit(os_qspi_ctrl_p); - if(read_handle) + BaseType_t xReturn = pdPASS; + FFreeRTOSQspiDeinit(os_qspi_ctrl_p); + if (read_handle) { vTaskDelete(read_handle); - printf("Delete QspiReadTask success\r\n"); + printf("Delete QspiReadTask successfully.\r\n"); } - if(write_handle) + if (write_handle) { vTaskDelete(write_handle); - printf("Delete QspiWriteTask success\r\n"); + printf("Delete QspiWriteTask successfully.\r\n"); } - /* delete count sem */ - vSemaphoreDelete(xCountingSemaphore); - - /* delete timer */ - xReturn = xTimerDelete(xOneShotTimer, 0); - if(xReturn != pdPASS) - { - printf("OneShot Software Timer Delete failed.\r\n"); - } - else - { - printf("OneShot Software Timer Delete success.\r\n"); - } + /* delete count sem */ + vSemaphoreDelete(xCountingSemaphore); + + /* delete timer */ + xReturn = xTimerDelete(xOneShotTimer, 0); + if (xReturn != pdPASS) + { + printf("OneShot Software Timer Delete failed.\r\n"); + } + else + { + printf("OneShot Software Timer Delete successfully.\r\n"); + } } diff --git a/example/peripheral/sdio/README.md b/example/peripheral/sdio/README.md index df45cc8e..e6e011d5 100644 --- a/example/peripheral/sdio/README.md +++ b/example/peripheral/sdio/README.md @@ -124,7 +124,3 @@ sd wr 0 emmc 7 3 ## 4. 修改历史记录 - - - - diff --git a/example/peripheral/sdio/configs/e2000d_aarch32_eg_configs b/example/peripheral/sdio/configs/e2000d_aarch32_eg_configs index 64f01042..f657b176 100644 --- a/example/peripheral/sdio/configs/e2000d_aarch32_eg_configs +++ b/example/peripheral/sdio/configs/e2000d_aarch32_eg_configs @@ -57,6 +57,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_TIMER is not set # CONFIG_USE_MIO is not set CONFIG_USE_SDMMC=y +# CONFIG_ENABLE_FSDMMC is not set CONFIG_ENABLE_FSDIO=y # CONFIG_USE_PCIE is not set # CONFIG_USE_WDT is not set @@ -68,6 +69,7 @@ CONFIG_ENABLE_FSDIO=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -112,6 +114,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -148,6 +159,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -169,12 +181,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -CONFIG_FREERTOS_USE_FSDIO=y -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -186,14 +192,32 @@ CONFIG_FREERTOS_USE_FSDIO=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -214,8 +238,32 @@ CONFIG_USE_SDMMC_CMD=y # # SDMMC Configuration # -CONFIG_SDMMC_PORT_FSDIO=y +# CONFIG_SDMMC_USE_FSDMMC is not set +CONFIG_SDMMC_USE_FSDIO=y # end of SDMMC Configuration # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/sdio/configs/e2000d_aarch64_eg_configs b/example/peripheral/sdio/configs/e2000d_aarch64_eg_configs index 24897cad..1bf9c3b9 100644 --- a/example/peripheral/sdio/configs/e2000d_aarch64_eg_configs +++ b/example/peripheral/sdio/configs/e2000d_aarch64_eg_configs @@ -57,6 +57,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_TIMER is not set # CONFIG_USE_MIO is not set CONFIG_USE_SDMMC=y +# CONFIG_ENABLE_FSDMMC is not set CONFIG_ENABLE_FSDIO=y # CONFIG_USE_PCIE is not set # CONFIG_USE_WDT is not set @@ -68,6 +69,7 @@ CONFIG_ENABLE_FSDIO=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -77,8 +79,8 @@ CONFIG_USE_NEW_LIBC=y # Building Option # # CONFIG_LOG_VERBOS is not set -# CONFIG_LOG_DEBUG is not set -CONFIG_LOG_INFO=y +CONFIG_LOG_DEBUG=y +# CONFIG_LOG_INFO is not set # CONFIG_LOG_WARN is not set # CONFIG_LOG_ERROR is not set # CONFIG_LOG_NONE is not set @@ -108,6 +110,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -144,6 +155,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -165,12 +177,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -CONFIG_FREERTOS_USE_FSDIO=y -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -182,14 +188,32 @@ CONFIG_FREERTOS_USE_FSDIO=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -210,8 +234,32 @@ CONFIG_USE_SDMMC_CMD=y # # SDMMC Configuration # -CONFIG_SDMMC_PORT_FSDIO=y +# CONFIG_SDMMC_USE_FSDMMC is not set +CONFIG_SDMMC_USE_FSDIO=y # end of SDMMC Configuration # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/sdio/configs/e2000q_aarch32_eg_configs b/example/peripheral/sdio/configs/e2000q_aarch32_eg_configs index 76430549..e516e173 100644 --- a/example/peripheral/sdio/configs/e2000q_aarch32_eg_configs +++ b/example/peripheral/sdio/configs/e2000q_aarch32_eg_configs @@ -57,6 +57,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_TIMER is not set # CONFIG_USE_MIO is not set CONFIG_USE_SDMMC=y +# CONFIG_ENABLE_FSDMMC is not set CONFIG_ENABLE_FSDIO=y # CONFIG_USE_PCIE is not set # CONFIG_USE_WDT is not set @@ -68,6 +69,7 @@ CONFIG_ENABLE_FSDIO=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -112,6 +114,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -148,6 +159,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -169,12 +181,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -CONFIG_FREERTOS_USE_FSDIO=y -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -186,14 +192,32 @@ CONFIG_FREERTOS_USE_FSDIO=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -214,8 +238,32 @@ CONFIG_USE_SDMMC_CMD=y # # SDMMC Configuration # -CONFIG_SDMMC_PORT_FSDIO=y +# CONFIG_SDMMC_USE_FSDMMC is not set +CONFIG_SDMMC_USE_FSDIO=y # end of SDMMC Configuration # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/sdio/configs/e2000q_aarch64_eg_configs b/example/peripheral/sdio/configs/e2000q_aarch64_eg_configs index c9591ec6..08837673 100644 --- a/example/peripheral/sdio/configs/e2000q_aarch64_eg_configs +++ b/example/peripheral/sdio/configs/e2000q_aarch64_eg_configs @@ -57,6 +57,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_TIMER is not set # CONFIG_USE_MIO is not set CONFIG_USE_SDMMC=y +# CONFIG_ENABLE_FSDMMC is not set CONFIG_ENABLE_FSDIO=y # CONFIG_USE_PCIE is not set # CONFIG_USE_WDT is not set @@ -68,6 +69,7 @@ CONFIG_ENABLE_FSDIO=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -78,9 +80,9 @@ CONFIG_USE_NEW_LIBC=y # # CONFIG_LOG_VERBOS is not set # CONFIG_LOG_DEBUG is not set -CONFIG_LOG_INFO=y +# CONFIG_LOG_INFO is not set # CONFIG_LOG_WARN is not set -# CONFIG_LOG_ERROR is not set +CONFIG_LOG_ERROR=y # CONFIG_LOG_NONE is not set CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y CONFIG_INTERRUPT_ROLE_MASTER=y @@ -108,6 +110,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -144,6 +155,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -165,12 +177,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -CONFIG_FREERTOS_USE_FSDIO=y -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -182,14 +188,32 @@ CONFIG_FREERTOS_USE_FSDIO=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -210,8 +234,32 @@ CONFIG_USE_SDMMC_CMD=y # # SDMMC Configuration # -CONFIG_SDMMC_PORT_FSDIO=y +# CONFIG_SDMMC_USE_FSDMMC is not set +CONFIG_SDMMC_USE_FSDIO=y # end of SDMMC Configuration # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/sdio/inc/sd_read_write.h b/example/peripheral/sdio/inc/sd_read_write.h index f5a37e28..a5c2ea3d 100644 --- a/example/peripheral/sdio/inc/sd_read_write.h +++ b/example/peripheral/sdio/inc/sd_read_write.h @@ -1,27 +1,28 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: sd_read_write.h * Date: 2022-07-18 16:43:35 * LastEditTime: 2022-07-18 16:43:35 - * Description:  This files is for - * - * Modify History: + * Description:  This file is for providing some sd apis. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2022/8/26 first commit */ -#ifndef EXAMPLE_SD_READ_WRITE_H -#define EXAMPLE_SD_READ_WRITE_H +#ifndef SD_READ_WRITE_H +#define SD_READ_WRITE_H #ifdef __cplusplus extern "C" diff --git a/example/peripheral/sdio/main.c b/example/peripheral/sdio/main.c index e28f6df8..71a28ae6 100644 --- a/example/peripheral/sdio/main.c +++ b/example/peripheral/sdio/main.c @@ -1,44 +1,52 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: main.c * Date: 2022-06-17 08:17:59 * LastEditTime: 2022-06-17 08:17:59 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for sdio test main entry. + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2022/8/26 first commit */ #include "shell.h" #include "shell_port.h" #include +#include "sdmmc_system.h" +#include "sd_read_write.h" int main(void) { BaseType_t ret; ret = LSUserShellTask() ; - if(ret != pdPASS) + if (ret != pdPASS) + { goto FAIL_EXIT; + } - /* ret = FFreeRTOSSdWriteRead(1U, FALSE, 0, 2); */ + /* board init */ + sdmmc_sys_init(); + + ret = FFreeRTOSSdWriteRead(1U, FALSE, 0, 4); + + vTaskStartScheduler(); + while (1); - vTaskStartScheduler(); /* 启动任务,开启调度 */ - while (1); /* 正常不会执行到这里 */ - FAIL_EXIT: - printf("failed 0x%x \r\n", ret); + printf("Failed,the ret value is 0x%x. \r\n", ret); return 0; } diff --git a/example/peripheral/sdio/sdkconfig b/example/peripheral/sdio/sdkconfig index 9a99079b..08837673 100644 --- a/example/peripheral/sdio/sdkconfig +++ b/example/peripheral/sdio/sdkconfig @@ -2,7 +2,7 @@ # # Freertos Configuration # -CONFIG_TARGET_NAME="e2000d_freertos_a64" +CONFIG_TARGET_NAME="e2000q_freertos_a64" # end of Freertos Configuration # @@ -26,8 +26,8 @@ CONFIG_USE_MMU=y # # CONFIG_TARGET_F2000_4 is not set # CONFIG_TARGET_D2000 is not set -# CONFIG_TARGET_E2000Q is not set -CONFIG_TARGET_E2000D=y +CONFIG_TARGET_E2000Q=y +# CONFIG_TARGET_E2000D is not set # CONFIG_TARGET_E2000S is not set CONFIG_TARGET_E2000=y CONFIG_DEFAULT_DEBUG_PRINT_UART1=y @@ -57,6 +57,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_TIMER is not set # CONFIG_USE_MIO is not set CONFIG_USE_SDMMC=y +# CONFIG_ENABLE_FSDMMC is not set CONFIG_ENABLE_FSDIO=y # CONFIG_USE_PCIE is not set # CONFIG_USE_WDT is not set @@ -68,6 +69,7 @@ CONFIG_ENABLE_FSDIO=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -108,6 +110,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -144,6 +155,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -165,12 +177,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -CONFIG_FREERTOS_USE_FSDIO=y -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -182,14 +188,32 @@ CONFIG_FREERTOS_USE_FSDIO=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -210,8 +234,32 @@ CONFIG_USE_SDMMC_CMD=y # # SDMMC Configuration # -CONFIG_SDMMC_PORT_FSDIO=y +# CONFIG_SDMMC_USE_FSDMMC is not set +CONFIG_SDMMC_USE_FSDIO=y # end of SDMMC Configuration # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/sdio/sdkconfig.h b/example/peripheral/sdio/sdkconfig.h index 36c7b85a..041cfb5e 100644 --- a/example/peripheral/sdio/sdkconfig.h +++ b/example/peripheral/sdio/sdkconfig.h @@ -3,7 +3,7 @@ /* Freertos Configuration */ -#define CONFIG_TARGET_NAME "e2000d_freertos_a64" +#define CONFIG_TARGET_NAME "e2000q_freertos_a64" /* end of Freertos Configuration */ /* Standalone Setting */ @@ -24,8 +24,8 @@ /* CONFIG_TARGET_F2000_4 is not set */ /* CONFIG_TARGET_D2000 is not set */ -/* CONFIG_TARGET_E2000Q is not set */ -#define CONFIG_TARGET_E2000D +#define CONFIG_TARGET_E2000Q +/* CONFIG_TARGET_E2000D is not set */ /* CONFIG_TARGET_E2000S is not set */ #define CONFIG_TARGET_E2000 #define CONFIG_DEFAULT_DEBUG_PRINT_UART1 @@ -52,6 +52,7 @@ /* CONFIG_USE_TIMER is not set */ /* CONFIG_USE_MIO is not set */ #define CONFIG_USE_SDMMC +/* CONFIG_ENABLE_FSDMMC is not set */ #define CONFIG_ENABLE_FSDIO /* CONFIG_USE_PCIE is not set */ /* CONFIG_USE_WDT is not set */ @@ -63,6 +64,7 @@ /* CONFIG_USE_ADC is not set */ /* CONFIG_USE_PWM is not set */ /* CONFIG_USE_IPC is not set */ +/* CONFIG_USE_MEDIA is not set */ /* end of Components Configuration */ #define CONFIG_USE_NEW_LIBC /* end of Standalone Setting */ @@ -99,6 +101,12 @@ /* Compiler Options */ +/* Cross-Compiler Setting */ + +#define CONFIG_GCC_OPTIMIZE_LEVEL 0 +/* CONFIG_USE_EXT_COMPILER is not set */ +/* CONFIG_USE_KLIN_SYS is not set */ +/* end of Cross-Compiler Setting */ #define CONFIG_OUTPUT_BINARY /* end of Compiler Options */ /* end of Building Option */ @@ -128,6 +136,7 @@ /* Freertos Eth Drivers */ /* CONFIG_FREERTOS_USE_XMAC is not set */ +/* CONFIG_FREERTOS_USE_GMAC is not set */ /* end of Freertos Eth Drivers */ /* Freertos Gpio Drivers */ @@ -146,11 +155,6 @@ /* CONFIG_FREERTOS_USE_FGDMA is not set */ /* end of Freertos DMA Drivers */ -/* Freertos MMC Drivers */ - -#define CONFIG_FREERTOS_USE_FSDIO -/* end of Freertos MMC Drivers */ - /* Freertos Adc Drivers */ /* CONFIG_FREERTOS_USE_ADC is not set */ @@ -160,13 +164,28 @@ /* CONFIG_FREERTOS_USE_CAN is not set */ /* end of Freertos Can Drivers */ + +/* Freertos I2c Drivers */ + +/* CONFIG_FREERTOS_USE_I2C is not set */ +/* end of Freertos I2c Drivers */ + +/* Freertos Mio Drivers */ + +/* CONFIG_FREERTOS_USE_MIO is not set */ +/* end of Freertos Mio Drivers */ + +/* Freertos Timer Drivers */ + +/* CONFIG_FREERTOS_USE_TIMER is not set */ +/* end of Freertos Timer Drivers */ /* end of Component Configuration */ -/* FreeRTOS Setting */ +/* Third-Party Configuration */ /* CONFIG_USE_LWIP is not set */ #define CONFIG_USE_BACKTRACE -/* CONFIG_USE_FATFS is not set */ +/* CONFIG_USE_FATFS_0_1_4 is not set */ /* CONFIG_USE_SFUD is not set */ /* CONFIG_USE_SPIFFS is not set */ /* CONFIG_USE_AMP is not set */ @@ -184,9 +203,32 @@ /* SDMMC Configuration */ -#define CONFIG_SDMMC_PORT_FSDIO +/* CONFIG_SDMMC_USE_FSDMMC is not set */ +#define CONFIG_SDMMC_USE_FSDIO /* end of SDMMC Configuration */ /* CONFIG_USE_CHERRY_USB is not set */ -/* end of FreeRTOS Setting */ +/* end of Third-Party Configuration */ + +/* Kernel Configuration */ + +#define CONFIG_FREERTOS_OPTIMIZED_SCHEDULER +#define CONFIG_FREERTOS_HZ 1000 +#define CONFIG_FREERTOS_MAX_PRIORITIES 32 +#define CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES 13 +#define CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES 11 +#define CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS 1 +#define CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE 1024 +#define CONFIG_FREERTOS_MAX_TASK_NAME_LEN 32 +#define CONFIG_FREERTOS_TIMER_TASK_PRIORITY 1 +#define CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH 2048 +#define CONFIG_FREERTOS_TIMER_QUEUE_LENGTH 10 +#define CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE 0 +#define CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS +#define CONFIG_FREERTOS_USE_TRACE_FACILITY +#define CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS +/* CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set */ +#define CONFIG_FREERTOS_TOTAL_HEAP_SIZE 10240 +#define CONFIG_FREERTOS_TASK_FPU_SUPPORT 1 +/* end of Kernel Configuration */ #endif diff --git a/example/peripheral/sdio/src/cmd_sd.c b/example/peripheral/sdio/src/cmd_sd.c index 253adeb3..7f857833 100644 --- a/example/peripheral/sdio/src/cmd_sd.c +++ b/example/peripheral/sdio/src/cmd_sd.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: cmd_sd.c * Date: 2022-07-12 09:33:12 * LastEditTime: 2022-07-12 09:33:12 - * Description:  This files is for - * - * Modify History: + * Description:  This file is for providing user command functions. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2022/8/26 first commit */ /***************************** Include Files *********************************/ #include @@ -43,9 +44,9 @@ /*****************************************************************************/ static void SdCmdUsage() { - printf("usage:\r\n"); + printf("Usage:\r\n"); printf(" sd wr \r\n"); - printf(" -- demo read and write by sdmmc\r\n"); + printf(" -- Demo read and write by sdmmc\r\n"); } static int SdCmdEntry(int argc, char *argv[]) @@ -53,14 +54,14 @@ static int SdCmdEntry(int argc, char *argv[]) int ret = 0; if (argc < 2) - { - SdCmdUsage(); + { + SdCmdUsage(); return -1; - } - + } + if (!strcmp(argv[1], "wr")) { - u32 sdio_id = FSDIO_HOST_INSTANCE_1; + u32 sdio_id = FSDIO1_ID; boolean is_emmc = FALSE; u32 start_blk = 0U; u32 blk_num = 2U; @@ -84,17 +85,19 @@ static int SdCmdEntry(int argc, char *argv[]) if (argc > 4) { - start_blk = (u32)simple_strtoul(argv[4], NULL, 10); + start_blk = (u32)simple_strtoul(argv[4], NULL, 10); } if (argc > 5) { - blk_num = (u32)simple_strtoul(argv[5], NULL, 10); + blk_num = (u32)simple_strtoul(argv[5], NULL, 10); } BaseType_t task_ret = FFreeRTOSSdWriteRead(sdio_id, is_emmc, start_blk, blk_num); if (pdPASS != task_ret) - return -2; + { + return -2; + } } return 0; diff --git a/example/peripheral/sdio/src/sd_read_write.c b/example/peripheral/sdio/src/sd_read_write.c index 61a81f31..d92790cb 100644 --- a/example/peripheral/sdio/src/sd_read_write.c +++ b/example/peripheral/sdio/src/sd_read_write.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: sd_read_write.c * Date: 2022-07-25 15:58:24 * LastEditTime: 2022-07-25 15:58:25 - * Description:  This files is for - * - * Modify History: + * Description:   This file is for providing functions used in cmd_sd.c file. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2022/8/26 first commit */ /***************************** Include Files *********************************/ #include @@ -26,6 +27,7 @@ #include "FreeRTOS.h" #include "task.h" +#include "event_groups.h" #include "fassert.h" #include "fdebug.h" @@ -33,45 +35,41 @@ #include "fkernel.h" #include "fcache.h" -#include "fsdio_os.h" +#include "sdmmc_host_os.h" /************************** Constant Definitions *****************************/ #define SD_WR_BUF_LEN 4096 #define SD_EVT_INIT_DONE (0x1 << 0) #define SD_EVT_WRITE_DONE (0x1 << 1) #define SD_EVT_READ_DONE (0x1 << 2) +/**************************** Type Definitions *******************************/ +typedef struct +{ + sdmmc_host_instance_t *cur_host; + sdmmc_host_config_t *cur_host_config; + fsize_t start_blk; + fsize_t block_num; +} SdioTestInfo; /************************** Variable Definitions *****************************/ static u8 sd_write_buffer[SD_WR_BUF_LEN] = {0}; static u8 sd_read_buffer[SD_WR_BUF_LEN] = {0}; + +static sdmmc_host_instance_t tf_host; +static sdmmc_host_config_t tf_host_config; +static sdmmc_host_instance_t emmc_host; +static sdmmc_host_config_t emmc_host_config; +static SdioTestInfo test_info = +{ + .cur_host = &tf_host, + .cur_host_config = &tf_host_config, + .start_blk = 0U, + .block_num = 4U +}; + static u32 sd_slot = 0U; static EventGroupHandle_t sync = NULL; static TaskHandle_t write_task = NULL; -static TaskHandle_t read_task = NULL; static TimerHandle_t exit_timer = NULL; -static FFreeRTOSSdio *sdio = NULL; -static FFreeRTOSSdioConifg sdio_config = -{ - .en_dma = TRUE, - .medium_type = FFREERTOS_SDIO_MEDIUM_TF, - .card_detect_handler = NULL, - .card_detect_args = NULL -}; -static FFreeRTOSSdioMessage read_message = -{ - .buf = sd_read_buffer, - .buf_len = SD_WR_BUF_LEN, - .start_block = 0U, - .block_num = 3U, - .trans_type = FFREERTOS_SDIO_TRANS_READ -}; -static FFreeRTOSSdioMessage write_message = -{ - .buf = sd_write_buffer, - .buf_len = SD_WR_BUF_LEN, - .start_block = 0U, - .block_num = 3U, - .trans_type = FFREERTOS_SDIO_TRANS_WRITE -}; -static u32 run_times = 3U; +static u32 run_times = 2U; static boolean is_running = FALSE; /***************** Macros (Inline Functions) Definitions *********************/ #define FSDIO_DEBUG_TAG "FSDIO-SD" @@ -86,7 +84,7 @@ static boolean is_running = FALSE; static void SDExitCallback(TimerHandle_t timer) { FError err = FT_SUCCESS; - printf("exiting.....\r\n"); + printf("Exiting.....\r\n"); if (write_task) { @@ -94,31 +92,19 @@ static void SDExitCallback(TimerHandle_t timer) write_task = NULL; } - if (read_task) - { - vTaskDelete(read_task); - read_task = NULL; - } - if (sync) { vEventGroupDelete(sync); sync = NULL; } - if (sdio) - { - err = FFreeRTOSSdioDeInit(sdio); - sdio = NULL; - } - if (pdPASS != xTimerDelete(timer, 0)) /* delete timer ifself */ { - FSDIO_ERROR("delete exit timer failed !!!"); + FSDIO_ERROR("Delete exit timer failed."); exit_timer = NULL; } - is_running = FALSE; + is_running = FALSE; } static void SDSendEvent(u32 evt_bits) @@ -126,7 +112,7 @@ static void SDSendEvent(u32 evt_bits) FASSERT(sync); BaseType_t x_result = pdFALSE; - FSDIO_DEBUG("ack evt 0x%x", evt_bits); + FSDIO_DEBUG("Ack evt 0x%x", evt_bits); x_result = xEventGroupSetBits(sync, evt_bits); } @@ -144,104 +130,84 @@ static boolean SDWaitEvent(u32 evt_bits, TickType_t wait_delay) return FALSE; } -static void SDInitTask(void * args) +static void SDInitTask(void *args) { - sdio = FFreeRTOSSdioInit(sd_slot, &sdio_config); - if (NULL == sdio) + if (SDMMC_OK != sdmmc_host_init(test_info.cur_host, test_info.cur_host_config)) { - FSDIO_ERROR("init sdio failed !!!"); + FSDIO_ERROR("Init sdio failed."); goto task_exit; } SDSendEvent(SD_EVT_INIT_DONE); task_exit: - vTaskDelete(NULL); /* delete task itself */ + vTaskDelete(NULL); /* delete task itself */ } -static void SDReadTask(void * args) +static void SDWriteReadTask(void *args) { u32 times = 0U; - const TickType_t wait_delay = pdMS_TO_TICKS(5000UL); /* wait for 5 seconds */ - const uintptr trans_len = read_message.block_num * FFREERTOS_SDIO_BLOCK_SIZE; + const TickType_t wait_delay = pdMS_TO_TICKS(2000UL); /* wait for 2 seconds */ + FError err; + const uintptr trans_len = test_info.block_num * 512U; + char ch = 'A'; - FASSERT_MSG(trans_len <= SD_WR_BUF_LEN, "trans length exceed buffer limits"); - - for (;;) + if (trans_len > SD_WR_BUF_LEN) { - /* wait write finish to get the updated contents */ - if (!SDWaitEvent(SD_EVT_WRITE_DONE, portMAX_DELAY)) - { - FSDIO_ERROR("sdio read timeout !!!"); - goto task_exit; - } + FSDIO_ERROR("Trans length exceeds the buffer limits."); + goto task_exit; + } - printf("start read ...\r\n"); + SDWaitEvent(SD_EVT_INIT_DONE, portMAX_DELAY); - memset(read_message.buf, 0U, trans_len); - FError err = FFreeRTOSSdioTransfer(sdio, &read_message); - if (FFREERTOS_SDIO_OK != err) + for (;;) + { + printf("Start reading ...\r\n"); + memset(sd_read_buffer, 0U, trans_len); + if (SDMMC_OK != sdmmc_os_read_sectors(&(test_info.cur_host->card), + sd_read_buffer, + test_info.start_blk, + test_info.block_num)) { - FSDIO_ERROR("sdio read failed !!!"); + FSDIO_ERROR("Sdio read failed."); goto task_exit; } - FCacheDCacheFlushRange((uintptr)(void *)read_message.buf, trans_len); - printf("==>Read from Block [%d:%d]\r\n", - read_message.start_block, - read_message.start_block + read_message.block_num); - - FtDumpHexByte(read_message.buf, trans_len); - - SDSendEvent(SD_EVT_READ_DONE); /* send read finish singal */ - vTaskDelay(wait_delay); + FCacheDCacheFlushRange((uintptr)(void *)sd_read_buffer, trans_len); + printf("==>Read from Block [%d:%d]\r\n", + test_info.start_blk, + test_info.start_blk + test_info.block_num); - if (++times > run_times) - break; - } + FtDumpHexByte(sd_read_buffer, min(trans_len, (fsize_t)(2 * 512U))); -task_exit: - printf("exit from read task \r\n"); - vTaskSuspend(NULL); /* suspend task */ -} - -static void SDWriteTask(void * args) -{ - u32 times = 0U; - const TickType_t wait_delay = pdMS_TO_TICKS(2000UL); /* wait for 2 seconds */ - FError err; - const uintptr trans_len = write_message.block_num * FFREERTOS_SDIO_BLOCK_SIZE; - char ch = 'A'; + /*************************************************************/ - FASSERT_MSG(trans_len <= SD_WR_BUF_LEN, "trans length exceed buffer limits"); - SDWaitEvent(SD_EVT_INIT_DONE, portMAX_DELAY); + printf("Start writing ...\r\n"); + memset(sd_write_buffer, (ch + times), trans_len); + printf("==>Write %c to Block [%d:%d]\r\n", + ch, + test_info.start_blk, + test_info.start_blk + test_info.block_num); - for (;;) - { - printf("start write ...\r\n"); - memset(write_message.buf, (ch + times), trans_len); - FCacheDCacheInvalidateRange((uintptr)(void *)write_message.buf, trans_len); - printf("==>Write %c to Block [%d:%d]\r\n", - ch, write_message.start_block, - write_message.start_block + write_message.block_num); - - err = FFreeRTOSSdioTransfer(sdio, &write_message); - if (FFREERTOS_SDIO_OK != err) + if (SDMMC_OK != sdmmc_os_write_sectors(&(test_info.cur_host->card), + sd_write_buffer, + test_info.start_blk, + test_info.block_num)) { - FSDIO_ERROR("sdio write failed !!!"); + FSDIO_ERROR("Sdio write failed."); goto task_exit; } - SDSendEvent(SD_EVT_WRITE_DONE); /* send write finish signal */ vTaskDelay(wait_delay); - SDWaitEvent(SD_EVT_READ_DONE, portMAX_DELAY); /* wait until read done and go on next write */ if (++times > run_times) + { break; + } } task_exit: - printf("exit from write task \r\n"); + printf("Exit from write task.\r\n"); vTaskSuspend(NULL); /* suspend task */ } @@ -252,65 +218,59 @@ BaseType_t FFreeRTOSSdWriteRead(u32 slot_id, boolean is_emmc, u32 start_blk, u32 if (is_running) { - FSDIO_ERROR("task is running !!!!"); + FSDIO_ERROR("Task is running."); return pdPASS; } is_running = TRUE; - printf("sd write read task\r\n"); + printf("This is sd write read task.\r\n"); + + FASSERT_MSG(NULL == sync, "Event group exists."); + FASSERT_MSG((sync = xEventGroupCreate()) != NULL, "Create event group failed."); - FASSERT_MSG(NULL == sync, "event group exists !!!"); - FASSERT_MSG((sync = xEventGroupCreate()) != NULL, "create event group failed !!!"); + test_info.cur_host = is_emmc ? &emmc_host : &tf_host; + test_info.cur_host_config = is_emmc ? &emmc_host_config : &tf_host_config; - sd_slot = slot_id; - sdio_config.medium_type = is_emmc ? FFREERTOS_SDIO_MEDIUM_EMMC: FFREERTOS_SDIO_MEDIUM_TF; + test_info.cur_host_config->slot = slot_id; + test_info.cur_host_config->type = SDMMC_HOST_TYPE_FSDIO; + test_info.cur_host_config->flags = SDMMC_HOST_WORK_MODE_DMA | SDMMC_HOST_WORK_MODE_IRQ; + test_info.cur_host_config->flags |= is_emmc ? 0U : SDMMC_HOST_REMOVABLE_CARD; - read_message.start_block = start_blk; - read_message.block_num = blk_num; - write_message.start_block = start_blk; - write_message.block_num = blk_num; + test_info.start_blk = start_blk; + test_info.block_num = blk_num; taskENTER_CRITICAL(); /* no schedule when create task */ - ret = xTaskCreate((TaskFunction_t )SDInitTask, - (const char* )"SDInitTask", - (uint16_t )2048, - NULL, - (UBaseType_t )configMAX_PRIORITIES - 1, - NULL); - FASSERT_MSG(pdPASS == ret, "create task failed"); - - ret = xTaskCreate((TaskFunction_t )SDWriteTask, - (const char* )"SDWriteTask", - (uint16_t )2048, - NULL, - (UBaseType_t )configMAX_PRIORITIES - 2, - &write_task); - - FASSERT_MSG(pdPASS == ret, "create task failed"); - - ret = xTaskCreate((TaskFunction_t )SDReadTask, - (const char* )"SDReadTask", - (uint16_t )2048, - NULL, - (UBaseType_t )configMAX_PRIORITIES - 2, - &read_task); - - FASSERT_MSG(pdPASS == ret, "create task failed"); - - exit_timer = xTimerCreate("Exit-Timer", /* Text name for the software timer - not used by FreeRTOS. */ - total_run_time, /* The software timer's period in ticks. */ - pdFALSE, /* Setting uxAutoRealod to pdFALSE creates a one-shot software timer. */ - NULL, /* use timer id to pass task data for reference. */ - SDExitCallback); /* The callback function to be used by the software timer being created. */ - - FASSERT_MSG(NULL != exit_timer, "create exit timer failed"); + ret = xTaskCreate((TaskFunction_t)SDInitTask, + (const char *)"SDInitTask", + (uint16_t)2048, + NULL, + (UBaseType_t)configMAX_PRIORITIES - 1, + NULL); + FASSERT_MSG(pdPASS == ret, "Create task failed."); + + ret = xTaskCreate((TaskFunction_t)SDWriteReadTask, + (const char *)"SDWriteReadTask", + (uint16_t)2048, + NULL, + (UBaseType_t)configMAX_PRIORITIES - 2, + &write_task); + + FASSERT_MSG(pdPASS == ret, "Create task failed."); + + exit_timer = xTimerCreate("Exit-Timer", /* Text name for the software timer - not used by FreeRTOS. */ + total_run_time, /* The software timer's period in ticks. */ + pdFALSE, /* Setting uxAutoRealod to pdFALSE creates a one-shot software timer. */ + NULL, /* use timer id to pass task data for reference. */ + SDExitCallback); /* The callback function to be used by the software timer being created. */ + + FASSERT_MSG(NULL != exit_timer, "Create exit timer failed."); taskEXIT_CRITICAL(); /* allow schedule since task created */ ret = xTimerStart(exit_timer, 0); /* start */ - FASSERT_MSG(pdPASS == ret, "start exit timer failed"); + FASSERT_MSG(pdPASS == ret, "Start exit timer failed."); return ret; } \ No newline at end of file diff --git a/example/peripheral/spi/README.md b/example/peripheral/spi/README.md index 4db99f5c..aeb88f3e 100644 --- a/example/peripheral/spi/README.md +++ b/example/peripheral/spi/README.md @@ -108,7 +108,7 @@ sf probe - 初始化成功后,在flash的偏移量0x20位置,写入一段不带空格的连续字符串,如‘write-spi-nor-flash-from-freertos-sfud’ ``` -sf write 0x10 ‘write-spi-nor-flash-from-freertos-sfud’ +sf write 0x10 "write-spi-nor-flash-from-freertos-sfud" ``` - 写入成功后,从flash的偏移量0x0开始,读取64个字节 diff --git a/example/peripheral/spi/configs/e2000d_aarch32_eg_configs b/example/peripheral/spi/configs/e2000d_aarch32_eg_configs index c014aa05..b0cc9254 100644 --- a/example/peripheral/spi/configs/e2000d_aarch32_eg_configs +++ b/example/peripheral/spi/configs/e2000d_aarch32_eg_configs @@ -68,6 +68,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -112,6 +113,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -148,6 +158,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -169,12 +180,6 @@ CONFIG_FREERTOS_USE_FSPIM=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -186,20 +191,38 @@ CONFIG_FREERTOS_USE_FSPIM=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set CONFIG_USE_SFUD=y # # SFUD Configuration # -# CONFIG_SFUD_CTRL_FSPIM is not set +CONFIG_SFUD_CTRL_FSPIM=y # CONFIG_SFUD_CTRL_FQSPI is not set # end of SFUD Configuration @@ -219,4 +242,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/spi/configs/e2000d_aarch64_eg_configs b/example/peripheral/spi/configs/e2000d_aarch64_eg_configs index 956cb09a..b047f308 100644 --- a/example/peripheral/spi/configs/e2000d_aarch64_eg_configs +++ b/example/peripheral/spi/configs/e2000d_aarch64_eg_configs @@ -68,6 +68,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -108,6 +109,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -144,6 +154,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -165,12 +176,6 @@ CONFIG_FREERTOS_USE_FSPIM=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -182,14 +187,32 @@ CONFIG_FREERTOS_USE_FSPIM=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set CONFIG_USE_SFUD=y # @@ -215,4 +238,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/spi/figs/wr_rd.png b/example/peripheral/spi/figs/wr_rd.png index 9ad3d211748dc479a956f12754d7b8987fe35abe..a308c4fe85df23803b3f9fc9f7df6b82d249c8e9 100644 GIT binary patch literal 19290 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 @@ -43,11 +44,11 @@ /*****************************************************************************/ static void SfudCmdUsage() { - printf("usage:\r\n"); - printf(" sf probe\r\n"); - printf(" -- probe and init SPI flash\r\n"); + printf("Usage:\r\n"); + printf(" sf probe\r\n"); + printf(" -- Probe and init SPI flash\r\n"); printf(" sf rw \r\n"); - printf(" -- demo read and write by sfud\r\n"); + printf(" -- Demo read and write by sfud\r\n"); } static int SfudCmdEntry(int argc, char *argv[]) @@ -56,11 +57,11 @@ static int SfudCmdEntry(int argc, char *argv[]) static boolean inited = FALSE; if (argc < 2) - { - SfudCmdUsage(); + { + SfudCmdUsage(); return -1; - } - + } + if ((FALSE == inited) || (!strcmp(argv[1], "probe"))) { if (pdPASS != FFreeRTOSSfudInit()) @@ -70,19 +71,21 @@ static int SfudCmdEntry(int argc, char *argv[]) inited = TRUE; } - + if (!strcmp(argv[1], "read")) { u32 in_chip_addr = 0x0; if (argc > 2) { - in_chip_addr = (u32)simple_strtoul(argv[2], NULL, 16); + in_chip_addr = (u32)simple_strtoul(argv[2], NULL, 16); } BaseType_t task_ret = FFreeRTOSSfudRead(in_chip_addr); if (pdPASS != task_ret) + { return -2; + } } else if (!strcmp(argv[1], "write")) { @@ -91,7 +94,7 @@ static int SfudCmdEntry(int argc, char *argv[]) if (argc > 2) { - in_chip_addr = (u32)simple_strtoul(argv[2], NULL, 16); + in_chip_addr = (u32)simple_strtoul(argv[2], NULL, 16); } if (argc > 3) @@ -101,7 +104,9 @@ static int SfudCmdEntry(int argc, char *argv[]) BaseType_t task_ret = FFreeRTOSSfudWrite(in_chip_addr, wr_str); if (pdPASS != task_ret) - return -2; + { + return -2; + } } return 0; diff --git a/example/peripheral/spi/src/sfud_read_write.c b/example/peripheral/spi/src/sfud_read_write.c index b8f6839a..3d4723dc 100644 --- a/example/peripheral/spi/src/sfud_read_write.c +++ b/example/peripheral/spi/src/sfud_read_write.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: sfud_read_write.c * Date: 2022-07-12 09:53:00 * LastEditTime: 2022-07-12 09:53:02 - * Description:  This files is for - * - * Modify History: + * Description:  This file is for providing functions used in cmd_sf.c file. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2022/8/26 first commit */ /***************************** Include Files *********************************/ #include @@ -35,7 +36,7 @@ /************************** Constant Definitions *****************************/ #define SFUD_WR_BUF_LEN 64 -#define SFUD_FLASH_INDEX SFUD_FSPIM2_INDEX +#define SFUD_FLASH_INDEX SFUD_FSPIM2_INDEX /************************** Variable Definitions *****************************/ static u32 flash_addr = 0x0; @@ -50,24 +51,26 @@ static u8 flash_buffer[SFUD_WR_BUF_LEN]; /************************** Function Prototypes ******************************/ /*****************************************************************************/ -static void SfudInitTask(void * args) +static void SfudInitTask(void *args) { sfud_err sfud_ret = sfud_init(); if (SFUD_SUCCESS != sfud_ret) + { goto task_exit; + } const sfud_flash *flash = sfud_get_device(SFUD_FLASH_INDEX); if (NULL == flash) { - FSPIM_ERROR("flash not found !!!"); + FSPIM_ERROR("Flash not found."); goto task_exit; } /* print flash info */ - printf("flash %s is found !!!!\r\n", flash->name); + printf("Flash %s is found.\r\n", flash->name); printf(" manufacturer id: 0x%x \r\n", flash->chip.mf_id); printf(" memory-type id: 0x%x \r\n", flash->chip.type_id); - printf(" capacity id: 0x%x \r\n", flash->chip.capacity_id); + printf(" capacity id: 0x%x \r\n", flash->chip.capacity_id); if (flash->chip.capacity < SZ_1M) { @@ -75,16 +78,16 @@ static void SfudInitTask(void * args) } else { - printf(" cacpity: %d MB\r\n", flash->chip.capacity / SZ_1M); + printf(" cacpity: %d MB\r\n", flash->chip.capacity / SZ_1M); } - printf(" erase granularity: %d Bytes\r\n", flash->chip.erase_gran); + printf(" Erase granularity: %d Bytes\r\n", flash->chip.erase_gran); task_exit: - vTaskDelete(NULL); /* delete task itself */ + vTaskDelete(NULL); /* delete task itself */ } -static void SfudWriteTask(void * args) +static void SfudWriteTask(void *args) { sfud_err sfud_ret; u32 in_chip_addr = flash_addr; @@ -95,7 +98,7 @@ static void SfudWriteTask(void * args) flash = sfud_get_device(SFUD_FLASH_INDEX); if (NULL == flash) { - FSPIM_ERROR("flash not found!!!"); + FSPIM_ERROR("Flash not found."); goto task_exit; } @@ -103,25 +106,25 @@ static void SfudWriteTask(void * args) sfud_ret = sfud_write_status(flash, TRUE, status); if (SFUD_SUCCESS != sfud_ret) { - FSPIM_ERROR("write flash status failed !!!"); + FSPIM_ERROR("Write flash status failed."); goto task_exit; - } + } /* get flash status */ sfud_ret = sfud_read_status(flash, &status); if (SFUD_SUCCESS != sfud_ret) { - FSPIM_ERROR("read flash status failed !!!"); + FSPIM_ERROR("Read flash status failed."); goto task_exit; } else { - printf("flash status: 0x%x\r\n", status); + printf("Flash status: 0x%x\r\n", status); } /* write to flash */ taskENTER_CRITICAL(); /* no schedule when printf bulk */ - printf("data to write @0x%x...\r\n", in_chip_addr); + printf("Data to write @0x%x...\r\n", in_chip_addr); FtDumpHexByte(write_buf, SFUD_WR_BUF_LEN); taskEXIT_CRITICAL(); @@ -129,14 +132,14 @@ static void SfudWriteTask(void * args) sfud_ret = sfud_erase(flash, in_chip_addr, SFUD_WR_BUF_LEN); if (SFUD_SUCCESS != sfud_ret) { - FSPIM_ERROR("erase flash failed !!!"); + FSPIM_ERROR("Erase flash failed."); goto task_exit; } sfud_ret = sfud_write(flash, in_chip_addr, SFUD_WR_BUF_LEN, write_buf); if (SFUD_SUCCESS != sfud_ret) { - FSPIM_ERROR("write flash failed !!!"); + FSPIM_ERROR("Write flash failed."); goto task_exit; } @@ -144,7 +147,7 @@ task_exit: vTaskDelete(NULL); /* delete task itself */ } -static void SfudReadTask(void * args) +static void SfudReadTask(void *args) { sfud_err sfud_ret; u32 in_chip_addr = flash_addr; @@ -155,7 +158,7 @@ static void SfudReadTask(void * args) flash = sfud_get_device(SFUD_FLASH_INDEX); if (NULL == flash) { - FSPIM_ERROR("flash not found!!!"); + FSPIM_ERROR("Flash not found."); goto task_exit; } @@ -163,12 +166,12 @@ static void SfudReadTask(void * args) sfud_ret = sfud_read_status(flash, &status); if (SFUD_SUCCESS != sfud_ret) { - FSPIM_ERROR("read flash status failed !!!"); + FSPIM_ERROR("Read flash status failed."); goto task_exit; } else { - printf("flash status: 0x%x\r\n", status); + printf("Flash status: 0x%x\r\n", status); } /* read from flash */ @@ -176,12 +179,12 @@ static void SfudReadTask(void * args) sfud_ret = sfud_read(flash, in_chip_addr, SFUD_WR_BUF_LEN, read_buf); if (SFUD_SUCCESS != sfud_ret) { - FSPIM_ERROR("read flash failed !!!"); + FSPIM_ERROR("Read flash failed."); goto task_exit; } taskENTER_CRITICAL(); /* no schedule when printf bulk */ - printf("data read from flash @0x%x...\r\n", in_chip_addr); + printf("Data read from flash @0x%x...\r\n", in_chip_addr); FtDumpHexByte(read_buf, SFUD_WR_BUF_LEN); taskEXIT_CRITICAL(); @@ -192,31 +195,31 @@ task_exit: BaseType_t FFreeRTOSSfudRead(u32 in_chip_addr) { BaseType_t xReturn = pdPASS; - - printf("sfud read task\r\n"); - + + printf("This is sfud read task.\r\n"); + memset(flash_buffer, 0, sizeof(flash_buffer)); flash_addr = in_chip_addr; taskENTER_CRITICAL(); /* no schedule when create task */ - xReturn = xTaskCreate((TaskFunction_t )SfudReadTask, - (const char* )"SfudReadTask", - (uint16_t )2048, - NULL, - (UBaseType_t )configMAX_PRIORITIES - 1, - NULL); - + xReturn = xTaskCreate((TaskFunction_t)SfudReadTask, + (const char *)"SfudReadTask", + (uint16_t)2048, + NULL, + (UBaseType_t)configMAX_PRIORITIES - 1, + NULL); + taskEXIT_CRITICAL(); /* allow schedule since task created */ - + return xReturn; } BaseType_t FFreeRTOSSfudWrite(u32 in_chip_addr, const char *content) { BaseType_t xReturn = pdPASS; - - printf("sfud write task\r\n"); + + printf("This is sfud write task.\r\n"); flash_addr = in_chip_addr; if (strlen(content) + 1 > SFUD_WR_BUF_LEN) @@ -226,16 +229,16 @@ BaseType_t FFreeRTOSSfudWrite(u32 in_chip_addr, const char *content) memset(flash_buffer, 0, sizeof(flash_buffer)); memcpy(flash_buffer, content, strlen(content) + 1); - + taskENTER_CRITICAL(); /* no schedule when create task */ - xReturn = xTaskCreate((TaskFunction_t )SfudWriteTask, - (const char* )"SfudWriteTask", - (uint16_t )2048, - NULL, - (UBaseType_t )configMAX_PRIORITIES - 1, - NULL); - + xReturn = xTaskCreate((TaskFunction_t)SfudWriteTask, + (const char *)"SfudWriteTask", + (uint16_t)2048, + NULL, + (UBaseType_t)configMAX_PRIORITIES - 1, + NULL); + taskEXIT_CRITICAL(); /* allow schedule since task created */ return xReturn; @@ -244,18 +247,18 @@ BaseType_t FFreeRTOSSfudWrite(u32 in_chip_addr, const char *content) BaseType_t FFreeRTOSSfudInit(void) { BaseType_t xReturn = pdPASS; - - printf("sfud init task\r\n"); + + printf("This is sfud init task.\r\n"); taskENTER_CRITICAL(); /* no schedule when create task */ - xReturn = xTaskCreate((TaskFunction_t )SfudInitTask, - (const char* )"SfudInitTask", - (uint16_t )2048, - NULL, - (UBaseType_t )configMAX_PRIORITIES - 1, - NULL); - + xReturn = xTaskCreate((TaskFunction_t)SfudInitTask, + (const char *)"SfudInitTask", + (uint16_t)2048, + NULL, + (UBaseType_t)configMAX_PRIORITIES - 1, + NULL); + taskEXIT_CRITICAL(); /* allow schedule since task created */ return pdPASS; diff --git a/example/storage/spim_spiffs/Kconfig b/example/peripheral/timer_tacho/Kconfig similarity index 100% rename from example/storage/spim_spiffs/Kconfig rename to example/peripheral/timer_tacho/Kconfig diff --git a/example/storage/sata_fatfs/README.md b/example/peripheral/timer_tacho/README.md similarity index 38% rename from example/storage/sata_fatfs/README.md rename to example/peripheral/timer_tacho/README.md index 4cede421..60016387 100644 --- a/example/storage/sata_fatfs/README.md +++ b/example/peripheral/timer_tacho/README.md @@ -12,57 +12,58 @@ * * * FilePath: README.md - * Date: 2022-02-24 16:55:00 - * LastEditTime: 2022-03-21 17:00:59 - * Description:  This file is for + * Date: 2022-08-26 16:17:36 + * LastEditTime: 2022-08-26 16:17:36 + * Description:  This file is for timer_tacho * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 0.1.0 liushengming 2022.08.26 init --> -# Sata FATFS测试 + +# timer_tacho base on freertos ## 1. 例程介绍 ->介绍例程的用途,使用场景,相关基本概念,描述用户可以使用例程完成哪些工作
    +本例程示范了freertos环境下的timer、tacho和capture的使用,包括timer控制器的初始化、定时、信号捕捉操作; +程序启动后,创建timer、tacho或capture(两者使用同一IO,默认tacho,变更需要更改初始化和任务)的初始化任务,分别测试定时功能,采样转换功能,以及脉冲计数触发功能; +例程仅仅支持E2000上使用; +E2000DQ上使用的demo板上的 PWM-IN12(tacho—in12) 进行测试。 -文件系统是一类负责管理和存储文件信息的软件机构,在磁盘上组织文件的方法。作为常用的文件系统,FATFS免费开源,专门为小型嵌入式系统设计。 +## 2. 如何使用例程 -本例程在Sata上实现FATFS的存储媒介读/写接口(disk I/O),支持文件系统格式化加载,文件创建读写和遍历等基本操作。 +本例程需要用到 +- Phytium开发板(E2000DQ of demo板) +- [Phytium freeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) +- [Phytium standalone SDK](https://gitee.com/phytium_embedded/phytium-standalone-sdk) +### 2.1 硬件配置方法 -## 2. 如何使用例程 +本例程支持的硬件平台包括 +- E2000DQ demo开发板 ->描述开发平台准备,使用例程配置,构建和下载镜像的过程
    +对应的配置项是 -### 2.1 硬件配置方法 +- CONFIG_TARGET_E2000D、 CONFIG_TARGET_E2000Q ->哪些硬件平台是支持的,需要哪些外设,例程与开发板哪些IO口相关等(建议附录开发板照片,展示哪些IO口被引出)
    +### 2.1.1 硬件连线 -本例程在FT2000/4,D2000,E2000平台测试通过,您可以参考以下方法配置本例程所需要的硬件和软件环境, -- FT2000/4,D2000或E2000开发板 -- 本例程基于FT2000/4平台,使用Marvell 88SE9215芯片通过PCIE接口转接Sata,外接Sata硬盘 -- 将转接板插入PCIE插槽,接入sata硬盘至转接板的CN1(也就是port 0) +- E2000 pwm_in12使用1KHz的方波 -![hardware](./figs/hardware.png) +![hardware_e2000](./figs/tacho_hdw.png) ### 2.2 SDK配置方法 ->依赖哪些驱动、库和第三方组件,如何完成配置(列出需要使能的关键配置项)
    +本例程需要, -本例程需要的配置包括, -- Letter Shell组件,依赖 USE_LETTER_SHELL -- FATFS组件,依赖 USE_FATFS 和 SELECT_FATFS_FSATA_PCIE -- PCIE组件,作为转接接口,依赖USE_PCIE -- SATA组件,依赖 USE_SATA +- CONFIG_USE_LETTER_SHELL +- CONFIG_FREERTOS_USE_TIMER +- CONFIG_LS_PL011_UART 本例子已经提供好具体的编译指令,以下进行介绍: - make 将目录下的工程进行编译 - make clean 将目录下的工程进行清理 - make boot 将目录下的工程进行编译,并将生成的elf 复制到目标地址 -- make load_d2000_aarch64 将预设64bit d2000 下的配置加载至工程中 -- make load_d2000_aarch32 将预设32bit d2000 下的配置加载至工程中 -- make load_ft2004_aarch64 将预设64bit ft2004 下的配置加载至工程中 -- make load_ft2004_aarch32 将预设32bit ft2004 下的配置加载至工程中 - make load_e2000d_aarch64 将预设64bit e2000d 下的配置加载至工程中 - make load_e2000d_aarch32 将预设32bit e2000d 下的配置加载至工程中 - make load_e2000q_aarch64 将预设64bit e2000q 下的配置加载至工程中 @@ -70,19 +71,25 @@ - make menuconfig 配置目录下的参数变量 - make backup_kconfig 将目录下的sdkconfig 备份到./configs下 -具体使用方法为: +具体使用方法为: - 在当前目录下 - 执行以上指令 ### 2.3 构建和下载 ->描述构建、烧录下载镜像的过程,列出相关的命令
    +#### 2.3.1 构建过程 + +- 在host侧完成配置 +>配置成E2000Q,对于其它平台,使用对应的默认配置,如E2000D `make load_e2000d_aarch32` -使用例程的一般过程为 +- 选择目标平台 +``` +make load_e2000q_aarch64 +``` -- 选择目标平台和例程需要的配置 +- 选择例程需要的配置 ``` -make load_ft2004_aarch32 +make menuconfig ``` - 进行编译 @@ -95,6 +102,8 @@ make make boot ``` +#### 2.3.2 下载过程 + - host侧设置重启host侧tftp服务器 ``` sudo service tftpd-hpa restart @@ -111,30 +120,23 @@ bootelf -p 0x90100000 ### 2.4 输出与实验现象 ->描述输入输出情况,列出存在哪些输出,对应的输出是什么(建议附录相关现象图片)
    -程序启动后,依次创建Init、Read、Write任务,创建单次模式软件定时器用于删除任务,Init任务会首先初始化并挂载sata盘(如果sata盘不是fat格式,还会进行格式化操作),随后创建一个文件,然后释放信号量通知Read和Write任务开始执行; -- Init完成,目前只在port0上接了sata盘 -![init](./figs/init.png) - -- 读写任务周期性执行 -![wr](./figs/wr.png) - -- 软件定时器触发,删除读写任务 -![delete](./figs/delete.png) - -## 3. 如何解决问题 +- 系统进入后,创建timer初始化任务,创建tacho初始化任务,注册中断服务函数,创建两个功能的任务函数。 ->主要记录使用例程中可能会遇到的问题,给出相应的解决方案
    -- 如果使用E2000D开发板,可以选择使用sata控制器,只需要在fatfs的介质选择中使能SELECT_FATFS_FSATA_CONTROLLER -![menuconfig](./figs/menuconfig.png) +- E2000 -- 在configs文件夹的默认配置中,ft2004和d2000是使用的pcie转sata配置,e2000是使用的sata控制器配置 +![e2000d](./figs/timer_capture.png) -## 4. 修改历史记录 +![e2000d](./figs/timer_tacho.png) ->记录例程的重大修改记录,标明修改发生的版本号
    +- 图中我们使用timer id 0 作为定时器任务的控制器,time in 的数字表示进入循环定时中断服务的次数。 +- get captureCnt表示使用timer id 12控制器来采集脉冲的个数(设置上升沿捕获) +- tachometer id使用timer id 12控制器来抓取1KHz信号来模拟风扇波形信号。RPM表示转速 -V0.0.1 首次合入 +## 3. 如何解决问题 +- 若出现风扇中断异常,需确认连接是否正确,确保风扇波形不低于报警中断的最低设置转速。 +- 由于timer控制器的数量远多余pwm_in IO口数值,所以尽量使用id 15后面的定时控制器来做普通定时器。 +## 4. 修改历史记录 +v0.1.0 init diff --git a/example/storage/spim_spiffs/configs/e2000d_aarch32_eg_configs b/example/peripheral/timer_tacho/configs/e2000d_aarch32_eg_configs similarity index 67% rename from example/storage/spim_spiffs/configs/e2000d_aarch32_eg_configs rename to example/peripheral/timer_tacho/configs/e2000d_aarch32_eg_configs index 85b81d19..faaaf578 100644 --- a/example/storage/spim_spiffs/configs/e2000d_aarch32_eg_configs +++ b/example/peripheral/timer_tacho/configs/e2000d_aarch32_eg_configs @@ -2,7 +2,7 @@ # # Freertos Configuration # -CONFIG_TARGET_NAME="e2000d_freertos_a32" +CONFIG_TARGET_NAME="freertos" # end of Freertos Configuration # @@ -15,9 +15,8 @@ CONFIG_USE_FREERTOS=y # CONFIG_TARGET_ARMV8_AARCH32=y # CONFIG_TARGET_ARMV8_AARCH64 is not set -CONFIG_USE_CACHE=y -CONFIG_USE_MMU=y -CONFIG_USE_SYS_TICK=y +# CONFIG_USE_CACHE is not set +# CONFIG_USE_SYS_TICK is not set CONFIG_USE_AARCH64_L1_TO_AARCH32=y # end of Arch Configuration @@ -39,14 +38,7 @@ CONFIG_DEFAULT_DEBUG_PRINT_UART1=y # Components Configuration # # CONFIG_USE_SPI is not set -CONFIG_USE_QSPI=y - -# -# Qspi Configuration -# -CONFIG_USE_FQSPI=y -# end of Qspi Configuration - +# CONFIG_USE_QSPI is not set CONFIG_USE_GIC=y CONFIG_ENABLE_GICV3=y CONFIG_USE_SERIAL=y @@ -61,7 +53,14 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ETH is not set # CONFIG_USE_CAN is not set # CONFIG_USE_I2C is not set -# CONFIG_USE_TIMER is not set +CONFIG_USE_TIMER=y + +# +# Hardware Timer Configuration +# +CONFIG_ENABLE_TIMER_TACHO=y +# end of Hardware Timer Configuration + # CONFIG_USE_MIO is not set # CONFIG_USE_SDMMC is not set # CONFIG_USE_PCIE is not set @@ -74,6 +73,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -84,9 +84,9 @@ CONFIG_USE_NEW_LIBC=y # # CONFIG_LOG_VERBOS is not set # CONFIG_LOG_DEBUG is not set -CONFIG_LOG_INFO=y +# CONFIG_LOG_INFO is not set # CONFIG_LOG_WARN is not set -# CONFIG_LOG_ERROR is not set +CONFIG_LOG_ERROR=y # CONFIG_LOG_NONE is not set CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y CONFIG_INTERRUPT_ROLE_MASTER=y @@ -118,6 +118,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -141,7 +150,7 @@ CONFIG_FREERTOS_USE_UART=y # # Freertos Qspi Drivers # -CONFIG_FREERTOS_USE_QSPI=y +# CONFIG_FREERTOS_USE_QSPI is not set # end of Freertos Qspi Drivers # @@ -154,6 +163,7 @@ CONFIG_FREERTOS_USE_QSPI=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -175,12 +185,6 @@ CONFIG_FREERTOS_USE_QSPI=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -192,35 +196,34 @@ CONFIG_FREERTOS_USE_QSPI=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers -# end of Component Configuration # -# FreeRTOS Setting +# Freertos I2c Drivers # -# CONFIG_USE_LWIP is not set -CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set -CONFIG_USE_SFUD=y +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers # -# SFUD Configuration +# Freertos Mio Drivers # -# CONFIG_SFUD_CTRL_FSPIM is not set -CONFIG_SFUD_CTRL_FQSPI=y -# CONFIG_SFUD_QSPI_READ_MODE_READ is not set -# CONFIG_SFUD_QSPI_READ_MODE_DUAL_READ is not set -CONFIG_SFUD_QSPI_READ_MODE_QUAD_READ=y -# end of SFUD Configuration - -CONFIG_USE_SPIFFS=y +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers # -# SPIFFS Configuration +# Freertos Timer Drivers # -# CONFIG_SPIFFS_ON_FSPIM_SFUD is not set -CONFIG_SPIFFS_ON_FQSPI_SFUD=y -# end of SPIFFS Configuration +CONFIG_FREERTOS_USE_TIMER=y +# end of Freertos Timer Drivers +# end of Component Configuration +# +# Third-Party Configuration +# +# CONFIG_USE_LWIP is not set +CONFIG_USE_BACKTRACE=y +# CONFIG_USE_FATFS_0_1_4 is not set +# CONFIG_USE_SFUD is not set +# CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set CONFIG_USE_LETTER_SHELL=y @@ -233,7 +236,30 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set # end of Letter Shell Configuration -CONFIG_USE_TLSF=y +# CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/timer_tacho/configs/e2000d_aarch64_eg_configs b/example/peripheral/timer_tacho/configs/e2000d_aarch64_eg_configs new file mode 100644 index 00000000..3d1c2f6c --- /dev/null +++ b/example/peripheral/timer_tacho/configs/e2000d_aarch64_eg_configs @@ -0,0 +1,261 @@ + +# +# Freertos Configuration +# +CONFIG_TARGET_NAME="freertos" +# end of Freertos Configuration + +# +# Standalone Setting +# +CONFIG_USE_FREERTOS=y + +# +# Arch Configuration +# +# CONFIG_TARGET_ARMV8_AARCH32 is not set +CONFIG_TARGET_ARMV8_AARCH64=y +# CONFIG_USE_CACHE is not set +# CONFIG_USE_SYS_TICK is not set +# CONFIG_MMU_DEBUG_PRINTS is not set +# end of Arch Configuration + +# +# Board Configuration +# +# CONFIG_TARGET_F2000_4 is not set +# CONFIG_TARGET_D2000 is not set +# CONFIG_TARGET_E2000Q is not set +CONFIG_TARGET_E2000D=y +# CONFIG_TARGET_E2000S is not set +CONFIG_TARGET_E2000=y +CONFIG_DEFAULT_DEBUG_PRINT_UART1=y +# CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set +# CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set +# end of Board Configuration + +# +# Components Configuration +# +# CONFIG_USE_SPI is not set +# CONFIG_USE_QSPI is not set +CONFIG_USE_GIC=y +CONFIG_ENABLE_GICV3=y +CONFIG_USE_SERIAL=y + +# +# Usart Configuration +# +CONFIG_ENABLE_Pl011_UART=y +# end of Usart Configuration + +# CONFIG_USE_GPIO is not set +# CONFIG_USE_ETH is not set +# CONFIG_USE_CAN is not set +# CONFIG_USE_I2C is not set +CONFIG_USE_TIMER=y + +# +# Hardware Timer Configuration +# +CONFIG_ENABLE_TIMER_TACHO=y +# end of Hardware Timer Configuration + +# CONFIG_USE_MIO is not set +# CONFIG_USE_SDMMC is not set +# CONFIG_USE_PCIE is not set +# CONFIG_USE_WDT is not set +# CONFIG_USE_DMA is not set +# CONFIG_USE_NAND is not set +# CONFIG_USE_RTC is not set +# CONFIG_USE_SATA is not set +# CONFIG_USE_USB is not set +# CONFIG_USE_ADC is not set +# CONFIG_USE_PWM is not set +# CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set +# end of Components Configuration + +CONFIG_USE_NEW_LIBC=y +# end of Standalone Setting + +# +# Building Option +# +# CONFIG_LOG_VERBOS is not set +# CONFIG_LOG_DEBUG is not set +# CONFIG_LOG_INFO is not set +# CONFIG_LOG_WARN is not set +CONFIG_LOG_ERROR=y +# CONFIG_LOG_NONE is not set +CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y +CONFIG_INTERRUPT_ROLE_MASTER=y +# CONFIG_INTERRUPT_ROLE_SLAVE is not set +# CONFIG_LOG_EXTRA_INFO is not set +# CONFIG_BOOTUP_DEBUG_PRINTS is not set + +# +# Linker Options +# +# CONFIG_AARCH32_RAM_LD is not set +CONFIG_AARCH64_RAM_LD=y +# CONFIG_USER_DEFINED_LD is not set +CONFIG_LINK_SCRIPT_ROM=y +CONFIG_ROM_START_UP_ADDR=0x80100000 +CONFIG_ROM_SIZE_MB=1 +CONFIG_LINK_SCRIPT_RAM=y +CONFIG_RAM_START_UP_ADDR=0x81000000 +CONFIG_RAM_SIZE_MB=64 +CONFIG_HEAP_SIZE=1 +CONFIG_STACK_SIZE=0x100000 +CONFIG_FPU_STACK_SIZE=0x1000 +# end of Linker Options + +# +# Compiler Options +# + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + +CONFIG_OUTPUT_BINARY=y +# end of Compiler Options +# end of Building Option + +# +# Component Configuration +# + +# +# Freertos Uart Drivers +# +CONFIG_FREERTOS_USE_UART=y +# end of Freertos Uart Drivers + +# +# Freertos Pwm Drivers +# +# CONFIG_FREERTOS_USE_PWM is not set +# end of Freertos Pwm Drivers + +# +# Freertos Qspi Drivers +# +# CONFIG_FREERTOS_USE_QSPI is not set +# end of Freertos Qspi Drivers + +# +# Freertos Wdt Drivers +# +# CONFIG_FREERTOS_USE_WDT is not set +# end of Freertos Wdt Drivers + +# +# Freertos Eth Drivers +# +# CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set +# end of Freertos Eth Drivers + +# +# Freertos Gpio Drivers +# +# CONFIG_FREERTOS_USE_GPIO is not set +# end of Freertos Gpio Drivers + +# +# Freertos Spim Drivers +# +# CONFIG_FREERTOS_USE_FSPIM is not set +# end of Freertos Spim Drivers + +# +# Freertos DMA Drivers +# +# CONFIG_FREERTOS_USE_FDDMA is not set +# CONFIG_FREERTOS_USE_FGDMA is not set +# end of Freertos DMA Drivers + +# +# Freertos Adc Drivers +# +# CONFIG_FREERTOS_USE_ADC is not set +# end of Freertos Adc Drivers + +# +# Freertos Can Drivers +# +# CONFIG_FREERTOS_USE_CAN is not set +# end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +CONFIG_FREERTOS_USE_TIMER=y +# end of Freertos Timer Drivers +# end of Component Configuration + +# +# Third-Party Configuration +# +# CONFIG_USE_LWIP is not set +CONFIG_USE_BACKTRACE=y +# CONFIG_USE_FATFS_0_1_4 is not set +# CONFIG_USE_SFUD is not set +# CONFIG_USE_SPIFFS is not set +# CONFIG_USE_AMP is not set +CONFIG_USE_LETTER_SHELL=y + +# +# Letter Shell Configuration +# +CONFIG_LS_PL011_UART=y +CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y +# CONFIG_DEFAULT_LETTER_SHELL_USE_UART0 is not set +# CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set +# end of Letter Shell Configuration + +# CONFIG_USE_TLSF is not set +# CONFIG_USE_SDMMC_CMD is not set +# CONFIG_USE_CHERRY_USB is not set +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/storage/sata_fatfs/configs/ft2004_aarch32_eg_configs b/example/peripheral/timer_tacho/configs/e2000q_aarch32_eg_configs similarity index 67% rename from example/storage/sata_fatfs/configs/ft2004_aarch32_eg_configs rename to example/peripheral/timer_tacho/configs/e2000q_aarch32_eg_configs index 1570e26b..bb9b4af4 100644 --- a/example/storage/sata_fatfs/configs/ft2004_aarch32_eg_configs +++ b/example/peripheral/timer_tacho/configs/e2000q_aarch32_eg_configs @@ -2,7 +2,7 @@ # # Freertos Configuration # -CONFIG_TARGET_NAME="ft2004_freertos_a32" +CONFIG_TARGET_NAME="freertos" # end of Freertos Configuration # @@ -15,21 +15,20 @@ CONFIG_USE_FREERTOS=y # CONFIG_TARGET_ARMV8_AARCH32=y # CONFIG_TARGET_ARMV8_AARCH64 is not set -CONFIG_USE_CACHE=y -CONFIG_USE_L3CACHE=y -CONFIG_USE_MMU=y -CONFIG_USE_SYS_TICK=y +# CONFIG_USE_CACHE is not set +# CONFIG_USE_SYS_TICK is not set CONFIG_USE_AARCH64_L1_TO_AARCH32=y # end of Arch Configuration # # Board Configuration # -CONFIG_TARGET_F2000_4=y +# CONFIG_TARGET_F2000_4 is not set # CONFIG_TARGET_D2000 is not set -# CONFIG_TARGET_E2000Q is not set +CONFIG_TARGET_E2000Q=y # CONFIG_TARGET_E2000D is not set # CONFIG_TARGET_E2000S is not set +CONFIG_TARGET_E2000=y CONFIG_DEFAULT_DEBUG_PRINT_UART1=y # CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set # CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set @@ -54,33 +53,27 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ETH is not set # CONFIG_USE_CAN is not set # CONFIG_USE_I2C is not set -# CONFIG_USE_TIMER is not set -# CONFIG_USE_MIO is not set -# CONFIG_USE_SDMMC is not set -CONFIG_USE_PCIE=y +CONFIG_USE_TIMER=y # -# Pcie Configuration +# Hardware Timer Configuration # -CONFIG_ENABLE_F_PCIE=y -# end of Pcie Configuration +CONFIG_ENABLE_TIMER_TACHO=y +# end of Hardware Timer Configuration +# CONFIG_USE_MIO is not set +# CONFIG_USE_SDMMC is not set +# CONFIG_USE_PCIE is not set # CONFIG_USE_WDT is not set # CONFIG_USE_DMA is not set # CONFIG_USE_NAND is not set # CONFIG_USE_RTC is not set -CONFIG_USE_SATA=y - -# -# FSATA Configuration -# -CONFIG_ENABLE_FSATA=y -# end of FSATA Configuration - +# CONFIG_USE_SATA is not set # CONFIG_USE_USB is not set # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -91,9 +84,9 @@ CONFIG_USE_NEW_LIBC=y # # CONFIG_LOG_VERBOS is not set # CONFIG_LOG_DEBUG is not set -CONFIG_LOG_INFO=y +# CONFIG_LOG_INFO is not set # CONFIG_LOG_WARN is not set -# CONFIG_LOG_ERROR is not set +CONFIG_LOG_ERROR=y # CONFIG_LOG_NONE is not set CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y CONFIG_INTERRUPT_ROLE_MASTER=y @@ -125,6 +118,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -161,6 +163,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -182,12 +185,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -199,24 +196,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers -# end of Component Configuration # -# FreeRTOS Setting +# Freertos I2c Drivers # -# CONFIG_USE_LWIP is not set -CONFIG_USE_BACKTRACE=y -CONFIG_USE_FATFS=y +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers # -# FATFS Configuration +# Freertos Mio Drivers # -# CONFIG_SELECT_FATFS_RAM_DISK is not set -# CONFIG_SELECT_FATFS_FSDMMC is not set -CONFIG_SELECT_FATFS_FSATA_PCIE=y -# CONFIG_SELECT_FATFS_USB is not set -# end of FATFS Configuration +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers +# +# Freertos Timer Drivers +# +CONFIG_FREERTOS_USE_TIMER=y +# end of Freertos Timer Drivers +# end of Component Configuration + +# +# Third-Party Configuration +# +# CONFIG_USE_LWIP is not set +CONFIG_USE_BACKTRACE=y +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -231,7 +236,30 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set # end of Letter Shell Configuration -CONFIG_USE_TLSF=y +# CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/timer_tacho/configs/e2000q_aarch64_eg_configs b/example/peripheral/timer_tacho/configs/e2000q_aarch64_eg_configs new file mode 100644 index 00000000..2879a78d --- /dev/null +++ b/example/peripheral/timer_tacho/configs/e2000q_aarch64_eg_configs @@ -0,0 +1,261 @@ + +# +# Freertos Configuration +# +CONFIG_TARGET_NAME="freertos" +# end of Freertos Configuration + +# +# Standalone Setting +# +CONFIG_USE_FREERTOS=y + +# +# Arch Configuration +# +# CONFIG_TARGET_ARMV8_AARCH32 is not set +CONFIG_TARGET_ARMV8_AARCH64=y +# CONFIG_USE_CACHE is not set +# CONFIG_USE_SYS_TICK is not set +# CONFIG_MMU_DEBUG_PRINTS is not set +# end of Arch Configuration + +# +# Board Configuration +# +# CONFIG_TARGET_F2000_4 is not set +# CONFIG_TARGET_D2000 is not set +CONFIG_TARGET_E2000Q=y +# CONFIG_TARGET_E2000D is not set +# CONFIG_TARGET_E2000S is not set +CONFIG_TARGET_E2000=y +CONFIG_DEFAULT_DEBUG_PRINT_UART1=y +# CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set +# CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set +# end of Board Configuration + +# +# Components Configuration +# +# CONFIG_USE_SPI is not set +# CONFIG_USE_QSPI is not set +CONFIG_USE_GIC=y +CONFIG_ENABLE_GICV3=y +CONFIG_USE_SERIAL=y + +# +# Usart Configuration +# +CONFIG_ENABLE_Pl011_UART=y +# end of Usart Configuration + +# CONFIG_USE_GPIO is not set +# CONFIG_USE_ETH is not set +# CONFIG_USE_CAN is not set +# CONFIG_USE_I2C is not set +CONFIG_USE_TIMER=y + +# +# Hardware Timer Configuration +# +CONFIG_ENABLE_TIMER_TACHO=y +# end of Hardware Timer Configuration + +# CONFIG_USE_MIO is not set +# CONFIG_USE_SDMMC is not set +# CONFIG_USE_PCIE is not set +# CONFIG_USE_WDT is not set +# CONFIG_USE_DMA is not set +# CONFIG_USE_NAND is not set +# CONFIG_USE_RTC is not set +# CONFIG_USE_SATA is not set +# CONFIG_USE_USB is not set +# CONFIG_USE_ADC is not set +# CONFIG_USE_PWM is not set +# CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set +# end of Components Configuration + +CONFIG_USE_NEW_LIBC=y +# end of Standalone Setting + +# +# Building Option +# +# CONFIG_LOG_VERBOS is not set +# CONFIG_LOG_DEBUG is not set +# CONFIG_LOG_INFO is not set +# CONFIG_LOG_WARN is not set +CONFIG_LOG_ERROR=y +# CONFIG_LOG_NONE is not set +CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y +CONFIG_INTERRUPT_ROLE_MASTER=y +# CONFIG_INTERRUPT_ROLE_SLAVE is not set +# CONFIG_LOG_EXTRA_INFO is not set +# CONFIG_BOOTUP_DEBUG_PRINTS is not set + +# +# Linker Options +# +# CONFIG_AARCH32_RAM_LD is not set +CONFIG_AARCH64_RAM_LD=y +# CONFIG_USER_DEFINED_LD is not set +CONFIG_LINK_SCRIPT_ROM=y +CONFIG_ROM_START_UP_ADDR=0x80100000 +CONFIG_ROM_SIZE_MB=1 +CONFIG_LINK_SCRIPT_RAM=y +CONFIG_RAM_START_UP_ADDR=0x81000000 +CONFIG_RAM_SIZE_MB=64 +CONFIG_HEAP_SIZE=1 +CONFIG_STACK_SIZE=0x100000 +CONFIG_FPU_STACK_SIZE=0x1000 +# end of Linker Options + +# +# Compiler Options +# + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + +CONFIG_OUTPUT_BINARY=y +# end of Compiler Options +# end of Building Option + +# +# Component Configuration +# + +# +# Freertos Uart Drivers +# +CONFIG_FREERTOS_USE_UART=y +# end of Freertos Uart Drivers + +# +# Freertos Pwm Drivers +# +# CONFIG_FREERTOS_USE_PWM is not set +# end of Freertos Pwm Drivers + +# +# Freertos Qspi Drivers +# +# CONFIG_FREERTOS_USE_QSPI is not set +# end of Freertos Qspi Drivers + +# +# Freertos Wdt Drivers +# +# CONFIG_FREERTOS_USE_WDT is not set +# end of Freertos Wdt Drivers + +# +# Freertos Eth Drivers +# +# CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set +# end of Freertos Eth Drivers + +# +# Freertos Gpio Drivers +# +# CONFIG_FREERTOS_USE_GPIO is not set +# end of Freertos Gpio Drivers + +# +# Freertos Spim Drivers +# +# CONFIG_FREERTOS_USE_FSPIM is not set +# end of Freertos Spim Drivers + +# +# Freertos DMA Drivers +# +# CONFIG_FREERTOS_USE_FDDMA is not set +# CONFIG_FREERTOS_USE_FGDMA is not set +# end of Freertos DMA Drivers + +# +# Freertos Adc Drivers +# +# CONFIG_FREERTOS_USE_ADC is not set +# end of Freertos Adc Drivers + +# +# Freertos Can Drivers +# +# CONFIG_FREERTOS_USE_CAN is not set +# end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +CONFIG_FREERTOS_USE_TIMER=y +# end of Freertos Timer Drivers +# end of Component Configuration + +# +# Third-Party Configuration +# +# CONFIG_USE_LWIP is not set +CONFIG_USE_BACKTRACE=y +# CONFIG_USE_FATFS_0_1_4 is not set +# CONFIG_USE_SFUD is not set +# CONFIG_USE_SPIFFS is not set +# CONFIG_USE_AMP is not set +CONFIG_USE_LETTER_SHELL=y + +# +# Letter Shell Configuration +# +CONFIG_LS_PL011_UART=y +CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y +# CONFIG_DEFAULT_LETTER_SHELL_USE_UART0 is not set +# CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set +# end of Letter Shell Configuration + +# CONFIG_USE_TLSF is not set +# CONFIG_USE_SDMMC_CMD is not set +# CONFIG_USE_CHERRY_USB is not set +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/timer_tacho/figs/tacho_hdw.png b/example/peripheral/timer_tacho/figs/tacho_hdw.png new file mode 100644 index 0000000000000000000000000000000000000000..e523d350e997be2da72068cecce9130074c4d032 GIT binary patch literal 1144514 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μv1J`fYIvAur(Z0~@tyFs9iIjGZd0=yJG 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

    ?&Y@dDeN?iY+L`p;+>%{i|)&hZAhZ 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

    ;Ef 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

    KAltxmHgX(m;NwP)X)Ro~ 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

    93qS#A5-tp+^2R)c#2H-4uC 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 z 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

    O9x9&S@PBx`vNs!=J}vq(LGCchiy5ll{>ij+yy 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 z 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 literal 0 HcmV?d00001 diff --git a/example/peripheral/timer_tacho/figs/timer_capture.png b/example/peripheral/timer_tacho/figs/timer_capture.png new file mode 100644 index 0000000000000000000000000000000000000000..be579323637c5aed38ca6d5781ad51f6d60354b3 GIT binary patch literal 39549 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

    b+_4O^fo&s0B&o-+w*_`dlEj9Ml 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 MhSy8A?mYN^0C~4SegFUf literal 0 HcmV?d00001 diff --git a/example/peripheral/timer_tacho/figs/timer_tacho.png b/example/peripheral/timer_tacho/figs/timer_tacho.png new file mode 100644 index 0000000000000000000000000000000000000000..ac6729b4d558dd755b0eb6d7e145b4f8da6fdf13 GIT binary patch literal 43535 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 -#include "FreeRTOS.h" -#include "task.h" +#include "shell.h" #include "shell_port.h" +#include "timer_tacho_example.h" -int main() +int main(void) { - BaseType_t ret = pdPASS; + BaseType_t ret; + + ret = FFreeRTOSTimerTachoCreate(); + if (ret != pdPASS) + { + goto FAIL_EXIT; + } ret = LSUserShellTask(); - if(ret != pdPASS) + if (ret != pdPASS) + { goto FAIL_EXIT; - - vTaskStartScheduler(); /* 启动任务,开启调度 */ + } + + vTaskStartScheduler(); /* 启动任务,开启调度 */ while (1); /* 正常不会执行到这里 */ - -FAIL_EXIT: - printf("failed 0x%x \r\n", ret); +FAIL_EXIT: + printf("Failed,the ret value is 0x%x. \r\n", ret); return 0; -} \ No newline at end of file +} diff --git a/example/storage/spim_spiffs/makefile b/example/peripheral/timer_tacho/makefile similarity index 89% rename from example/storage/spim_spiffs/makefile rename to example/peripheral/timer_tacho/makefile index c1f632e8..d5622739 100644 --- a/example/storage/spim_spiffs/makefile +++ b/example/peripheral/timer_tacho/makefile @@ -23,9 +23,7 @@ include $(FREERTOS_SDK_ROOT)/make/build_freertos.mk boot: make -j @cp ./$(CONFIG_TARGET_NAME).elf $(USR_BOOT_DIR)/$(BOOT_IMG_NAME).elf -ifdef CONFIG_OUTPUT_BINARY @cp ./$(CONFIG_TARGET_NAME).bin $(USR_BOOT_DIR)/$(BOOT_IMG_NAME).bin -endif - @ls $(USR_BOOT_DIR)/$(BOOT_IMG_NAME).* -l + @ls -l $(USR_BOOT_DIR)/$(BOOT_IMG_NAME).* diff --git a/example/peripheral/timer_tacho/sdkconfig b/example/peripheral/timer_tacho/sdkconfig new file mode 100644 index 00000000..2879a78d --- /dev/null +++ b/example/peripheral/timer_tacho/sdkconfig @@ -0,0 +1,261 @@ + +# +# Freertos Configuration +# +CONFIG_TARGET_NAME="freertos" +# end of Freertos Configuration + +# +# Standalone Setting +# +CONFIG_USE_FREERTOS=y + +# +# Arch Configuration +# +# CONFIG_TARGET_ARMV8_AARCH32 is not set +CONFIG_TARGET_ARMV8_AARCH64=y +# CONFIG_USE_CACHE is not set +# CONFIG_USE_SYS_TICK is not set +# CONFIG_MMU_DEBUG_PRINTS is not set +# end of Arch Configuration + +# +# Board Configuration +# +# CONFIG_TARGET_F2000_4 is not set +# CONFIG_TARGET_D2000 is not set +CONFIG_TARGET_E2000Q=y +# CONFIG_TARGET_E2000D is not set +# CONFIG_TARGET_E2000S is not set +CONFIG_TARGET_E2000=y +CONFIG_DEFAULT_DEBUG_PRINT_UART1=y +# CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set +# CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set +# end of Board Configuration + +# +# Components Configuration +# +# CONFIG_USE_SPI is not set +# CONFIG_USE_QSPI is not set +CONFIG_USE_GIC=y +CONFIG_ENABLE_GICV3=y +CONFIG_USE_SERIAL=y + +# +# Usart Configuration +# +CONFIG_ENABLE_Pl011_UART=y +# end of Usart Configuration + +# CONFIG_USE_GPIO is not set +# CONFIG_USE_ETH is not set +# CONFIG_USE_CAN is not set +# CONFIG_USE_I2C is not set +CONFIG_USE_TIMER=y + +# +# Hardware Timer Configuration +# +CONFIG_ENABLE_TIMER_TACHO=y +# end of Hardware Timer Configuration + +# CONFIG_USE_MIO is not set +# CONFIG_USE_SDMMC is not set +# CONFIG_USE_PCIE is not set +# CONFIG_USE_WDT is not set +# CONFIG_USE_DMA is not set +# CONFIG_USE_NAND is not set +# CONFIG_USE_RTC is not set +# CONFIG_USE_SATA is not set +# CONFIG_USE_USB is not set +# CONFIG_USE_ADC is not set +# CONFIG_USE_PWM is not set +# CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set +# end of Components Configuration + +CONFIG_USE_NEW_LIBC=y +# end of Standalone Setting + +# +# Building Option +# +# CONFIG_LOG_VERBOS is not set +# CONFIG_LOG_DEBUG is not set +# CONFIG_LOG_INFO is not set +# CONFIG_LOG_WARN is not set +CONFIG_LOG_ERROR=y +# CONFIG_LOG_NONE is not set +CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y +CONFIG_INTERRUPT_ROLE_MASTER=y +# CONFIG_INTERRUPT_ROLE_SLAVE is not set +# CONFIG_LOG_EXTRA_INFO is not set +# CONFIG_BOOTUP_DEBUG_PRINTS is not set + +# +# Linker Options +# +# CONFIG_AARCH32_RAM_LD is not set +CONFIG_AARCH64_RAM_LD=y +# CONFIG_USER_DEFINED_LD is not set +CONFIG_LINK_SCRIPT_ROM=y +CONFIG_ROM_START_UP_ADDR=0x80100000 +CONFIG_ROM_SIZE_MB=1 +CONFIG_LINK_SCRIPT_RAM=y +CONFIG_RAM_START_UP_ADDR=0x81000000 +CONFIG_RAM_SIZE_MB=64 +CONFIG_HEAP_SIZE=1 +CONFIG_STACK_SIZE=0x100000 +CONFIG_FPU_STACK_SIZE=0x1000 +# end of Linker Options + +# +# Compiler Options +# + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + +CONFIG_OUTPUT_BINARY=y +# end of Compiler Options +# end of Building Option + +# +# Component Configuration +# + +# +# Freertos Uart Drivers +# +CONFIG_FREERTOS_USE_UART=y +# end of Freertos Uart Drivers + +# +# Freertos Pwm Drivers +# +# CONFIG_FREERTOS_USE_PWM is not set +# end of Freertos Pwm Drivers + +# +# Freertos Qspi Drivers +# +# CONFIG_FREERTOS_USE_QSPI is not set +# end of Freertos Qspi Drivers + +# +# Freertos Wdt Drivers +# +# CONFIG_FREERTOS_USE_WDT is not set +# end of Freertos Wdt Drivers + +# +# Freertos Eth Drivers +# +# CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set +# end of Freertos Eth Drivers + +# +# Freertos Gpio Drivers +# +# CONFIG_FREERTOS_USE_GPIO is not set +# end of Freertos Gpio Drivers + +# +# Freertos Spim Drivers +# +# CONFIG_FREERTOS_USE_FSPIM is not set +# end of Freertos Spim Drivers + +# +# Freertos DMA Drivers +# +# CONFIG_FREERTOS_USE_FDDMA is not set +# CONFIG_FREERTOS_USE_FGDMA is not set +# end of Freertos DMA Drivers + +# +# Freertos Adc Drivers +# +# CONFIG_FREERTOS_USE_ADC is not set +# end of Freertos Adc Drivers + +# +# Freertos Can Drivers +# +# CONFIG_FREERTOS_USE_CAN is not set +# end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +CONFIG_FREERTOS_USE_TIMER=y +# end of Freertos Timer Drivers +# end of Component Configuration + +# +# Third-Party Configuration +# +# CONFIG_USE_LWIP is not set +CONFIG_USE_BACKTRACE=y +# CONFIG_USE_FATFS_0_1_4 is not set +# CONFIG_USE_SFUD is not set +# CONFIG_USE_SPIFFS is not set +# CONFIG_USE_AMP is not set +CONFIG_USE_LETTER_SHELL=y + +# +# Letter Shell Configuration +# +CONFIG_LS_PL011_UART=y +CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y +# CONFIG_DEFAULT_LETTER_SHELL_USE_UART0 is not set +# CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set +# end of Letter Shell Configuration + +# CONFIG_USE_TLSF is not set +# CONFIG_USE_SDMMC_CMD is not set +# CONFIG_USE_CHERRY_USB is not set +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/storage/spim_spiffs/sdkconfig.h b/example/peripheral/timer_tacho/sdkconfig.h similarity index 65% rename from example/storage/spim_spiffs/sdkconfig.h rename to example/peripheral/timer_tacho/sdkconfig.h index 58cde585..cec51f9a 100644 --- a/example/storage/spim_spiffs/sdkconfig.h +++ b/example/peripheral/timer_tacho/sdkconfig.h @@ -3,7 +3,7 @@ /* Freertos Configuration */ -#define CONFIG_TARGET_NAME "e2000d_freertos_a64" +#define CONFIG_TARGET_NAME "freertos" /* end of Freertos Configuration */ /* Standalone Setting */ @@ -14,9 +14,8 @@ /* CONFIG_TARGET_ARMV8_AARCH32 is not set */ #define CONFIG_TARGET_ARMV8_AARCH64 -#define CONFIG_USE_CACHE -#define CONFIG_USE_MMU -#define CONFIG_USE_SYS_TICK +/* CONFIG_USE_CACHE is not set */ +/* CONFIG_USE_SYS_TICK is not set */ /* CONFIG_MMU_DEBUG_PRINTS is not set */ /* end of Arch Configuration */ @@ -24,8 +23,8 @@ /* CONFIG_TARGET_F2000_4 is not set */ /* CONFIG_TARGET_D2000 is not set */ -/* CONFIG_TARGET_E2000Q is not set */ -#define CONFIG_TARGET_E2000D +#define CONFIG_TARGET_E2000Q +/* CONFIG_TARGET_E2000D is not set */ /* CONFIG_TARGET_E2000S is not set */ #define CONFIG_TARGET_E2000 #define CONFIG_DEFAULT_DEBUG_PRINT_UART1 @@ -35,14 +34,8 @@ /* Components Configuration */ -#define CONFIG_USE_SPI -#define CONFIG_USE_FSPIM -#define CONFIG_USE_QSPI - -/* Qspi Configuration */ - -#define CONFIG_USE_FQSPI -/* end of Qspi Configuration */ +/* CONFIG_USE_SPI is not set */ +/* CONFIG_USE_QSPI is not set */ #define CONFIG_USE_GIC #define CONFIG_ENABLE_GICV3 #define CONFIG_USE_SERIAL @@ -55,7 +48,12 @@ /* CONFIG_USE_ETH is not set */ /* CONFIG_USE_CAN is not set */ /* CONFIG_USE_I2C is not set */ -/* CONFIG_USE_TIMER is not set */ +#define CONFIG_USE_TIMER + +/* Hardware Timer Configuration */ + +#define CONFIG_ENABLE_TIMER_TACHO +/* end of Hardware Timer Configuration */ /* CONFIG_USE_MIO is not set */ /* CONFIG_USE_SDMMC is not set */ /* CONFIG_USE_PCIE is not set */ @@ -68,6 +66,7 @@ /* CONFIG_USE_ADC is not set */ /* CONFIG_USE_PWM is not set */ /* CONFIG_USE_IPC is not set */ +/* CONFIG_USE_MEDIA is not set */ /* end of Components Configuration */ #define CONFIG_USE_NEW_LIBC /* end of Standalone Setting */ @@ -104,6 +103,12 @@ /* Compiler Options */ +/* Cross-Compiler Setting */ + +#define CONFIG_GCC_OPTIMIZE_LEVEL 0 +/* CONFIG_USE_EXT_COMPILER is not set */ +/* CONFIG_USE_KLIN_SYS is not set */ +/* end of Cross-Compiler Setting */ #define CONFIG_OUTPUT_BINARY /* end of Compiler Options */ /* end of Building Option */ @@ -122,7 +127,7 @@ /* Freertos Qspi Drivers */ -#define CONFIG_FREERTOS_USE_QSPI +/* CONFIG_FREERTOS_USE_QSPI is not set */ /* end of Freertos Qspi Drivers */ /* Freertos Wdt Drivers */ @@ -133,6 +138,7 @@ /* Freertos Eth Drivers */ /* CONFIG_FREERTOS_USE_XMAC is not set */ +/* CONFIG_FREERTOS_USE_GMAC is not set */ /* end of Freertos Eth Drivers */ /* Freertos Gpio Drivers */ @@ -142,7 +148,7 @@ /* Freertos Spim Drivers */ -#define CONFIG_FREERTOS_USE_FSPIM +/* CONFIG_FREERTOS_USE_FSPIM is not set */ /* end of Freertos Spim Drivers */ /* Freertos DMA Drivers */ @@ -151,11 +157,6 @@ /* CONFIG_FREERTOS_USE_FGDMA is not set */ /* end of Freertos DMA Drivers */ -/* Freertos MMC Drivers */ - -/* CONFIG_FREERTOS_USE_FSDIO is not set */ -/* end of Freertos MMC Drivers */ - /* Freertos Adc Drivers */ /* CONFIG_FREERTOS_USE_ADC is not set */ @@ -165,30 +166,30 @@ /* CONFIG_FREERTOS_USE_CAN is not set */ /* end of Freertos Can Drivers */ -/* end of Component Configuration */ -/* FreeRTOS Setting */ +/* Freertos I2c Drivers */ -/* CONFIG_USE_LWIP is not set */ -#define CONFIG_USE_BACKTRACE -/* CONFIG_USE_FATFS is not set */ -#define CONFIG_USE_SFUD +/* CONFIG_FREERTOS_USE_I2C is not set */ +/* end of Freertos I2c Drivers */ -/* SFUD Configuration */ +/* Freertos Mio Drivers */ -#define CONFIG_SFUD_CTRL_FSPIM -#define CONFIG_SFUD_CTRL_FQSPI -/* CONFIG_SFUD_QSPI_READ_MODE_READ is not set */ -/* CONFIG_SFUD_QSPI_READ_MODE_DUAL_READ is not set */ -#define CONFIG_SFUD_QSPI_READ_MODE_QUAD_READ -/* end of SFUD Configuration */ -#define CONFIG_USE_SPIFFS +/* CONFIG_FREERTOS_USE_MIO is not set */ +/* end of Freertos Mio Drivers */ -/* SPIFFS Configuration */ +/* Freertos Timer Drivers */ + +#define CONFIG_FREERTOS_USE_TIMER +/* end of Freertos Timer Drivers */ +/* end of Component Configuration */ -#define CONFIG_SPIFFS_ON_FSPIM_SFUD -/* CONFIG_SPIFFS_ON_FQSPI_SFUD is not set */ -/* end of SPIFFS Configuration */ +/* Third-Party Configuration */ + +/* CONFIG_USE_LWIP is not set */ +#define CONFIG_USE_BACKTRACE +/* CONFIG_USE_FATFS_0_1_4 is not set */ +/* CONFIG_USE_SFUD is not set */ +/* CONFIG_USE_SPIFFS is not set */ /* CONFIG_USE_AMP is not set */ #define CONFIG_USE_LETTER_SHELL @@ -199,9 +200,31 @@ /* CONFIG_DEFAULT_LETTER_SHELL_USE_UART0 is not set */ /* CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set */ /* end of Letter Shell Configuration */ -#define CONFIG_USE_TLSF +/* CONFIG_USE_TLSF is not set */ /* CONFIG_USE_SDMMC_CMD is not set */ /* CONFIG_USE_CHERRY_USB is not set */ -/* end of FreeRTOS Setting */ +/* end of Third-Party Configuration */ + +/* Kernel Configuration */ + +#define CONFIG_FREERTOS_OPTIMIZED_SCHEDULER +#define CONFIG_FREERTOS_HZ 1000 +#define CONFIG_FREERTOS_MAX_PRIORITIES 32 +#define CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES 13 +#define CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES 11 +#define CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS 1 +#define CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE 1024 +#define CONFIG_FREERTOS_MAX_TASK_NAME_LEN 32 +#define CONFIG_FREERTOS_TIMER_TASK_PRIORITY 1 +#define CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH 2048 +#define CONFIG_FREERTOS_TIMER_QUEUE_LENGTH 10 +#define CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE 0 +#define CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS +#define CONFIG_FREERTOS_USE_TRACE_FACILITY +#define CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS +/* CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set */ +#define CONFIG_FREERTOS_TOTAL_HEAP_SIZE 10240 +#define CONFIG_FREERTOS_TASK_FPU_SUPPORT 1 +/* end of Kernel Configuration */ #endif diff --git a/example/peripheral/timer_tacho/src/timer_tacho_example.c b/example/peripheral/timer_tacho/src/timer_tacho_example.c new file mode 100644 index 00000000..88f0819b --- /dev/null +++ b/example/peripheral/timer_tacho/src/timer_tacho_example.c @@ -0,0 +1,387 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: timer_tacho_example.c + * Date: 2022-08-24 13:57:55 + * LastEditTime: 2022-08-24 13:57:56 + * Description:  This file is for timer tacho example functions. + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 liushengming 2022/11/25 init + */ + +#include +#include "FreeRTOSConfig.h" +#include "FreeRTOS.h" +#include "task.h" +#include "fpinctrl.h" +#include "fassert.h" +#include "timers.h" +#include "ftimer_tacho_os.h" +#include "timer_tacho_example.h" +#include "fparameters.h" +#include "fpinctrl.h" +#include "fcpu_info.h" +#include "sdkconfig.h" +#include "fdebug.h" + +/* The periods assigned to the one-shot timers. */ +#define ONE_SHOT_TIMER_PERIOD ( pdMS_TO_TICKS( 50000UL ) ) + +#define TIMER_IRQ_PRIORITY 0xb +#define TACHO_IRQ_PRIORITY 0xc +#define TIMER_INSTANCE_NUM 0U +#define TACHO_INSTANCE_NUM 12U + +/* write and read task delay in milliseconds */ +#define TASK_DELAY_MS 2000UL + +static xTaskHandle timer_handle; +static xTaskHandle tacho_handle; +static xTaskHandle cap_handle; +static xTaskHandle init_handle; + +static FFreeRTOSTimerTacho *os_timer_ctrl; +static FFreeRTOSTimerTacho *os_tacho_ctrl; + +volatile int timerflag = 0; +volatile int tachoflag = 0; + +/***** timer intr and handler******/ +/** + * @name: CycCmpIntrHandler + * @msg: 循环定时回调函数 + * @return {*} + * @param {void} *param + */ +static void CycCmpIntrHandler(void *param) +{ + FTimerTachoCtrl *instance_p = (FTimerTachoCtrl *)param; + timerflag++; + printf("Cyc intr,id: %d,times_in: %d.\r\n", instance_p->config.id, timerflag); +} + +/** + * @name: OnceCmpIntrHandler + * @msg: 单次定时回调服务函数 + * @return {*} + * @param {void} *param + */ +static void OnceCmpIntrHandler(void *param) +{ + FTimerTachoCtrl *instance_p = (FTimerTachoCtrl *)param; + printf("Once cmp intr, timer id: %d.\r\n", instance_p->config.id); + FTimerSetInterruptMask(instance_p, FTIMER_EVENT_ONCE_CMP, FALSE); +} + +/** + * @name: RolloverIntrHandler + * @msg: 此中断已经在驱动层进行了屏蔽,由于我们设置的cmp值已经是翻转值,所以等同于中断计数中断,此处可作为用法的拓展 + * @return {*} + * @param {void} *param + */ +static void RolloverIntrHandler(void *param) +{ + FTimerTachoCtrl *instance_p = (FTimerTachoCtrl *)param; + /* Anything else that you can do.*/ + printf("Roll over cmp intr, timer id: %d", instance_p->config.id); +} + +/** + * @name: TimerDisableIntr + * @msg: 失能中断 + * @return {void} + * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构 + */ +void TimerDisableIntr(FTimerTachoCtrl *instance_p) +{ + u32 irq_num = FTIMER_TACHO_IRQ_NUM(instance_p->config.id); + + InterruptMask(irq_num); +} + +/** + * @name: TimerEnableIntr + * @msg: 设置并且使能中断 + * @return {void} + * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构 + */ +static void TimerEnableIntr(FTimerTachoCtrl *instance_p) +{ + FASSERT(instance_p); + + u32 irq_num = FTIMER_TACHO_IRQ_NUM(instance_p->config.id); + + u32 cpu_id; + GetCpuId(&cpu_id); + InterruptSetTargetCpus(irq_num, cpu_id); + /* disable timer irq */ + InterruptMask(irq_num); + + /* umask timer irq */ + InterruptSetPriority(irq_num, TIMER_IRQ_PRIORITY); + InterruptInstall(irq_num, FTimerTachoIntrHandler, instance_p, instance_p->config.name); + + FTimerTachoSetIntr(instance_p); + /* enable irq */ + InterruptUmask(irq_num); + + return ; +} + +/***** tacho intr and handler******/ + +static void TachoDisableIntr(FTimerTachoCtrl *instance_p) +{ + FASSERT(instance_p); + u32 irq_num = FTIMER_TACHO_IRQ_NUM(instance_p->config.id); + InterruptMask(irq_num); +} + +static void TachOverIntrHandler(void *param) +{ + FTimerTachoCtrl *instance_p = (FTimerTachoCtrl *)param; + u32 irq_num = FTIMER_TACHO_IRQ_NUM(instance_p->config.id); + InterruptMask(irq_num); + u32 rpm; + FTachoGetFanRPM(instance_p, &rpm); + printf("TachOver intr,tacho id: %d,rpm:%d.\r\n", instance_p->config.id, rpm); + InterruptUmask(irq_num); + tachoflag++; + if (tachoflag > 20) + { + tachoflag = 0; + TachoDisableIntr(instance_p); + printf("Please deinit tacho,then init."); + } +} + +static void CapIntrHandler(void *param) +{ + FTimerTachoCtrl *instance_p = (FTimerTachoCtrl *)param; + printf("TachCapt intr,tacho id: %d", instance_p->config.id); +} + +static void TachUnderIntrHandler(void *param) +{ + FTimerTachoCtrl *instance_p = (FTimerTachoCtrl *)param; + u32 irq_num = FTIMER_TACHO_IRQ_NUM(instance_p->config.id); + InterruptMask(irq_num); + u32 rpm; + FTachoGetFanRPM(instance_p, &rpm); + printf("TachUnder intr,tacho id: %d,rpm:%d.\r\n", instance_p->config.id, rpm); + InterruptUmask(irq_num); + tachoflag++; + if (tachoflag > 20) + { + tachoflag = 0; + TachoDisableIntr(instance_p); + printf("Please deinit tacho,then init again."); + } +} + +void TachoEnableIntr(FTimerTachoCtrl *instance_p) +{ + FASSERT(instance_p); + u32 irq_num = FTIMER_TACHO_IRQ_NUM(instance_p->config.id); + + u32 cpu_id; + GetCpuId(&cpu_id); + InterruptSetTargetCpus(irq_num, cpu_id); + + /* disable timer irq */ + InterruptMask(irq_num); + + /* umask timer irq */ + InterruptSetPriority(irq_num, TACHO_IRQ_PRIORITY); + InterruptInstall(irq_num, FTimerTachoIntrHandler, instance_p, instance_p->config.name); + + FTimerTachoSetIntr(instance_p); + /* enable irq */ + InterruptUmask(irq_num); + + return; +} + +static void TimerTask(void *pvParameters) +{ + TickType_t xDelay = pdMS_TO_TICKS(TASK_DELAY_MS); + FError ret = FREERTOS_TIMER_TACHO_SUCCESS; + FFreeRTOSTimerTacho *timer_p = (FFreeRTOSTimerTacho *)pvParameters; + vTaskDelay(xDelay); + printf("\r\n*****TimerTask is running...\r\n"); + + TimerEnableIntr(&os_timer_ctrl->ctrl); + ret = FFreeRTOSTimerStart(timer_p); + if (ret != FREERTOS_TIMER_TACHO_SUCCESS) + { + printf("TimerTask Start failed.\r\n"); + return; + } + + xDelay = pdMS_TO_TICKS(10000);/*delay 10s*/ + vTaskDelay(xDelay); + + ret = FFreeRTOSTimerStop(timer_p); + if (ret != FREERTOS_TIMER_TACHO_SUCCESS) + { + printf("TimerTask Stop failed.\r\n"); + return; + } + + /* disable timer irq */ + TimerDisableIntr(&os_timer_ctrl->ctrl); + FFreeRTOSTimerDeinit(timer_p); + printf("***TimerTask is over.\r\n"); + vTaskDelete(NULL); +} + +static void TachoTask(void *pvParameters) +{ + const TickType_t xDelay = pdMS_TO_TICKS(TASK_DELAY_MS); + FFreeRTOSTimerTacho *tacho_p = (FFreeRTOSTimerTacho *)pvParameters; + FError ret = FREERTOS_TIMER_TACHO_SUCCESS; + vTaskDelay(xDelay); + printf("\r\n*****TachoTask is running...\r\n"); + + TachoEnableIntr(&tacho_p->ctrl); + ret = FFreeRTOSTimerStart(tacho_p); + u32 rpm; + vTaskDelay(100);/*等待采样周期完成*/ + if (ret != FREERTOS_TIMER_TACHO_SUCCESS) + { + printf("Tacho start failed.\r\n"); + return; + } + for (size_t i = 0; i < 5; i++) + { + ret = FFreeRTOSTachoGetRPM(tacho_p, &rpm); + if (ret != FREERTOS_TIMER_TACHO_SUCCESS) + { + printf("TachoTask Stop failed.\r\n"); + return; + } + printf("***GET_RPM:%d.\r\n", rpm); + vTaskDelay(xDelay);/*Collect every 2 seconds*/ + } + TachoDisableIntr(&tacho_p->ctrl); + FFreeRTOSTimerStop(tacho_p); + FFreeRTOSTachoDeinit(tacho_p); + +tacho_task_exit: + printf("***TachoTask over.\r\n"); + vTaskDelete(NULL); +} + +static void captask(void *pvParameters) +{ + const TickType_t xDelay = pdMS_TO_TICKS(TASK_DELAY_MS); + FFreeRTOSTimerTacho *cap_p = (FFreeRTOSTimerTacho *)pvParameters; + FError ret = FREERTOS_TIMER_TACHO_SUCCESS; + vTaskDelay(pdMS_TO_TICKS(1)); + + printf("\r\n*****TimerCapTask is running...\r\n"); + + TachoEnableIntr(&cap_p->ctrl); + ret = FFreeRTOSTimerStart(cap_p); + if (ret != FREERTOS_TIMER_TACHO_SUCCESS) + { + printf("Tacho start failed.\r\n"); + goto tacho_task_exit; + } + for (size_t i = 0; i < 5; i++) + { + printf("Get id %d CaptureCnt is :%d.\r\n", cap_p->ctrl.config.id, FFreeRTOSTachoGetCNT(cap_p)); + vTaskDelay(pdMS_TO_TICKS(1)); + } + /* disable tacho irq */ + TachoDisableIntr(&cap_p->ctrl); + FFreeRTOSTimerStop(cap_p); + FFreeRTOSTachoDeinit(cap_p); + +tacho_task_exit: + printf("TimerCapTask is over.\r\n"); + vTaskDelete(NULL); +} + +static void InitTask(void *pvParameters) +{ + BaseType_t xReturn = pdPASS; + /* init timers controller */ + + os_timer_ctrl = FFreeRTOSTimerInit(TIMER_INSTANCE_NUM, FTIMER_CYC_CMP, 2000000);/* 2000000 us = 2 s */ + if (os_timer_ctrl == NULL) + { + printf("*Timer init error.\r\n"); + goto timer_init_exit; + } + FTimerRegisterEvtCallback(&os_timer_ctrl->ctrl, FTIMER_EVENT_CYC_CMP, CycCmpIntrHandler); + FTimerRegisterEvtCallback(&os_timer_ctrl->ctrl, FTIMER_EVENT_ONCE_CMP, OnceCmpIntrHandler); + FTimerRegisterEvtCallback(&os_timer_ctrl->ctrl, FTIMER_EVENT_ROLL_OVER, RolloverIntrHandler); + + /*init mode: FTIMER_WORK_MODE_CAPTURE or FTIMER_WORK_MODE_TACHO */ + os_tacho_ctrl = FFreeRTOSTachoInit(TACHO_INSTANCE_NUM, FTIMER_WORK_MODE_TACHO); + if (os_timer_ctrl == NULL) + { + printf("*Tacho init error.\r\n"); + goto timer_init_exit; + } + FTimerRegisterEvtCallback(&os_tacho_ctrl->ctrl, FTACHO_EVENT_OVER, TachOverIntrHandler); + FTimerRegisterEvtCallback(&os_tacho_ctrl->ctrl, FTACHO_EVENT_UNDER, TachUnderIntrHandler); + FTimerRegisterEvtCallback(&os_tacho_ctrl->ctrl, FTACHO_EVENT_CAPTURE, CapIntrHandler); + + taskENTER_CRITICAL(); //进入临界区 + xReturn = xTaskCreate((TaskFunction_t)TimerTask, /* 任务入口函数 */ + (const char *)"TimerTask", /* 任务名字 */ + (uint16_t)1024, /* 任务栈大小 */ + (void *)os_timer_ctrl, /* 任务入口函数参数 */ + (UBaseType_t)configMAX_PRIORITIES - 1, /* 任务的优先级 */ + (TaskHandle_t *)&timer_handle); /* 任务控制 */ + FASSERT_MSG(xReturn == pdPASS, "TimerTask create is failed."); + + xReturn = xTaskCreate((TaskFunction_t)TachoTask, /* 任务入口函数 */ + (const char *)"TachoTask",/* 任务名字 */ + (uint16_t)1024, /* 任务栈大小 */ + (void *)os_tacho_ctrl,/* 任务入口函数参数 */ + (UBaseType_t)configMAX_PRIORITIES - 2, /* 任务的优先级 */ + (TaskHandle_t *)&tacho_handle); /* 任务控制 */ + FASSERT_MSG(xReturn == pdPASS, "TachoTask create is failed."); + + taskEXIT_CRITICAL(); //退出临界区 +timer_init_exit: + vTaskDelete(NULL); +} + +BaseType_t FFreeRTOSTimerTachoCreate(void) +{ + BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为 pdPASS */ + + taskENTER_CRITICAL(); //进入临界区 + + /* init timers controller */ + + xReturn = xTaskCreate((TaskFunction_t)InitTask, /* 任务入口函数 */ + (const char *)"InitTask",/* 任务名字 */ + (uint16_t)1024, /* 任务栈大小 */ + (void *)NULL,/* 任务入口函数参数 */ + (UBaseType_t)configMAX_PRIORITIES - 1, /* 任务的优先级 */ + (TaskHandle_t *)&init_handle); /* 任务控制 */ + FASSERT_MSG(xReturn == pdPASS, "TachoTask create is failed."); + + taskEXIT_CRITICAL(); //退出临界区 + + return xReturn; +} + diff --git a/example/peripheral/usb/cherryusb_host/configs/e2000d_aarch32_eg_configs b/example/peripheral/usb/cherryusb_host/configs/e2000d_aarch32_eg_configs index 6c949218..c52ecc84 100644 --- a/example/peripheral/usb/cherryusb_host/configs/e2000d_aarch32_eg_configs +++ b/example/peripheral/usb/cherryusb_host/configs/e2000d_aarch32_eg_configs @@ -68,6 +68,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -112,6 +113,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -148,6 +158,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -169,12 +180,6 @@ CONFIG_FREERTOS_USE_FSPIM=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -186,14 +191,32 @@ CONFIG_FREERTOS_USE_FSPIM=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -226,4 +249,27 @@ CONFIG_CHERRY_USB_HOST_VEDIO=y CONFIG_CHERRY_USB_HOST_CDC=y CONFIG_CHERRY_USB_HOST_RNDIS_WIRELESS=y # end of CherryUSB Configuration -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/usb/cherryusb_host/configs/e2000d_aarch64_eg_configs b/example/peripheral/usb/cherryusb_host/configs/e2000d_aarch64_eg_configs index 5ee6831f..899e03a8 100644 --- a/example/peripheral/usb/cherryusb_host/configs/e2000d_aarch64_eg_configs +++ b/example/peripheral/usb/cherryusb_host/configs/e2000d_aarch64_eg_configs @@ -68,6 +68,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -108,6 +109,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -144,6 +154,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -165,12 +176,6 @@ CONFIG_FREERTOS_USE_FSPIM=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -182,14 +187,32 @@ CONFIG_FREERTOS_USE_FSPIM=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -222,4 +245,27 @@ CONFIG_CHERRY_USB_HOST_VEDIO=y CONFIG_CHERRY_USB_HOST_CDC=y CONFIG_CHERRY_USB_HOST_RNDIS_WIRELESS=y # end of CherryUSB Configuration -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/usb/cherryusb_host/configs/e2000s_aarch32_eg_configs b/example/peripheral/usb/cherryusb_host/configs/e2000s_aarch32_eg_configs index ecbd00e8..0ed600da 100644 --- a/example/peripheral/usb/cherryusb_host/configs/e2000s_aarch32_eg_configs +++ b/example/peripheral/usb/cherryusb_host/configs/e2000s_aarch32_eg_configs @@ -68,6 +68,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -112,6 +113,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -148,6 +158,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -169,12 +180,6 @@ CONFIG_FREERTOS_USE_FSPIM=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -186,14 +191,32 @@ CONFIG_FREERTOS_USE_FSPIM=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -226,4 +249,27 @@ CONFIG_CHERRY_USB_HOST_VEDIO=y CONFIG_CHERRY_USB_HOST_CDC=y CONFIG_CHERRY_USB_HOST_RNDIS_WIRELESS=y # end of CherryUSB Configuration -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/usb/cherryusb_host/configs/e2000s_aarch64_eg_configs b/example/peripheral/usb/cherryusb_host/configs/e2000s_aarch64_eg_configs index f1823f78..45563421 100644 --- a/example/peripheral/usb/cherryusb_host/configs/e2000s_aarch64_eg_configs +++ b/example/peripheral/usb/cherryusb_host/configs/e2000s_aarch64_eg_configs @@ -68,6 +68,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -108,6 +109,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -144,6 +154,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -165,12 +176,6 @@ CONFIG_FREERTOS_USE_FSPIM=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -182,14 +187,32 @@ CONFIG_FREERTOS_USE_FSPIM=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -222,4 +245,27 @@ CONFIG_CHERRY_USB_HOST_VEDIO=y CONFIG_CHERRY_USB_HOST_CDC=y CONFIG_CHERRY_USB_HOST_RNDIS_WIRELESS=y # end of CherryUSB Configuration -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/usb/cherryusb_host/inc/usb_host.h b/example/peripheral/usb/cherryusb_host/inc/usb_host.h index 48edc36a..5888559c 100644 --- a/example/peripheral/usb/cherryusb_host/inc/usb_host.h +++ b/example/peripheral/usb/cherryusb_host/inc/usb_host.h @@ -1,27 +1,28 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: usb_host.h * Date: 2022-07-19 09:26:25 * LastEditTime: 2022-07-19 09:26:25 - * Description:  This files is for - * - * Modify History: + * Description:  This file is for the usb host definition. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2022/9/20 init commit */ -#ifndef EXAMPLE_USB_HOST_H -#define EXAMPLE_USB_HOST_H +#ifndef USB_HOST_H +#define USB_HOST_H #ifdef __cplusplus extern "C" diff --git a/example/peripheral/usb/cherryusb_host/main.c b/example/peripheral/usb/cherryusb_host/main.c index c188a8dd..b1c1a3a5 100644 --- a/example/peripheral/usb/cherryusb_host/main.c +++ b/example/peripheral/usb/cherryusb_host/main.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: main.c * Date: 2022-06-17 08:17:59 * LastEditTime: 2022-06-17 08:17:59 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description:  This file is for cherry-usb test main entry. + * + * Modify History: + * Ver   Who         Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2022/10/19 init commit */ #include "shell.h" @@ -30,13 +31,15 @@ int main(void) BaseType_t ret; ret = LSUserShellTask(); - if(ret != pdPASS) + if (ret != pdPASS) + { goto FAIL_EXIT; + } - vTaskStartScheduler(); /* 启动任务,开启调度 */ + vTaskStartScheduler(); /* 启动任务,开启调度 */ while (1); /* 正常不会执行到这里 */ - + FAIL_EXIT: - printf("failed 0x%x \r\n", ret); + printf("Failed,the ret value is 0x%x. \r\n", ret); return 0; } diff --git a/example/peripheral/usb/cherryusb_host/sdkconfig b/example/peripheral/usb/cherryusb_host/sdkconfig index f1823f78..45563421 100644 --- a/example/peripheral/usb/cherryusb_host/sdkconfig +++ b/example/peripheral/usb/cherryusb_host/sdkconfig @@ -68,6 +68,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -108,6 +109,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -144,6 +154,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -165,12 +176,6 @@ CONFIG_FREERTOS_USE_FSPIM=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -182,14 +187,32 @@ CONFIG_FREERTOS_USE_FSPIM=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -222,4 +245,27 @@ CONFIG_CHERRY_USB_HOST_VEDIO=y CONFIG_CHERRY_USB_HOST_CDC=y CONFIG_CHERRY_USB_HOST_RNDIS_WIRELESS=y # end of CherryUSB Configuration -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/usb/cherryusb_host/sdkconfig.h b/example/peripheral/usb/cherryusb_host/sdkconfig.h index ef67d74f..ba85cf18 100644 --- a/example/peripheral/usb/cherryusb_host/sdkconfig.h +++ b/example/peripheral/usb/cherryusb_host/sdkconfig.h @@ -63,6 +63,7 @@ /* CONFIG_USE_ADC is not set */ /* CONFIG_USE_PWM is not set */ /* CONFIG_USE_IPC is not set */ +/* CONFIG_USE_MEDIA is not set */ /* end of Components Configuration */ #define CONFIG_USE_NEW_LIBC /* end of Standalone Setting */ @@ -99,6 +100,12 @@ /* Compiler Options */ +/* Cross-Compiler Setting */ + +#define CONFIG_GCC_OPTIMIZE_LEVEL 0 +/* CONFIG_USE_EXT_COMPILER is not set */ +/* CONFIG_USE_KLIN_SYS is not set */ +/* end of Cross-Compiler Setting */ #define CONFIG_OUTPUT_BINARY /* end of Compiler Options */ /* end of Building Option */ @@ -128,6 +135,7 @@ /* Freertos Eth Drivers */ /* CONFIG_FREERTOS_USE_XMAC is not set */ +/* CONFIG_FREERTOS_USE_GMAC is not set */ /* end of Freertos Eth Drivers */ /* Freertos Gpio Drivers */ @@ -146,11 +154,6 @@ /* CONFIG_FREERTOS_USE_FGDMA is not set */ /* end of Freertos DMA Drivers */ -/* Freertos MMC Drivers */ - -/* CONFIG_FREERTOS_USE_FSDIO is not set */ -/* end of Freertos MMC Drivers */ - /* Freertos Adc Drivers */ /* CONFIG_FREERTOS_USE_ADC is not set */ @@ -160,13 +163,28 @@ /* CONFIG_FREERTOS_USE_CAN is not set */ /* end of Freertos Can Drivers */ + +/* Freertos I2c Drivers */ + +/* CONFIG_FREERTOS_USE_I2C is not set */ +/* end of Freertos I2c Drivers */ + +/* Freertos Mio Drivers */ + +/* CONFIG_FREERTOS_USE_MIO is not set */ +/* end of Freertos Mio Drivers */ + +/* Freertos Timer Drivers */ + +/* CONFIG_FREERTOS_USE_TIMER is not set */ +/* end of Freertos Timer Drivers */ /* end of Component Configuration */ -/* FreeRTOS Setting */ +/* Third-Party Configuration */ /* CONFIG_USE_LWIP is not set */ #define CONFIG_USE_BACKTRACE -/* CONFIG_USE_FATFS is not set */ +/* CONFIG_USE_FATFS_0_1_4 is not set */ /* CONFIG_USE_SFUD is not set */ /* CONFIG_USE_SPIFFS is not set */ /* CONFIG_USE_AMP is not set */ @@ -196,6 +214,28 @@ #define CONFIG_CHERRY_USB_HOST_CDC #define CONFIG_CHERRY_USB_HOST_RNDIS_WIRELESS /* end of CherryUSB Configuration */ -/* end of FreeRTOS Setting */ +/* end of Third-Party Configuration */ + +/* Kernel Configuration */ + +#define CONFIG_FREERTOS_OPTIMIZED_SCHEDULER +#define CONFIG_FREERTOS_HZ 1000 +#define CONFIG_FREERTOS_MAX_PRIORITIES 32 +#define CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES 13 +#define CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES 11 +#define CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS 1 +#define CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE 1024 +#define CONFIG_FREERTOS_MAX_TASK_NAME_LEN 32 +#define CONFIG_FREERTOS_TIMER_TASK_PRIORITY 1 +#define CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH 2048 +#define CONFIG_FREERTOS_TIMER_QUEUE_LENGTH 10 +#define CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE 0 +#define CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS +#define CONFIG_FREERTOS_USE_TRACE_FACILITY +#define CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS +/* CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set */ +#define CONFIG_FREERTOS_TOTAL_HEAP_SIZE 10240 +#define CONFIG_FREERTOS_TASK_FPU_SUPPORT 1 +/* end of Kernel Configuration */ #endif diff --git a/example/peripheral/usb/cherryusb_host/src/cmd_usb.c b/example/peripheral/usb/cherryusb_host/src/cmd_usb.c index f0faed08..60d5a6f8 100644 --- a/example/peripheral/usb/cherryusb_host/src/cmd_usb.c +++ b/example/peripheral/usb/cherryusb_host/src/cmd_usb.c @@ -1,22 +1,22 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: cmd_usb.c * Date: 2022-09-19 14:34:44 * LastEditTime: 2022-09-19 14:34:45 - * Description:  This files is for - * - * Modify History: + * Description:  This file is for USB shell command. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- * 1.0 zhugengyu 2022/9/20 init commit diff --git a/example/peripheral/usb/cherryusb_host/src/usb_disk.c b/example/peripheral/usb/cherryusb_host/src/usb_disk.c index da825a82..7a76663b 100644 --- a/example/peripheral/usb/cherryusb_host/src/usb_disk.c +++ b/example/peripheral/usb/cherryusb_host/src/usb_disk.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: usb_disk.c * Date: 2022-09-23 08:24:09 * LastEditTime: 2022-09-23 08:24:10 - * Description:  This files is for - * - * Modify History: - * Ver   Who        Date         Changes + * Description:  This file is for the usb disk functions. + * + * Modify History: + * Ver   Who         Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2022/10/19 init commit */ /***************************** Include Files *********************************/ #include @@ -51,7 +52,7 @@ /*****************************************************************************/ -static void UsbMscTask(void * args) +static void UsbMscTask(void *args) { int ret; struct usbh_msc *msc_class; @@ -62,9 +63,9 @@ static void UsbMscTask(void * args) while (TRUE) { msc_class = (struct usbh_msc *)usbh_find_class_instance("/dev/sda"); - if (msc_class == NULL) + if (msc_class == NULL) { - USB_LOG_RAW("do not find /dev/sda\r\n"); + USB_LOG_RAW("Do not find /dev/sda. \r\n"); goto err_exit; } @@ -76,29 +77,29 @@ static void UsbMscTask(void * args) } ret = usbh_msc_scsi_write10(msc_class, 0, wr_table, 1); - if (ret < 0) + if (ret < 0) { - USB_LOG_ERR("scsi_write10 error,ret:%d\r\n", ret); + USB_LOG_ERR("Error in scsi_write10 error, ret:%d", ret); goto err_exit; } /* get the partition table */ ret = usbh_msc_scsi_read10(msc_class, 0, rd_table, 1); - if (ret < 0) + if (ret < 0) { - USB_LOG_RAW("scsi_read10 error,ret:%d\r\n", ret); + USB_LOG_RAW("Error in scsi_read10, ret:%d", ret); goto err_exit; } - + /* check if read table == write table */ if (0 != memcmp(wr_table, rd_table, sizeof(rd_table))) { - USB_LOG_ERR("check read and write failed !!!\r\n"); + USB_LOG_ERR("Failed to check read and write.\r\n"); goto err_exit; } else { - printf("[%d] disk read and write successful\r\n", loop++); + printf("[%d] disk read and write successfully.\r\n", loop++); } vTaskDelay(10); @@ -114,15 +115,15 @@ BaseType_t FFreeRTOSRunUsbDisk(void) taskENTER_CRITICAL(); /* no schedule when create task */ - ret = xTaskCreate((TaskFunction_t )UsbMscTask, - (const char* )"UsbMscTask", - (uint16_t )2048, - NULL, - (UBaseType_t )configMAX_PRIORITIES - 1, - NULL); + ret = xTaskCreate((TaskFunction_t)UsbMscTask, + (const char *)"UsbMscTask", + (uint16_t)2048, + NULL, + (UBaseType_t)configMAX_PRIORITIES - 1, + NULL); FASSERT_MSG(pdPASS == ret, "create task failed"); taskEXIT_CRITICAL(); /* allow schedule since task created */ - return ret; + return ret; } diff --git a/example/peripheral/usb/cherryusb_host/src/usb_host.c b/example/peripheral/usb/cherryusb_host/src/usb_host.c index f01654ea..6ef0c007 100644 --- a/example/peripheral/usb/cherryusb_host/src/usb_host.c +++ b/example/peripheral/usb/cherryusb_host/src/usb_host.c @@ -1,22 +1,22 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: usb_host.c * Date: 2022-07-22 13:57:42 * LastEditTime: 2022-07-22 13:57:43 - * Description:  This files is for - * - * Modify History: + * Description:  This file is for the usb host functions. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- * 1.0 zhugengyu 2022/9/20 init commit @@ -73,9 +73,9 @@ static void UsbHcSetupInterrupt(void) InterruptSetPriority(irq_num, irq_priority); /* register intr callback */ - InterruptInstall(irq_num, - UsbHcInterrruptHandler, - NULL, + InterruptInstall(irq_num, + UsbHcInterrruptHandler, + NULL, NULL); /* enable irq */ @@ -110,17 +110,21 @@ void *usb_hc_malloc(size_t size) void *usb_hc_malloc_align(size_t align, size_t size) { void *result = FMempMallocAlign(&memp, size, align); - + if (result) + { memset(result, 0U, size); + } return result; } void usb_hc_free(void *ptr) { - if (NULL != ptr) - FMempFree(&memp, ptr); + if (NULL != ptr) + { + FMempFree(&memp, ptr); + } } void usb_assert(const char *filename, int linenum) @@ -134,15 +138,15 @@ void usb_hc_dcache_invalidate(void *addr, unsigned long len) } /*****************************************/ -static void UsbInitTask(void * args) +static void UsbInitTask(void *args) { - if (0 == usbh_initialize()) + if (0 == usbh_initialize()) { - printf("init cherryusb host success !!! input 'usb lsusb -t' to see devices\r\n"); + printf("Init cherryusb host successfully.put 'usb lsusb -t' to see devices.\r\n"); } else { - FUSB_ERROR("init cherryusb host failed !!!"); + FUSB_ERROR("Init cherryusb host failed."); } vTaskDelete(NULL); @@ -154,12 +158,12 @@ BaseType_t FFreeRTOSInitUsb(void) taskENTER_CRITICAL(); /* no schedule when create task */ - ret = xTaskCreate((TaskFunction_t )UsbInitTask, - (const char* )"UsbInitTask", - (uint16_t )2048, - NULL, - (UBaseType_t )configMAX_PRIORITIES - 1, - NULL); + ret = xTaskCreate((TaskFunction_t)UsbInitTask, + (const char *)"UsbInitTask", + (uint16_t)2048, + NULL, + (UBaseType_t)configMAX_PRIORITIES - 1, + NULL); FASSERT_MSG(pdPASS == ret, "create task failed"); taskEXIT_CRITICAL(); /* allow schedule since task created */ diff --git a/example/peripheral/usb/cherryusb_host/src/usb_input.c b/example/peripheral/usb/cherryusb_host/src/usb_input.c index a96a2c00..04e06d99 100644 --- a/example/peripheral/usb/cherryusb_host/src/usb_input.c +++ b/example/peripheral/usb/cherryusb_host/src/usb_input.c @@ -1,22 +1,22 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: usb_input.c * Date: 2022-07-22 13:57:42 * LastEditTime: 2022-07-22 13:57:43 - * Description:  This files is for - * - * Modify History: + * Description:  This file is for the usb input functions. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- * 1.0 zhugengyu 2022/9/20 init commit @@ -199,10 +199,12 @@ static void UsbMouseHandleInput(struct usb_hid_mouse_report *input) /* look up new key in previous keys */ static inline boolean FindKeyInPrevInput(const struct usb_hid_kbd_report *report, u8 keycode) { - for(u8 i=0; i < 6; i++) + for (u8 i = 0; i < 6; i++) { - if (report->key[i] == keycode) + if (report->key[i] == keycode) + { return TRUE; + } } return FALSE; @@ -257,7 +259,7 @@ static void UsbHidCallback(void *arg, int nbytes) intf_protocol = UsbInputGetInterfaceProtocol(hid_class); if (HID_PROTOCOL_KEYBOARD == intf_protocol) /* handle input from keyboard */ { - if (nbytes < (int)sizeof(struct usb_hid_kbd_report)) + if (nbytes < (int)sizeof(struct usb_hid_kbd_report)) { FUSB_ERROR("nbytes = %d", nbytes); } @@ -268,24 +270,24 @@ static void UsbHidCallback(void *arg, int nbytes) } else if (HID_PROTOCOL_MOUSE == intf_protocol) /* handle input from mouse */ { - if (nbytes < (int)sizeof(struct usb_hid_mouse_report)) + if (nbytes < (int)sizeof(struct usb_hid_mouse_report)) { FUSB_ERROR("nbytes = %d", nbytes); } else { - UsbMouseHandleInput((struct usb_hid_mouse_report *)hid_buffer); + UsbMouseHandleInput((struct usb_hid_mouse_report *)hid_buffer); } } else { - FUSB_ERROR("unsupported hid interface %d", intf_protocol); + FUSB_ERROR("Unsupported hid interface %d", intf_protocol); } - + usbh_submit_urb(&hid_intin_urb); /* ask for next inputs */ } -static void UsbInputTask(void * args) +static void UsbInputTask(void *args) { int ret; struct usbh_hid *hid_class; @@ -294,9 +296,9 @@ static void UsbInputTask(void * args) while (TRUE) { hid_class = (struct usbh_hid *)usbh_find_class_instance("/dev/input0"); - if (hid_class == NULL) + if (hid_class == NULL) { - FUSB_ERROR("do not find /dev/input0"); + FUSB_ERROR("Do not find /dev/input0."); goto err_exit; } @@ -316,15 +318,15 @@ BaseType_t FFreeRTOSRunUsbInput(void) taskENTER_CRITICAL(); /* no schedule when create task */ - ret = xTaskCreate((TaskFunction_t )UsbInputTask, - (const char* )"UsbInputTask", - (uint16_t )2048, - NULL, - (UBaseType_t )configMAX_PRIORITIES - 1, - NULL); + ret = xTaskCreate((TaskFunction_t)UsbInputTask, + (const char *)"UsbInputTask", + (uint16_t)2048, + NULL, + (UBaseType_t)configMAX_PRIORITIES - 1, + NULL); FASSERT_MSG(pdPASS == ret, "create task failed"); taskEXIT_CRITICAL(); /* allow schedule since task created */ - return ret; + return ret; } \ No newline at end of file diff --git a/example/peripheral/wdt/configs/d2000_aarch32_eg_configs b/example/peripheral/wdt/configs/d2000_aarch32_eg_configs index 76098bcb..150e30fe 100644 --- a/example/peripheral/wdt/configs/d2000_aarch32_eg_configs +++ b/example/peripheral/wdt/configs/d2000_aarch32_eg_configs @@ -74,6 +74,7 @@ CONFIG_USE_FWDT=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -118,6 +119,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -154,6 +164,7 @@ CONFIG_FREERTOS_USE_WDT=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -175,12 +186,6 @@ CONFIG_FREERTOS_USE_WDT=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -192,14 +197,32 @@ CONFIG_FREERTOS_USE_WDT=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -217,4 +240,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/wdt/configs/d2000_aarch64_eg_configs b/example/peripheral/wdt/configs/d2000_aarch64_eg_configs index 1d2d7a81..faf09823 100644 --- a/example/peripheral/wdt/configs/d2000_aarch64_eg_configs +++ b/example/peripheral/wdt/configs/d2000_aarch64_eg_configs @@ -74,6 +74,7 @@ CONFIG_USE_FWDT=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -114,6 +115,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -150,6 +160,7 @@ CONFIG_FREERTOS_USE_WDT=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -171,12 +182,6 @@ CONFIG_FREERTOS_USE_WDT=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -188,14 +193,32 @@ CONFIG_FREERTOS_USE_WDT=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -213,4 +236,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/wdt/configs/e2000d_aarch32_eg_configs b/example/peripheral/wdt/configs/e2000d_aarch32_eg_configs index bb8130e2..2b5328e4 100644 --- a/example/peripheral/wdt/configs/e2000d_aarch32_eg_configs +++ b/example/peripheral/wdt/configs/e2000d_aarch32_eg_configs @@ -74,6 +74,7 @@ CONFIG_USE_FWDT=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -118,6 +119,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -154,6 +164,7 @@ CONFIG_FREERTOS_USE_WDT=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -175,12 +186,6 @@ CONFIG_FREERTOS_USE_WDT=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -192,14 +197,32 @@ CONFIG_FREERTOS_USE_WDT=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -217,4 +240,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/wdt/configs/e2000d_aarch64_eg_configs b/example/peripheral/wdt/configs/e2000d_aarch64_eg_configs index 5b6d679c..eac02dee 100644 --- a/example/peripheral/wdt/configs/e2000d_aarch64_eg_configs +++ b/example/peripheral/wdt/configs/e2000d_aarch64_eg_configs @@ -74,6 +74,7 @@ CONFIG_USE_FWDT=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -114,6 +115,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -150,6 +160,7 @@ CONFIG_FREERTOS_USE_WDT=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -171,12 +182,6 @@ CONFIG_FREERTOS_USE_WDT=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -188,14 +193,32 @@ CONFIG_FREERTOS_USE_WDT=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -213,4 +236,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/wdt/configs/e2000q_aarch32_eg_configs b/example/peripheral/wdt/configs/e2000q_aarch32_eg_configs index 186928ad..14b06ad5 100644 --- a/example/peripheral/wdt/configs/e2000q_aarch32_eg_configs +++ b/example/peripheral/wdt/configs/e2000q_aarch32_eg_configs @@ -74,6 +74,7 @@ CONFIG_USE_FWDT=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -118,6 +119,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -154,6 +164,7 @@ CONFIG_FREERTOS_USE_WDT=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -175,12 +186,6 @@ CONFIG_FREERTOS_USE_WDT=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -192,14 +197,32 @@ CONFIG_FREERTOS_USE_WDT=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -217,4 +240,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/wdt/configs/e2000q_aarch64_eg_configs b/example/peripheral/wdt/configs/e2000q_aarch64_eg_configs index bfebe8b9..414a9424 100644 --- a/example/peripheral/wdt/configs/e2000q_aarch64_eg_configs +++ b/example/peripheral/wdt/configs/e2000q_aarch64_eg_configs @@ -74,6 +74,7 @@ CONFIG_USE_FWDT=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -114,6 +115,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -150,6 +160,7 @@ CONFIG_FREERTOS_USE_WDT=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -171,12 +182,6 @@ CONFIG_FREERTOS_USE_WDT=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -188,14 +193,32 @@ CONFIG_FREERTOS_USE_WDT=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -213,4 +236,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/wdt/configs/ft2004_aarch32_eg_configs b/example/peripheral/wdt/configs/ft2004_aarch32_eg_configs index 0c4e6a66..5cee0111 100644 --- a/example/peripheral/wdt/configs/ft2004_aarch32_eg_configs +++ b/example/peripheral/wdt/configs/ft2004_aarch32_eg_configs @@ -74,6 +74,7 @@ CONFIG_USE_FWDT=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -118,6 +119,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -154,6 +164,7 @@ CONFIG_FREERTOS_USE_WDT=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -175,12 +186,6 @@ CONFIG_FREERTOS_USE_WDT=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -192,14 +197,32 @@ CONFIG_FREERTOS_USE_WDT=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -217,4 +240,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/wdt/configs/ft2004_aarch64_eg_configs b/example/peripheral/wdt/configs/ft2004_aarch64_eg_configs index d5e9c66c..ff15bf21 100644 --- a/example/peripheral/wdt/configs/ft2004_aarch64_eg_configs +++ b/example/peripheral/wdt/configs/ft2004_aarch64_eg_configs @@ -74,6 +74,7 @@ CONFIG_USE_FWDT=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -114,6 +115,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -150,6 +160,7 @@ CONFIG_FREERTOS_USE_WDT=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -171,12 +182,6 @@ CONFIG_FREERTOS_USE_WDT=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -188,14 +193,32 @@ CONFIG_FREERTOS_USE_WDT=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -213,4 +236,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/wdt/inc/wdt_example.h b/example/peripheral/wdt/inc/wdt_example.h index cc1e293f..ed1e77ba 100644 --- a/example/peripheral/wdt/inc/wdt_example.h +++ b/example/peripheral/wdt/inc/wdt_example.h @@ -1,30 +1,41 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: wdt_example.h * Date: 2022-06-17 10:42:40 * LastEditTime: 2022-06-17 10:42:40 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for wdt test example function declarations. + * + * Modify History: + * Ver    Who          Date          Changes + * -----  ------      --------     -------------------------------------- + * 1.0 wangxiaodong 2022/8/9 first release */ #ifndef WDT_EXAMPLE_H #define WDT_EXAMPLE_H +#ifdef __cplusplus +extern "C" +{ +#endif + /* wdt read and write test */ BaseType_t FFreeRTOSWdtCreate(u32 id); + +#ifdef __cplusplus +} +#endif + #endif // ! \ No newline at end of file diff --git a/example/peripheral/wdt/main.c b/example/peripheral/wdt/main.c index 1ea241e5..2dd2538b 100644 --- a/example/peripheral/wdt/main.c +++ b/example/peripheral/wdt/main.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: main.c * Date: 2022-06-17 08:17:59 * LastEditTime: 2022-06-17 08:17:59 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for wdt test main entry. + * + * Modify History: + * Ver    Who          Date          Changes + * -----  ------      --------     -------------------------------------- + * 1.0 wangxiaodong 2022/8/9 first release */ #include "shell.h" @@ -31,17 +32,21 @@ int main(void) BaseType_t ret; ret = FFreeRTOSWdtCreate(0); - if(ret != pdPASS) + if (ret != pdPASS) + { goto FAIL_EXIT; + } ret = LSUserShellTask() ; - if(ret != pdPASS) + if (ret != pdPASS) + { goto FAIL_EXIT; + } - vTaskStartScheduler(); /* 启动任务,开启调度 */ + vTaskStartScheduler(); /* 启动任务,开启调度 */ while (1); /* 正常不会执行到这里 */ - + FAIL_EXIT: - printf("failed 0x%x \r\n", ret); + printf("Failed,the ret value is 0x%x. \r\n", ret); return 0; } diff --git a/example/peripheral/wdt/sdkconfig b/example/peripheral/wdt/sdkconfig index 5b6d679c..414a9424 100644 --- a/example/peripheral/wdt/sdkconfig +++ b/example/peripheral/wdt/sdkconfig @@ -2,7 +2,7 @@ # # Freertos Configuration # -CONFIG_TARGET_NAME="e2000d_freertos_a64" +CONFIG_TARGET_NAME="e2000q_freertos_a64" # end of Freertos Configuration # @@ -26,8 +26,8 @@ CONFIG_USE_SYS_TICK=y # # CONFIG_TARGET_F2000_4 is not set # CONFIG_TARGET_D2000 is not set -# CONFIG_TARGET_E2000Q is not set -CONFIG_TARGET_E2000D=y +CONFIG_TARGET_E2000Q=y +# CONFIG_TARGET_E2000D is not set # CONFIG_TARGET_E2000S is not set CONFIG_TARGET_E2000=y CONFIG_DEFAULT_DEBUG_PRINT_UART1=y @@ -74,6 +74,7 @@ CONFIG_USE_FWDT=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -114,6 +115,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -150,6 +160,7 @@ CONFIG_FREERTOS_USE_WDT=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -171,12 +182,6 @@ CONFIG_FREERTOS_USE_WDT=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -188,14 +193,32 @@ CONFIG_FREERTOS_USE_WDT=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -210,7 +233,30 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set # end of Letter Shell Configuration -CONFIG_USE_TLSF=y +# CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/peripheral/wdt/sdkconfig.h b/example/peripheral/wdt/sdkconfig.h index 1c8b59bb..f8dd6b5a 100644 --- a/example/peripheral/wdt/sdkconfig.h +++ b/example/peripheral/wdt/sdkconfig.h @@ -3,7 +3,7 @@ /* Freertos Configuration */ -#define CONFIG_TARGET_NAME "e2000d_freertos_a64" +#define CONFIG_TARGET_NAME "e2000q_freertos_a64" /* end of Freertos Configuration */ /* Standalone Setting */ @@ -24,8 +24,8 @@ /* CONFIG_TARGET_F2000_4 is not set */ /* CONFIG_TARGET_D2000 is not set */ -/* CONFIG_TARGET_E2000Q is not set */ -#define CONFIG_TARGET_E2000D +#define CONFIG_TARGET_E2000Q +/* CONFIG_TARGET_E2000D is not set */ /* CONFIG_TARGET_E2000S is not set */ #define CONFIG_TARGET_E2000 #define CONFIG_DEFAULT_DEBUG_PRINT_UART1 @@ -67,6 +67,7 @@ /* CONFIG_USE_ADC is not set */ /* CONFIG_USE_PWM is not set */ /* CONFIG_USE_IPC is not set */ +/* CONFIG_USE_MEDIA is not set */ /* end of Components Configuration */ #define CONFIG_USE_NEW_LIBC /* end of Standalone Setting */ @@ -103,6 +104,12 @@ /* Compiler Options */ +/* Cross-Compiler Setting */ + +#define CONFIG_GCC_OPTIMIZE_LEVEL 0 +/* CONFIG_USE_EXT_COMPILER is not set */ +/* CONFIG_USE_KLIN_SYS is not set */ +/* end of Cross-Compiler Setting */ #define CONFIG_OUTPUT_BINARY /* end of Compiler Options */ /* end of Building Option */ @@ -132,6 +139,7 @@ /* Freertos Eth Drivers */ /* CONFIG_FREERTOS_USE_XMAC is not set */ +/* CONFIG_FREERTOS_USE_GMAC is not set */ /* end of Freertos Eth Drivers */ /* Freertos Gpio Drivers */ @@ -150,11 +158,6 @@ /* CONFIG_FREERTOS_USE_FGDMA is not set */ /* end of Freertos DMA Drivers */ -/* Freertos MMC Drivers */ - -/* CONFIG_FREERTOS_USE_FSDIO is not set */ -/* end of Freertos MMC Drivers */ - /* Freertos Adc Drivers */ /* CONFIG_FREERTOS_USE_ADC is not set */ @@ -164,13 +167,28 @@ /* CONFIG_FREERTOS_USE_CAN is not set */ /* end of Freertos Can Drivers */ + +/* Freertos I2c Drivers */ + +/* CONFIG_FREERTOS_USE_I2C is not set */ +/* end of Freertos I2c Drivers */ + +/* Freertos Mio Drivers */ + +/* CONFIG_FREERTOS_USE_MIO is not set */ +/* end of Freertos Mio Drivers */ + +/* Freertos Timer Drivers */ + +/* CONFIG_FREERTOS_USE_TIMER is not set */ +/* end of Freertos Timer Drivers */ /* end of Component Configuration */ -/* FreeRTOS Setting */ +/* Third-Party Configuration */ /* CONFIG_USE_LWIP is not set */ #define CONFIG_USE_BACKTRACE -/* CONFIG_USE_FATFS is not set */ +/* CONFIG_USE_FATFS_0_1_4 is not set */ /* CONFIG_USE_SFUD is not set */ /* CONFIG_USE_SPIFFS is not set */ /* CONFIG_USE_AMP is not set */ @@ -183,9 +201,31 @@ /* CONFIG_DEFAULT_LETTER_SHELL_USE_UART0 is not set */ /* CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set */ /* end of Letter Shell Configuration */ -#define CONFIG_USE_TLSF +/* CONFIG_USE_TLSF is not set */ /* CONFIG_USE_SDMMC_CMD is not set */ /* CONFIG_USE_CHERRY_USB is not set */ -/* end of FreeRTOS Setting */ +/* end of Third-Party Configuration */ + +/* Kernel Configuration */ + +#define CONFIG_FREERTOS_OPTIMIZED_SCHEDULER +#define CONFIG_FREERTOS_HZ 1000 +#define CONFIG_FREERTOS_MAX_PRIORITIES 32 +#define CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES 13 +#define CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES 11 +#define CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS 1 +#define CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE 1024 +#define CONFIG_FREERTOS_MAX_TASK_NAME_LEN 32 +#define CONFIG_FREERTOS_TIMER_TASK_PRIORITY 1 +#define CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH 2048 +#define CONFIG_FREERTOS_TIMER_QUEUE_LENGTH 10 +#define CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE 0 +#define CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS +#define CONFIG_FREERTOS_USE_TRACE_FACILITY +#define CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS +/* CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set */ +#define CONFIG_FREERTOS_TOTAL_HEAP_SIZE 10240 +#define CONFIG_FREERTOS_TASK_FPU_SUPPORT 1 +/* end of Kernel Configuration */ #endif diff --git a/example/peripheral/wdt/src/wdt_example.c b/example/peripheral/wdt/src/wdt_example.c index f76abfb2..9011e3ec 100644 --- a/example/peripheral/wdt/src/wdt_example.c +++ b/example/peripheral/wdt/src/wdt_example.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: wdt_example.c * Date: 2022-07-11 11:32:48 * LastEditTime: 2022-07-11 11:32:48 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for wdt test example functions. + * + * Modify History: + * Ver    Who          Date          Changes + * -----  ------      --------     -------------------------------------- + * 1.0 wangxiaodong 2022/8/9 first release */ #include #include "FreeRTOSConfig.h" @@ -33,14 +34,14 @@ #include "wdt_example.h" /* The periods assigned to the one-shot timers. */ -#define ONE_SHOT_TIMER_PERIOD ( pdMS_TO_TICKS( 15000UL ) ) -#define AUTO_RELOAD_TIMER_PERIOD ( pdMS_TO_TICKS( 1000UL ) ) +#define ONE_SHOT_TIMER_PERIOD ( pdMS_TO_TICKS( 15000UL ) ) +#define AUTO_RELOAD_TIMER_PERIOD ( pdMS_TO_TICKS( 1000UL ) ) /* watchdog timeout value in seconds */ #define WDT_TIMEOUT 4 /* watchdog feed period */ -#define WDT_FEED_PERIOD ( pdMS_TO_TICKS( 3000UL )) +#define WDT_FEED_PERIOD ( pdMS_TO_TICKS( 3000UL )) /* test task number */ #define READ_WRITE_TASK_NUM 2 @@ -57,275 +58,274 @@ static QueueHandle_t xQueue; static FFreeRTOSWdt *os_wdt_ctrl_p; -typedef struct +typedef struct { - u32 count; - FWdtCtrl *ctrl; + u32 count; + FWdtCtrl *ctrl; } FWdtQueueData; static void FFreeRTOSWdtDelete(FFreeRTOSWdt *os_wdt_p); static void FFreeRTOSWdtInterruptHandler(s32 vector, void *param) { - FASSERT(param != NULL); - static FWdtQueueData xSendStructure; + FASSERT(param != NULL); + static FWdtQueueData xSendStructure; - portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; - - xSendStructure.ctrl = (FWdtCtrl *)param; - xSendStructure.count++; + portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; - FWdtRefresh(xSendStructure.ctrl); + xSendStructure.ctrl = (FWdtCtrl *)param; + xSendStructure.count++; - printf("FFreeRTOSWdtInterruptHandler run count = %d\r\n", xSendStructure.count); + FWdtRefresh(xSendStructure.ctrl); - xQueueSendToBackFromISR(xQueue, &xSendStructure, &xHigherPriorityTaskWoken); + printf("FFreeRTOSWdtInterruptHandler has been run %d times \r\n", xSendStructure.count); - /* never call taskYIELD() form ISR! */ - portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); + xQueueSendToBackFromISR(xQueue, &xSendStructure, &xHigherPriorityTaskWoken); + + /* never call taskYIELD() form ISR! */ + portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); } static void FFreeRTOSWdtInitTask(void *pvParameters) { - /* The wdt_id to use is passed in via the parameter. - Cast this to a wdt_id pointer. */ - u32 wdt_id = (u32)(uintptr)pvParameters; - u32 timeout = WDT_TIMEOUT; - u32 cpu_id = 0; - - /* init wdt controller */ - os_wdt_ctrl_p = FFreeRTOSWdtInit(wdt_id); - if(os_wdt_ctrl_p == NULL) - { - printf("FFreeRTOSWdtInit failed!!!\n"); - goto wdt_init_exit; - } - /* set wdt timeout value */ - FFreeRTOSWdtControl(os_wdt_ctrl_p, FREERTOS_WDT_CTRL_SET_TIMEOUT, &timeout); - - /* start wdt controller */ - FFreeRTOSWdtControl(os_wdt_ctrl_p, FREERTOS_WDT_CTRL_START, NULL); - - /* set wdt timeout interrupt handler */ - FWdtCtrl *pctrl = &os_wdt_ctrl_p->wdt_ctrl; + /* The wdt_id to use is passed in via the parameter. + Cast this to a wdt_id pointer. */ + u32 wdt_id = (u32)(uintptr)pvParameters; + u32 timeout = WDT_TIMEOUT; + u32 cpu_id = 0; + + /* init wdt controller */ + os_wdt_ctrl_p = FFreeRTOSWdtInit(wdt_id); + if (os_wdt_ctrl_p == NULL) + { + printf("FFreeRTOSWdtInit failed.\n"); + goto wdt_init_exit; + } + /* set wdt timeout value */ + FFreeRTOSWdtControl(os_wdt_ctrl_p, FREERTOS_WDT_CTRL_SET_TIMEOUT, &timeout); + + /* start wdt controller */ + FFreeRTOSWdtControl(os_wdt_ctrl_p, FREERTOS_WDT_CTRL_START, NULL); + + /* set wdt timeout interrupt handler */ + FWdtCtrl *pctrl = &os_wdt_ctrl_p->wdt_ctrl; FWdtConfig *pconfig = &os_wdt_ctrl_p->wdt_ctrl.config; - GetCpuId(&cpu_id); - printf("cpu_id is %d \r\n", cpu_id); - InterruptSetTargetCpus(pconfig->irq_num, cpu_id); - /* interrupt init */ - InterruptSetPriority(pconfig->irq_num, pconfig->irq_prority); - InterruptInstall(pconfig->irq_num, FFreeRTOSWdtInterruptHandler, pctrl, pconfig->instance_name); - InterruptUmask(pconfig->irq_num); - - printf("FFreeRTOSWdtInitTask execute success !!!\r\n"); + GetCpuId(&cpu_id); + InterruptSetTargetCpus(pconfig->irq_num, cpu_id); + /* interrupt init */ + InterruptSetPriority(pconfig->irq_num, pconfig->irq_prority); + InterruptInstall(pconfig->irq_num, FFreeRTOSWdtInterruptHandler, pctrl, pconfig->instance_name); + InterruptUmask(pconfig->irq_num); + + printf("FFreeRTOSWdtInitTask execute successfully.\r\n"); for (int i = 0; i < READ_WRITE_TASK_NUM; i++) { xSemaphoreGive(xCountingSemaphore); } -wdt_init_exit: +wdt_init_exit: vTaskDelete(NULL); } static void FFreeRTOSWdtQueueReceiveTask(void) { - xSemaphoreTake(xCountingSemaphore, portMAX_DELAY); + xSemaphoreTake(xCountingSemaphore, portMAX_DELAY); - static FWdtQueueData xReceiveStructure; + static FWdtQueueData xReceiveStructure; /* As per most tasks, this task is implemented in an infinite loop. */ - for (;;) - { - xQueueReceive(xQueue, &xReceiveStructure, portMAX_DELAY); - u32 seconds = GenericTimerRead() / GenericTimerFrequecy(); - vPrintf("FFreeRTOSWdtQueueReceiveTask run, count = %d, time seconds: %d\r\n", xReceiveStructure.count, seconds); - } + for (;;) + { + xQueueReceive(xQueue, &xReceiveStructure, portMAX_DELAY); + u32 seconds = GenericTimerRead() / GenericTimerFrequecy(); + vPrintf("FFreeRTOSWdtQueueReceiveTask run, count = %d, time seconds: %d\r\n", xReceiveStructure.count, seconds); + } } static void FFreeRTOSWdtFeedTask(void *pvParameters) { - xSemaphoreTake(xCountingSemaphore, portMAX_DELAY); - - /* As per most tasks, this task is implemented in an infinite loop. */ - for (;;) - { - FFreeRTOSWdtControl(os_wdt_ctrl_p, FREERTOS_WDT_CTRL_KEEPALIVE, NULL); - u32 seconds = GenericTimerRead() / GenericTimerFrequecy(); - vPrintf("FFreeRTOSWdtFeedTask run, time seconds: %d\r\n", seconds); - vTaskDelay(WDT_FEED_PERIOD); - } + xSemaphoreTake(xCountingSemaphore, portMAX_DELAY); + + /* As per most tasks, this task is implemented in an infinite loop. */ + for (;;) + { + FFreeRTOSWdtControl(os_wdt_ctrl_p, FREERTOS_WDT_CTRL_KEEPALIVE, NULL); + u32 seconds = GenericTimerRead() / GenericTimerFrequecy(); + vPrintf("FFreeRTOSWdtFeedTask run, time seconds: %d\r\n", seconds); + vTaskDelay(WDT_FEED_PERIOD); + } } -static void prvOneShotTimerCallback( TimerHandle_t xTimer ) +static void prvOneShotTimerCallback(TimerHandle_t xTimer) { - /* Output a string to show the time at which the callback was executed. */ - vPrintf("One-shot timer callback executing, will delete FFreeRTOSWdtFeedTask.\r\n" ); + /* Output a string to show the time at which the callback was executed. */ + vPrintf("One-shot timer callback executing, will delete FFreeRTOSWdtFeedTask.\r\n"); - /* The count of the number of times this software timer has expired is - stored in the timer's ID. Obtain the ID, increment it, then save it as the - new ID value. The ID is a void pointer, so is cast to a uint32_t. */ + /* The count of the number of times this software timer has expired is + stored in the timer's ID. Obtain the ID, increment it, then save it as the + new ID value. The ID is a void pointer, so is cast to a uint32_t. */ - if(feed_handle) + if (feed_handle) { vTaskDelete(feed_handle); - vPrintf("Delete FFreeRTOSWdtFeedTask success\r\n"); + vPrintf("Delete FFreeRTOSWdtFeedTask success.\r\n"); } } -static void prvAutoReloadTimerCallback( TimerHandle_t xTimer ) +static void prvAutoReloadTimerCallback(TimerHandle_t xTimer) { - /* Output a string to show the time at which the callback was executed. */ - static u32 count = 0; - u32 time_left = 0; - - count++; - /* The count of the number of times this software timer has expired is - stored in the timer's ID. Obtain the ID, increment it, then save it as the - new ID value. The ID is a void pointer, so is cast to a uint32_t. */ - - if(count >= 30) - { - vPrintf("Auto-reload callback executing, Delete FFreeRTOSWdtQueueReceiveTask and software timer.\r\n"); - FFreeRTOSWdtDelete(os_wdt_ctrl_p); - } - else - { - FFreeRTOSWdtControl(os_wdt_ctrl_p, FREERTOS_WDT_CTRL_GET_TIMELEFT, &time_left); - vPrintf("Auto-reload callback executing, wdt timeleft=%d\n", time_left); - } + /* Output a string to show the time at which the callback was executed. */ + static u32 count = 0; + u32 time_left = 0; + + count++; + /* The count of the number of times this software timer has expired is + stored in the timer's ID. Obtain the ID, increment it, then save it as the + new ID value. The ID is a void pointer, so is cast to a uint32_t. */ + + if (count >= 30) + { + vPrintf("Auto-reload callback executing, Delete FFreeRTOSWdtQueueReceiveTask and software timer.\r\n"); + FFreeRTOSWdtDelete(os_wdt_ctrl_p); + } + else + { + FFreeRTOSWdtControl(os_wdt_ctrl_p, FREERTOS_WDT_CTRL_GET_TIMELEFT, &time_left); + vPrintf("Auto-reload callback executing, wdt timeleft=%d\n", time_left); + } } BaseType_t FFreeRTOSWdtCreate(u32 id) { BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为 pdPASS */ - BaseType_t xTimer1Started = pdPASS; - BaseType_t xTimer2Started = pdPASS; - u32 wdt_id = id; - /* The queue is created to hold a maximum of 3 structures of type xData. */ - xQueue = xQueueCreate(3, sizeof(FWdtQueueData)); - if (xQueue == NULL) - { - printf("FFreeRTOSWdtCreate FWdtQueueData create failed.\r\n" ); - return pdFAIL; - } - - xCountingSemaphore = xSemaphoreCreateCounting(READ_WRITE_TASK_NUM, 0); - if (xCountingSemaphore == NULL) - { - printf("FFreeRTOSWdtCreate xCountingSemaphore create failed.\r\n" ); - return pdFAIL; - } - - taskENTER_CRITICAL(); //进入临界区 - /* wdt init task */ - xReturn = xTaskCreate((TaskFunction_t )FFreeRTOSWdtInitTask, /* 任务入口函数 */ - (const char* )"FFreeRTOSWdtInitTask",/* 任务名字 */ - (uint16_t )1024, /* 任务栈大小 */ - (void* )(uintptr)id,/* 任务入口函数参数 */ - (UBaseType_t )1, /* 任务的优先级 */ - NULL); /* 任务控制 */ - - /* 看门狗后半段的处理任务,等待处理超时中断触发后的发送的消息队列 */ - xReturn = xTaskCreate((TaskFunction_t )FFreeRTOSWdtQueueReceiveTask, /* 任务入口函数 */ - (const char* )"FFreeRTOSWdtQueueReceiveTask",/* 任务名字 */ - (uint16_t )1024, /* 任务栈大小 */ - NULL,/* 任务入口函数参数 */ - (UBaseType_t )configMAX_PRIORITIES-1, /* 任务的优先级 */ - (TaskHandle_t* )&queue_receive_handle); /* 任务控制 */ - - /* 主动喂狗任务,周期比看门狗的超时时间短 */ - xReturn = xTaskCreate((TaskFunction_t )FFreeRTOSWdtFeedTask, /* 任务入口函数 */ - (const char* )"FFreeRTOSWdtFeedTask",/* 任务名字 */ - (uint16_t )1024, /* 任务栈大小 */ - NULL,/* 任务入口函数参数 */ - (UBaseType_t )configMAX_PRIORITIES-1, /* 任务的优先级 */ - (TaskHandle_t* )&feed_handle); /* 任务控制 */ - - /* Create the one shot software timer, storing the handle to the created - software timer in xOneShotTimer. */ - xOneShotTimer = xTimerCreate( "OneShot Software Timer", /* Text name for the software timer - not used by FreeRTOS. */ - ONE_SHOT_TIMER_PERIOD, /* The software timer's period in ticks. */ - pdFALSE, /* Setting uxAutoRealod to pdFALSE creates a one-shot software timer. */ - 0, /* This example use the timer id. */ - prvOneShotTimerCallback ); /* The callback function to be used by the software timer being created. */ - - /* Create the auto-reload, storing the handle to the created timer in - xAutoReloadTimer. */ - xAutoReloadTimer = xTimerCreate( "Auto-reload Timer", /* Text name for the software timer - not used by FreeRTOS. */ - AUTO_RELOAD_TIMER_PERIOD, /* The software timer's period in ticks. */ - pdTRUE, /* Set uxAutoRealod to pdTRUE to create an auto-reload timer. */ - 0, /* This example use the timer id. */ - prvAutoReloadTimerCallback ); /* The callback function to be used by the software timer being created. */ - - /* Check the timers were created. */ - if( ( xOneShotTimer != NULL ) && ( xAutoReloadTimer != NULL ) ) - { - /* Start the software timers, using a block time of 0 (no block time). - The scheduler has not been started yet so any block time specified here - would be ignored anyway. */ - xTimer1Started = xTimerStart( xOneShotTimer, 0 ); - xTimer2Started = xTimerStart( xAutoReloadTimer, 0 ); - - /* The implementation of xTimerStart() uses the timer command queue, and - xTimerStart() will fail if the timer command queue gets full. The timer - service task does not get created until the scheduler is started, so all - commands sent to the command queue will stay in the queue until after - the scheduler has been started. Check both calls to xTimerStart() - passed. */ - if( (xTimer1Started != pdPASS) || ( xTimer2Started != pdPASS ) ) - { - vPrintf("CreateSoftwareTimerTasks xTimerStart failed \r\n"); - } - } - else - { - vPrintf("CreateSoftwareTimerTasks xTimerCreate failed \r\n"); - } - - taskEXIT_CRITICAL(); //退出临界区 - + BaseType_t xTimer1Started = pdPASS; + BaseType_t xTimer2Started = pdPASS; + u32 wdt_id = id; + /* The queue is created to hold a maximum of 3 structures of type xData. */ + xQueue = xQueueCreate(3, sizeof(FWdtQueueData)); + if (xQueue == NULL) + { + printf("FFreeRTOSWdtCreate FWdtQueueData create failed.\r\n"); + return pdFAIL; + } + + xCountingSemaphore = xSemaphoreCreateCounting(READ_WRITE_TASK_NUM, 0); + if (xCountingSemaphore == NULL) + { + printf("FFreeRTOSWdtCreate xCountingSemaphore create failed.\r\n"); + return pdFAIL; + } + + taskENTER_CRITICAL(); //进入临界区 + /* wdt init task */ + xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSWdtInitTask, /* 任务入口函数 */ + (const char *)"FFreeRTOSWdtInitTask",/* 任务名字 */ + (uint16_t)1024, /* 任务栈大小 */ + (void *)(uintptr)id,/* 任务入口函数参数 */ + (UBaseType_t)1, /* 任务的优先级 */ + NULL); /* 任务控制 */ + + /* 看门狗后半段的处理任务,等待处理超时中断触发后的发送的消息队列 */ + xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSWdtQueueReceiveTask, /* 任务入口函数 */ + (const char *)"FFreeRTOSWdtQueueReceiveTask",/* 任务名字 */ + (uint16_t)1024, /* 任务栈大小 */ + NULL,/* 任务入口函数参数 */ + (UBaseType_t)configMAX_PRIORITIES - 1, /* 任务的优先级 */ + (TaskHandle_t *)&queue_receive_handle); /* 任务控制 */ + + /* 主动喂狗任务,周期比看门狗的超时时间短 */ + xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSWdtFeedTask, /* 任务入口函数 */ + (const char *)"FFreeRTOSWdtFeedTask",/* 任务名字 */ + (uint16_t)1024, /* 任务栈大小 */ + NULL,/* 任务入口函数参数 */ + (UBaseType_t)configMAX_PRIORITIES - 1, /* 任务的优先级 */ + (TaskHandle_t *)&feed_handle); /* 任务控制 */ + + /* Create the one shot software timer, storing the handle to the created + software timer in xOneShotTimer. */ + xOneShotTimer = xTimerCreate("OneShot Software Timer", /* Text name for the software timer - not used by FreeRTOS. */ + ONE_SHOT_TIMER_PERIOD, /* The software timer's period in ticks. */ + pdFALSE, /* Setting uxAutoRealod to pdFALSE creates a one-shot software timer. */ + 0, /* This example use the timer id. */ + prvOneShotTimerCallback); /* The callback function to be used by the software timer being created. */ + + /* Create the auto-reload, storing the handle to the created timer in + xAutoReloadTimer. */ + xAutoReloadTimer = xTimerCreate("Auto-reload Timer", /* Text name for the software timer - not used by FreeRTOS. */ + AUTO_RELOAD_TIMER_PERIOD, /* The software timer's period in ticks. */ + pdTRUE, /* Set uxAutoRealod to pdTRUE to create an auto-reload timer. */ + 0, /* This example use the timer id. */ + prvAutoReloadTimerCallback); /* The callback function to be used by the software timer being created. */ + + /* Check the timers were created. */ + if ((xOneShotTimer != NULL) && (xAutoReloadTimer != NULL)) + { + /* Start the software timers, using a block time of 0 (no block time). + The scheduler has not been started yet so any block time specified here + would be ignored anyway. */ + xTimer1Started = xTimerStart(xOneShotTimer, 0); + xTimer2Started = xTimerStart(xAutoReloadTimer, 0); + + /* The implementation of xTimerStart() uses the timer command queue, and + xTimerStart() will fail if the timer command queue gets full. The timer + service task does not get created until the scheduler is started, so all + commands sent to the command queue will stay in the queue until after + the scheduler has been started. Check both calls to xTimerStart() + passed. */ + if ((xTimer1Started != pdPASS) || (xTimer2Started != pdPASS)) + { + vPrintf("CreateSoftwareTimerTasks xTimerStart failed.\r\n"); + } + } + else + { + vPrintf("CreateSoftwareTimerTasks xTimerCreate failed.\r\n"); + } + + taskEXIT_CRITICAL(); //退出临界区 + return xReturn; } static void FFreeRTOSWdtDelete(FFreeRTOSWdt *os_wdt_p) { - BaseType_t xReturn = pdPASS; - FFreeRTOSWdtControl(os_wdt_p, FREERTOS_WDT_CTRL_STOP, NULL); - FFreeRTOSWdtDeinit(os_wdt_p); - if(queue_receive_handle) + BaseType_t xReturn = pdPASS; + FFreeRTOSWdtControl(os_wdt_p, FREERTOS_WDT_CTRL_STOP, NULL); + FFreeRTOSWdtDeinit(os_wdt_p); + if (queue_receive_handle) { vTaskDelete(queue_receive_handle); - vPrintf("Delete FFreeRTOSWdtQueueReceiveTask success\r\n"); + vPrintf("Delete FFreeRTOSWdtQueueReceiveTask success.\r\n"); + } + + /* delete queue */ + vQueueDelete(xQueue); + + /* delete count sem */ + vSemaphoreDelete(xCountingSemaphore); + + /* delete timer */ + xReturn = xTimerDelete(xOneShotTimer, 0); + if (xReturn != pdPASS) + { + vPrintf("Delete OneShot Software Timer failed.\r\n"); + } + else + { + vPrintf("Delete OneShot Software Timer success.\r\n"); } - /* delete queue */ - vQueueDelete(xQueue); - - /* delete count sem */ - vSemaphoreDelete(xCountingSemaphore); - - /* delete timer */ - xReturn = xTimerDelete(xOneShotTimer, 0); - if(xReturn != pdPASS) - { - vPrintf("Delete OneShot Software Timer failed.\r\n"); - } - else - { - vPrintf("Delete OneShot Software Timer success.\r\n"); - } - - xReturn = xTimerDelete(xAutoReloadTimer, 0); - if(xReturn != pdPASS) - { - vPrintf("Delete AutoReload Software Timer failed.\r\n"); - } - else - { - vPrintf("Delete AutoReload Software Timer success.\r\n"); - } + xReturn = xTimerDelete(xAutoReloadTimer, 0); + if (xReturn != pdPASS) + { + vPrintf("Delete AutoReload Software Timer failed.\r\n"); + } + else + { + vPrintf("Delete AutoReload Software Timer success.\r\n"); + } } \ No newline at end of file diff --git a/example/storage/fatfs/Kconfig b/example/storage/fatfs/Kconfig new file mode 100644 index 00000000..3caed92f --- /dev/null +++ b/example/storage/fatfs/Kconfig @@ -0,0 +1,25 @@ +mainmenu "Phytium Baremetal Configuration" + +menu "Project Configuration" + + config TARGET_NAME + string "Build Target Name" + default "template" + help + Build Target name for the demo + + config FATFS_BASIC_TEST + bool "Basic Test" + default y + + config FATFS_SPEED_TEST + bool "Speed Test" + default n + + config FATFS_CYCLE_TEST + bool "Cycle Test" + default n + +endmenu + +source "$(FREERTOS_SDK_ROOT)/Kconfig" \ No newline at end of file diff --git a/example/storage/fatfs/READEME.md b/example/storage/fatfs/READEME.md new file mode 100644 index 00000000..80e163dc --- /dev/null +++ b/example/storage/fatfs/READEME.md @@ -0,0 +1,118 @@ +# FATFS 文件系统测试 + +## 1. 例程介绍 + +- 文件系统是一类负责管理和存储文件信息的软件机构,在磁盘上组织文件的方法。作为常用的文件系统,FATFS免费开源,专门为小型嵌入式系统设计。 +- 本例程中通过在文件系统的根目录下挂载多个目录,支持在 RAM Disk, MicroSD 卡,eMMC 卡,SATA硬盘 和 U盘上同时使用和测试 FATFS 文件系统 + + +## 2. 如何使用例程 + +本例程在 E2000 平台测试通过,您可以参考以下方法配置本例程所需要的硬件和软件环境, +- E2000 开发板 +- 本例程基于 E2000 Q Demo 板 + +![hardware](./figures/hardware.png) + +### 2.1 硬件配置方法 + +本例程支持的硬件平台包括 + +- E2000Q + +对应的配置项是, + +- CONFIG_TARGET_E2000Q + +### 2.2 SDK配置方法 + +本例程需要, + +- 使能Shell + +对应的配置项是, + +- CONFIG_USE_LETTER_SHELL + +本例子已经提供好具体的编译指令,以下进行介绍: +- make 将目录下的工程进行编译 +- make clean 将目录下的工程进行清理 +- make boot 将目录下的工程进行编译,并将生成的elf 复制到目标地址 +- make load_e2000d_aarch64 将预设64bit e2000d 下的配置加载至工程中 +- make load_e2000d_aarch32 将预设32bit e2000d 下的配置加载至工程中 +- make menuconfig 配置目录下的参数变量 +- make backup_kconfig 将目录下的sdkconfig 备份到./configs下 + +具体使用方法为: +- 在当前目录下 +- 执行以上指令 + +### 2.3 构建和下载 + +#### 2.3.1 构建过程 + +- 在host侧完成配置 +>配置成 e2000,对于其它平台,使用对于的默认配置,如 e2000q `make load_e2000q_aarch32` + +- 选择目标平台 +``` +make load_e2000q_aarch32 +``` + +- 选择例程需要的配置 +``` +make menuconfig +``` + +- 进行编译 +``` +make +``` + +- 将编译出的镜像放置到tftp目录下 +``` +make boot +``` + +#### 2.3.2 下载过程 + +- host侧设置重启host侧tftp服务器 +``` +sudo service tftpd-hpa restart +``` + +- 开发板侧使用bootelf命令跳转 +``` +setenv ipaddr 192.168.4.20 +setenv serverip 192.168.4.50 +setenv gatewayip 192.168.4.1 +tftpboot 0x90100000 freertos.elf +bootelf -p 0x90100000 +``` + +### 2.4 输出与实验现象 + +- 打开配置 CONFIG_FATFS_SDIO_TF, 使能 MicroSD(TF) 卡 +- 打开配置 CONFIG_FATFS_SDIO_EMMC, 使能 eMMC +- 打开配置 CONFIG_FATFS_USB, 使能 U 盘 +- 打开配置 CONFIG_FATFS_FSATA, 使能 SATA 硬盘 +- 打开配置 CONFIG_FATFS_FSATA_PCIE, 使能 SATA 硬盘与 PCIE 接口 + +- 打开配置 CONFIG_FATFS_BASIC_TEST,测试 FATFS 的基本功能 +- 打开配置 CONFIG_FATFS_SPEED_TEST, 测试 FATFS 的读写速度,会破环文件系统 +- 打开配置 CONFIG_FATFS_CYCLE_TEST, 运行 FATFS 的测试项,会破环文件系统 +- 编译镜像,加载到开发板上电启动 + +![](./figures/config.png) + +![](./figures/test_item.png) + +- 加载镜像启动后,自动开始测试 + +![](./figures/test_1.png) +![](./figures/test_2.png) +![](./figures/test_3.png) +![](./figures/test_4.png) +![](./figures/test_5.png) + +## 3. 如何解决问题 diff --git a/example/storage/fatfs/configs/e2000d_aarch32_eg_configs b/example/storage/fatfs/configs/e2000d_aarch32_eg_configs new file mode 100644 index 00000000..8898745a --- /dev/null +++ b/example/storage/fatfs/configs/e2000d_aarch32_eg_configs @@ -0,0 +1,327 @@ + +# +# Project Configuration +# +CONFIG_TARGET_NAME="e2000d_freertos_a32" +CONFIG_FATFS_BASIC_TEST=y +# CONFIG_FATFS_SPEED_TEST is not set +# CONFIG_FATFS_CYCLE_TEST is not set +# end of Project Configuration + +# +# Standalone Setting +# +CONFIG_USE_FREERTOS=y + +# +# Arch Configuration +# +CONFIG_TARGET_ARMV8_AARCH32=y +# CONFIG_TARGET_ARMV8_AARCH64 is not set +CONFIG_USE_CACHE=y +CONFIG_USE_MMU=y +# CONFIG_USE_SYS_TICK is not set +CONFIG_USE_AARCH64_L1_TO_AARCH32=y +# end of Arch Configuration + +# +# Board Configuration +# +# CONFIG_TARGET_F2000_4 is not set +# CONFIG_TARGET_D2000 is not set +# CONFIG_TARGET_E2000Q is not set +CONFIG_TARGET_E2000D=y +# CONFIG_TARGET_E2000S is not set +CONFIG_TARGET_E2000=y +CONFIG_DEFAULT_DEBUG_PRINT_UART1=y +# CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set +# CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set +# end of Board Configuration + +# +# Components Configuration +# +# CONFIG_USE_SPI is not set +# CONFIG_USE_QSPI is not set +CONFIG_USE_GIC=y +CONFIG_ENABLE_GICV3=y +CONFIG_USE_SERIAL=y + +# +# Usart Configuration +# +CONFIG_ENABLE_Pl011_UART=y +# end of Usart Configuration + +# CONFIG_USE_GPIO is not set +# CONFIG_USE_ETH is not set +# CONFIG_USE_CAN is not set +# CONFIG_USE_I2C is not set +# CONFIG_USE_TIMER is not set +# CONFIG_USE_MIO is not set +CONFIG_USE_SDMMC=y +# CONFIG_ENABLE_FSDMMC is not set +CONFIG_ENABLE_FSDIO=y +# CONFIG_USE_PCIE is not set +# CONFIG_USE_WDT is not set +# CONFIG_USE_DMA is not set +# CONFIG_USE_NAND is not set +# CONFIG_USE_RTC is not set +# CONFIG_USE_SATA is not set +# CONFIG_USE_USB is not set +# CONFIG_USE_ADC is not set +# CONFIG_USE_PWM is not set +# CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set +# end of Components Configuration + +CONFIG_USE_NEW_LIBC=y +# end of Standalone Setting + +# +# Building Option +# +# CONFIG_LOG_VERBOS is not set +# CONFIG_LOG_DEBUG is not set +# CONFIG_LOG_INFO is not set +# CONFIG_LOG_WARN is not set +CONFIG_LOG_ERROR=y +# CONFIG_LOG_NONE is not set +CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y +CONFIG_INTERRUPT_ROLE_MASTER=y +# CONFIG_INTERRUPT_ROLE_SLAVE is not set +# CONFIG_LOG_EXTRA_INFO is not set +# CONFIG_BOOTUP_DEBUG_PRINTS is not set + +# +# Linker Options +# +CONFIG_AARCH32_RAM_LD=y +# CONFIG_AARCH64_RAM_LD is not set +# CONFIG_USER_DEFINED_LD is not set +CONFIG_LINK_SCRIPT_ROM=y +CONFIG_ROM_START_UP_ADDR=0x80100000 +CONFIG_ROM_SIZE_MB=2 +CONFIG_LINK_SCRIPT_RAM=y +CONFIG_RAM_START_UP_ADDR=0x81000000 +CONFIG_RAM_SIZE_MB=64 +CONFIG_HEAP_SIZE=1 +CONFIG_SVC_STACK_SIZE=0x1000 +CONFIG_SYS_STACK_SIZE=0x1000 +CONFIG_IRQ_STACK_SIZE=0x1000 +CONFIG_ABORT_STACK_SIZE=0x1000 +CONFIG_FIQ_STACK_SIZE=0x1000 +CONFIG_UNDEF_STACK_SIZE=0x1000 +# end of Linker Options + +# +# Compiler Options +# + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + +CONFIG_OUTPUT_BINARY=y +# end of Compiler Options +# end of Building Option + +# +# Component Configuration +# + +# +# Freertos Uart Drivers +# +CONFIG_FREERTOS_USE_UART=y +# end of Freertos Uart Drivers + +# +# Freertos Pwm Drivers +# +# CONFIG_FREERTOS_USE_PWM is not set +# end of Freertos Pwm Drivers + +# +# Freertos Qspi Drivers +# +# CONFIG_FREERTOS_USE_QSPI is not set +# end of Freertos Qspi Drivers + +# +# Freertos Wdt Drivers +# +# CONFIG_FREERTOS_USE_WDT is not set +# end of Freertos Wdt Drivers + +# +# Freertos Eth Drivers +# +# CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set +# end of Freertos Eth Drivers + +# +# Freertos Gpio Drivers +# +# CONFIG_FREERTOS_USE_GPIO is not set +# end of Freertos Gpio Drivers + +# +# Freertos Spim Drivers +# +# CONFIG_FREERTOS_USE_FSPIM is not set +# end of Freertos Spim Drivers + +# +# Freertos DMA Drivers +# +# CONFIG_FREERTOS_USE_FDDMA is not set +# CONFIG_FREERTOS_USE_FGDMA is not set +# end of Freertos DMA Drivers + +# +# Freertos Adc Drivers +# +# CONFIG_FREERTOS_USE_ADC is not set +# end of Freertos Adc Drivers + +# +# Freertos Can Drivers +# +# CONFIG_FREERTOS_USE_CAN is not set +# end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers +# end of Component Configuration + +# +# Third-Party Configuration +# +# CONFIG_USE_LWIP is not set +CONFIG_USE_BACKTRACE=y +CONFIG_USE_FATFS_0_1_4=y + +# +# FATFS Configuration (0.1.4) +# +CONFIG_FATFS_RAM_DISK=y + +# +# RAM Disk Configuration +# +CONFIG_FATFS_RAM_DISK_BASE=0xa0000000 +CONFIG_FATFS_RAM_DISK_SIZE_MB=500 +CONFIG_FATFS_RAM_DISK_SECTOR_SIZE_BYTE=512 +# end of RAM Disk Configuration + +CONFIG_FATFS_SDMMC=y +CONFIG_FATFS_SDMMC_FSDIO_TF=y +CONFIG_FATFS_SDMMC_FSDIO_EMMC=y +# CONFIG_FATFS_SDMMC_FSDMMC_TF is not set +CONFIG_FATFS_SATA_DISK=y + +# +# SATA Disk Configuration +# +# CONFIG_FATFS_FSATA is not set +# CONFIG_FATFS_FSATA_PCIE is not set +# end of SATA Disk Configuration + +CONFIG_FATFS_USB=y +CONFIG_FATFS_VOLUME_COUNT=6 +# CONFIG_FATFS_LFN_NONE is not set +CONFIG_FATFS_LFN_HEAP=y +# CONFIG_FATFS_LFN_STACK is not set +CONFIG_FATFS_MAX_LFN=255 +CONFIG_FATFS_FS_LOCK=0 +CONFIG_FATFS_TIMEOUT_MS=10000 +CONFIG_FATFS_PER_FILE_CACHE=y +CONFIG_FATFS_ALLOC_PREFER_MEMP=y +CONFIG_FATFS_MEMP_SIZE=2 +# end of FATFS Configuration (0.1.4) + +# CONFIG_USE_SFUD is not set +# CONFIG_USE_SPIFFS is not set +# CONFIG_USE_AMP is not set +CONFIG_USE_LETTER_SHELL=y + +# +# Letter Shell Configuration +# +CONFIG_LS_PL011_UART=y +CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y +# CONFIG_DEFAULT_LETTER_SHELL_USE_UART0 is not set +# CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set +# end of Letter Shell Configuration + +CONFIG_USE_TLSF=y +CONFIG_USE_SDMMC_CMD=y + +# +# SDMMC Configuration +# +# CONFIG_SDMMC_USE_FSDMMC is not set +CONFIG_SDMMC_USE_FSDIO=y +# end of SDMMC Configuration + +CONFIG_USE_CHERRY_USB=y + +# +# CherryUSB Configuration +# +CONFIG_CHERRY_USB_PORT_XHCI=y +# CONFIG_CHERRY_USB_PORT_PHYTIUM_OTG is not set +CONFIG_CHERRYUSB_HOST=y +# CONFIG_CHERRYUSB_DEVICE is not set +CONFIG_CHERRY_USB_HOST_HUB=y +CONFIG_CHERRY_USB_HOST_MSC=y +# CONFIG_CHERRY_USB_HOST_HID is not set +# CONFIG_CHERRY_USB_HOST_VEDIO is not set +# CONFIG_CHERRY_USB_HOST_CDC is not set +# CONFIG_CHERRY_USB_HOST_RNDIS_WIRELESS is not set +# end of CherryUSB Configuration +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/storage/spim_spiffs/configs/e2000d_aarch64_eg_configs b/example/storage/fatfs/configs/e2000d_aarch64_eg_configs similarity index 51% rename from example/storage/spim_spiffs/configs/e2000d_aarch64_eg_configs rename to example/storage/fatfs/configs/e2000d_aarch64_eg_configs index 86833bab..39d4ff17 100644 --- a/example/storage/spim_spiffs/configs/e2000d_aarch64_eg_configs +++ b/example/storage/fatfs/configs/e2000d_aarch64_eg_configs @@ -1,9 +1,12 @@ # -# Freertos Configuration +# Project Configuration # CONFIG_TARGET_NAME="e2000d_freertos_a64" -# end of Freertos Configuration +CONFIG_FATFS_BASIC_TEST=y +# CONFIG_FATFS_SPEED_TEST is not set +# CONFIG_FATFS_CYCLE_TEST is not set +# end of Project Configuration # # Standalone Setting @@ -17,7 +20,7 @@ CONFIG_USE_FREERTOS=y CONFIG_TARGET_ARMV8_AARCH64=y CONFIG_USE_CACHE=y CONFIG_USE_MMU=y -CONFIG_USE_SYS_TICK=y +# CONFIG_USE_SYS_TICK is not set # CONFIG_MMU_DEBUG_PRINTS is not set # end of Arch Configuration @@ -38,16 +41,8 @@ CONFIG_DEFAULT_DEBUG_PRINT_UART1=y # # Components Configuration # -CONFIG_USE_SPI=y -CONFIG_USE_FSPIM=y -CONFIG_USE_QSPI=y - -# -# Qspi Configuration -# -CONFIG_USE_FQSPI=y -# end of Qspi Configuration - +# CONFIG_USE_SPI is not set +# CONFIG_USE_QSPI is not set CONFIG_USE_GIC=y CONFIG_ENABLE_GICV3=y CONFIG_USE_SERIAL=y @@ -64,7 +59,9 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_I2C is not set # CONFIG_USE_TIMER is not set # CONFIG_USE_MIO is not set -# CONFIG_USE_SDMMC is not set +CONFIG_USE_SDMMC=y +# CONFIG_ENABLE_FSDMMC is not set +CONFIG_ENABLE_FSDIO=y # CONFIG_USE_PCIE is not set # CONFIG_USE_WDT is not set # CONFIG_USE_DMA is not set @@ -75,6 +72,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -92,7 +90,7 @@ CONFIG_LOG_ERROR=y CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y CONFIG_INTERRUPT_ROLE_MASTER=y # CONFIG_INTERRUPT_ROLE_SLAVE is not set -# CONFIG_LOG_EXTRA_INFO is not set +CONFIG_LOG_EXTRA_INFO=y # CONFIG_BOOTUP_DEBUG_PRINTS is not set # @@ -103,7 +101,7 @@ CONFIG_AARCH64_RAM_LD=y # CONFIG_USER_DEFINED_LD is not set CONFIG_LINK_SCRIPT_ROM=y CONFIG_ROM_START_UP_ADDR=0x80100000 -CONFIG_ROM_SIZE_MB=1 +CONFIG_ROM_SIZE_MB=2 CONFIG_LINK_SCRIPT_RAM=y CONFIG_RAM_START_UP_ADDR=0x81000000 CONFIG_RAM_SIZE_MB=64 @@ -115,6 +113,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -138,7 +145,7 @@ CONFIG_FREERTOS_USE_UART=y # # Freertos Qspi Drivers # -CONFIG_FREERTOS_USE_QSPI=y +# CONFIG_FREERTOS_USE_QSPI is not set # end of Freertos Qspi Drivers # @@ -151,6 +158,7 @@ CONFIG_FREERTOS_USE_QSPI=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -162,7 +170,7 @@ CONFIG_FREERTOS_USE_QSPI=y # # Freertos Spim Drivers # -CONFIG_FREERTOS_USE_FSPIM=y +# CONFIG_FREERTOS_USE_FSPIM is not set # end of Freertos Spim Drivers # @@ -172,12 +180,6 @@ CONFIG_FREERTOS_USE_FSPIM=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -189,35 +191,74 @@ CONFIG_FREERTOS_USE_FSPIM=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set -CONFIG_USE_SFUD=y +CONFIG_USE_FATFS_0_1_4=y + +# +# FATFS Configuration (0.1.4) +# +CONFIG_FATFS_RAM_DISK=y # -# SFUD Configuration +# RAM Disk Configuration # -CONFIG_SFUD_CTRL_FSPIM=y -CONFIG_SFUD_CTRL_FQSPI=y -# CONFIG_SFUD_QSPI_READ_MODE_READ is not set -# CONFIG_SFUD_QSPI_READ_MODE_DUAL_READ is not set -CONFIG_SFUD_QSPI_READ_MODE_QUAD_READ=y -# end of SFUD Configuration +CONFIG_FATFS_RAM_DISK_BASE=0xa0000000 +CONFIG_FATFS_RAM_DISK_SIZE_MB=500 +CONFIG_FATFS_RAM_DISK_SECTOR_SIZE_BYTE=512 +# end of RAM Disk Configuration -CONFIG_USE_SPIFFS=y +CONFIG_FATFS_SDMMC=y +CONFIG_FATFS_SDMMC_FSDIO_TF=y +CONFIG_FATFS_SDMMC_FSDIO_EMMC=y +# CONFIG_FATFS_SDMMC_FSDMMC_TF is not set +CONFIG_FATFS_SATA_DISK=y # -# SPIFFS Configuration +# SATA Disk Configuration # -CONFIG_SPIFFS_ON_FSPIM_SFUD=y -# CONFIG_SPIFFS_ON_FQSPI_SFUD is not set -# end of SPIFFS Configuration +# CONFIG_FATFS_FSATA is not set +# CONFIG_FATFS_FSATA_PCIE is not set +# end of SATA Disk Configuration + +CONFIG_FATFS_USB=y +CONFIG_FATFS_VOLUME_COUNT=10 +# CONFIG_FATFS_LFN_NONE is not set +CONFIG_FATFS_LFN_HEAP=y +# CONFIG_FATFS_LFN_STACK is not set +CONFIG_FATFS_MAX_LFN=255 +CONFIG_FATFS_FS_LOCK=0 +CONFIG_FATFS_TIMEOUT_MS=10000 +CONFIG_FATFS_PER_FILE_CACHE=y +CONFIG_FATFS_ALLOC_PREFER_MEMP=y +CONFIG_FATFS_MEMP_SIZE=2 +# end of FATFS Configuration (0.1.4) +# CONFIG_USE_SFUD is not set +# CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set CONFIG_USE_LETTER_SHELL=y @@ -231,6 +272,52 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # end of Letter Shell Configuration CONFIG_USE_TLSF=y -# CONFIG_USE_SDMMC_CMD is not set -# CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +CONFIG_USE_SDMMC_CMD=y + +# +# SDMMC Configuration +# +# CONFIG_SDMMC_USE_FSDMMC is not set +CONFIG_SDMMC_USE_FSDIO=y +# end of SDMMC Configuration + +CONFIG_USE_CHERRY_USB=y + +# +# CherryUSB Configuration +# +CONFIG_CHERRY_USB_PORT_XHCI=y +# CONFIG_CHERRY_USB_PORT_PHYTIUM_OTG is not set +CONFIG_CHERRYUSB_HOST=y +# CONFIG_CHERRYUSB_DEVICE is not set +CONFIG_CHERRY_USB_HOST_HUB=y +CONFIG_CHERRY_USB_HOST_MSC=y +# CONFIG_CHERRY_USB_HOST_HID is not set +# CONFIG_CHERRY_USB_HOST_VEDIO is not set +# CONFIG_CHERRY_USB_HOST_CDC is not set +# CONFIG_CHERRY_USB_HOST_RNDIS_WIRELESS is not set +# end of CherryUSB Configuration +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/storage/fatfs/configs/e2000q_aarch32_eg_configs b/example/storage/fatfs/configs/e2000q_aarch32_eg_configs new file mode 100644 index 00000000..8b0e1078 --- /dev/null +++ b/example/storage/fatfs/configs/e2000q_aarch32_eg_configs @@ -0,0 +1,327 @@ + +# +# Project Configuration +# +CONFIG_TARGET_NAME="e2000q_freertos_a32" +CONFIG_FATFS_BASIC_TEST=y +# CONFIG_FATFS_SPEED_TEST is not set +# CONFIG_FATFS_CYCLE_TEST is not set +# end of Project Configuration + +# +# Standalone Setting +# +CONFIG_USE_FREERTOS=y + +# +# Arch Configuration +# +CONFIG_TARGET_ARMV8_AARCH32=y +# CONFIG_TARGET_ARMV8_AARCH64 is not set +CONFIG_USE_CACHE=y +CONFIG_USE_MMU=y +# CONFIG_USE_SYS_TICK is not set +CONFIG_USE_AARCH64_L1_TO_AARCH32=y +# end of Arch Configuration + +# +# Board Configuration +# +# CONFIG_TARGET_F2000_4 is not set +# CONFIG_TARGET_D2000 is not set +CONFIG_TARGET_E2000Q=y +# CONFIG_TARGET_E2000D is not set +# CONFIG_TARGET_E2000S is not set +CONFIG_TARGET_E2000=y +CONFIG_DEFAULT_DEBUG_PRINT_UART1=y +# CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set +# CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set +# end of Board Configuration + +# +# Components Configuration +# +# CONFIG_USE_SPI is not set +# CONFIG_USE_QSPI is not set +CONFIG_USE_GIC=y +CONFIG_ENABLE_GICV3=y +CONFIG_USE_SERIAL=y + +# +# Usart Configuration +# +CONFIG_ENABLE_Pl011_UART=y +# end of Usart Configuration + +# CONFIG_USE_GPIO is not set +# CONFIG_USE_ETH is not set +# CONFIG_USE_CAN is not set +# CONFIG_USE_I2C is not set +# CONFIG_USE_TIMER is not set +# CONFIG_USE_MIO is not set +CONFIG_USE_SDMMC=y +# CONFIG_ENABLE_FSDMMC is not set +CONFIG_ENABLE_FSDIO=y +# CONFIG_USE_PCIE is not set +# CONFIG_USE_WDT is not set +# CONFIG_USE_DMA is not set +# CONFIG_USE_NAND is not set +# CONFIG_USE_RTC is not set +# CONFIG_USE_SATA is not set +# CONFIG_USE_USB is not set +# CONFIG_USE_ADC is not set +# CONFIG_USE_PWM is not set +# CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set +# end of Components Configuration + +CONFIG_USE_NEW_LIBC=y +# end of Standalone Setting + +# +# Building Option +# +# CONFIG_LOG_VERBOS is not set +# CONFIG_LOG_DEBUG is not set +# CONFIG_LOG_INFO is not set +# CONFIG_LOG_WARN is not set +CONFIG_LOG_ERROR=y +# CONFIG_LOG_NONE is not set +CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y +CONFIG_INTERRUPT_ROLE_MASTER=y +# CONFIG_INTERRUPT_ROLE_SLAVE is not set +# CONFIG_LOG_EXTRA_INFO is not set +# CONFIG_BOOTUP_DEBUG_PRINTS is not set + +# +# Linker Options +# +CONFIG_AARCH32_RAM_LD=y +# CONFIG_AARCH64_RAM_LD is not set +# CONFIG_USER_DEFINED_LD is not set +CONFIG_LINK_SCRIPT_ROM=y +CONFIG_ROM_START_UP_ADDR=0x80100000 +CONFIG_ROM_SIZE_MB=2 +CONFIG_LINK_SCRIPT_RAM=y +CONFIG_RAM_START_UP_ADDR=0x81000000 +CONFIG_RAM_SIZE_MB=64 +CONFIG_HEAP_SIZE=1 +CONFIG_SVC_STACK_SIZE=0x1000 +CONFIG_SYS_STACK_SIZE=0x1000 +CONFIG_IRQ_STACK_SIZE=0x1000 +CONFIG_ABORT_STACK_SIZE=0x1000 +CONFIG_FIQ_STACK_SIZE=0x1000 +CONFIG_UNDEF_STACK_SIZE=0x1000 +# end of Linker Options + +# +# Compiler Options +# + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + +CONFIG_OUTPUT_BINARY=y +# end of Compiler Options +# end of Building Option + +# +# Component Configuration +# + +# +# Freertos Uart Drivers +# +CONFIG_FREERTOS_USE_UART=y +# end of Freertos Uart Drivers + +# +# Freertos Pwm Drivers +# +# CONFIG_FREERTOS_USE_PWM is not set +# end of Freertos Pwm Drivers + +# +# Freertos Qspi Drivers +# +# CONFIG_FREERTOS_USE_QSPI is not set +# end of Freertos Qspi Drivers + +# +# Freertos Wdt Drivers +# +# CONFIG_FREERTOS_USE_WDT is not set +# end of Freertos Wdt Drivers + +# +# Freertos Eth Drivers +# +# CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set +# end of Freertos Eth Drivers + +# +# Freertos Gpio Drivers +# +# CONFIG_FREERTOS_USE_GPIO is not set +# end of Freertos Gpio Drivers + +# +# Freertos Spim Drivers +# +# CONFIG_FREERTOS_USE_FSPIM is not set +# end of Freertos Spim Drivers + +# +# Freertos DMA Drivers +# +# CONFIG_FREERTOS_USE_FDDMA is not set +# CONFIG_FREERTOS_USE_FGDMA is not set +# end of Freertos DMA Drivers + +# +# Freertos Adc Drivers +# +# CONFIG_FREERTOS_USE_ADC is not set +# end of Freertos Adc Drivers + +# +# Freertos Can Drivers +# +# CONFIG_FREERTOS_USE_CAN is not set +# end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers +# end of Component Configuration + +# +# Third-Party Configuration +# +# CONFIG_USE_LWIP is not set +CONFIG_USE_BACKTRACE=y +CONFIG_USE_FATFS_0_1_4=y + +# +# FATFS Configuration (0.1.4) +# +CONFIG_FATFS_RAM_DISK=y + +# +# RAM Disk Configuration +# +CONFIG_FATFS_RAM_DISK_BASE=0xa0000000 +CONFIG_FATFS_RAM_DISK_SIZE_MB=500 +CONFIG_FATFS_RAM_DISK_SECTOR_SIZE_BYTE=512 +# end of RAM Disk Configuration + +CONFIG_FATFS_SDMMC=y +CONFIG_FATFS_SDMMC_FSDIO_TF=y +CONFIG_FATFS_SDMMC_FSDIO_EMMC=y +# CONFIG_FATFS_SDMMC_FSDMMC_TF is not set +CONFIG_FATFS_SATA_DISK=y + +# +# SATA Disk Configuration +# +# CONFIG_FATFS_FSATA is not set +# CONFIG_FATFS_FSATA_PCIE is not set +# end of SATA Disk Configuration + +CONFIG_FATFS_USB=y +CONFIG_FATFS_VOLUME_COUNT=10 +# CONFIG_FATFS_LFN_NONE is not set +CONFIG_FATFS_LFN_HEAP=y +# CONFIG_FATFS_LFN_STACK is not set +CONFIG_FATFS_MAX_LFN=255 +CONFIG_FATFS_FS_LOCK=0 +CONFIG_FATFS_TIMEOUT_MS=10000 +CONFIG_FATFS_PER_FILE_CACHE=y +CONFIG_FATFS_ALLOC_PREFER_MEMP=y +CONFIG_FATFS_MEMP_SIZE=2 +# end of FATFS Configuration (0.1.4) + +# CONFIG_USE_SFUD is not set +# CONFIG_USE_SPIFFS is not set +# CONFIG_USE_AMP is not set +CONFIG_USE_LETTER_SHELL=y + +# +# Letter Shell Configuration +# +CONFIG_LS_PL011_UART=y +CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y +# CONFIG_DEFAULT_LETTER_SHELL_USE_UART0 is not set +# CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set +# end of Letter Shell Configuration + +CONFIG_USE_TLSF=y +CONFIG_USE_SDMMC_CMD=y + +# +# SDMMC Configuration +# +# CONFIG_SDMMC_USE_FSDMMC is not set +CONFIG_SDMMC_USE_FSDIO=y +# end of SDMMC Configuration + +CONFIG_USE_CHERRY_USB=y + +# +# CherryUSB Configuration +# +CONFIG_CHERRY_USB_PORT_XHCI=y +# CONFIG_CHERRY_USB_PORT_PHYTIUM_OTG is not set +CONFIG_CHERRYUSB_HOST=y +# CONFIG_CHERRYUSB_DEVICE is not set +CONFIG_CHERRY_USB_HOST_HUB=y +CONFIG_CHERRY_USB_HOST_MSC=y +# CONFIG_CHERRY_USB_HOST_HID is not set +# CONFIG_CHERRY_USB_HOST_VEDIO is not set +# CONFIG_CHERRY_USB_HOST_CDC is not set +# CONFIG_CHERRY_USB_HOST_RNDIS_WIRELESS is not set +# end of CherryUSB Configuration +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/storage/fatfs/configs/e2000q_aarch64_eg_configs b/example/storage/fatfs/configs/e2000q_aarch64_eg_configs new file mode 100644 index 00000000..27fb43f5 --- /dev/null +++ b/example/storage/fatfs/configs/e2000q_aarch64_eg_configs @@ -0,0 +1,323 @@ + +# +# Project Configuration +# +CONFIG_TARGET_NAME="e2000q_freertos_a64" +CONFIG_FATFS_BASIC_TEST=y +# CONFIG_FATFS_SPEED_TEST is not set +# CONFIG_FATFS_CYCLE_TEST is not set +# end of Project Configuration + +# +# Standalone Setting +# +CONFIG_USE_FREERTOS=y + +# +# Arch Configuration +# +# CONFIG_TARGET_ARMV8_AARCH32 is not set +CONFIG_TARGET_ARMV8_AARCH64=y +CONFIG_USE_CACHE=y +CONFIG_USE_MMU=y +# CONFIG_USE_SYS_TICK is not set +# CONFIG_MMU_DEBUG_PRINTS is not set +# end of Arch Configuration + +# +# Board Configuration +# +# CONFIG_TARGET_F2000_4 is not set +# CONFIG_TARGET_D2000 is not set +CONFIG_TARGET_E2000Q=y +# CONFIG_TARGET_E2000D is not set +# CONFIG_TARGET_E2000S is not set +CONFIG_TARGET_E2000=y +CONFIG_DEFAULT_DEBUG_PRINT_UART1=y +# CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set +# CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set +# end of Board Configuration + +# +# Components Configuration +# +# CONFIG_USE_SPI is not set +# CONFIG_USE_QSPI is not set +CONFIG_USE_GIC=y +CONFIG_ENABLE_GICV3=y +CONFIG_USE_SERIAL=y + +# +# Usart Configuration +# +CONFIG_ENABLE_Pl011_UART=y +# end of Usart Configuration + +# CONFIG_USE_GPIO is not set +# CONFIG_USE_ETH is not set +# CONFIG_USE_CAN is not set +# CONFIG_USE_I2C is not set +# CONFIG_USE_TIMER is not set +# CONFIG_USE_MIO is not set +CONFIG_USE_SDMMC=y +# CONFIG_ENABLE_FSDMMC is not set +CONFIG_ENABLE_FSDIO=y +# CONFIG_USE_PCIE is not set +# CONFIG_USE_WDT is not set +# CONFIG_USE_DMA is not set +# CONFIG_USE_NAND is not set +# CONFIG_USE_RTC is not set +# CONFIG_USE_SATA is not set +# CONFIG_USE_USB is not set +# CONFIG_USE_ADC is not set +# CONFIG_USE_PWM is not set +# CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set +# end of Components Configuration + +CONFIG_USE_NEW_LIBC=y +# end of Standalone Setting + +# +# Building Option +# +# CONFIG_LOG_VERBOS is not set +# CONFIG_LOG_DEBUG is not set +# CONFIG_LOG_INFO is not set +# CONFIG_LOG_WARN is not set +CONFIG_LOG_ERROR=y +# CONFIG_LOG_NONE is not set +CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y +CONFIG_INTERRUPT_ROLE_MASTER=y +# CONFIG_INTERRUPT_ROLE_SLAVE is not set +CONFIG_LOG_EXTRA_INFO=y +# CONFIG_BOOTUP_DEBUG_PRINTS is not set + +# +# Linker Options +# +# CONFIG_AARCH32_RAM_LD is not set +CONFIG_AARCH64_RAM_LD=y +# CONFIG_USER_DEFINED_LD is not set +CONFIG_LINK_SCRIPT_ROM=y +CONFIG_ROM_START_UP_ADDR=0x80100000 +CONFIG_ROM_SIZE_MB=2 +CONFIG_LINK_SCRIPT_RAM=y +CONFIG_RAM_START_UP_ADDR=0x81000000 +CONFIG_RAM_SIZE_MB=64 +CONFIG_HEAP_SIZE=1 +CONFIG_STACK_SIZE=0x100000 +CONFIG_FPU_STACK_SIZE=0x1000 +# end of Linker Options + +# +# Compiler Options +# + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + +CONFIG_OUTPUT_BINARY=y +# end of Compiler Options +# end of Building Option + +# +# Component Configuration +# + +# +# Freertos Uart Drivers +# +CONFIG_FREERTOS_USE_UART=y +# end of Freertos Uart Drivers + +# +# Freertos Pwm Drivers +# +# CONFIG_FREERTOS_USE_PWM is not set +# end of Freertos Pwm Drivers + +# +# Freertos Qspi Drivers +# +# CONFIG_FREERTOS_USE_QSPI is not set +# end of Freertos Qspi Drivers + +# +# Freertos Wdt Drivers +# +# CONFIG_FREERTOS_USE_WDT is not set +# end of Freertos Wdt Drivers + +# +# Freertos Eth Drivers +# +# CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set +# end of Freertos Eth Drivers + +# +# Freertos Gpio Drivers +# +# CONFIG_FREERTOS_USE_GPIO is not set +# end of Freertos Gpio Drivers + +# +# Freertos Spim Drivers +# +# CONFIG_FREERTOS_USE_FSPIM is not set +# end of Freertos Spim Drivers + +# +# Freertos DMA Drivers +# +# CONFIG_FREERTOS_USE_FDDMA is not set +# CONFIG_FREERTOS_USE_FGDMA is not set +# end of Freertos DMA Drivers + +# +# Freertos Adc Drivers +# +# CONFIG_FREERTOS_USE_ADC is not set +# end of Freertos Adc Drivers + +# +# Freertos Can Drivers +# +# CONFIG_FREERTOS_USE_CAN is not set +# end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers +# end of Component Configuration + +# +# Third-Party Configuration +# +# CONFIG_USE_LWIP is not set +CONFIG_USE_BACKTRACE=y +CONFIG_USE_FATFS_0_1_4=y + +# +# FATFS Configuration (0.1.4) +# +CONFIG_FATFS_RAM_DISK=y + +# +# RAM Disk Configuration +# +CONFIG_FATFS_RAM_DISK_BASE=0xa0000000 +CONFIG_FATFS_RAM_DISK_SIZE_MB=500 +CONFIG_FATFS_RAM_DISK_SECTOR_SIZE_BYTE=512 +# end of RAM Disk Configuration + +CONFIG_FATFS_SDMMC=y +CONFIG_FATFS_SDMMC_FSDIO_TF=y +CONFIG_FATFS_SDMMC_FSDIO_EMMC=y +# CONFIG_FATFS_SDMMC_FSDMMC_TF is not set +CONFIG_FATFS_SATA_DISK=y + +# +# SATA Disk Configuration +# +# CONFIG_FATFS_FSATA is not set +# CONFIG_FATFS_FSATA_PCIE is not set +# end of SATA Disk Configuration + +CONFIG_FATFS_USB=y +CONFIG_FATFS_VOLUME_COUNT=10 +# CONFIG_FATFS_LFN_NONE is not set +CONFIG_FATFS_LFN_HEAP=y +# CONFIG_FATFS_LFN_STACK is not set +CONFIG_FATFS_MAX_LFN=255 +CONFIG_FATFS_FS_LOCK=0 +CONFIG_FATFS_TIMEOUT_MS=10000 +CONFIG_FATFS_PER_FILE_CACHE=y +CONFIG_FATFS_ALLOC_PREFER_MEMP=y +CONFIG_FATFS_MEMP_SIZE=2 +# end of FATFS Configuration (0.1.4) + +# CONFIG_USE_SFUD is not set +# CONFIG_USE_SPIFFS is not set +# CONFIG_USE_AMP is not set +CONFIG_USE_LETTER_SHELL=y + +# +# Letter Shell Configuration +# +CONFIG_LS_PL011_UART=y +CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y +# CONFIG_DEFAULT_LETTER_SHELL_USE_UART0 is not set +# CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set +# end of Letter Shell Configuration + +CONFIG_USE_TLSF=y +CONFIG_USE_SDMMC_CMD=y + +# +# SDMMC Configuration +# +# CONFIG_SDMMC_USE_FSDMMC is not set +CONFIG_SDMMC_USE_FSDIO=y +# end of SDMMC Configuration + +CONFIG_USE_CHERRY_USB=y + +# +# CherryUSB Configuration +# +CONFIG_CHERRY_USB_PORT_XHCI=y +# CONFIG_CHERRY_USB_PORT_PHYTIUM_OTG is not set +CONFIG_CHERRYUSB_HOST=y +# CONFIG_CHERRYUSB_DEVICE is not set +CONFIG_CHERRY_USB_HOST_HUB=y +CONFIG_CHERRY_USB_HOST_MSC=y +# CONFIG_CHERRY_USB_HOST_HID is not set +# CONFIG_CHERRY_USB_HOST_VEDIO is not set +# CONFIG_CHERRY_USB_HOST_CDC is not set +# CONFIG_CHERRY_USB_HOST_RNDIS_WIRELESS is not set +# end of CherryUSB Configuration +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/storage/fatfs/figures/config.png b/example/storage/fatfs/figures/config.png new file mode 100644 index 0000000000000000000000000000000000000000..3ca3c87e319e6f77d4e96e183c25eb067c9af2c8 GIT binary patch literal 12944 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 literal 0 HcmV?d00001 diff --git a/example/storage/fatfs/figures/hardware.png b/example/storage/fatfs/figures/hardware.png new file mode 100644 index 0000000000000000000000000000000000000000..a5636d4138d74e24374a8fd7f1c215d6aed80980 GIT binary patch literal 702896 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�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

    BpSkIP?44eVCL+~@HK_?t@(sSiZa9lV` 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

    `G&ffd4|uPN~`l(-lwNM6}h1 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� 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 bH@g$>ZYqiX&4g125)lA@d$gZT|9ku&LD5ug literal 0 HcmV?d00001 diff --git a/example/storage/fatfs/figures/test_1.png b/example/storage/fatfs/figures/test_1.png new file mode 100644 index 0000000000000000000000000000000000000000..3bda1d0341a93c86f75eba6dccdd6c684dc56d65 GIT binary patch literal 43656 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 literal 0 HcmV?d00001 diff --git a/example/storage/fatfs/figures/test_2.png b/example/storage/fatfs/figures/test_2.png new file mode 100644 index 0000000000000000000000000000000000000000..a9786c6c346160a80d703d2e5c6af286e11e7e91 GIT binary patch literal 38075 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

    =MeNRCXq3juONTj($ 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 m%jv%--+Y~my1g|QwoQ|gN~3p%wE}60mM>ZW literal 0 HcmV?d00001 diff --git a/example/storage/fatfs/figures/test_3.png b/example/storage/fatfs/figures/test_3.png new file mode 100644 index 0000000000000000000000000000000000000000..f3f1014c46b51ca88c2335f5d100e15cf12638b6 GIT binary patch literal 27642 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%0DjU1AQFgj6O+PQ*BoMwZ6ox{@Ecz4+RkHMKU}C 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 YY=8PQA$=13ADQG&D*v8*!tnb404@hI$^ZZW literal 0 HcmV?d00001 diff --git a/example/storage/fatfs/figures/test_4.png b/example/storage/fatfs/figures/test_4.png new file mode 100644 index 0000000000000000000000000000000000000000..cd334840894e874b852dc562724d91883ad6e7d7 GIT binary patch literal 26619 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 literal 0 HcmV?d00001 diff --git a/example/storage/fatfs/figures/test_5.png b/example/storage/fatfs/figures/test_5.png new file mode 100644 index 0000000000000000000000000000000000000000..25a6b67cc779395c01be1868000dfcbf918bd0da GIT binary patch literal 423064 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

    M6L6f05w!F^g-@uFz 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

    sC1vj$BApQBWRqU1%6ZY7kt)yVc3 zvlE_RH9Ck=j68ZQMM`lJl{R(6?j$~jCYj$rla^|4r``z^O>)mu|d#g`fl6YmJjE`U5Gx`VW zbplp*S%LcZeyW0;bUngO$CE~fvd$$foN=WkoY1y7u^Q1ay%OD3jwsQbm$zTU0VGl! ze1YM1>Dw9=`+CXN{&gEa=gmq^Ot5Yk`=sgVkT3HuzQ)SqFYVlKDl&MaWO=AKP1-&R zl%Ih*u=Obp{TlWJORDSWnGiJ6HIyCZv_lOF5iPPWV*VzABsp3EI&A$AVmJ7M?$mDC z)sB`nZenI4pRk*;#CbpyuZ0 z_?w>|>18E>>7AylT1k2O5GLl%e!SLizSOm}$KlAj z+74EFDD>Lbd+NA4d#reNJ^xXVf(7h-f=gj+(!2Bpr`nj-Li#A&doc3ZBH-UhA+nXj zP7b@ZucZZqdTYLIowb$TXL!3IkY$_ba zGlcZZCT)%ppu&G$QQ=g)wSd>NsqrI@W7wv5A6^B2r+rbHoz7kqzw=HbOvkWN(B|{^ zwpZASJg?5&zRL)&QcW+a1-li6XQbC6y1IdE!g)50huTlJq3iac#0VT$87hlQMd_oc z_b-wG19Z+dQ8T`yH6IBSfae@4%vCGG4Zy)a(BxPh0AqdbBir0ptx%j-6s*4Wclma~ zc++p67s>6%f+tb|Xyie9#TNE7GiAhAAP?HFQ6jM?ii+RToue0r@$%VRs<8bZH@e$d zGT)-^qhqm58e)WYUaO^;z?m=2{w%>|hT@vHd+#(rWw}%}y3~T&73S7dADgmFsp=0K z0`Uy1Y=4fCTDo^-ZGw>vlW}>s=rMBr^FfxE)YG?Z^nH35W`LQg4*MCf#yGyrtnud# znD6n#5!*eyivvwcUie*Pf+`>FLEYLVz-|k(iLkvbYJneP%Qa_e;>~`KRTx6~WWdFIxZlh8kFQjpQ=^AuUNgU4-4zL65#xo%|ui zcXC6G_v~(`AJlWgyytt|?sx^Emk#r(=%&seD89P70RG3wrX|vhz>Aota7jtHy!7*6K^%ABL%Ri22XrF zP(AU+XN80zBC;*@u9%GwskKV~yKPPT6}+az>s4`!|5;vmGX=olVyF>(*w}gKQ?F8T z)vL7KNOUR$%E>>4M|eZUl3_bc6RpS`+G;(UUZ*IQk?VeRqwSP5wPV&6Y!QRfcmSCS zo-xX5 zgVX9pRw72CLw3xD@C&h+?bMVP#J9OwzYmszmk4I=OP2(h9u_AtQL@Ire_a}2P z+(RDPAxnK2MyTwltW#jw!#}W`Xawkrs)Q`DhqR`Is?;iAWv~VDX;o;uC{m0V@ZBMi z`)l-F0Hbq`2(HX;xw?lKP-?N#?pk8=FM2s=BrtQd=j9vm{Ip=y>zV}i zG1{>M0$d@+BHtRTu`M^Y*XWOE;cyI1u2(a%TBPb#8h z=<2NkR$&48+=z%qL-)!cv19EO)nz1_SdqPhtxs=W_;QzW{ak41f5D{;ui?YAXU6;- zv~X23y);;Qs%#S$aWa{}ZZBvdb}27T-+uG&%tw8HI*5ESbuVz?8dchyr6vvu?8qX` zrwo@4AG9R&3f^pRvc3+65oG8Fa}{N#zkNZUT*#yr;cxqcxZuulAbcy6<|$|nV`a-u z!3Ti2Y3udbhwJspdv(+Ny%r)f5LFu5zFyw6z;vM#Ep5}2woZR*EoYL;PN;9E!}MEK zOV_+0DiD-#%z>HR=1QuAS0>JntGKip=?g__drg>M?J@RT{p1QD7qt>|iRRKpG*nX4 zHp){p{bz3gTNJIAgn(T`)p32c3{Ru}3ocp;cO9ot(U+j9P!ae-w!SM$>3w=W9+mK_ z;`yGFlPZ2PuV(3idemK<|4$An%)-}k4l+(T9N}FfZ5TLoyyF0Q_rr68YSfjAB;EKN zqr~P+T~gqdx(L+{);PS{>kc3S?5#NBLBCe{vOa=RCkPNadA)@vRz;vtYJhn&q*(SV z>2w*3G+%4<^shg)-%N<#Kjh6F@4FihlGkOOk%=wK142OQd)t2>hg$z9kin{mLdzeD zFev-}F%s_q^}sgNd;5KT##?Y_HNAonvL5*2A5jG8!g~BXu0K|tY)IzKGH0LC0xp<- z9(!tmF^uJdVgd*#q9@mHjb9LM+>*dQ{&y0L>~Rl_JXUynlGhZ@xMT zUQFJ=g4U4Zm)N~T@&}_0{KD-sqSeuP*L}Qg%1^D+&(wu~8872|3%>w| z5TS~G!#$|OOXSGm+h#7km_RW-10afdDPGxmWKs<_Xhf+VdhQWZlDGndH84eh=R$@u^_RG5fY{&nLB^om@r4a!b9fa%KHKOOQV%OvS8g|n+eGt#`0AK~C z-uzU&Y#{EVQ=$a7He{jP@7Gl7B`}2m3viZ0{~st3??AW3MJZxp11lMUM<-q+O*G5q zH}Do#3xv-Y^WOsGjPp{c5we9N<;^gOLK*n}$b z{`)*M&Q0$h=;P<3wg`?Ru4)1(F{#g5@}B8Oh`sibR+P;q*(U692%LiKRf(l3K_FMo-8~4aQ#pxJW7Mtc%AG zz9N9N!8ljkp>maj)1pS;7K!bB<$n5iVk4g9AD7SJcj9;Oe*2wMf1+Y5P4Xd%W5+)% z3LJrVKCZNu{0(}TSz2fJY#g|DRKMAUHg=ji zstWA7UbS-#_-!!GNnm5fU4Y*}_}AwP{xvN=zxY2^$o|VjT?~I)LImu#*&L-L5VkBh(Kv?1~YQF&eEQYz*kH|suOyL0E0~S`4We*M}iBUt3g|(^k^~f!4PZyi39;6sOI|vNVfX-Tz~Xn>fz?SIB3@(H`9Et9 zYQg4!(?wfdRh>KNmhS$+4*zj_DrvXFLYn@f|092c`uH1g|51z0uHqCsOn3sbKniV( z%wae@egx^NbVeW+N`vNX)NB6z2zbyXFcrU+Jn|=_uEt98oz-)Hr_?Po7GnAM9`g8P z0tDKyAi*47taUi{Iv1kY#Q(l1b0ld^2Y@09=l8c_0<0# z0MRA5zg|&O7~|pJRXV!Zq+j3)*~t$|u}R=LPcP5J6fd=%C{@JB=J)l<8jyTz9JO-u zK+pK?d$JYzVQc{E+YylwDbg|{`mLGf9Lsx;szCMD@#gH!{jr|(%|%qi_@MyNk$TRn z0QZmB>8R$vWu-%nW4i@RZy(+M^-X>k5r<<@=2^6SvKhlsEo~0bVii2@y8?jUsC6p@q)4X|8_~z>U<33ivOIND)90 zo$z|O>s!A5s7nhwb+#t(?D|0T8{pVDNr(Q%n{FmwQ6M>PVvCbN#tt~Z=mi|{~h+|N+${Yz=u!&Ts*Tq;`kK(jI}4g`@Q>gFi^{4ZdK^Ex==Svfypkw zst2!B^dg3a052p}__7&KGMT#DjMNS|OUh0B2dC4XYugzXbpSVbrQCm>{0YJP_zC~h;T_t>J2k`1mrKiJeN&GmLppID`mO7UZSZH zkLS^5o)hD&l%nb*&B0BkGe&TUTcRovF+I>Y5PHnK^P+v*LyOwZ44RXm?MYal zkf?NkjhTKo9n@geXT4vH@i#c^Us{smn**D-{NO#|W5kL{pj8~i^x}l_B+x#bfAVj1 zuQSxL$nlTLc<~K^?yv~1)f&(g(3KGugv1s$AJ2rd?$sCi-$0>fYCaz>Rp+rP4dPi* zrS?*r{(W~gV}S|Ws*~x#*_Xwp0~)>I9OIo&0ZI^{x~!Kfmc*ukECJL8rQZYaU>26mr+l1)X_T>u8&PKsJuL30dI zhxQ8T&$Z@0r&DvuMhj zjihxiC$CTO$7ZtkaUT)5aw7@71xBMTEBjUWs!|ub|anD8VO3o`;;2tE}P80tYM67s8JD1A|!IY zzh_3?VDhT3XRjv~tr+RuBxi4@IggZ@uBSBWSKSE1UWN)$!-nsN@^j^?Gn>9~>}D#afw**J&f_1VT>U}-E!Y7R8^ z@y?xPGRTAi*#(|7D-&xEmn1xy?(Z)+7hizM+!`iWW~ih?enkI1lF$4vp~IC3Ys!=> ztJb_pJ6IhOJ2-oNibe1Ao?zqB9{nj za}$^efWt_;qMEvGM)?E`!&>%aP(Qwm5M3vz5HkYELzTNejzLNgowjvje&@vW{nSh? z&F@6sYN}Rc9$g0iz|w(dabu2CT3F34qJB-F7V^HgeVDHJ|B#6Q6^UUEC4;NE<4kCb?gU39(*)J|S zEw#QEfj;`q_PJKCunStpfmS>03&DW6M;I{klgN|DF&OY7{?E!Jozl7O;kdlqV?&4a z%HTsNDFvpzecH;wbus)k`e31spxJ2OpY)$+a^eiEO#cTY zgd1Y~6%1ljHZ4Zqx!)M4rKEVUKV^w1Um%Fmu`E@$4-yR0~2Pt#ZLi8u*?V)i*DSG6E3p4+qnI^KGY79lE*6>G~9JevPt16wnxq+Ifui(!Q$cu1~qL~ zn3=;aa>7*sKLnV1+Mlj|Mhd7#mb=PZU*NGqNXOLPQ)DKOue}{w9O~AoA9US+f%g#< zUO86d*PgggcN@e6iqB^Z(ZgR^tDSH5ExUg4B_gb*hdZA1afbAuFm|yv`6kse+@WZI z1#NnMAmgVq4ax(y2p1c{r%C)T67(_0X8=ct)=!7Jrzv2aBeWoJCRI#U!?lgXQEZGs za-rrM ztT*u&>Jm^{1_#T36s5%d(LV9t_Glqjud!@cBAB3$j|)gOIiTHY2DZ8EdgDs}kHN`` z;c{KCZ8!+~Jzwnh#eqWmT~Z~d&@A>})FO<;a=>c#Iq7<6U2b#zCTiBn07a%a3L3lP zu}B~SyFGe=_ztul_I(pPZlpXG+STM3-d2v*Q8V9Mx6rvns`II5^U-?DmA3)nCKS?E ziX{z4jTzCgl&jSZNLFOjU!#1FdKRdB@H$wQRqo;7g&z#%EN|`tx%U8(#dRW%-H~NN z=+~40C_xw)jAi~zRd7Uw|i*#0_|_0d%2_xk*i#lI%>bkBSSQi zZZ(nai7XK?&*=>7umc#yY?1fc=<8e#!SKl7Y~+h~*ylO4__pv-KG2vmi>1fi3*O6F zr$03+c{pr4nvlRX>Wql_pBO8%h+jsRqfMX!y|tlvY)psW!&BcoYX1cNi`S#3lpDu5 zzH~O(swCdTzR$gH?i;uUvd4X4WL0U@#A@QLmJK?S+( z2r$xG4aGIwzu>j6+2EFY&_Xld(Fl=Dey@rLit>JUO{E65!@(9dCEXpg64NixtL$~> zvXJ?|iWHd8!4!#Q%uJ2ML?oBf%93ZpN-D9bkA|oMDUMXKIr$daU<#7}C_zlEw*3bU zc)?81U(55GH7VxIdY%MRV+79`i&l4=^|M44M!!uu7imh}x=g`n2xv~i+4+`FhrK7U zhBM%pnabS!2KIQ!&I;(o&VQ&1P-tz8FLKEqU^E;EzSJ{{Eq-d1_4ky2XR!q(r5`G2 zCidwR^3HijGQ92Kr!^vF(~pV~h*sdnzv1YBcD%X;rKF5hoQ_4;Aeue%fVl8)9{S=^ z7s=mt(ASe@P++f^;AWW%%*B3lM&%+!3(tf|W>|i=;%T?n#N(zT9we2PHdwI2``n!ImxJILOhc@KCs<=WhggQVLWMtU>$2r*)~QZJ*K(vJae+e(uU~+gs~6 z3>QT}{%M-@tdtJ|c8O(F^sA!+?~f)ZKl7IL&0CzXhjIPyB*E~ zd}1A*fRU?*^ctJ>4=x>Sp4?sK((Q^_EfuTub=Ap_y>PMaFqy_~4*foNh z)E+4ngE2ey34G)CTglOAc*F@_`<5745B9KJ?9Xv&k32G{oW(ZM!V|3H;x15}o(>&` z?$UF-zH z9A}K#B;62?y;u{dAVsM%(2_q^w@N-(1;|ky;j+7H(GkX}EF)cX#W!8ME|+gpY(quncWMXnbf#_s5^Q-55hX{>J5b+<|%RT(QptN;ul{3 zdFl^;ts(x!2fGZSW-LlA*tyOZe?M|fNVhtp9B;S%Qqh==Lq1WrkH)iFqCHYi>A7zN zW&sQc3_V*OaMnIKtXb;)$kDQ$hL!4dwpPBhnyUbWe*?^)L^6(q4Zi(4f@5h-c(?U_ zGBJ}OLoSO`#F6H&KGUrLKxdl@(s?vhg0$k^5t^HTjpfGmBHZ>OKja)WUqihCX3j_+ zwcc%kb(>8lIO3xnz;_g~QPi48De4=(J$^A4Y9zUn-5l0GAQAPtaF4y>j!j|Mt!%yDI`*!B|S$yk+HO|cnui^-66`!sp6 z65CkRui}W>lKwQ;MhxPGc4?1|XXen^8(RW@I5~^dX#DYS%f!?nGZep5z~j|JpCb}? z6DUDt*^tot0|0*2A3!z=C=n_spJa%5YzptWH@gAlg=p3VYu3dlgCU{uYd4(HTjbFI z50!Z9XiPb-9f9ofQ`MoWtP4w!TrEolE6H$rZ4r<);(R z2xYxh{Q|qqqnG$Q1SES`&n2ID0;?FI(J4gY7R}Z{YAErps6XEFC$uMKd-$-@vbpQ# z^ycV2j}IZCYRBikD;Mub$J<;Oe`N!zj{wP`Ke#+Y#A?1j)9{+}wa1P$VO2uMNt$>j z%6ZwbEE|!$#e(aEwrDE2g$>>v{{ipH+Q^-~M)lT^h#K@r^6Ou4xT&)mh3(#LQOCJG zzet@DM@p3Q6kFBO>Y|5%7c?%hF|{%%@I!iwzB9Ivzm!!oGQ`mT>DMSIOt-|@6o}nA2m7B%A1k@A6sV`6-UtY z`{3^G?ry;$c!1!+eevLK!QBGEgF8uBWFff2VnG9BaVI#z-R|Uh-Vg7&_wEPIVRm+Q zrnkGgx~uB<@2Ya@ezlX)8ta*T)VPi%x;|0%cPH21$bTrQs2?-R2<0#C9~;r=x%MNr z+9l>_Cpl}^S3?pp78@8{U;Ljub3ywK1l!~c3*u}AV^X0fK*4l(Y5gWzSU`He)^vEB zrAi)Dk(Jpg`-d@~<8N7pZ8;&aI5ZC_mZ8M7$|6_s&_Bv(=^j)@R}Hbp+VD+8J&HYu zQk7U-{E~?2J=<(8B9f+1G$eP3J02s5Z4nwl>b=BAk{9hc5vip{BR?o(pC{u~z?=3O zDYM<3uwPw1!t-?8c)hfzp}c|O#h%2%;wN@hj1*4$hAI@&C8r!^nb5x?@^gu_X=NYz zh#cD*V0sKQX@A|7i>;l4ngqLy$=_Euvvcn|jYQ3IGX0X}5+&sryC!Qnjv)Q@wpjCf z@flOf+U+I#9ED2umJh<>oe?VX5T8?Fbj;EC2Q)%;AfBp zJ$~R~X;{pvqd~^sDrb_aRZ*{brbn1Y(S3i5Te5y`XB1W&J3pm$B zB;l5_sjFoXwqXv5OG6uZQ!*^ffelDjXtp;@(E~pLP?;2f*^lE(%;hoE&xF(vpBItm z_F1=u&ZLcAuhCe$kM$Jp!-mR3B(-)7b;o@zQ#(_fo6278O#J$RwIW70 z#ZyF6Lwti>GsXQ-f2*U)4N@S@6q+@Lp#dzCQB3dYgvOE zGCJLZsamqIup_(Ueo|pJT9Wvp0;Y*97l=XBgnke!fRthDzbA#L!x8tl6c3I7RzWkak$E4n`^EZ!ns>zhwl}Da{Rur-fZH6Hl)}nw zD4e=xV<^lIPKfiC?lT{`FBwJU?iXX~!UX1Vs{oKbd(5DBt~ZW{I>Y@y`dh6{@%I2r zSoPY2Nw9!*+Pq)vZXXe{3Lt@yt2x_&TKeD|klc%!^mrXLglq~Z6OCcj;)Y0-;mZ}% z!6L{wB~!d@-{qwiUYjTu%8$2&=|-1 zsTarws{HZw<)-%TR#_}*I3P?-lVefmylVs;0h>)cIf(Kr$(Hd5{C9Zip$>nlxU&my zO(^zM+gT|SG%tS4=5Nl)b@0-RjCOE^%}L3(_LGpHYL;fvJ>{DnGOX$e|zod z%4G8`jdAwN{M?5A>?Y5j*J=_ zkPTlP=JR-3A9JL{_vHs2VcSQ_TXTJ9-RV)YM~!5prgy2;f@`&YeTc;}Wjo%aMX#TO z+s8dRH`m2i5hW4`*QeKlMT~k1V&H|n*O{RY@_B==($?!n|kOPjq|(P&(lENxqG#Cy@(vhJ*&yAE+ADE__IJ54Tdv+|=>kEETfOvz>)pv44LVs`cu z-a3a&+%M?if3rkG7L!_d=~P9V$fgM-e7gpqEm*4XpjZ-KO_`9@swivz(1t3Oou6Jm z2xZ?7$r!7O9tN=5%K9mV-2jLW@01(*uSYULTSSMovEJk~o*4@(qiyR9utRckgNK)3 zZ9o+dD4)~=Zea-xWheG(sJ3R_d2kXQWAF($HF2Vc`){8H6D;JVgeX~lD;tf8eNn%v zu}1_5UZ2z&g#11hS z5vSy8%1rA_w2?Y9va!6!5O`!FgjV5qgnqQAd7tu6WX%jqu}+u3ka%Id4O(x!hK^riP@NDku!c zF>lTnd5TwV|M@7CSYAf)Yx?Gw7ixkk-@Te8;moB!bac^N${$}Y4AT0cDs@;Y`<=zZ z{RlzMyavBW(OL@X1LTL+?GJ*VjoIr(m)mHKc&#h8t@P>3Sp^c7K*Vg7a|@IYEP!fYuAd}4OB!kpN4b`eJhH`ge#sX05EEjC_IBkB|54Wq{Zb8lRW^i)~ zXD&BM1U5~L_{C8UeIPbM;><@0-mQ&#h<%}9uHJf*Q2kSEC4kk54U)AKiZ6dpW_Ga~7f{-H{ zgg1K61ypQuKt>t!PzoXHb6Ey2w_FBmlUCjE?Y{M0z9RwWi^0^tFq67N1P*hJeIW&1 zBLO2PF1oCVlJXe_b_>-hi2?x)U!eC`u>I!k>G=mmus%>I{&cDi`^Ga86H%jbEQ^O4C|F};VTIwqyaktRMW#q{T9;-HK|;OoJOO*gJc5l0$D7tv8- z^}kJap!4C=*)F!yG>j^2aqQxt{hyAX`o{eT{*|cM+t0L!_Msr|O`Ts@C0C{3r z--$H-1F8AH{&W=?{eOu$`xw9nsJ{zi+_up48%;#{`4LlxDASRA924VtNbu#E(5?RD z(PDr@M~y|NGbUky0sXHy&Hujqe(`q$2}@#)hg(}D8khY;l6%l|@YUbz$-Q<@F{%CQ zHGbn+zWd=vt}4}~B_EvM<4wxGc|%vOBC(q#7K7Ps7*}ewr|m3EoqwT)D1xNiP>9L3 z?~QABI81WhlkKccEpGL*A>&>{mG0ESVc!qmhk*LIUB`#20Mq=*B+t9PyZ4Uf)qg*{ z)F82wJ+u$n0%R#&=ZBZ;i*JHH+1Dp6*S~?;z|}))&F^Tr`RT)P)o;1U-RNVIqbl9T z1G^BS4`k-u3Li#<>3deewFGTcj}FDrWJ8`1*e^ zLS9*bdS3RiQU8`vETQ)0TgE;85444DArZ&YUv&38=hYV0o9%luOqvYqSW?Rju{vF|-3n(y0v}sfelK&+ta2hkl4*PSy5M_fn z?uwi_pg>l&SbNWzOsxno)sFj~!*&SO7UQR7#QFWl$Q@-L#}yUv zaNhQ2-lcKueWJPRk`17oiC@7c!p%h!L{v18K}EAmTKo`?8SK3P$M zuPvsmrPbL~7p3H|Ogw!@P;WszITpjw^_Pq${2ILz>{#zwq%C2CW{ZC$967Xx+_CsTLgE<~Vx$N?gAP8xx;`zt zb>+*tyP)py!xW(RUc8?Y(8WJ?EWES$Y(Ud7&?cF8%e<7u-(F4_Yide%hz|;S#)bhZ z2n{pPww-uyGRWUs+a(u)_B6&g(>tPe4<^W8c~(!9!!Z|B0N}e0S~ktNteU6k~#W{u3ydPi}MeTGbEZo>@n-LDrPbSJwchDxfo;cQ%IkCk>@s?*}#gZ814i_jK=zAtZWUWg-N8HQU=j~{T z{N4X^sI@Tj)JIwlj;W!#2F3D3@KFy7k&+r&Frp4zV|nqlZw<1P>Hj%zrua~qqfJPM zG@*P!-(g;IIhn0)p?E!YA>Kte$@GJ?+;Plunp@KM-u*w}c9a9N`rli4&&G; zH7^St6T}XYN?3W)2wPq{Ce7^E;nj9q)vw=G_5*i*w1@AFk^tZ|)VDyDRndB3s3N0c zvcV^8^g2MB{9c~@t5PMNsTp+Rm(BXn@|U*xGV7m?QEk?1%2t;@%^V?gUG=eBsX>kR z0QLtU^f2aGX=*>1&IXe#Nfpj(_lpQ6Y#-3CrlY^3S>xRJC>c9{#7bzrHnJ$dIekmw zz$>yPAK;8plfS0F zjP)Y*3`kjH-CRLH*uqir&#U(1brq6*cigP`&^arm^e%{Q+NzJDXVdoVzUDH9AxAZH zC7VL%jr{ev^%@Ia<`Gu*ISS;*)hXoVnKof7%6|+~t6tejNR@D}@)`xIeL0HEwvlY% z{h;%3;=nCBJZbr}46g9V*dQ=kflVZyZcNe2V9EdXt`1yDMLH7%%9nG3fE|IY@#P2T z&vw)Mkm+c=r0|+JOlK&u)f!K#Tp2|KOa7qV7r=HIn8&I2GxFFyrJ63Ri@--w`i#!o z81O__SfrRi)H&;~RanQ;P`QZfUWmZvxQG60w?J+i*m2Mn2uvo|7@AuePWpj0KL_1# z!Mybz<{%SJ!rgfC%Z3x&GtW%z72ib5q^u-E_l{5j(vQq_R`AVq@bHd&w1IR8z|!PA zgt}NPnhgGBI+O%-$1e-=5UH-M#r*{p(_pc8#9tB4O-0%a)FE9@|6Rg*iz#K6wc-+Kp znwC{J4|~%ZN+}n?pw5Ow??H_IU1s~<}q3Eol*RmC*T3^L$CO6kPv|IxI&c&{g6 zXp?^p1Cx40!Aq++)m0MLwUQ5MfhZgLUc2ckVvbeL7v0i5_zH|1WhS9?y^GQpLpeuL z_4E8Z^f#PJXPJ2xqtQMebMrFW9qdo36G|jtPrHFJwLF6&80F2rp;8YlM1A)%IM7#cDw{N%i&P~lGFCX#^ zEzQ~umfVNRS9Xn|zEv)aO3t#GQ~w&0PIl~{x~?2(?ik@t zc|Pv2(4H3~q-k`1O={IO&Y&_h&{Gfbn`~TR`D+n=jCqhjvhfD)kML6dFhE>ND`oVO zhyd4h{tkEAU+S~?`WO+Ule|CJ8dG4|7V~Qi?PZy}yo~*om2-v~^;{(~E8FyX1`I94 z9VxI1&*@=2d#_pvhv^YLB${i2ceg+BqVdekE3VOgieQLCut2YW{xsX-I5>*?N#sZI zSj5mo?xqAWSEoHb>6DcG#nb`%C;bS6FEf^9&3J$W6Q)8#mQ{>b8*jpqJ&oB#(jNKQ zbc@m8$cI;|K3HQxT=rCD)~ufcPwy!0D)Fdx*7@vk^UhvPGr=y>(6dGI?FA>TnEUI3 z{iT!~R6dNEJPPt6_P$3YBi|)S$F&=>;dKktls*b$7_GalyAVxG2CYJe)?&R|8R8`% z&jkh=mfo1} zCHT^t)T`uCPoT^#;mm{n(=0${5>}nRI^_LMw1pF-hk2)CzzkdC5nG?Tlv5e8e0opW znuJmxoIccKj22-Oed3o^H!Whw0Gs@ZvvSUj`sc%sr8I+L#9W*F)SF{}GC_9HXS%#W zYl+GF;GBX;ooTo(*_gizjIUWOgNN^UM@}l_P~%MEl=#JM8xlAVWB4$R9*Hx(3pk<> zR74Dc4Pn>$TU^}3$#m?NbA=<^!@v!#F}IwlT0S{>aABTA%9W5bjQN4}?DuBlMBMr` z`gPnD*Bb6%pjoN0Qk+ZZeFVNu<`oeSWHkc&GqxHs34K)-xVBxb4)-ws9&HbR%+DyW zpj!pm)565ZsG)JD(N}*AsiFgOf7#YsX78*y!Z5I{6(6(!K2hR*>=jcU{-HuHx!hB= zJ(*X}xe$1Ul7TfrM!f4|%F0ZU8wn&!czcg-xl2&xO<+@AQKM;tb}n>V*Fs3~N-*k@|em_l}>x za^M4JtS3Kh@uEx{7^-biLH_F8$k1n$T8f3i>txsZjs4G>s_k3-rZTdUV?#FH^_#Dh zh-(=#?v7-;N(p|=czrcG*hEM{JmoW}E?n#DdU7|va=kr{0O|!r;$E`?#P>%c4#}ur zgJM{(8&81XVEyI@|Ed;lfI;FvP9ir*&RsFSfSUR1ExJYa;XT>9Im<_f^Ptc+N z;e+|HbQA5uT9x==_L;u15J#QX2CulL{Dp#0V=u=Pn&L@Tbh58Vf}}$*0v}kJj<)=z zNL-W|Ix0oL^g0-9p1tN(^%h>sMZ(e6KzGWMmNhAN8e+%^Z$D)`DB_crsYSoUpc>pt z3MqOR;kb^n%2>Rg=Z{Ep>;@6c9NyBb4W45LQVr%hg=?BM#P#w}4d(PxXXdD3Z6F^a z385Q~KuomjguLJDb=2`cF&>YW`J0|^o0@eMGRX{Ty({<=pW<)d#Elok;5#+qOS=zl znEV7~9ZmY|@Nt~P7*r^|n2@(#*}$HkUb}B;_kMl98D{}cjc$Fz{tp2I)2GTN_L3{2 z3_bv^2$A_6vhG{-4u*|P}qJBYzR-o zP+`>3!)z9|d?Sr!nj#|A@k1Iw4msw;NWn4X$*FT{KK$ld9;?gk@$e&!pyJvSTHqrr z_TRGySVHg<=h&QTK(e|}sH1nOA0)gXL4^28?nU}~^??h*x$^MrSh$-fAYfM!C|eny znJJ2)G9enz8c)VR`!+q%Vq&3w`tmC1q*DQ-st3RQUgDx)Bj)6H5K*(E>$Op#Hww%Q zV`swW^0M6mrySrOos2xwi^g5np{hv;KucY=_sCtlT6Tg!!M)gYe4}-%5!?^(iV241 z?)3buGFU^hapU-aQpJQWF2q6d(u7-#wKX@^#^rdjgdsg!`4l{)5|@N?=!NAoupBYa z(TDqH_*--)3y_1tmo*j)lC&Qx(TxuATC^~|hu+smJjT39)U(4)*ayL!)3Zm;f*xKW z!xt+x{Dr6#5wcD3cfr4K9lBF;ec@9Chs^QC{xV3ndFpQ^Nnpk!#3x#0(Z~I1z7!&1 zLI-2xo8dTXE}(nIs9&dlo^!(%CyauTt#u>AJ{PeSPZvBIfQo`)WFYk6k=_j?RmkW= zAhMP}@FNc+ZW?jb3G*A*;0gYrIGoR_@OL3UZtAE&hN%A3xeg6?%33wccT-582a!i) zDINduq}#`tj#{@h@egZt2~dyB8-i2vd)}I(AR38p|3!R#g8|lo?-u8ZdS4-z=7avZ zbh#9$B~9*GU3dphe$y;JxxNQvv4Qksr66$mnPg?$bA~Ws2JHDo@?Uo35x)vK>)wLx z>>xtSuVM^#=c)U}8Ww58^ITtLe$sOT&(tAFLju3#$oj~~5*MI_f7SroN$6#_i^X1% zVMfgyv7=;OK@n52@yH*>QWB*zuV^;~6iG!Wy%tIMn$F{{1VED3S?f$g=vQO-kam?L zWC;I2-D<)oI-ZKnIdF*e5kvne4j@pyg#HvxL*bS5^L37$fw`iayaE`*P+C$0NPWo% zn3IJpuov~@o=- zqK{5}^g5&hf{4M#mE9*Lx9rqR()oQ40yxB&vcu&cyl@XUKK{+QiXfs4z$BfnI`#d8 zp!02>0jPoa_c~b9DvW2blR2tHF19}me3a=jkf(nKve>L6GvWHSb&@cXmcQj<Bkx8~qbvC}Ek2Q#k0JZQggjiAY?DImM22duE8Tc=F{AP;&hr75KHc`XCu^D<%R2)=wSG8 zIqONAi)HEG@HPKf;Yd?39gj-<_aIvNdQ{Q3O_5nA){}? z(OdNIB>bOu9&oeao)0nMN_+O_pGn&RG$|`u6=s z7BSaR9H~df>ZIYTz&M#U#@JY-hS`XC=AezdoW<42{kkk%hKE z5M*aqqXh&DT&@p`?QR_V&`V9?^gD?YU9IcxraC{mcm-xrctD*jSRmJ7E%;f; z6lwrNv4OulYt*cDq74}pyRvb?T%{B03gnJj4IICJ=yaclN}RIp!|)F&3L#RiI$N$n z=-HVOZzaR8F0SyJ+y?Y7``>|2R_Y5Z4QYhGo$90^BS2X7lI29qyx+|HM(A4n6byP= z&-4y}?aN^5gx{3u#`Ica-YL~}5j4v!E~6FyLPLQB`;3Z7w#!R%sxW;Ju}!Qg|7Rp$ zqaH5N2_^%g9pqgG=<*$I#{?0(nF-3h>vBpp=+0jvqv-}k zzAJi@Hv8#IzjuI-8RH7Gmn0pG%G2#n!r~&%x|KYRWg%s?3d+vDD2+t;Rh??`->l=5 z#6XC_*x$eS6OWgMS(K*HS|G`xdg|<{lJ+KyX*TJO?IG7=Uy1ad!zmaY!qB+^Y!JZkK(H?I}8VU;K zhrjjSOfqUt>LgyE!lbFyd$^gTxu#^~z_lxN!OB6cVuSblC+5Qzr(6vFlmkmEdV(&gWOk2GLs$YT5O`!=u|e#ZiJUuEGx))g?X+JJdQQJqIKm{Nml?h(T#5k0=h z?TN*|Hy0k_wS8amEkFF{TX;5=57+hmQ_YP4fJkwrh(dgf1CcQ0@q#z}1`ffC8RH>9 z{X8W#=)>-@3vN3%8e@>jW2anLfhZ3=N5ZgwOz}FJh1YnWobpY(HrxS;Ba|?8%PV$26;eE1`_4MxYfmzM=ppT^>e>GAq5ml1zw&F*`YnQZ9r4>!ggG+z-NSd$?;NazE&CV>pMo=NIl$R zwF759&ZMu2kUCAMoc1}-2ZCCgLuWhiu6RUK#MrXS_|CdgX%87?l^19)L1$Cc%~CO1vxH+PuNl;J`rTo!FXI!KY5~O3oC61YMT47TgEegHoLHJ z9!Z4VOT{AZo3XtK@w5tAx|z+ABsbV}uucFjQSz)lL8f(+im|XKA&#-qITPtzx6! z2$(bX#mQ#D9oKalA>}5%M{9wvKC^#yQE<7RyyH93n?r2cdUI=ypb+wAnPrAIwXm>X zn_VHX^Uu^nUft-mY!3X0CFXTq6!qHYP=q!9Xto^R3D_X7i(W}_($0Zf;?4nm;K74h zH$?Aum2W~ zEjC6^D?Hue1u2-LKwP{)@kbgiI|uNGI(neaR{1q)`E8BYPqsgV&uJ;Mp`4IF|52b& zgdqUQsO>#(ZCQ$;C&O-W>%BJ(RBpzA_MwU*#ANoSnvx4#c=IIpLp=Ew3|9*XhHhP) z;vUk&4cLdmkIxe>fX}$*!$#*h)k%F$OV8O{OLoOrr zcOkCrb@ET9I{gv0y~&#HAv8$tpD9DrRWDxOIqfd8U(Z$4iImAWQ;q*Fpe^w=FdtMN zL$)M=s0U4sU6c#w^DtDjG%0rhPv510Y~_X&xA|;qCCCwAWWU<<$uh@4+MHq_TRCpf zhiUAy$aEp3YeS&4G|Zr~%g&(t_#tL5{XQ^=6yd`^CU6LQf{A;`30FN(`VxIM(_mm? z+#3j5DWQe2DL#PA+dBQBzy?+jOfIPV6%WKr>ug&jFBzHcaYpUX>jw&Uh5$q<*M&|rR%@`=lAdY0L)_{Z)hivypiy|Zw6OE ztfq#HSVOanpLjxZpp?@)c3R@IQv?kJPu{pAGfX9a66OIy%0)%X1V&cB4m1BgCzBzk zoP8QTS=i9Pq~yohE0rk*VVQLkD2ROoIfserAR?Xx%?X9A#V}`}%oQ$d9X>pvpS1Do zl=e)#iwbcx!M+lq#&7}rc-r`@&0f(+lIpqx=Y0JJ?aX2VA(o;FFAjOmW zKQ?gdh*MUb4hh-l^nuDvE3j)G-j*ei_k8KBpJU(qY@0I)!{;iD@Wnp;jZVEENXFF| zMNDX}+m?C-5vv;rpom19Z;c%w@D=#Xh_C|SiPF|4GD*RvykD#}CARiu^c@!A^{E2{ zR0rm-!>n@q{F>~U`sAQssn`R$9SkjF0H829TA8#*Q4qt?mUtuBElRKT+ z^{u%97_Em5A7%xwi`#+oCtpX1bNc}sc<3#V^*i~$w}hB<~Y(yPecdt2yJnoWMP;BF_RlM7uX96U&HN12Q<3J#Y|0t^4_Z(q4}bc;BH zHBZN>x515_K&yq%C7HxZnR{R2I#19^m-Z#xn_Z@J6`=l_;*Nyoz7Z6QxJ*ayp1leO zenMHWuQKgbr7>T7?(@{5Pd@miWN{YE)Bf=(HT@7>V6esvtK{T=Y*a_J8QF{@>Z{@QV!gMd zhq>wlO<753SAOKS$9M}-KsE*5Mw8@%iX~Nt*~7DFQ8;}7b(*5d0f+IZum~Tf=0SR- ztAk!Rcn#C6w$Yy+FFns^VE?)!`G=aPO9R0~UoD1o5Z(us0ej$?BNpudfj7+dgRdn3 zHQ<>JjL@wSItR26^zVi3Y2G#r)z z6n)9fU>vLXG8RXk5W)QR4)nwE_YoSsq&AV*IJZay-!>a58<~W35kT@0iP&;_m7D8u zl$vHo@V%7x+(mrWyU~x!Zgu06o|yz2EI$MF&$R?wabN<=?2azJKMj*)r<%Q{n8kUt zyX?#Jb9|SoA8A88x5T$JfUpI1cC#P2RV_t40GdT0;2*}PzPC;m?s44LGSwUXyWX-F zRw-J&3<>cjfO)OJ5e_l`_KCGPp0qdv{miO4I($$YXwDo*iYZI-2ua-D+)!$C$SY|9 z8AISlAim-;FP-5BiWW{)Y82TkB~`w{e>lCr_0s~zJ#>`CdyhJ=U%n^#CYUIIb@)4* zv4obUCM>jIL*bnrMxo?;W9mFk_FwX7x^h5I2gp^6Jyhm{pwNXa#kjfZAbWOW3B1y# zVuIywxE&eDL5>Xuxv5*qay*Np#2T?zFtf|?0X)o>6tb+X7%}d)pTrvWCcdaW#_#B4 zk5^h(=YEKNI<3PD3Fwt^{nss%D9I3?CA7o%Zc)l_lPf7tfvW^e%~nS8)`dASb+huz zc>fGDR55r-yUk4h*IiGJ)~}drpo@apYW9#2Kq~un2c_Obv@tlH(Z_3_f&{A5&=$F$=w{BsuMz`Fxr5e z*IP8*dDKSv*h1j00g{HUhUdLVG`!{Ou+MS!tAA%oyRCul+D78N_e0$hNOt(D+15N( zzq&L!H2QDYJuNtT;f!1HulE}lqOVAP>;PKobLox(LxAFPb}{0~#8p=Xm+&W&?2K1I z_ME_bMc3XaEd+2a2pIGEx#9d zRBLSz!Br|u(}H}2PxRSrw0u{$#&0_2UY*YGub|%E#lKI~Z=s4=-}Vb&-vdt}V!!>9 z&cIAgj5nUCo$zHB?Y|ZxzcM`5z`Q#4iZWPDY`y;NX$(1a8Sv#)_IMOUnAQ+wa5BZf ztxi7fIbfW9e*EN|!aWoxf~Y^qfN{Pm+ydT#^TOu8s41!r?I$Z>S|{8%Iab+ICDy>) z1L6(d{d>v!2CR~0t%C2?j5#~5XP6RLj09(Sg9G3{y+J*R^=4KKGy-~~;&FqR*Fwd{ zJADI*V$x%TyZ!U32-in1$pA`>Y;4Yrar}YI6^YqQu7Y9B{>Qglm!KwXSk-^lMfc6K z`I{qyKj0@R*oyB}&LVwvB-jK!2J?>F+^@`VPE&2&jvl+Ht z4S2JCtO_d+^qS%Ig7-~9Et0ap4>RzXJ4(0 zrzatgu5KXaVYIze=XyCL(pXJl2-#BbGr|aV=7_YC;w0=|db*2-C=8^XP-{x?5tC>H z;}FHOhyhGJbG8DnoIzd#)&kZ6_{Z~%P30_`RJE_vIuaXzVVM>XQ9}FeeHPhY9C^So zKrnGiZ<5SfkjKsb>k&BBIc`(=LUJIjEn1y?GMT49!nx=_r>&ag;s0AICF8IboRa9o zO4a+Fuko<{YX*6P_Y!xLD1;i>kq3~0v=`t|nS#7ki>AaEe&y53T0#w@@*O3{_dxA8 z9oBzt??=^fx~3_K#=UO3reu*HC2g&01l(FA&`>WAp__5p29uH{e*70bn{n(Z1H=$1OTw-0!${4K<$fiAYBP;x!<%pUu5f7zw>0^Da3;1&g7Yh%^vmx<5^5I(J=KjCH9-ttS&>o z`c3~Hmoshj)Bf)SAv_JRENf7fR26>+T}6E1kEK%HUfpS0N zuodKK)wOQP_52Bysg$XV^v5xaWmXq1n4R6!cntZqiADfDo=jz!D{8I5`F{5*e4tk9 zqnU*03E-s!_0RNXo5)ECL<~m~cLOU;VBFKo$4sGm z+9FV7F!GKKMo^@kVppAEoKPf_uzb@AQ*_@JP8m@YSEFy?Mmw$iECoK(u}p zupq%Q#+0Q1qi8fMaaaP`3=<}Rwnq|8OX2-@rpuB{Y5jPrYeYGJvz5+f;)^zA`fq+c zM3zcVpo`>J6)B2rY0t;`=l8;6jnjYa)RG4xcF{wj0FvtzFwNHXf79hiROr7L_8fFj z*B%DYvHqJA%9W6U1S8&+gI&kzUzZQe>{7l3PX6k88<4GiXfWD>OFp+=$wD~{9E|mb zpb>+D8t7r)y5qc)<_u4@9+;;rj zr*t+^;Tl~<|J=Ns-IWw|e@HsoI=f3)OV*$g&@kkULX^XHkEi-S1O78ubzd@prJShY zpqbOF5K0u!eq;Vv&5QDOJUYgS51Yj`#T3_G?*)vyW3!6R z7@NLHwHMSIE$ZUQ!H23FL=ZWsHBUeYC8E50c*0fx_yIkX$#48*XdA}fB<*`{&Q(z6 z-n1bD8bj?gOW-a?Ho32zDw3_uj#*qZdi-PFmvMtUOOom`+_>;TZtZ&JAmElJ#e9Y*}GD+`{RN5ez!QbV?L9S}<#| zSZQRSE8%OE7EyS~OJ(#v*Kn1J6XA-wquEUw4WubfPP#UdftX{wYz26?0Y&u1gm5?J zVWYy(IT^S|Rldst8z?*46j^?>+h@-=AGBNy-eMM@4o?d4>$5SF1Ku-H`uHfA;y8qlA95m~Dw%{+K*4yn%~TdLw9R%nUD zT{TdwsuSD_iKDhh4}!9&<@O2BfpvED{ja$xtYUAA~i?y3SoikKWkKO6QcsF{@8U zt_dtLf*NIDigByRb>~QeX^(otkp&dn=WYq+%$2PJ8^i z_{m?KvA-dk&c}7vrvewCrwxrZ$2(`w8xCPZs0#&3?vyFYN-><=kDIFdX{DIQQqFAb zvzGW2z$dy;u`6N7L|*#u`+AD=NsO(B;Jg^My~EEXO2XlWpr=>^yVq$hRexmp+CK_! ztQz;Z_rw;cqqPXuP7si=0KVu}gn?bW0F@g2R|zfoc*8Y!t5K^ro@u1;4}=oXdnCx; zdiJRW=IBL|((J0?;6S)LB*}wA1zap(hiqBbs~#qL7yg7M0%&OHy`h*`zM6rG>0Aci zYop$6!@~!vYnsRj!cswAXd_xS<%3bi4BBy6AxhRB5LuOg**qsnoiC&_UGd1OC%U8`d zH7)H4FTg^&q=D_!{VB0-YIIwi(8VUvS4CC(K^ zA0kY8WinchvR_s!^uNia<0c%a>^ zqP_g{xwt34QQCYU<`&l^{q(U|5674>vhiO&0iOx=JIlB8Sf8PA6T8A5{LltA0y0$Ry60*6dVpDKY&cl{*}2|iHEOCa5<`j@#FPU5v=j~VLTPLflBi)qiH z_YVzZi9ZAB@V^53QVs1$4-K4B&}{v>_qQ{S2uBWtdZOvwM%?)d zzSLVmA1N2EjcR=~Zl(jSHo(B}=z&+O9AN|r(EBRIQ!0#X6_UnoNNlO-`GV<(>x_B| zm_C4en&a9wmds|e4RWS#7f_k?weMk)?v$OgP$%OII@WHpmE^4mZ)wGNjH6v{rPuS| z-eyksQvoLo?tG?&0rjG5b?}>d*nVSsQ(w4`{$&kAw}~@cGV6kKmvAHo$2Jn2#LAR&%VBF>f&b){e0iX zeCtODb7+#elG(5P=XdCbxHt}xV?VAG5Se26)Ow>GvDPOZ0>6zGbsZL~Ek&qUk&Qog zC8o%NKxiLSeK^6o*IB+|=!uOL_6qv*ZJnUI#>n`?9w(lyHzD8R>a{E|CC421ri-T6 zdlm)RG}8So-;A+5A3(QcRVn=*yY}XA#L|JAv%n+6cRq-_h1KC~eIouY4CT8?8Aw=w@}ns70qzDYZRqs!%?)^mZ_r4uE$^#(ee8$Qn31$=xP-I0Em zUji?MnYMhtSo(&|XN%jI^(e@&B|ja}$GM6V3%4_t+UI3ltCMFoDj5-o8WyORJaC^E z$PD{#$>p(l_DZmvc zBDP}i*fYrFkQ8gf>|gI`(O+UibzQ8CMvlXsF>Kb+e0@1VKhGEsQ@V>%H$Qn2KbYZU zvDLgQ{KBBete*V6xKw%f>l*@Ln8<~1s()^-+6?=9&9VVx2q9Z06$C==PN<{~)JW7f zEP-SX1~G@<=cBFIIuJMgDSF{FX?w}6Fn-k}aA8%o;WZfDV*cc-W^w?MIcUL%_Ta@T zYelW=n*3+6lDF{aJD}v}GrlHi@Lolck)3?~SfW)Di0yWI9__C64c3gkhwA-2YdJUW z1eKjt1TG{w=`c8x>F#d#ftO7C z+wz|v?D0UwTbmiaBz?u?zHh9;@}}na%3PYnq|@(QBK%80(X&8g2_{7R`PUEm;80bl zUjGIU^3fJ-DbS+;ef*pae=;^!2sSA$1cxd@$5}~}9hS=?b$I(%$wvn^u`|z;U&9A$ z@l-SL^zd+xtA+MSkd&S|X*0E7eq8~%U&*Ynk=o96RabS?e9aF#MT+e7WB8{KArtScuGh1^Srg4LO9~EmCv+cuD^2t81yD{DUM4;JV!(~JBvBlKA1xwf(p`M zEQvby6Ca5J9j97q6mO=_?`A4K~U?-7PHIfFJQoBsW-fPChAM(|a<~o66fKlZ+cQB_t_HXeaglWAwhFNl~md z<|kACewiy39XgEi?bKyvX>w47bFa>c*CGAwlcrLZ3GT98w$-nn{#YSJLg{w0rq+eT zdI=nDN$Q%F_f%k}#!KFLsllj{$JrjLwU5J8DnrZfI4 zPxZo#CXP1*jv;4L(u|oY9Z#Rq$C2;Wr=Fs)-E6qr?#L(r1ga@=?8r!Gca z&fh3g-Y{hh4XZd`F+ef9p<(p++UTV;(+fQViTFeaWFmqu7Nt&s zV_)~V>cOiojs{bb1A-aq>v!p%f5@&5{8LKc24x~8eTo`uJP!=a&1C@zJ3#}SUH+M7Y*?;`?9 z3a+tR*tt?*$CL9bv0Y6#oV(O2k0STC8+c|RIAok3!CDD@!v|r?Um|C=y3c+}P%QUl z(@fha&%_SMO6D}29ocqu()6rkGH}ma0GyNrx@@^cyYn7gPRc3FPq+K9B-GFF1p^i& zoR$U&qJJrE9ahJhgb0o?Si;r5wXv5t@9K~@UoV(?WAwa>A5#P`*F+Snf0N>>4U-D>u0j2N^bQ~fLvSuxHkJUjln!GDi#=a8TXbfJng!a4Rkt)+<1%-V zb&U=kees8TO3{%zVp1}JtImP8Q&Y_b@-C7Wi`=r5#2h%&WH*%L*F+8pq1C6|geVh+ z8(=hkWoUXql6yOM@R)XU9v0@k+Jb(7$_qEf{xOAbUB2KgXuYxoux$+H=Sh@7HpyY;+S~ zNotrqZ%O~&!a<%Nz0!FHl&8zR&rZI@%%v^-2FMY6 ztA~>H4iSI6=)hyl7GR1_IjD)DW5WfJ*bjAy^$AT+{mzW|#9TZQSAdFS&-CdNMF!l^ zj|gu0h2kPbIP{3x(1DCScko=cYb|NpYw^EhvlC@z9JpC38V9Ns>+?J+n-wWuCoAqX z);c5hC)S4xCM%EtY?OSd<(MC=$AifdWc4NR!HTlF;B?-77WV35o^vd zfCClYU#b03_gp(9X1=4{`kpgsdRIU-=A8Z$w%4CVJR}ReRZ;!o2bX5Zw141<1Y(tr zsBK+geiR)MYmV8+2LoOzh)W0yIb|7alhMSB@rggl@yR&NIWML`Q~<}|y&LrC2D6B} zHl&Ylq!p|R4I~<+tnW;yVxyU%zUM`j;vv(qMz~Cc#(A0kyaum=6@g;koNvGm^K7ay z=8=j@f(C1RNTh{rj8Aa_Slp~$wx?D%w#lF@yq`wV8QEOh`5tubRDCs|ms}gN7_?b& z?{_cK7vR4b_a?3{Vp|VNW90P(pW+O2102YT9L;VS8tpc*x<}}dBB6z1gaCO1PE}u|R21Iwm~*ZHG3VewRE2v0sZPyTK!W-G1E+T18g2T~j8VuE61X&;o?mr#|7(O0R z+kO$(WqCUa_29D}iAlZRYR9OtY#*?sCUYidd8oN$Ik+|2LpomAIZ&7*x=Ux;O%QBcm)%FE zoAB-~?kth$`vG>>a>=5eoH^{zN$dsl zJ2f@Ao4@|W@W!xH!hW>1;l)Npj_%zmL0oW_lB?i9pJh&^c3PjZQ(?*>yf+`c7X?WO z>ifSqpM3u3v8vTj`rD-O`&1V;N>0&TSOGYi_0&Odf`vFwD-_wb6_y`^>mPVT%FO3N-Tn@71Fyo)# zTMLU}=@@c54@JSazYbX3ee=UA{V3oorZoSFm1A+RC%$)QT!s2eG-fUNi~`4D&*^|{ zou8GESfYG429?d*X=5(YlM|UxG+_$~ae<*uvce~mYSh?A;>@uI` zGL?%J1g+S^a#XHNr7+x+QVs3HThE@*w$h6|lb_|6RJfIvqTP2P^X<;r&c+dsV4 znxi#X^QebzrQDb9A}cY**L!~C%Q)ZwpK+kkg7Mk^yp?qI5^VkXs9XDUSEGOLZr%-} zrrT+N)SIInu2rnr2trB@OAJm2BuYdTvq#&K`#~Z0&^ztxg|ei=C6j+Pp_B?Nga>qP z%?EOnOIG=~=?!w)ZR^vQ#bq5ptYjD^$@BgAp45vBXMVAGbbE9KE$*cUzjL~o!9LJw zq}Jk*YPn$Lp^DCF`+Sjc3KW!stghl0Qj+H+S7IN_(aj5S}F1}r(oRQ8Y z@Rl-2DLV=n6lL03>|9NCk_e6@2v6ICB9@yE9_M+L+I&zJeC+w!Tpk}-!_Oj6UWLq6 z-RsHVcoXtK5>YqD54dM%6;NY|H9_&FN3-wc_Ip-VvY?iS)r{LO6i4rEA0xJHVyEMk za6Zd5*Sy@JQBZazIislO6Ht)Z>-)8r1ud-Rt%qKElf(EL!Z58(n@&9BR}~&& z5q9RY5Hqj83TA;-dqbp--N377$#vW$p-!B&OQUSQ9JL_cv73P@EMRzLuw1=zg5;;x zmd!U?%XC={zWJ%NWH`K4jyNC z)f^s~z1YB^etD|SW`sV(NV&J^yRbG`=lPZ5kHnSzL1G4Dg~ivStrWe){1=y9wwGQU zaq}sty%5B^0Clx2kD#lolC4CL99^+(%F=!8IgMPf5oaqolJ!V!h*{ZB5XsDqS8aDe zKJvGbiLagHU@HO0iW*Y}Fz48z0)*beoFNB52{oY4rHfN9y4nc1w&Pwg{od>4uQHf% zWG7zH%;JATds9nV_kM2SL*eUR{#AvFu1B34v6M6++hk3?Ks=j#niDlw&glq+(uK^> zyTskk{(B&L@2PSmME!bW7%#}?+01Oy#*w+| zP(^h-6L6svm_Ya8%*-}!x-YYTv2Xts&!l}~8;J8Z-0R|HW7h?^sI3O%MVhvho!uUv zIIMHozcq?N|9TVDtp37qHStKYX$hjfura(1%2Oq_5c4>un@j5XwPA)777Vm@lM?() znkqvXx=sLLC4l^qO+x+Zj&Z)~FHTH;$vQ-7t<`{%~8Dz!hY@*eHNgzGx_9g+Eo z72Bbbm*|6OcSl?^hoCE4R&7CY{h<4b>z|>!KLeezsivyTbORUqowYrzq%SHwn&^5| zr=rQ7Z_Dpr^2Ocv@jQQL{xqvUx0Ku!-l0yhula0SNu)8XLup&)J5O~}-@Nv13TIHk zP(&?^xXdczK}PA3{^)EHbQRVV%+B?| z-t(rP;6mF&KFLkIw~67geGJl{#dQ_Gxy!1iphCfrR5Cxt%amU<4mn${C*F5e{aPh3 zH7xKaSL0$XHdo`%rV9N|t~InG^UYF11t1{{R6fyUWgX>KtiYyyA&{QHYt2Spe3W8c z7&sgYQv`&%GI{P8>BRWlTfn=A+&xDNjV|EeG^T}68hriXf9gf*Id+duD7lXgSD2-*LDYl zsS>QWTUGZYE}<`&--jfC5%nSPc(5KZQq3+EDIVy#ZxxsA^uj0 z2d4e@>51wGGmYDPm%xh!vi<3IIW~uRXXg_4X#=b1V@9t<3V${g;xV>m_Nv5gJgIl@ zLm$J<-P5y?%fy5D$nTGEhTX5C||&kf%<_i?FPS9Nh{;d0-NFE(Pl3mYlEA2J;9RdH=F-sLut z8L#lvk2ZG1%&dd=b*G}arqgTt%p$?9GY`3X3 zIwoK0pjpw9BE= z#PZJyyQvbx|6Dl5y<-8}9fYgbuzBciuF2kxbO_XmnDh_H)@Q=|`vdlD^N1HLUufqP ze`CtTVrnaB57FsN=Vj5n8uwFFpRRYlVi#_e-~MX*x*rA`otqI+hiac3-nF$VvDO#-U5l z`KGIHJ3;(<_E|2!Q9Osyy}Qvcuo(V-{muOY9P9s&zeD~1M*aMsukuO$r$24*w{&7M zCd!s^Ic$r*Z_8BycRJhRg1N2GKKbI=b@TuEiodsJAKhQp`S-dSUtCBe)`yGe;zGnc zZx1R81!y9xV7a;G`nTe4^-`m?G*!VZKfC2tgRYxLquz{0#hMJ7nx$4}k3lu(WsJ3N z=Pp$)J?r9{y%`v^n#O~orB@huHog19P;>~Xm#9y&=Ekm)&VsoqXTv=&fEYKRO{sV7Gzw{|)3#)}+w8*nE3T@XrJ{ad9NSa@$Mv$q69Q z{fe>)Xo^VL56eTKZMSFM*fmS;#3Pd>H1DSwx^HCBH6jfIPKr5)!Sf zg_D=3`48wTE5kv-M_i+cU_mKSg3BKm1h{JatK^$kePCSt-hn;kW_8Tr35o4ZEv&Q+ zVnPxW!i$S(za;CxddhxZZ<1;z;Q{-K+J?3dY5cl-U(K}TQwkZni#`-Eo$_eV24t3h z`sMCL>r@8OePNa4C+cL^d^zpn)xA!TsSU}V*3RBE$EV(_3NCzyrt7|&%epm696zkj z`%-h*?N%BID*sM<9+-2$cYrH^3wzSmvDggs{ zt3`0u`DEF#xW@ZWr753mmNNXn4E%vJM;bq($sy(zRvkt_l@<;Gnj2MU#WEHNvg9?w zjt5zgAq3^11S77Sq1-@L_0`5|l+X6AEg|d&SM3T@S>W4I7PD=~HFHSt2k=p+wYe^o zkl*STP2C|gV(Blq$p^q;XLTIA>2(g^!iFFSOv^4J0c?4X0Tqrc@qsKm-OPj}51@{H zPL^TXej8X`3)`met%YTuhg{4bxO;}-zBM3yD{}h&!SL3sBVPv6HRGf@n5(<+j>vcnN)It`? zd4OwvB*3NN{V1Pew4f!{?cUX>^ZyKN55e9Q{(nw*;z#aKrETt0)X8>@_n0QWFq&xe zq&ZH=NyZ<)qHzDguyZGy$Lax-O8RDv6R@R;rJcSD79r9NO%*Sayq6`38a)+?X;Zv(3czGNEp}Bc(Uvl_HXQCZDWeAy+vPh zhI&8^J^Tzdj=htxhw(kP1=OvtPxVTp!osv<8{MftMTClm z*G~hRaF)fZ&~NL7)bG>5`}%v`92Df}6l0~+SX*^1{#*PG4C6vAqrA2KL*u4LHl~FD z#%cd?UPfor%ZC70mm6-t);be_C8{};E_4>#2+A%{^OlMCOV$pPqvi1YnBQ|&M8)jf zW$0G)P636haaHSpa4axo9^7$Hetu6p#zsZSj;U>113Bo2cI55*fGp0K8?Uc6)&p|_ zbyE#NFwp$Te3_tp$w#GQ06nV0~NK5YV+ZV z*YjkDlVuCg^L5WNq+=2@A}|h|^tHM ze1p=$tnW&(VDc>LJZ~I3Kg`<1(5kt+^&QsR6F41k?f5*w4~_a0Y6lQEiH2EiwOCHi)TkjqRTFrJj*5iSZ}4a+QGEzq%BjBGVFS_`v!;>kfuFST4L=D&Kfh6CxLO%_}(vnYgEr;GxeprVe-2 z>DC|jBYBWLtD`q!us5^7_X6&o&)9X%CQz$Ap+eGp(9fQ=tm6|VLQayq9zJ3qnxBHt z6XgeQ_Gl3C_ui;&{ZMyamIJD&S2t|P-+;T3(fhyx{IqFUYRD_2tqNSIr4Tfb_!FJ& z0TsnW5}~-1<>__5D-lo3C^Dx|B}1`ZRzmkL@eFX((E)p z`696o&vg`}B|GbOzO9yWbrX}y-n}?WrTyd;G~U{JIOd%>NBIJz_xj1 zAW>>7>@2Lnl2sf(7~P%~Ur{6J-z(gGksHsULF+(CRAQ^flvWZw7#=p#qt{3~quylz zL<;r%$tI|=I8%_>QSvx?`<#7OYmHG5w@aT8ri@C^$iKI~b|gwWQyJ=V65%A5oOT65 zy$|;1YEY0LPt@S!=i(aDb+#t;E}7g26VAC}kZ`}h2_Xm%&lbf!_In_DSdTTyNE07Jpjn)Sb?jw@eW;zo zt7+u>ICojUBWew2>i%u25W*50T0PF)%rdhilRgw>@wz#cy0`{aYz>m7`e)eZ zDZ^t&$#exhme)#Kt$SvWcrjpN%>T?Wik|Oj?Y(-*_Wbv$d$usBsx zBM~!iV=AX%h{ANoLh=*J!9#voJo(6a4##%i_ zogdgilm9T4D4%A$p*ZwTvbz`9?QZyj-mw@Gvt1$)!h_tJJ0&2HfCrSmqyKOxifq$* z3OaI;Zw|rIgxtsd<-hJwy~3AwSrMN^h(2RUIYPN1lyZRBA6p<>Yca8*c0 z;6z{DNS&-pSomC+@w5c=0|Ze)#DuUUMRxS152fArM-fV9(TCrOiR5w!f`BowMq<7G z&#|_|lam$(jZ7c@sZHlI+%|pp{C=3Svs1`_pXQ zI}F6rryj(})l=GuAF0XDuJ*|POk-dd-ZfChLksz851S!BIR^@FqpZO(wa`%3+gcsG z{Ff0szH&j8$=3I2g@D!YIKLBdFrc@yQ|r22AJRHNEDw;^S?^|_hv%cyxk^bs@PPV? z+dThaR)7qj?rL;G!dwekwL#HN&uH5Yoz(aJBIK)dj!EiaL~JU zIUPeH(jJ5}(YG(SxzjjjUhh`F`1iJ_3OF zyi`t)c!KqmX%=0d>I_!9u8}y>bRe-jdr4!dOaBE{HWuLL1P1Hn53N% z7l{^0`}r|=z$UV|1K(_kCy^_v-zT$Qe9s9g)$jOQRB_i#KC0UDx?l8&^fcb{35@C~ zY$frKNt}J7ADYaxow8xqj2-7h=rtPGQE8`K;XQHTG5PD*V8go)fkKo#Sw`dm? z;EVmP6(emcqtlnmyq+FpOoBx9PQc*u{7%xAJ}Vcsr8W8Zf;k^)tokkM+rqSA;O>w{c zc>QOh^{+ls(2&O-f{i0U?p zIyv~!gQy3lMwqLbSa?I5JG8(QcwVelplX)c1zEL#B30_^)!w+#T>TN(94GKjx5pjRRFKau$ zDMLq?fSMJvn^^R}Jk0*a)W%iK3qaj;)~NCY_$oYt46OXzKF*Veb4(SFi6mbA0z!18 zuAjbr`}AgXvldMj=AV%}xbhi`_5-~+VzBlHR1Dbnnjy4#&E0a(heuIg;A!plG9gp; zsejTtNERfcl5y${E^LM1M>mgZ2~Z%oJjF+IqFYo^r1d?IdFj>cat$))oIH!Z^^hL2 z9IgSm&s@F&l_(jsGa@qhj(CwDv3W)EEWGjgt=UaSTS*aG4HPRFBBdd?#cc0`I>hSiO^W2E0emp&xJ|f2Z>>dS zm+yjLK>!}|Ka<7#=YQ*s^Sr;`VzhNzCIUqXrZ034>v)Ccbk{gN#}LtM-xsoy$c0Nu z_Kk!;A&DmiAGfY+^bd29XUZ0&O)pdJ&%BypK zf&yY3Eb5k&@kpZiXU-0TiRQ@!I=lwQ80BlFJKmo4$)jw`bDkg`Wy>oxwepp6x)lNw3s7`;7-Z#nFb0y3k}9xu>3A(te=`8Xj-fLp!oB% zY?Xgno-_(3lH*{71~HX0P9|cVE2-o@wS@16unTZfmSojLN;M_jDXa^Z^Utxb(ID2^ zDj>T*W#P%j$JU{E_aw46%497A;B`JW1Cw3%>!quvDR#l8`i}NkMie6$7S1ow#CeR;iI}%t9&tz9pG# zV9fm79}41PwDMDx=buUGd8W)fZm$anvzVSHzNTvR*5#r9+0eW-@5Im)HYp6p9luw^0)@uA(0-zZG+oSwEEDhQmI(do2D+y<_ z0~tLRN`Fq^t!A8R^#IZp?z2yfj8!3(Dj-6#oMxMIJI8M%C;x|BPA{QQUfO0A4iOOG4y~}kuUshVh+g`+{c*2 zE0uIQ&>%ZJsNQlWbZzQx%P z1AMN}XyxVvHWEoQ3S_sHy5P1&{b{A1xo&BMpUFuQ>I5MslNsM$v8d^!BTx(2gPd}P z;PlPmN**na0)NQw^imgR;=^uQ5?rN}czEsTk3PL0kLFyMkMB3I>!XK#JwO4aMEq^9 zPnt2NkoG}y6R~m)!$qbRih0+O4aa=vbjz=$nFiaR>tSaQ@SgKt{qkXXFgvAwJo!uz z>OUJH*TrWRPmGSQ=lTXNw+cT5^1YKOCCv`17?0|#)tTj&kra2}@w~OZ9z8|6n+^qE z^xo)ro`-K5!M29Q)gMz)L(xuhH=dL#0nX5r^cC5r^Jz2q+~m=wkXx~<~H>v z#E-&S)7Mh=z&^C<@>kzg3f+56M%64RL*LBh^ZwxRYLTgpSzNyKdMz*?AD)bI^oT_A zrP2%wnwl{D;{L!MPFX1;RxY5Yu!;;oX(%9KekYeyYJ4ok#Uzqom5O?{`8rUuyNP|i z)7_CoNiCRxo8Scy^c_6nuIfNa81{fYN`#~o*BF#UAI&ZGpeA!Xe9;ZkV9xim8FMLt ztzu3xE_0s`=F$WLNt}7EtIZc*tdq(`4z3;ue9ABve6xPWIxl3=4K2Yzdem1yBySiQsGGhmqGPtRPvab zf7U_lLnVkU4wH2=S{G&0iIP9VMffQhd%U{s7Egu<74|xXkZrQFQ7@7SMB1p6Uk-kt z%niY9%?ViO^qZV-{g;0tIXt(X7foNgaGWe04H~#%7K&FD>10MkJAe_Z#7N^vysF@U zd7(=1-)pMp!OQXVzi%a5oLr4wa`M(zlWRZZ3+0A z^f10=>xg}Kae9Y1j^}($N0uG?k#XDo-7H|aL{p|+im=MJR(ScT4fPluUH8WzyZ3rjDNT2@))ZFCGcd3;y@ zG!J*-O1k|l$enaIjdP@0AE?9lmshi4kpn`9XU7X(JnDQ~=RYKb+}nf@Nim(Xop$_A%z)J6TP zb@jjMzp!w<8r^l=jZC=-i5ft-0azIx(uDwz?Elibo(^MO@7>|7>_l6A)LO`RXSuJ{ zEIwXcR2huW0kkf{#42E2JZK$cM)yAF&f8%abP%8-Al#HLyj5|k(5|z@ctl$K8sNJA zv;`Kz4$C@gg8N5LN7#&s{q`ITu7qVO z^3NNxccmuS%U&d3m&s|j%h$Hzi)cW7L~K)oJEKU+EzWV11yoJPQ9L6COgV3l<2(|$ zaV+tjCj(G%A$Kdw`wQW-0@hl(yeRS7m~XX&u@QvBcI87w3b!Nn7lHT#1^}{=B7-jG z&_)bpZ&$xQ010WHjGVqXBS?Tq$j@m|q+>I6e6mj_YoC4q91C~E@=)6h(b-p~m(KhBvU$x7-ePUrw*Gig|dSnujC< z9(cU%C~CM_M8z_7Ho&BuIaa$VCfm`neB`WVW_M&|mUj48?BWH)t}sCC0{<&^H88+y zi0PE2QJeu4=cWI314>8VsfSADiR>5j8k2vKB+Z$2N7cgVL`j^fzxc-D$%c3A0ONV^ zTOhk0uhA!eO^>&a#&ff~O4X2tunGv$A(;_9lNTTjD_m@Q+fn0WLx6-Ij0{+K18@=+ zz{^C>)2Xovh3_|z==~1p0c;@RqGCg|VFMi4hNT<>pms5r;@q91Q?~!BcD*G}K|dW* z9v}u~Zgv%VF#@X1dP!tOlyuz(Gd64v(w7eT+0DbpJCwmG!25fbCT{b(*^<8oc93`s zf-Je;m)M?sX4oj;YZ!_B2%ZFNsuXO!Df0>pTto)w9u??oj?C(kH~1b;7y#W>#XK0m&`@|(C}7QBRBc=s7Qa*IvHCBo+XRax*xlUy zm3|UU|8PB%t~pZi1O5{!sqQH70<;o%K!8DPp-b#JKxW8Nx4~1crefs6&IM#vj|$!n z?PPHmoRxgqz&3TnH-#)8rEDhaNe}@IM}!Q*Cj;;ZR`W^-eGk(@9{6BWrklv*pM1*9ZEd~YW zBN4yWfAuc>wMFx6#=qdhKJTWIIyonFo4Um{ruWgfEfbU|^HE0?70U5A=ug<8Fyns~@wJ>QBse6w`+sRo+Mw_9X z&hTgPhXzH(HIZ+V@H_{{IQz>%V(2@J;$ZXmIj`ro@sr=|5%8!;#KSvz$7QDzc z!FI)n7T`Nn1{OMhCfQu+p__52yVIXZiD@wTTN{WZC{s#z9@yW6D{%us#%wPDMlE}C z2@xiifgeSVv*zB3d-{F+1B1pY=l)Z%UA3Jxt$q*PLYbRJI`-lcG!1U@jlnng+5n;< zB{C;g1T19&8NWA@*T)z=1Wl+W^E5gmtD?e*Er~O!Cir>ULRKi@)u6@<)TN z6>~>`_;|C!GLjyr&Kc-=oW%hv|MFdi6Mlc`(M(K^cuf&~#aTd~WA3SJ74sO(f`P#B zp7zvbhKjEM#*wfXrR!0lcx+64Ry783(@f&P?{EZqJQLz|;G{UEn!uW(y;%~&@0MM_ zuqyUkW_sc-7>U*R@4Nq&=jXRKS^;3NM#s zi}-+V%YCi#5&IuQf>DFsn?iW=XTaLSc<0WMqaqUZv~nH`4>HBt!{CCR0;n<#r7F%* zIV9}|5V1~n_Tsp6!`^4TemVw@!11iT)K#~jRar_ zjYO60w;Lw5m)0yZBupW#&He_-KtV&m?J`66P66O9zSq)|MTaVMQdNc^CZL<98z=&> z`u~^OWy%|L@xtw!XM2&dO&|j`(5+d&1TUi;DnB{wM)h?d|Khf%^mnAi@=09Y%_p#l zJ-qyT>^D+vvH!aI)=5bRG*Qrua3$FeDHeM9N7}T_qeim;i(i13^yP>wY)987Qnm{i zhPj?66)8o@NpBX_xSm9Wt5(y7{Sy8Bv=m&YbrM?O!3fAOOo(^SVq(r`h3%fn*|fi1+yr#9 zsGKaFHHnVws`UQ`HSnH)^{*3*PNYJ&5HV0R0{SN$nQ3vnV}nI;kLsHVid;oR7yfQN zxg4NqCo=F5{T=R*5!MxkUq8H;>&Ea$S2iM8Xhu_QP13CY8M+n%w@~I&7z(+ z#5~pP{=LLm+*;vpFgFp|x%c81_UsK0!VE{+1z^AmHZ){TpA9L}7N_8T(m)S^BLALg zuo>{_6tSeal(}`jc#&cm65RsTbzUr+NUwiqeD#BcoVrhl&Fay|9T3OZUv5lb)MZpl zYY^I0TgJ%|txf?$51&{uRiRZ;W+i4Z$yH&SYRdU zY`xnbOFZQnQ$fS*_T7n%^{+%IjcHq{1vgu=k|JB z`=M=~`^Lpz^P|fF_bZ?R^*Dl}R=h@;4u$~E#fngI-_mjNsO0UWf4Mw|lw9MrEP%@c z5G*3(LC`TJDOPm(M`p`YCEl#<0k3{i`nK=dYdS2(T*%5zEWyaB9ooMdQ;XwoBY85g z61zxTnF7_rU$V@;lbQt5QDprb!{AQAP%_-8isi% zswU=dq*cG^X`e)F0o@Npo4`DZh%olp&W=gk25JC!zrr)+D7EPuy%-4Lxi|&9B<&2 zKLAZBdK&2nx0J4YH%b3bSirgaSH1o;8N#MdexNYG&Z&k^M>KOJTBXCkF2g z7h1B`{>Ebpu-QOjABf!pmVR*E!1=D14m4QWN|t z`pD96WAI|7_dcz)?S&Q!>FJ0xsnxivy+@tYKqv0wpA{LsfCU-h0Zz`A<-5yEqSH6t zKR%!|;+-#3|DC-hI94Bg@bI7(UI4Awb6pv#b20HX@5G{<^S3e57xYWBk&)k12Lsrd zDa{PC;H#tM)6b-J*y8OAL@O0HOgr%tAx8xqGAV6<-?fqiv{$O&yIV>Jw!SzhSC%aB?pplbE$U!p2*LCly^xHGkh&tgIZRe9ME==G& zPD(7L%nq(sp$U^!1{UYKJP)#-Uw4W zy<<&0UwZez1TkfRTyi__PWHa?9Z!1`6J?e?R=q|Cdy}a(=?yds{AP%j!VzlHu%q$8 zC*wsz6YwQ@owI`}%B8{IF;4iLA`{d$OM#ygZo)75V)UxkOb{88r^>U7Bq;(KD+26J zB!56ajMS3A%ATD5f!Pc^^+S|Bv51!b-;K0t8XEeXK$_cbU@Gyk_*)uR1KUTSz7M72 zVHMI&oQ>BU==6az0@b!DRoUmJ@Nysji#+hZ(++eD@Dvivfl%6fb$1u>_depfTbgrH zB>90m{OodoRhmGw0C8OOtZfIILFPLOo}CFy4LWZ4C{t7Vt@-aNqL+`pt!oks7SeWo zqy%p_Xj8?@CHJ3Y4lmvZes}ddGSUUsA9XCC;%}|h=GcY{GI|ng)6#M(HXSARiMkLT zq;Xlo`E=Q(G*j0LCFpZ|fvm)hU<5&_cAS0Oq~_7P619VRKHmb%&;Mf8oDqb3A)II; zvOuSZIp5i;sOUH*Mw(!Avvx3huQcyy;8Vt#%4Ko~qgVZBo*SwKu&;SMHvD2wG+YSL zRK12ORl3xLDh^&ek^W+|VN^k{^p*9GibBs4ou+S=_wL%;laew_pHZ)O<3h|!WOwAQ z*(@l{B;hY+#T6WBBV`m6%$U@JLWu?z>L{Fx$ulx1Y#TxWIPt(UeP3S zqDoZ$r+e7<^63A?*IPzK^@eTV(%s!%(%m3kQX(=m4BbdccXxNAqB6vQNOwz%4BbdL zq@)b-ZvXdtuk}1%o-eS5wPz3OoIQKa>pG9)cYv6bZOnPQDeh~?b-l7tC;P;|yqIeW zykF!}$WkOInKWa?aU$H&(o#RJ-}VY4cgMbyqP{CP!(5Y%uvv&&V?!}9VclHflz9K_ zs57(t^D99PPuiE({hUhgs&NZn{64{=HEmKi@VdXxiC<$CXejIL_y<>db$Q8Ij^}V% z+6$G8T6~Y+(@Cf(*c?xY=1Ru)dY|<2IL-P6J8E8i6dyEIm%~$Uqh7aPS7C0W6uZLw z%-T*qkw97pG>Ci&V3yeBr6X+IXiJ#@N)}f{Uq`Y(8emAYvtKpNSEg*$mKP=+jL@mq=mG%m%YV_fCxQ3U| zhpT+Z^{tDyr7L)_%luF*iQim)a8u^C)57nLC)c1azRa`N$6p5G(8Q`COfvg&+= zGuL0qh&5Xs66RO7v4E%kz%6(YD^@@^CsKDUSEhABGH^4C+;0&0wd)|-^#=|C+TWJ4 zxu(`+%Gm`Ll{`O6Z$tp?@pKc1=hq%^qD$y)qNVBb#TKiTvThzJZQ%`h{7|Cqie$01 z?&g8(uEJPxuRiVWX)E+tu)NJ!aqOJ56G3Hm)FI$vP+6mbnez_qozCW>Meki?Y34h@ zXeGYe_@wVTD;3cQE8-n=st^uIk-p0{5(zPfjQ6{@PAQmw63|c+u5JeJ;#HCHjfPH$ zy!TO4@hB=M66mI5^mICi*iW8oews1@!Q5Vf&CBCT7rVTXNA6H_V+-bjm1o)>;)&p= zEhPdte-FrttTf5Wdf!goZI@Ha!vr||P}4uTH*HLQLD8wg<~I?gj2~(+0d7^UYHoyLMDT1+ z;p+WW^6~sRzj)t0+uC+|me?jI$SDGVC8=44a42Vc>JkFju2=RRHDB@AW00>x>?IZ& z7dy|b34lq$wVvWrCm!(#kA3{rN?TWN`zuzpq`}zFYraP(9Ykf~l~)?v@23JLNZ>7Q zbm-@T?vdI2N*!QAK58SxzlF0l1Y>OBYu8a^urt>BG)SI+YIcQJrNtff0wDkuCjYQ^juROJFK*6l=mv28dB@pCDC!W#4D4>V1DyRl7kVB+}Z~})= z3qN4{G$)puBwBxHZT%{ncHc?wdj%|r{629bv7gi6VM7|6;S zyxT=qL;&z0>t@Pg3(>E$t83fK!y^46x{qhcdmpF>m~$FKzeT2XR5fT)%DaVEECO+T z_1e8VjPehPxLqS@x1p#W;%ZjJXR{olKy-}9TBDAjQD|~$GqrqIX5TIWvoY8I4w_B> z4Vs@PR{3HpN*)t_ans|k2k(2*G4TDlRo6L4u_TC6OsVc|?&gZP*W}g_g_kA7p3oFieZ4h21kuj7V6+17~crEU0y1#j=D6Hl% za0>^<|1Q+8riycuOl=|cUqhvskPT}E4PXTBG1Ph8?&lC>IPvcC(jEBnS+ke01O=8- zNOq35r_&gfe>BIKJ&?(~yzy{9iTZnz-OwYcx#gHA`CKaMVonB8_pP{ zj!ATGk2UXqi2}QLkzPQu*R@T>`yFQ@zOHA)rL@H{xZole|LLz`-HA0hOcN%CxAi8} zY88yIy39-0eZkLr3Ost1(S0wtBvUQ1PTMZPy!C>0 zUa2!%#l2rm1MSvNvw^l~f+_%!!QVExu-W^CS{kFvjCCl-`u#V?KQt%ifz z&O{kmBO%lM?Wuug@K+}J^Uvs_nb!XJjS`&y&eK2qo$)Ik-loBiSzWAa$w@p{gsGfa zI~gISsN?H2CiUsf+voAYj?ca}3?Iyw3 zIJS%SGPCpc(ic)TmmCBOTdld%Zd`CA@-wPZs#J8JM8Jb5f9HjWaa2cXOlHKth9~TD zkZ%CmGFe_Vn-=n}sBG66(fq6tP0NmK&QT87K$gj z+3jhATw-rJ@x}tY!u--Y2N2Kv8jdtX#xg>kaz*X~!**EC@Hx*nd;=-F(yU8}WxydO zBXRll&)x|p-SWbX%~UW1ZS=PY>Qg8&;~GM9dJ#>MFF)Nel7H!Aff=lzA?5&^K{!?x zc9^?}4JUa3DqPU)m7+Ay?+A7K@MzHVDcPcIWdNgNU-_F9AlOf!G{vUqX!;w6;OJ?j zo^|YM+0Y&@oO`ex>y0Rze=*X_dfC*gsA7`bx;L02eh2Ya4^_zUAf{a3l$R+KiWuZ$ z6h|cRjzjDG&8DYYzpFr&Y0DL#>oGQ7hVr#1j+?^r z;?2=+k?{&gF=9ufN+hoLN<&g;Q#CO$4dW z493)UWOO-J1Q0$KgLk|g1zhjd$oyenqHMt#pz3pN2)}f~6+T}eN2F&xd6QhkZ9KBP zIK135Aict+6R}-*b6Dtm^X#wF-d6!5-0?ERp#mEamUnfc3z;?@9Bij7Zevx1t6U5I zArNDG1l7bPY&XdOGP``1gtWYi{2zqy-Rhu(wZVU|vlg4e`^&Q5+6`I2gRpl}NpIPp zd_TfZ$C%A00vBTitFXhIzFA2S4cU*mJnFQ+Ki7c{ab1{P^9_M_#W#c|@*3@Y3I^il zA|L3NNP;{P(hx@*bMIuh78$Z0I^q@$UXCs^WXKLB-YoS82@cU0p`^a{9@MT6P;Y?x1 zNo7xlmMd-Glend1cTAm7l+u9++{n`@Yp4G3bvZ%moB>K>{O$O*;S}wm zN(aS<*5f8?MUGznR~*SnM7u3b{yoP^_GWlR#c6r5#xF-mT3P=|&~q0e^-D12)m5#} zm7(8C`r?k+-mB&`e2?+BFCH-y8Y2&VUKCvbevJY{?JLM^352WE&E4dP*kDqehsA04D3*?*a8yV4)nuC%<;F#t(3`Z)4^jU=tR+S^7U^t5)8;AW~25~QPIy@r3{JSQ>- z7o2!gt|g;F$8}GZ#_rgxV@&+0f&9GY$SSIETlRPo@SW^ZS>2TN&}s~Q3;Q3{-PpaSye<*RBou#}{F(&8UISO=N#38Uz z*hn&JWa0$2PNyjan0EkZ0+t%5>aj4AKY2$V)5Jl5Ka=+hS(^UeVkuc}@?LXNxMPk} z0xt)sDwNCW^u;!LKO@7n9w-;E&a-?-*})I7YnS=h4_-(Xl>3{S!QhZNn_*1oBf%IY zWStY%GIu+g%vFs{9)qcyf|IZNfDYUD0U*6Sc{ARi)Fw#Ss*jDG9&(prtOGg0eVfSm z-AEGaA3i(?wd5mTS)_1wuh_ud9dacKvtthS&&wbp6F@kg9Zjp2;4A6lOctu&Au!oU zKVs;IuHel;`W&w?Hdy_~{cY~i27PQgRgR)IM1Els%m*~rc7fF6s(kMU9pMcO1%Lu) zN6lIN8CLVfvPjy8qvz0$$hk#{&O$!Sd3Mj?JZQjRLlH~Zk;;#CjEe8!s&M37Z%JAr z_{gk&t0CQ{6VIkLdV?0yZ52>N7W+eVBPZ3kwWu8J*ed~iWc&#&)81M97n(NL+4mv? zcN%`=+#hv(h~R7Z{KP8@kkh{yf?AMwMDQ;$XDr6k#PF=k;*MEG$c0+HaSx+k%j!dZ zHh`>Bdz>&G40OfSLdU269~! zV?SeE>0LSC@t3c%Q@Rg(~6jP4?)j^Gc3GVkhJr_@F9?hMEx^qfc zOXr(p0PjEyx4+?ldHjo~VQ3mdg&JC|xeYe}TX$N+)}|(04LT2E%yGs{>_8`;4`}%z zWu^0dA9J?qe`w%hP|9mVJP6@_g7E4x(@u~*;P(qHwbB(3A%Q=o>)P-HPf8h}rY%O# zaOU{iU1au*0SSg1G!wo+RhO^Kye3ej?>)B;4^W};dI3G z1hu66-0Z81a+cg4VGYqdLvj7&`fLDmdM_B79 zA)Reso}Jy{%_m-yzMVfaFU<-$`5dr2*p3UxViBYZle01~ZbpOxh~fc&(fmCU8tJy6 z_9>WI;8xB8W1_6vB@T>Fh*KC}lZifMXMkOasLAkg|03Tk3Jd<_>D(dBx?m;EGSDF_ zKUXNrDVEQlAL$SV(auMVR~2g<4*E+>xcllY%c)2v;dl?2c-{*AtWgytOKG@f+ei5a zOmk{Q7q#WD4z^3))=j)RXv*vqs`qx+wFbXPp^qT0pCQ|z3GoU8&_R3^nOoYBV8y%&gU z>S9DYiJH-pn&q3TeCJQJRZE*X-PpQ##Uxl0YwS9>3lZ-{1o5o$kBnNB7T3#d^OsA(%kL=1fS~)z&vaoP z6qR#wxI3H=9Z8Wc1ZaHHX#02NK&V7En`gSWO~G=h?J~oUfsfn3hPU7S46iCdvjY!D?tPw-zFVe(Zf(`C6YRHCWKfQY|1Xg`Xt5~{`1q- z=4amY6%6YZxOF+I`NwkGewr6vNqA4g=okI*zvU%%B+-V==&@g_J zw1O5{iGE=u97Dl?MzTP+yx>zSnmO}A=E^K?vv`86L zLQMRb`kM*^m?o`D!`D2+Af*mx9!HUM$^evJeN zj3U9;od_P)0!afGF3R#XATok?0s^tUr(9qvBH~n|r^_CocgZ&FDv+{Aa+uQ;!}A6$ zfRKhy*zqcMZI+9NxWi+re(BD$*vgoJrO1No;?5<)cTN=k@hyeS5^l%#_JxbA@&Y8y zYE*M9{=RSx4C9^4_9ujk%X@W7$2UR<^6QQB2$O(P7ze>8m?L{4u3Cbaj^Ylae|v!V z!A6yePyNJ|KwKdSWn?!nTlv$WT1)(@AQp5(0#9>*JCCO|e^B5wl*;v0iSX@GMJo8- z+gQqHA2Jtbm{xN2H@KGUJ2G4<);9$!>QSIk8aTZ#0r6n_i~ff7>BbW)ki!EIJGM-Y zI2;#E#Bsow;b^xm0Rd{!NBPX&y~iDp!!YVjHHtWd;{Fm3P7NniO;}q)?s$5y{1@y? z-aUp4|A=(p4$2#=XvVXVDednA2B~3R@k185i{oz>78LJ!7}TtUQG^Jw(ktVeO!sc;D1}|_1a}>74VJF*E zE_*J!aYqlNu>d@a9{-dck>@k61q!9$n8u-kt^i2u&rbm+N%G=cv+hMh>{oVUV4Q)6 z6CTAZ%})PUNl)%?s)9V}S1yg6f(j|P*l*IFpWPq2+=Gt#W-4U#O1>n~o^x3|AkXdau^kh6jccpriEuhk>1>aDH)Ji6Po)X+e-G_fp{rUaMGIwU+BZb4idHHyOj2x)#u zp`3}WBQuo8RVhNuSwe*t5&?L*JgfT?h(As`5=zv%hYb77SG?#DAP}L0B%gIl@w{ z*(rIQEI<22W_dcHed@9+Nh2R1?d0Blp|$A2Ye4*QYsYRyv_rS!po7xDDhfipz;iuLjxKdk~4amXWVjPGr;>xx>WiySbIz50rQ1n#QYUw-5O zcj^BMpF;rHv$V-RrK4}F4eP_!#%1`~*0NGjXk9?0<^s>-kM$(`HHke%fF5zYiTbfQ zxU=2PDE!TUNG{k8bdzSSI60C8iwtRr2bC!>67d67g~{UMa&wjU*qJB#jmvyPDr|BaP*<{Y-{&`rlFfi(Nzy= z7Qh8OTpD7*bQf}o*kFHwXN_ab$W!zp#z)B35`BxWnAIUSt9OSku(pbb$-jF za1O|XhARk)`a&@e5in1YgRhg!-mNCeb8y9cV5$)IUxjZy6iod zrOq>J)XHq=X>Mv|mfo>6J1TNOA1fE0Rd^Fg|AV8E6BP-Um)!jhsK@$o4&PQi%y};I zc)iEPz5vJ@&m2PRIrDRPFO3g#I0gq!Xpyr_8c+L$OUVigfMcD4w%y*5cMIZ~n6{s1 zFAykIwCcA5v;3P>oD(8Z6B7yl{+7O@Zi}T?Lc{in94}w$bYHTwx9D5wub1w19CNjz zlR7%X2c{zxaCtG7fY;u}nyfY@$#3{RTDoV-G}P1w&*A-GR629tEt;yIMVgXr`M^p$ z?9ckDo3fwORBU8(CW)(uxbg3z56|~H*Z+`d8()B%Xp0(GaeC8)1Inm9GH5ckp*y4h zkdC9cN?AVP!HlrORD+hDq%~%8bn)H!4a=fA4ojJ3#Wc)ws5^E*VhNXz>(j<~OoOId z({cSPL=jeTF{CkTNYryeIvML|Ru)2bq?vfaTco>rn_s6fHYM#GB+t1oM{#5zA)jay2W@kz$)-d!v#yz*1Tx#O`xPGX9Z1m>2wW44GLd0Zl?|d| z7@N@#E?#?=wHQO@F}>g##n4m6x-Ay%pB|hVQmdFYC2~Chs>v`f{iD;5Zv)=kLoQr5 zzZMa!FaJ6y@Hn+S49Hejr&RM+edwU8a8M4*N^9DPc#FINu0*^D@zikhm}_lqE4!z@ z5|_LqV2fmDckE(B)J`AWj6K@t^m!0v%?P2DOwL#Cx6<=dg*RT4l9qYIHoP4vy^AW< z=R#;+ok*k@IEOuadthuX8+=<}o7>DmzJSeR-(=gPuyam>I+#oeOVeryRh7y4D*ryn zoM0{WaNdx*y66|s=o&CeyuYq5o76@Ou4o)uqSs%4=09CjTT~pfOHefb01o|Si%p1d zQE?@Tdg=B0xwX|B5rONVvLz3}>y2_kQ0f(3>=p44#>ZRlHj*Ko3|V1@(-Zsi$BY{E zMBf2-E|`2SfNJU-mztChs@X{Pja{2I<{xpFgr#*0!d=9VDHglZe1}gT-GLtM6`~Cr zB>%kc?(cca-<(G+7|Q~HDa*5az&G7Uze4UPYno~_WrA;19!xjt9FaFoHJDPtp&nCr zN)JB9u(8wJV7GR~wT4GM`N@XRYw1P{C?6;6AJa@OfcnN|a2_qCsIfjkU-2>ZsGv=( zg?i}j4R)Rg{z;Pqc)fNWz^T=WtOpN0CT`F37SezaZjIHFosfrs*zKQ`VuzA@UfheT z8as)1&9*{Q@kjhOMx6HD-!_(+biOYM??fH(U%#odv1;5{pKK6x4hUjr?}1jg2A#sM z_d70WajrW=QpZR?|Lih+o;mto<$QF+Nx?Am|T+?es2B*`J!A|H+mB#4P_S za{a%4x4-#+V9NflBme&gL9cmBW!~&_1+U&PkYB45GtBgVjG+JL&k$ii1uRhHVtzE-(9#x3r)oMe zY_$Ql5wovqkXbKz@2PWqy8g9?YGBHbm}5k;vup8x=w=N33uliaQ5O%WI@bmg(v~9~ z{U1MXC{Cceo$CCM*wEU%41d(RIqx0}F$=?JpI&35MNK&{@}6B?ie)gBJ{LaBb4Rim z<)s`~Z7}`^IV&S;e%dO%uK%{S_~+0%{iYmR_3440$if8(J&JEqg9_3tKxvRpW`ucU zrp*I$CsZ9bz*Vi9L&3WCEWK67McsB{N7`Gv0!CgolJ-^7z#j*ukJG$1Y=MU;rhZj@ zwUyWJJ~MoG%^Y?08F59u)dN17TO#A``JI+O<(jb00t)c-3sTNcmgk;MiOcMcxD7u* znu=V>n>vPEZwrQsJQ|!>SnTH}gq@%EmX64m`J0_=B!ldQH$9+EEW(cfY)$vHA*YwA z+0t2fj|P!7eOxfP(cR}HG(ii(g5xH6Bn<6Hy9(0e*5$5tw!O*$@MpErzV2|1sM{FI&>_wPzy(iM8Z4}CDj)zg zEi44qGYP8u@5=bSp$4dkk1`U-sg@CUXJ3kv7G$sjA$+%?7jNGu+a%dYOCaZIB(l5n zuRPXRFj;U-Gz8^kY_O;qRdW8hjz|7*OS%`UP3ei-*PJ_YJ(lN}Hb0LfIhXVHB>}ad z#P7i)82Ys?uo;yqA8%&$Z1`HtM@TIu_2obhwQ}Opl8nX%)9ZKEw|)? zVQq;UnpJ))(i0p~{3SnZCA2yewMy$lnuv^js@OMfMpCk)pt~6-PjLT}TdIg{>Pxe4 zV|`?2i`Vd0WS=6A@APVc>G>nCdT3?uUC7~qDhJ)22=j@D4QY`&MUW6{x#cFHBt4m_WkyHYL(}g%M?WX-j`>? znItxWST5tsNumcde;7-ijz{uBWu{rC0ih(>#j(WkaxVQ%p2lUhln9v{H1H*F29josp%HJP*BgC^i-*adSaLPd!zx~T->d4GMI527Fi)w97mlB@E0yj}f2NU8Jn>q5M5(O_fKf{^Jrt)}j2S{oh6yNk!3 z>-7t6D6cu<(WUH0vRZd!tz+QiyIqcClKPZnR6JEvWTg7*#z@KP#vkiDfv0GnKxnzG zHPZp@(|4XJ)K#q|F3`RENoj$FVz!1g4cCzyrWr}G4TK`>>^pVr~h zcx$oM;O;&>Qc_cF{S+PAC4`&x2BZ5GLBtqti3Zk(S4aupldZ!D3re24k-yL9G8_&m zaQ<>Wd;N2SU32v%_9&SqCoX<+oXz5D2i|U-ScrO{S-OVd=4YxPmSlEGTQ9cPA46LY z+uTp(<<5fgE|{eNH_InfU7P4Z+wd{YxYr+}hsEMQ`x7JLh9dDVToya<2o&cY2uY8$ z({qp5Ua|S4T2HWMN=O8*@*B!q+P-a*BPd(Z87ssNks`5Wm&HYw93&>gtrO&VpD7{9 z)p+$+CTg6A&A`T1_vq?yB3<}8P!iaNr}Y{r(%Cw?%-|^%g6P`#eZq#@%$+$H_`kEj z^^q@O^~@;j&mMpERUA|<;#9#Bw1)t#31dR4&wv)IM2^08OJ-~M(*SDs>nORZoZ)bE z6Fic$FPr)7dt&ZsL-+ozi5IsLv2M2fbL2}s&B*L%)1XCl~6JbZVu zvjhg|2AJ!Ox*LlN0q8SL@EV=*kUdq0QIS?WKQ1uP$+I>$n`&Q5NT7sAflrt~4B3F%sN{8+2$=CIPHnE)sraeFcMCMF0OiKN&{3&9OK5oq4$ZfkwS2ipJ4KZFd8cbHgVx+R}h;Q8t*`5pIVH%wvfS<{*Pf(y_ozDn}0lFAx}~ zsK63bM4`ZQyr+^tk46pM41LxZ0ii<3;+B;_Wy%20@ z@NR|}+Wo){+A!|3x55m(GKb+Dec`3Viau%Vrt3wA))^ARzc9m-Hw@D^a$MXfaa0@5 zYd{>p9BAAF7=#B+}3_mEyfhM^bgFr3gr5W%z= z;*cNo)UQinY}xxgdxsA`$UM+q3M$iLe>+(B!g?qXxQ7tDHa@qdGYaA!O--yQ4@bo0 z64x}7UW>6vB=pE@uogZ##usgEczTJQR5yS`rX zlhFo{IZ$5i5`=uAgSQS#D!0UDZh!hfHy4_V+)cz&(B{wk_Jxcp(z-qQso2A)&hIVK zcU65N34Jrp)@Uz>E)IH%^2_C-y6iC6@sRJ$cO(78;xFy78N?|7=6XN#udNSuNW$k5 zYt!hV>$WoPaWYMU74^ZTcWEt+V=ZNHz-PTN`%<9pa7S*(BYWI0;Dyl|!>{yi(`h?k9 zxJg%rFYw0c)b`6~XXVGU_VVoXBH~R2CCt=j+EYi{IJ2b zo7%Arx>(i~qefYct)l_yNBiM50+maes}PS($E;;j`rh}SsAStiNB8<$TPO4p#>Ms1 zOxCBWEvwOD(pOG$aaog$etER{gd&w%`;pE}k=)Kb-w<4lzKUZugFjNp3&>~}n88If z5-acjx|C*8SaUDqvIqbl&(PGx@7oe5sx$o+k`w6bGsJJi7v4hKl2;*EN|k;hG{aV= zsbnX>RSzKIHU)%|RSXy`H13$FELFk6N)SYP!3^Nf{3Nbz&Dp8yDtMz5LgHn;J~$u@ zB}vqvHY#%JtbWffS{GsdBT4)tRk8{dVg%X@Z?TD7e5mmxY;PkJVuLNjk_u@3^|wB^ z5-V-B4sjSu)bGNSCxm~DVTP9_T;*$_SG|mOfT{Su>WRDxKq;2u3gxF%>EVy1g(4)y z(+Ht;8RKWGC)LqCqj&pBtYQw$4K8-KS^l_nzYM`4cnk{;P%zPp4||z~CC8C0vioh!=KnbiO7P_^j6+sG&IZZj+Ju;)<3S&lMH9vx8+-52Qa-D= z5e#M%wvfQ#L22h5090H^Xh2bY?6mvGv=viEpByxln5wU{5+yhVZ50a~N30H9hg`-w z1es;*unlSlsCsuUkQXBnZEQ?)CnARV5nz&q(8BitED4?L0UONJ6$jJZbu)i)?Lu0R z%T=*u3QO{Dl$K^T6>Pe(Nqw<>Mg{UtLMGl-2vTq5FpC5vjA=kzWPo}MqW0&~i)3x= zfY}ylI5{ttv`kuZ@eUg(<_&} zqO=9eH1o~oYsw}14(obM!e@0MPYM#)9Dfgy;WQVR%h71^5B*!!f`;G+nTY#j^f$G% z^6JBal%OH@0jZSF;ROUA6cePtC0yO}Q&RtRV|N>$8n-n_N7~;0%WZxCO#!NmwD*WE zSL|@^#2+tQPc9WhJv|n|=gI+nQc)t94OoxMucZ@8BD;6O9>(rlK<68qb--xbq~-yT zOm{~-DdQ!E*sGO`8WYxGZ?Nd|Zb}k4hOYU)*~Gl?a&V&#niKNzx#%`Hk4DztTL^J3 z)6jfpLqf`^H9G^lp-beLsFxX!*Ey_kK2@wAPfCzrGuS76Sz=J0-UWc z&yT0EpqK+cwaxL|B{lOiDbib|EUb@g*qVpb%>YkQ$erI_n|Tz~%SU^JXsUMS;jdJv z{Trhg+WfDa=SAqkcS;Jo^_;iupx&=K&pzv+O}R!!e$ISwLZ;vrOD@R14Z%rCT3qXL zrT-|}DgEBoa4JUmOPm!`#7{ry!?c=UF+!UZ_sf}$I2($SJ%5p**^!QQKC+!48!p&` zc*#6grBOb9bHX9quxfatP3NT>#JXi$^wfYTDSSLCPKBM zVzVUjc8wIjj(Jfxt#^G5y#j_+D<9KUMJt#2Fmh~H%=f80-ARvwA>uTg_#qL9r?qw+ zG81SPiSVF}2w;oJ$^s)8IGN-Naw7RFqYcDU&xX)->J&#~N@m1G!X4yrQ9%hAJB`gN&D%@O0qt=?qN<7Sg zSP&OA&xq-TMR;pBucxh9-`JOx4x_)_7@dt0SJz-P-}zGm!0BRr<(ac^;cEvUcHJ9` zuLdQy2k&se=D)82N==w81MR|#r6ruH28Je$;ZhCOAN~{!O165j9LMOKA3N3OM88|| z-+#+DqRic-(IW&9aA|Q3`CJYmgmT+=arP{@^ztw*ND!USXdBo^S9y!yK~^XntpmBo zLqtFF&L8H$*_MSxdQhst=rs^XOrapnKB0MUl!Z3s8NZlf&@*A9IUe`=z3Qo1rQX5w zMPQGz8$1-R571+l1-?@Ey%_>@!-hZ{vd!yd9O%R|CTQt8(3%BNvcXb39Sv`}s~JcN znBfl6S(LktiZ{JM)bU@SV!d~pp-5bPs>pRY(-cY`>hg)W>iQ|*YFebrd+ZHmV=ulk0pka5LUO`8~5hHvw^`09X>d`$N#DxtF(Tnz&7tbc?Mwo=eK}J*yHaiP<^%knLoZ#j{pUZ#ag&Vhu^GnDLmMDBW;yqWJNGu>yBB^K3Tf+vWUJ=sC*TnIwv7{XLxin=t)}ER~&)S z=0bUwGaq@;)7?iyhkCB1r>0||2V^X{dcMo8vH}O-vSjH<#A;E~#M;=SXG}ILHW3>=blqI;Ov0?WHsZqJ_`M7@#h|GosES{r}=Ctl9pQi7U z`V~o>U!~EiE#&h~v%=&fGHz0U99&_-^rNVg9`k~>HYA%mv=ZwJVY`}oX zhn@kP{WEx(Cc=>CnUQUHC~w+*GoZShyrYysp}zn1fi(7m9R$|CFlCHM(WY?FYIa5{ z1|kVKvPd(>ejYZ4Yu#VjFHfD_5IdkwkN!6Et-|~oPH8(sDr-s(+~t+xt=4jkeirt$ ziHPT5rMl5-(LQ|%pUt~whHY~2nnbb!_yJOU#cFO)I|v6L$ii5zw0BUdZ&4dFSQU1p zECn)rQ(D&}mk<)ad@}6LUxk958H(Mn^v~o9b-?Wh!{7eg4xVaNRvh;E~+wm6kv5<$-_l>L(fs}(ihg2!I16*H~ksjdyTA6Okl%DR)z5@cQVrshtWQA;ZpB%a6X`u7HD~WN&`en)Nui;|)aAQ*DBZ&ekFV+D7G$#0>_860 zo%^*Wm-R#Gfbw5jA0v9woG@QiK>4WD^1`!G6C!P8z@Z4WE&U zo#pv^3_lN~WrMj1jFEjhZL(r58@8W>@H00%s_tLBiO2XTsByGDaU7=tBU1#MZ};wo z;sc%Rawn0St_dSxWXJvctLPj4n=?uK=x7eLqW%P@-!~71#${@rigDL@CF$*Xo4gJs z+eH^-D1jYg^@nkSVfjPnTeSBg7Sg{18H-F}J!&RG-w~;WqDV=-TrXG14xGsp+bEUZ7hly%LZ*M~8SzK> zJKoJg(tamgxl8^%Bqjd!ug#RV$Sf-by=dsYlRy^*dj=ZnsWqzSG?f;;aD1KABSWGf zx)Xv5*AHH2h|yLIHTeV}-&W~hBb#>jmpE9LNxRj6(QRcw04v}iE8iMuOx!`$5{@CL z-uR-A*Cyz5f3UZk8~{&ppbfk}VoZRi+oj67xPqhPj5H6gjk%6nI|d*)jL*AyZ% z@qhi7xs*l@L_Sh*5EZ^vWY_N%>j{4*xt~~lAXDz|)y%-_s_N3HKHCc)p7VRKWbfv-gjt?PzugV;#(a4&t8v`p?9^AbA+jl72HPRPqkFfKM>!)U5oh)@MxzM3 zo`y^BEDjo|=T{40-vC0`%H53G*g0iLURF`}d&Dwz)C%)p);{m;w3zVMCR^Py**!x@ zWPWsz4dDZ|Bz1>qLmhj18$N)23rerBZ7D$3ne8RDZxrmD#_#=-UD0NQ5hRpy^{0Ea zNDVv{f0wsLdZ{m~B|38+uIRCk`@aHo9re~3gGx+K2;h4fp=r!~1L zpDdD|DNqC@rdz)A1o1<&O0t^TW8+W7H9FDvJ5SPY;VWD(>a8)|0j8fAMRz%>s|&4x zAKULD<(a$w_~2%tLz?9q@VJAbG}=M%ip0mmzZPZ~fA>iRJW}=g+0_iZWqp{s}xun!AoYd?jYXOkWd~ES80=vZ@ zLNu{Vr_h>`?=tJ-*qS3!j&PZ?&t!tWM@)1*+i*Aj$AOa*f7S(x*2%yU(|i=`$>%sB zo7*tW0#U;@my+Z@?RA5U{W>GxWqW>aL%!7Wl1ZNg^TUVx!>Rdyqt5svW9Iz_f~)b1 z54r{VRR8$Qp(v9`ANH-OG;qHrmU|Xy?2BD)*t@9zKybooRx(AsPJWau>}c!XxU8^; z(m7AlqEuY(CbNsLUTpwDhQr(109UL!+tZ_UQ*V6cXH^VuDX=Am_MSZ1F<2YY@lmiS zWg7+RuCG4(qdHDDr*D`7Qa?#~wx=S_I?x0vhk^_$F7t`q!REZARp#KnXHWzioO?&A zGZ2RIcNZLSMW8{mD?`oTB^^5&debhSzdbfZ8vOI7-ihbAeK6=F)OSB{<3|NUwLZ81 z8nUMkUoufg3&g;y^LW^`2m1<7(UDvUlLU^TfFp4n?CDfj%7`dxYaf)FyTO|TJ3bH% zI@^UzC*5aa)ux0HO04EH`FSKVIjF$mF1z_`ebdQ&Gdi?voQ$l^w)u;OL?eb2@Jf5O6=YA<8j7!~$jk=m(yxi( z&oRuFZ~>)FKw*s~Af z0ahlr1d+yHkW*d&4>wRlACFNjs0Im}kh0DsfsDRf6mk(b7!3|+I7 zrqs{{opW{$FX+!OI0VQ)z#)0rNlZOik9S`af{aQ58w#uW(MUsyv8vo|^c>?rlDJI# zu)P2kw~KsFV(ld5`UofGjMmw{D%MZ3Bo2GemF1ZVzurzwh1IKfe;r75Q#t!m3M=xG z&eGiR%&R<_` zh#T^js_Wl;M3K1>>SQ9oCx7kex>NDN`CK_t9B*w?7j3KR`o!$i6aZm-%<*6ERdJXH z04+KT6nqe7(n8fh#fY+X&spFF`qh-G2`h(CD=+{4JAZb1blk7o9UOdr;6F0M-u#u0 z3d_Jvv0h>u36uTx;@?U@L0A{fi8Jjb?>{VDb*z9(-gXQB9b>JD%%Nh%!ip3+6elSAdARb=z*;Wv^r8^ld_Rw=~dC6rBVSci3`;bjFCMlyY|dXQWOSPO3kBbu+8KTK1-@Hejvr|4|k50er3;H@q;|Zbut6 zc!x+w(u5LDBQ6^Zc}g9D+mCGEQ5LYg~TX-3_SzmBP1<~a?|5}<<_hpC#iESeoQ`QBb)1*@xZJzpeZ2~F}Lby3|d~Rm^ zyovf$DvJc`$SGIfFC$(6{*h1Md*H?1V0+6^q`a_3Kg`pHsOjVR0AJ8 z%szB#an4u+l7T8MYeBS9W@3LVV&nC?fM_6a5HscL zZZ$Um)N}No4|gx38K@wXBZPYqK`ppcxk+__&$cS$M%S9h+~(ZYgR1O}$iWV_o>8;E zVrU__YrO*PWn6IUAD5ZA0ksgIKD70g&E+0GMBdGfQ~#zP|I<@t7IC?H-9R#uzWuA! z`nStU5B9`oB!f8?)8{Fl7>Td8Q@oxfA_?EAi5%oEZke3floTId5#Q^MocHq~+>_{o zyJ>@~@%}%m&N3j5W$o4p?(XjH5G+V=4G;)0I1C;L4#C~s-ARCiK?Vo}x4||J3GSW@ z8r*NQ&$-|I?muL@sjluSs_R|rS=wn71Q`T}-{?gp=ppeV6YfkGt+#ef)PYZLdn;6RA}bUky$oP| z*s1jGio*}fy?c@3qehfbSIDT#x9vZ?>@mAr#Lj6B9^o?d-(eygKXCPq;V_0`rqP#g#ULw%`c4cWaDCa+ zt@fUdy49ffF0?v~m_8@dGZwhtB}WYax{ONb@*jH8>Kg&R&@X}Pj}wGANWf2F;z?jU zu%r$ld>eC%N8NzwdW@5%ALUmpE43XyWii%gs0t*By#M-;l71Wb_@P~fK{5TT14nwH zb`TyM=Q~=^Ghs^|^4bCevY8EPW>dI^nxF^tZ^pc&#)h>z;WhoDh+~Zs%F4tjLY6iG zCgSVgu0IfD{OM+M$PVp+;YZ;)v06ML6|-TL&`%gUC6!WC(<=T0z^L7ONctL|Wn*z| ztfXQTtVsL>?#R%|A8SI<6uy0S1Yh@TiSlmQkEC_6glOyH+h##4%sk#WG+l5O*>9u|J*A^CQ3e)aMAUi-*fr zc<-iyb1so^*753Kr)+*1EsX>!;2hRejiU*(abeATl8j|NeH^ToxUr2k@p0>#&tScZ zGx5yr!w!8`dUEiHh%XJM@8mf8STgN{%ZmfjfWp*$CNE zDCYeQ$UpkS!WmObNW$}9u%dzP4ev5#Mgj-M^d^R=llbLOTuPL@=-8FibSulQlQ5qk zoIx89M9;U09+$de8LMw+E<+#7~Hufb!0 zCJP+)xs5^YTq&TTa~D9rw$q2lT!dvjUrZd`CEDy+9PaWNQ~nzP9iW|1CE$RYZb?mT zv2B4Fw0BPd?h}Miaxd_6Q-o=M?8QvK)Mp6;#PU6Uz$7J-_ar4h%K2RkJpX*lM*q8P zt=lO2v8OVNOnLJg_0UHaSdNNXq)Gx8k-H}e^L^W&R)#0_h33cJ@HWGJ4zY1REzn_{ z0P#Bz>4Wuu_d{!e{m{?5GhR-VEsLewgJm+DMRBBKlHMaJVIxe`pM>9HgB`}ubpr^) z2k_5p-{I+F5J(Fs37~jRMt`Z?Ghk~O_3wy#5{YAV5H&1{nD`c|U4b}g9^yOs@+_JB zLjlsq3(sqrYiDhV7N)$dg~5WRvk5%E#qkHQ=2D9p>w*1i-TuNR_pbRFuOm{wMGa44 zkgev@SB}d@>VJn*{~yj363v=Y(eZ@71tpoZMVtuUh_MH3f6)nTFga|Y6sT6AOhkl% z<~2x!$+(g7SX~`&^T`C!PgU(X4k+mz;RDVQMCm|XBAiNlN+z<7`jgDkPox@~7m*o6 z8WV2U{@+712kDIm*x7W3CjSw%U@K6394WrY>rZ=8Pjntr)Fo3jjrAodbYO&P)kGe1 z4EZe*;cgYcj1%oI6JaD;#!}g*^?s|l(Kr$=r6u#5-Oj)gfR|-q+&Px7qBWc5@_3~ zTq^XT?%!k2R@kxPeCbm2=q}5XSFAxycVTGb0gCfNAMQKmV!mFyI?w}(6|tMq2xE_? zk)Ei~)ZR;(n2QzSe4kg71aMw?xs!u(7Z>85KwqS$n%UlO{D*EBeoA8gOm|7IM}%sA zY5gNqnU>J~Df!0t*Sv_rgplwHOLxZW^!1!D`&<##LuZ~%4-J$MtvH)Q(OyzY(UKM> zrGUz+TGR;v93!>_%v?3HJ6thb4O@1f4INpl{5SE7(hq-puVSu$7|MJY#_*IQyrr5U zi??wZcJzJg*fB8ZA1b!Xe(*_*K^K?yk$JM>M?5~+2-Y9cTmU#S$HxAP~UpXklJNakUE0L zykW!qST%)UD=L35V4pu~sofVPFMlQp?eqoIMfGvSl!^%)_a*(2CBM*`IDllMYJhV_ z!KjS`6F>}y`R0On>-@<2Th@@G^b)!*&n+2rtRCWb@8~T=DcIEymd^z+-v2 zPh8{&Ss#})BW}}u75^X=PG`>lBV2dXLRQ2W+|gRAJ?C2TW#NAz9OQ1QtG52UT7ZK;9@e> z#1eLLizJN4D?)PH&)%&JZq$=rPDxf}= z%@{I~g_%8zjuF@zHJ@PG5SZJ3I@9IAAWaP{KB#Cl_V`M6Wf*3IUl+j^^~B(_vKD`n zs)ey?6=-{IYbTjc<*(|BY)!e7EF50z9yF^q#k29;yQp7^)la-TXp+0!#_Y20(yw2m zmkv~rSh0P2j0VSG=Q6qr@g9}~+Sp6|D61|FiL?ivF=|@2ni?m~t*nDjKsNc+g5asx zLYF0u9ou}ZMUb>f^t{V87Rspl5Av4n3$O!^j}vZ4}IotAI8W_ZT>0(dd#g8!CDv)taBx zq5a`yb+~3ef(4t#p%juM#^C9N^`V_(p6(5JHG&5DGh0n9WC;!bNss|}E2656^SjCP z!Mwv8g?sGiu3p9ZbP8dap?42l8eR7hpCdO_il)&kc=ht{uSk;%e#u^z;siZ?^7*(I z+w#PPQ^p7qa6dJi#vQ&EATS~l{dkj7@YC|masmnln@Pzp*^TXi7(TV0-;bn`ulDyh zw<5e>JaoRH->_zBYn$__+|SXXYi?GLiIoZNibE;M!=`V@=pC$9fJJ50srq=^=L~vC zXuPCF*0Jh>H&`sw^(OUNkdgKdIWeCCuR6M_N9qDE3ymbQHCZr*O+Kc%oCY?L#Jl|d zd|eQnib{doQY{*|YW!xNK2(FJUndWDWWnn6e+#=@vAAj(G%t(X+|dk?C)u{W7mk(K zvcB=Zux``{ndWdyQzd()dao-L0(GHUGWsb(wtlJ)Qi{>>O~!?4M~OrlaFq*+&SPweO2mu#y!NKR^iGpGNSomr z#eT&e7nhGZ9EkG+gK>-!6SOejeX56cH-eZ=@G7hf9_5&rssg?xTqvs5aRWaKyW+i~ zP*dKjHa3L{mD^!qP)sSr6vYnwd<_V@TurRtOky$7Ur@OPIDLU#uh#D&XVou+Nx8^~ zn@Y#{u+n%{4@r;r{?&B>azPv#W=ZwrKi^YsZ5r{ng#IK!?lV$TPI6dJ zKHp5Rrzo5H-savH_TI{2&Ur9gCb|nFs<;Rfzm0h|il|Q6-W1AZULJo@z|5(5!EpZu zl2>Uq8*?#%1?M4;7oaaR=m04{V9f4eyAZ&;NaLsc^{gJ;18FSU&LX5%11 zoyy=e|4LuOhyJ2->WIWGp|ZEFs3ICV7D++pd&nKV_wm zlaTDj&)t%HrvgfdZD|rB>U9UQE;87-Ys!Thh5m0D8hKU8Rf@ej`F|B%Lg8Z1imusS zQ#I5I$|UfEzvW96C0t)(mc~UAI}K}4MN8i?EWHk0Qk-@B%)&Ui$Yx%AWSqeQE=vks zojO+Vh_eVlZd1ciCjxzvIgF7g^vu=igZVc6L~#;>pOM6)J&U>?u;=5%Z>N_*&W+kJsl`WEEPJXtcIp4ZM1Ot5?Op^lt&II8l_WVvF zzCYhvmXH;;=+W$QxyD;IpSO-xM&Gs-s{62WEwec=`Hx}B#f1R`bgjjnUdcFH<}+}t z*SagMqQof*1dk|=Dk18J37-jpU#A!A1F)>d_>M|KjFkzAm@6Ddk9=ANY?aql~+8ESz~)wf)E3$1Dr{eRS`_n62!M&pof!vDc6`CJ}@u zL@+En>pPmYK5u(?lqEVxdi)GC*}U6T>Tu&fz3D`CIJ5C+PV4AKh*&aWqtb7xaBXc4 z9)h5o98$HD%opbva@=EN~;MPnA&ts-dvH9*f* z%F^_BDW`WdIQM{EgQSg*2#o||A>(i>A|G6D7SrT}U#JqvM}e`CEmb8d&0h<4ZsWJn zDgJI0Z#!-AgOLb6WlQX1ZMw5UF<57im`Q_PsH()@LD7#Mphvj|0X@JgA^&1jTncjs z4)Bnb2(Z0TIMZz;v3!x`!OWv&Iz-A}Tny$%m}FiKNQlwVZ*vIxn#3tnX`44{%4pf) z2`i9_TYoqgwXMsqSbvIVISP>0rjZ<_AZ|rA9J;HX#LYE#vn!s8Eg`4sRptvv%ng?| z?q`4Vw^w>PX+!2U#ETm80mt-J^H$Q^4!d%{w5yq?B&;5Bg+z(wP-8H`%%-XG4aWI9 za~szMzU`wZzxiO5+a=)|GUqRPpz?iF5&b$9nf$Cp8mq--d-Hc*TlSWefp$A3zZ|2! zO+KPI3KB&-vc@HD$n+Dkpc(c%eZZmlu+-n^tSbW)#nx7vHh8HKJhbj8SRbDD*--2l zR_E17sr$lWSrt0gOnUUp(G;t3{J*@EZ9qn8z~IOTMQ|dFyqEdh{I%n6mnF;Ualm_5 z6@8F>;ymITo3u@_nScy9IIlbh}d}gL_`dg1&rrF__ zSm6`?d+D-D>hSI|(x8mn{0JEVesXu6?-5TC!O6FIB55l&p zos=^#ZyAF`<{l^rNE#DKFted^bSZNCcFCO)Lu=;z$66aMr6VAvX%xq z1FgpB8N)HBY<;&|^I%vVWnqiWRik|I=i4Y!31|lK(A) z_K{*XW~KksVK(j{w`RdJ!9psh_ct~?9qEhhI{EhuXib;Jis*J^6iE8%6@;~dPZBiV zdX#wqwZD$OsCo_2GzSM;6b#@(Yj~hMbhFh*1_1J9OsS#M&^%xs@Y#l3{6-FszJSw; z)fmt=rgr3mSV_LaO7(QW0hzluX8pcos44jK2?|~}u$shq?mC`d7TsHehUD<$E7^H$ z?7mXgC0-Ee2(}CNqv0HGGwMW^*cuF2QM_>G-OQXo!nMFcIOKHu|i2^QRtQ&Eor zwDv$8m=3bNZ#)XX{E0uRHLN+lJ54#L`%05 zZ?fKyA>^s#>jE=-UHD-z{>t02YaL1E#&53jUiKQ5RwMh}aS6eu$ZyKyA;6%;(+)W2#^x|Iz zswzCM1JVc%FUcLX&GfjM_?C~y>Gt(D`_shlYYY;c_NbbG*t*O9>}BcF?z0N#(=2|dPi9kqx}O@%vcbtxyFxZ%B{m|-%lnTd!;sHmI=3# zY#pe#TL*7JWK@x<*ZPy!ytxqu(E(6($?iz}8&=2Jat*`@-Um_Rh-QUFfHf5E(l$Fi zSjbU>{C*`o%`7C9XjN*BTEwwJ9!;K!C)FK8M7v|!jjk=;3;jKLQv9vlIw$>T-zeMI za730}VvzY-mdP|%j>1khf(dYIX-F_47j=c>wbu2GnYE2ka6HE-}U@9YiSFy zlu=J^3r+8$_5Dz`Ga@|FuTwV67n5P!zCWKG6Ywc9zk?bfgeI(HXyxsC=j2@((zFgq zc1CZWaNZ8!H?{w}Qj6D3{B2qAByoRo48K%kH#DwO?$w^qE@+s8vmK> z=d1?-?6jm0u*SLn>%KtI7IL3Xf21~Mu z90KE9n)~+l32op4{L_>4?ptB%SJOcRJwYPA_jMDzI2PeQY#hm7Y1RMZ>6-$wHQl>j z>?8@0ng9o^8i=x7w>~Jw;FOjqI64ZrFPPjVRoGkEQb&|2)*j}4Mj2AftZRAr9#HKY zM5g3Bjin<7$G{YFlE&evdvppSR%yofy#c(Gs+?G9Bcf9N{sNxWn7PhdeTHmbnh%=3 z-C5*euCEk~^~Q-$)S7?P!oDGeye8FS!+*Mf6j=pCpO4VDTXba2e>sJ|&so_zXOM-7 z*TQZ&BR%`jmLFZ7I}EQVDhYJFkpVg;#)EHVSNGmN{^4qe`P!Prc=Gh!B1xnGfLJ?% z1{U^Qz%8nR3E{2PwfW@NpTJ&*lpq2b>4A%_Lb}SEaxUTQEr*9@ z-G;ie_NzR$CJ-4~XyGjmBuIS3JRoslt~%cHD^2PK^L7(QU0|xL*8oo5pUi%i9Q?oU zRNX$&m<_ee{_3I7CbS_VZa!?rgSVnfBdUubff70$_5eZ_O^TJ0}Q+>8IW{(Y2>cc&y`zwV+ zgkndNx zgEZ^laB_@`I2IA0prF6a>;8SzXB2~2ey5j8q*th=E@kmX6BpO{v&Ou{RW*}^Ug0R% zUfoQT;3>i5#e-V^ua#f=g`?ePliBT!f32Lf!gvzVYOS}o^g<(+zt&5RB`u|8y8*&n z&H>IFzJb1-mRV8`h(u2CQi-fmEm18IV|J|Kw^}B4h=i-<&u?#(=xHhY4h$QUd7=G; zdQUaqKoS-RVR0*DULuV1<7vWW^Gk07QtoTE7-jtHiTh6jztwGQU+kJm&uqi)Q~lc; zVpk4DHQ1ARXkLu~xRRR0P0@u!izxfN#s>1fRa1gJ+nwX#>a9L|f8o5a{AExPimbVXbuRb|ipF3QOy|Io^ z`Idc!UAwfrV9JREqUC%L7!u8$zAGGc9ba1NzoN}idGJ&BDB|4@WIuV$)m9`+t5xsS z@nJntlDSgfgEvYj(dqDaA=`S@wXbf%?fVZ;=2hqI0GM$4Q;nUbj1Xb8z{sNWVVYPOq>%d47&QmOf+FQ>{6#>0gwLph&59xqk^sBMnO3-`#2=}+8somb3ovn8{J zk&~YGF5|IIy#Ud2+YY(Wj73{hUGQSpx8!)UrJ_}+88;C&C-V9CSn?os*VG)5f0k@9 zh%+$!G7jU8b%K&MyZ1OCw7M1r7N?R>@Au;jV}ql2b8CztEfxYYip>X=jfunhD@@fmcOiwLsyw)t&^ zd7L8&+80~B7X34KcaZa=%Z`@UO?#}6oOZO3!)gNdh|4CjdC$z%nbo=F{U-PBy zwvLl~^*@)kRzU^41ylKED}`hXcQdl%phnxj&~KN(%Nb=Q_%!@qSwHkyGWDPGW`C^i zJ0O|mf4=*_U;LqY9xKl!+W+-Y;wnEFi6%`|gQ(P@Pu(9%*mWg#c}Qv`szpJLj1}v< z`IE1kYxV!%5zl%I>-SJ^?Rn9Ug5e43FLFFyEU4q%jQz=Tl{6Nc7GI^U*E`fGbIG z{M}X_2Ab%v3rOzOjY!zZPT0&&7`t@qNey@br%dTB|DGZI)v8d&u?T*dME2oU9 ztLe!$Zh`H{jWx8u^UuumgX84Y%9@(~@{h!Yp~KLF=B~!IF3HTxxym~9EibaXg{4dP z8=wkLV!Tx39MM@<;pz%ncpeBU8}W-1EAdgpAEZs^m1|2S8&nvez_$NTUFs6V$*c~eWA&O-n_vMpJi9WwZ-%d0imLiVan718Tjm1^NOgt3ayf#00b-DE+bv7> z_vnTBWHG2sSAPEmS`)y6%rg|oQ`W1m9dN4VsOzNcKO%)3>sdU^cE)oL6oMc>ay$~i zpxS?&Ud_hzw_WyQdv^`8q-HEU6j?ts=3hA186{jCyBcDYqBZ!`CArC%gCY}XE7oj?3(a`cj-0e;nUBa zeoY2ME=(yaui;ZYHp6!5&)qEIi7HVvByH4|a0ABz|BqK7lS3VI0-By|UCgSHh?p^n zOASr{Hxh(wUxb}oPSS|}Rx5stzLi)mu~F^i?$M&ac+#}!$^~N=ID8hSAeq%^i+L7+ z?9JUAD%~8td^D#-C-Bl^LsZ+|>~tadPx$C*rP}=B<1LyzOZQuTB_h>*asZP&*^r)a z&E|3|rSgWmbsmE>kud|^*ZHWz)F#5>Lkl>0gv#t6DrT--cc%l&Z7+}w!WuIgH**9GW3)-9_!P+Qd#97i@QWN2TjuCmh9`hIS~q5^-77=spRd z?zhTdB)qZ|JRwuC`^~c`eYjn!p#NaEWvDCa3u1*WIn1^p+X-rb`3-X}4!g-%8igX& z4y2CpOU8r}b~uzM=QwuvH!NP!Y8u4_T$Jj^;*3a?e*I@KYgYo%ucwK@9Tm-XPe}yuUx~ssx~NqRfVqFE#^87# zK#%YfSB@T;dQf1Z(C40LVou_mX4x_oq1S=XDyvBGd|AMV^>37wp&I41+a8 znut75kms1VQoPp;7J}~cDSddys$fTHKqa+Bzyq|0ucmJkU>UOeafdsO_l^jNh9O)4 z&gbg2h~gjyN5J+*)JESiI67pKhZ>7o{iDzp{Cz(9KR#g<9CjI0yTyt-?7n%GRn}hi-Vi(CDh>6g?nr9oy3Vkxd z^XY1k9sY{xTTLU8fv$}zNgG9j!p+PkfK3JX4TYT%D}arZzdt+msu49mMvlt#pfA8* zsSXi|pYx(5&)*(%7PpV^GPF$M#=J-DoJEM}3ki%Op~yf`EkLfxV4MBqjM(x?jCXeT zmYyiBV;tj4A5MiFVuJR|jGoAzNe(x^B;0$RxtzfIGX3Jn;61^s#&GtjNJP1;cvIx0`C@;Iy34O@ zf$lw0VFt?y!veE_fa);v0-XyFK8nAHe77YEeI4mqL2mpNhoOp4vA#L?eR8xFUxG$Y z9#~IDl85ino2<{?5h+ZV@Yc#Vdfz9HN)d#`5sf4OVzJqnD0d3nxp%?qxA#EPh{F$X zLzKUKnLWH}T;HrQW@-HZ2XDz;Sn!62P12dHy(pYUi?Mv67xhw+ni&tw%=|JgI=!Kd z5_S|DC)H&=X9(73(Cve+%W*wj-?c27Dvpc1`2H>5(hwGLQ3rVRp+;=ga%+Mn%5UW=P0K%aB1iGRVhQH{7 zwSI%O=31qn;DD>#3$@%l!3I!aU5UQ(rQ&O-Q^brSWMq4C z(FA$+igx7I2W9UoyZ1jpLEQ*!a!l1j1oblpU!9Tn-7@V)cG;LHLMV+bvsL&86{IpR zkf2hDF)zVcAW{Q0fIp%Qo)Z;#i3`0uY9E??1-E>_f&+ph&lzsGr4C3PAgt&^rLeNT z3$$epi*XUcpQ#^I@)(e-ykS#|;A{}rJUl~Twt_T}7=9dc@lYJM*k)5;(LB^DUm6{nvq}8dBN!ntW`_sF8T2|6(RCL>{=0mX26k|^X)G@8ri)ChUPv-?v zm*77>+h*noTFOsHu&j_BJhJf&KLXQkRMa}Z%c~EenS37F~&PN1w5w%mni>G9)K0exkTQ3UQ<^biyZx&gnr=bHsxBpOF+&ptW zsueI5JsIwGB@h}|LlX{(q(1V}OF_aFcwmBC5;j||^%dcJ&o*nD`_IWmWuLV<`)T{P zTy8CgoLNuKGD+W6Ao)^gYO2SbSf~DAxGUl%9D3_uF*kH#`x_}zPY>EcJy>y%(2IlL zNOav%$MY_E{C{X4Z1r0hWIt8!Kj(+OPVFAQq*w(!!{A++lApyrzxx*TD2`+Lag{8r z6s?I~RGq2|Cj9=z_eZ0f7b$EWL6rZ|`@Dwd)V+9u+Gh8eP`w516+D z`gMNwkI^k5sbdK~5JSIi-R#NT6T0-J?o%%^RL-#MjHb{s*Ea&xu;11=w8M|-scYFS zn35Qn;svI#CO05s!(!qX7XO2M#gH}Ko!(gME~0cdtiLY1$JHM}#!|#^$Lkz>MxwDJ zBhHMNzME_5dLu2x%!9y1h)r-V&#OMxNeTMjt3^WlLg-Zio1VzJvAC+G=7>8F3Adj+cA~(_W`8w%E1tt&$5wvX> z+RVRQKVxBbeNdP!G9Y26=dFLdVMt71$9AL;3rv4&p1r%y9eJ@V(d&gTgu!gOkcqdf zEE#&iB}Jo@Or9lItG7Y>ja^+p!4Q1KA(;^T71!+x$y>xg3LS;nHCmJuniSbG?X4Cs z6hQ}-gOmqrx7306yq`HF4N)JIr86(6rBe|RlrzNJ`Nu8zGuZ0_DJaAASCC&a@8?5b zG$oP&%kD7+*xj%uC$?SVXkQU`eIONiPiTD@fiI``5%EERlSJ%A!-W{cuyv}6uWV&Q z!O9(x6?P=k9buq?=_~Y*Jci_YSp!7Mqwwpnw#Hl>g(yIrvOrg2K=I*|J!)|-z-Na! zEhoHyt^!FL?2iDbe17HcBw3b6aRx|)d$oT2+Mf32x8mO!hQBjd@c5$fv?3a2=@oUz z5+KOY175M`Lj`Y{_Pa z*%>G9Tk8O!E+GEmFDJ;X5gZSCqJ%nKrZ?1tXFR8D%m@MsWUJ@2lw`el+I~P;pqRp0 z*BSj?Mois}zmQB4q|8Fo^FNbjEih>!DYd*46{SuW6)QF!H{VMRjljeZzUuSdo9ipq z+G2Np(Xfqm)oHg+FFtXH_q|ER1}Y<}7DI|`Ry4fPx%Ah<@&|5!qJzO{xRm83y_ou@ zhjd~Ygp`%$6_Ui`Cl0{DvzH!B#pKdTI_T<4GkE6aadFaVbQ-?UwY^0i5aoWGogQren({Qw{{;nZgM9u?XCTZ5TTAGBiSuMw4AR4jLd^-5lvPE_r;&GSUy+?% zNF3CI{dVNMwNZW4SeZYmWou+ERIsK{r)}xB;gqI`!G4=&cYmFh45Z~BNhgKwr_0Uu zD;>)tb$VjJeg_8H-113<7ORCwivX!{MzXgYDl#>sfE-Rc5v^mU3eA!4lE|O`(n0Rz zit{9@S!lOC(CV4;5ilxngp9!!k$kefK3aiS_M*T?|9;OML%uBC+$iIELYzXWhuG2h z-KGbB6#6S#f)I>=LZM9~<~u>v;$9r}?2K!ZF!XU{w3}ya1JMr}4GU0j2ZjhYdU z06paUXFcS)O90Ykp%)tayD21r`8Es5@J~|I9&W1JNQl{MD)?}VgD+9$zwIKlL|*i% zqC^cU+-bIP{xF_?!>qfNVTHFECWP~>wL?y+keYfWBx_y@W6bZlG58vgOUWbYh89jC z^i2sW3#7)y-f}6szc-P*))Toc`&qHa?5BFqLu$4DSIF*H5~KQIk-ulh9gGR_>YbpF@X>TxpKjf9HL(Ix z$k|YM{s4zbn95%cK){%7W*30=j)BSfH$v9#V9t9nIH7XVKc}T{QBUV32+|!*O}Od# zzD2edAo4KxWBxWGk!D%}QD$zb#NpJV1x>?9-gpi&y zNOOy0I>|ncpv%W0oRLWW=tIKpw!sfw3FYt)C(##3%p*Wz923-O@P`T@q|D{V!;}v7 zRQ+(p%Fo0wYptjpeR0u2(557W3(4O2`Ryc2GPaDr@+#Xl#?dp~F#9P4J zxK@{!`^HT^(Y9J#d4M$9lVS~a`?n6GKGD==P=9?my+JDR7d>*|hgli^9fjDMcSg{v zq1HkAutp_i$Y7oSpeAnL@%!~8SnI0$$ZflVEJUq4CxJ1WvmvQv{X6HWnWt~I{|KnU zq3*x?au>DbOPj;L1upfdlN&GJm{av?MIxj$q;CAC2vm8^zOS?CSwVw1EIO;XmA=m1 zE4>-)5PCx_7#jz-?zdIBPtEJE55nn-8=03h;YHfdG8!5BA(}k2Q#qFaW}xZ2^dgFK zm?66VTTDh3$u9rW=1T_;PUtmrW!QT*z&UgSWVo}O_BM+~KjLGaC#It0PbO(HbUT6+ zy@;tVYiNtIboUQ;f=nbVGI42Z>1gx1i&wB3-eG8%;RbpyhR(?{`@XfFqo593Ano;v zkVK2^S>&jfLWM}atpp;v4w6XpKU0nMij>OSQQ{B@j+{7WJWxyS$#uOfpeAtPE(3`U zt)H8t&}30iV+UxBqeAOVoR0gCQeSd&6Pz44dE=gmcC9MyrXIm3lVE?@Q1Wre25mMp zwdysBBz-;qQ3zekFa9hSd89$kyoC(izgi|;DL~}iq#;}^Y?2iaiX#VK*rffI%VpiP8A1|h9KPfCc{6c)Yf8&d z-aXu&De_fmDNbW(Iqt+MGobT$(0V?)lZL(3BP?4IG&t2ml{xs`E@%buCY`p^&Fjiv zv;^r#Mcgjd4BD^uN5jenI<)3gV9WMPNqbI^evLUert`M5%jVgr7JsTin3vj z@fL&U2}W!FIXTZj`+MpG!GqJrT+nkf>vV9~^^t%6$6!K}UUuT>_&J`~2ajP^dJZN& zRs?GWVt+8%Vi>*LMIbt6y8}?6${w@AxZ<;Ge8ySnBdk8I%`i^kp7bHhGr*~w|Ka{H zg9yd!g~O``8rVWBCIt?uLgPe=ed+){1q1;q5f6S4U*jb58V6B<{ zj^asu4uunTrei<&9N%v!RG}pPA`^Jka5U)k6UTxO>O|86gp~*O9eoJ#%rlG;kyOO8 zNgblTPR3lE)L%nS`AD?|6K{y|>v_yB^qj^?lMT6*5{z`Wca#eCEazJ|1p{TonRtG+*Z zS&#WQhM6m{=hkNu&8eAa<(7Vw+A7BLZ&n%1m-^=SZ{GX!Rf5FKg#ACsrE}_mxBL)V z4a;#Ah{$QlUwORNzFP!gNnau17_@xbvcRJnMcUmrlRs}kE&0?|d%BbER z3hX0PftHds?FtCYWke`^cf9QjyFW-J#5Hh99U#|j}Iz=R3tA@<7XYvTsnvo?@H|FWK59VXT7}g=z z!i?>AZXcc*cH|8M(%WAGLLLt0CU3QhvVb8hGhiw2Zh{-GfpIy_->&)ELRWd}XH}SF z&Va9v+0hsyzwH}IDo8%Y?%HCQfQ{C}tomBg%dPTu#D^3RSoQ1>xOsghvulmxT#+(Xa# z!=*gEdEi|p!fpg{__P!i^4R_%Ua;K5Uiop5zoq7u^?y+t;gejE_+RV)e*G4GF~-ce zm>cb>nhZSqad5h)e1zRGd@Rc73mmcYo>#CLOpqC0F|@N5uW@4Ps!OGEe3p%kW*}Hk z)wt3;nu(pB>)8@J0sa_!yQRR(#OQva-FtE>UMck@oO>_SfJO1OCayaek@B~_{Ia1$ zz`vvoT4pSf{85h<())1=3lJN%keJp_#Zk{V$hkFHO9@eRGV7<|1cZKP${7}9}4&@ zVpTOrRk)B86A9Mj)lKR}hAX$JBs|iwH}1C(GO|;yWj};ptR>&~!-?B7#Zef-K^jl zictH8tSDcMPkmQwq2GTI8_^duui~eEu54e^FBZx;YDeu&_|a46^)W#G(%uxwV;oR? z`I&`)$Tdvm1`|(ndD=pcBJjYy-|2q|emH9-6feOm01G<8Zg)xfdpf|kua6_=z6>rVq#H zg{zfT8ftnay53k8a2MA7OUwv*1y}|DHVkQUo|LAErqx&S%{k1EmUUhj#qRNzTxmTEJ~egUHf%BUvd8u}b-c)KR<27riGzHX z!bpkUpOrJBL2O+V#yh6p_2Y6D!T{2DLWc4S&ab)$&b6C#Vo}|7FFPjSQ{QMKBM@MV zajaIFDo1x)NQq5lqRR2+u?UrW6JmHtqTA3{x8V45ow*?=<6!>-0bKFf!w#+>Xp6r~a-EAgdx z)DY@js_-!4>#?*MQq4MyFGO^FxkIr1^N-$ zw8KvRcoLzUovriPa=#R(Q;SheEg_`$AAAONz>&3gD3CI)Us_U)%MJLl!R_|@2+ji0 z%&lv$=k7Ay1n0B0*L@I43xMAt{A|9I;p>Vucfnw9MhL11|JDYeB9bC;=)+f$7{0UQ zFSv$BSzY&G;@koa@}2t08RqRnJ-p7AX#$wX*-=A*7UAUja43iRSp8#gn+cfb#i9-J zh@LJ=ai?SZ314q7^EAd{YoQ9xW8s+ha`ha;k&*!x#xp|WP2MP$N%(*scYnT4uHW1N z*<{S=9t*n=(9P-o%}u3pGq`Fl*h(^-2LPvKdVmR*5ex7hUcD*{OZB@mT)^my+K(n! zj>b3qiubfX)vFEkrQ8-A#lv8Lj|^)gKnpiQIoeieVhN}X3wfVyaEWhNN3E8_8y;uG4|6;kORO7p`WE}>&e6D(R3et=8d%2Td@**YfmWXKl4de$D_B`8Ki4Ho#gjXY|km?_yC601rL&^r}XqYWyV9%sj*FN_#K1Jr4Od_kPhAG~t0Sc=UWtpw!z<*q<2`>Q- z3Qml)@t{E2pqrieVDXT=s|_HIN#wf_H?ZswjtlyAq6AA!2iP8$ahMFP$3w7Gy8LpAM_-# zMs_)FPW!dIp5!PGvADGcmJi~P4xL{CT7ZOM-@+d@#dz^^jC8yttT$VeGGE`7794Q9 z6U9$@a@GiV4>`Q9AkTMJbgj!8;5TVb)+$g;J`*c(hV)V9Af~ox9rmZWtuW23t)6Ws zvJLxpiJ>ORAy$uL(ID@ZRKGu^{$17!9g zimR9H1@M{pbbSct%ks4{zQIHmTQ@TJvX#wdfNN=I{rhqgdQ~@Ojp@`B; zXadqCfYL!)s6vny*unpYeRt2hXU~3KK2GM$NoJn8&%?~UzZ-QRs!aM85>~J)0&meM z?@8`dPwq)?y#XVwASazn1O}9D1-wP2(Ti~f53F=%x=|FhH5t;AzJ6toC#5SM$;^M=uEW zT!nnYYrh_5dLg<4rhN@UjRAVXd5#2BkYj-%sA3P`SqOk18%{48rkxDHC|_X+Y-7TmmHS%-5=K6)`AEe>s|pp$ABEf}n{ zQdkYd!pL6h2ZV!c+QgbQKg4>j0=mK%;mbO721GPS_y^!0l4wt+vb(ewYYbH5K(k-U z`nX$$#N*R^=)NTA#c?wApP&T(DoJu_RN(Vy<1H%aToL1v0k9;`jrZYy6mH5+hhcnw z6Z~1YsQNmP_(axJDHZ$E7Vn8LGUB{}n6Ogbw?syG5DsyI)|Ugn$@Pa~P^9R&!;%)w zXaBDMkTjFtPZWw!O5l<%OqmiHw35L60 z9TXqHq~sVL{@`B8);BuETukoh@C7SJ%A$~ageFgym*WEu;G}@WhpNXmS?NCF7%phh zDk!?bT_A(>)&@sjw}U?mr+NLNCz1aXfSM|e`p7bCN9Blq2;4OCiLzGXg{|pYD{Yns z>M>0+`HK@LM=^@B`xRsAqLLUvuKTO{=#35Q?Qi#BQ8k9y}nq0QMBk{i>@S$)-(*fn~8@VWS9)fYTvn zdBWNskHx;a-v%mcH&M$*4(!L8EA#_LX&SwAPlZk2UVgia@N^U0N~3CVjX7D`Mcds= zZMB3rk-hgMA@-)dXwV?Gx}Ib|v4!PBz@)!y%@YqyCf{BYQuT#{vQaQ7uH_E;1GxC8 z^*xUQ5W2>SmKaW5-m&p6Q7c8=iZ*o=+p_{-4*-wKgE#@T3)germW^IxPdZLxTYRsp zalZq&iH!JHCh66~7Rq39YNr@$k6 zyJpME@AM$JboC&(JMoCCAkF;2{I^)7e+Dj)=_(e`h!*X=@ahOOJsyOdJXB-*Km`7A zZ`p5TYd`e-k_3=k!Zh)MZSx|s8EK>^Zr}Yq9=&>a$HSI(Lr-Qc-?arM9Pw!j&L8aI z6UjVW=9%$csrJME+PtEH|DutylK#T)qb9K{7U+GJIp(e~&6Ki_LGbL+r+wl6wq#y2 z%=1oGHNwxFiwY5c;QX3D+PA|UoQcV$8DFMt#%^TOZn%TJc}V4U=MGER5=g~@X8_=Y z-SD7iqseb1-CCeLtLCX&m&cc+!|Yqdx4C7ngI7z4a2T3RT^3VLI8A0 z?3NyMBiIh*Do82LgKi9V^uB+<1w?A2!mnz0_5vvm=*U~uq$1c5>TBg^>}N^LgG}`% zg|N^#-!wYtJoeZ%rL9BTc)ht7I8Pd#%Qc2h|oaq z2eW93Dj-jHoM3bRu7Wh9+t0&NRFj#23Lw|TQ&z)03$vd_f!R>8r5w7qkpM%bifCU| zy|=)oV{yPIACE37YGS0^_v?RtCGz4s0Qg!yT z&;5@AX%{j_6#H?bTzD@4s@^S3$rrg=US||MMA^ZURh$g1{}u!vRT$X@OUqG-C5!wo z6Ws%HTkviaqKXZ_n~T_(9%UsDyYoO_lHa3ZzjiRJ)0_QkZQ-I7jJVQENczCvf9yx( z*=<3&ask6(BXPr8yA*+0OD|Q^1;QdvLY&)b|3j7K@^10(YQ)Yx#?t#Ax0kPmmj{F> zrA)GA`ne`I$J~56q*X|94&Wij2Tg2S`z8DB&HiaU<#hs*UV#*rKHdfs`*-N3uOtHk zv)(Iv+`g0$X_`M$zTZG$b1IfJwdJC0Ie`dJwGrVV~ z_xx)x00yl=2Diso3e;z6xX67{nLXi~QYLPf7Cs>uKF-u@z|T z3#3qK(J@ax9R0-`>k3L%Kb0CX;FkN;vtS)Z&hHWRfzwsDLKNx^Uh()Az4)iWuylDi;pMQJA_7&ipRp6t@K1Ct_JL^9H9|_zyvH!}@cSAIx1wEdQkDXuysRo}c^7sg zTJO5?4e=-&vth#odS_aB@rL&Bxe^V&7DsQT=VgTa z(6p6;Vu7Fhrb)!qX)(vRrx>HN=$F&rk<`J$H@#I9R!w$y*{fDgoNwdl?#tQusodY} zhMwvc&VlmovW-saxMyoFy+8kON|>@@;SYe`GOxG`sOA(c+=B3a-Btum8Sm$(?{mEO z@RW}H3Il;Gf&~_PKOM*dMW7rHxSM-S`0hUiv2vezHDmU#h4|;3UNkSnK*VAcS4^}V?(&GXS;h-!TJzN~+|dPG zM)eBldNsxPXak6ZRKs><7YrIuoY#+=5(X*vf8TKYz)1z9V0hJj0#En3$n!c z@moA)F`fqVCiqlG;w#Y1Zy^>BHD3E*7yaSR-7BKuKUZ?yYrnhQk#r@JK###a-n2nyI>CAH*M{zjF1XWFCb;%*xoL|_aUUl z(2zf)CCX1-+-qQ8}k#Z|>QwE~^;Aw$a(u$%nWiU?NS4u4VIJIm9R{=?_=-3KvjY8U#@ zIpVJ};lnsLbe5+=bwms#6vWZH{DLgj+=$(wSA6sranWbak3EFGl=t_;kqdv8oXtq1 zA0;+^GrG&^=<)a<_isFWbBoJ;M{kiW))u0_ydkT#Q+}Yd-no=P82pB^idd%jKLD43 zJ!*FL2Hb_7QFn1f-|M7*x_V^ABQ3&@8>F78gD^UGva#AzlJFuxE|u`TSrhv7oc6mR z+4_*s1J^4cuk0e5@OcQaN4}Ky)8~s3+v(QiN6)J^e1>erjqAmLlmvBO^@uWS0>X?7 z&?f89rRv*iD;?=RTFj8x=bzt2p>qU&|AZ7bdk6?^LyP%CDkf>p($a3JIb9W9_AYX_ z6ZEKO0>n4~^C2w4V}bkT7Uo*3XMQ@E6i)m5vH$E(A+3-oXMTzBerW=NX*&5!jdRvY zpPAI7#6chzvN-tUIV%sr?d!@9f)bNUg`WJX0D;q=L3 zfqWTN5@}J@YtqT(=ylN5JO8%&i5{}+ga4;C%A5Cm1>&$(ZsL1Z&h zd0V%G7yT=VF7C~h5(w=jt@%g~yO`5wYgHs+0zJT;u^;oJ7H=MH)aoln0M95;F9PEs zFQ4O0DQR3T=32#I1>KW$N4xHYt>=P#r+}vz6St*~cAlfowt)h*Jmo-01ToY~cIaeN z;dE1Xs;Z0!Gp3_hZ#B2!86bf)`+g=+EXrc-ol}_I@=Q@$AMy97IH*512PJ}GLfR4L zODb%Nt4K8;X`@5-oBIvCh){vl^JK6y66jn@{Uey1#x^a6(!%bUd7nRF+beV=E*pdn zU2qRqtTDF59Z2-Ge-RZ}lS{A@ZcTce*2{HzAhp$K@YbE>4eq>K;Jyj0mWn(5;o`-G z(mDMn%Hn?h#N(M@e5O_Ty}D4X2I+e)050k zYaul}^?ibJ`TH-u-@)x?ZE6-SGjSI9{7-%uB!$Q&4!0p&`+5*IQ49W7JW zjwx79->5ke_F*U4B&GO!uLP+TerJ$kTx*D?ca`v!N!-t$qr+Ln*6Y1L?HHYGE_sa9 z4x*~r!v-4@sH9Ir=btD$T9OYO%3a{vPaEc)E(~Hx~a*UtcmK9Ui{Oss|m~)UaUh6R>DFUV7V4xfDm`<`A0m zms>ABU2R%tB$TY%uD8v7+#ZITg?Av*A6(XwgznUJchP^{sM9L=Y|?ZU`4%>mO?W~c zdSh#oq4bYnaDR~C*Ys|_-EOycOkVMXR+2+PlOq_w4@;XFA4Qi1BShI z$>e;Z!0&P_us+W4Zl-Qc*sTJz6OH(xVCUu1Nu;w}s)bq*9j z*3SJyiKifbWW|bd*^k12sECSu3S>igY9GCTo?zjGz=2E-o4uWG;2$Hh!nys5W^SX+ zQ6)yy*=>-;^;{B%ZDm;PMZK<+_Ai5XQ4nnsp}Tpr-!`Zfa+}@ho|cC~%2!{;(k{{9 zp>##8UCNQK`)$FTy+$6?6KQ7q(q=auyJQu<@+((<^kHqZcCc#Qc*{2GoEr&lHo8f9 z9E|fgWE)e9&x3O7UWnTlq-7@uIOHjAWU`Dw-zyFO_Q zLb12HKSLaFhrR4(ckwIYv02}5sIqCG!6wBuQq_@>kgHZ(Lfj?uE7V!vHbthMg1~RG z7SF2Di*s2t7>NPR zXPp`%R@>IR+96wwr+9`Zpg5-bs;9|iO>t{ zKp#}2E}mll2uQ)x5CtGr8!kJ&oMu%1@cT3OneCl{~e};F3V(>*f8EJiO=0fQ(&2^3vnBJjzca=#J8Y z{jutglJ`XnSBuPCtQH-jA-;#awqLWegZ(IrbVPF5eh$nN&U|UyFQGN5Ir#=Z9rKG_ zJM+Ai%PPNbQqA&lpl9oNsB)72P%Ncl^v93r_P>@z?*!q71LBtrA-T|P!MhYfW79v9 z+dZG7!rKFrhFd;qNt{07zO!!lXt&TG3(wA*(X<;(CT*s`inKZ`q{0@+C^zd84n3E! zLlQ|ArO^|{S6yr!wp?!PhK|iU4gU@ecIR~6lqnt0xM=q!Sd`p;Q5)y_} zYdg8g!=>&cP2~EGaO6Cuef_LDk&Dwij%czUTAX| z)rK;6s(2HM>h3pz$h;x^HQ6QV80kbm5LLRlTRlIIx!q#Q!X-X-C7(B%^qsd>f57$?>tU^u zc7X9wT!Z10q#DX!5|R!mM0g_QC+e5#niX11)PqK0**QIT8=l+$oDwd~^j2ed8*|2;{g))IKT7vFw1p z+F9FE+SaP!Pe1I3_vXz+&os#TQe8V*lVwzuGBIra`Bc^W#f|YaMVm^&Y4TFnjl7cmG80)j$FzoTQ_Tio z8$;u?LmnXWCms@Rts6&ZdGE2S;0f)$B()c00w%I0QBlaNVEq<%|3yFfemI0LhkcwcZ{=d!^RLMXNJ>66nuZNU3kuXl2 z`xw#s#a2v>6X{rxCrqEI^pt+bjlnDGR3ng;PT#92wCSFvcD=Niz_Z1Kdgg2_^le() z$onpSuUAtVu4ML0!^_6baFciqt{q+SQRaK z9ZbAZq&#k-c zOd*B%>xykexVd|fbocMfeZGRp#0|eS%KpK+zxp$xHEp}+6{u8>fp8;Lw8`W z3`JF*o%s`JBdW>ehE%27w4gmM0b(FZsRA;cuK`G_Pqh@rs#h3`)ZykA(;`k*80K(5 z!cu5+%#R4x)#R<4LQDid>1~49QY50z4oZOTlg&?Utxg#*WlN+dbwC?OkFUrZ3%4*a zZ0GaT{n^Nwr;r|ARE0MnO1P$ekgRx;2P0*4xRf$grR7rt>U070(1%z zO}m!vrg~ek2|COhf%|_$i7>zL{!Da_(qA0i!~BMwk)s>qeDUPhnjD8+O*)}DR)5D9W8N!obf+FP*I<6p+A_AYX7)QKTcBzk#(uO(7a zA?Rn=6`&Z(ZVA#m0q^O^&c}83k1Tj$6Ru%Dc0{JlMd2C8@9W|Zjsm1E>n3mh{$X4s zYckeGpPu?|5c=n95cH3#MAS@HN@{3}b9ZR{6Wc%Zi6X$W^!Fi~(h3(xwFFm<-Ne6) z3vF$_`qT2Bt4zOrdVw?Lzig)@$s6oc^(^}g6$es9+nRu$&O2fs9LZ)_YYIVj```Tw4g3(diSS zA>Z%GFXrCvzWhk1#;Cy!aUa*Sm1qcSn7+CF553|WD~@K52iKW-yAP?i8pP+s;`=A92$ZEtI;i)ioG@#rYI@F?Px$ z7F@+7qlucyth&+^K~i17^QdnLVeOi~gz3E@Z=HVw0G8UPNdM79_4`I+Ft-4DI@CS; zCpG5GTrAeAfsq0ED{kkON2gGZ(;k(i>=zc>#_x*Q54qbl@Wz>r3-qP>$6Cal@77I0 z3VqIzt%vu3IEORBpRpie|Bb+~i_>AW7$EI(5H-i2#KItJnd39qv?GD6V&JuXHJE?X zSUQ#Y+YAV81?T!C#COK@gqyFIV)WySov&rw6k;*^2XEs2zv|0mBJY=mFO#GBGllD5 zX;^Mu#Go!h=1^nNqEDjkPd>yTutpU@UJCM!HiqU$9BVV6R}S~-FfFv0DxL>~DK00_ zg;;FshO~ko#GIzt>n2DDsQ!j`JZ^=&+KVE zQ!yp>szqBLX3h5*+r!k9-+A@CU_R$Je0d{B2lzHJpKxk>4DKaIZcbExV2CFfOd2ErEJQ3Ib{%ueeJY^OFQKtawbO z`7W~jG#dJflP;aS+Wr+Q=aEHEb{??T_bz!?LYoTZ#F(`nk1w`1$S<9U$1^#d7d7Fp zXh69Q_Sq?!>y|cgg5S3v+4sKZ4PwakS;>BqxSXM6Zw_R4nm+DX9w@J)_#|Kmo--Dec8S*_Vp^)DNqFUIY)cl)XmvaO39eKGqn&_YWjqk)ApT$4`BD z)(rhsN>CQEX1=?OQPxoYaBGd}!P&*Jl8~TI=m;W)`@GBN!}GPK_aiwNo4iu;J#D6| zcIQxy&T$ggs|e&*m&&yM%hzy{2Agc>?D+gU6IA7bd1FpP=k1(rfef*y@SbxgxWVLc zYC;fE#+AsS8=HypSB1NE^4d#z7RFZG8@6x&!D&Akzbvf{Ik?nV3pES{@7n;?!^YvLBU_Y|@%w5jpAAhhBqJQ;iCx;I!e6Dr5 zb^bn^t92CiVMp~Gs0IYRn>zNhXjy18Q%u4(AMf>Fo>{j&1BffhoduS`o@4OS$1e(W zpl$U|Y0-Ocl9(WOhxmW*(ET<2S?y?(JZEVtjFCBJfLvT~?3S})CZ}pHZnANoV$0;5d*O$WzJx@i>|K6K%+MSkKxqNa=l`@b69b-BkYExbKbvZ|4 zZQ5WYJW$TORYg#QM35;oKLKe|uv2f#xwRsaA1 literal 0 HcmV?d00001 diff --git a/example/storage/fatfs/figures/test_item.png b/example/storage/fatfs/figures/test_item.png new file mode 100644 index 0000000000000000000000000000000000000000..31a5ccde67beaffc7395c4dcc58e546a07cf2dbf GIT binary patch literal 6186 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 U$U-(-Qh%RJQ&m@`QVEXye+jwOhX4Qo literal 0 HcmV?d00001 diff --git a/example/storage/sata_fatfs/inc/sata_fatfs_example.h b/example/storage/fatfs/inc/fatfs_examples.h similarity index 32% rename from example/storage/sata_fatfs/inc/sata_fatfs_example.h rename to example/storage/fatfs/inc/fatfs_examples.h index 7b6a830e..04106731 100644 --- a/example/storage/sata_fatfs/inc/sata_fatfs_example.h +++ b/example/storage/fatfs/inc/fatfs_examples.h @@ -1,30 +1,52 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * - * FilePath: sata_fatfs_example.h + * See the Phytium Public License for more details. + * + * + * FilePath: fatfs_examples.h * Date: 2022-06-17 10:42:40 * LastEditTime: 2022-06-17 10:42:40 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for the fatfs test example function declarations. + * + * Modify History: + * Ver   Who         Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2022/12/7 init commit */ -#ifndef SATA_FATFS_EXAMPLE_H -#define SATA_FATFS_EXAMPLE_H +#ifndef FATFS_EXAMPLES_H +#define FATFS_EXAMPLES_H -/* sata fatfs read and write test */ -BaseType_t FFreeRTOSSataFatfsCreate(void); +#ifdef __cplusplus +extern "C" +{ +#endif + +enum +{ + FFREERTOS_FATFS_RAM_DISK = 0U, + FFREERTOS_FATFS_TF_CARD = 1U, + FFREERTOS_FATFS_EMMC_CARD = 2U, + FFREERTOS_FATFS_USB_DISK = 3U, + FFREERTOS_FATFS_SATA_DISK = 4U, + FFREERTOS_FATFS_SATA_PCIE_DISK = 5U, + + FFREERTOS_DISK_TYPE_NUM, +}; + +/* fatfs run */ +BaseType_t FFreeRTOSFatfsTest(void); + +#ifdef __cplusplus +} +#endif #endif // ! \ No newline at end of file diff --git a/example/storage/spim_spiffs/main.c b/example/storage/fatfs/main.c similarity index 45% rename from example/storage/spim_spiffs/main.c rename to example/storage/fatfs/main.c index 8f49ee06..2b47cb9b 100644 --- a/example/storage/spim_spiffs/main.c +++ b/example/storage/fatfs/main.c @@ -1,47 +1,58 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: main.c * Date: 2022-06-17 08:17:59 * LastEditTime: 2022-06-17 08:17:59 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for fatfs main entry. + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2022/12/7 init commit */ +#include #include "shell.h" #include "shell_port.h" -#include -#include "spim_spiffs_example.h" +#include "fatfs_examples.h" +#include "sdkconfig.h" + + +#ifdef CONFIG_FATFS_SDMMC + #include "sdmmc_system.h" +#endif int main(void) { BaseType_t ret; - ret = FFreeRTOSSpimSpiffsCreate(0); - if(ret != pdPASS) - goto FAIL_EXIT; +#ifdef CONFIG_FATFS_SDMMC + sdmmc_sys_init(); +#endif + + ret = FFreeRTOSFatfsTest(); ret = LSUserShellTask() ; - if(ret != pdPASS) + if (ret != pdPASS) + { goto FAIL_EXIT; + } - vTaskStartScheduler(); /* 启动任务,开启调度 */ + vTaskStartScheduler(); /* 启动任务,开启调度 */ while (1); /* 正常不会执行到这里 */ - + FAIL_EXIT: - printf("failed 0x%x \r\n", ret); + printf("Failed,the ret value is 0x%x. \r\n", ret); return 0; } diff --git a/example/network/gmac_lwip_test/makefile b/example/storage/fatfs/makefile similarity index 71% rename from example/network/gmac_lwip_test/makefile rename to example/storage/fatfs/makefile index a497d88a..baf1a3fe 100644 --- a/example/network/gmac_lwip_test/makefile +++ b/example/storage/fatfs/makefile @@ -1,5 +1,6 @@ # 指定工程项目根目录为当前(只能指定一个目录) export PROJECT_DIR ?= $(shell pwd) +export KCONFIG_DIR ?= $(PROJECT_DIR) # 用户添加的源文件夹和头文件夹(可以指定多个) export USR_SRC_DIR ?= $(PROJECT_DIR) \ $(PROJECT_DIR)/src @@ -13,7 +14,6 @@ else USR_BOOT_DIR ?= /mnt/d/tftboot endif - # 设置启动镜像名 BOOT_IMG_NAME ?= freertos @@ -23,4 +23,8 @@ include $(FREERTOS_SDK_ROOT)/make/build_freertos.mk # 完成编译 boot: make -j - cp ./$(CONFIG_TARGET_NAME).elf $(USR_BOOT_DIR)/$(BOOT_IMG_NAME).elf + @cp ./$(CONFIG_TARGET_NAME).elf $(USR_BOOT_DIR)/$(BOOT_IMG_NAME).elf +ifdef CONFIG_OUTPUT_BINARY + @cp ./$(CONFIG_TARGET_NAME).bin $(USR_BOOT_DIR)/$(BOOT_IMG_NAME).bin +endif + @ls $(USR_BOOT_DIR)/$(BOOT_IMG_NAME).* -l \ No newline at end of file diff --git a/example/storage/fatfs/sdkconfig b/example/storage/fatfs/sdkconfig new file mode 100644 index 00000000..27fb43f5 --- /dev/null +++ b/example/storage/fatfs/sdkconfig @@ -0,0 +1,323 @@ + +# +# Project Configuration +# +CONFIG_TARGET_NAME="e2000q_freertos_a64" +CONFIG_FATFS_BASIC_TEST=y +# CONFIG_FATFS_SPEED_TEST is not set +# CONFIG_FATFS_CYCLE_TEST is not set +# end of Project Configuration + +# +# Standalone Setting +# +CONFIG_USE_FREERTOS=y + +# +# Arch Configuration +# +# CONFIG_TARGET_ARMV8_AARCH32 is not set +CONFIG_TARGET_ARMV8_AARCH64=y +CONFIG_USE_CACHE=y +CONFIG_USE_MMU=y +# CONFIG_USE_SYS_TICK is not set +# CONFIG_MMU_DEBUG_PRINTS is not set +# end of Arch Configuration + +# +# Board Configuration +# +# CONFIG_TARGET_F2000_4 is not set +# CONFIG_TARGET_D2000 is not set +CONFIG_TARGET_E2000Q=y +# CONFIG_TARGET_E2000D is not set +# CONFIG_TARGET_E2000S is not set +CONFIG_TARGET_E2000=y +CONFIG_DEFAULT_DEBUG_PRINT_UART1=y +# CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set +# CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set +# end of Board Configuration + +# +# Components Configuration +# +# CONFIG_USE_SPI is not set +# CONFIG_USE_QSPI is not set +CONFIG_USE_GIC=y +CONFIG_ENABLE_GICV3=y +CONFIG_USE_SERIAL=y + +# +# Usart Configuration +# +CONFIG_ENABLE_Pl011_UART=y +# end of Usart Configuration + +# CONFIG_USE_GPIO is not set +# CONFIG_USE_ETH is not set +# CONFIG_USE_CAN is not set +# CONFIG_USE_I2C is not set +# CONFIG_USE_TIMER is not set +# CONFIG_USE_MIO is not set +CONFIG_USE_SDMMC=y +# CONFIG_ENABLE_FSDMMC is not set +CONFIG_ENABLE_FSDIO=y +# CONFIG_USE_PCIE is not set +# CONFIG_USE_WDT is not set +# CONFIG_USE_DMA is not set +# CONFIG_USE_NAND is not set +# CONFIG_USE_RTC is not set +# CONFIG_USE_SATA is not set +# CONFIG_USE_USB is not set +# CONFIG_USE_ADC is not set +# CONFIG_USE_PWM is not set +# CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set +# end of Components Configuration + +CONFIG_USE_NEW_LIBC=y +# end of Standalone Setting + +# +# Building Option +# +# CONFIG_LOG_VERBOS is not set +# CONFIG_LOG_DEBUG is not set +# CONFIG_LOG_INFO is not set +# CONFIG_LOG_WARN is not set +CONFIG_LOG_ERROR=y +# CONFIG_LOG_NONE is not set +CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y +CONFIG_INTERRUPT_ROLE_MASTER=y +# CONFIG_INTERRUPT_ROLE_SLAVE is not set +CONFIG_LOG_EXTRA_INFO=y +# CONFIG_BOOTUP_DEBUG_PRINTS is not set + +# +# Linker Options +# +# CONFIG_AARCH32_RAM_LD is not set +CONFIG_AARCH64_RAM_LD=y +# CONFIG_USER_DEFINED_LD is not set +CONFIG_LINK_SCRIPT_ROM=y +CONFIG_ROM_START_UP_ADDR=0x80100000 +CONFIG_ROM_SIZE_MB=2 +CONFIG_LINK_SCRIPT_RAM=y +CONFIG_RAM_START_UP_ADDR=0x81000000 +CONFIG_RAM_SIZE_MB=64 +CONFIG_HEAP_SIZE=1 +CONFIG_STACK_SIZE=0x100000 +CONFIG_FPU_STACK_SIZE=0x1000 +# end of Linker Options + +# +# Compiler Options +# + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + +CONFIG_OUTPUT_BINARY=y +# end of Compiler Options +# end of Building Option + +# +# Component Configuration +# + +# +# Freertos Uart Drivers +# +CONFIG_FREERTOS_USE_UART=y +# end of Freertos Uart Drivers + +# +# Freertos Pwm Drivers +# +# CONFIG_FREERTOS_USE_PWM is not set +# end of Freertos Pwm Drivers + +# +# Freertos Qspi Drivers +# +# CONFIG_FREERTOS_USE_QSPI is not set +# end of Freertos Qspi Drivers + +# +# Freertos Wdt Drivers +# +# CONFIG_FREERTOS_USE_WDT is not set +# end of Freertos Wdt Drivers + +# +# Freertos Eth Drivers +# +# CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set +# end of Freertos Eth Drivers + +# +# Freertos Gpio Drivers +# +# CONFIG_FREERTOS_USE_GPIO is not set +# end of Freertos Gpio Drivers + +# +# Freertos Spim Drivers +# +# CONFIG_FREERTOS_USE_FSPIM is not set +# end of Freertos Spim Drivers + +# +# Freertos DMA Drivers +# +# CONFIG_FREERTOS_USE_FDDMA is not set +# CONFIG_FREERTOS_USE_FGDMA is not set +# end of Freertos DMA Drivers + +# +# Freertos Adc Drivers +# +# CONFIG_FREERTOS_USE_ADC is not set +# end of Freertos Adc Drivers + +# +# Freertos Can Drivers +# +# CONFIG_FREERTOS_USE_CAN is not set +# end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers +# end of Component Configuration + +# +# Third-Party Configuration +# +# CONFIG_USE_LWIP is not set +CONFIG_USE_BACKTRACE=y +CONFIG_USE_FATFS_0_1_4=y + +# +# FATFS Configuration (0.1.4) +# +CONFIG_FATFS_RAM_DISK=y + +# +# RAM Disk Configuration +# +CONFIG_FATFS_RAM_DISK_BASE=0xa0000000 +CONFIG_FATFS_RAM_DISK_SIZE_MB=500 +CONFIG_FATFS_RAM_DISK_SECTOR_SIZE_BYTE=512 +# end of RAM Disk Configuration + +CONFIG_FATFS_SDMMC=y +CONFIG_FATFS_SDMMC_FSDIO_TF=y +CONFIG_FATFS_SDMMC_FSDIO_EMMC=y +# CONFIG_FATFS_SDMMC_FSDMMC_TF is not set +CONFIG_FATFS_SATA_DISK=y + +# +# SATA Disk Configuration +# +# CONFIG_FATFS_FSATA is not set +# CONFIG_FATFS_FSATA_PCIE is not set +# end of SATA Disk Configuration + +CONFIG_FATFS_USB=y +CONFIG_FATFS_VOLUME_COUNT=10 +# CONFIG_FATFS_LFN_NONE is not set +CONFIG_FATFS_LFN_HEAP=y +# CONFIG_FATFS_LFN_STACK is not set +CONFIG_FATFS_MAX_LFN=255 +CONFIG_FATFS_FS_LOCK=0 +CONFIG_FATFS_TIMEOUT_MS=10000 +CONFIG_FATFS_PER_FILE_CACHE=y +CONFIG_FATFS_ALLOC_PREFER_MEMP=y +CONFIG_FATFS_MEMP_SIZE=2 +# end of FATFS Configuration (0.1.4) + +# CONFIG_USE_SFUD is not set +# CONFIG_USE_SPIFFS is not set +# CONFIG_USE_AMP is not set +CONFIG_USE_LETTER_SHELL=y + +# +# Letter Shell Configuration +# +CONFIG_LS_PL011_UART=y +CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y +# CONFIG_DEFAULT_LETTER_SHELL_USE_UART0 is not set +# CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set +# end of Letter Shell Configuration + +CONFIG_USE_TLSF=y +CONFIG_USE_SDMMC_CMD=y + +# +# SDMMC Configuration +# +# CONFIG_SDMMC_USE_FSDMMC is not set +CONFIG_SDMMC_USE_FSDIO=y +# end of SDMMC Configuration + +CONFIG_USE_CHERRY_USB=y + +# +# CherryUSB Configuration +# +CONFIG_CHERRY_USB_PORT_XHCI=y +# CONFIG_CHERRY_USB_PORT_PHYTIUM_OTG is not set +CONFIG_CHERRYUSB_HOST=y +# CONFIG_CHERRYUSB_DEVICE is not set +CONFIG_CHERRY_USB_HOST_HUB=y +CONFIG_CHERRY_USB_HOST_MSC=y +# CONFIG_CHERRY_USB_HOST_HID is not set +# CONFIG_CHERRY_USB_HOST_VEDIO is not set +# CONFIG_CHERRY_USB_HOST_CDC is not set +# CONFIG_CHERRY_USB_HOST_RNDIS_WIRELESS is not set +# end of CherryUSB Configuration +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/network/gmac_lwip_test/sdkconfig.h b/example/storage/fatfs/sdkconfig.h similarity index 45% rename from example/network/gmac_lwip_test/sdkconfig.h rename to example/storage/fatfs/sdkconfig.h index 985d2d50..54265e1b 100644 --- a/example/network/gmac_lwip_test/sdkconfig.h +++ b/example/storage/fatfs/sdkconfig.h @@ -3,13 +3,10 @@ /* Project Configuration */ -#define CONFIG_TARGET_NAME "d2000_freertos_a64" -#define CONFIG_LWIP_IPV4_TEST -/* CONFIG_LWIP_IPV4_DHCP_TEST is not set */ -/* CONFIG_LWIP_IPV6_TEST is not set */ -#define CONFIG_GMAC_RX_DESCNUM 16 -#define CONFIG_GMAC_TX_DESCNUM 16 -#define CONFIG_GMAC_IRQ_PRIORITY 12 +#define CONFIG_TARGET_NAME "e2000q_freertos_a64" +#define CONFIG_FATFS_BASIC_TEST +/* CONFIG_FATFS_SPEED_TEST is not set */ +/* CONFIG_FATFS_CYCLE_TEST is not set */ /* end of Project Configuration */ /* Standalone Setting */ @@ -21,19 +18,19 @@ /* CONFIG_TARGET_ARMV8_AARCH32 is not set */ #define CONFIG_TARGET_ARMV8_AARCH64 #define CONFIG_USE_CACHE -#define CONFIG_USE_L3CACHE #define CONFIG_USE_MMU -#define CONFIG_USE_SYS_TICK +/* CONFIG_USE_SYS_TICK is not set */ /* CONFIG_MMU_DEBUG_PRINTS is not set */ /* end of Arch Configuration */ /* Board Configuration */ /* CONFIG_TARGET_F2000_4 is not set */ -#define CONFIG_TARGET_D2000 -/* CONFIG_TARGET_E2000Q is not set */ +/* CONFIG_TARGET_D2000 is not set */ +#define CONFIG_TARGET_E2000Q /* CONFIG_TARGET_E2000D is not set */ /* CONFIG_TARGET_E2000S is not set */ +#define CONFIG_TARGET_E2000 #define CONFIG_DEFAULT_DEBUG_PRINT_UART1 /* CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set */ /* CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set */ @@ -52,20 +49,14 @@ #define CONFIG_ENABLE_Pl011_UART /* end of Usart Configuration */ /* CONFIG_USE_GPIO is not set */ -#define CONFIG_USE_ETH - -/* Eth Configuration */ - -/* CONFIG_ENABLE_FXMAC is not set */ -#define CONFIG_ENABLE_FGMAC -#define CONFIG_FGMAC_PHY_COMMON -/* CONFIG_FGMAC_PHY_AR803X is not set */ -/* end of Eth Configuration */ +/* CONFIG_USE_ETH is not set */ /* CONFIG_USE_CAN is not set */ /* CONFIG_USE_I2C is not set */ /* CONFIG_USE_TIMER is not set */ /* CONFIG_USE_MIO is not set */ -/* CONFIG_USE_SDMMC is not set */ +#define CONFIG_USE_SDMMC +/* CONFIG_ENABLE_FSDMMC is not set */ +#define CONFIG_ENABLE_FSDIO /* CONFIG_USE_PCIE is not set */ /* CONFIG_USE_WDT is not set */ /* CONFIG_USE_DMA is not set */ @@ -76,6 +67,7 @@ /* CONFIG_USE_ADC is not set */ /* CONFIG_USE_PWM is not set */ /* CONFIG_USE_IPC is not set */ +/* CONFIG_USE_MEDIA is not set */ /* end of Components Configuration */ #define CONFIG_USE_NEW_LIBC /* end of Standalone Setting */ @@ -84,14 +76,14 @@ /* CONFIG_LOG_VERBOS is not set */ /* CONFIG_LOG_DEBUG is not set */ -#define CONFIG_LOG_INFO +/* CONFIG_LOG_INFO is not set */ /* CONFIG_LOG_WARN is not set */ -/* CONFIG_LOG_ERROR is not set */ +#define CONFIG_LOG_ERROR /* CONFIG_LOG_NONE is not set */ #define CONFIG_USE_DEFAULT_INTERRUPT_CONFIG #define CONFIG_INTERRUPT_ROLE_MASTER /* CONFIG_INTERRUPT_ROLE_SLAVE is not set */ -/* CONFIG_LOG_EXTRA_INFO is not set */ +#define CONFIG_LOG_EXTRA_INFO /* CONFIG_BOOTUP_DEBUG_PRINTS is not set */ /* Linker Options */ @@ -101,7 +93,7 @@ /* CONFIG_USER_DEFINED_LD is not set */ #define CONFIG_LINK_SCRIPT_ROM #define CONFIG_ROM_START_UP_ADDR 0x80100000 -#define CONFIG_ROM_SIZE_MB 1 +#define CONFIG_ROM_SIZE_MB 2 #define CONFIG_LINK_SCRIPT_RAM #define CONFIG_RAM_START_UP_ADDR 0x81000000 #define CONFIG_RAM_SIZE_MB 64 @@ -112,7 +104,13 @@ /* Compiler Options */ -/* CONFIG_OUTPUT_BINARY is not set */ +/* Cross-Compiler Setting */ + +#define CONFIG_GCC_OPTIMIZE_LEVEL 0 +/* CONFIG_USE_EXT_COMPILER is not set */ +/* CONFIG_USE_KLIN_SYS is not set */ +/* end of Cross-Compiler Setting */ +#define CONFIG_OUTPUT_BINARY /* end of Compiler Options */ /* end of Building Option */ @@ -141,6 +139,7 @@ /* Freertos Eth Drivers */ /* CONFIG_FREERTOS_USE_XMAC is not set */ +/* CONFIG_FREERTOS_USE_GMAC is not set */ /* end of Freertos Eth Drivers */ /* Freertos Gpio Drivers */ @@ -159,11 +158,6 @@ /* CONFIG_FREERTOS_USE_FGDMA is not set */ /* end of Freertos DMA Drivers */ -/* Freertos MMC Drivers */ - -/* CONFIG_FREERTOS_USE_FSDIO is not set */ -/* end of Freertos MMC Drivers */ - /* Freertos Adc Drivers */ /* CONFIG_FREERTOS_USE_ADC is not set */ @@ -173,167 +167,62 @@ /* CONFIG_FREERTOS_USE_CAN is not set */ /* end of Freertos Can Drivers */ -/* end of Component Configuration */ - -/* FreeRTOS Setting */ - -#define CONFIG_USE_LWIP - -/* LWIP Configuration */ - -/* LWIP Port Configuration */ - -#define CONFIG_LWIP_FGMAC -/* CONFIG_LWIP_FXMAC is not set */ -/* end of LWIP Port Configuration */ -#define CONFIG_LWIP_LOCAL_HOSTNAME "phytium" - -/* memory configuration */ - -#define CONFIG_LWIP_USE_MEM_POOL -/* CONFIG_LWIP_USE_MEM_HEAP is not set */ -#define CONFIG_MEMP_NUM_PBUF 64 -#define CONFIG_MEM_ALIGNMENT 64 -/* end of memory configuration */ - -/* NETWORK_INTERFACE_OPTIONS */ - -/* CONFIG_LWIP_NETIF_API is not set */ -/* CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set */ -/* end of NETWORK_INTERFACE_OPTIONS */ - -/* LOOPIF */ - -#define CONFIG_LWIP_NETIF_LOOPBACK -#define CONFIG_LWIP_LOOPBACK_MAX_PBUFS 8 -/* end of LOOPIF */ - -/* SLIPIF */ - -/* CONFIG_LWIP_SLIP_SUPPORT is not set */ -/* end of SLIPIF */ - -/* Pbuf options */ -#define CONFIG_PBUF_POOL_BUFSIZE 2 -/* end of Pbuf options */ +/* Freertos I2c Drivers */ -/* Internal Memory Pool Sizes */ +/* CONFIG_FREERTOS_USE_I2C is not set */ +/* end of Freertos I2c Drivers */ -#define CONFIG_PBUF_POOL_SIZE 1 -/* end of Internal Memory Pool Sizes */ -#define CONFIG_LWIP_MAX_SOCKETS 10 +/* Freertos Mio Drivers */ -/* LWIP RAW API */ +/* CONFIG_FREERTOS_USE_MIO is not set */ +/* end of Freertos Mio Drivers */ -#define CONFIG_LWIP_MAX_RAW_PCBS 16 -/* end of LWIP RAW API */ +/* Freertos Timer Drivers */ -/* TCP */ - -#define CONFIG_LWIP_MAX_ACTIVE_TCP 16 -#define CONFIG_LWIP_MAX_LISTENING_TCP 16 -#define CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION -#define CONFIG_LWIP_TCP_MAXRTX 12 -#define CONFIG_LWIP_TCP_SYNMAXRTX 12 -#define CONFIG_LWIP_TCP_MSS 1440 -#define CONFIG_LWIP_TCP_TMR_INTERVAL 250 -#define CONFIG_LWIP_TCP_MSL 60000 -#define CONFIG_LWIP_TCP_SND_BUF_DEFAULT 5744 -#define CONFIG_LWIP_TCP_WND_DEFAULT 5744 -#define CONFIG_LWIP_TCP_RECVMBOX_SIZE 6 -#define CONFIG_LWIP_TCP_QUEUE_OOSEQ -/* CONFIG_LWIP_TCP_SACK_OUT is not set */ -#define CONFIG_LWIP_TCP_OVERSIZE_MSS -/* CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set */ -/* CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set */ -/* end of TCP */ - -/* UDP */ - -#define CONFIG_LWIP_MAX_UDP_PCBS 16 -#define CONFIG_LWIP_UDP_RECVMBOX_SIZE 6 -/* CONFIG_LWIP_NETBUF_RECVINFO is not set */ -/* end of UDP */ - -/* IPv4 */ - -/* CONFIG_USE_IPV4_ONLY is not set */ -/* CONFIG_LWIP_IP4_REASSEMBLY is not set */ -#define CONFIG_LWIP_IP4_FRAG -/* CONFIG_LWIP_IP_FORWARD is not set */ -#define CONFIG_IP_REASS_MAX_PBUFS 16 -/* end of IPv4 */ - -/* ICMP */ - -#define CONFIG_LWIP_ICMP -/* CONFIG_LWIP_MULTICAST_PING is not set */ -/* CONFIG_LWIP_BROADCAST_PING is not set */ -/* end of ICMP */ - -/* DHCP */ - -/* CONFIG_LWIP_DHCP_ENABLE is not set */ -#define CONFIG_LWIP_DHCP_DOES_ARP_CHECK -/* CONFIG_LWIP_DHCP_GET_NTP_SRV is not set */ -/* CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set */ -/* CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set */ -#define CONFIG_LWIP_DHCP_OPTIONS_LEN 68 -#define CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID -/* end of DHCP */ - -/* AUTOIP */ - -/* CONFIG_LWIP_AUTOIP is not set */ -/* end of AUTOIP */ - -/* DNS */ - -#define CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES -/* end of DNS */ - -/* TCP options */ - -#define CONFIG_LWIP_TCP_RTO_TIME 1500 -/* end of TCP options */ -/* CONFIG_LWIP_TCPIP_CORE_LOCKING is not set */ - -/* socket */ - -/* CONFIG_LWIP_SO_LINGER is not set */ -#define CONFIG_LWIP_SO_REUSE -#define CONFIG_LWIP_SO_REUSE_RXTOALL -/* end of socket */ -/* CONFIG_LWIP_STATS is not set */ - -/* PPP */ +/* CONFIG_FREERTOS_USE_TIMER is not set */ +/* end of Freertos Timer Drivers */ +/* end of Component Configuration */ -/* CONFIG_LWIP_PPP_SUPPORT is not set */ -#define CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE 3 -#define CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS 5 -/* end of PPP */ +/* Third-Party Configuration */ -/* Checksums */ - -/* CONFIG_LWIP_CHECKSUM_CHECK_IP is not set */ -/* CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set */ -#define CONFIG_LWIP_CHECKSUM_CHECK_ICMP -/* end of Checksums */ - -/* ipv6 */ - -#define CONFIG_LWIP_IPV6 -/* CONFIG_LWIP_IPV6_AUTOCONFIG is not set */ -#define CONFIG_LWIP_IPV6_NUM_ADDRESSES 3 -/* CONFIG_LWIP_IPV6_FORWARD is not set */ -#define CONFIG_LWIP_IP6_FRAG -/* CONFIG_LWIP_IP6_REASSEMBLY is not set */ -/* end of ipv6 */ -/* CONFIG_LWIP_DEBUG is not set */ -/* end of LWIP Configuration */ +/* CONFIG_USE_LWIP is not set */ #define CONFIG_USE_BACKTRACE -/* CONFIG_USE_FATFS is not set */ +#define CONFIG_USE_FATFS_0_1_4 + +/* FATFS Configuration (0.1.4) */ + +#define CONFIG_FATFS_RAM_DISK + +/* RAM Disk Configuration */ + +#define CONFIG_FATFS_RAM_DISK_BASE 0xa0000000 +#define CONFIG_FATFS_RAM_DISK_SIZE_MB 500 +#define CONFIG_FATFS_RAM_DISK_SECTOR_SIZE_BYTE 512 +/* end of RAM Disk Configuration */ +#define CONFIG_FATFS_SDMMC +#define CONFIG_FATFS_SDMMC_FSDIO_TF +#define CONFIG_FATFS_SDMMC_FSDIO_EMMC +/* CONFIG_FATFS_SDMMC_FSDMMC_TF is not set */ +#define CONFIG_FATFS_SATA_DISK + +/* SATA Disk Configuration */ + +/* CONFIG_FATFS_FSATA is not set */ +/* CONFIG_FATFS_FSATA_PCIE is not set */ +/* end of SATA Disk Configuration */ +#define CONFIG_FATFS_USB +#define CONFIG_FATFS_VOLUME_COUNT 10 +/* CONFIG_FATFS_LFN_NONE is not set */ +#define CONFIG_FATFS_LFN_HEAP +/* CONFIG_FATFS_LFN_STACK is not set */ +#define CONFIG_FATFS_MAX_LFN 255 +#define CONFIG_FATFS_FS_LOCK 0 +#define CONFIG_FATFS_TIMEOUT_MS 10000 +#define CONFIG_FATFS_PER_FILE_CACHE +#define CONFIG_FATFS_ALLOC_PREFER_MEMP +#define CONFIG_FATFS_MEMP_SIZE 2 +/* end of FATFS Configuration (0.1.4) */ /* CONFIG_USE_SFUD is not set */ /* CONFIG_USE_SPIFFS is not set */ /* CONFIG_USE_AMP is not set */ @@ -347,8 +236,50 @@ /* CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set */ /* end of Letter Shell Configuration */ #define CONFIG_USE_TLSF -/* CONFIG_USE_SDMMC_CMD is not set */ -/* CONFIG_USE_CHERRY_USB is not set */ -/* end of FreeRTOS Setting */ +#define CONFIG_USE_SDMMC_CMD + +/* SDMMC Configuration */ + +/* CONFIG_SDMMC_USE_FSDMMC is not set */ +#define CONFIG_SDMMC_USE_FSDIO +/* end of SDMMC Configuration */ +#define CONFIG_USE_CHERRY_USB + +/* CherryUSB Configuration */ + +#define CONFIG_CHERRY_USB_PORT_XHCI +/* CONFIG_CHERRY_USB_PORT_PHYTIUM_OTG is not set */ +#define CONFIG_CHERRYUSB_HOST +/* CONFIG_CHERRYUSB_DEVICE is not set */ +#define CONFIG_CHERRY_USB_HOST_HUB +#define CONFIG_CHERRY_USB_HOST_MSC +/* CONFIG_CHERRY_USB_HOST_HID is not set */ +/* CONFIG_CHERRY_USB_HOST_VEDIO is not set */ +/* CONFIG_CHERRY_USB_HOST_CDC is not set */ +/* CONFIG_CHERRY_USB_HOST_RNDIS_WIRELESS is not set */ +/* end of CherryUSB Configuration */ +/* end of Third-Party Configuration */ + +/* Kernel Configuration */ + +#define CONFIG_FREERTOS_OPTIMIZED_SCHEDULER +#define CONFIG_FREERTOS_HZ 1000 +#define CONFIG_FREERTOS_MAX_PRIORITIES 32 +#define CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES 13 +#define CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES 11 +#define CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS 1 +#define CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE 1024 +#define CONFIG_FREERTOS_MAX_TASK_NAME_LEN 32 +#define CONFIG_FREERTOS_TIMER_TASK_PRIORITY 1 +#define CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH 2048 +#define CONFIG_FREERTOS_TIMER_QUEUE_LENGTH 10 +#define CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE 0 +#define CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS +#define CONFIG_FREERTOS_USE_TRACE_FACILITY +#define CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS +/* CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set */ +#define CONFIG_FREERTOS_TOTAL_HEAP_SIZE 10240 +#define CONFIG_FREERTOS_TASK_FPU_SUPPORT 1 +/* end of Kernel Configuration */ #endif diff --git a/example/storage/fatfs/src/fatfs_examples.c b/example/storage/fatfs/src/fatfs_examples.c new file mode 100644 index 00000000..7c2b787d --- /dev/null +++ b/example/storage/fatfs/src/fatfs_examples.c @@ -0,0 +1,431 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fatfs_examples.c + * Date: 2022-07-11 11:32:48 + * LastEditTime: 2022-07-11 11:32:48 + * Description: This file is for the fatfs test example functions. + * + * Modify History: + * Ver   Who         Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2022/12/7 init commit + */ +#include +#include +#include + +#include "FreeRTOSConfig.h" +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" +#include "timers.h" +#include "event_groups.h" + +#include "fkernel.h" +#include "strto.h" +#include "fassert.h" +#include "fdebug.h" +#include "fparameters.h" +#include "sdkconfig.h" + +#include "ff_utils.h" +#include "fatfs_examples.h" +/************************** Constant Definitions *****************************/ +#define FATFS_EVT_INIT_DONE (0x1 << 0) +#define FATFS_EVT_CYC_TEST_DONE (0x1 << 1) + +/************************** Variable Definitions *****************************/ +static const char *mount_points[FFREERTOS_DISK_TYPE_NUM] = +{ + [FFREERTOS_FATFS_RAM_DISK] = FF_RAM_DISK_MOUNT_POINT, + [FFREERTOS_FATFS_TF_CARD] = FF_FSDIO_TF_DISK_MOUNT_POINT, + [FFREERTOS_FATFS_EMMC_CARD] = FF_FSDIO_EMMC_DISK_MOUNT_POINT, + [FFREERTOS_FATFS_USB_DISK] = FF_USB_DISK_MOUNT_POINT, + [FFREERTOS_FATFS_SATA_DISK] = FF_SATA_DISK_MOUNT_POINT, + [FFREERTOS_FATFS_SATA_PCIE_DISK] = FF_SATA_PCIE_DISK_MOUNT_POINT +}; +static const MKFS_PARM fs_option = +{ + .fmt = FM_EXFAT, /* format file system as exFAT to support > 4GB storage */ + .n_fat = 0, /* use default setting for other options */ + .align = 0, + .n_root = 0, + .au_size = 0 +}; +static boolean is_running = FALSE; +static EventGroupHandle_t sync = NULL; +static TimerHandle_t exit_timer = NULL; +static ff_fatfs file_sys[FFREERTOS_DISK_TYPE_NUM]; + +/***************** Macros (Inline Functions) Definitions *********************/ +#define FF_DEBUG_TAG "FATFS" +#define FF_ERROR(format, ...) FT_DEBUG_PRINT_E(FF_DEBUG_TAG, format, ##__VA_ARGS__) +#define FF_WARN(format, ...) FT_DEBUG_PRINT_W(FF_DEBUG_TAG, format, ##__VA_ARGS__) +#define FF_INFO(format, ...) FT_DEBUG_PRINT_I(FF_DEBUG_TAG, format, ##__VA_ARGS__) +#define FF_DEBUG(format, ...) FT_DEBUG_PRINT_D(FF_DEBUG_TAG, format, ##__VA_ARGS__) + +/************************** Function Prototypes ******************************/ + +/*****************************************************************************/ +static void FatfsSendEvent(u32 evt_bits) +{ + FASSERT(sync); + BaseType_t x_result = pdFALSE; + + FF_DEBUG("Ack evt_bits is 0x%x.", evt_bits); + x_result = xEventGroupSetBits(sync, evt_bits); +} + +static boolean FatfsWaitEvent(u32 evt_bits, TickType_t wait_delay) +{ + FASSERT(sync); + EventBits_t ev; + ev = xEventGroupWaitBits(sync, evt_bits, + pdTRUE, pdFALSE, wait_delay); + if (ev & evt_bits) + { + return TRUE; + } + + return FALSE; +} + +static void FatfsInitTask(void *args) +{ + FRESULT fr = FR_OK; + +#ifdef CONFIG_FATFS_RAM_DISK + fr = ff_setup(&file_sys[FFREERTOS_FATFS_RAM_DISK], + mount_points[FFREERTOS_FATFS_RAM_DISK], + &fs_option, pdFALSE); + + if (FR_OK != fr) + { + FF_ERROR("RAM disk init failed, err = %d.", fr); + goto task_exit; + } +#endif + +#ifdef CONFIG_FATFS_SDMMC_FSDIO_TF + fr = ff_setup(&file_sys[FFREERTOS_FATFS_TF_CARD], + mount_points[FFREERTOS_FATFS_TF_CARD], + &fs_option, pdFALSE); + + if (FR_OK != fr) + { + FF_ERROR("TF card init failed, err = %d.", fr); + goto task_exit; + } +#endif + +#ifdef CONFIG_FATFS_SDMMC_FSDIO_EMMC + fr = ff_setup(&file_sys[FFREERTOS_FATFS_EMMC_CARD], + mount_points[FFREERTOS_FATFS_EMMC_CARD], + &fs_option, pdFALSE); + + if (FR_OK != fr) + { + FF_ERROR("SDIO card init failed, err = %d.", fr); + goto task_exit; + } +#endif + +#ifdef CONFIG_FATFS_USB + fr = ff_setup(&file_sys[FFREERTOS_FATFS_USB_DISK], + mount_points[FFREERTOS_FATFS_USB_DISK], + &fs_option, pdFALSE); + + if (FR_OK != fr) + { + FF_ERROR("USB init failed, err = %d.", fr); + goto task_exit; + } +#endif + +#ifdef CONFIG_FATFS_FSATA + fr = ff_setup(&file_sys[FFREERTOS_FATFS_SATA_DISK], + mount_points[FFREERTOS_FATFS_SATA_DISK], + &fs_option, pdFALSE); + + if (FR_OK != fr) + { + FF_ERROR("SATA init failed, err = %d.", fr); + goto task_exit; + } +#endif +#ifdef CONFIG_FATFS_FSATA_PCIE + fr = ff_setup(&file_sys[FFREERTOS_FATFS_SATA_PCIE_DISK], + mount_points[FFREERTOS_FATFS_SATA_PCIE_DISK], + &fs_option, pdFALSE); + + if (FR_OK != fr) + { + FF_ERROR("SATA PCIE init failed, err = %d.", fr); + goto task_exit; + } +#endif + FatfsSendEvent(FATFS_EVT_INIT_DONE); +task_exit: + vTaskDelete(NULL); /* delete task itself */ +} + +static void FatfsTestTask(void *args) +{ + const char *root = NULL; + FRESULT fr = FR_OK; + + FatfsWaitEvent(FATFS_EVT_INIT_DONE, portMAX_DELAY); + +#ifdef CONFIG_FATFS_BASIC_TEST + { +#ifdef CONFIG_FATFS_RAM_DISK + printf("\r\n========Basic test for RAM Disk=================\r\n"); + fr = ff_basic_test(mount_points[FFREERTOS_FATFS_RAM_DISK], "logfile.txt"); + if (FR_OK != fr) + { + FF_ERROR("RAM disk basic test failed, err = %d.", fr); + goto task_exit; + } +#endif + +#ifdef CONFIG_FATFS_SDMMC_FSDIO_TF + printf("\r\n========Basic test for TF Card=================\r\n"); + fr = ff_basic_test(mount_points[FFREERTOS_FATFS_TF_CARD], "logfile.txt"); + if (FR_OK != fr) + { + FF_ERROR("TF card basic test failed, err = %d.", fr); + goto task_exit; + } +#endif + +#ifdef CONFIG_FATFS_SDMMC_FSDIO_EMMC + printf("\r\n========Basic test for eMMC=================\r\n"); + fr = ff_basic_test(mount_points[FFREERTOS_FATFS_EMMC_CARD], "logfile.txt"); + if (FR_OK != fr) + { + FF_ERROR("SDIO basic test failed, err = %d.", fr); + goto task_exit; + } +#endif + +#ifdef CONFIG_FATFS_USB + printf("\r\n========Basic test for USB Disk=================\r\n"); + fr = ff_basic_test(mount_points[FFREERTOS_FATFS_USB_DISK], "logfile.txt"); + if (FR_OK != fr) + { + FF_ERROR("USB basic test failed, err = %d.", fr); + goto task_exit; + } +#endif + +#ifdef CONFIG_FATFS_FSATA + printf("\r\n========Basic test for SATA Disk=================\r\n"); + fr = ff_basic_test(mount_points[FFREERTOS_FATFS_SATA_DISK], "logfile.txt"); + if (FR_OK != fr) + { + FF_ERROR("SATA basic test failed, err = %d.", fr); + goto task_exit; + } +#endif + +#ifdef CONFIG_FATFS_FSATA_PCIE + printf("\r\n========Basic test for SATA PCIE Disk=================\r\n"); + fr = ff_basic_test(mount_points[FFREERTOS_FATFS_SATA_PCIE_DISK], "logfile.txt"); + if (FR_OK != fr) + { + FF_ERROR("SATA PCIE basic test failed, err = %d.", fr); + goto task_exit; + } +#endif + } +#endif + + /* speed test will test diskio and destory file system */ +#ifdef CONFIG_FATFS_SPEED_TEST + { +#ifdef CONFIG_FATFS_RAM_DISK + printf("\r\n========Speed test for RAM Disk=================\r\n"); + fr = ff_speed_bench(mount_points[FFREERTOS_FATFS_RAM_DISK], 300000U); + if (FR_OK != fr) + { + FF_ERROR("RAM disk speed test failed, err = %d.", fr); + goto task_exit; + } +#endif + +#ifdef CONFIG_FATFS_SDMMC_FSDIO_TF + printf("\r\n========Speed test for TF Card=================\r\n"); + fr = ff_speed_bench(mount_points[FFREERTOS_FATFS_TF_CARD], 300000U); + if (FR_OK != fr) + { + FF_ERROR("TF speed test failed, err = %d.", fr); + goto task_exit; + } +#endif + +#ifdef CONFIG_FATFS_SDMMC_FSDIO_EMMC + printf("\r\n========Speed test for eMMC=================\r\n"); + fr = ff_speed_bench(mount_points[FFREERTOS_FATFS_EMMC_CARD], 300000U); + if (FR_OK != fr) + { + FF_ERROR("SDIO speed test failed, err = %d.", fr); + goto task_exit; + } +#endif + +#ifdef CONFIG_FATFS_USB + printf("\r\n========Speed test for USB Disk=================\r\n"); + fr = ff_speed_bench(mount_points[FFREERTOS_FATFS_USB_DISK], 300000U); + if (FR_OK != fr) + { + FF_ERROR("USB speed test failed, err = %d.", fr); + goto task_exit; + } +#endif + +#ifdef CONFIG_FATFS_FSATA + printf("\r\n========Speed test for SATA Disk=================\r\n"); + fr = ff_speed_bench(mount_points[FFREERTOS_FATFS_SATA_DISK], 30000U); + if (FR_OK != fr) + { + FF_ERROR("SATA speed test failed, err = %d.", fr); + goto task_exit; + } +#endif + +#ifdef CONFIG_FATFS_FSATA_PCIE + printf("\r\n========Speed test for SATA PCIE Disk=================\r\n"); + fr = ff_speed_bench(mount_points[FFREERTOS_FATFS_SATA_PCIE_DISK], 30000U); + if (FR_OK != fr) + { + FF_ERROR("SATA PCIE speed test failed, err = %d.", fr); + goto task_exit; + } +#endif + } +#endif + + /* cycle test will test diskio and destory file system */ +#ifdef CONFIG_FATFS_CYCLE_TEST + { +#ifdef CONFIG_FATFS_RAM_DISK + printf("\r\n========Cycle test for RAM Disk=================\r\n"); + if (ff_cycle_test(mount_points[FFREERTOS_FATFS_RAM_DISK], 3)) + { + goto task_exit; + } +#endif + +#ifdef CONFIG_FATFS_SDMMC_FSDIO_TF + printf("\r\n========Cycle test for TF Disk=================\r\n"); + if (ff_cycle_test(mount_points[FFREERTOS_FATFS_TF_CARD], 3)) + { + goto task_exit; + } +#endif + +#ifdef CONFIG_FATFS_SDMMC_FSDIO_EMMC + printf("\r\n========Cycle test for SDIO Disk=================\r\n"); + if (ff_cycle_test(mount_points[FFREERTOS_FATFS_EMMC_CARD], 3)) + { + goto task_exit; + } +#endif + +#ifdef CONFIG_FATFS_USB + printf("\r\n========Cycle test for USB Disk=================\r\n"); + if (ff_cycle_test(mount_points[FFREERTOS_FATFS_USB_DISK], 3)) + { + goto task_exit; + } +#endif + +#ifdef CONFIG_FATFS_FSATA + printf("\r\n========Cycle test for SATA Disk=================\r\n"); + if (ff_cycle_test(mount_points[FFREERTOS_FATFS_SATA_DISK], 3)) + { + goto task_exit; + } +#endif + +#ifdef CONFIG_FATFS_FSATA_PCIE + printf("\r\n========Cycle test for SATA PCIE Disk=================\r\n"); + if (ff_cycle_test(mount_points[FFREERTOS_FATFS_SATA_PCIE_DISK], 3)) + { + goto task_exit; + } +#endif + } +#endif + +task_exit: + FatfsSendEvent(FATFS_EVT_CYC_TEST_DONE); + printf("Exit from test task.\r\n"); + vTaskDelete(NULL); /* delete task itself */ +} + +static void FatfsExitCallback(TimerHandle_t timer) +{ + if (sync) + { + vEventGroupDelete(sync); + sync = NULL; + } + + is_running = FALSE; +} + +BaseType_t FFreeRTOSFatfsTest(void) +{ + BaseType_t ret = pdPASS; + const TickType_t total_run_time = pdMS_TO_TICKS(30000UL); /* run for 30 secs deadline */ + + if (is_running) + { + FF_ERROR("The task is running."); + return pdPASS; + } + + FASSERT_MSG(NULL == sync, "Event group exists."); + FASSERT_MSG((sync = xEventGroupCreate()) != NULL, "Create event group failed."); + + taskENTER_CRITICAL(); /* no schedule when create task */ + + ret = xTaskCreate((TaskFunction_t)FatfsInitTask, + (const char *)"FatfsInitTask", + (uint16_t)2048, + NULL, + (UBaseType_t)configMAX_PRIORITIES - 1, + NULL); + FASSERT_MSG(pdPASS == ret, "Create task failed."); + + ret = xTaskCreate((TaskFunction_t)FatfsTestTask, + (const char *)"FatfsTestTask", + (uint16_t)2048, + NULL, + (UBaseType_t)configMAX_PRIORITIES - 1, + NULL); + FASSERT_MSG(pdPASS == ret, "Create task failed."); + + exit_timer = xTimerCreate("FatfsExitTimer", /* Text name for the software timer - not used by FreeRTOS. */ + total_run_time, /* The software timer's period in ticks. */ + pdFALSE, /* Setting uxAutoRealod to pdFALSE creates a one-shot software timer. */ + NULL, /* use timer id to pass task data for reference. */ + FatfsExitCallback); /* The callback function to be used by the software timer being created. */ + + FASSERT_MSG(NULL != exit_timer, "Create exit timer failed."); + + taskEXIT_CRITICAL(); /* allow schedule since task created */ + return ret; +} \ No newline at end of file diff --git a/example/storage/qspi_spiffs/README.md b/example/storage/qspi_spiffs/README.md index cda3dd2f..10a22f8a 100644 --- a/example/storage/qspi_spiffs/README.md +++ b/example/storage/qspi_spiffs/README.md @@ -118,15 +118,18 @@ bootelf -p 0x90100000 ### 2.4 输出与实验现象 >描述输入输出情况,列出存在哪些输出,对应的输出是什么(建议附录相关现象图片)
    -程序启动后,依次创建Init、Read、Write任务,创建单次模式软件定时器用于删除任务,Init任务会首先初始化并挂载qspi flash的部分区域(可通过FSPIFFS_IF_FORMAT选择是否进行格式化操作),随后创建一个文件,然后释放信号量通知Read和Write任务开始执行; +程序启动后,依次创建Init、WriteRead任务,创建单次模式软件定时器用于删除任务,Init任务会首先初始化并挂载qspi flash的部分区域(可通过FSPIFFS_IF_FORMAT选择是否进行格式化操作),随后创建一个文件,然后释放信号量通知WriteRead任务开始执行; - init完成,挂载文件系统完成,创建测试文件 + ![init](./figs/init.png) -- 读写任务周期性执行,有两个读任务,一个写任务 +- 读写任务周期性执行 + ![wr](./figs/wr.png) - 软件定时器触发,删除读写任务 + ![delete](./figs/delete.png) ## 3. 如何解决问题 diff --git a/example/storage/qspi_spiffs/configs/d2000_aarch32_eg_configs b/example/storage/qspi_spiffs/configs/d2000_aarch32_eg_configs index 8b17a1da..b10fdebc 100644 --- a/example/storage/qspi_spiffs/configs/d2000_aarch32_eg_configs +++ b/example/storage/qspi_spiffs/configs/d2000_aarch32_eg_configs @@ -74,6 +74,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -118,6 +119,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -154,6 +164,7 @@ CONFIG_FREERTOS_USE_QSPI=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -175,12 +186,6 @@ CONFIG_FREERTOS_USE_QSPI=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -192,14 +197,32 @@ CONFIG_FREERTOS_USE_QSPI=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set CONFIG_USE_SFUD=y # @@ -236,4 +259,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/storage/qspi_spiffs/configs/d2000_aarch64_eg_configs b/example/storage/qspi_spiffs/configs/d2000_aarch64_eg_configs index 2b35d2de..0406ccf7 100644 --- a/example/storage/qspi_spiffs/configs/d2000_aarch64_eg_configs +++ b/example/storage/qspi_spiffs/configs/d2000_aarch64_eg_configs @@ -74,6 +74,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -114,6 +115,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -150,6 +160,7 @@ CONFIG_FREERTOS_USE_QSPI=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -171,12 +182,6 @@ CONFIG_FREERTOS_USE_QSPI=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -188,14 +193,32 @@ CONFIG_FREERTOS_USE_QSPI=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set CONFIG_USE_SFUD=y # @@ -232,4 +255,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/storage/qspi_spiffs/configs/e2000d_aarch32_eg_configs b/example/storage/qspi_spiffs/configs/e2000d_aarch32_eg_configs index 85b81d19..ba3109b7 100644 --- a/example/storage/qspi_spiffs/configs/e2000d_aarch32_eg_configs +++ b/example/storage/qspi_spiffs/configs/e2000d_aarch32_eg_configs @@ -74,6 +74,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -118,6 +119,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -154,6 +164,7 @@ CONFIG_FREERTOS_USE_QSPI=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -175,12 +186,6 @@ CONFIG_FREERTOS_USE_QSPI=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -192,14 +197,32 @@ CONFIG_FREERTOS_USE_QSPI=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set CONFIG_USE_SFUD=y # @@ -236,4 +259,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/storage/qspi_spiffs/configs/e2000d_aarch64_eg_configs b/example/storage/qspi_spiffs/configs/e2000d_aarch64_eg_configs index 6a2d29da..d6d2f93d 100644 --- a/example/storage/qspi_spiffs/configs/e2000d_aarch64_eg_configs +++ b/example/storage/qspi_spiffs/configs/e2000d_aarch64_eg_configs @@ -74,6 +74,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -114,6 +115,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -150,6 +160,7 @@ CONFIG_FREERTOS_USE_QSPI=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -171,12 +182,6 @@ CONFIG_FREERTOS_USE_QSPI=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -188,14 +193,32 @@ CONFIG_FREERTOS_USE_QSPI=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set CONFIG_USE_SFUD=y # @@ -232,4 +255,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/storage/qspi_spiffs/configs/e2000q_aarch32_eg_configs b/example/storage/qspi_spiffs/configs/e2000q_aarch32_eg_configs index 015408c1..f2bd11a8 100644 --- a/example/storage/qspi_spiffs/configs/e2000q_aarch32_eg_configs +++ b/example/storage/qspi_spiffs/configs/e2000q_aarch32_eg_configs @@ -74,6 +74,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -118,6 +119,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -154,6 +164,7 @@ CONFIG_FREERTOS_USE_QSPI=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -175,12 +186,6 @@ CONFIG_FREERTOS_USE_QSPI=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -192,14 +197,32 @@ CONFIG_FREERTOS_USE_QSPI=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set CONFIG_USE_SFUD=y # @@ -236,4 +259,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/storage/qspi_spiffs/configs/e2000q_aarch64_eg_configs b/example/storage/qspi_spiffs/configs/e2000q_aarch64_eg_configs index 4004e2e6..3842526f 100644 --- a/example/storage/qspi_spiffs/configs/e2000q_aarch64_eg_configs +++ b/example/storage/qspi_spiffs/configs/e2000q_aarch64_eg_configs @@ -74,6 +74,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -114,6 +115,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -150,6 +160,7 @@ CONFIG_FREERTOS_USE_QSPI=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -171,12 +182,6 @@ CONFIG_FREERTOS_USE_QSPI=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -188,14 +193,32 @@ CONFIG_FREERTOS_USE_QSPI=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set CONFIG_USE_SFUD=y # @@ -232,4 +255,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/storage/qspi_spiffs/configs/ft2004_aarch32_eg_configs b/example/storage/qspi_spiffs/configs/ft2004_aarch32_eg_configs index a190e8e7..db70d187 100644 --- a/example/storage/qspi_spiffs/configs/ft2004_aarch32_eg_configs +++ b/example/storage/qspi_spiffs/configs/ft2004_aarch32_eg_configs @@ -74,6 +74,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -118,6 +119,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -154,6 +164,7 @@ CONFIG_FREERTOS_USE_QSPI=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -175,12 +186,6 @@ CONFIG_FREERTOS_USE_QSPI=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -192,14 +197,32 @@ CONFIG_FREERTOS_USE_QSPI=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set CONFIG_USE_SFUD=y # @@ -236,4 +259,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/storage/qspi_spiffs/configs/ft2004_aarch64_eg_configs b/example/storage/qspi_spiffs/configs/ft2004_aarch64_eg_configs index 3ab805e7..46475ff2 100644 --- a/example/storage/qspi_spiffs/configs/ft2004_aarch64_eg_configs +++ b/example/storage/qspi_spiffs/configs/ft2004_aarch64_eg_configs @@ -74,6 +74,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -114,6 +115,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -150,6 +160,7 @@ CONFIG_FREERTOS_USE_QSPI=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -171,12 +182,6 @@ CONFIG_FREERTOS_USE_QSPI=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -188,14 +193,32 @@ CONFIG_FREERTOS_USE_QSPI=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set CONFIG_USE_SFUD=y # @@ -232,4 +255,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/storage/qspi_spiffs/figs/delete.png b/example/storage/qspi_spiffs/figs/delete.png index a585b77fc45514cbdda04731aa8bd53713483bd1..b594ae6c866977f006bd52caf93cb8c075e13f52 100644 GIT binary patch literal 23080 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∨>ljE!Tc!Bf+xvd)#AeA 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 SlP}k8ldFrzmyDxlQvLBD56M_NE4(*iXbW= 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�~>RPVN}d_iJML3tm|=TfFJlY~}aJ}fay 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 PZ)|O0f2R1l=Y_ literal 24680 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 diff --git a/example/storage/qspi_spiffs/figs/wr.png b/example/storage/qspi_spiffs/figs/wr.png index 3e2665527e25cd45278e23939bd7a6c48f025fef..b2ff8c3a38cac020ab64bf050d945064398d6103 100644 GIT binary patch literal 31283 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 IZ}W@)H$sl43jhEB diff --git a/example/storage/qspi_spiffs/inc/qspi_spiffs_example.h b/example/storage/qspi_spiffs/inc/qspi_spiffs_example.h index b1caa8f8..309a9423 100644 --- a/example/storage/qspi_spiffs/inc/qspi_spiffs_example.h +++ b/example/storage/qspi_spiffs/inc/qspi_spiffs_example.h @@ -1,30 +1,41 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: qspi_spiffs_example.h * Date: 2022-06-17 10:42:40 * LastEditTime: 2022-06-17 10:42:40 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for the qspi_spiffs example function declarations. + * + * Modify History: + * Ver    Who         Date          Changes + * -----  ------       --------    -------------------------------------- + * 1.0 wangxiaodong 2022/8/9 first release */ #ifndef QSPI_SPIFFS_EXAMPLE_H #define QSPI_SPIFFS_EXAMPLE_H +#ifdef __cplusplus +extern "C" +{ +#endif + /* qspi spiffs read and write test */ BaseType_t FFreeRTOSQspiSpiffsCreate(u32 qspi_id); + +#ifdef __cplusplus +} +#endif + #endif // ! \ No newline at end of file diff --git a/example/storage/qspi_spiffs/main.c b/example/storage/qspi_spiffs/main.c index bcaa4735..e26855e9 100644 --- a/example/storage/qspi_spiffs/main.c +++ b/example/storage/qspi_spiffs/main.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: main.c * Date: 2022-06-17 08:17:59 * LastEditTime: 2022-06-17 08:17:59 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for the main functions. + * + * Modify History: + * Ver    Who         Date          Changes + * -----  ------       --------    -------------------------------------- + * 1.0 wangxiaodong 2022/8/9 first release */ #include "shell.h" @@ -31,17 +32,21 @@ int main(void) BaseType_t ret; ret = FFreeRTOSQspiSpiffsCreate(0); - if(ret != pdPASS) + if (ret != pdPASS) + { goto FAIL_EXIT; + } ret = LSUserShellTask() ; - if(ret != pdPASS) + if (ret != pdPASS) + { goto FAIL_EXIT; + } - vTaskStartScheduler(); /* 启动任务,开启调度 */ + vTaskStartScheduler(); /* 启动任务,开启调度 */ while (1); /* 正常不会执行到这里 */ - + FAIL_EXIT: - printf("failed 0x%x \r\n", ret); + printf("Failed,the ret value is 0x%x. \r\n", ret); return 0; } diff --git a/example/storage/qspi_spiffs/sdkconfig b/example/storage/qspi_spiffs/sdkconfig index 4004e2e6..3842526f 100644 --- a/example/storage/qspi_spiffs/sdkconfig +++ b/example/storage/qspi_spiffs/sdkconfig @@ -74,6 +74,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -114,6 +115,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -150,6 +160,7 @@ CONFIG_FREERTOS_USE_QSPI=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -171,12 +182,6 @@ CONFIG_FREERTOS_USE_QSPI=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -188,14 +193,32 @@ CONFIG_FREERTOS_USE_QSPI=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set CONFIG_USE_SFUD=y # @@ -232,4 +255,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y # CONFIG_USE_TLSF is not set # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/storage/qspi_spiffs/sdkconfig.h b/example/storage/qspi_spiffs/sdkconfig.h index 978530b0..e4710ac9 100644 --- a/example/storage/qspi_spiffs/sdkconfig.h +++ b/example/storage/qspi_spiffs/sdkconfig.h @@ -67,6 +67,7 @@ /* CONFIG_USE_ADC is not set */ /* CONFIG_USE_PWM is not set */ /* CONFIG_USE_IPC is not set */ +/* CONFIG_USE_MEDIA is not set */ /* end of Components Configuration */ #define CONFIG_USE_NEW_LIBC /* end of Standalone Setting */ @@ -103,6 +104,12 @@ /* Compiler Options */ +/* Cross-Compiler Setting */ + +#define CONFIG_GCC_OPTIMIZE_LEVEL 0 +/* CONFIG_USE_EXT_COMPILER is not set */ +/* CONFIG_USE_KLIN_SYS is not set */ +/* end of Cross-Compiler Setting */ #define CONFIG_OUTPUT_BINARY /* end of Compiler Options */ /* end of Building Option */ @@ -132,6 +139,7 @@ /* Freertos Eth Drivers */ /* CONFIG_FREERTOS_USE_XMAC is not set */ +/* CONFIG_FREERTOS_USE_GMAC is not set */ /* end of Freertos Eth Drivers */ /* Freertos Gpio Drivers */ @@ -150,11 +158,6 @@ /* CONFIG_FREERTOS_USE_FGDMA is not set */ /* end of Freertos DMA Drivers */ -/* Freertos MMC Drivers */ - -/* CONFIG_FREERTOS_USE_FSDIO is not set */ -/* end of Freertos MMC Drivers */ - /* Freertos Adc Drivers */ /* CONFIG_FREERTOS_USE_ADC is not set */ @@ -164,13 +167,28 @@ /* CONFIG_FREERTOS_USE_CAN is not set */ /* end of Freertos Can Drivers */ + +/* Freertos I2c Drivers */ + +/* CONFIG_FREERTOS_USE_I2C is not set */ +/* end of Freertos I2c Drivers */ + +/* Freertos Mio Drivers */ + +/* CONFIG_FREERTOS_USE_MIO is not set */ +/* end of Freertos Mio Drivers */ + +/* Freertos Timer Drivers */ + +/* CONFIG_FREERTOS_USE_TIMER is not set */ +/* end of Freertos Timer Drivers */ /* end of Component Configuration */ -/* FreeRTOS Setting */ +/* Third-Party Configuration */ /* CONFIG_USE_LWIP is not set */ #define CONFIG_USE_BACKTRACE -/* CONFIG_USE_FATFS is not set */ +/* CONFIG_USE_FATFS_0_1_4 is not set */ #define CONFIG_USE_SFUD /* SFUD Configuration */ @@ -201,6 +219,28 @@ /* CONFIG_USE_TLSF is not set */ /* CONFIG_USE_SDMMC_CMD is not set */ /* CONFIG_USE_CHERRY_USB is not set */ -/* end of FreeRTOS Setting */ +/* end of Third-Party Configuration */ + +/* Kernel Configuration */ + +#define CONFIG_FREERTOS_OPTIMIZED_SCHEDULER +#define CONFIG_FREERTOS_HZ 1000 +#define CONFIG_FREERTOS_MAX_PRIORITIES 32 +#define CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES 13 +#define CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES 11 +#define CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS 1 +#define CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE 1024 +#define CONFIG_FREERTOS_MAX_TASK_NAME_LEN 32 +#define CONFIG_FREERTOS_TIMER_TASK_PRIORITY 1 +#define CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH 2048 +#define CONFIG_FREERTOS_TIMER_QUEUE_LENGTH 10 +#define CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE 0 +#define CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS +#define CONFIG_FREERTOS_USE_TRACE_FACILITY +#define CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS +/* CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set */ +#define CONFIG_FREERTOS_TOTAL_HEAP_SIZE 10240 +#define CONFIG_FREERTOS_TASK_FPU_SUPPORT 1 +/* end of Kernel Configuration */ #endif diff --git a/example/storage/qspi_spiffs/src/qspi_spiffs_example.c b/example/storage/qspi_spiffs/src/qspi_spiffs_example.c index e12242e7..84d4700b 100644 --- a/example/storage/qspi_spiffs/src/qspi_spiffs_example.c +++ b/example/storage/qspi_spiffs/src/qspi_spiffs_example.c @@ -1,24 +1,26 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: qspi_spiffs_example.c * Date: 2022-07-11 11:32:48 * LastEditTime: 2022-07-11 11:32:48 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for the qspi_spiffs example functions. + * + * Modify History: + * Ver    Who         Date          Changes + * -----  ------       --------    -------------------------------------- + * 1.0 wangxiaodong 2022/8/9 first release + * 1.1 zhangyan 2023/2/9 improve functions */ #include #include @@ -38,11 +40,11 @@ #include "spiffs_port.h" #include "sdkconfig.h" #ifdef CONFIG_SPIFFS_ON_FSPIM_SFUD -#include "fspim_spiffs_port.h" + #include "fspim_spiffs_port.h" #endif #ifdef CONFIG_SPIFFS_ON_FQSPI_SFUD -#include "fqspi_spiffs_port.h" + #include "fqspi_spiffs_port.h" #endif @@ -67,20 +69,26 @@ enum #define FSPIFFS_INFO(format, ...) FT_DEBUG_PRINT_I(FSPIFFS_DEBUG_TAG, format, ##__VA_ARGS__) #define FSPIFFS_DEBUG(format, ...) FT_DEBUG_PRINT_D(FSPIFFS_DEBUG_TAG, format, ##__VA_ARGS__) -/* spiffs start address and size */ -#define FSPIFFS_START_ADDR (7 * SZ_1M) -#define FSPIFFS_USE_SIZE SZ_1M +/* spiffs start address and size */ +#if defined(CONFIG_TARGET_E2000) +#define FSPIFFS_START_ADDR (3 * SZ_1M) +#elif defined(CONFIG_TARGET_F2000_4) || defined(CONFIG_TARGET_D2000) +#define FSPIFFS_START_ADDR (7 * SZ_1M) +#endif + +#define FSPIFFS_USE_SIZE SZ_1M #define FSPIFFS_RW_BUF_SIZE 64 /* if format flash, TRUE is need format, it tasks some time */ -#define FSPIFFS_IF_FORMAT TRUE +#define FSPIFFS_IF_FORMAT TRUE /* 一个页大小两倍的一个RAM缓冲区, 用来加载和维护SPIFFS的逻辑页 */ static volatile u8 fspiffs_work_buf[FSPIFFS_LOG_PAGE_SIZE * 2] = {0}; static volatile u8 fspiffs_fds_buf[32 * 4] = {0}; static volatile u8 fspiffs_cache_buf[(FSPIFFS_LOG_PAGE_SIZE + 32) * 4] = {0}; -static u8 fspiffs_rw_buf[FSPIFFS_RW_BUF_SIZE] = {0}; +static u8 fspiffs_rd_buf[FSPIFFS_RW_BUF_SIZE] = {0}; +static u8 fspiffs_wr_buf[FSPIFFS_RW_BUF_SIZE] = {0}; static FSpiffs instance; static spiffs_config config; static boolean spiffs_inited = FALSE; @@ -89,20 +97,21 @@ const char *file_name = "test.txt"; /************************** Constant Definitions *****************************/ /* The periods assigned to the one-shot timers. */ -#define ONE_SHOT_TIMER_PERIOD ( pdMS_TO_TICKS( 50000UL ) ) +#define ONE_SHOT_TIMER_PERIOD ( pdMS_TO_TICKS( 50000UL ) ) /* write and read task delay in milliseconds */ -#define TASK_DELAY_MS 3000UL +#define TASK_DELAY_MS 3000UL /* write and read task number */ -#define READ_WRITE_TASK_NUM 3 +#define READ_WRITE_TASK_NUM 1 static xSemaphoreHandle xCountingSemaphore; -static xTaskHandle qspi_read1_handle; -static xTaskHandle qspi_read2_handle; -static xTaskHandle qspi_write_handle; +static xTaskHandle qspi_rw_handle; + static TimerHandle_t xOneShotTimer; +static const char *xString = "FFreeRTOSQspiSpiffsWriteReadTask is running\r\n"; + static void FFreeRTOSQspiSpiffsDelete(void); static int FSpiffsOpsMount(boolean do_format) @@ -112,52 +121,52 @@ static int FSpiffsOpsMount(boolean do_format) if (do_format) { result = SPIFFS_mount(&instance.fs, - &config, - (u8_t *)fspiffs_work_buf, - (u8_t *)fspiffs_fds_buf, - sizeof(fspiffs_fds_buf), - (u8_t *)fspiffs_cache_buf, - sizeof(fspiffs_cache_buf), - NULL); + &config, + (u8_t *)fspiffs_work_buf, + (u8_t *)fspiffs_fds_buf, + sizeof(fspiffs_fds_buf), + (u8_t *)fspiffs_cache_buf, + sizeof(fspiffs_cache_buf), + NULL); /* try mount to get status of filesystem */ if ((SPIFFS_OK != result) && (SPIFFS_ERR_NOT_A_FS != result)) { - /* if not a valid filesystem, continue to format, + /* if not a valid filesystem, continue to format, other error cannot handle, just exit */ - FSPIFFS_ERROR("mount spiffs failed: %d", result); - return FSPIFFS_OPS_MOUNT_FAILED; + FSPIFFS_ERROR("Mount spiffs failed: %d", result); + return FSPIFFS_OPS_MOUNT_FAILED; } /* must be unmounted prior to formatting */ SPIFFS_unmount(&instance.fs); - FSPIFFS_DEBUG("format spiffs in progress ...\r\n"); + FSPIFFS_DEBUG("Spiffs formatting in progress ..."); result = SPIFFS_format(&instance.fs); if (SPIFFS_OK != result) { - FSPIFFS_ERROR("format spiffs failed: %d", result); + FSPIFFS_ERROR("Spiffs formatting failed: %d", result); return FSPIFFS_OPS_FORMAT_FAILED; - } + } } /* real mount */ result = SPIFFS_mount(&instance.fs, - &config, - (u8_t *)fspiffs_work_buf, - (u8_t *)fspiffs_fds_buf, - sizeof(fspiffs_fds_buf), - (u8_t *)fspiffs_cache_buf, - sizeof(fspiffs_cache_buf), - NULL); + &config, + (u8_t *)fspiffs_work_buf, + (u8_t *)fspiffs_fds_buf, + sizeof(fspiffs_fds_buf), + (u8_t *)fspiffs_cache_buf, + sizeof(fspiffs_cache_buf), + NULL); if (SPIFFS_OK != result) { - FSPIFFS_ERROR("remount spiffs failed: %d, you may format the medium first", result); + FSPIFFS_ERROR("Remount spiffs failed: %d, you may format the medium first.", result); return FSPIFFS_OPS_MOUNT_FAILED; } else { - vPrintf("mount spiffs success !!! \r\n"); + vPrintf("Mount spiffs success. \r\n"); instance.fs_ready = TRUE; } @@ -171,7 +180,7 @@ static int FSpiffsOpsListAll(void) if (FALSE == instance.fs_ready) { - FSPIFFS_ERROR("please mount file system first !!!"); + FSPIFFS_ERROR("Please mount file system first."); return FSPIFFS_OPS_NOT_YET_MOUNT; } @@ -186,11 +195,11 @@ static int FSpiffsOpsListAll(void) while (NULL != (cur_entry = SPIFFS_readdir(&dir, cur_entry))) { - printf("-- %s file-id: [0x%04x] page-id: [%d] file-size: %d\r\n", - cur_entry->name, - cur_entry->pix, - cur_entry->obj_id, - cur_entry->size); + printf("-- %s file-id: [0x%04x] page-id: [%d] file-size: %d\r\n", + cur_entry->name, + cur_entry->pix, + cur_entry->obj_id, + cur_entry->size); } (void)SPIFFS_closedir(&dir); @@ -202,7 +211,7 @@ int FSpiffsOpsCreateFile(const char *file_name) FASSERT((file_name) && (strlen(file_name) > 0)); if (FALSE == instance.fs_ready) { - FSPIFFS_ERROR("please mount file system first !!!"); + FSPIFFS_ERROR("Please mount file system first."); return FSPIFFS_OPS_NOT_YET_MOUNT; } @@ -212,7 +221,7 @@ int FSpiffsOpsCreateFile(const char *file_name) s32_t result = SPIFFS_creat(&instance.fs, file_name, 0); if (result < 0) { - FSPIFFS_ERROR("failed to create file %s", file_name); + FSPIFFS_ERROR("Failed to create file %s", file_name); return FSPIFFS_OPS_OPEN_FILE_FAILED; } @@ -220,7 +229,7 @@ int FSpiffsOpsCreateFile(const char *file_name) spiffs_file fd = SPIFFS_open(&instance.fs, file_name, SPIFFS_RDONLY, 0); if (0 > fd) { - FSPIFFS_ERROR("failed to open file %s errno %d", file_name, SPIFFS_errno(&instance.fs)); + FSPIFFS_ERROR("Failed to open file %s errno %d", file_name, SPIFFS_errno(&instance.fs)); return FSPIFFS_OPS_OPEN_FILE_FAILED; } @@ -230,26 +239,26 @@ int FSpiffsOpsCreateFile(const char *file_name) result = SPIFFS_fstat(&instance.fs, fd, &status); if (result < 0) { - FSPIFFS_ERROR("failed to get status of file %s errno %d", file_name, SPIFFS_errno(&instance.fs)); + FSPIFFS_ERROR("Failed to get status of file %s, errno %d", file_name, SPIFFS_errno(&instance.fs)); ret = FSPIFFS_OPS_OPEN_FILE_FAILED; goto err_exit; - } + } if (0 != strcmp(status.name, file_name)) { - FSPIFFS_ERROR("created file name %s != %s", status.name, file_name); + FSPIFFS_ERROR("Created file name %s != %s", status.name, file_name); ret = FSPIFFS_OPS_OPEN_FILE_FAILED; goto err_exit; } if (0 != status.size) { - FSPIFFS_ERROR("invalid file size %d", status.size); + FSPIFFS_ERROR("Invalid file size %d", status.size); ret = FSPIFFS_OPS_OPEN_FILE_FAILED; goto err_exit; } - vPrintf("create file %s success !!!\r\n", file_name); + vPrintf("File %s created successfully.\r\n", file_name); err_exit: (void)SPIFFS_close(&instance.fs, fd); @@ -266,14 +275,14 @@ int FSpiffsOpsWriteFile(const char *file_name, const char *str) spiffs_file fd = SPIFFS_open(&instance.fs, file_name, SPIFFS_RDWR | SPIFFS_TRUNC, 0); if (0 > fd) { - FSPIFFS_ERROR("failed to open file %s errno %d", file_name, SPIFFS_errno(&instance.fs)); + FSPIFFS_ERROR("Failed to open file %s, errno %d", file_name, SPIFFS_errno(&instance.fs)); return FSPIFFS_OPS_OPEN_FILE_FAILED; } int result = SPIFFS_write(&instance.fs, fd, (void *)str, wr_len); if (result < 0) { - FSPIFFS_ERROR("failed to write file %s errno %d", file_name, SPIFFS_errno(&instance.fs)); + FSPIFFS_ERROR("Failed to write file %s, errno %d", file_name, SPIFFS_errno(&instance.fs)); ret = FSPIFFS_OPS_WRITE_FILE_FAILED; goto err_exit; } @@ -284,24 +293,24 @@ int FSpiffsOpsWriteFile(const char *file_name, const char *str) result = SPIFFS_fstat(&instance.fs, fd, &status); if (result < 0) { - FSPIFFS_ERROR("failed to get status of file %s errno %d", file_name, SPIFFS_errno(&instance.fs)); + FSPIFFS_ERROR("Failed to get status of file %s, errno %d", file_name, SPIFFS_errno(&instance.fs)); ret = FSPIFFS_OPS_WRITE_FILE_FAILED; goto err_exit; } if (status.size != wr_len) { - FSPIFFS_ERROR("file write size %ld != %ld", status.size, wr_len); + FSPIFFS_ERROR("File write size %ld != %ld", status.size, wr_len); ret = FSPIFFS_OPS_WRITE_FILE_FAILED; goto err_exit; } /* flush all pending writes from cache to flash */ (void)SPIFFS_fflush(&instance.fs, fd); - vPrintf("write file %s with %d bytes success !!!\r\n", file_name, wr_len); + vPrintf("Write file %s with %d bytes successfully.\r\n", file_name, wr_len); err_exit: (void)SPIFFS_close(&instance.fs, fd); - return ret; + return ret; } int FSpiffsOpsReadFile(const char *file_name) @@ -312,7 +321,7 @@ int FSpiffsOpsReadFile(const char *file_name) if (FALSE == instance.fs_ready) { - FSPIFFS_ERROR("please mount file system first !!!"); + FSPIFFS_ERROR("Please mount file system first."); return FSPIFFS_OPS_NOT_YET_MOUNT; } @@ -326,7 +335,7 @@ int FSpiffsOpsReadFile(const char *file_name) spiffs_file fd = SPIFFS_open(&instance.fs, file_name, open_flags, 0); if (0 > fd) { - FSPIFFS_ERROR("failed to open file %s errno %d", file_name, SPIFFS_errno(&instance.fs)); + FSPIFFS_ERROR("Failed to open file %s, errno %d", file_name, SPIFFS_errno(&instance.fs)); return FSPIFFS_OPS_OPEN_FILE_FAILED; } @@ -335,7 +344,7 @@ int FSpiffsOpsReadFile(const char *file_name) result = SPIFFS_fstat(&instance.fs, fd, &status); if (result < 0) { - FSPIFFS_ERROR("failed to get status of file %s errno %d", file_name, SPIFFS_errno(&instance.fs)); + FSPIFFS_ERROR("Failed to get status of file %s, errno %d", file_name, SPIFFS_errno(&instance.fs)); ret = FSPIFFS_OPS_OPEN_FILE_FAILED; goto err_exit; } @@ -343,35 +352,34 @@ int FSpiffsOpsReadFile(const char *file_name) s32_t offset = SPIFFS_lseek(&instance.fs, fd, 0, SPIFFS_SEEK_END); if ((s32_t)status.size != offset) { - FSPIFFS_ERROR("file %s spiffs:%ld! = fs:%ld", file_name, status.size, offset); + FSPIFFS_ERROR("File %s spiffs:%ld != fs:%ld", file_name, status.size, offset); ret = FSPIFFS_OPS_OPEN_FILE_FAILED; goto err_exit; } - memset(fspiffs_rw_buf, 0 , FSPIFFS_RW_BUF_SIZE); + memset(fspiffs_rd_buf, 0, FSPIFFS_RW_BUF_SIZE); /* seek to offset and start read */ if (0 > SPIFFS_lseek(&instance.fs, fd, 0, SPIFFS_SEEK_SET)) { - FSPIFFS_ERROR("seek file failed !!!"); + FSPIFFS_ERROR("Seek file failed."); ret = FSPIFFS_OPS_READ_FILE_FAILED; goto err_exit; } - /*vPrintf("read %s from position %ld\n", file_name, SPIFFS_tell(&instance.fs, fd));*/ s32_t read_len = min((s32_t)FSPIFFS_RW_BUF_SIZE, (s32_t)status.size); - s32_t read_bytes = SPIFFS_read(&instance.fs, fd, (void *)fspiffs_rw_buf, read_len); + s32_t read_bytes = SPIFFS_read(&instance.fs, fd, (void *)fspiffs_rd_buf, read_len); if (read_bytes < 0) { - FSPIFFS_ERROR("failed to read file %s errno %d", file_name, SPIFFS_errno(&instance.fs)); + FSPIFFS_ERROR("Failed to read file %s, errno %d", file_name, SPIFFS_errno(&instance.fs)); ret = FSPIFFS_OPS_READ_FILE_FAILED; goto err_exit; } - vPrintf("read %s success, str = %s\n\n", file_name, fspiffs_rw_buf); + vPrintf("Read %s success, str = %s\n", file_name, fspiffs_rd_buf); -err_exit : +err_exit : /* close file */ (void)SPIFFS_close(&instance.fs, fd); @@ -381,17 +389,17 @@ err_exit : static void FFreeRTOSQspiSpiffsInitTask(void *pvParameters) { - int result = 0; + int result = 0; if (TRUE == spiffs_inited) { - FSPIFFS_WARN("spiffs is already initialized"); + FSPIFFS_WARN("Spiffs is already initialized."); return; } - /* The qspi_id to use is passed in via the parameter. - Cast this to a qspi_id pointer. */ - u32 qspi_id = (u32)(uintptr)pvParameters; + /* The qspi_id to use is passed in via the parameter. + Cast this to a qspi_id pointer. */ + u32 qspi_id = (u32)(uintptr)pvParameters; printf("qspi_id: %d\n", qspi_id); #if defined(CONFIG_TARGET_E2000) @@ -411,7 +419,7 @@ static void FFreeRTOSQspiSpiffsInitTask(void *pvParameters) result = FSpiffsInitialize(&instance, FSPIFFS_PORT_TO_FQSPI); if (FSPIFFS_PORT_OK != result) { - FSPIFFS_ERROR("initialize spiffs failed"); + FSPIFFS_ERROR("Initialize spiffs failed."); return; } @@ -420,209 +428,163 @@ static void FFreeRTOSQspiSpiffsInitTask(void *pvParameters) FSpiffsOpsCreateFile(file_name); spiffs_inited = TRUE; - + FSpiffsOpsListAll(); - FSPIFFS_INFO("spiffs init success !!!\r\n"); + FSPIFFS_INFO("Spiffs init successfully."); for (int i = 0; i < READ_WRITE_TASK_NUM; i++) { xSemaphoreGive(xCountingSemaphore); } - - vTaskDelete(NULL); - -} + vTaskDelete(NULL); -static void FFreeRTOSQspiSpiffsReadTask(void *pvParameters) -{ - const char *pcTaskName = (char *) pvParameters; - const TickType_t xDelay = pdMS_TO_TICKS(TASK_DELAY_MS); - FError ret = FT_SUCCESS; - - xSemaphoreTake(xCountingSemaphore, portMAX_DELAY); - - /* As per most tasks, this task is implemented in an infinite loop. */ - for( ;; ) - { - /* Print out the name of this task. */ - vPrintf( pcTaskName ); - - FSpiffsOpsReadFile(file_name); - - /* Delay for a period. This time a call to vTaskDelay() is used which - places the task into the Blocked state until the delay period has - expired. The parameter takes a time specified in 'ticks', and the - pdMS_TO_TICKS() macro is used (where the xDelay constant is - declared) to convert TASK_DELAY_MS milliseconds into an equivalent time in - ticks. */ - vTaskDelay(xDelay); - } } - -static void FFreeRTOSQspiSpiffsWriteTask(void *pvParameters) +static void FFreeRTOSQspiSpiffsWriteReadTask(void *pvParameters) { - const char *pcTaskName = "FFreeRTOSQspiSpiffsWriteTask is running\r\n"; - const TickType_t xDelay = pdMS_TO_TICKS(TASK_DELAY_MS); - FError ret = FT_SUCCESS; - char *string = "spiffs qspi write"; - static char string_out[FSPIFFS_RW_BUF_SIZE] = {0}; + const char *pcTaskName = (char *) pvParameters; + const TickType_t xDelay = pdMS_TO_TICKS(TASK_DELAY_MS); + FError ret = FT_SUCCESS; + char *string = "spiffs qspi write times"; + static int i = 0; + memset(fspiffs_wr_buf, 0, FSPIFFS_RW_BUF_SIZE); - static int i = 0; - xSemaphoreTake(xCountingSemaphore, portMAX_DELAY); - /* As per most tasks, this task is implemented in an infinite loop. */ for (;;) { - /* Print out the name of this task. */ - vPrintf( pcTaskName ); - i++; - sprintf(string_out, "%s-%d", string, i); - vPrintf( "write to %s, str = %s\n", file_name, string_out); - FSpiffsOpsWriteFile(file_name, string_out); - - /* Delay for a period. This time a call to vTaskDelay() is used which - places the task into the Blocked state until the delay period has - expired. The parameter takes a time specified in 'ticks', and the - pdMS_TO_TICKS() macro is used (where the xDelay constant is - declared) to convert TASK_DELAY_MS milliseconds into an equivalent time in - ticks. */ - vTaskDelay(xDelay); - } + /* Print out the name of this task. */ + vPrintf(pcTaskName); + i++; + sprintf(fspiffs_wr_buf, "%s-%d", string, i); + vPrintf("Write to %s, str = %s\n", file_name, fspiffs_wr_buf); + + FSpiffsOpsWriteFile(file_name, fspiffs_wr_buf); + FSpiffsOpsReadFile(file_name); + + if (0 != strcmp(fspiffs_wr_buf, fspiffs_rd_buf)) + { + FSPIFFS_ERROR("Read and write data are not equal!!!!\nwrite data:%s ,read data:%s\n", fspiffs_wr_buf, fspiffs_rd_buf); + vTaskDelete(NULL); + } + else + { + printf("Successfully, read and write data are equal.\n\n"); + } + /* Delay for a period. This time a call to vTaskDelay() is used which + places the task into the Blocked state until the delay period has + expired. The parameter takes a time specified in 'ticks', and the + pdMS_TO_TICKS() macro is used (where the xDelay constant is + declared) to convert TASK_DELAY_MS milliseconds into an equivalent time in + ticks. */ + vTaskDelay(xDelay); + } } -static void prvOneShotTimerCallback( TimerHandle_t xTimer ) +static void prvOneShotTimerCallback(TimerHandle_t xTimer) { - /* Output a string to show the time at which the callback was executed. */ - vPrintf( "One-shot timer callback executing, delete QspiSpiffs ReadTask and WriteTask.\r\n" ); + /* Output a string to show the time at which the callback was executed. */ + vPrintf("One-shot timer callback executing, delete QspiSpiffs ReadTask and WriteTask.\r\n"); - FFreeRTOSQspiSpiffsDelete(); + FFreeRTOSQspiSpiffsDelete(); } BaseType_t FFreeRTOSQspiSpiffsCreate(u32 qspi_id) { BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为 pdPASS */ - BaseType_t xTimerStarted = pdPASS; - + BaseType_t xTimerStarted = pdPASS; + xCountingSemaphore = xSemaphoreCreateCounting(READ_WRITE_TASK_NUM, 0); if (xCountingSemaphore == NULL) - { - printf("FFreeRTOSQspiSpiffsCreate xCountingSemaphore create failed.\r\n" ); + { + printf("FFreeRTOSQspiSpiffsCreate xCountingSemaphore create failed.\r\n"); return pdFAIL; } - char *xString1 = "FFreeRTOSQspiSpiffsReadTask1 is running\r\n"; - char *xString2 = "FFreeRTOSQspiSpiffsReadTask2 is running\r\n"; + taskENTER_CRITICAL(); /*进入临界区*/ - - xReturn = xTaskCreate((TaskFunction_t )FFreeRTOSQspiSpiffsInitTask, /* 任务入口函数 */ - (const char* )"FFreeRTOSQspiSpiffsInitTask",/* 任务名字 */ - (uint16_t )4096, /* 任务栈大小 */ - (void* )(uintptr)qspi_id,/* 任务入口函数参数 */ - (UBaseType_t )1, /* 任务的优先级 */ - NULL); /* 任务控制 */ - - xReturn = xTaskCreate((TaskFunction_t )FFreeRTOSQspiSpiffsReadTask, /* 任务入口函数 */ - (const char* )"FFreeRTOSQspiSpiffsReadTask",/* 任务名字 */ - (uint16_t )4096, /* 任务栈大小 */ - (void* )xString1,/* 任务入口函数参数 */ - (UBaseType_t )configMAX_PRIORITIES-1, /* 任务的优先级 */ - (TaskHandle_t* )&qspi_read1_handle); /* 任务控制 */ - - xReturn = xTaskCreate((TaskFunction_t )FFreeRTOSQspiSpiffsReadTask, /* 任务入口函数 */ - (const char* )"FFreeRTOSQspiSpiffsReadTask",/* 任务名字 */ - (uint16_t )4096, /* 任务栈大小 */ - (void* )xString2,/* 任务入口函数参数 */ - (UBaseType_t )configMAX_PRIORITIES-1, /* 任务的优先级 */ - (TaskHandle_t* )&qspi_read2_handle); /* 任务控制 */ - - xReturn = xTaskCreate((TaskFunction_t )FFreeRTOSQspiSpiffsWriteTask, /* 任务入口函数 */ - (const char* )"FFreeRTOSQspiSpiffsWriteTask",/* 任务名字 */ - (uint16_t )4096, /* 任务栈大小 */ - (void* )NULL,/* 任务入口函数参数 */ - (UBaseType_t )configMAX_PRIORITIES-1, /* 任务的优先级 */ - (TaskHandle_t* )&qspi_write_handle); /* 任务控制 */ - - /* Create the one shot software timer, storing the handle to the created - software timer in xOneShotTimer. */ - xOneShotTimer = xTimerCreate( "OneShot Software Timer", /* Text name for the software timer - not used by FreeRTOS. */ - ONE_SHOT_TIMER_PERIOD, /* The software timer's period in ticks. */ - pdFALSE, /* Setting uxAutoRealod to pdFALSE creates a one-shot software timer. */ - 0, /* This example does not use the timer id. */ - prvOneShotTimerCallback ); /* The callback function to be used by the software timer being created. */ - - /* Check the timers were created. */ - if( xOneShotTimer != NULL ) - { - /* Start the software timers, using a block time of 0 (no block time). - The scheduler has not been started yet so any block time specified here - would be ignored anyway. */ - xTimerStarted = xTimerStart( xOneShotTimer, 0 ); - - /* The implementation of xTimerStart() uses the timer command queue, and - xTimerStart() will fail if the timer command queue gets full. The timer - service task does not get created until the scheduler is started, so all - commands sent to the command queue will stay in the queue until after - the scheduler has been started. Check both calls to xTimerStart() - passed. */ - if( xTimerStarted != pdPASS) - { - vPrintf("CreateSoftwareTimerTasks xTimerStart failed \r\n"); - } - } - else - { - vPrintf("CreateSoftwareTimerTasks xTimerCreate failed \r\n"); - } - - taskEXIT_CRITICAL(); - + + xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSQspiSpiffsInitTask, /* 任务入口函数 */ + (const char *)"FFreeRTOSQspiSpiffsInitTask",/* 任务名字 */ + (uint16_t)4096, /* 任务栈大小 */ + (void *)(uintptr)qspi_id,/* 任务入口函数参数 */ + (UBaseType_t)1, /* 任务的优先级 */ + NULL); /* 任务控制 */ + + xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSQspiSpiffsWriteReadTask, /* 任务入口函数 */ + (const char *)"FFreeRTOSQspiSpiffsWriteReadTask",/* 任务名字 */ + (uint16_t)4096, /* 任务栈大小 */ + (void *)xString,/* 任务入口函数参数 */ + (UBaseType_t)configMAX_PRIORITIES - 1, /* 任务的优先级 */ + (TaskHandle_t *)&qspi_rw_handle); /* 任务控制 */ + + /* Create the one shot software timer, storing the handle to the created + software timer in xOneShotTimer. */ + xOneShotTimer = xTimerCreate("OneShot Software Timer", /* Text name for the software timer - not used by FreeRTOS. */ + ONE_SHOT_TIMER_PERIOD, /* The software timer's period in ticks. */ + pdFALSE, /* Setting uxAutoRealod to pdFALSE creates a one-shot software timer. */ + 0, /* This example does not use the timer id. */ + prvOneShotTimerCallback); /* The callback function to be used by the software timer being created. */ + + /* Check the timers were created. */ + if (xOneShotTimer != NULL) + { + /* Start the software timers, using a block time of 0 (no block time). + The scheduler has not been started yet so any block time specified here + would be ignored anyway. */ + xTimerStarted = xTimerStart(xOneShotTimer, 0); + + /* The implementation of xTimerStart() uses the timer command queue, and + xTimerStart() will fail if the timer command queue gets full. The timer + service task does not get created until the scheduler is started, so all + commands sent to the command queue will stay in the queue until after + the scheduler has been started. Check both calls to xTimerStart() + passed. */ + if (xTimerStarted != pdPASS) + { + vPrintf("CreateSoftwareTimerTasks xTimerStart failed. \r\n"); + } + } + else + { + vPrintf("CreateSoftwareTimerTasks xTimerCreate failed. \r\n"); + } + + taskEXIT_CRITICAL(); + return xReturn; } static void FFreeRTOSQspiSpiffsDelete(void) { - BaseType_t xReturn = pdPASS; + BaseType_t xReturn = pdPASS; FSpiffsDeInitialize(&instance); - - if(qspi_read1_handle) + + if (qspi_rw_handle) { - vTaskDelete(qspi_read1_handle); - vPrintf("Delete FFreeRTOSQspiSpiffsReadTask1 success\r\n"); + vTaskDelete(qspi_rw_handle); + vPrintf("Delete FFreeRTOSQspiSpiffsWriteReadTask successfully.\r\n"); } - if(qspi_read2_handle) + /* delete count sem */ + vSemaphoreDelete(xCountingSemaphore); + + /* delete timer */ + xReturn = xTimerDelete(xOneShotTimer, 0); + if (xReturn != pdPASS) { - vTaskDelete(qspi_read2_handle); - vPrintf("Delete FFreeRTOSQspiSpiffsReadTask2 success\r\n"); + vPrintf("OneShot Software Timer Delete failed.\r\n"); } - - if(qspi_write_handle) + else { - vTaskDelete(qspi_write_handle); - vPrintf("Delete FFreeRTOSQspiSpiffsWriteTask success\r\n"); + vPrintf("OneShot Software Timer Delete successfully.\r\n"); } - - /* delete count sem */ - vSemaphoreDelete(xCountingSemaphore); - - /* delete timer */ - xReturn = xTimerDelete(xOneShotTimer, 0); - if(xReturn != pdPASS) - { - vPrintf("OneShot Software Timer Delete failed.\r\n"); - } - else - { - vPrintf("OneShot Software Timer Delete success.\r\n"); - } - + } diff --git a/example/storage/sata_fatfs/configs/ft2004_aarch64_eg_configs b/example/storage/sata_fatfs/configs/ft2004_aarch64_eg_configs deleted file mode 100644 index 3868441a..00000000 --- a/example/storage/sata_fatfs/configs/ft2004_aarch64_eg_configs +++ /dev/null @@ -1,233 +0,0 @@ - -# -# Freertos Configuration -# -CONFIG_TARGET_NAME="ft2004_freertos_a64" -# end of Freertos Configuration - -# -# Standalone Setting -# -CONFIG_USE_FREERTOS=y - -# -# Arch Configuration -# -# CONFIG_TARGET_ARMV8_AARCH32 is not set -CONFIG_TARGET_ARMV8_AARCH64=y -CONFIG_USE_CACHE=y -CONFIG_USE_L3CACHE=y -CONFIG_USE_MMU=y -CONFIG_USE_SYS_TICK=y -# CONFIG_MMU_DEBUG_PRINTS is not set -# end of Arch Configuration - -# -# Board Configuration -# -CONFIG_TARGET_F2000_4=y -# CONFIG_TARGET_D2000 is not set -# CONFIG_TARGET_E2000Q is not set -# CONFIG_TARGET_E2000D is not set -# CONFIG_TARGET_E2000S is not set -CONFIG_DEFAULT_DEBUG_PRINT_UART1=y -# CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set -# CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set -# end of Board Configuration - -# -# Components Configuration -# -# CONFIG_USE_SPI is not set -# CONFIG_USE_QSPI is not set -CONFIG_USE_GIC=y -CONFIG_ENABLE_GICV3=y -CONFIG_USE_SERIAL=y - -# -# Usart Configuration -# -CONFIG_ENABLE_Pl011_UART=y -# end of Usart Configuration - -# CONFIG_USE_GPIO is not set -# CONFIG_USE_ETH is not set -# CONFIG_USE_CAN is not set -# CONFIG_USE_I2C is not set -# CONFIG_USE_TIMER is not set -# CONFIG_USE_MIO is not set -# CONFIG_USE_SDMMC is not set -CONFIG_USE_PCIE=y - -# -# Pcie Configuration -# -CONFIG_ENABLE_F_PCIE=y -# end of Pcie Configuration - -# CONFIG_USE_WDT is not set -# CONFIG_USE_DMA is not set -# CONFIG_USE_NAND is not set -# CONFIG_USE_RTC is not set -CONFIG_USE_SATA=y - -# -# FSATA Configuration -# -CONFIG_ENABLE_FSATA=y -# end of FSATA Configuration - -# CONFIG_USE_USB is not set -# CONFIG_USE_ADC is not set -# CONFIG_USE_PWM is not set -# CONFIG_USE_IPC is not set -# end of Components Configuration - -CONFIG_USE_NEW_LIBC=y -# end of Standalone Setting - -# -# Building Option -# -# CONFIG_LOG_VERBOS is not set -# CONFIG_LOG_DEBUG is not set -CONFIG_LOG_INFO=y -# CONFIG_LOG_WARN is not set -# CONFIG_LOG_ERROR is not set -# CONFIG_LOG_NONE is not set -CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y -CONFIG_INTERRUPT_ROLE_MASTER=y -# CONFIG_INTERRUPT_ROLE_SLAVE is not set -# CONFIG_LOG_EXTRA_INFO is not set -# CONFIG_BOOTUP_DEBUG_PRINTS is not set - -# -# Linker Options -# -# CONFIG_AARCH32_RAM_LD is not set -CONFIG_AARCH64_RAM_LD=y -# CONFIG_USER_DEFINED_LD is not set -CONFIG_LINK_SCRIPT_ROM=y -CONFIG_ROM_START_UP_ADDR=0x80100000 -CONFIG_ROM_SIZE_MB=1 -CONFIG_LINK_SCRIPT_RAM=y -CONFIG_RAM_START_UP_ADDR=0x81000000 -CONFIG_RAM_SIZE_MB=64 -CONFIG_HEAP_SIZE=1 -CONFIG_STACK_SIZE=0x100000 -CONFIG_FPU_STACK_SIZE=0x1000 -# end of Linker Options - -# -# Compiler Options -# -CONFIG_OUTPUT_BINARY=y -# end of Compiler Options -# end of Building Option - -# -# Component Configuration -# - -# -# Freertos Uart Drivers -# -CONFIG_FREERTOS_USE_UART=y -# end of Freertos Uart Drivers - -# -# Freertos Pwm Drivers -# -# CONFIG_FREERTOS_USE_PWM is not set -# end of Freertos Pwm Drivers - -# -# Freertos Qspi Drivers -# -# CONFIG_FREERTOS_USE_QSPI is not set -# end of Freertos Qspi Drivers - -# -# Freertos Wdt Drivers -# -# CONFIG_FREERTOS_USE_WDT is not set -# end of Freertos Wdt Drivers - -# -# Freertos Eth Drivers -# -# CONFIG_FREERTOS_USE_XMAC is not set -# end of Freertos Eth Drivers - -# -# Freertos Gpio Drivers -# -# CONFIG_FREERTOS_USE_GPIO is not set -# end of Freertos Gpio Drivers - -# -# Freertos Spim Drivers -# -# CONFIG_FREERTOS_USE_FSPIM is not set -# end of Freertos Spim Drivers - -# -# Freertos DMA Drivers -# -# CONFIG_FREERTOS_USE_FDDMA is not set -# CONFIG_FREERTOS_USE_FGDMA is not set -# end of Freertos DMA Drivers - -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - -# -# Freertos Adc Drivers -# -# CONFIG_FREERTOS_USE_ADC is not set -# end of Freertos Adc Drivers - -# -# Freertos Can Drivers -# -# CONFIG_FREERTOS_USE_CAN is not set -# end of Freertos Can Drivers -# end of Component Configuration - -# -# FreeRTOS Setting -# -# CONFIG_USE_LWIP is not set -CONFIG_USE_BACKTRACE=y -CONFIG_USE_FATFS=y - -# -# FATFS Configuration -# -# CONFIG_SELECT_FATFS_RAM_DISK is not set -# CONFIG_SELECT_FATFS_FSDMMC is not set -CONFIG_SELECT_FATFS_FSATA_PCIE=y -# CONFIG_SELECT_FATFS_USB is not set -# end of FATFS Configuration - -# CONFIG_USE_SFUD is not set -# CONFIG_USE_SPIFFS is not set -# CONFIG_USE_AMP is not set -CONFIG_USE_LETTER_SHELL=y - -# -# Letter Shell Configuration -# -CONFIG_LS_PL011_UART=y -CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y -# CONFIG_DEFAULT_LETTER_SHELL_USE_UART0 is not set -# CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set -# end of Letter Shell Configuration - -CONFIG_USE_TLSF=y -# CONFIG_USE_SDMMC_CMD is not set -# CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting diff --git a/example/storage/sata_fatfs/figs/delete.png b/example/storage/sata_fatfs/figs/delete.png deleted file mode 100644 index 4c5fbb6407cadb3bdc9b0537dba4860944667f7e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26235 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

    U@`YO!*NB)IDR`T556{yFIja=K8N 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 CHfrwx diff --git a/example/storage/sata_fatfs/figs/hardware.png b/example/storage/sata_fatfs/figs/hardware.png deleted file mode 100644 index cdea6452d22db6b1273d70a7ed4f95882d69f250..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 882786 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

  • A8ZinZ}iqZHtB4awmCwZxX$ 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

    Y zA+@R)?x|7mOi6=VN-|tC65y7d49CngIOk-+DL(^ld07Z4EJajx4Z-dl(glp@yN6|kpjKdtzL_%F$k&r6 z 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 z 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 z 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� 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�m^kQ!77VbWOfvo=a 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℞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%0D(+je66 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

    Wd@ED-j1$w!~Qk)*t60WJC|8u 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%0DRYY2O*1@>6J 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 bsAPWwHI3}Aemi5o00000NkvXXu0mjf-ENdS diff --git a/example/storage/sata_fatfs/figs/init.png b/example/storage/sata_fatfs/figs/init.png deleted file mode 100644 index 59afd7bf10df65c6dc26f568b7c54e0ffe099556..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40282 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

    Ll(19o3$~-y*$R*e7T@GhyNbJ@_xHbvzU5 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 A%>V!Z diff --git a/example/storage/sata_fatfs/figs/menuconfig.png b/example/storage/sata_fatfs/figs/menuconfig.png deleted file mode 100644 index be837a354997dd96023fd925b79c1cd40e405bab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11688 zcmd6Ni9eLz`}g#zsD#pnY%P+kQT8RN4@D^|WXn3l*p1yNTcnh2LP$umZ!^}hg&2%= z27@8HnK8DRF*Al|rq6fz{a(-W2Rzs7#Xa}A&vnjquH}8MbKQ6BqlbFj#{`c7008cL z`ge>0fP?m|-z7&lSpPNE3m&m92Yih6ZUajDg;rQMhk!Z{bO3;g1g>4%!>s$Gp8DoK z005sa`|rTClV|_{AftKjj?R++YvL3NDc#kC^I{$d+DmpOdmgu5H2QGj;IzwJ=D_WB zw`yq9uitS;%`Gp)o;dRS>YJlG;h*pF8Llm+3)%aqc;0o3kCo*YdM!5TxWr(BP5u4+ zp87rYM{V~ilA@s{io?TJPpzg*vI`)+77v{0PzVjur@c?oRw}b$ViraBkT~UL`X;b% z1-FM^T!8G9(_;3+UhZudXy1g;kT&W2w1oX!+M0IQwB^XGr5y8RBnz1@Fl!uDeP_5VRc`IDWW{s)0SO$Xs6_D5J|0{~>*Hrw7R_jTFq z<^(R?U8jp%=?bvhXFmVE|KY^;+PP*|tuRzDNRGtJp%LCP!mWr#JHx+ubZnz_!)8dbjkc4x3hadrr$2zQg@T{A)3-rtxOP4|GD zu@w9c<=R_?_jy1vPV_h5wAe4gtC+yUqr06ORD-i=jCKDF?|T^#N{+v0DUnmHS!ia8 zF;O=C&aK_wfr$%3(kNVMBoo?ev#|o0^|bjmh!(=@Mhd&`7V#LjPRC~1?7gKJz^A-P z9jW>CO5d$W54M-$gWZ?>wa8G(h$*=+Ovn{vd|!iV(~qAX1!H2XJnwZcp}rt8C?+6Y zV$yAB;9Fb5%T7~q2A1P1d9)&Z`_;Tk$lEXv)54W{4sazFrI+I%vB*bfM9i!Z>K+~OAW&48#*D9tjkNUH`!+9d=sq| zegI3u=1fHBKQd+7Z7fzORS1XK?o0;-zDMgJww-u+^0#9Bx62GsyK*19na_9$7*9$Q zxOpV>7GmcLq}-d7vL>33*EEG7s@2_qGEnYclS`nqbAk?I8FwN_Kmun_F(QD!Xw2QbrVDDEzfd%WQ_3Ne-(Mn)dC5WC#`AD`ow096g}O+wOrsw; zelzo+pO15oGV!=^P7e3>snyO{VQICX6O*AY(#I&dt-5!$%XI?gTV5c2B78Il#QOtQ z&l&nxcVy#3LrQFmPff`=?xD0s>>uZ8j|xc`po9DOLR|dO{b-Us zzQ(TuStV`(acd4PU7M{9UYvVH5rAmdzbS!P5I6Fl*wSPX%`Tzs-Y(|ifGofBS6EVx z{3E5?K`egGWX3kvC62gH_m>5W#eJ?(KUX;1WwH14l27?SeN%8@Q2u4Gg8Hvot;Z9* z^`JAFS9gdnI1_$C-y|0Vl_SWTLQ`7Cm}SJQR3_>p4Oa(?=<8%^(Zp+XyJFNUOe_Ke*|9mGEPv+=Atlq#Y-hYHgUtY6z%d zY(drCx;eBh6UB2jOkJYKT*1apqDo1BJ9eH@?kN7+XFW?sds)==iA>oSD@)N&M__kX zLh2vxtF1g?kQp)kIOt;fm#nBQEH(@l-w3ca8HYyoK!RKT$LUD^W zwM4av#lcN-7vJcpjB~I$&*)-Y4|C3L85k8Y1<&a$0w1Ws^#}H(`X7#3)V%p6)E3G*%{k8FxQO8;w9r2m6UEdDC1G(^)q!FQu%JSyRU%Mp|&tjzSH5O-su)2xBXtIB~D); zCSp16;P*;;y(9NmqO-6ySm?n{A$eu+wM?kxSXQA2@#+|7|Ea-hrRS{kcR{Yr94tw!~j7dk(XevX`H>1mKjCbuvCMeVK;At7g zZxYfFI}&2rFA{VAy<7!`U?wVQ(@M=qx!0o|q%CxWZihGeH3|<1ezUA~>XIYYO?%aC zk9p+>@kMMrOdWrp#R~NLD?J|gZfOgI13}JJkt~;L zX6@CWQn)90Ez`(>_kG2}*o>5O!&t}}$4_ImI0>u?T_+&z>)um?eZUt;ra?+mP($A! z?AoN9-;|FH1u?&ua}BLtN#6TdIk!Pt#EzrQ*XwF<(26;o0w>6KEuIvF6ZvhmZY$No zh%;nu^Ac8M4mAF@MEim{E}i)JC7yY;dX#EGwf-T>isc5m&L?j0;$M{RwWagaBFhFf zahyko@j_30nK#z-OiG!k#LE*!lW0XJD3GyKp7~Wr2`k$Ugc3y0+3)9`k-Vy3IcUsj zbLPh1F1cg{8x3V0{CTv&gj5jf&JS*ldhWIZ1}Im|5UtJcc|kl#)TmN)tdbAg12KZR ztVSD4`4b;Lu4w!X_A+MPe4>{9OGL;X8B09Kbe;0v#uXAPBj#Hl&~*sWJ`HOPjJF`4#vU?MRu#z>Q>c6|?VucB@>3q+bS*Nt+n4p{A1$CzJ zk-6|^bF)*(FMpLA2#^!?8>AIC>c;4&63HdwBEjF63n--Zo#o3Dk{I5&R17)A!6vSd zwGoRm0;vt`E>8G-;F#)3eYfG8qo8w_($U!8)hX}hxQJEeLoT$ik@4CaZ zFXLp85?RHfPa!u+?v)k*WpOi5!73kvxB-fv@aoa7jfxUgwTzp^>d-2yzs z6!UpR!RlZ>s)gs%^&WO?#$h`oWsL6DRdIHWdDCBgq^1uvp9savnx9NU%7c@46BGB& za@lJN2k4)Vgy@t_yZcmU8c+-*N%OOkirIasH4aS{B+=md0`S`V%oT-uIE>a*AAEKSKAWvc8lW;tsNaY;mHqKFEcpheU>!+Nq1Jii;-HEOX3+0>kE7ERT&q4qR6?AP*B zMW6qg1XwOyOAPWDGC%b$b#yC@D}zvD@-IO<#M5S<~ckr!Xc+i{P9eCBUT>MZC_AoK*g+)pNvc3M}v}u zc-3w$paYYLra>XGsUEicRa7bMbES}3FBXgta=vC?K}sR@K}bv1W`|mQO9|FAI718R z03)xBqfldIiNrY;dY>^^^PpWf_qNJk;KKe;=aBiKD;6x|Zz+6=p;K*jr#3VZD^&%t zG~5@R7^}$aP6AbzR_yBCdl{EWxJpTPb9OlaF9jp?F9CUOD_=r$NY+I}%z^(ZV-n~a z>(M=I-Be@F^1QAmzl?#Cdz$Ty@`oJ9ltjtrh!IGb|HkHhY=;+dxapkm4RkM%(Wc6HYmx&s zp>3`e&FFGpE6HpiweIZ{l$k@q&TKEmk&uaVIufd5Z+?ly)cf^{*tls^CweIN(oD7N zjik4*1HzX~us^wL8)3to&#H}1j-a|BF$+_xwHEc7U~d>n`SB316ZG6TxD=;{v8b4; zjC(J)gg32XWDuL%z2j>PLiRJy2=Ny4>QC9}{Ooqe4Q+N%tb#$aUPDQm?}Lj=Ovu$? zV&rYO7j>dG8%+{DH@B}Vb)G1OUY>rXI!enoW+sK**`_f|6}uI%t^rXZ^Ov|k67MLt zs2Sm$(lSwMee&5!nztriO4}#!d#}D#i~d?7KF*yAsmS<5oT22X zi-C~_qq(<6Sz0Yq9J!nQCS@&QoVKe(rg1_CDa#Wu#zn6(YN-Aq88fKWWPq33T0jWN zcH_FDnE9FnIVB?ozq7JUWu_F|;{ITm>V)-N*fdYP+8Ku4#>Oo-7Cg z3Gue6!7m=nXC+@hR1iCOn3|b@qbT^`=f|2HgCuzObzRN}rM(-kaI15rCJJHW-HSL6 z9c{sQYCd>+bI-C$G$pL;+X!LFf?D*OS+d9gbuI@i>qE%<;R8}cs`$cNk(f>-3KrVa z>lJcQuj=Uv#p}T@bW#$>rb-1zdz@uO29M*#9e>|GgZbG=5L# zq5%57Psh!S#utSf@hR6_s(qjbYP~3?3gZc#&~wXSNjq;90jGcO{Pn^=2=+8VIp~VA zzxSefbcLc|_Jrn^fXa+&a1QnNib=xcUS33jBUBsEa-{1VK;4zZ7_v8_7mrnSpV4Oe z?-#MoqyT{BS=;06EBF@wLDnT)_(UfFpif(Uur-J&%aDUG>jSkZS^$6)yWM|@nFN`G zlb&uZtT1e~xb2!hVjxvOeg=XTl{yP=_Rxw$Kmu1N_+9#gZ6C8W<}fJ(8hXC@rS%@2 zI%Fz0(r@F(cxAEgVHdhVr>_J~S%iAYMqUTBgwpBM;a4N39uqnRqE~zoRgu>Pde3Be zRXtjc`dM_sRl9Il@9c=XSNL;;rYten#{a;w6g9oNstNpR^Ztoo$yw4lX1$~6$6J&I z%H1akX56;BqYH|s<0yPy+ zdF;!K(@Cp_OaEoO9~HZ9*kayhMofE0%Ahh7PjQ8cBi}S3o?MAHXS!dDw^}zeNm(Sr=|JIfBB6F<9!v0q7^C1lrGdbFq0-~eyN32Gv1QXx1bxVYw3CQJ zr!pKps)(pnnZgl3wN8Jme0sX?D?4s|$3r61?wg zm4t#5shcCItTb70=h$M=a}PZmlzT!cH-p@xCav+aM}oLAWip!T;c^}tR{AAmLUsy< z*(-iEX$=n(wK3{Tt8mjM!myrY=5XN}qaN5QR@j2ZvJ4nthg3xJueR}F*M#AWKinLxzz^AT??zhr7Z2n{L${9&Z9fNo{M`u zq~>qF11i#r>HwVcz&V?TDgna#!5S?OkNYm&negy->RsXJtMgkHyGa@MGDj{c9>xeW zyY1|738mVyR=6z?uZH#?Z#~9&S286+oSTb?R}e#TuPO;_$1Z!fwc>Yha|gh7U(_Wg z!df-$AFdhR>FVeA1!Ar=(o_0@$Iw`$dxGJ4arEHc-d+PwM3E z=KgrbdM@%^L#BM{BYEeCnH$GgGsbb?GYOOdr5-mDK@H)7;+J)qb8lJ!k+Qy-Jw`Zd z%AM@o4%L(z<#@tXSUGtwSPuzZ&aJ}2OQ5Nc>c+{XulR)jH6eT9qY?S;08M{XmqVRL zdcsBRyrQ)W@%fz0xvm&!Kk!*p#Rf$`s^wlFA`x|WLZN|MkzhFEz__*&G2LX`u~0-n ztx&Rh(2wC!ss5$eXUI$alav}(QlmV~8&XHlat)rLU5GybSWDu0eV=2Mi^D)^COzcJ z3`gYDt?T}fae^2|)DxUAj7DM!_uMITa?Ewix7;f6XV7x1`%A+Z12i^mN@U_;eP0Yw zJ}@q~a!*0J%b9kTw-ifWr3j9iw(SK3-dvC(p_0}=d?Xf3sYM&ycbpyz^}EX)&sK(q zVwE-+J&dW%3Gl~#9;7;!mxD&n0{&a7_uTSRUj{e~H)s=lx$t z<9gzlrH|wT{4QQVl_fA2Q&S$3KDuxwg25fr7@coCN)3UInYq;03*V$&n{~h~)9~1V z)*xRo4MiJrkOhr+!9k3)A7-}gKadwnUOJB0Mna!kSG0lCq-^d&c;H@AXD7HAF6Bmz z`zh9l!dCr7?zU-5Na+Lurr8)M{i#l&YyU{aXjt6>rDf|bYnOUqPseNzy*Q`=5q!Z1 zv>_)PtPndmd9;lm0I(Q9W)sSmJ<{d4j22>W5$*zeF9e)Bb=1CKabd8|y|#H)>}e;nl;S~ZEzn1m9hH2JLj#|!Y^us_j{!wQG9-d`?ox4d`FP!666UKX^jJB)UIy2Mjy5rcxiyUC zzi($cKTl|%b(!SQY1pBbfzEwr=OUjoqADJ=B>|H>m5X#q{%_}|Ea#I#p6M0=zO37+^MRI2f{&?!yuB;GS5msbdLcN@c z8_I2gq>B%WFldXlu2eyI;Lo;wf@L(80SWKZ7+5-ZPz(lo!#0bjYWqPAB`*7=!0?#E z-_3R^6z>y5Uw|Q_8_o$IaKv6S!cbekCBF$}hp~pJ7)xt`S#7(0X;dzhU{7Z;7+oQ@ zQ=B{N6yf-wClAT3YkhwAhS|H@kGHF!N9|Vz%+7Xl6i`|(+m6TSUSo5(qNA_pKpRW6 zGQ>M|fKmFls*#e+8QZNpuSeW%i@DuGKMRCNR828@c}Sjc~Vr70>PlkAI(Ho5=F#iO$IAsGGp9O55D%L#L>RIz~LeWZV0%-%KkmE_y_m`_t^G z=9;-^S%db6=hNM+CGpFe&Bq1S6cL<9b2v#A+YvdvbF_#7C-MO9%vPAPVGm>->oX!- z+Bmo1;RQa$nxuvHu5IjxqJ`iUdesBA_~D<$;w6td#7rR1KttGi2dtT1W??Cd`rom3 zPZp`qD0Belvfu}p?2v>5HvtKAvn>ZT-23B*6w85qR->o=->i2QBB18DLrL}w3wtAF z<|pcAQ1O&I($YrVMsJ_(G(E>{4IvPGdf2x4=l3yt%B>@FvxTZ!!duOpXy)?P1a4AI zlN*o5F@iLN(j$u1l}P5v=u4GTH}dRG_*pZH<53XRB!m6MbE{)&q&|$4l6b?pxc{j zO>o!2@X7ugDUklPnnZGKaLJX0lm+2!>#DA<+2br283=Xa%e#jEIORSle+9_}L#7hl zkVBplIZyFp)~jRIlw}Ou7hyZq9!zA=B=p<||E$!fN*+d@@yqb^U*+6OID6K3VYo{D zd6+*g>G-50lU}zf?{wgb*SD(!HvP+eu4Ocx+Xp*0t}b}B>i7KM?HWKCwi$yzR1|)WUcWt=1fcly1V~! zO~l@qz~_4a1unU#MaS*uIBnjHXj)S0`$bcI%JW2gYz?u}$?1>`un1?Nm-aeNDpRgv zx>VBy>(a;$w;46EtsAlxkDl#c7WZa~gWB;Mewo_w+}i}xVAZeImHe9ail; z!m(Sy`$BHBTgi>f$wQSuj(z6vY3zb)_$O;E|5o`_3-=rGQ80I)wm#9%$xyo)_8-^D ziI|q@zY@=hHdqmZ@PA;mEp%ZD4sJS@h1?MIwcTa6OUbt$E=&*GQWVvt2)p*cU z|D4#(z4(3Wm5{06L1GS&*0!0~bCe~LWwutl`HMF^L9Th6)Eep2D_?e1KA)*T0wj?B zuUh&FatfOu2BPJUw|`MSf&M zOC7VffLHY^hPc0#Uqq`1ncatLb}pD;$$$KIGFtwM@1w?fx5V7+vW7fq;gASsl0o-O$PQ8Vs8|8`(cV?tR$hUH8_vDOrnf&>6ufMIT?*$?R%7HVVXM8b zqm%Xs9I~z*;9%Kh2&=vJx(>gILOE(zV*Zhk^7%^&5!>;nTj$ylK}t-;mFf$ zXL!Mx#2Fw&?hepsVIvfv|K;h<(v?99`}g{1ZWdmVR^nKAmC44d?*#wvJVt#RD=G}# zPRzyKCOJJw453`D`lSWlBR#OWi~U8yjMFxY%gw)!l}#M{^(UJ+Q6*{&E?W^#u5_bD z^z1c0l?{PpjM(#isuwk~#y%{V8|KL2VX?M|Ovrx&b||U0U(~TDR}KNkZhRg`?q2P4kbamCaoSEIP2Dwb&uB!`N1u9uzG3 zt$EtT%(cBVLju=7x3Hr5>Mj0{qD;y4IU~DmdNl#(JM+&nIsC*dX_&61EW1!!Z@E z4TfH~Z<{l&QlF@(-qZ`NpUG+ZDIdt;d?lXy7*x4n-EAaM2^m!}vMId{s{MyeQKQAa z>Hz&L@4CMBCp$r*hOVFZ@heQ>%DIY$cr*%LjWzEZ(GL7KH5*knAx%U3B?Rsny!}fTcxwR?YO)U^>pV7)id%mn~N`t=+SfLVTg; zJNvzlQn40b8?(#Bqq1^$vF$Q?eK63u-N{|?W<{mm^ISs;B*G?pbp+efozF7IhfZ8- z6{m}^TV7l~Vt*g?ZN$2?cAgD{0MF)&w#NgBO;&s2udh2&W7)>4HT7sBCqZ6@2cN*Q z@57r6+sEE&D>d(~#VmHbogsf_;jyeV>`&YU3&dPM`cyQ8idlqeZ&^!`t61M^AQ(Qo znls0Kg4t8Nkjs^){N8H5i3?E>X+aO5n(4a*J(nStssHG*RFi<~M@n0zgscvUf)<_7nPw zNMX)eJC+>l$^okLZ&A#8{hgh)vOZ;F=vbrj14cOdfpe&jZLu?gyW?LXh4M3I8bs%S z9nv4}-i99kYM-Nzde5xwScnt+>7W{_lI$0@o++&^Z6G7Xa3pyQ!0+UIPff!DSDoI4usfg^3(>_p#MK*fP=T zcm86d0YiZ>UAdh5fJ z|FiCp!&K3f$Od!kF=tLD8(Vwx* zMp~+z97Q54#2%gPBp5!+>$_4GqjSgnh53n2p`vWGx~7d6O(P?+;tnl06#Px(Umj>6 z+UeAulnMIq%3Y`S4No#=$Y7pOS@n}nHtds_atu+zRm!8KtgIip@ZU~=w&F^aBKZxG?I$hP(VPLjk=L1-(!%q9bG9NZ<*$k( z13vOUGJ2iM5ha^9p6`;qTNh{xCCVJPuVD%8`DozmSuo#)wp6cJ`P4$22Q&?fsO$b^ zV|UET(t`dSU?6@ef%pc1!@(`XmU5~h^4e^f+%wVeSK{vt?93#&mp3~EDiV4h7ME1NpKf|kIB?wsRb$&*R%Y_3`S<2wQVF+x z_kuyD1kechA9HQn_HtBK416hziJ09pyeA*tANl?HS-Ttjf%tOdVdjGW!n$Z}4)3mW zcH8#|ZyL$-1Brt$rSP|oPxt1cFLLD8AiQL1p91#^SY6!0`fiTgdV0Roo6Nnm0Ts9= zlMQ6$Ijc%R-{U|@^#3S^ji*;BoZH}Mw<97sPAi+OadahN8fXR_IC1G4A-`Wgf+H{+ z2Lkqkjh~C0uWnH2jF{zQDik!MY8(Qqwzqu9kN6bm5_+rk;=b>)L|kSIETXxDWeI+E zucXa!gPR=PAQe-sGs(ack$J3=?sOVOs#wpBjpYCetNsBRc+RhKxy`Dgc&c>b{yd3~ZyQ@#sZbT_QXCmTX=`PEB@tJB z-QMeQzf}&StX;M>$8Q8UzptRO(S0)hLOiQ()74dDyD*}msU@pkwWum0k`Bj(VKsIf z)kNqR*W0-6zk1sP%%z-{eHT1M@}^@7?44*6O2*OuS3TxB_bu1{I90(XB1*NE*XxA1 zFB|ko>bMulJH1}WeAqSK0?hFwrs;C`u}Z6~oqDmx)@}FzA~KOXHHFLG$dteH`EzQ_ zmi3Q&e_p&~vC<}x;FAgD20F{Jp-qArm7u+L>d{PREjf#veB(fp|Q)|<5y!lS4B zRR)J*7_}lIyp;0yk6)~`Cuv1DXHsW%M9nJ8KNorylp(!i7>g60t39b8XkySI)}h7a z6QsSIor2F4vrcm-vqCH)8#d+9nm2xOJuSE=#&G$o(Bhlo$Z%Ifnawj0|M|}ZYbkE&B;@H!vo3f=`?`gc$O@gWBCW9JmSL>P01YqO zKMfd6qqF*qyH7lo6i~SQCB7$6?IB7e_TKuv$N~^aU|1|2;VXZ>^FIFi(SBmuugwo^ zXP*&d2RE$=JsIi-tlCUI`BUU|>crnfc7V)WWSvcJNEfTBr*fY+(Ep{f(>&<+=8$lP9wY(D zXp%X4C8k`6FZD)oHFU2A`8hKCc92qENs$fk#5M;pt!QOe$Ljv-1xL|opI2^;yE6Um zY~!djKjydab24cE>BM{BPfoKW!^(vIV&$+;(1|Ek4?qhu?vG0WTIx=+w^r5(L%QfA8+YJEgZ@y#7D6cas(X diff --git a/example/storage/sata_fatfs/figs/wr.png b/example/storage/sata_fatfs/figs/wr.png deleted file mode 100644 index 22f247968d7aeda26a56c9a7dcdb16944b116578..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41755 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 J9=mw+{{YAi`;7nq diff --git a/example/storage/sata_fatfs/src/sata_fatfs_example.c b/example/storage/sata_fatfs/src/sata_fatfs_example.c deleted file mode 100644 index a76aa5ae..00000000 --- a/example/storage/sata_fatfs/src/sata_fatfs_example.c +++ /dev/null @@ -1,484 +0,0 @@ -/* - * Copyright : (C) 2022 Phytium Information Technology, Inc. - * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * - * FilePath: qspi_example.c - * Date: 2022-07-11 11:32:48 - * LastEditTime: 2022-07-11 11:32:48 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- - */ -#include -#include -#include -#include "FreeRTOSConfig.h" -#include "FreeRTOS.h" -#include "task.h" -#include "fpinctrl.h" -#include "fsata.h" -#include "fsata_hw.h" -#include "timers.h" -#include "sata_fatfs_example.h" -#include "strto.h" -#include "fassert.h" -#include "fdebug.h" -#include "fparameters.h" - -/* file system */ -#include "ff.h" - -#define FSATA_DEBUG_TAG "FATFS-SATA" -#define FSATA_ERROR(format, ...) FT_DEBUG_PRINT_E(FSATA_DEBUG_TAG, format, ##__VA_ARGS__) -#define FSATA_WARN(format, ...) FT_DEBUG_PRINT_W(FSATA_DEBUG_TAG, format, ##__VA_ARGS__) -#define FSATA_INFO(format, ...) FT_DEBUG_PRINT_I(FSATA_DEBUG_TAG, format, ##__VA_ARGS__) -#define FSATA_DEBUG(format, ...) FT_DEBUG_PRINT_D(FSATA_DEBUG_TAG, format, ##__VA_ARGS__) - -/* The periods assigned to the one-shot timers. */ -#define ONE_SHOT_TIMER_PERIOD ( pdMS_TO_TICKS( 500000UL ) ) - -/* write and read task delay in milliseconds */ -#define TASK_DELAY_MS 3000UL - -static xTaskHandle read_handle; -static xTaskHandle write_handle; -static TimerHandle_t xOneShotTimer; - -static void FFreeRTOSSataFatfsDelete(void); - -static xSemaphoreHandle xCountingSemaphore; - -#define FSATA_FATFS_FILE_SIZE 128 - -#define FSATA_READ_LEN 32 - -static FATFS fatfs; -static boolean fatfs_ok = FALSE; -static BYTE work[FF_MAX_SS] __attribute__((aligned(32))) = {0}; -static BYTE buff[FSATA_FATFS_FILE_SIZE] __attribute__((aligned(32))) = {0}; -static char mount_path[256] = ""; -const char *file_name = "test.txt"; - -int FatfsSataFormat(const char *mount_point) -{ - FRESULT res; - - printf("no file system, formatting ...\r\n"); - - res = f_mkfs(mount_point, FM_EXFAT, 0, work, sizeof(work)); - if (res == FR_OK) - { - printf("format ok\r\n"); - res = f_mount(NULL, mount_point, 1); - res = f_mount(&fatfs, mount_point, 1); - if (FR_OK != res) - { - FSATA_ERROR("mount failed %d", res); - } - } - else - { - FSATA_ERROR("format fail %d", res); - return -1; - } - - return 0; -} - -FRESULT FatfsSataListFile(char *path) -{ - FRESULT res; - DIR dir; - UINT i; - static FILINFO fno; - res = f_opendir(&dir,path); /* open dir */ - - if(res == FR_OK) - { - for(;;) /* traversal dir */ - { - res = f_readdir(&dir, &fno); /* read dir */ - if(res != FR_OK || fno.fname[0] == 0) - break; - if(fno.fattrib & AM_DIR) /* if it is dir */ - { - i = strlen(path); /* get length of dir */ - sprintf(&path[i],"/%s",fno.fname); /* append dir */ - printf("is dir::%s\r\n",path); - res = FatfsSataListFile(path); - if(res != FR_OK) break; - path[i] = 0; - } - else - { - printf("is file:%s/%s\r\n",path,fno.fname); /* if it is file */ - } - } - } - else - { - printf("failed - %s\r\n",&res); - } - - f_closedir(&dir); - return res; -} - -static int FatfsSataSetup(const char *mount_point) -{ - FASSERT(mount_point); - FRESULT res; - UINT fnum; - FIL file_handler; - - if (TRUE == fatfs_ok) - { - FSATA_WARN("fatfs initialization already done !!!"); - return 0; - } - - fatfs.pdrv = DEV_MMC; - - res = f_mount(&fatfs, mount_point, 1); - printf("mount fatfs at %s, ret = %d\r\n", mount_point, res); - if (res == FR_NO_FILESYSTEM) - { - if (0 != FatfsSataFormat(mount_point)) - { - return -1; - } - else - { - res = FR_OK; - } - } - else if (res != FR_OK) - { - FSATA_ERROR("file system mount fail %d", res); - return -2; - } - else - { - printf("file system mount ok\r\n"); - } - - if (FR_OK == res) - { - fatfs_ok = TRUE; - (void)FatfsSataListFile(mount_path); - } - - return 0; -} - -int FatfsSataWriteFile(const char *file_name, const char *input_str, boolean create, size_t off) -{ - FASSERT(file_name); - FRESULT res; - UINT fnum; - FIL file_handler; - BYTE temp; - int ret = 0; - - if (FALSE == fatfs_ok) - { - printf("please setup fatfs first !!!\n"); - return -1; - } - - if (create) - res = f_open(&file_handler, file_name, FA_CREATE_ALWAYS | FA_WRITE | FA_READ); - else - res = f_open(&file_handler, file_name, FA_WRITE | FA_READ); - - if (res == FR_OK) - { - f_lseek(&file_handler, off); - - if (NULL == input_str) - { - memset(buff, 0x0, sizeof(buff)); - res = f_write(&file_handler, buff, sizeof(buff), &fnum); - } - else - { - res = f_write(&file_handler, input_str, strlen(input_str) + 1, &fnum); - } - - if (res != FR_OK) - { - printf("write %s fail\n", file_name); - ret = -3; - goto err_handle; - } - } - else - { - printf("f_open %s fail %d\n", file_name, res); - return -4; /* no file handler, directly return */ - } - -err_handle: - getchar(); - res = f_close(&file_handler); - if (FR_OK != res) - { - printf("close file %s failed !!!\n", file_name); - ret = -6; - } - - return ret; -} - -int FatfsSataReadFile(const char *file_name, size_t len) -{ - FASSERT(file_name); - FRESULT res; - UINT fnum; - FIL file_handler; - - if (FALSE == fatfs_ok) - { - printf("please setup fatfs first !!!\n"); - return -1; - } - - if (len > sizeof(buff)) - { - printf("length %d is not support\n", len); - return -2; - } - - res = f_open(&file_handler, file_name, FA_READ); - if (res != FR_OK) - { - printf("open file %s failed !!!\n", file_name); - return -3; - } - - res = f_lseek(&file_handler, 0); - if (res != FR_OK) - { - printf("seek to file begin failed !!!\n"); - return -4; - } - - memset(buff, 0, sizeof(buff)); - res = f_read(&file_handler, buff, len, &fnum); - if (res != FR_OK) - { - printf("read file %s failed !!!\n", file_name); - return -5; - } - else - { - printf("read %s success, str = %s\n\n", file_name, buff); - } - - return 0; -} - -static void FFreeRTOSSataFatfsReadTask(void *pvParameters) -{ - const char *pcTaskName = "FFreeRTOSSataFatfsReadTask is running\r\n"; - const TickType_t xDelay = pdMS_TO_TICKS(TASK_DELAY_MS); - FError ret = FT_SUCCESS; - - xSemaphoreTake(xCountingSemaphore, portMAX_DELAY); - - /* As per most tasks, this task is implemented in an infinite loop. */ - for( ;; ) - { - /* Print out the name of this task. */ - // printf( pcTaskName ); - - FatfsSataReadFile(file_name, FSATA_READ_LEN); - - /* Delay for a period. This time a call to vTaskDelay() is used which - places the task into the Blocked state until the delay period has - expired. The parameter takes a time specified in 'ticks', and the - pdMS_TO_TICKS() macro is used (where the xDelay constant is - declared) to convert TASK_DELAY_MS milliseconds into an equivalent time in - ticks. */ - vTaskDelay(xDelay); - } -} - -static void FFreeRTOSSataFatfsWriteTask(void *pvParameters) -{ - const char *pcTaskName = "FFreeRTOSSataFatfsWriteTask is running\r\n"; - const TickType_t xDelay = pdMS_TO_TICKS(TASK_DELAY_MS); - FError ret = FT_SUCCESS; - const char *string = "write to test.txt."; - char string_out[FSATA_READ_LEN] = {0}; - static int i = 0; - - xSemaphoreTake(xCountingSemaphore, portMAX_DELAY); - - /* As per most tasks, this task is implemented in an infinite loop. */ - for (;;) - { - /* Print out the name of this task. */ - // printf( pcTaskName ); - i++; - sprintf(string_out, "%s-%d", string, i); - printf( "write to %s, str = %s\n", file_name, string_out); - FatfsSataWriteFile(file_name, string_out, FALSE, 0); - - /* Delay for a period. This time a call to vTaskDelay() is used which - places the task into the Blocked state until the delay period has - expired. The parameter takes a time specified in 'ticks', and the - pdMS_TO_TICKS() macro is used (where the xDelay constant is - declared) to convert TASK_DELAY_MS milliseconds into an equivalent time in - ticks. */ - vTaskDelay(xDelay); - } -} - -static void prvOneShotTimerCallback( TimerHandle_t xTimer ) -{ - /* Output a string to show the time at which the callback was executed. */ - vPrintf( "One-shot timer callback executing, delete SataFatfs ReadTask and WriteTask.\r\n" ); - - FFreeRTOSSataFatfsDelete(); -} - -static void FFreeRTOSSataFatfsInitTask(void *pvParameters) -{ - const char *pcTaskName = "FFreeRTOSSataFatfsInitTask is running\r\n"; - const TickType_t xDelay = pdMS_TO_TICKS(TASK_DELAY_MS); - FError ret = FT_SUCCESS; - - const char *string = NULL; - const char *mount_point = "0:/"; - - /* setup sata */ - FatfsSataSetup(mount_point); - - /* create a file*/ - FatfsSataWriteFile(file_name, NULL, TRUE, 0); - - xSemaphoreGive(xCountingSemaphore); - xSemaphoreGive(xCountingSemaphore); - - vTaskDelete(NULL); - -} - -BaseType_t FFreeRTOSSataFatfsCreate(void) -{ - BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为 pdPASS */ - BaseType_t xTimerStarted = pdPASS; - - xCountingSemaphore = xSemaphoreCreateCounting(2, 0); - if (xCountingSemaphore == NULL) - { - printf("FFreeRTOSSataFatfsCreate xCountingSemaphore create failed.\r\n" ); - return pdFAIL; - } - - taskENTER_CRITICAL(); /*进入临界区*/ - - xReturn = xTaskCreate((TaskFunction_t )FFreeRTOSSataFatfsInitTask, /* 任务入口函数 */ - (const char* )"FFreeRTOSSataFatfsInitTask",/* 任务名字 */ - (uint16_t )4096, /* 任务栈大小 */ - (void* )NULL,/* 任务入口函数参数 */ - (UBaseType_t )2, /* 任务的优先级 */ - NULL); /* 任务控制 */ - - xReturn = xTaskCreate((TaskFunction_t )FFreeRTOSSataFatfsReadTask, /* 任务入口函数 */ - (const char* )"FFreeRTOSSataFatfsReadTask",/* 任务名字 */ - (uint16_t )4096, /* 任务栈大小 */ - (void* )NULL,/* 任务入口函数参数 */ - (UBaseType_t )configMAX_PRIORITIES-1, /* 任务的优先级 */ - (TaskHandle_t* )&read_handle); /* 任务控制 */ - - xReturn = xTaskCreate((TaskFunction_t )FFreeRTOSSataFatfsWriteTask, /* 任务入口函数 */ - (const char* )"FFreeRTOSSataFatfsWriteTask",/* 任务名字 */ - (uint16_t )4096, /* 任务栈大小 */ - (void* )NULL,/* 任务入口函数参数 */ - (UBaseType_t )configMAX_PRIORITIES-1, /* 任务的优先级 */ - (TaskHandle_t* )&write_handle); /* 任务控制 */ - - /* Create the one shot software timer, storing the handle to the created - software timer in xOneShotTimer. */ - xOneShotTimer = xTimerCreate( "OneShot Software Timer", /* Text name for the software timer - not used by FreeRTOS. */ - ONE_SHOT_TIMER_PERIOD, /* The software timer's period in ticks. */ - pdFALSE, /* Setting uxAutoRealod to pdFALSE creates a one-shot software timer. */ - 0, /* This example does not use the timer id. */ - prvOneShotTimerCallback ); /* The callback function to be used by the software timer being created. */ - - /* Check the timers were created. */ - if( xOneShotTimer != NULL ) - { - /* Start the software timers, using a block time of 0 (no block time). - The scheduler has not been started yet so any block time specified here - would be ignored anyway. */ - xTimerStarted = xTimerStart( xOneShotTimer, 0 ); - - /* The implementation of xTimerStart() uses the timer command queue, and - xTimerStart() will fail if the timer command queue gets full. The timer - service task does not get created until the scheduler is started, so all - commands sent to the command queue will stay in the queue until after - the scheduler has been started. Check both calls to xTimerStart() - passed. */ - if( xTimerStarted != pdPASS) - { - vPrintf("CreateSoftwareTimerTasks xTimerStart failed \r\n"); - } - } - else - { - vPrintf("CreateSoftwareTimerTasks xTimerCreate failed \r\n"); - } - - taskEXIT_CRITICAL(); - - return xReturn; -} - -static void FFreeRTOSSataFatfsDelete(void) -{ - BaseType_t xReturn = pdPASS; - - if(read_handle) - { - vTaskDelete(read_handle); - vPrintf("Delete FFreeRTOSSataFatfsReadTask success\r\n"); - } - - if(write_handle) - { - vTaskDelete(write_handle); - vPrintf("Delete FFreeRTOSSataFatfsWriteTask success\r\n"); - } - - /* delete count sem */ - vSemaphoreDelete(xCountingSemaphore); - - /* delete timer */ - xReturn = xTimerDelete(xOneShotTimer, 0); - if(xReturn != pdPASS) - { - vPrintf("OneShot Software Timer Delete failed.\r\n"); - } - else - { - vPrintf("OneShot Software Timer Delete success.\r\n"); - } - -} - - - diff --git a/example/storage/spim_spiffs/README.md b/example/storage/spim_spiffs/README.md deleted file mode 100644 index b41445e0..00000000 --- a/example/storage/spim_spiffs/README.md +++ /dev/null @@ -1,135 +0,0 @@ -# SPIFFS SPI Nor-flash 文件系统测试 -## 1. 例程介绍 - ->介绍例程的用途,使用场景,相关基本概念,描述用户可以使用例程完成哪些工作
    - -[SPIFFS](https://github.com/pellepl/spiffs) 是一个面向SPI FLASH的文件系统, 它需要的系统资源极少,可以完全运行在RAM中不需要堆的支持, 有以下几个特点, - -- 1. 面向小型嵌入式系统,不要求系统支持堆和动态内存 -- 2. 尽可能少地进行擦除,只进行大块擦除,清除小块数据时采用标记的方法 -- 3. 支持负载均衡,尽可能延长 Flash 的使用寿命 -- 4. 内置文件系统的一致性检查,对文件系统损坏有一定的保护能力 -- 5. 使用方便,高度可配置 - -但是,SPIFFS 也存在以下几个缺陷, - -- 1. 不支持目录,SPIFFS 提供的是一个平面结构文件系统,路径 `tmp/myfile.txt` 会直接被创建成一个名字为 `tmp/myfile.txt` 的文件 -- 2. 不是实时的,一个写操作的持续时间可能比另一个长得多 -- 3. 支持的 Flash 容量不能超过 128 MB -- 4. 不支持坏块检测和坏块处理 - -本例程通过Freertos下的SPIFFS测试,验证了SPIM Nor-flash文件系统的基本功能,如文件系统格式化,文件的创建、读写、删除和枚举等。例程在E2000 test板上测试通过,使用的Nor Flash介质型号是GD25LQ128E,容量为16MB,如下: -![hardware](./figs/hardware.jpg) - -## 2. 如何使用例程 - ->描述开发平台准备,使用例程配置,构建和下载镜像的过程
    - -### 2.1 硬件配置方法 - ->哪些硬件平台是支持的,需要哪些外设,例程与开发板哪些IO口相关等(建议附录开发板照片,展示哪些IO口被引出)
    - -本例程支持的硬件平台包括 -- E2000D开发板 -- E2000S开发板 - -对应的配置项是 -- CONFIG_TARGET_E2000D - - -- 本例程适配了GD25Q256、GD25Q128、GD25Q64、S25FS256的Nor-Flash芯片,如使用其他型号,需自行参考适配 -### 2.2 SDK配置方法 - ->依赖哪些驱动、库和第三方组件,如何完成配置(列出需要使能的关键配置项)
    - -使能以下配置 - -- CONFIG_USE_SPI,使能SPI驱动组件 -- CONFIG_USE_FSPIM,选择FSPIM驱动 -- CONFIG_USE_IOMUX,使能IO复用驱动组件 -- CONFIG_ENABLE_FIOMUX,选择FIOMUX驱动 -- CONFIG_USE_GPIO,使能GPIO驱动组件 -- CONFIG_ENABLE_F_GPIO,选择FGPIO驱动 -- CONFIG_USE_SFUD,选择SFUD协议框架 -- CONFIG_SFUD_CTRL_F_SPIM,关联SFUD框架和FSPIM驱动 -- CONFIG_USE_SPIFFS CONFIG_SPIFFS_ON_FSPIM_SFUD,使能SPIFFS - -本例子已经提供好具体的编译指令,以下进行介绍: -- make 将目录下的工程进行编译 -- make clean 将目录下的工程进行清理 -- make boot 将目录下的工程进行编译,并将生成的elf 复制到目标地址 -- make load_e2000d_aarch64 将预设64bit e2000d 下的配置加载至工程中 -- make load_e2000d_aarch32 将预设32bit e2000d 下的配置加载至工程中 -- make menuconfig 配置目录下的参数变量 -- make backup_kconfig 将目录下的sdkconfig 备份到./configs下 - -### 2.3 构建和下载 - ->描述构建、烧录下载镜像的过程,列出相关的命令
    - -#### 2.3.1 构建过程 - -- 在host侧完成配置 -配置成e2000d,对于其它平台,使用对应的默认配置,如ft2004 `make load_ft2004_aarch32` - -- 选择目标平台 -``` -make load_e2000d_aarch64 -``` - -- 选择例程需要的配置 -``` -make menuconfig -``` - -- 进行编译 -``` -make -``` - -- 将编译出的镜像放置到tftp目录下 -``` -make boot -``` - -#### 2.3.2 下载过程 - -- host侧设置重启host侧tftp服务器 -``` -sudo service tftpd-hpa restart -``` - -- 开发板侧使用bootelf命令跳转 -``` -setenv ipaddr 192.168.4.20 -setenv serverip 192.168.4.50 -setenv gatewayip 192.168.4.1 -tftpboot 0x90100000 freertos.elf -bootelf -p 0x90100000 -``` - -### 2.4 输出与实验现象 - ->描述输入输出情况,列出存在哪些输出,对应的输出是什么(建议附录相关现象图片)
    -程序启动后,依次创建Init、Read、Write任务,创建单次模式软件定时器用于删除任务,Init任务会首先初始化并挂载spim flash的部分区域(可通过FSPIFFS_IF_FORMAT选择是否进行格式化操作),随后创建一个文件,然后释放信号量通知Read和Write任务开始执行; - -- init完成,挂载文件系统完成,创建测试文件 -![init](./figs/init.png) - -- 读写任务周期性执行,有两个读任务,一个写任务 -![wr](./figs/wr.png) - -- 软件定时器触发,删除读写任务 -![delete](./figs/delete.png) - -## 3. 如何解决问题 - ->主要记录使用例程中可能会遇到的问题,给出相应的解决方案
    - -- FSPIFFS_IF_FORMAT决定初始化阶段是否格式化指定的区域,TRUE为格式化,FLASE为不格式化 - -## 4. 修改历史记录 - ->记录例程的重大修改记录,标明修改发生的版本号
    - -v0.1. 2022-10-27 首次合入 \ No newline at end of file diff --git a/example/storage/spim_spiffs/figs/delete.png b/example/storage/spim_spiffs/figs/delete.png deleted file mode 100644 index fb0d47c2e106319953300b8e2da62e54a44513b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41471 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
    Y1>tAw80FUthB|wCAz^Ig-Y~%XSIJ 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 z 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

    0@_+At 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 diff --git a/example/storage/spim_spiffs/figs/init.png b/example/storage/spim_spiffs/figs/init.png deleted file mode 100644 index 49fe3c33bf239f172ec58ed1cdf05b3631d3ab19..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24680 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 f#N)wYQ9Iy7T>_ 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 diff --git a/example/storage/spim_spiffs/figs/wr.png b/example/storage/spim_spiffs/figs/wr.png deleted file mode 100644 index 05b0cf56ceb81102d5b02ef24238cc6df1b51345..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44533 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 RyC4o1f@}3#a6T=~`2(o`nNt7& diff --git a/example/storage/spim_spiffs/inc/spim_spiffs_example.h b/example/storage/spim_spiffs/inc/spim_spiffs_example.h deleted file mode 100644 index 84826977..00000000 --- a/example/storage/spim_spiffs/inc/spim_spiffs_example.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright : (C) 2022 Phytium Information Technology, Inc. - * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * - * FilePath: spim_spiffs_example.h - * Date: 2022-06-17 10:42:40 - * LastEditTime: 2022-06-17 10:42:40 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- - */ - -#ifndef SPIM_SPIFFS_EXAMPLE_H -#define SPIM_SPIFFS_EXAMPLE_H - -/* spim spiffs read and write test */ -BaseType_t FFreeRTOSSpimSpiffsCreate(u32 spim_id); - -#endif // ! \ No newline at end of file diff --git a/example/storage/spim_spiffs/sdkconfig b/example/storage/spim_spiffs/sdkconfig deleted file mode 100644 index 86833bab..00000000 --- a/example/storage/spim_spiffs/sdkconfig +++ /dev/null @@ -1,236 +0,0 @@ - -# -# Freertos Configuration -# -CONFIG_TARGET_NAME="e2000d_freertos_a64" -# end of Freertos Configuration - -# -# Standalone Setting -# -CONFIG_USE_FREERTOS=y - -# -# Arch Configuration -# -# CONFIG_TARGET_ARMV8_AARCH32 is not set -CONFIG_TARGET_ARMV8_AARCH64=y -CONFIG_USE_CACHE=y -CONFIG_USE_MMU=y -CONFIG_USE_SYS_TICK=y -# CONFIG_MMU_DEBUG_PRINTS is not set -# end of Arch Configuration - -# -# Board Configuration -# -# CONFIG_TARGET_F2000_4 is not set -# CONFIG_TARGET_D2000 is not set -# CONFIG_TARGET_E2000Q is not set -CONFIG_TARGET_E2000D=y -# CONFIG_TARGET_E2000S is not set -CONFIG_TARGET_E2000=y -CONFIG_DEFAULT_DEBUG_PRINT_UART1=y -# CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set -# CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set -# end of Board Configuration - -# -# Components Configuration -# -CONFIG_USE_SPI=y -CONFIG_USE_FSPIM=y -CONFIG_USE_QSPI=y - -# -# Qspi Configuration -# -CONFIG_USE_FQSPI=y -# end of Qspi Configuration - -CONFIG_USE_GIC=y -CONFIG_ENABLE_GICV3=y -CONFIG_USE_SERIAL=y - -# -# Usart Configuration -# -CONFIG_ENABLE_Pl011_UART=y -# end of Usart Configuration - -# CONFIG_USE_GPIO is not set -# CONFIG_USE_ETH is not set -# CONFIG_USE_CAN is not set -# CONFIG_USE_I2C is not set -# CONFIG_USE_TIMER is not set -# CONFIG_USE_MIO is not set -# CONFIG_USE_SDMMC is not set -# CONFIG_USE_PCIE is not set -# CONFIG_USE_WDT is not set -# CONFIG_USE_DMA is not set -# CONFIG_USE_NAND is not set -# CONFIG_USE_RTC is not set -# CONFIG_USE_SATA is not set -# CONFIG_USE_USB is not set -# CONFIG_USE_ADC is not set -# CONFIG_USE_PWM is not set -# CONFIG_USE_IPC is not set -# end of Components Configuration - -CONFIG_USE_NEW_LIBC=y -# end of Standalone Setting - -# -# Building Option -# -# CONFIG_LOG_VERBOS is not set -# CONFIG_LOG_DEBUG is not set -# CONFIG_LOG_INFO is not set -# CONFIG_LOG_WARN is not set -CONFIG_LOG_ERROR=y -# CONFIG_LOG_NONE is not set -CONFIG_USE_DEFAULT_INTERRUPT_CONFIG=y -CONFIG_INTERRUPT_ROLE_MASTER=y -# CONFIG_INTERRUPT_ROLE_SLAVE is not set -# CONFIG_LOG_EXTRA_INFO is not set -# CONFIG_BOOTUP_DEBUG_PRINTS is not set - -# -# Linker Options -# -# CONFIG_AARCH32_RAM_LD is not set -CONFIG_AARCH64_RAM_LD=y -# CONFIG_USER_DEFINED_LD is not set -CONFIG_LINK_SCRIPT_ROM=y -CONFIG_ROM_START_UP_ADDR=0x80100000 -CONFIG_ROM_SIZE_MB=1 -CONFIG_LINK_SCRIPT_RAM=y -CONFIG_RAM_START_UP_ADDR=0x81000000 -CONFIG_RAM_SIZE_MB=64 -CONFIG_HEAP_SIZE=1 -CONFIG_STACK_SIZE=0x100000 -CONFIG_FPU_STACK_SIZE=0x1000 -# end of Linker Options - -# -# Compiler Options -# -CONFIG_OUTPUT_BINARY=y -# end of Compiler Options -# end of Building Option - -# -# Component Configuration -# - -# -# Freertos Uart Drivers -# -CONFIG_FREERTOS_USE_UART=y -# end of Freertos Uart Drivers - -# -# Freertos Pwm Drivers -# -# CONFIG_FREERTOS_USE_PWM is not set -# end of Freertos Pwm Drivers - -# -# Freertos Qspi Drivers -# -CONFIG_FREERTOS_USE_QSPI=y -# end of Freertos Qspi Drivers - -# -# Freertos Wdt Drivers -# -# CONFIG_FREERTOS_USE_WDT is not set -# end of Freertos Wdt Drivers - -# -# Freertos Eth Drivers -# -# CONFIG_FREERTOS_USE_XMAC is not set -# end of Freertos Eth Drivers - -# -# Freertos Gpio Drivers -# -# CONFIG_FREERTOS_USE_GPIO is not set -# end of Freertos Gpio Drivers - -# -# Freertos Spim Drivers -# -CONFIG_FREERTOS_USE_FSPIM=y -# end of Freertos Spim Drivers - -# -# Freertos DMA Drivers -# -# CONFIG_FREERTOS_USE_FDDMA is not set -# CONFIG_FREERTOS_USE_FGDMA is not set -# end of Freertos DMA Drivers - -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - -# -# Freertos Adc Drivers -# -# CONFIG_FREERTOS_USE_ADC is not set -# end of Freertos Adc Drivers - -# -# Freertos Can Drivers -# -# CONFIG_FREERTOS_USE_CAN is not set -# end of Freertos Can Drivers -# end of Component Configuration - -# -# FreeRTOS Setting -# -# CONFIG_USE_LWIP is not set -CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set -CONFIG_USE_SFUD=y - -# -# SFUD Configuration -# -CONFIG_SFUD_CTRL_FSPIM=y -CONFIG_SFUD_CTRL_FQSPI=y -# CONFIG_SFUD_QSPI_READ_MODE_READ is not set -# CONFIG_SFUD_QSPI_READ_MODE_DUAL_READ is not set -CONFIG_SFUD_QSPI_READ_MODE_QUAD_READ=y -# end of SFUD Configuration - -CONFIG_USE_SPIFFS=y - -# -# SPIFFS Configuration -# -CONFIG_SPIFFS_ON_FSPIM_SFUD=y -# CONFIG_SPIFFS_ON_FQSPI_SFUD is not set -# end of SPIFFS Configuration - -# CONFIG_USE_AMP is not set -CONFIG_USE_LETTER_SHELL=y - -# -# Letter Shell Configuration -# -CONFIG_LS_PL011_UART=y -CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y -# CONFIG_DEFAULT_LETTER_SHELL_USE_UART0 is not set -# CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 is not set -# end of Letter Shell Configuration - -CONFIG_USE_TLSF=y -# CONFIG_USE_SDMMC_CMD is not set -# CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting diff --git a/example/storage/spim_spiffs/src/spim_spiffs_example.c b/example/storage/spim_spiffs/src/spim_spiffs_example.c deleted file mode 100644 index b7967934..00000000 --- a/example/storage/spim_spiffs/src/spim_spiffs_example.c +++ /dev/null @@ -1,620 +0,0 @@ -/* - * Copyright : (C) 2022 Phytium Information Technology, Inc. - * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * - * FilePath: spim_spiffs_example.c - * Date: 2022-07-11 11:32:48 - * LastEditTime: 2022-07-11 11:32:48 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- - */ -#include -#include -#include -#include "fkernel.h" -#include "FreeRTOSConfig.h" -#include "FreeRTOS.h" -#include "task.h" -#include "semphr.h" -#include "fpinctrl.h" -#include "timers.h" -#include "spim_spiffs_example.h" -#include "strto.h" -#include "fassert.h" -#include "fdebug.h" -#include "fparameters.h" -#include "spiffs_port.h" -#include "sdkconfig.h" -#ifdef CONFIG_SPIFFS_ON_FSPIM_SFUD -#include "fspim_spiffs_port.h" -#endif - -enum -{ - FSPIFFS_OPS_OK = 0, - FSPIFFS_OPS_INIT_FAILED, - FSPIFFS_OPS_ALREADY_INITED, - FSPIFFS_OPS_MOUNT_FAILED, - FSPIFFS_OPS_FORMAT_FAILED, - FSPIFFS_OPS_NOT_YET_MOUNT, - FSPIFFS_OPS_OPEN_FILE_FAILED, - FSPIFFS_OPS_WRITE_FILE_FAILED, - FSPIFFS_OPS_READ_FILE_FAILED, - FSPIFFS_OPS_REMOVE_FILE_FAILED, - FSPIFFS_OPS_CLOSE_FILE_FAILED, -}; - -#define FSPIFFS_DEBUG_TAG "SPIFFS-SPIM" -#define FSPIFFS_ERROR(format, ...) FT_DEBUG_PRINT_E(FSPIFFS_DEBUG_TAG, format, ##__VA_ARGS__) -#define FSPIFFS_WARN(format, ...) FT_DEBUG_PRINT_W(FSPIFFS_DEBUG_TAG, format, ##__VA_ARGS__) -#define FSPIFFS_INFO(format, ...) FT_DEBUG_PRINT_I(FSPIFFS_DEBUG_TAG, format, ##__VA_ARGS__) -#define FSPIFFS_DEBUG(format, ...) FT_DEBUG_PRINT_D(FSPIFFS_DEBUG_TAG, format, ##__VA_ARGS__) - -/* spiffs start address and size */ -#define FSPIFFS_START_ADDR (0 * SZ_1M) -#define FSPIFFS_USE_SIZE SZ_1M - -#define FSPIFFS_RW_BUF_SIZE 64 - -/* if format flash, TRUE is need format, it tasks some time */ -#define FSPIFFS_IF_FORMAT TRUE - -/* 一个页大小两倍的一个RAM缓冲区, 用来加载和维护SPIFFS的逻辑页 */ -static volatile u8 fspiffs_work_buf[FSPIFFS_LOG_PAGE_SIZE * 2] = {0}; -static volatile u8 fspiffs_fds_buf[32 * 4] = {0}; -static volatile u8 fspiffs_cache_buf[(FSPIFFS_LOG_PAGE_SIZE + 32) * 4] = {0}; -static u8 fspiffs_rw_buf[FSPIFFS_RW_BUF_SIZE] = {0}; -static FSpiffs instance; -static spiffs_config config; -static boolean spiffs_inited = FALSE; -const char *file_name = "test.txt"; - -/************************** Constant Definitions *****************************/ - -/* The periods assigned to the one-shot timers. */ -#define ONE_SHOT_TIMER_PERIOD ( pdMS_TO_TICKS( 50000UL ) ) - -/* write and read task delay in milliseconds */ -#define TASK_DELAY_MS 3000UL - -/* write and read task number */ -#define READ_WRITE_TASK_NUM 3 -static xSemaphoreHandle xCountingSemaphore; - -static xTaskHandle spim_read1_handle; -static xTaskHandle spim_read2_handle; -static xTaskHandle spim_write_handle; -static TimerHandle_t xOneShotTimer; - -static void FFreeRTOSSpimSpiffsDelete(void); - -static int FSpiffsOpsMount(boolean do_format) -{ - int result = 0; - - if (do_format) - { - result = SPIFFS_mount(&instance.fs,/*挂载spiffs系统*/ - &config, - (u8_t *)fspiffs_work_buf, - - (u8_t *)fspiffs_fds_buf, - sizeof(fspiffs_fds_buf), - (u8_t *)fspiffs_cache_buf, - sizeof(fspiffs_cache_buf), - NULL); - - /* try mount to get status of filesystem */ - if ((SPIFFS_OK != result) && (SPIFFS_ERR_NOT_A_FS != result)) - { - /* if not a valid filesystem, continue to format, - other error cannot handle, just exit */ - FSPIFFS_ERROR("mount spiffs failed: %d", result); - return FSPIFFS_OPS_MOUNT_FAILED; - } - - /* must be unmounted prior to formatting */ - SPIFFS_unmount(&instance.fs); - - FSPIFFS_DEBUG("format spiffs in progress ...\r\n"); - result = SPIFFS_format(&instance.fs); - if (SPIFFS_OK != result) - { - FSPIFFS_ERROR("format spiffs failed: %d", result); - return FSPIFFS_OPS_FORMAT_FAILED; - } - } - - /* real mount */ - result = SPIFFS_mount(&instance.fs, - &config, - (u8_t *)fspiffs_work_buf, - (u8_t *)fspiffs_fds_buf, - sizeof(fspiffs_fds_buf), - (u8_t *)fspiffs_cache_buf, - sizeof(fspiffs_cache_buf), - NULL); - if (SPIFFS_OK != result) - { - FSPIFFS_ERROR("remount spiffs failed: %d, you may format the medium first", result); - return FSPIFFS_OPS_MOUNT_FAILED; - } - else - { - vPrintf("mount spiffs success !!! \r\n"); - instance.fs_ready = TRUE; - } - - return FSPIFFS_OPS_OK; -} - -static int FSpiffsOpsListAll(void) -{ - int ret = FSPIFFS_OPS_OK; - int result = SPIFFS_OK; - - if (FALSE == instance.fs_ready) - { - FSPIFFS_ERROR("please mount file system first !!!"); - return FSPIFFS_OPS_NOT_YET_MOUNT; - } - - static spiffs_DIR dir; - static struct spiffs_dirent entry; - - memset(&dir, 0, sizeof(dir)); - memset(&entry, 0, sizeof(entry)); - - struct spiffs_dirent *cur_entry = &entry; - (void)SPIFFS_opendir(&instance.fs, "/", &dir); - - while (NULL != (cur_entry = SPIFFS_readdir(&dir, cur_entry))) - { - printf("-- %s file-id: [0x%04x] page-id: [%d] file-size: %d\r\n", - cur_entry->name, - cur_entry->pix, - cur_entry->obj_id, - cur_entry->size); - } - - (void)SPIFFS_closedir(&dir); - return ret; -} - -int FSpiffsOpsCreateFile(const char *file_name) -{ - FASSERT((file_name) && (strlen(file_name) > 0)); - if (FALSE == instance.fs_ready) - { - FSPIFFS_ERROR("please mount file system first !!!"); - return FSPIFFS_OPS_NOT_YET_MOUNT; - } - - int ret = FSPIFFS_OPS_OK; - - /* create file */ - s32_t result = SPIFFS_creat(&instance.fs, file_name, 0); - if (result < 0) - { - FSPIFFS_ERROR("failed to create file %s", file_name); - return FSPIFFS_OPS_OPEN_FILE_FAILED; - } - - /* open file */ - spiffs_file fd = SPIFFS_open(&instance.fs, file_name, SPIFFS_RDONLY, 0); - if (0 > fd) - { - FSPIFFS_ERROR("failed to open file %s errno %d", file_name, SPIFFS_errno(&instance.fs)); - return FSPIFFS_OPS_OPEN_FILE_FAILED; - } - - /* check file status */ - static spiffs_stat status; - memset(&status, 0, sizeof(status)); - result = SPIFFS_fstat(&instance.fs, fd, &status); - if (result < 0) - { - FSPIFFS_ERROR("failed to get status of file %s errno %d", file_name, SPIFFS_errno(&instance.fs)); - ret = FSPIFFS_OPS_OPEN_FILE_FAILED; - goto err_exit; - } - - if (0 != strcmp(status.name, file_name)) - { - FSPIFFS_ERROR("created file name %s != %s", status.name, file_name); - ret = FSPIFFS_OPS_OPEN_FILE_FAILED; - goto err_exit; - } - - if (0 != status.size) - { - FSPIFFS_ERROR("invalid file size %d", status.size); - ret = FSPIFFS_OPS_OPEN_FILE_FAILED; - goto err_exit; - } - - vPrintf("create file %s success !!!\r\n", file_name); - -err_exit: - (void)SPIFFS_close(&instance.fs, fd); - return ret; -} - -int FSpiffsOpsWriteFile(const char *file_name, const char *str) -{ - FASSERT((file_name) && (strlen(file_name) > 0)); - FASSERT(str); - int ret = FSPIFFS_OPS_OK; - const u32 wr_len = strlen(str) + 1; - - spiffs_file fd = SPIFFS_open(&instance.fs, file_name, SPIFFS_RDWR | SPIFFS_TRUNC, 0); - if (0 > fd) - { - FSPIFFS_ERROR("failed to open file %s errno %d", file_name, SPIFFS_errno(&instance.fs)); - return FSPIFFS_OPS_OPEN_FILE_FAILED; - } - - int result = SPIFFS_write(&instance.fs, fd, (void *)str, wr_len); - if (result < 0) - { - FSPIFFS_ERROR("failed to write file %s errno %d", file_name, SPIFFS_errno(&instance.fs)); - ret = FSPIFFS_OPS_WRITE_FILE_FAILED; - goto err_exit; - } - - /* check file status */ - static spiffs_stat status; - memset(&status, 0, sizeof(status)); - result = SPIFFS_fstat(&instance.fs, fd, &status); - if (result < 0) - { - FSPIFFS_ERROR("failed to get status of file %s errno %d", file_name, SPIFFS_errno(&instance.fs)); - ret = FSPIFFS_OPS_WRITE_FILE_FAILED; - goto err_exit; - } - - if (status.size != wr_len) - { - FSPIFFS_ERROR("file write size %ld != %ld", status.size, wr_len); - ret = FSPIFFS_OPS_WRITE_FILE_FAILED; - goto err_exit; - } - - /* flush all pending writes from cache to flash */ - (void)SPIFFS_fflush(&instance.fs, fd); - vPrintf("write file %s with %d bytes success !!!\r\n", file_name, wr_len); -err_exit: - (void)SPIFFS_close(&instance.fs, fd); - return ret; -} - -int FSpiffsOpsReadFile(const char *file_name) -{ - FASSERT((file_name) && (strlen(file_name) > 0)); - int ret = FSPIFFS_OPS_OK; - int result = SPIFFS_OK; - - if (FALSE == instance.fs_ready) - { - FSPIFFS_ERROR("please mount file system first !!!"); - return FSPIFFS_OPS_NOT_YET_MOUNT; - } - - /* check file status */ - static spiffs_stat status; - - spiffs_flags open_flags = 0; - - /* open the file in read-only mode */ - open_flags = SPIFFS_RDWR; - spiffs_file fd = SPIFFS_open(&instance.fs, file_name, open_flags, 0); - if (0 > fd) - { - FSPIFFS_ERROR("failed to open file %s errno %d", file_name, SPIFFS_errno(&instance.fs)); - return FSPIFFS_OPS_OPEN_FILE_FAILED; - } - - /* check file status */ - memset(&status, 0, sizeof(status)); - result = SPIFFS_fstat(&instance.fs, fd, &status); - if (result < 0) - { - FSPIFFS_ERROR("failed to get status of file %s errno %d", file_name, SPIFFS_errno(&instance.fs)); - ret = FSPIFFS_OPS_OPEN_FILE_FAILED; - goto err_exit; - } - - s32_t offset = SPIFFS_lseek(&instance.fs, fd, 0, SPIFFS_SEEK_END); - if ((s32_t)status.size != offset) - { - FSPIFFS_ERROR("file %s spiffs:%ld! = fs:%ld", file_name, status.size, offset); - ret = FSPIFFS_OPS_OPEN_FILE_FAILED; - goto err_exit; - } - - memset(fspiffs_rw_buf, 0 , FSPIFFS_RW_BUF_SIZE); - - /* seek to offset and start read */ - if (0 > SPIFFS_lseek(&instance.fs, fd, 0, SPIFFS_SEEK_SET)) - { - FSPIFFS_ERROR("seek file failed !!!"); - ret = FSPIFFS_OPS_READ_FILE_FAILED; - goto err_exit; - } - - /*vPrintf("read %s from position %ld\n", file_name, SPIFFS_tell(&instance.fs, fd));*/ - - s32_t read_len = min((s32_t)FSPIFFS_RW_BUF_SIZE, (s32_t)status.size); - s32_t read_bytes = SPIFFS_read(&instance.fs, fd, (void *)fspiffs_rw_buf, read_len); - if (read_bytes < 0) - { - FSPIFFS_ERROR("failed to read file %s errno %d", file_name, SPIFFS_errno(&instance.fs)); - ret = FSPIFFS_OPS_READ_FILE_FAILED; - goto err_exit; - } - - vPrintf("read %s success, str = %s\n\n", file_name, fspiffs_rw_buf); - -err_exit : - /* close file */ - (void)SPIFFS_close(&instance.fs, fd); - - return ret; -} - - -static void FFreeRTOSSpimSpiffsInitTask(void *pvParameters) -{ - int result = 0; - - if (TRUE == spiffs_inited) - { - FSPIFFS_WARN("spiffs is already initialized"); - return; - } - - /* The spim_id to use is passed in via the parameter. - Cast this to a spim_id pointer. */ - u32 spim_id = (u32)(uintptr)pvParameters; - printf("spim_id: %d\n", spim_id); - - memset(&config, 0, sizeof(config)); - config = *FSpiffsGetDefaultConfig(); - config.phys_addr = FSPIFFS_START_ADDR; /* may use part of flash */ - config.phys_size = FSPIFFS_USE_SIZE; - - memset(&instance, 0, sizeof(instance)); - instance.fs_addr = FSPIFFS_START_ADDR; - instance.fs_size = FSPIFFS_USE_SIZE; - - result = FSpiffsInitialize(&instance, FSPIFFS_PORT_TO_FSPIM); - if (FSPIFFS_PORT_OK != result) - { - FSPIFFS_ERROR("initialize spiffs failed"); - return; - } - - FSpiffsOpsMount(FSPIFFS_IF_FORMAT); - - FSpiffsOpsCreateFile(file_name); - - spiffs_inited = TRUE; - - FSpiffsOpsListAll(); - - FSPIFFS_INFO("spiffs init success !!!\r\n"); - - for (int i = 0; i < READ_WRITE_TASK_NUM; i++) - { - xSemaphoreGive(xCountingSemaphore); - } - - vTaskDelete(NULL); - -} - - -static void FFreeRTOSSpimSpiffsReadTask(void *pvParameters) -{ - const char *pcTaskName = (char *) pvParameters; - const TickType_t xDelay = pdMS_TO_TICKS(TASK_DELAY_MS); - FError ret = FT_SUCCESS; - - xSemaphoreTake(xCountingSemaphore, portMAX_DELAY); - - /* As per most tasks, this task is implemented in an infinite loop. */ - for( ;; ) - { - /* Print out the name of this task. */ - vPrintf( pcTaskName ); - - FSpiffsOpsReadFile(file_name); - - /* Delay for a period. This time a call to vTaskDelay() is used which - places the task into the Blocked state until the delay period has - expired. The parameter takes a time specified in 'ticks', and the - pdMS_TO_TICKS() macro is used (where the xDelay constant is - declared) to convert TASK_DELAY_MS milliseconds into an equivalent time in - ticks. */ - vTaskDelay(xDelay); - } -} - - -static void FFreeRTOSSpimSpiffsWriteTask(void *pvParameters) -{ - const char *pcTaskName = "FFreeRTOSSpimSpiffsWriteTask is running\r\n"; - const TickType_t xDelay = pdMS_TO_TICKS(TASK_DELAY_MS); - FError ret = FT_SUCCESS; - char *string = "spiffs spim write"; - static char string_out[FSPIFFS_RW_BUF_SIZE] = {0}; - - static int i = 0; - - xSemaphoreTake(xCountingSemaphore, portMAX_DELAY); - - /* As per most tasks, this task is implemented in an infinite loop. */ - for (;;) - { - /* Print out the name of this task. */ - vPrintf( pcTaskName ); - i++; - sprintf(string_out, "%s-%d", string, i); - vPrintf( "write to %s, str = %s\n", file_name, string_out); - FSpiffsOpsWriteFile(file_name, string_out); - - /* Delay for a period. This time a call to vTaskDelay() is used which - places the task into the Blocked state until the delay period has - expired. The parameter takes a time specified in 'ticks', and the - pdMS_TO_TICKS() macro is used (where the xDelay constant is - declared) to convert TASK_DELAY_MS milliseconds into an equivalent time in - ticks. */ - vTaskDelay(xDelay); - } -} - -static void prvOneShotTimerCallback( TimerHandle_t xTimer ) -{ - /* Output a string to show the time at which the callback was executed. */ - vPrintf( "One-shot timer callback executing, delete SpimSpiffs ReadTask and WriteTask.\r\n" ); - - FFreeRTOSSpimSpiffsDelete(); -} - - -BaseType_t FFreeRTOSSpimSpiffsCreate(u32 spim_id)/* 主要任务函数 */ -{ - BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为 pdPASS */ - BaseType_t xTimerStarted = pdPASS; - - xCountingSemaphore = xSemaphoreCreateCounting(READ_WRITE_TASK_NUM, 0); - if (xCountingSemaphore == NULL) - { - printf("FFreeRTOSSpimSpiffsCreate xCountingSemaphore create failed.\r\n" ); - return pdFAIL; - } - - char *xString1 = "FFreeRTOSSpimSpiffsReadTask1 is running\r\n"; - char *xString2 = "FFreeRTOSSpimSpiffsReadTask2 is running\r\n"; - - taskENTER_CRITICAL(); /* 进入临界区 */ - - xReturn = xTaskCreate((TaskFunction_t )FFreeRTOSSpimSpiffsInitTask, /* 任务入口函数 */ - (const char* )"FFreeRTOSSpimSpiffsInitTask",/* 任务名字 */ - (uint16_t )4096, /* 任务栈大小 */ - (void* )(uintptr)spim_id,/* 任务入口函数参数 */ - (UBaseType_t )1, /* 任务的优先级 */ - NULL); /* 任务控制 */ - - xReturn = xTaskCreate((TaskFunction_t )FFreeRTOSSpimSpiffsReadTask, /* 任务入口函数 */ - (const char* )"FFreeRTOSSpimSpiffsReadTask",/* 任务名字 */ - (uint16_t )4096, /* 任务栈大小 */ - (void* )xString1,/* 任务入口函数参数 */ - (UBaseType_t )configMAX_PRIORITIES-1, /* 任务的优先级 */ - (TaskHandle_t* )&spim_read1_handle); /* 任务控制 */ - - xReturn = xTaskCreate((TaskFunction_t )FFreeRTOSSpimSpiffsReadTask, /* 任务入口函数 */ - (const char* )"FFreeRTOSSpimSpiffsReadTask",/* 任务名字 */ - (uint16_t )4096, /* 任务栈大小 */ - (void* )xString2,/* 任务入口函数参数 */ - (UBaseType_t )configMAX_PRIORITIES-1, /* 任务的优先级 */ - (TaskHandle_t* )&spim_read2_handle); /* 任务控制 */ - - xReturn = xTaskCreate((TaskFunction_t )FFreeRTOSSpimSpiffsWriteTask, /* 任务入口函数 */ - (const char* )"FFreeRTOSSpimSpiffsWriteTask",/* 任务名字 */ - (uint16_t )4096, /* 任务栈大小 */ - (void* )NULL,/* 任务入口函数参数 */ - (UBaseType_t )configMAX_PRIORITIES-1, /* 任务的优先级 */ - (TaskHandle_t* )&spim_write_handle); /* 任务控制 */ - - /* Create the one shot software timer, storing the handle to the created - software timer in xOneShotTimer. */ - xOneShotTimer = xTimerCreate( "OneShot Software Timer", /* Text name for the software timer - not used by FreeRTOS. */ - ONE_SHOT_TIMER_PERIOD, /* The software timer's period in ticks. */ - pdFALSE, /* Setting uxAutoRealod to pdFALSE creates a one-shot software timer. */ - 0, /* This example does not use the timer id. */ - prvOneShotTimerCallback ); /* The callback function to be used by the software timer being created. */ - - /* Check the timers were created. */ - if( xOneShotTimer != NULL ) - { - /* Start the software timers, using a block time of 0 (no block time). - The scheduler has not been started yet so any block time specified here - would be ignored anyway. */ - xTimerStarted = xTimerStart( xOneShotTimer, 0 ); - - /* The implementation of xTimerStart() uses the timer command queue, and - xTimerStart() will fail if the timer command queue gets full. The timer - service task does not get created until the scheduler is started, so all - commands sent to the command queue will stay in the queue until after - the scheduler has been started. Check both calls to xTimerStart() - passed. */ - if( xTimerStarted != pdPASS) - { - vPrintf("CreateSoftwareTimerTasks xTimerStart failed \r\n"); - } - } - else - { - vPrintf("CreateSoftwareTimerTasks xTimerCreate failed \r\n"); - } - - taskEXIT_CRITICAL(); - - return xReturn; -} - -static void FFreeRTOSSpimSpiffsDelete(void) -{ - BaseType_t xReturn = pdPASS; - - FSpiffsDeInitialize(&instance); - - if(spim_read1_handle) - { - vTaskDelete(spim_read1_handle); - vPrintf("Delete FFreeRTOSSpimSpiffsReadTask1 success\r\n"); - } - - if(spim_read2_handle) - { - vTaskDelete(spim_read2_handle); - vPrintf("Delete FFreeRTOSSpimSpiffsReadTask2 success\r\n"); - } - - if(spim_write_handle) - { - vTaskDelete(spim_write_handle); - vPrintf("Delete FFreeRTOSSpimSpiffsWriteTask success\r\n"); - } - - /* delete count sem */ - vSemaphoreDelete(xCountingSemaphore); - - /* delete timer */ - xReturn = xTimerDelete(xOneShotTimer, 0); - if(xReturn != pdPASS) - { - vPrintf("OneShot Software Timer Delete failed.\r\n"); - } - else - { - vPrintf("OneShot Software Timer Delete success.\r\n"); - } - -} - - - diff --git a/example/template/READEME.md b/example/template/README.md similarity index 99% rename from example/template/READEME.md rename to example/template/README.md index 08cab5c6..de741af5 100644 --- a/example/template/READEME.md +++ b/example/template/README.md @@ -11,7 +11,7 @@ * See the Phytium Public License for more details. * * - * FilePath: READEME.md + * FilePath: README.md * Date: 2022-02-24 13:42:19 * LastEditTime: 2022-03-21 17:02:58 * Description:  This file is for diff --git a/example/template/configs/d2000_aarch32_eg_configs b/example/template/configs/d2000_aarch32_eg_configs index f75409dd..db43ff18 100644 --- a/example/template/configs/d2000_aarch32_eg_configs +++ b/example/template/configs/d2000_aarch32_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -111,6 +112,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + # CONFIG_OUTPUT_BINARY is not set # end of Compiler Options # end of Building Option @@ -147,6 +157,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -168,12 +179,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -185,14 +190,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -210,4 +233,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/template/configs/d2000_aarch64_eg_configs b/example/template/configs/d2000_aarch64_eg_configs index 8479669d..0476ac57 100644 --- a/example/template/configs/d2000_aarch64_eg_configs +++ b/example/template/configs/d2000_aarch64_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + # CONFIG_OUTPUT_BINARY is not set # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/template/configs/e2000d_aarch32_eg_configs b/example/template/configs/e2000d_aarch32_eg_configs index 2bd43e71..93bbaf57 100644 --- a/example/template/configs/e2000d_aarch32_eg_configs +++ b/example/template/configs/e2000d_aarch32_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -111,6 +112,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -147,6 +157,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -168,12 +179,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -185,14 +190,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -210,4 +233,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/template/configs/e2000d_aarch64_eg_configs b/example/template/configs/e2000d_aarch64_eg_configs index b8c6027e..2038c875 100644 --- a/example/template/configs/e2000d_aarch64_eg_configs +++ b/example/template/configs/e2000d_aarch64_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/template/configs/e2000q_aarch32_eg_configs b/example/template/configs/e2000q_aarch32_eg_configs index 57c04828..504364d5 100644 --- a/example/template/configs/e2000q_aarch32_eg_configs +++ b/example/template/configs/e2000q_aarch32_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -111,6 +112,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -147,6 +157,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -168,12 +179,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -185,14 +190,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -210,4 +233,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/template/configs/e2000q_aarch64_eg_configs b/example/template/configs/e2000q_aarch64_eg_configs index 205bf7fd..dcf9e9eb 100644 --- a/example/template/configs/e2000q_aarch64_eg_configs +++ b/example/template/configs/e2000q_aarch64_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/template/configs/ft2004_aarch32_eg_configs b/example/template/configs/ft2004_aarch32_eg_configs index 77be645a..57be672b 100644 --- a/example/template/configs/ft2004_aarch32_eg_configs +++ b/example/template/configs/ft2004_aarch32_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -111,6 +112,15 @@ CONFIG_UNDEF_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + # CONFIG_OUTPUT_BINARY is not set # end of Compiler Options # end of Building Option @@ -147,6 +157,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -168,12 +179,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -185,14 +190,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -210,4 +233,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/template/configs/ft2004_aarch64_eg_configs b/example/template/configs/ft2004_aarch64_eg_configs index b095059c..bcb9a56d 100644 --- a/example/template/configs/ft2004_aarch64_eg_configs +++ b/example/template/configs/ft2004_aarch64_eg_configs @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + # CONFIG_OUTPUT_BINARY is not set # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/template/main.c b/example/template/main.c index b157fbf0..6c611a23 100644 --- a/example/template/main.c +++ b/example/template/main.c @@ -1,125 +1,50 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: main.c * Date: 2022-02-24 13:42:19 * LastEditTime: 2022-03-21 17:02:53 - * Description:  This file is for - * - * Modify History: - * Ver   Who        Date         Changes - * ----- ------     --------    -------------------------------------- + * Description:  This file is for providing a template main.c file when creating new freertos examples. + * + * Modify History: + * Ver   Who         Date         Changes + * ----- ------      --------    -------------------------------------- + * 1.0 wangxiaodong 2022/11/1 init commit */ - - #include #include #include "FreeRTOS.h" #include "task.h" -#include "queue.h" #include "ftypes.h" -#include "fassert.h" -#include "fgeneric_timer.h" -#include "finterrupt.h" -#include "fparameters.h" #include "shell.h" #include "shell_port.h" -static TaskHandle_t cpuStatsTaskHandle = NULL; -static uint8_t CPU_RunInfo[800] = {0}; //保存任务运行时间信息 - -static void CpuStatsTask(void* parameter) -{ - while (1) - { - memset(CPU_RunInfo,0,800); //信息缓冲区清零 - vTaskList((char *)&CPU_RunInfo); //获取任务运行时间信息 - - printf("---------------------------------------------\r\n"); - printf("task_name task_state priority stack task_num\r\n"); - printf("%s", CPU_RunInfo); - printf("---------------------------------------------\r\n"); - - memset(CPU_RunInfo, 0, 800); //信息缓冲区清零 - vTaskGetRunTimeStats((char *)&CPU_RunInfo); - - printf("task_name\trun_time_count\tusage_rate\r\n"); - printf("%s", CPU_RunInfo); - printf("---------------------------------------------\r\n\n"); - vTaskDelay(5000); /* 延时 */ - } -} - -static TaskHandle_t appTaskCreateHandle = NULL; - -static void AppTaskCreate(void) -{ - BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为 pdPASS */ - - printf("create AppTaskCreate!\r\n"); - taskENTER_CRITICAL(); //进入临界区 - /* 创建 CPU stats 任务 */ - xReturn = xTaskCreate((TaskFunction_t )CpuStatsTask, /* 任务入口函数 */ - (const char* )"CPU_STATS_Task",/* 任务名字 */ - (uint16_t )512, /* 任务栈大小 */ - (void* )NULL, /* 任务入口函数参数 */ - (UBaseType_t )4, /* 任务的优先级 */ - (TaskHandle_t* )&cpuStatsTaskHandle);/* 任务控制块指针 */ - - if (pdPASS == xReturn) - { - printf("create cpu stats task success!\r\n"); - } - - vTaskDelete(appTaskCreateHandle); //删除 AppTaskCreate 任务 - - taskEXIT_CRITICAL(); //退出临界区 -} - -BaseType_t TestFreeRTOSEntry() -{ - BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为 pdPASS */ - - printf("get cpu stats TestCpuStatsEntry\r\n"); - xReturn = xTaskCreate((TaskFunction_t )AppTaskCreate, /* 任务入口函数 */ - (const char* )"AppTaskCreate",/* 任务名字 */ - (uint16_t )512, /* 任务栈大小 */ - (void* )NULL,/* 任务入口函数参数 */ - (UBaseType_t )1, /* 任务的优先级 */ - (TaskHandle_t* )&appTaskCreateHandle); /* 任务控制 */ - - return xReturn; -} - int main() { - printf("main hello ft Date: %s, Time: %s\n", __DATE__, __TIME__); + printf("Hello main func,FT Date: %s, Time: %s\n", __DATE__, __TIME__); BaseType_t xReturn = pdPASS; - /* 创建 CPU stats 任务 */ - xReturn = TestFreeRTOSEntry(); - if(xReturn != pdPASS) - goto FAIL_EXIT; - - xReturn = LSUserShellTask() ; - if(xReturn != pdPASS) + xReturn = LSUserShellTask(); + if (xReturn != pdPASS) + { goto FAIL_EXIT; + } - vTaskStartScheduler(); /* 启动任务,开启调度 */ + vTaskStartScheduler(); /* 启动任务,开启调度 */ while (1); /* 正常不会执行到这里 */ FAIL_EXIT: - printf("failed 0x%x \r\n", xReturn); + printf("Failed,the xReturn value is 0x%x. \r\n", xReturn); return 0; } \ No newline at end of file diff --git a/example/template/sdkconfig b/example/template/sdkconfig index b8c6027e..dcf9e9eb 100644 --- a/example/template/sdkconfig +++ b/example/template/sdkconfig @@ -26,8 +26,8 @@ CONFIG_USE_MMU=y # # CONFIG_TARGET_F2000_4 is not set # CONFIG_TARGET_D2000 is not set -# CONFIG_TARGET_E2000Q is not set -CONFIG_TARGET_E2000D=y +CONFIG_TARGET_E2000Q=y +# CONFIG_TARGET_E2000D is not set # CONFIG_TARGET_E2000S is not set CONFIG_TARGET_E2000=y CONFIG_DEFAULT_DEBUG_PRINT_UART1=y @@ -67,6 +67,7 @@ CONFIG_ENABLE_Pl011_UART=y # CONFIG_USE_ADC is not set # CONFIG_USE_PWM is not set # CONFIG_USE_IPC is not set +# CONFIG_USE_MEDIA is not set # end of Components Configuration CONFIG_USE_NEW_LIBC=y @@ -107,6 +108,15 @@ CONFIG_FPU_STACK_SIZE=0x1000 # # Compiler Options # + +# +# Cross-Compiler Setting +# +CONFIG_GCC_OPTIMIZE_LEVEL=0 +# CONFIG_USE_EXT_COMPILER is not set +# CONFIG_USE_KLIN_SYS is not set +# end of Cross-Compiler Setting + CONFIG_OUTPUT_BINARY=y # end of Compiler Options # end of Building Option @@ -143,6 +153,7 @@ CONFIG_FREERTOS_USE_UART=y # Freertos Eth Drivers # # CONFIG_FREERTOS_USE_XMAC is not set +# CONFIG_FREERTOS_USE_GMAC is not set # end of Freertos Eth Drivers # @@ -164,12 +175,6 @@ CONFIG_FREERTOS_USE_UART=y # CONFIG_FREERTOS_USE_FGDMA is not set # end of Freertos DMA Drivers -# -# Freertos MMC Drivers -# -# CONFIG_FREERTOS_USE_FSDIO is not set -# end of Freertos MMC Drivers - # # Freertos Adc Drivers # @@ -181,14 +186,32 @@ CONFIG_FREERTOS_USE_UART=y # # CONFIG_FREERTOS_USE_CAN is not set # end of Freertos Can Drivers + +# +# Freertos I2c Drivers +# +# CONFIG_FREERTOS_USE_I2C is not set +# end of Freertos I2c Drivers + +# +# Freertos Mio Drivers +# +# CONFIG_FREERTOS_USE_MIO is not set +# end of Freertos Mio Drivers + +# +# Freertos Timer Drivers +# +# CONFIG_FREERTOS_USE_TIMER is not set +# end of Freertos Timer Drivers # end of Component Configuration # -# FreeRTOS Setting +# Third-Party Configuration # # CONFIG_USE_LWIP is not set CONFIG_USE_BACKTRACE=y -# CONFIG_USE_FATFS is not set +# CONFIG_USE_FATFS_0_1_4 is not set # CONFIG_USE_SFUD is not set # CONFIG_USE_SPIFFS is not set # CONFIG_USE_AMP is not set @@ -206,4 +229,27 @@ CONFIG_DEFAULT_LETTER_SHELL_USE_UART1=y CONFIG_USE_TLSF=y # CONFIG_USE_SDMMC_CMD is not set # CONFIG_USE_CHERRY_USB is not set -# end of FreeRTOS Setting +# end of Third-Party Configuration + +# +# Kernel Configuration +# +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_MAX_PRIORITIES=32 +CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES=13 +CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES=11 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE=1024 +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=32 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_USE_TRACE_FACILITY=y +CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y +# CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set +CONFIG_FREERTOS_TOTAL_HEAP_SIZE=10240 +CONFIG_FREERTOS_TASK_FPU_SUPPORT=1 +# end of Kernel Configuration diff --git a/example/template/sdkconfig.h b/example/template/sdkconfig.h index 3690ee18..bf6c6b65 100644 --- a/example/template/sdkconfig.h +++ b/example/template/sdkconfig.h @@ -24,8 +24,8 @@ /* CONFIG_TARGET_F2000_4 is not set */ /* CONFIG_TARGET_D2000 is not set */ -/* CONFIG_TARGET_E2000Q is not set */ -#define CONFIG_TARGET_E2000D +#define CONFIG_TARGET_E2000Q +/* CONFIG_TARGET_E2000D is not set */ /* CONFIG_TARGET_E2000S is not set */ #define CONFIG_TARGET_E2000 #define CONFIG_DEFAULT_DEBUG_PRINT_UART1 @@ -62,6 +62,7 @@ /* CONFIG_USE_ADC is not set */ /* CONFIG_USE_PWM is not set */ /* CONFIG_USE_IPC is not set */ +/* CONFIG_USE_MEDIA is not set */ /* end of Components Configuration */ #define CONFIG_USE_NEW_LIBC /* end of Standalone Setting */ @@ -98,6 +99,12 @@ /* Compiler Options */ +/* Cross-Compiler Setting */ + +#define CONFIG_GCC_OPTIMIZE_LEVEL 0 +/* CONFIG_USE_EXT_COMPILER is not set */ +/* CONFIG_USE_KLIN_SYS is not set */ +/* end of Cross-Compiler Setting */ #define CONFIG_OUTPUT_BINARY /* end of Compiler Options */ /* end of Building Option */ @@ -127,6 +134,7 @@ /* Freertos Eth Drivers */ /* CONFIG_FREERTOS_USE_XMAC is not set */ +/* CONFIG_FREERTOS_USE_GMAC is not set */ /* end of Freertos Eth Drivers */ /* Freertos Gpio Drivers */ @@ -145,11 +153,6 @@ /* CONFIG_FREERTOS_USE_FGDMA is not set */ /* end of Freertos DMA Drivers */ -/* Freertos MMC Drivers */ - -/* CONFIG_FREERTOS_USE_FSDIO is not set */ -/* end of Freertos MMC Drivers */ - /* Freertos Adc Drivers */ /* CONFIG_FREERTOS_USE_ADC is not set */ @@ -159,13 +162,28 @@ /* CONFIG_FREERTOS_USE_CAN is not set */ /* end of Freertos Can Drivers */ + +/* Freertos I2c Drivers */ + +/* CONFIG_FREERTOS_USE_I2C is not set */ +/* end of Freertos I2c Drivers */ + +/* Freertos Mio Drivers */ + +/* CONFIG_FREERTOS_USE_MIO is not set */ +/* end of Freertos Mio Drivers */ + +/* Freertos Timer Drivers */ + +/* CONFIG_FREERTOS_USE_TIMER is not set */ +/* end of Freertos Timer Drivers */ /* end of Component Configuration */ -/* FreeRTOS Setting */ +/* Third-Party Configuration */ /* CONFIG_USE_LWIP is not set */ #define CONFIG_USE_BACKTRACE -/* CONFIG_USE_FATFS is not set */ +/* CONFIG_USE_FATFS_0_1_4 is not set */ /* CONFIG_USE_SFUD is not set */ /* CONFIG_USE_SPIFFS is not set */ /* CONFIG_USE_AMP is not set */ @@ -181,6 +199,28 @@ #define CONFIG_USE_TLSF /* CONFIG_USE_SDMMC_CMD is not set */ /* CONFIG_USE_CHERRY_USB is not set */ -/* end of FreeRTOS Setting */ +/* end of Third-Party Configuration */ + +/* Kernel Configuration */ + +#define CONFIG_FREERTOS_OPTIMIZED_SCHEDULER +#define CONFIG_FREERTOS_HZ 1000 +#define CONFIG_FREERTOS_MAX_PRIORITIES 32 +#define CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES 13 +#define CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES 11 +#define CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS 1 +#define CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE 1024 +#define CONFIG_FREERTOS_MAX_TASK_NAME_LEN 32 +#define CONFIG_FREERTOS_TIMER_TASK_PRIORITY 1 +#define CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH 2048 +#define CONFIG_FREERTOS_TIMER_QUEUE_LENGTH 10 +#define CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE 0 +#define CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS +#define CONFIG_FREERTOS_USE_TRACE_FACILITY +#define CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS +/* CONFIG_FREERTOS_USE_TICKLESS_IDLE is not set */ +#define CONFIG_FREERTOS_TOTAL_HEAP_SIZE 10240 +#define CONFIG_FREERTOS_TASK_FPU_SUPPORT 1 +/* end of Kernel Configuration */ #endif diff --git a/install.py b/install.py index aa2b9064..0a96337c 100644 --- a/install.py +++ b/install.py @@ -86,7 +86,7 @@ os.system("chmod +x ./make/*.mk --silent ") os.system("chmod +x ./lib/Kconfiglib/*.py --silent ") # Add standalone sdk -standalone_sdk_v="0.4.0" +standalone_sdk_v="v1.0.0" standalone_path=freertos_sdk_path + '/standalone' standalone_branche="release" standalone_remote="https://gitee.com/phytium_embedded/phytium-standalone-sdk.git" @@ -105,10 +105,16 @@ if not os.path.exists(standalone_path): os.system("echo \"standalone.mk\" >> {}".format(r'.git/info/sparse-checkout')) os.system("echo \"lib/*\" >> {}".format(r'.git/info/sparse-checkout')) os.system("echo \"doc/*\" >> {}".format(r'.git/info/sparse-checkout')) - + os.system("echo \"third-party/fatfs-0.1.4/*\" >> {}".format(r'.git/info/sparse-checkout')) + os.system("echo \"third-party/sdmmc/*\" >> {}".format(r'.git/info/sparse-checkout')) + os.system("echo \"third-party/lwip-2.1.2/*\" >> {}".format(r'.git/info/sparse-checkout')) + + os.system("git checkout {}".format(standalone_sdk_v)) print('[1]: Standalone sdk download is succeed') os.chdir(current_path) # 切换回当前路径 + lwip_port_arch_path=standalone_path + '/third-party/lwip-2.1.2/ports/arch' + shutil.rmtree(lwip_port_arch_path) else: print('[1]: Standalone sdk is exist') pass diff --git a/make/Kconfig b/make/Kconfig index 69db4668..631b56ae 100644 --- a/make/Kconfig +++ b/make/Kconfig @@ -1,6 +1,30 @@ menu "Compiler Options" + +menu "Cross-Compiler Setting" + + config GCC_OPTIMIZE_LEVEL + int "Set Optimize Level" + default 0 + help + Set Optimize level for GCC + + config USE_EXT_COMPILER + bool "Use User-Specified Compiler" + default n + + config USE_KLIN_SYS + bool "Use Klin system" + default n + + config EXT_COMPILER_PREFIX + depends on USE_EXT_COMPILER + string "" + default "arm-none-eabi-" if TARGET_ARMV8_AARCH32 + default "aarch64-none-elf-" if TARGET_ARMV8_AARCH64 +endmenu + config OUTPUT_BINARY bool "Build *.bin as Ouput" default n diff --git a/make/complier.mk b/make/complier.mk index c2a7c60d..4da6e060 100755 --- a/make/complier.mk +++ b/make/complier.mk @@ -14,7 +14,8 @@ APP ?= $(CONFIG_TARGET_NAME) QUIET ?=@ -OPT_LEVEL ?= 0 +# OPT_LEVEL ?= 0 +OPT_LEVEL ?= $(CONFIG_GCC_OPTIMIZE_LEVEL) INC_DIR ?= # include 目录 SRC_DIR ?= # 源文件目录 @@ -86,7 +87,7 @@ RM_DIRS = $(foreach dir,$(1),rm -rf $(dir)$(EOL)) DEPEND_FLAGS = -MD -MF $@.d CPPFLAGS = $(DEFINES) $(INCLUDES) $(DEPEND_FLAGS) $(CPPFLAGS_EXTRA) -CFLAGS = $(DEBUG_FLAGS) -DGUEST -ffreestanding -Wextra -g -O$(OPT_LEVEL) +CFLAGS = $(DEBUG_FLAGS) -DGUEST -ffreestanding -Wextra -Wno-implicit-fallthrough -g -O$(OPT_LEVEL) ASFLAGS = $(CFLAGS) #mkdir 创建输出文件目录 @@ -137,6 +138,8 @@ ifdef CONFIG_USE_NEW_LIBC LDFLAGS += -lgcc -L $(LIBPATH) endif +OBJ_FILES += $(LIB_OBJ_FILES) + # 不使用Libc库 ifdef CONFIG_USE_NOSTD_LIBC LDFLAGS += -nostdlib -nostartfiles diff --git a/third-party/Kconfig b/third-party/Kconfig index 9276ae4f..51c610d9 100644 --- a/third-party/Kconfig +++ b/third-party/Kconfig @@ -16,15 +16,15 @@ config USE_BACKTRACE prompt "Display a backtrace." default y -config USE_FATFS +config USE_FATFS_0_1_4 bool - prompt "Use FATFS" + prompt "Use FATFS(0.1.4)" default n help Include FATFS - if USE_FATFS - source "$(FREERTOS_SDK_ROOT)/third-party/fatfs-0.1.3/Kconfig" + if USE_FATFS_0_1_4 + source "$(FREERTOS_SDK_ROOT)/third-party/fatfs-0.1.4/Kconfig" endif config USE_SFUD @@ -107,4 +107,5 @@ config USE_CHERRY_USB if USE_CHERRY_USB source "$(FREERTOS_SDK_ROOT)/third-party/cherryusb-0.6.0/Kconfig" - endif \ No newline at end of file + endif + diff --git a/third-party/cherryusb-0.6.0/port/xhci/usb_config.h b/third-party/cherryusb-0.6.0/port/xhci/usb_config.h index 0869d15e..c7e5547e 100644 --- a/third-party/cherryusb-0.6.0/port/xhci/usb_config.h +++ b/third-party/cherryusb-0.6.0/port/xhci/usb_config.h @@ -1,39 +1,43 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: usb_config.h * Date: 2022-09-19 17:28:44 * LastEditTime: 2022-09-19 17:28:45 * Description:  This files is for usb hc xhci configuration - * - * Modify History: + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- * 1.0 zhugengyu 2022/9/19 init commit */ -#ifndef CHERRYUSB_CONFIG_H -#define CHERRYUSB_CONFIG_H +#ifndef USB_CONFIG_H +#define USB_CONFIG_H +#ifdef __cplusplus +extern "C" +{ +#endif /* ================ USB common Configuration ================ */ #ifndef CONFIG_USB_DBG_LEVEL -#define CONFIG_USB_DBG_LEVEL USB_DBG_ERROR + #define CONFIG_USB_DBG_LEVEL USB_DBG_ERROR #endif #ifndef CONFIG_USB_PRINTF -#define CONFIG_USB_PRINTF printf + #define CONFIG_USB_PRINTF printf #endif /* Enable print with color */ @@ -41,7 +45,7 @@ /* data align size when use dma */ #ifndef CONFIG_USB_ALIGN_SIZE -#define CONFIG_USB_ALIGN_SIZE 4 + #define CONFIG_USB_ALIGN_SIZE 4 #endif /* attribute data into no cache ram */ @@ -54,19 +58,19 @@ #ifndef CONFIG_USBDEV_MSC_BLOCK_SIZE -#define CONFIG_USBDEV_MSC_BLOCK_SIZE 512 + #define CONFIG_USBDEV_MSC_BLOCK_SIZE 512 #endif #ifndef CONFIG_USBDEV_MSC_MANUFACTURER_STRING -#define CONFIG_USBDEV_MSC_MANUFACTURER_STRING "" + #define CONFIG_USBDEV_MSC_MANUFACTURER_STRING "" #endif #ifndef CONFIG_USBDEV_MSC_PRODUCT_STRING -#define CONFIG_USBDEV_MSC_PRODUCT_STRING "" + #define CONFIG_USBDEV_MSC_PRODUCT_STRING "" #endif #ifndef CONFIG_USBDEV_MSC_VERSION_STRING -#define CONFIG_USBDEV_MSC_VERSION_STRING "0.01" + #define CONFIG_USBDEV_MSC_VERSION_STRING "0.01" #endif // #define CONFIG_USBHOST_GET_STRING_DESC @@ -76,21 +80,21 @@ #define CONFIG_INPUT_MOUSE_WHEEL #ifdef CONFIG_USBDEV_MSC_THREAD -#ifndef CONFIG_USBDEV_MSC_STACKSIZE -#define CONFIG_USBDEV_MSC_STACKSIZE 2048 -#endif + #ifndef CONFIG_USBDEV_MSC_STACKSIZE + #define CONFIG_USBDEV_MSC_STACKSIZE 2048 + #endif -#ifndef CONFIG_USBDEV_MSC_PRIO -#define CONFIG_USBDEV_MSC_PRIO 4 -#endif + #ifndef CONFIG_USBDEV_MSC_PRIO + #define CONFIG_USBDEV_MSC_PRIO 4 + #endif #endif #ifndef CONFIG_USBDEV_AUDIO_VERSION -#define CONFIG_USBDEV_AUDIO_VERSION 0x0100 + #define CONFIG_USBDEV_AUDIO_VERSION 0x0100 #endif #ifndef CONFIG_USBDEV_AUDIO_MAX_CHANNEL -#define CONFIG_USBDEV_AUDIO_MAX_CHANNEL 8 + #define CONFIG_USBDEV_AUDIO_MAX_CHANNEL 8 #endif /* ================ USB HOST Stack Configuration ================== */ @@ -105,21 +109,21 @@ #define CONFIG_USBHOST_DEV_NAMELEN 16 #ifndef CONFIG_USBHOST_PSC_PRIO -#define CONFIG_USBHOST_PSC_PRIO 4 + #define CONFIG_USBHOST_PSC_PRIO 4 #endif #ifndef CONFIG_USBHOST_PSC_STACKSIZE -#define CONFIG_USBHOST_PSC_STACKSIZE 2048 + #define CONFIG_USBHOST_PSC_STACKSIZE 2048 #endif /* Ep0 max transfer buffer */ #define CONFIG_USBHOST_REQUEST_BUFFER_LEN 512 #ifndef CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT -#define CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT 500 + #define CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT 500 #endif #ifndef CONFIG_USBHOST_MSC_TIMEOUT -#define CONFIG_USBHOST_MSC_TIMEOUT 5000 + #define CONFIG_USBHOST_MSC_TIMEOUT 5000 #endif /* ================ USB Device Port Configuration ================*/ @@ -132,6 +136,10 @@ #define CONFIG_USBHOST_PIPE_NUM 10 /* ================ XHCI Configuration ================ */ -#define CONFIG_USBHOST_XHCI +#define CONFIG_USBHOST_XHCI + +#ifdef __cplusplus +} +#endif #endif diff --git a/third-party/cherryusb-0.6.0/port/xhci/usb_hc_xhci.c b/third-party/cherryusb-0.6.0/port/xhci/usb_hc_xhci.c index 0d9100d6..d153b5bf 100644 --- a/third-party/cherryusb-0.6.0/port/xhci/usb_hc_xhci.c +++ b/third-party/cherryusb-0.6.0/port/xhci/usb_hc_xhci.c @@ -1,22 +1,22 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: usb_hc_xhci.c * Date: 2022-09-19 17:24:36 * LastEditTime: 2022-09-19 17:24:36 * Description:  This files is for xhci function implementation - * - * Modify History: + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- * 1.0 zhugengyu 2022/9/19 init commit @@ -33,7 +33,8 @@ /************************** Variable Definitions *****************************/ /* input is xhci speed */ -static const char *speed_name[16] = { +static const char *speed_name[16] = +{ [ 0 ] = " - ", [ 1 ] = "Full", [ 2 ] = "Low", @@ -41,7 +42,8 @@ static const char *speed_name[16] = { [ 4 ] = "Super", }; -static const int speed_from_xhci[16] = { +static const int speed_from_xhci[16] = +{ [ 0 ] = -1, [ 1 ] = USB_SPEED_FULL, [ 2 ] = USB_SPEED_LOW, @@ -50,7 +52,8 @@ static const int speed_from_xhci[16] = { [ 5 ... 15 ] = -1, }; -static const int speed_to_xhci[] = { +static const int speed_to_xhci[] = +{ [ USB_SPEED_FULL ] = 1, [ USB_SPEED_LOW ] = 2, [ USB_SPEED_HIGH ] = 3, @@ -68,13 +71,13 @@ struct xhci_pipe *xhci_event_process(struct xhci_s *xhci); static void xhci_dump_slot_ctx(const struct xhci_slotctx *const sc) { USB_LOG_DBG("ctx[0]=0x%x\n", sc->ctx[0]); - USB_LOG_DBG(" route=0x%x\n", - XHCI_SLOTCTX_0_ROUTE_GET(sc->ctx[0])); + USB_LOG_DBG(" route=0x%x\n", + XHCI_SLOTCTX_0_ROUTE_GET(sc->ctx[0])); USB_LOG_DBG("ctx[1]=0x%x\n", sc->ctx[1]); USB_LOG_DBG("ctx[2]=0x%x\n", sc->ctx[2]); - USB_LOG_DBG(" tt-port=0x%x, tt-hub-slot=0x%x\n", - XHCI_SLOTCTX_2_HUB_PORT_GET(sc->ctx[2]), - XHCI_SLOTCTX_2_HUB_SLOT_GET(sc->ctx[2])); + USB_LOG_DBG(" tt-port=0x%x, tt-hub-slot=0x%x\n", + XHCI_SLOTCTX_2_HUB_PORT_GET(sc->ctx[2]), + XHCI_SLOTCTX_2_HUB_SLOT_GET(sc->ctx[2])); USB_LOG_DBG("ctx[3]=0x%x\n", sc->ctx[3]); } @@ -82,7 +85,7 @@ static void xhci_dump_ep_ctx(const struct xhci_epctx *const ec) { USB_LOG_DBG("ctx[0]=0x%x\n", ec->ctx[0]); USB_LOG_DBG("ctx[1]=0x%x\n", ec->ctx[1]); - USB_LOG_DBG(" ep_type=%d, mps=%d\n", + USB_LOG_DBG(" ep_type=%d, mps=%d\n", XHCI_EPCTX_1_EPTYPE_GET(ec->ctx[1]), XHCI_EPCTX_1_MPS_GET(ec->ctx[1])); USB_LOG_DBG("deq_low=0x%x\n", ec->deq_low); @@ -95,17 +98,19 @@ static void xhci_dump_input_ctx(struct xhci_s *xhci, const struct xhci_inctx *co USB_LOG_DBG("===input ctx====\n"); USB_LOG_DBG("add=0x%x\n", inctx->add); USB_LOG_DBG("del=0x%x\n", inctx->del); - if (inctx->add & (0x1)) { + if (inctx->add & (0x1)) + { USB_LOG_DBG("===slot ctx====\n"); - const struct xhci_slotctx *const sc = (void*)&inctx[1 << xhci->context64]; + const struct xhci_slotctx *const sc = (void *)&inctx[1 << xhci->context64]; xhci_dump_slot_ctx(sc); } - for (int epid = 1; epid <= 31; epid++){ + for (int epid = 1; epid <= 31; epid++) + { if (inctx->add & (0x1 << (epid))) { USB_LOG_DBG("===ep-%d ctx====\n", epid); - const struct xhci_epctx *const ec = (void*)&inctx[(epid+1) << xhci->context64]; + const struct xhci_epctx *const ec = (void *)&inctx[(epid + 1) << xhci->context64]; xhci_dump_ep_ctx(ec); } } @@ -116,7 +121,9 @@ static void xhci_dump_pipe(const struct xhci_pipe *const ppipe) { USB_LOG_DBG("pipe@%p\n", ppipe); if (NULL == ppipe) + { return; + } USB_LOG_DBG("epaddr=%d\n", ppipe->epaddr); USB_LOG_DBG("speed=%d\n", ppipe->speed); @@ -137,9 +144,11 @@ static int xhci_wait_bit(unsigned long reg_off, uint32_t mask, uint32_t value, u { uint32_t delay = 0U; /* calc wait end time */ - while ((readl(reg_off) & mask) != value) { - if (++delay > timeout) { /* check if timeout */ - USB_LOG_ERR("wait timeout !!!\n"); + while ((readl(reg_off) & mask) != value) + { + if (++delay > timeout) /* check if timeout */ + { + USB_LOG_ERR("Wait timeout !!!\n"); return -1; } usb_osal_msleep(1U); @@ -154,10 +163,10 @@ static void xhci_print_port_state(const char *prefix, uint32_t port, uint32_t po uint32_t speed = XHCI_REG_OP_PORTS_PORTSC_PORT_SPEED_GET(portsc); USB_LOG_DBG("%s port #%d: 0x%08x,%s%s pls %d, speed %d [%s]\n", - prefix, port + 1, portsc, - (portsc & XHCI_REG_OP_PORTS_PORTSC_PP) ? " powered," : "", - (portsc & XHCI_REG_OP_PORTS_PORTSC_PED) ? " enabled," : "", - pls, speed, speed_name[speed]); + prefix, port + 1, portsc, + (portsc & XHCI_REG_OP_PORTS_PORTSC_PP) ? " powered," : "", + (portsc & XHCI_REG_OP_PORTS_PORTSC_PED) ? " enabled," : "", + pls, speed, speed_name[speed]); } static inline uint32_t xhci_readl_port(struct xhci_s *xhci, uint32_t port, uint32_t offset) @@ -195,10 +204,10 @@ static void xhci_setup_mmio(struct xhci_s *xhci, unsigned long base_addr) xhci->ports = XHCI_REG_CAP_HCS1_MAX_PORTS_GET(xhci->hcs[0]); /* bit[31:24] max ports */ xhci->slots = XHCI_REG_CAP_HCS1_MAX_SLOTS_GET(xhci->hcs[0]); /* bit[7:0] max device slots */ - - /* For example, using the offset of Base is 1000h and the xECP value of 0068h, we can calculated + + /* For example, using the offset of Base is 1000h and the xECP value of 0068h, we can calculated the following effective address of the first extended capability: - 1000h + (0068h << 2) -> 1000h + 01A0h -> 11A0h */ + 1000h + (0068h << 2) -> 1000h + 01A0h -> 11A0h */ xhci->xcap = XHCI_REG_CAP_HCC_XECP_GET(xhci->hcc) << 2; /* bit[31:16] xHCI extended cap pointer */ xhci->context64 = (XHCI_REG_CAP_HCC_CSZ & xhci->hcc) ? true : false; @@ -207,11 +216,11 @@ static void xhci_setup_mmio(struct xhci_s *xhci, unsigned long base_addr) USB_LOG_INFO(" oper base: 0x%x\n", xhci->op); USB_LOG_INFO(" doorbell base: 0x%x\n", xhci->db); USB_LOG_INFO(" runtime base: 0x%x\n", xhci->ir); - USB_LOG_INFO(" port base: 0x%x\n", xhci->pr); - USB_LOG_INFO(" xcap base: 0x%x\n", xhci->xcap); + USB_LOG_INFO(" port base: 0x%x\n", xhci->pr); + USB_LOG_INFO(" xcap base: 0x%x\n", xhci->xcap); - USB_LOG_INFO(" slot num: 0x%x\n", xhci->slots); - USB_LOG_INFO(" port num: 0x%x\n", xhci->ports); + USB_LOG_INFO(" slot num: 0x%x\n", xhci->slots); + USB_LOG_INFO(" port num: 0x%x\n", xhci->ports); USB_LOG_INFO(" context: %d bit\n", xhci->context64 ? 64 : 32); } @@ -222,36 +231,45 @@ static int xhci_hub_reset(struct xhci_s *xhci, uint32_t port) uint32_t portsc = xhci_readl_port(xhci, port, XHCI_REG_OP_PORTS_PORTSC); if (!(portsc & XHCI_REG_OP_PORTS_PORTSC_CCS)) /* double check if connected */ /* Device no longer connected?! */ + { return -1; + } - switch (XHCI_REG_OP_PORTS_PORTSC_PLS_GET(portsc)) { - case PLS_U0: - /* A USB3 port - controller automatically performs reset */ - break; - case PLS_POLLING: - /* A USB2 port - perform device reset */ - xhci_print_port_state(__func__, port, portsc); - xhci_writel_port(xhci, port, XHCI_REG_OP_PORTS_PORTSC, - portsc | XHCI_REG_OP_PORTS_PORTSC_PR); /* reset port */ - break; - default: - return -1; + switch (XHCI_REG_OP_PORTS_PORTSC_PLS_GET(portsc)) + { + case PLS_U0: + /* A USB3 port - controller automatically performs reset */ + break; + case PLS_POLLING: + /* A USB2 port - perform device reset */ + xhci_print_port_state(__func__, port, portsc); + xhci_writel_port(xhci, port, XHCI_REG_OP_PORTS_PORTSC, + portsc | XHCI_REG_OP_PORTS_PORTSC_PR); /* reset port */ + break; + default: + return -1; } // Wait for device to complete reset and be enabled uint32_t end = 1000U, start = 0U; - for (;;) { + for (;;) + { portsc = xhci_readl_port(xhci, port, XHCI_REG_OP_PORTS_PORTSC); if (!(portsc & XHCI_REG_OP_PORTS_PORTSC_CCS)) /* Device disconnected during reset */ + { return -1; - + } + if (portsc & XHCI_REG_OP_PORTS_PORTSC_PED) /* check if port enabled */ /* Reset complete */ + { break; + } - if (++start > end) { - USB_LOG_ERR("wait timeout, portsc=0x%x!!!\n", portsc); + if (++start > end) + { + USB_LOG_ERR("Wait timeout, portsc=0x%x !!!\n", portsc); return -1; } @@ -267,9 +285,12 @@ static int xhci_hub_reset(struct xhci_s *xhci, uint32_t port) static void xhci_trb_fill(struct xhci_ring *ring, void *data, uint32_t xferlen, uint32_t flags) { struct xhci_trb *dst = &ring->ring[ring->nidx]; - if (flags & TRB_TR_IDT) { + if (flags & TRB_TR_IDT) + { memcpy(&dst->ptr_low, data, xferlen); - } else { + } + else + { dst->ptr_low = (uint32_t)(unsigned long)data; #ifdef XHCI_AARCH64 dst->ptr_high = (uint32_t)((uint64_t)data >> 32U); @@ -285,9 +306,10 @@ static void xhci_trb_fill(struct xhci_ring *ring, void *data, uint32_t xferlen, /* Queue a TRB onto a ring, wrapping ring as needed */ static void xhci_trb_queue(struct xhci_ring *ring, void *data, uint32_t xferlen, uint32_t flags) { - if (ring->nidx >= ARRAY_SIZE(ring->ring) - 1) { /* if it is the last trb in the list */ + if (ring->nidx >= ARRAY_SIZE(ring->ring) - 1) /* if it is the last trb in the list */ + { /* indicate the end of ring, bit[1], toggle cycle = 1, xHc shall toggle cycle bit interpretation */ - xhci_trb_fill(ring, ring->ring, 0, (TR_LINK << 10) | TRB_LK_TC); + xhci_trb_fill(ring, ring->ring, 0, (TR_LINK << 10) | TRB_LK_TC); ring->nidx = 0; /* adjust dequeue index to 0 */ ring->cs ^= 1; /* toggle cycle interpretation of sw */ } @@ -309,12 +331,16 @@ static int xhci_event_wait(struct xhci_s *xhci, { int ret = CC_SUCCESS; - if (pipe->timeout > 0){ + if (pipe->timeout > 0) + { ret = usb_osal_sem_take(pipe->waitsem, pipe->timeout); - if (ret < 0) { + if (ret < 0) + { ret = CC_TIMEOUT; - } else { - ret = TRB_CC_GET(ring->evt.status); /* bit[31:24] completion code */ + } + else + { + ret = TRB_CC_GET(ring->evt.status); /* bit[31:24] completion code */ } } @@ -326,20 +352,21 @@ static int xhci_cmd_abort(struct xhci_s *xhci, struct xhci_pipe *pipe) uint64_t crcr; crcr = readq(xhci->op + XHCI_REG_OP_CRCR); - USB_LOG_WRN("aborting command, crcr = 0x%llx\r\n", crcr); + USB_LOG_WRN("Aborting command, crcr = 0x%llx .\r\n", crcr); crcr |= XHCI_REG_OP_CRCR_CA; writeq(xhci->op + XHCI_REG_OP_CRCR, crcr); /* abort command */ usb_osal_msleep(500); /* allow time for command to abort */ crcr = readl(xhci->op + XHCI_REG_OP_CRCR); - if (XHCI_REG_OP_CRCR_CRR & crcr) { - /* Device has failed to abort a command and is almost - * certainly beyond repair. Reset device, abandoning - * all state, and mark device as failed to avoid - * delays on any future command attempts. - */ - USB_LOG_ERR("failed to abort command \r\n"); + if (XHCI_REG_OP_CRCR_CRR & crcr) + { + /* Device has failed to abort a command and is almost + * certainly beyond repair. Reset device, abandoning + * all state, and mark device as failed to avoid + * delays on any future command attempts. + */ + USB_LOG_ERR("Failed to abort command.\r\n"); return -1; } @@ -357,14 +384,16 @@ static int xhci_cmd_abort(struct xhci_s *xhci, struct xhci_pipe *pipe) } /* Submit a command to the xhci controller ring */ -static int xhci_cmd_submit(struct xhci_s *xhci, struct xhci_inctx *inctx, +static int xhci_cmd_submit(struct xhci_s *xhci, struct xhci_inctx *inctx, struct xhci_pipe *pipe, uint32_t flags) { - if (inctx) { - struct xhci_slotctx *slot = (void*)&inctx[1 << xhci->context64]; + if (inctx) + { + struct xhci_slotctx *slot = (void *)&inctx[1 << xhci->context64]; uint32_t port = XHCI_SLOTCTX_1_ROOT_PORT_GET(slot->ctx[1]) - 1; uint32_t portsc = xhci_readl_port(xhci, port, XHCI_REG_OP_PORTS_PORTSC); - if (!(portsc & XHCI_REG_OP_PORTS_PORTSC_CCS)) { + if (!(portsc & XHCI_REG_OP_PORTS_PORTSC_CCS)) + { /* Device no longer connected?! */ xhci_print_port_state(__func__, port, portsc); return CC_DISCONNECTED; @@ -385,7 +414,8 @@ static int xhci_cmd_submit(struct xhci_s *xhci, struct xhci_inctx *inctx, xhci_doorbell(xhci, 0, 0); /* 0 = db host controller, 0 = db targe hc command */ int rc = xhci_event_wait(xhci, pipe, xhci->cmds); - if (CC_SUCCESS != rc) { + if (CC_SUCCESS != rc) + { rc = xhci_cmd_abort(xhci, pipe); } @@ -404,7 +434,9 @@ static int xhci_cmd_enable_slot(struct xhci_s *xhci, struct xhci_pipe *pipe) { int cc = xhci_cmd_submit(xhci, NULL, pipe, TRB_TYPE_SET(CR_ENABLE_SLOT)); if (cc != CC_SUCCESS) + { return cc; + } struct xhci_trb *evt = &(xhci->cmds->evt); return TRB_CR_SLOTID_GET(evt->control); /* bit [31:24] slot id */ @@ -422,13 +454,13 @@ static int xhci_cmd_address_device(struct xhci_s *xhci, struct xhci_pipe *pipe, return xhci_cmd_submit(xhci, inctx, pipe, TRB_TYPE_SET(CR_ADDRESS_DEVICE) | TRB_CR_SLOTID_SET(pipe->slotid)); } -static int xhci_cmd_configure_endpoint(struct xhci_s *xhci, struct xhci_pipe *pipe, +static int xhci_cmd_configure_endpoint(struct xhci_s *xhci, struct xhci_pipe *pipe, struct xhci_inctx *inctx, bool defconfig) { USB_LOG_DBG("%s: slotid %d\n", __func__, pipe->slotid); - return xhci_cmd_submit(xhci, inctx, pipe, TRB_TYPE_SET(CR_CONFIGURE_ENDPOINT) | - TRB_CR_SLOTID_SET(pipe->slotid) | - (defconfig ? TRB_CR_DC : 0)); + return xhci_cmd_submit(xhci, inctx, pipe, TRB_TYPE_SET(CR_CONFIGURE_ENDPOINT) | + TRB_CR_SLOTID_SET(pipe->slotid) | + (defconfig ? TRB_CR_DC : 0)); } static int xhci_cmd_evaluate_context(struct xhci_s *xhci, struct xhci_pipe *pipe, struct xhci_inctx *inctx) @@ -441,8 +473,8 @@ static int xhci_cmd_reset_endpoint(struct xhci_s *xhci, struct xhci_pipe *pipe) { USB_LOG_DBG("%s: slotid %d, epid %d\n", __func__, pipe->slotid, pipe->epid); /* bit[15:10] TRB type, bit[31:24] Slot id */ - return xhci_cmd_submit(xhci, NULL, pipe, TRB_TYPE_SET(CR_RESET_ENDPOINT) | TRB_CR_SLOTID_SET(pipe->slotid) | - TRB_CR_EPID_SET(pipe->epid)); + return xhci_cmd_submit(xhci, NULL, pipe, TRB_TYPE_SET(CR_RESET_ENDPOINT) | TRB_CR_SLOTID_SET(pipe->slotid) | + TRB_CR_EPID_SET(pipe->epid)); } static int xhci_controller_configure(struct xhci_s *xhci) @@ -454,9 +486,10 @@ static int xhci_controller_configure(struct xhci_s *xhci) xhci->eseg = usb_align(XHCI_ALIGMENT, sizeof(*xhci->eseg)); /* event segment */ xhci->cmds = usb_align(XHCI_RING_SIZE, sizeof(*xhci->cmds)); /* command ring */ xhci->evts = usb_align(XHCI_RING_SIZE, sizeof(*xhci->evts)); /* event ring */ - - if (!xhci->devs || !xhci->cmds || !xhci->evts || !xhci->eseg) { - USB_LOG_ERR("allocate memory failed !!!\n"); + + if (!xhci->devs || !xhci->cmds || !xhci->evts || !xhci->eseg) + { + USB_LOG_ERR("Allocate memory failed !!!\n"); goto fail; } @@ -469,30 +502,37 @@ static int xhci_controller_configure(struct xhci_s *xhci) USB_ASSERT(xhci->cmds->lock); reg = readl(xhci->op + XHCI_REG_OP_USBCMD); - if (reg & XHCI_REG_OP_USBCMD_RUN_STOP) { /* if xHc running, stop it first */ + if (reg & XHCI_REG_OP_USBCMD_RUN_STOP) /* if xHc running, stop it first */ + { reg &= ~XHCI_REG_OP_USBCMD_RUN_STOP; writel(xhci->op + XHCI_REG_OP_USBCMD, reg); /* stop xHc */ - if (xhci_wait_bit(xhci->op + XHCI_REG_OP_USBSTS, - XHCI_REG_OP_USBSTS_HCH, XHCI_REG_OP_USBSTS_HCH, 32) != 0) /* wait xHc halt */ + if (xhci_wait_bit(xhci->op + XHCI_REG_OP_USBSTS, + XHCI_REG_OP_USBSTS_HCH, XHCI_REG_OP_USBSTS_HCH, 32) != 0) /* wait xHc halt */ + { goto fail; + } } USB_LOG_DBG("%s: resetting\n", __func__); - + writel(xhci->op + XHCI_REG_OP_USBCMD, XHCI_REG_OP_USBCMD_HCRST); /* reset xHc */ if (xhci_wait_bit(xhci->op + XHCI_REG_OP_USBCMD, XHCI_REG_OP_USBCMD_HCRST, 0, 1000) != 0) /* wait reset process done */ + { goto fail; + } if (xhci_wait_bit(xhci->op + XHCI_REG_OP_USBSTS, XHCI_REG_OP_USBSTS_CNR, 0, 1000) != 0) /* wait until xHc ready */ + { goto fail; + } writel(xhci->op + XHCI_REG_OP_CONFIG, xhci->slots); /* bit[7:0], set max num of device slot enabled */ writeq(xhci->op + XHCI_REG_OP_DCBAAP, (uint64_t)(unsigned long)xhci->devs); /* bit[63:6] device context base address array pointer */ writeq(xhci->op + XHCI_REG_OP_CRCR, (uint64_t)(unsigned long)xhci->cmds | 1); /* command ring pointer, cycle state = 1 */ xhci->cmds->cs = 1; /* cycle state = 1 */ - xhci->eseg->ptr_low = (uint32_t)((unsigned long)xhci->evts); /* event ring pointer */ + xhci->eseg->ptr_low = (uint32_t)((unsigned long)xhci->evts); /* event ring pointer */ #ifdef XHCI_AARCH64 xhci->eseg->ptr_high = (uint32_t)((unsigned long)xhci->evts >> 32U); #else @@ -507,19 +547,23 @@ static int xhci_controller_configure(struct xhci_s *xhci) reg = xhci->hcs[1]; uint32_t spb = XHCI_REG_CAP_HCS2_MAX_SCRATCHPAD_BUFS_GET(reg); /* bit [25:21] | bit [31:27] max scratchpad buffers */ - if (spb) { + if (spb) + { /* reserve scratchpad buffers for xHc */ - USB_LOG_DBG("%s: setup %d scratch pad buffers\n", __func__, spb); + USB_LOG_DBG("%s: setup %d scratch pad buffers.\n", __func__, spb); uint64_t *spba = usb_align(XHCI_ALIGMENT, sizeof(*spba) * spb); /* base addr of scratchpad buffers */ void *pad = usb_align(CONFIG_XHCI_PAGE_SIZE, CONFIG_XHCI_PAGE_SIZE * spb); /* the whole scratchpad buffers */ - if (!spba || !pad) { - USB_LOG_ERR("allocate memory failed !!!\n"); + if (!spba || !pad) + { + USB_LOG_ERR("Allocate memory failed !!!\n"); usb_free(spba); usb_free(pad); goto fail; } for (uint32_t i = 0; i < spb; i++) - spba[i] = (uint64_t)(unsigned long)(pad + (i * CONFIG_XHCI_PAGE_SIZE)); /* assign base addr for each pad */ + { + spba[i] = (uint64_t)(unsigned long)(pad + (i * CONFIG_XHCI_PAGE_SIZE)); /* assign base addr for each pad */ + } xhci->devs[0].ptr_low = (uint32_t)((unsigned long)spba); /* bit[63:6] scratchpad buffers base addr */ #ifdef XHCI_AARCH64 xhci->devs[0].ptr_high = (uint32_t)((uint64_t)spba >> 32U); @@ -556,14 +600,17 @@ fail: static void xhci_check_xcap(struct xhci_s *xhci) { - if (xhci->xcap) { /* read Extended Capabilities */ + if (xhci->xcap) /* read Extended Capabilities */ + { uint32_t off; unsigned long addr = xhci->base + xhci->xcap; /* start read ext-cap */ - - do { + + do + { unsigned long xcap = addr; uint32_t ports, name, cap = readl(xcap + XHCI_REG_EXT_CAP_USBSPCF_OFFSET); - switch (XHCI_REG_EXT_CAP_CAP_ID_GET(cap)) { + switch (XHCI_REG_EXT_CAP_CAP_ID_GET(cap)) + { case XHCI_EXT_CAP_ID_SUPPORT_PROTOCOL: /* 0x2, supported protocol */ name = readl(xcap + XHCI_REG_EXT_CAP_USBSPCFDEF_OFFSET); ports = readl(xcap + XHCI_REG_EXT_CAP_USBSPCFDEF2_OFFSET); @@ -572,35 +619,39 @@ static void xhci_check_xcap(struct xhci_s *xhci) uint8_t count = XHCI_USBSPCFDEF2_COMPATIBLE_PORT_CNT_GET(ports); uint8_t start = XHCI_USBSPCFDEF2_COMPATIBLE_PORT_OFF_GET(ports); USB_LOG_INFO("XHCI protocol %c%c%c%c %x.%02x" - ", %d ports (offset %d), def %x\n" - , (name >> 0) & 0xff - , (name >> 8) & 0xff - , (name >> 16) & 0xff - , (name >> 24) & 0xff /* Print string 'USB' */ - , major, minor - , count, start - , ports >> 16); - if (name == XHCI_USBSPCFDEF_NAME_STRING_USB /* ASCII "USB " */) { - if (major == 2) { + ", %d ports (offset %d), def %x\n" + , (name >> 0) & 0xff + , (name >> 8) & 0xff + , (name >> 16) & 0xff + , (name >> 24) & 0xff /* Print string 'USB' */ + , major, minor + , count, start + , ports >> 16); + if (name == XHCI_USBSPCFDEF_NAME_STRING_USB /* ASCII "USB " */) + { + if (major == 2) + { xhci->usb2.start = start; /* USB 2.0 port range */ xhci->usb2.count = count; } - if (major == 3) { + if (major == 3) + { xhci->usb3.start = start; /* USB 3.0 port range */ xhci->usb3.count = count; } } break; default: - USB_LOG_INFO("XHCI extcap 0x%x @ %p\n", + USB_LOG_INFO("XHCI extcap 0x%x @ %p\n", XHCI_REG_EXT_CAP_CAP_ID_GET(cap), addr); break; - } + } off = XHCI_REG_EXT_NEXT_CAP_PTR_GET(cap); addr += off << 2; /* addr of next ext-cap */ - } while (off > 0); - } - + } + while (off > 0); + } + } static int xhci_controller_setup(struct xhci_s *xhci, unsigned long baseaddr) @@ -609,8 +660,9 @@ static int xhci_controller_setup(struct xhci_s *xhci, unsigned long baseaddr) /* get register offset */ xhci_setup_mmio(xhci, baseaddr); - if (xhci->version < 0x96 || xhci->version > 0x120) { - USB_LOG_ERR("xHCI-0x%x not support\n", xhci->version); + if (xhci->version < 0x96 || xhci->version > 0x120) + { + USB_LOG_ERR("XHCI-0x%x not support.\n", xhci->version); return -1; } @@ -618,18 +670,22 @@ static int xhci_controller_setup(struct xhci_s *xhci, unsigned long baseaddr) uint32_t pagesize = readl(xhci->op + XHCI_REG_OP_PAGESIZE); /* get page-size */ USB_LOG_INFO("XHCI page size %d \n", (pagesize << CONFIG_XHCI_PAGE_SHIFT)); - if (CONFIG_XHCI_PAGE_SIZE != (pagesize << CONFIG_XHCI_PAGE_SHIFT)) { - USB_LOG_ERR("XHCI driver does not support page size code %d\n" - , pagesize << CONFIG_XHCI_PAGE_SHIFT); + if (CONFIG_XHCI_PAGE_SIZE != (pagesize << CONFIG_XHCI_PAGE_SHIFT)) + { + USB_LOG_ERR("XHCI driver does not support page size code %d.\n" + , pagesize << CONFIG_XHCI_PAGE_SHIFT); return -1; } - USB_LOG_INFO("config XHCI ....\n"); - if (xhci_controller_configure(xhci)) { - USB_LOG_ERR("init XHCI failed !!!\n"); + USB_LOG_INFO("Config XHCI ....\n"); + if (xhci_controller_configure(xhci)) + { + USB_LOG_ERR("Init XHCI failed !!!\n"); return -1; - } else { - USB_LOG_INFO("init XHCI success !!!\n"); + } + else + { + USB_LOG_INFO("Init XHCI success !!!\n"); } return 0; @@ -637,34 +693,41 @@ static int xhci_controller_setup(struct xhci_s *xhci, unsigned long baseaddr) struct xhci_pipe *xhci_event_process(struct xhci_s *xhci) { - struct xhci_pipe *work_pipe = NULL; + struct xhci_pipe *work_pipe = NULL; struct xhci_ring *evts = xhci->evts; /* check and ack event */ - for (;;) { + for (;;) + { uint32_t nidx = evts->nidx; /* index of dequeue trb */ uint32_t cs = evts->cs; /* cycle state toggle by xHc */ struct xhci_trb *etrb = evts->ring + nidx; /* current trb */ uint32_t control = etrb->control; /* trb control field */ if ((control & TRB_C) != (cs ? 1 : 0)) /* if cycle state not toggle, no events need to handle */ + { break; + } /* process event on etrb */ uint32_t evt_type = TRB_TYPE_GET(control); uint32_t evt_cc = TRB_CC_GET(etrb->status); /* bit[31:24] completion code */ - - if (ER_PORT_STATUS_CHANGE == evt_type) { + + if (ER_PORT_STATUS_CHANGE == evt_type) + { /* bit[31:24] port id, the port num of root hub port that generated this event */ uint32_t port = TRB_PORT_ID_GET(etrb->ptr_low) - 1; uint32_t portsc = xhci_readl_port(xhci, port, XHCI_REG_OP_PORTS_PORTSC); /* Read status */ xhci_print_port_state(__func__, port, portsc); - if (portsc & XHCI_REG_OP_PORTS_PORTSC_CSC) { + if (portsc & XHCI_REG_OP_PORTS_PORTSC_CSC) + { usbh_roothub_thread_wakeup(port + 1); /* wakeup when connection status changed */ } - } else if ((ER_COMMAND_COMPLETE == evt_type) || (ER_TRANSFER_COMPLETE == evt_type)) { - struct xhci_trb *rtrb = (void*)(unsigned long)etrb->ptr_low; + } + else if ((ER_COMMAND_COMPLETE == evt_type) || (ER_TRANSFER_COMPLETE == evt_type)) + { + struct xhci_trb *rtrb = (void *)(unsigned long)etrb->ptr_low; struct xhci_ring *ring = XHCI_RING(rtrb); /* to align addr is ring base */ struct xhci_trb *evt = &ring->evt; /* first event trb */ uint32_t eidx = rtrb - ring->ring + 1; /* calculate current evt trb index */ @@ -672,46 +735,55 @@ struct xhci_pipe *xhci_event_process(struct xhci_s *xhci) memcpy(evt, etrb, sizeof(*etrb)); /* copy current trb to cmd/transfer ring */ ring->eidx = eidx; - if (ER_COMMAND_COMPLETE == evt_type) { + if (ER_COMMAND_COMPLETE == evt_type) + { work_pipe = (struct xhci_pipe *)cur_cmd_pipe; - } else if (ER_TRANSFER_COMPLETE == evt_type) { + } + else if (ER_TRANSFER_COMPLETE == evt_type) + { /* xhci_pipe begin with reqs ring, therefore we get pipe instance from reqs ring */ work_pipe = (struct xhci_pipe *)(void *)ring; } - if (work_pipe) { - if (work_pipe->waiter) { + if (work_pipe) + { + if (work_pipe->waiter) + { work_pipe->waiter = false; usb_osal_sem_give(work_pipe->waitsem); } - if (work_pipe->urb) { + if (work_pipe->urb) + { struct usbh_urb *cur_urb = work_pipe->urb; cur_urb->errorcode = evt_cc; /* bit [23:0] TRB Transfer length, residual number of bytes not transferred for OUT, is the value of (len of trb) - (data bytes transmitted), '0' means successful - for IN, is the value of (len of trb) - (data bytes received), + for IN, is the value of (len of trb) - (data bytes received), if cc is Short Packet, value is the diff between expected trans size and actual recv bytes if cc is other error, value is the diff between expected trans size and actual recv bytes */ - cur_urb->actual_length += cur_urb->transfer_buffer_length - - TRB_TR_TRANS_LEN_SET(evt->status); /* bit [23:0] */ + cur_urb->actual_length += cur_urb->transfer_buffer_length - + TRB_TR_TRANS_LEN_SET(evt->status); /* bit [23:0] */ } - } - } else { - USB_LOG_ERR("%s: unknown event, type %d, cc %d\n", - __func__, evt_type, evt_cc); + } + } + else + { + USB_LOG_ERR("%s: Unknown event, type %d, cc %d.\n", + __func__, evt_type, evt_cc); } /* move ring index, notify xhci */ nidx++; /* head to next trb */ - if (nidx == XHCI_RING_ITEMS) { + if (nidx == XHCI_RING_ITEMS) + { nidx = 0; /* roll-back if reach end of list */ cs = cs ? 0 : 1; evts->cs = cs; /* sw toggle cycle state */ } evts->nidx = nidx; uint64_t erdp = (uint64_t)(unsigned long)(evts->ring + nidx); - writeq(xhci->ir + XHCI_REG_RT_IR_ERDP, erdp | XHCI_REG_RT_IR_ERDP_EHB); /* bit[63:4] update current event ring dequeue pointer */ + writeq(xhci->ir + XHCI_REG_RT_IR_ERDP, erdp | XHCI_REG_RT_IR_ERDP_EHB); /* bit[63:4] update current event ring dequeue pointer */ } return work_pipe; @@ -725,47 +797,55 @@ static struct xhci_inctx *xhci_alloc_inctx_config_ep(struct xhci_s *xhci, struct struct xhci_inctx *in = usb_align(XHCI_INCTX_ALIGMENT << xhci->context64, size); int devport = hport->port; - if (!in) { - USB_LOG_ERR("allocate memory failed !!!\n"); + if (!in) + { + USB_LOG_ERR("Allocate memory failed !!!\n"); return NULL; } memset(in, 0, size); - struct xhci_slotctx *slot = (void*)&in[1 << xhci->context64]; /* slot context */ + struct xhci_slotctx *slot = (void *)&in[1 << xhci->context64]; /* slot context */ slot->ctx[0] |= XHCI_SLOTCTX_0_MAX_EPID_SET(maxepid); /* bit[31:27] index of the last valid ep context */ slot->ctx[0] |= XHCI_SLOTCTX_0_SPEED_SET(speed_to_xhci[hport->speed]); /* bit[23:20] speed of this device */ - + /* Set high-speed hub flags. */ struct usbh_hub *hubdev = hport->parent; USB_ASSERT(hubdev); - if (!hubdev->is_roothub) { /* if device is not under roothub */ + if (!hubdev->is_roothub) /* if device is not under roothub */ + { /* Is this the first high-speed hub with a non-high-speed device following in chain */ struct usbh_hubport *hub_port = hubdev->parent; - if (hport->speed == USB_SPEED_LOW || hport->speed == USB_SPEED_FULL) { - if (hub_port->speed == USB_SPEED_HIGH) { + if (hport->speed == USB_SPEED_LOW || hport->speed == USB_SPEED_FULL) + { + if (hub_port->speed == USB_SPEED_HIGH) + { slot->ctx[2] |= XHCI_SLOTCTX_2_HUB_SLOT_SET(hub_port->dev_addr); /* bit[7:0] parent hub slot id */ slot->ctx[2] |= XHCI_SLOTCTX_2_HUB_PORT_SET(hport->port); /* bit[15:8] parent port num */ slot->ctx[0] |= XHCI_SLOTCTX_0_MULTI_TT; - } else { - struct xhci_slotctx *hslot = (void*)(unsigned long)xhci->devs[hub_port->dev_addr].ptr_low; + } + else + { + struct xhci_slotctx *hslot = (void *)(unsigned long)xhci->devs[hub_port->dev_addr].ptr_low; slot->ctx[2] = hslot->ctx[2]; /* 08h, copy hub slot context */ } } uint32_t route = 0U; - do { + do + { route <<= 4; route |= (hport->port) & 0xf; /* record port for each tire */ hport = hubdev->parent; hubdev = hport->parent; - } while ((!hubdev) || (!hubdev->is_roothub)); + } + while ((!hubdev) || (!hubdev->is_roothub)); slot->ctx[0] |= XHCI_SLOTCTX_0_ROUTE_SET(route); /* bit[19:0] route string, max 5 tires */ } /* refer to spec. Ports are numbered from 1 to MaxPorts. */ - slot->ctx[1] |= XHCI_SLOTCTX_1_ROOT_PORT_SET(hport->port); /* bit[23:16] root hub port number */ + slot->ctx[1] |= XHCI_SLOTCTX_1_ROOT_PORT_SET(hport->port); /* bit[23:16] root hub port number */ return in; } @@ -777,29 +857,30 @@ static struct xhci_inctx *xhci_alloc_inctx_set_ep_mps(struct xhci_s *xhci, uint3 int size = (sizeof(struct xhci_inctx) * XHCI_INCTX_ENTRY_NUM) << xhci->context64; struct xhci_inctx *in = usb_align(XHCI_INCTX_ALIGMENT << xhci->context64, size); - if (!in) { - USB_LOG_ERR("allocate memory failed !!!\n"); + if (!in) + { + USB_LOG_ERR("Allocate memory failed !!!\n"); return NULL; } memset(in, 0, size); /* copy 32 entries after inctx controller field from devctx to inctx */ #ifdef XHCI_AARCH64 - struct xhci_slotctx *devctx = (struct xhci_slotctx *)(((uint64_t)xhci->devs[slotid].ptr_high << 32U) | - ((uint64_t)xhci->devs[slotid].ptr_low)); + struct xhci_slotctx *devctx = (struct xhci_slotctx *)(((uint64_t)xhci->devs[slotid].ptr_high << 32U) | + ((uint64_t)xhci->devs[slotid].ptr_low)); #else struct xhci_slotctx *devctx = (struct xhci_slotctx *)(unsigned long)xhci->devs[slotid].ptr_low; #endif - struct xhci_slotctx *input_devctx = (void*)&in[1 << xhci->context64]; + struct xhci_slotctx *input_devctx = (void *)&in[1 << xhci->context64]; memcpy(input_devctx, devctx, XHCI_SLOTCTX_ENTRY_NUM * sizeof(struct xhci_slotctx)); /* input ctrl context slot - ep-0 context, offset = 2 * xhci->context64, e.g, for 64 bit (0x40), offset = 0x80 + ep-0 context, offset = 2 * xhci->context64, e.g, for 64 bit (0x40), offset = 0x80 */ - struct xhci_epctx *ep = (void*)&in[2 << xhci->context64]; /* ep context */ + struct xhci_epctx *ep = (void *)&in[2 << xhci->context64]; /* ep context */ ep->ctx[1] |= XHCI_EPCTX_1_MPS_SET(ep_mps); /* bit[31:16] update maxpacket size */ return in; @@ -811,20 +892,21 @@ static struct xhci_inctx *xhci_alloc_inctx_enable_hub_func(struct xhci_s *xhci, int size = (sizeof(struct xhci_inctx) * XHCI_INCTX_ENTRY_NUM) << xhci->context64; struct xhci_inctx *in = usb_align(XHCI_INCTX_ALIGMENT << xhci->context64, size); - if (!in) { - USB_LOG_ERR("allocate memory failed !!!\n"); + if (!in) + { + USB_LOG_ERR("Allocate memory failed !!!\n"); return NULL; } memset(in, 0, size); /* copy 32 entries after inctx controller field from devctx to inctx */ #ifdef XHCI_AARCH64 - struct xhci_slotctx *devctx = (struct xhci_slotctx *)(((uint64_t)xhci->devs[slotid].ptr_high << 32U) | - ((uint64_t)xhci->devs[slotid].ptr_low)); + struct xhci_slotctx *devctx = (struct xhci_slotctx *)(((uint64_t)xhci->devs[slotid].ptr_high << 32U) | + ((uint64_t)xhci->devs[slotid].ptr_low)); #else struct xhci_slotctx *devctx = (struct xhci_slotctx *)(unsigned long)xhci->devs[slotid].ptr_low; #endif - struct xhci_slotctx *input_devctx = (void*)&in[1 << xhci->context64]; + struct xhci_slotctx *input_devctx = (void *)&in[1 << xhci->context64]; memcpy(input_devctx, devctx, XHCI_SLOTCTX_ENTRY_NUM * sizeof(struct xhci_slotctx)); @@ -833,7 +915,8 @@ static struct xhci_inctx *xhci_alloc_inctx_enable_hub_func(struct xhci_s *xhci, input_devctx->ctx[0] |= XHCI_SLOTCTX_0_SPEED_SET(hub_info->speed); input_devctx->ctx[1] |= XHCI_SLOTCTX_1_PORTS_NUM_SET(hub_info->num_of_ports); - if (hub_info->speed == USB_SPEED_HIGH) { + if (hub_info->speed == USB_SPEED_HIGH) + { input_devctx->ctx[0] |= hub_info->has_multiple_tts ? XHCI_SLOTCTX_0_MULTI_TT : 0U; input_devctx->ctx[2] |= XHCI_SLOTCTX_2_TTT_THINK_SET(hub_info->tt_think_time); } @@ -842,31 +925,32 @@ static struct xhci_inctx *xhci_alloc_inctx_enable_hub_func(struct xhci_s *xhci, } /* Submit a USB "setup" message request to the pipe's ring */ -static void xhci_xfer_setup(struct xhci_s *xhci, struct xhci_pipe *pipe, +static void xhci_xfer_setup(struct xhci_s *xhci, struct xhci_pipe *pipe, bool dir_in, void *cmd, void *data, int datalen) { /* SETUP TRB ctrl, bit[15:10] trb type bit[6] Immediate Data (IDT), parameters take effect bit[17:16] Transfer type, 2 = OUT Data, 3 = IN Data */ - uint32_t trans_type = (datalen > 0) ? (dir_in ? TRB_TR_IN_DATA : TRB_TR_OUT_DATA): TRB_TR_NO_DATA; + uint32_t trans_type = (datalen > 0) ? (dir_in ? TRB_TR_IN_DATA : TRB_TR_OUT_DATA) : TRB_TR_NO_DATA; xhci_trb_queue(&pipe->reqs, cmd, USB_SIZEOF_SETUP_PACKET, TRB_TYPE_SET(TR_SETUP) | TRB_TR_IDT | TRB_TR_TYPE_SET(trans_type)); /* DATA TRB ctrl, bit[15:10] trb type bit[16] Direction, 0 = OUT, 1 = IN */ - if (datalen) { + if (datalen) + { xhci_trb_queue(&pipe->reqs, data, datalen, TRB_TYPE_SET(TR_DATA) | (dir_in ? TRB_TR_DIR : 0)); } /* STATUS TRB ctrl, bit[5] Interrupt On Completion (IOC). bit[16] Direction, 0 = OUT, 1 = IN */ - xhci_trb_queue(&pipe->reqs, NULL, 0, - TRB_TYPE_SET(TR_STATUS) | TRB_TR_IOC | ((dir_in ? 0 : TRB_TR_DIR))); + xhci_trb_queue(&pipe->reqs, NULL, 0, + TRB_TYPE_SET(TR_STATUS) | TRB_TR_IOC | ((dir_in ? 0 : TRB_TR_DIR))); - /* pass command trb to hardware */ + /* pass command trb to hardware */ DSB(); - + /* notfiy xHc that device slot - epid */ xhci_doorbell(xhci, pipe->slotid, pipe->epid); } @@ -878,7 +962,7 @@ static void xhci_xfer_normal(struct xhci_s *xhci, struct xhci_pipe *pipe, /* Normal trb, used in bulk and interrupt transfer */ xhci_trb_queue(&pipe->reqs, data, datalen, TRB_TYPE_SET(TR_NORMAL) | TRB_TR_IOC); - /* pass command trb to hardware */ + /* pass command trb to hardware */ DSB(); xhci_doorbell(xhci, pipe->slotid, pipe->epid); @@ -918,8 +1002,10 @@ int usb_hc_init(void) memset(&xhci_host, 0, sizeof(xhci_host)); if (xhci_controller_setup(&xhci_host, usb_hc_get_register_base())) + { return -1; - + } + return 0; } @@ -935,10 +1021,13 @@ int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf) nports = CONFIG_USBHOST_MAX_RHPORTS; port = setup->wIndex; - if (setup->bmRequestType & USB_REQUEST_RECIPIENT_DEVICE) { - switch (setup->bRequest) { + if (setup->bmRequestType & USB_REQUEST_RECIPIENT_DEVICE) + { + switch (setup->bRequest) + { case HUB_REQUEST_CLEAR_FEATURE: - switch (setup->wValue) { + switch (setup->wValue) + { case HUB_FEATURE_HUB_C_LOCALPOWER: break; case HUB_FEATURE_HUB_C_OVERCURRENT: @@ -948,7 +1037,8 @@ int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf) } break; case HUB_REQUEST_SET_FEATURE: - switch (setup->wValue) { + switch (setup->wValue) + { case HUB_FEATURE_HUB_C_LOCALPOWER: break; case HUB_FEATURE_HUB_C_OVERCURRENT: @@ -958,7 +1048,7 @@ int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf) } break; case HUB_REQUEST_GET_DESCRIPTOR: - USB_LOG_ERR("HUB_REQUEST_GET_DESCRIPTOR not implmented \n"); + USB_LOG_ERR("HUB_REQUEST_GET_DESCRIPTOR not implmented.\n"); break; case HUB_REQUEST_GET_STATUS: memset(buf, 0, 4); @@ -966,16 +1056,21 @@ int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf) default: break; } - } else if (setup->bmRequestType & USB_REQUEST_RECIPIENT_OTHER) { - switch (setup->bRequest) { + } + else if (setup->bmRequestType & USB_REQUEST_RECIPIENT_OTHER) + { + switch (setup->bRequest) + { case HUB_REQUEST_CLEAR_FEATURE: - if (!port || port > nports) { + if (!port || port > nports) + { return -EPIPE; } portsc = xhci_readl_port(xhci, port - 1, XHCI_REG_OP_PORTS_PORTSC); - switch (setup->wValue) { + switch (setup->wValue) + { case HUB_PORT_FEATURE_ENABLE: break; case HUB_PORT_FEATURE_SUSPEND: @@ -1002,11 +1097,13 @@ int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf) break; case HUB_REQUEST_SET_FEATURE: - if (!port || port > nports) { + if (!port || port > nports) + { return -EPIPE; } - switch (setup->wValue) { + switch (setup->wValue) + { case HUB_PORT_FEATURE_SUSPEND: break; case HUB_PORT_FEATURE_POWER: @@ -1020,57 +1117,69 @@ int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf) } break; case HUB_REQUEST_GET_STATUS: - if (!port || port > nports) { + if (!port || port > nports) + { return -EPIPE; } - + portsc = xhci_readl_port(xhci, port - 1, XHCI_REG_OP_PORTS_PORTSC); status = 0; - if (portsc & XHCI_REG_OP_PORTS_PORTSC_CSC) { + if (portsc & XHCI_REG_OP_PORTS_PORTSC_CSC) + { /* Port connection status changed */ status |= (1 << HUB_PORT_FEATURE_C_CONNECTION); } - if (portsc & XHCI_REG_OP_PORTS_PORTSC_PEC) { + if (portsc & XHCI_REG_OP_PORTS_PORTSC_PEC) + { /* Port enabled status changed */ status |= (1 << HUB_PORT_FEATURE_C_ENABLE); } - if (portsc & XHCI_REG_OP_PORTS_PORTSC_OCC) { + if (portsc & XHCI_REG_OP_PORTS_PORTSC_OCC) + { /* Port status changed due to over-current */ status |= (1 << HUB_PORT_FEATURE_C_OVER_CURREN); } - if (portsc & XHCI_REG_OP_PORTS_PORTSC_CCS) { + if (portsc & XHCI_REG_OP_PORTS_PORTSC_CCS) + { /* Port connected */ status |= (1 << HUB_PORT_FEATURE_CONNECTION); } - - if (portsc & XHCI_REG_OP_PORTS_PORTSC_PED) { + + if (portsc & XHCI_REG_OP_PORTS_PORTSC_PED) + { /* Port enabled */ status |= (1 << HUB_PORT_FEATURE_ENABLE); const int speed = speed_from_xhci[XHCI_REG_OP_PORTS_PORTSC_PORT_SPEED_GET(portsc)]; - if (speed == USB_SPEED_LOW) { + if (speed == USB_SPEED_LOW) + { status |= (1 << HUB_PORT_FEATURE_LOWSPEED); - } else if ((speed == USB_SPEED_HIGH) || (speed == USB_SPEED_SUPER) || - (speed == USB_SPEED_FULL)) { + } + else if ((speed == USB_SPEED_HIGH) || (speed == USB_SPEED_SUPER) || + (speed == USB_SPEED_FULL)) + { status |= (1 << HUB_PORT_FEATURE_HIGHSPEED); } } - if (portsc & XHCI_REG_OP_PORTS_PORTSC_OCA) { + if (portsc & XHCI_REG_OP_PORTS_PORTSC_OCA) + { /* Over-current condition */ status |= (1 << HUB_PORT_FEATURE_OVERCURRENT); } - if (portsc & XHCI_REG_OP_PORTS_PORTSC_PR) { + if (portsc & XHCI_REG_OP_PORTS_PORTSC_PR) + { /* Reset is in progress */ status |= (1 << HUB_PORT_FEATURE_RESET); } - if (portsc & XHCI_REG_OP_PORTS_PORTSC_PP) { + if (portsc & XHCI_REG_OP_PORTS_PORTSC_PP) + { /* Port is not power off */ status |= (1 << HUB_PORT_FEATURE_POWER); } @@ -1097,26 +1206,32 @@ int usbh_ep0_pipe_reconfigure(usbh_pipe_t pipe, uint8_t dev_addr, uint8_t ep_mps struct xhci_pipe *ppipe = (struct xhci_pipe *)pipe; int oldmaxpacket = ppipe->maxpacket; /* original max packetsz */ - if (ep_mps != oldmaxpacket) { + if (ep_mps != oldmaxpacket) + { /* maxpacket has changed on control endpoint - update controller. */ - USB_LOG_DBG("update ep0 mps from %d to %d\r\n", oldmaxpacket, ep_mps); + USB_LOG_DBG("Update ep0 mps from %d to %d.\r\n", oldmaxpacket, ep_mps); struct xhci_inctx *in = xhci_alloc_inctx_set_ep_mps(xhci, ppipe->slotid, ep_mps); /* allocate input context */ if (!in) - return -1; + { + return -1; + } in->add = (1 << 1); /* update ep0 context */ in->del = (1 << 1); usb_hc_dcache_invalidate(in, sizeof(struct xhci_inctx) * XHCI_INCTX_ENTRY_NUM); xhci_dump_input_ctx(xhci, in); - + int cc = xhci_cmd_evaluate_context(xhci, ppipe, in); - if (cc != CC_SUCCESS) { - USB_LOG_ERR("%s: reconf ctl endpoint: failed (cc %d) (mps %d => %d)\n", + if (cc != CC_SUCCESS) + { + USB_LOG_ERR("%s: reconf ctl endpoint: failed (cc %d) (mps %d => %d).\n", __func__, cc, oldmaxpacket, ep_mps); ret = -1; - } else { - ppipe->maxpacket = ep_mps; /* mps update success */ + } + else + { + ppipe->maxpacket = ep_mps; /* mps update success */ } usb_free(in); @@ -1127,9 +1242,10 @@ int usbh_ep0_pipe_reconfigure(usbh_pipe_t pipe, uint8_t dev_addr, uint8_t ep_mps static int usbh_get_period(int speed, int interval) { - if (speed != USB_SPEED_HIGH){ + if (speed != USB_SPEED_HIGH) + { /* fls - find last (most-significant) bit set */ - return (interval <= 4) ? 0 : fls(interval); + return (interval <= 4) ? 0 : fls(interval); } return (interval <= 4) ? 0 : interval - 4; @@ -1145,16 +1261,20 @@ int usbh_pipe_alloc(usbh_pipe_t *pipe, const struct usbh_endpoint_cfg *ep_cfg) uint32_t epid = 0U; uint8_t eptype = 0U; - if (ppipe == NULL) { + if (ppipe == NULL) + { return -ENOMEM; } memset(ppipe, 0, sizeof(struct xhci_pipe)); ppipe->epaddr = ep_cfg->ep_addr; - if (ep_cfg->ep_addr == 0) { + if (ep_cfg->ep_addr == 0) + { epid = 1; /* ep0, ep_id = 1 */ - } else { + } + else + { /* refer to spec. Figure 4-4: Endpoint Context Addressing ep0 = 1, ep1-out = 2, ep1-in = 3, ... ep15-out = 30, ep15-in = 31 */ epid = (ep_cfg->ep_addr & 0x0f) * 2; @@ -1171,23 +1291,27 @@ int usbh_pipe_alloc(usbh_pipe_t *pipe, const struct usbh_endpoint_cfg *ep_cfg) ppipe->waiter = false; ppipe->urb = NULL; - USB_LOG_DBG("%s epid = %d, epaddr = 0x%x eptype = %d, mps = %d, speed = %d, urb = %p\n", - __func__, ppipe->epid, ppipe->epaddr, ppipe->eptype, ppipe->maxpacket, + USB_LOG_DBG("%s epid = %d, epaddr = 0x%x eptype = %d, mps = %d, speed = %d, urb = %p\n", + __func__, ppipe->epid, ppipe->epaddr, ppipe->eptype, ppipe->maxpacket, ppipe->speed, ppipe->urb); - ppipe->reqs.cs = 1; /* cycle state = 1 */ + ppipe->reqs.cs = 1; /* cycle state = 1 */ /* Allocate input context and initialize endpoint info. */ struct xhci_inctx *in = xhci_alloc_inctx_config_ep(xhci, hport, epid); - if (!in){ + if (!in) + { ret = -1; goto fail; } - if (ppipe->epid == 1) { + if (ppipe->epid == 1) + { /* address device */ - in->add = 0x01 /* Slot Context */ | (1 << epid); /* EP Context */ - } else { + in->add = 0x01 /* Slot Context */ | (1 << epid); /* EP Context */ + } + else + { /* config endpoint */ in->add = (1 << epid); in->del = (1 << epid); @@ -1195,8 +1319,10 @@ int usbh_pipe_alloc(usbh_pipe_t *pipe, const struct usbh_endpoint_cfg *ep_cfg) struct xhci_epctx *ep = (void *)&in[(epid + 1) << xhci->context64]; if (eptype == USB_ENDPOINT_TYPE_INTERRUPT) - ep->ctx[0] = XHCI_EPCTX_0_INTERVAL_SET(usbh_get_period(ppipe->speed, ppipe->interval) + 3); /* bit[23:16] for interrupt ep, set interval to control interrupt period */ - + { + ep->ctx[0] = XHCI_EPCTX_0_INTERVAL_SET(usbh_get_period(ppipe->speed, ppipe->interval) + 3); /* bit[23:16] for interrupt ep, set interval to control interrupt period */ + } + /* Value Endpoint Type Direction 0 Not Valid N/A @@ -1210,11 +1336,15 @@ int usbh_pipe_alloc(usbh_pipe_t *pipe, const struct usbh_endpoint_cfg *ep_cfg) */ ep->ctx[1] |= eptype << 3; /* bit[5:3] endpoint type */ if (ppipe->epaddr & USB_EP_DIR_IN || eptype == USB_ENDPOINT_TYPE_CONTROL) - ep->ctx[1] |= 1 << 5; /* ep_type 4 ~ 7 */ - + { + ep->ctx[1] |= 1 << 5; /* ep_type 4 ~ 7 */ + } + ep->ctx[1] |= XHCI_EPCTX_1_MPS_SET(ppipe->maxpacket); /* bit[31:16] max packet size */ if (eptype == USB_ENDPOINT_TYPE_INTERRUPT) + { ep->ctx[1] |= XHCI_EPCTX_1_CERR_SET(3); + } ep->deq_low = (uint32_t)((unsigned long)&ppipe->reqs.ring[0]); /* bit[63:4] tr dequeue pointer */ ep->deq_low |= 1; /* bit[0] dequeue cycle state */ @@ -1224,23 +1354,29 @@ int usbh_pipe_alloc(usbh_pipe_t *pipe, const struct usbh_endpoint_cfg *ep_cfg) ep->deq_high = 0U; #endif - if (eptype == USB_ENDPOINT_TYPE_BULK){ + if (eptype == USB_ENDPOINT_TYPE_BULK) + { ep->length = XHCI_EPCTX_AVE_TRB_LEN_SET(256U); /* bit[15:0] average trb length */ - } else if (eptype == USB_ENDPOINT_TYPE_INTERRUPT){ + } + else if (eptype == USB_ENDPOINT_TYPE_INTERRUPT) + { ep->length = XHCI_EPCTX_AVE_TRB_LEN_SET(16U) | /* bit[15:0] average trb length */ XHCI_EPCTX_MAX_ESIT_SET(ppipe->maxpacket); /* bit[31:16] max ESIT payload */ } - if (ppipe->epid == 1) { /* when allocate ep-0, allocate device first */ + if (ppipe->epid == 1) /* when allocate ep-0, allocate device first */ + { struct usbh_hub *hubdev = hport->parent; - if (!hubdev->is_roothub){ + if (!hubdev->is_roothub) + { /* make sure parent hub has been configured */ struct usbh_hubport *hubport = hubdev->parent; struct xhci_pipe *hubep0 = (struct xhci_pipe *)hubport->ep0; - struct xhci_slotctx *hdslot = (void*)(unsigned long)xhci->devs[hubep0->slotid].ptr_low; - if (XHCI_SLOTCTX_3_SLOT_STATE_GET(hdslot->ctx[3]) != XHCI_SLOT_CONFIG) { /* bit [31:27] slot state, 3 means configured */ - USB_LOG_ERR("%s parent hub-%d not yet configured\n", __func__, hubep0->slotid); + struct xhci_slotctx *hdslot = (void *)(unsigned long)xhci->devs[hubep0->slotid].ptr_low; + if (XHCI_SLOTCTX_3_SLOT_STATE_GET(hdslot->ctx[3]) != XHCI_SLOT_CONFIG) /* bit [31:27] slot state, 3 means configured */ + { + USB_LOG_ERR("%s parent hub-%d not yet configured.\n", __func__, hubep0->slotid); ret = -1; goto fail; } @@ -1249,50 +1385,56 @@ int usbh_pipe_alloc(usbh_pipe_t *pipe, const struct usbh_endpoint_cfg *ep_cfg) /* enable slot. */ size_t size = (sizeof(struct xhci_slotctx) * XHCI_SLOTCTX_ENTRY_NUM) << xhci->context64; struct xhci_slotctx *dev = usb_align(XHCI_SLOTCTX_ALIGMENT << xhci->context64, size); - if (!dev) { - USB_LOG_ERR("allocate memory failed !!!\n"); + if (!dev) + { + USB_LOG_ERR("Allocate memory failed !!!\n"); ret = -1; goto fail; } /* send nop command to test if command ring ok */ - for (int i = 0 ; i < 3; ++i) { + for (int i = 0 ; i < 3; ++i) + { int cc = xhci_cmd_nop(xhci, ppipe); - if (cc != CC_SUCCESS) { + if (cc != CC_SUCCESS) + { USB_LOG_ERR("%s: nop: failed\n", __func__); usb_free(dev); - ret = -1; - goto fail; + ret = -1; + goto fail; } } int slotid = xhci_cmd_enable_slot(xhci, ppipe); /* get slot-id */ - if (slotid < 0) { - USB_LOG_ERR("%s: enable slot: failed\n", __func__); + if (slotid < 0) + { + USB_LOG_ERR("%s: enable slot: failed.\n", __func__); usb_free(dev); ret = -1; goto fail; - } + } ppipe->slotid = slotid; - USB_LOG_DBG("%s: enable slot: got slotid %d\n", __func__, ppipe->slotid); + USB_LOG_DBG("%s: enable slot: got slotid %d.\n", __func__, ppipe->slotid); memset(dev, 0, size); xhci->devs[slotid].ptr_low = (uint32_t)(unsigned long)dev; /* DCBAA */ #ifdef XHCI_AARCH64 xhci->devs[slotid].ptr_high = (uint32_t)((uint64_t)dev >> 32U); #else xhci->devs[slotid].ptr_high = 0; -#endif +#endif usb_hc_dcache_invalidate(in, sizeof(struct xhci_inctx) * XHCI_INCTX_ENTRY_NUM); /* Send set_address command. */ int cc = xhci_cmd_address_device(xhci, ppipe, in); - if (cc != CC_SUCCESS) { - USB_LOG_ERR("%s: address device: failed (cc %d)\n", __func__, cc); + if (cc != CC_SUCCESS) + { + USB_LOG_ERR("%s: address device: failed (cc %d).\n", __func__, cc); cc = xhci_cmd_disable_slot(xhci, ppipe); - if (cc != CC_SUCCESS) { - USB_LOG_ERR("%s: disable failed (cc %d)\n", __func__, cc); + if (cc != CC_SUCCESS) + { + USB_LOG_ERR("%s: disable failed (cc %d).\n", __func__, cc); ret = -1; goto fail; } @@ -1303,14 +1445,17 @@ int usbh_pipe_alloc(usbh_pipe_t *pipe, const struct usbh_endpoint_cfg *ep_cfg) ret = -1; goto fail; - } - } else { /* when allocate other ep, config ep */ + } + } + else /* when allocate other ep, config ep */ + { struct xhci_pipe *defpipe = (struct xhci_pipe *)hport->ep0; ppipe->slotid = defpipe->slotid; /* handle hub device */ struct usb_device_descriptor *device_desc = &hport->device_desc; - if (device_desc->bDeviceClass == USB_DEVICE_CLASS_HUB) { + if (device_desc->bDeviceClass == USB_DEVICE_CLASS_HUB) + { /* enable hub function */ struct usb_interface_descriptor *intf = &hport->config.intf[0U].altsetting[0U].intf_desc; struct usbh_hub *this_hub = hport->config.intf[0U].priv; @@ -1318,26 +1463,27 @@ int usbh_pipe_alloc(usbh_pipe_t *pipe, const struct usbh_endpoint_cfg *ep_cfg) struct usb_hub_descriptor *hub_desc = &this_hub->hub_desc; struct xhci_hubinfo hub_info = {0}; -#define HUB_TT_THINK_TIME(reg) (((reg) >> 5) & 3) +#define HUB_TT_THINK_TIME(reg) (((reg) >> 5) & 3) hub_info.num_of_ports = hub_desc->bNbrPorts; hub_info.has_multiple_tts = (intf->bInterfaceProtocol == 2); hub_info.tt_think_time = ((hub_desc->wHubCharacteristics) & HUB_CHAR_TTTT_MASK) >> HUB_CHAR_TTTT_SHIFT; hub_info.speed = hport->speed; - USB_LOG_INFO("enable hub function, num_of_ports=%d, multi_tt=%d, tt_think=%d, speed=%d\r\n", - hub_info.num_of_ports, - hub_info.has_multiple_tts, - hub_info.tt_think_time, - hub_info.speed); + USB_LOG_INFO("Enable hub function, num_of_ports=%d, multi_tt=%d, tt_think=%d, speed=%d.\r\n", + hub_info.num_of_ports, + hub_info.has_multiple_tts, + hub_info.tt_think_time, + hub_info.speed); struct xhci_inctx *inctx_hub = xhci_alloc_inctx_enable_hub_func(xhci, ppipe->slotid, &hub_info); inctx_hub->add = 0x01; inctx_hub->del = 0x01; usb_hc_dcache_invalidate(in, sizeof(struct xhci_inctx) * XHCI_INCTX_ENTRY_NUM); - if (CC_SUCCESS != xhci_cmd_evaluate_context(xhci, ppipe, inctx_hub)) { - USB_LOG_ERR("cannot enable hub function\r\n"); + if (CC_SUCCESS != xhci_cmd_evaluate_context(xhci, ppipe, inctx_hub)) + { + USB_LOG_ERR("Cannot enable hub function.\r\n"); } usb_free(inctx_hub); @@ -1345,38 +1491,41 @@ int usbh_pipe_alloc(usbh_pipe_t *pipe, const struct usbh_endpoint_cfg *ep_cfg) /* reset if endpoint is not running */ #ifdef XHCI_AARCH64 - struct xhci_slotctx *devctx = (struct xhci_slotctx *)(((uint64_t)xhci->devs[ppipe->slotid].ptr_high << 32U) | - ((uint64_t)xhci->devs[ppipe->slotid].ptr_low)); + struct xhci_slotctx *devctx = (struct xhci_slotctx *)(((uint64_t)xhci->devs[ppipe->slotid].ptr_high << 32U) | + ((uint64_t)xhci->devs[ppipe->slotid].ptr_low)); #else struct xhci_slotctx *devctx = (struct xhci_slotctx *)(unsigned long)xhci->devs[ppipe->slotid].ptr_low; #endif - struct xhci_epctx *epctx = (void*)&devctx[epid << xhci->context64]; /* ep0 context */ + struct xhci_epctx *epctx = (void *)&devctx[epid << xhci->context64]; /* ep0 context */ uint32_t epstate = XHCI_EPCTX_0_EP_STATE_GET(epctx->ctx[0]); int cc; - - /* Reset endpoint in case it is not running */ - if (epstate > 1){ + + /* Reset endpoint in case it is not running */ + if (epstate > 1) + { cc = xhci_cmd_reset_endpoint(xhci, ppipe); - if (cc != CC_SUCCESS) { - USB_LOG_ERR("%s: reset endpoint: failed (cc %d)\n", __func__, cc); + if (cc != CC_SUCCESS) + { + USB_LOG_ERR("%s: reset endpoint: failed (cc %d).\n", __func__, cc); ret = -1; goto fail; - } + } } - + usb_hc_dcache_invalidate(in, sizeof(struct xhci_inctx) * XHCI_INCTX_ENTRY_NUM); xhci_dump_input_ctx(xhci, in); /* Send configure command. */ cc = xhci_cmd_configure_endpoint(xhci, ppipe, in, false); - if (cc != CC_SUCCESS) { - epctx = (void*)&devctx[epid << xhci->context64]; /* ep0 context */ + if (cc != CC_SUCCESS) + { + epctx = (void *)&devctx[epid << xhci->context64]; /* ep0 context */ epstate = XHCI_EPCTX_0_EP_STATE_GET(epctx->ctx[0]); - USB_LOG_ERR("%s: configure endpoint: failed (cc %d, epstate %d)\n", __func__, cc, epstate); + USB_LOG_ERR("%s: configure endpoint: failed (cc %d, epstate %d).\n", __func__, cc, epstate); ret = -1; goto fail; - } + } } *pipe = (usbh_pipe_t)ppipe; @@ -1392,13 +1541,15 @@ int usbh_pipe_free(usbh_pipe_t pipe) struct xhci_s *xhci = &xhci_host; struct xhci_pipe *ppipe = (struct xhci_pipe *)pipe; - if (!ppipe) { + if (!ppipe) + { return -EINVAL; } struct usbh_urb *urb = ppipe->urb; - if (urb) { + if (urb) + { usbh_kill_urb(urb); } @@ -1408,13 +1559,14 @@ int usbh_pipe_free(usbh_pipe_t pipe) int usbh_submit_urb(struct usbh_urb *urb) { int ret = 0; - if (!urb || !urb->pipe) { + if (!urb || !urb->pipe) + { return -EINVAL; } struct xhci_s *xhci = &xhci_host; struct xhci_pipe *ppipe = urb->pipe; - struct usb_setup_packet *setup = urb->setup; + struct usb_setup_packet *setup = urb->setup; size_t flags; flags = usb_osal_enter_critical_section(); @@ -1426,39 +1578,43 @@ int usbh_submit_urb(struct usbh_urb *urb) ppipe->urb = urb; ppipe->timeout = urb->timeout; - if (ppipe->timeout > 0) { + if (ppipe->timeout > 0) + { ppipe->waiter = true; } usb_osal_leave_critical_section(flags); - switch (ppipe->eptype){ + switch (ppipe->eptype) + { case USB_ENDPOINT_TYPE_CONTROL: USB_ASSERT(setup); - if (setup->bRequest == USB_REQUEST_SET_ADDRESS){ + if (setup->bRequest == USB_REQUEST_SET_ADDRESS) + { /* Set address command sent during xhci_alloc_pipe. */ goto skip_req; } - USB_LOG_DBG("%s request-%d\n", __func__, setup->bRequest); + USB_LOG_DBG("%s request-%d.\n", __func__, setup->bRequest); /* send setup in/out for command */ - xhci_xfer_setup(xhci, ppipe, setup->bmRequestType & USB_EP_DIR_IN, (void*)setup, + xhci_xfer_setup(xhci, ppipe, setup->bmRequestType & USB_EP_DIR_IN, (void *)setup, urb->transfer_buffer, urb->transfer_buffer_length); break; - case USB_ENDPOINT_TYPE_INTERRUPT: + case USB_ENDPOINT_TYPE_INTERRUPT: case USB_ENDPOINT_TYPE_BULK: xhci_xfer_normal(xhci, ppipe, urb->transfer_buffer, urb->transfer_buffer_length); break; default: USB_ASSERT(0U); - break; + break; } /* wait all ring handled by xHc */ int cc = xhci_event_wait(xhci, ppipe, &ppipe->reqs); - if ((cc != CC_SUCCESS) && - !((cc == CC_TIMEOUT) && (ppipe->eptype == USB_ENDPOINT_TYPE_INTERRUPT))) { + if ((cc != CC_SUCCESS) && + !((cc == CC_TIMEOUT) && (ppipe->eptype == USB_ENDPOINT_TYPE_INTERRUPT))) + { /* ignore transfer timeout for interrupt type */ - USB_LOG_ERR("%s: xfer failed (cc %d)\n", __func__, cc); + USB_LOG_ERR("%s: xfer failed (cc %d).\n", __func__, cc); ret = -1; urb->errorcode = cc; goto errout_timeout; @@ -1468,7 +1624,7 @@ skip_req: errout_timeout: /* Timeout will run here */ usbh_kill_urb(urb); - return ret; + return ret; } int usbh_kill_urb(struct usbh_urb *urb) @@ -1480,7 +1636,7 @@ void USBH_IRQHandler(void) { uint32_t reg, status; struct xhci_s *xhci = &xhci_host; - struct xhci_pipe *work_pipe = NULL; + struct xhci_pipe *work_pipe = NULL; USB_LOG_DBG("%s\n", __func__); @@ -1495,17 +1651,22 @@ void USBH_IRQHandler(void) work_pipe = xhci_event_process(xhci); /* handle callbacks in interrupt */ - if ((work_pipe) && (work_pipe->urb)) { + if ((work_pipe) && (work_pipe->urb)) + { struct usbh_urb *cur_urb = work_pipe->urb; - if (cur_urb->complete) { - if (cur_urb->errorcode < 0) { + if (cur_urb->complete) + { + if (cur_urb->errorcode < 0) + { cur_urb->complete(cur_urb->arg, cur_urb->errorcode); - } else { + } + else + { cur_urb->complete(cur_urb->arg, cur_urb->actual_length); } - } + } } - USB_LOG_DBG("%s exit\n", __func__); + USB_LOG_DBG("%s exit.\n", __func__); return; } \ No newline at end of file diff --git a/third-party/cherryusb-0.6.0/port/xhci/usb_hc_xhci.h b/third-party/cherryusb-0.6.0/port/xhci/usb_hc_xhci.h index d01c00f2..a3036766 100644 --- a/third-party/cherryusb-0.6.0/port/xhci/usb_hc_xhci.h +++ b/third-party/cherryusb-0.6.0/port/xhci/usb_hc_xhci.h @@ -1,22 +1,22 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: usb_hc_xhci.h * Date: 2022-07-19 09:26:25 * LastEditTime: 2022-07-19 09:26:25 * Description:  This files is for xhci data structure definition - * - * Modify History: + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- * 1.0 zhugengyu 2022/9/19 init commit @@ -27,16 +27,17 @@ /***************************** Include Files *********************************/ #include "usbh_core.h" +/************************** Constant Definitions *****************************/ + +/************************** Type Definitions *****************************/ +/* slot context */ #ifdef __cplusplus extern "C" { #endif -/************************** Constant Definitions *****************************/ - -/************************** Type Definitions *****************************/ -/* slot context */ -struct xhci_slotctx { +struct xhci_slotctx +{ uint32_t ctx[4]; #define XHCI_SLOTCTX_0_ROUTE_SET(route) XHCI32_SET_BITS(route, 19, 0) #define XHCI_SLOTCTX_0_ROUTE_GET(route) XHCI32_GET_BITS(route, 19, 0) @@ -62,47 +63,52 @@ struct xhci_slotctx { #define XHCI_SLOTCTX_ALIGMENT 1024U } __PACKED; -enum xhci_slot_state { +enum xhci_slot_state +{ XHCI_SLOT_DEFAULT = 1, XHCI_SLOT_ADDRESS = 2, XHCI_SLOT_CONFIG = 3 }; /* endpoint context */ -struct xhci_epctx { +struct xhci_epctx +{ uint32_t ctx[2]; #define XHCI_EPCTX_0_EP_STATE_GET(ctx) XHCI32_GET_BITS(ctx, 2, 0) #define XHCI_EPCTX_0_INTERVAL_SET(interval) XHCI32_SET_BITS(interval, 23, 16) -#define XHCI_EPCTX_1_MPS_SET(mps) XHCI32_SET_BITS(mps, 31, 16) +#define XHCI_EPCTX_1_MPS_SET(mps) XHCI32_SET_BITS(mps, 31, 16) #define XHCI_EPCTX_1_MPS_GET(ctx) XHCI32_GET_BITS(ctx, 31, 16) #define XHCI_EPCTX_1_EPTYPE_GET(ctx) XHCI32_GET_BITS(ctx, 5, 3) -#define XHCI_EPCTX_1_CERR_SET(cerr) XHCI32_SET_BITS(cerr, 2, 1) +#define XHCI_EPCTX_1_CERR_SET(cerr) XHCI32_SET_BITS(cerr, 2, 1) uint32_t deq_low; uint32_t deq_high; uint32_t length; -#define XHCI_EPCTX_AVE_TRB_LEN_SET(len) XHCI32_SET_BITS(len, 15, 0) +#define XHCI_EPCTX_AVE_TRB_LEN_SET(len) XHCI32_SET_BITS(len, 15, 0) #define XHCI_EPCTX_MAX_ESIT_SET(esit) XHCI32_SET_BITS(esit, 31, 16) uint32_t reserved_01[3]; } __PACKED; /* device context array element */ -struct xhci_devlist { +struct xhci_devlist +{ uint32_t ptr_low; uint32_t ptr_high; } __PACKED; /* input context */ -struct xhci_inctx { +struct xhci_inctx +{ uint32_t del; uint32_t add; uint32_t reserved_01[6]; -/* refer to spec. The Input Context is an array of up to 33 context data structure entries */ + /* refer to spec. The Input Context is an array of up to 33 context data structure entries */ #define XHCI_INCTX_ENTRY_NUM 33U #define XHCI_INCTX_ALIGMENT 2048 } __PACKED; /* transfer block (ring element) */ -struct xhci_trb { +struct xhci_trb +{ uint32_t ptr_low; uint32_t ptr_high; uint32_t status; @@ -110,19 +116,22 @@ struct xhci_trb { } __PACKED; /* event ring segment */ -struct xhci_er_seg { +struct xhci_er_seg +{ uint32_t ptr_low; uint32_t ptr_high; uint32_t size; uint32_t reserved_01; } __PACKED; -struct xhci_portmap { +struct xhci_portmap +{ uint8_t start; uint8_t count; }; -struct xhci_ring { +struct xhci_ring +{ struct xhci_trb ring[XHCI_RING_ITEMS]; struct xhci_trb evt; uint32_t eidx; @@ -131,7 +140,8 @@ struct xhci_ring { usb_osal_mutex_t lock; }; -struct xhci_pipe { +struct xhci_pipe +{ struct xhci_ring reqs; /* DO NOT MOVE reqs from structure beg */ uint8_t epaddr; uint8_t speed; @@ -151,7 +161,8 @@ struct xhci_pipe { struct usbh_urb *urb; /* NULL if no active URB */ }; -struct xhci_s { +struct xhci_s +{ /* devinfo */ uint32_t ports; uint32_t slots; @@ -178,7 +189,8 @@ struct xhci_s { struct xhci_er_seg *eseg; }; -struct xhci_hubinfo { +struct xhci_hubinfo +{ uint32_t num_of_ports; bool has_multiple_tts; uint8_t tt_think_time; diff --git a/third-party/cherryusb-0.6.0/port/xhci/xhci_reg.h b/third-party/cherryusb-0.6.0/port/xhci/xhci_reg.h index 613dcb33..d45ba1fe 100644 --- a/third-party/cherryusb-0.6.0/port/xhci/xhci_reg.h +++ b/third-party/cherryusb-0.6.0/port/xhci/xhci_reg.h @@ -1,22 +1,22 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: xhci_reg.h * Date: 2022-07-19 09:26:25 * LastEditTime: 2022-07-19 09:26:25 * Description:  This files is for xhci register definition - * - * Modify History: + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- * 1.0 zhugengyu 2022/9/19 init commit @@ -27,12 +27,12 @@ /***************************** Include Files *********************************/ #include "usbh_core.h" +/************************** Constant Definitions *****************************/ #ifdef __cplusplus extern "C" { #endif -/************************** Constant Definitions *****************************/ #if defined(__aarch64__) #define BITS_PER_LONG 64U #define XHCI_AARCH64 @@ -42,11 +42,11 @@ extern "C" #endif #define XHCI_GENMASK(h, l) \ - (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h)))) + (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h)))) #define XHCI_GENMASK_ULL(h, l) \ - (((~0ULL) - (1ULL << (l)) + 1) & \ - (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h)))) + (((~0ULL) - (1ULL << (l)) + 1) & \ + (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h)))) #define XHCI32_GET_BITS(x, a, b) (uint32_t)((((uint32_t)(x)) & XHCI_GENMASK(a, b)) >> b) #define XHCI32_SET_BITS(x, a, b) (uint32_t)((((uint32_t)(x)) << b) & XHCI_GENMASK(a, b)) @@ -58,44 +58,44 @@ extern "C" * Register offsets from the base address of an XHCI device. * @{ */ -#define XHCI_REG_CAP_CAPLENGTH 0x00 /* specify the limits, restrictions and capabilities */ -#define XHCI_REG_CAP_HCIVERSION 0x02 /* Interface Version Number */ -#define XHCI_REG_CAP_HCS1 0x04 /* Host Controller Structural Parameters 1 */ -#define XHCI_REG_CAP_HCS2 0x08 /* Host Controller Structural Parameters 2 */ -#define XHCI_REG_CAP_HCS3 0x0C /* Host Controller Structural Parameters 3 */ -#define XHCI_REG_CAP_HCC 0x10 /* Capability Parameters 1 */ -#define XHCI_REG_CAP_DBOFF 0x14 /* Doorbell Offset Register */ -#define XHCI_REG_CAP_RTSOFF 0x18 /* Runtime Register Space Offset Register */ +#define XHCI_REG_CAP_CAPLENGTH 0x00 /* specify the limits, restrictions and capabilities */ +#define XHCI_REG_CAP_HCIVERSION 0x02 /* Interface Version Number */ +#define XHCI_REG_CAP_HCS1 0x04 /* Host Controller Structural Parameters 1 */ +#define XHCI_REG_CAP_HCS2 0x08 /* Host Controller Structural Parameters 2 */ +#define XHCI_REG_CAP_HCS3 0x0C /* Host Controller Structural Parameters 3 */ +#define XHCI_REG_CAP_HCC 0x10 /* Capability Parameters 1 */ +#define XHCI_REG_CAP_DBOFF 0x14 /* Doorbell Offset Register */ +#define XHCI_REG_CAP_RTSOFF 0x18 /* Runtime Register Space Offset Register */ /***************** Host Controller Operational Registers ***********************/ -#define XHCI_REG_OP_USBCMD 0x00 /* USB Command Register */ -#define XHCI_REG_OP_USBSTS 0x04 /* USB Status Register */ -#define XHCI_REG_OP_PAGESIZE 0x08 /* Page Size Register */ -#define XHCI_REG_OP_DNCTRL 0x14 /* Device Notification Control Register */ -#define XHCI_REG_OP_CRCR 0x18 /* Command Ring Control Register */ -#define XHCI_REG_OP_DCBAAP 0x30 /* Device Context Base Address Array Pointer Register */ -#define XHCI_REG_OP_CONFIG 0x38 /* Configure Register */ +#define XHCI_REG_OP_USBCMD 0x00 /* USB Command Register */ +#define XHCI_REG_OP_USBSTS 0x04 /* USB Status Register */ +#define XHCI_REG_OP_PAGESIZE 0x08 /* Page Size Register */ +#define XHCI_REG_OP_DNCTRL 0x14 /* Device Notification Control Register */ +#define XHCI_REG_OP_CRCR 0x18 /* Command Ring Control Register */ +#define XHCI_REG_OP_DCBAAP 0x30 /* Device Context Base Address Array Pointer Register */ +#define XHCI_REG_OP_CONFIG 0x38 /* Configure Register */ /* Port Status and Ctrl Register : OP Base + (400h + (10h * (n–1))) 'n' is port num */ -#define XHCI_REG_OP_PORTS_BASE 0x400 /* Port Status and Control Register Base */ +#define XHCI_REG_OP_PORTS_BASE 0x400 /* Port Status and Control Register Base */ #define XHCI_REG_OP_PORTS_SIZE 0x10 /* Size of one Port SC Register */ #define XHCI_REG_OP_PORTS_OFF(port, off) ((port) * XHCI_REG_OP_PORTS_SIZE + offset) -#define XHCI_REG_OP_PORTS_PORTSC 0x00 /* Port Status and Control Register */ -#define XHCI_REG_OP_PORTS_PORTPMSC 0x04 /* USB3 Port Power Management Status and Control Register */ -#define XHCI_REG_OP_PORTS_PORTLI 0x08 /* Port Link Info Register */ +#define XHCI_REG_OP_PORTS_PORTSC 0x00 /* Port Status and Control Register */ +#define XHCI_REG_OP_PORTS_PORTPMSC 0x04 /* USB3 Port Power Management Status and Control Register */ +#define XHCI_REG_OP_PORTS_PORTLI 0x08 /* Port Link Info Register */ /***************** Host Controller Runtime Registers ***********************/ -#define XHCI_REG_RT_MFINDEX 0x00 /* Microframe Index */ -#define XHCI_REG_RT_IR0 0x20 /* Interrupter Register Set 0 */ -#define XHCI_REG_RT_IR1023 0x8000 /* Interrupter Register Set 1023 */ +#define XHCI_REG_RT_MFINDEX 0x00 /* Microframe Index */ +#define XHCI_REG_RT_IR0 0x20 /* Interrupter Register Set 0 */ +#define XHCI_REG_RT_IR1023 0x8000 /* Interrupter Register Set 1023 */ /* Interrupter Register Set : RT Base + 020h + (32 * Interrupter) */ -#define XHCI_REG_RT_IR_IMAN 0x00 /* Interrupter Management Register */ -#define XHCI_REG_RT_IR_IMOD 0x04 /* Interrupter Moderation Register */ -#define XHCI_REG_RT_IR_ERSTSZ 0x08 /* Event Ring Segment Table Size Register */ -#define XHCI_REG_RT_IR_ERSTBA 0x10 /* Event Ring Segment Table Base Address Register */ -#define XHCI_REG_RT_IR_ERDP 0x18 /* Event Ring Dequeue Pointer Register */ +#define XHCI_REG_RT_IR_IMAN 0x00 /* Interrupter Management Register */ +#define XHCI_REG_RT_IR_IMOD 0x04 /* Interrupter Moderation Register */ +#define XHCI_REG_RT_IR_ERSTSZ 0x08 /* Event Ring Segment Table Size Register */ +#define XHCI_REG_RT_IR_ERSTBA 0x10 /* Event Ring Segment Table Base Address Register */ +#define XHCI_REG_RT_IR_ERDP 0x18 /* Event Ring Dequeue Pointer Register */ #define XHCI_REG_RT_IR_SIZE 0x20 /* Size of one IR Register */ /***************** Doorbell Register ***********************/ @@ -103,110 +103,111 @@ extern "C" /***************** eXtensible Host Controller Capability Registers ***********************/ -/** @name XHCI_REG_CAP_HCS1 Register +/** @name XHCI_REG_CAP_HCS1 Register */ #define XHCI_REG_CAP_HCS1_MAX_SLOTS_GET(x) XHCI32_GET_BITS(x, 7, 0) /* Number of Device Slots (MaxSlots) */ -#define XHCI_REG_CAP_HCS1_MAX_INTRS_GET(x) XHCI32_GET_BITS(x, 18, 8) /* Number of Interrupters (MaxIntrs) */ -#define XHCI_REG_CAP_HCS1_MAX_PORTS_GET(x) XHCI32_GET_BITS(x, 31, 24) /* Number of Ports (MaxPorts) */ +#define XHCI_REG_CAP_HCS1_MAX_INTRS_GET(x) XHCI32_GET_BITS(x, 18, 8) /* Number of Interrupters (MaxIntrs) */ +#define XHCI_REG_CAP_HCS1_MAX_PORTS_GET(x) XHCI32_GET_BITS(x, 31, 24) /* Number of Ports (MaxPorts) */ -/** @name XHCI_REG_CAP_HCS2 Register +/** @name XHCI_REG_CAP_HCS2 Register */ -#define XHCI_REG_CAP_HCS2_IST_GET(x) XHCI32_GET_BITS(x, 3, 0) /* Isochronous Scheduling Threshold (IST) */ -#define XHCI_REG_CAP_HCS2_ERST_MAX_GET(x) XHCI32_GET_BITS(x, 7, 4) /* Event Ring Segment Table Max (ERST Max) */ -#define XHCI_REG_CAP_HCS2_SPR (1 << 26) /* Scratchpad Restore (SPR) */ -#define XHCI_REG_CAP_HCS2_MAX_SCRATCHPAD_BUFS_GET(x) XHCI32_GET_BITS(x, 25, 21) | XHCI32_GET_BITS(x, 31, 27) /* Max Scratchpad Buffers (Max Scratchpad Bufs) */ +#define XHCI_REG_CAP_HCS2_IST_GET(x) XHCI32_GET_BITS(x, 3, 0) /* Isochronous Scheduling Threshold (IST) */ +#define XHCI_REG_CAP_HCS2_ERST_MAX_GET(x) XHCI32_GET_BITS(x, 7, 4) /* Event Ring Segment Table Max (ERST Max) */ +#define XHCI_REG_CAP_HCS2_SPR (1 << 26) /* Scratchpad Restore (SPR) */ +#define XHCI_REG_CAP_HCS2_MAX_SCRATCHPAD_BUFS_GET(x) XHCI32_GET_BITS(x, 25, 21) | XHCI32_GET_BITS(x, 31, 27) /* Max Scratchpad Buffers (Max Scratchpad Bufs) */ -/** @name XHCI_REG_CAP_HCS3 Register +/** @name XHCI_REG_CAP_HCS3 Register */ -#define XHCI_REG_CAP_HCS3_U1_DEV_EXIT_LATENCY_GET(x) XHCI32_GET_BITS(x, 7, 0) /* U1 Device Exit Latency */ -#define XHCI_REG_CAP_HCS3_U2_DEV_EXIT_LATENCY_GET(x) XHCI32_GET_BITS(x, 31, 16) /* U2 Device Exit Latency */ +#define XHCI_REG_CAP_HCS3_U1_DEV_EXIT_LATENCY_GET(x) XHCI32_GET_BITS(x, 7, 0) /* U1 Device Exit Latency */ +#define XHCI_REG_CAP_HCS3_U2_DEV_EXIT_LATENCY_GET(x) XHCI32_GET_BITS(x, 31, 16) /* U2 Device Exit Latency */ -/** @name XHCI_REG_CAP_HCC Register +/** @name XHCI_REG_CAP_HCC Register */ -#define XHCI_REG_CAP_HCC_AC64 (1 << 0) /* 64-bit Addressing Capabilitya 1: 64-bit */ -#define XHCI_REG_CAP_HCC_BNC (1 << 1) /* BW Negotiation Capability (BNC) 1: support */ -#define XHCI_REG_CAP_HCC_CSZ (1 << 2) /* Context Size (CSZ) 1: 64 byte context data */ -#define XHCI_REG_CAP_HCC_PPC (1 << 3) /* Port Power Control (PPC) 1: support */ -#define XHCI_REG_CAP_HCC_PIND (1 << 4) /* Port Indicators (PIND) 1: support */ -#define XHCI_REG_CAP_HCC_LHRC (1 << 5) /* Light HC Reset Capability (LHRC) 1: support */ -#define XHCI_REG_CAP_HCC_LTC (1 << 6) /* Latency Tolerance Messaging Capability (LTC) */ -#define XHCI_REG_CAP_HCC_NSS (1 << 7) /* No Secondary SID Support (NSS) */ -#define XHCI_REG_CAP_HCC_MAX_PSA_SIZE_GET(x) XHCI32_GET_BITS(x, 15, 12) /* Maximum Primary Stream Array Size (MaxPSASize) */ -#define XHCI_REG_CAP_HCC_XECP_GET(x) XHCI32_GET_BITS(x, 31, 16) /* xHCI Extended Capabilities Pointer (xECP) */ - -/** @name XHCI_REG_CAP_DBOFF Register +#define XHCI_REG_CAP_HCC_AC64 (1 << 0) /* 64-bit Addressing Capabilitya 1: 64-bit */ +#define XHCI_REG_CAP_HCC_BNC (1 << 1) /* BW Negotiation Capability (BNC) 1: support */ +#define XHCI_REG_CAP_HCC_CSZ (1 << 2) /* Context Size (CSZ) 1: 64 byte context data */ +#define XHCI_REG_CAP_HCC_PPC (1 << 3) /* Port Power Control (PPC) 1: support */ +#define XHCI_REG_CAP_HCC_PIND (1 << 4) /* Port Indicators (PIND) 1: support */ +#define XHCI_REG_CAP_HCC_LHRC (1 << 5) /* Light HC Reset Capability (LHRC) 1: support */ +#define XHCI_REG_CAP_HCC_LTC (1 << 6) /* Latency Tolerance Messaging Capability (LTC) */ +#define XHCI_REG_CAP_HCC_NSS (1 << 7) /* No Secondary SID Support (NSS) */ +#define XHCI_REG_CAP_HCC_MAX_PSA_SIZE_GET(x) XHCI32_GET_BITS(x, 15, 12) /* Maximum Primary Stream Array Size (MaxPSASize) */ +#define XHCI_REG_CAP_HCC_XECP_GET(x) XHCI32_GET_BITS(x, 31, 16) /* xHCI Extended Capabilities Pointer (xECP) */ + +/** @name XHCI_REG_CAP_DBOFF Register */ #define XHCI_REG_CAP_DBOFF_GET(x) ((x) & XHCI_GENMASK(31, 2)) /* 32-byte offset of the Doorbell Array base address from the Base */ -/** @name XHCI_REG_CAP_RTSOFF Register +/** @name XHCI_REG_CAP_RTSOFF Register */ #define XHCI_REG_CAP_RTSOFF_GET(x) ((x) & XHCI_GENMASK(31, 5)) /* 32-byte offset of the xHCI Runtime Registers */ /***************** Host Controller Operational Registers ***********************/ -/** @name XHCI_REG_OP_USBCMD Register +/** @name XHCI_REG_OP_USBCMD Register */ -#define XHCI_REG_OP_USBCMD_RUN_STOP (1 << 0) /* Run/Stop (R/S) 1: RUN, 0: STOP - RW */ -#define XHCI_REG_OP_USBCMD_HCRST (1 << 1) /* Host Controller Reset (HCRST) 1: RESET - RW */ -#define XHCI_REG_OP_USBCMD_INTE (1 << 2) /* Interrupter Enable (INTE) 1: enabled - RW */ -#define XHCI_REG_OP_USBCMD_HSEE (1 << 3) /* Host System Error Enable (HSEE) - RW */ -#define XHCI_REG_OP_USBCMD_LHCRST (1 << 7) /* Light Host Controller Reset (LHCRST) - RW */ -#define XHCI_REG_OP_USBCMD_CSS (1 << 8) /* Controller Save State (CSS) - RW */ -#define XHCI_REG_OP_USBCMD_CRS (1 << 9) /* Controller Restore State (CRS) - RW */ -#define XHCI_REG_OP_USBCMD_EWE (1 << 10) /* Enable Wrap Event (EWE) - RW */ -#define XHCI_REG_OP_USBCMD_EU3S (1 << 11) /* Enable U3 MFINDEX Stop (EU3S) - RW */ - -/** @name XHCI_REG_OP_USBSTS Register +#define XHCI_REG_OP_USBCMD_RUN_STOP (1 << 0) /* Run/Stop (R/S) 1: RUN, 0: STOP - RW */ +#define XHCI_REG_OP_USBCMD_HCRST (1 << 1) /* Host Controller Reset (HCRST) 1: RESET - RW */ +#define XHCI_REG_OP_USBCMD_INTE (1 << 2) /* Interrupter Enable (INTE) 1: enabled - RW */ +#define XHCI_REG_OP_USBCMD_HSEE (1 << 3) /* Host System Error Enable (HSEE) - RW */ +#define XHCI_REG_OP_USBCMD_LHCRST (1 << 7) /* Light Host Controller Reset (LHCRST) - RW */ +#define XHCI_REG_OP_USBCMD_CSS (1 << 8) /* Controller Save State (CSS) - RW */ +#define XHCI_REG_OP_USBCMD_CRS (1 << 9) /* Controller Restore State (CRS) - RW */ +#define XHCI_REG_OP_USBCMD_EWE (1 << 10) /* Enable Wrap Event (EWE) - RW */ +#define XHCI_REG_OP_USBCMD_EU3S (1 << 11) /* Enable U3 MFINDEX Stop (EU3S) - RW */ + +/** @name XHCI_REG_OP_USBSTS Register */ -#define XHCI_REG_OP_USBSTS_HCH (1 << 0) /* 1: Stopped executing */ -#define XHCI_REG_OP_USBSTS_HSE (1 << 2) /* 1: Serious error detected */ -#define XHCI_REG_OP_USBSTS_EINT (1 << 3) /* 1: Interrupt Pending (IP) */ -#define XHCI_REG_OP_USBSTS_PCD (1 << 4) /* 1: Port Change Detect */ -#define XHCI_REG_OP_USBSTS_SSS (1 << 8) /* remain 1 while the xHC saves its internal state */ -#define XHCI_REG_OP_USBSTS_RSS (1 << 9) /* remain 1 while the xHC restores its internal state */ -#define XHCI_REG_OP_USBSTS_SRE (1 << 10) /* if error occurs during a Save or Restore operation this bit shall be set to ‘1’. */ -#define XHCI_REG_OP_USBSTS_CNR (1 << 11) /* 1: Controller Not Ready */ -#define XHCI_REG_OP_USBSTS_HCE (1 << 12) /* 1: Internal xHC error condition */ -#define XHCI_REG_OP_USBSTS_PRSRV_MASK ((1 << 1) | 0xffffe000) /* Rsvd bits */ - - -/** @name XHCI_REG_OP_PAGESIZE Register +#define XHCI_REG_OP_USBSTS_HCH (1 << 0) /* 1: Stopped executing */ +#define XHCI_REG_OP_USBSTS_HSE (1 << 2) /* 1: Serious error detected */ +#define XHCI_REG_OP_USBSTS_EINT (1 << 3) /* 1: Interrupt Pending (IP) */ +#define XHCI_REG_OP_USBSTS_PCD (1 << 4) /* 1: Port Change Detect */ +#define XHCI_REG_OP_USBSTS_SSS (1 << 8) /* remain 1 while the xHC saves its internal state */ +#define XHCI_REG_OP_USBSTS_RSS (1 << 9) /* remain 1 while the xHC restores its internal state */ +#define XHCI_REG_OP_USBSTS_SRE (1 << 10) /* if error occurs during a Save or Restore operation this bit shall be set to ‘1’. */ +#define XHCI_REG_OP_USBSTS_CNR (1 << 11) /* 1: Controller Not Ready */ +#define XHCI_REG_OP_USBSTS_HCE (1 << 12) /* 1: Internal xHC error condition */ +#define XHCI_REG_OP_USBSTS_PRSRV_MASK ((1 << 1) | 0xffffe000) /* Rsvd bits */ + + +/** @name XHCI_REG_OP_PAGESIZE Register */ /* This xHC supports a page size of 2^(n+12) if bit n is Set */ -#define XHCI_REG_OP_PAGESIZE_4K (1 << 0) /* if bit 0 is Set, the xHC supports 4k byte page sizes */ +#define XHCI_REG_OP_PAGESIZE_4K (1 << 0) /* if bit 0 is Set, the xHC supports 4k byte page sizes */ -/** @name XHCI_REG_OP_CRCR Register +/** @name XHCI_REG_OP_CRCR Register */ -#define XHCI_REG_OP_CRCR_RCS (1 << 0) /* Ring Cycle State, value of the xHC Consumer Cycle State (CCS) flag */ -#define XHCI_REG_OP_CRCR_CS (1 << 1) /* Command Stop, 1 */ -#define XHCI_REG_OP_CRCR_CA (1 << 2) /* Command Abort, 1 */ -#define XHCI_REG_OP_CRCR_CRR (1 << 3) /* Command Ring Running */ -#define XHCI_REG_OP_CRCR_CR_PTR_MASK XHCI_GENMASK_ULL(63, 6) /* Command Ring Pointer, Dequeue Ptr of Command Ring */ +#define XHCI_REG_OP_CRCR_RCS (1 << 0) /* Ring Cycle State, value of the xHC Consumer Cycle State (CCS) flag */ +#define XHCI_REG_OP_CRCR_CS (1 << 1) /* Command Stop, 1 */ +#define XHCI_REG_OP_CRCR_CA (1 << 2) /* Command Abort, 1 */ +#define XHCI_REG_OP_CRCR_CRR (1 << 3) /* Command Ring Running */ +#define XHCI_REG_OP_CRCR_CR_PTR_MASK XHCI_GENMASK_ULL(63, 6) /* Command Ring Pointer, Dequeue Ptr of Command Ring */ -/** @name XHCI_REG_OP_DCBAAP Register +/** @name XHCI_REG_OP_DCBAAP Register */ -#define XHCI_REG_OP_DCBAAP_MASK XHCI_GENMASK_ULL(63, 6) /* bit[31:6] Ptr of DCBAA */ +#define XHCI_REG_OP_DCBAAP_MASK XHCI_GENMASK_ULL(63, 6) /* bit[31:6] Ptr of DCBAA */ -/** @name XHCI_REG_OP_CONFIG Register +/** @name XHCI_REG_OP_CONFIG Register */ #define XHCI_REG_OP_CONFIG_MAX_SLOTS_EN_MASK XHCI_GENMASK(7, 0) /* Max Device Slots Enabled (MaxSlotsEn) – RW */ -#define XHCI_REG_OP_CONFIG_MAX_SLOTS_EN_SET(x) XHCI32_SET_BITS(x, 7, 0) /* bit[7:0] Max Device Slots Enabled */ +#define XHCI_REG_OP_CONFIG_MAX_SLOTS_EN_SET(x) XHCI32_SET_BITS(x, 7, 0) /* bit[7:0] Max Device Slots Enabled */ #define XHCI_REG_OP_CONFIG_MAX_SLOTS_EN_GET(x) XHCI32_GET_BITS(x, 7, 0) -/** @name XHCI_REG_OP_PORTS_PORTSC Register +/** @name XHCI_REG_OP_PORTS_PORTSC Register */ -#define XHCI_REG_OP_PORTS_PORTSC_CCS (1 << 0) /* Current Connect Status (CCS) – ROS */ -#define XHCI_REG_OP_PORTS_PORTSC_PED (1 << 1) /* Port Enabled/Disabled (PED) – RW1CS */ -#define XHCI_REG_OP_PORTS_PORTSC_OCA (1 << 3) /* Over-current Active (OCA) – RO */ -#define XHCI_REG_OP_PORTS_PORTSC_PR (1 << 4) /* Port Reset (PR) – RW1S */ -#define XHCI_REG_OP_PORTS_PORTSC_PLS_GET(x) XHCI32_GET_BITS(x, 8, 5) /* Port Link State (PLS) – RWS */ -#define XHCI_REG_OP_PORTS_PORTSC_PLS_SET(x) XHCI32_SET_BITS(x, 8, 5) -#define XHCI_REG_OP_PORTS_PORTSC_PLS_MASK XHCI_GENMASK(8, 5) -#define XHCI_REG_OP_PORTS_PORTSC_PLS(x) (x << 5) -#define XHCI_REG_OP_PORTS_PORTSC_PLS_SET(x) XHCI32_SET_BITS(x, 8, 5) - -enum PLSStatus{ +#define XHCI_REG_OP_PORTS_PORTSC_CCS (1 << 0) /* Current Connect Status (CCS) – ROS */ +#define XHCI_REG_OP_PORTS_PORTSC_PED (1 << 1) /* Port Enabled/Disabled (PED) – RW1CS */ +#define XHCI_REG_OP_PORTS_PORTSC_OCA (1 << 3) /* Over-current Active (OCA) – RO */ +#define XHCI_REG_OP_PORTS_PORTSC_PR (1 << 4) /* Port Reset (PR) – RW1S */ +#define XHCI_REG_OP_PORTS_PORTSC_PLS_GET(x) XHCI32_GET_BITS(x, 8, 5) /* Port Link State (PLS) – RWS */ +#define XHCI_REG_OP_PORTS_PORTSC_PLS_SET(x) XHCI32_SET_BITS(x, 8, 5) +#define XHCI_REG_OP_PORTS_PORTSC_PLS_MASK XHCI_GENMASK(8, 5) +#define XHCI_REG_OP_PORTS_PORTSC_PLS(x) (x << 5) +#define XHCI_REG_OP_PORTS_PORTSC_PLS_SET(x) XHCI32_SET_BITS(x, 8, 5) + +enum PLSStatus +{ PLS_U0 = 0, PLS_U1 = 1, PLS_U2 = 2, @@ -222,105 +223,105 @@ enum PLSStatus{ PLS_RESUME = 15, }; /* Port status type */ -#define XHCI_REG_OP_PORTS_PORTSC_PP (1 << 9) /* Port Power (PP) – RWS */ -#define XHCI_REG_OP_PORTS_PORTSC_PORT_SPEED_GET(x) XHCI32_GET_BITS(x, 13, 10) /* Port Speed (Port Speed) – ROS */ +#define XHCI_REG_OP_PORTS_PORTSC_PP (1 << 9) /* Port Power (PP) – RWS */ +#define XHCI_REG_OP_PORTS_PORTSC_PORT_SPEED_GET(x) XHCI32_GET_BITS(x, 13, 10) /* Port Speed (Port Speed) – ROS */ /* Protocol Speed ID (PSI) */ -#define XHCI_PORT_SPEED_UNKOWN 0U -#define XHCI_PORT_SPEED_FULL 1U -#define XHCI_PORT_SPEED_LOW 2U -#define XHCI_PORT_SPEED_HIGH 3U -#define XHCI_PORT_SPEED_SUPER 4U +#define XHCI_PORT_SPEED_UNKOWN 0U +#define XHCI_PORT_SPEED_FULL 1U +#define XHCI_PORT_SPEED_LOW 2U +#define XHCI_PORT_SPEED_HIGH 3U +#define XHCI_PORT_SPEED_SUPER 4U #define XHCI_REG_OP_PORTS_PORTSC_PIC_SET(x) XHCI32_SET_BITS(x, 15, 14) -#define XHCI_REG_OP_PORTS_PORTSC_PIC_MASK XHCI_GENMASK(15, 14) - -#define XHCI_REG_OP_PORTS_PORTSC_LWS (1 << 16) /* Port Link State Write Strobe (LWS) */ -#define XHCI_REG_OP_PORTS_PORTSC_CSC (1 << 17) /* Connect Status Change (CSC) */ -#define XHCI_REG_OP_PORTS_PORTSC_PEC (1 << 18) /* Port Enabled/Disabled Change (PEC) 1: clear PED */ -#define XHCI_REG_OP_PORTS_PORTSC_WRC (1 << 19) /* Warm Port Reset Change 1: Warm Reset complete */ -#define XHCI_REG_OP_PORTS_PORTSC_OCC (1 << 20) /* Over-current Change 1: Over-current Active */ -#define XHCI_REG_OP_PORTS_PORTSC_PRC (1 << 21) /* Port Reset Change 1: Transition of Port Reset */ -#define XHCI_REG_OP_PORTS_PORTSC_PLC (1 << 22) /* Port Link State Change 1: PLS transition */ -#define XHCI_REG_OP_PORTS_PORTSC_CEC (1 << 23) /* Port Config Error Change 1: Port Config Error detected */ -#define XHCI_REG_OP_PORTS_PORTSC_CAS (1 << 24) /* Cold Attach Status 1: Far-end Receiver Terminations were detected */ -#define XHCI_REG_OP_PORTS_PORTSC_WCE (1 << 25) /* Wake on Connect Enable 1: enable port to be sensitive to device connects */ -#define XHCI_REG_OP_PORTS_PORTSC_WDE (1 << 26) /* Wake on Disconnect Enable 1: enable port to be sensitive to device disconnects */ -#define XHCI_REG_OP_PORTS_PORTSC_WOE (1 << 27) /* Wake on Over-current Enable 1: enable port to be sensitive to over-current conditions */ -#define XHCI_REG_OP_PORTS_PORTSC_DR (1 << 30) /* Device Removable, 0: Device is removable. 1: Device is non-removable */ -#define XHCI_REG_OP_PORTS_PORTSC_WPR (1 << 31) /* Warm Port Reset 1: follow Warm Reset sequence */ +#define XHCI_REG_OP_PORTS_PORTSC_PIC_MASK XHCI_GENMASK(15, 14) + +#define XHCI_REG_OP_PORTS_PORTSC_LWS (1 << 16) /* Port Link State Write Strobe (LWS) */ +#define XHCI_REG_OP_PORTS_PORTSC_CSC (1 << 17) /* Connect Status Change (CSC) */ +#define XHCI_REG_OP_PORTS_PORTSC_PEC (1 << 18) /* Port Enabled/Disabled Change (PEC) 1: clear PED */ +#define XHCI_REG_OP_PORTS_PORTSC_WRC (1 << 19) /* Warm Port Reset Change 1: Warm Reset complete */ +#define XHCI_REG_OP_PORTS_PORTSC_OCC (1 << 20) /* Over-current Change 1: Over-current Active */ +#define XHCI_REG_OP_PORTS_PORTSC_PRC (1 << 21) /* Port Reset Change 1: Transition of Port Reset */ +#define XHCI_REG_OP_PORTS_PORTSC_PLC (1 << 22) /* Port Link State Change 1: PLS transition */ +#define XHCI_REG_OP_PORTS_PORTSC_CEC (1 << 23) /* Port Config Error Change 1: Port Config Error detected */ +#define XHCI_REG_OP_PORTS_PORTSC_CAS (1 << 24) /* Cold Attach Status 1: Far-end Receiver Terminations were detected */ +#define XHCI_REG_OP_PORTS_PORTSC_WCE (1 << 25) /* Wake on Connect Enable 1: enable port to be sensitive to device connects */ +#define XHCI_REG_OP_PORTS_PORTSC_WDE (1 << 26) /* Wake on Disconnect Enable 1: enable port to be sensitive to device disconnects */ +#define XHCI_REG_OP_PORTS_PORTSC_WOE (1 << 27) /* Wake on Over-current Enable 1: enable port to be sensitive to over-current conditions */ +#define XHCI_REG_OP_PORTS_PORTSC_DR (1 << 30) /* Device Removable, 0: Device is removable. 1: Device is non-removable */ +#define XHCI_REG_OP_PORTS_PORTSC_WPR (1 << 31) /* Warm Port Reset 1: follow Warm Reset sequence */ #define XHCI_REG_OP_PORTS_PORTSC_RW_MASK (XHCI_REG_OP_PORTS_PORTSC_PR | XHCI_REG_OP_PORTS_PORTSC_PLS_MASK | XHCI_REG_OP_PORTS_PORTSC_PP \ - | XHCI_REG_OP_PORTS_PORTSC_PIC_MASK | XHCI_REG_OP_PORTS_PORTSC_LWS | XHCI_REG_OP_PORTS_PORTSC_WCE \ - | XHCI_REG_OP_PORTS_PORTSC_WDE | XHCI_REG_OP_PORTS_PORTSC_WOE) + | XHCI_REG_OP_PORTS_PORTSC_PIC_MASK | XHCI_REG_OP_PORTS_PORTSC_LWS | XHCI_REG_OP_PORTS_PORTSC_WCE \ + | XHCI_REG_OP_PORTS_PORTSC_WDE | XHCI_REG_OP_PORTS_PORTSC_WOE) /***************** Host Controller Runtime Registers ***********************/ -/** @name XHCI_REG_RT_IR_IMAN Register +/** @name XHCI_REG_RT_IR_IMAN Register */ -#define XHCI_REG_RT_IR_IMAN_IP (1 << 0) /* Interrupt Pending, 1: an interrupt is pending for this Interrupter */ -#define XHCI_REG_RT_IR_IMAN_IE (1 << 1) /* Interrupt Enable, 1: capable of generating an interrupt. */ +#define XHCI_REG_RT_IR_IMAN_IP (1 << 0) /* Interrupt Pending, 1: an interrupt is pending for this Interrupter */ +#define XHCI_REG_RT_IR_IMAN_IE (1 << 1) /* Interrupt Enable, 1: capable of generating an interrupt. */ -/** @name XHCI_REG_RT_IR_IMOD Register +/** @name XHCI_REG_RT_IR_IMOD Register */ -#define XHCI_REG_RT_IR_IMOD_IMODI_MASK XHCI_GENMASK(15, 0) /* bit[15:0] Interrupt Moderation Interval default 4000 ==> 1ms */ -#define XHCI_REG_RT_IR_IMOD_IMODC_MASK XHCI_GENMASK(31, 16) /* bit[31:16] Interrupt Moderation Counter(Down counter) */ +#define XHCI_REG_RT_IR_IMOD_IMODI_MASK XHCI_GENMASK(15, 0) /* bit[15:0] Interrupt Moderation Interval default 4000 ==> 1ms */ +#define XHCI_REG_RT_IR_IMOD_IMODC_MASK XHCI_GENMASK(31, 16) /* bit[31:16] Interrupt Moderation Counter(Down counter) */ -/** @name XHCI_REG_RT_IR_ERSTSZ Register +/** @name XHCI_REG_RT_IR_ERSTSZ Register */ -#define XHCI_REG_RT_IR_ERSTSZ_MASK XHCI_GENMASK(15, 0) /* bit[15:0] the number of valid Event Ring Segment Table entries */ +#define XHCI_REG_RT_IR_ERSTSZ_MASK XHCI_GENMASK(15, 0) /* bit[15:0] the number of valid Event Ring Segment Table entries */ -/** @name XHCI_REG_RT_IR_ERSTBA Register +/** @name XHCI_REG_RT_IR_ERSTBA Register */ -#define XHCI_REG_RT_IR_ERSTBA_MASK XHCI_GENMASK_ULL(63, 6) /* Event Ring Segment Table Base Address */ +#define XHCI_REG_RT_IR_ERSTBA_MASK XHCI_GENMASK_ULL(63, 6) /* Event Ring Segment Table Base Address */ -/** @name XHCI_REG_RT_IR_ERDP Register +/** @name XHCI_REG_RT_IR_ERDP Register */ -#define XHCI_REG_RT_IR_ERDP_DESI_MASK XHCI_GENMASK_ULL(2, 0) /* bit[2:0] Dequeue ERST Segment Index */ -#define XHCI_REG_RT_IR_ERDP_EHB (1 << 3) /* Event Handler Busy */ -#define XHCI_REG_RT_IR_ERDP_MASK XHCI_GENMASK_ULL(63, 4) /* Event Ring Dequeue Pointer */ +#define XHCI_REG_RT_IR_ERDP_DESI_MASK XHCI_GENMASK_ULL(2, 0) /* bit[2:0] Dequeue ERST Segment Index */ +#define XHCI_REG_RT_IR_ERDP_EHB (1 << 3) /* Event Handler Busy */ +#define XHCI_REG_RT_IR_ERDP_MASK XHCI_GENMASK_ULL(63, 4) /* Event Ring Dequeue Pointer */ /***************** Doorbell Register ***********************/ -#define XHCI_REG_DB_TARGET_HC_COMMAND 0 /* Host Controller Doorbell (0) Command Doorbell */ -#define XHCI_REG_DB_TARGET_EP0 1 /* Device Context Doorbells Control EP 0 Enqueue Pointer Update */ -#define XHCI_REG_DB_TARGET_EP1_OUT 2 /* EP 1 OUT Enqueue Pointer Update */ -#define XHCI_REG_DB_TARGET_EP1_IN 3 /* EP 1 IN Enqueue Pointer Update */ -#define XHCI_REG_DB_TARGET_EP15_OUT 30 /* EP 15 OUT Enqueue Pointer Update */ -#define XHCI_REG_DB_TARGET_EP15_IN 31 /* EP 15 IN Enqueue Pointer Update */ +#define XHCI_REG_DB_TARGET_HC_COMMAND 0 /* Host Controller Doorbell (0) Command Doorbell */ +#define XHCI_REG_DB_TARGET_EP0 1 /* Device Context Doorbells Control EP 0 Enqueue Pointer Update */ +#define XHCI_REG_DB_TARGET_EP1_OUT 2 /* EP 1 OUT Enqueue Pointer Update */ +#define XHCI_REG_DB_TARGET_EP1_IN 3 /* EP 1 IN Enqueue Pointer Update */ +#define XHCI_REG_DB_TARGET_EP15_OUT 30 /* EP 15 OUT Enqueue Pointer Update */ +#define XHCI_REG_DB_TARGET_EP15_IN 31 /* EP 15 IN Enqueue Pointer Update */ /***************** xHCI Extended Capabilities Registers ***********************/ -#define XHCI_REG_EXT_CAP_USBSPCF_OFFSET 0x0 -#define XHCI_REG_EXT_CAP_CAP_ID_GET(x) XHCI32_GET_BITS(x, 7, 0) +#define XHCI_REG_EXT_CAP_USBSPCF_OFFSET 0x0 +#define XHCI_REG_EXT_CAP_CAP_ID_GET(x) XHCI32_GET_BITS(x, 7, 0) #define XHCI_REG_EXT_NEXT_CAP_PTR_GET(x) XHCI32_GET_BITS(x, 15, 8) /* refer to 'Table 138: xHCI Extended Capability Codes' for more details */ enum { - XHCI_EXT_CAP_ID_USB_LEGACY_SUPPORT = 1, - XHCI_EXT_CAP_ID_SUPPORT_PROTOCOL = 2, - XHCI_EXT_CAP_ID_EXTEND_POWER_MANAGEMENT = 3, - XHCI_EXT_CAP_ID_IO_VIRTUALIZATION = 4, - XHCI_EXT_CAP_ID_MESSAGE_INTERRUPT = 5, - XHCI_EXT_CAP_ID_LOCAL_MEMORY = 6, - XHCI_EXT_CAP_ID_USB_DEBUG_CAPABILITY = 10, - XHCI_EXT_CAP_ID_EXT_MESSAGE_INTERRUPT = 17, - - XHCI_EXT_CAP_ID_VENDOR_DEFINED_MIN = 192, - XHCI_EXT_CAP_ID_VENDOR_DEFINED_MAX = 255 + XHCI_EXT_CAP_ID_USB_LEGACY_SUPPORT = 1, + XHCI_EXT_CAP_ID_SUPPORT_PROTOCOL = 2, + XHCI_EXT_CAP_ID_EXTEND_POWER_MANAGEMENT = 3, + XHCI_EXT_CAP_ID_IO_VIRTUALIZATION = 4, + XHCI_EXT_CAP_ID_MESSAGE_INTERRUPT = 5, + XHCI_EXT_CAP_ID_LOCAL_MEMORY = 6, + XHCI_EXT_CAP_ID_USB_DEBUG_CAPABILITY = 10, + XHCI_EXT_CAP_ID_EXT_MESSAGE_INTERRUPT = 17, + + XHCI_EXT_CAP_ID_VENDOR_DEFINED_MIN = 192, + XHCI_EXT_CAP_ID_VENDOR_DEFINED_MAX = 255 }; /* xHCI Supported Protocol Capability */ -#define XHCI_REG_EXT_CAP_USBSPCFDEF_OFFSET 0x4 +#define XHCI_REG_EXT_CAP_USBSPCFDEF_OFFSET 0x4 -#define XHCI_USBSPCF_MINOR_REVERSION_GET(x) XHCI32_GET_BITS(x, 23, 16) -#define XHCI_USBSPCF_MAJOR_REVERSION_GET(x) XHCI32_GET_BITS(x, 31, 24) +#define XHCI_USBSPCF_MINOR_REVERSION_GET(x) XHCI32_GET_BITS(x, 23, 16) +#define XHCI_USBSPCF_MAJOR_REVERSION_GET(x) XHCI32_GET_BITS(x, 31, 24) -#define XHCI_USBSPCFDEF_NAME_STRING_GET(x) XHCI32_GET_BITS(x, 31, 0) /* four ASCII characters may be defined */ -#define XHCI_USBSPCFDEF_NAME_STRING_USB 0x20425355 /* ASCII = "USB" */ +#define XHCI_USBSPCFDEF_NAME_STRING_GET(x) XHCI32_GET_BITS(x, 31, 0) /* four ASCII characters may be defined */ +#define XHCI_USBSPCFDEF_NAME_STRING_USB 0x20425355 /* ASCII = "USB" */ -#define XHCI_REG_EXT_CAP_USBSPCFDEF2_OFFSET 0x8 +#define XHCI_REG_EXT_CAP_USBSPCFDEF2_OFFSET 0x8 #define XHCI_USBSPCFDEF2_COMPATIBLE_PORT_OFF_GET(x) XHCI32_GET_BITS(x, 7, 0) #define XHCI_USBSPCFDEF2_COMPATIBLE_PORT_CNT_GET(x) XHCI32_GET_BITS(x, 15, 8) -#define XHCI_USBSPCFDEF2_PROTOCOL_DEFINED_GET(x) XHCI32_GET_BITS(x, 27, 16) +#define XHCI_USBSPCFDEF2_PROTOCOL_DEFINED_GET(x) XHCI32_GET_BITS(x, 27, 16) /* trb bit definitions */ @@ -351,7 +352,7 @@ enum #define TRB_TR_FRAMEID_SHIFT 20 #define TRB_TR_FRAMEID_MASK 0x7ff #define TRB_TR_SIA (1<<31) -#define TRB_TR_TRANS_LEN_SET(len) XHCI32_SET_BITS(len, 23, 0) +#define TRB_TR_TRANS_LEN_SET(len) XHCI32_SET_BITS(len, 23, 0) #define TRB_TR_TRANS_LEN_MASK XHCI_GENMASK(23, 0) #define TRB_TR_DIR (1<<16) @@ -384,7 +385,8 @@ enum #define TRB_INTR(t) (((t).status >> TRB_INTR_SHIFT) & TRB_INTR_MASK) /************************** Type Definitions *********************************/ -enum TRBType { +enum TRBType +{ TRB_RESERVED = 0, TR_NORMAL, TR_SETUP, @@ -419,7 +421,8 @@ enum TRBType { ER_MFINDEX_WRAP, }; -enum TRBCCode { +enum TRBCCode +{ CC_DISCONNECTED = -2, CC_TIMEOUT = -1, CC_INVALID = 0, @@ -478,45 +481,53 @@ enum TRBCCode { /************************** Function Prototypes ******************************/ /*****************************************************************************/ -static inline void writeq(unsigned long addr, uint64_t val) { +static inline void writeq(unsigned long addr, uint64_t val) +{ BARRIER(); *(volatile uint64_t *)addr = val; } -static inline void writel(unsigned long addr, uint32_t val) { +static inline void writel(unsigned long addr, uint32_t val) +{ BARRIER(); *(volatile uint32_t *)addr = val; } -static inline void writew(unsigned long addr, uint16_t val) { +static inline void writew(unsigned long addr, uint16_t val) +{ BARRIER(); *(volatile uint16_t *)addr = val; } -static inline void writeb(unsigned long addr, uint8_t val) { +static inline void writeb(unsigned long addr, uint8_t val) +{ BARRIER(); *(volatile uint8_t *)addr = val; } -static inline uint64_t readq(unsigned long addr) { +static inline uint64_t readq(unsigned long addr) +{ uint64_t val = *(volatile const uint64_t *)addr; BARRIER(); return val; } -static inline uint32_t readl(unsigned long addr) { +static inline uint32_t readl(unsigned long addr) +{ uint32_t val = *(volatile const uint32_t *)addr; BARRIER(); return val; } -static inline uint16_t readw(unsigned long addr) { +static inline uint16_t readw(unsigned long addr) +{ uint16_t val = *(volatile const uint16_t *)addr; BARRIER(); return val; } -static inline uint8_t readb(unsigned long addr) { +static inline uint8_t readb(unsigned long addr) +{ uint8_t val = *(volatile const uint8_t *)addr; BARRIER(); return val; diff --git a/third-party/fatfs-0.1.3/Kconfig b/third-party/fatfs-0.1.3/Kconfig deleted file mode 100644 index 26db7515..00000000 --- a/third-party/fatfs-0.1.3/Kconfig +++ /dev/null @@ -1,34 +0,0 @@ -menu "FATFS Configuration" - choice FATFS_DISK_TYPE - prompt "Select Fatfs Disk Type" - default SELECT_FATFS_RAM_DISK - help - Select Disk Type for FATFS - - config SELECT_FATFS_RAM_DISK - bool "Ram Disk" - - config SELECT_FATFS_FSDMMC - bool "Sd Card(FSdmmc)" - select USE_SDMMC_CMD - - config SELECT_FATFS_FSATA_PCIE - bool "Sata_Pcie" - select USE_PCIE - select ENABLE_F_PCIE - select USE_SATA - select ENABLE_FSATA - - config SELECT_FATFS_FSATA_CONTROLLER - depends on TARGET_E2000 - bool "Sata_Controller" - select USE_SATA - select ENABLE_FSATA - - config SELECT_FATFS_USB - bool "Usb Disk" - select USE_USB - select ENABLE_USB_FXHCI - - endchoice # LETTER_SHELL_USART_TYPE -endmenu \ No newline at end of file diff --git a/third-party/fatfs-0.1.3/ff.c b/third-party/fatfs-0.1.3/ff.c deleted file mode 100644 index 35c97553..00000000 --- a/third-party/fatfs-0.1.3/ff.c +++ /dev/null @@ -1,6533 +0,0 @@ -/*----------------------------------------------------------------------------/ -/ FatFs - Generic FAT Filesystem Module R0.13b / -/-----------------------------------------------------------------------------/ -/ -/ Copyright (C) 2018, ChaN, all right reserved. -/ -/ FatFs module is an open source software. Redistribution and use of FatFs in -/ source and binary forms, with or without modification, are permitted provided -/ that the following condition is met: -/ -/ 1. Redistributions of source code must retain the above copyright notice, -/ this condition and the following disclaimer. -/ -/ This software is provided by the copyright holder and contributors "AS IS" -/ and any warranties related to this software are DISCLAIMED. -/ The copyright owner or contributors be NOT LIABLE for any damages caused -/ by use of this software. -/ -/----------------------------------------------------------------------------*/ - - -#include "ff.h" /* Declarations of FatFs API */ -#include "diskio.h" /* Declarations of device I/O functions */ - - -/*-------------------------------------------------------------------------- - - Module Private Definitions - ----------------------------------------------------------------------------*/ - -#if FF_DEFINED != 63463 /* Revision ID */ -#error Wrong include file (ff.h). -#endif - - -/* Character code support macros */ -#define IsUpper(c) ((c) >= 'A' && (c) <= 'Z') -#define IsLower(c) ((c) >= 'a' && (c) <= 'z') -#define IsDigit(c) ((c) >= '0' && (c) <= '9') -#define IsSurrogate(c) ((c) >= 0xD800 && (c) <= 0xDFFF) -#define IsSurrogateH(c) ((c) >= 0xD800 && (c) <= 0xDBFF) -#define IsSurrogateL(c) ((c) >= 0xDC00 && (c) <= 0xDFFF) - - -/* Additional file attribute bits for internal use */ -#define AM_VOL 0x08 /* Volume label */ -#define AM_LFN 0x0F /* LFN entry */ -#define AM_MASK 0x3F /* Mask of defined bits */ - - -/* Additional file access control and file status flags for internal use */ -#define FA_SEEKEND 0x20 /* Seek to end of the file on file open */ -#define FA_MODIFIED 0x40 /* File has been modified */ -#define FA_DIRTY 0x80 /* FIL.buf[] needs to be written-back */ - - -/* Name status flags in fn[11] */ -#define NSFLAG 11 /* Index of the name status byte */ -#define NS_LOSS 0x01 /* Out of 8.3 format */ -#define NS_LFN 0x02 /* Force to create LFN entry */ -#define NS_LAST 0x04 /* Last segment */ -#define NS_BODY 0x08 /* Lower case flag (body) */ -#define NS_EXT 0x10 /* Lower case flag (ext) */ -#define NS_DOT 0x20 /* Dot entry */ -#define NS_NOLFN 0x40 /* Do not find LFN */ -#define NS_NONAME 0x80 /* Not followed */ - - -/* Limits and boundaries */ -#define MAX_DIR 0x200000 /* Max size of FAT directory */ -#define MAX_DIR_EX 0x10000000 /* Max size of exFAT directory */ -#define MAX_FAT12 0xFF5 /* Max FAT12 clusters (differs from specs, but right for real DOS/Windows behavior) */ -#define MAX_FAT16 0xFFF5 /* Max FAT16 clusters (differs from specs, but right for real DOS/Windows behavior) */ -#define MAX_FAT32 0x0FFFFFF5 /* Max FAT32 clusters (not specified, practical limit) */ -#define MAX_EXFAT 0x7FFFFFFD /* Max exFAT clusters (differs from specs, implementation limit) */ - - -/* FatFs refers the FAT structure as simple byte array instead of structure member -/ because the C structure is not binary compatible between different platforms */ - -#define BS_JmpBoot 0 /* x86 jump instruction (3-byte) */ -#define BS_OEMName 3 /* OEM name (8-byte) */ -#define BPB_BytsPerSec 11 /* Sector size [byte] (WORD) */ -#define BPB_SecPerClus 13 /* Cluster size [sector] (BYTE) */ -#define BPB_RsvdSecCnt 14 /* Size of reserved area [sector] (WORD) */ -#define BPB_NumFATs 16 /* Number of FATs (BYTE) */ -#define BPB_RootEntCnt 17 /* Size of root directory area for FAT [entry] (WORD) */ -#define BPB_TotSec16 19 /* Volume size (16-bit) [sector] (WORD) */ -#define BPB_Media 21 /* Media descriptor byte (BYTE) */ -#define BPB_FATSz16 22 /* FAT size (16-bit) [sector] (WORD) */ -#define BPB_SecPerTrk 24 /* Number of sectors per track for int13h [sector] (WORD) */ -#define BPB_NumHeads 26 /* Number of heads for int13h (WORD) */ -#define BPB_HiddSec 28 /* Volume offset from top of the drive (DWORD) */ -#define BPB_TotSec32 32 /* Volume size (32-bit) [sector] (DWORD) */ -#define BS_DrvNum 36 /* Physical drive number for int13h (BYTE) */ -#define BS_NTres 37 /* WindowsNT error flag (BYTE) */ -#define BS_BootSig 38 /* Extended boot signature (BYTE) */ -#define BS_VolID 39 /* Volume serial number (DWORD) */ -#define BS_VolLab 43 /* Volume label string (8-byte) */ -#define BS_FilSysType 54 /* Filesystem type string (8-byte) */ -#define BS_BootCode 62 /* Boot code (448-byte) */ -#define BS_55AA 510 /* Signature word (WORD) */ - -#define BPB_FATSz32 36 /* FAT32: FAT size [sector] (DWORD) */ -#define BPB_ExtFlags32 40 /* FAT32: Extended flags (WORD) */ -#define BPB_FSVer32 42 /* FAT32: Filesystem version (WORD) */ -#define BPB_RootClus32 44 /* FAT32: Root directory cluster (DWORD) */ -#define BPB_FSInfo32 48 /* FAT32: Offset of FSINFO sector (WORD) */ -#define BPB_BkBootSec32 50 /* FAT32: Offset of backup boot sector (WORD) */ -#define BS_DrvNum32 64 /* FAT32: Physical drive number for int13h (BYTE) */ -#define BS_NTres32 65 /* FAT32: Error flag (BYTE) */ -#define BS_BootSig32 66 /* FAT32: Extended boot signature (BYTE) */ -#define BS_VolID32 67 /* FAT32: Volume serial number (DWORD) */ -#define BS_VolLab32 71 /* FAT32: Volume label string (8-byte) */ -#define BS_FilSysType32 82 /* FAT32: Filesystem type string (8-byte) */ -#define BS_BootCode32 90 /* FAT32: Boot code (420-byte) */ - -#define BPB_ZeroedEx 11 /* exFAT: MBZ field (53-byte) */ -#define BPB_VolOfsEx 64 /* exFAT: Volume offset from top of the drive [sector] (QWORD) */ -#define BPB_TotSecEx 72 /* exFAT: Volume size [sector] (QWORD) */ -#define BPB_FatOfsEx 80 /* exFAT: FAT offset from top of the volume [sector] (DWORD) */ -#define BPB_FatSzEx 84 /* exFAT: FAT size [sector] (DWORD) */ -#define BPB_DataOfsEx 88 /* exFAT: Data offset from top of the volume [sector] (DWORD) */ -#define BPB_NumClusEx 92 /* exFAT: Number of clusters (DWORD) */ -#define BPB_RootClusEx 96 /* exFAT: Root directory start cluster (DWORD) */ -#define BPB_VolIDEx 100 /* exFAT: Volume serial number (DWORD) */ -#define BPB_FSVerEx 104 /* exFAT: Filesystem version (WORD) */ -#define BPB_VolFlagEx 106 /* exFAT: Volume flags (WORD) */ -#define BPB_BytsPerSecEx 108 /* exFAT: Log2 of sector size in unit of byte (BYTE) */ -#define BPB_SecPerClusEx 109 /* exFAT: Log2 of cluster size in unit of sector (BYTE) */ -#define BPB_NumFATsEx 110 /* exFAT: Number of FATs (BYTE) */ -#define BPB_DrvNumEx 111 /* exFAT: Physical drive number for int13h (BYTE) */ -#define BPB_PercInUseEx 112 /* exFAT: Percent in use (BYTE) */ -#define BPB_RsvdEx 113 /* exFAT: Reserved (7-byte) */ -#define BS_BootCodeEx 120 /* exFAT: Boot code (390-byte) */ - -#define DIR_Name 0 /* Short file name (11-byte) */ -#define DIR_Attr 11 /* Attribute (BYTE) */ -#define DIR_NTres 12 /* Lower case flag (BYTE) */ -#define DIR_CrtTime10 13 /* Created time sub-second (BYTE) */ -#define DIR_CrtTime 14 /* Created time (DWORD) */ -#define DIR_LstAccDate 18 /* Last accessed date (WORD) */ -#define DIR_FstClusHI 20 /* Higher 16-bit of first cluster (WORD) */ -#define DIR_ModTime 22 /* Modified time (DWORD) */ -#define DIR_FstClusLO 26 /* Lower 16-bit of first cluster (WORD) */ -#define DIR_FileSize 28 /* File size (DWORD) */ -#define LDIR_Ord 0 /* LFN: LFN order and LLE flag (BYTE) */ -#define LDIR_Attr 11 /* LFN: LFN attribute (BYTE) */ -#define LDIR_Type 12 /* LFN: Entry type (BYTE) */ -#define LDIR_Chksum 13 /* LFN: Checksum of the SFN (BYTE) */ -#define LDIR_FstClusLO 26 /* LFN: MBZ field (WORD) */ -#define XDIR_Type 0 /* exFAT: Type of exFAT directory entry (BYTE) */ -#define XDIR_NumLabel 1 /* exFAT: Number of volume label characters (BYTE) */ -#define XDIR_Label 2 /* exFAT: Volume label (11-WORD) */ -#define XDIR_CaseSum 4 /* exFAT: Sum of case conversion table (DWORD) */ -#define XDIR_NumSec 1 /* exFAT: Number of secondary entries (BYTE) */ -#define XDIR_SetSum 2 /* exFAT: Sum of the set of directory entries (WORD) */ -#define XDIR_Attr 4 /* exFAT: File attribute (WORD) */ -#define XDIR_CrtTime 8 /* exFAT: Created time (DWORD) */ -#define XDIR_ModTime 12 /* exFAT: Modified time (DWORD) */ -#define XDIR_AccTime 16 /* exFAT: Last accessed time (DWORD) */ -#define XDIR_CrtTime10 20 /* exFAT: Created time subsecond (BYTE) */ -#define XDIR_ModTime10 21 /* exFAT: Modified time subsecond (BYTE) */ -#define XDIR_CrtTZ 22 /* exFAT: Created timezone (BYTE) */ -#define XDIR_ModTZ 23 /* exFAT: Modified timezone (BYTE) */ -#define XDIR_AccTZ 24 /* exFAT: Last accessed timezone (BYTE) */ -#define XDIR_GenFlags 33 /* exFAT: General secondary flags (BYTE) */ -#define XDIR_NumName 35 /* exFAT: Number of file name characters (BYTE) */ -#define XDIR_NameHash 36 /* exFAT: Hash of file name (WORD) */ -#define XDIR_ValidFileSize 40 /* exFAT: Valid file size (QWORD) */ -#define XDIR_FstClus 52 /* exFAT: First cluster of the file data (DWORD) */ -#define XDIR_FileSize 56 /* exFAT: File/Directory size (QWORD) */ - -#define SZDIRE 32 /* Size of a directory entry */ -#define DDEM 0xE5 /* Deleted directory entry mark set to DIR_Name[0] */ -#define RDDEM 0x05 /* Replacement of the character collides with DDEM */ -#define LLEF 0x40 /* Last long entry flag in LDIR_Ord */ - -#define FSI_LeadSig 0 /* FAT32 FSI: Leading signature (DWORD) */ -#define FSI_StrucSig 484 /* FAT32 FSI: Structure signature (DWORD) */ -#define FSI_Free_Count 488 /* FAT32 FSI: Number of free clusters (DWORD) */ -#define FSI_Nxt_Free 492 /* FAT32 FSI: Last allocated cluster (DWORD) */ - -#define MBR_Table 446 /* MBR: Offset of partition table in the MBR */ -#define SZ_PTE 16 /* MBR: Size of a partition table entry */ -#define PTE_Boot 0 /* MBR PTE: Boot indicator */ -#define PTE_StHead 1 /* MBR PTE: Start head */ -#define PTE_StSec 2 /* MBR PTE: Start sector */ -#define PTE_StCyl 3 /* MBR PTE: Start cylinder */ -#define PTE_System 4 /* MBR PTE: System ID */ -#define PTE_EdHead 5 /* MBR PTE: End head */ -#define PTE_EdSec 6 /* MBR PTE: End sector */ -#define PTE_EdCyl 7 /* MBR PTE: End cylinder */ -#define PTE_StLba 8 /* MBR PTE: Start in LBA */ -#define PTE_SizLba 12 /* MBR PTE: Size in LBA */ - - -/* Post process on fatal error in the file operations */ -#define ABORT(fs, res) { fp->err = (BYTE)(res); LEAVE_FF(fs, res); } - - -/* Re-entrancy related */ -#if FF_FS_REENTRANT -#if FF_USE_LFN == 1 -#error Static LFN work area cannot be used at thread-safe configuration -#endif -#define LEAVE_FF(fs, res) { unlock_fs(fs, res); return res; } -#else -#define LEAVE_FF(fs, res) return res -#endif - - -/* Definitions of volume - physical location conversion */ -#if FF_MULTI_PARTITION -#define LD2PD(vol) VolToPart[vol].pd /* Get physical drive number */ -#define LD2PT(vol) VolToPart[vol].pt /* Get partition index */ -#else -#define LD2PD(vol) (BYTE)(vol) /* Each logical drive is bound to the same physical drive number */ -#define LD2PT(vol) 0 /* Find first valid partition or in SFD */ -#endif - - -/* Definitions of sector size */ -#if (FF_MAX_SS < FF_MIN_SS) || (FF_MAX_SS != 512 && FF_MAX_SS != 1024 && FF_MAX_SS != 2048 && FF_MAX_SS != 4096) || (FF_MIN_SS != 512 && FF_MIN_SS != 1024 && FF_MIN_SS != 2048 && FF_MIN_SS != 4096) -#error Wrong sector size configuration -#endif -#if FF_MAX_SS == FF_MIN_SS -#define SS(fs) ((UINT)FF_MAX_SS) /* Fixed sector size */ -#else -#define SS(fs) ((fs)->ssize) /* Variable sector size */ -#endif - - -/* Timestamp */ -#if FF_FS_NORTC == 1 -#if FF_NORTC_YEAR < 1980 || FF_NORTC_YEAR > 2107 || FF_NORTC_MON < 1 || FF_NORTC_MON > 12 || FF_NORTC_MDAY < 1 || FF_NORTC_MDAY > 31 -#error Invalid FF_FS_NORTC settings -#endif -#define GET_FATTIME() ((DWORD)(FF_NORTC_YEAR - 1980) << 25 | (DWORD)FF_NORTC_MON << 21 | (DWORD)FF_NORTC_MDAY << 16) -#else -#define GET_FATTIME() get_fattime() -#endif - - -/* File lock controls */ -#if FF_FS_LOCK != 0 -#if FF_FS_READONLY -#error FF_FS_LOCK must be 0 at read-only configuration -#endif -typedef struct { - FATFS *fs; /* Object ID 1, volume (NULL:blank entry) */ - DWORD clu; /* Object ID 2, containing directory (0:root) */ - DWORD ofs; /* Object ID 3, offset in the directory */ - WORD ctr; /* Object open counter, 0:none, 0x01..0xFF:read mode open count, 0x100:write mode */ -} FILESEM; -#endif - - -/* SBCS up-case tables (\x80-\xFF) */ -#define TBL_CT437 {0x80,0x9A,0x45,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F, \ - 0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ - 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ - 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ - 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ - 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} -#define TBL_CT720 {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ - 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ - 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ - 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ - 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ - 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} -#define TBL_CT737 {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ - 0x90,0x92,0x92,0x93,0x94,0x95,0x96,0x97,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, \ - 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96, \ - 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ - 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ - 0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xEF,0xF5,0xF0,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} -#define TBL_CT771 {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ - 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ - 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ - 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ - 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDC,0xDE,0xDE, \ - 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ - 0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFE,0xFF} -#define TBL_CT775 {0x80,0x9A,0x91,0xA0,0x8E,0x95,0x8F,0x80,0xAD,0xED,0x8A,0x8A,0xA1,0x8D,0x8E,0x8F, \ - 0x90,0x92,0x92,0xE2,0x99,0x95,0x96,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ - 0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ - 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ - 0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ - 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF, \ - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} -#define TBL_CT850 {0x43,0x55,0x45,0x41,0x41,0x41,0x41,0x43,0x45,0x45,0x45,0x49,0x49,0x49,0x41,0x41, \ - 0x45,0x92,0x92,0x4F,0x4F,0x4F,0x55,0x55,0x59,0x4F,0x55,0x4F,0x9C,0x4F,0x9E,0x9F, \ - 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ - 0xB0,0xB1,0xB2,0xB3,0xB4,0x41,0x41,0x41,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0x41,0x41,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ - 0xD1,0xD1,0x45,0x45,0x45,0x49,0x49,0x49,0x49,0xD9,0xDA,0xDB,0xDC,0xDD,0x49,0xDF, \ - 0x4F,0xE1,0x4F,0x4F,0x4F,0x4F,0xE6,0xE8,0xE8,0x55,0x55,0x55,0x59,0x59,0xEE,0xEF, \ - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} -#define TBL_CT852 {0x80,0x9A,0x90,0xB6,0x8E,0xDE,0x8F,0x80,0x9D,0xD3,0x8A,0x8A,0xD7,0x8D,0x8E,0x8F, \ - 0x90,0x91,0x91,0xE2,0x99,0x95,0x95,0x97,0x97,0x99,0x9A,0x9B,0x9B,0x9D,0x9E,0xAC, \ - 0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF, \ - 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \ - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ - 0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ - 0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF, \ - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF} -#define TBL_CT855 {0x81,0x81,0x83,0x83,0x85,0x85,0x87,0x87,0x89,0x89,0x8B,0x8B,0x8D,0x8D,0x8F,0x8F, \ - 0x91,0x91,0x93,0x93,0x95,0x95,0x97,0x97,0x99,0x99,0x9B,0x9B,0x9D,0x9D,0x9F,0x9F, \ - 0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF, \ - 0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \ - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ - 0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \ - 0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF, \ - 0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF} -#define TBL_CT857 {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0x49,0x8E,0x8F, \ - 0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x98,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9E, \ - 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ - 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ - 0xD0,0xD1,0xD2,0xD3,0xD4,0x49,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ - 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0xED,0xEE,0xEF, \ - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} -#define TBL_CT860 {0x80,0x9A,0x90,0x8F,0x8E,0x91,0x86,0x80,0x89,0x89,0x92,0x8B,0x8C,0x98,0x8E,0x8F, \ - 0x90,0x91,0x92,0x8C,0x99,0xA9,0x96,0x9D,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ - 0x86,0x8B,0x9F,0x96,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ - 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ - 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ - 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} -#define TBL_CT861 {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x8B,0x8B,0x8D,0x8E,0x8F, \ - 0x90,0x92,0x92,0x4F,0x99,0x8D,0x55,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ - 0xA4,0xA5,0xA6,0xA7,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ - 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ - 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ - 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} -#define TBL_CT862 {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ - 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ - 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ - 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ - 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ - 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} -#define TBL_CT863 {0x43,0x55,0x45,0x41,0x41,0x41,0x86,0x43,0x45,0x45,0x45,0x49,0x49,0x8D,0x41,0x8F, \ - 0x45,0x45,0x45,0x4F,0x45,0x49,0x55,0x55,0x98,0x4F,0x55,0x9B,0x9C,0x55,0x55,0x9F, \ - 0xA0,0xA1,0x4F,0x55,0xA4,0xA5,0xA6,0xA7,0x49,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ - 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ - 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ - 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} -#define TBL_CT864 {0x80,0x9A,0x45,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F, \ - 0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ - 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ - 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ - 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ - 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} -#define TBL_CT865 {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F, \ - 0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ - 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ - 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ - 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ - 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} -#define TBL_CT866 {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ - 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ - 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ - 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ - 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ - 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ - 0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} -#define TBL_CT869 {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ - 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x86,0x9C,0x8D,0x8F,0x90, \ - 0x91,0x90,0x92,0x95,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ - 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ - 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xA4,0xA5,0xA6,0xD9,0xDA,0xDB,0xDC,0xA7,0xA8,0xDF, \ - 0xA9,0xAA,0xAC,0xAD,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xCF,0xCF,0xD0,0xEF, \ - 0xF0,0xF1,0xD1,0xD2,0xD3,0xF5,0xD4,0xF7,0xF8,0xF9,0xD5,0x96,0x95,0x98,0xFE,0xFF} - - -/* DBCS code range |----- 1st byte -----| |----------- 2nd byte -----------| */ -#define TBL_DC932 {0x81, 0x9F, 0xE0, 0xFC, 0x40, 0x7E, 0x80, 0xFC, 0x00, 0x00} -#define TBL_DC936 {0x81, 0xFE, 0x00, 0x00, 0x40, 0x7E, 0x80, 0xFE, 0x00, 0x00} -#define TBL_DC949 {0x81, 0xFE, 0x00, 0x00, 0x41, 0x5A, 0x61, 0x7A, 0x81, 0xFE} -#define TBL_DC950 {0x81, 0xFE, 0x00, 0x00, 0x40, 0x7E, 0xA1, 0xFE, 0x00, 0x00} - - -/* Macros for table definitions */ -#define MERGE_2STR(a, b) a ## b -#define MKCVTBL(hd, cp) MERGE_2STR(hd, cp) - - - - -/*-------------------------------------------------------------------------- - - Module Private Work Area - ----------------------------------------------------------------------------*/ -/* Remark: Variables defined here without initial value shall be guaranteed -/ zero/null at start-up. If not, the linker option or start-up routine is -/ not compliance with C standard. */ - -/*--------------------------------*/ -/* File/Volume controls */ -/*--------------------------------*/ - -#if FF_VOLUMES < 1 || FF_VOLUMES > 10 -#error Wrong FF_VOLUMES setting -#endif -static FATFS* FatFs[FF_VOLUMES]; /* Pointer to the filesystem objects (logical drives) */ -static WORD Fsid; /* Filesystem mount ID */ - -#if FF_FS_RPATH != 0 -static BYTE CurrVol; /* Current drive */ -#endif - -#if FF_FS_LOCK != 0 -static FILESEM Files[FF_FS_LOCK]; /* Open object lock semaphores */ -#endif - -#if FF_STR_VOLUME_ID -#ifdef FF_VOLUME_STRS -static const char* const VolumeStr[FF_VOLUMES] = {FF_VOLUME_STRS}; /* Pre-defined volume ID */ -#endif -#endif - - -/*--------------------------------*/ -/* LFN/Directory working buffer */ -/*--------------------------------*/ - -#if FF_USE_LFN == 0 /* Non-LFN configuration */ -#if FF_FS_EXFAT -#error LFN must be enabled when enable exFAT -#endif -#define DEF_NAMBUF -#define INIT_NAMBUF(fs) -#define FREE_NAMBUF() -#define LEAVE_MKFS(res) return res - -#else /* LFN configurations */ -#if FF_MAX_LFN < 12 || FF_MAX_LFN > 255 -#error Wrong setting of FF_MAX_LFN -#endif -#if FF_LFN_BUF < FF_SFN_BUF || FF_SFN_BUF < 12 -#error Wrong setting of FF_LFN_BUF or FF_SFN_BUF -#endif -#if FF_LFN_UNICODE < 0 || FF_LFN_UNICODE > 3 -#error Wrong setting of FF_LFN_UNICODE -#endif -static const BYTE LfnOfs[] = {1,3,5,7,9,14,16,18,20,22,24,28,30}; /* FAT: Offset of LFN characters in the directory entry */ -#define MAXDIRB(nc) ((nc + 44U) / 15 * SZDIRE) /* exFAT: Size of directory entry block scratchpad buffer needed for the name length */ - -#if FF_USE_LFN == 1 /* LFN enabled with static working buffer */ -#if FF_FS_EXFAT -static BYTE DirBuf[MAXDIRB(FF_MAX_LFN)]; /* Directory entry block scratchpad buffer */ -#endif -static WCHAR LfnBuf[FF_MAX_LFN + 1]; /* LFN working buffer */ -#define DEF_NAMBUF -#define INIT_NAMBUF(fs) -#define FREE_NAMBUF() -#define LEAVE_MKFS(res) return res - -#elif FF_USE_LFN == 2 /* LFN enabled with dynamic working buffer on the stack */ -#if FF_FS_EXFAT -#define DEF_NAMBUF WCHAR lbuf[FF_MAX_LFN+1]; BYTE dbuf[MAXDIRB(FF_MAX_LFN)]; /* LFN working buffer and directory entry block scratchpad buffer */ -#define INIT_NAMBUF(fs) { (fs)->lfnbuf = lbuf; (fs)->dirbuf = dbuf; } -#define FREE_NAMBUF() -#else -#define DEF_NAMBUF WCHAR lbuf[FF_MAX_LFN+1]; /* LFN working buffer */ -#define INIT_NAMBUF(fs) { (fs)->lfnbuf = lbuf; } -#define FREE_NAMBUF() -#endif -#define LEAVE_MKFS(res) return res - -#elif FF_USE_LFN == 3 /* LFN enabled with dynamic working buffer on the heap */ -#if FF_FS_EXFAT -#define DEF_NAMBUF WCHAR *lfn; /* Pointer to LFN working buffer and directory entry block scratchpad buffer */ -#define INIT_NAMBUF(fs) { lfn = ff_memalloc((FF_MAX_LFN+1)*2 + MAXDIRB(FF_MAX_LFN)); if (!lfn) LEAVE_FF(fs, FR_NOT_ENOUGH_CORE); (fs)->lfnbuf = lfn; (fs)->dirbuf = (BYTE*)(lfn+FF_MAX_LFN+1); } -#define FREE_NAMBUF() ff_memfree(lfn) -#else -#define DEF_NAMBUF WCHAR *lfn; /* Pointer to LFN working buffer */ -#define INIT_NAMBUF(fs) { lfn = ff_memalloc((FF_MAX_LFN+1)*2); if (!lfn) LEAVE_FF(fs, FR_NOT_ENOUGH_CORE); (fs)->lfnbuf = lfn; } -#define FREE_NAMBUF() ff_memfree(lfn) -#endif -#define LEAVE_MKFS(res) { if (!work) ff_memfree(buf); return res; } -#define MAX_MALLOC 0x8000 /* Must be >=FF_MAX_SS */ - -#else -#error Wrong setting of FF_USE_LFN - -#endif /* FF_USE_LFN == 1 */ -#endif /* FF_USE_LFN == 0 */ - - - -/*--------------------------------*/ -/* Code conversion tables */ -/*--------------------------------*/ - -#if FF_CODE_PAGE == 0 /* Run-time code page configuration */ -#define CODEPAGE CodePage -static WORD CodePage; /* Current code page */ -static const BYTE *ExCvt, *DbcTbl; /* Pointer to current SBCS up-case table and DBCS code range table below */ -static const BYTE Ct437[] = TBL_CT437; -static const BYTE Ct720[] = TBL_CT720; -static const BYTE Ct737[] = TBL_CT737; -static const BYTE Ct771[] = TBL_CT771; -static const BYTE Ct775[] = TBL_CT775; -static const BYTE Ct850[] = TBL_CT850; -static const BYTE Ct852[] = TBL_CT852; -static const BYTE Ct855[] = TBL_CT855; -static const BYTE Ct857[] = TBL_CT857; -static const BYTE Ct860[] = TBL_CT860; -static const BYTE Ct861[] = TBL_CT861; -static const BYTE Ct862[] = TBL_CT862; -static const BYTE Ct863[] = TBL_CT863; -static const BYTE Ct864[] = TBL_CT864; -static const BYTE Ct865[] = TBL_CT865; -static const BYTE Ct866[] = TBL_CT866; -static const BYTE Ct869[] = TBL_CT869; -static const BYTE Dc932[] = TBL_DC932; -static const BYTE Dc936[] = TBL_DC936; -static const BYTE Dc949[] = TBL_DC949; -static const BYTE Dc950[] = TBL_DC950; - -#elif FF_CODE_PAGE < 900 /* Static code page configuration (SBCS) */ -#define CODEPAGE FF_CODE_PAGE -static const BYTE ExCvt[] = MKCVTBL(TBL_CT, FF_CODE_PAGE); - -#else /* Static code page configuration (DBCS) */ -#define CODEPAGE FF_CODE_PAGE -static const BYTE DbcTbl[] = MKCVTBL(TBL_DC, FF_CODE_PAGE); - -#endif - - - - -/*-------------------------------------------------------------------------- - - Module Private Functions - ----------------------------------------------------------------------------*/ - - -/*-----------------------------------------------------------------------*/ -/* Load/Store multi-byte word in the FAT structure */ -/*-----------------------------------------------------------------------*/ - -static WORD ld_word (const BYTE* ptr) /* Load a 2-byte little-endian word */ -{ - WORD rv; - - rv = ptr[1]; - rv = rv << 8 | ptr[0]; - return rv; -} - -static DWORD ld_dword (const BYTE* ptr) /* Load a 4-byte little-endian word */ -{ - DWORD rv; - - rv = ptr[3]; - rv = rv << 8 | ptr[2]; - rv = rv << 8 | ptr[1]; - rv = rv << 8 | ptr[0]; - return rv; -} - -#if FF_FS_EXFAT -static QWORD ld_qword (const BYTE* ptr) /* Load an 8-byte little-endian word */ -{ - QWORD rv; - - rv = ptr[7]; - rv = rv << 8 | ptr[6]; - rv = rv << 8 | ptr[5]; - rv = rv << 8 | ptr[4]; - rv = rv << 8 | ptr[3]; - rv = rv << 8 | ptr[2]; - rv = rv << 8 | ptr[1]; - rv = rv << 8 | ptr[0]; - return rv; -} -#endif - -#if !FF_FS_READONLY -static void st_word (BYTE* ptr, WORD val) /* Store a 2-byte word in little-endian */ -{ - *ptr++ = (BYTE)val; val >>= 8; - *ptr++ = (BYTE)val; -} - -static void st_dword (BYTE* ptr, DWORD val) /* Store a 4-byte word in little-endian */ -{ - *ptr++ = (BYTE)val; val >>= 8; - *ptr++ = (BYTE)val; val >>= 8; - *ptr++ = (BYTE)val; val >>= 8; - *ptr++ = (BYTE)val; -} - -#if FF_FS_EXFAT -static void st_qword (BYTE* ptr, QWORD val) /* Store an 8-byte word in little-endian */ -{ - *ptr++ = (BYTE)val; val >>= 8; - *ptr++ = (BYTE)val; val >>= 8; - *ptr++ = (BYTE)val; val >>= 8; - *ptr++ = (BYTE)val; val >>= 8; - *ptr++ = (BYTE)val; val >>= 8; - *ptr++ = (BYTE)val; val >>= 8; - *ptr++ = (BYTE)val; val >>= 8; - *ptr++ = (BYTE)val; -} -#endif -#endif /* !FF_FS_READONLY */ - - - -/*-----------------------------------------------------------------------*/ -/* String functions */ -/*-----------------------------------------------------------------------*/ - -/* Copy memory to memory */ -static void mem_cpy (void* dst, const void* src, UINT cnt) -{ - BYTE *d = (BYTE*)dst; - const BYTE *s = (const BYTE*)src; - - if (cnt != 0) { - do { - *d++ = *s++; - } while (--cnt); - } -} - - -/* Fill memory block */ -static void mem_set (void* dst, int val, UINT cnt) -{ - BYTE *d = (BYTE*)dst; - - do { - *d++ = (BYTE)val; - } while (--cnt); -} - - -/* Compare memory block */ -static int mem_cmp (const void* dst, const void* src, UINT cnt) /* ZR:same, NZ:different */ -{ - const BYTE *d = (const BYTE *)dst, *s = (const BYTE *)src; - int r = 0; - - do { - r = *d++ - *s++; - } while (--cnt && r == 0); - - return r; -} - - -/* Check if chr is contained in the string */ -static int chk_chr (const char* str, int chr) /* NZ:contained, ZR:not contained */ -{ - while (*str && *str != chr) str++; - return *str; -} - - -/* Test if the character is DBC 1st byte */ -static int dbc_1st (BYTE c) -{ -#if FF_CODE_PAGE == 0 /* Variable code page */ - if (DbcTbl && c >= DbcTbl[0]) { - if (c <= DbcTbl[1]) return 1; /* 1st byte range 1 */ - if (c >= DbcTbl[2] && c <= DbcTbl[3]) return 1; /* 1st byte range 2 */ - } -#elif FF_CODE_PAGE >= 900 /* DBCS fixed code page */ - if (c >= DbcTbl[0]) { - if (c <= DbcTbl[1]) return 1; - if (c >= DbcTbl[2] && c <= DbcTbl[3]) return 1; - } -#else /* SBCS fixed code page */ - if (c != 0) return 0; /* Always false */ -#endif - return 0; -} - - -/* Test if the character is DBC 2nd byte */ -static int dbc_2nd (BYTE c) -{ -#if FF_CODE_PAGE == 0 /* Variable code page */ - if (DbcTbl && c >= DbcTbl[4]) { - if (c <= DbcTbl[5]) return 1; /* 2nd byte range 1 */ - if (c >= DbcTbl[6] && c <= DbcTbl[7]) return 1; /* 2nd byte range 2 */ - if (c >= DbcTbl[8] && c <= DbcTbl[9]) return 1; /* 2nd byte range 3 */ - } -#elif FF_CODE_PAGE >= 900 /* DBCS fixed code page */ - if (c >= DbcTbl[4]) { - if (c <= DbcTbl[5]) return 1; - if (c >= DbcTbl[6] && c <= DbcTbl[7]) return 1; - if (c >= DbcTbl[8] && c <= DbcTbl[9]) return 1; - } -#else /* SBCS fixed code page */ - if (c != 0) return 0; /* Always false */ -#endif - return 0; -} - - -#if FF_USE_LFN - -/* Get a character from TCHAR string in defined API encodeing */ -static DWORD tchar2uni ( /* Returns character in UTF-16 encoding (>=0x10000 on double encoding unit, 0xFFFFFFFF on decode error) */ - const TCHAR** str /* Pointer to pointer to TCHAR string in configured encoding */ -) -{ - DWORD uc; - const TCHAR *p = *str; - -#if FF_LFN_UNICODE == 1 /* UTF-16 input */ - WCHAR wc; - - uc = *p++; /* Get a unit */ - if (IsSurrogate(uc)) { /* Surrogate? */ - wc = *p++; /* Get low surrogate */ - if (!IsSurrogateH(uc) || !IsSurrogateL(wc)) return 0xFFFFFFFF; /* Wrong surrogate? */ - uc = uc << 16 | wc; - } - -#elif FF_LFN_UNICODE == 2 /* UTF-8 input */ - BYTE b; - int nf; - - uc = (BYTE)*p++; /* Get a unit */ - if (uc & 0x80) { /* Multiple byte code? */ - if ((uc & 0xE0) == 0xC0) { /* 2-byte sequence? */ - uc &= 0x1F; nf = 1; - } else { - if ((uc & 0xF0) == 0xE0) { /* 3-byte sequence? */ - uc &= 0x0F; nf = 2; - } else { - if ((uc & 0xF8) == 0xF0) { /* 4-byte sequence? */ - uc &= 0x07; nf = 3; - } else { /* Wrong sequence */ - return 0xFFFFFFFF; - } - } - } - do { /* Get trailing bytes */ - b = (BYTE)*p++; - if ((b & 0xC0) != 0x80) return 0xFFFFFFFF; /* Wrong sequence? */ - uc = uc << 6 | (b & 0x3F); - } while (--nf != 0); - if (uc < 0x80 || IsSurrogate(uc) || uc >= 0x110000) return 0xFFFFFFFF; /* Wrong code? */ - if (uc >= 0x010000) uc = 0xD800DC00 | ((uc - 0x10000) << 6 & 0x3FF0000) | (uc & 0x3FF); /* Make a surrogate pair if needed */ - } - -#elif FF_LFN_UNICODE == 3 /* UTF-32 input */ - uc = (TCHAR)*p++; /* Get a unit */ - if (uc >= 0x110000) return 0xFFFFFFFF; /* Wrong code? */ - if (uc >= 0x010000) uc = 0xD800DC00 | ((uc - 0x10000) << 6 & 0x3FF0000) | (uc & 0x3FF); /* Make a surrogate pair if needed */ - -#else /* ANSI/OEM input */ - BYTE b; - WCHAR wc; - - wc = (BYTE)*p++; /* Get a byte */ - if (dbc_1st((BYTE)wc)) { /* Is it a DBC 1st byte? */ - b = (BYTE)*p++; /* Get 2nd byte */ - if (!dbc_2nd(b)) return 0xFFFFFFFF; /* Invalid code? */ - wc = (wc << 8) + b; /* Make a DBC */ - } - if (wc != 0) { - wc = ff_oem2uni(wc, CODEPAGE); /* ANSI/OEM ==> Unicode */ - if (wc == 0) return 0xFFFFFFFF; /* Invalid code? */ - } - uc = wc; - -#endif - *str = p; /* Next read pointer */ - return uc; -} - - -/* Output a TCHAR string in defined API encoding */ -static BYTE put_utf ( /* Returns number of encoding units written (0:buffer overflow or wrong encoding) */ - DWORD chr, /* UTF-16 encoded character (Double encoding unit char if >=0x10000) */ - TCHAR* buf, /* Output buffer */ - UINT szb /* Size of the buffer */ -) -{ -#if FF_LFN_UNICODE == 1 /* UTF-16 output */ - WCHAR hs, wc; - - hs = (WCHAR)(chr >> 16); - wc = (WCHAR)chr; - if (hs == 0) { /* Single encoding unit? */ - if (szb < 1 || IsSurrogate(wc)) return 0; /* Buffer overflow or wrong code? */ - *buf = wc; - return 1; - } - if (szb < 2 || !IsSurrogateH(hs) || !IsSurrogateL(wc)) return 0; /* Buffer overflow or wrong surrogate? */ - *buf++ = hs; - *buf++ = wc; - return 2; - -#elif FF_LFN_UNICODE == 2 /* UTF-8 output */ - DWORD hc; - - if (chr < 0x80) { /* Single byte code? */ - if (szb < 1) return 0; /* Buffer overflow? */ - *buf = (TCHAR)chr; - return 1; - } - if (chr < 0x800) { /* 2-byte sequence? */ - if (szb < 2) return 0; /* Buffer overflow? */ - *buf++ = (TCHAR)(0xC0 | (chr >> 6 & 0x1F)); - *buf++ = (TCHAR)(0x80 | (chr >> 0 & 0x3F)); - return 2; - } - if (chr < 0x10000) { /* 3-byte sequence? */ - if (szb < 3 || IsSurrogate(chr)) return 0; /* Buffer overflow or wrong code? */ - *buf++ = (TCHAR)(0xE0 | (chr >> 12 & 0x0F)); - *buf++ = (TCHAR)(0x80 | (chr >> 6 & 0x3F)); - *buf++ = (TCHAR)(0x80 | (chr >> 0 & 0x3F)); - return 3; - } - /* 4-byte sequence */ - if (szb < 4) return 0; /* Buffer overflow? */ - hc = ((chr & 0xFFFF0000) - 0xD8000000) >> 6; /* Get high 10 bits */ - chr = (chr & 0xFFFF) - 0xDC00; /* Get low 10 bits */ - if (hc >= 0x100000 || chr >= 0x400) return 0; /* Wrong surrogate? */ - chr = (hc | chr) + 0x10000; - *buf++ = (TCHAR)(0xF0 | (chr >> 18 & 0x07)); - *buf++ = (TCHAR)(0x80 | (chr >> 12 & 0x3F)); - *buf++ = (TCHAR)(0x80 | (chr >> 6 & 0x3F)); - *buf++ = (TCHAR)(0x80 | (chr >> 0 & 0x3F)); - return 4; - -#elif FF_LFN_UNICODE == 3 /* UTF-32 output */ - DWORD hc; - - if (szb < 1) return 0; /* Buffer overflow? */ - if (chr >= 0x10000) { /* Out of BMP? */ - hc = ((chr & 0xFFFF0000) - 0xD8000000) >> 6; /* Get high 10 bits */ - chr = (chr & 0xFFFF) - 0xDC00; /* Get low 10 bits */ - if (hc >= 0x100000 || chr >= 0x400) return 0; /* Wrong surrogate? */ - chr = (hc | chr) + 0x10000; - } - *buf++ = (TCHAR)chr; - return 1; - -#else /* ANSI/OEM output */ - WCHAR wc; - - wc = ff_uni2oem(chr, CODEPAGE); - if (wc >= 0x100) { /* Is this a DBC? */ - if (szb < 2) return 0; - *buf++ = (char)(wc >> 8); /* Store DBC 1st byte */ - *buf++ = (TCHAR)wc; /* Store DBC 2nd byte */ - return 2; - } - if (wc == 0 || szb < 1) return 0; /* Invalid char or buffer overflow? */ - *buf++ = (TCHAR)wc; /* Store the character */ - return 1; -#endif -} -#endif /* FF_USE_LFN */ - - -#if FF_FS_REENTRANT -/*-----------------------------------------------------------------------*/ -/* Request/Release grant to access the volume */ -/*-----------------------------------------------------------------------*/ -static int lock_fs ( /* 1:Ok, 0:timeout */ - FATFS* fs /* Filesystem object */ -) -{ - return ff_req_grant(fs->sobj); -} - - -static void unlock_fs ( - FATFS* fs, /* Filesystem object */ - FRESULT res /* Result code to be returned */ -) -{ - if (fs && res != FR_NOT_ENABLED && res != FR_INVALID_DRIVE && res != FR_TIMEOUT) { - ff_rel_grant(fs->sobj); - } -} - -#endif - - - -#if FF_FS_LOCK != 0 -/*-----------------------------------------------------------------------*/ -/* File lock control functions */ -/*-----------------------------------------------------------------------*/ - -static FRESULT chk_lock ( /* Check if the file can be accessed */ - DIR* dp, /* Directory object pointing the file to be checked */ - int acc /* Desired access type (0:Read mode open, 1:Write mode open, 2:Delete or rename) */ -) -{ - UINT i, be; - - /* Search open object table for the object */ - be = 0; - for (i = 0; i < FF_FS_LOCK; i++) { - if (Files[i].fs) { /* Existing entry */ - if (Files[i].fs == dp->obj.fs && /* Check if the object matches with an open object */ - Files[i].clu == dp->obj.sclust && - Files[i].ofs == dp->dptr) break; - } else { /* Blank entry */ - be = 1; - } - } - if (i == FF_FS_LOCK) { /* The object has not been opened */ - return (!be && acc != 2) ? FR_TOO_MANY_OPEN_FILES : FR_OK; /* Is there a blank entry for new object? */ - } - - /* The object was opened. Reject any open against writing file and all write mode open */ - return (acc != 0 || Files[i].ctr == 0x100) ? FR_LOCKED : FR_OK; -} - - -static int enq_lock (void) /* Check if an entry is available for a new object */ -{ - UINT i; - - for (i = 0; i < FF_FS_LOCK && Files[i].fs; i++) ; - return (i == FF_FS_LOCK) ? 0 : 1; -} - - -static UINT inc_lock ( /* Increment object open counter and returns its index (0:Internal error) */ - DIR* dp, /* Directory object pointing the file to register or increment */ - int acc /* Desired access (0:Read, 1:Write, 2:Delete/Rename) */ -) -{ - UINT i; - - - for (i = 0; i < FF_FS_LOCK; i++) { /* Find the object */ - if (Files[i].fs == dp->obj.fs && - Files[i].clu == dp->obj.sclust && - Files[i].ofs == dp->dptr) break; - } - - if (i == FF_FS_LOCK) { /* Not opened. Register it as new. */ - for (i = 0; i < FF_FS_LOCK && Files[i].fs; i++) ; - if (i == FF_FS_LOCK) return 0; /* No free entry to register (int err) */ - Files[i].fs = dp->obj.fs; - Files[i].clu = dp->obj.sclust; - Files[i].ofs = dp->dptr; - Files[i].ctr = 0; - } - - if (acc >= 1 && Files[i].ctr) return 0; /* Access violation (int err) */ - - Files[i].ctr = acc ? 0x100 : Files[i].ctr + 1; /* Set semaphore value */ - - return i + 1; /* Index number origin from 1 */ -} - - -static FRESULT dec_lock ( /* Decrement object open counter */ - UINT i /* Semaphore index (1..) */ -) -{ - WORD n; - FRESULT res; - - - if (--i < FF_FS_LOCK) { /* Index number origin from 0 */ - n = Files[i].ctr; - if (n == 0x100) n = 0; /* If write mode open, delete the entry */ - if (n > 0) n--; /* Decrement read mode open count */ - Files[i].ctr = n; - if (n == 0) Files[i].fs = 0; /* Delete the entry if open count gets zero */ - res = FR_OK; - } else { - res = FR_INT_ERR; /* Invalid index nunber */ - } - return res; -} - - -static void clear_lock ( /* Clear lock entries of the volume */ - FATFS *fs -) -{ - UINT i; - - for (i = 0; i < FF_FS_LOCK; i++) { - if (Files[i].fs == fs) Files[i].fs = 0; - } -} - -#endif /* FF_FS_LOCK != 0 */ - - - -/*-----------------------------------------------------------------------*/ -/* Move/Flush disk access window in the filesystem object */ -/*-----------------------------------------------------------------------*/ -#if !FF_FS_READONLY -static FRESULT sync_window ( /* Returns FR_OK or FR_DISK_ERR */ - FATFS* fs /* Filesystem object */ -) -{ - FRESULT res = FR_OK; - - - if (fs->wflag) { /* Is the disk access window dirty */ - if (disk_write(fs->pdrv, fs->win, fs->winsect, 1) == RES_OK) { /* Write back the window */ - fs->wflag = 0; /* Clear window dirty flag */ - if (fs->winsect - fs->fatbase < fs->fsize) { /* Is it in the 1st FAT? */ - if (fs->n_fats == 2) disk_write(fs->pdrv, fs->win, fs->winsect + fs->fsize, 1); /* Reflect it to 2nd FAT if needed */ - } - } else { - res = FR_DISK_ERR; - } - } - return res; -} -#endif - - -static FRESULT move_window ( /* Returns FR_OK or FR_DISK_ERR */ - FATFS* fs, /* Filesystem object */ - DWORD sector /* Sector number to make appearance in the fs->win[] */ -) -{ - FRESULT res = FR_OK; - - - if (sector != fs->winsect) { /* Window offset changed? */ -#if !FF_FS_READONLY - res = sync_window(fs); /* Write-back changes */ -#endif - if (res == FR_OK) { /* Fill sector window with new data */ - if (disk_read(fs->pdrv, fs->win, sector, 1) != RES_OK) { - sector = 0xFFFFFFFF; /* Invalidate window if read data is not valid */ - res = FR_DISK_ERR; - } - fs->winsect = sector; - } - } - return res; -} - - - - -#if !FF_FS_READONLY -/*-----------------------------------------------------------------------*/ -/* Synchronize filesystem and data on the storage */ -/*-----------------------------------------------------------------------*/ - -static FRESULT sync_fs ( /* Returns FR_OK or FR_DISK_ERR */ - FATFS* fs /* Filesystem object */ -) -{ - FRESULT res; - - - res = sync_window(fs); - if (res == FR_OK) { - if (fs->fs_type == FS_FAT32 && fs->fsi_flag == 1) { /* FAT32: Update FSInfo sector if needed */ - /* Create FSInfo structure */ - mem_set(fs->win, 0, SS(fs)); - st_word(fs->win + BS_55AA, 0xAA55); - st_dword(fs->win + FSI_LeadSig, 0x41615252); - st_dword(fs->win + FSI_StrucSig, 0x61417272); - st_dword(fs->win + FSI_Free_Count, fs->free_clst); - st_dword(fs->win + FSI_Nxt_Free, fs->last_clst); - /* Write it into the FSInfo sector */ - fs->winsect = fs->volbase + 1; - disk_write(fs->pdrv, fs->win, fs->winsect, 1); - fs->fsi_flag = 0; - } - /* Make sure that no pending write process in the lower layer */ - if (disk_ioctl(fs->pdrv, CTRL_SYNC, 0) != RES_OK) res = FR_DISK_ERR; - } - - return res; -} - -#endif - - - -/*-----------------------------------------------------------------------*/ -/* Get physical sector number from cluster number */ -/*-----------------------------------------------------------------------*/ - -static DWORD clst2sect ( /* !=0:Sector number, 0:Failed (invalid cluster#) */ - FATFS* fs, /* Filesystem object */ - DWORD clst /* Cluster# to be converted */ -) -{ - clst -= 2; /* Cluster number is origin from 2 */ - if (clst >= fs->n_fatent - 2) return 0; /* Is it invalid cluster number? */ - return fs->database + fs->csize * clst; /* Start sector number of the cluster */ -} - - - - -/*-----------------------------------------------------------------------*/ -/* FAT access - Read value of a FAT entry */ -/*-----------------------------------------------------------------------*/ - -static DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Internal error, 2..0x7FFFFFFF:Cluster status */ - FFOBJID* obj, /* Corresponding object */ - DWORD clst /* Cluster number to get the value */ -) -{ - UINT wc, bc; - DWORD val; - FATFS *fs = obj->fs; - - - if (clst < 2 || clst >= fs->n_fatent) { /* Check if in valid range */ - val = 1; /* Internal error */ - - } else { - val = 0xFFFFFFFF; /* Default value falls on disk error */ - - switch (fs->fs_type) { - case FS_FAT12 : - bc = (UINT)clst; bc += bc / 2; - if (move_window(fs, fs->fatbase + (bc / SS(fs))) != FR_OK) break; - wc = fs->win[bc++ % SS(fs)]; /* Get 1st byte of the entry */ - if (move_window(fs, fs->fatbase + (bc / SS(fs))) != FR_OK) break; - wc |= fs->win[bc % SS(fs)] << 8; /* Merge 2nd byte of the entry */ - val = (clst & 1) ? (wc >> 4) : (wc & 0xFFF); /* Adjust bit position */ - break; - - case FS_FAT16 : - if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 2))) != FR_OK) break; - val = ld_word(fs->win + clst * 2 % SS(fs)); /* Simple WORD array */ - break; - - case FS_FAT32 : - if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4))) != FR_OK) break; - val = ld_dword(fs->win + clst * 4 % SS(fs)) & 0x0FFFFFFF; /* Simple DWORD array but mask out upper 4 bits */ - break; -#if FF_FS_EXFAT - case FS_EXFAT : - if ((obj->objsize != 0 && obj->sclust != 0) || obj->stat == 0) { /* Object except root dir must have valid data length */ - DWORD cofs = clst - obj->sclust; /* Offset from start cluster */ - DWORD clen = (DWORD)((obj->objsize - 1) / SS(fs)) / fs->csize; /* Number of clusters - 1 */ - - if (obj->stat == 2 && cofs <= clen) { /* Is it a contiguous chain? */ - val = (cofs == clen) ? 0x7FFFFFFF : clst + 1; /* No data on the FAT, generate the value */ - break; - } - if (obj->stat == 3 && cofs < obj->n_cont) { /* Is it in the 1st fragment? */ - val = clst + 1; /* Generate the value */ - break; - } - if (obj->stat != 2) { /* Get value from FAT if FAT chain is valid */ - if (obj->n_frag != 0) { /* Is it on the growing edge? */ - val = 0x7FFFFFFF; /* Generate EOC */ - } else { - if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4))) != FR_OK) break; - val = ld_dword(fs->win + clst * 4 % SS(fs)) & 0x7FFFFFFF; - } - break; - } - } - /* go to default */ -#endif - default: - val = 1; /* Internal error */ - } - } - - return val; -} - - - - -#if !FF_FS_READONLY -/*-----------------------------------------------------------------------*/ -/* FAT access - Change value of a FAT entry */ -/*-----------------------------------------------------------------------*/ - -static FRESULT put_fat ( /* FR_OK(0):succeeded, !=0:error */ - FATFS* fs, /* Corresponding filesystem object */ - DWORD clst, /* FAT index number (cluster number) to be changed */ - DWORD val /* New value to be set to the entry */ -) -{ - UINT bc; - BYTE *p; - FRESULT res = FR_INT_ERR; - - - if (clst >= 2 && clst < fs->n_fatent) { /* Check if in valid range */ - switch (fs->fs_type) { - case FS_FAT12 : - bc = (UINT)clst; bc += bc / 2; /* bc: byte offset of the entry */ - res = move_window(fs, fs->fatbase + (bc / SS(fs))); - if (res != FR_OK) break; - p = fs->win + bc++ % SS(fs); - *p = (clst & 1) ? ((*p & 0x0F) | ((BYTE)val << 4)) : (BYTE)val; /* Put 1st byte */ - fs->wflag = 1; - res = move_window(fs, fs->fatbase + (bc / SS(fs))); - if (res != FR_OK) break; - p = fs->win + bc % SS(fs); - *p = (clst & 1) ? (BYTE)(val >> 4) : ((*p & 0xF0) | ((BYTE)(val >> 8) & 0x0F)); /* Put 2nd byte */ - fs->wflag = 1; - break; - - case FS_FAT16 : - res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 2))); - if (res != FR_OK) break; - st_word(fs->win + clst * 2 % SS(fs), (WORD)val); /* Simple WORD array */ - fs->wflag = 1; - break; - - case FS_FAT32 : -#if FF_FS_EXFAT - case FS_EXFAT : -#endif - res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 4))); - if (res != FR_OK) break; - if (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) { - val = (val & 0x0FFFFFFF) | (ld_dword(fs->win + clst * 4 % SS(fs)) & 0xF0000000); - } - st_dword(fs->win + clst * 4 % SS(fs), val); - fs->wflag = 1; - break; - } - } - return res; -} - -#endif /* !FF_FS_READONLY */ - - - - -#if FF_FS_EXFAT && !FF_FS_READONLY -/*-----------------------------------------------------------------------*/ -/* exFAT: Accessing FAT and Allocation Bitmap */ -/*-----------------------------------------------------------------------*/ - -/*--------------------------------------*/ -/* Find a contiguous free cluster block */ -/*--------------------------------------*/ - -static DWORD find_bitmap ( /* 0:Not found, 2..:Cluster block found, 0xFFFFFFFF:Disk error */ - FATFS* fs, /* Filesystem object */ - DWORD clst, /* Cluster number to scan from */ - DWORD ncl /* Number of contiguous clusters to find (1..) */ -) -{ - BYTE bm, bv; - UINT i; - DWORD val, scl, ctr; - - - clst -= 2; /* The first bit in the bitmap corresponds to cluster #2 */ - if (clst >= fs->n_fatent - 2) clst = 0; - scl = val = clst; ctr = 0; - for (;;) { - if (move_window(fs, fs->database + val / 8 / SS(fs)) != FR_OK) return 0xFFFFFFFF; /* (assuming bitmap is located top of the cluster heap) */ - i = val / 8 % SS(fs); bm = 1 << (val % 8); - do { - do { - bv = fs->win[i] & bm; bm <<= 1; /* Get bit value */ - if (++val >= fs->n_fatent - 2) { /* Next cluster (with wrap-around) */ - val = 0; bm = 0; i = SS(fs); - } - if (bv == 0) { /* Is it a free cluster? */ - if (++ctr == ncl) return scl + 2; /* Check if run length is sufficient for required */ - } else { - scl = val; ctr = 0; /* Encountered a cluster in-use, restart to scan */ - } - if (val == clst) return 0; /* All cluster scanned? */ - } while (bm != 0); - bm = 1; - } while (++i < SS(fs)); - } -} - - -/*----------------------------------------*/ -/* Set/Clear a block of allocation bitmap */ -/*----------------------------------------*/ - -static FRESULT change_bitmap ( - FATFS* fs, /* Filesystem object */ - DWORD clst, /* Cluster number to change from */ - DWORD ncl, /* Number of clusters to be changed */ - int bv /* bit value to be set (0 or 1) */ -) -{ - BYTE bm; - UINT i; - DWORD sect; - - - clst -= 2; /* The first bit corresponds to cluster #2 */ - sect = fs->database + clst / 8 / SS(fs); /* Sector address (assuming bitmap is located top of the cluster heap) */ - i = clst / 8 % SS(fs); /* Byte offset in the sector */ - bm = 1 << (clst % 8); /* Bit mask in the byte */ - for (;;) { - if (move_window(fs, sect++) != FR_OK) return FR_DISK_ERR; - do { - do { - if (bv == (int)((fs->win[i] & bm) != 0)) return FR_INT_ERR; /* Is the bit expected value? */ - fs->win[i] ^= bm; /* Flip the bit */ - fs->wflag = 1; - if (--ncl == 0) return FR_OK; /* All bits processed? */ - } while (bm <<= 1); /* Next bit */ - bm = 1; - } while (++i < SS(fs)); /* Next byte */ - i = 0; - } -} - - -/*---------------------------------------------*/ -/* Fill the first fragment of the FAT chain */ -/*---------------------------------------------*/ - -static FRESULT fill_first_frag ( - FFOBJID* obj /* Pointer to the corresponding object */ -) -{ - FRESULT res; - DWORD cl, n; - - - if (obj->stat == 3) { /* Has the object been changed 'fragmented' in this session? */ - for (cl = obj->sclust, n = obj->n_cont; n; cl++, n--) { /* Create cluster chain on the FAT */ - res = put_fat(obj->fs, cl, cl + 1); - if (res != FR_OK) return res; - } - obj->stat = 0; /* Change status 'FAT chain is valid' */ - } - return FR_OK; -} - - -/*---------------------------------------------*/ -/* Fill the last fragment of the FAT chain */ -/*---------------------------------------------*/ - -static FRESULT fill_last_frag ( - FFOBJID* obj, /* Pointer to the corresponding object */ - DWORD lcl, /* Last cluster of the fragment */ - DWORD term /* Value to set the last FAT entry */ -) -{ - FRESULT res; - - - while (obj->n_frag > 0) { /* Create the chain of last fragment */ - res = put_fat(obj->fs, lcl - obj->n_frag + 1, (obj->n_frag > 1) ? lcl - obj->n_frag + 2 : term); - if (res != FR_OK) return res; - obj->n_frag--; - } - return FR_OK; -} - -#endif /* FF_FS_EXFAT && !FF_FS_READONLY */ - - - -#if !FF_FS_READONLY -/*-----------------------------------------------------------------------*/ -/* FAT handling - Remove a cluster chain */ -/*-----------------------------------------------------------------------*/ - -static FRESULT remove_chain ( /* FR_OK(0):succeeded, !=0:error */ - FFOBJID* obj, /* Corresponding object */ - DWORD clst, /* Cluster to remove a chain from */ - DWORD pclst /* Previous cluster of clst (0:entire chain) */ -) -{ - FRESULT res = FR_OK; - DWORD nxt; - FATFS *fs = obj->fs; -#if FF_FS_EXFAT || FF_USE_TRIM - DWORD scl = clst, ecl = clst; -#endif -#if FF_USE_TRIM - DWORD rt[2]; -#endif - - if (clst < 2 || clst >= fs->n_fatent) return FR_INT_ERR; /* Check if in valid range */ - - /* Mark the previous cluster 'EOC' on the FAT if it exists */ - if (pclst != 0 && (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT || obj->stat != 2)) { - res = put_fat(fs, pclst, 0xFFFFFFFF); - if (res != FR_OK) return res; - } - - /* Remove the chain */ - do { - nxt = get_fat(obj, clst); /* Get cluster status */ - if (nxt == 0) break; /* Empty cluster? */ - if (nxt == 1) return FR_INT_ERR; /* Internal error? */ - if (nxt == 0xFFFFFFFF) return FR_DISK_ERR; /* Disk error? */ - if (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) { - res = put_fat(fs, clst, 0); /* Mark the cluster 'free' on the FAT */ - if (res != FR_OK) return res; - } - if (fs->free_clst < fs->n_fatent - 2) { /* Update FSINFO */ - fs->free_clst++; - fs->fsi_flag |= 1; - } -#if FF_FS_EXFAT || FF_USE_TRIM - if (ecl + 1 == nxt) { /* Is next cluster contiguous? */ - ecl = nxt; - } else { /* End of contiguous cluster block */ -#if FF_FS_EXFAT - if (fs->fs_type == FS_EXFAT) { - res = change_bitmap(fs, scl, ecl - scl + 1, 0); /* Mark the cluster block 'free' on the bitmap */ - if (res != FR_OK) return res; - } -#endif -#if FF_USE_TRIM - rt[0] = clst2sect(fs, scl); /* Start of data area freed */ - rt[1] = clst2sect(fs, ecl) + fs->csize - 1; /* End of data area freed */ - disk_ioctl(fs->pdrv, CTRL_TRIM, rt); /* Inform device the data in the block is no longer needed */ -#endif - scl = ecl = nxt; - } -#endif - clst = nxt; /* Next cluster */ - } while (clst < fs->n_fatent); /* Repeat while not the last link */ - -#if FF_FS_EXFAT - /* Some post processes for chain status */ - if (fs->fs_type == FS_EXFAT) { - if (pclst == 0) { /* Has the entire chain been removed? */ - obj->stat = 0; /* Change the chain status 'initial' */ - } else { - if (obj->stat == 0) { /* Is it a fragmented chain from the beginning of this session? */ - clst = obj->sclust; /* Follow the chain to check if it gets contiguous */ - while (clst != pclst) { - nxt = get_fat(obj, clst); - if (nxt < 2) return FR_INT_ERR; - if (nxt == 0xFFFFFFFF) return FR_DISK_ERR; - if (nxt != clst + 1) break; /* Not contiguous? */ - clst++; - } - if (clst == pclst) { /* Has the chain got contiguous again? */ - obj->stat = 2; /* Change the chain status 'contiguous' */ - } - } else { - if (obj->stat == 3 && pclst >= obj->sclust && pclst <= obj->sclust + obj->n_cont) { /* Was the chain fragmented in this session and got contiguous again? */ - obj->stat = 2; /* Change the chain status 'contiguous' */ - } - } - } - } -#endif - return FR_OK; -} - - - - -/*-----------------------------------------------------------------------*/ -/* FAT handling - Stretch a chain or Create a new chain */ -/*-----------------------------------------------------------------------*/ - -static DWORD create_chain ( /* 0:No free cluster, 1:Internal error, 0xFFFFFFFF:Disk error, >=2:New cluster# */ - FFOBJID* obj, /* Corresponding object */ - DWORD clst /* Cluster# to stretch, 0:Create a new chain */ -) -{ - DWORD cs, ncl, scl; - FRESULT res; - FATFS *fs = obj->fs; - - - if (clst == 0) { /* Create a new chain */ - scl = fs->last_clst; /* Suggested cluster to start to find */ - if (scl == 0 || scl >= fs->n_fatent) scl = 1; - } - else { /* Stretch a chain */ - cs = get_fat(obj, clst); /* Check the cluster status */ - if (cs < 2) return 1; /* Test for insanity */ - if (cs == 0xFFFFFFFF) return cs; /* Test for disk error */ - if (cs < fs->n_fatent) return cs; /* It is already followed by next cluster */ - scl = clst; /* Cluster to start to find */ - } - if (fs->free_clst == 0) return 0; /* No free cluster */ - -#if FF_FS_EXFAT - if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ - ncl = find_bitmap(fs, scl, 1); /* Find a free cluster */ - if (ncl == 0 || ncl == 0xFFFFFFFF) return ncl; /* No free cluster or hard error? */ - res = change_bitmap(fs, ncl, 1, 1); /* Mark the cluster 'in use' */ - if (res == FR_INT_ERR) return 1; - if (res == FR_DISK_ERR) return 0xFFFFFFFF; - if (clst == 0) { /* Is it a new chain? */ - obj->stat = 2; /* Set status 'contiguous' */ - } else { /* It is a stretched chain */ - if (obj->stat == 2 && ncl != scl + 1) { /* Is the chain got fragmented? */ - obj->n_cont = scl - obj->sclust; /* Set size of the contiguous part */ - obj->stat = 3; /* Change status 'just fragmented' */ - } - } - if (obj->stat != 2) { /* Is the file non-contiguous? */ - if (ncl == clst + 1) { /* Is the cluster next to previous one? */ - obj->n_frag = obj->n_frag ? obj->n_frag + 1 : 2; /* Increment size of last framgent */ - } else { /* New fragment */ - if (obj->n_frag == 0) obj->n_frag = 1; - res = fill_last_frag(obj, clst, ncl); /* Fill last fragment on the FAT and link it to new one */ - if (res == FR_OK) obj->n_frag = 1; - } - } - } else -#endif - { /* On the FAT/FAT32 volume */ - ncl = 0; - if (scl == clst) { /* Stretching an existing chain? */ - ncl = scl + 1; /* Test if next cluster is free */ - if (ncl >= fs->n_fatent) ncl = 2; - cs = get_fat(obj, ncl); /* Get next cluster status */ - if (cs == 1 || cs == 0xFFFFFFFF) return cs; /* Test for error */ - if (cs != 0) { /* Not free? */ - cs = fs->last_clst; /* Start at suggested cluster if it is valid */ - if (cs >= 2 && cs < fs->n_fatent) scl = cs; - ncl = 0; - } - } - if (ncl == 0) { /* The new cluster cannot be contiguous and find another fragment */ - ncl = scl; /* Start cluster */ - for (;;) { - ncl++; /* Next cluster */ - if (ncl >= fs->n_fatent) { /* Check wrap-around */ - ncl = 2; - if (ncl > scl) return 0; /* No free cluster found? */ - } - cs = get_fat(obj, ncl); /* Get the cluster status */ - if (cs == 0) break; /* Found a free cluster? */ - if (cs == 1 || cs == 0xFFFFFFFF) return cs; /* Test for error */ - if (ncl == scl) return 0; /* No free cluster found? */ - } - } - res = put_fat(fs, ncl, 0xFFFFFFFF); /* Mark the new cluster 'EOC' */ - if (res == FR_OK && clst != 0) { - res = put_fat(fs, clst, ncl); /* Link it from the previous one if needed */ - } - } - - if (res == FR_OK) { /* Update FSINFO if function succeeded. */ - fs->last_clst = ncl; - if (fs->free_clst <= fs->n_fatent - 2) fs->free_clst--; - fs->fsi_flag |= 1; - } else { - ncl = (res == FR_DISK_ERR) ? 0xFFFFFFFF : 1; /* Failed. Generate error status */ - } - - return ncl; /* Return new cluster number or error status */ -} - -#endif /* !FF_FS_READONLY */ - - - - -#if FF_USE_FASTSEEK -/*-----------------------------------------------------------------------*/ -/* FAT handling - Convert offset into cluster with link map table */ -/*-----------------------------------------------------------------------*/ - -static DWORD clmt_clust ( /* <2:Error, >=2:Cluster number */ - FIL* fp, /* Pointer to the file object */ - FSIZE_t ofs /* File offset to be converted to cluster# */ -) -{ - DWORD cl, ncl, *tbl; - FATFS *fs = fp->obj.fs; - - - tbl = fp->cltbl + 1; /* Top of CLMT */ - cl = (DWORD)(ofs / SS(fs) / fs->csize); /* Cluster order from top of the file */ - for (;;) { - ncl = *tbl++; /* Number of cluters in the fragment */ - if (ncl == 0) return 0; /* End of table? (error) */ - if (cl < ncl) break; /* In this fragment? */ - cl -= ncl; tbl++; /* Next fragment */ - } - return cl + *tbl; /* Return the cluster number */ -} - -#endif /* FF_USE_FASTSEEK */ - - - - -/*-----------------------------------------------------------------------*/ -/* Directory handling - Fill a cluster with zeros */ -/*-----------------------------------------------------------------------*/ - -#if !FF_FS_READONLY -static FRESULT dir_clear ( /* Returns FR_OK or FR_DISK_ERR */ - FATFS *fs, /* Filesystem object */ - DWORD clst /* Directory table to clear */ -) -{ - DWORD sect; - UINT n, szb; - BYTE *ibuf; - - - if (sync_window(fs) != FR_OK) return FR_DISK_ERR; /* Flush disk access window */ - sect = clst2sect(fs, clst); /* Top of the cluster */ - fs->winsect = sect; /* Set window to top of the cluster */ - mem_set(fs->win, 0, SS(fs)); /* Clear window buffer */ -#if FF_USE_LFN == 3 /* Quick table clear by using multi-secter write */ - /* Allocate a temporary buffer */ - for (szb = ((DWORD)fs->csize * SS(fs) >= MAX_MALLOC) ? MAX_MALLOC : fs->csize * SS(fs), ibuf = 0; szb > SS(fs) && (ibuf = ff_memalloc(szb)) == 0; szb /= 2) ; - if (szb > SS(fs)) { /* Buffer allocated? */ - mem_set(ibuf, 0, szb); - szb /= SS(fs); /* Bytes -> Sectors */ - for (n = 0; n < fs->csize && disk_write(fs->pdrv, ibuf, sect + n, szb) == RES_OK; n += szb) ; /* Fill the cluster with 0 */ - ff_memfree(ibuf); - } else -#endif - { - ibuf = fs->win; szb = 1; /* Use window buffer (many single-sector writes may take a time) */ - for (n = 0; n < fs->csize && disk_write(fs->pdrv, ibuf, sect + n, szb) == RES_OK; n += szb) ; /* Fill the cluster with 0 */ - } - return (n == fs->csize) ? FR_OK : FR_DISK_ERR; -} -#endif /* !FF_FS_READONLY */ - - - - -/*-----------------------------------------------------------------------*/ -/* Directory handling - Set directory index */ -/*-----------------------------------------------------------------------*/ - -static FRESULT dir_sdi ( /* FR_OK(0):succeeded, !=0:error */ - DIR* dp, /* Pointer to directory object */ - DWORD ofs /* Offset of directory table */ -) -{ - DWORD csz, clst; - FATFS *fs = dp->obj.fs; - - - if (ofs >= (DWORD)((FF_FS_EXFAT && fs->fs_type == FS_EXFAT) ? MAX_DIR_EX : MAX_DIR) || ofs % SZDIRE) { /* Check range of offset and alignment */ - return FR_INT_ERR; - } - dp->dptr = ofs; /* Set current offset */ - clst = dp->obj.sclust; /* Table start cluster (0:root) */ - if (clst == 0 && fs->fs_type >= FS_FAT32) { /* Replace cluster# 0 with root cluster# */ - clst = fs->dirbase; - if (FF_FS_EXFAT) dp->obj.stat = 0; /* exFAT: Root dir has an FAT chain */ - } - - if (clst == 0) { /* Static table (root-directory on the FAT volume) */ - if (ofs / SZDIRE >= fs->n_rootdir) return FR_INT_ERR; /* Is index out of range? */ - dp->sect = fs->dirbase; - - } else { /* Dynamic table (sub-directory or root-directory on the FAT32/exFAT volume) */ - csz = (DWORD)fs->csize * SS(fs); /* Bytes per cluster */ - while (ofs >= csz) { /* Follow cluster chain */ - clst = get_fat(&dp->obj, clst); /* Get next cluster */ - if (clst == 0xFFFFFFFF) return FR_DISK_ERR; /* Disk error */ - if (clst < 2 || clst >= fs->n_fatent) return FR_INT_ERR; /* Reached to end of table or internal error */ - ofs -= csz; - } - dp->sect = clst2sect(fs, clst); - } - dp->clust = clst; /* Current cluster# */ - if (dp->sect == 0) return FR_INT_ERR; - dp->sect += ofs / SS(fs); /* Sector# of the directory entry */ - dp->dir = fs->win + (ofs % SS(fs)); /* Pointer to the entry in the win[] */ - - return FR_OK; -} - - - - -/*-----------------------------------------------------------------------*/ -/* Directory handling - Move directory table index next */ -/*-----------------------------------------------------------------------*/ - -static FRESULT dir_next ( /* FR_OK(0):succeeded, FR_NO_FILE:End of table, FR_DENIED:Could not stretch */ - DIR* dp, /* Pointer to the directory object */ - int stretch /* 0: Do not stretch table, 1: Stretch table if needed */ -) -{ - DWORD ofs, clst; - FATFS *fs = dp->obj.fs; - - - ofs = dp->dptr + SZDIRE; /* Next entry */ - if (dp->sect == 0 || ofs >= (DWORD)((FF_FS_EXFAT && fs->fs_type == FS_EXFAT) ? MAX_DIR_EX : MAX_DIR)) return FR_NO_FILE; /* Report EOT when offset has reached max value */ - - if (ofs % SS(fs) == 0) { /* Sector changed? */ - dp->sect++; /* Next sector */ - - if (dp->clust == 0) { /* Static table */ - if (ofs / SZDIRE >= fs->n_rootdir) { /* Report EOT if it reached end of static table */ - dp->sect = 0; return FR_NO_FILE; - } - } - else { /* Dynamic table */ - if ((ofs / SS(fs) & (fs->csize - 1)) == 0) { /* Cluster changed? */ - clst = get_fat(&dp->obj, dp->clust); /* Get next cluster */ - if (clst <= 1) return FR_INT_ERR; /* Internal error */ - if (clst == 0xFFFFFFFF) return FR_DISK_ERR; /* Disk error */ - if (clst >= fs->n_fatent) { /* It reached end of dynamic table */ -#if !FF_FS_READONLY - if (!stretch) { /* If no stretch, report EOT */ - dp->sect = 0; return FR_NO_FILE; - } - clst = create_chain(&dp->obj, dp->clust); /* Allocate a cluster */ - if (clst == 0) return FR_DENIED; /* No free cluster */ - if (clst == 1) return FR_INT_ERR; /* Internal error */ - if (clst == 0xFFFFFFFF) return FR_DISK_ERR; /* Disk error */ - if (dir_clear(fs, clst) != FR_OK) return FR_DISK_ERR; /* Clean up the stretched table */ - if (FF_FS_EXFAT) dp->obj.stat |= 4; /* exFAT: The directory has been stretched */ -#else - if (!stretch) dp->sect = 0; /* (this line is to suppress compiler warning) */ - dp->sect = 0; return FR_NO_FILE; /* Report EOT */ -#endif - } - dp->clust = clst; /* Initialize data for new cluster */ - dp->sect = clst2sect(fs, clst); - } - } - } - dp->dptr = ofs; /* Current entry */ - dp->dir = fs->win + ofs % SS(fs); /* Pointer to the entry in the win[] */ - - return FR_OK; -} - - - - -#if !FF_FS_READONLY -/*-----------------------------------------------------------------------*/ -/* Directory handling - Reserve a block of directory entries */ -/*-----------------------------------------------------------------------*/ - -static FRESULT dir_alloc ( /* FR_OK(0):succeeded, !=0:error */ - DIR* dp, /* Pointer to the directory object */ - UINT nent /* Number of contiguous entries to allocate */ -) -{ - FRESULT res; - UINT n; - FATFS *fs = dp->obj.fs; - - - res = dir_sdi(dp, 0); - if (res == FR_OK) { - n = 0; - do { - res = move_window(fs, dp->sect); - if (res != FR_OK) break; -#if FF_FS_EXFAT - if ((fs->fs_type == FS_EXFAT) ? (int)((dp->dir[XDIR_Type] & 0x80) == 0) : (int)(dp->dir[DIR_Name] == DDEM || dp->dir[DIR_Name] == 0)) { -#else - if (dp->dir[DIR_Name] == DDEM || dp->dir[DIR_Name] == 0) { -#endif - if (++n == nent) break; /* A block of contiguous free entries is found */ - } else { - n = 0; /* Not a blank entry. Restart to search */ - } - res = dir_next(dp, 1); - } while (res == FR_OK); /* Next entry with table stretch enabled */ - } - - if (res == FR_NO_FILE) res = FR_DENIED; /* No directory entry to allocate */ - return res; -} - -#endif /* !FF_FS_READONLY */ - - - - -/*-----------------------------------------------------------------------*/ -/* FAT: Directory handling - Load/Store start cluster number */ -/*-----------------------------------------------------------------------*/ - -static DWORD ld_clust ( /* Returns the top cluster value of the SFN entry */ - FATFS* fs, /* Pointer to the fs object */ - const BYTE* dir /* Pointer to the key entry */ -) -{ - DWORD cl; - - cl = ld_word(dir + DIR_FstClusLO); - if (fs->fs_type == FS_FAT32) { - cl |= (DWORD)ld_word(dir + DIR_FstClusHI) << 16; - } - - return cl; -} - - -#if !FF_FS_READONLY -static void st_clust ( - FATFS* fs, /* Pointer to the fs object */ - BYTE* dir, /* Pointer to the key entry */ - DWORD cl /* Value to be set */ -) -{ - st_word(dir + DIR_FstClusLO, (WORD)cl); - if (fs->fs_type == FS_FAT32) { - st_word(dir + DIR_FstClusHI, (WORD)(cl >> 16)); - } -} -#endif - - - -#if FF_USE_LFN -/*--------------------------------------------------------*/ -/* FAT-LFN: Compare a part of file name with an LFN entry */ -/*--------------------------------------------------------*/ - -static int cmp_lfn ( /* 1:matched, 0:not matched */ - const WCHAR* lfnbuf, /* Pointer to the LFN working buffer to be compared */ - BYTE* dir /* Pointer to the directory entry containing the part of LFN */ -) -{ - UINT i, s; - WCHAR wc, uc; - - - if (ld_word(dir + LDIR_FstClusLO) != 0) return 0; /* Check LDIR_FstClusLO */ - - i = ((dir[LDIR_Ord] & 0x3F) - 1) * 13; /* Offset in the LFN buffer */ - - for (wc = 1, s = 0; s < 13; s++) { /* Process all characters in the entry */ - uc = ld_word(dir + LfnOfs[s]); /* Pick an LFN character */ - if (wc != 0) { - if (i >= FF_MAX_LFN || ff_wtoupper(uc) != ff_wtoupper(lfnbuf[i++])) { /* Compare it */ - return 0; /* Not matched */ - } - wc = uc; - } else { - if (uc != 0xFFFF) return 0; /* Check filler */ - } - } - - if ((dir[LDIR_Ord] & LLEF) && wc && lfnbuf[i]) return 0; /* Last segment matched but different length */ - - return 1; /* The part of LFN matched */ -} - - -#if FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2 || FF_USE_LABEL || FF_FS_EXFAT -/*-----------------------------------------------------*/ -/* FAT-LFN: Pick a part of file name from an LFN entry */ -/*-----------------------------------------------------*/ - -static int pick_lfn ( /* 1:succeeded, 0:buffer overflow or invalid LFN entry */ - WCHAR* lfnbuf, /* Pointer to the LFN working buffer */ - BYTE* dir /* Pointer to the LFN entry */ -) -{ - UINT i, s; - WCHAR wc, uc; - - - if (ld_word(dir + LDIR_FstClusLO) != 0) return 0; /* Check LDIR_FstClusLO is 0 */ - - i = ((dir[LDIR_Ord] & ~LLEF) - 1) * 13; /* Offset in the LFN buffer */ - - for (wc = 1, s = 0; s < 13; s++) { /* Process all characters in the entry */ - uc = ld_word(dir + LfnOfs[s]); /* Pick an LFN character */ - if (wc != 0) { - if (i >= FF_MAX_LFN) return 0; /* Buffer overflow? */ - lfnbuf[i++] = wc = uc; /* Store it */ - } else { - if (uc != 0xFFFF) return 0; /* Check filler */ - } - } - - if (dir[LDIR_Ord] & LLEF) { /* Put terminator if it is the last LFN part */ - if (i >= FF_MAX_LFN) return 0; /* Buffer overflow? */ - lfnbuf[i] = 0; - } - - return 1; /* The part of LFN is valid */ -} -#endif - - -#if !FF_FS_READONLY -/*-----------------------------------------*/ -/* FAT-LFN: Create an entry of LFN entries */ -/*-----------------------------------------*/ - -static void put_lfn ( - const WCHAR* lfn, /* Pointer to the LFN */ - BYTE* dir, /* Pointer to the LFN entry to be created */ - BYTE ord, /* LFN order (1-20) */ - BYTE sum /* Checksum of the corresponding SFN */ -) -{ - UINT i, s; - WCHAR wc; - - - dir[LDIR_Chksum] = sum; /* Set checksum */ - dir[LDIR_Attr] = AM_LFN; /* Set attribute. LFN entry */ - dir[LDIR_Type] = 0; - st_word(dir + LDIR_FstClusLO, 0); - - i = (ord - 1) * 13; /* Get offset in the LFN working buffer */ - s = wc = 0; - do { - if (wc != 0xFFFF) wc = lfn[i++]; /* Get an effective character */ - st_word(dir + LfnOfs[s], wc); /* Put it */ - if (wc == 0) wc = 0xFFFF; /* Padding characters for left locations */ - } while (++s < 13); - if (wc == 0xFFFF || !lfn[i]) ord |= LLEF; /* Last LFN part is the start of LFN sequence */ - dir[LDIR_Ord] = ord; /* Set the LFN order */ -} - -#endif /* !FF_FS_READONLY */ -#endif /* FF_USE_LFN */ - - - -#if FF_USE_LFN && !FF_FS_READONLY -/*-----------------------------------------------------------------------*/ -/* FAT-LFN: Create a Numbered SFN */ -/*-----------------------------------------------------------------------*/ - -static void gen_numname ( - BYTE* dst, /* Pointer to the buffer to store numbered SFN */ - const BYTE* src, /* Pointer to SFN */ - const WCHAR* lfn, /* Pointer to LFN */ - UINT seq /* Sequence number */ -) -{ - BYTE ns[8], c; - UINT i, j; - WCHAR wc; - DWORD sr; - - - mem_cpy(dst, src, 11); - - if (seq > 5) { /* In case of many collisions, generate a hash number instead of sequential number */ - sr = seq; - while (*lfn) { /* Create a CRC as hash value */ - wc = *lfn++; - for (i = 0; i < 16; i++) { - sr = (sr << 1) + (wc & 1); - wc >>= 1; - if (sr & 0x10000) sr ^= 0x11021; - } - } - seq = (UINT)sr; - } - - /* itoa (hexdecimal) */ - i = 7; - do { - c = (BYTE)((seq % 16) + '0'); - if (c > '9') c += 7; - ns[i--] = c; - seq /= 16; - } while (seq); - ns[i] = '~'; - - /* Append the number to the SFN body */ - for (j = 0; j < i && dst[j] != ' '; j++) { - if (dbc_1st(dst[j])) { - if (j == i - 1) break; - j++; - } - } - do { - dst[j++] = (i < 8) ? ns[i++] : ' '; - } while (j < 8); -} -#endif /* FF_USE_LFN && !FF_FS_READONLY */ - - - -#if FF_USE_LFN -/*-----------------------------------------------------------------------*/ -/* FAT-LFN: Calculate checksum of an SFN entry */ -/*-----------------------------------------------------------------------*/ - -static BYTE sum_sfn ( - const BYTE* dir /* Pointer to the SFN entry */ -) -{ - BYTE sum = 0; - UINT n = 11; - - do { - sum = (sum >> 1) + (sum << 7) + *dir++; - } while (--n); - return sum; -} - -#endif /* FF_USE_LFN */ - - - -#if FF_FS_EXFAT -/*-----------------------------------------------------------------------*/ -/* exFAT: Checksum */ -/*-----------------------------------------------------------------------*/ - -static WORD xdir_sum ( /* Get checksum of the directoly entry block */ - const BYTE* dir /* Directory entry block to be calculated */ -) -{ - UINT i, szblk; - WORD sum; - - - szblk = (dir[XDIR_NumSec] + 1) * SZDIRE; /* Number of bytes of the entry block */ - for (i = sum = 0; i < szblk; i++) { - if (i == XDIR_SetSum) { /* Skip 2-byte sum field */ - i++; - } else { - sum = ((sum & 1) ? 0x8000 : 0) + (sum >> 1) + dir[i]; - } - } - return sum; -} - - - -static WORD xname_sum ( /* Get check sum (to be used as hash) of the file name */ - const WCHAR* name /* File name to be calculated */ -) -{ - WCHAR chr; - WORD sum = 0; - - - while ((chr = *name++) != 0) { - chr = (WCHAR)ff_wtoupper(chr); /* File name needs to be up-case converted */ - sum = ((sum & 1) ? 0x8000 : 0) + (sum >> 1) + (chr & 0xFF); - sum = ((sum & 1) ? 0x8000 : 0) + (sum >> 1) + (chr >> 8); - } - return sum; -} - - -#if !FF_FS_READONLY && FF_USE_MKFS -static DWORD xsum32 ( /* Returns 32-bit checksum */ - BYTE dat, /* Byte to be calculated (byte-by-byte processing) */ - DWORD sum /* Previous sum value */ -) -{ - sum = ((sum & 1) ? 0x80000000 : 0) + (sum >> 1) + dat; - return sum; -} -#endif - - -#if FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2 -/*------------------------------------------------------*/ -/* exFAT: Get object information from a directory block */ -/*------------------------------------------------------*/ - -static void get_xfileinfo ( - BYTE* dirb, /* Pointer to the direcotry entry block 85+C0+C1s */ - FILINFO* fno /* Buffer to store the extracted file information */ -) -{ - WCHAR wc, hs; - UINT di, si, nc; - - /* Get file name from the entry block */ - si = SZDIRE * 2; /* 1st C1 entry */ - nc = 0; hs = 0; di = 0; - while (nc < dirb[XDIR_NumName]) { - if (si >= MAXDIRB(FF_MAX_LFN)) { di = 0; break; } /* Truncated directory block? */ - if ((si % SZDIRE) == 0) si += 2; /* Skip entry type field */ - wc = ld_word(dirb + si); si += 2; nc++; /* Get a character */ - if (hs == 0 && IsSurrogate(wc)) { /* Is it a surrogate? */ - hs = wc; continue; /* Get low surrogate */ - } - wc = put_utf((DWORD)hs << 16 | wc, &fno->fname[di], FF_LFN_BUF - di); /* Store it in API encoding */ - if (wc == 0) { di = 0; break; } /* Buffer overflow or wrong encoding? */ - di += wc; - hs = 0; - } - if (hs != 0) di = 0; /* Broken surrogate pair? */ - if (di == 0) fno->fname[di++] = '?'; /* Inaccessible object name? */ - fno->fname[di] = 0; /* Terminate the name */ - fno->altname[0] = 0; /* exFAT does not support SFN */ - - fno->fattrib = dirb[XDIR_Attr]; /* Attribute */ - fno->fsize = (fno->fattrib & AM_DIR) ? 0 : ld_qword(dirb + XDIR_FileSize); /* Size */ - fno->ftime = ld_word(dirb + XDIR_ModTime + 0); /* Time */ - fno->fdate = ld_word(dirb + XDIR_ModTime + 2); /* Date */ -} - -#endif /* FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2 */ - - -/*-----------------------------------*/ -/* exFAT: Get a directry entry block */ -/*-----------------------------------*/ - -static FRESULT load_xdir ( /* FR_INT_ERR: invalid entry block */ - DIR* dp /* Reading direcotry object pointing top of the entry block to load */ -) -{ - FRESULT res; - UINT i, sz_ent; - BYTE* dirb = dp->obj.fs->dirbuf; /* Pointer to the on-memory direcotry entry block 85+C0+C1s */ - - - /* Load 85 entry */ - res = move_window(dp->obj.fs, dp->sect); - if (res != FR_OK) return res; - if (dp->dir[XDIR_Type] != 0x85) return FR_INT_ERR; /* Invalid order */ - mem_cpy(dirb + 0 * SZDIRE, dp->dir, SZDIRE); - sz_ent = (dirb[XDIR_NumSec] + 1) * SZDIRE; - if (sz_ent < 3 * SZDIRE || sz_ent > 19 * SZDIRE) return FR_INT_ERR; - - /* Load C0 entry */ - res = dir_next(dp, 0); - if (res == FR_NO_FILE) res = FR_INT_ERR; /* It cannot be */ - if (res != FR_OK) return res; - res = move_window(dp->obj.fs, dp->sect); - if (res != FR_OK) return res; - if (dp->dir[XDIR_Type] != 0xC0) return FR_INT_ERR; /* Invalid order */ - mem_cpy(dirb + 1 * SZDIRE, dp->dir, SZDIRE); - if (MAXDIRB(dirb[XDIR_NumName]) > sz_ent) return FR_INT_ERR; - - /* Load C1 entries */ - i = 2 * SZDIRE; /* C1 offset to load */ - do { - res = dir_next(dp, 0); - if (res == FR_NO_FILE) res = FR_INT_ERR; /* It cannot be */ - if (res != FR_OK) return res; - res = move_window(dp->obj.fs, dp->sect); - if (res != FR_OK) return res; - if (dp->dir[XDIR_Type] != 0xC1) return FR_INT_ERR; /* Invalid order */ - if (i < MAXDIRB(FF_MAX_LFN)) mem_cpy(dirb + i, dp->dir, SZDIRE); - } while ((i += SZDIRE) < sz_ent); - - /* Sanity check (do it for only accessible object) */ - if (i <= MAXDIRB(FF_MAX_LFN)) { - if (xdir_sum(dirb) != ld_word(dirb + XDIR_SetSum)) return FR_INT_ERR; - } - return FR_OK; -} - - -/*------------------------------------------------------------------*/ -/* exFAT: Initialize object allocation info with loaded entry block */ -/*------------------------------------------------------------------*/ - -static void init_alloc_info ( - FATFS* fs, /* Filesystem object */ - FFOBJID* obj /* Object allocation information to be initialized */ -) -{ - obj->sclust = ld_dword(fs->dirbuf + XDIR_FstClus); /* Start cluster */ - obj->objsize = ld_qword(fs->dirbuf + XDIR_FileSize); /* Size */ - obj->stat = fs->dirbuf[XDIR_GenFlags] & 2; /* Allocation status */ - obj->n_frag = 0; /* No last fragment info */ -} - - - -#if !FF_FS_READONLY || FF_FS_RPATH != 0 -/*------------------------------------------------*/ -/* exFAT: Load the object's directory entry block */ -/*------------------------------------------------*/ - -static FRESULT load_obj_xdir ( - DIR* dp, /* Blank directory object to be used to access containing direcotry */ - const FFOBJID* obj /* Object with its containing directory information */ -) -{ - FRESULT res; - - /* Open object containing directory */ - dp->obj.fs = obj->fs; - dp->obj.sclust = obj->c_scl; - dp->obj.stat = (BYTE)obj->c_size; - dp->obj.objsize = obj->c_size & 0xFFFFFF00; - dp->obj.n_frag = 0; - dp->blk_ofs = obj->c_ofs; - - res = dir_sdi(dp, dp->blk_ofs); /* Goto object's entry block */ - if (res == FR_OK) { - res = load_xdir(dp); /* Load the object's entry block */ - } - return res; -} -#endif - - -#if !FF_FS_READONLY -/*----------------------------------------*/ -/* exFAT: Store the directory entry block */ -/*----------------------------------------*/ - -static FRESULT store_xdir ( - DIR* dp /* Pointer to the direcotry object */ -) -{ - FRESULT res; - UINT nent; - BYTE* dirb = dp->obj.fs->dirbuf; /* Pointer to the direcotry entry block 85+C0+C1s */ - - /* Create set sum */ - st_word(dirb + XDIR_SetSum, xdir_sum(dirb)); - nent = dirb[XDIR_NumSec] + 1; - - /* Store the direcotry entry block to the directory */ - res = dir_sdi(dp, dp->blk_ofs); - while (res == FR_OK) { - res = move_window(dp->obj.fs, dp->sect); - if (res != FR_OK) break; - mem_cpy(dp->dir, dirb, SZDIRE); - dp->obj.fs->wflag = 1; - if (--nent == 0) break; - dirb += SZDIRE; - res = dir_next(dp, 0); - } - return (res == FR_OK || res == FR_DISK_ERR) ? res : FR_INT_ERR; -} - - - -/*-------------------------------------------*/ -/* exFAT: Create a new directory enrty block */ -/*-------------------------------------------*/ - -static void create_xdir ( - BYTE* dirb, /* Pointer to the direcotry entry block buffer */ - const WCHAR* lfn /* Pointer to the object name */ -) -{ - UINT i; - BYTE nc1, nlen; - WCHAR wc; - - - /* Create 85,C0 entry */ - mem_set(dirb, 0, 2 * SZDIRE); - dirb[0 * SZDIRE + XDIR_Type] = 0x85; /* 85 entry */ - dirb[1 * SZDIRE + XDIR_Type] = 0xC0; /* C0 entry */ - - /* Create C1 entries */ - i = SZDIRE * 2; /* Top of C1 entries */ - nlen = nc1 = 0; wc = 1; - do { - dirb[i++] = 0xC1; dirb[i++] = 0; /* Entry type C1 */ - do { /* Fill name field */ - if (wc != 0 && (wc = lfn[nlen]) != 0) nlen++; /* Get a character if exist */ - st_word(dirb + i, wc); /* Store it */ - i += 2; - } while (i % SZDIRE != 0); - nc1++; - } while (lfn[nlen]); /* Fill next entry if any char follows */ - - dirb[XDIR_NumName] = nlen; /* Set name length */ - dirb[XDIR_NumSec] = 1 + nc1; /* Set secondary count (C0 + C1s) */ - st_word(dirb + XDIR_NameHash, xname_sum(lfn)); /* Set name hash */ -} - -#endif /* !FF_FS_READONLY */ -#endif /* FF_FS_EXFAT */ - - - -#if FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2 || FF_USE_LABEL || FF_FS_EXFAT -/*-----------------------------------------------------------------------*/ -/* Read an object from the directory */ -/*-----------------------------------------------------------------------*/ - -#define dir_read_file(dp) dir_read(dp, 0) -#define dir_read_label(dp) dir_read(dp, 1) - -static FRESULT dir_read ( - DIR* dp, /* Pointer to the directory object */ - int vol /* Filtered by 0:file/directory or 1:volume label */ -) -{ - FRESULT res = FR_NO_FILE; - FATFS *fs = dp->obj.fs; - BYTE a, c; -#if FF_USE_LFN - BYTE ord = 0xFF, sum = 0xFF; -#endif - - while (dp->sect) { - res = move_window(fs, dp->sect); - if (res != FR_OK) break; - c = dp->dir[DIR_Name]; /* Test for the entry type */ - if (c == 0) { - res = FR_NO_FILE; break; /* Reached to end of the directory */ - } -#if FF_FS_EXFAT - if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ - if (FF_USE_LABEL && vol) { - if (c == 0x83) break; /* Volume label entry? */ - } else { - if (c == 0x85) { /* Start of the file entry block? */ - dp->blk_ofs = dp->dptr; /* Get location of the block */ - res = load_xdir(dp); /* Load the entry block */ - if (res == FR_OK) { - dp->obj.attr = fs->dirbuf[XDIR_Attr] & AM_MASK; /* Get attribute */ - } - break; - } - } - } else -#endif - { /* On the FAT/FAT32 volume */ - dp->obj.attr = a = dp->dir[DIR_Attr] & AM_MASK; /* Get attribute */ -#if FF_USE_LFN /* LFN configuration */ - if (c == DDEM || c == '.' || (int)((a & ~AM_ARC) == AM_VOL) != vol) { /* An entry without valid data */ - ord = 0xFF; - } else { - if (a == AM_LFN) { /* An LFN entry is found */ - if (c & LLEF) { /* Is it start of an LFN sequence? */ - sum = dp->dir[LDIR_Chksum]; - c &= (BYTE)~LLEF; ord = c; - dp->blk_ofs = dp->dptr; - } - /* Check LFN validity and capture it */ - ord = (c == ord && sum == dp->dir[LDIR_Chksum] && pick_lfn(fs->lfnbuf, dp->dir)) ? ord - 1 : 0xFF; - } else { /* An SFN entry is found */ - if (ord != 0 || sum != sum_sfn(dp->dir)) { /* Is there a valid LFN? */ - dp->blk_ofs = 0xFFFFFFFF; /* It has no LFN. */ - } - break; - } - } -#else /* Non LFN configuration */ - if (c != DDEM && c != '.' && a != AM_LFN && (int)((a & ~AM_ARC) == AM_VOL) == vol) { /* Is it a valid entry? */ - break; - } -#endif - } - res = dir_next(dp, 0); /* Next entry */ - if (res != FR_OK) break; - } - - if (res != FR_OK) dp->sect = 0; /* Terminate the read operation on error or EOT */ - return res; -} - -#endif /* FF_FS_MINIMIZE <= 1 || FF_USE_LABEL || FF_FS_RPATH >= 2 */ - - - -/*-----------------------------------------------------------------------*/ -/* Directory handling - Find an object in the directory */ -/*-----------------------------------------------------------------------*/ - -static FRESULT dir_find ( /* FR_OK(0):succeeded, !=0:error */ - DIR* dp /* Pointer to the directory object with the file name */ -) -{ - FRESULT res; - FATFS *fs = dp->obj.fs; - BYTE c; -#if FF_USE_LFN - BYTE a, ord, sum; -#endif - - res = dir_sdi(dp, 0); /* Rewind directory object */ - if (res != FR_OK) return res; -#if FF_FS_EXFAT - if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ - BYTE nc; - UINT di, ni; - WORD hash = xname_sum(fs->lfnbuf); /* Hash value of the name to find */ - - while ((res = dir_read_file(dp)) == FR_OK) { /* Read an item */ -#if FF_MAX_LFN < 255 - if (fs->dirbuf[XDIR_NumName] > FF_MAX_LFN) continue; /* Skip comparison if inaccessible object name */ -#endif - if (ld_word(fs->dirbuf + XDIR_NameHash) != hash) continue; /* Skip comparison if hash mismatched */ - for (nc = fs->dirbuf[XDIR_NumName], di = SZDIRE * 2, ni = 0; nc; nc--, di += 2, ni++) { /* Compare the name */ - if ((di % SZDIRE) == 0) di += 2; - if (ff_wtoupper(ld_word(fs->dirbuf + di)) != ff_wtoupper(fs->lfnbuf[ni])) break; - } - if (nc == 0 && !fs->lfnbuf[ni]) break; /* Name matched? */ - } - return res; - } -#endif - /* On the FAT/FAT32 volume */ -#if FF_USE_LFN - ord = sum = 0xFF; dp->blk_ofs = 0xFFFFFFFF; /* Reset LFN sequence */ -#endif - do { - res = move_window(fs, dp->sect); - if (res != FR_OK) break; - c = dp->dir[DIR_Name]; - if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */ -#if FF_USE_LFN /* LFN configuration */ - dp->obj.attr = a = dp->dir[DIR_Attr] & AM_MASK; - if (c == DDEM || ((a & AM_VOL) && a != AM_LFN)) { /* An entry without valid data */ - ord = 0xFF; dp->blk_ofs = 0xFFFFFFFF; /* Reset LFN sequence */ - } else { - if (a == AM_LFN) { /* An LFN entry is found */ - if (!(dp->fn[NSFLAG] & NS_NOLFN)) { - if (c & LLEF) { /* Is it start of LFN sequence? */ - sum = dp->dir[LDIR_Chksum]; - c &= (BYTE)~LLEF; ord = c; /* LFN start order */ - dp->blk_ofs = dp->dptr; /* Start offset of LFN */ - } - /* Check validity of the LFN entry and compare it with given name */ - ord = (c == ord && sum == dp->dir[LDIR_Chksum] && cmp_lfn(fs->lfnbuf, dp->dir)) ? ord - 1 : 0xFF; - } - } else { /* An SFN entry is found */ - if (ord == 0 && sum == sum_sfn(dp->dir)) break; /* LFN matched? */ - if (!(dp->fn[NSFLAG] & NS_LOSS) && !mem_cmp(dp->dir, dp->fn, 11)) break; /* SFN matched? */ - ord = 0xFF; dp->blk_ofs = 0xFFFFFFFF; /* Reset LFN sequence */ - } - } -#else /* Non LFN configuration */ - dp->obj.attr = dp->dir[DIR_Attr] & AM_MASK; - if (!(dp->dir[DIR_Attr] & AM_VOL) && !mem_cmp(dp->dir, dp->fn, 11)) break; /* Is it a valid entry? */ -#endif - res = dir_next(dp, 0); /* Next entry */ - } while (res == FR_OK); - - return res; -} - - - - -#if !FF_FS_READONLY -/*-----------------------------------------------------------------------*/ -/* Register an object to the directory */ -/*-----------------------------------------------------------------------*/ - -static FRESULT dir_register ( /* FR_OK:succeeded, FR_DENIED:no free entry or too many SFN collision, FR_DISK_ERR:disk error */ - DIR* dp /* Target directory with object name to be created */ -) -{ - FRESULT res; - FATFS *fs = dp->obj.fs; -#if FF_USE_LFN /* LFN configuration */ - UINT n, nlen, nent; - BYTE sn[12], sum; - - - if (dp->fn[NSFLAG] & (NS_DOT | NS_NONAME)) return FR_INVALID_NAME; /* Check name validity */ - for (nlen = 0; fs->lfnbuf[nlen]; nlen++) ; /* Get lfn length */ - -#if FF_FS_EXFAT - if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ - nent = (nlen + 14) / 15 + 2; /* Number of entries to allocate (85+C0+C1s) */ - res = dir_alloc(dp, nent); /* Allocate entries */ - if (res != FR_OK) return res; - dp->blk_ofs = dp->dptr - SZDIRE * (nent - 1); /* Set the allocated entry block offset */ - - if (dp->obj.stat & 4) { /* Has the directory been stretched? */ - dp->obj.stat &= ~4; - res = fill_first_frag(&dp->obj); /* Fill the first fragment on the FAT if needed */ - if (res != FR_OK) return res; - res = fill_last_frag(&dp->obj, dp->clust, 0xFFFFFFFF); /* Fill the last fragment on the FAT if needed */ - if (res != FR_OK) return res; - if (dp->obj.sclust != 0) { /* Is it a sub directory? */ - DIR dj; - - res = load_obj_xdir(&dj, &dp->obj); /* Load the object status */ - if (res != FR_OK) return res; - dp->obj.objsize += (DWORD)fs->csize * SS(fs); /* Increase the directory size by cluster size */ - st_qword(fs->dirbuf + XDIR_FileSize, dp->obj.objsize); /* Update the allocation status */ - st_qword(fs->dirbuf + XDIR_ValidFileSize, dp->obj.objsize); - fs->dirbuf[XDIR_GenFlags] = dp->obj.stat | 1; - res = store_xdir(&dj); /* Store the object status */ - if (res != FR_OK) return res; - } - } - - create_xdir(fs->dirbuf, fs->lfnbuf); /* Create on-memory directory block to be written later */ - return FR_OK; - } -#endif - /* On the FAT/FAT32 volume */ - mem_cpy(sn, dp->fn, 12); - if (sn[NSFLAG] & NS_LOSS) { /* When LFN is out of 8.3 format, generate a numbered name */ - dp->fn[NSFLAG] = NS_NOLFN; /* Find only SFN */ - for (n = 1; n < 100; n++) { - gen_numname(dp->fn, sn, fs->lfnbuf, n); /* Generate a numbered name */ - res = dir_find(dp); /* Check if the name collides with existing SFN */ - if (res != FR_OK) break; - } - if (n == 100) return FR_DENIED; /* Abort if too many collisions */ - if (res != FR_NO_FILE) return res; /* Abort if the result is other than 'not collided' */ - dp->fn[NSFLAG] = sn[NSFLAG]; - } - - /* Create an SFN with/without LFNs. */ - nent = (sn[NSFLAG] & NS_LFN) ? (nlen + 12) / 13 + 1 : 1; /* Number of entries to allocate */ - res = dir_alloc(dp, nent); /* Allocate entries */ - if (res == FR_OK && --nent) { /* Set LFN entry if needed */ - res = dir_sdi(dp, dp->dptr - nent * SZDIRE); - if (res == FR_OK) { - sum = sum_sfn(dp->fn); /* Checksum value of the SFN tied to the LFN */ - do { /* Store LFN entries in bottom first */ - res = move_window(fs, dp->sect); - if (res != FR_OK) break; - put_lfn(fs->lfnbuf, dp->dir, (BYTE)nent, sum); - fs->wflag = 1; - res = dir_next(dp, 0); /* Next entry */ - } while (res == FR_OK && --nent); - } - } - -#else /* Non LFN configuration */ - res = dir_alloc(dp, 1); /* Allocate an entry for SFN */ - -#endif - - /* Set SFN entry */ - if (res == FR_OK) { - res = move_window(fs, dp->sect); - if (res == FR_OK) { - mem_set(dp->dir, 0, SZDIRE); /* Clean the entry */ - mem_cpy(dp->dir + DIR_Name, dp->fn, 11); /* Put SFN */ -#if FF_USE_LFN - dp->dir[DIR_NTres] = dp->fn[NSFLAG] & (NS_BODY | NS_EXT); /* Put NT flag */ -#endif - fs->wflag = 1; - } - } - - return res; -} - -#endif /* !FF_FS_READONLY */ - - - -#if !FF_FS_READONLY && FF_FS_MINIMIZE == 0 -/*-----------------------------------------------------------------------*/ -/* Remove an object from the directory */ -/*-----------------------------------------------------------------------*/ - -static FRESULT dir_remove ( /* FR_OK:Succeeded, FR_DISK_ERR:A disk error */ - DIR* dp /* Directory object pointing the entry to be removed */ -) -{ - FRESULT res; - FATFS *fs = dp->obj.fs; -#if FF_USE_LFN /* LFN configuration */ - DWORD last = dp->dptr; - - res = (dp->blk_ofs == 0xFFFFFFFF) ? FR_OK : dir_sdi(dp, dp->blk_ofs); /* Goto top of the entry block if LFN is exist */ - if (res == FR_OK) { - do { - res = move_window(fs, dp->sect); - if (res != FR_OK) break; - if (FF_FS_EXFAT && fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ - dp->dir[XDIR_Type] &= 0x7F; /* Clear the entry InUse flag. */ - } else { /* On the FAT/FAT32 volume */ - dp->dir[DIR_Name] = DDEM; /* Mark the entry 'deleted'. */ - } - fs->wflag = 1; - if (dp->dptr >= last) break; /* If reached last entry then all entries of the object has been deleted. */ - res = dir_next(dp, 0); /* Next entry */ - } while (res == FR_OK); - if (res == FR_NO_FILE) res = FR_INT_ERR; - } -#else /* Non LFN configuration */ - - res = move_window(fs, dp->sect); - if (res == FR_OK) { - dp->dir[DIR_Name] = DDEM; /* Mark the entry 'deleted'.*/ - fs->wflag = 1; - } -#endif - - return res; -} - -#endif /* !FF_FS_READONLY && FF_FS_MINIMIZE == 0 */ - - - -#if FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2 -/*-----------------------------------------------------------------------*/ -/* Get file information from directory entry */ -/*-----------------------------------------------------------------------*/ - -static void get_fileinfo ( - DIR* dp, /* Pointer to the directory object */ - FILINFO* fno /* Pointer to the file information to be filled */ -) -{ - UINT si, di; -#if FF_USE_LFN - WCHAR wc, hs; - FATFS *fs = dp->obj.fs; -#else - TCHAR c; -#endif - - - fno->fname[0] = 0; /* Invaidate file info */ - if (dp->sect == 0) return; /* Exit if read pointer has reached end of directory */ - -#if FF_USE_LFN /* LFN configuration */ -#if FF_FS_EXFAT - if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ - get_xfileinfo(fs->dirbuf, fno); - return; - } else -#endif - { /* On the FAT/FAT32 volume */ - if (dp->blk_ofs != 0xFFFFFFFF) { /* Get LFN if available */ - si = di = hs = 0; - while (fs->lfnbuf[si] != 0) { - wc = fs->lfnbuf[si++]; /* Get an LFN character (UTF-16) */ - if (hs == 0 && IsSurrogate(wc)) { /* Is it a surrogate? */ - hs = wc; continue; /* Get low surrogate */ - } - wc = put_utf((DWORD)hs << 16 | wc, &fno->fname[di], FF_LFN_BUF - di); /* Store it in UTF-16 or UTF-8 encoding */ - if (wc == 0) { di = 0; break; } /* Invalid char or buffer overflow? */ - di += wc; - hs = 0; - } - if (hs != 0) di = 0; /* Broken surrogate pair? */ - fno->fname[di] = 0; /* Terminate the LFN (null string means LFN is invalid) */ - } - } - - si = di = 0; - while (si < 11) { /* Get SFN from SFN entry */ - wc = dp->dir[si++]; /* Get a char */ - if (wc == ' ') continue; /* Skip padding spaces */ - if (wc == RDDEM) wc = DDEM; /* Restore replaced DDEM character */ - if (si == 9 && di < FF_SFN_BUF) fno->altname[di++] = '.'; /* Insert a . if extension is exist */ -#if FF_LFN_UNICODE >= 1 /* Unicode output */ - if (dbc_1st((BYTE)wc) && si != 8 && si != 11 && dbc_2nd(dp->dir[si])) { /* Make a DBC if needed */ - wc = wc << 8 | dp->dir[si++]; - } - wc = ff_oem2uni(wc, CODEPAGE); /* ANSI/OEM -> Unicode */ - if (wc == 0) { di = 0; break; } /* Wrong char in the current code page? */ - wc = put_utf(wc, &fno->altname[di], FF_SFN_BUF - di); /* Store it in Unicode */ - if (wc == 0) { di = 0; break; } /* Buffer overflow? */ - di += wc; -#else /* ANSI/OEM output */ - fno->altname[di++] = (TCHAR)wc; /* Store it without any conversion */ -#endif - } - fno->altname[di] = 0; /* Terminate the SFN (null string means SFN is invalid) */ - - if (fno->fname[0] == 0) { /* If LFN is invalid, altname[] needs to be copied to fname[] */ - if (di == 0) { /* If LFN and SFN both are invalid, this object is inaccesible */ - fno->fname[di++] = '?'; - } else { - for (si = di = 0; fno->altname[si]; si++, di++) { /* Copy altname[] to fname[] with case information */ - wc = (WCHAR)fno->altname[si]; - if (IsUpper(wc) && (dp->dir[DIR_NTres] & ((si >= 9) ? NS_EXT : NS_BODY))) wc += 0x20; - fno->fname[di] = (TCHAR)wc; - } - } - fno->fname[di] = 0; /* Terminate the LFN */ - if (!dp->dir[DIR_NTres]) fno->altname[0] = 0; /* Altname is not needed if neither LFN nor case info is exist. */ - } - -#else /* Non-LFN configuration */ - si = di = 0; - while (si < 11) { /* Copy name body and extension */ - c = (TCHAR)dp->dir[si++]; - if (c == ' ') continue; /* Skip padding spaces */ - if (c == RDDEM) c = DDEM; /* Restore replaced DDEM character */ - if (si == 9) fno->fname[di++] = '.';/* Insert a . if extension is exist */ - fno->fname[di++] = c; - } - fno->fname[di] = 0; -#endif - - fno->fattrib = dp->dir[DIR_Attr]; /* Attribute */ - fno->fsize = ld_dword(dp->dir + DIR_FileSize); /* Size */ - fno->ftime = ld_word(dp->dir + DIR_ModTime + 0); /* Time */ - fno->fdate = ld_word(dp->dir + DIR_ModTime + 2); /* Date */ -} - -#endif /* FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2 */ - - - -#if FF_USE_FIND && FF_FS_MINIMIZE <= 1 -/*-----------------------------------------------------------------------*/ -/* Pattern matching */ -/*-----------------------------------------------------------------------*/ - -static DWORD get_achar ( /* Get a character and advances ptr */ - const TCHAR** ptr /* Pointer to pointer to the ANSI/OEM or Unicode string */ -) -{ - DWORD chr; - - -#if FF_USE_LFN && FF_LFN_UNICODE >= 1 /* Unicode input */ - chr = tchar2uni(ptr); - if (chr == 0xFFFFFFFF) chr = 0; /* Wrong UTF encoding is recognized as end of the string */ - chr = ff_wtoupper(chr); - -#else /* ANSI/OEM input */ - chr = (BYTE)*(*ptr)++; /* Get a byte */ - if (IsLower(chr)) chr -= 0x20; /* To upper ASCII char */ -#if FF_CODE_PAGE == 0 - if (ExCvt && chr >= 0x80) chr = ExCvt[chr - 0x80]; /* To upper SBCS extended char */ -#elif FF_CODE_PAGE < 900 - if (chr >= 0x80) chr = ExCvt[chr - 0x80]; /* To upper SBCS extended char */ -#endif -#if FF_CODE_PAGE == 0 || FF_CODE_PAGE >= 900 - if (dbc_1st((BYTE)chr)) { /* Get DBC 2nd byte if needed */ - chr = dbc_2nd((BYTE)**ptr) ? chr << 8 | (BYTE)*(*ptr)++ : 0; - } -#endif - -#endif - return chr; -} - - -static int pattern_matching ( /* 0:not matched, 1:matched */ - const TCHAR* pat, /* Matching pattern */ - const TCHAR* nam, /* String to be tested */ - int skip, /* Number of pre-skip chars (number of ?s) */ - int inf /* Infinite search (* specified) */ -) -{ - const TCHAR *pp, *np; - DWORD pc, nc; - int nm, nx; - - - while (skip--) { /* Pre-skip name chars */ - if (!get_achar(&nam)) return 0; /* Branch mismatched if less name chars */ - } - if (*pat == 0 && inf) return 1; /* (short circuit) */ - - do { - pp = pat; np = nam; /* Top of pattern and name to match */ - for (;;) { - if (*pp == '?' || *pp == '*') { /* Wildcard? */ - nm = nx = 0; - do { /* Analyze the wildcard block */ - if (*pp++ == '?') nm++; else nx = 1; - } while (*pp == '?' || *pp == '*'); - if (pattern_matching(pp, np, nm, nx)) return 1; /* Test new branch (recurs upto number of wildcard blocks in the pattern) */ - nc = *np; break; /* Branch mismatched */ - } - pc = get_achar(&pp); /* Get a pattern char */ - nc = get_achar(&np); /* Get a name char */ - if (pc != nc) break; /* Branch mismatched? */ - if (pc == 0) return 1; /* Branch matched? (matched at end of both strings) */ - } - get_achar(&nam); /* nam++ */ - } while (inf && nc); /* Retry until end of name if infinite search is specified */ - - return 0; -} - -#endif /* FF_USE_FIND && FF_FS_MINIMIZE <= 1 */ - - - -/*-----------------------------------------------------------------------*/ -/* Pick a top segment and create the object name in directory form */ -/*-----------------------------------------------------------------------*/ - -static FRESULT create_name ( /* FR_OK: successful, FR_INVALID_NAME: could not create */ - DIR* dp, /* Pointer to the directory object */ - const TCHAR** path /* Pointer to pointer to the segment in the path string */ -) -{ -#if FF_USE_LFN /* LFN configuration */ - BYTE b, cf; - WCHAR wc, *lfn; - DWORD uc; - UINT i, ni, si, di; - const TCHAR *p; - - - /* Create LFN into LFN working buffer */ - p = *path; lfn = dp->obj.fs->lfnbuf; di = 0; - for (;;) { - uc = tchar2uni(&p); /* Get a character */ - if (uc == 0xFFFFFFFF) return FR_INVALID_NAME; /* Invalid code or UTF decode error */ - if (uc >= 0x10000) lfn[di++] = (WCHAR)(uc >> 16); /* Store high surrogate if needed */ - wc = (WCHAR)uc; - if (wc < ' ' || wc == '/' || wc == '\\') break; /* Break if end of the path or a separator is found */ - if (wc < 0x80 && chk_chr("\"*:<>\?|\x7F", wc)) return FR_INVALID_NAME; /* Reject illegal characters for LFN */ - if (di >= FF_MAX_LFN) return FR_INVALID_NAME; /* Reject too long name */ - lfn[di++] = wc; /* Store the Unicode character */ - } - while (*p == '/' || *p == '\\') p++; /* Skip duplicated separators if exist */ - *path = p; /* Return pointer to the next segment */ - cf = (wc < ' ') ? NS_LAST : 0; /* Set last segment flag if end of the path */ - -#if FF_FS_RPATH != 0 - if ((di == 1 && lfn[di - 1] == '.') || - (di == 2 && lfn[di - 1] == '.' && lfn[di - 2] == '.')) { /* Is this segment a dot name? */ - lfn[di] = 0; - for (i = 0; i < 11; i++) { /* Create dot name for SFN entry */ - dp->fn[i] = (i < di) ? '.' : ' '; - } - dp->fn[i] = cf | NS_DOT; /* This is a dot entry */ - return FR_OK; - } -#endif - while (di) { /* Snip off trailing spaces and dots if exist */ - wc = lfn[di - 1]; - if (wc != ' ' && wc != '.') break; - di--; - } - lfn[di] = 0; /* LFN is created into the working buffer */ - if (di == 0) return FR_INVALID_NAME; /* Reject null name */ - - /* Create SFN in directory form */ - for (si = 0; lfn[si] == ' '; si++) ; /* Remove leading spaces */ - if (si > 0 || lfn[si] == '.') cf |= NS_LOSS | NS_LFN; /* Is there any leading space or dot? */ - while (di > 0 && lfn[di - 1] != '.') di--; /* Find last dot (di<=si: no extension) */ - - mem_set(dp->fn, ' ', 11); - i = b = 0; ni = 8; - for (;;) { - wc = lfn[si++]; /* Get an LFN character */ - if (wc == 0) break; /* Break on end of the LFN */ - if (wc == ' ' || (wc == '.' && si != di)) { /* Remove embedded spaces and dots */ - cf |= NS_LOSS | NS_LFN; - continue; - } - - if (i >= ni || si == di) { /* End of field? */ - if (ni == 11) { /* Name extension overflow? */ - cf |= NS_LOSS | NS_LFN; - break; - } - if (si != di) cf |= NS_LOSS | NS_LFN; /* Name body overflow? */ - if (si > di) break; /* No name extension? */ - si = di; i = 8; ni = 11; b <<= 2; /* Enter name extension */ - continue; - } - - if (wc >= 0x80) { /* Is this a non-ASCII character? */ - cf |= NS_LFN; /* LFN entry needs to be created */ -#if FF_CODE_PAGE == 0 - if (ExCvt) { /* At SBCS */ - wc = ff_uni2oem(wc, CODEPAGE); /* Unicode ==> ANSI/OEM code */ - if (wc & 0x80) wc = ExCvt[wc & 0x7F]; /* Convert extended character to upper (SBCS) */ - } else { /* At DBCS */ - wc = ff_uni2oem(ff_wtoupper(wc), CODEPAGE); /* Unicode ==> Upper convert ==> ANSI/OEM code */ - } -#elif FF_CODE_PAGE < 900 /* SBCS cfg */ - wc = ff_uni2oem(wc, CODEPAGE); /* Unicode ==> ANSI/OEM code */ - if (wc & 0x80) wc = ExCvt[wc & 0x7F]; /* Convert extended character to upper (SBCS) */ -#else /* DBCS cfg */ - wc = ff_uni2oem(ff_wtoupper(wc), CODEPAGE); /* Unicode ==> Upper convert ==> ANSI/OEM code */ -#endif - } - - if (wc >= 0x100) { /* Is this a DBC? */ - if (i >= ni - 1) { /* Field overflow? */ - cf |= NS_LOSS | NS_LFN; - i = ni; continue; /* Next field */ - } - dp->fn[i++] = (BYTE)(wc >> 8); /* Put 1st byte */ - } else { /* SBC */ - if (wc == 0 || chk_chr("+,;=[]", wc)) { /* Replace illegal characters for SFN if needed */ - wc = '_'; cf |= NS_LOSS | NS_LFN;/* Lossy conversion */ - } else { - if (IsUpper(wc)) { /* ASCII upper case? */ - b |= 2; - } - if (IsLower(wc)) { /* ASCII lower case? */ - b |= 1; wc -= 0x20; - } - } - } - dp->fn[i++] = (BYTE)wc; - } - - if (dp->fn[0] == DDEM) dp->fn[0] = RDDEM; /* If the first character collides with DDEM, replace it with RDDEM */ - - if (ni == 8) b <<= 2; /* Shift capital flags if no extension */ - if ((b & 0x0C) == 0x0C || (b & 0x03) == 0x03) cf |= NS_LFN; /* LFN entry needs to be created if composite capitals */ - if (!(cf & NS_LFN)) { /* When LFN is in 8.3 format without extended character, NT flags are created */ - if (b & 0x01) cf |= NS_EXT; /* NT flag (Extension has small capital letters only) */ - if (b & 0x04) cf |= NS_BODY; /* NT flag (Body has small capital letters only) */ - } - - dp->fn[NSFLAG] = cf; /* SFN is created into dp->fn[] */ - - return FR_OK; - - -#else /* FF_USE_LFN : Non-LFN configuration */ - BYTE c, d, *sfn; - UINT ni, si, i; - const char *p; - - /* Create file name in directory form */ - p = *path; sfn = dp->fn; - mem_set(sfn, ' ', 11); - si = i = 0; ni = 8; -#if FF_FS_RPATH != 0 - if (p[si] == '.') { /* Is this a dot entry? */ - for (;;) { - c = (BYTE)p[si++]; - if (c != '.' || si >= 3) break; - sfn[i++] = c; - } - if (c != '/' && c != '\\' && c > ' ') return FR_INVALID_NAME; - *path = p + si; /* Return pointer to the next segment */ - sfn[NSFLAG] = (c <= ' ') ? NS_LAST | NS_DOT : NS_DOT; /* Set last segment flag if end of the path */ - return FR_OK; - } -#endif - for (;;) { - c = (BYTE)p[si++]; /* Get a byte */ - if (c <= ' ') break; /* Break if end of the path name */ - if (c == '/' || c == '\\') { /* Break if a separator is found */ - while (p[si] == '/' || p[si] == '\\') si++; /* Skip duplicated separator if exist */ - break; - } - if (c == '.' || i >= ni) { /* End of body or field overflow? */ - if (ni == 11 || c != '.') return FR_INVALID_NAME; /* Field overflow or invalid dot? */ - i = 8; ni = 11; /* Enter file extension field */ - continue; - } -#if FF_CODE_PAGE == 0 - if (ExCvt && c >= 0x80) { /* Is SBC extended character? */ - c = ExCvt[c & 0x7F]; /* To upper SBC extended character */ - } -#elif FF_CODE_PAGE < 900 - if (c >= 0x80) { /* Is SBC extended character? */ - c = ExCvt[c & 0x7F]; /* To upper SBC extended character */ - } -#endif - if (dbc_1st(c)) { /* Check if it is a DBC 1st byte */ - d = (BYTE)p[si++]; /* Get 2nd byte */ - if (!dbc_2nd(d) || i >= ni - 1) return FR_INVALID_NAME; /* Reject invalid DBC */ - sfn[i++] = c; - sfn[i++] = d; - } else { /* SBC */ - if (chk_chr("\"*+,:;<=>\?[]|\x7F", c)) return FR_INVALID_NAME; /* Reject illegal chrs for SFN */ - if (IsLower(c)) c -= 0x20; /* To upper */ - sfn[i++] = c; - } - } - *path = p + si; /* Return pointer to the next segment */ - if (i == 0) return FR_INVALID_NAME; /* Reject nul string */ - - if (sfn[0] == DDEM) sfn[0] = RDDEM; /* If the first character collides with DDEM, replace it with RDDEM */ - sfn[NSFLAG] = (c <= ' ') ? NS_LAST : 0; /* Set last segment flag if end of the path */ - - return FR_OK; -#endif /* FF_USE_LFN */ -} - - - - -/*-----------------------------------------------------------------------*/ -/* Follow a file path */ -/*-----------------------------------------------------------------------*/ - -static FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */ - DIR* dp, /* Directory object to return last directory and found object */ - const TCHAR* path /* Full-path string to find a file or directory */ -) -{ - FRESULT res; - BYTE ns; - FATFS *fs = dp->obj.fs; - - -#if FF_FS_RPATH != 0 - if (*path != '/' && *path != '\\') { /* Without heading separator */ - dp->obj.sclust = fs->cdir; /* Start from current directory */ - } else -#endif - { /* With heading separator */ - while (*path == '/' || *path == '\\') path++; /* Strip heading separator */ - dp->obj.sclust = 0; /* Start from root directory */ - } -#if FF_FS_EXFAT - dp->obj.n_frag = 0; /* Invalidate last fragment counter of the object */ -#if FF_FS_RPATH != 0 - if (fs->fs_type == FS_EXFAT && dp->obj.sclust) { /* exFAT: Retrieve the sub-directory's status */ - DIR dj; - - dp->obj.c_scl = fs->cdc_scl; - dp->obj.c_size = fs->cdc_size; - dp->obj.c_ofs = fs->cdc_ofs; - res = load_obj_xdir(&dj, &dp->obj); - if (res != FR_OK) return res; - dp->obj.objsize = ld_dword(fs->dirbuf + XDIR_FileSize); - dp->obj.stat = fs->dirbuf[XDIR_GenFlags] & 2; - } -#endif -#endif - - if ((UINT)*path < ' ') { /* Null path name is the origin directory itself */ - dp->fn[NSFLAG] = NS_NONAME; - res = dir_sdi(dp, 0); - - } else { /* Follow path */ - for (;;) { - res = create_name(dp, &path); /* Get a segment name of the path */ - if (res != FR_OK) break; - res = dir_find(dp); /* Find an object with the segment name */ - ns = dp->fn[NSFLAG]; - if (res != FR_OK) { /* Failed to find the object */ - if (res == FR_NO_FILE) { /* Object is not found */ - if (FF_FS_RPATH && (ns & NS_DOT)) { /* If dot entry is not exist, stay there */ - if (!(ns & NS_LAST)) continue; /* Continue to follow if not last segment */ - dp->fn[NSFLAG] = NS_NONAME; - res = FR_OK; - } else { /* Could not find the object */ - if (!(ns & NS_LAST)) res = FR_NO_PATH; /* Adjust error code if not last segment */ - } - } - break; - } - if (ns & NS_LAST) break; /* Last segment matched. Function completed. */ - /* Get into the sub-directory */ - if (!(dp->obj.attr & AM_DIR)) { /* It is not a sub-directory and cannot follow */ - res = FR_NO_PATH; break; - } -#if FF_FS_EXFAT - if (fs->fs_type == FS_EXFAT) { /* Save containing directory information for next dir */ - dp->obj.c_scl = dp->obj.sclust; - dp->obj.c_size = ((DWORD)dp->obj.objsize & 0xFFFFFF00) | dp->obj.stat; - dp->obj.c_ofs = dp->blk_ofs; - init_alloc_info(fs, &dp->obj); /* Open next directory */ - } else -#endif - { - dp->obj.sclust = ld_clust(fs, fs->win + dp->dptr % SS(fs)); /* Open next directory */ - } - } - } - - return res; -} - - - - -/*-----------------------------------------------------------------------*/ -/* Get logical drive number from path name */ -/*-----------------------------------------------------------------------*/ - -static int get_ldnumber ( /* Returns logical drive number (-1:invalid drive number or null pointer) */ - const TCHAR** path /* Pointer to pointer to the path name */ -) -{ - const TCHAR *tp, *tt; - TCHAR tc; - int i, vol = -1; -#if FF_STR_VOLUME_ID /* Find string volume ID */ - const char *sp; - char c; -#endif - - tt = tp = *path; - if (!tp) return vol; /* Invalid path name? */ - do tc = *tt++; while ((UINT)tc >= (FF_USE_LFN ? ' ' : '!') && tc != ':'); /* Find a colon in the path */ - - if (tc == ':') { /* DOS/Windows style volume ID? */ - i = FF_VOLUMES; - if (IsDigit(*tp) && tp + 2 == tt) { /* Is there a numeric volume ID + colon? */ - i = (int)*tp - '0'; /* Get the LD number */ - } -#if FF_STR_VOLUME_ID == 1 /* Arbitrary string is enabled */ - else { - i = 0; - do { - sp = VolumeStr[i]; tp = *path; /* This string volume ID and path name */ - do { /* Compare the volume ID with path name */ - c = *sp++; tc = *tp++; - if (IsLower(c)) c -= 0x20; - if (IsLower(tc)) tc -= 0x20; - } while (c && (TCHAR)c == tc); - } while ((c || tp != tt) && ++i < FF_VOLUMES); /* Repeat for each id until pattern match */ - } -#endif - if (i < FF_VOLUMES) { /* If a volume ID is found, get the drive number and strip it */ - vol = i; /* Drive number */ - *path = tt; /* Snip the drive prefix off */ - } - return vol; - } -#if FF_STR_VOLUME_ID == 2 /* Unix style volume ID is enabled */ - if (*tp == '/') { - i = 0; - do { - sp = VolumeStr[i]; tp = *path; /* This string volume ID and path name */ - do { /* Compare the volume ID with path name */ - c = *sp++; tc = *(++tp); - if (IsLower(c)) c -= 0x20; - if (IsLower(tc)) tc -= 0x20; - } while (c && (TCHAR)c == tc); - } while ((c || (tc != '/' && (UINT)tc >= (FF_USE_LFN ? ' ' : '!'))) && ++i < FF_VOLUMES); /* Repeat for each ID until pattern match */ - if (i < FF_VOLUMES) { /* If a volume ID is found, get the drive number and strip it */ - vol = i; /* Drive number */ - *path = tp; /* Snip the drive prefix off */ - return vol; - } - } -#endif - /* No drive prefix is found */ -#if FF_FS_RPATH != 0 - vol = CurrVol; /* Default drive is current drive */ -#else - vol = 0; /* Default drive is 0 */ -#endif - return vol; /* Return the default drive */ -} - - - - -/*-----------------------------------------------------------------------*/ -/* Load a sector and check if it is an FAT VBR */ -/*-----------------------------------------------------------------------*/ - -static BYTE check_fs ( /* 0:FAT, 1:exFAT, 2:Valid BS but not FAT, 3:Not a BS, 4:Disk error */ - FATFS* fs, /* Filesystem object */ - DWORD sect /* Sector# (lba) to load and check if it is an FAT-VBR or not */ -) -{ - fs->wflag = 0; fs->winsect = 0xFFFFFFFF; /* Invaidate window */ - if (move_window(fs, sect) != FR_OK) return 4; /* Load boot record */ - - if (ld_word(fs->win + BS_55AA) != 0xAA55) return 3; /* Check boot record signature (always here regardless of the sector size) */ - -#if FF_FS_EXFAT - if (!mem_cmp(fs->win + BS_JmpBoot, "\xEB\x76\x90" "EXFAT ", 11)) return 1; /* Check if exFAT VBR */ -#endif - if (fs->win[BS_JmpBoot] == 0xE9 || fs->win[BS_JmpBoot] == 0xEB || fs->win[BS_JmpBoot] == 0xE8) { /* Valid JumpBoot code? */ - if (!mem_cmp(fs->win + BS_FilSysType, "FAT", 3)) return 0; /* Is it an FAT VBR? */ - if (!mem_cmp(fs->win + BS_FilSysType32, "FAT32", 5)) return 0; /* Is it an FAT32 VBR? */ - } - return 2; /* Valid BS but not FAT */ -} - - - - -/*-----------------------------------------------------------------------*/ -/* Determine logical drive number and mount the volume if needed */ -/*-----------------------------------------------------------------------*/ - -static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */ - const TCHAR** path, /* Pointer to pointer to the path name (drive number) */ - FATFS** rfs, /* Pointer to pointer to the found filesystem object */ - BYTE mode /* !=0: Check write protection for write access */ -) -{ - BYTE fmt, *pt; - int vol; - DSTATUS stat; - DWORD bsect, fasize, tsect, sysect, nclst, szbfat, br[4]; - WORD nrsv; - FATFS *fs; - UINT i; - - - /* Get logical drive number */ - *rfs = 0; - vol = get_ldnumber(path); - if (vol < 0) return FR_INVALID_DRIVE; - - /* Check if the filesystem object is valid or not */ - fs = FatFs[vol]; /* Get pointer to the filesystem object */ - if (!fs) return FR_NOT_ENABLED; /* Is the filesystem object available? */ -#if FF_FS_REENTRANT - if (!lock_fs(fs)) return FR_TIMEOUT; /* Lock the volume */ -#endif - *rfs = fs; /* Return pointer to the filesystem object */ - - mode &= (BYTE)~FA_READ; /* Desired access mode, write access or not */ - if (fs->fs_type != 0) { /* If the volume has been mounted */ - stat = disk_status(fs->pdrv); - if (!(stat & STA_NOINIT)) { /* and the physical drive is kept initialized */ - if (!FF_FS_READONLY && mode && (stat & STA_PROTECT)) { /* Check write protection if needed */ - return FR_WRITE_PROTECTED; - } - return FR_OK; /* The filesystem object is valid */ - } - } - - /* The filesystem object is not valid. */ - /* Following code attempts to mount the volume. (analyze BPB and initialize the filesystem object) */ - - fs->fs_type = 0; /* Clear the filesystem object */ - fs->pdrv = LD2PD(vol); /* Bind the logical drive and a physical drive */ - stat = disk_initialize(fs->pdrv); /* Initialize the physical drive */ - if (stat & STA_NOINIT) { /* Check if the initialization succeeded */ - return FR_NOT_READY; /* Failed to initialize due to no medium or hard error */ - } - if (!FF_FS_READONLY && mode && (stat & STA_PROTECT)) { /* Check disk write protection if needed */ - return FR_WRITE_PROTECTED; - } -#if FF_MAX_SS != FF_MIN_SS /* Get sector size (multiple sector size cfg only) */ - if (disk_ioctl(fs->pdrv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK) return FR_DISK_ERR; - if (SS(fs) > FF_MAX_SS || SS(fs) < FF_MIN_SS || (SS(fs) & (SS(fs) - 1))) return FR_DISK_ERR; -#endif - - /* Find an FAT partition on the drive. Supports only generic partitioning rules, FDISK and SFD. */ - bsect = 0; - fmt = check_fs(fs, bsect); /* Load sector 0 and check if it is an FAT-VBR as SFD */ - if (fmt == 2 || (fmt < 2 && LD2PT(vol) != 0)) { /* Not an FAT-VBR or forced partition number */ - for (i = 0; i < 4; i++) { /* Get partition offset */ - pt = fs->win + (MBR_Table + i * SZ_PTE); - br[i] = pt[PTE_System] ? ld_dword(pt + PTE_StLba) : 0; - } - i = LD2PT(vol); /* Partition number: 0:auto, 1-4:forced */ - if (i != 0) i--; - do { /* Find an FAT volume */ - bsect = br[i]; - fmt = bsect ? check_fs(fs, bsect) : 3; /* Check the partition */ - } while (LD2PT(vol) == 0 && fmt >= 2 && ++i < 4); - } - if (fmt == 4) return FR_DISK_ERR; /* An error occured in the disk I/O layer */ - if (fmt >= 2) return FR_NO_FILESYSTEM; /* No FAT volume is found */ - - /* An FAT volume is found (bsect). Following code initializes the filesystem object */ - -#if FF_FS_EXFAT - if (fmt == 1) { - QWORD maxlba; - - for (i = BPB_ZeroedEx; i < BPB_ZeroedEx + 53 && fs->win[i] == 0; i++) ; /* Check zero filler */ - if (i < BPB_ZeroedEx + 53) return FR_NO_FILESYSTEM; - - if (ld_word(fs->win + BPB_FSVerEx) != 0x100) return FR_NO_FILESYSTEM; /* Check exFAT version (must be version 1.0) */ - - if (1 << fs->win[BPB_BytsPerSecEx] != SS(fs)) { /* (BPB_BytsPerSecEx must be equal to the physical sector size) */ - return FR_NO_FILESYSTEM; - } - - maxlba = ld_qword(fs->win + BPB_TotSecEx) + bsect; /* Last LBA + 1 of the volume */ - if (maxlba >= 0x100000000) return FR_NO_FILESYSTEM; /* (It cannot be handled in 32-bit LBA) */ - - fs->fsize = ld_dword(fs->win + BPB_FatSzEx); /* Number of sectors per FAT */ - - fs->n_fats = fs->win[BPB_NumFATsEx]; /* Number of FATs */ - if (fs->n_fats != 1) return FR_NO_FILESYSTEM; /* (Supports only 1 FAT) */ - - fs->csize = 1 << fs->win[BPB_SecPerClusEx]; /* Cluster size */ - if (fs->csize == 0) return FR_NO_FILESYSTEM; /* (Must be 1..32768) */ - - nclst = ld_dword(fs->win + BPB_NumClusEx); /* Number of clusters */ - if (nclst > MAX_EXFAT) return FR_NO_FILESYSTEM; /* (Too many clusters) */ - fs->n_fatent = nclst + 2; - - /* Boundaries and Limits */ - fs->volbase = bsect; - fs->database = bsect + ld_dword(fs->win + BPB_DataOfsEx); - fs->fatbase = bsect + ld_dword(fs->win + BPB_FatOfsEx); - if (maxlba < (QWORD)fs->database + nclst * fs->csize) return FR_NO_FILESYSTEM; /* (Volume size must not be smaller than the size requiered) */ - fs->dirbase = ld_dword(fs->win + BPB_RootClusEx); - - /* Check if bitmap location is in assumption (at the first cluster) */ - if (move_window(fs, clst2sect(fs, fs->dirbase)) != FR_OK) return FR_DISK_ERR; - for (i = 0; i < SS(fs); i += SZDIRE) { - if (fs->win[i] == 0x81 && ld_dword(fs->win + i + 20) == 2) break; /* 81 entry with cluster #2? */ - } - if (i == SS(fs)) return FR_NO_FILESYSTEM; -#if !FF_FS_READONLY - fs->last_clst = fs->free_clst = 0xFFFFFFFF; /* Initialize cluster allocation information */ -#endif - fmt = FS_EXFAT; /* FAT sub-type */ - } else -#endif /* FF_FS_EXFAT */ - { - if (ld_word(fs->win + BPB_BytsPerSec) != SS(fs)) return FR_NO_FILESYSTEM; /* (BPB_BytsPerSec must be equal to the physical sector size) */ - - fasize = ld_word(fs->win + BPB_FATSz16); /* Number of sectors per FAT */ - if (fasize == 0) fasize = ld_dword(fs->win + BPB_FATSz32); - fs->fsize = fasize; - - fs->n_fats = fs->win[BPB_NumFATs]; /* Number of FATs */ - if (fs->n_fats != 1 && fs->n_fats != 2) return FR_NO_FILESYSTEM; /* (Must be 1 or 2) */ - fasize *= fs->n_fats; /* Number of sectors for FAT area */ - - fs->csize = fs->win[BPB_SecPerClus]; /* Cluster size */ - if (fs->csize == 0 || (fs->csize & (fs->csize - 1))) return FR_NO_FILESYSTEM; /* (Must be power of 2) */ - - fs->n_rootdir = ld_word(fs->win + BPB_RootEntCnt); /* Number of root directory entries */ - if (fs->n_rootdir % (SS(fs) / SZDIRE)) return FR_NO_FILESYSTEM; /* (Must be sector aligned) */ - - tsect = ld_word(fs->win + BPB_TotSec16); /* Number of sectors on the volume */ - if (tsect == 0) tsect = ld_dword(fs->win + BPB_TotSec32); - - nrsv = ld_word(fs->win + BPB_RsvdSecCnt); /* Number of reserved sectors */ - if (nrsv == 0) return FR_NO_FILESYSTEM; /* (Must not be 0) */ - - /* Determine the FAT sub type */ - sysect = nrsv + fasize + fs->n_rootdir / (SS(fs) / SZDIRE); /* RSV + FAT + DIR */ - if (tsect < sysect) return FR_NO_FILESYSTEM; /* (Invalid volume size) */ - nclst = (tsect - sysect) / fs->csize; /* Number of clusters */ - if (nclst == 0) return FR_NO_FILESYSTEM; /* (Invalid volume size) */ - fmt = 0; - if (nclst <= MAX_FAT32) fmt = FS_FAT32; - if (nclst <= MAX_FAT16) fmt = FS_FAT16; - if (nclst <= MAX_FAT12) fmt = FS_FAT12; - if (fmt == 0) return FR_NO_FILESYSTEM; - - /* Boundaries and Limits */ - fs->n_fatent = nclst + 2; /* Number of FAT entries */ - fs->volbase = bsect; /* Volume start sector */ - fs->fatbase = bsect + nrsv; /* FAT start sector */ - fs->database = bsect + sysect; /* Data start sector */ - if (fmt == FS_FAT32) { - if (ld_word(fs->win + BPB_FSVer32) != 0) return FR_NO_FILESYSTEM; /* (Must be FAT32 revision 0.0) */ - if (fs->n_rootdir != 0) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be 0) */ - fs->dirbase = ld_dword(fs->win + BPB_RootClus32); /* Root directory start cluster */ - szbfat = fs->n_fatent * 4; /* (Needed FAT size) */ - } else { - if (fs->n_rootdir == 0) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must not be 0) */ - fs->dirbase = fs->fatbase + fasize; /* Root directory start sector */ - szbfat = (fmt == FS_FAT16) ? /* (Needed FAT size) */ - fs->n_fatent * 2 : fs->n_fatent * 3 / 2 + (fs->n_fatent & 1); - } - if (fs->fsize < (szbfat + (SS(fs) - 1)) / SS(fs)) return FR_NO_FILESYSTEM; /* (BPB_FATSz must not be less than the size needed) */ - -#if !FF_FS_READONLY - /* Get FSInfo if available */ - fs->last_clst = fs->free_clst = 0xFFFFFFFF; /* Initialize cluster allocation information */ - fs->fsi_flag = 0x80; -#if (FF_FS_NOFSINFO & 3) != 3 - if (fmt == FS_FAT32 /* Allow to update FSInfo only if BPB_FSInfo32 == 1 */ - && ld_word(fs->win + BPB_FSInfo32) == 1 - && move_window(fs, bsect + 1) == FR_OK) - { - fs->fsi_flag = 0; - if (ld_word(fs->win + BS_55AA) == 0xAA55 /* Load FSInfo data if available */ - && ld_dword(fs->win + FSI_LeadSig) == 0x41615252 - && ld_dword(fs->win + FSI_StrucSig) == 0x61417272) - { -#if (FF_FS_NOFSINFO & 1) == 0 - fs->free_clst = ld_dword(fs->win + FSI_Free_Count); -#endif -#if (FF_FS_NOFSINFO & 2) == 0 - fs->last_clst = ld_dword(fs->win + FSI_Nxt_Free); -#endif - } - } -#endif /* (FF_FS_NOFSINFO & 3) != 3 */ -#endif /* !FF_FS_READONLY */ - } - - fs->fs_type = fmt; /* FAT sub-type */ - fs->id = ++Fsid; /* Volume mount ID */ -#if FF_USE_LFN == 1 - fs->lfnbuf = LfnBuf; /* Static LFN working buffer */ -#if FF_FS_EXFAT - fs->dirbuf = DirBuf; /* Static directory block scratchpad buuffer */ -#endif -#endif -#if FF_FS_RPATH != 0 - fs->cdir = 0; /* Initialize current directory */ -#endif -#if FF_FS_LOCK != 0 /* Clear file lock semaphores */ - clear_lock(fs); -#endif - return FR_OK; -} - - - - -/*-----------------------------------------------------------------------*/ -/* Check if the file/directory object is valid or not */ -/*-----------------------------------------------------------------------*/ - -static FRESULT validate ( /* Returns FR_OK or FR_INVALID_OBJECT */ - FFOBJID* obj, /* Pointer to the FFOBJID, the 1st member in the FIL/DIR object, to check validity */ - FATFS** rfs /* Pointer to pointer to the owner filesystem object to return */ -) -{ - FRESULT res = FR_INVALID_OBJECT; - - - if (obj && obj->fs && obj->fs->fs_type && obj->id == obj->fs->id) { /* Test if the object is valid */ -#if FF_FS_REENTRANT - if (lock_fs(obj->fs)) { /* Obtain the filesystem object */ - if (!(disk_status(obj->fs->pdrv) & STA_NOINIT)) { /* Test if the phsical drive is kept initialized */ - res = FR_OK; - } else { - unlock_fs(obj->fs, FR_OK); - } - } else { - res = FR_TIMEOUT; - } -#else - if (!(disk_status(obj->fs->pdrv) & STA_NOINIT)) { /* Test if the phsical drive is kept initialized */ - res = FR_OK; - } -#endif - } - *rfs = (res == FR_OK) ? obj->fs : 0; /* Corresponding filesystem object */ - return res; -} - - - - -/*--------------------------------------------------------------------------- - - Public Functions (FatFs API) - -----------------------------------------------------------------------------*/ - - - -/*-----------------------------------------------------------------------*/ -/* Mount/Unmount a Logical Drive */ -/*-----------------------------------------------------------------------*/ - -FRESULT f_mount ( - FATFS* fs, /* Pointer to the filesystem object (NULL:unmount)*/ - const TCHAR* path, /* Logical drive number to be mounted/unmounted */ - BYTE opt /* Mode option 0:Do not mount (delayed mount), 1:Mount immediately */ -) -{ - FATFS *cfs; - int vol; - FRESULT res; - const TCHAR *rp = path; - - - /* Get logical drive number */ - vol = get_ldnumber(&rp); - if (vol < 0) return FR_INVALID_DRIVE; - cfs = FatFs[vol]; /* Pointer to fs object */ - - if (cfs) { -#if FF_FS_LOCK != 0 - clear_lock(cfs); -#endif -#if FF_FS_REENTRANT /* Discard sync object of the current volume */ - if (!ff_del_syncobj(cfs->sobj)) return FR_INT_ERR; -#endif - cfs->fs_type = 0; /* Clear old fs object */ - } - - if (fs) { - fs->fs_type = 0; /* Clear new fs object */ -#if FF_FS_REENTRANT /* Create sync object for the new volume */ - if (!ff_cre_syncobj((BYTE)vol, &fs->sobj)) return FR_INT_ERR; -#endif - } - FatFs[vol] = fs; /* Register new fs object */ - - if (opt == 0) return FR_OK; /* Do not mount now, it will be mounted later */ - - res = find_volume(&path, &fs, 0); /* Force mounted the volume */ - LEAVE_FF(fs, res); -} - - - - -/*-----------------------------------------------------------------------*/ -/* Open or Create a File */ -/*-----------------------------------------------------------------------*/ - -FRESULT f_open ( - FIL* fp, /* Pointer to the blank file object */ - const TCHAR* path, /* Pointer to the file name */ - BYTE mode /* Access mode and file open mode flags */ -) -{ - FRESULT res; - DIR dj; - FATFS *fs; -#if !FF_FS_READONLY - DWORD dw, cl, bcs, clst, sc; - FSIZE_t ofs; -#endif - DEF_NAMBUF - - - if (!fp) return FR_INVALID_OBJECT; - - /* Get logical drive number */ - mode &= FF_FS_READONLY ? FA_READ : FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_CREATE_NEW | FA_OPEN_ALWAYS | FA_OPEN_APPEND; - res = find_volume(&path, &fs, mode); - if (res == FR_OK) { - dj.obj.fs = fs; - INIT_NAMBUF(fs); - res = follow_path(&dj, path); /* Follow the file path */ -#if !FF_FS_READONLY /* Read/Write configuration */ - if (res == FR_OK) { - if (dj.fn[NSFLAG] & NS_NONAME) { /* Origin directory itself? */ - res = FR_INVALID_NAME; - } -#if FF_FS_LOCK != 0 - else { - res = chk_lock(&dj, (mode & ~FA_READ) ? 1 : 0); /* Check if the file can be used */ - } -#endif - } - /* Create or Open a file */ - if (mode & (FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)) { - if (res != FR_OK) { /* No file, create new */ - if (res == FR_NO_FILE) { /* There is no file to open, create a new entry */ -#if FF_FS_LOCK != 0 - res = enq_lock() ? dir_register(&dj) : FR_TOO_MANY_OPEN_FILES; -#else - res = dir_register(&dj); -#endif - } - mode |= FA_CREATE_ALWAYS; /* File is created */ - } - else { /* Any object with the same name is already existing */ - if (dj.obj.attr & (AM_RDO | AM_DIR)) { /* Cannot overwrite it (R/O or DIR) */ - res = FR_DENIED; - } else { - if (mode & FA_CREATE_NEW) res = FR_EXIST; /* Cannot create as new file */ - } - } - if (res == FR_OK && (mode & FA_CREATE_ALWAYS)) { /* Truncate the file if overwrite mode */ -#if FF_FS_EXFAT - if (fs->fs_type == FS_EXFAT) { - /* Get current allocation info */ - fp->obj.fs = fs; - init_alloc_info(fs, &fp->obj); - /* Set directory entry block initial state */ - mem_set(fs->dirbuf + 2, 0, 30); /* Clear 85 entry except for NumSec */ - mem_set(fs->dirbuf + 38, 0, 26); /* Clear C0 entry except for NumName and NameHash */ - fs->dirbuf[XDIR_Attr] = AM_ARC; - st_dword(fs->dirbuf + XDIR_CrtTime, GET_FATTIME()); - fs->dirbuf[XDIR_GenFlags] = 1; - res = store_xdir(&dj); - if (res == FR_OK && fp->obj.sclust != 0) { /* Remove the cluster chain if exist */ - res = remove_chain(&fp->obj, fp->obj.sclust, 0); - fs->last_clst = fp->obj.sclust - 1; /* Reuse the cluster hole */ - } - } else -#endif - { - /* Set directory entry initial state */ - cl = ld_clust(fs, dj.dir); /* Get current cluster chain */ - st_dword(dj.dir + DIR_CrtTime, GET_FATTIME()); /* Set created time */ - dj.dir[DIR_Attr] = AM_ARC; /* Reset attribute */ - st_clust(fs, dj.dir, 0); /* Reset file allocation info */ - st_dword(dj.dir + DIR_FileSize, 0); - fs->wflag = 1; - if (cl != 0) { /* Remove the cluster chain if exist */ - dw = fs->winsect; - res = remove_chain(&dj.obj, cl, 0); - if (res == FR_OK) { - res = move_window(fs, dw); - fs->last_clst = cl - 1; /* Reuse the cluster hole */ - } - } - } - } - } - else { /* Open an existing file */ - if (res == FR_OK) { /* Is the object exsiting? */ - if (dj.obj.attr & AM_DIR) { /* File open against a directory */ - res = FR_NO_FILE; - } else { - if ((mode & FA_WRITE) && (dj.obj.attr & AM_RDO)) { /* Write mode open against R/O file */ - res = FR_DENIED; - } - } - } - } - if (res == FR_OK) { - if (mode & FA_CREATE_ALWAYS) mode |= FA_MODIFIED; /* Set file change flag if created or overwritten */ - fp->dir_sect = fs->winsect; /* Pointer to the directory entry */ - fp->dir_ptr = dj.dir; -#if FF_FS_LOCK != 0 - fp->obj.lockid = inc_lock(&dj, (mode & ~FA_READ) ? 1 : 0); /* Lock the file for this session */ - if (fp->obj.lockid == 0) res = FR_INT_ERR; -#endif - } -#else /* R/O configuration */ - if (res == FR_OK) { - if (dj.fn[NSFLAG] & NS_NONAME) { /* Is it origin directory itself? */ - res = FR_INVALID_NAME; - } else { - if (dj.obj.attr & AM_DIR) { /* Is it a directory? */ - res = FR_NO_FILE; - } - } - } -#endif - - if (res == FR_OK) { -#if FF_FS_EXFAT - if (fs->fs_type == FS_EXFAT) { - fp->obj.c_scl = dj.obj.sclust; /* Get containing directory info */ - fp->obj.c_size = ((DWORD)dj.obj.objsize & 0xFFFFFF00) | dj.obj.stat; - fp->obj.c_ofs = dj.blk_ofs; - init_alloc_info(fs, &fp->obj); - } else -#endif - { - fp->obj.sclust = ld_clust(fs, dj.dir); /* Get object allocation info */ - fp->obj.objsize = ld_dword(dj.dir + DIR_FileSize); - } -#if FF_USE_FASTSEEK - fp->cltbl = 0; /* Disable fast seek mode */ -#endif - fp->obj.fs = fs; /* Validate the file object */ - fp->obj.id = fs->id; - fp->flag = mode; /* Set file access mode */ - fp->err = 0; /* Clear error flag */ - fp->sect = 0; /* Invalidate current data sector */ - fp->fptr = 0; /* Set file pointer top of the file */ -#if !FF_FS_READONLY -#if !FF_FS_TINY - mem_set(fp->buf, 0, FF_MAX_SS); /* Clear sector buffer */ -#endif - if ((mode & FA_SEEKEND) && fp->obj.objsize > 0) { /* Seek to end of file if FA_OPEN_APPEND is specified */ - fp->fptr = fp->obj.objsize; /* Offset to seek */ - bcs = (DWORD)fs->csize * SS(fs); /* Cluster size in byte */ - clst = fp->obj.sclust; /* Follow the cluster chain */ - for (ofs = fp->obj.objsize; res == FR_OK && ofs > bcs; ofs -= bcs) { - clst = get_fat(&fp->obj, clst); - if (clst <= 1) res = FR_INT_ERR; - if (clst == 0xFFFFFFFF) res = FR_DISK_ERR; - } - fp->clust = clst; - if (res == FR_OK && ofs % SS(fs)) { /* Fill sector buffer if not on the sector boundary */ - if ((sc = clst2sect(fs, clst)) == 0) { - res = FR_INT_ERR; - } else { - fp->sect = sc + (DWORD)(ofs / SS(fs)); -#if !FF_FS_TINY - if (disk_read(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) res = FR_DISK_ERR; -#endif - } - } - } -#endif - } - - FREE_NAMBUF(); - } - - if (res != FR_OK) fp->obj.fs = 0; /* Invalidate file object on error */ - - LEAVE_FF(fs, res); -} - - - - -/*-----------------------------------------------------------------------*/ -/* Read File */ -/*-----------------------------------------------------------------------*/ - -FRESULT f_read ( - FIL* fp, /* Pointer to the file object */ - void* buff, /* Pointer to data buffer */ - UINT btr, /* Number of bytes to read */ - UINT* br /* Pointer to number of bytes read */ -) -{ - FRESULT res; - FATFS *fs; - DWORD clst, sect; - FSIZE_t remain; - UINT rcnt, cc, csect; - BYTE *rbuff = (BYTE*)buff; - - - *br = 0; /* Clear read byte counter */ - res = validate(&fp->obj, &fs); /* Check validity of the file object */ - if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); /* Check validity */ - if (!(fp->flag & FA_READ)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */ - remain = fp->obj.objsize - fp->fptr; - if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */ - - for ( ; btr; /* Repeat until btr bytes read */ - btr -= rcnt, *br += rcnt, rbuff += rcnt, fp->fptr += rcnt) { - if (fp->fptr % SS(fs) == 0) { /* On the sector boundary? */ - csect = (UINT)(fp->fptr / SS(fs) & (fs->csize - 1)); /* Sector offset in the cluster */ - if (csect == 0) { /* On the cluster boundary? */ - if (fp->fptr == 0) { /* On the top of the file? */ - clst = fp->obj.sclust; /* Follow cluster chain from the origin */ - } else { /* Middle or end of the file */ -#if FF_USE_FASTSEEK - if (fp->cltbl) { - clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */ - } else -#endif - { - clst = get_fat(&fp->obj, fp->clust); /* Follow cluster chain on the FAT */ - } - } - if (clst < 2) ABORT(fs, FR_INT_ERR); - if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR); - fp->clust = clst; /* Update current cluster */ - } - sect = clst2sect(fs, fp->clust); /* Get current sector */ - if (sect == 0) ABORT(fs, FR_INT_ERR); - sect += csect; - cc = btr / SS(fs); /* When remaining bytes >= sector size, */ - if (cc > 0) { /* Read maximum contiguous sectors directly */ - if (csect + cc > fs->csize) { /* Clip at cluster boundary */ - cc = fs->csize - csect; - } - if (disk_read(fs->pdrv, rbuff, sect, cc) != RES_OK) ABORT(fs, FR_DISK_ERR); -#if !FF_FS_READONLY && FF_FS_MINIMIZE <= 2 /* Replace one of the read sectors with cached data if it contains a dirty sector */ -#if FF_FS_TINY - if (fs->wflag && fs->winsect - sect < cc) { - mem_cpy(rbuff + ((fs->winsect - sect) * SS(fs)), fs->win, SS(fs)); - } -#else - if ((fp->flag & FA_DIRTY) && fp->sect - sect < cc) { - mem_cpy(rbuff + ((fp->sect - sect) * SS(fs)), fp->buf, SS(fs)); - } -#endif -#endif - rcnt = SS(fs) * cc; /* Number of bytes transferred */ - continue; - } -#if !FF_FS_TINY - if (fp->sect != sect) { /* Load data sector if not in cache */ -#if !FF_FS_READONLY - if (fp->flag & FA_DIRTY) { /* Write-back dirty sector cache */ - if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); - fp->flag &= (BYTE)~FA_DIRTY; - } -#endif - if (disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Fill sector cache */ - } -#endif - fp->sect = sect; - } - rcnt = SS(fs) - (UINT)fp->fptr % SS(fs); /* Number of bytes left in the sector */ - if (rcnt > btr) rcnt = btr; /* Clip it by btr if needed */ -#if FF_FS_TINY - if (move_window(fs, fp->sect) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Move sector window */ - mem_cpy(rbuff, fs->win + fp->fptr % SS(fs), rcnt); /* Extract partial sector */ -#else - mem_cpy(rbuff, fp->buf + fp->fptr % SS(fs), rcnt); /* Extract partial sector */ -#endif - } - - LEAVE_FF(fs, FR_OK); -} - - - - -#if !FF_FS_READONLY -/*-----------------------------------------------------------------------*/ -/* Write File */ -/*-----------------------------------------------------------------------*/ - -FRESULT f_write ( - FIL* fp, /* Pointer to the file object */ - const void* buff, /* Pointer to the data to be written */ - UINT btw, /* Number of bytes to write */ - UINT* bw /* Pointer to number of bytes written */ -) -{ - FRESULT res; - FATFS *fs; - DWORD clst, sect; - UINT wcnt, cc, csect; - const BYTE *wbuff = (const BYTE*)buff; - - - *bw = 0; /* Clear write byte counter */ - res = validate(&fp->obj, &fs); /* Check validity of the file object */ - if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); /* Check validity */ - if (!(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */ - - /* Check fptr wrap-around (file size cannot reach 4 GiB at FAT volume) */ - if ((!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) && (DWORD)(fp->fptr + btw) < (DWORD)fp->fptr) { - btw = (UINT)(0xFFFFFFFF - (DWORD)fp->fptr); - } - - for ( ; btw; /* Repeat until all data written */ - btw -= wcnt, *bw += wcnt, wbuff += wcnt, fp->fptr += wcnt, fp->obj.objsize = (fp->fptr > fp->obj.objsize) ? fp->fptr : fp->obj.objsize) { - if (fp->fptr % SS(fs) == 0) { /* On the sector boundary? */ - csect = (UINT)(fp->fptr / SS(fs)) & (fs->csize - 1); /* Sector offset in the cluster */ - if (csect == 0) { /* On the cluster boundary? */ - if (fp->fptr == 0) { /* On the top of the file? */ - clst = fp->obj.sclust; /* Follow from the origin */ - if (clst == 0) { /* If no cluster is allocated, */ - clst = create_chain(&fp->obj, 0); /* create a new cluster chain */ - } - } else { /* On the middle or end of the file */ -#if FF_USE_FASTSEEK - if (fp->cltbl) { - clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */ - } else -#endif - { - clst = create_chain(&fp->obj, fp->clust); /* Follow or stretch cluster chain on the FAT */ - } - } - if (clst == 0) break; /* Could not allocate a new cluster (disk full) */ - if (clst == 1) ABORT(fs, FR_INT_ERR); - if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR); - fp->clust = clst; /* Update current cluster */ - if (fp->obj.sclust == 0) fp->obj.sclust = clst; /* Set start cluster if the first write */ - } -#if FF_FS_TINY - if (fs->winsect == fp->sect && sync_window(fs) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Write-back sector cache */ -#else - if (fp->flag & FA_DIRTY) { /* Write-back sector cache */ - if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); - fp->flag &= (BYTE)~FA_DIRTY; - } -#endif - sect = clst2sect(fs, fp->clust); /* Get current sector */ - if (sect == 0) ABORT(fs, FR_INT_ERR); - sect += csect; - cc = btw / SS(fs); /* When remaining bytes >= sector size, */ - if (cc > 0) { /* Write maximum contiguous sectors directly */ - if (csect + cc > fs->csize) { /* Clip at cluster boundary */ - cc = fs->csize - csect; - } - if (disk_write(fs->pdrv, wbuff, sect, cc) != RES_OK) ABORT(fs, FR_DISK_ERR); -#if FF_FS_MINIMIZE <= 2 -#if FF_FS_TINY - if (fs->winsect - sect < cc) { /* Refill sector cache if it gets invalidated by the direct write */ - mem_cpy(fs->win, wbuff + ((fs->winsect - sect) * SS(fs)), SS(fs)); - fs->wflag = 0; - } -#else - if (fp->sect - sect < cc) { /* Refill sector cache if it gets invalidated by the direct write */ - mem_cpy(fp->buf, wbuff + ((fp->sect - sect) * SS(fs)), SS(fs)); - fp->flag &= (BYTE)~FA_DIRTY; - } -#endif -#endif - wcnt = SS(fs) * cc; /* Number of bytes transferred */ - continue; - } -#if FF_FS_TINY - if (fp->fptr >= fp->obj.objsize) { /* Avoid silly cache filling on the growing edge */ - if (sync_window(fs) != FR_OK) ABORT(fs, FR_DISK_ERR); - fs->winsect = sect; - } -#else - if (fp->sect != sect && /* Fill sector cache with file data */ - fp->fptr < fp->obj.objsize && - disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) { - ABORT(fs, FR_DISK_ERR); - } -#endif - fp->sect = sect; - } - wcnt = SS(fs) - (UINT)fp->fptr % SS(fs); /* Number of bytes left in the sector */ - if (wcnt > btw) wcnt = btw; /* Clip it by btw if needed */ -#if FF_FS_TINY - if (move_window(fs, fp->sect) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Move sector window */ - mem_cpy(fs->win + fp->fptr % SS(fs), wbuff, wcnt); /* Fit data to the sector */ - fs->wflag = 1; -#else - mem_cpy(fp->buf + fp->fptr % SS(fs), wbuff, wcnt); /* Fit data to the sector */ - fp->flag |= FA_DIRTY; -#endif - } - - fp->flag |= FA_MODIFIED; /* Set file change flag */ - - LEAVE_FF(fs, FR_OK); -} - - - - -/*-----------------------------------------------------------------------*/ -/* Synchronize the File */ -/*-----------------------------------------------------------------------*/ - -FRESULT f_sync ( - FIL* fp /* Pointer to the file object */ -) -{ - FRESULT res; - FATFS *fs; - DWORD tm; - BYTE *dir; - - - res = validate(&fp->obj, &fs); /* Check validity of the file object */ - if (res == FR_OK) { - if (fp->flag & FA_MODIFIED) { /* Is there any change to the file? */ -#if !FF_FS_TINY - if (fp->flag & FA_DIRTY) { /* Write-back cached data if needed */ - if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) LEAVE_FF(fs, FR_DISK_ERR); - fp->flag &= (BYTE)~FA_DIRTY; - } -#endif - /* Update the directory entry */ - tm = GET_FATTIME(); /* Modified time */ -#if FF_FS_EXFAT - if (fs->fs_type == FS_EXFAT) { - res = fill_first_frag(&fp->obj); /* Fill first fragment on the FAT if needed */ - if (res == FR_OK) { - res = fill_last_frag(&fp->obj, fp->clust, 0xFFFFFFFF); /* Fill last fragment on the FAT if needed */ - } - if (res == FR_OK) { - DIR dj; - DEF_NAMBUF - - INIT_NAMBUF(fs); - res = load_obj_xdir(&dj, &fp->obj); /* Load directory entry block */ - if (res == FR_OK) { - fs->dirbuf[XDIR_Attr] |= AM_ARC; /* Set archive attribute to indicate that the file has been changed */ - fs->dirbuf[XDIR_GenFlags] = fp->obj.stat | 1; /* Update file allocation information */ - st_dword(fs->dirbuf + XDIR_FstClus, fp->obj.sclust); - st_qword(fs->dirbuf + XDIR_FileSize, fp->obj.objsize); - st_qword(fs->dirbuf + XDIR_ValidFileSize, fp->obj.objsize); - st_dword(fs->dirbuf + XDIR_ModTime, tm); /* Update modified time */ - fs->dirbuf[XDIR_ModTime10] = 0; - st_dword(fs->dirbuf + XDIR_AccTime, 0); - res = store_xdir(&dj); /* Restore it to the directory */ - if (res == FR_OK) { - res = sync_fs(fs); - fp->flag &= (BYTE)~FA_MODIFIED; - } - } - FREE_NAMBUF(); - } - } else -#endif - { - res = move_window(fs, fp->dir_sect); - if (res == FR_OK) { - dir = fp->dir_ptr; - dir[DIR_Attr] |= AM_ARC; /* Set archive attribute to indicate that the file has been changed */ - st_clust(fp->obj.fs, dir, fp->obj.sclust); /* Update file allocation information */ - st_dword(dir + DIR_FileSize, (DWORD)fp->obj.objsize); /* Update file size */ - st_dword(dir + DIR_ModTime, tm); /* Update modified time */ - st_word(dir + DIR_LstAccDate, 0); - fs->wflag = 1; - res = sync_fs(fs); /* Restore it to the directory */ - fp->flag &= (BYTE)~FA_MODIFIED; - } - } - } - } - - LEAVE_FF(fs, res); -} - -#endif /* !FF_FS_READONLY */ - - - - -/*-----------------------------------------------------------------------*/ -/* Close File */ -/*-----------------------------------------------------------------------*/ - -FRESULT f_close ( - FIL* fp /* Pointer to the file object to be closed */ -) -{ - FRESULT res; - FATFS *fs; - -#if !FF_FS_READONLY - res = f_sync(fp); /* Flush cached data */ - if (res == FR_OK) -#endif - { - res = validate(&fp->obj, &fs); /* Lock volume */ - if (res == FR_OK) { -#if FF_FS_LOCK != 0 - res = dec_lock(fp->obj.lockid); /* Decrement file open counter */ - if (res == FR_OK) fp->obj.fs = 0; /* Invalidate file object */ -#else - fp->obj.fs = 0; /* Invalidate file object */ -#endif -#if FF_FS_REENTRANT - unlock_fs(fs, FR_OK); /* Unlock volume */ -#endif - } - } - return res; -} - - - - -#if FF_FS_RPATH >= 1 -/*-----------------------------------------------------------------------*/ -/* Change Current Directory or Current Drive, Get Current Directory */ -/*-----------------------------------------------------------------------*/ - -FRESULT f_chdrive ( - const TCHAR* path /* Drive number to set */ -) -{ - int vol; - - - /* Get logical drive number */ - vol = get_ldnumber(&path); - if (vol < 0) return FR_INVALID_DRIVE; - CurrVol = (BYTE)vol; /* Set it as current volume */ - - return FR_OK; -} - - - -FRESULT f_chdir ( - const TCHAR* path /* Pointer to the directory path */ -) -{ -#if FF_STR_VOLUME_ID == 2 - UINT i; -#endif - FRESULT res; - DIR dj; - FATFS *fs; - DEF_NAMBUF - - - /* Get logical drive */ - res = find_volume(&path, &fs, 0); - if (res == FR_OK) { - dj.obj.fs = fs; - INIT_NAMBUF(fs); - res = follow_path(&dj, path); /* Follow the path */ - if (res == FR_OK) { /* Follow completed */ - if (dj.fn[NSFLAG] & NS_NONAME) { /* Is it the start directory itself? */ - fs->cdir = dj.obj.sclust; -#if FF_FS_EXFAT - if (fs->fs_type == FS_EXFAT) { - fs->cdc_scl = dj.obj.c_scl; - fs->cdc_size = dj.obj.c_size; - fs->cdc_ofs = dj.obj.c_ofs; - } -#endif - } else { - if (dj.obj.attr & AM_DIR) { /* It is a sub-directory */ -#if FF_FS_EXFAT - if (fs->fs_type == FS_EXFAT) { - fs->cdir = ld_dword(fs->dirbuf + XDIR_FstClus); /* Sub-directory cluster */ - fs->cdc_scl = dj.obj.sclust; /* Save containing directory information */ - fs->cdc_size = ((DWORD)dj.obj.objsize & 0xFFFFFF00) | dj.obj.stat; - fs->cdc_ofs = dj.blk_ofs; - } else -#endif - { - fs->cdir = ld_clust(fs, dj.dir); /* Sub-directory cluster */ - } - } else { - res = FR_NO_PATH; /* Reached but a file */ - } - } - } - FREE_NAMBUF(); - if (res == FR_NO_FILE) res = FR_NO_PATH; -#if FF_STR_VOLUME_ID == 2 /* Also current drive is changed at Unix style volume ID */ - if (res == FR_OK) { - for (i = FF_VOLUMES - 1; i && fs != FatFs[i]; i--) ; /* Set current drive */ - CurrVol = (BYTE)i; - } -#endif - } - - LEAVE_FF(fs, res); -} - - -#if FF_FS_RPATH >= 2 -FRESULT f_getcwd ( - TCHAR* buff, /* Pointer to the directory path */ - UINT len /* Size of buff in unit of TCHAR */ -) -{ - FRESULT res; - DIR dj; - FATFS *fs; - UINT i, n; - DWORD ccl; - TCHAR *tp = buff; -#if FF_VOLUMES >= 2 - UINT vl; -#endif -#if FF_STR_VOLUME_ID - const char *vp; -#endif - FILINFO fno; - DEF_NAMBUF - - - /* Get logical drive */ - res = find_volume((const TCHAR**)&buff, &fs, 0); /* Get current volume */ - if (res == FR_OK) { - dj.obj.fs = fs; - INIT_NAMBUF(fs); - - /* Follow parent directories and create the path */ - i = len; /* Bottom of buffer (directory stack base) */ - if (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) { /* (Cannot do getcwd on exFAT and returns root path) */ - dj.obj.sclust = fs->cdir; /* Start to follow upper directory from current directory */ - while ((ccl = dj.obj.sclust) != 0) { /* Repeat while current directory is a sub-directory */ - res = dir_sdi(&dj, 1 * SZDIRE); /* Get parent directory */ - if (res != FR_OK) break; - res = move_window(fs, dj.sect); - if (res != FR_OK) break; - dj.obj.sclust = ld_clust(fs, dj.dir); /* Goto parent directory */ - res = dir_sdi(&dj, 0); - if (res != FR_OK) break; - do { /* Find the entry links to the child directory */ - res = dir_read_file(&dj); - if (res != FR_OK) break; - if (ccl == ld_clust(fs, dj.dir)) break; /* Found the entry */ - res = dir_next(&dj, 0); - } while (res == FR_OK); - if (res == FR_NO_FILE) res = FR_INT_ERR;/* It cannot be 'not found'. */ - if (res != FR_OK) break; - get_fileinfo(&dj, &fno); /* Get the directory name and push it to the buffer */ - for (n = 0; fno.fname[n]; n++) ; /* Name length */ - if (i < n + 1) { /* Insufficient space to store the path name? */ - res = FR_NOT_ENOUGH_CORE; break; - } - while (n) buff[--i] = fno.fname[--n]; /* Stack the name */ - buff[--i] = '/'; - } - } - if (res == FR_OK) { - if (i == len) buff[--i] = '/'; /* Is it the root-directory? */ -#if FF_VOLUMES >= 2 /* Put drive prefix */ - vl = 0; -#if FF_STR_VOLUME_ID >= 1 /* String volume ID */ - for (n = 0, vp = (const char*)VolumeStr[CurrVol]; vp[n]; n++) ; - if (i >= n + 2) { - if (FF_STR_VOLUME_ID == 2) *tp++ = (TCHAR)'/'; - for (vl = 0; vl < n; *tp++ = (TCHAR)vp[vl], vl++) ; - if (FF_STR_VOLUME_ID == 1) *tp++ = (TCHAR)':'; - vl++; - } -#else /* Numeric volume ID */ - if (i >= 3) { - *tp++ = (TCHAR)'0' + CurrVol; - *tp++ = (TCHAR)':'; - vl = 2; - } -#endif - if (vl == 0) res = FR_NOT_ENOUGH_CORE; -#endif - /* Add current directory path */ - if (res == FR_OK) { - do *tp++ = buff[i++]; while (i < len); /* Copy stacked path string */ - } - } - FREE_NAMBUF(); - } - - *tp = 0; - LEAVE_FF(fs, res); -} - -#endif /* FF_FS_RPATH >= 2 */ -#endif /* FF_FS_RPATH >= 1 */ - - - -#if FF_FS_MINIMIZE <= 2 -/*-----------------------------------------------------------------------*/ -/* Seek File Read/Write Pointer */ -/*-----------------------------------------------------------------------*/ - -FRESULT f_lseek ( - FIL* fp, /* Pointer to the file object */ - FSIZE_t ofs /* File pointer from top of file */ -) -{ - FRESULT res; - FATFS *fs; - DWORD clst, bcs, nsect; - FSIZE_t ifptr; -#if FF_USE_FASTSEEK - DWORD cl, pcl, ncl, tcl, dsc, tlen, ulen, *tbl; -#endif - - res = validate(&fp->obj, &fs); /* Check validity of the file object */ - if (res == FR_OK) res = (FRESULT)fp->err; -#if FF_FS_EXFAT && !FF_FS_READONLY - if (res == FR_OK && fs->fs_type == FS_EXFAT) { - res = fill_last_frag(&fp->obj, fp->clust, 0xFFFFFFFF); /* Fill last fragment on the FAT if needed */ - } -#endif - if (res != FR_OK) LEAVE_FF(fs, res); - -#if FF_USE_FASTSEEK - if (fp->cltbl) { /* Fast seek */ - if (ofs == CREATE_LINKMAP) { /* Create CLMT */ - tbl = fp->cltbl; - tlen = *tbl++; ulen = 2; /* Given table size and required table size */ - cl = fp->obj.sclust; /* Origin of the chain */ - if (cl != 0) { - do { - /* Get a fragment */ - tcl = cl; ncl = 0; ulen += 2; /* Top, length and used items */ - do { - pcl = cl; ncl++; - cl = get_fat(&fp->obj, cl); - if (cl <= 1) ABORT(fs, FR_INT_ERR); - if (cl == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR); - } while (cl == pcl + 1); - if (ulen <= tlen) { /* Store the length and top of the fragment */ - *tbl++ = ncl; *tbl++ = tcl; - } - } while (cl < fs->n_fatent); /* Repeat until end of chain */ - } - *fp->cltbl = ulen; /* Number of items used */ - if (ulen <= tlen) { - *tbl = 0; /* Terminate table */ - } else { - res = FR_NOT_ENOUGH_CORE; /* Given table size is smaller than required */ - } - } else { /* Fast seek */ - if (ofs > fp->obj.objsize) ofs = fp->obj.objsize; /* Clip offset at the file size */ - fp->fptr = ofs; /* Set file pointer */ - if (ofs > 0) { - fp->clust = clmt_clust(fp, ofs - 1); - dsc = clst2sect(fs, fp->clust); - if (dsc == 0) ABORT(fs, FR_INT_ERR); - dsc += (DWORD)((ofs - 1) / SS(fs)) & (fs->csize - 1); - if (fp->fptr % SS(fs) && dsc != fp->sect) { /* Refill sector cache if needed */ -#if !FF_FS_TINY -#if !FF_FS_READONLY - if (fp->flag & FA_DIRTY) { /* Write-back dirty sector cache */ - if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); - fp->flag &= (BYTE)~FA_DIRTY; - } -#endif - if (disk_read(fs->pdrv, fp->buf, dsc, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Load current sector */ -#endif - fp->sect = dsc; - } - } - } - } else -#endif - - /* Normal Seek */ - { -#if FF_FS_EXFAT - if (fs->fs_type != FS_EXFAT && ofs >= 0x100000000) ofs = 0xFFFFFFFF; /* Clip at 4 GiB - 1 if at FATxx */ -#endif - if (ofs > fp->obj.objsize && (FF_FS_READONLY || !(fp->flag & FA_WRITE))) { /* In read-only mode, clip offset with the file size */ - ofs = fp->obj.objsize; - } - ifptr = fp->fptr; - fp->fptr = nsect = 0; - if (ofs > 0) { - bcs = (DWORD)fs->csize * SS(fs); /* Cluster size (byte) */ - if (ifptr > 0 && - (ofs - 1) / bcs >= (ifptr - 1) / bcs) { /* When seek to same or following cluster, */ - fp->fptr = (ifptr - 1) & ~(FSIZE_t)(bcs - 1); /* start from the current cluster */ - ofs -= fp->fptr; - clst = fp->clust; - } else { /* When seek to back cluster, */ - clst = fp->obj.sclust; /* start from the first cluster */ -#if !FF_FS_READONLY - if (clst == 0) { /* If no cluster chain, create a new chain */ - clst = create_chain(&fp->obj, 0); - if (clst == 1) ABORT(fs, FR_INT_ERR); - if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR); - fp->obj.sclust = clst; - } -#endif - fp->clust = clst; - } - if (clst != 0) { - while (ofs > bcs) { /* Cluster following loop */ - ofs -= bcs; fp->fptr += bcs; -#if !FF_FS_READONLY - if (fp->flag & FA_WRITE) { /* Check if in write mode or not */ - if (FF_FS_EXFAT && fp->fptr > fp->obj.objsize) { /* No FAT chain object needs correct objsize to generate FAT value */ - fp->obj.objsize = fp->fptr; - fp->flag |= FA_MODIFIED; - } - clst = create_chain(&fp->obj, clst); /* Follow chain with forceed stretch */ - if (clst == 0) { /* Clip file size in case of disk full */ - ofs = 0; break; - } - } else -#endif - { - clst = get_fat(&fp->obj, clst); /* Follow cluster chain if not in write mode */ - } - if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR); - if (clst <= 1 || clst >= fs->n_fatent) ABORT(fs, FR_INT_ERR); - fp->clust = clst; - } - fp->fptr += ofs; - if (ofs % SS(fs)) { - nsect = clst2sect(fs, clst); /* Current sector */ - if (nsect == 0) ABORT(fs, FR_INT_ERR); - nsect += (DWORD)(ofs / SS(fs)); - } - } - } - if (!FF_FS_READONLY && fp->fptr > fp->obj.objsize) { /* Set file change flag if the file size is extended */ - fp->obj.objsize = fp->fptr; - fp->flag |= FA_MODIFIED; - } - if (fp->fptr % SS(fs) && nsect != fp->sect) { /* Fill sector cache if needed */ -#if !FF_FS_TINY -#if !FF_FS_READONLY - if (fp->flag & FA_DIRTY) { /* Write-back dirty sector cache */ - if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); - fp->flag &= (BYTE)~FA_DIRTY; - } -#endif - if (disk_read(fs->pdrv, fp->buf, nsect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Fill sector cache */ -#endif - fp->sect = nsect; - } - } - - LEAVE_FF(fs, res); -} - - - -#if FF_FS_MINIMIZE <= 1 -/*-----------------------------------------------------------------------*/ -/* Create a Directory Object */ -/*-----------------------------------------------------------------------*/ - -FRESULT f_opendir ( - DIR* dp, /* Pointer to directory object to create */ - const TCHAR* path /* Pointer to the directory path */ -) -{ - FRESULT res; - FATFS *fs; - DEF_NAMBUF - - - if (!dp) return FR_INVALID_OBJECT; - - /* Get logical drive */ - res = find_volume(&path, &fs, 0); - if (res == FR_OK) { - dp->obj.fs = fs; - INIT_NAMBUF(fs); - res = follow_path(dp, path); /* Follow the path to the directory */ - if (res == FR_OK) { /* Follow completed */ - if (!(dp->fn[NSFLAG] & NS_NONAME)) { /* It is not the origin directory itself */ - if (dp->obj.attr & AM_DIR) { /* This object is a sub-directory */ -#if FF_FS_EXFAT - if (fs->fs_type == FS_EXFAT) { - dp->obj.c_scl = dp->obj.sclust; /* Get containing directory inforamation */ - dp->obj.c_size = ((DWORD)dp->obj.objsize & 0xFFFFFF00) | dp->obj.stat; - dp->obj.c_ofs = dp->blk_ofs; - init_alloc_info(fs, &dp->obj); /* Get object allocation info */ - } else -#endif - { - dp->obj.sclust = ld_clust(fs, dp->dir); /* Get object allocation info */ - } - } else { /* This object is a file */ - res = FR_NO_PATH; - } - } - if (res == FR_OK) { - dp->obj.id = fs->id; - res = dir_sdi(dp, 0); /* Rewind directory */ -#if FF_FS_LOCK != 0 - if (res == FR_OK) { - if (dp->obj.sclust != 0) { - dp->obj.lockid = inc_lock(dp, 0); /* Lock the sub directory */ - if (!dp->obj.lockid) res = FR_TOO_MANY_OPEN_FILES; - } else { - dp->obj.lockid = 0; /* Root directory need not to be locked */ - } - } -#endif - } - } - FREE_NAMBUF(); - if (res == FR_NO_FILE) res = FR_NO_PATH; - } - if (res != FR_OK) dp->obj.fs = 0; /* Invalidate the directory object if function faild */ - - LEAVE_FF(fs, res); -} - - - - -/*-----------------------------------------------------------------------*/ -/* Close Directory */ -/*-----------------------------------------------------------------------*/ - -FRESULT f_closedir ( - DIR *dp /* Pointer to the directory object to be closed */ -) -{ - FRESULT res; - FATFS *fs; - - - res = validate(&dp->obj, &fs); /* Check validity of the file object */ - if (res == FR_OK) { -#if FF_FS_LOCK != 0 - if (dp->obj.lockid) res = dec_lock(dp->obj.lockid); /* Decrement sub-directory open counter */ - if (res == FR_OK) dp->obj.fs = 0; /* Invalidate directory object */ -#else - dp->obj.fs = 0; /* Invalidate directory object */ -#endif -#if FF_FS_REENTRANT - unlock_fs(fs, FR_OK); /* Unlock volume */ -#endif - } - return res; -} - - - - -/*-----------------------------------------------------------------------*/ -/* Read Directory Entries in Sequence */ -/*-----------------------------------------------------------------------*/ - -FRESULT f_readdir ( - DIR* dp, /* Pointer to the open directory object */ - FILINFO* fno /* Pointer to file information to return */ -) -{ - FRESULT res; - FATFS *fs; - DEF_NAMBUF - - - res = validate(&dp->obj, &fs); /* Check validity of the directory object */ - if (res == FR_OK) { - if (!fno) { - res = dir_sdi(dp, 0); /* Rewind the directory object */ - } else { - INIT_NAMBUF(fs); - res = dir_read_file(dp); /* Read an item */ - if (res == FR_NO_FILE) res = FR_OK; /* Ignore end of directory */ - if (res == FR_OK) { /* A valid entry is found */ - get_fileinfo(dp, fno); /* Get the object information */ - res = dir_next(dp, 0); /* Increment index for next */ - if (res == FR_NO_FILE) res = FR_OK; /* Ignore end of directory now */ - } - FREE_NAMBUF(); - } - } - LEAVE_FF(fs, res); -} - - - -#if FF_USE_FIND -/*-----------------------------------------------------------------------*/ -/* Find Next File */ -/*-----------------------------------------------------------------------*/ - -FRESULT f_findnext ( - DIR* dp, /* Pointer to the open directory object */ - FILINFO* fno /* Pointer to the file information structure */ -) -{ - FRESULT res; - - - for (;;) { - res = f_readdir(dp, fno); /* Get a directory item */ - if (res != FR_OK || !fno || !fno->fname[0]) break; /* Terminate if any error or end of directory */ - if (pattern_matching(dp->pat, fno->fname, 0, 0)) break; /* Test for the file name */ -#if FF_USE_LFN && FF_USE_FIND == 2 - if (pattern_matching(dp->pat, fno->altname, 0, 0)) break; /* Test for alternative name if exist */ -#endif - } - return res; -} - - - -/*-----------------------------------------------------------------------*/ -/* Find First File */ -/*-----------------------------------------------------------------------*/ - -FRESULT f_findfirst ( - DIR* dp, /* Pointer to the blank directory object */ - FILINFO* fno, /* Pointer to the file information structure */ - const TCHAR* path, /* Pointer to the directory to open */ - const TCHAR* pattern /* Pointer to the matching pattern */ -) -{ - FRESULT res; - - - dp->pat = pattern; /* Save pointer to pattern string */ - res = f_opendir(dp, path); /* Open the target directory */ - if (res == FR_OK) { - res = f_findnext(dp, fno); /* Find the first item */ - } - return res; -} - -#endif /* FF_USE_FIND */ - - - -#if FF_FS_MINIMIZE == 0 -/*-----------------------------------------------------------------------*/ -/* Get File Status */ -/*-----------------------------------------------------------------------*/ - -FRESULT f_stat ( - const TCHAR* path, /* Pointer to the file path */ - FILINFO* fno /* Pointer to file information to return */ -) -{ - FRESULT res; - DIR dj; - DEF_NAMBUF - - - /* Get logical drive */ - res = find_volume(&path, &dj.obj.fs, 0); - if (res == FR_OK) { - INIT_NAMBUF(dj.obj.fs); - res = follow_path(&dj, path); /* Follow the file path */ - if (res == FR_OK) { /* Follow completed */ - if (dj.fn[NSFLAG] & NS_NONAME) { /* It is origin directory */ - res = FR_INVALID_NAME; - } else { /* Found an object */ - if (fno) get_fileinfo(&dj, fno); - } - } - FREE_NAMBUF(); - } - - LEAVE_FF(dj.obj.fs, res); -} - - - -#if !FF_FS_READONLY -/*-----------------------------------------------------------------------*/ -/* Get Number of Free Clusters */ -/*-----------------------------------------------------------------------*/ - -FRESULT f_getfree ( - const TCHAR* path, /* Logical drive number */ - DWORD* nclst, /* Pointer to a variable to return number of free clusters */ - FATFS** fatfs /* Pointer to return pointer to corresponding filesystem object */ -) -{ - FRESULT res; - FATFS *fs; - DWORD nfree, clst, sect, stat; - UINT i; - FFOBJID obj; - - - /* Get logical drive */ - res = find_volume(&path, &fs, 0); - if (res == FR_OK) { - *fatfs = fs; /* Return ptr to the fs object */ - /* If free_clst is valid, return it without full FAT scan */ - if (fs->free_clst <= fs->n_fatent - 2) { - *nclst = fs->free_clst; - } else { - /* Scan FAT to obtain number of free clusters */ - nfree = 0; - if (fs->fs_type == FS_FAT12) { /* FAT12: Scan bit field FAT entries */ - clst = 2; obj.fs = fs; - do { - stat = get_fat(&obj, clst); - if (stat == 0xFFFFFFFF) { res = FR_DISK_ERR; break; } - if (stat == 1) { res = FR_INT_ERR; break; } - if (stat == 0) nfree++; - } while (++clst < fs->n_fatent); - } else { -#if FF_FS_EXFAT - if (fs->fs_type == FS_EXFAT) { /* exFAT: Scan allocation bitmap */ - BYTE bm; - UINT b; - - clst = fs->n_fatent - 2; /* Number of clusters */ - sect = fs->database; /* Assuming bitmap starts at cluster 2 */ - i = 0; /* Offset in the sector */ - do { /* Counts numbuer of bits with zero in the bitmap */ - if (i == 0) { - res = move_window(fs, sect++); - if (res != FR_OK) break; - } - for (b = 8, bm = fs->win[i]; b && clst; b--, clst--) { - if (!(bm & 1)) nfree++; - bm >>= 1; - } - i = (i + 1) % SS(fs); - } while (clst); - } else -#endif - { /* FAT16/32: Scan WORD/DWORD FAT entries */ - clst = fs->n_fatent; /* Number of entries */ - sect = fs->fatbase; /* Top of the FAT */ - i = 0; /* Offset in the sector */ - do { /* Counts numbuer of entries with zero in the FAT */ - if (i == 0) { - res = move_window(fs, sect++); - if (res != FR_OK) break; - } - if (fs->fs_type == FS_FAT16) { - if (ld_word(fs->win + i) == 0) nfree++; - i += 2; - } else { - if ((ld_dword(fs->win + i) & 0x0FFFFFFF) == 0) nfree++; - i += 4; - } - i %= SS(fs); - } while (--clst); - } - } - *nclst = nfree; /* Return the free clusters */ - fs->free_clst = nfree; /* Now free_clst is valid */ - fs->fsi_flag |= 1; /* FAT32: FSInfo is to be updated */ - } - } - - LEAVE_FF(fs, res); -} - - - - -/*-----------------------------------------------------------------------*/ -/* Truncate File */ -/*-----------------------------------------------------------------------*/ - -FRESULT f_truncate ( - FIL* fp /* Pointer to the file object */ -) -{ - FRESULT res; - FATFS *fs; - DWORD ncl; - - - res = validate(&fp->obj, &fs); /* Check validity of the file object */ - if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); - if (!(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */ - - if (fp->fptr < fp->obj.objsize) { /* Process when fptr is not on the eof */ - if (fp->fptr == 0) { /* When set file size to zero, remove entire cluster chain */ - res = remove_chain(&fp->obj, fp->obj.sclust, 0); - fp->obj.sclust = 0; - } else { /* When truncate a part of the file, remove remaining clusters */ - ncl = get_fat(&fp->obj, fp->clust); - res = FR_OK; - if (ncl == 0xFFFFFFFF) res = FR_DISK_ERR; - if (ncl == 1) res = FR_INT_ERR; - if (res == FR_OK && ncl < fs->n_fatent) { - res = remove_chain(&fp->obj, ncl, fp->clust); - } - } - fp->obj.objsize = fp->fptr; /* Set file size to current read/write point */ - fp->flag |= FA_MODIFIED; -#if !FF_FS_TINY - if (res == FR_OK && (fp->flag & FA_DIRTY)) { - if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) { - res = FR_DISK_ERR; - } else { - fp->flag &= (BYTE)~FA_DIRTY; - } - } -#endif - if (res != FR_OK) ABORT(fs, res); - } - - LEAVE_FF(fs, res); -} - - - - -/*-----------------------------------------------------------------------*/ -/* Delete a File/Directory */ -/*-----------------------------------------------------------------------*/ - -FRESULT f_unlink ( - const TCHAR* path /* Pointer to the file or directory path */ -) -{ - FRESULT res; - DIR dj, sdj; - DWORD dclst = 0; - FATFS *fs; -#if FF_FS_EXFAT - FFOBJID obj; -#endif - DEF_NAMBUF - - - /* Get logical drive */ - res = find_volume(&path, &fs, FA_WRITE); - if (res == FR_OK) { - dj.obj.fs = fs; - INIT_NAMBUF(fs); - res = follow_path(&dj, path); /* Follow the file path */ - if (FF_FS_RPATH && res == FR_OK && (dj.fn[NSFLAG] & NS_DOT)) { - res = FR_INVALID_NAME; /* Cannot remove dot entry */ - } -#if FF_FS_LOCK != 0 - if (res == FR_OK) res = chk_lock(&dj, 2); /* Check if it is an open object */ -#endif - if (res == FR_OK) { /* The object is accessible */ - if (dj.fn[NSFLAG] & NS_NONAME) { - res = FR_INVALID_NAME; /* Cannot remove the origin directory */ - } else { - if (dj.obj.attr & AM_RDO) { - res = FR_DENIED; /* Cannot remove R/O object */ - } - } - if (res == FR_OK) { -#if FF_FS_EXFAT - obj.fs = fs; - if (fs->fs_type == FS_EXFAT) { - init_alloc_info(fs, &obj); - dclst = obj.sclust; - } else -#endif - { - dclst = ld_clust(fs, dj.dir); - } - if (dj.obj.attr & AM_DIR) { /* Is it a sub-directory? */ -#if FF_FS_RPATH != 0 - if (dclst == fs->cdir) { /* Is it the current directory? */ - res = FR_DENIED; - } else -#endif - { - sdj.obj.fs = fs; /* Open the sub-directory */ - sdj.obj.sclust = dclst; -#if FF_FS_EXFAT - if (fs->fs_type == FS_EXFAT) { - sdj.obj.objsize = obj.objsize; - sdj.obj.stat = obj.stat; - } -#endif - res = dir_sdi(&sdj, 0); - if (res == FR_OK) { - res = dir_read_file(&sdj); /* Test if the directory is empty */ - if (res == FR_OK) res = FR_DENIED; /* Not empty? */ - if (res == FR_NO_FILE) res = FR_OK; /* Empty? */ - } - } - } - } - if (res == FR_OK) { - res = dir_remove(&dj); /* Remove the directory entry */ - if (res == FR_OK && dclst != 0) { /* Remove the cluster chain if exist */ -#if FF_FS_EXFAT - res = remove_chain(&obj, dclst, 0); -#else - res = remove_chain(&dj.obj, dclst, 0); -#endif - } - if (res == FR_OK) res = sync_fs(fs); - } - } - FREE_NAMBUF(); - } - - LEAVE_FF(fs, res); -} - - - - -/*-----------------------------------------------------------------------*/ -/* Create a Directory */ -/*-----------------------------------------------------------------------*/ - -FRESULT f_mkdir ( - const TCHAR* path /* Pointer to the directory path */ -) -{ - FRESULT res; - DIR dj; - FATFS *fs; - BYTE *dir; - DWORD dcl, pcl, tm; - DEF_NAMBUF - - - /* Get logical drive */ - res = find_volume(&path, &fs, FA_WRITE); - if (res == FR_OK) { - dj.obj.fs = fs; - INIT_NAMBUF(fs); - res = follow_path(&dj, path); /* Follow the file path */ - if (res == FR_OK) res = FR_EXIST; /* Any object with same name is already existing */ - if (FF_FS_RPATH && res == FR_NO_FILE && (dj.fn[NSFLAG] & NS_DOT)) { - res = FR_INVALID_NAME; - } - if (res == FR_NO_FILE) { /* Can create a new directory */ - dcl = create_chain(&dj.obj, 0); /* Allocate a cluster for the new directory table */ - dj.obj.objsize = (DWORD)fs->csize * SS(fs); - res = FR_OK; - if (dcl == 0) res = FR_DENIED; /* No space to allocate a new cluster */ - if (dcl == 1) res = FR_INT_ERR; - if (dcl == 0xFFFFFFFF) res = FR_DISK_ERR; - if (res == FR_OK) res = sync_window(fs); /* Flush FAT */ - tm = GET_FATTIME(); - if (res == FR_OK) { /* Initialize the new directory table */ - res = dir_clear(fs, dcl); /* Clean up the new table */ - if (res == FR_OK && (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT)) { /* Create dot entries (FAT only) */ - dir = fs->win; - mem_set(dir + DIR_Name, ' ', 11); /* Create "." entry */ - dir[DIR_Name] = '.'; - dir[DIR_Attr] = AM_DIR; - st_dword(dir + DIR_ModTime, tm); - st_clust(fs, dir, dcl); - mem_cpy(dir + SZDIRE, dir, SZDIRE); /* Create ".." entry */ - dir[SZDIRE + 1] = '.'; pcl = dj.obj.sclust; - st_clust(fs, dir + SZDIRE, pcl); - fs->wflag = 1; - } - } - if (res == FR_OK) { - res = dir_register(&dj); /* Register the object to the directoy */ - } - if (res == FR_OK) { -#if FF_FS_EXFAT - if (fs->fs_type == FS_EXFAT) { /* Initialize directory entry block */ - st_dword(fs->dirbuf + XDIR_ModTime, tm); /* Created time */ - st_dword(fs->dirbuf + XDIR_FstClus, dcl); /* Table start cluster */ - st_dword(fs->dirbuf + XDIR_FileSize, (DWORD)dj.obj.objsize); /* File size needs to be valid */ - st_dword(fs->dirbuf + XDIR_ValidFileSize, (DWORD)dj.obj.objsize); - fs->dirbuf[XDIR_GenFlags] = 3; /* Initialize the object flag */ - fs->dirbuf[XDIR_Attr] = AM_DIR; /* Attribute */ - res = store_xdir(&dj); - } else -#endif - { - dir = dj.dir; - st_dword(dir + DIR_ModTime, tm); /* Created time */ - st_clust(fs, dir, dcl); /* Table start cluster */ - dir[DIR_Attr] = AM_DIR; /* Attribute */ - fs->wflag = 1; - } - if (res == FR_OK) { - res = sync_fs(fs); - } - } else { - remove_chain(&dj.obj, dcl, 0); /* Could not register, remove cluster chain */ - } - } - FREE_NAMBUF(); - } - - LEAVE_FF(fs, res); -} - - - - -/*-----------------------------------------------------------------------*/ -/* Rename a File/Directory */ -/*-----------------------------------------------------------------------*/ - -FRESULT f_rename ( - const TCHAR* path_old, /* Pointer to the object name to be renamed */ - const TCHAR* path_new /* Pointer to the new name */ -) -{ - FRESULT res; - DIR djo, djn; - FATFS *fs; - BYTE buf[FF_FS_EXFAT ? SZDIRE * 2 : SZDIRE], *dir; - DWORD dw; - DEF_NAMBUF - - - get_ldnumber(&path_new); /* Snip the drive number of new name off */ - res = find_volume(&path_old, &fs, FA_WRITE); /* Get logical drive of the old object */ - if (res == FR_OK) { - djo.obj.fs = fs; - INIT_NAMBUF(fs); - res = follow_path(&djo, path_old); /* Check old object */ - if (res == FR_OK && (djo.fn[NSFLAG] & (NS_DOT | NS_NONAME))) res = FR_INVALID_NAME; /* Check validity of name */ -#if FF_FS_LOCK != 0 - if (res == FR_OK) { - res = chk_lock(&djo, 2); - } -#endif - if (res == FR_OK) { /* Object to be renamed is found */ -#if FF_FS_EXFAT - if (fs->fs_type == FS_EXFAT) { /* At exFAT volume */ - BYTE nf, nn; - WORD nh; - - mem_cpy(buf, fs->dirbuf, SZDIRE * 2); /* Save 85+C0 entry of old object */ - mem_cpy(&djn, &djo, sizeof djo); - res = follow_path(&djn, path_new); /* Make sure if new object name is not in use */ - if (res == FR_OK) { /* Is new name already in use by any other object? */ - res = (djn.obj.sclust == djo.obj.sclust && djn.dptr == djo.dptr) ? FR_NO_FILE : FR_EXIST; - } - if (res == FR_NO_FILE) { /* It is a valid path and no name collision */ - res = dir_register(&djn); /* Register the new entry */ - if (res == FR_OK) { - nf = fs->dirbuf[XDIR_NumSec]; nn = fs->dirbuf[XDIR_NumName]; - nh = ld_word(fs->dirbuf + XDIR_NameHash); - mem_cpy(fs->dirbuf, buf, SZDIRE * 2); /* Restore 85+C0 entry */ - fs->dirbuf[XDIR_NumSec] = nf; fs->dirbuf[XDIR_NumName] = nn; - st_word(fs->dirbuf + XDIR_NameHash, nh); - if (!(fs->dirbuf[XDIR_Attr] & AM_DIR)) fs->dirbuf[XDIR_Attr] |= AM_ARC; /* Set archive attribute if it is a file */ -/* Start of critical section where an interruption can cause a cross-link */ - res = store_xdir(&djn); - } - } - } else -#endif - { /* At FAT/FAT32 volume */ - mem_cpy(buf, djo.dir, SZDIRE); /* Save directory entry of the object */ - mem_cpy(&djn, &djo, sizeof (DIR)); /* Duplicate the directory object */ - res = follow_path(&djn, path_new); /* Make sure if new object name is not in use */ - if (res == FR_OK) { /* Is new name already in use by any other object? */ - res = (djn.obj.sclust == djo.obj.sclust && djn.dptr == djo.dptr) ? FR_NO_FILE : FR_EXIST; - } - if (res == FR_NO_FILE) { /* It is a valid path and no name collision */ - res = dir_register(&djn); /* Register the new entry */ - if (res == FR_OK) { - dir = djn.dir; /* Copy directory entry of the object except name */ - mem_cpy(dir + 13, buf + 13, SZDIRE - 13); - dir[DIR_Attr] = buf[DIR_Attr]; - if (!(dir[DIR_Attr] & AM_DIR)) dir[DIR_Attr] |= AM_ARC; /* Set archive attribute if it is a file */ - fs->wflag = 1; - if ((dir[DIR_Attr] & AM_DIR) && djo.obj.sclust != djn.obj.sclust) { /* Update .. entry in the sub-directory if needed */ - dw = clst2sect(fs, ld_clust(fs, dir)); - if (dw == 0) { - res = FR_INT_ERR; - } else { -/* Start of critical section where an interruption can cause a cross-link */ - res = move_window(fs, dw); - dir = fs->win + SZDIRE * 1; /* Ptr to .. entry */ - if (res == FR_OK && dir[1] == '.') { - st_clust(fs, dir, djn.obj.sclust); - fs->wflag = 1; - } - } - } - } - } - } - if (res == FR_OK) { - res = dir_remove(&djo); /* Remove old entry */ - if (res == FR_OK) { - res = sync_fs(fs); - } - } -/* End of the critical section */ - } - FREE_NAMBUF(); - } - - LEAVE_FF(fs, res); -} - -#endif /* !FF_FS_READONLY */ -#endif /* FF_FS_MINIMIZE == 0 */ -#endif /* FF_FS_MINIMIZE <= 1 */ -#endif /* FF_FS_MINIMIZE <= 2 */ - - - -#if FF_USE_CHMOD && !FF_FS_READONLY -/*-----------------------------------------------------------------------*/ -/* Change Attribute */ -/*-----------------------------------------------------------------------*/ - -FRESULT f_chmod ( - const TCHAR* path, /* Pointer to the file path */ - BYTE attr, /* Attribute bits */ - BYTE mask /* Attribute mask to change */ -) -{ - FRESULT res; - DIR dj; - FATFS *fs; - DEF_NAMBUF - - - res = find_volume(&path, &fs, FA_WRITE); /* Get logical drive */ - if (res == FR_OK) { - dj.obj.fs = fs; - INIT_NAMBUF(fs); - res = follow_path(&dj, path); /* Follow the file path */ - if (res == FR_OK && (dj.fn[NSFLAG] & (NS_DOT | NS_NONAME))) res = FR_INVALID_NAME; /* Check object validity */ - if (res == FR_OK) { - mask &= AM_RDO|AM_HID|AM_SYS|AM_ARC; /* Valid attribute mask */ -#if FF_FS_EXFAT - if (fs->fs_type == FS_EXFAT) { - fs->dirbuf[XDIR_Attr] = (attr & mask) | (fs->dirbuf[XDIR_Attr] & (BYTE)~mask); /* Apply attribute change */ - res = store_xdir(&dj); - } else -#endif - { - dj.dir[DIR_Attr] = (attr & mask) | (dj.dir[DIR_Attr] & (BYTE)~mask); /* Apply attribute change */ - fs->wflag = 1; - } - if (res == FR_OK) { - res = sync_fs(fs); - } - } - FREE_NAMBUF(); - } - - LEAVE_FF(fs, res); -} - - - - -/*-----------------------------------------------------------------------*/ -/* Change Timestamp */ -/*-----------------------------------------------------------------------*/ - -FRESULT f_utime ( - const TCHAR* path, /* Pointer to the file/directory name */ - const FILINFO* fno /* Pointer to the timestamp to be set */ -) -{ - FRESULT res; - DIR dj; - FATFS *fs; - DEF_NAMBUF - - - res = find_volume(&path, &fs, FA_WRITE); /* Get logical drive */ - if (res == FR_OK) { - dj.obj.fs = fs; - INIT_NAMBUF(fs); - res = follow_path(&dj, path); /* Follow the file path */ - if (res == FR_OK && (dj.fn[NSFLAG] & (NS_DOT | NS_NONAME))) res = FR_INVALID_NAME; /* Check object validity */ - if (res == FR_OK) { -#if FF_FS_EXFAT - if (fs->fs_type == FS_EXFAT) { - st_dword(fs->dirbuf + XDIR_ModTime, (DWORD)fno->fdate << 16 | fno->ftime); - res = store_xdir(&dj); - } else -#endif - { - st_dword(dj.dir + DIR_ModTime, (DWORD)fno->fdate << 16 | fno->ftime); - fs->wflag = 1; - } - if (res == FR_OK) { - res = sync_fs(fs); - } - } - FREE_NAMBUF(); - } - - LEAVE_FF(fs, res); -} - -#endif /* FF_USE_CHMOD && !FF_FS_READONLY */ - - - -#if FF_USE_LABEL -/*-----------------------------------------------------------------------*/ -/* Get Volume Label */ -/*-----------------------------------------------------------------------*/ - -FRESULT f_getlabel ( - const TCHAR* path, /* Logical drive number */ - TCHAR* label, /* Buffer to store the volume label */ - DWORD* vsn /* Variable to store the volume serial number */ -) -{ - FRESULT res; - DIR dj; - FATFS *fs; - UINT si, di; - WCHAR wc; - - /* Get logical drive */ - res = find_volume(&path, &fs, 0); - - /* Get volume label */ - if (res == FR_OK && label) { - dj.obj.fs = fs; dj.obj.sclust = 0; /* Open root directory */ - res = dir_sdi(&dj, 0); - if (res == FR_OK) { - res = dir_read_label(&dj); /* Find a volume label entry */ - if (res == FR_OK) { -#if FF_FS_EXFAT - if (fs->fs_type == FS_EXFAT) { - WCHAR hs; - - for (si = di = hs = 0; si < dj.dir[XDIR_NumLabel]; si++) { /* Extract volume label from 83 entry */ - wc = ld_word(dj.dir + XDIR_Label + si * 2); - if (hs == 0 && IsSurrogate(wc)) { /* Is the code a surrogate? */ - hs = wc; continue; - } - wc = put_utf((DWORD)hs << 16 | wc, &label[di], 4); - if (wc == 0) { di = 0; break; } - di += wc; - hs = 0; - } - if (hs != 0) di = 0; /* Broken surrogate pair? */ - label[di] = 0; - } else -#endif - { - si = di = 0; /* Extract volume label from AM_VOL entry */ - while (si < 11) { - wc = dj.dir[si++]; -#if FF_USE_LFN && FF_LFN_UNICODE >= 1 /* Unicode output */ - if (dbc_1st((BYTE)wc) && si < 11) wc = wc << 8 | dj.dir[si++]; /* Is it a DBC? */ - wc = ff_oem2uni(wc, CODEPAGE); /* Convert it into Unicode */ - if (wc != 0) wc = put_utf(wc, &label[di], 4); /* Put it in Unicode */ - if (wc == 0) { di = 0; break; } - di += wc; -#else /* ANSI/OEM output */ - label[di++] = (TCHAR)wc; -#endif - } - do { /* Truncate trailing spaces */ - label[di] = 0; - if (di == 0) break; - } while (label[--di] == ' '); - } - } - } - if (res == FR_NO_FILE) { /* No label entry and return nul string */ - label[0] = 0; - res = FR_OK; - } - } - - /* Get volume serial number */ - if (res == FR_OK && vsn) { - res = move_window(fs, fs->volbase); - if (res == FR_OK) { - switch (fs->fs_type) { - case FS_EXFAT: - di = BPB_VolIDEx; break; - - case FS_FAT32: - di = BS_VolID32; break; - - default: - di = BS_VolID; - } - *vsn = ld_dword(fs->win + di); - } - } - - LEAVE_FF(fs, res); -} - - - -#if !FF_FS_READONLY -/*-----------------------------------------------------------------------*/ -/* Set Volume Label */ -/*-----------------------------------------------------------------------*/ - -FRESULT f_setlabel ( - const TCHAR* label /* Volume label to set with heading logical drive number */ -) -{ - FRESULT res; - DIR dj; - FATFS *fs; - BYTE dirvn[22]; - UINT di; - WCHAR wc; - static const char badchr[] = "+.,;=[]/\\\"*:<>\?|\x7F"; /* [0..] for FAT, [7..] for exFAT */ -#if FF_USE_LFN - DWORD dc; -#endif - - /* Get logical drive */ - res = find_volume(&label, &fs, FA_WRITE); - if (res != FR_OK) LEAVE_FF(fs, res); - -#if FF_FS_EXFAT - if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ - mem_set(dirvn, 0, 22); - di = 0; - while ((UINT)*label >= ' ') { /* Create volume label */ - dc = tchar2uni(&label); /* Get a Unicode character */ - if (dc >= 0x10000) { - if (dc == 0xFFFFFFFF || di >= 10) { /* Wrong surrogate or buffer overflow */ - dc = 0; - } else { - st_word(dirvn + di * 2, (WCHAR)(dc >> 16)); di++; - } - } - if (dc == 0 || chk_chr(badchr + 7, (int)dc) || di >= 11) { /* Check validity of the volume label */ - LEAVE_FF(fs, FR_INVALID_NAME); - } - st_word(dirvn + di * 2, (WCHAR)dc); di++; - } - } else -#endif - { /* On the FAT/FAT32 volume */ - mem_set(dirvn, ' ', 11); - di = 0; - while ((UINT)*label >= ' ') { /* Create volume label */ -#if FF_USE_LFN - dc = tchar2uni(&label); - wc = (dc < 0x10000) ? ff_uni2oem(ff_wtoupper(dc), CODEPAGE) : 0; -#else /* ANSI/OEM input */ - wc = (BYTE)*label++; - if (dbc_1st((BYTE)wc)) wc = dbc_2nd((BYTE)*label) ? wc << 8 | (BYTE)*label++ : 0; - if (IsLower(wc)) wc -= 0x20; /* To upper ASCII characters */ -#if FF_CODE_PAGE == 0 - if (ExCvt && wc >= 0x80) wc = ExCvt[wc - 0x80]; /* To upper extended characters (SBCS cfg) */ -#elif FF_CODE_PAGE < 900 - if (wc >= 0x80) wc = ExCvt[wc - 0x80]; /* To upper extended characters (SBCS cfg) */ -#endif -#endif - if (wc == 0 || chk_chr(badchr + 0, (int)wc) || di >= (UINT)((wc >= 0x100) ? 10 : 11)) { /* Reject invalid characters for volume label */ - LEAVE_FF(fs, FR_INVALID_NAME); - } - if (wc >= 0x100) dirvn[di++] = (BYTE)(wc >> 8); - dirvn[di++] = (BYTE)wc; - } - if (dirvn[0] == DDEM) LEAVE_FF(fs, FR_INVALID_NAME); /* Reject illegal name (heading DDEM) */ - while (di && dirvn[di - 1] == ' ') di--; /* Snip trailing spaces */ - } - - /* Set volume label */ - dj.obj.fs = fs; dj.obj.sclust = 0; /* Open root directory */ - res = dir_sdi(&dj, 0); - if (res == FR_OK) { - res = dir_read_label(&dj); /* Get volume label entry */ - if (res == FR_OK) { - if (FF_FS_EXFAT && fs->fs_type == FS_EXFAT) { - dj.dir[XDIR_NumLabel] = (BYTE)di; /* Change the volume label */ - mem_cpy(dj.dir + XDIR_Label, dirvn, 22); - } else { - if (di != 0) { - mem_cpy(dj.dir, dirvn, 11); /* Change the volume label */ - } else { - dj.dir[DIR_Name] = DDEM; /* Remove the volume label */ - } - } - fs->wflag = 1; - res = sync_fs(fs); - } else { /* No volume label entry or an error */ - if (res == FR_NO_FILE) { - res = FR_OK; - if (di != 0) { /* Create a volume label entry */ - res = dir_alloc(&dj, 1); /* Allocate an entry */ - if (res == FR_OK) { - mem_set(dj.dir, 0, SZDIRE); /* Clean the entry */ - if (FF_FS_EXFAT && fs->fs_type == FS_EXFAT) { - dj.dir[XDIR_Type] = 0x83; /* Create 83 entry */ - dj.dir[XDIR_NumLabel] = (BYTE)di; - mem_cpy(dj.dir + XDIR_Label, dirvn, 22); - } else { - dj.dir[DIR_Attr] = AM_VOL; /* Create volume label entry */ - mem_cpy(dj.dir, dirvn, 11); - } - fs->wflag = 1; - res = sync_fs(fs); - } - } - } - } - } - - LEAVE_FF(fs, res); -} - -#endif /* !FF_FS_READONLY */ -#endif /* FF_USE_LABEL */ - - - -#if FF_USE_EXPAND && !FF_FS_READONLY -/*-----------------------------------------------------------------------*/ -/* Allocate a Contiguous Blocks to the File */ -/*-----------------------------------------------------------------------*/ - -FRESULT f_expand ( - FIL* fp, /* Pointer to the file object */ - FSIZE_t fsz, /* File size to be expanded to */ - BYTE opt /* Operation mode 0:Find and prepare or 1:Find and allocate */ -) -{ - FRESULT res; - FATFS *fs; - DWORD n, clst, stcl, scl, ncl, tcl, lclst; - - - res = validate(&fp->obj, &fs); /* Check validity of the file object */ - if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); - if (fsz == 0 || fp->obj.objsize != 0 || !(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED); -#if FF_FS_EXFAT - if (fs->fs_type != FS_EXFAT && fsz >= 0x100000000) LEAVE_FF(fs, FR_DENIED); /* Check if in size limit */ -#endif - n = (DWORD)fs->csize * SS(fs); /* Cluster size */ - tcl = (DWORD)(fsz / n) + ((fsz & (n - 1)) ? 1 : 0); /* Number of clusters required */ - stcl = fs->last_clst; lclst = 0; - if (stcl < 2 || stcl >= fs->n_fatent) stcl = 2; - -#if FF_FS_EXFAT - if (fs->fs_type == FS_EXFAT) { - scl = find_bitmap(fs, stcl, tcl); /* Find a contiguous cluster block */ - if (scl == 0) res = FR_DENIED; /* No contiguous cluster block was found */ - if (scl == 0xFFFFFFFF) res = FR_DISK_ERR; - if (res == FR_OK) { /* A contiguous free area is found */ - if (opt) { /* Allocate it now */ - res = change_bitmap(fs, scl, tcl, 1); /* Mark the cluster block 'in use' */ - lclst = scl + tcl - 1; - } else { /* Set it as suggested point for next allocation */ - lclst = scl - 1; - } - } - } else -#endif - { - scl = clst = stcl; ncl = 0; - for (;;) { /* Find a contiguous cluster block */ - n = get_fat(&fp->obj, clst); - if (++clst >= fs->n_fatent) clst = 2; - if (n == 1) { res = FR_INT_ERR; break; } - if (n == 0xFFFFFFFF) { res = FR_DISK_ERR; break; } - if (n == 0) { /* Is it a free cluster? */ - if (++ncl == tcl) break; /* Break if a contiguous cluster block is found */ - } else { - scl = clst; ncl = 0; /* Not a free cluster */ - } - if (clst == stcl) { res = FR_DENIED; break; } /* No contiguous cluster? */ - } - if (res == FR_OK) { /* A contiguous free area is found */ - if (opt) { /* Allocate it now */ - for (clst = scl, n = tcl; n; clst++, n--) { /* Create a cluster chain on the FAT */ - res = put_fat(fs, clst, (n == 1) ? 0xFFFFFFFF : clst + 1); - if (res != FR_OK) break; - lclst = clst; - } - } else { /* Set it as suggested point for next allocation */ - lclst = scl - 1; - } - } - } - - if (res == FR_OK) { - fs->last_clst = lclst; /* Set suggested start cluster to start next */ - if (opt) { /* Is it allocated now? */ - fp->obj.sclust = scl; /* Update object allocation information */ - fp->obj.objsize = fsz; - if (FF_FS_EXFAT) fp->obj.stat = 2; /* Set status 'contiguous chain' */ - fp->flag |= FA_MODIFIED; - if (fs->free_clst <= fs->n_fatent - 2) { /* Update FSINFO */ - fs->free_clst -= tcl; - fs->fsi_flag |= 1; - } - } - } - - LEAVE_FF(fs, res); -} - -#endif /* FF_USE_EXPAND && !FF_FS_READONLY */ - - - -#if FF_USE_FORWARD -/*-----------------------------------------------------------------------*/ -/* Forward Data to the Stream Directly */ -/*-----------------------------------------------------------------------*/ - -FRESULT f_forward ( - FIL* fp, /* Pointer to the file object */ - UINT (*func)(const BYTE*,UINT), /* Pointer to the streaming function */ - UINT btf, /* Number of bytes to forward */ - UINT* bf /* Pointer to number of bytes forwarded */ -) -{ - FRESULT res; - FATFS *fs; - DWORD clst, sect; - FSIZE_t remain; - UINT rcnt, csect; - BYTE *dbuf; - - - *bf = 0; /* Clear transfer byte counter */ - res = validate(&fp->obj, &fs); /* Check validity of the file object */ - if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); - if (!(fp->flag & FA_READ)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */ - - remain = fp->obj.objsize - fp->fptr; - if (btf > remain) btf = (UINT)remain; /* Truncate btf by remaining bytes */ - - for ( ; btf && (*func)(0, 0); /* Repeat until all data transferred or stream goes busy */ - fp->fptr += rcnt, *bf += rcnt, btf -= rcnt) { - csect = (UINT)(fp->fptr / SS(fs) & (fs->csize - 1)); /* Sector offset in the cluster */ - if (fp->fptr % SS(fs) == 0) { /* On the sector boundary? */ - if (csect == 0) { /* On the cluster boundary? */ - clst = (fp->fptr == 0) ? /* On the top of the file? */ - fp->obj.sclust : get_fat(&fp->obj, fp->clust); - if (clst <= 1) ABORT(fs, FR_INT_ERR); - if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR); - fp->clust = clst; /* Update current cluster */ - } - } - sect = clst2sect(fs, fp->clust); /* Get current data sector */ - if (sect == 0) ABORT(fs, FR_INT_ERR); - sect += csect; -#if FF_FS_TINY - if (move_window(fs, sect) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Move sector window to the file data */ - dbuf = fs->win; -#else - if (fp->sect != sect) { /* Fill sector cache with file data */ -#if !FF_FS_READONLY - if (fp->flag & FA_DIRTY) { /* Write-back dirty sector cache */ - if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); - fp->flag &= (BYTE)~FA_DIRTY; - } -#endif - if (disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); - } - dbuf = fp->buf; -#endif - fp->sect = sect; - rcnt = SS(fs) - (UINT)fp->fptr % SS(fs); /* Number of bytes left in the sector */ - if (rcnt > btf) rcnt = btf; /* Clip it by btr if needed */ - rcnt = (*func)(dbuf + ((UINT)fp->fptr % SS(fs)), rcnt); /* Forward the file data */ - if (rcnt == 0) ABORT(fs, FR_INT_ERR); - } - - LEAVE_FF(fs, FR_OK); -} -#endif /* FF_USE_FORWARD */ - - - -#if FF_USE_MKFS && !FF_FS_READONLY -/*-----------------------------------------------------------------------*/ -/* Create an FAT/exFAT volume */ -/*-----------------------------------------------------------------------*/ - -FRESULT f_mkfs ( - const TCHAR* path, /* Logical drive number */ - BYTE opt, /* Format option */ - DWORD au, /* Size of allocation unit (cluster) [byte] */ - void* work, /* Pointer to working buffer (null: use heap memory) */ - UINT len /* Size of working buffer [byte] */ -) -{ - const UINT n_fats = 1; /* Number of FATs for FAT/FAT32 volume (1 or 2) */ - const UINT n_rootdir = 512; /* Number of root directory entries for FAT volume */ - static const WORD cst[] = {1, 4, 16, 64, 256, 512, 0}; /* Cluster size boundary for FAT volume (4Ks unit) */ - static const WORD cst32[] = {1, 2, 4, 8, 16, 32, 0}; /* Cluster size boundary for FAT32 volume (128Ks unit) */ - BYTE fmt, sys, *buf, *pte, pdrv, part; - WORD ss; /* Sector size */ - DWORD szb_buf, sz_buf, sz_blk, n_clst, pau, sect, nsect, n; - DWORD b_vol, b_fat, b_data; /* Base LBA for volume, fat, data */ - DWORD sz_vol, sz_rsv, sz_fat, sz_dir; /* Size for volume, fat, dir, data */ - UINT i; - int vol; - DSTATUS stat; -#if FF_USE_TRIM || FF_FS_EXFAT - DWORD tbl[3]; -#endif - - - /* Check mounted drive and clear work area */ - vol = get_ldnumber(&path); /* Get target logical drive */ - if (vol < 0) return FR_INVALID_DRIVE; - if (FatFs[vol]) FatFs[vol]->fs_type = 0; /* Clear the volume if mounted */ - pdrv = LD2PD(vol); /* Physical drive */ - part = LD2PT(vol); /* Partition (0:create as new, 1-4:get from partition table) */ - - /* Check physical drive status */ - stat = disk_initialize(pdrv); - if (stat & STA_NOINIT) return FR_NOT_READY; - if (stat & STA_PROTECT) return FR_WRITE_PROTECTED; - if (disk_ioctl(pdrv, GET_BLOCK_SIZE, &sz_blk) != RES_OK || !sz_blk || sz_blk > 32768 || (sz_blk & (sz_blk - 1))) sz_blk = 1; /* Erase block to align data area */ -#if FF_MAX_SS != FF_MIN_SS /* Get sector size of the medium if variable sector size cfg. */ - if (disk_ioctl(pdrv, GET_SECTOR_SIZE, &ss) != RES_OK) return FR_DISK_ERR; - if (ss > FF_MAX_SS || ss < FF_MIN_SS || (ss & (ss - 1))) return FR_DISK_ERR; -#else - ss = FF_MAX_SS; -#endif - if ((au != 0 && au < ss) || au > 0x1000000 || (au & (au - 1))) return FR_INVALID_PARAMETER; /* Check if au is valid */ - au /= ss; /* Cluster size in unit of sector */ - - /* Get working buffer */ -#if FF_USE_LFN == 3 - if (!work) { /* Use heap memory for working buffer */ - for (szb_buf = MAX_MALLOC, buf = 0; szb_buf >= ss && (buf = ff_memalloc(szb_buf)) == 0; szb_buf /= 2) ; - sz_buf = szb_buf / ss; /* Size of working buffer (sector) */ - } else -#endif - { - buf = (BYTE*)work; /* Working buffer */ - sz_buf = len / ss; /* Size of working buffer (sector) */ - szb_buf = sz_buf * ss; /* Size of working buffer (byte) */ - } - if (!buf || sz_buf == 0) return FR_NOT_ENOUGH_CORE; - - /* Determine where the volume to be located (b_vol, sz_vol) */ - if (FF_MULTI_PARTITION && part != 0) { - /* Get partition information from partition table in the MBR */ - if (disk_read(pdrv, buf, 0, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Load MBR */ - if (ld_word(buf + BS_55AA) != 0xAA55) LEAVE_MKFS(FR_MKFS_ABORTED); /* Check if MBR is valid */ - pte = buf + (MBR_Table + (part - 1) * SZ_PTE); - if (pte[PTE_System] == 0) LEAVE_MKFS(FR_MKFS_ABORTED); /* No partition? */ - b_vol = ld_dword(pte + PTE_StLba); /* Get volume start sector */ - sz_vol = ld_dword(pte + PTE_SizLba); /* Get volume size */ - } else { - /* Create a single-partition in this function */ - if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_vol) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); - b_vol = (opt & FM_SFD) ? 0 : 63; /* Volume start sector */ - if (sz_vol < b_vol) LEAVE_MKFS(FR_MKFS_ABORTED); - sz_vol -= b_vol; /* Volume size */ - } - if (sz_vol < 128) LEAVE_MKFS(FR_MKFS_ABORTED); /* Check if volume size is >=128s */ - - /* Pre-determine the FAT type */ - do { - if (FF_FS_EXFAT && (opt & FM_EXFAT)) { /* exFAT possible? */ - if ((opt & FM_ANY) == FM_EXFAT || sz_vol >= 0x4000000 || au > 128) { /* exFAT only, vol >= 64Ms or au > 128s ? */ - fmt = FS_EXFAT; break; - } - } - if (au > 128) LEAVE_MKFS(FR_INVALID_PARAMETER); /* Too large au for FAT/FAT32 */ - if (opt & FM_FAT32) { /* FAT32 possible? */ - if ((opt & FM_ANY) == FM_FAT32 || !(opt & FM_FAT)) { /* FAT32 only or no-FAT? */ - fmt = FS_FAT32; break; - } - } - if (!(opt & FM_FAT)) LEAVE_MKFS(FR_INVALID_PARAMETER); /* no-FAT? */ - fmt = FS_FAT16; - } while (0); - -#if FF_FS_EXFAT - if (fmt == FS_EXFAT) { /* Create an exFAT volume */ - DWORD szb_bit, szb_case, sum, nb, cl; - WCHAR ch, si; - UINT j, st; - BYTE b; - - if (sz_vol < 0x1000) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too small volume? */ -#if FF_USE_TRIM - tbl[0] = b_vol; tbl[1] = b_vol + sz_vol - 1; /* Inform the device the volume area may be erased */ - disk_ioctl(pdrv, CTRL_TRIM, tbl); -#endif - /* Determine FAT location, data location and number of clusters */ - if (au == 0) { /* au auto-selection */ - au = 8; - if (sz_vol >= 0x80000) au = 64; /* >= 512Ks */ - if (sz_vol >= 0x4000000) au = 256; /* >= 64Ms */ - } - b_fat = b_vol + 32; /* FAT start at offset 32 */ - sz_fat = ((sz_vol / au + 2) * 4 + ss - 1) / ss; /* Number of FAT sectors */ - b_data = (b_fat + sz_fat + sz_blk - 1) & ~(sz_blk - 1); /* Align data area to the erase block boundary */ - if (b_data >= sz_vol / 2) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too small volume? */ - n_clst = (sz_vol - (b_data - b_vol)) / au; /* Number of clusters */ - if (n_clst <16) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too few clusters? */ - if (n_clst > MAX_EXFAT) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too many clusters? */ - - szb_bit = (n_clst + 7) / 8; /* Size of allocation bitmap */ - tbl[0] = (szb_bit + au * ss - 1) / (au * ss); /* Number of allocation bitmap clusters */ - - /* Create a compressed up-case table */ - sect = b_data + au * tbl[0]; /* Table start sector */ - sum = 0; /* Table checksum to be stored in the 82 entry */ - st = 0; si = 0; i = 0; j = 0; szb_case = 0; - do { - switch (st) { - case 0: - ch = (WCHAR)ff_wtoupper(si); /* Get an up-case char */ - if (ch != si) { - si++; break; /* Store the up-case char if exist */ - } - for (j = 1; (WCHAR)(si + j) && (WCHAR)(si + j) == ff_wtoupper((WCHAR)(si + j)); j++) ; /* Get run length of no-case block */ - if (j >= 128) { - ch = 0xFFFF; st = 2; break; /* Compress the no-case block if run is >= 128 */ - } - st = 1; /* Do not compress short run */ - /* go to next case */ - case 1: - ch = si++; /* Fill the short run */ - if (--j == 0) st = 0; - break; - - default: - ch = (WCHAR)j; si += (WCHAR)j; /* Number of chars to skip */ - st = 0; - } - sum = xsum32(buf[i + 0] = (BYTE)ch, sum); /* Put it into the write buffer */ - sum = xsum32(buf[i + 1] = (BYTE)(ch >> 8), sum); - i += 2; szb_case += 2; - if (si == 0 || i == szb_buf) { /* Write buffered data when buffer full or end of process */ - n = (i + ss - 1) / ss; - if (disk_write(pdrv, buf, sect, n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); - sect += n; i = 0; - } - } while (si); - tbl[1] = (szb_case + au * ss - 1) / (au * ss); /* Number of up-case table clusters */ - tbl[2] = 1; /* Number of root dir clusters */ - - /* Initialize the allocation bitmap */ - sect = b_data; nsect = (szb_bit + ss - 1) / ss; /* Start of bitmap and number of sectors */ - nb = tbl[0] + tbl[1] + tbl[2]; /* Number of clusters in-use by system */ - do { - mem_set(buf, 0, szb_buf); - for (i = 0; nb >= 8 && i < szb_buf; buf[i++] = 0xFF, nb -= 8) ; - for (b = 1; nb != 0 && i < szb_buf; buf[i] |= b, b <<= 1, nb--) ; - n = (nsect > sz_buf) ? sz_buf : nsect; /* Write the buffered data */ - if (disk_write(pdrv, buf, sect, n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); - sect += n; nsect -= n; - } while (nsect); - - /* Initialize the FAT */ - sect = b_fat; nsect = sz_fat; /* Start of FAT and number of FAT sectors */ - j = nb = cl = 0; - do { - mem_set(buf, 0, szb_buf); i = 0; /* Clear work area and reset write index */ - if (cl == 0) { /* Set entry 0 and 1 */ - st_dword(buf + i, 0xFFFFFFF8); i += 4; cl++; - st_dword(buf + i, 0xFFFFFFFF); i += 4; cl++; - } - do { /* Create chains of bitmap, up-case and root dir */ - while (nb != 0 && i < szb_buf) { /* Create a chain */ - st_dword(buf + i, (nb > 1) ? cl + 1 : 0xFFFFFFFF); - i += 4; cl++; nb--; - } - if (nb == 0 && j < 3) nb = tbl[j++]; /* Next chain */ - } while (nb != 0 && i < szb_buf); - n = (nsect > sz_buf) ? sz_buf : nsect; /* Write the buffered data */ - if (disk_write(pdrv, buf, sect, n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); - sect += n; nsect -= n; - } while (nsect); - - /* Initialize the root directory */ - mem_set(buf, 0, szb_buf); - buf[SZDIRE * 0 + 0] = 0x83; /* 83 entry (volume label) */ - buf[SZDIRE * 1 + 0] = 0x81; /* 81 entry (allocation bitmap) */ - st_dword(buf + SZDIRE * 1 + 20, 2); /* cluster */ - st_dword(buf + SZDIRE * 1 + 24, szb_bit); /* size */ - buf[SZDIRE * 2 + 0] = 0x82; /* 82 entry (up-case table) */ - st_dword(buf + SZDIRE * 2 + 4, sum); /* sum */ - st_dword(buf + SZDIRE * 2 + 20, 2 + tbl[0]); /* cluster */ - st_dword(buf + SZDIRE * 2 + 24, szb_case); /* size */ - sect = b_data + au * (tbl[0] + tbl[1]); nsect = au; /* Start of the root directory and number of sectors */ - do { /* Fill root directory sectors */ - n = (nsect > sz_buf) ? sz_buf : nsect; - if (disk_write(pdrv, buf, sect, n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); - mem_set(buf, 0, ss); - sect += n; nsect -= n; - } while (nsect); - - /* Create two set of the exFAT VBR blocks */ - sect = b_vol; - for (n = 0; n < 2; n++) { - /* Main record (+0) */ - mem_set(buf, 0, ss); - mem_cpy(buf + BS_JmpBoot, "\xEB\x76\x90" "EXFAT ", 11); /* Boot jump code (x86), OEM name */ - st_dword(buf + BPB_VolOfsEx, b_vol); /* Volume offset in the physical drive [sector] */ - st_dword(buf + BPB_TotSecEx, sz_vol); /* Volume size [sector] */ - st_dword(buf + BPB_FatOfsEx, b_fat - b_vol); /* FAT offset [sector] */ - st_dword(buf + BPB_FatSzEx, sz_fat); /* FAT size [sector] */ - st_dword(buf + BPB_DataOfsEx, b_data - b_vol); /* Data offset [sector] */ - st_dword(buf + BPB_NumClusEx, n_clst); /* Number of clusters */ - st_dword(buf + BPB_RootClusEx, 2 + tbl[0] + tbl[1]); /* Root dir cluster # */ - st_dword(buf + BPB_VolIDEx, GET_FATTIME()); /* VSN */ - st_word(buf + BPB_FSVerEx, 0x100); /* Filesystem version (1.00) */ - for (buf[BPB_BytsPerSecEx] = 0, i = ss; i >>= 1; buf[BPB_BytsPerSecEx]++) ; /* Log2 of sector size [byte] */ - for (buf[BPB_SecPerClusEx] = 0, i = au; i >>= 1; buf[BPB_SecPerClusEx]++) ; /* Log2 of cluster size [sector] */ - buf[BPB_NumFATsEx] = 1; /* Number of FATs */ - buf[BPB_DrvNumEx] = 0x80; /* Drive number (for int13) */ - st_word(buf + BS_BootCodeEx, 0xFEEB); /* Boot code (x86) */ - st_word(buf + BS_55AA, 0xAA55); /* Signature (placed here regardless of sector size) */ - for (i = sum = 0; i < ss; i++) { /* VBR checksum */ - if (i != BPB_VolFlagEx && i != BPB_VolFlagEx + 1 && i != BPB_PercInUseEx) sum = xsum32(buf[i], sum); - } - if (disk_write(pdrv, buf, sect++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); - /* Extended bootstrap record (+1..+8) */ - mem_set(buf, 0, ss); - st_word(buf + ss - 2, 0xAA55); /* Signature (placed at end of sector) */ - for (j = 1; j < 9; j++) { - for (i = 0; i < ss; sum = xsum32(buf[i++], sum)) ; /* VBR checksum */ - if (disk_write(pdrv, buf, sect++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); - } - /* OEM/Reserved record (+9..+10) */ - mem_set(buf, 0, ss); - for ( ; j < 11; j++) { - for (i = 0; i < ss; sum = xsum32(buf[i++], sum)) ; /* VBR checksum */ - if (disk_write(pdrv, buf, sect++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); - } - /* Sum record (+11) */ - for (i = 0; i < ss; i += 4) st_dword(buf + i, sum); /* Fill with checksum value */ - if (disk_write(pdrv, buf, sect++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); - } - - } else -#endif /* FF_FS_EXFAT */ - { /* Create an FAT/FAT32 volume */ - do { - pau = au; - /* Pre-determine number of clusters and FAT sub-type */ - if (fmt == FS_FAT32) { /* FAT32 volume */ - if (pau == 0) { /* au auto-selection */ - n = sz_vol / 0x20000; /* Volume size in unit of 128KS */ - for (i = 0, pau = 1; cst32[i] && cst32[i] <= n; i++, pau <<= 1) ; /* Get from table */ - } - n_clst = sz_vol / pau; /* Number of clusters */ - sz_fat = (n_clst * 4 + 8 + ss - 1) / ss; /* FAT size [sector] */ - sz_rsv = 32; /* Number of reserved sectors */ - sz_dir = 0; /* No static directory */ - if (n_clst <= MAX_FAT16 || n_clst > MAX_FAT32) LEAVE_MKFS(FR_MKFS_ABORTED); - } else { /* FAT volume */ - if (pau == 0) { /* au auto-selection */ - n = sz_vol / 0x1000; /* Volume size in unit of 4KS */ - for (i = 0, pau = 1; cst[i] && cst[i] <= n; i++, pau <<= 1) ; /* Get from table */ - } - n_clst = sz_vol / pau; - if (n_clst > MAX_FAT12) { - n = n_clst * 2 + 4; /* FAT size [byte] */ - } else { - fmt = FS_FAT12; - n = (n_clst * 3 + 1) / 2 + 3; /* FAT size [byte] */ - } - sz_fat = (n + ss - 1) / ss; /* FAT size [sector] */ - sz_rsv = 1; /* Number of reserved sectors */ - sz_dir = (DWORD)n_rootdir * SZDIRE / ss; /* Rootdir size [sector] */ - } - b_fat = b_vol + sz_rsv; /* FAT base */ - b_data = b_fat + sz_fat * n_fats + sz_dir; /* Data base */ - - /* Align data base to erase block boundary (for flash memory media) */ - n = ((b_data + sz_blk - 1) & ~(sz_blk - 1)) - b_data; /* Next nearest erase block from current data base */ - if (fmt == FS_FAT32) { /* FAT32: Move FAT base */ - sz_rsv += n; b_fat += n; - } else { /* FAT: Expand FAT size */ - sz_fat += n / n_fats; - } - - /* Determine number of clusters and final check of validity of the FAT sub-type */ - if (sz_vol < b_data + pau * 16 - b_vol) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too small volume */ - n_clst = (sz_vol - sz_rsv - sz_fat * n_fats - sz_dir) / pau; - if (fmt == FS_FAT32) { - if (n_clst <= MAX_FAT16) { /* Too few clusters for FAT32 */ - if (au == 0 && (au = pau / 2) != 0) continue; /* Adjust cluster size and retry */ - LEAVE_MKFS(FR_MKFS_ABORTED); - } - } - if (fmt == FS_FAT16) { - if (n_clst > MAX_FAT16) { /* Too many clusters for FAT16 */ - if (au == 0 && (pau * 2) <= 64) { - au = pau * 2; continue; /* Adjust cluster size and retry */ - } - if ((opt & FM_FAT32)) { - fmt = FS_FAT32; continue; /* Switch type to FAT32 and retry */ - } - if (au == 0 && (au = pau * 2) <= 128) continue; /* Adjust cluster size and retry */ - LEAVE_MKFS(FR_MKFS_ABORTED); - } - if (n_clst <= MAX_FAT12) { /* Too few clusters for FAT16 */ - if (au == 0 && (au = pau * 2) <= 128) continue; /* Adjust cluster size and retry */ - LEAVE_MKFS(FR_MKFS_ABORTED); - } - } - if (fmt == FS_FAT12 && n_clst > MAX_FAT12) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too many clusters for FAT12 */ - - /* Ok, it is the valid cluster configuration */ - break; - } while (1); - -#if FF_USE_TRIM - tbl[0] = b_vol; tbl[1] = b_vol + sz_vol - 1; /* Inform the device the volume area can be erased */ - disk_ioctl(pdrv, CTRL_TRIM, tbl); -#endif - /* Create FAT VBR */ - mem_set(buf, 0, ss); - mem_cpy(buf + BS_JmpBoot, "\xEB\xFE\x90" "MSDOS5.0", 11);/* Boot jump code (x86), OEM name */ - st_word(buf + BPB_BytsPerSec, ss); /* Sector size [byte] */ - buf[BPB_SecPerClus] = (BYTE)pau; /* Cluster size [sector] */ - st_word(buf + BPB_RsvdSecCnt, (WORD)sz_rsv); /* Size of reserved area */ - buf[BPB_NumFATs] = (BYTE)n_fats; /* Number of FATs */ - st_word(buf + BPB_RootEntCnt, (WORD)((fmt == FS_FAT32) ? 0 : n_rootdir)); /* Number of root directory entries */ - if (sz_vol < 0x10000) { - st_word(buf + BPB_TotSec16, (WORD)sz_vol); /* Volume size in 16-bit LBA */ - } else { - st_dword(buf + BPB_TotSec32, sz_vol); /* Volume size in 32-bit LBA */ - } - buf[BPB_Media] = 0xF8; /* Media descriptor byte */ - st_word(buf + BPB_SecPerTrk, 63); /* Number of sectors per track (for int13) */ - st_word(buf + BPB_NumHeads, 255); /* Number of heads (for int13) */ - st_dword(buf + BPB_HiddSec, b_vol); /* Volume offset in the physical drive [sector] */ - if (fmt == FS_FAT32) { - st_dword(buf + BS_VolID32, GET_FATTIME()); /* VSN */ - st_dword(buf + BPB_FATSz32, sz_fat); /* FAT size [sector] */ - st_dword(buf + BPB_RootClus32, 2); /* Root directory cluster # (2) */ - st_word(buf + BPB_FSInfo32, 1); /* Offset of FSINFO sector (VBR + 1) */ - st_word(buf + BPB_BkBootSec32, 6); /* Offset of backup VBR (VBR + 6) */ - buf[BS_DrvNum32] = 0x80; /* Drive number (for int13) */ - buf[BS_BootSig32] = 0x29; /* Extended boot signature */ - mem_cpy(buf + BS_VolLab32, "NO NAME " "FAT32 ", 19); /* Volume label, FAT signature */ - } else { - st_dword(buf + BS_VolID, GET_FATTIME()); /* VSN */ - st_word(buf + BPB_FATSz16, (WORD)sz_fat); /* FAT size [sector] */ - buf[BS_DrvNum] = 0x80; /* Drive number (for int13) */ - buf[BS_BootSig] = 0x29; /* Extended boot signature */ - mem_cpy(buf + BS_VolLab, "NO NAME " "FAT ", 19); /* Volume label, FAT signature */ - } - st_word(buf + BS_55AA, 0xAA55); /* Signature (offset is fixed here regardless of sector size) */ - if (disk_write(pdrv, buf, b_vol, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Write it to the VBR sector */ - - /* Create FSINFO record if needed */ - if (fmt == FS_FAT32) { - disk_write(pdrv, buf, b_vol + 6, 1); /* Write backup VBR (VBR + 6) */ - mem_set(buf, 0, ss); - st_dword(buf + FSI_LeadSig, 0x41615252); - st_dword(buf + FSI_StrucSig, 0x61417272); - st_dword(buf + FSI_Free_Count, n_clst - 1); /* Number of free clusters */ - st_dword(buf + FSI_Nxt_Free, 2); /* Last allocated cluster# */ - st_word(buf + BS_55AA, 0xAA55); - disk_write(pdrv, buf, b_vol + 7, 1); /* Write backup FSINFO (VBR + 7) */ - disk_write(pdrv, buf, b_vol + 1, 1); /* Write original FSINFO (VBR + 1) */ - } - - /* Initialize FAT area */ - mem_set(buf, 0, (UINT)szb_buf); - sect = b_fat; /* FAT start sector */ - for (i = 0; i < n_fats; i++) { /* Initialize FATs each */ - if (fmt == FS_FAT32) { - st_dword(buf + 0, 0xFFFFFFF8); /* Entry 0 */ - st_dword(buf + 4, 0xFFFFFFFF); /* Entry 1 */ - st_dword(buf + 8, 0x0FFFFFFF); /* Entry 2 (root directory) */ - } else { - st_dword(buf + 0, (fmt == FS_FAT12) ? 0xFFFFF8 : 0xFFFFFFF8); /* Entry 0 and 1 */ - } - nsect = sz_fat; /* Number of FAT sectors */ - do { /* Fill FAT sectors */ - n = (nsect > sz_buf) ? sz_buf : nsect; - if (disk_write(pdrv, buf, sect, (UINT)n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); - mem_set(buf, 0, ss); - sect += n; nsect -= n; - } while (nsect); - } - - /* Initialize root directory (fill with zero) */ - nsect = (fmt == FS_FAT32) ? pau : sz_dir; /* Number of root directory sectors */ - do { - n = (nsect > sz_buf) ? sz_buf : nsect; - if (disk_write(pdrv, buf, sect, (UINT)n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); - sect += n; nsect -= n; - } while (nsect); - } - - /* Determine system ID in the partition table */ - if (FF_FS_EXFAT && fmt == FS_EXFAT) { - sys = 0x07; /* HPFS/NTFS/exFAT */ - } else { - if (fmt == FS_FAT32) { - sys = 0x0C; /* FAT32X */ - } else { - if (sz_vol >= 0x10000) { - sys = 0x06; /* FAT12/16 (large) */ - } else { - sys = (fmt == FS_FAT16) ? 0x04 : 0x01; /* FAT16 : FAT12 */ - } - } - } - - /* Update partition information */ - if (FF_MULTI_PARTITION && part != 0) { /* Created in the existing partition */ - /* Update system ID in the partition table */ - if (disk_read(pdrv, buf, 0, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Read the MBR */ - buf[MBR_Table + (part - 1) * SZ_PTE + PTE_System] = sys; /* Set system ID */ - if (disk_write(pdrv, buf, 0, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Write it back to the MBR */ - } else { /* Created as a new single partition */ - if (!(opt & FM_SFD)) { /* Create partition table if in FDISK format */ - mem_set(buf, 0, ss); - st_word(buf + BS_55AA, 0xAA55); /* MBR signature */ - pte = buf + MBR_Table; /* Create partition table for single partition in the drive */ - pte[PTE_Boot] = 0; /* Boot indicator */ - pte[PTE_StHead] = 1; /* Start head */ - pte[PTE_StSec] = 1; /* Start sector */ - pte[PTE_StCyl] = 0; /* Start cylinder */ - pte[PTE_System] = sys; /* System type */ - n = (b_vol + sz_vol) / (63 * 255); /* (End CHS may be invalid) */ - pte[PTE_EdHead] = 254; /* End head */ - pte[PTE_EdSec] = (BYTE)(((n >> 2) & 0xC0) | 63); /* End sector */ - pte[PTE_EdCyl] = (BYTE)n; /* End cylinder */ - st_dword(pte + PTE_StLba, b_vol); /* Start offset in LBA */ - st_dword(pte + PTE_SizLba, sz_vol); /* Size in sectors */ - if (disk_write(pdrv, buf, 0, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Write it to the MBR */ - } - } - - if (disk_ioctl(pdrv, CTRL_SYNC, 0) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); - - LEAVE_MKFS(FR_OK); -} - - - -#if FF_MULTI_PARTITION -/*-----------------------------------------------------------------------*/ -/* Create Partition Table on the Physical Drive */ -/*-----------------------------------------------------------------------*/ - -FRESULT f_fdisk ( - BYTE pdrv, /* Physical drive number */ - const DWORD* szt, /* Pointer to the size table for each partitions */ - void* work /* Pointer to the working buffer (null: use heap memory) */ -) -{ - UINT i, n, sz_cyl, tot_cyl, b_cyl, e_cyl, p_cyl; - BYTE s_hd, e_hd, *p, *buf = (BYTE*)work; - DSTATUS stat; - DWORD sz_disk, sz_part, s_part; - FRESULT res; - - - stat = disk_initialize(pdrv); - if (stat & STA_NOINIT) return FR_NOT_READY; - if (stat & STA_PROTECT) return FR_WRITE_PROTECTED; - if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_disk)) return FR_DISK_ERR; - - buf = (BYTE*)work; -#if FF_USE_LFN == 3 - if (!buf) buf = ff_memalloc(FF_MAX_SS); /* Use heap memory for working buffer */ -#endif - if (!buf) return FR_NOT_ENOUGH_CORE; - - /* Determine the CHS without any consideration of the drive geometry */ - for (n = 16; n < 256 && sz_disk / n / 63 > 1024; n *= 2) ; - if (n == 256) n--; - e_hd = (BYTE)(n - 1); - sz_cyl = 63 * n; - tot_cyl = sz_disk / sz_cyl; - - /* Create partition table */ - mem_set(buf, 0, FF_MAX_SS); - p = buf + MBR_Table; b_cyl = 0; - for (i = 0; i < 4; i++, p += SZ_PTE) { - p_cyl = (szt[i] <= 100U) ? (DWORD)tot_cyl * szt[i] / 100 : szt[i] / sz_cyl; /* Number of cylinders */ - if (p_cyl == 0) continue; - s_part = (DWORD)sz_cyl * b_cyl; - sz_part = (DWORD)sz_cyl * p_cyl; - if (i == 0) { /* Exclude first track of cylinder 0 */ - s_hd = 1; - s_part += 63; sz_part -= 63; - } else { - s_hd = 0; - } - e_cyl = b_cyl + p_cyl - 1; /* End cylinder */ - if (e_cyl >= tot_cyl) LEAVE_MKFS(FR_INVALID_PARAMETER); - - /* Set partition table */ - p[1] = s_hd; /* Start head */ - p[2] = (BYTE)(((b_cyl >> 2) & 0xC0) | 1); /* Start sector */ - p[3] = (BYTE)b_cyl; /* Start cylinder */ - p[4] = 0x07; /* System type (temporary setting) */ - p[5] = e_hd; /* End head */ - p[6] = (BYTE)(((e_cyl >> 2) & 0xC0) | 63); /* End sector */ - p[7] = (BYTE)e_cyl; /* End cylinder */ - st_dword(p + 8, s_part); /* Start sector in LBA */ - st_dword(p + 12, sz_part); /* Number of sectors */ - - /* Next partition */ - b_cyl += p_cyl; - } - st_word(p, 0xAA55); /* MBR signature (always at offset 510) */ - - /* Write it to the MBR */ - res = (disk_write(pdrv, buf, 0, 1) == RES_OK && disk_ioctl(pdrv, CTRL_SYNC, 0) == RES_OK) ? FR_OK : FR_DISK_ERR; - LEAVE_MKFS(res); -} - -#endif /* FF_MULTI_PARTITION */ -#endif /* FF_USE_MKFS && !FF_FS_READONLY */ - - - - -#if FF_USE_STRFUNC -#if FF_USE_LFN && FF_LFN_UNICODE && (FF_STRF_ENCODE < 0 || FF_STRF_ENCODE > 3) -#error Wrong FF_STRF_ENCODE setting -#endif -/*-----------------------------------------------------------------------*/ -/* Get a String from the File */ -/*-----------------------------------------------------------------------*/ - -TCHAR* f_gets ( - TCHAR* buff, /* Pointer to the string buffer to read */ - int len, /* Size of string buffer (items) */ - FIL* fp /* Pointer to the file object */ -) -{ - int nc = 0; - TCHAR *p = buff; - BYTE s[4]; - UINT rc; - DWORD dc; -#if FF_USE_LFN && FF_LFN_UNICODE && FF_STRF_ENCODE <= 2 - WCHAR wc; -#endif -#if FF_USE_LFN && FF_LFN_UNICODE && FF_STRF_ENCODE == 3 - UINT ct; -#endif - -#if FF_USE_LFN && FF_LFN_UNICODE /* With code conversion (Unicode API) */ - /* Make a room for the character and terminator */ - if (FF_LFN_UNICODE == 1) len -= (FF_STRF_ENCODE == 0) ? 1 : 2; - if (FF_LFN_UNICODE == 2) len -= (FF_STRF_ENCODE == 0) ? 3 : 4; - if (FF_LFN_UNICODE == 3) len -= 1; - while (nc < len) { -#if FF_STRF_ENCODE == 0 /* Read a character in ANSI/OEM */ - f_read(fp, s, 1, &rc); - if (rc != 1) break; - wc = s[0]; - if (dbc_1st((BYTE)wc)) { - f_read(fp, s, 1, &rc); - if (rc != 1 || !dbc_2nd(s[0])) continue; - wc = wc << 8 | s[0]; - } - dc = ff_oem2uni(wc, CODEPAGE); - if (dc == 0) continue; -#elif FF_STRF_ENCODE == 1 || FF_STRF_ENCODE == 2 /* Read a character in UTF-16LE/BE */ - f_read(fp, s, 2, &rc); - if (rc != 2) break; - dc = (FF_STRF_ENCODE == 1) ? ld_word(s) : s[0] << 8 | s[1]; - if (IsSurrogateL(dc)) continue; - if (IsSurrogateH(dc)) { - f_read(fp, s, 2, &rc); - if (rc != 2) break; - wc = (FF_STRF_ENCODE == 1) ? ld_word(s) : s[0] << 8 | s[1]; - if (!IsSurrogateL(wc)) continue; - dc = ((dc & 0x3FF) + 0x40) << 10 | (wc & 0x3FF); - } -#else /* Read a character in UTF-8 */ - f_read(fp, s, 1, &rc); - if (rc != 1) break; - dc = s[0]; - if (dc >= 0x80) { /* Multi-byte character? */ - ct = 0; - if ((dc & 0xE0) == 0xC0) { dc &= 0x1F; ct = 1; } /* 2-byte? */ - if ((dc & 0xF0) == 0xE0) { dc &= 0x0F; ct = 2; } /* 3-byte? */ - if ((dc & 0xF8) == 0xF0) { dc &= 0x07; ct = 3; } /* 4-byte? */ - if (ct == 0) continue; - f_read(fp, s, ct, &rc); /* Get trailing bytes */ - if (rc != ct) break; - rc = 0; - do { /* Merge trailing bytes */ - if ((s[rc] & 0xC0) != 0x80) break; - dc = dc << 6 | (s[rc] & 0x3F); - } while (++rc < ct); - if (rc != ct || dc < 0x80 || IsSurrogate(dc) || dc >= 0x110000) continue; /* Wrong encoding? */ - } -#endif - if (FF_USE_STRFUNC == 2 && dc == '\r') continue; /* Strip \r off if needed */ -#if FF_LFN_UNICODE == 1 || FF_LFN_UNICODE == 3 /* Output it in UTF-16/32 encoding */ - if (FF_LFN_UNICODE == 1 && dc >= 0x10000) { /* Out of BMP at UTF-16? */ - *p++ = (TCHAR)(0xD800 | ((dc >> 10) - 0x40)); nc++; /* Make and output high surrogate */ - dc = 0xDC00 | (dc & 0x3FF); /* Make low surrogate */ - } - *p++ = (TCHAR)dc; nc++; - if (dc == '\n') break; /* End of line? */ -#elif FF_LFN_UNICODE == 2 /* Output it in UTF-8 encoding */ - if (dc < 0x80) { /* 1-byte */ - *p++ = (TCHAR)dc; - nc++; - if (dc == '\n') break; /* End of line? */ - } else { - if (dc < 0x800) { /* 2-byte */ - *p++ = (TCHAR)(0xC0 | (dc >> 6 & 0x1F)); - *p++ = (TCHAR)(0x80 | (dc >> 0 & 0x3F)); - nc += 2; - } else { - if (dc < 0x10000) { /* 3-byte */ - *p++ = (TCHAR)(0xE0 | (dc >> 12 & 0x0F)); - *p++ = (TCHAR)(0x80 | (dc >> 6 & 0x3F)); - *p++ = (TCHAR)(0x80 | (dc >> 0 & 0x3F)); - nc += 3; - } else { /* 4-byte */ - *p++ = (TCHAR)(0xF0 | (dc >> 18 & 0x07)); - *p++ = (TCHAR)(0x80 | (dc >> 12 & 0x3F)); - *p++ = (TCHAR)(0x80 | (dc >> 6 & 0x3F)); - *p++ = (TCHAR)(0x80 | (dc >> 0 & 0x3F)); - nc += 4; - } - } - } -#endif - } - -#else /* Byte-by-byte without any conversion (ANSI/OEM API) */ - len -= 1; /* Make a room for the terminator */ - while (nc < len) { - f_read(fp, s, 1, &rc); - if (rc != 1) break; - dc = s[0]; - if (FF_USE_STRFUNC == 2 && dc == '\r') continue; - *p++ = (TCHAR)dc; nc++; - if (dc == '\n') break; - } -#endif - - *p = 0; /* Terminate the string */ - return nc ? buff : 0; /* When no data read due to EOF or error, return with error. */ -} - - - - -#if !FF_FS_READONLY -#include -/*-----------------------------------------------------------------------*/ -/* Put a Character to the File */ -/*-----------------------------------------------------------------------*/ - -typedef struct { /* Putchar output buffer and work area */ - FIL *fp; /* Ptr to the writing file */ - int idx, nchr; /* Write index of buf[] (-1:error), number of encoding units written */ -#if FF_USE_LFN && FF_LFN_UNICODE == 1 - WCHAR hs; -#elif FF_USE_LFN && FF_LFN_UNICODE == 2 - BYTE bs[4]; - UINT wi, ct; -#endif - BYTE buf[64]; /* Write buffer */ -} putbuff; - - -static -void putc_bfd ( /* Buffered write with code conversion */ - putbuff* pb, - TCHAR c -) -{ - UINT n; - int i, nc; -#if FF_USE_LFN && FF_LFN_UNICODE - WCHAR hs, wc; -#if FF_LFN_UNICODE == 2 - DWORD dc; - TCHAR *tp; -#endif -#endif - - if (FF_USE_STRFUNC == 2 && c == '\n') { /* LF -> CRLF conversion */ - putc_bfd(pb, '\r'); - } - - i = pb->idx; /* Write index of pb->buf[] */ - if (i < 0) return; - nc = pb->nchr; /* Write unit counter */ - -#if FF_USE_LFN && FF_LFN_UNICODE -#if FF_LFN_UNICODE == 1 /* UTF-16 input */ - if (IsSurrogateH(c)) { - pb->hs = c; return; - } - hs = pb->hs; pb->hs = 0; - if (hs != 0) { - if (!IsSurrogateL(c)) hs = 0; - } else { - if (IsSurrogateL(c)) return; - } - wc = c; -#elif FF_LFN_UNICODE == 2 /* UTF-8 input */ - for (;;) { - if (pb->ct == 0) { /* Out of multi-byte sequence? */ - pb->bs[pb->wi = 0] = (BYTE)c; /* Save 1st byte */ - if ((BYTE)c < 0x80) break; /* 1-byte? */ - if (((BYTE)c & 0xE0) == 0xC0) pb->ct = 1; /* 2-byte? */ - if (((BYTE)c & 0xF0) == 0xE0) pb->ct = 2; /* 3-byte? */ - if (((BYTE)c & 0xF1) == 0xF0) pb->ct = 3; /* 4-byte? */ - return; - } else { /* In the multi-byte sequence */ - if (((BYTE)c & 0xC0) != 0x80) { /* Broken sequence? */ - pb->ct = 0; continue; - } - pb->bs[++pb->wi] = (BYTE)c; /* Save the trailing byte */ - if (--pb->ct == 0) break; /* End of multi-byte sequence? */ - return; - } - } - tp = (TCHAR*)pb->bs; - dc = tchar2uni(&tp); /* UTF-8 ==> UTF-16 */ - if (dc == 0xFFFFFFFF) return; - wc = (WCHAR)dc; - hs = (WCHAR)(dc >> 16); -#elif FF_LFN_UNICODE == 3 /* UTF-32 input */ - if (IsSurrogate(c) || c >= 0x110000) return; - if (c >= 0x10000) { - hs = (WCHAR)(0xD800 | ((c >> 10) - 0x40)); /* Make high surrogate */ - wc = 0xDC00 | (c & 0x3FF); /* Make low surrogate */ - } else { - hs = 0; - wc = (WCHAR)c; - } -#endif - -#if FF_STRF_ENCODE == 1 /* Write a character in UTF-16LE */ - if (hs != 0) { - st_word(&pb->buf[i], hs); - i += 2; - nc++; - } - st_word(&pb->buf[i], wc); - i += 2; -#elif FF_STRF_ENCODE == 2 /* Write a character in UTF-16BE */ - if (hs != 0) { - pb->buf[i++] = (BYTE)(hs >> 8); - pb->buf[i++] = (BYTE)hs; - nc++; - } - pb->buf[i++] = (BYTE)(wc >> 8); - pb->buf[i++] = (BYTE)wc; -#elif FF_STRF_ENCODE == 3 /* Write it in UTF-8 */ - if (hs != 0) { /* 4-byte */ - nc += 3; - hs = (hs & 0x3FF) + 0x40; - pb->buf[i++] = (BYTE)(0xF0 | hs >> 8); - pb->buf[i++] = (BYTE)(0x80 | (hs >> 2 & 0x3F)); - pb->buf[i++] = (BYTE)(0x80 | (hs & 3) << 4 | (wc >> 6 & 0x0F)); - pb->buf[i++] = (BYTE)(0x80 | (wc & 0x3F)); - } else { - if (wc < 0x80) { /* 1-byte */ - pb->buf[i++] = (BYTE)wc; - } else { - if (wc < 0x800) { /* 2-byte */ - nc += 1; - pb->buf[i++] = (BYTE)(0xC0 | wc >> 6); - } else { /* 3-byte */ - nc += 2; - pb->buf[i++] = (BYTE)(0xE0 | wc >> 12); - pb->buf[i++] = (BYTE)(0x80 | (wc >> 6 & 0x3F)); - } - pb->buf[i++] = (BYTE)(0x80 | (wc & 0x3F)); - } - } -#else /* Write it in ANSI/OEM */ - if (hs != 0) return; - wc = ff_uni2oem(wc, CODEPAGE); /* UTF-16 ==> ANSI/OEM */ - if (wc == 0) return;; - if (wc >= 0x100) { - pb->buf[i++] = (BYTE)(wc >> 8); nc++; - } - pb->buf[i++] = (BYTE)wc; -#endif - -#else /* ANSI/OEM input (without re-encode) */ - pb->buf[i++] = (BYTE)c; -#endif - - if (i >= (int)(sizeof pb->buf) - 4) { /* Write buffered characters to the file */ - f_write(pb->fp, pb->buf, (UINT)i, &n); - i = (n == (UINT)i) ? 0 : -1; - } - pb->idx = i; - pb->nchr = nc + 1; -} - - -static -int putc_flush ( /* Flush left characters in the buffer */ - putbuff* pb -) -{ - UINT nw; - - if ( pb->idx >= 0 /* Flush buffered characters to the file */ - && f_write(pb->fp, pb->buf, (UINT)pb->idx, &nw) == FR_OK - && (UINT)pb->idx == nw) return pb->nchr; - return EOF; -} - - -static -void putc_init ( /* Initialize write buffer */ - putbuff* pb, - FIL* fp -) -{ - mem_set(pb, 0, sizeof (putbuff)); - pb->fp = fp; -} - - - -int f_putc ( - TCHAR c, /* A character to be output */ - FIL* fp /* Pointer to the file object */ -) -{ - putbuff pb; - - - putc_init(&pb, fp); - putc_bfd(&pb, c); /* Put the character */ - return putc_flush(&pb); -} - - - - -/*-----------------------------------------------------------------------*/ -/* Put a String to the File */ -/*-----------------------------------------------------------------------*/ - -int f_puts ( - const TCHAR* str, /* Pointer to the string to be output */ - FIL* fp /* Pointer to the file object */ -) -{ - putbuff pb; - - - putc_init(&pb, fp); - while (*str) putc_bfd(&pb, *str++); /* Put the string */ - return putc_flush(&pb); -} - - - - -/*-----------------------------------------------------------------------*/ -/* Put a Formatted String to the File */ -/*-----------------------------------------------------------------------*/ - -int f_printf ( - FIL* fp, /* Pointer to the file object */ - const TCHAR* fmt, /* Pointer to the format string */ - ... /* Optional arguments... */ -) -{ - va_list arp; - putbuff pb; - BYTE f, r; - UINT i, j, w; - DWORD v; - TCHAR c, d, str[32], *p; - - - putc_init(&pb, fp); - - va_start(arp, fmt); - - for (;;) { - c = *fmt++; - if (c == 0) break; /* End of string */ - if (c != '%') { /* Non escape character */ - putc_bfd(&pb, c); - continue; - } - w = f = 0; - c = *fmt++; - if (c == '0') { /* Flag: '0' padding */ - f = 1; c = *fmt++; - } else { - if (c == '-') { /* Flag: left justified */ - f = 2; c = *fmt++; - } - } - if (c == '*') { /* Minimum width by argument */ - w = va_arg(arp, int); - c = *fmt++; - } else { - while (IsDigit(c)) { /* Minimum width */ - w = w * 10 + c - '0'; - c = *fmt++; - } - } - if (c == 'l' || c == 'L') { /* Type prefix: Size is long int */ - f |= 4; c = *fmt++; - } - if (c == 0) break; - d = c; - if (IsLower(d)) d -= 0x20; - switch (d) { /* Atgument type is... */ - case 'S' : /* String */ - p = va_arg(arp, TCHAR*); - for (j = 0; p[j]; j++) ; - if (!(f & 2)) { /* Right padded */ - while (j++ < w) putc_bfd(&pb, ' ') ; - } - while (*p) putc_bfd(&pb, *p++) ; /* String body */ - while (j++ < w) putc_bfd(&pb, ' ') ; /* Left padded */ - continue; - - case 'C' : /* Character */ - putc_bfd(&pb, (TCHAR)va_arg(arp, int)); continue; - - case 'B' : /* Unsigned binary */ - r = 2; break; - - case 'O' : /* Unsigned octal */ - r = 8; break; - - case 'D' : /* Signed decimal */ - case 'U' : /* Unsigned decimal */ - r = 10; break; - - case 'X' : /* Unsigned hexdecimal */ - r = 16; break; - - default: /* Unknown type (pass-through) */ - putc_bfd(&pb, c); continue; - } - - /* Get an argument and put it in numeral */ - v = (f & 4) ? (DWORD)va_arg(arp, long) : ((d == 'D') ? (DWORD)(long)va_arg(arp, int) : (DWORD)va_arg(arp, unsigned int)); - if (d == 'D' && (v & 0x80000000)) { - v = 0 - v; - f |= 8; - } - i = 0; - do { - d = (TCHAR)(v % r); v /= r; - if (d > 9) d += (c == 'x') ? 0x27 : 0x07; - str[i++] = d + '0'; - } while (v && i < sizeof str / sizeof *str); - if (f & 8) str[i++] = '-'; - j = i; d = (f & 1) ? '0' : ' '; - if (!(f & 2)) { - while (j++ < w) putc_bfd(&pb, d); /* Right pad */ - } - do { - putc_bfd(&pb, str[--i]); /* Number body */ - } while (i); - while (j++ < w) putc_bfd(&pb, d); /* Left pad */ - } - - va_end(arp); - - return putc_flush(&pb); -} - -#endif /* !FF_FS_READONLY */ -#endif /* FF_USE_STRFUNC */ - - - -#if FF_CODE_PAGE == 0 -/*-----------------------------------------------------------------------*/ -/* Set Active Codepage for the Path Name */ -/*-----------------------------------------------------------------------*/ - -FRESULT f_setcp ( - WORD cp /* Value to be set as active code page */ -) -{ - static const WORD validcp[] = { 437, 720, 737, 771, 775, 850, 852, 857, 860, 861, 862, 863, 864, 865, 866, 869, 932, 936, 949, 950, 0}; - static const BYTE* const tables[] = {Ct437, Ct720, Ct737, Ct771, Ct775, Ct850, Ct852, Ct857, Ct860, Ct861, Ct862, Ct863, Ct864, Ct865, Ct866, Ct869, Dc932, Dc936, Dc949, Dc950, 0}; - UINT i; - - - for (i = 0; validcp[i] != 0 && validcp[i] != cp; i++) ; /* Find the code page */ - if (validcp[i] != cp) return FR_INVALID_PARAMETER; /* Not found? */ - - CodePage = cp; - if (cp >= 900) { /* DBCS */ - ExCvt = 0; - DbcTbl = tables[i]; - } else { /* SBCS */ - ExCvt = tables[i]; - DbcTbl = 0; - } - return FR_OK; -} -#endif /* FF_CODE_PAGE == 0 */ - diff --git a/third-party/fatfs-0.1.3/ff.h b/third-party/fatfs-0.1.3/ff.h deleted file mode 100644 index de226874..00000000 --- a/third-party/fatfs-0.1.3/ff.h +++ /dev/null @@ -1,380 +0,0 @@ -/*----------------------------------------------------------------------------/ -/ FatFs - Generic FAT Filesystem module R0.13b / -/-----------------------------------------------------------------------------/ -/ -/ Copyright (C) 2018, ChaN, all right reserved. -/ -/ FatFs module is an open source software. Redistribution and use of FatFs in -/ source and binary forms, with or without modification, are permitted provided -/ that the following condition is met: - -/ 1. Redistributions of source code must retain the above copyright notice, -/ this condition and the following disclaimer. -/ -/ This software is provided by the copyright holder and contributors "AS IS" -/ and any warranties related to this software are DISCLAIMED. -/ The copyright owner or contributors be NOT LIABLE for any damages caused -/ by use of this software. -/ -/----------------------------------------------------------------------------*/ - - -#ifndef FF_DEFINED -#define FF_DEFINED 63463 /* Revision ID */ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "integer.h" /* Basic integer types */ -#include "ffconf.h" /* FatFs configuration options */ - -#if FF_DEFINED != FFCONF_DEF -#error Wrong configuration file (ffconf.h). -#endif - - - -/* Definitions of volume management */ - -#if FF_MULTI_PARTITION /* Multiple partition configuration */ -typedef struct { - BYTE pd; /* Physical drive number */ - BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */ -} PARTITION; -extern PARTITION VolToPart[]; /* Volume - Partition resolution table */ -#endif - -#if FF_STR_VOLUME_ID -#ifndef FF_VOLUME_STRS -extern const char* VolumeStr[FF_VOLUMES]; /* User defied volume ID */ -#endif -#endif - - - -/* Type of path name strings on FatFs API */ - -#ifndef _INC_TCHAR_ -#define _INC_TCHAR_ - -#if FF_USE_LFN && FF_LFN_UNICODE == 1 /* Unicode in UTF-16 encoding */ -typedef WCHAR TCHAR; -#define _T(x) L ## x -#define _TEXT(x) L ## x -#elif FF_USE_LFN && FF_LFN_UNICODE == 2 /* Unicode in UTF-8 encoding */ -typedef char TCHAR; -#define _T(x) u8 ## x -#define _TEXT(x) u8 ## x -#elif FF_USE_LFN && FF_LFN_UNICODE == 3 /* Unicode in UTF-32 encoding */ -typedef DWORD TCHAR; -#define _T(x) U ## x -#define _TEXT(x) U ## x -#elif FF_USE_LFN && (FF_LFN_UNICODE < 0 || FF_LFN_UNICODE > 3) -#error Wrong FF_LFN_UNICODE setting -#else /* ANSI/OEM code in SBCS/DBCS */ -typedef char TCHAR; -#define _T(x) x -#define _TEXT(x) x -#endif - -#endif - - - -/* Type of file size variables */ - -#if FF_FS_EXFAT -typedef QWORD FSIZE_t; -#else -typedef DWORD FSIZE_t; -#endif - - - -/* Filesystem object structure (FATFS) */ - -typedef struct { - BYTE fs_type; /* Filesystem type (0:N/A) */ - BYTE pdrv; /* Physical drive number */ - BYTE n_fats; /* Number of FATs (1 or 2) */ - BYTE wflag; /* win[] flag (b0:dirty) */ - BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */ - WORD id; /* Volume mount ID */ - WORD n_rootdir; /* Number of root directory entries (FAT12/16) */ - WORD csize; /* Cluster size [sectors] */ -#if FF_MAX_SS != FF_MIN_SS - WORD ssize; /* Sector size (512, 1024, 2048 or 4096) */ -#endif -#if FF_USE_LFN - WCHAR* lfnbuf; /* LFN working buffer */ -#endif -#if FF_FS_EXFAT - BYTE* dirbuf; /* Directory entry block scratchpad buffer for exFAT */ -#endif -#if FF_FS_REENTRANT - FF_SYNC_t sobj; /* Identifier of sync object */ -#endif -#if !FF_FS_READONLY - DWORD last_clst; /* Last allocated cluster */ - DWORD free_clst; /* Number of free clusters */ -#endif -#if FF_FS_RPATH - DWORD cdir; /* Current directory start cluster (0:root) */ -#if FF_FS_EXFAT - DWORD cdc_scl; /* Containing directory start cluster (invalid when cdir is 0) */ - DWORD cdc_size; /* b31-b8:Size of containing directory, b7-b0: Chain status */ - DWORD cdc_ofs; /* Offset in the containing directory (invalid when cdir is 0) */ -#endif -#endif - DWORD n_fatent; /* Number of FAT entries (number of clusters + 2) */ - DWORD fsize; /* Size of an FAT [sectors] */ - DWORD volbase; /* Volume base sector */ - DWORD fatbase; /* FAT base sector */ - DWORD dirbase; /* Root directory base sector/cluster */ - DWORD database; /* Data base sector */ - DWORD winsect; /* Current sector appearing in the win[] */ - BYTE win[FF_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */ -} FATFS; - - - -/* Object ID and allocation information (FFOBJID) */ - -typedef struct { - FATFS* fs; /* Pointer to the hosting volume of this object */ - WORD id; /* Hosting volume mount ID */ - BYTE attr; /* Object attribute */ - BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous, =3:flagmented in this session, b2:sub-directory stretched) */ - DWORD sclust; /* Object data start cluster (0:no cluster or root directory) */ - FSIZE_t objsize; /* Object size (valid when sclust != 0) */ -#if FF_FS_EXFAT - DWORD n_cont; /* Size of first fragment - 1 (valid when stat == 3) */ - DWORD n_frag; /* Size of last fragment needs to be written to FAT (valid when not zero) */ - DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */ - DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */ - DWORD c_ofs; /* Offset in the containing directory (valid when file object and sclust != 0) */ -#endif -#if FF_FS_LOCK - UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */ -#endif -} FFOBJID; - - - -/* File object structure (FIL) */ - -typedef struct { - FFOBJID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */ - BYTE flag; /* File status flags */ - BYTE err; /* Abort flag (error code) */ - FSIZE_t fptr; /* File read/write pointer (Zeroed on file open) */ - DWORD clust; /* Current cluster of fpter (invalid when fptr is 0) */ - DWORD sect; /* Sector number appearing in buf[] (0:invalid) */ -#if !FF_FS_READONLY - DWORD dir_sect; /* Sector number containing the directory entry (not used at exFAT) */ - BYTE* dir_ptr; /* Pointer to the directory entry in the win[] (not used at exFAT) */ -#endif -#if FF_USE_FASTSEEK - DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */ -#endif -#if !FF_FS_TINY - BYTE buf[FF_MAX_SS]; /* File private data read/write window */ -#endif -} FIL; - - - -/* Directory object structure (DIR) */ - -typedef struct { - FFOBJID obj; /* Object identifier */ - DWORD dptr; /* Current read/write offset */ - DWORD clust; /* Current cluster */ - DWORD sect; /* Current sector (0:Read operation has terminated) */ - BYTE* dir; /* Pointer to the directory item in the win[] */ - BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */ -#if FF_USE_LFN - DWORD blk_ofs; /* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */ -#endif -#if FF_USE_FIND - const TCHAR* pat; /* Pointer to the name matching pattern */ -#endif -} DIR; - - - -/* File information structure (FILINFO) */ - -typedef struct { - FSIZE_t fsize; /* File size */ - WORD fdate; /* Modified date */ - WORD ftime; /* Modified time */ - BYTE fattrib; /* File attribute */ -#if FF_USE_LFN - TCHAR altname[FF_SFN_BUF + 1];/* Altenative file name */ - TCHAR fname[FF_LFN_BUF + 1]; /* Primary file name */ -#else - TCHAR fname[12 + 1]; /* File name */ -#endif -} FILINFO; - - - -/* File function return code (FRESULT) */ - -typedef enum { - FR_OK = 0, /* (0) Succeeded */ - FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */ - FR_INT_ERR, /* (2) Assertion failed */ - FR_NOT_READY, /* (3) The physical drive cannot work */ - FR_NO_FILE, /* (4) Could not find the file */ - FR_NO_PATH, /* (5) Could not find the path */ - FR_INVALID_NAME, /* (6) The path name format is invalid */ - FR_DENIED, /* (7) Access denied due to prohibited access or directory full */ - FR_EXIST, /* (8) Access denied due to prohibited access */ - FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */ - FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */ - FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */ - FR_NOT_ENABLED, /* (12) The volume has no work area */ - FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */ - FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any problem */ - FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */ - FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */ - FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */ - FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > FF_FS_LOCK */ - FR_INVALID_PARAMETER /* (19) Given parameter is invalid */ -} FRESULT; - - - -/*--------------------------------------------------------------*/ -/* FatFs module application interface */ - -FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */ -FRESULT f_close (FIL* fp); /* Close an open file object */ -FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */ -FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */ -FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */ -FRESULT f_truncate (FIL* fp); /* Truncate the file */ -FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */ -FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */ -FRESULT f_closedir (DIR* dp); /* Close an open directory */ -FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */ -FRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */ -FRESULT f_findnext (DIR* dp, FILINFO* fno); /* Find next file */ -FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */ -FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */ -FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */ -FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */ -FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of a file/dir */ -FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change timestamp of a file/dir */ -FRESULT f_chdir (const TCHAR* path); /* Change current directory */ -FRESULT f_chdrive (const TCHAR* path); /* Change current drive */ -FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */ -FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */ -FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */ -FRESULT f_setlabel (const TCHAR* label); /* Set volume label */ -FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */ -FRESULT f_expand (FIL* fp, FSIZE_t szf, BYTE opt); /* Allocate a contiguous block to the file */ -FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */ -FRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */ -FRESULT f_fdisk (BYTE pdrv, const DWORD* szt, void* work); /* Divide a physical drive into some partitions */ -FRESULT f_setcp (WORD cp); /* Set current code page */ -int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */ -int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */ -int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */ -TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */ - -#define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize)) -#define f_error(fp) ((fp)->err) -#define f_tell(fp) ((fp)->fptr) -#define f_size(fp) ((fp)->obj.objsize) -#define f_rewind(fp) f_lseek((fp), 0) -#define f_rewinddir(dp) f_readdir((dp), 0) -#define f_rmdir(path) f_unlink(path) -#define f_unmount(path) f_mount(0, path, 0) - -#ifndef EOF -#define EOF (-1) -#endif - - - - -/*--------------------------------------------------------------*/ -/* Additional user defined functions */ - -/* RTC function */ -#if !FF_FS_READONLY && !FF_FS_NORTC -DWORD get_fattime (void); -#endif - -/* LFN support functions */ -#if FF_USE_LFN >= 1 /* Code conversion (defined in unicode.c) */ -WCHAR ff_oem2uni (WCHAR oem, WORD cp); /* OEM code to Unicode conversion */ -WCHAR ff_uni2oem (DWORD uni, WORD cp); /* Unicode to OEM code conversion */ -DWORD ff_wtoupper (DWORD uni); /* Unicode upper-case conversion */ -#endif -#if FF_USE_LFN == 3 /* Dynamic memory allocation */ -void* ff_memalloc (UINT msize); /* Allocate memory block */ -void ff_memfree (void* mblock); /* Free memory block */ -#endif - -/* Sync functions */ -#if FF_FS_REENTRANT -int ff_cre_syncobj (BYTE vol, FF_SYNC_t* sobj); /* Create a sync object */ -int ff_req_grant (FF_SYNC_t sobj); /* Lock sync object */ -void ff_rel_grant (FF_SYNC_t sobj); /* Unlock sync object */ -int ff_del_syncobj (FF_SYNC_t sobj); /* Delete a sync object */ -#endif - - - - -/*--------------------------------------------------------------*/ -/* Flags and offset address */ - - -/* File access mode and open method flags (3rd argument of f_open) */ -#define FA_READ 0x01 -#define FA_WRITE 0x02 -#define FA_OPEN_EXISTING 0x00 -#define FA_CREATE_NEW 0x04 -#define FA_CREATE_ALWAYS 0x08 -#define FA_OPEN_ALWAYS 0x10 -#define FA_OPEN_APPEND 0x30 - -/* Fast seek controls (2nd argument of f_lseek) */ -#define CREATE_LINKMAP ((FSIZE_t)0 - 1) - -/* Format options (2nd argument of f_mkfs) */ -#define FM_FAT 0x01 -#define FM_FAT32 0x02 -#define FM_EXFAT 0x04 -#define FM_ANY 0x07 -#define FM_SFD 0x08 - -/* Filesystem type (FATFS.fs_type) */ -#define FS_FAT12 1 -#define FS_FAT16 2 -#define FS_FAT32 3 -#define FS_EXFAT 4 - -/* File attribute bits for directory entry (FILINFO.fattrib) */ -#define AM_RDO 0x01 /* Read only */ -#define AM_HID 0x02 /* Hidden */ -#define AM_SYS 0x04 /* System */ -#define AM_DIR 0x10 /* Directory */ -#define AM_ARC 0x20 /* Archive */ - -/* Definitions of physical drive number for each drive */ -#define DEV_RAM 0 /* Example: Map Ramdisk to physical drive 0 */ -#define DEV_MMC 1 /* Example: Map MMC/SD card to physical drive 1 */ -#define DEV_USB 2 /* Example: Map USB MSD to physical drive 2 */ - -#ifdef __cplusplus -} -#endif - -#endif /* FF_DEFINED */ diff --git a/third-party/fatfs-0.1.3/ffconf.h b/third-party/fatfs-0.1.3/ffconf.h deleted file mode 100644 index 3274fce3..00000000 --- a/third-party/fatfs-0.1.3/ffconf.h +++ /dev/null @@ -1,293 +0,0 @@ - -#include -#include - -/*---------------------------------------------------------------------------/ -/ FatFs - Configuration file -/---------------------------------------------------------------------------*/ - -#define FFCONF_DEF 63463 /* Revision ID */ - -/*---------------------------------------------------------------------------/ -/ Function Configurations -/---------------------------------------------------------------------------*/ - -#define FF_FS_READONLY 0 -/* This option switches read-only configuration. (0:Read/Write or 1:Read-only) -/ Read-only configuration removes writing API functions, f_write(), f_sync(), -/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree() -/ and optional writing functions as well. */ - - -#define FF_FS_MINIMIZE 0 -/* This option defines minimization level to remove some basic API functions. -/ -/ 0: Basic functions are fully enabled. -/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename() -/ are removed. -/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1. -/ 3: f_lseek() function is removed in addition to 2. */ - - -#define FF_USE_STRFUNC 0 -/* This option switches string functions, f_gets(), f_putc(), f_puts() and f_printf(). -/ -/ 0: Disable string functions. -/ 1: Enable without LF-CRLF conversion. -/ 2: Enable with LF-CRLF conversion. */ - - -#define FF_USE_FIND 0 -/* This option switches filtered directory read functions, f_findfirst() and -/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */ - - -#define FF_USE_MKFS 1 -/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */ - - -#define FF_USE_FASTSEEK 0 -/* This option switches fast seek function. (0:Disable or 1:Enable) */ - - -#define FF_USE_EXPAND 0 -/* This option switches f_expand function. (0:Disable or 1:Enable) */ - - -#define FF_USE_CHMOD 0 -/* This option switches attribute manipulation functions, f_chmod() and f_utime(). -/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */ - - -#define FF_USE_LABEL 0 -/* This option switches volume label functions, f_getlabel() and f_setlabel(). -/ (0:Disable or 1:Enable) */ - - -#define FF_USE_FORWARD 0 -/* This option switches f_forward() function. (0:Disable or 1:Enable) */ - - -/*---------------------------------------------------------------------------/ -/ Locale and Namespace Configurations -/---------------------------------------------------------------------------*/ - -#define FF_CODE_PAGE 932 -/* This option specifies the OEM code page to be used on the target system. -/ Incorrect code page setting can cause a file open failure. -/ -/ 437 - U.S. -/ 720 - Arabic -/ 737 - Greek -/ 771 - KBL -/ 775 - Baltic -/ 850 - Latin 1 -/ 852 - Latin 2 -/ 855 - Cyrillic -/ 857 - Turkish -/ 860 - Portuguese -/ 861 - Icelandic -/ 862 - Hebrew -/ 863 - Canadian French -/ 864 - Arabic -/ 865 - Nordic -/ 866 - Russian -/ 869 - Greek 2 -/ 932 - Japanese (DBCS) -/ 936 - Simplified Chinese (DBCS) -/ 949 - Korean (DBCS) -/ 950 - Traditional Chinese (DBCS) -/ 0 - Include all code pages above and configured by f_setcp() -*/ - - -#define FF_USE_LFN 3/*1*/ -#define FF_MAX_LFN 255 -/* The FF_USE_LFN switches the support for LFN (long file name). -/ -/ 0: Disable LFN. FF_MAX_LFN has no effect. -/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe. -/ 2: Enable LFN with dynamic working buffer on the STACK. -/ 3: Enable LFN with dynamic working buffer on the HEAP. -/ -/ To enable the LFN, ffunicode.c needs to be added to the project. The LFN function -/ requiers certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and -/ additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled. -/ The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can -/ be in range of 12 to 255. It is recommended to be set 255 to fully support LFN -/ specification. -/ When use stack for the working buffer, take care on stack overflow. When use heap -/ memory for the working buffer, memory management functions, ff_memalloc() and -/ ff_memfree() in ffsystem.c, need to be added to the project. */ - - -#define FF_LFN_UNICODE 0 -/* This option switches the character encoding on the API when LFN is enabled. -/ -/ 0: ANSI/OEM in current CP (TCHAR = char) -/ 1: Unicode in UTF-16 (TCHAR = WCHAR) -/ 2: Unicode in UTF-8 (TCHAR = char) -/ 3: Unicode in UTF-32 (TCHAR = DWORD) -/ -/ Also behavior of string I/O functions will be affected by this option. -/ When LFN is not enabled, this option has no effect. */ - - -#define FF_LFN_BUF 255 -#define FF_SFN_BUF 12 -/* This set of options defines size of file name members in the FILINFO structure -/ which is used to read out directory items. These values should be suffcient for -/ the file names to read. The maximum possible length of the read file name depends -/ on character encoding. When LFN is not enabled, these options have no effect. */ - - -#define FF_STRF_ENCODE 3 -/* When FF_LFN_UNICODE >= 1 with LFN enabled, string I/O functions, f_gets(), -/ f_putc(), f_puts and f_printf() convert the character encoding in it. -/ This option selects assumption of character encoding ON THE FILE to be -/ read/written via those functions. -/ -/ 0: ANSI/OEM in current CP -/ 1: Unicode in UTF-16LE -/ 2: Unicode in UTF-16BE -/ 3: Unicode in UTF-8 -*/ - - -#define FF_FS_RPATH 0 -/* This option configures support for relative path. -/ -/ 0: Disable relative path and remove related functions. -/ 1: Enable relative path. f_chdir() and f_chdrive() are available. -/ 2: f_getcwd() function is available in addition to 1. -*/ - - -/*---------------------------------------------------------------------------/ -/ Drive/Volume Configurations -/---------------------------------------------------------------------------*/ - -#define FF_VOLUMES 1 -/* Number of volumes (logical drives) to be used. (1-10) */ - - -#define FF_STR_VOLUME_ID 0 -#define FF_VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3" -/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings. -/ When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive -/ number in the path name. FF_VOLUME_STRS defines the volume ID strings for each -/ logical drives. Number of items must not be less than FF_VOLUMES. Valid -/ characters for the volume ID strings are A-Z, a-z and 0-9, however, they are -/ compared in case-insensitive. If FF_STR_VOLUME_ID >= 1 and FF_VOLUME_STRS is -/ not defined, a user defined volume string table needs to be defined as: -/ -/ const char* VolumeStr[FF_VOLUMES] = {"ram","flash","sd","usb",... -*/ - - -#define FF_MULTI_PARTITION 0 -/* This option switches support for multiple volumes on the physical drive. -/ By default (0), each logical drive number is bound to the same physical drive -/ number and only an FAT volume found on the physical drive will be mounted. -/ When this function is enabled (1), each logical drive number can be bound to -/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk() -/ funciton will be available. */ - - -#define FF_MIN_SS 512 -#define FF_MAX_SS 512 -/* This set of options configures the range of sector size to be supported. (512, -/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and -/ harddisk. But a larger value may be required for on-board flash memory and some -/ type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured -/ for variable sector size mode and disk_ioctl() function needs to implement -/ GET_SECTOR_SIZE command. */ - - -#define FF_USE_TRIM 0 -/* This option switches support for ATA-TRIM. (0:Disable or 1:Enable) -/ To enable Trim function, also CTRL_TRIM command should be implemented to the -/ disk_ioctl() function. */ - - -#define FF_FS_NOFSINFO 0 -/* If you need to know correct free space on the FAT32 volume, set bit 0 of this -/ option, and f_getfree() function at first time after volume mount will force -/ a full FAT scan. Bit 1 controls the use of last allocated cluster number. -/ -/ bit0=0: Use free cluster count in the FSINFO if available. -/ bit0=1: Do not trust free cluster count in the FSINFO. -/ bit1=0: Use last allocated cluster number in the FSINFO if available. -/ bit1=1: Do not trust last allocated cluster number in the FSINFO. -*/ - - - -/*---------------------------------------------------------------------------/ -/ System Configurations -/---------------------------------------------------------------------------*/ - -#define FF_FS_TINY 0 -/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny) -/ At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes. -/ Instead of private sector buffer eliminated from the file object, common sector -/ buffer in the filesystem object (FATFS) is used for the file data transfer. */ - - -#define FF_FS_EXFAT 1 -/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable) -/ To enable exFAT, also LFN needs to be enabled. -/ Note that enabling exFAT discards ANSI C (C89) compatibility. */ - - -#define FF_FS_NORTC 1 -#define FF_NORTC_MON 1 -#define FF_NORTC_MDAY 1 -#define FF_NORTC_YEAR 2018 -/* The option FF_FS_NORTC switches timestamp functiton. If the system does not have -/ any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable -/ the timestamp function. Every object modified by FatFs will have a fixed timestamp -/ defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time. -/ To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be -/ added to the project to read current time form real-time clock. FF_NORTC_MON, -/ FF_NORTC_MDAY and FF_NORTC_YEAR have no effect. -/ These options have no effect at read-only configuration (FF_FS_READONLY = 1). */ - - -#define FF_FS_LOCK 0 -/* The option FF_FS_LOCK switches file lock function to control duplicated file open -/ and illegal operation to open objects. This option must be 0 when FF_FS_READONLY -/ is 1. -/ -/ 0: Disable file lock function. To avoid volume corruption, application program -/ should avoid illegal open, remove and rename to the open objects. -/ >0: Enable file lock function. The value defines how many files/sub-directories -/ can be opened simultaneously under file lock control. Note that the file -/ lock control is independent of re-entrancy. */ - - -#define FF_FS_REENTRANT 1/*0*/ -#define FF_FS_TIMEOUT 1000 -#define FF_SYNC_t xSemaphoreHandle -/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs -/ module itself. Note that regardless of this option, file access to different -/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs() -/ and f_fdisk() function, are always not re-entrant. Only file/directory access -/ to the same volume is under control of this function. -/ -/ 0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect. -/ 1: Enable re-entrancy. Also user provided synchronization handlers, -/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj() -/ function, must be added to the project. Samples are available in -/ option/syscall.c. -/ -/ The FF_FS_TIMEOUT defines timeout period in unit of time tick. -/ The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*, -/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be -/ included somewhere in the scope of ff.h. */ - -/* #include // O/S definitions */ - - - -/*--- End of configuration options ---*/ diff --git a/third-party/fatfs-0.1.3/ffunicode.c b/third-party/fatfs-0.1.3/ffunicode.c deleted file mode 100644 index 9a5d37ef..00000000 --- a/third-party/fatfs-0.1.3/ffunicode.c +++ /dev/null @@ -1,15597 +0,0 @@ -/*------------------------------------------------------------------------*/ -/* Unicode handling functions for FatFs R0.13b */ -/*------------------------------------------------------------------------*/ -/* This module will occupy a huge memory in the .const section when the / -/ FatFs is configured for LFN with DBCS. If the system has any Unicode / -/ utilitiy for the code conversion, this module should be modified to use / -/ that function to avoid silly memory consumption. / -/-------------------------------------------------------------------------*/ -/* -/ Copyright (C) 2018, ChaN, all right reserved. -/ -/ FatFs module is an open source software. Redistribution and use of FatFs in -/ source and binary forms, with or without modification, are permitted provided -/ that the following condition is met: -/ -/ 1. Redistributions of source code must retain the above copyright notice, -/ this condition and the following disclaimer. -/ -/ This software is provided by the copyright holder and contributors "AS IS" -/ and any warranties related to this software are DISCLAIMED. -/ The copyright owner or contributors be NOT LIABLE for any damages caused -/ by use of this software. -*/ - - -#include "ff.h" - -#if FF_USE_LFN /* This module is blanked when non-LFN configuration */ - -#if FF_DEFINED != 63463 /* Revision ID */ -#error Wrong include file (ff.h). -#endif - -#define MERGE2(a, b) a ## b -#define CVTBL(tbl, cp) MERGE2(tbl, cp) - - -/*------------------------------------------------------------------------*/ -/* Code Conversion Tables */ -/*------------------------------------------------------------------------*/ - -#if FF_CODE_PAGE == 932 || FF_CODE_PAGE == 0 /* Japanese */ -static const WCHAR uni2oem932[] = { /* Unicode --> Shift_JIS pairs */ - 0x00A7, 0x8198, 0x00A8, 0x814E, 0x00B0, 0x818B, 0x00B1, 0x817D, 0x00B4, 0x814C, 0x00B6, 0x81F7, 0x00D7, 0x817E, 0x00F7, 0x8180, - 0x0391, 0x839F, 0x0392, 0x83A0, 0x0393, 0x83A1, 0x0394, 0x83A2, 0x0395, 0x83A3, 0x0396, 0x83A4, 0x0397, 0x83A5, 0x0398, 0x83A6, - 0x0399, 0x83A7, 0x039A, 0x83A8, 0x039B, 0x83A9, 0x039C, 0x83AA, 0x039D, 0x83AB, 0x039E, 0x83AC, 0x039F, 0x83AD, 0x03A0, 0x83AE, - 0x03A1, 0x83AF, 0x03A3, 0x83B0, 0x03A4, 0x83B1, 0x03A5, 0x83B2, 0x03A6, 0x83B3, 0x03A7, 0x83B4, 0x03A8, 0x83B5, 0x03A9, 0x83B6, - 0x03B1, 0x83BF, 0x03B2, 0x83C0, 0x03B3, 0x83C1, 0x03B4, 0x83C2, 0x03B5, 0x83C3, 0x03B6, 0x83C4, 0x03B7, 0x83C5, 0x03B8, 0x83C6, - 0x03B9, 0x83C7, 0x03BA, 0x83C8, 0x03BB, 0x83C9, 0x03BC, 0x83CA, 0x03BD, 0x83CB, 0x03BE, 0x83CC, 0x03BF, 0x83CD, 0x03C0, 0x83CE, - 0x03C1, 0x83CF, 0x03C3, 0x83D0, 0x03C4, 0x83D1, 0x03C5, 0x83D2, 0x03C6, 0x83D3, 0x03C7, 0x83D4, 0x03C8, 0x83D5, 0x03C9, 0x83D6, - 0x0401, 0x8446, 0x0410, 0x8440, 0x0411, 0x8441, 0x0412, 0x8442, 0x0413, 0x8443, 0x0414, 0x8444, 0x0415, 0x8445, 0x0416, 0x8447, - 0x0417, 0x8448, 0x0418, 0x8449, 0x0419, 0x844A, 0x041A, 0x844B, 0x041B, 0x844C, 0x041C, 0x844D, 0x041D, 0x844E, 0x041E, 0x844F, - 0x041F, 0x8450, 0x0420, 0x8451, 0x0421, 0x8452, 0x0422, 0x8453, 0x0423, 0x8454, 0x0424, 0x8455, 0x0425, 0x8456, 0x0426, 0x8457, - 0x0427, 0x8458, 0x0428, 0x8459, 0x0429, 0x845A, 0x042A, 0x845B, 0x042B, 0x845C, 0x042C, 0x845D, 0x042D, 0x845E, 0x042E, 0x845F, - 0x042F, 0x8460, 0x0430, 0x8470, 0x0431, 0x8471, 0x0432, 0x8472, 0x0433, 0x8473, 0x0434, 0x8474, 0x0435, 0x8475, 0x0436, 0x8477, - 0x0437, 0x8478, 0x0438, 0x8479, 0x0439, 0x847A, 0x043A, 0x847B, 0x043B, 0x847C, 0x043C, 0x847D, 0x043D, 0x847E, 0x043E, 0x8480, - 0x043F, 0x8481, 0x0440, 0x8482, 0x0441, 0x8483, 0x0442, 0x8484, 0x0443, 0x8485, 0x0444, 0x8486, 0x0445, 0x8487, 0x0446, 0x8488, - 0x0447, 0x8489, 0x0448, 0x848A, 0x0449, 0x848B, 0x044A, 0x848C, 0x044B, 0x848D, 0x044C, 0x848E, 0x044D, 0x848F, 0x044E, 0x8490, - 0x044F, 0x8491, 0x0451, 0x8476, 0x2010, 0x815D, 0x2015, 0x815C, 0x2018, 0x8165, 0x2019, 0x8166, 0x201C, 0x8167, 0x201D, 0x8168, - 0x2020, 0x81F5, 0x2021, 0x81F6, 0x2025, 0x8164, 0x2026, 0x8163, 0x2030, 0x81F1, 0x2032, 0x818C, 0x2033, 0x818D, 0x203B, 0x81A6, - 0x2103, 0x818E, 0x2116, 0x8782, 0x2121, 0x8784, 0x212B, 0x81F0, 0x2160, 0x8754, 0x2161, 0x8755, 0x2162, 0x8756, 0x2163, 0x8757, - 0x2164, 0x8758, 0x2165, 0x8759, 0x2166, 0x875A, 0x2167, 0x875B, 0x2168, 0x875C, 0x2169, 0x875D, 0x2170, 0xFA40, 0x2171, 0xFA41, - 0x2172, 0xFA42, 0x2173, 0xFA43, 0x2174, 0xFA44, 0x2175, 0xFA45, 0x2176, 0xFA46, 0x2177, 0xFA47, 0x2178, 0xFA48, 0x2179, 0xFA49, - 0x2190, 0x81A9, 0x2191, 0x81AA, 0x2192, 0x81A8, 0x2193, 0x81AB, 0x21D2, 0x81CB, 0x21D4, 0x81CC, 0x2200, 0x81CD, 0x2202, 0x81DD, - 0x2203, 0x81CE, 0x2207, 0x81DE, 0x2208, 0x81B8, 0x220B, 0x81B9, 0x2211, 0x8794, 0x221A, 0x81E3, 0x221D, 0x81E5, 0x221E, 0x8187, - 0x221F, 0x8798, 0x2220, 0x81DA, 0x2225, 0x8161, 0x2227, 0x81C8, 0x2228, 0x81C9, 0x2229, 0x81BF, 0x222A, 0x81BE, 0x222B, 0x81E7, - 0x222C, 0x81E8, 0x222E, 0x8793, 0x2234, 0x8188, 0x2235, 0x81E6, 0x223D, 0x81E4, 0x2252, 0x81E0, 0x2260, 0x8182, 0x2261, 0x81DF, - 0x2266, 0x8185, 0x2267, 0x8186, 0x226A, 0x81E1, 0x226B, 0x81E2, 0x2282, 0x81BC, 0x2283, 0x81BD, 0x2286, 0x81BA, 0x2287, 0x81BB, - 0x22A5, 0x81DB, 0x22BF, 0x8799, 0x2312, 0x81DC, 0x2460, 0x8740, 0x2461, 0x8741, 0x2462, 0x8742, 0x2463, 0x8743, 0x2464, 0x8744, - 0x2465, 0x8745, 0x2466, 0x8746, 0x2467, 0x8747, 0x2468, 0x8748, 0x2469, 0x8749, 0x246A, 0x874A, 0x246B, 0x874B, 0x246C, 0x874C, - 0x246D, 0x874D, 0x246E, 0x874E, 0x246F, 0x874F, 0x2470, 0x8750, 0x2471, 0x8751, 0x2472, 0x8752, 0x2473, 0x8753, 0x2500, 0x849F, - 0x2501, 0x84AA, 0x2502, 0x84A0, 0x2503, 0x84AB, 0x250C, 0x84A1, 0x250F, 0x84AC, 0x2510, 0x84A2, 0x2513, 0x84AD, 0x2514, 0x84A4, - 0x2517, 0x84AF, 0x2518, 0x84A3, 0x251B, 0x84AE, 0x251C, 0x84A5, 0x251D, 0x84BA, 0x2520, 0x84B5, 0x2523, 0x84B0, 0x2524, 0x84A7, - 0x2525, 0x84BC, 0x2528, 0x84B7, 0x252B, 0x84B2, 0x252C, 0x84A6, 0x252F, 0x84B6, 0x2530, 0x84BB, 0x2533, 0x84B1, 0x2534, 0x84A8, - 0x2537, 0x84B8, 0x2538, 0x84BD, 0x253B, 0x84B3, 0x253C, 0x84A9, 0x253F, 0x84B9, 0x2542, 0x84BE, 0x254B, 0x84B4, 0x25A0, 0x81A1, - 0x25A1, 0x81A0, 0x25B2, 0x81A3, 0x25B3, 0x81A2, 0x25BC, 0x81A5, 0x25BD, 0x81A4, 0x25C6, 0x819F, 0x25C7, 0x819E, 0x25CB, 0x819B, - 0x25CE, 0x819D, 0x25CF, 0x819C, 0x25EF, 0x81FC, 0x2605, 0x819A, 0x2606, 0x8199, 0x2640, 0x818A, 0x2642, 0x8189, 0x266A, 0x81F4, - 0x266D, 0x81F3, 0x266F, 0x81F2, 0x3000, 0x8140, 0x3001, 0x8141, 0x3002, 0x8142, 0x3003, 0x8156, 0x3005, 0x8158, 0x3006, 0x8159, - 0x3007, 0x815A, 0x3008, 0x8171, 0x3009, 0x8172, 0x300A, 0x8173, 0x300B, 0x8174, 0x300C, 0x8175, 0x300D, 0x8176, 0x300E, 0x8177, - 0x300F, 0x8178, 0x3010, 0x8179, 0x3011, 0x817A, 0x3012, 0x81A7, 0x3013, 0x81AC, 0x3014, 0x816B, 0x3015, 0x816C, 0x301D, 0x8780, - 0x301F, 0x8781, 0x3041, 0x829F, 0x3042, 0x82A0, 0x3043, 0x82A1, 0x3044, 0x82A2, 0x3045, 0x82A3, 0x3046, 0x82A4, 0x3047, 0x82A5, - 0x3048, 0x82A6, 0x3049, 0x82A7, 0x304A, 0x82A8, 0x304B, 0x82A9, 0x304C, 0x82AA, 0x304D, 0x82AB, 0x304E, 0x82AC, 0x304F, 0x82AD, - 0x3050, 0x82AE, 0x3051, 0x82AF, 0x3052, 0x82B0, 0x3053, 0x82B1, 0x3054, 0x82B2, 0x3055, 0x82B3, 0x3056, 0x82B4, 0x3057, 0x82B5, - 0x3058, 0x82B6, 0x3059, 0x82B7, 0x305A, 0x82B8, 0x305B, 0x82B9, 0x305C, 0x82BA, 0x305D, 0x82BB, 0x305E, 0x82BC, 0x305F, 0x82BD, - 0x3060, 0x82BE, 0x3061, 0x82BF, 0x3062, 0x82C0, 0x3063, 0x82C1, 0x3064, 0x82C2, 0x3065, 0x82C3, 0x3066, 0x82C4, 0x3067, 0x82C5, - 0x3068, 0x82C6, 0x3069, 0x82C7, 0x306A, 0x82C8, 0x306B, 0x82C9, 0x306C, 0x82CA, 0x306D, 0x82CB, 0x306E, 0x82CC, 0x306F, 0x82CD, - 0x3070, 0x82CE, 0x3071, 0x82CF, 0x3072, 0x82D0, 0x3073, 0x82D1, 0x3074, 0x82D2, 0x3075, 0x82D3, 0x3076, 0x82D4, 0x3077, 0x82D5, - 0x3078, 0x82D6, 0x3079, 0x82D7, 0x307A, 0x82D8, 0x307B, 0x82D9, 0x307C, 0x82DA, 0x307D, 0x82DB, 0x307E, 0x82DC, 0x307F, 0x82DD, - 0x3080, 0x82DE, 0x3081, 0x82DF, 0x3082, 0x82E0, 0x3083, 0x82E1, 0x3084, 0x82E2, 0x3085, 0x82E3, 0x3086, 0x82E4, 0x3087, 0x82E5, - 0x3088, 0x82E6, 0x3089, 0x82E7, 0x308A, 0x82E8, 0x308B, 0x82E9, 0x308C, 0x82EA, 0x308D, 0x82EB, 0x308E, 0x82EC, 0x308F, 0x82ED, - 0x3090, 0x82EE, 0x3091, 0x82EF, 0x3092, 0x82F0, 0x3093, 0x82F1, 0x309B, 0x814A, 0x309C, 0x814B, 0x309D, 0x8154, 0x309E, 0x8155, - 0x30A1, 0x8340, 0x30A2, 0x8341, 0x30A3, 0x8342, 0x30A4, 0x8343, 0x30A5, 0x8344, 0x30A6, 0x8345, 0x30A7, 0x8346, 0x30A8, 0x8347, - 0x30A9, 0x8348, 0x30AA, 0x8349, 0x30AB, 0x834A, 0x30AC, 0x834B, 0x30AD, 0x834C, 0x30AE, 0x834D, 0x30AF, 0x834E, 0x30B0, 0x834F, - 0x30B1, 0x8350, 0x30B2, 0x8351, 0x30B3, 0x8352, 0x30B4, 0x8353, 0x30B5, 0x8354, 0x30B6, 0x8355, 0x30B7, 0x8356, 0x30B8, 0x8357, - 0x30B9, 0x8358, 0x30BA, 0x8359, 0x30BB, 0x835A, 0x30BC, 0x835B, 0x30BD, 0x835C, 0x30BE, 0x835D, 0x30BF, 0x835E, 0x30C0, 0x835F, - 0x30C1, 0x8360, 0x30C2, 0x8361, 0x30C3, 0x8362, 0x30C4, 0x8363, 0x30C5, 0x8364, 0x30C6, 0x8365, 0x30C7, 0x8366, 0x30C8, 0x8367, - 0x30C9, 0x8368, 0x30CA, 0x8369, 0x30CB, 0x836A, 0x30CC, 0x836B, 0x30CD, 0x836C, 0x30CE, 0x836D, 0x30CF, 0x836E, 0x30D0, 0x836F, - 0x30D1, 0x8370, 0x30D2, 0x8371, 0x30D3, 0x8372, 0x30D4, 0x8373, 0x30D5, 0x8374, 0x30D6, 0x8375, 0x30D7, 0x8376, 0x30D8, 0x8377, - 0x30D9, 0x8378, 0x30DA, 0x8379, 0x30DB, 0x837A, 0x30DC, 0x837B, 0x30DD, 0x837C, 0x30DE, 0x837D, 0x30DF, 0x837E, 0x30E0, 0x8380, - 0x30E1, 0x8381, 0x30E2, 0x8382, 0x30E3, 0x8383, 0x30E4, 0x8384, 0x30E5, 0x8385, 0x30E6, 0x8386, 0x30E7, 0x8387, 0x30E8, 0x8388, - 0x30E9, 0x8389, 0x30EA, 0x838A, 0x30EB, 0x838B, 0x30EC, 0x838C, 0x30ED, 0x838D, 0x30EE, 0x838E, 0x30EF, 0x838F, 0x30F0, 0x8390, - 0x30F1, 0x8391, 0x30F2, 0x8392, 0x30F3, 0x8393, 0x30F4, 0x8394, 0x30F5, 0x8395, 0x30F6, 0x8396, 0x30FB, 0x8145, 0x30FC, 0x815B, - 0x30FD, 0x8152, 0x30FE, 0x8153, 0x3231, 0x878A, 0x3232, 0x878B, 0x3239, 0x878C, 0x32A4, 0x8785, 0x32A5, 0x8786, 0x32A6, 0x8787, - 0x32A7, 0x8788, 0x32A8, 0x8789, 0x3303, 0x8765, 0x330D, 0x8769, 0x3314, 0x8760, 0x3318, 0x8763, 0x3322, 0x8761, 0x3323, 0x876B, - 0x3326, 0x876A, 0x3327, 0x8764, 0x332B, 0x876C, 0x3336, 0x8766, 0x333B, 0x876E, 0x3349, 0x875F, 0x334A, 0x876D, 0x334D, 0x8762, - 0x3351, 0x8767, 0x3357, 0x8768, 0x337B, 0x877E, 0x337C, 0x878F, 0x337D, 0x878E, 0x337E, 0x878D, 0x338E, 0x8772, 0x338F, 0x8773, - 0x339C, 0x876F, 0x339D, 0x8770, 0x339E, 0x8771, 0x33A1, 0x8775, 0x33C4, 0x8774, 0x33CD, 0x8783, 0x4E00, 0x88EA, 0x4E01, 0x929A, - 0x4E03, 0x8EB5, 0x4E07, 0x969C, 0x4E08, 0x8FE4, 0x4E09, 0x8E4F, 0x4E0A, 0x8FE3, 0x4E0B, 0x89BA, 0x4E0D, 0x9573, 0x4E0E, 0x975E, - 0x4E10, 0x98A0, 0x4E11, 0x894E, 0x4E14, 0x8A8E, 0x4E15, 0x98A1, 0x4E16, 0x90A2, 0x4E17, 0x99C0, 0x4E18, 0x8B75, 0x4E19, 0x95B8, - 0x4E1E, 0x8FE5, 0x4E21, 0x97BC, 0x4E26, 0x95C0, 0x4E28, 0xFA68, 0x4E2A, 0x98A2, 0x4E2D, 0x9286, 0x4E31, 0x98A3, 0x4E32, 0x8BF8, - 0x4E36, 0x98A4, 0x4E38, 0x8ADB, 0x4E39, 0x924F, 0x4E3B, 0x8EE5, 0x4E3C, 0x98A5, 0x4E3F, 0x98A6, 0x4E42, 0x98A7, 0x4E43, 0x9454, - 0x4E45, 0x8B76, 0x4E4B, 0x9456, 0x4E4D, 0x93E1, 0x4E4E, 0x8CC1, 0x4E4F, 0x9652, 0x4E55, 0xE568, 0x4E56, 0x98A8, 0x4E57, 0x8FE6, - 0x4E58, 0x98A9, 0x4E59, 0x89B3, 0x4E5D, 0x8BE3, 0x4E5E, 0x8CEE, 0x4E5F, 0x96E7, 0x4E62, 0x9BA4, 0x4E71, 0x9790, 0x4E73, 0x93FB, - 0x4E7E, 0x8AA3, 0x4E80, 0x8B54, 0x4E82, 0x98AA, 0x4E85, 0x98AB, 0x4E86, 0x97B9, 0x4E88, 0x975C, 0x4E89, 0x9188, 0x4E8A, 0x98AD, - 0x4E8B, 0x8E96, 0x4E8C, 0x93F1, 0x4E8E, 0x98B0, 0x4E91, 0x895D, 0x4E92, 0x8CDD, 0x4E94, 0x8CDC, 0x4E95, 0x88E4, 0x4E98, 0x986A, - 0x4E99, 0x9869, 0x4E9B, 0x8DB1, 0x4E9C, 0x889F, 0x4E9E, 0x98B1, 0x4E9F, 0x98B2, 0x4EA0, 0x98B3, 0x4EA1, 0x9653, 0x4EA2, 0x98B4, - 0x4EA4, 0x8CF0, 0x4EA5, 0x88E5, 0x4EA6, 0x9692, 0x4EA8, 0x8B9C, 0x4EAB, 0x8B9D, 0x4EAC, 0x8B9E, 0x4EAD, 0x92E0, 0x4EAE, 0x97BA, - 0x4EB0, 0x98B5, 0x4EB3, 0x98B6, 0x4EB6, 0x98B7, 0x4EBA, 0x906C, 0x4EC0, 0x8F59, 0x4EC1, 0x906D, 0x4EC2, 0x98BC, 0x4EC4, 0x98BA, - 0x4EC6, 0x98BB, 0x4EC7, 0x8B77, 0x4ECA, 0x8DA1, 0x4ECB, 0x89EE, 0x4ECD, 0x98B9, 0x4ECE, 0x98B8, 0x4ECF, 0x95A7, 0x4ED4, 0x8E65, - 0x4ED5, 0x8E64, 0x4ED6, 0x91BC, 0x4ED7, 0x98BD, 0x4ED8, 0x9574, 0x4ED9, 0x90E5, 0x4EDD, 0x8157, 0x4EDE, 0x98BE, 0x4EDF, 0x98C0, - 0x4EE1, 0xFA69, 0x4EE3, 0x91E3, 0x4EE4, 0x97DF, 0x4EE5, 0x88C8, 0x4EED, 0x98BF, 0x4EEE, 0x89BC, 0x4EF0, 0x8BC2, 0x4EF2, 0x9287, - 0x4EF6, 0x8C8F, 0x4EF7, 0x98C1, 0x4EFB, 0x9443, 0x4EFC, 0xFA6A, 0x4F00, 0xFA6B, 0x4F01, 0x8AE9, 0x4F03, 0xFA6C, 0x4F09, 0x98C2, - 0x4F0A, 0x88C9, 0x4F0D, 0x8CDE, 0x4F0E, 0x8AEA, 0x4F0F, 0x959A, 0x4F10, 0x94B0, 0x4F11, 0x8B78, 0x4F1A, 0x89EF, 0x4F1C, 0x98E5, - 0x4F1D, 0x9360, 0x4F2F, 0x948C, 0x4F30, 0x98C4, 0x4F34, 0x94BA, 0x4F36, 0x97E0, 0x4F38, 0x904C, 0x4F39, 0xFA6D, 0x4F3A, 0x8E66, - 0x4F3C, 0x8E97, 0x4F3D, 0x89BE, 0x4F43, 0x92CF, 0x4F46, 0x9241, 0x4F47, 0x98C8, 0x4F4D, 0x88CA, 0x4F4E, 0x92E1, 0x4F4F, 0x8F5A, - 0x4F50, 0x8DB2, 0x4F51, 0x9743, 0x4F53, 0x91CC, 0x4F55, 0x89BD, 0x4F56, 0xFA6E, 0x4F57, 0x98C7, 0x4F59, 0x975D, 0x4F5A, 0x98C3, - 0x4F5B, 0x98C5, 0x4F5C, 0x8DEC, 0x4F5D, 0x98C6, 0x4F5E, 0x9B43, 0x4F69, 0x98CE, 0x4F6F, 0x98D1, 0x4F70, 0x98CF, 0x4F73, 0x89C0, - 0x4F75, 0x95B9, 0x4F76, 0x98C9, 0x4F7B, 0x98CD, 0x4F7C, 0x8CF1, 0x4F7F, 0x8E67, 0x4F83, 0x8AA4, 0x4F86, 0x98D2, 0x4F88, 0x98CA, - 0x4F8A, 0xFA70, 0x4F8B, 0x97E1, 0x4F8D, 0x8E98, 0x4F8F, 0x98CB, 0x4F91, 0x98D0, 0x4F92, 0xFA6F, 0x4F94, 0xFA72, 0x4F96, 0x98D3, - 0x4F98, 0x98CC, 0x4F9A, 0xFA71, 0x4F9B, 0x8B9F, 0x4F9D, 0x88CB, 0x4FA0, 0x8BA0, 0x4FA1, 0x89BF, 0x4FAB, 0x9B44, 0x4FAD, 0x9699, - 0x4FAE, 0x958E, 0x4FAF, 0x8CF2, 0x4FB5, 0x904E, 0x4FB6, 0x97B5, 0x4FBF, 0x95D6, 0x4FC2, 0x8C57, 0x4FC3, 0x91A3, 0x4FC4, 0x89E2, - 0x4FC9, 0xFA61, 0x4FCA, 0x8F72, 0x4FCD, 0xFA73, 0x4FCE, 0x98D7, 0x4FD0, 0x98DC, 0x4FD1, 0x98DA, 0x4FD4, 0x98D5, 0x4FD7, 0x91AD, - 0x4FD8, 0x98D8, 0x4FDA, 0x98DB, 0x4FDB, 0x98D9, 0x4FDD, 0x95DB, 0x4FDF, 0x98D6, 0x4FE1, 0x904D, 0x4FE3, 0x9693, 0x4FE4, 0x98DD, - 0x4FE5, 0x98DE, 0x4FEE, 0x8F43, 0x4FEF, 0x98EB, 0x4FF3, 0x946F, 0x4FF5, 0x9555, 0x4FF6, 0x98E6, 0x4FF8, 0x95EE, 0x4FFA, 0x89B4, - 0x4FFE, 0x98EA, 0x4FFF, 0xFA76, 0x5005, 0x98E4, 0x5006, 0x98ED, 0x5009, 0x9171, 0x500B, 0x8CC2, 0x500D, 0x947B, 0x500F, 0xE0C5, - 0x5011, 0x98EC, 0x5012, 0x937C, 0x5014, 0x98E1, 0x5016, 0x8CF4, 0x5019, 0x8CF3, 0x501A, 0x98DF, 0x501E, 0xFA77, 0x501F, 0x8ED8, - 0x5021, 0x98E7, 0x5022, 0xFA75, 0x5023, 0x95ED, 0x5024, 0x926C, 0x5025, 0x98E3, 0x5026, 0x8C91, 0x5028, 0x98E0, 0x5029, 0x98E8, - 0x502A, 0x98E2, 0x502B, 0x97CF, 0x502C, 0x98E9, 0x502D, 0x9860, 0x5036, 0x8BE4, 0x5039, 0x8C90, 0x5040, 0xFA74, 0x5042, 0xFA7A, - 0x5043, 0x98EE, 0x5046, 0xFA78, 0x5047, 0x98EF, 0x5048, 0x98F3, 0x5049, 0x88CC, 0x504F, 0x95CE, 0x5050, 0x98F2, 0x5055, 0x98F1, - 0x5056, 0x98F5, 0x505A, 0x98F4, 0x505C, 0x92E2, 0x5065, 0x8C92, 0x506C, 0x98F6, 0x5070, 0xFA79, 0x5072, 0x8EC3, 0x5074, 0x91A4, - 0x5075, 0x92E3, 0x5076, 0x8BF4, 0x5078, 0x98F7, 0x507D, 0x8B55, 0x5080, 0x98F8, 0x5085, 0x98FA, 0x508D, 0x9654, 0x5091, 0x8C86, - 0x5094, 0xFA7B, 0x5098, 0x8E50, 0x5099, 0x94F5, 0x509A, 0x98F9, 0x50AC, 0x8DC3, 0x50AD, 0x9762, 0x50B2, 0x98FC, 0x50B3, 0x9942, - 0x50B4, 0x98FB, 0x50B5, 0x8DC2, 0x50B7, 0x8F9D, 0x50BE, 0x8C58, 0x50C2, 0x9943, 0x50C5, 0x8BCD, 0x50C9, 0x9940, 0x50CA, 0x9941, - 0x50CD, 0x93AD, 0x50CF, 0x919C, 0x50D1, 0x8BA1, 0x50D5, 0x966C, 0x50D6, 0x9944, 0x50D8, 0xFA7D, 0x50DA, 0x97BB, 0x50DE, 0x9945, - 0x50E3, 0x9948, 0x50E5, 0x9946, 0x50E7, 0x916D, 0x50ED, 0x9947, 0x50EE, 0x9949, 0x50F4, 0xFA7C, 0x50F5, 0x994B, 0x50F9, 0x994A, - 0x50FB, 0x95C6, 0x5100, 0x8B56, 0x5101, 0x994D, 0x5102, 0x994E, 0x5104, 0x89AD, 0x5109, 0x994C, 0x5112, 0x8EF2, 0x5114, 0x9951, - 0x5115, 0x9950, 0x5116, 0x994F, 0x5118, 0x98D4, 0x511A, 0x9952, 0x511F, 0x8F9E, 0x5121, 0x9953, 0x512A, 0x9744, 0x5132, 0x96D7, - 0x5137, 0x9955, 0x513A, 0x9954, 0x513B, 0x9957, 0x513C, 0x9956, 0x513F, 0x9958, 0x5140, 0x9959, 0x5141, 0x88F2, 0x5143, 0x8CB3, - 0x5144, 0x8C5A, 0x5145, 0x8F5B, 0x5146, 0x929B, 0x5147, 0x8BA2, 0x5148, 0x90E6, 0x5149, 0x8CF5, 0x514A, 0xFA7E, 0x514B, 0x8D8E, - 0x514C, 0x995B, 0x514D, 0x96C6, 0x514E, 0x9365, 0x5150, 0x8E99, 0x5152, 0x995A, 0x5154, 0x995C, 0x515A, 0x937D, 0x515C, 0x8A95, - 0x5162, 0x995D, 0x5164, 0xFA80, 0x5165, 0x93FC, 0x5168, 0x9153, 0x5169, 0x995F, 0x516A, 0x9960, 0x516B, 0x94AA, 0x516C, 0x8CF6, - 0x516D, 0x985A, 0x516E, 0x9961, 0x5171, 0x8BA4, 0x5175, 0x95BA, 0x5176, 0x91B4, 0x5177, 0x8BEF, 0x5178, 0x9354, 0x517C, 0x8C93, - 0x5180, 0x9962, 0x5182, 0x9963, 0x5185, 0x93E0, 0x5186, 0x897E, 0x5189, 0x9966, 0x518A, 0x8DFB, 0x518C, 0x9965, 0x518D, 0x8DC4, - 0x518F, 0x9967, 0x5190, 0xE3EC, 0x5191, 0x9968, 0x5192, 0x9660, 0x5193, 0x9969, 0x5195, 0x996A, 0x5196, 0x996B, 0x5197, 0x8FE7, - 0x5199, 0x8ECA, 0x519D, 0xFA81, 0x51A0, 0x8AA5, 0x51A2, 0x996E, 0x51A4, 0x996C, 0x51A5, 0x96BB, 0x51A6, 0x996D, 0x51A8, 0x9579, - 0x51A9, 0x996F, 0x51AA, 0x9970, 0x51AB, 0x9971, 0x51AC, 0x937E, 0x51B0, 0x9975, 0x51B1, 0x9973, 0x51B2, 0x9974, 0x51B3, 0x9972, - 0x51B4, 0x8DE1, 0x51B5, 0x9976, 0x51B6, 0x96E8, 0x51B7, 0x97E2, 0x51BD, 0x9977, 0x51BE, 0xFA82, 0x51C4, 0x90A6, 0x51C5, 0x9978, - 0x51C6, 0x8F79, 0x51C9, 0x9979, 0x51CB, 0x929C, 0x51CC, 0x97BD, 0x51CD, 0x9380, 0x51D6, 0x99C3, 0x51DB, 0x997A, 0x51DC, 0xEAA3, - 0x51DD, 0x8BC3, 0x51E0, 0x997B, 0x51E1, 0x967D, 0x51E6, 0x8F88, 0x51E7, 0x91FA, 0x51E9, 0x997D, 0x51EA, 0x93E2, 0x51EC, 0xFA83, - 0x51ED, 0x997E, 0x51F0, 0x9980, 0x51F1, 0x8A4D, 0x51F5, 0x9981, 0x51F6, 0x8BA5, 0x51F8, 0x93CA, 0x51F9, 0x899A, 0x51FA, 0x8F6F, - 0x51FD, 0x949F, 0x51FE, 0x9982, 0x5200, 0x9381, 0x5203, 0x906E, 0x5204, 0x9983, 0x5206, 0x95AA, 0x5207, 0x90D8, 0x5208, 0x8AA0, - 0x520A, 0x8AA7, 0x520B, 0x9984, 0x520E, 0x9986, 0x5211, 0x8C59, 0x5214, 0x9985, 0x5215, 0xFA84, 0x5217, 0x97F1, 0x521D, 0x8F89, - 0x5224, 0x94BB, 0x5225, 0x95CA, 0x5227, 0x9987, 0x5229, 0x9798, 0x522A, 0x9988, 0x522E, 0x9989, 0x5230, 0x939E, 0x5233, 0x998A, - 0x5236, 0x90A7, 0x5237, 0x8DFC, 0x5238, 0x8C94, 0x5239, 0x998B, 0x523A, 0x8E68, 0x523B, 0x8D8F, 0x5243, 0x92E4, 0x5244, 0x998D, - 0x5247, 0x91A5, 0x524A, 0x8DED, 0x524B, 0x998E, 0x524C, 0x998F, 0x524D, 0x914F, 0x524F, 0x998C, 0x5254, 0x9991, 0x5256, 0x9655, - 0x525B, 0x8D84, 0x525E, 0x9990, 0x5263, 0x8C95, 0x5264, 0x8DDC, 0x5265, 0x948D, 0x5269, 0x9994, 0x526A, 0x9992, 0x526F, 0x959B, - 0x5270, 0x8FE8, 0x5271, 0x999B, 0x5272, 0x8A84, 0x5273, 0x9995, 0x5274, 0x9993, 0x5275, 0x916E, 0x527D, 0x9997, 0x527F, 0x9996, - 0x5283, 0x8A63, 0x5287, 0x8C80, 0x5288, 0x999C, 0x5289, 0x97AB, 0x528D, 0x9998, 0x5291, 0x999D, 0x5292, 0x999A, 0x5294, 0x9999, - 0x529B, 0x97CD, 0x529C, 0xFA85, 0x529F, 0x8CF7, 0x52A0, 0x89C1, 0x52A3, 0x97F2, 0x52A6, 0xFA86, 0x52A9, 0x8F95, 0x52AA, 0x9377, - 0x52AB, 0x8D85, 0x52AC, 0x99A0, 0x52AD, 0x99A1, 0x52AF, 0xFB77, 0x52B1, 0x97E3, 0x52B4, 0x984A, 0x52B5, 0x99A3, 0x52B9, 0x8CF8, - 0x52BC, 0x99A2, 0x52BE, 0x8A4E, 0x52C0, 0xFA87, 0x52C1, 0x99A4, 0x52C3, 0x9675, 0x52C5, 0x92BA, 0x52C7, 0x9745, 0x52C9, 0x95D7, - 0x52CD, 0x99A5, 0x52D2, 0xE8D3, 0x52D5, 0x93AE, 0x52D7, 0x99A6, 0x52D8, 0x8AA8, 0x52D9, 0x96B1, 0x52DB, 0xFA88, 0x52DD, 0x8F9F, - 0x52DE, 0x99A7, 0x52DF, 0x95E5, 0x52E0, 0x99AB, 0x52E2, 0x90A8, 0x52E3, 0x99A8, 0x52E4, 0x8BCE, 0x52E6, 0x99A9, 0x52E7, 0x8AA9, - 0x52F2, 0x8C4D, 0x52F3, 0x99AC, 0x52F5, 0x99AD, 0x52F8, 0x99AE, 0x52F9, 0x99AF, 0x52FA, 0x8ED9, 0x52FE, 0x8CF9, 0x52FF, 0x96DC, - 0x5300, 0xFA89, 0x5301, 0x96E6, 0x5302, 0x93F5, 0x5305, 0x95EF, 0x5306, 0x99B0, 0x5307, 0xFA8A, 0x5308, 0x99B1, 0x530D, 0x99B3, - 0x530F, 0x99B5, 0x5310, 0x99B4, 0x5315, 0x99B6, 0x5316, 0x89BB, 0x5317, 0x966B, 0x5319, 0x8DFA, 0x531A, 0x99B7, 0x531D, 0x9178, - 0x5320, 0x8FA0, 0x5321, 0x8BA7, 0x5323, 0x99B8, 0x5324, 0xFA8B, 0x532A, 0x94D9, 0x532F, 0x99B9, 0x5331, 0x99BA, 0x5333, 0x99BB, - 0x5338, 0x99BC, 0x5339, 0x9543, 0x533A, 0x8BE6, 0x533B, 0x88E3, 0x533F, 0x93BD, 0x5340, 0x99BD, 0x5341, 0x8F5C, 0x5343, 0x90E7, - 0x5345, 0x99BF, 0x5346, 0x99BE, 0x5347, 0x8FA1, 0x5348, 0x8CDF, 0x5349, 0x99C1, 0x534A, 0x94BC, 0x534D, 0x99C2, 0x5351, 0x94DA, - 0x5352, 0x91B2, 0x5353, 0x91EC, 0x5354, 0x8BA6, 0x5357, 0x93EC, 0x5358, 0x9250, 0x535A, 0x948E, 0x535C, 0x966D, 0x535E, 0x99C4, - 0x5360, 0x90E8, 0x5366, 0x8C54, 0x5369, 0x99C5, 0x536E, 0x99C6, 0x536F, 0x894B, 0x5370, 0x88F3, 0x5371, 0x8AEB, 0x5372, 0xFA8C, - 0x5373, 0x91A6, 0x5374, 0x8B70, 0x5375, 0x9791, 0x5377, 0x99C9, 0x5378, 0x89B5, 0x537B, 0x99C8, 0x537F, 0x8BA8, 0x5382, 0x99CA, - 0x5384, 0x96EF, 0x5393, 0xFA8D, 0x5396, 0x99CB, 0x5398, 0x97D0, 0x539A, 0x8CFA, 0x539F, 0x8CB4, 0x53A0, 0x99CC, 0x53A5, 0x99CE, - 0x53A6, 0x99CD, 0x53A8, 0x907E, 0x53A9, 0x8958, 0x53AD, 0x897D, 0x53AE, 0x99CF, 0x53B0, 0x99D0, 0x53B2, 0xFA8E, 0x53B3, 0x8CB5, - 0x53B6, 0x99D1, 0x53BB, 0x8B8E, 0x53C2, 0x8E51, 0x53C3, 0x99D2, 0x53C8, 0x9694, 0x53C9, 0x8DB3, 0x53CA, 0x8B79, 0x53CB, 0x9746, - 0x53CC, 0x916F, 0x53CD, 0x94BD, 0x53CE, 0x8EFB, 0x53D4, 0x8F66, 0x53D6, 0x8EE6, 0x53D7, 0x8EF3, 0x53D9, 0x8F96, 0x53DB, 0x94BE, - 0x53DD, 0xFA8F, 0x53DF, 0x99D5, 0x53E1, 0x8962, 0x53E2, 0x9170, 0x53E3, 0x8CFB, 0x53E4, 0x8CC3, 0x53E5, 0x8BE5, 0x53E8, 0x99D9, - 0x53E9, 0x9240, 0x53EA, 0x91FC, 0x53EB, 0x8BA9, 0x53EC, 0x8FA2, 0x53ED, 0x99DA, 0x53EE, 0x99D8, 0x53EF, 0x89C2, 0x53F0, 0x91E4, - 0x53F1, 0x8EB6, 0x53F2, 0x8E6A, 0x53F3, 0x8945, 0x53F6, 0x8A90, 0x53F7, 0x8D86, 0x53F8, 0x8E69, 0x53FA, 0x99DB, 0x5401, 0x99DC, - 0x5403, 0x8B68, 0x5404, 0x8A65, 0x5408, 0x8D87, 0x5409, 0x8B67, 0x540A, 0x92DD, 0x540B, 0x8944, 0x540C, 0x93AF, 0x540D, 0x96BC, - 0x540E, 0x8D40, 0x540F, 0x9799, 0x5410, 0x9366, 0x5411, 0x8CFC, 0x541B, 0x8C4E, 0x541D, 0x99E5, 0x541F, 0x8BE1, 0x5420, 0x9669, - 0x5426, 0x94DB, 0x5429, 0x99E4, 0x542B, 0x8ADC, 0x542C, 0x99DF, 0x542D, 0x99E0, 0x542E, 0x99E2, 0x5436, 0x99E3, 0x5438, 0x8B7A, - 0x5439, 0x9081, 0x543B, 0x95AB, 0x543C, 0x99E1, 0x543D, 0x99DD, 0x543E, 0x8CE1, 0x5440, 0x99DE, 0x5442, 0x9843, 0x5446, 0x95F0, - 0x5448, 0x92E6, 0x5449, 0x8CE0, 0x544A, 0x8D90, 0x544E, 0x99E6, 0x5451, 0x93DB, 0x545F, 0x99EA, 0x5468, 0x8EFC, 0x546A, 0x8EF4, - 0x5470, 0x99ED, 0x5471, 0x99EB, 0x5473, 0x96A1, 0x5475, 0x99E8, 0x5476, 0x99F1, 0x5477, 0x99EC, 0x547B, 0x99EF, 0x547C, 0x8CC4, - 0x547D, 0x96BD, 0x5480, 0x99F0, 0x5484, 0x99F2, 0x5486, 0x99F4, 0x548A, 0xFA92, 0x548B, 0x8DEE, 0x548C, 0x9861, 0x548E, 0x99E9, - 0x548F, 0x99E7, 0x5490, 0x99F3, 0x5492, 0x99EE, 0x549C, 0xFA91, 0x54A2, 0x99F6, 0x54A4, 0x9A42, 0x54A5, 0x99F8, 0x54A8, 0x99FC, - 0x54A9, 0xFA93, 0x54AB, 0x9A40, 0x54AC, 0x99F9, 0x54AF, 0x9A5D, 0x54B2, 0x8DE7, 0x54B3, 0x8A50, 0x54B8, 0x99F7, 0x54BC, 0x9A44, - 0x54BD, 0x88F4, 0x54BE, 0x9A43, 0x54C0, 0x88A3, 0x54C1, 0x9569, 0x54C2, 0x9A41, 0x54C4, 0x99FA, 0x54C7, 0x99F5, 0x54C8, 0x99FB, - 0x54C9, 0x8DC6, 0x54D8, 0x9A45, 0x54E1, 0x88F5, 0x54E2, 0x9A4E, 0x54E5, 0x9A46, 0x54E6, 0x9A47, 0x54E8, 0x8FA3, 0x54E9, 0x9689, - 0x54ED, 0x9A4C, 0x54EE, 0x9A4B, 0x54F2, 0x934E, 0x54FA, 0x9A4D, 0x54FD, 0x9A4A, 0x54FF, 0xFA94, 0x5504, 0x8953, 0x5506, 0x8DB4, - 0x5507, 0x904F, 0x550F, 0x9A48, 0x5510, 0x9382, 0x5514, 0x9A49, 0x5516, 0x88A0, 0x552E, 0x9A53, 0x552F, 0x9742, 0x5531, 0x8FA5, - 0x5533, 0x9A59, 0x5538, 0x9A58, 0x5539, 0x9A4F, 0x553E, 0x91C1, 0x5540, 0x9A50, 0x5544, 0x91ED, 0x5545, 0x9A55, 0x5546, 0x8FA4, - 0x554C, 0x9A52, 0x554F, 0x96E2, 0x5553, 0x8C5B, 0x5556, 0x9A56, 0x5557, 0x9A57, 0x555C, 0x9A54, 0x555D, 0x9A5A, 0x5563, 0x9A51, - 0x557B, 0x9A60, 0x557C, 0x9A65, 0x557E, 0x9A61, 0x5580, 0x9A5C, 0x5583, 0x9A66, 0x5584, 0x9150, 0x5586, 0xFA95, 0x5587, 0x9A68, - 0x5589, 0x8D41, 0x558A, 0x9A5E, 0x558B, 0x929D, 0x5598, 0x9A62, 0x5599, 0x9A5B, 0x559A, 0x8AAB, 0x559C, 0x8AEC, 0x559D, 0x8A85, - 0x559E, 0x9A63, 0x559F, 0x9A5F, 0x55A7, 0x8C96, 0x55A8, 0x9A69, 0x55A9, 0x9A67, 0x55AA, 0x9172, 0x55AB, 0x8B69, 0x55AC, 0x8BAA, - 0x55AE, 0x9A64, 0x55B0, 0x8BF2, 0x55B6, 0x8963, 0x55C4, 0x9A6D, 0x55C5, 0x9A6B, 0x55C7, 0x9AA5, 0x55D4, 0x9A70, 0x55DA, 0x9A6A, - 0x55DC, 0x9A6E, 0x55DF, 0x9A6C, 0x55E3, 0x8E6B, 0x55E4, 0x9A6F, 0x55F7, 0x9A72, 0x55F9, 0x9A77, 0x55FD, 0x9A75, 0x55FE, 0x9A74, - 0x5606, 0x9251, 0x5609, 0x89C3, 0x5614, 0x9A71, 0x5616, 0x9A73, 0x5617, 0x8FA6, 0x5618, 0x8952, 0x561B, 0x9A76, 0x5629, 0x89DC, - 0x562F, 0x9A82, 0x5631, 0x8FFA, 0x5632, 0x9A7D, 0x5634, 0x9A7B, 0x5636, 0x9A7C, 0x5638, 0x9A7E, 0x5642, 0x895C, 0x564C, 0x9158, - 0x564E, 0x9A78, 0x5650, 0x9A79, 0x565B, 0x8A9A, 0x5664, 0x9A81, 0x5668, 0x8AED, 0x566A, 0x9A84, 0x566B, 0x9A80, 0x566C, 0x9A83, - 0x5674, 0x95AC, 0x5678, 0x93D3, 0x567A, 0x94B6, 0x5680, 0x9A86, 0x5686, 0x9A85, 0x5687, 0x8A64, 0x568A, 0x9A87, 0x568F, 0x9A8A, - 0x5694, 0x9A89, 0x56A0, 0x9A88, 0x56A2, 0x9458, 0x56A5, 0x9A8B, 0x56AE, 0x9A8C, 0x56B4, 0x9A8E, 0x56B6, 0x9A8D, 0x56BC, 0x9A90, - 0x56C0, 0x9A93, 0x56C1, 0x9A91, 0x56C2, 0x9A8F, 0x56C3, 0x9A92, 0x56C8, 0x9A94, 0x56CE, 0x9A95, 0x56D1, 0x9A96, 0x56D3, 0x9A97, - 0x56D7, 0x9A98, 0x56D8, 0x9964, 0x56DA, 0x8EFA, 0x56DB, 0x8E6C, 0x56DE, 0x89F1, 0x56E0, 0x88F6, 0x56E3, 0x9263, 0x56EE, 0x9A99, - 0x56F0, 0x8DA2, 0x56F2, 0x88CD, 0x56F3, 0x907D, 0x56F9, 0x9A9A, 0x56FA, 0x8CC5, 0x56FD, 0x8D91, 0x56FF, 0x9A9C, 0x5700, 0x9A9B, - 0x5703, 0x95DE, 0x5704, 0x9A9D, 0x5708, 0x9A9F, 0x5709, 0x9A9E, 0x570B, 0x9AA0, 0x570D, 0x9AA1, 0x570F, 0x8C97, 0x5712, 0x8980, - 0x5713, 0x9AA2, 0x5716, 0x9AA4, 0x5718, 0x9AA3, 0x571C, 0x9AA6, 0x571F, 0x9379, 0x5726, 0x9AA7, 0x5727, 0x88B3, 0x5728, 0x8DDD, - 0x572D, 0x8C5C, 0x5730, 0x926E, 0x5737, 0x9AA8, 0x5738, 0x9AA9, 0x573B, 0x9AAB, 0x5740, 0x9AAC, 0x5742, 0x8DE2, 0x5747, 0x8BCF, - 0x574A, 0x9656, 0x574E, 0x9AAA, 0x574F, 0x9AAD, 0x5750, 0x8DBF, 0x5751, 0x8D42, 0x5759, 0xFA96, 0x5761, 0x9AB1, 0x5764, 0x8DA3, - 0x5765, 0xFA97, 0x5766, 0x9252, 0x5769, 0x9AAE, 0x576A, 0x92D8, 0x577F, 0x9AB2, 0x5782, 0x9082, 0x5788, 0x9AB0, 0x5789, 0x9AB3, - 0x578B, 0x8C5E, 0x5793, 0x9AB4, 0x57A0, 0x9AB5, 0x57A2, 0x8D43, 0x57A3, 0x8A5F, 0x57A4, 0x9AB7, 0x57AA, 0x9AB8, 0x57AC, 0xFA98, - 0x57B0, 0x9AB9, 0x57B3, 0x9AB6, 0x57C0, 0x9AAF, 0x57C3, 0x9ABA, 0x57C6, 0x9ABB, 0x57C7, 0xFA9A, 0x57C8, 0xFA99, 0x57CB, 0x9684, - 0x57CE, 0x8FE9, 0x57D2, 0x9ABD, 0x57D3, 0x9ABE, 0x57D4, 0x9ABC, 0x57D6, 0x9AC0, 0x57DC, 0x9457, 0x57DF, 0x88E6, 0x57E0, 0x9575, - 0x57E3, 0x9AC1, 0x57F4, 0x8FFB, 0x57F7, 0x8EB7, 0x57F9, 0x947C, 0x57FA, 0x8AEE, 0x57FC, 0x8DE9, 0x5800, 0x9678, 0x5802, 0x93B0, - 0x5805, 0x8C98, 0x5806, 0x91CD, 0x580A, 0x9ABF, 0x580B, 0x9AC2, 0x5815, 0x91C2, 0x5819, 0x9AC3, 0x581D, 0x9AC4, 0x5821, 0x9AC6, - 0x5824, 0x92E7, 0x582A, 0x8AAC, 0x582F, 0xEA9F, 0x5830, 0x8981, 0x5831, 0x95F1, 0x5834, 0x8FEA, 0x5835, 0x9367, 0x583A, 0x8DE4, - 0x583D, 0x9ACC, 0x5840, 0x95BB, 0x5841, 0x97DB, 0x584A, 0x89F2, 0x584B, 0x9AC8, 0x5851, 0x9159, 0x5852, 0x9ACB, 0x5854, 0x9383, - 0x5857, 0x9368, 0x5858, 0x9384, 0x5859, 0x94B7, 0x585A, 0x92CB, 0x585E, 0x8DC7, 0x5862, 0x9AC7, 0x5869, 0x8996, 0x586B, 0x9355, - 0x5870, 0x9AC9, 0x5872, 0x9AC5, 0x5875, 0x906F, 0x5879, 0x9ACD, 0x587E, 0x8F6D, 0x5883, 0x8BAB, 0x5885, 0x9ACE, 0x5893, 0x95E6, - 0x5897, 0x919D, 0x589C, 0x92C4, 0x589E, 0xFA9D, 0x589F, 0x9AD0, 0x58A8, 0x966E, 0x58AB, 0x9AD1, 0x58AE, 0x9AD6, 0x58B2, 0xFA9E, - 0x58B3, 0x95AD, 0x58B8, 0x9AD5, 0x58B9, 0x9ACF, 0x58BA, 0x9AD2, 0x58BB, 0x9AD4, 0x58BE, 0x8DA4, 0x58C1, 0x95C7, 0x58C5, 0x9AD7, - 0x58C7, 0x9264, 0x58CA, 0x89F3, 0x58CC, 0x8FEB, 0x58D1, 0x9AD9, 0x58D3, 0x9AD8, 0x58D5, 0x8D88, 0x58D7, 0x9ADA, 0x58D8, 0x9ADC, - 0x58D9, 0x9ADB, 0x58DC, 0x9ADE, 0x58DE, 0x9AD3, 0x58DF, 0x9AE0, 0x58E4, 0x9ADF, 0x58E5, 0x9ADD, 0x58EB, 0x8E6D, 0x58EC, 0x9070, - 0x58EE, 0x9173, 0x58EF, 0x9AE1, 0x58F0, 0x90BA, 0x58F1, 0x88EB, 0x58F2, 0x9484, 0x58F7, 0x92D9, 0x58F9, 0x9AE3, 0x58FA, 0x9AE2, - 0x58FB, 0x9AE4, 0x58FC, 0x9AE5, 0x58FD, 0x9AE6, 0x5902, 0x9AE7, 0x5909, 0x95CF, 0x590A, 0x9AE8, 0x590B, 0xFA9F, 0x590F, 0x89C4, - 0x5910, 0x9AE9, 0x5915, 0x975B, 0x5916, 0x8A4F, 0x5918, 0x99C7, 0x5919, 0x8F67, 0x591A, 0x91BD, 0x591B, 0x9AEA, 0x591C, 0x96E9, - 0x5922, 0x96B2, 0x5925, 0x9AEC, 0x5927, 0x91E5, 0x5929, 0x9356, 0x592A, 0x91BE, 0x592B, 0x9576, 0x592C, 0x9AED, 0x592D, 0x9AEE, - 0x592E, 0x899B, 0x5931, 0x8EB8, 0x5932, 0x9AEF, 0x5937, 0x88CE, 0x5938, 0x9AF0, 0x593E, 0x9AF1, 0x5944, 0x8982, 0x5947, 0x8AEF, - 0x5948, 0x93DE, 0x5949, 0x95F2, 0x594E, 0x9AF5, 0x594F, 0x9174, 0x5950, 0x9AF4, 0x5951, 0x8C5F, 0x5953, 0xFAA0, 0x5954, 0x967A, - 0x5955, 0x9AF3, 0x5957, 0x9385, 0x5958, 0x9AF7, 0x595A, 0x9AF6, 0x595B, 0xFAA1, 0x595D, 0xFAA2, 0x5960, 0x9AF9, 0x5962, 0x9AF8, - 0x5963, 0xFAA3, 0x5965, 0x899C, 0x5967, 0x9AFA, 0x5968, 0x8FA7, 0x5969, 0x9AFC, 0x596A, 0x9244, 0x596C, 0x9AFB, 0x596E, 0x95B1, - 0x5973, 0x8F97, 0x5974, 0x937A, 0x5978, 0x9B40, 0x597D, 0x8D44, 0x5981, 0x9B41, 0x5982, 0x9440, 0x5983, 0x94DC, 0x5984, 0x96CF, - 0x598A, 0x9444, 0x598D, 0x9B4A, 0x5993, 0x8B57, 0x5996, 0x9764, 0x5999, 0x96AD, 0x599B, 0x9BAA, 0x599D, 0x9B42, 0x59A3, 0x9B45, - 0x59A4, 0xFAA4, 0x59A5, 0x91C3, 0x59A8, 0x9657, 0x59AC, 0x9369, 0x59B2, 0x9B46, 0x59B9, 0x9685, 0x59BA, 0xFAA5, 0x59BB, 0x8DC8, - 0x59BE, 0x8FA8, 0x59C6, 0x9B47, 0x59C9, 0x8E6F, 0x59CB, 0x8E6E, 0x59D0, 0x88B7, 0x59D1, 0x8CC6, 0x59D3, 0x90A9, 0x59D4, 0x88CF, - 0x59D9, 0x9B4B, 0x59DA, 0x9B4C, 0x59DC, 0x9B49, 0x59E5, 0x8957, 0x59E6, 0x8AAD, 0x59E8, 0x9B48, 0x59EA, 0x96C3, 0x59EB, 0x9550, - 0x59F6, 0x88A6, 0x59FB, 0x88F7, 0x59FF, 0x8E70, 0x5A01, 0x88D0, 0x5A03, 0x88A1, 0x5A09, 0x9B51, 0x5A11, 0x9B4F, 0x5A18, 0x96BA, - 0x5A1A, 0x9B52, 0x5A1C, 0x9B50, 0x5A1F, 0x9B4E, 0x5A20, 0x9050, 0x5A25, 0x9B4D, 0x5A29, 0x95D8, 0x5A2F, 0x8CE2, 0x5A35, 0x9B56, - 0x5A36, 0x9B57, 0x5A3C, 0x8FA9, 0x5A40, 0x9B53, 0x5A41, 0x984B, 0x5A46, 0x946B, 0x5A49, 0x9B55, 0x5A5A, 0x8DA5, 0x5A62, 0x9B58, - 0x5A66, 0x9577, 0x5A6A, 0x9B59, 0x5A6C, 0x9B54, 0x5A7F, 0x96B9, 0x5A92, 0x947D, 0x5A9A, 0x9B5A, 0x5A9B, 0x9551, 0x5ABC, 0x9B5B, - 0x5ABD, 0x9B5F, 0x5ABE, 0x9B5C, 0x5AC1, 0x89C5, 0x5AC2, 0x9B5E, 0x5AC9, 0x8EB9, 0x5ACB, 0x9B5D, 0x5ACC, 0x8C99, 0x5AD0, 0x9B6B, - 0x5AD6, 0x9B64, 0x5AD7, 0x9B61, 0x5AE1, 0x9284, 0x5AE3, 0x9B60, 0x5AE6, 0x9B62, 0x5AE9, 0x9B63, 0x5AFA, 0x9B65, 0x5AFB, 0x9B66, - 0x5B09, 0x8AF0, 0x5B0B, 0x9B68, 0x5B0C, 0x9B67, 0x5B16, 0x9B69, 0x5B22, 0x8FEC, 0x5B2A, 0x9B6C, 0x5B2C, 0x92DA, 0x5B30, 0x8964, - 0x5B32, 0x9B6A, 0x5B36, 0x9B6D, 0x5B3E, 0x9B6E, 0x5B40, 0x9B71, 0x5B43, 0x9B6F, 0x5B45, 0x9B70, 0x5B50, 0x8E71, 0x5B51, 0x9B72, - 0x5B54, 0x8D45, 0x5B55, 0x9B73, 0x5B56, 0xFAA6, 0x5B57, 0x8E9A, 0x5B58, 0x91B6, 0x5B5A, 0x9B74, 0x5B5B, 0x9B75, 0x5B5C, 0x8E79, - 0x5B5D, 0x8D46, 0x5B5F, 0x96D0, 0x5B63, 0x8B47, 0x5B64, 0x8CC7, 0x5B65, 0x9B76, 0x5B66, 0x8A77, 0x5B69, 0x9B77, 0x5B6B, 0x91B7, - 0x5B70, 0x9B78, 0x5B71, 0x9BA1, 0x5B73, 0x9B79, 0x5B75, 0x9B7A, 0x5B78, 0x9B7B, 0x5B7A, 0x9B7D, 0x5B80, 0x9B7E, 0x5B83, 0x9B80, - 0x5B85, 0x91EE, 0x5B87, 0x8946, 0x5B88, 0x8EE7, 0x5B89, 0x88C0, 0x5B8B, 0x9176, 0x5B8C, 0x8AAE, 0x5B8D, 0x8EB3, 0x5B8F, 0x8D47, - 0x5B95, 0x9386, 0x5B97, 0x8F40, 0x5B98, 0x8AAF, 0x5B99, 0x9288, 0x5B9A, 0x92E8, 0x5B9B, 0x88B6, 0x5B9C, 0x8B58, 0x5B9D, 0x95F3, - 0x5B9F, 0x8EC0, 0x5BA2, 0x8B71, 0x5BA3, 0x90E9, 0x5BA4, 0x8EBA, 0x5BA5, 0x9747, 0x5BA6, 0x9B81, 0x5BAE, 0x8B7B, 0x5BB0, 0x8DC9, - 0x5BB3, 0x8A51, 0x5BB4, 0x8983, 0x5BB5, 0x8FAA, 0x5BB6, 0x89C6, 0x5BB8, 0x9B82, 0x5BB9, 0x9765, 0x5BBF, 0x8F68, 0x5BC0, 0xFAA7, - 0x5BC2, 0x8EE2, 0x5BC3, 0x9B83, 0x5BC4, 0x8AF1, 0x5BC5, 0x93D0, 0x5BC6, 0x96A7, 0x5BC7, 0x9B84, 0x5BC9, 0x9B85, 0x5BCC, 0x9578, - 0x5BD0, 0x9B87, 0x5BD2, 0x8AA6, 0x5BD3, 0x8BF5, 0x5BD4, 0x9B86, 0x5BD8, 0xFAA9, 0x5BDB, 0x8AB0, 0x5BDD, 0x9051, 0x5BDE, 0x9B8B, - 0x5BDF, 0x8E40, 0x5BE1, 0x89C7, 0x5BE2, 0x9B8A, 0x5BE4, 0x9B88, 0x5BE5, 0x9B8C, 0x5BE6, 0x9B89, 0x5BE7, 0x944A, 0x5BE8, 0x9ECB, - 0x5BE9, 0x9052, 0x5BEB, 0x9B8D, 0x5BEC, 0xFAAA, 0x5BEE, 0x97BE, 0x5BF0, 0x9B8E, 0x5BF3, 0x9B90, 0x5BF5, 0x929E, 0x5BF6, 0x9B8F, - 0x5BF8, 0x90A1, 0x5BFA, 0x8E9B, 0x5BFE, 0x91CE, 0x5BFF, 0x8EF5, 0x5C01, 0x9595, 0x5C02, 0x90EA, 0x5C04, 0x8ECB, 0x5C05, 0x9B91, - 0x5C06, 0x8FAB, 0x5C07, 0x9B92, 0x5C08, 0x9B93, 0x5C09, 0x88D1, 0x5C0A, 0x91B8, 0x5C0B, 0x9071, 0x5C0D, 0x9B94, 0x5C0E, 0x93B1, - 0x5C0F, 0x8FAC, 0x5C11, 0x8FAD, 0x5C13, 0x9B95, 0x5C16, 0x90EB, 0x5C1A, 0x8FAE, 0x5C1E, 0xFAAB, 0x5C20, 0x9B96, 0x5C22, 0x9B97, - 0x5C24, 0x96DE, 0x5C28, 0x9B98, 0x5C2D, 0x8BC4, 0x5C31, 0x8F41, 0x5C38, 0x9B99, 0x5C39, 0x9B9A, 0x5C3A, 0x8EDA, 0x5C3B, 0x904B, - 0x5C3C, 0x93F2, 0x5C3D, 0x9073, 0x5C3E, 0x94F6, 0x5C3F, 0x9441, 0x5C40, 0x8BC7, 0x5C41, 0x9B9B, 0x5C45, 0x8B8F, 0x5C46, 0x9B9C, - 0x5C48, 0x8BFC, 0x5C4A, 0x93CD, 0x5C4B, 0x89AE, 0x5C4D, 0x8E72, 0x5C4E, 0x9B9D, 0x5C4F, 0x9BA0, 0x5C50, 0x9B9F, 0x5C51, 0x8BFB, - 0x5C53, 0x9B9E, 0x5C55, 0x9357, 0x5C5E, 0x91AE, 0x5C60, 0x936A, 0x5C61, 0x8EC6, 0x5C64, 0x9177, 0x5C65, 0x979A, 0x5C6C, 0x9BA2, - 0x5C6E, 0x9BA3, 0x5C6F, 0x93D4, 0x5C71, 0x8E52, 0x5C76, 0x9BA5, 0x5C79, 0x9BA6, 0x5C8C, 0x9BA7, 0x5C90, 0x8AF2, 0x5C91, 0x9BA8, - 0x5C94, 0x9BA9, 0x5CA1, 0x89AA, 0x5CA6, 0xFAAC, 0x5CA8, 0x915A, 0x5CA9, 0x8AE2, 0x5CAB, 0x9BAB, 0x5CAC, 0x96A6, 0x5CB1, 0x91D0, - 0x5CB3, 0x8A78, 0x5CB6, 0x9BAD, 0x5CB7, 0x9BAF, 0x5CB8, 0x8ADD, 0x5CBA, 0xFAAD, 0x5CBB, 0x9BAC, 0x5CBC, 0x9BAE, 0x5CBE, 0x9BB1, - 0x5CC5, 0x9BB0, 0x5CC7, 0x9BB2, 0x5CD9, 0x9BB3, 0x5CE0, 0x93BB, 0x5CE1, 0x8BAC, 0x5CE8, 0x89E3, 0x5CE9, 0x9BB4, 0x5CEA, 0x9BB9, - 0x5CED, 0x9BB7, 0x5CEF, 0x95F5, 0x5CF0, 0x95F4, 0x5CF5, 0xFAAE, 0x5CF6, 0x9387, 0x5CFA, 0x9BB6, 0x5CFB, 0x8F73, 0x5CFD, 0x9BB5, - 0x5D07, 0x9092, 0x5D0B, 0x9BBA, 0x5D0E, 0x8DE8, 0x5D11, 0x9BC0, 0x5D14, 0x9BC1, 0x5D15, 0x9BBB, 0x5D16, 0x8A52, 0x5D17, 0x9BBC, - 0x5D18, 0x9BC5, 0x5D19, 0x9BC4, 0x5D1A, 0x9BC3, 0x5D1B, 0x9BBF, 0x5D1F, 0x9BBE, 0x5D22, 0x9BC2, 0x5D27, 0xFAAF, 0x5D29, 0x95F6, - 0x5D42, 0xFAB2, 0x5D4B, 0x9BC9, 0x5D4C, 0x9BC6, 0x5D4E, 0x9BC8, 0x5D50, 0x9792, 0x5D52, 0x9BC7, 0x5D53, 0xFAB0, 0x5D5C, 0x9BBD, - 0x5D69, 0x9093, 0x5D6C, 0x9BCA, 0x5D6D, 0xFAB3, 0x5D6F, 0x8DB5, 0x5D73, 0x9BCB, 0x5D76, 0x9BCC, 0x5D82, 0x9BCF, 0x5D84, 0x9BCE, - 0x5D87, 0x9BCD, 0x5D8B, 0x9388, 0x5D8C, 0x9BB8, 0x5D90, 0x9BD5, 0x5D9D, 0x9BD1, 0x5DA2, 0x9BD0, 0x5DAC, 0x9BD2, 0x5DAE, 0x9BD3, - 0x5DB7, 0x9BD6, 0x5DB8, 0xFAB4, 0x5DB9, 0xFAB5, 0x5DBA, 0x97E4, 0x5DBC, 0x9BD7, 0x5DBD, 0x9BD4, 0x5DC9, 0x9BD8, 0x5DCC, 0x8ADE, - 0x5DCD, 0x9BD9, 0x5DD0, 0xFAB6, 0x5DD2, 0x9BDB, 0x5DD3, 0x9BDA, 0x5DD6, 0x9BDC, 0x5DDB, 0x9BDD, 0x5DDD, 0x90EC, 0x5DDE, 0x8F42, - 0x5DE1, 0x8F84, 0x5DE3, 0x9183, 0x5DE5, 0x8D48, 0x5DE6, 0x8DB6, 0x5DE7, 0x8D49, 0x5DE8, 0x8B90, 0x5DEB, 0x9BDE, 0x5DEE, 0x8DB7, - 0x5DF1, 0x8CC8, 0x5DF2, 0x9BDF, 0x5DF3, 0x96A4, 0x5DF4, 0x9462, 0x5DF5, 0x9BE0, 0x5DF7, 0x8D4A, 0x5DFB, 0x8AAA, 0x5DFD, 0x9246, - 0x5DFE, 0x8BD0, 0x5E02, 0x8E73, 0x5E03, 0x957A, 0x5E06, 0x94BF, 0x5E0B, 0x9BE1, 0x5E0C, 0x8AF3, 0x5E11, 0x9BE4, 0x5E16, 0x929F, - 0x5E19, 0x9BE3, 0x5E1A, 0x9BE2, 0x5E1B, 0x9BE5, 0x5E1D, 0x92E9, 0x5E25, 0x9083, 0x5E2B, 0x8E74, 0x5E2D, 0x90C8, 0x5E2F, 0x91D1, - 0x5E30, 0x8B41, 0x5E33, 0x92A0, 0x5E36, 0x9BE6, 0x5E37, 0x9BE7, 0x5E38, 0x8FED, 0x5E3D, 0x9658, 0x5E40, 0x9BEA, 0x5E43, 0x9BE9, - 0x5E44, 0x9BE8, 0x5E45, 0x959D, 0x5E47, 0x9BF1, 0x5E4C, 0x9679, 0x5E4E, 0x9BEB, 0x5E54, 0x9BED, 0x5E55, 0x968B, 0x5E57, 0x9BEC, - 0x5E5F, 0x9BEE, 0x5E61, 0x94A6, 0x5E62, 0x9BEF, 0x5E63, 0x95BC, 0x5E64, 0x9BF0, 0x5E72, 0x8AB1, 0x5E73, 0x95BD, 0x5E74, 0x944E, - 0x5E75, 0x9BF2, 0x5E76, 0x9BF3, 0x5E78, 0x8D4B, 0x5E79, 0x8AB2, 0x5E7A, 0x9BF4, 0x5E7B, 0x8CB6, 0x5E7C, 0x9763, 0x5E7D, 0x9748, - 0x5E7E, 0x8AF4, 0x5E7F, 0x9BF6, 0x5E81, 0x92A1, 0x5E83, 0x8D4C, 0x5E84, 0x8FAF, 0x5E87, 0x94DD, 0x5E8A, 0x8FB0, 0x5E8F, 0x8F98, - 0x5E95, 0x92EA, 0x5E96, 0x95F7, 0x5E97, 0x9358, 0x5E9A, 0x8D4D, 0x5E9C, 0x957B, 0x5EA0, 0x9BF7, 0x5EA6, 0x9378, 0x5EA7, 0x8DC0, - 0x5EAB, 0x8CC9, 0x5EAD, 0x92EB, 0x5EB5, 0x88C1, 0x5EB6, 0x8F8E, 0x5EB7, 0x8D4E, 0x5EB8, 0x9766, 0x5EC1, 0x9BF8, 0x5EC2, 0x9BF9, - 0x5EC3, 0x9470, 0x5EC8, 0x9BFA, 0x5EC9, 0x97F5, 0x5ECA, 0x984C, 0x5ECF, 0x9BFC, 0x5ED0, 0x9BFB, 0x5ED3, 0x8A66, 0x5ED6, 0x9C40, - 0x5EDA, 0x9C43, 0x5EDB, 0x9C44, 0x5EDD, 0x9C42, 0x5EDF, 0x955F, 0x5EE0, 0x8FB1, 0x5EE1, 0x9C46, 0x5EE2, 0x9C45, 0x5EE3, 0x9C41, - 0x5EE8, 0x9C47, 0x5EE9, 0x9C48, 0x5EEC, 0x9C49, 0x5EF0, 0x9C4C, 0x5EF1, 0x9C4A, 0x5EF3, 0x9C4B, 0x5EF4, 0x9C4D, 0x5EF6, 0x8984, - 0x5EF7, 0x92EC, 0x5EF8, 0x9C4E, 0x5EFA, 0x8C9A, 0x5EFB, 0x89F4, 0x5EFC, 0x9455, 0x5EFE, 0x9C4F, 0x5EFF, 0x93F9, 0x5F01, 0x95D9, - 0x5F03, 0x9C50, 0x5F04, 0x984D, 0x5F09, 0x9C51, 0x5F0A, 0x95BE, 0x5F0B, 0x9C54, 0x5F0C, 0x989F, 0x5F0D, 0x98AF, 0x5F0F, 0x8EAE, - 0x5F10, 0x93F3, 0x5F11, 0x9C55, 0x5F13, 0x8B7C, 0x5F14, 0x92A2, 0x5F15, 0x88F8, 0x5F16, 0x9C56, 0x5F17, 0x95A4, 0x5F18, 0x8D4F, - 0x5F1B, 0x926F, 0x5F1F, 0x92ED, 0x5F21, 0xFAB7, 0x5F25, 0x96ED, 0x5F26, 0x8CB7, 0x5F27, 0x8CCA, 0x5F29, 0x9C57, 0x5F2D, 0x9C58, - 0x5F2F, 0x9C5E, 0x5F31, 0x8EE3, 0x5F34, 0xFAB8, 0x5F35, 0x92A3, 0x5F37, 0x8BAD, 0x5F38, 0x9C59, 0x5F3C, 0x954A, 0x5F3E, 0x9265, - 0x5F41, 0x9C5A, 0x5F45, 0xFA67, 0x5F48, 0x9C5B, 0x5F4A, 0x8BAE, 0x5F4C, 0x9C5C, 0x5F4E, 0x9C5D, 0x5F51, 0x9C5F, 0x5F53, 0x9396, - 0x5F56, 0x9C60, 0x5F57, 0x9C61, 0x5F59, 0x9C62, 0x5F5C, 0x9C53, 0x5F5D, 0x9C52, 0x5F61, 0x9C63, 0x5F62, 0x8C60, 0x5F66, 0x9546, - 0x5F67, 0xFAB9, 0x5F69, 0x8DCA, 0x5F6A, 0x9556, 0x5F6B, 0x92A4, 0x5F6C, 0x956A, 0x5F6D, 0x9C64, 0x5F70, 0x8FB2, 0x5F71, 0x8965, - 0x5F73, 0x9C65, 0x5F77, 0x9C66, 0x5F79, 0x96F0, 0x5F7C, 0x94DE, 0x5F7F, 0x9C69, 0x5F80, 0x899D, 0x5F81, 0x90AA, 0x5F82, 0x9C68, - 0x5F83, 0x9C67, 0x5F84, 0x8C61, 0x5F85, 0x91D2, 0x5F87, 0x9C6D, 0x5F88, 0x9C6B, 0x5F8A, 0x9C6A, 0x5F8B, 0x97A5, 0x5F8C, 0x8CE3, - 0x5F90, 0x8F99, 0x5F91, 0x9C6C, 0x5F92, 0x936B, 0x5F93, 0x8F5D, 0x5F97, 0x93BE, 0x5F98, 0x9C70, 0x5F99, 0x9C6F, 0x5F9E, 0x9C6E, - 0x5FA0, 0x9C71, 0x5FA1, 0x8CE4, 0x5FA8, 0x9C72, 0x5FA9, 0x959C, 0x5FAA, 0x8F7A, 0x5FAD, 0x9C73, 0x5FAE, 0x94F7, 0x5FB3, 0x93BF, - 0x5FB4, 0x92A5, 0x5FB7, 0xFABA, 0x5FB9, 0x934F, 0x5FBC, 0x9C74, 0x5FBD, 0x8B4A, 0x5FC3, 0x9053, 0x5FC5, 0x954B, 0x5FCC, 0x8AF5, - 0x5FCD, 0x9445, 0x5FD6, 0x9C75, 0x5FD7, 0x8E75, 0x5FD8, 0x9659, 0x5FD9, 0x965A, 0x5FDC, 0x899E, 0x5FDD, 0x9C7A, 0x5FDE, 0xFABB, - 0x5FE0, 0x9289, 0x5FE4, 0x9C77, 0x5FEB, 0x89F5, 0x5FF0, 0x9CAB, 0x5FF1, 0x9C79, 0x5FF5, 0x944F, 0x5FF8, 0x9C78, 0x5FFB, 0x9C76, - 0x5FFD, 0x8D9A, 0x5FFF, 0x9C7C, 0x600E, 0x9C83, 0x600F, 0x9C89, 0x6010, 0x9C81, 0x6012, 0x937B, 0x6015, 0x9C86, 0x6016, 0x957C, - 0x6019, 0x9C80, 0x601B, 0x9C85, 0x601C, 0x97E5, 0x601D, 0x8E76, 0x6020, 0x91D3, 0x6021, 0x9C7D, 0x6025, 0x8B7D, 0x6026, 0x9C88, - 0x6027, 0x90AB, 0x6028, 0x8985, 0x6029, 0x9C82, 0x602A, 0x89F6, 0x602B, 0x9C87, 0x602F, 0x8BAF, 0x6031, 0x9C84, 0x603A, 0x9C8A, - 0x6041, 0x9C8C, 0x6042, 0x9C96, 0x6043, 0x9C94, 0x6046, 0x9C91, 0x604A, 0x9C90, 0x604B, 0x97F6, 0x604D, 0x9C92, 0x6050, 0x8BB0, - 0x6052, 0x8D50, 0x6055, 0x8F9A, 0x6059, 0x9C99, 0x605A, 0x9C8B, 0x605D, 0xFABC, 0x605F, 0x9C8F, 0x6060, 0x9C7E, 0x6062, 0x89F8, - 0x6063, 0x9C93, 0x6064, 0x9C95, 0x6065, 0x9270, 0x6068, 0x8DA6, 0x6069, 0x89B6, 0x606A, 0x9C8D, 0x606B, 0x9C98, 0x606C, 0x9C97, - 0x606D, 0x8BB1, 0x606F, 0x91A7, 0x6070, 0x8A86, 0x6075, 0x8C62, 0x6077, 0x9C8E, 0x6081, 0x9C9A, 0x6083, 0x9C9D, 0x6084, 0x9C9F, - 0x6085, 0xFABD, 0x6089, 0x8EBB, 0x608A, 0xFABE, 0x608B, 0x9CA5, 0x608C, 0x92EE, 0x608D, 0x9C9B, 0x6092, 0x9CA3, 0x6094, 0x89F7, - 0x6096, 0x9CA1, 0x6097, 0x9CA2, 0x609A, 0x9C9E, 0x609B, 0x9CA0, 0x609F, 0x8CE5, 0x60A0, 0x9749, 0x60A3, 0x8AB3, 0x60A6, 0x8978, - 0x60A7, 0x9CA4, 0x60A9, 0x9459, 0x60AA, 0x88AB, 0x60B2, 0x94DF, 0x60B3, 0x9C7B, 0x60B4, 0x9CAA, 0x60B5, 0x9CAE, 0x60B6, 0x96E3, - 0x60B8, 0x9CA7, 0x60BC, 0x9389, 0x60BD, 0x9CAC, 0x60C5, 0x8FEE, 0x60C6, 0x9CAD, 0x60C7, 0x93D5, 0x60D1, 0x9866, 0x60D3, 0x9CA9, - 0x60D5, 0xFAC0, 0x60D8, 0x9CAF, 0x60DA, 0x8D9B, 0x60DC, 0x90C9, 0x60DE, 0xFABF, 0x60DF, 0x88D2, 0x60E0, 0x9CA8, 0x60E1, 0x9CA6, - 0x60E3, 0x9179, 0x60E7, 0x9C9C, 0x60E8, 0x8E53, 0x60F0, 0x91C4, 0x60F1, 0x9CBB, 0x60F2, 0xFAC2, 0x60F3, 0x917A, 0x60F4, 0x9CB6, - 0x60F6, 0x9CB3, 0x60F7, 0x9CB4, 0x60F9, 0x8EE4, 0x60FA, 0x9CB7, 0x60FB, 0x9CBA, 0x6100, 0x9CB5, 0x6101, 0x8F44, 0x6103, 0x9CB8, - 0x6106, 0x9CB2, 0x6108, 0x96FA, 0x6109, 0x96F9, 0x610D, 0x9CBC, 0x610E, 0x9CBD, 0x610F, 0x88D3, 0x6111, 0xFAC3, 0x6115, 0x9CB1, - 0x611A, 0x8BF0, 0x611B, 0x88A4, 0x611F, 0x8AB4, 0x6120, 0xFAC1, 0x6121, 0x9CB9, 0x6127, 0x9CC1, 0x6128, 0x9CC0, 0x612C, 0x9CC5, - 0x6130, 0xFAC5, 0x6134, 0x9CC6, 0x6137, 0xFAC4, 0x613C, 0x9CC4, 0x613D, 0x9CC7, 0x613E, 0x9CBF, 0x613F, 0x9CC3, 0x6142, 0x9CC8, - 0x6144, 0x9CC9, 0x6147, 0x9CBE, 0x6148, 0x8E9C, 0x614A, 0x9CC2, 0x614B, 0x91D4, 0x614C, 0x8D51, 0x614D, 0x9CB0, 0x614E, 0x9054, - 0x6153, 0x9CD6, 0x6155, 0x95E7, 0x6158, 0x9CCC, 0x6159, 0x9CCD, 0x615A, 0x9CCE, 0x615D, 0x9CD5, 0x615F, 0x9CD4, 0x6162, 0x969D, - 0x6163, 0x8AB5, 0x6165, 0x9CD2, 0x6167, 0x8C64, 0x6168, 0x8A53, 0x616B, 0x9CCF, 0x616E, 0x97B6, 0x616F, 0x9CD1, 0x6170, 0x88D4, - 0x6171, 0x9CD3, 0x6173, 0x9CCA, 0x6174, 0x9CD0, 0x6175, 0x9CD7, 0x6176, 0x8C63, 0x6177, 0x9CCB, 0x617E, 0x977C, 0x6182, 0x974A, - 0x6187, 0x9CDA, 0x618A, 0x9CDE, 0x618E, 0x919E, 0x6190, 0x97F7, 0x6191, 0x9CDF, 0x6194, 0x9CDC, 0x6196, 0x9CD9, 0x6198, 0xFAC6, - 0x6199, 0x9CD8, 0x619A, 0x9CDD, 0x61A4, 0x95AE, 0x61A7, 0x93B2, 0x61A9, 0x8C65, 0x61AB, 0x9CE0, 0x61AC, 0x9CDB, 0x61AE, 0x9CE1, - 0x61B2, 0x8C9B, 0x61B6, 0x89AF, 0x61BA, 0x9CE9, 0x61BE, 0x8AB6, 0x61C3, 0x9CE7, 0x61C6, 0x9CE8, 0x61C7, 0x8DA7, 0x61C8, 0x9CE6, - 0x61C9, 0x9CE4, 0x61CA, 0x9CE3, 0x61CB, 0x9CEA, 0x61CC, 0x9CE2, 0x61CD, 0x9CEC, 0x61D0, 0x89F9, 0x61E3, 0x9CEE, 0x61E6, 0x9CED, - 0x61F2, 0x92A6, 0x61F4, 0x9CF1, 0x61F6, 0x9CEF, 0x61F7, 0x9CE5, 0x61F8, 0x8C9C, 0x61FA, 0x9CF0, 0x61FC, 0x9CF4, 0x61FD, 0x9CF3, - 0x61FE, 0x9CF5, 0x61FF, 0x9CF2, 0x6200, 0x9CF6, 0x6208, 0x9CF7, 0x6209, 0x9CF8, 0x620A, 0x95E8, 0x620C, 0x9CFA, 0x620D, 0x9CF9, - 0x620E, 0x8F5E, 0x6210, 0x90AC, 0x6211, 0x89E4, 0x6212, 0x89FA, 0x6213, 0xFAC7, 0x6214, 0x9CFB, 0x6216, 0x88BD, 0x621A, 0x90CA, - 0x621B, 0x9CFC, 0x621D, 0xE6C1, 0x621E, 0x9D40, 0x621F, 0x8C81, 0x6221, 0x9D41, 0x6226, 0x90ED, 0x622A, 0x9D42, 0x622E, 0x9D43, - 0x622F, 0x8B59, 0x6230, 0x9D44, 0x6232, 0x9D45, 0x6233, 0x9D46, 0x6234, 0x91D5, 0x6238, 0x8CCB, 0x623B, 0x96DF, 0x623F, 0x965B, - 0x6240, 0x8F8A, 0x6241, 0x9D47, 0x6247, 0x90EE, 0x6248, 0xE7BB, 0x6249, 0x94E0, 0x624B, 0x8EE8, 0x624D, 0x8DCB, 0x624E, 0x9D48, - 0x6253, 0x91C5, 0x6255, 0x95A5, 0x6258, 0x91EF, 0x625B, 0x9D4B, 0x625E, 0x9D49, 0x6260, 0x9D4C, 0x6263, 0x9D4A, 0x6268, 0x9D4D, - 0x626E, 0x95AF, 0x6271, 0x88B5, 0x6276, 0x957D, 0x6279, 0x94E1, 0x627C, 0x9D4E, 0x627E, 0x9D51, 0x627F, 0x8FB3, 0x6280, 0x8B5A, - 0x6282, 0x9D4F, 0x6283, 0x9D56, 0x6284, 0x8FB4, 0x6289, 0x9D50, 0x628A, 0x9463, 0x6291, 0x977D, 0x6292, 0x9D52, 0x6293, 0x9D53, - 0x6294, 0x9D57, 0x6295, 0x938A, 0x6296, 0x9D54, 0x6297, 0x8D52, 0x6298, 0x90DC, 0x629B, 0x9D65, 0x629C, 0x94B2, 0x629E, 0x91F0, - 0x62A6, 0xFAC8, 0x62AB, 0x94E2, 0x62AC, 0x9DAB, 0x62B1, 0x95F8, 0x62B5, 0x92EF, 0x62B9, 0x9695, 0x62BB, 0x9D5A, 0x62BC, 0x899F, - 0x62BD, 0x928A, 0x62C2, 0x9D63, 0x62C5, 0x9253, 0x62C6, 0x9D5D, 0x62C7, 0x9D64, 0x62C8, 0x9D5F, 0x62C9, 0x9D66, 0x62CA, 0x9D62, - 0x62CC, 0x9D61, 0x62CD, 0x948F, 0x62CF, 0x9D5B, 0x62D0, 0x89FB, 0x62D1, 0x9D59, 0x62D2, 0x8B91, 0x62D3, 0x91F1, 0x62D4, 0x9D55, - 0x62D7, 0x9D58, 0x62D8, 0x8D53, 0x62D9, 0x90D9, 0x62DB, 0x8FB5, 0x62DC, 0x9D60, 0x62DD, 0x9471, 0x62E0, 0x8B92, 0x62E1, 0x8A67, - 0x62EC, 0x8A87, 0x62ED, 0x9040, 0x62EE, 0x9D68, 0x62EF, 0x9D6D, 0x62F1, 0x9D69, 0x62F3, 0x8C9D, 0x62F5, 0x9D6E, 0x62F6, 0x8E41, - 0x62F7, 0x8D89, 0x62FE, 0x8F45, 0x62FF, 0x9D5C, 0x6301, 0x8E9D, 0x6302, 0x9D6B, 0x6307, 0x8E77, 0x6308, 0x9D6C, 0x6309, 0x88C2, - 0x630C, 0x9D67, 0x6311, 0x92A7, 0x6319, 0x8B93, 0x631F, 0x8BB2, 0x6327, 0x9D6A, 0x6328, 0x88A5, 0x632B, 0x8DC1, 0x632F, 0x9055, - 0x633A, 0x92F0, 0x633D, 0x94D2, 0x633E, 0x9D70, 0x633F, 0x917D, 0x6349, 0x91A8, 0x634C, 0x8E4A, 0x634D, 0x9D71, 0x634F, 0x9D73, - 0x6350, 0x9D6F, 0x6355, 0x95DF, 0x6357, 0x92BB, 0x635C, 0x917B, 0x6367, 0x95F9, 0x6368, 0x8ECC, 0x6369, 0x9D80, 0x636B, 0x9D7E, - 0x636E, 0x9098, 0x6372, 0x8C9E, 0x6376, 0x9D78, 0x6377, 0x8FB7, 0x637A, 0x93E6, 0x637B, 0x9450, 0x6380, 0x9D76, 0x6383, 0x917C, - 0x6388, 0x8EF6, 0x6389, 0x9D7B, 0x638C, 0x8FB6, 0x638E, 0x9D75, 0x638F, 0x9D7A, 0x6392, 0x9472, 0x6396, 0x9D74, 0x6398, 0x8C40, - 0x639B, 0x8A7C, 0x639F, 0x9D7C, 0x63A0, 0x97A9, 0x63A1, 0x8DCC, 0x63A2, 0x9254, 0x63A3, 0x9D79, 0x63A5, 0x90DA, 0x63A7, 0x8D54, - 0x63A8, 0x9084, 0x63A9, 0x8986, 0x63AA, 0x915B, 0x63AB, 0x9D77, 0x63AC, 0x8B64, 0x63B2, 0x8C66, 0x63B4, 0x92CD, 0x63B5, 0x9D7D, - 0x63BB, 0x917E, 0x63BE, 0x9D81, 0x63C0, 0x9D83, 0x63C3, 0x91B5, 0x63C4, 0x9D89, 0x63C6, 0x9D84, 0x63C9, 0x9D86, 0x63CF, 0x9560, - 0x63D0, 0x92F1, 0x63D2, 0x9D87, 0x63D6, 0x974B, 0x63DA, 0x9767, 0x63DB, 0x8AB7, 0x63E1, 0x88AC, 0x63E3, 0x9D85, 0x63E9, 0x9D82, - 0x63EE, 0x8AF6, 0x63F4, 0x8987, 0x63F5, 0xFAC9, 0x63F6, 0x9D88, 0x63FA, 0x9768, 0x6406, 0x9D8C, 0x640D, 0x91B9, 0x640F, 0x9D93, - 0x6413, 0x9D8D, 0x6416, 0x9D8A, 0x6417, 0x9D91, 0x641C, 0x9D72, 0x6426, 0x9D8E, 0x6428, 0x9D92, 0x642C, 0x94C0, 0x642D, 0x938B, - 0x6434, 0x9D8B, 0x6436, 0x9D8F, 0x643A, 0x8C67, 0x643E, 0x8DEF, 0x6442, 0x90DB, 0x644E, 0x9D97, 0x6458, 0x9345, 0x6460, 0xFACA, - 0x6467, 0x9D94, 0x6469, 0x9680, 0x646F, 0x9D95, 0x6476, 0x9D96, 0x6478, 0x96CC, 0x647A, 0x90A0, 0x6483, 0x8C82, 0x6488, 0x9D9D, - 0x6492, 0x8E54, 0x6493, 0x9D9A, 0x6495, 0x9D99, 0x649A, 0x9451, 0x649D, 0xFACB, 0x649E, 0x93B3, 0x64A4, 0x9350, 0x64A5, 0x9D9B, - 0x64A9, 0x9D9C, 0x64AB, 0x958F, 0x64AD, 0x9464, 0x64AE, 0x8E42, 0x64B0, 0x90EF, 0x64B2, 0x966F, 0x64B9, 0x8A68, 0x64BB, 0x9DA3, - 0x64BC, 0x9D9E, 0x64C1, 0x9769, 0x64C2, 0x9DA5, 0x64C5, 0x9DA1, 0x64C7, 0x9DA2, 0x64CD, 0x9180, 0x64CE, 0xFACC, 0x64D2, 0x9DA0, - 0x64D4, 0x9D5E, 0x64D8, 0x9DA4, 0x64DA, 0x9D9F, 0x64E0, 0x9DA9, 0x64E1, 0x9DAA, 0x64E2, 0x9346, 0x64E3, 0x9DAC, 0x64E6, 0x8E43, - 0x64E7, 0x9DA7, 0x64EC, 0x8B5B, 0x64EF, 0x9DAD, 0x64F1, 0x9DA6, 0x64F2, 0x9DB1, 0x64F4, 0x9DB0, 0x64F6, 0x9DAF, 0x64FA, 0x9DB2, - 0x64FD, 0x9DB4, 0x64FE, 0x8FEF, 0x6500, 0x9DB3, 0x6505, 0x9DB7, 0x6518, 0x9DB5, 0x651C, 0x9DB6, 0x651D, 0x9D90, 0x6523, 0x9DB9, - 0x6524, 0x9DB8, 0x652A, 0x9D98, 0x652B, 0x9DBA, 0x652C, 0x9DAE, 0x652F, 0x8E78, 0x6534, 0x9DBB, 0x6535, 0x9DBC, 0x6536, 0x9DBE, - 0x6537, 0x9DBD, 0x6538, 0x9DBF, 0x6539, 0x89FC, 0x653B, 0x8D55, 0x653E, 0x95FA, 0x653F, 0x90AD, 0x6545, 0x8CCC, 0x6548, 0x9DC1, - 0x654D, 0x9DC4, 0x654E, 0xFACD, 0x654F, 0x9571, 0x6551, 0x8B7E, 0x6555, 0x9DC3, 0x6556, 0x9DC2, 0x6557, 0x9473, 0x6558, 0x9DC5, - 0x6559, 0x8BB3, 0x655D, 0x9DC7, 0x655E, 0x9DC6, 0x6562, 0x8AB8, 0x6563, 0x8E55, 0x6566, 0x93D6, 0x656C, 0x8C68, 0x6570, 0x9094, - 0x6572, 0x9DC8, 0x6574, 0x90AE, 0x6575, 0x9347, 0x6577, 0x957E, 0x6578, 0x9DC9, 0x6582, 0x9DCA, 0x6583, 0x9DCB, 0x6587, 0x95B6, - 0x6588, 0x9B7C, 0x6589, 0x90C4, 0x658C, 0x956B, 0x658E, 0x8DD6, 0x6590, 0x94E3, 0x6591, 0x94C1, 0x6597, 0x936C, 0x6599, 0x97BF, - 0x659B, 0x9DCD, 0x659C, 0x8ECE, 0x659F, 0x9DCE, 0x65A1, 0x88B4, 0x65A4, 0x8BD2, 0x65A5, 0x90CB, 0x65A7, 0x9580, 0x65AB, 0x9DCF, - 0x65AC, 0x8E61, 0x65AD, 0x9266, 0x65AF, 0x8E7A, 0x65B0, 0x9056, 0x65B7, 0x9DD0, 0x65B9, 0x95FB, 0x65BC, 0x8997, 0x65BD, 0x8E7B, - 0x65C1, 0x9DD3, 0x65C3, 0x9DD1, 0x65C4, 0x9DD4, 0x65C5, 0x97B7, 0x65C6, 0x9DD2, 0x65CB, 0x90F9, 0x65CC, 0x9DD5, 0x65CF, 0x91B0, - 0x65D2, 0x9DD6, 0x65D7, 0x8AF8, 0x65D9, 0x9DD8, 0x65DB, 0x9DD7, 0x65E0, 0x9DD9, 0x65E1, 0x9DDA, 0x65E2, 0x8AF9, 0x65E5, 0x93FA, - 0x65E6, 0x9255, 0x65E7, 0x8B8C, 0x65E8, 0x8E7C, 0x65E9, 0x9181, 0x65EC, 0x8F7B, 0x65ED, 0x88AE, 0x65F1, 0x9DDB, 0x65FA, 0x89A0, - 0x65FB, 0x9DDF, 0x6600, 0xFACE, 0x6602, 0x8D56, 0x6603, 0x9DDE, 0x6606, 0x8DA9, 0x6607, 0x8FB8, 0x6609, 0xFAD1, 0x660A, 0x9DDD, - 0x660C, 0x8FB9, 0x660E, 0x96BE, 0x660F, 0x8DA8, 0x6613, 0x88D5, 0x6614, 0x90CC, 0x6615, 0xFACF, 0x661C, 0x9DE4, 0x661E, 0xFAD3, - 0x661F, 0x90AF, 0x6620, 0x8966, 0x6624, 0xFAD4, 0x6625, 0x8F74, 0x6627, 0x9686, 0x6628, 0x8DF0, 0x662D, 0x8FBA, 0x662E, 0xFAD2, - 0x662F, 0x90A5, 0x6631, 0xFA63, 0x6634, 0x9DE3, 0x6635, 0x9DE1, 0x6636, 0x9DE2, 0x663B, 0xFAD0, 0x663C, 0x928B, 0x663F, 0x9E45, - 0x6641, 0x9DE8, 0x6642, 0x8E9E, 0x6643, 0x8D57, 0x6644, 0x9DE6, 0x6649, 0x9DE7, 0x664B, 0x9057, 0x664F, 0x9DE5, 0x6652, 0x8E4E, - 0x6657, 0xFAD6, 0x6659, 0xFAD7, 0x665D, 0x9DEA, 0x665E, 0x9DE9, 0x665F, 0x9DEE, 0x6662, 0x9DEF, 0x6664, 0x9DEB, 0x6665, 0xFAD5, - 0x6666, 0x8A41, 0x6667, 0x9DEC, 0x6668, 0x9DED, 0x6669, 0x94D3, 0x666E, 0x9581, 0x666F, 0x8C69, 0x6670, 0x9DF0, 0x6673, 0xFAD9, - 0x6674, 0x90B0, 0x6676, 0x8FBB, 0x667A, 0x9271, 0x6681, 0x8BC5, 0x6683, 0x9DF1, 0x6684, 0x9DF5, 0x6687, 0x89C9, 0x6688, 0x9DF2, - 0x6689, 0x9DF4, 0x668E, 0x9DF3, 0x6691, 0x8F8B, 0x6696, 0x9267, 0x6697, 0x88C3, 0x6698, 0x9DF6, 0x6699, 0xFADA, 0x669D, 0x9DF7, - 0x66A0, 0xFADB, 0x66A2, 0x92A8, 0x66A6, 0x97EF, 0x66AB, 0x8E62, 0x66AE, 0x95E9, 0x66B2, 0xFADC, 0x66B4, 0x965C, 0x66B8, 0x9E41, - 0x66B9, 0x9DF9, 0x66BC, 0x9DFC, 0x66BE, 0x9DFB, 0x66BF, 0xFADD, 0x66C1, 0x9DF8, 0x66C4, 0x9E40, 0x66C7, 0x93DC, 0x66C9, 0x9DFA, - 0x66D6, 0x9E42, 0x66D9, 0x8F8C, 0x66DA, 0x9E43, 0x66DC, 0x976A, 0x66DD, 0x9498, 0x66E0, 0x9E44, 0x66E6, 0x9E46, 0x66E9, 0x9E47, - 0x66F0, 0x9E48, 0x66F2, 0x8BC8, 0x66F3, 0x8967, 0x66F4, 0x8D58, 0x66F5, 0x9E49, 0x66F7, 0x9E4A, 0x66F8, 0x8F91, 0x66F9, 0x9182, - 0x66FA, 0xFADE, 0x66FB, 0xFA66, 0x66FC, 0x99D6, 0x66FD, 0x915D, 0x66FE, 0x915C, 0x66FF, 0x91D6, 0x6700, 0x8DC5, 0x6703, 0x98F0, - 0x6708, 0x8C8E, 0x6709, 0x974C, 0x670B, 0x95FC, 0x670D, 0x959E, 0x670E, 0xFADF, 0x670F, 0x9E4B, 0x6714, 0x8DF1, 0x6715, 0x92BD, - 0x6716, 0x9E4C, 0x6717, 0x984E, 0x671B, 0x965D, 0x671D, 0x92A9, 0x671E, 0x9E4D, 0x671F, 0x8AFA, 0x6726, 0x9E4E, 0x6727, 0x9E4F, - 0x6728, 0x96D8, 0x672A, 0x96A2, 0x672B, 0x9696, 0x672C, 0x967B, 0x672D, 0x8E44, 0x672E, 0x9E51, 0x6731, 0x8EE9, 0x6734, 0x9670, - 0x6736, 0x9E53, 0x6737, 0x9E56, 0x6738, 0x9E55, 0x673A, 0x8AF7, 0x673D, 0x8B80, 0x673F, 0x9E52, 0x6741, 0x9E54, 0x6746, 0x9E57, - 0x6749, 0x9099, 0x674E, 0x979B, 0x674F, 0x88C7, 0x6750, 0x8DDE, 0x6751, 0x91BA, 0x6753, 0x8EDB, 0x6756, 0x8FF1, 0x6759, 0x9E5A, - 0x675C, 0x936D, 0x675E, 0x9E58, 0x675F, 0x91A9, 0x6760, 0x9E59, 0x6761, 0x8FF0, 0x6762, 0x96DB, 0x6763, 0x9E5B, 0x6764, 0x9E5C, - 0x6765, 0x9788, 0x6766, 0xFAE1, 0x676A, 0x9E61, 0x676D, 0x8D59, 0x676F, 0x9474, 0x6770, 0x9E5E, 0x6771, 0x938C, 0x6772, 0x9DDC, - 0x6773, 0x9DE0, 0x6775, 0x8B6E, 0x6777, 0x9466, 0x677C, 0x9E60, 0x677E, 0x8FBC, 0x677F, 0x94C2, 0x6785, 0x9E66, 0x6787, 0x94F8, - 0x6789, 0x9E5D, 0x678B, 0x9E63, 0x678C, 0x9E62, 0x6790, 0x90CD, 0x6795, 0x968D, 0x6797, 0x97D1, 0x679A, 0x9687, 0x679C, 0x89CA, - 0x679D, 0x8E7D, 0x67A0, 0x9867, 0x67A1, 0x9E65, 0x67A2, 0x9095, 0x67A6, 0x9E64, 0x67A9, 0x9E5F, 0x67AF, 0x8CCD, 0x67B3, 0x9E6B, - 0x67B4, 0x9E69, 0x67B6, 0x89CB, 0x67B7, 0x9E67, 0x67B8, 0x9E6D, 0x67B9, 0x9E73, 0x67BB, 0xFAE2, 0x67C0, 0xFAE4, 0x67C1, 0x91C6, - 0x67C4, 0x95BF, 0x67C6, 0x9E75, 0x67CA, 0x9541, 0x67CE, 0x9E74, 0x67CF, 0x9490, 0x67D0, 0x965E, 0x67D1, 0x8AB9, 0x67D3, 0x90F5, - 0x67D4, 0x8F5F, 0x67D8, 0x92D1, 0x67DA, 0x974D, 0x67DD, 0x9E70, 0x67DE, 0x9E6F, 0x67E2, 0x9E71, 0x67E4, 0x9E6E, 0x67E7, 0x9E76, - 0x67E9, 0x9E6C, 0x67EC, 0x9E6A, 0x67EE, 0x9E72, 0x67EF, 0x9E68, 0x67F1, 0x928C, 0x67F3, 0x96F6, 0x67F4, 0x8EC4, 0x67F5, 0x8DF2, - 0x67FB, 0x8DB8, 0x67FE, 0x968F, 0x67FF, 0x8A60, 0x6801, 0xFAE5, 0x6802, 0x92CC, 0x6803, 0x93C8, 0x6804, 0x8968, 0x6813, 0x90F0, - 0x6816, 0x90B2, 0x6817, 0x8C49, 0x681E, 0x9E78, 0x6821, 0x8D5A, 0x6822, 0x8A9C, 0x6829, 0x9E7A, 0x682A, 0x8A94, 0x682B, 0x9E81, - 0x6832, 0x9E7D, 0x6834, 0x90F1, 0x6838, 0x8A6A, 0x6839, 0x8DAA, 0x683C, 0x8A69, 0x683D, 0x8DCD, 0x6840, 0x9E7B, 0x6841, 0x8C85, - 0x6842, 0x8C6A, 0x6843, 0x938D, 0x6844, 0xFAE6, 0x6846, 0x9E79, 0x6848, 0x88C4, 0x684D, 0x9E7C, 0x684E, 0x9E7E, 0x6850, 0x8BCB, - 0x6851, 0x8C4B, 0x6852, 0xFAE3, 0x6853, 0x8ABA, 0x6854, 0x8B6A, 0x6859, 0x9E82, 0x685C, 0x8DF7, 0x685D, 0x9691, 0x685F, 0x8E56, - 0x6863, 0x9E83, 0x6867, 0x954F, 0x6874, 0x9E8F, 0x6876, 0x89B1, 0x6877, 0x9E84, 0x687E, 0x9E95, 0x687F, 0x9E85, 0x6881, 0x97C0, - 0x6883, 0x9E8C, 0x6885, 0x947E, 0x688D, 0x9E94, 0x688F, 0x9E87, 0x6893, 0x88B2, 0x6894, 0x9E89, 0x6897, 0x8D5B, 0x689B, 0x9E8B, - 0x689D, 0x9E8A, 0x689F, 0x9E86, 0x68A0, 0x9E91, 0x68A2, 0x8FBD, 0x68A6, 0x9AEB, 0x68A7, 0x8CE6, 0x68A8, 0x979C, 0x68AD, 0x9E88, - 0x68AF, 0x92F2, 0x68B0, 0x8A42, 0x68B1, 0x8DAB, 0x68B3, 0x9E80, 0x68B5, 0x9E90, 0x68B6, 0x8A81, 0x68B9, 0x9E8E, 0x68BA, 0x9E92, - 0x68BC, 0x938E, 0x68C4, 0x8AFC, 0x68C6, 0x9EB0, 0x68C8, 0xFA64, 0x68C9, 0x96C7, 0x68CA, 0x9E97, 0x68CB, 0x8AFB, 0x68CD, 0x9E9E, - 0x68CF, 0xFAE7, 0x68D2, 0x965F, 0x68D4, 0x9E9F, 0x68D5, 0x9EA1, 0x68D7, 0x9EA5, 0x68D8, 0x9E99, 0x68DA, 0x9249, 0x68DF, 0x938F, - 0x68E0, 0x9EA9, 0x68E1, 0x9E9C, 0x68E3, 0x9EA6, 0x68E7, 0x9EA0, 0x68EE, 0x9058, 0x68EF, 0x9EAA, 0x68F2, 0x90B1, 0x68F9, 0x9EA8, - 0x68FA, 0x8ABB, 0x6900, 0x986F, 0x6901, 0x9E96, 0x6904, 0x9EA4, 0x6905, 0x88D6, 0x6908, 0x9E98, 0x690B, 0x96B8, 0x690C, 0x9E9D, - 0x690D, 0x9041, 0x690E, 0x92C5, 0x690F, 0x9E93, 0x6912, 0x9EA3, 0x6919, 0x909A, 0x691A, 0x9EAD, 0x691B, 0x8A91, 0x691C, 0x8C9F, - 0x6921, 0x9EAF, 0x6922, 0x9E9A, 0x6923, 0x9EAE, 0x6925, 0x9EA7, 0x6926, 0x9E9B, 0x6928, 0x9EAB, 0x692A, 0x9EAC, 0x6930, 0x9EBD, - 0x6934, 0x93CC, 0x6936, 0x9EA2, 0x6939, 0x9EB9, 0x693D, 0x9EBB, 0x693F, 0x92D6, 0x694A, 0x976B, 0x6953, 0x9596, 0x6954, 0x9EB6, - 0x6955, 0x91C8, 0x6959, 0x9EBC, 0x695A, 0x915E, 0x695C, 0x9EB3, 0x695D, 0x9EC0, 0x695E, 0x9EBF, 0x6960, 0x93ED, 0x6961, 0x9EBE, - 0x6962, 0x93E8, 0x6968, 0xFAE9, 0x696A, 0x9EC2, 0x696B, 0x9EB5, 0x696D, 0x8BC6, 0x696E, 0x9EB8, 0x696F, 0x8F7C, 0x6973, 0x9480, - 0x6974, 0x9EBA, 0x6975, 0x8BC9, 0x6977, 0x9EB2, 0x6978, 0x9EB4, 0x6979, 0x9EB1, 0x697C, 0x984F, 0x697D, 0x8A79, 0x697E, 0x9EB7, - 0x6981, 0x9EC1, 0x6982, 0x8A54, 0x698A, 0x8DE5, 0x698E, 0x897C, 0x6991, 0x9ED2, 0x6994, 0x9850, 0x6995, 0x9ED5, 0x6998, 0xFAEB, - 0x699B, 0x9059, 0x699C, 0x9ED4, 0x69A0, 0x9ED3, 0x69A7, 0x9ED0, 0x69AE, 0x9EC4, 0x69B1, 0x9EE1, 0x69B2, 0x9EC3, 0x69B4, 0x9ED6, - 0x69BB, 0x9ECE, 0x69BE, 0x9EC9, 0x69BF, 0x9EC6, 0x69C1, 0x9EC7, 0x69C3, 0x9ECF, 0x69C7, 0xEAA0, 0x69CA, 0x9ECC, 0x69CB, 0x8D5C, - 0x69CC, 0x92C6, 0x69CD, 0x9184, 0x69CE, 0x9ECA, 0x69D0, 0x9EC5, 0x69D3, 0x9EC8, 0x69D8, 0x976C, 0x69D9, 0x968A, 0x69DD, 0x9ECD, - 0x69DE, 0x9ED7, 0x69E2, 0xFAEC, 0x69E7, 0x9EDF, 0x69E8, 0x9ED8, 0x69EB, 0x9EE5, 0x69ED, 0x9EE3, 0x69F2, 0x9EDE, 0x69F9, 0x9EDD, - 0x69FB, 0x92CE, 0x69FD, 0x9185, 0x69FF, 0x9EDB, 0x6A02, 0x9ED9, 0x6A05, 0x9EE0, 0x6A0A, 0x9EE6, 0x6A0B, 0x94F3, 0x6A0C, 0x9EEC, - 0x6A12, 0x9EE7, 0x6A13, 0x9EEA, 0x6A14, 0x9EE4, 0x6A17, 0x9294, 0x6A19, 0x9557, 0x6A1B, 0x9EDA, 0x6A1E, 0x9EE2, 0x6A1F, 0x8FBE, - 0x6A21, 0x96CD, 0x6A22, 0x9EF6, 0x6A23, 0x9EE9, 0x6A29, 0x8CA0, 0x6A2A, 0x89A1, 0x6A2B, 0x8A7E, 0x6A2E, 0x9ED1, 0x6A30, 0xFAED, - 0x6A35, 0x8FBF, 0x6A36, 0x9EEE, 0x6A38, 0x9EF5, 0x6A39, 0x8EF7, 0x6A3A, 0x8A92, 0x6A3D, 0x924D, 0x6A44, 0x9EEB, 0x6A46, 0xFAEF, - 0x6A47, 0x9EF0, 0x6A48, 0x9EF4, 0x6A4B, 0x8BB4, 0x6A58, 0x8B6B, 0x6A59, 0x9EF2, 0x6A5F, 0x8B40, 0x6A61, 0x93C9, 0x6A62, 0x9EF1, - 0x6A66, 0x9EF3, 0x6A6B, 0xFAEE, 0x6A72, 0x9EED, 0x6A73, 0xFAF0, 0x6A78, 0x9EEF, 0x6A7E, 0xFAF1, 0x6A7F, 0x8A80, 0x6A80, 0x9268, - 0x6A84, 0x9EFA, 0x6A8D, 0x9EF8, 0x6A8E, 0x8CE7, 0x6A90, 0x9EF7, 0x6A97, 0x9F40, 0x6A9C, 0x9E77, 0x6AA0, 0x9EF9, 0x6AA2, 0x9EFB, - 0x6AA3, 0x9EFC, 0x6AAA, 0x9F4B, 0x6AAC, 0x9F47, 0x6AAE, 0x9E8D, 0x6AB3, 0x9F46, 0x6AB8, 0x9F45, 0x6ABB, 0x9F42, 0x6AC1, 0x9EE8, - 0x6AC2, 0x9F44, 0x6AC3, 0x9F43, 0x6AD1, 0x9F49, 0x6AD3, 0x9845, 0x6ADA, 0x9F4C, 0x6ADB, 0x8BF9, 0x6ADE, 0x9F48, 0x6ADF, 0x9F4A, - 0x6AE2, 0xFAF2, 0x6AE4, 0xFAF3, 0x6AE8, 0x94A5, 0x6AEA, 0x9F4D, 0x6AFA, 0x9F51, 0x6AFB, 0x9F4E, 0x6B04, 0x9793, 0x6B05, 0x9F4F, - 0x6B0A, 0x9EDC, 0x6B12, 0x9F52, 0x6B16, 0x9F53, 0x6B1D, 0x8954, 0x6B1F, 0x9F55, 0x6B20, 0x8C87, 0x6B21, 0x8E9F, 0x6B23, 0x8BD3, - 0x6B27, 0x89A2, 0x6B32, 0x977E, 0x6B37, 0x9F57, 0x6B38, 0x9F56, 0x6B39, 0x9F59, 0x6B3A, 0x8B5C, 0x6B3D, 0x8BD4, 0x6B3E, 0x8ABC, - 0x6B43, 0x9F5C, 0x6B47, 0x9F5B, 0x6B49, 0x9F5D, 0x6B4C, 0x89CC, 0x6B4E, 0x9256, 0x6B50, 0x9F5E, 0x6B53, 0x8ABD, 0x6B54, 0x9F60, - 0x6B59, 0x9F5F, 0x6B5B, 0x9F61, 0x6B5F, 0x9F62, 0x6B61, 0x9F63, 0x6B62, 0x8E7E, 0x6B63, 0x90B3, 0x6B64, 0x8D9F, 0x6B66, 0x9590, - 0x6B69, 0x95E0, 0x6B6A, 0x9863, 0x6B6F, 0x8E95, 0x6B73, 0x8DCE, 0x6B74, 0x97F0, 0x6B78, 0x9F64, 0x6B79, 0x9F65, 0x6B7B, 0x8E80, - 0x6B7F, 0x9F66, 0x6B80, 0x9F67, 0x6B83, 0x9F69, 0x6B84, 0x9F68, 0x6B86, 0x9677, 0x6B89, 0x8F7D, 0x6B8A, 0x8EEA, 0x6B8B, 0x8E63, - 0x6B8D, 0x9F6A, 0x6B95, 0x9F6C, 0x6B96, 0x9042, 0x6B98, 0x9F6B, 0x6B9E, 0x9F6D, 0x6BA4, 0x9F6E, 0x6BAA, 0x9F6F, 0x6BAB, 0x9F70, - 0x6BAF, 0x9F71, 0x6BB1, 0x9F73, 0x6BB2, 0x9F72, 0x6BB3, 0x9F74, 0x6BB4, 0x89A3, 0x6BB5, 0x9269, 0x6BB7, 0x9F75, 0x6BBA, 0x8E45, - 0x6BBB, 0x8A6B, 0x6BBC, 0x9F76, 0x6BBF, 0x9361, 0x6BC0, 0x9ACA, 0x6BC5, 0x8B42, 0x6BC6, 0x9F77, 0x6BCB, 0x9F78, 0x6BCD, 0x95EA, - 0x6BCE, 0x9688, 0x6BD2, 0x93C5, 0x6BD3, 0x9F79, 0x6BD4, 0x94E4, 0x6BD6, 0xFAF4, 0x6BD8, 0x94F9, 0x6BDB, 0x96D1, 0x6BDF, 0x9F7A, - 0x6BEB, 0x9F7C, 0x6BEC, 0x9F7B, 0x6BEF, 0x9F7E, 0x6BF3, 0x9F7D, 0x6C08, 0x9F81, 0x6C0F, 0x8E81, 0x6C11, 0x96AF, 0x6C13, 0x9F82, - 0x6C14, 0x9F83, 0x6C17, 0x8B43, 0x6C1B, 0x9F84, 0x6C23, 0x9F86, 0x6C24, 0x9F85, 0x6C34, 0x9085, 0x6C37, 0x9558, 0x6C38, 0x8969, - 0x6C3E, 0x94C3, 0x6C3F, 0xFAF5, 0x6C40, 0x92F3, 0x6C41, 0x8F60, 0x6C42, 0x8B81, 0x6C4E, 0x94C4, 0x6C50, 0x8EAC, 0x6C55, 0x9F88, - 0x6C57, 0x8ABE, 0x6C5A, 0x8998, 0x6C5C, 0xFAF6, 0x6C5D, 0x93F0, 0x6C5E, 0x9F87, 0x6C5F, 0x8D5D, 0x6C60, 0x9272, 0x6C62, 0x9F89, - 0x6C68, 0x9F91, 0x6C6A, 0x9F8A, 0x6C6F, 0xFAF8, 0x6C70, 0x91BF, 0x6C72, 0x8B82, 0x6C73, 0x9F92, 0x6C7A, 0x8C88, 0x6C7D, 0x8B44, - 0x6C7E, 0x9F90, 0x6C81, 0x9F8E, 0x6C82, 0x9F8B, 0x6C83, 0x9780, 0x6C86, 0xFAF7, 0x6C88, 0x92BE, 0x6C8C, 0x93D7, 0x6C8D, 0x9F8C, - 0x6C90, 0x9F94, 0x6C92, 0x9F93, 0x6C93, 0x8C42, 0x6C96, 0x89AB, 0x6C99, 0x8DB9, 0x6C9A, 0x9F8D, 0x6C9B, 0x9F8F, 0x6CA1, 0x9676, - 0x6CA2, 0x91F2, 0x6CAB, 0x9697, 0x6CAE, 0x9F9C, 0x6CB1, 0x9F9D, 0x6CB3, 0x89CD, 0x6CB8, 0x95A6, 0x6CB9, 0x96FB, 0x6CBA, 0x9F9F, - 0x6CBB, 0x8EA1, 0x6CBC, 0x8FC0, 0x6CBD, 0x9F98, 0x6CBE, 0x9F9E, 0x6CBF, 0x8988, 0x6CC1, 0x8BB5, 0x6CC4, 0x9F95, 0x6CC5, 0x9F9A, - 0x6CC9, 0x90F2, 0x6CCA, 0x9491, 0x6CCC, 0x94E5, 0x6CD3, 0x9F97, 0x6CD5, 0x9640, 0x6CD7, 0x9F99, 0x6CD9, 0x9FA2, 0x6CDA, 0xFAF9, - 0x6CDB, 0x9FA0, 0x6CDD, 0x9F9B, 0x6CE1, 0x9641, 0x6CE2, 0x9467, 0x6CE3, 0x8B83, 0x6CE5, 0x9344, 0x6CE8, 0x928D, 0x6CEA, 0x9FA3, - 0x6CEF, 0x9FA1, 0x6CF0, 0x91D7, 0x6CF1, 0x9F96, 0x6CF3, 0x896A, 0x6D04, 0xFAFA, 0x6D0B, 0x976D, 0x6D0C, 0x9FAE, 0x6D12, 0x9FAD, - 0x6D17, 0x90F4, 0x6D19, 0x9FAA, 0x6D1B, 0x978C, 0x6D1E, 0x93B4, 0x6D1F, 0x9FA4, 0x6D25, 0x92C3, 0x6D29, 0x896B, 0x6D2A, 0x8D5E, - 0x6D2B, 0x9FA7, 0x6D32, 0x8F46, 0x6D33, 0x9FAC, 0x6D35, 0x9FAB, 0x6D36, 0x9FA6, 0x6D38, 0x9FA9, 0x6D3B, 0x8A88, 0x6D3D, 0x9FA8, - 0x6D3E, 0x9468, 0x6D41, 0x97AC, 0x6D44, 0x8FF2, 0x6D45, 0x90F3, 0x6D59, 0x9FB4, 0x6D5A, 0x9FB2, 0x6D5C, 0x956C, 0x6D63, 0x9FAF, - 0x6D64, 0x9FB1, 0x6D66, 0x8959, 0x6D69, 0x8D5F, 0x6D6A, 0x9851, 0x6D6C, 0x8A5C, 0x6D6E, 0x9582, 0x6D6F, 0xFAFC, 0x6D74, 0x9781, - 0x6D77, 0x8A43, 0x6D78, 0x905A, 0x6D79, 0x9FB3, 0x6D85, 0x9FB8, 0x6D87, 0xFAFB, 0x6D88, 0x8FC1, 0x6D8C, 0x974F, 0x6D8E, 0x9FB5, - 0x6D93, 0x9FB0, 0x6D95, 0x9FB6, 0x6D96, 0xFB40, 0x6D99, 0x97DC, 0x6D9B, 0x9393, 0x6D9C, 0x93C0, 0x6DAC, 0xFB41, 0x6DAF, 0x8A55, - 0x6DB2, 0x8974, 0x6DB5, 0x9FBC, 0x6DB8, 0x9FBF, 0x6DBC, 0x97C1, 0x6DC0, 0x9784, 0x6DC5, 0x9FC6, 0x6DC6, 0x9FC0, 0x6DC7, 0x9FBD, - 0x6DCB, 0x97D2, 0x6DCC, 0x9FC3, 0x6DCF, 0xFB42, 0x6DD1, 0x8F69, 0x6DD2, 0x9FC5, 0x6DD5, 0x9FCA, 0x6DD8, 0x9391, 0x6DD9, 0x9FC8, - 0x6DDE, 0x9FC2, 0x6DE1, 0x9257, 0x6DE4, 0x9FC9, 0x6DE6, 0x9FBE, 0x6DE8, 0x9FC4, 0x6DEA, 0x9FCB, 0x6DEB, 0x88FA, 0x6DEC, 0x9FC1, - 0x6DEE, 0x9FCC, 0x6DF1, 0x905B, 0x6DF2, 0xFB44, 0x6DF3, 0x8F7E, 0x6DF5, 0x95A3, 0x6DF7, 0x8DAC, 0x6DF8, 0xFB43, 0x6DF9, 0x9FB9, - 0x6DFA, 0x9FC7, 0x6DFB, 0x9359, 0x6DFC, 0xFB45, 0x6E05, 0x90B4, 0x6E07, 0x8A89, 0x6E08, 0x8DCF, 0x6E09, 0x8FC2, 0x6E0A, 0x9FBB, - 0x6E0B, 0x8F61, 0x6E13, 0x8C6B, 0x6E15, 0x9FBA, 0x6E19, 0x9FD0, 0x6E1A, 0x8F8D, 0x6E1B, 0x8CB8, 0x6E1D, 0x9FDF, 0x6E1F, 0x9FD9, - 0x6E20, 0x8B94, 0x6E21, 0x936E, 0x6E23, 0x9FD4, 0x6E24, 0x9FDD, 0x6E25, 0x88AD, 0x6E26, 0x8951, 0x6E27, 0xFB48, 0x6E29, 0x89B7, - 0x6E2B, 0x9FD6, 0x6E2C, 0x91AA, 0x6E2D, 0x9FCD, 0x6E2E, 0x9FCF, 0x6E2F, 0x8D60, 0x6E38, 0x9FE0, 0x6E39, 0xFB46, 0x6E3A, 0x9FDB, - 0x6E3C, 0xFB49, 0x6E3E, 0x9FD3, 0x6E43, 0x9FDA, 0x6E4A, 0x96A9, 0x6E4D, 0x9FD8, 0x6E4E, 0x9FDC, 0x6E56, 0x8CCE, 0x6E58, 0x8FC3, - 0x6E5B, 0x9258, 0x6E5C, 0xFB47, 0x6E5F, 0x9FD2, 0x6E67, 0x974E, 0x6E6B, 0x9FD5, 0x6E6E, 0x9FCE, 0x6E6F, 0x9392, 0x6E72, 0x9FD1, - 0x6E76, 0x9FD7, 0x6E7E, 0x9870, 0x6E7F, 0x8EBC, 0x6E80, 0x969E, 0x6E82, 0x9FE1, 0x6E8C, 0x94AC, 0x6E8F, 0x9FED, 0x6E90, 0x8CB9, - 0x6E96, 0x8F80, 0x6E98, 0x9FE3, 0x6E9C, 0x97AD, 0x6E9D, 0x8D61, 0x6E9F, 0x9FF0, 0x6EA2, 0x88EC, 0x6EA5, 0x9FEE, 0x6EAA, 0x9FE2, - 0x6EAF, 0x9FE8, 0x6EB2, 0x9FEA, 0x6EB6, 0x976E, 0x6EB7, 0x9FE5, 0x6EBA, 0x934D, 0x6EBD, 0x9FE7, 0x6EBF, 0xFB4A, 0x6EC2, 0x9FEF, - 0x6EC4, 0x9FE9, 0x6EC5, 0x96C5, 0x6EC9, 0x9FE4, 0x6ECB, 0x8EA0, 0x6ECC, 0x9FFC, 0x6ED1, 0x8A8A, 0x6ED3, 0x9FE6, 0x6ED4, 0x9FEB, - 0x6ED5, 0x9FEC, 0x6EDD, 0x91EA, 0x6EDE, 0x91D8, 0x6EEC, 0x9FF4, 0x6EEF, 0x9FFA, 0x6EF2, 0x9FF8, 0x6EF4, 0x9348, 0x6EF7, 0xE042, - 0x6EF8, 0x9FF5, 0x6EFE, 0x9FF6, 0x6EFF, 0x9FDE, 0x6F01, 0x8B99, 0x6F02, 0x9559, 0x6F06, 0x8EBD, 0x6F09, 0x8D97, 0x6F0F, 0x9852, - 0x6F11, 0x9FF2, 0x6F13, 0xE041, 0x6F14, 0x8989, 0x6F15, 0x9186, 0x6F20, 0x9499, 0x6F22, 0x8ABF, 0x6F23, 0x97F8, 0x6F2B, 0x969F, - 0x6F2C, 0x92D0, 0x6F31, 0x9FF9, 0x6F32, 0x9FFB, 0x6F38, 0x9151, 0x6F3E, 0xE040, 0x6F3F, 0x9FF7, 0x6F41, 0x9FF1, 0x6F45, 0x8AC1, - 0x6F54, 0x8C89, 0x6F58, 0xE04E, 0x6F5B, 0xE049, 0x6F5C, 0x90F6, 0x6F5F, 0x8A83, 0x6F64, 0x8F81, 0x6F66, 0xE052, 0x6F6D, 0xE04B, - 0x6F6E, 0x92AA, 0x6F6F, 0xE048, 0x6F70, 0x92D7, 0x6F74, 0xE06B, 0x6F78, 0xE045, 0x6F7A, 0xE044, 0x6F7C, 0xE04D, 0x6F80, 0xE047, - 0x6F81, 0xE046, 0x6F82, 0xE04C, 0x6F84, 0x909F, 0x6F86, 0xE043, 0x6F88, 0xFB4B, 0x6F8E, 0xE04F, 0x6F91, 0xE050, 0x6F97, 0x8AC0, - 0x6FA1, 0xE055, 0x6FA3, 0xE054, 0x6FA4, 0xE056, 0x6FAA, 0xE059, 0x6FB1, 0x9362, 0x6FB3, 0xE053, 0x6FB5, 0xFB4C, 0x6FB9, 0xE057, - 0x6FC0, 0x8C83, 0x6FC1, 0x91F7, 0x6FC2, 0xE051, 0x6FC3, 0x945A, 0x6FC6, 0xE058, 0x6FD4, 0xE05D, 0x6FD5, 0xE05B, 0x6FD8, 0xE05E, - 0x6FDB, 0xE061, 0x6FDF, 0xE05A, 0x6FE0, 0x8D8A, 0x6FE1, 0x9447, 0x6FE4, 0x9FB7, 0x6FEB, 0x9794, 0x6FEC, 0xE05C, 0x6FEE, 0xE060, - 0x6FEF, 0x91F3, 0x6FF1, 0xE05F, 0x6FF3, 0xE04A, 0x6FF5, 0xFB4D, 0x6FF6, 0xE889, 0x6FFA, 0xE064, 0x6FFE, 0xE068, 0x7001, 0xE066, - 0x7005, 0xFB4E, 0x7007, 0xFB4F, 0x7009, 0xE062, 0x700B, 0xE063, 0x700F, 0xE067, 0x7011, 0xE065, 0x7015, 0x956D, 0x7018, 0xE06D, - 0x701A, 0xE06A, 0x701B, 0xE069, 0x701D, 0xE06C, 0x701E, 0x93D2, 0x701F, 0xE06E, 0x7026, 0x9295, 0x7027, 0x91EB, 0x7028, 0xFB50, - 0x702C, 0x90A3, 0x7030, 0xE06F, 0x7032, 0xE071, 0x703E, 0xE070, 0x704C, 0x9FF3, 0x7051, 0xE072, 0x7058, 0x93E5, 0x7063, 0xE073, - 0x706B, 0x89CE, 0x706F, 0x9394, 0x7070, 0x8A44, 0x7078, 0x8B84, 0x707C, 0x8EDC, 0x707D, 0x8DD0, 0x7085, 0xFB51, 0x7089, 0x9846, - 0x708A, 0x9086, 0x708E, 0x898A, 0x7092, 0xE075, 0x7099, 0xE074, 0x70AB, 0xFB52, 0x70AC, 0xE078, 0x70AD, 0x9259, 0x70AE, 0xE07B, - 0x70AF, 0xE076, 0x70B3, 0xE07A, 0x70B8, 0xE079, 0x70B9, 0x935F, 0x70BA, 0x88D7, 0x70BB, 0xFA62, 0x70C8, 0x97F3, 0x70CB, 0xE07D, - 0x70CF, 0x8947, 0x70D9, 0xE080, 0x70DD, 0xE07E, 0x70DF, 0xE07C, 0x70F1, 0xE077, 0x70F9, 0x9642, 0x70FD, 0xE082, 0x7104, 0xFB54, - 0x7109, 0xE081, 0x710F, 0xFB53, 0x7114, 0x898B, 0x7119, 0xE084, 0x711A, 0x95B0, 0x711C, 0xE083, 0x7121, 0x96B3, 0x7126, 0x8FC5, - 0x7136, 0x9152, 0x713C, 0x8FC4, 0x7146, 0xFB56, 0x7147, 0xFB57, 0x7149, 0x97F9, 0x714C, 0xE08A, 0x714E, 0x90F7, 0x7155, 0xE086, - 0x7156, 0xE08B, 0x7159, 0x898C, 0x715C, 0xFB55, 0x7162, 0xE089, 0x7164, 0x9481, 0x7165, 0xE085, 0x7166, 0xE088, 0x7167, 0x8FC6, - 0x7169, 0x94CF, 0x716C, 0xE08C, 0x716E, 0x8ECF, 0x717D, 0x90F8, 0x7184, 0xE08F, 0x7188, 0xE087, 0x718A, 0x8C46, 0x718F, 0xE08D, - 0x7194, 0x976F, 0x7195, 0xE090, 0x7199, 0xEAA4, 0x719F, 0x8F6E, 0x71A8, 0xE091, 0x71AC, 0xE092, 0x71B1, 0x944D, 0x71B9, 0xE094, - 0x71BE, 0xE095, 0x71C1, 0xFB59, 0x71C3, 0x9452, 0x71C8, 0x9395, 0x71C9, 0xE097, 0x71CE, 0xE099, 0x71D0, 0x97D3, 0x71D2, 0xE096, - 0x71D4, 0xE098, 0x71D5, 0x898D, 0x71D7, 0xE093, 0x71DF, 0x9A7A, 0x71E0, 0xE09A, 0x71E5, 0x9187, 0x71E6, 0x8E57, 0x71E7, 0xE09C, - 0x71EC, 0xE09B, 0x71ED, 0x9043, 0x71EE, 0x99D7, 0x71F5, 0xE09D, 0x71F9, 0xE09F, 0x71FB, 0xE08E, 0x71FC, 0xE09E, 0x71FE, 0xFB5A, - 0x71FF, 0xE0A0, 0x7206, 0x949A, 0x720D, 0xE0A1, 0x7210, 0xE0A2, 0x721B, 0xE0A3, 0x7228, 0xE0A4, 0x722A, 0x92DC, 0x722C, 0xE0A6, - 0x722D, 0xE0A5, 0x7230, 0xE0A7, 0x7232, 0xE0A8, 0x7235, 0x8EDD, 0x7236, 0x9583, 0x723A, 0x96EA, 0x723B, 0xE0A9, 0x723C, 0xE0AA, - 0x723D, 0x9175, 0x723E, 0x8EA2, 0x723F, 0xE0AB, 0x7240, 0xE0AC, 0x7246, 0xE0AD, 0x7247, 0x95D0, 0x7248, 0x94C5, 0x724B, 0xE0AE, - 0x724C, 0x9476, 0x7252, 0x92AB, 0x7258, 0xE0AF, 0x7259, 0x89E5, 0x725B, 0x8B8D, 0x725D, 0x96C4, 0x725F, 0x96B4, 0x7261, 0x89B2, - 0x7262, 0x9853, 0x7267, 0x9671, 0x7269, 0x95A8, 0x7272, 0x90B5, 0x7274, 0xE0B0, 0x7279, 0x93C1, 0x727D, 0x8CA1, 0x727E, 0xE0B1, - 0x7280, 0x8DD2, 0x7281, 0xE0B3, 0x7282, 0xE0B2, 0x7287, 0xE0B4, 0x7292, 0xE0B5, 0x7296, 0xE0B6, 0x72A0, 0x8B5D, 0x72A2, 0xE0B7, - 0x72A7, 0xE0B8, 0x72AC, 0x8CA2, 0x72AF, 0x94C6, 0x72B1, 0xFB5B, 0x72B2, 0xE0BA, 0x72B6, 0x8FF3, 0x72B9, 0xE0B9, 0x72BE, 0xFB5C, - 0x72C2, 0x8BB6, 0x72C3, 0xE0BB, 0x72C4, 0xE0BD, 0x72C6, 0xE0BC, 0x72CE, 0xE0BE, 0x72D0, 0x8CCF, 0x72D2, 0xE0BF, 0x72D7, 0x8BE7, - 0x72D9, 0x915F, 0x72DB, 0x8D9D, 0x72E0, 0xE0C1, 0x72E1, 0xE0C2, 0x72E2, 0xE0C0, 0x72E9, 0x8EEB, 0x72EC, 0x93C6, 0x72ED, 0x8BB7, - 0x72F7, 0xE0C4, 0x72F8, 0x924B, 0x72F9, 0xE0C3, 0x72FC, 0x9854, 0x72FD, 0x9482, 0x730A, 0xE0C7, 0x7316, 0xE0C9, 0x7317, 0xE0C6, - 0x731B, 0x96D2, 0x731C, 0xE0C8, 0x731D, 0xE0CA, 0x731F, 0x97C2, 0x7324, 0xFB5D, 0x7325, 0xE0CE, 0x7329, 0xE0CD, 0x732A, 0x9296, - 0x732B, 0x944C, 0x732E, 0x8CA3, 0x732F, 0xE0CC, 0x7334, 0xE0CB, 0x7336, 0x9750, 0x7337, 0x9751, 0x733E, 0xE0CF, 0x733F, 0x898E, - 0x7344, 0x8D96, 0x7345, 0x8E82, 0x734E, 0xE0D0, 0x734F, 0xE0D1, 0x7357, 0xE0D3, 0x7363, 0x8F62, 0x7368, 0xE0D5, 0x736A, 0xE0D4, - 0x7370, 0xE0D6, 0x7372, 0x8A6C, 0x7375, 0xE0D8, 0x7377, 0xFB5F, 0x7378, 0xE0D7, 0x737A, 0xE0DA, 0x737B, 0xE0D9, 0x7384, 0x8CBA, - 0x7387, 0x97A6, 0x7389, 0x8BCA, 0x738B, 0x89A4, 0x7396, 0x8BE8, 0x73A9, 0x8ADF, 0x73B2, 0x97E6, 0x73B3, 0xE0DC, 0x73BB, 0xE0DE, - 0x73BD, 0xFB60, 0x73C0, 0xE0DF, 0x73C2, 0x89CF, 0x73C8, 0xE0DB, 0x73C9, 0xFB61, 0x73CA, 0x8E58, 0x73CD, 0x92BF, 0x73CE, 0xE0DD, - 0x73D2, 0xFB64, 0x73D6, 0xFB62, 0x73DE, 0xE0E2, 0x73E0, 0x8EEC, 0x73E3, 0xFB63, 0x73E5, 0xE0E0, 0x73EA, 0x8C5D, 0x73ED, 0x94C7, - 0x73EE, 0xE0E1, 0x73F1, 0xE0FC, 0x73F5, 0xFB66, 0x73F8, 0xE0E7, 0x73FE, 0x8CBB, 0x7403, 0x8B85, 0x7405, 0xE0E4, 0x7406, 0x979D, - 0x7407, 0xFB65, 0x7409, 0x97AE, 0x7422, 0x91F4, 0x7425, 0xE0E6, 0x7426, 0xFB67, 0x7429, 0xFB69, 0x742A, 0xFB68, 0x742E, 0xFB6A, - 0x7432, 0xE0E8, 0x7433, 0x97D4, 0x7434, 0x8BD5, 0x7435, 0x94FA, 0x7436, 0x9469, 0x743A, 0xE0E9, 0x743F, 0xE0EB, 0x7441, 0xE0EE, - 0x7455, 0xE0EA, 0x7459, 0xE0ED, 0x745A, 0x8CE8, 0x745B, 0x896C, 0x745C, 0xE0EF, 0x745E, 0x9090, 0x745F, 0xE0EC, 0x7460, 0x97DA, - 0x7462, 0xFB6B, 0x7463, 0xE0F2, 0x7464, 0xEAA2, 0x7469, 0xE0F0, 0x746A, 0xE0F3, 0x746F, 0xE0E5, 0x7470, 0xE0F1, 0x7473, 0x8DBA, - 0x7476, 0xE0F4, 0x747E, 0xE0F5, 0x7483, 0x979E, 0x7489, 0xFB6C, 0x748B, 0xE0F6, 0x749E, 0xE0F7, 0x749F, 0xFB6D, 0x74A2, 0xE0E3, - 0x74A7, 0xE0F8, 0x74B0, 0x8AC2, 0x74BD, 0x8EA3, 0x74CA, 0xE0F9, 0x74CF, 0xE0FA, 0x74D4, 0xE0FB, 0x74DC, 0x895A, 0x74E0, 0xE140, - 0x74E2, 0x955A, 0x74E3, 0xE141, 0x74E6, 0x8AA2, 0x74E7, 0xE142, 0x74E9, 0xE143, 0x74EE, 0xE144, 0x74F0, 0xE146, 0x74F1, 0xE147, - 0x74F2, 0xE145, 0x74F6, 0x9572, 0x74F7, 0xE149, 0x74F8, 0xE148, 0x7501, 0xFB6E, 0x7503, 0xE14B, 0x7504, 0xE14A, 0x7505, 0xE14C, - 0x750C, 0xE14D, 0x750D, 0xE14F, 0x750E, 0xE14E, 0x7511, 0x8D99, 0x7513, 0xE151, 0x7515, 0xE150, 0x7518, 0x8AC3, 0x751A, 0x9072, - 0x751C, 0x935B, 0x751E, 0xE152, 0x751F, 0x90B6, 0x7523, 0x8E59, 0x7525, 0x8999, 0x7526, 0xE153, 0x7528, 0x9770, 0x752B, 0x95E1, - 0x752C, 0xE154, 0x752F, 0xFAA8, 0x7530, 0x9363, 0x7531, 0x9752, 0x7532, 0x8D62, 0x7533, 0x905C, 0x7537, 0x926A, 0x7538, 0x99B2, - 0x753A, 0x92AC, 0x753B, 0x89E6, 0x753C, 0xE155, 0x7544, 0xE156, 0x7546, 0xE15B, 0x7549, 0xE159, 0x754A, 0xE158, 0x754B, 0x9DC0, - 0x754C, 0x8A45, 0x754D, 0xE157, 0x754F, 0x88D8, 0x7551, 0x94A8, 0x7554, 0x94C8, 0x7559, 0x97AF, 0x755A, 0xE15C, 0x755B, 0xE15A, - 0x755C, 0x927B, 0x755D, 0x90A4, 0x7560, 0x94A9, 0x7562, 0x954C, 0x7564, 0xE15E, 0x7565, 0x97AA, 0x7566, 0x8C6C, 0x7567, 0xE15F, - 0x7569, 0xE15D, 0x756A, 0x94D4, 0x756B, 0xE160, 0x756D, 0xE161, 0x756F, 0xFB6F, 0x7570, 0x88D9, 0x7573, 0x8FF4, 0x7574, 0xE166, - 0x7576, 0xE163, 0x7577, 0x93EB, 0x7578, 0xE162, 0x757F, 0x8B45, 0x7582, 0xE169, 0x7586, 0xE164, 0x7587, 0xE165, 0x7589, 0xE168, - 0x758A, 0xE167, 0x758B, 0x9544, 0x758E, 0x9161, 0x758F, 0x9160, 0x7591, 0x8B5E, 0x7594, 0xE16A, 0x759A, 0xE16B, 0x759D, 0xE16C, - 0x75A3, 0xE16E, 0x75A5, 0xE16D, 0x75AB, 0x8975, 0x75B1, 0xE176, 0x75B2, 0x94E6, 0x75B3, 0xE170, 0x75B5, 0xE172, 0x75B8, 0xE174, - 0x75B9, 0x905D, 0x75BC, 0xE175, 0x75BD, 0xE173, 0x75BE, 0x8EBE, 0x75C2, 0xE16F, 0x75C3, 0xE171, 0x75C5, 0x9561, 0x75C7, 0x8FC7, - 0x75CA, 0xE178, 0x75CD, 0xE177, 0x75D2, 0xE179, 0x75D4, 0x8EA4, 0x75D5, 0x8DAD, 0x75D8, 0x9397, 0x75D9, 0xE17A, 0x75DB, 0x92C9, - 0x75DE, 0xE17C, 0x75E2, 0x979F, 0x75E3, 0xE17B, 0x75E9, 0x9189, 0x75F0, 0xE182, 0x75F2, 0xE184, 0x75F3, 0xE185, 0x75F4, 0x9273, - 0x75FA, 0xE183, 0x75FC, 0xE180, 0x75FE, 0xE17D, 0x75FF, 0xE17E, 0x7601, 0xE181, 0x7609, 0xE188, 0x760B, 0xE186, 0x760D, 0xE187, - 0x761F, 0xE189, 0x7620, 0xE18B, 0x7621, 0xE18C, 0x7622, 0xE18D, 0x7624, 0xE18E, 0x7627, 0xE18A, 0x7630, 0xE190, 0x7634, 0xE18F, - 0x763B, 0xE191, 0x7642, 0x97C3, 0x7646, 0xE194, 0x7647, 0xE192, 0x7648, 0xE193, 0x764C, 0x8AE0, 0x7652, 0x96FC, 0x7656, 0x95C8, - 0x7658, 0xE196, 0x765C, 0xE195, 0x7661, 0xE197, 0x7662, 0xE198, 0x7667, 0xE19C, 0x7668, 0xE199, 0x7669, 0xE19A, 0x766A, 0xE19B, - 0x766C, 0xE19D, 0x7670, 0xE19E, 0x7672, 0xE19F, 0x7676, 0xE1A0, 0x7678, 0xE1A1, 0x767A, 0x94AD, 0x767B, 0x936F, 0x767C, 0xE1A2, - 0x767D, 0x9492, 0x767E, 0x9553, 0x7680, 0xE1A3, 0x7682, 0xFB70, 0x7683, 0xE1A4, 0x7684, 0x9349, 0x7686, 0x8A46, 0x7687, 0x8D63, - 0x7688, 0xE1A5, 0x768B, 0xE1A6, 0x768E, 0xE1A7, 0x7690, 0x8E48, 0x7693, 0xE1A9, 0x7696, 0xE1A8, 0x7699, 0xE1AA, 0x769A, 0xE1AB, - 0x769B, 0xFB73, 0x769C, 0xFB71, 0x769E, 0xFB72, 0x76A6, 0xFB74, 0x76AE, 0x94E7, 0x76B0, 0xE1AC, 0x76B4, 0xE1AD, 0x76B7, 0xEA89, - 0x76B8, 0xE1AE, 0x76B9, 0xE1AF, 0x76BA, 0xE1B0, 0x76BF, 0x8E4D, 0x76C2, 0xE1B1, 0x76C3, 0x9475, 0x76C6, 0x967E, 0x76C8, 0x896D, - 0x76CA, 0x8976, 0x76CD, 0xE1B2, 0x76D2, 0xE1B4, 0x76D6, 0xE1B3, 0x76D7, 0x9390, 0x76DB, 0x90B7, 0x76DC, 0x9F58, 0x76DE, 0xE1B5, - 0x76DF, 0x96BF, 0x76E1, 0xE1B6, 0x76E3, 0x8AC4, 0x76E4, 0x94D5, 0x76E5, 0xE1B7, 0x76E7, 0xE1B8, 0x76EA, 0xE1B9, 0x76EE, 0x96DA, - 0x76F2, 0x96D3, 0x76F4, 0x92BC, 0x76F8, 0x918A, 0x76FB, 0xE1BB, 0x76FE, 0x8F82, 0x7701, 0x8FC8, 0x7704, 0xE1BE, 0x7707, 0xE1BD, - 0x7708, 0xE1BC, 0x7709, 0x94FB, 0x770B, 0x8AC5, 0x770C, 0x8CA7, 0x771B, 0xE1C4, 0x771E, 0xE1C1, 0x771F, 0x905E, 0x7720, 0x96B0, - 0x7724, 0xE1C0, 0x7725, 0xE1C2, 0x7726, 0xE1C3, 0x7729, 0xE1BF, 0x7737, 0xE1C5, 0x7738, 0xE1C6, 0x773A, 0x92AD, 0x773C, 0x8AE1, - 0x7740, 0x9285, 0x7746, 0xFB76, 0x7747, 0xE1C7, 0x775A, 0xE1C8, 0x775B, 0xE1CB, 0x7761, 0x9087, 0x7763, 0x93C2, 0x7765, 0xE1CC, - 0x7766, 0x9672, 0x7768, 0xE1C9, 0x776B, 0xE1CA, 0x7779, 0xE1CF, 0x777E, 0xE1CE, 0x777F, 0xE1CD, 0x778B, 0xE1D1, 0x778E, 0xE1D0, - 0x7791, 0xE1D2, 0x779E, 0xE1D4, 0x77A0, 0xE1D3, 0x77A5, 0x95CB, 0x77AC, 0x8F75, 0x77AD, 0x97C4, 0x77B0, 0xE1D5, 0x77B3, 0x93B5, - 0x77B6, 0xE1D6, 0x77B9, 0xE1D7, 0x77BB, 0xE1DB, 0x77BC, 0xE1D9, 0x77BD, 0xE1DA, 0x77BF, 0xE1D8, 0x77C7, 0xE1DC, 0x77CD, 0xE1DD, - 0x77D7, 0xE1DE, 0x77DA, 0xE1DF, 0x77DB, 0x96B5, 0x77DC, 0xE1E0, 0x77E2, 0x96EE, 0x77E3, 0xE1E1, 0x77E5, 0x926D, 0x77E7, 0x948A, - 0x77E9, 0x8BE9, 0x77ED, 0x925A, 0x77EE, 0xE1E2, 0x77EF, 0x8BB8, 0x77F3, 0x90CE, 0x77FC, 0xE1E3, 0x7802, 0x8DBB, 0x780C, 0xE1E4, - 0x7812, 0xE1E5, 0x7814, 0x8CA4, 0x7815, 0x8DD3, 0x7820, 0xE1E7, 0x7821, 0xFB78, 0x7825, 0x9375, 0x7826, 0x8DD4, 0x7827, 0x8B6D, - 0x7832, 0x9643, 0x7834, 0x946A, 0x783A, 0x9376, 0x783F, 0x8D7B, 0x7845, 0xE1E9, 0x784E, 0xFB79, 0x785D, 0x8FC9, 0x7864, 0xFB7A, - 0x786B, 0x97B0, 0x786C, 0x8D64, 0x786F, 0x8CA5, 0x7872, 0x94A1, 0x7874, 0xE1EB, 0x787A, 0xFB7B, 0x787C, 0xE1ED, 0x7881, 0x8CE9, - 0x7886, 0xE1EC, 0x7887, 0x92F4, 0x788C, 0xE1EF, 0x788D, 0x8A56, 0x788E, 0xE1EA, 0x7891, 0x94E8, 0x7893, 0x894F, 0x7895, 0x8DEA, - 0x7897, 0x9871, 0x789A, 0xE1EE, 0x78A3, 0xE1F0, 0x78A7, 0x95C9, 0x78A9, 0x90D7, 0x78AA, 0xE1F2, 0x78AF, 0xE1F3, 0x78B5, 0xE1F1, - 0x78BA, 0x8A6D, 0x78BC, 0xE1F9, 0x78BE, 0xE1F8, 0x78C1, 0x8EA5, 0x78C5, 0xE1FA, 0x78C6, 0xE1F5, 0x78CA, 0xE1FB, 0x78CB, 0xE1F6, - 0x78D0, 0x94D6, 0x78D1, 0xE1F4, 0x78D4, 0xE1F7, 0x78DA, 0xE241, 0x78E7, 0xE240, 0x78E8, 0x9681, 0x78EC, 0xE1FC, 0x78EF, 0x88E9, - 0x78F4, 0xE243, 0x78FD, 0xE242, 0x7901, 0x8FCA, 0x7907, 0xE244, 0x790E, 0x9162, 0x7911, 0xE246, 0x7912, 0xE245, 0x7919, 0xE247, - 0x7926, 0xE1E6, 0x792A, 0xE1E8, 0x792B, 0xE249, 0x792C, 0xE248, 0x7930, 0xFB7C, 0x793A, 0x8EA6, 0x793C, 0x97E7, 0x793E, 0x8ED0, - 0x7940, 0xE24A, 0x7941, 0x8C56, 0x7947, 0x8B5F, 0x7948, 0x8B46, 0x7949, 0x8E83, 0x7950, 0x9753, 0x7953, 0xE250, 0x7955, 0xE24F, - 0x7956, 0x9163, 0x7957, 0xE24C, 0x795A, 0xE24E, 0x795D, 0x8F6A, 0x795E, 0x905F, 0x795F, 0xE24D, 0x7960, 0xE24B, 0x7962, 0x9449, - 0x7965, 0x8FCB, 0x7968, 0x955B, 0x796D, 0x8DD5, 0x7977, 0x9398, 0x797A, 0xE251, 0x797F, 0xE252, 0x7980, 0xE268, 0x7981, 0x8BD6, - 0x7984, 0x985C, 0x7985, 0x9154, 0x798A, 0xE253, 0x798D, 0x89D0, 0x798E, 0x92F5, 0x798F, 0x959F, 0x7994, 0xFB81, 0x799B, 0xFB83, - 0x799D, 0xE254, 0x79A6, 0x8B9A, 0x79A7, 0xE255, 0x79AA, 0xE257, 0x79AE, 0xE258, 0x79B0, 0x9448, 0x79B3, 0xE259, 0x79B9, 0xE25A, - 0x79BA, 0xE25B, 0x79BD, 0x8BD7, 0x79BE, 0x89D1, 0x79BF, 0x93C3, 0x79C0, 0x8F47, 0x79C1, 0x8E84, 0x79C9, 0xE25C, 0x79CB, 0x8F48, - 0x79D1, 0x89C8, 0x79D2, 0x9562, 0x79D5, 0xE25D, 0x79D8, 0x94E9, 0x79DF, 0x9164, 0x79E1, 0xE260, 0x79E3, 0xE261, 0x79E4, 0x9489, - 0x79E6, 0x9060, 0x79E7, 0xE25E, 0x79E9, 0x9281, 0x79EC, 0xE25F, 0x79F0, 0x8FCC, 0x79FB, 0x88DA, 0x7A00, 0x8B48, 0x7A08, 0xE262, - 0x7A0B, 0x92F6, 0x7A0D, 0xE263, 0x7A0E, 0x90C5, 0x7A14, 0x96AB, 0x7A17, 0x9542, 0x7A18, 0xE264, 0x7A19, 0xE265, 0x7A1A, 0x9274, - 0x7A1C, 0x97C5, 0x7A1F, 0xE267, 0x7A20, 0xE266, 0x7A2E, 0x8EED, 0x7A31, 0xE269, 0x7A32, 0x88EE, 0x7A37, 0xE26C, 0x7A3B, 0xE26A, - 0x7A3C, 0x89D2, 0x7A3D, 0x8C6D, 0x7A3E, 0xE26B, 0x7A3F, 0x8D65, 0x7A40, 0x8D92, 0x7A42, 0x95E4, 0x7A43, 0xE26D, 0x7A46, 0x9673, - 0x7A49, 0xE26F, 0x7A4D, 0x90CF, 0x7A4E, 0x896E, 0x7A4F, 0x89B8, 0x7A50, 0x88AA, 0x7A57, 0xE26E, 0x7A61, 0xE270, 0x7A62, 0xE271, - 0x7A63, 0x8FF5, 0x7A69, 0xE272, 0x7A6B, 0x8A6E, 0x7A70, 0xE274, 0x7A74, 0x8C8A, 0x7A76, 0x8B86, 0x7A79, 0xE275, 0x7A7A, 0x8BF3, - 0x7A7D, 0xE276, 0x7A7F, 0x90FA, 0x7A81, 0x93CB, 0x7A83, 0x90DE, 0x7A84, 0x8DF3, 0x7A88, 0xE277, 0x7A92, 0x9282, 0x7A93, 0x918B, - 0x7A95, 0xE279, 0x7A96, 0xE27B, 0x7A97, 0xE278, 0x7A98, 0xE27A, 0x7A9F, 0x8C41, 0x7AA9, 0xE27C, 0x7AAA, 0x8C45, 0x7AAE, 0x8B87, - 0x7AAF, 0x9771, 0x7AB0, 0xE27E, 0x7AB6, 0xE280, 0x7ABA, 0x894D, 0x7ABF, 0xE283, 0x7AC3, 0x8A96, 0x7AC4, 0xE282, 0x7AC5, 0xE281, - 0x7AC7, 0xE285, 0x7AC8, 0xE27D, 0x7ACA, 0xE286, 0x7ACB, 0x97A7, 0x7ACD, 0xE287, 0x7ACF, 0xE288, 0x7AD1, 0xFB84, 0x7AD2, 0x9AF2, - 0x7AD3, 0xE28A, 0x7AD5, 0xE289, 0x7AD9, 0xE28B, 0x7ADA, 0xE28C, 0x7ADC, 0x97B3, 0x7ADD, 0xE28D, 0x7ADF, 0xE8ED, 0x7AE0, 0x8FCD, - 0x7AE1, 0xE28E, 0x7AE2, 0xE28F, 0x7AE3, 0x8F76, 0x7AE5, 0x93B6, 0x7AE6, 0xE290, 0x7AE7, 0xFB85, 0x7AEA, 0x9247, 0x7AEB, 0xFB87, - 0x7AED, 0xE291, 0x7AEF, 0x925B, 0x7AF0, 0xE292, 0x7AF6, 0x8BA3, 0x7AF8, 0x995E, 0x7AF9, 0x927C, 0x7AFA, 0x8EB1, 0x7AFF, 0x8AC6, - 0x7B02, 0xE293, 0x7B04, 0xE2A0, 0x7B06, 0xE296, 0x7B08, 0x8B88, 0x7B0A, 0xE295, 0x7B0B, 0xE2A2, 0x7B0F, 0xE294, 0x7B11, 0x8FCE, - 0x7B18, 0xE298, 0x7B19, 0xE299, 0x7B1B, 0x934A, 0x7B1E, 0xE29A, 0x7B20, 0x8A7D, 0x7B25, 0x9079, 0x7B26, 0x9584, 0x7B28, 0xE29C, - 0x7B2C, 0x91E6, 0x7B33, 0xE297, 0x7B35, 0xE29B, 0x7B36, 0xE29D, 0x7B39, 0x8DF9, 0x7B45, 0xE2A4, 0x7B46, 0x954D, 0x7B48, 0x94A4, - 0x7B49, 0x9399, 0x7B4B, 0x8BD8, 0x7B4C, 0xE2A3, 0x7B4D, 0xE2A1, 0x7B4F, 0x94B3, 0x7B50, 0xE29E, 0x7B51, 0x927D, 0x7B52, 0x939B, - 0x7B54, 0x939A, 0x7B56, 0x8DF4, 0x7B5D, 0xE2B6, 0x7B65, 0xE2A6, 0x7B67, 0xE2A8, 0x7B6C, 0xE2AB, 0x7B6E, 0xE2AC, 0x7B70, 0xE2A9, - 0x7B71, 0xE2AA, 0x7B74, 0xE2A7, 0x7B75, 0xE2A5, 0x7B7A, 0xE29F, 0x7B86, 0x95CD, 0x7B87, 0x89D3, 0x7B8B, 0xE2B3, 0x7B8D, 0xE2B0, - 0x7B8F, 0xE2B5, 0x7B92, 0xE2B4, 0x7B94, 0x9493, 0x7B95, 0x96A5, 0x7B97, 0x8E5A, 0x7B98, 0xE2AE, 0x7B99, 0xE2B7, 0x7B9A, 0xE2B2, - 0x7B9C, 0xE2B1, 0x7B9D, 0xE2AD, 0x7B9E, 0xFB88, 0x7B9F, 0xE2AF, 0x7BA1, 0x8AC7, 0x7BAA, 0x925C, 0x7BAD, 0x90FB, 0x7BB1, 0x94A0, - 0x7BB4, 0xE2BC, 0x7BB8, 0x94A2, 0x7BC0, 0x90DF, 0x7BC1, 0xE2B9, 0x7BC4, 0x94CD, 0x7BC6, 0xE2BD, 0x7BC7, 0x95D1, 0x7BC9, 0x927A, - 0x7BCB, 0xE2B8, 0x7BCC, 0xE2BA, 0x7BCF, 0xE2BB, 0x7BDD, 0xE2BE, 0x7BE0, 0x8EC2, 0x7BE4, 0x93C4, 0x7BE5, 0xE2C3, 0x7BE6, 0xE2C2, - 0x7BE9, 0xE2BF, 0x7BED, 0x9855, 0x7BF3, 0xE2C8, 0x7BF6, 0xE2CC, 0x7BF7, 0xE2C9, 0x7C00, 0xE2C5, 0x7C07, 0xE2C6, 0x7C0D, 0xE2CB, - 0x7C11, 0xE2C0, 0x7C12, 0x99D3, 0x7C13, 0xE2C7, 0x7C14, 0xE2C1, 0x7C17, 0xE2CA, 0x7C1F, 0xE2D0, 0x7C21, 0x8AC8, 0x7C23, 0xE2CD, - 0x7C27, 0xE2CE, 0x7C2A, 0xE2CF, 0x7C2B, 0xE2D2, 0x7C37, 0xE2D1, 0x7C38, 0x94F4, 0x7C3D, 0xE2D3, 0x7C3E, 0x97FA, 0x7C3F, 0x95EB, - 0x7C40, 0xE2D8, 0x7C43, 0xE2D5, 0x7C4C, 0xE2D4, 0x7C4D, 0x90D0, 0x7C4F, 0xE2D7, 0x7C50, 0xE2D9, 0x7C54, 0xE2D6, 0x7C56, 0xE2DD, - 0x7C58, 0xE2DA, 0x7C5F, 0xE2DB, 0x7C60, 0xE2C4, 0x7C64, 0xE2DC, 0x7C65, 0xE2DE, 0x7C6C, 0xE2DF, 0x7C73, 0x95C4, 0x7C75, 0xE2E0, - 0x7C7E, 0x96E0, 0x7C81, 0x8BCC, 0x7C82, 0x8C48, 0x7C83, 0xE2E1, 0x7C89, 0x95B2, 0x7C8B, 0x9088, 0x7C8D, 0x96AE, 0x7C90, 0xE2E2, - 0x7C92, 0x97B1, 0x7C95, 0x9494, 0x7C97, 0x9165, 0x7C98, 0x9453, 0x7C9B, 0x8F6C, 0x7C9F, 0x88BE, 0x7CA1, 0xE2E7, 0x7CA2, 0xE2E5, - 0x7CA4, 0xE2E3, 0x7CA5, 0x8A9F, 0x7CA7, 0x8FCF, 0x7CA8, 0xE2E8, 0x7CAB, 0xE2E6, 0x7CAD, 0xE2E4, 0x7CAE, 0xE2EC, 0x7CB1, 0xE2EB, - 0x7CB2, 0xE2EA, 0x7CB3, 0xE2E9, 0x7CB9, 0xE2ED, 0x7CBD, 0xE2EE, 0x7CBE, 0x90B8, 0x7CC0, 0xE2EF, 0x7CC2, 0xE2F1, 0x7CC5, 0xE2F0, - 0x7CCA, 0x8CD0, 0x7CCE, 0x9157, 0x7CD2, 0xE2F3, 0x7CD6, 0x939C, 0x7CD8, 0xE2F2, 0x7CDC, 0xE2F4, 0x7CDE, 0x95B3, 0x7CDF, 0x918C, - 0x7CE0, 0x8D66, 0x7CE2, 0xE2F5, 0x7CE7, 0x97C6, 0x7CEF, 0xE2F7, 0x7CF2, 0xE2F8, 0x7CF4, 0xE2F9, 0x7CF6, 0xE2FA, 0x7CF8, 0x8E85, - 0x7CFA, 0xE2FB, 0x7CFB, 0x8C6E, 0x7CFE, 0x8B8A, 0x7D00, 0x8B49, 0x7D02, 0xE340, 0x7D04, 0x96F1, 0x7D05, 0x8D67, 0x7D06, 0xE2FC, - 0x7D0A, 0xE343, 0x7D0B, 0x96E4, 0x7D0D, 0x945B, 0x7D10, 0x9552, 0x7D14, 0x8F83, 0x7D15, 0xE342, 0x7D17, 0x8ED1, 0x7D18, 0x8D68, - 0x7D19, 0x8E86, 0x7D1A, 0x8B89, 0x7D1B, 0x95B4, 0x7D1C, 0xE341, 0x7D20, 0x9166, 0x7D21, 0x9661, 0x7D22, 0x8DF5, 0x7D2B, 0x8E87, - 0x7D2C, 0x92DB, 0x7D2E, 0xE346, 0x7D2F, 0x97DD, 0x7D30, 0x8DD7, 0x7D32, 0xE347, 0x7D33, 0x9061, 0x7D35, 0xE349, 0x7D39, 0x8FD0, - 0x7D3A, 0x8DAE, 0x7D3F, 0xE348, 0x7D42, 0x8F49, 0x7D43, 0x8CBC, 0x7D44, 0x9167, 0x7D45, 0xE344, 0x7D46, 0xE34A, 0x7D48, 0xFB8A, - 0x7D4B, 0xE345, 0x7D4C, 0x8C6F, 0x7D4E, 0xE34D, 0x7D4F, 0xE351, 0x7D50, 0x8C8B, 0x7D56, 0xE34C, 0x7D5B, 0xE355, 0x7D5C, 0xFB8B, - 0x7D5E, 0x8D69, 0x7D61, 0x978D, 0x7D62, 0x88BA, 0x7D63, 0xE352, 0x7D66, 0x8B8B, 0x7D68, 0xE34F, 0x7D6E, 0xE350, 0x7D71, 0x939D, - 0x7D72, 0xE34E, 0x7D73, 0xE34B, 0x7D75, 0x8A47, 0x7D76, 0x90E2, 0x7D79, 0x8CA6, 0x7D7D, 0xE357, 0x7D89, 0xE354, 0x7D8F, 0xE356, - 0x7D93, 0xE353, 0x7D99, 0x8C70, 0x7D9A, 0x91B1, 0x7D9B, 0xE358, 0x7D9C, 0x918E, 0x7D9F, 0xE365, 0x7DA0, 0xFB8D, 0x7DA2, 0xE361, - 0x7DA3, 0xE35B, 0x7DAB, 0xE35F, 0x7DAC, 0x8EF8, 0x7DAD, 0x88DB, 0x7DAE, 0xE35A, 0x7DAF, 0xE362, 0x7DB0, 0xE366, 0x7DB1, 0x8D6A, - 0x7DB2, 0x96D4, 0x7DB4, 0x92D4, 0x7DB5, 0xE35C, 0x7DB7, 0xFB8C, 0x7DB8, 0xE364, 0x7DBA, 0xE359, 0x7DBB, 0x925D, 0x7DBD, 0xE35E, - 0x7DBE, 0x88BB, 0x7DBF, 0x96C8, 0x7DC7, 0xE35D, 0x7DCA, 0x8BD9, 0x7DCB, 0x94EA, 0x7DCF, 0x918D, 0x7DD1, 0x97CE, 0x7DD2, 0x8F8F, - 0x7DD5, 0xE38E, 0x7DD6, 0xFB8E, 0x7DD8, 0xE367, 0x7DDA, 0x90FC, 0x7DDC, 0xE363, 0x7DDD, 0xE368, 0x7DDE, 0xE36A, 0x7DE0, 0x92F7, - 0x7DE1, 0xE36D, 0x7DE4, 0xE369, 0x7DE8, 0x95D2, 0x7DE9, 0x8AC9, 0x7DEC, 0x96C9, 0x7DEF, 0x88DC, 0x7DF2, 0xE36C, 0x7DF4, 0x97FB, - 0x7DFB, 0xE36B, 0x7E01, 0x898F, 0x7E04, 0x93EA, 0x7E05, 0xE36E, 0x7E09, 0xE375, 0x7E0A, 0xE36F, 0x7E0B, 0xE376, 0x7E12, 0xE372, - 0x7E1B, 0x949B, 0x7E1E, 0x8EC8, 0x7E1F, 0xE374, 0x7E21, 0xE371, 0x7E22, 0xE377, 0x7E23, 0xE370, 0x7E26, 0x8F63, 0x7E2B, 0x9644, - 0x7E2E, 0x8F6B, 0x7E31, 0xE373, 0x7E32, 0xE380, 0x7E35, 0xE37B, 0x7E37, 0xE37E, 0x7E39, 0xE37C, 0x7E3A, 0xE381, 0x7E3B, 0xE37A, - 0x7E3D, 0xE360, 0x7E3E, 0x90D1, 0x7E41, 0x94C9, 0x7E43, 0xE37D, 0x7E46, 0xE378, 0x7E4A, 0x9140, 0x7E4B, 0x8C71, 0x7E4D, 0x8F4A, - 0x7E52, 0xFB8F, 0x7E54, 0x9044, 0x7E55, 0x9155, 0x7E56, 0xE384, 0x7E59, 0xE386, 0x7E5A, 0xE387, 0x7E5D, 0xE383, 0x7E5E, 0xE385, - 0x7E66, 0xE379, 0x7E67, 0xE382, 0x7E69, 0xE38A, 0x7E6A, 0xE389, 0x7E6D, 0x969A, 0x7E70, 0x8C4A, 0x7E79, 0xE388, 0x7E7B, 0xE38C, - 0x7E7C, 0xE38B, 0x7E7D, 0xE38F, 0x7E7F, 0xE391, 0x7E82, 0x8E5B, 0x7E83, 0xE38D, 0x7E88, 0xE392, 0x7E89, 0xE393, 0x7E8A, 0xFA5C, - 0x7E8C, 0xE394, 0x7E8E, 0xE39A, 0x7E8F, 0x935A, 0x7E90, 0xE396, 0x7E92, 0xE395, 0x7E93, 0xE397, 0x7E94, 0xE398, 0x7E96, 0xE399, - 0x7E9B, 0xE39B, 0x7E9C, 0xE39C, 0x7F36, 0x8ACA, 0x7F38, 0xE39D, 0x7F3A, 0xE39E, 0x7F45, 0xE39F, 0x7F47, 0xFB90, 0x7F4C, 0xE3A0, - 0x7F4D, 0xE3A1, 0x7F4E, 0xE3A2, 0x7F50, 0xE3A3, 0x7F51, 0xE3A4, 0x7F54, 0xE3A6, 0x7F55, 0xE3A5, 0x7F58, 0xE3A7, 0x7F5F, 0xE3A8, - 0x7F60, 0xE3A9, 0x7F67, 0xE3AC, 0x7F68, 0xE3AA, 0x7F69, 0xE3AB, 0x7F6A, 0x8DDF, 0x7F6B, 0x8C72, 0x7F6E, 0x9275, 0x7F70, 0x94B1, - 0x7F72, 0x8F90, 0x7F75, 0x946C, 0x7F77, 0x94EB, 0x7F78, 0xE3AD, 0x7F79, 0x9CEB, 0x7F82, 0xE3AE, 0x7F83, 0xE3B0, 0x7F85, 0x9785, - 0x7F86, 0xE3AF, 0x7F87, 0xE3B2, 0x7F88, 0xE3B1, 0x7F8A, 0x9772, 0x7F8C, 0xE3B3, 0x7F8E, 0x94FC, 0x7F94, 0xE3B4, 0x7F9A, 0xE3B7, - 0x7F9D, 0xE3B6, 0x7F9E, 0xE3B5, 0x7FA1, 0xFB91, 0x7FA3, 0xE3B8, 0x7FA4, 0x8C51, 0x7FA8, 0x9141, 0x7FA9, 0x8B60, 0x7FAE, 0xE3BC, - 0x7FAF, 0xE3B9, 0x7FB2, 0xE3BA, 0x7FB6, 0xE3BD, 0x7FB8, 0xE3BE, 0x7FB9, 0xE3BB, 0x7FBD, 0x8948, 0x7FC1, 0x89A5, 0x7FC5, 0xE3C0, - 0x7FC6, 0xE3C1, 0x7FCA, 0xE3C2, 0x7FCC, 0x9782, 0x7FD2, 0x8F4B, 0x7FD4, 0xE3C4, 0x7FD5, 0xE3C3, 0x7FE0, 0x9089, 0x7FE1, 0xE3C5, - 0x7FE6, 0xE3C6, 0x7FE9, 0xE3C7, 0x7FEB, 0x8AE3, 0x7FF0, 0x8ACB, 0x7FF3, 0xE3C8, 0x7FF9, 0xE3C9, 0x7FFB, 0x967C, 0x7FFC, 0x9783, - 0x8000, 0x9773, 0x8001, 0x9856, 0x8003, 0x8D6C, 0x8004, 0xE3CC, 0x8005, 0x8ED2, 0x8006, 0xE3CB, 0x800B, 0xE3CD, 0x800C, 0x8EA7, - 0x8010, 0x91CF, 0x8012, 0xE3CE, 0x8015, 0x8D6B, 0x8017, 0x96D5, 0x8018, 0xE3CF, 0x8019, 0xE3D0, 0x801C, 0xE3D1, 0x8021, 0xE3D2, - 0x8028, 0xE3D3, 0x8033, 0x8EA8, 0x8036, 0x96EB, 0x803B, 0xE3D5, 0x803D, 0x925E, 0x803F, 0xE3D4, 0x8046, 0xE3D7, 0x804A, 0xE3D6, - 0x8052, 0xE3D8, 0x8056, 0x90B9, 0x8058, 0xE3D9, 0x805A, 0xE3DA, 0x805E, 0x95B7, 0x805F, 0xE3DB, 0x8061, 0x918F, 0x8062, 0xE3DC, - 0x8068, 0xE3DD, 0x806F, 0x97FC, 0x8070, 0xE3E0, 0x8072, 0xE3DF, 0x8073, 0xE3DE, 0x8074, 0x92AE, 0x8076, 0xE3E1, 0x8077, 0x9045, - 0x8079, 0xE3E2, 0x807D, 0xE3E3, 0x807E, 0x9857, 0x807F, 0xE3E4, 0x8084, 0xE3E5, 0x8085, 0xE3E7, 0x8086, 0xE3E6, 0x8087, 0x94A3, - 0x8089, 0x93F7, 0x808B, 0x985D, 0x808C, 0x94A7, 0x8093, 0xE3E9, 0x8096, 0x8FD1, 0x8098, 0x9549, 0x809A, 0xE3EA, 0x809B, 0xE3E8, - 0x809D, 0x8ACC, 0x80A1, 0x8CD2, 0x80A2, 0x8E88, 0x80A5, 0x94EC, 0x80A9, 0x8CA8, 0x80AA, 0x9662, 0x80AC, 0xE3ED, 0x80AD, 0xE3EB, - 0x80AF, 0x8D6D, 0x80B1, 0x8D6E, 0x80B2, 0x88E7, 0x80B4, 0x8DE6, 0x80BA, 0x9478, 0x80C3, 0x88DD, 0x80C4, 0xE3F2, 0x80C6, 0x925F, - 0x80CC, 0x9477, 0x80CE, 0x91D9, 0x80D6, 0xE3F4, 0x80D9, 0xE3F0, 0x80DA, 0xE3F3, 0x80DB, 0xE3EE, 0x80DD, 0xE3F1, 0x80DE, 0x9645, - 0x80E1, 0x8CD3, 0x80E4, 0x88FB, 0x80E5, 0xE3EF, 0x80EF, 0xE3F6, 0x80F1, 0xE3F7, 0x80F4, 0x93B7, 0x80F8, 0x8BB9, 0x80FC, 0xE445, - 0x80FD, 0x945C, 0x8102, 0x8E89, 0x8105, 0x8BBA, 0x8106, 0x90C6, 0x8107, 0x9865, 0x8108, 0x96AC, 0x8109, 0xE3F5, 0x810A, 0x90D2, - 0x811A, 0x8B72, 0x811B, 0xE3F8, 0x8123, 0xE3FA, 0x8129, 0xE3F9, 0x812F, 0xE3FB, 0x8131, 0x9245, 0x8133, 0x945D, 0x8139, 0x92AF, - 0x813E, 0xE442, 0x8146, 0xE441, 0x814B, 0xE3FC, 0x814E, 0x9074, 0x8150, 0x9585, 0x8151, 0xE444, 0x8153, 0xE443, 0x8154, 0x8D6F, - 0x8155, 0x9872, 0x815F, 0xE454, 0x8165, 0xE448, 0x8166, 0xE449, 0x816B, 0x8EEE, 0x816E, 0xE447, 0x8170, 0x8D98, 0x8171, 0xE446, - 0x8174, 0xE44A, 0x8178, 0x92B0, 0x8179, 0x95A0, 0x817A, 0x9142, 0x817F, 0x91DA, 0x8180, 0xE44E, 0x8182, 0xE44F, 0x8183, 0xE44B, - 0x8188, 0xE44C, 0x818A, 0xE44D, 0x818F, 0x8D70, 0x8193, 0xE455, 0x8195, 0xE451, 0x819A, 0x9586, 0x819C, 0x968C, 0x819D, 0x9547, - 0x81A0, 0xE450, 0x81A3, 0xE453, 0x81A4, 0xE452, 0x81A8, 0x9663, 0x81A9, 0xE456, 0x81B0, 0xE457, 0x81B3, 0x9156, 0x81B5, 0xE458, - 0x81B8, 0xE45A, 0x81BA, 0xE45E, 0x81BD, 0xE45B, 0x81BE, 0xE459, 0x81BF, 0x945E, 0x81C0, 0xE45C, 0x81C2, 0xE45D, 0x81C6, 0x89B0, - 0x81C8, 0xE464, 0x81C9, 0xE45F, 0x81CD, 0xE460, 0x81D1, 0xE461, 0x81D3, 0x919F, 0x81D8, 0xE463, 0x81D9, 0xE462, 0x81DA, 0xE465, - 0x81DF, 0xE466, 0x81E0, 0xE467, 0x81E3, 0x9062, 0x81E5, 0x89E7, 0x81E7, 0xE468, 0x81E8, 0x97D5, 0x81EA, 0x8EA9, 0x81ED, 0x8F4C, - 0x81F3, 0x8E8A, 0x81F4, 0x9276, 0x81FA, 0xE469, 0x81FB, 0xE46A, 0x81FC, 0x8950, 0x81FE, 0xE46B, 0x8201, 0xE46C, 0x8202, 0xE46D, - 0x8205, 0xE46E, 0x8207, 0xE46F, 0x8208, 0x8BBB, 0x8209, 0x9DA8, 0x820A, 0xE470, 0x820C, 0x90E3, 0x820D, 0xE471, 0x820E, 0x8EC9, - 0x8210, 0xE472, 0x8212, 0x98AE, 0x8216, 0xE473, 0x8217, 0x95DC, 0x8218, 0x8ADA, 0x821B, 0x9143, 0x821C, 0x8F77, 0x821E, 0x9591, - 0x821F, 0x8F4D, 0x8229, 0xE474, 0x822A, 0x8D71, 0x822B, 0xE475, 0x822C, 0x94CA, 0x822E, 0xE484, 0x8233, 0xE477, 0x8235, 0x91C7, - 0x8236, 0x9495, 0x8237, 0x8CBD, 0x8238, 0xE476, 0x8239, 0x9144, 0x8240, 0xE478, 0x8247, 0x92F8, 0x8258, 0xE47A, 0x8259, 0xE479, - 0x825A, 0xE47C, 0x825D, 0xE47B, 0x825F, 0xE47D, 0x8262, 0xE480, 0x8264, 0xE47E, 0x8266, 0x8ACD, 0x8268, 0xE481, 0x826A, 0xE482, - 0x826B, 0xE483, 0x826E, 0x8DAF, 0x826F, 0x97C7, 0x8271, 0xE485, 0x8272, 0x9046, 0x8276, 0x8990, 0x8277, 0xE486, 0x8278, 0xE487, - 0x827E, 0xE488, 0x828B, 0x88F0, 0x828D, 0xE489, 0x8292, 0xE48A, 0x8299, 0x9587, 0x829D, 0x8EC5, 0x829F, 0xE48C, 0x82A5, 0x8A48, - 0x82A6, 0x88B0, 0x82AB, 0xE48B, 0x82AC, 0xE48E, 0x82AD, 0x946D, 0x82AF, 0x9063, 0x82B1, 0x89D4, 0x82B3, 0x9646, 0x82B8, 0x8C7C, - 0x82B9, 0x8BDA, 0x82BB, 0xE48D, 0x82BD, 0x89E8, 0x82C5, 0x8AA1, 0x82D1, 0x8991, 0x82D2, 0xE492, 0x82D3, 0x97E8, 0x82D4, 0x91DB, - 0x82D7, 0x9563, 0x82D9, 0xE49E, 0x82DB, 0x89D5, 0x82DC, 0xE49C, 0x82DE, 0xE49A, 0x82DF, 0xE491, 0x82E1, 0xE48F, 0x82E3, 0xE490, - 0x82E5, 0x8EE1, 0x82E6, 0x8BEA, 0x82E7, 0x9297, 0x82EB, 0x93CF, 0x82F1, 0x8970, 0x82F3, 0xE494, 0x82F4, 0xE493, 0x82F9, 0xE499, - 0x82FA, 0xE495, 0x82FB, 0xE498, 0x8301, 0xFB93, 0x8302, 0x96CE, 0x8303, 0xE497, 0x8304, 0x89D6, 0x8305, 0x8A9D, 0x8306, 0xE49B, - 0x8309, 0xE49D, 0x830E, 0x8C73, 0x8316, 0xE4A1, 0x8317, 0xE4AA, 0x8318, 0xE4AB, 0x831C, 0x88A9, 0x8323, 0xE4B2, 0x8328, 0x88EF, - 0x832B, 0xE4A9, 0x832F, 0xE4A8, 0x8331, 0xE4A3, 0x8332, 0xE4A2, 0x8334, 0xE4A0, 0x8335, 0xE49F, 0x8336, 0x9283, 0x8338, 0x91F9, - 0x8339, 0xE4A5, 0x8340, 0xE4A4, 0x8345, 0xE4A7, 0x8349, 0x9190, 0x834A, 0x8C74, 0x834F, 0x8960, 0x8350, 0xE4A6, 0x8352, 0x8D72, - 0x8358, 0x9191, 0x8362, 0xFB94, 0x8373, 0xE4B8, 0x8375, 0xE4B9, 0x8377, 0x89D7, 0x837B, 0x89AC, 0x837C, 0xE4B6, 0x837F, 0xFB95, - 0x8385, 0xE4AC, 0x8387, 0xE4B4, 0x8389, 0xE4BB, 0x838A, 0xE4B5, 0x838E, 0xE4B3, 0x8393, 0xE496, 0x8396, 0xE4B1, 0x839A, 0xE4AD, - 0x839E, 0x8ACE, 0x839F, 0xE4AF, 0x83A0, 0xE4BA, 0x83A2, 0xE4B0, 0x83A8, 0xE4BC, 0x83AA, 0xE4AE, 0x83AB, 0x949C, 0x83B1, 0x9789, - 0x83B5, 0xE4B7, 0x83BD, 0xE4CD, 0x83C1, 0xE4C5, 0x83C5, 0x909B, 0x83C7, 0xFB96, 0x83CA, 0x8B65, 0x83CC, 0x8BDB, 0x83CE, 0xE4C0, - 0x83D3, 0x89D9, 0x83D6, 0x8FD2, 0x83D8, 0xE4C3, 0x83DC, 0x8DD8, 0x83DF, 0x9370, 0x83E0, 0xE4C8, 0x83E9, 0x95EC, 0x83EB, 0xE4BF, - 0x83EF, 0x89D8, 0x83F0, 0x8CD4, 0x83F1, 0x9548, 0x83F2, 0xE4C9, 0x83F4, 0xE4BD, 0x83F6, 0xFB97, 0x83F7, 0xE4C6, 0x83FB, 0xE4D0, - 0x83FD, 0xE4C1, 0x8403, 0xE4C2, 0x8404, 0x93B8, 0x8407, 0xE4C7, 0x840B, 0xE4C4, 0x840C, 0x9647, 0x840D, 0xE4CA, 0x840E, 0x88DE, - 0x8413, 0xE4BE, 0x8420, 0xE4CC, 0x8422, 0xE4CB, 0x8429, 0x948B, 0x842A, 0xE4D2, 0x842C, 0xE4DD, 0x8431, 0x8A9E, 0x8435, 0xE4E0, - 0x8438, 0xE4CE, 0x843C, 0xE4D3, 0x843D, 0x978E, 0x8446, 0xE4DC, 0x8448, 0xFB98, 0x8449, 0x9774, 0x844E, 0x97A8, 0x8457, 0x9298, - 0x845B, 0x8A8B, 0x8461, 0x9592, 0x8462, 0xE4E2, 0x8463, 0x939F, 0x8466, 0x88AF, 0x8469, 0xE4DB, 0x846B, 0xE4D7, 0x846C, 0x9192, - 0x846D, 0xE4D1, 0x846E, 0xE4D9, 0x846F, 0xE4DE, 0x8471, 0x944B, 0x8475, 0x88A8, 0x8477, 0xE4D6, 0x8479, 0xE4DF, 0x847A, 0x9598, - 0x8482, 0xE4DA, 0x8484, 0xE4D5, 0x848B, 0x8FD3, 0x8490, 0x8F4E, 0x8494, 0x8EAA, 0x8499, 0x96D6, 0x849C, 0x9566, 0x849F, 0xE4E5, - 0x84A1, 0xE4EE, 0x84AD, 0xE4D8, 0x84B2, 0x8A97, 0x84B4, 0xFB99, 0x84B8, 0x8FF6, 0x84B9, 0xE4E3, 0x84BB, 0xE4E8, 0x84BC, 0x9193, - 0x84BF, 0xE4E4, 0x84C1, 0xE4EB, 0x84C4, 0x927E, 0x84C6, 0xE4EC, 0x84C9, 0x9775, 0x84CA, 0xE4E1, 0x84CB, 0x8A57, 0x84CD, 0xE4E7, - 0x84D0, 0xE4EA, 0x84D1, 0x96AA, 0x84D6, 0xE4ED, 0x84D9, 0xE4E6, 0x84DA, 0xE4E9, 0x84DC, 0xFA60, 0x84EC, 0x9648, 0x84EE, 0x9840, - 0x84F4, 0xE4F1, 0x84FC, 0xE4F8, 0x84FF, 0xE4F0, 0x8500, 0x8EC1, 0x8506, 0xE4CF, 0x8511, 0x95CC, 0x8513, 0x96A0, 0x8514, 0xE4F7, - 0x8515, 0xE4F6, 0x8517, 0xE4F2, 0x8518, 0xE4F3, 0x851A, 0x8955, 0x851F, 0xE4F5, 0x8521, 0xE4EF, 0x8526, 0x92D3, 0x852C, 0xE4F4, - 0x852D, 0x88FC, 0x8535, 0x91A0, 0x853D, 0x95C1, 0x8540, 0xE4F9, 0x8541, 0xE540, 0x8543, 0x94D7, 0x8548, 0xE4FC, 0x8549, 0x8FD4, - 0x854A, 0x8EC7, 0x854B, 0xE542, 0x854E, 0x8BBC, 0x8553, 0xFB9A, 0x8555, 0xE543, 0x8557, 0x9599, 0x8558, 0xE4FB, 0x8559, 0xFB9B, - 0x855A, 0xE4D4, 0x8563, 0xE4FA, 0x8568, 0x986E, 0x8569, 0x93A0, 0x856A, 0x9593, 0x856B, 0xFB9C, 0x856D, 0xE54A, 0x8577, 0xE550, - 0x857E, 0xE551, 0x8580, 0xE544, 0x8584, 0x9496, 0x8587, 0xE54E, 0x8588, 0xE546, 0x858A, 0xE548, 0x8590, 0xE552, 0x8591, 0xE547, - 0x8594, 0xE54B, 0x8597, 0x8992, 0x8599, 0x93E3, 0x859B, 0xE54C, 0x859C, 0xE54F, 0x85A4, 0xE545, 0x85A6, 0x9145, 0x85A8, 0xE549, - 0x85A9, 0x8E46, 0x85AA, 0x9064, 0x85AB, 0x8C4F, 0x85AC, 0x96F2, 0x85AE, 0x96F7, 0x85AF, 0x8F92, 0x85B0, 0xFB9E, 0x85B9, 0xE556, - 0x85BA, 0xE554, 0x85C1, 0x986D, 0x85C9, 0xE553, 0x85CD, 0x9795, 0x85CF, 0xE555, 0x85D0, 0xE557, 0x85D5, 0xE558, 0x85DC, 0xE55B, - 0x85DD, 0xE559, 0x85E4, 0x93A1, 0x85E5, 0xE55A, 0x85E9, 0x94CB, 0x85EA, 0xE54D, 0x85F7, 0x8F93, 0x85F9, 0xE55C, 0x85FA, 0xE561, - 0x85FB, 0x9194, 0x85FE, 0xE560, 0x8602, 0xE541, 0x8606, 0xE562, 0x8607, 0x9168, 0x860A, 0xE55D, 0x860B, 0xE55F, 0x8613, 0xE55E, - 0x8616, 0x9F50, 0x8617, 0x9F41, 0x861A, 0xE564, 0x8622, 0xE563, 0x862D, 0x9796, 0x862F, 0xE1BA, 0x8630, 0xE565, 0x863F, 0xE566, - 0x864D, 0xE567, 0x864E, 0x8CD5, 0x8650, 0x8B73, 0x8654, 0xE569, 0x8655, 0x997C, 0x865A, 0x8B95, 0x865C, 0x97B8, 0x865E, 0x8BF1, - 0x865F, 0xE56A, 0x8667, 0xE56B, 0x866B, 0x928E, 0x8671, 0xE56C, 0x8679, 0x93F8, 0x867B, 0x88B8, 0x868A, 0x89E1, 0x868B, 0xE571, - 0x868C, 0xE572, 0x8693, 0xE56D, 0x8695, 0x8E5C, 0x86A3, 0xE56E, 0x86A4, 0x9461, 0x86A9, 0xE56F, 0x86AA, 0xE570, 0x86AB, 0xE57A, - 0x86AF, 0xE574, 0x86B0, 0xE577, 0x86B6, 0xE573, 0x86C4, 0xE575, 0x86C6, 0xE576, 0x86C7, 0x8ED6, 0x86C9, 0xE578, 0x86CB, 0x9260, - 0x86CD, 0x8C75, 0x86CE, 0x8A61, 0x86D4, 0xE57B, 0x86D9, 0x8A5E, 0x86DB, 0xE581, 0x86DE, 0xE57C, 0x86DF, 0xE580, 0x86E4, 0x94B8, - 0x86E9, 0xE57D, 0x86EC, 0xE57E, 0x86ED, 0x9567, 0x86EE, 0x94D8, 0x86EF, 0xE582, 0x86F8, 0x91FB, 0x86F9, 0xE58C, 0x86FB, 0xE588, - 0x86FE, 0x89E9, 0x8700, 0xE586, 0x8702, 0x9649, 0x8703, 0xE587, 0x8706, 0xE584, 0x8708, 0xE585, 0x8709, 0xE58A, 0x870A, 0xE58D, - 0x870D, 0xE58B, 0x8711, 0xE589, 0x8712, 0xE583, 0x8718, 0x9277, 0x871A, 0xE594, 0x871C, 0x96A8, 0x8725, 0xE592, 0x8729, 0xE593, - 0x8734, 0xE58E, 0x8737, 0xE590, 0x873B, 0xE591, 0x873F, 0xE58F, 0x8749, 0x90E4, 0x874B, 0x9858, 0x874C, 0xE598, 0x874E, 0xE599, - 0x8753, 0xE59F, 0x8755, 0x9049, 0x8757, 0xE59B, 0x8759, 0xE59E, 0x875F, 0xE596, 0x8760, 0xE595, 0x8763, 0xE5A0, 0x8766, 0x89DA, - 0x8768, 0xE59C, 0x876A, 0xE5A1, 0x876E, 0xE59D, 0x8774, 0xE59A, 0x8776, 0x92B1, 0x8778, 0xE597, 0x877F, 0x9488, 0x8782, 0xE5A5, - 0x878D, 0x975A, 0x879F, 0xE5A4, 0x87A2, 0xE5A3, 0x87AB, 0xE5AC, 0x87AF, 0xE5A6, 0x87B3, 0xE5AE, 0x87BA, 0x9786, 0x87BB, 0xE5B1, - 0x87BD, 0xE5A8, 0x87C0, 0xE5A9, 0x87C4, 0xE5AD, 0x87C6, 0xE5B0, 0x87C7, 0xE5AF, 0x87CB, 0xE5A7, 0x87D0, 0xE5AA, 0x87D2, 0xE5BB, - 0x87E0, 0xE5B4, 0x87EF, 0xE5B2, 0x87F2, 0xE5B3, 0x87F6, 0xE5B8, 0x87F7, 0xE5B9, 0x87F9, 0x8A49, 0x87FB, 0x8B61, 0x87FE, 0xE5B7, - 0x8805, 0xE5A2, 0x8807, 0xFBA1, 0x880D, 0xE5B6, 0x880E, 0xE5BA, 0x880F, 0xE5B5, 0x8811, 0xE5BC, 0x8815, 0xE5BE, 0x8816, 0xE5BD, - 0x8821, 0xE5C0, 0x8822, 0xE5BF, 0x8823, 0xE579, 0x8827, 0xE5C4, 0x8831, 0xE5C1, 0x8836, 0xE5C2, 0x8839, 0xE5C3, 0x883B, 0xE5C5, - 0x8840, 0x8C8C, 0x8842, 0xE5C7, 0x8844, 0xE5C6, 0x8846, 0x8F4F, 0x884C, 0x8D73, 0x884D, 0x9FA5, 0x8852, 0xE5C8, 0x8853, 0x8F70, - 0x8857, 0x8A58, 0x8859, 0xE5C9, 0x885B, 0x8971, 0x885D, 0x8FD5, 0x885E, 0xE5CA, 0x8861, 0x8D74, 0x8862, 0xE5CB, 0x8863, 0x88DF, - 0x8868, 0x955C, 0x886B, 0xE5CC, 0x8870, 0x908A, 0x8872, 0xE5D3, 0x8875, 0xE5D0, 0x8877, 0x928F, 0x887D, 0xE5D1, 0x887E, 0xE5CE, - 0x887F, 0x8BDC, 0x8881, 0xE5CD, 0x8882, 0xE5D4, 0x8888, 0x8C55, 0x888B, 0x91DC, 0x888D, 0xE5DA, 0x8892, 0xE5D6, 0x8896, 0x91B3, - 0x8897, 0xE5D5, 0x8899, 0xE5D8, 0x889E, 0xE5CF, 0x88A2, 0xE5D9, 0x88A4, 0xE5DB, 0x88AB, 0x94ED, 0x88AE, 0xE5D7, 0x88B0, 0xE5DC, - 0x88B1, 0xE5DE, 0x88B4, 0x8CD1, 0x88B5, 0xE5D2, 0x88B7, 0x88BF, 0x88BF, 0xE5DD, 0x88C1, 0x8DD9, 0x88C2, 0x97F4, 0x88C3, 0xE5DF, - 0x88C4, 0xE5E0, 0x88C5, 0x9195, 0x88CF, 0x97A0, 0x88D4, 0xE5E1, 0x88D5, 0x9754, 0x88D8, 0xE5E2, 0x88D9, 0xE5E3, 0x88DC, 0x95E2, - 0x88DD, 0xE5E4, 0x88DF, 0x8DBE, 0x88E1, 0x97A1, 0x88E8, 0xE5E9, 0x88F2, 0xE5EA, 0x88F3, 0x8FD6, 0x88F4, 0xE5E8, 0x88F5, 0xFBA2, - 0x88F8, 0x9787, 0x88F9, 0xE5E5, 0x88FC, 0xE5E7, 0x88FD, 0x90BB, 0x88FE, 0x909E, 0x8902, 0xE5E6, 0x8904, 0xE5EB, 0x8907, 0x95A1, - 0x890A, 0xE5ED, 0x890C, 0xE5EC, 0x8910, 0x8A8C, 0x8912, 0x964A, 0x8913, 0xE5EE, 0x891C, 0xFA5D, 0x891D, 0xE5FA, 0x891E, 0xE5F0, - 0x8925, 0xE5F1, 0x892A, 0xE5F2, 0x892B, 0xE5F3, 0x8936, 0xE5F7, 0x8938, 0xE5F8, 0x893B, 0xE5F6, 0x8941, 0xE5F4, 0x8943, 0xE5EF, - 0x8944, 0xE5F5, 0x894C, 0xE5F9, 0x894D, 0xE8B5, 0x8956, 0x89A6, 0x895E, 0xE5FC, 0x895F, 0x8BDD, 0x8960, 0xE5FB, 0x8964, 0xE641, - 0x8966, 0xE640, 0x896A, 0xE643, 0x896D, 0xE642, 0x896F, 0xE644, 0x8972, 0x8F50, 0x8974, 0xE645, 0x8977, 0xE646, 0x897E, 0xE647, - 0x897F, 0x90BC, 0x8981, 0x9776, 0x8983, 0xE648, 0x8986, 0x95A2, 0x8987, 0x9465, 0x8988, 0xE649, 0x898A, 0xE64A, 0x898B, 0x8CA9, - 0x898F, 0x8B4B, 0x8993, 0xE64B, 0x8996, 0x8E8B, 0x8997, 0x9460, 0x8998, 0xE64C, 0x899A, 0x8A6F, 0x89A1, 0xE64D, 0x89A6, 0xE64F, - 0x89A7, 0x9797, 0x89A9, 0xE64E, 0x89AA, 0x9065, 0x89AC, 0xE650, 0x89AF, 0xE651, 0x89B2, 0xE652, 0x89B3, 0x8ACF, 0x89BA, 0xE653, - 0x89BD, 0xE654, 0x89BF, 0xE655, 0x89C0, 0xE656, 0x89D2, 0x8A70, 0x89DA, 0xE657, 0x89DC, 0xE658, 0x89DD, 0xE659, 0x89E3, 0x89F0, - 0x89E6, 0x9047, 0x89E7, 0xE65A, 0x89F4, 0xE65B, 0x89F8, 0xE65C, 0x8A00, 0x8CBE, 0x8A02, 0x92F9, 0x8A03, 0xE65D, 0x8A08, 0x8C76, - 0x8A0A, 0x9075, 0x8A0C, 0xE660, 0x8A0E, 0x93A2, 0x8A10, 0xE65F, 0x8A12, 0xFBA3, 0x8A13, 0x8C50, 0x8A16, 0xE65E, 0x8A17, 0x91F5, - 0x8A18, 0x8B4C, 0x8A1B, 0xE661, 0x8A1D, 0xE662, 0x8A1F, 0x8FD7, 0x8A23, 0x8C8D, 0x8A25, 0xE663, 0x8A2A, 0x964B, 0x8A2D, 0x90DD, - 0x8A31, 0x8B96, 0x8A33, 0x96F3, 0x8A34, 0x9169, 0x8A36, 0xE664, 0x8A37, 0xFBA4, 0x8A3A, 0x9066, 0x8A3B, 0x9290, 0x8A3C, 0x8FD8, - 0x8A41, 0xE665, 0x8A46, 0xE668, 0x8A48, 0xE669, 0x8A50, 0x8DBC, 0x8A51, 0x91C0, 0x8A52, 0xE667, 0x8A54, 0x8FD9, 0x8A55, 0x955D, - 0x8A5B, 0xE666, 0x8A5E, 0x8E8C, 0x8A60, 0x8972, 0x8A62, 0xE66D, 0x8A63, 0x8C77, 0x8A66, 0x8E8E, 0x8A69, 0x8E8D, 0x8A6B, 0x986C, - 0x8A6C, 0xE66C, 0x8A6D, 0xE66B, 0x8A6E, 0x9146, 0x8A70, 0x8B6C, 0x8A71, 0x9862, 0x8A72, 0x8A59, 0x8A73, 0x8FDA, 0x8A79, 0xFBA5, - 0x8A7C, 0xE66A, 0x8A82, 0xE66F, 0x8A84, 0xE670, 0x8A85, 0xE66E, 0x8A87, 0x8CD6, 0x8A89, 0x975F, 0x8A8C, 0x8E8F, 0x8A8D, 0x9446, - 0x8A91, 0xE673, 0x8A93, 0x90BE, 0x8A95, 0x9261, 0x8A98, 0x9755, 0x8A9A, 0xE676, 0x8A9E, 0x8CEA, 0x8AA0, 0x90BD, 0x8AA1, 0xE672, - 0x8AA3, 0xE677, 0x8AA4, 0x8CEB, 0x8AA5, 0xE674, 0x8AA6, 0xE675, 0x8AA7, 0xFBA6, 0x8AA8, 0xE671, 0x8AAC, 0x90E0, 0x8AAD, 0x93C7, - 0x8AB0, 0x924E, 0x8AB2, 0x89DB, 0x8AB9, 0x94EE, 0x8ABC, 0x8B62, 0x8ABE, 0xFBA7, 0x8ABF, 0x92B2, 0x8AC2, 0xE67A, 0x8AC4, 0xE678, - 0x8AC7, 0x926B, 0x8ACB, 0x90BF, 0x8ACC, 0x8AD0, 0x8ACD, 0xE679, 0x8ACF, 0x907A, 0x8AD2, 0x97C8, 0x8AD6, 0x985F, 0x8ADA, 0xE67B, - 0x8ADB, 0xE687, 0x8ADC, 0x92B3, 0x8ADE, 0xE686, 0x8ADF, 0xFBA8, 0x8AE0, 0xE683, 0x8AE1, 0xE68B, 0x8AE2, 0xE684, 0x8AE4, 0xE680, - 0x8AE6, 0x92FA, 0x8AE7, 0xE67E, 0x8AEB, 0xE67C, 0x8AED, 0x9740, 0x8AEE, 0x8E90, 0x8AF1, 0xE681, 0x8AF3, 0xE67D, 0x8AF6, 0xFBAA, - 0x8AF7, 0xE685, 0x8AF8, 0x8F94, 0x8AFA, 0x8CBF, 0x8AFE, 0x91F8, 0x8B00, 0x9664, 0x8B01, 0x8979, 0x8B02, 0x88E0, 0x8B04, 0x93A3, - 0x8B07, 0xE689, 0x8B0C, 0xE688, 0x8B0E, 0x93E4, 0x8B10, 0xE68D, 0x8B14, 0xE682, 0x8B16, 0xE68C, 0x8B17, 0xE68E, 0x8B19, 0x8CAA, - 0x8B1A, 0xE68A, 0x8B1B, 0x8D75, 0x8B1D, 0x8ED3, 0x8B20, 0xE68F, 0x8B21, 0x9777, 0x8B26, 0xE692, 0x8B28, 0xE695, 0x8B2B, 0xE693, - 0x8B2C, 0x9554, 0x8B33, 0xE690, 0x8B39, 0x8BDE, 0x8B3E, 0xE694, 0x8B41, 0xE696, 0x8B49, 0xE69A, 0x8B4C, 0xE697, 0x8B4E, 0xE699, - 0x8B4F, 0xE698, 0x8B53, 0xFBAB, 0x8B56, 0xE69B, 0x8B58, 0x8EAF, 0x8B5A, 0xE69D, 0x8B5B, 0xE69C, 0x8B5C, 0x9588, 0x8B5F, 0xE69F, - 0x8B66, 0x8C78, 0x8B6B, 0xE69E, 0x8B6C, 0xE6A0, 0x8B6F, 0xE6A1, 0x8B70, 0x8B63, 0x8B71, 0xE3BF, 0x8B72, 0x8FF7, 0x8B74, 0xE6A2, - 0x8B77, 0x8CEC, 0x8B7D, 0xE6A3, 0x8B7F, 0xFBAC, 0x8B80, 0xE6A4, 0x8B83, 0x8E5D, 0x8B8A, 0x9DCC, 0x8B8C, 0xE6A5, 0x8B8E, 0xE6A6, - 0x8B90, 0x8F51, 0x8B92, 0xE6A7, 0x8B93, 0xE6A8, 0x8B96, 0xE6A9, 0x8B99, 0xE6AA, 0x8B9A, 0xE6AB, 0x8C37, 0x924A, 0x8C3A, 0xE6AC, - 0x8C3F, 0xE6AE, 0x8C41, 0xE6AD, 0x8C46, 0x93A4, 0x8C48, 0xE6AF, 0x8C4A, 0x964C, 0x8C4C, 0xE6B0, 0x8C4E, 0xE6B1, 0x8C50, 0xE6B2, - 0x8C55, 0xE6B3, 0x8C5A, 0x93D8, 0x8C61, 0x8FDB, 0x8C62, 0xE6B4, 0x8C6A, 0x8D8B, 0x8C6B, 0x98AC, 0x8C6C, 0xE6B5, 0x8C78, 0xE6B6, - 0x8C79, 0x955E, 0x8C7A, 0xE6B7, 0x8C7C, 0xE6BF, 0x8C82, 0xE6B8, 0x8C85, 0xE6BA, 0x8C89, 0xE6B9, 0x8C8A, 0xE6BB, 0x8C8C, 0x9665, - 0x8C8D, 0xE6BC, 0x8C8E, 0xE6BD, 0x8C94, 0xE6BE, 0x8C98, 0xE6C0, 0x8C9D, 0x8A4C, 0x8C9E, 0x92E5, 0x8CA0, 0x9589, 0x8CA1, 0x8DE0, - 0x8CA2, 0x8D76, 0x8CA7, 0x956E, 0x8CA8, 0x89DD, 0x8CA9, 0x94CC, 0x8CAA, 0xE6C3, 0x8CAB, 0x8AD1, 0x8CAC, 0x90D3, 0x8CAD, 0xE6C2, - 0x8CAE, 0xE6C7, 0x8CAF, 0x9299, 0x8CB0, 0x96E1, 0x8CB2, 0xE6C5, 0x8CB3, 0xE6C6, 0x8CB4, 0x8B4D, 0x8CB6, 0xE6C8, 0x8CB7, 0x9483, - 0x8CB8, 0x91DD, 0x8CBB, 0x94EF, 0x8CBC, 0x935C, 0x8CBD, 0xE6C4, 0x8CBF, 0x9666, 0x8CC0, 0x89EA, 0x8CC1, 0xE6CA, 0x8CC2, 0x9847, - 0x8CC3, 0x92C0, 0x8CC4, 0x9864, 0x8CC7, 0x8E91, 0x8CC8, 0xE6C9, 0x8CCA, 0x91AF, 0x8CCD, 0xE6DA, 0x8CCE, 0x9147, 0x8CD1, 0x93F6, - 0x8CD3, 0x956F, 0x8CDA, 0xE6CD, 0x8CDB, 0x8E5E, 0x8CDC, 0x8E92, 0x8CDE, 0x8FDC, 0x8CE0, 0x9485, 0x8CE2, 0x8CAB, 0x8CE3, 0xE6CC, - 0x8CE4, 0xE6CB, 0x8CE6, 0x958A, 0x8CEA, 0x8EBF, 0x8CED, 0x9371, 0x8CF0, 0xFBAD, 0x8CF4, 0xFBAE, 0x8CFA, 0xE6CF, 0x8CFB, 0xE6D0, - 0x8CFC, 0x8D77, 0x8CFD, 0xE6CE, 0x8D04, 0xE6D1, 0x8D05, 0xE6D2, 0x8D07, 0xE6D4, 0x8D08, 0x91A1, 0x8D0A, 0xE6D3, 0x8D0B, 0x8AE4, - 0x8D0D, 0xE6D6, 0x8D0F, 0xE6D5, 0x8D10, 0xE6D7, 0x8D12, 0xFBAF, 0x8D13, 0xE6D9, 0x8D14, 0xE6DB, 0x8D16, 0xE6DC, 0x8D64, 0x90D4, - 0x8D66, 0x8ECD, 0x8D67, 0xE6DD, 0x8D6B, 0x8A71, 0x8D6D, 0xE6DE, 0x8D70, 0x9196, 0x8D71, 0xE6DF, 0x8D73, 0xE6E0, 0x8D74, 0x958B, - 0x8D76, 0xFBB0, 0x8D77, 0x8B4E, 0x8D81, 0xE6E1, 0x8D85, 0x92B4, 0x8D8A, 0x897A, 0x8D99, 0xE6E2, 0x8DA3, 0x8EEF, 0x8DA8, 0x9096, - 0x8DB3, 0x91AB, 0x8DBA, 0xE6E5, 0x8DBE, 0xE6E4, 0x8DC2, 0xE6E3, 0x8DCB, 0xE6EB, 0x8DCC, 0xE6E9, 0x8DCF, 0xE6E6, 0x8DD6, 0xE6E8, - 0x8DDA, 0xE6E7, 0x8DDB, 0xE6EA, 0x8DDD, 0x8B97, 0x8DDF, 0xE6EE, 0x8DE1, 0x90D5, 0x8DE3, 0xE6EF, 0x8DE8, 0x8CD7, 0x8DEA, 0xE6EC, - 0x8DEB, 0xE6ED, 0x8DEF, 0x9848, 0x8DF3, 0x92B5, 0x8DF5, 0x9148, 0x8DFC, 0xE6F0, 0x8DFF, 0xE6F3, 0x8E08, 0xE6F1, 0x8E09, 0xE6F2, - 0x8E0A, 0x9778, 0x8E0F, 0x93A5, 0x8E10, 0xE6F6, 0x8E1D, 0xE6F4, 0x8E1E, 0xE6F5, 0x8E1F, 0xE6F7, 0x8E2A, 0xE748, 0x8E30, 0xE6FA, - 0x8E34, 0xE6FB, 0x8E35, 0xE6F9, 0x8E42, 0xE6F8, 0x8E44, 0x92FB, 0x8E47, 0xE740, 0x8E48, 0xE744, 0x8E49, 0xE741, 0x8E4A, 0xE6FC, - 0x8E4C, 0xE742, 0x8E50, 0xE743, 0x8E55, 0xE74A, 0x8E59, 0xE745, 0x8E5F, 0x90D6, 0x8E60, 0xE747, 0x8E63, 0xE749, 0x8E64, 0xE746, - 0x8E72, 0xE74C, 0x8E74, 0x8F52, 0x8E76, 0xE74B, 0x8E7C, 0xE74D, 0x8E81, 0xE74E, 0x8E84, 0xE751, 0x8E85, 0xE750, 0x8E87, 0xE74F, - 0x8E8A, 0xE753, 0x8E8B, 0xE752, 0x8E8D, 0x96F4, 0x8E91, 0xE755, 0x8E93, 0xE754, 0x8E94, 0xE756, 0x8E99, 0xE757, 0x8EA1, 0xE759, - 0x8EAA, 0xE758, 0x8EAB, 0x9067, 0x8EAC, 0xE75A, 0x8EAF, 0x8BEB, 0x8EB0, 0xE75B, 0x8EB1, 0xE75D, 0x8EBE, 0xE75E, 0x8EC5, 0xE75F, - 0x8EC6, 0xE75C, 0x8EC8, 0xE760, 0x8ECA, 0x8ED4, 0x8ECB, 0xE761, 0x8ECC, 0x8B4F, 0x8ECD, 0x8C52, 0x8ECF, 0xFBB2, 0x8ED2, 0x8CAC, - 0x8EDB, 0xE762, 0x8EDF, 0x93EE, 0x8EE2, 0x935D, 0x8EE3, 0xE763, 0x8EEB, 0xE766, 0x8EF8, 0x8EB2, 0x8EFB, 0xE765, 0x8EFC, 0xE764, - 0x8EFD, 0x8C79, 0x8EFE, 0xE767, 0x8F03, 0x8A72, 0x8F05, 0xE769, 0x8F09, 0x8DDA, 0x8F0A, 0xE768, 0x8F0C, 0xE771, 0x8F12, 0xE76B, - 0x8F13, 0xE76D, 0x8F14, 0x95E3, 0x8F15, 0xE76A, 0x8F19, 0xE76C, 0x8F1B, 0xE770, 0x8F1C, 0xE76E, 0x8F1D, 0x8B50, 0x8F1F, 0xE76F, - 0x8F26, 0xE772, 0x8F29, 0x9479, 0x8F2A, 0x97D6, 0x8F2F, 0x8F53, 0x8F33, 0xE773, 0x8F38, 0x9741, 0x8F39, 0xE775, 0x8F3B, 0xE774, - 0x8F3E, 0xE778, 0x8F3F, 0x9760, 0x8F42, 0xE777, 0x8F44, 0x8A8D, 0x8F45, 0xE776, 0x8F46, 0xE77B, 0x8F49, 0xE77A, 0x8F4C, 0xE779, - 0x8F4D, 0x9351, 0x8F4E, 0xE77C, 0x8F57, 0xE77D, 0x8F5C, 0xE77E, 0x8F5F, 0x8D8C, 0x8F61, 0x8C44, 0x8F62, 0xE780, 0x8F63, 0xE781, - 0x8F64, 0xE782, 0x8F9B, 0x9068, 0x8F9C, 0xE783, 0x8F9E, 0x8EAB, 0x8F9F, 0xE784, 0x8FA3, 0xE785, 0x8FA7, 0x999F, 0x8FA8, 0x999E, - 0x8FAD, 0xE786, 0x8FAE, 0xE390, 0x8FAF, 0xE787, 0x8FB0, 0x9243, 0x8FB1, 0x904A, 0x8FB2, 0x945F, 0x8FB7, 0xE788, 0x8FBA, 0x95D3, - 0x8FBB, 0x92D2, 0x8FBC, 0x8D9E, 0x8FBF, 0x9248, 0x8FC2, 0x8949, 0x8FC4, 0x9698, 0x8FC5, 0x9076, 0x8FCE, 0x8C7D, 0x8FD1, 0x8BDF, - 0x8FD4, 0x95D4, 0x8FDA, 0xE789, 0x8FE2, 0xE78B, 0x8FE5, 0xE78A, 0x8FE6, 0x89DE, 0x8FE9, 0x93F4, 0x8FEA, 0xE78C, 0x8FEB, 0x9497, - 0x8FED, 0x9352, 0x8FEF, 0xE78D, 0x8FF0, 0x8F71, 0x8FF4, 0xE78F, 0x8FF7, 0x96C0, 0x8FF8, 0xE79E, 0x8FF9, 0xE791, 0x8FFA, 0xE792, - 0x8FFD, 0x92C7, 0x9000, 0x91DE, 0x9001, 0x9197, 0x9003, 0x93A6, 0x9005, 0xE790, 0x9006, 0x8B74, 0x900B, 0xE799, 0x900D, 0xE796, - 0x900E, 0xE7A3, 0x900F, 0x93A7, 0x9010, 0x9280, 0x9011, 0xE793, 0x9013, 0x92FC, 0x9014, 0x9372, 0x9015, 0xE794, 0x9016, 0xE798, - 0x9017, 0x9080, 0x9019, 0x9487, 0x901A, 0x92CA, 0x901D, 0x90C0, 0x901E, 0xE797, 0x901F, 0x91AC, 0x9020, 0x91A2, 0x9021, 0xE795, - 0x9022, 0x88A7, 0x9023, 0x9841, 0x9027, 0xE79A, 0x902E, 0x91DF, 0x9031, 0x8F54, 0x9032, 0x9069, 0x9035, 0xE79C, 0x9036, 0xE79B, - 0x9038, 0x88ED, 0x9039, 0xE79D, 0x903C, 0x954E, 0x903E, 0xE7A5, 0x9041, 0x93D9, 0x9042, 0x908B, 0x9045, 0x9278, 0x9047, 0x8BF6, - 0x9049, 0xE7A4, 0x904A, 0x9756, 0x904B, 0x895E, 0x904D, 0x95D5, 0x904E, 0x89DF, 0x904F, 0xE79F, 0x9050, 0xE7A0, 0x9051, 0xE7A1, - 0x9052, 0xE7A2, 0x9053, 0x93B9, 0x9054, 0x9242, 0x9055, 0x88E1, 0x9056, 0xE7A6, 0x9058, 0xE7A7, 0x9059, 0xEAA1, 0x905C, 0x91BB, - 0x905E, 0xE7A8, 0x9060, 0x8993, 0x9061, 0x916B, 0x9063, 0x8CAD, 0x9065, 0x9779, 0x9067, 0xFBB5, 0x9068, 0xE7A9, 0x9069, 0x934B, - 0x906D, 0x9198, 0x906E, 0x8ED5, 0x906F, 0xE7AA, 0x9072, 0xE7AD, 0x9075, 0x8F85, 0x9076, 0xE7AB, 0x9077, 0x914A, 0x9078, 0x9149, - 0x907A, 0x88E2, 0x907C, 0x97C9, 0x907D, 0xE7AF, 0x907F, 0x94F0, 0x9080, 0xE7B1, 0x9081, 0xE7B0, 0x9082, 0xE7AE, 0x9083, 0xE284, - 0x9084, 0x8AD2, 0x9087, 0xE78E, 0x9089, 0xE7B3, 0x908A, 0xE7B2, 0x908F, 0xE7B4, 0x9091, 0x9757, 0x90A3, 0x93DF, 0x90A6, 0x964D, - 0x90A8, 0xE7B5, 0x90AA, 0x8ED7, 0x90AF, 0xE7B6, 0x90B1, 0xE7B7, 0x90B5, 0xE7B8, 0x90B8, 0x9340, 0x90C1, 0x88E8, 0x90CA, 0x8D78, - 0x90CE, 0x9859, 0x90DB, 0xE7BC, 0x90DE, 0xFBB6, 0x90E1, 0x8C53, 0x90E2, 0xE7B9, 0x90E4, 0xE7BA, 0x90E8, 0x9594, 0x90ED, 0x8A73, - 0x90F5, 0x9758, 0x90F7, 0x8BBD, 0x90FD, 0x9373, 0x9102, 0xE7BD, 0x9112, 0xE7BE, 0x9115, 0xFBB8, 0x9119, 0xE7BF, 0x9127, 0xFBB9, - 0x912D, 0x9341, 0x9130, 0xE7C1, 0x9132, 0xE7C0, 0x9149, 0x93D1, 0x914A, 0xE7C2, 0x914B, 0x8F55, 0x914C, 0x8EDE, 0x914D, 0x947A, - 0x914E, 0x9291, 0x9152, 0x8EF0, 0x9154, 0x908C, 0x9156, 0xE7C3, 0x9158, 0xE7C4, 0x9162, 0x907C, 0x9163, 0xE7C5, 0x9165, 0xE7C6, - 0x9169, 0xE7C7, 0x916A, 0x978F, 0x916C, 0x8F56, 0x9172, 0xE7C9, 0x9173, 0xE7C8, 0x9175, 0x8D79, 0x9177, 0x8D93, 0x9178, 0x8E5F, - 0x9182, 0xE7CC, 0x9187, 0x8F86, 0x9189, 0xE7CB, 0x918B, 0xE7CA, 0x918D, 0x91E7, 0x9190, 0x8CED, 0x9192, 0x90C1, 0x9197, 0x94AE, - 0x919C, 0x8F58, 0x91A2, 0xE7CD, 0x91A4, 0x8FDD, 0x91AA, 0xE7D0, 0x91AB, 0xE7CE, 0x91AF, 0xE7CF, 0x91B4, 0xE7D2, 0x91B5, 0xE7D1, - 0x91B8, 0x8FF8, 0x91BA, 0xE7D3, 0x91C0, 0xE7D4, 0x91C1, 0xE7D5, 0x91C6, 0x94CE, 0x91C7, 0x8DD1, 0x91C8, 0x8EDF, 0x91C9, 0xE7D6, - 0x91CB, 0xE7D7, 0x91CC, 0x97A2, 0x91CD, 0x8F64, 0x91CE, 0x96EC, 0x91CF, 0x97CA, 0x91D0, 0xE7D8, 0x91D1, 0x8BE0, 0x91D6, 0xE7D9, - 0x91D7, 0xFBBB, 0x91D8, 0x9342, 0x91DA, 0xFBBA, 0x91DB, 0xE7DC, 0x91DC, 0x8A98, 0x91DD, 0x906A, 0x91DE, 0xFBBC, 0x91DF, 0xE7DA, - 0x91E1, 0xE7DB, 0x91E3, 0x92DE, 0x91E4, 0xFBBF, 0x91E5, 0xFBC0, 0x91E6, 0x9674, 0x91E7, 0x8BFA, 0x91ED, 0xFBBD, 0x91EE, 0xFBBE, - 0x91F5, 0xE7DE, 0x91F6, 0xE7DF, 0x91FC, 0xE7DD, 0x91FF, 0xE7E1, 0x9206, 0xFBC1, 0x920A, 0xFBC3, 0x920D, 0x93DD, 0x920E, 0x8A62, - 0x9210, 0xFBC2, 0x9211, 0xE7E5, 0x9214, 0xE7E2, 0x9215, 0xE7E4, 0x921E, 0xE7E0, 0x9229, 0xE86E, 0x922C, 0xE7E3, 0x9234, 0x97E9, - 0x9237, 0x8CD8, 0x9239, 0xFBCA, 0x923A, 0xFBC4, 0x923C, 0xFBC6, 0x923F, 0xE7ED, 0x9240, 0xFBC5, 0x9244, 0x9353, 0x9245, 0xE7E8, - 0x9248, 0xE7EB, 0x9249, 0xE7E9, 0x924B, 0xE7EE, 0x924E, 0xFBC7, 0x9250, 0xE7EF, 0x9251, 0xFBC9, 0x9257, 0xE7E7, 0x9259, 0xFBC8, - 0x925A, 0xE7F4, 0x925B, 0x8994, 0x925E, 0xE7E6, 0x9262, 0x94AB, 0x9264, 0xE7EA, 0x9266, 0x8FDE, 0x9267, 0xFBCB, 0x9271, 0x8D7A, - 0x9277, 0xFBCD, 0x9278, 0xFBCE, 0x927E, 0x9667, 0x9280, 0x8BE2, 0x9283, 0x8F65, 0x9285, 0x93BA, 0x9288, 0xFA5F, 0x9291, 0x914C, - 0x9293, 0xE7F2, 0x9295, 0xE7EC, 0x9296, 0xE7F1, 0x9298, 0x96C1, 0x929A, 0x92B6, 0x929B, 0xE7F3, 0x929C, 0xE7F0, 0x92A7, 0xFBCC, - 0x92AD, 0x914B, 0x92B7, 0xE7F7, 0x92B9, 0xE7F6, 0x92CF, 0xE7F5, 0x92D0, 0xFBD2, 0x92D2, 0x964E, 0x92D3, 0xFBD6, 0x92D5, 0xFBD4, - 0x92D7, 0xFBD0, 0x92D9, 0xFBD1, 0x92E0, 0xFBD5, 0x92E4, 0x8F9B, 0x92E7, 0xFBCF, 0x92E9, 0xE7F8, 0x92EA, 0x95DD, 0x92ED, 0x8973, - 0x92F2, 0x9565, 0x92F3, 0x9292, 0x92F8, 0x8B98, 0x92F9, 0xFA65, 0x92FA, 0xE7FA, 0x92FB, 0xFBD9, 0x92FC, 0x8D7C, 0x92FF, 0xFBDC, - 0x9302, 0xFBDE, 0x9306, 0x8E4B, 0x930F, 0xE7F9, 0x9310, 0x908D, 0x9318, 0x908E, 0x9319, 0xE840, 0x931A, 0xE842, 0x931D, 0xFBDD, - 0x931E, 0xFBDB, 0x9320, 0x8FF9, 0x9321, 0xFBD8, 0x9322, 0xE841, 0x9323, 0xE843, 0x9325, 0xFBD7, 0x9326, 0x8BD1, 0x9328, 0x9564, - 0x932B, 0x8EE0, 0x932C, 0x9842, 0x932E, 0xE7FC, 0x932F, 0x8DF6, 0x9332, 0x985E, 0x9335, 0xE845, 0x933A, 0xE844, 0x933B, 0xE846, - 0x9344, 0xE7FB, 0x9348, 0xFA5E, 0x934B, 0x93E7, 0x934D, 0x9374, 0x9354, 0x92D5, 0x9356, 0xE84B, 0x9357, 0xFBE0, 0x935B, 0x9262, - 0x935C, 0xE847, 0x9360, 0xE848, 0x936C, 0x8C4C, 0x936E, 0xE84A, 0x9370, 0xFBDF, 0x9375, 0x8CAE, 0x937C, 0xE849, 0x937E, 0x8FDF, - 0x938C, 0x8A99, 0x9394, 0xE84F, 0x9396, 0x8DBD, 0x9397, 0x9199, 0x939A, 0x92C8, 0x93A4, 0xFBE1, 0x93A7, 0x8A5A, 0x93AC, 0xE84D, - 0x93AD, 0xE84E, 0x93AE, 0x92C1, 0x93B0, 0xE84C, 0x93B9, 0xE850, 0x93C3, 0xE856, 0x93C6, 0xFBE2, 0x93C8, 0xE859, 0x93D0, 0xE858, - 0x93D1, 0x934C, 0x93D6, 0xE851, 0x93D7, 0xE852, 0x93D8, 0xE855, 0x93DD, 0xE857, 0x93DE, 0xFBE3, 0x93E1, 0x8BBE, 0x93E4, 0xE85A, - 0x93E5, 0xE854, 0x93E8, 0xE853, 0x93F8, 0xFBE4, 0x9403, 0xE85E, 0x9407, 0xE85F, 0x9410, 0xE860, 0x9413, 0xE85D, 0x9414, 0xE85C, - 0x9418, 0x8FE0, 0x9419, 0x93A8, 0x941A, 0xE85B, 0x9421, 0xE864, 0x942B, 0xE862, 0x9431, 0xFBE5, 0x9435, 0xE863, 0x9436, 0xE861, - 0x9438, 0x91F6, 0x943A, 0xE865, 0x9441, 0xE866, 0x9444, 0xE868, 0x9445, 0xFBE6, 0x9448, 0xFBE7, 0x9451, 0x8AD3, 0x9452, 0xE867, - 0x9453, 0x96F8, 0x945A, 0xE873, 0x945B, 0xE869, 0x945E, 0xE86C, 0x9460, 0xE86A, 0x9462, 0xE86B, 0x946A, 0xE86D, 0x9470, 0xE86F, - 0x9475, 0xE870, 0x9477, 0xE871, 0x947C, 0xE874, 0x947D, 0xE872, 0x947E, 0xE875, 0x947F, 0xE877, 0x9481, 0xE876, 0x9577, 0x92B7, - 0x9580, 0x96E5, 0x9582, 0xE878, 0x9583, 0x914D, 0x9587, 0xE879, 0x9589, 0x95C2, 0x958A, 0xE87A, 0x958B, 0x8A4A, 0x958F, 0x895B, - 0x9591, 0x8AD5, 0x9592, 0xFBE8, 0x9593, 0x8AD4, 0x9594, 0xE87B, 0x9596, 0xE87C, 0x9598, 0xE87D, 0x9599, 0xE87E, 0x95A0, 0xE880, - 0x95A2, 0x8AD6, 0x95A3, 0x8A74, 0x95A4, 0x8D7D, 0x95A5, 0x94B4, 0x95A7, 0xE882, 0x95A8, 0xE881, 0x95AD, 0xE883, 0x95B2, 0x897B, - 0x95B9, 0xE886, 0x95BB, 0xE885, 0x95BC, 0xE884, 0x95BE, 0xE887, 0x95C3, 0xE88A, 0x95C7, 0x88C5, 0x95CA, 0xE888, 0x95CC, 0xE88C, - 0x95CD, 0xE88B, 0x95D4, 0xE88E, 0x95D5, 0xE88D, 0x95D6, 0xE88F, 0x95D8, 0x93AC, 0x95DC, 0xE890, 0x95E1, 0xE891, 0x95E2, 0xE893, - 0x95E5, 0xE892, 0x961C, 0x958C, 0x9621, 0xE894, 0x9628, 0xE895, 0x962A, 0x8DE3, 0x962E, 0xE896, 0x962F, 0xE897, 0x9632, 0x9668, - 0x963B, 0x916A, 0x963F, 0x88A2, 0x9640, 0x91C9, 0x9642, 0xE898, 0x9644, 0x958D, 0x964B, 0xE89B, 0x964C, 0xE899, 0x964D, 0x8D7E, - 0x964F, 0xE89A, 0x9650, 0x8CC0, 0x965B, 0x95C3, 0x965C, 0xE89D, 0x965D, 0xE89F, 0x965E, 0xE89E, 0x965F, 0xE8A0, 0x9662, 0x8940, - 0x9663, 0x9077, 0x9664, 0x8F9C, 0x9665, 0x8AD7, 0x9666, 0xE8A1, 0x966A, 0x9486, 0x966C, 0xE8A3, 0x9670, 0x8941, 0x9672, 0xE8A2, - 0x9673, 0x92C2, 0x9675, 0x97CB, 0x9676, 0x93A9, 0x9677, 0xE89C, 0x9678, 0x97A4, 0x967A, 0x8CAF, 0x967D, 0x977A, 0x9685, 0x8BF7, - 0x9686, 0x97B2, 0x9688, 0x8C47, 0x968A, 0x91E0, 0x968B, 0xE440, 0x968D, 0xE8A4, 0x968E, 0x8A4B, 0x968F, 0x908F, 0x9694, 0x8A75, - 0x9695, 0xE8A6, 0x9697, 0xE8A7, 0x9698, 0xE8A5, 0x9699, 0x8C84, 0x969B, 0x8DDB, 0x969C, 0x8FE1, 0x969D, 0xFBEB, 0x96A0, 0x8942, - 0x96A3, 0x97D7, 0x96A7, 0xE8A9, 0x96A8, 0xE7AC, 0x96AA, 0xE8A8, 0x96AF, 0xFBEC, 0x96B0, 0xE8AC, 0x96B1, 0xE8AA, 0x96B2, 0xE8AB, - 0x96B4, 0xE8AD, 0x96B6, 0xE8AE, 0x96B7, 0x97EA, 0x96B8, 0xE8AF, 0x96B9, 0xE8B0, 0x96BB, 0x90C7, 0x96BC, 0x94B9, 0x96C0, 0x909D, - 0x96C1, 0x8AE5, 0x96C4, 0x9759, 0x96C5, 0x89EB, 0x96C6, 0x8F57, 0x96C7, 0x8CD9, 0x96C9, 0xE8B3, 0x96CB, 0xE8B2, 0x96CC, 0x8E93, - 0x96CD, 0xE8B4, 0x96CE, 0xE8B1, 0x96D1, 0x8E47, 0x96D5, 0xE8B8, 0x96D6, 0xE5AB, 0x96D9, 0x99D4, 0x96DB, 0x9097, 0x96DC, 0xE8B6, - 0x96E2, 0x97A3, 0x96E3, 0x93EF, 0x96E8, 0x894A, 0x96EA, 0x90E1, 0x96EB, 0x8EB4, 0x96F0, 0x95B5, 0x96F2, 0x895F, 0x96F6, 0x97EB, - 0x96F7, 0x978B, 0x96F9, 0xE8B9, 0x96FB, 0x9364, 0x9700, 0x8EF9, 0x9704, 0xE8BA, 0x9706, 0xE8BB, 0x9707, 0x906B, 0x9708, 0xE8BC, - 0x970A, 0x97EC, 0x970D, 0xE8B7, 0x970E, 0xE8BE, 0x970F, 0xE8C0, 0x9711, 0xE8BF, 0x9713, 0xE8BD, 0x9716, 0xE8C1, 0x9719, 0xE8C2, - 0x971C, 0x919A, 0x971E, 0x89E0, 0x9724, 0xE8C3, 0x9727, 0x96B6, 0x972A, 0xE8C4, 0x9730, 0xE8C5, 0x9732, 0x9849, 0x9733, 0xFBED, - 0x9738, 0x9E50, 0x9739, 0xE8C6, 0x973B, 0xFBEE, 0x973D, 0xE8C7, 0x973E, 0xE8C8, 0x9742, 0xE8CC, 0x9743, 0xFBEF, 0x9744, 0xE8C9, - 0x9746, 0xE8CA, 0x9748, 0xE8CB, 0x9749, 0xE8CD, 0x974D, 0xFBF0, 0x974F, 0xFBF1, 0x9751, 0xFBF2, 0x9752, 0x90C2, 0x9755, 0xFBF3, - 0x9756, 0x96F5, 0x9759, 0x90C3, 0x975C, 0xE8CE, 0x975E, 0x94F1, 0x9760, 0xE8CF, 0x9761, 0xEA72, 0x9762, 0x96CA, 0x9764, 0xE8D0, - 0x9766, 0xE8D1, 0x9768, 0xE8D2, 0x9769, 0x8A76, 0x976B, 0xE8D4, 0x976D, 0x9078, 0x9771, 0xE8D5, 0x9774, 0x8C43, 0x9779, 0xE8D6, - 0x977A, 0xE8DA, 0x977C, 0xE8D8, 0x9781, 0xE8D9, 0x9784, 0x8A93, 0x9785, 0xE8D7, 0x9786, 0xE8DB, 0x978B, 0xE8DC, 0x978D, 0x88C6, - 0x978F, 0xE8DD, 0x9790, 0xE8DE, 0x9798, 0x8FE2, 0x979C, 0xE8DF, 0x97A0, 0x8B66, 0x97A3, 0xE8E2, 0x97A6, 0xE8E1, 0x97A8, 0xE8E0, - 0x97AB, 0xE691, 0x97AD, 0x95DA, 0x97B3, 0xE8E3, 0x97B4, 0xE8E4, 0x97C3, 0xE8E5, 0x97C6, 0xE8E6, 0x97C8, 0xE8E7, 0x97CB, 0xE8E8, - 0x97D3, 0x8AD8, 0x97DC, 0xE8E9, 0x97ED, 0xE8EA, 0x97EE, 0x9442, 0x97F2, 0xE8EC, 0x97F3, 0x89B9, 0x97F5, 0xE8EF, 0x97F6, 0xE8EE, - 0x97FB, 0x8943, 0x97FF, 0x8BBF, 0x9801, 0x95C5, 0x9802, 0x92B8, 0x9803, 0x8DA0, 0x9805, 0x8D80, 0x9806, 0x8F87, 0x9808, 0x907B, - 0x980C, 0xE8F1, 0x980F, 0xE8F0, 0x9810, 0x9761, 0x9811, 0x8AE6, 0x9812, 0x94D0, 0x9813, 0x93DA, 0x9817, 0x909C, 0x9818, 0x97CC, - 0x981A, 0x8C7A, 0x9821, 0xE8F4, 0x9824, 0xE8F3, 0x982C, 0x966A, 0x982D, 0x93AA, 0x9834, 0x896F, 0x9837, 0xE8F5, 0x9838, 0xE8F2, - 0x983B, 0x9570, 0x983C, 0x978A, 0x983D, 0xE8F6, 0x9846, 0xE8F7, 0x984B, 0xE8F9, 0x984C, 0x91E8, 0x984D, 0x8A7A, 0x984E, 0x8A7B, - 0x984F, 0xE8F8, 0x9854, 0x8AE7, 0x9855, 0x8CB0, 0x9857, 0xFBF4, 0x9858, 0x8AE8, 0x985B, 0x935E, 0x985E, 0x97DE, 0x9865, 0xFBF5, - 0x9867, 0x8CDA, 0x986B, 0xE8FA, 0x986F, 0xE8FB, 0x9870, 0xE8FC, 0x9871, 0xE940, 0x9873, 0xE942, 0x9874, 0xE941, 0x98A8, 0x9597, - 0x98AA, 0xE943, 0x98AF, 0xE944, 0x98B1, 0xE945, 0x98B6, 0xE946, 0x98C3, 0xE948, 0x98C4, 0xE947, 0x98C6, 0xE949, 0x98DB, 0x94F2, - 0x98DC, 0xE3CA, 0x98DF, 0x9048, 0x98E2, 0x8B51, 0x98E9, 0xE94A, 0x98EB, 0xE94B, 0x98ED, 0x99AA, 0x98EE, 0x9F5A, 0x98EF, 0x94D1, - 0x98F2, 0x88F9, 0x98F4, 0x88B9, 0x98FC, 0x8E94, 0x98FD, 0x964F, 0x98FE, 0x8FFC, 0x9903, 0xE94C, 0x9905, 0x96DD, 0x9909, 0xE94D, - 0x990A, 0x977B, 0x990C, 0x8961, 0x9910, 0x8E60, 0x9912, 0xE94E, 0x9913, 0x89EC, 0x9914, 0xE94F, 0x9918, 0xE950, 0x991D, 0xE952, - 0x991E, 0xE953, 0x9920, 0xE955, 0x9921, 0xE951, 0x9924, 0xE954, 0x9927, 0xFBF8, 0x9928, 0x8AD9, 0x992C, 0xE956, 0x992E, 0xE957, - 0x993D, 0xE958, 0x993E, 0xE959, 0x9942, 0xE95A, 0x9945, 0xE95C, 0x9949, 0xE95B, 0x994B, 0xE95E, 0x994C, 0xE961, 0x9950, 0xE95D, - 0x9951, 0xE95F, 0x9952, 0xE960, 0x9955, 0xE962, 0x9957, 0x8BC0, 0x9996, 0x8EF1, 0x9997, 0xE963, 0x9998, 0xE964, 0x9999, 0x8D81, - 0x999E, 0xFBFA, 0x99A5, 0xE965, 0x99A8, 0x8A5D, 0x99AC, 0x946E, 0x99AD, 0xE966, 0x99AE, 0xE967, 0x99B3, 0x9279, 0x99B4, 0x93E9, - 0x99BC, 0xE968, 0x99C1, 0x949D, 0x99C4, 0x91CA, 0x99C5, 0x8977, 0x99C6, 0x8BEC, 0x99C8, 0x8BED, 0x99D0, 0x9293, 0x99D1, 0xE96D, - 0x99D2, 0x8BEE, 0x99D5, 0x89ED, 0x99D8, 0xE96C, 0x99DB, 0xE96A, 0x99DD, 0xE96B, 0x99DF, 0xE969, 0x99E2, 0xE977, 0x99ED, 0xE96E, - 0x99EE, 0xE96F, 0x99F1, 0xE970, 0x99F2, 0xE971, 0x99F8, 0xE973, 0x99FB, 0xE972, 0x99FF, 0x8F78, 0x9A01, 0xE974, 0x9A05, 0xE976, - 0x9A0E, 0x8B52, 0x9A0F, 0xE975, 0x9A12, 0x919B, 0x9A13, 0x8CB1, 0x9A19, 0xE978, 0x9A28, 0x91CB, 0x9A2B, 0xE979, 0x9A30, 0x93AB, - 0x9A37, 0xE97A, 0x9A3E, 0xE980, 0x9A40, 0xE97D, 0x9A42, 0xE97C, 0x9A43, 0xE97E, 0x9A45, 0xE97B, 0x9A4D, 0xE982, 0x9A4E, 0xFBFB, - 0x9A55, 0xE981, 0x9A57, 0xE984, 0x9A5A, 0x8BC1, 0x9A5B, 0xE983, 0x9A5F, 0xE985, 0x9A62, 0xE986, 0x9A64, 0xE988, 0x9A65, 0xE987, - 0x9A69, 0xE989, 0x9A6A, 0xE98B, 0x9A6B, 0xE98A, 0x9AA8, 0x8D9C, 0x9AAD, 0xE98C, 0x9AB0, 0xE98D, 0x9AB8, 0x8A5B, 0x9ABC, 0xE98E, - 0x9AC0, 0xE98F, 0x9AC4, 0x9091, 0x9ACF, 0xE990, 0x9AD1, 0xE991, 0x9AD3, 0xE992, 0x9AD4, 0xE993, 0x9AD8, 0x8D82, 0x9AD9, 0xFBFC, - 0x9ADC, 0xFC40, 0x9ADE, 0xE994, 0x9ADF, 0xE995, 0x9AE2, 0xE996, 0x9AE3, 0xE997, 0x9AE6, 0xE998, 0x9AEA, 0x94AF, 0x9AEB, 0xE99A, - 0x9AED, 0x9545, 0x9AEE, 0xE99B, 0x9AEF, 0xE999, 0x9AF1, 0xE99D, 0x9AF4, 0xE99C, 0x9AF7, 0xE99E, 0x9AFB, 0xE99F, 0x9B06, 0xE9A0, - 0x9B18, 0xE9A1, 0x9B1A, 0xE9A2, 0x9B1F, 0xE9A3, 0x9B22, 0xE9A4, 0x9B23, 0xE9A5, 0x9B25, 0xE9A6, 0x9B27, 0xE9A7, 0x9B28, 0xE9A8, - 0x9B29, 0xE9A9, 0x9B2A, 0xE9AA, 0x9B2E, 0xE9AB, 0x9B2F, 0xE9AC, 0x9B31, 0x9F54, 0x9B32, 0xE9AD, 0x9B3B, 0xE2F6, 0x9B3C, 0x8B53, - 0x9B41, 0x8A40, 0x9B42, 0x8DB0, 0x9B43, 0xE9AF, 0x9B44, 0xE9AE, 0x9B45, 0x96A3, 0x9B4D, 0xE9B1, 0x9B4E, 0xE9B2, 0x9B4F, 0xE9B0, - 0x9B51, 0xE9B3, 0x9B54, 0x9682, 0x9B58, 0xE9B4, 0x9B5A, 0x8B9B, 0x9B6F, 0x9844, 0x9B72, 0xFC42, 0x9B74, 0xE9B5, 0x9B75, 0xFC41, - 0x9B83, 0xE9B7, 0x9B8E, 0x88BC, 0x9B8F, 0xFC43, 0x9B91, 0xE9B8, 0x9B92, 0x95A9, 0x9B93, 0xE9B6, 0x9B96, 0xE9B9, 0x9B97, 0xE9BA, - 0x9B9F, 0xE9BB, 0x9BA0, 0xE9BC, 0x9BA8, 0xE9BD, 0x9BAA, 0x968E, 0x9BAB, 0x8E4C, 0x9BAD, 0x8DF8, 0x9BAE, 0x914E, 0x9BB1, 0xFC44, - 0x9BB4, 0xE9BE, 0x9BB9, 0xE9C1, 0x9BBB, 0xFC45, 0x9BC0, 0xE9BF, 0x9BC6, 0xE9C2, 0x9BC9, 0x8CEF, 0x9BCA, 0xE9C0, 0x9BCF, 0xE9C3, - 0x9BD1, 0xE9C4, 0x9BD2, 0xE9C5, 0x9BD4, 0xE9C9, 0x9BD6, 0x8E49, 0x9BDB, 0x91E2, 0x9BE1, 0xE9CA, 0x9BE2, 0xE9C7, 0x9BE3, 0xE9C6, - 0x9BE4, 0xE9C8, 0x9BE8, 0x8C7E, 0x9BF0, 0xE9CE, 0x9BF1, 0xE9CD, 0x9BF2, 0xE9CC, 0x9BF5, 0x88B1, 0x9C00, 0xFC46, 0x9C04, 0xE9D8, - 0x9C06, 0xE9D4, 0x9C08, 0xE9D5, 0x9C09, 0xE9D1, 0x9C0A, 0xE9D7, 0x9C0C, 0xE9D3, 0x9C0D, 0x8A82, 0x9C10, 0x986B, 0x9C12, 0xE9D6, - 0x9C13, 0xE9D2, 0x9C14, 0xE9D0, 0x9C15, 0xE9CF, 0x9C1B, 0xE9DA, 0x9C21, 0xE9DD, 0x9C24, 0xE9DC, 0x9C25, 0xE9DB, 0x9C2D, 0x9568, - 0x9C2E, 0xE9D9, 0x9C2F, 0x88F1, 0x9C30, 0xE9DE, 0x9C32, 0xE9E0, 0x9C39, 0x8A8F, 0x9C3A, 0xE9CB, 0x9C3B, 0x8956, 0x9C3E, 0xE9E2, - 0x9C46, 0xE9E1, 0x9C47, 0xE9DF, 0x9C48, 0x924C, 0x9C52, 0x9690, 0x9C57, 0x97D8, 0x9C5A, 0xE9E3, 0x9C60, 0xE9E4, 0x9C67, 0xE9E5, - 0x9C76, 0xE9E6, 0x9C78, 0xE9E7, 0x9CE5, 0x92B9, 0x9CE7, 0xE9E8, 0x9CE9, 0x94B5, 0x9CEB, 0xE9ED, 0x9CEC, 0xE9E9, 0x9CF0, 0xE9EA, - 0x9CF3, 0x9650, 0x9CF4, 0x96C2, 0x9CF6, 0x93CE, 0x9D03, 0xE9EE, 0x9D06, 0xE9EF, 0x9D07, 0x93BC, 0x9D08, 0xE9EC, 0x9D09, 0xE9EB, - 0x9D0E, 0x89A8, 0x9D12, 0xE9F7, 0x9D15, 0xE9F6, 0x9D1B, 0x8995, 0x9D1F, 0xE9F4, 0x9D23, 0xE9F3, 0x9D26, 0xE9F1, 0x9D28, 0x8A9B, - 0x9D2A, 0xE9F0, 0x9D2B, 0x8EB0, 0x9D2C, 0x89A7, 0x9D3B, 0x8D83, 0x9D3E, 0xE9FA, 0x9D3F, 0xE9F9, 0x9D41, 0xE9F8, 0x9D44, 0xE9F5, - 0x9D46, 0xE9FB, 0x9D48, 0xE9FC, 0x9D50, 0xEA44, 0x9D51, 0xEA43, 0x9D59, 0xEA45, 0x9D5C, 0x894C, 0x9D5D, 0xEA40, 0x9D5E, 0xEA41, - 0x9D60, 0x8D94, 0x9D61, 0x96B7, 0x9D64, 0xEA42, 0x9D6B, 0xFC48, 0x9D6C, 0x9651, 0x9D6F, 0xEA4A, 0x9D70, 0xFC47, 0x9D72, 0xEA46, - 0x9D7A, 0xEA4B, 0x9D87, 0xEA48, 0x9D89, 0xEA47, 0x9D8F, 0x8C7B, 0x9D9A, 0xEA4C, 0x9DA4, 0xEA4D, 0x9DA9, 0xEA4E, 0x9DAB, 0xEA49, - 0x9DAF, 0xE9F2, 0x9DB2, 0xEA4F, 0x9DB4, 0x92DF, 0x9DB8, 0xEA53, 0x9DBA, 0xEA54, 0x9DBB, 0xEA52, 0x9DC1, 0xEA51, 0x9DC2, 0xEA57, - 0x9DC4, 0xEA50, 0x9DC6, 0xEA55, 0x9DCF, 0xEA56, 0x9DD3, 0xEA59, 0x9DD9, 0xEA58, 0x9DE6, 0xEA5B, 0x9DED, 0xEA5C, 0x9DEF, 0xEA5D, - 0x9DF2, 0x9868, 0x9DF8, 0xEA5A, 0x9DF9, 0x91E9, 0x9DFA, 0x8DEB, 0x9DFD, 0xEA5E, 0x9E19, 0xFC4A, 0x9E1A, 0xEA5F, 0x9E1B, 0xEA60, - 0x9E1E, 0xEA61, 0x9E75, 0xEA62, 0x9E78, 0x8CB2, 0x9E79, 0xEA63, 0x9E7D, 0xEA64, 0x9E7F, 0x8EAD, 0x9E81, 0xEA65, 0x9E88, 0xEA66, - 0x9E8B, 0xEA67, 0x9E8C, 0xEA68, 0x9E91, 0xEA6B, 0x9E92, 0xEA69, 0x9E93, 0x985B, 0x9E95, 0xEA6A, 0x9E97, 0x97ED, 0x9E9D, 0xEA6C, - 0x9E9F, 0x97D9, 0x9EA5, 0xEA6D, 0x9EA6, 0x949E, 0x9EA9, 0xEA6E, 0x9EAA, 0xEA70, 0x9EAD, 0xEA71, 0x9EB8, 0xEA6F, 0x9EB9, 0x8D8D, - 0x9EBA, 0x96CB, 0x9EBB, 0x9683, 0x9EBC, 0x9BF5, 0x9EBE, 0x9F80, 0x9EBF, 0x969B, 0x9EC4, 0x89A9, 0x9ECC, 0xEA73, 0x9ECD, 0x8B6F, - 0x9ECE, 0xEA74, 0x9ECF, 0xEA75, 0x9ED0, 0xEA76, 0x9ED1, 0xFC4B, 0x9ED2, 0x8D95, 0x9ED4, 0xEA77, 0x9ED8, 0xE0D2, 0x9ED9, 0x96D9, - 0x9EDB, 0x91E1, 0x9EDC, 0xEA78, 0x9EDD, 0xEA7A, 0x9EDE, 0xEA79, 0x9EE0, 0xEA7B, 0x9EE5, 0xEA7C, 0x9EE8, 0xEA7D, 0x9EEF, 0xEA7E, - 0x9EF4, 0xEA80, 0x9EF6, 0xEA81, 0x9EF7, 0xEA82, 0x9EF9, 0xEA83, 0x9EFB, 0xEA84, 0x9EFC, 0xEA85, 0x9EFD, 0xEA86, 0x9F07, 0xEA87, - 0x9F08, 0xEA88, 0x9F0E, 0x9343, 0x9F13, 0x8CDB, 0x9F15, 0xEA8A, 0x9F20, 0x916C, 0x9F21, 0xEA8B, 0x9F2C, 0xEA8C, 0x9F3B, 0x9540, - 0x9F3E, 0xEA8D, 0x9F4A, 0xEA8E, 0x9F4B, 0xE256, 0x9F4E, 0xE6D8, 0x9F4F, 0xE8EB, 0x9F52, 0xEA8F, 0x9F54, 0xEA90, 0x9F5F, 0xEA92, - 0x9F60, 0xEA93, 0x9F61, 0xEA94, 0x9F62, 0x97EE, 0x9F63, 0xEA91, 0x9F66, 0xEA95, 0x9F67, 0xEA96, 0x9F6A, 0xEA98, 0x9F6C, 0xEA97, - 0x9F72, 0xEA9A, 0x9F76, 0xEA9B, 0x9F77, 0xEA99, 0x9F8D, 0x97B4, 0x9F95, 0xEA9C, 0x9F9C, 0xEA9D, 0x9F9D, 0xE273, 0x9FA0, 0xEA9E, - 0xF929, 0xFAE0, 0xF9DC, 0xFBE9, 0xFA0E, 0xFA90, 0xFA0F, 0xFA9B, 0xFA10, 0xFA9C, 0xFA11, 0xFAB1, 0xFA12, 0xFAD8, 0xFA13, 0xFAE8, - 0xFA14, 0xFAEA, 0xFA15, 0xFB58, 0xFA16, 0xFB5E, 0xFA17, 0xFB75, 0xFA18, 0xFB7D, 0xFA19, 0xFB7E, 0xFA1A, 0xFB80, 0xFA1B, 0xFB82, - 0xFA1C, 0xFB86, 0xFA1D, 0xFB89, 0xFA1E, 0xFB92, 0xFA1F, 0xFB9D, 0xFA20, 0xFB9F, 0xFA21, 0xFBA0, 0xFA22, 0xFBA9, 0xFA23, 0xFBB1, - 0xFA24, 0xFBB3, 0xFA25, 0xFBB4, 0xFA26, 0xFBB7, 0xFA27, 0xFBD3, 0xFA28, 0xFBDA, 0xFA29, 0xFBEA, 0xFA2A, 0xFBF6, 0xFA2B, 0xFBF7, - 0xFA2C, 0xFBF9, 0xFA2D, 0xFC49, 0xFF01, 0x8149, 0xFF02, 0xFA57, 0xFF03, 0x8194, 0xFF04, 0x8190, 0xFF05, 0x8193, 0xFF06, 0x8195, - 0xFF07, 0xFA56, 0xFF08, 0x8169, 0xFF09, 0x816A, 0xFF0A, 0x8196, 0xFF0B, 0x817B, 0xFF0C, 0x8143, 0xFF0D, 0x817C, 0xFF0E, 0x8144, - 0xFF0F, 0x815E, 0xFF10, 0x824F, 0xFF11, 0x8250, 0xFF12, 0x8251, 0xFF13, 0x8252, 0xFF14, 0x8253, 0xFF15, 0x8254, 0xFF16, 0x8255, - 0xFF17, 0x8256, 0xFF18, 0x8257, 0xFF19, 0x8258, 0xFF1A, 0x8146, 0xFF1B, 0x8147, 0xFF1C, 0x8183, 0xFF1D, 0x8181, 0xFF1E, 0x8184, - 0xFF1F, 0x8148, 0xFF20, 0x8197, 0xFF21, 0x8260, 0xFF22, 0x8261, 0xFF23, 0x8262, 0xFF24, 0x8263, 0xFF25, 0x8264, 0xFF26, 0x8265, - 0xFF27, 0x8266, 0xFF28, 0x8267, 0xFF29, 0x8268, 0xFF2A, 0x8269, 0xFF2B, 0x826A, 0xFF2C, 0x826B, 0xFF2D, 0x826C, 0xFF2E, 0x826D, - 0xFF2F, 0x826E, 0xFF30, 0x826F, 0xFF31, 0x8270, 0xFF32, 0x8271, 0xFF33, 0x8272, 0xFF34, 0x8273, 0xFF35, 0x8274, 0xFF36, 0x8275, - 0xFF37, 0x8276, 0xFF38, 0x8277, 0xFF39, 0x8278, 0xFF3A, 0x8279, 0xFF3B, 0x816D, 0xFF3C, 0x815F, 0xFF3D, 0x816E, 0xFF3E, 0x814F, - 0xFF3F, 0x8151, 0xFF40, 0x814D, 0xFF41, 0x8281, 0xFF42, 0x8282, 0xFF43, 0x8283, 0xFF44, 0x8284, 0xFF45, 0x8285, 0xFF46, 0x8286, - 0xFF47, 0x8287, 0xFF48, 0x8288, 0xFF49, 0x8289, 0xFF4A, 0x828A, 0xFF4B, 0x828B, 0xFF4C, 0x828C, 0xFF4D, 0x828D, 0xFF4E, 0x828E, - 0xFF4F, 0x828F, 0xFF50, 0x8290, 0xFF51, 0x8291, 0xFF52, 0x8292, 0xFF53, 0x8293, 0xFF54, 0x8294, 0xFF55, 0x8295, 0xFF56, 0x8296, - 0xFF57, 0x8297, 0xFF58, 0x8298, 0xFF59, 0x8299, 0xFF5A, 0x829A, 0xFF5B, 0x816F, 0xFF5C, 0x8162, 0xFF5D, 0x8170, 0xFF5E, 0x8160, - 0xFF61, 0x00A1, 0xFF62, 0x00A2, 0xFF63, 0x00A3, 0xFF64, 0x00A4, 0xFF65, 0x00A5, 0xFF66, 0x00A6, 0xFF67, 0x00A7, 0xFF68, 0x00A8, - 0xFF69, 0x00A9, 0xFF6A, 0x00AA, 0xFF6B, 0x00AB, 0xFF6C, 0x00AC, 0xFF6D, 0x00AD, 0xFF6E, 0x00AE, 0xFF6F, 0x00AF, 0xFF70, 0x00B0, - 0xFF71, 0x00B1, 0xFF72, 0x00B2, 0xFF73, 0x00B3, 0xFF74, 0x00B4, 0xFF75, 0x00B5, 0xFF76, 0x00B6, 0xFF77, 0x00B7, 0xFF78, 0x00B8, - 0xFF79, 0x00B9, 0xFF7A, 0x00BA, 0xFF7B, 0x00BB, 0xFF7C, 0x00BC, 0xFF7D, 0x00BD, 0xFF7E, 0x00BE, 0xFF7F, 0x00BF, 0xFF80, 0x00C0, - 0xFF81, 0x00C1, 0xFF82, 0x00C2, 0xFF83, 0x00C3, 0xFF84, 0x00C4, 0xFF85, 0x00C5, 0xFF86, 0x00C6, 0xFF87, 0x00C7, 0xFF88, 0x00C8, - 0xFF89, 0x00C9, 0xFF8A, 0x00CA, 0xFF8B, 0x00CB, 0xFF8C, 0x00CC, 0xFF8D, 0x00CD, 0xFF8E, 0x00CE, 0xFF8F, 0x00CF, 0xFF90, 0x00D0, - 0xFF91, 0x00D1, 0xFF92, 0x00D2, 0xFF93, 0x00D3, 0xFF94, 0x00D4, 0xFF95, 0x00D5, 0xFF96, 0x00D6, 0xFF97, 0x00D7, 0xFF98, 0x00D8, - 0xFF99, 0x00D9, 0xFF9A, 0x00DA, 0xFF9B, 0x00DB, 0xFF9C, 0x00DC, 0xFF9D, 0x00DD, 0xFF9E, 0x00DE, 0xFF9F, 0x00DF, 0xFFE0, 0x8191, - 0xFFE1, 0x8192, 0xFFE2, 0x81CA, 0xFFE3, 0x8150, 0xFFE4, 0xFA55, 0xFFE5, 0x818F, 0, 0 -}; - -static const WCHAR oem2uni932[] = { /* Shift_JIS --> Unicode pairs */ - 0x00A1, 0xFF61, 0x00A2, 0xFF62, 0x00A3, 0xFF63, 0x00A4, 0xFF64, 0x00A5, 0xFF65, 0x00A6, 0xFF66, 0x00A7, 0xFF67, 0x00A8, 0xFF68, - 0x00A9, 0xFF69, 0x00AA, 0xFF6A, 0x00AB, 0xFF6B, 0x00AC, 0xFF6C, 0x00AD, 0xFF6D, 0x00AE, 0xFF6E, 0x00AF, 0xFF6F, 0x00B0, 0xFF70, - 0x00B1, 0xFF71, 0x00B2, 0xFF72, 0x00B3, 0xFF73, 0x00B4, 0xFF74, 0x00B5, 0xFF75, 0x00B6, 0xFF76, 0x00B7, 0xFF77, 0x00B8, 0xFF78, - 0x00B9, 0xFF79, 0x00BA, 0xFF7A, 0x00BB, 0xFF7B, 0x00BC, 0xFF7C, 0x00BD, 0xFF7D, 0x00BE, 0xFF7E, 0x00BF, 0xFF7F, 0x00C0, 0xFF80, - 0x00C1, 0xFF81, 0x00C2, 0xFF82, 0x00C3, 0xFF83, 0x00C4, 0xFF84, 0x00C5, 0xFF85, 0x00C6, 0xFF86, 0x00C7, 0xFF87, 0x00C8, 0xFF88, - 0x00C9, 0xFF89, 0x00CA, 0xFF8A, 0x00CB, 0xFF8B, 0x00CC, 0xFF8C, 0x00CD, 0xFF8D, 0x00CE, 0xFF8E, 0x00CF, 0xFF8F, 0x00D0, 0xFF90, - 0x00D1, 0xFF91, 0x00D2, 0xFF92, 0x00D3, 0xFF93, 0x00D4, 0xFF94, 0x00D5, 0xFF95, 0x00D6, 0xFF96, 0x00D7, 0xFF97, 0x00D8, 0xFF98, - 0x00D9, 0xFF99, 0x00DA, 0xFF9A, 0x00DB, 0xFF9B, 0x00DC, 0xFF9C, 0x00DD, 0xFF9D, 0x00DE, 0xFF9E, 0x00DF, 0xFF9F, 0x8140, 0x3000, - 0x8141, 0x3001, 0x8142, 0x3002, 0x8143, 0xFF0C, 0x8144, 0xFF0E, 0x8145, 0x30FB, 0x8146, 0xFF1A, 0x8147, 0xFF1B, 0x8148, 0xFF1F, - 0x8149, 0xFF01, 0x814A, 0x309B, 0x814B, 0x309C, 0x814C, 0x00B4, 0x814D, 0xFF40, 0x814E, 0x00A8, 0x814F, 0xFF3E, 0x8150, 0xFFE3, - 0x8151, 0xFF3F, 0x8152, 0x30FD, 0x8153, 0x30FE, 0x8154, 0x309D, 0x8155, 0x309E, 0x8156, 0x3003, 0x8157, 0x4EDD, 0x8158, 0x3005, - 0x8159, 0x3006, 0x815A, 0x3007, 0x815B, 0x30FC, 0x815C, 0x2015, 0x815D, 0x2010, 0x815E, 0xFF0F, 0x815F, 0xFF3C, 0x8160, 0xFF5E, - 0x8161, 0x2225, 0x8162, 0xFF5C, 0x8163, 0x2026, 0x8164, 0x2025, 0x8165, 0x2018, 0x8166, 0x2019, 0x8167, 0x201C, 0x8168, 0x201D, - 0x8169, 0xFF08, 0x816A, 0xFF09, 0x816B, 0x3014, 0x816C, 0x3015, 0x816D, 0xFF3B, 0x816E, 0xFF3D, 0x816F, 0xFF5B, 0x8170, 0xFF5D, - 0x8171, 0x3008, 0x8172, 0x3009, 0x8173, 0x300A, 0x8174, 0x300B, 0x8175, 0x300C, 0x8176, 0x300D, 0x8177, 0x300E, 0x8178, 0x300F, - 0x8179, 0x3010, 0x817A, 0x3011, 0x817B, 0xFF0B, 0x817C, 0xFF0D, 0x817D, 0x00B1, 0x817E, 0x00D7, 0x8180, 0x00F7, 0x8181, 0xFF1D, - 0x8182, 0x2260, 0x8183, 0xFF1C, 0x8184, 0xFF1E, 0x8185, 0x2266, 0x8186, 0x2267, 0x8187, 0x221E, 0x8188, 0x2234, 0x8189, 0x2642, - 0x818A, 0x2640, 0x818B, 0x00B0, 0x818C, 0x2032, 0x818D, 0x2033, 0x818E, 0x2103, 0x818F, 0xFFE5, 0x8190, 0xFF04, 0x8191, 0xFFE0, - 0x8192, 0xFFE1, 0x8193, 0xFF05, 0x8194, 0xFF03, 0x8195, 0xFF06, 0x8196, 0xFF0A, 0x8197, 0xFF20, 0x8198, 0x00A7, 0x8199, 0x2606, - 0x819A, 0x2605, 0x819B, 0x25CB, 0x819C, 0x25CF, 0x819D, 0x25CE, 0x819E, 0x25C7, 0x819F, 0x25C6, 0x81A0, 0x25A1, 0x81A1, 0x25A0, - 0x81A2, 0x25B3, 0x81A3, 0x25B2, 0x81A4, 0x25BD, 0x81A5, 0x25BC, 0x81A6, 0x203B, 0x81A7, 0x3012, 0x81A8, 0x2192, 0x81A9, 0x2190, - 0x81AA, 0x2191, 0x81AB, 0x2193, 0x81AC, 0x3013, 0x81B8, 0x2208, 0x81B9, 0x220B, 0x81BA, 0x2286, 0x81BB, 0x2287, 0x81BC, 0x2282, - 0x81BD, 0x2283, 0x81BE, 0x222A, 0x81BF, 0x2229, 0x81C8, 0x2227, 0x81C9, 0x2228, 0x81CA, 0xFFE2, 0x81CB, 0x21D2, 0x81CC, 0x21D4, - 0x81CD, 0x2200, 0x81CE, 0x2203, 0x81DA, 0x2220, 0x81DB, 0x22A5, 0x81DC, 0x2312, 0x81DD, 0x2202, 0x81DE, 0x2207, 0x81DF, 0x2261, - 0x81E0, 0x2252, 0x81E1, 0x226A, 0x81E2, 0x226B, 0x81E3, 0x221A, 0x81E4, 0x223D, 0x81E5, 0x221D, 0x81E6, 0x2235, 0x81E7, 0x222B, - 0x81E8, 0x222C, 0x81F0, 0x212B, 0x81F1, 0x2030, 0x81F2, 0x266F, 0x81F3, 0x266D, 0x81F4, 0x266A, 0x81F5, 0x2020, 0x81F6, 0x2021, - 0x81F7, 0x00B6, 0x81FC, 0x25EF, 0x824F, 0xFF10, 0x8250, 0xFF11, 0x8251, 0xFF12, 0x8252, 0xFF13, 0x8253, 0xFF14, 0x8254, 0xFF15, - 0x8255, 0xFF16, 0x8256, 0xFF17, 0x8257, 0xFF18, 0x8258, 0xFF19, 0x8260, 0xFF21, 0x8261, 0xFF22, 0x8262, 0xFF23, 0x8263, 0xFF24, - 0x8264, 0xFF25, 0x8265, 0xFF26, 0x8266, 0xFF27, 0x8267, 0xFF28, 0x8268, 0xFF29, 0x8269, 0xFF2A, 0x826A, 0xFF2B, 0x826B, 0xFF2C, - 0x826C, 0xFF2D, 0x826D, 0xFF2E, 0x826E, 0xFF2F, 0x826F, 0xFF30, 0x8270, 0xFF31, 0x8271, 0xFF32, 0x8272, 0xFF33, 0x8273, 0xFF34, - 0x8274, 0xFF35, 0x8275, 0xFF36, 0x8276, 0xFF37, 0x8277, 0xFF38, 0x8278, 0xFF39, 0x8279, 0xFF3A, 0x8281, 0xFF41, 0x8282, 0xFF42, - 0x8283, 0xFF43, 0x8284, 0xFF44, 0x8285, 0xFF45, 0x8286, 0xFF46, 0x8287, 0xFF47, 0x8288, 0xFF48, 0x8289, 0xFF49, 0x828A, 0xFF4A, - 0x828B, 0xFF4B, 0x828C, 0xFF4C, 0x828D, 0xFF4D, 0x828E, 0xFF4E, 0x828F, 0xFF4F, 0x8290, 0xFF50, 0x8291, 0xFF51, 0x8292, 0xFF52, - 0x8293, 0xFF53, 0x8294, 0xFF54, 0x8295, 0xFF55, 0x8296, 0xFF56, 0x8297, 0xFF57, 0x8298, 0xFF58, 0x8299, 0xFF59, 0x829A, 0xFF5A, - 0x829F, 0x3041, 0x82A0, 0x3042, 0x82A1, 0x3043, 0x82A2, 0x3044, 0x82A3, 0x3045, 0x82A4, 0x3046, 0x82A5, 0x3047, 0x82A6, 0x3048, - 0x82A7, 0x3049, 0x82A8, 0x304A, 0x82A9, 0x304B, 0x82AA, 0x304C, 0x82AB, 0x304D, 0x82AC, 0x304E, 0x82AD, 0x304F, 0x82AE, 0x3050, - 0x82AF, 0x3051, 0x82B0, 0x3052, 0x82B1, 0x3053, 0x82B2, 0x3054, 0x82B3, 0x3055, 0x82B4, 0x3056, 0x82B5, 0x3057, 0x82B6, 0x3058, - 0x82B7, 0x3059, 0x82B8, 0x305A, 0x82B9, 0x305B, 0x82BA, 0x305C, 0x82BB, 0x305D, 0x82BC, 0x305E, 0x82BD, 0x305F, 0x82BE, 0x3060, - 0x82BF, 0x3061, 0x82C0, 0x3062, 0x82C1, 0x3063, 0x82C2, 0x3064, 0x82C3, 0x3065, 0x82C4, 0x3066, 0x82C5, 0x3067, 0x82C6, 0x3068, - 0x82C7, 0x3069, 0x82C8, 0x306A, 0x82C9, 0x306B, 0x82CA, 0x306C, 0x82CB, 0x306D, 0x82CC, 0x306E, 0x82CD, 0x306F, 0x82CE, 0x3070, - 0x82CF, 0x3071, 0x82D0, 0x3072, 0x82D1, 0x3073, 0x82D2, 0x3074, 0x82D3, 0x3075, 0x82D4, 0x3076, 0x82D5, 0x3077, 0x82D6, 0x3078, - 0x82D7, 0x3079, 0x82D8, 0x307A, 0x82D9, 0x307B, 0x82DA, 0x307C, 0x82DB, 0x307D, 0x82DC, 0x307E, 0x82DD, 0x307F, 0x82DE, 0x3080, - 0x82DF, 0x3081, 0x82E0, 0x3082, 0x82E1, 0x3083, 0x82E2, 0x3084, 0x82E3, 0x3085, 0x82E4, 0x3086, 0x82E5, 0x3087, 0x82E6, 0x3088, - 0x82E7, 0x3089, 0x82E8, 0x308A, 0x82E9, 0x308B, 0x82EA, 0x308C, 0x82EB, 0x308D, 0x82EC, 0x308E, 0x82ED, 0x308F, 0x82EE, 0x3090, - 0x82EF, 0x3091, 0x82F0, 0x3092, 0x82F1, 0x3093, 0x8340, 0x30A1, 0x8341, 0x30A2, 0x8342, 0x30A3, 0x8343, 0x30A4, 0x8344, 0x30A5, - 0x8345, 0x30A6, 0x8346, 0x30A7, 0x8347, 0x30A8, 0x8348, 0x30A9, 0x8349, 0x30AA, 0x834A, 0x30AB, 0x834B, 0x30AC, 0x834C, 0x30AD, - 0x834D, 0x30AE, 0x834E, 0x30AF, 0x834F, 0x30B0, 0x8350, 0x30B1, 0x8351, 0x30B2, 0x8352, 0x30B3, 0x8353, 0x30B4, 0x8354, 0x30B5, - 0x8355, 0x30B6, 0x8356, 0x30B7, 0x8357, 0x30B8, 0x8358, 0x30B9, 0x8359, 0x30BA, 0x835A, 0x30BB, 0x835B, 0x30BC, 0x835C, 0x30BD, - 0x835D, 0x30BE, 0x835E, 0x30BF, 0x835F, 0x30C0, 0x8360, 0x30C1, 0x8361, 0x30C2, 0x8362, 0x30C3, 0x8363, 0x30C4, 0x8364, 0x30C5, - 0x8365, 0x30C6, 0x8366, 0x30C7, 0x8367, 0x30C8, 0x8368, 0x30C9, 0x8369, 0x30CA, 0x836A, 0x30CB, 0x836B, 0x30CC, 0x836C, 0x30CD, - 0x836D, 0x30CE, 0x836E, 0x30CF, 0x836F, 0x30D0, 0x8370, 0x30D1, 0x8371, 0x30D2, 0x8372, 0x30D3, 0x8373, 0x30D4, 0x8374, 0x30D5, - 0x8375, 0x30D6, 0x8376, 0x30D7, 0x8377, 0x30D8, 0x8378, 0x30D9, 0x8379, 0x30DA, 0x837A, 0x30DB, 0x837B, 0x30DC, 0x837C, 0x30DD, - 0x837D, 0x30DE, 0x837E, 0x30DF, 0x8380, 0x30E0, 0x8381, 0x30E1, 0x8382, 0x30E2, 0x8383, 0x30E3, 0x8384, 0x30E4, 0x8385, 0x30E5, - 0x8386, 0x30E6, 0x8387, 0x30E7, 0x8388, 0x30E8, 0x8389, 0x30E9, 0x838A, 0x30EA, 0x838B, 0x30EB, 0x838C, 0x30EC, 0x838D, 0x30ED, - 0x838E, 0x30EE, 0x838F, 0x30EF, 0x8390, 0x30F0, 0x8391, 0x30F1, 0x8392, 0x30F2, 0x8393, 0x30F3, 0x8394, 0x30F4, 0x8395, 0x30F5, - 0x8396, 0x30F6, 0x839F, 0x0391, 0x83A0, 0x0392, 0x83A1, 0x0393, 0x83A2, 0x0394, 0x83A3, 0x0395, 0x83A4, 0x0396, 0x83A5, 0x0397, - 0x83A6, 0x0398, 0x83A7, 0x0399, 0x83A8, 0x039A, 0x83A9, 0x039B, 0x83AA, 0x039C, 0x83AB, 0x039D, 0x83AC, 0x039E, 0x83AD, 0x039F, - 0x83AE, 0x03A0, 0x83AF, 0x03A1, 0x83B0, 0x03A3, 0x83B1, 0x03A4, 0x83B2, 0x03A5, 0x83B3, 0x03A6, 0x83B4, 0x03A7, 0x83B5, 0x03A8, - 0x83B6, 0x03A9, 0x83BF, 0x03B1, 0x83C0, 0x03B2, 0x83C1, 0x03B3, 0x83C2, 0x03B4, 0x83C3, 0x03B5, 0x83C4, 0x03B6, 0x83C5, 0x03B7, - 0x83C6, 0x03B8, 0x83C7, 0x03B9, 0x83C8, 0x03BA, 0x83C9, 0x03BB, 0x83CA, 0x03BC, 0x83CB, 0x03BD, 0x83CC, 0x03BE, 0x83CD, 0x03BF, - 0x83CE, 0x03C0, 0x83CF, 0x03C1, 0x83D0, 0x03C3, 0x83D1, 0x03C4, 0x83D2, 0x03C5, 0x83D3, 0x03C6, 0x83D4, 0x03C7, 0x83D5, 0x03C8, - 0x83D6, 0x03C9, 0x8440, 0x0410, 0x8441, 0x0411, 0x8442, 0x0412, 0x8443, 0x0413, 0x8444, 0x0414, 0x8445, 0x0415, 0x8446, 0x0401, - 0x8447, 0x0416, 0x8448, 0x0417, 0x8449, 0x0418, 0x844A, 0x0419, 0x844B, 0x041A, 0x844C, 0x041B, 0x844D, 0x041C, 0x844E, 0x041D, - 0x844F, 0x041E, 0x8450, 0x041F, 0x8451, 0x0420, 0x8452, 0x0421, 0x8453, 0x0422, 0x8454, 0x0423, 0x8455, 0x0424, 0x8456, 0x0425, - 0x8457, 0x0426, 0x8458, 0x0427, 0x8459, 0x0428, 0x845A, 0x0429, 0x845B, 0x042A, 0x845C, 0x042B, 0x845D, 0x042C, 0x845E, 0x042D, - 0x845F, 0x042E, 0x8460, 0x042F, 0x8470, 0x0430, 0x8471, 0x0431, 0x8472, 0x0432, 0x8473, 0x0433, 0x8474, 0x0434, 0x8475, 0x0435, - 0x8476, 0x0451, 0x8477, 0x0436, 0x8478, 0x0437, 0x8479, 0x0438, 0x847A, 0x0439, 0x847B, 0x043A, 0x847C, 0x043B, 0x847D, 0x043C, - 0x847E, 0x043D, 0x8480, 0x043E, 0x8481, 0x043F, 0x8482, 0x0440, 0x8483, 0x0441, 0x8484, 0x0442, 0x8485, 0x0443, 0x8486, 0x0444, - 0x8487, 0x0445, 0x8488, 0x0446, 0x8489, 0x0447, 0x848A, 0x0448, 0x848B, 0x0449, 0x848C, 0x044A, 0x848D, 0x044B, 0x848E, 0x044C, - 0x848F, 0x044D, 0x8490, 0x044E, 0x8491, 0x044F, 0x849F, 0x2500, 0x84A0, 0x2502, 0x84A1, 0x250C, 0x84A2, 0x2510, 0x84A3, 0x2518, - 0x84A4, 0x2514, 0x84A5, 0x251C, 0x84A6, 0x252C, 0x84A7, 0x2524, 0x84A8, 0x2534, 0x84A9, 0x253C, 0x84AA, 0x2501, 0x84AB, 0x2503, - 0x84AC, 0x250F, 0x84AD, 0x2513, 0x84AE, 0x251B, 0x84AF, 0x2517, 0x84B0, 0x2523, 0x84B1, 0x2533, 0x84B2, 0x252B, 0x84B3, 0x253B, - 0x84B4, 0x254B, 0x84B5, 0x2520, 0x84B6, 0x252F, 0x84B7, 0x2528, 0x84B8, 0x2537, 0x84B9, 0x253F, 0x84BA, 0x251D, 0x84BB, 0x2530, - 0x84BC, 0x2525, 0x84BD, 0x2538, 0x84BE, 0x2542, 0x8740, 0x2460, 0x8741, 0x2461, 0x8742, 0x2462, 0x8743, 0x2463, 0x8744, 0x2464, - 0x8745, 0x2465, 0x8746, 0x2466, 0x8747, 0x2467, 0x8748, 0x2468, 0x8749, 0x2469, 0x874A, 0x246A, 0x874B, 0x246B, 0x874C, 0x246C, - 0x874D, 0x246D, 0x874E, 0x246E, 0x874F, 0x246F, 0x8750, 0x2470, 0x8751, 0x2471, 0x8752, 0x2472, 0x8753, 0x2473, 0x8754, 0x2160, - 0x8755, 0x2161, 0x8756, 0x2162, 0x8757, 0x2163, 0x8758, 0x2164, 0x8759, 0x2165, 0x875A, 0x2166, 0x875B, 0x2167, 0x875C, 0x2168, - 0x875D, 0x2169, 0x875F, 0x3349, 0x8760, 0x3314, 0x8761, 0x3322, 0x8762, 0x334D, 0x8763, 0x3318, 0x8764, 0x3327, 0x8765, 0x3303, - 0x8766, 0x3336, 0x8767, 0x3351, 0x8768, 0x3357, 0x8769, 0x330D, 0x876A, 0x3326, 0x876B, 0x3323, 0x876C, 0x332B, 0x876D, 0x334A, - 0x876E, 0x333B, 0x876F, 0x339C, 0x8770, 0x339D, 0x8771, 0x339E, 0x8772, 0x338E, 0x8773, 0x338F, 0x8774, 0x33C4, 0x8775, 0x33A1, - 0x877E, 0x337B, 0x8780, 0x301D, 0x8781, 0x301F, 0x8782, 0x2116, 0x8783, 0x33CD, 0x8784, 0x2121, 0x8785, 0x32A4, 0x8786, 0x32A5, - 0x8787, 0x32A6, 0x8788, 0x32A7, 0x8789, 0x32A8, 0x878A, 0x3231, 0x878B, 0x3232, 0x878C, 0x3239, 0x878D, 0x337E, 0x878E, 0x337D, - 0x878F, 0x337C, 0x8793, 0x222E, 0x8794, 0x2211, 0x8798, 0x221F, 0x8799, 0x22BF, 0x889F, 0x4E9C, 0x88A0, 0x5516, 0x88A1, 0x5A03, - 0x88A2, 0x963F, 0x88A3, 0x54C0, 0x88A4, 0x611B, 0x88A5, 0x6328, 0x88A6, 0x59F6, 0x88A7, 0x9022, 0x88A8, 0x8475, 0x88A9, 0x831C, - 0x88AA, 0x7A50, 0x88AB, 0x60AA, 0x88AC, 0x63E1, 0x88AD, 0x6E25, 0x88AE, 0x65ED, 0x88AF, 0x8466, 0x88B0, 0x82A6, 0x88B1, 0x9BF5, - 0x88B2, 0x6893, 0x88B3, 0x5727, 0x88B4, 0x65A1, 0x88B5, 0x6271, 0x88B6, 0x5B9B, 0x88B7, 0x59D0, 0x88B8, 0x867B, 0x88B9, 0x98F4, - 0x88BA, 0x7D62, 0x88BB, 0x7DBE, 0x88BC, 0x9B8E, 0x88BD, 0x6216, 0x88BE, 0x7C9F, 0x88BF, 0x88B7, 0x88C0, 0x5B89, 0x88C1, 0x5EB5, - 0x88C2, 0x6309, 0x88C3, 0x6697, 0x88C4, 0x6848, 0x88C5, 0x95C7, 0x88C6, 0x978D, 0x88C7, 0x674F, 0x88C8, 0x4EE5, 0x88C9, 0x4F0A, - 0x88CA, 0x4F4D, 0x88CB, 0x4F9D, 0x88CC, 0x5049, 0x88CD, 0x56F2, 0x88CE, 0x5937, 0x88CF, 0x59D4, 0x88D0, 0x5A01, 0x88D1, 0x5C09, - 0x88D2, 0x60DF, 0x88D3, 0x610F, 0x88D4, 0x6170, 0x88D5, 0x6613, 0x88D6, 0x6905, 0x88D7, 0x70BA, 0x88D8, 0x754F, 0x88D9, 0x7570, - 0x88DA, 0x79FB, 0x88DB, 0x7DAD, 0x88DC, 0x7DEF, 0x88DD, 0x80C3, 0x88DE, 0x840E, 0x88DF, 0x8863, 0x88E0, 0x8B02, 0x88E1, 0x9055, - 0x88E2, 0x907A, 0x88E3, 0x533B, 0x88E4, 0x4E95, 0x88E5, 0x4EA5, 0x88E6, 0x57DF, 0x88E7, 0x80B2, 0x88E8, 0x90C1, 0x88E9, 0x78EF, - 0x88EA, 0x4E00, 0x88EB, 0x58F1, 0x88EC, 0x6EA2, 0x88ED, 0x9038, 0x88EE, 0x7A32, 0x88EF, 0x8328, 0x88F0, 0x828B, 0x88F1, 0x9C2F, - 0x88F2, 0x5141, 0x88F3, 0x5370, 0x88F4, 0x54BD, 0x88F5, 0x54E1, 0x88F6, 0x56E0, 0x88F7, 0x59FB, 0x88F8, 0x5F15, 0x88F9, 0x98F2, - 0x88FA, 0x6DEB, 0x88FB, 0x80E4, 0x88FC, 0x852D, 0x8940, 0x9662, 0x8941, 0x9670, 0x8942, 0x96A0, 0x8943, 0x97FB, 0x8944, 0x540B, - 0x8945, 0x53F3, 0x8946, 0x5B87, 0x8947, 0x70CF, 0x8948, 0x7FBD, 0x8949, 0x8FC2, 0x894A, 0x96E8, 0x894B, 0x536F, 0x894C, 0x9D5C, - 0x894D, 0x7ABA, 0x894E, 0x4E11, 0x894F, 0x7893, 0x8950, 0x81FC, 0x8951, 0x6E26, 0x8952, 0x5618, 0x8953, 0x5504, 0x8954, 0x6B1D, - 0x8955, 0x851A, 0x8956, 0x9C3B, 0x8957, 0x59E5, 0x8958, 0x53A9, 0x8959, 0x6D66, 0x895A, 0x74DC, 0x895B, 0x958F, 0x895C, 0x5642, - 0x895D, 0x4E91, 0x895E, 0x904B, 0x895F, 0x96F2, 0x8960, 0x834F, 0x8961, 0x990C, 0x8962, 0x53E1, 0x8963, 0x55B6, 0x8964, 0x5B30, - 0x8965, 0x5F71, 0x8966, 0x6620, 0x8967, 0x66F3, 0x8968, 0x6804, 0x8969, 0x6C38, 0x896A, 0x6CF3, 0x896B, 0x6D29, 0x896C, 0x745B, - 0x896D, 0x76C8, 0x896E, 0x7A4E, 0x896F, 0x9834, 0x8970, 0x82F1, 0x8971, 0x885B, 0x8972, 0x8A60, 0x8973, 0x92ED, 0x8974, 0x6DB2, - 0x8975, 0x75AB, 0x8976, 0x76CA, 0x8977, 0x99C5, 0x8978, 0x60A6, 0x8979, 0x8B01, 0x897A, 0x8D8A, 0x897B, 0x95B2, 0x897C, 0x698E, - 0x897D, 0x53AD, 0x897E, 0x5186, 0x8980, 0x5712, 0x8981, 0x5830, 0x8982, 0x5944, 0x8983, 0x5BB4, 0x8984, 0x5EF6, 0x8985, 0x6028, - 0x8986, 0x63A9, 0x8987, 0x63F4, 0x8988, 0x6CBF, 0x8989, 0x6F14, 0x898A, 0x708E, 0x898B, 0x7114, 0x898C, 0x7159, 0x898D, 0x71D5, - 0x898E, 0x733F, 0x898F, 0x7E01, 0x8990, 0x8276, 0x8991, 0x82D1, 0x8992, 0x8597, 0x8993, 0x9060, 0x8994, 0x925B, 0x8995, 0x9D1B, - 0x8996, 0x5869, 0x8997, 0x65BC, 0x8998, 0x6C5A, 0x8999, 0x7525, 0x899A, 0x51F9, 0x899B, 0x592E, 0x899C, 0x5965, 0x899D, 0x5F80, - 0x899E, 0x5FDC, 0x899F, 0x62BC, 0x89A0, 0x65FA, 0x89A1, 0x6A2A, 0x89A2, 0x6B27, 0x89A3, 0x6BB4, 0x89A4, 0x738B, 0x89A5, 0x7FC1, - 0x89A6, 0x8956, 0x89A7, 0x9D2C, 0x89A8, 0x9D0E, 0x89A9, 0x9EC4, 0x89AA, 0x5CA1, 0x89AB, 0x6C96, 0x89AC, 0x837B, 0x89AD, 0x5104, - 0x89AE, 0x5C4B, 0x89AF, 0x61B6, 0x89B0, 0x81C6, 0x89B1, 0x6876, 0x89B2, 0x7261, 0x89B3, 0x4E59, 0x89B4, 0x4FFA, 0x89B5, 0x5378, - 0x89B6, 0x6069, 0x89B7, 0x6E29, 0x89B8, 0x7A4F, 0x89B9, 0x97F3, 0x89BA, 0x4E0B, 0x89BB, 0x5316, 0x89BC, 0x4EEE, 0x89BD, 0x4F55, - 0x89BE, 0x4F3D, 0x89BF, 0x4FA1, 0x89C0, 0x4F73, 0x89C1, 0x52A0, 0x89C2, 0x53EF, 0x89C3, 0x5609, 0x89C4, 0x590F, 0x89C5, 0x5AC1, - 0x89C6, 0x5BB6, 0x89C7, 0x5BE1, 0x89C8, 0x79D1, 0x89C9, 0x6687, 0x89CA, 0x679C, 0x89CB, 0x67B6, 0x89CC, 0x6B4C, 0x89CD, 0x6CB3, - 0x89CE, 0x706B, 0x89CF, 0x73C2, 0x89D0, 0x798D, 0x89D1, 0x79BE, 0x89D2, 0x7A3C, 0x89D3, 0x7B87, 0x89D4, 0x82B1, 0x89D5, 0x82DB, - 0x89D6, 0x8304, 0x89D7, 0x8377, 0x89D8, 0x83EF, 0x89D9, 0x83D3, 0x89DA, 0x8766, 0x89DB, 0x8AB2, 0x89DC, 0x5629, 0x89DD, 0x8CA8, - 0x89DE, 0x8FE6, 0x89DF, 0x904E, 0x89E0, 0x971E, 0x89E1, 0x868A, 0x89E2, 0x4FC4, 0x89E3, 0x5CE8, 0x89E4, 0x6211, 0x89E5, 0x7259, - 0x89E6, 0x753B, 0x89E7, 0x81E5, 0x89E8, 0x82BD, 0x89E9, 0x86FE, 0x89EA, 0x8CC0, 0x89EB, 0x96C5, 0x89EC, 0x9913, 0x89ED, 0x99D5, - 0x89EE, 0x4ECB, 0x89EF, 0x4F1A, 0x89F0, 0x89E3, 0x89F1, 0x56DE, 0x89F2, 0x584A, 0x89F3, 0x58CA, 0x89F4, 0x5EFB, 0x89F5, 0x5FEB, - 0x89F6, 0x602A, 0x89F7, 0x6094, 0x89F8, 0x6062, 0x89F9, 0x61D0, 0x89FA, 0x6212, 0x89FB, 0x62D0, 0x89FC, 0x6539, 0x8A40, 0x9B41, - 0x8A41, 0x6666, 0x8A42, 0x68B0, 0x8A43, 0x6D77, 0x8A44, 0x7070, 0x8A45, 0x754C, 0x8A46, 0x7686, 0x8A47, 0x7D75, 0x8A48, 0x82A5, - 0x8A49, 0x87F9, 0x8A4A, 0x958B, 0x8A4B, 0x968E, 0x8A4C, 0x8C9D, 0x8A4D, 0x51F1, 0x8A4E, 0x52BE, 0x8A4F, 0x5916, 0x8A50, 0x54B3, - 0x8A51, 0x5BB3, 0x8A52, 0x5D16, 0x8A53, 0x6168, 0x8A54, 0x6982, 0x8A55, 0x6DAF, 0x8A56, 0x788D, 0x8A57, 0x84CB, 0x8A58, 0x8857, - 0x8A59, 0x8A72, 0x8A5A, 0x93A7, 0x8A5B, 0x9AB8, 0x8A5C, 0x6D6C, 0x8A5D, 0x99A8, 0x8A5E, 0x86D9, 0x8A5F, 0x57A3, 0x8A60, 0x67FF, - 0x8A61, 0x86CE, 0x8A62, 0x920E, 0x8A63, 0x5283, 0x8A64, 0x5687, 0x8A65, 0x5404, 0x8A66, 0x5ED3, 0x8A67, 0x62E1, 0x8A68, 0x64B9, - 0x8A69, 0x683C, 0x8A6A, 0x6838, 0x8A6B, 0x6BBB, 0x8A6C, 0x7372, 0x8A6D, 0x78BA, 0x8A6E, 0x7A6B, 0x8A6F, 0x899A, 0x8A70, 0x89D2, - 0x8A71, 0x8D6B, 0x8A72, 0x8F03, 0x8A73, 0x90ED, 0x8A74, 0x95A3, 0x8A75, 0x9694, 0x8A76, 0x9769, 0x8A77, 0x5B66, 0x8A78, 0x5CB3, - 0x8A79, 0x697D, 0x8A7A, 0x984D, 0x8A7B, 0x984E, 0x8A7C, 0x639B, 0x8A7D, 0x7B20, 0x8A7E, 0x6A2B, 0x8A80, 0x6A7F, 0x8A81, 0x68B6, - 0x8A82, 0x9C0D, 0x8A83, 0x6F5F, 0x8A84, 0x5272, 0x8A85, 0x559D, 0x8A86, 0x6070, 0x8A87, 0x62EC, 0x8A88, 0x6D3B, 0x8A89, 0x6E07, - 0x8A8A, 0x6ED1, 0x8A8B, 0x845B, 0x8A8C, 0x8910, 0x8A8D, 0x8F44, 0x8A8E, 0x4E14, 0x8A8F, 0x9C39, 0x8A90, 0x53F6, 0x8A91, 0x691B, - 0x8A92, 0x6A3A, 0x8A93, 0x9784, 0x8A94, 0x682A, 0x8A95, 0x515C, 0x8A96, 0x7AC3, 0x8A97, 0x84B2, 0x8A98, 0x91DC, 0x8A99, 0x938C, - 0x8A9A, 0x565B, 0x8A9B, 0x9D28, 0x8A9C, 0x6822, 0x8A9D, 0x8305, 0x8A9E, 0x8431, 0x8A9F, 0x7CA5, 0x8AA0, 0x5208, 0x8AA1, 0x82C5, - 0x8AA2, 0x74E6, 0x8AA3, 0x4E7E, 0x8AA4, 0x4F83, 0x8AA5, 0x51A0, 0x8AA6, 0x5BD2, 0x8AA7, 0x520A, 0x8AA8, 0x52D8, 0x8AA9, 0x52E7, - 0x8AAA, 0x5DFB, 0x8AAB, 0x559A, 0x8AAC, 0x582A, 0x8AAD, 0x59E6, 0x8AAE, 0x5B8C, 0x8AAF, 0x5B98, 0x8AB0, 0x5BDB, 0x8AB1, 0x5E72, - 0x8AB2, 0x5E79, 0x8AB3, 0x60A3, 0x8AB4, 0x611F, 0x8AB5, 0x6163, 0x8AB6, 0x61BE, 0x8AB7, 0x63DB, 0x8AB8, 0x6562, 0x8AB9, 0x67D1, - 0x8ABA, 0x6853, 0x8ABB, 0x68FA, 0x8ABC, 0x6B3E, 0x8ABD, 0x6B53, 0x8ABE, 0x6C57, 0x8ABF, 0x6F22, 0x8AC0, 0x6F97, 0x8AC1, 0x6F45, - 0x8AC2, 0x74B0, 0x8AC3, 0x7518, 0x8AC4, 0x76E3, 0x8AC5, 0x770B, 0x8AC6, 0x7AFF, 0x8AC7, 0x7BA1, 0x8AC8, 0x7C21, 0x8AC9, 0x7DE9, - 0x8ACA, 0x7F36, 0x8ACB, 0x7FF0, 0x8ACC, 0x809D, 0x8ACD, 0x8266, 0x8ACE, 0x839E, 0x8ACF, 0x89B3, 0x8AD0, 0x8ACC, 0x8AD1, 0x8CAB, - 0x8AD2, 0x9084, 0x8AD3, 0x9451, 0x8AD4, 0x9593, 0x8AD5, 0x9591, 0x8AD6, 0x95A2, 0x8AD7, 0x9665, 0x8AD8, 0x97D3, 0x8AD9, 0x9928, - 0x8ADA, 0x8218, 0x8ADB, 0x4E38, 0x8ADC, 0x542B, 0x8ADD, 0x5CB8, 0x8ADE, 0x5DCC, 0x8ADF, 0x73A9, 0x8AE0, 0x764C, 0x8AE1, 0x773C, - 0x8AE2, 0x5CA9, 0x8AE3, 0x7FEB, 0x8AE4, 0x8D0B, 0x8AE5, 0x96C1, 0x8AE6, 0x9811, 0x8AE7, 0x9854, 0x8AE8, 0x9858, 0x8AE9, 0x4F01, - 0x8AEA, 0x4F0E, 0x8AEB, 0x5371, 0x8AEC, 0x559C, 0x8AED, 0x5668, 0x8AEE, 0x57FA, 0x8AEF, 0x5947, 0x8AF0, 0x5B09, 0x8AF1, 0x5BC4, - 0x8AF2, 0x5C90, 0x8AF3, 0x5E0C, 0x8AF4, 0x5E7E, 0x8AF5, 0x5FCC, 0x8AF6, 0x63EE, 0x8AF7, 0x673A, 0x8AF8, 0x65D7, 0x8AF9, 0x65E2, - 0x8AFA, 0x671F, 0x8AFB, 0x68CB, 0x8AFC, 0x68C4, 0x8B40, 0x6A5F, 0x8B41, 0x5E30, 0x8B42, 0x6BC5, 0x8B43, 0x6C17, 0x8B44, 0x6C7D, - 0x8B45, 0x757F, 0x8B46, 0x7948, 0x8B47, 0x5B63, 0x8B48, 0x7A00, 0x8B49, 0x7D00, 0x8B4A, 0x5FBD, 0x8B4B, 0x898F, 0x8B4C, 0x8A18, - 0x8B4D, 0x8CB4, 0x8B4E, 0x8D77, 0x8B4F, 0x8ECC, 0x8B50, 0x8F1D, 0x8B51, 0x98E2, 0x8B52, 0x9A0E, 0x8B53, 0x9B3C, 0x8B54, 0x4E80, - 0x8B55, 0x507D, 0x8B56, 0x5100, 0x8B57, 0x5993, 0x8B58, 0x5B9C, 0x8B59, 0x622F, 0x8B5A, 0x6280, 0x8B5B, 0x64EC, 0x8B5C, 0x6B3A, - 0x8B5D, 0x72A0, 0x8B5E, 0x7591, 0x8B5F, 0x7947, 0x8B60, 0x7FA9, 0x8B61, 0x87FB, 0x8B62, 0x8ABC, 0x8B63, 0x8B70, 0x8B64, 0x63AC, - 0x8B65, 0x83CA, 0x8B66, 0x97A0, 0x8B67, 0x5409, 0x8B68, 0x5403, 0x8B69, 0x55AB, 0x8B6A, 0x6854, 0x8B6B, 0x6A58, 0x8B6C, 0x8A70, - 0x8B6D, 0x7827, 0x8B6E, 0x6775, 0x8B6F, 0x9ECD, 0x8B70, 0x5374, 0x8B71, 0x5BA2, 0x8B72, 0x811A, 0x8B73, 0x8650, 0x8B74, 0x9006, - 0x8B75, 0x4E18, 0x8B76, 0x4E45, 0x8B77, 0x4EC7, 0x8B78, 0x4F11, 0x8B79, 0x53CA, 0x8B7A, 0x5438, 0x8B7B, 0x5BAE, 0x8B7C, 0x5F13, - 0x8B7D, 0x6025, 0x8B7E, 0x6551, 0x8B80, 0x673D, 0x8B81, 0x6C42, 0x8B82, 0x6C72, 0x8B83, 0x6CE3, 0x8B84, 0x7078, 0x8B85, 0x7403, - 0x8B86, 0x7A76, 0x8B87, 0x7AAE, 0x8B88, 0x7B08, 0x8B89, 0x7D1A, 0x8B8A, 0x7CFE, 0x8B8B, 0x7D66, 0x8B8C, 0x65E7, 0x8B8D, 0x725B, - 0x8B8E, 0x53BB, 0x8B8F, 0x5C45, 0x8B90, 0x5DE8, 0x8B91, 0x62D2, 0x8B92, 0x62E0, 0x8B93, 0x6319, 0x8B94, 0x6E20, 0x8B95, 0x865A, - 0x8B96, 0x8A31, 0x8B97, 0x8DDD, 0x8B98, 0x92F8, 0x8B99, 0x6F01, 0x8B9A, 0x79A6, 0x8B9B, 0x9B5A, 0x8B9C, 0x4EA8, 0x8B9D, 0x4EAB, - 0x8B9E, 0x4EAC, 0x8B9F, 0x4F9B, 0x8BA0, 0x4FA0, 0x8BA1, 0x50D1, 0x8BA2, 0x5147, 0x8BA3, 0x7AF6, 0x8BA4, 0x5171, 0x8BA5, 0x51F6, - 0x8BA6, 0x5354, 0x8BA7, 0x5321, 0x8BA8, 0x537F, 0x8BA9, 0x53EB, 0x8BAA, 0x55AC, 0x8BAB, 0x5883, 0x8BAC, 0x5CE1, 0x8BAD, 0x5F37, - 0x8BAE, 0x5F4A, 0x8BAF, 0x602F, 0x8BB0, 0x6050, 0x8BB1, 0x606D, 0x8BB2, 0x631F, 0x8BB3, 0x6559, 0x8BB4, 0x6A4B, 0x8BB5, 0x6CC1, - 0x8BB6, 0x72C2, 0x8BB7, 0x72ED, 0x8BB8, 0x77EF, 0x8BB9, 0x80F8, 0x8BBA, 0x8105, 0x8BBB, 0x8208, 0x8BBC, 0x854E, 0x8BBD, 0x90F7, - 0x8BBE, 0x93E1, 0x8BBF, 0x97FF, 0x8BC0, 0x9957, 0x8BC1, 0x9A5A, 0x8BC2, 0x4EF0, 0x8BC3, 0x51DD, 0x8BC4, 0x5C2D, 0x8BC5, 0x6681, - 0x8BC6, 0x696D, 0x8BC7, 0x5C40, 0x8BC8, 0x66F2, 0x8BC9, 0x6975, 0x8BCA, 0x7389, 0x8BCB, 0x6850, 0x8BCC, 0x7C81, 0x8BCD, 0x50C5, - 0x8BCE, 0x52E4, 0x8BCF, 0x5747, 0x8BD0, 0x5DFE, 0x8BD1, 0x9326, 0x8BD2, 0x65A4, 0x8BD3, 0x6B23, 0x8BD4, 0x6B3D, 0x8BD5, 0x7434, - 0x8BD6, 0x7981, 0x8BD7, 0x79BD, 0x8BD8, 0x7B4B, 0x8BD9, 0x7DCA, 0x8BDA, 0x82B9, 0x8BDB, 0x83CC, 0x8BDC, 0x887F, 0x8BDD, 0x895F, - 0x8BDE, 0x8B39, 0x8BDF, 0x8FD1, 0x8BE0, 0x91D1, 0x8BE1, 0x541F, 0x8BE2, 0x9280, 0x8BE3, 0x4E5D, 0x8BE4, 0x5036, 0x8BE5, 0x53E5, - 0x8BE6, 0x533A, 0x8BE7, 0x72D7, 0x8BE8, 0x7396, 0x8BE9, 0x77E9, 0x8BEA, 0x82E6, 0x8BEB, 0x8EAF, 0x8BEC, 0x99C6, 0x8BED, 0x99C8, - 0x8BEE, 0x99D2, 0x8BEF, 0x5177, 0x8BF0, 0x611A, 0x8BF1, 0x865E, 0x8BF2, 0x55B0, 0x8BF3, 0x7A7A, 0x8BF4, 0x5076, 0x8BF5, 0x5BD3, - 0x8BF6, 0x9047, 0x8BF7, 0x9685, 0x8BF8, 0x4E32, 0x8BF9, 0x6ADB, 0x8BFA, 0x91E7, 0x8BFB, 0x5C51, 0x8BFC, 0x5C48, 0x8C40, 0x6398, - 0x8C41, 0x7A9F, 0x8C42, 0x6C93, 0x8C43, 0x9774, 0x8C44, 0x8F61, 0x8C45, 0x7AAA, 0x8C46, 0x718A, 0x8C47, 0x9688, 0x8C48, 0x7C82, - 0x8C49, 0x6817, 0x8C4A, 0x7E70, 0x8C4B, 0x6851, 0x8C4C, 0x936C, 0x8C4D, 0x52F2, 0x8C4E, 0x541B, 0x8C4F, 0x85AB, 0x8C50, 0x8A13, - 0x8C51, 0x7FA4, 0x8C52, 0x8ECD, 0x8C53, 0x90E1, 0x8C54, 0x5366, 0x8C55, 0x8888, 0x8C56, 0x7941, 0x8C57, 0x4FC2, 0x8C58, 0x50BE, - 0x8C59, 0x5211, 0x8C5A, 0x5144, 0x8C5B, 0x5553, 0x8C5C, 0x572D, 0x8C5D, 0x73EA, 0x8C5E, 0x578B, 0x8C5F, 0x5951, 0x8C60, 0x5F62, - 0x8C61, 0x5F84, 0x8C62, 0x6075, 0x8C63, 0x6176, 0x8C64, 0x6167, 0x8C65, 0x61A9, 0x8C66, 0x63B2, 0x8C67, 0x643A, 0x8C68, 0x656C, - 0x8C69, 0x666F, 0x8C6A, 0x6842, 0x8C6B, 0x6E13, 0x8C6C, 0x7566, 0x8C6D, 0x7A3D, 0x8C6E, 0x7CFB, 0x8C6F, 0x7D4C, 0x8C70, 0x7D99, - 0x8C71, 0x7E4B, 0x8C72, 0x7F6B, 0x8C73, 0x830E, 0x8C74, 0x834A, 0x8C75, 0x86CD, 0x8C76, 0x8A08, 0x8C77, 0x8A63, 0x8C78, 0x8B66, - 0x8C79, 0x8EFD, 0x8C7A, 0x981A, 0x8C7B, 0x9D8F, 0x8C7C, 0x82B8, 0x8C7D, 0x8FCE, 0x8C7E, 0x9BE8, 0x8C80, 0x5287, 0x8C81, 0x621F, - 0x8C82, 0x6483, 0x8C83, 0x6FC0, 0x8C84, 0x9699, 0x8C85, 0x6841, 0x8C86, 0x5091, 0x8C87, 0x6B20, 0x8C88, 0x6C7A, 0x8C89, 0x6F54, - 0x8C8A, 0x7A74, 0x8C8B, 0x7D50, 0x8C8C, 0x8840, 0x8C8D, 0x8A23, 0x8C8E, 0x6708, 0x8C8F, 0x4EF6, 0x8C90, 0x5039, 0x8C91, 0x5026, - 0x8C92, 0x5065, 0x8C93, 0x517C, 0x8C94, 0x5238, 0x8C95, 0x5263, 0x8C96, 0x55A7, 0x8C97, 0x570F, 0x8C98, 0x5805, 0x8C99, 0x5ACC, - 0x8C9A, 0x5EFA, 0x8C9B, 0x61B2, 0x8C9C, 0x61F8, 0x8C9D, 0x62F3, 0x8C9E, 0x6372, 0x8C9F, 0x691C, 0x8CA0, 0x6A29, 0x8CA1, 0x727D, - 0x8CA2, 0x72AC, 0x8CA3, 0x732E, 0x8CA4, 0x7814, 0x8CA5, 0x786F, 0x8CA6, 0x7D79, 0x8CA7, 0x770C, 0x8CA8, 0x80A9, 0x8CA9, 0x898B, - 0x8CAA, 0x8B19, 0x8CAB, 0x8CE2, 0x8CAC, 0x8ED2, 0x8CAD, 0x9063, 0x8CAE, 0x9375, 0x8CAF, 0x967A, 0x8CB0, 0x9855, 0x8CB1, 0x9A13, - 0x8CB2, 0x9E78, 0x8CB3, 0x5143, 0x8CB4, 0x539F, 0x8CB5, 0x53B3, 0x8CB6, 0x5E7B, 0x8CB7, 0x5F26, 0x8CB8, 0x6E1B, 0x8CB9, 0x6E90, - 0x8CBA, 0x7384, 0x8CBB, 0x73FE, 0x8CBC, 0x7D43, 0x8CBD, 0x8237, 0x8CBE, 0x8A00, 0x8CBF, 0x8AFA, 0x8CC0, 0x9650, 0x8CC1, 0x4E4E, - 0x8CC2, 0x500B, 0x8CC3, 0x53E4, 0x8CC4, 0x547C, 0x8CC5, 0x56FA, 0x8CC6, 0x59D1, 0x8CC7, 0x5B64, 0x8CC8, 0x5DF1, 0x8CC9, 0x5EAB, - 0x8CCA, 0x5F27, 0x8CCB, 0x6238, 0x8CCC, 0x6545, 0x8CCD, 0x67AF, 0x8CCE, 0x6E56, 0x8CCF, 0x72D0, 0x8CD0, 0x7CCA, 0x8CD1, 0x88B4, - 0x8CD2, 0x80A1, 0x8CD3, 0x80E1, 0x8CD4, 0x83F0, 0x8CD5, 0x864E, 0x8CD6, 0x8A87, 0x8CD7, 0x8DE8, 0x8CD8, 0x9237, 0x8CD9, 0x96C7, - 0x8CDA, 0x9867, 0x8CDB, 0x9F13, 0x8CDC, 0x4E94, 0x8CDD, 0x4E92, 0x8CDE, 0x4F0D, 0x8CDF, 0x5348, 0x8CE0, 0x5449, 0x8CE1, 0x543E, - 0x8CE2, 0x5A2F, 0x8CE3, 0x5F8C, 0x8CE4, 0x5FA1, 0x8CE5, 0x609F, 0x8CE6, 0x68A7, 0x8CE7, 0x6A8E, 0x8CE8, 0x745A, 0x8CE9, 0x7881, - 0x8CEA, 0x8A9E, 0x8CEB, 0x8AA4, 0x8CEC, 0x8B77, 0x8CED, 0x9190, 0x8CEE, 0x4E5E, 0x8CEF, 0x9BC9, 0x8CF0, 0x4EA4, 0x8CF1, 0x4F7C, - 0x8CF2, 0x4FAF, 0x8CF3, 0x5019, 0x8CF4, 0x5016, 0x8CF5, 0x5149, 0x8CF6, 0x516C, 0x8CF7, 0x529F, 0x8CF8, 0x52B9, 0x8CF9, 0x52FE, - 0x8CFA, 0x539A, 0x8CFB, 0x53E3, 0x8CFC, 0x5411, 0x8D40, 0x540E, 0x8D41, 0x5589, 0x8D42, 0x5751, 0x8D43, 0x57A2, 0x8D44, 0x597D, - 0x8D45, 0x5B54, 0x8D46, 0x5B5D, 0x8D47, 0x5B8F, 0x8D48, 0x5DE5, 0x8D49, 0x5DE7, 0x8D4A, 0x5DF7, 0x8D4B, 0x5E78, 0x8D4C, 0x5E83, - 0x8D4D, 0x5E9A, 0x8D4E, 0x5EB7, 0x8D4F, 0x5F18, 0x8D50, 0x6052, 0x8D51, 0x614C, 0x8D52, 0x6297, 0x8D53, 0x62D8, 0x8D54, 0x63A7, - 0x8D55, 0x653B, 0x8D56, 0x6602, 0x8D57, 0x6643, 0x8D58, 0x66F4, 0x8D59, 0x676D, 0x8D5A, 0x6821, 0x8D5B, 0x6897, 0x8D5C, 0x69CB, - 0x8D5D, 0x6C5F, 0x8D5E, 0x6D2A, 0x8D5F, 0x6D69, 0x8D60, 0x6E2F, 0x8D61, 0x6E9D, 0x8D62, 0x7532, 0x8D63, 0x7687, 0x8D64, 0x786C, - 0x8D65, 0x7A3F, 0x8D66, 0x7CE0, 0x8D67, 0x7D05, 0x8D68, 0x7D18, 0x8D69, 0x7D5E, 0x8D6A, 0x7DB1, 0x8D6B, 0x8015, 0x8D6C, 0x8003, - 0x8D6D, 0x80AF, 0x8D6E, 0x80B1, 0x8D6F, 0x8154, 0x8D70, 0x818F, 0x8D71, 0x822A, 0x8D72, 0x8352, 0x8D73, 0x884C, 0x8D74, 0x8861, - 0x8D75, 0x8B1B, 0x8D76, 0x8CA2, 0x8D77, 0x8CFC, 0x8D78, 0x90CA, 0x8D79, 0x9175, 0x8D7A, 0x9271, 0x8D7B, 0x783F, 0x8D7C, 0x92FC, - 0x8D7D, 0x95A4, 0x8D7E, 0x964D, 0x8D80, 0x9805, 0x8D81, 0x9999, 0x8D82, 0x9AD8, 0x8D83, 0x9D3B, 0x8D84, 0x525B, 0x8D85, 0x52AB, - 0x8D86, 0x53F7, 0x8D87, 0x5408, 0x8D88, 0x58D5, 0x8D89, 0x62F7, 0x8D8A, 0x6FE0, 0x8D8B, 0x8C6A, 0x8D8C, 0x8F5F, 0x8D8D, 0x9EB9, - 0x8D8E, 0x514B, 0x8D8F, 0x523B, 0x8D90, 0x544A, 0x8D91, 0x56FD, 0x8D92, 0x7A40, 0x8D93, 0x9177, 0x8D94, 0x9D60, 0x8D95, 0x9ED2, - 0x8D96, 0x7344, 0x8D97, 0x6F09, 0x8D98, 0x8170, 0x8D99, 0x7511, 0x8D9A, 0x5FFD, 0x8D9B, 0x60DA, 0x8D9C, 0x9AA8, 0x8D9D, 0x72DB, - 0x8D9E, 0x8FBC, 0x8D9F, 0x6B64, 0x8DA0, 0x9803, 0x8DA1, 0x4ECA, 0x8DA2, 0x56F0, 0x8DA3, 0x5764, 0x8DA4, 0x58BE, 0x8DA5, 0x5A5A, - 0x8DA6, 0x6068, 0x8DA7, 0x61C7, 0x8DA8, 0x660F, 0x8DA9, 0x6606, 0x8DAA, 0x6839, 0x8DAB, 0x68B1, 0x8DAC, 0x6DF7, 0x8DAD, 0x75D5, - 0x8DAE, 0x7D3A, 0x8DAF, 0x826E, 0x8DB0, 0x9B42, 0x8DB1, 0x4E9B, 0x8DB2, 0x4F50, 0x8DB3, 0x53C9, 0x8DB4, 0x5506, 0x8DB5, 0x5D6F, - 0x8DB6, 0x5DE6, 0x8DB7, 0x5DEE, 0x8DB8, 0x67FB, 0x8DB9, 0x6C99, 0x8DBA, 0x7473, 0x8DBB, 0x7802, 0x8DBC, 0x8A50, 0x8DBD, 0x9396, - 0x8DBE, 0x88DF, 0x8DBF, 0x5750, 0x8DC0, 0x5EA7, 0x8DC1, 0x632B, 0x8DC2, 0x50B5, 0x8DC3, 0x50AC, 0x8DC4, 0x518D, 0x8DC5, 0x6700, - 0x8DC6, 0x54C9, 0x8DC7, 0x585E, 0x8DC8, 0x59BB, 0x8DC9, 0x5BB0, 0x8DCA, 0x5F69, 0x8DCB, 0x624D, 0x8DCC, 0x63A1, 0x8DCD, 0x683D, - 0x8DCE, 0x6B73, 0x8DCF, 0x6E08, 0x8DD0, 0x707D, 0x8DD1, 0x91C7, 0x8DD2, 0x7280, 0x8DD3, 0x7815, 0x8DD4, 0x7826, 0x8DD5, 0x796D, - 0x8DD6, 0x658E, 0x8DD7, 0x7D30, 0x8DD8, 0x83DC, 0x8DD9, 0x88C1, 0x8DDA, 0x8F09, 0x8DDB, 0x969B, 0x8DDC, 0x5264, 0x8DDD, 0x5728, - 0x8DDE, 0x6750, 0x8DDF, 0x7F6A, 0x8DE0, 0x8CA1, 0x8DE1, 0x51B4, 0x8DE2, 0x5742, 0x8DE3, 0x962A, 0x8DE4, 0x583A, 0x8DE5, 0x698A, - 0x8DE6, 0x80B4, 0x8DE7, 0x54B2, 0x8DE8, 0x5D0E, 0x8DE9, 0x57FC, 0x8DEA, 0x7895, 0x8DEB, 0x9DFA, 0x8DEC, 0x4F5C, 0x8DED, 0x524A, - 0x8DEE, 0x548B, 0x8DEF, 0x643E, 0x8DF0, 0x6628, 0x8DF1, 0x6714, 0x8DF2, 0x67F5, 0x8DF3, 0x7A84, 0x8DF4, 0x7B56, 0x8DF5, 0x7D22, - 0x8DF6, 0x932F, 0x8DF7, 0x685C, 0x8DF8, 0x9BAD, 0x8DF9, 0x7B39, 0x8DFA, 0x5319, 0x8DFB, 0x518A, 0x8DFC, 0x5237, 0x8E40, 0x5BDF, - 0x8E41, 0x62F6, 0x8E42, 0x64AE, 0x8E43, 0x64E6, 0x8E44, 0x672D, 0x8E45, 0x6BBA, 0x8E46, 0x85A9, 0x8E47, 0x96D1, 0x8E48, 0x7690, - 0x8E49, 0x9BD6, 0x8E4A, 0x634C, 0x8E4B, 0x9306, 0x8E4C, 0x9BAB, 0x8E4D, 0x76BF, 0x8E4E, 0x6652, 0x8E4F, 0x4E09, 0x8E50, 0x5098, - 0x8E51, 0x53C2, 0x8E52, 0x5C71, 0x8E53, 0x60E8, 0x8E54, 0x6492, 0x8E55, 0x6563, 0x8E56, 0x685F, 0x8E57, 0x71E6, 0x8E58, 0x73CA, - 0x8E59, 0x7523, 0x8E5A, 0x7B97, 0x8E5B, 0x7E82, 0x8E5C, 0x8695, 0x8E5D, 0x8B83, 0x8E5E, 0x8CDB, 0x8E5F, 0x9178, 0x8E60, 0x9910, - 0x8E61, 0x65AC, 0x8E62, 0x66AB, 0x8E63, 0x6B8B, 0x8E64, 0x4ED5, 0x8E65, 0x4ED4, 0x8E66, 0x4F3A, 0x8E67, 0x4F7F, 0x8E68, 0x523A, - 0x8E69, 0x53F8, 0x8E6A, 0x53F2, 0x8E6B, 0x55E3, 0x8E6C, 0x56DB, 0x8E6D, 0x58EB, 0x8E6E, 0x59CB, 0x8E6F, 0x59C9, 0x8E70, 0x59FF, - 0x8E71, 0x5B50, 0x8E72, 0x5C4D, 0x8E73, 0x5E02, 0x8E74, 0x5E2B, 0x8E75, 0x5FD7, 0x8E76, 0x601D, 0x8E77, 0x6307, 0x8E78, 0x652F, - 0x8E79, 0x5B5C, 0x8E7A, 0x65AF, 0x8E7B, 0x65BD, 0x8E7C, 0x65E8, 0x8E7D, 0x679D, 0x8E7E, 0x6B62, 0x8E80, 0x6B7B, 0x8E81, 0x6C0F, - 0x8E82, 0x7345, 0x8E83, 0x7949, 0x8E84, 0x79C1, 0x8E85, 0x7CF8, 0x8E86, 0x7D19, 0x8E87, 0x7D2B, 0x8E88, 0x80A2, 0x8E89, 0x8102, - 0x8E8A, 0x81F3, 0x8E8B, 0x8996, 0x8E8C, 0x8A5E, 0x8E8D, 0x8A69, 0x8E8E, 0x8A66, 0x8E8F, 0x8A8C, 0x8E90, 0x8AEE, 0x8E91, 0x8CC7, - 0x8E92, 0x8CDC, 0x8E93, 0x96CC, 0x8E94, 0x98FC, 0x8E95, 0x6B6F, 0x8E96, 0x4E8B, 0x8E97, 0x4F3C, 0x8E98, 0x4F8D, 0x8E99, 0x5150, - 0x8E9A, 0x5B57, 0x8E9B, 0x5BFA, 0x8E9C, 0x6148, 0x8E9D, 0x6301, 0x8E9E, 0x6642, 0x8E9F, 0x6B21, 0x8EA0, 0x6ECB, 0x8EA1, 0x6CBB, - 0x8EA2, 0x723E, 0x8EA3, 0x74BD, 0x8EA4, 0x75D4, 0x8EA5, 0x78C1, 0x8EA6, 0x793A, 0x8EA7, 0x800C, 0x8EA8, 0x8033, 0x8EA9, 0x81EA, - 0x8EAA, 0x8494, 0x8EAB, 0x8F9E, 0x8EAC, 0x6C50, 0x8EAD, 0x9E7F, 0x8EAE, 0x5F0F, 0x8EAF, 0x8B58, 0x8EB0, 0x9D2B, 0x8EB1, 0x7AFA, - 0x8EB2, 0x8EF8, 0x8EB3, 0x5B8D, 0x8EB4, 0x96EB, 0x8EB5, 0x4E03, 0x8EB6, 0x53F1, 0x8EB7, 0x57F7, 0x8EB8, 0x5931, 0x8EB9, 0x5AC9, - 0x8EBA, 0x5BA4, 0x8EBB, 0x6089, 0x8EBC, 0x6E7F, 0x8EBD, 0x6F06, 0x8EBE, 0x75BE, 0x8EBF, 0x8CEA, 0x8EC0, 0x5B9F, 0x8EC1, 0x8500, - 0x8EC2, 0x7BE0, 0x8EC3, 0x5072, 0x8EC4, 0x67F4, 0x8EC5, 0x829D, 0x8EC6, 0x5C61, 0x8EC7, 0x854A, 0x8EC8, 0x7E1E, 0x8EC9, 0x820E, - 0x8ECA, 0x5199, 0x8ECB, 0x5C04, 0x8ECC, 0x6368, 0x8ECD, 0x8D66, 0x8ECE, 0x659C, 0x8ECF, 0x716E, 0x8ED0, 0x793E, 0x8ED1, 0x7D17, - 0x8ED2, 0x8005, 0x8ED3, 0x8B1D, 0x8ED4, 0x8ECA, 0x8ED5, 0x906E, 0x8ED6, 0x86C7, 0x8ED7, 0x90AA, 0x8ED8, 0x501F, 0x8ED9, 0x52FA, - 0x8EDA, 0x5C3A, 0x8EDB, 0x6753, 0x8EDC, 0x707C, 0x8EDD, 0x7235, 0x8EDE, 0x914C, 0x8EDF, 0x91C8, 0x8EE0, 0x932B, 0x8EE1, 0x82E5, - 0x8EE2, 0x5BC2, 0x8EE3, 0x5F31, 0x8EE4, 0x60F9, 0x8EE5, 0x4E3B, 0x8EE6, 0x53D6, 0x8EE7, 0x5B88, 0x8EE8, 0x624B, 0x8EE9, 0x6731, - 0x8EEA, 0x6B8A, 0x8EEB, 0x72E9, 0x8EEC, 0x73E0, 0x8EED, 0x7A2E, 0x8EEE, 0x816B, 0x8EEF, 0x8DA3, 0x8EF0, 0x9152, 0x8EF1, 0x9996, - 0x8EF2, 0x5112, 0x8EF3, 0x53D7, 0x8EF4, 0x546A, 0x8EF5, 0x5BFF, 0x8EF6, 0x6388, 0x8EF7, 0x6A39, 0x8EF8, 0x7DAC, 0x8EF9, 0x9700, - 0x8EFA, 0x56DA, 0x8EFB, 0x53CE, 0x8EFC, 0x5468, 0x8F40, 0x5B97, 0x8F41, 0x5C31, 0x8F42, 0x5DDE, 0x8F43, 0x4FEE, 0x8F44, 0x6101, - 0x8F45, 0x62FE, 0x8F46, 0x6D32, 0x8F47, 0x79C0, 0x8F48, 0x79CB, 0x8F49, 0x7D42, 0x8F4A, 0x7E4D, 0x8F4B, 0x7FD2, 0x8F4C, 0x81ED, - 0x8F4D, 0x821F, 0x8F4E, 0x8490, 0x8F4F, 0x8846, 0x8F50, 0x8972, 0x8F51, 0x8B90, 0x8F52, 0x8E74, 0x8F53, 0x8F2F, 0x8F54, 0x9031, - 0x8F55, 0x914B, 0x8F56, 0x916C, 0x8F57, 0x96C6, 0x8F58, 0x919C, 0x8F59, 0x4EC0, 0x8F5A, 0x4F4F, 0x8F5B, 0x5145, 0x8F5C, 0x5341, - 0x8F5D, 0x5F93, 0x8F5E, 0x620E, 0x8F5F, 0x67D4, 0x8F60, 0x6C41, 0x8F61, 0x6E0B, 0x8F62, 0x7363, 0x8F63, 0x7E26, 0x8F64, 0x91CD, - 0x8F65, 0x9283, 0x8F66, 0x53D4, 0x8F67, 0x5919, 0x8F68, 0x5BBF, 0x8F69, 0x6DD1, 0x8F6A, 0x795D, 0x8F6B, 0x7E2E, 0x8F6C, 0x7C9B, - 0x8F6D, 0x587E, 0x8F6E, 0x719F, 0x8F6F, 0x51FA, 0x8F70, 0x8853, 0x8F71, 0x8FF0, 0x8F72, 0x4FCA, 0x8F73, 0x5CFB, 0x8F74, 0x6625, - 0x8F75, 0x77AC, 0x8F76, 0x7AE3, 0x8F77, 0x821C, 0x8F78, 0x99FF, 0x8F79, 0x51C6, 0x8F7A, 0x5FAA, 0x8F7B, 0x65EC, 0x8F7C, 0x696F, - 0x8F7D, 0x6B89, 0x8F7E, 0x6DF3, 0x8F80, 0x6E96, 0x8F81, 0x6F64, 0x8F82, 0x76FE, 0x8F83, 0x7D14, 0x8F84, 0x5DE1, 0x8F85, 0x9075, - 0x8F86, 0x9187, 0x8F87, 0x9806, 0x8F88, 0x51E6, 0x8F89, 0x521D, 0x8F8A, 0x6240, 0x8F8B, 0x6691, 0x8F8C, 0x66D9, 0x8F8D, 0x6E1A, - 0x8F8E, 0x5EB6, 0x8F8F, 0x7DD2, 0x8F90, 0x7F72, 0x8F91, 0x66F8, 0x8F92, 0x85AF, 0x8F93, 0x85F7, 0x8F94, 0x8AF8, 0x8F95, 0x52A9, - 0x8F96, 0x53D9, 0x8F97, 0x5973, 0x8F98, 0x5E8F, 0x8F99, 0x5F90, 0x8F9A, 0x6055, 0x8F9B, 0x92E4, 0x8F9C, 0x9664, 0x8F9D, 0x50B7, - 0x8F9E, 0x511F, 0x8F9F, 0x52DD, 0x8FA0, 0x5320, 0x8FA1, 0x5347, 0x8FA2, 0x53EC, 0x8FA3, 0x54E8, 0x8FA4, 0x5546, 0x8FA5, 0x5531, - 0x8FA6, 0x5617, 0x8FA7, 0x5968, 0x8FA8, 0x59BE, 0x8FA9, 0x5A3C, 0x8FAA, 0x5BB5, 0x8FAB, 0x5C06, 0x8FAC, 0x5C0F, 0x8FAD, 0x5C11, - 0x8FAE, 0x5C1A, 0x8FAF, 0x5E84, 0x8FB0, 0x5E8A, 0x8FB1, 0x5EE0, 0x8FB2, 0x5F70, 0x8FB3, 0x627F, 0x8FB4, 0x6284, 0x8FB5, 0x62DB, - 0x8FB6, 0x638C, 0x8FB7, 0x6377, 0x8FB8, 0x6607, 0x8FB9, 0x660C, 0x8FBA, 0x662D, 0x8FBB, 0x6676, 0x8FBC, 0x677E, 0x8FBD, 0x68A2, - 0x8FBE, 0x6A1F, 0x8FBF, 0x6A35, 0x8FC0, 0x6CBC, 0x8FC1, 0x6D88, 0x8FC2, 0x6E09, 0x8FC3, 0x6E58, 0x8FC4, 0x713C, 0x8FC5, 0x7126, - 0x8FC6, 0x7167, 0x8FC7, 0x75C7, 0x8FC8, 0x7701, 0x8FC9, 0x785D, 0x8FCA, 0x7901, 0x8FCB, 0x7965, 0x8FCC, 0x79F0, 0x8FCD, 0x7AE0, - 0x8FCE, 0x7B11, 0x8FCF, 0x7CA7, 0x8FD0, 0x7D39, 0x8FD1, 0x8096, 0x8FD2, 0x83D6, 0x8FD3, 0x848B, 0x8FD4, 0x8549, 0x8FD5, 0x885D, - 0x8FD6, 0x88F3, 0x8FD7, 0x8A1F, 0x8FD8, 0x8A3C, 0x8FD9, 0x8A54, 0x8FDA, 0x8A73, 0x8FDB, 0x8C61, 0x8FDC, 0x8CDE, 0x8FDD, 0x91A4, - 0x8FDE, 0x9266, 0x8FDF, 0x937E, 0x8FE0, 0x9418, 0x8FE1, 0x969C, 0x8FE2, 0x9798, 0x8FE3, 0x4E0A, 0x8FE4, 0x4E08, 0x8FE5, 0x4E1E, - 0x8FE6, 0x4E57, 0x8FE7, 0x5197, 0x8FE8, 0x5270, 0x8FE9, 0x57CE, 0x8FEA, 0x5834, 0x8FEB, 0x58CC, 0x8FEC, 0x5B22, 0x8FED, 0x5E38, - 0x8FEE, 0x60C5, 0x8FEF, 0x64FE, 0x8FF0, 0x6761, 0x8FF1, 0x6756, 0x8FF2, 0x6D44, 0x8FF3, 0x72B6, 0x8FF4, 0x7573, 0x8FF5, 0x7A63, - 0x8FF6, 0x84B8, 0x8FF7, 0x8B72, 0x8FF8, 0x91B8, 0x8FF9, 0x9320, 0x8FFA, 0x5631, 0x8FFB, 0x57F4, 0x8FFC, 0x98FE, 0x9040, 0x62ED, - 0x9041, 0x690D, 0x9042, 0x6B96, 0x9043, 0x71ED, 0x9044, 0x7E54, 0x9045, 0x8077, 0x9046, 0x8272, 0x9047, 0x89E6, 0x9048, 0x98DF, - 0x9049, 0x8755, 0x904A, 0x8FB1, 0x904B, 0x5C3B, 0x904C, 0x4F38, 0x904D, 0x4FE1, 0x904E, 0x4FB5, 0x904F, 0x5507, 0x9050, 0x5A20, - 0x9051, 0x5BDD, 0x9052, 0x5BE9, 0x9053, 0x5FC3, 0x9054, 0x614E, 0x9055, 0x632F, 0x9056, 0x65B0, 0x9057, 0x664B, 0x9058, 0x68EE, - 0x9059, 0x699B, 0x905A, 0x6D78, 0x905B, 0x6DF1, 0x905C, 0x7533, 0x905D, 0x75B9, 0x905E, 0x771F, 0x905F, 0x795E, 0x9060, 0x79E6, - 0x9061, 0x7D33, 0x9062, 0x81E3, 0x9063, 0x82AF, 0x9064, 0x85AA, 0x9065, 0x89AA, 0x9066, 0x8A3A, 0x9067, 0x8EAB, 0x9068, 0x8F9B, - 0x9069, 0x9032, 0x906A, 0x91DD, 0x906B, 0x9707, 0x906C, 0x4EBA, 0x906D, 0x4EC1, 0x906E, 0x5203, 0x906F, 0x5875, 0x9070, 0x58EC, - 0x9071, 0x5C0B, 0x9072, 0x751A, 0x9073, 0x5C3D, 0x9074, 0x814E, 0x9075, 0x8A0A, 0x9076, 0x8FC5, 0x9077, 0x9663, 0x9078, 0x976D, - 0x9079, 0x7B25, 0x907A, 0x8ACF, 0x907B, 0x9808, 0x907C, 0x9162, 0x907D, 0x56F3, 0x907E, 0x53A8, 0x9080, 0x9017, 0x9081, 0x5439, - 0x9082, 0x5782, 0x9083, 0x5E25, 0x9084, 0x63A8, 0x9085, 0x6C34, 0x9086, 0x708A, 0x9087, 0x7761, 0x9088, 0x7C8B, 0x9089, 0x7FE0, - 0x908A, 0x8870, 0x908B, 0x9042, 0x908C, 0x9154, 0x908D, 0x9310, 0x908E, 0x9318, 0x908F, 0x968F, 0x9090, 0x745E, 0x9091, 0x9AC4, - 0x9092, 0x5D07, 0x9093, 0x5D69, 0x9094, 0x6570, 0x9095, 0x67A2, 0x9096, 0x8DA8, 0x9097, 0x96DB, 0x9098, 0x636E, 0x9099, 0x6749, - 0x909A, 0x6919, 0x909B, 0x83C5, 0x909C, 0x9817, 0x909D, 0x96C0, 0x909E, 0x88FE, 0x909F, 0x6F84, 0x90A0, 0x647A, 0x90A1, 0x5BF8, - 0x90A2, 0x4E16, 0x90A3, 0x702C, 0x90A4, 0x755D, 0x90A5, 0x662F, 0x90A6, 0x51C4, 0x90A7, 0x5236, 0x90A8, 0x52E2, 0x90A9, 0x59D3, - 0x90AA, 0x5F81, 0x90AB, 0x6027, 0x90AC, 0x6210, 0x90AD, 0x653F, 0x90AE, 0x6574, 0x90AF, 0x661F, 0x90B0, 0x6674, 0x90B1, 0x68F2, - 0x90B2, 0x6816, 0x90B3, 0x6B63, 0x90B4, 0x6E05, 0x90B5, 0x7272, 0x90B6, 0x751F, 0x90B7, 0x76DB, 0x90B8, 0x7CBE, 0x90B9, 0x8056, - 0x90BA, 0x58F0, 0x90BB, 0x88FD, 0x90BC, 0x897F, 0x90BD, 0x8AA0, 0x90BE, 0x8A93, 0x90BF, 0x8ACB, 0x90C0, 0x901D, 0x90C1, 0x9192, - 0x90C2, 0x9752, 0x90C3, 0x9759, 0x90C4, 0x6589, 0x90C5, 0x7A0E, 0x90C6, 0x8106, 0x90C7, 0x96BB, 0x90C8, 0x5E2D, 0x90C9, 0x60DC, - 0x90CA, 0x621A, 0x90CB, 0x65A5, 0x90CC, 0x6614, 0x90CD, 0x6790, 0x90CE, 0x77F3, 0x90CF, 0x7A4D, 0x90D0, 0x7C4D, 0x90D1, 0x7E3E, - 0x90D2, 0x810A, 0x90D3, 0x8CAC, 0x90D4, 0x8D64, 0x90D5, 0x8DE1, 0x90D6, 0x8E5F, 0x90D7, 0x78A9, 0x90D8, 0x5207, 0x90D9, 0x62D9, - 0x90DA, 0x63A5, 0x90DB, 0x6442, 0x90DC, 0x6298, 0x90DD, 0x8A2D, 0x90DE, 0x7A83, 0x90DF, 0x7BC0, 0x90E0, 0x8AAC, 0x90E1, 0x96EA, - 0x90E2, 0x7D76, 0x90E3, 0x820C, 0x90E4, 0x8749, 0x90E5, 0x4ED9, 0x90E6, 0x5148, 0x90E7, 0x5343, 0x90E8, 0x5360, 0x90E9, 0x5BA3, - 0x90EA, 0x5C02, 0x90EB, 0x5C16, 0x90EC, 0x5DDD, 0x90ED, 0x6226, 0x90EE, 0x6247, 0x90EF, 0x64B0, 0x90F0, 0x6813, 0x90F1, 0x6834, - 0x90F2, 0x6CC9, 0x90F3, 0x6D45, 0x90F4, 0x6D17, 0x90F5, 0x67D3, 0x90F6, 0x6F5C, 0x90F7, 0x714E, 0x90F8, 0x717D, 0x90F9, 0x65CB, - 0x90FA, 0x7A7F, 0x90FB, 0x7BAD, 0x90FC, 0x7DDA, 0x9140, 0x7E4A, 0x9141, 0x7FA8, 0x9142, 0x817A, 0x9143, 0x821B, 0x9144, 0x8239, - 0x9145, 0x85A6, 0x9146, 0x8A6E, 0x9147, 0x8CCE, 0x9148, 0x8DF5, 0x9149, 0x9078, 0x914A, 0x9077, 0x914B, 0x92AD, 0x914C, 0x9291, - 0x914D, 0x9583, 0x914E, 0x9BAE, 0x914F, 0x524D, 0x9150, 0x5584, 0x9151, 0x6F38, 0x9152, 0x7136, 0x9153, 0x5168, 0x9154, 0x7985, - 0x9155, 0x7E55, 0x9156, 0x81B3, 0x9157, 0x7CCE, 0x9158, 0x564C, 0x9159, 0x5851, 0x915A, 0x5CA8, 0x915B, 0x63AA, 0x915C, 0x66FE, - 0x915D, 0x66FD, 0x915E, 0x695A, 0x915F, 0x72D9, 0x9160, 0x758F, 0x9161, 0x758E, 0x9162, 0x790E, 0x9163, 0x7956, 0x9164, 0x79DF, - 0x9165, 0x7C97, 0x9166, 0x7D20, 0x9167, 0x7D44, 0x9168, 0x8607, 0x9169, 0x8A34, 0x916A, 0x963B, 0x916B, 0x9061, 0x916C, 0x9F20, - 0x916D, 0x50E7, 0x916E, 0x5275, 0x916F, 0x53CC, 0x9170, 0x53E2, 0x9171, 0x5009, 0x9172, 0x55AA, 0x9173, 0x58EE, 0x9174, 0x594F, - 0x9175, 0x723D, 0x9176, 0x5B8B, 0x9177, 0x5C64, 0x9178, 0x531D, 0x9179, 0x60E3, 0x917A, 0x60F3, 0x917B, 0x635C, 0x917C, 0x6383, - 0x917D, 0x633F, 0x917E, 0x63BB, 0x9180, 0x64CD, 0x9181, 0x65E9, 0x9182, 0x66F9, 0x9183, 0x5DE3, 0x9184, 0x69CD, 0x9185, 0x69FD, - 0x9186, 0x6F15, 0x9187, 0x71E5, 0x9188, 0x4E89, 0x9189, 0x75E9, 0x918A, 0x76F8, 0x918B, 0x7A93, 0x918C, 0x7CDF, 0x918D, 0x7DCF, - 0x918E, 0x7D9C, 0x918F, 0x8061, 0x9190, 0x8349, 0x9191, 0x8358, 0x9192, 0x846C, 0x9193, 0x84BC, 0x9194, 0x85FB, 0x9195, 0x88C5, - 0x9196, 0x8D70, 0x9197, 0x9001, 0x9198, 0x906D, 0x9199, 0x9397, 0x919A, 0x971C, 0x919B, 0x9A12, 0x919C, 0x50CF, 0x919D, 0x5897, - 0x919E, 0x618E, 0x919F, 0x81D3, 0x91A0, 0x8535, 0x91A1, 0x8D08, 0x91A2, 0x9020, 0x91A3, 0x4FC3, 0x91A4, 0x5074, 0x91A5, 0x5247, - 0x91A6, 0x5373, 0x91A7, 0x606F, 0x91A8, 0x6349, 0x91A9, 0x675F, 0x91AA, 0x6E2C, 0x91AB, 0x8DB3, 0x91AC, 0x901F, 0x91AD, 0x4FD7, - 0x91AE, 0x5C5E, 0x91AF, 0x8CCA, 0x91B0, 0x65CF, 0x91B1, 0x7D9A, 0x91B2, 0x5352, 0x91B3, 0x8896, 0x91B4, 0x5176, 0x91B5, 0x63C3, - 0x91B6, 0x5B58, 0x91B7, 0x5B6B, 0x91B8, 0x5C0A, 0x91B9, 0x640D, 0x91BA, 0x6751, 0x91BB, 0x905C, 0x91BC, 0x4ED6, 0x91BD, 0x591A, - 0x91BE, 0x592A, 0x91BF, 0x6C70, 0x91C0, 0x8A51, 0x91C1, 0x553E, 0x91C2, 0x5815, 0x91C3, 0x59A5, 0x91C4, 0x60F0, 0x91C5, 0x6253, - 0x91C6, 0x67C1, 0x91C7, 0x8235, 0x91C8, 0x6955, 0x91C9, 0x9640, 0x91CA, 0x99C4, 0x91CB, 0x9A28, 0x91CC, 0x4F53, 0x91CD, 0x5806, - 0x91CE, 0x5BFE, 0x91CF, 0x8010, 0x91D0, 0x5CB1, 0x91D1, 0x5E2F, 0x91D2, 0x5F85, 0x91D3, 0x6020, 0x91D4, 0x614B, 0x91D5, 0x6234, - 0x91D6, 0x66FF, 0x91D7, 0x6CF0, 0x91D8, 0x6EDE, 0x91D9, 0x80CE, 0x91DA, 0x817F, 0x91DB, 0x82D4, 0x91DC, 0x888B, 0x91DD, 0x8CB8, - 0x91DE, 0x9000, 0x91DF, 0x902E, 0x91E0, 0x968A, 0x91E1, 0x9EDB, 0x91E2, 0x9BDB, 0x91E3, 0x4EE3, 0x91E4, 0x53F0, 0x91E5, 0x5927, - 0x91E6, 0x7B2C, 0x91E7, 0x918D, 0x91E8, 0x984C, 0x91E9, 0x9DF9, 0x91EA, 0x6EDD, 0x91EB, 0x7027, 0x91EC, 0x5353, 0x91ED, 0x5544, - 0x91EE, 0x5B85, 0x91EF, 0x6258, 0x91F0, 0x629E, 0x91F1, 0x62D3, 0x91F2, 0x6CA2, 0x91F3, 0x6FEF, 0x91F4, 0x7422, 0x91F5, 0x8A17, - 0x91F6, 0x9438, 0x91F7, 0x6FC1, 0x91F8, 0x8AFE, 0x91F9, 0x8338, 0x91FA, 0x51E7, 0x91FB, 0x86F8, 0x91FC, 0x53EA, 0x9240, 0x53E9, - 0x9241, 0x4F46, 0x9242, 0x9054, 0x9243, 0x8FB0, 0x9244, 0x596A, 0x9245, 0x8131, 0x9246, 0x5DFD, 0x9247, 0x7AEA, 0x9248, 0x8FBF, - 0x9249, 0x68DA, 0x924A, 0x8C37, 0x924B, 0x72F8, 0x924C, 0x9C48, 0x924D, 0x6A3D, 0x924E, 0x8AB0, 0x924F, 0x4E39, 0x9250, 0x5358, - 0x9251, 0x5606, 0x9252, 0x5766, 0x9253, 0x62C5, 0x9254, 0x63A2, 0x9255, 0x65E6, 0x9256, 0x6B4E, 0x9257, 0x6DE1, 0x9258, 0x6E5B, - 0x9259, 0x70AD, 0x925A, 0x77ED, 0x925B, 0x7AEF, 0x925C, 0x7BAA, 0x925D, 0x7DBB, 0x925E, 0x803D, 0x925F, 0x80C6, 0x9260, 0x86CB, - 0x9261, 0x8A95, 0x9262, 0x935B, 0x9263, 0x56E3, 0x9264, 0x58C7, 0x9265, 0x5F3E, 0x9266, 0x65AD, 0x9267, 0x6696, 0x9268, 0x6A80, - 0x9269, 0x6BB5, 0x926A, 0x7537, 0x926B, 0x8AC7, 0x926C, 0x5024, 0x926D, 0x77E5, 0x926E, 0x5730, 0x926F, 0x5F1B, 0x9270, 0x6065, - 0x9271, 0x667A, 0x9272, 0x6C60, 0x9273, 0x75F4, 0x9274, 0x7A1A, 0x9275, 0x7F6E, 0x9276, 0x81F4, 0x9277, 0x8718, 0x9278, 0x9045, - 0x9279, 0x99B3, 0x927A, 0x7BC9, 0x927B, 0x755C, 0x927C, 0x7AF9, 0x927D, 0x7B51, 0x927E, 0x84C4, 0x9280, 0x9010, 0x9281, 0x79E9, - 0x9282, 0x7A92, 0x9283, 0x8336, 0x9284, 0x5AE1, 0x9285, 0x7740, 0x9286, 0x4E2D, 0x9287, 0x4EF2, 0x9288, 0x5B99, 0x9289, 0x5FE0, - 0x928A, 0x62BD, 0x928B, 0x663C, 0x928C, 0x67F1, 0x928D, 0x6CE8, 0x928E, 0x866B, 0x928F, 0x8877, 0x9290, 0x8A3B, 0x9291, 0x914E, - 0x9292, 0x92F3, 0x9293, 0x99D0, 0x9294, 0x6A17, 0x9295, 0x7026, 0x9296, 0x732A, 0x9297, 0x82E7, 0x9298, 0x8457, 0x9299, 0x8CAF, - 0x929A, 0x4E01, 0x929B, 0x5146, 0x929C, 0x51CB, 0x929D, 0x558B, 0x929E, 0x5BF5, 0x929F, 0x5E16, 0x92A0, 0x5E33, 0x92A1, 0x5E81, - 0x92A2, 0x5F14, 0x92A3, 0x5F35, 0x92A4, 0x5F6B, 0x92A5, 0x5FB4, 0x92A6, 0x61F2, 0x92A7, 0x6311, 0x92A8, 0x66A2, 0x92A9, 0x671D, - 0x92AA, 0x6F6E, 0x92AB, 0x7252, 0x92AC, 0x753A, 0x92AD, 0x773A, 0x92AE, 0x8074, 0x92AF, 0x8139, 0x92B0, 0x8178, 0x92B1, 0x8776, - 0x92B2, 0x8ABF, 0x92B3, 0x8ADC, 0x92B4, 0x8D85, 0x92B5, 0x8DF3, 0x92B6, 0x929A, 0x92B7, 0x9577, 0x92B8, 0x9802, 0x92B9, 0x9CE5, - 0x92BA, 0x52C5, 0x92BB, 0x6357, 0x92BC, 0x76F4, 0x92BD, 0x6715, 0x92BE, 0x6C88, 0x92BF, 0x73CD, 0x92C0, 0x8CC3, 0x92C1, 0x93AE, - 0x92C2, 0x9673, 0x92C3, 0x6D25, 0x92C4, 0x589C, 0x92C5, 0x690E, 0x92C6, 0x69CC, 0x92C7, 0x8FFD, 0x92C8, 0x939A, 0x92C9, 0x75DB, - 0x92CA, 0x901A, 0x92CB, 0x585A, 0x92CC, 0x6802, 0x92CD, 0x63B4, 0x92CE, 0x69FB, 0x92CF, 0x4F43, 0x92D0, 0x6F2C, 0x92D1, 0x67D8, - 0x92D2, 0x8FBB, 0x92D3, 0x8526, 0x92D4, 0x7DB4, 0x92D5, 0x9354, 0x92D6, 0x693F, 0x92D7, 0x6F70, 0x92D8, 0x576A, 0x92D9, 0x58F7, - 0x92DA, 0x5B2C, 0x92DB, 0x7D2C, 0x92DC, 0x722A, 0x92DD, 0x540A, 0x92DE, 0x91E3, 0x92DF, 0x9DB4, 0x92E0, 0x4EAD, 0x92E1, 0x4F4E, - 0x92E2, 0x505C, 0x92E3, 0x5075, 0x92E4, 0x5243, 0x92E5, 0x8C9E, 0x92E6, 0x5448, 0x92E7, 0x5824, 0x92E8, 0x5B9A, 0x92E9, 0x5E1D, - 0x92EA, 0x5E95, 0x92EB, 0x5EAD, 0x92EC, 0x5EF7, 0x92ED, 0x5F1F, 0x92EE, 0x608C, 0x92EF, 0x62B5, 0x92F0, 0x633A, 0x92F1, 0x63D0, - 0x92F2, 0x68AF, 0x92F3, 0x6C40, 0x92F4, 0x7887, 0x92F5, 0x798E, 0x92F6, 0x7A0B, 0x92F7, 0x7DE0, 0x92F8, 0x8247, 0x92F9, 0x8A02, - 0x92FA, 0x8AE6, 0x92FB, 0x8E44, 0x92FC, 0x9013, 0x9340, 0x90B8, 0x9341, 0x912D, 0x9342, 0x91D8, 0x9343, 0x9F0E, 0x9344, 0x6CE5, - 0x9345, 0x6458, 0x9346, 0x64E2, 0x9347, 0x6575, 0x9348, 0x6EF4, 0x9349, 0x7684, 0x934A, 0x7B1B, 0x934B, 0x9069, 0x934C, 0x93D1, - 0x934D, 0x6EBA, 0x934E, 0x54F2, 0x934F, 0x5FB9, 0x9350, 0x64A4, 0x9351, 0x8F4D, 0x9352, 0x8FED, 0x9353, 0x9244, 0x9354, 0x5178, - 0x9355, 0x586B, 0x9356, 0x5929, 0x9357, 0x5C55, 0x9358, 0x5E97, 0x9359, 0x6DFB, 0x935A, 0x7E8F, 0x935B, 0x751C, 0x935C, 0x8CBC, - 0x935D, 0x8EE2, 0x935E, 0x985B, 0x935F, 0x70B9, 0x9360, 0x4F1D, 0x9361, 0x6BBF, 0x9362, 0x6FB1, 0x9363, 0x7530, 0x9364, 0x96FB, - 0x9365, 0x514E, 0x9366, 0x5410, 0x9367, 0x5835, 0x9368, 0x5857, 0x9369, 0x59AC, 0x936A, 0x5C60, 0x936B, 0x5F92, 0x936C, 0x6597, - 0x936D, 0x675C, 0x936E, 0x6E21, 0x936F, 0x767B, 0x9370, 0x83DF, 0x9371, 0x8CED, 0x9372, 0x9014, 0x9373, 0x90FD, 0x9374, 0x934D, - 0x9375, 0x7825, 0x9376, 0x783A, 0x9377, 0x52AA, 0x9378, 0x5EA6, 0x9379, 0x571F, 0x937A, 0x5974, 0x937B, 0x6012, 0x937C, 0x5012, - 0x937D, 0x515A, 0x937E, 0x51AC, 0x9380, 0x51CD, 0x9381, 0x5200, 0x9382, 0x5510, 0x9383, 0x5854, 0x9384, 0x5858, 0x9385, 0x5957, - 0x9386, 0x5B95, 0x9387, 0x5CF6, 0x9388, 0x5D8B, 0x9389, 0x60BC, 0x938A, 0x6295, 0x938B, 0x642D, 0x938C, 0x6771, 0x938D, 0x6843, - 0x938E, 0x68BC, 0x938F, 0x68DF, 0x9390, 0x76D7, 0x9391, 0x6DD8, 0x9392, 0x6E6F, 0x9393, 0x6D9B, 0x9394, 0x706F, 0x9395, 0x71C8, - 0x9396, 0x5F53, 0x9397, 0x75D8, 0x9398, 0x7977, 0x9399, 0x7B49, 0x939A, 0x7B54, 0x939B, 0x7B52, 0x939C, 0x7CD6, 0x939D, 0x7D71, - 0x939E, 0x5230, 0x939F, 0x8463, 0x93A0, 0x8569, 0x93A1, 0x85E4, 0x93A2, 0x8A0E, 0x93A3, 0x8B04, 0x93A4, 0x8C46, 0x93A5, 0x8E0F, - 0x93A6, 0x9003, 0x93A7, 0x900F, 0x93A8, 0x9419, 0x93A9, 0x9676, 0x93AA, 0x982D, 0x93AB, 0x9A30, 0x93AC, 0x95D8, 0x93AD, 0x50CD, - 0x93AE, 0x52D5, 0x93AF, 0x540C, 0x93B0, 0x5802, 0x93B1, 0x5C0E, 0x93B2, 0x61A7, 0x93B3, 0x649E, 0x93B4, 0x6D1E, 0x93B5, 0x77B3, - 0x93B6, 0x7AE5, 0x93B7, 0x80F4, 0x93B8, 0x8404, 0x93B9, 0x9053, 0x93BA, 0x9285, 0x93BB, 0x5CE0, 0x93BC, 0x9D07, 0x93BD, 0x533F, - 0x93BE, 0x5F97, 0x93BF, 0x5FB3, 0x93C0, 0x6D9C, 0x93C1, 0x7279, 0x93C2, 0x7763, 0x93C3, 0x79BF, 0x93C4, 0x7BE4, 0x93C5, 0x6BD2, - 0x93C6, 0x72EC, 0x93C7, 0x8AAD, 0x93C8, 0x6803, 0x93C9, 0x6A61, 0x93CA, 0x51F8, 0x93CB, 0x7A81, 0x93CC, 0x6934, 0x93CD, 0x5C4A, - 0x93CE, 0x9CF6, 0x93CF, 0x82EB, 0x93D0, 0x5BC5, 0x93D1, 0x9149, 0x93D2, 0x701E, 0x93D3, 0x5678, 0x93D4, 0x5C6F, 0x93D5, 0x60C7, - 0x93D6, 0x6566, 0x93D7, 0x6C8C, 0x93D8, 0x8C5A, 0x93D9, 0x9041, 0x93DA, 0x9813, 0x93DB, 0x5451, 0x93DC, 0x66C7, 0x93DD, 0x920D, - 0x93DE, 0x5948, 0x93DF, 0x90A3, 0x93E0, 0x5185, 0x93E1, 0x4E4D, 0x93E2, 0x51EA, 0x93E3, 0x8599, 0x93E4, 0x8B0E, 0x93E5, 0x7058, - 0x93E6, 0x637A, 0x93E7, 0x934B, 0x93E8, 0x6962, 0x93E9, 0x99B4, 0x93EA, 0x7E04, 0x93EB, 0x7577, 0x93EC, 0x5357, 0x93ED, 0x6960, - 0x93EE, 0x8EDF, 0x93EF, 0x96E3, 0x93F0, 0x6C5D, 0x93F1, 0x4E8C, 0x93F2, 0x5C3C, 0x93F3, 0x5F10, 0x93F4, 0x8FE9, 0x93F5, 0x5302, - 0x93F6, 0x8CD1, 0x93F7, 0x8089, 0x93F8, 0x8679, 0x93F9, 0x5EFF, 0x93FA, 0x65E5, 0x93FB, 0x4E73, 0x93FC, 0x5165, 0x9440, 0x5982, - 0x9441, 0x5C3F, 0x9442, 0x97EE, 0x9443, 0x4EFB, 0x9444, 0x598A, 0x9445, 0x5FCD, 0x9446, 0x8A8D, 0x9447, 0x6FE1, 0x9448, 0x79B0, - 0x9449, 0x7962, 0x944A, 0x5BE7, 0x944B, 0x8471, 0x944C, 0x732B, 0x944D, 0x71B1, 0x944E, 0x5E74, 0x944F, 0x5FF5, 0x9450, 0x637B, - 0x9451, 0x649A, 0x9452, 0x71C3, 0x9453, 0x7C98, 0x9454, 0x4E43, 0x9455, 0x5EFC, 0x9456, 0x4E4B, 0x9457, 0x57DC, 0x9458, 0x56A2, - 0x9459, 0x60A9, 0x945A, 0x6FC3, 0x945B, 0x7D0D, 0x945C, 0x80FD, 0x945D, 0x8133, 0x945E, 0x81BF, 0x945F, 0x8FB2, 0x9460, 0x8997, - 0x9461, 0x86A4, 0x9462, 0x5DF4, 0x9463, 0x628A, 0x9464, 0x64AD, 0x9465, 0x8987, 0x9466, 0x6777, 0x9467, 0x6CE2, 0x9468, 0x6D3E, - 0x9469, 0x7436, 0x946A, 0x7834, 0x946B, 0x5A46, 0x946C, 0x7F75, 0x946D, 0x82AD, 0x946E, 0x99AC, 0x946F, 0x4FF3, 0x9470, 0x5EC3, - 0x9471, 0x62DD, 0x9472, 0x6392, 0x9473, 0x6557, 0x9474, 0x676F, 0x9475, 0x76C3, 0x9476, 0x724C, 0x9477, 0x80CC, 0x9478, 0x80BA, - 0x9479, 0x8F29, 0x947A, 0x914D, 0x947B, 0x500D, 0x947C, 0x57F9, 0x947D, 0x5A92, 0x947E, 0x6885, 0x9480, 0x6973, 0x9481, 0x7164, - 0x9482, 0x72FD, 0x9483, 0x8CB7, 0x9484, 0x58F2, 0x9485, 0x8CE0, 0x9486, 0x966A, 0x9487, 0x9019, 0x9488, 0x877F, 0x9489, 0x79E4, - 0x948A, 0x77E7, 0x948B, 0x8429, 0x948C, 0x4F2F, 0x948D, 0x5265, 0x948E, 0x535A, 0x948F, 0x62CD, 0x9490, 0x67CF, 0x9491, 0x6CCA, - 0x9492, 0x767D, 0x9493, 0x7B94, 0x9494, 0x7C95, 0x9495, 0x8236, 0x9496, 0x8584, 0x9497, 0x8FEB, 0x9498, 0x66DD, 0x9499, 0x6F20, - 0x949A, 0x7206, 0x949B, 0x7E1B, 0x949C, 0x83AB, 0x949D, 0x99C1, 0x949E, 0x9EA6, 0x949F, 0x51FD, 0x94A0, 0x7BB1, 0x94A1, 0x7872, - 0x94A2, 0x7BB8, 0x94A3, 0x8087, 0x94A4, 0x7B48, 0x94A5, 0x6AE8, 0x94A6, 0x5E61, 0x94A7, 0x808C, 0x94A8, 0x7551, 0x94A9, 0x7560, - 0x94AA, 0x516B, 0x94AB, 0x9262, 0x94AC, 0x6E8C, 0x94AD, 0x767A, 0x94AE, 0x9197, 0x94AF, 0x9AEA, 0x94B0, 0x4F10, 0x94B1, 0x7F70, - 0x94B2, 0x629C, 0x94B3, 0x7B4F, 0x94B4, 0x95A5, 0x94B5, 0x9CE9, 0x94B6, 0x567A, 0x94B7, 0x5859, 0x94B8, 0x86E4, 0x94B9, 0x96BC, - 0x94BA, 0x4F34, 0x94BB, 0x5224, 0x94BC, 0x534A, 0x94BD, 0x53CD, 0x94BE, 0x53DB, 0x94BF, 0x5E06, 0x94C0, 0x642C, 0x94C1, 0x6591, - 0x94C2, 0x677F, 0x94C3, 0x6C3E, 0x94C4, 0x6C4E, 0x94C5, 0x7248, 0x94C6, 0x72AF, 0x94C7, 0x73ED, 0x94C8, 0x7554, 0x94C9, 0x7E41, - 0x94CA, 0x822C, 0x94CB, 0x85E9, 0x94CC, 0x8CA9, 0x94CD, 0x7BC4, 0x94CE, 0x91C6, 0x94CF, 0x7169, 0x94D0, 0x9812, 0x94D1, 0x98EF, - 0x94D2, 0x633D, 0x94D3, 0x6669, 0x94D4, 0x756A, 0x94D5, 0x76E4, 0x94D6, 0x78D0, 0x94D7, 0x8543, 0x94D8, 0x86EE, 0x94D9, 0x532A, - 0x94DA, 0x5351, 0x94DB, 0x5426, 0x94DC, 0x5983, 0x94DD, 0x5E87, 0x94DE, 0x5F7C, 0x94DF, 0x60B2, 0x94E0, 0x6249, 0x94E1, 0x6279, - 0x94E2, 0x62AB, 0x94E3, 0x6590, 0x94E4, 0x6BD4, 0x94E5, 0x6CCC, 0x94E6, 0x75B2, 0x94E7, 0x76AE, 0x94E8, 0x7891, 0x94E9, 0x79D8, - 0x94EA, 0x7DCB, 0x94EB, 0x7F77, 0x94EC, 0x80A5, 0x94ED, 0x88AB, 0x94EE, 0x8AB9, 0x94EF, 0x8CBB, 0x94F0, 0x907F, 0x94F1, 0x975E, - 0x94F2, 0x98DB, 0x94F3, 0x6A0B, 0x94F4, 0x7C38, 0x94F5, 0x5099, 0x94F6, 0x5C3E, 0x94F7, 0x5FAE, 0x94F8, 0x6787, 0x94F9, 0x6BD8, - 0x94FA, 0x7435, 0x94FB, 0x7709, 0x94FC, 0x7F8E, 0x9540, 0x9F3B, 0x9541, 0x67CA, 0x9542, 0x7A17, 0x9543, 0x5339, 0x9544, 0x758B, - 0x9545, 0x9AED, 0x9546, 0x5F66, 0x9547, 0x819D, 0x9548, 0x83F1, 0x9549, 0x8098, 0x954A, 0x5F3C, 0x954B, 0x5FC5, 0x954C, 0x7562, - 0x954D, 0x7B46, 0x954E, 0x903C, 0x954F, 0x6867, 0x9550, 0x59EB, 0x9551, 0x5A9B, 0x9552, 0x7D10, 0x9553, 0x767E, 0x9554, 0x8B2C, - 0x9555, 0x4FF5, 0x9556, 0x5F6A, 0x9557, 0x6A19, 0x9558, 0x6C37, 0x9559, 0x6F02, 0x955A, 0x74E2, 0x955B, 0x7968, 0x955C, 0x8868, - 0x955D, 0x8A55, 0x955E, 0x8C79, 0x955F, 0x5EDF, 0x9560, 0x63CF, 0x9561, 0x75C5, 0x9562, 0x79D2, 0x9563, 0x82D7, 0x9564, 0x9328, - 0x9565, 0x92F2, 0x9566, 0x849C, 0x9567, 0x86ED, 0x9568, 0x9C2D, 0x9569, 0x54C1, 0x956A, 0x5F6C, 0x956B, 0x658C, 0x956C, 0x6D5C, - 0x956D, 0x7015, 0x956E, 0x8CA7, 0x956F, 0x8CD3, 0x9570, 0x983B, 0x9571, 0x654F, 0x9572, 0x74F6, 0x9573, 0x4E0D, 0x9574, 0x4ED8, - 0x9575, 0x57E0, 0x9576, 0x592B, 0x9577, 0x5A66, 0x9578, 0x5BCC, 0x9579, 0x51A8, 0x957A, 0x5E03, 0x957B, 0x5E9C, 0x957C, 0x6016, - 0x957D, 0x6276, 0x957E, 0x6577, 0x9580, 0x65A7, 0x9581, 0x666E, 0x9582, 0x6D6E, 0x9583, 0x7236, 0x9584, 0x7B26, 0x9585, 0x8150, - 0x9586, 0x819A, 0x9587, 0x8299, 0x9588, 0x8B5C, 0x9589, 0x8CA0, 0x958A, 0x8CE6, 0x958B, 0x8D74, 0x958C, 0x961C, 0x958D, 0x9644, - 0x958E, 0x4FAE, 0x958F, 0x64AB, 0x9590, 0x6B66, 0x9591, 0x821E, 0x9592, 0x8461, 0x9593, 0x856A, 0x9594, 0x90E8, 0x9595, 0x5C01, - 0x9596, 0x6953, 0x9597, 0x98A8, 0x9598, 0x847A, 0x9599, 0x8557, 0x959A, 0x4F0F, 0x959B, 0x526F, 0x959C, 0x5FA9, 0x959D, 0x5E45, - 0x959E, 0x670D, 0x959F, 0x798F, 0x95A0, 0x8179, 0x95A1, 0x8907, 0x95A2, 0x8986, 0x95A3, 0x6DF5, 0x95A4, 0x5F17, 0x95A5, 0x6255, - 0x95A6, 0x6CB8, 0x95A7, 0x4ECF, 0x95A8, 0x7269, 0x95A9, 0x9B92, 0x95AA, 0x5206, 0x95AB, 0x543B, 0x95AC, 0x5674, 0x95AD, 0x58B3, - 0x95AE, 0x61A4, 0x95AF, 0x626E, 0x95B0, 0x711A, 0x95B1, 0x596E, 0x95B2, 0x7C89, 0x95B3, 0x7CDE, 0x95B4, 0x7D1B, 0x95B5, 0x96F0, - 0x95B6, 0x6587, 0x95B7, 0x805E, 0x95B8, 0x4E19, 0x95B9, 0x4F75, 0x95BA, 0x5175, 0x95BB, 0x5840, 0x95BC, 0x5E63, 0x95BD, 0x5E73, - 0x95BE, 0x5F0A, 0x95BF, 0x67C4, 0x95C0, 0x4E26, 0x95C1, 0x853D, 0x95C2, 0x9589, 0x95C3, 0x965B, 0x95C4, 0x7C73, 0x95C5, 0x9801, - 0x95C6, 0x50FB, 0x95C7, 0x58C1, 0x95C8, 0x7656, 0x95C9, 0x78A7, 0x95CA, 0x5225, 0x95CB, 0x77A5, 0x95CC, 0x8511, 0x95CD, 0x7B86, - 0x95CE, 0x504F, 0x95CF, 0x5909, 0x95D0, 0x7247, 0x95D1, 0x7BC7, 0x95D2, 0x7DE8, 0x95D3, 0x8FBA, 0x95D4, 0x8FD4, 0x95D5, 0x904D, - 0x95D6, 0x4FBF, 0x95D7, 0x52C9, 0x95D8, 0x5A29, 0x95D9, 0x5F01, 0x95DA, 0x97AD, 0x95DB, 0x4FDD, 0x95DC, 0x8217, 0x95DD, 0x92EA, - 0x95DE, 0x5703, 0x95DF, 0x6355, 0x95E0, 0x6B69, 0x95E1, 0x752B, 0x95E2, 0x88DC, 0x95E3, 0x8F14, 0x95E4, 0x7A42, 0x95E5, 0x52DF, - 0x95E6, 0x5893, 0x95E7, 0x6155, 0x95E8, 0x620A, 0x95E9, 0x66AE, 0x95EA, 0x6BCD, 0x95EB, 0x7C3F, 0x95EC, 0x83E9, 0x95ED, 0x5023, - 0x95EE, 0x4FF8, 0x95EF, 0x5305, 0x95F0, 0x5446, 0x95F1, 0x5831, 0x95F2, 0x5949, 0x95F3, 0x5B9D, 0x95F4, 0x5CF0, 0x95F5, 0x5CEF, - 0x95F6, 0x5D29, 0x95F7, 0x5E96, 0x95F8, 0x62B1, 0x95F9, 0x6367, 0x95FA, 0x653E, 0x95FB, 0x65B9, 0x95FC, 0x670B, 0x9640, 0x6CD5, - 0x9641, 0x6CE1, 0x9642, 0x70F9, 0x9643, 0x7832, 0x9644, 0x7E2B, 0x9645, 0x80DE, 0x9646, 0x82B3, 0x9647, 0x840C, 0x9648, 0x84EC, - 0x9649, 0x8702, 0x964A, 0x8912, 0x964B, 0x8A2A, 0x964C, 0x8C4A, 0x964D, 0x90A6, 0x964E, 0x92D2, 0x964F, 0x98FD, 0x9650, 0x9CF3, - 0x9651, 0x9D6C, 0x9652, 0x4E4F, 0x9653, 0x4EA1, 0x9654, 0x508D, 0x9655, 0x5256, 0x9656, 0x574A, 0x9657, 0x59A8, 0x9658, 0x5E3D, - 0x9659, 0x5FD8, 0x965A, 0x5FD9, 0x965B, 0x623F, 0x965C, 0x66B4, 0x965D, 0x671B, 0x965E, 0x67D0, 0x965F, 0x68D2, 0x9660, 0x5192, - 0x9661, 0x7D21, 0x9662, 0x80AA, 0x9663, 0x81A8, 0x9664, 0x8B00, 0x9665, 0x8C8C, 0x9666, 0x8CBF, 0x9667, 0x927E, 0x9668, 0x9632, - 0x9669, 0x5420, 0x966A, 0x982C, 0x966B, 0x5317, 0x966C, 0x50D5, 0x966D, 0x535C, 0x966E, 0x58A8, 0x966F, 0x64B2, 0x9670, 0x6734, - 0x9671, 0x7267, 0x9672, 0x7766, 0x9673, 0x7A46, 0x9674, 0x91E6, 0x9675, 0x52C3, 0x9676, 0x6CA1, 0x9677, 0x6B86, 0x9678, 0x5800, - 0x9679, 0x5E4C, 0x967A, 0x5954, 0x967B, 0x672C, 0x967C, 0x7FFB, 0x967D, 0x51E1, 0x967E, 0x76C6, 0x9680, 0x6469, 0x9681, 0x78E8, - 0x9682, 0x9B54, 0x9683, 0x9EBB, 0x9684, 0x57CB, 0x9685, 0x59B9, 0x9686, 0x6627, 0x9687, 0x679A, 0x9688, 0x6BCE, 0x9689, 0x54E9, - 0x968A, 0x69D9, 0x968B, 0x5E55, 0x968C, 0x819C, 0x968D, 0x6795, 0x968E, 0x9BAA, 0x968F, 0x67FE, 0x9690, 0x9C52, 0x9691, 0x685D, - 0x9692, 0x4EA6, 0x9693, 0x4FE3, 0x9694, 0x53C8, 0x9695, 0x62B9, 0x9696, 0x672B, 0x9697, 0x6CAB, 0x9698, 0x8FC4, 0x9699, 0x4FAD, - 0x969A, 0x7E6D, 0x969B, 0x9EBF, 0x969C, 0x4E07, 0x969D, 0x6162, 0x969E, 0x6E80, 0x969F, 0x6F2B, 0x96A0, 0x8513, 0x96A1, 0x5473, - 0x96A2, 0x672A, 0x96A3, 0x9B45, 0x96A4, 0x5DF3, 0x96A5, 0x7B95, 0x96A6, 0x5CAC, 0x96A7, 0x5BC6, 0x96A8, 0x871C, 0x96A9, 0x6E4A, - 0x96AA, 0x84D1, 0x96AB, 0x7A14, 0x96AC, 0x8108, 0x96AD, 0x5999, 0x96AE, 0x7C8D, 0x96AF, 0x6C11, 0x96B0, 0x7720, 0x96B1, 0x52D9, - 0x96B2, 0x5922, 0x96B3, 0x7121, 0x96B4, 0x725F, 0x96B5, 0x77DB, 0x96B6, 0x9727, 0x96B7, 0x9D61, 0x96B8, 0x690B, 0x96B9, 0x5A7F, - 0x96BA, 0x5A18, 0x96BB, 0x51A5, 0x96BC, 0x540D, 0x96BD, 0x547D, 0x96BE, 0x660E, 0x96BF, 0x76DF, 0x96C0, 0x8FF7, 0x96C1, 0x9298, - 0x96C2, 0x9CF4, 0x96C3, 0x59EA, 0x96C4, 0x725D, 0x96C5, 0x6EC5, 0x96C6, 0x514D, 0x96C7, 0x68C9, 0x96C8, 0x7DBF, 0x96C9, 0x7DEC, - 0x96CA, 0x9762, 0x96CB, 0x9EBA, 0x96CC, 0x6478, 0x96CD, 0x6A21, 0x96CE, 0x8302, 0x96CF, 0x5984, 0x96D0, 0x5B5F, 0x96D1, 0x6BDB, - 0x96D2, 0x731B, 0x96D3, 0x76F2, 0x96D4, 0x7DB2, 0x96D5, 0x8017, 0x96D6, 0x8499, 0x96D7, 0x5132, 0x96D8, 0x6728, 0x96D9, 0x9ED9, - 0x96DA, 0x76EE, 0x96DB, 0x6762, 0x96DC, 0x52FF, 0x96DD, 0x9905, 0x96DE, 0x5C24, 0x96DF, 0x623B, 0x96E0, 0x7C7E, 0x96E1, 0x8CB0, - 0x96E2, 0x554F, 0x96E3, 0x60B6, 0x96E4, 0x7D0B, 0x96E5, 0x9580, 0x96E6, 0x5301, 0x96E7, 0x4E5F, 0x96E8, 0x51B6, 0x96E9, 0x591C, - 0x96EA, 0x723A, 0x96EB, 0x8036, 0x96EC, 0x91CE, 0x96ED, 0x5F25, 0x96EE, 0x77E2, 0x96EF, 0x5384, 0x96F0, 0x5F79, 0x96F1, 0x7D04, - 0x96F2, 0x85AC, 0x96F3, 0x8A33, 0x96F4, 0x8E8D, 0x96F5, 0x9756, 0x96F6, 0x67F3, 0x96F7, 0x85AE, 0x96F8, 0x9453, 0x96F9, 0x6109, - 0x96FA, 0x6108, 0x96FB, 0x6CB9, 0x96FC, 0x7652, 0x9740, 0x8AED, 0x9741, 0x8F38, 0x9742, 0x552F, 0x9743, 0x4F51, 0x9744, 0x512A, - 0x9745, 0x52C7, 0x9746, 0x53CB, 0x9747, 0x5BA5, 0x9748, 0x5E7D, 0x9749, 0x60A0, 0x974A, 0x6182, 0x974B, 0x63D6, 0x974C, 0x6709, - 0x974D, 0x67DA, 0x974E, 0x6E67, 0x974F, 0x6D8C, 0x9750, 0x7336, 0x9751, 0x7337, 0x9752, 0x7531, 0x9753, 0x7950, 0x9754, 0x88D5, - 0x9755, 0x8A98, 0x9756, 0x904A, 0x9757, 0x9091, 0x9758, 0x90F5, 0x9759, 0x96C4, 0x975A, 0x878D, 0x975B, 0x5915, 0x975C, 0x4E88, - 0x975D, 0x4F59, 0x975E, 0x4E0E, 0x975F, 0x8A89, 0x9760, 0x8F3F, 0x9761, 0x9810, 0x9762, 0x50AD, 0x9763, 0x5E7C, 0x9764, 0x5996, - 0x9765, 0x5BB9, 0x9766, 0x5EB8, 0x9767, 0x63DA, 0x9768, 0x63FA, 0x9769, 0x64C1, 0x976A, 0x66DC, 0x976B, 0x694A, 0x976C, 0x69D8, - 0x976D, 0x6D0B, 0x976E, 0x6EB6, 0x976F, 0x7194, 0x9770, 0x7528, 0x9771, 0x7AAF, 0x9772, 0x7F8A, 0x9773, 0x8000, 0x9774, 0x8449, - 0x9775, 0x84C9, 0x9776, 0x8981, 0x9777, 0x8B21, 0x9778, 0x8E0A, 0x9779, 0x9065, 0x977A, 0x967D, 0x977B, 0x990A, 0x977C, 0x617E, - 0x977D, 0x6291, 0x977E, 0x6B32, 0x9780, 0x6C83, 0x9781, 0x6D74, 0x9782, 0x7FCC, 0x9783, 0x7FFC, 0x9784, 0x6DC0, 0x9785, 0x7F85, - 0x9786, 0x87BA, 0x9787, 0x88F8, 0x9788, 0x6765, 0x9789, 0x83B1, 0x978A, 0x983C, 0x978B, 0x96F7, 0x978C, 0x6D1B, 0x978D, 0x7D61, - 0x978E, 0x843D, 0x978F, 0x916A, 0x9790, 0x4E71, 0x9791, 0x5375, 0x9792, 0x5D50, 0x9793, 0x6B04, 0x9794, 0x6FEB, 0x9795, 0x85CD, - 0x9796, 0x862D, 0x9797, 0x89A7, 0x9798, 0x5229, 0x9799, 0x540F, 0x979A, 0x5C65, 0x979B, 0x674E, 0x979C, 0x68A8, 0x979D, 0x7406, - 0x979E, 0x7483, 0x979F, 0x75E2, 0x97A0, 0x88CF, 0x97A1, 0x88E1, 0x97A2, 0x91CC, 0x97A3, 0x96E2, 0x97A4, 0x9678, 0x97A5, 0x5F8B, - 0x97A6, 0x7387, 0x97A7, 0x7ACB, 0x97A8, 0x844E, 0x97A9, 0x63A0, 0x97AA, 0x7565, 0x97AB, 0x5289, 0x97AC, 0x6D41, 0x97AD, 0x6E9C, - 0x97AE, 0x7409, 0x97AF, 0x7559, 0x97B0, 0x786B, 0x97B1, 0x7C92, 0x97B2, 0x9686, 0x97B3, 0x7ADC, 0x97B4, 0x9F8D, 0x97B5, 0x4FB6, - 0x97B6, 0x616E, 0x97B7, 0x65C5, 0x97B8, 0x865C, 0x97B9, 0x4E86, 0x97BA, 0x4EAE, 0x97BB, 0x50DA, 0x97BC, 0x4E21, 0x97BD, 0x51CC, - 0x97BE, 0x5BEE, 0x97BF, 0x6599, 0x97C0, 0x6881, 0x97C1, 0x6DBC, 0x97C2, 0x731F, 0x97C3, 0x7642, 0x97C4, 0x77AD, 0x97C5, 0x7A1C, - 0x97C6, 0x7CE7, 0x97C7, 0x826F, 0x97C8, 0x8AD2, 0x97C9, 0x907C, 0x97CA, 0x91CF, 0x97CB, 0x9675, 0x97CC, 0x9818, 0x97CD, 0x529B, - 0x97CE, 0x7DD1, 0x97CF, 0x502B, 0x97D0, 0x5398, 0x97D1, 0x6797, 0x97D2, 0x6DCB, 0x97D3, 0x71D0, 0x97D4, 0x7433, 0x97D5, 0x81E8, - 0x97D6, 0x8F2A, 0x97D7, 0x96A3, 0x97D8, 0x9C57, 0x97D9, 0x9E9F, 0x97DA, 0x7460, 0x97DB, 0x5841, 0x97DC, 0x6D99, 0x97DD, 0x7D2F, - 0x97DE, 0x985E, 0x97DF, 0x4EE4, 0x97E0, 0x4F36, 0x97E1, 0x4F8B, 0x97E2, 0x51B7, 0x97E3, 0x52B1, 0x97E4, 0x5DBA, 0x97E5, 0x601C, - 0x97E6, 0x73B2, 0x97E7, 0x793C, 0x97E8, 0x82D3, 0x97E9, 0x9234, 0x97EA, 0x96B7, 0x97EB, 0x96F6, 0x97EC, 0x970A, 0x97ED, 0x9E97, - 0x97EE, 0x9F62, 0x97EF, 0x66A6, 0x97F0, 0x6B74, 0x97F1, 0x5217, 0x97F2, 0x52A3, 0x97F3, 0x70C8, 0x97F4, 0x88C2, 0x97F5, 0x5EC9, - 0x97F6, 0x604B, 0x97F7, 0x6190, 0x97F8, 0x6F23, 0x97F9, 0x7149, 0x97FA, 0x7C3E, 0x97FB, 0x7DF4, 0x97FC, 0x806F, 0x9840, 0x84EE, - 0x9841, 0x9023, 0x9842, 0x932C, 0x9843, 0x5442, 0x9844, 0x9B6F, 0x9845, 0x6AD3, 0x9846, 0x7089, 0x9847, 0x8CC2, 0x9848, 0x8DEF, - 0x9849, 0x9732, 0x984A, 0x52B4, 0x984B, 0x5A41, 0x984C, 0x5ECA, 0x984D, 0x5F04, 0x984E, 0x6717, 0x984F, 0x697C, 0x9850, 0x6994, - 0x9851, 0x6D6A, 0x9852, 0x6F0F, 0x9853, 0x7262, 0x9854, 0x72FC, 0x9855, 0x7BED, 0x9856, 0x8001, 0x9857, 0x807E, 0x9858, 0x874B, - 0x9859, 0x90CE, 0x985A, 0x516D, 0x985B, 0x9E93, 0x985C, 0x7984, 0x985D, 0x808B, 0x985E, 0x9332, 0x985F, 0x8AD6, 0x9860, 0x502D, - 0x9861, 0x548C, 0x9862, 0x8A71, 0x9863, 0x6B6A, 0x9864, 0x8CC4, 0x9865, 0x8107, 0x9866, 0x60D1, 0x9867, 0x67A0, 0x9868, 0x9DF2, - 0x9869, 0x4E99, 0x986A, 0x4E98, 0x986B, 0x9C10, 0x986C, 0x8A6B, 0x986D, 0x85C1, 0x986E, 0x8568, 0x986F, 0x6900, 0x9870, 0x6E7E, - 0x9871, 0x7897, 0x9872, 0x8155, 0x989F, 0x5F0C, 0x98A0, 0x4E10, 0x98A1, 0x4E15, 0x98A2, 0x4E2A, 0x98A3, 0x4E31, 0x98A4, 0x4E36, - 0x98A5, 0x4E3C, 0x98A6, 0x4E3F, 0x98A7, 0x4E42, 0x98A8, 0x4E56, 0x98A9, 0x4E58, 0x98AA, 0x4E82, 0x98AB, 0x4E85, 0x98AC, 0x8C6B, - 0x98AD, 0x4E8A, 0x98AE, 0x8212, 0x98AF, 0x5F0D, 0x98B0, 0x4E8E, 0x98B1, 0x4E9E, 0x98B2, 0x4E9F, 0x98B3, 0x4EA0, 0x98B4, 0x4EA2, - 0x98B5, 0x4EB0, 0x98B6, 0x4EB3, 0x98B7, 0x4EB6, 0x98B8, 0x4ECE, 0x98B9, 0x4ECD, 0x98BA, 0x4EC4, 0x98BB, 0x4EC6, 0x98BC, 0x4EC2, - 0x98BD, 0x4ED7, 0x98BE, 0x4EDE, 0x98BF, 0x4EED, 0x98C0, 0x4EDF, 0x98C1, 0x4EF7, 0x98C2, 0x4F09, 0x98C3, 0x4F5A, 0x98C4, 0x4F30, - 0x98C5, 0x4F5B, 0x98C6, 0x4F5D, 0x98C7, 0x4F57, 0x98C8, 0x4F47, 0x98C9, 0x4F76, 0x98CA, 0x4F88, 0x98CB, 0x4F8F, 0x98CC, 0x4F98, - 0x98CD, 0x4F7B, 0x98CE, 0x4F69, 0x98CF, 0x4F70, 0x98D0, 0x4F91, 0x98D1, 0x4F6F, 0x98D2, 0x4F86, 0x98D3, 0x4F96, 0x98D4, 0x5118, - 0x98D5, 0x4FD4, 0x98D6, 0x4FDF, 0x98D7, 0x4FCE, 0x98D8, 0x4FD8, 0x98D9, 0x4FDB, 0x98DA, 0x4FD1, 0x98DB, 0x4FDA, 0x98DC, 0x4FD0, - 0x98DD, 0x4FE4, 0x98DE, 0x4FE5, 0x98DF, 0x501A, 0x98E0, 0x5028, 0x98E1, 0x5014, 0x98E2, 0x502A, 0x98E3, 0x5025, 0x98E4, 0x5005, - 0x98E5, 0x4F1C, 0x98E6, 0x4FF6, 0x98E7, 0x5021, 0x98E8, 0x5029, 0x98E9, 0x502C, 0x98EA, 0x4FFE, 0x98EB, 0x4FEF, 0x98EC, 0x5011, - 0x98ED, 0x5006, 0x98EE, 0x5043, 0x98EF, 0x5047, 0x98F0, 0x6703, 0x98F1, 0x5055, 0x98F2, 0x5050, 0x98F3, 0x5048, 0x98F4, 0x505A, - 0x98F5, 0x5056, 0x98F6, 0x506C, 0x98F7, 0x5078, 0x98F8, 0x5080, 0x98F9, 0x509A, 0x98FA, 0x5085, 0x98FB, 0x50B4, 0x98FC, 0x50B2, - 0x9940, 0x50C9, 0x9941, 0x50CA, 0x9942, 0x50B3, 0x9943, 0x50C2, 0x9944, 0x50D6, 0x9945, 0x50DE, 0x9946, 0x50E5, 0x9947, 0x50ED, - 0x9948, 0x50E3, 0x9949, 0x50EE, 0x994A, 0x50F9, 0x994B, 0x50F5, 0x994C, 0x5109, 0x994D, 0x5101, 0x994E, 0x5102, 0x994F, 0x5116, - 0x9950, 0x5115, 0x9951, 0x5114, 0x9952, 0x511A, 0x9953, 0x5121, 0x9954, 0x513A, 0x9955, 0x5137, 0x9956, 0x513C, 0x9957, 0x513B, - 0x9958, 0x513F, 0x9959, 0x5140, 0x995A, 0x5152, 0x995B, 0x514C, 0x995C, 0x5154, 0x995D, 0x5162, 0x995E, 0x7AF8, 0x995F, 0x5169, - 0x9960, 0x516A, 0x9961, 0x516E, 0x9962, 0x5180, 0x9963, 0x5182, 0x9964, 0x56D8, 0x9965, 0x518C, 0x9966, 0x5189, 0x9967, 0x518F, - 0x9968, 0x5191, 0x9969, 0x5193, 0x996A, 0x5195, 0x996B, 0x5196, 0x996C, 0x51A4, 0x996D, 0x51A6, 0x996E, 0x51A2, 0x996F, 0x51A9, - 0x9970, 0x51AA, 0x9971, 0x51AB, 0x9972, 0x51B3, 0x9973, 0x51B1, 0x9974, 0x51B2, 0x9975, 0x51B0, 0x9976, 0x51B5, 0x9977, 0x51BD, - 0x9978, 0x51C5, 0x9979, 0x51C9, 0x997A, 0x51DB, 0x997B, 0x51E0, 0x997C, 0x8655, 0x997D, 0x51E9, 0x997E, 0x51ED, 0x9980, 0x51F0, - 0x9981, 0x51F5, 0x9982, 0x51FE, 0x9983, 0x5204, 0x9984, 0x520B, 0x9985, 0x5214, 0x9986, 0x520E, 0x9987, 0x5227, 0x9988, 0x522A, - 0x9989, 0x522E, 0x998A, 0x5233, 0x998B, 0x5239, 0x998C, 0x524F, 0x998D, 0x5244, 0x998E, 0x524B, 0x998F, 0x524C, 0x9990, 0x525E, - 0x9991, 0x5254, 0x9992, 0x526A, 0x9993, 0x5274, 0x9994, 0x5269, 0x9995, 0x5273, 0x9996, 0x527F, 0x9997, 0x527D, 0x9998, 0x528D, - 0x9999, 0x5294, 0x999A, 0x5292, 0x999B, 0x5271, 0x999C, 0x5288, 0x999D, 0x5291, 0x999E, 0x8FA8, 0x999F, 0x8FA7, 0x99A0, 0x52AC, - 0x99A1, 0x52AD, 0x99A2, 0x52BC, 0x99A3, 0x52B5, 0x99A4, 0x52C1, 0x99A5, 0x52CD, 0x99A6, 0x52D7, 0x99A7, 0x52DE, 0x99A8, 0x52E3, - 0x99A9, 0x52E6, 0x99AA, 0x98ED, 0x99AB, 0x52E0, 0x99AC, 0x52F3, 0x99AD, 0x52F5, 0x99AE, 0x52F8, 0x99AF, 0x52F9, 0x99B0, 0x5306, - 0x99B1, 0x5308, 0x99B2, 0x7538, 0x99B3, 0x530D, 0x99B4, 0x5310, 0x99B5, 0x530F, 0x99B6, 0x5315, 0x99B7, 0x531A, 0x99B8, 0x5323, - 0x99B9, 0x532F, 0x99BA, 0x5331, 0x99BB, 0x5333, 0x99BC, 0x5338, 0x99BD, 0x5340, 0x99BE, 0x5346, 0x99BF, 0x5345, 0x99C0, 0x4E17, - 0x99C1, 0x5349, 0x99C2, 0x534D, 0x99C3, 0x51D6, 0x99C4, 0x535E, 0x99C5, 0x5369, 0x99C6, 0x536E, 0x99C7, 0x5918, 0x99C8, 0x537B, - 0x99C9, 0x5377, 0x99CA, 0x5382, 0x99CB, 0x5396, 0x99CC, 0x53A0, 0x99CD, 0x53A6, 0x99CE, 0x53A5, 0x99CF, 0x53AE, 0x99D0, 0x53B0, - 0x99D1, 0x53B6, 0x99D2, 0x53C3, 0x99D3, 0x7C12, 0x99D4, 0x96D9, 0x99D5, 0x53DF, 0x99D6, 0x66FC, 0x99D7, 0x71EE, 0x99D8, 0x53EE, - 0x99D9, 0x53E8, 0x99DA, 0x53ED, 0x99DB, 0x53FA, 0x99DC, 0x5401, 0x99DD, 0x543D, 0x99DE, 0x5440, 0x99DF, 0x542C, 0x99E0, 0x542D, - 0x99E1, 0x543C, 0x99E2, 0x542E, 0x99E3, 0x5436, 0x99E4, 0x5429, 0x99E5, 0x541D, 0x99E6, 0x544E, 0x99E7, 0x548F, 0x99E8, 0x5475, - 0x99E9, 0x548E, 0x99EA, 0x545F, 0x99EB, 0x5471, 0x99EC, 0x5477, 0x99ED, 0x5470, 0x99EE, 0x5492, 0x99EF, 0x547B, 0x99F0, 0x5480, - 0x99F1, 0x5476, 0x99F2, 0x5484, 0x99F3, 0x5490, 0x99F4, 0x5486, 0x99F5, 0x54C7, 0x99F6, 0x54A2, 0x99F7, 0x54B8, 0x99F8, 0x54A5, - 0x99F9, 0x54AC, 0x99FA, 0x54C4, 0x99FB, 0x54C8, 0x99FC, 0x54A8, 0x9A40, 0x54AB, 0x9A41, 0x54C2, 0x9A42, 0x54A4, 0x9A43, 0x54BE, - 0x9A44, 0x54BC, 0x9A45, 0x54D8, 0x9A46, 0x54E5, 0x9A47, 0x54E6, 0x9A48, 0x550F, 0x9A49, 0x5514, 0x9A4A, 0x54FD, 0x9A4B, 0x54EE, - 0x9A4C, 0x54ED, 0x9A4D, 0x54FA, 0x9A4E, 0x54E2, 0x9A4F, 0x5539, 0x9A50, 0x5540, 0x9A51, 0x5563, 0x9A52, 0x554C, 0x9A53, 0x552E, - 0x9A54, 0x555C, 0x9A55, 0x5545, 0x9A56, 0x5556, 0x9A57, 0x5557, 0x9A58, 0x5538, 0x9A59, 0x5533, 0x9A5A, 0x555D, 0x9A5B, 0x5599, - 0x9A5C, 0x5580, 0x9A5D, 0x54AF, 0x9A5E, 0x558A, 0x9A5F, 0x559F, 0x9A60, 0x557B, 0x9A61, 0x557E, 0x9A62, 0x5598, 0x9A63, 0x559E, - 0x9A64, 0x55AE, 0x9A65, 0x557C, 0x9A66, 0x5583, 0x9A67, 0x55A9, 0x9A68, 0x5587, 0x9A69, 0x55A8, 0x9A6A, 0x55DA, 0x9A6B, 0x55C5, - 0x9A6C, 0x55DF, 0x9A6D, 0x55C4, 0x9A6E, 0x55DC, 0x9A6F, 0x55E4, 0x9A70, 0x55D4, 0x9A71, 0x5614, 0x9A72, 0x55F7, 0x9A73, 0x5616, - 0x9A74, 0x55FE, 0x9A75, 0x55FD, 0x9A76, 0x561B, 0x9A77, 0x55F9, 0x9A78, 0x564E, 0x9A79, 0x5650, 0x9A7A, 0x71DF, 0x9A7B, 0x5634, - 0x9A7C, 0x5636, 0x9A7D, 0x5632, 0x9A7E, 0x5638, 0x9A80, 0x566B, 0x9A81, 0x5664, 0x9A82, 0x562F, 0x9A83, 0x566C, 0x9A84, 0x566A, - 0x9A85, 0x5686, 0x9A86, 0x5680, 0x9A87, 0x568A, 0x9A88, 0x56A0, 0x9A89, 0x5694, 0x9A8A, 0x568F, 0x9A8B, 0x56A5, 0x9A8C, 0x56AE, - 0x9A8D, 0x56B6, 0x9A8E, 0x56B4, 0x9A8F, 0x56C2, 0x9A90, 0x56BC, 0x9A91, 0x56C1, 0x9A92, 0x56C3, 0x9A93, 0x56C0, 0x9A94, 0x56C8, - 0x9A95, 0x56CE, 0x9A96, 0x56D1, 0x9A97, 0x56D3, 0x9A98, 0x56D7, 0x9A99, 0x56EE, 0x9A9A, 0x56F9, 0x9A9B, 0x5700, 0x9A9C, 0x56FF, - 0x9A9D, 0x5704, 0x9A9E, 0x5709, 0x9A9F, 0x5708, 0x9AA0, 0x570B, 0x9AA1, 0x570D, 0x9AA2, 0x5713, 0x9AA3, 0x5718, 0x9AA4, 0x5716, - 0x9AA5, 0x55C7, 0x9AA6, 0x571C, 0x9AA7, 0x5726, 0x9AA8, 0x5737, 0x9AA9, 0x5738, 0x9AAA, 0x574E, 0x9AAB, 0x573B, 0x9AAC, 0x5740, - 0x9AAD, 0x574F, 0x9AAE, 0x5769, 0x9AAF, 0x57C0, 0x9AB0, 0x5788, 0x9AB1, 0x5761, 0x9AB2, 0x577F, 0x9AB3, 0x5789, 0x9AB4, 0x5793, - 0x9AB5, 0x57A0, 0x9AB6, 0x57B3, 0x9AB7, 0x57A4, 0x9AB8, 0x57AA, 0x9AB9, 0x57B0, 0x9ABA, 0x57C3, 0x9ABB, 0x57C6, 0x9ABC, 0x57D4, - 0x9ABD, 0x57D2, 0x9ABE, 0x57D3, 0x9ABF, 0x580A, 0x9AC0, 0x57D6, 0x9AC1, 0x57E3, 0x9AC2, 0x580B, 0x9AC3, 0x5819, 0x9AC4, 0x581D, - 0x9AC5, 0x5872, 0x9AC6, 0x5821, 0x9AC7, 0x5862, 0x9AC8, 0x584B, 0x9AC9, 0x5870, 0x9ACA, 0x6BC0, 0x9ACB, 0x5852, 0x9ACC, 0x583D, - 0x9ACD, 0x5879, 0x9ACE, 0x5885, 0x9ACF, 0x58B9, 0x9AD0, 0x589F, 0x9AD1, 0x58AB, 0x9AD2, 0x58BA, 0x9AD3, 0x58DE, 0x9AD4, 0x58BB, - 0x9AD5, 0x58B8, 0x9AD6, 0x58AE, 0x9AD7, 0x58C5, 0x9AD8, 0x58D3, 0x9AD9, 0x58D1, 0x9ADA, 0x58D7, 0x9ADB, 0x58D9, 0x9ADC, 0x58D8, - 0x9ADD, 0x58E5, 0x9ADE, 0x58DC, 0x9ADF, 0x58E4, 0x9AE0, 0x58DF, 0x9AE1, 0x58EF, 0x9AE2, 0x58FA, 0x9AE3, 0x58F9, 0x9AE4, 0x58FB, - 0x9AE5, 0x58FC, 0x9AE6, 0x58FD, 0x9AE7, 0x5902, 0x9AE8, 0x590A, 0x9AE9, 0x5910, 0x9AEA, 0x591B, 0x9AEB, 0x68A6, 0x9AEC, 0x5925, - 0x9AED, 0x592C, 0x9AEE, 0x592D, 0x9AEF, 0x5932, 0x9AF0, 0x5938, 0x9AF1, 0x593E, 0x9AF2, 0x7AD2, 0x9AF3, 0x5955, 0x9AF4, 0x5950, - 0x9AF5, 0x594E, 0x9AF6, 0x595A, 0x9AF7, 0x5958, 0x9AF8, 0x5962, 0x9AF9, 0x5960, 0x9AFA, 0x5967, 0x9AFB, 0x596C, 0x9AFC, 0x5969, - 0x9B40, 0x5978, 0x9B41, 0x5981, 0x9B42, 0x599D, 0x9B43, 0x4F5E, 0x9B44, 0x4FAB, 0x9B45, 0x59A3, 0x9B46, 0x59B2, 0x9B47, 0x59C6, - 0x9B48, 0x59E8, 0x9B49, 0x59DC, 0x9B4A, 0x598D, 0x9B4B, 0x59D9, 0x9B4C, 0x59DA, 0x9B4D, 0x5A25, 0x9B4E, 0x5A1F, 0x9B4F, 0x5A11, - 0x9B50, 0x5A1C, 0x9B51, 0x5A09, 0x9B52, 0x5A1A, 0x9B53, 0x5A40, 0x9B54, 0x5A6C, 0x9B55, 0x5A49, 0x9B56, 0x5A35, 0x9B57, 0x5A36, - 0x9B58, 0x5A62, 0x9B59, 0x5A6A, 0x9B5A, 0x5A9A, 0x9B5B, 0x5ABC, 0x9B5C, 0x5ABE, 0x9B5D, 0x5ACB, 0x9B5E, 0x5AC2, 0x9B5F, 0x5ABD, - 0x9B60, 0x5AE3, 0x9B61, 0x5AD7, 0x9B62, 0x5AE6, 0x9B63, 0x5AE9, 0x9B64, 0x5AD6, 0x9B65, 0x5AFA, 0x9B66, 0x5AFB, 0x9B67, 0x5B0C, - 0x9B68, 0x5B0B, 0x9B69, 0x5B16, 0x9B6A, 0x5B32, 0x9B6B, 0x5AD0, 0x9B6C, 0x5B2A, 0x9B6D, 0x5B36, 0x9B6E, 0x5B3E, 0x9B6F, 0x5B43, - 0x9B70, 0x5B45, 0x9B71, 0x5B40, 0x9B72, 0x5B51, 0x9B73, 0x5B55, 0x9B74, 0x5B5A, 0x9B75, 0x5B5B, 0x9B76, 0x5B65, 0x9B77, 0x5B69, - 0x9B78, 0x5B70, 0x9B79, 0x5B73, 0x9B7A, 0x5B75, 0x9B7B, 0x5B78, 0x9B7C, 0x6588, 0x9B7D, 0x5B7A, 0x9B7E, 0x5B80, 0x9B80, 0x5B83, - 0x9B81, 0x5BA6, 0x9B82, 0x5BB8, 0x9B83, 0x5BC3, 0x9B84, 0x5BC7, 0x9B85, 0x5BC9, 0x9B86, 0x5BD4, 0x9B87, 0x5BD0, 0x9B88, 0x5BE4, - 0x9B89, 0x5BE6, 0x9B8A, 0x5BE2, 0x9B8B, 0x5BDE, 0x9B8C, 0x5BE5, 0x9B8D, 0x5BEB, 0x9B8E, 0x5BF0, 0x9B8F, 0x5BF6, 0x9B90, 0x5BF3, - 0x9B91, 0x5C05, 0x9B92, 0x5C07, 0x9B93, 0x5C08, 0x9B94, 0x5C0D, 0x9B95, 0x5C13, 0x9B96, 0x5C20, 0x9B97, 0x5C22, 0x9B98, 0x5C28, - 0x9B99, 0x5C38, 0x9B9A, 0x5C39, 0x9B9B, 0x5C41, 0x9B9C, 0x5C46, 0x9B9D, 0x5C4E, 0x9B9E, 0x5C53, 0x9B9F, 0x5C50, 0x9BA0, 0x5C4F, - 0x9BA1, 0x5B71, 0x9BA2, 0x5C6C, 0x9BA3, 0x5C6E, 0x9BA4, 0x4E62, 0x9BA5, 0x5C76, 0x9BA6, 0x5C79, 0x9BA7, 0x5C8C, 0x9BA8, 0x5C91, - 0x9BA9, 0x5C94, 0x9BAA, 0x599B, 0x9BAB, 0x5CAB, 0x9BAC, 0x5CBB, 0x9BAD, 0x5CB6, 0x9BAE, 0x5CBC, 0x9BAF, 0x5CB7, 0x9BB0, 0x5CC5, - 0x9BB1, 0x5CBE, 0x9BB2, 0x5CC7, 0x9BB3, 0x5CD9, 0x9BB4, 0x5CE9, 0x9BB5, 0x5CFD, 0x9BB6, 0x5CFA, 0x9BB7, 0x5CED, 0x9BB8, 0x5D8C, - 0x9BB9, 0x5CEA, 0x9BBA, 0x5D0B, 0x9BBB, 0x5D15, 0x9BBC, 0x5D17, 0x9BBD, 0x5D5C, 0x9BBE, 0x5D1F, 0x9BBF, 0x5D1B, 0x9BC0, 0x5D11, - 0x9BC1, 0x5D14, 0x9BC2, 0x5D22, 0x9BC3, 0x5D1A, 0x9BC4, 0x5D19, 0x9BC5, 0x5D18, 0x9BC6, 0x5D4C, 0x9BC7, 0x5D52, 0x9BC8, 0x5D4E, - 0x9BC9, 0x5D4B, 0x9BCA, 0x5D6C, 0x9BCB, 0x5D73, 0x9BCC, 0x5D76, 0x9BCD, 0x5D87, 0x9BCE, 0x5D84, 0x9BCF, 0x5D82, 0x9BD0, 0x5DA2, - 0x9BD1, 0x5D9D, 0x9BD2, 0x5DAC, 0x9BD3, 0x5DAE, 0x9BD4, 0x5DBD, 0x9BD5, 0x5D90, 0x9BD6, 0x5DB7, 0x9BD7, 0x5DBC, 0x9BD8, 0x5DC9, - 0x9BD9, 0x5DCD, 0x9BDA, 0x5DD3, 0x9BDB, 0x5DD2, 0x9BDC, 0x5DD6, 0x9BDD, 0x5DDB, 0x9BDE, 0x5DEB, 0x9BDF, 0x5DF2, 0x9BE0, 0x5DF5, - 0x9BE1, 0x5E0B, 0x9BE2, 0x5E1A, 0x9BE3, 0x5E19, 0x9BE4, 0x5E11, 0x9BE5, 0x5E1B, 0x9BE6, 0x5E36, 0x9BE7, 0x5E37, 0x9BE8, 0x5E44, - 0x9BE9, 0x5E43, 0x9BEA, 0x5E40, 0x9BEB, 0x5E4E, 0x9BEC, 0x5E57, 0x9BED, 0x5E54, 0x9BEE, 0x5E5F, 0x9BEF, 0x5E62, 0x9BF0, 0x5E64, - 0x9BF1, 0x5E47, 0x9BF2, 0x5E75, 0x9BF3, 0x5E76, 0x9BF4, 0x5E7A, 0x9BF5, 0x9EBC, 0x9BF6, 0x5E7F, 0x9BF7, 0x5EA0, 0x9BF8, 0x5EC1, - 0x9BF9, 0x5EC2, 0x9BFA, 0x5EC8, 0x9BFB, 0x5ED0, 0x9BFC, 0x5ECF, 0x9C40, 0x5ED6, 0x9C41, 0x5EE3, 0x9C42, 0x5EDD, 0x9C43, 0x5EDA, - 0x9C44, 0x5EDB, 0x9C45, 0x5EE2, 0x9C46, 0x5EE1, 0x9C47, 0x5EE8, 0x9C48, 0x5EE9, 0x9C49, 0x5EEC, 0x9C4A, 0x5EF1, 0x9C4B, 0x5EF3, - 0x9C4C, 0x5EF0, 0x9C4D, 0x5EF4, 0x9C4E, 0x5EF8, 0x9C4F, 0x5EFE, 0x9C50, 0x5F03, 0x9C51, 0x5F09, 0x9C52, 0x5F5D, 0x9C53, 0x5F5C, - 0x9C54, 0x5F0B, 0x9C55, 0x5F11, 0x9C56, 0x5F16, 0x9C57, 0x5F29, 0x9C58, 0x5F2D, 0x9C59, 0x5F38, 0x9C5A, 0x5F41, 0x9C5B, 0x5F48, - 0x9C5C, 0x5F4C, 0x9C5D, 0x5F4E, 0x9C5E, 0x5F2F, 0x9C5F, 0x5F51, 0x9C60, 0x5F56, 0x9C61, 0x5F57, 0x9C62, 0x5F59, 0x9C63, 0x5F61, - 0x9C64, 0x5F6D, 0x9C65, 0x5F73, 0x9C66, 0x5F77, 0x9C67, 0x5F83, 0x9C68, 0x5F82, 0x9C69, 0x5F7F, 0x9C6A, 0x5F8A, 0x9C6B, 0x5F88, - 0x9C6C, 0x5F91, 0x9C6D, 0x5F87, 0x9C6E, 0x5F9E, 0x9C6F, 0x5F99, 0x9C70, 0x5F98, 0x9C71, 0x5FA0, 0x9C72, 0x5FA8, 0x9C73, 0x5FAD, - 0x9C74, 0x5FBC, 0x9C75, 0x5FD6, 0x9C76, 0x5FFB, 0x9C77, 0x5FE4, 0x9C78, 0x5FF8, 0x9C79, 0x5FF1, 0x9C7A, 0x5FDD, 0x9C7B, 0x60B3, - 0x9C7C, 0x5FFF, 0x9C7D, 0x6021, 0x9C7E, 0x6060, 0x9C80, 0x6019, 0x9C81, 0x6010, 0x9C82, 0x6029, 0x9C83, 0x600E, 0x9C84, 0x6031, - 0x9C85, 0x601B, 0x9C86, 0x6015, 0x9C87, 0x602B, 0x9C88, 0x6026, 0x9C89, 0x600F, 0x9C8A, 0x603A, 0x9C8B, 0x605A, 0x9C8C, 0x6041, - 0x9C8D, 0x606A, 0x9C8E, 0x6077, 0x9C8F, 0x605F, 0x9C90, 0x604A, 0x9C91, 0x6046, 0x9C92, 0x604D, 0x9C93, 0x6063, 0x9C94, 0x6043, - 0x9C95, 0x6064, 0x9C96, 0x6042, 0x9C97, 0x606C, 0x9C98, 0x606B, 0x9C99, 0x6059, 0x9C9A, 0x6081, 0x9C9B, 0x608D, 0x9C9C, 0x60E7, - 0x9C9D, 0x6083, 0x9C9E, 0x609A, 0x9C9F, 0x6084, 0x9CA0, 0x609B, 0x9CA1, 0x6096, 0x9CA2, 0x6097, 0x9CA3, 0x6092, 0x9CA4, 0x60A7, - 0x9CA5, 0x608B, 0x9CA6, 0x60E1, 0x9CA7, 0x60B8, 0x9CA8, 0x60E0, 0x9CA9, 0x60D3, 0x9CAA, 0x60B4, 0x9CAB, 0x5FF0, 0x9CAC, 0x60BD, - 0x9CAD, 0x60C6, 0x9CAE, 0x60B5, 0x9CAF, 0x60D8, 0x9CB0, 0x614D, 0x9CB1, 0x6115, 0x9CB2, 0x6106, 0x9CB3, 0x60F6, 0x9CB4, 0x60F7, - 0x9CB5, 0x6100, 0x9CB6, 0x60F4, 0x9CB7, 0x60FA, 0x9CB8, 0x6103, 0x9CB9, 0x6121, 0x9CBA, 0x60FB, 0x9CBB, 0x60F1, 0x9CBC, 0x610D, - 0x9CBD, 0x610E, 0x9CBE, 0x6147, 0x9CBF, 0x613E, 0x9CC0, 0x6128, 0x9CC1, 0x6127, 0x9CC2, 0x614A, 0x9CC3, 0x613F, 0x9CC4, 0x613C, - 0x9CC5, 0x612C, 0x9CC6, 0x6134, 0x9CC7, 0x613D, 0x9CC8, 0x6142, 0x9CC9, 0x6144, 0x9CCA, 0x6173, 0x9CCB, 0x6177, 0x9CCC, 0x6158, - 0x9CCD, 0x6159, 0x9CCE, 0x615A, 0x9CCF, 0x616B, 0x9CD0, 0x6174, 0x9CD1, 0x616F, 0x9CD2, 0x6165, 0x9CD3, 0x6171, 0x9CD4, 0x615F, - 0x9CD5, 0x615D, 0x9CD6, 0x6153, 0x9CD7, 0x6175, 0x9CD8, 0x6199, 0x9CD9, 0x6196, 0x9CDA, 0x6187, 0x9CDB, 0x61AC, 0x9CDC, 0x6194, - 0x9CDD, 0x619A, 0x9CDE, 0x618A, 0x9CDF, 0x6191, 0x9CE0, 0x61AB, 0x9CE1, 0x61AE, 0x9CE2, 0x61CC, 0x9CE3, 0x61CA, 0x9CE4, 0x61C9, - 0x9CE5, 0x61F7, 0x9CE6, 0x61C8, 0x9CE7, 0x61C3, 0x9CE8, 0x61C6, 0x9CE9, 0x61BA, 0x9CEA, 0x61CB, 0x9CEB, 0x7F79, 0x9CEC, 0x61CD, - 0x9CED, 0x61E6, 0x9CEE, 0x61E3, 0x9CEF, 0x61F6, 0x9CF0, 0x61FA, 0x9CF1, 0x61F4, 0x9CF2, 0x61FF, 0x9CF3, 0x61FD, 0x9CF4, 0x61FC, - 0x9CF5, 0x61FE, 0x9CF6, 0x6200, 0x9CF7, 0x6208, 0x9CF8, 0x6209, 0x9CF9, 0x620D, 0x9CFA, 0x620C, 0x9CFB, 0x6214, 0x9CFC, 0x621B, - 0x9D40, 0x621E, 0x9D41, 0x6221, 0x9D42, 0x622A, 0x9D43, 0x622E, 0x9D44, 0x6230, 0x9D45, 0x6232, 0x9D46, 0x6233, 0x9D47, 0x6241, - 0x9D48, 0x624E, 0x9D49, 0x625E, 0x9D4A, 0x6263, 0x9D4B, 0x625B, 0x9D4C, 0x6260, 0x9D4D, 0x6268, 0x9D4E, 0x627C, 0x9D4F, 0x6282, - 0x9D50, 0x6289, 0x9D51, 0x627E, 0x9D52, 0x6292, 0x9D53, 0x6293, 0x9D54, 0x6296, 0x9D55, 0x62D4, 0x9D56, 0x6283, 0x9D57, 0x6294, - 0x9D58, 0x62D7, 0x9D59, 0x62D1, 0x9D5A, 0x62BB, 0x9D5B, 0x62CF, 0x9D5C, 0x62FF, 0x9D5D, 0x62C6, 0x9D5E, 0x64D4, 0x9D5F, 0x62C8, - 0x9D60, 0x62DC, 0x9D61, 0x62CC, 0x9D62, 0x62CA, 0x9D63, 0x62C2, 0x9D64, 0x62C7, 0x9D65, 0x629B, 0x9D66, 0x62C9, 0x9D67, 0x630C, - 0x9D68, 0x62EE, 0x9D69, 0x62F1, 0x9D6A, 0x6327, 0x9D6B, 0x6302, 0x9D6C, 0x6308, 0x9D6D, 0x62EF, 0x9D6E, 0x62F5, 0x9D6F, 0x6350, - 0x9D70, 0x633E, 0x9D71, 0x634D, 0x9D72, 0x641C, 0x9D73, 0x634F, 0x9D74, 0x6396, 0x9D75, 0x638E, 0x9D76, 0x6380, 0x9D77, 0x63AB, - 0x9D78, 0x6376, 0x9D79, 0x63A3, 0x9D7A, 0x638F, 0x9D7B, 0x6389, 0x9D7C, 0x639F, 0x9D7D, 0x63B5, 0x9D7E, 0x636B, 0x9D80, 0x6369, - 0x9D81, 0x63BE, 0x9D82, 0x63E9, 0x9D83, 0x63C0, 0x9D84, 0x63C6, 0x9D85, 0x63E3, 0x9D86, 0x63C9, 0x9D87, 0x63D2, 0x9D88, 0x63F6, - 0x9D89, 0x63C4, 0x9D8A, 0x6416, 0x9D8B, 0x6434, 0x9D8C, 0x6406, 0x9D8D, 0x6413, 0x9D8E, 0x6426, 0x9D8F, 0x6436, 0x9D90, 0x651D, - 0x9D91, 0x6417, 0x9D92, 0x6428, 0x9D93, 0x640F, 0x9D94, 0x6467, 0x9D95, 0x646F, 0x9D96, 0x6476, 0x9D97, 0x644E, 0x9D98, 0x652A, - 0x9D99, 0x6495, 0x9D9A, 0x6493, 0x9D9B, 0x64A5, 0x9D9C, 0x64A9, 0x9D9D, 0x6488, 0x9D9E, 0x64BC, 0x9D9F, 0x64DA, 0x9DA0, 0x64D2, - 0x9DA1, 0x64C5, 0x9DA2, 0x64C7, 0x9DA3, 0x64BB, 0x9DA4, 0x64D8, 0x9DA5, 0x64C2, 0x9DA6, 0x64F1, 0x9DA7, 0x64E7, 0x9DA8, 0x8209, - 0x9DA9, 0x64E0, 0x9DAA, 0x64E1, 0x9DAB, 0x62AC, 0x9DAC, 0x64E3, 0x9DAD, 0x64EF, 0x9DAE, 0x652C, 0x9DAF, 0x64F6, 0x9DB0, 0x64F4, - 0x9DB1, 0x64F2, 0x9DB2, 0x64FA, 0x9DB3, 0x6500, 0x9DB4, 0x64FD, 0x9DB5, 0x6518, 0x9DB6, 0x651C, 0x9DB7, 0x6505, 0x9DB8, 0x6524, - 0x9DB9, 0x6523, 0x9DBA, 0x652B, 0x9DBB, 0x6534, 0x9DBC, 0x6535, 0x9DBD, 0x6537, 0x9DBE, 0x6536, 0x9DBF, 0x6538, 0x9DC0, 0x754B, - 0x9DC1, 0x6548, 0x9DC2, 0x6556, 0x9DC3, 0x6555, 0x9DC4, 0x654D, 0x9DC5, 0x6558, 0x9DC6, 0x655E, 0x9DC7, 0x655D, 0x9DC8, 0x6572, - 0x9DC9, 0x6578, 0x9DCA, 0x6582, 0x9DCB, 0x6583, 0x9DCC, 0x8B8A, 0x9DCD, 0x659B, 0x9DCE, 0x659F, 0x9DCF, 0x65AB, 0x9DD0, 0x65B7, - 0x9DD1, 0x65C3, 0x9DD2, 0x65C6, 0x9DD3, 0x65C1, 0x9DD4, 0x65C4, 0x9DD5, 0x65CC, 0x9DD6, 0x65D2, 0x9DD7, 0x65DB, 0x9DD8, 0x65D9, - 0x9DD9, 0x65E0, 0x9DDA, 0x65E1, 0x9DDB, 0x65F1, 0x9DDC, 0x6772, 0x9DDD, 0x660A, 0x9DDE, 0x6603, 0x9DDF, 0x65FB, 0x9DE0, 0x6773, - 0x9DE1, 0x6635, 0x9DE2, 0x6636, 0x9DE3, 0x6634, 0x9DE4, 0x661C, 0x9DE5, 0x664F, 0x9DE6, 0x6644, 0x9DE7, 0x6649, 0x9DE8, 0x6641, - 0x9DE9, 0x665E, 0x9DEA, 0x665D, 0x9DEB, 0x6664, 0x9DEC, 0x6667, 0x9DED, 0x6668, 0x9DEE, 0x665F, 0x9DEF, 0x6662, 0x9DF0, 0x6670, - 0x9DF1, 0x6683, 0x9DF2, 0x6688, 0x9DF3, 0x668E, 0x9DF4, 0x6689, 0x9DF5, 0x6684, 0x9DF6, 0x6698, 0x9DF7, 0x669D, 0x9DF8, 0x66C1, - 0x9DF9, 0x66B9, 0x9DFA, 0x66C9, 0x9DFB, 0x66BE, 0x9DFC, 0x66BC, 0x9E40, 0x66C4, 0x9E41, 0x66B8, 0x9E42, 0x66D6, 0x9E43, 0x66DA, - 0x9E44, 0x66E0, 0x9E45, 0x663F, 0x9E46, 0x66E6, 0x9E47, 0x66E9, 0x9E48, 0x66F0, 0x9E49, 0x66F5, 0x9E4A, 0x66F7, 0x9E4B, 0x670F, - 0x9E4C, 0x6716, 0x9E4D, 0x671E, 0x9E4E, 0x6726, 0x9E4F, 0x6727, 0x9E50, 0x9738, 0x9E51, 0x672E, 0x9E52, 0x673F, 0x9E53, 0x6736, - 0x9E54, 0x6741, 0x9E55, 0x6738, 0x9E56, 0x6737, 0x9E57, 0x6746, 0x9E58, 0x675E, 0x9E59, 0x6760, 0x9E5A, 0x6759, 0x9E5B, 0x6763, - 0x9E5C, 0x6764, 0x9E5D, 0x6789, 0x9E5E, 0x6770, 0x9E5F, 0x67A9, 0x9E60, 0x677C, 0x9E61, 0x676A, 0x9E62, 0x678C, 0x9E63, 0x678B, - 0x9E64, 0x67A6, 0x9E65, 0x67A1, 0x9E66, 0x6785, 0x9E67, 0x67B7, 0x9E68, 0x67EF, 0x9E69, 0x67B4, 0x9E6A, 0x67EC, 0x9E6B, 0x67B3, - 0x9E6C, 0x67E9, 0x9E6D, 0x67B8, 0x9E6E, 0x67E4, 0x9E6F, 0x67DE, 0x9E70, 0x67DD, 0x9E71, 0x67E2, 0x9E72, 0x67EE, 0x9E73, 0x67B9, - 0x9E74, 0x67CE, 0x9E75, 0x67C6, 0x9E76, 0x67E7, 0x9E77, 0x6A9C, 0x9E78, 0x681E, 0x9E79, 0x6846, 0x9E7A, 0x6829, 0x9E7B, 0x6840, - 0x9E7C, 0x684D, 0x9E7D, 0x6832, 0x9E7E, 0x684E, 0x9E80, 0x68B3, 0x9E81, 0x682B, 0x9E82, 0x6859, 0x9E83, 0x6863, 0x9E84, 0x6877, - 0x9E85, 0x687F, 0x9E86, 0x689F, 0x9E87, 0x688F, 0x9E88, 0x68AD, 0x9E89, 0x6894, 0x9E8A, 0x689D, 0x9E8B, 0x689B, 0x9E8C, 0x6883, - 0x9E8D, 0x6AAE, 0x9E8E, 0x68B9, 0x9E8F, 0x6874, 0x9E90, 0x68B5, 0x9E91, 0x68A0, 0x9E92, 0x68BA, 0x9E93, 0x690F, 0x9E94, 0x688D, - 0x9E95, 0x687E, 0x9E96, 0x6901, 0x9E97, 0x68CA, 0x9E98, 0x6908, 0x9E99, 0x68D8, 0x9E9A, 0x6922, 0x9E9B, 0x6926, 0x9E9C, 0x68E1, - 0x9E9D, 0x690C, 0x9E9E, 0x68CD, 0x9E9F, 0x68D4, 0x9EA0, 0x68E7, 0x9EA1, 0x68D5, 0x9EA2, 0x6936, 0x9EA3, 0x6912, 0x9EA4, 0x6904, - 0x9EA5, 0x68D7, 0x9EA6, 0x68E3, 0x9EA7, 0x6925, 0x9EA8, 0x68F9, 0x9EA9, 0x68E0, 0x9EAA, 0x68EF, 0x9EAB, 0x6928, 0x9EAC, 0x692A, - 0x9EAD, 0x691A, 0x9EAE, 0x6923, 0x9EAF, 0x6921, 0x9EB0, 0x68C6, 0x9EB1, 0x6979, 0x9EB2, 0x6977, 0x9EB3, 0x695C, 0x9EB4, 0x6978, - 0x9EB5, 0x696B, 0x9EB6, 0x6954, 0x9EB7, 0x697E, 0x9EB8, 0x696E, 0x9EB9, 0x6939, 0x9EBA, 0x6974, 0x9EBB, 0x693D, 0x9EBC, 0x6959, - 0x9EBD, 0x6930, 0x9EBE, 0x6961, 0x9EBF, 0x695E, 0x9EC0, 0x695D, 0x9EC1, 0x6981, 0x9EC2, 0x696A, 0x9EC3, 0x69B2, 0x9EC4, 0x69AE, - 0x9EC5, 0x69D0, 0x9EC6, 0x69BF, 0x9EC7, 0x69C1, 0x9EC8, 0x69D3, 0x9EC9, 0x69BE, 0x9ECA, 0x69CE, 0x9ECB, 0x5BE8, 0x9ECC, 0x69CA, - 0x9ECD, 0x69DD, 0x9ECE, 0x69BB, 0x9ECF, 0x69C3, 0x9ED0, 0x69A7, 0x9ED1, 0x6A2E, 0x9ED2, 0x6991, 0x9ED3, 0x69A0, 0x9ED4, 0x699C, - 0x9ED5, 0x6995, 0x9ED6, 0x69B4, 0x9ED7, 0x69DE, 0x9ED8, 0x69E8, 0x9ED9, 0x6A02, 0x9EDA, 0x6A1B, 0x9EDB, 0x69FF, 0x9EDC, 0x6B0A, - 0x9EDD, 0x69F9, 0x9EDE, 0x69F2, 0x9EDF, 0x69E7, 0x9EE0, 0x6A05, 0x9EE1, 0x69B1, 0x9EE2, 0x6A1E, 0x9EE3, 0x69ED, 0x9EE4, 0x6A14, - 0x9EE5, 0x69EB, 0x9EE6, 0x6A0A, 0x9EE7, 0x6A12, 0x9EE8, 0x6AC1, 0x9EE9, 0x6A23, 0x9EEA, 0x6A13, 0x9EEB, 0x6A44, 0x9EEC, 0x6A0C, - 0x9EED, 0x6A72, 0x9EEE, 0x6A36, 0x9EEF, 0x6A78, 0x9EF0, 0x6A47, 0x9EF1, 0x6A62, 0x9EF2, 0x6A59, 0x9EF3, 0x6A66, 0x9EF4, 0x6A48, - 0x9EF5, 0x6A38, 0x9EF6, 0x6A22, 0x9EF7, 0x6A90, 0x9EF8, 0x6A8D, 0x9EF9, 0x6AA0, 0x9EFA, 0x6A84, 0x9EFB, 0x6AA2, 0x9EFC, 0x6AA3, - 0x9F40, 0x6A97, 0x9F41, 0x8617, 0x9F42, 0x6ABB, 0x9F43, 0x6AC3, 0x9F44, 0x6AC2, 0x9F45, 0x6AB8, 0x9F46, 0x6AB3, 0x9F47, 0x6AAC, - 0x9F48, 0x6ADE, 0x9F49, 0x6AD1, 0x9F4A, 0x6ADF, 0x9F4B, 0x6AAA, 0x9F4C, 0x6ADA, 0x9F4D, 0x6AEA, 0x9F4E, 0x6AFB, 0x9F4F, 0x6B05, - 0x9F50, 0x8616, 0x9F51, 0x6AFA, 0x9F52, 0x6B12, 0x9F53, 0x6B16, 0x9F54, 0x9B31, 0x9F55, 0x6B1F, 0x9F56, 0x6B38, 0x9F57, 0x6B37, - 0x9F58, 0x76DC, 0x9F59, 0x6B39, 0x9F5A, 0x98EE, 0x9F5B, 0x6B47, 0x9F5C, 0x6B43, 0x9F5D, 0x6B49, 0x9F5E, 0x6B50, 0x9F5F, 0x6B59, - 0x9F60, 0x6B54, 0x9F61, 0x6B5B, 0x9F62, 0x6B5F, 0x9F63, 0x6B61, 0x9F64, 0x6B78, 0x9F65, 0x6B79, 0x9F66, 0x6B7F, 0x9F67, 0x6B80, - 0x9F68, 0x6B84, 0x9F69, 0x6B83, 0x9F6A, 0x6B8D, 0x9F6B, 0x6B98, 0x9F6C, 0x6B95, 0x9F6D, 0x6B9E, 0x9F6E, 0x6BA4, 0x9F6F, 0x6BAA, - 0x9F70, 0x6BAB, 0x9F71, 0x6BAF, 0x9F72, 0x6BB2, 0x9F73, 0x6BB1, 0x9F74, 0x6BB3, 0x9F75, 0x6BB7, 0x9F76, 0x6BBC, 0x9F77, 0x6BC6, - 0x9F78, 0x6BCB, 0x9F79, 0x6BD3, 0x9F7A, 0x6BDF, 0x9F7B, 0x6BEC, 0x9F7C, 0x6BEB, 0x9F7D, 0x6BF3, 0x9F7E, 0x6BEF, 0x9F80, 0x9EBE, - 0x9F81, 0x6C08, 0x9F82, 0x6C13, 0x9F83, 0x6C14, 0x9F84, 0x6C1B, 0x9F85, 0x6C24, 0x9F86, 0x6C23, 0x9F87, 0x6C5E, 0x9F88, 0x6C55, - 0x9F89, 0x6C62, 0x9F8A, 0x6C6A, 0x9F8B, 0x6C82, 0x9F8C, 0x6C8D, 0x9F8D, 0x6C9A, 0x9F8E, 0x6C81, 0x9F8F, 0x6C9B, 0x9F90, 0x6C7E, - 0x9F91, 0x6C68, 0x9F92, 0x6C73, 0x9F93, 0x6C92, 0x9F94, 0x6C90, 0x9F95, 0x6CC4, 0x9F96, 0x6CF1, 0x9F97, 0x6CD3, 0x9F98, 0x6CBD, - 0x9F99, 0x6CD7, 0x9F9A, 0x6CC5, 0x9F9B, 0x6CDD, 0x9F9C, 0x6CAE, 0x9F9D, 0x6CB1, 0x9F9E, 0x6CBE, 0x9F9F, 0x6CBA, 0x9FA0, 0x6CDB, - 0x9FA1, 0x6CEF, 0x9FA2, 0x6CD9, 0x9FA3, 0x6CEA, 0x9FA4, 0x6D1F, 0x9FA5, 0x884D, 0x9FA6, 0x6D36, 0x9FA7, 0x6D2B, 0x9FA8, 0x6D3D, - 0x9FA9, 0x6D38, 0x9FAA, 0x6D19, 0x9FAB, 0x6D35, 0x9FAC, 0x6D33, 0x9FAD, 0x6D12, 0x9FAE, 0x6D0C, 0x9FAF, 0x6D63, 0x9FB0, 0x6D93, - 0x9FB1, 0x6D64, 0x9FB2, 0x6D5A, 0x9FB3, 0x6D79, 0x9FB4, 0x6D59, 0x9FB5, 0x6D8E, 0x9FB6, 0x6D95, 0x9FB7, 0x6FE4, 0x9FB8, 0x6D85, - 0x9FB9, 0x6DF9, 0x9FBA, 0x6E15, 0x9FBB, 0x6E0A, 0x9FBC, 0x6DB5, 0x9FBD, 0x6DC7, 0x9FBE, 0x6DE6, 0x9FBF, 0x6DB8, 0x9FC0, 0x6DC6, - 0x9FC1, 0x6DEC, 0x9FC2, 0x6DDE, 0x9FC3, 0x6DCC, 0x9FC4, 0x6DE8, 0x9FC5, 0x6DD2, 0x9FC6, 0x6DC5, 0x9FC7, 0x6DFA, 0x9FC8, 0x6DD9, - 0x9FC9, 0x6DE4, 0x9FCA, 0x6DD5, 0x9FCB, 0x6DEA, 0x9FCC, 0x6DEE, 0x9FCD, 0x6E2D, 0x9FCE, 0x6E6E, 0x9FCF, 0x6E2E, 0x9FD0, 0x6E19, - 0x9FD1, 0x6E72, 0x9FD2, 0x6E5F, 0x9FD3, 0x6E3E, 0x9FD4, 0x6E23, 0x9FD5, 0x6E6B, 0x9FD6, 0x6E2B, 0x9FD7, 0x6E76, 0x9FD8, 0x6E4D, - 0x9FD9, 0x6E1F, 0x9FDA, 0x6E43, 0x9FDB, 0x6E3A, 0x9FDC, 0x6E4E, 0x9FDD, 0x6E24, 0x9FDE, 0x6EFF, 0x9FDF, 0x6E1D, 0x9FE0, 0x6E38, - 0x9FE1, 0x6E82, 0x9FE2, 0x6EAA, 0x9FE3, 0x6E98, 0x9FE4, 0x6EC9, 0x9FE5, 0x6EB7, 0x9FE6, 0x6ED3, 0x9FE7, 0x6EBD, 0x9FE8, 0x6EAF, - 0x9FE9, 0x6EC4, 0x9FEA, 0x6EB2, 0x9FEB, 0x6ED4, 0x9FEC, 0x6ED5, 0x9FED, 0x6E8F, 0x9FEE, 0x6EA5, 0x9FEF, 0x6EC2, 0x9FF0, 0x6E9F, - 0x9FF1, 0x6F41, 0x9FF2, 0x6F11, 0x9FF3, 0x704C, 0x9FF4, 0x6EEC, 0x9FF5, 0x6EF8, 0x9FF6, 0x6EFE, 0x9FF7, 0x6F3F, 0x9FF8, 0x6EF2, - 0x9FF9, 0x6F31, 0x9FFA, 0x6EEF, 0x9FFB, 0x6F32, 0x9FFC, 0x6ECC, 0xE040, 0x6F3E, 0xE041, 0x6F13, 0xE042, 0x6EF7, 0xE043, 0x6F86, - 0xE044, 0x6F7A, 0xE045, 0x6F78, 0xE046, 0x6F81, 0xE047, 0x6F80, 0xE048, 0x6F6F, 0xE049, 0x6F5B, 0xE04A, 0x6FF3, 0xE04B, 0x6F6D, - 0xE04C, 0x6F82, 0xE04D, 0x6F7C, 0xE04E, 0x6F58, 0xE04F, 0x6F8E, 0xE050, 0x6F91, 0xE051, 0x6FC2, 0xE052, 0x6F66, 0xE053, 0x6FB3, - 0xE054, 0x6FA3, 0xE055, 0x6FA1, 0xE056, 0x6FA4, 0xE057, 0x6FB9, 0xE058, 0x6FC6, 0xE059, 0x6FAA, 0xE05A, 0x6FDF, 0xE05B, 0x6FD5, - 0xE05C, 0x6FEC, 0xE05D, 0x6FD4, 0xE05E, 0x6FD8, 0xE05F, 0x6FF1, 0xE060, 0x6FEE, 0xE061, 0x6FDB, 0xE062, 0x7009, 0xE063, 0x700B, - 0xE064, 0x6FFA, 0xE065, 0x7011, 0xE066, 0x7001, 0xE067, 0x700F, 0xE068, 0x6FFE, 0xE069, 0x701B, 0xE06A, 0x701A, 0xE06B, 0x6F74, - 0xE06C, 0x701D, 0xE06D, 0x7018, 0xE06E, 0x701F, 0xE06F, 0x7030, 0xE070, 0x703E, 0xE071, 0x7032, 0xE072, 0x7051, 0xE073, 0x7063, - 0xE074, 0x7099, 0xE075, 0x7092, 0xE076, 0x70AF, 0xE077, 0x70F1, 0xE078, 0x70AC, 0xE079, 0x70B8, 0xE07A, 0x70B3, 0xE07B, 0x70AE, - 0xE07C, 0x70DF, 0xE07D, 0x70CB, 0xE07E, 0x70DD, 0xE080, 0x70D9, 0xE081, 0x7109, 0xE082, 0x70FD, 0xE083, 0x711C, 0xE084, 0x7119, - 0xE085, 0x7165, 0xE086, 0x7155, 0xE087, 0x7188, 0xE088, 0x7166, 0xE089, 0x7162, 0xE08A, 0x714C, 0xE08B, 0x7156, 0xE08C, 0x716C, - 0xE08D, 0x718F, 0xE08E, 0x71FB, 0xE08F, 0x7184, 0xE090, 0x7195, 0xE091, 0x71A8, 0xE092, 0x71AC, 0xE093, 0x71D7, 0xE094, 0x71B9, - 0xE095, 0x71BE, 0xE096, 0x71D2, 0xE097, 0x71C9, 0xE098, 0x71D4, 0xE099, 0x71CE, 0xE09A, 0x71E0, 0xE09B, 0x71EC, 0xE09C, 0x71E7, - 0xE09D, 0x71F5, 0xE09E, 0x71FC, 0xE09F, 0x71F9, 0xE0A0, 0x71FF, 0xE0A1, 0x720D, 0xE0A2, 0x7210, 0xE0A3, 0x721B, 0xE0A4, 0x7228, - 0xE0A5, 0x722D, 0xE0A6, 0x722C, 0xE0A7, 0x7230, 0xE0A8, 0x7232, 0xE0A9, 0x723B, 0xE0AA, 0x723C, 0xE0AB, 0x723F, 0xE0AC, 0x7240, - 0xE0AD, 0x7246, 0xE0AE, 0x724B, 0xE0AF, 0x7258, 0xE0B0, 0x7274, 0xE0B1, 0x727E, 0xE0B2, 0x7282, 0xE0B3, 0x7281, 0xE0B4, 0x7287, - 0xE0B5, 0x7292, 0xE0B6, 0x7296, 0xE0B7, 0x72A2, 0xE0B8, 0x72A7, 0xE0B9, 0x72B9, 0xE0BA, 0x72B2, 0xE0BB, 0x72C3, 0xE0BC, 0x72C6, - 0xE0BD, 0x72C4, 0xE0BE, 0x72CE, 0xE0BF, 0x72D2, 0xE0C0, 0x72E2, 0xE0C1, 0x72E0, 0xE0C2, 0x72E1, 0xE0C3, 0x72F9, 0xE0C4, 0x72F7, - 0xE0C5, 0x500F, 0xE0C6, 0x7317, 0xE0C7, 0x730A, 0xE0C8, 0x731C, 0xE0C9, 0x7316, 0xE0CA, 0x731D, 0xE0CB, 0x7334, 0xE0CC, 0x732F, - 0xE0CD, 0x7329, 0xE0CE, 0x7325, 0xE0CF, 0x733E, 0xE0D0, 0x734E, 0xE0D1, 0x734F, 0xE0D2, 0x9ED8, 0xE0D3, 0x7357, 0xE0D4, 0x736A, - 0xE0D5, 0x7368, 0xE0D6, 0x7370, 0xE0D7, 0x7378, 0xE0D8, 0x7375, 0xE0D9, 0x737B, 0xE0DA, 0x737A, 0xE0DB, 0x73C8, 0xE0DC, 0x73B3, - 0xE0DD, 0x73CE, 0xE0DE, 0x73BB, 0xE0DF, 0x73C0, 0xE0E0, 0x73E5, 0xE0E1, 0x73EE, 0xE0E2, 0x73DE, 0xE0E3, 0x74A2, 0xE0E4, 0x7405, - 0xE0E5, 0x746F, 0xE0E6, 0x7425, 0xE0E7, 0x73F8, 0xE0E8, 0x7432, 0xE0E9, 0x743A, 0xE0EA, 0x7455, 0xE0EB, 0x743F, 0xE0EC, 0x745F, - 0xE0ED, 0x7459, 0xE0EE, 0x7441, 0xE0EF, 0x745C, 0xE0F0, 0x7469, 0xE0F1, 0x7470, 0xE0F2, 0x7463, 0xE0F3, 0x746A, 0xE0F4, 0x7476, - 0xE0F5, 0x747E, 0xE0F6, 0x748B, 0xE0F7, 0x749E, 0xE0F8, 0x74A7, 0xE0F9, 0x74CA, 0xE0FA, 0x74CF, 0xE0FB, 0x74D4, 0xE0FC, 0x73F1, - 0xE140, 0x74E0, 0xE141, 0x74E3, 0xE142, 0x74E7, 0xE143, 0x74E9, 0xE144, 0x74EE, 0xE145, 0x74F2, 0xE146, 0x74F0, 0xE147, 0x74F1, - 0xE148, 0x74F8, 0xE149, 0x74F7, 0xE14A, 0x7504, 0xE14B, 0x7503, 0xE14C, 0x7505, 0xE14D, 0x750C, 0xE14E, 0x750E, 0xE14F, 0x750D, - 0xE150, 0x7515, 0xE151, 0x7513, 0xE152, 0x751E, 0xE153, 0x7526, 0xE154, 0x752C, 0xE155, 0x753C, 0xE156, 0x7544, 0xE157, 0x754D, - 0xE158, 0x754A, 0xE159, 0x7549, 0xE15A, 0x755B, 0xE15B, 0x7546, 0xE15C, 0x755A, 0xE15D, 0x7569, 0xE15E, 0x7564, 0xE15F, 0x7567, - 0xE160, 0x756B, 0xE161, 0x756D, 0xE162, 0x7578, 0xE163, 0x7576, 0xE164, 0x7586, 0xE165, 0x7587, 0xE166, 0x7574, 0xE167, 0x758A, - 0xE168, 0x7589, 0xE169, 0x7582, 0xE16A, 0x7594, 0xE16B, 0x759A, 0xE16C, 0x759D, 0xE16D, 0x75A5, 0xE16E, 0x75A3, 0xE16F, 0x75C2, - 0xE170, 0x75B3, 0xE171, 0x75C3, 0xE172, 0x75B5, 0xE173, 0x75BD, 0xE174, 0x75B8, 0xE175, 0x75BC, 0xE176, 0x75B1, 0xE177, 0x75CD, - 0xE178, 0x75CA, 0xE179, 0x75D2, 0xE17A, 0x75D9, 0xE17B, 0x75E3, 0xE17C, 0x75DE, 0xE17D, 0x75FE, 0xE17E, 0x75FF, 0xE180, 0x75FC, - 0xE181, 0x7601, 0xE182, 0x75F0, 0xE183, 0x75FA, 0xE184, 0x75F2, 0xE185, 0x75F3, 0xE186, 0x760B, 0xE187, 0x760D, 0xE188, 0x7609, - 0xE189, 0x761F, 0xE18A, 0x7627, 0xE18B, 0x7620, 0xE18C, 0x7621, 0xE18D, 0x7622, 0xE18E, 0x7624, 0xE18F, 0x7634, 0xE190, 0x7630, - 0xE191, 0x763B, 0xE192, 0x7647, 0xE193, 0x7648, 0xE194, 0x7646, 0xE195, 0x765C, 0xE196, 0x7658, 0xE197, 0x7661, 0xE198, 0x7662, - 0xE199, 0x7668, 0xE19A, 0x7669, 0xE19B, 0x766A, 0xE19C, 0x7667, 0xE19D, 0x766C, 0xE19E, 0x7670, 0xE19F, 0x7672, 0xE1A0, 0x7676, - 0xE1A1, 0x7678, 0xE1A2, 0x767C, 0xE1A3, 0x7680, 0xE1A4, 0x7683, 0xE1A5, 0x7688, 0xE1A6, 0x768B, 0xE1A7, 0x768E, 0xE1A8, 0x7696, - 0xE1A9, 0x7693, 0xE1AA, 0x7699, 0xE1AB, 0x769A, 0xE1AC, 0x76B0, 0xE1AD, 0x76B4, 0xE1AE, 0x76B8, 0xE1AF, 0x76B9, 0xE1B0, 0x76BA, - 0xE1B1, 0x76C2, 0xE1B2, 0x76CD, 0xE1B3, 0x76D6, 0xE1B4, 0x76D2, 0xE1B5, 0x76DE, 0xE1B6, 0x76E1, 0xE1B7, 0x76E5, 0xE1B8, 0x76E7, - 0xE1B9, 0x76EA, 0xE1BA, 0x862F, 0xE1BB, 0x76FB, 0xE1BC, 0x7708, 0xE1BD, 0x7707, 0xE1BE, 0x7704, 0xE1BF, 0x7729, 0xE1C0, 0x7724, - 0xE1C1, 0x771E, 0xE1C2, 0x7725, 0xE1C3, 0x7726, 0xE1C4, 0x771B, 0xE1C5, 0x7737, 0xE1C6, 0x7738, 0xE1C7, 0x7747, 0xE1C8, 0x775A, - 0xE1C9, 0x7768, 0xE1CA, 0x776B, 0xE1CB, 0x775B, 0xE1CC, 0x7765, 0xE1CD, 0x777F, 0xE1CE, 0x777E, 0xE1CF, 0x7779, 0xE1D0, 0x778E, - 0xE1D1, 0x778B, 0xE1D2, 0x7791, 0xE1D3, 0x77A0, 0xE1D4, 0x779E, 0xE1D5, 0x77B0, 0xE1D6, 0x77B6, 0xE1D7, 0x77B9, 0xE1D8, 0x77BF, - 0xE1D9, 0x77BC, 0xE1DA, 0x77BD, 0xE1DB, 0x77BB, 0xE1DC, 0x77C7, 0xE1DD, 0x77CD, 0xE1DE, 0x77D7, 0xE1DF, 0x77DA, 0xE1E0, 0x77DC, - 0xE1E1, 0x77E3, 0xE1E2, 0x77EE, 0xE1E3, 0x77FC, 0xE1E4, 0x780C, 0xE1E5, 0x7812, 0xE1E6, 0x7926, 0xE1E7, 0x7820, 0xE1E8, 0x792A, - 0xE1E9, 0x7845, 0xE1EA, 0x788E, 0xE1EB, 0x7874, 0xE1EC, 0x7886, 0xE1ED, 0x787C, 0xE1EE, 0x789A, 0xE1EF, 0x788C, 0xE1F0, 0x78A3, - 0xE1F1, 0x78B5, 0xE1F2, 0x78AA, 0xE1F3, 0x78AF, 0xE1F4, 0x78D1, 0xE1F5, 0x78C6, 0xE1F6, 0x78CB, 0xE1F7, 0x78D4, 0xE1F8, 0x78BE, - 0xE1F9, 0x78BC, 0xE1FA, 0x78C5, 0xE1FB, 0x78CA, 0xE1FC, 0x78EC, 0xE240, 0x78E7, 0xE241, 0x78DA, 0xE242, 0x78FD, 0xE243, 0x78F4, - 0xE244, 0x7907, 0xE245, 0x7912, 0xE246, 0x7911, 0xE247, 0x7919, 0xE248, 0x792C, 0xE249, 0x792B, 0xE24A, 0x7940, 0xE24B, 0x7960, - 0xE24C, 0x7957, 0xE24D, 0x795F, 0xE24E, 0x795A, 0xE24F, 0x7955, 0xE250, 0x7953, 0xE251, 0x797A, 0xE252, 0x797F, 0xE253, 0x798A, - 0xE254, 0x799D, 0xE255, 0x79A7, 0xE256, 0x9F4B, 0xE257, 0x79AA, 0xE258, 0x79AE, 0xE259, 0x79B3, 0xE25A, 0x79B9, 0xE25B, 0x79BA, - 0xE25C, 0x79C9, 0xE25D, 0x79D5, 0xE25E, 0x79E7, 0xE25F, 0x79EC, 0xE260, 0x79E1, 0xE261, 0x79E3, 0xE262, 0x7A08, 0xE263, 0x7A0D, - 0xE264, 0x7A18, 0xE265, 0x7A19, 0xE266, 0x7A20, 0xE267, 0x7A1F, 0xE268, 0x7980, 0xE269, 0x7A31, 0xE26A, 0x7A3B, 0xE26B, 0x7A3E, - 0xE26C, 0x7A37, 0xE26D, 0x7A43, 0xE26E, 0x7A57, 0xE26F, 0x7A49, 0xE270, 0x7A61, 0xE271, 0x7A62, 0xE272, 0x7A69, 0xE273, 0x9F9D, - 0xE274, 0x7A70, 0xE275, 0x7A79, 0xE276, 0x7A7D, 0xE277, 0x7A88, 0xE278, 0x7A97, 0xE279, 0x7A95, 0xE27A, 0x7A98, 0xE27B, 0x7A96, - 0xE27C, 0x7AA9, 0xE27D, 0x7AC8, 0xE27E, 0x7AB0, 0xE280, 0x7AB6, 0xE281, 0x7AC5, 0xE282, 0x7AC4, 0xE283, 0x7ABF, 0xE284, 0x9083, - 0xE285, 0x7AC7, 0xE286, 0x7ACA, 0xE287, 0x7ACD, 0xE288, 0x7ACF, 0xE289, 0x7AD5, 0xE28A, 0x7AD3, 0xE28B, 0x7AD9, 0xE28C, 0x7ADA, - 0xE28D, 0x7ADD, 0xE28E, 0x7AE1, 0xE28F, 0x7AE2, 0xE290, 0x7AE6, 0xE291, 0x7AED, 0xE292, 0x7AF0, 0xE293, 0x7B02, 0xE294, 0x7B0F, - 0xE295, 0x7B0A, 0xE296, 0x7B06, 0xE297, 0x7B33, 0xE298, 0x7B18, 0xE299, 0x7B19, 0xE29A, 0x7B1E, 0xE29B, 0x7B35, 0xE29C, 0x7B28, - 0xE29D, 0x7B36, 0xE29E, 0x7B50, 0xE29F, 0x7B7A, 0xE2A0, 0x7B04, 0xE2A1, 0x7B4D, 0xE2A2, 0x7B0B, 0xE2A3, 0x7B4C, 0xE2A4, 0x7B45, - 0xE2A5, 0x7B75, 0xE2A6, 0x7B65, 0xE2A7, 0x7B74, 0xE2A8, 0x7B67, 0xE2A9, 0x7B70, 0xE2AA, 0x7B71, 0xE2AB, 0x7B6C, 0xE2AC, 0x7B6E, - 0xE2AD, 0x7B9D, 0xE2AE, 0x7B98, 0xE2AF, 0x7B9F, 0xE2B0, 0x7B8D, 0xE2B1, 0x7B9C, 0xE2B2, 0x7B9A, 0xE2B3, 0x7B8B, 0xE2B4, 0x7B92, - 0xE2B5, 0x7B8F, 0xE2B6, 0x7B5D, 0xE2B7, 0x7B99, 0xE2B8, 0x7BCB, 0xE2B9, 0x7BC1, 0xE2BA, 0x7BCC, 0xE2BB, 0x7BCF, 0xE2BC, 0x7BB4, - 0xE2BD, 0x7BC6, 0xE2BE, 0x7BDD, 0xE2BF, 0x7BE9, 0xE2C0, 0x7C11, 0xE2C1, 0x7C14, 0xE2C2, 0x7BE6, 0xE2C3, 0x7BE5, 0xE2C4, 0x7C60, - 0xE2C5, 0x7C00, 0xE2C6, 0x7C07, 0xE2C7, 0x7C13, 0xE2C8, 0x7BF3, 0xE2C9, 0x7BF7, 0xE2CA, 0x7C17, 0xE2CB, 0x7C0D, 0xE2CC, 0x7BF6, - 0xE2CD, 0x7C23, 0xE2CE, 0x7C27, 0xE2CF, 0x7C2A, 0xE2D0, 0x7C1F, 0xE2D1, 0x7C37, 0xE2D2, 0x7C2B, 0xE2D3, 0x7C3D, 0xE2D4, 0x7C4C, - 0xE2D5, 0x7C43, 0xE2D6, 0x7C54, 0xE2D7, 0x7C4F, 0xE2D8, 0x7C40, 0xE2D9, 0x7C50, 0xE2DA, 0x7C58, 0xE2DB, 0x7C5F, 0xE2DC, 0x7C64, - 0xE2DD, 0x7C56, 0xE2DE, 0x7C65, 0xE2DF, 0x7C6C, 0xE2E0, 0x7C75, 0xE2E1, 0x7C83, 0xE2E2, 0x7C90, 0xE2E3, 0x7CA4, 0xE2E4, 0x7CAD, - 0xE2E5, 0x7CA2, 0xE2E6, 0x7CAB, 0xE2E7, 0x7CA1, 0xE2E8, 0x7CA8, 0xE2E9, 0x7CB3, 0xE2EA, 0x7CB2, 0xE2EB, 0x7CB1, 0xE2EC, 0x7CAE, - 0xE2ED, 0x7CB9, 0xE2EE, 0x7CBD, 0xE2EF, 0x7CC0, 0xE2F0, 0x7CC5, 0xE2F1, 0x7CC2, 0xE2F2, 0x7CD8, 0xE2F3, 0x7CD2, 0xE2F4, 0x7CDC, - 0xE2F5, 0x7CE2, 0xE2F6, 0x9B3B, 0xE2F7, 0x7CEF, 0xE2F8, 0x7CF2, 0xE2F9, 0x7CF4, 0xE2FA, 0x7CF6, 0xE2FB, 0x7CFA, 0xE2FC, 0x7D06, - 0xE340, 0x7D02, 0xE341, 0x7D1C, 0xE342, 0x7D15, 0xE343, 0x7D0A, 0xE344, 0x7D45, 0xE345, 0x7D4B, 0xE346, 0x7D2E, 0xE347, 0x7D32, - 0xE348, 0x7D3F, 0xE349, 0x7D35, 0xE34A, 0x7D46, 0xE34B, 0x7D73, 0xE34C, 0x7D56, 0xE34D, 0x7D4E, 0xE34E, 0x7D72, 0xE34F, 0x7D68, - 0xE350, 0x7D6E, 0xE351, 0x7D4F, 0xE352, 0x7D63, 0xE353, 0x7D93, 0xE354, 0x7D89, 0xE355, 0x7D5B, 0xE356, 0x7D8F, 0xE357, 0x7D7D, - 0xE358, 0x7D9B, 0xE359, 0x7DBA, 0xE35A, 0x7DAE, 0xE35B, 0x7DA3, 0xE35C, 0x7DB5, 0xE35D, 0x7DC7, 0xE35E, 0x7DBD, 0xE35F, 0x7DAB, - 0xE360, 0x7E3D, 0xE361, 0x7DA2, 0xE362, 0x7DAF, 0xE363, 0x7DDC, 0xE364, 0x7DB8, 0xE365, 0x7D9F, 0xE366, 0x7DB0, 0xE367, 0x7DD8, - 0xE368, 0x7DDD, 0xE369, 0x7DE4, 0xE36A, 0x7DDE, 0xE36B, 0x7DFB, 0xE36C, 0x7DF2, 0xE36D, 0x7DE1, 0xE36E, 0x7E05, 0xE36F, 0x7E0A, - 0xE370, 0x7E23, 0xE371, 0x7E21, 0xE372, 0x7E12, 0xE373, 0x7E31, 0xE374, 0x7E1F, 0xE375, 0x7E09, 0xE376, 0x7E0B, 0xE377, 0x7E22, - 0xE378, 0x7E46, 0xE379, 0x7E66, 0xE37A, 0x7E3B, 0xE37B, 0x7E35, 0xE37C, 0x7E39, 0xE37D, 0x7E43, 0xE37E, 0x7E37, 0xE380, 0x7E32, - 0xE381, 0x7E3A, 0xE382, 0x7E67, 0xE383, 0x7E5D, 0xE384, 0x7E56, 0xE385, 0x7E5E, 0xE386, 0x7E59, 0xE387, 0x7E5A, 0xE388, 0x7E79, - 0xE389, 0x7E6A, 0xE38A, 0x7E69, 0xE38B, 0x7E7C, 0xE38C, 0x7E7B, 0xE38D, 0x7E83, 0xE38E, 0x7DD5, 0xE38F, 0x7E7D, 0xE390, 0x8FAE, - 0xE391, 0x7E7F, 0xE392, 0x7E88, 0xE393, 0x7E89, 0xE394, 0x7E8C, 0xE395, 0x7E92, 0xE396, 0x7E90, 0xE397, 0x7E93, 0xE398, 0x7E94, - 0xE399, 0x7E96, 0xE39A, 0x7E8E, 0xE39B, 0x7E9B, 0xE39C, 0x7E9C, 0xE39D, 0x7F38, 0xE39E, 0x7F3A, 0xE39F, 0x7F45, 0xE3A0, 0x7F4C, - 0xE3A1, 0x7F4D, 0xE3A2, 0x7F4E, 0xE3A3, 0x7F50, 0xE3A4, 0x7F51, 0xE3A5, 0x7F55, 0xE3A6, 0x7F54, 0xE3A7, 0x7F58, 0xE3A8, 0x7F5F, - 0xE3A9, 0x7F60, 0xE3AA, 0x7F68, 0xE3AB, 0x7F69, 0xE3AC, 0x7F67, 0xE3AD, 0x7F78, 0xE3AE, 0x7F82, 0xE3AF, 0x7F86, 0xE3B0, 0x7F83, - 0xE3B1, 0x7F88, 0xE3B2, 0x7F87, 0xE3B3, 0x7F8C, 0xE3B4, 0x7F94, 0xE3B5, 0x7F9E, 0xE3B6, 0x7F9D, 0xE3B7, 0x7F9A, 0xE3B8, 0x7FA3, - 0xE3B9, 0x7FAF, 0xE3BA, 0x7FB2, 0xE3BB, 0x7FB9, 0xE3BC, 0x7FAE, 0xE3BD, 0x7FB6, 0xE3BE, 0x7FB8, 0xE3BF, 0x8B71, 0xE3C0, 0x7FC5, - 0xE3C1, 0x7FC6, 0xE3C2, 0x7FCA, 0xE3C3, 0x7FD5, 0xE3C4, 0x7FD4, 0xE3C5, 0x7FE1, 0xE3C6, 0x7FE6, 0xE3C7, 0x7FE9, 0xE3C8, 0x7FF3, - 0xE3C9, 0x7FF9, 0xE3CA, 0x98DC, 0xE3CB, 0x8006, 0xE3CC, 0x8004, 0xE3CD, 0x800B, 0xE3CE, 0x8012, 0xE3CF, 0x8018, 0xE3D0, 0x8019, - 0xE3D1, 0x801C, 0xE3D2, 0x8021, 0xE3D3, 0x8028, 0xE3D4, 0x803F, 0xE3D5, 0x803B, 0xE3D6, 0x804A, 0xE3D7, 0x8046, 0xE3D8, 0x8052, - 0xE3D9, 0x8058, 0xE3DA, 0x805A, 0xE3DB, 0x805F, 0xE3DC, 0x8062, 0xE3DD, 0x8068, 0xE3DE, 0x8073, 0xE3DF, 0x8072, 0xE3E0, 0x8070, - 0xE3E1, 0x8076, 0xE3E2, 0x8079, 0xE3E3, 0x807D, 0xE3E4, 0x807F, 0xE3E5, 0x8084, 0xE3E6, 0x8086, 0xE3E7, 0x8085, 0xE3E8, 0x809B, - 0xE3E9, 0x8093, 0xE3EA, 0x809A, 0xE3EB, 0x80AD, 0xE3EC, 0x5190, 0xE3ED, 0x80AC, 0xE3EE, 0x80DB, 0xE3EF, 0x80E5, 0xE3F0, 0x80D9, - 0xE3F1, 0x80DD, 0xE3F2, 0x80C4, 0xE3F3, 0x80DA, 0xE3F4, 0x80D6, 0xE3F5, 0x8109, 0xE3F6, 0x80EF, 0xE3F7, 0x80F1, 0xE3F8, 0x811B, - 0xE3F9, 0x8129, 0xE3FA, 0x8123, 0xE3FB, 0x812F, 0xE3FC, 0x814B, 0xE440, 0x968B, 0xE441, 0x8146, 0xE442, 0x813E, 0xE443, 0x8153, - 0xE444, 0x8151, 0xE445, 0x80FC, 0xE446, 0x8171, 0xE447, 0x816E, 0xE448, 0x8165, 0xE449, 0x8166, 0xE44A, 0x8174, 0xE44B, 0x8183, - 0xE44C, 0x8188, 0xE44D, 0x818A, 0xE44E, 0x8180, 0xE44F, 0x8182, 0xE450, 0x81A0, 0xE451, 0x8195, 0xE452, 0x81A4, 0xE453, 0x81A3, - 0xE454, 0x815F, 0xE455, 0x8193, 0xE456, 0x81A9, 0xE457, 0x81B0, 0xE458, 0x81B5, 0xE459, 0x81BE, 0xE45A, 0x81B8, 0xE45B, 0x81BD, - 0xE45C, 0x81C0, 0xE45D, 0x81C2, 0xE45E, 0x81BA, 0xE45F, 0x81C9, 0xE460, 0x81CD, 0xE461, 0x81D1, 0xE462, 0x81D9, 0xE463, 0x81D8, - 0xE464, 0x81C8, 0xE465, 0x81DA, 0xE466, 0x81DF, 0xE467, 0x81E0, 0xE468, 0x81E7, 0xE469, 0x81FA, 0xE46A, 0x81FB, 0xE46B, 0x81FE, - 0xE46C, 0x8201, 0xE46D, 0x8202, 0xE46E, 0x8205, 0xE46F, 0x8207, 0xE470, 0x820A, 0xE471, 0x820D, 0xE472, 0x8210, 0xE473, 0x8216, - 0xE474, 0x8229, 0xE475, 0x822B, 0xE476, 0x8238, 0xE477, 0x8233, 0xE478, 0x8240, 0xE479, 0x8259, 0xE47A, 0x8258, 0xE47B, 0x825D, - 0xE47C, 0x825A, 0xE47D, 0x825F, 0xE47E, 0x8264, 0xE480, 0x8262, 0xE481, 0x8268, 0xE482, 0x826A, 0xE483, 0x826B, 0xE484, 0x822E, - 0xE485, 0x8271, 0xE486, 0x8277, 0xE487, 0x8278, 0xE488, 0x827E, 0xE489, 0x828D, 0xE48A, 0x8292, 0xE48B, 0x82AB, 0xE48C, 0x829F, - 0xE48D, 0x82BB, 0xE48E, 0x82AC, 0xE48F, 0x82E1, 0xE490, 0x82E3, 0xE491, 0x82DF, 0xE492, 0x82D2, 0xE493, 0x82F4, 0xE494, 0x82F3, - 0xE495, 0x82FA, 0xE496, 0x8393, 0xE497, 0x8303, 0xE498, 0x82FB, 0xE499, 0x82F9, 0xE49A, 0x82DE, 0xE49B, 0x8306, 0xE49C, 0x82DC, - 0xE49D, 0x8309, 0xE49E, 0x82D9, 0xE49F, 0x8335, 0xE4A0, 0x8334, 0xE4A1, 0x8316, 0xE4A2, 0x8332, 0xE4A3, 0x8331, 0xE4A4, 0x8340, - 0xE4A5, 0x8339, 0xE4A6, 0x8350, 0xE4A7, 0x8345, 0xE4A8, 0x832F, 0xE4A9, 0x832B, 0xE4AA, 0x8317, 0xE4AB, 0x8318, 0xE4AC, 0x8385, - 0xE4AD, 0x839A, 0xE4AE, 0x83AA, 0xE4AF, 0x839F, 0xE4B0, 0x83A2, 0xE4B1, 0x8396, 0xE4B2, 0x8323, 0xE4B3, 0x838E, 0xE4B4, 0x8387, - 0xE4B5, 0x838A, 0xE4B6, 0x837C, 0xE4B7, 0x83B5, 0xE4B8, 0x8373, 0xE4B9, 0x8375, 0xE4BA, 0x83A0, 0xE4BB, 0x8389, 0xE4BC, 0x83A8, - 0xE4BD, 0x83F4, 0xE4BE, 0x8413, 0xE4BF, 0x83EB, 0xE4C0, 0x83CE, 0xE4C1, 0x83FD, 0xE4C2, 0x8403, 0xE4C3, 0x83D8, 0xE4C4, 0x840B, - 0xE4C5, 0x83C1, 0xE4C6, 0x83F7, 0xE4C7, 0x8407, 0xE4C8, 0x83E0, 0xE4C9, 0x83F2, 0xE4CA, 0x840D, 0xE4CB, 0x8422, 0xE4CC, 0x8420, - 0xE4CD, 0x83BD, 0xE4CE, 0x8438, 0xE4CF, 0x8506, 0xE4D0, 0x83FB, 0xE4D1, 0x846D, 0xE4D2, 0x842A, 0xE4D3, 0x843C, 0xE4D4, 0x855A, - 0xE4D5, 0x8484, 0xE4D6, 0x8477, 0xE4D7, 0x846B, 0xE4D8, 0x84AD, 0xE4D9, 0x846E, 0xE4DA, 0x8482, 0xE4DB, 0x8469, 0xE4DC, 0x8446, - 0xE4DD, 0x842C, 0xE4DE, 0x846F, 0xE4DF, 0x8479, 0xE4E0, 0x8435, 0xE4E1, 0x84CA, 0xE4E2, 0x8462, 0xE4E3, 0x84B9, 0xE4E4, 0x84BF, - 0xE4E5, 0x849F, 0xE4E6, 0x84D9, 0xE4E7, 0x84CD, 0xE4E8, 0x84BB, 0xE4E9, 0x84DA, 0xE4EA, 0x84D0, 0xE4EB, 0x84C1, 0xE4EC, 0x84C6, - 0xE4ED, 0x84D6, 0xE4EE, 0x84A1, 0xE4EF, 0x8521, 0xE4F0, 0x84FF, 0xE4F1, 0x84F4, 0xE4F2, 0x8517, 0xE4F3, 0x8518, 0xE4F4, 0x852C, - 0xE4F5, 0x851F, 0xE4F6, 0x8515, 0xE4F7, 0x8514, 0xE4F8, 0x84FC, 0xE4F9, 0x8540, 0xE4FA, 0x8563, 0xE4FB, 0x8558, 0xE4FC, 0x8548, - 0xE540, 0x8541, 0xE541, 0x8602, 0xE542, 0x854B, 0xE543, 0x8555, 0xE544, 0x8580, 0xE545, 0x85A4, 0xE546, 0x8588, 0xE547, 0x8591, - 0xE548, 0x858A, 0xE549, 0x85A8, 0xE54A, 0x856D, 0xE54B, 0x8594, 0xE54C, 0x859B, 0xE54D, 0x85EA, 0xE54E, 0x8587, 0xE54F, 0x859C, - 0xE550, 0x8577, 0xE551, 0x857E, 0xE552, 0x8590, 0xE553, 0x85C9, 0xE554, 0x85BA, 0xE555, 0x85CF, 0xE556, 0x85B9, 0xE557, 0x85D0, - 0xE558, 0x85D5, 0xE559, 0x85DD, 0xE55A, 0x85E5, 0xE55B, 0x85DC, 0xE55C, 0x85F9, 0xE55D, 0x860A, 0xE55E, 0x8613, 0xE55F, 0x860B, - 0xE560, 0x85FE, 0xE561, 0x85FA, 0xE562, 0x8606, 0xE563, 0x8622, 0xE564, 0x861A, 0xE565, 0x8630, 0xE566, 0x863F, 0xE567, 0x864D, - 0xE568, 0x4E55, 0xE569, 0x8654, 0xE56A, 0x865F, 0xE56B, 0x8667, 0xE56C, 0x8671, 0xE56D, 0x8693, 0xE56E, 0x86A3, 0xE56F, 0x86A9, - 0xE570, 0x86AA, 0xE571, 0x868B, 0xE572, 0x868C, 0xE573, 0x86B6, 0xE574, 0x86AF, 0xE575, 0x86C4, 0xE576, 0x86C6, 0xE577, 0x86B0, - 0xE578, 0x86C9, 0xE579, 0x8823, 0xE57A, 0x86AB, 0xE57B, 0x86D4, 0xE57C, 0x86DE, 0xE57D, 0x86E9, 0xE57E, 0x86EC, 0xE580, 0x86DF, - 0xE581, 0x86DB, 0xE582, 0x86EF, 0xE583, 0x8712, 0xE584, 0x8706, 0xE585, 0x8708, 0xE586, 0x8700, 0xE587, 0x8703, 0xE588, 0x86FB, - 0xE589, 0x8711, 0xE58A, 0x8709, 0xE58B, 0x870D, 0xE58C, 0x86F9, 0xE58D, 0x870A, 0xE58E, 0x8734, 0xE58F, 0x873F, 0xE590, 0x8737, - 0xE591, 0x873B, 0xE592, 0x8725, 0xE593, 0x8729, 0xE594, 0x871A, 0xE595, 0x8760, 0xE596, 0x875F, 0xE597, 0x8778, 0xE598, 0x874C, - 0xE599, 0x874E, 0xE59A, 0x8774, 0xE59B, 0x8757, 0xE59C, 0x8768, 0xE59D, 0x876E, 0xE59E, 0x8759, 0xE59F, 0x8753, 0xE5A0, 0x8763, - 0xE5A1, 0x876A, 0xE5A2, 0x8805, 0xE5A3, 0x87A2, 0xE5A4, 0x879F, 0xE5A5, 0x8782, 0xE5A6, 0x87AF, 0xE5A7, 0x87CB, 0xE5A8, 0x87BD, - 0xE5A9, 0x87C0, 0xE5AA, 0x87D0, 0xE5AB, 0x96D6, 0xE5AC, 0x87AB, 0xE5AD, 0x87C4, 0xE5AE, 0x87B3, 0xE5AF, 0x87C7, 0xE5B0, 0x87C6, - 0xE5B1, 0x87BB, 0xE5B2, 0x87EF, 0xE5B3, 0x87F2, 0xE5B4, 0x87E0, 0xE5B5, 0x880F, 0xE5B6, 0x880D, 0xE5B7, 0x87FE, 0xE5B8, 0x87F6, - 0xE5B9, 0x87F7, 0xE5BA, 0x880E, 0xE5BB, 0x87D2, 0xE5BC, 0x8811, 0xE5BD, 0x8816, 0xE5BE, 0x8815, 0xE5BF, 0x8822, 0xE5C0, 0x8821, - 0xE5C1, 0x8831, 0xE5C2, 0x8836, 0xE5C3, 0x8839, 0xE5C4, 0x8827, 0xE5C5, 0x883B, 0xE5C6, 0x8844, 0xE5C7, 0x8842, 0xE5C8, 0x8852, - 0xE5C9, 0x8859, 0xE5CA, 0x885E, 0xE5CB, 0x8862, 0xE5CC, 0x886B, 0xE5CD, 0x8881, 0xE5CE, 0x887E, 0xE5CF, 0x889E, 0xE5D0, 0x8875, - 0xE5D1, 0x887D, 0xE5D2, 0x88B5, 0xE5D3, 0x8872, 0xE5D4, 0x8882, 0xE5D5, 0x8897, 0xE5D6, 0x8892, 0xE5D7, 0x88AE, 0xE5D8, 0x8899, - 0xE5D9, 0x88A2, 0xE5DA, 0x888D, 0xE5DB, 0x88A4, 0xE5DC, 0x88B0, 0xE5DD, 0x88BF, 0xE5DE, 0x88B1, 0xE5DF, 0x88C3, 0xE5E0, 0x88C4, - 0xE5E1, 0x88D4, 0xE5E2, 0x88D8, 0xE5E3, 0x88D9, 0xE5E4, 0x88DD, 0xE5E5, 0x88F9, 0xE5E6, 0x8902, 0xE5E7, 0x88FC, 0xE5E8, 0x88F4, - 0xE5E9, 0x88E8, 0xE5EA, 0x88F2, 0xE5EB, 0x8904, 0xE5EC, 0x890C, 0xE5ED, 0x890A, 0xE5EE, 0x8913, 0xE5EF, 0x8943, 0xE5F0, 0x891E, - 0xE5F1, 0x8925, 0xE5F2, 0x892A, 0xE5F3, 0x892B, 0xE5F4, 0x8941, 0xE5F5, 0x8944, 0xE5F6, 0x893B, 0xE5F7, 0x8936, 0xE5F8, 0x8938, - 0xE5F9, 0x894C, 0xE5FA, 0x891D, 0xE5FB, 0x8960, 0xE5FC, 0x895E, 0xE640, 0x8966, 0xE641, 0x8964, 0xE642, 0x896D, 0xE643, 0x896A, - 0xE644, 0x896F, 0xE645, 0x8974, 0xE646, 0x8977, 0xE647, 0x897E, 0xE648, 0x8983, 0xE649, 0x8988, 0xE64A, 0x898A, 0xE64B, 0x8993, - 0xE64C, 0x8998, 0xE64D, 0x89A1, 0xE64E, 0x89A9, 0xE64F, 0x89A6, 0xE650, 0x89AC, 0xE651, 0x89AF, 0xE652, 0x89B2, 0xE653, 0x89BA, - 0xE654, 0x89BD, 0xE655, 0x89BF, 0xE656, 0x89C0, 0xE657, 0x89DA, 0xE658, 0x89DC, 0xE659, 0x89DD, 0xE65A, 0x89E7, 0xE65B, 0x89F4, - 0xE65C, 0x89F8, 0xE65D, 0x8A03, 0xE65E, 0x8A16, 0xE65F, 0x8A10, 0xE660, 0x8A0C, 0xE661, 0x8A1B, 0xE662, 0x8A1D, 0xE663, 0x8A25, - 0xE664, 0x8A36, 0xE665, 0x8A41, 0xE666, 0x8A5B, 0xE667, 0x8A52, 0xE668, 0x8A46, 0xE669, 0x8A48, 0xE66A, 0x8A7C, 0xE66B, 0x8A6D, - 0xE66C, 0x8A6C, 0xE66D, 0x8A62, 0xE66E, 0x8A85, 0xE66F, 0x8A82, 0xE670, 0x8A84, 0xE671, 0x8AA8, 0xE672, 0x8AA1, 0xE673, 0x8A91, - 0xE674, 0x8AA5, 0xE675, 0x8AA6, 0xE676, 0x8A9A, 0xE677, 0x8AA3, 0xE678, 0x8AC4, 0xE679, 0x8ACD, 0xE67A, 0x8AC2, 0xE67B, 0x8ADA, - 0xE67C, 0x8AEB, 0xE67D, 0x8AF3, 0xE67E, 0x8AE7, 0xE680, 0x8AE4, 0xE681, 0x8AF1, 0xE682, 0x8B14, 0xE683, 0x8AE0, 0xE684, 0x8AE2, - 0xE685, 0x8AF7, 0xE686, 0x8ADE, 0xE687, 0x8ADB, 0xE688, 0x8B0C, 0xE689, 0x8B07, 0xE68A, 0x8B1A, 0xE68B, 0x8AE1, 0xE68C, 0x8B16, - 0xE68D, 0x8B10, 0xE68E, 0x8B17, 0xE68F, 0x8B20, 0xE690, 0x8B33, 0xE691, 0x97AB, 0xE692, 0x8B26, 0xE693, 0x8B2B, 0xE694, 0x8B3E, - 0xE695, 0x8B28, 0xE696, 0x8B41, 0xE697, 0x8B4C, 0xE698, 0x8B4F, 0xE699, 0x8B4E, 0xE69A, 0x8B49, 0xE69B, 0x8B56, 0xE69C, 0x8B5B, - 0xE69D, 0x8B5A, 0xE69E, 0x8B6B, 0xE69F, 0x8B5F, 0xE6A0, 0x8B6C, 0xE6A1, 0x8B6F, 0xE6A2, 0x8B74, 0xE6A3, 0x8B7D, 0xE6A4, 0x8B80, - 0xE6A5, 0x8B8C, 0xE6A6, 0x8B8E, 0xE6A7, 0x8B92, 0xE6A8, 0x8B93, 0xE6A9, 0x8B96, 0xE6AA, 0x8B99, 0xE6AB, 0x8B9A, 0xE6AC, 0x8C3A, - 0xE6AD, 0x8C41, 0xE6AE, 0x8C3F, 0xE6AF, 0x8C48, 0xE6B0, 0x8C4C, 0xE6B1, 0x8C4E, 0xE6B2, 0x8C50, 0xE6B3, 0x8C55, 0xE6B4, 0x8C62, - 0xE6B5, 0x8C6C, 0xE6B6, 0x8C78, 0xE6B7, 0x8C7A, 0xE6B8, 0x8C82, 0xE6B9, 0x8C89, 0xE6BA, 0x8C85, 0xE6BB, 0x8C8A, 0xE6BC, 0x8C8D, - 0xE6BD, 0x8C8E, 0xE6BE, 0x8C94, 0xE6BF, 0x8C7C, 0xE6C0, 0x8C98, 0xE6C1, 0x621D, 0xE6C2, 0x8CAD, 0xE6C3, 0x8CAA, 0xE6C4, 0x8CBD, - 0xE6C5, 0x8CB2, 0xE6C6, 0x8CB3, 0xE6C7, 0x8CAE, 0xE6C8, 0x8CB6, 0xE6C9, 0x8CC8, 0xE6CA, 0x8CC1, 0xE6CB, 0x8CE4, 0xE6CC, 0x8CE3, - 0xE6CD, 0x8CDA, 0xE6CE, 0x8CFD, 0xE6CF, 0x8CFA, 0xE6D0, 0x8CFB, 0xE6D1, 0x8D04, 0xE6D2, 0x8D05, 0xE6D3, 0x8D0A, 0xE6D4, 0x8D07, - 0xE6D5, 0x8D0F, 0xE6D6, 0x8D0D, 0xE6D7, 0x8D10, 0xE6D8, 0x9F4E, 0xE6D9, 0x8D13, 0xE6DA, 0x8CCD, 0xE6DB, 0x8D14, 0xE6DC, 0x8D16, - 0xE6DD, 0x8D67, 0xE6DE, 0x8D6D, 0xE6DF, 0x8D71, 0xE6E0, 0x8D73, 0xE6E1, 0x8D81, 0xE6E2, 0x8D99, 0xE6E3, 0x8DC2, 0xE6E4, 0x8DBE, - 0xE6E5, 0x8DBA, 0xE6E6, 0x8DCF, 0xE6E7, 0x8DDA, 0xE6E8, 0x8DD6, 0xE6E9, 0x8DCC, 0xE6EA, 0x8DDB, 0xE6EB, 0x8DCB, 0xE6EC, 0x8DEA, - 0xE6ED, 0x8DEB, 0xE6EE, 0x8DDF, 0xE6EF, 0x8DE3, 0xE6F0, 0x8DFC, 0xE6F1, 0x8E08, 0xE6F2, 0x8E09, 0xE6F3, 0x8DFF, 0xE6F4, 0x8E1D, - 0xE6F5, 0x8E1E, 0xE6F6, 0x8E10, 0xE6F7, 0x8E1F, 0xE6F8, 0x8E42, 0xE6F9, 0x8E35, 0xE6FA, 0x8E30, 0xE6FB, 0x8E34, 0xE6FC, 0x8E4A, - 0xE740, 0x8E47, 0xE741, 0x8E49, 0xE742, 0x8E4C, 0xE743, 0x8E50, 0xE744, 0x8E48, 0xE745, 0x8E59, 0xE746, 0x8E64, 0xE747, 0x8E60, - 0xE748, 0x8E2A, 0xE749, 0x8E63, 0xE74A, 0x8E55, 0xE74B, 0x8E76, 0xE74C, 0x8E72, 0xE74D, 0x8E7C, 0xE74E, 0x8E81, 0xE74F, 0x8E87, - 0xE750, 0x8E85, 0xE751, 0x8E84, 0xE752, 0x8E8B, 0xE753, 0x8E8A, 0xE754, 0x8E93, 0xE755, 0x8E91, 0xE756, 0x8E94, 0xE757, 0x8E99, - 0xE758, 0x8EAA, 0xE759, 0x8EA1, 0xE75A, 0x8EAC, 0xE75B, 0x8EB0, 0xE75C, 0x8EC6, 0xE75D, 0x8EB1, 0xE75E, 0x8EBE, 0xE75F, 0x8EC5, - 0xE760, 0x8EC8, 0xE761, 0x8ECB, 0xE762, 0x8EDB, 0xE763, 0x8EE3, 0xE764, 0x8EFC, 0xE765, 0x8EFB, 0xE766, 0x8EEB, 0xE767, 0x8EFE, - 0xE768, 0x8F0A, 0xE769, 0x8F05, 0xE76A, 0x8F15, 0xE76B, 0x8F12, 0xE76C, 0x8F19, 0xE76D, 0x8F13, 0xE76E, 0x8F1C, 0xE76F, 0x8F1F, - 0xE770, 0x8F1B, 0xE771, 0x8F0C, 0xE772, 0x8F26, 0xE773, 0x8F33, 0xE774, 0x8F3B, 0xE775, 0x8F39, 0xE776, 0x8F45, 0xE777, 0x8F42, - 0xE778, 0x8F3E, 0xE779, 0x8F4C, 0xE77A, 0x8F49, 0xE77B, 0x8F46, 0xE77C, 0x8F4E, 0xE77D, 0x8F57, 0xE77E, 0x8F5C, 0xE780, 0x8F62, - 0xE781, 0x8F63, 0xE782, 0x8F64, 0xE783, 0x8F9C, 0xE784, 0x8F9F, 0xE785, 0x8FA3, 0xE786, 0x8FAD, 0xE787, 0x8FAF, 0xE788, 0x8FB7, - 0xE789, 0x8FDA, 0xE78A, 0x8FE5, 0xE78B, 0x8FE2, 0xE78C, 0x8FEA, 0xE78D, 0x8FEF, 0xE78E, 0x9087, 0xE78F, 0x8FF4, 0xE790, 0x9005, - 0xE791, 0x8FF9, 0xE792, 0x8FFA, 0xE793, 0x9011, 0xE794, 0x9015, 0xE795, 0x9021, 0xE796, 0x900D, 0xE797, 0x901E, 0xE798, 0x9016, - 0xE799, 0x900B, 0xE79A, 0x9027, 0xE79B, 0x9036, 0xE79C, 0x9035, 0xE79D, 0x9039, 0xE79E, 0x8FF8, 0xE79F, 0x904F, 0xE7A0, 0x9050, - 0xE7A1, 0x9051, 0xE7A2, 0x9052, 0xE7A3, 0x900E, 0xE7A4, 0x9049, 0xE7A5, 0x903E, 0xE7A6, 0x9056, 0xE7A7, 0x9058, 0xE7A8, 0x905E, - 0xE7A9, 0x9068, 0xE7AA, 0x906F, 0xE7AB, 0x9076, 0xE7AC, 0x96A8, 0xE7AD, 0x9072, 0xE7AE, 0x9082, 0xE7AF, 0x907D, 0xE7B0, 0x9081, - 0xE7B1, 0x9080, 0xE7B2, 0x908A, 0xE7B3, 0x9089, 0xE7B4, 0x908F, 0xE7B5, 0x90A8, 0xE7B6, 0x90AF, 0xE7B7, 0x90B1, 0xE7B8, 0x90B5, - 0xE7B9, 0x90E2, 0xE7BA, 0x90E4, 0xE7BB, 0x6248, 0xE7BC, 0x90DB, 0xE7BD, 0x9102, 0xE7BE, 0x9112, 0xE7BF, 0x9119, 0xE7C0, 0x9132, - 0xE7C1, 0x9130, 0xE7C2, 0x914A, 0xE7C3, 0x9156, 0xE7C4, 0x9158, 0xE7C5, 0x9163, 0xE7C6, 0x9165, 0xE7C7, 0x9169, 0xE7C8, 0x9173, - 0xE7C9, 0x9172, 0xE7CA, 0x918B, 0xE7CB, 0x9189, 0xE7CC, 0x9182, 0xE7CD, 0x91A2, 0xE7CE, 0x91AB, 0xE7CF, 0x91AF, 0xE7D0, 0x91AA, - 0xE7D1, 0x91B5, 0xE7D2, 0x91B4, 0xE7D3, 0x91BA, 0xE7D4, 0x91C0, 0xE7D5, 0x91C1, 0xE7D6, 0x91C9, 0xE7D7, 0x91CB, 0xE7D8, 0x91D0, - 0xE7D9, 0x91D6, 0xE7DA, 0x91DF, 0xE7DB, 0x91E1, 0xE7DC, 0x91DB, 0xE7DD, 0x91FC, 0xE7DE, 0x91F5, 0xE7DF, 0x91F6, 0xE7E0, 0x921E, - 0xE7E1, 0x91FF, 0xE7E2, 0x9214, 0xE7E3, 0x922C, 0xE7E4, 0x9215, 0xE7E5, 0x9211, 0xE7E6, 0x925E, 0xE7E7, 0x9257, 0xE7E8, 0x9245, - 0xE7E9, 0x9249, 0xE7EA, 0x9264, 0xE7EB, 0x9248, 0xE7EC, 0x9295, 0xE7ED, 0x923F, 0xE7EE, 0x924B, 0xE7EF, 0x9250, 0xE7F0, 0x929C, - 0xE7F1, 0x9296, 0xE7F2, 0x9293, 0xE7F3, 0x929B, 0xE7F4, 0x925A, 0xE7F5, 0x92CF, 0xE7F6, 0x92B9, 0xE7F7, 0x92B7, 0xE7F8, 0x92E9, - 0xE7F9, 0x930F, 0xE7FA, 0x92FA, 0xE7FB, 0x9344, 0xE7FC, 0x932E, 0xE840, 0x9319, 0xE841, 0x9322, 0xE842, 0x931A, 0xE843, 0x9323, - 0xE844, 0x933A, 0xE845, 0x9335, 0xE846, 0x933B, 0xE847, 0x935C, 0xE848, 0x9360, 0xE849, 0x937C, 0xE84A, 0x936E, 0xE84B, 0x9356, - 0xE84C, 0x93B0, 0xE84D, 0x93AC, 0xE84E, 0x93AD, 0xE84F, 0x9394, 0xE850, 0x93B9, 0xE851, 0x93D6, 0xE852, 0x93D7, 0xE853, 0x93E8, - 0xE854, 0x93E5, 0xE855, 0x93D8, 0xE856, 0x93C3, 0xE857, 0x93DD, 0xE858, 0x93D0, 0xE859, 0x93C8, 0xE85A, 0x93E4, 0xE85B, 0x941A, - 0xE85C, 0x9414, 0xE85D, 0x9413, 0xE85E, 0x9403, 0xE85F, 0x9407, 0xE860, 0x9410, 0xE861, 0x9436, 0xE862, 0x942B, 0xE863, 0x9435, - 0xE864, 0x9421, 0xE865, 0x943A, 0xE866, 0x9441, 0xE867, 0x9452, 0xE868, 0x9444, 0xE869, 0x945B, 0xE86A, 0x9460, 0xE86B, 0x9462, - 0xE86C, 0x945E, 0xE86D, 0x946A, 0xE86E, 0x9229, 0xE86F, 0x9470, 0xE870, 0x9475, 0xE871, 0x9477, 0xE872, 0x947D, 0xE873, 0x945A, - 0xE874, 0x947C, 0xE875, 0x947E, 0xE876, 0x9481, 0xE877, 0x947F, 0xE878, 0x9582, 0xE879, 0x9587, 0xE87A, 0x958A, 0xE87B, 0x9594, - 0xE87C, 0x9596, 0xE87D, 0x9598, 0xE87E, 0x9599, 0xE880, 0x95A0, 0xE881, 0x95A8, 0xE882, 0x95A7, 0xE883, 0x95AD, 0xE884, 0x95BC, - 0xE885, 0x95BB, 0xE886, 0x95B9, 0xE887, 0x95BE, 0xE888, 0x95CA, 0xE889, 0x6FF6, 0xE88A, 0x95C3, 0xE88B, 0x95CD, 0xE88C, 0x95CC, - 0xE88D, 0x95D5, 0xE88E, 0x95D4, 0xE88F, 0x95D6, 0xE890, 0x95DC, 0xE891, 0x95E1, 0xE892, 0x95E5, 0xE893, 0x95E2, 0xE894, 0x9621, - 0xE895, 0x9628, 0xE896, 0x962E, 0xE897, 0x962F, 0xE898, 0x9642, 0xE899, 0x964C, 0xE89A, 0x964F, 0xE89B, 0x964B, 0xE89C, 0x9677, - 0xE89D, 0x965C, 0xE89E, 0x965E, 0xE89F, 0x965D, 0xE8A0, 0x965F, 0xE8A1, 0x9666, 0xE8A2, 0x9672, 0xE8A3, 0x966C, 0xE8A4, 0x968D, - 0xE8A5, 0x9698, 0xE8A6, 0x9695, 0xE8A7, 0x9697, 0xE8A8, 0x96AA, 0xE8A9, 0x96A7, 0xE8AA, 0x96B1, 0xE8AB, 0x96B2, 0xE8AC, 0x96B0, - 0xE8AD, 0x96B4, 0xE8AE, 0x96B6, 0xE8AF, 0x96B8, 0xE8B0, 0x96B9, 0xE8B1, 0x96CE, 0xE8B2, 0x96CB, 0xE8B3, 0x96C9, 0xE8B4, 0x96CD, - 0xE8B5, 0x894D, 0xE8B6, 0x96DC, 0xE8B7, 0x970D, 0xE8B8, 0x96D5, 0xE8B9, 0x96F9, 0xE8BA, 0x9704, 0xE8BB, 0x9706, 0xE8BC, 0x9708, - 0xE8BD, 0x9713, 0xE8BE, 0x970E, 0xE8BF, 0x9711, 0xE8C0, 0x970F, 0xE8C1, 0x9716, 0xE8C2, 0x9719, 0xE8C3, 0x9724, 0xE8C4, 0x972A, - 0xE8C5, 0x9730, 0xE8C6, 0x9739, 0xE8C7, 0x973D, 0xE8C8, 0x973E, 0xE8C9, 0x9744, 0xE8CA, 0x9746, 0xE8CB, 0x9748, 0xE8CC, 0x9742, - 0xE8CD, 0x9749, 0xE8CE, 0x975C, 0xE8CF, 0x9760, 0xE8D0, 0x9764, 0xE8D1, 0x9766, 0xE8D2, 0x9768, 0xE8D3, 0x52D2, 0xE8D4, 0x976B, - 0xE8D5, 0x9771, 0xE8D6, 0x9779, 0xE8D7, 0x9785, 0xE8D8, 0x977C, 0xE8D9, 0x9781, 0xE8DA, 0x977A, 0xE8DB, 0x9786, 0xE8DC, 0x978B, - 0xE8DD, 0x978F, 0xE8DE, 0x9790, 0xE8DF, 0x979C, 0xE8E0, 0x97A8, 0xE8E1, 0x97A6, 0xE8E2, 0x97A3, 0xE8E3, 0x97B3, 0xE8E4, 0x97B4, - 0xE8E5, 0x97C3, 0xE8E6, 0x97C6, 0xE8E7, 0x97C8, 0xE8E8, 0x97CB, 0xE8E9, 0x97DC, 0xE8EA, 0x97ED, 0xE8EB, 0x9F4F, 0xE8EC, 0x97F2, - 0xE8ED, 0x7ADF, 0xE8EE, 0x97F6, 0xE8EF, 0x97F5, 0xE8F0, 0x980F, 0xE8F1, 0x980C, 0xE8F2, 0x9838, 0xE8F3, 0x9824, 0xE8F4, 0x9821, - 0xE8F5, 0x9837, 0xE8F6, 0x983D, 0xE8F7, 0x9846, 0xE8F8, 0x984F, 0xE8F9, 0x984B, 0xE8FA, 0x986B, 0xE8FB, 0x986F, 0xE8FC, 0x9870, - 0xE940, 0x9871, 0xE941, 0x9874, 0xE942, 0x9873, 0xE943, 0x98AA, 0xE944, 0x98AF, 0xE945, 0x98B1, 0xE946, 0x98B6, 0xE947, 0x98C4, - 0xE948, 0x98C3, 0xE949, 0x98C6, 0xE94A, 0x98E9, 0xE94B, 0x98EB, 0xE94C, 0x9903, 0xE94D, 0x9909, 0xE94E, 0x9912, 0xE94F, 0x9914, - 0xE950, 0x9918, 0xE951, 0x9921, 0xE952, 0x991D, 0xE953, 0x991E, 0xE954, 0x9924, 0xE955, 0x9920, 0xE956, 0x992C, 0xE957, 0x992E, - 0xE958, 0x993D, 0xE959, 0x993E, 0xE95A, 0x9942, 0xE95B, 0x9949, 0xE95C, 0x9945, 0xE95D, 0x9950, 0xE95E, 0x994B, 0xE95F, 0x9951, - 0xE960, 0x9952, 0xE961, 0x994C, 0xE962, 0x9955, 0xE963, 0x9997, 0xE964, 0x9998, 0xE965, 0x99A5, 0xE966, 0x99AD, 0xE967, 0x99AE, - 0xE968, 0x99BC, 0xE969, 0x99DF, 0xE96A, 0x99DB, 0xE96B, 0x99DD, 0xE96C, 0x99D8, 0xE96D, 0x99D1, 0xE96E, 0x99ED, 0xE96F, 0x99EE, - 0xE970, 0x99F1, 0xE971, 0x99F2, 0xE972, 0x99FB, 0xE973, 0x99F8, 0xE974, 0x9A01, 0xE975, 0x9A0F, 0xE976, 0x9A05, 0xE977, 0x99E2, - 0xE978, 0x9A19, 0xE979, 0x9A2B, 0xE97A, 0x9A37, 0xE97B, 0x9A45, 0xE97C, 0x9A42, 0xE97D, 0x9A40, 0xE97E, 0x9A43, 0xE980, 0x9A3E, - 0xE981, 0x9A55, 0xE982, 0x9A4D, 0xE983, 0x9A5B, 0xE984, 0x9A57, 0xE985, 0x9A5F, 0xE986, 0x9A62, 0xE987, 0x9A65, 0xE988, 0x9A64, - 0xE989, 0x9A69, 0xE98A, 0x9A6B, 0xE98B, 0x9A6A, 0xE98C, 0x9AAD, 0xE98D, 0x9AB0, 0xE98E, 0x9ABC, 0xE98F, 0x9AC0, 0xE990, 0x9ACF, - 0xE991, 0x9AD1, 0xE992, 0x9AD3, 0xE993, 0x9AD4, 0xE994, 0x9ADE, 0xE995, 0x9ADF, 0xE996, 0x9AE2, 0xE997, 0x9AE3, 0xE998, 0x9AE6, - 0xE999, 0x9AEF, 0xE99A, 0x9AEB, 0xE99B, 0x9AEE, 0xE99C, 0x9AF4, 0xE99D, 0x9AF1, 0xE99E, 0x9AF7, 0xE99F, 0x9AFB, 0xE9A0, 0x9B06, - 0xE9A1, 0x9B18, 0xE9A2, 0x9B1A, 0xE9A3, 0x9B1F, 0xE9A4, 0x9B22, 0xE9A5, 0x9B23, 0xE9A6, 0x9B25, 0xE9A7, 0x9B27, 0xE9A8, 0x9B28, - 0xE9A9, 0x9B29, 0xE9AA, 0x9B2A, 0xE9AB, 0x9B2E, 0xE9AC, 0x9B2F, 0xE9AD, 0x9B32, 0xE9AE, 0x9B44, 0xE9AF, 0x9B43, 0xE9B0, 0x9B4F, - 0xE9B1, 0x9B4D, 0xE9B2, 0x9B4E, 0xE9B3, 0x9B51, 0xE9B4, 0x9B58, 0xE9B5, 0x9B74, 0xE9B6, 0x9B93, 0xE9B7, 0x9B83, 0xE9B8, 0x9B91, - 0xE9B9, 0x9B96, 0xE9BA, 0x9B97, 0xE9BB, 0x9B9F, 0xE9BC, 0x9BA0, 0xE9BD, 0x9BA8, 0xE9BE, 0x9BB4, 0xE9BF, 0x9BC0, 0xE9C0, 0x9BCA, - 0xE9C1, 0x9BB9, 0xE9C2, 0x9BC6, 0xE9C3, 0x9BCF, 0xE9C4, 0x9BD1, 0xE9C5, 0x9BD2, 0xE9C6, 0x9BE3, 0xE9C7, 0x9BE2, 0xE9C8, 0x9BE4, - 0xE9C9, 0x9BD4, 0xE9CA, 0x9BE1, 0xE9CB, 0x9C3A, 0xE9CC, 0x9BF2, 0xE9CD, 0x9BF1, 0xE9CE, 0x9BF0, 0xE9CF, 0x9C15, 0xE9D0, 0x9C14, - 0xE9D1, 0x9C09, 0xE9D2, 0x9C13, 0xE9D3, 0x9C0C, 0xE9D4, 0x9C06, 0xE9D5, 0x9C08, 0xE9D6, 0x9C12, 0xE9D7, 0x9C0A, 0xE9D8, 0x9C04, - 0xE9D9, 0x9C2E, 0xE9DA, 0x9C1B, 0xE9DB, 0x9C25, 0xE9DC, 0x9C24, 0xE9DD, 0x9C21, 0xE9DE, 0x9C30, 0xE9DF, 0x9C47, 0xE9E0, 0x9C32, - 0xE9E1, 0x9C46, 0xE9E2, 0x9C3E, 0xE9E3, 0x9C5A, 0xE9E4, 0x9C60, 0xE9E5, 0x9C67, 0xE9E6, 0x9C76, 0xE9E7, 0x9C78, 0xE9E8, 0x9CE7, - 0xE9E9, 0x9CEC, 0xE9EA, 0x9CF0, 0xE9EB, 0x9D09, 0xE9EC, 0x9D08, 0xE9ED, 0x9CEB, 0xE9EE, 0x9D03, 0xE9EF, 0x9D06, 0xE9F0, 0x9D2A, - 0xE9F1, 0x9D26, 0xE9F2, 0x9DAF, 0xE9F3, 0x9D23, 0xE9F4, 0x9D1F, 0xE9F5, 0x9D44, 0xE9F6, 0x9D15, 0xE9F7, 0x9D12, 0xE9F8, 0x9D41, - 0xE9F9, 0x9D3F, 0xE9FA, 0x9D3E, 0xE9FB, 0x9D46, 0xE9FC, 0x9D48, 0xEA40, 0x9D5D, 0xEA41, 0x9D5E, 0xEA42, 0x9D64, 0xEA43, 0x9D51, - 0xEA44, 0x9D50, 0xEA45, 0x9D59, 0xEA46, 0x9D72, 0xEA47, 0x9D89, 0xEA48, 0x9D87, 0xEA49, 0x9DAB, 0xEA4A, 0x9D6F, 0xEA4B, 0x9D7A, - 0xEA4C, 0x9D9A, 0xEA4D, 0x9DA4, 0xEA4E, 0x9DA9, 0xEA4F, 0x9DB2, 0xEA50, 0x9DC4, 0xEA51, 0x9DC1, 0xEA52, 0x9DBB, 0xEA53, 0x9DB8, - 0xEA54, 0x9DBA, 0xEA55, 0x9DC6, 0xEA56, 0x9DCF, 0xEA57, 0x9DC2, 0xEA58, 0x9DD9, 0xEA59, 0x9DD3, 0xEA5A, 0x9DF8, 0xEA5B, 0x9DE6, - 0xEA5C, 0x9DED, 0xEA5D, 0x9DEF, 0xEA5E, 0x9DFD, 0xEA5F, 0x9E1A, 0xEA60, 0x9E1B, 0xEA61, 0x9E1E, 0xEA62, 0x9E75, 0xEA63, 0x9E79, - 0xEA64, 0x9E7D, 0xEA65, 0x9E81, 0xEA66, 0x9E88, 0xEA67, 0x9E8B, 0xEA68, 0x9E8C, 0xEA69, 0x9E92, 0xEA6A, 0x9E95, 0xEA6B, 0x9E91, - 0xEA6C, 0x9E9D, 0xEA6D, 0x9EA5, 0xEA6E, 0x9EA9, 0xEA6F, 0x9EB8, 0xEA70, 0x9EAA, 0xEA71, 0x9EAD, 0xEA72, 0x9761, 0xEA73, 0x9ECC, - 0xEA74, 0x9ECE, 0xEA75, 0x9ECF, 0xEA76, 0x9ED0, 0xEA77, 0x9ED4, 0xEA78, 0x9EDC, 0xEA79, 0x9EDE, 0xEA7A, 0x9EDD, 0xEA7B, 0x9EE0, - 0xEA7C, 0x9EE5, 0xEA7D, 0x9EE8, 0xEA7E, 0x9EEF, 0xEA80, 0x9EF4, 0xEA81, 0x9EF6, 0xEA82, 0x9EF7, 0xEA83, 0x9EF9, 0xEA84, 0x9EFB, - 0xEA85, 0x9EFC, 0xEA86, 0x9EFD, 0xEA87, 0x9F07, 0xEA88, 0x9F08, 0xEA89, 0x76B7, 0xEA8A, 0x9F15, 0xEA8B, 0x9F21, 0xEA8C, 0x9F2C, - 0xEA8D, 0x9F3E, 0xEA8E, 0x9F4A, 0xEA8F, 0x9F52, 0xEA90, 0x9F54, 0xEA91, 0x9F63, 0xEA92, 0x9F5F, 0xEA93, 0x9F60, 0xEA94, 0x9F61, - 0xEA95, 0x9F66, 0xEA96, 0x9F67, 0xEA97, 0x9F6C, 0xEA98, 0x9F6A, 0xEA99, 0x9F77, 0xEA9A, 0x9F72, 0xEA9B, 0x9F76, 0xEA9C, 0x9F95, - 0xEA9D, 0x9F9C, 0xEA9E, 0x9FA0, 0xEA9F, 0x582F, 0xEAA0, 0x69C7, 0xEAA1, 0x9059, 0xEAA2, 0x7464, 0xEAA3, 0x51DC, 0xEAA4, 0x7199, - 0xFA40, 0x2170, 0xFA41, 0x2171, 0xFA42, 0x2172, 0xFA43, 0x2173, 0xFA44, 0x2174, 0xFA45, 0x2175, 0xFA46, 0x2176, 0xFA47, 0x2177, - 0xFA48, 0x2178, 0xFA49, 0x2179, 0xFA55, 0xFFE4, 0xFA56, 0xFF07, 0xFA57, 0xFF02, 0xFA5C, 0x7E8A, 0xFA5D, 0x891C, 0xFA5E, 0x9348, - 0xFA5F, 0x9288, 0xFA60, 0x84DC, 0xFA61, 0x4FC9, 0xFA62, 0x70BB, 0xFA63, 0x6631, 0xFA64, 0x68C8, 0xFA65, 0x92F9, 0xFA66, 0x66FB, - 0xFA67, 0x5F45, 0xFA68, 0x4E28, 0xFA69, 0x4EE1, 0xFA6A, 0x4EFC, 0xFA6B, 0x4F00, 0xFA6C, 0x4F03, 0xFA6D, 0x4F39, 0xFA6E, 0x4F56, - 0xFA6F, 0x4F92, 0xFA70, 0x4F8A, 0xFA71, 0x4F9A, 0xFA72, 0x4F94, 0xFA73, 0x4FCD, 0xFA74, 0x5040, 0xFA75, 0x5022, 0xFA76, 0x4FFF, - 0xFA77, 0x501E, 0xFA78, 0x5046, 0xFA79, 0x5070, 0xFA7A, 0x5042, 0xFA7B, 0x5094, 0xFA7C, 0x50F4, 0xFA7D, 0x50D8, 0xFA7E, 0x514A, - 0xFA80, 0x5164, 0xFA81, 0x519D, 0xFA82, 0x51BE, 0xFA83, 0x51EC, 0xFA84, 0x5215, 0xFA85, 0x529C, 0xFA86, 0x52A6, 0xFA87, 0x52C0, - 0xFA88, 0x52DB, 0xFA89, 0x5300, 0xFA8A, 0x5307, 0xFA8B, 0x5324, 0xFA8C, 0x5372, 0xFA8D, 0x5393, 0xFA8E, 0x53B2, 0xFA8F, 0x53DD, - 0xFA90, 0xFA0E, 0xFA91, 0x549C, 0xFA92, 0x548A, 0xFA93, 0x54A9, 0xFA94, 0x54FF, 0xFA95, 0x5586, 0xFA96, 0x5759, 0xFA97, 0x5765, - 0xFA98, 0x57AC, 0xFA99, 0x57C8, 0xFA9A, 0x57C7, 0xFA9B, 0xFA0F, 0xFA9C, 0xFA10, 0xFA9D, 0x589E, 0xFA9E, 0x58B2, 0xFA9F, 0x590B, - 0xFAA0, 0x5953, 0xFAA1, 0x595B, 0xFAA2, 0x595D, 0xFAA3, 0x5963, 0xFAA4, 0x59A4, 0xFAA5, 0x59BA, 0xFAA6, 0x5B56, 0xFAA7, 0x5BC0, - 0xFAA8, 0x752F, 0xFAA9, 0x5BD8, 0xFAAA, 0x5BEC, 0xFAAB, 0x5C1E, 0xFAAC, 0x5CA6, 0xFAAD, 0x5CBA, 0xFAAE, 0x5CF5, 0xFAAF, 0x5D27, - 0xFAB0, 0x5D53, 0xFAB1, 0xFA11, 0xFAB2, 0x5D42, 0xFAB3, 0x5D6D, 0xFAB4, 0x5DB8, 0xFAB5, 0x5DB9, 0xFAB6, 0x5DD0, 0xFAB7, 0x5F21, - 0xFAB8, 0x5F34, 0xFAB9, 0x5F67, 0xFABA, 0x5FB7, 0xFABB, 0x5FDE, 0xFABC, 0x605D, 0xFABD, 0x6085, 0xFABE, 0x608A, 0xFABF, 0x60DE, - 0xFAC0, 0x60D5, 0xFAC1, 0x6120, 0xFAC2, 0x60F2, 0xFAC3, 0x6111, 0xFAC4, 0x6137, 0xFAC5, 0x6130, 0xFAC6, 0x6198, 0xFAC7, 0x6213, - 0xFAC8, 0x62A6, 0xFAC9, 0x63F5, 0xFACA, 0x6460, 0xFACB, 0x649D, 0xFACC, 0x64CE, 0xFACD, 0x654E, 0xFACE, 0x6600, 0xFACF, 0x6615, - 0xFAD0, 0x663B, 0xFAD1, 0x6609, 0xFAD2, 0x662E, 0xFAD3, 0x661E, 0xFAD4, 0x6624, 0xFAD5, 0x6665, 0xFAD6, 0x6657, 0xFAD7, 0x6659, - 0xFAD8, 0xFA12, 0xFAD9, 0x6673, 0xFADA, 0x6699, 0xFADB, 0x66A0, 0xFADC, 0x66B2, 0xFADD, 0x66BF, 0xFADE, 0x66FA, 0xFADF, 0x670E, - 0xFAE0, 0xF929, 0xFAE1, 0x6766, 0xFAE2, 0x67BB, 0xFAE3, 0x6852, 0xFAE4, 0x67C0, 0xFAE5, 0x6801, 0xFAE6, 0x6844, 0xFAE7, 0x68CF, - 0xFAE8, 0xFA13, 0xFAE9, 0x6968, 0xFAEA, 0xFA14, 0xFAEB, 0x6998, 0xFAEC, 0x69E2, 0xFAED, 0x6A30, 0xFAEE, 0x6A6B, 0xFAEF, 0x6A46, - 0xFAF0, 0x6A73, 0xFAF1, 0x6A7E, 0xFAF2, 0x6AE2, 0xFAF3, 0x6AE4, 0xFAF4, 0x6BD6, 0xFAF5, 0x6C3F, 0xFAF6, 0x6C5C, 0xFAF7, 0x6C86, - 0xFAF8, 0x6C6F, 0xFAF9, 0x6CDA, 0xFAFA, 0x6D04, 0xFAFB, 0x6D87, 0xFAFC, 0x6D6F, 0xFB40, 0x6D96, 0xFB41, 0x6DAC, 0xFB42, 0x6DCF, - 0xFB43, 0x6DF8, 0xFB44, 0x6DF2, 0xFB45, 0x6DFC, 0xFB46, 0x6E39, 0xFB47, 0x6E5C, 0xFB48, 0x6E27, 0xFB49, 0x6E3C, 0xFB4A, 0x6EBF, - 0xFB4B, 0x6F88, 0xFB4C, 0x6FB5, 0xFB4D, 0x6FF5, 0xFB4E, 0x7005, 0xFB4F, 0x7007, 0xFB50, 0x7028, 0xFB51, 0x7085, 0xFB52, 0x70AB, - 0xFB53, 0x710F, 0xFB54, 0x7104, 0xFB55, 0x715C, 0xFB56, 0x7146, 0xFB57, 0x7147, 0xFB58, 0xFA15, 0xFB59, 0x71C1, 0xFB5A, 0x71FE, - 0xFB5B, 0x72B1, 0xFB5C, 0x72BE, 0xFB5D, 0x7324, 0xFB5E, 0xFA16, 0xFB5F, 0x7377, 0xFB60, 0x73BD, 0xFB61, 0x73C9, 0xFB62, 0x73D6, - 0xFB63, 0x73E3, 0xFB64, 0x73D2, 0xFB65, 0x7407, 0xFB66, 0x73F5, 0xFB67, 0x7426, 0xFB68, 0x742A, 0xFB69, 0x7429, 0xFB6A, 0x742E, - 0xFB6B, 0x7462, 0xFB6C, 0x7489, 0xFB6D, 0x749F, 0xFB6E, 0x7501, 0xFB6F, 0x756F, 0xFB70, 0x7682, 0xFB71, 0x769C, 0xFB72, 0x769E, - 0xFB73, 0x769B, 0xFB74, 0x76A6, 0xFB75, 0xFA17, 0xFB76, 0x7746, 0xFB77, 0x52AF, 0xFB78, 0x7821, 0xFB79, 0x784E, 0xFB7A, 0x7864, - 0xFB7B, 0x787A, 0xFB7C, 0x7930, 0xFB7D, 0xFA18, 0xFB7E, 0xFA19, 0xFB80, 0xFA1A, 0xFB81, 0x7994, 0xFB82, 0xFA1B, 0xFB83, 0x799B, - 0xFB84, 0x7AD1, 0xFB85, 0x7AE7, 0xFB86, 0xFA1C, 0xFB87, 0x7AEB, 0xFB88, 0x7B9E, 0xFB89, 0xFA1D, 0xFB8A, 0x7D48, 0xFB8B, 0x7D5C, - 0xFB8C, 0x7DB7, 0xFB8D, 0x7DA0, 0xFB8E, 0x7DD6, 0xFB8F, 0x7E52, 0xFB90, 0x7F47, 0xFB91, 0x7FA1, 0xFB92, 0xFA1E, 0xFB93, 0x8301, - 0xFB94, 0x8362, 0xFB95, 0x837F, 0xFB96, 0x83C7, 0xFB97, 0x83F6, 0xFB98, 0x8448, 0xFB99, 0x84B4, 0xFB9A, 0x8553, 0xFB9B, 0x8559, - 0xFB9C, 0x856B, 0xFB9D, 0xFA1F, 0xFB9E, 0x85B0, 0xFB9F, 0xFA20, 0xFBA0, 0xFA21, 0xFBA1, 0x8807, 0xFBA2, 0x88F5, 0xFBA3, 0x8A12, - 0xFBA4, 0x8A37, 0xFBA5, 0x8A79, 0xFBA6, 0x8AA7, 0xFBA7, 0x8ABE, 0xFBA8, 0x8ADF, 0xFBA9, 0xFA22, 0xFBAA, 0x8AF6, 0xFBAB, 0x8B53, - 0xFBAC, 0x8B7F, 0xFBAD, 0x8CF0, 0xFBAE, 0x8CF4, 0xFBAF, 0x8D12, 0xFBB0, 0x8D76, 0xFBB1, 0xFA23, 0xFBB2, 0x8ECF, 0xFBB3, 0xFA24, - 0xFBB4, 0xFA25, 0xFBB5, 0x9067, 0xFBB6, 0x90DE, 0xFBB7, 0xFA26, 0xFBB8, 0x9115, 0xFBB9, 0x9127, 0xFBBA, 0x91DA, 0xFBBB, 0x91D7, - 0xFBBC, 0x91DE, 0xFBBD, 0x91ED, 0xFBBE, 0x91EE, 0xFBBF, 0x91E4, 0xFBC0, 0x91E5, 0xFBC1, 0x9206, 0xFBC2, 0x9210, 0xFBC3, 0x920A, - 0xFBC4, 0x923A, 0xFBC5, 0x9240, 0xFBC6, 0x923C, 0xFBC7, 0x924E, 0xFBC8, 0x9259, 0xFBC9, 0x9251, 0xFBCA, 0x9239, 0xFBCB, 0x9267, - 0xFBCC, 0x92A7, 0xFBCD, 0x9277, 0xFBCE, 0x9278, 0xFBCF, 0x92E7, 0xFBD0, 0x92D7, 0xFBD1, 0x92D9, 0xFBD2, 0x92D0, 0xFBD3, 0xFA27, - 0xFBD4, 0x92D5, 0xFBD5, 0x92E0, 0xFBD6, 0x92D3, 0xFBD7, 0x9325, 0xFBD8, 0x9321, 0xFBD9, 0x92FB, 0xFBDA, 0xFA28, 0xFBDB, 0x931E, - 0xFBDC, 0x92FF, 0xFBDD, 0x931D, 0xFBDE, 0x9302, 0xFBDF, 0x9370, 0xFBE0, 0x9357, 0xFBE1, 0x93A4, 0xFBE2, 0x93C6, 0xFBE3, 0x93DE, - 0xFBE4, 0x93F8, 0xFBE5, 0x9431, 0xFBE6, 0x9445, 0xFBE7, 0x9448, 0xFBE8, 0x9592, 0xFBE9, 0xF9DC, 0xFBEA, 0xFA29, 0xFBEB, 0x969D, - 0xFBEC, 0x96AF, 0xFBED, 0x9733, 0xFBEE, 0x973B, 0xFBEF, 0x9743, 0xFBF0, 0x974D, 0xFBF1, 0x974F, 0xFBF2, 0x9751, 0xFBF3, 0x9755, - 0xFBF4, 0x9857, 0xFBF5, 0x9865, 0xFBF6, 0xFA2A, 0xFBF7, 0xFA2B, 0xFBF8, 0x9927, 0xFBF9, 0xFA2C, 0xFBFA, 0x999E, 0xFBFB, 0x9A4E, - 0xFBFC, 0x9AD9, 0xFC40, 0x9ADC, 0xFC41, 0x9B75, 0xFC42, 0x9B72, 0xFC43, 0x9B8F, 0xFC44, 0x9BB1, 0xFC45, 0x9BBB, 0xFC46, 0x9C00, - 0xFC47, 0x9D70, 0xFC48, 0x9D6B, 0xFC49, 0xFA2D, 0xFC4A, 0x9E19, 0xFC4B, 0x9ED1, 0, 0 -}; -#endif - -#if FF_CODE_PAGE == 936 || FF_CODE_PAGE == 0 /* Simplified Chinese */ -static const WCHAR uni2oem936[] = { /* Unicode --> GBK pairs */ - 0x00A4, 0xA1E8, 0x00A7, 0xA1EC, 0x00A8, 0xA1A7, 0x00B0, 0xA1E3, 0x00B1, 0xA1C0, 0x00B7, 0xA1A4, 0x00D7, 0xA1C1, 0x00E0, 0xA8A4, - 0x00E1, 0xA8A2, 0x00E8, 0xA8A8, 0x00E9, 0xA8A6, 0x00EA, 0xA8BA, 0x00EC, 0xA8AC, 0x00ED, 0xA8AA, 0x00F2, 0xA8B0, 0x00F3, 0xA8AE, - 0x00F7, 0xA1C2, 0x00F9, 0xA8B4, 0x00FA, 0xA8B2, 0x00FC, 0xA8B9, 0x0101, 0xA8A1, 0x0113, 0xA8A5, 0x011B, 0xA8A7, 0x012B, 0xA8A9, - 0x0144, 0xA8BD, 0x0148, 0xA8BE, 0x014D, 0xA8AD, 0x016B, 0xA8B1, 0x01CE, 0xA8A3, 0x01D0, 0xA8AB, 0x01D2, 0xA8AF, 0x01D4, 0xA8B3, - 0x01D6, 0xA8B5, 0x01D8, 0xA8B6, 0x01DA, 0xA8B7, 0x01DC, 0xA8B8, 0x0251, 0xA8BB, 0x0261, 0xA8C0, 0x02C7, 0xA1A6, 0x02C9, 0xA1A5, - 0x02CA, 0xA840, 0x02CB, 0xA841, 0x02D9, 0xA842, 0x0391, 0xA6A1, 0x0392, 0xA6A2, 0x0393, 0xA6A3, 0x0394, 0xA6A4, 0x0395, 0xA6A5, - 0x0396, 0xA6A6, 0x0397, 0xA6A7, 0x0398, 0xA6A8, 0x0399, 0xA6A9, 0x039A, 0xA6AA, 0x039B, 0xA6AB, 0x039C, 0xA6AC, 0x039D, 0xA6AD, - 0x039E, 0xA6AE, 0x039F, 0xA6AF, 0x03A0, 0xA6B0, 0x03A1, 0xA6B1, 0x03A3, 0xA6B2, 0x03A4, 0xA6B3, 0x03A5, 0xA6B4, 0x03A6, 0xA6B5, - 0x03A7, 0xA6B6, 0x03A8, 0xA6B7, 0x03A9, 0xA6B8, 0x03B1, 0xA6C1, 0x03B2, 0xA6C2, 0x03B3, 0xA6C3, 0x03B4, 0xA6C4, 0x03B5, 0xA6C5, - 0x03B6, 0xA6C6, 0x03B7, 0xA6C7, 0x03B8, 0xA6C8, 0x03B9, 0xA6C9, 0x03BA, 0xA6CA, 0x03BB, 0xA6CB, 0x03BC, 0xA6CC, 0x03BD, 0xA6CD, - 0x03BE, 0xA6CE, 0x03BF, 0xA6CF, 0x03C0, 0xA6D0, 0x03C1, 0xA6D1, 0x03C3, 0xA6D2, 0x03C4, 0xA6D3, 0x03C5, 0xA6D4, 0x03C6, 0xA6D5, - 0x03C7, 0xA6D6, 0x03C8, 0xA6D7, 0x03C9, 0xA6D8, 0x0401, 0xA7A7, 0x0410, 0xA7A1, 0x0411, 0xA7A2, 0x0412, 0xA7A3, 0x0413, 0xA7A4, - 0x0414, 0xA7A5, 0x0415, 0xA7A6, 0x0416, 0xA7A8, 0x0417, 0xA7A9, 0x0418, 0xA7AA, 0x0419, 0xA7AB, 0x041A, 0xA7AC, 0x041B, 0xA7AD, - 0x041C, 0xA7AE, 0x041D, 0xA7AF, 0x041E, 0xA7B0, 0x041F, 0xA7B1, 0x0420, 0xA7B2, 0x0421, 0xA7B3, 0x0422, 0xA7B4, 0x0423, 0xA7B5, - 0x0424, 0xA7B6, 0x0425, 0xA7B7, 0x0426, 0xA7B8, 0x0427, 0xA7B9, 0x0428, 0xA7BA, 0x0429, 0xA7BB, 0x042A, 0xA7BC, 0x042B, 0xA7BD, - 0x042C, 0xA7BE, 0x042D, 0xA7BF, 0x042E, 0xA7C0, 0x042F, 0xA7C1, 0x0430, 0xA7D1, 0x0431, 0xA7D2, 0x0432, 0xA7D3, 0x0433, 0xA7D4, - 0x0434, 0xA7D5, 0x0435, 0xA7D6, 0x0436, 0xA7D8, 0x0437, 0xA7D9, 0x0438, 0xA7DA, 0x0439, 0xA7DB, 0x043A, 0xA7DC, 0x043B, 0xA7DD, - 0x043C, 0xA7DE, 0x043D, 0xA7DF, 0x043E, 0xA7E0, 0x043F, 0xA7E1, 0x0440, 0xA7E2, 0x0441, 0xA7E3, 0x0442, 0xA7E4, 0x0443, 0xA7E5, - 0x0444, 0xA7E6, 0x0445, 0xA7E7, 0x0446, 0xA7E8, 0x0447, 0xA7E9, 0x0448, 0xA7EA, 0x0449, 0xA7EB, 0x044A, 0xA7EC, 0x044B, 0xA7ED, - 0x044C, 0xA7EE, 0x044D, 0xA7EF, 0x044E, 0xA7F0, 0x044F, 0xA7F1, 0x0451, 0xA7D7, 0x2010, 0xA95C, 0x2013, 0xA843, 0x2014, 0xA1AA, - 0x2015, 0xA844, 0x2016, 0xA1AC, 0x2018, 0xA1AE, 0x2019, 0xA1AF, 0x201C, 0xA1B0, 0x201D, 0xA1B1, 0x2025, 0xA845, 0x2026, 0xA1AD, - 0x2030, 0xA1EB, 0x2032, 0xA1E4, 0x2033, 0xA1E5, 0x2035, 0xA846, 0x203B, 0xA1F9, 0x20AC, 0x0080, 0x2103, 0xA1E6, 0x2105, 0xA847, - 0x2109, 0xA848, 0x2116, 0xA1ED, 0x2121, 0xA959, 0x2160, 0xA2F1, 0x2161, 0xA2F2, 0x2162, 0xA2F3, 0x2163, 0xA2F4, 0x2164, 0xA2F5, - 0x2165, 0xA2F6, 0x2166, 0xA2F7, 0x2167, 0xA2F8, 0x2168, 0xA2F9, 0x2169, 0xA2FA, 0x216A, 0xA2FB, 0x216B, 0xA2FC, 0x2170, 0xA2A1, - 0x2171, 0xA2A2, 0x2172, 0xA2A3, 0x2173, 0xA2A4, 0x2174, 0xA2A5, 0x2175, 0xA2A6, 0x2176, 0xA2A7, 0x2177, 0xA2A8, 0x2178, 0xA2A9, - 0x2179, 0xA2AA, 0x2190, 0xA1FB, 0x2191, 0xA1FC, 0x2192, 0xA1FA, 0x2193, 0xA1FD, 0x2196, 0xA849, 0x2197, 0xA84A, 0x2198, 0xA84B, - 0x2199, 0xA84C, 0x2208, 0xA1CA, 0x220F, 0xA1C7, 0x2211, 0xA1C6, 0x2215, 0xA84D, 0x221A, 0xA1CC, 0x221D, 0xA1D8, 0x221E, 0xA1DE, - 0x221F, 0xA84E, 0x2220, 0xA1CF, 0x2223, 0xA84F, 0x2225, 0xA1CE, 0x2227, 0xA1C4, 0x2228, 0xA1C5, 0x2229, 0xA1C9, 0x222A, 0xA1C8, - 0x222B, 0xA1D2, 0x222E, 0xA1D3, 0x2234, 0xA1E0, 0x2235, 0xA1DF, 0x2236, 0xA1C3, 0x2237, 0xA1CB, 0x223D, 0xA1D7, 0x2248, 0xA1D6, - 0x224C, 0xA1D5, 0x2252, 0xA850, 0x2260, 0xA1D9, 0x2261, 0xA1D4, 0x2264, 0xA1DC, 0x2265, 0xA1DD, 0x2266, 0xA851, 0x2267, 0xA852, - 0x226E, 0xA1DA, 0x226F, 0xA1DB, 0x2295, 0xA892, 0x2299, 0xA1D1, 0x22A5, 0xA1CD, 0x22BF, 0xA853, 0x2312, 0xA1D0, 0x2460, 0xA2D9, - 0x2461, 0xA2DA, 0x2462, 0xA2DB, 0x2463, 0xA2DC, 0x2464, 0xA2DD, 0x2465, 0xA2DE, 0x2466, 0xA2DF, 0x2467, 0xA2E0, 0x2468, 0xA2E1, - 0x2469, 0xA2E2, 0x2474, 0xA2C5, 0x2475, 0xA2C6, 0x2476, 0xA2C7, 0x2477, 0xA2C8, 0x2478, 0xA2C9, 0x2479, 0xA2CA, 0x247A, 0xA2CB, - 0x247B, 0xA2CC, 0x247C, 0xA2CD, 0x247D, 0xA2CE, 0x247E, 0xA2CF, 0x247F, 0xA2D0, 0x2480, 0xA2D1, 0x2481, 0xA2D2, 0x2482, 0xA2D3, - 0x2483, 0xA2D4, 0x2484, 0xA2D5, 0x2485, 0xA2D6, 0x2486, 0xA2D7, 0x2487, 0xA2D8, 0x2488, 0xA2B1, 0x2489, 0xA2B2, 0x248A, 0xA2B3, - 0x248B, 0xA2B4, 0x248C, 0xA2B5, 0x248D, 0xA2B6, 0x248E, 0xA2B7, 0x248F, 0xA2B8, 0x2490, 0xA2B9, 0x2491, 0xA2BA, 0x2492, 0xA2BB, - 0x2493, 0xA2BC, 0x2494, 0xA2BD, 0x2495, 0xA2BE, 0x2496, 0xA2BF, 0x2497, 0xA2C0, 0x2498, 0xA2C1, 0x2499, 0xA2C2, 0x249A, 0xA2C3, - 0x249B, 0xA2C4, 0x2500, 0xA9A4, 0x2501, 0xA9A5, 0x2502, 0xA9A6, 0x2503, 0xA9A7, 0x2504, 0xA9A8, 0x2505, 0xA9A9, 0x2506, 0xA9AA, - 0x2507, 0xA9AB, 0x2508, 0xA9AC, 0x2509, 0xA9AD, 0x250A, 0xA9AE, 0x250B, 0xA9AF, 0x250C, 0xA9B0, 0x250D, 0xA9B1, 0x250E, 0xA9B2, - 0x250F, 0xA9B3, 0x2510, 0xA9B4, 0x2511, 0xA9B5, 0x2512, 0xA9B6, 0x2513, 0xA9B7, 0x2514, 0xA9B8, 0x2515, 0xA9B9, 0x2516, 0xA9BA, - 0x2517, 0xA9BB, 0x2518, 0xA9BC, 0x2519, 0xA9BD, 0x251A, 0xA9BE, 0x251B, 0xA9BF, 0x251C, 0xA9C0, 0x251D, 0xA9C1, 0x251E, 0xA9C2, - 0x251F, 0xA9C3, 0x2520, 0xA9C4, 0x2521, 0xA9C5, 0x2522, 0xA9C6, 0x2523, 0xA9C7, 0x2524, 0xA9C8, 0x2525, 0xA9C9, 0x2526, 0xA9CA, - 0x2527, 0xA9CB, 0x2528, 0xA9CC, 0x2529, 0xA9CD, 0x252A, 0xA9CE, 0x252B, 0xA9CF, 0x252C, 0xA9D0, 0x252D, 0xA9D1, 0x252E, 0xA9D2, - 0x252F, 0xA9D3, 0x2530, 0xA9D4, 0x2531, 0xA9D5, 0x2532, 0xA9D6, 0x2533, 0xA9D7, 0x2534, 0xA9D8, 0x2535, 0xA9D9, 0x2536, 0xA9DA, - 0x2537, 0xA9DB, 0x2538, 0xA9DC, 0x2539, 0xA9DD, 0x253A, 0xA9DE, 0x253B, 0xA9DF, 0x253C, 0xA9E0, 0x253D, 0xA9E1, 0x253E, 0xA9E2, - 0x253F, 0xA9E3, 0x2540, 0xA9E4, 0x2541, 0xA9E5, 0x2542, 0xA9E6, 0x2543, 0xA9E7, 0x2544, 0xA9E8, 0x2545, 0xA9E9, 0x2546, 0xA9EA, - 0x2547, 0xA9EB, 0x2548, 0xA9EC, 0x2549, 0xA9ED, 0x254A, 0xA9EE, 0x254B, 0xA9EF, 0x2550, 0xA854, 0x2551, 0xA855, 0x2552, 0xA856, - 0x2553, 0xA857, 0x2554, 0xA858, 0x2555, 0xA859, 0x2556, 0xA85A, 0x2557, 0xA85B, 0x2558, 0xA85C, 0x2559, 0xA85D, 0x255A, 0xA85E, - 0x255B, 0xA85F, 0x255C, 0xA860, 0x255D, 0xA861, 0x255E, 0xA862, 0x255F, 0xA863, 0x2560, 0xA864, 0x2561, 0xA865, 0x2562, 0xA866, - 0x2563, 0xA867, 0x2564, 0xA868, 0x2565, 0xA869, 0x2566, 0xA86A, 0x2567, 0xA86B, 0x2568, 0xA86C, 0x2569, 0xA86D, 0x256A, 0xA86E, - 0x256B, 0xA86F, 0x256C, 0xA870, 0x256D, 0xA871, 0x256E, 0xA872, 0x256F, 0xA873, 0x2570, 0xA874, 0x2571, 0xA875, 0x2572, 0xA876, - 0x2573, 0xA877, 0x2581, 0xA878, 0x2582, 0xA879, 0x2583, 0xA87A, 0x2584, 0xA87B, 0x2585, 0xA87C, 0x2586, 0xA87D, 0x2587, 0xA87E, - 0x2588, 0xA880, 0x2589, 0xA881, 0x258A, 0xA882, 0x258B, 0xA883, 0x258C, 0xA884, 0x258D, 0xA885, 0x258E, 0xA886, 0x258F, 0xA887, - 0x2593, 0xA888, 0x2594, 0xA889, 0x2595, 0xA88A, 0x25A0, 0xA1F6, 0x25A1, 0xA1F5, 0x25B2, 0xA1F8, 0x25B3, 0xA1F7, 0x25BC, 0xA88B, - 0x25BD, 0xA88C, 0x25C6, 0xA1F4, 0x25C7, 0xA1F3, 0x25CB, 0xA1F0, 0x25CE, 0xA1F2, 0x25CF, 0xA1F1, 0x25E2, 0xA88D, 0x25E3, 0xA88E, - 0x25E4, 0xA88F, 0x25E5, 0xA890, 0x2605, 0xA1EF, 0x2606, 0xA1EE, 0x2609, 0xA891, 0x2640, 0xA1E2, 0x2642, 0xA1E1, 0x3000, 0xA1A1, - 0x3001, 0xA1A2, 0x3002, 0xA1A3, 0x3003, 0xA1A8, 0x3005, 0xA1A9, 0x3006, 0xA965, 0x3007, 0xA996, 0x3008, 0xA1B4, 0x3009, 0xA1B5, - 0x300A, 0xA1B6, 0x300B, 0xA1B7, 0x300C, 0xA1B8, 0x300D, 0xA1B9, 0x300E, 0xA1BA, 0x300F, 0xA1BB, 0x3010, 0xA1BE, 0x3011, 0xA1BF, - 0x3012, 0xA893, 0x3013, 0xA1FE, 0x3014, 0xA1B2, 0x3015, 0xA1B3, 0x3016, 0xA1BC, 0x3017, 0xA1BD, 0x301D, 0xA894, 0x301E, 0xA895, - 0x3021, 0xA940, 0x3022, 0xA941, 0x3023, 0xA942, 0x3024, 0xA943, 0x3025, 0xA944, 0x3026, 0xA945, 0x3027, 0xA946, 0x3028, 0xA947, - 0x3029, 0xA948, 0x3041, 0xA4A1, 0x3042, 0xA4A2, 0x3043, 0xA4A3, 0x3044, 0xA4A4, 0x3045, 0xA4A5, 0x3046, 0xA4A6, 0x3047, 0xA4A7, - 0x3048, 0xA4A8, 0x3049, 0xA4A9, 0x304A, 0xA4AA, 0x304B, 0xA4AB, 0x304C, 0xA4AC, 0x304D, 0xA4AD, 0x304E, 0xA4AE, 0x304F, 0xA4AF, - 0x3050, 0xA4B0, 0x3051, 0xA4B1, 0x3052, 0xA4B2, 0x3053, 0xA4B3, 0x3054, 0xA4B4, 0x3055, 0xA4B5, 0x3056, 0xA4B6, 0x3057, 0xA4B7, - 0x3058, 0xA4B8, 0x3059, 0xA4B9, 0x305A, 0xA4BA, 0x305B, 0xA4BB, 0x305C, 0xA4BC, 0x305D, 0xA4BD, 0x305E, 0xA4BE, 0x305F, 0xA4BF, - 0x3060, 0xA4C0, 0x3061, 0xA4C1, 0x3062, 0xA4C2, 0x3063, 0xA4C3, 0x3064, 0xA4C4, 0x3065, 0xA4C5, 0x3066, 0xA4C6, 0x3067, 0xA4C7, - 0x3068, 0xA4C8, 0x3069, 0xA4C9, 0x306A, 0xA4CA, 0x306B, 0xA4CB, 0x306C, 0xA4CC, 0x306D, 0xA4CD, 0x306E, 0xA4CE, 0x306F, 0xA4CF, - 0x3070, 0xA4D0, 0x3071, 0xA4D1, 0x3072, 0xA4D2, 0x3073, 0xA4D3, 0x3074, 0xA4D4, 0x3075, 0xA4D5, 0x3076, 0xA4D6, 0x3077, 0xA4D7, - 0x3078, 0xA4D8, 0x3079, 0xA4D9, 0x307A, 0xA4DA, 0x307B, 0xA4DB, 0x307C, 0xA4DC, 0x307D, 0xA4DD, 0x307E, 0xA4DE, 0x307F, 0xA4DF, - 0x3080, 0xA4E0, 0x3081, 0xA4E1, 0x3082, 0xA4E2, 0x3083, 0xA4E3, 0x3084, 0xA4E4, 0x3085, 0xA4E5, 0x3086, 0xA4E6, 0x3087, 0xA4E7, - 0x3088, 0xA4E8, 0x3089, 0xA4E9, 0x308A, 0xA4EA, 0x308B, 0xA4EB, 0x308C, 0xA4EC, 0x308D, 0xA4ED, 0x308E, 0xA4EE, 0x308F, 0xA4EF, - 0x3090, 0xA4F0, 0x3091, 0xA4F1, 0x3092, 0xA4F2, 0x3093, 0xA4F3, 0x309B, 0xA961, 0x309C, 0xA962, 0x309D, 0xA966, 0x309E, 0xA967, - 0x30A1, 0xA5A1, 0x30A2, 0xA5A2, 0x30A3, 0xA5A3, 0x30A4, 0xA5A4, 0x30A5, 0xA5A5, 0x30A6, 0xA5A6, 0x30A7, 0xA5A7, 0x30A8, 0xA5A8, - 0x30A9, 0xA5A9, 0x30AA, 0xA5AA, 0x30AB, 0xA5AB, 0x30AC, 0xA5AC, 0x30AD, 0xA5AD, 0x30AE, 0xA5AE, 0x30AF, 0xA5AF, 0x30B0, 0xA5B0, - 0x30B1, 0xA5B1, 0x30B2, 0xA5B2, 0x30B3, 0xA5B3, 0x30B4, 0xA5B4, 0x30B5, 0xA5B5, 0x30B6, 0xA5B6, 0x30B7, 0xA5B7, 0x30B8, 0xA5B8, - 0x30B9, 0xA5B9, 0x30BA, 0xA5BA, 0x30BB, 0xA5BB, 0x30BC, 0xA5BC, 0x30BD, 0xA5BD, 0x30BE, 0xA5BE, 0x30BF, 0xA5BF, 0x30C0, 0xA5C0, - 0x30C1, 0xA5C1, 0x30C2, 0xA5C2, 0x30C3, 0xA5C3, 0x30C4, 0xA5C4, 0x30C5, 0xA5C5, 0x30C6, 0xA5C6, 0x30C7, 0xA5C7, 0x30C8, 0xA5C8, - 0x30C9, 0xA5C9, 0x30CA, 0xA5CA, 0x30CB, 0xA5CB, 0x30CC, 0xA5CC, 0x30CD, 0xA5CD, 0x30CE, 0xA5CE, 0x30CF, 0xA5CF, 0x30D0, 0xA5D0, - 0x30D1, 0xA5D1, 0x30D2, 0xA5D2, 0x30D3, 0xA5D3, 0x30D4, 0xA5D4, 0x30D5, 0xA5D5, 0x30D6, 0xA5D6, 0x30D7, 0xA5D7, 0x30D8, 0xA5D8, - 0x30D9, 0xA5D9, 0x30DA, 0xA5DA, 0x30DB, 0xA5DB, 0x30DC, 0xA5DC, 0x30DD, 0xA5DD, 0x30DE, 0xA5DE, 0x30DF, 0xA5DF, 0x30E0, 0xA5E0, - 0x30E1, 0xA5E1, 0x30E2, 0xA5E2, 0x30E3, 0xA5E3, 0x30E4, 0xA5E4, 0x30E5, 0xA5E5, 0x30E6, 0xA5E6, 0x30E7, 0xA5E7, 0x30E8, 0xA5E8, - 0x30E9, 0xA5E9, 0x30EA, 0xA5EA, 0x30EB, 0xA5EB, 0x30EC, 0xA5EC, 0x30ED, 0xA5ED, 0x30EE, 0xA5EE, 0x30EF, 0xA5EF, 0x30F0, 0xA5F0, - 0x30F1, 0xA5F1, 0x30F2, 0xA5F2, 0x30F3, 0xA5F3, 0x30F4, 0xA5F4, 0x30F5, 0xA5F5, 0x30F6, 0xA5F6, 0x30FC, 0xA960, 0x30FD, 0xA963, - 0x30FE, 0xA964, 0x3105, 0xA8C5, 0x3106, 0xA8C6, 0x3107, 0xA8C7, 0x3108, 0xA8C8, 0x3109, 0xA8C9, 0x310A, 0xA8CA, 0x310B, 0xA8CB, - 0x310C, 0xA8CC, 0x310D, 0xA8CD, 0x310E, 0xA8CE, 0x310F, 0xA8CF, 0x3110, 0xA8D0, 0x3111, 0xA8D1, 0x3112, 0xA8D2, 0x3113, 0xA8D3, - 0x3114, 0xA8D4, 0x3115, 0xA8D5, 0x3116, 0xA8D6, 0x3117, 0xA8D7, 0x3118, 0xA8D8, 0x3119, 0xA8D9, 0x311A, 0xA8DA, 0x311B, 0xA8DB, - 0x311C, 0xA8DC, 0x311D, 0xA8DD, 0x311E, 0xA8DE, 0x311F, 0xA8DF, 0x3120, 0xA8E0, 0x3121, 0xA8E1, 0x3122, 0xA8E2, 0x3123, 0xA8E3, - 0x3124, 0xA8E4, 0x3125, 0xA8E5, 0x3126, 0xA8E6, 0x3127, 0xA8E7, 0x3128, 0xA8E8, 0x3129, 0xA8E9, 0x3220, 0xA2E5, 0x3221, 0xA2E6, - 0x3222, 0xA2E7, 0x3223, 0xA2E8, 0x3224, 0xA2E9, 0x3225, 0xA2EA, 0x3226, 0xA2EB, 0x3227, 0xA2EC, 0x3228, 0xA2ED, 0x3229, 0xA2EE, - 0x3231, 0xA95A, 0x32A3, 0xA949, 0x338E, 0xA94A, 0x338F, 0xA94B, 0x339C, 0xA94C, 0x339D, 0xA94D, 0x339E, 0xA94E, 0x33A1, 0xA94F, - 0x33C4, 0xA950, 0x33CE, 0xA951, 0x33D1, 0xA952, 0x33D2, 0xA953, 0x33D5, 0xA954, 0x4E00, 0xD2BB, 0x4E01, 0xB6A1, 0x4E02, 0x8140, - 0x4E03, 0xC6DF, 0x4E04, 0x8141, 0x4E05, 0x8142, 0x4E06, 0x8143, 0x4E07, 0xCDF2, 0x4E08, 0xD5C9, 0x4E09, 0xC8FD, 0x4E0A, 0xC9CF, - 0x4E0B, 0xCFC2, 0x4E0C, 0xD8A2, 0x4E0D, 0xB2BB, 0x4E0E, 0xD3EB, 0x4E0F, 0x8144, 0x4E10, 0xD8A4, 0x4E11, 0xB3F3, 0x4E12, 0x8145, - 0x4E13, 0xD7A8, 0x4E14, 0xC7D2, 0x4E15, 0xD8A7, 0x4E16, 0xCAC0, 0x4E17, 0x8146, 0x4E18, 0xC7F0, 0x4E19, 0xB1FB, 0x4E1A, 0xD2B5, - 0x4E1B, 0xB4D4, 0x4E1C, 0xB6AB, 0x4E1D, 0xCBBF, 0x4E1E, 0xD8A9, 0x4E1F, 0x8147, 0x4E20, 0x8148, 0x4E21, 0x8149, 0x4E22, 0xB6AA, - 0x4E23, 0x814A, 0x4E24, 0xC1BD, 0x4E25, 0xD1CF, 0x4E26, 0x814B, 0x4E27, 0xC9A5, 0x4E28, 0xD8AD, 0x4E29, 0x814C, 0x4E2A, 0xB8F6, - 0x4E2B, 0xD1BE, 0x4E2C, 0xE3DC, 0x4E2D, 0xD6D0, 0x4E2E, 0x814D, 0x4E2F, 0x814E, 0x4E30, 0xB7E1, 0x4E31, 0x814F, 0x4E32, 0xB4AE, - 0x4E33, 0x8150, 0x4E34, 0xC1D9, 0x4E35, 0x8151, 0x4E36, 0xD8BC, 0x4E37, 0x8152, 0x4E38, 0xCDE8, 0x4E39, 0xB5A4, 0x4E3A, 0xCEAA, - 0x4E3B, 0xD6F7, 0x4E3C, 0x8153, 0x4E3D, 0xC0F6, 0x4E3E, 0xBED9, 0x4E3F, 0xD8AF, 0x4E40, 0x8154, 0x4E41, 0x8155, 0x4E42, 0x8156, - 0x4E43, 0xC4CB, 0x4E44, 0x8157, 0x4E45, 0xBEC3, 0x4E46, 0x8158, 0x4E47, 0xD8B1, 0x4E48, 0xC3B4, 0x4E49, 0xD2E5, 0x4E4A, 0x8159, - 0x4E4B, 0xD6AE, 0x4E4C, 0xCEDA, 0x4E4D, 0xD5A7, 0x4E4E, 0xBAF5, 0x4E4F, 0xB7A6, 0x4E50, 0xC0D6, 0x4E51, 0x815A, 0x4E52, 0xC6B9, - 0x4E53, 0xC5D2, 0x4E54, 0xC7C7, 0x4E55, 0x815B, 0x4E56, 0xB9D4, 0x4E57, 0x815C, 0x4E58, 0xB3CB, 0x4E59, 0xD2D2, 0x4E5A, 0x815D, - 0x4E5B, 0x815E, 0x4E5C, 0xD8BF, 0x4E5D, 0xBEC5, 0x4E5E, 0xC6F2, 0x4E5F, 0xD2B2, 0x4E60, 0xCFB0, 0x4E61, 0xCFE7, 0x4E62, 0x815F, - 0x4E63, 0x8160, 0x4E64, 0x8161, 0x4E65, 0x8162, 0x4E66, 0xCAE9, 0x4E67, 0x8163, 0x4E68, 0x8164, 0x4E69, 0xD8C0, 0x4E6A, 0x8165, - 0x4E6B, 0x8166, 0x4E6C, 0x8167, 0x4E6D, 0x8168, 0x4E6E, 0x8169, 0x4E6F, 0x816A, 0x4E70, 0xC2F2, 0x4E71, 0xC2D2, 0x4E72, 0x816B, - 0x4E73, 0xC8E9, 0x4E74, 0x816C, 0x4E75, 0x816D, 0x4E76, 0x816E, 0x4E77, 0x816F, 0x4E78, 0x8170, 0x4E79, 0x8171, 0x4E7A, 0x8172, - 0x4E7B, 0x8173, 0x4E7C, 0x8174, 0x4E7D, 0x8175, 0x4E7E, 0xC7AC, 0x4E7F, 0x8176, 0x4E80, 0x8177, 0x4E81, 0x8178, 0x4E82, 0x8179, - 0x4E83, 0x817A, 0x4E84, 0x817B, 0x4E85, 0x817C, 0x4E86, 0xC1CB, 0x4E87, 0x817D, 0x4E88, 0xD3E8, 0x4E89, 0xD5F9, 0x4E8A, 0x817E, - 0x4E8B, 0xCAC2, 0x4E8C, 0xB6FE, 0x4E8D, 0xD8A1, 0x4E8E, 0xD3DA, 0x4E8F, 0xBFF7, 0x4E90, 0x8180, 0x4E91, 0xD4C6, 0x4E92, 0xBBA5, - 0x4E93, 0xD8C1, 0x4E94, 0xCEE5, 0x4E95, 0xBEAE, 0x4E96, 0x8181, 0x4E97, 0x8182, 0x4E98, 0xD8A8, 0x4E99, 0x8183, 0x4E9A, 0xD1C7, - 0x4E9B, 0xD0A9, 0x4E9C, 0x8184, 0x4E9D, 0x8185, 0x4E9E, 0x8186, 0x4E9F, 0xD8BD, 0x4EA0, 0xD9EF, 0x4EA1, 0xCDF6, 0x4EA2, 0xBFBA, - 0x4EA3, 0x8187, 0x4EA4, 0xBDBB, 0x4EA5, 0xBAA5, 0x4EA6, 0xD2E0, 0x4EA7, 0xB2FA, 0x4EA8, 0xBAE0, 0x4EA9, 0xC4B6, 0x4EAA, 0x8188, - 0x4EAB, 0xCFED, 0x4EAC, 0xBEA9, 0x4EAD, 0xCDA4, 0x4EAE, 0xC1C1, 0x4EAF, 0x8189, 0x4EB0, 0x818A, 0x4EB1, 0x818B, 0x4EB2, 0xC7D7, - 0x4EB3, 0xD9F1, 0x4EB4, 0x818C, 0x4EB5, 0xD9F4, 0x4EB6, 0x818D, 0x4EB7, 0x818E, 0x4EB8, 0x818F, 0x4EB9, 0x8190, 0x4EBA, 0xC8CB, - 0x4EBB, 0xD8E9, 0x4EBC, 0x8191, 0x4EBD, 0x8192, 0x4EBE, 0x8193, 0x4EBF, 0xD2DA, 0x4EC0, 0xCAB2, 0x4EC1, 0xC8CA, 0x4EC2, 0xD8EC, - 0x4EC3, 0xD8EA, 0x4EC4, 0xD8C6, 0x4EC5, 0xBDF6, 0x4EC6, 0xC6CD, 0x4EC7, 0xB3F0, 0x4EC8, 0x8194, 0x4EC9, 0xD8EB, 0x4ECA, 0xBDF1, - 0x4ECB, 0xBDE9, 0x4ECC, 0x8195, 0x4ECD, 0xC8D4, 0x4ECE, 0xB4D3, 0x4ECF, 0x8196, 0x4ED0, 0x8197, 0x4ED1, 0xC2D8, 0x4ED2, 0x8198, - 0x4ED3, 0xB2D6, 0x4ED4, 0xD7D0, 0x4ED5, 0xCACB, 0x4ED6, 0xCBFB, 0x4ED7, 0xD5CC, 0x4ED8, 0xB8B6, 0x4ED9, 0xCFC9, 0x4EDA, 0x8199, - 0x4EDB, 0x819A, 0x4EDC, 0x819B, 0x4EDD, 0xD9DA, 0x4EDE, 0xD8F0, 0x4EDF, 0xC7AA, 0x4EE0, 0x819C, 0x4EE1, 0xD8EE, 0x4EE2, 0x819D, - 0x4EE3, 0xB4FA, 0x4EE4, 0xC1EE, 0x4EE5, 0xD2D4, 0x4EE6, 0x819E, 0x4EE7, 0x819F, 0x4EE8, 0xD8ED, 0x4EE9, 0x81A0, 0x4EEA, 0xD2C7, - 0x4EEB, 0xD8EF, 0x4EEC, 0xC3C7, 0x4EED, 0x81A1, 0x4EEE, 0x81A2, 0x4EEF, 0x81A3, 0x4EF0, 0xD1F6, 0x4EF1, 0x81A4, 0x4EF2, 0xD6D9, - 0x4EF3, 0xD8F2, 0x4EF4, 0x81A5, 0x4EF5, 0xD8F5, 0x4EF6, 0xBCFE, 0x4EF7, 0xBCDB, 0x4EF8, 0x81A6, 0x4EF9, 0x81A7, 0x4EFA, 0x81A8, - 0x4EFB, 0xC8CE, 0x4EFC, 0x81A9, 0x4EFD, 0xB7DD, 0x4EFE, 0x81AA, 0x4EFF, 0xB7C2, 0x4F00, 0x81AB, 0x4F01, 0xC6F3, 0x4F02, 0x81AC, - 0x4F03, 0x81AD, 0x4F04, 0x81AE, 0x4F05, 0x81AF, 0x4F06, 0x81B0, 0x4F07, 0x81B1, 0x4F08, 0x81B2, 0x4F09, 0xD8F8, 0x4F0A, 0xD2C1, - 0x4F0B, 0x81B3, 0x4F0C, 0x81B4, 0x4F0D, 0xCEE9, 0x4F0E, 0xBCBF, 0x4F0F, 0xB7FC, 0x4F10, 0xB7A5, 0x4F11, 0xD0DD, 0x4F12, 0x81B5, - 0x4F13, 0x81B6, 0x4F14, 0x81B7, 0x4F15, 0x81B8, 0x4F16, 0x81B9, 0x4F17, 0xD6DA, 0x4F18, 0xD3C5, 0x4F19, 0xBBEF, 0x4F1A, 0xBBE1, - 0x4F1B, 0xD8F1, 0x4F1C, 0x81BA, 0x4F1D, 0x81BB, 0x4F1E, 0xC9A1, 0x4F1F, 0xCEB0, 0x4F20, 0xB4AB, 0x4F21, 0x81BC, 0x4F22, 0xD8F3, - 0x4F23, 0x81BD, 0x4F24, 0xC9CB, 0x4F25, 0xD8F6, 0x4F26, 0xC2D7, 0x4F27, 0xD8F7, 0x4F28, 0x81BE, 0x4F29, 0x81BF, 0x4F2A, 0xCEB1, - 0x4F2B, 0xD8F9, 0x4F2C, 0x81C0, 0x4F2D, 0x81C1, 0x4F2E, 0x81C2, 0x4F2F, 0xB2AE, 0x4F30, 0xB9C0, 0x4F31, 0x81C3, 0x4F32, 0xD9A3, - 0x4F33, 0x81C4, 0x4F34, 0xB0E9, 0x4F35, 0x81C5, 0x4F36, 0xC1E6, 0x4F37, 0x81C6, 0x4F38, 0xC9EC, 0x4F39, 0x81C7, 0x4F3A, 0xCBC5, - 0x4F3B, 0x81C8, 0x4F3C, 0xCBC6, 0x4F3D, 0xD9A4, 0x4F3E, 0x81C9, 0x4F3F, 0x81CA, 0x4F40, 0x81CB, 0x4F41, 0x81CC, 0x4F42, 0x81CD, - 0x4F43, 0xB5E8, 0x4F44, 0x81CE, 0x4F45, 0x81CF, 0x4F46, 0xB5AB, 0x4F47, 0x81D0, 0x4F48, 0x81D1, 0x4F49, 0x81D2, 0x4F4A, 0x81D3, - 0x4F4B, 0x81D4, 0x4F4C, 0x81D5, 0x4F4D, 0xCEBB, 0x4F4E, 0xB5CD, 0x4F4F, 0xD7A1, 0x4F50, 0xD7F4, 0x4F51, 0xD3D3, 0x4F52, 0x81D6, - 0x4F53, 0xCCE5, 0x4F54, 0x81D7, 0x4F55, 0xBACE, 0x4F56, 0x81D8, 0x4F57, 0xD9A2, 0x4F58, 0xD9DC, 0x4F59, 0xD3E0, 0x4F5A, 0xD8FD, - 0x4F5B, 0xB7F0, 0x4F5C, 0xD7F7, 0x4F5D, 0xD8FE, 0x4F5E, 0xD8FA, 0x4F5F, 0xD9A1, 0x4F60, 0xC4E3, 0x4F61, 0x81D9, 0x4F62, 0x81DA, - 0x4F63, 0xD3B6, 0x4F64, 0xD8F4, 0x4F65, 0xD9DD, 0x4F66, 0x81DB, 0x4F67, 0xD8FB, 0x4F68, 0x81DC, 0x4F69, 0xC5E5, 0x4F6A, 0x81DD, - 0x4F6B, 0x81DE, 0x4F6C, 0xC0D0, 0x4F6D, 0x81DF, 0x4F6E, 0x81E0, 0x4F6F, 0xD1F0, 0x4F70, 0xB0DB, 0x4F71, 0x81E1, 0x4F72, 0x81E2, - 0x4F73, 0xBCD1, 0x4F74, 0xD9A6, 0x4F75, 0x81E3, 0x4F76, 0xD9A5, 0x4F77, 0x81E4, 0x4F78, 0x81E5, 0x4F79, 0x81E6, 0x4F7A, 0x81E7, - 0x4F7B, 0xD9AC, 0x4F7C, 0xD9AE, 0x4F7D, 0x81E8, 0x4F7E, 0xD9AB, 0x4F7F, 0xCAB9, 0x4F80, 0x81E9, 0x4F81, 0x81EA, 0x4F82, 0x81EB, - 0x4F83, 0xD9A9, 0x4F84, 0xD6B6, 0x4F85, 0x81EC, 0x4F86, 0x81ED, 0x4F87, 0x81EE, 0x4F88, 0xB3DE, 0x4F89, 0xD9A8, 0x4F8A, 0x81EF, - 0x4F8B, 0xC0FD, 0x4F8C, 0x81F0, 0x4F8D, 0xCACC, 0x4F8E, 0x81F1, 0x4F8F, 0xD9AA, 0x4F90, 0x81F2, 0x4F91, 0xD9A7, 0x4F92, 0x81F3, - 0x4F93, 0x81F4, 0x4F94, 0xD9B0, 0x4F95, 0x81F5, 0x4F96, 0x81F6, 0x4F97, 0xB6B1, 0x4F98, 0x81F7, 0x4F99, 0x81F8, 0x4F9A, 0x81F9, - 0x4F9B, 0xB9A9, 0x4F9C, 0x81FA, 0x4F9D, 0xD2C0, 0x4F9E, 0x81FB, 0x4F9F, 0x81FC, 0x4FA0, 0xCFC0, 0x4FA1, 0x81FD, 0x4FA2, 0x81FE, - 0x4FA3, 0xC2C2, 0x4FA4, 0x8240, 0x4FA5, 0xBDC4, 0x4FA6, 0xD5EC, 0x4FA7, 0xB2E0, 0x4FA8, 0xC7C8, 0x4FA9, 0xBFEB, 0x4FAA, 0xD9AD, - 0x4FAB, 0x8241, 0x4FAC, 0xD9AF, 0x4FAD, 0x8242, 0x4FAE, 0xCEEA, 0x4FAF, 0xBAEE, 0x4FB0, 0x8243, 0x4FB1, 0x8244, 0x4FB2, 0x8245, - 0x4FB3, 0x8246, 0x4FB4, 0x8247, 0x4FB5, 0xC7D6, 0x4FB6, 0x8248, 0x4FB7, 0x8249, 0x4FB8, 0x824A, 0x4FB9, 0x824B, 0x4FBA, 0x824C, - 0x4FBB, 0x824D, 0x4FBC, 0x824E, 0x4FBD, 0x824F, 0x4FBE, 0x8250, 0x4FBF, 0xB1E3, 0x4FC0, 0x8251, 0x4FC1, 0x8252, 0x4FC2, 0x8253, - 0x4FC3, 0xB4D9, 0x4FC4, 0xB6ED, 0x4FC5, 0xD9B4, 0x4FC6, 0x8254, 0x4FC7, 0x8255, 0x4FC8, 0x8256, 0x4FC9, 0x8257, 0x4FCA, 0xBFA1, - 0x4FCB, 0x8258, 0x4FCC, 0x8259, 0x4FCD, 0x825A, 0x4FCE, 0xD9DE, 0x4FCF, 0xC7CE, 0x4FD0, 0xC0FE, 0x4FD1, 0xD9B8, 0x4FD2, 0x825B, - 0x4FD3, 0x825C, 0x4FD4, 0x825D, 0x4FD5, 0x825E, 0x4FD6, 0x825F, 0x4FD7, 0xCBD7, 0x4FD8, 0xB7FD, 0x4FD9, 0x8260, 0x4FDA, 0xD9B5, - 0x4FDB, 0x8261, 0x4FDC, 0xD9B7, 0x4FDD, 0xB1A3, 0x4FDE, 0xD3E1, 0x4FDF, 0xD9B9, 0x4FE0, 0x8262, 0x4FE1, 0xD0C5, 0x4FE2, 0x8263, - 0x4FE3, 0xD9B6, 0x4FE4, 0x8264, 0x4FE5, 0x8265, 0x4FE6, 0xD9B1, 0x4FE7, 0x8266, 0x4FE8, 0xD9B2, 0x4FE9, 0xC1A9, 0x4FEA, 0xD9B3, - 0x4FEB, 0x8267, 0x4FEC, 0x8268, 0x4FED, 0xBCF3, 0x4FEE, 0xD0DE, 0x4FEF, 0xB8A9, 0x4FF0, 0x8269, 0x4FF1, 0xBEE3, 0x4FF2, 0x826A, - 0x4FF3, 0xD9BD, 0x4FF4, 0x826B, 0x4FF5, 0x826C, 0x4FF6, 0x826D, 0x4FF7, 0x826E, 0x4FF8, 0xD9BA, 0x4FF9, 0x826F, 0x4FFA, 0xB0B3, - 0x4FFB, 0x8270, 0x4FFC, 0x8271, 0x4FFD, 0x8272, 0x4FFE, 0xD9C2, 0x4FFF, 0x8273, 0x5000, 0x8274, 0x5001, 0x8275, 0x5002, 0x8276, - 0x5003, 0x8277, 0x5004, 0x8278, 0x5005, 0x8279, 0x5006, 0x827A, 0x5007, 0x827B, 0x5008, 0x827C, 0x5009, 0x827D, 0x500A, 0x827E, - 0x500B, 0x8280, 0x500C, 0xD9C4, 0x500D, 0xB1B6, 0x500E, 0x8281, 0x500F, 0xD9BF, 0x5010, 0x8282, 0x5011, 0x8283, 0x5012, 0xB5B9, - 0x5013, 0x8284, 0x5014, 0xBEF3, 0x5015, 0x8285, 0x5016, 0x8286, 0x5017, 0x8287, 0x5018, 0xCCC8, 0x5019, 0xBAF2, 0x501A, 0xD2D0, - 0x501B, 0x8288, 0x501C, 0xD9C3, 0x501D, 0x8289, 0x501E, 0x828A, 0x501F, 0xBDE8, 0x5020, 0x828B, 0x5021, 0xB3AB, 0x5022, 0x828C, - 0x5023, 0x828D, 0x5024, 0x828E, 0x5025, 0xD9C5, 0x5026, 0xBEEB, 0x5027, 0x828F, 0x5028, 0xD9C6, 0x5029, 0xD9BB, 0x502A, 0xC4DF, - 0x502B, 0x8290, 0x502C, 0xD9BE, 0x502D, 0xD9C1, 0x502E, 0xD9C0, 0x502F, 0x8291, 0x5030, 0x8292, 0x5031, 0x8293, 0x5032, 0x8294, - 0x5033, 0x8295, 0x5034, 0x8296, 0x5035, 0x8297, 0x5036, 0x8298, 0x5037, 0x8299, 0x5038, 0x829A, 0x5039, 0x829B, 0x503A, 0xD5AE, - 0x503B, 0x829C, 0x503C, 0xD6B5, 0x503D, 0x829D, 0x503E, 0xC7E3, 0x503F, 0x829E, 0x5040, 0x829F, 0x5041, 0x82A0, 0x5042, 0x82A1, - 0x5043, 0xD9C8, 0x5044, 0x82A2, 0x5045, 0x82A3, 0x5046, 0x82A4, 0x5047, 0xBCD9, 0x5048, 0xD9CA, 0x5049, 0x82A5, 0x504A, 0x82A6, - 0x504B, 0x82A7, 0x504C, 0xD9BC, 0x504D, 0x82A8, 0x504E, 0xD9CB, 0x504F, 0xC6AB, 0x5050, 0x82A9, 0x5051, 0x82AA, 0x5052, 0x82AB, - 0x5053, 0x82AC, 0x5054, 0x82AD, 0x5055, 0xD9C9, 0x5056, 0x82AE, 0x5057, 0x82AF, 0x5058, 0x82B0, 0x5059, 0x82B1, 0x505A, 0xD7F6, - 0x505B, 0x82B2, 0x505C, 0xCDA3, 0x505D, 0x82B3, 0x505E, 0x82B4, 0x505F, 0x82B5, 0x5060, 0x82B6, 0x5061, 0x82B7, 0x5062, 0x82B8, - 0x5063, 0x82B9, 0x5064, 0x82BA, 0x5065, 0xBDA1, 0x5066, 0x82BB, 0x5067, 0x82BC, 0x5068, 0x82BD, 0x5069, 0x82BE, 0x506A, 0x82BF, - 0x506B, 0x82C0, 0x506C, 0xD9CC, 0x506D, 0x82C1, 0x506E, 0x82C2, 0x506F, 0x82C3, 0x5070, 0x82C4, 0x5071, 0x82C5, 0x5072, 0x82C6, - 0x5073, 0x82C7, 0x5074, 0x82C8, 0x5075, 0x82C9, 0x5076, 0xC5BC, 0x5077, 0xCDB5, 0x5078, 0x82CA, 0x5079, 0x82CB, 0x507A, 0x82CC, - 0x507B, 0xD9CD, 0x507C, 0x82CD, 0x507D, 0x82CE, 0x507E, 0xD9C7, 0x507F, 0xB3A5, 0x5080, 0xBFFE, 0x5081, 0x82CF, 0x5082, 0x82D0, - 0x5083, 0x82D1, 0x5084, 0x82D2, 0x5085, 0xB8B5, 0x5086, 0x82D3, 0x5087, 0x82D4, 0x5088, 0xC0FC, 0x5089, 0x82D5, 0x508A, 0x82D6, - 0x508B, 0x82D7, 0x508C, 0x82D8, 0x508D, 0xB0F8, 0x508E, 0x82D9, 0x508F, 0x82DA, 0x5090, 0x82DB, 0x5091, 0x82DC, 0x5092, 0x82DD, - 0x5093, 0x82DE, 0x5094, 0x82DF, 0x5095, 0x82E0, 0x5096, 0x82E1, 0x5097, 0x82E2, 0x5098, 0x82E3, 0x5099, 0x82E4, 0x509A, 0x82E5, - 0x509B, 0x82E6, 0x509C, 0x82E7, 0x509D, 0x82E8, 0x509E, 0x82E9, 0x509F, 0x82EA, 0x50A0, 0x82EB, 0x50A1, 0x82EC, 0x50A2, 0x82ED, - 0x50A3, 0xB4F6, 0x50A4, 0x82EE, 0x50A5, 0xD9CE, 0x50A6, 0x82EF, 0x50A7, 0xD9CF, 0x50A8, 0xB4A2, 0x50A9, 0xD9D0, 0x50AA, 0x82F0, - 0x50AB, 0x82F1, 0x50AC, 0xB4DF, 0x50AD, 0x82F2, 0x50AE, 0x82F3, 0x50AF, 0x82F4, 0x50B0, 0x82F5, 0x50B1, 0x82F6, 0x50B2, 0xB0C1, - 0x50B3, 0x82F7, 0x50B4, 0x82F8, 0x50B5, 0x82F9, 0x50B6, 0x82FA, 0x50B7, 0x82FB, 0x50B8, 0x82FC, 0x50B9, 0x82FD, 0x50BA, 0xD9D1, - 0x50BB, 0xC9B5, 0x50BC, 0x82FE, 0x50BD, 0x8340, 0x50BE, 0x8341, 0x50BF, 0x8342, 0x50C0, 0x8343, 0x50C1, 0x8344, 0x50C2, 0x8345, - 0x50C3, 0x8346, 0x50C4, 0x8347, 0x50C5, 0x8348, 0x50C6, 0x8349, 0x50C7, 0x834A, 0x50C8, 0x834B, 0x50C9, 0x834C, 0x50CA, 0x834D, - 0x50CB, 0x834E, 0x50CC, 0x834F, 0x50CD, 0x8350, 0x50CE, 0x8351, 0x50CF, 0xCFF1, 0x50D0, 0x8352, 0x50D1, 0x8353, 0x50D2, 0x8354, - 0x50D3, 0x8355, 0x50D4, 0x8356, 0x50D5, 0x8357, 0x50D6, 0xD9D2, 0x50D7, 0x8358, 0x50D8, 0x8359, 0x50D9, 0x835A, 0x50DA, 0xC1C5, - 0x50DB, 0x835B, 0x50DC, 0x835C, 0x50DD, 0x835D, 0x50DE, 0x835E, 0x50DF, 0x835F, 0x50E0, 0x8360, 0x50E1, 0x8361, 0x50E2, 0x8362, - 0x50E3, 0x8363, 0x50E4, 0x8364, 0x50E5, 0x8365, 0x50E6, 0xD9D6, 0x50E7, 0xC9AE, 0x50E8, 0x8366, 0x50E9, 0x8367, 0x50EA, 0x8368, - 0x50EB, 0x8369, 0x50EC, 0xD9D5, 0x50ED, 0xD9D4, 0x50EE, 0xD9D7, 0x50EF, 0x836A, 0x50F0, 0x836B, 0x50F1, 0x836C, 0x50F2, 0x836D, - 0x50F3, 0xCBDB, 0x50F4, 0x836E, 0x50F5, 0xBDA9, 0x50F6, 0x836F, 0x50F7, 0x8370, 0x50F8, 0x8371, 0x50F9, 0x8372, 0x50FA, 0x8373, - 0x50FB, 0xC6A7, 0x50FC, 0x8374, 0x50FD, 0x8375, 0x50FE, 0x8376, 0x50FF, 0x8377, 0x5100, 0x8378, 0x5101, 0x8379, 0x5102, 0x837A, - 0x5103, 0x837B, 0x5104, 0x837C, 0x5105, 0x837D, 0x5106, 0xD9D3, 0x5107, 0xD9D8, 0x5108, 0x837E, 0x5109, 0x8380, 0x510A, 0x8381, - 0x510B, 0xD9D9, 0x510C, 0x8382, 0x510D, 0x8383, 0x510E, 0x8384, 0x510F, 0x8385, 0x5110, 0x8386, 0x5111, 0x8387, 0x5112, 0xC8E5, - 0x5113, 0x8388, 0x5114, 0x8389, 0x5115, 0x838A, 0x5116, 0x838B, 0x5117, 0x838C, 0x5118, 0x838D, 0x5119, 0x838E, 0x511A, 0x838F, - 0x511B, 0x8390, 0x511C, 0x8391, 0x511D, 0x8392, 0x511E, 0x8393, 0x511F, 0x8394, 0x5120, 0x8395, 0x5121, 0xC0DC, 0x5122, 0x8396, - 0x5123, 0x8397, 0x5124, 0x8398, 0x5125, 0x8399, 0x5126, 0x839A, 0x5127, 0x839B, 0x5128, 0x839C, 0x5129, 0x839D, 0x512A, 0x839E, - 0x512B, 0x839F, 0x512C, 0x83A0, 0x512D, 0x83A1, 0x512E, 0x83A2, 0x512F, 0x83A3, 0x5130, 0x83A4, 0x5131, 0x83A5, 0x5132, 0x83A6, - 0x5133, 0x83A7, 0x5134, 0x83A8, 0x5135, 0x83A9, 0x5136, 0x83AA, 0x5137, 0x83AB, 0x5138, 0x83AC, 0x5139, 0x83AD, 0x513A, 0x83AE, - 0x513B, 0x83AF, 0x513C, 0x83B0, 0x513D, 0x83B1, 0x513E, 0x83B2, 0x513F, 0xB6F9, 0x5140, 0xD8A3, 0x5141, 0xD4CA, 0x5142, 0x83B3, - 0x5143, 0xD4AA, 0x5144, 0xD0D6, 0x5145, 0xB3E4, 0x5146, 0xD5D7, 0x5147, 0x83B4, 0x5148, 0xCFC8, 0x5149, 0xB9E2, 0x514A, 0x83B5, - 0x514B, 0xBFCB, 0x514C, 0x83B6, 0x514D, 0xC3E2, 0x514E, 0x83B7, 0x514F, 0x83B8, 0x5150, 0x83B9, 0x5151, 0xB6D2, 0x5152, 0x83BA, - 0x5153, 0x83BB, 0x5154, 0xCDC3, 0x5155, 0xD9EE, 0x5156, 0xD9F0, 0x5157, 0x83BC, 0x5158, 0x83BD, 0x5159, 0x83BE, 0x515A, 0xB5B3, - 0x515B, 0x83BF, 0x515C, 0xB6B5, 0x515D, 0x83C0, 0x515E, 0x83C1, 0x515F, 0x83C2, 0x5160, 0x83C3, 0x5161, 0x83C4, 0x5162, 0xBEA4, - 0x5163, 0x83C5, 0x5164, 0x83C6, 0x5165, 0xC8EB, 0x5166, 0x83C7, 0x5167, 0x83C8, 0x5168, 0xC8AB, 0x5169, 0x83C9, 0x516A, 0x83CA, - 0x516B, 0xB0CB, 0x516C, 0xB9AB, 0x516D, 0xC1F9, 0x516E, 0xD9E2, 0x516F, 0x83CB, 0x5170, 0xC0BC, 0x5171, 0xB9B2, 0x5172, 0x83CC, - 0x5173, 0xB9D8, 0x5174, 0xD0CB, 0x5175, 0xB1F8, 0x5176, 0xC6E4, 0x5177, 0xBEDF, 0x5178, 0xB5E4, 0x5179, 0xD7C8, 0x517A, 0x83CD, - 0x517B, 0xD1F8, 0x517C, 0xBCE6, 0x517D, 0xCADE, 0x517E, 0x83CE, 0x517F, 0x83CF, 0x5180, 0xBCBD, 0x5181, 0xD9E6, 0x5182, 0xD8E7, - 0x5183, 0x83D0, 0x5184, 0x83D1, 0x5185, 0xC4DA, 0x5186, 0x83D2, 0x5187, 0x83D3, 0x5188, 0xB8D4, 0x5189, 0xC8BD, 0x518A, 0x83D4, - 0x518B, 0x83D5, 0x518C, 0xB2E1, 0x518D, 0xD4D9, 0x518E, 0x83D6, 0x518F, 0x83D7, 0x5190, 0x83D8, 0x5191, 0x83D9, 0x5192, 0xC3B0, - 0x5193, 0x83DA, 0x5194, 0x83DB, 0x5195, 0xC3E1, 0x5196, 0xDAA2, 0x5197, 0xC8DF, 0x5198, 0x83DC, 0x5199, 0xD0B4, 0x519A, 0x83DD, - 0x519B, 0xBEFC, 0x519C, 0xC5A9, 0x519D, 0x83DE, 0x519E, 0x83DF, 0x519F, 0x83E0, 0x51A0, 0xB9DA, 0x51A1, 0x83E1, 0x51A2, 0xDAA3, - 0x51A3, 0x83E2, 0x51A4, 0xD4A9, 0x51A5, 0xDAA4, 0x51A6, 0x83E3, 0x51A7, 0x83E4, 0x51A8, 0x83E5, 0x51A9, 0x83E6, 0x51AA, 0x83E7, - 0x51AB, 0xD9FB, 0x51AC, 0xB6AC, 0x51AD, 0x83E8, 0x51AE, 0x83E9, 0x51AF, 0xB7EB, 0x51B0, 0xB1F9, 0x51B1, 0xD9FC, 0x51B2, 0xB3E5, - 0x51B3, 0xBEF6, 0x51B4, 0x83EA, 0x51B5, 0xBFF6, 0x51B6, 0xD2B1, 0x51B7, 0xC0E4, 0x51B8, 0x83EB, 0x51B9, 0x83EC, 0x51BA, 0x83ED, - 0x51BB, 0xB6B3, 0x51BC, 0xD9FE, 0x51BD, 0xD9FD, 0x51BE, 0x83EE, 0x51BF, 0x83EF, 0x51C0, 0xBEBB, 0x51C1, 0x83F0, 0x51C2, 0x83F1, - 0x51C3, 0x83F2, 0x51C4, 0xC6E0, 0x51C5, 0x83F3, 0x51C6, 0xD7BC, 0x51C7, 0xDAA1, 0x51C8, 0x83F4, 0x51C9, 0xC1B9, 0x51CA, 0x83F5, - 0x51CB, 0xB5F2, 0x51CC, 0xC1E8, 0x51CD, 0x83F6, 0x51CE, 0x83F7, 0x51CF, 0xBCF5, 0x51D0, 0x83F8, 0x51D1, 0xB4D5, 0x51D2, 0x83F9, - 0x51D3, 0x83FA, 0x51D4, 0x83FB, 0x51D5, 0x83FC, 0x51D6, 0x83FD, 0x51D7, 0x83FE, 0x51D8, 0x8440, 0x51D9, 0x8441, 0x51DA, 0x8442, - 0x51DB, 0xC1DD, 0x51DC, 0x8443, 0x51DD, 0xC4FD, 0x51DE, 0x8444, 0x51DF, 0x8445, 0x51E0, 0xBCB8, 0x51E1, 0xB7B2, 0x51E2, 0x8446, - 0x51E3, 0x8447, 0x51E4, 0xB7EF, 0x51E5, 0x8448, 0x51E6, 0x8449, 0x51E7, 0x844A, 0x51E8, 0x844B, 0x51E9, 0x844C, 0x51EA, 0x844D, - 0x51EB, 0xD9EC, 0x51EC, 0x844E, 0x51ED, 0xC6BE, 0x51EE, 0x844F, 0x51EF, 0xBFAD, 0x51F0, 0xBBCB, 0x51F1, 0x8450, 0x51F2, 0x8451, - 0x51F3, 0xB5CA, 0x51F4, 0x8452, 0x51F5, 0xDBC9, 0x51F6, 0xD0D7, 0x51F7, 0x8453, 0x51F8, 0xCDB9, 0x51F9, 0xB0BC, 0x51FA, 0xB3F6, - 0x51FB, 0xBBF7, 0x51FC, 0xDBCA, 0x51FD, 0xBAAF, 0x51FE, 0x8454, 0x51FF, 0xD4E4, 0x5200, 0xB5B6, 0x5201, 0xB5F3, 0x5202, 0xD8D6, - 0x5203, 0xC8D0, 0x5204, 0x8455, 0x5205, 0x8456, 0x5206, 0xB7D6, 0x5207, 0xC7D0, 0x5208, 0xD8D7, 0x5209, 0x8457, 0x520A, 0xBFAF, - 0x520B, 0x8458, 0x520C, 0x8459, 0x520D, 0xDBBB, 0x520E, 0xD8D8, 0x520F, 0x845A, 0x5210, 0x845B, 0x5211, 0xD0CC, 0x5212, 0xBBAE, - 0x5213, 0x845C, 0x5214, 0x845D, 0x5215, 0x845E, 0x5216, 0xEBBE, 0x5217, 0xC1D0, 0x5218, 0xC1F5, 0x5219, 0xD4F2, 0x521A, 0xB8D5, - 0x521B, 0xB4B4, 0x521C, 0x845F, 0x521D, 0xB3F5, 0x521E, 0x8460, 0x521F, 0x8461, 0x5220, 0xC9BE, 0x5221, 0x8462, 0x5222, 0x8463, - 0x5223, 0x8464, 0x5224, 0xC5D0, 0x5225, 0x8465, 0x5226, 0x8466, 0x5227, 0x8467, 0x5228, 0xC5D9, 0x5229, 0xC0FB, 0x522A, 0x8468, - 0x522B, 0xB1F0, 0x522C, 0x8469, 0x522D, 0xD8D9, 0x522E, 0xB9CE, 0x522F, 0x846A, 0x5230, 0xB5BD, 0x5231, 0x846B, 0x5232, 0x846C, - 0x5233, 0xD8DA, 0x5234, 0x846D, 0x5235, 0x846E, 0x5236, 0xD6C6, 0x5237, 0xCBA2, 0x5238, 0xC8AF, 0x5239, 0xC9B2, 0x523A, 0xB4CC, - 0x523B, 0xBFCC, 0x523C, 0x846F, 0x523D, 0xB9F4, 0x523E, 0x8470, 0x523F, 0xD8DB, 0x5240, 0xD8DC, 0x5241, 0xB6E7, 0x5242, 0xBCC1, - 0x5243, 0xCCEA, 0x5244, 0x8471, 0x5245, 0x8472, 0x5246, 0x8473, 0x5247, 0x8474, 0x5248, 0x8475, 0x5249, 0x8476, 0x524A, 0xCFF7, - 0x524B, 0x8477, 0x524C, 0xD8DD, 0x524D, 0xC7B0, 0x524E, 0x8478, 0x524F, 0x8479, 0x5250, 0xB9D0, 0x5251, 0xBDA3, 0x5252, 0x847A, - 0x5253, 0x847B, 0x5254, 0xCCDE, 0x5255, 0x847C, 0x5256, 0xC6CA, 0x5257, 0x847D, 0x5258, 0x847E, 0x5259, 0x8480, 0x525A, 0x8481, - 0x525B, 0x8482, 0x525C, 0xD8E0, 0x525D, 0x8483, 0x525E, 0xD8DE, 0x525F, 0x8484, 0x5260, 0x8485, 0x5261, 0xD8DF, 0x5262, 0x8486, - 0x5263, 0x8487, 0x5264, 0x8488, 0x5265, 0xB0FE, 0x5266, 0x8489, 0x5267, 0xBEE7, 0x5268, 0x848A, 0x5269, 0xCAA3, 0x526A, 0xBCF4, - 0x526B, 0x848B, 0x526C, 0x848C, 0x526D, 0x848D, 0x526E, 0x848E, 0x526F, 0xB8B1, 0x5270, 0x848F, 0x5271, 0x8490, 0x5272, 0xB8EE, - 0x5273, 0x8491, 0x5274, 0x8492, 0x5275, 0x8493, 0x5276, 0x8494, 0x5277, 0x8495, 0x5278, 0x8496, 0x5279, 0x8497, 0x527A, 0x8498, - 0x527B, 0x8499, 0x527C, 0x849A, 0x527D, 0xD8E2, 0x527E, 0x849B, 0x527F, 0xBDCB, 0x5280, 0x849C, 0x5281, 0xD8E4, 0x5282, 0xD8E3, - 0x5283, 0x849D, 0x5284, 0x849E, 0x5285, 0x849F, 0x5286, 0x84A0, 0x5287, 0x84A1, 0x5288, 0xC5FC, 0x5289, 0x84A2, 0x528A, 0x84A3, - 0x528B, 0x84A4, 0x528C, 0x84A5, 0x528D, 0x84A6, 0x528E, 0x84A7, 0x528F, 0x84A8, 0x5290, 0xD8E5, 0x5291, 0x84A9, 0x5292, 0x84AA, - 0x5293, 0xD8E6, 0x5294, 0x84AB, 0x5295, 0x84AC, 0x5296, 0x84AD, 0x5297, 0x84AE, 0x5298, 0x84AF, 0x5299, 0x84B0, 0x529A, 0x84B1, - 0x529B, 0xC1A6, 0x529C, 0x84B2, 0x529D, 0xC8B0, 0x529E, 0xB0EC, 0x529F, 0xB9A6, 0x52A0, 0xBCD3, 0x52A1, 0xCEF1, 0x52A2, 0xDBBD, - 0x52A3, 0xC1D3, 0x52A4, 0x84B3, 0x52A5, 0x84B4, 0x52A6, 0x84B5, 0x52A7, 0x84B6, 0x52A8, 0xB6AF, 0x52A9, 0xD6FA, 0x52AA, 0xC5AC, - 0x52AB, 0xBDD9, 0x52AC, 0xDBBE, 0x52AD, 0xDBBF, 0x52AE, 0x84B7, 0x52AF, 0x84B8, 0x52B0, 0x84B9, 0x52B1, 0xC0F8, 0x52B2, 0xBEA2, - 0x52B3, 0xC0CD, 0x52B4, 0x84BA, 0x52B5, 0x84BB, 0x52B6, 0x84BC, 0x52B7, 0x84BD, 0x52B8, 0x84BE, 0x52B9, 0x84BF, 0x52BA, 0x84C0, - 0x52BB, 0x84C1, 0x52BC, 0x84C2, 0x52BD, 0x84C3, 0x52BE, 0xDBC0, 0x52BF, 0xCAC6, 0x52C0, 0x84C4, 0x52C1, 0x84C5, 0x52C2, 0x84C6, - 0x52C3, 0xB2AA, 0x52C4, 0x84C7, 0x52C5, 0x84C8, 0x52C6, 0x84C9, 0x52C7, 0xD3C2, 0x52C8, 0x84CA, 0x52C9, 0xC3E3, 0x52CA, 0x84CB, - 0x52CB, 0xD1AB, 0x52CC, 0x84CC, 0x52CD, 0x84CD, 0x52CE, 0x84CE, 0x52CF, 0x84CF, 0x52D0, 0xDBC2, 0x52D1, 0x84D0, 0x52D2, 0xC0D5, - 0x52D3, 0x84D1, 0x52D4, 0x84D2, 0x52D5, 0x84D3, 0x52D6, 0xDBC3, 0x52D7, 0x84D4, 0x52D8, 0xBFB1, 0x52D9, 0x84D5, 0x52DA, 0x84D6, - 0x52DB, 0x84D7, 0x52DC, 0x84D8, 0x52DD, 0x84D9, 0x52DE, 0x84DA, 0x52DF, 0xC4BC, 0x52E0, 0x84DB, 0x52E1, 0x84DC, 0x52E2, 0x84DD, - 0x52E3, 0x84DE, 0x52E4, 0xC7DA, 0x52E5, 0x84DF, 0x52E6, 0x84E0, 0x52E7, 0x84E1, 0x52E8, 0x84E2, 0x52E9, 0x84E3, 0x52EA, 0x84E4, - 0x52EB, 0x84E5, 0x52EC, 0x84E6, 0x52ED, 0x84E7, 0x52EE, 0x84E8, 0x52EF, 0x84E9, 0x52F0, 0xDBC4, 0x52F1, 0x84EA, 0x52F2, 0x84EB, - 0x52F3, 0x84EC, 0x52F4, 0x84ED, 0x52F5, 0x84EE, 0x52F6, 0x84EF, 0x52F7, 0x84F0, 0x52F8, 0x84F1, 0x52F9, 0xD9E8, 0x52FA, 0xC9D7, - 0x52FB, 0x84F2, 0x52FC, 0x84F3, 0x52FD, 0x84F4, 0x52FE, 0xB9B4, 0x52FF, 0xCEF0, 0x5300, 0xD4C8, 0x5301, 0x84F5, 0x5302, 0x84F6, - 0x5303, 0x84F7, 0x5304, 0x84F8, 0x5305, 0xB0FC, 0x5306, 0xB4D2, 0x5307, 0x84F9, 0x5308, 0xD0D9, 0x5309, 0x84FA, 0x530A, 0x84FB, - 0x530B, 0x84FC, 0x530C, 0x84FD, 0x530D, 0xD9E9, 0x530E, 0x84FE, 0x530F, 0xDECB, 0x5310, 0xD9EB, 0x5311, 0x8540, 0x5312, 0x8541, - 0x5313, 0x8542, 0x5314, 0x8543, 0x5315, 0xD8B0, 0x5316, 0xBBAF, 0x5317, 0xB1B1, 0x5318, 0x8544, 0x5319, 0xB3D7, 0x531A, 0xD8CE, - 0x531B, 0x8545, 0x531C, 0x8546, 0x531D, 0xD4D1, 0x531E, 0x8547, 0x531F, 0x8548, 0x5320, 0xBDB3, 0x5321, 0xBFEF, 0x5322, 0x8549, - 0x5323, 0xCFBB, 0x5324, 0x854A, 0x5325, 0x854B, 0x5326, 0xD8D0, 0x5327, 0x854C, 0x5328, 0x854D, 0x5329, 0x854E, 0x532A, 0xB7CB, - 0x532B, 0x854F, 0x532C, 0x8550, 0x532D, 0x8551, 0x532E, 0xD8D1, 0x532F, 0x8552, 0x5330, 0x8553, 0x5331, 0x8554, 0x5332, 0x8555, - 0x5333, 0x8556, 0x5334, 0x8557, 0x5335, 0x8558, 0x5336, 0x8559, 0x5337, 0x855A, 0x5338, 0x855B, 0x5339, 0xC6A5, 0x533A, 0xC7F8, - 0x533B, 0xD2BD, 0x533C, 0x855C, 0x533D, 0x855D, 0x533E, 0xD8D2, 0x533F, 0xC4E4, 0x5340, 0x855E, 0x5341, 0xCAAE, 0x5342, 0x855F, - 0x5343, 0xC7A7, 0x5344, 0x8560, 0x5345, 0xD8A6, 0x5346, 0x8561, 0x5347, 0xC9FD, 0x5348, 0xCEE7, 0x5349, 0xBBDC, 0x534A, 0xB0EB, - 0x534B, 0x8562, 0x534C, 0x8563, 0x534D, 0x8564, 0x534E, 0xBBAA, 0x534F, 0xD0AD, 0x5350, 0x8565, 0x5351, 0xB1B0, 0x5352, 0xD7E4, - 0x5353, 0xD7BF, 0x5354, 0x8566, 0x5355, 0xB5A5, 0x5356, 0xC2F4, 0x5357, 0xC4CF, 0x5358, 0x8567, 0x5359, 0x8568, 0x535A, 0xB2A9, - 0x535B, 0x8569, 0x535C, 0xB2B7, 0x535D, 0x856A, 0x535E, 0xB1E5, 0x535F, 0xDFB2, 0x5360, 0xD5BC, 0x5361, 0xBFA8, 0x5362, 0xC2AC, - 0x5363, 0xD8D5, 0x5364, 0xC2B1, 0x5365, 0x856B, 0x5366, 0xD8D4, 0x5367, 0xCED4, 0x5368, 0x856C, 0x5369, 0xDAE0, 0x536A, 0x856D, - 0x536B, 0xCEC0, 0x536C, 0x856E, 0x536D, 0x856F, 0x536E, 0xD8B4, 0x536F, 0xC3AE, 0x5370, 0xD3A1, 0x5371, 0xCEA3, 0x5372, 0x8570, - 0x5373, 0xBCB4, 0x5374, 0xC8B4, 0x5375, 0xC2D1, 0x5376, 0x8571, 0x5377, 0xBEED, 0x5378, 0xD0B6, 0x5379, 0x8572, 0x537A, 0xDAE1, - 0x537B, 0x8573, 0x537C, 0x8574, 0x537D, 0x8575, 0x537E, 0x8576, 0x537F, 0xC7E4, 0x5380, 0x8577, 0x5381, 0x8578, 0x5382, 0xB3A7, - 0x5383, 0x8579, 0x5384, 0xB6F2, 0x5385, 0xCCFC, 0x5386, 0xC0FA, 0x5387, 0x857A, 0x5388, 0x857B, 0x5389, 0xC0F7, 0x538A, 0x857C, - 0x538B, 0xD1B9, 0x538C, 0xD1E1, 0x538D, 0xD8C7, 0x538E, 0x857D, 0x538F, 0x857E, 0x5390, 0x8580, 0x5391, 0x8581, 0x5392, 0x8582, - 0x5393, 0x8583, 0x5394, 0x8584, 0x5395, 0xB2DE, 0x5396, 0x8585, 0x5397, 0x8586, 0x5398, 0xC0E5, 0x5399, 0x8587, 0x539A, 0xBAF1, - 0x539B, 0x8588, 0x539C, 0x8589, 0x539D, 0xD8C8, 0x539E, 0x858A, 0x539F, 0xD4AD, 0x53A0, 0x858B, 0x53A1, 0x858C, 0x53A2, 0xCFE1, - 0x53A3, 0xD8C9, 0x53A4, 0x858D, 0x53A5, 0xD8CA, 0x53A6, 0xCFC3, 0x53A7, 0x858E, 0x53A8, 0xB3F8, 0x53A9, 0xBEC7, 0x53AA, 0x858F, - 0x53AB, 0x8590, 0x53AC, 0x8591, 0x53AD, 0x8592, 0x53AE, 0xD8CB, 0x53AF, 0x8593, 0x53B0, 0x8594, 0x53B1, 0x8595, 0x53B2, 0x8596, - 0x53B3, 0x8597, 0x53B4, 0x8598, 0x53B5, 0x8599, 0x53B6, 0xDBCC, 0x53B7, 0x859A, 0x53B8, 0x859B, 0x53B9, 0x859C, 0x53BA, 0x859D, - 0x53BB, 0xC8A5, 0x53BC, 0x859E, 0x53BD, 0x859F, 0x53BE, 0x85A0, 0x53BF, 0xCFD8, 0x53C0, 0x85A1, 0x53C1, 0xC8FE, 0x53C2, 0xB2CE, - 0x53C3, 0x85A2, 0x53C4, 0x85A3, 0x53C5, 0x85A4, 0x53C6, 0x85A5, 0x53C7, 0x85A6, 0x53C8, 0xD3D6, 0x53C9, 0xB2E6, 0x53CA, 0xBCB0, - 0x53CB, 0xD3D1, 0x53CC, 0xCBAB, 0x53CD, 0xB7B4, 0x53CE, 0x85A7, 0x53CF, 0x85A8, 0x53D0, 0x85A9, 0x53D1, 0xB7A2, 0x53D2, 0x85AA, - 0x53D3, 0x85AB, 0x53D4, 0xCAE5, 0x53D5, 0x85AC, 0x53D6, 0xC8A1, 0x53D7, 0xCADC, 0x53D8, 0xB1E4, 0x53D9, 0xD0F0, 0x53DA, 0x85AD, - 0x53DB, 0xC5D1, 0x53DC, 0x85AE, 0x53DD, 0x85AF, 0x53DE, 0x85B0, 0x53DF, 0xDBC5, 0x53E0, 0xB5FE, 0x53E1, 0x85B1, 0x53E2, 0x85B2, - 0x53E3, 0xBFDA, 0x53E4, 0xB9C5, 0x53E5, 0xBEE4, 0x53E6, 0xC1ED, 0x53E7, 0x85B3, 0x53E8, 0xDFB6, 0x53E9, 0xDFB5, 0x53EA, 0xD6BB, - 0x53EB, 0xBDD0, 0x53EC, 0xD5D9, 0x53ED, 0xB0C8, 0x53EE, 0xB6A3, 0x53EF, 0xBFC9, 0x53F0, 0xCCA8, 0x53F1, 0xDFB3, 0x53F2, 0xCAB7, - 0x53F3, 0xD3D2, 0x53F4, 0x85B4, 0x53F5, 0xD8CF, 0x53F6, 0xD2B6, 0x53F7, 0xBAC5, 0x53F8, 0xCBBE, 0x53F9, 0xCCBE, 0x53FA, 0x85B5, - 0x53FB, 0xDFB7, 0x53FC, 0xB5F0, 0x53FD, 0xDFB4, 0x53FE, 0x85B6, 0x53FF, 0x85B7, 0x5400, 0x85B8, 0x5401, 0xD3F5, 0x5402, 0x85B9, - 0x5403, 0xB3D4, 0x5404, 0xB8F7, 0x5405, 0x85BA, 0x5406, 0xDFBA, 0x5407, 0x85BB, 0x5408, 0xBACF, 0x5409, 0xBCAA, 0x540A, 0xB5F5, - 0x540B, 0x85BC, 0x540C, 0xCDAC, 0x540D, 0xC3FB, 0x540E, 0xBAF3, 0x540F, 0xC0F4, 0x5410, 0xCDC2, 0x5411, 0xCFF2, 0x5412, 0xDFB8, - 0x5413, 0xCFC5, 0x5414, 0x85BD, 0x5415, 0xC2C0, 0x5416, 0xDFB9, 0x5417, 0xC2F0, 0x5418, 0x85BE, 0x5419, 0x85BF, 0x541A, 0x85C0, - 0x541B, 0xBEFD, 0x541C, 0x85C1, 0x541D, 0xC1DF, 0x541E, 0xCDCC, 0x541F, 0xD2F7, 0x5420, 0xB7CD, 0x5421, 0xDFC1, 0x5422, 0x85C2, - 0x5423, 0xDFC4, 0x5424, 0x85C3, 0x5425, 0x85C4, 0x5426, 0xB7F1, 0x5427, 0xB0C9, 0x5428, 0xB6D6, 0x5429, 0xB7D4, 0x542A, 0x85C5, - 0x542B, 0xBAAC, 0x542C, 0xCCFD, 0x542D, 0xBFD4, 0x542E, 0xCBB1, 0x542F, 0xC6F4, 0x5430, 0x85C6, 0x5431, 0xD6A8, 0x5432, 0xDFC5, - 0x5433, 0x85C7, 0x5434, 0xCEE2, 0x5435, 0xB3B3, 0x5436, 0x85C8, 0x5437, 0x85C9, 0x5438, 0xCEFC, 0x5439, 0xB4B5, 0x543A, 0x85CA, - 0x543B, 0xCEC7, 0x543C, 0xBAF0, 0x543D, 0x85CB, 0x543E, 0xCEE1, 0x543F, 0x85CC, 0x5440, 0xD1BD, 0x5441, 0x85CD, 0x5442, 0x85CE, - 0x5443, 0xDFC0, 0x5444, 0x85CF, 0x5445, 0x85D0, 0x5446, 0xB4F4, 0x5447, 0x85D1, 0x5448, 0xB3CA, 0x5449, 0x85D2, 0x544A, 0xB8E6, - 0x544B, 0xDFBB, 0x544C, 0x85D3, 0x544D, 0x85D4, 0x544E, 0x85D5, 0x544F, 0x85D6, 0x5450, 0xC4C5, 0x5451, 0x85D7, 0x5452, 0xDFBC, - 0x5453, 0xDFBD, 0x5454, 0xDFBE, 0x5455, 0xC5BB, 0x5456, 0xDFBF, 0x5457, 0xDFC2, 0x5458, 0xD4B1, 0x5459, 0xDFC3, 0x545A, 0x85D8, - 0x545B, 0xC7BA, 0x545C, 0xCED8, 0x545D, 0x85D9, 0x545E, 0x85DA, 0x545F, 0x85DB, 0x5460, 0x85DC, 0x5461, 0x85DD, 0x5462, 0xC4D8, - 0x5463, 0x85DE, 0x5464, 0xDFCA, 0x5465, 0x85DF, 0x5466, 0xDFCF, 0x5467, 0x85E0, 0x5468, 0xD6DC, 0x5469, 0x85E1, 0x546A, 0x85E2, - 0x546B, 0x85E3, 0x546C, 0x85E4, 0x546D, 0x85E5, 0x546E, 0x85E6, 0x546F, 0x85E7, 0x5470, 0x85E8, 0x5471, 0xDFC9, 0x5472, 0xDFDA, - 0x5473, 0xCEB6, 0x5474, 0x85E9, 0x5475, 0xBAC7, 0x5476, 0xDFCE, 0x5477, 0xDFC8, 0x5478, 0xC5DE, 0x5479, 0x85EA, 0x547A, 0x85EB, - 0x547B, 0xC9EB, 0x547C, 0xBAF4, 0x547D, 0xC3FC, 0x547E, 0x85EC, 0x547F, 0x85ED, 0x5480, 0xBED7, 0x5481, 0x85EE, 0x5482, 0xDFC6, - 0x5483, 0x85EF, 0x5484, 0xDFCD, 0x5485, 0x85F0, 0x5486, 0xC5D8, 0x5487, 0x85F1, 0x5488, 0x85F2, 0x5489, 0x85F3, 0x548A, 0x85F4, - 0x548B, 0xD5A6, 0x548C, 0xBACD, 0x548D, 0x85F5, 0x548E, 0xBECC, 0x548F, 0xD3BD, 0x5490, 0xB8C0, 0x5491, 0x85F6, 0x5492, 0xD6E4, - 0x5493, 0x85F7, 0x5494, 0xDFC7, 0x5495, 0xB9BE, 0x5496, 0xBFA7, 0x5497, 0x85F8, 0x5498, 0x85F9, 0x5499, 0xC1FC, 0x549A, 0xDFCB, - 0x549B, 0xDFCC, 0x549C, 0x85FA, 0x549D, 0xDFD0, 0x549E, 0x85FB, 0x549F, 0x85FC, 0x54A0, 0x85FD, 0x54A1, 0x85FE, 0x54A2, 0x8640, - 0x54A3, 0xDFDB, 0x54A4, 0xDFE5, 0x54A5, 0x8641, 0x54A6, 0xDFD7, 0x54A7, 0xDFD6, 0x54A8, 0xD7C9, 0x54A9, 0xDFE3, 0x54AA, 0xDFE4, - 0x54AB, 0xE5EB, 0x54AC, 0xD2A7, 0x54AD, 0xDFD2, 0x54AE, 0x8642, 0x54AF, 0xBFA9, 0x54B0, 0x8643, 0x54B1, 0xD4DB, 0x54B2, 0x8644, - 0x54B3, 0xBFC8, 0x54B4, 0xDFD4, 0x54B5, 0x8645, 0x54B6, 0x8646, 0x54B7, 0x8647, 0x54B8, 0xCFCC, 0x54B9, 0x8648, 0x54BA, 0x8649, - 0x54BB, 0xDFDD, 0x54BC, 0x864A, 0x54BD, 0xD1CA, 0x54BE, 0x864B, 0x54BF, 0xDFDE, 0x54C0, 0xB0A7, 0x54C1, 0xC6B7, 0x54C2, 0xDFD3, - 0x54C3, 0x864C, 0x54C4, 0xBAE5, 0x54C5, 0x864D, 0x54C6, 0xB6DF, 0x54C7, 0xCDDB, 0x54C8, 0xB9FE, 0x54C9, 0xD4D5, 0x54CA, 0x864E, - 0x54CB, 0x864F, 0x54CC, 0xDFDF, 0x54CD, 0xCFEC, 0x54CE, 0xB0A5, 0x54CF, 0xDFE7, 0x54D0, 0xDFD1, 0x54D1, 0xD1C6, 0x54D2, 0xDFD5, - 0x54D3, 0xDFD8, 0x54D4, 0xDFD9, 0x54D5, 0xDFDC, 0x54D6, 0x8650, 0x54D7, 0xBBA9, 0x54D8, 0x8651, 0x54D9, 0xDFE0, 0x54DA, 0xDFE1, - 0x54DB, 0x8652, 0x54DC, 0xDFE2, 0x54DD, 0xDFE6, 0x54DE, 0xDFE8, 0x54DF, 0xD3B4, 0x54E0, 0x8653, 0x54E1, 0x8654, 0x54E2, 0x8655, - 0x54E3, 0x8656, 0x54E4, 0x8657, 0x54E5, 0xB8E7, 0x54E6, 0xC5B6, 0x54E7, 0xDFEA, 0x54E8, 0xC9DA, 0x54E9, 0xC1A8, 0x54EA, 0xC4C4, - 0x54EB, 0x8658, 0x54EC, 0x8659, 0x54ED, 0xBFDE, 0x54EE, 0xCFF8, 0x54EF, 0x865A, 0x54F0, 0x865B, 0x54F1, 0x865C, 0x54F2, 0xD5DC, - 0x54F3, 0xDFEE, 0x54F4, 0x865D, 0x54F5, 0x865E, 0x54F6, 0x865F, 0x54F7, 0x8660, 0x54F8, 0x8661, 0x54F9, 0x8662, 0x54FA, 0xB2B8, - 0x54FB, 0x8663, 0x54FC, 0xBADF, 0x54FD, 0xDFEC, 0x54FE, 0x8664, 0x54FF, 0xDBC1, 0x5500, 0x8665, 0x5501, 0xD1E4, 0x5502, 0x8666, - 0x5503, 0x8667, 0x5504, 0x8668, 0x5505, 0x8669, 0x5506, 0xCBF4, 0x5507, 0xB4BD, 0x5508, 0x866A, 0x5509, 0xB0A6, 0x550A, 0x866B, - 0x550B, 0x866C, 0x550C, 0x866D, 0x550D, 0x866E, 0x550E, 0x866F, 0x550F, 0xDFF1, 0x5510, 0xCCC6, 0x5511, 0xDFF2, 0x5512, 0x8670, - 0x5513, 0x8671, 0x5514, 0xDFED, 0x5515, 0x8672, 0x5516, 0x8673, 0x5517, 0x8674, 0x5518, 0x8675, 0x5519, 0x8676, 0x551A, 0x8677, - 0x551B, 0xDFE9, 0x551C, 0x8678, 0x551D, 0x8679, 0x551E, 0x867A, 0x551F, 0x867B, 0x5520, 0xDFEB, 0x5521, 0x867C, 0x5522, 0xDFEF, - 0x5523, 0xDFF0, 0x5524, 0xBBBD, 0x5525, 0x867D, 0x5526, 0x867E, 0x5527, 0xDFF3, 0x5528, 0x8680, 0x5529, 0x8681, 0x552A, 0xDFF4, - 0x552B, 0x8682, 0x552C, 0xBBA3, 0x552D, 0x8683, 0x552E, 0xCADB, 0x552F, 0xCEA8, 0x5530, 0xE0A7, 0x5531, 0xB3AA, 0x5532, 0x8684, - 0x5533, 0xE0A6, 0x5534, 0x8685, 0x5535, 0x8686, 0x5536, 0x8687, 0x5537, 0xE0A1, 0x5538, 0x8688, 0x5539, 0x8689, 0x553A, 0x868A, - 0x553B, 0x868B, 0x553C, 0xDFFE, 0x553D, 0x868C, 0x553E, 0xCDD9, 0x553F, 0xDFFC, 0x5540, 0x868D, 0x5541, 0xDFFA, 0x5542, 0x868E, - 0x5543, 0xBFD0, 0x5544, 0xD7C4, 0x5545, 0x868F, 0x5546, 0xC9CC, 0x5547, 0x8690, 0x5548, 0x8691, 0x5549, 0xDFF8, 0x554A, 0xB0A1, - 0x554B, 0x8692, 0x554C, 0x8693, 0x554D, 0x8694, 0x554E, 0x8695, 0x554F, 0x8696, 0x5550, 0xDFFD, 0x5551, 0x8697, 0x5552, 0x8698, - 0x5553, 0x8699, 0x5554, 0x869A, 0x5555, 0xDFFB, 0x5556, 0xE0A2, 0x5557, 0x869B, 0x5558, 0x869C, 0x5559, 0x869D, 0x555A, 0x869E, - 0x555B, 0x869F, 0x555C, 0xE0A8, 0x555D, 0x86A0, 0x555E, 0x86A1, 0x555F, 0x86A2, 0x5560, 0x86A3, 0x5561, 0xB7C8, 0x5562, 0x86A4, - 0x5563, 0x86A5, 0x5564, 0xC6A1, 0x5565, 0xC9B6, 0x5566, 0xC0B2, 0x5567, 0xDFF5, 0x5568, 0x86A6, 0x5569, 0x86A7, 0x556A, 0xC5BE, - 0x556B, 0x86A8, 0x556C, 0xD8C4, 0x556D, 0xDFF9, 0x556E, 0xC4F6, 0x556F, 0x86A9, 0x5570, 0x86AA, 0x5571, 0x86AB, 0x5572, 0x86AC, - 0x5573, 0x86AD, 0x5574, 0x86AE, 0x5575, 0xE0A3, 0x5576, 0xE0A4, 0x5577, 0xE0A5, 0x5578, 0xD0A5, 0x5579, 0x86AF, 0x557A, 0x86B0, - 0x557B, 0xE0B4, 0x557C, 0xCCE4, 0x557D, 0x86B1, 0x557E, 0xE0B1, 0x557F, 0x86B2, 0x5580, 0xBFA6, 0x5581, 0xE0AF, 0x5582, 0xCEB9, - 0x5583, 0xE0AB, 0x5584, 0xC9C6, 0x5585, 0x86B3, 0x5586, 0x86B4, 0x5587, 0xC0AE, 0x5588, 0xE0AE, 0x5589, 0xBAED, 0x558A, 0xBAB0, - 0x558B, 0xE0A9, 0x558C, 0x86B5, 0x558D, 0x86B6, 0x558E, 0x86B7, 0x558F, 0xDFF6, 0x5590, 0x86B8, 0x5591, 0xE0B3, 0x5592, 0x86B9, - 0x5593, 0x86BA, 0x5594, 0xE0B8, 0x5595, 0x86BB, 0x5596, 0x86BC, 0x5597, 0x86BD, 0x5598, 0xB4AD, 0x5599, 0xE0B9, 0x559A, 0x86BE, - 0x559B, 0x86BF, 0x559C, 0xCFB2, 0x559D, 0xBAC8, 0x559E, 0x86C0, 0x559F, 0xE0B0, 0x55A0, 0x86C1, 0x55A1, 0x86C2, 0x55A2, 0x86C3, - 0x55A3, 0x86C4, 0x55A4, 0x86C5, 0x55A5, 0x86C6, 0x55A6, 0x86C7, 0x55A7, 0xD0FA, 0x55A8, 0x86C8, 0x55A9, 0x86C9, 0x55AA, 0x86CA, - 0x55AB, 0x86CB, 0x55AC, 0x86CC, 0x55AD, 0x86CD, 0x55AE, 0x86CE, 0x55AF, 0x86CF, 0x55B0, 0x86D0, 0x55B1, 0xE0AC, 0x55B2, 0x86D1, - 0x55B3, 0xD4FB, 0x55B4, 0x86D2, 0x55B5, 0xDFF7, 0x55B6, 0x86D3, 0x55B7, 0xC5E7, 0x55B8, 0x86D4, 0x55B9, 0xE0AD, 0x55BA, 0x86D5, - 0x55BB, 0xD3F7, 0x55BC, 0x86D6, 0x55BD, 0xE0B6, 0x55BE, 0xE0B7, 0x55BF, 0x86D7, 0x55C0, 0x86D8, 0x55C1, 0x86D9, 0x55C2, 0x86DA, - 0x55C3, 0x86DB, 0x55C4, 0xE0C4, 0x55C5, 0xD0E1, 0x55C6, 0x86DC, 0x55C7, 0x86DD, 0x55C8, 0x86DE, 0x55C9, 0xE0BC, 0x55CA, 0x86DF, - 0x55CB, 0x86E0, 0x55CC, 0xE0C9, 0x55CD, 0xE0CA, 0x55CE, 0x86E1, 0x55CF, 0x86E2, 0x55D0, 0x86E3, 0x55D1, 0xE0BE, 0x55D2, 0xE0AA, - 0x55D3, 0xC9A4, 0x55D4, 0xE0C1, 0x55D5, 0x86E4, 0x55D6, 0xE0B2, 0x55D7, 0x86E5, 0x55D8, 0x86E6, 0x55D9, 0x86E7, 0x55DA, 0x86E8, - 0x55DB, 0x86E9, 0x55DC, 0xCAC8, 0x55DD, 0xE0C3, 0x55DE, 0x86EA, 0x55DF, 0xE0B5, 0x55E0, 0x86EB, 0x55E1, 0xCECB, 0x55E2, 0x86EC, - 0x55E3, 0xCBC3, 0x55E4, 0xE0CD, 0x55E5, 0xE0C6, 0x55E6, 0xE0C2, 0x55E7, 0x86ED, 0x55E8, 0xE0CB, 0x55E9, 0x86EE, 0x55EA, 0xE0BA, - 0x55EB, 0xE0BF, 0x55EC, 0xE0C0, 0x55ED, 0x86EF, 0x55EE, 0x86F0, 0x55EF, 0xE0C5, 0x55F0, 0x86F1, 0x55F1, 0x86F2, 0x55F2, 0xE0C7, - 0x55F3, 0xE0C8, 0x55F4, 0x86F3, 0x55F5, 0xE0CC, 0x55F6, 0x86F4, 0x55F7, 0xE0BB, 0x55F8, 0x86F5, 0x55F9, 0x86F6, 0x55FA, 0x86F7, - 0x55FB, 0x86F8, 0x55FC, 0x86F9, 0x55FD, 0xCBD4, 0x55FE, 0xE0D5, 0x55FF, 0x86FA, 0x5600, 0xE0D6, 0x5601, 0xE0D2, 0x5602, 0x86FB, - 0x5603, 0x86FC, 0x5604, 0x86FD, 0x5605, 0x86FE, 0x5606, 0x8740, 0x5607, 0x8741, 0x5608, 0xE0D0, 0x5609, 0xBCCE, 0x560A, 0x8742, - 0x560B, 0x8743, 0x560C, 0xE0D1, 0x560D, 0x8744, 0x560E, 0xB8C2, 0x560F, 0xD8C5, 0x5610, 0x8745, 0x5611, 0x8746, 0x5612, 0x8747, - 0x5613, 0x8748, 0x5614, 0x8749, 0x5615, 0x874A, 0x5616, 0x874B, 0x5617, 0x874C, 0x5618, 0xD0EA, 0x5619, 0x874D, 0x561A, 0x874E, - 0x561B, 0xC2EF, 0x561C, 0x874F, 0x561D, 0x8750, 0x561E, 0xE0CF, 0x561F, 0xE0BD, 0x5620, 0x8751, 0x5621, 0x8752, 0x5622, 0x8753, - 0x5623, 0xE0D4, 0x5624, 0xE0D3, 0x5625, 0x8754, 0x5626, 0x8755, 0x5627, 0xE0D7, 0x5628, 0x8756, 0x5629, 0x8757, 0x562A, 0x8758, - 0x562B, 0x8759, 0x562C, 0xE0DC, 0x562D, 0xE0D8, 0x562E, 0x875A, 0x562F, 0x875B, 0x5630, 0x875C, 0x5631, 0xD6F6, 0x5632, 0xB3B0, - 0x5633, 0x875D, 0x5634, 0xD7EC, 0x5635, 0x875E, 0x5636, 0xCBBB, 0x5637, 0x875F, 0x5638, 0x8760, 0x5639, 0xE0DA, 0x563A, 0x8761, - 0x563B, 0xCEFB, 0x563C, 0x8762, 0x563D, 0x8763, 0x563E, 0x8764, 0x563F, 0xBAD9, 0x5640, 0x8765, 0x5641, 0x8766, 0x5642, 0x8767, - 0x5643, 0x8768, 0x5644, 0x8769, 0x5645, 0x876A, 0x5646, 0x876B, 0x5647, 0x876C, 0x5648, 0x876D, 0x5649, 0x876E, 0x564A, 0x876F, - 0x564B, 0x8770, 0x564C, 0xE0E1, 0x564D, 0xE0DD, 0x564E, 0xD2AD, 0x564F, 0x8771, 0x5650, 0x8772, 0x5651, 0x8773, 0x5652, 0x8774, - 0x5653, 0x8775, 0x5654, 0xE0E2, 0x5655, 0x8776, 0x5656, 0x8777, 0x5657, 0xE0DB, 0x5658, 0xE0D9, 0x5659, 0xE0DF, 0x565A, 0x8778, - 0x565B, 0x8779, 0x565C, 0xE0E0, 0x565D, 0x877A, 0x565E, 0x877B, 0x565F, 0x877C, 0x5660, 0x877D, 0x5661, 0x877E, 0x5662, 0xE0DE, - 0x5663, 0x8780, 0x5664, 0xE0E4, 0x5665, 0x8781, 0x5666, 0x8782, 0x5667, 0x8783, 0x5668, 0xC6F7, 0x5669, 0xD8AC, 0x566A, 0xD4EB, - 0x566B, 0xE0E6, 0x566C, 0xCAC9, 0x566D, 0x8784, 0x566E, 0x8785, 0x566F, 0x8786, 0x5670, 0x8787, 0x5671, 0xE0E5, 0x5672, 0x8788, - 0x5673, 0x8789, 0x5674, 0x878A, 0x5675, 0x878B, 0x5676, 0xB8C1, 0x5677, 0x878C, 0x5678, 0x878D, 0x5679, 0x878E, 0x567A, 0x878F, - 0x567B, 0xE0E7, 0x567C, 0xE0E8, 0x567D, 0x8790, 0x567E, 0x8791, 0x567F, 0x8792, 0x5680, 0x8793, 0x5681, 0x8794, 0x5682, 0x8795, - 0x5683, 0x8796, 0x5684, 0x8797, 0x5685, 0xE0E9, 0x5686, 0xE0E3, 0x5687, 0x8798, 0x5688, 0x8799, 0x5689, 0x879A, 0x568A, 0x879B, - 0x568B, 0x879C, 0x568C, 0x879D, 0x568D, 0x879E, 0x568E, 0xBABF, 0x568F, 0xCCE7, 0x5690, 0x879F, 0x5691, 0x87A0, 0x5692, 0x87A1, - 0x5693, 0xE0EA, 0x5694, 0x87A2, 0x5695, 0x87A3, 0x5696, 0x87A4, 0x5697, 0x87A5, 0x5698, 0x87A6, 0x5699, 0x87A7, 0x569A, 0x87A8, - 0x569B, 0x87A9, 0x569C, 0x87AA, 0x569D, 0x87AB, 0x569E, 0x87AC, 0x569F, 0x87AD, 0x56A0, 0x87AE, 0x56A1, 0x87AF, 0x56A2, 0x87B0, - 0x56A3, 0xCFF9, 0x56A4, 0x87B1, 0x56A5, 0x87B2, 0x56A6, 0x87B3, 0x56A7, 0x87B4, 0x56A8, 0x87B5, 0x56A9, 0x87B6, 0x56AA, 0x87B7, - 0x56AB, 0x87B8, 0x56AC, 0x87B9, 0x56AD, 0x87BA, 0x56AE, 0x87BB, 0x56AF, 0xE0EB, 0x56B0, 0x87BC, 0x56B1, 0x87BD, 0x56B2, 0x87BE, - 0x56B3, 0x87BF, 0x56B4, 0x87C0, 0x56B5, 0x87C1, 0x56B6, 0x87C2, 0x56B7, 0xC8C2, 0x56B8, 0x87C3, 0x56B9, 0x87C4, 0x56BA, 0x87C5, - 0x56BB, 0x87C6, 0x56BC, 0xBDC0, 0x56BD, 0x87C7, 0x56BE, 0x87C8, 0x56BF, 0x87C9, 0x56C0, 0x87CA, 0x56C1, 0x87CB, 0x56C2, 0x87CC, - 0x56C3, 0x87CD, 0x56C4, 0x87CE, 0x56C5, 0x87CF, 0x56C6, 0x87D0, 0x56C7, 0x87D1, 0x56C8, 0x87D2, 0x56C9, 0x87D3, 0x56CA, 0xC4D2, - 0x56CB, 0x87D4, 0x56CC, 0x87D5, 0x56CD, 0x87D6, 0x56CE, 0x87D7, 0x56CF, 0x87D8, 0x56D0, 0x87D9, 0x56D1, 0x87DA, 0x56D2, 0x87DB, - 0x56D3, 0x87DC, 0x56D4, 0xE0EC, 0x56D5, 0x87DD, 0x56D6, 0x87DE, 0x56D7, 0xE0ED, 0x56D8, 0x87DF, 0x56D9, 0x87E0, 0x56DA, 0xC7F4, - 0x56DB, 0xCBC4, 0x56DC, 0x87E1, 0x56DD, 0xE0EE, 0x56DE, 0xBBD8, 0x56DF, 0xD8B6, 0x56E0, 0xD2F2, 0x56E1, 0xE0EF, 0x56E2, 0xCDC5, - 0x56E3, 0x87E2, 0x56E4, 0xB6DA, 0x56E5, 0x87E3, 0x56E6, 0x87E4, 0x56E7, 0x87E5, 0x56E8, 0x87E6, 0x56E9, 0x87E7, 0x56EA, 0x87E8, - 0x56EB, 0xE0F1, 0x56EC, 0x87E9, 0x56ED, 0xD4B0, 0x56EE, 0x87EA, 0x56EF, 0x87EB, 0x56F0, 0xC0A7, 0x56F1, 0xB4D1, 0x56F2, 0x87EC, - 0x56F3, 0x87ED, 0x56F4, 0xCEA7, 0x56F5, 0xE0F0, 0x56F6, 0x87EE, 0x56F7, 0x87EF, 0x56F8, 0x87F0, 0x56F9, 0xE0F2, 0x56FA, 0xB9CC, - 0x56FB, 0x87F1, 0x56FC, 0x87F2, 0x56FD, 0xB9FA, 0x56FE, 0xCDBC, 0x56FF, 0xE0F3, 0x5700, 0x87F3, 0x5701, 0x87F4, 0x5702, 0x87F5, - 0x5703, 0xC6D4, 0x5704, 0xE0F4, 0x5705, 0x87F6, 0x5706, 0xD4B2, 0x5707, 0x87F7, 0x5708, 0xC8A6, 0x5709, 0xE0F6, 0x570A, 0xE0F5, - 0x570B, 0x87F8, 0x570C, 0x87F9, 0x570D, 0x87FA, 0x570E, 0x87FB, 0x570F, 0x87FC, 0x5710, 0x87FD, 0x5711, 0x87FE, 0x5712, 0x8840, - 0x5713, 0x8841, 0x5714, 0x8842, 0x5715, 0x8843, 0x5716, 0x8844, 0x5717, 0x8845, 0x5718, 0x8846, 0x5719, 0x8847, 0x571A, 0x8848, - 0x571B, 0x8849, 0x571C, 0xE0F7, 0x571D, 0x884A, 0x571E, 0x884B, 0x571F, 0xCDC1, 0x5720, 0x884C, 0x5721, 0x884D, 0x5722, 0x884E, - 0x5723, 0xCAA5, 0x5724, 0x884F, 0x5725, 0x8850, 0x5726, 0x8851, 0x5727, 0x8852, 0x5728, 0xD4DA, 0x5729, 0xDBD7, 0x572A, 0xDBD9, - 0x572B, 0x8853, 0x572C, 0xDBD8, 0x572D, 0xB9E7, 0x572E, 0xDBDC, 0x572F, 0xDBDD, 0x5730, 0xB5D8, 0x5731, 0x8854, 0x5732, 0x8855, - 0x5733, 0xDBDA, 0x5734, 0x8856, 0x5735, 0x8857, 0x5736, 0x8858, 0x5737, 0x8859, 0x5738, 0x885A, 0x5739, 0xDBDB, 0x573A, 0xB3A1, - 0x573B, 0xDBDF, 0x573C, 0x885B, 0x573D, 0x885C, 0x573E, 0xBBF8, 0x573F, 0x885D, 0x5740, 0xD6B7, 0x5741, 0x885E, 0x5742, 0xDBE0, - 0x5743, 0x885F, 0x5744, 0x8860, 0x5745, 0x8861, 0x5746, 0x8862, 0x5747, 0xBEF9, 0x5748, 0x8863, 0x5749, 0x8864, 0x574A, 0xB7BB, - 0x574B, 0x8865, 0x574C, 0xDBD0, 0x574D, 0xCCAE, 0x574E, 0xBFB2, 0x574F, 0xBBB5, 0x5750, 0xD7F8, 0x5751, 0xBFD3, 0x5752, 0x8866, - 0x5753, 0x8867, 0x5754, 0x8868, 0x5755, 0x8869, 0x5756, 0x886A, 0x5757, 0xBFE9, 0x5758, 0x886B, 0x5759, 0x886C, 0x575A, 0xBCE1, - 0x575B, 0xCCB3, 0x575C, 0xDBDE, 0x575D, 0xB0D3, 0x575E, 0xCEEB, 0x575F, 0xB7D8, 0x5760, 0xD7B9, 0x5761, 0xC6C2, 0x5762, 0x886D, - 0x5763, 0x886E, 0x5764, 0xC0A4, 0x5765, 0x886F, 0x5766, 0xCCB9, 0x5767, 0x8870, 0x5768, 0xDBE7, 0x5769, 0xDBE1, 0x576A, 0xC6BA, - 0x576B, 0xDBE3, 0x576C, 0x8871, 0x576D, 0xDBE8, 0x576E, 0x8872, 0x576F, 0xC5F7, 0x5770, 0x8873, 0x5771, 0x8874, 0x5772, 0x8875, - 0x5773, 0xDBEA, 0x5774, 0x8876, 0x5775, 0x8877, 0x5776, 0xDBE9, 0x5777, 0xBFC0, 0x5778, 0x8878, 0x5779, 0x8879, 0x577A, 0x887A, - 0x577B, 0xDBE6, 0x577C, 0xDBE5, 0x577D, 0x887B, 0x577E, 0x887C, 0x577F, 0x887D, 0x5780, 0x887E, 0x5781, 0x8880, 0x5782, 0xB4B9, - 0x5783, 0xC0AC, 0x5784, 0xC2A2, 0x5785, 0xDBE2, 0x5786, 0xDBE4, 0x5787, 0x8881, 0x5788, 0x8882, 0x5789, 0x8883, 0x578A, 0x8884, - 0x578B, 0xD0CD, 0x578C, 0xDBED, 0x578D, 0x8885, 0x578E, 0x8886, 0x578F, 0x8887, 0x5790, 0x8888, 0x5791, 0x8889, 0x5792, 0xC0DD, - 0x5793, 0xDBF2, 0x5794, 0x888A, 0x5795, 0x888B, 0x5796, 0x888C, 0x5797, 0x888D, 0x5798, 0x888E, 0x5799, 0x888F, 0x579A, 0x8890, - 0x579B, 0xB6E2, 0x579C, 0x8891, 0x579D, 0x8892, 0x579E, 0x8893, 0x579F, 0x8894, 0x57A0, 0xDBF3, 0x57A1, 0xDBD2, 0x57A2, 0xB9B8, - 0x57A3, 0xD4AB, 0x57A4, 0xDBEC, 0x57A5, 0x8895, 0x57A6, 0xBFD1, 0x57A7, 0xDBF0, 0x57A8, 0x8896, 0x57A9, 0xDBD1, 0x57AA, 0x8897, - 0x57AB, 0xB5E6, 0x57AC, 0x8898, 0x57AD, 0xDBEB, 0x57AE, 0xBFE5, 0x57AF, 0x8899, 0x57B0, 0x889A, 0x57B1, 0x889B, 0x57B2, 0xDBEE, - 0x57B3, 0x889C, 0x57B4, 0xDBF1, 0x57B5, 0x889D, 0x57B6, 0x889E, 0x57B7, 0x889F, 0x57B8, 0xDBF9, 0x57B9, 0x88A0, 0x57BA, 0x88A1, - 0x57BB, 0x88A2, 0x57BC, 0x88A3, 0x57BD, 0x88A4, 0x57BE, 0x88A5, 0x57BF, 0x88A6, 0x57C0, 0x88A7, 0x57C1, 0x88A8, 0x57C2, 0xB9A1, - 0x57C3, 0xB0A3, 0x57C4, 0x88A9, 0x57C5, 0x88AA, 0x57C6, 0x88AB, 0x57C7, 0x88AC, 0x57C8, 0x88AD, 0x57C9, 0x88AE, 0x57CA, 0x88AF, - 0x57CB, 0xC2F1, 0x57CC, 0x88B0, 0x57CD, 0x88B1, 0x57CE, 0xB3C7, 0x57CF, 0xDBEF, 0x57D0, 0x88B2, 0x57D1, 0x88B3, 0x57D2, 0xDBF8, - 0x57D3, 0x88B4, 0x57D4, 0xC6D2, 0x57D5, 0xDBF4, 0x57D6, 0x88B5, 0x57D7, 0x88B6, 0x57D8, 0xDBF5, 0x57D9, 0xDBF7, 0x57DA, 0xDBF6, - 0x57DB, 0x88B7, 0x57DC, 0x88B8, 0x57DD, 0xDBFE, 0x57DE, 0x88B9, 0x57DF, 0xD3F2, 0x57E0, 0xB2BA, 0x57E1, 0x88BA, 0x57E2, 0x88BB, - 0x57E3, 0x88BC, 0x57E4, 0xDBFD, 0x57E5, 0x88BD, 0x57E6, 0x88BE, 0x57E7, 0x88BF, 0x57E8, 0x88C0, 0x57E9, 0x88C1, 0x57EA, 0x88C2, - 0x57EB, 0x88C3, 0x57EC, 0x88C4, 0x57ED, 0xDCA4, 0x57EE, 0x88C5, 0x57EF, 0xDBFB, 0x57F0, 0x88C6, 0x57F1, 0x88C7, 0x57F2, 0x88C8, - 0x57F3, 0x88C9, 0x57F4, 0xDBFA, 0x57F5, 0x88CA, 0x57F6, 0x88CB, 0x57F7, 0x88CC, 0x57F8, 0xDBFC, 0x57F9, 0xC5E0, 0x57FA, 0xBBF9, - 0x57FB, 0x88CD, 0x57FC, 0x88CE, 0x57FD, 0xDCA3, 0x57FE, 0x88CF, 0x57FF, 0x88D0, 0x5800, 0xDCA5, 0x5801, 0x88D1, 0x5802, 0xCCC3, - 0x5803, 0x88D2, 0x5804, 0x88D3, 0x5805, 0x88D4, 0x5806, 0xB6D1, 0x5807, 0xDDC0, 0x5808, 0x88D5, 0x5809, 0x88D6, 0x580A, 0x88D7, - 0x580B, 0xDCA1, 0x580C, 0x88D8, 0x580D, 0xDCA2, 0x580E, 0x88D9, 0x580F, 0x88DA, 0x5810, 0x88DB, 0x5811, 0xC7B5, 0x5812, 0x88DC, - 0x5813, 0x88DD, 0x5814, 0x88DE, 0x5815, 0xB6E9, 0x5816, 0x88DF, 0x5817, 0x88E0, 0x5818, 0x88E1, 0x5819, 0xDCA7, 0x581A, 0x88E2, - 0x581B, 0x88E3, 0x581C, 0x88E4, 0x581D, 0x88E5, 0x581E, 0xDCA6, 0x581F, 0x88E6, 0x5820, 0xDCA9, 0x5821, 0xB1A4, 0x5822, 0x88E7, - 0x5823, 0x88E8, 0x5824, 0xB5CC, 0x5825, 0x88E9, 0x5826, 0x88EA, 0x5827, 0x88EB, 0x5828, 0x88EC, 0x5829, 0x88ED, 0x582A, 0xBFB0, - 0x582B, 0x88EE, 0x582C, 0x88EF, 0x582D, 0x88F0, 0x582E, 0x88F1, 0x582F, 0x88F2, 0x5830, 0xD1DF, 0x5831, 0x88F3, 0x5832, 0x88F4, - 0x5833, 0x88F5, 0x5834, 0x88F6, 0x5835, 0xB6C2, 0x5836, 0x88F7, 0x5837, 0x88F8, 0x5838, 0x88F9, 0x5839, 0x88FA, 0x583A, 0x88FB, - 0x583B, 0x88FC, 0x583C, 0x88FD, 0x583D, 0x88FE, 0x583E, 0x8940, 0x583F, 0x8941, 0x5840, 0x8942, 0x5841, 0x8943, 0x5842, 0x8944, - 0x5843, 0x8945, 0x5844, 0xDCA8, 0x5845, 0x8946, 0x5846, 0x8947, 0x5847, 0x8948, 0x5848, 0x8949, 0x5849, 0x894A, 0x584A, 0x894B, - 0x584B, 0x894C, 0x584C, 0xCBFA, 0x584D, 0xEBF3, 0x584E, 0x894D, 0x584F, 0x894E, 0x5850, 0x894F, 0x5851, 0xCBDC, 0x5852, 0x8950, - 0x5853, 0x8951, 0x5854, 0xCBFE, 0x5855, 0x8952, 0x5856, 0x8953, 0x5857, 0x8954, 0x5858, 0xCCC1, 0x5859, 0x8955, 0x585A, 0x8956, - 0x585B, 0x8957, 0x585C, 0x8958, 0x585D, 0x8959, 0x585E, 0xC8FB, 0x585F, 0x895A, 0x5860, 0x895B, 0x5861, 0x895C, 0x5862, 0x895D, - 0x5863, 0x895E, 0x5864, 0x895F, 0x5865, 0xDCAA, 0x5866, 0x8960, 0x5867, 0x8961, 0x5868, 0x8962, 0x5869, 0x8963, 0x586A, 0x8964, - 0x586B, 0xCCEE, 0x586C, 0xDCAB, 0x586D, 0x8965, 0x586E, 0x8966, 0x586F, 0x8967, 0x5870, 0x8968, 0x5871, 0x8969, 0x5872, 0x896A, - 0x5873, 0x896B, 0x5874, 0x896C, 0x5875, 0x896D, 0x5876, 0x896E, 0x5877, 0x896F, 0x5878, 0x8970, 0x5879, 0x8971, 0x587A, 0x8972, - 0x587B, 0x8973, 0x587C, 0x8974, 0x587D, 0x8975, 0x587E, 0xDBD3, 0x587F, 0x8976, 0x5880, 0xDCAF, 0x5881, 0xDCAC, 0x5882, 0x8977, - 0x5883, 0xBEB3, 0x5884, 0x8978, 0x5885, 0xCAFB, 0x5886, 0x8979, 0x5887, 0x897A, 0x5888, 0x897B, 0x5889, 0xDCAD, 0x588A, 0x897C, - 0x588B, 0x897D, 0x588C, 0x897E, 0x588D, 0x8980, 0x588E, 0x8981, 0x588F, 0x8982, 0x5890, 0x8983, 0x5891, 0x8984, 0x5892, 0xC9CA, - 0x5893, 0xC4B9, 0x5894, 0x8985, 0x5895, 0x8986, 0x5896, 0x8987, 0x5897, 0x8988, 0x5898, 0x8989, 0x5899, 0xC7BD, 0x589A, 0xDCAE, - 0x589B, 0x898A, 0x589C, 0x898B, 0x589D, 0x898C, 0x589E, 0xD4F6, 0x589F, 0xD0E6, 0x58A0, 0x898D, 0x58A1, 0x898E, 0x58A2, 0x898F, - 0x58A3, 0x8990, 0x58A4, 0x8991, 0x58A5, 0x8992, 0x58A6, 0x8993, 0x58A7, 0x8994, 0x58A8, 0xC4AB, 0x58A9, 0xB6D5, 0x58AA, 0x8995, - 0x58AB, 0x8996, 0x58AC, 0x8997, 0x58AD, 0x8998, 0x58AE, 0x8999, 0x58AF, 0x899A, 0x58B0, 0x899B, 0x58B1, 0x899C, 0x58B2, 0x899D, - 0x58B3, 0x899E, 0x58B4, 0x899F, 0x58B5, 0x89A0, 0x58B6, 0x89A1, 0x58B7, 0x89A2, 0x58B8, 0x89A3, 0x58B9, 0x89A4, 0x58BA, 0x89A5, - 0x58BB, 0x89A6, 0x58BC, 0xDBD4, 0x58BD, 0x89A7, 0x58BE, 0x89A8, 0x58BF, 0x89A9, 0x58C0, 0x89AA, 0x58C1, 0xB1DA, 0x58C2, 0x89AB, - 0x58C3, 0x89AC, 0x58C4, 0x89AD, 0x58C5, 0xDBD5, 0x58C6, 0x89AE, 0x58C7, 0x89AF, 0x58C8, 0x89B0, 0x58C9, 0x89B1, 0x58CA, 0x89B2, - 0x58CB, 0x89B3, 0x58CC, 0x89B4, 0x58CD, 0x89B5, 0x58CE, 0x89B6, 0x58CF, 0x89B7, 0x58D0, 0x89B8, 0x58D1, 0xDBD6, 0x58D2, 0x89B9, - 0x58D3, 0x89BA, 0x58D4, 0x89BB, 0x58D5, 0xBABE, 0x58D6, 0x89BC, 0x58D7, 0x89BD, 0x58D8, 0x89BE, 0x58D9, 0x89BF, 0x58DA, 0x89C0, - 0x58DB, 0x89C1, 0x58DC, 0x89C2, 0x58DD, 0x89C3, 0x58DE, 0x89C4, 0x58DF, 0x89C5, 0x58E0, 0x89C6, 0x58E1, 0x89C7, 0x58E2, 0x89C8, - 0x58E3, 0x89C9, 0x58E4, 0xC8C0, 0x58E5, 0x89CA, 0x58E6, 0x89CB, 0x58E7, 0x89CC, 0x58E8, 0x89CD, 0x58E9, 0x89CE, 0x58EA, 0x89CF, - 0x58EB, 0xCABF, 0x58EC, 0xC8C9, 0x58ED, 0x89D0, 0x58EE, 0xD7B3, 0x58EF, 0x89D1, 0x58F0, 0xC9F9, 0x58F1, 0x89D2, 0x58F2, 0x89D3, - 0x58F3, 0xBFC7, 0x58F4, 0x89D4, 0x58F5, 0x89D5, 0x58F6, 0xBAF8, 0x58F7, 0x89D6, 0x58F8, 0x89D7, 0x58F9, 0xD2BC, 0x58FA, 0x89D8, - 0x58FB, 0x89D9, 0x58FC, 0x89DA, 0x58FD, 0x89DB, 0x58FE, 0x89DC, 0x58FF, 0x89DD, 0x5900, 0x89DE, 0x5901, 0x89DF, 0x5902, 0xE2BA, - 0x5903, 0x89E0, 0x5904, 0xB4A6, 0x5905, 0x89E1, 0x5906, 0x89E2, 0x5907, 0xB1B8, 0x5908, 0x89E3, 0x5909, 0x89E4, 0x590A, 0x89E5, - 0x590B, 0x89E6, 0x590C, 0x89E7, 0x590D, 0xB8B4, 0x590E, 0x89E8, 0x590F, 0xCFC4, 0x5910, 0x89E9, 0x5911, 0x89EA, 0x5912, 0x89EB, - 0x5913, 0x89EC, 0x5914, 0xD9E7, 0x5915, 0xCFA6, 0x5916, 0xCDE2, 0x5917, 0x89ED, 0x5918, 0x89EE, 0x5919, 0xD9ED, 0x591A, 0xB6E0, - 0x591B, 0x89EF, 0x591C, 0xD2B9, 0x591D, 0x89F0, 0x591E, 0x89F1, 0x591F, 0xB9BB, 0x5920, 0x89F2, 0x5921, 0x89F3, 0x5922, 0x89F4, - 0x5923, 0x89F5, 0x5924, 0xE2B9, 0x5925, 0xE2B7, 0x5926, 0x89F6, 0x5927, 0xB4F3, 0x5928, 0x89F7, 0x5929, 0xCCEC, 0x592A, 0xCCAB, - 0x592B, 0xB7F2, 0x592C, 0x89F8, 0x592D, 0xD8B2, 0x592E, 0xD1EB, 0x592F, 0xBABB, 0x5930, 0x89F9, 0x5931, 0xCAA7, 0x5932, 0x89FA, - 0x5933, 0x89FB, 0x5934, 0xCDB7, 0x5935, 0x89FC, 0x5936, 0x89FD, 0x5937, 0xD2C4, 0x5938, 0xBFE4, 0x5939, 0xBCD0, 0x593A, 0xB6E1, - 0x593B, 0x89FE, 0x593C, 0xDEC5, 0x593D, 0x8A40, 0x593E, 0x8A41, 0x593F, 0x8A42, 0x5940, 0x8A43, 0x5941, 0xDEC6, 0x5942, 0xDBBC, - 0x5943, 0x8A44, 0x5944, 0xD1D9, 0x5945, 0x8A45, 0x5946, 0x8A46, 0x5947, 0xC6E6, 0x5948, 0xC4CE, 0x5949, 0xB7EE, 0x594A, 0x8A47, - 0x594B, 0xB7DC, 0x594C, 0x8A48, 0x594D, 0x8A49, 0x594E, 0xBFFC, 0x594F, 0xD7E0, 0x5950, 0x8A4A, 0x5951, 0xC6F5, 0x5952, 0x8A4B, - 0x5953, 0x8A4C, 0x5954, 0xB1BC, 0x5955, 0xDEC8, 0x5956, 0xBDB1, 0x5957, 0xCCD7, 0x5958, 0xDECA, 0x5959, 0x8A4D, 0x595A, 0xDEC9, - 0x595B, 0x8A4E, 0x595C, 0x8A4F, 0x595D, 0x8A50, 0x595E, 0x8A51, 0x595F, 0x8A52, 0x5960, 0xB5EC, 0x5961, 0x8A53, 0x5962, 0xC9DD, - 0x5963, 0x8A54, 0x5964, 0x8A55, 0x5965, 0xB0C2, 0x5966, 0x8A56, 0x5967, 0x8A57, 0x5968, 0x8A58, 0x5969, 0x8A59, 0x596A, 0x8A5A, - 0x596B, 0x8A5B, 0x596C, 0x8A5C, 0x596D, 0x8A5D, 0x596E, 0x8A5E, 0x596F, 0x8A5F, 0x5970, 0x8A60, 0x5971, 0x8A61, 0x5972, 0x8A62, - 0x5973, 0xC5AE, 0x5974, 0xC5AB, 0x5975, 0x8A63, 0x5976, 0xC4CC, 0x5977, 0x8A64, 0x5978, 0xBCE9, 0x5979, 0xCBFD, 0x597A, 0x8A65, - 0x597B, 0x8A66, 0x597C, 0x8A67, 0x597D, 0xBAC3, 0x597E, 0x8A68, 0x597F, 0x8A69, 0x5980, 0x8A6A, 0x5981, 0xE5F9, 0x5982, 0xC8E7, - 0x5983, 0xE5FA, 0x5984, 0xCDFD, 0x5985, 0x8A6B, 0x5986, 0xD7B1, 0x5987, 0xB8BE, 0x5988, 0xC2E8, 0x5989, 0x8A6C, 0x598A, 0xC8D1, - 0x598B, 0x8A6D, 0x598C, 0x8A6E, 0x598D, 0xE5FB, 0x598E, 0x8A6F, 0x598F, 0x8A70, 0x5990, 0x8A71, 0x5991, 0x8A72, 0x5992, 0xB6CA, - 0x5993, 0xBCCB, 0x5994, 0x8A73, 0x5995, 0x8A74, 0x5996, 0xD1FD, 0x5997, 0xE6A1, 0x5998, 0x8A75, 0x5999, 0xC3EE, 0x599A, 0x8A76, - 0x599B, 0x8A77, 0x599C, 0x8A78, 0x599D, 0x8A79, 0x599E, 0xE6A4, 0x599F, 0x8A7A, 0x59A0, 0x8A7B, 0x59A1, 0x8A7C, 0x59A2, 0x8A7D, - 0x59A3, 0xE5FE, 0x59A4, 0xE6A5, 0x59A5, 0xCDD7, 0x59A6, 0x8A7E, 0x59A7, 0x8A80, 0x59A8, 0xB7C1, 0x59A9, 0xE5FC, 0x59AA, 0xE5FD, - 0x59AB, 0xE6A3, 0x59AC, 0x8A81, 0x59AD, 0x8A82, 0x59AE, 0xC4DD, 0x59AF, 0xE6A8, 0x59B0, 0x8A83, 0x59B1, 0x8A84, 0x59B2, 0xE6A7, - 0x59B3, 0x8A85, 0x59B4, 0x8A86, 0x59B5, 0x8A87, 0x59B6, 0x8A88, 0x59B7, 0x8A89, 0x59B8, 0x8A8A, 0x59B9, 0xC3C3, 0x59BA, 0x8A8B, - 0x59BB, 0xC6DE, 0x59BC, 0x8A8C, 0x59BD, 0x8A8D, 0x59BE, 0xE6AA, 0x59BF, 0x8A8E, 0x59C0, 0x8A8F, 0x59C1, 0x8A90, 0x59C2, 0x8A91, - 0x59C3, 0x8A92, 0x59C4, 0x8A93, 0x59C5, 0x8A94, 0x59C6, 0xC4B7, 0x59C7, 0x8A95, 0x59C8, 0x8A96, 0x59C9, 0x8A97, 0x59CA, 0xE6A2, - 0x59CB, 0xCABC, 0x59CC, 0x8A98, 0x59CD, 0x8A99, 0x59CE, 0x8A9A, 0x59CF, 0x8A9B, 0x59D0, 0xBDE3, 0x59D1, 0xB9C3, 0x59D2, 0xE6A6, - 0x59D3, 0xD0D5, 0x59D4, 0xCEAF, 0x59D5, 0x8A9C, 0x59D6, 0x8A9D, 0x59D7, 0xE6A9, 0x59D8, 0xE6B0, 0x59D9, 0x8A9E, 0x59DA, 0xD2A6, - 0x59DB, 0x8A9F, 0x59DC, 0xBDAA, 0x59DD, 0xE6AD, 0x59DE, 0x8AA0, 0x59DF, 0x8AA1, 0x59E0, 0x8AA2, 0x59E1, 0x8AA3, 0x59E2, 0x8AA4, - 0x59E3, 0xE6AF, 0x59E4, 0x8AA5, 0x59E5, 0xC0D1, 0x59E6, 0x8AA6, 0x59E7, 0x8AA7, 0x59E8, 0xD2CC, 0x59E9, 0x8AA8, 0x59EA, 0x8AA9, - 0x59EB, 0x8AAA, 0x59EC, 0xBCA7, 0x59ED, 0x8AAB, 0x59EE, 0x8AAC, 0x59EF, 0x8AAD, 0x59F0, 0x8AAE, 0x59F1, 0x8AAF, 0x59F2, 0x8AB0, - 0x59F3, 0x8AB1, 0x59F4, 0x8AB2, 0x59F5, 0x8AB3, 0x59F6, 0x8AB4, 0x59F7, 0x8AB5, 0x59F8, 0x8AB6, 0x59F9, 0xE6B1, 0x59FA, 0x8AB7, - 0x59FB, 0xD2F6, 0x59FC, 0x8AB8, 0x59FD, 0x8AB9, 0x59FE, 0x8ABA, 0x59FF, 0xD7CB, 0x5A00, 0x8ABB, 0x5A01, 0xCDFE, 0x5A02, 0x8ABC, - 0x5A03, 0xCDDE, 0x5A04, 0xC2A6, 0x5A05, 0xE6AB, 0x5A06, 0xE6AC, 0x5A07, 0xBDBF, 0x5A08, 0xE6AE, 0x5A09, 0xE6B3, 0x5A0A, 0x8ABD, - 0x5A0B, 0x8ABE, 0x5A0C, 0xE6B2, 0x5A0D, 0x8ABF, 0x5A0E, 0x8AC0, 0x5A0F, 0x8AC1, 0x5A10, 0x8AC2, 0x5A11, 0xE6B6, 0x5A12, 0x8AC3, - 0x5A13, 0xE6B8, 0x5A14, 0x8AC4, 0x5A15, 0x8AC5, 0x5A16, 0x8AC6, 0x5A17, 0x8AC7, 0x5A18, 0xC4EF, 0x5A19, 0x8AC8, 0x5A1A, 0x8AC9, - 0x5A1B, 0x8ACA, 0x5A1C, 0xC4C8, 0x5A1D, 0x8ACB, 0x5A1E, 0x8ACC, 0x5A1F, 0xBEEA, 0x5A20, 0xC9EF, 0x5A21, 0x8ACD, 0x5A22, 0x8ACE, - 0x5A23, 0xE6B7, 0x5A24, 0x8ACF, 0x5A25, 0xB6F0, 0x5A26, 0x8AD0, 0x5A27, 0x8AD1, 0x5A28, 0x8AD2, 0x5A29, 0xC3E4, 0x5A2A, 0x8AD3, - 0x5A2B, 0x8AD4, 0x5A2C, 0x8AD5, 0x5A2D, 0x8AD6, 0x5A2E, 0x8AD7, 0x5A2F, 0x8AD8, 0x5A30, 0x8AD9, 0x5A31, 0xD3E9, 0x5A32, 0xE6B4, - 0x5A33, 0x8ADA, 0x5A34, 0xE6B5, 0x5A35, 0x8ADB, 0x5A36, 0xC8A2, 0x5A37, 0x8ADC, 0x5A38, 0x8ADD, 0x5A39, 0x8ADE, 0x5A3A, 0x8ADF, - 0x5A3B, 0x8AE0, 0x5A3C, 0xE6BD, 0x5A3D, 0x8AE1, 0x5A3E, 0x8AE2, 0x5A3F, 0x8AE3, 0x5A40, 0xE6B9, 0x5A41, 0x8AE4, 0x5A42, 0x8AE5, - 0x5A43, 0x8AE6, 0x5A44, 0x8AE7, 0x5A45, 0x8AE8, 0x5A46, 0xC6C5, 0x5A47, 0x8AE9, 0x5A48, 0x8AEA, 0x5A49, 0xCDF1, 0x5A4A, 0xE6BB, - 0x5A4B, 0x8AEB, 0x5A4C, 0x8AEC, 0x5A4D, 0x8AED, 0x5A4E, 0x8AEE, 0x5A4F, 0x8AEF, 0x5A50, 0x8AF0, 0x5A51, 0x8AF1, 0x5A52, 0x8AF2, - 0x5A53, 0x8AF3, 0x5A54, 0x8AF4, 0x5A55, 0xE6BC, 0x5A56, 0x8AF5, 0x5A57, 0x8AF6, 0x5A58, 0x8AF7, 0x5A59, 0x8AF8, 0x5A5A, 0xBBE9, - 0x5A5B, 0x8AF9, 0x5A5C, 0x8AFA, 0x5A5D, 0x8AFB, 0x5A5E, 0x8AFC, 0x5A5F, 0x8AFD, 0x5A60, 0x8AFE, 0x5A61, 0x8B40, 0x5A62, 0xE6BE, - 0x5A63, 0x8B41, 0x5A64, 0x8B42, 0x5A65, 0x8B43, 0x5A66, 0x8B44, 0x5A67, 0xE6BA, 0x5A68, 0x8B45, 0x5A69, 0x8B46, 0x5A6A, 0xC0B7, - 0x5A6B, 0x8B47, 0x5A6C, 0x8B48, 0x5A6D, 0x8B49, 0x5A6E, 0x8B4A, 0x5A6F, 0x8B4B, 0x5A70, 0x8B4C, 0x5A71, 0x8B4D, 0x5A72, 0x8B4E, - 0x5A73, 0x8B4F, 0x5A74, 0xD3A4, 0x5A75, 0xE6BF, 0x5A76, 0xC9F4, 0x5A77, 0xE6C3, 0x5A78, 0x8B50, 0x5A79, 0x8B51, 0x5A7A, 0xE6C4, - 0x5A7B, 0x8B52, 0x5A7C, 0x8B53, 0x5A7D, 0x8B54, 0x5A7E, 0x8B55, 0x5A7F, 0xD0F6, 0x5A80, 0x8B56, 0x5A81, 0x8B57, 0x5A82, 0x8B58, - 0x5A83, 0x8B59, 0x5A84, 0x8B5A, 0x5A85, 0x8B5B, 0x5A86, 0x8B5C, 0x5A87, 0x8B5D, 0x5A88, 0x8B5E, 0x5A89, 0x8B5F, 0x5A8A, 0x8B60, - 0x5A8B, 0x8B61, 0x5A8C, 0x8B62, 0x5A8D, 0x8B63, 0x5A8E, 0x8B64, 0x5A8F, 0x8B65, 0x5A90, 0x8B66, 0x5A91, 0x8B67, 0x5A92, 0xC3BD, - 0x5A93, 0x8B68, 0x5A94, 0x8B69, 0x5A95, 0x8B6A, 0x5A96, 0x8B6B, 0x5A97, 0x8B6C, 0x5A98, 0x8B6D, 0x5A99, 0x8B6E, 0x5A9A, 0xC3C4, - 0x5A9B, 0xE6C2, 0x5A9C, 0x8B6F, 0x5A9D, 0x8B70, 0x5A9E, 0x8B71, 0x5A9F, 0x8B72, 0x5AA0, 0x8B73, 0x5AA1, 0x8B74, 0x5AA2, 0x8B75, - 0x5AA3, 0x8B76, 0x5AA4, 0x8B77, 0x5AA5, 0x8B78, 0x5AA6, 0x8B79, 0x5AA7, 0x8B7A, 0x5AA8, 0x8B7B, 0x5AA9, 0x8B7C, 0x5AAA, 0xE6C1, - 0x5AAB, 0x8B7D, 0x5AAC, 0x8B7E, 0x5AAD, 0x8B80, 0x5AAE, 0x8B81, 0x5AAF, 0x8B82, 0x5AB0, 0x8B83, 0x5AB1, 0x8B84, 0x5AB2, 0xE6C7, - 0x5AB3, 0xCFB1, 0x5AB4, 0x8B85, 0x5AB5, 0xEBF4, 0x5AB6, 0x8B86, 0x5AB7, 0x8B87, 0x5AB8, 0xE6CA, 0x5AB9, 0x8B88, 0x5ABA, 0x8B89, - 0x5ABB, 0x8B8A, 0x5ABC, 0x8B8B, 0x5ABD, 0x8B8C, 0x5ABE, 0xE6C5, 0x5ABF, 0x8B8D, 0x5AC0, 0x8B8E, 0x5AC1, 0xBCDE, 0x5AC2, 0xC9A9, - 0x5AC3, 0x8B8F, 0x5AC4, 0x8B90, 0x5AC5, 0x8B91, 0x5AC6, 0x8B92, 0x5AC7, 0x8B93, 0x5AC8, 0x8B94, 0x5AC9, 0xBCB5, 0x5ACA, 0x8B95, - 0x5ACB, 0x8B96, 0x5ACC, 0xCFD3, 0x5ACD, 0x8B97, 0x5ACE, 0x8B98, 0x5ACF, 0x8B99, 0x5AD0, 0x8B9A, 0x5AD1, 0x8B9B, 0x5AD2, 0xE6C8, - 0x5AD3, 0x8B9C, 0x5AD4, 0xE6C9, 0x5AD5, 0x8B9D, 0x5AD6, 0xE6CE, 0x5AD7, 0x8B9E, 0x5AD8, 0xE6D0, 0x5AD9, 0x8B9F, 0x5ADA, 0x8BA0, - 0x5ADB, 0x8BA1, 0x5ADC, 0xE6D1, 0x5ADD, 0x8BA2, 0x5ADE, 0x8BA3, 0x5ADF, 0x8BA4, 0x5AE0, 0xE6CB, 0x5AE1, 0xB5D5, 0x5AE2, 0x8BA5, - 0x5AE3, 0xE6CC, 0x5AE4, 0x8BA6, 0x5AE5, 0x8BA7, 0x5AE6, 0xE6CF, 0x5AE7, 0x8BA8, 0x5AE8, 0x8BA9, 0x5AE9, 0xC4DB, 0x5AEA, 0x8BAA, - 0x5AEB, 0xE6C6, 0x5AEC, 0x8BAB, 0x5AED, 0x8BAC, 0x5AEE, 0x8BAD, 0x5AEF, 0x8BAE, 0x5AF0, 0x8BAF, 0x5AF1, 0xE6CD, 0x5AF2, 0x8BB0, - 0x5AF3, 0x8BB1, 0x5AF4, 0x8BB2, 0x5AF5, 0x8BB3, 0x5AF6, 0x8BB4, 0x5AF7, 0x8BB5, 0x5AF8, 0x8BB6, 0x5AF9, 0x8BB7, 0x5AFA, 0x8BB8, - 0x5AFB, 0x8BB9, 0x5AFC, 0x8BBA, 0x5AFD, 0x8BBB, 0x5AFE, 0x8BBC, 0x5AFF, 0x8BBD, 0x5B00, 0x8BBE, 0x5B01, 0x8BBF, 0x5B02, 0x8BC0, - 0x5B03, 0x8BC1, 0x5B04, 0x8BC2, 0x5B05, 0x8BC3, 0x5B06, 0x8BC4, 0x5B07, 0x8BC5, 0x5B08, 0x8BC6, 0x5B09, 0xE6D2, 0x5B0A, 0x8BC7, - 0x5B0B, 0x8BC8, 0x5B0C, 0x8BC9, 0x5B0D, 0x8BCA, 0x5B0E, 0x8BCB, 0x5B0F, 0x8BCC, 0x5B10, 0x8BCD, 0x5B11, 0x8BCE, 0x5B12, 0x8BCF, - 0x5B13, 0x8BD0, 0x5B14, 0x8BD1, 0x5B15, 0x8BD2, 0x5B16, 0xE6D4, 0x5B17, 0xE6D3, 0x5B18, 0x8BD3, 0x5B19, 0x8BD4, 0x5B1A, 0x8BD5, - 0x5B1B, 0x8BD6, 0x5B1C, 0x8BD7, 0x5B1D, 0x8BD8, 0x5B1E, 0x8BD9, 0x5B1F, 0x8BDA, 0x5B20, 0x8BDB, 0x5B21, 0x8BDC, 0x5B22, 0x8BDD, - 0x5B23, 0x8BDE, 0x5B24, 0x8BDF, 0x5B25, 0x8BE0, 0x5B26, 0x8BE1, 0x5B27, 0x8BE2, 0x5B28, 0x8BE3, 0x5B29, 0x8BE4, 0x5B2A, 0x8BE5, - 0x5B2B, 0x8BE6, 0x5B2C, 0x8BE7, 0x5B2D, 0x8BE8, 0x5B2E, 0x8BE9, 0x5B2F, 0x8BEA, 0x5B30, 0x8BEB, 0x5B31, 0x8BEC, 0x5B32, 0xE6D5, - 0x5B33, 0x8BED, 0x5B34, 0xD9F8, 0x5B35, 0x8BEE, 0x5B36, 0x8BEF, 0x5B37, 0xE6D6, 0x5B38, 0x8BF0, 0x5B39, 0x8BF1, 0x5B3A, 0x8BF2, - 0x5B3B, 0x8BF3, 0x5B3C, 0x8BF4, 0x5B3D, 0x8BF5, 0x5B3E, 0x8BF6, 0x5B3F, 0x8BF7, 0x5B40, 0xE6D7, 0x5B41, 0x8BF8, 0x5B42, 0x8BF9, - 0x5B43, 0x8BFA, 0x5B44, 0x8BFB, 0x5B45, 0x8BFC, 0x5B46, 0x8BFD, 0x5B47, 0x8BFE, 0x5B48, 0x8C40, 0x5B49, 0x8C41, 0x5B4A, 0x8C42, - 0x5B4B, 0x8C43, 0x5B4C, 0x8C44, 0x5B4D, 0x8C45, 0x5B4E, 0x8C46, 0x5B4F, 0x8C47, 0x5B50, 0xD7D3, 0x5B51, 0xE6DD, 0x5B52, 0x8C48, - 0x5B53, 0xE6DE, 0x5B54, 0xBFD7, 0x5B55, 0xD4D0, 0x5B56, 0x8C49, 0x5B57, 0xD7D6, 0x5B58, 0xB4E6, 0x5B59, 0xCBEF, 0x5B5A, 0xE6DA, - 0x5B5B, 0xD8C3, 0x5B5C, 0xD7CE, 0x5B5D, 0xD0A2, 0x5B5E, 0x8C4A, 0x5B5F, 0xC3CF, 0x5B60, 0x8C4B, 0x5B61, 0x8C4C, 0x5B62, 0xE6DF, - 0x5B63, 0xBCBE, 0x5B64, 0xB9C2, 0x5B65, 0xE6DB, 0x5B66, 0xD1A7, 0x5B67, 0x8C4D, 0x5B68, 0x8C4E, 0x5B69, 0xBAA2, 0x5B6A, 0xC2CF, - 0x5B6B, 0x8C4F, 0x5B6C, 0xD8AB, 0x5B6D, 0x8C50, 0x5B6E, 0x8C51, 0x5B6F, 0x8C52, 0x5B70, 0xCAEB, 0x5B71, 0xE5EE, 0x5B72, 0x8C53, - 0x5B73, 0xE6DC, 0x5B74, 0x8C54, 0x5B75, 0xB7F5, 0x5B76, 0x8C55, 0x5B77, 0x8C56, 0x5B78, 0x8C57, 0x5B79, 0x8C58, 0x5B7A, 0xC8E6, - 0x5B7B, 0x8C59, 0x5B7C, 0x8C5A, 0x5B7D, 0xC4F5, 0x5B7E, 0x8C5B, 0x5B7F, 0x8C5C, 0x5B80, 0xE5B2, 0x5B81, 0xC4FE, 0x5B82, 0x8C5D, - 0x5B83, 0xCBFC, 0x5B84, 0xE5B3, 0x5B85, 0xD5AC, 0x5B86, 0x8C5E, 0x5B87, 0xD3EE, 0x5B88, 0xCAD8, 0x5B89, 0xB0B2, 0x5B8A, 0x8C5F, - 0x5B8B, 0xCBCE, 0x5B8C, 0xCDEA, 0x5B8D, 0x8C60, 0x5B8E, 0x8C61, 0x5B8F, 0xBAEA, 0x5B90, 0x8C62, 0x5B91, 0x8C63, 0x5B92, 0x8C64, - 0x5B93, 0xE5B5, 0x5B94, 0x8C65, 0x5B95, 0xE5B4, 0x5B96, 0x8C66, 0x5B97, 0xD7DA, 0x5B98, 0xB9D9, 0x5B99, 0xD6E6, 0x5B9A, 0xB6A8, - 0x5B9B, 0xCDF0, 0x5B9C, 0xD2CB, 0x5B9D, 0xB1A6, 0x5B9E, 0xCAB5, 0x5B9F, 0x8C67, 0x5BA0, 0xB3E8, 0x5BA1, 0xC9F3, 0x5BA2, 0xBFCD, - 0x5BA3, 0xD0FB, 0x5BA4, 0xCAD2, 0x5BA5, 0xE5B6, 0x5BA6, 0xBBC2, 0x5BA7, 0x8C68, 0x5BA8, 0x8C69, 0x5BA9, 0x8C6A, 0x5BAA, 0xCFDC, - 0x5BAB, 0xB9AC, 0x5BAC, 0x8C6B, 0x5BAD, 0x8C6C, 0x5BAE, 0x8C6D, 0x5BAF, 0x8C6E, 0x5BB0, 0xD4D7, 0x5BB1, 0x8C6F, 0x5BB2, 0x8C70, - 0x5BB3, 0xBAA6, 0x5BB4, 0xD1E7, 0x5BB5, 0xCFFC, 0x5BB6, 0xBCD2, 0x5BB7, 0x8C71, 0x5BB8, 0xE5B7, 0x5BB9, 0xC8DD, 0x5BBA, 0x8C72, - 0x5BBB, 0x8C73, 0x5BBC, 0x8C74, 0x5BBD, 0xBFED, 0x5BBE, 0xB1F6, 0x5BBF, 0xCBDE, 0x5BC0, 0x8C75, 0x5BC1, 0x8C76, 0x5BC2, 0xBCC5, - 0x5BC3, 0x8C77, 0x5BC4, 0xBCC4, 0x5BC5, 0xD2FA, 0x5BC6, 0xC3DC, 0x5BC7, 0xBFDC, 0x5BC8, 0x8C78, 0x5BC9, 0x8C79, 0x5BCA, 0x8C7A, - 0x5BCB, 0x8C7B, 0x5BCC, 0xB8BB, 0x5BCD, 0x8C7C, 0x5BCE, 0x8C7D, 0x5BCF, 0x8C7E, 0x5BD0, 0xC3C2, 0x5BD1, 0x8C80, 0x5BD2, 0xBAAE, - 0x5BD3, 0xD4A2, 0x5BD4, 0x8C81, 0x5BD5, 0x8C82, 0x5BD6, 0x8C83, 0x5BD7, 0x8C84, 0x5BD8, 0x8C85, 0x5BD9, 0x8C86, 0x5BDA, 0x8C87, - 0x5BDB, 0x8C88, 0x5BDC, 0x8C89, 0x5BDD, 0xC7DE, 0x5BDE, 0xC4AF, 0x5BDF, 0xB2EC, 0x5BE0, 0x8C8A, 0x5BE1, 0xB9D1, 0x5BE2, 0x8C8B, - 0x5BE3, 0x8C8C, 0x5BE4, 0xE5BB, 0x5BE5, 0xC1C8, 0x5BE6, 0x8C8D, 0x5BE7, 0x8C8E, 0x5BE8, 0xD5AF, 0x5BE9, 0x8C8F, 0x5BEA, 0x8C90, - 0x5BEB, 0x8C91, 0x5BEC, 0x8C92, 0x5BED, 0x8C93, 0x5BEE, 0xE5BC, 0x5BEF, 0x8C94, 0x5BF0, 0xE5BE, 0x5BF1, 0x8C95, 0x5BF2, 0x8C96, - 0x5BF3, 0x8C97, 0x5BF4, 0x8C98, 0x5BF5, 0x8C99, 0x5BF6, 0x8C9A, 0x5BF7, 0x8C9B, 0x5BF8, 0xB4E7, 0x5BF9, 0xB6D4, 0x5BFA, 0xCBC2, - 0x5BFB, 0xD1B0, 0x5BFC, 0xB5BC, 0x5BFD, 0x8C9C, 0x5BFE, 0x8C9D, 0x5BFF, 0xCAD9, 0x5C00, 0x8C9E, 0x5C01, 0xB7E2, 0x5C02, 0x8C9F, - 0x5C03, 0x8CA0, 0x5C04, 0xC9E4, 0x5C05, 0x8CA1, 0x5C06, 0xBDAB, 0x5C07, 0x8CA2, 0x5C08, 0x8CA3, 0x5C09, 0xCEBE, 0x5C0A, 0xD7F0, - 0x5C0B, 0x8CA4, 0x5C0C, 0x8CA5, 0x5C0D, 0x8CA6, 0x5C0E, 0x8CA7, 0x5C0F, 0xD0A1, 0x5C10, 0x8CA8, 0x5C11, 0xC9D9, 0x5C12, 0x8CA9, - 0x5C13, 0x8CAA, 0x5C14, 0xB6FB, 0x5C15, 0xE6D8, 0x5C16, 0xBCE2, 0x5C17, 0x8CAB, 0x5C18, 0xB3BE, 0x5C19, 0x8CAC, 0x5C1A, 0xC9D0, - 0x5C1B, 0x8CAD, 0x5C1C, 0xE6D9, 0x5C1D, 0xB3A2, 0x5C1E, 0x8CAE, 0x5C1F, 0x8CAF, 0x5C20, 0x8CB0, 0x5C21, 0x8CB1, 0x5C22, 0xDECC, - 0x5C23, 0x8CB2, 0x5C24, 0xD3C8, 0x5C25, 0xDECD, 0x5C26, 0x8CB3, 0x5C27, 0xD2A2, 0x5C28, 0x8CB4, 0x5C29, 0x8CB5, 0x5C2A, 0x8CB6, - 0x5C2B, 0x8CB7, 0x5C2C, 0xDECE, 0x5C2D, 0x8CB8, 0x5C2E, 0x8CB9, 0x5C2F, 0x8CBA, 0x5C30, 0x8CBB, 0x5C31, 0xBECD, 0x5C32, 0x8CBC, - 0x5C33, 0x8CBD, 0x5C34, 0xDECF, 0x5C35, 0x8CBE, 0x5C36, 0x8CBF, 0x5C37, 0x8CC0, 0x5C38, 0xCAAC, 0x5C39, 0xD2FC, 0x5C3A, 0xB3DF, - 0x5C3B, 0xE5EA, 0x5C3C, 0xC4E1, 0x5C3D, 0xBEA1, 0x5C3E, 0xCEB2, 0x5C3F, 0xC4F2, 0x5C40, 0xBED6, 0x5C41, 0xC6A8, 0x5C42, 0xB2E3, - 0x5C43, 0x8CC1, 0x5C44, 0x8CC2, 0x5C45, 0xBED3, 0x5C46, 0x8CC3, 0x5C47, 0x8CC4, 0x5C48, 0xC7FC, 0x5C49, 0xCCEB, 0x5C4A, 0xBDEC, - 0x5C4B, 0xCEDD, 0x5C4C, 0x8CC5, 0x5C4D, 0x8CC6, 0x5C4E, 0xCABA, 0x5C4F, 0xC6C1, 0x5C50, 0xE5EC, 0x5C51, 0xD0BC, 0x5C52, 0x8CC7, - 0x5C53, 0x8CC8, 0x5C54, 0x8CC9, 0x5C55, 0xD5B9, 0x5C56, 0x8CCA, 0x5C57, 0x8CCB, 0x5C58, 0x8CCC, 0x5C59, 0xE5ED, 0x5C5A, 0x8CCD, - 0x5C5B, 0x8CCE, 0x5C5C, 0x8CCF, 0x5C5D, 0x8CD0, 0x5C5E, 0xCAF4, 0x5C5F, 0x8CD1, 0x5C60, 0xCDC0, 0x5C61, 0xC2C5, 0x5C62, 0x8CD2, - 0x5C63, 0xE5EF, 0x5C64, 0x8CD3, 0x5C65, 0xC2C4, 0x5C66, 0xE5F0, 0x5C67, 0x8CD4, 0x5C68, 0x8CD5, 0x5C69, 0x8CD6, 0x5C6A, 0x8CD7, - 0x5C6B, 0x8CD8, 0x5C6C, 0x8CD9, 0x5C6D, 0x8CDA, 0x5C6E, 0xE5F8, 0x5C6F, 0xCDCD, 0x5C70, 0x8CDB, 0x5C71, 0xC9BD, 0x5C72, 0x8CDC, - 0x5C73, 0x8CDD, 0x5C74, 0x8CDE, 0x5C75, 0x8CDF, 0x5C76, 0x8CE0, 0x5C77, 0x8CE1, 0x5C78, 0x8CE2, 0x5C79, 0xD2D9, 0x5C7A, 0xE1A8, - 0x5C7B, 0x8CE3, 0x5C7C, 0x8CE4, 0x5C7D, 0x8CE5, 0x5C7E, 0x8CE6, 0x5C7F, 0xD3EC, 0x5C80, 0x8CE7, 0x5C81, 0xCBEA, 0x5C82, 0xC6F1, - 0x5C83, 0x8CE8, 0x5C84, 0x8CE9, 0x5C85, 0x8CEA, 0x5C86, 0x8CEB, 0x5C87, 0x8CEC, 0x5C88, 0xE1AC, 0x5C89, 0x8CED, 0x5C8A, 0x8CEE, - 0x5C8B, 0x8CEF, 0x5C8C, 0xE1A7, 0x5C8D, 0xE1A9, 0x5C8E, 0x8CF0, 0x5C8F, 0x8CF1, 0x5C90, 0xE1AA, 0x5C91, 0xE1AF, 0x5C92, 0x8CF2, - 0x5C93, 0x8CF3, 0x5C94, 0xB2ED, 0x5C95, 0x8CF4, 0x5C96, 0xE1AB, 0x5C97, 0xB8DA, 0x5C98, 0xE1AD, 0x5C99, 0xE1AE, 0x5C9A, 0xE1B0, - 0x5C9B, 0xB5BA, 0x5C9C, 0xE1B1, 0x5C9D, 0x8CF5, 0x5C9E, 0x8CF6, 0x5C9F, 0x8CF7, 0x5CA0, 0x8CF8, 0x5CA1, 0x8CF9, 0x5CA2, 0xE1B3, - 0x5CA3, 0xE1B8, 0x5CA4, 0x8CFA, 0x5CA5, 0x8CFB, 0x5CA6, 0x8CFC, 0x5CA7, 0x8CFD, 0x5CA8, 0x8CFE, 0x5CA9, 0xD1D2, 0x5CAA, 0x8D40, - 0x5CAB, 0xE1B6, 0x5CAC, 0xE1B5, 0x5CAD, 0xC1EB, 0x5CAE, 0x8D41, 0x5CAF, 0x8D42, 0x5CB0, 0x8D43, 0x5CB1, 0xE1B7, 0x5CB2, 0x8D44, - 0x5CB3, 0xD4C0, 0x5CB4, 0x8D45, 0x5CB5, 0xE1B2, 0x5CB6, 0x8D46, 0x5CB7, 0xE1BA, 0x5CB8, 0xB0B6, 0x5CB9, 0x8D47, 0x5CBA, 0x8D48, - 0x5CBB, 0x8D49, 0x5CBC, 0x8D4A, 0x5CBD, 0xE1B4, 0x5CBE, 0x8D4B, 0x5CBF, 0xBFF9, 0x5CC0, 0x8D4C, 0x5CC1, 0xE1B9, 0x5CC2, 0x8D4D, - 0x5CC3, 0x8D4E, 0x5CC4, 0xE1BB, 0x5CC5, 0x8D4F, 0x5CC6, 0x8D50, 0x5CC7, 0x8D51, 0x5CC8, 0x8D52, 0x5CC9, 0x8D53, 0x5CCA, 0x8D54, - 0x5CCB, 0xE1BE, 0x5CCC, 0x8D55, 0x5CCD, 0x8D56, 0x5CCE, 0x8D57, 0x5CCF, 0x8D58, 0x5CD0, 0x8D59, 0x5CD1, 0x8D5A, 0x5CD2, 0xE1BC, - 0x5CD3, 0x8D5B, 0x5CD4, 0x8D5C, 0x5CD5, 0x8D5D, 0x5CD6, 0x8D5E, 0x5CD7, 0x8D5F, 0x5CD8, 0x8D60, 0x5CD9, 0xD6C5, 0x5CDA, 0x8D61, - 0x5CDB, 0x8D62, 0x5CDC, 0x8D63, 0x5CDD, 0x8D64, 0x5CDE, 0x8D65, 0x5CDF, 0x8D66, 0x5CE0, 0x8D67, 0x5CE1, 0xCFBF, 0x5CE2, 0x8D68, - 0x5CE3, 0x8D69, 0x5CE4, 0xE1BD, 0x5CE5, 0xE1BF, 0x5CE6, 0xC2CD, 0x5CE7, 0x8D6A, 0x5CE8, 0xB6EB, 0x5CE9, 0x8D6B, 0x5CEA, 0xD3F8, - 0x5CEB, 0x8D6C, 0x5CEC, 0x8D6D, 0x5CED, 0xC7CD, 0x5CEE, 0x8D6E, 0x5CEF, 0x8D6F, 0x5CF0, 0xB7E5, 0x5CF1, 0x8D70, 0x5CF2, 0x8D71, - 0x5CF3, 0x8D72, 0x5CF4, 0x8D73, 0x5CF5, 0x8D74, 0x5CF6, 0x8D75, 0x5CF7, 0x8D76, 0x5CF8, 0x8D77, 0x5CF9, 0x8D78, 0x5CFA, 0x8D79, - 0x5CFB, 0xBEFE, 0x5CFC, 0x8D7A, 0x5CFD, 0x8D7B, 0x5CFE, 0x8D7C, 0x5CFF, 0x8D7D, 0x5D00, 0x8D7E, 0x5D01, 0x8D80, 0x5D02, 0xE1C0, - 0x5D03, 0xE1C1, 0x5D04, 0x8D81, 0x5D05, 0x8D82, 0x5D06, 0xE1C7, 0x5D07, 0xB3E7, 0x5D08, 0x8D83, 0x5D09, 0x8D84, 0x5D0A, 0x8D85, - 0x5D0B, 0x8D86, 0x5D0C, 0x8D87, 0x5D0D, 0x8D88, 0x5D0E, 0xC6E9, 0x5D0F, 0x8D89, 0x5D10, 0x8D8A, 0x5D11, 0x8D8B, 0x5D12, 0x8D8C, - 0x5D13, 0x8D8D, 0x5D14, 0xB4DE, 0x5D15, 0x8D8E, 0x5D16, 0xD1C2, 0x5D17, 0x8D8F, 0x5D18, 0x8D90, 0x5D19, 0x8D91, 0x5D1A, 0x8D92, - 0x5D1B, 0xE1C8, 0x5D1C, 0x8D93, 0x5D1D, 0x8D94, 0x5D1E, 0xE1C6, 0x5D1F, 0x8D95, 0x5D20, 0x8D96, 0x5D21, 0x8D97, 0x5D22, 0x8D98, - 0x5D23, 0x8D99, 0x5D24, 0xE1C5, 0x5D25, 0x8D9A, 0x5D26, 0xE1C3, 0x5D27, 0xE1C2, 0x5D28, 0x8D9B, 0x5D29, 0xB1C0, 0x5D2A, 0x8D9C, - 0x5D2B, 0x8D9D, 0x5D2C, 0x8D9E, 0x5D2D, 0xD5B8, 0x5D2E, 0xE1C4, 0x5D2F, 0x8D9F, 0x5D30, 0x8DA0, 0x5D31, 0x8DA1, 0x5D32, 0x8DA2, - 0x5D33, 0x8DA3, 0x5D34, 0xE1CB, 0x5D35, 0x8DA4, 0x5D36, 0x8DA5, 0x5D37, 0x8DA6, 0x5D38, 0x8DA7, 0x5D39, 0x8DA8, 0x5D3A, 0x8DA9, - 0x5D3B, 0x8DAA, 0x5D3C, 0x8DAB, 0x5D3D, 0xE1CC, 0x5D3E, 0xE1CA, 0x5D3F, 0x8DAC, 0x5D40, 0x8DAD, 0x5D41, 0x8DAE, 0x5D42, 0x8DAF, - 0x5D43, 0x8DB0, 0x5D44, 0x8DB1, 0x5D45, 0x8DB2, 0x5D46, 0x8DB3, 0x5D47, 0xEFFA, 0x5D48, 0x8DB4, 0x5D49, 0x8DB5, 0x5D4A, 0xE1D3, - 0x5D4B, 0xE1D2, 0x5D4C, 0xC7B6, 0x5D4D, 0x8DB6, 0x5D4E, 0x8DB7, 0x5D4F, 0x8DB8, 0x5D50, 0x8DB9, 0x5D51, 0x8DBA, 0x5D52, 0x8DBB, - 0x5D53, 0x8DBC, 0x5D54, 0x8DBD, 0x5D55, 0x8DBE, 0x5D56, 0x8DBF, 0x5D57, 0x8DC0, 0x5D58, 0xE1C9, 0x5D59, 0x8DC1, 0x5D5A, 0x8DC2, - 0x5D5B, 0xE1CE, 0x5D5C, 0x8DC3, 0x5D5D, 0xE1D0, 0x5D5E, 0x8DC4, 0x5D5F, 0x8DC5, 0x5D60, 0x8DC6, 0x5D61, 0x8DC7, 0x5D62, 0x8DC8, - 0x5D63, 0x8DC9, 0x5D64, 0x8DCA, 0x5D65, 0x8DCB, 0x5D66, 0x8DCC, 0x5D67, 0x8DCD, 0x5D68, 0x8DCE, 0x5D69, 0xE1D4, 0x5D6A, 0x8DCF, - 0x5D6B, 0xE1D1, 0x5D6C, 0xE1CD, 0x5D6D, 0x8DD0, 0x5D6E, 0x8DD1, 0x5D6F, 0xE1CF, 0x5D70, 0x8DD2, 0x5D71, 0x8DD3, 0x5D72, 0x8DD4, - 0x5D73, 0x8DD5, 0x5D74, 0xE1D5, 0x5D75, 0x8DD6, 0x5D76, 0x8DD7, 0x5D77, 0x8DD8, 0x5D78, 0x8DD9, 0x5D79, 0x8DDA, 0x5D7A, 0x8DDB, - 0x5D7B, 0x8DDC, 0x5D7C, 0x8DDD, 0x5D7D, 0x8DDE, 0x5D7E, 0x8DDF, 0x5D7F, 0x8DE0, 0x5D80, 0x8DE1, 0x5D81, 0x8DE2, 0x5D82, 0xE1D6, - 0x5D83, 0x8DE3, 0x5D84, 0x8DE4, 0x5D85, 0x8DE5, 0x5D86, 0x8DE6, 0x5D87, 0x8DE7, 0x5D88, 0x8DE8, 0x5D89, 0x8DE9, 0x5D8A, 0x8DEA, - 0x5D8B, 0x8DEB, 0x5D8C, 0x8DEC, 0x5D8D, 0x8DED, 0x5D8E, 0x8DEE, 0x5D8F, 0x8DEF, 0x5D90, 0x8DF0, 0x5D91, 0x8DF1, 0x5D92, 0x8DF2, - 0x5D93, 0x8DF3, 0x5D94, 0x8DF4, 0x5D95, 0x8DF5, 0x5D96, 0x8DF6, 0x5D97, 0x8DF7, 0x5D98, 0x8DF8, 0x5D99, 0xE1D7, 0x5D9A, 0x8DF9, - 0x5D9B, 0x8DFA, 0x5D9C, 0x8DFB, 0x5D9D, 0xE1D8, 0x5D9E, 0x8DFC, 0x5D9F, 0x8DFD, 0x5DA0, 0x8DFE, 0x5DA1, 0x8E40, 0x5DA2, 0x8E41, - 0x5DA3, 0x8E42, 0x5DA4, 0x8E43, 0x5DA5, 0x8E44, 0x5DA6, 0x8E45, 0x5DA7, 0x8E46, 0x5DA8, 0x8E47, 0x5DA9, 0x8E48, 0x5DAA, 0x8E49, - 0x5DAB, 0x8E4A, 0x5DAC, 0x8E4B, 0x5DAD, 0x8E4C, 0x5DAE, 0x8E4D, 0x5DAF, 0x8E4E, 0x5DB0, 0x8E4F, 0x5DB1, 0x8E50, 0x5DB2, 0x8E51, - 0x5DB3, 0x8E52, 0x5DB4, 0x8E53, 0x5DB5, 0x8E54, 0x5DB6, 0x8E55, 0x5DB7, 0xE1DA, 0x5DB8, 0x8E56, 0x5DB9, 0x8E57, 0x5DBA, 0x8E58, - 0x5DBB, 0x8E59, 0x5DBC, 0x8E5A, 0x5DBD, 0x8E5B, 0x5DBE, 0x8E5C, 0x5DBF, 0x8E5D, 0x5DC0, 0x8E5E, 0x5DC1, 0x8E5F, 0x5DC2, 0x8E60, - 0x5DC3, 0x8E61, 0x5DC4, 0x8E62, 0x5DC5, 0xE1DB, 0x5DC6, 0x8E63, 0x5DC7, 0x8E64, 0x5DC8, 0x8E65, 0x5DC9, 0x8E66, 0x5DCA, 0x8E67, - 0x5DCB, 0x8E68, 0x5DCC, 0x8E69, 0x5DCD, 0xCEA1, 0x5DCE, 0x8E6A, 0x5DCF, 0x8E6B, 0x5DD0, 0x8E6C, 0x5DD1, 0x8E6D, 0x5DD2, 0x8E6E, - 0x5DD3, 0x8E6F, 0x5DD4, 0x8E70, 0x5DD5, 0x8E71, 0x5DD6, 0x8E72, 0x5DD7, 0x8E73, 0x5DD8, 0x8E74, 0x5DD9, 0x8E75, 0x5DDA, 0x8E76, - 0x5DDB, 0xE7DD, 0x5DDC, 0x8E77, 0x5DDD, 0xB4A8, 0x5DDE, 0xD6DD, 0x5DDF, 0x8E78, 0x5DE0, 0x8E79, 0x5DE1, 0xD1B2, 0x5DE2, 0xB3B2, - 0x5DE3, 0x8E7A, 0x5DE4, 0x8E7B, 0x5DE5, 0xB9A4, 0x5DE6, 0xD7F3, 0x5DE7, 0xC7C9, 0x5DE8, 0xBEDE, 0x5DE9, 0xB9AE, 0x5DEA, 0x8E7C, - 0x5DEB, 0xCED7, 0x5DEC, 0x8E7D, 0x5DED, 0x8E7E, 0x5DEE, 0xB2EE, 0x5DEF, 0xDBCF, 0x5DF0, 0x8E80, 0x5DF1, 0xBCBA, 0x5DF2, 0xD2D1, - 0x5DF3, 0xCBC8, 0x5DF4, 0xB0CD, 0x5DF5, 0x8E81, 0x5DF6, 0x8E82, 0x5DF7, 0xCFEF, 0x5DF8, 0x8E83, 0x5DF9, 0x8E84, 0x5DFA, 0x8E85, - 0x5DFB, 0x8E86, 0x5DFC, 0x8E87, 0x5DFD, 0xD9E3, 0x5DFE, 0xBDED, 0x5DFF, 0x8E88, 0x5E00, 0x8E89, 0x5E01, 0xB1D2, 0x5E02, 0xCAD0, - 0x5E03, 0xB2BC, 0x5E04, 0x8E8A, 0x5E05, 0xCBA7, 0x5E06, 0xB7AB, 0x5E07, 0x8E8B, 0x5E08, 0xCAA6, 0x5E09, 0x8E8C, 0x5E0A, 0x8E8D, - 0x5E0B, 0x8E8E, 0x5E0C, 0xCFA3, 0x5E0D, 0x8E8F, 0x5E0E, 0x8E90, 0x5E0F, 0xE0F8, 0x5E10, 0xD5CA, 0x5E11, 0xE0FB, 0x5E12, 0x8E91, - 0x5E13, 0x8E92, 0x5E14, 0xE0FA, 0x5E15, 0xC5C1, 0x5E16, 0xCCFB, 0x5E17, 0x8E93, 0x5E18, 0xC1B1, 0x5E19, 0xE0F9, 0x5E1A, 0xD6E3, - 0x5E1B, 0xB2AF, 0x5E1C, 0xD6C4, 0x5E1D, 0xB5DB, 0x5E1E, 0x8E94, 0x5E1F, 0x8E95, 0x5E20, 0x8E96, 0x5E21, 0x8E97, 0x5E22, 0x8E98, - 0x5E23, 0x8E99, 0x5E24, 0x8E9A, 0x5E25, 0x8E9B, 0x5E26, 0xB4F8, 0x5E27, 0xD6A1, 0x5E28, 0x8E9C, 0x5E29, 0x8E9D, 0x5E2A, 0x8E9E, - 0x5E2B, 0x8E9F, 0x5E2C, 0x8EA0, 0x5E2D, 0xCFAF, 0x5E2E, 0xB0EF, 0x5E2F, 0x8EA1, 0x5E30, 0x8EA2, 0x5E31, 0xE0FC, 0x5E32, 0x8EA3, - 0x5E33, 0x8EA4, 0x5E34, 0x8EA5, 0x5E35, 0x8EA6, 0x5E36, 0x8EA7, 0x5E37, 0xE1A1, 0x5E38, 0xB3A3, 0x5E39, 0x8EA8, 0x5E3A, 0x8EA9, - 0x5E3B, 0xE0FD, 0x5E3C, 0xE0FE, 0x5E3D, 0xC3B1, 0x5E3E, 0x8EAA, 0x5E3F, 0x8EAB, 0x5E40, 0x8EAC, 0x5E41, 0x8EAD, 0x5E42, 0xC3DD, - 0x5E43, 0x8EAE, 0x5E44, 0xE1A2, 0x5E45, 0xB7F9, 0x5E46, 0x8EAF, 0x5E47, 0x8EB0, 0x5E48, 0x8EB1, 0x5E49, 0x8EB2, 0x5E4A, 0x8EB3, - 0x5E4B, 0x8EB4, 0x5E4C, 0xBBCF, 0x5E4D, 0x8EB5, 0x5E4E, 0x8EB6, 0x5E4F, 0x8EB7, 0x5E50, 0x8EB8, 0x5E51, 0x8EB9, 0x5E52, 0x8EBA, - 0x5E53, 0x8EBB, 0x5E54, 0xE1A3, 0x5E55, 0xC4BB, 0x5E56, 0x8EBC, 0x5E57, 0x8EBD, 0x5E58, 0x8EBE, 0x5E59, 0x8EBF, 0x5E5A, 0x8EC0, - 0x5E5B, 0xE1A4, 0x5E5C, 0x8EC1, 0x5E5D, 0x8EC2, 0x5E5E, 0xE1A5, 0x5E5F, 0x8EC3, 0x5E60, 0x8EC4, 0x5E61, 0xE1A6, 0x5E62, 0xB4B1, - 0x5E63, 0x8EC5, 0x5E64, 0x8EC6, 0x5E65, 0x8EC7, 0x5E66, 0x8EC8, 0x5E67, 0x8EC9, 0x5E68, 0x8ECA, 0x5E69, 0x8ECB, 0x5E6A, 0x8ECC, - 0x5E6B, 0x8ECD, 0x5E6C, 0x8ECE, 0x5E6D, 0x8ECF, 0x5E6E, 0x8ED0, 0x5E6F, 0x8ED1, 0x5E70, 0x8ED2, 0x5E71, 0x8ED3, 0x5E72, 0xB8C9, - 0x5E73, 0xC6BD, 0x5E74, 0xC4EA, 0x5E75, 0x8ED4, 0x5E76, 0xB2A2, 0x5E77, 0x8ED5, 0x5E78, 0xD0D2, 0x5E79, 0x8ED6, 0x5E7A, 0xE7DB, - 0x5E7B, 0xBBC3, 0x5E7C, 0xD3D7, 0x5E7D, 0xD3C4, 0x5E7E, 0x8ED7, 0x5E7F, 0xB9E3, 0x5E80, 0xE2CF, 0x5E81, 0x8ED8, 0x5E82, 0x8ED9, - 0x5E83, 0x8EDA, 0x5E84, 0xD7AF, 0x5E85, 0x8EDB, 0x5E86, 0xC7EC, 0x5E87, 0xB1D3, 0x5E88, 0x8EDC, 0x5E89, 0x8EDD, 0x5E8A, 0xB4B2, - 0x5E8B, 0xE2D1, 0x5E8C, 0x8EDE, 0x5E8D, 0x8EDF, 0x5E8E, 0x8EE0, 0x5E8F, 0xD0F2, 0x5E90, 0xC2AE, 0x5E91, 0xE2D0, 0x5E92, 0x8EE1, - 0x5E93, 0xBFE2, 0x5E94, 0xD3A6, 0x5E95, 0xB5D7, 0x5E96, 0xE2D2, 0x5E97, 0xB5EA, 0x5E98, 0x8EE2, 0x5E99, 0xC3ED, 0x5E9A, 0xB8FD, - 0x5E9B, 0x8EE3, 0x5E9C, 0xB8AE, 0x5E9D, 0x8EE4, 0x5E9E, 0xC5D3, 0x5E9F, 0xB7CF, 0x5EA0, 0xE2D4, 0x5EA1, 0x8EE5, 0x5EA2, 0x8EE6, - 0x5EA3, 0x8EE7, 0x5EA4, 0x8EE8, 0x5EA5, 0xE2D3, 0x5EA6, 0xB6C8, 0x5EA7, 0xD7F9, 0x5EA8, 0x8EE9, 0x5EA9, 0x8EEA, 0x5EAA, 0x8EEB, - 0x5EAB, 0x8EEC, 0x5EAC, 0x8EED, 0x5EAD, 0xCDA5, 0x5EAE, 0x8EEE, 0x5EAF, 0x8EEF, 0x5EB0, 0x8EF0, 0x5EB1, 0x8EF1, 0x5EB2, 0x8EF2, - 0x5EB3, 0xE2D8, 0x5EB4, 0x8EF3, 0x5EB5, 0xE2D6, 0x5EB6, 0xCAFC, 0x5EB7, 0xBFB5, 0x5EB8, 0xD3B9, 0x5EB9, 0xE2D5, 0x5EBA, 0x8EF4, - 0x5EBB, 0x8EF5, 0x5EBC, 0x8EF6, 0x5EBD, 0x8EF7, 0x5EBE, 0xE2D7, 0x5EBF, 0x8EF8, 0x5EC0, 0x8EF9, 0x5EC1, 0x8EFA, 0x5EC2, 0x8EFB, - 0x5EC3, 0x8EFC, 0x5EC4, 0x8EFD, 0x5EC5, 0x8EFE, 0x5EC6, 0x8F40, 0x5EC7, 0x8F41, 0x5EC8, 0x8F42, 0x5EC9, 0xC1AE, 0x5ECA, 0xC0C8, - 0x5ECB, 0x8F43, 0x5ECC, 0x8F44, 0x5ECD, 0x8F45, 0x5ECE, 0x8F46, 0x5ECF, 0x8F47, 0x5ED0, 0x8F48, 0x5ED1, 0xE2DB, 0x5ED2, 0xE2DA, - 0x5ED3, 0xC0AA, 0x5ED4, 0x8F49, 0x5ED5, 0x8F4A, 0x5ED6, 0xC1CE, 0x5ED7, 0x8F4B, 0x5ED8, 0x8F4C, 0x5ED9, 0x8F4D, 0x5EDA, 0x8F4E, - 0x5EDB, 0xE2DC, 0x5EDC, 0x8F4F, 0x5EDD, 0x8F50, 0x5EDE, 0x8F51, 0x5EDF, 0x8F52, 0x5EE0, 0x8F53, 0x5EE1, 0x8F54, 0x5EE2, 0x8F55, - 0x5EE3, 0x8F56, 0x5EE4, 0x8F57, 0x5EE5, 0x8F58, 0x5EE6, 0x8F59, 0x5EE7, 0x8F5A, 0x5EE8, 0xE2DD, 0x5EE9, 0x8F5B, 0x5EEA, 0xE2DE, - 0x5EEB, 0x8F5C, 0x5EEC, 0x8F5D, 0x5EED, 0x8F5E, 0x5EEE, 0x8F5F, 0x5EEF, 0x8F60, 0x5EF0, 0x8F61, 0x5EF1, 0x8F62, 0x5EF2, 0x8F63, - 0x5EF3, 0x8F64, 0x5EF4, 0xDBC8, 0x5EF5, 0x8F65, 0x5EF6, 0xD1D3, 0x5EF7, 0xCDA2, 0x5EF8, 0x8F66, 0x5EF9, 0x8F67, 0x5EFA, 0xBDA8, - 0x5EFB, 0x8F68, 0x5EFC, 0x8F69, 0x5EFD, 0x8F6A, 0x5EFE, 0xDEC3, 0x5EFF, 0xD8A5, 0x5F00, 0xBFAA, 0x5F01, 0xDBCD, 0x5F02, 0xD2EC, - 0x5F03, 0xC6FA, 0x5F04, 0xC5AA, 0x5F05, 0x8F6B, 0x5F06, 0x8F6C, 0x5F07, 0x8F6D, 0x5F08, 0xDEC4, 0x5F09, 0x8F6E, 0x5F0A, 0xB1D7, - 0x5F0B, 0xDFAE, 0x5F0C, 0x8F6F, 0x5F0D, 0x8F70, 0x5F0E, 0x8F71, 0x5F0F, 0xCABD, 0x5F10, 0x8F72, 0x5F11, 0xDFB1, 0x5F12, 0x8F73, - 0x5F13, 0xB9AD, 0x5F14, 0x8F74, 0x5F15, 0xD2FD, 0x5F16, 0x8F75, 0x5F17, 0xB8A5, 0x5F18, 0xBAEB, 0x5F19, 0x8F76, 0x5F1A, 0x8F77, - 0x5F1B, 0xB3DA, 0x5F1C, 0x8F78, 0x5F1D, 0x8F79, 0x5F1E, 0x8F7A, 0x5F1F, 0xB5DC, 0x5F20, 0xD5C5, 0x5F21, 0x8F7B, 0x5F22, 0x8F7C, - 0x5F23, 0x8F7D, 0x5F24, 0x8F7E, 0x5F25, 0xC3D6, 0x5F26, 0xCFD2, 0x5F27, 0xBBA1, 0x5F28, 0x8F80, 0x5F29, 0xE5F3, 0x5F2A, 0xE5F2, - 0x5F2B, 0x8F81, 0x5F2C, 0x8F82, 0x5F2D, 0xE5F4, 0x5F2E, 0x8F83, 0x5F2F, 0xCDE4, 0x5F30, 0x8F84, 0x5F31, 0xC8F5, 0x5F32, 0x8F85, - 0x5F33, 0x8F86, 0x5F34, 0x8F87, 0x5F35, 0x8F88, 0x5F36, 0x8F89, 0x5F37, 0x8F8A, 0x5F38, 0x8F8B, 0x5F39, 0xB5AF, 0x5F3A, 0xC7BF, - 0x5F3B, 0x8F8C, 0x5F3C, 0xE5F6, 0x5F3D, 0x8F8D, 0x5F3E, 0x8F8E, 0x5F3F, 0x8F8F, 0x5F40, 0xECB0, 0x5F41, 0x8F90, 0x5F42, 0x8F91, - 0x5F43, 0x8F92, 0x5F44, 0x8F93, 0x5F45, 0x8F94, 0x5F46, 0x8F95, 0x5F47, 0x8F96, 0x5F48, 0x8F97, 0x5F49, 0x8F98, 0x5F4A, 0x8F99, - 0x5F4B, 0x8F9A, 0x5F4C, 0x8F9B, 0x5F4D, 0x8F9C, 0x5F4E, 0x8F9D, 0x5F4F, 0x8F9E, 0x5F50, 0xE5E6, 0x5F51, 0x8F9F, 0x5F52, 0xB9E9, - 0x5F53, 0xB5B1, 0x5F54, 0x8FA0, 0x5F55, 0xC2BC, 0x5F56, 0xE5E8, 0x5F57, 0xE5E7, 0x5F58, 0xE5E9, 0x5F59, 0x8FA1, 0x5F5A, 0x8FA2, - 0x5F5B, 0x8FA3, 0x5F5C, 0x8FA4, 0x5F5D, 0xD2CD, 0x5F5E, 0x8FA5, 0x5F5F, 0x8FA6, 0x5F60, 0x8FA7, 0x5F61, 0xE1EA, 0x5F62, 0xD0CE, - 0x5F63, 0x8FA8, 0x5F64, 0xCDAE, 0x5F65, 0x8FA9, 0x5F66, 0xD1E5, 0x5F67, 0x8FAA, 0x5F68, 0x8FAB, 0x5F69, 0xB2CA, 0x5F6A, 0xB1EB, - 0x5F6B, 0x8FAC, 0x5F6C, 0xB1F2, 0x5F6D, 0xC5ED, 0x5F6E, 0x8FAD, 0x5F6F, 0x8FAE, 0x5F70, 0xD5C3, 0x5F71, 0xD3B0, 0x5F72, 0x8FAF, - 0x5F73, 0xE1DC, 0x5F74, 0x8FB0, 0x5F75, 0x8FB1, 0x5F76, 0x8FB2, 0x5F77, 0xE1DD, 0x5F78, 0x8FB3, 0x5F79, 0xD2DB, 0x5F7A, 0x8FB4, - 0x5F7B, 0xB3B9, 0x5F7C, 0xB1CB, 0x5F7D, 0x8FB5, 0x5F7E, 0x8FB6, 0x5F7F, 0x8FB7, 0x5F80, 0xCDF9, 0x5F81, 0xD5F7, 0x5F82, 0xE1DE, - 0x5F83, 0x8FB8, 0x5F84, 0xBEB6, 0x5F85, 0xB4FD, 0x5F86, 0x8FB9, 0x5F87, 0xE1DF, 0x5F88, 0xBADC, 0x5F89, 0xE1E0, 0x5F8A, 0xBBB2, - 0x5F8B, 0xC2C9, 0x5F8C, 0xE1E1, 0x5F8D, 0x8FBA, 0x5F8E, 0x8FBB, 0x5F8F, 0x8FBC, 0x5F90, 0xD0EC, 0x5F91, 0x8FBD, 0x5F92, 0xCDBD, - 0x5F93, 0x8FBE, 0x5F94, 0x8FBF, 0x5F95, 0xE1E2, 0x5F96, 0x8FC0, 0x5F97, 0xB5C3, 0x5F98, 0xC5C7, 0x5F99, 0xE1E3, 0x5F9A, 0x8FC1, - 0x5F9B, 0x8FC2, 0x5F9C, 0xE1E4, 0x5F9D, 0x8FC3, 0x5F9E, 0x8FC4, 0x5F9F, 0x8FC5, 0x5FA0, 0x8FC6, 0x5FA1, 0xD3F9, 0x5FA2, 0x8FC7, - 0x5FA3, 0x8FC8, 0x5FA4, 0x8FC9, 0x5FA5, 0x8FCA, 0x5FA6, 0x8FCB, 0x5FA7, 0x8FCC, 0x5FA8, 0xE1E5, 0x5FA9, 0x8FCD, 0x5FAA, 0xD1AD, - 0x5FAB, 0x8FCE, 0x5FAC, 0x8FCF, 0x5FAD, 0xE1E6, 0x5FAE, 0xCEA2, 0x5FAF, 0x8FD0, 0x5FB0, 0x8FD1, 0x5FB1, 0x8FD2, 0x5FB2, 0x8FD3, - 0x5FB3, 0x8FD4, 0x5FB4, 0x8FD5, 0x5FB5, 0xE1E7, 0x5FB6, 0x8FD6, 0x5FB7, 0xB5C2, 0x5FB8, 0x8FD7, 0x5FB9, 0x8FD8, 0x5FBA, 0x8FD9, - 0x5FBB, 0x8FDA, 0x5FBC, 0xE1E8, 0x5FBD, 0xBBD5, 0x5FBE, 0x8FDB, 0x5FBF, 0x8FDC, 0x5FC0, 0x8FDD, 0x5FC1, 0x8FDE, 0x5FC2, 0x8FDF, - 0x5FC3, 0xD0C4, 0x5FC4, 0xE2E0, 0x5FC5, 0xB1D8, 0x5FC6, 0xD2E4, 0x5FC7, 0x8FE0, 0x5FC8, 0x8FE1, 0x5FC9, 0xE2E1, 0x5FCA, 0x8FE2, - 0x5FCB, 0x8FE3, 0x5FCC, 0xBCC9, 0x5FCD, 0xC8CC, 0x5FCE, 0x8FE4, 0x5FCF, 0xE2E3, 0x5FD0, 0xECFE, 0x5FD1, 0xECFD, 0x5FD2, 0xDFAF, - 0x5FD3, 0x8FE5, 0x5FD4, 0x8FE6, 0x5FD5, 0x8FE7, 0x5FD6, 0xE2E2, 0x5FD7, 0xD6BE, 0x5FD8, 0xCDFC, 0x5FD9, 0xC3A6, 0x5FDA, 0x8FE8, - 0x5FDB, 0x8FE9, 0x5FDC, 0x8FEA, 0x5FDD, 0xE3C3, 0x5FDE, 0x8FEB, 0x5FDF, 0x8FEC, 0x5FE0, 0xD6D2, 0x5FE1, 0xE2E7, 0x5FE2, 0x8FED, - 0x5FE3, 0x8FEE, 0x5FE4, 0xE2E8, 0x5FE5, 0x8FEF, 0x5FE6, 0x8FF0, 0x5FE7, 0xD3C7, 0x5FE8, 0x8FF1, 0x5FE9, 0x8FF2, 0x5FEA, 0xE2EC, - 0x5FEB, 0xBFEC, 0x5FEC, 0x8FF3, 0x5FED, 0xE2ED, 0x5FEE, 0xE2E5, 0x5FEF, 0x8FF4, 0x5FF0, 0x8FF5, 0x5FF1, 0xB3C0, 0x5FF2, 0x8FF6, - 0x5FF3, 0x8FF7, 0x5FF4, 0x8FF8, 0x5FF5, 0xC4EE, 0x5FF6, 0x8FF9, 0x5FF7, 0x8FFA, 0x5FF8, 0xE2EE, 0x5FF9, 0x8FFB, 0x5FFA, 0x8FFC, - 0x5FFB, 0xD0C3, 0x5FFC, 0x8FFD, 0x5FFD, 0xBAF6, 0x5FFE, 0xE2E9, 0x5FFF, 0xB7DE, 0x6000, 0xBBB3, 0x6001, 0xCCAC, 0x6002, 0xCBCB, - 0x6003, 0xE2E4, 0x6004, 0xE2E6, 0x6005, 0xE2EA, 0x6006, 0xE2EB, 0x6007, 0x8FFE, 0x6008, 0x9040, 0x6009, 0x9041, 0x600A, 0xE2F7, - 0x600B, 0x9042, 0x600C, 0x9043, 0x600D, 0xE2F4, 0x600E, 0xD4F5, 0x600F, 0xE2F3, 0x6010, 0x9044, 0x6011, 0x9045, 0x6012, 0xC5AD, - 0x6013, 0x9046, 0x6014, 0xD5FA, 0x6015, 0xC5C2, 0x6016, 0xB2C0, 0x6017, 0x9047, 0x6018, 0x9048, 0x6019, 0xE2EF, 0x601A, 0x9049, - 0x601B, 0xE2F2, 0x601C, 0xC1AF, 0x601D, 0xCBBC, 0x601E, 0x904A, 0x601F, 0x904B, 0x6020, 0xB5A1, 0x6021, 0xE2F9, 0x6022, 0x904C, - 0x6023, 0x904D, 0x6024, 0x904E, 0x6025, 0xBCB1, 0x6026, 0xE2F1, 0x6027, 0xD0D4, 0x6028, 0xD4B9, 0x6029, 0xE2F5, 0x602A, 0xB9D6, - 0x602B, 0xE2F6, 0x602C, 0x904F, 0x602D, 0x9050, 0x602E, 0x9051, 0x602F, 0xC7D3, 0x6030, 0x9052, 0x6031, 0x9053, 0x6032, 0x9054, - 0x6033, 0x9055, 0x6034, 0x9056, 0x6035, 0xE2F0, 0x6036, 0x9057, 0x6037, 0x9058, 0x6038, 0x9059, 0x6039, 0x905A, 0x603A, 0x905B, - 0x603B, 0xD7DC, 0x603C, 0xEDA1, 0x603D, 0x905C, 0x603E, 0x905D, 0x603F, 0xE2F8, 0x6040, 0x905E, 0x6041, 0xEDA5, 0x6042, 0xE2FE, - 0x6043, 0xCAD1, 0x6044, 0x905F, 0x6045, 0x9060, 0x6046, 0x9061, 0x6047, 0x9062, 0x6048, 0x9063, 0x6049, 0x9064, 0x604A, 0x9065, - 0x604B, 0xC1B5, 0x604C, 0x9066, 0x604D, 0xBBD0, 0x604E, 0x9067, 0x604F, 0x9068, 0x6050, 0xBFD6, 0x6051, 0x9069, 0x6052, 0xBAE3, - 0x6053, 0x906A, 0x6054, 0x906B, 0x6055, 0xCBA1, 0x6056, 0x906C, 0x6057, 0x906D, 0x6058, 0x906E, 0x6059, 0xEDA6, 0x605A, 0xEDA3, - 0x605B, 0x906F, 0x605C, 0x9070, 0x605D, 0xEDA2, 0x605E, 0x9071, 0x605F, 0x9072, 0x6060, 0x9073, 0x6061, 0x9074, 0x6062, 0xBBD6, - 0x6063, 0xEDA7, 0x6064, 0xD0F4, 0x6065, 0x9075, 0x6066, 0x9076, 0x6067, 0xEDA4, 0x6068, 0xBADE, 0x6069, 0xB6F7, 0x606A, 0xE3A1, - 0x606B, 0xB6B2, 0x606C, 0xCCF1, 0x606D, 0xB9A7, 0x606E, 0x9077, 0x606F, 0xCFA2, 0x6070, 0xC7A1, 0x6071, 0x9078, 0x6072, 0x9079, - 0x6073, 0xBFD2, 0x6074, 0x907A, 0x6075, 0x907B, 0x6076, 0xB6F1, 0x6077, 0x907C, 0x6078, 0xE2FA, 0x6079, 0xE2FB, 0x607A, 0xE2FD, - 0x607B, 0xE2FC, 0x607C, 0xC4D5, 0x607D, 0xE3A2, 0x607E, 0x907D, 0x607F, 0xD3C1, 0x6080, 0x907E, 0x6081, 0x9080, 0x6082, 0x9081, - 0x6083, 0xE3A7, 0x6084, 0xC7C4, 0x6085, 0x9082, 0x6086, 0x9083, 0x6087, 0x9084, 0x6088, 0x9085, 0x6089, 0xCFA4, 0x608A, 0x9086, - 0x608B, 0x9087, 0x608C, 0xE3A9, 0x608D, 0xBAB7, 0x608E, 0x9088, 0x608F, 0x9089, 0x6090, 0x908A, 0x6091, 0x908B, 0x6092, 0xE3A8, - 0x6093, 0x908C, 0x6094, 0xBBDA, 0x6095, 0x908D, 0x6096, 0xE3A3, 0x6097, 0x908E, 0x6098, 0x908F, 0x6099, 0x9090, 0x609A, 0xE3A4, - 0x609B, 0xE3AA, 0x609C, 0x9091, 0x609D, 0xE3A6, 0x609E, 0x9092, 0x609F, 0xCEF2, 0x60A0, 0xD3C6, 0x60A1, 0x9093, 0x60A2, 0x9094, - 0x60A3, 0xBBBC, 0x60A4, 0x9095, 0x60A5, 0x9096, 0x60A6, 0xD4C3, 0x60A7, 0x9097, 0x60A8, 0xC4FA, 0x60A9, 0x9098, 0x60AA, 0x9099, - 0x60AB, 0xEDA8, 0x60AC, 0xD0FC, 0x60AD, 0xE3A5, 0x60AE, 0x909A, 0x60AF, 0xC3F5, 0x60B0, 0x909B, 0x60B1, 0xE3AD, 0x60B2, 0xB1AF, - 0x60B3, 0x909C, 0x60B4, 0xE3B2, 0x60B5, 0x909D, 0x60B6, 0x909E, 0x60B7, 0x909F, 0x60B8, 0xBCC2, 0x60B9, 0x90A0, 0x60BA, 0x90A1, - 0x60BB, 0xE3AC, 0x60BC, 0xB5BF, 0x60BD, 0x90A2, 0x60BE, 0x90A3, 0x60BF, 0x90A4, 0x60C0, 0x90A5, 0x60C1, 0x90A6, 0x60C2, 0x90A7, - 0x60C3, 0x90A8, 0x60C4, 0x90A9, 0x60C5, 0xC7E9, 0x60C6, 0xE3B0, 0x60C7, 0x90AA, 0x60C8, 0x90AB, 0x60C9, 0x90AC, 0x60CA, 0xBEAA, - 0x60CB, 0xCDEF, 0x60CC, 0x90AD, 0x60CD, 0x90AE, 0x60CE, 0x90AF, 0x60CF, 0x90B0, 0x60D0, 0x90B1, 0x60D1, 0xBBF3, 0x60D2, 0x90B2, - 0x60D3, 0x90B3, 0x60D4, 0x90B4, 0x60D5, 0xCCE8, 0x60D6, 0x90B5, 0x60D7, 0x90B6, 0x60D8, 0xE3AF, 0x60D9, 0x90B7, 0x60DA, 0xE3B1, - 0x60DB, 0x90B8, 0x60DC, 0xCFA7, 0x60DD, 0xE3AE, 0x60DE, 0x90B9, 0x60DF, 0xCEA9, 0x60E0, 0xBBDD, 0x60E1, 0x90BA, 0x60E2, 0x90BB, - 0x60E3, 0x90BC, 0x60E4, 0x90BD, 0x60E5, 0x90BE, 0x60E6, 0xB5EB, 0x60E7, 0xBEE5, 0x60E8, 0xB2D2, 0x60E9, 0xB3CD, 0x60EA, 0x90BF, - 0x60EB, 0xB1B9, 0x60EC, 0xE3AB, 0x60ED, 0xB2D1, 0x60EE, 0xB5AC, 0x60EF, 0xB9DF, 0x60F0, 0xB6E8, 0x60F1, 0x90C0, 0x60F2, 0x90C1, - 0x60F3, 0xCFEB, 0x60F4, 0xE3B7, 0x60F5, 0x90C2, 0x60F6, 0xBBCC, 0x60F7, 0x90C3, 0x60F8, 0x90C4, 0x60F9, 0xC8C7, 0x60FA, 0xD0CA, - 0x60FB, 0x90C5, 0x60FC, 0x90C6, 0x60FD, 0x90C7, 0x60FE, 0x90C8, 0x60FF, 0x90C9, 0x6100, 0xE3B8, 0x6101, 0xB3EE, 0x6102, 0x90CA, - 0x6103, 0x90CB, 0x6104, 0x90CC, 0x6105, 0x90CD, 0x6106, 0xEDA9, 0x6107, 0x90CE, 0x6108, 0xD3FA, 0x6109, 0xD3E4, 0x610A, 0x90CF, - 0x610B, 0x90D0, 0x610C, 0x90D1, 0x610D, 0xEDAA, 0x610E, 0xE3B9, 0x610F, 0xD2E2, 0x6110, 0x90D2, 0x6111, 0x90D3, 0x6112, 0x90D4, - 0x6113, 0x90D5, 0x6114, 0x90D6, 0x6115, 0xE3B5, 0x6116, 0x90D7, 0x6117, 0x90D8, 0x6118, 0x90D9, 0x6119, 0x90DA, 0x611A, 0xD3DE, - 0x611B, 0x90DB, 0x611C, 0x90DC, 0x611D, 0x90DD, 0x611E, 0x90DE, 0x611F, 0xB8D0, 0x6120, 0xE3B3, 0x6121, 0x90DF, 0x6122, 0x90E0, - 0x6123, 0xE3B6, 0x6124, 0xB7DF, 0x6125, 0x90E1, 0x6126, 0xE3B4, 0x6127, 0xC0A2, 0x6128, 0x90E2, 0x6129, 0x90E3, 0x612A, 0x90E4, - 0x612B, 0xE3BA, 0x612C, 0x90E5, 0x612D, 0x90E6, 0x612E, 0x90E7, 0x612F, 0x90E8, 0x6130, 0x90E9, 0x6131, 0x90EA, 0x6132, 0x90EB, - 0x6133, 0x90EC, 0x6134, 0x90ED, 0x6135, 0x90EE, 0x6136, 0x90EF, 0x6137, 0x90F0, 0x6138, 0x90F1, 0x6139, 0x90F2, 0x613A, 0x90F3, - 0x613B, 0x90F4, 0x613C, 0x90F5, 0x613D, 0x90F6, 0x613E, 0x90F7, 0x613F, 0xD4B8, 0x6140, 0x90F8, 0x6141, 0x90F9, 0x6142, 0x90FA, - 0x6143, 0x90FB, 0x6144, 0x90FC, 0x6145, 0x90FD, 0x6146, 0x90FE, 0x6147, 0x9140, 0x6148, 0xB4C8, 0x6149, 0x9141, 0x614A, 0xE3BB, - 0x614B, 0x9142, 0x614C, 0xBBC5, 0x614D, 0x9143, 0x614E, 0xC9F7, 0x614F, 0x9144, 0x6150, 0x9145, 0x6151, 0xC9E5, 0x6152, 0x9146, - 0x6153, 0x9147, 0x6154, 0x9148, 0x6155, 0xC4BD, 0x6156, 0x9149, 0x6157, 0x914A, 0x6158, 0x914B, 0x6159, 0x914C, 0x615A, 0x914D, - 0x615B, 0x914E, 0x615C, 0x914F, 0x615D, 0xEDAB, 0x615E, 0x9150, 0x615F, 0x9151, 0x6160, 0x9152, 0x6161, 0x9153, 0x6162, 0xC2FD, - 0x6163, 0x9154, 0x6164, 0x9155, 0x6165, 0x9156, 0x6166, 0x9157, 0x6167, 0xBBDB, 0x6168, 0xBFAE, 0x6169, 0x9158, 0x616A, 0x9159, - 0x616B, 0x915A, 0x616C, 0x915B, 0x616D, 0x915C, 0x616E, 0x915D, 0x616F, 0x915E, 0x6170, 0xCEBF, 0x6171, 0x915F, 0x6172, 0x9160, - 0x6173, 0x9161, 0x6174, 0x9162, 0x6175, 0xE3BC, 0x6176, 0x9163, 0x6177, 0xBFB6, 0x6178, 0x9164, 0x6179, 0x9165, 0x617A, 0x9166, - 0x617B, 0x9167, 0x617C, 0x9168, 0x617D, 0x9169, 0x617E, 0x916A, 0x617F, 0x916B, 0x6180, 0x916C, 0x6181, 0x916D, 0x6182, 0x916E, - 0x6183, 0x916F, 0x6184, 0x9170, 0x6185, 0x9171, 0x6186, 0x9172, 0x6187, 0x9173, 0x6188, 0x9174, 0x6189, 0x9175, 0x618A, 0x9176, - 0x618B, 0xB1EF, 0x618C, 0x9177, 0x618D, 0x9178, 0x618E, 0xD4F7, 0x618F, 0x9179, 0x6190, 0x917A, 0x6191, 0x917B, 0x6192, 0x917C, - 0x6193, 0x917D, 0x6194, 0xE3BE, 0x6195, 0x917E, 0x6196, 0x9180, 0x6197, 0x9181, 0x6198, 0x9182, 0x6199, 0x9183, 0x619A, 0x9184, - 0x619B, 0x9185, 0x619C, 0x9186, 0x619D, 0xEDAD, 0x619E, 0x9187, 0x619F, 0x9188, 0x61A0, 0x9189, 0x61A1, 0x918A, 0x61A2, 0x918B, - 0x61A3, 0x918C, 0x61A4, 0x918D, 0x61A5, 0x918E, 0x61A6, 0x918F, 0x61A7, 0xE3BF, 0x61A8, 0xBAA9, 0x61A9, 0xEDAC, 0x61AA, 0x9190, - 0x61AB, 0x9191, 0x61AC, 0xE3BD, 0x61AD, 0x9192, 0x61AE, 0x9193, 0x61AF, 0x9194, 0x61B0, 0x9195, 0x61B1, 0x9196, 0x61B2, 0x9197, - 0x61B3, 0x9198, 0x61B4, 0x9199, 0x61B5, 0x919A, 0x61B6, 0x919B, 0x61B7, 0xE3C0, 0x61B8, 0x919C, 0x61B9, 0x919D, 0x61BA, 0x919E, - 0x61BB, 0x919F, 0x61BC, 0x91A0, 0x61BD, 0x91A1, 0x61BE, 0xBAB6, 0x61BF, 0x91A2, 0x61C0, 0x91A3, 0x61C1, 0x91A4, 0x61C2, 0xB6AE, - 0x61C3, 0x91A5, 0x61C4, 0x91A6, 0x61C5, 0x91A7, 0x61C6, 0x91A8, 0x61C7, 0x91A9, 0x61C8, 0xD0B8, 0x61C9, 0x91AA, 0x61CA, 0xB0C3, - 0x61CB, 0xEDAE, 0x61CC, 0x91AB, 0x61CD, 0x91AC, 0x61CE, 0x91AD, 0x61CF, 0x91AE, 0x61D0, 0x91AF, 0x61D1, 0xEDAF, 0x61D2, 0xC0C1, - 0x61D3, 0x91B0, 0x61D4, 0xE3C1, 0x61D5, 0x91B1, 0x61D6, 0x91B2, 0x61D7, 0x91B3, 0x61D8, 0x91B4, 0x61D9, 0x91B5, 0x61DA, 0x91B6, - 0x61DB, 0x91B7, 0x61DC, 0x91B8, 0x61DD, 0x91B9, 0x61DE, 0x91BA, 0x61DF, 0x91BB, 0x61E0, 0x91BC, 0x61E1, 0x91BD, 0x61E2, 0x91BE, - 0x61E3, 0x91BF, 0x61E4, 0x91C0, 0x61E5, 0x91C1, 0x61E6, 0xC5B3, 0x61E7, 0x91C2, 0x61E8, 0x91C3, 0x61E9, 0x91C4, 0x61EA, 0x91C5, - 0x61EB, 0x91C6, 0x61EC, 0x91C7, 0x61ED, 0x91C8, 0x61EE, 0x91C9, 0x61EF, 0x91CA, 0x61F0, 0x91CB, 0x61F1, 0x91CC, 0x61F2, 0x91CD, - 0x61F3, 0x91CE, 0x61F4, 0x91CF, 0x61F5, 0xE3C2, 0x61F6, 0x91D0, 0x61F7, 0x91D1, 0x61F8, 0x91D2, 0x61F9, 0x91D3, 0x61FA, 0x91D4, - 0x61FB, 0x91D5, 0x61FC, 0x91D6, 0x61FD, 0x91D7, 0x61FE, 0x91D8, 0x61FF, 0xDCB2, 0x6200, 0x91D9, 0x6201, 0x91DA, 0x6202, 0x91DB, - 0x6203, 0x91DC, 0x6204, 0x91DD, 0x6205, 0x91DE, 0x6206, 0xEDB0, 0x6207, 0x91DF, 0x6208, 0xB8EA, 0x6209, 0x91E0, 0x620A, 0xCEEC, - 0x620B, 0xEAA7, 0x620C, 0xD0E7, 0x620D, 0xCAF9, 0x620E, 0xC8D6, 0x620F, 0xCFB7, 0x6210, 0xB3C9, 0x6211, 0xCED2, 0x6212, 0xBDE4, - 0x6213, 0x91E1, 0x6214, 0x91E2, 0x6215, 0xE3DE, 0x6216, 0xBBF2, 0x6217, 0xEAA8, 0x6218, 0xD5BD, 0x6219, 0x91E3, 0x621A, 0xC6DD, - 0x621B, 0xEAA9, 0x621C, 0x91E4, 0x621D, 0x91E5, 0x621E, 0x91E6, 0x621F, 0xEAAA, 0x6220, 0x91E7, 0x6221, 0xEAAC, 0x6222, 0xEAAB, - 0x6223, 0x91E8, 0x6224, 0xEAAE, 0x6225, 0xEAAD, 0x6226, 0x91E9, 0x6227, 0x91EA, 0x6228, 0x91EB, 0x6229, 0x91EC, 0x622A, 0xBDD8, - 0x622B, 0x91ED, 0x622C, 0xEAAF, 0x622D, 0x91EE, 0x622E, 0xC2BE, 0x622F, 0x91EF, 0x6230, 0x91F0, 0x6231, 0x91F1, 0x6232, 0x91F2, - 0x6233, 0xB4C1, 0x6234, 0xB4F7, 0x6235, 0x91F3, 0x6236, 0x91F4, 0x6237, 0xBBA7, 0x6238, 0x91F5, 0x6239, 0x91F6, 0x623A, 0x91F7, - 0x623B, 0x91F8, 0x623C, 0x91F9, 0x623D, 0xECE6, 0x623E, 0xECE5, 0x623F, 0xB7BF, 0x6240, 0xCBF9, 0x6241, 0xB1E2, 0x6242, 0x91FA, - 0x6243, 0xECE7, 0x6244, 0x91FB, 0x6245, 0x91FC, 0x6246, 0x91FD, 0x6247, 0xC9C8, 0x6248, 0xECE8, 0x6249, 0xECE9, 0x624A, 0x91FE, - 0x624B, 0xCAD6, 0x624C, 0xDED0, 0x624D, 0xB2C5, 0x624E, 0xD4FA, 0x624F, 0x9240, 0x6250, 0x9241, 0x6251, 0xC6CB, 0x6252, 0xB0C7, - 0x6253, 0xB4F2, 0x6254, 0xC8D3, 0x6255, 0x9242, 0x6256, 0x9243, 0x6257, 0x9244, 0x6258, 0xCDD0, 0x6259, 0x9245, 0x625A, 0x9246, - 0x625B, 0xBFB8, 0x625C, 0x9247, 0x625D, 0x9248, 0x625E, 0x9249, 0x625F, 0x924A, 0x6260, 0x924B, 0x6261, 0x924C, 0x6262, 0x924D, - 0x6263, 0xBFDB, 0x6264, 0x924E, 0x6265, 0x924F, 0x6266, 0xC7A4, 0x6267, 0xD6B4, 0x6268, 0x9250, 0x6269, 0xC0A9, 0x626A, 0xDED1, - 0x626B, 0xC9A8, 0x626C, 0xD1EF, 0x626D, 0xC5A4, 0x626E, 0xB0E7, 0x626F, 0xB3B6, 0x6270, 0xC8C5, 0x6271, 0x9251, 0x6272, 0x9252, - 0x6273, 0xB0E2, 0x6274, 0x9253, 0x6275, 0x9254, 0x6276, 0xB7F6, 0x6277, 0x9255, 0x6278, 0x9256, 0x6279, 0xC5FA, 0x627A, 0x9257, - 0x627B, 0x9258, 0x627C, 0xB6F3, 0x627D, 0x9259, 0x627E, 0xD5D2, 0x627F, 0xB3D0, 0x6280, 0xBCBC, 0x6281, 0x925A, 0x6282, 0x925B, - 0x6283, 0x925C, 0x6284, 0xB3AD, 0x6285, 0x925D, 0x6286, 0x925E, 0x6287, 0x925F, 0x6288, 0x9260, 0x6289, 0xBEF1, 0x628A, 0xB0D1, - 0x628B, 0x9261, 0x628C, 0x9262, 0x628D, 0x9263, 0x628E, 0x9264, 0x628F, 0x9265, 0x6290, 0x9266, 0x6291, 0xD2D6, 0x6292, 0xCAE3, - 0x6293, 0xD7A5, 0x6294, 0x9267, 0x6295, 0xCDB6, 0x6296, 0xB6B6, 0x6297, 0xBFB9, 0x6298, 0xD5DB, 0x6299, 0x9268, 0x629A, 0xB8A7, - 0x629B, 0xC5D7, 0x629C, 0x9269, 0x629D, 0x926A, 0x629E, 0x926B, 0x629F, 0xDED2, 0x62A0, 0xBFD9, 0x62A1, 0xC2D5, 0x62A2, 0xC7C0, - 0x62A3, 0x926C, 0x62A4, 0xBBA4, 0x62A5, 0xB1A8, 0x62A6, 0x926D, 0x62A7, 0x926E, 0x62A8, 0xC5EA, 0x62A9, 0x926F, 0x62AA, 0x9270, - 0x62AB, 0xC5FB, 0x62AC, 0xCCA7, 0x62AD, 0x9271, 0x62AE, 0x9272, 0x62AF, 0x9273, 0x62B0, 0x9274, 0x62B1, 0xB1A7, 0x62B2, 0x9275, - 0x62B3, 0x9276, 0x62B4, 0x9277, 0x62B5, 0xB5D6, 0x62B6, 0x9278, 0x62B7, 0x9279, 0x62B8, 0x927A, 0x62B9, 0xC4A8, 0x62BA, 0x927B, - 0x62BB, 0xDED3, 0x62BC, 0xD1BA, 0x62BD, 0xB3E9, 0x62BE, 0x927C, 0x62BF, 0xC3F2, 0x62C0, 0x927D, 0x62C1, 0x927E, 0x62C2, 0xB7F7, - 0x62C3, 0x9280, 0x62C4, 0xD6F4, 0x62C5, 0xB5A3, 0x62C6, 0xB2F0, 0x62C7, 0xC4B4, 0x62C8, 0xC4E9, 0x62C9, 0xC0AD, 0x62CA, 0xDED4, - 0x62CB, 0x9281, 0x62CC, 0xB0E8, 0x62CD, 0xC5C4, 0x62CE, 0xC1E0, 0x62CF, 0x9282, 0x62D0, 0xB9D5, 0x62D1, 0x9283, 0x62D2, 0xBEDC, - 0x62D3, 0xCDD8, 0x62D4, 0xB0CE, 0x62D5, 0x9284, 0x62D6, 0xCDCF, 0x62D7, 0xDED6, 0x62D8, 0xBED0, 0x62D9, 0xD7BE, 0x62DA, 0xDED5, - 0x62DB, 0xD5D0, 0x62DC, 0xB0DD, 0x62DD, 0x9285, 0x62DE, 0x9286, 0x62DF, 0xC4E2, 0x62E0, 0x9287, 0x62E1, 0x9288, 0x62E2, 0xC2A3, - 0x62E3, 0xBCF0, 0x62E4, 0x9289, 0x62E5, 0xD3B5, 0x62E6, 0xC0B9, 0x62E7, 0xC5A1, 0x62E8, 0xB2A6, 0x62E9, 0xD4F1, 0x62EA, 0x928A, - 0x62EB, 0x928B, 0x62EC, 0xC0A8, 0x62ED, 0xCAC3, 0x62EE, 0xDED7, 0x62EF, 0xD5FC, 0x62F0, 0x928C, 0x62F1, 0xB9B0, 0x62F2, 0x928D, - 0x62F3, 0xC8AD, 0x62F4, 0xCBA9, 0x62F5, 0x928E, 0x62F6, 0xDED9, 0x62F7, 0xBFBD, 0x62F8, 0x928F, 0x62F9, 0x9290, 0x62FA, 0x9291, - 0x62FB, 0x9292, 0x62FC, 0xC6B4, 0x62FD, 0xD7A7, 0x62FE, 0xCAB0, 0x62FF, 0xC4C3, 0x6300, 0x9293, 0x6301, 0xB3D6, 0x6302, 0xB9D2, - 0x6303, 0x9294, 0x6304, 0x9295, 0x6305, 0x9296, 0x6306, 0x9297, 0x6307, 0xD6B8, 0x6308, 0xEAFC, 0x6309, 0xB0B4, 0x630A, 0x9298, - 0x630B, 0x9299, 0x630C, 0x929A, 0x630D, 0x929B, 0x630E, 0xBFE6, 0x630F, 0x929C, 0x6310, 0x929D, 0x6311, 0xCCF4, 0x6312, 0x929E, - 0x6313, 0x929F, 0x6314, 0x92A0, 0x6315, 0x92A1, 0x6316, 0xCDDA, 0x6317, 0x92A2, 0x6318, 0x92A3, 0x6319, 0x92A4, 0x631A, 0xD6BF, - 0x631B, 0xC2CE, 0x631C, 0x92A5, 0x631D, 0xCECE, 0x631E, 0xCCA2, 0x631F, 0xD0AE, 0x6320, 0xC4D3, 0x6321, 0xB5B2, 0x6322, 0xDED8, - 0x6323, 0xD5F5, 0x6324, 0xBCB7, 0x6325, 0xBBD3, 0x6326, 0x92A6, 0x6327, 0x92A7, 0x6328, 0xB0A4, 0x6329, 0x92A8, 0x632A, 0xC5B2, - 0x632B, 0xB4EC, 0x632C, 0x92A9, 0x632D, 0x92AA, 0x632E, 0x92AB, 0x632F, 0xD5F1, 0x6330, 0x92AC, 0x6331, 0x92AD, 0x6332, 0xEAFD, - 0x6333, 0x92AE, 0x6334, 0x92AF, 0x6335, 0x92B0, 0x6336, 0x92B1, 0x6337, 0x92B2, 0x6338, 0x92B3, 0x6339, 0xDEDA, 0x633A, 0xCDA6, - 0x633B, 0x92B4, 0x633C, 0x92B5, 0x633D, 0xCDEC, 0x633E, 0x92B6, 0x633F, 0x92B7, 0x6340, 0x92B8, 0x6341, 0x92B9, 0x6342, 0xCEE6, - 0x6343, 0xDEDC, 0x6344, 0x92BA, 0x6345, 0xCDB1, 0x6346, 0xC0A6, 0x6347, 0x92BB, 0x6348, 0x92BC, 0x6349, 0xD7BD, 0x634A, 0x92BD, - 0x634B, 0xDEDB, 0x634C, 0xB0C6, 0x634D, 0xBAB4, 0x634E, 0xC9D3, 0x634F, 0xC4F3, 0x6350, 0xBEE8, 0x6351, 0x92BE, 0x6352, 0x92BF, - 0x6353, 0x92C0, 0x6354, 0x92C1, 0x6355, 0xB2B6, 0x6356, 0x92C2, 0x6357, 0x92C3, 0x6358, 0x92C4, 0x6359, 0x92C5, 0x635A, 0x92C6, - 0x635B, 0x92C7, 0x635C, 0x92C8, 0x635D, 0x92C9, 0x635E, 0xC0CC, 0x635F, 0xCBF0, 0x6360, 0x92CA, 0x6361, 0xBCF1, 0x6362, 0xBBBB, - 0x6363, 0xB5B7, 0x6364, 0x92CB, 0x6365, 0x92CC, 0x6366, 0x92CD, 0x6367, 0xC5F5, 0x6368, 0x92CE, 0x6369, 0xDEE6, 0x636A, 0x92CF, - 0x636B, 0x92D0, 0x636C, 0x92D1, 0x636D, 0xDEE3, 0x636E, 0xBEDD, 0x636F, 0x92D2, 0x6370, 0x92D3, 0x6371, 0xDEDF, 0x6372, 0x92D4, - 0x6373, 0x92D5, 0x6374, 0x92D6, 0x6375, 0x92D7, 0x6376, 0xB4B7, 0x6377, 0xBDDD, 0x6378, 0x92D8, 0x6379, 0x92D9, 0x637A, 0xDEE0, - 0x637B, 0xC4ED, 0x637C, 0x92DA, 0x637D, 0x92DB, 0x637E, 0x92DC, 0x637F, 0x92DD, 0x6380, 0xCFC6, 0x6381, 0x92DE, 0x6382, 0xB5E0, - 0x6383, 0x92DF, 0x6384, 0x92E0, 0x6385, 0x92E1, 0x6386, 0x92E2, 0x6387, 0xB6DE, 0x6388, 0xCADA, 0x6389, 0xB5F4, 0x638A, 0xDEE5, - 0x638B, 0x92E3, 0x638C, 0xD5C6, 0x638D, 0x92E4, 0x638E, 0xDEE1, 0x638F, 0xCCCD, 0x6390, 0xC6FE, 0x6391, 0x92E5, 0x6392, 0xC5C5, - 0x6393, 0x92E6, 0x6394, 0x92E7, 0x6395, 0x92E8, 0x6396, 0xD2B4, 0x6397, 0x92E9, 0x6398, 0xBEF2, 0x6399, 0x92EA, 0x639A, 0x92EB, - 0x639B, 0x92EC, 0x639C, 0x92ED, 0x639D, 0x92EE, 0x639E, 0x92EF, 0x639F, 0x92F0, 0x63A0, 0xC2D3, 0x63A1, 0x92F1, 0x63A2, 0xCCBD, - 0x63A3, 0xB3B8, 0x63A4, 0x92F2, 0x63A5, 0xBDD3, 0x63A6, 0x92F3, 0x63A7, 0xBFD8, 0x63A8, 0xCDC6, 0x63A9, 0xD1DA, 0x63AA, 0xB4EB, - 0x63AB, 0x92F4, 0x63AC, 0xDEE4, 0x63AD, 0xDEDD, 0x63AE, 0xDEE7, 0x63AF, 0x92F5, 0x63B0, 0xEAFE, 0x63B1, 0x92F6, 0x63B2, 0x92F7, - 0x63B3, 0xC2B0, 0x63B4, 0xDEE2, 0x63B5, 0x92F8, 0x63B6, 0x92F9, 0x63B7, 0xD6C0, 0x63B8, 0xB5A7, 0x63B9, 0x92FA, 0x63BA, 0xB2F4, - 0x63BB, 0x92FB, 0x63BC, 0xDEE8, 0x63BD, 0x92FC, 0x63BE, 0xDEF2, 0x63BF, 0x92FD, 0x63C0, 0x92FE, 0x63C1, 0x9340, 0x63C2, 0x9341, - 0x63C3, 0x9342, 0x63C4, 0xDEED, 0x63C5, 0x9343, 0x63C6, 0xDEF1, 0x63C7, 0x9344, 0x63C8, 0x9345, 0x63C9, 0xC8E0, 0x63CA, 0x9346, - 0x63CB, 0x9347, 0x63CC, 0x9348, 0x63CD, 0xD7E1, 0x63CE, 0xDEEF, 0x63CF, 0xC3E8, 0x63D0, 0xCCE1, 0x63D1, 0x9349, 0x63D2, 0xB2E5, - 0x63D3, 0x934A, 0x63D4, 0x934B, 0x63D5, 0x934C, 0x63D6, 0xD2BE, 0x63D7, 0x934D, 0x63D8, 0x934E, 0x63D9, 0x934F, 0x63DA, 0x9350, - 0x63DB, 0x9351, 0x63DC, 0x9352, 0x63DD, 0x9353, 0x63DE, 0xDEEE, 0x63DF, 0x9354, 0x63E0, 0xDEEB, 0x63E1, 0xCED5, 0x63E2, 0x9355, - 0x63E3, 0xB4A7, 0x63E4, 0x9356, 0x63E5, 0x9357, 0x63E6, 0x9358, 0x63E7, 0x9359, 0x63E8, 0x935A, 0x63E9, 0xBFAB, 0x63EA, 0xBEBE, - 0x63EB, 0x935B, 0x63EC, 0x935C, 0x63ED, 0xBDD2, 0x63EE, 0x935D, 0x63EF, 0x935E, 0x63F0, 0x935F, 0x63F1, 0x9360, 0x63F2, 0xDEE9, - 0x63F3, 0x9361, 0x63F4, 0xD4AE, 0x63F5, 0x9362, 0x63F6, 0xDEDE, 0x63F7, 0x9363, 0x63F8, 0xDEEA, 0x63F9, 0x9364, 0x63FA, 0x9365, - 0x63FB, 0x9366, 0x63FC, 0x9367, 0x63FD, 0xC0BF, 0x63FE, 0x9368, 0x63FF, 0xDEEC, 0x6400, 0xB2F3, 0x6401, 0xB8E9, 0x6402, 0xC2A7, - 0x6403, 0x9369, 0x6404, 0x936A, 0x6405, 0xBDC1, 0x6406, 0x936B, 0x6407, 0x936C, 0x6408, 0x936D, 0x6409, 0x936E, 0x640A, 0x936F, - 0x640B, 0xDEF5, 0x640C, 0xDEF8, 0x640D, 0x9370, 0x640E, 0x9371, 0x640F, 0xB2AB, 0x6410, 0xB4A4, 0x6411, 0x9372, 0x6412, 0x9373, - 0x6413, 0xB4EA, 0x6414, 0xC9A6, 0x6415, 0x9374, 0x6416, 0x9375, 0x6417, 0x9376, 0x6418, 0x9377, 0x6419, 0x9378, 0x641A, 0x9379, - 0x641B, 0xDEF6, 0x641C, 0xCBD1, 0x641D, 0x937A, 0x641E, 0xB8E3, 0x641F, 0x937B, 0x6420, 0xDEF7, 0x6421, 0xDEFA, 0x6422, 0x937C, - 0x6423, 0x937D, 0x6424, 0x937E, 0x6425, 0x9380, 0x6426, 0xDEF9, 0x6427, 0x9381, 0x6428, 0x9382, 0x6429, 0x9383, 0x642A, 0xCCC2, - 0x642B, 0x9384, 0x642C, 0xB0E1, 0x642D, 0xB4EE, 0x642E, 0x9385, 0x642F, 0x9386, 0x6430, 0x9387, 0x6431, 0x9388, 0x6432, 0x9389, - 0x6433, 0x938A, 0x6434, 0xE5BA, 0x6435, 0x938B, 0x6436, 0x938C, 0x6437, 0x938D, 0x6438, 0x938E, 0x6439, 0x938F, 0x643A, 0xD0AF, - 0x643B, 0x9390, 0x643C, 0x9391, 0x643D, 0xB2EB, 0x643E, 0x9392, 0x643F, 0xEBA1, 0x6440, 0x9393, 0x6441, 0xDEF4, 0x6442, 0x9394, - 0x6443, 0x9395, 0x6444, 0xC9E3, 0x6445, 0xDEF3, 0x6446, 0xB0DA, 0x6447, 0xD2A1, 0x6448, 0xB1F7, 0x6449, 0x9396, 0x644A, 0xCCAF, - 0x644B, 0x9397, 0x644C, 0x9398, 0x644D, 0x9399, 0x644E, 0x939A, 0x644F, 0x939B, 0x6450, 0x939C, 0x6451, 0x939D, 0x6452, 0xDEF0, - 0x6453, 0x939E, 0x6454, 0xCBA4, 0x6455, 0x939F, 0x6456, 0x93A0, 0x6457, 0x93A1, 0x6458, 0xD5AA, 0x6459, 0x93A2, 0x645A, 0x93A3, - 0x645B, 0x93A4, 0x645C, 0x93A5, 0x645D, 0x93A6, 0x645E, 0xDEFB, 0x645F, 0x93A7, 0x6460, 0x93A8, 0x6461, 0x93A9, 0x6462, 0x93AA, - 0x6463, 0x93AB, 0x6464, 0x93AC, 0x6465, 0x93AD, 0x6466, 0x93AE, 0x6467, 0xB4DD, 0x6468, 0x93AF, 0x6469, 0xC4A6, 0x646A, 0x93B0, - 0x646B, 0x93B1, 0x646C, 0x93B2, 0x646D, 0xDEFD, 0x646E, 0x93B3, 0x646F, 0x93B4, 0x6470, 0x93B5, 0x6471, 0x93B6, 0x6472, 0x93B7, - 0x6473, 0x93B8, 0x6474, 0x93B9, 0x6475, 0x93BA, 0x6476, 0x93BB, 0x6477, 0x93BC, 0x6478, 0xC3FE, 0x6479, 0xC4A1, 0x647A, 0xDFA1, - 0x647B, 0x93BD, 0x647C, 0x93BE, 0x647D, 0x93BF, 0x647E, 0x93C0, 0x647F, 0x93C1, 0x6480, 0x93C2, 0x6481, 0x93C3, 0x6482, 0xC1CC, - 0x6483, 0x93C4, 0x6484, 0xDEFC, 0x6485, 0xBEEF, 0x6486, 0x93C5, 0x6487, 0xC6B2, 0x6488, 0x93C6, 0x6489, 0x93C7, 0x648A, 0x93C8, - 0x648B, 0x93C9, 0x648C, 0x93CA, 0x648D, 0x93CB, 0x648E, 0x93CC, 0x648F, 0x93CD, 0x6490, 0x93CE, 0x6491, 0xB3C5, 0x6492, 0xC8F6, - 0x6493, 0x93CF, 0x6494, 0x93D0, 0x6495, 0xCBBA, 0x6496, 0xDEFE, 0x6497, 0x93D1, 0x6498, 0x93D2, 0x6499, 0xDFA4, 0x649A, 0x93D3, - 0x649B, 0x93D4, 0x649C, 0x93D5, 0x649D, 0x93D6, 0x649E, 0xD7B2, 0x649F, 0x93D7, 0x64A0, 0x93D8, 0x64A1, 0x93D9, 0x64A2, 0x93DA, - 0x64A3, 0x93DB, 0x64A4, 0xB3B7, 0x64A5, 0x93DC, 0x64A6, 0x93DD, 0x64A7, 0x93DE, 0x64A8, 0x93DF, 0x64A9, 0xC1C3, 0x64AA, 0x93E0, - 0x64AB, 0x93E1, 0x64AC, 0xC7CB, 0x64AD, 0xB2A5, 0x64AE, 0xB4E9, 0x64AF, 0x93E2, 0x64B0, 0xD7AB, 0x64B1, 0x93E3, 0x64B2, 0x93E4, - 0x64B3, 0x93E5, 0x64B4, 0x93E6, 0x64B5, 0xC4EC, 0x64B6, 0x93E7, 0x64B7, 0xDFA2, 0x64B8, 0xDFA3, 0x64B9, 0x93E8, 0x64BA, 0xDFA5, - 0x64BB, 0x93E9, 0x64BC, 0xBAB3, 0x64BD, 0x93EA, 0x64BE, 0x93EB, 0x64BF, 0x93EC, 0x64C0, 0xDFA6, 0x64C1, 0x93ED, 0x64C2, 0xC0DE, - 0x64C3, 0x93EE, 0x64C4, 0x93EF, 0x64C5, 0xC9C3, 0x64C6, 0x93F0, 0x64C7, 0x93F1, 0x64C8, 0x93F2, 0x64C9, 0x93F3, 0x64CA, 0x93F4, - 0x64CB, 0x93F5, 0x64CC, 0x93F6, 0x64CD, 0xB2D9, 0x64CE, 0xC7E6, 0x64CF, 0x93F7, 0x64D0, 0xDFA7, 0x64D1, 0x93F8, 0x64D2, 0xC7DC, - 0x64D3, 0x93F9, 0x64D4, 0x93FA, 0x64D5, 0x93FB, 0x64D6, 0x93FC, 0x64D7, 0xDFA8, 0x64D8, 0xEBA2, 0x64D9, 0x93FD, 0x64DA, 0x93FE, - 0x64DB, 0x9440, 0x64DC, 0x9441, 0x64DD, 0x9442, 0x64DE, 0xCBD3, 0x64DF, 0x9443, 0x64E0, 0x9444, 0x64E1, 0x9445, 0x64E2, 0xDFAA, - 0x64E3, 0x9446, 0x64E4, 0xDFA9, 0x64E5, 0x9447, 0x64E6, 0xB2C1, 0x64E7, 0x9448, 0x64E8, 0x9449, 0x64E9, 0x944A, 0x64EA, 0x944B, - 0x64EB, 0x944C, 0x64EC, 0x944D, 0x64ED, 0x944E, 0x64EE, 0x944F, 0x64EF, 0x9450, 0x64F0, 0x9451, 0x64F1, 0x9452, 0x64F2, 0x9453, - 0x64F3, 0x9454, 0x64F4, 0x9455, 0x64F5, 0x9456, 0x64F6, 0x9457, 0x64F7, 0x9458, 0x64F8, 0x9459, 0x64F9, 0x945A, 0x64FA, 0x945B, - 0x64FB, 0x945C, 0x64FC, 0x945D, 0x64FD, 0x945E, 0x64FE, 0x945F, 0x64FF, 0x9460, 0x6500, 0xC5CA, 0x6501, 0x9461, 0x6502, 0x9462, - 0x6503, 0x9463, 0x6504, 0x9464, 0x6505, 0x9465, 0x6506, 0x9466, 0x6507, 0x9467, 0x6508, 0x9468, 0x6509, 0xDFAB, 0x650A, 0x9469, - 0x650B, 0x946A, 0x650C, 0x946B, 0x650D, 0x946C, 0x650E, 0x946D, 0x650F, 0x946E, 0x6510, 0x946F, 0x6511, 0x9470, 0x6512, 0xD4DC, - 0x6513, 0x9471, 0x6514, 0x9472, 0x6515, 0x9473, 0x6516, 0x9474, 0x6517, 0x9475, 0x6518, 0xC8C1, 0x6519, 0x9476, 0x651A, 0x9477, - 0x651B, 0x9478, 0x651C, 0x9479, 0x651D, 0x947A, 0x651E, 0x947B, 0x651F, 0x947C, 0x6520, 0x947D, 0x6521, 0x947E, 0x6522, 0x9480, - 0x6523, 0x9481, 0x6524, 0x9482, 0x6525, 0xDFAC, 0x6526, 0x9483, 0x6527, 0x9484, 0x6528, 0x9485, 0x6529, 0x9486, 0x652A, 0x9487, - 0x652B, 0xBEF0, 0x652C, 0x9488, 0x652D, 0x9489, 0x652E, 0xDFAD, 0x652F, 0xD6A7, 0x6530, 0x948A, 0x6531, 0x948B, 0x6532, 0x948C, - 0x6533, 0x948D, 0x6534, 0xEAB7, 0x6535, 0xEBB6, 0x6536, 0xCAD5, 0x6537, 0x948E, 0x6538, 0xD8FC, 0x6539, 0xB8C4, 0x653A, 0x948F, - 0x653B, 0xB9A5, 0x653C, 0x9490, 0x653D, 0x9491, 0x653E, 0xB7C5, 0x653F, 0xD5FE, 0x6540, 0x9492, 0x6541, 0x9493, 0x6542, 0x9494, - 0x6543, 0x9495, 0x6544, 0x9496, 0x6545, 0xB9CA, 0x6546, 0x9497, 0x6547, 0x9498, 0x6548, 0xD0A7, 0x6549, 0xF4CD, 0x654A, 0x9499, - 0x654B, 0x949A, 0x654C, 0xB5D0, 0x654D, 0x949B, 0x654E, 0x949C, 0x654F, 0xC3F4, 0x6550, 0x949D, 0x6551, 0xBEC8, 0x6552, 0x949E, - 0x6553, 0x949F, 0x6554, 0x94A0, 0x6555, 0xEBB7, 0x6556, 0xB0BD, 0x6557, 0x94A1, 0x6558, 0x94A2, 0x6559, 0xBDCC, 0x655A, 0x94A3, - 0x655B, 0xC1B2, 0x655C, 0x94A4, 0x655D, 0xB1D6, 0x655E, 0xB3A8, 0x655F, 0x94A5, 0x6560, 0x94A6, 0x6561, 0x94A7, 0x6562, 0xB8D2, - 0x6563, 0xC9A2, 0x6564, 0x94A8, 0x6565, 0x94A9, 0x6566, 0xB6D8, 0x6567, 0x94AA, 0x6568, 0x94AB, 0x6569, 0x94AC, 0x656A, 0x94AD, - 0x656B, 0xEBB8, 0x656C, 0xBEB4, 0x656D, 0x94AE, 0x656E, 0x94AF, 0x656F, 0x94B0, 0x6570, 0xCAFD, 0x6571, 0x94B1, 0x6572, 0xC7C3, - 0x6573, 0x94B2, 0x6574, 0xD5FB, 0x6575, 0x94B3, 0x6576, 0x94B4, 0x6577, 0xB7F3, 0x6578, 0x94B5, 0x6579, 0x94B6, 0x657A, 0x94B7, - 0x657B, 0x94B8, 0x657C, 0x94B9, 0x657D, 0x94BA, 0x657E, 0x94BB, 0x657F, 0x94BC, 0x6580, 0x94BD, 0x6581, 0x94BE, 0x6582, 0x94BF, - 0x6583, 0x94C0, 0x6584, 0x94C1, 0x6585, 0x94C2, 0x6586, 0x94C3, 0x6587, 0xCEC4, 0x6588, 0x94C4, 0x6589, 0x94C5, 0x658A, 0x94C6, - 0x658B, 0xD5AB, 0x658C, 0xB1F3, 0x658D, 0x94C7, 0x658E, 0x94C8, 0x658F, 0x94C9, 0x6590, 0xECB3, 0x6591, 0xB0DF, 0x6592, 0x94CA, - 0x6593, 0xECB5, 0x6594, 0x94CB, 0x6595, 0x94CC, 0x6596, 0x94CD, 0x6597, 0xB6B7, 0x6598, 0x94CE, 0x6599, 0xC1CF, 0x659A, 0x94CF, - 0x659B, 0xF5FA, 0x659C, 0xD0B1, 0x659D, 0x94D0, 0x659E, 0x94D1, 0x659F, 0xD5E5, 0x65A0, 0x94D2, 0x65A1, 0xCED3, 0x65A2, 0x94D3, - 0x65A3, 0x94D4, 0x65A4, 0xBDEF, 0x65A5, 0xB3E2, 0x65A6, 0x94D5, 0x65A7, 0xB8AB, 0x65A8, 0x94D6, 0x65A9, 0xD5B6, 0x65AA, 0x94D7, - 0x65AB, 0xEDBD, 0x65AC, 0x94D8, 0x65AD, 0xB6CF, 0x65AE, 0x94D9, 0x65AF, 0xCBB9, 0x65B0, 0xD0C2, 0x65B1, 0x94DA, 0x65B2, 0x94DB, - 0x65B3, 0x94DC, 0x65B4, 0x94DD, 0x65B5, 0x94DE, 0x65B6, 0x94DF, 0x65B7, 0x94E0, 0x65B8, 0x94E1, 0x65B9, 0xB7BD, 0x65BA, 0x94E2, - 0x65BB, 0x94E3, 0x65BC, 0xECB6, 0x65BD, 0xCAA9, 0x65BE, 0x94E4, 0x65BF, 0x94E5, 0x65C0, 0x94E6, 0x65C1, 0xC5D4, 0x65C2, 0x94E7, - 0x65C3, 0xECB9, 0x65C4, 0xECB8, 0x65C5, 0xC2C3, 0x65C6, 0xECB7, 0x65C7, 0x94E8, 0x65C8, 0x94E9, 0x65C9, 0x94EA, 0x65CA, 0x94EB, - 0x65CB, 0xD0FD, 0x65CC, 0xECBA, 0x65CD, 0x94EC, 0x65CE, 0xECBB, 0x65CF, 0xD7E5, 0x65D0, 0x94ED, 0x65D1, 0x94EE, 0x65D2, 0xECBC, - 0x65D3, 0x94EF, 0x65D4, 0x94F0, 0x65D5, 0x94F1, 0x65D6, 0xECBD, 0x65D7, 0xC6EC, 0x65D8, 0x94F2, 0x65D9, 0x94F3, 0x65DA, 0x94F4, - 0x65DB, 0x94F5, 0x65DC, 0x94F6, 0x65DD, 0x94F7, 0x65DE, 0x94F8, 0x65DF, 0x94F9, 0x65E0, 0xCEDE, 0x65E1, 0x94FA, 0x65E2, 0xBCC8, - 0x65E3, 0x94FB, 0x65E4, 0x94FC, 0x65E5, 0xC8D5, 0x65E6, 0xB5A9, 0x65E7, 0xBEC9, 0x65E8, 0xD6BC, 0x65E9, 0xD4E7, 0x65EA, 0x94FD, - 0x65EB, 0x94FE, 0x65EC, 0xD1AE, 0x65ED, 0xD0F1, 0x65EE, 0xEAB8, 0x65EF, 0xEAB9, 0x65F0, 0xEABA, 0x65F1, 0xBAB5, 0x65F2, 0x9540, - 0x65F3, 0x9541, 0x65F4, 0x9542, 0x65F5, 0x9543, 0x65F6, 0xCAB1, 0x65F7, 0xBFF5, 0x65F8, 0x9544, 0x65F9, 0x9545, 0x65FA, 0xCDFA, - 0x65FB, 0x9546, 0x65FC, 0x9547, 0x65FD, 0x9548, 0x65FE, 0x9549, 0x65FF, 0x954A, 0x6600, 0xEAC0, 0x6601, 0x954B, 0x6602, 0xB0BA, - 0x6603, 0xEABE, 0x6604, 0x954C, 0x6605, 0x954D, 0x6606, 0xC0A5, 0x6607, 0x954E, 0x6608, 0x954F, 0x6609, 0x9550, 0x660A, 0xEABB, - 0x660B, 0x9551, 0x660C, 0xB2FD, 0x660D, 0x9552, 0x660E, 0xC3F7, 0x660F, 0xBBE8, 0x6610, 0x9553, 0x6611, 0x9554, 0x6612, 0x9555, - 0x6613, 0xD2D7, 0x6614, 0xCEF4, 0x6615, 0xEABF, 0x6616, 0x9556, 0x6617, 0x9557, 0x6618, 0x9558, 0x6619, 0xEABC, 0x661A, 0x9559, - 0x661B, 0x955A, 0x661C, 0x955B, 0x661D, 0xEAC3, 0x661E, 0x955C, 0x661F, 0xD0C7, 0x6620, 0xD3B3, 0x6621, 0x955D, 0x6622, 0x955E, - 0x6623, 0x955F, 0x6624, 0x9560, 0x6625, 0xB4BA, 0x6626, 0x9561, 0x6627, 0xC3C1, 0x6628, 0xD7F2, 0x6629, 0x9562, 0x662A, 0x9563, - 0x662B, 0x9564, 0x662C, 0x9565, 0x662D, 0xD5D1, 0x662E, 0x9566, 0x662F, 0xCAC7, 0x6630, 0x9567, 0x6631, 0xEAC5, 0x6632, 0x9568, - 0x6633, 0x9569, 0x6634, 0xEAC4, 0x6635, 0xEAC7, 0x6636, 0xEAC6, 0x6637, 0x956A, 0x6638, 0x956B, 0x6639, 0x956C, 0x663A, 0x956D, - 0x663B, 0x956E, 0x663C, 0xD6E7, 0x663D, 0x956F, 0x663E, 0xCFD4, 0x663F, 0x9570, 0x6640, 0x9571, 0x6641, 0xEACB, 0x6642, 0x9572, - 0x6643, 0xBBCE, 0x6644, 0x9573, 0x6645, 0x9574, 0x6646, 0x9575, 0x6647, 0x9576, 0x6648, 0x9577, 0x6649, 0x9578, 0x664A, 0x9579, - 0x664B, 0xBDFA, 0x664C, 0xC9CE, 0x664D, 0x957A, 0x664E, 0x957B, 0x664F, 0xEACC, 0x6650, 0x957C, 0x6651, 0x957D, 0x6652, 0xC9B9, - 0x6653, 0xCFFE, 0x6654, 0xEACA, 0x6655, 0xD4CE, 0x6656, 0xEACD, 0x6657, 0xEACF, 0x6658, 0x957E, 0x6659, 0x9580, 0x665A, 0xCDED, - 0x665B, 0x9581, 0x665C, 0x9582, 0x665D, 0x9583, 0x665E, 0x9584, 0x665F, 0xEAC9, 0x6660, 0x9585, 0x6661, 0xEACE, 0x6662, 0x9586, - 0x6663, 0x9587, 0x6664, 0xCEEE, 0x6665, 0x9588, 0x6666, 0xBBDE, 0x6667, 0x9589, 0x6668, 0xB3BF, 0x6669, 0x958A, 0x666A, 0x958B, - 0x666B, 0x958C, 0x666C, 0x958D, 0x666D, 0x958E, 0x666E, 0xC6D5, 0x666F, 0xBEB0, 0x6670, 0xCEFA, 0x6671, 0x958F, 0x6672, 0x9590, - 0x6673, 0x9591, 0x6674, 0xC7E7, 0x6675, 0x9592, 0x6676, 0xBEA7, 0x6677, 0xEAD0, 0x6678, 0x9593, 0x6679, 0x9594, 0x667A, 0xD6C7, - 0x667B, 0x9595, 0x667C, 0x9596, 0x667D, 0x9597, 0x667E, 0xC1C0, 0x667F, 0x9598, 0x6680, 0x9599, 0x6681, 0x959A, 0x6682, 0xD4DD, - 0x6683, 0x959B, 0x6684, 0xEAD1, 0x6685, 0x959C, 0x6686, 0x959D, 0x6687, 0xCFBE, 0x6688, 0x959E, 0x6689, 0x959F, 0x668A, 0x95A0, - 0x668B, 0x95A1, 0x668C, 0xEAD2, 0x668D, 0x95A2, 0x668E, 0x95A3, 0x668F, 0x95A4, 0x6690, 0x95A5, 0x6691, 0xCAEE, 0x6692, 0x95A6, - 0x6693, 0x95A7, 0x6694, 0x95A8, 0x6695, 0x95A9, 0x6696, 0xC5AF, 0x6697, 0xB0B5, 0x6698, 0x95AA, 0x6699, 0x95AB, 0x669A, 0x95AC, - 0x669B, 0x95AD, 0x669C, 0x95AE, 0x669D, 0xEAD4, 0x669E, 0x95AF, 0x669F, 0x95B0, 0x66A0, 0x95B1, 0x66A1, 0x95B2, 0x66A2, 0x95B3, - 0x66A3, 0x95B4, 0x66A4, 0x95B5, 0x66A5, 0x95B6, 0x66A6, 0x95B7, 0x66A7, 0xEAD3, 0x66A8, 0xF4DF, 0x66A9, 0x95B8, 0x66AA, 0x95B9, - 0x66AB, 0x95BA, 0x66AC, 0x95BB, 0x66AD, 0x95BC, 0x66AE, 0xC4BA, 0x66AF, 0x95BD, 0x66B0, 0x95BE, 0x66B1, 0x95BF, 0x66B2, 0x95C0, - 0x66B3, 0x95C1, 0x66B4, 0xB1A9, 0x66B5, 0x95C2, 0x66B6, 0x95C3, 0x66B7, 0x95C4, 0x66B8, 0x95C5, 0x66B9, 0xE5DF, 0x66BA, 0x95C6, - 0x66BB, 0x95C7, 0x66BC, 0x95C8, 0x66BD, 0x95C9, 0x66BE, 0xEAD5, 0x66BF, 0x95CA, 0x66C0, 0x95CB, 0x66C1, 0x95CC, 0x66C2, 0x95CD, - 0x66C3, 0x95CE, 0x66C4, 0x95CF, 0x66C5, 0x95D0, 0x66C6, 0x95D1, 0x66C7, 0x95D2, 0x66C8, 0x95D3, 0x66C9, 0x95D4, 0x66CA, 0x95D5, - 0x66CB, 0x95D6, 0x66CC, 0x95D7, 0x66CD, 0x95D8, 0x66CE, 0x95D9, 0x66CF, 0x95DA, 0x66D0, 0x95DB, 0x66D1, 0x95DC, 0x66D2, 0x95DD, - 0x66D3, 0x95DE, 0x66D4, 0x95DF, 0x66D5, 0x95E0, 0x66D6, 0x95E1, 0x66D7, 0x95E2, 0x66D8, 0x95E3, 0x66D9, 0xCAEF, 0x66DA, 0x95E4, - 0x66DB, 0xEAD6, 0x66DC, 0xEAD7, 0x66DD, 0xC6D8, 0x66DE, 0x95E5, 0x66DF, 0x95E6, 0x66E0, 0x95E7, 0x66E1, 0x95E8, 0x66E2, 0x95E9, - 0x66E3, 0x95EA, 0x66E4, 0x95EB, 0x66E5, 0x95EC, 0x66E6, 0xEAD8, 0x66E7, 0x95ED, 0x66E8, 0x95EE, 0x66E9, 0xEAD9, 0x66EA, 0x95EF, - 0x66EB, 0x95F0, 0x66EC, 0x95F1, 0x66ED, 0x95F2, 0x66EE, 0x95F3, 0x66EF, 0x95F4, 0x66F0, 0xD4BB, 0x66F1, 0x95F5, 0x66F2, 0xC7FA, - 0x66F3, 0xD2B7, 0x66F4, 0xB8FC, 0x66F5, 0x95F6, 0x66F6, 0x95F7, 0x66F7, 0xEAC2, 0x66F8, 0x95F8, 0x66F9, 0xB2DC, 0x66FA, 0x95F9, - 0x66FB, 0x95FA, 0x66FC, 0xC2FC, 0x66FD, 0x95FB, 0x66FE, 0xD4F8, 0x66FF, 0xCCE6, 0x6700, 0xD7EE, 0x6701, 0x95FC, 0x6702, 0x95FD, - 0x6703, 0x95FE, 0x6704, 0x9640, 0x6705, 0x9641, 0x6706, 0x9642, 0x6707, 0x9643, 0x6708, 0xD4C2, 0x6709, 0xD3D0, 0x670A, 0xEBC3, - 0x670B, 0xC5F3, 0x670C, 0x9644, 0x670D, 0xB7FE, 0x670E, 0x9645, 0x670F, 0x9646, 0x6710, 0xEBD4, 0x6711, 0x9647, 0x6712, 0x9648, - 0x6713, 0x9649, 0x6714, 0xCBB7, 0x6715, 0xEBDE, 0x6716, 0x964A, 0x6717, 0xC0CA, 0x6718, 0x964B, 0x6719, 0x964C, 0x671A, 0x964D, - 0x671B, 0xCDFB, 0x671C, 0x964E, 0x671D, 0xB3AF, 0x671E, 0x964F, 0x671F, 0xC6DA, 0x6720, 0x9650, 0x6721, 0x9651, 0x6722, 0x9652, - 0x6723, 0x9653, 0x6724, 0x9654, 0x6725, 0x9655, 0x6726, 0xEBFC, 0x6727, 0x9656, 0x6728, 0xC4BE, 0x6729, 0x9657, 0x672A, 0xCEB4, - 0x672B, 0xC4A9, 0x672C, 0xB1BE, 0x672D, 0xD4FD, 0x672E, 0x9658, 0x672F, 0xCAF5, 0x6730, 0x9659, 0x6731, 0xD6EC, 0x6732, 0x965A, - 0x6733, 0x965B, 0x6734, 0xC6D3, 0x6735, 0xB6E4, 0x6736, 0x965C, 0x6737, 0x965D, 0x6738, 0x965E, 0x6739, 0x965F, 0x673A, 0xBBFA, - 0x673B, 0x9660, 0x673C, 0x9661, 0x673D, 0xD0E0, 0x673E, 0x9662, 0x673F, 0x9663, 0x6740, 0xC9B1, 0x6741, 0x9664, 0x6742, 0xD4D3, - 0x6743, 0xC8A8, 0x6744, 0x9665, 0x6745, 0x9666, 0x6746, 0xB8CB, 0x6747, 0x9667, 0x6748, 0xE8BE, 0x6749, 0xC9BC, 0x674A, 0x9668, - 0x674B, 0x9669, 0x674C, 0xE8BB, 0x674D, 0x966A, 0x674E, 0xC0EE, 0x674F, 0xD0D3, 0x6750, 0xB2C4, 0x6751, 0xB4E5, 0x6752, 0x966B, - 0x6753, 0xE8BC, 0x6754, 0x966C, 0x6755, 0x966D, 0x6756, 0xD5C8, 0x6757, 0x966E, 0x6758, 0x966F, 0x6759, 0x9670, 0x675A, 0x9671, - 0x675B, 0x9672, 0x675C, 0xB6C5, 0x675D, 0x9673, 0x675E, 0xE8BD, 0x675F, 0xCAF8, 0x6760, 0xB8DC, 0x6761, 0xCCF5, 0x6762, 0x9674, - 0x6763, 0x9675, 0x6764, 0x9676, 0x6765, 0xC0B4, 0x6766, 0x9677, 0x6767, 0x9678, 0x6768, 0xD1EE, 0x6769, 0xE8BF, 0x676A, 0xE8C2, - 0x676B, 0x9679, 0x676C, 0x967A, 0x676D, 0xBABC, 0x676E, 0x967B, 0x676F, 0xB1AD, 0x6770, 0xBDDC, 0x6771, 0x967C, 0x6772, 0xEABD, - 0x6773, 0xE8C3, 0x6774, 0x967D, 0x6775, 0xE8C6, 0x6776, 0x967E, 0x6777, 0xE8CB, 0x6778, 0x9680, 0x6779, 0x9681, 0x677A, 0x9682, - 0x677B, 0x9683, 0x677C, 0xE8CC, 0x677D, 0x9684, 0x677E, 0xCBC9, 0x677F, 0xB0E5, 0x6780, 0x9685, 0x6781, 0xBCAB, 0x6782, 0x9686, - 0x6783, 0x9687, 0x6784, 0xB9B9, 0x6785, 0x9688, 0x6786, 0x9689, 0x6787, 0xE8C1, 0x6788, 0x968A, 0x6789, 0xCDF7, 0x678A, 0x968B, - 0x678B, 0xE8CA, 0x678C, 0x968C, 0x678D, 0x968D, 0x678E, 0x968E, 0x678F, 0x968F, 0x6790, 0xCEF6, 0x6791, 0x9690, 0x6792, 0x9691, - 0x6793, 0x9692, 0x6794, 0x9693, 0x6795, 0xD5ED, 0x6796, 0x9694, 0x6797, 0xC1D6, 0x6798, 0xE8C4, 0x6799, 0x9695, 0x679A, 0xC3B6, - 0x679B, 0x9696, 0x679C, 0xB9FB, 0x679D, 0xD6A6, 0x679E, 0xE8C8, 0x679F, 0x9697, 0x67A0, 0x9698, 0x67A1, 0x9699, 0x67A2, 0xCAE0, - 0x67A3, 0xD4E6, 0x67A4, 0x969A, 0x67A5, 0xE8C0, 0x67A6, 0x969B, 0x67A7, 0xE8C5, 0x67A8, 0xE8C7, 0x67A9, 0x969C, 0x67AA, 0xC7B9, - 0x67AB, 0xB7E3, 0x67AC, 0x969D, 0x67AD, 0xE8C9, 0x67AE, 0x969E, 0x67AF, 0xBFDD, 0x67B0, 0xE8D2, 0x67B1, 0x969F, 0x67B2, 0x96A0, - 0x67B3, 0xE8D7, 0x67B4, 0x96A1, 0x67B5, 0xE8D5, 0x67B6, 0xBCDC, 0x67B7, 0xBCCF, 0x67B8, 0xE8DB, 0x67B9, 0x96A2, 0x67BA, 0x96A3, - 0x67BB, 0x96A4, 0x67BC, 0x96A5, 0x67BD, 0x96A6, 0x67BE, 0x96A7, 0x67BF, 0x96A8, 0x67C0, 0x96A9, 0x67C1, 0xE8DE, 0x67C2, 0x96AA, - 0x67C3, 0xE8DA, 0x67C4, 0xB1FA, 0x67C5, 0x96AB, 0x67C6, 0x96AC, 0x67C7, 0x96AD, 0x67C8, 0x96AE, 0x67C9, 0x96AF, 0x67CA, 0x96B0, - 0x67CB, 0x96B1, 0x67CC, 0x96B2, 0x67CD, 0x96B3, 0x67CE, 0x96B4, 0x67CF, 0xB0D8, 0x67D0, 0xC4B3, 0x67D1, 0xB8CC, 0x67D2, 0xC6E2, - 0x67D3, 0xC8BE, 0x67D4, 0xC8E1, 0x67D5, 0x96B5, 0x67D6, 0x96B6, 0x67D7, 0x96B7, 0x67D8, 0xE8CF, 0x67D9, 0xE8D4, 0x67DA, 0xE8D6, - 0x67DB, 0x96B8, 0x67DC, 0xB9F1, 0x67DD, 0xE8D8, 0x67DE, 0xD7F5, 0x67DF, 0x96B9, 0x67E0, 0xC4FB, 0x67E1, 0x96BA, 0x67E2, 0xE8DC, - 0x67E3, 0x96BB, 0x67E4, 0x96BC, 0x67E5, 0xB2E9, 0x67E6, 0x96BD, 0x67E7, 0x96BE, 0x67E8, 0x96BF, 0x67E9, 0xE8D1, 0x67EA, 0x96C0, - 0x67EB, 0x96C1, 0x67EC, 0xBCED, 0x67ED, 0x96C2, 0x67EE, 0x96C3, 0x67EF, 0xBFC2, 0x67F0, 0xE8CD, 0x67F1, 0xD6F9, 0x67F2, 0x96C4, - 0x67F3, 0xC1F8, 0x67F4, 0xB2F1, 0x67F5, 0x96C5, 0x67F6, 0x96C6, 0x67F7, 0x96C7, 0x67F8, 0x96C8, 0x67F9, 0x96C9, 0x67FA, 0x96CA, - 0x67FB, 0x96CB, 0x67FC, 0x96CC, 0x67FD, 0xE8DF, 0x67FE, 0x96CD, 0x67FF, 0xCAC1, 0x6800, 0xE8D9, 0x6801, 0x96CE, 0x6802, 0x96CF, - 0x6803, 0x96D0, 0x6804, 0x96D1, 0x6805, 0xD5A4, 0x6806, 0x96D2, 0x6807, 0xB1EA, 0x6808, 0xD5BB, 0x6809, 0xE8CE, 0x680A, 0xE8D0, - 0x680B, 0xB6B0, 0x680C, 0xE8D3, 0x680D, 0x96D3, 0x680E, 0xE8DD, 0x680F, 0xC0B8, 0x6810, 0x96D4, 0x6811, 0xCAF7, 0x6812, 0x96D5, - 0x6813, 0xCBA8, 0x6814, 0x96D6, 0x6815, 0x96D7, 0x6816, 0xC6DC, 0x6817, 0xC0F5, 0x6818, 0x96D8, 0x6819, 0x96D9, 0x681A, 0x96DA, - 0x681B, 0x96DB, 0x681C, 0x96DC, 0x681D, 0xE8E9, 0x681E, 0x96DD, 0x681F, 0x96DE, 0x6820, 0x96DF, 0x6821, 0xD0A3, 0x6822, 0x96E0, - 0x6823, 0x96E1, 0x6824, 0x96E2, 0x6825, 0x96E3, 0x6826, 0x96E4, 0x6827, 0x96E5, 0x6828, 0x96E6, 0x6829, 0xE8F2, 0x682A, 0xD6EA, - 0x682B, 0x96E7, 0x682C, 0x96E8, 0x682D, 0x96E9, 0x682E, 0x96EA, 0x682F, 0x96EB, 0x6830, 0x96EC, 0x6831, 0x96ED, 0x6832, 0xE8E0, - 0x6833, 0xE8E1, 0x6834, 0x96EE, 0x6835, 0x96EF, 0x6836, 0x96F0, 0x6837, 0xD1F9, 0x6838, 0xBACB, 0x6839, 0xB8F9, 0x683A, 0x96F1, - 0x683B, 0x96F2, 0x683C, 0xB8F1, 0x683D, 0xD4D4, 0x683E, 0xE8EF, 0x683F, 0x96F3, 0x6840, 0xE8EE, 0x6841, 0xE8EC, 0x6842, 0xB9F0, - 0x6843, 0xCCD2, 0x6844, 0xE8E6, 0x6845, 0xCEA6, 0x6846, 0xBFF2, 0x6847, 0x96F4, 0x6848, 0xB0B8, 0x6849, 0xE8F1, 0x684A, 0xE8F0, - 0x684B, 0x96F5, 0x684C, 0xD7C0, 0x684D, 0x96F6, 0x684E, 0xE8E4, 0x684F, 0x96F7, 0x6850, 0xCDA9, 0x6851, 0xC9A3, 0x6852, 0x96F8, - 0x6853, 0xBBB8, 0x6854, 0xBDDB, 0x6855, 0xE8EA, 0x6856, 0x96F9, 0x6857, 0x96FA, 0x6858, 0x96FB, 0x6859, 0x96FC, 0x685A, 0x96FD, - 0x685B, 0x96FE, 0x685C, 0x9740, 0x685D, 0x9741, 0x685E, 0x9742, 0x685F, 0x9743, 0x6860, 0xE8E2, 0x6861, 0xE8E3, 0x6862, 0xE8E5, - 0x6863, 0xB5B5, 0x6864, 0xE8E7, 0x6865, 0xC7C5, 0x6866, 0xE8EB, 0x6867, 0xE8ED, 0x6868, 0xBDB0, 0x6869, 0xD7AE, 0x686A, 0x9744, - 0x686B, 0xE8F8, 0x686C, 0x9745, 0x686D, 0x9746, 0x686E, 0x9747, 0x686F, 0x9748, 0x6870, 0x9749, 0x6871, 0x974A, 0x6872, 0x974B, - 0x6873, 0x974C, 0x6874, 0xE8F5, 0x6875, 0x974D, 0x6876, 0xCDB0, 0x6877, 0xE8F6, 0x6878, 0x974E, 0x6879, 0x974F, 0x687A, 0x9750, - 0x687B, 0x9751, 0x687C, 0x9752, 0x687D, 0x9753, 0x687E, 0x9754, 0x687F, 0x9755, 0x6880, 0x9756, 0x6881, 0xC1BA, 0x6882, 0x9757, - 0x6883, 0xE8E8, 0x6884, 0x9758, 0x6885, 0xC3B7, 0x6886, 0xB0F0, 0x6887, 0x9759, 0x6888, 0x975A, 0x6889, 0x975B, 0x688A, 0x975C, - 0x688B, 0x975D, 0x688C, 0x975E, 0x688D, 0x975F, 0x688E, 0x9760, 0x688F, 0xE8F4, 0x6890, 0x9761, 0x6891, 0x9762, 0x6892, 0x9763, - 0x6893, 0xE8F7, 0x6894, 0x9764, 0x6895, 0x9765, 0x6896, 0x9766, 0x6897, 0xB9A3, 0x6898, 0x9767, 0x6899, 0x9768, 0x689A, 0x9769, - 0x689B, 0x976A, 0x689C, 0x976B, 0x689D, 0x976C, 0x689E, 0x976D, 0x689F, 0x976E, 0x68A0, 0x976F, 0x68A1, 0x9770, 0x68A2, 0xC9D2, - 0x68A3, 0x9771, 0x68A4, 0x9772, 0x68A5, 0x9773, 0x68A6, 0xC3CE, 0x68A7, 0xCEE0, 0x68A8, 0xC0E6, 0x68A9, 0x9774, 0x68AA, 0x9775, - 0x68AB, 0x9776, 0x68AC, 0x9777, 0x68AD, 0xCBF3, 0x68AE, 0x9778, 0x68AF, 0xCCDD, 0x68B0, 0xD0B5, 0x68B1, 0x9779, 0x68B2, 0x977A, - 0x68B3, 0xCAE1, 0x68B4, 0x977B, 0x68B5, 0xE8F3, 0x68B6, 0x977C, 0x68B7, 0x977D, 0x68B8, 0x977E, 0x68B9, 0x9780, 0x68BA, 0x9781, - 0x68BB, 0x9782, 0x68BC, 0x9783, 0x68BD, 0x9784, 0x68BE, 0x9785, 0x68BF, 0x9786, 0x68C0, 0xBCEC, 0x68C1, 0x9787, 0x68C2, 0xE8F9, - 0x68C3, 0x9788, 0x68C4, 0x9789, 0x68C5, 0x978A, 0x68C6, 0x978B, 0x68C7, 0x978C, 0x68C8, 0x978D, 0x68C9, 0xC3DE, 0x68CA, 0x978E, - 0x68CB, 0xC6E5, 0x68CC, 0x978F, 0x68CD, 0xB9F7, 0x68CE, 0x9790, 0x68CF, 0x9791, 0x68D0, 0x9792, 0x68D1, 0x9793, 0x68D2, 0xB0F4, - 0x68D3, 0x9794, 0x68D4, 0x9795, 0x68D5, 0xD7D8, 0x68D6, 0x9796, 0x68D7, 0x9797, 0x68D8, 0xBCAC, 0x68D9, 0x9798, 0x68DA, 0xC5EF, - 0x68DB, 0x9799, 0x68DC, 0x979A, 0x68DD, 0x979B, 0x68DE, 0x979C, 0x68DF, 0x979D, 0x68E0, 0xCCC4, 0x68E1, 0x979E, 0x68E2, 0x979F, - 0x68E3, 0xE9A6, 0x68E4, 0x97A0, 0x68E5, 0x97A1, 0x68E6, 0x97A2, 0x68E7, 0x97A3, 0x68E8, 0x97A4, 0x68E9, 0x97A5, 0x68EA, 0x97A6, - 0x68EB, 0x97A7, 0x68EC, 0x97A8, 0x68ED, 0x97A9, 0x68EE, 0xC9AD, 0x68EF, 0x97AA, 0x68F0, 0xE9A2, 0x68F1, 0xC0E2, 0x68F2, 0x97AB, - 0x68F3, 0x97AC, 0x68F4, 0x97AD, 0x68F5, 0xBFC3, 0x68F6, 0x97AE, 0x68F7, 0x97AF, 0x68F8, 0x97B0, 0x68F9, 0xE8FE, 0x68FA, 0xB9D7, - 0x68FB, 0x97B1, 0x68FC, 0xE8FB, 0x68FD, 0x97B2, 0x68FE, 0x97B3, 0x68FF, 0x97B4, 0x6900, 0x97B5, 0x6901, 0xE9A4, 0x6902, 0x97B6, - 0x6903, 0x97B7, 0x6904, 0x97B8, 0x6905, 0xD2CE, 0x6906, 0x97B9, 0x6907, 0x97BA, 0x6908, 0x97BB, 0x6909, 0x97BC, 0x690A, 0x97BD, - 0x690B, 0xE9A3, 0x690C, 0x97BE, 0x690D, 0xD6B2, 0x690E, 0xD7B5, 0x690F, 0x97BF, 0x6910, 0xE9A7, 0x6911, 0x97C0, 0x6912, 0xBDB7, - 0x6913, 0x97C1, 0x6914, 0x97C2, 0x6915, 0x97C3, 0x6916, 0x97C4, 0x6917, 0x97C5, 0x6918, 0x97C6, 0x6919, 0x97C7, 0x691A, 0x97C8, - 0x691B, 0x97C9, 0x691C, 0x97CA, 0x691D, 0x97CB, 0x691E, 0x97CC, 0x691F, 0xE8FC, 0x6920, 0xE8FD, 0x6921, 0x97CD, 0x6922, 0x97CE, - 0x6923, 0x97CF, 0x6924, 0xE9A1, 0x6925, 0x97D0, 0x6926, 0x97D1, 0x6927, 0x97D2, 0x6928, 0x97D3, 0x6929, 0x97D4, 0x692A, 0x97D5, - 0x692B, 0x97D6, 0x692C, 0x97D7, 0x692D, 0xCDD6, 0x692E, 0x97D8, 0x692F, 0x97D9, 0x6930, 0xD2AC, 0x6931, 0x97DA, 0x6932, 0x97DB, - 0x6933, 0x97DC, 0x6934, 0xE9B2, 0x6935, 0x97DD, 0x6936, 0x97DE, 0x6937, 0x97DF, 0x6938, 0x97E0, 0x6939, 0xE9A9, 0x693A, 0x97E1, - 0x693B, 0x97E2, 0x693C, 0x97E3, 0x693D, 0xB4AA, 0x693E, 0x97E4, 0x693F, 0xB4BB, 0x6940, 0x97E5, 0x6941, 0x97E6, 0x6942, 0xE9AB, - 0x6943, 0x97E7, 0x6944, 0x97E8, 0x6945, 0x97E9, 0x6946, 0x97EA, 0x6947, 0x97EB, 0x6948, 0x97EC, 0x6949, 0x97ED, 0x694A, 0x97EE, - 0x694B, 0x97EF, 0x694C, 0x97F0, 0x694D, 0x97F1, 0x694E, 0x97F2, 0x694F, 0x97F3, 0x6950, 0x97F4, 0x6951, 0x97F5, 0x6952, 0x97F6, - 0x6953, 0x97F7, 0x6954, 0xD0A8, 0x6955, 0x97F8, 0x6956, 0x97F9, 0x6957, 0xE9A5, 0x6958, 0x97FA, 0x6959, 0x97FB, 0x695A, 0xB3FE, - 0x695B, 0x97FC, 0x695C, 0x97FD, 0x695D, 0xE9AC, 0x695E, 0xC0E3, 0x695F, 0x97FE, 0x6960, 0xE9AA, 0x6961, 0x9840, 0x6962, 0x9841, - 0x6963, 0xE9B9, 0x6964, 0x9842, 0x6965, 0x9843, 0x6966, 0xE9B8, 0x6967, 0x9844, 0x6968, 0x9845, 0x6969, 0x9846, 0x696A, 0x9847, - 0x696B, 0xE9AE, 0x696C, 0x9848, 0x696D, 0x9849, 0x696E, 0xE8FA, 0x696F, 0x984A, 0x6970, 0x984B, 0x6971, 0xE9A8, 0x6972, 0x984C, - 0x6973, 0x984D, 0x6974, 0x984E, 0x6975, 0x984F, 0x6976, 0x9850, 0x6977, 0xBFAC, 0x6978, 0xE9B1, 0x6979, 0xE9BA, 0x697A, 0x9851, - 0x697B, 0x9852, 0x697C, 0xC2A5, 0x697D, 0x9853, 0x697E, 0x9854, 0x697F, 0x9855, 0x6980, 0xE9AF, 0x6981, 0x9856, 0x6982, 0xB8C5, - 0x6983, 0x9857, 0x6984, 0xE9AD, 0x6985, 0x9858, 0x6986, 0xD3DC, 0x6987, 0xE9B4, 0x6988, 0xE9B5, 0x6989, 0xE9B7, 0x698A, 0x9859, - 0x698B, 0x985A, 0x698C, 0x985B, 0x698D, 0xE9C7, 0x698E, 0x985C, 0x698F, 0x985D, 0x6990, 0x985E, 0x6991, 0x985F, 0x6992, 0x9860, - 0x6993, 0x9861, 0x6994, 0xC0C6, 0x6995, 0xE9C5, 0x6996, 0x9862, 0x6997, 0x9863, 0x6998, 0xE9B0, 0x6999, 0x9864, 0x699A, 0x9865, - 0x699B, 0xE9BB, 0x699C, 0xB0F1, 0x699D, 0x9866, 0x699E, 0x9867, 0x699F, 0x9868, 0x69A0, 0x9869, 0x69A1, 0x986A, 0x69A2, 0x986B, - 0x69A3, 0x986C, 0x69A4, 0x986D, 0x69A5, 0x986E, 0x69A6, 0x986F, 0x69A7, 0xE9BC, 0x69A8, 0xD5A5, 0x69A9, 0x9870, 0x69AA, 0x9871, - 0x69AB, 0xE9BE, 0x69AC, 0x9872, 0x69AD, 0xE9BF, 0x69AE, 0x9873, 0x69AF, 0x9874, 0x69B0, 0x9875, 0x69B1, 0xE9C1, 0x69B2, 0x9876, - 0x69B3, 0x9877, 0x69B4, 0xC1F1, 0x69B5, 0x9878, 0x69B6, 0x9879, 0x69B7, 0xC8B6, 0x69B8, 0x987A, 0x69B9, 0x987B, 0x69BA, 0x987C, - 0x69BB, 0xE9BD, 0x69BC, 0x987D, 0x69BD, 0x987E, 0x69BE, 0x9880, 0x69BF, 0x9881, 0x69C0, 0x9882, 0x69C1, 0xE9C2, 0x69C2, 0x9883, - 0x69C3, 0x9884, 0x69C4, 0x9885, 0x69C5, 0x9886, 0x69C6, 0x9887, 0x69C7, 0x9888, 0x69C8, 0x9889, 0x69C9, 0x988A, 0x69CA, 0xE9C3, - 0x69CB, 0x988B, 0x69CC, 0xE9B3, 0x69CD, 0x988C, 0x69CE, 0xE9B6, 0x69CF, 0x988D, 0x69D0, 0xBBB1, 0x69D1, 0x988E, 0x69D2, 0x988F, - 0x69D3, 0x9890, 0x69D4, 0xE9C0, 0x69D5, 0x9891, 0x69D6, 0x9892, 0x69D7, 0x9893, 0x69D8, 0x9894, 0x69D9, 0x9895, 0x69DA, 0x9896, - 0x69DB, 0xBCF7, 0x69DC, 0x9897, 0x69DD, 0x9898, 0x69DE, 0x9899, 0x69DF, 0xE9C4, 0x69E0, 0xE9C6, 0x69E1, 0x989A, 0x69E2, 0x989B, - 0x69E3, 0x989C, 0x69E4, 0x989D, 0x69E5, 0x989E, 0x69E6, 0x989F, 0x69E7, 0x98A0, 0x69E8, 0x98A1, 0x69E9, 0x98A2, 0x69EA, 0x98A3, - 0x69EB, 0x98A4, 0x69EC, 0x98A5, 0x69ED, 0xE9CA, 0x69EE, 0x98A6, 0x69EF, 0x98A7, 0x69F0, 0x98A8, 0x69F1, 0x98A9, 0x69F2, 0xE9CE, - 0x69F3, 0x98AA, 0x69F4, 0x98AB, 0x69F5, 0x98AC, 0x69F6, 0x98AD, 0x69F7, 0x98AE, 0x69F8, 0x98AF, 0x69F9, 0x98B0, 0x69FA, 0x98B1, - 0x69FB, 0x98B2, 0x69FC, 0x98B3, 0x69FD, 0xB2DB, 0x69FE, 0x98B4, 0x69FF, 0xE9C8, 0x6A00, 0x98B5, 0x6A01, 0x98B6, 0x6A02, 0x98B7, - 0x6A03, 0x98B8, 0x6A04, 0x98B9, 0x6A05, 0x98BA, 0x6A06, 0x98BB, 0x6A07, 0x98BC, 0x6A08, 0x98BD, 0x6A09, 0x98BE, 0x6A0A, 0xB7AE, - 0x6A0B, 0x98BF, 0x6A0C, 0x98C0, 0x6A0D, 0x98C1, 0x6A0E, 0x98C2, 0x6A0F, 0x98C3, 0x6A10, 0x98C4, 0x6A11, 0x98C5, 0x6A12, 0x98C6, - 0x6A13, 0x98C7, 0x6A14, 0x98C8, 0x6A15, 0x98C9, 0x6A16, 0x98CA, 0x6A17, 0xE9CB, 0x6A18, 0xE9CC, 0x6A19, 0x98CB, 0x6A1A, 0x98CC, - 0x6A1B, 0x98CD, 0x6A1C, 0x98CE, 0x6A1D, 0x98CF, 0x6A1E, 0x98D0, 0x6A1F, 0xD5C1, 0x6A20, 0x98D1, 0x6A21, 0xC4A3, 0x6A22, 0x98D2, - 0x6A23, 0x98D3, 0x6A24, 0x98D4, 0x6A25, 0x98D5, 0x6A26, 0x98D6, 0x6A27, 0x98D7, 0x6A28, 0xE9D8, 0x6A29, 0x98D8, 0x6A2A, 0xBAE1, - 0x6A2B, 0x98D9, 0x6A2C, 0x98DA, 0x6A2D, 0x98DB, 0x6A2E, 0x98DC, 0x6A2F, 0xE9C9, 0x6A30, 0x98DD, 0x6A31, 0xD3A3, 0x6A32, 0x98DE, - 0x6A33, 0x98DF, 0x6A34, 0x98E0, 0x6A35, 0xE9D4, 0x6A36, 0x98E1, 0x6A37, 0x98E2, 0x6A38, 0x98E3, 0x6A39, 0x98E4, 0x6A3A, 0x98E5, - 0x6A3B, 0x98E6, 0x6A3C, 0x98E7, 0x6A3D, 0xE9D7, 0x6A3E, 0xE9D0, 0x6A3F, 0x98E8, 0x6A40, 0x98E9, 0x6A41, 0x98EA, 0x6A42, 0x98EB, - 0x6A43, 0x98EC, 0x6A44, 0xE9CF, 0x6A45, 0x98ED, 0x6A46, 0x98EE, 0x6A47, 0xC7C1, 0x6A48, 0x98EF, 0x6A49, 0x98F0, 0x6A4A, 0x98F1, - 0x6A4B, 0x98F2, 0x6A4C, 0x98F3, 0x6A4D, 0x98F4, 0x6A4E, 0x98F5, 0x6A4F, 0x98F6, 0x6A50, 0xE9D2, 0x6A51, 0x98F7, 0x6A52, 0x98F8, - 0x6A53, 0x98F9, 0x6A54, 0x98FA, 0x6A55, 0x98FB, 0x6A56, 0x98FC, 0x6A57, 0x98FD, 0x6A58, 0xE9D9, 0x6A59, 0xB3C8, 0x6A5A, 0x98FE, - 0x6A5B, 0xE9D3, 0x6A5C, 0x9940, 0x6A5D, 0x9941, 0x6A5E, 0x9942, 0x6A5F, 0x9943, 0x6A60, 0x9944, 0x6A61, 0xCFF0, 0x6A62, 0x9945, - 0x6A63, 0x9946, 0x6A64, 0x9947, 0x6A65, 0xE9CD, 0x6A66, 0x9948, 0x6A67, 0x9949, 0x6A68, 0x994A, 0x6A69, 0x994B, 0x6A6A, 0x994C, - 0x6A6B, 0x994D, 0x6A6C, 0x994E, 0x6A6D, 0x994F, 0x6A6E, 0x9950, 0x6A6F, 0x9951, 0x6A70, 0x9952, 0x6A71, 0xB3F7, 0x6A72, 0x9953, - 0x6A73, 0x9954, 0x6A74, 0x9955, 0x6A75, 0x9956, 0x6A76, 0x9957, 0x6A77, 0x9958, 0x6A78, 0x9959, 0x6A79, 0xE9D6, 0x6A7A, 0x995A, - 0x6A7B, 0x995B, 0x6A7C, 0xE9DA, 0x6A7D, 0x995C, 0x6A7E, 0x995D, 0x6A7F, 0x995E, 0x6A80, 0xCCB4, 0x6A81, 0x995F, 0x6A82, 0x9960, - 0x6A83, 0x9961, 0x6A84, 0xCFAD, 0x6A85, 0x9962, 0x6A86, 0x9963, 0x6A87, 0x9964, 0x6A88, 0x9965, 0x6A89, 0x9966, 0x6A8A, 0x9967, - 0x6A8B, 0x9968, 0x6A8C, 0x9969, 0x6A8D, 0x996A, 0x6A8E, 0xE9D5, 0x6A8F, 0x996B, 0x6A90, 0xE9DC, 0x6A91, 0xE9DB, 0x6A92, 0x996C, - 0x6A93, 0x996D, 0x6A94, 0x996E, 0x6A95, 0x996F, 0x6A96, 0x9970, 0x6A97, 0xE9DE, 0x6A98, 0x9971, 0x6A99, 0x9972, 0x6A9A, 0x9973, - 0x6A9B, 0x9974, 0x6A9C, 0x9975, 0x6A9D, 0x9976, 0x6A9E, 0x9977, 0x6A9F, 0x9978, 0x6AA0, 0xE9D1, 0x6AA1, 0x9979, 0x6AA2, 0x997A, - 0x6AA3, 0x997B, 0x6AA4, 0x997C, 0x6AA5, 0x997D, 0x6AA6, 0x997E, 0x6AA7, 0x9980, 0x6AA8, 0x9981, 0x6AA9, 0xE9DD, 0x6AAA, 0x9982, - 0x6AAB, 0xE9DF, 0x6AAC, 0xC3CA, 0x6AAD, 0x9983, 0x6AAE, 0x9984, 0x6AAF, 0x9985, 0x6AB0, 0x9986, 0x6AB1, 0x9987, 0x6AB2, 0x9988, - 0x6AB3, 0x9989, 0x6AB4, 0x998A, 0x6AB5, 0x998B, 0x6AB6, 0x998C, 0x6AB7, 0x998D, 0x6AB8, 0x998E, 0x6AB9, 0x998F, 0x6ABA, 0x9990, - 0x6ABB, 0x9991, 0x6ABC, 0x9992, 0x6ABD, 0x9993, 0x6ABE, 0x9994, 0x6ABF, 0x9995, 0x6AC0, 0x9996, 0x6AC1, 0x9997, 0x6AC2, 0x9998, - 0x6AC3, 0x9999, 0x6AC4, 0x999A, 0x6AC5, 0x999B, 0x6AC6, 0x999C, 0x6AC7, 0x999D, 0x6AC8, 0x999E, 0x6AC9, 0x999F, 0x6ACA, 0x99A0, - 0x6ACB, 0x99A1, 0x6ACC, 0x99A2, 0x6ACD, 0x99A3, 0x6ACE, 0x99A4, 0x6ACF, 0x99A5, 0x6AD0, 0x99A6, 0x6AD1, 0x99A7, 0x6AD2, 0x99A8, - 0x6AD3, 0x99A9, 0x6AD4, 0x99AA, 0x6AD5, 0x99AB, 0x6AD6, 0x99AC, 0x6AD7, 0x99AD, 0x6AD8, 0x99AE, 0x6AD9, 0x99AF, 0x6ADA, 0x99B0, - 0x6ADB, 0x99B1, 0x6ADC, 0x99B2, 0x6ADD, 0x99B3, 0x6ADE, 0x99B4, 0x6ADF, 0x99B5, 0x6AE0, 0x99B6, 0x6AE1, 0x99B7, 0x6AE2, 0x99B8, - 0x6AE3, 0x99B9, 0x6AE4, 0x99BA, 0x6AE5, 0x99BB, 0x6AE6, 0x99BC, 0x6AE7, 0x99BD, 0x6AE8, 0x99BE, 0x6AE9, 0x99BF, 0x6AEA, 0x99C0, - 0x6AEB, 0x99C1, 0x6AEC, 0x99C2, 0x6AED, 0x99C3, 0x6AEE, 0x99C4, 0x6AEF, 0x99C5, 0x6AF0, 0x99C6, 0x6AF1, 0x99C7, 0x6AF2, 0x99C8, - 0x6AF3, 0x99C9, 0x6AF4, 0x99CA, 0x6AF5, 0x99CB, 0x6AF6, 0x99CC, 0x6AF7, 0x99CD, 0x6AF8, 0x99CE, 0x6AF9, 0x99CF, 0x6AFA, 0x99D0, - 0x6AFB, 0x99D1, 0x6AFC, 0x99D2, 0x6AFD, 0x99D3, 0x6AFE, 0x99D4, 0x6AFF, 0x99D5, 0x6B00, 0x99D6, 0x6B01, 0x99D7, 0x6B02, 0x99D8, - 0x6B03, 0x99D9, 0x6B04, 0x99DA, 0x6B05, 0x99DB, 0x6B06, 0x99DC, 0x6B07, 0x99DD, 0x6B08, 0x99DE, 0x6B09, 0x99DF, 0x6B0A, 0x99E0, - 0x6B0B, 0x99E1, 0x6B0C, 0x99E2, 0x6B0D, 0x99E3, 0x6B0E, 0x99E4, 0x6B0F, 0x99E5, 0x6B10, 0x99E6, 0x6B11, 0x99E7, 0x6B12, 0x99E8, - 0x6B13, 0x99E9, 0x6B14, 0x99EA, 0x6B15, 0x99EB, 0x6B16, 0x99EC, 0x6B17, 0x99ED, 0x6B18, 0x99EE, 0x6B19, 0x99EF, 0x6B1A, 0x99F0, - 0x6B1B, 0x99F1, 0x6B1C, 0x99F2, 0x6B1D, 0x99F3, 0x6B1E, 0x99F4, 0x6B1F, 0x99F5, 0x6B20, 0xC7B7, 0x6B21, 0xB4CE, 0x6B22, 0xBBB6, - 0x6B23, 0xD0C0, 0x6B24, 0xECA3, 0x6B25, 0x99F6, 0x6B26, 0x99F7, 0x6B27, 0xC5B7, 0x6B28, 0x99F8, 0x6B29, 0x99F9, 0x6B2A, 0x99FA, - 0x6B2B, 0x99FB, 0x6B2C, 0x99FC, 0x6B2D, 0x99FD, 0x6B2E, 0x99FE, 0x6B2F, 0x9A40, 0x6B30, 0x9A41, 0x6B31, 0x9A42, 0x6B32, 0xD3FB, - 0x6B33, 0x9A43, 0x6B34, 0x9A44, 0x6B35, 0x9A45, 0x6B36, 0x9A46, 0x6B37, 0xECA4, 0x6B38, 0x9A47, 0x6B39, 0xECA5, 0x6B3A, 0xC6DB, - 0x6B3B, 0x9A48, 0x6B3C, 0x9A49, 0x6B3D, 0x9A4A, 0x6B3E, 0xBFEE, 0x6B3F, 0x9A4B, 0x6B40, 0x9A4C, 0x6B41, 0x9A4D, 0x6B42, 0x9A4E, - 0x6B43, 0xECA6, 0x6B44, 0x9A4F, 0x6B45, 0x9A50, 0x6B46, 0xECA7, 0x6B47, 0xD0AA, 0x6B48, 0x9A51, 0x6B49, 0xC7B8, 0x6B4A, 0x9A52, - 0x6B4B, 0x9A53, 0x6B4C, 0xB8E8, 0x6B4D, 0x9A54, 0x6B4E, 0x9A55, 0x6B4F, 0x9A56, 0x6B50, 0x9A57, 0x6B51, 0x9A58, 0x6B52, 0x9A59, - 0x6B53, 0x9A5A, 0x6B54, 0x9A5B, 0x6B55, 0x9A5C, 0x6B56, 0x9A5D, 0x6B57, 0x9A5E, 0x6B58, 0x9A5F, 0x6B59, 0xECA8, 0x6B5A, 0x9A60, - 0x6B5B, 0x9A61, 0x6B5C, 0x9A62, 0x6B5D, 0x9A63, 0x6B5E, 0x9A64, 0x6B5F, 0x9A65, 0x6B60, 0x9A66, 0x6B61, 0x9A67, 0x6B62, 0xD6B9, - 0x6B63, 0xD5FD, 0x6B64, 0xB4CB, 0x6B65, 0xB2BD, 0x6B66, 0xCEE4, 0x6B67, 0xC6E7, 0x6B68, 0x9A68, 0x6B69, 0x9A69, 0x6B6A, 0xCDE1, - 0x6B6B, 0x9A6A, 0x6B6C, 0x9A6B, 0x6B6D, 0x9A6C, 0x6B6E, 0x9A6D, 0x6B6F, 0x9A6E, 0x6B70, 0x9A6F, 0x6B71, 0x9A70, 0x6B72, 0x9A71, - 0x6B73, 0x9A72, 0x6B74, 0x9A73, 0x6B75, 0x9A74, 0x6B76, 0x9A75, 0x6B77, 0x9A76, 0x6B78, 0x9A77, 0x6B79, 0xB4F5, 0x6B7A, 0x9A78, - 0x6B7B, 0xCBC0, 0x6B7C, 0xBCDF, 0x6B7D, 0x9A79, 0x6B7E, 0x9A7A, 0x6B7F, 0x9A7B, 0x6B80, 0x9A7C, 0x6B81, 0xE9E2, 0x6B82, 0xE9E3, - 0x6B83, 0xD1EA, 0x6B84, 0xE9E5, 0x6B85, 0x9A7D, 0x6B86, 0xB4F9, 0x6B87, 0xE9E4, 0x6B88, 0x9A7E, 0x6B89, 0xD1B3, 0x6B8A, 0xCAE2, - 0x6B8B, 0xB2D0, 0x6B8C, 0x9A80, 0x6B8D, 0xE9E8, 0x6B8E, 0x9A81, 0x6B8F, 0x9A82, 0x6B90, 0x9A83, 0x6B91, 0x9A84, 0x6B92, 0xE9E6, - 0x6B93, 0xE9E7, 0x6B94, 0x9A85, 0x6B95, 0x9A86, 0x6B96, 0xD6B3, 0x6B97, 0x9A87, 0x6B98, 0x9A88, 0x6B99, 0x9A89, 0x6B9A, 0xE9E9, - 0x6B9B, 0xE9EA, 0x6B9C, 0x9A8A, 0x6B9D, 0x9A8B, 0x6B9E, 0x9A8C, 0x6B9F, 0x9A8D, 0x6BA0, 0x9A8E, 0x6BA1, 0xE9EB, 0x6BA2, 0x9A8F, - 0x6BA3, 0x9A90, 0x6BA4, 0x9A91, 0x6BA5, 0x9A92, 0x6BA6, 0x9A93, 0x6BA7, 0x9A94, 0x6BA8, 0x9A95, 0x6BA9, 0x9A96, 0x6BAA, 0xE9EC, - 0x6BAB, 0x9A97, 0x6BAC, 0x9A98, 0x6BAD, 0x9A99, 0x6BAE, 0x9A9A, 0x6BAF, 0x9A9B, 0x6BB0, 0x9A9C, 0x6BB1, 0x9A9D, 0x6BB2, 0x9A9E, - 0x6BB3, 0xECAF, 0x6BB4, 0xC5B9, 0x6BB5, 0xB6CE, 0x6BB6, 0x9A9F, 0x6BB7, 0xD2F3, 0x6BB8, 0x9AA0, 0x6BB9, 0x9AA1, 0x6BBA, 0x9AA2, - 0x6BBB, 0x9AA3, 0x6BBC, 0x9AA4, 0x6BBD, 0x9AA5, 0x6BBE, 0x9AA6, 0x6BBF, 0xB5EE, 0x6BC0, 0x9AA7, 0x6BC1, 0xBBD9, 0x6BC2, 0xECB1, - 0x6BC3, 0x9AA8, 0x6BC4, 0x9AA9, 0x6BC5, 0xD2E3, 0x6BC6, 0x9AAA, 0x6BC7, 0x9AAB, 0x6BC8, 0x9AAC, 0x6BC9, 0x9AAD, 0x6BCA, 0x9AAE, - 0x6BCB, 0xCEE3, 0x6BCC, 0x9AAF, 0x6BCD, 0xC4B8, 0x6BCE, 0x9AB0, 0x6BCF, 0xC3BF, 0x6BD0, 0x9AB1, 0x6BD1, 0x9AB2, 0x6BD2, 0xB6BE, - 0x6BD3, 0xD8B9, 0x6BD4, 0xB1C8, 0x6BD5, 0xB1CF, 0x6BD6, 0xB1D1, 0x6BD7, 0xC5FE, 0x6BD8, 0x9AB3, 0x6BD9, 0xB1D0, 0x6BDA, 0x9AB4, - 0x6BDB, 0xC3AB, 0x6BDC, 0x9AB5, 0x6BDD, 0x9AB6, 0x6BDE, 0x9AB7, 0x6BDF, 0x9AB8, 0x6BE0, 0x9AB9, 0x6BE1, 0xD5B1, 0x6BE2, 0x9ABA, - 0x6BE3, 0x9ABB, 0x6BE4, 0x9ABC, 0x6BE5, 0x9ABD, 0x6BE6, 0x9ABE, 0x6BE7, 0x9ABF, 0x6BE8, 0x9AC0, 0x6BE9, 0x9AC1, 0x6BEA, 0xEBA4, - 0x6BEB, 0xBAC1, 0x6BEC, 0x9AC2, 0x6BED, 0x9AC3, 0x6BEE, 0x9AC4, 0x6BEF, 0xCCBA, 0x6BF0, 0x9AC5, 0x6BF1, 0x9AC6, 0x6BF2, 0x9AC7, - 0x6BF3, 0xEBA5, 0x6BF4, 0x9AC8, 0x6BF5, 0xEBA7, 0x6BF6, 0x9AC9, 0x6BF7, 0x9ACA, 0x6BF8, 0x9ACB, 0x6BF9, 0xEBA8, 0x6BFA, 0x9ACC, - 0x6BFB, 0x9ACD, 0x6BFC, 0x9ACE, 0x6BFD, 0xEBA6, 0x6BFE, 0x9ACF, 0x6BFF, 0x9AD0, 0x6C00, 0x9AD1, 0x6C01, 0x9AD2, 0x6C02, 0x9AD3, - 0x6C03, 0x9AD4, 0x6C04, 0x9AD5, 0x6C05, 0xEBA9, 0x6C06, 0xEBAB, 0x6C07, 0xEBAA, 0x6C08, 0x9AD6, 0x6C09, 0x9AD7, 0x6C0A, 0x9AD8, - 0x6C0B, 0x9AD9, 0x6C0C, 0x9ADA, 0x6C0D, 0xEBAC, 0x6C0E, 0x9ADB, 0x6C0F, 0xCACF, 0x6C10, 0xD8B5, 0x6C11, 0xC3F1, 0x6C12, 0x9ADC, - 0x6C13, 0xC3A5, 0x6C14, 0xC6F8, 0x6C15, 0xEBAD, 0x6C16, 0xC4CA, 0x6C17, 0x9ADD, 0x6C18, 0xEBAE, 0x6C19, 0xEBAF, 0x6C1A, 0xEBB0, - 0x6C1B, 0xB7D5, 0x6C1C, 0x9ADE, 0x6C1D, 0x9ADF, 0x6C1E, 0x9AE0, 0x6C1F, 0xB7FA, 0x6C20, 0x9AE1, 0x6C21, 0xEBB1, 0x6C22, 0xC7E2, - 0x6C23, 0x9AE2, 0x6C24, 0xEBB3, 0x6C25, 0x9AE3, 0x6C26, 0xBAA4, 0x6C27, 0xD1F5, 0x6C28, 0xB0B1, 0x6C29, 0xEBB2, 0x6C2A, 0xEBB4, - 0x6C2B, 0x9AE4, 0x6C2C, 0x9AE5, 0x6C2D, 0x9AE6, 0x6C2E, 0xB5AA, 0x6C2F, 0xC2C8, 0x6C30, 0xC7E8, 0x6C31, 0x9AE7, 0x6C32, 0xEBB5, - 0x6C33, 0x9AE8, 0x6C34, 0xCBAE, 0x6C35, 0xE3DF, 0x6C36, 0x9AE9, 0x6C37, 0x9AEA, 0x6C38, 0xD3C0, 0x6C39, 0x9AEB, 0x6C3A, 0x9AEC, - 0x6C3B, 0x9AED, 0x6C3C, 0x9AEE, 0x6C3D, 0xD9DB, 0x6C3E, 0x9AEF, 0x6C3F, 0x9AF0, 0x6C40, 0xCDA1, 0x6C41, 0xD6AD, 0x6C42, 0xC7F3, - 0x6C43, 0x9AF1, 0x6C44, 0x9AF2, 0x6C45, 0x9AF3, 0x6C46, 0xD9E0, 0x6C47, 0xBBE3, 0x6C48, 0x9AF4, 0x6C49, 0xBABA, 0x6C4A, 0xE3E2, - 0x6C4B, 0x9AF5, 0x6C4C, 0x9AF6, 0x6C4D, 0x9AF7, 0x6C4E, 0x9AF8, 0x6C4F, 0x9AF9, 0x6C50, 0xCFAB, 0x6C51, 0x9AFA, 0x6C52, 0x9AFB, - 0x6C53, 0x9AFC, 0x6C54, 0xE3E0, 0x6C55, 0xC9C7, 0x6C56, 0x9AFD, 0x6C57, 0xBAB9, 0x6C58, 0x9AFE, 0x6C59, 0x9B40, 0x6C5A, 0x9B41, - 0x6C5B, 0xD1B4, 0x6C5C, 0xE3E1, 0x6C5D, 0xC8EA, 0x6C5E, 0xB9AF, 0x6C5F, 0xBDAD, 0x6C60, 0xB3D8, 0x6C61, 0xCEDB, 0x6C62, 0x9B42, - 0x6C63, 0x9B43, 0x6C64, 0xCCC0, 0x6C65, 0x9B44, 0x6C66, 0x9B45, 0x6C67, 0x9B46, 0x6C68, 0xE3E8, 0x6C69, 0xE3E9, 0x6C6A, 0xCDF4, - 0x6C6B, 0x9B47, 0x6C6C, 0x9B48, 0x6C6D, 0x9B49, 0x6C6E, 0x9B4A, 0x6C6F, 0x9B4B, 0x6C70, 0xCCAD, 0x6C71, 0x9B4C, 0x6C72, 0xBCB3, - 0x6C73, 0x9B4D, 0x6C74, 0xE3EA, 0x6C75, 0x9B4E, 0x6C76, 0xE3EB, 0x6C77, 0x9B4F, 0x6C78, 0x9B50, 0x6C79, 0xD0DA, 0x6C7A, 0x9B51, - 0x6C7B, 0x9B52, 0x6C7C, 0x9B53, 0x6C7D, 0xC6FB, 0x6C7E, 0xB7DA, 0x6C7F, 0x9B54, 0x6C80, 0x9B55, 0x6C81, 0xC7DF, 0x6C82, 0xD2CA, - 0x6C83, 0xCED6, 0x6C84, 0x9B56, 0x6C85, 0xE3E4, 0x6C86, 0xE3EC, 0x6C87, 0x9B57, 0x6C88, 0xC9F2, 0x6C89, 0xB3C1, 0x6C8A, 0x9B58, - 0x6C8B, 0x9B59, 0x6C8C, 0xE3E7, 0x6C8D, 0x9B5A, 0x6C8E, 0x9B5B, 0x6C8F, 0xC6E3, 0x6C90, 0xE3E5, 0x6C91, 0x9B5C, 0x6C92, 0x9B5D, - 0x6C93, 0xEDB3, 0x6C94, 0xE3E6, 0x6C95, 0x9B5E, 0x6C96, 0x9B5F, 0x6C97, 0x9B60, 0x6C98, 0x9B61, 0x6C99, 0xC9B3, 0x6C9A, 0x9B62, - 0x6C9B, 0xC5E6, 0x6C9C, 0x9B63, 0x6C9D, 0x9B64, 0x6C9E, 0x9B65, 0x6C9F, 0xB9B5, 0x6CA0, 0x9B66, 0x6CA1, 0xC3BB, 0x6CA2, 0x9B67, - 0x6CA3, 0xE3E3, 0x6CA4, 0xC5BD, 0x6CA5, 0xC1A4, 0x6CA6, 0xC2D9, 0x6CA7, 0xB2D7, 0x6CA8, 0x9B68, 0x6CA9, 0xE3ED, 0x6CAA, 0xBBA6, - 0x6CAB, 0xC4AD, 0x6CAC, 0x9B69, 0x6CAD, 0xE3F0, 0x6CAE, 0xBEDA, 0x6CAF, 0x9B6A, 0x6CB0, 0x9B6B, 0x6CB1, 0xE3FB, 0x6CB2, 0xE3F5, - 0x6CB3, 0xBAD3, 0x6CB4, 0x9B6C, 0x6CB5, 0x9B6D, 0x6CB6, 0x9B6E, 0x6CB7, 0x9B6F, 0x6CB8, 0xB7D0, 0x6CB9, 0xD3CD, 0x6CBA, 0x9B70, - 0x6CBB, 0xD6CE, 0x6CBC, 0xD5D3, 0x6CBD, 0xB9C1, 0x6CBE, 0xD5B4, 0x6CBF, 0xD1D8, 0x6CC0, 0x9B71, 0x6CC1, 0x9B72, 0x6CC2, 0x9B73, - 0x6CC3, 0x9B74, 0x6CC4, 0xD0B9, 0x6CC5, 0xC7F6, 0x6CC6, 0x9B75, 0x6CC7, 0x9B76, 0x6CC8, 0x9B77, 0x6CC9, 0xC8AA, 0x6CCA, 0xB2B4, - 0x6CCB, 0x9B78, 0x6CCC, 0xC3DA, 0x6CCD, 0x9B79, 0x6CCE, 0x9B7A, 0x6CCF, 0x9B7B, 0x6CD0, 0xE3EE, 0x6CD1, 0x9B7C, 0x6CD2, 0x9B7D, - 0x6CD3, 0xE3FC, 0x6CD4, 0xE3EF, 0x6CD5, 0xB7A8, 0x6CD6, 0xE3F7, 0x6CD7, 0xE3F4, 0x6CD8, 0x9B7E, 0x6CD9, 0x9B80, 0x6CDA, 0x9B81, - 0x6CDB, 0xB7BA, 0x6CDC, 0x9B82, 0x6CDD, 0x9B83, 0x6CDE, 0xC5A2, 0x6CDF, 0x9B84, 0x6CE0, 0xE3F6, 0x6CE1, 0xC5DD, 0x6CE2, 0xB2A8, - 0x6CE3, 0xC6FC, 0x6CE4, 0x9B85, 0x6CE5, 0xC4E0, 0x6CE6, 0x9B86, 0x6CE7, 0x9B87, 0x6CE8, 0xD7A2, 0x6CE9, 0x9B88, 0x6CEA, 0xC0E1, - 0x6CEB, 0xE3F9, 0x6CEC, 0x9B89, 0x6CED, 0x9B8A, 0x6CEE, 0xE3FA, 0x6CEF, 0xE3FD, 0x6CF0, 0xCCA9, 0x6CF1, 0xE3F3, 0x6CF2, 0x9B8B, - 0x6CF3, 0xD3BE, 0x6CF4, 0x9B8C, 0x6CF5, 0xB1C3, 0x6CF6, 0xEDB4, 0x6CF7, 0xE3F1, 0x6CF8, 0xE3F2, 0x6CF9, 0x9B8D, 0x6CFA, 0xE3F8, - 0x6CFB, 0xD0BA, 0x6CFC, 0xC6C3, 0x6CFD, 0xD4F3, 0x6CFE, 0xE3FE, 0x6CFF, 0x9B8E, 0x6D00, 0x9B8F, 0x6D01, 0xBDE0, 0x6D02, 0x9B90, - 0x6D03, 0x9B91, 0x6D04, 0xE4A7, 0x6D05, 0x9B92, 0x6D06, 0x9B93, 0x6D07, 0xE4A6, 0x6D08, 0x9B94, 0x6D09, 0x9B95, 0x6D0A, 0x9B96, - 0x6D0B, 0xD1F3, 0x6D0C, 0xE4A3, 0x6D0D, 0x9B97, 0x6D0E, 0xE4A9, 0x6D0F, 0x9B98, 0x6D10, 0x9B99, 0x6D11, 0x9B9A, 0x6D12, 0xC8F7, - 0x6D13, 0x9B9B, 0x6D14, 0x9B9C, 0x6D15, 0x9B9D, 0x6D16, 0x9B9E, 0x6D17, 0xCFB4, 0x6D18, 0x9B9F, 0x6D19, 0xE4A8, 0x6D1A, 0xE4AE, - 0x6D1B, 0xC2E5, 0x6D1C, 0x9BA0, 0x6D1D, 0x9BA1, 0x6D1E, 0xB6B4, 0x6D1F, 0x9BA2, 0x6D20, 0x9BA3, 0x6D21, 0x9BA4, 0x6D22, 0x9BA5, - 0x6D23, 0x9BA6, 0x6D24, 0x9BA7, 0x6D25, 0xBDF2, 0x6D26, 0x9BA8, 0x6D27, 0xE4A2, 0x6D28, 0x9BA9, 0x6D29, 0x9BAA, 0x6D2A, 0xBAE9, - 0x6D2B, 0xE4AA, 0x6D2C, 0x9BAB, 0x6D2D, 0x9BAC, 0x6D2E, 0xE4AC, 0x6D2F, 0x9BAD, 0x6D30, 0x9BAE, 0x6D31, 0xB6FD, 0x6D32, 0xD6DE, - 0x6D33, 0xE4B2, 0x6D34, 0x9BAF, 0x6D35, 0xE4AD, 0x6D36, 0x9BB0, 0x6D37, 0x9BB1, 0x6D38, 0x9BB2, 0x6D39, 0xE4A1, 0x6D3A, 0x9BB3, - 0x6D3B, 0xBBEE, 0x6D3C, 0xCDDD, 0x6D3D, 0xC7A2, 0x6D3E, 0xC5C9, 0x6D3F, 0x9BB4, 0x6D40, 0x9BB5, 0x6D41, 0xC1F7, 0x6D42, 0x9BB6, - 0x6D43, 0xE4A4, 0x6D44, 0x9BB7, 0x6D45, 0xC7B3, 0x6D46, 0xBDAC, 0x6D47, 0xBDBD, 0x6D48, 0xE4A5, 0x6D49, 0x9BB8, 0x6D4A, 0xD7C7, - 0x6D4B, 0xB2E2, 0x6D4C, 0x9BB9, 0x6D4D, 0xE4AB, 0x6D4E, 0xBCC3, 0x6D4F, 0xE4AF, 0x6D50, 0x9BBA, 0x6D51, 0xBBEB, 0x6D52, 0xE4B0, - 0x6D53, 0xC5A8, 0x6D54, 0xE4B1, 0x6D55, 0x9BBB, 0x6D56, 0x9BBC, 0x6D57, 0x9BBD, 0x6D58, 0x9BBE, 0x6D59, 0xD5E3, 0x6D5A, 0xBFA3, - 0x6D5B, 0x9BBF, 0x6D5C, 0xE4BA, 0x6D5D, 0x9BC0, 0x6D5E, 0xE4B7, 0x6D5F, 0x9BC1, 0x6D60, 0xE4BB, 0x6D61, 0x9BC2, 0x6D62, 0x9BC3, - 0x6D63, 0xE4BD, 0x6D64, 0x9BC4, 0x6D65, 0x9BC5, 0x6D66, 0xC6D6, 0x6D67, 0x9BC6, 0x6D68, 0x9BC7, 0x6D69, 0xBAC6, 0x6D6A, 0xC0CB, - 0x6D6B, 0x9BC8, 0x6D6C, 0x9BC9, 0x6D6D, 0x9BCA, 0x6D6E, 0xB8A1, 0x6D6F, 0xE4B4, 0x6D70, 0x9BCB, 0x6D71, 0x9BCC, 0x6D72, 0x9BCD, - 0x6D73, 0x9BCE, 0x6D74, 0xD4A1, 0x6D75, 0x9BCF, 0x6D76, 0x9BD0, 0x6D77, 0xBAA3, 0x6D78, 0xBDFE, 0x6D79, 0x9BD1, 0x6D7A, 0x9BD2, - 0x6D7B, 0x9BD3, 0x6D7C, 0xE4BC, 0x6D7D, 0x9BD4, 0x6D7E, 0x9BD5, 0x6D7F, 0x9BD6, 0x6D80, 0x9BD7, 0x6D81, 0x9BD8, 0x6D82, 0xCDBF, - 0x6D83, 0x9BD9, 0x6D84, 0x9BDA, 0x6D85, 0xC4F9, 0x6D86, 0x9BDB, 0x6D87, 0x9BDC, 0x6D88, 0xCFFB, 0x6D89, 0xC9E6, 0x6D8A, 0x9BDD, - 0x6D8B, 0x9BDE, 0x6D8C, 0xD3BF, 0x6D8D, 0x9BDF, 0x6D8E, 0xCFD1, 0x6D8F, 0x9BE0, 0x6D90, 0x9BE1, 0x6D91, 0xE4B3, 0x6D92, 0x9BE2, - 0x6D93, 0xE4B8, 0x6D94, 0xE4B9, 0x6D95, 0xCCE9, 0x6D96, 0x9BE3, 0x6D97, 0x9BE4, 0x6D98, 0x9BE5, 0x6D99, 0x9BE6, 0x6D9A, 0x9BE7, - 0x6D9B, 0xCCCE, 0x6D9C, 0x9BE8, 0x6D9D, 0xC0D4, 0x6D9E, 0xE4B5, 0x6D9F, 0xC1B0, 0x6DA0, 0xE4B6, 0x6DA1, 0xCED0, 0x6DA2, 0x9BE9, - 0x6DA3, 0xBBC1, 0x6DA4, 0xB5D3, 0x6DA5, 0x9BEA, 0x6DA6, 0xC8F3, 0x6DA7, 0xBDA7, 0x6DA8, 0xD5C7, 0x6DA9, 0xC9AC, 0x6DAA, 0xB8A2, - 0x6DAB, 0xE4CA, 0x6DAC, 0x9BEB, 0x6DAD, 0x9BEC, 0x6DAE, 0xE4CC, 0x6DAF, 0xD1C4, 0x6DB0, 0x9BED, 0x6DB1, 0x9BEE, 0x6DB2, 0xD2BA, - 0x6DB3, 0x9BEF, 0x6DB4, 0x9BF0, 0x6DB5, 0xBAAD, 0x6DB6, 0x9BF1, 0x6DB7, 0x9BF2, 0x6DB8, 0xBAD4, 0x6DB9, 0x9BF3, 0x6DBA, 0x9BF4, - 0x6DBB, 0x9BF5, 0x6DBC, 0x9BF6, 0x6DBD, 0x9BF7, 0x6DBE, 0x9BF8, 0x6DBF, 0xE4C3, 0x6DC0, 0xB5ED, 0x6DC1, 0x9BF9, 0x6DC2, 0x9BFA, - 0x6DC3, 0x9BFB, 0x6DC4, 0xD7CD, 0x6DC5, 0xE4C0, 0x6DC6, 0xCFFD, 0x6DC7, 0xE4BF, 0x6DC8, 0x9BFC, 0x6DC9, 0x9BFD, 0x6DCA, 0x9BFE, - 0x6DCB, 0xC1DC, 0x6DCC, 0xCCCA, 0x6DCD, 0x9C40, 0x6DCE, 0x9C41, 0x6DCF, 0x9C42, 0x6DD0, 0x9C43, 0x6DD1, 0xCAE7, 0x6DD2, 0x9C44, - 0x6DD3, 0x9C45, 0x6DD4, 0x9C46, 0x6DD5, 0x9C47, 0x6DD6, 0xC4D7, 0x6DD7, 0x9C48, 0x6DD8, 0xCCD4, 0x6DD9, 0xE4C8, 0x6DDA, 0x9C49, - 0x6DDB, 0x9C4A, 0x6DDC, 0x9C4B, 0x6DDD, 0xE4C7, 0x6DDE, 0xE4C1, 0x6DDF, 0x9C4C, 0x6DE0, 0xE4C4, 0x6DE1, 0xB5AD, 0x6DE2, 0x9C4D, - 0x6DE3, 0x9C4E, 0x6DE4, 0xD3D9, 0x6DE5, 0x9C4F, 0x6DE6, 0xE4C6, 0x6DE7, 0x9C50, 0x6DE8, 0x9C51, 0x6DE9, 0x9C52, 0x6DEA, 0x9C53, - 0x6DEB, 0xD2F9, 0x6DEC, 0xB4E3, 0x6DED, 0x9C54, 0x6DEE, 0xBBB4, 0x6DEF, 0x9C55, 0x6DF0, 0x9C56, 0x6DF1, 0xC9EE, 0x6DF2, 0x9C57, - 0x6DF3, 0xB4BE, 0x6DF4, 0x9C58, 0x6DF5, 0x9C59, 0x6DF6, 0x9C5A, 0x6DF7, 0xBBEC, 0x6DF8, 0x9C5B, 0x6DF9, 0xD1CD, 0x6DFA, 0x9C5C, - 0x6DFB, 0xCCED, 0x6DFC, 0xEDB5, 0x6DFD, 0x9C5D, 0x6DFE, 0x9C5E, 0x6DFF, 0x9C5F, 0x6E00, 0x9C60, 0x6E01, 0x9C61, 0x6E02, 0x9C62, - 0x6E03, 0x9C63, 0x6E04, 0x9C64, 0x6E05, 0xC7E5, 0x6E06, 0x9C65, 0x6E07, 0x9C66, 0x6E08, 0x9C67, 0x6E09, 0x9C68, 0x6E0A, 0xD4A8, - 0x6E0B, 0x9C69, 0x6E0C, 0xE4CB, 0x6E0D, 0xD7D5, 0x6E0E, 0xE4C2, 0x6E0F, 0x9C6A, 0x6E10, 0xBDA5, 0x6E11, 0xE4C5, 0x6E12, 0x9C6B, - 0x6E13, 0x9C6C, 0x6E14, 0xD3E6, 0x6E15, 0x9C6D, 0x6E16, 0xE4C9, 0x6E17, 0xC9F8, 0x6E18, 0x9C6E, 0x6E19, 0x9C6F, 0x6E1A, 0xE4BE, - 0x6E1B, 0x9C70, 0x6E1C, 0x9C71, 0x6E1D, 0xD3E5, 0x6E1E, 0x9C72, 0x6E1F, 0x9C73, 0x6E20, 0xC7FE, 0x6E21, 0xB6C9, 0x6E22, 0x9C74, - 0x6E23, 0xD4FC, 0x6E24, 0xB2B3, 0x6E25, 0xE4D7, 0x6E26, 0x9C75, 0x6E27, 0x9C76, 0x6E28, 0x9C77, 0x6E29, 0xCEC2, 0x6E2A, 0x9C78, - 0x6E2B, 0xE4CD, 0x6E2C, 0x9C79, 0x6E2D, 0xCEBC, 0x6E2E, 0x9C7A, 0x6E2F, 0xB8DB, 0x6E30, 0x9C7B, 0x6E31, 0x9C7C, 0x6E32, 0xE4D6, - 0x6E33, 0x9C7D, 0x6E34, 0xBFCA, 0x6E35, 0x9C7E, 0x6E36, 0x9C80, 0x6E37, 0x9C81, 0x6E38, 0xD3CE, 0x6E39, 0x9C82, 0x6E3A, 0xC3EC, - 0x6E3B, 0x9C83, 0x6E3C, 0x9C84, 0x6E3D, 0x9C85, 0x6E3E, 0x9C86, 0x6E3F, 0x9C87, 0x6E40, 0x9C88, 0x6E41, 0x9C89, 0x6E42, 0x9C8A, - 0x6E43, 0xC5C8, 0x6E44, 0xE4D8, 0x6E45, 0x9C8B, 0x6E46, 0x9C8C, 0x6E47, 0x9C8D, 0x6E48, 0x9C8E, 0x6E49, 0x9C8F, 0x6E4A, 0x9C90, - 0x6E4B, 0x9C91, 0x6E4C, 0x9C92, 0x6E4D, 0xCDC4, 0x6E4E, 0xE4CF, 0x6E4F, 0x9C93, 0x6E50, 0x9C94, 0x6E51, 0x9C95, 0x6E52, 0x9C96, - 0x6E53, 0xE4D4, 0x6E54, 0xE4D5, 0x6E55, 0x9C97, 0x6E56, 0xBAFE, 0x6E57, 0x9C98, 0x6E58, 0xCFE6, 0x6E59, 0x9C99, 0x6E5A, 0x9C9A, - 0x6E5B, 0xD5BF, 0x6E5C, 0x9C9B, 0x6E5D, 0x9C9C, 0x6E5E, 0x9C9D, 0x6E5F, 0xE4D2, 0x6E60, 0x9C9E, 0x6E61, 0x9C9F, 0x6E62, 0x9CA0, - 0x6E63, 0x9CA1, 0x6E64, 0x9CA2, 0x6E65, 0x9CA3, 0x6E66, 0x9CA4, 0x6E67, 0x9CA5, 0x6E68, 0x9CA6, 0x6E69, 0x9CA7, 0x6E6A, 0x9CA8, - 0x6E6B, 0xE4D0, 0x6E6C, 0x9CA9, 0x6E6D, 0x9CAA, 0x6E6E, 0xE4CE, 0x6E6F, 0x9CAB, 0x6E70, 0x9CAC, 0x6E71, 0x9CAD, 0x6E72, 0x9CAE, - 0x6E73, 0x9CAF, 0x6E74, 0x9CB0, 0x6E75, 0x9CB1, 0x6E76, 0x9CB2, 0x6E77, 0x9CB3, 0x6E78, 0x9CB4, 0x6E79, 0x9CB5, 0x6E7A, 0x9CB6, - 0x6E7B, 0x9CB7, 0x6E7C, 0x9CB8, 0x6E7D, 0x9CB9, 0x6E7E, 0xCDE5, 0x6E7F, 0xCAAA, 0x6E80, 0x9CBA, 0x6E81, 0x9CBB, 0x6E82, 0x9CBC, - 0x6E83, 0xC0A3, 0x6E84, 0x9CBD, 0x6E85, 0xBDA6, 0x6E86, 0xE4D3, 0x6E87, 0x9CBE, 0x6E88, 0x9CBF, 0x6E89, 0xB8C8, 0x6E8A, 0x9CC0, - 0x6E8B, 0x9CC1, 0x6E8C, 0x9CC2, 0x6E8D, 0x9CC3, 0x6E8E, 0x9CC4, 0x6E8F, 0xE4E7, 0x6E90, 0xD4B4, 0x6E91, 0x9CC5, 0x6E92, 0x9CC6, - 0x6E93, 0x9CC7, 0x6E94, 0x9CC8, 0x6E95, 0x9CC9, 0x6E96, 0x9CCA, 0x6E97, 0x9CCB, 0x6E98, 0xE4DB, 0x6E99, 0x9CCC, 0x6E9A, 0x9CCD, - 0x6E9B, 0x9CCE, 0x6E9C, 0xC1EF, 0x6E9D, 0x9CCF, 0x6E9E, 0x9CD0, 0x6E9F, 0xE4E9, 0x6EA0, 0x9CD1, 0x6EA1, 0x9CD2, 0x6EA2, 0xD2E7, - 0x6EA3, 0x9CD3, 0x6EA4, 0x9CD4, 0x6EA5, 0xE4DF, 0x6EA6, 0x9CD5, 0x6EA7, 0xE4E0, 0x6EA8, 0x9CD6, 0x6EA9, 0x9CD7, 0x6EAA, 0xCFAA, - 0x6EAB, 0x9CD8, 0x6EAC, 0x9CD9, 0x6EAD, 0x9CDA, 0x6EAE, 0x9CDB, 0x6EAF, 0xCBDD, 0x6EB0, 0x9CDC, 0x6EB1, 0xE4DA, 0x6EB2, 0xE4D1, - 0x6EB3, 0x9CDD, 0x6EB4, 0xE4E5, 0x6EB5, 0x9CDE, 0x6EB6, 0xC8DC, 0x6EB7, 0xE4E3, 0x6EB8, 0x9CDF, 0x6EB9, 0x9CE0, 0x6EBA, 0xC4E7, - 0x6EBB, 0xE4E2, 0x6EBC, 0x9CE1, 0x6EBD, 0xE4E1, 0x6EBE, 0x9CE2, 0x6EBF, 0x9CE3, 0x6EC0, 0x9CE4, 0x6EC1, 0xB3FC, 0x6EC2, 0xE4E8, - 0x6EC3, 0x9CE5, 0x6EC4, 0x9CE6, 0x6EC5, 0x9CE7, 0x6EC6, 0x9CE8, 0x6EC7, 0xB5E1, 0x6EC8, 0x9CE9, 0x6EC9, 0x9CEA, 0x6ECA, 0x9CEB, - 0x6ECB, 0xD7CC, 0x6ECC, 0x9CEC, 0x6ECD, 0x9CED, 0x6ECE, 0x9CEE, 0x6ECF, 0xE4E6, 0x6ED0, 0x9CEF, 0x6ED1, 0xBBAC, 0x6ED2, 0x9CF0, - 0x6ED3, 0xD7D2, 0x6ED4, 0xCCCF, 0x6ED5, 0xEBF8, 0x6ED6, 0x9CF1, 0x6ED7, 0xE4E4, 0x6ED8, 0x9CF2, 0x6ED9, 0x9CF3, 0x6EDA, 0xB9F6, - 0x6EDB, 0x9CF4, 0x6EDC, 0x9CF5, 0x6EDD, 0x9CF6, 0x6EDE, 0xD6CD, 0x6EDF, 0xE4D9, 0x6EE0, 0xE4DC, 0x6EE1, 0xC2FA, 0x6EE2, 0xE4DE, - 0x6EE3, 0x9CF7, 0x6EE4, 0xC2CB, 0x6EE5, 0xC0C4, 0x6EE6, 0xC2D0, 0x6EE7, 0x9CF8, 0x6EE8, 0xB1F5, 0x6EE9, 0xCCB2, 0x6EEA, 0x9CF9, - 0x6EEB, 0x9CFA, 0x6EEC, 0x9CFB, 0x6EED, 0x9CFC, 0x6EEE, 0x9CFD, 0x6EEF, 0x9CFE, 0x6EF0, 0x9D40, 0x6EF1, 0x9D41, 0x6EF2, 0x9D42, - 0x6EF3, 0x9D43, 0x6EF4, 0xB5CE, 0x6EF5, 0x9D44, 0x6EF6, 0x9D45, 0x6EF7, 0x9D46, 0x6EF8, 0x9D47, 0x6EF9, 0xE4EF, 0x6EFA, 0x9D48, - 0x6EFB, 0x9D49, 0x6EFC, 0x9D4A, 0x6EFD, 0x9D4B, 0x6EFE, 0x9D4C, 0x6EFF, 0x9D4D, 0x6F00, 0x9D4E, 0x6F01, 0x9D4F, 0x6F02, 0xC6AF, - 0x6F03, 0x9D50, 0x6F04, 0x9D51, 0x6F05, 0x9D52, 0x6F06, 0xC6E1, 0x6F07, 0x9D53, 0x6F08, 0x9D54, 0x6F09, 0xE4F5, 0x6F0A, 0x9D55, - 0x6F0B, 0x9D56, 0x6F0C, 0x9D57, 0x6F0D, 0x9D58, 0x6F0E, 0x9D59, 0x6F0F, 0xC2A9, 0x6F10, 0x9D5A, 0x6F11, 0x9D5B, 0x6F12, 0x9D5C, - 0x6F13, 0xC0EC, 0x6F14, 0xD1DD, 0x6F15, 0xE4EE, 0x6F16, 0x9D5D, 0x6F17, 0x9D5E, 0x6F18, 0x9D5F, 0x6F19, 0x9D60, 0x6F1A, 0x9D61, - 0x6F1B, 0x9D62, 0x6F1C, 0x9D63, 0x6F1D, 0x9D64, 0x6F1E, 0x9D65, 0x6F1F, 0x9D66, 0x6F20, 0xC4AE, 0x6F21, 0x9D67, 0x6F22, 0x9D68, - 0x6F23, 0x9D69, 0x6F24, 0xE4ED, 0x6F25, 0x9D6A, 0x6F26, 0x9D6B, 0x6F27, 0x9D6C, 0x6F28, 0x9D6D, 0x6F29, 0xE4F6, 0x6F2A, 0xE4F4, - 0x6F2B, 0xC2FE, 0x6F2C, 0x9D6E, 0x6F2D, 0xE4DD, 0x6F2E, 0x9D6F, 0x6F2F, 0xE4F0, 0x6F30, 0x9D70, 0x6F31, 0xCAFE, 0x6F32, 0x9D71, - 0x6F33, 0xD5C4, 0x6F34, 0x9D72, 0x6F35, 0x9D73, 0x6F36, 0xE4F1, 0x6F37, 0x9D74, 0x6F38, 0x9D75, 0x6F39, 0x9D76, 0x6F3A, 0x9D77, - 0x6F3B, 0x9D78, 0x6F3C, 0x9D79, 0x6F3D, 0x9D7A, 0x6F3E, 0xD1FA, 0x6F3F, 0x9D7B, 0x6F40, 0x9D7C, 0x6F41, 0x9D7D, 0x6F42, 0x9D7E, - 0x6F43, 0x9D80, 0x6F44, 0x9D81, 0x6F45, 0x9D82, 0x6F46, 0xE4EB, 0x6F47, 0xE4EC, 0x6F48, 0x9D83, 0x6F49, 0x9D84, 0x6F4A, 0x9D85, - 0x6F4B, 0xE4F2, 0x6F4C, 0x9D86, 0x6F4D, 0xCEAB, 0x6F4E, 0x9D87, 0x6F4F, 0x9D88, 0x6F50, 0x9D89, 0x6F51, 0x9D8A, 0x6F52, 0x9D8B, - 0x6F53, 0x9D8C, 0x6F54, 0x9D8D, 0x6F55, 0x9D8E, 0x6F56, 0x9D8F, 0x6F57, 0x9D90, 0x6F58, 0xC5CB, 0x6F59, 0x9D91, 0x6F5A, 0x9D92, - 0x6F5B, 0x9D93, 0x6F5C, 0xC7B1, 0x6F5D, 0x9D94, 0x6F5E, 0xC2BA, 0x6F5F, 0x9D95, 0x6F60, 0x9D96, 0x6F61, 0x9D97, 0x6F62, 0xE4EA, - 0x6F63, 0x9D98, 0x6F64, 0x9D99, 0x6F65, 0x9D9A, 0x6F66, 0xC1CA, 0x6F67, 0x9D9B, 0x6F68, 0x9D9C, 0x6F69, 0x9D9D, 0x6F6A, 0x9D9E, - 0x6F6B, 0x9D9F, 0x6F6C, 0x9DA0, 0x6F6D, 0xCCB6, 0x6F6E, 0xB3B1, 0x6F6F, 0x9DA1, 0x6F70, 0x9DA2, 0x6F71, 0x9DA3, 0x6F72, 0xE4FB, - 0x6F73, 0x9DA4, 0x6F74, 0xE4F3, 0x6F75, 0x9DA5, 0x6F76, 0x9DA6, 0x6F77, 0x9DA7, 0x6F78, 0xE4FA, 0x6F79, 0x9DA8, 0x6F7A, 0xE4FD, - 0x6F7B, 0x9DA9, 0x6F7C, 0xE4FC, 0x6F7D, 0x9DAA, 0x6F7E, 0x9DAB, 0x6F7F, 0x9DAC, 0x6F80, 0x9DAD, 0x6F81, 0x9DAE, 0x6F82, 0x9DAF, - 0x6F83, 0x9DB0, 0x6F84, 0xB3CE, 0x6F85, 0x9DB1, 0x6F86, 0x9DB2, 0x6F87, 0x9DB3, 0x6F88, 0xB3BA, 0x6F89, 0xE4F7, 0x6F8A, 0x9DB4, - 0x6F8B, 0x9DB5, 0x6F8C, 0xE4F9, 0x6F8D, 0xE4F8, 0x6F8E, 0xC5EC, 0x6F8F, 0x9DB6, 0x6F90, 0x9DB7, 0x6F91, 0x9DB8, 0x6F92, 0x9DB9, - 0x6F93, 0x9DBA, 0x6F94, 0x9DBB, 0x6F95, 0x9DBC, 0x6F96, 0x9DBD, 0x6F97, 0x9DBE, 0x6F98, 0x9DBF, 0x6F99, 0x9DC0, 0x6F9A, 0x9DC1, - 0x6F9B, 0x9DC2, 0x6F9C, 0xC0BD, 0x6F9D, 0x9DC3, 0x6F9E, 0x9DC4, 0x6F9F, 0x9DC5, 0x6FA0, 0x9DC6, 0x6FA1, 0xD4E8, 0x6FA2, 0x9DC7, - 0x6FA3, 0x9DC8, 0x6FA4, 0x9DC9, 0x6FA5, 0x9DCA, 0x6FA6, 0x9DCB, 0x6FA7, 0xE5A2, 0x6FA8, 0x9DCC, 0x6FA9, 0x9DCD, 0x6FAA, 0x9DCE, - 0x6FAB, 0x9DCF, 0x6FAC, 0x9DD0, 0x6FAD, 0x9DD1, 0x6FAE, 0x9DD2, 0x6FAF, 0x9DD3, 0x6FB0, 0x9DD4, 0x6FB1, 0x9DD5, 0x6FB2, 0x9DD6, - 0x6FB3, 0xB0C4, 0x6FB4, 0x9DD7, 0x6FB5, 0x9DD8, 0x6FB6, 0xE5A4, 0x6FB7, 0x9DD9, 0x6FB8, 0x9DDA, 0x6FB9, 0xE5A3, 0x6FBA, 0x9DDB, - 0x6FBB, 0x9DDC, 0x6FBC, 0x9DDD, 0x6FBD, 0x9DDE, 0x6FBE, 0x9DDF, 0x6FBF, 0x9DE0, 0x6FC0, 0xBCA4, 0x6FC1, 0x9DE1, 0x6FC2, 0xE5A5, - 0x6FC3, 0x9DE2, 0x6FC4, 0x9DE3, 0x6FC5, 0x9DE4, 0x6FC6, 0x9DE5, 0x6FC7, 0x9DE6, 0x6FC8, 0x9DE7, 0x6FC9, 0xE5A1, 0x6FCA, 0x9DE8, - 0x6FCB, 0x9DE9, 0x6FCC, 0x9DEA, 0x6FCD, 0x9DEB, 0x6FCE, 0x9DEC, 0x6FCF, 0x9DED, 0x6FD0, 0x9DEE, 0x6FD1, 0xE4FE, 0x6FD2, 0xB1F4, - 0x6FD3, 0x9DEF, 0x6FD4, 0x9DF0, 0x6FD5, 0x9DF1, 0x6FD6, 0x9DF2, 0x6FD7, 0x9DF3, 0x6FD8, 0x9DF4, 0x6FD9, 0x9DF5, 0x6FDA, 0x9DF6, - 0x6FDB, 0x9DF7, 0x6FDC, 0x9DF8, 0x6FDD, 0x9DF9, 0x6FDE, 0xE5A8, 0x6FDF, 0x9DFA, 0x6FE0, 0xE5A9, 0x6FE1, 0xE5A6, 0x6FE2, 0x9DFB, - 0x6FE3, 0x9DFC, 0x6FE4, 0x9DFD, 0x6FE5, 0x9DFE, 0x6FE6, 0x9E40, 0x6FE7, 0x9E41, 0x6FE8, 0x9E42, 0x6FE9, 0x9E43, 0x6FEA, 0x9E44, - 0x6FEB, 0x9E45, 0x6FEC, 0x9E46, 0x6FED, 0x9E47, 0x6FEE, 0xE5A7, 0x6FEF, 0xE5AA, 0x6FF0, 0x9E48, 0x6FF1, 0x9E49, 0x6FF2, 0x9E4A, - 0x6FF3, 0x9E4B, 0x6FF4, 0x9E4C, 0x6FF5, 0x9E4D, 0x6FF6, 0x9E4E, 0x6FF7, 0x9E4F, 0x6FF8, 0x9E50, 0x6FF9, 0x9E51, 0x6FFA, 0x9E52, - 0x6FFB, 0x9E53, 0x6FFC, 0x9E54, 0x6FFD, 0x9E55, 0x6FFE, 0x9E56, 0x6FFF, 0x9E57, 0x7000, 0x9E58, 0x7001, 0x9E59, 0x7002, 0x9E5A, - 0x7003, 0x9E5B, 0x7004, 0x9E5C, 0x7005, 0x9E5D, 0x7006, 0x9E5E, 0x7007, 0x9E5F, 0x7008, 0x9E60, 0x7009, 0x9E61, 0x700A, 0x9E62, - 0x700B, 0x9E63, 0x700C, 0x9E64, 0x700D, 0x9E65, 0x700E, 0x9E66, 0x700F, 0x9E67, 0x7010, 0x9E68, 0x7011, 0xC6D9, 0x7012, 0x9E69, - 0x7013, 0x9E6A, 0x7014, 0x9E6B, 0x7015, 0x9E6C, 0x7016, 0x9E6D, 0x7017, 0x9E6E, 0x7018, 0x9E6F, 0x7019, 0x9E70, 0x701A, 0xE5AB, - 0x701B, 0xE5AD, 0x701C, 0x9E71, 0x701D, 0x9E72, 0x701E, 0x9E73, 0x701F, 0x9E74, 0x7020, 0x9E75, 0x7021, 0x9E76, 0x7022, 0x9E77, - 0x7023, 0xE5AC, 0x7024, 0x9E78, 0x7025, 0x9E79, 0x7026, 0x9E7A, 0x7027, 0x9E7B, 0x7028, 0x9E7C, 0x7029, 0x9E7D, 0x702A, 0x9E7E, - 0x702B, 0x9E80, 0x702C, 0x9E81, 0x702D, 0x9E82, 0x702E, 0x9E83, 0x702F, 0x9E84, 0x7030, 0x9E85, 0x7031, 0x9E86, 0x7032, 0x9E87, - 0x7033, 0x9E88, 0x7034, 0x9E89, 0x7035, 0xE5AF, 0x7036, 0x9E8A, 0x7037, 0x9E8B, 0x7038, 0x9E8C, 0x7039, 0xE5AE, 0x703A, 0x9E8D, - 0x703B, 0x9E8E, 0x703C, 0x9E8F, 0x703D, 0x9E90, 0x703E, 0x9E91, 0x703F, 0x9E92, 0x7040, 0x9E93, 0x7041, 0x9E94, 0x7042, 0x9E95, - 0x7043, 0x9E96, 0x7044, 0x9E97, 0x7045, 0x9E98, 0x7046, 0x9E99, 0x7047, 0x9E9A, 0x7048, 0x9E9B, 0x7049, 0x9E9C, 0x704A, 0x9E9D, - 0x704B, 0x9E9E, 0x704C, 0xB9E0, 0x704D, 0x9E9F, 0x704E, 0x9EA0, 0x704F, 0xE5B0, 0x7050, 0x9EA1, 0x7051, 0x9EA2, 0x7052, 0x9EA3, - 0x7053, 0x9EA4, 0x7054, 0x9EA5, 0x7055, 0x9EA6, 0x7056, 0x9EA7, 0x7057, 0x9EA8, 0x7058, 0x9EA9, 0x7059, 0x9EAA, 0x705A, 0x9EAB, - 0x705B, 0x9EAC, 0x705C, 0x9EAD, 0x705D, 0x9EAE, 0x705E, 0xE5B1, 0x705F, 0x9EAF, 0x7060, 0x9EB0, 0x7061, 0x9EB1, 0x7062, 0x9EB2, - 0x7063, 0x9EB3, 0x7064, 0x9EB4, 0x7065, 0x9EB5, 0x7066, 0x9EB6, 0x7067, 0x9EB7, 0x7068, 0x9EB8, 0x7069, 0x9EB9, 0x706A, 0x9EBA, - 0x706B, 0xBBF0, 0x706C, 0xECE1, 0x706D, 0xC3F0, 0x706E, 0x9EBB, 0x706F, 0xB5C6, 0x7070, 0xBBD2, 0x7071, 0x9EBC, 0x7072, 0x9EBD, - 0x7073, 0x9EBE, 0x7074, 0x9EBF, 0x7075, 0xC1E9, 0x7076, 0xD4EE, 0x7077, 0x9EC0, 0x7078, 0xBEC4, 0x7079, 0x9EC1, 0x707A, 0x9EC2, - 0x707B, 0x9EC3, 0x707C, 0xD7C6, 0x707D, 0x9EC4, 0x707E, 0xD4D6, 0x707F, 0xB2D3, 0x7080, 0xECBE, 0x7081, 0x9EC5, 0x7082, 0x9EC6, - 0x7083, 0x9EC7, 0x7084, 0x9EC8, 0x7085, 0xEAC1, 0x7086, 0x9EC9, 0x7087, 0x9ECA, 0x7088, 0x9ECB, 0x7089, 0xC2AF, 0x708A, 0xB4B6, - 0x708B, 0x9ECC, 0x708C, 0x9ECD, 0x708D, 0x9ECE, 0x708E, 0xD1D7, 0x708F, 0x9ECF, 0x7090, 0x9ED0, 0x7091, 0x9ED1, 0x7092, 0xB3B4, - 0x7093, 0x9ED2, 0x7094, 0xC8B2, 0x7095, 0xBFBB, 0x7096, 0xECC0, 0x7097, 0x9ED3, 0x7098, 0x9ED4, 0x7099, 0xD6CB, 0x709A, 0x9ED5, - 0x709B, 0x9ED6, 0x709C, 0xECBF, 0x709D, 0xECC1, 0x709E, 0x9ED7, 0x709F, 0x9ED8, 0x70A0, 0x9ED9, 0x70A1, 0x9EDA, 0x70A2, 0x9EDB, - 0x70A3, 0x9EDC, 0x70A4, 0x9EDD, 0x70A5, 0x9EDE, 0x70A6, 0x9EDF, 0x70A7, 0x9EE0, 0x70A8, 0x9EE1, 0x70A9, 0x9EE2, 0x70AA, 0x9EE3, - 0x70AB, 0xECC5, 0x70AC, 0xBEE6, 0x70AD, 0xCCBF, 0x70AE, 0xC5DA, 0x70AF, 0xBEBC, 0x70B0, 0x9EE4, 0x70B1, 0xECC6, 0x70B2, 0x9EE5, - 0x70B3, 0xB1FE, 0x70B4, 0x9EE6, 0x70B5, 0x9EE7, 0x70B6, 0x9EE8, 0x70B7, 0xECC4, 0x70B8, 0xD5A8, 0x70B9, 0xB5E3, 0x70BA, 0x9EE9, - 0x70BB, 0xECC2, 0x70BC, 0xC1B6, 0x70BD, 0xB3E3, 0x70BE, 0x9EEA, 0x70BF, 0x9EEB, 0x70C0, 0xECC3, 0x70C1, 0xCBB8, 0x70C2, 0xC0C3, - 0x70C3, 0xCCFE, 0x70C4, 0x9EEC, 0x70C5, 0x9EED, 0x70C6, 0x9EEE, 0x70C7, 0x9EEF, 0x70C8, 0xC1D2, 0x70C9, 0x9EF0, 0x70CA, 0xECC8, - 0x70CB, 0x9EF1, 0x70CC, 0x9EF2, 0x70CD, 0x9EF3, 0x70CE, 0x9EF4, 0x70CF, 0x9EF5, 0x70D0, 0x9EF6, 0x70D1, 0x9EF7, 0x70D2, 0x9EF8, - 0x70D3, 0x9EF9, 0x70D4, 0x9EFA, 0x70D5, 0x9EFB, 0x70D6, 0x9EFC, 0x70D7, 0x9EFD, 0x70D8, 0xBAE6, 0x70D9, 0xC0D3, 0x70DA, 0x9EFE, - 0x70DB, 0xD6F2, 0x70DC, 0x9F40, 0x70DD, 0x9F41, 0x70DE, 0x9F42, 0x70DF, 0xD1CC, 0x70E0, 0x9F43, 0x70E1, 0x9F44, 0x70E2, 0x9F45, - 0x70E3, 0x9F46, 0x70E4, 0xBFBE, 0x70E5, 0x9F47, 0x70E6, 0xB7B3, 0x70E7, 0xC9D5, 0x70E8, 0xECC7, 0x70E9, 0xBBE2, 0x70EA, 0x9F48, - 0x70EB, 0xCCCC, 0x70EC, 0xBDFD, 0x70ED, 0xC8C8, 0x70EE, 0x9F49, 0x70EF, 0xCFA9, 0x70F0, 0x9F4A, 0x70F1, 0x9F4B, 0x70F2, 0x9F4C, - 0x70F3, 0x9F4D, 0x70F4, 0x9F4E, 0x70F5, 0x9F4F, 0x70F6, 0x9F50, 0x70F7, 0xCDE9, 0x70F8, 0x9F51, 0x70F9, 0xC5EB, 0x70FA, 0x9F52, - 0x70FB, 0x9F53, 0x70FC, 0x9F54, 0x70FD, 0xB7E9, 0x70FE, 0x9F55, 0x70FF, 0x9F56, 0x7100, 0x9F57, 0x7101, 0x9F58, 0x7102, 0x9F59, - 0x7103, 0x9F5A, 0x7104, 0x9F5B, 0x7105, 0x9F5C, 0x7106, 0x9F5D, 0x7107, 0x9F5E, 0x7108, 0x9F5F, 0x7109, 0xD1C9, 0x710A, 0xBAB8, - 0x710B, 0x9F60, 0x710C, 0x9F61, 0x710D, 0x9F62, 0x710E, 0x9F63, 0x710F, 0x9F64, 0x7110, 0xECC9, 0x7111, 0x9F65, 0x7112, 0x9F66, - 0x7113, 0xECCA, 0x7114, 0x9F67, 0x7115, 0xBBC0, 0x7116, 0xECCB, 0x7117, 0x9F68, 0x7118, 0xECE2, 0x7119, 0xB1BA, 0x711A, 0xB7D9, - 0x711B, 0x9F69, 0x711C, 0x9F6A, 0x711D, 0x9F6B, 0x711E, 0x9F6C, 0x711F, 0x9F6D, 0x7120, 0x9F6E, 0x7121, 0x9F6F, 0x7122, 0x9F70, - 0x7123, 0x9F71, 0x7124, 0x9F72, 0x7125, 0x9F73, 0x7126, 0xBDB9, 0x7127, 0x9F74, 0x7128, 0x9F75, 0x7129, 0x9F76, 0x712A, 0x9F77, - 0x712B, 0x9F78, 0x712C, 0x9F79, 0x712D, 0x9F7A, 0x712E, 0x9F7B, 0x712F, 0xECCC, 0x7130, 0xD1E6, 0x7131, 0xECCD, 0x7132, 0x9F7C, - 0x7133, 0x9F7D, 0x7134, 0x9F7E, 0x7135, 0x9F80, 0x7136, 0xC8BB, 0x7137, 0x9F81, 0x7138, 0x9F82, 0x7139, 0x9F83, 0x713A, 0x9F84, - 0x713B, 0x9F85, 0x713C, 0x9F86, 0x713D, 0x9F87, 0x713E, 0x9F88, 0x713F, 0x9F89, 0x7140, 0x9F8A, 0x7141, 0x9F8B, 0x7142, 0x9F8C, - 0x7143, 0x9F8D, 0x7144, 0x9F8E, 0x7145, 0xECD1, 0x7146, 0x9F8F, 0x7147, 0x9F90, 0x7148, 0x9F91, 0x7149, 0x9F92, 0x714A, 0xECD3, - 0x714B, 0x9F93, 0x714C, 0xBBCD, 0x714D, 0x9F94, 0x714E, 0xBCE5, 0x714F, 0x9F95, 0x7150, 0x9F96, 0x7151, 0x9F97, 0x7152, 0x9F98, - 0x7153, 0x9F99, 0x7154, 0x9F9A, 0x7155, 0x9F9B, 0x7156, 0x9F9C, 0x7157, 0x9F9D, 0x7158, 0x9F9E, 0x7159, 0x9F9F, 0x715A, 0x9FA0, - 0x715B, 0x9FA1, 0x715C, 0xECCF, 0x715D, 0x9FA2, 0x715E, 0xC9B7, 0x715F, 0x9FA3, 0x7160, 0x9FA4, 0x7161, 0x9FA5, 0x7162, 0x9FA6, - 0x7163, 0x9FA7, 0x7164, 0xC3BA, 0x7165, 0x9FA8, 0x7166, 0xECE3, 0x7167, 0xD5D5, 0x7168, 0xECD0, 0x7169, 0x9FA9, 0x716A, 0x9FAA, - 0x716B, 0x9FAB, 0x716C, 0x9FAC, 0x716D, 0x9FAD, 0x716E, 0xD6F3, 0x716F, 0x9FAE, 0x7170, 0x9FAF, 0x7171, 0x9FB0, 0x7172, 0xECD2, - 0x7173, 0xECCE, 0x7174, 0x9FB1, 0x7175, 0x9FB2, 0x7176, 0x9FB3, 0x7177, 0x9FB4, 0x7178, 0xECD4, 0x7179, 0x9FB5, 0x717A, 0xECD5, - 0x717B, 0x9FB6, 0x717C, 0x9FB7, 0x717D, 0xC9BF, 0x717E, 0x9FB8, 0x717F, 0x9FB9, 0x7180, 0x9FBA, 0x7181, 0x9FBB, 0x7182, 0x9FBC, - 0x7183, 0x9FBD, 0x7184, 0xCFA8, 0x7185, 0x9FBE, 0x7186, 0x9FBF, 0x7187, 0x9FC0, 0x7188, 0x9FC1, 0x7189, 0x9FC2, 0x718A, 0xD0DC, - 0x718B, 0x9FC3, 0x718C, 0x9FC4, 0x718D, 0x9FC5, 0x718E, 0x9FC6, 0x718F, 0xD1AC, 0x7190, 0x9FC7, 0x7191, 0x9FC8, 0x7192, 0x9FC9, - 0x7193, 0x9FCA, 0x7194, 0xC8DB, 0x7195, 0x9FCB, 0x7196, 0x9FCC, 0x7197, 0x9FCD, 0x7198, 0xECD6, 0x7199, 0xCEF5, 0x719A, 0x9FCE, - 0x719B, 0x9FCF, 0x719C, 0x9FD0, 0x719D, 0x9FD1, 0x719E, 0x9FD2, 0x719F, 0xCAEC, 0x71A0, 0xECDA, 0x71A1, 0x9FD3, 0x71A2, 0x9FD4, - 0x71A3, 0x9FD5, 0x71A4, 0x9FD6, 0x71A5, 0x9FD7, 0x71A6, 0x9FD8, 0x71A7, 0x9FD9, 0x71A8, 0xECD9, 0x71A9, 0x9FDA, 0x71AA, 0x9FDB, - 0x71AB, 0x9FDC, 0x71AC, 0xB0BE, 0x71AD, 0x9FDD, 0x71AE, 0x9FDE, 0x71AF, 0x9FDF, 0x71B0, 0x9FE0, 0x71B1, 0x9FE1, 0x71B2, 0x9FE2, - 0x71B3, 0xECD7, 0x71B4, 0x9FE3, 0x71B5, 0xECD8, 0x71B6, 0x9FE4, 0x71B7, 0x9FE5, 0x71B8, 0x9FE6, 0x71B9, 0xECE4, 0x71BA, 0x9FE7, - 0x71BB, 0x9FE8, 0x71BC, 0x9FE9, 0x71BD, 0x9FEA, 0x71BE, 0x9FEB, 0x71BF, 0x9FEC, 0x71C0, 0x9FED, 0x71C1, 0x9FEE, 0x71C2, 0x9FEF, - 0x71C3, 0xC8BC, 0x71C4, 0x9FF0, 0x71C5, 0x9FF1, 0x71C6, 0x9FF2, 0x71C7, 0x9FF3, 0x71C8, 0x9FF4, 0x71C9, 0x9FF5, 0x71CA, 0x9FF6, - 0x71CB, 0x9FF7, 0x71CC, 0x9FF8, 0x71CD, 0x9FF9, 0x71CE, 0xC1C7, 0x71CF, 0x9FFA, 0x71D0, 0x9FFB, 0x71D1, 0x9FFC, 0x71D2, 0x9FFD, - 0x71D3, 0x9FFE, 0x71D4, 0xECDC, 0x71D5, 0xD1E0, 0x71D6, 0xA040, 0x71D7, 0xA041, 0x71D8, 0xA042, 0x71D9, 0xA043, 0x71DA, 0xA044, - 0x71DB, 0xA045, 0x71DC, 0xA046, 0x71DD, 0xA047, 0x71DE, 0xA048, 0x71DF, 0xA049, 0x71E0, 0xECDB, 0x71E1, 0xA04A, 0x71E2, 0xA04B, - 0x71E3, 0xA04C, 0x71E4, 0xA04D, 0x71E5, 0xD4EF, 0x71E6, 0xA04E, 0x71E7, 0xECDD, 0x71E8, 0xA04F, 0x71E9, 0xA050, 0x71EA, 0xA051, - 0x71EB, 0xA052, 0x71EC, 0xA053, 0x71ED, 0xA054, 0x71EE, 0xDBC6, 0x71EF, 0xA055, 0x71F0, 0xA056, 0x71F1, 0xA057, 0x71F2, 0xA058, - 0x71F3, 0xA059, 0x71F4, 0xA05A, 0x71F5, 0xA05B, 0x71F6, 0xA05C, 0x71F7, 0xA05D, 0x71F8, 0xA05E, 0x71F9, 0xECDE, 0x71FA, 0xA05F, - 0x71FB, 0xA060, 0x71FC, 0xA061, 0x71FD, 0xA062, 0x71FE, 0xA063, 0x71FF, 0xA064, 0x7200, 0xA065, 0x7201, 0xA066, 0x7202, 0xA067, - 0x7203, 0xA068, 0x7204, 0xA069, 0x7205, 0xA06A, 0x7206, 0xB1AC, 0x7207, 0xA06B, 0x7208, 0xA06C, 0x7209, 0xA06D, 0x720A, 0xA06E, - 0x720B, 0xA06F, 0x720C, 0xA070, 0x720D, 0xA071, 0x720E, 0xA072, 0x720F, 0xA073, 0x7210, 0xA074, 0x7211, 0xA075, 0x7212, 0xA076, - 0x7213, 0xA077, 0x7214, 0xA078, 0x7215, 0xA079, 0x7216, 0xA07A, 0x7217, 0xA07B, 0x7218, 0xA07C, 0x7219, 0xA07D, 0x721A, 0xA07E, - 0x721B, 0xA080, 0x721C, 0xA081, 0x721D, 0xECDF, 0x721E, 0xA082, 0x721F, 0xA083, 0x7220, 0xA084, 0x7221, 0xA085, 0x7222, 0xA086, - 0x7223, 0xA087, 0x7224, 0xA088, 0x7225, 0xA089, 0x7226, 0xA08A, 0x7227, 0xA08B, 0x7228, 0xECE0, 0x7229, 0xA08C, 0x722A, 0xD7A6, - 0x722B, 0xA08D, 0x722C, 0xC5C0, 0x722D, 0xA08E, 0x722E, 0xA08F, 0x722F, 0xA090, 0x7230, 0xEBBC, 0x7231, 0xB0AE, 0x7232, 0xA091, - 0x7233, 0xA092, 0x7234, 0xA093, 0x7235, 0xBEF4, 0x7236, 0xB8B8, 0x7237, 0xD2AF, 0x7238, 0xB0D6, 0x7239, 0xB5F9, 0x723A, 0xA094, - 0x723B, 0xD8B3, 0x723C, 0xA095, 0x723D, 0xCBAC, 0x723E, 0xA096, 0x723F, 0xE3DD, 0x7240, 0xA097, 0x7241, 0xA098, 0x7242, 0xA099, - 0x7243, 0xA09A, 0x7244, 0xA09B, 0x7245, 0xA09C, 0x7246, 0xA09D, 0x7247, 0xC6AC, 0x7248, 0xB0E6, 0x7249, 0xA09E, 0x724A, 0xA09F, - 0x724B, 0xA0A0, 0x724C, 0xC5C6, 0x724D, 0xEBB9, 0x724E, 0xA0A1, 0x724F, 0xA0A2, 0x7250, 0xA0A3, 0x7251, 0xA0A4, 0x7252, 0xEBBA, - 0x7253, 0xA0A5, 0x7254, 0xA0A6, 0x7255, 0xA0A7, 0x7256, 0xEBBB, 0x7257, 0xA0A8, 0x7258, 0xA0A9, 0x7259, 0xD1C0, 0x725A, 0xA0AA, - 0x725B, 0xC5A3, 0x725C, 0xA0AB, 0x725D, 0xEAF2, 0x725E, 0xA0AC, 0x725F, 0xC4B2, 0x7260, 0xA0AD, 0x7261, 0xC4B5, 0x7262, 0xC0CE, - 0x7263, 0xA0AE, 0x7264, 0xA0AF, 0x7265, 0xA0B0, 0x7266, 0xEAF3, 0x7267, 0xC4C1, 0x7268, 0xA0B1, 0x7269, 0xCEEF, 0x726A, 0xA0B2, - 0x726B, 0xA0B3, 0x726C, 0xA0B4, 0x726D, 0xA0B5, 0x726E, 0xEAF0, 0x726F, 0xEAF4, 0x7270, 0xA0B6, 0x7271, 0xA0B7, 0x7272, 0xC9FC, - 0x7273, 0xA0B8, 0x7274, 0xA0B9, 0x7275, 0xC7A3, 0x7276, 0xA0BA, 0x7277, 0xA0BB, 0x7278, 0xA0BC, 0x7279, 0xCCD8, 0x727A, 0xCEFE, - 0x727B, 0xA0BD, 0x727C, 0xA0BE, 0x727D, 0xA0BF, 0x727E, 0xEAF5, 0x727F, 0xEAF6, 0x7280, 0xCFAC, 0x7281, 0xC0E7, 0x7282, 0xA0C0, - 0x7283, 0xA0C1, 0x7284, 0xEAF7, 0x7285, 0xA0C2, 0x7286, 0xA0C3, 0x7287, 0xA0C4, 0x7288, 0xA0C5, 0x7289, 0xA0C6, 0x728A, 0xB6BF, - 0x728B, 0xEAF8, 0x728C, 0xA0C7, 0x728D, 0xEAF9, 0x728E, 0xA0C8, 0x728F, 0xEAFA, 0x7290, 0xA0C9, 0x7291, 0xA0CA, 0x7292, 0xEAFB, - 0x7293, 0xA0CB, 0x7294, 0xA0CC, 0x7295, 0xA0CD, 0x7296, 0xA0CE, 0x7297, 0xA0CF, 0x7298, 0xA0D0, 0x7299, 0xA0D1, 0x729A, 0xA0D2, - 0x729B, 0xA0D3, 0x729C, 0xA0D4, 0x729D, 0xA0D5, 0x729E, 0xA0D6, 0x729F, 0xEAF1, 0x72A0, 0xA0D7, 0x72A1, 0xA0D8, 0x72A2, 0xA0D9, - 0x72A3, 0xA0DA, 0x72A4, 0xA0DB, 0x72A5, 0xA0DC, 0x72A6, 0xA0DD, 0x72A7, 0xA0DE, 0x72A8, 0xA0DF, 0x72A9, 0xA0E0, 0x72AA, 0xA0E1, - 0x72AB, 0xA0E2, 0x72AC, 0xC8AE, 0x72AD, 0xE1EB, 0x72AE, 0xA0E3, 0x72AF, 0xB7B8, 0x72B0, 0xE1EC, 0x72B1, 0xA0E4, 0x72B2, 0xA0E5, - 0x72B3, 0xA0E6, 0x72B4, 0xE1ED, 0x72B5, 0xA0E7, 0x72B6, 0xD7B4, 0x72B7, 0xE1EE, 0x72B8, 0xE1EF, 0x72B9, 0xD3CC, 0x72BA, 0xA0E8, - 0x72BB, 0xA0E9, 0x72BC, 0xA0EA, 0x72BD, 0xA0EB, 0x72BE, 0xA0EC, 0x72BF, 0xA0ED, 0x72C0, 0xA0EE, 0x72C1, 0xE1F1, 0x72C2, 0xBFF1, - 0x72C3, 0xE1F0, 0x72C4, 0xB5D2, 0x72C5, 0xA0EF, 0x72C6, 0xA0F0, 0x72C7, 0xA0F1, 0x72C8, 0xB1B7, 0x72C9, 0xA0F2, 0x72CA, 0xA0F3, - 0x72CB, 0xA0F4, 0x72CC, 0xA0F5, 0x72CD, 0xE1F3, 0x72CE, 0xE1F2, 0x72CF, 0xA0F6, 0x72D0, 0xBAFC, 0x72D1, 0xA0F7, 0x72D2, 0xE1F4, - 0x72D3, 0xA0F8, 0x72D4, 0xA0F9, 0x72D5, 0xA0FA, 0x72D6, 0xA0FB, 0x72D7, 0xB9B7, 0x72D8, 0xA0FC, 0x72D9, 0xBED1, 0x72DA, 0xA0FD, - 0x72DB, 0xA0FE, 0x72DC, 0xAA40, 0x72DD, 0xAA41, 0x72DE, 0xC4FC, 0x72DF, 0xAA42, 0x72E0, 0xBADD, 0x72E1, 0xBDC6, 0x72E2, 0xAA43, - 0x72E3, 0xAA44, 0x72E4, 0xAA45, 0x72E5, 0xAA46, 0x72E6, 0xAA47, 0x72E7, 0xAA48, 0x72E8, 0xE1F5, 0x72E9, 0xE1F7, 0x72EA, 0xAA49, - 0x72EB, 0xAA4A, 0x72EC, 0xB6C0, 0x72ED, 0xCFC1, 0x72EE, 0xCAA8, 0x72EF, 0xE1F6, 0x72F0, 0xD5F8, 0x72F1, 0xD3FC, 0x72F2, 0xE1F8, - 0x72F3, 0xE1FC, 0x72F4, 0xE1F9, 0x72F5, 0xAA4B, 0x72F6, 0xAA4C, 0x72F7, 0xE1FA, 0x72F8, 0xC0EA, 0x72F9, 0xAA4D, 0x72FA, 0xE1FE, - 0x72FB, 0xE2A1, 0x72FC, 0xC0C7, 0x72FD, 0xAA4E, 0x72FE, 0xAA4F, 0x72FF, 0xAA50, 0x7300, 0xAA51, 0x7301, 0xE1FB, 0x7302, 0xAA52, - 0x7303, 0xE1FD, 0x7304, 0xAA53, 0x7305, 0xAA54, 0x7306, 0xAA55, 0x7307, 0xAA56, 0x7308, 0xAA57, 0x7309, 0xAA58, 0x730A, 0xE2A5, - 0x730B, 0xAA59, 0x730C, 0xAA5A, 0x730D, 0xAA5B, 0x730E, 0xC1D4, 0x730F, 0xAA5C, 0x7310, 0xAA5D, 0x7311, 0xAA5E, 0x7312, 0xAA5F, - 0x7313, 0xE2A3, 0x7314, 0xAA60, 0x7315, 0xE2A8, 0x7316, 0xB2FE, 0x7317, 0xE2A2, 0x7318, 0xAA61, 0x7319, 0xAA62, 0x731A, 0xAA63, - 0x731B, 0xC3CD, 0x731C, 0xB2C2, 0x731D, 0xE2A7, 0x731E, 0xE2A6, 0x731F, 0xAA64, 0x7320, 0xAA65, 0x7321, 0xE2A4, 0x7322, 0xE2A9, - 0x7323, 0xAA66, 0x7324, 0xAA67, 0x7325, 0xE2AB, 0x7326, 0xAA68, 0x7327, 0xAA69, 0x7328, 0xAA6A, 0x7329, 0xD0C9, 0x732A, 0xD6ED, - 0x732B, 0xC3A8, 0x732C, 0xE2AC, 0x732D, 0xAA6B, 0x732E, 0xCFD7, 0x732F, 0xAA6C, 0x7330, 0xAA6D, 0x7331, 0xE2AE, 0x7332, 0xAA6E, - 0x7333, 0xAA6F, 0x7334, 0xBAEF, 0x7335, 0xAA70, 0x7336, 0xAA71, 0x7337, 0xE9E0, 0x7338, 0xE2AD, 0x7339, 0xE2AA, 0x733A, 0xAA72, - 0x733B, 0xAA73, 0x733C, 0xAA74, 0x733D, 0xAA75, 0x733E, 0xBBAB, 0x733F, 0xD4B3, 0x7340, 0xAA76, 0x7341, 0xAA77, 0x7342, 0xAA78, - 0x7343, 0xAA79, 0x7344, 0xAA7A, 0x7345, 0xAA7B, 0x7346, 0xAA7C, 0x7347, 0xAA7D, 0x7348, 0xAA7E, 0x7349, 0xAA80, 0x734A, 0xAA81, - 0x734B, 0xAA82, 0x734C, 0xAA83, 0x734D, 0xE2B0, 0x734E, 0xAA84, 0x734F, 0xAA85, 0x7350, 0xE2AF, 0x7351, 0xAA86, 0x7352, 0xE9E1, - 0x7353, 0xAA87, 0x7354, 0xAA88, 0x7355, 0xAA89, 0x7356, 0xAA8A, 0x7357, 0xE2B1, 0x7358, 0xAA8B, 0x7359, 0xAA8C, 0x735A, 0xAA8D, - 0x735B, 0xAA8E, 0x735C, 0xAA8F, 0x735D, 0xAA90, 0x735E, 0xAA91, 0x735F, 0xAA92, 0x7360, 0xE2B2, 0x7361, 0xAA93, 0x7362, 0xAA94, - 0x7363, 0xAA95, 0x7364, 0xAA96, 0x7365, 0xAA97, 0x7366, 0xAA98, 0x7367, 0xAA99, 0x7368, 0xAA9A, 0x7369, 0xAA9B, 0x736A, 0xAA9C, - 0x736B, 0xAA9D, 0x736C, 0xE2B3, 0x736D, 0xCCA1, 0x736E, 0xAA9E, 0x736F, 0xE2B4, 0x7370, 0xAA9F, 0x7371, 0xAAA0, 0x7372, 0xAB40, - 0x7373, 0xAB41, 0x7374, 0xAB42, 0x7375, 0xAB43, 0x7376, 0xAB44, 0x7377, 0xAB45, 0x7378, 0xAB46, 0x7379, 0xAB47, 0x737A, 0xAB48, - 0x737B, 0xAB49, 0x737C, 0xAB4A, 0x737D, 0xAB4B, 0x737E, 0xE2B5, 0x737F, 0xAB4C, 0x7380, 0xAB4D, 0x7381, 0xAB4E, 0x7382, 0xAB4F, - 0x7383, 0xAB50, 0x7384, 0xD0FE, 0x7385, 0xAB51, 0x7386, 0xAB52, 0x7387, 0xC2CA, 0x7388, 0xAB53, 0x7389, 0xD3F1, 0x738A, 0xAB54, - 0x738B, 0xCDF5, 0x738C, 0xAB55, 0x738D, 0xAB56, 0x738E, 0xE7E0, 0x738F, 0xAB57, 0x7390, 0xAB58, 0x7391, 0xE7E1, 0x7392, 0xAB59, - 0x7393, 0xAB5A, 0x7394, 0xAB5B, 0x7395, 0xAB5C, 0x7396, 0xBEC1, 0x7397, 0xAB5D, 0x7398, 0xAB5E, 0x7399, 0xAB5F, 0x739A, 0xAB60, - 0x739B, 0xC2EA, 0x739C, 0xAB61, 0x739D, 0xAB62, 0x739E, 0xAB63, 0x739F, 0xE7E4, 0x73A0, 0xAB64, 0x73A1, 0xAB65, 0x73A2, 0xE7E3, - 0x73A3, 0xAB66, 0x73A4, 0xAB67, 0x73A5, 0xAB68, 0x73A6, 0xAB69, 0x73A7, 0xAB6A, 0x73A8, 0xAB6B, 0x73A9, 0xCDE6, 0x73AA, 0xAB6C, - 0x73AB, 0xC3B5, 0x73AC, 0xAB6D, 0x73AD, 0xAB6E, 0x73AE, 0xE7E2, 0x73AF, 0xBBB7, 0x73B0, 0xCFD6, 0x73B1, 0xAB6F, 0x73B2, 0xC1E1, - 0x73B3, 0xE7E9, 0x73B4, 0xAB70, 0x73B5, 0xAB71, 0x73B6, 0xAB72, 0x73B7, 0xE7E8, 0x73B8, 0xAB73, 0x73B9, 0xAB74, 0x73BA, 0xE7F4, - 0x73BB, 0xB2A3, 0x73BC, 0xAB75, 0x73BD, 0xAB76, 0x73BE, 0xAB77, 0x73BF, 0xAB78, 0x73C0, 0xE7EA, 0x73C1, 0xAB79, 0x73C2, 0xE7E6, - 0x73C3, 0xAB7A, 0x73C4, 0xAB7B, 0x73C5, 0xAB7C, 0x73C6, 0xAB7D, 0x73C7, 0xAB7E, 0x73C8, 0xE7EC, 0x73C9, 0xE7EB, 0x73CA, 0xC9BA, - 0x73CB, 0xAB80, 0x73CC, 0xAB81, 0x73CD, 0xD5E4, 0x73CE, 0xAB82, 0x73CF, 0xE7E5, 0x73D0, 0xB7A9, 0x73D1, 0xE7E7, 0x73D2, 0xAB83, - 0x73D3, 0xAB84, 0x73D4, 0xAB85, 0x73D5, 0xAB86, 0x73D6, 0xAB87, 0x73D7, 0xAB88, 0x73D8, 0xAB89, 0x73D9, 0xE7EE, 0x73DA, 0xAB8A, - 0x73DB, 0xAB8B, 0x73DC, 0xAB8C, 0x73DD, 0xAB8D, 0x73DE, 0xE7F3, 0x73DF, 0xAB8E, 0x73E0, 0xD6E9, 0x73E1, 0xAB8F, 0x73E2, 0xAB90, - 0x73E3, 0xAB91, 0x73E4, 0xAB92, 0x73E5, 0xE7ED, 0x73E6, 0xAB93, 0x73E7, 0xE7F2, 0x73E8, 0xAB94, 0x73E9, 0xE7F1, 0x73EA, 0xAB95, - 0x73EB, 0xAB96, 0x73EC, 0xAB97, 0x73ED, 0xB0E0, 0x73EE, 0xAB98, 0x73EF, 0xAB99, 0x73F0, 0xAB9A, 0x73F1, 0xAB9B, 0x73F2, 0xE7F5, - 0x73F3, 0xAB9C, 0x73F4, 0xAB9D, 0x73F5, 0xAB9E, 0x73F6, 0xAB9F, 0x73F7, 0xABA0, 0x73F8, 0xAC40, 0x73F9, 0xAC41, 0x73FA, 0xAC42, - 0x73FB, 0xAC43, 0x73FC, 0xAC44, 0x73FD, 0xAC45, 0x73FE, 0xAC46, 0x73FF, 0xAC47, 0x7400, 0xAC48, 0x7401, 0xAC49, 0x7402, 0xAC4A, - 0x7403, 0xC7F2, 0x7404, 0xAC4B, 0x7405, 0xC0C5, 0x7406, 0xC0ED, 0x7407, 0xAC4C, 0x7408, 0xAC4D, 0x7409, 0xC1F0, 0x740A, 0xE7F0, - 0x740B, 0xAC4E, 0x740C, 0xAC4F, 0x740D, 0xAC50, 0x740E, 0xAC51, 0x740F, 0xE7F6, 0x7410, 0xCBF6, 0x7411, 0xAC52, 0x7412, 0xAC53, - 0x7413, 0xAC54, 0x7414, 0xAC55, 0x7415, 0xAC56, 0x7416, 0xAC57, 0x7417, 0xAC58, 0x7418, 0xAC59, 0x7419, 0xAC5A, 0x741A, 0xE8A2, - 0x741B, 0xE8A1, 0x741C, 0xAC5B, 0x741D, 0xAC5C, 0x741E, 0xAC5D, 0x741F, 0xAC5E, 0x7420, 0xAC5F, 0x7421, 0xAC60, 0x7422, 0xD7C1, - 0x7423, 0xAC61, 0x7424, 0xAC62, 0x7425, 0xE7FA, 0x7426, 0xE7F9, 0x7427, 0xAC63, 0x7428, 0xE7FB, 0x7429, 0xAC64, 0x742A, 0xE7F7, - 0x742B, 0xAC65, 0x742C, 0xE7FE, 0x742D, 0xAC66, 0x742E, 0xE7FD, 0x742F, 0xAC67, 0x7430, 0xE7FC, 0x7431, 0xAC68, 0x7432, 0xAC69, - 0x7433, 0xC1D5, 0x7434, 0xC7D9, 0x7435, 0xC5FD, 0x7436, 0xC5C3, 0x7437, 0xAC6A, 0x7438, 0xAC6B, 0x7439, 0xAC6C, 0x743A, 0xAC6D, - 0x743B, 0xAC6E, 0x743C, 0xC7ED, 0x743D, 0xAC6F, 0x743E, 0xAC70, 0x743F, 0xAC71, 0x7440, 0xAC72, 0x7441, 0xE8A3, 0x7442, 0xAC73, - 0x7443, 0xAC74, 0x7444, 0xAC75, 0x7445, 0xAC76, 0x7446, 0xAC77, 0x7447, 0xAC78, 0x7448, 0xAC79, 0x7449, 0xAC7A, 0x744A, 0xAC7B, - 0x744B, 0xAC7C, 0x744C, 0xAC7D, 0x744D, 0xAC7E, 0x744E, 0xAC80, 0x744F, 0xAC81, 0x7450, 0xAC82, 0x7451, 0xAC83, 0x7452, 0xAC84, - 0x7453, 0xAC85, 0x7454, 0xAC86, 0x7455, 0xE8A6, 0x7456, 0xAC87, 0x7457, 0xE8A5, 0x7458, 0xAC88, 0x7459, 0xE8A7, 0x745A, 0xBAF7, - 0x745B, 0xE7F8, 0x745C, 0xE8A4, 0x745D, 0xAC89, 0x745E, 0xC8F0, 0x745F, 0xC9AA, 0x7460, 0xAC8A, 0x7461, 0xAC8B, 0x7462, 0xAC8C, - 0x7463, 0xAC8D, 0x7464, 0xAC8E, 0x7465, 0xAC8F, 0x7466, 0xAC90, 0x7467, 0xAC91, 0x7468, 0xAC92, 0x7469, 0xAC93, 0x746A, 0xAC94, - 0x746B, 0xAC95, 0x746C, 0xAC96, 0x746D, 0xE8A9, 0x746E, 0xAC97, 0x746F, 0xAC98, 0x7470, 0xB9E5, 0x7471, 0xAC99, 0x7472, 0xAC9A, - 0x7473, 0xAC9B, 0x7474, 0xAC9C, 0x7475, 0xAC9D, 0x7476, 0xD1FE, 0x7477, 0xE8A8, 0x7478, 0xAC9E, 0x7479, 0xAC9F, 0x747A, 0xACA0, - 0x747B, 0xAD40, 0x747C, 0xAD41, 0x747D, 0xAD42, 0x747E, 0xE8AA, 0x747F, 0xAD43, 0x7480, 0xE8AD, 0x7481, 0xE8AE, 0x7482, 0xAD44, - 0x7483, 0xC1A7, 0x7484, 0xAD45, 0x7485, 0xAD46, 0x7486, 0xAD47, 0x7487, 0xE8AF, 0x7488, 0xAD48, 0x7489, 0xAD49, 0x748A, 0xAD4A, - 0x748B, 0xE8B0, 0x748C, 0xAD4B, 0x748D, 0xAD4C, 0x748E, 0xE8AC, 0x748F, 0xAD4D, 0x7490, 0xE8B4, 0x7491, 0xAD4E, 0x7492, 0xAD4F, - 0x7493, 0xAD50, 0x7494, 0xAD51, 0x7495, 0xAD52, 0x7496, 0xAD53, 0x7497, 0xAD54, 0x7498, 0xAD55, 0x7499, 0xAD56, 0x749A, 0xAD57, - 0x749B, 0xAD58, 0x749C, 0xE8AB, 0x749D, 0xAD59, 0x749E, 0xE8B1, 0x749F, 0xAD5A, 0x74A0, 0xAD5B, 0x74A1, 0xAD5C, 0x74A2, 0xAD5D, - 0x74A3, 0xAD5E, 0x74A4, 0xAD5F, 0x74A5, 0xAD60, 0x74A6, 0xAD61, 0x74A7, 0xE8B5, 0x74A8, 0xE8B2, 0x74A9, 0xE8B3, 0x74AA, 0xAD62, - 0x74AB, 0xAD63, 0x74AC, 0xAD64, 0x74AD, 0xAD65, 0x74AE, 0xAD66, 0x74AF, 0xAD67, 0x74B0, 0xAD68, 0x74B1, 0xAD69, 0x74B2, 0xAD6A, - 0x74B3, 0xAD6B, 0x74B4, 0xAD6C, 0x74B5, 0xAD6D, 0x74B6, 0xAD6E, 0x74B7, 0xAD6F, 0x74B8, 0xAD70, 0x74B9, 0xAD71, 0x74BA, 0xE8B7, - 0x74BB, 0xAD72, 0x74BC, 0xAD73, 0x74BD, 0xAD74, 0x74BE, 0xAD75, 0x74BF, 0xAD76, 0x74C0, 0xAD77, 0x74C1, 0xAD78, 0x74C2, 0xAD79, - 0x74C3, 0xAD7A, 0x74C4, 0xAD7B, 0x74C5, 0xAD7C, 0x74C6, 0xAD7D, 0x74C7, 0xAD7E, 0x74C8, 0xAD80, 0x74C9, 0xAD81, 0x74CA, 0xAD82, - 0x74CB, 0xAD83, 0x74CC, 0xAD84, 0x74CD, 0xAD85, 0x74CE, 0xAD86, 0x74CF, 0xAD87, 0x74D0, 0xAD88, 0x74D1, 0xAD89, 0x74D2, 0xE8B6, - 0x74D3, 0xAD8A, 0x74D4, 0xAD8B, 0x74D5, 0xAD8C, 0x74D6, 0xAD8D, 0x74D7, 0xAD8E, 0x74D8, 0xAD8F, 0x74D9, 0xAD90, 0x74DA, 0xAD91, - 0x74DB, 0xAD92, 0x74DC, 0xB9CF, 0x74DD, 0xAD93, 0x74DE, 0xF0AC, 0x74DF, 0xAD94, 0x74E0, 0xF0AD, 0x74E1, 0xAD95, 0x74E2, 0xC6B0, - 0x74E3, 0xB0EA, 0x74E4, 0xC8BF, 0x74E5, 0xAD96, 0x74E6, 0xCDDF, 0x74E7, 0xAD97, 0x74E8, 0xAD98, 0x74E9, 0xAD99, 0x74EA, 0xAD9A, - 0x74EB, 0xAD9B, 0x74EC, 0xAD9C, 0x74ED, 0xAD9D, 0x74EE, 0xCECD, 0x74EF, 0xEAB1, 0x74F0, 0xAD9E, 0x74F1, 0xAD9F, 0x74F2, 0xADA0, - 0x74F3, 0xAE40, 0x74F4, 0xEAB2, 0x74F5, 0xAE41, 0x74F6, 0xC6BF, 0x74F7, 0xB4C9, 0x74F8, 0xAE42, 0x74F9, 0xAE43, 0x74FA, 0xAE44, - 0x74FB, 0xAE45, 0x74FC, 0xAE46, 0x74FD, 0xAE47, 0x74FE, 0xAE48, 0x74FF, 0xEAB3, 0x7500, 0xAE49, 0x7501, 0xAE4A, 0x7502, 0xAE4B, - 0x7503, 0xAE4C, 0x7504, 0xD5E7, 0x7505, 0xAE4D, 0x7506, 0xAE4E, 0x7507, 0xAE4F, 0x7508, 0xAE50, 0x7509, 0xAE51, 0x750A, 0xAE52, - 0x750B, 0xAE53, 0x750C, 0xAE54, 0x750D, 0xDDF9, 0x750E, 0xAE55, 0x750F, 0xEAB4, 0x7510, 0xAE56, 0x7511, 0xEAB5, 0x7512, 0xAE57, - 0x7513, 0xEAB6, 0x7514, 0xAE58, 0x7515, 0xAE59, 0x7516, 0xAE5A, 0x7517, 0xAE5B, 0x7518, 0xB8CA, 0x7519, 0xDFB0, 0x751A, 0xC9F5, - 0x751B, 0xAE5C, 0x751C, 0xCCF0, 0x751D, 0xAE5D, 0x751E, 0xAE5E, 0x751F, 0xC9FA, 0x7520, 0xAE5F, 0x7521, 0xAE60, 0x7522, 0xAE61, - 0x7523, 0xAE62, 0x7524, 0xAE63, 0x7525, 0xC9FB, 0x7526, 0xAE64, 0x7527, 0xAE65, 0x7528, 0xD3C3, 0x7529, 0xCBA6, 0x752A, 0xAE66, - 0x752B, 0xB8A6, 0x752C, 0xF0AE, 0x752D, 0xB1C2, 0x752E, 0xAE67, 0x752F, 0xE5B8, 0x7530, 0xCCEF, 0x7531, 0xD3C9, 0x7532, 0xBCD7, - 0x7533, 0xC9EA, 0x7534, 0xAE68, 0x7535, 0xB5E7, 0x7536, 0xAE69, 0x7537, 0xC4D0, 0x7538, 0xB5E9, 0x7539, 0xAE6A, 0x753A, 0xEEAE, - 0x753B, 0xBBAD, 0x753C, 0xAE6B, 0x753D, 0xAE6C, 0x753E, 0xE7DE, 0x753F, 0xAE6D, 0x7540, 0xEEAF, 0x7541, 0xAE6E, 0x7542, 0xAE6F, - 0x7543, 0xAE70, 0x7544, 0xAE71, 0x7545, 0xB3A9, 0x7546, 0xAE72, 0x7547, 0xAE73, 0x7548, 0xEEB2, 0x7549, 0xAE74, 0x754A, 0xAE75, - 0x754B, 0xEEB1, 0x754C, 0xBDE7, 0x754D, 0xAE76, 0x754E, 0xEEB0, 0x754F, 0xCEB7, 0x7550, 0xAE77, 0x7551, 0xAE78, 0x7552, 0xAE79, - 0x7553, 0xAE7A, 0x7554, 0xC5CF, 0x7555, 0xAE7B, 0x7556, 0xAE7C, 0x7557, 0xAE7D, 0x7558, 0xAE7E, 0x7559, 0xC1F4, 0x755A, 0xDBCE, - 0x755B, 0xEEB3, 0x755C, 0xD0F3, 0x755D, 0xAE80, 0x755E, 0xAE81, 0x755F, 0xAE82, 0x7560, 0xAE83, 0x7561, 0xAE84, 0x7562, 0xAE85, - 0x7563, 0xAE86, 0x7564, 0xAE87, 0x7565, 0xC2D4, 0x7566, 0xC6E8, 0x7567, 0xAE88, 0x7568, 0xAE89, 0x7569, 0xAE8A, 0x756A, 0xB7AC, - 0x756B, 0xAE8B, 0x756C, 0xAE8C, 0x756D, 0xAE8D, 0x756E, 0xAE8E, 0x756F, 0xAE8F, 0x7570, 0xAE90, 0x7571, 0xAE91, 0x7572, 0xEEB4, - 0x7573, 0xAE92, 0x7574, 0xB3EB, 0x7575, 0xAE93, 0x7576, 0xAE94, 0x7577, 0xAE95, 0x7578, 0xBBFB, 0x7579, 0xEEB5, 0x757A, 0xAE96, - 0x757B, 0xAE97, 0x757C, 0xAE98, 0x757D, 0xAE99, 0x757E, 0xAE9A, 0x757F, 0xE7DC, 0x7580, 0xAE9B, 0x7581, 0xAE9C, 0x7582, 0xAE9D, - 0x7583, 0xEEB6, 0x7584, 0xAE9E, 0x7585, 0xAE9F, 0x7586, 0xBDAE, 0x7587, 0xAEA0, 0x7588, 0xAF40, 0x7589, 0xAF41, 0x758A, 0xAF42, - 0x758B, 0xF1E2, 0x758C, 0xAF43, 0x758D, 0xAF44, 0x758E, 0xAF45, 0x758F, 0xCAE8, 0x7590, 0xAF46, 0x7591, 0xD2C9, 0x7592, 0xF0DA, - 0x7593, 0xAF47, 0x7594, 0xF0DB, 0x7595, 0xAF48, 0x7596, 0xF0DC, 0x7597, 0xC1C6, 0x7598, 0xAF49, 0x7599, 0xB8ED, 0x759A, 0xBECE, - 0x759B, 0xAF4A, 0x759C, 0xAF4B, 0x759D, 0xF0DE, 0x759E, 0xAF4C, 0x759F, 0xC5B1, 0x75A0, 0xF0DD, 0x75A1, 0xD1F1, 0x75A2, 0xAF4D, - 0x75A3, 0xF0E0, 0x75A4, 0xB0CC, 0x75A5, 0xBDEA, 0x75A6, 0xAF4E, 0x75A7, 0xAF4F, 0x75A8, 0xAF50, 0x75A9, 0xAF51, 0x75AA, 0xAF52, - 0x75AB, 0xD2DF, 0x75AC, 0xF0DF, 0x75AD, 0xAF53, 0x75AE, 0xB4AF, 0x75AF, 0xB7E8, 0x75B0, 0xF0E6, 0x75B1, 0xF0E5, 0x75B2, 0xC6A3, - 0x75B3, 0xF0E1, 0x75B4, 0xF0E2, 0x75B5, 0xB4C3, 0x75B6, 0xAF54, 0x75B7, 0xAF55, 0x75B8, 0xF0E3, 0x75B9, 0xD5EE, 0x75BA, 0xAF56, - 0x75BB, 0xAF57, 0x75BC, 0xCCDB, 0x75BD, 0xBED2, 0x75BE, 0xBCB2, 0x75BF, 0xAF58, 0x75C0, 0xAF59, 0x75C1, 0xAF5A, 0x75C2, 0xF0E8, - 0x75C3, 0xF0E7, 0x75C4, 0xF0E4, 0x75C5, 0xB2A1, 0x75C6, 0xAF5B, 0x75C7, 0xD6A2, 0x75C8, 0xD3B8, 0x75C9, 0xBEB7, 0x75CA, 0xC8AC, - 0x75CB, 0xAF5C, 0x75CC, 0xAF5D, 0x75CD, 0xF0EA, 0x75CE, 0xAF5E, 0x75CF, 0xAF5F, 0x75D0, 0xAF60, 0x75D1, 0xAF61, 0x75D2, 0xD1F7, - 0x75D3, 0xAF62, 0x75D4, 0xD6CC, 0x75D5, 0xBADB, 0x75D6, 0xF0E9, 0x75D7, 0xAF63, 0x75D8, 0xB6BB, 0x75D9, 0xAF64, 0x75DA, 0xAF65, - 0x75DB, 0xCDB4, 0x75DC, 0xAF66, 0x75DD, 0xAF67, 0x75DE, 0xC6A6, 0x75DF, 0xAF68, 0x75E0, 0xAF69, 0x75E1, 0xAF6A, 0x75E2, 0xC1A1, - 0x75E3, 0xF0EB, 0x75E4, 0xF0EE, 0x75E5, 0xAF6B, 0x75E6, 0xF0ED, 0x75E7, 0xF0F0, 0x75E8, 0xF0EC, 0x75E9, 0xAF6C, 0x75EA, 0xBBBE, - 0x75EB, 0xF0EF, 0x75EC, 0xAF6D, 0x75ED, 0xAF6E, 0x75EE, 0xAF6F, 0x75EF, 0xAF70, 0x75F0, 0xCCB5, 0x75F1, 0xF0F2, 0x75F2, 0xAF71, - 0x75F3, 0xAF72, 0x75F4, 0xB3D5, 0x75F5, 0xAF73, 0x75F6, 0xAF74, 0x75F7, 0xAF75, 0x75F8, 0xAF76, 0x75F9, 0xB1D4, 0x75FA, 0xAF77, - 0x75FB, 0xAF78, 0x75FC, 0xF0F3, 0x75FD, 0xAF79, 0x75FE, 0xAF7A, 0x75FF, 0xF0F4, 0x7600, 0xF0F6, 0x7601, 0xB4E1, 0x7602, 0xAF7B, - 0x7603, 0xF0F1, 0x7604, 0xAF7C, 0x7605, 0xF0F7, 0x7606, 0xAF7D, 0x7607, 0xAF7E, 0x7608, 0xAF80, 0x7609, 0xAF81, 0x760A, 0xF0FA, - 0x760B, 0xAF82, 0x760C, 0xF0F8, 0x760D, 0xAF83, 0x760E, 0xAF84, 0x760F, 0xAF85, 0x7610, 0xF0F5, 0x7611, 0xAF86, 0x7612, 0xAF87, - 0x7613, 0xAF88, 0x7614, 0xAF89, 0x7615, 0xF0FD, 0x7616, 0xAF8A, 0x7617, 0xF0F9, 0x7618, 0xF0FC, 0x7619, 0xF0FE, 0x761A, 0xAF8B, - 0x761B, 0xF1A1, 0x761C, 0xAF8C, 0x761D, 0xAF8D, 0x761E, 0xAF8E, 0x761F, 0xCEC1, 0x7620, 0xF1A4, 0x7621, 0xAF8F, 0x7622, 0xF1A3, - 0x7623, 0xAF90, 0x7624, 0xC1F6, 0x7625, 0xF0FB, 0x7626, 0xCADD, 0x7627, 0xAF91, 0x7628, 0xAF92, 0x7629, 0xB4F1, 0x762A, 0xB1F1, - 0x762B, 0xCCB1, 0x762C, 0xAF93, 0x762D, 0xF1A6, 0x762E, 0xAF94, 0x762F, 0xAF95, 0x7630, 0xF1A7, 0x7631, 0xAF96, 0x7632, 0xAF97, - 0x7633, 0xF1AC, 0x7634, 0xD5CE, 0x7635, 0xF1A9, 0x7636, 0xAF98, 0x7637, 0xAF99, 0x7638, 0xC8B3, 0x7639, 0xAF9A, 0x763A, 0xAF9B, - 0x763B, 0xAF9C, 0x763C, 0xF1A2, 0x763D, 0xAF9D, 0x763E, 0xF1AB, 0x763F, 0xF1A8, 0x7640, 0xF1A5, 0x7641, 0xAF9E, 0x7642, 0xAF9F, - 0x7643, 0xF1AA, 0x7644, 0xAFA0, 0x7645, 0xB040, 0x7646, 0xB041, 0x7647, 0xB042, 0x7648, 0xB043, 0x7649, 0xB044, 0x764A, 0xB045, - 0x764B, 0xB046, 0x764C, 0xB0A9, 0x764D, 0xF1AD, 0x764E, 0xB047, 0x764F, 0xB048, 0x7650, 0xB049, 0x7651, 0xB04A, 0x7652, 0xB04B, - 0x7653, 0xB04C, 0x7654, 0xF1AF, 0x7655, 0xB04D, 0x7656, 0xF1B1, 0x7657, 0xB04E, 0x7658, 0xB04F, 0x7659, 0xB050, 0x765A, 0xB051, - 0x765B, 0xB052, 0x765C, 0xF1B0, 0x765D, 0xB053, 0x765E, 0xF1AE, 0x765F, 0xB054, 0x7660, 0xB055, 0x7661, 0xB056, 0x7662, 0xB057, - 0x7663, 0xD1A2, 0x7664, 0xB058, 0x7665, 0xB059, 0x7666, 0xB05A, 0x7667, 0xB05B, 0x7668, 0xB05C, 0x7669, 0xB05D, 0x766A, 0xB05E, - 0x766B, 0xF1B2, 0x766C, 0xB05F, 0x766D, 0xB060, 0x766E, 0xB061, 0x766F, 0xF1B3, 0x7670, 0xB062, 0x7671, 0xB063, 0x7672, 0xB064, - 0x7673, 0xB065, 0x7674, 0xB066, 0x7675, 0xB067, 0x7676, 0xB068, 0x7677, 0xB069, 0x7678, 0xB9EF, 0x7679, 0xB06A, 0x767A, 0xB06B, - 0x767B, 0xB5C7, 0x767C, 0xB06C, 0x767D, 0xB0D7, 0x767E, 0xB0D9, 0x767F, 0xB06D, 0x7680, 0xB06E, 0x7681, 0xB06F, 0x7682, 0xD4ED, - 0x7683, 0xB070, 0x7684, 0xB5C4, 0x7685, 0xB071, 0x7686, 0xBDD4, 0x7687, 0xBBCA, 0x7688, 0xF0A7, 0x7689, 0xB072, 0x768A, 0xB073, - 0x768B, 0xB8DE, 0x768C, 0xB074, 0x768D, 0xB075, 0x768E, 0xF0A8, 0x768F, 0xB076, 0x7690, 0xB077, 0x7691, 0xB0A8, 0x7692, 0xB078, - 0x7693, 0xF0A9, 0x7694, 0xB079, 0x7695, 0xB07A, 0x7696, 0xCDEE, 0x7697, 0xB07B, 0x7698, 0xB07C, 0x7699, 0xF0AA, 0x769A, 0xB07D, - 0x769B, 0xB07E, 0x769C, 0xB080, 0x769D, 0xB081, 0x769E, 0xB082, 0x769F, 0xB083, 0x76A0, 0xB084, 0x76A1, 0xB085, 0x76A2, 0xB086, - 0x76A3, 0xB087, 0x76A4, 0xF0AB, 0x76A5, 0xB088, 0x76A6, 0xB089, 0x76A7, 0xB08A, 0x76A8, 0xB08B, 0x76A9, 0xB08C, 0x76AA, 0xB08D, - 0x76AB, 0xB08E, 0x76AC, 0xB08F, 0x76AD, 0xB090, 0x76AE, 0xC6A4, 0x76AF, 0xB091, 0x76B0, 0xB092, 0x76B1, 0xD6E5, 0x76B2, 0xF1E4, - 0x76B3, 0xB093, 0x76B4, 0xF1E5, 0x76B5, 0xB094, 0x76B6, 0xB095, 0x76B7, 0xB096, 0x76B8, 0xB097, 0x76B9, 0xB098, 0x76BA, 0xB099, - 0x76BB, 0xB09A, 0x76BC, 0xB09B, 0x76BD, 0xB09C, 0x76BE, 0xB09D, 0x76BF, 0xC3F3, 0x76C0, 0xB09E, 0x76C1, 0xB09F, 0x76C2, 0xD3DB, - 0x76C3, 0xB0A0, 0x76C4, 0xB140, 0x76C5, 0xD6D1, 0x76C6, 0xC5E8, 0x76C7, 0xB141, 0x76C8, 0xD3AF, 0x76C9, 0xB142, 0x76CA, 0xD2E6, - 0x76CB, 0xB143, 0x76CC, 0xB144, 0x76CD, 0xEEC1, 0x76CE, 0xB0BB, 0x76CF, 0xD5B5, 0x76D0, 0xD1CE, 0x76D1, 0xBCE0, 0x76D2, 0xBAD0, - 0x76D3, 0xB145, 0x76D4, 0xBFF8, 0x76D5, 0xB146, 0x76D6, 0xB8C7, 0x76D7, 0xB5C1, 0x76D8, 0xC5CC, 0x76D9, 0xB147, 0x76DA, 0xB148, - 0x76DB, 0xCAA2, 0x76DC, 0xB149, 0x76DD, 0xB14A, 0x76DE, 0xB14B, 0x76DF, 0xC3CB, 0x76E0, 0xB14C, 0x76E1, 0xB14D, 0x76E2, 0xB14E, - 0x76E3, 0xB14F, 0x76E4, 0xB150, 0x76E5, 0xEEC2, 0x76E6, 0xB151, 0x76E7, 0xB152, 0x76E8, 0xB153, 0x76E9, 0xB154, 0x76EA, 0xB155, - 0x76EB, 0xB156, 0x76EC, 0xB157, 0x76ED, 0xB158, 0x76EE, 0xC4BF, 0x76EF, 0xB6A2, 0x76F0, 0xB159, 0x76F1, 0xEDEC, 0x76F2, 0xC3A4, - 0x76F3, 0xB15A, 0x76F4, 0xD6B1, 0x76F5, 0xB15B, 0x76F6, 0xB15C, 0x76F7, 0xB15D, 0x76F8, 0xCFE0, 0x76F9, 0xEDEF, 0x76FA, 0xB15E, - 0x76FB, 0xB15F, 0x76FC, 0xC5CE, 0x76FD, 0xB160, 0x76FE, 0xB6DC, 0x76FF, 0xB161, 0x7700, 0xB162, 0x7701, 0xCAA1, 0x7702, 0xB163, - 0x7703, 0xB164, 0x7704, 0xEDED, 0x7705, 0xB165, 0x7706, 0xB166, 0x7707, 0xEDF0, 0x7708, 0xEDF1, 0x7709, 0xC3BC, 0x770A, 0xB167, - 0x770B, 0xBFB4, 0x770C, 0xB168, 0x770D, 0xEDEE, 0x770E, 0xB169, 0x770F, 0xB16A, 0x7710, 0xB16B, 0x7711, 0xB16C, 0x7712, 0xB16D, - 0x7713, 0xB16E, 0x7714, 0xB16F, 0x7715, 0xB170, 0x7716, 0xB171, 0x7717, 0xB172, 0x7718, 0xB173, 0x7719, 0xEDF4, 0x771A, 0xEDF2, - 0x771B, 0xB174, 0x771C, 0xB175, 0x771D, 0xB176, 0x771E, 0xB177, 0x771F, 0xD5E6, 0x7720, 0xC3DF, 0x7721, 0xB178, 0x7722, 0xEDF3, - 0x7723, 0xB179, 0x7724, 0xB17A, 0x7725, 0xB17B, 0x7726, 0xEDF6, 0x7727, 0xB17C, 0x7728, 0xD5A3, 0x7729, 0xD1A3, 0x772A, 0xB17D, - 0x772B, 0xB17E, 0x772C, 0xB180, 0x772D, 0xEDF5, 0x772E, 0xB181, 0x772F, 0xC3D0, 0x7730, 0xB182, 0x7731, 0xB183, 0x7732, 0xB184, - 0x7733, 0xB185, 0x7734, 0xB186, 0x7735, 0xEDF7, 0x7736, 0xBFF4, 0x7737, 0xBEEC, 0x7738, 0xEDF8, 0x7739, 0xB187, 0x773A, 0xCCF7, - 0x773B, 0xB188, 0x773C, 0xD1DB, 0x773D, 0xB189, 0x773E, 0xB18A, 0x773F, 0xB18B, 0x7740, 0xD7C5, 0x7741, 0xD5F6, 0x7742, 0xB18C, - 0x7743, 0xEDFC, 0x7744, 0xB18D, 0x7745, 0xB18E, 0x7746, 0xB18F, 0x7747, 0xEDFB, 0x7748, 0xB190, 0x7749, 0xB191, 0x774A, 0xB192, - 0x774B, 0xB193, 0x774C, 0xB194, 0x774D, 0xB195, 0x774E, 0xB196, 0x774F, 0xB197, 0x7750, 0xEDF9, 0x7751, 0xEDFA, 0x7752, 0xB198, - 0x7753, 0xB199, 0x7754, 0xB19A, 0x7755, 0xB19B, 0x7756, 0xB19C, 0x7757, 0xB19D, 0x7758, 0xB19E, 0x7759, 0xB19F, 0x775A, 0xEDFD, - 0x775B, 0xBEA6, 0x775C, 0xB1A0, 0x775D, 0xB240, 0x775E, 0xB241, 0x775F, 0xB242, 0x7760, 0xB243, 0x7761, 0xCBAF, 0x7762, 0xEEA1, - 0x7763, 0xB6BD, 0x7764, 0xB244, 0x7765, 0xEEA2, 0x7766, 0xC4C0, 0x7767, 0xB245, 0x7768, 0xEDFE, 0x7769, 0xB246, 0x776A, 0xB247, - 0x776B, 0xBDDE, 0x776C, 0xB2C7, 0x776D, 0xB248, 0x776E, 0xB249, 0x776F, 0xB24A, 0x7770, 0xB24B, 0x7771, 0xB24C, 0x7772, 0xB24D, - 0x7773, 0xB24E, 0x7774, 0xB24F, 0x7775, 0xB250, 0x7776, 0xB251, 0x7777, 0xB252, 0x7778, 0xB253, 0x7779, 0xB6C3, 0x777A, 0xB254, - 0x777B, 0xB255, 0x777C, 0xB256, 0x777D, 0xEEA5, 0x777E, 0xD8BA, 0x777F, 0xEEA3, 0x7780, 0xEEA6, 0x7781, 0xB257, 0x7782, 0xB258, - 0x7783, 0xB259, 0x7784, 0xC3E9, 0x7785, 0xB3F2, 0x7786, 0xB25A, 0x7787, 0xB25B, 0x7788, 0xB25C, 0x7789, 0xB25D, 0x778A, 0xB25E, - 0x778B, 0xB25F, 0x778C, 0xEEA7, 0x778D, 0xEEA4, 0x778E, 0xCFB9, 0x778F, 0xB260, 0x7790, 0xB261, 0x7791, 0xEEA8, 0x7792, 0xC2F7, - 0x7793, 0xB262, 0x7794, 0xB263, 0x7795, 0xB264, 0x7796, 0xB265, 0x7797, 0xB266, 0x7798, 0xB267, 0x7799, 0xB268, 0x779A, 0xB269, - 0x779B, 0xB26A, 0x779C, 0xB26B, 0x779D, 0xB26C, 0x779E, 0xB26D, 0x779F, 0xEEA9, 0x77A0, 0xEEAA, 0x77A1, 0xB26E, 0x77A2, 0xDEAB, - 0x77A3, 0xB26F, 0x77A4, 0xB270, 0x77A5, 0xC6B3, 0x77A6, 0xB271, 0x77A7, 0xC7C6, 0x77A8, 0xB272, 0x77A9, 0xD6F5, 0x77AA, 0xB5C9, - 0x77AB, 0xB273, 0x77AC, 0xCBB2, 0x77AD, 0xB274, 0x77AE, 0xB275, 0x77AF, 0xB276, 0x77B0, 0xEEAB, 0x77B1, 0xB277, 0x77B2, 0xB278, - 0x77B3, 0xCDAB, 0x77B4, 0xB279, 0x77B5, 0xEEAC, 0x77B6, 0xB27A, 0x77B7, 0xB27B, 0x77B8, 0xB27C, 0x77B9, 0xB27D, 0x77BA, 0xB27E, - 0x77BB, 0xD5B0, 0x77BC, 0xB280, 0x77BD, 0xEEAD, 0x77BE, 0xB281, 0x77BF, 0xF6C4, 0x77C0, 0xB282, 0x77C1, 0xB283, 0x77C2, 0xB284, - 0x77C3, 0xB285, 0x77C4, 0xB286, 0x77C5, 0xB287, 0x77C6, 0xB288, 0x77C7, 0xB289, 0x77C8, 0xB28A, 0x77C9, 0xB28B, 0x77CA, 0xB28C, - 0x77CB, 0xB28D, 0x77CC, 0xB28E, 0x77CD, 0xDBC7, 0x77CE, 0xB28F, 0x77CF, 0xB290, 0x77D0, 0xB291, 0x77D1, 0xB292, 0x77D2, 0xB293, - 0x77D3, 0xB294, 0x77D4, 0xB295, 0x77D5, 0xB296, 0x77D6, 0xB297, 0x77D7, 0xB4A3, 0x77D8, 0xB298, 0x77D9, 0xB299, 0x77DA, 0xB29A, - 0x77DB, 0xC3AC, 0x77DC, 0xF1E6, 0x77DD, 0xB29B, 0x77DE, 0xB29C, 0x77DF, 0xB29D, 0x77E0, 0xB29E, 0x77E1, 0xB29F, 0x77E2, 0xCAB8, - 0x77E3, 0xD2D3, 0x77E4, 0xB2A0, 0x77E5, 0xD6AA, 0x77E6, 0xB340, 0x77E7, 0xEFF2, 0x77E8, 0xB341, 0x77E9, 0xBED8, 0x77EA, 0xB342, - 0x77EB, 0xBDC3, 0x77EC, 0xEFF3, 0x77ED, 0xB6CC, 0x77EE, 0xB0AB, 0x77EF, 0xB343, 0x77F0, 0xB344, 0x77F1, 0xB345, 0x77F2, 0xB346, - 0x77F3, 0xCAAF, 0x77F4, 0xB347, 0x77F5, 0xB348, 0x77F6, 0xEDB6, 0x77F7, 0xB349, 0x77F8, 0xEDB7, 0x77F9, 0xB34A, 0x77FA, 0xB34B, - 0x77FB, 0xB34C, 0x77FC, 0xB34D, 0x77FD, 0xCEF9, 0x77FE, 0xB7AF, 0x77FF, 0xBFF3, 0x7800, 0xEDB8, 0x7801, 0xC2EB, 0x7802, 0xC9B0, - 0x7803, 0xB34E, 0x7804, 0xB34F, 0x7805, 0xB350, 0x7806, 0xB351, 0x7807, 0xB352, 0x7808, 0xB353, 0x7809, 0xEDB9, 0x780A, 0xB354, - 0x780B, 0xB355, 0x780C, 0xC6F6, 0x780D, 0xBFB3, 0x780E, 0xB356, 0x780F, 0xB357, 0x7810, 0xB358, 0x7811, 0xEDBC, 0x7812, 0xC5F8, - 0x7813, 0xB359, 0x7814, 0xD1D0, 0x7815, 0xB35A, 0x7816, 0xD7A9, 0x7817, 0xEDBA, 0x7818, 0xEDBB, 0x7819, 0xB35B, 0x781A, 0xD1E2, - 0x781B, 0xB35C, 0x781C, 0xEDBF, 0x781D, 0xEDC0, 0x781E, 0xB35D, 0x781F, 0xEDC4, 0x7820, 0xB35E, 0x7821, 0xB35F, 0x7822, 0xB360, - 0x7823, 0xEDC8, 0x7824, 0xB361, 0x7825, 0xEDC6, 0x7826, 0xEDCE, 0x7827, 0xD5E8, 0x7828, 0xB362, 0x7829, 0xEDC9, 0x782A, 0xB363, - 0x782B, 0xB364, 0x782C, 0xEDC7, 0x782D, 0xEDBE, 0x782E, 0xB365, 0x782F, 0xB366, 0x7830, 0xC5E9, 0x7831, 0xB367, 0x7832, 0xB368, - 0x7833, 0xB369, 0x7834, 0xC6C6, 0x7835, 0xB36A, 0x7836, 0xB36B, 0x7837, 0xC9E9, 0x7838, 0xD4D2, 0x7839, 0xEDC1, 0x783A, 0xEDC2, - 0x783B, 0xEDC3, 0x783C, 0xEDC5, 0x783D, 0xB36C, 0x783E, 0xC0F9, 0x783F, 0xB36D, 0x7840, 0xB4A1, 0x7841, 0xB36E, 0x7842, 0xB36F, - 0x7843, 0xB370, 0x7844, 0xB371, 0x7845, 0xB9E8, 0x7846, 0xB372, 0x7847, 0xEDD0, 0x7848, 0xB373, 0x7849, 0xB374, 0x784A, 0xB375, - 0x784B, 0xB376, 0x784C, 0xEDD1, 0x784D, 0xB377, 0x784E, 0xEDCA, 0x784F, 0xB378, 0x7850, 0xEDCF, 0x7851, 0xB379, 0x7852, 0xCEF8, - 0x7853, 0xB37A, 0x7854, 0xB37B, 0x7855, 0xCBB6, 0x7856, 0xEDCC, 0x7857, 0xEDCD, 0x7858, 0xB37C, 0x7859, 0xB37D, 0x785A, 0xB37E, - 0x785B, 0xB380, 0x785C, 0xB381, 0x785D, 0xCFF5, 0x785E, 0xB382, 0x785F, 0xB383, 0x7860, 0xB384, 0x7861, 0xB385, 0x7862, 0xB386, - 0x7863, 0xB387, 0x7864, 0xB388, 0x7865, 0xB389, 0x7866, 0xB38A, 0x7867, 0xB38B, 0x7868, 0xB38C, 0x7869, 0xB38D, 0x786A, 0xEDD2, - 0x786B, 0xC1F2, 0x786C, 0xD3B2, 0x786D, 0xEDCB, 0x786E, 0xC8B7, 0x786F, 0xB38E, 0x7870, 0xB38F, 0x7871, 0xB390, 0x7872, 0xB391, - 0x7873, 0xB392, 0x7874, 0xB393, 0x7875, 0xB394, 0x7876, 0xB395, 0x7877, 0xBCEF, 0x7878, 0xB396, 0x7879, 0xB397, 0x787A, 0xB398, - 0x787B, 0xB399, 0x787C, 0xC5F0, 0x787D, 0xB39A, 0x787E, 0xB39B, 0x787F, 0xB39C, 0x7880, 0xB39D, 0x7881, 0xB39E, 0x7882, 0xB39F, - 0x7883, 0xB3A0, 0x7884, 0xB440, 0x7885, 0xB441, 0x7886, 0xB442, 0x7887, 0xEDD6, 0x7888, 0xB443, 0x7889, 0xB5EF, 0x788A, 0xB444, - 0x788B, 0xB445, 0x788C, 0xC2B5, 0x788D, 0xB0AD, 0x788E, 0xCBE9, 0x788F, 0xB446, 0x7890, 0xB447, 0x7891, 0xB1AE, 0x7892, 0xB448, - 0x7893, 0xEDD4, 0x7894, 0xB449, 0x7895, 0xB44A, 0x7896, 0xB44B, 0x7897, 0xCDEB, 0x7898, 0xB5E2, 0x7899, 0xB44C, 0x789A, 0xEDD5, - 0x789B, 0xEDD3, 0x789C, 0xEDD7, 0x789D, 0xB44D, 0x789E, 0xB44E, 0x789F, 0xB5FA, 0x78A0, 0xB44F, 0x78A1, 0xEDD8, 0x78A2, 0xB450, - 0x78A3, 0xEDD9, 0x78A4, 0xB451, 0x78A5, 0xEDDC, 0x78A6, 0xB452, 0x78A7, 0xB1CC, 0x78A8, 0xB453, 0x78A9, 0xB454, 0x78AA, 0xB455, - 0x78AB, 0xB456, 0x78AC, 0xB457, 0x78AD, 0xB458, 0x78AE, 0xB459, 0x78AF, 0xB45A, 0x78B0, 0xC5F6, 0x78B1, 0xBCEE, 0x78B2, 0xEDDA, - 0x78B3, 0xCCBC, 0x78B4, 0xB2EA, 0x78B5, 0xB45B, 0x78B6, 0xB45C, 0x78B7, 0xB45D, 0x78B8, 0xB45E, 0x78B9, 0xEDDB, 0x78BA, 0xB45F, - 0x78BB, 0xB460, 0x78BC, 0xB461, 0x78BD, 0xB462, 0x78BE, 0xC4EB, 0x78BF, 0xB463, 0x78C0, 0xB464, 0x78C1, 0xB4C5, 0x78C2, 0xB465, - 0x78C3, 0xB466, 0x78C4, 0xB467, 0x78C5, 0xB0F5, 0x78C6, 0xB468, 0x78C7, 0xB469, 0x78C8, 0xB46A, 0x78C9, 0xEDDF, 0x78CA, 0xC0DA, - 0x78CB, 0xB4E8, 0x78CC, 0xB46B, 0x78CD, 0xB46C, 0x78CE, 0xB46D, 0x78CF, 0xB46E, 0x78D0, 0xC5CD, 0x78D1, 0xB46F, 0x78D2, 0xB470, - 0x78D3, 0xB471, 0x78D4, 0xEDDD, 0x78D5, 0xBFC4, 0x78D6, 0xB472, 0x78D7, 0xB473, 0x78D8, 0xB474, 0x78D9, 0xEDDE, 0x78DA, 0xB475, - 0x78DB, 0xB476, 0x78DC, 0xB477, 0x78DD, 0xB478, 0x78DE, 0xB479, 0x78DF, 0xB47A, 0x78E0, 0xB47B, 0x78E1, 0xB47C, 0x78E2, 0xB47D, - 0x78E3, 0xB47E, 0x78E4, 0xB480, 0x78E5, 0xB481, 0x78E6, 0xB482, 0x78E7, 0xB483, 0x78E8, 0xC4A5, 0x78E9, 0xB484, 0x78EA, 0xB485, - 0x78EB, 0xB486, 0x78EC, 0xEDE0, 0x78ED, 0xB487, 0x78EE, 0xB488, 0x78EF, 0xB489, 0x78F0, 0xB48A, 0x78F1, 0xB48B, 0x78F2, 0xEDE1, - 0x78F3, 0xB48C, 0x78F4, 0xEDE3, 0x78F5, 0xB48D, 0x78F6, 0xB48E, 0x78F7, 0xC1D7, 0x78F8, 0xB48F, 0x78F9, 0xB490, 0x78FA, 0xBBC7, - 0x78FB, 0xB491, 0x78FC, 0xB492, 0x78FD, 0xB493, 0x78FE, 0xB494, 0x78FF, 0xB495, 0x7900, 0xB496, 0x7901, 0xBDB8, 0x7902, 0xB497, - 0x7903, 0xB498, 0x7904, 0xB499, 0x7905, 0xEDE2, 0x7906, 0xB49A, 0x7907, 0xB49B, 0x7908, 0xB49C, 0x7909, 0xB49D, 0x790A, 0xB49E, - 0x790B, 0xB49F, 0x790C, 0xB4A0, 0x790D, 0xB540, 0x790E, 0xB541, 0x790F, 0xB542, 0x7910, 0xB543, 0x7911, 0xB544, 0x7912, 0xB545, - 0x7913, 0xEDE4, 0x7914, 0xB546, 0x7915, 0xB547, 0x7916, 0xB548, 0x7917, 0xB549, 0x7918, 0xB54A, 0x7919, 0xB54B, 0x791A, 0xB54C, - 0x791B, 0xB54D, 0x791C, 0xB54E, 0x791D, 0xB54F, 0x791E, 0xEDE6, 0x791F, 0xB550, 0x7920, 0xB551, 0x7921, 0xB552, 0x7922, 0xB553, - 0x7923, 0xB554, 0x7924, 0xEDE5, 0x7925, 0xB555, 0x7926, 0xB556, 0x7927, 0xB557, 0x7928, 0xB558, 0x7929, 0xB559, 0x792A, 0xB55A, - 0x792B, 0xB55B, 0x792C, 0xB55C, 0x792D, 0xB55D, 0x792E, 0xB55E, 0x792F, 0xB55F, 0x7930, 0xB560, 0x7931, 0xB561, 0x7932, 0xB562, - 0x7933, 0xB563, 0x7934, 0xEDE7, 0x7935, 0xB564, 0x7936, 0xB565, 0x7937, 0xB566, 0x7938, 0xB567, 0x7939, 0xB568, 0x793A, 0xCABE, - 0x793B, 0xECEA, 0x793C, 0xC0F1, 0x793D, 0xB569, 0x793E, 0xC9E7, 0x793F, 0xB56A, 0x7940, 0xECEB, 0x7941, 0xC6EE, 0x7942, 0xB56B, - 0x7943, 0xB56C, 0x7944, 0xB56D, 0x7945, 0xB56E, 0x7946, 0xECEC, 0x7947, 0xB56F, 0x7948, 0xC6ED, 0x7949, 0xECED, 0x794A, 0xB570, - 0x794B, 0xB571, 0x794C, 0xB572, 0x794D, 0xB573, 0x794E, 0xB574, 0x794F, 0xB575, 0x7950, 0xB576, 0x7951, 0xB577, 0x7952, 0xB578, - 0x7953, 0xECF0, 0x7954, 0xB579, 0x7955, 0xB57A, 0x7956, 0xD7E6, 0x7957, 0xECF3, 0x7958, 0xB57B, 0x7959, 0xB57C, 0x795A, 0xECF1, - 0x795B, 0xECEE, 0x795C, 0xECEF, 0x795D, 0xD7A3, 0x795E, 0xC9F1, 0x795F, 0xCBEE, 0x7960, 0xECF4, 0x7961, 0xB57D, 0x7962, 0xECF2, - 0x7963, 0xB57E, 0x7964, 0xB580, 0x7965, 0xCFE9, 0x7966, 0xB581, 0x7967, 0xECF6, 0x7968, 0xC6B1, 0x7969, 0xB582, 0x796A, 0xB583, - 0x796B, 0xB584, 0x796C, 0xB585, 0x796D, 0xBCC0, 0x796E, 0xB586, 0x796F, 0xECF5, 0x7970, 0xB587, 0x7971, 0xB588, 0x7972, 0xB589, - 0x7973, 0xB58A, 0x7974, 0xB58B, 0x7975, 0xB58C, 0x7976, 0xB58D, 0x7977, 0xB5BB, 0x7978, 0xBBF6, 0x7979, 0xB58E, 0x797A, 0xECF7, - 0x797B, 0xB58F, 0x797C, 0xB590, 0x797D, 0xB591, 0x797E, 0xB592, 0x797F, 0xB593, 0x7980, 0xD9F7, 0x7981, 0xBDFB, 0x7982, 0xB594, - 0x7983, 0xB595, 0x7984, 0xC2BB, 0x7985, 0xECF8, 0x7986, 0xB596, 0x7987, 0xB597, 0x7988, 0xB598, 0x7989, 0xB599, 0x798A, 0xECF9, - 0x798B, 0xB59A, 0x798C, 0xB59B, 0x798D, 0xB59C, 0x798E, 0xB59D, 0x798F, 0xB8A3, 0x7990, 0xB59E, 0x7991, 0xB59F, 0x7992, 0xB5A0, - 0x7993, 0xB640, 0x7994, 0xB641, 0x7995, 0xB642, 0x7996, 0xB643, 0x7997, 0xB644, 0x7998, 0xB645, 0x7999, 0xB646, 0x799A, 0xECFA, - 0x799B, 0xB647, 0x799C, 0xB648, 0x799D, 0xB649, 0x799E, 0xB64A, 0x799F, 0xB64B, 0x79A0, 0xB64C, 0x79A1, 0xB64D, 0x79A2, 0xB64E, - 0x79A3, 0xB64F, 0x79A4, 0xB650, 0x79A5, 0xB651, 0x79A6, 0xB652, 0x79A7, 0xECFB, 0x79A8, 0xB653, 0x79A9, 0xB654, 0x79AA, 0xB655, - 0x79AB, 0xB656, 0x79AC, 0xB657, 0x79AD, 0xB658, 0x79AE, 0xB659, 0x79AF, 0xB65A, 0x79B0, 0xB65B, 0x79B1, 0xB65C, 0x79B2, 0xB65D, - 0x79B3, 0xECFC, 0x79B4, 0xB65E, 0x79B5, 0xB65F, 0x79B6, 0xB660, 0x79B7, 0xB661, 0x79B8, 0xB662, 0x79B9, 0xD3ED, 0x79BA, 0xD8AE, - 0x79BB, 0xC0EB, 0x79BC, 0xB663, 0x79BD, 0xC7DD, 0x79BE, 0xBACC, 0x79BF, 0xB664, 0x79C0, 0xD0E3, 0x79C1, 0xCBBD, 0x79C2, 0xB665, - 0x79C3, 0xCDBA, 0x79C4, 0xB666, 0x79C5, 0xB667, 0x79C6, 0xB8D1, 0x79C7, 0xB668, 0x79C8, 0xB669, 0x79C9, 0xB1FC, 0x79CA, 0xB66A, - 0x79CB, 0xC7EF, 0x79CC, 0xB66B, 0x79CD, 0xD6D6, 0x79CE, 0xB66C, 0x79CF, 0xB66D, 0x79D0, 0xB66E, 0x79D1, 0xBFC6, 0x79D2, 0xC3EB, - 0x79D3, 0xB66F, 0x79D4, 0xB670, 0x79D5, 0xEFF5, 0x79D6, 0xB671, 0x79D7, 0xB672, 0x79D8, 0xC3D8, 0x79D9, 0xB673, 0x79DA, 0xB674, - 0x79DB, 0xB675, 0x79DC, 0xB676, 0x79DD, 0xB677, 0x79DE, 0xB678, 0x79DF, 0xD7E2, 0x79E0, 0xB679, 0x79E1, 0xB67A, 0x79E2, 0xB67B, - 0x79E3, 0xEFF7, 0x79E4, 0xB3D3, 0x79E5, 0xB67C, 0x79E6, 0xC7D8, 0x79E7, 0xD1ED, 0x79E8, 0xB67D, 0x79E9, 0xD6C8, 0x79EA, 0xB67E, - 0x79EB, 0xEFF8, 0x79EC, 0xB680, 0x79ED, 0xEFF6, 0x79EE, 0xB681, 0x79EF, 0xBBFD, 0x79F0, 0xB3C6, 0x79F1, 0xB682, 0x79F2, 0xB683, - 0x79F3, 0xB684, 0x79F4, 0xB685, 0x79F5, 0xB686, 0x79F6, 0xB687, 0x79F7, 0xB688, 0x79F8, 0xBDD5, 0x79F9, 0xB689, 0x79FA, 0xB68A, - 0x79FB, 0xD2C6, 0x79FC, 0xB68B, 0x79FD, 0xBBE0, 0x79FE, 0xB68C, 0x79FF, 0xB68D, 0x7A00, 0xCFA1, 0x7A01, 0xB68E, 0x7A02, 0xEFFC, - 0x7A03, 0xEFFB, 0x7A04, 0xB68F, 0x7A05, 0xB690, 0x7A06, 0xEFF9, 0x7A07, 0xB691, 0x7A08, 0xB692, 0x7A09, 0xB693, 0x7A0A, 0xB694, - 0x7A0B, 0xB3CC, 0x7A0C, 0xB695, 0x7A0D, 0xC9D4, 0x7A0E, 0xCBB0, 0x7A0F, 0xB696, 0x7A10, 0xB697, 0x7A11, 0xB698, 0x7A12, 0xB699, - 0x7A13, 0xB69A, 0x7A14, 0xEFFE, 0x7A15, 0xB69B, 0x7A16, 0xB69C, 0x7A17, 0xB0DE, 0x7A18, 0xB69D, 0x7A19, 0xB69E, 0x7A1A, 0xD6C9, - 0x7A1B, 0xB69F, 0x7A1C, 0xB6A0, 0x7A1D, 0xB740, 0x7A1E, 0xEFFD, 0x7A1F, 0xB741, 0x7A20, 0xB3ED, 0x7A21, 0xB742, 0x7A22, 0xB743, - 0x7A23, 0xF6D5, 0x7A24, 0xB744, 0x7A25, 0xB745, 0x7A26, 0xB746, 0x7A27, 0xB747, 0x7A28, 0xB748, 0x7A29, 0xB749, 0x7A2A, 0xB74A, - 0x7A2B, 0xB74B, 0x7A2C, 0xB74C, 0x7A2D, 0xB74D, 0x7A2E, 0xB74E, 0x7A2F, 0xB74F, 0x7A30, 0xB750, 0x7A31, 0xB751, 0x7A32, 0xB752, - 0x7A33, 0xCEC8, 0x7A34, 0xB753, 0x7A35, 0xB754, 0x7A36, 0xB755, 0x7A37, 0xF0A2, 0x7A38, 0xB756, 0x7A39, 0xF0A1, 0x7A3A, 0xB757, - 0x7A3B, 0xB5BE, 0x7A3C, 0xBCDA, 0x7A3D, 0xBBFC, 0x7A3E, 0xB758, 0x7A3F, 0xB8E5, 0x7A40, 0xB759, 0x7A41, 0xB75A, 0x7A42, 0xB75B, - 0x7A43, 0xB75C, 0x7A44, 0xB75D, 0x7A45, 0xB75E, 0x7A46, 0xC4C2, 0x7A47, 0xB75F, 0x7A48, 0xB760, 0x7A49, 0xB761, 0x7A4A, 0xB762, - 0x7A4B, 0xB763, 0x7A4C, 0xB764, 0x7A4D, 0xB765, 0x7A4E, 0xB766, 0x7A4F, 0xB767, 0x7A50, 0xB768, 0x7A51, 0xF0A3, 0x7A52, 0xB769, - 0x7A53, 0xB76A, 0x7A54, 0xB76B, 0x7A55, 0xB76C, 0x7A56, 0xB76D, 0x7A57, 0xCBEB, 0x7A58, 0xB76E, 0x7A59, 0xB76F, 0x7A5A, 0xB770, - 0x7A5B, 0xB771, 0x7A5C, 0xB772, 0x7A5D, 0xB773, 0x7A5E, 0xB774, 0x7A5F, 0xB775, 0x7A60, 0xB776, 0x7A61, 0xB777, 0x7A62, 0xB778, - 0x7A63, 0xB779, 0x7A64, 0xB77A, 0x7A65, 0xB77B, 0x7A66, 0xB77C, 0x7A67, 0xB77D, 0x7A68, 0xB77E, 0x7A69, 0xB780, 0x7A6A, 0xB781, - 0x7A6B, 0xB782, 0x7A6C, 0xB783, 0x7A6D, 0xB784, 0x7A6E, 0xB785, 0x7A6F, 0xB786, 0x7A70, 0xF0A6, 0x7A71, 0xB787, 0x7A72, 0xB788, - 0x7A73, 0xB789, 0x7A74, 0xD1A8, 0x7A75, 0xB78A, 0x7A76, 0xBEBF, 0x7A77, 0xC7EE, 0x7A78, 0xF1B6, 0x7A79, 0xF1B7, 0x7A7A, 0xBFD5, - 0x7A7B, 0xB78B, 0x7A7C, 0xB78C, 0x7A7D, 0xB78D, 0x7A7E, 0xB78E, 0x7A7F, 0xB4A9, 0x7A80, 0xF1B8, 0x7A81, 0xCDBB, 0x7A82, 0xB78F, - 0x7A83, 0xC7D4, 0x7A84, 0xD5AD, 0x7A85, 0xB790, 0x7A86, 0xF1B9, 0x7A87, 0xB791, 0x7A88, 0xF1BA, 0x7A89, 0xB792, 0x7A8A, 0xB793, - 0x7A8B, 0xB794, 0x7A8C, 0xB795, 0x7A8D, 0xC7CF, 0x7A8E, 0xB796, 0x7A8F, 0xB797, 0x7A90, 0xB798, 0x7A91, 0xD2A4, 0x7A92, 0xD6CF, - 0x7A93, 0xB799, 0x7A94, 0xB79A, 0x7A95, 0xF1BB, 0x7A96, 0xBDD1, 0x7A97, 0xB4B0, 0x7A98, 0xBEBD, 0x7A99, 0xB79B, 0x7A9A, 0xB79C, - 0x7A9B, 0xB79D, 0x7A9C, 0xB4DC, 0x7A9D, 0xCED1, 0x7A9E, 0xB79E, 0x7A9F, 0xBFDF, 0x7AA0, 0xF1BD, 0x7AA1, 0xB79F, 0x7AA2, 0xB7A0, - 0x7AA3, 0xB840, 0x7AA4, 0xB841, 0x7AA5, 0xBFFA, 0x7AA6, 0xF1BC, 0x7AA7, 0xB842, 0x7AA8, 0xF1BF, 0x7AA9, 0xB843, 0x7AAA, 0xB844, - 0x7AAB, 0xB845, 0x7AAC, 0xF1BE, 0x7AAD, 0xF1C0, 0x7AAE, 0xB846, 0x7AAF, 0xB847, 0x7AB0, 0xB848, 0x7AB1, 0xB849, 0x7AB2, 0xB84A, - 0x7AB3, 0xF1C1, 0x7AB4, 0xB84B, 0x7AB5, 0xB84C, 0x7AB6, 0xB84D, 0x7AB7, 0xB84E, 0x7AB8, 0xB84F, 0x7AB9, 0xB850, 0x7ABA, 0xB851, - 0x7ABB, 0xB852, 0x7ABC, 0xB853, 0x7ABD, 0xB854, 0x7ABE, 0xB855, 0x7ABF, 0xC1FE, 0x7AC0, 0xB856, 0x7AC1, 0xB857, 0x7AC2, 0xB858, - 0x7AC3, 0xB859, 0x7AC4, 0xB85A, 0x7AC5, 0xB85B, 0x7AC6, 0xB85C, 0x7AC7, 0xB85D, 0x7AC8, 0xB85E, 0x7AC9, 0xB85F, 0x7ACA, 0xB860, - 0x7ACB, 0xC1A2, 0x7ACC, 0xB861, 0x7ACD, 0xB862, 0x7ACE, 0xB863, 0x7ACF, 0xB864, 0x7AD0, 0xB865, 0x7AD1, 0xB866, 0x7AD2, 0xB867, - 0x7AD3, 0xB868, 0x7AD4, 0xB869, 0x7AD5, 0xB86A, 0x7AD6, 0xCAFA, 0x7AD7, 0xB86B, 0x7AD8, 0xB86C, 0x7AD9, 0xD5BE, 0x7ADA, 0xB86D, - 0x7ADB, 0xB86E, 0x7ADC, 0xB86F, 0x7ADD, 0xB870, 0x7ADE, 0xBEBA, 0x7ADF, 0xBEB9, 0x7AE0, 0xD5C2, 0x7AE1, 0xB871, 0x7AE2, 0xB872, - 0x7AE3, 0xBFA2, 0x7AE4, 0xB873, 0x7AE5, 0xCDAF, 0x7AE6, 0xF1B5, 0x7AE7, 0xB874, 0x7AE8, 0xB875, 0x7AE9, 0xB876, 0x7AEA, 0xB877, - 0x7AEB, 0xB878, 0x7AEC, 0xB879, 0x7AED, 0xBDDF, 0x7AEE, 0xB87A, 0x7AEF, 0xB6CB, 0x7AF0, 0xB87B, 0x7AF1, 0xB87C, 0x7AF2, 0xB87D, - 0x7AF3, 0xB87E, 0x7AF4, 0xB880, 0x7AF5, 0xB881, 0x7AF6, 0xB882, 0x7AF7, 0xB883, 0x7AF8, 0xB884, 0x7AF9, 0xD6F1, 0x7AFA, 0xF3C3, - 0x7AFB, 0xB885, 0x7AFC, 0xB886, 0x7AFD, 0xF3C4, 0x7AFE, 0xB887, 0x7AFF, 0xB8CD, 0x7B00, 0xB888, 0x7B01, 0xB889, 0x7B02, 0xB88A, - 0x7B03, 0xF3C6, 0x7B04, 0xF3C7, 0x7B05, 0xB88B, 0x7B06, 0xB0CA, 0x7B07, 0xB88C, 0x7B08, 0xF3C5, 0x7B09, 0xB88D, 0x7B0A, 0xF3C9, - 0x7B0B, 0xCBF1, 0x7B0C, 0xB88E, 0x7B0D, 0xB88F, 0x7B0E, 0xB890, 0x7B0F, 0xF3CB, 0x7B10, 0xB891, 0x7B11, 0xD0A6, 0x7B12, 0xB892, - 0x7B13, 0xB893, 0x7B14, 0xB1CA, 0x7B15, 0xF3C8, 0x7B16, 0xB894, 0x7B17, 0xB895, 0x7B18, 0xB896, 0x7B19, 0xF3CF, 0x7B1A, 0xB897, - 0x7B1B, 0xB5D1, 0x7B1C, 0xB898, 0x7B1D, 0xB899, 0x7B1E, 0xF3D7, 0x7B1F, 0xB89A, 0x7B20, 0xF3D2, 0x7B21, 0xB89B, 0x7B22, 0xB89C, - 0x7B23, 0xB89D, 0x7B24, 0xF3D4, 0x7B25, 0xF3D3, 0x7B26, 0xB7FB, 0x7B27, 0xB89E, 0x7B28, 0xB1BF, 0x7B29, 0xB89F, 0x7B2A, 0xF3CE, - 0x7B2B, 0xF3CA, 0x7B2C, 0xB5DA, 0x7B2D, 0xB8A0, 0x7B2E, 0xF3D0, 0x7B2F, 0xB940, 0x7B30, 0xB941, 0x7B31, 0xF3D1, 0x7B32, 0xB942, - 0x7B33, 0xF3D5, 0x7B34, 0xB943, 0x7B35, 0xB944, 0x7B36, 0xB945, 0x7B37, 0xB946, 0x7B38, 0xF3CD, 0x7B39, 0xB947, 0x7B3A, 0xBCE3, - 0x7B3B, 0xB948, 0x7B3C, 0xC1FD, 0x7B3D, 0xB949, 0x7B3E, 0xF3D6, 0x7B3F, 0xB94A, 0x7B40, 0xB94B, 0x7B41, 0xB94C, 0x7B42, 0xB94D, - 0x7B43, 0xB94E, 0x7B44, 0xB94F, 0x7B45, 0xF3DA, 0x7B46, 0xB950, 0x7B47, 0xF3CC, 0x7B48, 0xB951, 0x7B49, 0xB5C8, 0x7B4A, 0xB952, - 0x7B4B, 0xBDEE, 0x7B4C, 0xF3DC, 0x7B4D, 0xB953, 0x7B4E, 0xB954, 0x7B4F, 0xB7A4, 0x7B50, 0xBFF0, 0x7B51, 0xD6FE, 0x7B52, 0xCDB2, - 0x7B53, 0xB955, 0x7B54, 0xB4F0, 0x7B55, 0xB956, 0x7B56, 0xB2DF, 0x7B57, 0xB957, 0x7B58, 0xF3D8, 0x7B59, 0xB958, 0x7B5A, 0xF3D9, - 0x7B5B, 0xC9B8, 0x7B5C, 0xB959, 0x7B5D, 0xF3DD, 0x7B5E, 0xB95A, 0x7B5F, 0xB95B, 0x7B60, 0xF3DE, 0x7B61, 0xB95C, 0x7B62, 0xF3E1, - 0x7B63, 0xB95D, 0x7B64, 0xB95E, 0x7B65, 0xB95F, 0x7B66, 0xB960, 0x7B67, 0xB961, 0x7B68, 0xB962, 0x7B69, 0xB963, 0x7B6A, 0xB964, - 0x7B6B, 0xB965, 0x7B6C, 0xB966, 0x7B6D, 0xB967, 0x7B6E, 0xF3DF, 0x7B6F, 0xB968, 0x7B70, 0xB969, 0x7B71, 0xF3E3, 0x7B72, 0xF3E2, - 0x7B73, 0xB96A, 0x7B74, 0xB96B, 0x7B75, 0xF3DB, 0x7B76, 0xB96C, 0x7B77, 0xBFEA, 0x7B78, 0xB96D, 0x7B79, 0xB3EF, 0x7B7A, 0xB96E, - 0x7B7B, 0xF3E0, 0x7B7C, 0xB96F, 0x7B7D, 0xB970, 0x7B7E, 0xC7A9, 0x7B7F, 0xB971, 0x7B80, 0xBCF2, 0x7B81, 0xB972, 0x7B82, 0xB973, - 0x7B83, 0xB974, 0x7B84, 0xB975, 0x7B85, 0xF3EB, 0x7B86, 0xB976, 0x7B87, 0xB977, 0x7B88, 0xB978, 0x7B89, 0xB979, 0x7B8A, 0xB97A, - 0x7B8B, 0xB97B, 0x7B8C, 0xB97C, 0x7B8D, 0xB9BF, 0x7B8E, 0xB97D, 0x7B8F, 0xB97E, 0x7B90, 0xF3E4, 0x7B91, 0xB980, 0x7B92, 0xB981, - 0x7B93, 0xB982, 0x7B94, 0xB2AD, 0x7B95, 0xBBFE, 0x7B96, 0xB983, 0x7B97, 0xCBE3, 0x7B98, 0xB984, 0x7B99, 0xB985, 0x7B9A, 0xB986, - 0x7B9B, 0xB987, 0x7B9C, 0xF3ED, 0x7B9D, 0xF3E9, 0x7B9E, 0xB988, 0x7B9F, 0xB989, 0x7BA0, 0xB98A, 0x7BA1, 0xB9DC, 0x7BA2, 0xF3EE, - 0x7BA3, 0xB98B, 0x7BA4, 0xB98C, 0x7BA5, 0xB98D, 0x7BA6, 0xF3E5, 0x7BA7, 0xF3E6, 0x7BA8, 0xF3EA, 0x7BA9, 0xC2E1, 0x7BAA, 0xF3EC, - 0x7BAB, 0xF3EF, 0x7BAC, 0xF3E8, 0x7BAD, 0xBCFD, 0x7BAE, 0xB98E, 0x7BAF, 0xB98F, 0x7BB0, 0xB990, 0x7BB1, 0xCFE4, 0x7BB2, 0xB991, - 0x7BB3, 0xB992, 0x7BB4, 0xF3F0, 0x7BB5, 0xB993, 0x7BB6, 0xB994, 0x7BB7, 0xB995, 0x7BB8, 0xF3E7, 0x7BB9, 0xB996, 0x7BBA, 0xB997, - 0x7BBB, 0xB998, 0x7BBC, 0xB999, 0x7BBD, 0xB99A, 0x7BBE, 0xB99B, 0x7BBF, 0xB99C, 0x7BC0, 0xB99D, 0x7BC1, 0xF3F2, 0x7BC2, 0xB99E, - 0x7BC3, 0xB99F, 0x7BC4, 0xB9A0, 0x7BC5, 0xBA40, 0x7BC6, 0xD7AD, 0x7BC7, 0xC6AA, 0x7BC8, 0xBA41, 0x7BC9, 0xBA42, 0x7BCA, 0xBA43, - 0x7BCB, 0xBA44, 0x7BCC, 0xF3F3, 0x7BCD, 0xBA45, 0x7BCE, 0xBA46, 0x7BCF, 0xBA47, 0x7BD0, 0xBA48, 0x7BD1, 0xF3F1, 0x7BD2, 0xBA49, - 0x7BD3, 0xC2A8, 0x7BD4, 0xBA4A, 0x7BD5, 0xBA4B, 0x7BD6, 0xBA4C, 0x7BD7, 0xBA4D, 0x7BD8, 0xBA4E, 0x7BD9, 0xB8DD, 0x7BDA, 0xF3F5, - 0x7BDB, 0xBA4F, 0x7BDC, 0xBA50, 0x7BDD, 0xF3F4, 0x7BDE, 0xBA51, 0x7BDF, 0xBA52, 0x7BE0, 0xBA53, 0x7BE1, 0xB4DB, 0x7BE2, 0xBA54, - 0x7BE3, 0xBA55, 0x7BE4, 0xBA56, 0x7BE5, 0xF3F6, 0x7BE6, 0xF3F7, 0x7BE7, 0xBA57, 0x7BE8, 0xBA58, 0x7BE9, 0xBA59, 0x7BEA, 0xF3F8, - 0x7BEB, 0xBA5A, 0x7BEC, 0xBA5B, 0x7BED, 0xBA5C, 0x7BEE, 0xC0BA, 0x7BEF, 0xBA5D, 0x7BF0, 0xBA5E, 0x7BF1, 0xC0E9, 0x7BF2, 0xBA5F, - 0x7BF3, 0xBA60, 0x7BF4, 0xBA61, 0x7BF5, 0xBA62, 0x7BF6, 0xBA63, 0x7BF7, 0xC5F1, 0x7BF8, 0xBA64, 0x7BF9, 0xBA65, 0x7BFA, 0xBA66, - 0x7BFB, 0xBA67, 0x7BFC, 0xF3FB, 0x7BFD, 0xBA68, 0x7BFE, 0xF3FA, 0x7BFF, 0xBA69, 0x7C00, 0xBA6A, 0x7C01, 0xBA6B, 0x7C02, 0xBA6C, - 0x7C03, 0xBA6D, 0x7C04, 0xBA6E, 0x7C05, 0xBA6F, 0x7C06, 0xBA70, 0x7C07, 0xB4D8, 0x7C08, 0xBA71, 0x7C09, 0xBA72, 0x7C0A, 0xBA73, - 0x7C0B, 0xF3FE, 0x7C0C, 0xF3F9, 0x7C0D, 0xBA74, 0x7C0E, 0xBA75, 0x7C0F, 0xF3FC, 0x7C10, 0xBA76, 0x7C11, 0xBA77, 0x7C12, 0xBA78, - 0x7C13, 0xBA79, 0x7C14, 0xBA7A, 0x7C15, 0xBA7B, 0x7C16, 0xF3FD, 0x7C17, 0xBA7C, 0x7C18, 0xBA7D, 0x7C19, 0xBA7E, 0x7C1A, 0xBA80, - 0x7C1B, 0xBA81, 0x7C1C, 0xBA82, 0x7C1D, 0xBA83, 0x7C1E, 0xBA84, 0x7C1F, 0xF4A1, 0x7C20, 0xBA85, 0x7C21, 0xBA86, 0x7C22, 0xBA87, - 0x7C23, 0xBA88, 0x7C24, 0xBA89, 0x7C25, 0xBA8A, 0x7C26, 0xF4A3, 0x7C27, 0xBBC9, 0x7C28, 0xBA8B, 0x7C29, 0xBA8C, 0x7C2A, 0xF4A2, - 0x7C2B, 0xBA8D, 0x7C2C, 0xBA8E, 0x7C2D, 0xBA8F, 0x7C2E, 0xBA90, 0x7C2F, 0xBA91, 0x7C30, 0xBA92, 0x7C31, 0xBA93, 0x7C32, 0xBA94, - 0x7C33, 0xBA95, 0x7C34, 0xBA96, 0x7C35, 0xBA97, 0x7C36, 0xBA98, 0x7C37, 0xBA99, 0x7C38, 0xF4A4, 0x7C39, 0xBA9A, 0x7C3A, 0xBA9B, - 0x7C3B, 0xBA9C, 0x7C3C, 0xBA9D, 0x7C3D, 0xBA9E, 0x7C3E, 0xBA9F, 0x7C3F, 0xB2BE, 0x7C40, 0xF4A6, 0x7C41, 0xF4A5, 0x7C42, 0xBAA0, - 0x7C43, 0xBB40, 0x7C44, 0xBB41, 0x7C45, 0xBB42, 0x7C46, 0xBB43, 0x7C47, 0xBB44, 0x7C48, 0xBB45, 0x7C49, 0xBB46, 0x7C4A, 0xBB47, - 0x7C4B, 0xBB48, 0x7C4C, 0xBB49, 0x7C4D, 0xBCAE, 0x7C4E, 0xBB4A, 0x7C4F, 0xBB4B, 0x7C50, 0xBB4C, 0x7C51, 0xBB4D, 0x7C52, 0xBB4E, - 0x7C53, 0xBB4F, 0x7C54, 0xBB50, 0x7C55, 0xBB51, 0x7C56, 0xBB52, 0x7C57, 0xBB53, 0x7C58, 0xBB54, 0x7C59, 0xBB55, 0x7C5A, 0xBB56, - 0x7C5B, 0xBB57, 0x7C5C, 0xBB58, 0x7C5D, 0xBB59, 0x7C5E, 0xBB5A, 0x7C5F, 0xBB5B, 0x7C60, 0xBB5C, 0x7C61, 0xBB5D, 0x7C62, 0xBB5E, - 0x7C63, 0xBB5F, 0x7C64, 0xBB60, 0x7C65, 0xBB61, 0x7C66, 0xBB62, 0x7C67, 0xBB63, 0x7C68, 0xBB64, 0x7C69, 0xBB65, 0x7C6A, 0xBB66, - 0x7C6B, 0xBB67, 0x7C6C, 0xBB68, 0x7C6D, 0xBB69, 0x7C6E, 0xBB6A, 0x7C6F, 0xBB6B, 0x7C70, 0xBB6C, 0x7C71, 0xBB6D, 0x7C72, 0xBB6E, - 0x7C73, 0xC3D7, 0x7C74, 0xD9E1, 0x7C75, 0xBB6F, 0x7C76, 0xBB70, 0x7C77, 0xBB71, 0x7C78, 0xBB72, 0x7C79, 0xBB73, 0x7C7A, 0xBB74, - 0x7C7B, 0xC0E0, 0x7C7C, 0xF4CC, 0x7C7D, 0xD7D1, 0x7C7E, 0xBB75, 0x7C7F, 0xBB76, 0x7C80, 0xBB77, 0x7C81, 0xBB78, 0x7C82, 0xBB79, - 0x7C83, 0xBB7A, 0x7C84, 0xBB7B, 0x7C85, 0xBB7C, 0x7C86, 0xBB7D, 0x7C87, 0xBB7E, 0x7C88, 0xBB80, 0x7C89, 0xB7DB, 0x7C8A, 0xBB81, - 0x7C8B, 0xBB82, 0x7C8C, 0xBB83, 0x7C8D, 0xBB84, 0x7C8E, 0xBB85, 0x7C8F, 0xBB86, 0x7C90, 0xBB87, 0x7C91, 0xF4CE, 0x7C92, 0xC1A3, - 0x7C93, 0xBB88, 0x7C94, 0xBB89, 0x7C95, 0xC6C9, 0x7C96, 0xBB8A, 0x7C97, 0xB4D6, 0x7C98, 0xD5B3, 0x7C99, 0xBB8B, 0x7C9A, 0xBB8C, - 0x7C9B, 0xBB8D, 0x7C9C, 0xF4D0, 0x7C9D, 0xF4CF, 0x7C9E, 0xF4D1, 0x7C9F, 0xCBDA, 0x7CA0, 0xBB8E, 0x7CA1, 0xBB8F, 0x7CA2, 0xF4D2, - 0x7CA3, 0xBB90, 0x7CA4, 0xD4C1, 0x7CA5, 0xD6E0, 0x7CA6, 0xBB91, 0x7CA7, 0xBB92, 0x7CA8, 0xBB93, 0x7CA9, 0xBB94, 0x7CAA, 0xB7E0, - 0x7CAB, 0xBB95, 0x7CAC, 0xBB96, 0x7CAD, 0xBB97, 0x7CAE, 0xC1B8, 0x7CAF, 0xBB98, 0x7CB0, 0xBB99, 0x7CB1, 0xC1BB, 0x7CB2, 0xF4D3, - 0x7CB3, 0xBEAC, 0x7CB4, 0xBB9A, 0x7CB5, 0xBB9B, 0x7CB6, 0xBB9C, 0x7CB7, 0xBB9D, 0x7CB8, 0xBB9E, 0x7CB9, 0xB4E2, 0x7CBA, 0xBB9F, - 0x7CBB, 0xBBA0, 0x7CBC, 0xF4D4, 0x7CBD, 0xF4D5, 0x7CBE, 0xBEAB, 0x7CBF, 0xBC40, 0x7CC0, 0xBC41, 0x7CC1, 0xF4D6, 0x7CC2, 0xBC42, - 0x7CC3, 0xBC43, 0x7CC4, 0xBC44, 0x7CC5, 0xF4DB, 0x7CC6, 0xBC45, 0x7CC7, 0xF4D7, 0x7CC8, 0xF4DA, 0x7CC9, 0xBC46, 0x7CCA, 0xBAFD, - 0x7CCB, 0xBC47, 0x7CCC, 0xF4D8, 0x7CCD, 0xF4D9, 0x7CCE, 0xBC48, 0x7CCF, 0xBC49, 0x7CD0, 0xBC4A, 0x7CD1, 0xBC4B, 0x7CD2, 0xBC4C, - 0x7CD3, 0xBC4D, 0x7CD4, 0xBC4E, 0x7CD5, 0xB8E2, 0x7CD6, 0xCCC7, 0x7CD7, 0xF4DC, 0x7CD8, 0xBC4F, 0x7CD9, 0xB2DA, 0x7CDA, 0xBC50, - 0x7CDB, 0xBC51, 0x7CDC, 0xC3D3, 0x7CDD, 0xBC52, 0x7CDE, 0xBC53, 0x7CDF, 0xD4E3, 0x7CE0, 0xBFB7, 0x7CE1, 0xBC54, 0x7CE2, 0xBC55, - 0x7CE3, 0xBC56, 0x7CE4, 0xBC57, 0x7CE5, 0xBC58, 0x7CE6, 0xBC59, 0x7CE7, 0xBC5A, 0x7CE8, 0xF4DD, 0x7CE9, 0xBC5B, 0x7CEA, 0xBC5C, - 0x7CEB, 0xBC5D, 0x7CEC, 0xBC5E, 0x7CED, 0xBC5F, 0x7CEE, 0xBC60, 0x7CEF, 0xC5B4, 0x7CF0, 0xBC61, 0x7CF1, 0xBC62, 0x7CF2, 0xBC63, - 0x7CF3, 0xBC64, 0x7CF4, 0xBC65, 0x7CF5, 0xBC66, 0x7CF6, 0xBC67, 0x7CF7, 0xBC68, 0x7CF8, 0xF4E9, 0x7CF9, 0xBC69, 0x7CFA, 0xBC6A, - 0x7CFB, 0xCFB5, 0x7CFC, 0xBC6B, 0x7CFD, 0xBC6C, 0x7CFE, 0xBC6D, 0x7CFF, 0xBC6E, 0x7D00, 0xBC6F, 0x7D01, 0xBC70, 0x7D02, 0xBC71, - 0x7D03, 0xBC72, 0x7D04, 0xBC73, 0x7D05, 0xBC74, 0x7D06, 0xBC75, 0x7D07, 0xBC76, 0x7D08, 0xBC77, 0x7D09, 0xBC78, 0x7D0A, 0xCEC9, - 0x7D0B, 0xBC79, 0x7D0C, 0xBC7A, 0x7D0D, 0xBC7B, 0x7D0E, 0xBC7C, 0x7D0F, 0xBC7D, 0x7D10, 0xBC7E, 0x7D11, 0xBC80, 0x7D12, 0xBC81, - 0x7D13, 0xBC82, 0x7D14, 0xBC83, 0x7D15, 0xBC84, 0x7D16, 0xBC85, 0x7D17, 0xBC86, 0x7D18, 0xBC87, 0x7D19, 0xBC88, 0x7D1A, 0xBC89, - 0x7D1B, 0xBC8A, 0x7D1C, 0xBC8B, 0x7D1D, 0xBC8C, 0x7D1E, 0xBC8D, 0x7D1F, 0xBC8E, 0x7D20, 0xCBD8, 0x7D21, 0xBC8F, 0x7D22, 0xCBF7, - 0x7D23, 0xBC90, 0x7D24, 0xBC91, 0x7D25, 0xBC92, 0x7D26, 0xBC93, 0x7D27, 0xBDF4, 0x7D28, 0xBC94, 0x7D29, 0xBC95, 0x7D2A, 0xBC96, - 0x7D2B, 0xD7CF, 0x7D2C, 0xBC97, 0x7D2D, 0xBC98, 0x7D2E, 0xBC99, 0x7D2F, 0xC0DB, 0x7D30, 0xBC9A, 0x7D31, 0xBC9B, 0x7D32, 0xBC9C, - 0x7D33, 0xBC9D, 0x7D34, 0xBC9E, 0x7D35, 0xBC9F, 0x7D36, 0xBCA0, 0x7D37, 0xBD40, 0x7D38, 0xBD41, 0x7D39, 0xBD42, 0x7D3A, 0xBD43, - 0x7D3B, 0xBD44, 0x7D3C, 0xBD45, 0x7D3D, 0xBD46, 0x7D3E, 0xBD47, 0x7D3F, 0xBD48, 0x7D40, 0xBD49, 0x7D41, 0xBD4A, 0x7D42, 0xBD4B, - 0x7D43, 0xBD4C, 0x7D44, 0xBD4D, 0x7D45, 0xBD4E, 0x7D46, 0xBD4F, 0x7D47, 0xBD50, 0x7D48, 0xBD51, 0x7D49, 0xBD52, 0x7D4A, 0xBD53, - 0x7D4B, 0xBD54, 0x7D4C, 0xBD55, 0x7D4D, 0xBD56, 0x7D4E, 0xBD57, 0x7D4F, 0xBD58, 0x7D50, 0xBD59, 0x7D51, 0xBD5A, 0x7D52, 0xBD5B, - 0x7D53, 0xBD5C, 0x7D54, 0xBD5D, 0x7D55, 0xBD5E, 0x7D56, 0xBD5F, 0x7D57, 0xBD60, 0x7D58, 0xBD61, 0x7D59, 0xBD62, 0x7D5A, 0xBD63, - 0x7D5B, 0xBD64, 0x7D5C, 0xBD65, 0x7D5D, 0xBD66, 0x7D5E, 0xBD67, 0x7D5F, 0xBD68, 0x7D60, 0xBD69, 0x7D61, 0xBD6A, 0x7D62, 0xBD6B, - 0x7D63, 0xBD6C, 0x7D64, 0xBD6D, 0x7D65, 0xBD6E, 0x7D66, 0xBD6F, 0x7D67, 0xBD70, 0x7D68, 0xBD71, 0x7D69, 0xBD72, 0x7D6A, 0xBD73, - 0x7D6B, 0xBD74, 0x7D6C, 0xBD75, 0x7D6D, 0xBD76, 0x7D6E, 0xD0F5, 0x7D6F, 0xBD77, 0x7D70, 0xBD78, 0x7D71, 0xBD79, 0x7D72, 0xBD7A, - 0x7D73, 0xBD7B, 0x7D74, 0xBD7C, 0x7D75, 0xBD7D, 0x7D76, 0xBD7E, 0x7D77, 0xF4EA, 0x7D78, 0xBD80, 0x7D79, 0xBD81, 0x7D7A, 0xBD82, - 0x7D7B, 0xBD83, 0x7D7C, 0xBD84, 0x7D7D, 0xBD85, 0x7D7E, 0xBD86, 0x7D7F, 0xBD87, 0x7D80, 0xBD88, 0x7D81, 0xBD89, 0x7D82, 0xBD8A, - 0x7D83, 0xBD8B, 0x7D84, 0xBD8C, 0x7D85, 0xBD8D, 0x7D86, 0xBD8E, 0x7D87, 0xBD8F, 0x7D88, 0xBD90, 0x7D89, 0xBD91, 0x7D8A, 0xBD92, - 0x7D8B, 0xBD93, 0x7D8C, 0xBD94, 0x7D8D, 0xBD95, 0x7D8E, 0xBD96, 0x7D8F, 0xBD97, 0x7D90, 0xBD98, 0x7D91, 0xBD99, 0x7D92, 0xBD9A, - 0x7D93, 0xBD9B, 0x7D94, 0xBD9C, 0x7D95, 0xBD9D, 0x7D96, 0xBD9E, 0x7D97, 0xBD9F, 0x7D98, 0xBDA0, 0x7D99, 0xBE40, 0x7D9A, 0xBE41, - 0x7D9B, 0xBE42, 0x7D9C, 0xBE43, 0x7D9D, 0xBE44, 0x7D9E, 0xBE45, 0x7D9F, 0xBE46, 0x7DA0, 0xBE47, 0x7DA1, 0xBE48, 0x7DA2, 0xBE49, - 0x7DA3, 0xBE4A, 0x7DA4, 0xBE4B, 0x7DA5, 0xBE4C, 0x7DA6, 0xF4EB, 0x7DA7, 0xBE4D, 0x7DA8, 0xBE4E, 0x7DA9, 0xBE4F, 0x7DAA, 0xBE50, - 0x7DAB, 0xBE51, 0x7DAC, 0xBE52, 0x7DAD, 0xBE53, 0x7DAE, 0xF4EC, 0x7DAF, 0xBE54, 0x7DB0, 0xBE55, 0x7DB1, 0xBE56, 0x7DB2, 0xBE57, - 0x7DB3, 0xBE58, 0x7DB4, 0xBE59, 0x7DB5, 0xBE5A, 0x7DB6, 0xBE5B, 0x7DB7, 0xBE5C, 0x7DB8, 0xBE5D, 0x7DB9, 0xBE5E, 0x7DBA, 0xBE5F, - 0x7DBB, 0xBE60, 0x7DBC, 0xBE61, 0x7DBD, 0xBE62, 0x7DBE, 0xBE63, 0x7DBF, 0xBE64, 0x7DC0, 0xBE65, 0x7DC1, 0xBE66, 0x7DC2, 0xBE67, - 0x7DC3, 0xBE68, 0x7DC4, 0xBE69, 0x7DC5, 0xBE6A, 0x7DC6, 0xBE6B, 0x7DC7, 0xBE6C, 0x7DC8, 0xBE6D, 0x7DC9, 0xBE6E, 0x7DCA, 0xBE6F, - 0x7DCB, 0xBE70, 0x7DCC, 0xBE71, 0x7DCD, 0xBE72, 0x7DCE, 0xBE73, 0x7DCF, 0xBE74, 0x7DD0, 0xBE75, 0x7DD1, 0xBE76, 0x7DD2, 0xBE77, - 0x7DD3, 0xBE78, 0x7DD4, 0xBE79, 0x7DD5, 0xBE7A, 0x7DD6, 0xBE7B, 0x7DD7, 0xBE7C, 0x7DD8, 0xBE7D, 0x7DD9, 0xBE7E, 0x7DDA, 0xBE80, - 0x7DDB, 0xBE81, 0x7DDC, 0xBE82, 0x7DDD, 0xBE83, 0x7DDE, 0xBE84, 0x7DDF, 0xBE85, 0x7DE0, 0xBE86, 0x7DE1, 0xBE87, 0x7DE2, 0xBE88, - 0x7DE3, 0xBE89, 0x7DE4, 0xBE8A, 0x7DE5, 0xBE8B, 0x7DE6, 0xBE8C, 0x7DE7, 0xBE8D, 0x7DE8, 0xBE8E, 0x7DE9, 0xBE8F, 0x7DEA, 0xBE90, - 0x7DEB, 0xBE91, 0x7DEC, 0xBE92, 0x7DED, 0xBE93, 0x7DEE, 0xBE94, 0x7DEF, 0xBE95, 0x7DF0, 0xBE96, 0x7DF1, 0xBE97, 0x7DF2, 0xBE98, - 0x7DF3, 0xBE99, 0x7DF4, 0xBE9A, 0x7DF5, 0xBE9B, 0x7DF6, 0xBE9C, 0x7DF7, 0xBE9D, 0x7DF8, 0xBE9E, 0x7DF9, 0xBE9F, 0x7DFA, 0xBEA0, - 0x7DFB, 0xBF40, 0x7DFC, 0xBF41, 0x7DFD, 0xBF42, 0x7DFE, 0xBF43, 0x7DFF, 0xBF44, 0x7E00, 0xBF45, 0x7E01, 0xBF46, 0x7E02, 0xBF47, - 0x7E03, 0xBF48, 0x7E04, 0xBF49, 0x7E05, 0xBF4A, 0x7E06, 0xBF4B, 0x7E07, 0xBF4C, 0x7E08, 0xBF4D, 0x7E09, 0xBF4E, 0x7E0A, 0xBF4F, - 0x7E0B, 0xBF50, 0x7E0C, 0xBF51, 0x7E0D, 0xBF52, 0x7E0E, 0xBF53, 0x7E0F, 0xBF54, 0x7E10, 0xBF55, 0x7E11, 0xBF56, 0x7E12, 0xBF57, - 0x7E13, 0xBF58, 0x7E14, 0xBF59, 0x7E15, 0xBF5A, 0x7E16, 0xBF5B, 0x7E17, 0xBF5C, 0x7E18, 0xBF5D, 0x7E19, 0xBF5E, 0x7E1A, 0xBF5F, - 0x7E1B, 0xBF60, 0x7E1C, 0xBF61, 0x7E1D, 0xBF62, 0x7E1E, 0xBF63, 0x7E1F, 0xBF64, 0x7E20, 0xBF65, 0x7E21, 0xBF66, 0x7E22, 0xBF67, - 0x7E23, 0xBF68, 0x7E24, 0xBF69, 0x7E25, 0xBF6A, 0x7E26, 0xBF6B, 0x7E27, 0xBF6C, 0x7E28, 0xBF6D, 0x7E29, 0xBF6E, 0x7E2A, 0xBF6F, - 0x7E2B, 0xBF70, 0x7E2C, 0xBF71, 0x7E2D, 0xBF72, 0x7E2E, 0xBF73, 0x7E2F, 0xBF74, 0x7E30, 0xBF75, 0x7E31, 0xBF76, 0x7E32, 0xBF77, - 0x7E33, 0xBF78, 0x7E34, 0xBF79, 0x7E35, 0xBF7A, 0x7E36, 0xBF7B, 0x7E37, 0xBF7C, 0x7E38, 0xBF7D, 0x7E39, 0xBF7E, 0x7E3A, 0xBF80, - 0x7E3B, 0xF7E3, 0x7E3C, 0xBF81, 0x7E3D, 0xBF82, 0x7E3E, 0xBF83, 0x7E3F, 0xBF84, 0x7E40, 0xBF85, 0x7E41, 0xB7B1, 0x7E42, 0xBF86, - 0x7E43, 0xBF87, 0x7E44, 0xBF88, 0x7E45, 0xBF89, 0x7E46, 0xBF8A, 0x7E47, 0xF4ED, 0x7E48, 0xBF8B, 0x7E49, 0xBF8C, 0x7E4A, 0xBF8D, - 0x7E4B, 0xBF8E, 0x7E4C, 0xBF8F, 0x7E4D, 0xBF90, 0x7E4E, 0xBF91, 0x7E4F, 0xBF92, 0x7E50, 0xBF93, 0x7E51, 0xBF94, 0x7E52, 0xBF95, - 0x7E53, 0xBF96, 0x7E54, 0xBF97, 0x7E55, 0xBF98, 0x7E56, 0xBF99, 0x7E57, 0xBF9A, 0x7E58, 0xBF9B, 0x7E59, 0xBF9C, 0x7E5A, 0xBF9D, - 0x7E5B, 0xBF9E, 0x7E5C, 0xBF9F, 0x7E5D, 0xBFA0, 0x7E5E, 0xC040, 0x7E5F, 0xC041, 0x7E60, 0xC042, 0x7E61, 0xC043, 0x7E62, 0xC044, - 0x7E63, 0xC045, 0x7E64, 0xC046, 0x7E65, 0xC047, 0x7E66, 0xC048, 0x7E67, 0xC049, 0x7E68, 0xC04A, 0x7E69, 0xC04B, 0x7E6A, 0xC04C, - 0x7E6B, 0xC04D, 0x7E6C, 0xC04E, 0x7E6D, 0xC04F, 0x7E6E, 0xC050, 0x7E6F, 0xC051, 0x7E70, 0xC052, 0x7E71, 0xC053, 0x7E72, 0xC054, - 0x7E73, 0xC055, 0x7E74, 0xC056, 0x7E75, 0xC057, 0x7E76, 0xC058, 0x7E77, 0xC059, 0x7E78, 0xC05A, 0x7E79, 0xC05B, 0x7E7A, 0xC05C, - 0x7E7B, 0xC05D, 0x7E7C, 0xC05E, 0x7E7D, 0xC05F, 0x7E7E, 0xC060, 0x7E7F, 0xC061, 0x7E80, 0xC062, 0x7E81, 0xC063, 0x7E82, 0xD7EB, - 0x7E83, 0xC064, 0x7E84, 0xC065, 0x7E85, 0xC066, 0x7E86, 0xC067, 0x7E87, 0xC068, 0x7E88, 0xC069, 0x7E89, 0xC06A, 0x7E8A, 0xC06B, - 0x7E8B, 0xC06C, 0x7E8C, 0xC06D, 0x7E8D, 0xC06E, 0x7E8E, 0xC06F, 0x7E8F, 0xC070, 0x7E90, 0xC071, 0x7E91, 0xC072, 0x7E92, 0xC073, - 0x7E93, 0xC074, 0x7E94, 0xC075, 0x7E95, 0xC076, 0x7E96, 0xC077, 0x7E97, 0xC078, 0x7E98, 0xC079, 0x7E99, 0xC07A, 0x7E9A, 0xC07B, - 0x7E9B, 0xF4EE, 0x7E9C, 0xC07C, 0x7E9D, 0xC07D, 0x7E9E, 0xC07E, 0x7E9F, 0xE6F9, 0x7EA0, 0xBEC0, 0x7EA1, 0xE6FA, 0x7EA2, 0xBAEC, - 0x7EA3, 0xE6FB, 0x7EA4, 0xCFCB, 0x7EA5, 0xE6FC, 0x7EA6, 0xD4BC, 0x7EA7, 0xBCB6, 0x7EA8, 0xE6FD, 0x7EA9, 0xE6FE, 0x7EAA, 0xBCCD, - 0x7EAB, 0xC8D2, 0x7EAC, 0xCEB3, 0x7EAD, 0xE7A1, 0x7EAE, 0xC080, 0x7EAF, 0xB4BF, 0x7EB0, 0xE7A2, 0x7EB1, 0xC9B4, 0x7EB2, 0xB8D9, - 0x7EB3, 0xC4C9, 0x7EB4, 0xC081, 0x7EB5, 0xD7DD, 0x7EB6, 0xC2DA, 0x7EB7, 0xB7D7, 0x7EB8, 0xD6BD, 0x7EB9, 0xCEC6, 0x7EBA, 0xB7C4, - 0x7EBB, 0xC082, 0x7EBC, 0xC083, 0x7EBD, 0xC5A6, 0x7EBE, 0xE7A3, 0x7EBF, 0xCFDF, 0x7EC0, 0xE7A4, 0x7EC1, 0xE7A5, 0x7EC2, 0xE7A6, - 0x7EC3, 0xC1B7, 0x7EC4, 0xD7E9, 0x7EC5, 0xC9F0, 0x7EC6, 0xCFB8, 0x7EC7, 0xD6AF, 0x7EC8, 0xD6D5, 0x7EC9, 0xE7A7, 0x7ECA, 0xB0ED, - 0x7ECB, 0xE7A8, 0x7ECC, 0xE7A9, 0x7ECD, 0xC9DC, 0x7ECE, 0xD2EF, 0x7ECF, 0xBEAD, 0x7ED0, 0xE7AA, 0x7ED1, 0xB0F3, 0x7ED2, 0xC8DE, - 0x7ED3, 0xBDE1, 0x7ED4, 0xE7AB, 0x7ED5, 0xC8C6, 0x7ED6, 0xC084, 0x7ED7, 0xE7AC, 0x7ED8, 0xBBE6, 0x7ED9, 0xB8F8, 0x7EDA, 0xD1A4, - 0x7EDB, 0xE7AD, 0x7EDC, 0xC2E7, 0x7EDD, 0xBEF8, 0x7EDE, 0xBDCA, 0x7EDF, 0xCDB3, 0x7EE0, 0xE7AE, 0x7EE1, 0xE7AF, 0x7EE2, 0xBEEE, - 0x7EE3, 0xD0E5, 0x7EE4, 0xC085, 0x7EE5, 0xCBE7, 0x7EE6, 0xCCD0, 0x7EE7, 0xBCCC, 0x7EE8, 0xE7B0, 0x7EE9, 0xBCA8, 0x7EEA, 0xD0F7, - 0x7EEB, 0xE7B1, 0x7EEC, 0xC086, 0x7EED, 0xD0F8, 0x7EEE, 0xE7B2, 0x7EEF, 0xE7B3, 0x7EF0, 0xB4C2, 0x7EF1, 0xE7B4, 0x7EF2, 0xE7B5, - 0x7EF3, 0xC9FE, 0x7EF4, 0xCEAC, 0x7EF5, 0xC3E0, 0x7EF6, 0xE7B7, 0x7EF7, 0xB1C1, 0x7EF8, 0xB3F1, 0x7EF9, 0xC087, 0x7EFA, 0xE7B8, - 0x7EFB, 0xE7B9, 0x7EFC, 0xD7DB, 0x7EFD, 0xD5C0, 0x7EFE, 0xE7BA, 0x7EFF, 0xC2CC, 0x7F00, 0xD7BA, 0x7F01, 0xE7BB, 0x7F02, 0xE7BC, - 0x7F03, 0xE7BD, 0x7F04, 0xBCEA, 0x7F05, 0xC3E5, 0x7F06, 0xC0C2, 0x7F07, 0xE7BE, 0x7F08, 0xE7BF, 0x7F09, 0xBCA9, 0x7F0A, 0xC088, - 0x7F0B, 0xE7C0, 0x7F0C, 0xE7C1, 0x7F0D, 0xE7B6, 0x7F0E, 0xB6D0, 0x7F0F, 0xE7C2, 0x7F10, 0xC089, 0x7F11, 0xE7C3, 0x7F12, 0xE7C4, - 0x7F13, 0xBBBA, 0x7F14, 0xB5DE, 0x7F15, 0xC2C6, 0x7F16, 0xB1E0, 0x7F17, 0xE7C5, 0x7F18, 0xD4B5, 0x7F19, 0xE7C6, 0x7F1A, 0xB8BF, - 0x7F1B, 0xE7C8, 0x7F1C, 0xE7C7, 0x7F1D, 0xB7EC, 0x7F1E, 0xC08A, 0x7F1F, 0xE7C9, 0x7F20, 0xB2F8, 0x7F21, 0xE7CA, 0x7F22, 0xE7CB, - 0x7F23, 0xE7CC, 0x7F24, 0xE7CD, 0x7F25, 0xE7CE, 0x7F26, 0xE7CF, 0x7F27, 0xE7D0, 0x7F28, 0xD3A7, 0x7F29, 0xCBF5, 0x7F2A, 0xE7D1, - 0x7F2B, 0xE7D2, 0x7F2C, 0xE7D3, 0x7F2D, 0xE7D4, 0x7F2E, 0xC9C9, 0x7F2F, 0xE7D5, 0x7F30, 0xE7D6, 0x7F31, 0xE7D7, 0x7F32, 0xE7D8, - 0x7F33, 0xE7D9, 0x7F34, 0xBDC9, 0x7F35, 0xE7DA, 0x7F36, 0xF3BE, 0x7F37, 0xC08B, 0x7F38, 0xB8D7, 0x7F39, 0xC08C, 0x7F3A, 0xC8B1, - 0x7F3B, 0xC08D, 0x7F3C, 0xC08E, 0x7F3D, 0xC08F, 0x7F3E, 0xC090, 0x7F3F, 0xC091, 0x7F40, 0xC092, 0x7F41, 0xC093, 0x7F42, 0xF3BF, - 0x7F43, 0xC094, 0x7F44, 0xF3C0, 0x7F45, 0xF3C1, 0x7F46, 0xC095, 0x7F47, 0xC096, 0x7F48, 0xC097, 0x7F49, 0xC098, 0x7F4A, 0xC099, - 0x7F4B, 0xC09A, 0x7F4C, 0xC09B, 0x7F4D, 0xC09C, 0x7F4E, 0xC09D, 0x7F4F, 0xC09E, 0x7F50, 0xB9DE, 0x7F51, 0xCDF8, 0x7F52, 0xC09F, - 0x7F53, 0xC0A0, 0x7F54, 0xD8E8, 0x7F55, 0xBAB1, 0x7F56, 0xC140, 0x7F57, 0xC2DE, 0x7F58, 0xEEB7, 0x7F59, 0xC141, 0x7F5A, 0xB7A3, - 0x7F5B, 0xC142, 0x7F5C, 0xC143, 0x7F5D, 0xC144, 0x7F5E, 0xC145, 0x7F5F, 0xEEB9, 0x7F60, 0xC146, 0x7F61, 0xEEB8, 0x7F62, 0xB0D5, - 0x7F63, 0xC147, 0x7F64, 0xC148, 0x7F65, 0xC149, 0x7F66, 0xC14A, 0x7F67, 0xC14B, 0x7F68, 0xEEBB, 0x7F69, 0xD5D6, 0x7F6A, 0xD7EF, - 0x7F6B, 0xC14C, 0x7F6C, 0xC14D, 0x7F6D, 0xC14E, 0x7F6E, 0xD6C3, 0x7F6F, 0xC14F, 0x7F70, 0xC150, 0x7F71, 0xEEBD, 0x7F72, 0xCAF0, - 0x7F73, 0xC151, 0x7F74, 0xEEBC, 0x7F75, 0xC152, 0x7F76, 0xC153, 0x7F77, 0xC154, 0x7F78, 0xC155, 0x7F79, 0xEEBE, 0x7F7A, 0xC156, - 0x7F7B, 0xC157, 0x7F7C, 0xC158, 0x7F7D, 0xC159, 0x7F7E, 0xEEC0, 0x7F7F, 0xC15A, 0x7F80, 0xC15B, 0x7F81, 0xEEBF, 0x7F82, 0xC15C, - 0x7F83, 0xC15D, 0x7F84, 0xC15E, 0x7F85, 0xC15F, 0x7F86, 0xC160, 0x7F87, 0xC161, 0x7F88, 0xC162, 0x7F89, 0xC163, 0x7F8A, 0xD1F2, - 0x7F8B, 0xC164, 0x7F8C, 0xC7BC, 0x7F8D, 0xC165, 0x7F8E, 0xC3C0, 0x7F8F, 0xC166, 0x7F90, 0xC167, 0x7F91, 0xC168, 0x7F92, 0xC169, - 0x7F93, 0xC16A, 0x7F94, 0xB8E1, 0x7F95, 0xC16B, 0x7F96, 0xC16C, 0x7F97, 0xC16D, 0x7F98, 0xC16E, 0x7F99, 0xC16F, 0x7F9A, 0xC1E7, - 0x7F9B, 0xC170, 0x7F9C, 0xC171, 0x7F9D, 0xF4C6, 0x7F9E, 0xD0DF, 0x7F9F, 0xF4C7, 0x7FA0, 0xC172, 0x7FA1, 0xCFDB, 0x7FA2, 0xC173, - 0x7FA3, 0xC174, 0x7FA4, 0xC8BA, 0x7FA5, 0xC175, 0x7FA6, 0xC176, 0x7FA7, 0xF4C8, 0x7FA8, 0xC177, 0x7FA9, 0xC178, 0x7FAA, 0xC179, - 0x7FAB, 0xC17A, 0x7FAC, 0xC17B, 0x7FAD, 0xC17C, 0x7FAE, 0xC17D, 0x7FAF, 0xF4C9, 0x7FB0, 0xF4CA, 0x7FB1, 0xC17E, 0x7FB2, 0xF4CB, - 0x7FB3, 0xC180, 0x7FB4, 0xC181, 0x7FB5, 0xC182, 0x7FB6, 0xC183, 0x7FB7, 0xC184, 0x7FB8, 0xD9FA, 0x7FB9, 0xB8FE, 0x7FBA, 0xC185, - 0x7FBB, 0xC186, 0x7FBC, 0xE5F1, 0x7FBD, 0xD3F0, 0x7FBE, 0xC187, 0x7FBF, 0xF4E0, 0x7FC0, 0xC188, 0x7FC1, 0xCECC, 0x7FC2, 0xC189, - 0x7FC3, 0xC18A, 0x7FC4, 0xC18B, 0x7FC5, 0xB3E1, 0x7FC6, 0xC18C, 0x7FC7, 0xC18D, 0x7FC8, 0xC18E, 0x7FC9, 0xC18F, 0x7FCA, 0xF1B4, - 0x7FCB, 0xC190, 0x7FCC, 0xD2EE, 0x7FCD, 0xC191, 0x7FCE, 0xF4E1, 0x7FCF, 0xC192, 0x7FD0, 0xC193, 0x7FD1, 0xC194, 0x7FD2, 0xC195, - 0x7FD3, 0xC196, 0x7FD4, 0xCFE8, 0x7FD5, 0xF4E2, 0x7FD6, 0xC197, 0x7FD7, 0xC198, 0x7FD8, 0xC7CC, 0x7FD9, 0xC199, 0x7FDA, 0xC19A, - 0x7FDB, 0xC19B, 0x7FDC, 0xC19C, 0x7FDD, 0xC19D, 0x7FDE, 0xC19E, 0x7FDF, 0xB5D4, 0x7FE0, 0xB4E4, 0x7FE1, 0xF4E4, 0x7FE2, 0xC19F, - 0x7FE3, 0xC1A0, 0x7FE4, 0xC240, 0x7FE5, 0xF4E3, 0x7FE6, 0xF4E5, 0x7FE7, 0xC241, 0x7FE8, 0xC242, 0x7FE9, 0xF4E6, 0x7FEA, 0xC243, - 0x7FEB, 0xC244, 0x7FEC, 0xC245, 0x7FED, 0xC246, 0x7FEE, 0xF4E7, 0x7FEF, 0xC247, 0x7FF0, 0xBAB2, 0x7FF1, 0xB0BF, 0x7FF2, 0xC248, - 0x7FF3, 0xF4E8, 0x7FF4, 0xC249, 0x7FF5, 0xC24A, 0x7FF6, 0xC24B, 0x7FF7, 0xC24C, 0x7FF8, 0xC24D, 0x7FF9, 0xC24E, 0x7FFA, 0xC24F, - 0x7FFB, 0xB7AD, 0x7FFC, 0xD2ED, 0x7FFD, 0xC250, 0x7FFE, 0xC251, 0x7FFF, 0xC252, 0x8000, 0xD2AB, 0x8001, 0xC0CF, 0x8002, 0xC253, - 0x8003, 0xBFBC, 0x8004, 0xEBA3, 0x8005, 0xD5DF, 0x8006, 0xEAC8, 0x8007, 0xC254, 0x8008, 0xC255, 0x8009, 0xC256, 0x800A, 0xC257, - 0x800B, 0xF1F3, 0x800C, 0xB6F8, 0x800D, 0xCBA3, 0x800E, 0xC258, 0x800F, 0xC259, 0x8010, 0xC4CD, 0x8011, 0xC25A, 0x8012, 0xF1E7, - 0x8013, 0xC25B, 0x8014, 0xF1E8, 0x8015, 0xB8FB, 0x8016, 0xF1E9, 0x8017, 0xBAC4, 0x8018, 0xD4C5, 0x8019, 0xB0D2, 0x801A, 0xC25C, - 0x801B, 0xC25D, 0x801C, 0xF1EA, 0x801D, 0xC25E, 0x801E, 0xC25F, 0x801F, 0xC260, 0x8020, 0xF1EB, 0x8021, 0xC261, 0x8022, 0xF1EC, - 0x8023, 0xC262, 0x8024, 0xC263, 0x8025, 0xF1ED, 0x8026, 0xF1EE, 0x8027, 0xF1EF, 0x8028, 0xF1F1, 0x8029, 0xF1F0, 0x802A, 0xC5D5, - 0x802B, 0xC264, 0x802C, 0xC265, 0x802D, 0xC266, 0x802E, 0xC267, 0x802F, 0xC268, 0x8030, 0xC269, 0x8031, 0xF1F2, 0x8032, 0xC26A, - 0x8033, 0xB6FA, 0x8034, 0xC26B, 0x8035, 0xF1F4, 0x8036, 0xD2AE, 0x8037, 0xDEC7, 0x8038, 0xCBCA, 0x8039, 0xC26C, 0x803A, 0xC26D, - 0x803B, 0xB3DC, 0x803C, 0xC26E, 0x803D, 0xB5A2, 0x803E, 0xC26F, 0x803F, 0xB9A2, 0x8040, 0xC270, 0x8041, 0xC271, 0x8042, 0xC4F4, - 0x8043, 0xF1F5, 0x8044, 0xC272, 0x8045, 0xC273, 0x8046, 0xF1F6, 0x8047, 0xC274, 0x8048, 0xC275, 0x8049, 0xC276, 0x804A, 0xC1C4, - 0x804B, 0xC1FB, 0x804C, 0xD6B0, 0x804D, 0xF1F7, 0x804E, 0xC277, 0x804F, 0xC278, 0x8050, 0xC279, 0x8051, 0xC27A, 0x8052, 0xF1F8, - 0x8053, 0xC27B, 0x8054, 0xC1AA, 0x8055, 0xC27C, 0x8056, 0xC27D, 0x8057, 0xC27E, 0x8058, 0xC6B8, 0x8059, 0xC280, 0x805A, 0xBEDB, - 0x805B, 0xC281, 0x805C, 0xC282, 0x805D, 0xC283, 0x805E, 0xC284, 0x805F, 0xC285, 0x8060, 0xC286, 0x8061, 0xC287, 0x8062, 0xC288, - 0x8063, 0xC289, 0x8064, 0xC28A, 0x8065, 0xC28B, 0x8066, 0xC28C, 0x8067, 0xC28D, 0x8068, 0xC28E, 0x8069, 0xF1F9, 0x806A, 0xB4CF, - 0x806B, 0xC28F, 0x806C, 0xC290, 0x806D, 0xC291, 0x806E, 0xC292, 0x806F, 0xC293, 0x8070, 0xC294, 0x8071, 0xF1FA, 0x8072, 0xC295, - 0x8073, 0xC296, 0x8074, 0xC297, 0x8075, 0xC298, 0x8076, 0xC299, 0x8077, 0xC29A, 0x8078, 0xC29B, 0x8079, 0xC29C, 0x807A, 0xC29D, - 0x807B, 0xC29E, 0x807C, 0xC29F, 0x807D, 0xC2A0, 0x807E, 0xC340, 0x807F, 0xEDB2, 0x8080, 0xEDB1, 0x8081, 0xC341, 0x8082, 0xC342, - 0x8083, 0xCBE0, 0x8084, 0xD2DE, 0x8085, 0xC343, 0x8086, 0xCBC1, 0x8087, 0xD5D8, 0x8088, 0xC344, 0x8089, 0xC8E2, 0x808A, 0xC345, - 0x808B, 0xC0DF, 0x808C, 0xBCA1, 0x808D, 0xC346, 0x808E, 0xC347, 0x808F, 0xC348, 0x8090, 0xC349, 0x8091, 0xC34A, 0x8092, 0xC34B, - 0x8093, 0xEBC1, 0x8094, 0xC34C, 0x8095, 0xC34D, 0x8096, 0xD0A4, 0x8097, 0xC34E, 0x8098, 0xD6E2, 0x8099, 0xC34F, 0x809A, 0xB6C7, - 0x809B, 0xB8D8, 0x809C, 0xEBC0, 0x809D, 0xB8CE, 0x809E, 0xC350, 0x809F, 0xEBBF, 0x80A0, 0xB3A6, 0x80A1, 0xB9C9, 0x80A2, 0xD6AB, - 0x80A3, 0xC351, 0x80A4, 0xB7F4, 0x80A5, 0xB7CA, 0x80A6, 0xC352, 0x80A7, 0xC353, 0x80A8, 0xC354, 0x80A9, 0xBCE7, 0x80AA, 0xB7BE, - 0x80AB, 0xEBC6, 0x80AC, 0xC355, 0x80AD, 0xEBC7, 0x80AE, 0xB0B9, 0x80AF, 0xBFCF, 0x80B0, 0xC356, 0x80B1, 0xEBC5, 0x80B2, 0xD3FD, - 0x80B3, 0xC357, 0x80B4, 0xEBC8, 0x80B5, 0xC358, 0x80B6, 0xC359, 0x80B7, 0xEBC9, 0x80B8, 0xC35A, 0x80B9, 0xC35B, 0x80BA, 0xB7CE, - 0x80BB, 0xC35C, 0x80BC, 0xEBC2, 0x80BD, 0xEBC4, 0x80BE, 0xC9F6, 0x80BF, 0xD6D7, 0x80C0, 0xD5CD, 0x80C1, 0xD0B2, 0x80C2, 0xEBCF, - 0x80C3, 0xCEB8, 0x80C4, 0xEBD0, 0x80C5, 0xC35D, 0x80C6, 0xB5A8, 0x80C7, 0xC35E, 0x80C8, 0xC35F, 0x80C9, 0xC360, 0x80CA, 0xC361, - 0x80CB, 0xC362, 0x80CC, 0xB1B3, 0x80CD, 0xEBD2, 0x80CE, 0xCCA5, 0x80CF, 0xC363, 0x80D0, 0xC364, 0x80D1, 0xC365, 0x80D2, 0xC366, - 0x80D3, 0xC367, 0x80D4, 0xC368, 0x80D5, 0xC369, 0x80D6, 0xC5D6, 0x80D7, 0xEBD3, 0x80D8, 0xC36A, 0x80D9, 0xEBD1, 0x80DA, 0xC5DF, - 0x80DB, 0xEBCE, 0x80DC, 0xCAA4, 0x80DD, 0xEBD5, 0x80DE, 0xB0FB, 0x80DF, 0xC36B, 0x80E0, 0xC36C, 0x80E1, 0xBAFA, 0x80E2, 0xC36D, - 0x80E3, 0xC36E, 0x80E4, 0xD8B7, 0x80E5, 0xF1E3, 0x80E6, 0xC36F, 0x80E7, 0xEBCA, 0x80E8, 0xEBCB, 0x80E9, 0xEBCC, 0x80EA, 0xEBCD, - 0x80EB, 0xEBD6, 0x80EC, 0xE6C0, 0x80ED, 0xEBD9, 0x80EE, 0xC370, 0x80EF, 0xBFE8, 0x80F0, 0xD2C8, 0x80F1, 0xEBD7, 0x80F2, 0xEBDC, - 0x80F3, 0xB8EC, 0x80F4, 0xEBD8, 0x80F5, 0xC371, 0x80F6, 0xBDBA, 0x80F7, 0xC372, 0x80F8, 0xD0D8, 0x80F9, 0xC373, 0x80FA, 0xB0B7, - 0x80FB, 0xC374, 0x80FC, 0xEBDD, 0x80FD, 0xC4DC, 0x80FE, 0xC375, 0x80FF, 0xC376, 0x8100, 0xC377, 0x8101, 0xC378, 0x8102, 0xD6AC, - 0x8103, 0xC379, 0x8104, 0xC37A, 0x8105, 0xC37B, 0x8106, 0xB4E0, 0x8107, 0xC37C, 0x8108, 0xC37D, 0x8109, 0xC2F6, 0x810A, 0xBCB9, - 0x810B, 0xC37E, 0x810C, 0xC380, 0x810D, 0xEBDA, 0x810E, 0xEBDB, 0x810F, 0xD4E0, 0x8110, 0xC6EA, 0x8111, 0xC4D4, 0x8112, 0xEBDF, - 0x8113, 0xC5A7, 0x8114, 0xD9F5, 0x8115, 0xC381, 0x8116, 0xB2B1, 0x8117, 0xC382, 0x8118, 0xEBE4, 0x8119, 0xC383, 0x811A, 0xBDC5, - 0x811B, 0xC384, 0x811C, 0xC385, 0x811D, 0xC386, 0x811E, 0xEBE2, 0x811F, 0xC387, 0x8120, 0xC388, 0x8121, 0xC389, 0x8122, 0xC38A, - 0x8123, 0xC38B, 0x8124, 0xC38C, 0x8125, 0xC38D, 0x8126, 0xC38E, 0x8127, 0xC38F, 0x8128, 0xC390, 0x8129, 0xC391, 0x812A, 0xC392, - 0x812B, 0xC393, 0x812C, 0xEBE3, 0x812D, 0xC394, 0x812E, 0xC395, 0x812F, 0xB8AC, 0x8130, 0xC396, 0x8131, 0xCDD1, 0x8132, 0xEBE5, - 0x8133, 0xC397, 0x8134, 0xC398, 0x8135, 0xC399, 0x8136, 0xEBE1, 0x8137, 0xC39A, 0x8138, 0xC1B3, 0x8139, 0xC39B, 0x813A, 0xC39C, - 0x813B, 0xC39D, 0x813C, 0xC39E, 0x813D, 0xC39F, 0x813E, 0xC6A2, 0x813F, 0xC3A0, 0x8140, 0xC440, 0x8141, 0xC441, 0x8142, 0xC442, - 0x8143, 0xC443, 0x8144, 0xC444, 0x8145, 0xC445, 0x8146, 0xCCF3, 0x8147, 0xC446, 0x8148, 0xEBE6, 0x8149, 0xC447, 0x814A, 0xC0B0, - 0x814B, 0xD2B8, 0x814C, 0xEBE7, 0x814D, 0xC448, 0x814E, 0xC449, 0x814F, 0xC44A, 0x8150, 0xB8AF, 0x8151, 0xB8AD, 0x8152, 0xC44B, - 0x8153, 0xEBE8, 0x8154, 0xC7BB, 0x8155, 0xCDF3, 0x8156, 0xC44C, 0x8157, 0xC44D, 0x8158, 0xC44E, 0x8159, 0xEBEA, 0x815A, 0xEBEB, - 0x815B, 0xC44F, 0x815C, 0xC450, 0x815D, 0xC451, 0x815E, 0xC452, 0x815F, 0xC453, 0x8160, 0xEBED, 0x8161, 0xC454, 0x8162, 0xC455, - 0x8163, 0xC456, 0x8164, 0xC457, 0x8165, 0xD0C8, 0x8166, 0xC458, 0x8167, 0xEBF2, 0x8168, 0xC459, 0x8169, 0xEBEE, 0x816A, 0xC45A, - 0x816B, 0xC45B, 0x816C, 0xC45C, 0x816D, 0xEBF1, 0x816E, 0xC8F9, 0x816F, 0xC45D, 0x8170, 0xD1FC, 0x8171, 0xEBEC, 0x8172, 0xC45E, - 0x8173, 0xC45F, 0x8174, 0xEBE9, 0x8175, 0xC460, 0x8176, 0xC461, 0x8177, 0xC462, 0x8178, 0xC463, 0x8179, 0xB8B9, 0x817A, 0xCFD9, - 0x817B, 0xC4E5, 0x817C, 0xEBEF, 0x817D, 0xEBF0, 0x817E, 0xCCDA, 0x817F, 0xCDC8, 0x8180, 0xB0F2, 0x8181, 0xC464, 0x8182, 0xEBF6, - 0x8183, 0xC465, 0x8184, 0xC466, 0x8185, 0xC467, 0x8186, 0xC468, 0x8187, 0xC469, 0x8188, 0xEBF5, 0x8189, 0xC46A, 0x818A, 0xB2B2, - 0x818B, 0xC46B, 0x818C, 0xC46C, 0x818D, 0xC46D, 0x818E, 0xC46E, 0x818F, 0xB8E0, 0x8190, 0xC46F, 0x8191, 0xEBF7, 0x8192, 0xC470, - 0x8193, 0xC471, 0x8194, 0xC472, 0x8195, 0xC473, 0x8196, 0xC474, 0x8197, 0xC475, 0x8198, 0xB1EC, 0x8199, 0xC476, 0x819A, 0xC477, - 0x819B, 0xCCC5, 0x819C, 0xC4A4, 0x819D, 0xCFA5, 0x819E, 0xC478, 0x819F, 0xC479, 0x81A0, 0xC47A, 0x81A1, 0xC47B, 0x81A2, 0xC47C, - 0x81A3, 0xEBF9, 0x81A4, 0xC47D, 0x81A5, 0xC47E, 0x81A6, 0xECA2, 0x81A7, 0xC480, 0x81A8, 0xC5F2, 0x81A9, 0xC481, 0x81AA, 0xEBFA, - 0x81AB, 0xC482, 0x81AC, 0xC483, 0x81AD, 0xC484, 0x81AE, 0xC485, 0x81AF, 0xC486, 0x81B0, 0xC487, 0x81B1, 0xC488, 0x81B2, 0xC489, - 0x81B3, 0xC9C5, 0x81B4, 0xC48A, 0x81B5, 0xC48B, 0x81B6, 0xC48C, 0x81B7, 0xC48D, 0x81B8, 0xC48E, 0x81B9, 0xC48F, 0x81BA, 0xE2DF, - 0x81BB, 0xEBFE, 0x81BC, 0xC490, 0x81BD, 0xC491, 0x81BE, 0xC492, 0x81BF, 0xC493, 0x81C0, 0xCDCE, 0x81C1, 0xECA1, 0x81C2, 0xB1DB, - 0x81C3, 0xD3B7, 0x81C4, 0xC494, 0x81C5, 0xC495, 0x81C6, 0xD2DC, 0x81C7, 0xC496, 0x81C8, 0xC497, 0x81C9, 0xC498, 0x81CA, 0xEBFD, - 0x81CB, 0xC499, 0x81CC, 0xEBFB, 0x81CD, 0xC49A, 0x81CE, 0xC49B, 0x81CF, 0xC49C, 0x81D0, 0xC49D, 0x81D1, 0xC49E, 0x81D2, 0xC49F, - 0x81D3, 0xC4A0, 0x81D4, 0xC540, 0x81D5, 0xC541, 0x81D6, 0xC542, 0x81D7, 0xC543, 0x81D8, 0xC544, 0x81D9, 0xC545, 0x81DA, 0xC546, - 0x81DB, 0xC547, 0x81DC, 0xC548, 0x81DD, 0xC549, 0x81DE, 0xC54A, 0x81DF, 0xC54B, 0x81E0, 0xC54C, 0x81E1, 0xC54D, 0x81E2, 0xC54E, - 0x81E3, 0xB3BC, 0x81E4, 0xC54F, 0x81E5, 0xC550, 0x81E6, 0xC551, 0x81E7, 0xEAB0, 0x81E8, 0xC552, 0x81E9, 0xC553, 0x81EA, 0xD7D4, - 0x81EB, 0xC554, 0x81EC, 0xF4AB, 0x81ED, 0xB3F4, 0x81EE, 0xC555, 0x81EF, 0xC556, 0x81F0, 0xC557, 0x81F1, 0xC558, 0x81F2, 0xC559, - 0x81F3, 0xD6C1, 0x81F4, 0xD6C2, 0x81F5, 0xC55A, 0x81F6, 0xC55B, 0x81F7, 0xC55C, 0x81F8, 0xC55D, 0x81F9, 0xC55E, 0x81FA, 0xC55F, - 0x81FB, 0xD5E9, 0x81FC, 0xBECA, 0x81FD, 0xC560, 0x81FE, 0xF4A7, 0x81FF, 0xC561, 0x8200, 0xD2A8, 0x8201, 0xF4A8, 0x8202, 0xF4A9, - 0x8203, 0xC562, 0x8204, 0xF4AA, 0x8205, 0xBECB, 0x8206, 0xD3DF, 0x8207, 0xC563, 0x8208, 0xC564, 0x8209, 0xC565, 0x820A, 0xC566, - 0x820B, 0xC567, 0x820C, 0xC9E0, 0x820D, 0xC9E1, 0x820E, 0xC568, 0x820F, 0xC569, 0x8210, 0xF3C2, 0x8211, 0xC56A, 0x8212, 0xCAE6, - 0x8213, 0xC56B, 0x8214, 0xCCF2, 0x8215, 0xC56C, 0x8216, 0xC56D, 0x8217, 0xC56E, 0x8218, 0xC56F, 0x8219, 0xC570, 0x821A, 0xC571, - 0x821B, 0xE2B6, 0x821C, 0xCBB4, 0x821D, 0xC572, 0x821E, 0xCEE8, 0x821F, 0xD6DB, 0x8220, 0xC573, 0x8221, 0xF4AD, 0x8222, 0xF4AE, - 0x8223, 0xF4AF, 0x8224, 0xC574, 0x8225, 0xC575, 0x8226, 0xC576, 0x8227, 0xC577, 0x8228, 0xF4B2, 0x8229, 0xC578, 0x822A, 0xBABD, - 0x822B, 0xF4B3, 0x822C, 0xB0E3, 0x822D, 0xF4B0, 0x822E, 0xC579, 0x822F, 0xF4B1, 0x8230, 0xBDA2, 0x8231, 0xB2D5, 0x8232, 0xC57A, - 0x8233, 0xF4B6, 0x8234, 0xF4B7, 0x8235, 0xB6E6, 0x8236, 0xB2B0, 0x8237, 0xCFCF, 0x8238, 0xF4B4, 0x8239, 0xB4AC, 0x823A, 0xC57B, - 0x823B, 0xF4B5, 0x823C, 0xC57C, 0x823D, 0xC57D, 0x823E, 0xF4B8, 0x823F, 0xC57E, 0x8240, 0xC580, 0x8241, 0xC581, 0x8242, 0xC582, - 0x8243, 0xC583, 0x8244, 0xF4B9, 0x8245, 0xC584, 0x8246, 0xC585, 0x8247, 0xCDA7, 0x8248, 0xC586, 0x8249, 0xF4BA, 0x824A, 0xC587, - 0x824B, 0xF4BB, 0x824C, 0xC588, 0x824D, 0xC589, 0x824E, 0xC58A, 0x824F, 0xF4BC, 0x8250, 0xC58B, 0x8251, 0xC58C, 0x8252, 0xC58D, - 0x8253, 0xC58E, 0x8254, 0xC58F, 0x8255, 0xC590, 0x8256, 0xC591, 0x8257, 0xC592, 0x8258, 0xCBD2, 0x8259, 0xC593, 0x825A, 0xF4BD, - 0x825B, 0xC594, 0x825C, 0xC595, 0x825D, 0xC596, 0x825E, 0xC597, 0x825F, 0xF4BE, 0x8260, 0xC598, 0x8261, 0xC599, 0x8262, 0xC59A, - 0x8263, 0xC59B, 0x8264, 0xC59C, 0x8265, 0xC59D, 0x8266, 0xC59E, 0x8267, 0xC59F, 0x8268, 0xF4BF, 0x8269, 0xC5A0, 0x826A, 0xC640, - 0x826B, 0xC641, 0x826C, 0xC642, 0x826D, 0xC643, 0x826E, 0xF4DE, 0x826F, 0xC1BC, 0x8270, 0xBCE8, 0x8271, 0xC644, 0x8272, 0xC9AB, - 0x8273, 0xD1DE, 0x8274, 0xE5F5, 0x8275, 0xC645, 0x8276, 0xC646, 0x8277, 0xC647, 0x8278, 0xC648, 0x8279, 0xDCB3, 0x827A, 0xD2D5, - 0x827B, 0xC649, 0x827C, 0xC64A, 0x827D, 0xDCB4, 0x827E, 0xB0AC, 0x827F, 0xDCB5, 0x8280, 0xC64B, 0x8281, 0xC64C, 0x8282, 0xBDDA, - 0x8283, 0xC64D, 0x8284, 0xDCB9, 0x8285, 0xC64E, 0x8286, 0xC64F, 0x8287, 0xC650, 0x8288, 0xD8C2, 0x8289, 0xC651, 0x828A, 0xDCB7, - 0x828B, 0xD3F3, 0x828C, 0xC652, 0x828D, 0xC9D6, 0x828E, 0xDCBA, 0x828F, 0xDCB6, 0x8290, 0xC653, 0x8291, 0xDCBB, 0x8292, 0xC3A2, - 0x8293, 0xC654, 0x8294, 0xC655, 0x8295, 0xC656, 0x8296, 0xC657, 0x8297, 0xDCBC, 0x8298, 0xDCC5, 0x8299, 0xDCBD, 0x829A, 0xC658, - 0x829B, 0xC659, 0x829C, 0xCEDF, 0x829D, 0xD6A5, 0x829E, 0xC65A, 0x829F, 0xDCCF, 0x82A0, 0xC65B, 0x82A1, 0xDCCD, 0x82A2, 0xC65C, - 0x82A3, 0xC65D, 0x82A4, 0xDCD2, 0x82A5, 0xBDE6, 0x82A6, 0xC2AB, 0x82A7, 0xC65E, 0x82A8, 0xDCB8, 0x82A9, 0xDCCB, 0x82AA, 0xDCCE, - 0x82AB, 0xDCBE, 0x82AC, 0xB7D2, 0x82AD, 0xB0C5, 0x82AE, 0xDCC7, 0x82AF, 0xD0BE, 0x82B0, 0xDCC1, 0x82B1, 0xBBA8, 0x82B2, 0xC65F, - 0x82B3, 0xB7BC, 0x82B4, 0xDCCC, 0x82B5, 0xC660, 0x82B6, 0xC661, 0x82B7, 0xDCC6, 0x82B8, 0xDCBF, 0x82B9, 0xC7DB, 0x82BA, 0xC662, - 0x82BB, 0xC663, 0x82BC, 0xC664, 0x82BD, 0xD1BF, 0x82BE, 0xDCC0, 0x82BF, 0xC665, 0x82C0, 0xC666, 0x82C1, 0xDCCA, 0x82C2, 0xC667, - 0x82C3, 0xC668, 0x82C4, 0xDCD0, 0x82C5, 0xC669, 0x82C6, 0xC66A, 0x82C7, 0xCEAD, 0x82C8, 0xDCC2, 0x82C9, 0xC66B, 0x82CA, 0xDCC3, - 0x82CB, 0xDCC8, 0x82CC, 0xDCC9, 0x82CD, 0xB2D4, 0x82CE, 0xDCD1, 0x82CF, 0xCBD5, 0x82D0, 0xC66C, 0x82D1, 0xD4B7, 0x82D2, 0xDCDB, - 0x82D3, 0xDCDF, 0x82D4, 0xCCA6, 0x82D5, 0xDCE6, 0x82D6, 0xC66D, 0x82D7, 0xC3E7, 0x82D8, 0xDCDC, 0x82D9, 0xC66E, 0x82DA, 0xC66F, - 0x82DB, 0xBFC1, 0x82DC, 0xDCD9, 0x82DD, 0xC670, 0x82DE, 0xB0FA, 0x82DF, 0xB9B6, 0x82E0, 0xDCE5, 0x82E1, 0xDCD3, 0x82E2, 0xC671, - 0x82E3, 0xDCC4, 0x82E4, 0xDCD6, 0x82E5, 0xC8F4, 0x82E6, 0xBFE0, 0x82E7, 0xC672, 0x82E8, 0xC673, 0x82E9, 0xC674, 0x82EA, 0xC675, - 0x82EB, 0xC9BB, 0x82EC, 0xC676, 0x82ED, 0xC677, 0x82EE, 0xC678, 0x82EF, 0xB1BD, 0x82F0, 0xC679, 0x82F1, 0xD3A2, 0x82F2, 0xC67A, - 0x82F3, 0xC67B, 0x82F4, 0xDCDA, 0x82F5, 0xC67C, 0x82F6, 0xC67D, 0x82F7, 0xDCD5, 0x82F8, 0xC67E, 0x82F9, 0xC6BB, 0x82FA, 0xC680, - 0x82FB, 0xDCDE, 0x82FC, 0xC681, 0x82FD, 0xC682, 0x82FE, 0xC683, 0x82FF, 0xC684, 0x8300, 0xC685, 0x8301, 0xD7C2, 0x8302, 0xC3AF, - 0x8303, 0xB7B6, 0x8304, 0xC7D1, 0x8305, 0xC3A9, 0x8306, 0xDCE2, 0x8307, 0xDCD8, 0x8308, 0xDCEB, 0x8309, 0xDCD4, 0x830A, 0xC686, - 0x830B, 0xC687, 0x830C, 0xDCDD, 0x830D, 0xC688, 0x830E, 0xBEA5, 0x830F, 0xDCD7, 0x8310, 0xC689, 0x8311, 0xDCE0, 0x8312, 0xC68A, - 0x8313, 0xC68B, 0x8314, 0xDCE3, 0x8315, 0xDCE4, 0x8316, 0xC68C, 0x8317, 0xDCF8, 0x8318, 0xC68D, 0x8319, 0xC68E, 0x831A, 0xDCE1, - 0x831B, 0xDDA2, 0x831C, 0xDCE7, 0x831D, 0xC68F, 0x831E, 0xC690, 0x831F, 0xC691, 0x8320, 0xC692, 0x8321, 0xC693, 0x8322, 0xC694, - 0x8323, 0xC695, 0x8324, 0xC696, 0x8325, 0xC697, 0x8326, 0xC698, 0x8327, 0xBCEB, 0x8328, 0xB4C4, 0x8329, 0xC699, 0x832A, 0xC69A, - 0x832B, 0xC3A3, 0x832C, 0xB2E7, 0x832D, 0xDCFA, 0x832E, 0xC69B, 0x832F, 0xDCF2, 0x8330, 0xC69C, 0x8331, 0xDCEF, 0x8332, 0xC69D, - 0x8333, 0xDCFC, 0x8334, 0xDCEE, 0x8335, 0xD2F0, 0x8336, 0xB2E8, 0x8337, 0xC69E, 0x8338, 0xC8D7, 0x8339, 0xC8E3, 0x833A, 0xDCFB, - 0x833B, 0xC69F, 0x833C, 0xDCED, 0x833D, 0xC6A0, 0x833E, 0xC740, 0x833F, 0xC741, 0x8340, 0xDCF7, 0x8341, 0xC742, 0x8342, 0xC743, - 0x8343, 0xDCF5, 0x8344, 0xC744, 0x8345, 0xC745, 0x8346, 0xBEA3, 0x8347, 0xDCF4, 0x8348, 0xC746, 0x8349, 0xB2DD, 0x834A, 0xC747, - 0x834B, 0xC748, 0x834C, 0xC749, 0x834D, 0xC74A, 0x834E, 0xC74B, 0x834F, 0xDCF3, 0x8350, 0xBCF6, 0x8351, 0xDCE8, 0x8352, 0xBBC4, - 0x8353, 0xC74C, 0x8354, 0xC0F3, 0x8355, 0xC74D, 0x8356, 0xC74E, 0x8357, 0xC74F, 0x8358, 0xC750, 0x8359, 0xC751, 0x835A, 0xBCD4, - 0x835B, 0xDCE9, 0x835C, 0xDCEA, 0x835D, 0xC752, 0x835E, 0xDCF1, 0x835F, 0xDCF6, 0x8360, 0xDCF9, 0x8361, 0xB5B4, 0x8362, 0xC753, - 0x8363, 0xC8D9, 0x8364, 0xBBE7, 0x8365, 0xDCFE, 0x8366, 0xDCFD, 0x8367, 0xD3AB, 0x8368, 0xDDA1, 0x8369, 0xDDA3, 0x836A, 0xDDA5, - 0x836B, 0xD2F1, 0x836C, 0xDDA4, 0x836D, 0xDDA6, 0x836E, 0xDDA7, 0x836F, 0xD2A9, 0x8370, 0xC754, 0x8371, 0xC755, 0x8372, 0xC756, - 0x8373, 0xC757, 0x8374, 0xC758, 0x8375, 0xC759, 0x8376, 0xC75A, 0x8377, 0xBAC9, 0x8378, 0xDDA9, 0x8379, 0xC75B, 0x837A, 0xC75C, - 0x837B, 0xDDB6, 0x837C, 0xDDB1, 0x837D, 0xDDB4, 0x837E, 0xC75D, 0x837F, 0xC75E, 0x8380, 0xC75F, 0x8381, 0xC760, 0x8382, 0xC761, - 0x8383, 0xC762, 0x8384, 0xC763, 0x8385, 0xDDB0, 0x8386, 0xC6CE, 0x8387, 0xC764, 0x8388, 0xC765, 0x8389, 0xC0F2, 0x838A, 0xC766, - 0x838B, 0xC767, 0x838C, 0xC768, 0x838D, 0xC769, 0x838E, 0xC9AF, 0x838F, 0xC76A, 0x8390, 0xC76B, 0x8391, 0xC76C, 0x8392, 0xDCEC, - 0x8393, 0xDDAE, 0x8394, 0xC76D, 0x8395, 0xC76E, 0x8396, 0xC76F, 0x8397, 0xC770, 0x8398, 0xDDB7, 0x8399, 0xC771, 0x839A, 0xC772, - 0x839B, 0xDCF0, 0x839C, 0xDDAF, 0x839D, 0xC773, 0x839E, 0xDDB8, 0x839F, 0xC774, 0x83A0, 0xDDAC, 0x83A1, 0xC775, 0x83A2, 0xC776, - 0x83A3, 0xC777, 0x83A4, 0xC778, 0x83A5, 0xC779, 0x83A6, 0xC77A, 0x83A7, 0xC77B, 0x83A8, 0xDDB9, 0x83A9, 0xDDB3, 0x83AA, 0xDDAD, - 0x83AB, 0xC4AA, 0x83AC, 0xC77C, 0x83AD, 0xC77D, 0x83AE, 0xC77E, 0x83AF, 0xC780, 0x83B0, 0xDDA8, 0x83B1, 0xC0B3, 0x83B2, 0xC1AB, - 0x83B3, 0xDDAA, 0x83B4, 0xDDAB, 0x83B5, 0xC781, 0x83B6, 0xDDB2, 0x83B7, 0xBBF1, 0x83B8, 0xDDB5, 0x83B9, 0xD3A8, 0x83BA, 0xDDBA, - 0x83BB, 0xC782, 0x83BC, 0xDDBB, 0x83BD, 0xC3A7, 0x83BE, 0xC783, 0x83BF, 0xC784, 0x83C0, 0xDDD2, 0x83C1, 0xDDBC, 0x83C2, 0xC785, - 0x83C3, 0xC786, 0x83C4, 0xC787, 0x83C5, 0xDDD1, 0x83C6, 0xC788, 0x83C7, 0xB9BD, 0x83C8, 0xC789, 0x83C9, 0xC78A, 0x83CA, 0xBED5, - 0x83CB, 0xC78B, 0x83CC, 0xBEFA, 0x83CD, 0xC78C, 0x83CE, 0xC78D, 0x83CF, 0xBACA, 0x83D0, 0xC78E, 0x83D1, 0xC78F, 0x83D2, 0xC790, - 0x83D3, 0xC791, 0x83D4, 0xDDCA, 0x83D5, 0xC792, 0x83D6, 0xDDC5, 0x83D7, 0xC793, 0x83D8, 0xDDBF, 0x83D9, 0xC794, 0x83DA, 0xC795, - 0x83DB, 0xC796, 0x83DC, 0xB2CB, 0x83DD, 0xDDC3, 0x83DE, 0xC797, 0x83DF, 0xDDCB, 0x83E0, 0xB2A4, 0x83E1, 0xDDD5, 0x83E2, 0xC798, - 0x83E3, 0xC799, 0x83E4, 0xC79A, 0x83E5, 0xDDBE, 0x83E6, 0xC79B, 0x83E7, 0xC79C, 0x83E8, 0xC79D, 0x83E9, 0xC6D0, 0x83EA, 0xDDD0, - 0x83EB, 0xC79E, 0x83EC, 0xC79F, 0x83ED, 0xC7A0, 0x83EE, 0xC840, 0x83EF, 0xC841, 0x83F0, 0xDDD4, 0x83F1, 0xC1E2, 0x83F2, 0xB7C6, - 0x83F3, 0xC842, 0x83F4, 0xC843, 0x83F5, 0xC844, 0x83F6, 0xC845, 0x83F7, 0xC846, 0x83F8, 0xDDCE, 0x83F9, 0xDDCF, 0x83FA, 0xC847, - 0x83FB, 0xC848, 0x83FC, 0xC849, 0x83FD, 0xDDC4, 0x83FE, 0xC84A, 0x83FF, 0xC84B, 0x8400, 0xC84C, 0x8401, 0xDDBD, 0x8402, 0xC84D, - 0x8403, 0xDDCD, 0x8404, 0xCCD1, 0x8405, 0xC84E, 0x8406, 0xDDC9, 0x8407, 0xC84F, 0x8408, 0xC850, 0x8409, 0xC851, 0x840A, 0xC852, - 0x840B, 0xDDC2, 0x840C, 0xC3C8, 0x840D, 0xC6BC, 0x840E, 0xCEAE, 0x840F, 0xDDCC, 0x8410, 0xC853, 0x8411, 0xDDC8, 0x8412, 0xC854, - 0x8413, 0xC855, 0x8414, 0xC856, 0x8415, 0xC857, 0x8416, 0xC858, 0x8417, 0xC859, 0x8418, 0xDDC1, 0x8419, 0xC85A, 0x841A, 0xC85B, - 0x841B, 0xC85C, 0x841C, 0xDDC6, 0x841D, 0xC2DC, 0x841E, 0xC85D, 0x841F, 0xC85E, 0x8420, 0xC85F, 0x8421, 0xC860, 0x8422, 0xC861, - 0x8423, 0xC862, 0x8424, 0xD3A9, 0x8425, 0xD3AA, 0x8426, 0xDDD3, 0x8427, 0xCFF4, 0x8428, 0xC8F8, 0x8429, 0xC863, 0x842A, 0xC864, - 0x842B, 0xC865, 0x842C, 0xC866, 0x842D, 0xC867, 0x842E, 0xC868, 0x842F, 0xC869, 0x8430, 0xC86A, 0x8431, 0xDDE6, 0x8432, 0xC86B, - 0x8433, 0xC86C, 0x8434, 0xC86D, 0x8435, 0xC86E, 0x8436, 0xC86F, 0x8437, 0xC870, 0x8438, 0xDDC7, 0x8439, 0xC871, 0x843A, 0xC872, - 0x843B, 0xC873, 0x843C, 0xDDE0, 0x843D, 0xC2E4, 0x843E, 0xC874, 0x843F, 0xC875, 0x8440, 0xC876, 0x8441, 0xC877, 0x8442, 0xC878, - 0x8443, 0xC879, 0x8444, 0xC87A, 0x8445, 0xC87B, 0x8446, 0xDDE1, 0x8447, 0xC87C, 0x8448, 0xC87D, 0x8449, 0xC87E, 0x844A, 0xC880, - 0x844B, 0xC881, 0x844C, 0xC882, 0x844D, 0xC883, 0x844E, 0xC884, 0x844F, 0xC885, 0x8450, 0xC886, 0x8451, 0xDDD7, 0x8452, 0xC887, - 0x8453, 0xC888, 0x8454, 0xC889, 0x8455, 0xC88A, 0x8456, 0xC88B, 0x8457, 0xD6F8, 0x8458, 0xC88C, 0x8459, 0xDDD9, 0x845A, 0xDDD8, - 0x845B, 0xB8F0, 0x845C, 0xDDD6, 0x845D, 0xC88D, 0x845E, 0xC88E, 0x845F, 0xC88F, 0x8460, 0xC890, 0x8461, 0xC6CF, 0x8462, 0xC891, - 0x8463, 0xB6AD, 0x8464, 0xC892, 0x8465, 0xC893, 0x8466, 0xC894, 0x8467, 0xC895, 0x8468, 0xC896, 0x8469, 0xDDE2, 0x846A, 0xC897, - 0x846B, 0xBAF9, 0x846C, 0xD4E1, 0x846D, 0xDDE7, 0x846E, 0xC898, 0x846F, 0xC899, 0x8470, 0xC89A, 0x8471, 0xB4D0, 0x8472, 0xC89B, - 0x8473, 0xDDDA, 0x8474, 0xC89C, 0x8475, 0xBFFB, 0x8476, 0xDDE3, 0x8477, 0xC89D, 0x8478, 0xDDDF, 0x8479, 0xC89E, 0x847A, 0xDDDD, - 0x847B, 0xC89F, 0x847C, 0xC8A0, 0x847D, 0xC940, 0x847E, 0xC941, 0x847F, 0xC942, 0x8480, 0xC943, 0x8481, 0xC944, 0x8482, 0xB5D9, - 0x8483, 0xC945, 0x8484, 0xC946, 0x8485, 0xC947, 0x8486, 0xC948, 0x8487, 0xDDDB, 0x8488, 0xDDDC, 0x8489, 0xDDDE, 0x848A, 0xC949, - 0x848B, 0xBDAF, 0x848C, 0xDDE4, 0x848D, 0xC94A, 0x848E, 0xDDE5, 0x848F, 0xC94B, 0x8490, 0xC94C, 0x8491, 0xC94D, 0x8492, 0xC94E, - 0x8493, 0xC94F, 0x8494, 0xC950, 0x8495, 0xC951, 0x8496, 0xC952, 0x8497, 0xDDF5, 0x8498, 0xC953, 0x8499, 0xC3C9, 0x849A, 0xC954, - 0x849B, 0xC955, 0x849C, 0xCBE2, 0x849D, 0xC956, 0x849E, 0xC957, 0x849F, 0xC958, 0x84A0, 0xC959, 0x84A1, 0xDDF2, 0x84A2, 0xC95A, - 0x84A3, 0xC95B, 0x84A4, 0xC95C, 0x84A5, 0xC95D, 0x84A6, 0xC95E, 0x84A7, 0xC95F, 0x84A8, 0xC960, 0x84A9, 0xC961, 0x84AA, 0xC962, - 0x84AB, 0xC963, 0x84AC, 0xC964, 0x84AD, 0xC965, 0x84AE, 0xC966, 0x84AF, 0xD8E1, 0x84B0, 0xC967, 0x84B1, 0xC968, 0x84B2, 0xC6D1, - 0x84B3, 0xC969, 0x84B4, 0xDDF4, 0x84B5, 0xC96A, 0x84B6, 0xC96B, 0x84B7, 0xC96C, 0x84B8, 0xD5F4, 0x84B9, 0xDDF3, 0x84BA, 0xDDF0, - 0x84BB, 0xC96D, 0x84BC, 0xC96E, 0x84BD, 0xDDEC, 0x84BE, 0xC96F, 0x84BF, 0xDDEF, 0x84C0, 0xC970, 0x84C1, 0xDDE8, 0x84C2, 0xC971, - 0x84C3, 0xC972, 0x84C4, 0xD0EE, 0x84C5, 0xC973, 0x84C6, 0xC974, 0x84C7, 0xC975, 0x84C8, 0xC976, 0x84C9, 0xC8D8, 0x84CA, 0xDDEE, - 0x84CB, 0xC977, 0x84CC, 0xC978, 0x84CD, 0xDDE9, 0x84CE, 0xC979, 0x84CF, 0xC97A, 0x84D0, 0xDDEA, 0x84D1, 0xCBF2, 0x84D2, 0xC97B, - 0x84D3, 0xDDED, 0x84D4, 0xC97C, 0x84D5, 0xC97D, 0x84D6, 0xB1CD, 0x84D7, 0xC97E, 0x84D8, 0xC980, 0x84D9, 0xC981, 0x84DA, 0xC982, - 0x84DB, 0xC983, 0x84DC, 0xC984, 0x84DD, 0xC0B6, 0x84DE, 0xC985, 0x84DF, 0xBCBB, 0x84E0, 0xDDF1, 0x84E1, 0xC986, 0x84E2, 0xC987, - 0x84E3, 0xDDF7, 0x84E4, 0xC988, 0x84E5, 0xDDF6, 0x84E6, 0xDDEB, 0x84E7, 0xC989, 0x84E8, 0xC98A, 0x84E9, 0xC98B, 0x84EA, 0xC98C, - 0x84EB, 0xC98D, 0x84EC, 0xC5EE, 0x84ED, 0xC98E, 0x84EE, 0xC98F, 0x84EF, 0xC990, 0x84F0, 0xDDFB, 0x84F1, 0xC991, 0x84F2, 0xC992, - 0x84F3, 0xC993, 0x84F4, 0xC994, 0x84F5, 0xC995, 0x84F6, 0xC996, 0x84F7, 0xC997, 0x84F8, 0xC998, 0x84F9, 0xC999, 0x84FA, 0xC99A, - 0x84FB, 0xC99B, 0x84FC, 0xDEA4, 0x84FD, 0xC99C, 0x84FE, 0xC99D, 0x84FF, 0xDEA3, 0x8500, 0xC99E, 0x8501, 0xC99F, 0x8502, 0xC9A0, - 0x8503, 0xCA40, 0x8504, 0xCA41, 0x8505, 0xCA42, 0x8506, 0xCA43, 0x8507, 0xCA44, 0x8508, 0xCA45, 0x8509, 0xCA46, 0x850A, 0xCA47, - 0x850B, 0xCA48, 0x850C, 0xDDF8, 0x850D, 0xCA49, 0x850E, 0xCA4A, 0x850F, 0xCA4B, 0x8510, 0xCA4C, 0x8511, 0xC3EF, 0x8512, 0xCA4D, - 0x8513, 0xC2FB, 0x8514, 0xCA4E, 0x8515, 0xCA4F, 0x8516, 0xCA50, 0x8517, 0xD5E1, 0x8518, 0xCA51, 0x8519, 0xCA52, 0x851A, 0xCEB5, - 0x851B, 0xCA53, 0x851C, 0xCA54, 0x851D, 0xCA55, 0x851E, 0xCA56, 0x851F, 0xDDFD, 0x8520, 0xCA57, 0x8521, 0xB2CC, 0x8522, 0xCA58, - 0x8523, 0xCA59, 0x8524, 0xCA5A, 0x8525, 0xCA5B, 0x8526, 0xCA5C, 0x8527, 0xCA5D, 0x8528, 0xCA5E, 0x8529, 0xCA5F, 0x852A, 0xCA60, - 0x852B, 0xC4E8, 0x852C, 0xCADF, 0x852D, 0xCA61, 0x852E, 0xCA62, 0x852F, 0xCA63, 0x8530, 0xCA64, 0x8531, 0xCA65, 0x8532, 0xCA66, - 0x8533, 0xCA67, 0x8534, 0xCA68, 0x8535, 0xCA69, 0x8536, 0xCA6A, 0x8537, 0xC7BE, 0x8538, 0xDDFA, 0x8539, 0xDDFC, 0x853A, 0xDDFE, - 0x853B, 0xDEA2, 0x853C, 0xB0AA, 0x853D, 0xB1CE, 0x853E, 0xCA6B, 0x853F, 0xCA6C, 0x8540, 0xCA6D, 0x8541, 0xCA6E, 0x8542, 0xCA6F, - 0x8543, 0xDEAC, 0x8544, 0xCA70, 0x8545, 0xCA71, 0x8546, 0xCA72, 0x8547, 0xCA73, 0x8548, 0xDEA6, 0x8549, 0xBDB6, 0x854A, 0xC8EF, - 0x854B, 0xCA74, 0x854C, 0xCA75, 0x854D, 0xCA76, 0x854E, 0xCA77, 0x854F, 0xCA78, 0x8550, 0xCA79, 0x8551, 0xCA7A, 0x8552, 0xCA7B, - 0x8553, 0xCA7C, 0x8554, 0xCA7D, 0x8555, 0xCA7E, 0x8556, 0xDEA1, 0x8557, 0xCA80, 0x8558, 0xCA81, 0x8559, 0xDEA5, 0x855A, 0xCA82, - 0x855B, 0xCA83, 0x855C, 0xCA84, 0x855D, 0xCA85, 0x855E, 0xDEA9, 0x855F, 0xCA86, 0x8560, 0xCA87, 0x8561, 0xCA88, 0x8562, 0xCA89, - 0x8563, 0xCA8A, 0x8564, 0xDEA8, 0x8565, 0xCA8B, 0x8566, 0xCA8C, 0x8567, 0xCA8D, 0x8568, 0xDEA7, 0x8569, 0xCA8E, 0x856A, 0xCA8F, - 0x856B, 0xCA90, 0x856C, 0xCA91, 0x856D, 0xCA92, 0x856E, 0xCA93, 0x856F, 0xCA94, 0x8570, 0xCA95, 0x8571, 0xCA96, 0x8572, 0xDEAD, - 0x8573, 0xCA97, 0x8574, 0xD4CC, 0x8575, 0xCA98, 0x8576, 0xCA99, 0x8577, 0xCA9A, 0x8578, 0xCA9B, 0x8579, 0xDEB3, 0x857A, 0xDEAA, - 0x857B, 0xDEAE, 0x857C, 0xCA9C, 0x857D, 0xCA9D, 0x857E, 0xC0D9, 0x857F, 0xCA9E, 0x8580, 0xCA9F, 0x8581, 0xCAA0, 0x8582, 0xCB40, - 0x8583, 0xCB41, 0x8584, 0xB1A1, 0x8585, 0xDEB6, 0x8586, 0xCB42, 0x8587, 0xDEB1, 0x8588, 0xCB43, 0x8589, 0xCB44, 0x858A, 0xCB45, - 0x858B, 0xCB46, 0x858C, 0xCB47, 0x858D, 0xCB48, 0x858E, 0xCB49, 0x858F, 0xDEB2, 0x8590, 0xCB4A, 0x8591, 0xCB4B, 0x8592, 0xCB4C, - 0x8593, 0xCB4D, 0x8594, 0xCB4E, 0x8595, 0xCB4F, 0x8596, 0xCB50, 0x8597, 0xCB51, 0x8598, 0xCB52, 0x8599, 0xCB53, 0x859A, 0xCB54, - 0x859B, 0xD1A6, 0x859C, 0xDEB5, 0x859D, 0xCB55, 0x859E, 0xCB56, 0x859F, 0xCB57, 0x85A0, 0xCB58, 0x85A1, 0xCB59, 0x85A2, 0xCB5A, - 0x85A3, 0xCB5B, 0x85A4, 0xDEAF, 0x85A5, 0xCB5C, 0x85A6, 0xCB5D, 0x85A7, 0xCB5E, 0x85A8, 0xDEB0, 0x85A9, 0xCB5F, 0x85AA, 0xD0BD, - 0x85AB, 0xCB60, 0x85AC, 0xCB61, 0x85AD, 0xCB62, 0x85AE, 0xDEB4, 0x85AF, 0xCAED, 0x85B0, 0xDEB9, 0x85B1, 0xCB63, 0x85B2, 0xCB64, - 0x85B3, 0xCB65, 0x85B4, 0xCB66, 0x85B5, 0xCB67, 0x85B6, 0xCB68, 0x85B7, 0xDEB8, 0x85B8, 0xCB69, 0x85B9, 0xDEB7, 0x85BA, 0xCB6A, - 0x85BB, 0xCB6B, 0x85BC, 0xCB6C, 0x85BD, 0xCB6D, 0x85BE, 0xCB6E, 0x85BF, 0xCB6F, 0x85C0, 0xCB70, 0x85C1, 0xDEBB, 0x85C2, 0xCB71, - 0x85C3, 0xCB72, 0x85C4, 0xCB73, 0x85C5, 0xCB74, 0x85C6, 0xCB75, 0x85C7, 0xCB76, 0x85C8, 0xCB77, 0x85C9, 0xBDE5, 0x85CA, 0xCB78, - 0x85CB, 0xCB79, 0x85CC, 0xCB7A, 0x85CD, 0xCB7B, 0x85CE, 0xCB7C, 0x85CF, 0xB2D8, 0x85D0, 0xC3EA, 0x85D1, 0xCB7D, 0x85D2, 0xCB7E, - 0x85D3, 0xDEBA, 0x85D4, 0xCB80, 0x85D5, 0xC5BA, 0x85D6, 0xCB81, 0x85D7, 0xCB82, 0x85D8, 0xCB83, 0x85D9, 0xCB84, 0x85DA, 0xCB85, - 0x85DB, 0xCB86, 0x85DC, 0xDEBC, 0x85DD, 0xCB87, 0x85DE, 0xCB88, 0x85DF, 0xCB89, 0x85E0, 0xCB8A, 0x85E1, 0xCB8B, 0x85E2, 0xCB8C, - 0x85E3, 0xCB8D, 0x85E4, 0xCCD9, 0x85E5, 0xCB8E, 0x85E6, 0xCB8F, 0x85E7, 0xCB90, 0x85E8, 0xCB91, 0x85E9, 0xB7AA, 0x85EA, 0xCB92, - 0x85EB, 0xCB93, 0x85EC, 0xCB94, 0x85ED, 0xCB95, 0x85EE, 0xCB96, 0x85EF, 0xCB97, 0x85F0, 0xCB98, 0x85F1, 0xCB99, 0x85F2, 0xCB9A, - 0x85F3, 0xCB9B, 0x85F4, 0xCB9C, 0x85F5, 0xCB9D, 0x85F6, 0xCB9E, 0x85F7, 0xCB9F, 0x85F8, 0xCBA0, 0x85F9, 0xCC40, 0x85FA, 0xCC41, - 0x85FB, 0xD4E5, 0x85FC, 0xCC42, 0x85FD, 0xCC43, 0x85FE, 0xCC44, 0x85FF, 0xDEBD, 0x8600, 0xCC45, 0x8601, 0xCC46, 0x8602, 0xCC47, - 0x8603, 0xCC48, 0x8604, 0xCC49, 0x8605, 0xDEBF, 0x8606, 0xCC4A, 0x8607, 0xCC4B, 0x8608, 0xCC4C, 0x8609, 0xCC4D, 0x860A, 0xCC4E, - 0x860B, 0xCC4F, 0x860C, 0xCC50, 0x860D, 0xCC51, 0x860E, 0xCC52, 0x860F, 0xCC53, 0x8610, 0xCC54, 0x8611, 0xC4A2, 0x8612, 0xCC55, - 0x8613, 0xCC56, 0x8614, 0xCC57, 0x8615, 0xCC58, 0x8616, 0xDEC1, 0x8617, 0xCC59, 0x8618, 0xCC5A, 0x8619, 0xCC5B, 0x861A, 0xCC5C, - 0x861B, 0xCC5D, 0x861C, 0xCC5E, 0x861D, 0xCC5F, 0x861E, 0xCC60, 0x861F, 0xCC61, 0x8620, 0xCC62, 0x8621, 0xCC63, 0x8622, 0xCC64, - 0x8623, 0xCC65, 0x8624, 0xCC66, 0x8625, 0xCC67, 0x8626, 0xCC68, 0x8627, 0xDEBE, 0x8628, 0xCC69, 0x8629, 0xDEC0, 0x862A, 0xCC6A, - 0x862B, 0xCC6B, 0x862C, 0xCC6C, 0x862D, 0xCC6D, 0x862E, 0xCC6E, 0x862F, 0xCC6F, 0x8630, 0xCC70, 0x8631, 0xCC71, 0x8632, 0xCC72, - 0x8633, 0xCC73, 0x8634, 0xCC74, 0x8635, 0xCC75, 0x8636, 0xCC76, 0x8637, 0xCC77, 0x8638, 0xD5BA, 0x8639, 0xCC78, 0x863A, 0xCC79, - 0x863B, 0xCC7A, 0x863C, 0xDEC2, 0x863D, 0xCC7B, 0x863E, 0xCC7C, 0x863F, 0xCC7D, 0x8640, 0xCC7E, 0x8641, 0xCC80, 0x8642, 0xCC81, - 0x8643, 0xCC82, 0x8644, 0xCC83, 0x8645, 0xCC84, 0x8646, 0xCC85, 0x8647, 0xCC86, 0x8648, 0xCC87, 0x8649, 0xCC88, 0x864A, 0xCC89, - 0x864B, 0xCC8A, 0x864C, 0xCC8B, 0x864D, 0xF2AE, 0x864E, 0xBBA2, 0x864F, 0xC2B2, 0x8650, 0xC5B0, 0x8651, 0xC2C7, 0x8652, 0xCC8C, - 0x8653, 0xCC8D, 0x8654, 0xF2AF, 0x8655, 0xCC8E, 0x8656, 0xCC8F, 0x8657, 0xCC90, 0x8658, 0xCC91, 0x8659, 0xCC92, 0x865A, 0xD0E9, - 0x865B, 0xCC93, 0x865C, 0xCC94, 0x865D, 0xCC95, 0x865E, 0xD3DD, 0x865F, 0xCC96, 0x8660, 0xCC97, 0x8661, 0xCC98, 0x8662, 0xEBBD, - 0x8663, 0xCC99, 0x8664, 0xCC9A, 0x8665, 0xCC9B, 0x8666, 0xCC9C, 0x8667, 0xCC9D, 0x8668, 0xCC9E, 0x8669, 0xCC9F, 0x866A, 0xCCA0, - 0x866B, 0xB3E6, 0x866C, 0xF2B0, 0x866D, 0xCD40, 0x866E, 0xF2B1, 0x866F, 0xCD41, 0x8670, 0xCD42, 0x8671, 0xCAAD, 0x8672, 0xCD43, - 0x8673, 0xCD44, 0x8674, 0xCD45, 0x8675, 0xCD46, 0x8676, 0xCD47, 0x8677, 0xCD48, 0x8678, 0xCD49, 0x8679, 0xBAE7, 0x867A, 0xF2B3, - 0x867B, 0xF2B5, 0x867C, 0xF2B4, 0x867D, 0xCBE4, 0x867E, 0xCFBA, 0x867F, 0xF2B2, 0x8680, 0xCAB4, 0x8681, 0xD2CF, 0x8682, 0xC2EC, - 0x8683, 0xCD4A, 0x8684, 0xCD4B, 0x8685, 0xCD4C, 0x8686, 0xCD4D, 0x8687, 0xCD4E, 0x8688, 0xCD4F, 0x8689, 0xCD50, 0x868A, 0xCEC3, - 0x868B, 0xF2B8, 0x868C, 0xB0F6, 0x868D, 0xF2B7, 0x868E, 0xCD51, 0x868F, 0xCD52, 0x8690, 0xCD53, 0x8691, 0xCD54, 0x8692, 0xCD55, - 0x8693, 0xF2BE, 0x8694, 0xCD56, 0x8695, 0xB2CF, 0x8696, 0xCD57, 0x8697, 0xCD58, 0x8698, 0xCD59, 0x8699, 0xCD5A, 0x869A, 0xCD5B, - 0x869B, 0xCD5C, 0x869C, 0xD1C1, 0x869D, 0xF2BA, 0x869E, 0xCD5D, 0x869F, 0xCD5E, 0x86A0, 0xCD5F, 0x86A1, 0xCD60, 0x86A2, 0xCD61, - 0x86A3, 0xF2BC, 0x86A4, 0xD4E9, 0x86A5, 0xCD62, 0x86A6, 0xCD63, 0x86A7, 0xF2BB, 0x86A8, 0xF2B6, 0x86A9, 0xF2BF, 0x86AA, 0xF2BD, - 0x86AB, 0xCD64, 0x86AC, 0xF2B9, 0x86AD, 0xCD65, 0x86AE, 0xCD66, 0x86AF, 0xF2C7, 0x86B0, 0xF2C4, 0x86B1, 0xF2C6, 0x86B2, 0xCD67, - 0x86B3, 0xCD68, 0x86B4, 0xF2CA, 0x86B5, 0xF2C2, 0x86B6, 0xF2C0, 0x86B7, 0xCD69, 0x86B8, 0xCD6A, 0x86B9, 0xCD6B, 0x86BA, 0xF2C5, - 0x86BB, 0xCD6C, 0x86BC, 0xCD6D, 0x86BD, 0xCD6E, 0x86BE, 0xCD6F, 0x86BF, 0xCD70, 0x86C0, 0xD6FB, 0x86C1, 0xCD71, 0x86C2, 0xCD72, - 0x86C3, 0xCD73, 0x86C4, 0xF2C1, 0x86C5, 0xCD74, 0x86C6, 0xC7F9, 0x86C7, 0xC9DF, 0x86C8, 0xCD75, 0x86C9, 0xF2C8, 0x86CA, 0xB9C6, - 0x86CB, 0xB5B0, 0x86CC, 0xCD76, 0x86CD, 0xCD77, 0x86CE, 0xF2C3, 0x86CF, 0xF2C9, 0x86D0, 0xF2D0, 0x86D1, 0xF2D6, 0x86D2, 0xCD78, - 0x86D3, 0xCD79, 0x86D4, 0xBBD7, 0x86D5, 0xCD7A, 0x86D6, 0xCD7B, 0x86D7, 0xCD7C, 0x86D8, 0xF2D5, 0x86D9, 0xCDDC, 0x86DA, 0xCD7D, - 0x86DB, 0xD6EB, 0x86DC, 0xCD7E, 0x86DD, 0xCD80, 0x86DE, 0xF2D2, 0x86DF, 0xF2D4, 0x86E0, 0xCD81, 0x86E1, 0xCD82, 0x86E2, 0xCD83, - 0x86E3, 0xCD84, 0x86E4, 0xB8F2, 0x86E5, 0xCD85, 0x86E6, 0xCD86, 0x86E7, 0xCD87, 0x86E8, 0xCD88, 0x86E9, 0xF2CB, 0x86EA, 0xCD89, - 0x86EB, 0xCD8A, 0x86EC, 0xCD8B, 0x86ED, 0xF2CE, 0x86EE, 0xC2F9, 0x86EF, 0xCD8C, 0x86F0, 0xD5DD, 0x86F1, 0xF2CC, 0x86F2, 0xF2CD, - 0x86F3, 0xF2CF, 0x86F4, 0xF2D3, 0x86F5, 0xCD8D, 0x86F6, 0xCD8E, 0x86F7, 0xCD8F, 0x86F8, 0xF2D9, 0x86F9, 0xD3BC, 0x86FA, 0xCD90, - 0x86FB, 0xCD91, 0x86FC, 0xCD92, 0x86FD, 0xCD93, 0x86FE, 0xB6EA, 0x86FF, 0xCD94, 0x8700, 0xCAF1, 0x8701, 0xCD95, 0x8702, 0xB7E4, - 0x8703, 0xF2D7, 0x8704, 0xCD96, 0x8705, 0xCD97, 0x8706, 0xCD98, 0x8707, 0xF2D8, 0x8708, 0xF2DA, 0x8709, 0xF2DD, 0x870A, 0xF2DB, - 0x870B, 0xCD99, 0x870C, 0xCD9A, 0x870D, 0xF2DC, 0x870E, 0xCD9B, 0x870F, 0xCD9C, 0x8710, 0xCD9D, 0x8711, 0xCD9E, 0x8712, 0xD1D1, - 0x8713, 0xF2D1, 0x8714, 0xCD9F, 0x8715, 0xCDC9, 0x8716, 0xCDA0, 0x8717, 0xCECF, 0x8718, 0xD6A9, 0x8719, 0xCE40, 0x871A, 0xF2E3, - 0x871B, 0xCE41, 0x871C, 0xC3DB, 0x871D, 0xCE42, 0x871E, 0xF2E0, 0x871F, 0xCE43, 0x8720, 0xCE44, 0x8721, 0xC0AF, 0x8722, 0xF2EC, - 0x8723, 0xF2DE, 0x8724, 0xCE45, 0x8725, 0xF2E1, 0x8726, 0xCE46, 0x8727, 0xCE47, 0x8728, 0xCE48, 0x8729, 0xF2E8, 0x872A, 0xCE49, - 0x872B, 0xCE4A, 0x872C, 0xCE4B, 0x872D, 0xCE4C, 0x872E, 0xF2E2, 0x872F, 0xCE4D, 0x8730, 0xCE4E, 0x8731, 0xF2E7, 0x8732, 0xCE4F, - 0x8733, 0xCE50, 0x8734, 0xF2E6, 0x8735, 0xCE51, 0x8736, 0xCE52, 0x8737, 0xF2E9, 0x8738, 0xCE53, 0x8739, 0xCE54, 0x873A, 0xCE55, - 0x873B, 0xF2DF, 0x873C, 0xCE56, 0x873D, 0xCE57, 0x873E, 0xF2E4, 0x873F, 0xF2EA, 0x8740, 0xCE58, 0x8741, 0xCE59, 0x8742, 0xCE5A, - 0x8743, 0xCE5B, 0x8744, 0xCE5C, 0x8745, 0xCE5D, 0x8746, 0xCE5E, 0x8747, 0xD3AC, 0x8748, 0xF2E5, 0x8749, 0xB2F5, 0x874A, 0xCE5F, - 0x874B, 0xCE60, 0x874C, 0xF2F2, 0x874D, 0xCE61, 0x874E, 0xD0AB, 0x874F, 0xCE62, 0x8750, 0xCE63, 0x8751, 0xCE64, 0x8752, 0xCE65, - 0x8753, 0xF2F5, 0x8754, 0xCE66, 0x8755, 0xCE67, 0x8756, 0xCE68, 0x8757, 0xBBC8, 0x8758, 0xCE69, 0x8759, 0xF2F9, 0x875A, 0xCE6A, - 0x875B, 0xCE6B, 0x875C, 0xCE6C, 0x875D, 0xCE6D, 0x875E, 0xCE6E, 0x875F, 0xCE6F, 0x8760, 0xF2F0, 0x8761, 0xCE70, 0x8762, 0xCE71, - 0x8763, 0xF2F6, 0x8764, 0xF2F8, 0x8765, 0xF2FA, 0x8766, 0xCE72, 0x8767, 0xCE73, 0x8768, 0xCE74, 0x8769, 0xCE75, 0x876A, 0xCE76, - 0x876B, 0xCE77, 0x876C, 0xCE78, 0x876D, 0xCE79, 0x876E, 0xF2F3, 0x876F, 0xCE7A, 0x8770, 0xF2F1, 0x8771, 0xCE7B, 0x8772, 0xCE7C, - 0x8773, 0xCE7D, 0x8774, 0xBAFB, 0x8775, 0xCE7E, 0x8776, 0xB5FB, 0x8777, 0xCE80, 0x8778, 0xCE81, 0x8779, 0xCE82, 0x877A, 0xCE83, - 0x877B, 0xF2EF, 0x877C, 0xF2F7, 0x877D, 0xF2ED, 0x877E, 0xF2EE, 0x877F, 0xCE84, 0x8780, 0xCE85, 0x8781, 0xCE86, 0x8782, 0xF2EB, - 0x8783, 0xF3A6, 0x8784, 0xCE87, 0x8785, 0xF3A3, 0x8786, 0xCE88, 0x8787, 0xCE89, 0x8788, 0xF3A2, 0x8789, 0xCE8A, 0x878A, 0xCE8B, - 0x878B, 0xF2F4, 0x878C, 0xCE8C, 0x878D, 0xC8DA, 0x878E, 0xCE8D, 0x878F, 0xCE8E, 0x8790, 0xCE8F, 0x8791, 0xCE90, 0x8792, 0xCE91, - 0x8793, 0xF2FB, 0x8794, 0xCE92, 0x8795, 0xCE93, 0x8796, 0xCE94, 0x8797, 0xF3A5, 0x8798, 0xCE95, 0x8799, 0xCE96, 0x879A, 0xCE97, - 0x879B, 0xCE98, 0x879C, 0xCE99, 0x879D, 0xCE9A, 0x879E, 0xCE9B, 0x879F, 0xC3F8, 0x87A0, 0xCE9C, 0x87A1, 0xCE9D, 0x87A2, 0xCE9E, - 0x87A3, 0xCE9F, 0x87A4, 0xCEA0, 0x87A5, 0xCF40, 0x87A6, 0xCF41, 0x87A7, 0xCF42, 0x87A8, 0xF2FD, 0x87A9, 0xCF43, 0x87AA, 0xCF44, - 0x87AB, 0xF3A7, 0x87AC, 0xF3A9, 0x87AD, 0xF3A4, 0x87AE, 0xCF45, 0x87AF, 0xF2FC, 0x87B0, 0xCF46, 0x87B1, 0xCF47, 0x87B2, 0xCF48, - 0x87B3, 0xF3AB, 0x87B4, 0xCF49, 0x87B5, 0xF3AA, 0x87B6, 0xCF4A, 0x87B7, 0xCF4B, 0x87B8, 0xCF4C, 0x87B9, 0xCF4D, 0x87BA, 0xC2DD, - 0x87BB, 0xCF4E, 0x87BC, 0xCF4F, 0x87BD, 0xF3AE, 0x87BE, 0xCF50, 0x87BF, 0xCF51, 0x87C0, 0xF3B0, 0x87C1, 0xCF52, 0x87C2, 0xCF53, - 0x87C3, 0xCF54, 0x87C4, 0xCF55, 0x87C5, 0xCF56, 0x87C6, 0xF3A1, 0x87C7, 0xCF57, 0x87C8, 0xCF58, 0x87C9, 0xCF59, 0x87CA, 0xF3B1, - 0x87CB, 0xF3AC, 0x87CC, 0xCF5A, 0x87CD, 0xCF5B, 0x87CE, 0xCF5C, 0x87CF, 0xCF5D, 0x87D0, 0xCF5E, 0x87D1, 0xF3AF, 0x87D2, 0xF2FE, - 0x87D3, 0xF3AD, 0x87D4, 0xCF5F, 0x87D5, 0xCF60, 0x87D6, 0xCF61, 0x87D7, 0xCF62, 0x87D8, 0xCF63, 0x87D9, 0xCF64, 0x87DA, 0xCF65, - 0x87DB, 0xF3B2, 0x87DC, 0xCF66, 0x87DD, 0xCF67, 0x87DE, 0xCF68, 0x87DF, 0xCF69, 0x87E0, 0xF3B4, 0x87E1, 0xCF6A, 0x87E2, 0xCF6B, - 0x87E3, 0xCF6C, 0x87E4, 0xCF6D, 0x87E5, 0xF3A8, 0x87E6, 0xCF6E, 0x87E7, 0xCF6F, 0x87E8, 0xCF70, 0x87E9, 0xCF71, 0x87EA, 0xF3B3, - 0x87EB, 0xCF72, 0x87EC, 0xCF73, 0x87ED, 0xCF74, 0x87EE, 0xF3B5, 0x87EF, 0xCF75, 0x87F0, 0xCF76, 0x87F1, 0xCF77, 0x87F2, 0xCF78, - 0x87F3, 0xCF79, 0x87F4, 0xCF7A, 0x87F5, 0xCF7B, 0x87F6, 0xCF7C, 0x87F7, 0xCF7D, 0x87F8, 0xCF7E, 0x87F9, 0xD0B7, 0x87FA, 0xCF80, - 0x87FB, 0xCF81, 0x87FC, 0xCF82, 0x87FD, 0xCF83, 0x87FE, 0xF3B8, 0x87FF, 0xCF84, 0x8800, 0xCF85, 0x8801, 0xCF86, 0x8802, 0xCF87, - 0x8803, 0xD9F9, 0x8804, 0xCF88, 0x8805, 0xCF89, 0x8806, 0xCF8A, 0x8807, 0xCF8B, 0x8808, 0xCF8C, 0x8809, 0xCF8D, 0x880A, 0xF3B9, - 0x880B, 0xCF8E, 0x880C, 0xCF8F, 0x880D, 0xCF90, 0x880E, 0xCF91, 0x880F, 0xCF92, 0x8810, 0xCF93, 0x8811, 0xCF94, 0x8812, 0xCF95, - 0x8813, 0xF3B7, 0x8814, 0xCF96, 0x8815, 0xC8E4, 0x8816, 0xF3B6, 0x8817, 0xCF97, 0x8818, 0xCF98, 0x8819, 0xCF99, 0x881A, 0xCF9A, - 0x881B, 0xF3BA, 0x881C, 0xCF9B, 0x881D, 0xCF9C, 0x881E, 0xCF9D, 0x881F, 0xCF9E, 0x8820, 0xCF9F, 0x8821, 0xF3BB, 0x8822, 0xB4C0, - 0x8823, 0xCFA0, 0x8824, 0xD040, 0x8825, 0xD041, 0x8826, 0xD042, 0x8827, 0xD043, 0x8828, 0xD044, 0x8829, 0xD045, 0x882A, 0xD046, - 0x882B, 0xD047, 0x882C, 0xD048, 0x882D, 0xD049, 0x882E, 0xD04A, 0x882F, 0xD04B, 0x8830, 0xD04C, 0x8831, 0xD04D, 0x8832, 0xEEC3, - 0x8833, 0xD04E, 0x8834, 0xD04F, 0x8835, 0xD050, 0x8836, 0xD051, 0x8837, 0xD052, 0x8838, 0xD053, 0x8839, 0xF3BC, 0x883A, 0xD054, - 0x883B, 0xD055, 0x883C, 0xF3BD, 0x883D, 0xD056, 0x883E, 0xD057, 0x883F, 0xD058, 0x8840, 0xD1AA, 0x8841, 0xD059, 0x8842, 0xD05A, - 0x8843, 0xD05B, 0x8844, 0xF4AC, 0x8845, 0xD0C6, 0x8846, 0xD05C, 0x8847, 0xD05D, 0x8848, 0xD05E, 0x8849, 0xD05F, 0x884A, 0xD060, - 0x884B, 0xD061, 0x884C, 0xD0D0, 0x884D, 0xD1DC, 0x884E, 0xD062, 0x884F, 0xD063, 0x8850, 0xD064, 0x8851, 0xD065, 0x8852, 0xD066, - 0x8853, 0xD067, 0x8854, 0xCFCE, 0x8855, 0xD068, 0x8856, 0xD069, 0x8857, 0xBDD6, 0x8858, 0xD06A, 0x8859, 0xD1C3, 0x885A, 0xD06B, - 0x885B, 0xD06C, 0x885C, 0xD06D, 0x885D, 0xD06E, 0x885E, 0xD06F, 0x885F, 0xD070, 0x8860, 0xD071, 0x8861, 0xBAE2, 0x8862, 0xE1E9, - 0x8863, 0xD2C2, 0x8864, 0xF1C2, 0x8865, 0xB2B9, 0x8866, 0xD072, 0x8867, 0xD073, 0x8868, 0xB1ED, 0x8869, 0xF1C3, 0x886A, 0xD074, - 0x886B, 0xC9C0, 0x886C, 0xB3C4, 0x886D, 0xD075, 0x886E, 0xD9F2, 0x886F, 0xD076, 0x8870, 0xCBA5, 0x8871, 0xD077, 0x8872, 0xF1C4, - 0x8873, 0xD078, 0x8874, 0xD079, 0x8875, 0xD07A, 0x8876, 0xD07B, 0x8877, 0xD6D4, 0x8878, 0xD07C, 0x8879, 0xD07D, 0x887A, 0xD07E, - 0x887B, 0xD080, 0x887C, 0xD081, 0x887D, 0xF1C5, 0x887E, 0xF4C0, 0x887F, 0xF1C6, 0x8880, 0xD082, 0x8881, 0xD4AC, 0x8882, 0xF1C7, - 0x8883, 0xD083, 0x8884, 0xB0C0, 0x8885, 0xF4C1, 0x8886, 0xD084, 0x8887, 0xD085, 0x8888, 0xF4C2, 0x8889, 0xD086, 0x888A, 0xD087, - 0x888B, 0xB4FC, 0x888C, 0xD088, 0x888D, 0xC5DB, 0x888E, 0xD089, 0x888F, 0xD08A, 0x8890, 0xD08B, 0x8891, 0xD08C, 0x8892, 0xCCBB, - 0x8893, 0xD08D, 0x8894, 0xD08E, 0x8895, 0xD08F, 0x8896, 0xD0E4, 0x8897, 0xD090, 0x8898, 0xD091, 0x8899, 0xD092, 0x889A, 0xD093, - 0x889B, 0xD094, 0x889C, 0xCDE0, 0x889D, 0xD095, 0x889E, 0xD096, 0x889F, 0xD097, 0x88A0, 0xD098, 0x88A1, 0xD099, 0x88A2, 0xF1C8, - 0x88A3, 0xD09A, 0x88A4, 0xD9F3, 0x88A5, 0xD09B, 0x88A6, 0xD09C, 0x88A7, 0xD09D, 0x88A8, 0xD09E, 0x88A9, 0xD09F, 0x88AA, 0xD0A0, - 0x88AB, 0xB1BB, 0x88AC, 0xD140, 0x88AD, 0xCFAE, 0x88AE, 0xD141, 0x88AF, 0xD142, 0x88B0, 0xD143, 0x88B1, 0xB8A4, 0x88B2, 0xD144, - 0x88B3, 0xD145, 0x88B4, 0xD146, 0x88B5, 0xD147, 0x88B6, 0xD148, 0x88B7, 0xF1CA, 0x88B8, 0xD149, 0x88B9, 0xD14A, 0x88BA, 0xD14B, - 0x88BB, 0xD14C, 0x88BC, 0xF1CB, 0x88BD, 0xD14D, 0x88BE, 0xD14E, 0x88BF, 0xD14F, 0x88C0, 0xD150, 0x88C1, 0xB2C3, 0x88C2, 0xC1D1, - 0x88C3, 0xD151, 0x88C4, 0xD152, 0x88C5, 0xD7B0, 0x88C6, 0xF1C9, 0x88C7, 0xD153, 0x88C8, 0xD154, 0x88C9, 0xF1CC, 0x88CA, 0xD155, - 0x88CB, 0xD156, 0x88CC, 0xD157, 0x88CD, 0xD158, 0x88CE, 0xF1CE, 0x88CF, 0xD159, 0x88D0, 0xD15A, 0x88D1, 0xD15B, 0x88D2, 0xD9F6, - 0x88D3, 0xD15C, 0x88D4, 0xD2E1, 0x88D5, 0xD4A3, 0x88D6, 0xD15D, 0x88D7, 0xD15E, 0x88D8, 0xF4C3, 0x88D9, 0xC8B9, 0x88DA, 0xD15F, - 0x88DB, 0xD160, 0x88DC, 0xD161, 0x88DD, 0xD162, 0x88DE, 0xD163, 0x88DF, 0xF4C4, 0x88E0, 0xD164, 0x88E1, 0xD165, 0x88E2, 0xF1CD, - 0x88E3, 0xF1CF, 0x88E4, 0xBFE3, 0x88E5, 0xF1D0, 0x88E6, 0xD166, 0x88E7, 0xD167, 0x88E8, 0xF1D4, 0x88E9, 0xD168, 0x88EA, 0xD169, - 0x88EB, 0xD16A, 0x88EC, 0xD16B, 0x88ED, 0xD16C, 0x88EE, 0xD16D, 0x88EF, 0xD16E, 0x88F0, 0xF1D6, 0x88F1, 0xF1D1, 0x88F2, 0xD16F, - 0x88F3, 0xC9D1, 0x88F4, 0xC5E1, 0x88F5, 0xD170, 0x88F6, 0xD171, 0x88F7, 0xD172, 0x88F8, 0xC2E3, 0x88F9, 0xB9FC, 0x88FA, 0xD173, - 0x88FB, 0xD174, 0x88FC, 0xF1D3, 0x88FD, 0xD175, 0x88FE, 0xF1D5, 0x88FF, 0xD176, 0x8900, 0xD177, 0x8901, 0xD178, 0x8902, 0xB9D3, - 0x8903, 0xD179, 0x8904, 0xD17A, 0x8905, 0xD17B, 0x8906, 0xD17C, 0x8907, 0xD17D, 0x8908, 0xD17E, 0x8909, 0xD180, 0x890A, 0xF1DB, - 0x890B, 0xD181, 0x890C, 0xD182, 0x890D, 0xD183, 0x890E, 0xD184, 0x890F, 0xD185, 0x8910, 0xBAD6, 0x8911, 0xD186, 0x8912, 0xB0FD, - 0x8913, 0xF1D9, 0x8914, 0xD187, 0x8915, 0xD188, 0x8916, 0xD189, 0x8917, 0xD18A, 0x8918, 0xD18B, 0x8919, 0xF1D8, 0x891A, 0xF1D2, - 0x891B, 0xF1DA, 0x891C, 0xD18C, 0x891D, 0xD18D, 0x891E, 0xD18E, 0x891F, 0xD18F, 0x8920, 0xD190, 0x8921, 0xF1D7, 0x8922, 0xD191, - 0x8923, 0xD192, 0x8924, 0xD193, 0x8925, 0xC8EC, 0x8926, 0xD194, 0x8927, 0xD195, 0x8928, 0xD196, 0x8929, 0xD197, 0x892A, 0xCDCA, - 0x892B, 0xF1DD, 0x892C, 0xD198, 0x892D, 0xD199, 0x892E, 0xD19A, 0x892F, 0xD19B, 0x8930, 0xE5BD, 0x8931, 0xD19C, 0x8932, 0xD19D, - 0x8933, 0xD19E, 0x8934, 0xF1DC, 0x8935, 0xD19F, 0x8936, 0xF1DE, 0x8937, 0xD1A0, 0x8938, 0xD240, 0x8939, 0xD241, 0x893A, 0xD242, - 0x893B, 0xD243, 0x893C, 0xD244, 0x893D, 0xD245, 0x893E, 0xD246, 0x893F, 0xD247, 0x8940, 0xD248, 0x8941, 0xF1DF, 0x8942, 0xD249, - 0x8943, 0xD24A, 0x8944, 0xCFE5, 0x8945, 0xD24B, 0x8946, 0xD24C, 0x8947, 0xD24D, 0x8948, 0xD24E, 0x8949, 0xD24F, 0x894A, 0xD250, - 0x894B, 0xD251, 0x894C, 0xD252, 0x894D, 0xD253, 0x894E, 0xD254, 0x894F, 0xD255, 0x8950, 0xD256, 0x8951, 0xD257, 0x8952, 0xD258, - 0x8953, 0xD259, 0x8954, 0xD25A, 0x8955, 0xD25B, 0x8956, 0xD25C, 0x8957, 0xD25D, 0x8958, 0xD25E, 0x8959, 0xD25F, 0x895A, 0xD260, - 0x895B, 0xD261, 0x895C, 0xD262, 0x895D, 0xD263, 0x895E, 0xF4C5, 0x895F, 0xBDF3, 0x8960, 0xD264, 0x8961, 0xD265, 0x8962, 0xD266, - 0x8963, 0xD267, 0x8964, 0xD268, 0x8965, 0xD269, 0x8966, 0xF1E0, 0x8967, 0xD26A, 0x8968, 0xD26B, 0x8969, 0xD26C, 0x896A, 0xD26D, - 0x896B, 0xD26E, 0x896C, 0xD26F, 0x896D, 0xD270, 0x896E, 0xD271, 0x896F, 0xD272, 0x8970, 0xD273, 0x8971, 0xD274, 0x8972, 0xD275, - 0x8973, 0xD276, 0x8974, 0xD277, 0x8975, 0xD278, 0x8976, 0xD279, 0x8977, 0xD27A, 0x8978, 0xD27B, 0x8979, 0xD27C, 0x897A, 0xD27D, - 0x897B, 0xF1E1, 0x897C, 0xD27E, 0x897D, 0xD280, 0x897E, 0xD281, 0x897F, 0xCEF7, 0x8980, 0xD282, 0x8981, 0xD2AA, 0x8982, 0xD283, - 0x8983, 0xF1FB, 0x8984, 0xD284, 0x8985, 0xD285, 0x8986, 0xB8B2, 0x8987, 0xD286, 0x8988, 0xD287, 0x8989, 0xD288, 0x898A, 0xD289, - 0x898B, 0xD28A, 0x898C, 0xD28B, 0x898D, 0xD28C, 0x898E, 0xD28D, 0x898F, 0xD28E, 0x8990, 0xD28F, 0x8991, 0xD290, 0x8992, 0xD291, - 0x8993, 0xD292, 0x8994, 0xD293, 0x8995, 0xD294, 0x8996, 0xD295, 0x8997, 0xD296, 0x8998, 0xD297, 0x8999, 0xD298, 0x899A, 0xD299, - 0x899B, 0xD29A, 0x899C, 0xD29B, 0x899D, 0xD29C, 0x899E, 0xD29D, 0x899F, 0xD29E, 0x89A0, 0xD29F, 0x89A1, 0xD2A0, 0x89A2, 0xD340, - 0x89A3, 0xD341, 0x89A4, 0xD342, 0x89A5, 0xD343, 0x89A6, 0xD344, 0x89A7, 0xD345, 0x89A8, 0xD346, 0x89A9, 0xD347, 0x89AA, 0xD348, - 0x89AB, 0xD349, 0x89AC, 0xD34A, 0x89AD, 0xD34B, 0x89AE, 0xD34C, 0x89AF, 0xD34D, 0x89B0, 0xD34E, 0x89B1, 0xD34F, 0x89B2, 0xD350, - 0x89B3, 0xD351, 0x89B4, 0xD352, 0x89B5, 0xD353, 0x89B6, 0xD354, 0x89B7, 0xD355, 0x89B8, 0xD356, 0x89B9, 0xD357, 0x89BA, 0xD358, - 0x89BB, 0xD359, 0x89BC, 0xD35A, 0x89BD, 0xD35B, 0x89BE, 0xD35C, 0x89BF, 0xD35D, 0x89C0, 0xD35E, 0x89C1, 0xBCFB, 0x89C2, 0xB9DB, - 0x89C3, 0xD35F, 0x89C4, 0xB9E6, 0x89C5, 0xC3D9, 0x89C6, 0xCAD3, 0x89C7, 0xEAE8, 0x89C8, 0xC0C0, 0x89C9, 0xBEF5, 0x89CA, 0xEAE9, - 0x89CB, 0xEAEA, 0x89CC, 0xEAEB, 0x89CD, 0xD360, 0x89CE, 0xEAEC, 0x89CF, 0xEAED, 0x89D0, 0xEAEE, 0x89D1, 0xEAEF, 0x89D2, 0xBDC7, - 0x89D3, 0xD361, 0x89D4, 0xD362, 0x89D5, 0xD363, 0x89D6, 0xF5FB, 0x89D7, 0xD364, 0x89D8, 0xD365, 0x89D9, 0xD366, 0x89DA, 0xF5FD, - 0x89DB, 0xD367, 0x89DC, 0xF5FE, 0x89DD, 0xD368, 0x89DE, 0xF5FC, 0x89DF, 0xD369, 0x89E0, 0xD36A, 0x89E1, 0xD36B, 0x89E2, 0xD36C, - 0x89E3, 0xBDE2, 0x89E4, 0xD36D, 0x89E5, 0xF6A1, 0x89E6, 0xB4A5, 0x89E7, 0xD36E, 0x89E8, 0xD36F, 0x89E9, 0xD370, 0x89EA, 0xD371, - 0x89EB, 0xF6A2, 0x89EC, 0xD372, 0x89ED, 0xD373, 0x89EE, 0xD374, 0x89EF, 0xF6A3, 0x89F0, 0xD375, 0x89F1, 0xD376, 0x89F2, 0xD377, - 0x89F3, 0xECB2, 0x89F4, 0xD378, 0x89F5, 0xD379, 0x89F6, 0xD37A, 0x89F7, 0xD37B, 0x89F8, 0xD37C, 0x89F9, 0xD37D, 0x89FA, 0xD37E, - 0x89FB, 0xD380, 0x89FC, 0xD381, 0x89FD, 0xD382, 0x89FE, 0xD383, 0x89FF, 0xD384, 0x8A00, 0xD1D4, 0x8A01, 0xD385, 0x8A02, 0xD386, - 0x8A03, 0xD387, 0x8A04, 0xD388, 0x8A05, 0xD389, 0x8A06, 0xD38A, 0x8A07, 0xD9EA, 0x8A08, 0xD38B, 0x8A09, 0xD38C, 0x8A0A, 0xD38D, - 0x8A0B, 0xD38E, 0x8A0C, 0xD38F, 0x8A0D, 0xD390, 0x8A0E, 0xD391, 0x8A0F, 0xD392, 0x8A10, 0xD393, 0x8A11, 0xD394, 0x8A12, 0xD395, - 0x8A13, 0xD396, 0x8A14, 0xD397, 0x8A15, 0xD398, 0x8A16, 0xD399, 0x8A17, 0xD39A, 0x8A18, 0xD39B, 0x8A19, 0xD39C, 0x8A1A, 0xD39D, - 0x8A1B, 0xD39E, 0x8A1C, 0xD39F, 0x8A1D, 0xD3A0, 0x8A1E, 0xD440, 0x8A1F, 0xD441, 0x8A20, 0xD442, 0x8A21, 0xD443, 0x8A22, 0xD444, - 0x8A23, 0xD445, 0x8A24, 0xD446, 0x8A25, 0xD447, 0x8A26, 0xD448, 0x8A27, 0xD449, 0x8A28, 0xD44A, 0x8A29, 0xD44B, 0x8A2A, 0xD44C, - 0x8A2B, 0xD44D, 0x8A2C, 0xD44E, 0x8A2D, 0xD44F, 0x8A2E, 0xD450, 0x8A2F, 0xD451, 0x8A30, 0xD452, 0x8A31, 0xD453, 0x8A32, 0xD454, - 0x8A33, 0xD455, 0x8A34, 0xD456, 0x8A35, 0xD457, 0x8A36, 0xD458, 0x8A37, 0xD459, 0x8A38, 0xD45A, 0x8A39, 0xD45B, 0x8A3A, 0xD45C, - 0x8A3B, 0xD45D, 0x8A3C, 0xD45E, 0x8A3D, 0xD45F, 0x8A3E, 0xF6A4, 0x8A3F, 0xD460, 0x8A40, 0xD461, 0x8A41, 0xD462, 0x8A42, 0xD463, - 0x8A43, 0xD464, 0x8A44, 0xD465, 0x8A45, 0xD466, 0x8A46, 0xD467, 0x8A47, 0xD468, 0x8A48, 0xEEBA, 0x8A49, 0xD469, 0x8A4A, 0xD46A, - 0x8A4B, 0xD46B, 0x8A4C, 0xD46C, 0x8A4D, 0xD46D, 0x8A4E, 0xD46E, 0x8A4F, 0xD46F, 0x8A50, 0xD470, 0x8A51, 0xD471, 0x8A52, 0xD472, - 0x8A53, 0xD473, 0x8A54, 0xD474, 0x8A55, 0xD475, 0x8A56, 0xD476, 0x8A57, 0xD477, 0x8A58, 0xD478, 0x8A59, 0xD479, 0x8A5A, 0xD47A, - 0x8A5B, 0xD47B, 0x8A5C, 0xD47C, 0x8A5D, 0xD47D, 0x8A5E, 0xD47E, 0x8A5F, 0xD480, 0x8A60, 0xD481, 0x8A61, 0xD482, 0x8A62, 0xD483, - 0x8A63, 0xD484, 0x8A64, 0xD485, 0x8A65, 0xD486, 0x8A66, 0xD487, 0x8A67, 0xD488, 0x8A68, 0xD489, 0x8A69, 0xD48A, 0x8A6A, 0xD48B, - 0x8A6B, 0xD48C, 0x8A6C, 0xD48D, 0x8A6D, 0xD48E, 0x8A6E, 0xD48F, 0x8A6F, 0xD490, 0x8A70, 0xD491, 0x8A71, 0xD492, 0x8A72, 0xD493, - 0x8A73, 0xD494, 0x8A74, 0xD495, 0x8A75, 0xD496, 0x8A76, 0xD497, 0x8A77, 0xD498, 0x8A78, 0xD499, 0x8A79, 0xD5B2, 0x8A7A, 0xD49A, - 0x8A7B, 0xD49B, 0x8A7C, 0xD49C, 0x8A7D, 0xD49D, 0x8A7E, 0xD49E, 0x8A7F, 0xD49F, 0x8A80, 0xD4A0, 0x8A81, 0xD540, 0x8A82, 0xD541, - 0x8A83, 0xD542, 0x8A84, 0xD543, 0x8A85, 0xD544, 0x8A86, 0xD545, 0x8A87, 0xD546, 0x8A88, 0xD547, 0x8A89, 0xD3FE, 0x8A8A, 0xCCDC, - 0x8A8B, 0xD548, 0x8A8C, 0xD549, 0x8A8D, 0xD54A, 0x8A8E, 0xD54B, 0x8A8F, 0xD54C, 0x8A90, 0xD54D, 0x8A91, 0xD54E, 0x8A92, 0xD54F, - 0x8A93, 0xCAC4, 0x8A94, 0xD550, 0x8A95, 0xD551, 0x8A96, 0xD552, 0x8A97, 0xD553, 0x8A98, 0xD554, 0x8A99, 0xD555, 0x8A9A, 0xD556, - 0x8A9B, 0xD557, 0x8A9C, 0xD558, 0x8A9D, 0xD559, 0x8A9E, 0xD55A, 0x8A9F, 0xD55B, 0x8AA0, 0xD55C, 0x8AA1, 0xD55D, 0x8AA2, 0xD55E, - 0x8AA3, 0xD55F, 0x8AA4, 0xD560, 0x8AA5, 0xD561, 0x8AA6, 0xD562, 0x8AA7, 0xD563, 0x8AA8, 0xD564, 0x8AA9, 0xD565, 0x8AAA, 0xD566, - 0x8AAB, 0xD567, 0x8AAC, 0xD568, 0x8AAD, 0xD569, 0x8AAE, 0xD56A, 0x8AAF, 0xD56B, 0x8AB0, 0xD56C, 0x8AB1, 0xD56D, 0x8AB2, 0xD56E, - 0x8AB3, 0xD56F, 0x8AB4, 0xD570, 0x8AB5, 0xD571, 0x8AB6, 0xD572, 0x8AB7, 0xD573, 0x8AB8, 0xD574, 0x8AB9, 0xD575, 0x8ABA, 0xD576, - 0x8ABB, 0xD577, 0x8ABC, 0xD578, 0x8ABD, 0xD579, 0x8ABE, 0xD57A, 0x8ABF, 0xD57B, 0x8AC0, 0xD57C, 0x8AC1, 0xD57D, 0x8AC2, 0xD57E, - 0x8AC3, 0xD580, 0x8AC4, 0xD581, 0x8AC5, 0xD582, 0x8AC6, 0xD583, 0x8AC7, 0xD584, 0x8AC8, 0xD585, 0x8AC9, 0xD586, 0x8ACA, 0xD587, - 0x8ACB, 0xD588, 0x8ACC, 0xD589, 0x8ACD, 0xD58A, 0x8ACE, 0xD58B, 0x8ACF, 0xD58C, 0x8AD0, 0xD58D, 0x8AD1, 0xD58E, 0x8AD2, 0xD58F, - 0x8AD3, 0xD590, 0x8AD4, 0xD591, 0x8AD5, 0xD592, 0x8AD6, 0xD593, 0x8AD7, 0xD594, 0x8AD8, 0xD595, 0x8AD9, 0xD596, 0x8ADA, 0xD597, - 0x8ADB, 0xD598, 0x8ADC, 0xD599, 0x8ADD, 0xD59A, 0x8ADE, 0xD59B, 0x8ADF, 0xD59C, 0x8AE0, 0xD59D, 0x8AE1, 0xD59E, 0x8AE2, 0xD59F, - 0x8AE3, 0xD5A0, 0x8AE4, 0xD640, 0x8AE5, 0xD641, 0x8AE6, 0xD642, 0x8AE7, 0xD643, 0x8AE8, 0xD644, 0x8AE9, 0xD645, 0x8AEA, 0xD646, - 0x8AEB, 0xD647, 0x8AEC, 0xD648, 0x8AED, 0xD649, 0x8AEE, 0xD64A, 0x8AEF, 0xD64B, 0x8AF0, 0xD64C, 0x8AF1, 0xD64D, 0x8AF2, 0xD64E, - 0x8AF3, 0xD64F, 0x8AF4, 0xD650, 0x8AF5, 0xD651, 0x8AF6, 0xD652, 0x8AF7, 0xD653, 0x8AF8, 0xD654, 0x8AF9, 0xD655, 0x8AFA, 0xD656, - 0x8AFB, 0xD657, 0x8AFC, 0xD658, 0x8AFD, 0xD659, 0x8AFE, 0xD65A, 0x8AFF, 0xD65B, 0x8B00, 0xD65C, 0x8B01, 0xD65D, 0x8B02, 0xD65E, - 0x8B03, 0xD65F, 0x8B04, 0xD660, 0x8B05, 0xD661, 0x8B06, 0xD662, 0x8B07, 0xE5C0, 0x8B08, 0xD663, 0x8B09, 0xD664, 0x8B0A, 0xD665, - 0x8B0B, 0xD666, 0x8B0C, 0xD667, 0x8B0D, 0xD668, 0x8B0E, 0xD669, 0x8B0F, 0xD66A, 0x8B10, 0xD66B, 0x8B11, 0xD66C, 0x8B12, 0xD66D, - 0x8B13, 0xD66E, 0x8B14, 0xD66F, 0x8B15, 0xD670, 0x8B16, 0xD671, 0x8B17, 0xD672, 0x8B18, 0xD673, 0x8B19, 0xD674, 0x8B1A, 0xD675, - 0x8B1B, 0xD676, 0x8B1C, 0xD677, 0x8B1D, 0xD678, 0x8B1E, 0xD679, 0x8B1F, 0xD67A, 0x8B20, 0xD67B, 0x8B21, 0xD67C, 0x8B22, 0xD67D, - 0x8B23, 0xD67E, 0x8B24, 0xD680, 0x8B25, 0xD681, 0x8B26, 0xF6A5, 0x8B27, 0xD682, 0x8B28, 0xD683, 0x8B29, 0xD684, 0x8B2A, 0xD685, - 0x8B2B, 0xD686, 0x8B2C, 0xD687, 0x8B2D, 0xD688, 0x8B2E, 0xD689, 0x8B2F, 0xD68A, 0x8B30, 0xD68B, 0x8B31, 0xD68C, 0x8B32, 0xD68D, - 0x8B33, 0xD68E, 0x8B34, 0xD68F, 0x8B35, 0xD690, 0x8B36, 0xD691, 0x8B37, 0xD692, 0x8B38, 0xD693, 0x8B39, 0xD694, 0x8B3A, 0xD695, - 0x8B3B, 0xD696, 0x8B3C, 0xD697, 0x8B3D, 0xD698, 0x8B3E, 0xD699, 0x8B3F, 0xD69A, 0x8B40, 0xD69B, 0x8B41, 0xD69C, 0x8B42, 0xD69D, - 0x8B43, 0xD69E, 0x8B44, 0xD69F, 0x8B45, 0xD6A0, 0x8B46, 0xD740, 0x8B47, 0xD741, 0x8B48, 0xD742, 0x8B49, 0xD743, 0x8B4A, 0xD744, - 0x8B4B, 0xD745, 0x8B4C, 0xD746, 0x8B4D, 0xD747, 0x8B4E, 0xD748, 0x8B4F, 0xD749, 0x8B50, 0xD74A, 0x8B51, 0xD74B, 0x8B52, 0xD74C, - 0x8B53, 0xD74D, 0x8B54, 0xD74E, 0x8B55, 0xD74F, 0x8B56, 0xD750, 0x8B57, 0xD751, 0x8B58, 0xD752, 0x8B59, 0xD753, 0x8B5A, 0xD754, - 0x8B5B, 0xD755, 0x8B5C, 0xD756, 0x8B5D, 0xD757, 0x8B5E, 0xD758, 0x8B5F, 0xD759, 0x8B60, 0xD75A, 0x8B61, 0xD75B, 0x8B62, 0xD75C, - 0x8B63, 0xD75D, 0x8B64, 0xD75E, 0x8B65, 0xD75F, 0x8B66, 0xBEAF, 0x8B67, 0xD760, 0x8B68, 0xD761, 0x8B69, 0xD762, 0x8B6A, 0xD763, - 0x8B6B, 0xD764, 0x8B6C, 0xC6A9, 0x8B6D, 0xD765, 0x8B6E, 0xD766, 0x8B6F, 0xD767, 0x8B70, 0xD768, 0x8B71, 0xD769, 0x8B72, 0xD76A, - 0x8B73, 0xD76B, 0x8B74, 0xD76C, 0x8B75, 0xD76D, 0x8B76, 0xD76E, 0x8B77, 0xD76F, 0x8B78, 0xD770, 0x8B79, 0xD771, 0x8B7A, 0xD772, - 0x8B7B, 0xD773, 0x8B7C, 0xD774, 0x8B7D, 0xD775, 0x8B7E, 0xD776, 0x8B7F, 0xD777, 0x8B80, 0xD778, 0x8B81, 0xD779, 0x8B82, 0xD77A, - 0x8B83, 0xD77B, 0x8B84, 0xD77C, 0x8B85, 0xD77D, 0x8B86, 0xD77E, 0x8B87, 0xD780, 0x8B88, 0xD781, 0x8B89, 0xD782, 0x8B8A, 0xD783, - 0x8B8B, 0xD784, 0x8B8C, 0xD785, 0x8B8D, 0xD786, 0x8B8E, 0xD787, 0x8B8F, 0xD788, 0x8B90, 0xD789, 0x8B91, 0xD78A, 0x8B92, 0xD78B, - 0x8B93, 0xD78C, 0x8B94, 0xD78D, 0x8B95, 0xD78E, 0x8B96, 0xD78F, 0x8B97, 0xD790, 0x8B98, 0xD791, 0x8B99, 0xD792, 0x8B9A, 0xD793, - 0x8B9B, 0xD794, 0x8B9C, 0xD795, 0x8B9D, 0xD796, 0x8B9E, 0xD797, 0x8B9F, 0xD798, 0x8BA0, 0xDAA5, 0x8BA1, 0xBCC6, 0x8BA2, 0xB6A9, - 0x8BA3, 0xB8BC, 0x8BA4, 0xC8CF, 0x8BA5, 0xBCA5, 0x8BA6, 0xDAA6, 0x8BA7, 0xDAA7, 0x8BA8, 0xCCD6, 0x8BA9, 0xC8C3, 0x8BAA, 0xDAA8, - 0x8BAB, 0xC6FD, 0x8BAC, 0xD799, 0x8BAD, 0xD1B5, 0x8BAE, 0xD2E9, 0x8BAF, 0xD1B6, 0x8BB0, 0xBCC7, 0x8BB1, 0xD79A, 0x8BB2, 0xBDB2, - 0x8BB3, 0xBBE4, 0x8BB4, 0xDAA9, 0x8BB5, 0xDAAA, 0x8BB6, 0xD1C8, 0x8BB7, 0xDAAB, 0x8BB8, 0xD0ED, 0x8BB9, 0xB6EF, 0x8BBA, 0xC2DB, - 0x8BBB, 0xD79B, 0x8BBC, 0xCBCF, 0x8BBD, 0xB7ED, 0x8BBE, 0xC9E8, 0x8BBF, 0xB7C3, 0x8BC0, 0xBEF7, 0x8BC1, 0xD6A4, 0x8BC2, 0xDAAC, - 0x8BC3, 0xDAAD, 0x8BC4, 0xC6C0, 0x8BC5, 0xD7E7, 0x8BC6, 0xCAB6, 0x8BC7, 0xD79C, 0x8BC8, 0xD5A9, 0x8BC9, 0xCBDF, 0x8BCA, 0xD5EF, - 0x8BCB, 0xDAAE, 0x8BCC, 0xD6DF, 0x8BCD, 0xB4CA, 0x8BCE, 0xDAB0, 0x8BCF, 0xDAAF, 0x8BD0, 0xD79D, 0x8BD1, 0xD2EB, 0x8BD2, 0xDAB1, - 0x8BD3, 0xDAB2, 0x8BD4, 0xDAB3, 0x8BD5, 0xCAD4, 0x8BD6, 0xDAB4, 0x8BD7, 0xCAAB, 0x8BD8, 0xDAB5, 0x8BD9, 0xDAB6, 0x8BDA, 0xB3CF, - 0x8BDB, 0xD6EF, 0x8BDC, 0xDAB7, 0x8BDD, 0xBBB0, 0x8BDE, 0xB5AE, 0x8BDF, 0xDAB8, 0x8BE0, 0xDAB9, 0x8BE1, 0xB9EE, 0x8BE2, 0xD1AF, - 0x8BE3, 0xD2E8, 0x8BE4, 0xDABA, 0x8BE5, 0xB8C3, 0x8BE6, 0xCFEA, 0x8BE7, 0xB2EF, 0x8BE8, 0xDABB, 0x8BE9, 0xDABC, 0x8BEA, 0xD79E, - 0x8BEB, 0xBDEB, 0x8BEC, 0xCEDC, 0x8BED, 0xD3EF, 0x8BEE, 0xDABD, 0x8BEF, 0xCEF3, 0x8BF0, 0xDABE, 0x8BF1, 0xD3D5, 0x8BF2, 0xBBE5, - 0x8BF3, 0xDABF, 0x8BF4, 0xCBB5, 0x8BF5, 0xCBD0, 0x8BF6, 0xDAC0, 0x8BF7, 0xC7EB, 0x8BF8, 0xD6EE, 0x8BF9, 0xDAC1, 0x8BFA, 0xC5B5, - 0x8BFB, 0xB6C1, 0x8BFC, 0xDAC2, 0x8BFD, 0xB7CC, 0x8BFE, 0xBFCE, 0x8BFF, 0xDAC3, 0x8C00, 0xDAC4, 0x8C01, 0xCBAD, 0x8C02, 0xDAC5, - 0x8C03, 0xB5F7, 0x8C04, 0xDAC6, 0x8C05, 0xC1C2, 0x8C06, 0xD7BB, 0x8C07, 0xDAC7, 0x8C08, 0xCCB8, 0x8C09, 0xD79F, 0x8C0A, 0xD2EA, - 0x8C0B, 0xC4B1, 0x8C0C, 0xDAC8, 0x8C0D, 0xB5FD, 0x8C0E, 0xBBD1, 0x8C0F, 0xDAC9, 0x8C10, 0xD0B3, 0x8C11, 0xDACA, 0x8C12, 0xDACB, - 0x8C13, 0xCEBD, 0x8C14, 0xDACC, 0x8C15, 0xDACD, 0x8C16, 0xDACE, 0x8C17, 0xB2F7, 0x8C18, 0xDAD1, 0x8C19, 0xDACF, 0x8C1A, 0xD1E8, - 0x8C1B, 0xDAD0, 0x8C1C, 0xC3D5, 0x8C1D, 0xDAD2, 0x8C1E, 0xD7A0, 0x8C1F, 0xDAD3, 0x8C20, 0xDAD4, 0x8C21, 0xDAD5, 0x8C22, 0xD0BB, - 0x8C23, 0xD2A5, 0x8C24, 0xB0F9, 0x8C25, 0xDAD6, 0x8C26, 0xC7AB, 0x8C27, 0xDAD7, 0x8C28, 0xBDF7, 0x8C29, 0xC3A1, 0x8C2A, 0xDAD8, - 0x8C2B, 0xDAD9, 0x8C2C, 0xC3FD, 0x8C2D, 0xCCB7, 0x8C2E, 0xDADA, 0x8C2F, 0xDADB, 0x8C30, 0xC0BE, 0x8C31, 0xC6D7, 0x8C32, 0xDADC, - 0x8C33, 0xDADD, 0x8C34, 0xC7B4, 0x8C35, 0xDADE, 0x8C36, 0xDADF, 0x8C37, 0xB9C8, 0x8C38, 0xD840, 0x8C39, 0xD841, 0x8C3A, 0xD842, - 0x8C3B, 0xD843, 0x8C3C, 0xD844, 0x8C3D, 0xD845, 0x8C3E, 0xD846, 0x8C3F, 0xD847, 0x8C40, 0xD848, 0x8C41, 0xBBED, 0x8C42, 0xD849, - 0x8C43, 0xD84A, 0x8C44, 0xD84B, 0x8C45, 0xD84C, 0x8C46, 0xB6B9, 0x8C47, 0xF4F8, 0x8C48, 0xD84D, 0x8C49, 0xF4F9, 0x8C4A, 0xD84E, - 0x8C4B, 0xD84F, 0x8C4C, 0xCDE3, 0x8C4D, 0xD850, 0x8C4E, 0xD851, 0x8C4F, 0xD852, 0x8C50, 0xD853, 0x8C51, 0xD854, 0x8C52, 0xD855, - 0x8C53, 0xD856, 0x8C54, 0xD857, 0x8C55, 0xF5B9, 0x8C56, 0xD858, 0x8C57, 0xD859, 0x8C58, 0xD85A, 0x8C59, 0xD85B, 0x8C5A, 0xEBE0, - 0x8C5B, 0xD85C, 0x8C5C, 0xD85D, 0x8C5D, 0xD85E, 0x8C5E, 0xD85F, 0x8C5F, 0xD860, 0x8C60, 0xD861, 0x8C61, 0xCFF3, 0x8C62, 0xBBBF, - 0x8C63, 0xD862, 0x8C64, 0xD863, 0x8C65, 0xD864, 0x8C66, 0xD865, 0x8C67, 0xD866, 0x8C68, 0xD867, 0x8C69, 0xD868, 0x8C6A, 0xBAC0, - 0x8C6B, 0xD4A5, 0x8C6C, 0xD869, 0x8C6D, 0xD86A, 0x8C6E, 0xD86B, 0x8C6F, 0xD86C, 0x8C70, 0xD86D, 0x8C71, 0xD86E, 0x8C72, 0xD86F, - 0x8C73, 0xE1D9, 0x8C74, 0xD870, 0x8C75, 0xD871, 0x8C76, 0xD872, 0x8C77, 0xD873, 0x8C78, 0xF5F4, 0x8C79, 0xB1AA, 0x8C7A, 0xB2F2, - 0x8C7B, 0xD874, 0x8C7C, 0xD875, 0x8C7D, 0xD876, 0x8C7E, 0xD877, 0x8C7F, 0xD878, 0x8C80, 0xD879, 0x8C81, 0xD87A, 0x8C82, 0xF5F5, - 0x8C83, 0xD87B, 0x8C84, 0xD87C, 0x8C85, 0xF5F7, 0x8C86, 0xD87D, 0x8C87, 0xD87E, 0x8C88, 0xD880, 0x8C89, 0xBAD1, 0x8C8A, 0xF5F6, - 0x8C8B, 0xD881, 0x8C8C, 0xC3B2, 0x8C8D, 0xD882, 0x8C8E, 0xD883, 0x8C8F, 0xD884, 0x8C90, 0xD885, 0x8C91, 0xD886, 0x8C92, 0xD887, - 0x8C93, 0xD888, 0x8C94, 0xF5F9, 0x8C95, 0xD889, 0x8C96, 0xD88A, 0x8C97, 0xD88B, 0x8C98, 0xF5F8, 0x8C99, 0xD88C, 0x8C9A, 0xD88D, - 0x8C9B, 0xD88E, 0x8C9C, 0xD88F, 0x8C9D, 0xD890, 0x8C9E, 0xD891, 0x8C9F, 0xD892, 0x8CA0, 0xD893, 0x8CA1, 0xD894, 0x8CA2, 0xD895, - 0x8CA3, 0xD896, 0x8CA4, 0xD897, 0x8CA5, 0xD898, 0x8CA6, 0xD899, 0x8CA7, 0xD89A, 0x8CA8, 0xD89B, 0x8CA9, 0xD89C, 0x8CAA, 0xD89D, - 0x8CAB, 0xD89E, 0x8CAC, 0xD89F, 0x8CAD, 0xD8A0, 0x8CAE, 0xD940, 0x8CAF, 0xD941, 0x8CB0, 0xD942, 0x8CB1, 0xD943, 0x8CB2, 0xD944, - 0x8CB3, 0xD945, 0x8CB4, 0xD946, 0x8CB5, 0xD947, 0x8CB6, 0xD948, 0x8CB7, 0xD949, 0x8CB8, 0xD94A, 0x8CB9, 0xD94B, 0x8CBA, 0xD94C, - 0x8CBB, 0xD94D, 0x8CBC, 0xD94E, 0x8CBD, 0xD94F, 0x8CBE, 0xD950, 0x8CBF, 0xD951, 0x8CC0, 0xD952, 0x8CC1, 0xD953, 0x8CC2, 0xD954, - 0x8CC3, 0xD955, 0x8CC4, 0xD956, 0x8CC5, 0xD957, 0x8CC6, 0xD958, 0x8CC7, 0xD959, 0x8CC8, 0xD95A, 0x8CC9, 0xD95B, 0x8CCA, 0xD95C, - 0x8CCB, 0xD95D, 0x8CCC, 0xD95E, 0x8CCD, 0xD95F, 0x8CCE, 0xD960, 0x8CCF, 0xD961, 0x8CD0, 0xD962, 0x8CD1, 0xD963, 0x8CD2, 0xD964, - 0x8CD3, 0xD965, 0x8CD4, 0xD966, 0x8CD5, 0xD967, 0x8CD6, 0xD968, 0x8CD7, 0xD969, 0x8CD8, 0xD96A, 0x8CD9, 0xD96B, 0x8CDA, 0xD96C, - 0x8CDB, 0xD96D, 0x8CDC, 0xD96E, 0x8CDD, 0xD96F, 0x8CDE, 0xD970, 0x8CDF, 0xD971, 0x8CE0, 0xD972, 0x8CE1, 0xD973, 0x8CE2, 0xD974, - 0x8CE3, 0xD975, 0x8CE4, 0xD976, 0x8CE5, 0xD977, 0x8CE6, 0xD978, 0x8CE7, 0xD979, 0x8CE8, 0xD97A, 0x8CE9, 0xD97B, 0x8CEA, 0xD97C, - 0x8CEB, 0xD97D, 0x8CEC, 0xD97E, 0x8CED, 0xD980, 0x8CEE, 0xD981, 0x8CEF, 0xD982, 0x8CF0, 0xD983, 0x8CF1, 0xD984, 0x8CF2, 0xD985, - 0x8CF3, 0xD986, 0x8CF4, 0xD987, 0x8CF5, 0xD988, 0x8CF6, 0xD989, 0x8CF7, 0xD98A, 0x8CF8, 0xD98B, 0x8CF9, 0xD98C, 0x8CFA, 0xD98D, - 0x8CFB, 0xD98E, 0x8CFC, 0xD98F, 0x8CFD, 0xD990, 0x8CFE, 0xD991, 0x8CFF, 0xD992, 0x8D00, 0xD993, 0x8D01, 0xD994, 0x8D02, 0xD995, - 0x8D03, 0xD996, 0x8D04, 0xD997, 0x8D05, 0xD998, 0x8D06, 0xD999, 0x8D07, 0xD99A, 0x8D08, 0xD99B, 0x8D09, 0xD99C, 0x8D0A, 0xD99D, - 0x8D0B, 0xD99E, 0x8D0C, 0xD99F, 0x8D0D, 0xD9A0, 0x8D0E, 0xDA40, 0x8D0F, 0xDA41, 0x8D10, 0xDA42, 0x8D11, 0xDA43, 0x8D12, 0xDA44, - 0x8D13, 0xDA45, 0x8D14, 0xDA46, 0x8D15, 0xDA47, 0x8D16, 0xDA48, 0x8D17, 0xDA49, 0x8D18, 0xDA4A, 0x8D19, 0xDA4B, 0x8D1A, 0xDA4C, - 0x8D1B, 0xDA4D, 0x8D1C, 0xDA4E, 0x8D1D, 0xB1B4, 0x8D1E, 0xD5EA, 0x8D1F, 0xB8BA, 0x8D20, 0xDA4F, 0x8D21, 0xB9B1, 0x8D22, 0xB2C6, - 0x8D23, 0xD4F0, 0x8D24, 0xCFCD, 0x8D25, 0xB0DC, 0x8D26, 0xD5CB, 0x8D27, 0xBBF5, 0x8D28, 0xD6CA, 0x8D29, 0xB7B7, 0x8D2A, 0xCCB0, - 0x8D2B, 0xC6B6, 0x8D2C, 0xB1E1, 0x8D2D, 0xB9BA, 0x8D2E, 0xD6FC, 0x8D2F, 0xB9E1, 0x8D30, 0xB7A1, 0x8D31, 0xBCFA, 0x8D32, 0xEADA, - 0x8D33, 0xEADB, 0x8D34, 0xCCF9, 0x8D35, 0xB9F3, 0x8D36, 0xEADC, 0x8D37, 0xB4FB, 0x8D38, 0xC3B3, 0x8D39, 0xB7D1, 0x8D3A, 0xBAD8, - 0x8D3B, 0xEADD, 0x8D3C, 0xD4F4, 0x8D3D, 0xEADE, 0x8D3E, 0xBCD6, 0x8D3F, 0xBBDF, 0x8D40, 0xEADF, 0x8D41, 0xC1DE, 0x8D42, 0xC2B8, - 0x8D43, 0xD4DF, 0x8D44, 0xD7CA, 0x8D45, 0xEAE0, 0x8D46, 0xEAE1, 0x8D47, 0xEAE4, 0x8D48, 0xEAE2, 0x8D49, 0xEAE3, 0x8D4A, 0xC9DE, - 0x8D4B, 0xB8B3, 0x8D4C, 0xB6C4, 0x8D4D, 0xEAE5, 0x8D4E, 0xCAEA, 0x8D4F, 0xC9CD, 0x8D50, 0xB4CD, 0x8D51, 0xDA50, 0x8D52, 0xDA51, - 0x8D53, 0xE2D9, 0x8D54, 0xC5E2, 0x8D55, 0xEAE6, 0x8D56, 0xC0B5, 0x8D57, 0xDA52, 0x8D58, 0xD7B8, 0x8D59, 0xEAE7, 0x8D5A, 0xD7AC, - 0x8D5B, 0xC8FC, 0x8D5C, 0xD8D3, 0x8D5D, 0xD8CD, 0x8D5E, 0xD4DE, 0x8D5F, 0xDA53, 0x8D60, 0xD4F9, 0x8D61, 0xC9C4, 0x8D62, 0xD3AE, - 0x8D63, 0xB8D3, 0x8D64, 0xB3E0, 0x8D65, 0xDA54, 0x8D66, 0xC9E2, 0x8D67, 0xF4F6, 0x8D68, 0xDA55, 0x8D69, 0xDA56, 0x8D6A, 0xDA57, - 0x8D6B, 0xBAD5, 0x8D6C, 0xDA58, 0x8D6D, 0xF4F7, 0x8D6E, 0xDA59, 0x8D6F, 0xDA5A, 0x8D70, 0xD7DF, 0x8D71, 0xDA5B, 0x8D72, 0xDA5C, - 0x8D73, 0xF4F1, 0x8D74, 0xB8B0, 0x8D75, 0xD5D4, 0x8D76, 0xB8CF, 0x8D77, 0xC6F0, 0x8D78, 0xDA5D, 0x8D79, 0xDA5E, 0x8D7A, 0xDA5F, - 0x8D7B, 0xDA60, 0x8D7C, 0xDA61, 0x8D7D, 0xDA62, 0x8D7E, 0xDA63, 0x8D7F, 0xDA64, 0x8D80, 0xDA65, 0x8D81, 0xB3C3, 0x8D82, 0xDA66, - 0x8D83, 0xDA67, 0x8D84, 0xF4F2, 0x8D85, 0xB3AC, 0x8D86, 0xDA68, 0x8D87, 0xDA69, 0x8D88, 0xDA6A, 0x8D89, 0xDA6B, 0x8D8A, 0xD4BD, - 0x8D8B, 0xC7F7, 0x8D8C, 0xDA6C, 0x8D8D, 0xDA6D, 0x8D8E, 0xDA6E, 0x8D8F, 0xDA6F, 0x8D90, 0xDA70, 0x8D91, 0xF4F4, 0x8D92, 0xDA71, - 0x8D93, 0xDA72, 0x8D94, 0xF4F3, 0x8D95, 0xDA73, 0x8D96, 0xDA74, 0x8D97, 0xDA75, 0x8D98, 0xDA76, 0x8D99, 0xDA77, 0x8D9A, 0xDA78, - 0x8D9B, 0xDA79, 0x8D9C, 0xDA7A, 0x8D9D, 0xDA7B, 0x8D9E, 0xDA7C, 0x8D9F, 0xCCCB, 0x8DA0, 0xDA7D, 0x8DA1, 0xDA7E, 0x8DA2, 0xDA80, - 0x8DA3, 0xC8A4, 0x8DA4, 0xDA81, 0x8DA5, 0xDA82, 0x8DA6, 0xDA83, 0x8DA7, 0xDA84, 0x8DA8, 0xDA85, 0x8DA9, 0xDA86, 0x8DAA, 0xDA87, - 0x8DAB, 0xDA88, 0x8DAC, 0xDA89, 0x8DAD, 0xDA8A, 0x8DAE, 0xDA8B, 0x8DAF, 0xDA8C, 0x8DB0, 0xDA8D, 0x8DB1, 0xF4F5, 0x8DB2, 0xDA8E, - 0x8DB3, 0xD7E3, 0x8DB4, 0xC5BF, 0x8DB5, 0xF5C0, 0x8DB6, 0xDA8F, 0x8DB7, 0xDA90, 0x8DB8, 0xF5BB, 0x8DB9, 0xDA91, 0x8DBA, 0xF5C3, - 0x8DBB, 0xDA92, 0x8DBC, 0xF5C2, 0x8DBD, 0xDA93, 0x8DBE, 0xD6BA, 0x8DBF, 0xF5C1, 0x8DC0, 0xDA94, 0x8DC1, 0xDA95, 0x8DC2, 0xDA96, - 0x8DC3, 0xD4BE, 0x8DC4, 0xF5C4, 0x8DC5, 0xDA97, 0x8DC6, 0xF5CC, 0x8DC7, 0xDA98, 0x8DC8, 0xDA99, 0x8DC9, 0xDA9A, 0x8DCA, 0xDA9B, - 0x8DCB, 0xB0CF, 0x8DCC, 0xB5F8, 0x8DCD, 0xDA9C, 0x8DCE, 0xF5C9, 0x8DCF, 0xF5CA, 0x8DD0, 0xDA9D, 0x8DD1, 0xC5DC, 0x8DD2, 0xDA9E, - 0x8DD3, 0xDA9F, 0x8DD4, 0xDAA0, 0x8DD5, 0xDB40, 0x8DD6, 0xF5C5, 0x8DD7, 0xF5C6, 0x8DD8, 0xDB41, 0x8DD9, 0xDB42, 0x8DDA, 0xF5C7, - 0x8DDB, 0xF5CB, 0x8DDC, 0xDB43, 0x8DDD, 0xBEE0, 0x8DDE, 0xF5C8, 0x8DDF, 0xB8FA, 0x8DE0, 0xDB44, 0x8DE1, 0xDB45, 0x8DE2, 0xDB46, - 0x8DE3, 0xF5D0, 0x8DE4, 0xF5D3, 0x8DE5, 0xDB47, 0x8DE6, 0xDB48, 0x8DE7, 0xDB49, 0x8DE8, 0xBFE7, 0x8DE9, 0xDB4A, 0x8DEA, 0xB9F2, - 0x8DEB, 0xF5BC, 0x8DEC, 0xF5CD, 0x8DED, 0xDB4B, 0x8DEE, 0xDB4C, 0x8DEF, 0xC2B7, 0x8DF0, 0xDB4D, 0x8DF1, 0xDB4E, 0x8DF2, 0xDB4F, - 0x8DF3, 0xCCF8, 0x8DF4, 0xDB50, 0x8DF5, 0xBCF9, 0x8DF6, 0xDB51, 0x8DF7, 0xF5CE, 0x8DF8, 0xF5CF, 0x8DF9, 0xF5D1, 0x8DFA, 0xB6E5, - 0x8DFB, 0xF5D2, 0x8DFC, 0xDB52, 0x8DFD, 0xF5D5, 0x8DFE, 0xDB53, 0x8DFF, 0xDB54, 0x8E00, 0xDB55, 0x8E01, 0xDB56, 0x8E02, 0xDB57, - 0x8E03, 0xDB58, 0x8E04, 0xDB59, 0x8E05, 0xF5BD, 0x8E06, 0xDB5A, 0x8E07, 0xDB5B, 0x8E08, 0xDB5C, 0x8E09, 0xF5D4, 0x8E0A, 0xD3BB, - 0x8E0B, 0xDB5D, 0x8E0C, 0xB3EC, 0x8E0D, 0xDB5E, 0x8E0E, 0xDB5F, 0x8E0F, 0xCCA4, 0x8E10, 0xDB60, 0x8E11, 0xDB61, 0x8E12, 0xDB62, - 0x8E13, 0xDB63, 0x8E14, 0xF5D6, 0x8E15, 0xDB64, 0x8E16, 0xDB65, 0x8E17, 0xDB66, 0x8E18, 0xDB67, 0x8E19, 0xDB68, 0x8E1A, 0xDB69, - 0x8E1B, 0xDB6A, 0x8E1C, 0xDB6B, 0x8E1D, 0xF5D7, 0x8E1E, 0xBEE1, 0x8E1F, 0xF5D8, 0x8E20, 0xDB6C, 0x8E21, 0xDB6D, 0x8E22, 0xCCDF, - 0x8E23, 0xF5DB, 0x8E24, 0xDB6E, 0x8E25, 0xDB6F, 0x8E26, 0xDB70, 0x8E27, 0xDB71, 0x8E28, 0xDB72, 0x8E29, 0xB2C8, 0x8E2A, 0xD7D9, - 0x8E2B, 0xDB73, 0x8E2C, 0xF5D9, 0x8E2D, 0xDB74, 0x8E2E, 0xF5DA, 0x8E2F, 0xF5DC, 0x8E30, 0xDB75, 0x8E31, 0xF5E2, 0x8E32, 0xDB76, - 0x8E33, 0xDB77, 0x8E34, 0xDB78, 0x8E35, 0xF5E0, 0x8E36, 0xDB79, 0x8E37, 0xDB7A, 0x8E38, 0xDB7B, 0x8E39, 0xF5DF, 0x8E3A, 0xF5DD, - 0x8E3B, 0xDB7C, 0x8E3C, 0xDB7D, 0x8E3D, 0xF5E1, 0x8E3E, 0xDB7E, 0x8E3F, 0xDB80, 0x8E40, 0xF5DE, 0x8E41, 0xF5E4, 0x8E42, 0xF5E5, - 0x8E43, 0xDB81, 0x8E44, 0xCCE3, 0x8E45, 0xDB82, 0x8E46, 0xDB83, 0x8E47, 0xE5BF, 0x8E48, 0xB5B8, 0x8E49, 0xF5E3, 0x8E4A, 0xF5E8, - 0x8E4B, 0xCCA3, 0x8E4C, 0xDB84, 0x8E4D, 0xDB85, 0x8E4E, 0xDB86, 0x8E4F, 0xDB87, 0x8E50, 0xDB88, 0x8E51, 0xF5E6, 0x8E52, 0xF5E7, - 0x8E53, 0xDB89, 0x8E54, 0xDB8A, 0x8E55, 0xDB8B, 0x8E56, 0xDB8C, 0x8E57, 0xDB8D, 0x8E58, 0xDB8E, 0x8E59, 0xF5BE, 0x8E5A, 0xDB8F, - 0x8E5B, 0xDB90, 0x8E5C, 0xDB91, 0x8E5D, 0xDB92, 0x8E5E, 0xDB93, 0x8E5F, 0xDB94, 0x8E60, 0xDB95, 0x8E61, 0xDB96, 0x8E62, 0xDB97, - 0x8E63, 0xDB98, 0x8E64, 0xDB99, 0x8E65, 0xDB9A, 0x8E66, 0xB1C4, 0x8E67, 0xDB9B, 0x8E68, 0xDB9C, 0x8E69, 0xF5BF, 0x8E6A, 0xDB9D, - 0x8E6B, 0xDB9E, 0x8E6C, 0xB5C5, 0x8E6D, 0xB2E4, 0x8E6E, 0xDB9F, 0x8E6F, 0xF5EC, 0x8E70, 0xF5E9, 0x8E71, 0xDBA0, 0x8E72, 0xB6D7, - 0x8E73, 0xDC40, 0x8E74, 0xF5ED, 0x8E75, 0xDC41, 0x8E76, 0xF5EA, 0x8E77, 0xDC42, 0x8E78, 0xDC43, 0x8E79, 0xDC44, 0x8E7A, 0xDC45, - 0x8E7B, 0xDC46, 0x8E7C, 0xF5EB, 0x8E7D, 0xDC47, 0x8E7E, 0xDC48, 0x8E7F, 0xB4DA, 0x8E80, 0xDC49, 0x8E81, 0xD4EA, 0x8E82, 0xDC4A, - 0x8E83, 0xDC4B, 0x8E84, 0xDC4C, 0x8E85, 0xF5EE, 0x8E86, 0xDC4D, 0x8E87, 0xB3F9, 0x8E88, 0xDC4E, 0x8E89, 0xDC4F, 0x8E8A, 0xDC50, - 0x8E8B, 0xDC51, 0x8E8C, 0xDC52, 0x8E8D, 0xDC53, 0x8E8E, 0xDC54, 0x8E8F, 0xF5EF, 0x8E90, 0xF5F1, 0x8E91, 0xDC55, 0x8E92, 0xDC56, - 0x8E93, 0xDC57, 0x8E94, 0xF5F0, 0x8E95, 0xDC58, 0x8E96, 0xDC59, 0x8E97, 0xDC5A, 0x8E98, 0xDC5B, 0x8E99, 0xDC5C, 0x8E9A, 0xDC5D, - 0x8E9B, 0xDC5E, 0x8E9C, 0xF5F2, 0x8E9D, 0xDC5F, 0x8E9E, 0xF5F3, 0x8E9F, 0xDC60, 0x8EA0, 0xDC61, 0x8EA1, 0xDC62, 0x8EA2, 0xDC63, - 0x8EA3, 0xDC64, 0x8EA4, 0xDC65, 0x8EA5, 0xDC66, 0x8EA6, 0xDC67, 0x8EA7, 0xDC68, 0x8EA8, 0xDC69, 0x8EA9, 0xDC6A, 0x8EAA, 0xDC6B, - 0x8EAB, 0xC9ED, 0x8EAC, 0xB9AA, 0x8EAD, 0xDC6C, 0x8EAE, 0xDC6D, 0x8EAF, 0xC7FB, 0x8EB0, 0xDC6E, 0x8EB1, 0xDC6F, 0x8EB2, 0xB6E3, - 0x8EB3, 0xDC70, 0x8EB4, 0xDC71, 0x8EB5, 0xDC72, 0x8EB6, 0xDC73, 0x8EB7, 0xDC74, 0x8EB8, 0xDC75, 0x8EB9, 0xDC76, 0x8EBA, 0xCCC9, - 0x8EBB, 0xDC77, 0x8EBC, 0xDC78, 0x8EBD, 0xDC79, 0x8EBE, 0xDC7A, 0x8EBF, 0xDC7B, 0x8EC0, 0xDC7C, 0x8EC1, 0xDC7D, 0x8EC2, 0xDC7E, - 0x8EC3, 0xDC80, 0x8EC4, 0xDC81, 0x8EC5, 0xDC82, 0x8EC6, 0xDC83, 0x8EC7, 0xDC84, 0x8EC8, 0xDC85, 0x8EC9, 0xDC86, 0x8ECA, 0xDC87, - 0x8ECB, 0xDC88, 0x8ECC, 0xDC89, 0x8ECD, 0xDC8A, 0x8ECE, 0xEAA6, 0x8ECF, 0xDC8B, 0x8ED0, 0xDC8C, 0x8ED1, 0xDC8D, 0x8ED2, 0xDC8E, - 0x8ED3, 0xDC8F, 0x8ED4, 0xDC90, 0x8ED5, 0xDC91, 0x8ED6, 0xDC92, 0x8ED7, 0xDC93, 0x8ED8, 0xDC94, 0x8ED9, 0xDC95, 0x8EDA, 0xDC96, - 0x8EDB, 0xDC97, 0x8EDC, 0xDC98, 0x8EDD, 0xDC99, 0x8EDE, 0xDC9A, 0x8EDF, 0xDC9B, 0x8EE0, 0xDC9C, 0x8EE1, 0xDC9D, 0x8EE2, 0xDC9E, - 0x8EE3, 0xDC9F, 0x8EE4, 0xDCA0, 0x8EE5, 0xDD40, 0x8EE6, 0xDD41, 0x8EE7, 0xDD42, 0x8EE8, 0xDD43, 0x8EE9, 0xDD44, 0x8EEA, 0xDD45, - 0x8EEB, 0xDD46, 0x8EEC, 0xDD47, 0x8EED, 0xDD48, 0x8EEE, 0xDD49, 0x8EEF, 0xDD4A, 0x8EF0, 0xDD4B, 0x8EF1, 0xDD4C, 0x8EF2, 0xDD4D, - 0x8EF3, 0xDD4E, 0x8EF4, 0xDD4F, 0x8EF5, 0xDD50, 0x8EF6, 0xDD51, 0x8EF7, 0xDD52, 0x8EF8, 0xDD53, 0x8EF9, 0xDD54, 0x8EFA, 0xDD55, - 0x8EFB, 0xDD56, 0x8EFC, 0xDD57, 0x8EFD, 0xDD58, 0x8EFE, 0xDD59, 0x8EFF, 0xDD5A, 0x8F00, 0xDD5B, 0x8F01, 0xDD5C, 0x8F02, 0xDD5D, - 0x8F03, 0xDD5E, 0x8F04, 0xDD5F, 0x8F05, 0xDD60, 0x8F06, 0xDD61, 0x8F07, 0xDD62, 0x8F08, 0xDD63, 0x8F09, 0xDD64, 0x8F0A, 0xDD65, - 0x8F0B, 0xDD66, 0x8F0C, 0xDD67, 0x8F0D, 0xDD68, 0x8F0E, 0xDD69, 0x8F0F, 0xDD6A, 0x8F10, 0xDD6B, 0x8F11, 0xDD6C, 0x8F12, 0xDD6D, - 0x8F13, 0xDD6E, 0x8F14, 0xDD6F, 0x8F15, 0xDD70, 0x8F16, 0xDD71, 0x8F17, 0xDD72, 0x8F18, 0xDD73, 0x8F19, 0xDD74, 0x8F1A, 0xDD75, - 0x8F1B, 0xDD76, 0x8F1C, 0xDD77, 0x8F1D, 0xDD78, 0x8F1E, 0xDD79, 0x8F1F, 0xDD7A, 0x8F20, 0xDD7B, 0x8F21, 0xDD7C, 0x8F22, 0xDD7D, - 0x8F23, 0xDD7E, 0x8F24, 0xDD80, 0x8F25, 0xDD81, 0x8F26, 0xDD82, 0x8F27, 0xDD83, 0x8F28, 0xDD84, 0x8F29, 0xDD85, 0x8F2A, 0xDD86, - 0x8F2B, 0xDD87, 0x8F2C, 0xDD88, 0x8F2D, 0xDD89, 0x8F2E, 0xDD8A, 0x8F2F, 0xDD8B, 0x8F30, 0xDD8C, 0x8F31, 0xDD8D, 0x8F32, 0xDD8E, - 0x8F33, 0xDD8F, 0x8F34, 0xDD90, 0x8F35, 0xDD91, 0x8F36, 0xDD92, 0x8F37, 0xDD93, 0x8F38, 0xDD94, 0x8F39, 0xDD95, 0x8F3A, 0xDD96, - 0x8F3B, 0xDD97, 0x8F3C, 0xDD98, 0x8F3D, 0xDD99, 0x8F3E, 0xDD9A, 0x8F3F, 0xDD9B, 0x8F40, 0xDD9C, 0x8F41, 0xDD9D, 0x8F42, 0xDD9E, - 0x8F43, 0xDD9F, 0x8F44, 0xDDA0, 0x8F45, 0xDE40, 0x8F46, 0xDE41, 0x8F47, 0xDE42, 0x8F48, 0xDE43, 0x8F49, 0xDE44, 0x8F4A, 0xDE45, - 0x8F4B, 0xDE46, 0x8F4C, 0xDE47, 0x8F4D, 0xDE48, 0x8F4E, 0xDE49, 0x8F4F, 0xDE4A, 0x8F50, 0xDE4B, 0x8F51, 0xDE4C, 0x8F52, 0xDE4D, - 0x8F53, 0xDE4E, 0x8F54, 0xDE4F, 0x8F55, 0xDE50, 0x8F56, 0xDE51, 0x8F57, 0xDE52, 0x8F58, 0xDE53, 0x8F59, 0xDE54, 0x8F5A, 0xDE55, - 0x8F5B, 0xDE56, 0x8F5C, 0xDE57, 0x8F5D, 0xDE58, 0x8F5E, 0xDE59, 0x8F5F, 0xDE5A, 0x8F60, 0xDE5B, 0x8F61, 0xDE5C, 0x8F62, 0xDE5D, - 0x8F63, 0xDE5E, 0x8F64, 0xDE5F, 0x8F65, 0xDE60, 0x8F66, 0xB3B5, 0x8F67, 0xD4FE, 0x8F68, 0xB9EC, 0x8F69, 0xD0F9, 0x8F6A, 0xDE61, - 0x8F6B, 0xE9ED, 0x8F6C, 0xD7AA, 0x8F6D, 0xE9EE, 0x8F6E, 0xC2D6, 0x8F6F, 0xC8ED, 0x8F70, 0xBAE4, 0x8F71, 0xE9EF, 0x8F72, 0xE9F0, - 0x8F73, 0xE9F1, 0x8F74, 0xD6E1, 0x8F75, 0xE9F2, 0x8F76, 0xE9F3, 0x8F77, 0xE9F5, 0x8F78, 0xE9F4, 0x8F79, 0xE9F6, 0x8F7A, 0xE9F7, - 0x8F7B, 0xC7E1, 0x8F7C, 0xE9F8, 0x8F7D, 0xD4D8, 0x8F7E, 0xE9F9, 0x8F7F, 0xBDCE, 0x8F80, 0xDE62, 0x8F81, 0xE9FA, 0x8F82, 0xE9FB, - 0x8F83, 0xBDCF, 0x8F84, 0xE9FC, 0x8F85, 0xB8A8, 0x8F86, 0xC1BE, 0x8F87, 0xE9FD, 0x8F88, 0xB1B2, 0x8F89, 0xBBD4, 0x8F8A, 0xB9F5, - 0x8F8B, 0xE9FE, 0x8F8C, 0xDE63, 0x8F8D, 0xEAA1, 0x8F8E, 0xEAA2, 0x8F8F, 0xEAA3, 0x8F90, 0xB7F8, 0x8F91, 0xBCAD, 0x8F92, 0xDE64, - 0x8F93, 0xCAE4, 0x8F94, 0xE0CE, 0x8F95, 0xD4AF, 0x8F96, 0xCFBD, 0x8F97, 0xD5B7, 0x8F98, 0xEAA4, 0x8F99, 0xD5DE, 0x8F9A, 0xEAA5, - 0x8F9B, 0xD0C1, 0x8F9C, 0xB9BC, 0x8F9D, 0xDE65, 0x8F9E, 0xB4C7, 0x8F9F, 0xB1D9, 0x8FA0, 0xDE66, 0x8FA1, 0xDE67, 0x8FA2, 0xDE68, - 0x8FA3, 0xC0B1, 0x8FA4, 0xDE69, 0x8FA5, 0xDE6A, 0x8FA6, 0xDE6B, 0x8FA7, 0xDE6C, 0x8FA8, 0xB1E6, 0x8FA9, 0xB1E7, 0x8FAA, 0xDE6D, - 0x8FAB, 0xB1E8, 0x8FAC, 0xDE6E, 0x8FAD, 0xDE6F, 0x8FAE, 0xDE70, 0x8FAF, 0xDE71, 0x8FB0, 0xB3BD, 0x8FB1, 0xC8E8, 0x8FB2, 0xDE72, - 0x8FB3, 0xDE73, 0x8FB4, 0xDE74, 0x8FB5, 0xDE75, 0x8FB6, 0xE5C1, 0x8FB7, 0xDE76, 0x8FB8, 0xDE77, 0x8FB9, 0xB1DF, 0x8FBA, 0xDE78, - 0x8FBB, 0xDE79, 0x8FBC, 0xDE7A, 0x8FBD, 0xC1C9, 0x8FBE, 0xB4EF, 0x8FBF, 0xDE7B, 0x8FC0, 0xDE7C, 0x8FC1, 0xC7A8, 0x8FC2, 0xD3D8, - 0x8FC3, 0xDE7D, 0x8FC4, 0xC6F9, 0x8FC5, 0xD1B8, 0x8FC6, 0xDE7E, 0x8FC7, 0xB9FD, 0x8FC8, 0xC2F5, 0x8FC9, 0xDE80, 0x8FCA, 0xDE81, - 0x8FCB, 0xDE82, 0x8FCC, 0xDE83, 0x8FCD, 0xDE84, 0x8FCE, 0xD3AD, 0x8FCF, 0xDE85, 0x8FD0, 0xD4CB, 0x8FD1, 0xBDFC, 0x8FD2, 0xDE86, - 0x8FD3, 0xE5C2, 0x8FD4, 0xB7B5, 0x8FD5, 0xE5C3, 0x8FD6, 0xDE87, 0x8FD7, 0xDE88, 0x8FD8, 0xBBB9, 0x8FD9, 0xD5E2, 0x8FDA, 0xDE89, - 0x8FDB, 0xBDF8, 0x8FDC, 0xD4B6, 0x8FDD, 0xCEA5, 0x8FDE, 0xC1AC, 0x8FDF, 0xB3D9, 0x8FE0, 0xDE8A, 0x8FE1, 0xDE8B, 0x8FE2, 0xCCF6, - 0x8FE3, 0xDE8C, 0x8FE4, 0xE5C6, 0x8FE5, 0xE5C4, 0x8FE6, 0xE5C8, 0x8FE7, 0xDE8D, 0x8FE8, 0xE5CA, 0x8FE9, 0xE5C7, 0x8FEA, 0xB5CF, - 0x8FEB, 0xC6C8, 0x8FEC, 0xDE8E, 0x8FED, 0xB5FC, 0x8FEE, 0xE5C5, 0x8FEF, 0xDE8F, 0x8FF0, 0xCAF6, 0x8FF1, 0xDE90, 0x8FF2, 0xDE91, - 0x8FF3, 0xE5C9, 0x8FF4, 0xDE92, 0x8FF5, 0xDE93, 0x8FF6, 0xDE94, 0x8FF7, 0xC3D4, 0x8FF8, 0xB1C5, 0x8FF9, 0xBCA3, 0x8FFA, 0xDE95, - 0x8FFB, 0xDE96, 0x8FFC, 0xDE97, 0x8FFD, 0xD7B7, 0x8FFE, 0xDE98, 0x8FFF, 0xDE99, 0x9000, 0xCDCB, 0x9001, 0xCBCD, 0x9002, 0xCACA, - 0x9003, 0xCCD3, 0x9004, 0xE5CC, 0x9005, 0xE5CB, 0x9006, 0xC4E6, 0x9007, 0xDE9A, 0x9008, 0xDE9B, 0x9009, 0xD1A1, 0x900A, 0xD1B7, - 0x900B, 0xE5CD, 0x900C, 0xDE9C, 0x900D, 0xE5D0, 0x900E, 0xDE9D, 0x900F, 0xCDB8, 0x9010, 0xD6F0, 0x9011, 0xE5CF, 0x9012, 0xB5DD, - 0x9013, 0xDE9E, 0x9014, 0xCDBE, 0x9015, 0xDE9F, 0x9016, 0xE5D1, 0x9017, 0xB6BA, 0x9018, 0xDEA0, 0x9019, 0xDF40, 0x901A, 0xCDA8, - 0x901B, 0xB9E4, 0x901C, 0xDF41, 0x901D, 0xCAC5, 0x901E, 0xB3D1, 0x901F, 0xCBD9, 0x9020, 0xD4EC, 0x9021, 0xE5D2, 0x9022, 0xB7EA, - 0x9023, 0xDF42, 0x9024, 0xDF43, 0x9025, 0xDF44, 0x9026, 0xE5CE, 0x9027, 0xDF45, 0x9028, 0xDF46, 0x9029, 0xDF47, 0x902A, 0xDF48, - 0x902B, 0xDF49, 0x902C, 0xDF4A, 0x902D, 0xE5D5, 0x902E, 0xB4FE, 0x902F, 0xE5D6, 0x9030, 0xDF4B, 0x9031, 0xDF4C, 0x9032, 0xDF4D, - 0x9033, 0xDF4E, 0x9034, 0xDF4F, 0x9035, 0xE5D3, 0x9036, 0xE5D4, 0x9037, 0xDF50, 0x9038, 0xD2DD, 0x9039, 0xDF51, 0x903A, 0xDF52, - 0x903B, 0xC2DF, 0x903C, 0xB1C6, 0x903D, 0xDF53, 0x903E, 0xD3E2, 0x903F, 0xDF54, 0x9040, 0xDF55, 0x9041, 0xB6DD, 0x9042, 0xCBEC, - 0x9043, 0xDF56, 0x9044, 0xE5D7, 0x9045, 0xDF57, 0x9046, 0xDF58, 0x9047, 0xD3F6, 0x9048, 0xDF59, 0x9049, 0xDF5A, 0x904A, 0xDF5B, - 0x904B, 0xDF5C, 0x904C, 0xDF5D, 0x904D, 0xB1E9, 0x904E, 0xDF5E, 0x904F, 0xB6F4, 0x9050, 0xE5DA, 0x9051, 0xE5D8, 0x9052, 0xE5D9, - 0x9053, 0xB5C0, 0x9054, 0xDF5F, 0x9055, 0xDF60, 0x9056, 0xDF61, 0x9057, 0xD2C5, 0x9058, 0xE5DC, 0x9059, 0xDF62, 0x905A, 0xDF63, - 0x905B, 0xE5DE, 0x905C, 0xDF64, 0x905D, 0xDF65, 0x905E, 0xDF66, 0x905F, 0xDF67, 0x9060, 0xDF68, 0x9061, 0xDF69, 0x9062, 0xE5DD, - 0x9063, 0xC7B2, 0x9064, 0xDF6A, 0x9065, 0xD2A3, 0x9066, 0xDF6B, 0x9067, 0xDF6C, 0x9068, 0xE5DB, 0x9069, 0xDF6D, 0x906A, 0xDF6E, - 0x906B, 0xDF6F, 0x906C, 0xDF70, 0x906D, 0xD4E2, 0x906E, 0xD5DA, 0x906F, 0xDF71, 0x9070, 0xDF72, 0x9071, 0xDF73, 0x9072, 0xDF74, - 0x9073, 0xDF75, 0x9074, 0xE5E0, 0x9075, 0xD7F1, 0x9076, 0xDF76, 0x9077, 0xDF77, 0x9078, 0xDF78, 0x9079, 0xDF79, 0x907A, 0xDF7A, - 0x907B, 0xDF7B, 0x907C, 0xDF7C, 0x907D, 0xE5E1, 0x907E, 0xDF7D, 0x907F, 0xB1DC, 0x9080, 0xD1FB, 0x9081, 0xDF7E, 0x9082, 0xE5E2, - 0x9083, 0xE5E4, 0x9084, 0xDF80, 0x9085, 0xDF81, 0x9086, 0xDF82, 0x9087, 0xDF83, 0x9088, 0xE5E3, 0x9089, 0xDF84, 0x908A, 0xDF85, - 0x908B, 0xE5E5, 0x908C, 0xDF86, 0x908D, 0xDF87, 0x908E, 0xDF88, 0x908F, 0xDF89, 0x9090, 0xDF8A, 0x9091, 0xD2D8, 0x9092, 0xDF8B, - 0x9093, 0xB5CB, 0x9094, 0xDF8C, 0x9095, 0xE7DF, 0x9096, 0xDF8D, 0x9097, 0xDAF5, 0x9098, 0xDF8E, 0x9099, 0xDAF8, 0x909A, 0xDF8F, - 0x909B, 0xDAF6, 0x909C, 0xDF90, 0x909D, 0xDAF7, 0x909E, 0xDF91, 0x909F, 0xDF92, 0x90A0, 0xDF93, 0x90A1, 0xDAFA, 0x90A2, 0xD0CF, - 0x90A3, 0xC4C7, 0x90A4, 0xDF94, 0x90A5, 0xDF95, 0x90A6, 0xB0EE, 0x90A7, 0xDF96, 0x90A8, 0xDF97, 0x90A9, 0xDF98, 0x90AA, 0xD0B0, - 0x90AB, 0xDF99, 0x90AC, 0xDAF9, 0x90AD, 0xDF9A, 0x90AE, 0xD3CA, 0x90AF, 0xBAAA, 0x90B0, 0xDBA2, 0x90B1, 0xC7F1, 0x90B2, 0xDF9B, - 0x90B3, 0xDAFC, 0x90B4, 0xDAFB, 0x90B5, 0xC9DB, 0x90B6, 0xDAFD, 0x90B7, 0xDF9C, 0x90B8, 0xDBA1, 0x90B9, 0xD7DE, 0x90BA, 0xDAFE, - 0x90BB, 0xC1DA, 0x90BC, 0xDF9D, 0x90BD, 0xDF9E, 0x90BE, 0xDBA5, 0x90BF, 0xDF9F, 0x90C0, 0xDFA0, 0x90C1, 0xD3F4, 0x90C2, 0xE040, - 0x90C3, 0xE041, 0x90C4, 0xDBA7, 0x90C5, 0xDBA4, 0x90C6, 0xE042, 0x90C7, 0xDBA8, 0x90C8, 0xE043, 0x90C9, 0xE044, 0x90CA, 0xBDBC, - 0x90CB, 0xE045, 0x90CC, 0xE046, 0x90CD, 0xE047, 0x90CE, 0xC0C9, 0x90CF, 0xDBA3, 0x90D0, 0xDBA6, 0x90D1, 0xD6A3, 0x90D2, 0xE048, - 0x90D3, 0xDBA9, 0x90D4, 0xE049, 0x90D5, 0xE04A, 0x90D6, 0xE04B, 0x90D7, 0xDBAD, 0x90D8, 0xE04C, 0x90D9, 0xE04D, 0x90DA, 0xE04E, - 0x90DB, 0xDBAE, 0x90DC, 0xDBAC, 0x90DD, 0xBAC2, 0x90DE, 0xE04F, 0x90DF, 0xE050, 0x90E0, 0xE051, 0x90E1, 0xBFA4, 0x90E2, 0xDBAB, - 0x90E3, 0xE052, 0x90E4, 0xE053, 0x90E5, 0xE054, 0x90E6, 0xDBAA, 0x90E7, 0xD4C7, 0x90E8, 0xB2BF, 0x90E9, 0xE055, 0x90EA, 0xE056, - 0x90EB, 0xDBAF, 0x90EC, 0xE057, 0x90ED, 0xB9F9, 0x90EE, 0xE058, 0x90EF, 0xDBB0, 0x90F0, 0xE059, 0x90F1, 0xE05A, 0x90F2, 0xE05B, - 0x90F3, 0xE05C, 0x90F4, 0xB3BB, 0x90F5, 0xE05D, 0x90F6, 0xE05E, 0x90F7, 0xE05F, 0x90F8, 0xB5A6, 0x90F9, 0xE060, 0x90FA, 0xE061, - 0x90FB, 0xE062, 0x90FC, 0xE063, 0x90FD, 0xB6BC, 0x90FE, 0xDBB1, 0x90FF, 0xE064, 0x9100, 0xE065, 0x9101, 0xE066, 0x9102, 0xB6F5, - 0x9103, 0xE067, 0x9104, 0xDBB2, 0x9105, 0xE068, 0x9106, 0xE069, 0x9107, 0xE06A, 0x9108, 0xE06B, 0x9109, 0xE06C, 0x910A, 0xE06D, - 0x910B, 0xE06E, 0x910C, 0xE06F, 0x910D, 0xE070, 0x910E, 0xE071, 0x910F, 0xE072, 0x9110, 0xE073, 0x9111, 0xE074, 0x9112, 0xE075, - 0x9113, 0xE076, 0x9114, 0xE077, 0x9115, 0xE078, 0x9116, 0xE079, 0x9117, 0xE07A, 0x9118, 0xE07B, 0x9119, 0xB1C9, 0x911A, 0xE07C, - 0x911B, 0xE07D, 0x911C, 0xE07E, 0x911D, 0xE080, 0x911E, 0xDBB4, 0x911F, 0xE081, 0x9120, 0xE082, 0x9121, 0xE083, 0x9122, 0xDBB3, - 0x9123, 0xDBB5, 0x9124, 0xE084, 0x9125, 0xE085, 0x9126, 0xE086, 0x9127, 0xE087, 0x9128, 0xE088, 0x9129, 0xE089, 0x912A, 0xE08A, - 0x912B, 0xE08B, 0x912C, 0xE08C, 0x912D, 0xE08D, 0x912E, 0xE08E, 0x912F, 0xDBB7, 0x9130, 0xE08F, 0x9131, 0xDBB6, 0x9132, 0xE090, - 0x9133, 0xE091, 0x9134, 0xE092, 0x9135, 0xE093, 0x9136, 0xE094, 0x9137, 0xE095, 0x9138, 0xE096, 0x9139, 0xDBB8, 0x913A, 0xE097, - 0x913B, 0xE098, 0x913C, 0xE099, 0x913D, 0xE09A, 0x913E, 0xE09B, 0x913F, 0xE09C, 0x9140, 0xE09D, 0x9141, 0xE09E, 0x9142, 0xE09F, - 0x9143, 0xDBB9, 0x9144, 0xE0A0, 0x9145, 0xE140, 0x9146, 0xDBBA, 0x9147, 0xE141, 0x9148, 0xE142, 0x9149, 0xD3CF, 0x914A, 0xF4FA, - 0x914B, 0xC7F5, 0x914C, 0xD7C3, 0x914D, 0xC5E4, 0x914E, 0xF4FC, 0x914F, 0xF4FD, 0x9150, 0xF4FB, 0x9151, 0xE143, 0x9152, 0xBEC6, - 0x9153, 0xE144, 0x9154, 0xE145, 0x9155, 0xE146, 0x9156, 0xE147, 0x9157, 0xD0EF, 0x9158, 0xE148, 0x9159, 0xE149, 0x915A, 0xB7D3, - 0x915B, 0xE14A, 0x915C, 0xE14B, 0x915D, 0xD4CD, 0x915E, 0xCCAA, 0x915F, 0xE14C, 0x9160, 0xE14D, 0x9161, 0xF5A2, 0x9162, 0xF5A1, - 0x9163, 0xBAA8, 0x9164, 0xF4FE, 0x9165, 0xCBD6, 0x9166, 0xE14E, 0x9167, 0xE14F, 0x9168, 0xE150, 0x9169, 0xF5A4, 0x916A, 0xC0D2, - 0x916B, 0xE151, 0x916C, 0xB3EA, 0x916D, 0xE152, 0x916E, 0xCDAA, 0x916F, 0xF5A5, 0x9170, 0xF5A3, 0x9171, 0xBDB4, 0x9172, 0xF5A8, - 0x9173, 0xE153, 0x9174, 0xF5A9, 0x9175, 0xBDCD, 0x9176, 0xC3B8, 0x9177, 0xBFE1, 0x9178, 0xCBE1, 0x9179, 0xF5AA, 0x917A, 0xE154, - 0x917B, 0xE155, 0x917C, 0xE156, 0x917D, 0xF5A6, 0x917E, 0xF5A7, 0x917F, 0xC4F0, 0x9180, 0xE157, 0x9181, 0xE158, 0x9182, 0xE159, - 0x9183, 0xE15A, 0x9184, 0xE15B, 0x9185, 0xF5AC, 0x9186, 0xE15C, 0x9187, 0xB4BC, 0x9188, 0xE15D, 0x9189, 0xD7ED, 0x918A, 0xE15E, - 0x918B, 0xB4D7, 0x918C, 0xF5AB, 0x918D, 0xF5AE, 0x918E, 0xE15F, 0x918F, 0xE160, 0x9190, 0xF5AD, 0x9191, 0xF5AF, 0x9192, 0xD0D1, - 0x9193, 0xE161, 0x9194, 0xE162, 0x9195, 0xE163, 0x9196, 0xE164, 0x9197, 0xE165, 0x9198, 0xE166, 0x9199, 0xE167, 0x919A, 0xC3D1, - 0x919B, 0xC8A9, 0x919C, 0xE168, 0x919D, 0xE169, 0x919E, 0xE16A, 0x919F, 0xE16B, 0x91A0, 0xE16C, 0x91A1, 0xE16D, 0x91A2, 0xF5B0, - 0x91A3, 0xF5B1, 0x91A4, 0xE16E, 0x91A5, 0xE16F, 0x91A6, 0xE170, 0x91A7, 0xE171, 0x91A8, 0xE172, 0x91A9, 0xE173, 0x91AA, 0xF5B2, - 0x91AB, 0xE174, 0x91AC, 0xE175, 0x91AD, 0xF5B3, 0x91AE, 0xF5B4, 0x91AF, 0xF5B5, 0x91B0, 0xE176, 0x91B1, 0xE177, 0x91B2, 0xE178, - 0x91B3, 0xE179, 0x91B4, 0xF5B7, 0x91B5, 0xF5B6, 0x91B6, 0xE17A, 0x91B7, 0xE17B, 0x91B8, 0xE17C, 0x91B9, 0xE17D, 0x91BA, 0xF5B8, - 0x91BB, 0xE17E, 0x91BC, 0xE180, 0x91BD, 0xE181, 0x91BE, 0xE182, 0x91BF, 0xE183, 0x91C0, 0xE184, 0x91C1, 0xE185, 0x91C2, 0xE186, - 0x91C3, 0xE187, 0x91C4, 0xE188, 0x91C5, 0xE189, 0x91C6, 0xE18A, 0x91C7, 0xB2C9, 0x91C8, 0xE18B, 0x91C9, 0xD3D4, 0x91CA, 0xCACD, - 0x91CB, 0xE18C, 0x91CC, 0xC0EF, 0x91CD, 0xD6D8, 0x91CE, 0xD2B0, 0x91CF, 0xC1BF, 0x91D0, 0xE18D, 0x91D1, 0xBDF0, 0x91D2, 0xE18E, - 0x91D3, 0xE18F, 0x91D4, 0xE190, 0x91D5, 0xE191, 0x91D6, 0xE192, 0x91D7, 0xE193, 0x91D8, 0xE194, 0x91D9, 0xE195, 0x91DA, 0xE196, - 0x91DB, 0xE197, 0x91DC, 0xB8AA, 0x91DD, 0xE198, 0x91DE, 0xE199, 0x91DF, 0xE19A, 0x91E0, 0xE19B, 0x91E1, 0xE19C, 0x91E2, 0xE19D, - 0x91E3, 0xE19E, 0x91E4, 0xE19F, 0x91E5, 0xE1A0, 0x91E6, 0xE240, 0x91E7, 0xE241, 0x91E8, 0xE242, 0x91E9, 0xE243, 0x91EA, 0xE244, - 0x91EB, 0xE245, 0x91EC, 0xE246, 0x91ED, 0xE247, 0x91EE, 0xE248, 0x91EF, 0xE249, 0x91F0, 0xE24A, 0x91F1, 0xE24B, 0x91F2, 0xE24C, - 0x91F3, 0xE24D, 0x91F4, 0xE24E, 0x91F5, 0xE24F, 0x91F6, 0xE250, 0x91F7, 0xE251, 0x91F8, 0xE252, 0x91F9, 0xE253, 0x91FA, 0xE254, - 0x91FB, 0xE255, 0x91FC, 0xE256, 0x91FD, 0xE257, 0x91FE, 0xE258, 0x91FF, 0xE259, 0x9200, 0xE25A, 0x9201, 0xE25B, 0x9202, 0xE25C, - 0x9203, 0xE25D, 0x9204, 0xE25E, 0x9205, 0xE25F, 0x9206, 0xE260, 0x9207, 0xE261, 0x9208, 0xE262, 0x9209, 0xE263, 0x920A, 0xE264, - 0x920B, 0xE265, 0x920C, 0xE266, 0x920D, 0xE267, 0x920E, 0xE268, 0x920F, 0xE269, 0x9210, 0xE26A, 0x9211, 0xE26B, 0x9212, 0xE26C, - 0x9213, 0xE26D, 0x9214, 0xE26E, 0x9215, 0xE26F, 0x9216, 0xE270, 0x9217, 0xE271, 0x9218, 0xE272, 0x9219, 0xE273, 0x921A, 0xE274, - 0x921B, 0xE275, 0x921C, 0xE276, 0x921D, 0xE277, 0x921E, 0xE278, 0x921F, 0xE279, 0x9220, 0xE27A, 0x9221, 0xE27B, 0x9222, 0xE27C, - 0x9223, 0xE27D, 0x9224, 0xE27E, 0x9225, 0xE280, 0x9226, 0xE281, 0x9227, 0xE282, 0x9228, 0xE283, 0x9229, 0xE284, 0x922A, 0xE285, - 0x922B, 0xE286, 0x922C, 0xE287, 0x922D, 0xE288, 0x922E, 0xE289, 0x922F, 0xE28A, 0x9230, 0xE28B, 0x9231, 0xE28C, 0x9232, 0xE28D, - 0x9233, 0xE28E, 0x9234, 0xE28F, 0x9235, 0xE290, 0x9236, 0xE291, 0x9237, 0xE292, 0x9238, 0xE293, 0x9239, 0xE294, 0x923A, 0xE295, - 0x923B, 0xE296, 0x923C, 0xE297, 0x923D, 0xE298, 0x923E, 0xE299, 0x923F, 0xE29A, 0x9240, 0xE29B, 0x9241, 0xE29C, 0x9242, 0xE29D, - 0x9243, 0xE29E, 0x9244, 0xE29F, 0x9245, 0xE2A0, 0x9246, 0xE340, 0x9247, 0xE341, 0x9248, 0xE342, 0x9249, 0xE343, 0x924A, 0xE344, - 0x924B, 0xE345, 0x924C, 0xE346, 0x924D, 0xE347, 0x924E, 0xE348, 0x924F, 0xE349, 0x9250, 0xE34A, 0x9251, 0xE34B, 0x9252, 0xE34C, - 0x9253, 0xE34D, 0x9254, 0xE34E, 0x9255, 0xE34F, 0x9256, 0xE350, 0x9257, 0xE351, 0x9258, 0xE352, 0x9259, 0xE353, 0x925A, 0xE354, - 0x925B, 0xE355, 0x925C, 0xE356, 0x925D, 0xE357, 0x925E, 0xE358, 0x925F, 0xE359, 0x9260, 0xE35A, 0x9261, 0xE35B, 0x9262, 0xE35C, - 0x9263, 0xE35D, 0x9264, 0xE35E, 0x9265, 0xE35F, 0x9266, 0xE360, 0x9267, 0xE361, 0x9268, 0xE362, 0x9269, 0xE363, 0x926A, 0xE364, - 0x926B, 0xE365, 0x926C, 0xE366, 0x926D, 0xE367, 0x926E, 0xE368, 0x926F, 0xE369, 0x9270, 0xE36A, 0x9271, 0xE36B, 0x9272, 0xE36C, - 0x9273, 0xE36D, 0x9274, 0xBCF8, 0x9275, 0xE36E, 0x9276, 0xE36F, 0x9277, 0xE370, 0x9278, 0xE371, 0x9279, 0xE372, 0x927A, 0xE373, - 0x927B, 0xE374, 0x927C, 0xE375, 0x927D, 0xE376, 0x927E, 0xE377, 0x927F, 0xE378, 0x9280, 0xE379, 0x9281, 0xE37A, 0x9282, 0xE37B, - 0x9283, 0xE37C, 0x9284, 0xE37D, 0x9285, 0xE37E, 0x9286, 0xE380, 0x9287, 0xE381, 0x9288, 0xE382, 0x9289, 0xE383, 0x928A, 0xE384, - 0x928B, 0xE385, 0x928C, 0xE386, 0x928D, 0xE387, 0x928E, 0xF6C6, 0x928F, 0xE388, 0x9290, 0xE389, 0x9291, 0xE38A, 0x9292, 0xE38B, - 0x9293, 0xE38C, 0x9294, 0xE38D, 0x9295, 0xE38E, 0x9296, 0xE38F, 0x9297, 0xE390, 0x9298, 0xE391, 0x9299, 0xE392, 0x929A, 0xE393, - 0x929B, 0xE394, 0x929C, 0xE395, 0x929D, 0xE396, 0x929E, 0xE397, 0x929F, 0xE398, 0x92A0, 0xE399, 0x92A1, 0xE39A, 0x92A2, 0xE39B, - 0x92A3, 0xE39C, 0x92A4, 0xE39D, 0x92A5, 0xE39E, 0x92A6, 0xE39F, 0x92A7, 0xE3A0, 0x92A8, 0xE440, 0x92A9, 0xE441, 0x92AA, 0xE442, - 0x92AB, 0xE443, 0x92AC, 0xE444, 0x92AD, 0xE445, 0x92AE, 0xF6C7, 0x92AF, 0xE446, 0x92B0, 0xE447, 0x92B1, 0xE448, 0x92B2, 0xE449, - 0x92B3, 0xE44A, 0x92B4, 0xE44B, 0x92B5, 0xE44C, 0x92B6, 0xE44D, 0x92B7, 0xE44E, 0x92B8, 0xE44F, 0x92B9, 0xE450, 0x92BA, 0xE451, - 0x92BB, 0xE452, 0x92BC, 0xE453, 0x92BD, 0xE454, 0x92BE, 0xE455, 0x92BF, 0xE456, 0x92C0, 0xE457, 0x92C1, 0xE458, 0x92C2, 0xE459, - 0x92C3, 0xE45A, 0x92C4, 0xE45B, 0x92C5, 0xE45C, 0x92C6, 0xE45D, 0x92C7, 0xE45E, 0x92C8, 0xF6C8, 0x92C9, 0xE45F, 0x92CA, 0xE460, - 0x92CB, 0xE461, 0x92CC, 0xE462, 0x92CD, 0xE463, 0x92CE, 0xE464, 0x92CF, 0xE465, 0x92D0, 0xE466, 0x92D1, 0xE467, 0x92D2, 0xE468, - 0x92D3, 0xE469, 0x92D4, 0xE46A, 0x92D5, 0xE46B, 0x92D6, 0xE46C, 0x92D7, 0xE46D, 0x92D8, 0xE46E, 0x92D9, 0xE46F, 0x92DA, 0xE470, - 0x92DB, 0xE471, 0x92DC, 0xE472, 0x92DD, 0xE473, 0x92DE, 0xE474, 0x92DF, 0xE475, 0x92E0, 0xE476, 0x92E1, 0xE477, 0x92E2, 0xE478, - 0x92E3, 0xE479, 0x92E4, 0xE47A, 0x92E5, 0xE47B, 0x92E6, 0xE47C, 0x92E7, 0xE47D, 0x92E8, 0xE47E, 0x92E9, 0xE480, 0x92EA, 0xE481, - 0x92EB, 0xE482, 0x92EC, 0xE483, 0x92ED, 0xE484, 0x92EE, 0xE485, 0x92EF, 0xE486, 0x92F0, 0xE487, 0x92F1, 0xE488, 0x92F2, 0xE489, - 0x92F3, 0xE48A, 0x92F4, 0xE48B, 0x92F5, 0xE48C, 0x92F6, 0xE48D, 0x92F7, 0xE48E, 0x92F8, 0xE48F, 0x92F9, 0xE490, 0x92FA, 0xE491, - 0x92FB, 0xE492, 0x92FC, 0xE493, 0x92FD, 0xE494, 0x92FE, 0xE495, 0x92FF, 0xE496, 0x9300, 0xE497, 0x9301, 0xE498, 0x9302, 0xE499, - 0x9303, 0xE49A, 0x9304, 0xE49B, 0x9305, 0xE49C, 0x9306, 0xE49D, 0x9307, 0xE49E, 0x9308, 0xE49F, 0x9309, 0xE4A0, 0x930A, 0xE540, - 0x930B, 0xE541, 0x930C, 0xE542, 0x930D, 0xE543, 0x930E, 0xE544, 0x930F, 0xE545, 0x9310, 0xE546, 0x9311, 0xE547, 0x9312, 0xE548, - 0x9313, 0xE549, 0x9314, 0xE54A, 0x9315, 0xE54B, 0x9316, 0xE54C, 0x9317, 0xE54D, 0x9318, 0xE54E, 0x9319, 0xE54F, 0x931A, 0xE550, - 0x931B, 0xE551, 0x931C, 0xE552, 0x931D, 0xE553, 0x931E, 0xE554, 0x931F, 0xE555, 0x9320, 0xE556, 0x9321, 0xE557, 0x9322, 0xE558, - 0x9323, 0xE559, 0x9324, 0xE55A, 0x9325, 0xE55B, 0x9326, 0xE55C, 0x9327, 0xE55D, 0x9328, 0xE55E, 0x9329, 0xE55F, 0x932A, 0xE560, - 0x932B, 0xE561, 0x932C, 0xE562, 0x932D, 0xE563, 0x932E, 0xE564, 0x932F, 0xE565, 0x9330, 0xE566, 0x9331, 0xE567, 0x9332, 0xE568, - 0x9333, 0xE569, 0x9334, 0xE56A, 0x9335, 0xE56B, 0x9336, 0xE56C, 0x9337, 0xE56D, 0x9338, 0xE56E, 0x9339, 0xE56F, 0x933A, 0xE570, - 0x933B, 0xE571, 0x933C, 0xE572, 0x933D, 0xE573, 0x933E, 0xF6C9, 0x933F, 0xE574, 0x9340, 0xE575, 0x9341, 0xE576, 0x9342, 0xE577, - 0x9343, 0xE578, 0x9344, 0xE579, 0x9345, 0xE57A, 0x9346, 0xE57B, 0x9347, 0xE57C, 0x9348, 0xE57D, 0x9349, 0xE57E, 0x934A, 0xE580, - 0x934B, 0xE581, 0x934C, 0xE582, 0x934D, 0xE583, 0x934E, 0xE584, 0x934F, 0xE585, 0x9350, 0xE586, 0x9351, 0xE587, 0x9352, 0xE588, - 0x9353, 0xE589, 0x9354, 0xE58A, 0x9355, 0xE58B, 0x9356, 0xE58C, 0x9357, 0xE58D, 0x9358, 0xE58E, 0x9359, 0xE58F, 0x935A, 0xE590, - 0x935B, 0xE591, 0x935C, 0xE592, 0x935D, 0xE593, 0x935E, 0xE594, 0x935F, 0xE595, 0x9360, 0xE596, 0x9361, 0xE597, 0x9362, 0xE598, - 0x9363, 0xE599, 0x9364, 0xE59A, 0x9365, 0xE59B, 0x9366, 0xE59C, 0x9367, 0xE59D, 0x9368, 0xE59E, 0x9369, 0xE59F, 0x936A, 0xF6CA, - 0x936B, 0xE5A0, 0x936C, 0xE640, 0x936D, 0xE641, 0x936E, 0xE642, 0x936F, 0xE643, 0x9370, 0xE644, 0x9371, 0xE645, 0x9372, 0xE646, - 0x9373, 0xE647, 0x9374, 0xE648, 0x9375, 0xE649, 0x9376, 0xE64A, 0x9377, 0xE64B, 0x9378, 0xE64C, 0x9379, 0xE64D, 0x937A, 0xE64E, - 0x937B, 0xE64F, 0x937C, 0xE650, 0x937D, 0xE651, 0x937E, 0xE652, 0x937F, 0xE653, 0x9380, 0xE654, 0x9381, 0xE655, 0x9382, 0xE656, - 0x9383, 0xE657, 0x9384, 0xE658, 0x9385, 0xE659, 0x9386, 0xE65A, 0x9387, 0xE65B, 0x9388, 0xE65C, 0x9389, 0xE65D, 0x938A, 0xE65E, - 0x938B, 0xE65F, 0x938C, 0xE660, 0x938D, 0xE661, 0x938E, 0xE662, 0x938F, 0xF6CC, 0x9390, 0xE663, 0x9391, 0xE664, 0x9392, 0xE665, - 0x9393, 0xE666, 0x9394, 0xE667, 0x9395, 0xE668, 0x9396, 0xE669, 0x9397, 0xE66A, 0x9398, 0xE66B, 0x9399, 0xE66C, 0x939A, 0xE66D, - 0x939B, 0xE66E, 0x939C, 0xE66F, 0x939D, 0xE670, 0x939E, 0xE671, 0x939F, 0xE672, 0x93A0, 0xE673, 0x93A1, 0xE674, 0x93A2, 0xE675, - 0x93A3, 0xE676, 0x93A4, 0xE677, 0x93A5, 0xE678, 0x93A6, 0xE679, 0x93A7, 0xE67A, 0x93A8, 0xE67B, 0x93A9, 0xE67C, 0x93AA, 0xE67D, - 0x93AB, 0xE67E, 0x93AC, 0xE680, 0x93AD, 0xE681, 0x93AE, 0xE682, 0x93AF, 0xE683, 0x93B0, 0xE684, 0x93B1, 0xE685, 0x93B2, 0xE686, - 0x93B3, 0xE687, 0x93B4, 0xE688, 0x93B5, 0xE689, 0x93B6, 0xE68A, 0x93B7, 0xE68B, 0x93B8, 0xE68C, 0x93B9, 0xE68D, 0x93BA, 0xE68E, - 0x93BB, 0xE68F, 0x93BC, 0xE690, 0x93BD, 0xE691, 0x93BE, 0xE692, 0x93BF, 0xE693, 0x93C0, 0xE694, 0x93C1, 0xE695, 0x93C2, 0xE696, - 0x93C3, 0xE697, 0x93C4, 0xE698, 0x93C5, 0xE699, 0x93C6, 0xE69A, 0x93C7, 0xE69B, 0x93C8, 0xE69C, 0x93C9, 0xE69D, 0x93CA, 0xF6CB, - 0x93CB, 0xE69E, 0x93CC, 0xE69F, 0x93CD, 0xE6A0, 0x93CE, 0xE740, 0x93CF, 0xE741, 0x93D0, 0xE742, 0x93D1, 0xE743, 0x93D2, 0xE744, - 0x93D3, 0xE745, 0x93D4, 0xE746, 0x93D5, 0xE747, 0x93D6, 0xF7E9, 0x93D7, 0xE748, 0x93D8, 0xE749, 0x93D9, 0xE74A, 0x93DA, 0xE74B, - 0x93DB, 0xE74C, 0x93DC, 0xE74D, 0x93DD, 0xE74E, 0x93DE, 0xE74F, 0x93DF, 0xE750, 0x93E0, 0xE751, 0x93E1, 0xE752, 0x93E2, 0xE753, - 0x93E3, 0xE754, 0x93E4, 0xE755, 0x93E5, 0xE756, 0x93E6, 0xE757, 0x93E7, 0xE758, 0x93E8, 0xE759, 0x93E9, 0xE75A, 0x93EA, 0xE75B, - 0x93EB, 0xE75C, 0x93EC, 0xE75D, 0x93ED, 0xE75E, 0x93EE, 0xE75F, 0x93EF, 0xE760, 0x93F0, 0xE761, 0x93F1, 0xE762, 0x93F2, 0xE763, - 0x93F3, 0xE764, 0x93F4, 0xE765, 0x93F5, 0xE766, 0x93F6, 0xE767, 0x93F7, 0xE768, 0x93F8, 0xE769, 0x93F9, 0xE76A, 0x93FA, 0xE76B, - 0x93FB, 0xE76C, 0x93FC, 0xE76D, 0x93FD, 0xE76E, 0x93FE, 0xE76F, 0x93FF, 0xE770, 0x9400, 0xE771, 0x9401, 0xE772, 0x9402, 0xE773, - 0x9403, 0xE774, 0x9404, 0xE775, 0x9405, 0xE776, 0x9406, 0xE777, 0x9407, 0xE778, 0x9408, 0xE779, 0x9409, 0xE77A, 0x940A, 0xE77B, - 0x940B, 0xE77C, 0x940C, 0xE77D, 0x940D, 0xE77E, 0x940E, 0xE780, 0x940F, 0xE781, 0x9410, 0xE782, 0x9411, 0xE783, 0x9412, 0xE784, - 0x9413, 0xE785, 0x9414, 0xE786, 0x9415, 0xE787, 0x9416, 0xE788, 0x9417, 0xE789, 0x9418, 0xE78A, 0x9419, 0xE78B, 0x941A, 0xE78C, - 0x941B, 0xE78D, 0x941C, 0xE78E, 0x941D, 0xE78F, 0x941E, 0xE790, 0x941F, 0xE791, 0x9420, 0xE792, 0x9421, 0xE793, 0x9422, 0xE794, - 0x9423, 0xE795, 0x9424, 0xE796, 0x9425, 0xE797, 0x9426, 0xE798, 0x9427, 0xE799, 0x9428, 0xE79A, 0x9429, 0xE79B, 0x942A, 0xE79C, - 0x942B, 0xE79D, 0x942C, 0xE79E, 0x942D, 0xE79F, 0x942E, 0xE7A0, 0x942F, 0xE840, 0x9430, 0xE841, 0x9431, 0xE842, 0x9432, 0xE843, - 0x9433, 0xE844, 0x9434, 0xE845, 0x9435, 0xE846, 0x9436, 0xE847, 0x9437, 0xE848, 0x9438, 0xE849, 0x9439, 0xE84A, 0x943A, 0xE84B, - 0x943B, 0xE84C, 0x943C, 0xE84D, 0x943D, 0xE84E, 0x943E, 0xF6CD, 0x943F, 0xE84F, 0x9440, 0xE850, 0x9441, 0xE851, 0x9442, 0xE852, - 0x9443, 0xE853, 0x9444, 0xE854, 0x9445, 0xE855, 0x9446, 0xE856, 0x9447, 0xE857, 0x9448, 0xE858, 0x9449, 0xE859, 0x944A, 0xE85A, - 0x944B, 0xE85B, 0x944C, 0xE85C, 0x944D, 0xE85D, 0x944E, 0xE85E, 0x944F, 0xE85F, 0x9450, 0xE860, 0x9451, 0xE861, 0x9452, 0xE862, - 0x9453, 0xE863, 0x9454, 0xE864, 0x9455, 0xE865, 0x9456, 0xE866, 0x9457, 0xE867, 0x9458, 0xE868, 0x9459, 0xE869, 0x945A, 0xE86A, - 0x945B, 0xE86B, 0x945C, 0xE86C, 0x945D, 0xE86D, 0x945E, 0xE86E, 0x945F, 0xE86F, 0x9460, 0xE870, 0x9461, 0xE871, 0x9462, 0xE872, - 0x9463, 0xE873, 0x9464, 0xE874, 0x9465, 0xE875, 0x9466, 0xE876, 0x9467, 0xE877, 0x9468, 0xE878, 0x9469, 0xE879, 0x946A, 0xE87A, - 0x946B, 0xF6CE, 0x946C, 0xE87B, 0x946D, 0xE87C, 0x946E, 0xE87D, 0x946F, 0xE87E, 0x9470, 0xE880, 0x9471, 0xE881, 0x9472, 0xE882, - 0x9473, 0xE883, 0x9474, 0xE884, 0x9475, 0xE885, 0x9476, 0xE886, 0x9477, 0xE887, 0x9478, 0xE888, 0x9479, 0xE889, 0x947A, 0xE88A, - 0x947B, 0xE88B, 0x947C, 0xE88C, 0x947D, 0xE88D, 0x947E, 0xE88E, 0x947F, 0xE88F, 0x9480, 0xE890, 0x9481, 0xE891, 0x9482, 0xE892, - 0x9483, 0xE893, 0x9484, 0xE894, 0x9485, 0xEEC4, 0x9486, 0xEEC5, 0x9487, 0xEEC6, 0x9488, 0xD5EB, 0x9489, 0xB6A4, 0x948A, 0xEEC8, - 0x948B, 0xEEC7, 0x948C, 0xEEC9, 0x948D, 0xEECA, 0x948E, 0xC7A5, 0x948F, 0xEECB, 0x9490, 0xEECC, 0x9491, 0xE895, 0x9492, 0xB7B0, - 0x9493, 0xB5F6, 0x9494, 0xEECD, 0x9495, 0xEECF, 0x9496, 0xE896, 0x9497, 0xEECE, 0x9498, 0xE897, 0x9499, 0xB8C6, 0x949A, 0xEED0, - 0x949B, 0xEED1, 0x949C, 0xEED2, 0x949D, 0xB6DB, 0x949E, 0xB3AE, 0x949F, 0xD6D3, 0x94A0, 0xC4C6, 0x94A1, 0xB1B5, 0x94A2, 0xB8D6, - 0x94A3, 0xEED3, 0x94A4, 0xEED4, 0x94A5, 0xD4BF, 0x94A6, 0xC7D5, 0x94A7, 0xBEFB, 0x94A8, 0xCED9, 0x94A9, 0xB9B3, 0x94AA, 0xEED6, - 0x94AB, 0xEED5, 0x94AC, 0xEED8, 0x94AD, 0xEED7, 0x94AE, 0xC5A5, 0x94AF, 0xEED9, 0x94B0, 0xEEDA, 0x94B1, 0xC7AE, 0x94B2, 0xEEDB, - 0x94B3, 0xC7AF, 0x94B4, 0xEEDC, 0x94B5, 0xB2A7, 0x94B6, 0xEEDD, 0x94B7, 0xEEDE, 0x94B8, 0xEEDF, 0x94B9, 0xEEE0, 0x94BA, 0xEEE1, - 0x94BB, 0xD7EA, 0x94BC, 0xEEE2, 0x94BD, 0xEEE3, 0x94BE, 0xBCD8, 0x94BF, 0xEEE4, 0x94C0, 0xD3CB, 0x94C1, 0xCCFA, 0x94C2, 0xB2AC, - 0x94C3, 0xC1E5, 0x94C4, 0xEEE5, 0x94C5, 0xC7A6, 0x94C6, 0xC3AD, 0x94C7, 0xE898, 0x94C8, 0xEEE6, 0x94C9, 0xEEE7, 0x94CA, 0xEEE8, - 0x94CB, 0xEEE9, 0x94CC, 0xEEEA, 0x94CD, 0xEEEB, 0x94CE, 0xEEEC, 0x94CF, 0xE899, 0x94D0, 0xEEED, 0x94D1, 0xEEEE, 0x94D2, 0xEEEF, - 0x94D3, 0xE89A, 0x94D4, 0xE89B, 0x94D5, 0xEEF0, 0x94D6, 0xEEF1, 0x94D7, 0xEEF2, 0x94D8, 0xEEF4, 0x94D9, 0xEEF3, 0x94DA, 0xE89C, - 0x94DB, 0xEEF5, 0x94DC, 0xCDAD, 0x94DD, 0xC2C1, 0x94DE, 0xEEF6, 0x94DF, 0xEEF7, 0x94E0, 0xEEF8, 0x94E1, 0xD5A1, 0x94E2, 0xEEF9, - 0x94E3, 0xCFB3, 0x94E4, 0xEEFA, 0x94E5, 0xEEFB, 0x94E6, 0xE89D, 0x94E7, 0xEEFC, 0x94E8, 0xEEFD, 0x94E9, 0xEFA1, 0x94EA, 0xEEFE, - 0x94EB, 0xEFA2, 0x94EC, 0xB8F5, 0x94ED, 0xC3FA, 0x94EE, 0xEFA3, 0x94EF, 0xEFA4, 0x94F0, 0xBDC2, 0x94F1, 0xD2BF, 0x94F2, 0xB2F9, - 0x94F3, 0xEFA5, 0x94F4, 0xEFA6, 0x94F5, 0xEFA7, 0x94F6, 0xD2F8, 0x94F7, 0xEFA8, 0x94F8, 0xD6FD, 0x94F9, 0xEFA9, 0x94FA, 0xC6CC, - 0x94FB, 0xE89E, 0x94FC, 0xEFAA, 0x94FD, 0xEFAB, 0x94FE, 0xC1B4, 0x94FF, 0xEFAC, 0x9500, 0xCFFA, 0x9501, 0xCBF8, 0x9502, 0xEFAE, - 0x9503, 0xEFAD, 0x9504, 0xB3FA, 0x9505, 0xB9F8, 0x9506, 0xEFAF, 0x9507, 0xEFB0, 0x9508, 0xD0E2, 0x9509, 0xEFB1, 0x950A, 0xEFB2, - 0x950B, 0xB7E6, 0x950C, 0xD0BF, 0x950D, 0xEFB3, 0x950E, 0xEFB4, 0x950F, 0xEFB5, 0x9510, 0xC8F1, 0x9511, 0xCCE0, 0x9512, 0xEFB6, - 0x9513, 0xEFB7, 0x9514, 0xEFB8, 0x9515, 0xEFB9, 0x9516, 0xEFBA, 0x9517, 0xD5E0, 0x9518, 0xEFBB, 0x9519, 0xB4ED, 0x951A, 0xC3AA, - 0x951B, 0xEFBC, 0x951C, 0xE89F, 0x951D, 0xEFBD, 0x951E, 0xEFBE, 0x951F, 0xEFBF, 0x9520, 0xE8A0, 0x9521, 0xCEFD, 0x9522, 0xEFC0, - 0x9523, 0xC2E0, 0x9524, 0xB4B8, 0x9525, 0xD7B6, 0x9526, 0xBDF5, 0x9527, 0xE940, 0x9528, 0xCFC7, 0x9529, 0xEFC3, 0x952A, 0xEFC1, - 0x952B, 0xEFC2, 0x952C, 0xEFC4, 0x952D, 0xB6A7, 0x952E, 0xBCFC, 0x952F, 0xBEE2, 0x9530, 0xC3CC, 0x9531, 0xEFC5, 0x9532, 0xEFC6, - 0x9533, 0xE941, 0x9534, 0xEFC7, 0x9535, 0xEFCF, 0x9536, 0xEFC8, 0x9537, 0xEFC9, 0x9538, 0xEFCA, 0x9539, 0xC7C2, 0x953A, 0xEFF1, - 0x953B, 0xB6CD, 0x953C, 0xEFCB, 0x953D, 0xE942, 0x953E, 0xEFCC, 0x953F, 0xEFCD, 0x9540, 0xB6C6, 0x9541, 0xC3BE, 0x9542, 0xEFCE, - 0x9543, 0xE943, 0x9544, 0xEFD0, 0x9545, 0xEFD1, 0x9546, 0xEFD2, 0x9547, 0xD5F2, 0x9548, 0xE944, 0x9549, 0xEFD3, 0x954A, 0xC4F7, - 0x954B, 0xE945, 0x954C, 0xEFD4, 0x954D, 0xC4F8, 0x954E, 0xEFD5, 0x954F, 0xEFD6, 0x9550, 0xB8E4, 0x9551, 0xB0F7, 0x9552, 0xEFD7, - 0x9553, 0xEFD8, 0x9554, 0xEFD9, 0x9555, 0xE946, 0x9556, 0xEFDA, 0x9557, 0xEFDB, 0x9558, 0xEFDC, 0x9559, 0xEFDD, 0x955A, 0xE947, - 0x955B, 0xEFDE, 0x955C, 0xBEB5, 0x955D, 0xEFE1, 0x955E, 0xEFDF, 0x955F, 0xEFE0, 0x9560, 0xE948, 0x9561, 0xEFE2, 0x9562, 0xEFE3, - 0x9563, 0xC1CD, 0x9564, 0xEFE4, 0x9565, 0xEFE5, 0x9566, 0xEFE6, 0x9567, 0xEFE7, 0x9568, 0xEFE8, 0x9569, 0xEFE9, 0x956A, 0xEFEA, - 0x956B, 0xEFEB, 0x956C, 0xEFEC, 0x956D, 0xC0D8, 0x956E, 0xE949, 0x956F, 0xEFED, 0x9570, 0xC1AD, 0x9571, 0xEFEE, 0x9572, 0xEFEF, - 0x9573, 0xEFF0, 0x9574, 0xE94A, 0x9575, 0xE94B, 0x9576, 0xCFE2, 0x9577, 0xE94C, 0x9578, 0xE94D, 0x9579, 0xE94E, 0x957A, 0xE94F, - 0x957B, 0xE950, 0x957C, 0xE951, 0x957D, 0xE952, 0x957E, 0xE953, 0x957F, 0xB3A4, 0x9580, 0xE954, 0x9581, 0xE955, 0x9582, 0xE956, - 0x9583, 0xE957, 0x9584, 0xE958, 0x9585, 0xE959, 0x9586, 0xE95A, 0x9587, 0xE95B, 0x9588, 0xE95C, 0x9589, 0xE95D, 0x958A, 0xE95E, - 0x958B, 0xE95F, 0x958C, 0xE960, 0x958D, 0xE961, 0x958E, 0xE962, 0x958F, 0xE963, 0x9590, 0xE964, 0x9591, 0xE965, 0x9592, 0xE966, - 0x9593, 0xE967, 0x9594, 0xE968, 0x9595, 0xE969, 0x9596, 0xE96A, 0x9597, 0xE96B, 0x9598, 0xE96C, 0x9599, 0xE96D, 0x959A, 0xE96E, - 0x959B, 0xE96F, 0x959C, 0xE970, 0x959D, 0xE971, 0x959E, 0xE972, 0x959F, 0xE973, 0x95A0, 0xE974, 0x95A1, 0xE975, 0x95A2, 0xE976, - 0x95A3, 0xE977, 0x95A4, 0xE978, 0x95A5, 0xE979, 0x95A6, 0xE97A, 0x95A7, 0xE97B, 0x95A8, 0xE97C, 0x95A9, 0xE97D, 0x95AA, 0xE97E, - 0x95AB, 0xE980, 0x95AC, 0xE981, 0x95AD, 0xE982, 0x95AE, 0xE983, 0x95AF, 0xE984, 0x95B0, 0xE985, 0x95B1, 0xE986, 0x95B2, 0xE987, - 0x95B3, 0xE988, 0x95B4, 0xE989, 0x95B5, 0xE98A, 0x95B6, 0xE98B, 0x95B7, 0xE98C, 0x95B8, 0xE98D, 0x95B9, 0xE98E, 0x95BA, 0xE98F, - 0x95BB, 0xE990, 0x95BC, 0xE991, 0x95BD, 0xE992, 0x95BE, 0xE993, 0x95BF, 0xE994, 0x95C0, 0xE995, 0x95C1, 0xE996, 0x95C2, 0xE997, - 0x95C3, 0xE998, 0x95C4, 0xE999, 0x95C5, 0xE99A, 0x95C6, 0xE99B, 0x95C7, 0xE99C, 0x95C8, 0xE99D, 0x95C9, 0xE99E, 0x95CA, 0xE99F, - 0x95CB, 0xE9A0, 0x95CC, 0xEA40, 0x95CD, 0xEA41, 0x95CE, 0xEA42, 0x95CF, 0xEA43, 0x95D0, 0xEA44, 0x95D1, 0xEA45, 0x95D2, 0xEA46, - 0x95D3, 0xEA47, 0x95D4, 0xEA48, 0x95D5, 0xEA49, 0x95D6, 0xEA4A, 0x95D7, 0xEA4B, 0x95D8, 0xEA4C, 0x95D9, 0xEA4D, 0x95DA, 0xEA4E, - 0x95DB, 0xEA4F, 0x95DC, 0xEA50, 0x95DD, 0xEA51, 0x95DE, 0xEA52, 0x95DF, 0xEA53, 0x95E0, 0xEA54, 0x95E1, 0xEA55, 0x95E2, 0xEA56, - 0x95E3, 0xEA57, 0x95E4, 0xEA58, 0x95E5, 0xEA59, 0x95E6, 0xEA5A, 0x95E7, 0xEA5B, 0x95E8, 0xC3C5, 0x95E9, 0xE3C5, 0x95EA, 0xC9C1, - 0x95EB, 0xE3C6, 0x95EC, 0xEA5C, 0x95ED, 0xB1D5, 0x95EE, 0xCECA, 0x95EF, 0xB4B3, 0x95F0, 0xC8F2, 0x95F1, 0xE3C7, 0x95F2, 0xCFD0, - 0x95F3, 0xE3C8, 0x95F4, 0xBCE4, 0x95F5, 0xE3C9, 0x95F6, 0xE3CA, 0x95F7, 0xC3C6, 0x95F8, 0xD5A2, 0x95F9, 0xC4D6, 0x95FA, 0xB9EB, - 0x95FB, 0xCEC5, 0x95FC, 0xE3CB, 0x95FD, 0xC3F6, 0x95FE, 0xE3CC, 0x95FF, 0xEA5D, 0x9600, 0xB7A7, 0x9601, 0xB8F3, 0x9602, 0xBAD2, - 0x9603, 0xE3CD, 0x9604, 0xE3CE, 0x9605, 0xD4C4, 0x9606, 0xE3CF, 0x9607, 0xEA5E, 0x9608, 0xE3D0, 0x9609, 0xD1CB, 0x960A, 0xE3D1, - 0x960B, 0xE3D2, 0x960C, 0xE3D3, 0x960D, 0xE3D4, 0x960E, 0xD1D6, 0x960F, 0xE3D5, 0x9610, 0xB2FB, 0x9611, 0xC0BB, 0x9612, 0xE3D6, - 0x9613, 0xEA5F, 0x9614, 0xC0AB, 0x9615, 0xE3D7, 0x9616, 0xE3D8, 0x9617, 0xE3D9, 0x9618, 0xEA60, 0x9619, 0xE3DA, 0x961A, 0xE3DB, - 0x961B, 0xEA61, 0x961C, 0xB8B7, 0x961D, 0xDAE2, 0x961E, 0xEA62, 0x961F, 0xB6D3, 0x9620, 0xEA63, 0x9621, 0xDAE4, 0x9622, 0xDAE3, - 0x9623, 0xEA64, 0x9624, 0xEA65, 0x9625, 0xEA66, 0x9626, 0xEA67, 0x9627, 0xEA68, 0x9628, 0xEA69, 0x9629, 0xEA6A, 0x962A, 0xDAE6, - 0x962B, 0xEA6B, 0x962C, 0xEA6C, 0x962D, 0xEA6D, 0x962E, 0xC8EE, 0x962F, 0xEA6E, 0x9630, 0xEA6F, 0x9631, 0xDAE5, 0x9632, 0xB7C0, - 0x9633, 0xD1F4, 0x9634, 0xD2F5, 0x9635, 0xD5F3, 0x9636, 0xBDD7, 0x9637, 0xEA70, 0x9638, 0xEA71, 0x9639, 0xEA72, 0x963A, 0xEA73, - 0x963B, 0xD7E8, 0x963C, 0xDAE8, 0x963D, 0xDAE7, 0x963E, 0xEA74, 0x963F, 0xB0A2, 0x9640, 0xCDD3, 0x9641, 0xEA75, 0x9642, 0xDAE9, - 0x9643, 0xEA76, 0x9644, 0xB8BD, 0x9645, 0xBCCA, 0x9646, 0xC2BD, 0x9647, 0xC2A4, 0x9648, 0xB3C2, 0x9649, 0xDAEA, 0x964A, 0xEA77, - 0x964B, 0xC2AA, 0x964C, 0xC4B0, 0x964D, 0xBDB5, 0x964E, 0xEA78, 0x964F, 0xEA79, 0x9650, 0xCFDE, 0x9651, 0xEA7A, 0x9652, 0xEA7B, - 0x9653, 0xEA7C, 0x9654, 0xDAEB, 0x9655, 0xC9C2, 0x9656, 0xEA7D, 0x9657, 0xEA7E, 0x9658, 0xEA80, 0x9659, 0xEA81, 0x965A, 0xEA82, - 0x965B, 0xB1DD, 0x965C, 0xEA83, 0x965D, 0xEA84, 0x965E, 0xEA85, 0x965F, 0xDAEC, 0x9660, 0xEA86, 0x9661, 0xB6B8, 0x9662, 0xD4BA, - 0x9663, 0xEA87, 0x9664, 0xB3FD, 0x9665, 0xEA88, 0x9666, 0xEA89, 0x9667, 0xDAED, 0x9668, 0xD4C9, 0x9669, 0xCFD5, 0x966A, 0xC5E3, - 0x966B, 0xEA8A, 0x966C, 0xDAEE, 0x966D, 0xEA8B, 0x966E, 0xEA8C, 0x966F, 0xEA8D, 0x9670, 0xEA8E, 0x9671, 0xEA8F, 0x9672, 0xDAEF, - 0x9673, 0xEA90, 0x9674, 0xDAF0, 0x9675, 0xC1EA, 0x9676, 0xCCD5, 0x9677, 0xCFDD, 0x9678, 0xEA91, 0x9679, 0xEA92, 0x967A, 0xEA93, - 0x967B, 0xEA94, 0x967C, 0xEA95, 0x967D, 0xEA96, 0x967E, 0xEA97, 0x967F, 0xEA98, 0x9680, 0xEA99, 0x9681, 0xEA9A, 0x9682, 0xEA9B, - 0x9683, 0xEA9C, 0x9684, 0xEA9D, 0x9685, 0xD3E7, 0x9686, 0xC2A1, 0x9687, 0xEA9E, 0x9688, 0xDAF1, 0x9689, 0xEA9F, 0x968A, 0xEAA0, - 0x968B, 0xCBE5, 0x968C, 0xEB40, 0x968D, 0xDAF2, 0x968E, 0xEB41, 0x968F, 0xCBE6, 0x9690, 0xD2FE, 0x9691, 0xEB42, 0x9692, 0xEB43, - 0x9693, 0xEB44, 0x9694, 0xB8F4, 0x9695, 0xEB45, 0x9696, 0xEB46, 0x9697, 0xDAF3, 0x9698, 0xB0AF, 0x9699, 0xCFB6, 0x969A, 0xEB47, - 0x969B, 0xEB48, 0x969C, 0xD5CF, 0x969D, 0xEB49, 0x969E, 0xEB4A, 0x969F, 0xEB4B, 0x96A0, 0xEB4C, 0x96A1, 0xEB4D, 0x96A2, 0xEB4E, - 0x96A3, 0xEB4F, 0x96A4, 0xEB50, 0x96A5, 0xEB51, 0x96A6, 0xEB52, 0x96A7, 0xCBED, 0x96A8, 0xEB53, 0x96A9, 0xEB54, 0x96AA, 0xEB55, - 0x96AB, 0xEB56, 0x96AC, 0xEB57, 0x96AD, 0xEB58, 0x96AE, 0xEB59, 0x96AF, 0xEB5A, 0x96B0, 0xDAF4, 0x96B1, 0xEB5B, 0x96B2, 0xEB5C, - 0x96B3, 0xE3C4, 0x96B4, 0xEB5D, 0x96B5, 0xEB5E, 0x96B6, 0xC1A5, 0x96B7, 0xEB5F, 0x96B8, 0xEB60, 0x96B9, 0xF6BF, 0x96BA, 0xEB61, - 0x96BB, 0xEB62, 0x96BC, 0xF6C0, 0x96BD, 0xF6C1, 0x96BE, 0xC4D1, 0x96BF, 0xEB63, 0x96C0, 0xC8B8, 0x96C1, 0xD1E3, 0x96C2, 0xEB64, - 0x96C3, 0xEB65, 0x96C4, 0xD0DB, 0x96C5, 0xD1C5, 0x96C6, 0xBCAF, 0x96C7, 0xB9CD, 0x96C8, 0xEB66, 0x96C9, 0xEFF4, 0x96CA, 0xEB67, - 0x96CB, 0xEB68, 0x96CC, 0xB4C6, 0x96CD, 0xD3BA, 0x96CE, 0xF6C2, 0x96CF, 0xB3FB, 0x96D0, 0xEB69, 0x96D1, 0xEB6A, 0x96D2, 0xF6C3, - 0x96D3, 0xEB6B, 0x96D4, 0xEB6C, 0x96D5, 0xB5F1, 0x96D6, 0xEB6D, 0x96D7, 0xEB6E, 0x96D8, 0xEB6F, 0x96D9, 0xEB70, 0x96DA, 0xEB71, - 0x96DB, 0xEB72, 0x96DC, 0xEB73, 0x96DD, 0xEB74, 0x96DE, 0xEB75, 0x96DF, 0xEB76, 0x96E0, 0xF6C5, 0x96E1, 0xEB77, 0x96E2, 0xEB78, - 0x96E3, 0xEB79, 0x96E4, 0xEB7A, 0x96E5, 0xEB7B, 0x96E6, 0xEB7C, 0x96E7, 0xEB7D, 0x96E8, 0xD3EA, 0x96E9, 0xF6A7, 0x96EA, 0xD1A9, - 0x96EB, 0xEB7E, 0x96EC, 0xEB80, 0x96ED, 0xEB81, 0x96EE, 0xEB82, 0x96EF, 0xF6A9, 0x96F0, 0xEB83, 0x96F1, 0xEB84, 0x96F2, 0xEB85, - 0x96F3, 0xF6A8, 0x96F4, 0xEB86, 0x96F5, 0xEB87, 0x96F6, 0xC1E3, 0x96F7, 0xC0D7, 0x96F8, 0xEB88, 0x96F9, 0xB1A2, 0x96FA, 0xEB89, - 0x96FB, 0xEB8A, 0x96FC, 0xEB8B, 0x96FD, 0xEB8C, 0x96FE, 0xCEED, 0x96FF, 0xEB8D, 0x9700, 0xD0E8, 0x9701, 0xF6AB, 0x9702, 0xEB8E, - 0x9703, 0xEB8F, 0x9704, 0xCFF6, 0x9705, 0xEB90, 0x9706, 0xF6AA, 0x9707, 0xD5F0, 0x9708, 0xF6AC, 0x9709, 0xC3B9, 0x970A, 0xEB91, - 0x970B, 0xEB92, 0x970C, 0xEB93, 0x970D, 0xBBF4, 0x970E, 0xF6AE, 0x970F, 0xF6AD, 0x9710, 0xEB94, 0x9711, 0xEB95, 0x9712, 0xEB96, - 0x9713, 0xC4DE, 0x9714, 0xEB97, 0x9715, 0xEB98, 0x9716, 0xC1D8, 0x9717, 0xEB99, 0x9718, 0xEB9A, 0x9719, 0xEB9B, 0x971A, 0xEB9C, - 0x971B, 0xEB9D, 0x971C, 0xCBAA, 0x971D, 0xEB9E, 0x971E, 0xCFBC, 0x971F, 0xEB9F, 0x9720, 0xEBA0, 0x9721, 0xEC40, 0x9722, 0xEC41, - 0x9723, 0xEC42, 0x9724, 0xEC43, 0x9725, 0xEC44, 0x9726, 0xEC45, 0x9727, 0xEC46, 0x9728, 0xEC47, 0x9729, 0xEC48, 0x972A, 0xF6AF, - 0x972B, 0xEC49, 0x972C, 0xEC4A, 0x972D, 0xF6B0, 0x972E, 0xEC4B, 0x972F, 0xEC4C, 0x9730, 0xF6B1, 0x9731, 0xEC4D, 0x9732, 0xC2B6, - 0x9733, 0xEC4E, 0x9734, 0xEC4F, 0x9735, 0xEC50, 0x9736, 0xEC51, 0x9737, 0xEC52, 0x9738, 0xB0D4, 0x9739, 0xC5F9, 0x973A, 0xEC53, - 0x973B, 0xEC54, 0x973C, 0xEC55, 0x973D, 0xEC56, 0x973E, 0xF6B2, 0x973F, 0xEC57, 0x9740, 0xEC58, 0x9741, 0xEC59, 0x9742, 0xEC5A, - 0x9743, 0xEC5B, 0x9744, 0xEC5C, 0x9745, 0xEC5D, 0x9746, 0xEC5E, 0x9747, 0xEC5F, 0x9748, 0xEC60, 0x9749, 0xEC61, 0x974A, 0xEC62, - 0x974B, 0xEC63, 0x974C, 0xEC64, 0x974D, 0xEC65, 0x974E, 0xEC66, 0x974F, 0xEC67, 0x9750, 0xEC68, 0x9751, 0xEC69, 0x9752, 0xC7E0, - 0x9753, 0xF6A6, 0x9754, 0xEC6A, 0x9755, 0xEC6B, 0x9756, 0xBEB8, 0x9757, 0xEC6C, 0x9758, 0xEC6D, 0x9759, 0xBEB2, 0x975A, 0xEC6E, - 0x975B, 0xB5E5, 0x975C, 0xEC6F, 0x975D, 0xEC70, 0x975E, 0xB7C7, 0x975F, 0xEC71, 0x9760, 0xBFBF, 0x9761, 0xC3D2, 0x9762, 0xC3E6, - 0x9763, 0xEC72, 0x9764, 0xEC73, 0x9765, 0xD8CC, 0x9766, 0xEC74, 0x9767, 0xEC75, 0x9768, 0xEC76, 0x9769, 0xB8EF, 0x976A, 0xEC77, - 0x976B, 0xEC78, 0x976C, 0xEC79, 0x976D, 0xEC7A, 0x976E, 0xEC7B, 0x976F, 0xEC7C, 0x9770, 0xEC7D, 0x9771, 0xEC7E, 0x9772, 0xEC80, - 0x9773, 0xBDF9, 0x9774, 0xD1A5, 0x9775, 0xEC81, 0x9776, 0xB0D0, 0x9777, 0xEC82, 0x9778, 0xEC83, 0x9779, 0xEC84, 0x977A, 0xEC85, - 0x977B, 0xEC86, 0x977C, 0xF7B0, 0x977D, 0xEC87, 0x977E, 0xEC88, 0x977F, 0xEC89, 0x9780, 0xEC8A, 0x9781, 0xEC8B, 0x9782, 0xEC8C, - 0x9783, 0xEC8D, 0x9784, 0xEC8E, 0x9785, 0xF7B1, 0x9786, 0xEC8F, 0x9787, 0xEC90, 0x9788, 0xEC91, 0x9789, 0xEC92, 0x978A, 0xEC93, - 0x978B, 0xD0AC, 0x978C, 0xEC94, 0x978D, 0xB0B0, 0x978E, 0xEC95, 0x978F, 0xEC96, 0x9790, 0xEC97, 0x9791, 0xF7B2, 0x9792, 0xF7B3, - 0x9793, 0xEC98, 0x9794, 0xF7B4, 0x9795, 0xEC99, 0x9796, 0xEC9A, 0x9797, 0xEC9B, 0x9798, 0xC7CA, 0x9799, 0xEC9C, 0x979A, 0xEC9D, - 0x979B, 0xEC9E, 0x979C, 0xEC9F, 0x979D, 0xECA0, 0x979E, 0xED40, 0x979F, 0xED41, 0x97A0, 0xBECF, 0x97A1, 0xED42, 0x97A2, 0xED43, - 0x97A3, 0xF7B7, 0x97A4, 0xED44, 0x97A5, 0xED45, 0x97A6, 0xED46, 0x97A7, 0xED47, 0x97A8, 0xED48, 0x97A9, 0xED49, 0x97AA, 0xED4A, - 0x97AB, 0xF7B6, 0x97AC, 0xED4B, 0x97AD, 0xB1DE, 0x97AE, 0xED4C, 0x97AF, 0xF7B5, 0x97B0, 0xED4D, 0x97B1, 0xED4E, 0x97B2, 0xF7B8, - 0x97B3, 0xED4F, 0x97B4, 0xF7B9, 0x97B5, 0xED50, 0x97B6, 0xED51, 0x97B7, 0xED52, 0x97B8, 0xED53, 0x97B9, 0xED54, 0x97BA, 0xED55, - 0x97BB, 0xED56, 0x97BC, 0xED57, 0x97BD, 0xED58, 0x97BE, 0xED59, 0x97BF, 0xED5A, 0x97C0, 0xED5B, 0x97C1, 0xED5C, 0x97C2, 0xED5D, - 0x97C3, 0xED5E, 0x97C4, 0xED5F, 0x97C5, 0xED60, 0x97C6, 0xED61, 0x97C7, 0xED62, 0x97C8, 0xED63, 0x97C9, 0xED64, 0x97CA, 0xED65, - 0x97CB, 0xED66, 0x97CC, 0xED67, 0x97CD, 0xED68, 0x97CE, 0xED69, 0x97CF, 0xED6A, 0x97D0, 0xED6B, 0x97D1, 0xED6C, 0x97D2, 0xED6D, - 0x97D3, 0xED6E, 0x97D4, 0xED6F, 0x97D5, 0xED70, 0x97D6, 0xED71, 0x97D7, 0xED72, 0x97D8, 0xED73, 0x97D9, 0xED74, 0x97DA, 0xED75, - 0x97DB, 0xED76, 0x97DC, 0xED77, 0x97DD, 0xED78, 0x97DE, 0xED79, 0x97DF, 0xED7A, 0x97E0, 0xED7B, 0x97E1, 0xED7C, 0x97E2, 0xED7D, - 0x97E3, 0xED7E, 0x97E4, 0xED80, 0x97E5, 0xED81, 0x97E6, 0xCEA4, 0x97E7, 0xC8CD, 0x97E8, 0xED82, 0x97E9, 0xBAAB, 0x97EA, 0xE8B8, - 0x97EB, 0xE8B9, 0x97EC, 0xE8BA, 0x97ED, 0xBEC2, 0x97EE, 0xED83, 0x97EF, 0xED84, 0x97F0, 0xED85, 0x97F1, 0xED86, 0x97F2, 0xED87, - 0x97F3, 0xD2F4, 0x97F4, 0xED88, 0x97F5, 0xD4CF, 0x97F6, 0xC9D8, 0x97F7, 0xED89, 0x97F8, 0xED8A, 0x97F9, 0xED8B, 0x97FA, 0xED8C, - 0x97FB, 0xED8D, 0x97FC, 0xED8E, 0x97FD, 0xED8F, 0x97FE, 0xED90, 0x97FF, 0xED91, 0x9800, 0xED92, 0x9801, 0xED93, 0x9802, 0xED94, - 0x9803, 0xED95, 0x9804, 0xED96, 0x9805, 0xED97, 0x9806, 0xED98, 0x9807, 0xED99, 0x9808, 0xED9A, 0x9809, 0xED9B, 0x980A, 0xED9C, - 0x980B, 0xED9D, 0x980C, 0xED9E, 0x980D, 0xED9F, 0x980E, 0xEDA0, 0x980F, 0xEE40, 0x9810, 0xEE41, 0x9811, 0xEE42, 0x9812, 0xEE43, - 0x9813, 0xEE44, 0x9814, 0xEE45, 0x9815, 0xEE46, 0x9816, 0xEE47, 0x9817, 0xEE48, 0x9818, 0xEE49, 0x9819, 0xEE4A, 0x981A, 0xEE4B, - 0x981B, 0xEE4C, 0x981C, 0xEE4D, 0x981D, 0xEE4E, 0x981E, 0xEE4F, 0x981F, 0xEE50, 0x9820, 0xEE51, 0x9821, 0xEE52, 0x9822, 0xEE53, - 0x9823, 0xEE54, 0x9824, 0xEE55, 0x9825, 0xEE56, 0x9826, 0xEE57, 0x9827, 0xEE58, 0x9828, 0xEE59, 0x9829, 0xEE5A, 0x982A, 0xEE5B, - 0x982B, 0xEE5C, 0x982C, 0xEE5D, 0x982D, 0xEE5E, 0x982E, 0xEE5F, 0x982F, 0xEE60, 0x9830, 0xEE61, 0x9831, 0xEE62, 0x9832, 0xEE63, - 0x9833, 0xEE64, 0x9834, 0xEE65, 0x9835, 0xEE66, 0x9836, 0xEE67, 0x9837, 0xEE68, 0x9838, 0xEE69, 0x9839, 0xEE6A, 0x983A, 0xEE6B, - 0x983B, 0xEE6C, 0x983C, 0xEE6D, 0x983D, 0xEE6E, 0x983E, 0xEE6F, 0x983F, 0xEE70, 0x9840, 0xEE71, 0x9841, 0xEE72, 0x9842, 0xEE73, - 0x9843, 0xEE74, 0x9844, 0xEE75, 0x9845, 0xEE76, 0x9846, 0xEE77, 0x9847, 0xEE78, 0x9848, 0xEE79, 0x9849, 0xEE7A, 0x984A, 0xEE7B, - 0x984B, 0xEE7C, 0x984C, 0xEE7D, 0x984D, 0xEE7E, 0x984E, 0xEE80, 0x984F, 0xEE81, 0x9850, 0xEE82, 0x9851, 0xEE83, 0x9852, 0xEE84, - 0x9853, 0xEE85, 0x9854, 0xEE86, 0x9855, 0xEE87, 0x9856, 0xEE88, 0x9857, 0xEE89, 0x9858, 0xEE8A, 0x9859, 0xEE8B, 0x985A, 0xEE8C, - 0x985B, 0xEE8D, 0x985C, 0xEE8E, 0x985D, 0xEE8F, 0x985E, 0xEE90, 0x985F, 0xEE91, 0x9860, 0xEE92, 0x9861, 0xEE93, 0x9862, 0xEE94, - 0x9863, 0xEE95, 0x9864, 0xEE96, 0x9865, 0xEE97, 0x9866, 0xEE98, 0x9867, 0xEE99, 0x9868, 0xEE9A, 0x9869, 0xEE9B, 0x986A, 0xEE9C, - 0x986B, 0xEE9D, 0x986C, 0xEE9E, 0x986D, 0xEE9F, 0x986E, 0xEEA0, 0x986F, 0xEF40, 0x9870, 0xEF41, 0x9871, 0xEF42, 0x9872, 0xEF43, - 0x9873, 0xEF44, 0x9874, 0xEF45, 0x9875, 0xD2B3, 0x9876, 0xB6A5, 0x9877, 0xC7EA, 0x9878, 0xF1FC, 0x9879, 0xCFEE, 0x987A, 0xCBB3, - 0x987B, 0xD0EB, 0x987C, 0xE7EF, 0x987D, 0xCDE7, 0x987E, 0xB9CB, 0x987F, 0xB6D9, 0x9880, 0xF1FD, 0x9881, 0xB0E4, 0x9882, 0xCBCC, - 0x9883, 0xF1FE, 0x9884, 0xD4A4, 0x9885, 0xC2AD, 0x9886, 0xC1EC, 0x9887, 0xC6C4, 0x9888, 0xBEB1, 0x9889, 0xF2A1, 0x988A, 0xBCD5, - 0x988B, 0xEF46, 0x988C, 0xF2A2, 0x988D, 0xF2A3, 0x988E, 0xEF47, 0x988F, 0xF2A4, 0x9890, 0xD2C3, 0x9891, 0xC6B5, 0x9892, 0xEF48, - 0x9893, 0xCDC7, 0x9894, 0xF2A5, 0x9895, 0xEF49, 0x9896, 0xD3B1, 0x9897, 0xBFC5, 0x9898, 0xCCE2, 0x9899, 0xEF4A, 0x989A, 0xF2A6, - 0x989B, 0xF2A7, 0x989C, 0xD1D5, 0x989D, 0xB6EE, 0x989E, 0xF2A8, 0x989F, 0xF2A9, 0x98A0, 0xB5DF, 0x98A1, 0xF2AA, 0x98A2, 0xF2AB, - 0x98A3, 0xEF4B, 0x98A4, 0xB2FC, 0x98A5, 0xF2AC, 0x98A6, 0xF2AD, 0x98A7, 0xC8A7, 0x98A8, 0xEF4C, 0x98A9, 0xEF4D, 0x98AA, 0xEF4E, - 0x98AB, 0xEF4F, 0x98AC, 0xEF50, 0x98AD, 0xEF51, 0x98AE, 0xEF52, 0x98AF, 0xEF53, 0x98B0, 0xEF54, 0x98B1, 0xEF55, 0x98B2, 0xEF56, - 0x98B3, 0xEF57, 0x98B4, 0xEF58, 0x98B5, 0xEF59, 0x98B6, 0xEF5A, 0x98B7, 0xEF5B, 0x98B8, 0xEF5C, 0x98B9, 0xEF5D, 0x98BA, 0xEF5E, - 0x98BB, 0xEF5F, 0x98BC, 0xEF60, 0x98BD, 0xEF61, 0x98BE, 0xEF62, 0x98BF, 0xEF63, 0x98C0, 0xEF64, 0x98C1, 0xEF65, 0x98C2, 0xEF66, - 0x98C3, 0xEF67, 0x98C4, 0xEF68, 0x98C5, 0xEF69, 0x98C6, 0xEF6A, 0x98C7, 0xEF6B, 0x98C8, 0xEF6C, 0x98C9, 0xEF6D, 0x98CA, 0xEF6E, - 0x98CB, 0xEF6F, 0x98CC, 0xEF70, 0x98CD, 0xEF71, 0x98CE, 0xB7E7, 0x98CF, 0xEF72, 0x98D0, 0xEF73, 0x98D1, 0xECA9, 0x98D2, 0xECAA, - 0x98D3, 0xECAB, 0x98D4, 0xEF74, 0x98D5, 0xECAC, 0x98D6, 0xEF75, 0x98D7, 0xEF76, 0x98D8, 0xC6AE, 0x98D9, 0xECAD, 0x98DA, 0xECAE, - 0x98DB, 0xEF77, 0x98DC, 0xEF78, 0x98DD, 0xEF79, 0x98DE, 0xB7C9, 0x98DF, 0xCAB3, 0x98E0, 0xEF7A, 0x98E1, 0xEF7B, 0x98E2, 0xEF7C, - 0x98E3, 0xEF7D, 0x98E4, 0xEF7E, 0x98E5, 0xEF80, 0x98E6, 0xEF81, 0x98E7, 0xE2B8, 0x98E8, 0xF7CF, 0x98E9, 0xEF82, 0x98EA, 0xEF83, - 0x98EB, 0xEF84, 0x98EC, 0xEF85, 0x98ED, 0xEF86, 0x98EE, 0xEF87, 0x98EF, 0xEF88, 0x98F0, 0xEF89, 0x98F1, 0xEF8A, 0x98F2, 0xEF8B, - 0x98F3, 0xEF8C, 0x98F4, 0xEF8D, 0x98F5, 0xEF8E, 0x98F6, 0xEF8F, 0x98F7, 0xEF90, 0x98F8, 0xEF91, 0x98F9, 0xEF92, 0x98FA, 0xEF93, - 0x98FB, 0xEF94, 0x98FC, 0xEF95, 0x98FD, 0xEF96, 0x98FE, 0xEF97, 0x98FF, 0xEF98, 0x9900, 0xEF99, 0x9901, 0xEF9A, 0x9902, 0xEF9B, - 0x9903, 0xEF9C, 0x9904, 0xEF9D, 0x9905, 0xEF9E, 0x9906, 0xEF9F, 0x9907, 0xEFA0, 0x9908, 0xF040, 0x9909, 0xF041, 0x990A, 0xF042, - 0x990B, 0xF043, 0x990C, 0xF044, 0x990D, 0xF7D0, 0x990E, 0xF045, 0x990F, 0xF046, 0x9910, 0xB2CD, 0x9911, 0xF047, 0x9912, 0xF048, - 0x9913, 0xF049, 0x9914, 0xF04A, 0x9915, 0xF04B, 0x9916, 0xF04C, 0x9917, 0xF04D, 0x9918, 0xF04E, 0x9919, 0xF04F, 0x991A, 0xF050, - 0x991B, 0xF051, 0x991C, 0xF052, 0x991D, 0xF053, 0x991E, 0xF054, 0x991F, 0xF055, 0x9920, 0xF056, 0x9921, 0xF057, 0x9922, 0xF058, - 0x9923, 0xF059, 0x9924, 0xF05A, 0x9925, 0xF05B, 0x9926, 0xF05C, 0x9927, 0xF05D, 0x9928, 0xF05E, 0x9929, 0xF05F, 0x992A, 0xF060, - 0x992B, 0xF061, 0x992C, 0xF062, 0x992D, 0xF063, 0x992E, 0xF7D1, 0x992F, 0xF064, 0x9930, 0xF065, 0x9931, 0xF066, 0x9932, 0xF067, - 0x9933, 0xF068, 0x9934, 0xF069, 0x9935, 0xF06A, 0x9936, 0xF06B, 0x9937, 0xF06C, 0x9938, 0xF06D, 0x9939, 0xF06E, 0x993A, 0xF06F, - 0x993B, 0xF070, 0x993C, 0xF071, 0x993D, 0xF072, 0x993E, 0xF073, 0x993F, 0xF074, 0x9940, 0xF075, 0x9941, 0xF076, 0x9942, 0xF077, - 0x9943, 0xF078, 0x9944, 0xF079, 0x9945, 0xF07A, 0x9946, 0xF07B, 0x9947, 0xF07C, 0x9948, 0xF07D, 0x9949, 0xF07E, 0x994A, 0xF080, - 0x994B, 0xF081, 0x994C, 0xF082, 0x994D, 0xF083, 0x994E, 0xF084, 0x994F, 0xF085, 0x9950, 0xF086, 0x9951, 0xF087, 0x9952, 0xF088, - 0x9953, 0xF089, 0x9954, 0xF7D3, 0x9955, 0xF7D2, 0x9956, 0xF08A, 0x9957, 0xF08B, 0x9958, 0xF08C, 0x9959, 0xF08D, 0x995A, 0xF08E, - 0x995B, 0xF08F, 0x995C, 0xF090, 0x995D, 0xF091, 0x995E, 0xF092, 0x995F, 0xF093, 0x9960, 0xF094, 0x9961, 0xF095, 0x9962, 0xF096, - 0x9963, 0xE2BB, 0x9964, 0xF097, 0x9965, 0xBCA2, 0x9966, 0xF098, 0x9967, 0xE2BC, 0x9968, 0xE2BD, 0x9969, 0xE2BE, 0x996A, 0xE2BF, - 0x996B, 0xE2C0, 0x996C, 0xE2C1, 0x996D, 0xB7B9, 0x996E, 0xD2FB, 0x996F, 0xBDA4, 0x9970, 0xCACE, 0x9971, 0xB1A5, 0x9972, 0xCBC7, - 0x9973, 0xF099, 0x9974, 0xE2C2, 0x9975, 0xB6FC, 0x9976, 0xC8C4, 0x9977, 0xE2C3, 0x9978, 0xF09A, 0x9979, 0xF09B, 0x997A, 0xBDC8, - 0x997B, 0xF09C, 0x997C, 0xB1FD, 0x997D, 0xE2C4, 0x997E, 0xF09D, 0x997F, 0xB6F6, 0x9980, 0xE2C5, 0x9981, 0xC4D9, 0x9982, 0xF09E, - 0x9983, 0xF09F, 0x9984, 0xE2C6, 0x9985, 0xCFDA, 0x9986, 0xB9DD, 0x9987, 0xE2C7, 0x9988, 0xC0A1, 0x9989, 0xF0A0, 0x998A, 0xE2C8, - 0x998B, 0xB2F6, 0x998C, 0xF140, 0x998D, 0xE2C9, 0x998E, 0xF141, 0x998F, 0xC1F3, 0x9990, 0xE2CA, 0x9991, 0xE2CB, 0x9992, 0xC2F8, - 0x9993, 0xE2CC, 0x9994, 0xE2CD, 0x9995, 0xE2CE, 0x9996, 0xCAD7, 0x9997, 0xD8B8, 0x9998, 0xD9E5, 0x9999, 0xCFE3, 0x999A, 0xF142, - 0x999B, 0xF143, 0x999C, 0xF144, 0x999D, 0xF145, 0x999E, 0xF146, 0x999F, 0xF147, 0x99A0, 0xF148, 0x99A1, 0xF149, 0x99A2, 0xF14A, - 0x99A3, 0xF14B, 0x99A4, 0xF14C, 0x99A5, 0xF0A5, 0x99A6, 0xF14D, 0x99A7, 0xF14E, 0x99A8, 0xDCB0, 0x99A9, 0xF14F, 0x99AA, 0xF150, - 0x99AB, 0xF151, 0x99AC, 0xF152, 0x99AD, 0xF153, 0x99AE, 0xF154, 0x99AF, 0xF155, 0x99B0, 0xF156, 0x99B1, 0xF157, 0x99B2, 0xF158, - 0x99B3, 0xF159, 0x99B4, 0xF15A, 0x99B5, 0xF15B, 0x99B6, 0xF15C, 0x99B7, 0xF15D, 0x99B8, 0xF15E, 0x99B9, 0xF15F, 0x99BA, 0xF160, - 0x99BB, 0xF161, 0x99BC, 0xF162, 0x99BD, 0xF163, 0x99BE, 0xF164, 0x99BF, 0xF165, 0x99C0, 0xF166, 0x99C1, 0xF167, 0x99C2, 0xF168, - 0x99C3, 0xF169, 0x99C4, 0xF16A, 0x99C5, 0xF16B, 0x99C6, 0xF16C, 0x99C7, 0xF16D, 0x99C8, 0xF16E, 0x99C9, 0xF16F, 0x99CA, 0xF170, - 0x99CB, 0xF171, 0x99CC, 0xF172, 0x99CD, 0xF173, 0x99CE, 0xF174, 0x99CF, 0xF175, 0x99D0, 0xF176, 0x99D1, 0xF177, 0x99D2, 0xF178, - 0x99D3, 0xF179, 0x99D4, 0xF17A, 0x99D5, 0xF17B, 0x99D6, 0xF17C, 0x99D7, 0xF17D, 0x99D8, 0xF17E, 0x99D9, 0xF180, 0x99DA, 0xF181, - 0x99DB, 0xF182, 0x99DC, 0xF183, 0x99DD, 0xF184, 0x99DE, 0xF185, 0x99DF, 0xF186, 0x99E0, 0xF187, 0x99E1, 0xF188, 0x99E2, 0xF189, - 0x99E3, 0xF18A, 0x99E4, 0xF18B, 0x99E5, 0xF18C, 0x99E6, 0xF18D, 0x99E7, 0xF18E, 0x99E8, 0xF18F, 0x99E9, 0xF190, 0x99EA, 0xF191, - 0x99EB, 0xF192, 0x99EC, 0xF193, 0x99ED, 0xF194, 0x99EE, 0xF195, 0x99EF, 0xF196, 0x99F0, 0xF197, 0x99F1, 0xF198, 0x99F2, 0xF199, - 0x99F3, 0xF19A, 0x99F4, 0xF19B, 0x99F5, 0xF19C, 0x99F6, 0xF19D, 0x99F7, 0xF19E, 0x99F8, 0xF19F, 0x99F9, 0xF1A0, 0x99FA, 0xF240, - 0x99FB, 0xF241, 0x99FC, 0xF242, 0x99FD, 0xF243, 0x99FE, 0xF244, 0x99FF, 0xF245, 0x9A00, 0xF246, 0x9A01, 0xF247, 0x9A02, 0xF248, - 0x9A03, 0xF249, 0x9A04, 0xF24A, 0x9A05, 0xF24B, 0x9A06, 0xF24C, 0x9A07, 0xF24D, 0x9A08, 0xF24E, 0x9A09, 0xF24F, 0x9A0A, 0xF250, - 0x9A0B, 0xF251, 0x9A0C, 0xF252, 0x9A0D, 0xF253, 0x9A0E, 0xF254, 0x9A0F, 0xF255, 0x9A10, 0xF256, 0x9A11, 0xF257, 0x9A12, 0xF258, - 0x9A13, 0xF259, 0x9A14, 0xF25A, 0x9A15, 0xF25B, 0x9A16, 0xF25C, 0x9A17, 0xF25D, 0x9A18, 0xF25E, 0x9A19, 0xF25F, 0x9A1A, 0xF260, - 0x9A1B, 0xF261, 0x9A1C, 0xF262, 0x9A1D, 0xF263, 0x9A1E, 0xF264, 0x9A1F, 0xF265, 0x9A20, 0xF266, 0x9A21, 0xF267, 0x9A22, 0xF268, - 0x9A23, 0xF269, 0x9A24, 0xF26A, 0x9A25, 0xF26B, 0x9A26, 0xF26C, 0x9A27, 0xF26D, 0x9A28, 0xF26E, 0x9A29, 0xF26F, 0x9A2A, 0xF270, - 0x9A2B, 0xF271, 0x9A2C, 0xF272, 0x9A2D, 0xF273, 0x9A2E, 0xF274, 0x9A2F, 0xF275, 0x9A30, 0xF276, 0x9A31, 0xF277, 0x9A32, 0xF278, - 0x9A33, 0xF279, 0x9A34, 0xF27A, 0x9A35, 0xF27B, 0x9A36, 0xF27C, 0x9A37, 0xF27D, 0x9A38, 0xF27E, 0x9A39, 0xF280, 0x9A3A, 0xF281, - 0x9A3B, 0xF282, 0x9A3C, 0xF283, 0x9A3D, 0xF284, 0x9A3E, 0xF285, 0x9A3F, 0xF286, 0x9A40, 0xF287, 0x9A41, 0xF288, 0x9A42, 0xF289, - 0x9A43, 0xF28A, 0x9A44, 0xF28B, 0x9A45, 0xF28C, 0x9A46, 0xF28D, 0x9A47, 0xF28E, 0x9A48, 0xF28F, 0x9A49, 0xF290, 0x9A4A, 0xF291, - 0x9A4B, 0xF292, 0x9A4C, 0xF293, 0x9A4D, 0xF294, 0x9A4E, 0xF295, 0x9A4F, 0xF296, 0x9A50, 0xF297, 0x9A51, 0xF298, 0x9A52, 0xF299, - 0x9A53, 0xF29A, 0x9A54, 0xF29B, 0x9A55, 0xF29C, 0x9A56, 0xF29D, 0x9A57, 0xF29E, 0x9A58, 0xF29F, 0x9A59, 0xF2A0, 0x9A5A, 0xF340, - 0x9A5B, 0xF341, 0x9A5C, 0xF342, 0x9A5D, 0xF343, 0x9A5E, 0xF344, 0x9A5F, 0xF345, 0x9A60, 0xF346, 0x9A61, 0xF347, 0x9A62, 0xF348, - 0x9A63, 0xF349, 0x9A64, 0xF34A, 0x9A65, 0xF34B, 0x9A66, 0xF34C, 0x9A67, 0xF34D, 0x9A68, 0xF34E, 0x9A69, 0xF34F, 0x9A6A, 0xF350, - 0x9A6B, 0xF351, 0x9A6C, 0xC2ED, 0x9A6D, 0xD4A6, 0x9A6E, 0xCDD4, 0x9A6F, 0xD1B1, 0x9A70, 0xB3DB, 0x9A71, 0xC7FD, 0x9A72, 0xF352, - 0x9A73, 0xB2B5, 0x9A74, 0xC2BF, 0x9A75, 0xE6E0, 0x9A76, 0xCABB, 0x9A77, 0xE6E1, 0x9A78, 0xE6E2, 0x9A79, 0xBED4, 0x9A7A, 0xE6E3, - 0x9A7B, 0xD7A4, 0x9A7C, 0xCDD5, 0x9A7D, 0xE6E5, 0x9A7E, 0xBCDD, 0x9A7F, 0xE6E4, 0x9A80, 0xE6E6, 0x9A81, 0xE6E7, 0x9A82, 0xC2EE, - 0x9A83, 0xF353, 0x9A84, 0xBDBE, 0x9A85, 0xE6E8, 0x9A86, 0xC2E6, 0x9A87, 0xBAA7, 0x9A88, 0xE6E9, 0x9A89, 0xF354, 0x9A8A, 0xE6EA, - 0x9A8B, 0xB3D2, 0x9A8C, 0xD1E9, 0x9A8D, 0xF355, 0x9A8E, 0xF356, 0x9A8F, 0xBFA5, 0x9A90, 0xE6EB, 0x9A91, 0xC6EF, 0x9A92, 0xE6EC, - 0x9A93, 0xE6ED, 0x9A94, 0xF357, 0x9A95, 0xF358, 0x9A96, 0xE6EE, 0x9A97, 0xC6AD, 0x9A98, 0xE6EF, 0x9A99, 0xF359, 0x9A9A, 0xC9A7, - 0x9A9B, 0xE6F0, 0x9A9C, 0xE6F1, 0x9A9D, 0xE6F2, 0x9A9E, 0xE5B9, 0x9A9F, 0xE6F3, 0x9AA0, 0xE6F4, 0x9AA1, 0xC2E2, 0x9AA2, 0xE6F5, - 0x9AA3, 0xE6F6, 0x9AA4, 0xD6E8, 0x9AA5, 0xE6F7, 0x9AA6, 0xF35A, 0x9AA7, 0xE6F8, 0x9AA8, 0xB9C7, 0x9AA9, 0xF35B, 0x9AAA, 0xF35C, - 0x9AAB, 0xF35D, 0x9AAC, 0xF35E, 0x9AAD, 0xF35F, 0x9AAE, 0xF360, 0x9AAF, 0xF361, 0x9AB0, 0xF7BB, 0x9AB1, 0xF7BA, 0x9AB2, 0xF362, - 0x9AB3, 0xF363, 0x9AB4, 0xF364, 0x9AB5, 0xF365, 0x9AB6, 0xF7BE, 0x9AB7, 0xF7BC, 0x9AB8, 0xBAA1, 0x9AB9, 0xF366, 0x9ABA, 0xF7BF, - 0x9ABB, 0xF367, 0x9ABC, 0xF7C0, 0x9ABD, 0xF368, 0x9ABE, 0xF369, 0x9ABF, 0xF36A, 0x9AC0, 0xF7C2, 0x9AC1, 0xF7C1, 0x9AC2, 0xF7C4, - 0x9AC3, 0xF36B, 0x9AC4, 0xF36C, 0x9AC5, 0xF7C3, 0x9AC6, 0xF36D, 0x9AC7, 0xF36E, 0x9AC8, 0xF36F, 0x9AC9, 0xF370, 0x9ACA, 0xF371, - 0x9ACB, 0xF7C5, 0x9ACC, 0xF7C6, 0x9ACD, 0xF372, 0x9ACE, 0xF373, 0x9ACF, 0xF374, 0x9AD0, 0xF375, 0x9AD1, 0xF7C7, 0x9AD2, 0xF376, - 0x9AD3, 0xCBE8, 0x9AD4, 0xF377, 0x9AD5, 0xF378, 0x9AD6, 0xF379, 0x9AD7, 0xF37A, 0x9AD8, 0xB8DF, 0x9AD9, 0xF37B, 0x9ADA, 0xF37C, - 0x9ADB, 0xF37D, 0x9ADC, 0xF37E, 0x9ADD, 0xF380, 0x9ADE, 0xF381, 0x9ADF, 0xF7D4, 0x9AE0, 0xF382, 0x9AE1, 0xF7D5, 0x9AE2, 0xF383, - 0x9AE3, 0xF384, 0x9AE4, 0xF385, 0x9AE5, 0xF386, 0x9AE6, 0xF7D6, 0x9AE7, 0xF387, 0x9AE8, 0xF388, 0x9AE9, 0xF389, 0x9AEA, 0xF38A, - 0x9AEB, 0xF7D8, 0x9AEC, 0xF38B, 0x9AED, 0xF7DA, 0x9AEE, 0xF38C, 0x9AEF, 0xF7D7, 0x9AF0, 0xF38D, 0x9AF1, 0xF38E, 0x9AF2, 0xF38F, - 0x9AF3, 0xF390, 0x9AF4, 0xF391, 0x9AF5, 0xF392, 0x9AF6, 0xF393, 0x9AF7, 0xF394, 0x9AF8, 0xF395, 0x9AF9, 0xF7DB, 0x9AFA, 0xF396, - 0x9AFB, 0xF7D9, 0x9AFC, 0xF397, 0x9AFD, 0xF398, 0x9AFE, 0xF399, 0x9AFF, 0xF39A, 0x9B00, 0xF39B, 0x9B01, 0xF39C, 0x9B02, 0xF39D, - 0x9B03, 0xD7D7, 0x9B04, 0xF39E, 0x9B05, 0xF39F, 0x9B06, 0xF3A0, 0x9B07, 0xF440, 0x9B08, 0xF7DC, 0x9B09, 0xF441, 0x9B0A, 0xF442, - 0x9B0B, 0xF443, 0x9B0C, 0xF444, 0x9B0D, 0xF445, 0x9B0E, 0xF446, 0x9B0F, 0xF7DD, 0x9B10, 0xF447, 0x9B11, 0xF448, 0x9B12, 0xF449, - 0x9B13, 0xF7DE, 0x9B14, 0xF44A, 0x9B15, 0xF44B, 0x9B16, 0xF44C, 0x9B17, 0xF44D, 0x9B18, 0xF44E, 0x9B19, 0xF44F, 0x9B1A, 0xF450, - 0x9B1B, 0xF451, 0x9B1C, 0xF452, 0x9B1D, 0xF453, 0x9B1E, 0xF454, 0x9B1F, 0xF7DF, 0x9B20, 0xF455, 0x9B21, 0xF456, 0x9B22, 0xF457, - 0x9B23, 0xF7E0, 0x9B24, 0xF458, 0x9B25, 0xF459, 0x9B26, 0xF45A, 0x9B27, 0xF45B, 0x9B28, 0xF45C, 0x9B29, 0xF45D, 0x9B2A, 0xF45E, - 0x9B2B, 0xF45F, 0x9B2C, 0xF460, 0x9B2D, 0xF461, 0x9B2E, 0xF462, 0x9B2F, 0xDBCB, 0x9B30, 0xF463, 0x9B31, 0xF464, 0x9B32, 0xD8AA, - 0x9B33, 0xF465, 0x9B34, 0xF466, 0x9B35, 0xF467, 0x9B36, 0xF468, 0x9B37, 0xF469, 0x9B38, 0xF46A, 0x9B39, 0xF46B, 0x9B3A, 0xF46C, - 0x9B3B, 0xE5F7, 0x9B3C, 0xB9ED, 0x9B3D, 0xF46D, 0x9B3E, 0xF46E, 0x9B3F, 0xF46F, 0x9B40, 0xF470, 0x9B41, 0xBFFD, 0x9B42, 0xBBEA, - 0x9B43, 0xF7C9, 0x9B44, 0xC6C7, 0x9B45, 0xF7C8, 0x9B46, 0xF471, 0x9B47, 0xF7CA, 0x9B48, 0xF7CC, 0x9B49, 0xF7CB, 0x9B4A, 0xF472, - 0x9B4B, 0xF473, 0x9B4C, 0xF474, 0x9B4D, 0xF7CD, 0x9B4E, 0xF475, 0x9B4F, 0xCEBA, 0x9B50, 0xF476, 0x9B51, 0xF7CE, 0x9B52, 0xF477, - 0x9B53, 0xF478, 0x9B54, 0xC4A7, 0x9B55, 0xF479, 0x9B56, 0xF47A, 0x9B57, 0xF47B, 0x9B58, 0xF47C, 0x9B59, 0xF47D, 0x9B5A, 0xF47E, - 0x9B5B, 0xF480, 0x9B5C, 0xF481, 0x9B5D, 0xF482, 0x9B5E, 0xF483, 0x9B5F, 0xF484, 0x9B60, 0xF485, 0x9B61, 0xF486, 0x9B62, 0xF487, - 0x9B63, 0xF488, 0x9B64, 0xF489, 0x9B65, 0xF48A, 0x9B66, 0xF48B, 0x9B67, 0xF48C, 0x9B68, 0xF48D, 0x9B69, 0xF48E, 0x9B6A, 0xF48F, - 0x9B6B, 0xF490, 0x9B6C, 0xF491, 0x9B6D, 0xF492, 0x9B6E, 0xF493, 0x9B6F, 0xF494, 0x9B70, 0xF495, 0x9B71, 0xF496, 0x9B72, 0xF497, - 0x9B73, 0xF498, 0x9B74, 0xF499, 0x9B75, 0xF49A, 0x9B76, 0xF49B, 0x9B77, 0xF49C, 0x9B78, 0xF49D, 0x9B79, 0xF49E, 0x9B7A, 0xF49F, - 0x9B7B, 0xF4A0, 0x9B7C, 0xF540, 0x9B7D, 0xF541, 0x9B7E, 0xF542, 0x9B7F, 0xF543, 0x9B80, 0xF544, 0x9B81, 0xF545, 0x9B82, 0xF546, - 0x9B83, 0xF547, 0x9B84, 0xF548, 0x9B85, 0xF549, 0x9B86, 0xF54A, 0x9B87, 0xF54B, 0x9B88, 0xF54C, 0x9B89, 0xF54D, 0x9B8A, 0xF54E, - 0x9B8B, 0xF54F, 0x9B8C, 0xF550, 0x9B8D, 0xF551, 0x9B8E, 0xF552, 0x9B8F, 0xF553, 0x9B90, 0xF554, 0x9B91, 0xF555, 0x9B92, 0xF556, - 0x9B93, 0xF557, 0x9B94, 0xF558, 0x9B95, 0xF559, 0x9B96, 0xF55A, 0x9B97, 0xF55B, 0x9B98, 0xF55C, 0x9B99, 0xF55D, 0x9B9A, 0xF55E, - 0x9B9B, 0xF55F, 0x9B9C, 0xF560, 0x9B9D, 0xF561, 0x9B9E, 0xF562, 0x9B9F, 0xF563, 0x9BA0, 0xF564, 0x9BA1, 0xF565, 0x9BA2, 0xF566, - 0x9BA3, 0xF567, 0x9BA4, 0xF568, 0x9BA5, 0xF569, 0x9BA6, 0xF56A, 0x9BA7, 0xF56B, 0x9BA8, 0xF56C, 0x9BA9, 0xF56D, 0x9BAA, 0xF56E, - 0x9BAB, 0xF56F, 0x9BAC, 0xF570, 0x9BAD, 0xF571, 0x9BAE, 0xF572, 0x9BAF, 0xF573, 0x9BB0, 0xF574, 0x9BB1, 0xF575, 0x9BB2, 0xF576, - 0x9BB3, 0xF577, 0x9BB4, 0xF578, 0x9BB5, 0xF579, 0x9BB6, 0xF57A, 0x9BB7, 0xF57B, 0x9BB8, 0xF57C, 0x9BB9, 0xF57D, 0x9BBA, 0xF57E, - 0x9BBB, 0xF580, 0x9BBC, 0xF581, 0x9BBD, 0xF582, 0x9BBE, 0xF583, 0x9BBF, 0xF584, 0x9BC0, 0xF585, 0x9BC1, 0xF586, 0x9BC2, 0xF587, - 0x9BC3, 0xF588, 0x9BC4, 0xF589, 0x9BC5, 0xF58A, 0x9BC6, 0xF58B, 0x9BC7, 0xF58C, 0x9BC8, 0xF58D, 0x9BC9, 0xF58E, 0x9BCA, 0xF58F, - 0x9BCB, 0xF590, 0x9BCC, 0xF591, 0x9BCD, 0xF592, 0x9BCE, 0xF593, 0x9BCF, 0xF594, 0x9BD0, 0xF595, 0x9BD1, 0xF596, 0x9BD2, 0xF597, - 0x9BD3, 0xF598, 0x9BD4, 0xF599, 0x9BD5, 0xF59A, 0x9BD6, 0xF59B, 0x9BD7, 0xF59C, 0x9BD8, 0xF59D, 0x9BD9, 0xF59E, 0x9BDA, 0xF59F, - 0x9BDB, 0xF5A0, 0x9BDC, 0xF640, 0x9BDD, 0xF641, 0x9BDE, 0xF642, 0x9BDF, 0xF643, 0x9BE0, 0xF644, 0x9BE1, 0xF645, 0x9BE2, 0xF646, - 0x9BE3, 0xF647, 0x9BE4, 0xF648, 0x9BE5, 0xF649, 0x9BE6, 0xF64A, 0x9BE7, 0xF64B, 0x9BE8, 0xF64C, 0x9BE9, 0xF64D, 0x9BEA, 0xF64E, - 0x9BEB, 0xF64F, 0x9BEC, 0xF650, 0x9BED, 0xF651, 0x9BEE, 0xF652, 0x9BEF, 0xF653, 0x9BF0, 0xF654, 0x9BF1, 0xF655, 0x9BF2, 0xF656, - 0x9BF3, 0xF657, 0x9BF4, 0xF658, 0x9BF5, 0xF659, 0x9BF6, 0xF65A, 0x9BF7, 0xF65B, 0x9BF8, 0xF65C, 0x9BF9, 0xF65D, 0x9BFA, 0xF65E, - 0x9BFB, 0xF65F, 0x9BFC, 0xF660, 0x9BFD, 0xF661, 0x9BFE, 0xF662, 0x9BFF, 0xF663, 0x9C00, 0xF664, 0x9C01, 0xF665, 0x9C02, 0xF666, - 0x9C03, 0xF667, 0x9C04, 0xF668, 0x9C05, 0xF669, 0x9C06, 0xF66A, 0x9C07, 0xF66B, 0x9C08, 0xF66C, 0x9C09, 0xF66D, 0x9C0A, 0xF66E, - 0x9C0B, 0xF66F, 0x9C0C, 0xF670, 0x9C0D, 0xF671, 0x9C0E, 0xF672, 0x9C0F, 0xF673, 0x9C10, 0xF674, 0x9C11, 0xF675, 0x9C12, 0xF676, - 0x9C13, 0xF677, 0x9C14, 0xF678, 0x9C15, 0xF679, 0x9C16, 0xF67A, 0x9C17, 0xF67B, 0x9C18, 0xF67C, 0x9C19, 0xF67D, 0x9C1A, 0xF67E, - 0x9C1B, 0xF680, 0x9C1C, 0xF681, 0x9C1D, 0xF682, 0x9C1E, 0xF683, 0x9C1F, 0xF684, 0x9C20, 0xF685, 0x9C21, 0xF686, 0x9C22, 0xF687, - 0x9C23, 0xF688, 0x9C24, 0xF689, 0x9C25, 0xF68A, 0x9C26, 0xF68B, 0x9C27, 0xF68C, 0x9C28, 0xF68D, 0x9C29, 0xF68E, 0x9C2A, 0xF68F, - 0x9C2B, 0xF690, 0x9C2C, 0xF691, 0x9C2D, 0xF692, 0x9C2E, 0xF693, 0x9C2F, 0xF694, 0x9C30, 0xF695, 0x9C31, 0xF696, 0x9C32, 0xF697, - 0x9C33, 0xF698, 0x9C34, 0xF699, 0x9C35, 0xF69A, 0x9C36, 0xF69B, 0x9C37, 0xF69C, 0x9C38, 0xF69D, 0x9C39, 0xF69E, 0x9C3A, 0xF69F, - 0x9C3B, 0xF6A0, 0x9C3C, 0xF740, 0x9C3D, 0xF741, 0x9C3E, 0xF742, 0x9C3F, 0xF743, 0x9C40, 0xF744, 0x9C41, 0xF745, 0x9C42, 0xF746, - 0x9C43, 0xF747, 0x9C44, 0xF748, 0x9C45, 0xF749, 0x9C46, 0xF74A, 0x9C47, 0xF74B, 0x9C48, 0xF74C, 0x9C49, 0xF74D, 0x9C4A, 0xF74E, - 0x9C4B, 0xF74F, 0x9C4C, 0xF750, 0x9C4D, 0xF751, 0x9C4E, 0xF752, 0x9C4F, 0xF753, 0x9C50, 0xF754, 0x9C51, 0xF755, 0x9C52, 0xF756, - 0x9C53, 0xF757, 0x9C54, 0xF758, 0x9C55, 0xF759, 0x9C56, 0xF75A, 0x9C57, 0xF75B, 0x9C58, 0xF75C, 0x9C59, 0xF75D, 0x9C5A, 0xF75E, - 0x9C5B, 0xF75F, 0x9C5C, 0xF760, 0x9C5D, 0xF761, 0x9C5E, 0xF762, 0x9C5F, 0xF763, 0x9C60, 0xF764, 0x9C61, 0xF765, 0x9C62, 0xF766, - 0x9C63, 0xF767, 0x9C64, 0xF768, 0x9C65, 0xF769, 0x9C66, 0xF76A, 0x9C67, 0xF76B, 0x9C68, 0xF76C, 0x9C69, 0xF76D, 0x9C6A, 0xF76E, - 0x9C6B, 0xF76F, 0x9C6C, 0xF770, 0x9C6D, 0xF771, 0x9C6E, 0xF772, 0x9C6F, 0xF773, 0x9C70, 0xF774, 0x9C71, 0xF775, 0x9C72, 0xF776, - 0x9C73, 0xF777, 0x9C74, 0xF778, 0x9C75, 0xF779, 0x9C76, 0xF77A, 0x9C77, 0xF77B, 0x9C78, 0xF77C, 0x9C79, 0xF77D, 0x9C7A, 0xF77E, - 0x9C7B, 0xF780, 0x9C7C, 0xD3E3, 0x9C7D, 0xF781, 0x9C7E, 0xF782, 0x9C7F, 0xF6CF, 0x9C80, 0xF783, 0x9C81, 0xC2B3, 0x9C82, 0xF6D0, - 0x9C83, 0xF784, 0x9C84, 0xF785, 0x9C85, 0xF6D1, 0x9C86, 0xF6D2, 0x9C87, 0xF6D3, 0x9C88, 0xF6D4, 0x9C89, 0xF786, 0x9C8A, 0xF787, - 0x9C8B, 0xF6D6, 0x9C8C, 0xF788, 0x9C8D, 0xB1AB, 0x9C8E, 0xF6D7, 0x9C8F, 0xF789, 0x9C90, 0xF6D8, 0x9C91, 0xF6D9, 0x9C92, 0xF6DA, - 0x9C93, 0xF78A, 0x9C94, 0xF6DB, 0x9C95, 0xF6DC, 0x9C96, 0xF78B, 0x9C97, 0xF78C, 0x9C98, 0xF78D, 0x9C99, 0xF78E, 0x9C9A, 0xF6DD, - 0x9C9B, 0xF6DE, 0x9C9C, 0xCFCA, 0x9C9D, 0xF78F, 0x9C9E, 0xF6DF, 0x9C9F, 0xF6E0, 0x9CA0, 0xF6E1, 0x9CA1, 0xF6E2, 0x9CA2, 0xF6E3, - 0x9CA3, 0xF6E4, 0x9CA4, 0xC0F0, 0x9CA5, 0xF6E5, 0x9CA6, 0xF6E6, 0x9CA7, 0xF6E7, 0x9CA8, 0xF6E8, 0x9CA9, 0xF6E9, 0x9CAA, 0xF790, - 0x9CAB, 0xF6EA, 0x9CAC, 0xF791, 0x9CAD, 0xF6EB, 0x9CAE, 0xF6EC, 0x9CAF, 0xF792, 0x9CB0, 0xF6ED, 0x9CB1, 0xF6EE, 0x9CB2, 0xF6EF, - 0x9CB3, 0xF6F0, 0x9CB4, 0xF6F1, 0x9CB5, 0xF6F2, 0x9CB6, 0xF6F3, 0x9CB7, 0xF6F4, 0x9CB8, 0xBEA8, 0x9CB9, 0xF793, 0x9CBA, 0xF6F5, - 0x9CBB, 0xF6F6, 0x9CBC, 0xF6F7, 0x9CBD, 0xF6F8, 0x9CBE, 0xF794, 0x9CBF, 0xF795, 0x9CC0, 0xF796, 0x9CC1, 0xF797, 0x9CC2, 0xF798, - 0x9CC3, 0xC8FA, 0x9CC4, 0xF6F9, 0x9CC5, 0xF6FA, 0x9CC6, 0xF6FB, 0x9CC7, 0xF6FC, 0x9CC8, 0xF799, 0x9CC9, 0xF79A, 0x9CCA, 0xF6FD, - 0x9CCB, 0xF6FE, 0x9CCC, 0xF7A1, 0x9CCD, 0xF7A2, 0x9CCE, 0xF7A3, 0x9CCF, 0xF7A4, 0x9CD0, 0xF7A5, 0x9CD1, 0xF79B, 0x9CD2, 0xF79C, - 0x9CD3, 0xF7A6, 0x9CD4, 0xF7A7, 0x9CD5, 0xF7A8, 0x9CD6, 0xB1EE, 0x9CD7, 0xF7A9, 0x9CD8, 0xF7AA, 0x9CD9, 0xF7AB, 0x9CDA, 0xF79D, - 0x9CDB, 0xF79E, 0x9CDC, 0xF7AC, 0x9CDD, 0xF7AD, 0x9CDE, 0xC1DB, 0x9CDF, 0xF7AE, 0x9CE0, 0xF79F, 0x9CE1, 0xF7A0, 0x9CE2, 0xF7AF, - 0x9CE3, 0xF840, 0x9CE4, 0xF841, 0x9CE5, 0xF842, 0x9CE6, 0xF843, 0x9CE7, 0xF844, 0x9CE8, 0xF845, 0x9CE9, 0xF846, 0x9CEA, 0xF847, - 0x9CEB, 0xF848, 0x9CEC, 0xF849, 0x9CED, 0xF84A, 0x9CEE, 0xF84B, 0x9CEF, 0xF84C, 0x9CF0, 0xF84D, 0x9CF1, 0xF84E, 0x9CF2, 0xF84F, - 0x9CF3, 0xF850, 0x9CF4, 0xF851, 0x9CF5, 0xF852, 0x9CF6, 0xF853, 0x9CF7, 0xF854, 0x9CF8, 0xF855, 0x9CF9, 0xF856, 0x9CFA, 0xF857, - 0x9CFB, 0xF858, 0x9CFC, 0xF859, 0x9CFD, 0xF85A, 0x9CFE, 0xF85B, 0x9CFF, 0xF85C, 0x9D00, 0xF85D, 0x9D01, 0xF85E, 0x9D02, 0xF85F, - 0x9D03, 0xF860, 0x9D04, 0xF861, 0x9D05, 0xF862, 0x9D06, 0xF863, 0x9D07, 0xF864, 0x9D08, 0xF865, 0x9D09, 0xF866, 0x9D0A, 0xF867, - 0x9D0B, 0xF868, 0x9D0C, 0xF869, 0x9D0D, 0xF86A, 0x9D0E, 0xF86B, 0x9D0F, 0xF86C, 0x9D10, 0xF86D, 0x9D11, 0xF86E, 0x9D12, 0xF86F, - 0x9D13, 0xF870, 0x9D14, 0xF871, 0x9D15, 0xF872, 0x9D16, 0xF873, 0x9D17, 0xF874, 0x9D18, 0xF875, 0x9D19, 0xF876, 0x9D1A, 0xF877, - 0x9D1B, 0xF878, 0x9D1C, 0xF879, 0x9D1D, 0xF87A, 0x9D1E, 0xF87B, 0x9D1F, 0xF87C, 0x9D20, 0xF87D, 0x9D21, 0xF87E, 0x9D22, 0xF880, - 0x9D23, 0xF881, 0x9D24, 0xF882, 0x9D25, 0xF883, 0x9D26, 0xF884, 0x9D27, 0xF885, 0x9D28, 0xF886, 0x9D29, 0xF887, 0x9D2A, 0xF888, - 0x9D2B, 0xF889, 0x9D2C, 0xF88A, 0x9D2D, 0xF88B, 0x9D2E, 0xF88C, 0x9D2F, 0xF88D, 0x9D30, 0xF88E, 0x9D31, 0xF88F, 0x9D32, 0xF890, - 0x9D33, 0xF891, 0x9D34, 0xF892, 0x9D35, 0xF893, 0x9D36, 0xF894, 0x9D37, 0xF895, 0x9D38, 0xF896, 0x9D39, 0xF897, 0x9D3A, 0xF898, - 0x9D3B, 0xF899, 0x9D3C, 0xF89A, 0x9D3D, 0xF89B, 0x9D3E, 0xF89C, 0x9D3F, 0xF89D, 0x9D40, 0xF89E, 0x9D41, 0xF89F, 0x9D42, 0xF8A0, - 0x9D43, 0xF940, 0x9D44, 0xF941, 0x9D45, 0xF942, 0x9D46, 0xF943, 0x9D47, 0xF944, 0x9D48, 0xF945, 0x9D49, 0xF946, 0x9D4A, 0xF947, - 0x9D4B, 0xF948, 0x9D4C, 0xF949, 0x9D4D, 0xF94A, 0x9D4E, 0xF94B, 0x9D4F, 0xF94C, 0x9D50, 0xF94D, 0x9D51, 0xF94E, 0x9D52, 0xF94F, - 0x9D53, 0xF950, 0x9D54, 0xF951, 0x9D55, 0xF952, 0x9D56, 0xF953, 0x9D57, 0xF954, 0x9D58, 0xF955, 0x9D59, 0xF956, 0x9D5A, 0xF957, - 0x9D5B, 0xF958, 0x9D5C, 0xF959, 0x9D5D, 0xF95A, 0x9D5E, 0xF95B, 0x9D5F, 0xF95C, 0x9D60, 0xF95D, 0x9D61, 0xF95E, 0x9D62, 0xF95F, - 0x9D63, 0xF960, 0x9D64, 0xF961, 0x9D65, 0xF962, 0x9D66, 0xF963, 0x9D67, 0xF964, 0x9D68, 0xF965, 0x9D69, 0xF966, 0x9D6A, 0xF967, - 0x9D6B, 0xF968, 0x9D6C, 0xF969, 0x9D6D, 0xF96A, 0x9D6E, 0xF96B, 0x9D6F, 0xF96C, 0x9D70, 0xF96D, 0x9D71, 0xF96E, 0x9D72, 0xF96F, - 0x9D73, 0xF970, 0x9D74, 0xF971, 0x9D75, 0xF972, 0x9D76, 0xF973, 0x9D77, 0xF974, 0x9D78, 0xF975, 0x9D79, 0xF976, 0x9D7A, 0xF977, - 0x9D7B, 0xF978, 0x9D7C, 0xF979, 0x9D7D, 0xF97A, 0x9D7E, 0xF97B, 0x9D7F, 0xF97C, 0x9D80, 0xF97D, 0x9D81, 0xF97E, 0x9D82, 0xF980, - 0x9D83, 0xF981, 0x9D84, 0xF982, 0x9D85, 0xF983, 0x9D86, 0xF984, 0x9D87, 0xF985, 0x9D88, 0xF986, 0x9D89, 0xF987, 0x9D8A, 0xF988, - 0x9D8B, 0xF989, 0x9D8C, 0xF98A, 0x9D8D, 0xF98B, 0x9D8E, 0xF98C, 0x9D8F, 0xF98D, 0x9D90, 0xF98E, 0x9D91, 0xF98F, 0x9D92, 0xF990, - 0x9D93, 0xF991, 0x9D94, 0xF992, 0x9D95, 0xF993, 0x9D96, 0xF994, 0x9D97, 0xF995, 0x9D98, 0xF996, 0x9D99, 0xF997, 0x9D9A, 0xF998, - 0x9D9B, 0xF999, 0x9D9C, 0xF99A, 0x9D9D, 0xF99B, 0x9D9E, 0xF99C, 0x9D9F, 0xF99D, 0x9DA0, 0xF99E, 0x9DA1, 0xF99F, 0x9DA2, 0xF9A0, - 0x9DA3, 0xFA40, 0x9DA4, 0xFA41, 0x9DA5, 0xFA42, 0x9DA6, 0xFA43, 0x9DA7, 0xFA44, 0x9DA8, 0xFA45, 0x9DA9, 0xFA46, 0x9DAA, 0xFA47, - 0x9DAB, 0xFA48, 0x9DAC, 0xFA49, 0x9DAD, 0xFA4A, 0x9DAE, 0xFA4B, 0x9DAF, 0xFA4C, 0x9DB0, 0xFA4D, 0x9DB1, 0xFA4E, 0x9DB2, 0xFA4F, - 0x9DB3, 0xFA50, 0x9DB4, 0xFA51, 0x9DB5, 0xFA52, 0x9DB6, 0xFA53, 0x9DB7, 0xFA54, 0x9DB8, 0xFA55, 0x9DB9, 0xFA56, 0x9DBA, 0xFA57, - 0x9DBB, 0xFA58, 0x9DBC, 0xFA59, 0x9DBD, 0xFA5A, 0x9DBE, 0xFA5B, 0x9DBF, 0xFA5C, 0x9DC0, 0xFA5D, 0x9DC1, 0xFA5E, 0x9DC2, 0xFA5F, - 0x9DC3, 0xFA60, 0x9DC4, 0xFA61, 0x9DC5, 0xFA62, 0x9DC6, 0xFA63, 0x9DC7, 0xFA64, 0x9DC8, 0xFA65, 0x9DC9, 0xFA66, 0x9DCA, 0xFA67, - 0x9DCB, 0xFA68, 0x9DCC, 0xFA69, 0x9DCD, 0xFA6A, 0x9DCE, 0xFA6B, 0x9DCF, 0xFA6C, 0x9DD0, 0xFA6D, 0x9DD1, 0xFA6E, 0x9DD2, 0xFA6F, - 0x9DD3, 0xFA70, 0x9DD4, 0xFA71, 0x9DD5, 0xFA72, 0x9DD6, 0xFA73, 0x9DD7, 0xFA74, 0x9DD8, 0xFA75, 0x9DD9, 0xFA76, 0x9DDA, 0xFA77, - 0x9DDB, 0xFA78, 0x9DDC, 0xFA79, 0x9DDD, 0xFA7A, 0x9DDE, 0xFA7B, 0x9DDF, 0xFA7C, 0x9DE0, 0xFA7D, 0x9DE1, 0xFA7E, 0x9DE2, 0xFA80, - 0x9DE3, 0xFA81, 0x9DE4, 0xFA82, 0x9DE5, 0xFA83, 0x9DE6, 0xFA84, 0x9DE7, 0xFA85, 0x9DE8, 0xFA86, 0x9DE9, 0xFA87, 0x9DEA, 0xFA88, - 0x9DEB, 0xFA89, 0x9DEC, 0xFA8A, 0x9DED, 0xFA8B, 0x9DEE, 0xFA8C, 0x9DEF, 0xFA8D, 0x9DF0, 0xFA8E, 0x9DF1, 0xFA8F, 0x9DF2, 0xFA90, - 0x9DF3, 0xFA91, 0x9DF4, 0xFA92, 0x9DF5, 0xFA93, 0x9DF6, 0xFA94, 0x9DF7, 0xFA95, 0x9DF8, 0xFA96, 0x9DF9, 0xFA97, 0x9DFA, 0xFA98, - 0x9DFB, 0xFA99, 0x9DFC, 0xFA9A, 0x9DFD, 0xFA9B, 0x9DFE, 0xFA9C, 0x9DFF, 0xFA9D, 0x9E00, 0xFA9E, 0x9E01, 0xFA9F, 0x9E02, 0xFAA0, - 0x9E03, 0xFB40, 0x9E04, 0xFB41, 0x9E05, 0xFB42, 0x9E06, 0xFB43, 0x9E07, 0xFB44, 0x9E08, 0xFB45, 0x9E09, 0xFB46, 0x9E0A, 0xFB47, - 0x9E0B, 0xFB48, 0x9E0C, 0xFB49, 0x9E0D, 0xFB4A, 0x9E0E, 0xFB4B, 0x9E0F, 0xFB4C, 0x9E10, 0xFB4D, 0x9E11, 0xFB4E, 0x9E12, 0xFB4F, - 0x9E13, 0xFB50, 0x9E14, 0xFB51, 0x9E15, 0xFB52, 0x9E16, 0xFB53, 0x9E17, 0xFB54, 0x9E18, 0xFB55, 0x9E19, 0xFB56, 0x9E1A, 0xFB57, - 0x9E1B, 0xFB58, 0x9E1C, 0xFB59, 0x9E1D, 0xFB5A, 0x9E1E, 0xFB5B, 0x9E1F, 0xC4F1, 0x9E20, 0xF0AF, 0x9E21, 0xBCA6, 0x9E22, 0xF0B0, - 0x9E23, 0xC3F9, 0x9E24, 0xFB5C, 0x9E25, 0xC5B8, 0x9E26, 0xD1BB, 0x9E27, 0xFB5D, 0x9E28, 0xF0B1, 0x9E29, 0xF0B2, 0x9E2A, 0xF0B3, - 0x9E2B, 0xF0B4, 0x9E2C, 0xF0B5, 0x9E2D, 0xD1BC, 0x9E2E, 0xFB5E, 0x9E2F, 0xD1EC, 0x9E30, 0xFB5F, 0x9E31, 0xF0B7, 0x9E32, 0xF0B6, - 0x9E33, 0xD4A7, 0x9E34, 0xFB60, 0x9E35, 0xCDD2, 0x9E36, 0xF0B8, 0x9E37, 0xF0BA, 0x9E38, 0xF0B9, 0x9E39, 0xF0BB, 0x9E3A, 0xF0BC, - 0x9E3B, 0xFB61, 0x9E3C, 0xFB62, 0x9E3D, 0xB8EB, 0x9E3E, 0xF0BD, 0x9E3F, 0xBAE8, 0x9E40, 0xFB63, 0x9E41, 0xF0BE, 0x9E42, 0xF0BF, - 0x9E43, 0xBEE9, 0x9E44, 0xF0C0, 0x9E45, 0xB6EC, 0x9E46, 0xF0C1, 0x9E47, 0xF0C2, 0x9E48, 0xF0C3, 0x9E49, 0xF0C4, 0x9E4A, 0xC8B5, - 0x9E4B, 0xF0C5, 0x9E4C, 0xF0C6, 0x9E4D, 0xFB64, 0x9E4E, 0xF0C7, 0x9E4F, 0xC5F4, 0x9E50, 0xFB65, 0x9E51, 0xF0C8, 0x9E52, 0xFB66, - 0x9E53, 0xFB67, 0x9E54, 0xFB68, 0x9E55, 0xF0C9, 0x9E56, 0xFB69, 0x9E57, 0xF0CA, 0x9E58, 0xF7BD, 0x9E59, 0xFB6A, 0x9E5A, 0xF0CB, - 0x9E5B, 0xF0CC, 0x9E5C, 0xF0CD, 0x9E5D, 0xFB6B, 0x9E5E, 0xF0CE, 0x9E5F, 0xFB6C, 0x9E60, 0xFB6D, 0x9E61, 0xFB6E, 0x9E62, 0xFB6F, - 0x9E63, 0xF0CF, 0x9E64, 0xBAD7, 0x9E65, 0xFB70, 0x9E66, 0xF0D0, 0x9E67, 0xF0D1, 0x9E68, 0xF0D2, 0x9E69, 0xF0D3, 0x9E6A, 0xF0D4, - 0x9E6B, 0xF0D5, 0x9E6C, 0xF0D6, 0x9E6D, 0xF0D8, 0x9E6E, 0xFB71, 0x9E6F, 0xFB72, 0x9E70, 0xD3A5, 0x9E71, 0xF0D7, 0x9E72, 0xFB73, - 0x9E73, 0xF0D9, 0x9E74, 0xFB74, 0x9E75, 0xFB75, 0x9E76, 0xFB76, 0x9E77, 0xFB77, 0x9E78, 0xFB78, 0x9E79, 0xFB79, 0x9E7A, 0xFB7A, - 0x9E7B, 0xFB7B, 0x9E7C, 0xFB7C, 0x9E7D, 0xFB7D, 0x9E7E, 0xF5BA, 0x9E7F, 0xC2B9, 0x9E80, 0xFB7E, 0x9E81, 0xFB80, 0x9E82, 0xF7E4, - 0x9E83, 0xFB81, 0x9E84, 0xFB82, 0x9E85, 0xFB83, 0x9E86, 0xFB84, 0x9E87, 0xF7E5, 0x9E88, 0xF7E6, 0x9E89, 0xFB85, 0x9E8A, 0xFB86, - 0x9E8B, 0xF7E7, 0x9E8C, 0xFB87, 0x9E8D, 0xFB88, 0x9E8E, 0xFB89, 0x9E8F, 0xFB8A, 0x9E90, 0xFB8B, 0x9E91, 0xFB8C, 0x9E92, 0xF7E8, - 0x9E93, 0xC2B4, 0x9E94, 0xFB8D, 0x9E95, 0xFB8E, 0x9E96, 0xFB8F, 0x9E97, 0xFB90, 0x9E98, 0xFB91, 0x9E99, 0xFB92, 0x9E9A, 0xFB93, - 0x9E9B, 0xFB94, 0x9E9C, 0xFB95, 0x9E9D, 0xF7EA, 0x9E9E, 0xFB96, 0x9E9F, 0xF7EB, 0x9EA0, 0xFB97, 0x9EA1, 0xFB98, 0x9EA2, 0xFB99, - 0x9EA3, 0xFB9A, 0x9EA4, 0xFB9B, 0x9EA5, 0xFB9C, 0x9EA6, 0xC2F3, 0x9EA7, 0xFB9D, 0x9EA8, 0xFB9E, 0x9EA9, 0xFB9F, 0x9EAA, 0xFBA0, - 0x9EAB, 0xFC40, 0x9EAC, 0xFC41, 0x9EAD, 0xFC42, 0x9EAE, 0xFC43, 0x9EAF, 0xFC44, 0x9EB0, 0xFC45, 0x9EB1, 0xFC46, 0x9EB2, 0xFC47, - 0x9EB3, 0xFC48, 0x9EB4, 0xF4F0, 0x9EB5, 0xFC49, 0x9EB6, 0xFC4A, 0x9EB7, 0xFC4B, 0x9EB8, 0xF4EF, 0x9EB9, 0xFC4C, 0x9EBA, 0xFC4D, - 0x9EBB, 0xC2E9, 0x9EBC, 0xFC4E, 0x9EBD, 0xF7E1, 0x9EBE, 0xF7E2, 0x9EBF, 0xFC4F, 0x9EC0, 0xFC50, 0x9EC1, 0xFC51, 0x9EC2, 0xFC52, - 0x9EC3, 0xFC53, 0x9EC4, 0xBBC6, 0x9EC5, 0xFC54, 0x9EC6, 0xFC55, 0x9EC7, 0xFC56, 0x9EC8, 0xFC57, 0x9EC9, 0xD9E4, 0x9ECA, 0xFC58, - 0x9ECB, 0xFC59, 0x9ECC, 0xFC5A, 0x9ECD, 0xCAF2, 0x9ECE, 0xC0E8, 0x9ECF, 0xF0A4, 0x9ED0, 0xFC5B, 0x9ED1, 0xBADA, 0x9ED2, 0xFC5C, - 0x9ED3, 0xFC5D, 0x9ED4, 0xC7AD, 0x9ED5, 0xFC5E, 0x9ED6, 0xFC5F, 0x9ED7, 0xFC60, 0x9ED8, 0xC4AC, 0x9ED9, 0xFC61, 0x9EDA, 0xFC62, - 0x9EDB, 0xF7EC, 0x9EDC, 0xF7ED, 0x9EDD, 0xF7EE, 0x9EDE, 0xFC63, 0x9EDF, 0xF7F0, 0x9EE0, 0xF7EF, 0x9EE1, 0xFC64, 0x9EE2, 0xF7F1, - 0x9EE3, 0xFC65, 0x9EE4, 0xFC66, 0x9EE5, 0xF7F4, 0x9EE6, 0xFC67, 0x9EE7, 0xF7F3, 0x9EE8, 0xFC68, 0x9EE9, 0xF7F2, 0x9EEA, 0xF7F5, - 0x9EEB, 0xFC69, 0x9EEC, 0xFC6A, 0x9EED, 0xFC6B, 0x9EEE, 0xFC6C, 0x9EEF, 0xF7F6, 0x9EF0, 0xFC6D, 0x9EF1, 0xFC6E, 0x9EF2, 0xFC6F, - 0x9EF3, 0xFC70, 0x9EF4, 0xFC71, 0x9EF5, 0xFC72, 0x9EF6, 0xFC73, 0x9EF7, 0xFC74, 0x9EF8, 0xFC75, 0x9EF9, 0xEDE9, 0x9EFA, 0xFC76, - 0x9EFB, 0xEDEA, 0x9EFC, 0xEDEB, 0x9EFD, 0xFC77, 0x9EFE, 0xF6BC, 0x9EFF, 0xFC78, 0x9F00, 0xFC79, 0x9F01, 0xFC7A, 0x9F02, 0xFC7B, - 0x9F03, 0xFC7C, 0x9F04, 0xFC7D, 0x9F05, 0xFC7E, 0x9F06, 0xFC80, 0x9F07, 0xFC81, 0x9F08, 0xFC82, 0x9F09, 0xFC83, 0x9F0A, 0xFC84, - 0x9F0B, 0xF6BD, 0x9F0C, 0xFC85, 0x9F0D, 0xF6BE, 0x9F0E, 0xB6A6, 0x9F0F, 0xFC86, 0x9F10, 0xD8BE, 0x9F11, 0xFC87, 0x9F12, 0xFC88, - 0x9F13, 0xB9C4, 0x9F14, 0xFC89, 0x9F15, 0xFC8A, 0x9F16, 0xFC8B, 0x9F17, 0xD8BB, 0x9F18, 0xFC8C, 0x9F19, 0xDCB1, 0x9F1A, 0xFC8D, - 0x9F1B, 0xFC8E, 0x9F1C, 0xFC8F, 0x9F1D, 0xFC90, 0x9F1E, 0xFC91, 0x9F1F, 0xFC92, 0x9F20, 0xCAF3, 0x9F21, 0xFC93, 0x9F22, 0xF7F7, - 0x9F23, 0xFC94, 0x9F24, 0xFC95, 0x9F25, 0xFC96, 0x9F26, 0xFC97, 0x9F27, 0xFC98, 0x9F28, 0xFC99, 0x9F29, 0xFC9A, 0x9F2A, 0xFC9B, - 0x9F2B, 0xFC9C, 0x9F2C, 0xF7F8, 0x9F2D, 0xFC9D, 0x9F2E, 0xFC9E, 0x9F2F, 0xF7F9, 0x9F30, 0xFC9F, 0x9F31, 0xFCA0, 0x9F32, 0xFD40, - 0x9F33, 0xFD41, 0x9F34, 0xFD42, 0x9F35, 0xFD43, 0x9F36, 0xFD44, 0x9F37, 0xF7FB, 0x9F38, 0xFD45, 0x9F39, 0xF7FA, 0x9F3A, 0xFD46, - 0x9F3B, 0xB1C7, 0x9F3C, 0xFD47, 0x9F3D, 0xF7FC, 0x9F3E, 0xF7FD, 0x9F3F, 0xFD48, 0x9F40, 0xFD49, 0x9F41, 0xFD4A, 0x9F42, 0xFD4B, - 0x9F43, 0xFD4C, 0x9F44, 0xF7FE, 0x9F45, 0xFD4D, 0x9F46, 0xFD4E, 0x9F47, 0xFD4F, 0x9F48, 0xFD50, 0x9F49, 0xFD51, 0x9F4A, 0xFD52, - 0x9F4B, 0xFD53, 0x9F4C, 0xFD54, 0x9F4D, 0xFD55, 0x9F4E, 0xFD56, 0x9F4F, 0xFD57, 0x9F50, 0xC6EB, 0x9F51, 0xECB4, 0x9F52, 0xFD58, - 0x9F53, 0xFD59, 0x9F54, 0xFD5A, 0x9F55, 0xFD5B, 0x9F56, 0xFD5C, 0x9F57, 0xFD5D, 0x9F58, 0xFD5E, 0x9F59, 0xFD5F, 0x9F5A, 0xFD60, - 0x9F5B, 0xFD61, 0x9F5C, 0xFD62, 0x9F5D, 0xFD63, 0x9F5E, 0xFD64, 0x9F5F, 0xFD65, 0x9F60, 0xFD66, 0x9F61, 0xFD67, 0x9F62, 0xFD68, - 0x9F63, 0xFD69, 0x9F64, 0xFD6A, 0x9F65, 0xFD6B, 0x9F66, 0xFD6C, 0x9F67, 0xFD6D, 0x9F68, 0xFD6E, 0x9F69, 0xFD6F, 0x9F6A, 0xFD70, - 0x9F6B, 0xFD71, 0x9F6C, 0xFD72, 0x9F6D, 0xFD73, 0x9F6E, 0xFD74, 0x9F6F, 0xFD75, 0x9F70, 0xFD76, 0x9F71, 0xFD77, 0x9F72, 0xFD78, - 0x9F73, 0xFD79, 0x9F74, 0xFD7A, 0x9F75, 0xFD7B, 0x9F76, 0xFD7C, 0x9F77, 0xFD7D, 0x9F78, 0xFD7E, 0x9F79, 0xFD80, 0x9F7A, 0xFD81, - 0x9F7B, 0xFD82, 0x9F7C, 0xFD83, 0x9F7D, 0xFD84, 0x9F7E, 0xFD85, 0x9F7F, 0xB3DD, 0x9F80, 0xF6B3, 0x9F81, 0xFD86, 0x9F82, 0xFD87, - 0x9F83, 0xF6B4, 0x9F84, 0xC1E4, 0x9F85, 0xF6B5, 0x9F86, 0xF6B6, 0x9F87, 0xF6B7, 0x9F88, 0xF6B8, 0x9F89, 0xF6B9, 0x9F8A, 0xF6BA, - 0x9F8B, 0xC8A3, 0x9F8C, 0xF6BB, 0x9F8D, 0xFD88, 0x9F8E, 0xFD89, 0x9F8F, 0xFD8A, 0x9F90, 0xFD8B, 0x9F91, 0xFD8C, 0x9F92, 0xFD8D, - 0x9F93, 0xFD8E, 0x9F94, 0xFD8F, 0x9F95, 0xFD90, 0x9F96, 0xFD91, 0x9F97, 0xFD92, 0x9F98, 0xFD93, 0x9F99, 0xC1FA, 0x9F9A, 0xB9A8, - 0x9F9B, 0xEDE8, 0x9F9C, 0xFD94, 0x9F9D, 0xFD95, 0x9F9E, 0xFD96, 0x9F9F, 0xB9EA, 0x9FA0, 0xD9DF, 0x9FA1, 0xFD97, 0x9FA2, 0xFD98, - 0x9FA3, 0xFD99, 0x9FA4, 0xFD9A, 0x9FA5, 0xFD9B, 0xF92C, 0xFD9C, 0xF979, 0xFD9D, 0xF995, 0xFD9E, 0xF9E7, 0xFD9F, 0xF9F1, 0xFDA0, - 0xFA0C, 0xFE40, 0xFA0D, 0xFE41, 0xFA0E, 0xFE42, 0xFA0F, 0xFE43, 0xFA11, 0xFE44, 0xFA13, 0xFE45, 0xFA14, 0xFE46, 0xFA18, 0xFE47, - 0xFA1F, 0xFE48, 0xFA20, 0xFE49, 0xFA21, 0xFE4A, 0xFA23, 0xFE4B, 0xFA24, 0xFE4C, 0xFA27, 0xFE4D, 0xFA28, 0xFE4E, 0xFA29, 0xFE4F, - 0xFE30, 0xA955, 0xFE31, 0xA6F2, 0xFE33, 0xA6F4, 0xFE34, 0xA6F5, 0xFE35, 0xA6E0, 0xFE36, 0xA6E1, 0xFE37, 0xA6F0, 0xFE38, 0xA6F1, - 0xFE39, 0xA6E2, 0xFE3A, 0xA6E3, 0xFE3B, 0xA6EE, 0xFE3C, 0xA6EF, 0xFE3D, 0xA6E6, 0xFE3E, 0xA6E7, 0xFE3F, 0xA6E4, 0xFE40, 0xA6E5, - 0xFE41, 0xA6E8, 0xFE42, 0xA6E9, 0xFE43, 0xA6EA, 0xFE44, 0xA6EB, 0xFE49, 0xA968, 0xFE4A, 0xA969, 0xFE4B, 0xA96A, 0xFE4C, 0xA96B, - 0xFE4D, 0xA96C, 0xFE4E, 0xA96D, 0xFE4F, 0xA96E, 0xFE50, 0xA96F, 0xFE51, 0xA970, 0xFE52, 0xA971, 0xFE54, 0xA972, 0xFE55, 0xA973, - 0xFE56, 0xA974, 0xFE57, 0xA975, 0xFE59, 0xA976, 0xFE5A, 0xA977, 0xFE5B, 0xA978, 0xFE5C, 0xA979, 0xFE5D, 0xA97A, 0xFE5E, 0xA97B, - 0xFE5F, 0xA97C, 0xFE60, 0xA97D, 0xFE61, 0xA97E, 0xFE62, 0xA980, 0xFE63, 0xA981, 0xFE64, 0xA982, 0xFE65, 0xA983, 0xFE66, 0xA984, - 0xFE68, 0xA985, 0xFE69, 0xA986, 0xFE6A, 0xA987, 0xFE6B, 0xA988, 0xFF01, 0xA3A1, 0xFF02, 0xA3A2, 0xFF03, 0xA3A3, 0xFF04, 0xA1E7, - 0xFF05, 0xA3A5, 0xFF06, 0xA3A6, 0xFF07, 0xA3A7, 0xFF08, 0xA3A8, 0xFF09, 0xA3A9, 0xFF0A, 0xA3AA, 0xFF0B, 0xA3AB, 0xFF0C, 0xA3AC, - 0xFF0D, 0xA3AD, 0xFF0E, 0xA3AE, 0xFF0F, 0xA3AF, 0xFF10, 0xA3B0, 0xFF11, 0xA3B1, 0xFF12, 0xA3B2, 0xFF13, 0xA3B3, 0xFF14, 0xA3B4, - 0xFF15, 0xA3B5, 0xFF16, 0xA3B6, 0xFF17, 0xA3B7, 0xFF18, 0xA3B8, 0xFF19, 0xA3B9, 0xFF1A, 0xA3BA, 0xFF1B, 0xA3BB, 0xFF1C, 0xA3BC, - 0xFF1D, 0xA3BD, 0xFF1E, 0xA3BE, 0xFF1F, 0xA3BF, 0xFF20, 0xA3C0, 0xFF21, 0xA3C1, 0xFF22, 0xA3C2, 0xFF23, 0xA3C3, 0xFF24, 0xA3C4, - 0xFF25, 0xA3C5, 0xFF26, 0xA3C6, 0xFF27, 0xA3C7, 0xFF28, 0xA3C8, 0xFF29, 0xA3C9, 0xFF2A, 0xA3CA, 0xFF2B, 0xA3CB, 0xFF2C, 0xA3CC, - 0xFF2D, 0xA3CD, 0xFF2E, 0xA3CE, 0xFF2F, 0xA3CF, 0xFF30, 0xA3D0, 0xFF31, 0xA3D1, 0xFF32, 0xA3D2, 0xFF33, 0xA3D3, 0xFF34, 0xA3D4, - 0xFF35, 0xA3D5, 0xFF36, 0xA3D6, 0xFF37, 0xA3D7, 0xFF38, 0xA3D8, 0xFF39, 0xA3D9, 0xFF3A, 0xA3DA, 0xFF3B, 0xA3DB, 0xFF3C, 0xA3DC, - 0xFF3D, 0xA3DD, 0xFF3E, 0xA3DE, 0xFF3F, 0xA3DF, 0xFF40, 0xA3E0, 0xFF41, 0xA3E1, 0xFF42, 0xA3E2, 0xFF43, 0xA3E3, 0xFF44, 0xA3E4, - 0xFF45, 0xA3E5, 0xFF46, 0xA3E6, 0xFF47, 0xA3E7, 0xFF48, 0xA3E8, 0xFF49, 0xA3E9, 0xFF4A, 0xA3EA, 0xFF4B, 0xA3EB, 0xFF4C, 0xA3EC, - 0xFF4D, 0xA3ED, 0xFF4E, 0xA3EE, 0xFF4F, 0xA3EF, 0xFF50, 0xA3F0, 0xFF51, 0xA3F1, 0xFF52, 0xA3F2, 0xFF53, 0xA3F3, 0xFF54, 0xA3F4, - 0xFF55, 0xA3F5, 0xFF56, 0xA3F6, 0xFF57, 0xA3F7, 0xFF58, 0xA3F8, 0xFF59, 0xA3F9, 0xFF5A, 0xA3FA, 0xFF5B, 0xA3FB, 0xFF5C, 0xA3FC, - 0xFF5D, 0xA3FD, 0xFF5E, 0xA1AB, 0xFFE0, 0xA1E9, 0xFFE1, 0xA1EA, 0xFFE2, 0xA956, 0xFFE3, 0xA3FE, 0xFFE4, 0xA957, 0xFFE5, 0xA3A4, - 0, 0 -}; - -static const WCHAR oem2uni936[] = { /* GBK --> Unicode pairs */ - 0x0080, 0x20AC, 0x8140, 0x4E02, 0x8141, 0x4E04, 0x8142, 0x4E05, 0x8143, 0x4E06, 0x8144, 0x4E0F, 0x8145, 0x4E12, 0x8146, 0x4E17, - 0x8147, 0x4E1F, 0x8148, 0x4E20, 0x8149, 0x4E21, 0x814A, 0x4E23, 0x814B, 0x4E26, 0x814C, 0x4E29, 0x814D, 0x4E2E, 0x814E, 0x4E2F, - 0x814F, 0x4E31, 0x8150, 0x4E33, 0x8151, 0x4E35, 0x8152, 0x4E37, 0x8153, 0x4E3C, 0x8154, 0x4E40, 0x8155, 0x4E41, 0x8156, 0x4E42, - 0x8157, 0x4E44, 0x8158, 0x4E46, 0x8159, 0x4E4A, 0x815A, 0x4E51, 0x815B, 0x4E55, 0x815C, 0x4E57, 0x815D, 0x4E5A, 0x815E, 0x4E5B, - 0x815F, 0x4E62, 0x8160, 0x4E63, 0x8161, 0x4E64, 0x8162, 0x4E65, 0x8163, 0x4E67, 0x8164, 0x4E68, 0x8165, 0x4E6A, 0x8166, 0x4E6B, - 0x8167, 0x4E6C, 0x8168, 0x4E6D, 0x8169, 0x4E6E, 0x816A, 0x4E6F, 0x816B, 0x4E72, 0x816C, 0x4E74, 0x816D, 0x4E75, 0x816E, 0x4E76, - 0x816F, 0x4E77, 0x8170, 0x4E78, 0x8171, 0x4E79, 0x8172, 0x4E7A, 0x8173, 0x4E7B, 0x8174, 0x4E7C, 0x8175, 0x4E7D, 0x8176, 0x4E7F, - 0x8177, 0x4E80, 0x8178, 0x4E81, 0x8179, 0x4E82, 0x817A, 0x4E83, 0x817B, 0x4E84, 0x817C, 0x4E85, 0x817D, 0x4E87, 0x817E, 0x4E8A, - 0x8180, 0x4E90, 0x8181, 0x4E96, 0x8182, 0x4E97, 0x8183, 0x4E99, 0x8184, 0x4E9C, 0x8185, 0x4E9D, 0x8186, 0x4E9E, 0x8187, 0x4EA3, - 0x8188, 0x4EAA, 0x8189, 0x4EAF, 0x818A, 0x4EB0, 0x818B, 0x4EB1, 0x818C, 0x4EB4, 0x818D, 0x4EB6, 0x818E, 0x4EB7, 0x818F, 0x4EB8, - 0x8190, 0x4EB9, 0x8191, 0x4EBC, 0x8192, 0x4EBD, 0x8193, 0x4EBE, 0x8194, 0x4EC8, 0x8195, 0x4ECC, 0x8196, 0x4ECF, 0x8197, 0x4ED0, - 0x8198, 0x4ED2, 0x8199, 0x4EDA, 0x819A, 0x4EDB, 0x819B, 0x4EDC, 0x819C, 0x4EE0, 0x819D, 0x4EE2, 0x819E, 0x4EE6, 0x819F, 0x4EE7, - 0x81A0, 0x4EE9, 0x81A1, 0x4EED, 0x81A2, 0x4EEE, 0x81A3, 0x4EEF, 0x81A4, 0x4EF1, 0x81A5, 0x4EF4, 0x81A6, 0x4EF8, 0x81A7, 0x4EF9, - 0x81A8, 0x4EFA, 0x81A9, 0x4EFC, 0x81AA, 0x4EFE, 0x81AB, 0x4F00, 0x81AC, 0x4F02, 0x81AD, 0x4F03, 0x81AE, 0x4F04, 0x81AF, 0x4F05, - 0x81B0, 0x4F06, 0x81B1, 0x4F07, 0x81B2, 0x4F08, 0x81B3, 0x4F0B, 0x81B4, 0x4F0C, 0x81B5, 0x4F12, 0x81B6, 0x4F13, 0x81B7, 0x4F14, - 0x81B8, 0x4F15, 0x81B9, 0x4F16, 0x81BA, 0x4F1C, 0x81BB, 0x4F1D, 0x81BC, 0x4F21, 0x81BD, 0x4F23, 0x81BE, 0x4F28, 0x81BF, 0x4F29, - 0x81C0, 0x4F2C, 0x81C1, 0x4F2D, 0x81C2, 0x4F2E, 0x81C3, 0x4F31, 0x81C4, 0x4F33, 0x81C5, 0x4F35, 0x81C6, 0x4F37, 0x81C7, 0x4F39, - 0x81C8, 0x4F3B, 0x81C9, 0x4F3E, 0x81CA, 0x4F3F, 0x81CB, 0x4F40, 0x81CC, 0x4F41, 0x81CD, 0x4F42, 0x81CE, 0x4F44, 0x81CF, 0x4F45, - 0x81D0, 0x4F47, 0x81D1, 0x4F48, 0x81D2, 0x4F49, 0x81D3, 0x4F4A, 0x81D4, 0x4F4B, 0x81D5, 0x4F4C, 0x81D6, 0x4F52, 0x81D7, 0x4F54, - 0x81D8, 0x4F56, 0x81D9, 0x4F61, 0x81DA, 0x4F62, 0x81DB, 0x4F66, 0x81DC, 0x4F68, 0x81DD, 0x4F6A, 0x81DE, 0x4F6B, 0x81DF, 0x4F6D, - 0x81E0, 0x4F6E, 0x81E1, 0x4F71, 0x81E2, 0x4F72, 0x81E3, 0x4F75, 0x81E4, 0x4F77, 0x81E5, 0x4F78, 0x81E6, 0x4F79, 0x81E7, 0x4F7A, - 0x81E8, 0x4F7D, 0x81E9, 0x4F80, 0x81EA, 0x4F81, 0x81EB, 0x4F82, 0x81EC, 0x4F85, 0x81ED, 0x4F86, 0x81EE, 0x4F87, 0x81EF, 0x4F8A, - 0x81F0, 0x4F8C, 0x81F1, 0x4F8E, 0x81F2, 0x4F90, 0x81F3, 0x4F92, 0x81F4, 0x4F93, 0x81F5, 0x4F95, 0x81F6, 0x4F96, 0x81F7, 0x4F98, - 0x81F8, 0x4F99, 0x81F9, 0x4F9A, 0x81FA, 0x4F9C, 0x81FB, 0x4F9E, 0x81FC, 0x4F9F, 0x81FD, 0x4FA1, 0x81FE, 0x4FA2, 0x8240, 0x4FA4, - 0x8241, 0x4FAB, 0x8242, 0x4FAD, 0x8243, 0x4FB0, 0x8244, 0x4FB1, 0x8245, 0x4FB2, 0x8246, 0x4FB3, 0x8247, 0x4FB4, 0x8248, 0x4FB6, - 0x8249, 0x4FB7, 0x824A, 0x4FB8, 0x824B, 0x4FB9, 0x824C, 0x4FBA, 0x824D, 0x4FBB, 0x824E, 0x4FBC, 0x824F, 0x4FBD, 0x8250, 0x4FBE, - 0x8251, 0x4FC0, 0x8252, 0x4FC1, 0x8253, 0x4FC2, 0x8254, 0x4FC6, 0x8255, 0x4FC7, 0x8256, 0x4FC8, 0x8257, 0x4FC9, 0x8258, 0x4FCB, - 0x8259, 0x4FCC, 0x825A, 0x4FCD, 0x825B, 0x4FD2, 0x825C, 0x4FD3, 0x825D, 0x4FD4, 0x825E, 0x4FD5, 0x825F, 0x4FD6, 0x8260, 0x4FD9, - 0x8261, 0x4FDB, 0x8262, 0x4FE0, 0x8263, 0x4FE2, 0x8264, 0x4FE4, 0x8265, 0x4FE5, 0x8266, 0x4FE7, 0x8267, 0x4FEB, 0x8268, 0x4FEC, - 0x8269, 0x4FF0, 0x826A, 0x4FF2, 0x826B, 0x4FF4, 0x826C, 0x4FF5, 0x826D, 0x4FF6, 0x826E, 0x4FF7, 0x826F, 0x4FF9, 0x8270, 0x4FFB, - 0x8271, 0x4FFC, 0x8272, 0x4FFD, 0x8273, 0x4FFF, 0x8274, 0x5000, 0x8275, 0x5001, 0x8276, 0x5002, 0x8277, 0x5003, 0x8278, 0x5004, - 0x8279, 0x5005, 0x827A, 0x5006, 0x827B, 0x5007, 0x827C, 0x5008, 0x827D, 0x5009, 0x827E, 0x500A, 0x8280, 0x500B, 0x8281, 0x500E, - 0x8282, 0x5010, 0x8283, 0x5011, 0x8284, 0x5013, 0x8285, 0x5015, 0x8286, 0x5016, 0x8287, 0x5017, 0x8288, 0x501B, 0x8289, 0x501D, - 0x828A, 0x501E, 0x828B, 0x5020, 0x828C, 0x5022, 0x828D, 0x5023, 0x828E, 0x5024, 0x828F, 0x5027, 0x8290, 0x502B, 0x8291, 0x502F, - 0x8292, 0x5030, 0x8293, 0x5031, 0x8294, 0x5032, 0x8295, 0x5033, 0x8296, 0x5034, 0x8297, 0x5035, 0x8298, 0x5036, 0x8299, 0x5037, - 0x829A, 0x5038, 0x829B, 0x5039, 0x829C, 0x503B, 0x829D, 0x503D, 0x829E, 0x503F, 0x829F, 0x5040, 0x82A0, 0x5041, 0x82A1, 0x5042, - 0x82A2, 0x5044, 0x82A3, 0x5045, 0x82A4, 0x5046, 0x82A5, 0x5049, 0x82A6, 0x504A, 0x82A7, 0x504B, 0x82A8, 0x504D, 0x82A9, 0x5050, - 0x82AA, 0x5051, 0x82AB, 0x5052, 0x82AC, 0x5053, 0x82AD, 0x5054, 0x82AE, 0x5056, 0x82AF, 0x5057, 0x82B0, 0x5058, 0x82B1, 0x5059, - 0x82B2, 0x505B, 0x82B3, 0x505D, 0x82B4, 0x505E, 0x82B5, 0x505F, 0x82B6, 0x5060, 0x82B7, 0x5061, 0x82B8, 0x5062, 0x82B9, 0x5063, - 0x82BA, 0x5064, 0x82BB, 0x5066, 0x82BC, 0x5067, 0x82BD, 0x5068, 0x82BE, 0x5069, 0x82BF, 0x506A, 0x82C0, 0x506B, 0x82C1, 0x506D, - 0x82C2, 0x506E, 0x82C3, 0x506F, 0x82C4, 0x5070, 0x82C5, 0x5071, 0x82C6, 0x5072, 0x82C7, 0x5073, 0x82C8, 0x5074, 0x82C9, 0x5075, - 0x82CA, 0x5078, 0x82CB, 0x5079, 0x82CC, 0x507A, 0x82CD, 0x507C, 0x82CE, 0x507D, 0x82CF, 0x5081, 0x82D0, 0x5082, 0x82D1, 0x5083, - 0x82D2, 0x5084, 0x82D3, 0x5086, 0x82D4, 0x5087, 0x82D5, 0x5089, 0x82D6, 0x508A, 0x82D7, 0x508B, 0x82D8, 0x508C, 0x82D9, 0x508E, - 0x82DA, 0x508F, 0x82DB, 0x5090, 0x82DC, 0x5091, 0x82DD, 0x5092, 0x82DE, 0x5093, 0x82DF, 0x5094, 0x82E0, 0x5095, 0x82E1, 0x5096, - 0x82E2, 0x5097, 0x82E3, 0x5098, 0x82E4, 0x5099, 0x82E5, 0x509A, 0x82E6, 0x509B, 0x82E7, 0x509C, 0x82E8, 0x509D, 0x82E9, 0x509E, - 0x82EA, 0x509F, 0x82EB, 0x50A0, 0x82EC, 0x50A1, 0x82ED, 0x50A2, 0x82EE, 0x50A4, 0x82EF, 0x50A6, 0x82F0, 0x50AA, 0x82F1, 0x50AB, - 0x82F2, 0x50AD, 0x82F3, 0x50AE, 0x82F4, 0x50AF, 0x82F5, 0x50B0, 0x82F6, 0x50B1, 0x82F7, 0x50B3, 0x82F8, 0x50B4, 0x82F9, 0x50B5, - 0x82FA, 0x50B6, 0x82FB, 0x50B7, 0x82FC, 0x50B8, 0x82FD, 0x50B9, 0x82FE, 0x50BC, 0x8340, 0x50BD, 0x8341, 0x50BE, 0x8342, 0x50BF, - 0x8343, 0x50C0, 0x8344, 0x50C1, 0x8345, 0x50C2, 0x8346, 0x50C3, 0x8347, 0x50C4, 0x8348, 0x50C5, 0x8349, 0x50C6, 0x834A, 0x50C7, - 0x834B, 0x50C8, 0x834C, 0x50C9, 0x834D, 0x50CA, 0x834E, 0x50CB, 0x834F, 0x50CC, 0x8350, 0x50CD, 0x8351, 0x50CE, 0x8352, 0x50D0, - 0x8353, 0x50D1, 0x8354, 0x50D2, 0x8355, 0x50D3, 0x8356, 0x50D4, 0x8357, 0x50D5, 0x8358, 0x50D7, 0x8359, 0x50D8, 0x835A, 0x50D9, - 0x835B, 0x50DB, 0x835C, 0x50DC, 0x835D, 0x50DD, 0x835E, 0x50DE, 0x835F, 0x50DF, 0x8360, 0x50E0, 0x8361, 0x50E1, 0x8362, 0x50E2, - 0x8363, 0x50E3, 0x8364, 0x50E4, 0x8365, 0x50E5, 0x8366, 0x50E8, 0x8367, 0x50E9, 0x8368, 0x50EA, 0x8369, 0x50EB, 0x836A, 0x50EF, - 0x836B, 0x50F0, 0x836C, 0x50F1, 0x836D, 0x50F2, 0x836E, 0x50F4, 0x836F, 0x50F6, 0x8370, 0x50F7, 0x8371, 0x50F8, 0x8372, 0x50F9, - 0x8373, 0x50FA, 0x8374, 0x50FC, 0x8375, 0x50FD, 0x8376, 0x50FE, 0x8377, 0x50FF, 0x8378, 0x5100, 0x8379, 0x5101, 0x837A, 0x5102, - 0x837B, 0x5103, 0x837C, 0x5104, 0x837D, 0x5105, 0x837E, 0x5108, 0x8380, 0x5109, 0x8381, 0x510A, 0x8382, 0x510C, 0x8383, 0x510D, - 0x8384, 0x510E, 0x8385, 0x510F, 0x8386, 0x5110, 0x8387, 0x5111, 0x8388, 0x5113, 0x8389, 0x5114, 0x838A, 0x5115, 0x838B, 0x5116, - 0x838C, 0x5117, 0x838D, 0x5118, 0x838E, 0x5119, 0x838F, 0x511A, 0x8390, 0x511B, 0x8391, 0x511C, 0x8392, 0x511D, 0x8393, 0x511E, - 0x8394, 0x511F, 0x8395, 0x5120, 0x8396, 0x5122, 0x8397, 0x5123, 0x8398, 0x5124, 0x8399, 0x5125, 0x839A, 0x5126, 0x839B, 0x5127, - 0x839C, 0x5128, 0x839D, 0x5129, 0x839E, 0x512A, 0x839F, 0x512B, 0x83A0, 0x512C, 0x83A1, 0x512D, 0x83A2, 0x512E, 0x83A3, 0x512F, - 0x83A4, 0x5130, 0x83A5, 0x5131, 0x83A6, 0x5132, 0x83A7, 0x5133, 0x83A8, 0x5134, 0x83A9, 0x5135, 0x83AA, 0x5136, 0x83AB, 0x5137, - 0x83AC, 0x5138, 0x83AD, 0x5139, 0x83AE, 0x513A, 0x83AF, 0x513B, 0x83B0, 0x513C, 0x83B1, 0x513D, 0x83B2, 0x513E, 0x83B3, 0x5142, - 0x83B4, 0x5147, 0x83B5, 0x514A, 0x83B6, 0x514C, 0x83B7, 0x514E, 0x83B8, 0x514F, 0x83B9, 0x5150, 0x83BA, 0x5152, 0x83BB, 0x5153, - 0x83BC, 0x5157, 0x83BD, 0x5158, 0x83BE, 0x5159, 0x83BF, 0x515B, 0x83C0, 0x515D, 0x83C1, 0x515E, 0x83C2, 0x515F, 0x83C3, 0x5160, - 0x83C4, 0x5161, 0x83C5, 0x5163, 0x83C6, 0x5164, 0x83C7, 0x5166, 0x83C8, 0x5167, 0x83C9, 0x5169, 0x83CA, 0x516A, 0x83CB, 0x516F, - 0x83CC, 0x5172, 0x83CD, 0x517A, 0x83CE, 0x517E, 0x83CF, 0x517F, 0x83D0, 0x5183, 0x83D1, 0x5184, 0x83D2, 0x5186, 0x83D3, 0x5187, - 0x83D4, 0x518A, 0x83D5, 0x518B, 0x83D6, 0x518E, 0x83D7, 0x518F, 0x83D8, 0x5190, 0x83D9, 0x5191, 0x83DA, 0x5193, 0x83DB, 0x5194, - 0x83DC, 0x5198, 0x83DD, 0x519A, 0x83DE, 0x519D, 0x83DF, 0x519E, 0x83E0, 0x519F, 0x83E1, 0x51A1, 0x83E2, 0x51A3, 0x83E3, 0x51A6, - 0x83E4, 0x51A7, 0x83E5, 0x51A8, 0x83E6, 0x51A9, 0x83E7, 0x51AA, 0x83E8, 0x51AD, 0x83E9, 0x51AE, 0x83EA, 0x51B4, 0x83EB, 0x51B8, - 0x83EC, 0x51B9, 0x83ED, 0x51BA, 0x83EE, 0x51BE, 0x83EF, 0x51BF, 0x83F0, 0x51C1, 0x83F1, 0x51C2, 0x83F2, 0x51C3, 0x83F3, 0x51C5, - 0x83F4, 0x51C8, 0x83F5, 0x51CA, 0x83F6, 0x51CD, 0x83F7, 0x51CE, 0x83F8, 0x51D0, 0x83F9, 0x51D2, 0x83FA, 0x51D3, 0x83FB, 0x51D4, - 0x83FC, 0x51D5, 0x83FD, 0x51D6, 0x83FE, 0x51D7, 0x8440, 0x51D8, 0x8441, 0x51D9, 0x8442, 0x51DA, 0x8443, 0x51DC, 0x8444, 0x51DE, - 0x8445, 0x51DF, 0x8446, 0x51E2, 0x8447, 0x51E3, 0x8448, 0x51E5, 0x8449, 0x51E6, 0x844A, 0x51E7, 0x844B, 0x51E8, 0x844C, 0x51E9, - 0x844D, 0x51EA, 0x844E, 0x51EC, 0x844F, 0x51EE, 0x8450, 0x51F1, 0x8451, 0x51F2, 0x8452, 0x51F4, 0x8453, 0x51F7, 0x8454, 0x51FE, - 0x8455, 0x5204, 0x8456, 0x5205, 0x8457, 0x5209, 0x8458, 0x520B, 0x8459, 0x520C, 0x845A, 0x520F, 0x845B, 0x5210, 0x845C, 0x5213, - 0x845D, 0x5214, 0x845E, 0x5215, 0x845F, 0x521C, 0x8460, 0x521E, 0x8461, 0x521F, 0x8462, 0x5221, 0x8463, 0x5222, 0x8464, 0x5223, - 0x8465, 0x5225, 0x8466, 0x5226, 0x8467, 0x5227, 0x8468, 0x522A, 0x8469, 0x522C, 0x846A, 0x522F, 0x846B, 0x5231, 0x846C, 0x5232, - 0x846D, 0x5234, 0x846E, 0x5235, 0x846F, 0x523C, 0x8470, 0x523E, 0x8471, 0x5244, 0x8472, 0x5245, 0x8473, 0x5246, 0x8474, 0x5247, - 0x8475, 0x5248, 0x8476, 0x5249, 0x8477, 0x524B, 0x8478, 0x524E, 0x8479, 0x524F, 0x847A, 0x5252, 0x847B, 0x5253, 0x847C, 0x5255, - 0x847D, 0x5257, 0x847E, 0x5258, 0x8480, 0x5259, 0x8481, 0x525A, 0x8482, 0x525B, 0x8483, 0x525D, 0x8484, 0x525F, 0x8485, 0x5260, - 0x8486, 0x5262, 0x8487, 0x5263, 0x8488, 0x5264, 0x8489, 0x5266, 0x848A, 0x5268, 0x848B, 0x526B, 0x848C, 0x526C, 0x848D, 0x526D, - 0x848E, 0x526E, 0x848F, 0x5270, 0x8490, 0x5271, 0x8491, 0x5273, 0x8492, 0x5274, 0x8493, 0x5275, 0x8494, 0x5276, 0x8495, 0x5277, - 0x8496, 0x5278, 0x8497, 0x5279, 0x8498, 0x527A, 0x8499, 0x527B, 0x849A, 0x527C, 0x849B, 0x527E, 0x849C, 0x5280, 0x849D, 0x5283, - 0x849E, 0x5284, 0x849F, 0x5285, 0x84A0, 0x5286, 0x84A1, 0x5287, 0x84A2, 0x5289, 0x84A3, 0x528A, 0x84A4, 0x528B, 0x84A5, 0x528C, - 0x84A6, 0x528D, 0x84A7, 0x528E, 0x84A8, 0x528F, 0x84A9, 0x5291, 0x84AA, 0x5292, 0x84AB, 0x5294, 0x84AC, 0x5295, 0x84AD, 0x5296, - 0x84AE, 0x5297, 0x84AF, 0x5298, 0x84B0, 0x5299, 0x84B1, 0x529A, 0x84B2, 0x529C, 0x84B3, 0x52A4, 0x84B4, 0x52A5, 0x84B5, 0x52A6, - 0x84B6, 0x52A7, 0x84B7, 0x52AE, 0x84B8, 0x52AF, 0x84B9, 0x52B0, 0x84BA, 0x52B4, 0x84BB, 0x52B5, 0x84BC, 0x52B6, 0x84BD, 0x52B7, - 0x84BE, 0x52B8, 0x84BF, 0x52B9, 0x84C0, 0x52BA, 0x84C1, 0x52BB, 0x84C2, 0x52BC, 0x84C3, 0x52BD, 0x84C4, 0x52C0, 0x84C5, 0x52C1, - 0x84C6, 0x52C2, 0x84C7, 0x52C4, 0x84C8, 0x52C5, 0x84C9, 0x52C6, 0x84CA, 0x52C8, 0x84CB, 0x52CA, 0x84CC, 0x52CC, 0x84CD, 0x52CD, - 0x84CE, 0x52CE, 0x84CF, 0x52CF, 0x84D0, 0x52D1, 0x84D1, 0x52D3, 0x84D2, 0x52D4, 0x84D3, 0x52D5, 0x84D4, 0x52D7, 0x84D5, 0x52D9, - 0x84D6, 0x52DA, 0x84D7, 0x52DB, 0x84D8, 0x52DC, 0x84D9, 0x52DD, 0x84DA, 0x52DE, 0x84DB, 0x52E0, 0x84DC, 0x52E1, 0x84DD, 0x52E2, - 0x84DE, 0x52E3, 0x84DF, 0x52E5, 0x84E0, 0x52E6, 0x84E1, 0x52E7, 0x84E2, 0x52E8, 0x84E3, 0x52E9, 0x84E4, 0x52EA, 0x84E5, 0x52EB, - 0x84E6, 0x52EC, 0x84E7, 0x52ED, 0x84E8, 0x52EE, 0x84E9, 0x52EF, 0x84EA, 0x52F1, 0x84EB, 0x52F2, 0x84EC, 0x52F3, 0x84ED, 0x52F4, - 0x84EE, 0x52F5, 0x84EF, 0x52F6, 0x84F0, 0x52F7, 0x84F1, 0x52F8, 0x84F2, 0x52FB, 0x84F3, 0x52FC, 0x84F4, 0x52FD, 0x84F5, 0x5301, - 0x84F6, 0x5302, 0x84F7, 0x5303, 0x84F8, 0x5304, 0x84F9, 0x5307, 0x84FA, 0x5309, 0x84FB, 0x530A, 0x84FC, 0x530B, 0x84FD, 0x530C, - 0x84FE, 0x530E, 0x8540, 0x5311, 0x8541, 0x5312, 0x8542, 0x5313, 0x8543, 0x5314, 0x8544, 0x5318, 0x8545, 0x531B, 0x8546, 0x531C, - 0x8547, 0x531E, 0x8548, 0x531F, 0x8549, 0x5322, 0x854A, 0x5324, 0x854B, 0x5325, 0x854C, 0x5327, 0x854D, 0x5328, 0x854E, 0x5329, - 0x854F, 0x532B, 0x8550, 0x532C, 0x8551, 0x532D, 0x8552, 0x532F, 0x8553, 0x5330, 0x8554, 0x5331, 0x8555, 0x5332, 0x8556, 0x5333, - 0x8557, 0x5334, 0x8558, 0x5335, 0x8559, 0x5336, 0x855A, 0x5337, 0x855B, 0x5338, 0x855C, 0x533C, 0x855D, 0x533D, 0x855E, 0x5340, - 0x855F, 0x5342, 0x8560, 0x5344, 0x8561, 0x5346, 0x8562, 0x534B, 0x8563, 0x534C, 0x8564, 0x534D, 0x8565, 0x5350, 0x8566, 0x5354, - 0x8567, 0x5358, 0x8568, 0x5359, 0x8569, 0x535B, 0x856A, 0x535D, 0x856B, 0x5365, 0x856C, 0x5368, 0x856D, 0x536A, 0x856E, 0x536C, - 0x856F, 0x536D, 0x8570, 0x5372, 0x8571, 0x5376, 0x8572, 0x5379, 0x8573, 0x537B, 0x8574, 0x537C, 0x8575, 0x537D, 0x8576, 0x537E, - 0x8577, 0x5380, 0x8578, 0x5381, 0x8579, 0x5383, 0x857A, 0x5387, 0x857B, 0x5388, 0x857C, 0x538A, 0x857D, 0x538E, 0x857E, 0x538F, - 0x8580, 0x5390, 0x8581, 0x5391, 0x8582, 0x5392, 0x8583, 0x5393, 0x8584, 0x5394, 0x8585, 0x5396, 0x8586, 0x5397, 0x8587, 0x5399, - 0x8588, 0x539B, 0x8589, 0x539C, 0x858A, 0x539E, 0x858B, 0x53A0, 0x858C, 0x53A1, 0x858D, 0x53A4, 0x858E, 0x53A7, 0x858F, 0x53AA, - 0x8590, 0x53AB, 0x8591, 0x53AC, 0x8592, 0x53AD, 0x8593, 0x53AF, 0x8594, 0x53B0, 0x8595, 0x53B1, 0x8596, 0x53B2, 0x8597, 0x53B3, - 0x8598, 0x53B4, 0x8599, 0x53B5, 0x859A, 0x53B7, 0x859B, 0x53B8, 0x859C, 0x53B9, 0x859D, 0x53BA, 0x859E, 0x53BC, 0x859F, 0x53BD, - 0x85A0, 0x53BE, 0x85A1, 0x53C0, 0x85A2, 0x53C3, 0x85A3, 0x53C4, 0x85A4, 0x53C5, 0x85A5, 0x53C6, 0x85A6, 0x53C7, 0x85A7, 0x53CE, - 0x85A8, 0x53CF, 0x85A9, 0x53D0, 0x85AA, 0x53D2, 0x85AB, 0x53D3, 0x85AC, 0x53D5, 0x85AD, 0x53DA, 0x85AE, 0x53DC, 0x85AF, 0x53DD, - 0x85B0, 0x53DE, 0x85B1, 0x53E1, 0x85B2, 0x53E2, 0x85B3, 0x53E7, 0x85B4, 0x53F4, 0x85B5, 0x53FA, 0x85B6, 0x53FE, 0x85B7, 0x53FF, - 0x85B8, 0x5400, 0x85B9, 0x5402, 0x85BA, 0x5405, 0x85BB, 0x5407, 0x85BC, 0x540B, 0x85BD, 0x5414, 0x85BE, 0x5418, 0x85BF, 0x5419, - 0x85C0, 0x541A, 0x85C1, 0x541C, 0x85C2, 0x5422, 0x85C3, 0x5424, 0x85C4, 0x5425, 0x85C5, 0x542A, 0x85C6, 0x5430, 0x85C7, 0x5433, - 0x85C8, 0x5436, 0x85C9, 0x5437, 0x85CA, 0x543A, 0x85CB, 0x543D, 0x85CC, 0x543F, 0x85CD, 0x5441, 0x85CE, 0x5442, 0x85CF, 0x5444, - 0x85D0, 0x5445, 0x85D1, 0x5447, 0x85D2, 0x5449, 0x85D3, 0x544C, 0x85D4, 0x544D, 0x85D5, 0x544E, 0x85D6, 0x544F, 0x85D7, 0x5451, - 0x85D8, 0x545A, 0x85D9, 0x545D, 0x85DA, 0x545E, 0x85DB, 0x545F, 0x85DC, 0x5460, 0x85DD, 0x5461, 0x85DE, 0x5463, 0x85DF, 0x5465, - 0x85E0, 0x5467, 0x85E1, 0x5469, 0x85E2, 0x546A, 0x85E3, 0x546B, 0x85E4, 0x546C, 0x85E5, 0x546D, 0x85E6, 0x546E, 0x85E7, 0x546F, - 0x85E8, 0x5470, 0x85E9, 0x5474, 0x85EA, 0x5479, 0x85EB, 0x547A, 0x85EC, 0x547E, 0x85ED, 0x547F, 0x85EE, 0x5481, 0x85EF, 0x5483, - 0x85F0, 0x5485, 0x85F1, 0x5487, 0x85F2, 0x5488, 0x85F3, 0x5489, 0x85F4, 0x548A, 0x85F5, 0x548D, 0x85F6, 0x5491, 0x85F7, 0x5493, - 0x85F8, 0x5497, 0x85F9, 0x5498, 0x85FA, 0x549C, 0x85FB, 0x549E, 0x85FC, 0x549F, 0x85FD, 0x54A0, 0x85FE, 0x54A1, 0x8640, 0x54A2, - 0x8641, 0x54A5, 0x8642, 0x54AE, 0x8643, 0x54B0, 0x8644, 0x54B2, 0x8645, 0x54B5, 0x8646, 0x54B6, 0x8647, 0x54B7, 0x8648, 0x54B9, - 0x8649, 0x54BA, 0x864A, 0x54BC, 0x864B, 0x54BE, 0x864C, 0x54C3, 0x864D, 0x54C5, 0x864E, 0x54CA, 0x864F, 0x54CB, 0x8650, 0x54D6, - 0x8651, 0x54D8, 0x8652, 0x54DB, 0x8653, 0x54E0, 0x8654, 0x54E1, 0x8655, 0x54E2, 0x8656, 0x54E3, 0x8657, 0x54E4, 0x8658, 0x54EB, - 0x8659, 0x54EC, 0x865A, 0x54EF, 0x865B, 0x54F0, 0x865C, 0x54F1, 0x865D, 0x54F4, 0x865E, 0x54F5, 0x865F, 0x54F6, 0x8660, 0x54F7, - 0x8661, 0x54F8, 0x8662, 0x54F9, 0x8663, 0x54FB, 0x8664, 0x54FE, 0x8665, 0x5500, 0x8666, 0x5502, 0x8667, 0x5503, 0x8668, 0x5504, - 0x8669, 0x5505, 0x866A, 0x5508, 0x866B, 0x550A, 0x866C, 0x550B, 0x866D, 0x550C, 0x866E, 0x550D, 0x866F, 0x550E, 0x8670, 0x5512, - 0x8671, 0x5513, 0x8672, 0x5515, 0x8673, 0x5516, 0x8674, 0x5517, 0x8675, 0x5518, 0x8676, 0x5519, 0x8677, 0x551A, 0x8678, 0x551C, - 0x8679, 0x551D, 0x867A, 0x551E, 0x867B, 0x551F, 0x867C, 0x5521, 0x867D, 0x5525, 0x867E, 0x5526, 0x8680, 0x5528, 0x8681, 0x5529, - 0x8682, 0x552B, 0x8683, 0x552D, 0x8684, 0x5532, 0x8685, 0x5534, 0x8686, 0x5535, 0x8687, 0x5536, 0x8688, 0x5538, 0x8689, 0x5539, - 0x868A, 0x553A, 0x868B, 0x553B, 0x868C, 0x553D, 0x868D, 0x5540, 0x868E, 0x5542, 0x868F, 0x5545, 0x8690, 0x5547, 0x8691, 0x5548, - 0x8692, 0x554B, 0x8693, 0x554C, 0x8694, 0x554D, 0x8695, 0x554E, 0x8696, 0x554F, 0x8697, 0x5551, 0x8698, 0x5552, 0x8699, 0x5553, - 0x869A, 0x5554, 0x869B, 0x5557, 0x869C, 0x5558, 0x869D, 0x5559, 0x869E, 0x555A, 0x869F, 0x555B, 0x86A0, 0x555D, 0x86A1, 0x555E, - 0x86A2, 0x555F, 0x86A3, 0x5560, 0x86A4, 0x5562, 0x86A5, 0x5563, 0x86A6, 0x5568, 0x86A7, 0x5569, 0x86A8, 0x556B, 0x86A9, 0x556F, - 0x86AA, 0x5570, 0x86AB, 0x5571, 0x86AC, 0x5572, 0x86AD, 0x5573, 0x86AE, 0x5574, 0x86AF, 0x5579, 0x86B0, 0x557A, 0x86B1, 0x557D, - 0x86B2, 0x557F, 0x86B3, 0x5585, 0x86B4, 0x5586, 0x86B5, 0x558C, 0x86B6, 0x558D, 0x86B7, 0x558E, 0x86B8, 0x5590, 0x86B9, 0x5592, - 0x86BA, 0x5593, 0x86BB, 0x5595, 0x86BC, 0x5596, 0x86BD, 0x5597, 0x86BE, 0x559A, 0x86BF, 0x559B, 0x86C0, 0x559E, 0x86C1, 0x55A0, - 0x86C2, 0x55A1, 0x86C3, 0x55A2, 0x86C4, 0x55A3, 0x86C5, 0x55A4, 0x86C6, 0x55A5, 0x86C7, 0x55A6, 0x86C8, 0x55A8, 0x86C9, 0x55A9, - 0x86CA, 0x55AA, 0x86CB, 0x55AB, 0x86CC, 0x55AC, 0x86CD, 0x55AD, 0x86CE, 0x55AE, 0x86CF, 0x55AF, 0x86D0, 0x55B0, 0x86D1, 0x55B2, - 0x86D2, 0x55B4, 0x86D3, 0x55B6, 0x86D4, 0x55B8, 0x86D5, 0x55BA, 0x86D6, 0x55BC, 0x86D7, 0x55BF, 0x86D8, 0x55C0, 0x86D9, 0x55C1, - 0x86DA, 0x55C2, 0x86DB, 0x55C3, 0x86DC, 0x55C6, 0x86DD, 0x55C7, 0x86DE, 0x55C8, 0x86DF, 0x55CA, 0x86E0, 0x55CB, 0x86E1, 0x55CE, - 0x86E2, 0x55CF, 0x86E3, 0x55D0, 0x86E4, 0x55D5, 0x86E5, 0x55D7, 0x86E6, 0x55D8, 0x86E7, 0x55D9, 0x86E8, 0x55DA, 0x86E9, 0x55DB, - 0x86EA, 0x55DE, 0x86EB, 0x55E0, 0x86EC, 0x55E2, 0x86ED, 0x55E7, 0x86EE, 0x55E9, 0x86EF, 0x55ED, 0x86F0, 0x55EE, 0x86F1, 0x55F0, - 0x86F2, 0x55F1, 0x86F3, 0x55F4, 0x86F4, 0x55F6, 0x86F5, 0x55F8, 0x86F6, 0x55F9, 0x86F7, 0x55FA, 0x86F8, 0x55FB, 0x86F9, 0x55FC, - 0x86FA, 0x55FF, 0x86FB, 0x5602, 0x86FC, 0x5603, 0x86FD, 0x5604, 0x86FE, 0x5605, 0x8740, 0x5606, 0x8741, 0x5607, 0x8742, 0x560A, - 0x8743, 0x560B, 0x8744, 0x560D, 0x8745, 0x5610, 0x8746, 0x5611, 0x8747, 0x5612, 0x8748, 0x5613, 0x8749, 0x5614, 0x874A, 0x5615, - 0x874B, 0x5616, 0x874C, 0x5617, 0x874D, 0x5619, 0x874E, 0x561A, 0x874F, 0x561C, 0x8750, 0x561D, 0x8751, 0x5620, 0x8752, 0x5621, - 0x8753, 0x5622, 0x8754, 0x5625, 0x8755, 0x5626, 0x8756, 0x5628, 0x8757, 0x5629, 0x8758, 0x562A, 0x8759, 0x562B, 0x875A, 0x562E, - 0x875B, 0x562F, 0x875C, 0x5630, 0x875D, 0x5633, 0x875E, 0x5635, 0x875F, 0x5637, 0x8760, 0x5638, 0x8761, 0x563A, 0x8762, 0x563C, - 0x8763, 0x563D, 0x8764, 0x563E, 0x8765, 0x5640, 0x8766, 0x5641, 0x8767, 0x5642, 0x8768, 0x5643, 0x8769, 0x5644, 0x876A, 0x5645, - 0x876B, 0x5646, 0x876C, 0x5647, 0x876D, 0x5648, 0x876E, 0x5649, 0x876F, 0x564A, 0x8770, 0x564B, 0x8771, 0x564F, 0x8772, 0x5650, - 0x8773, 0x5651, 0x8774, 0x5652, 0x8775, 0x5653, 0x8776, 0x5655, 0x8777, 0x5656, 0x8778, 0x565A, 0x8779, 0x565B, 0x877A, 0x565D, - 0x877B, 0x565E, 0x877C, 0x565F, 0x877D, 0x5660, 0x877E, 0x5661, 0x8780, 0x5663, 0x8781, 0x5665, 0x8782, 0x5666, 0x8783, 0x5667, - 0x8784, 0x566D, 0x8785, 0x566E, 0x8786, 0x566F, 0x8787, 0x5670, 0x8788, 0x5672, 0x8789, 0x5673, 0x878A, 0x5674, 0x878B, 0x5675, - 0x878C, 0x5677, 0x878D, 0x5678, 0x878E, 0x5679, 0x878F, 0x567A, 0x8790, 0x567D, 0x8791, 0x567E, 0x8792, 0x567F, 0x8793, 0x5680, - 0x8794, 0x5681, 0x8795, 0x5682, 0x8796, 0x5683, 0x8797, 0x5684, 0x8798, 0x5687, 0x8799, 0x5688, 0x879A, 0x5689, 0x879B, 0x568A, - 0x879C, 0x568B, 0x879D, 0x568C, 0x879E, 0x568D, 0x879F, 0x5690, 0x87A0, 0x5691, 0x87A1, 0x5692, 0x87A2, 0x5694, 0x87A3, 0x5695, - 0x87A4, 0x5696, 0x87A5, 0x5697, 0x87A6, 0x5698, 0x87A7, 0x5699, 0x87A8, 0x569A, 0x87A9, 0x569B, 0x87AA, 0x569C, 0x87AB, 0x569D, - 0x87AC, 0x569E, 0x87AD, 0x569F, 0x87AE, 0x56A0, 0x87AF, 0x56A1, 0x87B0, 0x56A2, 0x87B1, 0x56A4, 0x87B2, 0x56A5, 0x87B3, 0x56A6, - 0x87B4, 0x56A7, 0x87B5, 0x56A8, 0x87B6, 0x56A9, 0x87B7, 0x56AA, 0x87B8, 0x56AB, 0x87B9, 0x56AC, 0x87BA, 0x56AD, 0x87BB, 0x56AE, - 0x87BC, 0x56B0, 0x87BD, 0x56B1, 0x87BE, 0x56B2, 0x87BF, 0x56B3, 0x87C0, 0x56B4, 0x87C1, 0x56B5, 0x87C2, 0x56B6, 0x87C3, 0x56B8, - 0x87C4, 0x56B9, 0x87C5, 0x56BA, 0x87C6, 0x56BB, 0x87C7, 0x56BD, 0x87C8, 0x56BE, 0x87C9, 0x56BF, 0x87CA, 0x56C0, 0x87CB, 0x56C1, - 0x87CC, 0x56C2, 0x87CD, 0x56C3, 0x87CE, 0x56C4, 0x87CF, 0x56C5, 0x87D0, 0x56C6, 0x87D1, 0x56C7, 0x87D2, 0x56C8, 0x87D3, 0x56C9, - 0x87D4, 0x56CB, 0x87D5, 0x56CC, 0x87D6, 0x56CD, 0x87D7, 0x56CE, 0x87D8, 0x56CF, 0x87D9, 0x56D0, 0x87DA, 0x56D1, 0x87DB, 0x56D2, - 0x87DC, 0x56D3, 0x87DD, 0x56D5, 0x87DE, 0x56D6, 0x87DF, 0x56D8, 0x87E0, 0x56D9, 0x87E1, 0x56DC, 0x87E2, 0x56E3, 0x87E3, 0x56E5, - 0x87E4, 0x56E6, 0x87E5, 0x56E7, 0x87E6, 0x56E8, 0x87E7, 0x56E9, 0x87E8, 0x56EA, 0x87E9, 0x56EC, 0x87EA, 0x56EE, 0x87EB, 0x56EF, - 0x87EC, 0x56F2, 0x87ED, 0x56F3, 0x87EE, 0x56F6, 0x87EF, 0x56F7, 0x87F0, 0x56F8, 0x87F1, 0x56FB, 0x87F2, 0x56FC, 0x87F3, 0x5700, - 0x87F4, 0x5701, 0x87F5, 0x5702, 0x87F6, 0x5705, 0x87F7, 0x5707, 0x87F8, 0x570B, 0x87F9, 0x570C, 0x87FA, 0x570D, 0x87FB, 0x570E, - 0x87FC, 0x570F, 0x87FD, 0x5710, 0x87FE, 0x5711, 0x8840, 0x5712, 0x8841, 0x5713, 0x8842, 0x5714, 0x8843, 0x5715, 0x8844, 0x5716, - 0x8845, 0x5717, 0x8846, 0x5718, 0x8847, 0x5719, 0x8848, 0x571A, 0x8849, 0x571B, 0x884A, 0x571D, 0x884B, 0x571E, 0x884C, 0x5720, - 0x884D, 0x5721, 0x884E, 0x5722, 0x884F, 0x5724, 0x8850, 0x5725, 0x8851, 0x5726, 0x8852, 0x5727, 0x8853, 0x572B, 0x8854, 0x5731, - 0x8855, 0x5732, 0x8856, 0x5734, 0x8857, 0x5735, 0x8858, 0x5736, 0x8859, 0x5737, 0x885A, 0x5738, 0x885B, 0x573C, 0x885C, 0x573D, - 0x885D, 0x573F, 0x885E, 0x5741, 0x885F, 0x5743, 0x8860, 0x5744, 0x8861, 0x5745, 0x8862, 0x5746, 0x8863, 0x5748, 0x8864, 0x5749, - 0x8865, 0x574B, 0x8866, 0x5752, 0x8867, 0x5753, 0x8868, 0x5754, 0x8869, 0x5755, 0x886A, 0x5756, 0x886B, 0x5758, 0x886C, 0x5759, - 0x886D, 0x5762, 0x886E, 0x5763, 0x886F, 0x5765, 0x8870, 0x5767, 0x8871, 0x576C, 0x8872, 0x576E, 0x8873, 0x5770, 0x8874, 0x5771, - 0x8875, 0x5772, 0x8876, 0x5774, 0x8877, 0x5775, 0x8878, 0x5778, 0x8879, 0x5779, 0x887A, 0x577A, 0x887B, 0x577D, 0x887C, 0x577E, - 0x887D, 0x577F, 0x887E, 0x5780, 0x8880, 0x5781, 0x8881, 0x5787, 0x8882, 0x5788, 0x8883, 0x5789, 0x8884, 0x578A, 0x8885, 0x578D, - 0x8886, 0x578E, 0x8887, 0x578F, 0x8888, 0x5790, 0x8889, 0x5791, 0x888A, 0x5794, 0x888B, 0x5795, 0x888C, 0x5796, 0x888D, 0x5797, - 0x888E, 0x5798, 0x888F, 0x5799, 0x8890, 0x579A, 0x8891, 0x579C, 0x8892, 0x579D, 0x8893, 0x579E, 0x8894, 0x579F, 0x8895, 0x57A5, - 0x8896, 0x57A8, 0x8897, 0x57AA, 0x8898, 0x57AC, 0x8899, 0x57AF, 0x889A, 0x57B0, 0x889B, 0x57B1, 0x889C, 0x57B3, 0x889D, 0x57B5, - 0x889E, 0x57B6, 0x889F, 0x57B7, 0x88A0, 0x57B9, 0x88A1, 0x57BA, 0x88A2, 0x57BB, 0x88A3, 0x57BC, 0x88A4, 0x57BD, 0x88A5, 0x57BE, - 0x88A6, 0x57BF, 0x88A7, 0x57C0, 0x88A8, 0x57C1, 0x88A9, 0x57C4, 0x88AA, 0x57C5, 0x88AB, 0x57C6, 0x88AC, 0x57C7, 0x88AD, 0x57C8, - 0x88AE, 0x57C9, 0x88AF, 0x57CA, 0x88B0, 0x57CC, 0x88B1, 0x57CD, 0x88B2, 0x57D0, 0x88B3, 0x57D1, 0x88B4, 0x57D3, 0x88B5, 0x57D6, - 0x88B6, 0x57D7, 0x88B7, 0x57DB, 0x88B8, 0x57DC, 0x88B9, 0x57DE, 0x88BA, 0x57E1, 0x88BB, 0x57E2, 0x88BC, 0x57E3, 0x88BD, 0x57E5, - 0x88BE, 0x57E6, 0x88BF, 0x57E7, 0x88C0, 0x57E8, 0x88C1, 0x57E9, 0x88C2, 0x57EA, 0x88C3, 0x57EB, 0x88C4, 0x57EC, 0x88C5, 0x57EE, - 0x88C6, 0x57F0, 0x88C7, 0x57F1, 0x88C8, 0x57F2, 0x88C9, 0x57F3, 0x88CA, 0x57F5, 0x88CB, 0x57F6, 0x88CC, 0x57F7, 0x88CD, 0x57FB, - 0x88CE, 0x57FC, 0x88CF, 0x57FE, 0x88D0, 0x57FF, 0x88D1, 0x5801, 0x88D2, 0x5803, 0x88D3, 0x5804, 0x88D4, 0x5805, 0x88D5, 0x5808, - 0x88D6, 0x5809, 0x88D7, 0x580A, 0x88D8, 0x580C, 0x88D9, 0x580E, 0x88DA, 0x580F, 0x88DB, 0x5810, 0x88DC, 0x5812, 0x88DD, 0x5813, - 0x88DE, 0x5814, 0x88DF, 0x5816, 0x88E0, 0x5817, 0x88E1, 0x5818, 0x88E2, 0x581A, 0x88E3, 0x581B, 0x88E4, 0x581C, 0x88E5, 0x581D, - 0x88E6, 0x581F, 0x88E7, 0x5822, 0x88E8, 0x5823, 0x88E9, 0x5825, 0x88EA, 0x5826, 0x88EB, 0x5827, 0x88EC, 0x5828, 0x88ED, 0x5829, - 0x88EE, 0x582B, 0x88EF, 0x582C, 0x88F0, 0x582D, 0x88F1, 0x582E, 0x88F2, 0x582F, 0x88F3, 0x5831, 0x88F4, 0x5832, 0x88F5, 0x5833, - 0x88F6, 0x5834, 0x88F7, 0x5836, 0x88F8, 0x5837, 0x88F9, 0x5838, 0x88FA, 0x5839, 0x88FB, 0x583A, 0x88FC, 0x583B, 0x88FD, 0x583C, - 0x88FE, 0x583D, 0x8940, 0x583E, 0x8941, 0x583F, 0x8942, 0x5840, 0x8943, 0x5841, 0x8944, 0x5842, 0x8945, 0x5843, 0x8946, 0x5845, - 0x8947, 0x5846, 0x8948, 0x5847, 0x8949, 0x5848, 0x894A, 0x5849, 0x894B, 0x584A, 0x894C, 0x584B, 0x894D, 0x584E, 0x894E, 0x584F, - 0x894F, 0x5850, 0x8950, 0x5852, 0x8951, 0x5853, 0x8952, 0x5855, 0x8953, 0x5856, 0x8954, 0x5857, 0x8955, 0x5859, 0x8956, 0x585A, - 0x8957, 0x585B, 0x8958, 0x585C, 0x8959, 0x585D, 0x895A, 0x585F, 0x895B, 0x5860, 0x895C, 0x5861, 0x895D, 0x5862, 0x895E, 0x5863, - 0x895F, 0x5864, 0x8960, 0x5866, 0x8961, 0x5867, 0x8962, 0x5868, 0x8963, 0x5869, 0x8964, 0x586A, 0x8965, 0x586D, 0x8966, 0x586E, - 0x8967, 0x586F, 0x8968, 0x5870, 0x8969, 0x5871, 0x896A, 0x5872, 0x896B, 0x5873, 0x896C, 0x5874, 0x896D, 0x5875, 0x896E, 0x5876, - 0x896F, 0x5877, 0x8970, 0x5878, 0x8971, 0x5879, 0x8972, 0x587A, 0x8973, 0x587B, 0x8974, 0x587C, 0x8975, 0x587D, 0x8976, 0x587F, - 0x8977, 0x5882, 0x8978, 0x5884, 0x8979, 0x5886, 0x897A, 0x5887, 0x897B, 0x5888, 0x897C, 0x588A, 0x897D, 0x588B, 0x897E, 0x588C, - 0x8980, 0x588D, 0x8981, 0x588E, 0x8982, 0x588F, 0x8983, 0x5890, 0x8984, 0x5891, 0x8985, 0x5894, 0x8986, 0x5895, 0x8987, 0x5896, - 0x8988, 0x5897, 0x8989, 0x5898, 0x898A, 0x589B, 0x898B, 0x589C, 0x898C, 0x589D, 0x898D, 0x58A0, 0x898E, 0x58A1, 0x898F, 0x58A2, - 0x8990, 0x58A3, 0x8991, 0x58A4, 0x8992, 0x58A5, 0x8993, 0x58A6, 0x8994, 0x58A7, 0x8995, 0x58AA, 0x8996, 0x58AB, 0x8997, 0x58AC, - 0x8998, 0x58AD, 0x8999, 0x58AE, 0x899A, 0x58AF, 0x899B, 0x58B0, 0x899C, 0x58B1, 0x899D, 0x58B2, 0x899E, 0x58B3, 0x899F, 0x58B4, - 0x89A0, 0x58B5, 0x89A1, 0x58B6, 0x89A2, 0x58B7, 0x89A3, 0x58B8, 0x89A4, 0x58B9, 0x89A5, 0x58BA, 0x89A6, 0x58BB, 0x89A7, 0x58BD, - 0x89A8, 0x58BE, 0x89A9, 0x58BF, 0x89AA, 0x58C0, 0x89AB, 0x58C2, 0x89AC, 0x58C3, 0x89AD, 0x58C4, 0x89AE, 0x58C6, 0x89AF, 0x58C7, - 0x89B0, 0x58C8, 0x89B1, 0x58C9, 0x89B2, 0x58CA, 0x89B3, 0x58CB, 0x89B4, 0x58CC, 0x89B5, 0x58CD, 0x89B6, 0x58CE, 0x89B7, 0x58CF, - 0x89B8, 0x58D0, 0x89B9, 0x58D2, 0x89BA, 0x58D3, 0x89BB, 0x58D4, 0x89BC, 0x58D6, 0x89BD, 0x58D7, 0x89BE, 0x58D8, 0x89BF, 0x58D9, - 0x89C0, 0x58DA, 0x89C1, 0x58DB, 0x89C2, 0x58DC, 0x89C3, 0x58DD, 0x89C4, 0x58DE, 0x89C5, 0x58DF, 0x89C6, 0x58E0, 0x89C7, 0x58E1, - 0x89C8, 0x58E2, 0x89C9, 0x58E3, 0x89CA, 0x58E5, 0x89CB, 0x58E6, 0x89CC, 0x58E7, 0x89CD, 0x58E8, 0x89CE, 0x58E9, 0x89CF, 0x58EA, - 0x89D0, 0x58ED, 0x89D1, 0x58EF, 0x89D2, 0x58F1, 0x89D3, 0x58F2, 0x89D4, 0x58F4, 0x89D5, 0x58F5, 0x89D6, 0x58F7, 0x89D7, 0x58F8, - 0x89D8, 0x58FA, 0x89D9, 0x58FB, 0x89DA, 0x58FC, 0x89DB, 0x58FD, 0x89DC, 0x58FE, 0x89DD, 0x58FF, 0x89DE, 0x5900, 0x89DF, 0x5901, - 0x89E0, 0x5903, 0x89E1, 0x5905, 0x89E2, 0x5906, 0x89E3, 0x5908, 0x89E4, 0x5909, 0x89E5, 0x590A, 0x89E6, 0x590B, 0x89E7, 0x590C, - 0x89E8, 0x590E, 0x89E9, 0x5910, 0x89EA, 0x5911, 0x89EB, 0x5912, 0x89EC, 0x5913, 0x89ED, 0x5917, 0x89EE, 0x5918, 0x89EF, 0x591B, - 0x89F0, 0x591D, 0x89F1, 0x591E, 0x89F2, 0x5920, 0x89F3, 0x5921, 0x89F4, 0x5922, 0x89F5, 0x5923, 0x89F6, 0x5926, 0x89F7, 0x5928, - 0x89F8, 0x592C, 0x89F9, 0x5930, 0x89FA, 0x5932, 0x89FB, 0x5933, 0x89FC, 0x5935, 0x89FD, 0x5936, 0x89FE, 0x593B, 0x8A40, 0x593D, - 0x8A41, 0x593E, 0x8A42, 0x593F, 0x8A43, 0x5940, 0x8A44, 0x5943, 0x8A45, 0x5945, 0x8A46, 0x5946, 0x8A47, 0x594A, 0x8A48, 0x594C, - 0x8A49, 0x594D, 0x8A4A, 0x5950, 0x8A4B, 0x5952, 0x8A4C, 0x5953, 0x8A4D, 0x5959, 0x8A4E, 0x595B, 0x8A4F, 0x595C, 0x8A50, 0x595D, - 0x8A51, 0x595E, 0x8A52, 0x595F, 0x8A53, 0x5961, 0x8A54, 0x5963, 0x8A55, 0x5964, 0x8A56, 0x5966, 0x8A57, 0x5967, 0x8A58, 0x5968, - 0x8A59, 0x5969, 0x8A5A, 0x596A, 0x8A5B, 0x596B, 0x8A5C, 0x596C, 0x8A5D, 0x596D, 0x8A5E, 0x596E, 0x8A5F, 0x596F, 0x8A60, 0x5970, - 0x8A61, 0x5971, 0x8A62, 0x5972, 0x8A63, 0x5975, 0x8A64, 0x5977, 0x8A65, 0x597A, 0x8A66, 0x597B, 0x8A67, 0x597C, 0x8A68, 0x597E, - 0x8A69, 0x597F, 0x8A6A, 0x5980, 0x8A6B, 0x5985, 0x8A6C, 0x5989, 0x8A6D, 0x598B, 0x8A6E, 0x598C, 0x8A6F, 0x598E, 0x8A70, 0x598F, - 0x8A71, 0x5990, 0x8A72, 0x5991, 0x8A73, 0x5994, 0x8A74, 0x5995, 0x8A75, 0x5998, 0x8A76, 0x599A, 0x8A77, 0x599B, 0x8A78, 0x599C, - 0x8A79, 0x599D, 0x8A7A, 0x599F, 0x8A7B, 0x59A0, 0x8A7C, 0x59A1, 0x8A7D, 0x59A2, 0x8A7E, 0x59A6, 0x8A80, 0x59A7, 0x8A81, 0x59AC, - 0x8A82, 0x59AD, 0x8A83, 0x59B0, 0x8A84, 0x59B1, 0x8A85, 0x59B3, 0x8A86, 0x59B4, 0x8A87, 0x59B5, 0x8A88, 0x59B6, 0x8A89, 0x59B7, - 0x8A8A, 0x59B8, 0x8A8B, 0x59BA, 0x8A8C, 0x59BC, 0x8A8D, 0x59BD, 0x8A8E, 0x59BF, 0x8A8F, 0x59C0, 0x8A90, 0x59C1, 0x8A91, 0x59C2, - 0x8A92, 0x59C3, 0x8A93, 0x59C4, 0x8A94, 0x59C5, 0x8A95, 0x59C7, 0x8A96, 0x59C8, 0x8A97, 0x59C9, 0x8A98, 0x59CC, 0x8A99, 0x59CD, - 0x8A9A, 0x59CE, 0x8A9B, 0x59CF, 0x8A9C, 0x59D5, 0x8A9D, 0x59D6, 0x8A9E, 0x59D9, 0x8A9F, 0x59DB, 0x8AA0, 0x59DE, 0x8AA1, 0x59DF, - 0x8AA2, 0x59E0, 0x8AA3, 0x59E1, 0x8AA4, 0x59E2, 0x8AA5, 0x59E4, 0x8AA6, 0x59E6, 0x8AA7, 0x59E7, 0x8AA8, 0x59E9, 0x8AA9, 0x59EA, - 0x8AAA, 0x59EB, 0x8AAB, 0x59ED, 0x8AAC, 0x59EE, 0x8AAD, 0x59EF, 0x8AAE, 0x59F0, 0x8AAF, 0x59F1, 0x8AB0, 0x59F2, 0x8AB1, 0x59F3, - 0x8AB2, 0x59F4, 0x8AB3, 0x59F5, 0x8AB4, 0x59F6, 0x8AB5, 0x59F7, 0x8AB6, 0x59F8, 0x8AB7, 0x59FA, 0x8AB8, 0x59FC, 0x8AB9, 0x59FD, - 0x8ABA, 0x59FE, 0x8ABB, 0x5A00, 0x8ABC, 0x5A02, 0x8ABD, 0x5A0A, 0x8ABE, 0x5A0B, 0x8ABF, 0x5A0D, 0x8AC0, 0x5A0E, 0x8AC1, 0x5A0F, - 0x8AC2, 0x5A10, 0x8AC3, 0x5A12, 0x8AC4, 0x5A14, 0x8AC5, 0x5A15, 0x8AC6, 0x5A16, 0x8AC7, 0x5A17, 0x8AC8, 0x5A19, 0x8AC9, 0x5A1A, - 0x8ACA, 0x5A1B, 0x8ACB, 0x5A1D, 0x8ACC, 0x5A1E, 0x8ACD, 0x5A21, 0x8ACE, 0x5A22, 0x8ACF, 0x5A24, 0x8AD0, 0x5A26, 0x8AD1, 0x5A27, - 0x8AD2, 0x5A28, 0x8AD3, 0x5A2A, 0x8AD4, 0x5A2B, 0x8AD5, 0x5A2C, 0x8AD6, 0x5A2D, 0x8AD7, 0x5A2E, 0x8AD8, 0x5A2F, 0x8AD9, 0x5A30, - 0x8ADA, 0x5A33, 0x8ADB, 0x5A35, 0x8ADC, 0x5A37, 0x8ADD, 0x5A38, 0x8ADE, 0x5A39, 0x8ADF, 0x5A3A, 0x8AE0, 0x5A3B, 0x8AE1, 0x5A3D, - 0x8AE2, 0x5A3E, 0x8AE3, 0x5A3F, 0x8AE4, 0x5A41, 0x8AE5, 0x5A42, 0x8AE6, 0x5A43, 0x8AE7, 0x5A44, 0x8AE8, 0x5A45, 0x8AE9, 0x5A47, - 0x8AEA, 0x5A48, 0x8AEB, 0x5A4B, 0x8AEC, 0x5A4C, 0x8AED, 0x5A4D, 0x8AEE, 0x5A4E, 0x8AEF, 0x5A4F, 0x8AF0, 0x5A50, 0x8AF1, 0x5A51, - 0x8AF2, 0x5A52, 0x8AF3, 0x5A53, 0x8AF4, 0x5A54, 0x8AF5, 0x5A56, 0x8AF6, 0x5A57, 0x8AF7, 0x5A58, 0x8AF8, 0x5A59, 0x8AF9, 0x5A5B, - 0x8AFA, 0x5A5C, 0x8AFB, 0x5A5D, 0x8AFC, 0x5A5E, 0x8AFD, 0x5A5F, 0x8AFE, 0x5A60, 0x8B40, 0x5A61, 0x8B41, 0x5A63, 0x8B42, 0x5A64, - 0x8B43, 0x5A65, 0x8B44, 0x5A66, 0x8B45, 0x5A68, 0x8B46, 0x5A69, 0x8B47, 0x5A6B, 0x8B48, 0x5A6C, 0x8B49, 0x5A6D, 0x8B4A, 0x5A6E, - 0x8B4B, 0x5A6F, 0x8B4C, 0x5A70, 0x8B4D, 0x5A71, 0x8B4E, 0x5A72, 0x8B4F, 0x5A73, 0x8B50, 0x5A78, 0x8B51, 0x5A79, 0x8B52, 0x5A7B, - 0x8B53, 0x5A7C, 0x8B54, 0x5A7D, 0x8B55, 0x5A7E, 0x8B56, 0x5A80, 0x8B57, 0x5A81, 0x8B58, 0x5A82, 0x8B59, 0x5A83, 0x8B5A, 0x5A84, - 0x8B5B, 0x5A85, 0x8B5C, 0x5A86, 0x8B5D, 0x5A87, 0x8B5E, 0x5A88, 0x8B5F, 0x5A89, 0x8B60, 0x5A8A, 0x8B61, 0x5A8B, 0x8B62, 0x5A8C, - 0x8B63, 0x5A8D, 0x8B64, 0x5A8E, 0x8B65, 0x5A8F, 0x8B66, 0x5A90, 0x8B67, 0x5A91, 0x8B68, 0x5A93, 0x8B69, 0x5A94, 0x8B6A, 0x5A95, - 0x8B6B, 0x5A96, 0x8B6C, 0x5A97, 0x8B6D, 0x5A98, 0x8B6E, 0x5A99, 0x8B6F, 0x5A9C, 0x8B70, 0x5A9D, 0x8B71, 0x5A9E, 0x8B72, 0x5A9F, - 0x8B73, 0x5AA0, 0x8B74, 0x5AA1, 0x8B75, 0x5AA2, 0x8B76, 0x5AA3, 0x8B77, 0x5AA4, 0x8B78, 0x5AA5, 0x8B79, 0x5AA6, 0x8B7A, 0x5AA7, - 0x8B7B, 0x5AA8, 0x8B7C, 0x5AA9, 0x8B7D, 0x5AAB, 0x8B7E, 0x5AAC, 0x8B80, 0x5AAD, 0x8B81, 0x5AAE, 0x8B82, 0x5AAF, 0x8B83, 0x5AB0, - 0x8B84, 0x5AB1, 0x8B85, 0x5AB4, 0x8B86, 0x5AB6, 0x8B87, 0x5AB7, 0x8B88, 0x5AB9, 0x8B89, 0x5ABA, 0x8B8A, 0x5ABB, 0x8B8B, 0x5ABC, - 0x8B8C, 0x5ABD, 0x8B8D, 0x5ABF, 0x8B8E, 0x5AC0, 0x8B8F, 0x5AC3, 0x8B90, 0x5AC4, 0x8B91, 0x5AC5, 0x8B92, 0x5AC6, 0x8B93, 0x5AC7, - 0x8B94, 0x5AC8, 0x8B95, 0x5ACA, 0x8B96, 0x5ACB, 0x8B97, 0x5ACD, 0x8B98, 0x5ACE, 0x8B99, 0x5ACF, 0x8B9A, 0x5AD0, 0x8B9B, 0x5AD1, - 0x8B9C, 0x5AD3, 0x8B9D, 0x5AD5, 0x8B9E, 0x5AD7, 0x8B9F, 0x5AD9, 0x8BA0, 0x5ADA, 0x8BA1, 0x5ADB, 0x8BA2, 0x5ADD, 0x8BA3, 0x5ADE, - 0x8BA4, 0x5ADF, 0x8BA5, 0x5AE2, 0x8BA6, 0x5AE4, 0x8BA7, 0x5AE5, 0x8BA8, 0x5AE7, 0x8BA9, 0x5AE8, 0x8BAA, 0x5AEA, 0x8BAB, 0x5AEC, - 0x8BAC, 0x5AED, 0x8BAD, 0x5AEE, 0x8BAE, 0x5AEF, 0x8BAF, 0x5AF0, 0x8BB0, 0x5AF2, 0x8BB1, 0x5AF3, 0x8BB2, 0x5AF4, 0x8BB3, 0x5AF5, - 0x8BB4, 0x5AF6, 0x8BB5, 0x5AF7, 0x8BB6, 0x5AF8, 0x8BB7, 0x5AF9, 0x8BB8, 0x5AFA, 0x8BB9, 0x5AFB, 0x8BBA, 0x5AFC, 0x8BBB, 0x5AFD, - 0x8BBC, 0x5AFE, 0x8BBD, 0x5AFF, 0x8BBE, 0x5B00, 0x8BBF, 0x5B01, 0x8BC0, 0x5B02, 0x8BC1, 0x5B03, 0x8BC2, 0x5B04, 0x8BC3, 0x5B05, - 0x8BC4, 0x5B06, 0x8BC5, 0x5B07, 0x8BC6, 0x5B08, 0x8BC7, 0x5B0A, 0x8BC8, 0x5B0B, 0x8BC9, 0x5B0C, 0x8BCA, 0x5B0D, 0x8BCB, 0x5B0E, - 0x8BCC, 0x5B0F, 0x8BCD, 0x5B10, 0x8BCE, 0x5B11, 0x8BCF, 0x5B12, 0x8BD0, 0x5B13, 0x8BD1, 0x5B14, 0x8BD2, 0x5B15, 0x8BD3, 0x5B18, - 0x8BD4, 0x5B19, 0x8BD5, 0x5B1A, 0x8BD6, 0x5B1B, 0x8BD7, 0x5B1C, 0x8BD8, 0x5B1D, 0x8BD9, 0x5B1E, 0x8BDA, 0x5B1F, 0x8BDB, 0x5B20, - 0x8BDC, 0x5B21, 0x8BDD, 0x5B22, 0x8BDE, 0x5B23, 0x8BDF, 0x5B24, 0x8BE0, 0x5B25, 0x8BE1, 0x5B26, 0x8BE2, 0x5B27, 0x8BE3, 0x5B28, - 0x8BE4, 0x5B29, 0x8BE5, 0x5B2A, 0x8BE6, 0x5B2B, 0x8BE7, 0x5B2C, 0x8BE8, 0x5B2D, 0x8BE9, 0x5B2E, 0x8BEA, 0x5B2F, 0x8BEB, 0x5B30, - 0x8BEC, 0x5B31, 0x8BED, 0x5B33, 0x8BEE, 0x5B35, 0x8BEF, 0x5B36, 0x8BF0, 0x5B38, 0x8BF1, 0x5B39, 0x8BF2, 0x5B3A, 0x8BF3, 0x5B3B, - 0x8BF4, 0x5B3C, 0x8BF5, 0x5B3D, 0x8BF6, 0x5B3E, 0x8BF7, 0x5B3F, 0x8BF8, 0x5B41, 0x8BF9, 0x5B42, 0x8BFA, 0x5B43, 0x8BFB, 0x5B44, - 0x8BFC, 0x5B45, 0x8BFD, 0x5B46, 0x8BFE, 0x5B47, 0x8C40, 0x5B48, 0x8C41, 0x5B49, 0x8C42, 0x5B4A, 0x8C43, 0x5B4B, 0x8C44, 0x5B4C, - 0x8C45, 0x5B4D, 0x8C46, 0x5B4E, 0x8C47, 0x5B4F, 0x8C48, 0x5B52, 0x8C49, 0x5B56, 0x8C4A, 0x5B5E, 0x8C4B, 0x5B60, 0x8C4C, 0x5B61, - 0x8C4D, 0x5B67, 0x8C4E, 0x5B68, 0x8C4F, 0x5B6B, 0x8C50, 0x5B6D, 0x8C51, 0x5B6E, 0x8C52, 0x5B6F, 0x8C53, 0x5B72, 0x8C54, 0x5B74, - 0x8C55, 0x5B76, 0x8C56, 0x5B77, 0x8C57, 0x5B78, 0x8C58, 0x5B79, 0x8C59, 0x5B7B, 0x8C5A, 0x5B7C, 0x8C5B, 0x5B7E, 0x8C5C, 0x5B7F, - 0x8C5D, 0x5B82, 0x8C5E, 0x5B86, 0x8C5F, 0x5B8A, 0x8C60, 0x5B8D, 0x8C61, 0x5B8E, 0x8C62, 0x5B90, 0x8C63, 0x5B91, 0x8C64, 0x5B92, - 0x8C65, 0x5B94, 0x8C66, 0x5B96, 0x8C67, 0x5B9F, 0x8C68, 0x5BA7, 0x8C69, 0x5BA8, 0x8C6A, 0x5BA9, 0x8C6B, 0x5BAC, 0x8C6C, 0x5BAD, - 0x8C6D, 0x5BAE, 0x8C6E, 0x5BAF, 0x8C6F, 0x5BB1, 0x8C70, 0x5BB2, 0x8C71, 0x5BB7, 0x8C72, 0x5BBA, 0x8C73, 0x5BBB, 0x8C74, 0x5BBC, - 0x8C75, 0x5BC0, 0x8C76, 0x5BC1, 0x8C77, 0x5BC3, 0x8C78, 0x5BC8, 0x8C79, 0x5BC9, 0x8C7A, 0x5BCA, 0x8C7B, 0x5BCB, 0x8C7C, 0x5BCD, - 0x8C7D, 0x5BCE, 0x8C7E, 0x5BCF, 0x8C80, 0x5BD1, 0x8C81, 0x5BD4, 0x8C82, 0x5BD5, 0x8C83, 0x5BD6, 0x8C84, 0x5BD7, 0x8C85, 0x5BD8, - 0x8C86, 0x5BD9, 0x8C87, 0x5BDA, 0x8C88, 0x5BDB, 0x8C89, 0x5BDC, 0x8C8A, 0x5BE0, 0x8C8B, 0x5BE2, 0x8C8C, 0x5BE3, 0x8C8D, 0x5BE6, - 0x8C8E, 0x5BE7, 0x8C8F, 0x5BE9, 0x8C90, 0x5BEA, 0x8C91, 0x5BEB, 0x8C92, 0x5BEC, 0x8C93, 0x5BED, 0x8C94, 0x5BEF, 0x8C95, 0x5BF1, - 0x8C96, 0x5BF2, 0x8C97, 0x5BF3, 0x8C98, 0x5BF4, 0x8C99, 0x5BF5, 0x8C9A, 0x5BF6, 0x8C9B, 0x5BF7, 0x8C9C, 0x5BFD, 0x8C9D, 0x5BFE, - 0x8C9E, 0x5C00, 0x8C9F, 0x5C02, 0x8CA0, 0x5C03, 0x8CA1, 0x5C05, 0x8CA2, 0x5C07, 0x8CA3, 0x5C08, 0x8CA4, 0x5C0B, 0x8CA5, 0x5C0C, - 0x8CA6, 0x5C0D, 0x8CA7, 0x5C0E, 0x8CA8, 0x5C10, 0x8CA9, 0x5C12, 0x8CAA, 0x5C13, 0x8CAB, 0x5C17, 0x8CAC, 0x5C19, 0x8CAD, 0x5C1B, - 0x8CAE, 0x5C1E, 0x8CAF, 0x5C1F, 0x8CB0, 0x5C20, 0x8CB1, 0x5C21, 0x8CB2, 0x5C23, 0x8CB3, 0x5C26, 0x8CB4, 0x5C28, 0x8CB5, 0x5C29, - 0x8CB6, 0x5C2A, 0x8CB7, 0x5C2B, 0x8CB8, 0x5C2D, 0x8CB9, 0x5C2E, 0x8CBA, 0x5C2F, 0x8CBB, 0x5C30, 0x8CBC, 0x5C32, 0x8CBD, 0x5C33, - 0x8CBE, 0x5C35, 0x8CBF, 0x5C36, 0x8CC0, 0x5C37, 0x8CC1, 0x5C43, 0x8CC2, 0x5C44, 0x8CC3, 0x5C46, 0x8CC4, 0x5C47, 0x8CC5, 0x5C4C, - 0x8CC6, 0x5C4D, 0x8CC7, 0x5C52, 0x8CC8, 0x5C53, 0x8CC9, 0x5C54, 0x8CCA, 0x5C56, 0x8CCB, 0x5C57, 0x8CCC, 0x5C58, 0x8CCD, 0x5C5A, - 0x8CCE, 0x5C5B, 0x8CCF, 0x5C5C, 0x8CD0, 0x5C5D, 0x8CD1, 0x5C5F, 0x8CD2, 0x5C62, 0x8CD3, 0x5C64, 0x8CD4, 0x5C67, 0x8CD5, 0x5C68, - 0x8CD6, 0x5C69, 0x8CD7, 0x5C6A, 0x8CD8, 0x5C6B, 0x8CD9, 0x5C6C, 0x8CDA, 0x5C6D, 0x8CDB, 0x5C70, 0x8CDC, 0x5C72, 0x8CDD, 0x5C73, - 0x8CDE, 0x5C74, 0x8CDF, 0x5C75, 0x8CE0, 0x5C76, 0x8CE1, 0x5C77, 0x8CE2, 0x5C78, 0x8CE3, 0x5C7B, 0x8CE4, 0x5C7C, 0x8CE5, 0x5C7D, - 0x8CE6, 0x5C7E, 0x8CE7, 0x5C80, 0x8CE8, 0x5C83, 0x8CE9, 0x5C84, 0x8CEA, 0x5C85, 0x8CEB, 0x5C86, 0x8CEC, 0x5C87, 0x8CED, 0x5C89, - 0x8CEE, 0x5C8A, 0x8CEF, 0x5C8B, 0x8CF0, 0x5C8E, 0x8CF1, 0x5C8F, 0x8CF2, 0x5C92, 0x8CF3, 0x5C93, 0x8CF4, 0x5C95, 0x8CF5, 0x5C9D, - 0x8CF6, 0x5C9E, 0x8CF7, 0x5C9F, 0x8CF8, 0x5CA0, 0x8CF9, 0x5CA1, 0x8CFA, 0x5CA4, 0x8CFB, 0x5CA5, 0x8CFC, 0x5CA6, 0x8CFD, 0x5CA7, - 0x8CFE, 0x5CA8, 0x8D40, 0x5CAA, 0x8D41, 0x5CAE, 0x8D42, 0x5CAF, 0x8D43, 0x5CB0, 0x8D44, 0x5CB2, 0x8D45, 0x5CB4, 0x8D46, 0x5CB6, - 0x8D47, 0x5CB9, 0x8D48, 0x5CBA, 0x8D49, 0x5CBB, 0x8D4A, 0x5CBC, 0x8D4B, 0x5CBE, 0x8D4C, 0x5CC0, 0x8D4D, 0x5CC2, 0x8D4E, 0x5CC3, - 0x8D4F, 0x5CC5, 0x8D50, 0x5CC6, 0x8D51, 0x5CC7, 0x8D52, 0x5CC8, 0x8D53, 0x5CC9, 0x8D54, 0x5CCA, 0x8D55, 0x5CCC, 0x8D56, 0x5CCD, - 0x8D57, 0x5CCE, 0x8D58, 0x5CCF, 0x8D59, 0x5CD0, 0x8D5A, 0x5CD1, 0x8D5B, 0x5CD3, 0x8D5C, 0x5CD4, 0x8D5D, 0x5CD5, 0x8D5E, 0x5CD6, - 0x8D5F, 0x5CD7, 0x8D60, 0x5CD8, 0x8D61, 0x5CDA, 0x8D62, 0x5CDB, 0x8D63, 0x5CDC, 0x8D64, 0x5CDD, 0x8D65, 0x5CDE, 0x8D66, 0x5CDF, - 0x8D67, 0x5CE0, 0x8D68, 0x5CE2, 0x8D69, 0x5CE3, 0x8D6A, 0x5CE7, 0x8D6B, 0x5CE9, 0x8D6C, 0x5CEB, 0x8D6D, 0x5CEC, 0x8D6E, 0x5CEE, - 0x8D6F, 0x5CEF, 0x8D70, 0x5CF1, 0x8D71, 0x5CF2, 0x8D72, 0x5CF3, 0x8D73, 0x5CF4, 0x8D74, 0x5CF5, 0x8D75, 0x5CF6, 0x8D76, 0x5CF7, - 0x8D77, 0x5CF8, 0x8D78, 0x5CF9, 0x8D79, 0x5CFA, 0x8D7A, 0x5CFC, 0x8D7B, 0x5CFD, 0x8D7C, 0x5CFE, 0x8D7D, 0x5CFF, 0x8D7E, 0x5D00, - 0x8D80, 0x5D01, 0x8D81, 0x5D04, 0x8D82, 0x5D05, 0x8D83, 0x5D08, 0x8D84, 0x5D09, 0x8D85, 0x5D0A, 0x8D86, 0x5D0B, 0x8D87, 0x5D0C, - 0x8D88, 0x5D0D, 0x8D89, 0x5D0F, 0x8D8A, 0x5D10, 0x8D8B, 0x5D11, 0x8D8C, 0x5D12, 0x8D8D, 0x5D13, 0x8D8E, 0x5D15, 0x8D8F, 0x5D17, - 0x8D90, 0x5D18, 0x8D91, 0x5D19, 0x8D92, 0x5D1A, 0x8D93, 0x5D1C, 0x8D94, 0x5D1D, 0x8D95, 0x5D1F, 0x8D96, 0x5D20, 0x8D97, 0x5D21, - 0x8D98, 0x5D22, 0x8D99, 0x5D23, 0x8D9A, 0x5D25, 0x8D9B, 0x5D28, 0x8D9C, 0x5D2A, 0x8D9D, 0x5D2B, 0x8D9E, 0x5D2C, 0x8D9F, 0x5D2F, - 0x8DA0, 0x5D30, 0x8DA1, 0x5D31, 0x8DA2, 0x5D32, 0x8DA3, 0x5D33, 0x8DA4, 0x5D35, 0x8DA5, 0x5D36, 0x8DA6, 0x5D37, 0x8DA7, 0x5D38, - 0x8DA8, 0x5D39, 0x8DA9, 0x5D3A, 0x8DAA, 0x5D3B, 0x8DAB, 0x5D3C, 0x8DAC, 0x5D3F, 0x8DAD, 0x5D40, 0x8DAE, 0x5D41, 0x8DAF, 0x5D42, - 0x8DB0, 0x5D43, 0x8DB1, 0x5D44, 0x8DB2, 0x5D45, 0x8DB3, 0x5D46, 0x8DB4, 0x5D48, 0x8DB5, 0x5D49, 0x8DB6, 0x5D4D, 0x8DB7, 0x5D4E, - 0x8DB8, 0x5D4F, 0x8DB9, 0x5D50, 0x8DBA, 0x5D51, 0x8DBB, 0x5D52, 0x8DBC, 0x5D53, 0x8DBD, 0x5D54, 0x8DBE, 0x5D55, 0x8DBF, 0x5D56, - 0x8DC0, 0x5D57, 0x8DC1, 0x5D59, 0x8DC2, 0x5D5A, 0x8DC3, 0x5D5C, 0x8DC4, 0x5D5E, 0x8DC5, 0x5D5F, 0x8DC6, 0x5D60, 0x8DC7, 0x5D61, - 0x8DC8, 0x5D62, 0x8DC9, 0x5D63, 0x8DCA, 0x5D64, 0x8DCB, 0x5D65, 0x8DCC, 0x5D66, 0x8DCD, 0x5D67, 0x8DCE, 0x5D68, 0x8DCF, 0x5D6A, - 0x8DD0, 0x5D6D, 0x8DD1, 0x5D6E, 0x8DD2, 0x5D70, 0x8DD3, 0x5D71, 0x8DD4, 0x5D72, 0x8DD5, 0x5D73, 0x8DD6, 0x5D75, 0x8DD7, 0x5D76, - 0x8DD8, 0x5D77, 0x8DD9, 0x5D78, 0x8DDA, 0x5D79, 0x8DDB, 0x5D7A, 0x8DDC, 0x5D7B, 0x8DDD, 0x5D7C, 0x8DDE, 0x5D7D, 0x8DDF, 0x5D7E, - 0x8DE0, 0x5D7F, 0x8DE1, 0x5D80, 0x8DE2, 0x5D81, 0x8DE3, 0x5D83, 0x8DE4, 0x5D84, 0x8DE5, 0x5D85, 0x8DE6, 0x5D86, 0x8DE7, 0x5D87, - 0x8DE8, 0x5D88, 0x8DE9, 0x5D89, 0x8DEA, 0x5D8A, 0x8DEB, 0x5D8B, 0x8DEC, 0x5D8C, 0x8DED, 0x5D8D, 0x8DEE, 0x5D8E, 0x8DEF, 0x5D8F, - 0x8DF0, 0x5D90, 0x8DF1, 0x5D91, 0x8DF2, 0x5D92, 0x8DF3, 0x5D93, 0x8DF4, 0x5D94, 0x8DF5, 0x5D95, 0x8DF6, 0x5D96, 0x8DF7, 0x5D97, - 0x8DF8, 0x5D98, 0x8DF9, 0x5D9A, 0x8DFA, 0x5D9B, 0x8DFB, 0x5D9C, 0x8DFC, 0x5D9E, 0x8DFD, 0x5D9F, 0x8DFE, 0x5DA0, 0x8E40, 0x5DA1, - 0x8E41, 0x5DA2, 0x8E42, 0x5DA3, 0x8E43, 0x5DA4, 0x8E44, 0x5DA5, 0x8E45, 0x5DA6, 0x8E46, 0x5DA7, 0x8E47, 0x5DA8, 0x8E48, 0x5DA9, - 0x8E49, 0x5DAA, 0x8E4A, 0x5DAB, 0x8E4B, 0x5DAC, 0x8E4C, 0x5DAD, 0x8E4D, 0x5DAE, 0x8E4E, 0x5DAF, 0x8E4F, 0x5DB0, 0x8E50, 0x5DB1, - 0x8E51, 0x5DB2, 0x8E52, 0x5DB3, 0x8E53, 0x5DB4, 0x8E54, 0x5DB5, 0x8E55, 0x5DB6, 0x8E56, 0x5DB8, 0x8E57, 0x5DB9, 0x8E58, 0x5DBA, - 0x8E59, 0x5DBB, 0x8E5A, 0x5DBC, 0x8E5B, 0x5DBD, 0x8E5C, 0x5DBE, 0x8E5D, 0x5DBF, 0x8E5E, 0x5DC0, 0x8E5F, 0x5DC1, 0x8E60, 0x5DC2, - 0x8E61, 0x5DC3, 0x8E62, 0x5DC4, 0x8E63, 0x5DC6, 0x8E64, 0x5DC7, 0x8E65, 0x5DC8, 0x8E66, 0x5DC9, 0x8E67, 0x5DCA, 0x8E68, 0x5DCB, - 0x8E69, 0x5DCC, 0x8E6A, 0x5DCE, 0x8E6B, 0x5DCF, 0x8E6C, 0x5DD0, 0x8E6D, 0x5DD1, 0x8E6E, 0x5DD2, 0x8E6F, 0x5DD3, 0x8E70, 0x5DD4, - 0x8E71, 0x5DD5, 0x8E72, 0x5DD6, 0x8E73, 0x5DD7, 0x8E74, 0x5DD8, 0x8E75, 0x5DD9, 0x8E76, 0x5DDA, 0x8E77, 0x5DDC, 0x8E78, 0x5DDF, - 0x8E79, 0x5DE0, 0x8E7A, 0x5DE3, 0x8E7B, 0x5DE4, 0x8E7C, 0x5DEA, 0x8E7D, 0x5DEC, 0x8E7E, 0x5DED, 0x8E80, 0x5DF0, 0x8E81, 0x5DF5, - 0x8E82, 0x5DF6, 0x8E83, 0x5DF8, 0x8E84, 0x5DF9, 0x8E85, 0x5DFA, 0x8E86, 0x5DFB, 0x8E87, 0x5DFC, 0x8E88, 0x5DFF, 0x8E89, 0x5E00, - 0x8E8A, 0x5E04, 0x8E8B, 0x5E07, 0x8E8C, 0x5E09, 0x8E8D, 0x5E0A, 0x8E8E, 0x5E0B, 0x8E8F, 0x5E0D, 0x8E90, 0x5E0E, 0x8E91, 0x5E12, - 0x8E92, 0x5E13, 0x8E93, 0x5E17, 0x8E94, 0x5E1E, 0x8E95, 0x5E1F, 0x8E96, 0x5E20, 0x8E97, 0x5E21, 0x8E98, 0x5E22, 0x8E99, 0x5E23, - 0x8E9A, 0x5E24, 0x8E9B, 0x5E25, 0x8E9C, 0x5E28, 0x8E9D, 0x5E29, 0x8E9E, 0x5E2A, 0x8E9F, 0x5E2B, 0x8EA0, 0x5E2C, 0x8EA1, 0x5E2F, - 0x8EA2, 0x5E30, 0x8EA3, 0x5E32, 0x8EA4, 0x5E33, 0x8EA5, 0x5E34, 0x8EA6, 0x5E35, 0x8EA7, 0x5E36, 0x8EA8, 0x5E39, 0x8EA9, 0x5E3A, - 0x8EAA, 0x5E3E, 0x8EAB, 0x5E3F, 0x8EAC, 0x5E40, 0x8EAD, 0x5E41, 0x8EAE, 0x5E43, 0x8EAF, 0x5E46, 0x8EB0, 0x5E47, 0x8EB1, 0x5E48, - 0x8EB2, 0x5E49, 0x8EB3, 0x5E4A, 0x8EB4, 0x5E4B, 0x8EB5, 0x5E4D, 0x8EB6, 0x5E4E, 0x8EB7, 0x5E4F, 0x8EB8, 0x5E50, 0x8EB9, 0x5E51, - 0x8EBA, 0x5E52, 0x8EBB, 0x5E53, 0x8EBC, 0x5E56, 0x8EBD, 0x5E57, 0x8EBE, 0x5E58, 0x8EBF, 0x5E59, 0x8EC0, 0x5E5A, 0x8EC1, 0x5E5C, - 0x8EC2, 0x5E5D, 0x8EC3, 0x5E5F, 0x8EC4, 0x5E60, 0x8EC5, 0x5E63, 0x8EC6, 0x5E64, 0x8EC7, 0x5E65, 0x8EC8, 0x5E66, 0x8EC9, 0x5E67, - 0x8ECA, 0x5E68, 0x8ECB, 0x5E69, 0x8ECC, 0x5E6A, 0x8ECD, 0x5E6B, 0x8ECE, 0x5E6C, 0x8ECF, 0x5E6D, 0x8ED0, 0x5E6E, 0x8ED1, 0x5E6F, - 0x8ED2, 0x5E70, 0x8ED3, 0x5E71, 0x8ED4, 0x5E75, 0x8ED5, 0x5E77, 0x8ED6, 0x5E79, 0x8ED7, 0x5E7E, 0x8ED8, 0x5E81, 0x8ED9, 0x5E82, - 0x8EDA, 0x5E83, 0x8EDB, 0x5E85, 0x8EDC, 0x5E88, 0x8EDD, 0x5E89, 0x8EDE, 0x5E8C, 0x8EDF, 0x5E8D, 0x8EE0, 0x5E8E, 0x8EE1, 0x5E92, - 0x8EE2, 0x5E98, 0x8EE3, 0x5E9B, 0x8EE4, 0x5E9D, 0x8EE5, 0x5EA1, 0x8EE6, 0x5EA2, 0x8EE7, 0x5EA3, 0x8EE8, 0x5EA4, 0x8EE9, 0x5EA8, - 0x8EEA, 0x5EA9, 0x8EEB, 0x5EAA, 0x8EEC, 0x5EAB, 0x8EED, 0x5EAC, 0x8EEE, 0x5EAE, 0x8EEF, 0x5EAF, 0x8EF0, 0x5EB0, 0x8EF1, 0x5EB1, - 0x8EF2, 0x5EB2, 0x8EF3, 0x5EB4, 0x8EF4, 0x5EBA, 0x8EF5, 0x5EBB, 0x8EF6, 0x5EBC, 0x8EF7, 0x5EBD, 0x8EF8, 0x5EBF, 0x8EF9, 0x5EC0, - 0x8EFA, 0x5EC1, 0x8EFB, 0x5EC2, 0x8EFC, 0x5EC3, 0x8EFD, 0x5EC4, 0x8EFE, 0x5EC5, 0x8F40, 0x5EC6, 0x8F41, 0x5EC7, 0x8F42, 0x5EC8, - 0x8F43, 0x5ECB, 0x8F44, 0x5ECC, 0x8F45, 0x5ECD, 0x8F46, 0x5ECE, 0x8F47, 0x5ECF, 0x8F48, 0x5ED0, 0x8F49, 0x5ED4, 0x8F4A, 0x5ED5, - 0x8F4B, 0x5ED7, 0x8F4C, 0x5ED8, 0x8F4D, 0x5ED9, 0x8F4E, 0x5EDA, 0x8F4F, 0x5EDC, 0x8F50, 0x5EDD, 0x8F51, 0x5EDE, 0x8F52, 0x5EDF, - 0x8F53, 0x5EE0, 0x8F54, 0x5EE1, 0x8F55, 0x5EE2, 0x8F56, 0x5EE3, 0x8F57, 0x5EE4, 0x8F58, 0x5EE5, 0x8F59, 0x5EE6, 0x8F5A, 0x5EE7, - 0x8F5B, 0x5EE9, 0x8F5C, 0x5EEB, 0x8F5D, 0x5EEC, 0x8F5E, 0x5EED, 0x8F5F, 0x5EEE, 0x8F60, 0x5EEF, 0x8F61, 0x5EF0, 0x8F62, 0x5EF1, - 0x8F63, 0x5EF2, 0x8F64, 0x5EF3, 0x8F65, 0x5EF5, 0x8F66, 0x5EF8, 0x8F67, 0x5EF9, 0x8F68, 0x5EFB, 0x8F69, 0x5EFC, 0x8F6A, 0x5EFD, - 0x8F6B, 0x5F05, 0x8F6C, 0x5F06, 0x8F6D, 0x5F07, 0x8F6E, 0x5F09, 0x8F6F, 0x5F0C, 0x8F70, 0x5F0D, 0x8F71, 0x5F0E, 0x8F72, 0x5F10, - 0x8F73, 0x5F12, 0x8F74, 0x5F14, 0x8F75, 0x5F16, 0x8F76, 0x5F19, 0x8F77, 0x5F1A, 0x8F78, 0x5F1C, 0x8F79, 0x5F1D, 0x8F7A, 0x5F1E, - 0x8F7B, 0x5F21, 0x8F7C, 0x5F22, 0x8F7D, 0x5F23, 0x8F7E, 0x5F24, 0x8F80, 0x5F28, 0x8F81, 0x5F2B, 0x8F82, 0x5F2C, 0x8F83, 0x5F2E, - 0x8F84, 0x5F30, 0x8F85, 0x5F32, 0x8F86, 0x5F33, 0x8F87, 0x5F34, 0x8F88, 0x5F35, 0x8F89, 0x5F36, 0x8F8A, 0x5F37, 0x8F8B, 0x5F38, - 0x8F8C, 0x5F3B, 0x8F8D, 0x5F3D, 0x8F8E, 0x5F3E, 0x8F8F, 0x5F3F, 0x8F90, 0x5F41, 0x8F91, 0x5F42, 0x8F92, 0x5F43, 0x8F93, 0x5F44, - 0x8F94, 0x5F45, 0x8F95, 0x5F46, 0x8F96, 0x5F47, 0x8F97, 0x5F48, 0x8F98, 0x5F49, 0x8F99, 0x5F4A, 0x8F9A, 0x5F4B, 0x8F9B, 0x5F4C, - 0x8F9C, 0x5F4D, 0x8F9D, 0x5F4E, 0x8F9E, 0x5F4F, 0x8F9F, 0x5F51, 0x8FA0, 0x5F54, 0x8FA1, 0x5F59, 0x8FA2, 0x5F5A, 0x8FA3, 0x5F5B, - 0x8FA4, 0x5F5C, 0x8FA5, 0x5F5E, 0x8FA6, 0x5F5F, 0x8FA7, 0x5F60, 0x8FA8, 0x5F63, 0x8FA9, 0x5F65, 0x8FAA, 0x5F67, 0x8FAB, 0x5F68, - 0x8FAC, 0x5F6B, 0x8FAD, 0x5F6E, 0x8FAE, 0x5F6F, 0x8FAF, 0x5F72, 0x8FB0, 0x5F74, 0x8FB1, 0x5F75, 0x8FB2, 0x5F76, 0x8FB3, 0x5F78, - 0x8FB4, 0x5F7A, 0x8FB5, 0x5F7D, 0x8FB6, 0x5F7E, 0x8FB7, 0x5F7F, 0x8FB8, 0x5F83, 0x8FB9, 0x5F86, 0x8FBA, 0x5F8D, 0x8FBB, 0x5F8E, - 0x8FBC, 0x5F8F, 0x8FBD, 0x5F91, 0x8FBE, 0x5F93, 0x8FBF, 0x5F94, 0x8FC0, 0x5F96, 0x8FC1, 0x5F9A, 0x8FC2, 0x5F9B, 0x8FC3, 0x5F9D, - 0x8FC4, 0x5F9E, 0x8FC5, 0x5F9F, 0x8FC6, 0x5FA0, 0x8FC7, 0x5FA2, 0x8FC8, 0x5FA3, 0x8FC9, 0x5FA4, 0x8FCA, 0x5FA5, 0x8FCB, 0x5FA6, - 0x8FCC, 0x5FA7, 0x8FCD, 0x5FA9, 0x8FCE, 0x5FAB, 0x8FCF, 0x5FAC, 0x8FD0, 0x5FAF, 0x8FD1, 0x5FB0, 0x8FD2, 0x5FB1, 0x8FD3, 0x5FB2, - 0x8FD4, 0x5FB3, 0x8FD5, 0x5FB4, 0x8FD6, 0x5FB6, 0x8FD7, 0x5FB8, 0x8FD8, 0x5FB9, 0x8FD9, 0x5FBA, 0x8FDA, 0x5FBB, 0x8FDB, 0x5FBE, - 0x8FDC, 0x5FBF, 0x8FDD, 0x5FC0, 0x8FDE, 0x5FC1, 0x8FDF, 0x5FC2, 0x8FE0, 0x5FC7, 0x8FE1, 0x5FC8, 0x8FE2, 0x5FCA, 0x8FE3, 0x5FCB, - 0x8FE4, 0x5FCE, 0x8FE5, 0x5FD3, 0x8FE6, 0x5FD4, 0x8FE7, 0x5FD5, 0x8FE8, 0x5FDA, 0x8FE9, 0x5FDB, 0x8FEA, 0x5FDC, 0x8FEB, 0x5FDE, - 0x8FEC, 0x5FDF, 0x8FED, 0x5FE2, 0x8FEE, 0x5FE3, 0x8FEF, 0x5FE5, 0x8FF0, 0x5FE6, 0x8FF1, 0x5FE8, 0x8FF2, 0x5FE9, 0x8FF3, 0x5FEC, - 0x8FF4, 0x5FEF, 0x8FF5, 0x5FF0, 0x8FF6, 0x5FF2, 0x8FF7, 0x5FF3, 0x8FF8, 0x5FF4, 0x8FF9, 0x5FF6, 0x8FFA, 0x5FF7, 0x8FFB, 0x5FF9, - 0x8FFC, 0x5FFA, 0x8FFD, 0x5FFC, 0x8FFE, 0x6007, 0x9040, 0x6008, 0x9041, 0x6009, 0x9042, 0x600B, 0x9043, 0x600C, 0x9044, 0x6010, - 0x9045, 0x6011, 0x9046, 0x6013, 0x9047, 0x6017, 0x9048, 0x6018, 0x9049, 0x601A, 0x904A, 0x601E, 0x904B, 0x601F, 0x904C, 0x6022, - 0x904D, 0x6023, 0x904E, 0x6024, 0x904F, 0x602C, 0x9050, 0x602D, 0x9051, 0x602E, 0x9052, 0x6030, 0x9053, 0x6031, 0x9054, 0x6032, - 0x9055, 0x6033, 0x9056, 0x6034, 0x9057, 0x6036, 0x9058, 0x6037, 0x9059, 0x6038, 0x905A, 0x6039, 0x905B, 0x603A, 0x905C, 0x603D, - 0x905D, 0x603E, 0x905E, 0x6040, 0x905F, 0x6044, 0x9060, 0x6045, 0x9061, 0x6046, 0x9062, 0x6047, 0x9063, 0x6048, 0x9064, 0x6049, - 0x9065, 0x604A, 0x9066, 0x604C, 0x9067, 0x604E, 0x9068, 0x604F, 0x9069, 0x6051, 0x906A, 0x6053, 0x906B, 0x6054, 0x906C, 0x6056, - 0x906D, 0x6057, 0x906E, 0x6058, 0x906F, 0x605B, 0x9070, 0x605C, 0x9071, 0x605E, 0x9072, 0x605F, 0x9073, 0x6060, 0x9074, 0x6061, - 0x9075, 0x6065, 0x9076, 0x6066, 0x9077, 0x606E, 0x9078, 0x6071, 0x9079, 0x6072, 0x907A, 0x6074, 0x907B, 0x6075, 0x907C, 0x6077, - 0x907D, 0x607E, 0x907E, 0x6080, 0x9080, 0x6081, 0x9081, 0x6082, 0x9082, 0x6085, 0x9083, 0x6086, 0x9084, 0x6087, 0x9085, 0x6088, - 0x9086, 0x608A, 0x9087, 0x608B, 0x9088, 0x608E, 0x9089, 0x608F, 0x908A, 0x6090, 0x908B, 0x6091, 0x908C, 0x6093, 0x908D, 0x6095, - 0x908E, 0x6097, 0x908F, 0x6098, 0x9090, 0x6099, 0x9091, 0x609C, 0x9092, 0x609E, 0x9093, 0x60A1, 0x9094, 0x60A2, 0x9095, 0x60A4, - 0x9096, 0x60A5, 0x9097, 0x60A7, 0x9098, 0x60A9, 0x9099, 0x60AA, 0x909A, 0x60AE, 0x909B, 0x60B0, 0x909C, 0x60B3, 0x909D, 0x60B5, - 0x909E, 0x60B6, 0x909F, 0x60B7, 0x90A0, 0x60B9, 0x90A1, 0x60BA, 0x90A2, 0x60BD, 0x90A3, 0x60BE, 0x90A4, 0x60BF, 0x90A5, 0x60C0, - 0x90A6, 0x60C1, 0x90A7, 0x60C2, 0x90A8, 0x60C3, 0x90A9, 0x60C4, 0x90AA, 0x60C7, 0x90AB, 0x60C8, 0x90AC, 0x60C9, 0x90AD, 0x60CC, - 0x90AE, 0x60CD, 0x90AF, 0x60CE, 0x90B0, 0x60CF, 0x90B1, 0x60D0, 0x90B2, 0x60D2, 0x90B3, 0x60D3, 0x90B4, 0x60D4, 0x90B5, 0x60D6, - 0x90B6, 0x60D7, 0x90B7, 0x60D9, 0x90B8, 0x60DB, 0x90B9, 0x60DE, 0x90BA, 0x60E1, 0x90BB, 0x60E2, 0x90BC, 0x60E3, 0x90BD, 0x60E4, - 0x90BE, 0x60E5, 0x90BF, 0x60EA, 0x90C0, 0x60F1, 0x90C1, 0x60F2, 0x90C2, 0x60F5, 0x90C3, 0x60F7, 0x90C4, 0x60F8, 0x90C5, 0x60FB, - 0x90C6, 0x60FC, 0x90C7, 0x60FD, 0x90C8, 0x60FE, 0x90C9, 0x60FF, 0x90CA, 0x6102, 0x90CB, 0x6103, 0x90CC, 0x6104, 0x90CD, 0x6105, - 0x90CE, 0x6107, 0x90CF, 0x610A, 0x90D0, 0x610B, 0x90D1, 0x610C, 0x90D2, 0x6110, 0x90D3, 0x6111, 0x90D4, 0x6112, 0x90D5, 0x6113, - 0x90D6, 0x6114, 0x90D7, 0x6116, 0x90D8, 0x6117, 0x90D9, 0x6118, 0x90DA, 0x6119, 0x90DB, 0x611B, 0x90DC, 0x611C, 0x90DD, 0x611D, - 0x90DE, 0x611E, 0x90DF, 0x6121, 0x90E0, 0x6122, 0x90E1, 0x6125, 0x90E2, 0x6128, 0x90E3, 0x6129, 0x90E4, 0x612A, 0x90E5, 0x612C, - 0x90E6, 0x612D, 0x90E7, 0x612E, 0x90E8, 0x612F, 0x90E9, 0x6130, 0x90EA, 0x6131, 0x90EB, 0x6132, 0x90EC, 0x6133, 0x90ED, 0x6134, - 0x90EE, 0x6135, 0x90EF, 0x6136, 0x90F0, 0x6137, 0x90F1, 0x6138, 0x90F2, 0x6139, 0x90F3, 0x613A, 0x90F4, 0x613B, 0x90F5, 0x613C, - 0x90F6, 0x613D, 0x90F7, 0x613E, 0x90F8, 0x6140, 0x90F9, 0x6141, 0x90FA, 0x6142, 0x90FB, 0x6143, 0x90FC, 0x6144, 0x90FD, 0x6145, - 0x90FE, 0x6146, 0x9140, 0x6147, 0x9141, 0x6149, 0x9142, 0x614B, 0x9143, 0x614D, 0x9144, 0x614F, 0x9145, 0x6150, 0x9146, 0x6152, - 0x9147, 0x6153, 0x9148, 0x6154, 0x9149, 0x6156, 0x914A, 0x6157, 0x914B, 0x6158, 0x914C, 0x6159, 0x914D, 0x615A, 0x914E, 0x615B, - 0x914F, 0x615C, 0x9150, 0x615E, 0x9151, 0x615F, 0x9152, 0x6160, 0x9153, 0x6161, 0x9154, 0x6163, 0x9155, 0x6164, 0x9156, 0x6165, - 0x9157, 0x6166, 0x9158, 0x6169, 0x9159, 0x616A, 0x915A, 0x616B, 0x915B, 0x616C, 0x915C, 0x616D, 0x915D, 0x616E, 0x915E, 0x616F, - 0x915F, 0x6171, 0x9160, 0x6172, 0x9161, 0x6173, 0x9162, 0x6174, 0x9163, 0x6176, 0x9164, 0x6178, 0x9165, 0x6179, 0x9166, 0x617A, - 0x9167, 0x617B, 0x9168, 0x617C, 0x9169, 0x617D, 0x916A, 0x617E, 0x916B, 0x617F, 0x916C, 0x6180, 0x916D, 0x6181, 0x916E, 0x6182, - 0x916F, 0x6183, 0x9170, 0x6184, 0x9171, 0x6185, 0x9172, 0x6186, 0x9173, 0x6187, 0x9174, 0x6188, 0x9175, 0x6189, 0x9176, 0x618A, - 0x9177, 0x618C, 0x9178, 0x618D, 0x9179, 0x618F, 0x917A, 0x6190, 0x917B, 0x6191, 0x917C, 0x6192, 0x917D, 0x6193, 0x917E, 0x6195, - 0x9180, 0x6196, 0x9181, 0x6197, 0x9182, 0x6198, 0x9183, 0x6199, 0x9184, 0x619A, 0x9185, 0x619B, 0x9186, 0x619C, 0x9187, 0x619E, - 0x9188, 0x619F, 0x9189, 0x61A0, 0x918A, 0x61A1, 0x918B, 0x61A2, 0x918C, 0x61A3, 0x918D, 0x61A4, 0x918E, 0x61A5, 0x918F, 0x61A6, - 0x9190, 0x61AA, 0x9191, 0x61AB, 0x9192, 0x61AD, 0x9193, 0x61AE, 0x9194, 0x61AF, 0x9195, 0x61B0, 0x9196, 0x61B1, 0x9197, 0x61B2, - 0x9198, 0x61B3, 0x9199, 0x61B4, 0x919A, 0x61B5, 0x919B, 0x61B6, 0x919C, 0x61B8, 0x919D, 0x61B9, 0x919E, 0x61BA, 0x919F, 0x61BB, - 0x91A0, 0x61BC, 0x91A1, 0x61BD, 0x91A2, 0x61BF, 0x91A3, 0x61C0, 0x91A4, 0x61C1, 0x91A5, 0x61C3, 0x91A6, 0x61C4, 0x91A7, 0x61C5, - 0x91A8, 0x61C6, 0x91A9, 0x61C7, 0x91AA, 0x61C9, 0x91AB, 0x61CC, 0x91AC, 0x61CD, 0x91AD, 0x61CE, 0x91AE, 0x61CF, 0x91AF, 0x61D0, - 0x91B0, 0x61D3, 0x91B1, 0x61D5, 0x91B2, 0x61D6, 0x91B3, 0x61D7, 0x91B4, 0x61D8, 0x91B5, 0x61D9, 0x91B6, 0x61DA, 0x91B7, 0x61DB, - 0x91B8, 0x61DC, 0x91B9, 0x61DD, 0x91BA, 0x61DE, 0x91BB, 0x61DF, 0x91BC, 0x61E0, 0x91BD, 0x61E1, 0x91BE, 0x61E2, 0x91BF, 0x61E3, - 0x91C0, 0x61E4, 0x91C1, 0x61E5, 0x91C2, 0x61E7, 0x91C3, 0x61E8, 0x91C4, 0x61E9, 0x91C5, 0x61EA, 0x91C6, 0x61EB, 0x91C7, 0x61EC, - 0x91C8, 0x61ED, 0x91C9, 0x61EE, 0x91CA, 0x61EF, 0x91CB, 0x61F0, 0x91CC, 0x61F1, 0x91CD, 0x61F2, 0x91CE, 0x61F3, 0x91CF, 0x61F4, - 0x91D0, 0x61F6, 0x91D1, 0x61F7, 0x91D2, 0x61F8, 0x91D3, 0x61F9, 0x91D4, 0x61FA, 0x91D5, 0x61FB, 0x91D6, 0x61FC, 0x91D7, 0x61FD, - 0x91D8, 0x61FE, 0x91D9, 0x6200, 0x91DA, 0x6201, 0x91DB, 0x6202, 0x91DC, 0x6203, 0x91DD, 0x6204, 0x91DE, 0x6205, 0x91DF, 0x6207, - 0x91E0, 0x6209, 0x91E1, 0x6213, 0x91E2, 0x6214, 0x91E3, 0x6219, 0x91E4, 0x621C, 0x91E5, 0x621D, 0x91E6, 0x621E, 0x91E7, 0x6220, - 0x91E8, 0x6223, 0x91E9, 0x6226, 0x91EA, 0x6227, 0x91EB, 0x6228, 0x91EC, 0x6229, 0x91ED, 0x622B, 0x91EE, 0x622D, 0x91EF, 0x622F, - 0x91F0, 0x6230, 0x91F1, 0x6231, 0x91F2, 0x6232, 0x91F3, 0x6235, 0x91F4, 0x6236, 0x91F5, 0x6238, 0x91F6, 0x6239, 0x91F7, 0x623A, - 0x91F8, 0x623B, 0x91F9, 0x623C, 0x91FA, 0x6242, 0x91FB, 0x6244, 0x91FC, 0x6245, 0x91FD, 0x6246, 0x91FE, 0x624A, 0x9240, 0x624F, - 0x9241, 0x6250, 0x9242, 0x6255, 0x9243, 0x6256, 0x9244, 0x6257, 0x9245, 0x6259, 0x9246, 0x625A, 0x9247, 0x625C, 0x9248, 0x625D, - 0x9249, 0x625E, 0x924A, 0x625F, 0x924B, 0x6260, 0x924C, 0x6261, 0x924D, 0x6262, 0x924E, 0x6264, 0x924F, 0x6265, 0x9250, 0x6268, - 0x9251, 0x6271, 0x9252, 0x6272, 0x9253, 0x6274, 0x9254, 0x6275, 0x9255, 0x6277, 0x9256, 0x6278, 0x9257, 0x627A, 0x9258, 0x627B, - 0x9259, 0x627D, 0x925A, 0x6281, 0x925B, 0x6282, 0x925C, 0x6283, 0x925D, 0x6285, 0x925E, 0x6286, 0x925F, 0x6287, 0x9260, 0x6288, - 0x9261, 0x628B, 0x9262, 0x628C, 0x9263, 0x628D, 0x9264, 0x628E, 0x9265, 0x628F, 0x9266, 0x6290, 0x9267, 0x6294, 0x9268, 0x6299, - 0x9269, 0x629C, 0x926A, 0x629D, 0x926B, 0x629E, 0x926C, 0x62A3, 0x926D, 0x62A6, 0x926E, 0x62A7, 0x926F, 0x62A9, 0x9270, 0x62AA, - 0x9271, 0x62AD, 0x9272, 0x62AE, 0x9273, 0x62AF, 0x9274, 0x62B0, 0x9275, 0x62B2, 0x9276, 0x62B3, 0x9277, 0x62B4, 0x9278, 0x62B6, - 0x9279, 0x62B7, 0x927A, 0x62B8, 0x927B, 0x62BA, 0x927C, 0x62BE, 0x927D, 0x62C0, 0x927E, 0x62C1, 0x9280, 0x62C3, 0x9281, 0x62CB, - 0x9282, 0x62CF, 0x9283, 0x62D1, 0x9284, 0x62D5, 0x9285, 0x62DD, 0x9286, 0x62DE, 0x9287, 0x62E0, 0x9288, 0x62E1, 0x9289, 0x62E4, - 0x928A, 0x62EA, 0x928B, 0x62EB, 0x928C, 0x62F0, 0x928D, 0x62F2, 0x928E, 0x62F5, 0x928F, 0x62F8, 0x9290, 0x62F9, 0x9291, 0x62FA, - 0x9292, 0x62FB, 0x9293, 0x6300, 0x9294, 0x6303, 0x9295, 0x6304, 0x9296, 0x6305, 0x9297, 0x6306, 0x9298, 0x630A, 0x9299, 0x630B, - 0x929A, 0x630C, 0x929B, 0x630D, 0x929C, 0x630F, 0x929D, 0x6310, 0x929E, 0x6312, 0x929F, 0x6313, 0x92A0, 0x6314, 0x92A1, 0x6315, - 0x92A2, 0x6317, 0x92A3, 0x6318, 0x92A4, 0x6319, 0x92A5, 0x631C, 0x92A6, 0x6326, 0x92A7, 0x6327, 0x92A8, 0x6329, 0x92A9, 0x632C, - 0x92AA, 0x632D, 0x92AB, 0x632E, 0x92AC, 0x6330, 0x92AD, 0x6331, 0x92AE, 0x6333, 0x92AF, 0x6334, 0x92B0, 0x6335, 0x92B1, 0x6336, - 0x92B2, 0x6337, 0x92B3, 0x6338, 0x92B4, 0x633B, 0x92B5, 0x633C, 0x92B6, 0x633E, 0x92B7, 0x633F, 0x92B8, 0x6340, 0x92B9, 0x6341, - 0x92BA, 0x6344, 0x92BB, 0x6347, 0x92BC, 0x6348, 0x92BD, 0x634A, 0x92BE, 0x6351, 0x92BF, 0x6352, 0x92C0, 0x6353, 0x92C1, 0x6354, - 0x92C2, 0x6356, 0x92C3, 0x6357, 0x92C4, 0x6358, 0x92C5, 0x6359, 0x92C6, 0x635A, 0x92C7, 0x635B, 0x92C8, 0x635C, 0x92C9, 0x635D, - 0x92CA, 0x6360, 0x92CB, 0x6364, 0x92CC, 0x6365, 0x92CD, 0x6366, 0x92CE, 0x6368, 0x92CF, 0x636A, 0x92D0, 0x636B, 0x92D1, 0x636C, - 0x92D2, 0x636F, 0x92D3, 0x6370, 0x92D4, 0x6372, 0x92D5, 0x6373, 0x92D6, 0x6374, 0x92D7, 0x6375, 0x92D8, 0x6378, 0x92D9, 0x6379, - 0x92DA, 0x637C, 0x92DB, 0x637D, 0x92DC, 0x637E, 0x92DD, 0x637F, 0x92DE, 0x6381, 0x92DF, 0x6383, 0x92E0, 0x6384, 0x92E1, 0x6385, - 0x92E2, 0x6386, 0x92E3, 0x638B, 0x92E4, 0x638D, 0x92E5, 0x6391, 0x92E6, 0x6393, 0x92E7, 0x6394, 0x92E8, 0x6395, 0x92E9, 0x6397, - 0x92EA, 0x6399, 0x92EB, 0x639A, 0x92EC, 0x639B, 0x92ED, 0x639C, 0x92EE, 0x639D, 0x92EF, 0x639E, 0x92F0, 0x639F, 0x92F1, 0x63A1, - 0x92F2, 0x63A4, 0x92F3, 0x63A6, 0x92F4, 0x63AB, 0x92F5, 0x63AF, 0x92F6, 0x63B1, 0x92F7, 0x63B2, 0x92F8, 0x63B5, 0x92F9, 0x63B6, - 0x92FA, 0x63B9, 0x92FB, 0x63BB, 0x92FC, 0x63BD, 0x92FD, 0x63BF, 0x92FE, 0x63C0, 0x9340, 0x63C1, 0x9341, 0x63C2, 0x9342, 0x63C3, - 0x9343, 0x63C5, 0x9344, 0x63C7, 0x9345, 0x63C8, 0x9346, 0x63CA, 0x9347, 0x63CB, 0x9348, 0x63CC, 0x9349, 0x63D1, 0x934A, 0x63D3, - 0x934B, 0x63D4, 0x934C, 0x63D5, 0x934D, 0x63D7, 0x934E, 0x63D8, 0x934F, 0x63D9, 0x9350, 0x63DA, 0x9351, 0x63DB, 0x9352, 0x63DC, - 0x9353, 0x63DD, 0x9354, 0x63DF, 0x9355, 0x63E2, 0x9356, 0x63E4, 0x9357, 0x63E5, 0x9358, 0x63E6, 0x9359, 0x63E7, 0x935A, 0x63E8, - 0x935B, 0x63EB, 0x935C, 0x63EC, 0x935D, 0x63EE, 0x935E, 0x63EF, 0x935F, 0x63F0, 0x9360, 0x63F1, 0x9361, 0x63F3, 0x9362, 0x63F5, - 0x9363, 0x63F7, 0x9364, 0x63F9, 0x9365, 0x63FA, 0x9366, 0x63FB, 0x9367, 0x63FC, 0x9368, 0x63FE, 0x9369, 0x6403, 0x936A, 0x6404, - 0x936B, 0x6406, 0x936C, 0x6407, 0x936D, 0x6408, 0x936E, 0x6409, 0x936F, 0x640A, 0x9370, 0x640D, 0x9371, 0x640E, 0x9372, 0x6411, - 0x9373, 0x6412, 0x9374, 0x6415, 0x9375, 0x6416, 0x9376, 0x6417, 0x9377, 0x6418, 0x9378, 0x6419, 0x9379, 0x641A, 0x937A, 0x641D, - 0x937B, 0x641F, 0x937C, 0x6422, 0x937D, 0x6423, 0x937E, 0x6424, 0x9380, 0x6425, 0x9381, 0x6427, 0x9382, 0x6428, 0x9383, 0x6429, - 0x9384, 0x642B, 0x9385, 0x642E, 0x9386, 0x642F, 0x9387, 0x6430, 0x9388, 0x6431, 0x9389, 0x6432, 0x938A, 0x6433, 0x938B, 0x6435, - 0x938C, 0x6436, 0x938D, 0x6437, 0x938E, 0x6438, 0x938F, 0x6439, 0x9390, 0x643B, 0x9391, 0x643C, 0x9392, 0x643E, 0x9393, 0x6440, - 0x9394, 0x6442, 0x9395, 0x6443, 0x9396, 0x6449, 0x9397, 0x644B, 0x9398, 0x644C, 0x9399, 0x644D, 0x939A, 0x644E, 0x939B, 0x644F, - 0x939C, 0x6450, 0x939D, 0x6451, 0x939E, 0x6453, 0x939F, 0x6455, 0x93A0, 0x6456, 0x93A1, 0x6457, 0x93A2, 0x6459, 0x93A3, 0x645A, - 0x93A4, 0x645B, 0x93A5, 0x645C, 0x93A6, 0x645D, 0x93A7, 0x645F, 0x93A8, 0x6460, 0x93A9, 0x6461, 0x93AA, 0x6462, 0x93AB, 0x6463, - 0x93AC, 0x6464, 0x93AD, 0x6465, 0x93AE, 0x6466, 0x93AF, 0x6468, 0x93B0, 0x646A, 0x93B1, 0x646B, 0x93B2, 0x646C, 0x93B3, 0x646E, - 0x93B4, 0x646F, 0x93B5, 0x6470, 0x93B6, 0x6471, 0x93B7, 0x6472, 0x93B8, 0x6473, 0x93B9, 0x6474, 0x93BA, 0x6475, 0x93BB, 0x6476, - 0x93BC, 0x6477, 0x93BD, 0x647B, 0x93BE, 0x647C, 0x93BF, 0x647D, 0x93C0, 0x647E, 0x93C1, 0x647F, 0x93C2, 0x6480, 0x93C3, 0x6481, - 0x93C4, 0x6483, 0x93C5, 0x6486, 0x93C6, 0x6488, 0x93C7, 0x6489, 0x93C8, 0x648A, 0x93C9, 0x648B, 0x93CA, 0x648C, 0x93CB, 0x648D, - 0x93CC, 0x648E, 0x93CD, 0x648F, 0x93CE, 0x6490, 0x93CF, 0x6493, 0x93D0, 0x6494, 0x93D1, 0x6497, 0x93D2, 0x6498, 0x93D3, 0x649A, - 0x93D4, 0x649B, 0x93D5, 0x649C, 0x93D6, 0x649D, 0x93D7, 0x649F, 0x93D8, 0x64A0, 0x93D9, 0x64A1, 0x93DA, 0x64A2, 0x93DB, 0x64A3, - 0x93DC, 0x64A5, 0x93DD, 0x64A6, 0x93DE, 0x64A7, 0x93DF, 0x64A8, 0x93E0, 0x64AA, 0x93E1, 0x64AB, 0x93E2, 0x64AF, 0x93E3, 0x64B1, - 0x93E4, 0x64B2, 0x93E5, 0x64B3, 0x93E6, 0x64B4, 0x93E7, 0x64B6, 0x93E8, 0x64B9, 0x93E9, 0x64BB, 0x93EA, 0x64BD, 0x93EB, 0x64BE, - 0x93EC, 0x64BF, 0x93ED, 0x64C1, 0x93EE, 0x64C3, 0x93EF, 0x64C4, 0x93F0, 0x64C6, 0x93F1, 0x64C7, 0x93F2, 0x64C8, 0x93F3, 0x64C9, - 0x93F4, 0x64CA, 0x93F5, 0x64CB, 0x93F6, 0x64CC, 0x93F7, 0x64CF, 0x93F8, 0x64D1, 0x93F9, 0x64D3, 0x93FA, 0x64D4, 0x93FB, 0x64D5, - 0x93FC, 0x64D6, 0x93FD, 0x64D9, 0x93FE, 0x64DA, 0x9440, 0x64DB, 0x9441, 0x64DC, 0x9442, 0x64DD, 0x9443, 0x64DF, 0x9444, 0x64E0, - 0x9445, 0x64E1, 0x9446, 0x64E3, 0x9447, 0x64E5, 0x9448, 0x64E7, 0x9449, 0x64E8, 0x944A, 0x64E9, 0x944B, 0x64EA, 0x944C, 0x64EB, - 0x944D, 0x64EC, 0x944E, 0x64ED, 0x944F, 0x64EE, 0x9450, 0x64EF, 0x9451, 0x64F0, 0x9452, 0x64F1, 0x9453, 0x64F2, 0x9454, 0x64F3, - 0x9455, 0x64F4, 0x9456, 0x64F5, 0x9457, 0x64F6, 0x9458, 0x64F7, 0x9459, 0x64F8, 0x945A, 0x64F9, 0x945B, 0x64FA, 0x945C, 0x64FB, - 0x945D, 0x64FC, 0x945E, 0x64FD, 0x945F, 0x64FE, 0x9460, 0x64FF, 0x9461, 0x6501, 0x9462, 0x6502, 0x9463, 0x6503, 0x9464, 0x6504, - 0x9465, 0x6505, 0x9466, 0x6506, 0x9467, 0x6507, 0x9468, 0x6508, 0x9469, 0x650A, 0x946A, 0x650B, 0x946B, 0x650C, 0x946C, 0x650D, - 0x946D, 0x650E, 0x946E, 0x650F, 0x946F, 0x6510, 0x9470, 0x6511, 0x9471, 0x6513, 0x9472, 0x6514, 0x9473, 0x6515, 0x9474, 0x6516, - 0x9475, 0x6517, 0x9476, 0x6519, 0x9477, 0x651A, 0x9478, 0x651B, 0x9479, 0x651C, 0x947A, 0x651D, 0x947B, 0x651E, 0x947C, 0x651F, - 0x947D, 0x6520, 0x947E, 0x6521, 0x9480, 0x6522, 0x9481, 0x6523, 0x9482, 0x6524, 0x9483, 0x6526, 0x9484, 0x6527, 0x9485, 0x6528, - 0x9486, 0x6529, 0x9487, 0x652A, 0x9488, 0x652C, 0x9489, 0x652D, 0x948A, 0x6530, 0x948B, 0x6531, 0x948C, 0x6532, 0x948D, 0x6533, - 0x948E, 0x6537, 0x948F, 0x653A, 0x9490, 0x653C, 0x9491, 0x653D, 0x9492, 0x6540, 0x9493, 0x6541, 0x9494, 0x6542, 0x9495, 0x6543, - 0x9496, 0x6544, 0x9497, 0x6546, 0x9498, 0x6547, 0x9499, 0x654A, 0x949A, 0x654B, 0x949B, 0x654D, 0x949C, 0x654E, 0x949D, 0x6550, - 0x949E, 0x6552, 0x949F, 0x6553, 0x94A0, 0x6554, 0x94A1, 0x6557, 0x94A2, 0x6558, 0x94A3, 0x655A, 0x94A4, 0x655C, 0x94A5, 0x655F, - 0x94A6, 0x6560, 0x94A7, 0x6561, 0x94A8, 0x6564, 0x94A9, 0x6565, 0x94AA, 0x6567, 0x94AB, 0x6568, 0x94AC, 0x6569, 0x94AD, 0x656A, - 0x94AE, 0x656D, 0x94AF, 0x656E, 0x94B0, 0x656F, 0x94B1, 0x6571, 0x94B2, 0x6573, 0x94B3, 0x6575, 0x94B4, 0x6576, 0x94B5, 0x6578, - 0x94B6, 0x6579, 0x94B7, 0x657A, 0x94B8, 0x657B, 0x94B9, 0x657C, 0x94BA, 0x657D, 0x94BB, 0x657E, 0x94BC, 0x657F, 0x94BD, 0x6580, - 0x94BE, 0x6581, 0x94BF, 0x6582, 0x94C0, 0x6583, 0x94C1, 0x6584, 0x94C2, 0x6585, 0x94C3, 0x6586, 0x94C4, 0x6588, 0x94C5, 0x6589, - 0x94C6, 0x658A, 0x94C7, 0x658D, 0x94C8, 0x658E, 0x94C9, 0x658F, 0x94CA, 0x6592, 0x94CB, 0x6594, 0x94CC, 0x6595, 0x94CD, 0x6596, - 0x94CE, 0x6598, 0x94CF, 0x659A, 0x94D0, 0x659D, 0x94D1, 0x659E, 0x94D2, 0x65A0, 0x94D3, 0x65A2, 0x94D4, 0x65A3, 0x94D5, 0x65A6, - 0x94D6, 0x65A8, 0x94D7, 0x65AA, 0x94D8, 0x65AC, 0x94D9, 0x65AE, 0x94DA, 0x65B1, 0x94DB, 0x65B2, 0x94DC, 0x65B3, 0x94DD, 0x65B4, - 0x94DE, 0x65B5, 0x94DF, 0x65B6, 0x94E0, 0x65B7, 0x94E1, 0x65B8, 0x94E2, 0x65BA, 0x94E3, 0x65BB, 0x94E4, 0x65BE, 0x94E5, 0x65BF, - 0x94E6, 0x65C0, 0x94E7, 0x65C2, 0x94E8, 0x65C7, 0x94E9, 0x65C8, 0x94EA, 0x65C9, 0x94EB, 0x65CA, 0x94EC, 0x65CD, 0x94ED, 0x65D0, - 0x94EE, 0x65D1, 0x94EF, 0x65D3, 0x94F0, 0x65D4, 0x94F1, 0x65D5, 0x94F2, 0x65D8, 0x94F3, 0x65D9, 0x94F4, 0x65DA, 0x94F5, 0x65DB, - 0x94F6, 0x65DC, 0x94F7, 0x65DD, 0x94F8, 0x65DE, 0x94F9, 0x65DF, 0x94FA, 0x65E1, 0x94FB, 0x65E3, 0x94FC, 0x65E4, 0x94FD, 0x65EA, - 0x94FE, 0x65EB, 0x9540, 0x65F2, 0x9541, 0x65F3, 0x9542, 0x65F4, 0x9543, 0x65F5, 0x9544, 0x65F8, 0x9545, 0x65F9, 0x9546, 0x65FB, - 0x9547, 0x65FC, 0x9548, 0x65FD, 0x9549, 0x65FE, 0x954A, 0x65FF, 0x954B, 0x6601, 0x954C, 0x6604, 0x954D, 0x6605, 0x954E, 0x6607, - 0x954F, 0x6608, 0x9550, 0x6609, 0x9551, 0x660B, 0x9552, 0x660D, 0x9553, 0x6610, 0x9554, 0x6611, 0x9555, 0x6612, 0x9556, 0x6616, - 0x9557, 0x6617, 0x9558, 0x6618, 0x9559, 0x661A, 0x955A, 0x661B, 0x955B, 0x661C, 0x955C, 0x661E, 0x955D, 0x6621, 0x955E, 0x6622, - 0x955F, 0x6623, 0x9560, 0x6624, 0x9561, 0x6626, 0x9562, 0x6629, 0x9563, 0x662A, 0x9564, 0x662B, 0x9565, 0x662C, 0x9566, 0x662E, - 0x9567, 0x6630, 0x9568, 0x6632, 0x9569, 0x6633, 0x956A, 0x6637, 0x956B, 0x6638, 0x956C, 0x6639, 0x956D, 0x663A, 0x956E, 0x663B, - 0x956F, 0x663D, 0x9570, 0x663F, 0x9571, 0x6640, 0x9572, 0x6642, 0x9573, 0x6644, 0x9574, 0x6645, 0x9575, 0x6646, 0x9576, 0x6647, - 0x9577, 0x6648, 0x9578, 0x6649, 0x9579, 0x664A, 0x957A, 0x664D, 0x957B, 0x664E, 0x957C, 0x6650, 0x957D, 0x6651, 0x957E, 0x6658, - 0x9580, 0x6659, 0x9581, 0x665B, 0x9582, 0x665C, 0x9583, 0x665D, 0x9584, 0x665E, 0x9585, 0x6660, 0x9586, 0x6662, 0x9587, 0x6663, - 0x9588, 0x6665, 0x9589, 0x6667, 0x958A, 0x6669, 0x958B, 0x666A, 0x958C, 0x666B, 0x958D, 0x666C, 0x958E, 0x666D, 0x958F, 0x6671, - 0x9590, 0x6672, 0x9591, 0x6673, 0x9592, 0x6675, 0x9593, 0x6678, 0x9594, 0x6679, 0x9595, 0x667B, 0x9596, 0x667C, 0x9597, 0x667D, - 0x9598, 0x667F, 0x9599, 0x6680, 0x959A, 0x6681, 0x959B, 0x6683, 0x959C, 0x6685, 0x959D, 0x6686, 0x959E, 0x6688, 0x959F, 0x6689, - 0x95A0, 0x668A, 0x95A1, 0x668B, 0x95A2, 0x668D, 0x95A3, 0x668E, 0x95A4, 0x668F, 0x95A5, 0x6690, 0x95A6, 0x6692, 0x95A7, 0x6693, - 0x95A8, 0x6694, 0x95A9, 0x6695, 0x95AA, 0x6698, 0x95AB, 0x6699, 0x95AC, 0x669A, 0x95AD, 0x669B, 0x95AE, 0x669C, 0x95AF, 0x669E, - 0x95B0, 0x669F, 0x95B1, 0x66A0, 0x95B2, 0x66A1, 0x95B3, 0x66A2, 0x95B4, 0x66A3, 0x95B5, 0x66A4, 0x95B6, 0x66A5, 0x95B7, 0x66A6, - 0x95B8, 0x66A9, 0x95B9, 0x66AA, 0x95BA, 0x66AB, 0x95BB, 0x66AC, 0x95BC, 0x66AD, 0x95BD, 0x66AF, 0x95BE, 0x66B0, 0x95BF, 0x66B1, - 0x95C0, 0x66B2, 0x95C1, 0x66B3, 0x95C2, 0x66B5, 0x95C3, 0x66B6, 0x95C4, 0x66B7, 0x95C5, 0x66B8, 0x95C6, 0x66BA, 0x95C7, 0x66BB, - 0x95C8, 0x66BC, 0x95C9, 0x66BD, 0x95CA, 0x66BF, 0x95CB, 0x66C0, 0x95CC, 0x66C1, 0x95CD, 0x66C2, 0x95CE, 0x66C3, 0x95CF, 0x66C4, - 0x95D0, 0x66C5, 0x95D1, 0x66C6, 0x95D2, 0x66C7, 0x95D3, 0x66C8, 0x95D4, 0x66C9, 0x95D5, 0x66CA, 0x95D6, 0x66CB, 0x95D7, 0x66CC, - 0x95D8, 0x66CD, 0x95D9, 0x66CE, 0x95DA, 0x66CF, 0x95DB, 0x66D0, 0x95DC, 0x66D1, 0x95DD, 0x66D2, 0x95DE, 0x66D3, 0x95DF, 0x66D4, - 0x95E0, 0x66D5, 0x95E1, 0x66D6, 0x95E2, 0x66D7, 0x95E3, 0x66D8, 0x95E4, 0x66DA, 0x95E5, 0x66DE, 0x95E6, 0x66DF, 0x95E7, 0x66E0, - 0x95E8, 0x66E1, 0x95E9, 0x66E2, 0x95EA, 0x66E3, 0x95EB, 0x66E4, 0x95EC, 0x66E5, 0x95ED, 0x66E7, 0x95EE, 0x66E8, 0x95EF, 0x66EA, - 0x95F0, 0x66EB, 0x95F1, 0x66EC, 0x95F2, 0x66ED, 0x95F3, 0x66EE, 0x95F4, 0x66EF, 0x95F5, 0x66F1, 0x95F6, 0x66F5, 0x95F7, 0x66F6, - 0x95F8, 0x66F8, 0x95F9, 0x66FA, 0x95FA, 0x66FB, 0x95FB, 0x66FD, 0x95FC, 0x6701, 0x95FD, 0x6702, 0x95FE, 0x6703, 0x9640, 0x6704, - 0x9641, 0x6705, 0x9642, 0x6706, 0x9643, 0x6707, 0x9644, 0x670C, 0x9645, 0x670E, 0x9646, 0x670F, 0x9647, 0x6711, 0x9648, 0x6712, - 0x9649, 0x6713, 0x964A, 0x6716, 0x964B, 0x6718, 0x964C, 0x6719, 0x964D, 0x671A, 0x964E, 0x671C, 0x964F, 0x671E, 0x9650, 0x6720, - 0x9651, 0x6721, 0x9652, 0x6722, 0x9653, 0x6723, 0x9654, 0x6724, 0x9655, 0x6725, 0x9656, 0x6727, 0x9657, 0x6729, 0x9658, 0x672E, - 0x9659, 0x6730, 0x965A, 0x6732, 0x965B, 0x6733, 0x965C, 0x6736, 0x965D, 0x6737, 0x965E, 0x6738, 0x965F, 0x6739, 0x9660, 0x673B, - 0x9661, 0x673C, 0x9662, 0x673E, 0x9663, 0x673F, 0x9664, 0x6741, 0x9665, 0x6744, 0x9666, 0x6745, 0x9667, 0x6747, 0x9668, 0x674A, - 0x9669, 0x674B, 0x966A, 0x674D, 0x966B, 0x6752, 0x966C, 0x6754, 0x966D, 0x6755, 0x966E, 0x6757, 0x966F, 0x6758, 0x9670, 0x6759, - 0x9671, 0x675A, 0x9672, 0x675B, 0x9673, 0x675D, 0x9674, 0x6762, 0x9675, 0x6763, 0x9676, 0x6764, 0x9677, 0x6766, 0x9678, 0x6767, - 0x9679, 0x676B, 0x967A, 0x676C, 0x967B, 0x676E, 0x967C, 0x6771, 0x967D, 0x6774, 0x967E, 0x6776, 0x9680, 0x6778, 0x9681, 0x6779, - 0x9682, 0x677A, 0x9683, 0x677B, 0x9684, 0x677D, 0x9685, 0x6780, 0x9686, 0x6782, 0x9687, 0x6783, 0x9688, 0x6785, 0x9689, 0x6786, - 0x968A, 0x6788, 0x968B, 0x678A, 0x968C, 0x678C, 0x968D, 0x678D, 0x968E, 0x678E, 0x968F, 0x678F, 0x9690, 0x6791, 0x9691, 0x6792, - 0x9692, 0x6793, 0x9693, 0x6794, 0x9694, 0x6796, 0x9695, 0x6799, 0x9696, 0x679B, 0x9697, 0x679F, 0x9698, 0x67A0, 0x9699, 0x67A1, - 0x969A, 0x67A4, 0x969B, 0x67A6, 0x969C, 0x67A9, 0x969D, 0x67AC, 0x969E, 0x67AE, 0x969F, 0x67B1, 0x96A0, 0x67B2, 0x96A1, 0x67B4, - 0x96A2, 0x67B9, 0x96A3, 0x67BA, 0x96A4, 0x67BB, 0x96A5, 0x67BC, 0x96A6, 0x67BD, 0x96A7, 0x67BE, 0x96A8, 0x67BF, 0x96A9, 0x67C0, - 0x96AA, 0x67C2, 0x96AB, 0x67C5, 0x96AC, 0x67C6, 0x96AD, 0x67C7, 0x96AE, 0x67C8, 0x96AF, 0x67C9, 0x96B0, 0x67CA, 0x96B1, 0x67CB, - 0x96B2, 0x67CC, 0x96B3, 0x67CD, 0x96B4, 0x67CE, 0x96B5, 0x67D5, 0x96B6, 0x67D6, 0x96B7, 0x67D7, 0x96B8, 0x67DB, 0x96B9, 0x67DF, - 0x96BA, 0x67E1, 0x96BB, 0x67E3, 0x96BC, 0x67E4, 0x96BD, 0x67E6, 0x96BE, 0x67E7, 0x96BF, 0x67E8, 0x96C0, 0x67EA, 0x96C1, 0x67EB, - 0x96C2, 0x67ED, 0x96C3, 0x67EE, 0x96C4, 0x67F2, 0x96C5, 0x67F5, 0x96C6, 0x67F6, 0x96C7, 0x67F7, 0x96C8, 0x67F8, 0x96C9, 0x67F9, - 0x96CA, 0x67FA, 0x96CB, 0x67FB, 0x96CC, 0x67FC, 0x96CD, 0x67FE, 0x96CE, 0x6801, 0x96CF, 0x6802, 0x96D0, 0x6803, 0x96D1, 0x6804, - 0x96D2, 0x6806, 0x96D3, 0x680D, 0x96D4, 0x6810, 0x96D5, 0x6812, 0x96D6, 0x6814, 0x96D7, 0x6815, 0x96D8, 0x6818, 0x96D9, 0x6819, - 0x96DA, 0x681A, 0x96DB, 0x681B, 0x96DC, 0x681C, 0x96DD, 0x681E, 0x96DE, 0x681F, 0x96DF, 0x6820, 0x96E0, 0x6822, 0x96E1, 0x6823, - 0x96E2, 0x6824, 0x96E3, 0x6825, 0x96E4, 0x6826, 0x96E5, 0x6827, 0x96E6, 0x6828, 0x96E7, 0x682B, 0x96E8, 0x682C, 0x96E9, 0x682D, - 0x96EA, 0x682E, 0x96EB, 0x682F, 0x96EC, 0x6830, 0x96ED, 0x6831, 0x96EE, 0x6834, 0x96EF, 0x6835, 0x96F0, 0x6836, 0x96F1, 0x683A, - 0x96F2, 0x683B, 0x96F3, 0x683F, 0x96F4, 0x6847, 0x96F5, 0x684B, 0x96F6, 0x684D, 0x96F7, 0x684F, 0x96F8, 0x6852, 0x96F9, 0x6856, - 0x96FA, 0x6857, 0x96FB, 0x6858, 0x96FC, 0x6859, 0x96FD, 0x685A, 0x96FE, 0x685B, 0x9740, 0x685C, 0x9741, 0x685D, 0x9742, 0x685E, - 0x9743, 0x685F, 0x9744, 0x686A, 0x9745, 0x686C, 0x9746, 0x686D, 0x9747, 0x686E, 0x9748, 0x686F, 0x9749, 0x6870, 0x974A, 0x6871, - 0x974B, 0x6872, 0x974C, 0x6873, 0x974D, 0x6875, 0x974E, 0x6878, 0x974F, 0x6879, 0x9750, 0x687A, 0x9751, 0x687B, 0x9752, 0x687C, - 0x9753, 0x687D, 0x9754, 0x687E, 0x9755, 0x687F, 0x9756, 0x6880, 0x9757, 0x6882, 0x9758, 0x6884, 0x9759, 0x6887, 0x975A, 0x6888, - 0x975B, 0x6889, 0x975C, 0x688A, 0x975D, 0x688B, 0x975E, 0x688C, 0x975F, 0x688D, 0x9760, 0x688E, 0x9761, 0x6890, 0x9762, 0x6891, - 0x9763, 0x6892, 0x9764, 0x6894, 0x9765, 0x6895, 0x9766, 0x6896, 0x9767, 0x6898, 0x9768, 0x6899, 0x9769, 0x689A, 0x976A, 0x689B, - 0x976B, 0x689C, 0x976C, 0x689D, 0x976D, 0x689E, 0x976E, 0x689F, 0x976F, 0x68A0, 0x9770, 0x68A1, 0x9771, 0x68A3, 0x9772, 0x68A4, - 0x9773, 0x68A5, 0x9774, 0x68A9, 0x9775, 0x68AA, 0x9776, 0x68AB, 0x9777, 0x68AC, 0x9778, 0x68AE, 0x9779, 0x68B1, 0x977A, 0x68B2, - 0x977B, 0x68B4, 0x977C, 0x68B6, 0x977D, 0x68B7, 0x977E, 0x68B8, 0x9780, 0x68B9, 0x9781, 0x68BA, 0x9782, 0x68BB, 0x9783, 0x68BC, - 0x9784, 0x68BD, 0x9785, 0x68BE, 0x9786, 0x68BF, 0x9787, 0x68C1, 0x9788, 0x68C3, 0x9789, 0x68C4, 0x978A, 0x68C5, 0x978B, 0x68C6, - 0x978C, 0x68C7, 0x978D, 0x68C8, 0x978E, 0x68CA, 0x978F, 0x68CC, 0x9790, 0x68CE, 0x9791, 0x68CF, 0x9792, 0x68D0, 0x9793, 0x68D1, - 0x9794, 0x68D3, 0x9795, 0x68D4, 0x9796, 0x68D6, 0x9797, 0x68D7, 0x9798, 0x68D9, 0x9799, 0x68DB, 0x979A, 0x68DC, 0x979B, 0x68DD, - 0x979C, 0x68DE, 0x979D, 0x68DF, 0x979E, 0x68E1, 0x979F, 0x68E2, 0x97A0, 0x68E4, 0x97A1, 0x68E5, 0x97A2, 0x68E6, 0x97A3, 0x68E7, - 0x97A4, 0x68E8, 0x97A5, 0x68E9, 0x97A6, 0x68EA, 0x97A7, 0x68EB, 0x97A8, 0x68EC, 0x97A9, 0x68ED, 0x97AA, 0x68EF, 0x97AB, 0x68F2, - 0x97AC, 0x68F3, 0x97AD, 0x68F4, 0x97AE, 0x68F6, 0x97AF, 0x68F7, 0x97B0, 0x68F8, 0x97B1, 0x68FB, 0x97B2, 0x68FD, 0x97B3, 0x68FE, - 0x97B4, 0x68FF, 0x97B5, 0x6900, 0x97B6, 0x6902, 0x97B7, 0x6903, 0x97B8, 0x6904, 0x97B9, 0x6906, 0x97BA, 0x6907, 0x97BB, 0x6908, - 0x97BC, 0x6909, 0x97BD, 0x690A, 0x97BE, 0x690C, 0x97BF, 0x690F, 0x97C0, 0x6911, 0x97C1, 0x6913, 0x97C2, 0x6914, 0x97C3, 0x6915, - 0x97C4, 0x6916, 0x97C5, 0x6917, 0x97C6, 0x6918, 0x97C7, 0x6919, 0x97C8, 0x691A, 0x97C9, 0x691B, 0x97CA, 0x691C, 0x97CB, 0x691D, - 0x97CC, 0x691E, 0x97CD, 0x6921, 0x97CE, 0x6922, 0x97CF, 0x6923, 0x97D0, 0x6925, 0x97D1, 0x6926, 0x97D2, 0x6927, 0x97D3, 0x6928, - 0x97D4, 0x6929, 0x97D5, 0x692A, 0x97D6, 0x692B, 0x97D7, 0x692C, 0x97D8, 0x692E, 0x97D9, 0x692F, 0x97DA, 0x6931, 0x97DB, 0x6932, - 0x97DC, 0x6933, 0x97DD, 0x6935, 0x97DE, 0x6936, 0x97DF, 0x6937, 0x97E0, 0x6938, 0x97E1, 0x693A, 0x97E2, 0x693B, 0x97E3, 0x693C, - 0x97E4, 0x693E, 0x97E5, 0x6940, 0x97E6, 0x6941, 0x97E7, 0x6943, 0x97E8, 0x6944, 0x97E9, 0x6945, 0x97EA, 0x6946, 0x97EB, 0x6947, - 0x97EC, 0x6948, 0x97ED, 0x6949, 0x97EE, 0x694A, 0x97EF, 0x694B, 0x97F0, 0x694C, 0x97F1, 0x694D, 0x97F2, 0x694E, 0x97F3, 0x694F, - 0x97F4, 0x6950, 0x97F5, 0x6951, 0x97F6, 0x6952, 0x97F7, 0x6953, 0x97F8, 0x6955, 0x97F9, 0x6956, 0x97FA, 0x6958, 0x97FB, 0x6959, - 0x97FC, 0x695B, 0x97FD, 0x695C, 0x97FE, 0x695F, 0x9840, 0x6961, 0x9841, 0x6962, 0x9842, 0x6964, 0x9843, 0x6965, 0x9844, 0x6967, - 0x9845, 0x6968, 0x9846, 0x6969, 0x9847, 0x696A, 0x9848, 0x696C, 0x9849, 0x696D, 0x984A, 0x696F, 0x984B, 0x6970, 0x984C, 0x6972, - 0x984D, 0x6973, 0x984E, 0x6974, 0x984F, 0x6975, 0x9850, 0x6976, 0x9851, 0x697A, 0x9852, 0x697B, 0x9853, 0x697D, 0x9854, 0x697E, - 0x9855, 0x697F, 0x9856, 0x6981, 0x9857, 0x6983, 0x9858, 0x6985, 0x9859, 0x698A, 0x985A, 0x698B, 0x985B, 0x698C, 0x985C, 0x698E, - 0x985D, 0x698F, 0x985E, 0x6990, 0x985F, 0x6991, 0x9860, 0x6992, 0x9861, 0x6993, 0x9862, 0x6996, 0x9863, 0x6997, 0x9864, 0x6999, - 0x9865, 0x699A, 0x9866, 0x699D, 0x9867, 0x699E, 0x9868, 0x699F, 0x9869, 0x69A0, 0x986A, 0x69A1, 0x986B, 0x69A2, 0x986C, 0x69A3, - 0x986D, 0x69A4, 0x986E, 0x69A5, 0x986F, 0x69A6, 0x9870, 0x69A9, 0x9871, 0x69AA, 0x9872, 0x69AC, 0x9873, 0x69AE, 0x9874, 0x69AF, - 0x9875, 0x69B0, 0x9876, 0x69B2, 0x9877, 0x69B3, 0x9878, 0x69B5, 0x9879, 0x69B6, 0x987A, 0x69B8, 0x987B, 0x69B9, 0x987C, 0x69BA, - 0x987D, 0x69BC, 0x987E, 0x69BD, 0x9880, 0x69BE, 0x9881, 0x69BF, 0x9882, 0x69C0, 0x9883, 0x69C2, 0x9884, 0x69C3, 0x9885, 0x69C4, - 0x9886, 0x69C5, 0x9887, 0x69C6, 0x9888, 0x69C7, 0x9889, 0x69C8, 0x988A, 0x69C9, 0x988B, 0x69CB, 0x988C, 0x69CD, 0x988D, 0x69CF, - 0x988E, 0x69D1, 0x988F, 0x69D2, 0x9890, 0x69D3, 0x9891, 0x69D5, 0x9892, 0x69D6, 0x9893, 0x69D7, 0x9894, 0x69D8, 0x9895, 0x69D9, - 0x9896, 0x69DA, 0x9897, 0x69DC, 0x9898, 0x69DD, 0x9899, 0x69DE, 0x989A, 0x69E1, 0x989B, 0x69E2, 0x989C, 0x69E3, 0x989D, 0x69E4, - 0x989E, 0x69E5, 0x989F, 0x69E6, 0x98A0, 0x69E7, 0x98A1, 0x69E8, 0x98A2, 0x69E9, 0x98A3, 0x69EA, 0x98A4, 0x69EB, 0x98A5, 0x69EC, - 0x98A6, 0x69EE, 0x98A7, 0x69EF, 0x98A8, 0x69F0, 0x98A9, 0x69F1, 0x98AA, 0x69F3, 0x98AB, 0x69F4, 0x98AC, 0x69F5, 0x98AD, 0x69F6, - 0x98AE, 0x69F7, 0x98AF, 0x69F8, 0x98B0, 0x69F9, 0x98B1, 0x69FA, 0x98B2, 0x69FB, 0x98B3, 0x69FC, 0x98B4, 0x69FE, 0x98B5, 0x6A00, - 0x98B6, 0x6A01, 0x98B7, 0x6A02, 0x98B8, 0x6A03, 0x98B9, 0x6A04, 0x98BA, 0x6A05, 0x98BB, 0x6A06, 0x98BC, 0x6A07, 0x98BD, 0x6A08, - 0x98BE, 0x6A09, 0x98BF, 0x6A0B, 0x98C0, 0x6A0C, 0x98C1, 0x6A0D, 0x98C2, 0x6A0E, 0x98C3, 0x6A0F, 0x98C4, 0x6A10, 0x98C5, 0x6A11, - 0x98C6, 0x6A12, 0x98C7, 0x6A13, 0x98C8, 0x6A14, 0x98C9, 0x6A15, 0x98CA, 0x6A16, 0x98CB, 0x6A19, 0x98CC, 0x6A1A, 0x98CD, 0x6A1B, - 0x98CE, 0x6A1C, 0x98CF, 0x6A1D, 0x98D0, 0x6A1E, 0x98D1, 0x6A20, 0x98D2, 0x6A22, 0x98D3, 0x6A23, 0x98D4, 0x6A24, 0x98D5, 0x6A25, - 0x98D6, 0x6A26, 0x98D7, 0x6A27, 0x98D8, 0x6A29, 0x98D9, 0x6A2B, 0x98DA, 0x6A2C, 0x98DB, 0x6A2D, 0x98DC, 0x6A2E, 0x98DD, 0x6A30, - 0x98DE, 0x6A32, 0x98DF, 0x6A33, 0x98E0, 0x6A34, 0x98E1, 0x6A36, 0x98E2, 0x6A37, 0x98E3, 0x6A38, 0x98E4, 0x6A39, 0x98E5, 0x6A3A, - 0x98E6, 0x6A3B, 0x98E7, 0x6A3C, 0x98E8, 0x6A3F, 0x98E9, 0x6A40, 0x98EA, 0x6A41, 0x98EB, 0x6A42, 0x98EC, 0x6A43, 0x98ED, 0x6A45, - 0x98EE, 0x6A46, 0x98EF, 0x6A48, 0x98F0, 0x6A49, 0x98F1, 0x6A4A, 0x98F2, 0x6A4B, 0x98F3, 0x6A4C, 0x98F4, 0x6A4D, 0x98F5, 0x6A4E, - 0x98F6, 0x6A4F, 0x98F7, 0x6A51, 0x98F8, 0x6A52, 0x98F9, 0x6A53, 0x98FA, 0x6A54, 0x98FB, 0x6A55, 0x98FC, 0x6A56, 0x98FD, 0x6A57, - 0x98FE, 0x6A5A, 0x9940, 0x6A5C, 0x9941, 0x6A5D, 0x9942, 0x6A5E, 0x9943, 0x6A5F, 0x9944, 0x6A60, 0x9945, 0x6A62, 0x9946, 0x6A63, - 0x9947, 0x6A64, 0x9948, 0x6A66, 0x9949, 0x6A67, 0x994A, 0x6A68, 0x994B, 0x6A69, 0x994C, 0x6A6A, 0x994D, 0x6A6B, 0x994E, 0x6A6C, - 0x994F, 0x6A6D, 0x9950, 0x6A6E, 0x9951, 0x6A6F, 0x9952, 0x6A70, 0x9953, 0x6A72, 0x9954, 0x6A73, 0x9955, 0x6A74, 0x9956, 0x6A75, - 0x9957, 0x6A76, 0x9958, 0x6A77, 0x9959, 0x6A78, 0x995A, 0x6A7A, 0x995B, 0x6A7B, 0x995C, 0x6A7D, 0x995D, 0x6A7E, 0x995E, 0x6A7F, - 0x995F, 0x6A81, 0x9960, 0x6A82, 0x9961, 0x6A83, 0x9962, 0x6A85, 0x9963, 0x6A86, 0x9964, 0x6A87, 0x9965, 0x6A88, 0x9966, 0x6A89, - 0x9967, 0x6A8A, 0x9968, 0x6A8B, 0x9969, 0x6A8C, 0x996A, 0x6A8D, 0x996B, 0x6A8F, 0x996C, 0x6A92, 0x996D, 0x6A93, 0x996E, 0x6A94, - 0x996F, 0x6A95, 0x9970, 0x6A96, 0x9971, 0x6A98, 0x9972, 0x6A99, 0x9973, 0x6A9A, 0x9974, 0x6A9B, 0x9975, 0x6A9C, 0x9976, 0x6A9D, - 0x9977, 0x6A9E, 0x9978, 0x6A9F, 0x9979, 0x6AA1, 0x997A, 0x6AA2, 0x997B, 0x6AA3, 0x997C, 0x6AA4, 0x997D, 0x6AA5, 0x997E, 0x6AA6, - 0x9980, 0x6AA7, 0x9981, 0x6AA8, 0x9982, 0x6AAA, 0x9983, 0x6AAD, 0x9984, 0x6AAE, 0x9985, 0x6AAF, 0x9986, 0x6AB0, 0x9987, 0x6AB1, - 0x9988, 0x6AB2, 0x9989, 0x6AB3, 0x998A, 0x6AB4, 0x998B, 0x6AB5, 0x998C, 0x6AB6, 0x998D, 0x6AB7, 0x998E, 0x6AB8, 0x998F, 0x6AB9, - 0x9990, 0x6ABA, 0x9991, 0x6ABB, 0x9992, 0x6ABC, 0x9993, 0x6ABD, 0x9994, 0x6ABE, 0x9995, 0x6ABF, 0x9996, 0x6AC0, 0x9997, 0x6AC1, - 0x9998, 0x6AC2, 0x9999, 0x6AC3, 0x999A, 0x6AC4, 0x999B, 0x6AC5, 0x999C, 0x6AC6, 0x999D, 0x6AC7, 0x999E, 0x6AC8, 0x999F, 0x6AC9, - 0x99A0, 0x6ACA, 0x99A1, 0x6ACB, 0x99A2, 0x6ACC, 0x99A3, 0x6ACD, 0x99A4, 0x6ACE, 0x99A5, 0x6ACF, 0x99A6, 0x6AD0, 0x99A7, 0x6AD1, - 0x99A8, 0x6AD2, 0x99A9, 0x6AD3, 0x99AA, 0x6AD4, 0x99AB, 0x6AD5, 0x99AC, 0x6AD6, 0x99AD, 0x6AD7, 0x99AE, 0x6AD8, 0x99AF, 0x6AD9, - 0x99B0, 0x6ADA, 0x99B1, 0x6ADB, 0x99B2, 0x6ADC, 0x99B3, 0x6ADD, 0x99B4, 0x6ADE, 0x99B5, 0x6ADF, 0x99B6, 0x6AE0, 0x99B7, 0x6AE1, - 0x99B8, 0x6AE2, 0x99B9, 0x6AE3, 0x99BA, 0x6AE4, 0x99BB, 0x6AE5, 0x99BC, 0x6AE6, 0x99BD, 0x6AE7, 0x99BE, 0x6AE8, 0x99BF, 0x6AE9, - 0x99C0, 0x6AEA, 0x99C1, 0x6AEB, 0x99C2, 0x6AEC, 0x99C3, 0x6AED, 0x99C4, 0x6AEE, 0x99C5, 0x6AEF, 0x99C6, 0x6AF0, 0x99C7, 0x6AF1, - 0x99C8, 0x6AF2, 0x99C9, 0x6AF3, 0x99CA, 0x6AF4, 0x99CB, 0x6AF5, 0x99CC, 0x6AF6, 0x99CD, 0x6AF7, 0x99CE, 0x6AF8, 0x99CF, 0x6AF9, - 0x99D0, 0x6AFA, 0x99D1, 0x6AFB, 0x99D2, 0x6AFC, 0x99D3, 0x6AFD, 0x99D4, 0x6AFE, 0x99D5, 0x6AFF, 0x99D6, 0x6B00, 0x99D7, 0x6B01, - 0x99D8, 0x6B02, 0x99D9, 0x6B03, 0x99DA, 0x6B04, 0x99DB, 0x6B05, 0x99DC, 0x6B06, 0x99DD, 0x6B07, 0x99DE, 0x6B08, 0x99DF, 0x6B09, - 0x99E0, 0x6B0A, 0x99E1, 0x6B0B, 0x99E2, 0x6B0C, 0x99E3, 0x6B0D, 0x99E4, 0x6B0E, 0x99E5, 0x6B0F, 0x99E6, 0x6B10, 0x99E7, 0x6B11, - 0x99E8, 0x6B12, 0x99E9, 0x6B13, 0x99EA, 0x6B14, 0x99EB, 0x6B15, 0x99EC, 0x6B16, 0x99ED, 0x6B17, 0x99EE, 0x6B18, 0x99EF, 0x6B19, - 0x99F0, 0x6B1A, 0x99F1, 0x6B1B, 0x99F2, 0x6B1C, 0x99F3, 0x6B1D, 0x99F4, 0x6B1E, 0x99F5, 0x6B1F, 0x99F6, 0x6B25, 0x99F7, 0x6B26, - 0x99F8, 0x6B28, 0x99F9, 0x6B29, 0x99FA, 0x6B2A, 0x99FB, 0x6B2B, 0x99FC, 0x6B2C, 0x99FD, 0x6B2D, 0x99FE, 0x6B2E, 0x9A40, 0x6B2F, - 0x9A41, 0x6B30, 0x9A42, 0x6B31, 0x9A43, 0x6B33, 0x9A44, 0x6B34, 0x9A45, 0x6B35, 0x9A46, 0x6B36, 0x9A47, 0x6B38, 0x9A48, 0x6B3B, - 0x9A49, 0x6B3C, 0x9A4A, 0x6B3D, 0x9A4B, 0x6B3F, 0x9A4C, 0x6B40, 0x9A4D, 0x6B41, 0x9A4E, 0x6B42, 0x9A4F, 0x6B44, 0x9A50, 0x6B45, - 0x9A51, 0x6B48, 0x9A52, 0x6B4A, 0x9A53, 0x6B4B, 0x9A54, 0x6B4D, 0x9A55, 0x6B4E, 0x9A56, 0x6B4F, 0x9A57, 0x6B50, 0x9A58, 0x6B51, - 0x9A59, 0x6B52, 0x9A5A, 0x6B53, 0x9A5B, 0x6B54, 0x9A5C, 0x6B55, 0x9A5D, 0x6B56, 0x9A5E, 0x6B57, 0x9A5F, 0x6B58, 0x9A60, 0x6B5A, - 0x9A61, 0x6B5B, 0x9A62, 0x6B5C, 0x9A63, 0x6B5D, 0x9A64, 0x6B5E, 0x9A65, 0x6B5F, 0x9A66, 0x6B60, 0x9A67, 0x6B61, 0x9A68, 0x6B68, - 0x9A69, 0x6B69, 0x9A6A, 0x6B6B, 0x9A6B, 0x6B6C, 0x9A6C, 0x6B6D, 0x9A6D, 0x6B6E, 0x9A6E, 0x6B6F, 0x9A6F, 0x6B70, 0x9A70, 0x6B71, - 0x9A71, 0x6B72, 0x9A72, 0x6B73, 0x9A73, 0x6B74, 0x9A74, 0x6B75, 0x9A75, 0x6B76, 0x9A76, 0x6B77, 0x9A77, 0x6B78, 0x9A78, 0x6B7A, - 0x9A79, 0x6B7D, 0x9A7A, 0x6B7E, 0x9A7B, 0x6B7F, 0x9A7C, 0x6B80, 0x9A7D, 0x6B85, 0x9A7E, 0x6B88, 0x9A80, 0x6B8C, 0x9A81, 0x6B8E, - 0x9A82, 0x6B8F, 0x9A83, 0x6B90, 0x9A84, 0x6B91, 0x9A85, 0x6B94, 0x9A86, 0x6B95, 0x9A87, 0x6B97, 0x9A88, 0x6B98, 0x9A89, 0x6B99, - 0x9A8A, 0x6B9C, 0x9A8B, 0x6B9D, 0x9A8C, 0x6B9E, 0x9A8D, 0x6B9F, 0x9A8E, 0x6BA0, 0x9A8F, 0x6BA2, 0x9A90, 0x6BA3, 0x9A91, 0x6BA4, - 0x9A92, 0x6BA5, 0x9A93, 0x6BA6, 0x9A94, 0x6BA7, 0x9A95, 0x6BA8, 0x9A96, 0x6BA9, 0x9A97, 0x6BAB, 0x9A98, 0x6BAC, 0x9A99, 0x6BAD, - 0x9A9A, 0x6BAE, 0x9A9B, 0x6BAF, 0x9A9C, 0x6BB0, 0x9A9D, 0x6BB1, 0x9A9E, 0x6BB2, 0x9A9F, 0x6BB6, 0x9AA0, 0x6BB8, 0x9AA1, 0x6BB9, - 0x9AA2, 0x6BBA, 0x9AA3, 0x6BBB, 0x9AA4, 0x6BBC, 0x9AA5, 0x6BBD, 0x9AA6, 0x6BBE, 0x9AA7, 0x6BC0, 0x9AA8, 0x6BC3, 0x9AA9, 0x6BC4, - 0x9AAA, 0x6BC6, 0x9AAB, 0x6BC7, 0x9AAC, 0x6BC8, 0x9AAD, 0x6BC9, 0x9AAE, 0x6BCA, 0x9AAF, 0x6BCC, 0x9AB0, 0x6BCE, 0x9AB1, 0x6BD0, - 0x9AB2, 0x6BD1, 0x9AB3, 0x6BD8, 0x9AB4, 0x6BDA, 0x9AB5, 0x6BDC, 0x9AB6, 0x6BDD, 0x9AB7, 0x6BDE, 0x9AB8, 0x6BDF, 0x9AB9, 0x6BE0, - 0x9ABA, 0x6BE2, 0x9ABB, 0x6BE3, 0x9ABC, 0x6BE4, 0x9ABD, 0x6BE5, 0x9ABE, 0x6BE6, 0x9ABF, 0x6BE7, 0x9AC0, 0x6BE8, 0x9AC1, 0x6BE9, - 0x9AC2, 0x6BEC, 0x9AC3, 0x6BED, 0x9AC4, 0x6BEE, 0x9AC5, 0x6BF0, 0x9AC6, 0x6BF1, 0x9AC7, 0x6BF2, 0x9AC8, 0x6BF4, 0x9AC9, 0x6BF6, - 0x9ACA, 0x6BF7, 0x9ACB, 0x6BF8, 0x9ACC, 0x6BFA, 0x9ACD, 0x6BFB, 0x9ACE, 0x6BFC, 0x9ACF, 0x6BFE, 0x9AD0, 0x6BFF, 0x9AD1, 0x6C00, - 0x9AD2, 0x6C01, 0x9AD3, 0x6C02, 0x9AD4, 0x6C03, 0x9AD5, 0x6C04, 0x9AD6, 0x6C08, 0x9AD7, 0x6C09, 0x9AD8, 0x6C0A, 0x9AD9, 0x6C0B, - 0x9ADA, 0x6C0C, 0x9ADB, 0x6C0E, 0x9ADC, 0x6C12, 0x9ADD, 0x6C17, 0x9ADE, 0x6C1C, 0x9ADF, 0x6C1D, 0x9AE0, 0x6C1E, 0x9AE1, 0x6C20, - 0x9AE2, 0x6C23, 0x9AE3, 0x6C25, 0x9AE4, 0x6C2B, 0x9AE5, 0x6C2C, 0x9AE6, 0x6C2D, 0x9AE7, 0x6C31, 0x9AE8, 0x6C33, 0x9AE9, 0x6C36, - 0x9AEA, 0x6C37, 0x9AEB, 0x6C39, 0x9AEC, 0x6C3A, 0x9AED, 0x6C3B, 0x9AEE, 0x6C3C, 0x9AEF, 0x6C3E, 0x9AF0, 0x6C3F, 0x9AF1, 0x6C43, - 0x9AF2, 0x6C44, 0x9AF3, 0x6C45, 0x9AF4, 0x6C48, 0x9AF5, 0x6C4B, 0x9AF6, 0x6C4C, 0x9AF7, 0x6C4D, 0x9AF8, 0x6C4E, 0x9AF9, 0x6C4F, - 0x9AFA, 0x6C51, 0x9AFB, 0x6C52, 0x9AFC, 0x6C53, 0x9AFD, 0x6C56, 0x9AFE, 0x6C58, 0x9B40, 0x6C59, 0x9B41, 0x6C5A, 0x9B42, 0x6C62, - 0x9B43, 0x6C63, 0x9B44, 0x6C65, 0x9B45, 0x6C66, 0x9B46, 0x6C67, 0x9B47, 0x6C6B, 0x9B48, 0x6C6C, 0x9B49, 0x6C6D, 0x9B4A, 0x6C6E, - 0x9B4B, 0x6C6F, 0x9B4C, 0x6C71, 0x9B4D, 0x6C73, 0x9B4E, 0x6C75, 0x9B4F, 0x6C77, 0x9B50, 0x6C78, 0x9B51, 0x6C7A, 0x9B52, 0x6C7B, - 0x9B53, 0x6C7C, 0x9B54, 0x6C7F, 0x9B55, 0x6C80, 0x9B56, 0x6C84, 0x9B57, 0x6C87, 0x9B58, 0x6C8A, 0x9B59, 0x6C8B, 0x9B5A, 0x6C8D, - 0x9B5B, 0x6C8E, 0x9B5C, 0x6C91, 0x9B5D, 0x6C92, 0x9B5E, 0x6C95, 0x9B5F, 0x6C96, 0x9B60, 0x6C97, 0x9B61, 0x6C98, 0x9B62, 0x6C9A, - 0x9B63, 0x6C9C, 0x9B64, 0x6C9D, 0x9B65, 0x6C9E, 0x9B66, 0x6CA0, 0x9B67, 0x6CA2, 0x9B68, 0x6CA8, 0x9B69, 0x6CAC, 0x9B6A, 0x6CAF, - 0x9B6B, 0x6CB0, 0x9B6C, 0x6CB4, 0x9B6D, 0x6CB5, 0x9B6E, 0x6CB6, 0x9B6F, 0x6CB7, 0x9B70, 0x6CBA, 0x9B71, 0x6CC0, 0x9B72, 0x6CC1, - 0x9B73, 0x6CC2, 0x9B74, 0x6CC3, 0x9B75, 0x6CC6, 0x9B76, 0x6CC7, 0x9B77, 0x6CC8, 0x9B78, 0x6CCB, 0x9B79, 0x6CCD, 0x9B7A, 0x6CCE, - 0x9B7B, 0x6CCF, 0x9B7C, 0x6CD1, 0x9B7D, 0x6CD2, 0x9B7E, 0x6CD8, 0x9B80, 0x6CD9, 0x9B81, 0x6CDA, 0x9B82, 0x6CDC, 0x9B83, 0x6CDD, - 0x9B84, 0x6CDF, 0x9B85, 0x6CE4, 0x9B86, 0x6CE6, 0x9B87, 0x6CE7, 0x9B88, 0x6CE9, 0x9B89, 0x6CEC, 0x9B8A, 0x6CED, 0x9B8B, 0x6CF2, - 0x9B8C, 0x6CF4, 0x9B8D, 0x6CF9, 0x9B8E, 0x6CFF, 0x9B8F, 0x6D00, 0x9B90, 0x6D02, 0x9B91, 0x6D03, 0x9B92, 0x6D05, 0x9B93, 0x6D06, - 0x9B94, 0x6D08, 0x9B95, 0x6D09, 0x9B96, 0x6D0A, 0x9B97, 0x6D0D, 0x9B98, 0x6D0F, 0x9B99, 0x6D10, 0x9B9A, 0x6D11, 0x9B9B, 0x6D13, - 0x9B9C, 0x6D14, 0x9B9D, 0x6D15, 0x9B9E, 0x6D16, 0x9B9F, 0x6D18, 0x9BA0, 0x6D1C, 0x9BA1, 0x6D1D, 0x9BA2, 0x6D1F, 0x9BA3, 0x6D20, - 0x9BA4, 0x6D21, 0x9BA5, 0x6D22, 0x9BA6, 0x6D23, 0x9BA7, 0x6D24, 0x9BA8, 0x6D26, 0x9BA9, 0x6D28, 0x9BAA, 0x6D29, 0x9BAB, 0x6D2C, - 0x9BAC, 0x6D2D, 0x9BAD, 0x6D2F, 0x9BAE, 0x6D30, 0x9BAF, 0x6D34, 0x9BB0, 0x6D36, 0x9BB1, 0x6D37, 0x9BB2, 0x6D38, 0x9BB3, 0x6D3A, - 0x9BB4, 0x6D3F, 0x9BB5, 0x6D40, 0x9BB6, 0x6D42, 0x9BB7, 0x6D44, 0x9BB8, 0x6D49, 0x9BB9, 0x6D4C, 0x9BBA, 0x6D50, 0x9BBB, 0x6D55, - 0x9BBC, 0x6D56, 0x9BBD, 0x6D57, 0x9BBE, 0x6D58, 0x9BBF, 0x6D5B, 0x9BC0, 0x6D5D, 0x9BC1, 0x6D5F, 0x9BC2, 0x6D61, 0x9BC3, 0x6D62, - 0x9BC4, 0x6D64, 0x9BC5, 0x6D65, 0x9BC6, 0x6D67, 0x9BC7, 0x6D68, 0x9BC8, 0x6D6B, 0x9BC9, 0x6D6C, 0x9BCA, 0x6D6D, 0x9BCB, 0x6D70, - 0x9BCC, 0x6D71, 0x9BCD, 0x6D72, 0x9BCE, 0x6D73, 0x9BCF, 0x6D75, 0x9BD0, 0x6D76, 0x9BD1, 0x6D79, 0x9BD2, 0x6D7A, 0x9BD3, 0x6D7B, - 0x9BD4, 0x6D7D, 0x9BD5, 0x6D7E, 0x9BD6, 0x6D7F, 0x9BD7, 0x6D80, 0x9BD8, 0x6D81, 0x9BD9, 0x6D83, 0x9BDA, 0x6D84, 0x9BDB, 0x6D86, - 0x9BDC, 0x6D87, 0x9BDD, 0x6D8A, 0x9BDE, 0x6D8B, 0x9BDF, 0x6D8D, 0x9BE0, 0x6D8F, 0x9BE1, 0x6D90, 0x9BE2, 0x6D92, 0x9BE3, 0x6D96, - 0x9BE4, 0x6D97, 0x9BE5, 0x6D98, 0x9BE6, 0x6D99, 0x9BE7, 0x6D9A, 0x9BE8, 0x6D9C, 0x9BE9, 0x6DA2, 0x9BEA, 0x6DA5, 0x9BEB, 0x6DAC, - 0x9BEC, 0x6DAD, 0x9BED, 0x6DB0, 0x9BEE, 0x6DB1, 0x9BEF, 0x6DB3, 0x9BF0, 0x6DB4, 0x9BF1, 0x6DB6, 0x9BF2, 0x6DB7, 0x9BF3, 0x6DB9, - 0x9BF4, 0x6DBA, 0x9BF5, 0x6DBB, 0x9BF6, 0x6DBC, 0x9BF7, 0x6DBD, 0x9BF8, 0x6DBE, 0x9BF9, 0x6DC1, 0x9BFA, 0x6DC2, 0x9BFB, 0x6DC3, - 0x9BFC, 0x6DC8, 0x9BFD, 0x6DC9, 0x9BFE, 0x6DCA, 0x9C40, 0x6DCD, 0x9C41, 0x6DCE, 0x9C42, 0x6DCF, 0x9C43, 0x6DD0, 0x9C44, 0x6DD2, - 0x9C45, 0x6DD3, 0x9C46, 0x6DD4, 0x9C47, 0x6DD5, 0x9C48, 0x6DD7, 0x9C49, 0x6DDA, 0x9C4A, 0x6DDB, 0x9C4B, 0x6DDC, 0x9C4C, 0x6DDF, - 0x9C4D, 0x6DE2, 0x9C4E, 0x6DE3, 0x9C4F, 0x6DE5, 0x9C50, 0x6DE7, 0x9C51, 0x6DE8, 0x9C52, 0x6DE9, 0x9C53, 0x6DEA, 0x9C54, 0x6DED, - 0x9C55, 0x6DEF, 0x9C56, 0x6DF0, 0x9C57, 0x6DF2, 0x9C58, 0x6DF4, 0x9C59, 0x6DF5, 0x9C5A, 0x6DF6, 0x9C5B, 0x6DF8, 0x9C5C, 0x6DFA, - 0x9C5D, 0x6DFD, 0x9C5E, 0x6DFE, 0x9C5F, 0x6DFF, 0x9C60, 0x6E00, 0x9C61, 0x6E01, 0x9C62, 0x6E02, 0x9C63, 0x6E03, 0x9C64, 0x6E04, - 0x9C65, 0x6E06, 0x9C66, 0x6E07, 0x9C67, 0x6E08, 0x9C68, 0x6E09, 0x9C69, 0x6E0B, 0x9C6A, 0x6E0F, 0x9C6B, 0x6E12, 0x9C6C, 0x6E13, - 0x9C6D, 0x6E15, 0x9C6E, 0x6E18, 0x9C6F, 0x6E19, 0x9C70, 0x6E1B, 0x9C71, 0x6E1C, 0x9C72, 0x6E1E, 0x9C73, 0x6E1F, 0x9C74, 0x6E22, - 0x9C75, 0x6E26, 0x9C76, 0x6E27, 0x9C77, 0x6E28, 0x9C78, 0x6E2A, 0x9C79, 0x6E2C, 0x9C7A, 0x6E2E, 0x9C7B, 0x6E30, 0x9C7C, 0x6E31, - 0x9C7D, 0x6E33, 0x9C7E, 0x6E35, 0x9C80, 0x6E36, 0x9C81, 0x6E37, 0x9C82, 0x6E39, 0x9C83, 0x6E3B, 0x9C84, 0x6E3C, 0x9C85, 0x6E3D, - 0x9C86, 0x6E3E, 0x9C87, 0x6E3F, 0x9C88, 0x6E40, 0x9C89, 0x6E41, 0x9C8A, 0x6E42, 0x9C8B, 0x6E45, 0x9C8C, 0x6E46, 0x9C8D, 0x6E47, - 0x9C8E, 0x6E48, 0x9C8F, 0x6E49, 0x9C90, 0x6E4A, 0x9C91, 0x6E4B, 0x9C92, 0x6E4C, 0x9C93, 0x6E4F, 0x9C94, 0x6E50, 0x9C95, 0x6E51, - 0x9C96, 0x6E52, 0x9C97, 0x6E55, 0x9C98, 0x6E57, 0x9C99, 0x6E59, 0x9C9A, 0x6E5A, 0x9C9B, 0x6E5C, 0x9C9C, 0x6E5D, 0x9C9D, 0x6E5E, - 0x9C9E, 0x6E60, 0x9C9F, 0x6E61, 0x9CA0, 0x6E62, 0x9CA1, 0x6E63, 0x9CA2, 0x6E64, 0x9CA3, 0x6E65, 0x9CA4, 0x6E66, 0x9CA5, 0x6E67, - 0x9CA6, 0x6E68, 0x9CA7, 0x6E69, 0x9CA8, 0x6E6A, 0x9CA9, 0x6E6C, 0x9CAA, 0x6E6D, 0x9CAB, 0x6E6F, 0x9CAC, 0x6E70, 0x9CAD, 0x6E71, - 0x9CAE, 0x6E72, 0x9CAF, 0x6E73, 0x9CB0, 0x6E74, 0x9CB1, 0x6E75, 0x9CB2, 0x6E76, 0x9CB3, 0x6E77, 0x9CB4, 0x6E78, 0x9CB5, 0x6E79, - 0x9CB6, 0x6E7A, 0x9CB7, 0x6E7B, 0x9CB8, 0x6E7C, 0x9CB9, 0x6E7D, 0x9CBA, 0x6E80, 0x9CBB, 0x6E81, 0x9CBC, 0x6E82, 0x9CBD, 0x6E84, - 0x9CBE, 0x6E87, 0x9CBF, 0x6E88, 0x9CC0, 0x6E8A, 0x9CC1, 0x6E8B, 0x9CC2, 0x6E8C, 0x9CC3, 0x6E8D, 0x9CC4, 0x6E8E, 0x9CC5, 0x6E91, - 0x9CC6, 0x6E92, 0x9CC7, 0x6E93, 0x9CC8, 0x6E94, 0x9CC9, 0x6E95, 0x9CCA, 0x6E96, 0x9CCB, 0x6E97, 0x9CCC, 0x6E99, 0x9CCD, 0x6E9A, - 0x9CCE, 0x6E9B, 0x9CCF, 0x6E9D, 0x9CD0, 0x6E9E, 0x9CD1, 0x6EA0, 0x9CD2, 0x6EA1, 0x9CD3, 0x6EA3, 0x9CD4, 0x6EA4, 0x9CD5, 0x6EA6, - 0x9CD6, 0x6EA8, 0x9CD7, 0x6EA9, 0x9CD8, 0x6EAB, 0x9CD9, 0x6EAC, 0x9CDA, 0x6EAD, 0x9CDB, 0x6EAE, 0x9CDC, 0x6EB0, 0x9CDD, 0x6EB3, - 0x9CDE, 0x6EB5, 0x9CDF, 0x6EB8, 0x9CE0, 0x6EB9, 0x9CE1, 0x6EBC, 0x9CE2, 0x6EBE, 0x9CE3, 0x6EBF, 0x9CE4, 0x6EC0, 0x9CE5, 0x6EC3, - 0x9CE6, 0x6EC4, 0x9CE7, 0x6EC5, 0x9CE8, 0x6EC6, 0x9CE9, 0x6EC8, 0x9CEA, 0x6EC9, 0x9CEB, 0x6ECA, 0x9CEC, 0x6ECC, 0x9CED, 0x6ECD, - 0x9CEE, 0x6ECE, 0x9CEF, 0x6ED0, 0x9CF0, 0x6ED2, 0x9CF1, 0x6ED6, 0x9CF2, 0x6ED8, 0x9CF3, 0x6ED9, 0x9CF4, 0x6EDB, 0x9CF5, 0x6EDC, - 0x9CF6, 0x6EDD, 0x9CF7, 0x6EE3, 0x9CF8, 0x6EE7, 0x9CF9, 0x6EEA, 0x9CFA, 0x6EEB, 0x9CFB, 0x6EEC, 0x9CFC, 0x6EED, 0x9CFD, 0x6EEE, - 0x9CFE, 0x6EEF, 0x9D40, 0x6EF0, 0x9D41, 0x6EF1, 0x9D42, 0x6EF2, 0x9D43, 0x6EF3, 0x9D44, 0x6EF5, 0x9D45, 0x6EF6, 0x9D46, 0x6EF7, - 0x9D47, 0x6EF8, 0x9D48, 0x6EFA, 0x9D49, 0x6EFB, 0x9D4A, 0x6EFC, 0x9D4B, 0x6EFD, 0x9D4C, 0x6EFE, 0x9D4D, 0x6EFF, 0x9D4E, 0x6F00, - 0x9D4F, 0x6F01, 0x9D50, 0x6F03, 0x9D51, 0x6F04, 0x9D52, 0x6F05, 0x9D53, 0x6F07, 0x9D54, 0x6F08, 0x9D55, 0x6F0A, 0x9D56, 0x6F0B, - 0x9D57, 0x6F0C, 0x9D58, 0x6F0D, 0x9D59, 0x6F0E, 0x9D5A, 0x6F10, 0x9D5B, 0x6F11, 0x9D5C, 0x6F12, 0x9D5D, 0x6F16, 0x9D5E, 0x6F17, - 0x9D5F, 0x6F18, 0x9D60, 0x6F19, 0x9D61, 0x6F1A, 0x9D62, 0x6F1B, 0x9D63, 0x6F1C, 0x9D64, 0x6F1D, 0x9D65, 0x6F1E, 0x9D66, 0x6F1F, - 0x9D67, 0x6F21, 0x9D68, 0x6F22, 0x9D69, 0x6F23, 0x9D6A, 0x6F25, 0x9D6B, 0x6F26, 0x9D6C, 0x6F27, 0x9D6D, 0x6F28, 0x9D6E, 0x6F2C, - 0x9D6F, 0x6F2E, 0x9D70, 0x6F30, 0x9D71, 0x6F32, 0x9D72, 0x6F34, 0x9D73, 0x6F35, 0x9D74, 0x6F37, 0x9D75, 0x6F38, 0x9D76, 0x6F39, - 0x9D77, 0x6F3A, 0x9D78, 0x6F3B, 0x9D79, 0x6F3C, 0x9D7A, 0x6F3D, 0x9D7B, 0x6F3F, 0x9D7C, 0x6F40, 0x9D7D, 0x6F41, 0x9D7E, 0x6F42, - 0x9D80, 0x6F43, 0x9D81, 0x6F44, 0x9D82, 0x6F45, 0x9D83, 0x6F48, 0x9D84, 0x6F49, 0x9D85, 0x6F4A, 0x9D86, 0x6F4C, 0x9D87, 0x6F4E, - 0x9D88, 0x6F4F, 0x9D89, 0x6F50, 0x9D8A, 0x6F51, 0x9D8B, 0x6F52, 0x9D8C, 0x6F53, 0x9D8D, 0x6F54, 0x9D8E, 0x6F55, 0x9D8F, 0x6F56, - 0x9D90, 0x6F57, 0x9D91, 0x6F59, 0x9D92, 0x6F5A, 0x9D93, 0x6F5B, 0x9D94, 0x6F5D, 0x9D95, 0x6F5F, 0x9D96, 0x6F60, 0x9D97, 0x6F61, - 0x9D98, 0x6F63, 0x9D99, 0x6F64, 0x9D9A, 0x6F65, 0x9D9B, 0x6F67, 0x9D9C, 0x6F68, 0x9D9D, 0x6F69, 0x9D9E, 0x6F6A, 0x9D9F, 0x6F6B, - 0x9DA0, 0x6F6C, 0x9DA1, 0x6F6F, 0x9DA2, 0x6F70, 0x9DA3, 0x6F71, 0x9DA4, 0x6F73, 0x9DA5, 0x6F75, 0x9DA6, 0x6F76, 0x9DA7, 0x6F77, - 0x9DA8, 0x6F79, 0x9DA9, 0x6F7B, 0x9DAA, 0x6F7D, 0x9DAB, 0x6F7E, 0x9DAC, 0x6F7F, 0x9DAD, 0x6F80, 0x9DAE, 0x6F81, 0x9DAF, 0x6F82, - 0x9DB0, 0x6F83, 0x9DB1, 0x6F85, 0x9DB2, 0x6F86, 0x9DB3, 0x6F87, 0x9DB4, 0x6F8A, 0x9DB5, 0x6F8B, 0x9DB6, 0x6F8F, 0x9DB7, 0x6F90, - 0x9DB8, 0x6F91, 0x9DB9, 0x6F92, 0x9DBA, 0x6F93, 0x9DBB, 0x6F94, 0x9DBC, 0x6F95, 0x9DBD, 0x6F96, 0x9DBE, 0x6F97, 0x9DBF, 0x6F98, - 0x9DC0, 0x6F99, 0x9DC1, 0x6F9A, 0x9DC2, 0x6F9B, 0x9DC3, 0x6F9D, 0x9DC4, 0x6F9E, 0x9DC5, 0x6F9F, 0x9DC6, 0x6FA0, 0x9DC7, 0x6FA2, - 0x9DC8, 0x6FA3, 0x9DC9, 0x6FA4, 0x9DCA, 0x6FA5, 0x9DCB, 0x6FA6, 0x9DCC, 0x6FA8, 0x9DCD, 0x6FA9, 0x9DCE, 0x6FAA, 0x9DCF, 0x6FAB, - 0x9DD0, 0x6FAC, 0x9DD1, 0x6FAD, 0x9DD2, 0x6FAE, 0x9DD3, 0x6FAF, 0x9DD4, 0x6FB0, 0x9DD5, 0x6FB1, 0x9DD6, 0x6FB2, 0x9DD7, 0x6FB4, - 0x9DD8, 0x6FB5, 0x9DD9, 0x6FB7, 0x9DDA, 0x6FB8, 0x9DDB, 0x6FBA, 0x9DDC, 0x6FBB, 0x9DDD, 0x6FBC, 0x9DDE, 0x6FBD, 0x9DDF, 0x6FBE, - 0x9DE0, 0x6FBF, 0x9DE1, 0x6FC1, 0x9DE2, 0x6FC3, 0x9DE3, 0x6FC4, 0x9DE4, 0x6FC5, 0x9DE5, 0x6FC6, 0x9DE6, 0x6FC7, 0x9DE7, 0x6FC8, - 0x9DE8, 0x6FCA, 0x9DE9, 0x6FCB, 0x9DEA, 0x6FCC, 0x9DEB, 0x6FCD, 0x9DEC, 0x6FCE, 0x9DED, 0x6FCF, 0x9DEE, 0x6FD0, 0x9DEF, 0x6FD3, - 0x9DF0, 0x6FD4, 0x9DF1, 0x6FD5, 0x9DF2, 0x6FD6, 0x9DF3, 0x6FD7, 0x9DF4, 0x6FD8, 0x9DF5, 0x6FD9, 0x9DF6, 0x6FDA, 0x9DF7, 0x6FDB, - 0x9DF8, 0x6FDC, 0x9DF9, 0x6FDD, 0x9DFA, 0x6FDF, 0x9DFB, 0x6FE2, 0x9DFC, 0x6FE3, 0x9DFD, 0x6FE4, 0x9DFE, 0x6FE5, 0x9E40, 0x6FE6, - 0x9E41, 0x6FE7, 0x9E42, 0x6FE8, 0x9E43, 0x6FE9, 0x9E44, 0x6FEA, 0x9E45, 0x6FEB, 0x9E46, 0x6FEC, 0x9E47, 0x6FED, 0x9E48, 0x6FF0, - 0x9E49, 0x6FF1, 0x9E4A, 0x6FF2, 0x9E4B, 0x6FF3, 0x9E4C, 0x6FF4, 0x9E4D, 0x6FF5, 0x9E4E, 0x6FF6, 0x9E4F, 0x6FF7, 0x9E50, 0x6FF8, - 0x9E51, 0x6FF9, 0x9E52, 0x6FFA, 0x9E53, 0x6FFB, 0x9E54, 0x6FFC, 0x9E55, 0x6FFD, 0x9E56, 0x6FFE, 0x9E57, 0x6FFF, 0x9E58, 0x7000, - 0x9E59, 0x7001, 0x9E5A, 0x7002, 0x9E5B, 0x7003, 0x9E5C, 0x7004, 0x9E5D, 0x7005, 0x9E5E, 0x7006, 0x9E5F, 0x7007, 0x9E60, 0x7008, - 0x9E61, 0x7009, 0x9E62, 0x700A, 0x9E63, 0x700B, 0x9E64, 0x700C, 0x9E65, 0x700D, 0x9E66, 0x700E, 0x9E67, 0x700F, 0x9E68, 0x7010, - 0x9E69, 0x7012, 0x9E6A, 0x7013, 0x9E6B, 0x7014, 0x9E6C, 0x7015, 0x9E6D, 0x7016, 0x9E6E, 0x7017, 0x9E6F, 0x7018, 0x9E70, 0x7019, - 0x9E71, 0x701C, 0x9E72, 0x701D, 0x9E73, 0x701E, 0x9E74, 0x701F, 0x9E75, 0x7020, 0x9E76, 0x7021, 0x9E77, 0x7022, 0x9E78, 0x7024, - 0x9E79, 0x7025, 0x9E7A, 0x7026, 0x9E7B, 0x7027, 0x9E7C, 0x7028, 0x9E7D, 0x7029, 0x9E7E, 0x702A, 0x9E80, 0x702B, 0x9E81, 0x702C, - 0x9E82, 0x702D, 0x9E83, 0x702E, 0x9E84, 0x702F, 0x9E85, 0x7030, 0x9E86, 0x7031, 0x9E87, 0x7032, 0x9E88, 0x7033, 0x9E89, 0x7034, - 0x9E8A, 0x7036, 0x9E8B, 0x7037, 0x9E8C, 0x7038, 0x9E8D, 0x703A, 0x9E8E, 0x703B, 0x9E8F, 0x703C, 0x9E90, 0x703D, 0x9E91, 0x703E, - 0x9E92, 0x703F, 0x9E93, 0x7040, 0x9E94, 0x7041, 0x9E95, 0x7042, 0x9E96, 0x7043, 0x9E97, 0x7044, 0x9E98, 0x7045, 0x9E99, 0x7046, - 0x9E9A, 0x7047, 0x9E9B, 0x7048, 0x9E9C, 0x7049, 0x9E9D, 0x704A, 0x9E9E, 0x704B, 0x9E9F, 0x704D, 0x9EA0, 0x704E, 0x9EA1, 0x7050, - 0x9EA2, 0x7051, 0x9EA3, 0x7052, 0x9EA4, 0x7053, 0x9EA5, 0x7054, 0x9EA6, 0x7055, 0x9EA7, 0x7056, 0x9EA8, 0x7057, 0x9EA9, 0x7058, - 0x9EAA, 0x7059, 0x9EAB, 0x705A, 0x9EAC, 0x705B, 0x9EAD, 0x705C, 0x9EAE, 0x705D, 0x9EAF, 0x705F, 0x9EB0, 0x7060, 0x9EB1, 0x7061, - 0x9EB2, 0x7062, 0x9EB3, 0x7063, 0x9EB4, 0x7064, 0x9EB5, 0x7065, 0x9EB6, 0x7066, 0x9EB7, 0x7067, 0x9EB8, 0x7068, 0x9EB9, 0x7069, - 0x9EBA, 0x706A, 0x9EBB, 0x706E, 0x9EBC, 0x7071, 0x9EBD, 0x7072, 0x9EBE, 0x7073, 0x9EBF, 0x7074, 0x9EC0, 0x7077, 0x9EC1, 0x7079, - 0x9EC2, 0x707A, 0x9EC3, 0x707B, 0x9EC4, 0x707D, 0x9EC5, 0x7081, 0x9EC6, 0x7082, 0x9EC7, 0x7083, 0x9EC8, 0x7084, 0x9EC9, 0x7086, - 0x9ECA, 0x7087, 0x9ECB, 0x7088, 0x9ECC, 0x708B, 0x9ECD, 0x708C, 0x9ECE, 0x708D, 0x9ECF, 0x708F, 0x9ED0, 0x7090, 0x9ED1, 0x7091, - 0x9ED2, 0x7093, 0x9ED3, 0x7097, 0x9ED4, 0x7098, 0x9ED5, 0x709A, 0x9ED6, 0x709B, 0x9ED7, 0x709E, 0x9ED8, 0x709F, 0x9ED9, 0x70A0, - 0x9EDA, 0x70A1, 0x9EDB, 0x70A2, 0x9EDC, 0x70A3, 0x9EDD, 0x70A4, 0x9EDE, 0x70A5, 0x9EDF, 0x70A6, 0x9EE0, 0x70A7, 0x9EE1, 0x70A8, - 0x9EE2, 0x70A9, 0x9EE3, 0x70AA, 0x9EE4, 0x70B0, 0x9EE5, 0x70B2, 0x9EE6, 0x70B4, 0x9EE7, 0x70B5, 0x9EE8, 0x70B6, 0x9EE9, 0x70BA, - 0x9EEA, 0x70BE, 0x9EEB, 0x70BF, 0x9EEC, 0x70C4, 0x9EED, 0x70C5, 0x9EEE, 0x70C6, 0x9EEF, 0x70C7, 0x9EF0, 0x70C9, 0x9EF1, 0x70CB, - 0x9EF2, 0x70CC, 0x9EF3, 0x70CD, 0x9EF4, 0x70CE, 0x9EF5, 0x70CF, 0x9EF6, 0x70D0, 0x9EF7, 0x70D1, 0x9EF8, 0x70D2, 0x9EF9, 0x70D3, - 0x9EFA, 0x70D4, 0x9EFB, 0x70D5, 0x9EFC, 0x70D6, 0x9EFD, 0x70D7, 0x9EFE, 0x70DA, 0x9F40, 0x70DC, 0x9F41, 0x70DD, 0x9F42, 0x70DE, - 0x9F43, 0x70E0, 0x9F44, 0x70E1, 0x9F45, 0x70E2, 0x9F46, 0x70E3, 0x9F47, 0x70E5, 0x9F48, 0x70EA, 0x9F49, 0x70EE, 0x9F4A, 0x70F0, - 0x9F4B, 0x70F1, 0x9F4C, 0x70F2, 0x9F4D, 0x70F3, 0x9F4E, 0x70F4, 0x9F4F, 0x70F5, 0x9F50, 0x70F6, 0x9F51, 0x70F8, 0x9F52, 0x70FA, - 0x9F53, 0x70FB, 0x9F54, 0x70FC, 0x9F55, 0x70FE, 0x9F56, 0x70FF, 0x9F57, 0x7100, 0x9F58, 0x7101, 0x9F59, 0x7102, 0x9F5A, 0x7103, - 0x9F5B, 0x7104, 0x9F5C, 0x7105, 0x9F5D, 0x7106, 0x9F5E, 0x7107, 0x9F5F, 0x7108, 0x9F60, 0x710B, 0x9F61, 0x710C, 0x9F62, 0x710D, - 0x9F63, 0x710E, 0x9F64, 0x710F, 0x9F65, 0x7111, 0x9F66, 0x7112, 0x9F67, 0x7114, 0x9F68, 0x7117, 0x9F69, 0x711B, 0x9F6A, 0x711C, - 0x9F6B, 0x711D, 0x9F6C, 0x711E, 0x9F6D, 0x711F, 0x9F6E, 0x7120, 0x9F6F, 0x7121, 0x9F70, 0x7122, 0x9F71, 0x7123, 0x9F72, 0x7124, - 0x9F73, 0x7125, 0x9F74, 0x7127, 0x9F75, 0x7128, 0x9F76, 0x7129, 0x9F77, 0x712A, 0x9F78, 0x712B, 0x9F79, 0x712C, 0x9F7A, 0x712D, - 0x9F7B, 0x712E, 0x9F7C, 0x7132, 0x9F7D, 0x7133, 0x9F7E, 0x7134, 0x9F80, 0x7135, 0x9F81, 0x7137, 0x9F82, 0x7138, 0x9F83, 0x7139, - 0x9F84, 0x713A, 0x9F85, 0x713B, 0x9F86, 0x713C, 0x9F87, 0x713D, 0x9F88, 0x713E, 0x9F89, 0x713F, 0x9F8A, 0x7140, 0x9F8B, 0x7141, - 0x9F8C, 0x7142, 0x9F8D, 0x7143, 0x9F8E, 0x7144, 0x9F8F, 0x7146, 0x9F90, 0x7147, 0x9F91, 0x7148, 0x9F92, 0x7149, 0x9F93, 0x714B, - 0x9F94, 0x714D, 0x9F95, 0x714F, 0x9F96, 0x7150, 0x9F97, 0x7151, 0x9F98, 0x7152, 0x9F99, 0x7153, 0x9F9A, 0x7154, 0x9F9B, 0x7155, - 0x9F9C, 0x7156, 0x9F9D, 0x7157, 0x9F9E, 0x7158, 0x9F9F, 0x7159, 0x9FA0, 0x715A, 0x9FA1, 0x715B, 0x9FA2, 0x715D, 0x9FA3, 0x715F, - 0x9FA4, 0x7160, 0x9FA5, 0x7161, 0x9FA6, 0x7162, 0x9FA7, 0x7163, 0x9FA8, 0x7165, 0x9FA9, 0x7169, 0x9FAA, 0x716A, 0x9FAB, 0x716B, - 0x9FAC, 0x716C, 0x9FAD, 0x716D, 0x9FAE, 0x716F, 0x9FAF, 0x7170, 0x9FB0, 0x7171, 0x9FB1, 0x7174, 0x9FB2, 0x7175, 0x9FB3, 0x7176, - 0x9FB4, 0x7177, 0x9FB5, 0x7179, 0x9FB6, 0x717B, 0x9FB7, 0x717C, 0x9FB8, 0x717E, 0x9FB9, 0x717F, 0x9FBA, 0x7180, 0x9FBB, 0x7181, - 0x9FBC, 0x7182, 0x9FBD, 0x7183, 0x9FBE, 0x7185, 0x9FBF, 0x7186, 0x9FC0, 0x7187, 0x9FC1, 0x7188, 0x9FC2, 0x7189, 0x9FC3, 0x718B, - 0x9FC4, 0x718C, 0x9FC5, 0x718D, 0x9FC6, 0x718E, 0x9FC7, 0x7190, 0x9FC8, 0x7191, 0x9FC9, 0x7192, 0x9FCA, 0x7193, 0x9FCB, 0x7195, - 0x9FCC, 0x7196, 0x9FCD, 0x7197, 0x9FCE, 0x719A, 0x9FCF, 0x719B, 0x9FD0, 0x719C, 0x9FD1, 0x719D, 0x9FD2, 0x719E, 0x9FD3, 0x71A1, - 0x9FD4, 0x71A2, 0x9FD5, 0x71A3, 0x9FD6, 0x71A4, 0x9FD7, 0x71A5, 0x9FD8, 0x71A6, 0x9FD9, 0x71A7, 0x9FDA, 0x71A9, 0x9FDB, 0x71AA, - 0x9FDC, 0x71AB, 0x9FDD, 0x71AD, 0x9FDE, 0x71AE, 0x9FDF, 0x71AF, 0x9FE0, 0x71B0, 0x9FE1, 0x71B1, 0x9FE2, 0x71B2, 0x9FE3, 0x71B4, - 0x9FE4, 0x71B6, 0x9FE5, 0x71B7, 0x9FE6, 0x71B8, 0x9FE7, 0x71BA, 0x9FE8, 0x71BB, 0x9FE9, 0x71BC, 0x9FEA, 0x71BD, 0x9FEB, 0x71BE, - 0x9FEC, 0x71BF, 0x9FED, 0x71C0, 0x9FEE, 0x71C1, 0x9FEF, 0x71C2, 0x9FF0, 0x71C4, 0x9FF1, 0x71C5, 0x9FF2, 0x71C6, 0x9FF3, 0x71C7, - 0x9FF4, 0x71C8, 0x9FF5, 0x71C9, 0x9FF6, 0x71CA, 0x9FF7, 0x71CB, 0x9FF8, 0x71CC, 0x9FF9, 0x71CD, 0x9FFA, 0x71CF, 0x9FFB, 0x71D0, - 0x9FFC, 0x71D1, 0x9FFD, 0x71D2, 0x9FFE, 0x71D3, 0xA040, 0x71D6, 0xA041, 0x71D7, 0xA042, 0x71D8, 0xA043, 0x71D9, 0xA044, 0x71DA, - 0xA045, 0x71DB, 0xA046, 0x71DC, 0xA047, 0x71DD, 0xA048, 0x71DE, 0xA049, 0x71DF, 0xA04A, 0x71E1, 0xA04B, 0x71E2, 0xA04C, 0x71E3, - 0xA04D, 0x71E4, 0xA04E, 0x71E6, 0xA04F, 0x71E8, 0xA050, 0x71E9, 0xA051, 0x71EA, 0xA052, 0x71EB, 0xA053, 0x71EC, 0xA054, 0x71ED, - 0xA055, 0x71EF, 0xA056, 0x71F0, 0xA057, 0x71F1, 0xA058, 0x71F2, 0xA059, 0x71F3, 0xA05A, 0x71F4, 0xA05B, 0x71F5, 0xA05C, 0x71F6, - 0xA05D, 0x71F7, 0xA05E, 0x71F8, 0xA05F, 0x71FA, 0xA060, 0x71FB, 0xA061, 0x71FC, 0xA062, 0x71FD, 0xA063, 0x71FE, 0xA064, 0x71FF, - 0xA065, 0x7200, 0xA066, 0x7201, 0xA067, 0x7202, 0xA068, 0x7203, 0xA069, 0x7204, 0xA06A, 0x7205, 0xA06B, 0x7207, 0xA06C, 0x7208, - 0xA06D, 0x7209, 0xA06E, 0x720A, 0xA06F, 0x720B, 0xA070, 0x720C, 0xA071, 0x720D, 0xA072, 0x720E, 0xA073, 0x720F, 0xA074, 0x7210, - 0xA075, 0x7211, 0xA076, 0x7212, 0xA077, 0x7213, 0xA078, 0x7214, 0xA079, 0x7215, 0xA07A, 0x7216, 0xA07B, 0x7217, 0xA07C, 0x7218, - 0xA07D, 0x7219, 0xA07E, 0x721A, 0xA080, 0x721B, 0xA081, 0x721C, 0xA082, 0x721E, 0xA083, 0x721F, 0xA084, 0x7220, 0xA085, 0x7221, - 0xA086, 0x7222, 0xA087, 0x7223, 0xA088, 0x7224, 0xA089, 0x7225, 0xA08A, 0x7226, 0xA08B, 0x7227, 0xA08C, 0x7229, 0xA08D, 0x722B, - 0xA08E, 0x722D, 0xA08F, 0x722E, 0xA090, 0x722F, 0xA091, 0x7232, 0xA092, 0x7233, 0xA093, 0x7234, 0xA094, 0x723A, 0xA095, 0x723C, - 0xA096, 0x723E, 0xA097, 0x7240, 0xA098, 0x7241, 0xA099, 0x7242, 0xA09A, 0x7243, 0xA09B, 0x7244, 0xA09C, 0x7245, 0xA09D, 0x7246, - 0xA09E, 0x7249, 0xA09F, 0x724A, 0xA0A0, 0x724B, 0xA0A1, 0x724E, 0xA0A2, 0x724F, 0xA0A3, 0x7250, 0xA0A4, 0x7251, 0xA0A5, 0x7253, - 0xA0A6, 0x7254, 0xA0A7, 0x7255, 0xA0A8, 0x7257, 0xA0A9, 0x7258, 0xA0AA, 0x725A, 0xA0AB, 0x725C, 0xA0AC, 0x725E, 0xA0AD, 0x7260, - 0xA0AE, 0x7263, 0xA0AF, 0x7264, 0xA0B0, 0x7265, 0xA0B1, 0x7268, 0xA0B2, 0x726A, 0xA0B3, 0x726B, 0xA0B4, 0x726C, 0xA0B5, 0x726D, - 0xA0B6, 0x7270, 0xA0B7, 0x7271, 0xA0B8, 0x7273, 0xA0B9, 0x7274, 0xA0BA, 0x7276, 0xA0BB, 0x7277, 0xA0BC, 0x7278, 0xA0BD, 0x727B, - 0xA0BE, 0x727C, 0xA0BF, 0x727D, 0xA0C0, 0x7282, 0xA0C1, 0x7283, 0xA0C2, 0x7285, 0xA0C3, 0x7286, 0xA0C4, 0x7287, 0xA0C5, 0x7288, - 0xA0C6, 0x7289, 0xA0C7, 0x728C, 0xA0C8, 0x728E, 0xA0C9, 0x7290, 0xA0CA, 0x7291, 0xA0CB, 0x7293, 0xA0CC, 0x7294, 0xA0CD, 0x7295, - 0xA0CE, 0x7296, 0xA0CF, 0x7297, 0xA0D0, 0x7298, 0xA0D1, 0x7299, 0xA0D2, 0x729A, 0xA0D3, 0x729B, 0xA0D4, 0x729C, 0xA0D5, 0x729D, - 0xA0D6, 0x729E, 0xA0D7, 0x72A0, 0xA0D8, 0x72A1, 0xA0D9, 0x72A2, 0xA0DA, 0x72A3, 0xA0DB, 0x72A4, 0xA0DC, 0x72A5, 0xA0DD, 0x72A6, - 0xA0DE, 0x72A7, 0xA0DF, 0x72A8, 0xA0E0, 0x72A9, 0xA0E1, 0x72AA, 0xA0E2, 0x72AB, 0xA0E3, 0x72AE, 0xA0E4, 0x72B1, 0xA0E5, 0x72B2, - 0xA0E6, 0x72B3, 0xA0E7, 0x72B5, 0xA0E8, 0x72BA, 0xA0E9, 0x72BB, 0xA0EA, 0x72BC, 0xA0EB, 0x72BD, 0xA0EC, 0x72BE, 0xA0ED, 0x72BF, - 0xA0EE, 0x72C0, 0xA0EF, 0x72C5, 0xA0F0, 0x72C6, 0xA0F1, 0x72C7, 0xA0F2, 0x72C9, 0xA0F3, 0x72CA, 0xA0F4, 0x72CB, 0xA0F5, 0x72CC, - 0xA0F6, 0x72CF, 0xA0F7, 0x72D1, 0xA0F8, 0x72D3, 0xA0F9, 0x72D4, 0xA0FA, 0x72D5, 0xA0FB, 0x72D6, 0xA0FC, 0x72D8, 0xA0FD, 0x72DA, - 0xA0FE, 0x72DB, 0xA1A1, 0x3000, 0xA1A2, 0x3001, 0xA1A3, 0x3002, 0xA1A4, 0x00B7, 0xA1A5, 0x02C9, 0xA1A6, 0x02C7, 0xA1A7, 0x00A8, - 0xA1A8, 0x3003, 0xA1A9, 0x3005, 0xA1AA, 0x2014, 0xA1AB, 0xFF5E, 0xA1AC, 0x2016, 0xA1AD, 0x2026, 0xA1AE, 0x2018, 0xA1AF, 0x2019, - 0xA1B0, 0x201C, 0xA1B1, 0x201D, 0xA1B2, 0x3014, 0xA1B3, 0x3015, 0xA1B4, 0x3008, 0xA1B5, 0x3009, 0xA1B6, 0x300A, 0xA1B7, 0x300B, - 0xA1B8, 0x300C, 0xA1B9, 0x300D, 0xA1BA, 0x300E, 0xA1BB, 0x300F, 0xA1BC, 0x3016, 0xA1BD, 0x3017, 0xA1BE, 0x3010, 0xA1BF, 0x3011, - 0xA1C0, 0x00B1, 0xA1C1, 0x00D7, 0xA1C2, 0x00F7, 0xA1C3, 0x2236, 0xA1C4, 0x2227, 0xA1C5, 0x2228, 0xA1C6, 0x2211, 0xA1C7, 0x220F, - 0xA1C8, 0x222A, 0xA1C9, 0x2229, 0xA1CA, 0x2208, 0xA1CB, 0x2237, 0xA1CC, 0x221A, 0xA1CD, 0x22A5, 0xA1CE, 0x2225, 0xA1CF, 0x2220, - 0xA1D0, 0x2312, 0xA1D1, 0x2299, 0xA1D2, 0x222B, 0xA1D3, 0x222E, 0xA1D4, 0x2261, 0xA1D5, 0x224C, 0xA1D6, 0x2248, 0xA1D7, 0x223D, - 0xA1D8, 0x221D, 0xA1D9, 0x2260, 0xA1DA, 0x226E, 0xA1DB, 0x226F, 0xA1DC, 0x2264, 0xA1DD, 0x2265, 0xA1DE, 0x221E, 0xA1DF, 0x2235, - 0xA1E0, 0x2234, 0xA1E1, 0x2642, 0xA1E2, 0x2640, 0xA1E3, 0x00B0, 0xA1E4, 0x2032, 0xA1E5, 0x2033, 0xA1E6, 0x2103, 0xA1E7, 0xFF04, - 0xA1E8, 0x00A4, 0xA1E9, 0xFFE0, 0xA1EA, 0xFFE1, 0xA1EB, 0x2030, 0xA1EC, 0x00A7, 0xA1ED, 0x2116, 0xA1EE, 0x2606, 0xA1EF, 0x2605, - 0xA1F0, 0x25CB, 0xA1F1, 0x25CF, 0xA1F2, 0x25CE, 0xA1F3, 0x25C7, 0xA1F4, 0x25C6, 0xA1F5, 0x25A1, 0xA1F6, 0x25A0, 0xA1F7, 0x25B3, - 0xA1F8, 0x25B2, 0xA1F9, 0x203B, 0xA1FA, 0x2192, 0xA1FB, 0x2190, 0xA1FC, 0x2191, 0xA1FD, 0x2193, 0xA1FE, 0x3013, 0xA2A1, 0x2170, - 0xA2A2, 0x2171, 0xA2A3, 0x2172, 0xA2A4, 0x2173, 0xA2A5, 0x2174, 0xA2A6, 0x2175, 0xA2A7, 0x2176, 0xA2A8, 0x2177, 0xA2A9, 0x2178, - 0xA2AA, 0x2179, 0xA2B1, 0x2488, 0xA2B2, 0x2489, 0xA2B3, 0x248A, 0xA2B4, 0x248B, 0xA2B5, 0x248C, 0xA2B6, 0x248D, 0xA2B7, 0x248E, - 0xA2B8, 0x248F, 0xA2B9, 0x2490, 0xA2BA, 0x2491, 0xA2BB, 0x2492, 0xA2BC, 0x2493, 0xA2BD, 0x2494, 0xA2BE, 0x2495, 0xA2BF, 0x2496, - 0xA2C0, 0x2497, 0xA2C1, 0x2498, 0xA2C2, 0x2499, 0xA2C3, 0x249A, 0xA2C4, 0x249B, 0xA2C5, 0x2474, 0xA2C6, 0x2475, 0xA2C7, 0x2476, - 0xA2C8, 0x2477, 0xA2C9, 0x2478, 0xA2CA, 0x2479, 0xA2CB, 0x247A, 0xA2CC, 0x247B, 0xA2CD, 0x247C, 0xA2CE, 0x247D, 0xA2CF, 0x247E, - 0xA2D0, 0x247F, 0xA2D1, 0x2480, 0xA2D2, 0x2481, 0xA2D3, 0x2482, 0xA2D4, 0x2483, 0xA2D5, 0x2484, 0xA2D6, 0x2485, 0xA2D7, 0x2486, - 0xA2D8, 0x2487, 0xA2D9, 0x2460, 0xA2DA, 0x2461, 0xA2DB, 0x2462, 0xA2DC, 0x2463, 0xA2DD, 0x2464, 0xA2DE, 0x2465, 0xA2DF, 0x2466, - 0xA2E0, 0x2467, 0xA2E1, 0x2468, 0xA2E2, 0x2469, 0xA2E5, 0x3220, 0xA2E6, 0x3221, 0xA2E7, 0x3222, 0xA2E8, 0x3223, 0xA2E9, 0x3224, - 0xA2EA, 0x3225, 0xA2EB, 0x3226, 0xA2EC, 0x3227, 0xA2ED, 0x3228, 0xA2EE, 0x3229, 0xA2F1, 0x2160, 0xA2F2, 0x2161, 0xA2F3, 0x2162, - 0xA2F4, 0x2163, 0xA2F5, 0x2164, 0xA2F6, 0x2165, 0xA2F7, 0x2166, 0xA2F8, 0x2167, 0xA2F9, 0x2168, 0xA2FA, 0x2169, 0xA2FB, 0x216A, - 0xA2FC, 0x216B, 0xA3A1, 0xFF01, 0xA3A2, 0xFF02, 0xA3A3, 0xFF03, 0xA3A4, 0xFFE5, 0xA3A5, 0xFF05, 0xA3A6, 0xFF06, 0xA3A7, 0xFF07, - 0xA3A8, 0xFF08, 0xA3A9, 0xFF09, 0xA3AA, 0xFF0A, 0xA3AB, 0xFF0B, 0xA3AC, 0xFF0C, 0xA3AD, 0xFF0D, 0xA3AE, 0xFF0E, 0xA3AF, 0xFF0F, - 0xA3B0, 0xFF10, 0xA3B1, 0xFF11, 0xA3B2, 0xFF12, 0xA3B3, 0xFF13, 0xA3B4, 0xFF14, 0xA3B5, 0xFF15, 0xA3B6, 0xFF16, 0xA3B7, 0xFF17, - 0xA3B8, 0xFF18, 0xA3B9, 0xFF19, 0xA3BA, 0xFF1A, 0xA3BB, 0xFF1B, 0xA3BC, 0xFF1C, 0xA3BD, 0xFF1D, 0xA3BE, 0xFF1E, 0xA3BF, 0xFF1F, - 0xA3C0, 0xFF20, 0xA3C1, 0xFF21, 0xA3C2, 0xFF22, 0xA3C3, 0xFF23, 0xA3C4, 0xFF24, 0xA3C5, 0xFF25, 0xA3C6, 0xFF26, 0xA3C7, 0xFF27, - 0xA3C8, 0xFF28, 0xA3C9, 0xFF29, 0xA3CA, 0xFF2A, 0xA3CB, 0xFF2B, 0xA3CC, 0xFF2C, 0xA3CD, 0xFF2D, 0xA3CE, 0xFF2E, 0xA3CF, 0xFF2F, - 0xA3D0, 0xFF30, 0xA3D1, 0xFF31, 0xA3D2, 0xFF32, 0xA3D3, 0xFF33, 0xA3D4, 0xFF34, 0xA3D5, 0xFF35, 0xA3D6, 0xFF36, 0xA3D7, 0xFF37, - 0xA3D8, 0xFF38, 0xA3D9, 0xFF39, 0xA3DA, 0xFF3A, 0xA3DB, 0xFF3B, 0xA3DC, 0xFF3C, 0xA3DD, 0xFF3D, 0xA3DE, 0xFF3E, 0xA3DF, 0xFF3F, - 0xA3E0, 0xFF40, 0xA3E1, 0xFF41, 0xA3E2, 0xFF42, 0xA3E3, 0xFF43, 0xA3E4, 0xFF44, 0xA3E5, 0xFF45, 0xA3E6, 0xFF46, 0xA3E7, 0xFF47, - 0xA3E8, 0xFF48, 0xA3E9, 0xFF49, 0xA3EA, 0xFF4A, 0xA3EB, 0xFF4B, 0xA3EC, 0xFF4C, 0xA3ED, 0xFF4D, 0xA3EE, 0xFF4E, 0xA3EF, 0xFF4F, - 0xA3F0, 0xFF50, 0xA3F1, 0xFF51, 0xA3F2, 0xFF52, 0xA3F3, 0xFF53, 0xA3F4, 0xFF54, 0xA3F5, 0xFF55, 0xA3F6, 0xFF56, 0xA3F7, 0xFF57, - 0xA3F8, 0xFF58, 0xA3F9, 0xFF59, 0xA3FA, 0xFF5A, 0xA3FB, 0xFF5B, 0xA3FC, 0xFF5C, 0xA3FD, 0xFF5D, 0xA3FE, 0xFFE3, 0xA4A1, 0x3041, - 0xA4A2, 0x3042, 0xA4A3, 0x3043, 0xA4A4, 0x3044, 0xA4A5, 0x3045, 0xA4A6, 0x3046, 0xA4A7, 0x3047, 0xA4A8, 0x3048, 0xA4A9, 0x3049, - 0xA4AA, 0x304A, 0xA4AB, 0x304B, 0xA4AC, 0x304C, 0xA4AD, 0x304D, 0xA4AE, 0x304E, 0xA4AF, 0x304F, 0xA4B0, 0x3050, 0xA4B1, 0x3051, - 0xA4B2, 0x3052, 0xA4B3, 0x3053, 0xA4B4, 0x3054, 0xA4B5, 0x3055, 0xA4B6, 0x3056, 0xA4B7, 0x3057, 0xA4B8, 0x3058, 0xA4B9, 0x3059, - 0xA4BA, 0x305A, 0xA4BB, 0x305B, 0xA4BC, 0x305C, 0xA4BD, 0x305D, 0xA4BE, 0x305E, 0xA4BF, 0x305F, 0xA4C0, 0x3060, 0xA4C1, 0x3061, - 0xA4C2, 0x3062, 0xA4C3, 0x3063, 0xA4C4, 0x3064, 0xA4C5, 0x3065, 0xA4C6, 0x3066, 0xA4C7, 0x3067, 0xA4C8, 0x3068, 0xA4C9, 0x3069, - 0xA4CA, 0x306A, 0xA4CB, 0x306B, 0xA4CC, 0x306C, 0xA4CD, 0x306D, 0xA4CE, 0x306E, 0xA4CF, 0x306F, 0xA4D0, 0x3070, 0xA4D1, 0x3071, - 0xA4D2, 0x3072, 0xA4D3, 0x3073, 0xA4D4, 0x3074, 0xA4D5, 0x3075, 0xA4D6, 0x3076, 0xA4D7, 0x3077, 0xA4D8, 0x3078, 0xA4D9, 0x3079, - 0xA4DA, 0x307A, 0xA4DB, 0x307B, 0xA4DC, 0x307C, 0xA4DD, 0x307D, 0xA4DE, 0x307E, 0xA4DF, 0x307F, 0xA4E0, 0x3080, 0xA4E1, 0x3081, - 0xA4E2, 0x3082, 0xA4E3, 0x3083, 0xA4E4, 0x3084, 0xA4E5, 0x3085, 0xA4E6, 0x3086, 0xA4E7, 0x3087, 0xA4E8, 0x3088, 0xA4E9, 0x3089, - 0xA4EA, 0x308A, 0xA4EB, 0x308B, 0xA4EC, 0x308C, 0xA4ED, 0x308D, 0xA4EE, 0x308E, 0xA4EF, 0x308F, 0xA4F0, 0x3090, 0xA4F1, 0x3091, - 0xA4F2, 0x3092, 0xA4F3, 0x3093, 0xA5A1, 0x30A1, 0xA5A2, 0x30A2, 0xA5A3, 0x30A3, 0xA5A4, 0x30A4, 0xA5A5, 0x30A5, 0xA5A6, 0x30A6, - 0xA5A7, 0x30A7, 0xA5A8, 0x30A8, 0xA5A9, 0x30A9, 0xA5AA, 0x30AA, 0xA5AB, 0x30AB, 0xA5AC, 0x30AC, 0xA5AD, 0x30AD, 0xA5AE, 0x30AE, - 0xA5AF, 0x30AF, 0xA5B0, 0x30B0, 0xA5B1, 0x30B1, 0xA5B2, 0x30B2, 0xA5B3, 0x30B3, 0xA5B4, 0x30B4, 0xA5B5, 0x30B5, 0xA5B6, 0x30B6, - 0xA5B7, 0x30B7, 0xA5B8, 0x30B8, 0xA5B9, 0x30B9, 0xA5BA, 0x30BA, 0xA5BB, 0x30BB, 0xA5BC, 0x30BC, 0xA5BD, 0x30BD, 0xA5BE, 0x30BE, - 0xA5BF, 0x30BF, 0xA5C0, 0x30C0, 0xA5C1, 0x30C1, 0xA5C2, 0x30C2, 0xA5C3, 0x30C3, 0xA5C4, 0x30C4, 0xA5C5, 0x30C5, 0xA5C6, 0x30C6, - 0xA5C7, 0x30C7, 0xA5C8, 0x30C8, 0xA5C9, 0x30C9, 0xA5CA, 0x30CA, 0xA5CB, 0x30CB, 0xA5CC, 0x30CC, 0xA5CD, 0x30CD, 0xA5CE, 0x30CE, - 0xA5CF, 0x30CF, 0xA5D0, 0x30D0, 0xA5D1, 0x30D1, 0xA5D2, 0x30D2, 0xA5D3, 0x30D3, 0xA5D4, 0x30D4, 0xA5D5, 0x30D5, 0xA5D6, 0x30D6, - 0xA5D7, 0x30D7, 0xA5D8, 0x30D8, 0xA5D9, 0x30D9, 0xA5DA, 0x30DA, 0xA5DB, 0x30DB, 0xA5DC, 0x30DC, 0xA5DD, 0x30DD, 0xA5DE, 0x30DE, - 0xA5DF, 0x30DF, 0xA5E0, 0x30E0, 0xA5E1, 0x30E1, 0xA5E2, 0x30E2, 0xA5E3, 0x30E3, 0xA5E4, 0x30E4, 0xA5E5, 0x30E5, 0xA5E6, 0x30E6, - 0xA5E7, 0x30E7, 0xA5E8, 0x30E8, 0xA5E9, 0x30E9, 0xA5EA, 0x30EA, 0xA5EB, 0x30EB, 0xA5EC, 0x30EC, 0xA5ED, 0x30ED, 0xA5EE, 0x30EE, - 0xA5EF, 0x30EF, 0xA5F0, 0x30F0, 0xA5F1, 0x30F1, 0xA5F2, 0x30F2, 0xA5F3, 0x30F3, 0xA5F4, 0x30F4, 0xA5F5, 0x30F5, 0xA5F6, 0x30F6, - 0xA6A1, 0x0391, 0xA6A2, 0x0392, 0xA6A3, 0x0393, 0xA6A4, 0x0394, 0xA6A5, 0x0395, 0xA6A6, 0x0396, 0xA6A7, 0x0397, 0xA6A8, 0x0398, - 0xA6A9, 0x0399, 0xA6AA, 0x039A, 0xA6AB, 0x039B, 0xA6AC, 0x039C, 0xA6AD, 0x039D, 0xA6AE, 0x039E, 0xA6AF, 0x039F, 0xA6B0, 0x03A0, - 0xA6B1, 0x03A1, 0xA6B2, 0x03A3, 0xA6B3, 0x03A4, 0xA6B4, 0x03A5, 0xA6B5, 0x03A6, 0xA6B6, 0x03A7, 0xA6B7, 0x03A8, 0xA6B8, 0x03A9, - 0xA6C1, 0x03B1, 0xA6C2, 0x03B2, 0xA6C3, 0x03B3, 0xA6C4, 0x03B4, 0xA6C5, 0x03B5, 0xA6C6, 0x03B6, 0xA6C7, 0x03B7, 0xA6C8, 0x03B8, - 0xA6C9, 0x03B9, 0xA6CA, 0x03BA, 0xA6CB, 0x03BB, 0xA6CC, 0x03BC, 0xA6CD, 0x03BD, 0xA6CE, 0x03BE, 0xA6CF, 0x03BF, 0xA6D0, 0x03C0, - 0xA6D1, 0x03C1, 0xA6D2, 0x03C3, 0xA6D3, 0x03C4, 0xA6D4, 0x03C5, 0xA6D5, 0x03C6, 0xA6D6, 0x03C7, 0xA6D7, 0x03C8, 0xA6D8, 0x03C9, - 0xA6E0, 0xFE35, 0xA6E1, 0xFE36, 0xA6E2, 0xFE39, 0xA6E3, 0xFE3A, 0xA6E4, 0xFE3F, 0xA6E5, 0xFE40, 0xA6E6, 0xFE3D, 0xA6E7, 0xFE3E, - 0xA6E8, 0xFE41, 0xA6E9, 0xFE42, 0xA6EA, 0xFE43, 0xA6EB, 0xFE44, 0xA6EE, 0xFE3B, 0xA6EF, 0xFE3C, 0xA6F0, 0xFE37, 0xA6F1, 0xFE38, - 0xA6F2, 0xFE31, 0xA6F4, 0xFE33, 0xA6F5, 0xFE34, 0xA7A1, 0x0410, 0xA7A2, 0x0411, 0xA7A3, 0x0412, 0xA7A4, 0x0413, 0xA7A5, 0x0414, - 0xA7A6, 0x0415, 0xA7A7, 0x0401, 0xA7A8, 0x0416, 0xA7A9, 0x0417, 0xA7AA, 0x0418, 0xA7AB, 0x0419, 0xA7AC, 0x041A, 0xA7AD, 0x041B, - 0xA7AE, 0x041C, 0xA7AF, 0x041D, 0xA7B0, 0x041E, 0xA7B1, 0x041F, 0xA7B2, 0x0420, 0xA7B3, 0x0421, 0xA7B4, 0x0422, 0xA7B5, 0x0423, - 0xA7B6, 0x0424, 0xA7B7, 0x0425, 0xA7B8, 0x0426, 0xA7B9, 0x0427, 0xA7BA, 0x0428, 0xA7BB, 0x0429, 0xA7BC, 0x042A, 0xA7BD, 0x042B, - 0xA7BE, 0x042C, 0xA7BF, 0x042D, 0xA7C0, 0x042E, 0xA7C1, 0x042F, 0xA7D1, 0x0430, 0xA7D2, 0x0431, 0xA7D3, 0x0432, 0xA7D4, 0x0433, - 0xA7D5, 0x0434, 0xA7D6, 0x0435, 0xA7D7, 0x0451, 0xA7D8, 0x0436, 0xA7D9, 0x0437, 0xA7DA, 0x0438, 0xA7DB, 0x0439, 0xA7DC, 0x043A, - 0xA7DD, 0x043B, 0xA7DE, 0x043C, 0xA7DF, 0x043D, 0xA7E0, 0x043E, 0xA7E1, 0x043F, 0xA7E2, 0x0440, 0xA7E3, 0x0441, 0xA7E4, 0x0442, - 0xA7E5, 0x0443, 0xA7E6, 0x0444, 0xA7E7, 0x0445, 0xA7E8, 0x0446, 0xA7E9, 0x0447, 0xA7EA, 0x0448, 0xA7EB, 0x0449, 0xA7EC, 0x044A, - 0xA7ED, 0x044B, 0xA7EE, 0x044C, 0xA7EF, 0x044D, 0xA7F0, 0x044E, 0xA7F1, 0x044F, 0xA840, 0x02CA, 0xA841, 0x02CB, 0xA842, 0x02D9, - 0xA843, 0x2013, 0xA844, 0x2015, 0xA845, 0x2025, 0xA846, 0x2035, 0xA847, 0x2105, 0xA848, 0x2109, 0xA849, 0x2196, 0xA84A, 0x2197, - 0xA84B, 0x2198, 0xA84C, 0x2199, 0xA84D, 0x2215, 0xA84E, 0x221F, 0xA84F, 0x2223, 0xA850, 0x2252, 0xA851, 0x2266, 0xA852, 0x2267, - 0xA853, 0x22BF, 0xA854, 0x2550, 0xA855, 0x2551, 0xA856, 0x2552, 0xA857, 0x2553, 0xA858, 0x2554, 0xA859, 0x2555, 0xA85A, 0x2556, - 0xA85B, 0x2557, 0xA85C, 0x2558, 0xA85D, 0x2559, 0xA85E, 0x255A, 0xA85F, 0x255B, 0xA860, 0x255C, 0xA861, 0x255D, 0xA862, 0x255E, - 0xA863, 0x255F, 0xA864, 0x2560, 0xA865, 0x2561, 0xA866, 0x2562, 0xA867, 0x2563, 0xA868, 0x2564, 0xA869, 0x2565, 0xA86A, 0x2566, - 0xA86B, 0x2567, 0xA86C, 0x2568, 0xA86D, 0x2569, 0xA86E, 0x256A, 0xA86F, 0x256B, 0xA870, 0x256C, 0xA871, 0x256D, 0xA872, 0x256E, - 0xA873, 0x256F, 0xA874, 0x2570, 0xA875, 0x2571, 0xA876, 0x2572, 0xA877, 0x2573, 0xA878, 0x2581, 0xA879, 0x2582, 0xA87A, 0x2583, - 0xA87B, 0x2584, 0xA87C, 0x2585, 0xA87D, 0x2586, 0xA87E, 0x2587, 0xA880, 0x2588, 0xA881, 0x2589, 0xA882, 0x258A, 0xA883, 0x258B, - 0xA884, 0x258C, 0xA885, 0x258D, 0xA886, 0x258E, 0xA887, 0x258F, 0xA888, 0x2593, 0xA889, 0x2594, 0xA88A, 0x2595, 0xA88B, 0x25BC, - 0xA88C, 0x25BD, 0xA88D, 0x25E2, 0xA88E, 0x25E3, 0xA88F, 0x25E4, 0xA890, 0x25E5, 0xA891, 0x2609, 0xA892, 0x2295, 0xA893, 0x3012, - 0xA894, 0x301D, 0xA895, 0x301E, 0xA8A1, 0x0101, 0xA8A2, 0x00E1, 0xA8A3, 0x01CE, 0xA8A4, 0x00E0, 0xA8A5, 0x0113, 0xA8A6, 0x00E9, - 0xA8A7, 0x011B, 0xA8A8, 0x00E8, 0xA8A9, 0x012B, 0xA8AA, 0x00ED, 0xA8AB, 0x01D0, 0xA8AC, 0x00EC, 0xA8AD, 0x014D, 0xA8AE, 0x00F3, - 0xA8AF, 0x01D2, 0xA8B0, 0x00F2, 0xA8B1, 0x016B, 0xA8B2, 0x00FA, 0xA8B3, 0x01D4, 0xA8B4, 0x00F9, 0xA8B5, 0x01D6, 0xA8B6, 0x01D8, - 0xA8B7, 0x01DA, 0xA8B8, 0x01DC, 0xA8B9, 0x00FC, 0xA8BA, 0x00EA, 0xA8BB, 0x0251, 0xA8BD, 0x0144, 0xA8BE, 0x0148, 0xA8C0, 0x0261, - 0xA8C5, 0x3105, 0xA8C6, 0x3106, 0xA8C7, 0x3107, 0xA8C8, 0x3108, 0xA8C9, 0x3109, 0xA8CA, 0x310A, 0xA8CB, 0x310B, 0xA8CC, 0x310C, - 0xA8CD, 0x310D, 0xA8CE, 0x310E, 0xA8CF, 0x310F, 0xA8D0, 0x3110, 0xA8D1, 0x3111, 0xA8D2, 0x3112, 0xA8D3, 0x3113, 0xA8D4, 0x3114, - 0xA8D5, 0x3115, 0xA8D6, 0x3116, 0xA8D7, 0x3117, 0xA8D8, 0x3118, 0xA8D9, 0x3119, 0xA8DA, 0x311A, 0xA8DB, 0x311B, 0xA8DC, 0x311C, - 0xA8DD, 0x311D, 0xA8DE, 0x311E, 0xA8DF, 0x311F, 0xA8E0, 0x3120, 0xA8E1, 0x3121, 0xA8E2, 0x3122, 0xA8E3, 0x3123, 0xA8E4, 0x3124, - 0xA8E5, 0x3125, 0xA8E6, 0x3126, 0xA8E7, 0x3127, 0xA8E8, 0x3128, 0xA8E9, 0x3129, 0xA940, 0x3021, 0xA941, 0x3022, 0xA942, 0x3023, - 0xA943, 0x3024, 0xA944, 0x3025, 0xA945, 0x3026, 0xA946, 0x3027, 0xA947, 0x3028, 0xA948, 0x3029, 0xA949, 0x32A3, 0xA94A, 0x338E, - 0xA94B, 0x338F, 0xA94C, 0x339C, 0xA94D, 0x339D, 0xA94E, 0x339E, 0xA94F, 0x33A1, 0xA950, 0x33C4, 0xA951, 0x33CE, 0xA952, 0x33D1, - 0xA953, 0x33D2, 0xA954, 0x33D5, 0xA955, 0xFE30, 0xA956, 0xFFE2, 0xA957, 0xFFE4, 0xA959, 0x2121, 0xA95A, 0x3231, 0xA95C, 0x2010, - 0xA960, 0x30FC, 0xA961, 0x309B, 0xA962, 0x309C, 0xA963, 0x30FD, 0xA964, 0x30FE, 0xA965, 0x3006, 0xA966, 0x309D, 0xA967, 0x309E, - 0xA968, 0xFE49, 0xA969, 0xFE4A, 0xA96A, 0xFE4B, 0xA96B, 0xFE4C, 0xA96C, 0xFE4D, 0xA96D, 0xFE4E, 0xA96E, 0xFE4F, 0xA96F, 0xFE50, - 0xA970, 0xFE51, 0xA971, 0xFE52, 0xA972, 0xFE54, 0xA973, 0xFE55, 0xA974, 0xFE56, 0xA975, 0xFE57, 0xA976, 0xFE59, 0xA977, 0xFE5A, - 0xA978, 0xFE5B, 0xA979, 0xFE5C, 0xA97A, 0xFE5D, 0xA97B, 0xFE5E, 0xA97C, 0xFE5F, 0xA97D, 0xFE60, 0xA97E, 0xFE61, 0xA980, 0xFE62, - 0xA981, 0xFE63, 0xA982, 0xFE64, 0xA983, 0xFE65, 0xA984, 0xFE66, 0xA985, 0xFE68, 0xA986, 0xFE69, 0xA987, 0xFE6A, 0xA988, 0xFE6B, - 0xA996, 0x3007, 0xA9A4, 0x2500, 0xA9A5, 0x2501, 0xA9A6, 0x2502, 0xA9A7, 0x2503, 0xA9A8, 0x2504, 0xA9A9, 0x2505, 0xA9AA, 0x2506, - 0xA9AB, 0x2507, 0xA9AC, 0x2508, 0xA9AD, 0x2509, 0xA9AE, 0x250A, 0xA9AF, 0x250B, 0xA9B0, 0x250C, 0xA9B1, 0x250D, 0xA9B2, 0x250E, - 0xA9B3, 0x250F, 0xA9B4, 0x2510, 0xA9B5, 0x2511, 0xA9B6, 0x2512, 0xA9B7, 0x2513, 0xA9B8, 0x2514, 0xA9B9, 0x2515, 0xA9BA, 0x2516, - 0xA9BB, 0x2517, 0xA9BC, 0x2518, 0xA9BD, 0x2519, 0xA9BE, 0x251A, 0xA9BF, 0x251B, 0xA9C0, 0x251C, 0xA9C1, 0x251D, 0xA9C2, 0x251E, - 0xA9C3, 0x251F, 0xA9C4, 0x2520, 0xA9C5, 0x2521, 0xA9C6, 0x2522, 0xA9C7, 0x2523, 0xA9C8, 0x2524, 0xA9C9, 0x2525, 0xA9CA, 0x2526, - 0xA9CB, 0x2527, 0xA9CC, 0x2528, 0xA9CD, 0x2529, 0xA9CE, 0x252A, 0xA9CF, 0x252B, 0xA9D0, 0x252C, 0xA9D1, 0x252D, 0xA9D2, 0x252E, - 0xA9D3, 0x252F, 0xA9D4, 0x2530, 0xA9D5, 0x2531, 0xA9D6, 0x2532, 0xA9D7, 0x2533, 0xA9D8, 0x2534, 0xA9D9, 0x2535, 0xA9DA, 0x2536, - 0xA9DB, 0x2537, 0xA9DC, 0x2538, 0xA9DD, 0x2539, 0xA9DE, 0x253A, 0xA9DF, 0x253B, 0xA9E0, 0x253C, 0xA9E1, 0x253D, 0xA9E2, 0x253E, - 0xA9E3, 0x253F, 0xA9E4, 0x2540, 0xA9E5, 0x2541, 0xA9E6, 0x2542, 0xA9E7, 0x2543, 0xA9E8, 0x2544, 0xA9E9, 0x2545, 0xA9EA, 0x2546, - 0xA9EB, 0x2547, 0xA9EC, 0x2548, 0xA9ED, 0x2549, 0xA9EE, 0x254A, 0xA9EF, 0x254B, 0xAA40, 0x72DC, 0xAA41, 0x72DD, 0xAA42, 0x72DF, - 0xAA43, 0x72E2, 0xAA44, 0x72E3, 0xAA45, 0x72E4, 0xAA46, 0x72E5, 0xAA47, 0x72E6, 0xAA48, 0x72E7, 0xAA49, 0x72EA, 0xAA4A, 0x72EB, - 0xAA4B, 0x72F5, 0xAA4C, 0x72F6, 0xAA4D, 0x72F9, 0xAA4E, 0x72FD, 0xAA4F, 0x72FE, 0xAA50, 0x72FF, 0xAA51, 0x7300, 0xAA52, 0x7302, - 0xAA53, 0x7304, 0xAA54, 0x7305, 0xAA55, 0x7306, 0xAA56, 0x7307, 0xAA57, 0x7308, 0xAA58, 0x7309, 0xAA59, 0x730B, 0xAA5A, 0x730C, - 0xAA5B, 0x730D, 0xAA5C, 0x730F, 0xAA5D, 0x7310, 0xAA5E, 0x7311, 0xAA5F, 0x7312, 0xAA60, 0x7314, 0xAA61, 0x7318, 0xAA62, 0x7319, - 0xAA63, 0x731A, 0xAA64, 0x731F, 0xAA65, 0x7320, 0xAA66, 0x7323, 0xAA67, 0x7324, 0xAA68, 0x7326, 0xAA69, 0x7327, 0xAA6A, 0x7328, - 0xAA6B, 0x732D, 0xAA6C, 0x732F, 0xAA6D, 0x7330, 0xAA6E, 0x7332, 0xAA6F, 0x7333, 0xAA70, 0x7335, 0xAA71, 0x7336, 0xAA72, 0x733A, - 0xAA73, 0x733B, 0xAA74, 0x733C, 0xAA75, 0x733D, 0xAA76, 0x7340, 0xAA77, 0x7341, 0xAA78, 0x7342, 0xAA79, 0x7343, 0xAA7A, 0x7344, - 0xAA7B, 0x7345, 0xAA7C, 0x7346, 0xAA7D, 0x7347, 0xAA7E, 0x7348, 0xAA80, 0x7349, 0xAA81, 0x734A, 0xAA82, 0x734B, 0xAA83, 0x734C, - 0xAA84, 0x734E, 0xAA85, 0x734F, 0xAA86, 0x7351, 0xAA87, 0x7353, 0xAA88, 0x7354, 0xAA89, 0x7355, 0xAA8A, 0x7356, 0xAA8B, 0x7358, - 0xAA8C, 0x7359, 0xAA8D, 0x735A, 0xAA8E, 0x735B, 0xAA8F, 0x735C, 0xAA90, 0x735D, 0xAA91, 0x735E, 0xAA92, 0x735F, 0xAA93, 0x7361, - 0xAA94, 0x7362, 0xAA95, 0x7363, 0xAA96, 0x7364, 0xAA97, 0x7365, 0xAA98, 0x7366, 0xAA99, 0x7367, 0xAA9A, 0x7368, 0xAA9B, 0x7369, - 0xAA9C, 0x736A, 0xAA9D, 0x736B, 0xAA9E, 0x736E, 0xAA9F, 0x7370, 0xAAA0, 0x7371, 0xAB40, 0x7372, 0xAB41, 0x7373, 0xAB42, 0x7374, - 0xAB43, 0x7375, 0xAB44, 0x7376, 0xAB45, 0x7377, 0xAB46, 0x7378, 0xAB47, 0x7379, 0xAB48, 0x737A, 0xAB49, 0x737B, 0xAB4A, 0x737C, - 0xAB4B, 0x737D, 0xAB4C, 0x737F, 0xAB4D, 0x7380, 0xAB4E, 0x7381, 0xAB4F, 0x7382, 0xAB50, 0x7383, 0xAB51, 0x7385, 0xAB52, 0x7386, - 0xAB53, 0x7388, 0xAB54, 0x738A, 0xAB55, 0x738C, 0xAB56, 0x738D, 0xAB57, 0x738F, 0xAB58, 0x7390, 0xAB59, 0x7392, 0xAB5A, 0x7393, - 0xAB5B, 0x7394, 0xAB5C, 0x7395, 0xAB5D, 0x7397, 0xAB5E, 0x7398, 0xAB5F, 0x7399, 0xAB60, 0x739A, 0xAB61, 0x739C, 0xAB62, 0x739D, - 0xAB63, 0x739E, 0xAB64, 0x73A0, 0xAB65, 0x73A1, 0xAB66, 0x73A3, 0xAB67, 0x73A4, 0xAB68, 0x73A5, 0xAB69, 0x73A6, 0xAB6A, 0x73A7, - 0xAB6B, 0x73A8, 0xAB6C, 0x73AA, 0xAB6D, 0x73AC, 0xAB6E, 0x73AD, 0xAB6F, 0x73B1, 0xAB70, 0x73B4, 0xAB71, 0x73B5, 0xAB72, 0x73B6, - 0xAB73, 0x73B8, 0xAB74, 0x73B9, 0xAB75, 0x73BC, 0xAB76, 0x73BD, 0xAB77, 0x73BE, 0xAB78, 0x73BF, 0xAB79, 0x73C1, 0xAB7A, 0x73C3, - 0xAB7B, 0x73C4, 0xAB7C, 0x73C5, 0xAB7D, 0x73C6, 0xAB7E, 0x73C7, 0xAB80, 0x73CB, 0xAB81, 0x73CC, 0xAB82, 0x73CE, 0xAB83, 0x73D2, - 0xAB84, 0x73D3, 0xAB85, 0x73D4, 0xAB86, 0x73D5, 0xAB87, 0x73D6, 0xAB88, 0x73D7, 0xAB89, 0x73D8, 0xAB8A, 0x73DA, 0xAB8B, 0x73DB, - 0xAB8C, 0x73DC, 0xAB8D, 0x73DD, 0xAB8E, 0x73DF, 0xAB8F, 0x73E1, 0xAB90, 0x73E2, 0xAB91, 0x73E3, 0xAB92, 0x73E4, 0xAB93, 0x73E6, - 0xAB94, 0x73E8, 0xAB95, 0x73EA, 0xAB96, 0x73EB, 0xAB97, 0x73EC, 0xAB98, 0x73EE, 0xAB99, 0x73EF, 0xAB9A, 0x73F0, 0xAB9B, 0x73F1, - 0xAB9C, 0x73F3, 0xAB9D, 0x73F4, 0xAB9E, 0x73F5, 0xAB9F, 0x73F6, 0xABA0, 0x73F7, 0xAC40, 0x73F8, 0xAC41, 0x73F9, 0xAC42, 0x73FA, - 0xAC43, 0x73FB, 0xAC44, 0x73FC, 0xAC45, 0x73FD, 0xAC46, 0x73FE, 0xAC47, 0x73FF, 0xAC48, 0x7400, 0xAC49, 0x7401, 0xAC4A, 0x7402, - 0xAC4B, 0x7404, 0xAC4C, 0x7407, 0xAC4D, 0x7408, 0xAC4E, 0x740B, 0xAC4F, 0x740C, 0xAC50, 0x740D, 0xAC51, 0x740E, 0xAC52, 0x7411, - 0xAC53, 0x7412, 0xAC54, 0x7413, 0xAC55, 0x7414, 0xAC56, 0x7415, 0xAC57, 0x7416, 0xAC58, 0x7417, 0xAC59, 0x7418, 0xAC5A, 0x7419, - 0xAC5B, 0x741C, 0xAC5C, 0x741D, 0xAC5D, 0x741E, 0xAC5E, 0x741F, 0xAC5F, 0x7420, 0xAC60, 0x7421, 0xAC61, 0x7423, 0xAC62, 0x7424, - 0xAC63, 0x7427, 0xAC64, 0x7429, 0xAC65, 0x742B, 0xAC66, 0x742D, 0xAC67, 0x742F, 0xAC68, 0x7431, 0xAC69, 0x7432, 0xAC6A, 0x7437, - 0xAC6B, 0x7438, 0xAC6C, 0x7439, 0xAC6D, 0x743A, 0xAC6E, 0x743B, 0xAC6F, 0x743D, 0xAC70, 0x743E, 0xAC71, 0x743F, 0xAC72, 0x7440, - 0xAC73, 0x7442, 0xAC74, 0x7443, 0xAC75, 0x7444, 0xAC76, 0x7445, 0xAC77, 0x7446, 0xAC78, 0x7447, 0xAC79, 0x7448, 0xAC7A, 0x7449, - 0xAC7B, 0x744A, 0xAC7C, 0x744B, 0xAC7D, 0x744C, 0xAC7E, 0x744D, 0xAC80, 0x744E, 0xAC81, 0x744F, 0xAC82, 0x7450, 0xAC83, 0x7451, - 0xAC84, 0x7452, 0xAC85, 0x7453, 0xAC86, 0x7454, 0xAC87, 0x7456, 0xAC88, 0x7458, 0xAC89, 0x745D, 0xAC8A, 0x7460, 0xAC8B, 0x7461, - 0xAC8C, 0x7462, 0xAC8D, 0x7463, 0xAC8E, 0x7464, 0xAC8F, 0x7465, 0xAC90, 0x7466, 0xAC91, 0x7467, 0xAC92, 0x7468, 0xAC93, 0x7469, - 0xAC94, 0x746A, 0xAC95, 0x746B, 0xAC96, 0x746C, 0xAC97, 0x746E, 0xAC98, 0x746F, 0xAC99, 0x7471, 0xAC9A, 0x7472, 0xAC9B, 0x7473, - 0xAC9C, 0x7474, 0xAC9D, 0x7475, 0xAC9E, 0x7478, 0xAC9F, 0x7479, 0xACA0, 0x747A, 0xAD40, 0x747B, 0xAD41, 0x747C, 0xAD42, 0x747D, - 0xAD43, 0x747F, 0xAD44, 0x7482, 0xAD45, 0x7484, 0xAD46, 0x7485, 0xAD47, 0x7486, 0xAD48, 0x7488, 0xAD49, 0x7489, 0xAD4A, 0x748A, - 0xAD4B, 0x748C, 0xAD4C, 0x748D, 0xAD4D, 0x748F, 0xAD4E, 0x7491, 0xAD4F, 0x7492, 0xAD50, 0x7493, 0xAD51, 0x7494, 0xAD52, 0x7495, - 0xAD53, 0x7496, 0xAD54, 0x7497, 0xAD55, 0x7498, 0xAD56, 0x7499, 0xAD57, 0x749A, 0xAD58, 0x749B, 0xAD59, 0x749D, 0xAD5A, 0x749F, - 0xAD5B, 0x74A0, 0xAD5C, 0x74A1, 0xAD5D, 0x74A2, 0xAD5E, 0x74A3, 0xAD5F, 0x74A4, 0xAD60, 0x74A5, 0xAD61, 0x74A6, 0xAD62, 0x74AA, - 0xAD63, 0x74AB, 0xAD64, 0x74AC, 0xAD65, 0x74AD, 0xAD66, 0x74AE, 0xAD67, 0x74AF, 0xAD68, 0x74B0, 0xAD69, 0x74B1, 0xAD6A, 0x74B2, - 0xAD6B, 0x74B3, 0xAD6C, 0x74B4, 0xAD6D, 0x74B5, 0xAD6E, 0x74B6, 0xAD6F, 0x74B7, 0xAD70, 0x74B8, 0xAD71, 0x74B9, 0xAD72, 0x74BB, - 0xAD73, 0x74BC, 0xAD74, 0x74BD, 0xAD75, 0x74BE, 0xAD76, 0x74BF, 0xAD77, 0x74C0, 0xAD78, 0x74C1, 0xAD79, 0x74C2, 0xAD7A, 0x74C3, - 0xAD7B, 0x74C4, 0xAD7C, 0x74C5, 0xAD7D, 0x74C6, 0xAD7E, 0x74C7, 0xAD80, 0x74C8, 0xAD81, 0x74C9, 0xAD82, 0x74CA, 0xAD83, 0x74CB, - 0xAD84, 0x74CC, 0xAD85, 0x74CD, 0xAD86, 0x74CE, 0xAD87, 0x74CF, 0xAD88, 0x74D0, 0xAD89, 0x74D1, 0xAD8A, 0x74D3, 0xAD8B, 0x74D4, - 0xAD8C, 0x74D5, 0xAD8D, 0x74D6, 0xAD8E, 0x74D7, 0xAD8F, 0x74D8, 0xAD90, 0x74D9, 0xAD91, 0x74DA, 0xAD92, 0x74DB, 0xAD93, 0x74DD, - 0xAD94, 0x74DF, 0xAD95, 0x74E1, 0xAD96, 0x74E5, 0xAD97, 0x74E7, 0xAD98, 0x74E8, 0xAD99, 0x74E9, 0xAD9A, 0x74EA, 0xAD9B, 0x74EB, - 0xAD9C, 0x74EC, 0xAD9D, 0x74ED, 0xAD9E, 0x74F0, 0xAD9F, 0x74F1, 0xADA0, 0x74F2, 0xAE40, 0x74F3, 0xAE41, 0x74F5, 0xAE42, 0x74F8, - 0xAE43, 0x74F9, 0xAE44, 0x74FA, 0xAE45, 0x74FB, 0xAE46, 0x74FC, 0xAE47, 0x74FD, 0xAE48, 0x74FE, 0xAE49, 0x7500, 0xAE4A, 0x7501, - 0xAE4B, 0x7502, 0xAE4C, 0x7503, 0xAE4D, 0x7505, 0xAE4E, 0x7506, 0xAE4F, 0x7507, 0xAE50, 0x7508, 0xAE51, 0x7509, 0xAE52, 0x750A, - 0xAE53, 0x750B, 0xAE54, 0x750C, 0xAE55, 0x750E, 0xAE56, 0x7510, 0xAE57, 0x7512, 0xAE58, 0x7514, 0xAE59, 0x7515, 0xAE5A, 0x7516, - 0xAE5B, 0x7517, 0xAE5C, 0x751B, 0xAE5D, 0x751D, 0xAE5E, 0x751E, 0xAE5F, 0x7520, 0xAE60, 0x7521, 0xAE61, 0x7522, 0xAE62, 0x7523, - 0xAE63, 0x7524, 0xAE64, 0x7526, 0xAE65, 0x7527, 0xAE66, 0x752A, 0xAE67, 0x752E, 0xAE68, 0x7534, 0xAE69, 0x7536, 0xAE6A, 0x7539, - 0xAE6B, 0x753C, 0xAE6C, 0x753D, 0xAE6D, 0x753F, 0xAE6E, 0x7541, 0xAE6F, 0x7542, 0xAE70, 0x7543, 0xAE71, 0x7544, 0xAE72, 0x7546, - 0xAE73, 0x7547, 0xAE74, 0x7549, 0xAE75, 0x754A, 0xAE76, 0x754D, 0xAE77, 0x7550, 0xAE78, 0x7551, 0xAE79, 0x7552, 0xAE7A, 0x7553, - 0xAE7B, 0x7555, 0xAE7C, 0x7556, 0xAE7D, 0x7557, 0xAE7E, 0x7558, 0xAE80, 0x755D, 0xAE81, 0x755E, 0xAE82, 0x755F, 0xAE83, 0x7560, - 0xAE84, 0x7561, 0xAE85, 0x7562, 0xAE86, 0x7563, 0xAE87, 0x7564, 0xAE88, 0x7567, 0xAE89, 0x7568, 0xAE8A, 0x7569, 0xAE8B, 0x756B, - 0xAE8C, 0x756C, 0xAE8D, 0x756D, 0xAE8E, 0x756E, 0xAE8F, 0x756F, 0xAE90, 0x7570, 0xAE91, 0x7571, 0xAE92, 0x7573, 0xAE93, 0x7575, - 0xAE94, 0x7576, 0xAE95, 0x7577, 0xAE96, 0x757A, 0xAE97, 0x757B, 0xAE98, 0x757C, 0xAE99, 0x757D, 0xAE9A, 0x757E, 0xAE9B, 0x7580, - 0xAE9C, 0x7581, 0xAE9D, 0x7582, 0xAE9E, 0x7584, 0xAE9F, 0x7585, 0xAEA0, 0x7587, 0xAF40, 0x7588, 0xAF41, 0x7589, 0xAF42, 0x758A, - 0xAF43, 0x758C, 0xAF44, 0x758D, 0xAF45, 0x758E, 0xAF46, 0x7590, 0xAF47, 0x7593, 0xAF48, 0x7595, 0xAF49, 0x7598, 0xAF4A, 0x759B, - 0xAF4B, 0x759C, 0xAF4C, 0x759E, 0xAF4D, 0x75A2, 0xAF4E, 0x75A6, 0xAF4F, 0x75A7, 0xAF50, 0x75A8, 0xAF51, 0x75A9, 0xAF52, 0x75AA, - 0xAF53, 0x75AD, 0xAF54, 0x75B6, 0xAF55, 0x75B7, 0xAF56, 0x75BA, 0xAF57, 0x75BB, 0xAF58, 0x75BF, 0xAF59, 0x75C0, 0xAF5A, 0x75C1, - 0xAF5B, 0x75C6, 0xAF5C, 0x75CB, 0xAF5D, 0x75CC, 0xAF5E, 0x75CE, 0xAF5F, 0x75CF, 0xAF60, 0x75D0, 0xAF61, 0x75D1, 0xAF62, 0x75D3, - 0xAF63, 0x75D7, 0xAF64, 0x75D9, 0xAF65, 0x75DA, 0xAF66, 0x75DC, 0xAF67, 0x75DD, 0xAF68, 0x75DF, 0xAF69, 0x75E0, 0xAF6A, 0x75E1, - 0xAF6B, 0x75E5, 0xAF6C, 0x75E9, 0xAF6D, 0x75EC, 0xAF6E, 0x75ED, 0xAF6F, 0x75EE, 0xAF70, 0x75EF, 0xAF71, 0x75F2, 0xAF72, 0x75F3, - 0xAF73, 0x75F5, 0xAF74, 0x75F6, 0xAF75, 0x75F7, 0xAF76, 0x75F8, 0xAF77, 0x75FA, 0xAF78, 0x75FB, 0xAF79, 0x75FD, 0xAF7A, 0x75FE, - 0xAF7B, 0x7602, 0xAF7C, 0x7604, 0xAF7D, 0x7606, 0xAF7E, 0x7607, 0xAF80, 0x7608, 0xAF81, 0x7609, 0xAF82, 0x760B, 0xAF83, 0x760D, - 0xAF84, 0x760E, 0xAF85, 0x760F, 0xAF86, 0x7611, 0xAF87, 0x7612, 0xAF88, 0x7613, 0xAF89, 0x7614, 0xAF8A, 0x7616, 0xAF8B, 0x761A, - 0xAF8C, 0x761C, 0xAF8D, 0x761D, 0xAF8E, 0x761E, 0xAF8F, 0x7621, 0xAF90, 0x7623, 0xAF91, 0x7627, 0xAF92, 0x7628, 0xAF93, 0x762C, - 0xAF94, 0x762E, 0xAF95, 0x762F, 0xAF96, 0x7631, 0xAF97, 0x7632, 0xAF98, 0x7636, 0xAF99, 0x7637, 0xAF9A, 0x7639, 0xAF9B, 0x763A, - 0xAF9C, 0x763B, 0xAF9D, 0x763D, 0xAF9E, 0x7641, 0xAF9F, 0x7642, 0xAFA0, 0x7644, 0xB040, 0x7645, 0xB041, 0x7646, 0xB042, 0x7647, - 0xB043, 0x7648, 0xB044, 0x7649, 0xB045, 0x764A, 0xB046, 0x764B, 0xB047, 0x764E, 0xB048, 0x764F, 0xB049, 0x7650, 0xB04A, 0x7651, - 0xB04B, 0x7652, 0xB04C, 0x7653, 0xB04D, 0x7655, 0xB04E, 0x7657, 0xB04F, 0x7658, 0xB050, 0x7659, 0xB051, 0x765A, 0xB052, 0x765B, - 0xB053, 0x765D, 0xB054, 0x765F, 0xB055, 0x7660, 0xB056, 0x7661, 0xB057, 0x7662, 0xB058, 0x7664, 0xB059, 0x7665, 0xB05A, 0x7666, - 0xB05B, 0x7667, 0xB05C, 0x7668, 0xB05D, 0x7669, 0xB05E, 0x766A, 0xB05F, 0x766C, 0xB060, 0x766D, 0xB061, 0x766E, 0xB062, 0x7670, - 0xB063, 0x7671, 0xB064, 0x7672, 0xB065, 0x7673, 0xB066, 0x7674, 0xB067, 0x7675, 0xB068, 0x7676, 0xB069, 0x7677, 0xB06A, 0x7679, - 0xB06B, 0x767A, 0xB06C, 0x767C, 0xB06D, 0x767F, 0xB06E, 0x7680, 0xB06F, 0x7681, 0xB070, 0x7683, 0xB071, 0x7685, 0xB072, 0x7689, - 0xB073, 0x768A, 0xB074, 0x768C, 0xB075, 0x768D, 0xB076, 0x768F, 0xB077, 0x7690, 0xB078, 0x7692, 0xB079, 0x7694, 0xB07A, 0x7695, - 0xB07B, 0x7697, 0xB07C, 0x7698, 0xB07D, 0x769A, 0xB07E, 0x769B, 0xB080, 0x769C, 0xB081, 0x769D, 0xB082, 0x769E, 0xB083, 0x769F, - 0xB084, 0x76A0, 0xB085, 0x76A1, 0xB086, 0x76A2, 0xB087, 0x76A3, 0xB088, 0x76A5, 0xB089, 0x76A6, 0xB08A, 0x76A7, 0xB08B, 0x76A8, - 0xB08C, 0x76A9, 0xB08D, 0x76AA, 0xB08E, 0x76AB, 0xB08F, 0x76AC, 0xB090, 0x76AD, 0xB091, 0x76AF, 0xB092, 0x76B0, 0xB093, 0x76B3, - 0xB094, 0x76B5, 0xB095, 0x76B6, 0xB096, 0x76B7, 0xB097, 0x76B8, 0xB098, 0x76B9, 0xB099, 0x76BA, 0xB09A, 0x76BB, 0xB09B, 0x76BC, - 0xB09C, 0x76BD, 0xB09D, 0x76BE, 0xB09E, 0x76C0, 0xB09F, 0x76C1, 0xB0A0, 0x76C3, 0xB0A1, 0x554A, 0xB0A2, 0x963F, 0xB0A3, 0x57C3, - 0xB0A4, 0x6328, 0xB0A5, 0x54CE, 0xB0A6, 0x5509, 0xB0A7, 0x54C0, 0xB0A8, 0x7691, 0xB0A9, 0x764C, 0xB0AA, 0x853C, 0xB0AB, 0x77EE, - 0xB0AC, 0x827E, 0xB0AD, 0x788D, 0xB0AE, 0x7231, 0xB0AF, 0x9698, 0xB0B0, 0x978D, 0xB0B1, 0x6C28, 0xB0B2, 0x5B89, 0xB0B3, 0x4FFA, - 0xB0B4, 0x6309, 0xB0B5, 0x6697, 0xB0B6, 0x5CB8, 0xB0B7, 0x80FA, 0xB0B8, 0x6848, 0xB0B9, 0x80AE, 0xB0BA, 0x6602, 0xB0BB, 0x76CE, - 0xB0BC, 0x51F9, 0xB0BD, 0x6556, 0xB0BE, 0x71AC, 0xB0BF, 0x7FF1, 0xB0C0, 0x8884, 0xB0C1, 0x50B2, 0xB0C2, 0x5965, 0xB0C3, 0x61CA, - 0xB0C4, 0x6FB3, 0xB0C5, 0x82AD, 0xB0C6, 0x634C, 0xB0C7, 0x6252, 0xB0C8, 0x53ED, 0xB0C9, 0x5427, 0xB0CA, 0x7B06, 0xB0CB, 0x516B, - 0xB0CC, 0x75A4, 0xB0CD, 0x5DF4, 0xB0CE, 0x62D4, 0xB0CF, 0x8DCB, 0xB0D0, 0x9776, 0xB0D1, 0x628A, 0xB0D2, 0x8019, 0xB0D3, 0x575D, - 0xB0D4, 0x9738, 0xB0D5, 0x7F62, 0xB0D6, 0x7238, 0xB0D7, 0x767D, 0xB0D8, 0x67CF, 0xB0D9, 0x767E, 0xB0DA, 0x6446, 0xB0DB, 0x4F70, - 0xB0DC, 0x8D25, 0xB0DD, 0x62DC, 0xB0DE, 0x7A17, 0xB0DF, 0x6591, 0xB0E0, 0x73ED, 0xB0E1, 0x642C, 0xB0E2, 0x6273, 0xB0E3, 0x822C, - 0xB0E4, 0x9881, 0xB0E5, 0x677F, 0xB0E6, 0x7248, 0xB0E7, 0x626E, 0xB0E8, 0x62CC, 0xB0E9, 0x4F34, 0xB0EA, 0x74E3, 0xB0EB, 0x534A, - 0xB0EC, 0x529E, 0xB0ED, 0x7ECA, 0xB0EE, 0x90A6, 0xB0EF, 0x5E2E, 0xB0F0, 0x6886, 0xB0F1, 0x699C, 0xB0F2, 0x8180, 0xB0F3, 0x7ED1, - 0xB0F4, 0x68D2, 0xB0F5, 0x78C5, 0xB0F6, 0x868C, 0xB0F7, 0x9551, 0xB0F8, 0x508D, 0xB0F9, 0x8C24, 0xB0FA, 0x82DE, 0xB0FB, 0x80DE, - 0xB0FC, 0x5305, 0xB0FD, 0x8912, 0xB0FE, 0x5265, 0xB140, 0x76C4, 0xB141, 0x76C7, 0xB142, 0x76C9, 0xB143, 0x76CB, 0xB144, 0x76CC, - 0xB145, 0x76D3, 0xB146, 0x76D5, 0xB147, 0x76D9, 0xB148, 0x76DA, 0xB149, 0x76DC, 0xB14A, 0x76DD, 0xB14B, 0x76DE, 0xB14C, 0x76E0, - 0xB14D, 0x76E1, 0xB14E, 0x76E2, 0xB14F, 0x76E3, 0xB150, 0x76E4, 0xB151, 0x76E6, 0xB152, 0x76E7, 0xB153, 0x76E8, 0xB154, 0x76E9, - 0xB155, 0x76EA, 0xB156, 0x76EB, 0xB157, 0x76EC, 0xB158, 0x76ED, 0xB159, 0x76F0, 0xB15A, 0x76F3, 0xB15B, 0x76F5, 0xB15C, 0x76F6, - 0xB15D, 0x76F7, 0xB15E, 0x76FA, 0xB15F, 0x76FB, 0xB160, 0x76FD, 0xB161, 0x76FF, 0xB162, 0x7700, 0xB163, 0x7702, 0xB164, 0x7703, - 0xB165, 0x7705, 0xB166, 0x7706, 0xB167, 0x770A, 0xB168, 0x770C, 0xB169, 0x770E, 0xB16A, 0x770F, 0xB16B, 0x7710, 0xB16C, 0x7711, - 0xB16D, 0x7712, 0xB16E, 0x7713, 0xB16F, 0x7714, 0xB170, 0x7715, 0xB171, 0x7716, 0xB172, 0x7717, 0xB173, 0x7718, 0xB174, 0x771B, - 0xB175, 0x771C, 0xB176, 0x771D, 0xB177, 0x771E, 0xB178, 0x7721, 0xB179, 0x7723, 0xB17A, 0x7724, 0xB17B, 0x7725, 0xB17C, 0x7727, - 0xB17D, 0x772A, 0xB17E, 0x772B, 0xB180, 0x772C, 0xB181, 0x772E, 0xB182, 0x7730, 0xB183, 0x7731, 0xB184, 0x7732, 0xB185, 0x7733, - 0xB186, 0x7734, 0xB187, 0x7739, 0xB188, 0x773B, 0xB189, 0x773D, 0xB18A, 0x773E, 0xB18B, 0x773F, 0xB18C, 0x7742, 0xB18D, 0x7744, - 0xB18E, 0x7745, 0xB18F, 0x7746, 0xB190, 0x7748, 0xB191, 0x7749, 0xB192, 0x774A, 0xB193, 0x774B, 0xB194, 0x774C, 0xB195, 0x774D, - 0xB196, 0x774E, 0xB197, 0x774F, 0xB198, 0x7752, 0xB199, 0x7753, 0xB19A, 0x7754, 0xB19B, 0x7755, 0xB19C, 0x7756, 0xB19D, 0x7757, - 0xB19E, 0x7758, 0xB19F, 0x7759, 0xB1A0, 0x775C, 0xB1A1, 0x8584, 0xB1A2, 0x96F9, 0xB1A3, 0x4FDD, 0xB1A4, 0x5821, 0xB1A5, 0x9971, - 0xB1A6, 0x5B9D, 0xB1A7, 0x62B1, 0xB1A8, 0x62A5, 0xB1A9, 0x66B4, 0xB1AA, 0x8C79, 0xB1AB, 0x9C8D, 0xB1AC, 0x7206, 0xB1AD, 0x676F, - 0xB1AE, 0x7891, 0xB1AF, 0x60B2, 0xB1B0, 0x5351, 0xB1B1, 0x5317, 0xB1B2, 0x8F88, 0xB1B3, 0x80CC, 0xB1B4, 0x8D1D, 0xB1B5, 0x94A1, - 0xB1B6, 0x500D, 0xB1B7, 0x72C8, 0xB1B8, 0x5907, 0xB1B9, 0x60EB, 0xB1BA, 0x7119, 0xB1BB, 0x88AB, 0xB1BC, 0x5954, 0xB1BD, 0x82EF, - 0xB1BE, 0x672C, 0xB1BF, 0x7B28, 0xB1C0, 0x5D29, 0xB1C1, 0x7EF7, 0xB1C2, 0x752D, 0xB1C3, 0x6CF5, 0xB1C4, 0x8E66, 0xB1C5, 0x8FF8, - 0xB1C6, 0x903C, 0xB1C7, 0x9F3B, 0xB1C8, 0x6BD4, 0xB1C9, 0x9119, 0xB1CA, 0x7B14, 0xB1CB, 0x5F7C, 0xB1CC, 0x78A7, 0xB1CD, 0x84D6, - 0xB1CE, 0x853D, 0xB1CF, 0x6BD5, 0xB1D0, 0x6BD9, 0xB1D1, 0x6BD6, 0xB1D2, 0x5E01, 0xB1D3, 0x5E87, 0xB1D4, 0x75F9, 0xB1D5, 0x95ED, - 0xB1D6, 0x655D, 0xB1D7, 0x5F0A, 0xB1D8, 0x5FC5, 0xB1D9, 0x8F9F, 0xB1DA, 0x58C1, 0xB1DB, 0x81C2, 0xB1DC, 0x907F, 0xB1DD, 0x965B, - 0xB1DE, 0x97AD, 0xB1DF, 0x8FB9, 0xB1E0, 0x7F16, 0xB1E1, 0x8D2C, 0xB1E2, 0x6241, 0xB1E3, 0x4FBF, 0xB1E4, 0x53D8, 0xB1E5, 0x535E, - 0xB1E6, 0x8FA8, 0xB1E7, 0x8FA9, 0xB1E8, 0x8FAB, 0xB1E9, 0x904D, 0xB1EA, 0x6807, 0xB1EB, 0x5F6A, 0xB1EC, 0x8198, 0xB1ED, 0x8868, - 0xB1EE, 0x9CD6, 0xB1EF, 0x618B, 0xB1F0, 0x522B, 0xB1F1, 0x762A, 0xB1F2, 0x5F6C, 0xB1F3, 0x658C, 0xB1F4, 0x6FD2, 0xB1F5, 0x6EE8, - 0xB1F6, 0x5BBE, 0xB1F7, 0x6448, 0xB1F8, 0x5175, 0xB1F9, 0x51B0, 0xB1FA, 0x67C4, 0xB1FB, 0x4E19, 0xB1FC, 0x79C9, 0xB1FD, 0x997C, - 0xB1FE, 0x70B3, 0xB240, 0x775D, 0xB241, 0x775E, 0xB242, 0x775F, 0xB243, 0x7760, 0xB244, 0x7764, 0xB245, 0x7767, 0xB246, 0x7769, - 0xB247, 0x776A, 0xB248, 0x776D, 0xB249, 0x776E, 0xB24A, 0x776F, 0xB24B, 0x7770, 0xB24C, 0x7771, 0xB24D, 0x7772, 0xB24E, 0x7773, - 0xB24F, 0x7774, 0xB250, 0x7775, 0xB251, 0x7776, 0xB252, 0x7777, 0xB253, 0x7778, 0xB254, 0x777A, 0xB255, 0x777B, 0xB256, 0x777C, - 0xB257, 0x7781, 0xB258, 0x7782, 0xB259, 0x7783, 0xB25A, 0x7786, 0xB25B, 0x7787, 0xB25C, 0x7788, 0xB25D, 0x7789, 0xB25E, 0x778A, - 0xB25F, 0x778B, 0xB260, 0x778F, 0xB261, 0x7790, 0xB262, 0x7793, 0xB263, 0x7794, 0xB264, 0x7795, 0xB265, 0x7796, 0xB266, 0x7797, - 0xB267, 0x7798, 0xB268, 0x7799, 0xB269, 0x779A, 0xB26A, 0x779B, 0xB26B, 0x779C, 0xB26C, 0x779D, 0xB26D, 0x779E, 0xB26E, 0x77A1, - 0xB26F, 0x77A3, 0xB270, 0x77A4, 0xB271, 0x77A6, 0xB272, 0x77A8, 0xB273, 0x77AB, 0xB274, 0x77AD, 0xB275, 0x77AE, 0xB276, 0x77AF, - 0xB277, 0x77B1, 0xB278, 0x77B2, 0xB279, 0x77B4, 0xB27A, 0x77B6, 0xB27B, 0x77B7, 0xB27C, 0x77B8, 0xB27D, 0x77B9, 0xB27E, 0x77BA, - 0xB280, 0x77BC, 0xB281, 0x77BE, 0xB282, 0x77C0, 0xB283, 0x77C1, 0xB284, 0x77C2, 0xB285, 0x77C3, 0xB286, 0x77C4, 0xB287, 0x77C5, - 0xB288, 0x77C6, 0xB289, 0x77C7, 0xB28A, 0x77C8, 0xB28B, 0x77C9, 0xB28C, 0x77CA, 0xB28D, 0x77CB, 0xB28E, 0x77CC, 0xB28F, 0x77CE, - 0xB290, 0x77CF, 0xB291, 0x77D0, 0xB292, 0x77D1, 0xB293, 0x77D2, 0xB294, 0x77D3, 0xB295, 0x77D4, 0xB296, 0x77D5, 0xB297, 0x77D6, - 0xB298, 0x77D8, 0xB299, 0x77D9, 0xB29A, 0x77DA, 0xB29B, 0x77DD, 0xB29C, 0x77DE, 0xB29D, 0x77DF, 0xB29E, 0x77E0, 0xB29F, 0x77E1, - 0xB2A0, 0x77E4, 0xB2A1, 0x75C5, 0xB2A2, 0x5E76, 0xB2A3, 0x73BB, 0xB2A4, 0x83E0, 0xB2A5, 0x64AD, 0xB2A6, 0x62E8, 0xB2A7, 0x94B5, - 0xB2A8, 0x6CE2, 0xB2A9, 0x535A, 0xB2AA, 0x52C3, 0xB2AB, 0x640F, 0xB2AC, 0x94C2, 0xB2AD, 0x7B94, 0xB2AE, 0x4F2F, 0xB2AF, 0x5E1B, - 0xB2B0, 0x8236, 0xB2B1, 0x8116, 0xB2B2, 0x818A, 0xB2B3, 0x6E24, 0xB2B4, 0x6CCA, 0xB2B5, 0x9A73, 0xB2B6, 0x6355, 0xB2B7, 0x535C, - 0xB2B8, 0x54FA, 0xB2B9, 0x8865, 0xB2BA, 0x57E0, 0xB2BB, 0x4E0D, 0xB2BC, 0x5E03, 0xB2BD, 0x6B65, 0xB2BE, 0x7C3F, 0xB2BF, 0x90E8, - 0xB2C0, 0x6016, 0xB2C1, 0x64E6, 0xB2C2, 0x731C, 0xB2C3, 0x88C1, 0xB2C4, 0x6750, 0xB2C5, 0x624D, 0xB2C6, 0x8D22, 0xB2C7, 0x776C, - 0xB2C8, 0x8E29, 0xB2C9, 0x91C7, 0xB2CA, 0x5F69, 0xB2CB, 0x83DC, 0xB2CC, 0x8521, 0xB2CD, 0x9910, 0xB2CE, 0x53C2, 0xB2CF, 0x8695, - 0xB2D0, 0x6B8B, 0xB2D1, 0x60ED, 0xB2D2, 0x60E8, 0xB2D3, 0x707F, 0xB2D4, 0x82CD, 0xB2D5, 0x8231, 0xB2D6, 0x4ED3, 0xB2D7, 0x6CA7, - 0xB2D8, 0x85CF, 0xB2D9, 0x64CD, 0xB2DA, 0x7CD9, 0xB2DB, 0x69FD, 0xB2DC, 0x66F9, 0xB2DD, 0x8349, 0xB2DE, 0x5395, 0xB2DF, 0x7B56, - 0xB2E0, 0x4FA7, 0xB2E1, 0x518C, 0xB2E2, 0x6D4B, 0xB2E3, 0x5C42, 0xB2E4, 0x8E6D, 0xB2E5, 0x63D2, 0xB2E6, 0x53C9, 0xB2E7, 0x832C, - 0xB2E8, 0x8336, 0xB2E9, 0x67E5, 0xB2EA, 0x78B4, 0xB2EB, 0x643D, 0xB2EC, 0x5BDF, 0xB2ED, 0x5C94, 0xB2EE, 0x5DEE, 0xB2EF, 0x8BE7, - 0xB2F0, 0x62C6, 0xB2F1, 0x67F4, 0xB2F2, 0x8C7A, 0xB2F3, 0x6400, 0xB2F4, 0x63BA, 0xB2F5, 0x8749, 0xB2F6, 0x998B, 0xB2F7, 0x8C17, - 0xB2F8, 0x7F20, 0xB2F9, 0x94F2, 0xB2FA, 0x4EA7, 0xB2FB, 0x9610, 0xB2FC, 0x98A4, 0xB2FD, 0x660C, 0xB2FE, 0x7316, 0xB340, 0x77E6, - 0xB341, 0x77E8, 0xB342, 0x77EA, 0xB343, 0x77EF, 0xB344, 0x77F0, 0xB345, 0x77F1, 0xB346, 0x77F2, 0xB347, 0x77F4, 0xB348, 0x77F5, - 0xB349, 0x77F7, 0xB34A, 0x77F9, 0xB34B, 0x77FA, 0xB34C, 0x77FB, 0xB34D, 0x77FC, 0xB34E, 0x7803, 0xB34F, 0x7804, 0xB350, 0x7805, - 0xB351, 0x7806, 0xB352, 0x7807, 0xB353, 0x7808, 0xB354, 0x780A, 0xB355, 0x780B, 0xB356, 0x780E, 0xB357, 0x780F, 0xB358, 0x7810, - 0xB359, 0x7813, 0xB35A, 0x7815, 0xB35B, 0x7819, 0xB35C, 0x781B, 0xB35D, 0x781E, 0xB35E, 0x7820, 0xB35F, 0x7821, 0xB360, 0x7822, - 0xB361, 0x7824, 0xB362, 0x7828, 0xB363, 0x782A, 0xB364, 0x782B, 0xB365, 0x782E, 0xB366, 0x782F, 0xB367, 0x7831, 0xB368, 0x7832, - 0xB369, 0x7833, 0xB36A, 0x7835, 0xB36B, 0x7836, 0xB36C, 0x783D, 0xB36D, 0x783F, 0xB36E, 0x7841, 0xB36F, 0x7842, 0xB370, 0x7843, - 0xB371, 0x7844, 0xB372, 0x7846, 0xB373, 0x7848, 0xB374, 0x7849, 0xB375, 0x784A, 0xB376, 0x784B, 0xB377, 0x784D, 0xB378, 0x784F, - 0xB379, 0x7851, 0xB37A, 0x7853, 0xB37B, 0x7854, 0xB37C, 0x7858, 0xB37D, 0x7859, 0xB37E, 0x785A, 0xB380, 0x785B, 0xB381, 0x785C, - 0xB382, 0x785E, 0xB383, 0x785F, 0xB384, 0x7860, 0xB385, 0x7861, 0xB386, 0x7862, 0xB387, 0x7863, 0xB388, 0x7864, 0xB389, 0x7865, - 0xB38A, 0x7866, 0xB38B, 0x7867, 0xB38C, 0x7868, 0xB38D, 0x7869, 0xB38E, 0x786F, 0xB38F, 0x7870, 0xB390, 0x7871, 0xB391, 0x7872, - 0xB392, 0x7873, 0xB393, 0x7874, 0xB394, 0x7875, 0xB395, 0x7876, 0xB396, 0x7878, 0xB397, 0x7879, 0xB398, 0x787A, 0xB399, 0x787B, - 0xB39A, 0x787D, 0xB39B, 0x787E, 0xB39C, 0x787F, 0xB39D, 0x7880, 0xB39E, 0x7881, 0xB39F, 0x7882, 0xB3A0, 0x7883, 0xB3A1, 0x573A, - 0xB3A2, 0x5C1D, 0xB3A3, 0x5E38, 0xB3A4, 0x957F, 0xB3A5, 0x507F, 0xB3A6, 0x80A0, 0xB3A7, 0x5382, 0xB3A8, 0x655E, 0xB3A9, 0x7545, - 0xB3AA, 0x5531, 0xB3AB, 0x5021, 0xB3AC, 0x8D85, 0xB3AD, 0x6284, 0xB3AE, 0x949E, 0xB3AF, 0x671D, 0xB3B0, 0x5632, 0xB3B1, 0x6F6E, - 0xB3B2, 0x5DE2, 0xB3B3, 0x5435, 0xB3B4, 0x7092, 0xB3B5, 0x8F66, 0xB3B6, 0x626F, 0xB3B7, 0x64A4, 0xB3B8, 0x63A3, 0xB3B9, 0x5F7B, - 0xB3BA, 0x6F88, 0xB3BB, 0x90F4, 0xB3BC, 0x81E3, 0xB3BD, 0x8FB0, 0xB3BE, 0x5C18, 0xB3BF, 0x6668, 0xB3C0, 0x5FF1, 0xB3C1, 0x6C89, - 0xB3C2, 0x9648, 0xB3C3, 0x8D81, 0xB3C4, 0x886C, 0xB3C5, 0x6491, 0xB3C6, 0x79F0, 0xB3C7, 0x57CE, 0xB3C8, 0x6A59, 0xB3C9, 0x6210, - 0xB3CA, 0x5448, 0xB3CB, 0x4E58, 0xB3CC, 0x7A0B, 0xB3CD, 0x60E9, 0xB3CE, 0x6F84, 0xB3CF, 0x8BDA, 0xB3D0, 0x627F, 0xB3D1, 0x901E, - 0xB3D2, 0x9A8B, 0xB3D3, 0x79E4, 0xB3D4, 0x5403, 0xB3D5, 0x75F4, 0xB3D6, 0x6301, 0xB3D7, 0x5319, 0xB3D8, 0x6C60, 0xB3D9, 0x8FDF, - 0xB3DA, 0x5F1B, 0xB3DB, 0x9A70, 0xB3DC, 0x803B, 0xB3DD, 0x9F7F, 0xB3DE, 0x4F88, 0xB3DF, 0x5C3A, 0xB3E0, 0x8D64, 0xB3E1, 0x7FC5, - 0xB3E2, 0x65A5, 0xB3E3, 0x70BD, 0xB3E4, 0x5145, 0xB3E5, 0x51B2, 0xB3E6, 0x866B, 0xB3E7, 0x5D07, 0xB3E8, 0x5BA0, 0xB3E9, 0x62BD, - 0xB3EA, 0x916C, 0xB3EB, 0x7574, 0xB3EC, 0x8E0C, 0xB3ED, 0x7A20, 0xB3EE, 0x6101, 0xB3EF, 0x7B79, 0xB3F0, 0x4EC7, 0xB3F1, 0x7EF8, - 0xB3F2, 0x7785, 0xB3F3, 0x4E11, 0xB3F4, 0x81ED, 0xB3F5, 0x521D, 0xB3F6, 0x51FA, 0xB3F7, 0x6A71, 0xB3F8, 0x53A8, 0xB3F9, 0x8E87, - 0xB3FA, 0x9504, 0xB3FB, 0x96CF, 0xB3FC, 0x6EC1, 0xB3FD, 0x9664, 0xB3FE, 0x695A, 0xB440, 0x7884, 0xB441, 0x7885, 0xB442, 0x7886, - 0xB443, 0x7888, 0xB444, 0x788A, 0xB445, 0x788B, 0xB446, 0x788F, 0xB447, 0x7890, 0xB448, 0x7892, 0xB449, 0x7894, 0xB44A, 0x7895, - 0xB44B, 0x7896, 0xB44C, 0x7899, 0xB44D, 0x789D, 0xB44E, 0x789E, 0xB44F, 0x78A0, 0xB450, 0x78A2, 0xB451, 0x78A4, 0xB452, 0x78A6, - 0xB453, 0x78A8, 0xB454, 0x78A9, 0xB455, 0x78AA, 0xB456, 0x78AB, 0xB457, 0x78AC, 0xB458, 0x78AD, 0xB459, 0x78AE, 0xB45A, 0x78AF, - 0xB45B, 0x78B5, 0xB45C, 0x78B6, 0xB45D, 0x78B7, 0xB45E, 0x78B8, 0xB45F, 0x78BA, 0xB460, 0x78BB, 0xB461, 0x78BC, 0xB462, 0x78BD, - 0xB463, 0x78BF, 0xB464, 0x78C0, 0xB465, 0x78C2, 0xB466, 0x78C3, 0xB467, 0x78C4, 0xB468, 0x78C6, 0xB469, 0x78C7, 0xB46A, 0x78C8, - 0xB46B, 0x78CC, 0xB46C, 0x78CD, 0xB46D, 0x78CE, 0xB46E, 0x78CF, 0xB46F, 0x78D1, 0xB470, 0x78D2, 0xB471, 0x78D3, 0xB472, 0x78D6, - 0xB473, 0x78D7, 0xB474, 0x78D8, 0xB475, 0x78DA, 0xB476, 0x78DB, 0xB477, 0x78DC, 0xB478, 0x78DD, 0xB479, 0x78DE, 0xB47A, 0x78DF, - 0xB47B, 0x78E0, 0xB47C, 0x78E1, 0xB47D, 0x78E2, 0xB47E, 0x78E3, 0xB480, 0x78E4, 0xB481, 0x78E5, 0xB482, 0x78E6, 0xB483, 0x78E7, - 0xB484, 0x78E9, 0xB485, 0x78EA, 0xB486, 0x78EB, 0xB487, 0x78ED, 0xB488, 0x78EE, 0xB489, 0x78EF, 0xB48A, 0x78F0, 0xB48B, 0x78F1, - 0xB48C, 0x78F3, 0xB48D, 0x78F5, 0xB48E, 0x78F6, 0xB48F, 0x78F8, 0xB490, 0x78F9, 0xB491, 0x78FB, 0xB492, 0x78FC, 0xB493, 0x78FD, - 0xB494, 0x78FE, 0xB495, 0x78FF, 0xB496, 0x7900, 0xB497, 0x7902, 0xB498, 0x7903, 0xB499, 0x7904, 0xB49A, 0x7906, 0xB49B, 0x7907, - 0xB49C, 0x7908, 0xB49D, 0x7909, 0xB49E, 0x790A, 0xB49F, 0x790B, 0xB4A0, 0x790C, 0xB4A1, 0x7840, 0xB4A2, 0x50A8, 0xB4A3, 0x77D7, - 0xB4A4, 0x6410, 0xB4A5, 0x89E6, 0xB4A6, 0x5904, 0xB4A7, 0x63E3, 0xB4A8, 0x5DDD, 0xB4A9, 0x7A7F, 0xB4AA, 0x693D, 0xB4AB, 0x4F20, - 0xB4AC, 0x8239, 0xB4AD, 0x5598, 0xB4AE, 0x4E32, 0xB4AF, 0x75AE, 0xB4B0, 0x7A97, 0xB4B1, 0x5E62, 0xB4B2, 0x5E8A, 0xB4B3, 0x95EF, - 0xB4B4, 0x521B, 0xB4B5, 0x5439, 0xB4B6, 0x708A, 0xB4B7, 0x6376, 0xB4B8, 0x9524, 0xB4B9, 0x5782, 0xB4BA, 0x6625, 0xB4BB, 0x693F, - 0xB4BC, 0x9187, 0xB4BD, 0x5507, 0xB4BE, 0x6DF3, 0xB4BF, 0x7EAF, 0xB4C0, 0x8822, 0xB4C1, 0x6233, 0xB4C2, 0x7EF0, 0xB4C3, 0x75B5, - 0xB4C4, 0x8328, 0xB4C5, 0x78C1, 0xB4C6, 0x96CC, 0xB4C7, 0x8F9E, 0xB4C8, 0x6148, 0xB4C9, 0x74F7, 0xB4CA, 0x8BCD, 0xB4CB, 0x6B64, - 0xB4CC, 0x523A, 0xB4CD, 0x8D50, 0xB4CE, 0x6B21, 0xB4CF, 0x806A, 0xB4D0, 0x8471, 0xB4D1, 0x56F1, 0xB4D2, 0x5306, 0xB4D3, 0x4ECE, - 0xB4D4, 0x4E1B, 0xB4D5, 0x51D1, 0xB4D6, 0x7C97, 0xB4D7, 0x918B, 0xB4D8, 0x7C07, 0xB4D9, 0x4FC3, 0xB4DA, 0x8E7F, 0xB4DB, 0x7BE1, - 0xB4DC, 0x7A9C, 0xB4DD, 0x6467, 0xB4DE, 0x5D14, 0xB4DF, 0x50AC, 0xB4E0, 0x8106, 0xB4E1, 0x7601, 0xB4E2, 0x7CB9, 0xB4E3, 0x6DEC, - 0xB4E4, 0x7FE0, 0xB4E5, 0x6751, 0xB4E6, 0x5B58, 0xB4E7, 0x5BF8, 0xB4E8, 0x78CB, 0xB4E9, 0x64AE, 0xB4EA, 0x6413, 0xB4EB, 0x63AA, - 0xB4EC, 0x632B, 0xB4ED, 0x9519, 0xB4EE, 0x642D, 0xB4EF, 0x8FBE, 0xB4F0, 0x7B54, 0xB4F1, 0x7629, 0xB4F2, 0x6253, 0xB4F3, 0x5927, - 0xB4F4, 0x5446, 0xB4F5, 0x6B79, 0xB4F6, 0x50A3, 0xB4F7, 0x6234, 0xB4F8, 0x5E26, 0xB4F9, 0x6B86, 0xB4FA, 0x4EE3, 0xB4FB, 0x8D37, - 0xB4FC, 0x888B, 0xB4FD, 0x5F85, 0xB4FE, 0x902E, 0xB540, 0x790D, 0xB541, 0x790E, 0xB542, 0x790F, 0xB543, 0x7910, 0xB544, 0x7911, - 0xB545, 0x7912, 0xB546, 0x7914, 0xB547, 0x7915, 0xB548, 0x7916, 0xB549, 0x7917, 0xB54A, 0x7918, 0xB54B, 0x7919, 0xB54C, 0x791A, - 0xB54D, 0x791B, 0xB54E, 0x791C, 0xB54F, 0x791D, 0xB550, 0x791F, 0xB551, 0x7920, 0xB552, 0x7921, 0xB553, 0x7922, 0xB554, 0x7923, - 0xB555, 0x7925, 0xB556, 0x7926, 0xB557, 0x7927, 0xB558, 0x7928, 0xB559, 0x7929, 0xB55A, 0x792A, 0xB55B, 0x792B, 0xB55C, 0x792C, - 0xB55D, 0x792D, 0xB55E, 0x792E, 0xB55F, 0x792F, 0xB560, 0x7930, 0xB561, 0x7931, 0xB562, 0x7932, 0xB563, 0x7933, 0xB564, 0x7935, - 0xB565, 0x7936, 0xB566, 0x7937, 0xB567, 0x7938, 0xB568, 0x7939, 0xB569, 0x793D, 0xB56A, 0x793F, 0xB56B, 0x7942, 0xB56C, 0x7943, - 0xB56D, 0x7944, 0xB56E, 0x7945, 0xB56F, 0x7947, 0xB570, 0x794A, 0xB571, 0x794B, 0xB572, 0x794C, 0xB573, 0x794D, 0xB574, 0x794E, - 0xB575, 0x794F, 0xB576, 0x7950, 0xB577, 0x7951, 0xB578, 0x7952, 0xB579, 0x7954, 0xB57A, 0x7955, 0xB57B, 0x7958, 0xB57C, 0x7959, - 0xB57D, 0x7961, 0xB57E, 0x7963, 0xB580, 0x7964, 0xB581, 0x7966, 0xB582, 0x7969, 0xB583, 0x796A, 0xB584, 0x796B, 0xB585, 0x796C, - 0xB586, 0x796E, 0xB587, 0x7970, 0xB588, 0x7971, 0xB589, 0x7972, 0xB58A, 0x7973, 0xB58B, 0x7974, 0xB58C, 0x7975, 0xB58D, 0x7976, - 0xB58E, 0x7979, 0xB58F, 0x797B, 0xB590, 0x797C, 0xB591, 0x797D, 0xB592, 0x797E, 0xB593, 0x797F, 0xB594, 0x7982, 0xB595, 0x7983, - 0xB596, 0x7986, 0xB597, 0x7987, 0xB598, 0x7988, 0xB599, 0x7989, 0xB59A, 0x798B, 0xB59B, 0x798C, 0xB59C, 0x798D, 0xB59D, 0x798E, - 0xB59E, 0x7990, 0xB59F, 0x7991, 0xB5A0, 0x7992, 0xB5A1, 0x6020, 0xB5A2, 0x803D, 0xB5A3, 0x62C5, 0xB5A4, 0x4E39, 0xB5A5, 0x5355, - 0xB5A6, 0x90F8, 0xB5A7, 0x63B8, 0xB5A8, 0x80C6, 0xB5A9, 0x65E6, 0xB5AA, 0x6C2E, 0xB5AB, 0x4F46, 0xB5AC, 0x60EE, 0xB5AD, 0x6DE1, - 0xB5AE, 0x8BDE, 0xB5AF, 0x5F39, 0xB5B0, 0x86CB, 0xB5B1, 0x5F53, 0xB5B2, 0x6321, 0xB5B3, 0x515A, 0xB5B4, 0x8361, 0xB5B5, 0x6863, - 0xB5B6, 0x5200, 0xB5B7, 0x6363, 0xB5B8, 0x8E48, 0xB5B9, 0x5012, 0xB5BA, 0x5C9B, 0xB5BB, 0x7977, 0xB5BC, 0x5BFC, 0xB5BD, 0x5230, - 0xB5BE, 0x7A3B, 0xB5BF, 0x60BC, 0xB5C0, 0x9053, 0xB5C1, 0x76D7, 0xB5C2, 0x5FB7, 0xB5C3, 0x5F97, 0xB5C4, 0x7684, 0xB5C5, 0x8E6C, - 0xB5C6, 0x706F, 0xB5C7, 0x767B, 0xB5C8, 0x7B49, 0xB5C9, 0x77AA, 0xB5CA, 0x51F3, 0xB5CB, 0x9093, 0xB5CC, 0x5824, 0xB5CD, 0x4F4E, - 0xB5CE, 0x6EF4, 0xB5CF, 0x8FEA, 0xB5D0, 0x654C, 0xB5D1, 0x7B1B, 0xB5D2, 0x72C4, 0xB5D3, 0x6DA4, 0xB5D4, 0x7FDF, 0xB5D5, 0x5AE1, - 0xB5D6, 0x62B5, 0xB5D7, 0x5E95, 0xB5D8, 0x5730, 0xB5D9, 0x8482, 0xB5DA, 0x7B2C, 0xB5DB, 0x5E1D, 0xB5DC, 0x5F1F, 0xB5DD, 0x9012, - 0xB5DE, 0x7F14, 0xB5DF, 0x98A0, 0xB5E0, 0x6382, 0xB5E1, 0x6EC7, 0xB5E2, 0x7898, 0xB5E3, 0x70B9, 0xB5E4, 0x5178, 0xB5E5, 0x975B, - 0xB5E6, 0x57AB, 0xB5E7, 0x7535, 0xB5E8, 0x4F43, 0xB5E9, 0x7538, 0xB5EA, 0x5E97, 0xB5EB, 0x60E6, 0xB5EC, 0x5960, 0xB5ED, 0x6DC0, - 0xB5EE, 0x6BBF, 0xB5EF, 0x7889, 0xB5F0, 0x53FC, 0xB5F1, 0x96D5, 0xB5F2, 0x51CB, 0xB5F3, 0x5201, 0xB5F4, 0x6389, 0xB5F5, 0x540A, - 0xB5F6, 0x9493, 0xB5F7, 0x8C03, 0xB5F8, 0x8DCC, 0xB5F9, 0x7239, 0xB5FA, 0x789F, 0xB5FB, 0x8776, 0xB5FC, 0x8FED, 0xB5FD, 0x8C0D, - 0xB5FE, 0x53E0, 0xB640, 0x7993, 0xB641, 0x7994, 0xB642, 0x7995, 0xB643, 0x7996, 0xB644, 0x7997, 0xB645, 0x7998, 0xB646, 0x7999, - 0xB647, 0x799B, 0xB648, 0x799C, 0xB649, 0x799D, 0xB64A, 0x799E, 0xB64B, 0x799F, 0xB64C, 0x79A0, 0xB64D, 0x79A1, 0xB64E, 0x79A2, - 0xB64F, 0x79A3, 0xB650, 0x79A4, 0xB651, 0x79A5, 0xB652, 0x79A6, 0xB653, 0x79A8, 0xB654, 0x79A9, 0xB655, 0x79AA, 0xB656, 0x79AB, - 0xB657, 0x79AC, 0xB658, 0x79AD, 0xB659, 0x79AE, 0xB65A, 0x79AF, 0xB65B, 0x79B0, 0xB65C, 0x79B1, 0xB65D, 0x79B2, 0xB65E, 0x79B4, - 0xB65F, 0x79B5, 0xB660, 0x79B6, 0xB661, 0x79B7, 0xB662, 0x79B8, 0xB663, 0x79BC, 0xB664, 0x79BF, 0xB665, 0x79C2, 0xB666, 0x79C4, - 0xB667, 0x79C5, 0xB668, 0x79C7, 0xB669, 0x79C8, 0xB66A, 0x79CA, 0xB66B, 0x79CC, 0xB66C, 0x79CE, 0xB66D, 0x79CF, 0xB66E, 0x79D0, - 0xB66F, 0x79D3, 0xB670, 0x79D4, 0xB671, 0x79D6, 0xB672, 0x79D7, 0xB673, 0x79D9, 0xB674, 0x79DA, 0xB675, 0x79DB, 0xB676, 0x79DC, - 0xB677, 0x79DD, 0xB678, 0x79DE, 0xB679, 0x79E0, 0xB67A, 0x79E1, 0xB67B, 0x79E2, 0xB67C, 0x79E5, 0xB67D, 0x79E8, 0xB67E, 0x79EA, - 0xB680, 0x79EC, 0xB681, 0x79EE, 0xB682, 0x79F1, 0xB683, 0x79F2, 0xB684, 0x79F3, 0xB685, 0x79F4, 0xB686, 0x79F5, 0xB687, 0x79F6, - 0xB688, 0x79F7, 0xB689, 0x79F9, 0xB68A, 0x79FA, 0xB68B, 0x79FC, 0xB68C, 0x79FE, 0xB68D, 0x79FF, 0xB68E, 0x7A01, 0xB68F, 0x7A04, - 0xB690, 0x7A05, 0xB691, 0x7A07, 0xB692, 0x7A08, 0xB693, 0x7A09, 0xB694, 0x7A0A, 0xB695, 0x7A0C, 0xB696, 0x7A0F, 0xB697, 0x7A10, - 0xB698, 0x7A11, 0xB699, 0x7A12, 0xB69A, 0x7A13, 0xB69B, 0x7A15, 0xB69C, 0x7A16, 0xB69D, 0x7A18, 0xB69E, 0x7A19, 0xB69F, 0x7A1B, - 0xB6A0, 0x7A1C, 0xB6A1, 0x4E01, 0xB6A2, 0x76EF, 0xB6A3, 0x53EE, 0xB6A4, 0x9489, 0xB6A5, 0x9876, 0xB6A6, 0x9F0E, 0xB6A7, 0x952D, - 0xB6A8, 0x5B9A, 0xB6A9, 0x8BA2, 0xB6AA, 0x4E22, 0xB6AB, 0x4E1C, 0xB6AC, 0x51AC, 0xB6AD, 0x8463, 0xB6AE, 0x61C2, 0xB6AF, 0x52A8, - 0xB6B0, 0x680B, 0xB6B1, 0x4F97, 0xB6B2, 0x606B, 0xB6B3, 0x51BB, 0xB6B4, 0x6D1E, 0xB6B5, 0x515C, 0xB6B6, 0x6296, 0xB6B7, 0x6597, - 0xB6B8, 0x9661, 0xB6B9, 0x8C46, 0xB6BA, 0x9017, 0xB6BB, 0x75D8, 0xB6BC, 0x90FD, 0xB6BD, 0x7763, 0xB6BE, 0x6BD2, 0xB6BF, 0x728A, - 0xB6C0, 0x72EC, 0xB6C1, 0x8BFB, 0xB6C2, 0x5835, 0xB6C3, 0x7779, 0xB6C4, 0x8D4C, 0xB6C5, 0x675C, 0xB6C6, 0x9540, 0xB6C7, 0x809A, - 0xB6C8, 0x5EA6, 0xB6C9, 0x6E21, 0xB6CA, 0x5992, 0xB6CB, 0x7AEF, 0xB6CC, 0x77ED, 0xB6CD, 0x953B, 0xB6CE, 0x6BB5, 0xB6CF, 0x65AD, - 0xB6D0, 0x7F0E, 0xB6D1, 0x5806, 0xB6D2, 0x5151, 0xB6D3, 0x961F, 0xB6D4, 0x5BF9, 0xB6D5, 0x58A9, 0xB6D6, 0x5428, 0xB6D7, 0x8E72, - 0xB6D8, 0x6566, 0xB6D9, 0x987F, 0xB6DA, 0x56E4, 0xB6DB, 0x949D, 0xB6DC, 0x76FE, 0xB6DD, 0x9041, 0xB6DE, 0x6387, 0xB6DF, 0x54C6, - 0xB6E0, 0x591A, 0xB6E1, 0x593A, 0xB6E2, 0x579B, 0xB6E3, 0x8EB2, 0xB6E4, 0x6735, 0xB6E5, 0x8DFA, 0xB6E6, 0x8235, 0xB6E7, 0x5241, - 0xB6E8, 0x60F0, 0xB6E9, 0x5815, 0xB6EA, 0x86FE, 0xB6EB, 0x5CE8, 0xB6EC, 0x9E45, 0xB6ED, 0x4FC4, 0xB6EE, 0x989D, 0xB6EF, 0x8BB9, - 0xB6F0, 0x5A25, 0xB6F1, 0x6076, 0xB6F2, 0x5384, 0xB6F3, 0x627C, 0xB6F4, 0x904F, 0xB6F5, 0x9102, 0xB6F6, 0x997F, 0xB6F7, 0x6069, - 0xB6F8, 0x800C, 0xB6F9, 0x513F, 0xB6FA, 0x8033, 0xB6FB, 0x5C14, 0xB6FC, 0x9975, 0xB6FD, 0x6D31, 0xB6FE, 0x4E8C, 0xB740, 0x7A1D, - 0xB741, 0x7A1F, 0xB742, 0x7A21, 0xB743, 0x7A22, 0xB744, 0x7A24, 0xB745, 0x7A25, 0xB746, 0x7A26, 0xB747, 0x7A27, 0xB748, 0x7A28, - 0xB749, 0x7A29, 0xB74A, 0x7A2A, 0xB74B, 0x7A2B, 0xB74C, 0x7A2C, 0xB74D, 0x7A2D, 0xB74E, 0x7A2E, 0xB74F, 0x7A2F, 0xB750, 0x7A30, - 0xB751, 0x7A31, 0xB752, 0x7A32, 0xB753, 0x7A34, 0xB754, 0x7A35, 0xB755, 0x7A36, 0xB756, 0x7A38, 0xB757, 0x7A3A, 0xB758, 0x7A3E, - 0xB759, 0x7A40, 0xB75A, 0x7A41, 0xB75B, 0x7A42, 0xB75C, 0x7A43, 0xB75D, 0x7A44, 0xB75E, 0x7A45, 0xB75F, 0x7A47, 0xB760, 0x7A48, - 0xB761, 0x7A49, 0xB762, 0x7A4A, 0xB763, 0x7A4B, 0xB764, 0x7A4C, 0xB765, 0x7A4D, 0xB766, 0x7A4E, 0xB767, 0x7A4F, 0xB768, 0x7A50, - 0xB769, 0x7A52, 0xB76A, 0x7A53, 0xB76B, 0x7A54, 0xB76C, 0x7A55, 0xB76D, 0x7A56, 0xB76E, 0x7A58, 0xB76F, 0x7A59, 0xB770, 0x7A5A, - 0xB771, 0x7A5B, 0xB772, 0x7A5C, 0xB773, 0x7A5D, 0xB774, 0x7A5E, 0xB775, 0x7A5F, 0xB776, 0x7A60, 0xB777, 0x7A61, 0xB778, 0x7A62, - 0xB779, 0x7A63, 0xB77A, 0x7A64, 0xB77B, 0x7A65, 0xB77C, 0x7A66, 0xB77D, 0x7A67, 0xB77E, 0x7A68, 0xB780, 0x7A69, 0xB781, 0x7A6A, - 0xB782, 0x7A6B, 0xB783, 0x7A6C, 0xB784, 0x7A6D, 0xB785, 0x7A6E, 0xB786, 0x7A6F, 0xB787, 0x7A71, 0xB788, 0x7A72, 0xB789, 0x7A73, - 0xB78A, 0x7A75, 0xB78B, 0x7A7B, 0xB78C, 0x7A7C, 0xB78D, 0x7A7D, 0xB78E, 0x7A7E, 0xB78F, 0x7A82, 0xB790, 0x7A85, 0xB791, 0x7A87, - 0xB792, 0x7A89, 0xB793, 0x7A8A, 0xB794, 0x7A8B, 0xB795, 0x7A8C, 0xB796, 0x7A8E, 0xB797, 0x7A8F, 0xB798, 0x7A90, 0xB799, 0x7A93, - 0xB79A, 0x7A94, 0xB79B, 0x7A99, 0xB79C, 0x7A9A, 0xB79D, 0x7A9B, 0xB79E, 0x7A9E, 0xB79F, 0x7AA1, 0xB7A0, 0x7AA2, 0xB7A1, 0x8D30, - 0xB7A2, 0x53D1, 0xB7A3, 0x7F5A, 0xB7A4, 0x7B4F, 0xB7A5, 0x4F10, 0xB7A6, 0x4E4F, 0xB7A7, 0x9600, 0xB7A8, 0x6CD5, 0xB7A9, 0x73D0, - 0xB7AA, 0x85E9, 0xB7AB, 0x5E06, 0xB7AC, 0x756A, 0xB7AD, 0x7FFB, 0xB7AE, 0x6A0A, 0xB7AF, 0x77FE, 0xB7B0, 0x9492, 0xB7B1, 0x7E41, - 0xB7B2, 0x51E1, 0xB7B3, 0x70E6, 0xB7B4, 0x53CD, 0xB7B5, 0x8FD4, 0xB7B6, 0x8303, 0xB7B7, 0x8D29, 0xB7B8, 0x72AF, 0xB7B9, 0x996D, - 0xB7BA, 0x6CDB, 0xB7BB, 0x574A, 0xB7BC, 0x82B3, 0xB7BD, 0x65B9, 0xB7BE, 0x80AA, 0xB7BF, 0x623F, 0xB7C0, 0x9632, 0xB7C1, 0x59A8, - 0xB7C2, 0x4EFF, 0xB7C3, 0x8BBF, 0xB7C4, 0x7EBA, 0xB7C5, 0x653E, 0xB7C6, 0x83F2, 0xB7C7, 0x975E, 0xB7C8, 0x5561, 0xB7C9, 0x98DE, - 0xB7CA, 0x80A5, 0xB7CB, 0x532A, 0xB7CC, 0x8BFD, 0xB7CD, 0x5420, 0xB7CE, 0x80BA, 0xB7CF, 0x5E9F, 0xB7D0, 0x6CB8, 0xB7D1, 0x8D39, - 0xB7D2, 0x82AC, 0xB7D3, 0x915A, 0xB7D4, 0x5429, 0xB7D5, 0x6C1B, 0xB7D6, 0x5206, 0xB7D7, 0x7EB7, 0xB7D8, 0x575F, 0xB7D9, 0x711A, - 0xB7DA, 0x6C7E, 0xB7DB, 0x7C89, 0xB7DC, 0x594B, 0xB7DD, 0x4EFD, 0xB7DE, 0x5FFF, 0xB7DF, 0x6124, 0xB7E0, 0x7CAA, 0xB7E1, 0x4E30, - 0xB7E2, 0x5C01, 0xB7E3, 0x67AB, 0xB7E4, 0x8702, 0xB7E5, 0x5CF0, 0xB7E6, 0x950B, 0xB7E7, 0x98CE, 0xB7E8, 0x75AF, 0xB7E9, 0x70FD, - 0xB7EA, 0x9022, 0xB7EB, 0x51AF, 0xB7EC, 0x7F1D, 0xB7ED, 0x8BBD, 0xB7EE, 0x5949, 0xB7EF, 0x51E4, 0xB7F0, 0x4F5B, 0xB7F1, 0x5426, - 0xB7F2, 0x592B, 0xB7F3, 0x6577, 0xB7F4, 0x80A4, 0xB7F5, 0x5B75, 0xB7F6, 0x6276, 0xB7F7, 0x62C2, 0xB7F8, 0x8F90, 0xB7F9, 0x5E45, - 0xB7FA, 0x6C1F, 0xB7FB, 0x7B26, 0xB7FC, 0x4F0F, 0xB7FD, 0x4FD8, 0xB7FE, 0x670D, 0xB840, 0x7AA3, 0xB841, 0x7AA4, 0xB842, 0x7AA7, - 0xB843, 0x7AA9, 0xB844, 0x7AAA, 0xB845, 0x7AAB, 0xB846, 0x7AAE, 0xB847, 0x7AAF, 0xB848, 0x7AB0, 0xB849, 0x7AB1, 0xB84A, 0x7AB2, - 0xB84B, 0x7AB4, 0xB84C, 0x7AB5, 0xB84D, 0x7AB6, 0xB84E, 0x7AB7, 0xB84F, 0x7AB8, 0xB850, 0x7AB9, 0xB851, 0x7ABA, 0xB852, 0x7ABB, - 0xB853, 0x7ABC, 0xB854, 0x7ABD, 0xB855, 0x7ABE, 0xB856, 0x7AC0, 0xB857, 0x7AC1, 0xB858, 0x7AC2, 0xB859, 0x7AC3, 0xB85A, 0x7AC4, - 0xB85B, 0x7AC5, 0xB85C, 0x7AC6, 0xB85D, 0x7AC7, 0xB85E, 0x7AC8, 0xB85F, 0x7AC9, 0xB860, 0x7ACA, 0xB861, 0x7ACC, 0xB862, 0x7ACD, - 0xB863, 0x7ACE, 0xB864, 0x7ACF, 0xB865, 0x7AD0, 0xB866, 0x7AD1, 0xB867, 0x7AD2, 0xB868, 0x7AD3, 0xB869, 0x7AD4, 0xB86A, 0x7AD5, - 0xB86B, 0x7AD7, 0xB86C, 0x7AD8, 0xB86D, 0x7ADA, 0xB86E, 0x7ADB, 0xB86F, 0x7ADC, 0xB870, 0x7ADD, 0xB871, 0x7AE1, 0xB872, 0x7AE2, - 0xB873, 0x7AE4, 0xB874, 0x7AE7, 0xB875, 0x7AE8, 0xB876, 0x7AE9, 0xB877, 0x7AEA, 0xB878, 0x7AEB, 0xB879, 0x7AEC, 0xB87A, 0x7AEE, - 0xB87B, 0x7AF0, 0xB87C, 0x7AF1, 0xB87D, 0x7AF2, 0xB87E, 0x7AF3, 0xB880, 0x7AF4, 0xB881, 0x7AF5, 0xB882, 0x7AF6, 0xB883, 0x7AF7, - 0xB884, 0x7AF8, 0xB885, 0x7AFB, 0xB886, 0x7AFC, 0xB887, 0x7AFE, 0xB888, 0x7B00, 0xB889, 0x7B01, 0xB88A, 0x7B02, 0xB88B, 0x7B05, - 0xB88C, 0x7B07, 0xB88D, 0x7B09, 0xB88E, 0x7B0C, 0xB88F, 0x7B0D, 0xB890, 0x7B0E, 0xB891, 0x7B10, 0xB892, 0x7B12, 0xB893, 0x7B13, - 0xB894, 0x7B16, 0xB895, 0x7B17, 0xB896, 0x7B18, 0xB897, 0x7B1A, 0xB898, 0x7B1C, 0xB899, 0x7B1D, 0xB89A, 0x7B1F, 0xB89B, 0x7B21, - 0xB89C, 0x7B22, 0xB89D, 0x7B23, 0xB89E, 0x7B27, 0xB89F, 0x7B29, 0xB8A0, 0x7B2D, 0xB8A1, 0x6D6E, 0xB8A2, 0x6DAA, 0xB8A3, 0x798F, - 0xB8A4, 0x88B1, 0xB8A5, 0x5F17, 0xB8A6, 0x752B, 0xB8A7, 0x629A, 0xB8A8, 0x8F85, 0xB8A9, 0x4FEF, 0xB8AA, 0x91DC, 0xB8AB, 0x65A7, - 0xB8AC, 0x812F, 0xB8AD, 0x8151, 0xB8AE, 0x5E9C, 0xB8AF, 0x8150, 0xB8B0, 0x8D74, 0xB8B1, 0x526F, 0xB8B2, 0x8986, 0xB8B3, 0x8D4B, - 0xB8B4, 0x590D, 0xB8B5, 0x5085, 0xB8B6, 0x4ED8, 0xB8B7, 0x961C, 0xB8B8, 0x7236, 0xB8B9, 0x8179, 0xB8BA, 0x8D1F, 0xB8BB, 0x5BCC, - 0xB8BC, 0x8BA3, 0xB8BD, 0x9644, 0xB8BE, 0x5987, 0xB8BF, 0x7F1A, 0xB8C0, 0x5490, 0xB8C1, 0x5676, 0xB8C2, 0x560E, 0xB8C3, 0x8BE5, - 0xB8C4, 0x6539, 0xB8C5, 0x6982, 0xB8C6, 0x9499, 0xB8C7, 0x76D6, 0xB8C8, 0x6E89, 0xB8C9, 0x5E72, 0xB8CA, 0x7518, 0xB8CB, 0x6746, - 0xB8CC, 0x67D1, 0xB8CD, 0x7AFF, 0xB8CE, 0x809D, 0xB8CF, 0x8D76, 0xB8D0, 0x611F, 0xB8D1, 0x79C6, 0xB8D2, 0x6562, 0xB8D3, 0x8D63, - 0xB8D4, 0x5188, 0xB8D5, 0x521A, 0xB8D6, 0x94A2, 0xB8D7, 0x7F38, 0xB8D8, 0x809B, 0xB8D9, 0x7EB2, 0xB8DA, 0x5C97, 0xB8DB, 0x6E2F, - 0xB8DC, 0x6760, 0xB8DD, 0x7BD9, 0xB8DE, 0x768B, 0xB8DF, 0x9AD8, 0xB8E0, 0x818F, 0xB8E1, 0x7F94, 0xB8E2, 0x7CD5, 0xB8E3, 0x641E, - 0xB8E4, 0x9550, 0xB8E5, 0x7A3F, 0xB8E6, 0x544A, 0xB8E7, 0x54E5, 0xB8E8, 0x6B4C, 0xB8E9, 0x6401, 0xB8EA, 0x6208, 0xB8EB, 0x9E3D, - 0xB8EC, 0x80F3, 0xB8ED, 0x7599, 0xB8EE, 0x5272, 0xB8EF, 0x9769, 0xB8F0, 0x845B, 0xB8F1, 0x683C, 0xB8F2, 0x86E4, 0xB8F3, 0x9601, - 0xB8F4, 0x9694, 0xB8F5, 0x94EC, 0xB8F6, 0x4E2A, 0xB8F7, 0x5404, 0xB8F8, 0x7ED9, 0xB8F9, 0x6839, 0xB8FA, 0x8DDF, 0xB8FB, 0x8015, - 0xB8FC, 0x66F4, 0xB8FD, 0x5E9A, 0xB8FE, 0x7FB9, 0xB940, 0x7B2F, 0xB941, 0x7B30, 0xB942, 0x7B32, 0xB943, 0x7B34, 0xB944, 0x7B35, - 0xB945, 0x7B36, 0xB946, 0x7B37, 0xB947, 0x7B39, 0xB948, 0x7B3B, 0xB949, 0x7B3D, 0xB94A, 0x7B3F, 0xB94B, 0x7B40, 0xB94C, 0x7B41, - 0xB94D, 0x7B42, 0xB94E, 0x7B43, 0xB94F, 0x7B44, 0xB950, 0x7B46, 0xB951, 0x7B48, 0xB952, 0x7B4A, 0xB953, 0x7B4D, 0xB954, 0x7B4E, - 0xB955, 0x7B53, 0xB956, 0x7B55, 0xB957, 0x7B57, 0xB958, 0x7B59, 0xB959, 0x7B5C, 0xB95A, 0x7B5E, 0xB95B, 0x7B5F, 0xB95C, 0x7B61, - 0xB95D, 0x7B63, 0xB95E, 0x7B64, 0xB95F, 0x7B65, 0xB960, 0x7B66, 0xB961, 0x7B67, 0xB962, 0x7B68, 0xB963, 0x7B69, 0xB964, 0x7B6A, - 0xB965, 0x7B6B, 0xB966, 0x7B6C, 0xB967, 0x7B6D, 0xB968, 0x7B6F, 0xB969, 0x7B70, 0xB96A, 0x7B73, 0xB96B, 0x7B74, 0xB96C, 0x7B76, - 0xB96D, 0x7B78, 0xB96E, 0x7B7A, 0xB96F, 0x7B7C, 0xB970, 0x7B7D, 0xB971, 0x7B7F, 0xB972, 0x7B81, 0xB973, 0x7B82, 0xB974, 0x7B83, - 0xB975, 0x7B84, 0xB976, 0x7B86, 0xB977, 0x7B87, 0xB978, 0x7B88, 0xB979, 0x7B89, 0xB97A, 0x7B8A, 0xB97B, 0x7B8B, 0xB97C, 0x7B8C, - 0xB97D, 0x7B8E, 0xB97E, 0x7B8F, 0xB980, 0x7B91, 0xB981, 0x7B92, 0xB982, 0x7B93, 0xB983, 0x7B96, 0xB984, 0x7B98, 0xB985, 0x7B99, - 0xB986, 0x7B9A, 0xB987, 0x7B9B, 0xB988, 0x7B9E, 0xB989, 0x7B9F, 0xB98A, 0x7BA0, 0xB98B, 0x7BA3, 0xB98C, 0x7BA4, 0xB98D, 0x7BA5, - 0xB98E, 0x7BAE, 0xB98F, 0x7BAF, 0xB990, 0x7BB0, 0xB991, 0x7BB2, 0xB992, 0x7BB3, 0xB993, 0x7BB5, 0xB994, 0x7BB6, 0xB995, 0x7BB7, - 0xB996, 0x7BB9, 0xB997, 0x7BBA, 0xB998, 0x7BBB, 0xB999, 0x7BBC, 0xB99A, 0x7BBD, 0xB99B, 0x7BBE, 0xB99C, 0x7BBF, 0xB99D, 0x7BC0, - 0xB99E, 0x7BC2, 0xB99F, 0x7BC3, 0xB9A0, 0x7BC4, 0xB9A1, 0x57C2, 0xB9A2, 0x803F, 0xB9A3, 0x6897, 0xB9A4, 0x5DE5, 0xB9A5, 0x653B, - 0xB9A6, 0x529F, 0xB9A7, 0x606D, 0xB9A8, 0x9F9A, 0xB9A9, 0x4F9B, 0xB9AA, 0x8EAC, 0xB9AB, 0x516C, 0xB9AC, 0x5BAB, 0xB9AD, 0x5F13, - 0xB9AE, 0x5DE9, 0xB9AF, 0x6C5E, 0xB9B0, 0x62F1, 0xB9B1, 0x8D21, 0xB9B2, 0x5171, 0xB9B3, 0x94A9, 0xB9B4, 0x52FE, 0xB9B5, 0x6C9F, - 0xB9B6, 0x82DF, 0xB9B7, 0x72D7, 0xB9B8, 0x57A2, 0xB9B9, 0x6784, 0xB9BA, 0x8D2D, 0xB9BB, 0x591F, 0xB9BC, 0x8F9C, 0xB9BD, 0x83C7, - 0xB9BE, 0x5495, 0xB9BF, 0x7B8D, 0xB9C0, 0x4F30, 0xB9C1, 0x6CBD, 0xB9C2, 0x5B64, 0xB9C3, 0x59D1, 0xB9C4, 0x9F13, 0xB9C5, 0x53E4, - 0xB9C6, 0x86CA, 0xB9C7, 0x9AA8, 0xB9C8, 0x8C37, 0xB9C9, 0x80A1, 0xB9CA, 0x6545, 0xB9CB, 0x987E, 0xB9CC, 0x56FA, 0xB9CD, 0x96C7, - 0xB9CE, 0x522E, 0xB9CF, 0x74DC, 0xB9D0, 0x5250, 0xB9D1, 0x5BE1, 0xB9D2, 0x6302, 0xB9D3, 0x8902, 0xB9D4, 0x4E56, 0xB9D5, 0x62D0, - 0xB9D6, 0x602A, 0xB9D7, 0x68FA, 0xB9D8, 0x5173, 0xB9D9, 0x5B98, 0xB9DA, 0x51A0, 0xB9DB, 0x89C2, 0xB9DC, 0x7BA1, 0xB9DD, 0x9986, - 0xB9DE, 0x7F50, 0xB9DF, 0x60EF, 0xB9E0, 0x704C, 0xB9E1, 0x8D2F, 0xB9E2, 0x5149, 0xB9E3, 0x5E7F, 0xB9E4, 0x901B, 0xB9E5, 0x7470, - 0xB9E6, 0x89C4, 0xB9E7, 0x572D, 0xB9E8, 0x7845, 0xB9E9, 0x5F52, 0xB9EA, 0x9F9F, 0xB9EB, 0x95FA, 0xB9EC, 0x8F68, 0xB9ED, 0x9B3C, - 0xB9EE, 0x8BE1, 0xB9EF, 0x7678, 0xB9F0, 0x6842, 0xB9F1, 0x67DC, 0xB9F2, 0x8DEA, 0xB9F3, 0x8D35, 0xB9F4, 0x523D, 0xB9F5, 0x8F8A, - 0xB9F6, 0x6EDA, 0xB9F7, 0x68CD, 0xB9F8, 0x9505, 0xB9F9, 0x90ED, 0xB9FA, 0x56FD, 0xB9FB, 0x679C, 0xB9FC, 0x88F9, 0xB9FD, 0x8FC7, - 0xB9FE, 0x54C8, 0xBA40, 0x7BC5, 0xBA41, 0x7BC8, 0xBA42, 0x7BC9, 0xBA43, 0x7BCA, 0xBA44, 0x7BCB, 0xBA45, 0x7BCD, 0xBA46, 0x7BCE, - 0xBA47, 0x7BCF, 0xBA48, 0x7BD0, 0xBA49, 0x7BD2, 0xBA4A, 0x7BD4, 0xBA4B, 0x7BD5, 0xBA4C, 0x7BD6, 0xBA4D, 0x7BD7, 0xBA4E, 0x7BD8, - 0xBA4F, 0x7BDB, 0xBA50, 0x7BDC, 0xBA51, 0x7BDE, 0xBA52, 0x7BDF, 0xBA53, 0x7BE0, 0xBA54, 0x7BE2, 0xBA55, 0x7BE3, 0xBA56, 0x7BE4, - 0xBA57, 0x7BE7, 0xBA58, 0x7BE8, 0xBA59, 0x7BE9, 0xBA5A, 0x7BEB, 0xBA5B, 0x7BEC, 0xBA5C, 0x7BED, 0xBA5D, 0x7BEF, 0xBA5E, 0x7BF0, - 0xBA5F, 0x7BF2, 0xBA60, 0x7BF3, 0xBA61, 0x7BF4, 0xBA62, 0x7BF5, 0xBA63, 0x7BF6, 0xBA64, 0x7BF8, 0xBA65, 0x7BF9, 0xBA66, 0x7BFA, - 0xBA67, 0x7BFB, 0xBA68, 0x7BFD, 0xBA69, 0x7BFF, 0xBA6A, 0x7C00, 0xBA6B, 0x7C01, 0xBA6C, 0x7C02, 0xBA6D, 0x7C03, 0xBA6E, 0x7C04, - 0xBA6F, 0x7C05, 0xBA70, 0x7C06, 0xBA71, 0x7C08, 0xBA72, 0x7C09, 0xBA73, 0x7C0A, 0xBA74, 0x7C0D, 0xBA75, 0x7C0E, 0xBA76, 0x7C10, - 0xBA77, 0x7C11, 0xBA78, 0x7C12, 0xBA79, 0x7C13, 0xBA7A, 0x7C14, 0xBA7B, 0x7C15, 0xBA7C, 0x7C17, 0xBA7D, 0x7C18, 0xBA7E, 0x7C19, - 0xBA80, 0x7C1A, 0xBA81, 0x7C1B, 0xBA82, 0x7C1C, 0xBA83, 0x7C1D, 0xBA84, 0x7C1E, 0xBA85, 0x7C20, 0xBA86, 0x7C21, 0xBA87, 0x7C22, - 0xBA88, 0x7C23, 0xBA89, 0x7C24, 0xBA8A, 0x7C25, 0xBA8B, 0x7C28, 0xBA8C, 0x7C29, 0xBA8D, 0x7C2B, 0xBA8E, 0x7C2C, 0xBA8F, 0x7C2D, - 0xBA90, 0x7C2E, 0xBA91, 0x7C2F, 0xBA92, 0x7C30, 0xBA93, 0x7C31, 0xBA94, 0x7C32, 0xBA95, 0x7C33, 0xBA96, 0x7C34, 0xBA97, 0x7C35, - 0xBA98, 0x7C36, 0xBA99, 0x7C37, 0xBA9A, 0x7C39, 0xBA9B, 0x7C3A, 0xBA9C, 0x7C3B, 0xBA9D, 0x7C3C, 0xBA9E, 0x7C3D, 0xBA9F, 0x7C3E, - 0xBAA0, 0x7C42, 0xBAA1, 0x9AB8, 0xBAA2, 0x5B69, 0xBAA3, 0x6D77, 0xBAA4, 0x6C26, 0xBAA5, 0x4EA5, 0xBAA6, 0x5BB3, 0xBAA7, 0x9A87, - 0xBAA8, 0x9163, 0xBAA9, 0x61A8, 0xBAAA, 0x90AF, 0xBAAB, 0x97E9, 0xBAAC, 0x542B, 0xBAAD, 0x6DB5, 0xBAAE, 0x5BD2, 0xBAAF, 0x51FD, - 0xBAB0, 0x558A, 0xBAB1, 0x7F55, 0xBAB2, 0x7FF0, 0xBAB3, 0x64BC, 0xBAB4, 0x634D, 0xBAB5, 0x65F1, 0xBAB6, 0x61BE, 0xBAB7, 0x608D, - 0xBAB8, 0x710A, 0xBAB9, 0x6C57, 0xBABA, 0x6C49, 0xBABB, 0x592F, 0xBABC, 0x676D, 0xBABD, 0x822A, 0xBABE, 0x58D5, 0xBABF, 0x568E, - 0xBAC0, 0x8C6A, 0xBAC1, 0x6BEB, 0xBAC2, 0x90DD, 0xBAC3, 0x597D, 0xBAC4, 0x8017, 0xBAC5, 0x53F7, 0xBAC6, 0x6D69, 0xBAC7, 0x5475, - 0xBAC8, 0x559D, 0xBAC9, 0x8377, 0xBACA, 0x83CF, 0xBACB, 0x6838, 0xBACC, 0x79BE, 0xBACD, 0x548C, 0xBACE, 0x4F55, 0xBACF, 0x5408, - 0xBAD0, 0x76D2, 0xBAD1, 0x8C89, 0xBAD2, 0x9602, 0xBAD3, 0x6CB3, 0xBAD4, 0x6DB8, 0xBAD5, 0x8D6B, 0xBAD6, 0x8910, 0xBAD7, 0x9E64, - 0xBAD8, 0x8D3A, 0xBAD9, 0x563F, 0xBADA, 0x9ED1, 0xBADB, 0x75D5, 0xBADC, 0x5F88, 0xBADD, 0x72E0, 0xBADE, 0x6068, 0xBADF, 0x54FC, - 0xBAE0, 0x4EA8, 0xBAE1, 0x6A2A, 0xBAE2, 0x8861, 0xBAE3, 0x6052, 0xBAE4, 0x8F70, 0xBAE5, 0x54C4, 0xBAE6, 0x70D8, 0xBAE7, 0x8679, - 0xBAE8, 0x9E3F, 0xBAE9, 0x6D2A, 0xBAEA, 0x5B8F, 0xBAEB, 0x5F18, 0xBAEC, 0x7EA2, 0xBAED, 0x5589, 0xBAEE, 0x4FAF, 0xBAEF, 0x7334, - 0xBAF0, 0x543C, 0xBAF1, 0x539A, 0xBAF2, 0x5019, 0xBAF3, 0x540E, 0xBAF4, 0x547C, 0xBAF5, 0x4E4E, 0xBAF6, 0x5FFD, 0xBAF7, 0x745A, - 0xBAF8, 0x58F6, 0xBAF9, 0x846B, 0xBAFA, 0x80E1, 0xBAFB, 0x8774, 0xBAFC, 0x72D0, 0xBAFD, 0x7CCA, 0xBAFE, 0x6E56, 0xBB40, 0x7C43, - 0xBB41, 0x7C44, 0xBB42, 0x7C45, 0xBB43, 0x7C46, 0xBB44, 0x7C47, 0xBB45, 0x7C48, 0xBB46, 0x7C49, 0xBB47, 0x7C4A, 0xBB48, 0x7C4B, - 0xBB49, 0x7C4C, 0xBB4A, 0x7C4E, 0xBB4B, 0x7C4F, 0xBB4C, 0x7C50, 0xBB4D, 0x7C51, 0xBB4E, 0x7C52, 0xBB4F, 0x7C53, 0xBB50, 0x7C54, - 0xBB51, 0x7C55, 0xBB52, 0x7C56, 0xBB53, 0x7C57, 0xBB54, 0x7C58, 0xBB55, 0x7C59, 0xBB56, 0x7C5A, 0xBB57, 0x7C5B, 0xBB58, 0x7C5C, - 0xBB59, 0x7C5D, 0xBB5A, 0x7C5E, 0xBB5B, 0x7C5F, 0xBB5C, 0x7C60, 0xBB5D, 0x7C61, 0xBB5E, 0x7C62, 0xBB5F, 0x7C63, 0xBB60, 0x7C64, - 0xBB61, 0x7C65, 0xBB62, 0x7C66, 0xBB63, 0x7C67, 0xBB64, 0x7C68, 0xBB65, 0x7C69, 0xBB66, 0x7C6A, 0xBB67, 0x7C6B, 0xBB68, 0x7C6C, - 0xBB69, 0x7C6D, 0xBB6A, 0x7C6E, 0xBB6B, 0x7C6F, 0xBB6C, 0x7C70, 0xBB6D, 0x7C71, 0xBB6E, 0x7C72, 0xBB6F, 0x7C75, 0xBB70, 0x7C76, - 0xBB71, 0x7C77, 0xBB72, 0x7C78, 0xBB73, 0x7C79, 0xBB74, 0x7C7A, 0xBB75, 0x7C7E, 0xBB76, 0x7C7F, 0xBB77, 0x7C80, 0xBB78, 0x7C81, - 0xBB79, 0x7C82, 0xBB7A, 0x7C83, 0xBB7B, 0x7C84, 0xBB7C, 0x7C85, 0xBB7D, 0x7C86, 0xBB7E, 0x7C87, 0xBB80, 0x7C88, 0xBB81, 0x7C8A, - 0xBB82, 0x7C8B, 0xBB83, 0x7C8C, 0xBB84, 0x7C8D, 0xBB85, 0x7C8E, 0xBB86, 0x7C8F, 0xBB87, 0x7C90, 0xBB88, 0x7C93, 0xBB89, 0x7C94, - 0xBB8A, 0x7C96, 0xBB8B, 0x7C99, 0xBB8C, 0x7C9A, 0xBB8D, 0x7C9B, 0xBB8E, 0x7CA0, 0xBB8F, 0x7CA1, 0xBB90, 0x7CA3, 0xBB91, 0x7CA6, - 0xBB92, 0x7CA7, 0xBB93, 0x7CA8, 0xBB94, 0x7CA9, 0xBB95, 0x7CAB, 0xBB96, 0x7CAC, 0xBB97, 0x7CAD, 0xBB98, 0x7CAF, 0xBB99, 0x7CB0, - 0xBB9A, 0x7CB4, 0xBB9B, 0x7CB5, 0xBB9C, 0x7CB6, 0xBB9D, 0x7CB7, 0xBB9E, 0x7CB8, 0xBB9F, 0x7CBA, 0xBBA0, 0x7CBB, 0xBBA1, 0x5F27, - 0xBBA2, 0x864E, 0xBBA3, 0x552C, 0xBBA4, 0x62A4, 0xBBA5, 0x4E92, 0xBBA6, 0x6CAA, 0xBBA7, 0x6237, 0xBBA8, 0x82B1, 0xBBA9, 0x54D7, - 0xBBAA, 0x534E, 0xBBAB, 0x733E, 0xBBAC, 0x6ED1, 0xBBAD, 0x753B, 0xBBAE, 0x5212, 0xBBAF, 0x5316, 0xBBB0, 0x8BDD, 0xBBB1, 0x69D0, - 0xBBB2, 0x5F8A, 0xBBB3, 0x6000, 0xBBB4, 0x6DEE, 0xBBB5, 0x574F, 0xBBB6, 0x6B22, 0xBBB7, 0x73AF, 0xBBB8, 0x6853, 0xBBB9, 0x8FD8, - 0xBBBA, 0x7F13, 0xBBBB, 0x6362, 0xBBBC, 0x60A3, 0xBBBD, 0x5524, 0xBBBE, 0x75EA, 0xBBBF, 0x8C62, 0xBBC0, 0x7115, 0xBBC1, 0x6DA3, - 0xBBC2, 0x5BA6, 0xBBC3, 0x5E7B, 0xBBC4, 0x8352, 0xBBC5, 0x614C, 0xBBC6, 0x9EC4, 0xBBC7, 0x78FA, 0xBBC8, 0x8757, 0xBBC9, 0x7C27, - 0xBBCA, 0x7687, 0xBBCB, 0x51F0, 0xBBCC, 0x60F6, 0xBBCD, 0x714C, 0xBBCE, 0x6643, 0xBBCF, 0x5E4C, 0xBBD0, 0x604D, 0xBBD1, 0x8C0E, - 0xBBD2, 0x7070, 0xBBD3, 0x6325, 0xBBD4, 0x8F89, 0xBBD5, 0x5FBD, 0xBBD6, 0x6062, 0xBBD7, 0x86D4, 0xBBD8, 0x56DE, 0xBBD9, 0x6BC1, - 0xBBDA, 0x6094, 0xBBDB, 0x6167, 0xBBDC, 0x5349, 0xBBDD, 0x60E0, 0xBBDE, 0x6666, 0xBBDF, 0x8D3F, 0xBBE0, 0x79FD, 0xBBE1, 0x4F1A, - 0xBBE2, 0x70E9, 0xBBE3, 0x6C47, 0xBBE4, 0x8BB3, 0xBBE5, 0x8BF2, 0xBBE6, 0x7ED8, 0xBBE7, 0x8364, 0xBBE8, 0x660F, 0xBBE9, 0x5A5A, - 0xBBEA, 0x9B42, 0xBBEB, 0x6D51, 0xBBEC, 0x6DF7, 0xBBED, 0x8C41, 0xBBEE, 0x6D3B, 0xBBEF, 0x4F19, 0xBBF0, 0x706B, 0xBBF1, 0x83B7, - 0xBBF2, 0x6216, 0xBBF3, 0x60D1, 0xBBF4, 0x970D, 0xBBF5, 0x8D27, 0xBBF6, 0x7978, 0xBBF7, 0x51FB, 0xBBF8, 0x573E, 0xBBF9, 0x57FA, - 0xBBFA, 0x673A, 0xBBFB, 0x7578, 0xBBFC, 0x7A3D, 0xBBFD, 0x79EF, 0xBBFE, 0x7B95, 0xBC40, 0x7CBF, 0xBC41, 0x7CC0, 0xBC42, 0x7CC2, - 0xBC43, 0x7CC3, 0xBC44, 0x7CC4, 0xBC45, 0x7CC6, 0xBC46, 0x7CC9, 0xBC47, 0x7CCB, 0xBC48, 0x7CCE, 0xBC49, 0x7CCF, 0xBC4A, 0x7CD0, - 0xBC4B, 0x7CD1, 0xBC4C, 0x7CD2, 0xBC4D, 0x7CD3, 0xBC4E, 0x7CD4, 0xBC4F, 0x7CD8, 0xBC50, 0x7CDA, 0xBC51, 0x7CDB, 0xBC52, 0x7CDD, - 0xBC53, 0x7CDE, 0xBC54, 0x7CE1, 0xBC55, 0x7CE2, 0xBC56, 0x7CE3, 0xBC57, 0x7CE4, 0xBC58, 0x7CE5, 0xBC59, 0x7CE6, 0xBC5A, 0x7CE7, - 0xBC5B, 0x7CE9, 0xBC5C, 0x7CEA, 0xBC5D, 0x7CEB, 0xBC5E, 0x7CEC, 0xBC5F, 0x7CED, 0xBC60, 0x7CEE, 0xBC61, 0x7CF0, 0xBC62, 0x7CF1, - 0xBC63, 0x7CF2, 0xBC64, 0x7CF3, 0xBC65, 0x7CF4, 0xBC66, 0x7CF5, 0xBC67, 0x7CF6, 0xBC68, 0x7CF7, 0xBC69, 0x7CF9, 0xBC6A, 0x7CFA, - 0xBC6B, 0x7CFC, 0xBC6C, 0x7CFD, 0xBC6D, 0x7CFE, 0xBC6E, 0x7CFF, 0xBC6F, 0x7D00, 0xBC70, 0x7D01, 0xBC71, 0x7D02, 0xBC72, 0x7D03, - 0xBC73, 0x7D04, 0xBC74, 0x7D05, 0xBC75, 0x7D06, 0xBC76, 0x7D07, 0xBC77, 0x7D08, 0xBC78, 0x7D09, 0xBC79, 0x7D0B, 0xBC7A, 0x7D0C, - 0xBC7B, 0x7D0D, 0xBC7C, 0x7D0E, 0xBC7D, 0x7D0F, 0xBC7E, 0x7D10, 0xBC80, 0x7D11, 0xBC81, 0x7D12, 0xBC82, 0x7D13, 0xBC83, 0x7D14, - 0xBC84, 0x7D15, 0xBC85, 0x7D16, 0xBC86, 0x7D17, 0xBC87, 0x7D18, 0xBC88, 0x7D19, 0xBC89, 0x7D1A, 0xBC8A, 0x7D1B, 0xBC8B, 0x7D1C, - 0xBC8C, 0x7D1D, 0xBC8D, 0x7D1E, 0xBC8E, 0x7D1F, 0xBC8F, 0x7D21, 0xBC90, 0x7D23, 0xBC91, 0x7D24, 0xBC92, 0x7D25, 0xBC93, 0x7D26, - 0xBC94, 0x7D28, 0xBC95, 0x7D29, 0xBC96, 0x7D2A, 0xBC97, 0x7D2C, 0xBC98, 0x7D2D, 0xBC99, 0x7D2E, 0xBC9A, 0x7D30, 0xBC9B, 0x7D31, - 0xBC9C, 0x7D32, 0xBC9D, 0x7D33, 0xBC9E, 0x7D34, 0xBC9F, 0x7D35, 0xBCA0, 0x7D36, 0xBCA1, 0x808C, 0xBCA2, 0x9965, 0xBCA3, 0x8FF9, - 0xBCA4, 0x6FC0, 0xBCA5, 0x8BA5, 0xBCA6, 0x9E21, 0xBCA7, 0x59EC, 0xBCA8, 0x7EE9, 0xBCA9, 0x7F09, 0xBCAA, 0x5409, 0xBCAB, 0x6781, - 0xBCAC, 0x68D8, 0xBCAD, 0x8F91, 0xBCAE, 0x7C4D, 0xBCAF, 0x96C6, 0xBCB0, 0x53CA, 0xBCB1, 0x6025, 0xBCB2, 0x75BE, 0xBCB3, 0x6C72, - 0xBCB4, 0x5373, 0xBCB5, 0x5AC9, 0xBCB6, 0x7EA7, 0xBCB7, 0x6324, 0xBCB8, 0x51E0, 0xBCB9, 0x810A, 0xBCBA, 0x5DF1, 0xBCBB, 0x84DF, - 0xBCBC, 0x6280, 0xBCBD, 0x5180, 0xBCBE, 0x5B63, 0xBCBF, 0x4F0E, 0xBCC0, 0x796D, 0xBCC1, 0x5242, 0xBCC2, 0x60B8, 0xBCC3, 0x6D4E, - 0xBCC4, 0x5BC4, 0xBCC5, 0x5BC2, 0xBCC6, 0x8BA1, 0xBCC7, 0x8BB0, 0xBCC8, 0x65E2, 0xBCC9, 0x5FCC, 0xBCCA, 0x9645, 0xBCCB, 0x5993, - 0xBCCC, 0x7EE7, 0xBCCD, 0x7EAA, 0xBCCE, 0x5609, 0xBCCF, 0x67B7, 0xBCD0, 0x5939, 0xBCD1, 0x4F73, 0xBCD2, 0x5BB6, 0xBCD3, 0x52A0, - 0xBCD4, 0x835A, 0xBCD5, 0x988A, 0xBCD6, 0x8D3E, 0xBCD7, 0x7532, 0xBCD8, 0x94BE, 0xBCD9, 0x5047, 0xBCDA, 0x7A3C, 0xBCDB, 0x4EF7, - 0xBCDC, 0x67B6, 0xBCDD, 0x9A7E, 0xBCDE, 0x5AC1, 0xBCDF, 0x6B7C, 0xBCE0, 0x76D1, 0xBCE1, 0x575A, 0xBCE2, 0x5C16, 0xBCE3, 0x7B3A, - 0xBCE4, 0x95F4, 0xBCE5, 0x714E, 0xBCE6, 0x517C, 0xBCE7, 0x80A9, 0xBCE8, 0x8270, 0xBCE9, 0x5978, 0xBCEA, 0x7F04, 0xBCEB, 0x8327, - 0xBCEC, 0x68C0, 0xBCED, 0x67EC, 0xBCEE, 0x78B1, 0xBCEF, 0x7877, 0xBCF0, 0x62E3, 0xBCF1, 0x6361, 0xBCF2, 0x7B80, 0xBCF3, 0x4FED, - 0xBCF4, 0x526A, 0xBCF5, 0x51CF, 0xBCF6, 0x8350, 0xBCF7, 0x69DB, 0xBCF8, 0x9274, 0xBCF9, 0x8DF5, 0xBCFA, 0x8D31, 0xBCFB, 0x89C1, - 0xBCFC, 0x952E, 0xBCFD, 0x7BAD, 0xBCFE, 0x4EF6, 0xBD40, 0x7D37, 0xBD41, 0x7D38, 0xBD42, 0x7D39, 0xBD43, 0x7D3A, 0xBD44, 0x7D3B, - 0xBD45, 0x7D3C, 0xBD46, 0x7D3D, 0xBD47, 0x7D3E, 0xBD48, 0x7D3F, 0xBD49, 0x7D40, 0xBD4A, 0x7D41, 0xBD4B, 0x7D42, 0xBD4C, 0x7D43, - 0xBD4D, 0x7D44, 0xBD4E, 0x7D45, 0xBD4F, 0x7D46, 0xBD50, 0x7D47, 0xBD51, 0x7D48, 0xBD52, 0x7D49, 0xBD53, 0x7D4A, 0xBD54, 0x7D4B, - 0xBD55, 0x7D4C, 0xBD56, 0x7D4D, 0xBD57, 0x7D4E, 0xBD58, 0x7D4F, 0xBD59, 0x7D50, 0xBD5A, 0x7D51, 0xBD5B, 0x7D52, 0xBD5C, 0x7D53, - 0xBD5D, 0x7D54, 0xBD5E, 0x7D55, 0xBD5F, 0x7D56, 0xBD60, 0x7D57, 0xBD61, 0x7D58, 0xBD62, 0x7D59, 0xBD63, 0x7D5A, 0xBD64, 0x7D5B, - 0xBD65, 0x7D5C, 0xBD66, 0x7D5D, 0xBD67, 0x7D5E, 0xBD68, 0x7D5F, 0xBD69, 0x7D60, 0xBD6A, 0x7D61, 0xBD6B, 0x7D62, 0xBD6C, 0x7D63, - 0xBD6D, 0x7D64, 0xBD6E, 0x7D65, 0xBD6F, 0x7D66, 0xBD70, 0x7D67, 0xBD71, 0x7D68, 0xBD72, 0x7D69, 0xBD73, 0x7D6A, 0xBD74, 0x7D6B, - 0xBD75, 0x7D6C, 0xBD76, 0x7D6D, 0xBD77, 0x7D6F, 0xBD78, 0x7D70, 0xBD79, 0x7D71, 0xBD7A, 0x7D72, 0xBD7B, 0x7D73, 0xBD7C, 0x7D74, - 0xBD7D, 0x7D75, 0xBD7E, 0x7D76, 0xBD80, 0x7D78, 0xBD81, 0x7D79, 0xBD82, 0x7D7A, 0xBD83, 0x7D7B, 0xBD84, 0x7D7C, 0xBD85, 0x7D7D, - 0xBD86, 0x7D7E, 0xBD87, 0x7D7F, 0xBD88, 0x7D80, 0xBD89, 0x7D81, 0xBD8A, 0x7D82, 0xBD8B, 0x7D83, 0xBD8C, 0x7D84, 0xBD8D, 0x7D85, - 0xBD8E, 0x7D86, 0xBD8F, 0x7D87, 0xBD90, 0x7D88, 0xBD91, 0x7D89, 0xBD92, 0x7D8A, 0xBD93, 0x7D8B, 0xBD94, 0x7D8C, 0xBD95, 0x7D8D, - 0xBD96, 0x7D8E, 0xBD97, 0x7D8F, 0xBD98, 0x7D90, 0xBD99, 0x7D91, 0xBD9A, 0x7D92, 0xBD9B, 0x7D93, 0xBD9C, 0x7D94, 0xBD9D, 0x7D95, - 0xBD9E, 0x7D96, 0xBD9F, 0x7D97, 0xBDA0, 0x7D98, 0xBDA1, 0x5065, 0xBDA2, 0x8230, 0xBDA3, 0x5251, 0xBDA4, 0x996F, 0xBDA5, 0x6E10, - 0xBDA6, 0x6E85, 0xBDA7, 0x6DA7, 0xBDA8, 0x5EFA, 0xBDA9, 0x50F5, 0xBDAA, 0x59DC, 0xBDAB, 0x5C06, 0xBDAC, 0x6D46, 0xBDAD, 0x6C5F, - 0xBDAE, 0x7586, 0xBDAF, 0x848B, 0xBDB0, 0x6868, 0xBDB1, 0x5956, 0xBDB2, 0x8BB2, 0xBDB3, 0x5320, 0xBDB4, 0x9171, 0xBDB5, 0x964D, - 0xBDB6, 0x8549, 0xBDB7, 0x6912, 0xBDB8, 0x7901, 0xBDB9, 0x7126, 0xBDBA, 0x80F6, 0xBDBB, 0x4EA4, 0xBDBC, 0x90CA, 0xBDBD, 0x6D47, - 0xBDBE, 0x9A84, 0xBDBF, 0x5A07, 0xBDC0, 0x56BC, 0xBDC1, 0x6405, 0xBDC2, 0x94F0, 0xBDC3, 0x77EB, 0xBDC4, 0x4FA5, 0xBDC5, 0x811A, - 0xBDC6, 0x72E1, 0xBDC7, 0x89D2, 0xBDC8, 0x997A, 0xBDC9, 0x7F34, 0xBDCA, 0x7EDE, 0xBDCB, 0x527F, 0xBDCC, 0x6559, 0xBDCD, 0x9175, - 0xBDCE, 0x8F7F, 0xBDCF, 0x8F83, 0xBDD0, 0x53EB, 0xBDD1, 0x7A96, 0xBDD2, 0x63ED, 0xBDD3, 0x63A5, 0xBDD4, 0x7686, 0xBDD5, 0x79F8, - 0xBDD6, 0x8857, 0xBDD7, 0x9636, 0xBDD8, 0x622A, 0xBDD9, 0x52AB, 0xBDDA, 0x8282, 0xBDDB, 0x6854, 0xBDDC, 0x6770, 0xBDDD, 0x6377, - 0xBDDE, 0x776B, 0xBDDF, 0x7AED, 0xBDE0, 0x6D01, 0xBDE1, 0x7ED3, 0xBDE2, 0x89E3, 0xBDE3, 0x59D0, 0xBDE4, 0x6212, 0xBDE5, 0x85C9, - 0xBDE6, 0x82A5, 0xBDE7, 0x754C, 0xBDE8, 0x501F, 0xBDE9, 0x4ECB, 0xBDEA, 0x75A5, 0xBDEB, 0x8BEB, 0xBDEC, 0x5C4A, 0xBDED, 0x5DFE, - 0xBDEE, 0x7B4B, 0xBDEF, 0x65A4, 0xBDF0, 0x91D1, 0xBDF1, 0x4ECA, 0xBDF2, 0x6D25, 0xBDF3, 0x895F, 0xBDF4, 0x7D27, 0xBDF5, 0x9526, - 0xBDF6, 0x4EC5, 0xBDF7, 0x8C28, 0xBDF8, 0x8FDB, 0xBDF9, 0x9773, 0xBDFA, 0x664B, 0xBDFB, 0x7981, 0xBDFC, 0x8FD1, 0xBDFD, 0x70EC, - 0xBDFE, 0x6D78, 0xBE40, 0x7D99, 0xBE41, 0x7D9A, 0xBE42, 0x7D9B, 0xBE43, 0x7D9C, 0xBE44, 0x7D9D, 0xBE45, 0x7D9E, 0xBE46, 0x7D9F, - 0xBE47, 0x7DA0, 0xBE48, 0x7DA1, 0xBE49, 0x7DA2, 0xBE4A, 0x7DA3, 0xBE4B, 0x7DA4, 0xBE4C, 0x7DA5, 0xBE4D, 0x7DA7, 0xBE4E, 0x7DA8, - 0xBE4F, 0x7DA9, 0xBE50, 0x7DAA, 0xBE51, 0x7DAB, 0xBE52, 0x7DAC, 0xBE53, 0x7DAD, 0xBE54, 0x7DAF, 0xBE55, 0x7DB0, 0xBE56, 0x7DB1, - 0xBE57, 0x7DB2, 0xBE58, 0x7DB3, 0xBE59, 0x7DB4, 0xBE5A, 0x7DB5, 0xBE5B, 0x7DB6, 0xBE5C, 0x7DB7, 0xBE5D, 0x7DB8, 0xBE5E, 0x7DB9, - 0xBE5F, 0x7DBA, 0xBE60, 0x7DBB, 0xBE61, 0x7DBC, 0xBE62, 0x7DBD, 0xBE63, 0x7DBE, 0xBE64, 0x7DBF, 0xBE65, 0x7DC0, 0xBE66, 0x7DC1, - 0xBE67, 0x7DC2, 0xBE68, 0x7DC3, 0xBE69, 0x7DC4, 0xBE6A, 0x7DC5, 0xBE6B, 0x7DC6, 0xBE6C, 0x7DC7, 0xBE6D, 0x7DC8, 0xBE6E, 0x7DC9, - 0xBE6F, 0x7DCA, 0xBE70, 0x7DCB, 0xBE71, 0x7DCC, 0xBE72, 0x7DCD, 0xBE73, 0x7DCE, 0xBE74, 0x7DCF, 0xBE75, 0x7DD0, 0xBE76, 0x7DD1, - 0xBE77, 0x7DD2, 0xBE78, 0x7DD3, 0xBE79, 0x7DD4, 0xBE7A, 0x7DD5, 0xBE7B, 0x7DD6, 0xBE7C, 0x7DD7, 0xBE7D, 0x7DD8, 0xBE7E, 0x7DD9, - 0xBE80, 0x7DDA, 0xBE81, 0x7DDB, 0xBE82, 0x7DDC, 0xBE83, 0x7DDD, 0xBE84, 0x7DDE, 0xBE85, 0x7DDF, 0xBE86, 0x7DE0, 0xBE87, 0x7DE1, - 0xBE88, 0x7DE2, 0xBE89, 0x7DE3, 0xBE8A, 0x7DE4, 0xBE8B, 0x7DE5, 0xBE8C, 0x7DE6, 0xBE8D, 0x7DE7, 0xBE8E, 0x7DE8, 0xBE8F, 0x7DE9, - 0xBE90, 0x7DEA, 0xBE91, 0x7DEB, 0xBE92, 0x7DEC, 0xBE93, 0x7DED, 0xBE94, 0x7DEE, 0xBE95, 0x7DEF, 0xBE96, 0x7DF0, 0xBE97, 0x7DF1, - 0xBE98, 0x7DF2, 0xBE99, 0x7DF3, 0xBE9A, 0x7DF4, 0xBE9B, 0x7DF5, 0xBE9C, 0x7DF6, 0xBE9D, 0x7DF7, 0xBE9E, 0x7DF8, 0xBE9F, 0x7DF9, - 0xBEA0, 0x7DFA, 0xBEA1, 0x5C3D, 0xBEA2, 0x52B2, 0xBEA3, 0x8346, 0xBEA4, 0x5162, 0xBEA5, 0x830E, 0xBEA6, 0x775B, 0xBEA7, 0x6676, - 0xBEA8, 0x9CB8, 0xBEA9, 0x4EAC, 0xBEAA, 0x60CA, 0xBEAB, 0x7CBE, 0xBEAC, 0x7CB3, 0xBEAD, 0x7ECF, 0xBEAE, 0x4E95, 0xBEAF, 0x8B66, - 0xBEB0, 0x666F, 0xBEB1, 0x9888, 0xBEB2, 0x9759, 0xBEB3, 0x5883, 0xBEB4, 0x656C, 0xBEB5, 0x955C, 0xBEB6, 0x5F84, 0xBEB7, 0x75C9, - 0xBEB8, 0x9756, 0xBEB9, 0x7ADF, 0xBEBA, 0x7ADE, 0xBEBB, 0x51C0, 0xBEBC, 0x70AF, 0xBEBD, 0x7A98, 0xBEBE, 0x63EA, 0xBEBF, 0x7A76, - 0xBEC0, 0x7EA0, 0xBEC1, 0x7396, 0xBEC2, 0x97ED, 0xBEC3, 0x4E45, 0xBEC4, 0x7078, 0xBEC5, 0x4E5D, 0xBEC6, 0x9152, 0xBEC7, 0x53A9, - 0xBEC8, 0x6551, 0xBEC9, 0x65E7, 0xBECA, 0x81FC, 0xBECB, 0x8205, 0xBECC, 0x548E, 0xBECD, 0x5C31, 0xBECE, 0x759A, 0xBECF, 0x97A0, - 0xBED0, 0x62D8, 0xBED1, 0x72D9, 0xBED2, 0x75BD, 0xBED3, 0x5C45, 0xBED4, 0x9A79, 0xBED5, 0x83CA, 0xBED6, 0x5C40, 0xBED7, 0x5480, - 0xBED8, 0x77E9, 0xBED9, 0x4E3E, 0xBEDA, 0x6CAE, 0xBEDB, 0x805A, 0xBEDC, 0x62D2, 0xBEDD, 0x636E, 0xBEDE, 0x5DE8, 0xBEDF, 0x5177, - 0xBEE0, 0x8DDD, 0xBEE1, 0x8E1E, 0xBEE2, 0x952F, 0xBEE3, 0x4FF1, 0xBEE4, 0x53E5, 0xBEE5, 0x60E7, 0xBEE6, 0x70AC, 0xBEE7, 0x5267, - 0xBEE8, 0x6350, 0xBEE9, 0x9E43, 0xBEEA, 0x5A1F, 0xBEEB, 0x5026, 0xBEEC, 0x7737, 0xBEED, 0x5377, 0xBEEE, 0x7EE2, 0xBEEF, 0x6485, - 0xBEF0, 0x652B, 0xBEF1, 0x6289, 0xBEF2, 0x6398, 0xBEF3, 0x5014, 0xBEF4, 0x7235, 0xBEF5, 0x89C9, 0xBEF6, 0x51B3, 0xBEF7, 0x8BC0, - 0xBEF8, 0x7EDD, 0xBEF9, 0x5747, 0xBEFA, 0x83CC, 0xBEFB, 0x94A7, 0xBEFC, 0x519B, 0xBEFD, 0x541B, 0xBEFE, 0x5CFB, 0xBF40, 0x7DFB, - 0xBF41, 0x7DFC, 0xBF42, 0x7DFD, 0xBF43, 0x7DFE, 0xBF44, 0x7DFF, 0xBF45, 0x7E00, 0xBF46, 0x7E01, 0xBF47, 0x7E02, 0xBF48, 0x7E03, - 0xBF49, 0x7E04, 0xBF4A, 0x7E05, 0xBF4B, 0x7E06, 0xBF4C, 0x7E07, 0xBF4D, 0x7E08, 0xBF4E, 0x7E09, 0xBF4F, 0x7E0A, 0xBF50, 0x7E0B, - 0xBF51, 0x7E0C, 0xBF52, 0x7E0D, 0xBF53, 0x7E0E, 0xBF54, 0x7E0F, 0xBF55, 0x7E10, 0xBF56, 0x7E11, 0xBF57, 0x7E12, 0xBF58, 0x7E13, - 0xBF59, 0x7E14, 0xBF5A, 0x7E15, 0xBF5B, 0x7E16, 0xBF5C, 0x7E17, 0xBF5D, 0x7E18, 0xBF5E, 0x7E19, 0xBF5F, 0x7E1A, 0xBF60, 0x7E1B, - 0xBF61, 0x7E1C, 0xBF62, 0x7E1D, 0xBF63, 0x7E1E, 0xBF64, 0x7E1F, 0xBF65, 0x7E20, 0xBF66, 0x7E21, 0xBF67, 0x7E22, 0xBF68, 0x7E23, - 0xBF69, 0x7E24, 0xBF6A, 0x7E25, 0xBF6B, 0x7E26, 0xBF6C, 0x7E27, 0xBF6D, 0x7E28, 0xBF6E, 0x7E29, 0xBF6F, 0x7E2A, 0xBF70, 0x7E2B, - 0xBF71, 0x7E2C, 0xBF72, 0x7E2D, 0xBF73, 0x7E2E, 0xBF74, 0x7E2F, 0xBF75, 0x7E30, 0xBF76, 0x7E31, 0xBF77, 0x7E32, 0xBF78, 0x7E33, - 0xBF79, 0x7E34, 0xBF7A, 0x7E35, 0xBF7B, 0x7E36, 0xBF7C, 0x7E37, 0xBF7D, 0x7E38, 0xBF7E, 0x7E39, 0xBF80, 0x7E3A, 0xBF81, 0x7E3C, - 0xBF82, 0x7E3D, 0xBF83, 0x7E3E, 0xBF84, 0x7E3F, 0xBF85, 0x7E40, 0xBF86, 0x7E42, 0xBF87, 0x7E43, 0xBF88, 0x7E44, 0xBF89, 0x7E45, - 0xBF8A, 0x7E46, 0xBF8B, 0x7E48, 0xBF8C, 0x7E49, 0xBF8D, 0x7E4A, 0xBF8E, 0x7E4B, 0xBF8F, 0x7E4C, 0xBF90, 0x7E4D, 0xBF91, 0x7E4E, - 0xBF92, 0x7E4F, 0xBF93, 0x7E50, 0xBF94, 0x7E51, 0xBF95, 0x7E52, 0xBF96, 0x7E53, 0xBF97, 0x7E54, 0xBF98, 0x7E55, 0xBF99, 0x7E56, - 0xBF9A, 0x7E57, 0xBF9B, 0x7E58, 0xBF9C, 0x7E59, 0xBF9D, 0x7E5A, 0xBF9E, 0x7E5B, 0xBF9F, 0x7E5C, 0xBFA0, 0x7E5D, 0xBFA1, 0x4FCA, - 0xBFA2, 0x7AE3, 0xBFA3, 0x6D5A, 0xBFA4, 0x90E1, 0xBFA5, 0x9A8F, 0xBFA6, 0x5580, 0xBFA7, 0x5496, 0xBFA8, 0x5361, 0xBFA9, 0x54AF, - 0xBFAA, 0x5F00, 0xBFAB, 0x63E9, 0xBFAC, 0x6977, 0xBFAD, 0x51EF, 0xBFAE, 0x6168, 0xBFAF, 0x520A, 0xBFB0, 0x582A, 0xBFB1, 0x52D8, - 0xBFB2, 0x574E, 0xBFB3, 0x780D, 0xBFB4, 0x770B, 0xBFB5, 0x5EB7, 0xBFB6, 0x6177, 0xBFB7, 0x7CE0, 0xBFB8, 0x625B, 0xBFB9, 0x6297, - 0xBFBA, 0x4EA2, 0xBFBB, 0x7095, 0xBFBC, 0x8003, 0xBFBD, 0x62F7, 0xBFBE, 0x70E4, 0xBFBF, 0x9760, 0xBFC0, 0x5777, 0xBFC1, 0x82DB, - 0xBFC2, 0x67EF, 0xBFC3, 0x68F5, 0xBFC4, 0x78D5, 0xBFC5, 0x9897, 0xBFC6, 0x79D1, 0xBFC7, 0x58F3, 0xBFC8, 0x54B3, 0xBFC9, 0x53EF, - 0xBFCA, 0x6E34, 0xBFCB, 0x514B, 0xBFCC, 0x523B, 0xBFCD, 0x5BA2, 0xBFCE, 0x8BFE, 0xBFCF, 0x80AF, 0xBFD0, 0x5543, 0xBFD1, 0x57A6, - 0xBFD2, 0x6073, 0xBFD3, 0x5751, 0xBFD4, 0x542D, 0xBFD5, 0x7A7A, 0xBFD6, 0x6050, 0xBFD7, 0x5B54, 0xBFD8, 0x63A7, 0xBFD9, 0x62A0, - 0xBFDA, 0x53E3, 0xBFDB, 0x6263, 0xBFDC, 0x5BC7, 0xBFDD, 0x67AF, 0xBFDE, 0x54ED, 0xBFDF, 0x7A9F, 0xBFE0, 0x82E6, 0xBFE1, 0x9177, - 0xBFE2, 0x5E93, 0xBFE3, 0x88E4, 0xBFE4, 0x5938, 0xBFE5, 0x57AE, 0xBFE6, 0x630E, 0xBFE7, 0x8DE8, 0xBFE8, 0x80EF, 0xBFE9, 0x5757, - 0xBFEA, 0x7B77, 0xBFEB, 0x4FA9, 0xBFEC, 0x5FEB, 0xBFED, 0x5BBD, 0xBFEE, 0x6B3E, 0xBFEF, 0x5321, 0xBFF0, 0x7B50, 0xBFF1, 0x72C2, - 0xBFF2, 0x6846, 0xBFF3, 0x77FF, 0xBFF4, 0x7736, 0xBFF5, 0x65F7, 0xBFF6, 0x51B5, 0xBFF7, 0x4E8F, 0xBFF8, 0x76D4, 0xBFF9, 0x5CBF, - 0xBFFA, 0x7AA5, 0xBFFB, 0x8475, 0xBFFC, 0x594E, 0xBFFD, 0x9B41, 0xBFFE, 0x5080, 0xC040, 0x7E5E, 0xC041, 0x7E5F, 0xC042, 0x7E60, - 0xC043, 0x7E61, 0xC044, 0x7E62, 0xC045, 0x7E63, 0xC046, 0x7E64, 0xC047, 0x7E65, 0xC048, 0x7E66, 0xC049, 0x7E67, 0xC04A, 0x7E68, - 0xC04B, 0x7E69, 0xC04C, 0x7E6A, 0xC04D, 0x7E6B, 0xC04E, 0x7E6C, 0xC04F, 0x7E6D, 0xC050, 0x7E6E, 0xC051, 0x7E6F, 0xC052, 0x7E70, - 0xC053, 0x7E71, 0xC054, 0x7E72, 0xC055, 0x7E73, 0xC056, 0x7E74, 0xC057, 0x7E75, 0xC058, 0x7E76, 0xC059, 0x7E77, 0xC05A, 0x7E78, - 0xC05B, 0x7E79, 0xC05C, 0x7E7A, 0xC05D, 0x7E7B, 0xC05E, 0x7E7C, 0xC05F, 0x7E7D, 0xC060, 0x7E7E, 0xC061, 0x7E7F, 0xC062, 0x7E80, - 0xC063, 0x7E81, 0xC064, 0x7E83, 0xC065, 0x7E84, 0xC066, 0x7E85, 0xC067, 0x7E86, 0xC068, 0x7E87, 0xC069, 0x7E88, 0xC06A, 0x7E89, - 0xC06B, 0x7E8A, 0xC06C, 0x7E8B, 0xC06D, 0x7E8C, 0xC06E, 0x7E8D, 0xC06F, 0x7E8E, 0xC070, 0x7E8F, 0xC071, 0x7E90, 0xC072, 0x7E91, - 0xC073, 0x7E92, 0xC074, 0x7E93, 0xC075, 0x7E94, 0xC076, 0x7E95, 0xC077, 0x7E96, 0xC078, 0x7E97, 0xC079, 0x7E98, 0xC07A, 0x7E99, - 0xC07B, 0x7E9A, 0xC07C, 0x7E9C, 0xC07D, 0x7E9D, 0xC07E, 0x7E9E, 0xC080, 0x7EAE, 0xC081, 0x7EB4, 0xC082, 0x7EBB, 0xC083, 0x7EBC, - 0xC084, 0x7ED6, 0xC085, 0x7EE4, 0xC086, 0x7EEC, 0xC087, 0x7EF9, 0xC088, 0x7F0A, 0xC089, 0x7F10, 0xC08A, 0x7F1E, 0xC08B, 0x7F37, - 0xC08C, 0x7F39, 0xC08D, 0x7F3B, 0xC08E, 0x7F3C, 0xC08F, 0x7F3D, 0xC090, 0x7F3E, 0xC091, 0x7F3F, 0xC092, 0x7F40, 0xC093, 0x7F41, - 0xC094, 0x7F43, 0xC095, 0x7F46, 0xC096, 0x7F47, 0xC097, 0x7F48, 0xC098, 0x7F49, 0xC099, 0x7F4A, 0xC09A, 0x7F4B, 0xC09B, 0x7F4C, - 0xC09C, 0x7F4D, 0xC09D, 0x7F4E, 0xC09E, 0x7F4F, 0xC09F, 0x7F52, 0xC0A0, 0x7F53, 0xC0A1, 0x9988, 0xC0A2, 0x6127, 0xC0A3, 0x6E83, - 0xC0A4, 0x5764, 0xC0A5, 0x6606, 0xC0A6, 0x6346, 0xC0A7, 0x56F0, 0xC0A8, 0x62EC, 0xC0A9, 0x6269, 0xC0AA, 0x5ED3, 0xC0AB, 0x9614, - 0xC0AC, 0x5783, 0xC0AD, 0x62C9, 0xC0AE, 0x5587, 0xC0AF, 0x8721, 0xC0B0, 0x814A, 0xC0B1, 0x8FA3, 0xC0B2, 0x5566, 0xC0B3, 0x83B1, - 0xC0B4, 0x6765, 0xC0B5, 0x8D56, 0xC0B6, 0x84DD, 0xC0B7, 0x5A6A, 0xC0B8, 0x680F, 0xC0B9, 0x62E6, 0xC0BA, 0x7BEE, 0xC0BB, 0x9611, - 0xC0BC, 0x5170, 0xC0BD, 0x6F9C, 0xC0BE, 0x8C30, 0xC0BF, 0x63FD, 0xC0C0, 0x89C8, 0xC0C1, 0x61D2, 0xC0C2, 0x7F06, 0xC0C3, 0x70C2, - 0xC0C4, 0x6EE5, 0xC0C5, 0x7405, 0xC0C6, 0x6994, 0xC0C7, 0x72FC, 0xC0C8, 0x5ECA, 0xC0C9, 0x90CE, 0xC0CA, 0x6717, 0xC0CB, 0x6D6A, - 0xC0CC, 0x635E, 0xC0CD, 0x52B3, 0xC0CE, 0x7262, 0xC0CF, 0x8001, 0xC0D0, 0x4F6C, 0xC0D1, 0x59E5, 0xC0D2, 0x916A, 0xC0D3, 0x70D9, - 0xC0D4, 0x6D9D, 0xC0D5, 0x52D2, 0xC0D6, 0x4E50, 0xC0D7, 0x96F7, 0xC0D8, 0x956D, 0xC0D9, 0x857E, 0xC0DA, 0x78CA, 0xC0DB, 0x7D2F, - 0xC0DC, 0x5121, 0xC0DD, 0x5792, 0xC0DE, 0x64C2, 0xC0DF, 0x808B, 0xC0E0, 0x7C7B, 0xC0E1, 0x6CEA, 0xC0E2, 0x68F1, 0xC0E3, 0x695E, - 0xC0E4, 0x51B7, 0xC0E5, 0x5398, 0xC0E6, 0x68A8, 0xC0E7, 0x7281, 0xC0E8, 0x9ECE, 0xC0E9, 0x7BF1, 0xC0EA, 0x72F8, 0xC0EB, 0x79BB, - 0xC0EC, 0x6F13, 0xC0ED, 0x7406, 0xC0EE, 0x674E, 0xC0EF, 0x91CC, 0xC0F0, 0x9CA4, 0xC0F1, 0x793C, 0xC0F2, 0x8389, 0xC0F3, 0x8354, - 0xC0F4, 0x540F, 0xC0F5, 0x6817, 0xC0F6, 0x4E3D, 0xC0F7, 0x5389, 0xC0F8, 0x52B1, 0xC0F9, 0x783E, 0xC0FA, 0x5386, 0xC0FB, 0x5229, - 0xC0FC, 0x5088, 0xC0FD, 0x4F8B, 0xC0FE, 0x4FD0, 0xC140, 0x7F56, 0xC141, 0x7F59, 0xC142, 0x7F5B, 0xC143, 0x7F5C, 0xC144, 0x7F5D, - 0xC145, 0x7F5E, 0xC146, 0x7F60, 0xC147, 0x7F63, 0xC148, 0x7F64, 0xC149, 0x7F65, 0xC14A, 0x7F66, 0xC14B, 0x7F67, 0xC14C, 0x7F6B, - 0xC14D, 0x7F6C, 0xC14E, 0x7F6D, 0xC14F, 0x7F6F, 0xC150, 0x7F70, 0xC151, 0x7F73, 0xC152, 0x7F75, 0xC153, 0x7F76, 0xC154, 0x7F77, - 0xC155, 0x7F78, 0xC156, 0x7F7A, 0xC157, 0x7F7B, 0xC158, 0x7F7C, 0xC159, 0x7F7D, 0xC15A, 0x7F7F, 0xC15B, 0x7F80, 0xC15C, 0x7F82, - 0xC15D, 0x7F83, 0xC15E, 0x7F84, 0xC15F, 0x7F85, 0xC160, 0x7F86, 0xC161, 0x7F87, 0xC162, 0x7F88, 0xC163, 0x7F89, 0xC164, 0x7F8B, - 0xC165, 0x7F8D, 0xC166, 0x7F8F, 0xC167, 0x7F90, 0xC168, 0x7F91, 0xC169, 0x7F92, 0xC16A, 0x7F93, 0xC16B, 0x7F95, 0xC16C, 0x7F96, - 0xC16D, 0x7F97, 0xC16E, 0x7F98, 0xC16F, 0x7F99, 0xC170, 0x7F9B, 0xC171, 0x7F9C, 0xC172, 0x7FA0, 0xC173, 0x7FA2, 0xC174, 0x7FA3, - 0xC175, 0x7FA5, 0xC176, 0x7FA6, 0xC177, 0x7FA8, 0xC178, 0x7FA9, 0xC179, 0x7FAA, 0xC17A, 0x7FAB, 0xC17B, 0x7FAC, 0xC17C, 0x7FAD, - 0xC17D, 0x7FAE, 0xC17E, 0x7FB1, 0xC180, 0x7FB3, 0xC181, 0x7FB4, 0xC182, 0x7FB5, 0xC183, 0x7FB6, 0xC184, 0x7FB7, 0xC185, 0x7FBA, - 0xC186, 0x7FBB, 0xC187, 0x7FBE, 0xC188, 0x7FC0, 0xC189, 0x7FC2, 0xC18A, 0x7FC3, 0xC18B, 0x7FC4, 0xC18C, 0x7FC6, 0xC18D, 0x7FC7, - 0xC18E, 0x7FC8, 0xC18F, 0x7FC9, 0xC190, 0x7FCB, 0xC191, 0x7FCD, 0xC192, 0x7FCF, 0xC193, 0x7FD0, 0xC194, 0x7FD1, 0xC195, 0x7FD2, - 0xC196, 0x7FD3, 0xC197, 0x7FD6, 0xC198, 0x7FD7, 0xC199, 0x7FD9, 0xC19A, 0x7FDA, 0xC19B, 0x7FDB, 0xC19C, 0x7FDC, 0xC19D, 0x7FDD, - 0xC19E, 0x7FDE, 0xC19F, 0x7FE2, 0xC1A0, 0x7FE3, 0xC1A1, 0x75E2, 0xC1A2, 0x7ACB, 0xC1A3, 0x7C92, 0xC1A4, 0x6CA5, 0xC1A5, 0x96B6, - 0xC1A6, 0x529B, 0xC1A7, 0x7483, 0xC1A8, 0x54E9, 0xC1A9, 0x4FE9, 0xC1AA, 0x8054, 0xC1AB, 0x83B2, 0xC1AC, 0x8FDE, 0xC1AD, 0x9570, - 0xC1AE, 0x5EC9, 0xC1AF, 0x601C, 0xC1B0, 0x6D9F, 0xC1B1, 0x5E18, 0xC1B2, 0x655B, 0xC1B3, 0x8138, 0xC1B4, 0x94FE, 0xC1B5, 0x604B, - 0xC1B6, 0x70BC, 0xC1B7, 0x7EC3, 0xC1B8, 0x7CAE, 0xC1B9, 0x51C9, 0xC1BA, 0x6881, 0xC1BB, 0x7CB1, 0xC1BC, 0x826F, 0xC1BD, 0x4E24, - 0xC1BE, 0x8F86, 0xC1BF, 0x91CF, 0xC1C0, 0x667E, 0xC1C1, 0x4EAE, 0xC1C2, 0x8C05, 0xC1C3, 0x64A9, 0xC1C4, 0x804A, 0xC1C5, 0x50DA, - 0xC1C6, 0x7597, 0xC1C7, 0x71CE, 0xC1C8, 0x5BE5, 0xC1C9, 0x8FBD, 0xC1CA, 0x6F66, 0xC1CB, 0x4E86, 0xC1CC, 0x6482, 0xC1CD, 0x9563, - 0xC1CE, 0x5ED6, 0xC1CF, 0x6599, 0xC1D0, 0x5217, 0xC1D1, 0x88C2, 0xC1D2, 0x70C8, 0xC1D3, 0x52A3, 0xC1D4, 0x730E, 0xC1D5, 0x7433, - 0xC1D6, 0x6797, 0xC1D7, 0x78F7, 0xC1D8, 0x9716, 0xC1D9, 0x4E34, 0xC1DA, 0x90BB, 0xC1DB, 0x9CDE, 0xC1DC, 0x6DCB, 0xC1DD, 0x51DB, - 0xC1DE, 0x8D41, 0xC1DF, 0x541D, 0xC1E0, 0x62CE, 0xC1E1, 0x73B2, 0xC1E2, 0x83F1, 0xC1E3, 0x96F6, 0xC1E4, 0x9F84, 0xC1E5, 0x94C3, - 0xC1E6, 0x4F36, 0xC1E7, 0x7F9A, 0xC1E8, 0x51CC, 0xC1E9, 0x7075, 0xC1EA, 0x9675, 0xC1EB, 0x5CAD, 0xC1EC, 0x9886, 0xC1ED, 0x53E6, - 0xC1EE, 0x4EE4, 0xC1EF, 0x6E9C, 0xC1F0, 0x7409, 0xC1F1, 0x69B4, 0xC1F2, 0x786B, 0xC1F3, 0x998F, 0xC1F4, 0x7559, 0xC1F5, 0x5218, - 0xC1F6, 0x7624, 0xC1F7, 0x6D41, 0xC1F8, 0x67F3, 0xC1F9, 0x516D, 0xC1FA, 0x9F99, 0xC1FB, 0x804B, 0xC1FC, 0x5499, 0xC1FD, 0x7B3C, - 0xC1FE, 0x7ABF, 0xC240, 0x7FE4, 0xC241, 0x7FE7, 0xC242, 0x7FE8, 0xC243, 0x7FEA, 0xC244, 0x7FEB, 0xC245, 0x7FEC, 0xC246, 0x7FED, - 0xC247, 0x7FEF, 0xC248, 0x7FF2, 0xC249, 0x7FF4, 0xC24A, 0x7FF5, 0xC24B, 0x7FF6, 0xC24C, 0x7FF7, 0xC24D, 0x7FF8, 0xC24E, 0x7FF9, - 0xC24F, 0x7FFA, 0xC250, 0x7FFD, 0xC251, 0x7FFE, 0xC252, 0x7FFF, 0xC253, 0x8002, 0xC254, 0x8007, 0xC255, 0x8008, 0xC256, 0x8009, - 0xC257, 0x800A, 0xC258, 0x800E, 0xC259, 0x800F, 0xC25A, 0x8011, 0xC25B, 0x8013, 0xC25C, 0x801A, 0xC25D, 0x801B, 0xC25E, 0x801D, - 0xC25F, 0x801E, 0xC260, 0x801F, 0xC261, 0x8021, 0xC262, 0x8023, 0xC263, 0x8024, 0xC264, 0x802B, 0xC265, 0x802C, 0xC266, 0x802D, - 0xC267, 0x802E, 0xC268, 0x802F, 0xC269, 0x8030, 0xC26A, 0x8032, 0xC26B, 0x8034, 0xC26C, 0x8039, 0xC26D, 0x803A, 0xC26E, 0x803C, - 0xC26F, 0x803E, 0xC270, 0x8040, 0xC271, 0x8041, 0xC272, 0x8044, 0xC273, 0x8045, 0xC274, 0x8047, 0xC275, 0x8048, 0xC276, 0x8049, - 0xC277, 0x804E, 0xC278, 0x804F, 0xC279, 0x8050, 0xC27A, 0x8051, 0xC27B, 0x8053, 0xC27C, 0x8055, 0xC27D, 0x8056, 0xC27E, 0x8057, - 0xC280, 0x8059, 0xC281, 0x805B, 0xC282, 0x805C, 0xC283, 0x805D, 0xC284, 0x805E, 0xC285, 0x805F, 0xC286, 0x8060, 0xC287, 0x8061, - 0xC288, 0x8062, 0xC289, 0x8063, 0xC28A, 0x8064, 0xC28B, 0x8065, 0xC28C, 0x8066, 0xC28D, 0x8067, 0xC28E, 0x8068, 0xC28F, 0x806B, - 0xC290, 0x806C, 0xC291, 0x806D, 0xC292, 0x806E, 0xC293, 0x806F, 0xC294, 0x8070, 0xC295, 0x8072, 0xC296, 0x8073, 0xC297, 0x8074, - 0xC298, 0x8075, 0xC299, 0x8076, 0xC29A, 0x8077, 0xC29B, 0x8078, 0xC29C, 0x8079, 0xC29D, 0x807A, 0xC29E, 0x807B, 0xC29F, 0x807C, - 0xC2A0, 0x807D, 0xC2A1, 0x9686, 0xC2A2, 0x5784, 0xC2A3, 0x62E2, 0xC2A4, 0x9647, 0xC2A5, 0x697C, 0xC2A6, 0x5A04, 0xC2A7, 0x6402, - 0xC2A8, 0x7BD3, 0xC2A9, 0x6F0F, 0xC2AA, 0x964B, 0xC2AB, 0x82A6, 0xC2AC, 0x5362, 0xC2AD, 0x9885, 0xC2AE, 0x5E90, 0xC2AF, 0x7089, - 0xC2B0, 0x63B3, 0xC2B1, 0x5364, 0xC2B2, 0x864F, 0xC2B3, 0x9C81, 0xC2B4, 0x9E93, 0xC2B5, 0x788C, 0xC2B6, 0x9732, 0xC2B7, 0x8DEF, - 0xC2B8, 0x8D42, 0xC2B9, 0x9E7F, 0xC2BA, 0x6F5E, 0xC2BB, 0x7984, 0xC2BC, 0x5F55, 0xC2BD, 0x9646, 0xC2BE, 0x622E, 0xC2BF, 0x9A74, - 0xC2C0, 0x5415, 0xC2C1, 0x94DD, 0xC2C2, 0x4FA3, 0xC2C3, 0x65C5, 0xC2C4, 0x5C65, 0xC2C5, 0x5C61, 0xC2C6, 0x7F15, 0xC2C7, 0x8651, - 0xC2C8, 0x6C2F, 0xC2C9, 0x5F8B, 0xC2CA, 0x7387, 0xC2CB, 0x6EE4, 0xC2CC, 0x7EFF, 0xC2CD, 0x5CE6, 0xC2CE, 0x631B, 0xC2CF, 0x5B6A, - 0xC2D0, 0x6EE6, 0xC2D1, 0x5375, 0xC2D2, 0x4E71, 0xC2D3, 0x63A0, 0xC2D4, 0x7565, 0xC2D5, 0x62A1, 0xC2D6, 0x8F6E, 0xC2D7, 0x4F26, - 0xC2D8, 0x4ED1, 0xC2D9, 0x6CA6, 0xC2DA, 0x7EB6, 0xC2DB, 0x8BBA, 0xC2DC, 0x841D, 0xC2DD, 0x87BA, 0xC2DE, 0x7F57, 0xC2DF, 0x903B, - 0xC2E0, 0x9523, 0xC2E1, 0x7BA9, 0xC2E2, 0x9AA1, 0xC2E3, 0x88F8, 0xC2E4, 0x843D, 0xC2E5, 0x6D1B, 0xC2E6, 0x9A86, 0xC2E7, 0x7EDC, - 0xC2E8, 0x5988, 0xC2E9, 0x9EBB, 0xC2EA, 0x739B, 0xC2EB, 0x7801, 0xC2EC, 0x8682, 0xC2ED, 0x9A6C, 0xC2EE, 0x9A82, 0xC2EF, 0x561B, - 0xC2F0, 0x5417, 0xC2F1, 0x57CB, 0xC2F2, 0x4E70, 0xC2F3, 0x9EA6, 0xC2F4, 0x5356, 0xC2F5, 0x8FC8, 0xC2F6, 0x8109, 0xC2F7, 0x7792, - 0xC2F8, 0x9992, 0xC2F9, 0x86EE, 0xC2FA, 0x6EE1, 0xC2FB, 0x8513, 0xC2FC, 0x66FC, 0xC2FD, 0x6162, 0xC2FE, 0x6F2B, 0xC340, 0x807E, - 0xC341, 0x8081, 0xC342, 0x8082, 0xC343, 0x8085, 0xC344, 0x8088, 0xC345, 0x808A, 0xC346, 0x808D, 0xC347, 0x808E, 0xC348, 0x808F, - 0xC349, 0x8090, 0xC34A, 0x8091, 0xC34B, 0x8092, 0xC34C, 0x8094, 0xC34D, 0x8095, 0xC34E, 0x8097, 0xC34F, 0x8099, 0xC350, 0x809E, - 0xC351, 0x80A3, 0xC352, 0x80A6, 0xC353, 0x80A7, 0xC354, 0x80A8, 0xC355, 0x80AC, 0xC356, 0x80B0, 0xC357, 0x80B3, 0xC358, 0x80B5, - 0xC359, 0x80B6, 0xC35A, 0x80B8, 0xC35B, 0x80B9, 0xC35C, 0x80BB, 0xC35D, 0x80C5, 0xC35E, 0x80C7, 0xC35F, 0x80C8, 0xC360, 0x80C9, - 0xC361, 0x80CA, 0xC362, 0x80CB, 0xC363, 0x80CF, 0xC364, 0x80D0, 0xC365, 0x80D1, 0xC366, 0x80D2, 0xC367, 0x80D3, 0xC368, 0x80D4, - 0xC369, 0x80D5, 0xC36A, 0x80D8, 0xC36B, 0x80DF, 0xC36C, 0x80E0, 0xC36D, 0x80E2, 0xC36E, 0x80E3, 0xC36F, 0x80E6, 0xC370, 0x80EE, - 0xC371, 0x80F5, 0xC372, 0x80F7, 0xC373, 0x80F9, 0xC374, 0x80FB, 0xC375, 0x80FE, 0xC376, 0x80FF, 0xC377, 0x8100, 0xC378, 0x8101, - 0xC379, 0x8103, 0xC37A, 0x8104, 0xC37B, 0x8105, 0xC37C, 0x8107, 0xC37D, 0x8108, 0xC37E, 0x810B, 0xC380, 0x810C, 0xC381, 0x8115, - 0xC382, 0x8117, 0xC383, 0x8119, 0xC384, 0x811B, 0xC385, 0x811C, 0xC386, 0x811D, 0xC387, 0x811F, 0xC388, 0x8120, 0xC389, 0x8121, - 0xC38A, 0x8122, 0xC38B, 0x8123, 0xC38C, 0x8124, 0xC38D, 0x8125, 0xC38E, 0x8126, 0xC38F, 0x8127, 0xC390, 0x8128, 0xC391, 0x8129, - 0xC392, 0x812A, 0xC393, 0x812B, 0xC394, 0x812D, 0xC395, 0x812E, 0xC396, 0x8130, 0xC397, 0x8133, 0xC398, 0x8134, 0xC399, 0x8135, - 0xC39A, 0x8137, 0xC39B, 0x8139, 0xC39C, 0x813A, 0xC39D, 0x813B, 0xC39E, 0x813C, 0xC39F, 0x813D, 0xC3A0, 0x813F, 0xC3A1, 0x8C29, - 0xC3A2, 0x8292, 0xC3A3, 0x832B, 0xC3A4, 0x76F2, 0xC3A5, 0x6C13, 0xC3A6, 0x5FD9, 0xC3A7, 0x83BD, 0xC3A8, 0x732B, 0xC3A9, 0x8305, - 0xC3AA, 0x951A, 0xC3AB, 0x6BDB, 0xC3AC, 0x77DB, 0xC3AD, 0x94C6, 0xC3AE, 0x536F, 0xC3AF, 0x8302, 0xC3B0, 0x5192, 0xC3B1, 0x5E3D, - 0xC3B2, 0x8C8C, 0xC3B3, 0x8D38, 0xC3B4, 0x4E48, 0xC3B5, 0x73AB, 0xC3B6, 0x679A, 0xC3B7, 0x6885, 0xC3B8, 0x9176, 0xC3B9, 0x9709, - 0xC3BA, 0x7164, 0xC3BB, 0x6CA1, 0xC3BC, 0x7709, 0xC3BD, 0x5A92, 0xC3BE, 0x9541, 0xC3BF, 0x6BCF, 0xC3C0, 0x7F8E, 0xC3C1, 0x6627, - 0xC3C2, 0x5BD0, 0xC3C3, 0x59B9, 0xC3C4, 0x5A9A, 0xC3C5, 0x95E8, 0xC3C6, 0x95F7, 0xC3C7, 0x4EEC, 0xC3C8, 0x840C, 0xC3C9, 0x8499, - 0xC3CA, 0x6AAC, 0xC3CB, 0x76DF, 0xC3CC, 0x9530, 0xC3CD, 0x731B, 0xC3CE, 0x68A6, 0xC3CF, 0x5B5F, 0xC3D0, 0x772F, 0xC3D1, 0x919A, - 0xC3D2, 0x9761, 0xC3D3, 0x7CDC, 0xC3D4, 0x8FF7, 0xC3D5, 0x8C1C, 0xC3D6, 0x5F25, 0xC3D7, 0x7C73, 0xC3D8, 0x79D8, 0xC3D9, 0x89C5, - 0xC3DA, 0x6CCC, 0xC3DB, 0x871C, 0xC3DC, 0x5BC6, 0xC3DD, 0x5E42, 0xC3DE, 0x68C9, 0xC3DF, 0x7720, 0xC3E0, 0x7EF5, 0xC3E1, 0x5195, - 0xC3E2, 0x514D, 0xC3E3, 0x52C9, 0xC3E4, 0x5A29, 0xC3E5, 0x7F05, 0xC3E6, 0x9762, 0xC3E7, 0x82D7, 0xC3E8, 0x63CF, 0xC3E9, 0x7784, - 0xC3EA, 0x85D0, 0xC3EB, 0x79D2, 0xC3EC, 0x6E3A, 0xC3ED, 0x5E99, 0xC3EE, 0x5999, 0xC3EF, 0x8511, 0xC3F0, 0x706D, 0xC3F1, 0x6C11, - 0xC3F2, 0x62BF, 0xC3F3, 0x76BF, 0xC3F4, 0x654F, 0xC3F5, 0x60AF, 0xC3F6, 0x95FD, 0xC3F7, 0x660E, 0xC3F8, 0x879F, 0xC3F9, 0x9E23, - 0xC3FA, 0x94ED, 0xC3FB, 0x540D, 0xC3FC, 0x547D, 0xC3FD, 0x8C2C, 0xC3FE, 0x6478, 0xC440, 0x8140, 0xC441, 0x8141, 0xC442, 0x8142, - 0xC443, 0x8143, 0xC444, 0x8144, 0xC445, 0x8145, 0xC446, 0x8147, 0xC447, 0x8149, 0xC448, 0x814D, 0xC449, 0x814E, 0xC44A, 0x814F, - 0xC44B, 0x8152, 0xC44C, 0x8156, 0xC44D, 0x8157, 0xC44E, 0x8158, 0xC44F, 0x815B, 0xC450, 0x815C, 0xC451, 0x815D, 0xC452, 0x815E, - 0xC453, 0x815F, 0xC454, 0x8161, 0xC455, 0x8162, 0xC456, 0x8163, 0xC457, 0x8164, 0xC458, 0x8166, 0xC459, 0x8168, 0xC45A, 0x816A, - 0xC45B, 0x816B, 0xC45C, 0x816C, 0xC45D, 0x816F, 0xC45E, 0x8172, 0xC45F, 0x8173, 0xC460, 0x8175, 0xC461, 0x8176, 0xC462, 0x8177, - 0xC463, 0x8178, 0xC464, 0x8181, 0xC465, 0x8183, 0xC466, 0x8184, 0xC467, 0x8185, 0xC468, 0x8186, 0xC469, 0x8187, 0xC46A, 0x8189, - 0xC46B, 0x818B, 0xC46C, 0x818C, 0xC46D, 0x818D, 0xC46E, 0x818E, 0xC46F, 0x8190, 0xC470, 0x8192, 0xC471, 0x8193, 0xC472, 0x8194, - 0xC473, 0x8195, 0xC474, 0x8196, 0xC475, 0x8197, 0xC476, 0x8199, 0xC477, 0x819A, 0xC478, 0x819E, 0xC479, 0x819F, 0xC47A, 0x81A0, - 0xC47B, 0x81A1, 0xC47C, 0x81A2, 0xC47D, 0x81A4, 0xC47E, 0x81A5, 0xC480, 0x81A7, 0xC481, 0x81A9, 0xC482, 0x81AB, 0xC483, 0x81AC, - 0xC484, 0x81AD, 0xC485, 0x81AE, 0xC486, 0x81AF, 0xC487, 0x81B0, 0xC488, 0x81B1, 0xC489, 0x81B2, 0xC48A, 0x81B4, 0xC48B, 0x81B5, - 0xC48C, 0x81B6, 0xC48D, 0x81B7, 0xC48E, 0x81B8, 0xC48F, 0x81B9, 0xC490, 0x81BC, 0xC491, 0x81BD, 0xC492, 0x81BE, 0xC493, 0x81BF, - 0xC494, 0x81C4, 0xC495, 0x81C5, 0xC496, 0x81C7, 0xC497, 0x81C8, 0xC498, 0x81C9, 0xC499, 0x81CB, 0xC49A, 0x81CD, 0xC49B, 0x81CE, - 0xC49C, 0x81CF, 0xC49D, 0x81D0, 0xC49E, 0x81D1, 0xC49F, 0x81D2, 0xC4A0, 0x81D3, 0xC4A1, 0x6479, 0xC4A2, 0x8611, 0xC4A3, 0x6A21, - 0xC4A4, 0x819C, 0xC4A5, 0x78E8, 0xC4A6, 0x6469, 0xC4A7, 0x9B54, 0xC4A8, 0x62B9, 0xC4A9, 0x672B, 0xC4AA, 0x83AB, 0xC4AB, 0x58A8, - 0xC4AC, 0x9ED8, 0xC4AD, 0x6CAB, 0xC4AE, 0x6F20, 0xC4AF, 0x5BDE, 0xC4B0, 0x964C, 0xC4B1, 0x8C0B, 0xC4B2, 0x725F, 0xC4B3, 0x67D0, - 0xC4B4, 0x62C7, 0xC4B5, 0x7261, 0xC4B6, 0x4EA9, 0xC4B7, 0x59C6, 0xC4B8, 0x6BCD, 0xC4B9, 0x5893, 0xC4BA, 0x66AE, 0xC4BB, 0x5E55, - 0xC4BC, 0x52DF, 0xC4BD, 0x6155, 0xC4BE, 0x6728, 0xC4BF, 0x76EE, 0xC4C0, 0x7766, 0xC4C1, 0x7267, 0xC4C2, 0x7A46, 0xC4C3, 0x62FF, - 0xC4C4, 0x54EA, 0xC4C5, 0x5450, 0xC4C6, 0x94A0, 0xC4C7, 0x90A3, 0xC4C8, 0x5A1C, 0xC4C9, 0x7EB3, 0xC4CA, 0x6C16, 0xC4CB, 0x4E43, - 0xC4CC, 0x5976, 0xC4CD, 0x8010, 0xC4CE, 0x5948, 0xC4CF, 0x5357, 0xC4D0, 0x7537, 0xC4D1, 0x96BE, 0xC4D2, 0x56CA, 0xC4D3, 0x6320, - 0xC4D4, 0x8111, 0xC4D5, 0x607C, 0xC4D6, 0x95F9, 0xC4D7, 0x6DD6, 0xC4D8, 0x5462, 0xC4D9, 0x9981, 0xC4DA, 0x5185, 0xC4DB, 0x5AE9, - 0xC4DC, 0x80FD, 0xC4DD, 0x59AE, 0xC4DE, 0x9713, 0xC4DF, 0x502A, 0xC4E0, 0x6CE5, 0xC4E1, 0x5C3C, 0xC4E2, 0x62DF, 0xC4E3, 0x4F60, - 0xC4E4, 0x533F, 0xC4E5, 0x817B, 0xC4E6, 0x9006, 0xC4E7, 0x6EBA, 0xC4E8, 0x852B, 0xC4E9, 0x62C8, 0xC4EA, 0x5E74, 0xC4EB, 0x78BE, - 0xC4EC, 0x64B5, 0xC4ED, 0x637B, 0xC4EE, 0x5FF5, 0xC4EF, 0x5A18, 0xC4F0, 0x917F, 0xC4F1, 0x9E1F, 0xC4F2, 0x5C3F, 0xC4F3, 0x634F, - 0xC4F4, 0x8042, 0xC4F5, 0x5B7D, 0xC4F6, 0x556E, 0xC4F7, 0x954A, 0xC4F8, 0x954D, 0xC4F9, 0x6D85, 0xC4FA, 0x60A8, 0xC4FB, 0x67E0, - 0xC4FC, 0x72DE, 0xC4FD, 0x51DD, 0xC4FE, 0x5B81, 0xC540, 0x81D4, 0xC541, 0x81D5, 0xC542, 0x81D6, 0xC543, 0x81D7, 0xC544, 0x81D8, - 0xC545, 0x81D9, 0xC546, 0x81DA, 0xC547, 0x81DB, 0xC548, 0x81DC, 0xC549, 0x81DD, 0xC54A, 0x81DE, 0xC54B, 0x81DF, 0xC54C, 0x81E0, - 0xC54D, 0x81E1, 0xC54E, 0x81E2, 0xC54F, 0x81E4, 0xC550, 0x81E5, 0xC551, 0x81E6, 0xC552, 0x81E8, 0xC553, 0x81E9, 0xC554, 0x81EB, - 0xC555, 0x81EE, 0xC556, 0x81EF, 0xC557, 0x81F0, 0xC558, 0x81F1, 0xC559, 0x81F2, 0xC55A, 0x81F5, 0xC55B, 0x81F6, 0xC55C, 0x81F7, - 0xC55D, 0x81F8, 0xC55E, 0x81F9, 0xC55F, 0x81FA, 0xC560, 0x81FD, 0xC561, 0x81FF, 0xC562, 0x8203, 0xC563, 0x8207, 0xC564, 0x8208, - 0xC565, 0x8209, 0xC566, 0x820A, 0xC567, 0x820B, 0xC568, 0x820E, 0xC569, 0x820F, 0xC56A, 0x8211, 0xC56B, 0x8213, 0xC56C, 0x8215, - 0xC56D, 0x8216, 0xC56E, 0x8217, 0xC56F, 0x8218, 0xC570, 0x8219, 0xC571, 0x821A, 0xC572, 0x821D, 0xC573, 0x8220, 0xC574, 0x8224, - 0xC575, 0x8225, 0xC576, 0x8226, 0xC577, 0x8227, 0xC578, 0x8229, 0xC579, 0x822E, 0xC57A, 0x8232, 0xC57B, 0x823A, 0xC57C, 0x823C, - 0xC57D, 0x823D, 0xC57E, 0x823F, 0xC580, 0x8240, 0xC581, 0x8241, 0xC582, 0x8242, 0xC583, 0x8243, 0xC584, 0x8245, 0xC585, 0x8246, - 0xC586, 0x8248, 0xC587, 0x824A, 0xC588, 0x824C, 0xC589, 0x824D, 0xC58A, 0x824E, 0xC58B, 0x8250, 0xC58C, 0x8251, 0xC58D, 0x8252, - 0xC58E, 0x8253, 0xC58F, 0x8254, 0xC590, 0x8255, 0xC591, 0x8256, 0xC592, 0x8257, 0xC593, 0x8259, 0xC594, 0x825B, 0xC595, 0x825C, - 0xC596, 0x825D, 0xC597, 0x825E, 0xC598, 0x8260, 0xC599, 0x8261, 0xC59A, 0x8262, 0xC59B, 0x8263, 0xC59C, 0x8264, 0xC59D, 0x8265, - 0xC59E, 0x8266, 0xC59F, 0x8267, 0xC5A0, 0x8269, 0xC5A1, 0x62E7, 0xC5A2, 0x6CDE, 0xC5A3, 0x725B, 0xC5A4, 0x626D, 0xC5A5, 0x94AE, - 0xC5A6, 0x7EBD, 0xC5A7, 0x8113, 0xC5A8, 0x6D53, 0xC5A9, 0x519C, 0xC5AA, 0x5F04, 0xC5AB, 0x5974, 0xC5AC, 0x52AA, 0xC5AD, 0x6012, - 0xC5AE, 0x5973, 0xC5AF, 0x6696, 0xC5B0, 0x8650, 0xC5B1, 0x759F, 0xC5B2, 0x632A, 0xC5B3, 0x61E6, 0xC5B4, 0x7CEF, 0xC5B5, 0x8BFA, - 0xC5B6, 0x54E6, 0xC5B7, 0x6B27, 0xC5B8, 0x9E25, 0xC5B9, 0x6BB4, 0xC5BA, 0x85D5, 0xC5BB, 0x5455, 0xC5BC, 0x5076, 0xC5BD, 0x6CA4, - 0xC5BE, 0x556A, 0xC5BF, 0x8DB4, 0xC5C0, 0x722C, 0xC5C1, 0x5E15, 0xC5C2, 0x6015, 0xC5C3, 0x7436, 0xC5C4, 0x62CD, 0xC5C5, 0x6392, - 0xC5C6, 0x724C, 0xC5C7, 0x5F98, 0xC5C8, 0x6E43, 0xC5C9, 0x6D3E, 0xC5CA, 0x6500, 0xC5CB, 0x6F58, 0xC5CC, 0x76D8, 0xC5CD, 0x78D0, - 0xC5CE, 0x76FC, 0xC5CF, 0x7554, 0xC5D0, 0x5224, 0xC5D1, 0x53DB, 0xC5D2, 0x4E53, 0xC5D3, 0x5E9E, 0xC5D4, 0x65C1, 0xC5D5, 0x802A, - 0xC5D6, 0x80D6, 0xC5D7, 0x629B, 0xC5D8, 0x5486, 0xC5D9, 0x5228, 0xC5DA, 0x70AE, 0xC5DB, 0x888D, 0xC5DC, 0x8DD1, 0xC5DD, 0x6CE1, - 0xC5DE, 0x5478, 0xC5DF, 0x80DA, 0xC5E0, 0x57F9, 0xC5E1, 0x88F4, 0xC5E2, 0x8D54, 0xC5E3, 0x966A, 0xC5E4, 0x914D, 0xC5E5, 0x4F69, - 0xC5E6, 0x6C9B, 0xC5E7, 0x55B7, 0xC5E8, 0x76C6, 0xC5E9, 0x7830, 0xC5EA, 0x62A8, 0xC5EB, 0x70F9, 0xC5EC, 0x6F8E, 0xC5ED, 0x5F6D, - 0xC5EE, 0x84EC, 0xC5EF, 0x68DA, 0xC5F0, 0x787C, 0xC5F1, 0x7BF7, 0xC5F2, 0x81A8, 0xC5F3, 0x670B, 0xC5F4, 0x9E4F, 0xC5F5, 0x6367, - 0xC5F6, 0x78B0, 0xC5F7, 0x576F, 0xC5F8, 0x7812, 0xC5F9, 0x9739, 0xC5FA, 0x6279, 0xC5FB, 0x62AB, 0xC5FC, 0x5288, 0xC5FD, 0x7435, - 0xC5FE, 0x6BD7, 0xC640, 0x826A, 0xC641, 0x826B, 0xC642, 0x826C, 0xC643, 0x826D, 0xC644, 0x8271, 0xC645, 0x8275, 0xC646, 0x8276, - 0xC647, 0x8277, 0xC648, 0x8278, 0xC649, 0x827B, 0xC64A, 0x827C, 0xC64B, 0x8280, 0xC64C, 0x8281, 0xC64D, 0x8283, 0xC64E, 0x8285, - 0xC64F, 0x8286, 0xC650, 0x8287, 0xC651, 0x8289, 0xC652, 0x828C, 0xC653, 0x8290, 0xC654, 0x8293, 0xC655, 0x8294, 0xC656, 0x8295, - 0xC657, 0x8296, 0xC658, 0x829A, 0xC659, 0x829B, 0xC65A, 0x829E, 0xC65B, 0x82A0, 0xC65C, 0x82A2, 0xC65D, 0x82A3, 0xC65E, 0x82A7, - 0xC65F, 0x82B2, 0xC660, 0x82B5, 0xC661, 0x82B6, 0xC662, 0x82BA, 0xC663, 0x82BB, 0xC664, 0x82BC, 0xC665, 0x82BF, 0xC666, 0x82C0, - 0xC667, 0x82C2, 0xC668, 0x82C3, 0xC669, 0x82C5, 0xC66A, 0x82C6, 0xC66B, 0x82C9, 0xC66C, 0x82D0, 0xC66D, 0x82D6, 0xC66E, 0x82D9, - 0xC66F, 0x82DA, 0xC670, 0x82DD, 0xC671, 0x82E2, 0xC672, 0x82E7, 0xC673, 0x82E8, 0xC674, 0x82E9, 0xC675, 0x82EA, 0xC676, 0x82EC, - 0xC677, 0x82ED, 0xC678, 0x82EE, 0xC679, 0x82F0, 0xC67A, 0x82F2, 0xC67B, 0x82F3, 0xC67C, 0x82F5, 0xC67D, 0x82F6, 0xC67E, 0x82F8, - 0xC680, 0x82FA, 0xC681, 0x82FC, 0xC682, 0x82FD, 0xC683, 0x82FE, 0xC684, 0x82FF, 0xC685, 0x8300, 0xC686, 0x830A, 0xC687, 0x830B, - 0xC688, 0x830D, 0xC689, 0x8310, 0xC68A, 0x8312, 0xC68B, 0x8313, 0xC68C, 0x8316, 0xC68D, 0x8318, 0xC68E, 0x8319, 0xC68F, 0x831D, - 0xC690, 0x831E, 0xC691, 0x831F, 0xC692, 0x8320, 0xC693, 0x8321, 0xC694, 0x8322, 0xC695, 0x8323, 0xC696, 0x8324, 0xC697, 0x8325, - 0xC698, 0x8326, 0xC699, 0x8329, 0xC69A, 0x832A, 0xC69B, 0x832E, 0xC69C, 0x8330, 0xC69D, 0x8332, 0xC69E, 0x8337, 0xC69F, 0x833B, - 0xC6A0, 0x833D, 0xC6A1, 0x5564, 0xC6A2, 0x813E, 0xC6A3, 0x75B2, 0xC6A4, 0x76AE, 0xC6A5, 0x5339, 0xC6A6, 0x75DE, 0xC6A7, 0x50FB, - 0xC6A8, 0x5C41, 0xC6A9, 0x8B6C, 0xC6AA, 0x7BC7, 0xC6AB, 0x504F, 0xC6AC, 0x7247, 0xC6AD, 0x9A97, 0xC6AE, 0x98D8, 0xC6AF, 0x6F02, - 0xC6B0, 0x74E2, 0xC6B1, 0x7968, 0xC6B2, 0x6487, 0xC6B3, 0x77A5, 0xC6B4, 0x62FC, 0xC6B5, 0x9891, 0xC6B6, 0x8D2B, 0xC6B7, 0x54C1, - 0xC6B8, 0x8058, 0xC6B9, 0x4E52, 0xC6BA, 0x576A, 0xC6BB, 0x82F9, 0xC6BC, 0x840D, 0xC6BD, 0x5E73, 0xC6BE, 0x51ED, 0xC6BF, 0x74F6, - 0xC6C0, 0x8BC4, 0xC6C1, 0x5C4F, 0xC6C2, 0x5761, 0xC6C3, 0x6CFC, 0xC6C4, 0x9887, 0xC6C5, 0x5A46, 0xC6C6, 0x7834, 0xC6C7, 0x9B44, - 0xC6C8, 0x8FEB, 0xC6C9, 0x7C95, 0xC6CA, 0x5256, 0xC6CB, 0x6251, 0xC6CC, 0x94FA, 0xC6CD, 0x4EC6, 0xC6CE, 0x8386, 0xC6CF, 0x8461, - 0xC6D0, 0x83E9, 0xC6D1, 0x84B2, 0xC6D2, 0x57D4, 0xC6D3, 0x6734, 0xC6D4, 0x5703, 0xC6D5, 0x666E, 0xC6D6, 0x6D66, 0xC6D7, 0x8C31, - 0xC6D8, 0x66DD, 0xC6D9, 0x7011, 0xC6DA, 0x671F, 0xC6DB, 0x6B3A, 0xC6DC, 0x6816, 0xC6DD, 0x621A, 0xC6DE, 0x59BB, 0xC6DF, 0x4E03, - 0xC6E0, 0x51C4, 0xC6E1, 0x6F06, 0xC6E2, 0x67D2, 0xC6E3, 0x6C8F, 0xC6E4, 0x5176, 0xC6E5, 0x68CB, 0xC6E6, 0x5947, 0xC6E7, 0x6B67, - 0xC6E8, 0x7566, 0xC6E9, 0x5D0E, 0xC6EA, 0x8110, 0xC6EB, 0x9F50, 0xC6EC, 0x65D7, 0xC6ED, 0x7948, 0xC6EE, 0x7941, 0xC6EF, 0x9A91, - 0xC6F0, 0x8D77, 0xC6F1, 0x5C82, 0xC6F2, 0x4E5E, 0xC6F3, 0x4F01, 0xC6F4, 0x542F, 0xC6F5, 0x5951, 0xC6F6, 0x780C, 0xC6F7, 0x5668, - 0xC6F8, 0x6C14, 0xC6F9, 0x8FC4, 0xC6FA, 0x5F03, 0xC6FB, 0x6C7D, 0xC6FC, 0x6CE3, 0xC6FD, 0x8BAB, 0xC6FE, 0x6390, 0xC740, 0x833E, - 0xC741, 0x833F, 0xC742, 0x8341, 0xC743, 0x8342, 0xC744, 0x8344, 0xC745, 0x8345, 0xC746, 0x8348, 0xC747, 0x834A, 0xC748, 0x834B, - 0xC749, 0x834C, 0xC74A, 0x834D, 0xC74B, 0x834E, 0xC74C, 0x8353, 0xC74D, 0x8355, 0xC74E, 0x8356, 0xC74F, 0x8357, 0xC750, 0x8358, - 0xC751, 0x8359, 0xC752, 0x835D, 0xC753, 0x8362, 0xC754, 0x8370, 0xC755, 0x8371, 0xC756, 0x8372, 0xC757, 0x8373, 0xC758, 0x8374, - 0xC759, 0x8375, 0xC75A, 0x8376, 0xC75B, 0x8379, 0xC75C, 0x837A, 0xC75D, 0x837E, 0xC75E, 0x837F, 0xC75F, 0x8380, 0xC760, 0x8381, - 0xC761, 0x8382, 0xC762, 0x8383, 0xC763, 0x8384, 0xC764, 0x8387, 0xC765, 0x8388, 0xC766, 0x838A, 0xC767, 0x838B, 0xC768, 0x838C, - 0xC769, 0x838D, 0xC76A, 0x838F, 0xC76B, 0x8390, 0xC76C, 0x8391, 0xC76D, 0x8394, 0xC76E, 0x8395, 0xC76F, 0x8396, 0xC770, 0x8397, - 0xC771, 0x8399, 0xC772, 0x839A, 0xC773, 0x839D, 0xC774, 0x839F, 0xC775, 0x83A1, 0xC776, 0x83A2, 0xC777, 0x83A3, 0xC778, 0x83A4, - 0xC779, 0x83A5, 0xC77A, 0x83A6, 0xC77B, 0x83A7, 0xC77C, 0x83AC, 0xC77D, 0x83AD, 0xC77E, 0x83AE, 0xC780, 0x83AF, 0xC781, 0x83B5, - 0xC782, 0x83BB, 0xC783, 0x83BE, 0xC784, 0x83BF, 0xC785, 0x83C2, 0xC786, 0x83C3, 0xC787, 0x83C4, 0xC788, 0x83C6, 0xC789, 0x83C8, - 0xC78A, 0x83C9, 0xC78B, 0x83CB, 0xC78C, 0x83CD, 0xC78D, 0x83CE, 0xC78E, 0x83D0, 0xC78F, 0x83D1, 0xC790, 0x83D2, 0xC791, 0x83D3, - 0xC792, 0x83D5, 0xC793, 0x83D7, 0xC794, 0x83D9, 0xC795, 0x83DA, 0xC796, 0x83DB, 0xC797, 0x83DE, 0xC798, 0x83E2, 0xC799, 0x83E3, - 0xC79A, 0x83E4, 0xC79B, 0x83E6, 0xC79C, 0x83E7, 0xC79D, 0x83E8, 0xC79E, 0x83EB, 0xC79F, 0x83EC, 0xC7A0, 0x83ED, 0xC7A1, 0x6070, - 0xC7A2, 0x6D3D, 0xC7A3, 0x7275, 0xC7A4, 0x6266, 0xC7A5, 0x948E, 0xC7A6, 0x94C5, 0xC7A7, 0x5343, 0xC7A8, 0x8FC1, 0xC7A9, 0x7B7E, - 0xC7AA, 0x4EDF, 0xC7AB, 0x8C26, 0xC7AC, 0x4E7E, 0xC7AD, 0x9ED4, 0xC7AE, 0x94B1, 0xC7AF, 0x94B3, 0xC7B0, 0x524D, 0xC7B1, 0x6F5C, - 0xC7B2, 0x9063, 0xC7B3, 0x6D45, 0xC7B4, 0x8C34, 0xC7B5, 0x5811, 0xC7B6, 0x5D4C, 0xC7B7, 0x6B20, 0xC7B8, 0x6B49, 0xC7B9, 0x67AA, - 0xC7BA, 0x545B, 0xC7BB, 0x8154, 0xC7BC, 0x7F8C, 0xC7BD, 0x5899, 0xC7BE, 0x8537, 0xC7BF, 0x5F3A, 0xC7C0, 0x62A2, 0xC7C1, 0x6A47, - 0xC7C2, 0x9539, 0xC7C3, 0x6572, 0xC7C4, 0x6084, 0xC7C5, 0x6865, 0xC7C6, 0x77A7, 0xC7C7, 0x4E54, 0xC7C8, 0x4FA8, 0xC7C9, 0x5DE7, - 0xC7CA, 0x9798, 0xC7CB, 0x64AC, 0xC7CC, 0x7FD8, 0xC7CD, 0x5CED, 0xC7CE, 0x4FCF, 0xC7CF, 0x7A8D, 0xC7D0, 0x5207, 0xC7D1, 0x8304, - 0xC7D2, 0x4E14, 0xC7D3, 0x602F, 0xC7D4, 0x7A83, 0xC7D5, 0x94A6, 0xC7D6, 0x4FB5, 0xC7D7, 0x4EB2, 0xC7D8, 0x79E6, 0xC7D9, 0x7434, - 0xC7DA, 0x52E4, 0xC7DB, 0x82B9, 0xC7DC, 0x64D2, 0xC7DD, 0x79BD, 0xC7DE, 0x5BDD, 0xC7DF, 0x6C81, 0xC7E0, 0x9752, 0xC7E1, 0x8F7B, - 0xC7E2, 0x6C22, 0xC7E3, 0x503E, 0xC7E4, 0x537F, 0xC7E5, 0x6E05, 0xC7E6, 0x64CE, 0xC7E7, 0x6674, 0xC7E8, 0x6C30, 0xC7E9, 0x60C5, - 0xC7EA, 0x9877, 0xC7EB, 0x8BF7, 0xC7EC, 0x5E86, 0xC7ED, 0x743C, 0xC7EE, 0x7A77, 0xC7EF, 0x79CB, 0xC7F0, 0x4E18, 0xC7F1, 0x90B1, - 0xC7F2, 0x7403, 0xC7F3, 0x6C42, 0xC7F4, 0x56DA, 0xC7F5, 0x914B, 0xC7F6, 0x6CC5, 0xC7F7, 0x8D8B, 0xC7F8, 0x533A, 0xC7F9, 0x86C6, - 0xC7FA, 0x66F2, 0xC7FB, 0x8EAF, 0xC7FC, 0x5C48, 0xC7FD, 0x9A71, 0xC7FE, 0x6E20, 0xC840, 0x83EE, 0xC841, 0x83EF, 0xC842, 0x83F3, - 0xC843, 0x83F4, 0xC844, 0x83F5, 0xC845, 0x83F6, 0xC846, 0x83F7, 0xC847, 0x83FA, 0xC848, 0x83FB, 0xC849, 0x83FC, 0xC84A, 0x83FE, - 0xC84B, 0x83FF, 0xC84C, 0x8400, 0xC84D, 0x8402, 0xC84E, 0x8405, 0xC84F, 0x8407, 0xC850, 0x8408, 0xC851, 0x8409, 0xC852, 0x840A, - 0xC853, 0x8410, 0xC854, 0x8412, 0xC855, 0x8413, 0xC856, 0x8414, 0xC857, 0x8415, 0xC858, 0x8416, 0xC859, 0x8417, 0xC85A, 0x8419, - 0xC85B, 0x841A, 0xC85C, 0x841B, 0xC85D, 0x841E, 0xC85E, 0x841F, 0xC85F, 0x8420, 0xC860, 0x8421, 0xC861, 0x8422, 0xC862, 0x8423, - 0xC863, 0x8429, 0xC864, 0x842A, 0xC865, 0x842B, 0xC866, 0x842C, 0xC867, 0x842D, 0xC868, 0x842E, 0xC869, 0x842F, 0xC86A, 0x8430, - 0xC86B, 0x8432, 0xC86C, 0x8433, 0xC86D, 0x8434, 0xC86E, 0x8435, 0xC86F, 0x8436, 0xC870, 0x8437, 0xC871, 0x8439, 0xC872, 0x843A, - 0xC873, 0x843B, 0xC874, 0x843E, 0xC875, 0x843F, 0xC876, 0x8440, 0xC877, 0x8441, 0xC878, 0x8442, 0xC879, 0x8443, 0xC87A, 0x8444, - 0xC87B, 0x8445, 0xC87C, 0x8447, 0xC87D, 0x8448, 0xC87E, 0x8449, 0xC880, 0x844A, 0xC881, 0x844B, 0xC882, 0x844C, 0xC883, 0x844D, - 0xC884, 0x844E, 0xC885, 0x844F, 0xC886, 0x8450, 0xC887, 0x8452, 0xC888, 0x8453, 0xC889, 0x8454, 0xC88A, 0x8455, 0xC88B, 0x8456, - 0xC88C, 0x8458, 0xC88D, 0x845D, 0xC88E, 0x845E, 0xC88F, 0x845F, 0xC890, 0x8460, 0xC891, 0x8462, 0xC892, 0x8464, 0xC893, 0x8465, - 0xC894, 0x8466, 0xC895, 0x8467, 0xC896, 0x8468, 0xC897, 0x846A, 0xC898, 0x846E, 0xC899, 0x846F, 0xC89A, 0x8470, 0xC89B, 0x8472, - 0xC89C, 0x8474, 0xC89D, 0x8477, 0xC89E, 0x8479, 0xC89F, 0x847B, 0xC8A0, 0x847C, 0xC8A1, 0x53D6, 0xC8A2, 0x5A36, 0xC8A3, 0x9F8B, - 0xC8A4, 0x8DA3, 0xC8A5, 0x53BB, 0xC8A6, 0x5708, 0xC8A7, 0x98A7, 0xC8A8, 0x6743, 0xC8A9, 0x919B, 0xC8AA, 0x6CC9, 0xC8AB, 0x5168, - 0xC8AC, 0x75CA, 0xC8AD, 0x62F3, 0xC8AE, 0x72AC, 0xC8AF, 0x5238, 0xC8B0, 0x529D, 0xC8B1, 0x7F3A, 0xC8B2, 0x7094, 0xC8B3, 0x7638, - 0xC8B4, 0x5374, 0xC8B5, 0x9E4A, 0xC8B6, 0x69B7, 0xC8B7, 0x786E, 0xC8B8, 0x96C0, 0xC8B9, 0x88D9, 0xC8BA, 0x7FA4, 0xC8BB, 0x7136, - 0xC8BC, 0x71C3, 0xC8BD, 0x5189, 0xC8BE, 0x67D3, 0xC8BF, 0x74E4, 0xC8C0, 0x58E4, 0xC8C1, 0x6518, 0xC8C2, 0x56B7, 0xC8C3, 0x8BA9, - 0xC8C4, 0x9976, 0xC8C5, 0x6270, 0xC8C6, 0x7ED5, 0xC8C7, 0x60F9, 0xC8C8, 0x70ED, 0xC8C9, 0x58EC, 0xC8CA, 0x4EC1, 0xC8CB, 0x4EBA, - 0xC8CC, 0x5FCD, 0xC8CD, 0x97E7, 0xC8CE, 0x4EFB, 0xC8CF, 0x8BA4, 0xC8D0, 0x5203, 0xC8D1, 0x598A, 0xC8D2, 0x7EAB, 0xC8D3, 0x6254, - 0xC8D4, 0x4ECD, 0xC8D5, 0x65E5, 0xC8D6, 0x620E, 0xC8D7, 0x8338, 0xC8D8, 0x84C9, 0xC8D9, 0x8363, 0xC8DA, 0x878D, 0xC8DB, 0x7194, - 0xC8DC, 0x6EB6, 0xC8DD, 0x5BB9, 0xC8DE, 0x7ED2, 0xC8DF, 0x5197, 0xC8E0, 0x63C9, 0xC8E1, 0x67D4, 0xC8E2, 0x8089, 0xC8E3, 0x8339, - 0xC8E4, 0x8815, 0xC8E5, 0x5112, 0xC8E6, 0x5B7A, 0xC8E7, 0x5982, 0xC8E8, 0x8FB1, 0xC8E9, 0x4E73, 0xC8EA, 0x6C5D, 0xC8EB, 0x5165, - 0xC8EC, 0x8925, 0xC8ED, 0x8F6F, 0xC8EE, 0x962E, 0xC8EF, 0x854A, 0xC8F0, 0x745E, 0xC8F1, 0x9510, 0xC8F2, 0x95F0, 0xC8F3, 0x6DA6, - 0xC8F4, 0x82E5, 0xC8F5, 0x5F31, 0xC8F6, 0x6492, 0xC8F7, 0x6D12, 0xC8F8, 0x8428, 0xC8F9, 0x816E, 0xC8FA, 0x9CC3, 0xC8FB, 0x585E, - 0xC8FC, 0x8D5B, 0xC8FD, 0x4E09, 0xC8FE, 0x53C1, 0xC940, 0x847D, 0xC941, 0x847E, 0xC942, 0x847F, 0xC943, 0x8480, 0xC944, 0x8481, - 0xC945, 0x8483, 0xC946, 0x8484, 0xC947, 0x8485, 0xC948, 0x8486, 0xC949, 0x848A, 0xC94A, 0x848D, 0xC94B, 0x848F, 0xC94C, 0x8490, - 0xC94D, 0x8491, 0xC94E, 0x8492, 0xC94F, 0x8493, 0xC950, 0x8494, 0xC951, 0x8495, 0xC952, 0x8496, 0xC953, 0x8498, 0xC954, 0x849A, - 0xC955, 0x849B, 0xC956, 0x849D, 0xC957, 0x849E, 0xC958, 0x849F, 0xC959, 0x84A0, 0xC95A, 0x84A2, 0xC95B, 0x84A3, 0xC95C, 0x84A4, - 0xC95D, 0x84A5, 0xC95E, 0x84A6, 0xC95F, 0x84A7, 0xC960, 0x84A8, 0xC961, 0x84A9, 0xC962, 0x84AA, 0xC963, 0x84AB, 0xC964, 0x84AC, - 0xC965, 0x84AD, 0xC966, 0x84AE, 0xC967, 0x84B0, 0xC968, 0x84B1, 0xC969, 0x84B3, 0xC96A, 0x84B5, 0xC96B, 0x84B6, 0xC96C, 0x84B7, - 0xC96D, 0x84BB, 0xC96E, 0x84BC, 0xC96F, 0x84BE, 0xC970, 0x84C0, 0xC971, 0x84C2, 0xC972, 0x84C3, 0xC973, 0x84C5, 0xC974, 0x84C6, - 0xC975, 0x84C7, 0xC976, 0x84C8, 0xC977, 0x84CB, 0xC978, 0x84CC, 0xC979, 0x84CE, 0xC97A, 0x84CF, 0xC97B, 0x84D2, 0xC97C, 0x84D4, - 0xC97D, 0x84D5, 0xC97E, 0x84D7, 0xC980, 0x84D8, 0xC981, 0x84D9, 0xC982, 0x84DA, 0xC983, 0x84DB, 0xC984, 0x84DC, 0xC985, 0x84DE, - 0xC986, 0x84E1, 0xC987, 0x84E2, 0xC988, 0x84E4, 0xC989, 0x84E7, 0xC98A, 0x84E8, 0xC98B, 0x84E9, 0xC98C, 0x84EA, 0xC98D, 0x84EB, - 0xC98E, 0x84ED, 0xC98F, 0x84EE, 0xC990, 0x84EF, 0xC991, 0x84F1, 0xC992, 0x84F2, 0xC993, 0x84F3, 0xC994, 0x84F4, 0xC995, 0x84F5, - 0xC996, 0x84F6, 0xC997, 0x84F7, 0xC998, 0x84F8, 0xC999, 0x84F9, 0xC99A, 0x84FA, 0xC99B, 0x84FB, 0xC99C, 0x84FD, 0xC99D, 0x84FE, - 0xC99E, 0x8500, 0xC99F, 0x8501, 0xC9A0, 0x8502, 0xC9A1, 0x4F1E, 0xC9A2, 0x6563, 0xC9A3, 0x6851, 0xC9A4, 0x55D3, 0xC9A5, 0x4E27, - 0xC9A6, 0x6414, 0xC9A7, 0x9A9A, 0xC9A8, 0x626B, 0xC9A9, 0x5AC2, 0xC9AA, 0x745F, 0xC9AB, 0x8272, 0xC9AC, 0x6DA9, 0xC9AD, 0x68EE, - 0xC9AE, 0x50E7, 0xC9AF, 0x838E, 0xC9B0, 0x7802, 0xC9B1, 0x6740, 0xC9B2, 0x5239, 0xC9B3, 0x6C99, 0xC9B4, 0x7EB1, 0xC9B5, 0x50BB, - 0xC9B6, 0x5565, 0xC9B7, 0x715E, 0xC9B8, 0x7B5B, 0xC9B9, 0x6652, 0xC9BA, 0x73CA, 0xC9BB, 0x82EB, 0xC9BC, 0x6749, 0xC9BD, 0x5C71, - 0xC9BE, 0x5220, 0xC9BF, 0x717D, 0xC9C0, 0x886B, 0xC9C1, 0x95EA, 0xC9C2, 0x9655, 0xC9C3, 0x64C5, 0xC9C4, 0x8D61, 0xC9C5, 0x81B3, - 0xC9C6, 0x5584, 0xC9C7, 0x6C55, 0xC9C8, 0x6247, 0xC9C9, 0x7F2E, 0xC9CA, 0x5892, 0xC9CB, 0x4F24, 0xC9CC, 0x5546, 0xC9CD, 0x8D4F, - 0xC9CE, 0x664C, 0xC9CF, 0x4E0A, 0xC9D0, 0x5C1A, 0xC9D1, 0x88F3, 0xC9D2, 0x68A2, 0xC9D3, 0x634E, 0xC9D4, 0x7A0D, 0xC9D5, 0x70E7, - 0xC9D6, 0x828D, 0xC9D7, 0x52FA, 0xC9D8, 0x97F6, 0xC9D9, 0x5C11, 0xC9DA, 0x54E8, 0xC9DB, 0x90B5, 0xC9DC, 0x7ECD, 0xC9DD, 0x5962, - 0xC9DE, 0x8D4A, 0xC9DF, 0x86C7, 0xC9E0, 0x820C, 0xC9E1, 0x820D, 0xC9E2, 0x8D66, 0xC9E3, 0x6444, 0xC9E4, 0x5C04, 0xC9E5, 0x6151, - 0xC9E6, 0x6D89, 0xC9E7, 0x793E, 0xC9E8, 0x8BBE, 0xC9E9, 0x7837, 0xC9EA, 0x7533, 0xC9EB, 0x547B, 0xC9EC, 0x4F38, 0xC9ED, 0x8EAB, - 0xC9EE, 0x6DF1, 0xC9EF, 0x5A20, 0xC9F0, 0x7EC5, 0xC9F1, 0x795E, 0xC9F2, 0x6C88, 0xC9F3, 0x5BA1, 0xC9F4, 0x5A76, 0xC9F5, 0x751A, - 0xC9F6, 0x80BE, 0xC9F7, 0x614E, 0xC9F8, 0x6E17, 0xC9F9, 0x58F0, 0xC9FA, 0x751F, 0xC9FB, 0x7525, 0xC9FC, 0x7272, 0xC9FD, 0x5347, - 0xC9FE, 0x7EF3, 0xCA40, 0x8503, 0xCA41, 0x8504, 0xCA42, 0x8505, 0xCA43, 0x8506, 0xCA44, 0x8507, 0xCA45, 0x8508, 0xCA46, 0x8509, - 0xCA47, 0x850A, 0xCA48, 0x850B, 0xCA49, 0x850D, 0xCA4A, 0x850E, 0xCA4B, 0x850F, 0xCA4C, 0x8510, 0xCA4D, 0x8512, 0xCA4E, 0x8514, - 0xCA4F, 0x8515, 0xCA50, 0x8516, 0xCA51, 0x8518, 0xCA52, 0x8519, 0xCA53, 0x851B, 0xCA54, 0x851C, 0xCA55, 0x851D, 0xCA56, 0x851E, - 0xCA57, 0x8520, 0xCA58, 0x8522, 0xCA59, 0x8523, 0xCA5A, 0x8524, 0xCA5B, 0x8525, 0xCA5C, 0x8526, 0xCA5D, 0x8527, 0xCA5E, 0x8528, - 0xCA5F, 0x8529, 0xCA60, 0x852A, 0xCA61, 0x852D, 0xCA62, 0x852E, 0xCA63, 0x852F, 0xCA64, 0x8530, 0xCA65, 0x8531, 0xCA66, 0x8532, - 0xCA67, 0x8533, 0xCA68, 0x8534, 0xCA69, 0x8535, 0xCA6A, 0x8536, 0xCA6B, 0x853E, 0xCA6C, 0x853F, 0xCA6D, 0x8540, 0xCA6E, 0x8541, - 0xCA6F, 0x8542, 0xCA70, 0x8544, 0xCA71, 0x8545, 0xCA72, 0x8546, 0xCA73, 0x8547, 0xCA74, 0x854B, 0xCA75, 0x854C, 0xCA76, 0x854D, - 0xCA77, 0x854E, 0xCA78, 0x854F, 0xCA79, 0x8550, 0xCA7A, 0x8551, 0xCA7B, 0x8552, 0xCA7C, 0x8553, 0xCA7D, 0x8554, 0xCA7E, 0x8555, - 0xCA80, 0x8557, 0xCA81, 0x8558, 0xCA82, 0x855A, 0xCA83, 0x855B, 0xCA84, 0x855C, 0xCA85, 0x855D, 0xCA86, 0x855F, 0xCA87, 0x8560, - 0xCA88, 0x8561, 0xCA89, 0x8562, 0xCA8A, 0x8563, 0xCA8B, 0x8565, 0xCA8C, 0x8566, 0xCA8D, 0x8567, 0xCA8E, 0x8569, 0xCA8F, 0x856A, - 0xCA90, 0x856B, 0xCA91, 0x856C, 0xCA92, 0x856D, 0xCA93, 0x856E, 0xCA94, 0x856F, 0xCA95, 0x8570, 0xCA96, 0x8571, 0xCA97, 0x8573, - 0xCA98, 0x8575, 0xCA99, 0x8576, 0xCA9A, 0x8577, 0xCA9B, 0x8578, 0xCA9C, 0x857C, 0xCA9D, 0x857D, 0xCA9E, 0x857F, 0xCA9F, 0x8580, - 0xCAA0, 0x8581, 0xCAA1, 0x7701, 0xCAA2, 0x76DB, 0xCAA3, 0x5269, 0xCAA4, 0x80DC, 0xCAA5, 0x5723, 0xCAA6, 0x5E08, 0xCAA7, 0x5931, - 0xCAA8, 0x72EE, 0xCAA9, 0x65BD, 0xCAAA, 0x6E7F, 0xCAAB, 0x8BD7, 0xCAAC, 0x5C38, 0xCAAD, 0x8671, 0xCAAE, 0x5341, 0xCAAF, 0x77F3, - 0xCAB0, 0x62FE, 0xCAB1, 0x65F6, 0xCAB2, 0x4EC0, 0xCAB3, 0x98DF, 0xCAB4, 0x8680, 0xCAB5, 0x5B9E, 0xCAB6, 0x8BC6, 0xCAB7, 0x53F2, - 0xCAB8, 0x77E2, 0xCAB9, 0x4F7F, 0xCABA, 0x5C4E, 0xCABB, 0x9A76, 0xCABC, 0x59CB, 0xCABD, 0x5F0F, 0xCABE, 0x793A, 0xCABF, 0x58EB, - 0xCAC0, 0x4E16, 0xCAC1, 0x67FF, 0xCAC2, 0x4E8B, 0xCAC3, 0x62ED, 0xCAC4, 0x8A93, 0xCAC5, 0x901D, 0xCAC6, 0x52BF, 0xCAC7, 0x662F, - 0xCAC8, 0x55DC, 0xCAC9, 0x566C, 0xCACA, 0x9002, 0xCACB, 0x4ED5, 0xCACC, 0x4F8D, 0xCACD, 0x91CA, 0xCACE, 0x9970, 0xCACF, 0x6C0F, - 0xCAD0, 0x5E02, 0xCAD1, 0x6043, 0xCAD2, 0x5BA4, 0xCAD3, 0x89C6, 0xCAD4, 0x8BD5, 0xCAD5, 0x6536, 0xCAD6, 0x624B, 0xCAD7, 0x9996, - 0xCAD8, 0x5B88, 0xCAD9, 0x5BFF, 0xCADA, 0x6388, 0xCADB, 0x552E, 0xCADC, 0x53D7, 0xCADD, 0x7626, 0xCADE, 0x517D, 0xCADF, 0x852C, - 0xCAE0, 0x67A2, 0xCAE1, 0x68B3, 0xCAE2, 0x6B8A, 0xCAE3, 0x6292, 0xCAE4, 0x8F93, 0xCAE5, 0x53D4, 0xCAE6, 0x8212, 0xCAE7, 0x6DD1, - 0xCAE8, 0x758F, 0xCAE9, 0x4E66, 0xCAEA, 0x8D4E, 0xCAEB, 0x5B70, 0xCAEC, 0x719F, 0xCAED, 0x85AF, 0xCAEE, 0x6691, 0xCAEF, 0x66D9, - 0xCAF0, 0x7F72, 0xCAF1, 0x8700, 0xCAF2, 0x9ECD, 0xCAF3, 0x9F20, 0xCAF4, 0x5C5E, 0xCAF5, 0x672F, 0xCAF6, 0x8FF0, 0xCAF7, 0x6811, - 0xCAF8, 0x675F, 0xCAF9, 0x620D, 0xCAFA, 0x7AD6, 0xCAFB, 0x5885, 0xCAFC, 0x5EB6, 0xCAFD, 0x6570, 0xCAFE, 0x6F31, 0xCB40, 0x8582, - 0xCB41, 0x8583, 0xCB42, 0x8586, 0xCB43, 0x8588, 0xCB44, 0x8589, 0xCB45, 0x858A, 0xCB46, 0x858B, 0xCB47, 0x858C, 0xCB48, 0x858D, - 0xCB49, 0x858E, 0xCB4A, 0x8590, 0xCB4B, 0x8591, 0xCB4C, 0x8592, 0xCB4D, 0x8593, 0xCB4E, 0x8594, 0xCB4F, 0x8595, 0xCB50, 0x8596, - 0xCB51, 0x8597, 0xCB52, 0x8598, 0xCB53, 0x8599, 0xCB54, 0x859A, 0xCB55, 0x859D, 0xCB56, 0x859E, 0xCB57, 0x859F, 0xCB58, 0x85A0, - 0xCB59, 0x85A1, 0xCB5A, 0x85A2, 0xCB5B, 0x85A3, 0xCB5C, 0x85A5, 0xCB5D, 0x85A6, 0xCB5E, 0x85A7, 0xCB5F, 0x85A9, 0xCB60, 0x85AB, - 0xCB61, 0x85AC, 0xCB62, 0x85AD, 0xCB63, 0x85B1, 0xCB64, 0x85B2, 0xCB65, 0x85B3, 0xCB66, 0x85B4, 0xCB67, 0x85B5, 0xCB68, 0x85B6, - 0xCB69, 0x85B8, 0xCB6A, 0x85BA, 0xCB6B, 0x85BB, 0xCB6C, 0x85BC, 0xCB6D, 0x85BD, 0xCB6E, 0x85BE, 0xCB6F, 0x85BF, 0xCB70, 0x85C0, - 0xCB71, 0x85C2, 0xCB72, 0x85C3, 0xCB73, 0x85C4, 0xCB74, 0x85C5, 0xCB75, 0x85C6, 0xCB76, 0x85C7, 0xCB77, 0x85C8, 0xCB78, 0x85CA, - 0xCB79, 0x85CB, 0xCB7A, 0x85CC, 0xCB7B, 0x85CD, 0xCB7C, 0x85CE, 0xCB7D, 0x85D1, 0xCB7E, 0x85D2, 0xCB80, 0x85D4, 0xCB81, 0x85D6, - 0xCB82, 0x85D7, 0xCB83, 0x85D8, 0xCB84, 0x85D9, 0xCB85, 0x85DA, 0xCB86, 0x85DB, 0xCB87, 0x85DD, 0xCB88, 0x85DE, 0xCB89, 0x85DF, - 0xCB8A, 0x85E0, 0xCB8B, 0x85E1, 0xCB8C, 0x85E2, 0xCB8D, 0x85E3, 0xCB8E, 0x85E5, 0xCB8F, 0x85E6, 0xCB90, 0x85E7, 0xCB91, 0x85E8, - 0xCB92, 0x85EA, 0xCB93, 0x85EB, 0xCB94, 0x85EC, 0xCB95, 0x85ED, 0xCB96, 0x85EE, 0xCB97, 0x85EF, 0xCB98, 0x85F0, 0xCB99, 0x85F1, - 0xCB9A, 0x85F2, 0xCB9B, 0x85F3, 0xCB9C, 0x85F4, 0xCB9D, 0x85F5, 0xCB9E, 0x85F6, 0xCB9F, 0x85F7, 0xCBA0, 0x85F8, 0xCBA1, 0x6055, - 0xCBA2, 0x5237, 0xCBA3, 0x800D, 0xCBA4, 0x6454, 0xCBA5, 0x8870, 0xCBA6, 0x7529, 0xCBA7, 0x5E05, 0xCBA8, 0x6813, 0xCBA9, 0x62F4, - 0xCBAA, 0x971C, 0xCBAB, 0x53CC, 0xCBAC, 0x723D, 0xCBAD, 0x8C01, 0xCBAE, 0x6C34, 0xCBAF, 0x7761, 0xCBB0, 0x7A0E, 0xCBB1, 0x542E, - 0xCBB2, 0x77AC, 0xCBB3, 0x987A, 0xCBB4, 0x821C, 0xCBB5, 0x8BF4, 0xCBB6, 0x7855, 0xCBB7, 0x6714, 0xCBB8, 0x70C1, 0xCBB9, 0x65AF, - 0xCBBA, 0x6495, 0xCBBB, 0x5636, 0xCBBC, 0x601D, 0xCBBD, 0x79C1, 0xCBBE, 0x53F8, 0xCBBF, 0x4E1D, 0xCBC0, 0x6B7B, 0xCBC1, 0x8086, - 0xCBC2, 0x5BFA, 0xCBC3, 0x55E3, 0xCBC4, 0x56DB, 0xCBC5, 0x4F3A, 0xCBC6, 0x4F3C, 0xCBC7, 0x9972, 0xCBC8, 0x5DF3, 0xCBC9, 0x677E, - 0xCBCA, 0x8038, 0xCBCB, 0x6002, 0xCBCC, 0x9882, 0xCBCD, 0x9001, 0xCBCE, 0x5B8B, 0xCBCF, 0x8BBC, 0xCBD0, 0x8BF5, 0xCBD1, 0x641C, - 0xCBD2, 0x8258, 0xCBD3, 0x64DE, 0xCBD4, 0x55FD, 0xCBD5, 0x82CF, 0xCBD6, 0x9165, 0xCBD7, 0x4FD7, 0xCBD8, 0x7D20, 0xCBD9, 0x901F, - 0xCBDA, 0x7C9F, 0xCBDB, 0x50F3, 0xCBDC, 0x5851, 0xCBDD, 0x6EAF, 0xCBDE, 0x5BBF, 0xCBDF, 0x8BC9, 0xCBE0, 0x8083, 0xCBE1, 0x9178, - 0xCBE2, 0x849C, 0xCBE3, 0x7B97, 0xCBE4, 0x867D, 0xCBE5, 0x968B, 0xCBE6, 0x968F, 0xCBE7, 0x7EE5, 0xCBE8, 0x9AD3, 0xCBE9, 0x788E, - 0xCBEA, 0x5C81, 0xCBEB, 0x7A57, 0xCBEC, 0x9042, 0xCBED, 0x96A7, 0xCBEE, 0x795F, 0xCBEF, 0x5B59, 0xCBF0, 0x635F, 0xCBF1, 0x7B0B, - 0xCBF2, 0x84D1, 0xCBF3, 0x68AD, 0xCBF4, 0x5506, 0xCBF5, 0x7F29, 0xCBF6, 0x7410, 0xCBF7, 0x7D22, 0xCBF8, 0x9501, 0xCBF9, 0x6240, - 0xCBFA, 0x584C, 0xCBFB, 0x4ED6, 0xCBFC, 0x5B83, 0xCBFD, 0x5979, 0xCBFE, 0x5854, 0xCC40, 0x85F9, 0xCC41, 0x85FA, 0xCC42, 0x85FC, - 0xCC43, 0x85FD, 0xCC44, 0x85FE, 0xCC45, 0x8600, 0xCC46, 0x8601, 0xCC47, 0x8602, 0xCC48, 0x8603, 0xCC49, 0x8604, 0xCC4A, 0x8606, - 0xCC4B, 0x8607, 0xCC4C, 0x8608, 0xCC4D, 0x8609, 0xCC4E, 0x860A, 0xCC4F, 0x860B, 0xCC50, 0x860C, 0xCC51, 0x860D, 0xCC52, 0x860E, - 0xCC53, 0x860F, 0xCC54, 0x8610, 0xCC55, 0x8612, 0xCC56, 0x8613, 0xCC57, 0x8614, 0xCC58, 0x8615, 0xCC59, 0x8617, 0xCC5A, 0x8618, - 0xCC5B, 0x8619, 0xCC5C, 0x861A, 0xCC5D, 0x861B, 0xCC5E, 0x861C, 0xCC5F, 0x861D, 0xCC60, 0x861E, 0xCC61, 0x861F, 0xCC62, 0x8620, - 0xCC63, 0x8621, 0xCC64, 0x8622, 0xCC65, 0x8623, 0xCC66, 0x8624, 0xCC67, 0x8625, 0xCC68, 0x8626, 0xCC69, 0x8628, 0xCC6A, 0x862A, - 0xCC6B, 0x862B, 0xCC6C, 0x862C, 0xCC6D, 0x862D, 0xCC6E, 0x862E, 0xCC6F, 0x862F, 0xCC70, 0x8630, 0xCC71, 0x8631, 0xCC72, 0x8632, - 0xCC73, 0x8633, 0xCC74, 0x8634, 0xCC75, 0x8635, 0xCC76, 0x8636, 0xCC77, 0x8637, 0xCC78, 0x8639, 0xCC79, 0x863A, 0xCC7A, 0x863B, - 0xCC7B, 0x863D, 0xCC7C, 0x863E, 0xCC7D, 0x863F, 0xCC7E, 0x8640, 0xCC80, 0x8641, 0xCC81, 0x8642, 0xCC82, 0x8643, 0xCC83, 0x8644, - 0xCC84, 0x8645, 0xCC85, 0x8646, 0xCC86, 0x8647, 0xCC87, 0x8648, 0xCC88, 0x8649, 0xCC89, 0x864A, 0xCC8A, 0x864B, 0xCC8B, 0x864C, - 0xCC8C, 0x8652, 0xCC8D, 0x8653, 0xCC8E, 0x8655, 0xCC8F, 0x8656, 0xCC90, 0x8657, 0xCC91, 0x8658, 0xCC92, 0x8659, 0xCC93, 0x865B, - 0xCC94, 0x865C, 0xCC95, 0x865D, 0xCC96, 0x865F, 0xCC97, 0x8660, 0xCC98, 0x8661, 0xCC99, 0x8663, 0xCC9A, 0x8664, 0xCC9B, 0x8665, - 0xCC9C, 0x8666, 0xCC9D, 0x8667, 0xCC9E, 0x8668, 0xCC9F, 0x8669, 0xCCA0, 0x866A, 0xCCA1, 0x736D, 0xCCA2, 0x631E, 0xCCA3, 0x8E4B, - 0xCCA4, 0x8E0F, 0xCCA5, 0x80CE, 0xCCA6, 0x82D4, 0xCCA7, 0x62AC, 0xCCA8, 0x53F0, 0xCCA9, 0x6CF0, 0xCCAA, 0x915E, 0xCCAB, 0x592A, - 0xCCAC, 0x6001, 0xCCAD, 0x6C70, 0xCCAE, 0x574D, 0xCCAF, 0x644A, 0xCCB0, 0x8D2A, 0xCCB1, 0x762B, 0xCCB2, 0x6EE9, 0xCCB3, 0x575B, - 0xCCB4, 0x6A80, 0xCCB5, 0x75F0, 0xCCB6, 0x6F6D, 0xCCB7, 0x8C2D, 0xCCB8, 0x8C08, 0xCCB9, 0x5766, 0xCCBA, 0x6BEF, 0xCCBB, 0x8892, - 0xCCBC, 0x78B3, 0xCCBD, 0x63A2, 0xCCBE, 0x53F9, 0xCCBF, 0x70AD, 0xCCC0, 0x6C64, 0xCCC1, 0x5858, 0xCCC2, 0x642A, 0xCCC3, 0x5802, - 0xCCC4, 0x68E0, 0xCCC5, 0x819B, 0xCCC6, 0x5510, 0xCCC7, 0x7CD6, 0xCCC8, 0x5018, 0xCCC9, 0x8EBA, 0xCCCA, 0x6DCC, 0xCCCB, 0x8D9F, - 0xCCCC, 0x70EB, 0xCCCD, 0x638F, 0xCCCE, 0x6D9B, 0xCCCF, 0x6ED4, 0xCCD0, 0x7EE6, 0xCCD1, 0x8404, 0xCCD2, 0x6843, 0xCCD3, 0x9003, - 0xCCD4, 0x6DD8, 0xCCD5, 0x9676, 0xCCD6, 0x8BA8, 0xCCD7, 0x5957, 0xCCD8, 0x7279, 0xCCD9, 0x85E4, 0xCCDA, 0x817E, 0xCCDB, 0x75BC, - 0xCCDC, 0x8A8A, 0xCCDD, 0x68AF, 0xCCDE, 0x5254, 0xCCDF, 0x8E22, 0xCCE0, 0x9511, 0xCCE1, 0x63D0, 0xCCE2, 0x9898, 0xCCE3, 0x8E44, - 0xCCE4, 0x557C, 0xCCE5, 0x4F53, 0xCCE6, 0x66FF, 0xCCE7, 0x568F, 0xCCE8, 0x60D5, 0xCCE9, 0x6D95, 0xCCEA, 0x5243, 0xCCEB, 0x5C49, - 0xCCEC, 0x5929, 0xCCED, 0x6DFB, 0xCCEE, 0x586B, 0xCCEF, 0x7530, 0xCCF0, 0x751C, 0xCCF1, 0x606C, 0xCCF2, 0x8214, 0xCCF3, 0x8146, - 0xCCF4, 0x6311, 0xCCF5, 0x6761, 0xCCF6, 0x8FE2, 0xCCF7, 0x773A, 0xCCF8, 0x8DF3, 0xCCF9, 0x8D34, 0xCCFA, 0x94C1, 0xCCFB, 0x5E16, - 0xCCFC, 0x5385, 0xCCFD, 0x542C, 0xCCFE, 0x70C3, 0xCD40, 0x866D, 0xCD41, 0x866F, 0xCD42, 0x8670, 0xCD43, 0x8672, 0xCD44, 0x8673, - 0xCD45, 0x8674, 0xCD46, 0x8675, 0xCD47, 0x8676, 0xCD48, 0x8677, 0xCD49, 0x8678, 0xCD4A, 0x8683, 0xCD4B, 0x8684, 0xCD4C, 0x8685, - 0xCD4D, 0x8686, 0xCD4E, 0x8687, 0xCD4F, 0x8688, 0xCD50, 0x8689, 0xCD51, 0x868E, 0xCD52, 0x868F, 0xCD53, 0x8690, 0xCD54, 0x8691, - 0xCD55, 0x8692, 0xCD56, 0x8694, 0xCD57, 0x8696, 0xCD58, 0x8697, 0xCD59, 0x8698, 0xCD5A, 0x8699, 0xCD5B, 0x869A, 0xCD5C, 0x869B, - 0xCD5D, 0x869E, 0xCD5E, 0x869F, 0xCD5F, 0x86A0, 0xCD60, 0x86A1, 0xCD61, 0x86A2, 0xCD62, 0x86A5, 0xCD63, 0x86A6, 0xCD64, 0x86AB, - 0xCD65, 0x86AD, 0xCD66, 0x86AE, 0xCD67, 0x86B2, 0xCD68, 0x86B3, 0xCD69, 0x86B7, 0xCD6A, 0x86B8, 0xCD6B, 0x86B9, 0xCD6C, 0x86BB, - 0xCD6D, 0x86BC, 0xCD6E, 0x86BD, 0xCD6F, 0x86BE, 0xCD70, 0x86BF, 0xCD71, 0x86C1, 0xCD72, 0x86C2, 0xCD73, 0x86C3, 0xCD74, 0x86C5, - 0xCD75, 0x86C8, 0xCD76, 0x86CC, 0xCD77, 0x86CD, 0xCD78, 0x86D2, 0xCD79, 0x86D3, 0xCD7A, 0x86D5, 0xCD7B, 0x86D6, 0xCD7C, 0x86D7, - 0xCD7D, 0x86DA, 0xCD7E, 0x86DC, 0xCD80, 0x86DD, 0xCD81, 0x86E0, 0xCD82, 0x86E1, 0xCD83, 0x86E2, 0xCD84, 0x86E3, 0xCD85, 0x86E5, - 0xCD86, 0x86E6, 0xCD87, 0x86E7, 0xCD88, 0x86E8, 0xCD89, 0x86EA, 0xCD8A, 0x86EB, 0xCD8B, 0x86EC, 0xCD8C, 0x86EF, 0xCD8D, 0x86F5, - 0xCD8E, 0x86F6, 0xCD8F, 0x86F7, 0xCD90, 0x86FA, 0xCD91, 0x86FB, 0xCD92, 0x86FC, 0xCD93, 0x86FD, 0xCD94, 0x86FF, 0xCD95, 0x8701, - 0xCD96, 0x8704, 0xCD97, 0x8705, 0xCD98, 0x8706, 0xCD99, 0x870B, 0xCD9A, 0x870C, 0xCD9B, 0x870E, 0xCD9C, 0x870F, 0xCD9D, 0x8710, - 0xCD9E, 0x8711, 0xCD9F, 0x8714, 0xCDA0, 0x8716, 0xCDA1, 0x6C40, 0xCDA2, 0x5EF7, 0xCDA3, 0x505C, 0xCDA4, 0x4EAD, 0xCDA5, 0x5EAD, - 0xCDA6, 0x633A, 0xCDA7, 0x8247, 0xCDA8, 0x901A, 0xCDA9, 0x6850, 0xCDAA, 0x916E, 0xCDAB, 0x77B3, 0xCDAC, 0x540C, 0xCDAD, 0x94DC, - 0xCDAE, 0x5F64, 0xCDAF, 0x7AE5, 0xCDB0, 0x6876, 0xCDB1, 0x6345, 0xCDB2, 0x7B52, 0xCDB3, 0x7EDF, 0xCDB4, 0x75DB, 0xCDB5, 0x5077, - 0xCDB6, 0x6295, 0xCDB7, 0x5934, 0xCDB8, 0x900F, 0xCDB9, 0x51F8, 0xCDBA, 0x79C3, 0xCDBB, 0x7A81, 0xCDBC, 0x56FE, 0xCDBD, 0x5F92, - 0xCDBE, 0x9014, 0xCDBF, 0x6D82, 0xCDC0, 0x5C60, 0xCDC1, 0x571F, 0xCDC2, 0x5410, 0xCDC3, 0x5154, 0xCDC4, 0x6E4D, 0xCDC5, 0x56E2, - 0xCDC6, 0x63A8, 0xCDC7, 0x9893, 0xCDC8, 0x817F, 0xCDC9, 0x8715, 0xCDCA, 0x892A, 0xCDCB, 0x9000, 0xCDCC, 0x541E, 0xCDCD, 0x5C6F, - 0xCDCE, 0x81C0, 0xCDCF, 0x62D6, 0xCDD0, 0x6258, 0xCDD1, 0x8131, 0xCDD2, 0x9E35, 0xCDD3, 0x9640, 0xCDD4, 0x9A6E, 0xCDD5, 0x9A7C, - 0xCDD6, 0x692D, 0xCDD7, 0x59A5, 0xCDD8, 0x62D3, 0xCDD9, 0x553E, 0xCDDA, 0x6316, 0xCDDB, 0x54C7, 0xCDDC, 0x86D9, 0xCDDD, 0x6D3C, - 0xCDDE, 0x5A03, 0xCDDF, 0x74E6, 0xCDE0, 0x889C, 0xCDE1, 0x6B6A, 0xCDE2, 0x5916, 0xCDE3, 0x8C4C, 0xCDE4, 0x5F2F, 0xCDE5, 0x6E7E, - 0xCDE6, 0x73A9, 0xCDE7, 0x987D, 0xCDE8, 0x4E38, 0xCDE9, 0x70F7, 0xCDEA, 0x5B8C, 0xCDEB, 0x7897, 0xCDEC, 0x633D, 0xCDED, 0x665A, - 0xCDEE, 0x7696, 0xCDEF, 0x60CB, 0xCDF0, 0x5B9B, 0xCDF1, 0x5A49, 0xCDF2, 0x4E07, 0xCDF3, 0x8155, 0xCDF4, 0x6C6A, 0xCDF5, 0x738B, - 0xCDF6, 0x4EA1, 0xCDF7, 0x6789, 0xCDF8, 0x7F51, 0xCDF9, 0x5F80, 0xCDFA, 0x65FA, 0xCDFB, 0x671B, 0xCDFC, 0x5FD8, 0xCDFD, 0x5984, - 0xCDFE, 0x5A01, 0xCE40, 0x8719, 0xCE41, 0x871B, 0xCE42, 0x871D, 0xCE43, 0x871F, 0xCE44, 0x8720, 0xCE45, 0x8724, 0xCE46, 0x8726, - 0xCE47, 0x8727, 0xCE48, 0x8728, 0xCE49, 0x872A, 0xCE4A, 0x872B, 0xCE4B, 0x872C, 0xCE4C, 0x872D, 0xCE4D, 0x872F, 0xCE4E, 0x8730, - 0xCE4F, 0x8732, 0xCE50, 0x8733, 0xCE51, 0x8735, 0xCE52, 0x8736, 0xCE53, 0x8738, 0xCE54, 0x8739, 0xCE55, 0x873A, 0xCE56, 0x873C, - 0xCE57, 0x873D, 0xCE58, 0x8740, 0xCE59, 0x8741, 0xCE5A, 0x8742, 0xCE5B, 0x8743, 0xCE5C, 0x8744, 0xCE5D, 0x8745, 0xCE5E, 0x8746, - 0xCE5F, 0x874A, 0xCE60, 0x874B, 0xCE61, 0x874D, 0xCE62, 0x874F, 0xCE63, 0x8750, 0xCE64, 0x8751, 0xCE65, 0x8752, 0xCE66, 0x8754, - 0xCE67, 0x8755, 0xCE68, 0x8756, 0xCE69, 0x8758, 0xCE6A, 0x875A, 0xCE6B, 0x875B, 0xCE6C, 0x875C, 0xCE6D, 0x875D, 0xCE6E, 0x875E, - 0xCE6F, 0x875F, 0xCE70, 0x8761, 0xCE71, 0x8762, 0xCE72, 0x8766, 0xCE73, 0x8767, 0xCE74, 0x8768, 0xCE75, 0x8769, 0xCE76, 0x876A, - 0xCE77, 0x876B, 0xCE78, 0x876C, 0xCE79, 0x876D, 0xCE7A, 0x876F, 0xCE7B, 0x8771, 0xCE7C, 0x8772, 0xCE7D, 0x8773, 0xCE7E, 0x8775, - 0xCE80, 0x8777, 0xCE81, 0x8778, 0xCE82, 0x8779, 0xCE83, 0x877A, 0xCE84, 0x877F, 0xCE85, 0x8780, 0xCE86, 0x8781, 0xCE87, 0x8784, - 0xCE88, 0x8786, 0xCE89, 0x8787, 0xCE8A, 0x8789, 0xCE8B, 0x878A, 0xCE8C, 0x878C, 0xCE8D, 0x878E, 0xCE8E, 0x878F, 0xCE8F, 0x8790, - 0xCE90, 0x8791, 0xCE91, 0x8792, 0xCE92, 0x8794, 0xCE93, 0x8795, 0xCE94, 0x8796, 0xCE95, 0x8798, 0xCE96, 0x8799, 0xCE97, 0x879A, - 0xCE98, 0x879B, 0xCE99, 0x879C, 0xCE9A, 0x879D, 0xCE9B, 0x879E, 0xCE9C, 0x87A0, 0xCE9D, 0x87A1, 0xCE9E, 0x87A2, 0xCE9F, 0x87A3, - 0xCEA0, 0x87A4, 0xCEA1, 0x5DCD, 0xCEA2, 0x5FAE, 0xCEA3, 0x5371, 0xCEA4, 0x97E6, 0xCEA5, 0x8FDD, 0xCEA6, 0x6845, 0xCEA7, 0x56F4, - 0xCEA8, 0x552F, 0xCEA9, 0x60DF, 0xCEAA, 0x4E3A, 0xCEAB, 0x6F4D, 0xCEAC, 0x7EF4, 0xCEAD, 0x82C7, 0xCEAE, 0x840E, 0xCEAF, 0x59D4, - 0xCEB0, 0x4F1F, 0xCEB1, 0x4F2A, 0xCEB2, 0x5C3E, 0xCEB3, 0x7EAC, 0xCEB4, 0x672A, 0xCEB5, 0x851A, 0xCEB6, 0x5473, 0xCEB7, 0x754F, - 0xCEB8, 0x80C3, 0xCEB9, 0x5582, 0xCEBA, 0x9B4F, 0xCEBB, 0x4F4D, 0xCEBC, 0x6E2D, 0xCEBD, 0x8C13, 0xCEBE, 0x5C09, 0xCEBF, 0x6170, - 0xCEC0, 0x536B, 0xCEC1, 0x761F, 0xCEC2, 0x6E29, 0xCEC3, 0x868A, 0xCEC4, 0x6587, 0xCEC5, 0x95FB, 0xCEC6, 0x7EB9, 0xCEC7, 0x543B, - 0xCEC8, 0x7A33, 0xCEC9, 0x7D0A, 0xCECA, 0x95EE, 0xCECB, 0x55E1, 0xCECC, 0x7FC1, 0xCECD, 0x74EE, 0xCECE, 0x631D, 0xCECF, 0x8717, - 0xCED0, 0x6DA1, 0xCED1, 0x7A9D, 0xCED2, 0x6211, 0xCED3, 0x65A1, 0xCED4, 0x5367, 0xCED5, 0x63E1, 0xCED6, 0x6C83, 0xCED7, 0x5DEB, - 0xCED8, 0x545C, 0xCED9, 0x94A8, 0xCEDA, 0x4E4C, 0xCEDB, 0x6C61, 0xCEDC, 0x8BEC, 0xCEDD, 0x5C4B, 0xCEDE, 0x65E0, 0xCEDF, 0x829C, - 0xCEE0, 0x68A7, 0xCEE1, 0x543E, 0xCEE2, 0x5434, 0xCEE3, 0x6BCB, 0xCEE4, 0x6B66, 0xCEE5, 0x4E94, 0xCEE6, 0x6342, 0xCEE7, 0x5348, - 0xCEE8, 0x821E, 0xCEE9, 0x4F0D, 0xCEEA, 0x4FAE, 0xCEEB, 0x575E, 0xCEEC, 0x620A, 0xCEED, 0x96FE, 0xCEEE, 0x6664, 0xCEEF, 0x7269, - 0xCEF0, 0x52FF, 0xCEF1, 0x52A1, 0xCEF2, 0x609F, 0xCEF3, 0x8BEF, 0xCEF4, 0x6614, 0xCEF5, 0x7199, 0xCEF6, 0x6790, 0xCEF7, 0x897F, - 0xCEF8, 0x7852, 0xCEF9, 0x77FD, 0xCEFA, 0x6670, 0xCEFB, 0x563B, 0xCEFC, 0x5438, 0xCEFD, 0x9521, 0xCEFE, 0x727A, 0xCF40, 0x87A5, - 0xCF41, 0x87A6, 0xCF42, 0x87A7, 0xCF43, 0x87A9, 0xCF44, 0x87AA, 0xCF45, 0x87AE, 0xCF46, 0x87B0, 0xCF47, 0x87B1, 0xCF48, 0x87B2, - 0xCF49, 0x87B4, 0xCF4A, 0x87B6, 0xCF4B, 0x87B7, 0xCF4C, 0x87B8, 0xCF4D, 0x87B9, 0xCF4E, 0x87BB, 0xCF4F, 0x87BC, 0xCF50, 0x87BE, - 0xCF51, 0x87BF, 0xCF52, 0x87C1, 0xCF53, 0x87C2, 0xCF54, 0x87C3, 0xCF55, 0x87C4, 0xCF56, 0x87C5, 0xCF57, 0x87C7, 0xCF58, 0x87C8, - 0xCF59, 0x87C9, 0xCF5A, 0x87CC, 0xCF5B, 0x87CD, 0xCF5C, 0x87CE, 0xCF5D, 0x87CF, 0xCF5E, 0x87D0, 0xCF5F, 0x87D4, 0xCF60, 0x87D5, - 0xCF61, 0x87D6, 0xCF62, 0x87D7, 0xCF63, 0x87D8, 0xCF64, 0x87D9, 0xCF65, 0x87DA, 0xCF66, 0x87DC, 0xCF67, 0x87DD, 0xCF68, 0x87DE, - 0xCF69, 0x87DF, 0xCF6A, 0x87E1, 0xCF6B, 0x87E2, 0xCF6C, 0x87E3, 0xCF6D, 0x87E4, 0xCF6E, 0x87E6, 0xCF6F, 0x87E7, 0xCF70, 0x87E8, - 0xCF71, 0x87E9, 0xCF72, 0x87EB, 0xCF73, 0x87EC, 0xCF74, 0x87ED, 0xCF75, 0x87EF, 0xCF76, 0x87F0, 0xCF77, 0x87F1, 0xCF78, 0x87F2, - 0xCF79, 0x87F3, 0xCF7A, 0x87F4, 0xCF7B, 0x87F5, 0xCF7C, 0x87F6, 0xCF7D, 0x87F7, 0xCF7E, 0x87F8, 0xCF80, 0x87FA, 0xCF81, 0x87FB, - 0xCF82, 0x87FC, 0xCF83, 0x87FD, 0xCF84, 0x87FF, 0xCF85, 0x8800, 0xCF86, 0x8801, 0xCF87, 0x8802, 0xCF88, 0x8804, 0xCF89, 0x8805, - 0xCF8A, 0x8806, 0xCF8B, 0x8807, 0xCF8C, 0x8808, 0xCF8D, 0x8809, 0xCF8E, 0x880B, 0xCF8F, 0x880C, 0xCF90, 0x880D, 0xCF91, 0x880E, - 0xCF92, 0x880F, 0xCF93, 0x8810, 0xCF94, 0x8811, 0xCF95, 0x8812, 0xCF96, 0x8814, 0xCF97, 0x8817, 0xCF98, 0x8818, 0xCF99, 0x8819, - 0xCF9A, 0x881A, 0xCF9B, 0x881C, 0xCF9C, 0x881D, 0xCF9D, 0x881E, 0xCF9E, 0x881F, 0xCF9F, 0x8820, 0xCFA0, 0x8823, 0xCFA1, 0x7A00, - 0xCFA2, 0x606F, 0xCFA3, 0x5E0C, 0xCFA4, 0x6089, 0xCFA5, 0x819D, 0xCFA6, 0x5915, 0xCFA7, 0x60DC, 0xCFA8, 0x7184, 0xCFA9, 0x70EF, - 0xCFAA, 0x6EAA, 0xCFAB, 0x6C50, 0xCFAC, 0x7280, 0xCFAD, 0x6A84, 0xCFAE, 0x88AD, 0xCFAF, 0x5E2D, 0xCFB0, 0x4E60, 0xCFB1, 0x5AB3, - 0xCFB2, 0x559C, 0xCFB3, 0x94E3, 0xCFB4, 0x6D17, 0xCFB5, 0x7CFB, 0xCFB6, 0x9699, 0xCFB7, 0x620F, 0xCFB8, 0x7EC6, 0xCFB9, 0x778E, - 0xCFBA, 0x867E, 0xCFBB, 0x5323, 0xCFBC, 0x971E, 0xCFBD, 0x8F96, 0xCFBE, 0x6687, 0xCFBF, 0x5CE1, 0xCFC0, 0x4FA0, 0xCFC1, 0x72ED, - 0xCFC2, 0x4E0B, 0xCFC3, 0x53A6, 0xCFC4, 0x590F, 0xCFC5, 0x5413, 0xCFC6, 0x6380, 0xCFC7, 0x9528, 0xCFC8, 0x5148, 0xCFC9, 0x4ED9, - 0xCFCA, 0x9C9C, 0xCFCB, 0x7EA4, 0xCFCC, 0x54B8, 0xCFCD, 0x8D24, 0xCFCE, 0x8854, 0xCFCF, 0x8237, 0xCFD0, 0x95F2, 0xCFD1, 0x6D8E, - 0xCFD2, 0x5F26, 0xCFD3, 0x5ACC, 0xCFD4, 0x663E, 0xCFD5, 0x9669, 0xCFD6, 0x73B0, 0xCFD7, 0x732E, 0xCFD8, 0x53BF, 0xCFD9, 0x817A, - 0xCFDA, 0x9985, 0xCFDB, 0x7FA1, 0xCFDC, 0x5BAA, 0xCFDD, 0x9677, 0xCFDE, 0x9650, 0xCFDF, 0x7EBF, 0xCFE0, 0x76F8, 0xCFE1, 0x53A2, - 0xCFE2, 0x9576, 0xCFE3, 0x9999, 0xCFE4, 0x7BB1, 0xCFE5, 0x8944, 0xCFE6, 0x6E58, 0xCFE7, 0x4E61, 0xCFE8, 0x7FD4, 0xCFE9, 0x7965, - 0xCFEA, 0x8BE6, 0xCFEB, 0x60F3, 0xCFEC, 0x54CD, 0xCFED, 0x4EAB, 0xCFEE, 0x9879, 0xCFEF, 0x5DF7, 0xCFF0, 0x6A61, 0xCFF1, 0x50CF, - 0xCFF2, 0x5411, 0xCFF3, 0x8C61, 0xCFF4, 0x8427, 0xCFF5, 0x785D, 0xCFF6, 0x9704, 0xCFF7, 0x524A, 0xCFF8, 0x54EE, 0xCFF9, 0x56A3, - 0xCFFA, 0x9500, 0xCFFB, 0x6D88, 0xCFFC, 0x5BB5, 0xCFFD, 0x6DC6, 0xCFFE, 0x6653, 0xD040, 0x8824, 0xD041, 0x8825, 0xD042, 0x8826, - 0xD043, 0x8827, 0xD044, 0x8828, 0xD045, 0x8829, 0xD046, 0x882A, 0xD047, 0x882B, 0xD048, 0x882C, 0xD049, 0x882D, 0xD04A, 0x882E, - 0xD04B, 0x882F, 0xD04C, 0x8830, 0xD04D, 0x8831, 0xD04E, 0x8833, 0xD04F, 0x8834, 0xD050, 0x8835, 0xD051, 0x8836, 0xD052, 0x8837, - 0xD053, 0x8838, 0xD054, 0x883A, 0xD055, 0x883B, 0xD056, 0x883D, 0xD057, 0x883E, 0xD058, 0x883F, 0xD059, 0x8841, 0xD05A, 0x8842, - 0xD05B, 0x8843, 0xD05C, 0x8846, 0xD05D, 0x8847, 0xD05E, 0x8848, 0xD05F, 0x8849, 0xD060, 0x884A, 0xD061, 0x884B, 0xD062, 0x884E, - 0xD063, 0x884F, 0xD064, 0x8850, 0xD065, 0x8851, 0xD066, 0x8852, 0xD067, 0x8853, 0xD068, 0x8855, 0xD069, 0x8856, 0xD06A, 0x8858, - 0xD06B, 0x885A, 0xD06C, 0x885B, 0xD06D, 0x885C, 0xD06E, 0x885D, 0xD06F, 0x885E, 0xD070, 0x885F, 0xD071, 0x8860, 0xD072, 0x8866, - 0xD073, 0x8867, 0xD074, 0x886A, 0xD075, 0x886D, 0xD076, 0x886F, 0xD077, 0x8871, 0xD078, 0x8873, 0xD079, 0x8874, 0xD07A, 0x8875, - 0xD07B, 0x8876, 0xD07C, 0x8878, 0xD07D, 0x8879, 0xD07E, 0x887A, 0xD080, 0x887B, 0xD081, 0x887C, 0xD082, 0x8880, 0xD083, 0x8883, - 0xD084, 0x8886, 0xD085, 0x8887, 0xD086, 0x8889, 0xD087, 0x888A, 0xD088, 0x888C, 0xD089, 0x888E, 0xD08A, 0x888F, 0xD08B, 0x8890, - 0xD08C, 0x8891, 0xD08D, 0x8893, 0xD08E, 0x8894, 0xD08F, 0x8895, 0xD090, 0x8897, 0xD091, 0x8898, 0xD092, 0x8899, 0xD093, 0x889A, - 0xD094, 0x889B, 0xD095, 0x889D, 0xD096, 0x889E, 0xD097, 0x889F, 0xD098, 0x88A0, 0xD099, 0x88A1, 0xD09A, 0x88A3, 0xD09B, 0x88A5, - 0xD09C, 0x88A6, 0xD09D, 0x88A7, 0xD09E, 0x88A8, 0xD09F, 0x88A9, 0xD0A0, 0x88AA, 0xD0A1, 0x5C0F, 0xD0A2, 0x5B5D, 0xD0A3, 0x6821, - 0xD0A4, 0x8096, 0xD0A5, 0x5578, 0xD0A6, 0x7B11, 0xD0A7, 0x6548, 0xD0A8, 0x6954, 0xD0A9, 0x4E9B, 0xD0AA, 0x6B47, 0xD0AB, 0x874E, - 0xD0AC, 0x978B, 0xD0AD, 0x534F, 0xD0AE, 0x631F, 0xD0AF, 0x643A, 0xD0B0, 0x90AA, 0xD0B1, 0x659C, 0xD0B2, 0x80C1, 0xD0B3, 0x8C10, - 0xD0B4, 0x5199, 0xD0B5, 0x68B0, 0xD0B6, 0x5378, 0xD0B7, 0x87F9, 0xD0B8, 0x61C8, 0xD0B9, 0x6CC4, 0xD0BA, 0x6CFB, 0xD0BB, 0x8C22, - 0xD0BC, 0x5C51, 0xD0BD, 0x85AA, 0xD0BE, 0x82AF, 0xD0BF, 0x950C, 0xD0C0, 0x6B23, 0xD0C1, 0x8F9B, 0xD0C2, 0x65B0, 0xD0C3, 0x5FFB, - 0xD0C4, 0x5FC3, 0xD0C5, 0x4FE1, 0xD0C6, 0x8845, 0xD0C7, 0x661F, 0xD0C8, 0x8165, 0xD0C9, 0x7329, 0xD0CA, 0x60FA, 0xD0CB, 0x5174, - 0xD0CC, 0x5211, 0xD0CD, 0x578B, 0xD0CE, 0x5F62, 0xD0CF, 0x90A2, 0xD0D0, 0x884C, 0xD0D1, 0x9192, 0xD0D2, 0x5E78, 0xD0D3, 0x674F, - 0xD0D4, 0x6027, 0xD0D5, 0x59D3, 0xD0D6, 0x5144, 0xD0D7, 0x51F6, 0xD0D8, 0x80F8, 0xD0D9, 0x5308, 0xD0DA, 0x6C79, 0xD0DB, 0x96C4, - 0xD0DC, 0x718A, 0xD0DD, 0x4F11, 0xD0DE, 0x4FEE, 0xD0DF, 0x7F9E, 0xD0E0, 0x673D, 0xD0E1, 0x55C5, 0xD0E2, 0x9508, 0xD0E3, 0x79C0, - 0xD0E4, 0x8896, 0xD0E5, 0x7EE3, 0xD0E6, 0x589F, 0xD0E7, 0x620C, 0xD0E8, 0x9700, 0xD0E9, 0x865A, 0xD0EA, 0x5618, 0xD0EB, 0x987B, - 0xD0EC, 0x5F90, 0xD0ED, 0x8BB8, 0xD0EE, 0x84C4, 0xD0EF, 0x9157, 0xD0F0, 0x53D9, 0xD0F1, 0x65ED, 0xD0F2, 0x5E8F, 0xD0F3, 0x755C, - 0xD0F4, 0x6064, 0xD0F5, 0x7D6E, 0xD0F6, 0x5A7F, 0xD0F7, 0x7EEA, 0xD0F8, 0x7EED, 0xD0F9, 0x8F69, 0xD0FA, 0x55A7, 0xD0FB, 0x5BA3, - 0xD0FC, 0x60AC, 0xD0FD, 0x65CB, 0xD0FE, 0x7384, 0xD140, 0x88AC, 0xD141, 0x88AE, 0xD142, 0x88AF, 0xD143, 0x88B0, 0xD144, 0x88B2, - 0xD145, 0x88B3, 0xD146, 0x88B4, 0xD147, 0x88B5, 0xD148, 0x88B6, 0xD149, 0x88B8, 0xD14A, 0x88B9, 0xD14B, 0x88BA, 0xD14C, 0x88BB, - 0xD14D, 0x88BD, 0xD14E, 0x88BE, 0xD14F, 0x88BF, 0xD150, 0x88C0, 0xD151, 0x88C3, 0xD152, 0x88C4, 0xD153, 0x88C7, 0xD154, 0x88C8, - 0xD155, 0x88CA, 0xD156, 0x88CB, 0xD157, 0x88CC, 0xD158, 0x88CD, 0xD159, 0x88CF, 0xD15A, 0x88D0, 0xD15B, 0x88D1, 0xD15C, 0x88D3, - 0xD15D, 0x88D6, 0xD15E, 0x88D7, 0xD15F, 0x88DA, 0xD160, 0x88DB, 0xD161, 0x88DC, 0xD162, 0x88DD, 0xD163, 0x88DE, 0xD164, 0x88E0, - 0xD165, 0x88E1, 0xD166, 0x88E6, 0xD167, 0x88E7, 0xD168, 0x88E9, 0xD169, 0x88EA, 0xD16A, 0x88EB, 0xD16B, 0x88EC, 0xD16C, 0x88ED, - 0xD16D, 0x88EE, 0xD16E, 0x88EF, 0xD16F, 0x88F2, 0xD170, 0x88F5, 0xD171, 0x88F6, 0xD172, 0x88F7, 0xD173, 0x88FA, 0xD174, 0x88FB, - 0xD175, 0x88FD, 0xD176, 0x88FF, 0xD177, 0x8900, 0xD178, 0x8901, 0xD179, 0x8903, 0xD17A, 0x8904, 0xD17B, 0x8905, 0xD17C, 0x8906, - 0xD17D, 0x8907, 0xD17E, 0x8908, 0xD180, 0x8909, 0xD181, 0x890B, 0xD182, 0x890C, 0xD183, 0x890D, 0xD184, 0x890E, 0xD185, 0x890F, - 0xD186, 0x8911, 0xD187, 0x8914, 0xD188, 0x8915, 0xD189, 0x8916, 0xD18A, 0x8917, 0xD18B, 0x8918, 0xD18C, 0x891C, 0xD18D, 0x891D, - 0xD18E, 0x891E, 0xD18F, 0x891F, 0xD190, 0x8920, 0xD191, 0x8922, 0xD192, 0x8923, 0xD193, 0x8924, 0xD194, 0x8926, 0xD195, 0x8927, - 0xD196, 0x8928, 0xD197, 0x8929, 0xD198, 0x892C, 0xD199, 0x892D, 0xD19A, 0x892E, 0xD19B, 0x892F, 0xD19C, 0x8931, 0xD19D, 0x8932, - 0xD19E, 0x8933, 0xD19F, 0x8935, 0xD1A0, 0x8937, 0xD1A1, 0x9009, 0xD1A2, 0x7663, 0xD1A3, 0x7729, 0xD1A4, 0x7EDA, 0xD1A5, 0x9774, - 0xD1A6, 0x859B, 0xD1A7, 0x5B66, 0xD1A8, 0x7A74, 0xD1A9, 0x96EA, 0xD1AA, 0x8840, 0xD1AB, 0x52CB, 0xD1AC, 0x718F, 0xD1AD, 0x5FAA, - 0xD1AE, 0x65EC, 0xD1AF, 0x8BE2, 0xD1B0, 0x5BFB, 0xD1B1, 0x9A6F, 0xD1B2, 0x5DE1, 0xD1B3, 0x6B89, 0xD1B4, 0x6C5B, 0xD1B5, 0x8BAD, - 0xD1B6, 0x8BAF, 0xD1B7, 0x900A, 0xD1B8, 0x8FC5, 0xD1B9, 0x538B, 0xD1BA, 0x62BC, 0xD1BB, 0x9E26, 0xD1BC, 0x9E2D, 0xD1BD, 0x5440, - 0xD1BE, 0x4E2B, 0xD1BF, 0x82BD, 0xD1C0, 0x7259, 0xD1C1, 0x869C, 0xD1C2, 0x5D16, 0xD1C3, 0x8859, 0xD1C4, 0x6DAF, 0xD1C5, 0x96C5, - 0xD1C6, 0x54D1, 0xD1C7, 0x4E9A, 0xD1C8, 0x8BB6, 0xD1C9, 0x7109, 0xD1CA, 0x54BD, 0xD1CB, 0x9609, 0xD1CC, 0x70DF, 0xD1CD, 0x6DF9, - 0xD1CE, 0x76D0, 0xD1CF, 0x4E25, 0xD1D0, 0x7814, 0xD1D1, 0x8712, 0xD1D2, 0x5CA9, 0xD1D3, 0x5EF6, 0xD1D4, 0x8A00, 0xD1D5, 0x989C, - 0xD1D6, 0x960E, 0xD1D7, 0x708E, 0xD1D8, 0x6CBF, 0xD1D9, 0x5944, 0xD1DA, 0x63A9, 0xD1DB, 0x773C, 0xD1DC, 0x884D, 0xD1DD, 0x6F14, - 0xD1DE, 0x8273, 0xD1DF, 0x5830, 0xD1E0, 0x71D5, 0xD1E1, 0x538C, 0xD1E2, 0x781A, 0xD1E3, 0x96C1, 0xD1E4, 0x5501, 0xD1E5, 0x5F66, - 0xD1E6, 0x7130, 0xD1E7, 0x5BB4, 0xD1E8, 0x8C1A, 0xD1E9, 0x9A8C, 0xD1EA, 0x6B83, 0xD1EB, 0x592E, 0xD1EC, 0x9E2F, 0xD1ED, 0x79E7, - 0xD1EE, 0x6768, 0xD1EF, 0x626C, 0xD1F0, 0x4F6F, 0xD1F1, 0x75A1, 0xD1F2, 0x7F8A, 0xD1F3, 0x6D0B, 0xD1F4, 0x9633, 0xD1F5, 0x6C27, - 0xD1F6, 0x4EF0, 0xD1F7, 0x75D2, 0xD1F8, 0x517B, 0xD1F9, 0x6837, 0xD1FA, 0x6F3E, 0xD1FB, 0x9080, 0xD1FC, 0x8170, 0xD1FD, 0x5996, - 0xD1FE, 0x7476, 0xD240, 0x8938, 0xD241, 0x8939, 0xD242, 0x893A, 0xD243, 0x893B, 0xD244, 0x893C, 0xD245, 0x893D, 0xD246, 0x893E, - 0xD247, 0x893F, 0xD248, 0x8940, 0xD249, 0x8942, 0xD24A, 0x8943, 0xD24B, 0x8945, 0xD24C, 0x8946, 0xD24D, 0x8947, 0xD24E, 0x8948, - 0xD24F, 0x8949, 0xD250, 0x894A, 0xD251, 0x894B, 0xD252, 0x894C, 0xD253, 0x894D, 0xD254, 0x894E, 0xD255, 0x894F, 0xD256, 0x8950, - 0xD257, 0x8951, 0xD258, 0x8952, 0xD259, 0x8953, 0xD25A, 0x8954, 0xD25B, 0x8955, 0xD25C, 0x8956, 0xD25D, 0x8957, 0xD25E, 0x8958, - 0xD25F, 0x8959, 0xD260, 0x895A, 0xD261, 0x895B, 0xD262, 0x895C, 0xD263, 0x895D, 0xD264, 0x8960, 0xD265, 0x8961, 0xD266, 0x8962, - 0xD267, 0x8963, 0xD268, 0x8964, 0xD269, 0x8965, 0xD26A, 0x8967, 0xD26B, 0x8968, 0xD26C, 0x8969, 0xD26D, 0x896A, 0xD26E, 0x896B, - 0xD26F, 0x896C, 0xD270, 0x896D, 0xD271, 0x896E, 0xD272, 0x896F, 0xD273, 0x8970, 0xD274, 0x8971, 0xD275, 0x8972, 0xD276, 0x8973, - 0xD277, 0x8974, 0xD278, 0x8975, 0xD279, 0x8976, 0xD27A, 0x8977, 0xD27B, 0x8978, 0xD27C, 0x8979, 0xD27D, 0x897A, 0xD27E, 0x897C, - 0xD280, 0x897D, 0xD281, 0x897E, 0xD282, 0x8980, 0xD283, 0x8982, 0xD284, 0x8984, 0xD285, 0x8985, 0xD286, 0x8987, 0xD287, 0x8988, - 0xD288, 0x8989, 0xD289, 0x898A, 0xD28A, 0x898B, 0xD28B, 0x898C, 0xD28C, 0x898D, 0xD28D, 0x898E, 0xD28E, 0x898F, 0xD28F, 0x8990, - 0xD290, 0x8991, 0xD291, 0x8992, 0xD292, 0x8993, 0xD293, 0x8994, 0xD294, 0x8995, 0xD295, 0x8996, 0xD296, 0x8997, 0xD297, 0x8998, - 0xD298, 0x8999, 0xD299, 0x899A, 0xD29A, 0x899B, 0xD29B, 0x899C, 0xD29C, 0x899D, 0xD29D, 0x899E, 0xD29E, 0x899F, 0xD29F, 0x89A0, - 0xD2A0, 0x89A1, 0xD2A1, 0x6447, 0xD2A2, 0x5C27, 0xD2A3, 0x9065, 0xD2A4, 0x7A91, 0xD2A5, 0x8C23, 0xD2A6, 0x59DA, 0xD2A7, 0x54AC, - 0xD2A8, 0x8200, 0xD2A9, 0x836F, 0xD2AA, 0x8981, 0xD2AB, 0x8000, 0xD2AC, 0x6930, 0xD2AD, 0x564E, 0xD2AE, 0x8036, 0xD2AF, 0x7237, - 0xD2B0, 0x91CE, 0xD2B1, 0x51B6, 0xD2B2, 0x4E5F, 0xD2B3, 0x9875, 0xD2B4, 0x6396, 0xD2B5, 0x4E1A, 0xD2B6, 0x53F6, 0xD2B7, 0x66F3, - 0xD2B8, 0x814B, 0xD2B9, 0x591C, 0xD2BA, 0x6DB2, 0xD2BB, 0x4E00, 0xD2BC, 0x58F9, 0xD2BD, 0x533B, 0xD2BE, 0x63D6, 0xD2BF, 0x94F1, - 0xD2C0, 0x4F9D, 0xD2C1, 0x4F0A, 0xD2C2, 0x8863, 0xD2C3, 0x9890, 0xD2C4, 0x5937, 0xD2C5, 0x9057, 0xD2C6, 0x79FB, 0xD2C7, 0x4EEA, - 0xD2C8, 0x80F0, 0xD2C9, 0x7591, 0xD2CA, 0x6C82, 0xD2CB, 0x5B9C, 0xD2CC, 0x59E8, 0xD2CD, 0x5F5D, 0xD2CE, 0x6905, 0xD2CF, 0x8681, - 0xD2D0, 0x501A, 0xD2D1, 0x5DF2, 0xD2D2, 0x4E59, 0xD2D3, 0x77E3, 0xD2D4, 0x4EE5, 0xD2D5, 0x827A, 0xD2D6, 0x6291, 0xD2D7, 0x6613, - 0xD2D8, 0x9091, 0xD2D9, 0x5C79, 0xD2DA, 0x4EBF, 0xD2DB, 0x5F79, 0xD2DC, 0x81C6, 0xD2DD, 0x9038, 0xD2DE, 0x8084, 0xD2DF, 0x75AB, - 0xD2E0, 0x4EA6, 0xD2E1, 0x88D4, 0xD2E2, 0x610F, 0xD2E3, 0x6BC5, 0xD2E4, 0x5FC6, 0xD2E5, 0x4E49, 0xD2E6, 0x76CA, 0xD2E7, 0x6EA2, - 0xD2E8, 0x8BE3, 0xD2E9, 0x8BAE, 0xD2EA, 0x8C0A, 0xD2EB, 0x8BD1, 0xD2EC, 0x5F02, 0xD2ED, 0x7FFC, 0xD2EE, 0x7FCC, 0xD2EF, 0x7ECE, - 0xD2F0, 0x8335, 0xD2F1, 0x836B, 0xD2F2, 0x56E0, 0xD2F3, 0x6BB7, 0xD2F4, 0x97F3, 0xD2F5, 0x9634, 0xD2F6, 0x59FB, 0xD2F7, 0x541F, - 0xD2F8, 0x94F6, 0xD2F9, 0x6DEB, 0xD2FA, 0x5BC5, 0xD2FB, 0x996E, 0xD2FC, 0x5C39, 0xD2FD, 0x5F15, 0xD2FE, 0x9690, 0xD340, 0x89A2, - 0xD341, 0x89A3, 0xD342, 0x89A4, 0xD343, 0x89A5, 0xD344, 0x89A6, 0xD345, 0x89A7, 0xD346, 0x89A8, 0xD347, 0x89A9, 0xD348, 0x89AA, - 0xD349, 0x89AB, 0xD34A, 0x89AC, 0xD34B, 0x89AD, 0xD34C, 0x89AE, 0xD34D, 0x89AF, 0xD34E, 0x89B0, 0xD34F, 0x89B1, 0xD350, 0x89B2, - 0xD351, 0x89B3, 0xD352, 0x89B4, 0xD353, 0x89B5, 0xD354, 0x89B6, 0xD355, 0x89B7, 0xD356, 0x89B8, 0xD357, 0x89B9, 0xD358, 0x89BA, - 0xD359, 0x89BB, 0xD35A, 0x89BC, 0xD35B, 0x89BD, 0xD35C, 0x89BE, 0xD35D, 0x89BF, 0xD35E, 0x89C0, 0xD35F, 0x89C3, 0xD360, 0x89CD, - 0xD361, 0x89D3, 0xD362, 0x89D4, 0xD363, 0x89D5, 0xD364, 0x89D7, 0xD365, 0x89D8, 0xD366, 0x89D9, 0xD367, 0x89DB, 0xD368, 0x89DD, - 0xD369, 0x89DF, 0xD36A, 0x89E0, 0xD36B, 0x89E1, 0xD36C, 0x89E2, 0xD36D, 0x89E4, 0xD36E, 0x89E7, 0xD36F, 0x89E8, 0xD370, 0x89E9, - 0xD371, 0x89EA, 0xD372, 0x89EC, 0xD373, 0x89ED, 0xD374, 0x89EE, 0xD375, 0x89F0, 0xD376, 0x89F1, 0xD377, 0x89F2, 0xD378, 0x89F4, - 0xD379, 0x89F5, 0xD37A, 0x89F6, 0xD37B, 0x89F7, 0xD37C, 0x89F8, 0xD37D, 0x89F9, 0xD37E, 0x89FA, 0xD380, 0x89FB, 0xD381, 0x89FC, - 0xD382, 0x89FD, 0xD383, 0x89FE, 0xD384, 0x89FF, 0xD385, 0x8A01, 0xD386, 0x8A02, 0xD387, 0x8A03, 0xD388, 0x8A04, 0xD389, 0x8A05, - 0xD38A, 0x8A06, 0xD38B, 0x8A08, 0xD38C, 0x8A09, 0xD38D, 0x8A0A, 0xD38E, 0x8A0B, 0xD38F, 0x8A0C, 0xD390, 0x8A0D, 0xD391, 0x8A0E, - 0xD392, 0x8A0F, 0xD393, 0x8A10, 0xD394, 0x8A11, 0xD395, 0x8A12, 0xD396, 0x8A13, 0xD397, 0x8A14, 0xD398, 0x8A15, 0xD399, 0x8A16, - 0xD39A, 0x8A17, 0xD39B, 0x8A18, 0xD39C, 0x8A19, 0xD39D, 0x8A1A, 0xD39E, 0x8A1B, 0xD39F, 0x8A1C, 0xD3A0, 0x8A1D, 0xD3A1, 0x5370, - 0xD3A2, 0x82F1, 0xD3A3, 0x6A31, 0xD3A4, 0x5A74, 0xD3A5, 0x9E70, 0xD3A6, 0x5E94, 0xD3A7, 0x7F28, 0xD3A8, 0x83B9, 0xD3A9, 0x8424, - 0xD3AA, 0x8425, 0xD3AB, 0x8367, 0xD3AC, 0x8747, 0xD3AD, 0x8FCE, 0xD3AE, 0x8D62, 0xD3AF, 0x76C8, 0xD3B0, 0x5F71, 0xD3B1, 0x9896, - 0xD3B2, 0x786C, 0xD3B3, 0x6620, 0xD3B4, 0x54DF, 0xD3B5, 0x62E5, 0xD3B6, 0x4F63, 0xD3B7, 0x81C3, 0xD3B8, 0x75C8, 0xD3B9, 0x5EB8, - 0xD3BA, 0x96CD, 0xD3BB, 0x8E0A, 0xD3BC, 0x86F9, 0xD3BD, 0x548F, 0xD3BE, 0x6CF3, 0xD3BF, 0x6D8C, 0xD3C0, 0x6C38, 0xD3C1, 0x607F, - 0xD3C2, 0x52C7, 0xD3C3, 0x7528, 0xD3C4, 0x5E7D, 0xD3C5, 0x4F18, 0xD3C6, 0x60A0, 0xD3C7, 0x5FE7, 0xD3C8, 0x5C24, 0xD3C9, 0x7531, - 0xD3CA, 0x90AE, 0xD3CB, 0x94C0, 0xD3CC, 0x72B9, 0xD3CD, 0x6CB9, 0xD3CE, 0x6E38, 0xD3CF, 0x9149, 0xD3D0, 0x6709, 0xD3D1, 0x53CB, - 0xD3D2, 0x53F3, 0xD3D3, 0x4F51, 0xD3D4, 0x91C9, 0xD3D5, 0x8BF1, 0xD3D6, 0x53C8, 0xD3D7, 0x5E7C, 0xD3D8, 0x8FC2, 0xD3D9, 0x6DE4, - 0xD3DA, 0x4E8E, 0xD3DB, 0x76C2, 0xD3DC, 0x6986, 0xD3DD, 0x865E, 0xD3DE, 0x611A, 0xD3DF, 0x8206, 0xD3E0, 0x4F59, 0xD3E1, 0x4FDE, - 0xD3E2, 0x903E, 0xD3E3, 0x9C7C, 0xD3E4, 0x6109, 0xD3E5, 0x6E1D, 0xD3E6, 0x6E14, 0xD3E7, 0x9685, 0xD3E8, 0x4E88, 0xD3E9, 0x5A31, - 0xD3EA, 0x96E8, 0xD3EB, 0x4E0E, 0xD3EC, 0x5C7F, 0xD3ED, 0x79B9, 0xD3EE, 0x5B87, 0xD3EF, 0x8BED, 0xD3F0, 0x7FBD, 0xD3F1, 0x7389, - 0xD3F2, 0x57DF, 0xD3F3, 0x828B, 0xD3F4, 0x90C1, 0xD3F5, 0x5401, 0xD3F6, 0x9047, 0xD3F7, 0x55BB, 0xD3F8, 0x5CEA, 0xD3F9, 0x5FA1, - 0xD3FA, 0x6108, 0xD3FB, 0x6B32, 0xD3FC, 0x72F1, 0xD3FD, 0x80B2, 0xD3FE, 0x8A89, 0xD440, 0x8A1E, 0xD441, 0x8A1F, 0xD442, 0x8A20, - 0xD443, 0x8A21, 0xD444, 0x8A22, 0xD445, 0x8A23, 0xD446, 0x8A24, 0xD447, 0x8A25, 0xD448, 0x8A26, 0xD449, 0x8A27, 0xD44A, 0x8A28, - 0xD44B, 0x8A29, 0xD44C, 0x8A2A, 0xD44D, 0x8A2B, 0xD44E, 0x8A2C, 0xD44F, 0x8A2D, 0xD450, 0x8A2E, 0xD451, 0x8A2F, 0xD452, 0x8A30, - 0xD453, 0x8A31, 0xD454, 0x8A32, 0xD455, 0x8A33, 0xD456, 0x8A34, 0xD457, 0x8A35, 0xD458, 0x8A36, 0xD459, 0x8A37, 0xD45A, 0x8A38, - 0xD45B, 0x8A39, 0xD45C, 0x8A3A, 0xD45D, 0x8A3B, 0xD45E, 0x8A3C, 0xD45F, 0x8A3D, 0xD460, 0x8A3F, 0xD461, 0x8A40, 0xD462, 0x8A41, - 0xD463, 0x8A42, 0xD464, 0x8A43, 0xD465, 0x8A44, 0xD466, 0x8A45, 0xD467, 0x8A46, 0xD468, 0x8A47, 0xD469, 0x8A49, 0xD46A, 0x8A4A, - 0xD46B, 0x8A4B, 0xD46C, 0x8A4C, 0xD46D, 0x8A4D, 0xD46E, 0x8A4E, 0xD46F, 0x8A4F, 0xD470, 0x8A50, 0xD471, 0x8A51, 0xD472, 0x8A52, - 0xD473, 0x8A53, 0xD474, 0x8A54, 0xD475, 0x8A55, 0xD476, 0x8A56, 0xD477, 0x8A57, 0xD478, 0x8A58, 0xD479, 0x8A59, 0xD47A, 0x8A5A, - 0xD47B, 0x8A5B, 0xD47C, 0x8A5C, 0xD47D, 0x8A5D, 0xD47E, 0x8A5E, 0xD480, 0x8A5F, 0xD481, 0x8A60, 0xD482, 0x8A61, 0xD483, 0x8A62, - 0xD484, 0x8A63, 0xD485, 0x8A64, 0xD486, 0x8A65, 0xD487, 0x8A66, 0xD488, 0x8A67, 0xD489, 0x8A68, 0xD48A, 0x8A69, 0xD48B, 0x8A6A, - 0xD48C, 0x8A6B, 0xD48D, 0x8A6C, 0xD48E, 0x8A6D, 0xD48F, 0x8A6E, 0xD490, 0x8A6F, 0xD491, 0x8A70, 0xD492, 0x8A71, 0xD493, 0x8A72, - 0xD494, 0x8A73, 0xD495, 0x8A74, 0xD496, 0x8A75, 0xD497, 0x8A76, 0xD498, 0x8A77, 0xD499, 0x8A78, 0xD49A, 0x8A7A, 0xD49B, 0x8A7B, - 0xD49C, 0x8A7C, 0xD49D, 0x8A7D, 0xD49E, 0x8A7E, 0xD49F, 0x8A7F, 0xD4A0, 0x8A80, 0xD4A1, 0x6D74, 0xD4A2, 0x5BD3, 0xD4A3, 0x88D5, - 0xD4A4, 0x9884, 0xD4A5, 0x8C6B, 0xD4A6, 0x9A6D, 0xD4A7, 0x9E33, 0xD4A8, 0x6E0A, 0xD4A9, 0x51A4, 0xD4AA, 0x5143, 0xD4AB, 0x57A3, - 0xD4AC, 0x8881, 0xD4AD, 0x539F, 0xD4AE, 0x63F4, 0xD4AF, 0x8F95, 0xD4B0, 0x56ED, 0xD4B1, 0x5458, 0xD4B2, 0x5706, 0xD4B3, 0x733F, - 0xD4B4, 0x6E90, 0xD4B5, 0x7F18, 0xD4B6, 0x8FDC, 0xD4B7, 0x82D1, 0xD4B8, 0x613F, 0xD4B9, 0x6028, 0xD4BA, 0x9662, 0xD4BB, 0x66F0, - 0xD4BC, 0x7EA6, 0xD4BD, 0x8D8A, 0xD4BE, 0x8DC3, 0xD4BF, 0x94A5, 0xD4C0, 0x5CB3, 0xD4C1, 0x7CA4, 0xD4C2, 0x6708, 0xD4C3, 0x60A6, - 0xD4C4, 0x9605, 0xD4C5, 0x8018, 0xD4C6, 0x4E91, 0xD4C7, 0x90E7, 0xD4C8, 0x5300, 0xD4C9, 0x9668, 0xD4CA, 0x5141, 0xD4CB, 0x8FD0, - 0xD4CC, 0x8574, 0xD4CD, 0x915D, 0xD4CE, 0x6655, 0xD4CF, 0x97F5, 0xD4D0, 0x5B55, 0xD4D1, 0x531D, 0xD4D2, 0x7838, 0xD4D3, 0x6742, - 0xD4D4, 0x683D, 0xD4D5, 0x54C9, 0xD4D6, 0x707E, 0xD4D7, 0x5BB0, 0xD4D8, 0x8F7D, 0xD4D9, 0x518D, 0xD4DA, 0x5728, 0xD4DB, 0x54B1, - 0xD4DC, 0x6512, 0xD4DD, 0x6682, 0xD4DE, 0x8D5E, 0xD4DF, 0x8D43, 0xD4E0, 0x810F, 0xD4E1, 0x846C, 0xD4E2, 0x906D, 0xD4E3, 0x7CDF, - 0xD4E4, 0x51FF, 0xD4E5, 0x85FB, 0xD4E6, 0x67A3, 0xD4E7, 0x65E9, 0xD4E8, 0x6FA1, 0xD4E9, 0x86A4, 0xD4EA, 0x8E81, 0xD4EB, 0x566A, - 0xD4EC, 0x9020, 0xD4ED, 0x7682, 0xD4EE, 0x7076, 0xD4EF, 0x71E5, 0xD4F0, 0x8D23, 0xD4F1, 0x62E9, 0xD4F2, 0x5219, 0xD4F3, 0x6CFD, - 0xD4F4, 0x8D3C, 0xD4F5, 0x600E, 0xD4F6, 0x589E, 0xD4F7, 0x618E, 0xD4F8, 0x66FE, 0xD4F9, 0x8D60, 0xD4FA, 0x624E, 0xD4FB, 0x55B3, - 0xD4FC, 0x6E23, 0xD4FD, 0x672D, 0xD4FE, 0x8F67, 0xD540, 0x8A81, 0xD541, 0x8A82, 0xD542, 0x8A83, 0xD543, 0x8A84, 0xD544, 0x8A85, - 0xD545, 0x8A86, 0xD546, 0x8A87, 0xD547, 0x8A88, 0xD548, 0x8A8B, 0xD549, 0x8A8C, 0xD54A, 0x8A8D, 0xD54B, 0x8A8E, 0xD54C, 0x8A8F, - 0xD54D, 0x8A90, 0xD54E, 0x8A91, 0xD54F, 0x8A92, 0xD550, 0x8A94, 0xD551, 0x8A95, 0xD552, 0x8A96, 0xD553, 0x8A97, 0xD554, 0x8A98, - 0xD555, 0x8A99, 0xD556, 0x8A9A, 0xD557, 0x8A9B, 0xD558, 0x8A9C, 0xD559, 0x8A9D, 0xD55A, 0x8A9E, 0xD55B, 0x8A9F, 0xD55C, 0x8AA0, - 0xD55D, 0x8AA1, 0xD55E, 0x8AA2, 0xD55F, 0x8AA3, 0xD560, 0x8AA4, 0xD561, 0x8AA5, 0xD562, 0x8AA6, 0xD563, 0x8AA7, 0xD564, 0x8AA8, - 0xD565, 0x8AA9, 0xD566, 0x8AAA, 0xD567, 0x8AAB, 0xD568, 0x8AAC, 0xD569, 0x8AAD, 0xD56A, 0x8AAE, 0xD56B, 0x8AAF, 0xD56C, 0x8AB0, - 0xD56D, 0x8AB1, 0xD56E, 0x8AB2, 0xD56F, 0x8AB3, 0xD570, 0x8AB4, 0xD571, 0x8AB5, 0xD572, 0x8AB6, 0xD573, 0x8AB7, 0xD574, 0x8AB8, - 0xD575, 0x8AB9, 0xD576, 0x8ABA, 0xD577, 0x8ABB, 0xD578, 0x8ABC, 0xD579, 0x8ABD, 0xD57A, 0x8ABE, 0xD57B, 0x8ABF, 0xD57C, 0x8AC0, - 0xD57D, 0x8AC1, 0xD57E, 0x8AC2, 0xD580, 0x8AC3, 0xD581, 0x8AC4, 0xD582, 0x8AC5, 0xD583, 0x8AC6, 0xD584, 0x8AC7, 0xD585, 0x8AC8, - 0xD586, 0x8AC9, 0xD587, 0x8ACA, 0xD588, 0x8ACB, 0xD589, 0x8ACC, 0xD58A, 0x8ACD, 0xD58B, 0x8ACE, 0xD58C, 0x8ACF, 0xD58D, 0x8AD0, - 0xD58E, 0x8AD1, 0xD58F, 0x8AD2, 0xD590, 0x8AD3, 0xD591, 0x8AD4, 0xD592, 0x8AD5, 0xD593, 0x8AD6, 0xD594, 0x8AD7, 0xD595, 0x8AD8, - 0xD596, 0x8AD9, 0xD597, 0x8ADA, 0xD598, 0x8ADB, 0xD599, 0x8ADC, 0xD59A, 0x8ADD, 0xD59B, 0x8ADE, 0xD59C, 0x8ADF, 0xD59D, 0x8AE0, - 0xD59E, 0x8AE1, 0xD59F, 0x8AE2, 0xD5A0, 0x8AE3, 0xD5A1, 0x94E1, 0xD5A2, 0x95F8, 0xD5A3, 0x7728, 0xD5A4, 0x6805, 0xD5A5, 0x69A8, - 0xD5A6, 0x548B, 0xD5A7, 0x4E4D, 0xD5A8, 0x70B8, 0xD5A9, 0x8BC8, 0xD5AA, 0x6458, 0xD5AB, 0x658B, 0xD5AC, 0x5B85, 0xD5AD, 0x7A84, - 0xD5AE, 0x503A, 0xD5AF, 0x5BE8, 0xD5B0, 0x77BB, 0xD5B1, 0x6BE1, 0xD5B2, 0x8A79, 0xD5B3, 0x7C98, 0xD5B4, 0x6CBE, 0xD5B5, 0x76CF, - 0xD5B6, 0x65A9, 0xD5B7, 0x8F97, 0xD5B8, 0x5D2D, 0xD5B9, 0x5C55, 0xD5BA, 0x8638, 0xD5BB, 0x6808, 0xD5BC, 0x5360, 0xD5BD, 0x6218, - 0xD5BE, 0x7AD9, 0xD5BF, 0x6E5B, 0xD5C0, 0x7EFD, 0xD5C1, 0x6A1F, 0xD5C2, 0x7AE0, 0xD5C3, 0x5F70, 0xD5C4, 0x6F33, 0xD5C5, 0x5F20, - 0xD5C6, 0x638C, 0xD5C7, 0x6DA8, 0xD5C8, 0x6756, 0xD5C9, 0x4E08, 0xD5CA, 0x5E10, 0xD5CB, 0x8D26, 0xD5CC, 0x4ED7, 0xD5CD, 0x80C0, - 0xD5CE, 0x7634, 0xD5CF, 0x969C, 0xD5D0, 0x62DB, 0xD5D1, 0x662D, 0xD5D2, 0x627E, 0xD5D3, 0x6CBC, 0xD5D4, 0x8D75, 0xD5D5, 0x7167, - 0xD5D6, 0x7F69, 0xD5D7, 0x5146, 0xD5D8, 0x8087, 0xD5D9, 0x53EC, 0xD5DA, 0x906E, 0xD5DB, 0x6298, 0xD5DC, 0x54F2, 0xD5DD, 0x86F0, - 0xD5DE, 0x8F99, 0xD5DF, 0x8005, 0xD5E0, 0x9517, 0xD5E1, 0x8517, 0xD5E2, 0x8FD9, 0xD5E3, 0x6D59, 0xD5E4, 0x73CD, 0xD5E5, 0x659F, - 0xD5E6, 0x771F, 0xD5E7, 0x7504, 0xD5E8, 0x7827, 0xD5E9, 0x81FB, 0xD5EA, 0x8D1E, 0xD5EB, 0x9488, 0xD5EC, 0x4FA6, 0xD5ED, 0x6795, - 0xD5EE, 0x75B9, 0xD5EF, 0x8BCA, 0xD5F0, 0x9707, 0xD5F1, 0x632F, 0xD5F2, 0x9547, 0xD5F3, 0x9635, 0xD5F4, 0x84B8, 0xD5F5, 0x6323, - 0xD5F6, 0x7741, 0xD5F7, 0x5F81, 0xD5F8, 0x72F0, 0xD5F9, 0x4E89, 0xD5FA, 0x6014, 0xD5FB, 0x6574, 0xD5FC, 0x62EF, 0xD5FD, 0x6B63, - 0xD5FE, 0x653F, 0xD640, 0x8AE4, 0xD641, 0x8AE5, 0xD642, 0x8AE6, 0xD643, 0x8AE7, 0xD644, 0x8AE8, 0xD645, 0x8AE9, 0xD646, 0x8AEA, - 0xD647, 0x8AEB, 0xD648, 0x8AEC, 0xD649, 0x8AED, 0xD64A, 0x8AEE, 0xD64B, 0x8AEF, 0xD64C, 0x8AF0, 0xD64D, 0x8AF1, 0xD64E, 0x8AF2, - 0xD64F, 0x8AF3, 0xD650, 0x8AF4, 0xD651, 0x8AF5, 0xD652, 0x8AF6, 0xD653, 0x8AF7, 0xD654, 0x8AF8, 0xD655, 0x8AF9, 0xD656, 0x8AFA, - 0xD657, 0x8AFB, 0xD658, 0x8AFC, 0xD659, 0x8AFD, 0xD65A, 0x8AFE, 0xD65B, 0x8AFF, 0xD65C, 0x8B00, 0xD65D, 0x8B01, 0xD65E, 0x8B02, - 0xD65F, 0x8B03, 0xD660, 0x8B04, 0xD661, 0x8B05, 0xD662, 0x8B06, 0xD663, 0x8B08, 0xD664, 0x8B09, 0xD665, 0x8B0A, 0xD666, 0x8B0B, - 0xD667, 0x8B0C, 0xD668, 0x8B0D, 0xD669, 0x8B0E, 0xD66A, 0x8B0F, 0xD66B, 0x8B10, 0xD66C, 0x8B11, 0xD66D, 0x8B12, 0xD66E, 0x8B13, - 0xD66F, 0x8B14, 0xD670, 0x8B15, 0xD671, 0x8B16, 0xD672, 0x8B17, 0xD673, 0x8B18, 0xD674, 0x8B19, 0xD675, 0x8B1A, 0xD676, 0x8B1B, - 0xD677, 0x8B1C, 0xD678, 0x8B1D, 0xD679, 0x8B1E, 0xD67A, 0x8B1F, 0xD67B, 0x8B20, 0xD67C, 0x8B21, 0xD67D, 0x8B22, 0xD67E, 0x8B23, - 0xD680, 0x8B24, 0xD681, 0x8B25, 0xD682, 0x8B27, 0xD683, 0x8B28, 0xD684, 0x8B29, 0xD685, 0x8B2A, 0xD686, 0x8B2B, 0xD687, 0x8B2C, - 0xD688, 0x8B2D, 0xD689, 0x8B2E, 0xD68A, 0x8B2F, 0xD68B, 0x8B30, 0xD68C, 0x8B31, 0xD68D, 0x8B32, 0xD68E, 0x8B33, 0xD68F, 0x8B34, - 0xD690, 0x8B35, 0xD691, 0x8B36, 0xD692, 0x8B37, 0xD693, 0x8B38, 0xD694, 0x8B39, 0xD695, 0x8B3A, 0xD696, 0x8B3B, 0xD697, 0x8B3C, - 0xD698, 0x8B3D, 0xD699, 0x8B3E, 0xD69A, 0x8B3F, 0xD69B, 0x8B40, 0xD69C, 0x8B41, 0xD69D, 0x8B42, 0xD69E, 0x8B43, 0xD69F, 0x8B44, - 0xD6A0, 0x8B45, 0xD6A1, 0x5E27, 0xD6A2, 0x75C7, 0xD6A3, 0x90D1, 0xD6A4, 0x8BC1, 0xD6A5, 0x829D, 0xD6A6, 0x679D, 0xD6A7, 0x652F, - 0xD6A8, 0x5431, 0xD6A9, 0x8718, 0xD6AA, 0x77E5, 0xD6AB, 0x80A2, 0xD6AC, 0x8102, 0xD6AD, 0x6C41, 0xD6AE, 0x4E4B, 0xD6AF, 0x7EC7, - 0xD6B0, 0x804C, 0xD6B1, 0x76F4, 0xD6B2, 0x690D, 0xD6B3, 0x6B96, 0xD6B4, 0x6267, 0xD6B5, 0x503C, 0xD6B6, 0x4F84, 0xD6B7, 0x5740, - 0xD6B8, 0x6307, 0xD6B9, 0x6B62, 0xD6BA, 0x8DBE, 0xD6BB, 0x53EA, 0xD6BC, 0x65E8, 0xD6BD, 0x7EB8, 0xD6BE, 0x5FD7, 0xD6BF, 0x631A, - 0xD6C0, 0x63B7, 0xD6C1, 0x81F3, 0xD6C2, 0x81F4, 0xD6C3, 0x7F6E, 0xD6C4, 0x5E1C, 0xD6C5, 0x5CD9, 0xD6C6, 0x5236, 0xD6C7, 0x667A, - 0xD6C8, 0x79E9, 0xD6C9, 0x7A1A, 0xD6CA, 0x8D28, 0xD6CB, 0x7099, 0xD6CC, 0x75D4, 0xD6CD, 0x6EDE, 0xD6CE, 0x6CBB, 0xD6CF, 0x7A92, - 0xD6D0, 0x4E2D, 0xD6D1, 0x76C5, 0xD6D2, 0x5FE0, 0xD6D3, 0x949F, 0xD6D4, 0x8877, 0xD6D5, 0x7EC8, 0xD6D6, 0x79CD, 0xD6D7, 0x80BF, - 0xD6D8, 0x91CD, 0xD6D9, 0x4EF2, 0xD6DA, 0x4F17, 0xD6DB, 0x821F, 0xD6DC, 0x5468, 0xD6DD, 0x5DDE, 0xD6DE, 0x6D32, 0xD6DF, 0x8BCC, - 0xD6E0, 0x7CA5, 0xD6E1, 0x8F74, 0xD6E2, 0x8098, 0xD6E3, 0x5E1A, 0xD6E4, 0x5492, 0xD6E5, 0x76B1, 0xD6E6, 0x5B99, 0xD6E7, 0x663C, - 0xD6E8, 0x9AA4, 0xD6E9, 0x73E0, 0xD6EA, 0x682A, 0xD6EB, 0x86DB, 0xD6EC, 0x6731, 0xD6ED, 0x732A, 0xD6EE, 0x8BF8, 0xD6EF, 0x8BDB, - 0xD6F0, 0x9010, 0xD6F1, 0x7AF9, 0xD6F2, 0x70DB, 0xD6F3, 0x716E, 0xD6F4, 0x62C4, 0xD6F5, 0x77A9, 0xD6F6, 0x5631, 0xD6F7, 0x4E3B, - 0xD6F8, 0x8457, 0xD6F9, 0x67F1, 0xD6FA, 0x52A9, 0xD6FB, 0x86C0, 0xD6FC, 0x8D2E, 0xD6FD, 0x94F8, 0xD6FE, 0x7B51, 0xD740, 0x8B46, - 0xD741, 0x8B47, 0xD742, 0x8B48, 0xD743, 0x8B49, 0xD744, 0x8B4A, 0xD745, 0x8B4B, 0xD746, 0x8B4C, 0xD747, 0x8B4D, 0xD748, 0x8B4E, - 0xD749, 0x8B4F, 0xD74A, 0x8B50, 0xD74B, 0x8B51, 0xD74C, 0x8B52, 0xD74D, 0x8B53, 0xD74E, 0x8B54, 0xD74F, 0x8B55, 0xD750, 0x8B56, - 0xD751, 0x8B57, 0xD752, 0x8B58, 0xD753, 0x8B59, 0xD754, 0x8B5A, 0xD755, 0x8B5B, 0xD756, 0x8B5C, 0xD757, 0x8B5D, 0xD758, 0x8B5E, - 0xD759, 0x8B5F, 0xD75A, 0x8B60, 0xD75B, 0x8B61, 0xD75C, 0x8B62, 0xD75D, 0x8B63, 0xD75E, 0x8B64, 0xD75F, 0x8B65, 0xD760, 0x8B67, - 0xD761, 0x8B68, 0xD762, 0x8B69, 0xD763, 0x8B6A, 0xD764, 0x8B6B, 0xD765, 0x8B6D, 0xD766, 0x8B6E, 0xD767, 0x8B6F, 0xD768, 0x8B70, - 0xD769, 0x8B71, 0xD76A, 0x8B72, 0xD76B, 0x8B73, 0xD76C, 0x8B74, 0xD76D, 0x8B75, 0xD76E, 0x8B76, 0xD76F, 0x8B77, 0xD770, 0x8B78, - 0xD771, 0x8B79, 0xD772, 0x8B7A, 0xD773, 0x8B7B, 0xD774, 0x8B7C, 0xD775, 0x8B7D, 0xD776, 0x8B7E, 0xD777, 0x8B7F, 0xD778, 0x8B80, - 0xD779, 0x8B81, 0xD77A, 0x8B82, 0xD77B, 0x8B83, 0xD77C, 0x8B84, 0xD77D, 0x8B85, 0xD77E, 0x8B86, 0xD780, 0x8B87, 0xD781, 0x8B88, - 0xD782, 0x8B89, 0xD783, 0x8B8A, 0xD784, 0x8B8B, 0xD785, 0x8B8C, 0xD786, 0x8B8D, 0xD787, 0x8B8E, 0xD788, 0x8B8F, 0xD789, 0x8B90, - 0xD78A, 0x8B91, 0xD78B, 0x8B92, 0xD78C, 0x8B93, 0xD78D, 0x8B94, 0xD78E, 0x8B95, 0xD78F, 0x8B96, 0xD790, 0x8B97, 0xD791, 0x8B98, - 0xD792, 0x8B99, 0xD793, 0x8B9A, 0xD794, 0x8B9B, 0xD795, 0x8B9C, 0xD796, 0x8B9D, 0xD797, 0x8B9E, 0xD798, 0x8B9F, 0xD799, 0x8BAC, - 0xD79A, 0x8BB1, 0xD79B, 0x8BBB, 0xD79C, 0x8BC7, 0xD79D, 0x8BD0, 0xD79E, 0x8BEA, 0xD79F, 0x8C09, 0xD7A0, 0x8C1E, 0xD7A1, 0x4F4F, - 0xD7A2, 0x6CE8, 0xD7A3, 0x795D, 0xD7A4, 0x9A7B, 0xD7A5, 0x6293, 0xD7A6, 0x722A, 0xD7A7, 0x62FD, 0xD7A8, 0x4E13, 0xD7A9, 0x7816, - 0xD7AA, 0x8F6C, 0xD7AB, 0x64B0, 0xD7AC, 0x8D5A, 0xD7AD, 0x7BC6, 0xD7AE, 0x6869, 0xD7AF, 0x5E84, 0xD7B0, 0x88C5, 0xD7B1, 0x5986, - 0xD7B2, 0x649E, 0xD7B3, 0x58EE, 0xD7B4, 0x72B6, 0xD7B5, 0x690E, 0xD7B6, 0x9525, 0xD7B7, 0x8FFD, 0xD7B8, 0x8D58, 0xD7B9, 0x5760, - 0xD7BA, 0x7F00, 0xD7BB, 0x8C06, 0xD7BC, 0x51C6, 0xD7BD, 0x6349, 0xD7BE, 0x62D9, 0xD7BF, 0x5353, 0xD7C0, 0x684C, 0xD7C1, 0x7422, - 0xD7C2, 0x8301, 0xD7C3, 0x914C, 0xD7C4, 0x5544, 0xD7C5, 0x7740, 0xD7C6, 0x707C, 0xD7C7, 0x6D4A, 0xD7C8, 0x5179, 0xD7C9, 0x54A8, - 0xD7CA, 0x8D44, 0xD7CB, 0x59FF, 0xD7CC, 0x6ECB, 0xD7CD, 0x6DC4, 0xD7CE, 0x5B5C, 0xD7CF, 0x7D2B, 0xD7D0, 0x4ED4, 0xD7D1, 0x7C7D, - 0xD7D2, 0x6ED3, 0xD7D3, 0x5B50, 0xD7D4, 0x81EA, 0xD7D5, 0x6E0D, 0xD7D6, 0x5B57, 0xD7D7, 0x9B03, 0xD7D8, 0x68D5, 0xD7D9, 0x8E2A, - 0xD7DA, 0x5B97, 0xD7DB, 0x7EFC, 0xD7DC, 0x603B, 0xD7DD, 0x7EB5, 0xD7DE, 0x90B9, 0xD7DF, 0x8D70, 0xD7E0, 0x594F, 0xD7E1, 0x63CD, - 0xD7E2, 0x79DF, 0xD7E3, 0x8DB3, 0xD7E4, 0x5352, 0xD7E5, 0x65CF, 0xD7E6, 0x7956, 0xD7E7, 0x8BC5, 0xD7E8, 0x963B, 0xD7E9, 0x7EC4, - 0xD7EA, 0x94BB, 0xD7EB, 0x7E82, 0xD7EC, 0x5634, 0xD7ED, 0x9189, 0xD7EE, 0x6700, 0xD7EF, 0x7F6A, 0xD7F0, 0x5C0A, 0xD7F1, 0x9075, - 0xD7F2, 0x6628, 0xD7F3, 0x5DE6, 0xD7F4, 0x4F50, 0xD7F5, 0x67DE, 0xD7F6, 0x505A, 0xD7F7, 0x4F5C, 0xD7F8, 0x5750, 0xD7F9, 0x5EA7, - 0xD840, 0x8C38, 0xD841, 0x8C39, 0xD842, 0x8C3A, 0xD843, 0x8C3B, 0xD844, 0x8C3C, 0xD845, 0x8C3D, 0xD846, 0x8C3E, 0xD847, 0x8C3F, - 0xD848, 0x8C40, 0xD849, 0x8C42, 0xD84A, 0x8C43, 0xD84B, 0x8C44, 0xD84C, 0x8C45, 0xD84D, 0x8C48, 0xD84E, 0x8C4A, 0xD84F, 0x8C4B, - 0xD850, 0x8C4D, 0xD851, 0x8C4E, 0xD852, 0x8C4F, 0xD853, 0x8C50, 0xD854, 0x8C51, 0xD855, 0x8C52, 0xD856, 0x8C53, 0xD857, 0x8C54, - 0xD858, 0x8C56, 0xD859, 0x8C57, 0xD85A, 0x8C58, 0xD85B, 0x8C59, 0xD85C, 0x8C5B, 0xD85D, 0x8C5C, 0xD85E, 0x8C5D, 0xD85F, 0x8C5E, - 0xD860, 0x8C5F, 0xD861, 0x8C60, 0xD862, 0x8C63, 0xD863, 0x8C64, 0xD864, 0x8C65, 0xD865, 0x8C66, 0xD866, 0x8C67, 0xD867, 0x8C68, - 0xD868, 0x8C69, 0xD869, 0x8C6C, 0xD86A, 0x8C6D, 0xD86B, 0x8C6E, 0xD86C, 0x8C6F, 0xD86D, 0x8C70, 0xD86E, 0x8C71, 0xD86F, 0x8C72, - 0xD870, 0x8C74, 0xD871, 0x8C75, 0xD872, 0x8C76, 0xD873, 0x8C77, 0xD874, 0x8C7B, 0xD875, 0x8C7C, 0xD876, 0x8C7D, 0xD877, 0x8C7E, - 0xD878, 0x8C7F, 0xD879, 0x8C80, 0xD87A, 0x8C81, 0xD87B, 0x8C83, 0xD87C, 0x8C84, 0xD87D, 0x8C86, 0xD87E, 0x8C87, 0xD880, 0x8C88, - 0xD881, 0x8C8B, 0xD882, 0x8C8D, 0xD883, 0x8C8E, 0xD884, 0x8C8F, 0xD885, 0x8C90, 0xD886, 0x8C91, 0xD887, 0x8C92, 0xD888, 0x8C93, - 0xD889, 0x8C95, 0xD88A, 0x8C96, 0xD88B, 0x8C97, 0xD88C, 0x8C99, 0xD88D, 0x8C9A, 0xD88E, 0x8C9B, 0xD88F, 0x8C9C, 0xD890, 0x8C9D, - 0xD891, 0x8C9E, 0xD892, 0x8C9F, 0xD893, 0x8CA0, 0xD894, 0x8CA1, 0xD895, 0x8CA2, 0xD896, 0x8CA3, 0xD897, 0x8CA4, 0xD898, 0x8CA5, - 0xD899, 0x8CA6, 0xD89A, 0x8CA7, 0xD89B, 0x8CA8, 0xD89C, 0x8CA9, 0xD89D, 0x8CAA, 0xD89E, 0x8CAB, 0xD89F, 0x8CAC, 0xD8A0, 0x8CAD, - 0xD8A1, 0x4E8D, 0xD8A2, 0x4E0C, 0xD8A3, 0x5140, 0xD8A4, 0x4E10, 0xD8A5, 0x5EFF, 0xD8A6, 0x5345, 0xD8A7, 0x4E15, 0xD8A8, 0x4E98, - 0xD8A9, 0x4E1E, 0xD8AA, 0x9B32, 0xD8AB, 0x5B6C, 0xD8AC, 0x5669, 0xD8AD, 0x4E28, 0xD8AE, 0x79BA, 0xD8AF, 0x4E3F, 0xD8B0, 0x5315, - 0xD8B1, 0x4E47, 0xD8B2, 0x592D, 0xD8B3, 0x723B, 0xD8B4, 0x536E, 0xD8B5, 0x6C10, 0xD8B6, 0x56DF, 0xD8B7, 0x80E4, 0xD8B8, 0x9997, - 0xD8B9, 0x6BD3, 0xD8BA, 0x777E, 0xD8BB, 0x9F17, 0xD8BC, 0x4E36, 0xD8BD, 0x4E9F, 0xD8BE, 0x9F10, 0xD8BF, 0x4E5C, 0xD8C0, 0x4E69, - 0xD8C1, 0x4E93, 0xD8C2, 0x8288, 0xD8C3, 0x5B5B, 0xD8C4, 0x556C, 0xD8C5, 0x560F, 0xD8C6, 0x4EC4, 0xD8C7, 0x538D, 0xD8C8, 0x539D, - 0xD8C9, 0x53A3, 0xD8CA, 0x53A5, 0xD8CB, 0x53AE, 0xD8CC, 0x9765, 0xD8CD, 0x8D5D, 0xD8CE, 0x531A, 0xD8CF, 0x53F5, 0xD8D0, 0x5326, - 0xD8D1, 0x532E, 0xD8D2, 0x533E, 0xD8D3, 0x8D5C, 0xD8D4, 0x5366, 0xD8D5, 0x5363, 0xD8D6, 0x5202, 0xD8D7, 0x5208, 0xD8D8, 0x520E, - 0xD8D9, 0x522D, 0xD8DA, 0x5233, 0xD8DB, 0x523F, 0xD8DC, 0x5240, 0xD8DD, 0x524C, 0xD8DE, 0x525E, 0xD8DF, 0x5261, 0xD8E0, 0x525C, - 0xD8E1, 0x84AF, 0xD8E2, 0x527D, 0xD8E3, 0x5282, 0xD8E4, 0x5281, 0xD8E5, 0x5290, 0xD8E6, 0x5293, 0xD8E7, 0x5182, 0xD8E8, 0x7F54, - 0xD8E9, 0x4EBB, 0xD8EA, 0x4EC3, 0xD8EB, 0x4EC9, 0xD8EC, 0x4EC2, 0xD8ED, 0x4EE8, 0xD8EE, 0x4EE1, 0xD8EF, 0x4EEB, 0xD8F0, 0x4EDE, - 0xD8F1, 0x4F1B, 0xD8F2, 0x4EF3, 0xD8F3, 0x4F22, 0xD8F4, 0x4F64, 0xD8F5, 0x4EF5, 0xD8F6, 0x4F25, 0xD8F7, 0x4F27, 0xD8F8, 0x4F09, - 0xD8F9, 0x4F2B, 0xD8FA, 0x4F5E, 0xD8FB, 0x4F67, 0xD8FC, 0x6538, 0xD8FD, 0x4F5A, 0xD8FE, 0x4F5D, 0xD940, 0x8CAE, 0xD941, 0x8CAF, - 0xD942, 0x8CB0, 0xD943, 0x8CB1, 0xD944, 0x8CB2, 0xD945, 0x8CB3, 0xD946, 0x8CB4, 0xD947, 0x8CB5, 0xD948, 0x8CB6, 0xD949, 0x8CB7, - 0xD94A, 0x8CB8, 0xD94B, 0x8CB9, 0xD94C, 0x8CBA, 0xD94D, 0x8CBB, 0xD94E, 0x8CBC, 0xD94F, 0x8CBD, 0xD950, 0x8CBE, 0xD951, 0x8CBF, - 0xD952, 0x8CC0, 0xD953, 0x8CC1, 0xD954, 0x8CC2, 0xD955, 0x8CC3, 0xD956, 0x8CC4, 0xD957, 0x8CC5, 0xD958, 0x8CC6, 0xD959, 0x8CC7, - 0xD95A, 0x8CC8, 0xD95B, 0x8CC9, 0xD95C, 0x8CCA, 0xD95D, 0x8CCB, 0xD95E, 0x8CCC, 0xD95F, 0x8CCD, 0xD960, 0x8CCE, 0xD961, 0x8CCF, - 0xD962, 0x8CD0, 0xD963, 0x8CD1, 0xD964, 0x8CD2, 0xD965, 0x8CD3, 0xD966, 0x8CD4, 0xD967, 0x8CD5, 0xD968, 0x8CD6, 0xD969, 0x8CD7, - 0xD96A, 0x8CD8, 0xD96B, 0x8CD9, 0xD96C, 0x8CDA, 0xD96D, 0x8CDB, 0xD96E, 0x8CDC, 0xD96F, 0x8CDD, 0xD970, 0x8CDE, 0xD971, 0x8CDF, - 0xD972, 0x8CE0, 0xD973, 0x8CE1, 0xD974, 0x8CE2, 0xD975, 0x8CE3, 0xD976, 0x8CE4, 0xD977, 0x8CE5, 0xD978, 0x8CE6, 0xD979, 0x8CE7, - 0xD97A, 0x8CE8, 0xD97B, 0x8CE9, 0xD97C, 0x8CEA, 0xD97D, 0x8CEB, 0xD97E, 0x8CEC, 0xD980, 0x8CED, 0xD981, 0x8CEE, 0xD982, 0x8CEF, - 0xD983, 0x8CF0, 0xD984, 0x8CF1, 0xD985, 0x8CF2, 0xD986, 0x8CF3, 0xD987, 0x8CF4, 0xD988, 0x8CF5, 0xD989, 0x8CF6, 0xD98A, 0x8CF7, - 0xD98B, 0x8CF8, 0xD98C, 0x8CF9, 0xD98D, 0x8CFA, 0xD98E, 0x8CFB, 0xD98F, 0x8CFC, 0xD990, 0x8CFD, 0xD991, 0x8CFE, 0xD992, 0x8CFF, - 0xD993, 0x8D00, 0xD994, 0x8D01, 0xD995, 0x8D02, 0xD996, 0x8D03, 0xD997, 0x8D04, 0xD998, 0x8D05, 0xD999, 0x8D06, 0xD99A, 0x8D07, - 0xD99B, 0x8D08, 0xD99C, 0x8D09, 0xD99D, 0x8D0A, 0xD99E, 0x8D0B, 0xD99F, 0x8D0C, 0xD9A0, 0x8D0D, 0xD9A1, 0x4F5F, 0xD9A2, 0x4F57, - 0xD9A3, 0x4F32, 0xD9A4, 0x4F3D, 0xD9A5, 0x4F76, 0xD9A6, 0x4F74, 0xD9A7, 0x4F91, 0xD9A8, 0x4F89, 0xD9A9, 0x4F83, 0xD9AA, 0x4F8F, - 0xD9AB, 0x4F7E, 0xD9AC, 0x4F7B, 0xD9AD, 0x4FAA, 0xD9AE, 0x4F7C, 0xD9AF, 0x4FAC, 0xD9B0, 0x4F94, 0xD9B1, 0x4FE6, 0xD9B2, 0x4FE8, - 0xD9B3, 0x4FEA, 0xD9B4, 0x4FC5, 0xD9B5, 0x4FDA, 0xD9B6, 0x4FE3, 0xD9B7, 0x4FDC, 0xD9B8, 0x4FD1, 0xD9B9, 0x4FDF, 0xD9BA, 0x4FF8, - 0xD9BB, 0x5029, 0xD9BC, 0x504C, 0xD9BD, 0x4FF3, 0xD9BE, 0x502C, 0xD9BF, 0x500F, 0xD9C0, 0x502E, 0xD9C1, 0x502D, 0xD9C2, 0x4FFE, - 0xD9C3, 0x501C, 0xD9C4, 0x500C, 0xD9C5, 0x5025, 0xD9C6, 0x5028, 0xD9C7, 0x507E, 0xD9C8, 0x5043, 0xD9C9, 0x5055, 0xD9CA, 0x5048, - 0xD9CB, 0x504E, 0xD9CC, 0x506C, 0xD9CD, 0x507B, 0xD9CE, 0x50A5, 0xD9CF, 0x50A7, 0xD9D0, 0x50A9, 0xD9D1, 0x50BA, 0xD9D2, 0x50D6, - 0xD9D3, 0x5106, 0xD9D4, 0x50ED, 0xD9D5, 0x50EC, 0xD9D6, 0x50E6, 0xD9D7, 0x50EE, 0xD9D8, 0x5107, 0xD9D9, 0x510B, 0xD9DA, 0x4EDD, - 0xD9DB, 0x6C3D, 0xD9DC, 0x4F58, 0xD9DD, 0x4F65, 0xD9DE, 0x4FCE, 0xD9DF, 0x9FA0, 0xD9E0, 0x6C46, 0xD9E1, 0x7C74, 0xD9E2, 0x516E, - 0xD9E3, 0x5DFD, 0xD9E4, 0x9EC9, 0xD9E5, 0x9998, 0xD9E6, 0x5181, 0xD9E7, 0x5914, 0xD9E8, 0x52F9, 0xD9E9, 0x530D, 0xD9EA, 0x8A07, - 0xD9EB, 0x5310, 0xD9EC, 0x51EB, 0xD9ED, 0x5919, 0xD9EE, 0x5155, 0xD9EF, 0x4EA0, 0xD9F0, 0x5156, 0xD9F1, 0x4EB3, 0xD9F2, 0x886E, - 0xD9F3, 0x88A4, 0xD9F4, 0x4EB5, 0xD9F5, 0x8114, 0xD9F6, 0x88D2, 0xD9F7, 0x7980, 0xD9F8, 0x5B34, 0xD9F9, 0x8803, 0xD9FA, 0x7FB8, - 0xD9FB, 0x51AB, 0xD9FC, 0x51B1, 0xD9FD, 0x51BD, 0xD9FE, 0x51BC, 0xDA40, 0x8D0E, 0xDA41, 0x8D0F, 0xDA42, 0x8D10, 0xDA43, 0x8D11, - 0xDA44, 0x8D12, 0xDA45, 0x8D13, 0xDA46, 0x8D14, 0xDA47, 0x8D15, 0xDA48, 0x8D16, 0xDA49, 0x8D17, 0xDA4A, 0x8D18, 0xDA4B, 0x8D19, - 0xDA4C, 0x8D1A, 0xDA4D, 0x8D1B, 0xDA4E, 0x8D1C, 0xDA4F, 0x8D20, 0xDA50, 0x8D51, 0xDA51, 0x8D52, 0xDA52, 0x8D57, 0xDA53, 0x8D5F, - 0xDA54, 0x8D65, 0xDA55, 0x8D68, 0xDA56, 0x8D69, 0xDA57, 0x8D6A, 0xDA58, 0x8D6C, 0xDA59, 0x8D6E, 0xDA5A, 0x8D6F, 0xDA5B, 0x8D71, - 0xDA5C, 0x8D72, 0xDA5D, 0x8D78, 0xDA5E, 0x8D79, 0xDA5F, 0x8D7A, 0xDA60, 0x8D7B, 0xDA61, 0x8D7C, 0xDA62, 0x8D7D, 0xDA63, 0x8D7E, - 0xDA64, 0x8D7F, 0xDA65, 0x8D80, 0xDA66, 0x8D82, 0xDA67, 0x8D83, 0xDA68, 0x8D86, 0xDA69, 0x8D87, 0xDA6A, 0x8D88, 0xDA6B, 0x8D89, - 0xDA6C, 0x8D8C, 0xDA6D, 0x8D8D, 0xDA6E, 0x8D8E, 0xDA6F, 0x8D8F, 0xDA70, 0x8D90, 0xDA71, 0x8D92, 0xDA72, 0x8D93, 0xDA73, 0x8D95, - 0xDA74, 0x8D96, 0xDA75, 0x8D97, 0xDA76, 0x8D98, 0xDA77, 0x8D99, 0xDA78, 0x8D9A, 0xDA79, 0x8D9B, 0xDA7A, 0x8D9C, 0xDA7B, 0x8D9D, - 0xDA7C, 0x8D9E, 0xDA7D, 0x8DA0, 0xDA7E, 0x8DA1, 0xDA80, 0x8DA2, 0xDA81, 0x8DA4, 0xDA82, 0x8DA5, 0xDA83, 0x8DA6, 0xDA84, 0x8DA7, - 0xDA85, 0x8DA8, 0xDA86, 0x8DA9, 0xDA87, 0x8DAA, 0xDA88, 0x8DAB, 0xDA89, 0x8DAC, 0xDA8A, 0x8DAD, 0xDA8B, 0x8DAE, 0xDA8C, 0x8DAF, - 0xDA8D, 0x8DB0, 0xDA8E, 0x8DB2, 0xDA8F, 0x8DB6, 0xDA90, 0x8DB7, 0xDA91, 0x8DB9, 0xDA92, 0x8DBB, 0xDA93, 0x8DBD, 0xDA94, 0x8DC0, - 0xDA95, 0x8DC1, 0xDA96, 0x8DC2, 0xDA97, 0x8DC5, 0xDA98, 0x8DC7, 0xDA99, 0x8DC8, 0xDA9A, 0x8DC9, 0xDA9B, 0x8DCA, 0xDA9C, 0x8DCD, - 0xDA9D, 0x8DD0, 0xDA9E, 0x8DD2, 0xDA9F, 0x8DD3, 0xDAA0, 0x8DD4, 0xDAA1, 0x51C7, 0xDAA2, 0x5196, 0xDAA3, 0x51A2, 0xDAA4, 0x51A5, - 0xDAA5, 0x8BA0, 0xDAA6, 0x8BA6, 0xDAA7, 0x8BA7, 0xDAA8, 0x8BAA, 0xDAA9, 0x8BB4, 0xDAAA, 0x8BB5, 0xDAAB, 0x8BB7, 0xDAAC, 0x8BC2, - 0xDAAD, 0x8BC3, 0xDAAE, 0x8BCB, 0xDAAF, 0x8BCF, 0xDAB0, 0x8BCE, 0xDAB1, 0x8BD2, 0xDAB2, 0x8BD3, 0xDAB3, 0x8BD4, 0xDAB4, 0x8BD6, - 0xDAB5, 0x8BD8, 0xDAB6, 0x8BD9, 0xDAB7, 0x8BDC, 0xDAB8, 0x8BDF, 0xDAB9, 0x8BE0, 0xDABA, 0x8BE4, 0xDABB, 0x8BE8, 0xDABC, 0x8BE9, - 0xDABD, 0x8BEE, 0xDABE, 0x8BF0, 0xDABF, 0x8BF3, 0xDAC0, 0x8BF6, 0xDAC1, 0x8BF9, 0xDAC2, 0x8BFC, 0xDAC3, 0x8BFF, 0xDAC4, 0x8C00, - 0xDAC5, 0x8C02, 0xDAC6, 0x8C04, 0xDAC7, 0x8C07, 0xDAC8, 0x8C0C, 0xDAC9, 0x8C0F, 0xDACA, 0x8C11, 0xDACB, 0x8C12, 0xDACC, 0x8C14, - 0xDACD, 0x8C15, 0xDACE, 0x8C16, 0xDACF, 0x8C19, 0xDAD0, 0x8C1B, 0xDAD1, 0x8C18, 0xDAD2, 0x8C1D, 0xDAD3, 0x8C1F, 0xDAD4, 0x8C20, - 0xDAD5, 0x8C21, 0xDAD6, 0x8C25, 0xDAD7, 0x8C27, 0xDAD8, 0x8C2A, 0xDAD9, 0x8C2B, 0xDADA, 0x8C2E, 0xDADB, 0x8C2F, 0xDADC, 0x8C32, - 0xDADD, 0x8C33, 0xDADE, 0x8C35, 0xDADF, 0x8C36, 0xDAE0, 0x5369, 0xDAE1, 0x537A, 0xDAE2, 0x961D, 0xDAE3, 0x9622, 0xDAE4, 0x9621, - 0xDAE5, 0x9631, 0xDAE6, 0x962A, 0xDAE7, 0x963D, 0xDAE8, 0x963C, 0xDAE9, 0x9642, 0xDAEA, 0x9649, 0xDAEB, 0x9654, 0xDAEC, 0x965F, - 0xDAED, 0x9667, 0xDAEE, 0x966C, 0xDAEF, 0x9672, 0xDAF0, 0x9674, 0xDAF1, 0x9688, 0xDAF2, 0x968D, 0xDAF3, 0x9697, 0xDAF4, 0x96B0, - 0xDAF5, 0x9097, 0xDAF6, 0x909B, 0xDAF7, 0x909D, 0xDAF8, 0x9099, 0xDAF9, 0x90AC, 0xDAFA, 0x90A1, 0xDAFB, 0x90B4, 0xDAFC, 0x90B3, - 0xDAFD, 0x90B6, 0xDAFE, 0x90BA, 0xDB40, 0x8DD5, 0xDB41, 0x8DD8, 0xDB42, 0x8DD9, 0xDB43, 0x8DDC, 0xDB44, 0x8DE0, 0xDB45, 0x8DE1, - 0xDB46, 0x8DE2, 0xDB47, 0x8DE5, 0xDB48, 0x8DE6, 0xDB49, 0x8DE7, 0xDB4A, 0x8DE9, 0xDB4B, 0x8DED, 0xDB4C, 0x8DEE, 0xDB4D, 0x8DF0, - 0xDB4E, 0x8DF1, 0xDB4F, 0x8DF2, 0xDB50, 0x8DF4, 0xDB51, 0x8DF6, 0xDB52, 0x8DFC, 0xDB53, 0x8DFE, 0xDB54, 0x8DFF, 0xDB55, 0x8E00, - 0xDB56, 0x8E01, 0xDB57, 0x8E02, 0xDB58, 0x8E03, 0xDB59, 0x8E04, 0xDB5A, 0x8E06, 0xDB5B, 0x8E07, 0xDB5C, 0x8E08, 0xDB5D, 0x8E0B, - 0xDB5E, 0x8E0D, 0xDB5F, 0x8E0E, 0xDB60, 0x8E10, 0xDB61, 0x8E11, 0xDB62, 0x8E12, 0xDB63, 0x8E13, 0xDB64, 0x8E15, 0xDB65, 0x8E16, - 0xDB66, 0x8E17, 0xDB67, 0x8E18, 0xDB68, 0x8E19, 0xDB69, 0x8E1A, 0xDB6A, 0x8E1B, 0xDB6B, 0x8E1C, 0xDB6C, 0x8E20, 0xDB6D, 0x8E21, - 0xDB6E, 0x8E24, 0xDB6F, 0x8E25, 0xDB70, 0x8E26, 0xDB71, 0x8E27, 0xDB72, 0x8E28, 0xDB73, 0x8E2B, 0xDB74, 0x8E2D, 0xDB75, 0x8E30, - 0xDB76, 0x8E32, 0xDB77, 0x8E33, 0xDB78, 0x8E34, 0xDB79, 0x8E36, 0xDB7A, 0x8E37, 0xDB7B, 0x8E38, 0xDB7C, 0x8E3B, 0xDB7D, 0x8E3C, - 0xDB7E, 0x8E3E, 0xDB80, 0x8E3F, 0xDB81, 0x8E43, 0xDB82, 0x8E45, 0xDB83, 0x8E46, 0xDB84, 0x8E4C, 0xDB85, 0x8E4D, 0xDB86, 0x8E4E, - 0xDB87, 0x8E4F, 0xDB88, 0x8E50, 0xDB89, 0x8E53, 0xDB8A, 0x8E54, 0xDB8B, 0x8E55, 0xDB8C, 0x8E56, 0xDB8D, 0x8E57, 0xDB8E, 0x8E58, - 0xDB8F, 0x8E5A, 0xDB90, 0x8E5B, 0xDB91, 0x8E5C, 0xDB92, 0x8E5D, 0xDB93, 0x8E5E, 0xDB94, 0x8E5F, 0xDB95, 0x8E60, 0xDB96, 0x8E61, - 0xDB97, 0x8E62, 0xDB98, 0x8E63, 0xDB99, 0x8E64, 0xDB9A, 0x8E65, 0xDB9B, 0x8E67, 0xDB9C, 0x8E68, 0xDB9D, 0x8E6A, 0xDB9E, 0x8E6B, - 0xDB9F, 0x8E6E, 0xDBA0, 0x8E71, 0xDBA1, 0x90B8, 0xDBA2, 0x90B0, 0xDBA3, 0x90CF, 0xDBA4, 0x90C5, 0xDBA5, 0x90BE, 0xDBA6, 0x90D0, - 0xDBA7, 0x90C4, 0xDBA8, 0x90C7, 0xDBA9, 0x90D3, 0xDBAA, 0x90E6, 0xDBAB, 0x90E2, 0xDBAC, 0x90DC, 0xDBAD, 0x90D7, 0xDBAE, 0x90DB, - 0xDBAF, 0x90EB, 0xDBB0, 0x90EF, 0xDBB1, 0x90FE, 0xDBB2, 0x9104, 0xDBB3, 0x9122, 0xDBB4, 0x911E, 0xDBB5, 0x9123, 0xDBB6, 0x9131, - 0xDBB7, 0x912F, 0xDBB8, 0x9139, 0xDBB9, 0x9143, 0xDBBA, 0x9146, 0xDBBB, 0x520D, 0xDBBC, 0x5942, 0xDBBD, 0x52A2, 0xDBBE, 0x52AC, - 0xDBBF, 0x52AD, 0xDBC0, 0x52BE, 0xDBC1, 0x54FF, 0xDBC2, 0x52D0, 0xDBC3, 0x52D6, 0xDBC4, 0x52F0, 0xDBC5, 0x53DF, 0xDBC6, 0x71EE, - 0xDBC7, 0x77CD, 0xDBC8, 0x5EF4, 0xDBC9, 0x51F5, 0xDBCA, 0x51FC, 0xDBCB, 0x9B2F, 0xDBCC, 0x53B6, 0xDBCD, 0x5F01, 0xDBCE, 0x755A, - 0xDBCF, 0x5DEF, 0xDBD0, 0x574C, 0xDBD1, 0x57A9, 0xDBD2, 0x57A1, 0xDBD3, 0x587E, 0xDBD4, 0x58BC, 0xDBD5, 0x58C5, 0xDBD6, 0x58D1, - 0xDBD7, 0x5729, 0xDBD8, 0x572C, 0xDBD9, 0x572A, 0xDBDA, 0x5733, 0xDBDB, 0x5739, 0xDBDC, 0x572E, 0xDBDD, 0x572F, 0xDBDE, 0x575C, - 0xDBDF, 0x573B, 0xDBE0, 0x5742, 0xDBE1, 0x5769, 0xDBE2, 0x5785, 0xDBE3, 0x576B, 0xDBE4, 0x5786, 0xDBE5, 0x577C, 0xDBE6, 0x577B, - 0xDBE7, 0x5768, 0xDBE8, 0x576D, 0xDBE9, 0x5776, 0xDBEA, 0x5773, 0xDBEB, 0x57AD, 0xDBEC, 0x57A4, 0xDBED, 0x578C, 0xDBEE, 0x57B2, - 0xDBEF, 0x57CF, 0xDBF0, 0x57A7, 0xDBF1, 0x57B4, 0xDBF2, 0x5793, 0xDBF3, 0x57A0, 0xDBF4, 0x57D5, 0xDBF5, 0x57D8, 0xDBF6, 0x57DA, - 0xDBF7, 0x57D9, 0xDBF8, 0x57D2, 0xDBF9, 0x57B8, 0xDBFA, 0x57F4, 0xDBFB, 0x57EF, 0xDBFC, 0x57F8, 0xDBFD, 0x57E4, 0xDBFE, 0x57DD, - 0xDC40, 0x8E73, 0xDC41, 0x8E75, 0xDC42, 0x8E77, 0xDC43, 0x8E78, 0xDC44, 0x8E79, 0xDC45, 0x8E7A, 0xDC46, 0x8E7B, 0xDC47, 0x8E7D, - 0xDC48, 0x8E7E, 0xDC49, 0x8E80, 0xDC4A, 0x8E82, 0xDC4B, 0x8E83, 0xDC4C, 0x8E84, 0xDC4D, 0x8E86, 0xDC4E, 0x8E88, 0xDC4F, 0x8E89, - 0xDC50, 0x8E8A, 0xDC51, 0x8E8B, 0xDC52, 0x8E8C, 0xDC53, 0x8E8D, 0xDC54, 0x8E8E, 0xDC55, 0x8E91, 0xDC56, 0x8E92, 0xDC57, 0x8E93, - 0xDC58, 0x8E95, 0xDC59, 0x8E96, 0xDC5A, 0x8E97, 0xDC5B, 0x8E98, 0xDC5C, 0x8E99, 0xDC5D, 0x8E9A, 0xDC5E, 0x8E9B, 0xDC5F, 0x8E9D, - 0xDC60, 0x8E9F, 0xDC61, 0x8EA0, 0xDC62, 0x8EA1, 0xDC63, 0x8EA2, 0xDC64, 0x8EA3, 0xDC65, 0x8EA4, 0xDC66, 0x8EA5, 0xDC67, 0x8EA6, - 0xDC68, 0x8EA7, 0xDC69, 0x8EA8, 0xDC6A, 0x8EA9, 0xDC6B, 0x8EAA, 0xDC6C, 0x8EAD, 0xDC6D, 0x8EAE, 0xDC6E, 0x8EB0, 0xDC6F, 0x8EB1, - 0xDC70, 0x8EB3, 0xDC71, 0x8EB4, 0xDC72, 0x8EB5, 0xDC73, 0x8EB6, 0xDC74, 0x8EB7, 0xDC75, 0x8EB8, 0xDC76, 0x8EB9, 0xDC77, 0x8EBB, - 0xDC78, 0x8EBC, 0xDC79, 0x8EBD, 0xDC7A, 0x8EBE, 0xDC7B, 0x8EBF, 0xDC7C, 0x8EC0, 0xDC7D, 0x8EC1, 0xDC7E, 0x8EC2, 0xDC80, 0x8EC3, - 0xDC81, 0x8EC4, 0xDC82, 0x8EC5, 0xDC83, 0x8EC6, 0xDC84, 0x8EC7, 0xDC85, 0x8EC8, 0xDC86, 0x8EC9, 0xDC87, 0x8ECA, 0xDC88, 0x8ECB, - 0xDC89, 0x8ECC, 0xDC8A, 0x8ECD, 0xDC8B, 0x8ECF, 0xDC8C, 0x8ED0, 0xDC8D, 0x8ED1, 0xDC8E, 0x8ED2, 0xDC8F, 0x8ED3, 0xDC90, 0x8ED4, - 0xDC91, 0x8ED5, 0xDC92, 0x8ED6, 0xDC93, 0x8ED7, 0xDC94, 0x8ED8, 0xDC95, 0x8ED9, 0xDC96, 0x8EDA, 0xDC97, 0x8EDB, 0xDC98, 0x8EDC, - 0xDC99, 0x8EDD, 0xDC9A, 0x8EDE, 0xDC9B, 0x8EDF, 0xDC9C, 0x8EE0, 0xDC9D, 0x8EE1, 0xDC9E, 0x8EE2, 0xDC9F, 0x8EE3, 0xDCA0, 0x8EE4, - 0xDCA1, 0x580B, 0xDCA2, 0x580D, 0xDCA3, 0x57FD, 0xDCA4, 0x57ED, 0xDCA5, 0x5800, 0xDCA6, 0x581E, 0xDCA7, 0x5819, 0xDCA8, 0x5844, - 0xDCA9, 0x5820, 0xDCAA, 0x5865, 0xDCAB, 0x586C, 0xDCAC, 0x5881, 0xDCAD, 0x5889, 0xDCAE, 0x589A, 0xDCAF, 0x5880, 0xDCB0, 0x99A8, - 0xDCB1, 0x9F19, 0xDCB2, 0x61FF, 0xDCB3, 0x8279, 0xDCB4, 0x827D, 0xDCB5, 0x827F, 0xDCB6, 0x828F, 0xDCB7, 0x828A, 0xDCB8, 0x82A8, - 0xDCB9, 0x8284, 0xDCBA, 0x828E, 0xDCBB, 0x8291, 0xDCBC, 0x8297, 0xDCBD, 0x8299, 0xDCBE, 0x82AB, 0xDCBF, 0x82B8, 0xDCC0, 0x82BE, - 0xDCC1, 0x82B0, 0xDCC2, 0x82C8, 0xDCC3, 0x82CA, 0xDCC4, 0x82E3, 0xDCC5, 0x8298, 0xDCC6, 0x82B7, 0xDCC7, 0x82AE, 0xDCC8, 0x82CB, - 0xDCC9, 0x82CC, 0xDCCA, 0x82C1, 0xDCCB, 0x82A9, 0xDCCC, 0x82B4, 0xDCCD, 0x82A1, 0xDCCE, 0x82AA, 0xDCCF, 0x829F, 0xDCD0, 0x82C4, - 0xDCD1, 0x82CE, 0xDCD2, 0x82A4, 0xDCD3, 0x82E1, 0xDCD4, 0x8309, 0xDCD5, 0x82F7, 0xDCD6, 0x82E4, 0xDCD7, 0x830F, 0xDCD8, 0x8307, - 0xDCD9, 0x82DC, 0xDCDA, 0x82F4, 0xDCDB, 0x82D2, 0xDCDC, 0x82D8, 0xDCDD, 0x830C, 0xDCDE, 0x82FB, 0xDCDF, 0x82D3, 0xDCE0, 0x8311, - 0xDCE1, 0x831A, 0xDCE2, 0x8306, 0xDCE3, 0x8314, 0xDCE4, 0x8315, 0xDCE5, 0x82E0, 0xDCE6, 0x82D5, 0xDCE7, 0x831C, 0xDCE8, 0x8351, - 0xDCE9, 0x835B, 0xDCEA, 0x835C, 0xDCEB, 0x8308, 0xDCEC, 0x8392, 0xDCED, 0x833C, 0xDCEE, 0x8334, 0xDCEF, 0x8331, 0xDCF0, 0x839B, - 0xDCF1, 0x835E, 0xDCF2, 0x832F, 0xDCF3, 0x834F, 0xDCF4, 0x8347, 0xDCF5, 0x8343, 0xDCF6, 0x835F, 0xDCF7, 0x8340, 0xDCF8, 0x8317, - 0xDCF9, 0x8360, 0xDCFA, 0x832D, 0xDCFB, 0x833A, 0xDCFC, 0x8333, 0xDCFD, 0x8366, 0xDCFE, 0x8365, 0xDD40, 0x8EE5, 0xDD41, 0x8EE6, - 0xDD42, 0x8EE7, 0xDD43, 0x8EE8, 0xDD44, 0x8EE9, 0xDD45, 0x8EEA, 0xDD46, 0x8EEB, 0xDD47, 0x8EEC, 0xDD48, 0x8EED, 0xDD49, 0x8EEE, - 0xDD4A, 0x8EEF, 0xDD4B, 0x8EF0, 0xDD4C, 0x8EF1, 0xDD4D, 0x8EF2, 0xDD4E, 0x8EF3, 0xDD4F, 0x8EF4, 0xDD50, 0x8EF5, 0xDD51, 0x8EF6, - 0xDD52, 0x8EF7, 0xDD53, 0x8EF8, 0xDD54, 0x8EF9, 0xDD55, 0x8EFA, 0xDD56, 0x8EFB, 0xDD57, 0x8EFC, 0xDD58, 0x8EFD, 0xDD59, 0x8EFE, - 0xDD5A, 0x8EFF, 0xDD5B, 0x8F00, 0xDD5C, 0x8F01, 0xDD5D, 0x8F02, 0xDD5E, 0x8F03, 0xDD5F, 0x8F04, 0xDD60, 0x8F05, 0xDD61, 0x8F06, - 0xDD62, 0x8F07, 0xDD63, 0x8F08, 0xDD64, 0x8F09, 0xDD65, 0x8F0A, 0xDD66, 0x8F0B, 0xDD67, 0x8F0C, 0xDD68, 0x8F0D, 0xDD69, 0x8F0E, - 0xDD6A, 0x8F0F, 0xDD6B, 0x8F10, 0xDD6C, 0x8F11, 0xDD6D, 0x8F12, 0xDD6E, 0x8F13, 0xDD6F, 0x8F14, 0xDD70, 0x8F15, 0xDD71, 0x8F16, - 0xDD72, 0x8F17, 0xDD73, 0x8F18, 0xDD74, 0x8F19, 0xDD75, 0x8F1A, 0xDD76, 0x8F1B, 0xDD77, 0x8F1C, 0xDD78, 0x8F1D, 0xDD79, 0x8F1E, - 0xDD7A, 0x8F1F, 0xDD7B, 0x8F20, 0xDD7C, 0x8F21, 0xDD7D, 0x8F22, 0xDD7E, 0x8F23, 0xDD80, 0x8F24, 0xDD81, 0x8F25, 0xDD82, 0x8F26, - 0xDD83, 0x8F27, 0xDD84, 0x8F28, 0xDD85, 0x8F29, 0xDD86, 0x8F2A, 0xDD87, 0x8F2B, 0xDD88, 0x8F2C, 0xDD89, 0x8F2D, 0xDD8A, 0x8F2E, - 0xDD8B, 0x8F2F, 0xDD8C, 0x8F30, 0xDD8D, 0x8F31, 0xDD8E, 0x8F32, 0xDD8F, 0x8F33, 0xDD90, 0x8F34, 0xDD91, 0x8F35, 0xDD92, 0x8F36, - 0xDD93, 0x8F37, 0xDD94, 0x8F38, 0xDD95, 0x8F39, 0xDD96, 0x8F3A, 0xDD97, 0x8F3B, 0xDD98, 0x8F3C, 0xDD99, 0x8F3D, 0xDD9A, 0x8F3E, - 0xDD9B, 0x8F3F, 0xDD9C, 0x8F40, 0xDD9D, 0x8F41, 0xDD9E, 0x8F42, 0xDD9F, 0x8F43, 0xDDA0, 0x8F44, 0xDDA1, 0x8368, 0xDDA2, 0x831B, - 0xDDA3, 0x8369, 0xDDA4, 0x836C, 0xDDA5, 0x836A, 0xDDA6, 0x836D, 0xDDA7, 0x836E, 0xDDA8, 0x83B0, 0xDDA9, 0x8378, 0xDDAA, 0x83B3, - 0xDDAB, 0x83B4, 0xDDAC, 0x83A0, 0xDDAD, 0x83AA, 0xDDAE, 0x8393, 0xDDAF, 0x839C, 0xDDB0, 0x8385, 0xDDB1, 0x837C, 0xDDB2, 0x83B6, - 0xDDB3, 0x83A9, 0xDDB4, 0x837D, 0xDDB5, 0x83B8, 0xDDB6, 0x837B, 0xDDB7, 0x8398, 0xDDB8, 0x839E, 0xDDB9, 0x83A8, 0xDDBA, 0x83BA, - 0xDDBB, 0x83BC, 0xDDBC, 0x83C1, 0xDDBD, 0x8401, 0xDDBE, 0x83E5, 0xDDBF, 0x83D8, 0xDDC0, 0x5807, 0xDDC1, 0x8418, 0xDDC2, 0x840B, - 0xDDC3, 0x83DD, 0xDDC4, 0x83FD, 0xDDC5, 0x83D6, 0xDDC6, 0x841C, 0xDDC7, 0x8438, 0xDDC8, 0x8411, 0xDDC9, 0x8406, 0xDDCA, 0x83D4, - 0xDDCB, 0x83DF, 0xDDCC, 0x840F, 0xDDCD, 0x8403, 0xDDCE, 0x83F8, 0xDDCF, 0x83F9, 0xDDD0, 0x83EA, 0xDDD1, 0x83C5, 0xDDD2, 0x83C0, - 0xDDD3, 0x8426, 0xDDD4, 0x83F0, 0xDDD5, 0x83E1, 0xDDD6, 0x845C, 0xDDD7, 0x8451, 0xDDD8, 0x845A, 0xDDD9, 0x8459, 0xDDDA, 0x8473, - 0xDDDB, 0x8487, 0xDDDC, 0x8488, 0xDDDD, 0x847A, 0xDDDE, 0x8489, 0xDDDF, 0x8478, 0xDDE0, 0x843C, 0xDDE1, 0x8446, 0xDDE2, 0x8469, - 0xDDE3, 0x8476, 0xDDE4, 0x848C, 0xDDE5, 0x848E, 0xDDE6, 0x8431, 0xDDE7, 0x846D, 0xDDE8, 0x84C1, 0xDDE9, 0x84CD, 0xDDEA, 0x84D0, - 0xDDEB, 0x84E6, 0xDDEC, 0x84BD, 0xDDED, 0x84D3, 0xDDEE, 0x84CA, 0xDDEF, 0x84BF, 0xDDF0, 0x84BA, 0xDDF1, 0x84E0, 0xDDF2, 0x84A1, - 0xDDF3, 0x84B9, 0xDDF4, 0x84B4, 0xDDF5, 0x8497, 0xDDF6, 0x84E5, 0xDDF7, 0x84E3, 0xDDF8, 0x850C, 0xDDF9, 0x750D, 0xDDFA, 0x8538, - 0xDDFB, 0x84F0, 0xDDFC, 0x8539, 0xDDFD, 0x851F, 0xDDFE, 0x853A, 0xDE40, 0x8F45, 0xDE41, 0x8F46, 0xDE42, 0x8F47, 0xDE43, 0x8F48, - 0xDE44, 0x8F49, 0xDE45, 0x8F4A, 0xDE46, 0x8F4B, 0xDE47, 0x8F4C, 0xDE48, 0x8F4D, 0xDE49, 0x8F4E, 0xDE4A, 0x8F4F, 0xDE4B, 0x8F50, - 0xDE4C, 0x8F51, 0xDE4D, 0x8F52, 0xDE4E, 0x8F53, 0xDE4F, 0x8F54, 0xDE50, 0x8F55, 0xDE51, 0x8F56, 0xDE52, 0x8F57, 0xDE53, 0x8F58, - 0xDE54, 0x8F59, 0xDE55, 0x8F5A, 0xDE56, 0x8F5B, 0xDE57, 0x8F5C, 0xDE58, 0x8F5D, 0xDE59, 0x8F5E, 0xDE5A, 0x8F5F, 0xDE5B, 0x8F60, - 0xDE5C, 0x8F61, 0xDE5D, 0x8F62, 0xDE5E, 0x8F63, 0xDE5F, 0x8F64, 0xDE60, 0x8F65, 0xDE61, 0x8F6A, 0xDE62, 0x8F80, 0xDE63, 0x8F8C, - 0xDE64, 0x8F92, 0xDE65, 0x8F9D, 0xDE66, 0x8FA0, 0xDE67, 0x8FA1, 0xDE68, 0x8FA2, 0xDE69, 0x8FA4, 0xDE6A, 0x8FA5, 0xDE6B, 0x8FA6, - 0xDE6C, 0x8FA7, 0xDE6D, 0x8FAA, 0xDE6E, 0x8FAC, 0xDE6F, 0x8FAD, 0xDE70, 0x8FAE, 0xDE71, 0x8FAF, 0xDE72, 0x8FB2, 0xDE73, 0x8FB3, - 0xDE74, 0x8FB4, 0xDE75, 0x8FB5, 0xDE76, 0x8FB7, 0xDE77, 0x8FB8, 0xDE78, 0x8FBA, 0xDE79, 0x8FBB, 0xDE7A, 0x8FBC, 0xDE7B, 0x8FBF, - 0xDE7C, 0x8FC0, 0xDE7D, 0x8FC3, 0xDE7E, 0x8FC6, 0xDE80, 0x8FC9, 0xDE81, 0x8FCA, 0xDE82, 0x8FCB, 0xDE83, 0x8FCC, 0xDE84, 0x8FCD, - 0xDE85, 0x8FCF, 0xDE86, 0x8FD2, 0xDE87, 0x8FD6, 0xDE88, 0x8FD7, 0xDE89, 0x8FDA, 0xDE8A, 0x8FE0, 0xDE8B, 0x8FE1, 0xDE8C, 0x8FE3, - 0xDE8D, 0x8FE7, 0xDE8E, 0x8FEC, 0xDE8F, 0x8FEF, 0xDE90, 0x8FF1, 0xDE91, 0x8FF2, 0xDE92, 0x8FF4, 0xDE93, 0x8FF5, 0xDE94, 0x8FF6, - 0xDE95, 0x8FFA, 0xDE96, 0x8FFB, 0xDE97, 0x8FFC, 0xDE98, 0x8FFE, 0xDE99, 0x8FFF, 0xDE9A, 0x9007, 0xDE9B, 0x9008, 0xDE9C, 0x900C, - 0xDE9D, 0x900E, 0xDE9E, 0x9013, 0xDE9F, 0x9015, 0xDEA0, 0x9018, 0xDEA1, 0x8556, 0xDEA2, 0x853B, 0xDEA3, 0x84FF, 0xDEA4, 0x84FC, - 0xDEA5, 0x8559, 0xDEA6, 0x8548, 0xDEA7, 0x8568, 0xDEA8, 0x8564, 0xDEA9, 0x855E, 0xDEAA, 0x857A, 0xDEAB, 0x77A2, 0xDEAC, 0x8543, - 0xDEAD, 0x8572, 0xDEAE, 0x857B, 0xDEAF, 0x85A4, 0xDEB0, 0x85A8, 0xDEB1, 0x8587, 0xDEB2, 0x858F, 0xDEB3, 0x8579, 0xDEB4, 0x85AE, - 0xDEB5, 0x859C, 0xDEB6, 0x8585, 0xDEB7, 0x85B9, 0xDEB8, 0x85B7, 0xDEB9, 0x85B0, 0xDEBA, 0x85D3, 0xDEBB, 0x85C1, 0xDEBC, 0x85DC, - 0xDEBD, 0x85FF, 0xDEBE, 0x8627, 0xDEBF, 0x8605, 0xDEC0, 0x8629, 0xDEC1, 0x8616, 0xDEC2, 0x863C, 0xDEC3, 0x5EFE, 0xDEC4, 0x5F08, - 0xDEC5, 0x593C, 0xDEC6, 0x5941, 0xDEC7, 0x8037, 0xDEC8, 0x5955, 0xDEC9, 0x595A, 0xDECA, 0x5958, 0xDECB, 0x530F, 0xDECC, 0x5C22, - 0xDECD, 0x5C25, 0xDECE, 0x5C2C, 0xDECF, 0x5C34, 0xDED0, 0x624C, 0xDED1, 0x626A, 0xDED2, 0x629F, 0xDED3, 0x62BB, 0xDED4, 0x62CA, - 0xDED5, 0x62DA, 0xDED6, 0x62D7, 0xDED7, 0x62EE, 0xDED8, 0x6322, 0xDED9, 0x62F6, 0xDEDA, 0x6339, 0xDEDB, 0x634B, 0xDEDC, 0x6343, - 0xDEDD, 0x63AD, 0xDEDE, 0x63F6, 0xDEDF, 0x6371, 0xDEE0, 0x637A, 0xDEE1, 0x638E, 0xDEE2, 0x63B4, 0xDEE3, 0x636D, 0xDEE4, 0x63AC, - 0xDEE5, 0x638A, 0xDEE6, 0x6369, 0xDEE7, 0x63AE, 0xDEE8, 0x63BC, 0xDEE9, 0x63F2, 0xDEEA, 0x63F8, 0xDEEB, 0x63E0, 0xDEEC, 0x63FF, - 0xDEED, 0x63C4, 0xDEEE, 0x63DE, 0xDEEF, 0x63CE, 0xDEF0, 0x6452, 0xDEF1, 0x63C6, 0xDEF2, 0x63BE, 0xDEF3, 0x6445, 0xDEF4, 0x6441, - 0xDEF5, 0x640B, 0xDEF6, 0x641B, 0xDEF7, 0x6420, 0xDEF8, 0x640C, 0xDEF9, 0x6426, 0xDEFA, 0x6421, 0xDEFB, 0x645E, 0xDEFC, 0x6484, - 0xDEFD, 0x646D, 0xDEFE, 0x6496, 0xDF40, 0x9019, 0xDF41, 0x901C, 0xDF42, 0x9023, 0xDF43, 0x9024, 0xDF44, 0x9025, 0xDF45, 0x9027, - 0xDF46, 0x9028, 0xDF47, 0x9029, 0xDF48, 0x902A, 0xDF49, 0x902B, 0xDF4A, 0x902C, 0xDF4B, 0x9030, 0xDF4C, 0x9031, 0xDF4D, 0x9032, - 0xDF4E, 0x9033, 0xDF4F, 0x9034, 0xDF50, 0x9037, 0xDF51, 0x9039, 0xDF52, 0x903A, 0xDF53, 0x903D, 0xDF54, 0x903F, 0xDF55, 0x9040, - 0xDF56, 0x9043, 0xDF57, 0x9045, 0xDF58, 0x9046, 0xDF59, 0x9048, 0xDF5A, 0x9049, 0xDF5B, 0x904A, 0xDF5C, 0x904B, 0xDF5D, 0x904C, - 0xDF5E, 0x904E, 0xDF5F, 0x9054, 0xDF60, 0x9055, 0xDF61, 0x9056, 0xDF62, 0x9059, 0xDF63, 0x905A, 0xDF64, 0x905C, 0xDF65, 0x905D, - 0xDF66, 0x905E, 0xDF67, 0x905F, 0xDF68, 0x9060, 0xDF69, 0x9061, 0xDF6A, 0x9064, 0xDF6B, 0x9066, 0xDF6C, 0x9067, 0xDF6D, 0x9069, - 0xDF6E, 0x906A, 0xDF6F, 0x906B, 0xDF70, 0x906C, 0xDF71, 0x906F, 0xDF72, 0x9070, 0xDF73, 0x9071, 0xDF74, 0x9072, 0xDF75, 0x9073, - 0xDF76, 0x9076, 0xDF77, 0x9077, 0xDF78, 0x9078, 0xDF79, 0x9079, 0xDF7A, 0x907A, 0xDF7B, 0x907B, 0xDF7C, 0x907C, 0xDF7D, 0x907E, - 0xDF7E, 0x9081, 0xDF80, 0x9084, 0xDF81, 0x9085, 0xDF82, 0x9086, 0xDF83, 0x9087, 0xDF84, 0x9089, 0xDF85, 0x908A, 0xDF86, 0x908C, - 0xDF87, 0x908D, 0xDF88, 0x908E, 0xDF89, 0x908F, 0xDF8A, 0x9090, 0xDF8B, 0x9092, 0xDF8C, 0x9094, 0xDF8D, 0x9096, 0xDF8E, 0x9098, - 0xDF8F, 0x909A, 0xDF90, 0x909C, 0xDF91, 0x909E, 0xDF92, 0x909F, 0xDF93, 0x90A0, 0xDF94, 0x90A4, 0xDF95, 0x90A5, 0xDF96, 0x90A7, - 0xDF97, 0x90A8, 0xDF98, 0x90A9, 0xDF99, 0x90AB, 0xDF9A, 0x90AD, 0xDF9B, 0x90B2, 0xDF9C, 0x90B7, 0xDF9D, 0x90BC, 0xDF9E, 0x90BD, - 0xDF9F, 0x90BF, 0xDFA0, 0x90C0, 0xDFA1, 0x647A, 0xDFA2, 0x64B7, 0xDFA3, 0x64B8, 0xDFA4, 0x6499, 0xDFA5, 0x64BA, 0xDFA6, 0x64C0, - 0xDFA7, 0x64D0, 0xDFA8, 0x64D7, 0xDFA9, 0x64E4, 0xDFAA, 0x64E2, 0xDFAB, 0x6509, 0xDFAC, 0x6525, 0xDFAD, 0x652E, 0xDFAE, 0x5F0B, - 0xDFAF, 0x5FD2, 0xDFB0, 0x7519, 0xDFB1, 0x5F11, 0xDFB2, 0x535F, 0xDFB3, 0x53F1, 0xDFB4, 0x53FD, 0xDFB5, 0x53E9, 0xDFB6, 0x53E8, - 0xDFB7, 0x53FB, 0xDFB8, 0x5412, 0xDFB9, 0x5416, 0xDFBA, 0x5406, 0xDFBB, 0x544B, 0xDFBC, 0x5452, 0xDFBD, 0x5453, 0xDFBE, 0x5454, - 0xDFBF, 0x5456, 0xDFC0, 0x5443, 0xDFC1, 0x5421, 0xDFC2, 0x5457, 0xDFC3, 0x5459, 0xDFC4, 0x5423, 0xDFC5, 0x5432, 0xDFC6, 0x5482, - 0xDFC7, 0x5494, 0xDFC8, 0x5477, 0xDFC9, 0x5471, 0xDFCA, 0x5464, 0xDFCB, 0x549A, 0xDFCC, 0x549B, 0xDFCD, 0x5484, 0xDFCE, 0x5476, - 0xDFCF, 0x5466, 0xDFD0, 0x549D, 0xDFD1, 0x54D0, 0xDFD2, 0x54AD, 0xDFD3, 0x54C2, 0xDFD4, 0x54B4, 0xDFD5, 0x54D2, 0xDFD6, 0x54A7, - 0xDFD7, 0x54A6, 0xDFD8, 0x54D3, 0xDFD9, 0x54D4, 0xDFDA, 0x5472, 0xDFDB, 0x54A3, 0xDFDC, 0x54D5, 0xDFDD, 0x54BB, 0xDFDE, 0x54BF, - 0xDFDF, 0x54CC, 0xDFE0, 0x54D9, 0xDFE1, 0x54DA, 0xDFE2, 0x54DC, 0xDFE3, 0x54A9, 0xDFE4, 0x54AA, 0xDFE5, 0x54A4, 0xDFE6, 0x54DD, - 0xDFE7, 0x54CF, 0xDFE8, 0x54DE, 0xDFE9, 0x551B, 0xDFEA, 0x54E7, 0xDFEB, 0x5520, 0xDFEC, 0x54FD, 0xDFED, 0x5514, 0xDFEE, 0x54F3, - 0xDFEF, 0x5522, 0xDFF0, 0x5523, 0xDFF1, 0x550F, 0xDFF2, 0x5511, 0xDFF3, 0x5527, 0xDFF4, 0x552A, 0xDFF5, 0x5567, 0xDFF6, 0x558F, - 0xDFF7, 0x55B5, 0xDFF8, 0x5549, 0xDFF9, 0x556D, 0xDFFA, 0x5541, 0xDFFB, 0x5555, 0xDFFC, 0x553F, 0xDFFD, 0x5550, 0xDFFE, 0x553C, - 0xE040, 0x90C2, 0xE041, 0x90C3, 0xE042, 0x90C6, 0xE043, 0x90C8, 0xE044, 0x90C9, 0xE045, 0x90CB, 0xE046, 0x90CC, 0xE047, 0x90CD, - 0xE048, 0x90D2, 0xE049, 0x90D4, 0xE04A, 0x90D5, 0xE04B, 0x90D6, 0xE04C, 0x90D8, 0xE04D, 0x90D9, 0xE04E, 0x90DA, 0xE04F, 0x90DE, - 0xE050, 0x90DF, 0xE051, 0x90E0, 0xE052, 0x90E3, 0xE053, 0x90E4, 0xE054, 0x90E5, 0xE055, 0x90E9, 0xE056, 0x90EA, 0xE057, 0x90EC, - 0xE058, 0x90EE, 0xE059, 0x90F0, 0xE05A, 0x90F1, 0xE05B, 0x90F2, 0xE05C, 0x90F3, 0xE05D, 0x90F5, 0xE05E, 0x90F6, 0xE05F, 0x90F7, - 0xE060, 0x90F9, 0xE061, 0x90FA, 0xE062, 0x90FB, 0xE063, 0x90FC, 0xE064, 0x90FF, 0xE065, 0x9100, 0xE066, 0x9101, 0xE067, 0x9103, - 0xE068, 0x9105, 0xE069, 0x9106, 0xE06A, 0x9107, 0xE06B, 0x9108, 0xE06C, 0x9109, 0xE06D, 0x910A, 0xE06E, 0x910B, 0xE06F, 0x910C, - 0xE070, 0x910D, 0xE071, 0x910E, 0xE072, 0x910F, 0xE073, 0x9110, 0xE074, 0x9111, 0xE075, 0x9112, 0xE076, 0x9113, 0xE077, 0x9114, - 0xE078, 0x9115, 0xE079, 0x9116, 0xE07A, 0x9117, 0xE07B, 0x9118, 0xE07C, 0x911A, 0xE07D, 0x911B, 0xE07E, 0x911C, 0xE080, 0x911D, - 0xE081, 0x911F, 0xE082, 0x9120, 0xE083, 0x9121, 0xE084, 0x9124, 0xE085, 0x9125, 0xE086, 0x9126, 0xE087, 0x9127, 0xE088, 0x9128, - 0xE089, 0x9129, 0xE08A, 0x912A, 0xE08B, 0x912B, 0xE08C, 0x912C, 0xE08D, 0x912D, 0xE08E, 0x912E, 0xE08F, 0x9130, 0xE090, 0x9132, - 0xE091, 0x9133, 0xE092, 0x9134, 0xE093, 0x9135, 0xE094, 0x9136, 0xE095, 0x9137, 0xE096, 0x9138, 0xE097, 0x913A, 0xE098, 0x913B, - 0xE099, 0x913C, 0xE09A, 0x913D, 0xE09B, 0x913E, 0xE09C, 0x913F, 0xE09D, 0x9140, 0xE09E, 0x9141, 0xE09F, 0x9142, 0xE0A0, 0x9144, - 0xE0A1, 0x5537, 0xE0A2, 0x5556, 0xE0A3, 0x5575, 0xE0A4, 0x5576, 0xE0A5, 0x5577, 0xE0A6, 0x5533, 0xE0A7, 0x5530, 0xE0A8, 0x555C, - 0xE0A9, 0x558B, 0xE0AA, 0x55D2, 0xE0AB, 0x5583, 0xE0AC, 0x55B1, 0xE0AD, 0x55B9, 0xE0AE, 0x5588, 0xE0AF, 0x5581, 0xE0B0, 0x559F, - 0xE0B1, 0x557E, 0xE0B2, 0x55D6, 0xE0B3, 0x5591, 0xE0B4, 0x557B, 0xE0B5, 0x55DF, 0xE0B6, 0x55BD, 0xE0B7, 0x55BE, 0xE0B8, 0x5594, - 0xE0B9, 0x5599, 0xE0BA, 0x55EA, 0xE0BB, 0x55F7, 0xE0BC, 0x55C9, 0xE0BD, 0x561F, 0xE0BE, 0x55D1, 0xE0BF, 0x55EB, 0xE0C0, 0x55EC, - 0xE0C1, 0x55D4, 0xE0C2, 0x55E6, 0xE0C3, 0x55DD, 0xE0C4, 0x55C4, 0xE0C5, 0x55EF, 0xE0C6, 0x55E5, 0xE0C7, 0x55F2, 0xE0C8, 0x55F3, - 0xE0C9, 0x55CC, 0xE0CA, 0x55CD, 0xE0CB, 0x55E8, 0xE0CC, 0x55F5, 0xE0CD, 0x55E4, 0xE0CE, 0x8F94, 0xE0CF, 0x561E, 0xE0D0, 0x5608, - 0xE0D1, 0x560C, 0xE0D2, 0x5601, 0xE0D3, 0x5624, 0xE0D4, 0x5623, 0xE0D5, 0x55FE, 0xE0D6, 0x5600, 0xE0D7, 0x5627, 0xE0D8, 0x562D, - 0xE0D9, 0x5658, 0xE0DA, 0x5639, 0xE0DB, 0x5657, 0xE0DC, 0x562C, 0xE0DD, 0x564D, 0xE0DE, 0x5662, 0xE0DF, 0x5659, 0xE0E0, 0x565C, - 0xE0E1, 0x564C, 0xE0E2, 0x5654, 0xE0E3, 0x5686, 0xE0E4, 0x5664, 0xE0E5, 0x5671, 0xE0E6, 0x566B, 0xE0E7, 0x567B, 0xE0E8, 0x567C, - 0xE0E9, 0x5685, 0xE0EA, 0x5693, 0xE0EB, 0x56AF, 0xE0EC, 0x56D4, 0xE0ED, 0x56D7, 0xE0EE, 0x56DD, 0xE0EF, 0x56E1, 0xE0F0, 0x56F5, - 0xE0F1, 0x56EB, 0xE0F2, 0x56F9, 0xE0F3, 0x56FF, 0xE0F4, 0x5704, 0xE0F5, 0x570A, 0xE0F6, 0x5709, 0xE0F7, 0x571C, 0xE0F8, 0x5E0F, - 0xE0F9, 0x5E19, 0xE0FA, 0x5E14, 0xE0FB, 0x5E11, 0xE0FC, 0x5E31, 0xE0FD, 0x5E3B, 0xE0FE, 0x5E3C, 0xE140, 0x9145, 0xE141, 0x9147, - 0xE142, 0x9148, 0xE143, 0x9151, 0xE144, 0x9153, 0xE145, 0x9154, 0xE146, 0x9155, 0xE147, 0x9156, 0xE148, 0x9158, 0xE149, 0x9159, - 0xE14A, 0x915B, 0xE14B, 0x915C, 0xE14C, 0x915F, 0xE14D, 0x9160, 0xE14E, 0x9166, 0xE14F, 0x9167, 0xE150, 0x9168, 0xE151, 0x916B, - 0xE152, 0x916D, 0xE153, 0x9173, 0xE154, 0x917A, 0xE155, 0x917B, 0xE156, 0x917C, 0xE157, 0x9180, 0xE158, 0x9181, 0xE159, 0x9182, - 0xE15A, 0x9183, 0xE15B, 0x9184, 0xE15C, 0x9186, 0xE15D, 0x9188, 0xE15E, 0x918A, 0xE15F, 0x918E, 0xE160, 0x918F, 0xE161, 0x9193, - 0xE162, 0x9194, 0xE163, 0x9195, 0xE164, 0x9196, 0xE165, 0x9197, 0xE166, 0x9198, 0xE167, 0x9199, 0xE168, 0x919C, 0xE169, 0x919D, - 0xE16A, 0x919E, 0xE16B, 0x919F, 0xE16C, 0x91A0, 0xE16D, 0x91A1, 0xE16E, 0x91A4, 0xE16F, 0x91A5, 0xE170, 0x91A6, 0xE171, 0x91A7, - 0xE172, 0x91A8, 0xE173, 0x91A9, 0xE174, 0x91AB, 0xE175, 0x91AC, 0xE176, 0x91B0, 0xE177, 0x91B1, 0xE178, 0x91B2, 0xE179, 0x91B3, - 0xE17A, 0x91B6, 0xE17B, 0x91B7, 0xE17C, 0x91B8, 0xE17D, 0x91B9, 0xE17E, 0x91BB, 0xE180, 0x91BC, 0xE181, 0x91BD, 0xE182, 0x91BE, - 0xE183, 0x91BF, 0xE184, 0x91C0, 0xE185, 0x91C1, 0xE186, 0x91C2, 0xE187, 0x91C3, 0xE188, 0x91C4, 0xE189, 0x91C5, 0xE18A, 0x91C6, - 0xE18B, 0x91C8, 0xE18C, 0x91CB, 0xE18D, 0x91D0, 0xE18E, 0x91D2, 0xE18F, 0x91D3, 0xE190, 0x91D4, 0xE191, 0x91D5, 0xE192, 0x91D6, - 0xE193, 0x91D7, 0xE194, 0x91D8, 0xE195, 0x91D9, 0xE196, 0x91DA, 0xE197, 0x91DB, 0xE198, 0x91DD, 0xE199, 0x91DE, 0xE19A, 0x91DF, - 0xE19B, 0x91E0, 0xE19C, 0x91E1, 0xE19D, 0x91E2, 0xE19E, 0x91E3, 0xE19F, 0x91E4, 0xE1A0, 0x91E5, 0xE1A1, 0x5E37, 0xE1A2, 0x5E44, - 0xE1A3, 0x5E54, 0xE1A4, 0x5E5B, 0xE1A5, 0x5E5E, 0xE1A6, 0x5E61, 0xE1A7, 0x5C8C, 0xE1A8, 0x5C7A, 0xE1A9, 0x5C8D, 0xE1AA, 0x5C90, - 0xE1AB, 0x5C96, 0xE1AC, 0x5C88, 0xE1AD, 0x5C98, 0xE1AE, 0x5C99, 0xE1AF, 0x5C91, 0xE1B0, 0x5C9A, 0xE1B1, 0x5C9C, 0xE1B2, 0x5CB5, - 0xE1B3, 0x5CA2, 0xE1B4, 0x5CBD, 0xE1B5, 0x5CAC, 0xE1B6, 0x5CAB, 0xE1B7, 0x5CB1, 0xE1B8, 0x5CA3, 0xE1B9, 0x5CC1, 0xE1BA, 0x5CB7, - 0xE1BB, 0x5CC4, 0xE1BC, 0x5CD2, 0xE1BD, 0x5CE4, 0xE1BE, 0x5CCB, 0xE1BF, 0x5CE5, 0xE1C0, 0x5D02, 0xE1C1, 0x5D03, 0xE1C2, 0x5D27, - 0xE1C3, 0x5D26, 0xE1C4, 0x5D2E, 0xE1C5, 0x5D24, 0xE1C6, 0x5D1E, 0xE1C7, 0x5D06, 0xE1C8, 0x5D1B, 0xE1C9, 0x5D58, 0xE1CA, 0x5D3E, - 0xE1CB, 0x5D34, 0xE1CC, 0x5D3D, 0xE1CD, 0x5D6C, 0xE1CE, 0x5D5B, 0xE1CF, 0x5D6F, 0xE1D0, 0x5D5D, 0xE1D1, 0x5D6B, 0xE1D2, 0x5D4B, - 0xE1D3, 0x5D4A, 0xE1D4, 0x5D69, 0xE1D5, 0x5D74, 0xE1D6, 0x5D82, 0xE1D7, 0x5D99, 0xE1D8, 0x5D9D, 0xE1D9, 0x8C73, 0xE1DA, 0x5DB7, - 0xE1DB, 0x5DC5, 0xE1DC, 0x5F73, 0xE1DD, 0x5F77, 0xE1DE, 0x5F82, 0xE1DF, 0x5F87, 0xE1E0, 0x5F89, 0xE1E1, 0x5F8C, 0xE1E2, 0x5F95, - 0xE1E3, 0x5F99, 0xE1E4, 0x5F9C, 0xE1E5, 0x5FA8, 0xE1E6, 0x5FAD, 0xE1E7, 0x5FB5, 0xE1E8, 0x5FBC, 0xE1E9, 0x8862, 0xE1EA, 0x5F61, - 0xE1EB, 0x72AD, 0xE1EC, 0x72B0, 0xE1ED, 0x72B4, 0xE1EE, 0x72B7, 0xE1EF, 0x72B8, 0xE1F0, 0x72C3, 0xE1F1, 0x72C1, 0xE1F2, 0x72CE, - 0xE1F3, 0x72CD, 0xE1F4, 0x72D2, 0xE1F5, 0x72E8, 0xE1F6, 0x72EF, 0xE1F7, 0x72E9, 0xE1F8, 0x72F2, 0xE1F9, 0x72F4, 0xE1FA, 0x72F7, - 0xE1FB, 0x7301, 0xE1FC, 0x72F3, 0xE1FD, 0x7303, 0xE1FE, 0x72FA, 0xE240, 0x91E6, 0xE241, 0x91E7, 0xE242, 0x91E8, 0xE243, 0x91E9, - 0xE244, 0x91EA, 0xE245, 0x91EB, 0xE246, 0x91EC, 0xE247, 0x91ED, 0xE248, 0x91EE, 0xE249, 0x91EF, 0xE24A, 0x91F0, 0xE24B, 0x91F1, - 0xE24C, 0x91F2, 0xE24D, 0x91F3, 0xE24E, 0x91F4, 0xE24F, 0x91F5, 0xE250, 0x91F6, 0xE251, 0x91F7, 0xE252, 0x91F8, 0xE253, 0x91F9, - 0xE254, 0x91FA, 0xE255, 0x91FB, 0xE256, 0x91FC, 0xE257, 0x91FD, 0xE258, 0x91FE, 0xE259, 0x91FF, 0xE25A, 0x9200, 0xE25B, 0x9201, - 0xE25C, 0x9202, 0xE25D, 0x9203, 0xE25E, 0x9204, 0xE25F, 0x9205, 0xE260, 0x9206, 0xE261, 0x9207, 0xE262, 0x9208, 0xE263, 0x9209, - 0xE264, 0x920A, 0xE265, 0x920B, 0xE266, 0x920C, 0xE267, 0x920D, 0xE268, 0x920E, 0xE269, 0x920F, 0xE26A, 0x9210, 0xE26B, 0x9211, - 0xE26C, 0x9212, 0xE26D, 0x9213, 0xE26E, 0x9214, 0xE26F, 0x9215, 0xE270, 0x9216, 0xE271, 0x9217, 0xE272, 0x9218, 0xE273, 0x9219, - 0xE274, 0x921A, 0xE275, 0x921B, 0xE276, 0x921C, 0xE277, 0x921D, 0xE278, 0x921E, 0xE279, 0x921F, 0xE27A, 0x9220, 0xE27B, 0x9221, - 0xE27C, 0x9222, 0xE27D, 0x9223, 0xE27E, 0x9224, 0xE280, 0x9225, 0xE281, 0x9226, 0xE282, 0x9227, 0xE283, 0x9228, 0xE284, 0x9229, - 0xE285, 0x922A, 0xE286, 0x922B, 0xE287, 0x922C, 0xE288, 0x922D, 0xE289, 0x922E, 0xE28A, 0x922F, 0xE28B, 0x9230, 0xE28C, 0x9231, - 0xE28D, 0x9232, 0xE28E, 0x9233, 0xE28F, 0x9234, 0xE290, 0x9235, 0xE291, 0x9236, 0xE292, 0x9237, 0xE293, 0x9238, 0xE294, 0x9239, - 0xE295, 0x923A, 0xE296, 0x923B, 0xE297, 0x923C, 0xE298, 0x923D, 0xE299, 0x923E, 0xE29A, 0x923F, 0xE29B, 0x9240, 0xE29C, 0x9241, - 0xE29D, 0x9242, 0xE29E, 0x9243, 0xE29F, 0x9244, 0xE2A0, 0x9245, 0xE2A1, 0x72FB, 0xE2A2, 0x7317, 0xE2A3, 0x7313, 0xE2A4, 0x7321, - 0xE2A5, 0x730A, 0xE2A6, 0x731E, 0xE2A7, 0x731D, 0xE2A8, 0x7315, 0xE2A9, 0x7322, 0xE2AA, 0x7339, 0xE2AB, 0x7325, 0xE2AC, 0x732C, - 0xE2AD, 0x7338, 0xE2AE, 0x7331, 0xE2AF, 0x7350, 0xE2B0, 0x734D, 0xE2B1, 0x7357, 0xE2B2, 0x7360, 0xE2B3, 0x736C, 0xE2B4, 0x736F, - 0xE2B5, 0x737E, 0xE2B6, 0x821B, 0xE2B7, 0x5925, 0xE2B8, 0x98E7, 0xE2B9, 0x5924, 0xE2BA, 0x5902, 0xE2BB, 0x9963, 0xE2BC, 0x9967, - 0xE2BD, 0x9968, 0xE2BE, 0x9969, 0xE2BF, 0x996A, 0xE2C0, 0x996B, 0xE2C1, 0x996C, 0xE2C2, 0x9974, 0xE2C3, 0x9977, 0xE2C4, 0x997D, - 0xE2C5, 0x9980, 0xE2C6, 0x9984, 0xE2C7, 0x9987, 0xE2C8, 0x998A, 0xE2C9, 0x998D, 0xE2CA, 0x9990, 0xE2CB, 0x9991, 0xE2CC, 0x9993, - 0xE2CD, 0x9994, 0xE2CE, 0x9995, 0xE2CF, 0x5E80, 0xE2D0, 0x5E91, 0xE2D1, 0x5E8B, 0xE2D2, 0x5E96, 0xE2D3, 0x5EA5, 0xE2D4, 0x5EA0, - 0xE2D5, 0x5EB9, 0xE2D6, 0x5EB5, 0xE2D7, 0x5EBE, 0xE2D8, 0x5EB3, 0xE2D9, 0x8D53, 0xE2DA, 0x5ED2, 0xE2DB, 0x5ED1, 0xE2DC, 0x5EDB, - 0xE2DD, 0x5EE8, 0xE2DE, 0x5EEA, 0xE2DF, 0x81BA, 0xE2E0, 0x5FC4, 0xE2E1, 0x5FC9, 0xE2E2, 0x5FD6, 0xE2E3, 0x5FCF, 0xE2E4, 0x6003, - 0xE2E5, 0x5FEE, 0xE2E6, 0x6004, 0xE2E7, 0x5FE1, 0xE2E8, 0x5FE4, 0xE2E9, 0x5FFE, 0xE2EA, 0x6005, 0xE2EB, 0x6006, 0xE2EC, 0x5FEA, - 0xE2ED, 0x5FED, 0xE2EE, 0x5FF8, 0xE2EF, 0x6019, 0xE2F0, 0x6035, 0xE2F1, 0x6026, 0xE2F2, 0x601B, 0xE2F3, 0x600F, 0xE2F4, 0x600D, - 0xE2F5, 0x6029, 0xE2F6, 0x602B, 0xE2F7, 0x600A, 0xE2F8, 0x603F, 0xE2F9, 0x6021, 0xE2FA, 0x6078, 0xE2FB, 0x6079, 0xE2FC, 0x607B, - 0xE2FD, 0x607A, 0xE2FE, 0x6042, 0xE340, 0x9246, 0xE341, 0x9247, 0xE342, 0x9248, 0xE343, 0x9249, 0xE344, 0x924A, 0xE345, 0x924B, - 0xE346, 0x924C, 0xE347, 0x924D, 0xE348, 0x924E, 0xE349, 0x924F, 0xE34A, 0x9250, 0xE34B, 0x9251, 0xE34C, 0x9252, 0xE34D, 0x9253, - 0xE34E, 0x9254, 0xE34F, 0x9255, 0xE350, 0x9256, 0xE351, 0x9257, 0xE352, 0x9258, 0xE353, 0x9259, 0xE354, 0x925A, 0xE355, 0x925B, - 0xE356, 0x925C, 0xE357, 0x925D, 0xE358, 0x925E, 0xE359, 0x925F, 0xE35A, 0x9260, 0xE35B, 0x9261, 0xE35C, 0x9262, 0xE35D, 0x9263, - 0xE35E, 0x9264, 0xE35F, 0x9265, 0xE360, 0x9266, 0xE361, 0x9267, 0xE362, 0x9268, 0xE363, 0x9269, 0xE364, 0x926A, 0xE365, 0x926B, - 0xE366, 0x926C, 0xE367, 0x926D, 0xE368, 0x926E, 0xE369, 0x926F, 0xE36A, 0x9270, 0xE36B, 0x9271, 0xE36C, 0x9272, 0xE36D, 0x9273, - 0xE36E, 0x9275, 0xE36F, 0x9276, 0xE370, 0x9277, 0xE371, 0x9278, 0xE372, 0x9279, 0xE373, 0x927A, 0xE374, 0x927B, 0xE375, 0x927C, - 0xE376, 0x927D, 0xE377, 0x927E, 0xE378, 0x927F, 0xE379, 0x9280, 0xE37A, 0x9281, 0xE37B, 0x9282, 0xE37C, 0x9283, 0xE37D, 0x9284, - 0xE37E, 0x9285, 0xE380, 0x9286, 0xE381, 0x9287, 0xE382, 0x9288, 0xE383, 0x9289, 0xE384, 0x928A, 0xE385, 0x928B, 0xE386, 0x928C, - 0xE387, 0x928D, 0xE388, 0x928F, 0xE389, 0x9290, 0xE38A, 0x9291, 0xE38B, 0x9292, 0xE38C, 0x9293, 0xE38D, 0x9294, 0xE38E, 0x9295, - 0xE38F, 0x9296, 0xE390, 0x9297, 0xE391, 0x9298, 0xE392, 0x9299, 0xE393, 0x929A, 0xE394, 0x929B, 0xE395, 0x929C, 0xE396, 0x929D, - 0xE397, 0x929E, 0xE398, 0x929F, 0xE399, 0x92A0, 0xE39A, 0x92A1, 0xE39B, 0x92A2, 0xE39C, 0x92A3, 0xE39D, 0x92A4, 0xE39E, 0x92A5, - 0xE39F, 0x92A6, 0xE3A0, 0x92A7, 0xE3A1, 0x606A, 0xE3A2, 0x607D, 0xE3A3, 0x6096, 0xE3A4, 0x609A, 0xE3A5, 0x60AD, 0xE3A6, 0x609D, - 0xE3A7, 0x6083, 0xE3A8, 0x6092, 0xE3A9, 0x608C, 0xE3AA, 0x609B, 0xE3AB, 0x60EC, 0xE3AC, 0x60BB, 0xE3AD, 0x60B1, 0xE3AE, 0x60DD, - 0xE3AF, 0x60D8, 0xE3B0, 0x60C6, 0xE3B1, 0x60DA, 0xE3B2, 0x60B4, 0xE3B3, 0x6120, 0xE3B4, 0x6126, 0xE3B5, 0x6115, 0xE3B6, 0x6123, - 0xE3B7, 0x60F4, 0xE3B8, 0x6100, 0xE3B9, 0x610E, 0xE3BA, 0x612B, 0xE3BB, 0x614A, 0xE3BC, 0x6175, 0xE3BD, 0x61AC, 0xE3BE, 0x6194, - 0xE3BF, 0x61A7, 0xE3C0, 0x61B7, 0xE3C1, 0x61D4, 0xE3C2, 0x61F5, 0xE3C3, 0x5FDD, 0xE3C4, 0x96B3, 0xE3C5, 0x95E9, 0xE3C6, 0x95EB, - 0xE3C7, 0x95F1, 0xE3C8, 0x95F3, 0xE3C9, 0x95F5, 0xE3CA, 0x95F6, 0xE3CB, 0x95FC, 0xE3CC, 0x95FE, 0xE3CD, 0x9603, 0xE3CE, 0x9604, - 0xE3CF, 0x9606, 0xE3D0, 0x9608, 0xE3D1, 0x960A, 0xE3D2, 0x960B, 0xE3D3, 0x960C, 0xE3D4, 0x960D, 0xE3D5, 0x960F, 0xE3D6, 0x9612, - 0xE3D7, 0x9615, 0xE3D8, 0x9616, 0xE3D9, 0x9617, 0xE3DA, 0x9619, 0xE3DB, 0x961A, 0xE3DC, 0x4E2C, 0xE3DD, 0x723F, 0xE3DE, 0x6215, - 0xE3DF, 0x6C35, 0xE3E0, 0x6C54, 0xE3E1, 0x6C5C, 0xE3E2, 0x6C4A, 0xE3E3, 0x6CA3, 0xE3E4, 0x6C85, 0xE3E5, 0x6C90, 0xE3E6, 0x6C94, - 0xE3E7, 0x6C8C, 0xE3E8, 0x6C68, 0xE3E9, 0x6C69, 0xE3EA, 0x6C74, 0xE3EB, 0x6C76, 0xE3EC, 0x6C86, 0xE3ED, 0x6CA9, 0xE3EE, 0x6CD0, - 0xE3EF, 0x6CD4, 0xE3F0, 0x6CAD, 0xE3F1, 0x6CF7, 0xE3F2, 0x6CF8, 0xE3F3, 0x6CF1, 0xE3F4, 0x6CD7, 0xE3F5, 0x6CB2, 0xE3F6, 0x6CE0, - 0xE3F7, 0x6CD6, 0xE3F8, 0x6CFA, 0xE3F9, 0x6CEB, 0xE3FA, 0x6CEE, 0xE3FB, 0x6CB1, 0xE3FC, 0x6CD3, 0xE3FD, 0x6CEF, 0xE3FE, 0x6CFE, - 0xE440, 0x92A8, 0xE441, 0x92A9, 0xE442, 0x92AA, 0xE443, 0x92AB, 0xE444, 0x92AC, 0xE445, 0x92AD, 0xE446, 0x92AF, 0xE447, 0x92B0, - 0xE448, 0x92B1, 0xE449, 0x92B2, 0xE44A, 0x92B3, 0xE44B, 0x92B4, 0xE44C, 0x92B5, 0xE44D, 0x92B6, 0xE44E, 0x92B7, 0xE44F, 0x92B8, - 0xE450, 0x92B9, 0xE451, 0x92BA, 0xE452, 0x92BB, 0xE453, 0x92BC, 0xE454, 0x92BD, 0xE455, 0x92BE, 0xE456, 0x92BF, 0xE457, 0x92C0, - 0xE458, 0x92C1, 0xE459, 0x92C2, 0xE45A, 0x92C3, 0xE45B, 0x92C4, 0xE45C, 0x92C5, 0xE45D, 0x92C6, 0xE45E, 0x92C7, 0xE45F, 0x92C9, - 0xE460, 0x92CA, 0xE461, 0x92CB, 0xE462, 0x92CC, 0xE463, 0x92CD, 0xE464, 0x92CE, 0xE465, 0x92CF, 0xE466, 0x92D0, 0xE467, 0x92D1, - 0xE468, 0x92D2, 0xE469, 0x92D3, 0xE46A, 0x92D4, 0xE46B, 0x92D5, 0xE46C, 0x92D6, 0xE46D, 0x92D7, 0xE46E, 0x92D8, 0xE46F, 0x92D9, - 0xE470, 0x92DA, 0xE471, 0x92DB, 0xE472, 0x92DC, 0xE473, 0x92DD, 0xE474, 0x92DE, 0xE475, 0x92DF, 0xE476, 0x92E0, 0xE477, 0x92E1, - 0xE478, 0x92E2, 0xE479, 0x92E3, 0xE47A, 0x92E4, 0xE47B, 0x92E5, 0xE47C, 0x92E6, 0xE47D, 0x92E7, 0xE47E, 0x92E8, 0xE480, 0x92E9, - 0xE481, 0x92EA, 0xE482, 0x92EB, 0xE483, 0x92EC, 0xE484, 0x92ED, 0xE485, 0x92EE, 0xE486, 0x92EF, 0xE487, 0x92F0, 0xE488, 0x92F1, - 0xE489, 0x92F2, 0xE48A, 0x92F3, 0xE48B, 0x92F4, 0xE48C, 0x92F5, 0xE48D, 0x92F6, 0xE48E, 0x92F7, 0xE48F, 0x92F8, 0xE490, 0x92F9, - 0xE491, 0x92FA, 0xE492, 0x92FB, 0xE493, 0x92FC, 0xE494, 0x92FD, 0xE495, 0x92FE, 0xE496, 0x92FF, 0xE497, 0x9300, 0xE498, 0x9301, - 0xE499, 0x9302, 0xE49A, 0x9303, 0xE49B, 0x9304, 0xE49C, 0x9305, 0xE49D, 0x9306, 0xE49E, 0x9307, 0xE49F, 0x9308, 0xE4A0, 0x9309, - 0xE4A1, 0x6D39, 0xE4A2, 0x6D27, 0xE4A3, 0x6D0C, 0xE4A4, 0x6D43, 0xE4A5, 0x6D48, 0xE4A6, 0x6D07, 0xE4A7, 0x6D04, 0xE4A8, 0x6D19, - 0xE4A9, 0x6D0E, 0xE4AA, 0x6D2B, 0xE4AB, 0x6D4D, 0xE4AC, 0x6D2E, 0xE4AD, 0x6D35, 0xE4AE, 0x6D1A, 0xE4AF, 0x6D4F, 0xE4B0, 0x6D52, - 0xE4B1, 0x6D54, 0xE4B2, 0x6D33, 0xE4B3, 0x6D91, 0xE4B4, 0x6D6F, 0xE4B5, 0x6D9E, 0xE4B6, 0x6DA0, 0xE4B7, 0x6D5E, 0xE4B8, 0x6D93, - 0xE4B9, 0x6D94, 0xE4BA, 0x6D5C, 0xE4BB, 0x6D60, 0xE4BC, 0x6D7C, 0xE4BD, 0x6D63, 0xE4BE, 0x6E1A, 0xE4BF, 0x6DC7, 0xE4C0, 0x6DC5, - 0xE4C1, 0x6DDE, 0xE4C2, 0x6E0E, 0xE4C3, 0x6DBF, 0xE4C4, 0x6DE0, 0xE4C5, 0x6E11, 0xE4C6, 0x6DE6, 0xE4C7, 0x6DDD, 0xE4C8, 0x6DD9, - 0xE4C9, 0x6E16, 0xE4CA, 0x6DAB, 0xE4CB, 0x6E0C, 0xE4CC, 0x6DAE, 0xE4CD, 0x6E2B, 0xE4CE, 0x6E6E, 0xE4CF, 0x6E4E, 0xE4D0, 0x6E6B, - 0xE4D1, 0x6EB2, 0xE4D2, 0x6E5F, 0xE4D3, 0x6E86, 0xE4D4, 0x6E53, 0xE4D5, 0x6E54, 0xE4D6, 0x6E32, 0xE4D7, 0x6E25, 0xE4D8, 0x6E44, - 0xE4D9, 0x6EDF, 0xE4DA, 0x6EB1, 0xE4DB, 0x6E98, 0xE4DC, 0x6EE0, 0xE4DD, 0x6F2D, 0xE4DE, 0x6EE2, 0xE4DF, 0x6EA5, 0xE4E0, 0x6EA7, - 0xE4E1, 0x6EBD, 0xE4E2, 0x6EBB, 0xE4E3, 0x6EB7, 0xE4E4, 0x6ED7, 0xE4E5, 0x6EB4, 0xE4E6, 0x6ECF, 0xE4E7, 0x6E8F, 0xE4E8, 0x6EC2, - 0xE4E9, 0x6E9F, 0xE4EA, 0x6F62, 0xE4EB, 0x6F46, 0xE4EC, 0x6F47, 0xE4ED, 0x6F24, 0xE4EE, 0x6F15, 0xE4EF, 0x6EF9, 0xE4F0, 0x6F2F, - 0xE4F1, 0x6F36, 0xE4F2, 0x6F4B, 0xE4F3, 0x6F74, 0xE4F4, 0x6F2A, 0xE4F5, 0x6F09, 0xE4F6, 0x6F29, 0xE4F7, 0x6F89, 0xE4F8, 0x6F8D, - 0xE4F9, 0x6F8C, 0xE4FA, 0x6F78, 0xE4FB, 0x6F72, 0xE4FC, 0x6F7C, 0xE4FD, 0x6F7A, 0xE4FE, 0x6FD1, 0xE540, 0x930A, 0xE541, 0x930B, - 0xE542, 0x930C, 0xE543, 0x930D, 0xE544, 0x930E, 0xE545, 0x930F, 0xE546, 0x9310, 0xE547, 0x9311, 0xE548, 0x9312, 0xE549, 0x9313, - 0xE54A, 0x9314, 0xE54B, 0x9315, 0xE54C, 0x9316, 0xE54D, 0x9317, 0xE54E, 0x9318, 0xE54F, 0x9319, 0xE550, 0x931A, 0xE551, 0x931B, - 0xE552, 0x931C, 0xE553, 0x931D, 0xE554, 0x931E, 0xE555, 0x931F, 0xE556, 0x9320, 0xE557, 0x9321, 0xE558, 0x9322, 0xE559, 0x9323, - 0xE55A, 0x9324, 0xE55B, 0x9325, 0xE55C, 0x9326, 0xE55D, 0x9327, 0xE55E, 0x9328, 0xE55F, 0x9329, 0xE560, 0x932A, 0xE561, 0x932B, - 0xE562, 0x932C, 0xE563, 0x932D, 0xE564, 0x932E, 0xE565, 0x932F, 0xE566, 0x9330, 0xE567, 0x9331, 0xE568, 0x9332, 0xE569, 0x9333, - 0xE56A, 0x9334, 0xE56B, 0x9335, 0xE56C, 0x9336, 0xE56D, 0x9337, 0xE56E, 0x9338, 0xE56F, 0x9339, 0xE570, 0x933A, 0xE571, 0x933B, - 0xE572, 0x933C, 0xE573, 0x933D, 0xE574, 0x933F, 0xE575, 0x9340, 0xE576, 0x9341, 0xE577, 0x9342, 0xE578, 0x9343, 0xE579, 0x9344, - 0xE57A, 0x9345, 0xE57B, 0x9346, 0xE57C, 0x9347, 0xE57D, 0x9348, 0xE57E, 0x9349, 0xE580, 0x934A, 0xE581, 0x934B, 0xE582, 0x934C, - 0xE583, 0x934D, 0xE584, 0x934E, 0xE585, 0x934F, 0xE586, 0x9350, 0xE587, 0x9351, 0xE588, 0x9352, 0xE589, 0x9353, 0xE58A, 0x9354, - 0xE58B, 0x9355, 0xE58C, 0x9356, 0xE58D, 0x9357, 0xE58E, 0x9358, 0xE58F, 0x9359, 0xE590, 0x935A, 0xE591, 0x935B, 0xE592, 0x935C, - 0xE593, 0x935D, 0xE594, 0x935E, 0xE595, 0x935F, 0xE596, 0x9360, 0xE597, 0x9361, 0xE598, 0x9362, 0xE599, 0x9363, 0xE59A, 0x9364, - 0xE59B, 0x9365, 0xE59C, 0x9366, 0xE59D, 0x9367, 0xE59E, 0x9368, 0xE59F, 0x9369, 0xE5A0, 0x936B, 0xE5A1, 0x6FC9, 0xE5A2, 0x6FA7, - 0xE5A3, 0x6FB9, 0xE5A4, 0x6FB6, 0xE5A5, 0x6FC2, 0xE5A6, 0x6FE1, 0xE5A7, 0x6FEE, 0xE5A8, 0x6FDE, 0xE5A9, 0x6FE0, 0xE5AA, 0x6FEF, - 0xE5AB, 0x701A, 0xE5AC, 0x7023, 0xE5AD, 0x701B, 0xE5AE, 0x7039, 0xE5AF, 0x7035, 0xE5B0, 0x704F, 0xE5B1, 0x705E, 0xE5B2, 0x5B80, - 0xE5B3, 0x5B84, 0xE5B4, 0x5B95, 0xE5B5, 0x5B93, 0xE5B6, 0x5BA5, 0xE5B7, 0x5BB8, 0xE5B8, 0x752F, 0xE5B9, 0x9A9E, 0xE5BA, 0x6434, - 0xE5BB, 0x5BE4, 0xE5BC, 0x5BEE, 0xE5BD, 0x8930, 0xE5BE, 0x5BF0, 0xE5BF, 0x8E47, 0xE5C0, 0x8B07, 0xE5C1, 0x8FB6, 0xE5C2, 0x8FD3, - 0xE5C3, 0x8FD5, 0xE5C4, 0x8FE5, 0xE5C5, 0x8FEE, 0xE5C6, 0x8FE4, 0xE5C7, 0x8FE9, 0xE5C8, 0x8FE6, 0xE5C9, 0x8FF3, 0xE5CA, 0x8FE8, - 0xE5CB, 0x9005, 0xE5CC, 0x9004, 0xE5CD, 0x900B, 0xE5CE, 0x9026, 0xE5CF, 0x9011, 0xE5D0, 0x900D, 0xE5D1, 0x9016, 0xE5D2, 0x9021, - 0xE5D3, 0x9035, 0xE5D4, 0x9036, 0xE5D5, 0x902D, 0xE5D6, 0x902F, 0xE5D7, 0x9044, 0xE5D8, 0x9051, 0xE5D9, 0x9052, 0xE5DA, 0x9050, - 0xE5DB, 0x9068, 0xE5DC, 0x9058, 0xE5DD, 0x9062, 0xE5DE, 0x905B, 0xE5DF, 0x66B9, 0xE5E0, 0x9074, 0xE5E1, 0x907D, 0xE5E2, 0x9082, - 0xE5E3, 0x9088, 0xE5E4, 0x9083, 0xE5E5, 0x908B, 0xE5E6, 0x5F50, 0xE5E7, 0x5F57, 0xE5E8, 0x5F56, 0xE5E9, 0x5F58, 0xE5EA, 0x5C3B, - 0xE5EB, 0x54AB, 0xE5EC, 0x5C50, 0xE5ED, 0x5C59, 0xE5EE, 0x5B71, 0xE5EF, 0x5C63, 0xE5F0, 0x5C66, 0xE5F1, 0x7FBC, 0xE5F2, 0x5F2A, - 0xE5F3, 0x5F29, 0xE5F4, 0x5F2D, 0xE5F5, 0x8274, 0xE5F6, 0x5F3C, 0xE5F7, 0x9B3B, 0xE5F8, 0x5C6E, 0xE5F9, 0x5981, 0xE5FA, 0x5983, - 0xE5FB, 0x598D, 0xE5FC, 0x59A9, 0xE5FD, 0x59AA, 0xE5FE, 0x59A3, 0xE640, 0x936C, 0xE641, 0x936D, 0xE642, 0x936E, 0xE643, 0x936F, - 0xE644, 0x9370, 0xE645, 0x9371, 0xE646, 0x9372, 0xE647, 0x9373, 0xE648, 0x9374, 0xE649, 0x9375, 0xE64A, 0x9376, 0xE64B, 0x9377, - 0xE64C, 0x9378, 0xE64D, 0x9379, 0xE64E, 0x937A, 0xE64F, 0x937B, 0xE650, 0x937C, 0xE651, 0x937D, 0xE652, 0x937E, 0xE653, 0x937F, - 0xE654, 0x9380, 0xE655, 0x9381, 0xE656, 0x9382, 0xE657, 0x9383, 0xE658, 0x9384, 0xE659, 0x9385, 0xE65A, 0x9386, 0xE65B, 0x9387, - 0xE65C, 0x9388, 0xE65D, 0x9389, 0xE65E, 0x938A, 0xE65F, 0x938B, 0xE660, 0x938C, 0xE661, 0x938D, 0xE662, 0x938E, 0xE663, 0x9390, - 0xE664, 0x9391, 0xE665, 0x9392, 0xE666, 0x9393, 0xE667, 0x9394, 0xE668, 0x9395, 0xE669, 0x9396, 0xE66A, 0x9397, 0xE66B, 0x9398, - 0xE66C, 0x9399, 0xE66D, 0x939A, 0xE66E, 0x939B, 0xE66F, 0x939C, 0xE670, 0x939D, 0xE671, 0x939E, 0xE672, 0x939F, 0xE673, 0x93A0, - 0xE674, 0x93A1, 0xE675, 0x93A2, 0xE676, 0x93A3, 0xE677, 0x93A4, 0xE678, 0x93A5, 0xE679, 0x93A6, 0xE67A, 0x93A7, 0xE67B, 0x93A8, - 0xE67C, 0x93A9, 0xE67D, 0x93AA, 0xE67E, 0x93AB, 0xE680, 0x93AC, 0xE681, 0x93AD, 0xE682, 0x93AE, 0xE683, 0x93AF, 0xE684, 0x93B0, - 0xE685, 0x93B1, 0xE686, 0x93B2, 0xE687, 0x93B3, 0xE688, 0x93B4, 0xE689, 0x93B5, 0xE68A, 0x93B6, 0xE68B, 0x93B7, 0xE68C, 0x93B8, - 0xE68D, 0x93B9, 0xE68E, 0x93BA, 0xE68F, 0x93BB, 0xE690, 0x93BC, 0xE691, 0x93BD, 0xE692, 0x93BE, 0xE693, 0x93BF, 0xE694, 0x93C0, - 0xE695, 0x93C1, 0xE696, 0x93C2, 0xE697, 0x93C3, 0xE698, 0x93C4, 0xE699, 0x93C5, 0xE69A, 0x93C6, 0xE69B, 0x93C7, 0xE69C, 0x93C8, - 0xE69D, 0x93C9, 0xE69E, 0x93CB, 0xE69F, 0x93CC, 0xE6A0, 0x93CD, 0xE6A1, 0x5997, 0xE6A2, 0x59CA, 0xE6A3, 0x59AB, 0xE6A4, 0x599E, - 0xE6A5, 0x59A4, 0xE6A6, 0x59D2, 0xE6A7, 0x59B2, 0xE6A8, 0x59AF, 0xE6A9, 0x59D7, 0xE6AA, 0x59BE, 0xE6AB, 0x5A05, 0xE6AC, 0x5A06, - 0xE6AD, 0x59DD, 0xE6AE, 0x5A08, 0xE6AF, 0x59E3, 0xE6B0, 0x59D8, 0xE6B1, 0x59F9, 0xE6B2, 0x5A0C, 0xE6B3, 0x5A09, 0xE6B4, 0x5A32, - 0xE6B5, 0x5A34, 0xE6B6, 0x5A11, 0xE6B7, 0x5A23, 0xE6B8, 0x5A13, 0xE6B9, 0x5A40, 0xE6BA, 0x5A67, 0xE6BB, 0x5A4A, 0xE6BC, 0x5A55, - 0xE6BD, 0x5A3C, 0xE6BE, 0x5A62, 0xE6BF, 0x5A75, 0xE6C0, 0x80EC, 0xE6C1, 0x5AAA, 0xE6C2, 0x5A9B, 0xE6C3, 0x5A77, 0xE6C4, 0x5A7A, - 0xE6C5, 0x5ABE, 0xE6C6, 0x5AEB, 0xE6C7, 0x5AB2, 0xE6C8, 0x5AD2, 0xE6C9, 0x5AD4, 0xE6CA, 0x5AB8, 0xE6CB, 0x5AE0, 0xE6CC, 0x5AE3, - 0xE6CD, 0x5AF1, 0xE6CE, 0x5AD6, 0xE6CF, 0x5AE6, 0xE6D0, 0x5AD8, 0xE6D1, 0x5ADC, 0xE6D2, 0x5B09, 0xE6D3, 0x5B17, 0xE6D4, 0x5B16, - 0xE6D5, 0x5B32, 0xE6D6, 0x5B37, 0xE6D7, 0x5B40, 0xE6D8, 0x5C15, 0xE6D9, 0x5C1C, 0xE6DA, 0x5B5A, 0xE6DB, 0x5B65, 0xE6DC, 0x5B73, - 0xE6DD, 0x5B51, 0xE6DE, 0x5B53, 0xE6DF, 0x5B62, 0xE6E0, 0x9A75, 0xE6E1, 0x9A77, 0xE6E2, 0x9A78, 0xE6E3, 0x9A7A, 0xE6E4, 0x9A7F, - 0xE6E5, 0x9A7D, 0xE6E6, 0x9A80, 0xE6E7, 0x9A81, 0xE6E8, 0x9A85, 0xE6E9, 0x9A88, 0xE6EA, 0x9A8A, 0xE6EB, 0x9A90, 0xE6EC, 0x9A92, - 0xE6ED, 0x9A93, 0xE6EE, 0x9A96, 0xE6EF, 0x9A98, 0xE6F0, 0x9A9B, 0xE6F1, 0x9A9C, 0xE6F2, 0x9A9D, 0xE6F3, 0x9A9F, 0xE6F4, 0x9AA0, - 0xE6F5, 0x9AA2, 0xE6F6, 0x9AA3, 0xE6F7, 0x9AA5, 0xE6F8, 0x9AA7, 0xE6F9, 0x7E9F, 0xE6FA, 0x7EA1, 0xE6FB, 0x7EA3, 0xE6FC, 0x7EA5, - 0xE6FD, 0x7EA8, 0xE6FE, 0x7EA9, 0xE740, 0x93CE, 0xE741, 0x93CF, 0xE742, 0x93D0, 0xE743, 0x93D1, 0xE744, 0x93D2, 0xE745, 0x93D3, - 0xE746, 0x93D4, 0xE747, 0x93D5, 0xE748, 0x93D7, 0xE749, 0x93D8, 0xE74A, 0x93D9, 0xE74B, 0x93DA, 0xE74C, 0x93DB, 0xE74D, 0x93DC, - 0xE74E, 0x93DD, 0xE74F, 0x93DE, 0xE750, 0x93DF, 0xE751, 0x93E0, 0xE752, 0x93E1, 0xE753, 0x93E2, 0xE754, 0x93E3, 0xE755, 0x93E4, - 0xE756, 0x93E5, 0xE757, 0x93E6, 0xE758, 0x93E7, 0xE759, 0x93E8, 0xE75A, 0x93E9, 0xE75B, 0x93EA, 0xE75C, 0x93EB, 0xE75D, 0x93EC, - 0xE75E, 0x93ED, 0xE75F, 0x93EE, 0xE760, 0x93EF, 0xE761, 0x93F0, 0xE762, 0x93F1, 0xE763, 0x93F2, 0xE764, 0x93F3, 0xE765, 0x93F4, - 0xE766, 0x93F5, 0xE767, 0x93F6, 0xE768, 0x93F7, 0xE769, 0x93F8, 0xE76A, 0x93F9, 0xE76B, 0x93FA, 0xE76C, 0x93FB, 0xE76D, 0x93FC, - 0xE76E, 0x93FD, 0xE76F, 0x93FE, 0xE770, 0x93FF, 0xE771, 0x9400, 0xE772, 0x9401, 0xE773, 0x9402, 0xE774, 0x9403, 0xE775, 0x9404, - 0xE776, 0x9405, 0xE777, 0x9406, 0xE778, 0x9407, 0xE779, 0x9408, 0xE77A, 0x9409, 0xE77B, 0x940A, 0xE77C, 0x940B, 0xE77D, 0x940C, - 0xE77E, 0x940D, 0xE780, 0x940E, 0xE781, 0x940F, 0xE782, 0x9410, 0xE783, 0x9411, 0xE784, 0x9412, 0xE785, 0x9413, 0xE786, 0x9414, - 0xE787, 0x9415, 0xE788, 0x9416, 0xE789, 0x9417, 0xE78A, 0x9418, 0xE78B, 0x9419, 0xE78C, 0x941A, 0xE78D, 0x941B, 0xE78E, 0x941C, - 0xE78F, 0x941D, 0xE790, 0x941E, 0xE791, 0x941F, 0xE792, 0x9420, 0xE793, 0x9421, 0xE794, 0x9422, 0xE795, 0x9423, 0xE796, 0x9424, - 0xE797, 0x9425, 0xE798, 0x9426, 0xE799, 0x9427, 0xE79A, 0x9428, 0xE79B, 0x9429, 0xE79C, 0x942A, 0xE79D, 0x942B, 0xE79E, 0x942C, - 0xE79F, 0x942D, 0xE7A0, 0x942E, 0xE7A1, 0x7EAD, 0xE7A2, 0x7EB0, 0xE7A3, 0x7EBE, 0xE7A4, 0x7EC0, 0xE7A5, 0x7EC1, 0xE7A6, 0x7EC2, - 0xE7A7, 0x7EC9, 0xE7A8, 0x7ECB, 0xE7A9, 0x7ECC, 0xE7AA, 0x7ED0, 0xE7AB, 0x7ED4, 0xE7AC, 0x7ED7, 0xE7AD, 0x7EDB, 0xE7AE, 0x7EE0, - 0xE7AF, 0x7EE1, 0xE7B0, 0x7EE8, 0xE7B1, 0x7EEB, 0xE7B2, 0x7EEE, 0xE7B3, 0x7EEF, 0xE7B4, 0x7EF1, 0xE7B5, 0x7EF2, 0xE7B6, 0x7F0D, - 0xE7B7, 0x7EF6, 0xE7B8, 0x7EFA, 0xE7B9, 0x7EFB, 0xE7BA, 0x7EFE, 0xE7BB, 0x7F01, 0xE7BC, 0x7F02, 0xE7BD, 0x7F03, 0xE7BE, 0x7F07, - 0xE7BF, 0x7F08, 0xE7C0, 0x7F0B, 0xE7C1, 0x7F0C, 0xE7C2, 0x7F0F, 0xE7C3, 0x7F11, 0xE7C4, 0x7F12, 0xE7C5, 0x7F17, 0xE7C6, 0x7F19, - 0xE7C7, 0x7F1C, 0xE7C8, 0x7F1B, 0xE7C9, 0x7F1F, 0xE7CA, 0x7F21, 0xE7CB, 0x7F22, 0xE7CC, 0x7F23, 0xE7CD, 0x7F24, 0xE7CE, 0x7F25, - 0xE7CF, 0x7F26, 0xE7D0, 0x7F27, 0xE7D1, 0x7F2A, 0xE7D2, 0x7F2B, 0xE7D3, 0x7F2C, 0xE7D4, 0x7F2D, 0xE7D5, 0x7F2F, 0xE7D6, 0x7F30, - 0xE7D7, 0x7F31, 0xE7D8, 0x7F32, 0xE7D9, 0x7F33, 0xE7DA, 0x7F35, 0xE7DB, 0x5E7A, 0xE7DC, 0x757F, 0xE7DD, 0x5DDB, 0xE7DE, 0x753E, - 0xE7DF, 0x9095, 0xE7E0, 0x738E, 0xE7E1, 0x7391, 0xE7E2, 0x73AE, 0xE7E3, 0x73A2, 0xE7E4, 0x739F, 0xE7E5, 0x73CF, 0xE7E6, 0x73C2, - 0xE7E7, 0x73D1, 0xE7E8, 0x73B7, 0xE7E9, 0x73B3, 0xE7EA, 0x73C0, 0xE7EB, 0x73C9, 0xE7EC, 0x73C8, 0xE7ED, 0x73E5, 0xE7EE, 0x73D9, - 0xE7EF, 0x987C, 0xE7F0, 0x740A, 0xE7F1, 0x73E9, 0xE7F2, 0x73E7, 0xE7F3, 0x73DE, 0xE7F4, 0x73BA, 0xE7F5, 0x73F2, 0xE7F6, 0x740F, - 0xE7F7, 0x742A, 0xE7F8, 0x745B, 0xE7F9, 0x7426, 0xE7FA, 0x7425, 0xE7FB, 0x7428, 0xE7FC, 0x7430, 0xE7FD, 0x742E, 0xE7FE, 0x742C, - 0xE840, 0x942F, 0xE841, 0x9430, 0xE842, 0x9431, 0xE843, 0x9432, 0xE844, 0x9433, 0xE845, 0x9434, 0xE846, 0x9435, 0xE847, 0x9436, - 0xE848, 0x9437, 0xE849, 0x9438, 0xE84A, 0x9439, 0xE84B, 0x943A, 0xE84C, 0x943B, 0xE84D, 0x943C, 0xE84E, 0x943D, 0xE84F, 0x943F, - 0xE850, 0x9440, 0xE851, 0x9441, 0xE852, 0x9442, 0xE853, 0x9443, 0xE854, 0x9444, 0xE855, 0x9445, 0xE856, 0x9446, 0xE857, 0x9447, - 0xE858, 0x9448, 0xE859, 0x9449, 0xE85A, 0x944A, 0xE85B, 0x944B, 0xE85C, 0x944C, 0xE85D, 0x944D, 0xE85E, 0x944E, 0xE85F, 0x944F, - 0xE860, 0x9450, 0xE861, 0x9451, 0xE862, 0x9452, 0xE863, 0x9453, 0xE864, 0x9454, 0xE865, 0x9455, 0xE866, 0x9456, 0xE867, 0x9457, - 0xE868, 0x9458, 0xE869, 0x9459, 0xE86A, 0x945A, 0xE86B, 0x945B, 0xE86C, 0x945C, 0xE86D, 0x945D, 0xE86E, 0x945E, 0xE86F, 0x945F, - 0xE870, 0x9460, 0xE871, 0x9461, 0xE872, 0x9462, 0xE873, 0x9463, 0xE874, 0x9464, 0xE875, 0x9465, 0xE876, 0x9466, 0xE877, 0x9467, - 0xE878, 0x9468, 0xE879, 0x9469, 0xE87A, 0x946A, 0xE87B, 0x946C, 0xE87C, 0x946D, 0xE87D, 0x946E, 0xE87E, 0x946F, 0xE880, 0x9470, - 0xE881, 0x9471, 0xE882, 0x9472, 0xE883, 0x9473, 0xE884, 0x9474, 0xE885, 0x9475, 0xE886, 0x9476, 0xE887, 0x9477, 0xE888, 0x9478, - 0xE889, 0x9479, 0xE88A, 0x947A, 0xE88B, 0x947B, 0xE88C, 0x947C, 0xE88D, 0x947D, 0xE88E, 0x947E, 0xE88F, 0x947F, 0xE890, 0x9480, - 0xE891, 0x9481, 0xE892, 0x9482, 0xE893, 0x9483, 0xE894, 0x9484, 0xE895, 0x9491, 0xE896, 0x9496, 0xE897, 0x9498, 0xE898, 0x94C7, - 0xE899, 0x94CF, 0xE89A, 0x94D3, 0xE89B, 0x94D4, 0xE89C, 0x94DA, 0xE89D, 0x94E6, 0xE89E, 0x94FB, 0xE89F, 0x951C, 0xE8A0, 0x9520, - 0xE8A1, 0x741B, 0xE8A2, 0x741A, 0xE8A3, 0x7441, 0xE8A4, 0x745C, 0xE8A5, 0x7457, 0xE8A6, 0x7455, 0xE8A7, 0x7459, 0xE8A8, 0x7477, - 0xE8A9, 0x746D, 0xE8AA, 0x747E, 0xE8AB, 0x749C, 0xE8AC, 0x748E, 0xE8AD, 0x7480, 0xE8AE, 0x7481, 0xE8AF, 0x7487, 0xE8B0, 0x748B, - 0xE8B1, 0x749E, 0xE8B2, 0x74A8, 0xE8B3, 0x74A9, 0xE8B4, 0x7490, 0xE8B5, 0x74A7, 0xE8B6, 0x74D2, 0xE8B7, 0x74BA, 0xE8B8, 0x97EA, - 0xE8B9, 0x97EB, 0xE8BA, 0x97EC, 0xE8BB, 0x674C, 0xE8BC, 0x6753, 0xE8BD, 0x675E, 0xE8BE, 0x6748, 0xE8BF, 0x6769, 0xE8C0, 0x67A5, - 0xE8C1, 0x6787, 0xE8C2, 0x676A, 0xE8C3, 0x6773, 0xE8C4, 0x6798, 0xE8C5, 0x67A7, 0xE8C6, 0x6775, 0xE8C7, 0x67A8, 0xE8C8, 0x679E, - 0xE8C9, 0x67AD, 0xE8CA, 0x678B, 0xE8CB, 0x6777, 0xE8CC, 0x677C, 0xE8CD, 0x67F0, 0xE8CE, 0x6809, 0xE8CF, 0x67D8, 0xE8D0, 0x680A, - 0xE8D1, 0x67E9, 0xE8D2, 0x67B0, 0xE8D3, 0x680C, 0xE8D4, 0x67D9, 0xE8D5, 0x67B5, 0xE8D6, 0x67DA, 0xE8D7, 0x67B3, 0xE8D8, 0x67DD, - 0xE8D9, 0x6800, 0xE8DA, 0x67C3, 0xE8DB, 0x67B8, 0xE8DC, 0x67E2, 0xE8DD, 0x680E, 0xE8DE, 0x67C1, 0xE8DF, 0x67FD, 0xE8E0, 0x6832, - 0xE8E1, 0x6833, 0xE8E2, 0x6860, 0xE8E3, 0x6861, 0xE8E4, 0x684E, 0xE8E5, 0x6862, 0xE8E6, 0x6844, 0xE8E7, 0x6864, 0xE8E8, 0x6883, - 0xE8E9, 0x681D, 0xE8EA, 0x6855, 0xE8EB, 0x6866, 0xE8EC, 0x6841, 0xE8ED, 0x6867, 0xE8EE, 0x6840, 0xE8EF, 0x683E, 0xE8F0, 0x684A, - 0xE8F1, 0x6849, 0xE8F2, 0x6829, 0xE8F3, 0x68B5, 0xE8F4, 0x688F, 0xE8F5, 0x6874, 0xE8F6, 0x6877, 0xE8F7, 0x6893, 0xE8F8, 0x686B, - 0xE8F9, 0x68C2, 0xE8FA, 0x696E, 0xE8FB, 0x68FC, 0xE8FC, 0x691F, 0xE8FD, 0x6920, 0xE8FE, 0x68F9, 0xE940, 0x9527, 0xE941, 0x9533, - 0xE942, 0x953D, 0xE943, 0x9543, 0xE944, 0x9548, 0xE945, 0x954B, 0xE946, 0x9555, 0xE947, 0x955A, 0xE948, 0x9560, 0xE949, 0x956E, - 0xE94A, 0x9574, 0xE94B, 0x9575, 0xE94C, 0x9577, 0xE94D, 0x9578, 0xE94E, 0x9579, 0xE94F, 0x957A, 0xE950, 0x957B, 0xE951, 0x957C, - 0xE952, 0x957D, 0xE953, 0x957E, 0xE954, 0x9580, 0xE955, 0x9581, 0xE956, 0x9582, 0xE957, 0x9583, 0xE958, 0x9584, 0xE959, 0x9585, - 0xE95A, 0x9586, 0xE95B, 0x9587, 0xE95C, 0x9588, 0xE95D, 0x9589, 0xE95E, 0x958A, 0xE95F, 0x958B, 0xE960, 0x958C, 0xE961, 0x958D, - 0xE962, 0x958E, 0xE963, 0x958F, 0xE964, 0x9590, 0xE965, 0x9591, 0xE966, 0x9592, 0xE967, 0x9593, 0xE968, 0x9594, 0xE969, 0x9595, - 0xE96A, 0x9596, 0xE96B, 0x9597, 0xE96C, 0x9598, 0xE96D, 0x9599, 0xE96E, 0x959A, 0xE96F, 0x959B, 0xE970, 0x959C, 0xE971, 0x959D, - 0xE972, 0x959E, 0xE973, 0x959F, 0xE974, 0x95A0, 0xE975, 0x95A1, 0xE976, 0x95A2, 0xE977, 0x95A3, 0xE978, 0x95A4, 0xE979, 0x95A5, - 0xE97A, 0x95A6, 0xE97B, 0x95A7, 0xE97C, 0x95A8, 0xE97D, 0x95A9, 0xE97E, 0x95AA, 0xE980, 0x95AB, 0xE981, 0x95AC, 0xE982, 0x95AD, - 0xE983, 0x95AE, 0xE984, 0x95AF, 0xE985, 0x95B0, 0xE986, 0x95B1, 0xE987, 0x95B2, 0xE988, 0x95B3, 0xE989, 0x95B4, 0xE98A, 0x95B5, - 0xE98B, 0x95B6, 0xE98C, 0x95B7, 0xE98D, 0x95B8, 0xE98E, 0x95B9, 0xE98F, 0x95BA, 0xE990, 0x95BB, 0xE991, 0x95BC, 0xE992, 0x95BD, - 0xE993, 0x95BE, 0xE994, 0x95BF, 0xE995, 0x95C0, 0xE996, 0x95C1, 0xE997, 0x95C2, 0xE998, 0x95C3, 0xE999, 0x95C4, 0xE99A, 0x95C5, - 0xE99B, 0x95C6, 0xE99C, 0x95C7, 0xE99D, 0x95C8, 0xE99E, 0x95C9, 0xE99F, 0x95CA, 0xE9A0, 0x95CB, 0xE9A1, 0x6924, 0xE9A2, 0x68F0, - 0xE9A3, 0x690B, 0xE9A4, 0x6901, 0xE9A5, 0x6957, 0xE9A6, 0x68E3, 0xE9A7, 0x6910, 0xE9A8, 0x6971, 0xE9A9, 0x6939, 0xE9AA, 0x6960, - 0xE9AB, 0x6942, 0xE9AC, 0x695D, 0xE9AD, 0x6984, 0xE9AE, 0x696B, 0xE9AF, 0x6980, 0xE9B0, 0x6998, 0xE9B1, 0x6978, 0xE9B2, 0x6934, - 0xE9B3, 0x69CC, 0xE9B4, 0x6987, 0xE9B5, 0x6988, 0xE9B6, 0x69CE, 0xE9B7, 0x6989, 0xE9B8, 0x6966, 0xE9B9, 0x6963, 0xE9BA, 0x6979, - 0xE9BB, 0x699B, 0xE9BC, 0x69A7, 0xE9BD, 0x69BB, 0xE9BE, 0x69AB, 0xE9BF, 0x69AD, 0xE9C0, 0x69D4, 0xE9C1, 0x69B1, 0xE9C2, 0x69C1, - 0xE9C3, 0x69CA, 0xE9C4, 0x69DF, 0xE9C5, 0x6995, 0xE9C6, 0x69E0, 0xE9C7, 0x698D, 0xE9C8, 0x69FF, 0xE9C9, 0x6A2F, 0xE9CA, 0x69ED, - 0xE9CB, 0x6A17, 0xE9CC, 0x6A18, 0xE9CD, 0x6A65, 0xE9CE, 0x69F2, 0xE9CF, 0x6A44, 0xE9D0, 0x6A3E, 0xE9D1, 0x6AA0, 0xE9D2, 0x6A50, - 0xE9D3, 0x6A5B, 0xE9D4, 0x6A35, 0xE9D5, 0x6A8E, 0xE9D6, 0x6A79, 0xE9D7, 0x6A3D, 0xE9D8, 0x6A28, 0xE9D9, 0x6A58, 0xE9DA, 0x6A7C, - 0xE9DB, 0x6A91, 0xE9DC, 0x6A90, 0xE9DD, 0x6AA9, 0xE9DE, 0x6A97, 0xE9DF, 0x6AAB, 0xE9E0, 0x7337, 0xE9E1, 0x7352, 0xE9E2, 0x6B81, - 0xE9E3, 0x6B82, 0xE9E4, 0x6B87, 0xE9E5, 0x6B84, 0xE9E6, 0x6B92, 0xE9E7, 0x6B93, 0xE9E8, 0x6B8D, 0xE9E9, 0x6B9A, 0xE9EA, 0x6B9B, - 0xE9EB, 0x6BA1, 0xE9EC, 0x6BAA, 0xE9ED, 0x8F6B, 0xE9EE, 0x8F6D, 0xE9EF, 0x8F71, 0xE9F0, 0x8F72, 0xE9F1, 0x8F73, 0xE9F2, 0x8F75, - 0xE9F3, 0x8F76, 0xE9F4, 0x8F78, 0xE9F5, 0x8F77, 0xE9F6, 0x8F79, 0xE9F7, 0x8F7A, 0xE9F8, 0x8F7C, 0xE9F9, 0x8F7E, 0xE9FA, 0x8F81, - 0xE9FB, 0x8F82, 0xE9FC, 0x8F84, 0xE9FD, 0x8F87, 0xE9FE, 0x8F8B, 0xEA40, 0x95CC, 0xEA41, 0x95CD, 0xEA42, 0x95CE, 0xEA43, 0x95CF, - 0xEA44, 0x95D0, 0xEA45, 0x95D1, 0xEA46, 0x95D2, 0xEA47, 0x95D3, 0xEA48, 0x95D4, 0xEA49, 0x95D5, 0xEA4A, 0x95D6, 0xEA4B, 0x95D7, - 0xEA4C, 0x95D8, 0xEA4D, 0x95D9, 0xEA4E, 0x95DA, 0xEA4F, 0x95DB, 0xEA50, 0x95DC, 0xEA51, 0x95DD, 0xEA52, 0x95DE, 0xEA53, 0x95DF, - 0xEA54, 0x95E0, 0xEA55, 0x95E1, 0xEA56, 0x95E2, 0xEA57, 0x95E3, 0xEA58, 0x95E4, 0xEA59, 0x95E5, 0xEA5A, 0x95E6, 0xEA5B, 0x95E7, - 0xEA5C, 0x95EC, 0xEA5D, 0x95FF, 0xEA5E, 0x9607, 0xEA5F, 0x9613, 0xEA60, 0x9618, 0xEA61, 0x961B, 0xEA62, 0x961E, 0xEA63, 0x9620, - 0xEA64, 0x9623, 0xEA65, 0x9624, 0xEA66, 0x9625, 0xEA67, 0x9626, 0xEA68, 0x9627, 0xEA69, 0x9628, 0xEA6A, 0x9629, 0xEA6B, 0x962B, - 0xEA6C, 0x962C, 0xEA6D, 0x962D, 0xEA6E, 0x962F, 0xEA6F, 0x9630, 0xEA70, 0x9637, 0xEA71, 0x9638, 0xEA72, 0x9639, 0xEA73, 0x963A, - 0xEA74, 0x963E, 0xEA75, 0x9641, 0xEA76, 0x9643, 0xEA77, 0x964A, 0xEA78, 0x964E, 0xEA79, 0x964F, 0xEA7A, 0x9651, 0xEA7B, 0x9652, - 0xEA7C, 0x9653, 0xEA7D, 0x9656, 0xEA7E, 0x9657, 0xEA80, 0x9658, 0xEA81, 0x9659, 0xEA82, 0x965A, 0xEA83, 0x965C, 0xEA84, 0x965D, - 0xEA85, 0x965E, 0xEA86, 0x9660, 0xEA87, 0x9663, 0xEA88, 0x9665, 0xEA89, 0x9666, 0xEA8A, 0x966B, 0xEA8B, 0x966D, 0xEA8C, 0x966E, - 0xEA8D, 0x966F, 0xEA8E, 0x9670, 0xEA8F, 0x9671, 0xEA90, 0x9673, 0xEA91, 0x9678, 0xEA92, 0x9679, 0xEA93, 0x967A, 0xEA94, 0x967B, - 0xEA95, 0x967C, 0xEA96, 0x967D, 0xEA97, 0x967E, 0xEA98, 0x967F, 0xEA99, 0x9680, 0xEA9A, 0x9681, 0xEA9B, 0x9682, 0xEA9C, 0x9683, - 0xEA9D, 0x9684, 0xEA9E, 0x9687, 0xEA9F, 0x9689, 0xEAA0, 0x968A, 0xEAA1, 0x8F8D, 0xEAA2, 0x8F8E, 0xEAA3, 0x8F8F, 0xEAA4, 0x8F98, - 0xEAA5, 0x8F9A, 0xEAA6, 0x8ECE, 0xEAA7, 0x620B, 0xEAA8, 0x6217, 0xEAA9, 0x621B, 0xEAAA, 0x621F, 0xEAAB, 0x6222, 0xEAAC, 0x6221, - 0xEAAD, 0x6225, 0xEAAE, 0x6224, 0xEAAF, 0x622C, 0xEAB0, 0x81E7, 0xEAB1, 0x74EF, 0xEAB2, 0x74F4, 0xEAB3, 0x74FF, 0xEAB4, 0x750F, - 0xEAB5, 0x7511, 0xEAB6, 0x7513, 0xEAB7, 0x6534, 0xEAB8, 0x65EE, 0xEAB9, 0x65EF, 0xEABA, 0x65F0, 0xEABB, 0x660A, 0xEABC, 0x6619, - 0xEABD, 0x6772, 0xEABE, 0x6603, 0xEABF, 0x6615, 0xEAC0, 0x6600, 0xEAC1, 0x7085, 0xEAC2, 0x66F7, 0xEAC3, 0x661D, 0xEAC4, 0x6634, - 0xEAC5, 0x6631, 0xEAC6, 0x6636, 0xEAC7, 0x6635, 0xEAC8, 0x8006, 0xEAC9, 0x665F, 0xEACA, 0x6654, 0xEACB, 0x6641, 0xEACC, 0x664F, - 0xEACD, 0x6656, 0xEACE, 0x6661, 0xEACF, 0x6657, 0xEAD0, 0x6677, 0xEAD1, 0x6684, 0xEAD2, 0x668C, 0xEAD3, 0x66A7, 0xEAD4, 0x669D, - 0xEAD5, 0x66BE, 0xEAD6, 0x66DB, 0xEAD7, 0x66DC, 0xEAD8, 0x66E6, 0xEAD9, 0x66E9, 0xEADA, 0x8D32, 0xEADB, 0x8D33, 0xEADC, 0x8D36, - 0xEADD, 0x8D3B, 0xEADE, 0x8D3D, 0xEADF, 0x8D40, 0xEAE0, 0x8D45, 0xEAE1, 0x8D46, 0xEAE2, 0x8D48, 0xEAE3, 0x8D49, 0xEAE4, 0x8D47, - 0xEAE5, 0x8D4D, 0xEAE6, 0x8D55, 0xEAE7, 0x8D59, 0xEAE8, 0x89C7, 0xEAE9, 0x89CA, 0xEAEA, 0x89CB, 0xEAEB, 0x89CC, 0xEAEC, 0x89CE, - 0xEAED, 0x89CF, 0xEAEE, 0x89D0, 0xEAEF, 0x89D1, 0xEAF0, 0x726E, 0xEAF1, 0x729F, 0xEAF2, 0x725D, 0xEAF3, 0x7266, 0xEAF4, 0x726F, - 0xEAF5, 0x727E, 0xEAF6, 0x727F, 0xEAF7, 0x7284, 0xEAF8, 0x728B, 0xEAF9, 0x728D, 0xEAFA, 0x728F, 0xEAFB, 0x7292, 0xEAFC, 0x6308, - 0xEAFD, 0x6332, 0xEAFE, 0x63B0, 0xEB40, 0x968C, 0xEB41, 0x968E, 0xEB42, 0x9691, 0xEB43, 0x9692, 0xEB44, 0x9693, 0xEB45, 0x9695, - 0xEB46, 0x9696, 0xEB47, 0x969A, 0xEB48, 0x969B, 0xEB49, 0x969D, 0xEB4A, 0x969E, 0xEB4B, 0x969F, 0xEB4C, 0x96A0, 0xEB4D, 0x96A1, - 0xEB4E, 0x96A2, 0xEB4F, 0x96A3, 0xEB50, 0x96A4, 0xEB51, 0x96A5, 0xEB52, 0x96A6, 0xEB53, 0x96A8, 0xEB54, 0x96A9, 0xEB55, 0x96AA, - 0xEB56, 0x96AB, 0xEB57, 0x96AC, 0xEB58, 0x96AD, 0xEB59, 0x96AE, 0xEB5A, 0x96AF, 0xEB5B, 0x96B1, 0xEB5C, 0x96B2, 0xEB5D, 0x96B4, - 0xEB5E, 0x96B5, 0xEB5F, 0x96B7, 0xEB60, 0x96B8, 0xEB61, 0x96BA, 0xEB62, 0x96BB, 0xEB63, 0x96BF, 0xEB64, 0x96C2, 0xEB65, 0x96C3, - 0xEB66, 0x96C8, 0xEB67, 0x96CA, 0xEB68, 0x96CB, 0xEB69, 0x96D0, 0xEB6A, 0x96D1, 0xEB6B, 0x96D3, 0xEB6C, 0x96D4, 0xEB6D, 0x96D6, - 0xEB6E, 0x96D7, 0xEB6F, 0x96D8, 0xEB70, 0x96D9, 0xEB71, 0x96DA, 0xEB72, 0x96DB, 0xEB73, 0x96DC, 0xEB74, 0x96DD, 0xEB75, 0x96DE, - 0xEB76, 0x96DF, 0xEB77, 0x96E1, 0xEB78, 0x96E2, 0xEB79, 0x96E3, 0xEB7A, 0x96E4, 0xEB7B, 0x96E5, 0xEB7C, 0x96E6, 0xEB7D, 0x96E7, - 0xEB7E, 0x96EB, 0xEB80, 0x96EC, 0xEB81, 0x96ED, 0xEB82, 0x96EE, 0xEB83, 0x96F0, 0xEB84, 0x96F1, 0xEB85, 0x96F2, 0xEB86, 0x96F4, - 0xEB87, 0x96F5, 0xEB88, 0x96F8, 0xEB89, 0x96FA, 0xEB8A, 0x96FB, 0xEB8B, 0x96FC, 0xEB8C, 0x96FD, 0xEB8D, 0x96FF, 0xEB8E, 0x9702, - 0xEB8F, 0x9703, 0xEB90, 0x9705, 0xEB91, 0x970A, 0xEB92, 0x970B, 0xEB93, 0x970C, 0xEB94, 0x9710, 0xEB95, 0x9711, 0xEB96, 0x9712, - 0xEB97, 0x9714, 0xEB98, 0x9715, 0xEB99, 0x9717, 0xEB9A, 0x9718, 0xEB9B, 0x9719, 0xEB9C, 0x971A, 0xEB9D, 0x971B, 0xEB9E, 0x971D, - 0xEB9F, 0x971F, 0xEBA0, 0x9720, 0xEBA1, 0x643F, 0xEBA2, 0x64D8, 0xEBA3, 0x8004, 0xEBA4, 0x6BEA, 0xEBA5, 0x6BF3, 0xEBA6, 0x6BFD, - 0xEBA7, 0x6BF5, 0xEBA8, 0x6BF9, 0xEBA9, 0x6C05, 0xEBAA, 0x6C07, 0xEBAB, 0x6C06, 0xEBAC, 0x6C0D, 0xEBAD, 0x6C15, 0xEBAE, 0x6C18, - 0xEBAF, 0x6C19, 0xEBB0, 0x6C1A, 0xEBB1, 0x6C21, 0xEBB2, 0x6C29, 0xEBB3, 0x6C24, 0xEBB4, 0x6C2A, 0xEBB5, 0x6C32, 0xEBB6, 0x6535, - 0xEBB7, 0x6555, 0xEBB8, 0x656B, 0xEBB9, 0x724D, 0xEBBA, 0x7252, 0xEBBB, 0x7256, 0xEBBC, 0x7230, 0xEBBD, 0x8662, 0xEBBE, 0x5216, - 0xEBBF, 0x809F, 0xEBC0, 0x809C, 0xEBC1, 0x8093, 0xEBC2, 0x80BC, 0xEBC3, 0x670A, 0xEBC4, 0x80BD, 0xEBC5, 0x80B1, 0xEBC6, 0x80AB, - 0xEBC7, 0x80AD, 0xEBC8, 0x80B4, 0xEBC9, 0x80B7, 0xEBCA, 0x80E7, 0xEBCB, 0x80E8, 0xEBCC, 0x80E9, 0xEBCD, 0x80EA, 0xEBCE, 0x80DB, - 0xEBCF, 0x80C2, 0xEBD0, 0x80C4, 0xEBD1, 0x80D9, 0xEBD2, 0x80CD, 0xEBD3, 0x80D7, 0xEBD4, 0x6710, 0xEBD5, 0x80DD, 0xEBD6, 0x80EB, - 0xEBD7, 0x80F1, 0xEBD8, 0x80F4, 0xEBD9, 0x80ED, 0xEBDA, 0x810D, 0xEBDB, 0x810E, 0xEBDC, 0x80F2, 0xEBDD, 0x80FC, 0xEBDE, 0x6715, - 0xEBDF, 0x8112, 0xEBE0, 0x8C5A, 0xEBE1, 0x8136, 0xEBE2, 0x811E, 0xEBE3, 0x812C, 0xEBE4, 0x8118, 0xEBE5, 0x8132, 0xEBE6, 0x8148, - 0xEBE7, 0x814C, 0xEBE8, 0x8153, 0xEBE9, 0x8174, 0xEBEA, 0x8159, 0xEBEB, 0x815A, 0xEBEC, 0x8171, 0xEBED, 0x8160, 0xEBEE, 0x8169, - 0xEBEF, 0x817C, 0xEBF0, 0x817D, 0xEBF1, 0x816D, 0xEBF2, 0x8167, 0xEBF3, 0x584D, 0xEBF4, 0x5AB5, 0xEBF5, 0x8188, 0xEBF6, 0x8182, - 0xEBF7, 0x8191, 0xEBF8, 0x6ED5, 0xEBF9, 0x81A3, 0xEBFA, 0x81AA, 0xEBFB, 0x81CC, 0xEBFC, 0x6726, 0xEBFD, 0x81CA, 0xEBFE, 0x81BB, - 0xEC40, 0x9721, 0xEC41, 0x9722, 0xEC42, 0x9723, 0xEC43, 0x9724, 0xEC44, 0x9725, 0xEC45, 0x9726, 0xEC46, 0x9727, 0xEC47, 0x9728, - 0xEC48, 0x9729, 0xEC49, 0x972B, 0xEC4A, 0x972C, 0xEC4B, 0x972E, 0xEC4C, 0x972F, 0xEC4D, 0x9731, 0xEC4E, 0x9733, 0xEC4F, 0x9734, - 0xEC50, 0x9735, 0xEC51, 0x9736, 0xEC52, 0x9737, 0xEC53, 0x973A, 0xEC54, 0x973B, 0xEC55, 0x973C, 0xEC56, 0x973D, 0xEC57, 0x973F, - 0xEC58, 0x9740, 0xEC59, 0x9741, 0xEC5A, 0x9742, 0xEC5B, 0x9743, 0xEC5C, 0x9744, 0xEC5D, 0x9745, 0xEC5E, 0x9746, 0xEC5F, 0x9747, - 0xEC60, 0x9748, 0xEC61, 0x9749, 0xEC62, 0x974A, 0xEC63, 0x974B, 0xEC64, 0x974C, 0xEC65, 0x974D, 0xEC66, 0x974E, 0xEC67, 0x974F, - 0xEC68, 0x9750, 0xEC69, 0x9751, 0xEC6A, 0x9754, 0xEC6B, 0x9755, 0xEC6C, 0x9757, 0xEC6D, 0x9758, 0xEC6E, 0x975A, 0xEC6F, 0x975C, - 0xEC70, 0x975D, 0xEC71, 0x975F, 0xEC72, 0x9763, 0xEC73, 0x9764, 0xEC74, 0x9766, 0xEC75, 0x9767, 0xEC76, 0x9768, 0xEC77, 0x976A, - 0xEC78, 0x976B, 0xEC79, 0x976C, 0xEC7A, 0x976D, 0xEC7B, 0x976E, 0xEC7C, 0x976F, 0xEC7D, 0x9770, 0xEC7E, 0x9771, 0xEC80, 0x9772, - 0xEC81, 0x9775, 0xEC82, 0x9777, 0xEC83, 0x9778, 0xEC84, 0x9779, 0xEC85, 0x977A, 0xEC86, 0x977B, 0xEC87, 0x977D, 0xEC88, 0x977E, - 0xEC89, 0x977F, 0xEC8A, 0x9780, 0xEC8B, 0x9781, 0xEC8C, 0x9782, 0xEC8D, 0x9783, 0xEC8E, 0x9784, 0xEC8F, 0x9786, 0xEC90, 0x9787, - 0xEC91, 0x9788, 0xEC92, 0x9789, 0xEC93, 0x978A, 0xEC94, 0x978C, 0xEC95, 0x978E, 0xEC96, 0x978F, 0xEC97, 0x9790, 0xEC98, 0x9793, - 0xEC99, 0x9795, 0xEC9A, 0x9796, 0xEC9B, 0x9797, 0xEC9C, 0x9799, 0xEC9D, 0x979A, 0xEC9E, 0x979B, 0xEC9F, 0x979C, 0xECA0, 0x979D, - 0xECA1, 0x81C1, 0xECA2, 0x81A6, 0xECA3, 0x6B24, 0xECA4, 0x6B37, 0xECA5, 0x6B39, 0xECA6, 0x6B43, 0xECA7, 0x6B46, 0xECA8, 0x6B59, - 0xECA9, 0x98D1, 0xECAA, 0x98D2, 0xECAB, 0x98D3, 0xECAC, 0x98D5, 0xECAD, 0x98D9, 0xECAE, 0x98DA, 0xECAF, 0x6BB3, 0xECB0, 0x5F40, - 0xECB1, 0x6BC2, 0xECB2, 0x89F3, 0xECB3, 0x6590, 0xECB4, 0x9F51, 0xECB5, 0x6593, 0xECB6, 0x65BC, 0xECB7, 0x65C6, 0xECB8, 0x65C4, - 0xECB9, 0x65C3, 0xECBA, 0x65CC, 0xECBB, 0x65CE, 0xECBC, 0x65D2, 0xECBD, 0x65D6, 0xECBE, 0x7080, 0xECBF, 0x709C, 0xECC0, 0x7096, - 0xECC1, 0x709D, 0xECC2, 0x70BB, 0xECC3, 0x70C0, 0xECC4, 0x70B7, 0xECC5, 0x70AB, 0xECC6, 0x70B1, 0xECC7, 0x70E8, 0xECC8, 0x70CA, - 0xECC9, 0x7110, 0xECCA, 0x7113, 0xECCB, 0x7116, 0xECCC, 0x712F, 0xECCD, 0x7131, 0xECCE, 0x7173, 0xECCF, 0x715C, 0xECD0, 0x7168, - 0xECD1, 0x7145, 0xECD2, 0x7172, 0xECD3, 0x714A, 0xECD4, 0x7178, 0xECD5, 0x717A, 0xECD6, 0x7198, 0xECD7, 0x71B3, 0xECD8, 0x71B5, - 0xECD9, 0x71A8, 0xECDA, 0x71A0, 0xECDB, 0x71E0, 0xECDC, 0x71D4, 0xECDD, 0x71E7, 0xECDE, 0x71F9, 0xECDF, 0x721D, 0xECE0, 0x7228, - 0xECE1, 0x706C, 0xECE2, 0x7118, 0xECE3, 0x7166, 0xECE4, 0x71B9, 0xECE5, 0x623E, 0xECE6, 0x623D, 0xECE7, 0x6243, 0xECE8, 0x6248, - 0xECE9, 0x6249, 0xECEA, 0x793B, 0xECEB, 0x7940, 0xECEC, 0x7946, 0xECED, 0x7949, 0xECEE, 0x795B, 0xECEF, 0x795C, 0xECF0, 0x7953, - 0xECF1, 0x795A, 0xECF2, 0x7962, 0xECF3, 0x7957, 0xECF4, 0x7960, 0xECF5, 0x796F, 0xECF6, 0x7967, 0xECF7, 0x797A, 0xECF8, 0x7985, - 0xECF9, 0x798A, 0xECFA, 0x799A, 0xECFB, 0x79A7, 0xECFC, 0x79B3, 0xECFD, 0x5FD1, 0xECFE, 0x5FD0, 0xED40, 0x979E, 0xED41, 0x979F, - 0xED42, 0x97A1, 0xED43, 0x97A2, 0xED44, 0x97A4, 0xED45, 0x97A5, 0xED46, 0x97A6, 0xED47, 0x97A7, 0xED48, 0x97A8, 0xED49, 0x97A9, - 0xED4A, 0x97AA, 0xED4B, 0x97AC, 0xED4C, 0x97AE, 0xED4D, 0x97B0, 0xED4E, 0x97B1, 0xED4F, 0x97B3, 0xED50, 0x97B5, 0xED51, 0x97B6, - 0xED52, 0x97B7, 0xED53, 0x97B8, 0xED54, 0x97B9, 0xED55, 0x97BA, 0xED56, 0x97BB, 0xED57, 0x97BC, 0xED58, 0x97BD, 0xED59, 0x97BE, - 0xED5A, 0x97BF, 0xED5B, 0x97C0, 0xED5C, 0x97C1, 0xED5D, 0x97C2, 0xED5E, 0x97C3, 0xED5F, 0x97C4, 0xED60, 0x97C5, 0xED61, 0x97C6, - 0xED62, 0x97C7, 0xED63, 0x97C8, 0xED64, 0x97C9, 0xED65, 0x97CA, 0xED66, 0x97CB, 0xED67, 0x97CC, 0xED68, 0x97CD, 0xED69, 0x97CE, - 0xED6A, 0x97CF, 0xED6B, 0x97D0, 0xED6C, 0x97D1, 0xED6D, 0x97D2, 0xED6E, 0x97D3, 0xED6F, 0x97D4, 0xED70, 0x97D5, 0xED71, 0x97D6, - 0xED72, 0x97D7, 0xED73, 0x97D8, 0xED74, 0x97D9, 0xED75, 0x97DA, 0xED76, 0x97DB, 0xED77, 0x97DC, 0xED78, 0x97DD, 0xED79, 0x97DE, - 0xED7A, 0x97DF, 0xED7B, 0x97E0, 0xED7C, 0x97E1, 0xED7D, 0x97E2, 0xED7E, 0x97E3, 0xED80, 0x97E4, 0xED81, 0x97E5, 0xED82, 0x97E8, - 0xED83, 0x97EE, 0xED84, 0x97EF, 0xED85, 0x97F0, 0xED86, 0x97F1, 0xED87, 0x97F2, 0xED88, 0x97F4, 0xED89, 0x97F7, 0xED8A, 0x97F8, - 0xED8B, 0x97F9, 0xED8C, 0x97FA, 0xED8D, 0x97FB, 0xED8E, 0x97FC, 0xED8F, 0x97FD, 0xED90, 0x97FE, 0xED91, 0x97FF, 0xED92, 0x9800, - 0xED93, 0x9801, 0xED94, 0x9802, 0xED95, 0x9803, 0xED96, 0x9804, 0xED97, 0x9805, 0xED98, 0x9806, 0xED99, 0x9807, 0xED9A, 0x9808, - 0xED9B, 0x9809, 0xED9C, 0x980A, 0xED9D, 0x980B, 0xED9E, 0x980C, 0xED9F, 0x980D, 0xEDA0, 0x980E, 0xEDA1, 0x603C, 0xEDA2, 0x605D, - 0xEDA3, 0x605A, 0xEDA4, 0x6067, 0xEDA5, 0x6041, 0xEDA6, 0x6059, 0xEDA7, 0x6063, 0xEDA8, 0x60AB, 0xEDA9, 0x6106, 0xEDAA, 0x610D, - 0xEDAB, 0x615D, 0xEDAC, 0x61A9, 0xEDAD, 0x619D, 0xEDAE, 0x61CB, 0xEDAF, 0x61D1, 0xEDB0, 0x6206, 0xEDB1, 0x8080, 0xEDB2, 0x807F, - 0xEDB3, 0x6C93, 0xEDB4, 0x6CF6, 0xEDB5, 0x6DFC, 0xEDB6, 0x77F6, 0xEDB7, 0x77F8, 0xEDB8, 0x7800, 0xEDB9, 0x7809, 0xEDBA, 0x7817, - 0xEDBB, 0x7818, 0xEDBC, 0x7811, 0xEDBD, 0x65AB, 0xEDBE, 0x782D, 0xEDBF, 0x781C, 0xEDC0, 0x781D, 0xEDC1, 0x7839, 0xEDC2, 0x783A, - 0xEDC3, 0x783B, 0xEDC4, 0x781F, 0xEDC5, 0x783C, 0xEDC6, 0x7825, 0xEDC7, 0x782C, 0xEDC8, 0x7823, 0xEDC9, 0x7829, 0xEDCA, 0x784E, - 0xEDCB, 0x786D, 0xEDCC, 0x7856, 0xEDCD, 0x7857, 0xEDCE, 0x7826, 0xEDCF, 0x7850, 0xEDD0, 0x7847, 0xEDD1, 0x784C, 0xEDD2, 0x786A, - 0xEDD3, 0x789B, 0xEDD4, 0x7893, 0xEDD5, 0x789A, 0xEDD6, 0x7887, 0xEDD7, 0x789C, 0xEDD8, 0x78A1, 0xEDD9, 0x78A3, 0xEDDA, 0x78B2, - 0xEDDB, 0x78B9, 0xEDDC, 0x78A5, 0xEDDD, 0x78D4, 0xEDDE, 0x78D9, 0xEDDF, 0x78C9, 0xEDE0, 0x78EC, 0xEDE1, 0x78F2, 0xEDE2, 0x7905, - 0xEDE3, 0x78F4, 0xEDE4, 0x7913, 0xEDE5, 0x7924, 0xEDE6, 0x791E, 0xEDE7, 0x7934, 0xEDE8, 0x9F9B, 0xEDE9, 0x9EF9, 0xEDEA, 0x9EFB, - 0xEDEB, 0x9EFC, 0xEDEC, 0x76F1, 0xEDED, 0x7704, 0xEDEE, 0x770D, 0xEDEF, 0x76F9, 0xEDF0, 0x7707, 0xEDF1, 0x7708, 0xEDF2, 0x771A, - 0xEDF3, 0x7722, 0xEDF4, 0x7719, 0xEDF5, 0x772D, 0xEDF6, 0x7726, 0xEDF7, 0x7735, 0xEDF8, 0x7738, 0xEDF9, 0x7750, 0xEDFA, 0x7751, - 0xEDFB, 0x7747, 0xEDFC, 0x7743, 0xEDFD, 0x775A, 0xEDFE, 0x7768, 0xEE40, 0x980F, 0xEE41, 0x9810, 0xEE42, 0x9811, 0xEE43, 0x9812, - 0xEE44, 0x9813, 0xEE45, 0x9814, 0xEE46, 0x9815, 0xEE47, 0x9816, 0xEE48, 0x9817, 0xEE49, 0x9818, 0xEE4A, 0x9819, 0xEE4B, 0x981A, - 0xEE4C, 0x981B, 0xEE4D, 0x981C, 0xEE4E, 0x981D, 0xEE4F, 0x981E, 0xEE50, 0x981F, 0xEE51, 0x9820, 0xEE52, 0x9821, 0xEE53, 0x9822, - 0xEE54, 0x9823, 0xEE55, 0x9824, 0xEE56, 0x9825, 0xEE57, 0x9826, 0xEE58, 0x9827, 0xEE59, 0x9828, 0xEE5A, 0x9829, 0xEE5B, 0x982A, - 0xEE5C, 0x982B, 0xEE5D, 0x982C, 0xEE5E, 0x982D, 0xEE5F, 0x982E, 0xEE60, 0x982F, 0xEE61, 0x9830, 0xEE62, 0x9831, 0xEE63, 0x9832, - 0xEE64, 0x9833, 0xEE65, 0x9834, 0xEE66, 0x9835, 0xEE67, 0x9836, 0xEE68, 0x9837, 0xEE69, 0x9838, 0xEE6A, 0x9839, 0xEE6B, 0x983A, - 0xEE6C, 0x983B, 0xEE6D, 0x983C, 0xEE6E, 0x983D, 0xEE6F, 0x983E, 0xEE70, 0x983F, 0xEE71, 0x9840, 0xEE72, 0x9841, 0xEE73, 0x9842, - 0xEE74, 0x9843, 0xEE75, 0x9844, 0xEE76, 0x9845, 0xEE77, 0x9846, 0xEE78, 0x9847, 0xEE79, 0x9848, 0xEE7A, 0x9849, 0xEE7B, 0x984A, - 0xEE7C, 0x984B, 0xEE7D, 0x984C, 0xEE7E, 0x984D, 0xEE80, 0x984E, 0xEE81, 0x984F, 0xEE82, 0x9850, 0xEE83, 0x9851, 0xEE84, 0x9852, - 0xEE85, 0x9853, 0xEE86, 0x9854, 0xEE87, 0x9855, 0xEE88, 0x9856, 0xEE89, 0x9857, 0xEE8A, 0x9858, 0xEE8B, 0x9859, 0xEE8C, 0x985A, - 0xEE8D, 0x985B, 0xEE8E, 0x985C, 0xEE8F, 0x985D, 0xEE90, 0x985E, 0xEE91, 0x985F, 0xEE92, 0x9860, 0xEE93, 0x9861, 0xEE94, 0x9862, - 0xEE95, 0x9863, 0xEE96, 0x9864, 0xEE97, 0x9865, 0xEE98, 0x9866, 0xEE99, 0x9867, 0xEE9A, 0x9868, 0xEE9B, 0x9869, 0xEE9C, 0x986A, - 0xEE9D, 0x986B, 0xEE9E, 0x986C, 0xEE9F, 0x986D, 0xEEA0, 0x986E, 0xEEA1, 0x7762, 0xEEA2, 0x7765, 0xEEA3, 0x777F, 0xEEA4, 0x778D, - 0xEEA5, 0x777D, 0xEEA6, 0x7780, 0xEEA7, 0x778C, 0xEEA8, 0x7791, 0xEEA9, 0x779F, 0xEEAA, 0x77A0, 0xEEAB, 0x77B0, 0xEEAC, 0x77B5, - 0xEEAD, 0x77BD, 0xEEAE, 0x753A, 0xEEAF, 0x7540, 0xEEB0, 0x754E, 0xEEB1, 0x754B, 0xEEB2, 0x7548, 0xEEB3, 0x755B, 0xEEB4, 0x7572, - 0xEEB5, 0x7579, 0xEEB6, 0x7583, 0xEEB7, 0x7F58, 0xEEB8, 0x7F61, 0xEEB9, 0x7F5F, 0xEEBA, 0x8A48, 0xEEBB, 0x7F68, 0xEEBC, 0x7F74, - 0xEEBD, 0x7F71, 0xEEBE, 0x7F79, 0xEEBF, 0x7F81, 0xEEC0, 0x7F7E, 0xEEC1, 0x76CD, 0xEEC2, 0x76E5, 0xEEC3, 0x8832, 0xEEC4, 0x9485, - 0xEEC5, 0x9486, 0xEEC6, 0x9487, 0xEEC7, 0x948B, 0xEEC8, 0x948A, 0xEEC9, 0x948C, 0xEECA, 0x948D, 0xEECB, 0x948F, 0xEECC, 0x9490, - 0xEECD, 0x9494, 0xEECE, 0x9497, 0xEECF, 0x9495, 0xEED0, 0x949A, 0xEED1, 0x949B, 0xEED2, 0x949C, 0xEED3, 0x94A3, 0xEED4, 0x94A4, - 0xEED5, 0x94AB, 0xEED6, 0x94AA, 0xEED7, 0x94AD, 0xEED8, 0x94AC, 0xEED9, 0x94AF, 0xEEDA, 0x94B0, 0xEEDB, 0x94B2, 0xEEDC, 0x94B4, - 0xEEDD, 0x94B6, 0xEEDE, 0x94B7, 0xEEDF, 0x94B8, 0xEEE0, 0x94B9, 0xEEE1, 0x94BA, 0xEEE2, 0x94BC, 0xEEE3, 0x94BD, 0xEEE4, 0x94BF, - 0xEEE5, 0x94C4, 0xEEE6, 0x94C8, 0xEEE7, 0x94C9, 0xEEE8, 0x94CA, 0xEEE9, 0x94CB, 0xEEEA, 0x94CC, 0xEEEB, 0x94CD, 0xEEEC, 0x94CE, - 0xEEED, 0x94D0, 0xEEEE, 0x94D1, 0xEEEF, 0x94D2, 0xEEF0, 0x94D5, 0xEEF1, 0x94D6, 0xEEF2, 0x94D7, 0xEEF3, 0x94D9, 0xEEF4, 0x94D8, - 0xEEF5, 0x94DB, 0xEEF6, 0x94DE, 0xEEF7, 0x94DF, 0xEEF8, 0x94E0, 0xEEF9, 0x94E2, 0xEEFA, 0x94E4, 0xEEFB, 0x94E5, 0xEEFC, 0x94E7, - 0xEEFD, 0x94E8, 0xEEFE, 0x94EA, 0xEF40, 0x986F, 0xEF41, 0x9870, 0xEF42, 0x9871, 0xEF43, 0x9872, 0xEF44, 0x9873, 0xEF45, 0x9874, - 0xEF46, 0x988B, 0xEF47, 0x988E, 0xEF48, 0x9892, 0xEF49, 0x9895, 0xEF4A, 0x9899, 0xEF4B, 0x98A3, 0xEF4C, 0x98A8, 0xEF4D, 0x98A9, - 0xEF4E, 0x98AA, 0xEF4F, 0x98AB, 0xEF50, 0x98AC, 0xEF51, 0x98AD, 0xEF52, 0x98AE, 0xEF53, 0x98AF, 0xEF54, 0x98B0, 0xEF55, 0x98B1, - 0xEF56, 0x98B2, 0xEF57, 0x98B3, 0xEF58, 0x98B4, 0xEF59, 0x98B5, 0xEF5A, 0x98B6, 0xEF5B, 0x98B7, 0xEF5C, 0x98B8, 0xEF5D, 0x98B9, - 0xEF5E, 0x98BA, 0xEF5F, 0x98BB, 0xEF60, 0x98BC, 0xEF61, 0x98BD, 0xEF62, 0x98BE, 0xEF63, 0x98BF, 0xEF64, 0x98C0, 0xEF65, 0x98C1, - 0xEF66, 0x98C2, 0xEF67, 0x98C3, 0xEF68, 0x98C4, 0xEF69, 0x98C5, 0xEF6A, 0x98C6, 0xEF6B, 0x98C7, 0xEF6C, 0x98C8, 0xEF6D, 0x98C9, - 0xEF6E, 0x98CA, 0xEF6F, 0x98CB, 0xEF70, 0x98CC, 0xEF71, 0x98CD, 0xEF72, 0x98CF, 0xEF73, 0x98D0, 0xEF74, 0x98D4, 0xEF75, 0x98D6, - 0xEF76, 0x98D7, 0xEF77, 0x98DB, 0xEF78, 0x98DC, 0xEF79, 0x98DD, 0xEF7A, 0x98E0, 0xEF7B, 0x98E1, 0xEF7C, 0x98E2, 0xEF7D, 0x98E3, - 0xEF7E, 0x98E4, 0xEF80, 0x98E5, 0xEF81, 0x98E6, 0xEF82, 0x98E9, 0xEF83, 0x98EA, 0xEF84, 0x98EB, 0xEF85, 0x98EC, 0xEF86, 0x98ED, - 0xEF87, 0x98EE, 0xEF88, 0x98EF, 0xEF89, 0x98F0, 0xEF8A, 0x98F1, 0xEF8B, 0x98F2, 0xEF8C, 0x98F3, 0xEF8D, 0x98F4, 0xEF8E, 0x98F5, - 0xEF8F, 0x98F6, 0xEF90, 0x98F7, 0xEF91, 0x98F8, 0xEF92, 0x98F9, 0xEF93, 0x98FA, 0xEF94, 0x98FB, 0xEF95, 0x98FC, 0xEF96, 0x98FD, - 0xEF97, 0x98FE, 0xEF98, 0x98FF, 0xEF99, 0x9900, 0xEF9A, 0x9901, 0xEF9B, 0x9902, 0xEF9C, 0x9903, 0xEF9D, 0x9904, 0xEF9E, 0x9905, - 0xEF9F, 0x9906, 0xEFA0, 0x9907, 0xEFA1, 0x94E9, 0xEFA2, 0x94EB, 0xEFA3, 0x94EE, 0xEFA4, 0x94EF, 0xEFA5, 0x94F3, 0xEFA6, 0x94F4, - 0xEFA7, 0x94F5, 0xEFA8, 0x94F7, 0xEFA9, 0x94F9, 0xEFAA, 0x94FC, 0xEFAB, 0x94FD, 0xEFAC, 0x94FF, 0xEFAD, 0x9503, 0xEFAE, 0x9502, - 0xEFAF, 0x9506, 0xEFB0, 0x9507, 0xEFB1, 0x9509, 0xEFB2, 0x950A, 0xEFB3, 0x950D, 0xEFB4, 0x950E, 0xEFB5, 0x950F, 0xEFB6, 0x9512, - 0xEFB7, 0x9513, 0xEFB8, 0x9514, 0xEFB9, 0x9515, 0xEFBA, 0x9516, 0xEFBB, 0x9518, 0xEFBC, 0x951B, 0xEFBD, 0x951D, 0xEFBE, 0x951E, - 0xEFBF, 0x951F, 0xEFC0, 0x9522, 0xEFC1, 0x952A, 0xEFC2, 0x952B, 0xEFC3, 0x9529, 0xEFC4, 0x952C, 0xEFC5, 0x9531, 0xEFC6, 0x9532, - 0xEFC7, 0x9534, 0xEFC8, 0x9536, 0xEFC9, 0x9537, 0xEFCA, 0x9538, 0xEFCB, 0x953C, 0xEFCC, 0x953E, 0xEFCD, 0x953F, 0xEFCE, 0x9542, - 0xEFCF, 0x9535, 0xEFD0, 0x9544, 0xEFD1, 0x9545, 0xEFD2, 0x9546, 0xEFD3, 0x9549, 0xEFD4, 0x954C, 0xEFD5, 0x954E, 0xEFD6, 0x954F, - 0xEFD7, 0x9552, 0xEFD8, 0x9553, 0xEFD9, 0x9554, 0xEFDA, 0x9556, 0xEFDB, 0x9557, 0xEFDC, 0x9558, 0xEFDD, 0x9559, 0xEFDE, 0x955B, - 0xEFDF, 0x955E, 0xEFE0, 0x955F, 0xEFE1, 0x955D, 0xEFE2, 0x9561, 0xEFE3, 0x9562, 0xEFE4, 0x9564, 0xEFE5, 0x9565, 0xEFE6, 0x9566, - 0xEFE7, 0x9567, 0xEFE8, 0x9568, 0xEFE9, 0x9569, 0xEFEA, 0x956A, 0xEFEB, 0x956B, 0xEFEC, 0x956C, 0xEFED, 0x956F, 0xEFEE, 0x9571, - 0xEFEF, 0x9572, 0xEFF0, 0x9573, 0xEFF1, 0x953A, 0xEFF2, 0x77E7, 0xEFF3, 0x77EC, 0xEFF4, 0x96C9, 0xEFF5, 0x79D5, 0xEFF6, 0x79ED, - 0xEFF7, 0x79E3, 0xEFF8, 0x79EB, 0xEFF9, 0x7A06, 0xEFFA, 0x5D47, 0xEFFB, 0x7A03, 0xEFFC, 0x7A02, 0xEFFD, 0x7A1E, 0xEFFE, 0x7A14, - 0xF040, 0x9908, 0xF041, 0x9909, 0xF042, 0x990A, 0xF043, 0x990B, 0xF044, 0x990C, 0xF045, 0x990E, 0xF046, 0x990F, 0xF047, 0x9911, - 0xF048, 0x9912, 0xF049, 0x9913, 0xF04A, 0x9914, 0xF04B, 0x9915, 0xF04C, 0x9916, 0xF04D, 0x9917, 0xF04E, 0x9918, 0xF04F, 0x9919, - 0xF050, 0x991A, 0xF051, 0x991B, 0xF052, 0x991C, 0xF053, 0x991D, 0xF054, 0x991E, 0xF055, 0x991F, 0xF056, 0x9920, 0xF057, 0x9921, - 0xF058, 0x9922, 0xF059, 0x9923, 0xF05A, 0x9924, 0xF05B, 0x9925, 0xF05C, 0x9926, 0xF05D, 0x9927, 0xF05E, 0x9928, 0xF05F, 0x9929, - 0xF060, 0x992A, 0xF061, 0x992B, 0xF062, 0x992C, 0xF063, 0x992D, 0xF064, 0x992F, 0xF065, 0x9930, 0xF066, 0x9931, 0xF067, 0x9932, - 0xF068, 0x9933, 0xF069, 0x9934, 0xF06A, 0x9935, 0xF06B, 0x9936, 0xF06C, 0x9937, 0xF06D, 0x9938, 0xF06E, 0x9939, 0xF06F, 0x993A, - 0xF070, 0x993B, 0xF071, 0x993C, 0xF072, 0x993D, 0xF073, 0x993E, 0xF074, 0x993F, 0xF075, 0x9940, 0xF076, 0x9941, 0xF077, 0x9942, - 0xF078, 0x9943, 0xF079, 0x9944, 0xF07A, 0x9945, 0xF07B, 0x9946, 0xF07C, 0x9947, 0xF07D, 0x9948, 0xF07E, 0x9949, 0xF080, 0x994A, - 0xF081, 0x994B, 0xF082, 0x994C, 0xF083, 0x994D, 0xF084, 0x994E, 0xF085, 0x994F, 0xF086, 0x9950, 0xF087, 0x9951, 0xF088, 0x9952, - 0xF089, 0x9953, 0xF08A, 0x9956, 0xF08B, 0x9957, 0xF08C, 0x9958, 0xF08D, 0x9959, 0xF08E, 0x995A, 0xF08F, 0x995B, 0xF090, 0x995C, - 0xF091, 0x995D, 0xF092, 0x995E, 0xF093, 0x995F, 0xF094, 0x9960, 0xF095, 0x9961, 0xF096, 0x9962, 0xF097, 0x9964, 0xF098, 0x9966, - 0xF099, 0x9973, 0xF09A, 0x9978, 0xF09B, 0x9979, 0xF09C, 0x997B, 0xF09D, 0x997E, 0xF09E, 0x9982, 0xF09F, 0x9983, 0xF0A0, 0x9989, - 0xF0A1, 0x7A39, 0xF0A2, 0x7A37, 0xF0A3, 0x7A51, 0xF0A4, 0x9ECF, 0xF0A5, 0x99A5, 0xF0A6, 0x7A70, 0xF0A7, 0x7688, 0xF0A8, 0x768E, - 0xF0A9, 0x7693, 0xF0AA, 0x7699, 0xF0AB, 0x76A4, 0xF0AC, 0x74DE, 0xF0AD, 0x74E0, 0xF0AE, 0x752C, 0xF0AF, 0x9E20, 0xF0B0, 0x9E22, - 0xF0B1, 0x9E28, 0xF0B2, 0x9E29, 0xF0B3, 0x9E2A, 0xF0B4, 0x9E2B, 0xF0B5, 0x9E2C, 0xF0B6, 0x9E32, 0xF0B7, 0x9E31, 0xF0B8, 0x9E36, - 0xF0B9, 0x9E38, 0xF0BA, 0x9E37, 0xF0BB, 0x9E39, 0xF0BC, 0x9E3A, 0xF0BD, 0x9E3E, 0xF0BE, 0x9E41, 0xF0BF, 0x9E42, 0xF0C0, 0x9E44, - 0xF0C1, 0x9E46, 0xF0C2, 0x9E47, 0xF0C3, 0x9E48, 0xF0C4, 0x9E49, 0xF0C5, 0x9E4B, 0xF0C6, 0x9E4C, 0xF0C7, 0x9E4E, 0xF0C8, 0x9E51, - 0xF0C9, 0x9E55, 0xF0CA, 0x9E57, 0xF0CB, 0x9E5A, 0xF0CC, 0x9E5B, 0xF0CD, 0x9E5C, 0xF0CE, 0x9E5E, 0xF0CF, 0x9E63, 0xF0D0, 0x9E66, - 0xF0D1, 0x9E67, 0xF0D2, 0x9E68, 0xF0D3, 0x9E69, 0xF0D4, 0x9E6A, 0xF0D5, 0x9E6B, 0xF0D6, 0x9E6C, 0xF0D7, 0x9E71, 0xF0D8, 0x9E6D, - 0xF0D9, 0x9E73, 0xF0DA, 0x7592, 0xF0DB, 0x7594, 0xF0DC, 0x7596, 0xF0DD, 0x75A0, 0xF0DE, 0x759D, 0xF0DF, 0x75AC, 0xF0E0, 0x75A3, - 0xF0E1, 0x75B3, 0xF0E2, 0x75B4, 0xF0E3, 0x75B8, 0xF0E4, 0x75C4, 0xF0E5, 0x75B1, 0xF0E6, 0x75B0, 0xF0E7, 0x75C3, 0xF0E8, 0x75C2, - 0xF0E9, 0x75D6, 0xF0EA, 0x75CD, 0xF0EB, 0x75E3, 0xF0EC, 0x75E8, 0xF0ED, 0x75E6, 0xF0EE, 0x75E4, 0xF0EF, 0x75EB, 0xF0F0, 0x75E7, - 0xF0F1, 0x7603, 0xF0F2, 0x75F1, 0xF0F3, 0x75FC, 0xF0F4, 0x75FF, 0xF0F5, 0x7610, 0xF0F6, 0x7600, 0xF0F7, 0x7605, 0xF0F8, 0x760C, - 0xF0F9, 0x7617, 0xF0FA, 0x760A, 0xF0FB, 0x7625, 0xF0FC, 0x7618, 0xF0FD, 0x7615, 0xF0FE, 0x7619, 0xF140, 0x998C, 0xF141, 0x998E, - 0xF142, 0x999A, 0xF143, 0x999B, 0xF144, 0x999C, 0xF145, 0x999D, 0xF146, 0x999E, 0xF147, 0x999F, 0xF148, 0x99A0, 0xF149, 0x99A1, - 0xF14A, 0x99A2, 0xF14B, 0x99A3, 0xF14C, 0x99A4, 0xF14D, 0x99A6, 0xF14E, 0x99A7, 0xF14F, 0x99A9, 0xF150, 0x99AA, 0xF151, 0x99AB, - 0xF152, 0x99AC, 0xF153, 0x99AD, 0xF154, 0x99AE, 0xF155, 0x99AF, 0xF156, 0x99B0, 0xF157, 0x99B1, 0xF158, 0x99B2, 0xF159, 0x99B3, - 0xF15A, 0x99B4, 0xF15B, 0x99B5, 0xF15C, 0x99B6, 0xF15D, 0x99B7, 0xF15E, 0x99B8, 0xF15F, 0x99B9, 0xF160, 0x99BA, 0xF161, 0x99BB, - 0xF162, 0x99BC, 0xF163, 0x99BD, 0xF164, 0x99BE, 0xF165, 0x99BF, 0xF166, 0x99C0, 0xF167, 0x99C1, 0xF168, 0x99C2, 0xF169, 0x99C3, - 0xF16A, 0x99C4, 0xF16B, 0x99C5, 0xF16C, 0x99C6, 0xF16D, 0x99C7, 0xF16E, 0x99C8, 0xF16F, 0x99C9, 0xF170, 0x99CA, 0xF171, 0x99CB, - 0xF172, 0x99CC, 0xF173, 0x99CD, 0xF174, 0x99CE, 0xF175, 0x99CF, 0xF176, 0x99D0, 0xF177, 0x99D1, 0xF178, 0x99D2, 0xF179, 0x99D3, - 0xF17A, 0x99D4, 0xF17B, 0x99D5, 0xF17C, 0x99D6, 0xF17D, 0x99D7, 0xF17E, 0x99D8, 0xF180, 0x99D9, 0xF181, 0x99DA, 0xF182, 0x99DB, - 0xF183, 0x99DC, 0xF184, 0x99DD, 0xF185, 0x99DE, 0xF186, 0x99DF, 0xF187, 0x99E0, 0xF188, 0x99E1, 0xF189, 0x99E2, 0xF18A, 0x99E3, - 0xF18B, 0x99E4, 0xF18C, 0x99E5, 0xF18D, 0x99E6, 0xF18E, 0x99E7, 0xF18F, 0x99E8, 0xF190, 0x99E9, 0xF191, 0x99EA, 0xF192, 0x99EB, - 0xF193, 0x99EC, 0xF194, 0x99ED, 0xF195, 0x99EE, 0xF196, 0x99EF, 0xF197, 0x99F0, 0xF198, 0x99F1, 0xF199, 0x99F2, 0xF19A, 0x99F3, - 0xF19B, 0x99F4, 0xF19C, 0x99F5, 0xF19D, 0x99F6, 0xF19E, 0x99F7, 0xF19F, 0x99F8, 0xF1A0, 0x99F9, 0xF1A1, 0x761B, 0xF1A2, 0x763C, - 0xF1A3, 0x7622, 0xF1A4, 0x7620, 0xF1A5, 0x7640, 0xF1A6, 0x762D, 0xF1A7, 0x7630, 0xF1A8, 0x763F, 0xF1A9, 0x7635, 0xF1AA, 0x7643, - 0xF1AB, 0x763E, 0xF1AC, 0x7633, 0xF1AD, 0x764D, 0xF1AE, 0x765E, 0xF1AF, 0x7654, 0xF1B0, 0x765C, 0xF1B1, 0x7656, 0xF1B2, 0x766B, - 0xF1B3, 0x766F, 0xF1B4, 0x7FCA, 0xF1B5, 0x7AE6, 0xF1B6, 0x7A78, 0xF1B7, 0x7A79, 0xF1B8, 0x7A80, 0xF1B9, 0x7A86, 0xF1BA, 0x7A88, - 0xF1BB, 0x7A95, 0xF1BC, 0x7AA6, 0xF1BD, 0x7AA0, 0xF1BE, 0x7AAC, 0xF1BF, 0x7AA8, 0xF1C0, 0x7AAD, 0xF1C1, 0x7AB3, 0xF1C2, 0x8864, - 0xF1C3, 0x8869, 0xF1C4, 0x8872, 0xF1C5, 0x887D, 0xF1C6, 0x887F, 0xF1C7, 0x8882, 0xF1C8, 0x88A2, 0xF1C9, 0x88C6, 0xF1CA, 0x88B7, - 0xF1CB, 0x88BC, 0xF1CC, 0x88C9, 0xF1CD, 0x88E2, 0xF1CE, 0x88CE, 0xF1CF, 0x88E3, 0xF1D0, 0x88E5, 0xF1D1, 0x88F1, 0xF1D2, 0x891A, - 0xF1D3, 0x88FC, 0xF1D4, 0x88E8, 0xF1D5, 0x88FE, 0xF1D6, 0x88F0, 0xF1D7, 0x8921, 0xF1D8, 0x8919, 0xF1D9, 0x8913, 0xF1DA, 0x891B, - 0xF1DB, 0x890A, 0xF1DC, 0x8934, 0xF1DD, 0x892B, 0xF1DE, 0x8936, 0xF1DF, 0x8941, 0xF1E0, 0x8966, 0xF1E1, 0x897B, 0xF1E2, 0x758B, - 0xF1E3, 0x80E5, 0xF1E4, 0x76B2, 0xF1E5, 0x76B4, 0xF1E6, 0x77DC, 0xF1E7, 0x8012, 0xF1E8, 0x8014, 0xF1E9, 0x8016, 0xF1EA, 0x801C, - 0xF1EB, 0x8020, 0xF1EC, 0x8022, 0xF1ED, 0x8025, 0xF1EE, 0x8026, 0xF1EF, 0x8027, 0xF1F0, 0x8029, 0xF1F1, 0x8028, 0xF1F2, 0x8031, - 0xF1F3, 0x800B, 0xF1F4, 0x8035, 0xF1F5, 0x8043, 0xF1F6, 0x8046, 0xF1F7, 0x804D, 0xF1F8, 0x8052, 0xF1F9, 0x8069, 0xF1FA, 0x8071, - 0xF1FB, 0x8983, 0xF1FC, 0x9878, 0xF1FD, 0x9880, 0xF1FE, 0x9883, 0xF240, 0x99FA, 0xF241, 0x99FB, 0xF242, 0x99FC, 0xF243, 0x99FD, - 0xF244, 0x99FE, 0xF245, 0x99FF, 0xF246, 0x9A00, 0xF247, 0x9A01, 0xF248, 0x9A02, 0xF249, 0x9A03, 0xF24A, 0x9A04, 0xF24B, 0x9A05, - 0xF24C, 0x9A06, 0xF24D, 0x9A07, 0xF24E, 0x9A08, 0xF24F, 0x9A09, 0xF250, 0x9A0A, 0xF251, 0x9A0B, 0xF252, 0x9A0C, 0xF253, 0x9A0D, - 0xF254, 0x9A0E, 0xF255, 0x9A0F, 0xF256, 0x9A10, 0xF257, 0x9A11, 0xF258, 0x9A12, 0xF259, 0x9A13, 0xF25A, 0x9A14, 0xF25B, 0x9A15, - 0xF25C, 0x9A16, 0xF25D, 0x9A17, 0xF25E, 0x9A18, 0xF25F, 0x9A19, 0xF260, 0x9A1A, 0xF261, 0x9A1B, 0xF262, 0x9A1C, 0xF263, 0x9A1D, - 0xF264, 0x9A1E, 0xF265, 0x9A1F, 0xF266, 0x9A20, 0xF267, 0x9A21, 0xF268, 0x9A22, 0xF269, 0x9A23, 0xF26A, 0x9A24, 0xF26B, 0x9A25, - 0xF26C, 0x9A26, 0xF26D, 0x9A27, 0xF26E, 0x9A28, 0xF26F, 0x9A29, 0xF270, 0x9A2A, 0xF271, 0x9A2B, 0xF272, 0x9A2C, 0xF273, 0x9A2D, - 0xF274, 0x9A2E, 0xF275, 0x9A2F, 0xF276, 0x9A30, 0xF277, 0x9A31, 0xF278, 0x9A32, 0xF279, 0x9A33, 0xF27A, 0x9A34, 0xF27B, 0x9A35, - 0xF27C, 0x9A36, 0xF27D, 0x9A37, 0xF27E, 0x9A38, 0xF280, 0x9A39, 0xF281, 0x9A3A, 0xF282, 0x9A3B, 0xF283, 0x9A3C, 0xF284, 0x9A3D, - 0xF285, 0x9A3E, 0xF286, 0x9A3F, 0xF287, 0x9A40, 0xF288, 0x9A41, 0xF289, 0x9A42, 0xF28A, 0x9A43, 0xF28B, 0x9A44, 0xF28C, 0x9A45, - 0xF28D, 0x9A46, 0xF28E, 0x9A47, 0xF28F, 0x9A48, 0xF290, 0x9A49, 0xF291, 0x9A4A, 0xF292, 0x9A4B, 0xF293, 0x9A4C, 0xF294, 0x9A4D, - 0xF295, 0x9A4E, 0xF296, 0x9A4F, 0xF297, 0x9A50, 0xF298, 0x9A51, 0xF299, 0x9A52, 0xF29A, 0x9A53, 0xF29B, 0x9A54, 0xF29C, 0x9A55, - 0xF29D, 0x9A56, 0xF29E, 0x9A57, 0xF29F, 0x9A58, 0xF2A0, 0x9A59, 0xF2A1, 0x9889, 0xF2A2, 0x988C, 0xF2A3, 0x988D, 0xF2A4, 0x988F, - 0xF2A5, 0x9894, 0xF2A6, 0x989A, 0xF2A7, 0x989B, 0xF2A8, 0x989E, 0xF2A9, 0x989F, 0xF2AA, 0x98A1, 0xF2AB, 0x98A2, 0xF2AC, 0x98A5, - 0xF2AD, 0x98A6, 0xF2AE, 0x864D, 0xF2AF, 0x8654, 0xF2B0, 0x866C, 0xF2B1, 0x866E, 0xF2B2, 0x867F, 0xF2B3, 0x867A, 0xF2B4, 0x867C, - 0xF2B5, 0x867B, 0xF2B6, 0x86A8, 0xF2B7, 0x868D, 0xF2B8, 0x868B, 0xF2B9, 0x86AC, 0xF2BA, 0x869D, 0xF2BB, 0x86A7, 0xF2BC, 0x86A3, - 0xF2BD, 0x86AA, 0xF2BE, 0x8693, 0xF2BF, 0x86A9, 0xF2C0, 0x86B6, 0xF2C1, 0x86C4, 0xF2C2, 0x86B5, 0xF2C3, 0x86CE, 0xF2C4, 0x86B0, - 0xF2C5, 0x86BA, 0xF2C6, 0x86B1, 0xF2C7, 0x86AF, 0xF2C8, 0x86C9, 0xF2C9, 0x86CF, 0xF2CA, 0x86B4, 0xF2CB, 0x86E9, 0xF2CC, 0x86F1, - 0xF2CD, 0x86F2, 0xF2CE, 0x86ED, 0xF2CF, 0x86F3, 0xF2D0, 0x86D0, 0xF2D1, 0x8713, 0xF2D2, 0x86DE, 0xF2D3, 0x86F4, 0xF2D4, 0x86DF, - 0xF2D5, 0x86D8, 0xF2D6, 0x86D1, 0xF2D7, 0x8703, 0xF2D8, 0x8707, 0xF2D9, 0x86F8, 0xF2DA, 0x8708, 0xF2DB, 0x870A, 0xF2DC, 0x870D, - 0xF2DD, 0x8709, 0xF2DE, 0x8723, 0xF2DF, 0x873B, 0xF2E0, 0x871E, 0xF2E1, 0x8725, 0xF2E2, 0x872E, 0xF2E3, 0x871A, 0xF2E4, 0x873E, - 0xF2E5, 0x8748, 0xF2E6, 0x8734, 0xF2E7, 0x8731, 0xF2E8, 0x8729, 0xF2E9, 0x8737, 0xF2EA, 0x873F, 0xF2EB, 0x8782, 0xF2EC, 0x8722, - 0xF2ED, 0x877D, 0xF2EE, 0x877E, 0xF2EF, 0x877B, 0xF2F0, 0x8760, 0xF2F1, 0x8770, 0xF2F2, 0x874C, 0xF2F3, 0x876E, 0xF2F4, 0x878B, - 0xF2F5, 0x8753, 0xF2F6, 0x8763, 0xF2F7, 0x877C, 0xF2F8, 0x8764, 0xF2F9, 0x8759, 0xF2FA, 0x8765, 0xF2FB, 0x8793, 0xF2FC, 0x87AF, - 0xF2FD, 0x87A8, 0xF2FE, 0x87D2, 0xF340, 0x9A5A, 0xF341, 0x9A5B, 0xF342, 0x9A5C, 0xF343, 0x9A5D, 0xF344, 0x9A5E, 0xF345, 0x9A5F, - 0xF346, 0x9A60, 0xF347, 0x9A61, 0xF348, 0x9A62, 0xF349, 0x9A63, 0xF34A, 0x9A64, 0xF34B, 0x9A65, 0xF34C, 0x9A66, 0xF34D, 0x9A67, - 0xF34E, 0x9A68, 0xF34F, 0x9A69, 0xF350, 0x9A6A, 0xF351, 0x9A6B, 0xF352, 0x9A72, 0xF353, 0x9A83, 0xF354, 0x9A89, 0xF355, 0x9A8D, - 0xF356, 0x9A8E, 0xF357, 0x9A94, 0xF358, 0x9A95, 0xF359, 0x9A99, 0xF35A, 0x9AA6, 0xF35B, 0x9AA9, 0xF35C, 0x9AAA, 0xF35D, 0x9AAB, - 0xF35E, 0x9AAC, 0xF35F, 0x9AAD, 0xF360, 0x9AAE, 0xF361, 0x9AAF, 0xF362, 0x9AB2, 0xF363, 0x9AB3, 0xF364, 0x9AB4, 0xF365, 0x9AB5, - 0xF366, 0x9AB9, 0xF367, 0x9ABB, 0xF368, 0x9ABD, 0xF369, 0x9ABE, 0xF36A, 0x9ABF, 0xF36B, 0x9AC3, 0xF36C, 0x9AC4, 0xF36D, 0x9AC6, - 0xF36E, 0x9AC7, 0xF36F, 0x9AC8, 0xF370, 0x9AC9, 0xF371, 0x9ACA, 0xF372, 0x9ACD, 0xF373, 0x9ACE, 0xF374, 0x9ACF, 0xF375, 0x9AD0, - 0xF376, 0x9AD2, 0xF377, 0x9AD4, 0xF378, 0x9AD5, 0xF379, 0x9AD6, 0xF37A, 0x9AD7, 0xF37B, 0x9AD9, 0xF37C, 0x9ADA, 0xF37D, 0x9ADB, - 0xF37E, 0x9ADC, 0xF380, 0x9ADD, 0xF381, 0x9ADE, 0xF382, 0x9AE0, 0xF383, 0x9AE2, 0xF384, 0x9AE3, 0xF385, 0x9AE4, 0xF386, 0x9AE5, - 0xF387, 0x9AE7, 0xF388, 0x9AE8, 0xF389, 0x9AE9, 0xF38A, 0x9AEA, 0xF38B, 0x9AEC, 0xF38C, 0x9AEE, 0xF38D, 0x9AF0, 0xF38E, 0x9AF1, - 0xF38F, 0x9AF2, 0xF390, 0x9AF3, 0xF391, 0x9AF4, 0xF392, 0x9AF5, 0xF393, 0x9AF6, 0xF394, 0x9AF7, 0xF395, 0x9AF8, 0xF396, 0x9AFA, - 0xF397, 0x9AFC, 0xF398, 0x9AFD, 0xF399, 0x9AFE, 0xF39A, 0x9AFF, 0xF39B, 0x9B00, 0xF39C, 0x9B01, 0xF39D, 0x9B02, 0xF39E, 0x9B04, - 0xF39F, 0x9B05, 0xF3A0, 0x9B06, 0xF3A1, 0x87C6, 0xF3A2, 0x8788, 0xF3A3, 0x8785, 0xF3A4, 0x87AD, 0xF3A5, 0x8797, 0xF3A6, 0x8783, - 0xF3A7, 0x87AB, 0xF3A8, 0x87E5, 0xF3A9, 0x87AC, 0xF3AA, 0x87B5, 0xF3AB, 0x87B3, 0xF3AC, 0x87CB, 0xF3AD, 0x87D3, 0xF3AE, 0x87BD, - 0xF3AF, 0x87D1, 0xF3B0, 0x87C0, 0xF3B1, 0x87CA, 0xF3B2, 0x87DB, 0xF3B3, 0x87EA, 0xF3B4, 0x87E0, 0xF3B5, 0x87EE, 0xF3B6, 0x8816, - 0xF3B7, 0x8813, 0xF3B8, 0x87FE, 0xF3B9, 0x880A, 0xF3BA, 0x881B, 0xF3BB, 0x8821, 0xF3BC, 0x8839, 0xF3BD, 0x883C, 0xF3BE, 0x7F36, - 0xF3BF, 0x7F42, 0xF3C0, 0x7F44, 0xF3C1, 0x7F45, 0xF3C2, 0x8210, 0xF3C3, 0x7AFA, 0xF3C4, 0x7AFD, 0xF3C5, 0x7B08, 0xF3C6, 0x7B03, - 0xF3C7, 0x7B04, 0xF3C8, 0x7B15, 0xF3C9, 0x7B0A, 0xF3CA, 0x7B2B, 0xF3CB, 0x7B0F, 0xF3CC, 0x7B47, 0xF3CD, 0x7B38, 0xF3CE, 0x7B2A, - 0xF3CF, 0x7B19, 0xF3D0, 0x7B2E, 0xF3D1, 0x7B31, 0xF3D2, 0x7B20, 0xF3D3, 0x7B25, 0xF3D4, 0x7B24, 0xF3D5, 0x7B33, 0xF3D6, 0x7B3E, - 0xF3D7, 0x7B1E, 0xF3D8, 0x7B58, 0xF3D9, 0x7B5A, 0xF3DA, 0x7B45, 0xF3DB, 0x7B75, 0xF3DC, 0x7B4C, 0xF3DD, 0x7B5D, 0xF3DE, 0x7B60, - 0xF3DF, 0x7B6E, 0xF3E0, 0x7B7B, 0xF3E1, 0x7B62, 0xF3E2, 0x7B72, 0xF3E3, 0x7B71, 0xF3E4, 0x7B90, 0xF3E5, 0x7BA6, 0xF3E6, 0x7BA7, - 0xF3E7, 0x7BB8, 0xF3E8, 0x7BAC, 0xF3E9, 0x7B9D, 0xF3EA, 0x7BA8, 0xF3EB, 0x7B85, 0xF3EC, 0x7BAA, 0xF3ED, 0x7B9C, 0xF3EE, 0x7BA2, - 0xF3EF, 0x7BAB, 0xF3F0, 0x7BB4, 0xF3F1, 0x7BD1, 0xF3F2, 0x7BC1, 0xF3F3, 0x7BCC, 0xF3F4, 0x7BDD, 0xF3F5, 0x7BDA, 0xF3F6, 0x7BE5, - 0xF3F7, 0x7BE6, 0xF3F8, 0x7BEA, 0xF3F9, 0x7C0C, 0xF3FA, 0x7BFE, 0xF3FB, 0x7BFC, 0xF3FC, 0x7C0F, 0xF3FD, 0x7C16, 0xF3FE, 0x7C0B, - 0xF440, 0x9B07, 0xF441, 0x9B09, 0xF442, 0x9B0A, 0xF443, 0x9B0B, 0xF444, 0x9B0C, 0xF445, 0x9B0D, 0xF446, 0x9B0E, 0xF447, 0x9B10, - 0xF448, 0x9B11, 0xF449, 0x9B12, 0xF44A, 0x9B14, 0xF44B, 0x9B15, 0xF44C, 0x9B16, 0xF44D, 0x9B17, 0xF44E, 0x9B18, 0xF44F, 0x9B19, - 0xF450, 0x9B1A, 0xF451, 0x9B1B, 0xF452, 0x9B1C, 0xF453, 0x9B1D, 0xF454, 0x9B1E, 0xF455, 0x9B20, 0xF456, 0x9B21, 0xF457, 0x9B22, - 0xF458, 0x9B24, 0xF459, 0x9B25, 0xF45A, 0x9B26, 0xF45B, 0x9B27, 0xF45C, 0x9B28, 0xF45D, 0x9B29, 0xF45E, 0x9B2A, 0xF45F, 0x9B2B, - 0xF460, 0x9B2C, 0xF461, 0x9B2D, 0xF462, 0x9B2E, 0xF463, 0x9B30, 0xF464, 0x9B31, 0xF465, 0x9B33, 0xF466, 0x9B34, 0xF467, 0x9B35, - 0xF468, 0x9B36, 0xF469, 0x9B37, 0xF46A, 0x9B38, 0xF46B, 0x9B39, 0xF46C, 0x9B3A, 0xF46D, 0x9B3D, 0xF46E, 0x9B3E, 0xF46F, 0x9B3F, - 0xF470, 0x9B40, 0xF471, 0x9B46, 0xF472, 0x9B4A, 0xF473, 0x9B4B, 0xF474, 0x9B4C, 0xF475, 0x9B4E, 0xF476, 0x9B50, 0xF477, 0x9B52, - 0xF478, 0x9B53, 0xF479, 0x9B55, 0xF47A, 0x9B56, 0xF47B, 0x9B57, 0xF47C, 0x9B58, 0xF47D, 0x9B59, 0xF47E, 0x9B5A, 0xF480, 0x9B5B, - 0xF481, 0x9B5C, 0xF482, 0x9B5D, 0xF483, 0x9B5E, 0xF484, 0x9B5F, 0xF485, 0x9B60, 0xF486, 0x9B61, 0xF487, 0x9B62, 0xF488, 0x9B63, - 0xF489, 0x9B64, 0xF48A, 0x9B65, 0xF48B, 0x9B66, 0xF48C, 0x9B67, 0xF48D, 0x9B68, 0xF48E, 0x9B69, 0xF48F, 0x9B6A, 0xF490, 0x9B6B, - 0xF491, 0x9B6C, 0xF492, 0x9B6D, 0xF493, 0x9B6E, 0xF494, 0x9B6F, 0xF495, 0x9B70, 0xF496, 0x9B71, 0xF497, 0x9B72, 0xF498, 0x9B73, - 0xF499, 0x9B74, 0xF49A, 0x9B75, 0xF49B, 0x9B76, 0xF49C, 0x9B77, 0xF49D, 0x9B78, 0xF49E, 0x9B79, 0xF49F, 0x9B7A, 0xF4A0, 0x9B7B, - 0xF4A1, 0x7C1F, 0xF4A2, 0x7C2A, 0xF4A3, 0x7C26, 0xF4A4, 0x7C38, 0xF4A5, 0x7C41, 0xF4A6, 0x7C40, 0xF4A7, 0x81FE, 0xF4A8, 0x8201, - 0xF4A9, 0x8202, 0xF4AA, 0x8204, 0xF4AB, 0x81EC, 0xF4AC, 0x8844, 0xF4AD, 0x8221, 0xF4AE, 0x8222, 0xF4AF, 0x8223, 0xF4B0, 0x822D, - 0xF4B1, 0x822F, 0xF4B2, 0x8228, 0xF4B3, 0x822B, 0xF4B4, 0x8238, 0xF4B5, 0x823B, 0xF4B6, 0x8233, 0xF4B7, 0x8234, 0xF4B8, 0x823E, - 0xF4B9, 0x8244, 0xF4BA, 0x8249, 0xF4BB, 0x824B, 0xF4BC, 0x824F, 0xF4BD, 0x825A, 0xF4BE, 0x825F, 0xF4BF, 0x8268, 0xF4C0, 0x887E, - 0xF4C1, 0x8885, 0xF4C2, 0x8888, 0xF4C3, 0x88D8, 0xF4C4, 0x88DF, 0xF4C5, 0x895E, 0xF4C6, 0x7F9D, 0xF4C7, 0x7F9F, 0xF4C8, 0x7FA7, - 0xF4C9, 0x7FAF, 0xF4CA, 0x7FB0, 0xF4CB, 0x7FB2, 0xF4CC, 0x7C7C, 0xF4CD, 0x6549, 0xF4CE, 0x7C91, 0xF4CF, 0x7C9D, 0xF4D0, 0x7C9C, - 0xF4D1, 0x7C9E, 0xF4D2, 0x7CA2, 0xF4D3, 0x7CB2, 0xF4D4, 0x7CBC, 0xF4D5, 0x7CBD, 0xF4D6, 0x7CC1, 0xF4D7, 0x7CC7, 0xF4D8, 0x7CCC, - 0xF4D9, 0x7CCD, 0xF4DA, 0x7CC8, 0xF4DB, 0x7CC5, 0xF4DC, 0x7CD7, 0xF4DD, 0x7CE8, 0xF4DE, 0x826E, 0xF4DF, 0x66A8, 0xF4E0, 0x7FBF, - 0xF4E1, 0x7FCE, 0xF4E2, 0x7FD5, 0xF4E3, 0x7FE5, 0xF4E4, 0x7FE1, 0xF4E5, 0x7FE6, 0xF4E6, 0x7FE9, 0xF4E7, 0x7FEE, 0xF4E8, 0x7FF3, - 0xF4E9, 0x7CF8, 0xF4EA, 0x7D77, 0xF4EB, 0x7DA6, 0xF4EC, 0x7DAE, 0xF4ED, 0x7E47, 0xF4EE, 0x7E9B, 0xF4EF, 0x9EB8, 0xF4F0, 0x9EB4, - 0xF4F1, 0x8D73, 0xF4F2, 0x8D84, 0xF4F3, 0x8D94, 0xF4F4, 0x8D91, 0xF4F5, 0x8DB1, 0xF4F6, 0x8D67, 0xF4F7, 0x8D6D, 0xF4F8, 0x8C47, - 0xF4F9, 0x8C49, 0xF4FA, 0x914A, 0xF4FB, 0x9150, 0xF4FC, 0x914E, 0xF4FD, 0x914F, 0xF4FE, 0x9164, 0xF540, 0x9B7C, 0xF541, 0x9B7D, - 0xF542, 0x9B7E, 0xF543, 0x9B7F, 0xF544, 0x9B80, 0xF545, 0x9B81, 0xF546, 0x9B82, 0xF547, 0x9B83, 0xF548, 0x9B84, 0xF549, 0x9B85, - 0xF54A, 0x9B86, 0xF54B, 0x9B87, 0xF54C, 0x9B88, 0xF54D, 0x9B89, 0xF54E, 0x9B8A, 0xF54F, 0x9B8B, 0xF550, 0x9B8C, 0xF551, 0x9B8D, - 0xF552, 0x9B8E, 0xF553, 0x9B8F, 0xF554, 0x9B90, 0xF555, 0x9B91, 0xF556, 0x9B92, 0xF557, 0x9B93, 0xF558, 0x9B94, 0xF559, 0x9B95, - 0xF55A, 0x9B96, 0xF55B, 0x9B97, 0xF55C, 0x9B98, 0xF55D, 0x9B99, 0xF55E, 0x9B9A, 0xF55F, 0x9B9B, 0xF560, 0x9B9C, 0xF561, 0x9B9D, - 0xF562, 0x9B9E, 0xF563, 0x9B9F, 0xF564, 0x9BA0, 0xF565, 0x9BA1, 0xF566, 0x9BA2, 0xF567, 0x9BA3, 0xF568, 0x9BA4, 0xF569, 0x9BA5, - 0xF56A, 0x9BA6, 0xF56B, 0x9BA7, 0xF56C, 0x9BA8, 0xF56D, 0x9BA9, 0xF56E, 0x9BAA, 0xF56F, 0x9BAB, 0xF570, 0x9BAC, 0xF571, 0x9BAD, - 0xF572, 0x9BAE, 0xF573, 0x9BAF, 0xF574, 0x9BB0, 0xF575, 0x9BB1, 0xF576, 0x9BB2, 0xF577, 0x9BB3, 0xF578, 0x9BB4, 0xF579, 0x9BB5, - 0xF57A, 0x9BB6, 0xF57B, 0x9BB7, 0xF57C, 0x9BB8, 0xF57D, 0x9BB9, 0xF57E, 0x9BBA, 0xF580, 0x9BBB, 0xF581, 0x9BBC, 0xF582, 0x9BBD, - 0xF583, 0x9BBE, 0xF584, 0x9BBF, 0xF585, 0x9BC0, 0xF586, 0x9BC1, 0xF587, 0x9BC2, 0xF588, 0x9BC3, 0xF589, 0x9BC4, 0xF58A, 0x9BC5, - 0xF58B, 0x9BC6, 0xF58C, 0x9BC7, 0xF58D, 0x9BC8, 0xF58E, 0x9BC9, 0xF58F, 0x9BCA, 0xF590, 0x9BCB, 0xF591, 0x9BCC, 0xF592, 0x9BCD, - 0xF593, 0x9BCE, 0xF594, 0x9BCF, 0xF595, 0x9BD0, 0xF596, 0x9BD1, 0xF597, 0x9BD2, 0xF598, 0x9BD3, 0xF599, 0x9BD4, 0xF59A, 0x9BD5, - 0xF59B, 0x9BD6, 0xF59C, 0x9BD7, 0xF59D, 0x9BD8, 0xF59E, 0x9BD9, 0xF59F, 0x9BDA, 0xF5A0, 0x9BDB, 0xF5A1, 0x9162, 0xF5A2, 0x9161, - 0xF5A3, 0x9170, 0xF5A4, 0x9169, 0xF5A5, 0x916F, 0xF5A6, 0x917D, 0xF5A7, 0x917E, 0xF5A8, 0x9172, 0xF5A9, 0x9174, 0xF5AA, 0x9179, - 0xF5AB, 0x918C, 0xF5AC, 0x9185, 0xF5AD, 0x9190, 0xF5AE, 0x918D, 0xF5AF, 0x9191, 0xF5B0, 0x91A2, 0xF5B1, 0x91A3, 0xF5B2, 0x91AA, - 0xF5B3, 0x91AD, 0xF5B4, 0x91AE, 0xF5B5, 0x91AF, 0xF5B6, 0x91B5, 0xF5B7, 0x91B4, 0xF5B8, 0x91BA, 0xF5B9, 0x8C55, 0xF5BA, 0x9E7E, - 0xF5BB, 0x8DB8, 0xF5BC, 0x8DEB, 0xF5BD, 0x8E05, 0xF5BE, 0x8E59, 0xF5BF, 0x8E69, 0xF5C0, 0x8DB5, 0xF5C1, 0x8DBF, 0xF5C2, 0x8DBC, - 0xF5C3, 0x8DBA, 0xF5C4, 0x8DC4, 0xF5C5, 0x8DD6, 0xF5C6, 0x8DD7, 0xF5C7, 0x8DDA, 0xF5C8, 0x8DDE, 0xF5C9, 0x8DCE, 0xF5CA, 0x8DCF, - 0xF5CB, 0x8DDB, 0xF5CC, 0x8DC6, 0xF5CD, 0x8DEC, 0xF5CE, 0x8DF7, 0xF5CF, 0x8DF8, 0xF5D0, 0x8DE3, 0xF5D1, 0x8DF9, 0xF5D2, 0x8DFB, - 0xF5D3, 0x8DE4, 0xF5D4, 0x8E09, 0xF5D5, 0x8DFD, 0xF5D6, 0x8E14, 0xF5D7, 0x8E1D, 0xF5D8, 0x8E1F, 0xF5D9, 0x8E2C, 0xF5DA, 0x8E2E, - 0xF5DB, 0x8E23, 0xF5DC, 0x8E2F, 0xF5DD, 0x8E3A, 0xF5DE, 0x8E40, 0xF5DF, 0x8E39, 0xF5E0, 0x8E35, 0xF5E1, 0x8E3D, 0xF5E2, 0x8E31, - 0xF5E3, 0x8E49, 0xF5E4, 0x8E41, 0xF5E5, 0x8E42, 0xF5E6, 0x8E51, 0xF5E7, 0x8E52, 0xF5E8, 0x8E4A, 0xF5E9, 0x8E70, 0xF5EA, 0x8E76, - 0xF5EB, 0x8E7C, 0xF5EC, 0x8E6F, 0xF5ED, 0x8E74, 0xF5EE, 0x8E85, 0xF5EF, 0x8E8F, 0xF5F0, 0x8E94, 0xF5F1, 0x8E90, 0xF5F2, 0x8E9C, - 0xF5F3, 0x8E9E, 0xF5F4, 0x8C78, 0xF5F5, 0x8C82, 0xF5F6, 0x8C8A, 0xF5F7, 0x8C85, 0xF5F8, 0x8C98, 0xF5F9, 0x8C94, 0xF5FA, 0x659B, - 0xF5FB, 0x89D6, 0xF5FC, 0x89DE, 0xF5FD, 0x89DA, 0xF5FE, 0x89DC, 0xF640, 0x9BDC, 0xF641, 0x9BDD, 0xF642, 0x9BDE, 0xF643, 0x9BDF, - 0xF644, 0x9BE0, 0xF645, 0x9BE1, 0xF646, 0x9BE2, 0xF647, 0x9BE3, 0xF648, 0x9BE4, 0xF649, 0x9BE5, 0xF64A, 0x9BE6, 0xF64B, 0x9BE7, - 0xF64C, 0x9BE8, 0xF64D, 0x9BE9, 0xF64E, 0x9BEA, 0xF64F, 0x9BEB, 0xF650, 0x9BEC, 0xF651, 0x9BED, 0xF652, 0x9BEE, 0xF653, 0x9BEF, - 0xF654, 0x9BF0, 0xF655, 0x9BF1, 0xF656, 0x9BF2, 0xF657, 0x9BF3, 0xF658, 0x9BF4, 0xF659, 0x9BF5, 0xF65A, 0x9BF6, 0xF65B, 0x9BF7, - 0xF65C, 0x9BF8, 0xF65D, 0x9BF9, 0xF65E, 0x9BFA, 0xF65F, 0x9BFB, 0xF660, 0x9BFC, 0xF661, 0x9BFD, 0xF662, 0x9BFE, 0xF663, 0x9BFF, - 0xF664, 0x9C00, 0xF665, 0x9C01, 0xF666, 0x9C02, 0xF667, 0x9C03, 0xF668, 0x9C04, 0xF669, 0x9C05, 0xF66A, 0x9C06, 0xF66B, 0x9C07, - 0xF66C, 0x9C08, 0xF66D, 0x9C09, 0xF66E, 0x9C0A, 0xF66F, 0x9C0B, 0xF670, 0x9C0C, 0xF671, 0x9C0D, 0xF672, 0x9C0E, 0xF673, 0x9C0F, - 0xF674, 0x9C10, 0xF675, 0x9C11, 0xF676, 0x9C12, 0xF677, 0x9C13, 0xF678, 0x9C14, 0xF679, 0x9C15, 0xF67A, 0x9C16, 0xF67B, 0x9C17, - 0xF67C, 0x9C18, 0xF67D, 0x9C19, 0xF67E, 0x9C1A, 0xF680, 0x9C1B, 0xF681, 0x9C1C, 0xF682, 0x9C1D, 0xF683, 0x9C1E, 0xF684, 0x9C1F, - 0xF685, 0x9C20, 0xF686, 0x9C21, 0xF687, 0x9C22, 0xF688, 0x9C23, 0xF689, 0x9C24, 0xF68A, 0x9C25, 0xF68B, 0x9C26, 0xF68C, 0x9C27, - 0xF68D, 0x9C28, 0xF68E, 0x9C29, 0xF68F, 0x9C2A, 0xF690, 0x9C2B, 0xF691, 0x9C2C, 0xF692, 0x9C2D, 0xF693, 0x9C2E, 0xF694, 0x9C2F, - 0xF695, 0x9C30, 0xF696, 0x9C31, 0xF697, 0x9C32, 0xF698, 0x9C33, 0xF699, 0x9C34, 0xF69A, 0x9C35, 0xF69B, 0x9C36, 0xF69C, 0x9C37, - 0xF69D, 0x9C38, 0xF69E, 0x9C39, 0xF69F, 0x9C3A, 0xF6A0, 0x9C3B, 0xF6A1, 0x89E5, 0xF6A2, 0x89EB, 0xF6A3, 0x89EF, 0xF6A4, 0x8A3E, - 0xF6A5, 0x8B26, 0xF6A6, 0x9753, 0xF6A7, 0x96E9, 0xF6A8, 0x96F3, 0xF6A9, 0x96EF, 0xF6AA, 0x9706, 0xF6AB, 0x9701, 0xF6AC, 0x9708, - 0xF6AD, 0x970F, 0xF6AE, 0x970E, 0xF6AF, 0x972A, 0xF6B0, 0x972D, 0xF6B1, 0x9730, 0xF6B2, 0x973E, 0xF6B3, 0x9F80, 0xF6B4, 0x9F83, - 0xF6B5, 0x9F85, 0xF6B6, 0x9F86, 0xF6B7, 0x9F87, 0xF6B8, 0x9F88, 0xF6B9, 0x9F89, 0xF6BA, 0x9F8A, 0xF6BB, 0x9F8C, 0xF6BC, 0x9EFE, - 0xF6BD, 0x9F0B, 0xF6BE, 0x9F0D, 0xF6BF, 0x96B9, 0xF6C0, 0x96BC, 0xF6C1, 0x96BD, 0xF6C2, 0x96CE, 0xF6C3, 0x96D2, 0xF6C4, 0x77BF, - 0xF6C5, 0x96E0, 0xF6C6, 0x928E, 0xF6C7, 0x92AE, 0xF6C8, 0x92C8, 0xF6C9, 0x933E, 0xF6CA, 0x936A, 0xF6CB, 0x93CA, 0xF6CC, 0x938F, - 0xF6CD, 0x943E, 0xF6CE, 0x946B, 0xF6CF, 0x9C7F, 0xF6D0, 0x9C82, 0xF6D1, 0x9C85, 0xF6D2, 0x9C86, 0xF6D3, 0x9C87, 0xF6D4, 0x9C88, - 0xF6D5, 0x7A23, 0xF6D6, 0x9C8B, 0xF6D7, 0x9C8E, 0xF6D8, 0x9C90, 0xF6D9, 0x9C91, 0xF6DA, 0x9C92, 0xF6DB, 0x9C94, 0xF6DC, 0x9C95, - 0xF6DD, 0x9C9A, 0xF6DE, 0x9C9B, 0xF6DF, 0x9C9E, 0xF6E0, 0x9C9F, 0xF6E1, 0x9CA0, 0xF6E2, 0x9CA1, 0xF6E3, 0x9CA2, 0xF6E4, 0x9CA3, - 0xF6E5, 0x9CA5, 0xF6E6, 0x9CA6, 0xF6E7, 0x9CA7, 0xF6E8, 0x9CA8, 0xF6E9, 0x9CA9, 0xF6EA, 0x9CAB, 0xF6EB, 0x9CAD, 0xF6EC, 0x9CAE, - 0xF6ED, 0x9CB0, 0xF6EE, 0x9CB1, 0xF6EF, 0x9CB2, 0xF6F0, 0x9CB3, 0xF6F1, 0x9CB4, 0xF6F2, 0x9CB5, 0xF6F3, 0x9CB6, 0xF6F4, 0x9CB7, - 0xF6F5, 0x9CBA, 0xF6F6, 0x9CBB, 0xF6F7, 0x9CBC, 0xF6F8, 0x9CBD, 0xF6F9, 0x9CC4, 0xF6FA, 0x9CC5, 0xF6FB, 0x9CC6, 0xF6FC, 0x9CC7, - 0xF6FD, 0x9CCA, 0xF6FE, 0x9CCB, 0xF740, 0x9C3C, 0xF741, 0x9C3D, 0xF742, 0x9C3E, 0xF743, 0x9C3F, 0xF744, 0x9C40, 0xF745, 0x9C41, - 0xF746, 0x9C42, 0xF747, 0x9C43, 0xF748, 0x9C44, 0xF749, 0x9C45, 0xF74A, 0x9C46, 0xF74B, 0x9C47, 0xF74C, 0x9C48, 0xF74D, 0x9C49, - 0xF74E, 0x9C4A, 0xF74F, 0x9C4B, 0xF750, 0x9C4C, 0xF751, 0x9C4D, 0xF752, 0x9C4E, 0xF753, 0x9C4F, 0xF754, 0x9C50, 0xF755, 0x9C51, - 0xF756, 0x9C52, 0xF757, 0x9C53, 0xF758, 0x9C54, 0xF759, 0x9C55, 0xF75A, 0x9C56, 0xF75B, 0x9C57, 0xF75C, 0x9C58, 0xF75D, 0x9C59, - 0xF75E, 0x9C5A, 0xF75F, 0x9C5B, 0xF760, 0x9C5C, 0xF761, 0x9C5D, 0xF762, 0x9C5E, 0xF763, 0x9C5F, 0xF764, 0x9C60, 0xF765, 0x9C61, - 0xF766, 0x9C62, 0xF767, 0x9C63, 0xF768, 0x9C64, 0xF769, 0x9C65, 0xF76A, 0x9C66, 0xF76B, 0x9C67, 0xF76C, 0x9C68, 0xF76D, 0x9C69, - 0xF76E, 0x9C6A, 0xF76F, 0x9C6B, 0xF770, 0x9C6C, 0xF771, 0x9C6D, 0xF772, 0x9C6E, 0xF773, 0x9C6F, 0xF774, 0x9C70, 0xF775, 0x9C71, - 0xF776, 0x9C72, 0xF777, 0x9C73, 0xF778, 0x9C74, 0xF779, 0x9C75, 0xF77A, 0x9C76, 0xF77B, 0x9C77, 0xF77C, 0x9C78, 0xF77D, 0x9C79, - 0xF77E, 0x9C7A, 0xF780, 0x9C7B, 0xF781, 0x9C7D, 0xF782, 0x9C7E, 0xF783, 0x9C80, 0xF784, 0x9C83, 0xF785, 0x9C84, 0xF786, 0x9C89, - 0xF787, 0x9C8A, 0xF788, 0x9C8C, 0xF789, 0x9C8F, 0xF78A, 0x9C93, 0xF78B, 0x9C96, 0xF78C, 0x9C97, 0xF78D, 0x9C98, 0xF78E, 0x9C99, - 0xF78F, 0x9C9D, 0xF790, 0x9CAA, 0xF791, 0x9CAC, 0xF792, 0x9CAF, 0xF793, 0x9CB9, 0xF794, 0x9CBE, 0xF795, 0x9CBF, 0xF796, 0x9CC0, - 0xF797, 0x9CC1, 0xF798, 0x9CC2, 0xF799, 0x9CC8, 0xF79A, 0x9CC9, 0xF79B, 0x9CD1, 0xF79C, 0x9CD2, 0xF79D, 0x9CDA, 0xF79E, 0x9CDB, - 0xF79F, 0x9CE0, 0xF7A0, 0x9CE1, 0xF7A1, 0x9CCC, 0xF7A2, 0x9CCD, 0xF7A3, 0x9CCE, 0xF7A4, 0x9CCF, 0xF7A5, 0x9CD0, 0xF7A6, 0x9CD3, - 0xF7A7, 0x9CD4, 0xF7A8, 0x9CD5, 0xF7A9, 0x9CD7, 0xF7AA, 0x9CD8, 0xF7AB, 0x9CD9, 0xF7AC, 0x9CDC, 0xF7AD, 0x9CDD, 0xF7AE, 0x9CDF, - 0xF7AF, 0x9CE2, 0xF7B0, 0x977C, 0xF7B1, 0x9785, 0xF7B2, 0x9791, 0xF7B3, 0x9792, 0xF7B4, 0x9794, 0xF7B5, 0x97AF, 0xF7B6, 0x97AB, - 0xF7B7, 0x97A3, 0xF7B8, 0x97B2, 0xF7B9, 0x97B4, 0xF7BA, 0x9AB1, 0xF7BB, 0x9AB0, 0xF7BC, 0x9AB7, 0xF7BD, 0x9E58, 0xF7BE, 0x9AB6, - 0xF7BF, 0x9ABA, 0xF7C0, 0x9ABC, 0xF7C1, 0x9AC1, 0xF7C2, 0x9AC0, 0xF7C3, 0x9AC5, 0xF7C4, 0x9AC2, 0xF7C5, 0x9ACB, 0xF7C6, 0x9ACC, - 0xF7C7, 0x9AD1, 0xF7C8, 0x9B45, 0xF7C9, 0x9B43, 0xF7CA, 0x9B47, 0xF7CB, 0x9B49, 0xF7CC, 0x9B48, 0xF7CD, 0x9B4D, 0xF7CE, 0x9B51, - 0xF7CF, 0x98E8, 0xF7D0, 0x990D, 0xF7D1, 0x992E, 0xF7D2, 0x9955, 0xF7D3, 0x9954, 0xF7D4, 0x9ADF, 0xF7D5, 0x9AE1, 0xF7D6, 0x9AE6, - 0xF7D7, 0x9AEF, 0xF7D8, 0x9AEB, 0xF7D9, 0x9AFB, 0xF7DA, 0x9AED, 0xF7DB, 0x9AF9, 0xF7DC, 0x9B08, 0xF7DD, 0x9B0F, 0xF7DE, 0x9B13, - 0xF7DF, 0x9B1F, 0xF7E0, 0x9B23, 0xF7E1, 0x9EBD, 0xF7E2, 0x9EBE, 0xF7E3, 0x7E3B, 0xF7E4, 0x9E82, 0xF7E5, 0x9E87, 0xF7E6, 0x9E88, - 0xF7E7, 0x9E8B, 0xF7E8, 0x9E92, 0xF7E9, 0x93D6, 0xF7EA, 0x9E9D, 0xF7EB, 0x9E9F, 0xF7EC, 0x9EDB, 0xF7ED, 0x9EDC, 0xF7EE, 0x9EDD, - 0xF7EF, 0x9EE0, 0xF7F0, 0x9EDF, 0xF7F1, 0x9EE2, 0xF7F2, 0x9EE9, 0xF7F3, 0x9EE7, 0xF7F4, 0x9EE5, 0xF7F5, 0x9EEA, 0xF7F6, 0x9EEF, - 0xF7F7, 0x9F22, 0xF7F8, 0x9F2C, 0xF7F9, 0x9F2F, 0xF7FA, 0x9F39, 0xF7FB, 0x9F37, 0xF7FC, 0x9F3D, 0xF7FD, 0x9F3E, 0xF7FE, 0x9F44, - 0xF840, 0x9CE3, 0xF841, 0x9CE4, 0xF842, 0x9CE5, 0xF843, 0x9CE6, 0xF844, 0x9CE7, 0xF845, 0x9CE8, 0xF846, 0x9CE9, 0xF847, 0x9CEA, - 0xF848, 0x9CEB, 0xF849, 0x9CEC, 0xF84A, 0x9CED, 0xF84B, 0x9CEE, 0xF84C, 0x9CEF, 0xF84D, 0x9CF0, 0xF84E, 0x9CF1, 0xF84F, 0x9CF2, - 0xF850, 0x9CF3, 0xF851, 0x9CF4, 0xF852, 0x9CF5, 0xF853, 0x9CF6, 0xF854, 0x9CF7, 0xF855, 0x9CF8, 0xF856, 0x9CF9, 0xF857, 0x9CFA, - 0xF858, 0x9CFB, 0xF859, 0x9CFC, 0xF85A, 0x9CFD, 0xF85B, 0x9CFE, 0xF85C, 0x9CFF, 0xF85D, 0x9D00, 0xF85E, 0x9D01, 0xF85F, 0x9D02, - 0xF860, 0x9D03, 0xF861, 0x9D04, 0xF862, 0x9D05, 0xF863, 0x9D06, 0xF864, 0x9D07, 0xF865, 0x9D08, 0xF866, 0x9D09, 0xF867, 0x9D0A, - 0xF868, 0x9D0B, 0xF869, 0x9D0C, 0xF86A, 0x9D0D, 0xF86B, 0x9D0E, 0xF86C, 0x9D0F, 0xF86D, 0x9D10, 0xF86E, 0x9D11, 0xF86F, 0x9D12, - 0xF870, 0x9D13, 0xF871, 0x9D14, 0xF872, 0x9D15, 0xF873, 0x9D16, 0xF874, 0x9D17, 0xF875, 0x9D18, 0xF876, 0x9D19, 0xF877, 0x9D1A, - 0xF878, 0x9D1B, 0xF879, 0x9D1C, 0xF87A, 0x9D1D, 0xF87B, 0x9D1E, 0xF87C, 0x9D1F, 0xF87D, 0x9D20, 0xF87E, 0x9D21, 0xF880, 0x9D22, - 0xF881, 0x9D23, 0xF882, 0x9D24, 0xF883, 0x9D25, 0xF884, 0x9D26, 0xF885, 0x9D27, 0xF886, 0x9D28, 0xF887, 0x9D29, 0xF888, 0x9D2A, - 0xF889, 0x9D2B, 0xF88A, 0x9D2C, 0xF88B, 0x9D2D, 0xF88C, 0x9D2E, 0xF88D, 0x9D2F, 0xF88E, 0x9D30, 0xF88F, 0x9D31, 0xF890, 0x9D32, - 0xF891, 0x9D33, 0xF892, 0x9D34, 0xF893, 0x9D35, 0xF894, 0x9D36, 0xF895, 0x9D37, 0xF896, 0x9D38, 0xF897, 0x9D39, 0xF898, 0x9D3A, - 0xF899, 0x9D3B, 0xF89A, 0x9D3C, 0xF89B, 0x9D3D, 0xF89C, 0x9D3E, 0xF89D, 0x9D3F, 0xF89E, 0x9D40, 0xF89F, 0x9D41, 0xF8A0, 0x9D42, - 0xF940, 0x9D43, 0xF941, 0x9D44, 0xF942, 0x9D45, 0xF943, 0x9D46, 0xF944, 0x9D47, 0xF945, 0x9D48, 0xF946, 0x9D49, 0xF947, 0x9D4A, - 0xF948, 0x9D4B, 0xF949, 0x9D4C, 0xF94A, 0x9D4D, 0xF94B, 0x9D4E, 0xF94C, 0x9D4F, 0xF94D, 0x9D50, 0xF94E, 0x9D51, 0xF94F, 0x9D52, - 0xF950, 0x9D53, 0xF951, 0x9D54, 0xF952, 0x9D55, 0xF953, 0x9D56, 0xF954, 0x9D57, 0xF955, 0x9D58, 0xF956, 0x9D59, 0xF957, 0x9D5A, - 0xF958, 0x9D5B, 0xF959, 0x9D5C, 0xF95A, 0x9D5D, 0xF95B, 0x9D5E, 0xF95C, 0x9D5F, 0xF95D, 0x9D60, 0xF95E, 0x9D61, 0xF95F, 0x9D62, - 0xF960, 0x9D63, 0xF961, 0x9D64, 0xF962, 0x9D65, 0xF963, 0x9D66, 0xF964, 0x9D67, 0xF965, 0x9D68, 0xF966, 0x9D69, 0xF967, 0x9D6A, - 0xF968, 0x9D6B, 0xF969, 0x9D6C, 0xF96A, 0x9D6D, 0xF96B, 0x9D6E, 0xF96C, 0x9D6F, 0xF96D, 0x9D70, 0xF96E, 0x9D71, 0xF96F, 0x9D72, - 0xF970, 0x9D73, 0xF971, 0x9D74, 0xF972, 0x9D75, 0xF973, 0x9D76, 0xF974, 0x9D77, 0xF975, 0x9D78, 0xF976, 0x9D79, 0xF977, 0x9D7A, - 0xF978, 0x9D7B, 0xF979, 0x9D7C, 0xF97A, 0x9D7D, 0xF97B, 0x9D7E, 0xF97C, 0x9D7F, 0xF97D, 0x9D80, 0xF97E, 0x9D81, 0xF980, 0x9D82, - 0xF981, 0x9D83, 0xF982, 0x9D84, 0xF983, 0x9D85, 0xF984, 0x9D86, 0xF985, 0x9D87, 0xF986, 0x9D88, 0xF987, 0x9D89, 0xF988, 0x9D8A, - 0xF989, 0x9D8B, 0xF98A, 0x9D8C, 0xF98B, 0x9D8D, 0xF98C, 0x9D8E, 0xF98D, 0x9D8F, 0xF98E, 0x9D90, 0xF98F, 0x9D91, 0xF990, 0x9D92, - 0xF991, 0x9D93, 0xF992, 0x9D94, 0xF993, 0x9D95, 0xF994, 0x9D96, 0xF995, 0x9D97, 0xF996, 0x9D98, 0xF997, 0x9D99, 0xF998, 0x9D9A, - 0xF999, 0x9D9B, 0xF99A, 0x9D9C, 0xF99B, 0x9D9D, 0xF99C, 0x9D9E, 0xF99D, 0x9D9F, 0xF99E, 0x9DA0, 0xF99F, 0x9DA1, 0xF9A0, 0x9DA2, - 0xFA40, 0x9DA3, 0xFA41, 0x9DA4, 0xFA42, 0x9DA5, 0xFA43, 0x9DA6, 0xFA44, 0x9DA7, 0xFA45, 0x9DA8, 0xFA46, 0x9DA9, 0xFA47, 0x9DAA, - 0xFA48, 0x9DAB, 0xFA49, 0x9DAC, 0xFA4A, 0x9DAD, 0xFA4B, 0x9DAE, 0xFA4C, 0x9DAF, 0xFA4D, 0x9DB0, 0xFA4E, 0x9DB1, 0xFA4F, 0x9DB2, - 0xFA50, 0x9DB3, 0xFA51, 0x9DB4, 0xFA52, 0x9DB5, 0xFA53, 0x9DB6, 0xFA54, 0x9DB7, 0xFA55, 0x9DB8, 0xFA56, 0x9DB9, 0xFA57, 0x9DBA, - 0xFA58, 0x9DBB, 0xFA59, 0x9DBC, 0xFA5A, 0x9DBD, 0xFA5B, 0x9DBE, 0xFA5C, 0x9DBF, 0xFA5D, 0x9DC0, 0xFA5E, 0x9DC1, 0xFA5F, 0x9DC2, - 0xFA60, 0x9DC3, 0xFA61, 0x9DC4, 0xFA62, 0x9DC5, 0xFA63, 0x9DC6, 0xFA64, 0x9DC7, 0xFA65, 0x9DC8, 0xFA66, 0x9DC9, 0xFA67, 0x9DCA, - 0xFA68, 0x9DCB, 0xFA69, 0x9DCC, 0xFA6A, 0x9DCD, 0xFA6B, 0x9DCE, 0xFA6C, 0x9DCF, 0xFA6D, 0x9DD0, 0xFA6E, 0x9DD1, 0xFA6F, 0x9DD2, - 0xFA70, 0x9DD3, 0xFA71, 0x9DD4, 0xFA72, 0x9DD5, 0xFA73, 0x9DD6, 0xFA74, 0x9DD7, 0xFA75, 0x9DD8, 0xFA76, 0x9DD9, 0xFA77, 0x9DDA, - 0xFA78, 0x9DDB, 0xFA79, 0x9DDC, 0xFA7A, 0x9DDD, 0xFA7B, 0x9DDE, 0xFA7C, 0x9DDF, 0xFA7D, 0x9DE0, 0xFA7E, 0x9DE1, 0xFA80, 0x9DE2, - 0xFA81, 0x9DE3, 0xFA82, 0x9DE4, 0xFA83, 0x9DE5, 0xFA84, 0x9DE6, 0xFA85, 0x9DE7, 0xFA86, 0x9DE8, 0xFA87, 0x9DE9, 0xFA88, 0x9DEA, - 0xFA89, 0x9DEB, 0xFA8A, 0x9DEC, 0xFA8B, 0x9DED, 0xFA8C, 0x9DEE, 0xFA8D, 0x9DEF, 0xFA8E, 0x9DF0, 0xFA8F, 0x9DF1, 0xFA90, 0x9DF2, - 0xFA91, 0x9DF3, 0xFA92, 0x9DF4, 0xFA93, 0x9DF5, 0xFA94, 0x9DF6, 0xFA95, 0x9DF7, 0xFA96, 0x9DF8, 0xFA97, 0x9DF9, 0xFA98, 0x9DFA, - 0xFA99, 0x9DFB, 0xFA9A, 0x9DFC, 0xFA9B, 0x9DFD, 0xFA9C, 0x9DFE, 0xFA9D, 0x9DFF, 0xFA9E, 0x9E00, 0xFA9F, 0x9E01, 0xFAA0, 0x9E02, - 0xFB40, 0x9E03, 0xFB41, 0x9E04, 0xFB42, 0x9E05, 0xFB43, 0x9E06, 0xFB44, 0x9E07, 0xFB45, 0x9E08, 0xFB46, 0x9E09, 0xFB47, 0x9E0A, - 0xFB48, 0x9E0B, 0xFB49, 0x9E0C, 0xFB4A, 0x9E0D, 0xFB4B, 0x9E0E, 0xFB4C, 0x9E0F, 0xFB4D, 0x9E10, 0xFB4E, 0x9E11, 0xFB4F, 0x9E12, - 0xFB50, 0x9E13, 0xFB51, 0x9E14, 0xFB52, 0x9E15, 0xFB53, 0x9E16, 0xFB54, 0x9E17, 0xFB55, 0x9E18, 0xFB56, 0x9E19, 0xFB57, 0x9E1A, - 0xFB58, 0x9E1B, 0xFB59, 0x9E1C, 0xFB5A, 0x9E1D, 0xFB5B, 0x9E1E, 0xFB5C, 0x9E24, 0xFB5D, 0x9E27, 0xFB5E, 0x9E2E, 0xFB5F, 0x9E30, - 0xFB60, 0x9E34, 0xFB61, 0x9E3B, 0xFB62, 0x9E3C, 0xFB63, 0x9E40, 0xFB64, 0x9E4D, 0xFB65, 0x9E50, 0xFB66, 0x9E52, 0xFB67, 0x9E53, - 0xFB68, 0x9E54, 0xFB69, 0x9E56, 0xFB6A, 0x9E59, 0xFB6B, 0x9E5D, 0xFB6C, 0x9E5F, 0xFB6D, 0x9E60, 0xFB6E, 0x9E61, 0xFB6F, 0x9E62, - 0xFB70, 0x9E65, 0xFB71, 0x9E6E, 0xFB72, 0x9E6F, 0xFB73, 0x9E72, 0xFB74, 0x9E74, 0xFB75, 0x9E75, 0xFB76, 0x9E76, 0xFB77, 0x9E77, - 0xFB78, 0x9E78, 0xFB79, 0x9E79, 0xFB7A, 0x9E7A, 0xFB7B, 0x9E7B, 0xFB7C, 0x9E7C, 0xFB7D, 0x9E7D, 0xFB7E, 0x9E80, 0xFB80, 0x9E81, - 0xFB81, 0x9E83, 0xFB82, 0x9E84, 0xFB83, 0x9E85, 0xFB84, 0x9E86, 0xFB85, 0x9E89, 0xFB86, 0x9E8A, 0xFB87, 0x9E8C, 0xFB88, 0x9E8D, - 0xFB89, 0x9E8E, 0xFB8A, 0x9E8F, 0xFB8B, 0x9E90, 0xFB8C, 0x9E91, 0xFB8D, 0x9E94, 0xFB8E, 0x9E95, 0xFB8F, 0x9E96, 0xFB90, 0x9E97, - 0xFB91, 0x9E98, 0xFB92, 0x9E99, 0xFB93, 0x9E9A, 0xFB94, 0x9E9B, 0xFB95, 0x9E9C, 0xFB96, 0x9E9E, 0xFB97, 0x9EA0, 0xFB98, 0x9EA1, - 0xFB99, 0x9EA2, 0xFB9A, 0x9EA3, 0xFB9B, 0x9EA4, 0xFB9C, 0x9EA5, 0xFB9D, 0x9EA7, 0xFB9E, 0x9EA8, 0xFB9F, 0x9EA9, 0xFBA0, 0x9EAA, - 0xFC40, 0x9EAB, 0xFC41, 0x9EAC, 0xFC42, 0x9EAD, 0xFC43, 0x9EAE, 0xFC44, 0x9EAF, 0xFC45, 0x9EB0, 0xFC46, 0x9EB1, 0xFC47, 0x9EB2, - 0xFC48, 0x9EB3, 0xFC49, 0x9EB5, 0xFC4A, 0x9EB6, 0xFC4B, 0x9EB7, 0xFC4C, 0x9EB9, 0xFC4D, 0x9EBA, 0xFC4E, 0x9EBC, 0xFC4F, 0x9EBF, - 0xFC50, 0x9EC0, 0xFC51, 0x9EC1, 0xFC52, 0x9EC2, 0xFC53, 0x9EC3, 0xFC54, 0x9EC5, 0xFC55, 0x9EC6, 0xFC56, 0x9EC7, 0xFC57, 0x9EC8, - 0xFC58, 0x9ECA, 0xFC59, 0x9ECB, 0xFC5A, 0x9ECC, 0xFC5B, 0x9ED0, 0xFC5C, 0x9ED2, 0xFC5D, 0x9ED3, 0xFC5E, 0x9ED5, 0xFC5F, 0x9ED6, - 0xFC60, 0x9ED7, 0xFC61, 0x9ED9, 0xFC62, 0x9EDA, 0xFC63, 0x9EDE, 0xFC64, 0x9EE1, 0xFC65, 0x9EE3, 0xFC66, 0x9EE4, 0xFC67, 0x9EE6, - 0xFC68, 0x9EE8, 0xFC69, 0x9EEB, 0xFC6A, 0x9EEC, 0xFC6B, 0x9EED, 0xFC6C, 0x9EEE, 0xFC6D, 0x9EF0, 0xFC6E, 0x9EF1, 0xFC6F, 0x9EF2, - 0xFC70, 0x9EF3, 0xFC71, 0x9EF4, 0xFC72, 0x9EF5, 0xFC73, 0x9EF6, 0xFC74, 0x9EF7, 0xFC75, 0x9EF8, 0xFC76, 0x9EFA, 0xFC77, 0x9EFD, - 0xFC78, 0x9EFF, 0xFC79, 0x9F00, 0xFC7A, 0x9F01, 0xFC7B, 0x9F02, 0xFC7C, 0x9F03, 0xFC7D, 0x9F04, 0xFC7E, 0x9F05, 0xFC80, 0x9F06, - 0xFC81, 0x9F07, 0xFC82, 0x9F08, 0xFC83, 0x9F09, 0xFC84, 0x9F0A, 0xFC85, 0x9F0C, 0xFC86, 0x9F0F, 0xFC87, 0x9F11, 0xFC88, 0x9F12, - 0xFC89, 0x9F14, 0xFC8A, 0x9F15, 0xFC8B, 0x9F16, 0xFC8C, 0x9F18, 0xFC8D, 0x9F1A, 0xFC8E, 0x9F1B, 0xFC8F, 0x9F1C, 0xFC90, 0x9F1D, - 0xFC91, 0x9F1E, 0xFC92, 0x9F1F, 0xFC93, 0x9F21, 0xFC94, 0x9F23, 0xFC95, 0x9F24, 0xFC96, 0x9F25, 0xFC97, 0x9F26, 0xFC98, 0x9F27, - 0xFC99, 0x9F28, 0xFC9A, 0x9F29, 0xFC9B, 0x9F2A, 0xFC9C, 0x9F2B, 0xFC9D, 0x9F2D, 0xFC9E, 0x9F2E, 0xFC9F, 0x9F30, 0xFCA0, 0x9F31, - 0xFD40, 0x9F32, 0xFD41, 0x9F33, 0xFD42, 0x9F34, 0xFD43, 0x9F35, 0xFD44, 0x9F36, 0xFD45, 0x9F38, 0xFD46, 0x9F3A, 0xFD47, 0x9F3C, - 0xFD48, 0x9F3F, 0xFD49, 0x9F40, 0xFD4A, 0x9F41, 0xFD4B, 0x9F42, 0xFD4C, 0x9F43, 0xFD4D, 0x9F45, 0xFD4E, 0x9F46, 0xFD4F, 0x9F47, - 0xFD50, 0x9F48, 0xFD51, 0x9F49, 0xFD52, 0x9F4A, 0xFD53, 0x9F4B, 0xFD54, 0x9F4C, 0xFD55, 0x9F4D, 0xFD56, 0x9F4E, 0xFD57, 0x9F4F, - 0xFD58, 0x9F52, 0xFD59, 0x9F53, 0xFD5A, 0x9F54, 0xFD5B, 0x9F55, 0xFD5C, 0x9F56, 0xFD5D, 0x9F57, 0xFD5E, 0x9F58, 0xFD5F, 0x9F59, - 0xFD60, 0x9F5A, 0xFD61, 0x9F5B, 0xFD62, 0x9F5C, 0xFD63, 0x9F5D, 0xFD64, 0x9F5E, 0xFD65, 0x9F5F, 0xFD66, 0x9F60, 0xFD67, 0x9F61, - 0xFD68, 0x9F62, 0xFD69, 0x9F63, 0xFD6A, 0x9F64, 0xFD6B, 0x9F65, 0xFD6C, 0x9F66, 0xFD6D, 0x9F67, 0xFD6E, 0x9F68, 0xFD6F, 0x9F69, - 0xFD70, 0x9F6A, 0xFD71, 0x9F6B, 0xFD72, 0x9F6C, 0xFD73, 0x9F6D, 0xFD74, 0x9F6E, 0xFD75, 0x9F6F, 0xFD76, 0x9F70, 0xFD77, 0x9F71, - 0xFD78, 0x9F72, 0xFD79, 0x9F73, 0xFD7A, 0x9F74, 0xFD7B, 0x9F75, 0xFD7C, 0x9F76, 0xFD7D, 0x9F77, 0xFD7E, 0x9F78, 0xFD80, 0x9F79, - 0xFD81, 0x9F7A, 0xFD82, 0x9F7B, 0xFD83, 0x9F7C, 0xFD84, 0x9F7D, 0xFD85, 0x9F7E, 0xFD86, 0x9F81, 0xFD87, 0x9F82, 0xFD88, 0x9F8D, - 0xFD89, 0x9F8E, 0xFD8A, 0x9F8F, 0xFD8B, 0x9F90, 0xFD8C, 0x9F91, 0xFD8D, 0x9F92, 0xFD8E, 0x9F93, 0xFD8F, 0x9F94, 0xFD90, 0x9F95, - 0xFD91, 0x9F96, 0xFD92, 0x9F97, 0xFD93, 0x9F98, 0xFD94, 0x9F9C, 0xFD95, 0x9F9D, 0xFD96, 0x9F9E, 0xFD97, 0x9FA1, 0xFD98, 0x9FA2, - 0xFD99, 0x9FA3, 0xFD9A, 0x9FA4, 0xFD9B, 0x9FA5, 0xFD9C, 0xF92C, 0xFD9D, 0xF979, 0xFD9E, 0xF995, 0xFD9F, 0xF9E7, 0xFDA0, 0xF9F1, - 0xFE40, 0xFA0C, 0xFE41, 0xFA0D, 0xFE42, 0xFA0E, 0xFE43, 0xFA0F, 0xFE44, 0xFA11, 0xFE45, 0xFA13, 0xFE46, 0xFA14, 0xFE47, 0xFA18, - 0xFE48, 0xFA1F, 0xFE49, 0xFA20, 0xFE4A, 0xFA21, 0xFE4B, 0xFA23, 0xFE4C, 0xFA24, 0xFE4D, 0xFA27, 0xFE4E, 0xFA28, 0xFE4F, 0xFA29, - 0, 0 -}; -#endif - -#if FF_CODE_PAGE == 949 || FF_CODE_PAGE == 0 /* Korean */ -static const WCHAR uni2oem949[] = { /* Unicode --> Korean pairs */ - 0x00A1, 0xA2AE, 0x00A4, 0xA2B4, 0x00A7, 0xA1D7, 0x00A8, 0xA1A7, 0x00AA, 0xA8A3, 0x00AD, 0xA1A9, 0x00AE, 0xA2E7, 0x00B0, 0xA1C6, - 0x00B1, 0xA1BE, 0x00B2, 0xA9F7, 0x00B3, 0xA9F8, 0x00B4, 0xA2A5, 0x00B6, 0xA2D2, 0x00B7, 0xA1A4, 0x00B8, 0xA2AC, 0x00B9, 0xA9F6, - 0x00BA, 0xA8AC, 0x00BC, 0xA8F9, 0x00BD, 0xA8F6, 0x00BE, 0xA8FA, 0x00BF, 0xA2AF, 0x00C6, 0xA8A1, 0x00D0, 0xA8A2, 0x00D7, 0xA1BF, - 0x00D8, 0xA8AA, 0x00DE, 0xA8AD, 0x00DF, 0xA9AC, 0x00E6, 0xA9A1, 0x00F0, 0xA9A3, 0x00F7, 0xA1C0, 0x00F8, 0xA9AA, 0x00FE, 0xA9AD, - 0x0111, 0xA9A2, 0x0126, 0xA8A4, 0x0127, 0xA9A4, 0x0131, 0xA9A5, 0x0132, 0xA8A6, 0x0133, 0xA9A6, 0x0138, 0xA9A7, 0x013F, 0xA8A8, - 0x0140, 0xA9A8, 0x0141, 0xA8A9, 0x0142, 0xA9A9, 0x0149, 0xA9B0, 0x014A, 0xA8AF, 0x014B, 0xA9AF, 0x0152, 0xA8AB, 0x0153, 0xA9AB, - 0x0166, 0xA8AE, 0x0167, 0xA9AE, 0x02C7, 0xA2A7, 0x02D0, 0xA2B0, 0x02D8, 0xA2A8, 0x02D9, 0xA2AB, 0x02DA, 0xA2AA, 0x02DB, 0xA2AD, - 0x02DD, 0xA2A9, 0x0391, 0xA5C1, 0x0392, 0xA5C2, 0x0393, 0xA5C3, 0x0394, 0xA5C4, 0x0395, 0xA5C5, 0x0396, 0xA5C6, 0x0397, 0xA5C7, - 0x0398, 0xA5C8, 0x0399, 0xA5C9, 0x039A, 0xA5CA, 0x039B, 0xA5CB, 0x039C, 0xA5CC, 0x039D, 0xA5CD, 0x039E, 0xA5CE, 0x039F, 0xA5CF, - 0x03A0, 0xA5D0, 0x03A1, 0xA5D1, 0x03A3, 0xA5D2, 0x03A4, 0xA5D3, 0x03A5, 0xA5D4, 0x03A6, 0xA5D5, 0x03A7, 0xA5D6, 0x03A8, 0xA5D7, - 0x03A9, 0xA5D8, 0x03B1, 0xA5E1, 0x03B2, 0xA5E2, 0x03B3, 0xA5E3, 0x03B4, 0xA5E4, 0x03B5, 0xA5E5, 0x03B6, 0xA5E6, 0x03B7, 0xA5E7, - 0x03B8, 0xA5E8, 0x03B9, 0xA5E9, 0x03BA, 0xA5EA, 0x03BB, 0xA5EB, 0x03BC, 0xA5EC, 0x03BD, 0xA5ED, 0x03BE, 0xA5EE, 0x03BF, 0xA5EF, - 0x03C0, 0xA5F0, 0x03C1, 0xA5F1, 0x03C3, 0xA5F2, 0x03C4, 0xA5F3, 0x03C5, 0xA5F4, 0x03C6, 0xA5F5, 0x03C7, 0xA5F6, 0x03C8, 0xA5F7, - 0x03C9, 0xA5F8, 0x0401, 0xACA7, 0x0410, 0xACA1, 0x0411, 0xACA2, 0x0412, 0xACA3, 0x0413, 0xACA4, 0x0414, 0xACA5, 0x0415, 0xACA6, - 0x0416, 0xACA8, 0x0417, 0xACA9, 0x0418, 0xACAA, 0x0419, 0xACAB, 0x041A, 0xACAC, 0x041B, 0xACAD, 0x041C, 0xACAE, 0x041D, 0xACAF, - 0x041E, 0xACB0, 0x041F, 0xACB1, 0x0420, 0xACB2, 0x0421, 0xACB3, 0x0422, 0xACB4, 0x0423, 0xACB5, 0x0424, 0xACB6, 0x0425, 0xACB7, - 0x0426, 0xACB8, 0x0427, 0xACB9, 0x0428, 0xACBA, 0x0429, 0xACBB, 0x042A, 0xACBC, 0x042B, 0xACBD, 0x042C, 0xACBE, 0x042D, 0xACBF, - 0x042E, 0xACC0, 0x042F, 0xACC1, 0x0430, 0xACD1, 0x0431, 0xACD2, 0x0432, 0xACD3, 0x0433, 0xACD4, 0x0434, 0xACD5, 0x0435, 0xACD6, - 0x0436, 0xACD8, 0x0437, 0xACD9, 0x0438, 0xACDA, 0x0439, 0xACDB, 0x043A, 0xACDC, 0x043B, 0xACDD, 0x043C, 0xACDE, 0x043D, 0xACDF, - 0x043E, 0xACE0, 0x043F, 0xACE1, 0x0440, 0xACE2, 0x0441, 0xACE3, 0x0442, 0xACE4, 0x0443, 0xACE5, 0x0444, 0xACE6, 0x0445, 0xACE7, - 0x0446, 0xACE8, 0x0447, 0xACE9, 0x0448, 0xACEA, 0x0449, 0xACEB, 0x044A, 0xACEC, 0x044B, 0xACED, 0x044C, 0xACEE, 0x044D, 0xACEF, - 0x044E, 0xACF0, 0x044F, 0xACF1, 0x0451, 0xACD7, 0x2015, 0xA1AA, 0x2018, 0xA1AE, 0x2019, 0xA1AF, 0x201C, 0xA1B0, 0x201D, 0xA1B1, - 0x2020, 0xA2D3, 0x2021, 0xA2D4, 0x2025, 0xA1A5, 0x2026, 0xA1A6, 0x2030, 0xA2B6, 0x2032, 0xA1C7, 0x2033, 0xA1C8, 0x203B, 0xA1D8, - 0x2074, 0xA9F9, 0x207F, 0xA9FA, 0x2081, 0xA9FB, 0x2082, 0xA9FC, 0x2083, 0xA9FD, 0x2084, 0xA9FE, 0x20AC, 0xA2E6, 0x2103, 0xA1C9, - 0x2109, 0xA2B5, 0x2113, 0xA7A4, 0x2116, 0xA2E0, 0x2121, 0xA2E5, 0x2122, 0xA2E2, 0x2126, 0xA7D9, 0x212B, 0xA1CA, 0x2153, 0xA8F7, - 0x2154, 0xA8F8, 0x215B, 0xA8FB, 0x215C, 0xA8FC, 0x215D, 0xA8FD, 0x215E, 0xA8FE, 0x2160, 0xA5B0, 0x2161, 0xA5B1, 0x2162, 0xA5B2, - 0x2163, 0xA5B3, 0x2164, 0xA5B4, 0x2165, 0xA5B5, 0x2166, 0xA5B6, 0x2167, 0xA5B7, 0x2168, 0xA5B8, 0x2169, 0xA5B9, 0x2170, 0xA5A1, - 0x2171, 0xA5A2, 0x2172, 0xA5A3, 0x2173, 0xA5A4, 0x2174, 0xA5A5, 0x2175, 0xA5A6, 0x2176, 0xA5A7, 0x2177, 0xA5A8, 0x2178, 0xA5A9, - 0x2179, 0xA5AA, 0x2190, 0xA1E7, 0x2191, 0xA1E8, 0x2192, 0xA1E6, 0x2193, 0xA1E9, 0x2194, 0xA1EA, 0x2195, 0xA2D5, 0x2196, 0xA2D8, - 0x2197, 0xA2D6, 0x2198, 0xA2D9, 0x2199, 0xA2D7, 0x21D2, 0xA2A1, 0x21D4, 0xA2A2, 0x2200, 0xA2A3, 0x2202, 0xA1D3, 0x2203, 0xA2A4, - 0x2207, 0xA1D4, 0x2208, 0xA1F4, 0x220B, 0xA1F5, 0x220F, 0xA2B3, 0x2211, 0xA2B2, 0x221A, 0xA1EE, 0x221D, 0xA1F0, 0x221E, 0xA1C4, - 0x2220, 0xA1D0, 0x2225, 0xA1AB, 0x2227, 0xA1FC, 0x2228, 0xA1FD, 0x2229, 0xA1FB, 0x222A, 0xA1FA, 0x222B, 0xA1F2, 0x222C, 0xA1F3, - 0x222E, 0xA2B1, 0x2234, 0xA1C5, 0x2235, 0xA1F1, 0x223C, 0xA1AD, 0x223D, 0xA1EF, 0x2252, 0xA1D6, 0x2260, 0xA1C1, 0x2261, 0xA1D5, - 0x2264, 0xA1C2, 0x2265, 0xA1C3, 0x226A, 0xA1EC, 0x226B, 0xA1ED, 0x2282, 0xA1F8, 0x2283, 0xA1F9, 0x2286, 0xA1F6, 0x2287, 0xA1F7, - 0x2299, 0xA2C1, 0x22A5, 0xA1D1, 0x2312, 0xA1D2, 0x2460, 0xA8E7, 0x2461, 0xA8E8, 0x2462, 0xA8E9, 0x2463, 0xA8EA, 0x2464, 0xA8EB, - 0x2465, 0xA8EC, 0x2466, 0xA8ED, 0x2467, 0xA8EE, 0x2468, 0xA8EF, 0x2469, 0xA8F0, 0x246A, 0xA8F1, 0x246B, 0xA8F2, 0x246C, 0xA8F3, - 0x246D, 0xA8F4, 0x246E, 0xA8F5, 0x2474, 0xA9E7, 0x2475, 0xA9E8, 0x2476, 0xA9E9, 0x2477, 0xA9EA, 0x2478, 0xA9EB, 0x2479, 0xA9EC, - 0x247A, 0xA9ED, 0x247B, 0xA9EE, 0x247C, 0xA9EF, 0x247D, 0xA9F0, 0x247E, 0xA9F1, 0x247F, 0xA9F2, 0x2480, 0xA9F3, 0x2481, 0xA9F4, - 0x2482, 0xA9F5, 0x249C, 0xA9CD, 0x249D, 0xA9CE, 0x249E, 0xA9CF, 0x249F, 0xA9D0, 0x24A0, 0xA9D1, 0x24A1, 0xA9D2, 0x24A2, 0xA9D3, - 0x24A3, 0xA9D4, 0x24A4, 0xA9D5, 0x24A5, 0xA9D6, 0x24A6, 0xA9D7, 0x24A7, 0xA9D8, 0x24A8, 0xA9D9, 0x24A9, 0xA9DA, 0x24AA, 0xA9DB, - 0x24AB, 0xA9DC, 0x24AC, 0xA9DD, 0x24AD, 0xA9DE, 0x24AE, 0xA9DF, 0x24AF, 0xA9E0, 0x24B0, 0xA9E1, 0x24B1, 0xA9E2, 0x24B2, 0xA9E3, - 0x24B3, 0xA9E4, 0x24B4, 0xA9E5, 0x24B5, 0xA9E6, 0x24D0, 0xA8CD, 0x24D1, 0xA8CE, 0x24D2, 0xA8CF, 0x24D3, 0xA8D0, 0x24D4, 0xA8D1, - 0x24D5, 0xA8D2, 0x24D6, 0xA8D3, 0x24D7, 0xA8D4, 0x24D8, 0xA8D5, 0x24D9, 0xA8D6, 0x24DA, 0xA8D7, 0x24DB, 0xA8D8, 0x24DC, 0xA8D9, - 0x24DD, 0xA8DA, 0x24DE, 0xA8DB, 0x24DF, 0xA8DC, 0x24E0, 0xA8DD, 0x24E1, 0xA8DE, 0x24E2, 0xA8DF, 0x24E3, 0xA8E0, 0x24E4, 0xA8E1, - 0x24E5, 0xA8E2, 0x24E6, 0xA8E3, 0x24E7, 0xA8E4, 0x24E8, 0xA8E5, 0x24E9, 0xA8E6, 0x2500, 0xA6A1, 0x2501, 0xA6AC, 0x2502, 0xA6A2, - 0x2503, 0xA6AD, 0x250C, 0xA6A3, 0x250D, 0xA6C8, 0x250E, 0xA6C7, 0x250F, 0xA6AE, 0x2510, 0xA6A4, 0x2511, 0xA6C2, 0x2512, 0xA6C1, - 0x2513, 0xA6AF, 0x2514, 0xA6A6, 0x2515, 0xA6C6, 0x2516, 0xA6C5, 0x2517, 0xA6B1, 0x2518, 0xA6A5, 0x2519, 0xA6C4, 0x251A, 0xA6C3, - 0x251B, 0xA6B0, 0x251C, 0xA6A7, 0x251D, 0xA6BC, 0x251E, 0xA6C9, 0x251F, 0xA6CA, 0x2520, 0xA6B7, 0x2521, 0xA6CB, 0x2522, 0xA6CC, - 0x2523, 0xA6B2, 0x2524, 0xA6A9, 0x2525, 0xA6BE, 0x2526, 0xA6CD, 0x2527, 0xA6CE, 0x2528, 0xA6B9, 0x2529, 0xA6CF, 0x252A, 0xA6D0, - 0x252B, 0xA6B4, 0x252C, 0xA6A8, 0x252D, 0xA6D1, 0x252E, 0xA6D2, 0x252F, 0xA6B8, 0x2530, 0xA6BD, 0x2531, 0xA6D3, 0x2532, 0xA6D4, - 0x2533, 0xA6B3, 0x2534, 0xA6AA, 0x2535, 0xA6D5, 0x2536, 0xA6D6, 0x2537, 0xA6BA, 0x2538, 0xA6BF, 0x2539, 0xA6D7, 0x253A, 0xA6D8, - 0x253B, 0xA6B5, 0x253C, 0xA6AB, 0x253D, 0xA6D9, 0x253E, 0xA6DA, 0x253F, 0xA6BB, 0x2540, 0xA6DB, 0x2541, 0xA6DC, 0x2542, 0xA6C0, - 0x2543, 0xA6DD, 0x2544, 0xA6DE, 0x2545, 0xA6DF, 0x2546, 0xA6E0, 0x2547, 0xA6E1, 0x2548, 0xA6E2, 0x2549, 0xA6E3, 0x254A, 0xA6E4, - 0x254B, 0xA6B6, 0x2592, 0xA2C6, 0x25A0, 0xA1E1, 0x25A1, 0xA1E0, 0x25A3, 0xA2C3, 0x25A4, 0xA2C7, 0x25A5, 0xA2C8, 0x25A6, 0xA2CB, - 0x25A7, 0xA2CA, 0x25A8, 0xA2C9, 0x25A9, 0xA2CC, 0x25B2, 0xA1E3, 0x25B3, 0xA1E2, 0x25B6, 0xA2BA, 0x25B7, 0xA2B9, 0x25BC, 0xA1E5, - 0x25BD, 0xA1E4, 0x25C0, 0xA2B8, 0x25C1, 0xA2B7, 0x25C6, 0xA1DF, 0x25C7, 0xA1DE, 0x25C8, 0xA2C2, 0x25CB, 0xA1DB, 0x25CE, 0xA1DD, - 0x25CF, 0xA1DC, 0x25D0, 0xA2C4, 0x25D1, 0xA2C5, 0x2605, 0xA1DA, 0x2606, 0xA1D9, 0x260E, 0xA2CF, 0x260F, 0xA2CE, 0x261C, 0xA2D0, - 0x261E, 0xA2D1, 0x2640, 0xA1CF, 0x2642, 0xA1CE, 0x2660, 0xA2BC, 0x2661, 0xA2BD, 0x2663, 0xA2C0, 0x2664, 0xA2BB, 0x2665, 0xA2BE, - 0x2667, 0xA2BF, 0x2668, 0xA2CD, 0x2669, 0xA2DB, 0x266A, 0xA2DC, 0x266C, 0xA2DD, 0x266D, 0xA2DA, 0x3000, 0xA1A1, 0x3001, 0xA1A2, - 0x3002, 0xA1A3, 0x3003, 0xA1A8, 0x3008, 0xA1B4, 0x3009, 0xA1B5, 0x300A, 0xA1B6, 0x300B, 0xA1B7, 0x300C, 0xA1B8, 0x300D, 0xA1B9, - 0x300E, 0xA1BA, 0x300F, 0xA1BB, 0x3010, 0xA1BC, 0x3011, 0xA1BD, 0x3013, 0xA1EB, 0x3014, 0xA1B2, 0x3015, 0xA1B3, 0x3041, 0xAAA1, - 0x3042, 0xAAA2, 0x3043, 0xAAA3, 0x3044, 0xAAA4, 0x3045, 0xAAA5, 0x3046, 0xAAA6, 0x3047, 0xAAA7, 0x3048, 0xAAA8, 0x3049, 0xAAA9, - 0x304A, 0xAAAA, 0x304B, 0xAAAB, 0x304C, 0xAAAC, 0x304D, 0xAAAD, 0x304E, 0xAAAE, 0x304F, 0xAAAF, 0x3050, 0xAAB0, 0x3051, 0xAAB1, - 0x3052, 0xAAB2, 0x3053, 0xAAB3, 0x3054, 0xAAB4, 0x3055, 0xAAB5, 0x3056, 0xAAB6, 0x3057, 0xAAB7, 0x3058, 0xAAB8, 0x3059, 0xAAB9, - 0x305A, 0xAABA, 0x305B, 0xAABB, 0x305C, 0xAABC, 0x305D, 0xAABD, 0x305E, 0xAABE, 0x305F, 0xAABF, 0x3060, 0xAAC0, 0x3061, 0xAAC1, - 0x3062, 0xAAC2, 0x3063, 0xAAC3, 0x3064, 0xAAC4, 0x3065, 0xAAC5, 0x3066, 0xAAC6, 0x3067, 0xAAC7, 0x3068, 0xAAC8, 0x3069, 0xAAC9, - 0x306A, 0xAACA, 0x306B, 0xAACB, 0x306C, 0xAACC, 0x306D, 0xAACD, 0x306E, 0xAACE, 0x306F, 0xAACF, 0x3070, 0xAAD0, 0x3071, 0xAAD1, - 0x3072, 0xAAD2, 0x3073, 0xAAD3, 0x3074, 0xAAD4, 0x3075, 0xAAD5, 0x3076, 0xAAD6, 0x3077, 0xAAD7, 0x3078, 0xAAD8, 0x3079, 0xAAD9, - 0x307A, 0xAADA, 0x307B, 0xAADB, 0x307C, 0xAADC, 0x307D, 0xAADD, 0x307E, 0xAADE, 0x307F, 0xAADF, 0x3080, 0xAAE0, 0x3081, 0xAAE1, - 0x3082, 0xAAE2, 0x3083, 0xAAE3, 0x3084, 0xAAE4, 0x3085, 0xAAE5, 0x3086, 0xAAE6, 0x3087, 0xAAE7, 0x3088, 0xAAE8, 0x3089, 0xAAE9, - 0x308A, 0xAAEA, 0x308B, 0xAAEB, 0x308C, 0xAAEC, 0x308D, 0xAAED, 0x308E, 0xAAEE, 0x308F, 0xAAEF, 0x3090, 0xAAF0, 0x3091, 0xAAF1, - 0x3092, 0xAAF2, 0x3093, 0xAAF3, 0x30A1, 0xABA1, 0x30A2, 0xABA2, 0x30A3, 0xABA3, 0x30A4, 0xABA4, 0x30A5, 0xABA5, 0x30A6, 0xABA6, - 0x30A7, 0xABA7, 0x30A8, 0xABA8, 0x30A9, 0xABA9, 0x30AA, 0xABAA, 0x30AB, 0xABAB, 0x30AC, 0xABAC, 0x30AD, 0xABAD, 0x30AE, 0xABAE, - 0x30AF, 0xABAF, 0x30B0, 0xABB0, 0x30B1, 0xABB1, 0x30B2, 0xABB2, 0x30B3, 0xABB3, 0x30B4, 0xABB4, 0x30B5, 0xABB5, 0x30B6, 0xABB6, - 0x30B7, 0xABB7, 0x30B8, 0xABB8, 0x30B9, 0xABB9, 0x30BA, 0xABBA, 0x30BB, 0xABBB, 0x30BC, 0xABBC, 0x30BD, 0xABBD, 0x30BE, 0xABBE, - 0x30BF, 0xABBF, 0x30C0, 0xABC0, 0x30C1, 0xABC1, 0x30C2, 0xABC2, 0x30C3, 0xABC3, 0x30C4, 0xABC4, 0x30C5, 0xABC5, 0x30C6, 0xABC6, - 0x30C7, 0xABC7, 0x30C8, 0xABC8, 0x30C9, 0xABC9, 0x30CA, 0xABCA, 0x30CB, 0xABCB, 0x30CC, 0xABCC, 0x30CD, 0xABCD, 0x30CE, 0xABCE, - 0x30CF, 0xABCF, 0x30D0, 0xABD0, 0x30D1, 0xABD1, 0x30D2, 0xABD2, 0x30D3, 0xABD3, 0x30D4, 0xABD4, 0x30D5, 0xABD5, 0x30D6, 0xABD6, - 0x30D7, 0xABD7, 0x30D8, 0xABD8, 0x30D9, 0xABD9, 0x30DA, 0xABDA, 0x30DB, 0xABDB, 0x30DC, 0xABDC, 0x30DD, 0xABDD, 0x30DE, 0xABDE, - 0x30DF, 0xABDF, 0x30E0, 0xABE0, 0x30E1, 0xABE1, 0x30E2, 0xABE2, 0x30E3, 0xABE3, 0x30E4, 0xABE4, 0x30E5, 0xABE5, 0x30E6, 0xABE6, - 0x30E7, 0xABE7, 0x30E8, 0xABE8, 0x30E9, 0xABE9, 0x30EA, 0xABEA, 0x30EB, 0xABEB, 0x30EC, 0xABEC, 0x30ED, 0xABED, 0x30EE, 0xABEE, - 0x30EF, 0xABEF, 0x30F0, 0xABF0, 0x30F1, 0xABF1, 0x30F2, 0xABF2, 0x30F3, 0xABF3, 0x30F4, 0xABF4, 0x30F5, 0xABF5, 0x30F6, 0xABF6, - 0x3131, 0xA4A1, 0x3132, 0xA4A2, 0x3133, 0xA4A3, 0x3134, 0xA4A4, 0x3135, 0xA4A5, 0x3136, 0xA4A6, 0x3137, 0xA4A7, 0x3138, 0xA4A8, - 0x3139, 0xA4A9, 0x313A, 0xA4AA, 0x313B, 0xA4AB, 0x313C, 0xA4AC, 0x313D, 0xA4AD, 0x313E, 0xA4AE, 0x313F, 0xA4AF, 0x3140, 0xA4B0, - 0x3141, 0xA4B1, 0x3142, 0xA4B2, 0x3143, 0xA4B3, 0x3144, 0xA4B4, 0x3145, 0xA4B5, 0x3146, 0xA4B6, 0x3147, 0xA4B7, 0x3148, 0xA4B8, - 0x3149, 0xA4B9, 0x314A, 0xA4BA, 0x314B, 0xA4BB, 0x314C, 0xA4BC, 0x314D, 0xA4BD, 0x314E, 0xA4BE, 0x314F, 0xA4BF, 0x3150, 0xA4C0, - 0x3151, 0xA4C1, 0x3152, 0xA4C2, 0x3153, 0xA4C3, 0x3154, 0xA4C4, 0x3155, 0xA4C5, 0x3156, 0xA4C6, 0x3157, 0xA4C7, 0x3158, 0xA4C8, - 0x3159, 0xA4C9, 0x315A, 0xA4CA, 0x315B, 0xA4CB, 0x315C, 0xA4CC, 0x315D, 0xA4CD, 0x315E, 0xA4CE, 0x315F, 0xA4CF, 0x3160, 0xA4D0, - 0x3161, 0xA4D1, 0x3162, 0xA4D2, 0x3163, 0xA4D3, 0x3164, 0xA4D4, 0x3165, 0xA4D5, 0x3166, 0xA4D6, 0x3167, 0xA4D7, 0x3168, 0xA4D8, - 0x3169, 0xA4D9, 0x316A, 0xA4DA, 0x316B, 0xA4DB, 0x316C, 0xA4DC, 0x316D, 0xA4DD, 0x316E, 0xA4DE, 0x316F, 0xA4DF, 0x3170, 0xA4E0, - 0x3171, 0xA4E1, 0x3172, 0xA4E2, 0x3173, 0xA4E3, 0x3174, 0xA4E4, 0x3175, 0xA4E5, 0x3176, 0xA4E6, 0x3177, 0xA4E7, 0x3178, 0xA4E8, - 0x3179, 0xA4E9, 0x317A, 0xA4EA, 0x317B, 0xA4EB, 0x317C, 0xA4EC, 0x317D, 0xA4ED, 0x317E, 0xA4EE, 0x317F, 0xA4EF, 0x3180, 0xA4F0, - 0x3181, 0xA4F1, 0x3182, 0xA4F2, 0x3183, 0xA4F3, 0x3184, 0xA4F4, 0x3185, 0xA4F5, 0x3186, 0xA4F6, 0x3187, 0xA4F7, 0x3188, 0xA4F8, - 0x3189, 0xA4F9, 0x318A, 0xA4FA, 0x318B, 0xA4FB, 0x318C, 0xA4FC, 0x318D, 0xA4FD, 0x318E, 0xA4FE, 0x3200, 0xA9B1, 0x3201, 0xA9B2, - 0x3202, 0xA9B3, 0x3203, 0xA9B4, 0x3204, 0xA9B5, 0x3205, 0xA9B6, 0x3206, 0xA9B7, 0x3207, 0xA9B8, 0x3208, 0xA9B9, 0x3209, 0xA9BA, - 0x320A, 0xA9BB, 0x320B, 0xA9BC, 0x320C, 0xA9BD, 0x320D, 0xA9BE, 0x320E, 0xA9BF, 0x320F, 0xA9C0, 0x3210, 0xA9C1, 0x3211, 0xA9C2, - 0x3212, 0xA9C3, 0x3213, 0xA9C4, 0x3214, 0xA9C5, 0x3215, 0xA9C6, 0x3216, 0xA9C7, 0x3217, 0xA9C8, 0x3218, 0xA9C9, 0x3219, 0xA9CA, - 0x321A, 0xA9CB, 0x321B, 0xA9CC, 0x321C, 0xA2DF, 0x3260, 0xA8B1, 0x3261, 0xA8B2, 0x3262, 0xA8B3, 0x3263, 0xA8B4, 0x3264, 0xA8B5, - 0x3265, 0xA8B6, 0x3266, 0xA8B7, 0x3267, 0xA8B8, 0x3268, 0xA8B9, 0x3269, 0xA8BA, 0x326A, 0xA8BB, 0x326B, 0xA8BC, 0x326C, 0xA8BD, - 0x326D, 0xA8BE, 0x326E, 0xA8BF, 0x326F, 0xA8C0, 0x3270, 0xA8C1, 0x3271, 0xA8C2, 0x3272, 0xA8C3, 0x3273, 0xA8C4, 0x3274, 0xA8C5, - 0x3275, 0xA8C6, 0x3276, 0xA8C7, 0x3277, 0xA8C8, 0x3278, 0xA8C9, 0x3279, 0xA8CA, 0x327A, 0xA8CB, 0x327B, 0xA8CC, 0x327F, 0xA2DE, - 0x3380, 0xA7C9, 0x3381, 0xA7CA, 0x3382, 0xA7CB, 0x3383, 0xA7CC, 0x3384, 0xA7CD, 0x3388, 0xA7BA, 0x3389, 0xA7BB, 0x338A, 0xA7DC, - 0x338B, 0xA7DD, 0x338C, 0xA7DE, 0x338D, 0xA7B6, 0x338E, 0xA7B7, 0x338F, 0xA7B8, 0x3390, 0xA7D4, 0x3391, 0xA7D5, 0x3392, 0xA7D6, - 0x3393, 0xA7D7, 0x3394, 0xA7D8, 0x3395, 0xA7A1, 0x3396, 0xA7A2, 0x3397, 0xA7A3, 0x3398, 0xA7A5, 0x3399, 0xA7AB, 0x339A, 0xA7AC, - 0x339B, 0xA7AD, 0x339C, 0xA7AE, 0x339D, 0xA7AF, 0x339E, 0xA7B0, 0x339F, 0xA7B1, 0x33A0, 0xA7B2, 0x33A1, 0xA7B3, 0x33A2, 0xA7B4, - 0x33A3, 0xA7A7, 0x33A4, 0xA7A8, 0x33A5, 0xA7A9, 0x33A6, 0xA7AA, 0x33A7, 0xA7BD, 0x33A8, 0xA7BE, 0x33A9, 0xA7E5, 0x33AA, 0xA7E6, - 0x33AB, 0xA7E7, 0x33AC, 0xA7E8, 0x33AD, 0xA7E1, 0x33AE, 0xA7E2, 0x33AF, 0xA7E3, 0x33B0, 0xA7BF, 0x33B1, 0xA7C0, 0x33B2, 0xA7C1, - 0x33B3, 0xA7C2, 0x33B4, 0xA7C3, 0x33B5, 0xA7C4, 0x33B6, 0xA7C5, 0x33B7, 0xA7C6, 0x33B8, 0xA7C7, 0x33B9, 0xA7C8, 0x33BA, 0xA7CE, - 0x33BB, 0xA7CF, 0x33BC, 0xA7D0, 0x33BD, 0xA7D1, 0x33BE, 0xA7D2, 0x33BF, 0xA7D3, 0x33C0, 0xA7DA, 0x33C1, 0xA7DB, 0x33C2, 0xA2E3, - 0x33C3, 0xA7EC, 0x33C4, 0xA7A6, 0x33C5, 0xA7E0, 0x33C6, 0xA7EF, 0x33C7, 0xA2E1, 0x33C8, 0xA7BC, 0x33C9, 0xA7ED, 0x33CA, 0xA7B5, - 0x33CF, 0xA7B9, 0x33D0, 0xA7EA, 0x33D3, 0xA7EB, 0x33D6, 0xA7DF, 0x33D8, 0xA2E4, 0x33DB, 0xA7E4, 0x33DC, 0xA7EE, 0x33DD, 0xA7E9, - 0x4E00, 0xECE9, 0x4E01, 0xEFCB, 0x4E03, 0xF6D2, 0x4E07, 0xD8B2, 0x4E08, 0xEDDB, 0x4E09, 0xDFB2, 0x4E0A, 0xDFBE, 0x4E0B, 0xF9BB, - 0x4E0D, 0xDCF4, 0x4E11, 0xF5E4, 0x4E14, 0xF3A6, 0x4E15, 0xDDE0, 0x4E16, 0xE1A6, 0x4E18, 0xCEF8, 0x4E19, 0xDCB0, 0x4E1E, 0xE3AA, - 0x4E2D, 0xF1E9, 0x4E32, 0xCDFA, 0x4E38, 0xFCAF, 0x4E39, 0xD3A1, 0x4E3B, 0xF1AB, 0x4E42, 0xE7D1, 0x4E43, 0xD2AC, 0x4E45, 0xCEF9, - 0x4E4B, 0xF1FD, 0x4E4D, 0xDEBF, 0x4E4E, 0xFBBA, 0x4E4F, 0xF9B9, 0x4E56, 0xCED2, 0x4E58, 0xE3AB, 0x4E59, 0xEBE0, 0x4E5D, 0xCEFA, - 0x4E5E, 0xCBF7, 0x4E5F, 0xE5A5, 0x4E6B, 0xCAE1, 0x4E6D, 0xD4CC, 0x4E73, 0xEAE1, 0x4E76, 0xDCE3, 0x4E77, 0xDFAD, 0x4E7E, 0xCBEB, - 0x4E82, 0xD5AF, 0x4E86, 0xD6F5, 0x4E88, 0xE5F8, 0x4E8B, 0xDEC0, 0x4E8C, 0xECA3, 0x4E8E, 0xE9CD, 0x4E90, 0xEAA7, 0x4E91, 0xE9F6, - 0x4E92, 0xFBBB, 0x4E94, 0xE7E9, 0x4E95, 0xEFCC, 0x4E98, 0xD0E6, 0x4E9B, 0xDEC1, 0x4E9E, 0xE4AC, 0x4EA1, 0xD8CC, 0x4EA2, 0xF9F1, - 0x4EA4, 0xCEDF, 0x4EA5, 0xFAA4, 0x4EA6, 0xE6B2, 0x4EA8, 0xFAFB, 0x4EAB, 0xFABD, 0x4EAC, 0xCCC8, 0x4EAD, 0xEFCD, 0x4EAE, 0xD5D5, - 0x4EB6, 0xD3A2, 0x4EBA, 0xECD1, 0x4EC0, 0xE4A7, 0x4EC1, 0xECD2, 0x4EC4, 0xF6B1, 0x4EC7, 0xCEFB, 0x4ECA, 0xD0D1, 0x4ECB, 0xCBBF, - 0x4ECD, 0xEDA4, 0x4ED4, 0xEDA8, 0x4ED5, 0xDEC2, 0x4ED6, 0xF6E2, 0x4ED7, 0xEDDC, 0x4ED8, 0xDCF5, 0x4ED9, 0xE0B9, 0x4EDD, 0xD4CE, - 0x4EDF, 0xF4B5, 0x4EE3, 0xD3DB, 0x4EE4, 0xD6B5, 0x4EE5, 0xECA4, 0x4EF0, 0xE4E6, 0x4EF2, 0xF1EA, 0x4EF6, 0xCBEC, 0x4EF7, 0xCBC0, - 0x4EFB, 0xECF2, 0x4F01, 0xD0EA, 0x4F09, 0xF9F2, 0x4F0A, 0xECA5, 0x4F0B, 0xD0DF, 0x4F0D, 0xE7EA, 0x4F0E, 0xD0EB, 0x4F0F, 0xDCD1, - 0x4F10, 0xDBE9, 0x4F11, 0xFDCC, 0x4F2F, 0xDBD7, 0x4F34, 0xDAE1, 0x4F36, 0xD6B6, 0x4F38, 0xE3DF, 0x4F3A, 0xDEC3, 0x4F3C, 0xDEC4, - 0x4F3D, 0xCAA1, 0x4F43, 0xEEEC, 0x4F46, 0xD3A3, 0x4F47, 0xEEB7, 0x4F48, 0xF8CF, 0x4F4D, 0xEAC8, 0x4F4E, 0xEEB8, 0x4F4F, 0xF1AC, - 0x4F50, 0xF1A5, 0x4F51, 0xE9CE, 0x4F55, 0xF9BC, 0x4F59, 0xE5F9, 0x4F5A, 0xECEA, 0x4F5B, 0xDDD6, 0x4F5C, 0xEDC2, 0x4F69, 0xF8A5, - 0x4F6F, 0xE5BA, 0x4F70, 0xDBD8, 0x4F73, 0xCAA2, 0x4F76, 0xD1CD, 0x4F7A, 0xEEED, 0x4F7E, 0xECEB, 0x4F7F, 0xDEC5, 0x4F81, 0xE3E0, - 0x4F83, 0xCAC9, 0x4F84, 0xF2E9, 0x4F86, 0xD5CE, 0x4F88, 0xF6B6, 0x4F8A, 0xCEC2, 0x4F8B, 0xD6C7, 0x4F8D, 0xE3B4, 0x4F8F, 0xF1AD, - 0x4F91, 0xEAE2, 0x4F96, 0xD7C2, 0x4F98, 0xF3A7, 0x4F9B, 0xCDEA, 0x4F9D, 0xEBEE, 0x4FAE, 0xD9B2, 0x4FAF, 0xFDA5, 0x4FB5, 0xF6D5, - 0x4FB6, 0xD5E2, 0x4FBF, 0xF8B5, 0x4FC2, 0xCCF5, 0x4FC3, 0xF5B5, 0x4FC4, 0xE4AD, 0x4FC9, 0xE7EB, 0x4FCA, 0xF1D5, 0x4FCE, 0xF0BB, - 0x4FD1, 0xE9B5, 0x4FD3, 0xCCC9, 0x4FD4, 0xFAD5, 0x4FD7, 0xE1D4, 0x4FDA, 0xD7D6, 0x4FDD, 0xDCC1, 0x4FDF, 0xDEC6, 0x4FE0, 0xFAEF, - 0x4FE1, 0xE3E1, 0x4FEE, 0xE1F3, 0x4FEF, 0xDCF6, 0x4FF1, 0xCEFC, 0x4FF3, 0xDBC4, 0x4FF5, 0xF8F1, 0x4FF8, 0xDCE4, 0x4FFA, 0xE5EF, - 0x5002, 0xDCB1, 0x5006, 0xD5D6, 0x5009, 0xF3DA, 0x500B, 0xCBC1, 0x500D, 0xDBC3, 0x5011, 0xD9FA, 0x5012, 0xD3EE, 0x5016, 0xFAB8, - 0x5019, 0xFDA6, 0x501A, 0xEBEF, 0x501C, 0xF4A6, 0x501E, 0xCCCA, 0x501F, 0xF3A8, 0x5021, 0xF3DB, 0x5023, 0xDBA7, 0x5024, 0xF6B7, - 0x5026, 0xCFE6, 0x5027, 0xF0F2, 0x5028, 0xCBDA, 0x502A, 0xE7D2, 0x502B, 0xD7C3, 0x502C, 0xF6F0, 0x502D, 0xE8DE, 0x503B, 0xE5A6, - 0x5043, 0xE5E7, 0x5047, 0xCAA3, 0x5048, 0xCCA7, 0x5049, 0xEAC9, 0x504F, 0xF8B6, 0x5055, 0xFAA5, 0x505A, 0xF1AE, 0x505C, 0xEFCE, - 0x5065, 0xCBED, 0x5074, 0xF6B0, 0x5075, 0xEFCF, 0x5076, 0xE9CF, 0x5078, 0xF7DE, 0x5080, 0xCED3, 0x5085, 0xDCF7, 0x508D, 0xDBA8, - 0x5091, 0xCBF8, 0x5098, 0xDFA1, 0x5099, 0xDDE1, 0x50AC, 0xF5CA, 0x50AD, 0xE9B6, 0x50B2, 0xE7EC, 0x50B3, 0xEEEE, 0x50B5, 0xF3F0, - 0x50B7, 0xDFBF, 0x50BE, 0xCCCB, 0x50C5, 0xD0C1, 0x50C9, 0xF4D2, 0x50CA, 0xE0BA, 0x50CF, 0xDFC0, 0x50D1, 0xCEE0, 0x50D5, 0xDCD2, - 0x50D6, 0xFDEA, 0x50DA, 0xD6F6, 0x50DE, 0xEACA, 0x50E5, 0xE8E9, 0x50E7, 0xE3AC, 0x50ED, 0xF3D0, 0x50F9, 0xCAA4, 0x50FB, 0xDBF8, - 0x50FF, 0xDEC7, 0x5100, 0xEBF0, 0x5101, 0xF1D6, 0x5104, 0xE5E2, 0x5106, 0xCCCC, 0x5109, 0xCBFB, 0x5112, 0xEAE3, 0x511F, 0xDFC1, - 0x5121, 0xD6ED, 0x512A, 0xE9D0, 0x5132, 0xEEB9, 0x5137, 0xD5E3, 0x513A, 0xD1D3, 0x513C, 0xE5F0, 0x5140, 0xE8B4, 0x5141, 0xEBC3, - 0x5143, 0xEAAA, 0x5144, 0xFAFC, 0x5145, 0xF5F6, 0x5146, 0xF0BC, 0x5147, 0xFDD4, 0x5148, 0xE0BB, 0x5149, 0xCEC3, 0x514B, 0xD0BA, - 0x514C, 0xF7BA, 0x514D, 0xD8F3, 0x514E, 0xF7CD, 0x5152, 0xE4AE, 0x515C, 0xD4DF, 0x5162, 0xD0E7, 0x5165, 0xECFD, 0x5167, 0xD2AE, - 0x5168, 0xEEEF, 0x5169, 0xD5D7, 0x516A, 0xEAE4, 0x516B, 0xF8A2, 0x516C, 0xCDEB, 0x516D, 0xD7BF, 0x516E, 0xFBB1, 0x5171, 0xCDEC, - 0x5175, 0xDCB2, 0x5176, 0xD0EC, 0x5177, 0xCEFD, 0x5178, 0xEEF0, 0x517C, 0xCCC2, 0x5180, 0xD0ED, 0x5186, 0xE5F7, 0x518A, 0xF3FC, - 0x518D, 0xEEA2, 0x5192, 0xD9B3, 0x5195, 0xD8F4, 0x5197, 0xE9B7, 0x51A0, 0xCEAE, 0x51A5, 0xD9A2, 0x51AA, 0xD8F1, 0x51AC, 0xD4CF, - 0x51B6, 0xE5A7, 0x51B7, 0xD5D2, 0x51BD, 0xD6A9, 0x51C4, 0xF4A2, 0x51C6, 0xF1D7, 0x51C9, 0xD5D8, 0x51CB, 0xF0BD, 0x51CC, 0xD7D0, - 0x51CD, 0xD4D0, 0x51DC, 0xD7CF, 0x51DD, 0xEBEA, 0x51DE, 0xFDEB, 0x51E1, 0xDBED, 0x51F0, 0xFCC5, 0x51F1, 0xCBC2, 0x51F6, 0xFDD5, - 0x51F8, 0xF4C8, 0x51F9, 0xE8EA, 0x51FA, 0xF5F3, 0x51FD, 0xF9DE, 0x5200, 0xD3EF, 0x5203, 0xECD3, 0x5206, 0xDDC2, 0x5207, 0xEFB7, - 0x5208, 0xE7D4, 0x520A, 0xCACA, 0x520E, 0xD9FB, 0x5211, 0xFAFD, 0x5217, 0xD6AA, 0x521D, 0xF4F8, 0x5224, 0xF7F7, 0x5225, 0xDCAC, - 0x5229, 0xD7D7, 0x522A, 0xDFA2, 0x522E, 0xCEBE, 0x5230, 0xD3F0, 0x5236, 0xF0A4, 0x5237, 0xE1EC, 0x5238, 0xCFE7, 0x5239, 0xF3CB, - 0x523A, 0xEDA9, 0x523B, 0xCABE, 0x5243, 0xF4EF, 0x5247, 0xF6CE, 0x524A, 0xDEFB, 0x524B, 0xD0BB, 0x524C, 0xD5B7, 0x524D, 0xEEF1, - 0x5254, 0xF4A8, 0x5256, 0xDCF8, 0x525B, 0xCBA7, 0x525D, 0xDACE, 0x5261, 0xE0E6, 0x5269, 0xEDA5, 0x526A, 0xEEF2, 0x526F, 0xDCF9, - 0x5272, 0xF9DC, 0x5275, 0xF3DC, 0x527D, 0xF8F2, 0x527F, 0xF4F9, 0x5283, 0xFCF1, 0x5287, 0xD0BC, 0x5288, 0xDBF9, 0x5289, 0xD7B1, - 0x528D, 0xCBFC, 0x5291, 0xF0A5, 0x5292, 0xCBFD, 0x529B, 0xD5F4, 0x529F, 0xCDED, 0x52A0, 0xCAA5, 0x52A3, 0xD6AB, 0x52A4, 0xD0C2, - 0x52A9, 0xF0BE, 0x52AA, 0xD2BD, 0x52AB, 0xCCA4, 0x52BE, 0xFAB6, 0x52C1, 0xCCCD, 0x52C3, 0xDAFA, 0x52C5, 0xF6CF, 0x52C7, 0xE9B8, - 0x52C9, 0xD8F5, 0x52CD, 0xCCCE, 0x52D2, 0xD7CD, 0x52D5, 0xD4D1, 0x52D6, 0xE9ED, 0x52D8, 0xCAEB, 0x52D9, 0xD9E2, 0x52DB, 0xFDB2, - 0x52DD, 0xE3AD, 0x52DE, 0xD6CC, 0x52DF, 0xD9B4, 0x52E2, 0xE1A7, 0x52E3, 0xEED3, 0x52E4, 0xD0C3, 0x52F3, 0xFDB3, 0x52F5, 0xD5E4, - 0x52F8, 0xCFE8, 0x52FA, 0xEDC3, 0x52FB, 0xD0B2, 0x52FE, 0xCEFE, 0x52FF, 0xDAA8, 0x5305, 0xF8D0, 0x5308, 0xFDD6, 0x530D, 0xF8D1, - 0x530F, 0xF8D2, 0x5310, 0xDCD3, 0x5315, 0xDDE2, 0x5316, 0xFBF9, 0x5317, 0xDDC1, 0x5319, 0xE3B5, 0x5320, 0xEDDD, 0x5321, 0xCEC4, - 0x5323, 0xCBA1, 0x532A, 0xDDE3, 0x532F, 0xFCDD, 0x5339, 0xF9AF, 0x533F, 0xD2FB, 0x5340, 0xCFA1, 0x5341, 0xE4A8, 0x5343, 0xF4B6, - 0x5344, 0xECFE, 0x5347, 0xE3AE, 0x5348, 0xE7ED, 0x5349, 0xFDC1, 0x534A, 0xDAE2, 0x534D, 0xD8B3, 0x5351, 0xDDE4, 0x5352, 0xF0EF, - 0x5353, 0xF6F1, 0x5354, 0xFAF0, 0x5357, 0xD1F5, 0x535A, 0xDACF, 0x535C, 0xDCD4, 0x535E, 0xDCA6, 0x5360, 0xEFBF, 0x5366, 0xCECF, - 0x5368, 0xE0D9, 0x536F, 0xD9D6, 0x5370, 0xECD4, 0x5371, 0xEACB, 0x5374, 0xCABF, 0x5375, 0xD5B0, 0x5377, 0xCFE9, 0x537D, 0xF1ED, - 0x537F, 0xCCCF, 0x5384, 0xE4F8, 0x5393, 0xE4ED, 0x5398, 0xD7D8, 0x539A, 0xFDA7, 0x539F, 0xEAAB, 0x53A0, 0xF6B2, 0x53A5, 0xCFF0, - 0x53A6, 0xF9BD, 0x53AD, 0xE6F4, 0x53BB, 0xCBDB, 0x53C3, 0xF3D1, 0x53C8, 0xE9D1, 0x53C9, 0xF3A9, 0x53CA, 0xD0E0, 0x53CB, 0xE9D2, - 0x53CD, 0xDAE3, 0x53D4, 0xE2D2, 0x53D6, 0xF6A2, 0x53D7, 0xE1F4, 0x53DB, 0xDAE4, 0x53E1, 0xE7D5, 0x53E2, 0xF5BF, 0x53E3, 0xCFA2, - 0x53E4, 0xCDAF, 0x53E5, 0xCFA3, 0x53E9, 0xCDB0, 0x53EA, 0xF1FE, 0x53EB, 0xD0A3, 0x53EC, 0xE1AF, 0x53ED, 0xF8A3, 0x53EF, 0xCAA6, - 0x53F0, 0xF7BB, 0x53F1, 0xF2EA, 0x53F2, 0xDEC8, 0x53F3, 0xE9D3, 0x53F8, 0xDEC9, 0x5403, 0xFDDE, 0x5404, 0xCAC0, 0x5408, 0xF9EA, - 0x5409, 0xD1CE, 0x540A, 0xEED4, 0x540C, 0xD4D2, 0x540D, 0xD9A3, 0x540E, 0xFDA8, 0x540F, 0xD7D9, 0x5410, 0xF7CE, 0x5411, 0xFABE, - 0x541B, 0xCFD6, 0x541D, 0xD7F0, 0x541F, 0xEBE1, 0x5420, 0xF8C5, 0x5426, 0xDCFA, 0x5429, 0xDDC3, 0x542B, 0xF9DF, 0x5433, 0xE7EF, - 0x5438, 0xFDE5, 0x5439, 0xF6A3, 0x543B, 0xD9FC, 0x543C, 0xFDA9, 0x543E, 0xE7EE, 0x5442, 0xD5E5, 0x5448, 0xEFD0, 0x544A, 0xCDB1, - 0x5451, 0xF7A2, 0x5468, 0xF1B2, 0x546A, 0xF1B1, 0x5471, 0xCDB2, 0x5473, 0xDAAB, 0x5475, 0xCAA7, 0x547B, 0xE3E2, 0x547C, 0xFBBC, - 0x547D, 0xD9A4, 0x5480, 0xEEBA, 0x5486, 0xF8D3, 0x548C, 0xFBFA, 0x548E, 0xCFA4, 0x5490, 0xDCFB, 0x54A4, 0xF6E3, 0x54A8, 0xEDAA, - 0x54AB, 0xF2A1, 0x54AC, 0xCEE1, 0x54B3, 0xFAA6, 0x54B8, 0xF9E0, 0x54BD, 0xECD6, 0x54C0, 0xE4EE, 0x54C1, 0xF9A1, 0x54C4, 0xFBEF, - 0x54C8, 0xF9EB, 0x54C9, 0xEEA3, 0x54E1, 0xEAAC, 0x54E5, 0xCAA8, 0x54E8, 0xF4FA, 0x54ED, 0xCDD6, 0x54EE, 0xFCF6, 0x54F2, 0xF4C9, - 0x54FA, 0xF8D4, 0x5504, 0xF8A6, 0x5506, 0xDECA, 0x5507, 0xF2C6, 0x550E, 0xD7DA, 0x5510, 0xD3D0, 0x551C, 0xD8C5, 0x552F, 0xEAE6, - 0x5531, 0xF3DD, 0x5535, 0xE4DA, 0x553E, 0xF6E4, 0x5544, 0xF6F2, 0x5546, 0xDFC2, 0x554F, 0xD9FD, 0x5553, 0xCCF6, 0x5556, 0xD3BA, - 0x555E, 0xE4AF, 0x5563, 0xF9E1, 0x557C, 0xF0A6, 0x5580, 0xCBD3, 0x5584, 0xE0BC, 0x5586, 0xF4CA, 0x5587, 0xD4FA, 0x5589, 0xFDAA, - 0x558A, 0xF9E2, 0x5598, 0xF4B7, 0x5599, 0xFDC2, 0x559A, 0xFCB0, 0x559C, 0xFDEC, 0x559D, 0xCAE2, 0x55A7, 0xFDBD, 0x55A9, 0xEAE7, - 0x55AA, 0xDFC3, 0x55AB, 0xD1D2, 0x55AC, 0xCEE2, 0x55AE, 0xD3A4, 0x55C5, 0xFDAB, 0x55C7, 0xDFE0, 0x55D4, 0xF2C7, 0x55DA, 0xE7F0, - 0x55DC, 0xD0EE, 0x55DF, 0xF3AA, 0x55E3, 0xDECB, 0x55E4, 0xF6B8, 0x55FD, 0xE1F5, 0x55FE, 0xF1B3, 0x5606, 0xF7A3, 0x5609, 0xCAA9, - 0x5614, 0xCFA5, 0x5617, 0xDFC4, 0x562F, 0xE1B0, 0x5632, 0xF0BF, 0x5634, 0xF6A4, 0x5636, 0xE3B6, 0x5653, 0xFAC6, 0x5668, 0xD0EF, - 0x566B, 0xFDED, 0x5674, 0xDDC4, 0x5686, 0xFCF7, 0x56A5, 0xE6BF, 0x56AC, 0xDEAD, 0x56AE, 0xFABF, 0x56B4, 0xE5F1, 0x56BC, 0xEDC4, - 0x56CA, 0xD2A5, 0x56CD, 0xFDEE, 0x56D1, 0xF5B6, 0x56DA, 0xE1F6, 0x56DB, 0xDECC, 0x56DE, 0xFCDE, 0x56E0, 0xECD7, 0x56F0, 0xCDDD, - 0x56F9, 0xD6B7, 0x56FA, 0xCDB3, 0x5703, 0xF8D5, 0x5704, 0xE5D8, 0x5708, 0xCFEA, 0x570B, 0xCFD0, 0x570D, 0xEACC, 0x5712, 0xEAAE, - 0x5713, 0xEAAD, 0x5716, 0xD3F1, 0x5718, 0xD3A5, 0x571F, 0xF7CF, 0x5728, 0xEEA4, 0x572D, 0xD0A4, 0x5730, 0xF2A2, 0x573B, 0xD0F0, - 0x5740, 0xF2A3, 0x5742, 0xF7F8, 0x5747, 0xD0B3, 0x574A, 0xDBA9, 0x574D, 0xD3BB, 0x574E, 0xCAEC, 0x5750, 0xF1A6, 0x5751, 0xCBD5, - 0x5761, 0xF7E7, 0x5764, 0xCDDE, 0x5766, 0xF7A4, 0x576A, 0xF8C0, 0x576E, 0xD3DD, 0x5770, 0xCCD0, 0x5775, 0xCFA6, 0x577C, 0xF6F3, - 0x5782, 0xE1F7, 0x5788, 0xD3DC, 0x578B, 0xFAFE, 0x5793, 0xFAA7, 0x57A0, 0xEBD9, 0x57A2, 0xCFA7, 0x57A3, 0xEAAF, 0x57C3, 0xE4EF, - 0x57C7, 0xE9B9, 0x57C8, 0xF1D8, 0x57CB, 0xD8D8, 0x57CE, 0xE0F2, 0x57DF, 0xE6B4, 0x57E0, 0xDCFC, 0x57F0, 0xF3F1, 0x57F4, 0xE3D0, - 0x57F7, 0xF2FB, 0x57F9, 0xDBC6, 0x57FA, 0xD0F1, 0x57FC, 0xD0F2, 0x5800, 0xCFDC, 0x5802, 0xD3D1, 0x5805, 0xCCB1, 0x5806, 0xF7D8, - 0x5808, 0xCBA8, 0x5809, 0xEBBC, 0x580A, 0xE4BE, 0x581E, 0xF4DC, 0x5821, 0xDCC2, 0x5824, 0xF0A7, 0x5827, 0xE6C0, 0x582A, 0xCAED, - 0x582F, 0xE8EB, 0x5830, 0xE5E8, 0x5831, 0xDCC3, 0x5834, 0xEDDE, 0x5835, 0xD3F2, 0x583A, 0xCCF7, 0x584A, 0xCED4, 0x584B, 0xE7AB, - 0x584F, 0xCBC3, 0x5851, 0xE1B1, 0x5854, 0xF7B2, 0x5857, 0xD3F3, 0x5858, 0xD3D2, 0x585A, 0xF5C0, 0x585E, 0xDFDD, 0x5861, 0xEEF3, - 0x5862, 0xE7F1, 0x5864, 0xFDB4, 0x5875, 0xF2C8, 0x5879, 0xF3D2, 0x587C, 0xEEF4, 0x587E, 0xE2D3, 0x5883, 0xCCD1, 0x5885, 0xDFEA, - 0x5889, 0xE9BA, 0x5893, 0xD9D7, 0x589C, 0xF5CD, 0x589E, 0xF1F2, 0x589F, 0xFAC7, 0x58A8, 0xD9F8, 0x58A9, 0xD4C2, 0x58AE, 0xF6E5, - 0x58B3, 0xDDC5, 0x58BA, 0xE7F2, 0x58BB, 0xEDDF, 0x58BE, 0xCACB, 0x58C1, 0xDBFA, 0x58C5, 0xE8B5, 0x58C7, 0xD3A6, 0x58CE, 0xFDB5, - 0x58D1, 0xF9C9, 0x58D3, 0xE4E2, 0x58D5, 0xFBBD, 0x58D8, 0xD7A4, 0x58D9, 0xCEC5, 0x58DE, 0xCED5, 0x58DF, 0xD6E6, 0x58E4, 0xE5BD, - 0x58EB, 0xDECD, 0x58EC, 0xECF3, 0x58EF, 0xEDE0, 0x58F9, 0xECEC, 0x58FA, 0xFBBE, 0x58FB, 0xDFEB, 0x58FD, 0xE1F8, 0x590F, 0xF9BE, - 0x5914, 0xD0F3, 0x5915, 0xE0AA, 0x5916, 0xE8E2, 0x5919, 0xE2D4, 0x591A, 0xD2FD, 0x591C, 0xE5A8, 0x5922, 0xD9D3, 0x5927, 0xD3DE, - 0x5929, 0xF4B8, 0x592A, 0xF7BC, 0x592B, 0xDCFD, 0x592D, 0xE8EC, 0x592E, 0xE4E7, 0x5931, 0xE3F7, 0x5937, 0xECA8, 0x593E, 0xFAF1, - 0x5944, 0xE5F2, 0x5947, 0xD0F4, 0x5948, 0xD2AF, 0x5949, 0xDCE5, 0x594E, 0xD0A5, 0x594F, 0xF1B4, 0x5950, 0xFCB1, 0x5951, 0xCCF8, - 0x5954, 0xDDC6, 0x5955, 0xFAD1, 0x5957, 0xF7DF, 0x595A, 0xFAA8, 0x5960, 0xEEF5, 0x5962, 0xDECE, 0x5967, 0xE7F3, 0x596A, 0xF7AC, - 0x596B, 0xEBC4, 0x596C, 0xEDE1, 0x596D, 0xE0AB, 0x596E, 0xDDC7, 0x5973, 0xD2B3, 0x5974, 0xD2BF, 0x5978, 0xCACC, 0x597D, 0xFBBF, - 0x5982, 0xE5FD, 0x5983, 0xDDE5, 0x5984, 0xD8CD, 0x598A, 0xECF4, 0x5993, 0xD0F5, 0x5996, 0xE8ED, 0x5997, 0xD0D2, 0x5999, 0xD9D8, - 0x59A5, 0xF6E6, 0x59A8, 0xDBAA, 0x59AC, 0xF7E0, 0x59B9, 0xD8D9, 0x59BB, 0xF4A3, 0x59BE, 0xF4DD, 0x59C3, 0xEFD1, 0x59C6, 0xD9B5, - 0x59C9, 0xEDAB, 0x59CB, 0xE3B7, 0x59D0, 0xEEBB, 0x59D1, 0xCDB4, 0x59D3, 0xE0F3, 0x59D4, 0xEACD, 0x59D9, 0xECF5, 0x59DA, 0xE8EE, - 0x59DC, 0xCBA9, 0x59DD, 0xF1AF, 0x59E6, 0xCACD, 0x59E8, 0xECA9, 0x59EA, 0xF2EB, 0x59EC, 0xFDEF, 0x59EE, 0xF9F3, 0x59F8, 0xE6C1, - 0x59FB, 0xECD8, 0x59FF, 0xEDAC, 0x5A01, 0xEACE, 0x5A03, 0xE8DF, 0x5A11, 0xDECF, 0x5A18, 0xD2A6, 0x5A1B, 0xE7F4, 0x5A1C, 0xD1D6, - 0x5A1F, 0xE6C2, 0x5A20, 0xE3E3, 0x5A25, 0xE4B0, 0x5A29, 0xD8B4, 0x5A36, 0xF6A5, 0x5A3C, 0xF3DE, 0x5A41, 0xD7A5, 0x5A46, 0xF7E8, - 0x5A49, 0xE8C6, 0x5A5A, 0xFBE6, 0x5A62, 0xDDE6, 0x5A66, 0xDCFE, 0x5A92, 0xD8DA, 0x5A9A, 0xDAAC, 0x5A9B, 0xEAB0, 0x5AA4, 0xE3B8, - 0x5AC1, 0xCAAA, 0x5AC2, 0xE1F9, 0x5AC4, 0xEAB1, 0x5AC9, 0xF2EC, 0x5ACC, 0xFAEE, 0x5AE1, 0xEED5, 0x5AE6, 0xF9F4, 0x5AE9, 0xD2EC, - 0x5B05, 0xFBFB, 0x5B09, 0xFDF0, 0x5B0B, 0xE0BD, 0x5B0C, 0xCEE3, 0x5B16, 0xF8C6, 0x5B2A, 0xDEAE, 0x5B40, 0xDFC5, 0x5B43, 0xE5BE, - 0x5B50, 0xEDAD, 0x5B51, 0xFAEA, 0x5B54, 0xCDEE, 0x5B55, 0xEDA6, 0x5B57, 0xEDAE, 0x5B58, 0xF0ED, 0x5B5A, 0xDDA1, 0x5B5C, 0xEDAF, - 0x5B5D, 0xFCF8, 0x5B5F, 0xD8EB, 0x5B63, 0xCCF9, 0x5B64, 0xCDB5, 0x5B69, 0xFAA9, 0x5B6B, 0xE1DD, 0x5B70, 0xE2D5, 0x5B71, 0xEDCF, - 0x5B75, 0xDDA2, 0x5B78, 0xF9CA, 0x5B7A, 0xEAE8, 0x5B7C, 0xE5ED, 0x5B85, 0xD3EB, 0x5B87, 0xE9D4, 0x5B88, 0xE1FA, 0x5B89, 0xE4CC, - 0x5B8B, 0xE1E4, 0x5B8C, 0xE8C7, 0x5B8F, 0xCEDB, 0x5B93, 0xDCD5, 0x5B95, 0xF7B5, 0x5B96, 0xFCF3, 0x5B97, 0xF0F3, 0x5B98, 0xCEAF, - 0x5B99, 0xF1B5, 0x5B9A, 0xEFD2, 0x5B9B, 0xE8C8, 0x5B9C, 0xEBF1, 0x5BA2, 0xCBD4, 0x5BA3, 0xE0BE, 0x5BA4, 0xE3F8, 0x5BA5, 0xEAE9, - 0x5BA6, 0xFCB2, 0x5BAC, 0xE0F4, 0x5BAE, 0xCFE0, 0x5BB0, 0xEEA5, 0x5BB3, 0xFAAA, 0x5BB4, 0xE6C3, 0x5BB5, 0xE1B2, 0x5BB6, 0xCAAB, - 0x5BB8, 0xE3E4, 0x5BB9, 0xE9BB, 0x5BBF, 0xE2D6, 0x5BC0, 0xF3F2, 0x5BC2, 0xEED6, 0x5BC3, 0xEAB2, 0x5BC4, 0xD0F6, 0x5BC5, 0xECD9, - 0x5BC6, 0xDACB, 0x5BC7, 0xCFA8, 0x5BCC, 0xDDA3, 0x5BD0, 0xD8DB, 0x5BD2, 0xF9CE, 0x5BD3, 0xE9D5, 0x5BD4, 0xE3D1, 0x5BD7, 0xD2BC, - 0x5BDE, 0xD8AC, 0x5BDF, 0xF3CC, 0x5BE1, 0xCDFB, 0x5BE2, 0xF6D6, 0x5BE4, 0xE7F5, 0x5BE5, 0xE8EF, 0x5BE6, 0xE3F9, 0x5BE7, 0xD2BB, - 0x5BE8, 0xF3F3, 0x5BE9, 0xE3FB, 0x5BEB, 0xDED0, 0x5BEC, 0xCEB0, 0x5BEE, 0xD6F7, 0x5BEF, 0xF1D9, 0x5BF5, 0xF5C1, 0x5BF6, 0xDCC4, - 0x5BF8, 0xF5BB, 0x5BFA, 0xDED1, 0x5C01, 0xDCE6, 0x5C04, 0xDED2, 0x5C07, 0xEDE2, 0x5C08, 0xEEF6, 0x5C09, 0xEACF, 0x5C0A, 0xF0EE, - 0x5C0B, 0xE3FC, 0x5C0D, 0xD3DF, 0x5C0E, 0xD3F4, 0x5C0F, 0xE1B3, 0x5C11, 0xE1B4, 0x5C16, 0xF4D3, 0x5C19, 0xDFC6, 0x5C24, 0xE9D6, - 0x5C28, 0xDBAB, 0x5C31, 0xF6A6, 0x5C38, 0xE3B9, 0x5C39, 0xEBC5, 0x5C3A, 0xF4A9, 0x5C3B, 0xCDB6, 0x5C3C, 0xD2F9, 0x5C3E, 0xDAAD, - 0x5C3F, 0xD2E3, 0x5C40, 0xCFD1, 0x5C45, 0xCBDC, 0x5C46, 0xCCFA, 0x5C48, 0xCFDD, 0x5C4B, 0xE8A9, 0x5C4D, 0xE3BB, 0x5C4E, 0xE3BA, - 0x5C51, 0xE0DA, 0x5C55, 0xEEF7, 0x5C5B, 0xDCB3, 0x5C60, 0xD3F5, 0x5C62, 0xD7A6, 0x5C64, 0xF6B5, 0x5C65, 0xD7DB, 0x5C6C, 0xE1D5, - 0x5C6F, 0xD4EA, 0x5C71, 0xDFA3, 0x5C79, 0xFDDF, 0x5C90, 0xD0F7, 0x5C91, 0xEDD4, 0x5CA1, 0xCBAA, 0x5CA9, 0xE4DB, 0x5CAB, 0xE1FB, - 0x5CAC, 0xCBA2, 0x5CB1, 0xD3E0, 0x5CB3, 0xE4BF, 0x5CB5, 0xFBC0, 0x5CB7, 0xDABE, 0x5CB8, 0xE4CD, 0x5CBA, 0xD6B9, 0x5CBE, 0xEFC0, - 0x5CC0, 0xE1FC, 0x5CD9, 0xF6B9, 0x5CE0, 0xDFC7, 0x5CE8, 0xE4B1, 0x5CEF, 0xDCE7, 0x5CF0, 0xDCE8, 0x5CF4, 0xFAD6, 0x5CF6, 0xD3F6, - 0x5CFB, 0xF1DA, 0x5CFD, 0xFAF2, 0x5D07, 0xE2FD, 0x5D0D, 0xD5CF, 0x5D0E, 0xD0F8, 0x5D11, 0xCDDF, 0x5D14, 0xF5CB, 0x5D16, 0xE4F0, - 0x5D17, 0xCBAB, 0x5D19, 0xD7C4, 0x5D27, 0xE2FE, 0x5D29, 0xDDDA, 0x5D4B, 0xDAAE, 0x5D4C, 0xCAEE, 0x5D50, 0xD5B9, 0x5D69, 0xE3A1, - 0x5D6C, 0xE8E3, 0x5D6F, 0xF3AB, 0x5D87, 0xCFA9, 0x5D8B, 0xD3F7, 0x5D9D, 0xD4F1, 0x5DA0, 0xCEE4, 0x5DA2, 0xE8F2, 0x5DAA, 0xE5F5, - 0x5DB8, 0xE7AE, 0x5DBA, 0xD6BA, 0x5DBC, 0xDFEC, 0x5DBD, 0xE4C0, 0x5DCD, 0xE8E4, 0x5DD2, 0xD8B5, 0x5DD6, 0xE4DC, 0x5DDD, 0xF4B9, - 0x5DDE, 0xF1B6, 0x5DE1, 0xE2DE, 0x5DE2, 0xE1B5, 0x5DE5, 0xCDEF, 0x5DE6, 0xF1A7, 0x5DE7, 0xCEE5, 0x5DE8, 0xCBDD, 0x5DEB, 0xD9E3, - 0x5DEE, 0xF3AC, 0x5DF1, 0xD0F9, 0x5DF2, 0xECAB, 0x5DF3, 0xDED3, 0x5DF4, 0xF7E9, 0x5DF7, 0xF9F5, 0x5DFD, 0xE1DE, 0x5DFE, 0xCBEE, - 0x5E02, 0xE3BC, 0x5E03, 0xF8D6, 0x5E06, 0xDBEE, 0x5E0C, 0xFDF1, 0x5E11, 0xF7B6, 0x5E16, 0xF4DE, 0x5E19, 0xF2ED, 0x5E1B, 0xDBD9, - 0x5E1D, 0xF0A8, 0x5E25, 0xE1FD, 0x5E2B, 0xDED4, 0x5E2D, 0xE0AC, 0x5E33, 0xEDE3, 0x5E36, 0xD3E1, 0x5E38, 0xDFC8, 0x5E3D, 0xD9B6, - 0x5E3F, 0xFDAC, 0x5E40, 0xEFD3, 0x5E44, 0xE4C1, 0x5E45, 0xF8EB, 0x5E47, 0xDBAC, 0x5E4C, 0xFCC6, 0x5E55, 0xD8AD, 0x5E5F, 0xF6BA, - 0x5E61, 0xDBDF, 0x5E62, 0xD3D3, 0x5E63, 0xF8C7, 0x5E72, 0xCACE, 0x5E73, 0xF8C1, 0x5E74, 0xD2B4, 0x5E77, 0xDCB4, 0x5E78, 0xFAB9, - 0x5E79, 0xCACF, 0x5E7B, 0xFCB3, 0x5E7C, 0xEAEA, 0x5E7D, 0xEAEB, 0x5E7E, 0xD0FA, 0x5E84, 0xEDE4, 0x5E87, 0xDDE7, 0x5E8A, 0xDFC9, - 0x5E8F, 0xDFED, 0x5E95, 0xEEBC, 0x5E97, 0xEFC1, 0x5E9A, 0xCCD2, 0x5E9C, 0xDDA4, 0x5EA0, 0xDFCA, 0x5EA6, 0xD3F8, 0x5EA7, 0xF1A8, - 0x5EAB, 0xCDB7, 0x5EAD, 0xEFD4, 0x5EB5, 0xE4DD, 0x5EB6, 0xDFEE, 0x5EB7, 0xCBAC, 0x5EB8, 0xE9BC, 0x5EBE, 0xEAEC, 0x5EC2, 0xDFCB, - 0x5EC8, 0xF9BF, 0x5EC9, 0xD6AF, 0x5ECA, 0xD5C6, 0x5ED0, 0xCFAA, 0x5ED3, 0xCEA9, 0x5ED6, 0xD6F8, 0x5EDA, 0xF1B7, 0x5EDB, 0xEEF8, - 0x5EDF, 0xD9D9, 0x5EE0, 0xF3DF, 0x5EE2, 0xF8C8, 0x5EE3, 0xCEC6, 0x5EEC, 0xD5E6, 0x5EF3, 0xF4E6, 0x5EF6, 0xE6C5, 0x5EF7, 0xEFD5, - 0x5EFA, 0xCBEF, 0x5EFB, 0xFCDF, 0x5F01, 0xDCA7, 0x5F04, 0xD6E7, 0x5F0A, 0xF8C9, 0x5F0F, 0xE3D2, 0x5F11, 0xE3BD, 0x5F13, 0xCFE1, - 0x5F14, 0xF0C0, 0x5F15, 0xECDA, 0x5F17, 0xDDD7, 0x5F18, 0xFBF0, 0x5F1B, 0xECAC, 0x5F1F, 0xF0A9, 0x5F26, 0xFAD7, 0x5F27, 0xFBC1, - 0x5F29, 0xD2C0, 0x5F31, 0xE5B0, 0x5F35, 0xEDE5, 0x5F3A, 0xCBAD, 0x5F3C, 0xF9B0, 0x5F48, 0xF7A5, 0x5F4A, 0xCBAE, 0x5F4C, 0xDAAF, - 0x5F4E, 0xD8B6, 0x5F56, 0xD3A7, 0x5F57, 0xFBB2, 0x5F59, 0xFDC4, 0x5F5B, 0xECAD, 0x5F62, 0xFBA1, 0x5F66, 0xE5E9, 0x5F67, 0xE9EE, - 0x5F69, 0xF3F4, 0x5F6A, 0xF8F3, 0x5F6B, 0xF0C1, 0x5F6C, 0xDEAF, 0x5F6D, 0xF8B0, 0x5F70, 0xF3E0, 0x5F71, 0xE7AF, 0x5F77, 0xDBAD, - 0x5F79, 0xE6B5, 0x5F7C, 0xF9A8, 0x5F7F, 0xDDD8, 0x5F80, 0xE8D9, 0x5F81, 0xEFD6, 0x5F85, 0xD3E2, 0x5F87, 0xE2DF, 0x5F8A, 0xFCE0, - 0x5F8B, 0xD7C8, 0x5F8C, 0xFDAD, 0x5F90, 0xDFEF, 0x5F91, 0xCCD3, 0x5F92, 0xD3F9, 0x5F97, 0xD4F0, 0x5F98, 0xDBC7, 0x5F99, 0xDED5, - 0x5F9E, 0xF0F4, 0x5FA0, 0xD5D0, 0x5FA1, 0xE5D9, 0x5FA8, 0xFCC7, 0x5FA9, 0xDCD6, 0x5FAA, 0xE2E0, 0x5FAE, 0xDAB0, 0x5FB5, 0xF3A3, - 0x5FB7, 0xD3EC, 0x5FB9, 0xF4CB, 0x5FBD, 0xFDC5, 0x5FC3, 0xE3FD, 0x5FC5, 0xF9B1, 0x5FCC, 0xD0FB, 0x5FCD, 0xECDB, 0x5FD6, 0xF5BC, - 0x5FD7, 0xF2A4, 0x5FD8, 0xD8CE, 0x5FD9, 0xD8CF, 0x5FE0, 0xF5F7, 0x5FEB, 0xF6E1, 0x5FF5, 0xD2B7, 0x5FFD, 0xFBEC, 0x5FFF, 0xDDC8, - 0x600F, 0xE4E8, 0x6012, 0xD2C1, 0x6016, 0xF8D7, 0x601C, 0xD6BB, 0x601D, 0xDED6, 0x6020, 0xF7BD, 0x6021, 0xECAE, 0x6025, 0xD0E1, - 0x6027, 0xE0F5, 0x6028, 0xEAB3, 0x602A, 0xCED6, 0x602F, 0xCCA5, 0x6041, 0xECF6, 0x6042, 0xE2E1, 0x6043, 0xE3BE, 0x604D, 0xFCC8, - 0x6050, 0xCDF0, 0x6052, 0xF9F6, 0x6055, 0xDFF0, 0x6059, 0xE5BF, 0x605D, 0xCEBF, 0x6062, 0xFCE1, 0x6063, 0xEDB0, 0x6064, 0xFDD1, - 0x6065, 0xF6BB, 0x6068, 0xF9CF, 0x6069, 0xEBDA, 0x606A, 0xCAC1, 0x606C, 0xD2B8, 0x606D, 0xCDF1, 0x606F, 0xE3D3, 0x6070, 0xFDE6, - 0x6085, 0xE6ED, 0x6089, 0xE3FA, 0x608C, 0xF0AA, 0x608D, 0xF9D0, 0x6094, 0xFCE2, 0x6096, 0xF8A7, 0x609A, 0xE1E5, 0x609B, 0xEEF9, - 0x609F, 0xE7F6, 0x60A0, 0xEAED, 0x60A3, 0xFCB4, 0x60A4, 0xF5C2, 0x60A7, 0xD7DC, 0x60B0, 0xF0F5, 0x60B2, 0xDDE8, 0x60B3, 0xD3ED, - 0x60B4, 0xF5FC, 0x60B6, 0xDABF, 0x60B8, 0xCCFB, 0x60BC, 0xD3FA, 0x60BD, 0xF4A4, 0x60C5, 0xEFD7, 0x60C7, 0xD4C3, 0x60D1, 0xFBE3, - 0x60DA, 0xFBED, 0x60DC, 0xE0AD, 0x60DF, 0xEAEE, 0x60E0, 0xFBB3, 0x60E1, 0xE4C2, 0x60F0, 0xF6E7, 0x60F1, 0xD2DD, 0x60F3, 0xDFCC, - 0x60F6, 0xFCC9, 0x60F9, 0xE5A9, 0x60FA, 0xE0F6, 0x60FB, 0xF6B3, 0x6101, 0xE1FE, 0x6106, 0xCBF0, 0x6108, 0xEAEF, 0x6109, 0xEAF0, - 0x610D, 0xDAC0, 0x610E, 0xF8B4, 0x610F, 0xEBF2, 0x6115, 0xE4C3, 0x611A, 0xE9D7, 0x611B, 0xE4F1, 0x611F, 0xCAEF, 0x6127, 0xCED7, - 0x6130, 0xFCCA, 0x6134, 0xF3E1, 0x6137, 0xCBC4, 0x613C, 0xE3E5, 0x613E, 0xCBC5, 0x613F, 0xEAB4, 0x6142, 0xE9BD, 0x6144, 0xD7C9, - 0x6147, 0xEBDB, 0x6148, 0xEDB1, 0x614A, 0xCCC3, 0x614B, 0xF7BE, 0x614C, 0xFCCB, 0x6153, 0xF8F4, 0x6155, 0xD9B7, 0x6158, 0xF3D3, - 0x6159, 0xF3D4, 0x615D, 0xF7E4, 0x615F, 0xF7D1, 0x6162, 0xD8B7, 0x6163, 0xCEB1, 0x6164, 0xCAC2, 0x6167, 0xFBB4, 0x6168, 0xCBC6, - 0x616B, 0xF0F6, 0x616E, 0xD5E7, 0x6170, 0xEAD0, 0x6176, 0xCCD4, 0x6177, 0xCBAF, 0x617D, 0xF4AA, 0x617E, 0xE9AF, 0x6181, 0xF5C3, - 0x6182, 0xE9D8, 0x618A, 0xDDE9, 0x618E, 0xF1F3, 0x6190, 0xD5FB, 0x6191, 0xDEBB, 0x6194, 0xF4FB, 0x6198, 0xFDF3, 0x6199, 0xFDF2, - 0x619A, 0xF7A6, 0x61A4, 0xDDC9, 0x61A7, 0xD4D3, 0x61A9, 0xCCA8, 0x61AB, 0xDAC1, 0x61AC, 0xCCD5, 0x61AE, 0xD9E4, 0x61B2, 0xFACA, - 0x61B6, 0xE5E3, 0x61BA, 0xD3BC, 0x61BE, 0xCAF0, 0x61C3, 0xD0C4, 0x61C7, 0xCAD0, 0x61C8, 0xFAAB, 0x61C9, 0xEBEB, 0x61CA, 0xE7F8, - 0x61CB, 0xD9E5, 0x61E6, 0xD1D7, 0x61F2, 0xF3A4, 0x61F6, 0xD4FB, 0x61F7, 0xFCE3, 0x61F8, 0xFAD8, 0x61FA, 0xF3D5, 0x61FC, 0xCFAB, - 0x61FF, 0xEBF3, 0x6200, 0xD5FC, 0x6207, 0xD3D4, 0x6208, 0xCDFC, 0x620A, 0xD9E6, 0x620C, 0xE2F9, 0x620D, 0xE2A1, 0x620E, 0xEBD4, - 0x6210, 0xE0F7, 0x6211, 0xE4B2, 0x6212, 0xCCFC, 0x6216, 0xFBE4, 0x621A, 0xF4AB, 0x621F, 0xD0BD, 0x6221, 0xCAF1, 0x622A, 0xEFB8, - 0x622E, 0xD7C0, 0x6230, 0xEEFA, 0x6231, 0xFDF4, 0x6234, 0xD3E3, 0x6236, 0xFBC2, 0x623E, 0xD5E8, 0x623F, 0xDBAE, 0x6240, 0xE1B6, - 0x6241, 0xF8B7, 0x6247, 0xE0BF, 0x6248, 0xFBC3, 0x6249, 0xDDEA, 0x624B, 0xE2A2, 0x624D, 0xEEA6, 0x6253, 0xF6E8, 0x6258, 0xF6F5, - 0x626E, 0xDDCA, 0x6271, 0xD0E2, 0x6276, 0xDDA6, 0x6279, 0xDDEB, 0x627C, 0xE4F9, 0x627F, 0xE3AF, 0x6280, 0xD0FC, 0x6284, 0xF4FC, - 0x6289, 0xCCBC, 0x628A, 0xF7EA, 0x6291, 0xE5E4, 0x6292, 0xDFF1, 0x6295, 0xF7E1, 0x6297, 0xF9F7, 0x6298, 0xEFB9, 0x629B, 0xF8D8, - 0x62AB, 0xF9A9, 0x62B1, 0xF8D9, 0x62B5, 0xEEBD, 0x62B9, 0xD8C6, 0x62BC, 0xE4E3, 0x62BD, 0xF5CE, 0x62C2, 0xDDD9, 0x62C7, 0xD9E7, - 0x62C8, 0xD2B9, 0x62C9, 0xD5C3, 0x62CC, 0xDAE5, 0x62CD, 0xDAD0, 0x62CF, 0xD1D9, 0x62D0, 0xCED8, 0x62D2, 0xCBDE, 0x62D3, 0xF4AC, - 0x62D4, 0xDAFB, 0x62D6, 0xF6E9, 0x62D7, 0xE8F3, 0x62D8, 0xCFAC, 0x62D9, 0xF0F0, 0x62DB, 0xF4FD, 0x62DC, 0xDBC8, 0x62EC, 0xCEC0, - 0x62ED, 0xE3D4, 0x62EE, 0xD1CF, 0x62EF, 0xF1F5, 0x62F1, 0xCDF2, 0x62F3, 0xCFEB, 0x62F7, 0xCDB8, 0x62FE, 0xE3A6, 0x62FF, 0xD1DA, - 0x6301, 0xF2A5, 0x6307, 0xF2A6, 0x6309, 0xE4CE, 0x6311, 0xD3FB, 0x632B, 0xF1A9, 0x632F, 0xF2C9, 0x633A, 0xEFD8, 0x633B, 0xE6C9, - 0x633D, 0xD8B8, 0x633E, 0xFAF3, 0x6349, 0xF3B5, 0x634C, 0xF8A4, 0x634F, 0xD1F3, 0x6350, 0xE6C8, 0x6355, 0xF8DA, 0x6367, 0xDCE9, - 0x6368, 0xDED7, 0x636E, 0xCBDF, 0x6372, 0xCFEC, 0x6377, 0xF4DF, 0x637A, 0xD1F4, 0x637B, 0xD2BA, 0x637F, 0xDFF2, 0x6383, 0xE1B7, - 0x6388, 0xE2A3, 0x6389, 0xD3FC, 0x638C, 0xEDE6, 0x6392, 0xDBC9, 0x6396, 0xE4FA, 0x6398, 0xCFDE, 0x639B, 0xCED0, 0x63A0, 0xD5D3, - 0x63A1, 0xF3F5, 0x63A2, 0xF7AE, 0x63A5, 0xEFC8, 0x63A7, 0xCDF3, 0x63A8, 0xF5CF, 0x63A9, 0xE5F3, 0x63AA, 0xF0C2, 0x63C0, 0xCAD1, - 0x63C4, 0xEAF1, 0x63C6, 0xD0A6, 0x63CF, 0xD9DA, 0x63D0, 0xF0AB, 0x63D6, 0xEBE7, 0x63DA, 0xE5C0, 0x63DB, 0xFCB5, 0x63E1, 0xE4C4, - 0x63ED, 0xCCA9, 0x63EE, 0xFDC6, 0x63F4, 0xEAB5, 0x63F6, 0xE5AA, 0x63F7, 0xDFBA, 0x640D, 0xE1DF, 0x640F, 0xDAD1, 0x6414, 0xE1B8, - 0x6416, 0xE8F4, 0x6417, 0xD3FD, 0x641C, 0xE2A4, 0x6422, 0xF2CA, 0x642C, 0xDAE6, 0x642D, 0xF7B3, 0x643A, 0xFDCD, 0x643E, 0xF3B6, - 0x6458, 0xEED7, 0x6460, 0xF5C4, 0x6469, 0xD8A4, 0x646F, 0xF2A7, 0x6478, 0xD9B8, 0x6479, 0xD9B9, 0x647A, 0xEFC9, 0x6488, 0xD6CE, - 0x6491, 0xF7CB, 0x6492, 0xDFAE, 0x6493, 0xE8F5, 0x649A, 0xD2B5, 0x649E, 0xD3D5, 0x64A4, 0xF4CC, 0x64A5, 0xDAFC, 0x64AB, 0xD9E8, - 0x64AD, 0xF7EB, 0x64AE, 0xF5C9, 0x64B0, 0xF3BC, 0x64B2, 0xDAD2, 0x64BB, 0xD3B5, 0x64C1, 0xE8B6, 0x64C4, 0xD6CF, 0x64C5, 0xF4BA, - 0x64C7, 0xF7C9, 0x64CA, 0xCCAA, 0x64CD, 0xF0C3, 0x64CE, 0xCCD6, 0x64D2, 0xD0D3, 0x64D4, 0xD3BD, 0x64D8, 0xDBFB, 0x64DA, 0xCBE0, - 0x64E1, 0xD3E4, 0x64E2, 0xF6F7, 0x64E5, 0xD5BA, 0x64E6, 0xF3CD, 0x64E7, 0xCBE1, 0x64EC, 0xEBF4, 0x64F2, 0xF4AD, 0x64F4, 0xFCAA, - 0x64FA, 0xF7EC, 0x64FE, 0xE8F6, 0x6500, 0xDAE7, 0x6504, 0xF7CC, 0x6518, 0xE5C1, 0x651D, 0xE0EE, 0x6523, 0xD5FD, 0x652A, 0xCEE6, - 0x652B, 0xFCAB, 0x652C, 0xD5BB, 0x652F, 0xF2A8, 0x6536, 0xE2A5, 0x6537, 0xCDB9, 0x6538, 0xEAF2, 0x6539, 0xCBC7, 0x653B, 0xCDF4, - 0x653E, 0xDBAF, 0x653F, 0xEFD9, 0x6545, 0xCDBA, 0x6548, 0xFCF9, 0x654D, 0xDFF3, 0x654E, 0xCEE7, 0x654F, 0xDAC2, 0x6551, 0xCFAD, - 0x6556, 0xE7F9, 0x6557, 0xF8A8, 0x655E, 0xF3E2, 0x6562, 0xCAF2, 0x6563, 0xDFA4, 0x6566, 0xD4C4, 0x656C, 0xCCD7, 0x656D, 0xE5C2, - 0x6572, 0xCDBB, 0x6574, 0xEFDA, 0x6575, 0xEED8, 0x6577, 0xDDA7, 0x6578, 0xE2A6, 0x657E, 0xE0C0, 0x6582, 0xD6B0, 0x6583, 0xF8CA, - 0x6585, 0xFCFA, 0x6587, 0xD9FE, 0x658C, 0xDEB0, 0x6590, 0xDDEC, 0x6591, 0xDAE8, 0x6597, 0xD4E0, 0x6599, 0xD6F9, 0x659B, 0xCDD7, - 0x659C, 0xDED8, 0x659F, 0xF2F8, 0x65A1, 0xE4D6, 0x65A4, 0xD0C5, 0x65A5, 0xF4AE, 0x65A7, 0xDDA8, 0x65AB, 0xEDC5, 0x65AC, 0xF3D6, - 0x65AF, 0xDED9, 0x65B0, 0xE3E6, 0x65B7, 0xD3A8, 0x65B9, 0xDBB0, 0x65BC, 0xE5DA, 0x65BD, 0xE3BF, 0x65C1, 0xDBB1, 0x65C5, 0xD5E9, - 0x65CB, 0xE0C1, 0x65CC, 0xEFDB, 0x65CF, 0xF0E9, 0x65D2, 0xD7B2, 0x65D7, 0xD0FD, 0x65E0, 0xD9E9, 0x65E3, 0xD0FE, 0x65E5, 0xECED, - 0x65E6, 0xD3A9, 0x65E8, 0xF2A9, 0x65E9, 0xF0C4, 0x65EC, 0xE2E2, 0x65ED, 0xE9EF, 0x65F1, 0xF9D1, 0x65F4, 0xE9D9, 0x65FA, 0xE8DA, - 0x65FB, 0xDAC3, 0x65FC, 0xDAC4, 0x65FD, 0xD4C5, 0x65FF, 0xE7FA, 0x6606, 0xCDE0, 0x6607, 0xE3B0, 0x6609, 0xDBB2, 0x660A, 0xFBC4, - 0x660C, 0xF3E3, 0x660E, 0xD9A5, 0x660F, 0xFBE7, 0x6610, 0xDDCB, 0x6611, 0xD0D4, 0x6613, 0xE6B6, 0x6614, 0xE0AE, 0x6615, 0xFDDA, - 0x661E, 0xDCB5, 0x661F, 0xE0F8, 0x6620, 0xE7B1, 0x6625, 0xF5F0, 0x6627, 0xD8DC, 0x6628, 0xEDC6, 0x662D, 0xE1B9, 0x662F, 0xE3C0, - 0x6630, 0xF9C0, 0x6631, 0xE9F0, 0x6634, 0xD9DB, 0x6636, 0xF3E4, 0x663A, 0xDCB6, 0x663B, 0xE4E9, 0x6641, 0xF0C5, 0x6642, 0xE3C1, - 0x6643, 0xFCCC, 0x6644, 0xFCCD, 0x6649, 0xF2CB, 0x664B, 0xF2CC, 0x664F, 0xE4CF, 0x6659, 0xF1DB, 0x665B, 0xFAD9, 0x665D, 0xF1B8, - 0x665E, 0xFDF5, 0x665F, 0xE0F9, 0x6664, 0xE7FB, 0x6665, 0xFCB7, 0x6666, 0xFCE4, 0x6667, 0xFBC5, 0x6668, 0xE3E7, 0x6669, 0xD8B9, - 0x666B, 0xF6F8, 0x666E, 0xDCC5, 0x666F, 0xCCD8, 0x6673, 0xE0AF, 0x6674, 0xF4E7, 0x6676, 0xEFDC, 0x6677, 0xCFFC, 0x6678, 0xEFDD, - 0x667A, 0xF2AA, 0x6684, 0xFDBE, 0x6687, 0xCAAC, 0x6688, 0xFDBB, 0x6689, 0xFDC7, 0x668E, 0xE7B2, 0x6690, 0xEAD1, 0x6691, 0xDFF4, - 0x6696, 0xD1EC, 0x6697, 0xE4DE, 0x6698, 0xE5C3, 0x669D, 0xD9A6, 0x66A0, 0xCDBC, 0x66A2, 0xF3E5, 0x66AB, 0xEDD5, 0x66AE, 0xD9BA, - 0x66B2, 0xEDE7, 0x66B3, 0xFBB5, 0x66B4, 0xF8EC, 0x66B9, 0xE0E7, 0x66BB, 0xCCD9, 0x66BE, 0xD4C6, 0x66C4, 0xE7A5, 0x66C6, 0xD5F5, - 0x66C7, 0xD3BE, 0x66C9, 0xFCFB, 0x66D6, 0xE4F2, 0x66D9, 0xDFF5, 0x66DC, 0xE8F8, 0x66DD, 0xF8ED, 0x66E0, 0xCEC7, 0x66E6, 0xFDF6, - 0x66F0, 0xE8D8, 0x66F2, 0xCDD8, 0x66F3, 0xE7D6, 0x66F4, 0xCCDA, 0x66F7, 0xCAE3, 0x66F8, 0xDFF6, 0x66F9, 0xF0C7, 0x66FA, 0xF0C6, - 0x66FC, 0xD8BA, 0x66FE, 0xF1F4, 0x66FF, 0xF4F0, 0x6700, 0xF5CC, 0x6703, 0xFCE5, 0x6708, 0xEAC5, 0x6709, 0xEAF3, 0x670B, 0xDDDB, - 0x670D, 0xDCD7, 0x6714, 0xDEFD, 0x6715, 0xF2F9, 0x6717, 0xD5C7, 0x671B, 0xD8D0, 0x671D, 0xF0C8, 0x671E, 0xD1A1, 0x671F, 0xD1A2, - 0x6726, 0xD9D4, 0x6727, 0xD6E8, 0x6728, 0xD9CA, 0x672A, 0xDAB1, 0x672B, 0xD8C7, 0x672C, 0xDCE2, 0x672D, 0xF3CE, 0x672E, 0xF5F4, - 0x6731, 0xF1B9, 0x6734, 0xDAD3, 0x6736, 0xF6EA, 0x673A, 0xCFF5, 0x673D, 0xFDAE, 0x6746, 0xCAD2, 0x6749, 0xDFB4, 0x674E, 0xD7DD, - 0x674F, 0xFABA, 0x6750, 0xEEA7, 0x6751, 0xF5BD, 0x6753, 0xF8F5, 0x6756, 0xEDE8, 0x675C, 0xD4E1, 0x675E, 0xD1A3, 0x675F, 0xE1D6, - 0x676D, 0xF9F8, 0x676F, 0xDBCA, 0x6770, 0xCBF9, 0x6771, 0xD4D4, 0x6773, 0xD9DC, 0x6775, 0xEEBE, 0x6777, 0xF7ED, 0x677B, 0xD2EE, - 0x677E, 0xE1E6, 0x677F, 0xF7F9, 0x6787, 0xDDED, 0x6789, 0xE8DB, 0x678B, 0xDBB3, 0x678F, 0xD1F7, 0x6790, 0xE0B0, 0x6793, 0xD4E2, - 0x6795, 0xF6D7, 0x6797, 0xD7F9, 0x679A, 0xD8DD, 0x679C, 0xCDFD, 0x679D, 0xF2AB, 0x67AF, 0xCDBD, 0x67B0, 0xF8C2, 0x67B3, 0xF2AC, - 0x67B6, 0xCAAD, 0x67B7, 0xCAAE, 0x67B8, 0xCFAE, 0x67BE, 0xE3C2, 0x67C4, 0xDCB7, 0x67CF, 0xDBDA, 0x67D0, 0xD9BB, 0x67D1, 0xCAF3, - 0x67D2, 0xF6D3, 0x67D3, 0xE6F8, 0x67D4, 0xEAF5, 0x67DA, 0xEAF6, 0x67DD, 0xF6F9, 0x67E9, 0xCFAF, 0x67EC, 0xCAD3, 0x67EF, 0xCAAF, - 0x67F0, 0xD2B0, 0x67F1, 0xF1BA, 0x67F3, 0xD7B3, 0x67F4, 0xE3C3, 0x67F5, 0xF3FD, 0x67F6, 0xDEDA, 0x67FB, 0xDEDB, 0x67FE, 0xEFDE, - 0x6812, 0xE2E3, 0x6813, 0xEEFB, 0x6816, 0xDFF7, 0x6817, 0xD7CA, 0x6821, 0xCEE8, 0x6822, 0xDBDB, 0x682A, 0xF1BB, 0x682F, 0xE9F1, - 0x6838, 0xFAB7, 0x6839, 0xD0C6, 0x683C, 0xCCAB, 0x683D, 0xEEA8, 0x6840, 0xCBFA, 0x6841, 0xF9F9, 0x6842, 0xCCFD, 0x6843, 0xD3FE, - 0x6848, 0xE4D0, 0x684E, 0xF2EE, 0x6850, 0xD4D5, 0x6851, 0xDFCD, 0x6853, 0xFCB8, 0x6854, 0xD1D0, 0x686D, 0xF2CD, 0x6876, 0xF7D2, - 0x687F, 0xCAD4, 0x6881, 0xD5D9, 0x6885, 0xD8DE, 0x688F, 0xCDD9, 0x6893, 0xEEA9, 0x6894, 0xF6BC, 0x6897, 0xCCDB, 0x689D, 0xF0C9, - 0x689F, 0xFCFC, 0x68A1, 0xE8C9, 0x68A2, 0xF4FE, 0x68A7, 0xE7FC, 0x68A8, 0xD7DE, 0x68AD, 0xDEDC, 0x68AF, 0xF0AC, 0x68B0, 0xCCFE, - 0x68B1, 0xCDE1, 0x68B3, 0xE1BA, 0x68B5, 0xDBEF, 0x68B6, 0xDAB2, 0x68C4, 0xD1A5, 0x68C5, 0xDCB8, 0x68C9, 0xD8F6, 0x68CB, 0xD1A4, - 0x68CD, 0xCDE2, 0x68D2, 0xDCEA, 0x68D5, 0xF0F7, 0x68D7, 0xF0CA, 0x68D8, 0xD0BE, 0x68DA, 0xDDDC, 0x68DF, 0xD4D6, 0x68E0, 0xD3D6, - 0x68E7, 0xEDD0, 0x68E8, 0xCDA1, 0x68EE, 0xDFB5, 0x68F2, 0xDFF8, 0x68F9, 0xD4A1, 0x68FA, 0xCEB2, 0x6900, 0xE8CA, 0x6905, 0xEBF5, - 0x690D, 0xE3D5, 0x690E, 0xF5D0, 0x6912, 0xF5A1, 0x6927, 0xD9A7, 0x6930, 0xE5AB, 0x693D, 0xE6CB, 0x693F, 0xF5F1, 0x694A, 0xE5C5, - 0x6953, 0xF9A3, 0x6954, 0xE0DB, 0x6955, 0xF6EB, 0x6957, 0xCBF1, 0x6959, 0xD9EA, 0x695A, 0xF5A2, 0x695E, 0xD7D1, 0x6960, 0xD1F8, - 0x6961, 0xEAF8, 0x6962, 0xEAF9, 0x6963, 0xDAB3, 0x6968, 0xEFDF, 0x696B, 0xF1EF, 0x696D, 0xE5F6, 0x696E, 0xEEBF, 0x696F, 0xE2E4, - 0x6975, 0xD0BF, 0x6977, 0xFAAC, 0x6978, 0xF5D1, 0x6979, 0xE7B3, 0x6995, 0xE9BE, 0x699B, 0xF2CE, 0x699C, 0xDBB4, 0x69A5, 0xFCCE, - 0x69A7, 0xDDEE, 0x69AE, 0xE7B4, 0x69B4, 0xD7B4, 0x69BB, 0xF7B4, 0x69C1, 0xCDBE, 0x69C3, 0xDAE9, 0x69CB, 0xCFB0, 0x69CC, 0xF7D9, - 0x69CD, 0xF3E6, 0x69D0, 0xCED9, 0x69E8, 0xCEAA, 0x69EA, 0xCBC8, 0x69FB, 0xD0A7, 0x69FD, 0xF0CB, 0x69FF, 0xD0C7, 0x6A02, 0xE4C5, - 0x6A0A, 0xDBE0, 0x6A11, 0xD5DA, 0x6A13, 0xD7A7, 0x6A17, 0xEEC0, 0x6A19, 0xF8F6, 0x6A1E, 0xF5D2, 0x6A1F, 0xEDE9, 0x6A21, 0xD9BC, - 0x6A23, 0xE5C6, 0x6A35, 0xF5A3, 0x6A38, 0xDAD4, 0x6A39, 0xE2A7, 0x6A3A, 0xFBFC, 0x6A3D, 0xF1DC, 0x6A44, 0xCAF4, 0x6A48, 0xE8FA, - 0x6A4B, 0xCEE9, 0x6A52, 0xE9F8, 0x6A53, 0xE2E5, 0x6A58, 0xD0B9, 0x6A59, 0xD4F2, 0x6A5F, 0xD1A6, 0x6A61, 0xDFCE, 0x6A6B, 0xFCF4, - 0x6A80, 0xD3AA, 0x6A84, 0xCCAC, 0x6A89, 0xEFE0, 0x6A8D, 0xE5E5, 0x6A8E, 0xD0D5, 0x6A97, 0xDBFC, 0x6A9C, 0xFCE6, 0x6AA2, 0xCBFE, - 0x6AA3, 0xEDEA, 0x6AB3, 0xDEB1, 0x6ABB, 0xF9E3, 0x6AC2, 0xD4A2, 0x6AC3, 0xCFF6, 0x6AD3, 0xD6D0, 0x6ADA, 0xD5EA, 0x6ADB, 0xF1EE, - 0x6AF6, 0xFACB, 0x6AFB, 0xE5A1, 0x6B04, 0xD5B1, 0x6B0A, 0xCFED, 0x6B0C, 0xEDEB, 0x6B12, 0xD5B2, 0x6B16, 0xD5BC, 0x6B20, 0xFDE2, - 0x6B21, 0xF3AD, 0x6B23, 0xFDDB, 0x6B32, 0xE9B0, 0x6B3A, 0xD1A7, 0x6B3D, 0xFDE3, 0x6B3E, 0xCEB3, 0x6B46, 0xFDE4, 0x6B47, 0xFACE, - 0x6B4C, 0xCAB0, 0x6B4E, 0xF7A7, 0x6B50, 0xCFB1, 0x6B5F, 0xE6A2, 0x6B61, 0xFCB6, 0x6B62, 0xF2AD, 0x6B63, 0xEFE1, 0x6B64, 0xF3AE, - 0x6B65, 0xDCC6, 0x6B66, 0xD9EB, 0x6B6A, 0xE8E0, 0x6B72, 0xE1A8, 0x6B77, 0xD5F6, 0x6B78, 0xCFFD, 0x6B7B, 0xDEDD, 0x6B7F, 0xD9D1, - 0x6B83, 0xE4EA, 0x6B84, 0xF2CF, 0x6B86, 0xF7BF, 0x6B89, 0xE2E6, 0x6B8A, 0xE2A8, 0x6B96, 0xE3D6, 0x6B98, 0xEDD1, 0x6B9E, 0xE9F9, - 0x6BAE, 0xD6B1, 0x6BAF, 0xDEB2, 0x6BB2, 0xE0E8, 0x6BB5, 0xD3AB, 0x6BB7, 0xEBDC, 0x6BBA, 0xDFAF, 0x6BBC, 0xCAC3, 0x6BBF, 0xEEFC, - 0x6BC1, 0xFDC3, 0x6BC5, 0xEBF6, 0x6BC6, 0xCFB2, 0x6BCB, 0xD9EC, 0x6BCD, 0xD9BD, 0x6BCF, 0xD8DF, 0x6BD2, 0xD4B8, 0x6BD3, 0xEBBE, - 0x6BD4, 0xDDEF, 0x6BD6, 0xDDF0, 0x6BD7, 0xDDF1, 0x6BD8, 0xDDF2, 0x6BDB, 0xD9BE, 0x6BEB, 0xFBC6, 0x6BEC, 0xCFB3, 0x6C08, 0xEEFD, - 0x6C0F, 0xE4AB, 0x6C11, 0xDAC5, 0x6C13, 0xD8EC, 0x6C23, 0xD1A8, 0x6C34, 0xE2A9, 0x6C37, 0xDEBC, 0x6C38, 0xE7B5, 0x6C3E, 0xDBF0, - 0x6C40, 0xEFE2, 0x6C41, 0xF1F0, 0x6C42, 0xCFB4, 0x6C4E, 0xDBF1, 0x6C50, 0xE0B1, 0x6C55, 0xDFA5, 0x6C57, 0xF9D2, 0x6C5A, 0xE7FD, - 0x6C5D, 0xE6A3, 0x6C5E, 0xFBF1, 0x6C5F, 0xCBB0, 0x6C60, 0xF2AE, 0x6C68, 0xCDE7, 0x6C6A, 0xE8DC, 0x6C6D, 0xE7D7, 0x6C70, 0xF7C0, - 0x6C72, 0xD0E3, 0x6C76, 0xDAA1, 0x6C7A, 0xCCBD, 0x6C7D, 0xD1A9, 0x6C7E, 0xDDCC, 0x6C81, 0xE3FE, 0x6C82, 0xD1AA, 0x6C83, 0xE8AA, - 0x6C85, 0xEAB6, 0x6C86, 0xF9FA, 0x6C87, 0xE6CC, 0x6C88, 0xF6D8, 0x6C8C, 0xD4C7, 0x6C90, 0xD9CB, 0x6C92, 0xD9D2, 0x6C93, 0xD3CB, - 0x6C94, 0xD8F7, 0x6C95, 0xDAA9, 0x6C96, 0xF5F8, 0x6C99, 0xDEDE, 0x6C9A, 0xF2AF, 0x6C9B, 0xF8A9, 0x6CAB, 0xD8C8, 0x6CAE, 0xEEC1, - 0x6CB3, 0xF9C1, 0x6CB8, 0xDDF3, 0x6CB9, 0xEAFA, 0x6CBB, 0xF6BD, 0x6CBC, 0xE1BB, 0x6CBD, 0xCDBF, 0x6CBE, 0xF4D4, 0x6CBF, 0xE6CD, - 0x6CC1, 0xFCCF, 0x6CC2, 0xFBA2, 0x6CC4, 0xE0DC, 0x6CC9, 0xF4BB, 0x6CCA, 0xDAD5, 0x6CCC, 0xF9B2, 0x6CD3, 0xFBF2, 0x6CD5, 0xDBF6, - 0x6CD7, 0xDEDF, 0x6CDB, 0xDBF2, 0x6CE1, 0xF8DC, 0x6CE2, 0xF7EE, 0x6CE3, 0xEBE8, 0x6CE5, 0xD2FA, 0x6CE8, 0xF1BC, 0x6CEB, 0xFADA, - 0x6CEE, 0xDAEA, 0x6CEF, 0xDAC6, 0x6CF0, 0xF7C1, 0x6CF3, 0xE7B6, 0x6D0B, 0xE5C7, 0x6D0C, 0xD6AC, 0x6D11, 0xDCC7, 0x6D17, 0xE1A9, - 0x6D19, 0xE2AA, 0x6D1B, 0xD5A6, 0x6D1E, 0xD4D7, 0x6D25, 0xF2D0, 0x6D27, 0xEAFB, 0x6D29, 0xE0DD, 0x6D2A, 0xFBF3, 0x6D32, 0xF1BD, - 0x6D35, 0xE2E7, 0x6D36, 0xFDD7, 0x6D38, 0xCEC8, 0x6D39, 0xEAB7, 0x6D3B, 0xFCC0, 0x6D3D, 0xFDE7, 0x6D3E, 0xF7EF, 0x6D41, 0xD7B5, - 0x6D59, 0xEFBA, 0x6D5A, 0xF1DD, 0x6D5C, 0xDEB3, 0x6D63, 0xE8CB, 0x6D66, 0xF8DD, 0x6D69, 0xFBC7, 0x6D6A, 0xD5C8, 0x6D6C, 0xD7DF, - 0x6D6E, 0xDDA9, 0x6D74, 0xE9B1, 0x6D77, 0xFAAD, 0x6D78, 0xF6D9, 0x6D79, 0xFAF4, 0x6D7F, 0xF8AA, 0x6D85, 0xE6EE, 0x6D87, 0xCCDC, - 0x6D88, 0xE1BC, 0x6D89, 0xE0EF, 0x6D8C, 0xE9BF, 0x6D8D, 0xFCFD, 0x6D8E, 0xE6CE, 0x6D91, 0xE1D7, 0x6D93, 0xE6CF, 0x6D95, 0xF4F1, - 0x6DAF, 0xE4F3, 0x6DB2, 0xE4FB, 0x6DB5, 0xF9E4, 0x6DC0, 0xEFE3, 0x6DC3, 0xCFEE, 0x6DC4, 0xF6BE, 0x6DC5, 0xE0B2, 0x6DC6, 0xFCFE, - 0x6DC7, 0xD1AB, 0x6DCB, 0xD7FA, 0x6DCF, 0xFBC8, 0x6DD1, 0xE2D7, 0x6DD8, 0xD4A3, 0x6DD9, 0xF0F8, 0x6DDA, 0xD7A8, 0x6DDE, 0xE1E7, - 0x6DE1, 0xD3BF, 0x6DE8, 0xEFE4, 0x6DEA, 0xD7C5, 0x6DEB, 0xEBE2, 0x6DEE, 0xFCE7, 0x6DF1, 0xE4A2, 0x6DF3, 0xE2E8, 0x6DF5, 0xE6D0, - 0x6DF7, 0xFBE8, 0x6DF8, 0xF4E8, 0x6DF9, 0xE5F4, 0x6DFA, 0xF4BC, 0x6DFB, 0xF4D5, 0x6E17, 0xDFB6, 0x6E19, 0xFCB9, 0x6E1A, 0xEEC2, - 0x6E1B, 0xCAF5, 0x6E1F, 0xEFE5, 0x6E20, 0xCBE2, 0x6E21, 0xD4A4, 0x6E23, 0xDEE0, 0x6E24, 0xDAFD, 0x6E25, 0xE4C6, 0x6E26, 0xE8BE, - 0x6E2B, 0xE0DE, 0x6E2C, 0xF6B4, 0x6E2D, 0xEAD2, 0x6E2F, 0xF9FB, 0x6E32, 0xE0C2, 0x6E34, 0xCAE4, 0x6E36, 0xE7B7, 0x6E38, 0xEAFD, - 0x6E3A, 0xD9DD, 0x6E3C, 0xDAB4, 0x6E3D, 0xEEAA, 0x6E3E, 0xFBE9, 0x6E43, 0xDBCB, 0x6E44, 0xDAB5, 0x6E4A, 0xF1BE, 0x6E4D, 0xD3AC, - 0x6E56, 0xFBC9, 0x6E58, 0xDFCF, 0x6E5B, 0xD3C0, 0x6E5C, 0xE3D7, 0x6E5E, 0xEFE6, 0x6E5F, 0xFCD0, 0x6E67, 0xE9C0, 0x6E6B, 0xF5D3, - 0x6E6E, 0xECDC, 0x6E6F, 0xF7B7, 0x6E72, 0xEAB8, 0x6E73, 0xD1F9, 0x6E7A, 0xDCC8, 0x6E90, 0xEAB9, 0x6E96, 0xF1DE, 0x6E9C, 0xD7B6, - 0x6E9D, 0xCFB5, 0x6E9F, 0xD9A8, 0x6EA2, 0xECEE, 0x6EA5, 0xDDAA, 0x6EAA, 0xCDA2, 0x6EAB, 0xE8AE, 0x6EAF, 0xE1BD, 0x6EB1, 0xF2D1, - 0x6EB6, 0xE9C1, 0x6EBA, 0xD2FC, 0x6EC2, 0xDBB5, 0x6EC4, 0xF3E7, 0x6EC5, 0xD8FE, 0x6EC9, 0xFCD1, 0x6ECB, 0xEDB2, 0x6ECC, 0xF4AF, - 0x6ECE, 0xFBA3, 0x6ED1, 0xFCC1, 0x6ED3, 0xEEAB, 0x6ED4, 0xD4A5, 0x6EEF, 0xF4F2, 0x6EF4, 0xEED9, 0x6EF8, 0xFBCA, 0x6EFE, 0xCDE3, - 0x6EFF, 0xD8BB, 0x6F01, 0xE5DB, 0x6F02, 0xF8F7, 0x6F06, 0xF6D4, 0x6F0F, 0xD7A9, 0x6F11, 0xCBC9, 0x6F14, 0xE6D1, 0x6F15, 0xF0CC, - 0x6F20, 0xD8AE, 0x6F22, 0xF9D3, 0x6F23, 0xD5FE, 0x6F2B, 0xD8BC, 0x6F2C, 0xF2B0, 0x6F31, 0xE2AB, 0x6F32, 0xF3E8, 0x6F38, 0xEFC2, - 0x6F3F, 0xEDEC, 0x6F41, 0xE7B8, 0x6F51, 0xDAFE, 0x6F54, 0xCCBE, 0x6F57, 0xF2FC, 0x6F58, 0xDAEB, 0x6F5A, 0xE2D8, 0x6F5B, 0xEDD6, - 0x6F5E, 0xD6D1, 0x6F5F, 0xE0B3, 0x6F62, 0xFCD2, 0x6F64, 0xEBC8, 0x6F6D, 0xD3C1, 0x6F6E, 0xF0CD, 0x6F70, 0xCFF7, 0x6F7A, 0xEDD2, - 0x6F7C, 0xD4D8, 0x6F7D, 0xDCC9, 0x6F7E, 0xD7F1, 0x6F81, 0xDFBB, 0x6F84, 0xF3A5, 0x6F88, 0xF4CD, 0x6F8D, 0xF1BF, 0x6F8E, 0xF8B1, - 0x6F90, 0xE9FA, 0x6F94, 0xFBCB, 0x6F97, 0xCAD5, 0x6FA3, 0xF9D4, 0x6FA4, 0xF7CA, 0x6FA7, 0xD6C8, 0x6FAE, 0xFCE8, 0x6FAF, 0xF3BD, - 0x6FB1, 0xEEFE, 0x6FB3, 0xE7FE, 0x6FB9, 0xD3C2, 0x6FBE, 0xD3B6, 0x6FC0, 0xCCAD, 0x6FC1, 0xF6FA, 0x6FC2, 0xD6B2, 0x6FC3, 0xD2D8, - 0x6FCA, 0xE7D8, 0x6FD5, 0xE3A5, 0x6FDA, 0xE7B9, 0x6FDF, 0xF0AD, 0x6FE0, 0xFBCC, 0x6FE1, 0xEBA1, 0x6FE4, 0xD4A6, 0x6FE9, 0xFBCD, - 0x6FEB, 0xD5BD, 0x6FEC, 0xF1DF, 0x6FEF, 0xF6FB, 0x6FF1, 0xDEB4, 0x6FFE, 0xD5EB, 0x7001, 0xE5C8, 0x7005, 0xFBA4, 0x7006, 0xD4B9, - 0x7009, 0xDEE1, 0x700B, 0xE4A3, 0x700F, 0xD7B7, 0x7011, 0xF8EE, 0x7015, 0xDEB5, 0x7018, 0xD6D2, 0x701A, 0xF9D5, 0x701B, 0xE7BA, - 0x701C, 0xEBD5, 0x701D, 0xD5F7, 0x701E, 0xEFE7, 0x701F, 0xE1BE, 0x7023, 0xFAAE, 0x7027, 0xD6E9, 0x7028, 0xD6EE, 0x702F, 0xE7BB, - 0x7037, 0xECCB, 0x703E, 0xD5B3, 0x704C, 0xCEB4, 0x7050, 0xFBA5, 0x7051, 0xE1EE, 0x7058, 0xF7A8, 0x705D, 0xFBCE, 0x7063, 0xD8BD, - 0x706B, 0xFBFD, 0x7070, 0xFCE9, 0x7078, 0xCFB6, 0x707C, 0xEDC7, 0x707D, 0xEEAC, 0x7085, 0xCCDD, 0x708A, 0xF6A7, 0x708E, 0xE6FA, - 0x7092, 0xF5A4, 0x7098, 0xFDDC, 0x7099, 0xEDB3, 0x709A, 0xCEC9, 0x70A1, 0xEFE8, 0x70A4, 0xE1BF, 0x70AB, 0xFADB, 0x70AC, 0xCBE3, - 0x70AD, 0xF7A9, 0x70AF, 0xFBA6, 0x70B3, 0xDCB9, 0x70B7, 0xF1C0, 0x70B8, 0xEDC8, 0x70B9, 0xEFC3, 0x70C8, 0xD6AD, 0x70CB, 0xFDCE, - 0x70CF, 0xE8A1, 0x70D8, 0xFBF4, 0x70D9, 0xD5A7, 0x70DD, 0xF1F6, 0x70DF, 0xE6D3, 0x70F1, 0xCCDE, 0x70F9, 0xF8B2, 0x70FD, 0xDCEB, - 0x7104, 0xFDB6, 0x7109, 0xE5EA, 0x710C, 0xF1E0, 0x7119, 0xDBCC, 0x711A, 0xDDCD, 0x711E, 0xD4C8, 0x7121, 0xD9ED, 0x7126, 0xF5A5, - 0x7130, 0xE6FB, 0x7136, 0xE6D4, 0x7147, 0xFDC8, 0x7149, 0xD6A1, 0x714A, 0xFDBF, 0x714C, 0xFCD3, 0x714E, 0xEFA1, 0x7150, 0xE7BC, - 0x7156, 0xD1EE, 0x7159, 0xE6D5, 0x715C, 0xE9F2, 0x715E, 0xDFB0, 0x7164, 0xD8E0, 0x7165, 0xFCBA, 0x7166, 0xFDAF, 0x7167, 0xF0CE, - 0x7169, 0xDBE1, 0x716C, 0xE5C9, 0x716E, 0xEDB4, 0x717D, 0xE0C3, 0x7184, 0xE3D8, 0x7189, 0xE9FB, 0x718A, 0xEAA8, 0x718F, 0xFDB7, - 0x7192, 0xFBA7, 0x7194, 0xE9C2, 0x7199, 0xFDF7, 0x719F, 0xE2D9, 0x71A2, 0xDCEC, 0x71AC, 0xE8A2, 0x71B1, 0xE6F0, 0x71B9, 0xFDF8, - 0x71BA, 0xFDF9, 0x71BE, 0xF6BF, 0x71C1, 0xE7A7, 0x71C3, 0xE6D7, 0x71C8, 0xD4F3, 0x71C9, 0xD4C9, 0x71CE, 0xD6FA, 0x71D0, 0xD7F2, - 0x71D2, 0xE1C0, 0x71D4, 0xDBE2, 0x71D5, 0xE6D8, 0x71DF, 0xE7BD, 0x71E5, 0xF0CF, 0x71E6, 0xF3BE, 0x71E7, 0xE2AC, 0x71ED, 0xF5B7, - 0x71EE, 0xE0F0, 0x71FB, 0xFDB8, 0x71FC, 0xE3E8, 0x71FE, 0xD4A7, 0x71FF, 0xE8FC, 0x7200, 0xFAD2, 0x7206, 0xF8EF, 0x7210, 0xD6D3, - 0x721B, 0xD5B4, 0x722A, 0xF0D0, 0x722C, 0xF7F0, 0x722D, 0xEEB3, 0x7230, 0xEABA, 0x7232, 0xEAD3, 0x7235, 0xEDC9, 0x7236, 0xDDAB, - 0x723A, 0xE5AC, 0x723B, 0xFDA1, 0x723D, 0xDFD0, 0x723E, 0xECB3, 0x7240, 0xDFD1, 0x7246, 0xEDED, 0x7247, 0xF8B8, 0x7248, 0xF7FA, - 0x724C, 0xF8AB, 0x7252, 0xF4E0, 0x7258, 0xD4BA, 0x7259, 0xE4B3, 0x725B, 0xE9DA, 0x725D, 0xDEB6, 0x725F, 0xD9BF, 0x7261, 0xD9C0, - 0x7262, 0xD6EF, 0x7267, 0xD9CC, 0x7269, 0xDAAA, 0x7272, 0xDFE5, 0x7279, 0xF7E5, 0x727D, 0xCCB2, 0x7280, 0xDFF9, 0x7281, 0xD7E0, - 0x72A2, 0xD4BB, 0x72A7, 0xFDFA, 0x72AC, 0xCCB3, 0x72AF, 0xDBF3, 0x72C0, 0xDFD2, 0x72C2, 0xCECA, 0x72C4, 0xEEDA, 0x72CE, 0xE4E4, - 0x72D0, 0xFBCF, 0x72D7, 0xCFB7, 0x72D9, 0xEEC3, 0x72E1, 0xCEEA, 0x72E9, 0xE2AD, 0x72F8, 0xD7E1, 0x72F9, 0xFAF5, 0x72FC, 0xD5C9, - 0x72FD, 0xF8AC, 0x730A, 0xE7D9, 0x7316, 0xF3E9, 0x731B, 0xD8ED, 0x731C, 0xE3C4, 0x731D, 0xF0F1, 0x7325, 0xE8E5, 0x7329, 0xE0FA, - 0x732A, 0xEEC4, 0x732B, 0xD9DE, 0x7336, 0xEBA2, 0x7337, 0xEBA3, 0x733E, 0xFCC2, 0x733F, 0xEABB, 0x7344, 0xE8AB, 0x7345, 0xDEE2, - 0x7350, 0xEDEF, 0x7352, 0xE8A3, 0x7357, 0xCFF1, 0x7368, 0xD4BC, 0x736A, 0xFCEA, 0x7370, 0xE7BE, 0x7372, 0xFCF2, 0x7375, 0xD6B4, - 0x7378, 0xE2AE, 0x737A, 0xD3B7, 0x737B, 0xFACC, 0x7384, 0xFADC, 0x7386, 0xEDB5, 0x7387, 0xE1E3, 0x7389, 0xE8AC, 0x738B, 0xE8DD, - 0x738E, 0xEFE9, 0x7394, 0xF4BD, 0x7396, 0xCFB8, 0x7397, 0xE9DB, 0x7398, 0xD1AC, 0x739F, 0xDAC7, 0x73A7, 0xEBC9, 0x73A9, 0xE8CC, - 0x73AD, 0xDEB7, 0x73B2, 0xD6BC, 0x73B3, 0xD3E5, 0x73B9, 0xFADD, 0x73C0, 0xDAD6, 0x73C2, 0xCAB1, 0x73C9, 0xDAC8, 0x73CA, 0xDFA6, - 0x73CC, 0xF9B3, 0x73CD, 0xF2D2, 0x73CF, 0xCAC4, 0x73D6, 0xCECB, 0x73D9, 0xCDF5, 0x73DD, 0xFDB0, 0x73DE, 0xD5A8, 0x73E0, 0xF1C1, - 0x73E3, 0xE2E9, 0x73E4, 0xDCCA, 0x73E5, 0xECB4, 0x73E6, 0xFAC0, 0x73E9, 0xFBA8, 0x73EA, 0xD0A8, 0x73ED, 0xDAEC, 0x73F7, 0xD9EE, - 0x73F9, 0xE0FB, 0x73FD, 0xEFEA, 0x73FE, 0xFADE, 0x7401, 0xE0C4, 0x7403, 0xCFB9, 0x7405, 0xD5CA, 0x7406, 0xD7E2, 0x7407, 0xE2AF, - 0x7409, 0xD7B8, 0x7413, 0xE8CD, 0x741B, 0xF6DA, 0x7420, 0xEFA2, 0x7421, 0xE2DA, 0x7422, 0xF6FC, 0x7425, 0xFBD0, 0x7426, 0xD1AD, - 0x7428, 0xCDE4, 0x742A, 0xD1AE, 0x742B, 0xDCED, 0x742C, 0xE8CE, 0x742E, 0xF0F9, 0x742F, 0xCEB5, 0x7430, 0xE6FC, 0x7433, 0xD7FB, - 0x7434, 0xD0D6, 0x7435, 0xDDF5, 0x7436, 0xF7F1, 0x7438, 0xF6FD, 0x743A, 0xDBF7, 0x743F, 0xFBEA, 0x7440, 0xE9DC, 0x7441, 0xD9C1, - 0x7443, 0xF5F2, 0x7444, 0xE0C5, 0x744B, 0xEAD4, 0x7455, 0xF9C2, 0x7457, 0xEABC, 0x7459, 0xD2C5, 0x745A, 0xFBD1, 0x745B, 0xE7C0, - 0x745C, 0xEBA5, 0x745E, 0xDFFA, 0x745F, 0xE3A2, 0x7460, 0xD7B9, 0x7462, 0xE9C3, 0x7464, 0xE8FD, 0x7465, 0xE8AF, 0x7468, 0xF2D3, - 0x7469, 0xFBA9, 0x746A, 0xD8A5, 0x746F, 0xD5CB, 0x747E, 0xD0C8, 0x7482, 0xD1AF, 0x7483, 0xD7E3, 0x7487, 0xE0C6, 0x7489, 0xD6A2, - 0x748B, 0xEDF0, 0x7498, 0xD7F3, 0x749C, 0xFCD4, 0x749E, 0xDAD7, 0x749F, 0xCCDF, 0x74A1, 0xF2D4, 0x74A3, 0xD1B0, 0x74A5, 0xCCE0, - 0x74A7, 0xDBFD, 0x74A8, 0xF3BF, 0x74AA, 0xF0D1, 0x74B0, 0xFCBB, 0x74B2, 0xE2B0, 0x74B5, 0xE6A5, 0x74B9, 0xE2DB, 0x74BD, 0xDFDE, - 0x74BF, 0xE0C7, 0x74C6, 0xF2EF, 0x74CA, 0xCCE1, 0x74CF, 0xD6EA, 0x74D4, 0xE7C2, 0x74D8, 0xCEB6, 0x74DA, 0xF3C0, 0x74DC, 0xCDFE, - 0x74E0, 0xFBD2, 0x74E2, 0xF8F8, 0x74E3, 0xF7FB, 0x74E6, 0xE8BF, 0x74EE, 0xE8B7, 0x74F7, 0xEDB6, 0x7501, 0xDCBA, 0x7504, 0xCCB4, - 0x7511, 0xF1F7, 0x7515, 0xE8B8, 0x7518, 0xCAF6, 0x751A, 0xE4A4, 0x751B, 0xF4D6, 0x751F, 0xDFE6, 0x7523, 0xDFA7, 0x7525, 0xDFE7, - 0x7526, 0xE1C1, 0x7528, 0xE9C4, 0x752B, 0xDCCB, 0x752C, 0xE9C5, 0x7530, 0xEFA3, 0x7531, 0xEBA6, 0x7532, 0xCBA3, 0x7533, 0xE3E9, - 0x7537, 0xD1FB, 0x7538, 0xEFA4, 0x753A, 0xEFEB, 0x7547, 0xD0B4, 0x754C, 0xCDA3, 0x754F, 0xE8E6, 0x7551, 0xEFA5, 0x7553, 0xD3CC, - 0x7554, 0xDAED, 0x7559, 0xD7BA, 0x755B, 0xF2D5, 0x755C, 0xF5E5, 0x755D, 0xD9EF, 0x7562, 0xF9B4, 0x7565, 0xD5D4, 0x7566, 0xFDCF, - 0x756A, 0xDBE3, 0x756F, 0xF1E1, 0x7570, 0xECB6, 0x7575, 0xFBFE, 0x7576, 0xD3D7, 0x7578, 0xD1B1, 0x757A, 0xCBB1, 0x757F, 0xD1B2, - 0x7586, 0xCBB2, 0x7587, 0xF1C2, 0x758A, 0xF4E1, 0x758B, 0xF9B5, 0x758E, 0xE1C3, 0x758F, 0xE1C2, 0x7591, 0xEBF7, 0x759D, 0xDFA8, - 0x75A5, 0xCBCA, 0x75AB, 0xE6B9, 0x75B1, 0xF8DE, 0x75B2, 0xF9AA, 0x75B3, 0xCAF7, 0x75B5, 0xEDB7, 0x75B8, 0xD3B8, 0x75B9, 0xF2D6, - 0x75BC, 0xD4D9, 0x75BD, 0xEEC5, 0x75BE, 0xF2F0, 0x75C2, 0xCAB2, 0x75C5, 0xDCBB, 0x75C7, 0xF1F8, 0x75CD, 0xECB7, 0x75D2, 0xE5CA, - 0x75D4, 0xF6C0, 0x75D5, 0xFDDD, 0x75D8, 0xD4E3, 0x75D9, 0xCCE2, 0x75DB, 0xF7D4, 0x75E2, 0xD7E5, 0x75F0, 0xD3C3, 0x75F2, 0xD8A6, - 0x75F4, 0xF6C1, 0x75FA, 0xDDF6, 0x75FC, 0xCDC0, 0x7600, 0xE5DC, 0x760D, 0xE5CB, 0x7619, 0xE1C4, 0x761F, 0xE8B0, 0x7620, 0xF4B0, - 0x7621, 0xF3EA, 0x7622, 0xDAEE, 0x7624, 0xD7BB, 0x7626, 0xE2B1, 0x763B, 0xD7AA, 0x7642, 0xD6FB, 0x764C, 0xE4DF, 0x764E, 0xCAD6, - 0x7652, 0xEBA8, 0x7656, 0xDBFE, 0x7661, 0xF6C2, 0x7664, 0xEFBB, 0x7669, 0xD4FD, 0x766C, 0xE0C8, 0x7670, 0xE8B9, 0x7672, 0xEFA6, - 0x7678, 0xCDA4, 0x767B, 0xD4F4, 0x767C, 0xDBA1, 0x767D, 0xDBDC, 0x767E, 0xDBDD, 0x7684, 0xEEDC, 0x7686, 0xCBCB, 0x7687, 0xFCD5, - 0x768E, 0xCEEB, 0x7690, 0xCDC1, 0x7693, 0xFBD3, 0x76AE, 0xF9AB, 0x76BA, 0xF5D4, 0x76BF, 0xD9A9, 0x76C2, 0xE9DD, 0x76C3, 0xDBCD, - 0x76C6, 0xDDCE, 0x76C8, 0xE7C3, 0x76CA, 0xECCC, 0x76D2, 0xF9EC, 0x76D6, 0xCBCC, 0x76DB, 0xE0FC, 0x76DC, 0xD4A8, 0x76DE, 0xEDD3, - 0x76DF, 0xD8EF, 0x76E1, 0xF2D7, 0x76E3, 0xCAF8, 0x76E4, 0xDAEF, 0x76E7, 0xD6D4, 0x76EE, 0xD9CD, 0x76F2, 0xD8EE, 0x76F4, 0xF2C1, - 0x76F8, 0xDFD3, 0x76FC, 0xDAF0, 0x76FE, 0xE2EA, 0x7701, 0xE0FD, 0x7704, 0xD8F8, 0x7708, 0xF7AF, 0x7709, 0xDAB6, 0x770B, 0xCAD7, - 0x771E, 0xF2D8, 0x7720, 0xD8F9, 0x7729, 0xFADF, 0x7737, 0xCFEF, 0x7738, 0xD9C2, 0x773A, 0xF0D2, 0x773C, 0xE4D1, 0x7740, 0xF3B7, - 0x774D, 0xFAE0, 0x775B, 0xEFEC, 0x7761, 0xE2B2, 0x7763, 0xD4BD, 0x7766, 0xD9CE, 0x776B, 0xF4E2, 0x7779, 0xD4A9, 0x777E, 0xCDC2, - 0x777F, 0xE7DA, 0x778B, 0xF2D9, 0x7791, 0xD9AA, 0x779E, 0xD8BE, 0x77A5, 0xDCAD, 0x77AC, 0xE2EB, 0x77AD, 0xD6FC, 0x77B0, 0xCAF9, - 0x77B3, 0xD4DA, 0x77BB, 0xF4D7, 0x77BC, 0xCCA1, 0x77BF, 0xCFBA, 0x77D7, 0xF5B8, 0x77DB, 0xD9C3, 0x77DC, 0xD0E8, 0x77E2, 0xE3C5, - 0x77E3, 0xEBF8, 0x77E5, 0xF2B1, 0x77E9, 0xCFBB, 0x77ED, 0xD3AD, 0x77EE, 0xE8E1, 0x77EF, 0xCEEC, 0x77F3, 0xE0B4, 0x7802, 0xDEE3, - 0x7812, 0xDDF7, 0x7825, 0xF2B2, 0x7826, 0xF3F6, 0x7827, 0xF6DB, 0x782C, 0xD7FE, 0x7832, 0xF8DF, 0x7834, 0xF7F2, 0x7845, 0xD0A9, - 0x784F, 0xE6DA, 0x785D, 0xF5A6, 0x786B, 0xD7BC, 0x786C, 0xCCE3, 0x786F, 0xE6DB, 0x787C, 0xDDDD, 0x7881, 0xD1B3, 0x7887, 0xEFED, - 0x788C, 0xD6DE, 0x788D, 0xE4F4, 0x788E, 0xE1EF, 0x7891, 0xDDF8, 0x7897, 0xE8CF, 0x78A3, 0xCAE5, 0x78A7, 0xDCA1, 0x78A9, 0xE0B5, - 0x78BA, 0xFCAC, 0x78BB, 0xFCAD, 0x78BC, 0xD8A7, 0x78C1, 0xEDB8, 0x78C5, 0xDBB6, 0x78CA, 0xD6F0, 0x78CB, 0xF3AF, 0x78CE, 0xCDA5, - 0x78D0, 0xDAF1, 0x78E8, 0xD8A8, 0x78EC, 0xCCE4, 0x78EF, 0xD1B4, 0x78F5, 0xCAD8, 0x78FB, 0xDAF2, 0x7901, 0xF5A7, 0x790E, 0xF5A8, - 0x7916, 0xE6A6, 0x792A, 0xD5EC, 0x792B, 0xD5F8, 0x792C, 0xDAF3, 0x793A, 0xE3C6, 0x793E, 0xDEE4, 0x7940, 0xDEE5, 0x7941, 0xD1B5, - 0x7947, 0xD1B6, 0x7948, 0xD1B7, 0x7949, 0xF2B3, 0x7950, 0xE9DE, 0x7956, 0xF0D3, 0x7957, 0xF2B4, 0x795A, 0xF0D4, 0x795B, 0xCBE4, - 0x795C, 0xFBD4, 0x795D, 0xF5E6, 0x795E, 0xE3EA, 0x7960, 0xDEE6, 0x7965, 0xDFD4, 0x7968, 0xF8F9, 0x796D, 0xF0AE, 0x797A, 0xD1B8, - 0x797F, 0xD6DF, 0x7981, 0xD0D7, 0x798D, 0xFCA1, 0x798E, 0xEFEE, 0x798F, 0xDCD8, 0x7991, 0xE9DF, 0x79A6, 0xE5DD, 0x79A7, 0xFDFB, - 0x79AA, 0xE0C9, 0x79AE, 0xD6C9, 0x79B1, 0xD4AA, 0x79B3, 0xE5CC, 0x79B9, 0xE9E0, 0x79BD, 0xD0D8, 0x79BE, 0xFCA2, 0x79BF, 0xD4BE, - 0x79C0, 0xE2B3, 0x79C1, 0xDEE7, 0x79C9, 0xDCBC, 0x79CA, 0xD2B6, 0x79CB, 0xF5D5, 0x79D1, 0xCEA1, 0x79D2, 0xF5A9, 0x79D5, 0xDDF9, - 0x79D8, 0xDDFA, 0x79DF, 0xF0D5, 0x79E4, 0xF6DF, 0x79E6, 0xF2DA, 0x79E7, 0xE4EB, 0x79E9, 0xF2F1, 0x79FB, 0xECB9, 0x7A00, 0xFDFC, - 0x7A05, 0xE1AA, 0x7A08, 0xCAD9, 0x7A0B, 0xEFEF, 0x7A0D, 0xF5AA, 0x7A14, 0xECF9, 0x7A17, 0xF8AD, 0x7A19, 0xF2C2, 0x7A1A, 0xF6C3, - 0x7A1C, 0xD7D2, 0x7A1F, 0xF9A2, 0x7A20, 0xF0D6, 0x7A2E, 0xF0FA, 0x7A31, 0xF6E0, 0x7A36, 0xE9F3, 0x7A37, 0xF2C3, 0x7A3B, 0xD4AB, - 0x7A3C, 0xCAB3, 0x7A3D, 0xCDA6, 0x7A3F, 0xCDC3, 0x7A40, 0xCDDA, 0x7A46, 0xD9CF, 0x7A49, 0xF6C4, 0x7A4D, 0xEEDD, 0x7A4E, 0xE7C4, - 0x7A57, 0xE2B4, 0x7A61, 0xDFE2, 0x7A62, 0xE7DB, 0x7A69, 0xE8B1, 0x7A6B, 0xFCAE, 0x7A70, 0xE5CD, 0x7A74, 0xFAEB, 0x7A76, 0xCFBC, - 0x7A79, 0xCFE2, 0x7A7A, 0xCDF6, 0x7A7D, 0xEFF0, 0x7A7F, 0xF4BE, 0x7A81, 0xD4CD, 0x7A84, 0xF3B8, 0x7A88, 0xE9A1, 0x7A92, 0xF2F2, - 0x7A93, 0xF3EB, 0x7A95, 0xF0D7, 0x7A98, 0xCFD7, 0x7A9F, 0xCFDF, 0x7AA9, 0xE8C0, 0x7AAA, 0xE8C1, 0x7AAE, 0xCFE3, 0x7AAF, 0xE9A2, - 0x7ABA, 0xD0AA, 0x7AC4, 0xF3C1, 0x7AC5, 0xD0AB, 0x7AC7, 0xD4E4, 0x7ACA, 0xEFBC, 0x7ACB, 0xD8A1, 0x7AD7, 0xD9DF, 0x7AD9, 0xF3D7, - 0x7ADD, 0xDCBD, 0x7ADF, 0xCCE5, 0x7AE0, 0xEDF1, 0x7AE3, 0xF1E2, 0x7AE5, 0xD4DB, 0x7AEA, 0xE2B5, 0x7AED, 0xCAE6, 0x7AEF, 0xD3AE, - 0x7AF6, 0xCCE6, 0x7AF9, 0xF1D3, 0x7AFA, 0xF5E7, 0x7AFF, 0xCADA, 0x7B0F, 0xFBEE, 0x7B11, 0xE1C5, 0x7B19, 0xDFE9, 0x7B1B, 0xEEDE, - 0x7B1E, 0xF7C2, 0x7B20, 0xD8A2, 0x7B26, 0xDDAC, 0x7B2C, 0xF0AF, 0x7B2D, 0xD6BD, 0x7B39, 0xE1AB, 0x7B46, 0xF9B6, 0x7B49, 0xD4F5, - 0x7B4B, 0xD0C9, 0x7B4C, 0xEFA7, 0x7B4D, 0xE2EC, 0x7B4F, 0xDBEA, 0x7B50, 0xCECC, 0x7B51, 0xF5E8, 0x7B52, 0xF7D5, 0x7B54, 0xD3CD, - 0x7B56, 0xF3FE, 0x7B60, 0xD0B5, 0x7B6C, 0xE0FE, 0x7B6E, 0xDFFB, 0x7B75, 0xE6DD, 0x7B7D, 0xE8A4, 0x7B87, 0xCBCD, 0x7B8B, 0xEFA8, - 0x7B8F, 0xEEB4, 0x7B94, 0xDAD8, 0x7B95, 0xD1B9, 0x7B97, 0xDFA9, 0x7B9A, 0xF3B0, 0x7B9D, 0xCCC4, 0x7BA1, 0xCEB7, 0x7BAD, 0xEFA9, - 0x7BB1, 0xDFD5, 0x7BB4, 0xEDD7, 0x7BB8, 0xEEC6, 0x7BC0, 0xEFBD, 0x7BC1, 0xFCD6, 0x7BC4, 0xDBF4, 0x7BC6, 0xEFAA, 0x7BC7, 0xF8B9, - 0x7BC9, 0xF5E9, 0x7BD2, 0xE3D9, 0x7BE0, 0xE1C6, 0x7BE4, 0xD4BF, 0x7BE9, 0xDEE8, 0x7C07, 0xF0EA, 0x7C12, 0xF3C2, 0x7C1E, 0xD3AF, - 0x7C21, 0xCADB, 0x7C27, 0xFCD7, 0x7C2A, 0xEDD8, 0x7C2B, 0xE1C7, 0x7C3D, 0xF4D8, 0x7C3E, 0xD6B3, 0x7C3F, 0xDDAD, 0x7C43, 0xD5BE, - 0x7C4C, 0xF1C3, 0x7C4D, 0xEEDF, 0x7C60, 0xD6EB, 0x7C64, 0xF4D9, 0x7C6C, 0xD7E6, 0x7C73, 0xDAB7, 0x7C83, 0xDDFB, 0x7C89, 0xDDCF, - 0x7C92, 0xD8A3, 0x7C95, 0xDAD9, 0x7C97, 0xF0D8, 0x7C98, 0xEFC4, 0x7C9F, 0xE1D8, 0x7CA5, 0xF1D4, 0x7CA7, 0xEDF2, 0x7CAE, 0xD5DB, - 0x7CB1, 0xD5DC, 0x7CB2, 0xF3C4, 0x7CB3, 0xCBD7, 0x7CB9, 0xE2B6, 0x7CBE, 0xEFF1, 0x7CCA, 0xFBD5, 0x7CD6, 0xD3D8, 0x7CDE, 0xDDD0, - 0x7CDF, 0xF0D9, 0x7CE0, 0xCBB3, 0x7CE7, 0xD5DD, 0x7CFB, 0xCDA7, 0x7CFE, 0xD0AC, 0x7D00, 0xD1BA, 0x7D02, 0xF1C4, 0x7D04, 0xE5B3, - 0x7D05, 0xFBF5, 0x7D06, 0xE9E1, 0x7D07, 0xFDE0, 0x7D08, 0xFCBC, 0x7D0A, 0xDAA2, 0x7D0B, 0xDAA3, 0x7D0D, 0xD2A1, 0x7D10, 0xD2EF, - 0x7D14, 0xE2ED, 0x7D17, 0xDEE9, 0x7D18, 0xCEDC, 0x7D19, 0xF2B5, 0x7D1A, 0xD0E4, 0x7D1B, 0xDDD1, 0x7D20, 0xE1C8, 0x7D21, 0xDBB7, - 0x7D22, 0xDFE3, 0x7D2B, 0xEDB9, 0x7D2C, 0xF1C5, 0x7D2E, 0xF3CF, 0x7D2F, 0xD7AB, 0x7D30, 0xE1AC, 0x7D33, 0xE3EB, 0x7D35, 0xEEC7, - 0x7D39, 0xE1C9, 0x7D3A, 0xCAFA, 0x7D42, 0xF0FB, 0x7D43, 0xFAE1, 0x7D44, 0xF0DA, 0x7D45, 0xCCE7, 0x7D46, 0xDAF4, 0x7D50, 0xCCBF, - 0x7D5E, 0xCEED, 0x7D61, 0xD5A9, 0x7D62, 0xFAE2, 0x7D66, 0xD0E5, 0x7D68, 0xEBD6, 0x7D6A, 0xECDF, 0x7D6E, 0xDFFC, 0x7D71, 0xF7D6, - 0x7D72, 0xDEEA, 0x7D73, 0xCBB4, 0x7D76, 0xEFBE, 0x7D79, 0xCCB5, 0x7D7F, 0xCFBD, 0x7D8E, 0xEFF2, 0x7D8F, 0xE2B7, 0x7D93, 0xCCE8, - 0x7D9C, 0xF0FC, 0x7DA0, 0xD6E0, 0x7DA2, 0xF1C6, 0x7DAC, 0xE2B8, 0x7DAD, 0xEBAB, 0x7DB1, 0xCBB5, 0x7DB2, 0xD8D1, 0x7DB4, 0xF4CE, - 0x7DB5, 0xF3F7, 0x7DB8, 0xD7C6, 0x7DBA, 0xD1BB, 0x7DBB, 0xF7AA, 0x7DBD, 0xEDCA, 0x7DBE, 0xD7D3, 0x7DBF, 0xD8FA, 0x7DC7, 0xF6C5, - 0x7DCA, 0xD1CC, 0x7DCB, 0xDDFC, 0x7DD6, 0xDFFD, 0x7DD8, 0xF9E5, 0x7DDA, 0xE0CA, 0x7DDD, 0xF2FD, 0x7DDE, 0xD3B0, 0x7DE0, 0xF4F3, - 0x7DE1, 0xDAC9, 0x7DE3, 0xE6DE, 0x7DE8, 0xF8BA, 0x7DE9, 0xE8D0, 0x7DEC, 0xD8FB, 0x7DEF, 0xEAD5, 0x7DF4, 0xD6A3, 0x7DFB, 0xF6C6, - 0x7E09, 0xF2DB, 0x7E0A, 0xE4FC, 0x7E15, 0xE8B2, 0x7E1B, 0xDADA, 0x7E1D, 0xF2DC, 0x7E1E, 0xFBD6, 0x7E1F, 0xE9B2, 0x7E21, 0xEEAD, - 0x7E23, 0xFAE3, 0x7E2B, 0xDCEE, 0x7E2E, 0xF5EA, 0x7E2F, 0xE6E0, 0x7E31, 0xF0FD, 0x7E37, 0xD7AC, 0x7E3D, 0xF5C5, 0x7E3E, 0xEEE0, - 0x7E41, 0xDBE5, 0x7E43, 0xDDDE, 0x7E46, 0xD9F0, 0x7E47, 0xE9A3, 0x7E52, 0xF1F9, 0x7E54, 0xF2C4, 0x7E55, 0xE0CB, 0x7E5E, 0xE9A4, - 0x7E61, 0xE2B9, 0x7E69, 0xE3B1, 0x7E6A, 0xFCEB, 0x7E6B, 0xCDA8, 0x7E6D, 0xCCB6, 0x7E70, 0xF0DB, 0x7E79, 0xE6BA, 0x7E7C, 0xCDA9, - 0x7E82, 0xF3C3, 0x7E8C, 0xE1D9, 0x7E8F, 0xEFAB, 0x7E93, 0xE7C5, 0x7E96, 0xE0E9, 0x7E98, 0xF3C5, 0x7E9B, 0xD4C0, 0x7E9C, 0xD5BF, - 0x7F36, 0xDDAE, 0x7F38, 0xF9FC, 0x7F3A, 0xCCC0, 0x7F4C, 0xE5A2, 0x7F50, 0xCEB8, 0x7F54, 0xD8D2, 0x7F55, 0xF9D6, 0x7F6A, 0xF1AA, - 0x7F6B, 0xCED1, 0x7F6E, 0xF6C7, 0x7F70, 0xDBEB, 0x7F72, 0xDFFE, 0x7F75, 0xD8E1, 0x7F77, 0xF7F3, 0x7F79, 0xD7E7, 0x7F85, 0xD4FE, - 0x7F88, 0xD1BC, 0x7F8A, 0xE5CF, 0x7F8C, 0xCBB6, 0x7F8E, 0xDAB8, 0x7F94, 0xCDC4, 0x7F9A, 0xD6BE, 0x7F9E, 0xE2BA, 0x7FA4, 0xCFD8, - 0x7FA8, 0xE0CC, 0x7FA9, 0xEBF9, 0x7FB2, 0xFDFD, 0x7FB8, 0xD7E8, 0x7FB9, 0xCBD8, 0x7FBD, 0xE9E2, 0x7FC1, 0xE8BA, 0x7FC5, 0xE3C7, - 0x7FCA, 0xECCD, 0x7FCC, 0xECCE, 0x7FCE, 0xD6BF, 0x7FD2, 0xE3A7, 0x7FD4, 0xDFD6, 0x7FD5, 0xFDE8, 0x7FDF, 0xEEE1, 0x7FE0, 0xF6A8, - 0x7FE1, 0xDDFD, 0x7FE9, 0xF8BB, 0x7FEB, 0xE8D1, 0x7FF0, 0xF9D7, 0x7FF9, 0xCEEE, 0x7FFC, 0xECCF, 0x8000, 0xE9A5, 0x8001, 0xD6D5, - 0x8003, 0xCDC5, 0x8005, 0xEDBA, 0x8006, 0xD1BD, 0x8009, 0xCFBE, 0x800C, 0xECBB, 0x8010, 0xD2B1, 0x8015, 0xCCE9, 0x8017, 0xD9C4, - 0x8018, 0xE9FC, 0x802D, 0xD1BE, 0x8033, 0xECBC, 0x8036, 0xE5AD, 0x803D, 0xF7B0, 0x803F, 0xCCEA, 0x8043, 0xD3C4, 0x8046, 0xD6C0, - 0x804A, 0xD6FD, 0x8056, 0xE1A1, 0x8058, 0xDEBD, 0x805A, 0xF6A9, 0x805E, 0xDAA4, 0x806F, 0xD6A4, 0x8070, 0xF5C6, 0x8072, 0xE1A2, - 0x8073, 0xE9C6, 0x8077, 0xF2C5, 0x807D, 0xF4E9, 0x807E, 0xD6EC, 0x807F, 0xEBD3, 0x8084, 0xECBD, 0x8085, 0xE2DC, 0x8086, 0xDEEB, - 0x8087, 0xF0DC, 0x8089, 0xEBBF, 0x808B, 0xD7CE, 0x808C, 0xD1BF, 0x8096, 0xF5AB, 0x809B, 0xF9FD, 0x809D, 0xCADC, 0x80A1, 0xCDC6, - 0x80A2, 0xF2B6, 0x80A5, 0xDDFE, 0x80A9, 0xCCB7, 0x80AA, 0xDBB8, 0x80AF, 0xD0E9, 0x80B1, 0xCEDD, 0x80B2, 0xEBC0, 0x80B4, 0xFDA2, - 0x80BA, 0xF8CB, 0x80C3, 0xEAD6, 0x80C4, 0xF1B0, 0x80CC, 0xDBCE, 0x80CE, 0xF7C3, 0x80DA, 0xDBCF, 0x80DB, 0xCBA4, 0x80DE, 0xF8E0, - 0x80E1, 0xFBD7, 0x80E4, 0xEBCA, 0x80E5, 0xE0A1, 0x80F1, 0xCECD, 0x80F4, 0xD4DC, 0x80F8, 0xFDD8, 0x80FD, 0xD2F6, 0x8102, 0xF2B7, - 0x8105, 0xFAF6, 0x8106, 0xF6AA, 0x8107, 0xFAF7, 0x8108, 0xD8E6, 0x810A, 0xF4B1, 0x8118, 0xE8D2, 0x811A, 0xCAC5, 0x811B, 0xCCEB, - 0x8123, 0xE2EE, 0x8129, 0xE2BB, 0x812B, 0xF7AD, 0x812F, 0xF8E1, 0x8139, 0xF3EC, 0x813E, 0xDEA1, 0x814B, 0xE4FD, 0x814E, 0xE3EC, - 0x8150, 0xDDAF, 0x8151, 0xDDB0, 0x8154, 0xCBB7, 0x8155, 0xE8D3, 0x8165, 0xE1A3, 0x8166, 0xD2E0, 0x816B, 0xF0FE, 0x8170, 0xE9A6, - 0x8171, 0xCBF2, 0x8178, 0xEDF3, 0x8179, 0xDCD9, 0x817A, 0xE0CD, 0x817F, 0xF7DA, 0x8180, 0xDBB9, 0x8188, 0xCCAE, 0x818A, 0xDADB, - 0x818F, 0xCDC7, 0x819A, 0xDDB1, 0x819C, 0xD8AF, 0x819D, 0xE3A3, 0x81A0, 0xCEEF, 0x81A3, 0xF2F3, 0x81A8, 0xF8B3, 0x81B3, 0xE0CE, - 0x81B5, 0xF5FD, 0x81BA, 0xEBEC, 0x81BD, 0xD3C5, 0x81BE, 0xFCEC, 0x81BF, 0xD2DB, 0x81C0, 0xD4EB, 0x81C2, 0xDEA2, 0x81C6, 0xE5E6, - 0x81CD, 0xF0B0, 0x81D8, 0xD5C4, 0x81DF, 0xEDF4, 0x81E3, 0xE3ED, 0x81E5, 0xE8C2, 0x81E7, 0xEDF5, 0x81E8, 0xD7FC, 0x81EA, 0xEDBB, - 0x81ED, 0xF6AB, 0x81F3, 0xF2B8, 0x81F4, 0xF6C8, 0x81FA, 0xD3E6, 0x81FB, 0xF2DD, 0x81FC, 0xCFBF, 0x81FE, 0xEBAC, 0x8205, 0xCFC0, - 0x8207, 0xE6A8, 0x8208, 0xFDE9, 0x820A, 0xCFC1, 0x820C, 0xE0DF, 0x820D, 0xDEEC, 0x8212, 0xE0A2, 0x821B, 0xF4BF, 0x821C, 0xE2EF, - 0x821E, 0xD9F1, 0x821F, 0xF1C7, 0x8221, 0xCBB8, 0x822A, 0xF9FE, 0x822B, 0xDBBA, 0x822C, 0xDAF5, 0x8235, 0xF6EC, 0x8236, 0xDADC, - 0x8237, 0xFAE4, 0x8239, 0xE0CF, 0x8240, 0xDDB2, 0x8245, 0xE6A9, 0x8247, 0xEFF3, 0x8259, 0xF3ED, 0x8264, 0xEBFA, 0x8266, 0xF9E6, - 0x826E, 0xCADD, 0x826F, 0xD5DE, 0x8271, 0xCADE, 0x8272, 0xDFE4, 0x8276, 0xE6FD, 0x8278, 0xF5AC, 0x827E, 0xE4F5, 0x828B, 0xE9E3, - 0x828D, 0xEDCB, 0x828E, 0xCFE4, 0x8292, 0xD8D3, 0x8299, 0xDDB3, 0x829A, 0xD4EC, 0x829D, 0xF2B9, 0x829F, 0xDFB7, 0x82A5, 0xCBCE, - 0x82A6, 0xFBD8, 0x82A9, 0xD0D9, 0x82AC, 0xDDD2, 0x82AD, 0xF7F4, 0x82AE, 0xE7DC, 0x82AF, 0xE4A5, 0x82B1, 0xFCA3, 0x82B3, 0xDBBB, - 0x82B7, 0xF2BA, 0x82B8, 0xE9FD, 0x82B9, 0xD0CA, 0x82BB, 0xF5D6, 0x82BC, 0xD9C5, 0x82BD, 0xE4B4, 0x82BF, 0xEDA7, 0x82D1, 0xEABD, - 0x82D2, 0xE6FE, 0x82D4, 0xF7C4, 0x82D5, 0xF5AD, 0x82D7, 0xD9E0, 0x82DB, 0xCAB4, 0x82DE, 0xF8E2, 0x82DF, 0xCFC2, 0x82E1, 0xECBE, - 0x82E5, 0xE5B4, 0x82E6, 0xCDC8, 0x82E7, 0xEEC8, 0x82F1, 0xE7C8, 0x82FD, 0xCDC9, 0x82FE, 0xF9B7, 0x8301, 0xF1E8, 0x8302, 0xD9F2, - 0x8303, 0xDBF5, 0x8304, 0xCAB5, 0x8305, 0xD9C6, 0x8309, 0xD8C9, 0x8317, 0xD9AB, 0x8328, 0xEDBC, 0x832B, 0xD8D4, 0x832F, 0xDCDA, - 0x8331, 0xE2BC, 0x8334, 0xFCED, 0x8335, 0xECE0, 0x8336, 0xD2FE, 0x8338, 0xE9C7, 0x8339, 0xE6AA, 0x8340, 0xE2F0, 0x8347, 0xFABB, - 0x8349, 0xF5AE, 0x834A, 0xFBAA, 0x834F, 0xECFB, 0x8351, 0xECBF, 0x8352, 0xFCD8, 0x8373, 0xD4E5, 0x8377, 0xF9C3, 0x837B, 0xEEE2, - 0x8389, 0xD7E9, 0x838A, 0xEDF6, 0x838E, 0xDEED, 0x8396, 0xCCEC, 0x8398, 0xE3EE, 0x839E, 0xE8D4, 0x83A2, 0xFAF8, 0x83A9, 0xDDB4, - 0x83AA, 0xE4B5, 0x83AB, 0xD8B0, 0x83BD, 0xD8D5, 0x83C1, 0xF4EA, 0x83C5, 0xCEB9, 0x83C9, 0xD6E1, 0x83CA, 0xCFD2, 0x83CC, 0xD0B6, - 0x83D3, 0xCEA2, 0x83D6, 0xF3EE, 0x83DC, 0xF3F8, 0x83E9, 0xDCCC, 0x83EB, 0xD0CB, 0x83EF, 0xFCA4, 0x83F0, 0xCDCA, 0x83F1, 0xD7D4, - 0x83F2, 0xDEA3, 0x83F4, 0xE4E0, 0x83F9, 0xEEC9, 0x83FD, 0xE2DD, 0x8403, 0xF5FE, 0x8404, 0xD4AC, 0x840A, 0xD5D1, 0x840C, 0xD8F0, - 0x840D, 0xF8C3, 0x840E, 0xEAD7, 0x8429, 0xF5D7, 0x842C, 0xD8BF, 0x8431, 0xFDC0, 0x8438, 0xEBAD, 0x843D, 0xD5AA, 0x8449, 0xE7A8, - 0x8457, 0xEECA, 0x845B, 0xCAE7, 0x8461, 0xF8E3, 0x8463, 0xD4DD, 0x8466, 0xEAD8, 0x846B, 0xFBD9, 0x846C, 0xEDF7, 0x846F, 0xE5B5, - 0x8475, 0xD0AD, 0x847A, 0xF1F1, 0x8490, 0xE2BD, 0x8494, 0xE3C8, 0x8499, 0xD9D5, 0x849C, 0xDFAA, 0x84A1, 0xDBBC, 0x84B2, 0xF8E4, - 0x84B8, 0xF1FA, 0x84BB, 0xE5B6, 0x84BC, 0xF3EF, 0x84BF, 0xFBDA, 0x84C0, 0xE1E0, 0x84C2, 0xD9AC, 0x84C4, 0xF5EB, 0x84C6, 0xE0B6, - 0x84C9, 0xE9C8, 0x84CB, 0xCBCF, 0x84CD, 0xE3C9, 0x84D1, 0xDEEE, 0x84DA, 0xE2BE, 0x84EC, 0xDCEF, 0x84EE, 0xD6A5, 0x84F4, 0xE2F1, - 0x84FC, 0xD6FE, 0x8511, 0xD9A1, 0x8513, 0xD8C0, 0x8514, 0xDCDB, 0x8517, 0xEDBD, 0x8518, 0xDFB8, 0x851A, 0xEAA5, 0x851E, 0xD7AD, - 0x8521, 0xF3F9, 0x8523, 0xEDF8, 0x8525, 0xF5C7, 0x852C, 0xE1CA, 0x852D, 0xEBE3, 0x852F, 0xF2DE, 0x853D, 0xF8CC, 0x853F, 0xEAD9, - 0x8541, 0xD3C6, 0x8543, 0xDBE6, 0x8549, 0xF5AF, 0x854E, 0xCEF0, 0x8553, 0xE9FE, 0x8559, 0xFBB6, 0x8563, 0xE2F2, 0x8568, 0xCFF2, - 0x8569, 0xF7B9, 0x856A, 0xD9F3, 0x856D, 0xE1CB, 0x8584, 0xDADD, 0x8587, 0xDAB9, 0x858F, 0xEBFB, 0x8591, 0xCBB9, 0x8594, 0xEDF9, - 0x859B, 0xE0E0, 0x85A6, 0xF4C0, 0x85A8, 0xFDBC, 0x85A9, 0xDFB1, 0x85AA, 0xE3EF, 0x85AF, 0xE0A3, 0x85B0, 0xFDB9, 0x85BA, 0xF0B1, - 0x85C1, 0xCDCB, 0x85C9, 0xEDBE, 0x85CD, 0xD5C0, 0x85CE, 0xE3F0, 0x85CF, 0xEDFA, 0x85D5, 0xE9E4, 0x85DC, 0xD5ED, 0x85DD, 0xE7DD, - 0x85E4, 0xD4F6, 0x85E5, 0xE5B7, 0x85E9, 0xDBE7, 0x85EA, 0xE2BF, 0x85F7, 0xEECB, 0x85FA, 0xD7F4, 0x85FB, 0xF0DD, 0x85FF, 0xCEAB, - 0x8602, 0xE7DE, 0x8606, 0xD6D6, 0x8607, 0xE1CC, 0x860A, 0xE8B3, 0x8616, 0xE5EE, 0x8617, 0xDCA2, 0x861A, 0xE0D0, 0x862D, 0xD5B5, - 0x863F, 0xD5A1, 0x864E, 0xFBDB, 0x8650, 0xF9CB, 0x8654, 0xCBF3, 0x8655, 0xF4A5, 0x865B, 0xFAC8, 0x865C, 0xD6D7, 0x865E, 0xE9E5, - 0x865F, 0xFBDC, 0x8667, 0xFDD0, 0x8679, 0xFBF6, 0x868A, 0xDAA5, 0x868C, 0xDBBD, 0x8693, 0xECE2, 0x86A3, 0xCDF7, 0x86A4, 0xF0DE, - 0x86A9, 0xF6C9, 0x86C7, 0xDEEF, 0x86CB, 0xD3B1, 0x86D4, 0xFCEE, 0x86D9, 0xE8C3, 0x86DB, 0xF1C8, 0x86DF, 0xCEF1, 0x86E4, 0xF9ED, - 0x86ED, 0xF2F4, 0x86FE, 0xE4B6, 0x8700, 0xF5B9, 0x8702, 0xDCF0, 0x8703, 0xE3F1, 0x8708, 0xE8A5, 0x8718, 0xF2BB, 0x871A, 0xDEA4, - 0x871C, 0xDACC, 0x874E, 0xCAE9, 0x8755, 0xE3DA, 0x8757, 0xFCD9, 0x875F, 0xEADA, 0x8766, 0xF9C4, 0x8768, 0xE3A4, 0x8774, 0xFBDD, - 0x8776, 0xEFCA, 0x8778, 0xE8C4, 0x8782, 0xD5CC, 0x878D, 0xEBD7, 0x879F, 0xD9AD, 0x87A2, 0xFBAB, 0x87B3, 0xD3D9, 0x87BA, 0xD5A2, - 0x87C4, 0xF6DE, 0x87E0, 0xDAF6, 0x87EC, 0xE0D1, 0x87EF, 0xE9A8, 0x87F2, 0xF5F9, 0x87F9, 0xFAAF, 0x87FB, 0xEBFC, 0x87FE, 0xE0EA, - 0x8805, 0xE3B2, 0x881F, 0xD5C5, 0x8822, 0xF1E3, 0x8823, 0xD5EE, 0x8831, 0xCDCC, 0x8836, 0xEDD9, 0x883B, 0xD8C1, 0x8840, 0xFAEC, - 0x8846, 0xF1EB, 0x884C, 0xFABC, 0x884D, 0xE6E2, 0x8852, 0xFAE5, 0x8853, 0xE2FA, 0x8857, 0xCAB6, 0x8859, 0xE4B7, 0x885B, 0xEADB, - 0x885D, 0xF5FA, 0x8861, 0xFBAC, 0x8862, 0xCFC3, 0x8863, 0xEBFD, 0x8868, 0xF8FA, 0x886B, 0xDFB9, 0x8870, 0xE1F1, 0x8872, 0xD2A4, - 0x8877, 0xF5FB, 0x887E, 0xD0DA, 0x887F, 0xD0DB, 0x8881, 0xEABE, 0x8882, 0xD9B1, 0x8888, 0xCAB7, 0x888B, 0xD3E7, 0x888D, 0xF8E5, - 0x8892, 0xD3B2, 0x8896, 0xE2C0, 0x8897, 0xF2DF, 0x889E, 0xCDE5, 0x88AB, 0xF9AC, 0x88B4, 0xCDCD, 0x88C1, 0xEEAE, 0x88C2, 0xD6AE, - 0x88CF, 0xD7EA, 0x88D4, 0xE7E0, 0x88D5, 0xEBAE, 0x88D9, 0xCFD9, 0x88DC, 0xDCCD, 0x88DD, 0xEDFB, 0x88DF, 0xDEF0, 0x88E1, 0xD7EB, - 0x88E8, 0xDEA5, 0x88F3, 0xDFD7, 0x88F4, 0xDBD0, 0x88F5, 0xDBD1, 0x88F8, 0xD5A3, 0x88FD, 0xF0B2, 0x8907, 0xDCDC, 0x8910, 0xCAE8, - 0x8912, 0xF8E6, 0x8913, 0xDCCE, 0x8918, 0xEADC, 0x8919, 0xDBD2, 0x8925, 0xE9B3, 0x892A, 0xF7DB, 0x8936, 0xE3A8, 0x8938, 0xD7AE, - 0x893B, 0xE0E1, 0x8941, 0xCBBA, 0x8944, 0xE5D1, 0x895F, 0xD0DC, 0x8964, 0xD5C1, 0x896A, 0xD8CA, 0x8972, 0xE3A9, 0x897F, 0xE0A4, - 0x8981, 0xE9A9, 0x8983, 0xD3C7, 0x8986, 0xDCDD, 0x8987, 0xF8AE, 0x898B, 0xCCB8, 0x898F, 0xD0AE, 0x8993, 0xD8F2, 0x8996, 0xE3CA, - 0x89A1, 0xCCAF, 0x89A9, 0xD4AD, 0x89AA, 0xF6D1, 0x89B2, 0xD0CC, 0x89BA, 0xCAC6, 0x89BD, 0xD5C2, 0x89C0, 0xCEBA, 0x89D2, 0xCAC7, - 0x89E3, 0xFAB0, 0x89F4, 0xDFD8, 0x89F8, 0xF5BA, 0x8A00, 0xE5EB, 0x8A02, 0xEFF4, 0x8A03, 0xDDB5, 0x8A08, 0xCDAA, 0x8A0A, 0xE3F2, - 0x8A0C, 0xFBF7, 0x8A0E, 0xF7D0, 0x8A13, 0xFDBA, 0x8A16, 0xFDE1, 0x8A17, 0xF6FE, 0x8A18, 0xD1C0, 0x8A1B, 0xE8C5, 0x8A1D, 0xE4B8, - 0x8A1F, 0xE1E8, 0x8A23, 0xCCC1, 0x8A25, 0xD2ED, 0x8A2A, 0xDBBE, 0x8A2D, 0xE0E2, 0x8A31, 0xFAC9, 0x8A34, 0xE1CD, 0x8A36, 0xCAB8, - 0x8A3A, 0xF2E0, 0x8A3B, 0xF1C9, 0x8A50, 0xDEF1, 0x8A54, 0xF0DF, 0x8A55, 0xF8C4, 0x8A5B, 0xEECC, 0x8A5E, 0xDEF2, 0x8A60, 0xE7C9, - 0x8A62, 0xE2F3, 0x8A63, 0xE7E1, 0x8A66, 0xE3CB, 0x8A69, 0xE3CC, 0x8A6D, 0xCFF8, 0x8A6E, 0xEFAC, 0x8A70, 0xFDFE, 0x8A71, 0xFCA5, - 0x8A72, 0xFAB1, 0x8A73, 0xDFD9, 0x8A75, 0xE0D2, 0x8A79, 0xF4DA, 0x8A85, 0xF1CA, 0x8A87, 0xCEA3, 0x8A8C, 0xF2BC, 0x8A8D, 0xECE3, - 0x8A93, 0xE0A5, 0x8A95, 0xF7AB, 0x8A98, 0xEBAF, 0x8A9E, 0xE5DE, 0x8AA0, 0xE1A4, 0x8AA1, 0xCDAB, 0x8AA3, 0xD9F4, 0x8AA4, 0xE8A6, - 0x8AA5, 0xCDCE, 0x8AA6, 0xE1E9, 0x8AA8, 0xFCEF, 0x8AAA, 0xE0E3, 0x8AB0, 0xE2C1, 0x8AB2, 0xCEA4, 0x8AB9, 0xDEA6, 0x8ABC, 0xEBFE, - 0x8ABE, 0xEBDD, 0x8ABF, 0xF0E0, 0x8AC2, 0xF4DB, 0x8AC4, 0xE2F4, 0x8AC7, 0xD3C8, 0x8ACB, 0xF4EB, 0x8ACD, 0xEEB5, 0x8ACF, 0xF5D8, - 0x8AD2, 0xD5DF, 0x8AD6, 0xD6E5, 0x8ADB, 0xEBB0, 0x8ADC, 0xF4E3, 0x8AE1, 0xE3CD, 0x8AE6, 0xF4F4, 0x8AE7, 0xFAB2, 0x8AEA, 0xEFF5, - 0x8AEB, 0xCADF, 0x8AED, 0xEBB1, 0x8AEE, 0xEDBF, 0x8AF1, 0xFDC9, 0x8AF6, 0xE4A6, 0x8AF7, 0xF9A4, 0x8AF8, 0xF0B3, 0x8AFA, 0xE5EC, - 0x8AFE, 0xD1E7, 0x8B00, 0xD9C7, 0x8B01, 0xE4D7, 0x8B02, 0xEADD, 0x8B04, 0xD4F7, 0x8B0E, 0xDABA, 0x8B10, 0xDACD, 0x8B14, 0xF9CC, - 0x8B16, 0xE1DA, 0x8B17, 0xDBBF, 0x8B19, 0xCCC5, 0x8B1A, 0xECD0, 0x8B1B, 0xCBBB, 0x8B1D, 0xDEF3, 0x8B20, 0xE9AA, 0x8B28, 0xD9C8, - 0x8B2B, 0xEEE3, 0x8B2C, 0xD7BD, 0x8B33, 0xCFC4, 0x8B39, 0xD0CD, 0x8B41, 0xFCA6, 0x8B49, 0xF1FB, 0x8B4E, 0xFDD2, 0x8B4F, 0xD1C1, - 0x8B58, 0xE3DB, 0x8B5A, 0xD3C9, 0x8B5C, 0xDCCF, 0x8B66, 0xCCED, 0x8B6C, 0xDEA7, 0x8B6F, 0xE6BB, 0x8B70, 0xECA1, 0x8B74, 0xCCB9, - 0x8B77, 0xFBDE, 0x8B7D, 0xE7E2, 0x8B80, 0xD4C1, 0x8B8A, 0xDCA8, 0x8B90, 0xE2C2, 0x8B92, 0xF3D8, 0x8B93, 0xE5D3, 0x8B96, 0xF3D9, - 0x8B9A, 0xF3C6, 0x8C37, 0xCDDB, 0x8C3F, 0xCDAC, 0x8C41, 0xFCC3, 0x8C46, 0xD4E7, 0x8C48, 0xD1C2, 0x8C4A, 0xF9A5, 0x8C4C, 0xE8D5, - 0x8C55, 0xE3CE, 0x8C5A, 0xD4CA, 0x8C61, 0xDFDA, 0x8C6A, 0xFBDF, 0x8C6B, 0xE7E3, 0x8C79, 0xF8FB, 0x8C7A, 0xE3CF, 0x8C82, 0xF5B0, - 0x8C8A, 0xD8E7, 0x8C8C, 0xD9C9, 0x8C9D, 0xF8AF, 0x8C9E, 0xEFF6, 0x8CA0, 0xDDB6, 0x8CA1, 0xEEAF, 0x8CA2, 0xCDF8, 0x8CA7, 0xDEB8, - 0x8CA8, 0xFCA7, 0x8CA9, 0xF7FC, 0x8CAA, 0xF7B1, 0x8CAB, 0xCEBB, 0x8CAC, 0xF4A1, 0x8CAF, 0xEECD, 0x8CB0, 0xE1AE, 0x8CB3, 0xECC3, - 0x8CB4, 0xCFFE, 0x8CB6, 0xF8BF, 0x8CB7, 0xD8E2, 0x8CB8, 0xD3E8, 0x8CBB, 0xDEA8, 0x8CBC, 0xF4E4, 0x8CBD, 0xECC2, 0x8CBF, 0xD9F5, - 0x8CC0, 0xF9C5, 0x8CC1, 0xDDD3, 0x8CC2, 0xD6F1, 0x8CC3, 0xECFC, 0x8CC4, 0xFCF0, 0x8CC7, 0xEDC0, 0x8CC8, 0xCAB9, 0x8CCA, 0xEEE4, - 0x8CD1, 0xF2E1, 0x8CD3, 0xDEB9, 0x8CDA, 0xD6F2, 0x8CDC, 0xDEF4, 0x8CDE, 0xDFDB, 0x8CE0, 0xDBD3, 0x8CE2, 0xFAE7, 0x8CE3, 0xD8E3, - 0x8CE4, 0xF4C1, 0x8CE6, 0xDDB7, 0x8CEA, 0xF2F5, 0x8CED, 0xD4AE, 0x8CF4, 0xD6F3, 0x8CFB, 0xDDB8, 0x8CFC, 0xCFC5, 0x8CFD, 0xDFDF, - 0x8D04, 0xF2BE, 0x8D05, 0xF6A1, 0x8D07, 0xEBCB, 0x8D08, 0xF1FC, 0x8D0A, 0xF3C7, 0x8D0D, 0xE0EB, 0x8D13, 0xEDFC, 0x8D16, 0xE1DB, - 0x8D64, 0xEEE5, 0x8D66, 0xDEF5, 0x8D6B, 0xFAD3, 0x8D70, 0xF1CB, 0x8D73, 0xD0AF, 0x8D74, 0xDDB9, 0x8D77, 0xD1C3, 0x8D85, 0xF5B1, - 0x8D8A, 0xEAC6, 0x8D99, 0xF0E1, 0x8DA3, 0xF6AC, 0x8DA8, 0xF5D9, 0x8DB3, 0xF0EB, 0x8DBA, 0xDDBA, 0x8DBE, 0xF2BF, 0x8DC6, 0xF7C5, - 0x8DCB, 0xDBA2, 0x8DCC, 0xF2F6, 0x8DCF, 0xCABA, 0x8DDB, 0xF7F5, 0x8DDD, 0xCBE5, 0x8DE1, 0xEEE6, 0x8DE3, 0xE0D3, 0x8DE8, 0xCEA5, - 0x8DEF, 0xD6D8, 0x8DF3, 0xD4AF, 0x8E0A, 0xE9C9, 0x8E0F, 0xD3CE, 0x8E10, 0xF4C2, 0x8E1E, 0xCBE6, 0x8E2A, 0xF1A1, 0x8E30, 0xEBB2, - 0x8E35, 0xF1A2, 0x8E42, 0xEBB3, 0x8E44, 0xF0B4, 0x8E47, 0xCBF4, 0x8E48, 0xD4B0, 0x8E49, 0xF3B2, 0x8E4A, 0xFBB7, 0x8E59, 0xF5EC, - 0x8E5F, 0xEEE7, 0x8E60, 0xF4B2, 0x8E74, 0xF5ED, 0x8E76, 0xCFF3, 0x8E81, 0xF0E2, 0x8E87, 0xEECE, 0x8E8A, 0xF1CC, 0x8E8D, 0xE5B8, - 0x8EAA, 0xD7F5, 0x8EAB, 0xE3F3, 0x8EAC, 0xCFE5, 0x8EC0, 0xCFC6, 0x8ECA, 0xF3B3, 0x8ECB, 0xE4D8, 0x8ECC, 0xCFF9, 0x8ECD, 0xCFDA, - 0x8ED2, 0xFACD, 0x8EDF, 0xE6E3, 0x8EEB, 0xF2E2, 0x8EF8, 0xF5EE, 0x8EFB, 0xCABB, 0x8EFE, 0xE3DC, 0x8F03, 0xCEF2, 0x8F05, 0xD6D9, - 0x8F09, 0xEEB0, 0x8F12, 0xF4E5, 0x8F13, 0xD8C2, 0x8F14, 0xDCD0, 0x8F15, 0xCCEE, 0x8F1B, 0xD5E0, 0x8F1C, 0xF6CA, 0x8F1D, 0xFDCA, - 0x8F1E, 0xD8D6, 0x8F1F, 0xF4CF, 0x8F26, 0xD6A6, 0x8F27, 0xDCBE, 0x8F29, 0xDBD4, 0x8F2A, 0xD7C7, 0x8F2F, 0xF2FE, 0x8F33, 0xF1CD, - 0x8F38, 0xE2C3, 0x8F39, 0xDCDE, 0x8F3B, 0xDCDF, 0x8F3E, 0xEFAD, 0x8F3F, 0xE6AB, 0x8F44, 0xF9DD, 0x8F45, 0xEABF, 0x8F49, 0xEFAE, - 0x8F4D, 0xF4D0, 0x8F4E, 0xCEF3, 0x8F5D, 0xE6AC, 0x8F5F, 0xCEDE, 0x8F62, 0xD5F9, 0x8F9B, 0xE3F4, 0x8F9C, 0xCDD0, 0x8FA3, 0xD5B8, - 0x8FA6, 0xF7FD, 0x8FA8, 0xDCA9, 0x8FAD, 0xDEF6, 0x8FAF, 0xDCAA, 0x8FB0, 0xF2E3, 0x8FB1, 0xE9B4, 0x8FB2, 0xD2DC, 0x8FC2, 0xE9E6, - 0x8FC5, 0xE3F6, 0x8FCE, 0xE7CA, 0x8FD1, 0xD0CE, 0x8FD4, 0xDAF7, 0x8FE6, 0xCABC, 0x8FEA, 0xEEE8, 0x8FEB, 0xDADE, 0x8FED, 0xF2F7, - 0x8FF0, 0xE2FB, 0x8FF2, 0xCCA6, 0x8FF7, 0xDABB, 0x8FF9, 0xEEE9, 0x8FFD, 0xF5DA, 0x9000, 0xF7DC, 0x9001, 0xE1EA, 0x9002, 0xCEC1, - 0x9003, 0xD4B1, 0x9005, 0xFDB1, 0x9006, 0xE6BD, 0x9008, 0xFBAD, 0x900B, 0xF8E7, 0x900D, 0xE1CE, 0x900F, 0xF7E2, 0x9010, 0xF5EF, - 0x9011, 0xCFC7, 0x9014, 0xD4B2, 0x9015, 0xCCEF, 0x9017, 0xD4E8, 0x9019, 0xEECF, 0x901A, 0xF7D7, 0x901D, 0xE0A6, 0x901E, 0xD6C1, - 0x901F, 0xE1DC, 0x9020, 0xF0E3, 0x9021, 0xF1E4, 0x9022, 0xDCF1, 0x9023, 0xD6A7, 0x902E, 0xF4F5, 0x9031, 0xF1CE, 0x9032, 0xF2E4, - 0x9035, 0xD0B0, 0x9038, 0xECEF, 0x903C, 0xF9BA, 0x903E, 0xEBB5, 0x9041, 0xD4ED, 0x9042, 0xE2C4, 0x9047, 0xE9E7, 0x904A, 0xEBB4, - 0x904B, 0xEAA1, 0x904D, 0xF8BC, 0x904E, 0xCEA6, 0x9050, 0xF9C6, 0x9051, 0xFCDA, 0x9053, 0xD4B3, 0x9054, 0xD3B9, 0x9055, 0xEADE, - 0x9059, 0xE9AB, 0x905C, 0xE1E1, 0x905D, 0xD3CF, 0x905E, 0xF4F6, 0x9060, 0xEAC0, 0x9061, 0xE1CF, 0x9063, 0xCCBA, 0x9069, 0xEEEA, - 0x906D, 0xF0E4, 0x906E, 0xF3B4, 0x906F, 0xD4EE, 0x9072, 0xF2C0, 0x9075, 0xF1E5, 0x9077, 0xF4C3, 0x9078, 0xE0D4, 0x907A, 0xEBB6, - 0x907C, 0xD7A1, 0x907D, 0xCBE8, 0x907F, 0xF9AD, 0x9080, 0xE9AD, 0x9081, 0xD8E4, 0x9082, 0xFAB3, 0x9083, 0xE2C5, 0x9084, 0xFCBD, - 0x9087, 0xECC4, 0x9088, 0xD8B1, 0x908A, 0xDCAB, 0x908F, 0xD5A4, 0x9091, 0xEBE9, 0x9095, 0xE8BB, 0x9099, 0xD8D7, 0x90A2, 0xFBAE, - 0x90A3, 0xD1E1, 0x90A6, 0xDBC0, 0x90A8, 0xF5BE, 0x90AA, 0xDEF7, 0x90AF, 0xCAFB, 0x90B0, 0xF7C6, 0x90B1, 0xCFC8, 0x90B5, 0xE1D0, - 0x90B8, 0xEED0, 0x90C1, 0xE9F4, 0x90CA, 0xCEF4, 0x90DE, 0xD5CD, 0x90E1, 0xCFDB, 0x90E8, 0xDDBB, 0x90ED, 0xCEAC, 0x90F5, 0xE9E8, - 0x90FD, 0xD4B4, 0x9102, 0xE4C7, 0x9112, 0xF5DB, 0x9115, 0xFAC1, 0x9119, 0xDEA9, 0x9127, 0xD4F8, 0x912D, 0xEFF7, 0x9132, 0xD3B3, - 0x9149, 0xEBB7, 0x914A, 0xEFF8, 0x914B, 0xF5DC, 0x914C, 0xEDCC, 0x914D, 0xDBD5, 0x914E, 0xF1CF, 0x9152, 0xF1D0, 0x9162, 0xF5B2, - 0x9169, 0xD9AE, 0x916A, 0xD5AC, 0x916C, 0xE2C6, 0x9175, 0xFDA3, 0x9177, 0xFBE5, 0x9178, 0xDFAB, 0x9187, 0xE2F5, 0x9189, 0xF6AD, - 0x918B, 0xF5B3, 0x918D, 0xF0B5, 0x9192, 0xE1A5, 0x919C, 0xF5DD, 0x91AB, 0xECA2, 0x91AC, 0xEDFD, 0x91AE, 0xF5B4, 0x91AF, 0xFBB8, - 0x91B1, 0xDBA3, 0x91B4, 0xD6CA, 0x91B5, 0xCBD9, 0x91C0, 0xE5D4, 0x91C7, 0xF3FA, 0x91C9, 0xEBB8, 0x91CB, 0xE0B7, 0x91CC, 0xD7EC, - 0x91CD, 0xF1EC, 0x91CE, 0xE5AF, 0x91CF, 0xD5E1, 0x91D0, 0xD7ED, 0x91D1, 0xD1D1, 0x91D7, 0xE1F2, 0x91D8, 0xEFF9, 0x91DC, 0xDDBC, - 0x91DD, 0xF6DC, 0x91E3, 0xF0E5, 0x91E7, 0xF4C4, 0x91EA, 0xE9E9, 0x91F5, 0xF3FB, 0x920D, 0xD4EF, 0x9210, 0xCCA2, 0x9211, 0xF7FE, - 0x9212, 0xDFBC, 0x9217, 0xEBCD, 0x921E, 0xD0B7, 0x9234, 0xD6C2, 0x923A, 0xE8AD, 0x923F, 0xEFAF, 0x9240, 0xCBA5, 0x9245, 0xCBE9, - 0x9249, 0xFAE8, 0x9257, 0xCCC6, 0x925B, 0xE6E7, 0x925E, 0xEAC7, 0x9262, 0xDBA4, 0x9264, 0xCFC9, 0x9265, 0xE2FC, 0x9266, 0xEFFA, - 0x9280, 0xEBDE, 0x9283, 0xF5C8, 0x9285, 0xD4DE, 0x9291, 0xE0D5, 0x9293, 0xEFB0, 0x9296, 0xE2C7, 0x9298, 0xD9AF, 0x929C, 0xF9E7, - 0x92B3, 0xE7E5, 0x92B6, 0xCFCA, 0x92B7, 0xE1D1, 0x92B9, 0xE2C8, 0x92CC, 0xEFFB, 0x92CF, 0xFAF9, 0x92D2, 0xDCF2, 0x92E4, 0xE0A7, - 0x92EA, 0xF8E8, 0x92F8, 0xCBEA, 0x92FC, 0xCBBC, 0x9304, 0xD6E2, 0x9310, 0xF5DE, 0x9318, 0xF5DF, 0x931A, 0xEEB6, 0x931E, 0xE2F6, - 0x931F, 0xD3CA, 0x9320, 0xEFFC, 0x9321, 0xD1C4, 0x9322, 0xEFB1, 0x9324, 0xD1C5, 0x9326, 0xD0DE, 0x9328, 0xD9E1, 0x932B, 0xE0B8, - 0x932E, 0xCDD1, 0x932F, 0xF3B9, 0x9348, 0xE7CC, 0x934A, 0xD6A8, 0x934B, 0xCEA7, 0x934D, 0xD4B5, 0x9354, 0xE4C8, 0x935B, 0xD3B4, - 0x936E, 0xEBB9, 0x9375, 0xCBF5, 0x937C, 0xF6DD, 0x937E, 0xF1A3, 0x938C, 0xCCC7, 0x9394, 0xE9CA, 0x9396, 0xE1F0, 0x939A, 0xF5E0, - 0x93A3, 0xFBAF, 0x93A7, 0xCBD1, 0x93AC, 0xFBE0, 0x93AD, 0xF2E5, 0x93B0, 0xECF0, 0x93C3, 0xF0EC, 0x93D1, 0xEEEB, 0x93DE, 0xE9CB, - 0x93E1, 0xCCF0, 0x93E4, 0xD7AF, 0x93F6, 0xF3A1, 0x9404, 0xFCF5, 0x9418, 0xF1A4, 0x9425, 0xE0D6, 0x942B, 0xEFB2, 0x9435, 0xF4D1, - 0x9438, 0xF7A1, 0x9444, 0xF1D1, 0x9451, 0xCAFC, 0x9452, 0xCAFD, 0x945B, 0xCECE, 0x947D, 0xF3C8, 0x947F, 0xF3BA, 0x9577, 0xEDFE, - 0x9580, 0xDAA6, 0x9583, 0xE0EC, 0x9589, 0xF8CD, 0x958B, 0xCBD2, 0x958F, 0xEBCE, 0x9591, 0xF9D8, 0x9592, 0xF9D9, 0x9593, 0xCAE0, - 0x9594, 0xDACA, 0x9598, 0xCBA6, 0x95A3, 0xCAC8, 0x95A4, 0xF9EE, 0x95A5, 0xDBEC, 0x95A8, 0xD0B1, 0x95AD, 0xD5EF, 0x95B1, 0xE6F3, - 0x95BB, 0xE7A2, 0x95BC, 0xE4D9, 0x95C7, 0xE4E1, 0x95CA, 0xFCC4, 0x95D4, 0xF9EF, 0x95D5, 0xCFF4, 0x95D6, 0xF7E6, 0x95DC, 0xCEBC, - 0x95E1, 0xF4C5, 0x95E2, 0xDCA3, 0x961C, 0xDDBD, 0x9621, 0xF4C6, 0x962A, 0xF8A1, 0x962E, 0xE8D6, 0x9632, 0xDBC1, 0x963B, 0xF0E6, - 0x963F, 0xE4B9, 0x9640, 0xF6ED, 0x9642, 0xF9AE, 0x9644, 0xDDBE, 0x964B, 0xD7B0, 0x964C, 0xD8E8, 0x964D, 0xCBBD, 0x9650, 0xF9DA, - 0x965B, 0xF8CE, 0x965C, 0xF9F0, 0x965D, 0xE0ED, 0x965E, 0xE3B3, 0x965F, 0xF4B3, 0x9662, 0xEAC2, 0x9663, 0xF2E6, 0x9664, 0xF0B6, - 0x966A, 0xDBD6, 0x9670, 0xEBE4, 0x9673, 0xF2E7, 0x9675, 0xD7D5, 0x9676, 0xD4B6, 0x9677, 0xF9E8, 0x9678, 0xD7C1, 0x967D, 0xE5D5, - 0x9685, 0xE9EA, 0x9686, 0xD7CC, 0x968A, 0xD3E9, 0x968B, 0xE2C9, 0x968D, 0xFCDB, 0x968E, 0xCDAD, 0x9694, 0xCCB0, 0x9695, 0xEAA2, - 0x9698, 0xE4F6, 0x9699, 0xD0C0, 0x969B, 0xF0B7, 0x969C, 0xEEA1, 0x96A3, 0xD7F6, 0x96A7, 0xE2CA, 0x96A8, 0xE2CB, 0x96AA, 0xFACF, - 0x96B1, 0xEBDF, 0x96B7, 0xD6CB, 0x96BB, 0xF4B4, 0x96C0, 0xEDCD, 0x96C1, 0xE4D2, 0x96C4, 0xEAA9, 0x96C5, 0xE4BA, 0x96C6, 0xF3A2, - 0x96C7, 0xCDD2, 0x96C9, 0xF6CB, 0x96CB, 0xF1E6, 0x96CC, 0xEDC1, 0x96CD, 0xE8BC, 0x96CE, 0xEED1, 0x96D5, 0xF0E7, 0x96D6, 0xE2CC, - 0x96D9, 0xE4AA, 0x96DB, 0xF5E1, 0x96DC, 0xEDDA, 0x96E2, 0xD7EE, 0x96E3, 0xD1F1, 0x96E8, 0xE9EB, 0x96E9, 0xE9EC, 0x96EA, 0xE0E4, - 0x96EF, 0xDAA7, 0x96F0, 0xDDD4, 0x96F2, 0xEAA3, 0x96F6, 0xD6C3, 0x96F7, 0xD6F4, 0x96F9, 0xDADF, 0x96FB, 0xEFB3, 0x9700, 0xE2CD, - 0x9706, 0xEFFD, 0x9707, 0xF2E8, 0x9711, 0xEFC5, 0x9713, 0xE7E7, 0x9716, 0xD7FD, 0x9719, 0xE7CE, 0x971C, 0xDFDC, 0x971E, 0xF9C7, - 0x9727, 0xD9F6, 0x9730, 0xDFAC, 0x9732, 0xD6DA, 0x9739, 0xDCA4, 0x973D, 0xF0B8, 0x9742, 0xD5FA, 0x9744, 0xE4F7, 0x9748, 0xD6C4, - 0x9751, 0xF4EC, 0x9756, 0xEFFE, 0x975C, 0xF0A1, 0x975E, 0xDEAA, 0x9761, 0xDABC, 0x9762, 0xD8FC, 0x9769, 0xFAD4, 0x976D, 0xECE5, - 0x9774, 0xFCA8, 0x9777, 0xECE6, 0x977A, 0xD8CB, 0x978B, 0xFBB9, 0x978D, 0xE4D3, 0x978F, 0xCDF9, 0x97A0, 0xCFD3, 0x97A8, 0xCAEA, - 0x97AB, 0xCFD4, 0x97AD, 0xF8BD, 0x97C6, 0xF4C7, 0x97CB, 0xEADF, 0x97D3, 0xF9DB, 0x97DC, 0xD4B7, 0x97F3, 0xEBE5, 0x97F6, 0xE1D2, - 0x97FB, 0xEAA4, 0x97FF, 0xFAC2, 0x9800, 0xFBE1, 0x9801, 0xFAED, 0x9802, 0xF0A2, 0x9803, 0xCCF1, 0x9805, 0xFAA3, 0x9806, 0xE2F7, - 0x9808, 0xE2CE, 0x980A, 0xE9F5, 0x980C, 0xE1EB, 0x9810, 0xE7E8, 0x9811, 0xE8D7, 0x9812, 0xDAF8, 0x9813, 0xD4CB, 0x9817, 0xF7F6, - 0x9818, 0xD6C5, 0x982D, 0xD4E9, 0x9830, 0xFAFA, 0x9838, 0xCCF2, 0x9839, 0xF7DD, 0x983B, 0xDEBA, 0x9846, 0xCEA8, 0x984C, 0xF0B9, - 0x984D, 0xE4FE, 0x984E, 0xE4C9, 0x9854, 0xE4D4, 0x9858, 0xEAC3, 0x985A, 0xEFB4, 0x985E, 0xD7BE, 0x9865, 0xFBE2, 0x9867, 0xCDD3, - 0x986B, 0xEFB5, 0x986F, 0xFAE9, 0x98A8, 0xF9A6, 0x98AF, 0xDFBD, 0x98B1, 0xF7C7, 0x98C4, 0xF8FD, 0x98C7, 0xF8FC, 0x98DB, 0xDEAB, - 0x98DC, 0xDBE8, 0x98DF, 0xE3DD, 0x98E1, 0xE1E2, 0x98E2, 0xD1C6, 0x98ED, 0xF6D0, 0x98EE, 0xEBE6, 0x98EF, 0xDAF9, 0x98F4, 0xECC7, - 0x98FC, 0xDEF8, 0x98FD, 0xF8E9, 0x98FE, 0xE3DE, 0x9903, 0xCEF5, 0x9909, 0xFAC3, 0x990A, 0xE5D7, 0x990C, 0xECC8, 0x9910, 0xF3C9, - 0x9913, 0xE4BB, 0x9918, 0xE6AE, 0x991E, 0xEFB6, 0x9920, 0xDCBF, 0x9928, 0xCEBD, 0x9945, 0xD8C3, 0x9949, 0xD0CF, 0x994B, 0xCFFA, - 0x994C, 0xF3CA, 0x994D, 0xE0D7, 0x9951, 0xD1C7, 0x9952, 0xE9AE, 0x9954, 0xE8BD, 0x9957, 0xFAC4, 0x9996, 0xE2CF, 0x9999, 0xFAC5, - 0x999D, 0xF9B8, 0x99A5, 0xDCE0, 0x99A8, 0xFBB0, 0x99AC, 0xD8A9, 0x99AD, 0xE5DF, 0x99AE, 0xF9A7, 0x99B1, 0xF6EE, 0x99B3, 0xF6CC, - 0x99B4, 0xE2F8, 0x99B9, 0xECF1, 0x99C1, 0xDAE0, 0x99D0, 0xF1D2, 0x99D1, 0xD2CC, 0x99D2, 0xCFCB, 0x99D5, 0xCABD, 0x99D9, 0xDDBF, - 0x99DD, 0xF6EF, 0x99DF, 0xDEF9, 0x99ED, 0xFAB4, 0x99F1, 0xD5AD, 0x99FF, 0xF1E7, 0x9A01, 0xDEBE, 0x9A08, 0xDCC0, 0x9A0E, 0xD1C8, - 0x9A0F, 0xD1C9, 0x9A19, 0xF8BE, 0x9A2B, 0xCBF6, 0x9A30, 0xD4F9, 0x9A36, 0xF5E2, 0x9A37, 0xE1D3, 0x9A40, 0xD8E9, 0x9A43, 0xF8FE, - 0x9A45, 0xCFCC, 0x9A4D, 0xFDA4, 0x9A55, 0xCEF6, 0x9A57, 0xFAD0, 0x9A5A, 0xCCF3, 0x9A5B, 0xE6BE, 0x9A5F, 0xF6AE, 0x9A62, 0xD5F0, - 0x9A65, 0xD1CA, 0x9A69, 0xFCBE, 0x9A6A, 0xD5F1, 0x9AA8, 0xCDE9, 0x9AB8, 0xFAB5, 0x9AD3, 0xE2D0, 0x9AD4, 0xF4F7, 0x9AD8, 0xCDD4, - 0x9AE5, 0xE7A3, 0x9AEE, 0xDBA5, 0x9B1A, 0xE2D1, 0x9B27, 0xD7A2, 0x9B2A, 0xF7E3, 0x9B31, 0xEAA6, 0x9B3C, 0xD0A1, 0x9B41, 0xCEDA, - 0x9B42, 0xFBEB, 0x9B43, 0xDBA6, 0x9B44, 0xDBDE, 0x9B45, 0xD8E5, 0x9B4F, 0xEAE0, 0x9B54, 0xD8AA, 0x9B5A, 0xE5E0, 0x9B6F, 0xD6DB, - 0x9B8E, 0xEFC6, 0x9B91, 0xF8EA, 0x9B9F, 0xE4D5, 0x9BAB, 0xCEF7, 0x9BAE, 0xE0D8, 0x9BC9, 0xD7EF, 0x9BD6, 0xF4ED, 0x9BE4, 0xCDE6, - 0x9BE8, 0xCCF4, 0x9C0D, 0xF5E3, 0x9C10, 0xE4CA, 0x9C12, 0xDCE1, 0x9C15, 0xF9C8, 0x9C25, 0xFCBF, 0x9C32, 0xE8A7, 0x9C3B, 0xD8C4, - 0x9C47, 0xCBBE, 0x9C49, 0xDCAE, 0x9C57, 0xD7F7, 0x9CE5, 0xF0E8, 0x9CE7, 0xDDC0, 0x9CE9, 0xCFCD, 0x9CF3, 0xDCF3, 0x9CF4, 0xD9B0, - 0x9CF6, 0xE6E9, 0x9D09, 0xE4BC, 0x9D1B, 0xEAC4, 0x9D26, 0xE4EC, 0x9D28, 0xE4E5, 0x9D3B, 0xFBF8, 0x9D51, 0xCCBB, 0x9D5D, 0xE4BD, - 0x9D60, 0xCDDC, 0x9D61, 0xD9F7, 0x9D6C, 0xDDDF, 0x9D72, 0xEDCE, 0x9DA9, 0xD9D0, 0x9DAF, 0xE5A3, 0x9DB4, 0xF9CD, 0x9DC4, 0xCDAE, - 0x9DD7, 0xCFCE, 0x9DF2, 0xF6AF, 0x9DF8, 0xFDD3, 0x9DF9, 0xEBED, 0x9DFA, 0xD6DC, 0x9E1A, 0xE5A4, 0x9E1E, 0xD5B6, 0x9E75, 0xD6DD, - 0x9E79, 0xF9E9, 0x9E7D, 0xE7A4, 0x9E7F, 0xD6E3, 0x9E92, 0xD1CB, 0x9E93, 0xD6E4, 0x9E97, 0xD5F2, 0x9E9D, 0xDEFA, 0x9E9F, 0xD7F8, - 0x9EA5, 0xD8EA, 0x9EB4, 0xCFD5, 0x9EB5, 0xD8FD, 0x9EBB, 0xD8AB, 0x9EBE, 0xFDCB, 0x9EC3, 0xFCDC, 0x9ECD, 0xE0A8, 0x9ECE, 0xD5F3, - 0x9ED1, 0xFDD9, 0x9ED4, 0xCCA3, 0x9ED8, 0xD9F9, 0x9EDB, 0xD3EA, 0x9EDC, 0xF5F5, 0x9EDE, 0xEFC7, 0x9EE8, 0xD3DA, 0x9EF4, 0xDABD, - 0x9F07, 0xE8A8, 0x9F08, 0xDCAF, 0x9F0E, 0xF0A3, 0x9F13, 0xCDD5, 0x9F20, 0xE0A9, 0x9F3B, 0xDEAC, 0x9F4A, 0xF0BA, 0x9F4B, 0xEEB1, - 0x9F4E, 0xEEB2, 0x9F52, 0xF6CD, 0x9F5F, 0xEED2, 0x9F61, 0xD6C6, 0x9F67, 0xE0E5, 0x9F6A, 0xF3BB, 0x9F6C, 0xE5E1, 0x9F77, 0xE4CB, - 0x9F8D, 0xD7A3, 0x9F90, 0xDBC2, 0x9F95, 0xCAFE, 0x9F9C, 0xCFCF, 0xAC00, 0xB0A1, 0xAC01, 0xB0A2, 0xAC02, 0x8141, 0xAC03, 0x8142, - 0xAC04, 0xB0A3, 0xAC05, 0x8143, 0xAC06, 0x8144, 0xAC07, 0xB0A4, 0xAC08, 0xB0A5, 0xAC09, 0xB0A6, 0xAC0A, 0xB0A7, 0xAC0B, 0x8145, - 0xAC0C, 0x8146, 0xAC0D, 0x8147, 0xAC0E, 0x8148, 0xAC0F, 0x8149, 0xAC10, 0xB0A8, 0xAC11, 0xB0A9, 0xAC12, 0xB0AA, 0xAC13, 0xB0AB, - 0xAC14, 0xB0AC, 0xAC15, 0xB0AD, 0xAC16, 0xB0AE, 0xAC17, 0xB0AF, 0xAC18, 0x814A, 0xAC19, 0xB0B0, 0xAC1A, 0xB0B1, 0xAC1B, 0xB0B2, - 0xAC1C, 0xB0B3, 0xAC1D, 0xB0B4, 0xAC1E, 0x814B, 0xAC1F, 0x814C, 0xAC20, 0xB0B5, 0xAC21, 0x814D, 0xAC22, 0x814E, 0xAC23, 0x814F, - 0xAC24, 0xB0B6, 0xAC25, 0x8150, 0xAC26, 0x8151, 0xAC27, 0x8152, 0xAC28, 0x8153, 0xAC29, 0x8154, 0xAC2A, 0x8155, 0xAC2B, 0x8156, - 0xAC2C, 0xB0B7, 0xAC2D, 0xB0B8, 0xAC2E, 0x8157, 0xAC2F, 0xB0B9, 0xAC30, 0xB0BA, 0xAC31, 0xB0BB, 0xAC32, 0x8158, 0xAC33, 0x8159, - 0xAC34, 0x815A, 0xAC35, 0x8161, 0xAC36, 0x8162, 0xAC37, 0x8163, 0xAC38, 0xB0BC, 0xAC39, 0xB0BD, 0xAC3A, 0x8164, 0xAC3B, 0x8165, - 0xAC3C, 0xB0BE, 0xAC3D, 0x8166, 0xAC3E, 0x8167, 0xAC3F, 0x8168, 0xAC40, 0xB0BF, 0xAC41, 0x8169, 0xAC42, 0x816A, 0xAC43, 0x816B, - 0xAC44, 0x816C, 0xAC45, 0x816D, 0xAC46, 0x816E, 0xAC47, 0x816F, 0xAC48, 0x8170, 0xAC49, 0x8171, 0xAC4A, 0x8172, 0xAC4B, 0xB0C0, - 0xAC4C, 0x8173, 0xAC4D, 0xB0C1, 0xAC4E, 0x8174, 0xAC4F, 0x8175, 0xAC50, 0x8176, 0xAC51, 0x8177, 0xAC52, 0x8178, 0xAC53, 0x8179, - 0xAC54, 0xB0C2, 0xAC55, 0x817A, 0xAC56, 0x8181, 0xAC57, 0x8182, 0xAC58, 0xB0C3, 0xAC59, 0x8183, 0xAC5A, 0x8184, 0xAC5B, 0x8185, - 0xAC5C, 0xB0C4, 0xAC5D, 0x8186, 0xAC5E, 0x8187, 0xAC5F, 0x8188, 0xAC60, 0x8189, 0xAC61, 0x818A, 0xAC62, 0x818B, 0xAC63, 0x818C, - 0xAC64, 0x818D, 0xAC65, 0x818E, 0xAC66, 0x818F, 0xAC67, 0x8190, 0xAC68, 0x8191, 0xAC69, 0x8192, 0xAC6A, 0x8193, 0xAC6B, 0x8194, - 0xAC6C, 0x8195, 0xAC6D, 0x8196, 0xAC6E, 0x8197, 0xAC6F, 0x8198, 0xAC70, 0xB0C5, 0xAC71, 0xB0C6, 0xAC72, 0x8199, 0xAC73, 0x819A, - 0xAC74, 0xB0C7, 0xAC75, 0x819B, 0xAC76, 0x819C, 0xAC77, 0xB0C8, 0xAC78, 0xB0C9, 0xAC79, 0x819D, 0xAC7A, 0xB0CA, 0xAC7B, 0x819E, - 0xAC7C, 0x819F, 0xAC7D, 0x81A0, 0xAC7E, 0x81A1, 0xAC7F, 0x81A2, 0xAC80, 0xB0CB, 0xAC81, 0xB0CC, 0xAC82, 0x81A3, 0xAC83, 0xB0CD, - 0xAC84, 0xB0CE, 0xAC85, 0xB0CF, 0xAC86, 0xB0D0, 0xAC87, 0x81A4, 0xAC88, 0x81A5, 0xAC89, 0xB0D1, 0xAC8A, 0xB0D2, 0xAC8B, 0xB0D3, - 0xAC8C, 0xB0D4, 0xAC8D, 0x81A6, 0xAC8E, 0x81A7, 0xAC8F, 0x81A8, 0xAC90, 0xB0D5, 0xAC91, 0x81A9, 0xAC92, 0x81AA, 0xAC93, 0x81AB, - 0xAC94, 0xB0D6, 0xAC95, 0x81AC, 0xAC96, 0x81AD, 0xAC97, 0x81AE, 0xAC98, 0x81AF, 0xAC99, 0x81B0, 0xAC9A, 0x81B1, 0xAC9B, 0x81B2, - 0xAC9C, 0xB0D7, 0xAC9D, 0xB0D8, 0xAC9E, 0x81B3, 0xAC9F, 0xB0D9, 0xACA0, 0xB0DA, 0xACA1, 0xB0DB, 0xACA2, 0x81B4, 0xACA3, 0x81B5, - 0xACA4, 0x81B6, 0xACA5, 0x81B7, 0xACA6, 0x81B8, 0xACA7, 0x81B9, 0xACA8, 0xB0DC, 0xACA9, 0xB0DD, 0xACAA, 0xB0DE, 0xACAB, 0x81BA, - 0xACAC, 0xB0DF, 0xACAD, 0x81BB, 0xACAE, 0x81BC, 0xACAF, 0xB0E0, 0xACB0, 0xB0E1, 0xACB1, 0x81BD, 0xACB2, 0x81BE, 0xACB3, 0x81BF, - 0xACB4, 0x81C0, 0xACB5, 0x81C1, 0xACB6, 0x81C2, 0xACB7, 0x81C3, 0xACB8, 0xB0E2, 0xACB9, 0xB0E3, 0xACBA, 0x81C4, 0xACBB, 0xB0E4, - 0xACBC, 0xB0E5, 0xACBD, 0xB0E6, 0xACBE, 0x81C5, 0xACBF, 0x81C6, 0xACC0, 0x81C7, 0xACC1, 0xB0E7, 0xACC2, 0x81C8, 0xACC3, 0x81C9, - 0xACC4, 0xB0E8, 0xACC5, 0x81CA, 0xACC6, 0x81CB, 0xACC7, 0x81CC, 0xACC8, 0xB0E9, 0xACC9, 0x81CD, 0xACCA, 0x81CE, 0xACCB, 0x81CF, - 0xACCC, 0xB0EA, 0xACCD, 0x81D0, 0xACCE, 0x81D1, 0xACCF, 0x81D2, 0xACD0, 0x81D3, 0xACD1, 0x81D4, 0xACD2, 0x81D5, 0xACD3, 0x81D6, - 0xACD4, 0x81D7, 0xACD5, 0xB0EB, 0xACD6, 0x81D8, 0xACD7, 0xB0EC, 0xACD8, 0x81D9, 0xACD9, 0x81DA, 0xACDA, 0x81DB, 0xACDB, 0x81DC, - 0xACDC, 0x81DD, 0xACDD, 0x81DE, 0xACDE, 0x81DF, 0xACDF, 0x81E0, 0xACE0, 0xB0ED, 0xACE1, 0xB0EE, 0xACE2, 0x81E1, 0xACE3, 0x81E2, - 0xACE4, 0xB0EF, 0xACE5, 0x81E3, 0xACE6, 0x81E4, 0xACE7, 0xB0F0, 0xACE8, 0xB0F1, 0xACE9, 0x81E5, 0xACEA, 0xB0F2, 0xACEB, 0x81E6, - 0xACEC, 0xB0F3, 0xACED, 0x81E7, 0xACEE, 0x81E8, 0xACEF, 0xB0F4, 0xACF0, 0xB0F5, 0xACF1, 0xB0F6, 0xACF2, 0x81E9, 0xACF3, 0xB0F7, - 0xACF4, 0x81EA, 0xACF5, 0xB0F8, 0xACF6, 0xB0F9, 0xACF7, 0x81EB, 0xACF8, 0x81EC, 0xACF9, 0x81ED, 0xACFA, 0x81EE, 0xACFB, 0x81EF, - 0xACFC, 0xB0FA, 0xACFD, 0xB0FB, 0xACFE, 0x81F0, 0xACFF, 0x81F1, 0xAD00, 0xB0FC, 0xAD01, 0x81F2, 0xAD02, 0x81F3, 0xAD03, 0x81F4, - 0xAD04, 0xB0FD, 0xAD05, 0x81F5, 0xAD06, 0xB0FE, 0xAD07, 0x81F6, 0xAD08, 0x81F7, 0xAD09, 0x81F8, 0xAD0A, 0x81F9, 0xAD0B, 0x81FA, - 0xAD0C, 0xB1A1, 0xAD0D, 0xB1A2, 0xAD0E, 0x81FB, 0xAD0F, 0xB1A3, 0xAD10, 0x81FC, 0xAD11, 0xB1A4, 0xAD12, 0x81FD, 0xAD13, 0x81FE, - 0xAD14, 0x8241, 0xAD15, 0x8242, 0xAD16, 0x8243, 0xAD17, 0x8244, 0xAD18, 0xB1A5, 0xAD19, 0x8245, 0xAD1A, 0x8246, 0xAD1B, 0x8247, - 0xAD1C, 0xB1A6, 0xAD1D, 0x8248, 0xAD1E, 0x8249, 0xAD1F, 0x824A, 0xAD20, 0xB1A7, 0xAD21, 0x824B, 0xAD22, 0x824C, 0xAD23, 0x824D, - 0xAD24, 0x824E, 0xAD25, 0x824F, 0xAD26, 0x8250, 0xAD27, 0x8251, 0xAD28, 0x8252, 0xAD29, 0xB1A8, 0xAD2A, 0x8253, 0xAD2B, 0x8254, - 0xAD2C, 0xB1A9, 0xAD2D, 0xB1AA, 0xAD2E, 0x8255, 0xAD2F, 0x8256, 0xAD30, 0x8257, 0xAD31, 0x8258, 0xAD32, 0x8259, 0xAD33, 0x825A, - 0xAD34, 0xB1AB, 0xAD35, 0xB1AC, 0xAD36, 0x8261, 0xAD37, 0x8262, 0xAD38, 0xB1AD, 0xAD39, 0x8263, 0xAD3A, 0x8264, 0xAD3B, 0x8265, - 0xAD3C, 0xB1AE, 0xAD3D, 0x8266, 0xAD3E, 0x8267, 0xAD3F, 0x8268, 0xAD40, 0x8269, 0xAD41, 0x826A, 0xAD42, 0x826B, 0xAD43, 0x826C, - 0xAD44, 0xB1AF, 0xAD45, 0xB1B0, 0xAD46, 0x826D, 0xAD47, 0xB1B1, 0xAD48, 0x826E, 0xAD49, 0xB1B2, 0xAD4A, 0x826F, 0xAD4B, 0x8270, - 0xAD4C, 0x8271, 0xAD4D, 0x8272, 0xAD4E, 0x8273, 0xAD4F, 0x8274, 0xAD50, 0xB1B3, 0xAD51, 0x8275, 0xAD52, 0x8276, 0xAD53, 0x8277, - 0xAD54, 0xB1B4, 0xAD55, 0x8278, 0xAD56, 0x8279, 0xAD57, 0x827A, 0xAD58, 0xB1B5, 0xAD59, 0x8281, 0xAD5A, 0x8282, 0xAD5B, 0x8283, - 0xAD5C, 0x8284, 0xAD5D, 0x8285, 0xAD5E, 0x8286, 0xAD5F, 0x8287, 0xAD60, 0x8288, 0xAD61, 0xB1B6, 0xAD62, 0x8289, 0xAD63, 0xB1B7, - 0xAD64, 0x828A, 0xAD65, 0x828B, 0xAD66, 0x828C, 0xAD67, 0x828D, 0xAD68, 0x828E, 0xAD69, 0x828F, 0xAD6A, 0x8290, 0xAD6B, 0x8291, - 0xAD6C, 0xB1B8, 0xAD6D, 0xB1B9, 0xAD6E, 0x8292, 0xAD6F, 0x8293, 0xAD70, 0xB1BA, 0xAD71, 0x8294, 0xAD72, 0x8295, 0xAD73, 0xB1BB, - 0xAD74, 0xB1BC, 0xAD75, 0xB1BD, 0xAD76, 0xB1BE, 0xAD77, 0x8296, 0xAD78, 0x8297, 0xAD79, 0x8298, 0xAD7A, 0x8299, 0xAD7B, 0xB1BF, - 0xAD7C, 0xB1C0, 0xAD7D, 0xB1C1, 0xAD7E, 0x829A, 0xAD7F, 0xB1C2, 0xAD80, 0x829B, 0xAD81, 0xB1C3, 0xAD82, 0xB1C4, 0xAD83, 0x829C, - 0xAD84, 0x829D, 0xAD85, 0x829E, 0xAD86, 0x829F, 0xAD87, 0x82A0, 0xAD88, 0xB1C5, 0xAD89, 0xB1C6, 0xAD8A, 0x82A1, 0xAD8B, 0x82A2, - 0xAD8C, 0xB1C7, 0xAD8D, 0x82A3, 0xAD8E, 0x82A4, 0xAD8F, 0x82A5, 0xAD90, 0xB1C8, 0xAD91, 0x82A6, 0xAD92, 0x82A7, 0xAD93, 0x82A8, - 0xAD94, 0x82A9, 0xAD95, 0x82AA, 0xAD96, 0x82AB, 0xAD97, 0x82AC, 0xAD98, 0x82AD, 0xAD99, 0x82AE, 0xAD9A, 0x82AF, 0xAD9B, 0x82B0, - 0xAD9C, 0xB1C9, 0xAD9D, 0xB1CA, 0xAD9E, 0x82B1, 0xAD9F, 0x82B2, 0xADA0, 0x82B3, 0xADA1, 0x82B4, 0xADA2, 0x82B5, 0xADA3, 0x82B6, - 0xADA4, 0xB1CB, 0xADA5, 0x82B7, 0xADA6, 0x82B8, 0xADA7, 0x82B9, 0xADA8, 0x82BA, 0xADA9, 0x82BB, 0xADAA, 0x82BC, 0xADAB, 0x82BD, - 0xADAC, 0x82BE, 0xADAD, 0x82BF, 0xADAE, 0x82C0, 0xADAF, 0x82C1, 0xADB0, 0x82C2, 0xADB1, 0x82C3, 0xADB2, 0x82C4, 0xADB3, 0x82C5, - 0xADB4, 0x82C6, 0xADB5, 0x82C7, 0xADB6, 0x82C8, 0xADB7, 0xB1CC, 0xADB8, 0x82C9, 0xADB9, 0x82CA, 0xADBA, 0x82CB, 0xADBB, 0x82CC, - 0xADBC, 0x82CD, 0xADBD, 0x82CE, 0xADBE, 0x82CF, 0xADBF, 0x82D0, 0xADC0, 0xB1CD, 0xADC1, 0xB1CE, 0xADC2, 0x82D1, 0xADC3, 0x82D2, - 0xADC4, 0xB1CF, 0xADC5, 0x82D3, 0xADC6, 0x82D4, 0xADC7, 0x82D5, 0xADC8, 0xB1D0, 0xADC9, 0x82D6, 0xADCA, 0x82D7, 0xADCB, 0x82D8, - 0xADCC, 0x82D9, 0xADCD, 0x82DA, 0xADCE, 0x82DB, 0xADCF, 0x82DC, 0xADD0, 0xB1D1, 0xADD1, 0xB1D2, 0xADD2, 0x82DD, 0xADD3, 0xB1D3, - 0xADD4, 0x82DE, 0xADD5, 0x82DF, 0xADD6, 0x82E0, 0xADD7, 0x82E1, 0xADD8, 0x82E2, 0xADD9, 0x82E3, 0xADDA, 0x82E4, 0xADDB, 0x82E5, - 0xADDC, 0xB1D4, 0xADDD, 0x82E6, 0xADDE, 0x82E7, 0xADDF, 0x82E8, 0xADE0, 0xB1D5, 0xADE1, 0x82E9, 0xADE2, 0x82EA, 0xADE3, 0x82EB, - 0xADE4, 0xB1D6, 0xADE5, 0x82EC, 0xADE6, 0x82ED, 0xADE7, 0x82EE, 0xADE8, 0x82EF, 0xADE9, 0x82F0, 0xADEA, 0x82F1, 0xADEB, 0x82F2, - 0xADEC, 0x82F3, 0xADED, 0x82F4, 0xADEE, 0x82F5, 0xADEF, 0x82F6, 0xADF0, 0x82F7, 0xADF1, 0x82F8, 0xADF2, 0x82F9, 0xADF3, 0x82FA, - 0xADF4, 0x82FB, 0xADF5, 0x82FC, 0xADF6, 0x82FD, 0xADF7, 0x82FE, 0xADF8, 0xB1D7, 0xADF9, 0xB1D8, 0xADFA, 0x8341, 0xADFB, 0x8342, - 0xADFC, 0xB1D9, 0xADFD, 0x8343, 0xADFE, 0x8344, 0xADFF, 0xB1DA, 0xAE00, 0xB1DB, 0xAE01, 0xB1DC, 0xAE02, 0x8345, 0xAE03, 0x8346, - 0xAE04, 0x8347, 0xAE05, 0x8348, 0xAE06, 0x8349, 0xAE07, 0x834A, 0xAE08, 0xB1DD, 0xAE09, 0xB1DE, 0xAE0A, 0x834B, 0xAE0B, 0xB1DF, - 0xAE0C, 0x834C, 0xAE0D, 0xB1E0, 0xAE0E, 0x834D, 0xAE0F, 0x834E, 0xAE10, 0x834F, 0xAE11, 0x8350, 0xAE12, 0x8351, 0xAE13, 0x8352, - 0xAE14, 0xB1E1, 0xAE15, 0x8353, 0xAE16, 0x8354, 0xAE17, 0x8355, 0xAE18, 0x8356, 0xAE19, 0x8357, 0xAE1A, 0x8358, 0xAE1B, 0x8359, - 0xAE1C, 0x835A, 0xAE1D, 0x8361, 0xAE1E, 0x8362, 0xAE1F, 0x8363, 0xAE20, 0x8364, 0xAE21, 0x8365, 0xAE22, 0x8366, 0xAE23, 0x8367, - 0xAE24, 0x8368, 0xAE25, 0x8369, 0xAE26, 0x836A, 0xAE27, 0x836B, 0xAE28, 0x836C, 0xAE29, 0x836D, 0xAE2A, 0x836E, 0xAE2B, 0x836F, - 0xAE2C, 0x8370, 0xAE2D, 0x8371, 0xAE2E, 0x8372, 0xAE2F, 0x8373, 0xAE30, 0xB1E2, 0xAE31, 0xB1E3, 0xAE32, 0x8374, 0xAE33, 0x8375, - 0xAE34, 0xB1E4, 0xAE35, 0x8376, 0xAE36, 0x8377, 0xAE37, 0xB1E5, 0xAE38, 0xB1E6, 0xAE39, 0x8378, 0xAE3A, 0xB1E7, 0xAE3B, 0x8379, - 0xAE3C, 0x837A, 0xAE3D, 0x8381, 0xAE3E, 0x8382, 0xAE3F, 0x8383, 0xAE40, 0xB1E8, 0xAE41, 0xB1E9, 0xAE42, 0x8384, 0xAE43, 0xB1EA, - 0xAE44, 0x8385, 0xAE45, 0xB1EB, 0xAE46, 0xB1EC, 0xAE47, 0x8386, 0xAE48, 0x8387, 0xAE49, 0x8388, 0xAE4A, 0xB1ED, 0xAE4B, 0x8389, - 0xAE4C, 0xB1EE, 0xAE4D, 0xB1EF, 0xAE4E, 0xB1F0, 0xAE4F, 0x838A, 0xAE50, 0xB1F1, 0xAE51, 0x838B, 0xAE52, 0x838C, 0xAE53, 0x838D, - 0xAE54, 0xB1F2, 0xAE55, 0x838E, 0xAE56, 0xB1F3, 0xAE57, 0x838F, 0xAE58, 0x8390, 0xAE59, 0x8391, 0xAE5A, 0x8392, 0xAE5B, 0x8393, - 0xAE5C, 0xB1F4, 0xAE5D, 0xB1F5, 0xAE5E, 0x8394, 0xAE5F, 0xB1F6, 0xAE60, 0xB1F7, 0xAE61, 0xB1F8, 0xAE62, 0x8395, 0xAE63, 0x8396, - 0xAE64, 0x8397, 0xAE65, 0xB1F9, 0xAE66, 0x8398, 0xAE67, 0x8399, 0xAE68, 0xB1FA, 0xAE69, 0xB1FB, 0xAE6A, 0x839A, 0xAE6B, 0x839B, - 0xAE6C, 0xB1FC, 0xAE6D, 0x839C, 0xAE6E, 0x839D, 0xAE6F, 0x839E, 0xAE70, 0xB1FD, 0xAE71, 0x839F, 0xAE72, 0x83A0, 0xAE73, 0x83A1, - 0xAE74, 0x83A2, 0xAE75, 0x83A3, 0xAE76, 0x83A4, 0xAE77, 0x83A5, 0xAE78, 0xB1FE, 0xAE79, 0xB2A1, 0xAE7A, 0x83A6, 0xAE7B, 0xB2A2, - 0xAE7C, 0xB2A3, 0xAE7D, 0xB2A4, 0xAE7E, 0x83A7, 0xAE7F, 0x83A8, 0xAE80, 0x83A9, 0xAE81, 0x83AA, 0xAE82, 0x83AB, 0xAE83, 0x83AC, - 0xAE84, 0xB2A5, 0xAE85, 0xB2A6, 0xAE86, 0x83AD, 0xAE87, 0x83AE, 0xAE88, 0x83AF, 0xAE89, 0x83B0, 0xAE8A, 0x83B1, 0xAE8B, 0x83B2, - 0xAE8C, 0xB2A7, 0xAE8D, 0x83B3, 0xAE8E, 0x83B4, 0xAE8F, 0x83B5, 0xAE90, 0x83B6, 0xAE91, 0x83B7, 0xAE92, 0x83B8, 0xAE93, 0x83B9, - 0xAE94, 0x83BA, 0xAE95, 0x83BB, 0xAE96, 0x83BC, 0xAE97, 0x83BD, 0xAE98, 0x83BE, 0xAE99, 0x83BF, 0xAE9A, 0x83C0, 0xAE9B, 0x83C1, - 0xAE9C, 0x83C2, 0xAE9D, 0x83C3, 0xAE9E, 0x83C4, 0xAE9F, 0x83C5, 0xAEA0, 0x83C6, 0xAEA1, 0x83C7, 0xAEA2, 0x83C8, 0xAEA3, 0x83C9, - 0xAEA4, 0x83CA, 0xAEA5, 0x83CB, 0xAEA6, 0x83CC, 0xAEA7, 0x83CD, 0xAEA8, 0x83CE, 0xAEA9, 0x83CF, 0xAEAA, 0x83D0, 0xAEAB, 0x83D1, - 0xAEAC, 0x83D2, 0xAEAD, 0x83D3, 0xAEAE, 0x83D4, 0xAEAF, 0x83D5, 0xAEB0, 0x83D6, 0xAEB1, 0x83D7, 0xAEB2, 0x83D8, 0xAEB3, 0x83D9, - 0xAEB4, 0x83DA, 0xAEB5, 0x83DB, 0xAEB6, 0x83DC, 0xAEB7, 0x83DD, 0xAEB8, 0x83DE, 0xAEB9, 0x83DF, 0xAEBA, 0x83E0, 0xAEBB, 0x83E1, - 0xAEBC, 0xB2A8, 0xAEBD, 0xB2A9, 0xAEBE, 0xB2AA, 0xAEBF, 0x83E2, 0xAEC0, 0xB2AB, 0xAEC1, 0x83E3, 0xAEC2, 0x83E4, 0xAEC3, 0x83E5, - 0xAEC4, 0xB2AC, 0xAEC5, 0x83E6, 0xAEC6, 0x83E7, 0xAEC7, 0x83E8, 0xAEC8, 0x83E9, 0xAEC9, 0x83EA, 0xAECA, 0x83EB, 0xAECB, 0x83EC, - 0xAECC, 0xB2AD, 0xAECD, 0xB2AE, 0xAECE, 0x83ED, 0xAECF, 0xB2AF, 0xAED0, 0xB2B0, 0xAED1, 0xB2B1, 0xAED2, 0x83EE, 0xAED3, 0x83EF, - 0xAED4, 0x83F0, 0xAED5, 0x83F1, 0xAED6, 0x83F2, 0xAED7, 0x83F3, 0xAED8, 0xB2B2, 0xAED9, 0xB2B3, 0xAEDA, 0x83F4, 0xAEDB, 0x83F5, - 0xAEDC, 0xB2B4, 0xAEDD, 0x83F6, 0xAEDE, 0x83F7, 0xAEDF, 0x83F8, 0xAEE0, 0x83F9, 0xAEE1, 0x83FA, 0xAEE2, 0x83FB, 0xAEE3, 0x83FC, - 0xAEE4, 0x83FD, 0xAEE5, 0x83FE, 0xAEE6, 0x8441, 0xAEE7, 0x8442, 0xAEE8, 0xB2B5, 0xAEE9, 0x8443, 0xAEEA, 0x8444, 0xAEEB, 0xB2B6, - 0xAEEC, 0x8445, 0xAEED, 0xB2B7, 0xAEEE, 0x8446, 0xAEEF, 0x8447, 0xAEF0, 0x8448, 0xAEF1, 0x8449, 0xAEF2, 0x844A, 0xAEF3, 0x844B, - 0xAEF4, 0xB2B8, 0xAEF5, 0x844C, 0xAEF6, 0x844D, 0xAEF7, 0x844E, 0xAEF8, 0xB2B9, 0xAEF9, 0x844F, 0xAEFA, 0x8450, 0xAEFB, 0x8451, - 0xAEFC, 0xB2BA, 0xAEFD, 0x8452, 0xAEFE, 0x8453, 0xAEFF, 0x8454, 0xAF00, 0x8455, 0xAF01, 0x8456, 0xAF02, 0x8457, 0xAF03, 0x8458, - 0xAF04, 0x8459, 0xAF05, 0x845A, 0xAF06, 0x8461, 0xAF07, 0xB2BB, 0xAF08, 0xB2BC, 0xAF09, 0x8462, 0xAF0A, 0x8463, 0xAF0B, 0x8464, - 0xAF0C, 0x8465, 0xAF0D, 0xB2BD, 0xAF0E, 0x8466, 0xAF0F, 0x8467, 0xAF10, 0xB2BE, 0xAF11, 0x8468, 0xAF12, 0x8469, 0xAF13, 0x846A, - 0xAF14, 0x846B, 0xAF15, 0x846C, 0xAF16, 0x846D, 0xAF17, 0x846E, 0xAF18, 0x846F, 0xAF19, 0x8470, 0xAF1A, 0x8471, 0xAF1B, 0x8472, - 0xAF1C, 0x8473, 0xAF1D, 0x8474, 0xAF1E, 0x8475, 0xAF1F, 0x8476, 0xAF20, 0x8477, 0xAF21, 0x8478, 0xAF22, 0x8479, 0xAF23, 0x847A, - 0xAF24, 0x8481, 0xAF25, 0x8482, 0xAF26, 0x8483, 0xAF27, 0x8484, 0xAF28, 0x8485, 0xAF29, 0x8486, 0xAF2A, 0x8487, 0xAF2B, 0x8488, - 0xAF2C, 0xB2BF, 0xAF2D, 0xB2C0, 0xAF2E, 0x8489, 0xAF2F, 0x848A, 0xAF30, 0xB2C1, 0xAF31, 0x848B, 0xAF32, 0xB2C2, 0xAF33, 0x848C, - 0xAF34, 0xB2C3, 0xAF35, 0x848D, 0xAF36, 0x848E, 0xAF37, 0x848F, 0xAF38, 0x8490, 0xAF39, 0x8491, 0xAF3A, 0x8492, 0xAF3B, 0x8493, - 0xAF3C, 0xB2C4, 0xAF3D, 0xB2C5, 0xAF3E, 0x8494, 0xAF3F, 0xB2C6, 0xAF40, 0x8495, 0xAF41, 0xB2C7, 0xAF42, 0xB2C8, 0xAF43, 0xB2C9, - 0xAF44, 0x8496, 0xAF45, 0x8497, 0xAF46, 0x8498, 0xAF47, 0x8499, 0xAF48, 0xB2CA, 0xAF49, 0xB2CB, 0xAF4A, 0x849A, 0xAF4B, 0x849B, - 0xAF4C, 0x849C, 0xAF4D, 0x849D, 0xAF4E, 0x849E, 0xAF4F, 0x849F, 0xAF50, 0xB2CC, 0xAF51, 0x84A0, 0xAF52, 0x84A1, 0xAF53, 0x84A2, - 0xAF54, 0x84A3, 0xAF55, 0x84A4, 0xAF56, 0x84A5, 0xAF57, 0x84A6, 0xAF58, 0x84A7, 0xAF59, 0x84A8, 0xAF5A, 0x84A9, 0xAF5B, 0x84AA, - 0xAF5C, 0xB2CD, 0xAF5D, 0xB2CE, 0xAF5E, 0x84AB, 0xAF5F, 0x84AC, 0xAF60, 0x84AD, 0xAF61, 0x84AE, 0xAF62, 0x84AF, 0xAF63, 0x84B0, - 0xAF64, 0xB2CF, 0xAF65, 0xB2D0, 0xAF66, 0x84B1, 0xAF67, 0x84B2, 0xAF68, 0x84B3, 0xAF69, 0x84B4, 0xAF6A, 0x84B5, 0xAF6B, 0x84B6, - 0xAF6C, 0x84B7, 0xAF6D, 0x84B8, 0xAF6E, 0x84B9, 0xAF6F, 0x84BA, 0xAF70, 0x84BB, 0xAF71, 0x84BC, 0xAF72, 0x84BD, 0xAF73, 0x84BE, - 0xAF74, 0x84BF, 0xAF75, 0x84C0, 0xAF76, 0x84C1, 0xAF77, 0x84C2, 0xAF78, 0x84C3, 0xAF79, 0xB2D1, 0xAF7A, 0x84C4, 0xAF7B, 0x84C5, - 0xAF7C, 0x84C6, 0xAF7D, 0x84C7, 0xAF7E, 0x84C8, 0xAF7F, 0x84C9, 0xAF80, 0xB2D2, 0xAF81, 0x84CA, 0xAF82, 0x84CB, 0xAF83, 0x84CC, - 0xAF84, 0xB2D3, 0xAF85, 0x84CD, 0xAF86, 0x84CE, 0xAF87, 0x84CF, 0xAF88, 0xB2D4, 0xAF89, 0x84D0, 0xAF8A, 0x84D1, 0xAF8B, 0x84D2, - 0xAF8C, 0x84D3, 0xAF8D, 0x84D4, 0xAF8E, 0x84D5, 0xAF8F, 0x84D6, 0xAF90, 0xB2D5, 0xAF91, 0xB2D6, 0xAF92, 0x84D7, 0xAF93, 0x84D8, - 0xAF94, 0x84D9, 0xAF95, 0xB2D7, 0xAF96, 0x84DA, 0xAF97, 0x84DB, 0xAF98, 0x84DC, 0xAF99, 0x84DD, 0xAF9A, 0x84DE, 0xAF9B, 0x84DF, - 0xAF9C, 0xB2D8, 0xAF9D, 0x84E0, 0xAF9E, 0x84E1, 0xAF9F, 0x84E2, 0xAFA0, 0x84E3, 0xAFA1, 0x84E4, 0xAFA2, 0x84E5, 0xAFA3, 0x84E6, - 0xAFA4, 0x84E7, 0xAFA5, 0x84E8, 0xAFA6, 0x84E9, 0xAFA7, 0x84EA, 0xAFA8, 0x84EB, 0xAFA9, 0x84EC, 0xAFAA, 0x84ED, 0xAFAB, 0x84EE, - 0xAFAC, 0x84EF, 0xAFAD, 0x84F0, 0xAFAE, 0x84F1, 0xAFAF, 0x84F2, 0xAFB0, 0x84F3, 0xAFB1, 0x84F4, 0xAFB2, 0x84F5, 0xAFB3, 0x84F6, - 0xAFB4, 0x84F7, 0xAFB5, 0x84F8, 0xAFB6, 0x84F9, 0xAFB7, 0x84FA, 0xAFB8, 0xB2D9, 0xAFB9, 0xB2DA, 0xAFBA, 0x84FB, 0xAFBB, 0x84FC, - 0xAFBC, 0xB2DB, 0xAFBD, 0x84FD, 0xAFBE, 0x84FE, 0xAFBF, 0x8541, 0xAFC0, 0xB2DC, 0xAFC1, 0x8542, 0xAFC2, 0x8543, 0xAFC3, 0x8544, - 0xAFC4, 0x8545, 0xAFC5, 0x8546, 0xAFC6, 0x8547, 0xAFC7, 0xB2DD, 0xAFC8, 0xB2DE, 0xAFC9, 0xB2DF, 0xAFCA, 0x8548, 0xAFCB, 0xB2E0, - 0xAFCC, 0x8549, 0xAFCD, 0xB2E1, 0xAFCE, 0xB2E2, 0xAFCF, 0x854A, 0xAFD0, 0x854B, 0xAFD1, 0x854C, 0xAFD2, 0x854D, 0xAFD3, 0x854E, - 0xAFD4, 0xB2E3, 0xAFD5, 0x854F, 0xAFD6, 0x8550, 0xAFD7, 0x8551, 0xAFD8, 0x8552, 0xAFD9, 0x8553, 0xAFDA, 0x8554, 0xAFDB, 0x8555, - 0xAFDC, 0xB2E4, 0xAFDD, 0x8556, 0xAFDE, 0x8557, 0xAFDF, 0x8558, 0xAFE0, 0x8559, 0xAFE1, 0x855A, 0xAFE2, 0x8561, 0xAFE3, 0x8562, - 0xAFE4, 0x8563, 0xAFE5, 0x8564, 0xAFE6, 0x8565, 0xAFE7, 0x8566, 0xAFE8, 0xB2E5, 0xAFE9, 0xB2E6, 0xAFEA, 0x8567, 0xAFEB, 0x8568, - 0xAFEC, 0x8569, 0xAFED, 0x856A, 0xAFEE, 0x856B, 0xAFEF, 0x856C, 0xAFF0, 0xB2E7, 0xAFF1, 0xB2E8, 0xAFF2, 0x856D, 0xAFF3, 0x856E, - 0xAFF4, 0xB2E9, 0xAFF5, 0x856F, 0xAFF6, 0x8570, 0xAFF7, 0x8571, 0xAFF8, 0xB2EA, 0xAFF9, 0x8572, 0xAFFA, 0x8573, 0xAFFB, 0x8574, - 0xAFFC, 0x8575, 0xAFFD, 0x8576, 0xAFFE, 0x8577, 0xAFFF, 0x8578, 0xB000, 0xB2EB, 0xB001, 0xB2EC, 0xB002, 0x8579, 0xB003, 0x857A, - 0xB004, 0xB2ED, 0xB005, 0x8581, 0xB006, 0x8582, 0xB007, 0x8583, 0xB008, 0x8584, 0xB009, 0x8585, 0xB00A, 0x8586, 0xB00B, 0x8587, - 0xB00C, 0xB2EE, 0xB00D, 0x8588, 0xB00E, 0x8589, 0xB00F, 0x858A, 0xB010, 0xB2EF, 0xB011, 0x858B, 0xB012, 0x858C, 0xB013, 0x858D, - 0xB014, 0xB2F0, 0xB015, 0x858E, 0xB016, 0x858F, 0xB017, 0x8590, 0xB018, 0x8591, 0xB019, 0x8592, 0xB01A, 0x8593, 0xB01B, 0x8594, - 0xB01C, 0xB2F1, 0xB01D, 0xB2F2, 0xB01E, 0x8595, 0xB01F, 0x8596, 0xB020, 0x8597, 0xB021, 0x8598, 0xB022, 0x8599, 0xB023, 0x859A, - 0xB024, 0x859B, 0xB025, 0x859C, 0xB026, 0x859D, 0xB027, 0x859E, 0xB028, 0xB2F3, 0xB029, 0x859F, 0xB02A, 0x85A0, 0xB02B, 0x85A1, - 0xB02C, 0x85A2, 0xB02D, 0x85A3, 0xB02E, 0x85A4, 0xB02F, 0x85A5, 0xB030, 0x85A6, 0xB031, 0x85A7, 0xB032, 0x85A8, 0xB033, 0x85A9, - 0xB034, 0x85AA, 0xB035, 0x85AB, 0xB036, 0x85AC, 0xB037, 0x85AD, 0xB038, 0x85AE, 0xB039, 0x85AF, 0xB03A, 0x85B0, 0xB03B, 0x85B1, - 0xB03C, 0x85B2, 0xB03D, 0x85B3, 0xB03E, 0x85B4, 0xB03F, 0x85B5, 0xB040, 0x85B6, 0xB041, 0x85B7, 0xB042, 0x85B8, 0xB043, 0x85B9, - 0xB044, 0xB2F4, 0xB045, 0xB2F5, 0xB046, 0x85BA, 0xB047, 0x85BB, 0xB048, 0xB2F6, 0xB049, 0x85BC, 0xB04A, 0xB2F7, 0xB04B, 0x85BD, - 0xB04C, 0xB2F8, 0xB04D, 0x85BE, 0xB04E, 0xB2F9, 0xB04F, 0x85BF, 0xB050, 0x85C0, 0xB051, 0x85C1, 0xB052, 0x85C2, 0xB053, 0xB2FA, - 0xB054, 0xB2FB, 0xB055, 0xB2FC, 0xB056, 0x85C3, 0xB057, 0xB2FD, 0xB058, 0x85C4, 0xB059, 0xB2FE, 0xB05A, 0x85C5, 0xB05B, 0x85C6, - 0xB05C, 0x85C7, 0xB05D, 0xB3A1, 0xB05E, 0x85C8, 0xB05F, 0x85C9, 0xB060, 0x85CA, 0xB061, 0x85CB, 0xB062, 0x85CC, 0xB063, 0x85CD, - 0xB064, 0x85CE, 0xB065, 0x85CF, 0xB066, 0x85D0, 0xB067, 0x85D1, 0xB068, 0x85D2, 0xB069, 0x85D3, 0xB06A, 0x85D4, 0xB06B, 0x85D5, - 0xB06C, 0x85D6, 0xB06D, 0x85D7, 0xB06E, 0x85D8, 0xB06F, 0x85D9, 0xB070, 0x85DA, 0xB071, 0x85DB, 0xB072, 0x85DC, 0xB073, 0x85DD, - 0xB074, 0x85DE, 0xB075, 0x85DF, 0xB076, 0x85E0, 0xB077, 0x85E1, 0xB078, 0x85E2, 0xB079, 0x85E3, 0xB07A, 0x85E4, 0xB07B, 0x85E5, - 0xB07C, 0xB3A2, 0xB07D, 0xB3A3, 0xB07E, 0x85E6, 0xB07F, 0x85E7, 0xB080, 0xB3A4, 0xB081, 0x85E8, 0xB082, 0x85E9, 0xB083, 0x85EA, - 0xB084, 0xB3A5, 0xB085, 0x85EB, 0xB086, 0x85EC, 0xB087, 0x85ED, 0xB088, 0x85EE, 0xB089, 0x85EF, 0xB08A, 0x85F0, 0xB08B, 0x85F1, - 0xB08C, 0xB3A6, 0xB08D, 0xB3A7, 0xB08E, 0x85F2, 0xB08F, 0xB3A8, 0xB090, 0x85F3, 0xB091, 0xB3A9, 0xB092, 0x85F4, 0xB093, 0x85F5, - 0xB094, 0x85F6, 0xB095, 0x85F7, 0xB096, 0x85F8, 0xB097, 0x85F9, 0xB098, 0xB3AA, 0xB099, 0xB3AB, 0xB09A, 0xB3AC, 0xB09B, 0x85FA, - 0xB09C, 0xB3AD, 0xB09D, 0x85FB, 0xB09E, 0x85FC, 0xB09F, 0xB3AE, 0xB0A0, 0xB3AF, 0xB0A1, 0xB3B0, 0xB0A2, 0xB3B1, 0xB0A3, 0x85FD, - 0xB0A4, 0x85FE, 0xB0A5, 0x8641, 0xB0A6, 0x8642, 0xB0A7, 0x8643, 0xB0A8, 0xB3B2, 0xB0A9, 0xB3B3, 0xB0AA, 0x8644, 0xB0AB, 0xB3B4, - 0xB0AC, 0xB3B5, 0xB0AD, 0xB3B6, 0xB0AE, 0xB3B7, 0xB0AF, 0xB3B8, 0xB0B0, 0x8645, 0xB0B1, 0xB3B9, 0xB0B2, 0x8646, 0xB0B3, 0xB3BA, - 0xB0B4, 0xB3BB, 0xB0B5, 0xB3BC, 0xB0B6, 0x8647, 0xB0B7, 0x8648, 0xB0B8, 0xB3BD, 0xB0B9, 0x8649, 0xB0BA, 0x864A, 0xB0BB, 0x864B, - 0xB0BC, 0xB3BE, 0xB0BD, 0x864C, 0xB0BE, 0x864D, 0xB0BF, 0x864E, 0xB0C0, 0x864F, 0xB0C1, 0x8650, 0xB0C2, 0x8651, 0xB0C3, 0x8652, - 0xB0C4, 0xB3BF, 0xB0C5, 0xB3C0, 0xB0C6, 0x8653, 0xB0C7, 0xB3C1, 0xB0C8, 0xB3C2, 0xB0C9, 0xB3C3, 0xB0CA, 0x8654, 0xB0CB, 0x8655, - 0xB0CC, 0x8656, 0xB0CD, 0x8657, 0xB0CE, 0x8658, 0xB0CF, 0x8659, 0xB0D0, 0xB3C4, 0xB0D1, 0xB3C5, 0xB0D2, 0x865A, 0xB0D3, 0x8661, - 0xB0D4, 0xB3C6, 0xB0D5, 0x8662, 0xB0D6, 0x8663, 0xB0D7, 0x8664, 0xB0D8, 0xB3C7, 0xB0D9, 0x8665, 0xB0DA, 0x8666, 0xB0DB, 0x8667, - 0xB0DC, 0x8668, 0xB0DD, 0x8669, 0xB0DE, 0x866A, 0xB0DF, 0x866B, 0xB0E0, 0xB3C8, 0xB0E1, 0x866C, 0xB0E2, 0x866D, 0xB0E3, 0x866E, - 0xB0E4, 0x866F, 0xB0E5, 0xB3C9, 0xB0E6, 0x8670, 0xB0E7, 0x8671, 0xB0E8, 0x8672, 0xB0E9, 0x8673, 0xB0EA, 0x8674, 0xB0EB, 0x8675, - 0xB0EC, 0x8676, 0xB0ED, 0x8677, 0xB0EE, 0x8678, 0xB0EF, 0x8679, 0xB0F0, 0x867A, 0xB0F1, 0x8681, 0xB0F2, 0x8682, 0xB0F3, 0x8683, - 0xB0F4, 0x8684, 0xB0F5, 0x8685, 0xB0F6, 0x8686, 0xB0F7, 0x8687, 0xB0F8, 0x8688, 0xB0F9, 0x8689, 0xB0FA, 0x868A, 0xB0FB, 0x868B, - 0xB0FC, 0x868C, 0xB0FD, 0x868D, 0xB0FE, 0x868E, 0xB0FF, 0x868F, 0xB100, 0x8690, 0xB101, 0x8691, 0xB102, 0x8692, 0xB103, 0x8693, - 0xB104, 0x8694, 0xB105, 0x8695, 0xB106, 0x8696, 0xB107, 0x8697, 0xB108, 0xB3CA, 0xB109, 0xB3CB, 0xB10A, 0x8698, 0xB10B, 0xB3CC, - 0xB10C, 0xB3CD, 0xB10D, 0x8699, 0xB10E, 0x869A, 0xB10F, 0x869B, 0xB110, 0xB3CE, 0xB111, 0x869C, 0xB112, 0xB3CF, 0xB113, 0xB3D0, - 0xB114, 0x869D, 0xB115, 0x869E, 0xB116, 0x869F, 0xB117, 0x86A0, 0xB118, 0xB3D1, 0xB119, 0xB3D2, 0xB11A, 0x86A1, 0xB11B, 0xB3D3, - 0xB11C, 0xB3D4, 0xB11D, 0xB3D5, 0xB11E, 0x86A2, 0xB11F, 0x86A3, 0xB120, 0x86A4, 0xB121, 0x86A5, 0xB122, 0x86A6, 0xB123, 0xB3D6, - 0xB124, 0xB3D7, 0xB125, 0xB3D8, 0xB126, 0x86A7, 0xB127, 0x86A8, 0xB128, 0xB3D9, 0xB129, 0x86A9, 0xB12A, 0x86AA, 0xB12B, 0x86AB, - 0xB12C, 0xB3DA, 0xB12D, 0x86AC, 0xB12E, 0x86AD, 0xB12F, 0x86AE, 0xB130, 0x86AF, 0xB131, 0x86B0, 0xB132, 0x86B1, 0xB133, 0x86B2, - 0xB134, 0xB3DB, 0xB135, 0xB3DC, 0xB136, 0x86B3, 0xB137, 0xB3DD, 0xB138, 0xB3DE, 0xB139, 0xB3DF, 0xB13A, 0x86B4, 0xB13B, 0x86B5, - 0xB13C, 0x86B6, 0xB13D, 0x86B7, 0xB13E, 0x86B8, 0xB13F, 0x86B9, 0xB140, 0xB3E0, 0xB141, 0xB3E1, 0xB142, 0x86BA, 0xB143, 0x86BB, - 0xB144, 0xB3E2, 0xB145, 0x86BC, 0xB146, 0x86BD, 0xB147, 0x86BE, 0xB148, 0xB3E3, 0xB149, 0x86BF, 0xB14A, 0x86C0, 0xB14B, 0x86C1, - 0xB14C, 0x86C2, 0xB14D, 0x86C3, 0xB14E, 0x86C4, 0xB14F, 0x86C5, 0xB150, 0xB3E4, 0xB151, 0xB3E5, 0xB152, 0x86C6, 0xB153, 0x86C7, - 0xB154, 0xB3E6, 0xB155, 0xB3E7, 0xB156, 0x86C8, 0xB157, 0x86C9, 0xB158, 0xB3E8, 0xB159, 0x86CA, 0xB15A, 0x86CB, 0xB15B, 0x86CC, - 0xB15C, 0xB3E9, 0xB15D, 0x86CD, 0xB15E, 0x86CE, 0xB15F, 0x86CF, 0xB160, 0xB3EA, 0xB161, 0x86D0, 0xB162, 0x86D1, 0xB163, 0x86D2, - 0xB164, 0x86D3, 0xB165, 0x86D4, 0xB166, 0x86D5, 0xB167, 0x86D6, 0xB168, 0x86D7, 0xB169, 0x86D8, 0xB16A, 0x86D9, 0xB16B, 0x86DA, - 0xB16C, 0x86DB, 0xB16D, 0x86DC, 0xB16E, 0x86DD, 0xB16F, 0x86DE, 0xB170, 0x86DF, 0xB171, 0x86E0, 0xB172, 0x86E1, 0xB173, 0x86E2, - 0xB174, 0x86E3, 0xB175, 0x86E4, 0xB176, 0x86E5, 0xB177, 0x86E6, 0xB178, 0xB3EB, 0xB179, 0xB3EC, 0xB17A, 0x86E7, 0xB17B, 0x86E8, - 0xB17C, 0xB3ED, 0xB17D, 0x86E9, 0xB17E, 0x86EA, 0xB17F, 0x86EB, 0xB180, 0xB3EE, 0xB181, 0x86EC, 0xB182, 0xB3EF, 0xB183, 0x86ED, - 0xB184, 0x86EE, 0xB185, 0x86EF, 0xB186, 0x86F0, 0xB187, 0x86F1, 0xB188, 0xB3F0, 0xB189, 0xB3F1, 0xB18A, 0x86F2, 0xB18B, 0xB3F2, - 0xB18C, 0x86F3, 0xB18D, 0xB3F3, 0xB18E, 0x86F4, 0xB18F, 0x86F5, 0xB190, 0x86F6, 0xB191, 0x86F7, 0xB192, 0xB3F4, 0xB193, 0xB3F5, - 0xB194, 0xB3F6, 0xB195, 0x86F8, 0xB196, 0x86F9, 0xB197, 0x86FA, 0xB198, 0xB3F7, 0xB199, 0x86FB, 0xB19A, 0x86FC, 0xB19B, 0x86FD, - 0xB19C, 0xB3F8, 0xB19D, 0x86FE, 0xB19E, 0x8741, 0xB19F, 0x8742, 0xB1A0, 0x8743, 0xB1A1, 0x8744, 0xB1A2, 0x8745, 0xB1A3, 0x8746, - 0xB1A4, 0x8747, 0xB1A5, 0x8748, 0xB1A6, 0x8749, 0xB1A7, 0x874A, 0xB1A8, 0xB3F9, 0xB1A9, 0x874B, 0xB1AA, 0x874C, 0xB1AB, 0x874D, - 0xB1AC, 0x874E, 0xB1AD, 0x874F, 0xB1AE, 0x8750, 0xB1AF, 0x8751, 0xB1B0, 0x8752, 0xB1B1, 0x8753, 0xB1B2, 0x8754, 0xB1B3, 0x8755, - 0xB1B4, 0x8756, 0xB1B5, 0x8757, 0xB1B6, 0x8758, 0xB1B7, 0x8759, 0xB1B8, 0x875A, 0xB1B9, 0x8761, 0xB1BA, 0x8762, 0xB1BB, 0x8763, - 0xB1BC, 0x8764, 0xB1BD, 0x8765, 0xB1BE, 0x8766, 0xB1BF, 0x8767, 0xB1C0, 0x8768, 0xB1C1, 0x8769, 0xB1C2, 0x876A, 0xB1C3, 0x876B, - 0xB1C4, 0x876C, 0xB1C5, 0x876D, 0xB1C6, 0x876E, 0xB1C7, 0x876F, 0xB1C8, 0x8770, 0xB1C9, 0x8771, 0xB1CA, 0x8772, 0xB1CB, 0x8773, - 0xB1CC, 0xB3FA, 0xB1CD, 0x8774, 0xB1CE, 0x8775, 0xB1CF, 0x8776, 0xB1D0, 0xB3FB, 0xB1D1, 0x8777, 0xB1D2, 0x8778, 0xB1D3, 0x8779, - 0xB1D4, 0xB3FC, 0xB1D5, 0x877A, 0xB1D6, 0x8781, 0xB1D7, 0x8782, 0xB1D8, 0x8783, 0xB1D9, 0x8784, 0xB1DA, 0x8785, 0xB1DB, 0x8786, - 0xB1DC, 0xB3FD, 0xB1DD, 0xB3FE, 0xB1DE, 0x8787, 0xB1DF, 0xB4A1, 0xB1E0, 0x8788, 0xB1E1, 0x8789, 0xB1E2, 0x878A, 0xB1E3, 0x878B, - 0xB1E4, 0x878C, 0xB1E5, 0x878D, 0xB1E6, 0x878E, 0xB1E7, 0x878F, 0xB1E8, 0xB4A2, 0xB1E9, 0xB4A3, 0xB1EA, 0x8790, 0xB1EB, 0x8791, - 0xB1EC, 0xB4A4, 0xB1ED, 0x8792, 0xB1EE, 0x8793, 0xB1EF, 0x8794, 0xB1F0, 0xB4A5, 0xB1F1, 0x8795, 0xB1F2, 0x8796, 0xB1F3, 0x8797, - 0xB1F4, 0x8798, 0xB1F5, 0x8799, 0xB1F6, 0x879A, 0xB1F7, 0x879B, 0xB1F8, 0x879C, 0xB1F9, 0xB4A6, 0xB1FA, 0x879D, 0xB1FB, 0xB4A7, - 0xB1FC, 0x879E, 0xB1FD, 0xB4A8, 0xB1FE, 0x879F, 0xB1FF, 0x87A0, 0xB200, 0x87A1, 0xB201, 0x87A2, 0xB202, 0x87A3, 0xB203, 0x87A4, - 0xB204, 0xB4A9, 0xB205, 0xB4AA, 0xB206, 0x87A5, 0xB207, 0x87A6, 0xB208, 0xB4AB, 0xB209, 0x87A7, 0xB20A, 0x87A8, 0xB20B, 0xB4AC, - 0xB20C, 0xB4AD, 0xB20D, 0x87A9, 0xB20E, 0x87AA, 0xB20F, 0x87AB, 0xB210, 0x87AC, 0xB211, 0x87AD, 0xB212, 0x87AE, 0xB213, 0x87AF, - 0xB214, 0xB4AE, 0xB215, 0xB4AF, 0xB216, 0x87B0, 0xB217, 0xB4B0, 0xB218, 0x87B1, 0xB219, 0xB4B1, 0xB21A, 0x87B2, 0xB21B, 0x87B3, - 0xB21C, 0x87B4, 0xB21D, 0x87B5, 0xB21E, 0x87B6, 0xB21F, 0x87B7, 0xB220, 0xB4B2, 0xB221, 0x87B8, 0xB222, 0x87B9, 0xB223, 0x87BA, - 0xB224, 0x87BB, 0xB225, 0x87BC, 0xB226, 0x87BD, 0xB227, 0x87BE, 0xB228, 0x87BF, 0xB229, 0x87C0, 0xB22A, 0x87C1, 0xB22B, 0x87C2, - 0xB22C, 0x87C3, 0xB22D, 0x87C4, 0xB22E, 0x87C5, 0xB22F, 0x87C6, 0xB230, 0x87C7, 0xB231, 0x87C8, 0xB232, 0x87C9, 0xB233, 0x87CA, - 0xB234, 0xB4B3, 0xB235, 0x87CB, 0xB236, 0x87CC, 0xB237, 0x87CD, 0xB238, 0x87CE, 0xB239, 0x87CF, 0xB23A, 0x87D0, 0xB23B, 0x87D1, - 0xB23C, 0xB4B4, 0xB23D, 0x87D2, 0xB23E, 0x87D3, 0xB23F, 0x87D4, 0xB240, 0x87D5, 0xB241, 0x87D6, 0xB242, 0x87D7, 0xB243, 0x87D8, - 0xB244, 0x87D9, 0xB245, 0x87DA, 0xB246, 0x87DB, 0xB247, 0x87DC, 0xB248, 0x87DD, 0xB249, 0x87DE, 0xB24A, 0x87DF, 0xB24B, 0x87E0, - 0xB24C, 0x87E1, 0xB24D, 0x87E2, 0xB24E, 0x87E3, 0xB24F, 0x87E4, 0xB250, 0x87E5, 0xB251, 0x87E6, 0xB252, 0x87E7, 0xB253, 0x87E8, - 0xB254, 0x87E9, 0xB255, 0x87EA, 0xB256, 0x87EB, 0xB257, 0x87EC, 0xB258, 0xB4B5, 0xB259, 0x87ED, 0xB25A, 0x87EE, 0xB25B, 0x87EF, - 0xB25C, 0xB4B6, 0xB25D, 0x87F0, 0xB25E, 0x87F1, 0xB25F, 0x87F2, 0xB260, 0xB4B7, 0xB261, 0x87F3, 0xB262, 0x87F4, 0xB263, 0x87F5, - 0xB264, 0x87F6, 0xB265, 0x87F7, 0xB266, 0x87F8, 0xB267, 0x87F9, 0xB268, 0xB4B8, 0xB269, 0xB4B9, 0xB26A, 0x87FA, 0xB26B, 0x87FB, - 0xB26C, 0x87FC, 0xB26D, 0x87FD, 0xB26E, 0x87FE, 0xB26F, 0x8841, 0xB270, 0x8842, 0xB271, 0x8843, 0xB272, 0x8844, 0xB273, 0x8845, - 0xB274, 0xB4BA, 0xB275, 0xB4BB, 0xB276, 0x8846, 0xB277, 0x8847, 0xB278, 0x8848, 0xB279, 0x8849, 0xB27A, 0x884A, 0xB27B, 0x884B, - 0xB27C, 0xB4BC, 0xB27D, 0x884C, 0xB27E, 0x884D, 0xB27F, 0x884E, 0xB280, 0x884F, 0xB281, 0x8850, 0xB282, 0x8851, 0xB283, 0x8852, - 0xB284, 0xB4BD, 0xB285, 0xB4BE, 0xB286, 0x8853, 0xB287, 0x8854, 0xB288, 0x8855, 0xB289, 0xB4BF, 0xB28A, 0x8856, 0xB28B, 0x8857, - 0xB28C, 0x8858, 0xB28D, 0x8859, 0xB28E, 0x885A, 0xB28F, 0x8861, 0xB290, 0xB4C0, 0xB291, 0xB4C1, 0xB292, 0x8862, 0xB293, 0x8863, - 0xB294, 0xB4C2, 0xB295, 0x8864, 0xB296, 0x8865, 0xB297, 0x8866, 0xB298, 0xB4C3, 0xB299, 0xB4C4, 0xB29A, 0xB4C5, 0xB29B, 0x8867, - 0xB29C, 0x8868, 0xB29D, 0x8869, 0xB29E, 0x886A, 0xB29F, 0x886B, 0xB2A0, 0xB4C6, 0xB2A1, 0xB4C7, 0xB2A2, 0x886C, 0xB2A3, 0xB4C8, - 0xB2A4, 0x886D, 0xB2A5, 0xB4C9, 0xB2A6, 0xB4CA, 0xB2A7, 0x886E, 0xB2A8, 0x886F, 0xB2A9, 0x8870, 0xB2AA, 0xB4CB, 0xB2AB, 0x8871, - 0xB2AC, 0xB4CC, 0xB2AD, 0x8872, 0xB2AE, 0x8873, 0xB2AF, 0x8874, 0xB2B0, 0xB4CD, 0xB2B1, 0x8875, 0xB2B2, 0x8876, 0xB2B3, 0x8877, - 0xB2B4, 0xB4CE, 0xB2B5, 0x8878, 0xB2B6, 0x8879, 0xB2B7, 0x887A, 0xB2B8, 0x8881, 0xB2B9, 0x8882, 0xB2BA, 0x8883, 0xB2BB, 0x8884, - 0xB2BC, 0x8885, 0xB2BD, 0x8886, 0xB2BE, 0x8887, 0xB2BF, 0x8888, 0xB2C0, 0x8889, 0xB2C1, 0x888A, 0xB2C2, 0x888B, 0xB2C3, 0x888C, - 0xB2C4, 0x888D, 0xB2C5, 0x888E, 0xB2C6, 0x888F, 0xB2C7, 0x8890, 0xB2C8, 0xB4CF, 0xB2C9, 0xB4D0, 0xB2CA, 0x8891, 0xB2CB, 0x8892, - 0xB2CC, 0xB4D1, 0xB2CD, 0x8893, 0xB2CE, 0x8894, 0xB2CF, 0x8895, 0xB2D0, 0xB4D2, 0xB2D1, 0x8896, 0xB2D2, 0xB4D3, 0xB2D3, 0x8897, - 0xB2D4, 0x8898, 0xB2D5, 0x8899, 0xB2D6, 0x889A, 0xB2D7, 0x889B, 0xB2D8, 0xB4D4, 0xB2D9, 0xB4D5, 0xB2DA, 0x889C, 0xB2DB, 0xB4D6, - 0xB2DC, 0x889D, 0xB2DD, 0xB4D7, 0xB2DE, 0x889E, 0xB2DF, 0x889F, 0xB2E0, 0x88A0, 0xB2E1, 0x88A1, 0xB2E2, 0xB4D8, 0xB2E3, 0x88A2, - 0xB2E4, 0xB4D9, 0xB2E5, 0xB4DA, 0xB2E6, 0xB4DB, 0xB2E7, 0x88A3, 0xB2E8, 0xB4DC, 0xB2E9, 0x88A4, 0xB2EA, 0x88A5, 0xB2EB, 0xB4DD, - 0xB2EC, 0xB4DE, 0xB2ED, 0xB4DF, 0xB2EE, 0xB4E0, 0xB2EF, 0xB4E1, 0xB2F0, 0x88A6, 0xB2F1, 0x88A7, 0xB2F2, 0x88A8, 0xB2F3, 0xB4E2, - 0xB2F4, 0xB4E3, 0xB2F5, 0xB4E4, 0xB2F6, 0x88A9, 0xB2F7, 0xB4E5, 0xB2F8, 0xB4E6, 0xB2F9, 0xB4E7, 0xB2FA, 0xB4E8, 0xB2FB, 0xB4E9, - 0xB2FC, 0x88AA, 0xB2FD, 0x88AB, 0xB2FE, 0x88AC, 0xB2FF, 0xB4EA, 0xB300, 0xB4EB, 0xB301, 0xB4EC, 0xB302, 0x88AD, 0xB303, 0x88AE, - 0xB304, 0xB4ED, 0xB305, 0x88AF, 0xB306, 0x88B0, 0xB307, 0x88B1, 0xB308, 0xB4EE, 0xB309, 0x88B2, 0xB30A, 0x88B3, 0xB30B, 0x88B4, - 0xB30C, 0x88B5, 0xB30D, 0x88B6, 0xB30E, 0x88B7, 0xB30F, 0x88B8, 0xB310, 0xB4EF, 0xB311, 0xB4F0, 0xB312, 0x88B9, 0xB313, 0xB4F1, - 0xB314, 0xB4F2, 0xB315, 0xB4F3, 0xB316, 0x88BA, 0xB317, 0x88BB, 0xB318, 0x88BC, 0xB319, 0x88BD, 0xB31A, 0x88BE, 0xB31B, 0x88BF, - 0xB31C, 0xB4F4, 0xB31D, 0x88C0, 0xB31E, 0x88C1, 0xB31F, 0x88C2, 0xB320, 0x88C3, 0xB321, 0x88C4, 0xB322, 0x88C5, 0xB323, 0x88C6, - 0xB324, 0x88C7, 0xB325, 0x88C8, 0xB326, 0x88C9, 0xB327, 0x88CA, 0xB328, 0x88CB, 0xB329, 0x88CC, 0xB32A, 0x88CD, 0xB32B, 0x88CE, - 0xB32C, 0x88CF, 0xB32D, 0x88D0, 0xB32E, 0x88D1, 0xB32F, 0x88D2, 0xB330, 0x88D3, 0xB331, 0x88D4, 0xB332, 0x88D5, 0xB333, 0x88D6, - 0xB334, 0x88D7, 0xB335, 0x88D8, 0xB336, 0x88D9, 0xB337, 0x88DA, 0xB338, 0x88DB, 0xB339, 0x88DC, 0xB33A, 0x88DD, 0xB33B, 0x88DE, - 0xB33C, 0x88DF, 0xB33D, 0x88E0, 0xB33E, 0x88E1, 0xB33F, 0x88E2, 0xB340, 0x88E3, 0xB341, 0x88E4, 0xB342, 0x88E5, 0xB343, 0x88E6, - 0xB344, 0x88E7, 0xB345, 0x88E8, 0xB346, 0x88E9, 0xB347, 0x88EA, 0xB348, 0x88EB, 0xB349, 0x88EC, 0xB34A, 0x88ED, 0xB34B, 0x88EE, - 0xB34C, 0x88EF, 0xB34D, 0x88F0, 0xB34E, 0x88F1, 0xB34F, 0x88F2, 0xB350, 0x88F3, 0xB351, 0x88F4, 0xB352, 0x88F5, 0xB353, 0x88F6, - 0xB354, 0xB4F5, 0xB355, 0xB4F6, 0xB356, 0xB4F7, 0xB357, 0x88F7, 0xB358, 0xB4F8, 0xB359, 0x88F8, 0xB35A, 0x88F9, 0xB35B, 0xB4F9, - 0xB35C, 0xB4FA, 0xB35D, 0x88FA, 0xB35E, 0xB4FB, 0xB35F, 0xB4FC, 0xB360, 0x88FB, 0xB361, 0x88FC, 0xB362, 0x88FD, 0xB363, 0x88FE, - 0xB364, 0xB4FD, 0xB365, 0xB4FE, 0xB366, 0x8941, 0xB367, 0xB5A1, 0xB368, 0x8942, 0xB369, 0xB5A2, 0xB36A, 0x8943, 0xB36B, 0xB5A3, - 0xB36C, 0x8944, 0xB36D, 0x8945, 0xB36E, 0xB5A4, 0xB36F, 0x8946, 0xB370, 0xB5A5, 0xB371, 0xB5A6, 0xB372, 0x8947, 0xB373, 0x8948, - 0xB374, 0xB5A7, 0xB375, 0x8949, 0xB376, 0x894A, 0xB377, 0x894B, 0xB378, 0xB5A8, 0xB379, 0x894C, 0xB37A, 0x894D, 0xB37B, 0x894E, - 0xB37C, 0x894F, 0xB37D, 0x8950, 0xB37E, 0x8951, 0xB37F, 0x8952, 0xB380, 0xB5A9, 0xB381, 0xB5AA, 0xB382, 0x8953, 0xB383, 0xB5AB, - 0xB384, 0xB5AC, 0xB385, 0xB5AD, 0xB386, 0x8954, 0xB387, 0x8955, 0xB388, 0x8956, 0xB389, 0x8957, 0xB38A, 0x8958, 0xB38B, 0x8959, - 0xB38C, 0xB5AE, 0xB38D, 0x895A, 0xB38E, 0x8961, 0xB38F, 0x8962, 0xB390, 0xB5AF, 0xB391, 0x8963, 0xB392, 0x8964, 0xB393, 0x8965, - 0xB394, 0xB5B0, 0xB395, 0x8966, 0xB396, 0x8967, 0xB397, 0x8968, 0xB398, 0x8969, 0xB399, 0x896A, 0xB39A, 0x896B, 0xB39B, 0x896C, - 0xB39C, 0x896D, 0xB39D, 0x896E, 0xB39E, 0x896F, 0xB39F, 0x8970, 0xB3A0, 0xB5B1, 0xB3A1, 0xB5B2, 0xB3A2, 0x8971, 0xB3A3, 0x8972, - 0xB3A4, 0x8973, 0xB3A5, 0x8974, 0xB3A6, 0x8975, 0xB3A7, 0x8976, 0xB3A8, 0xB5B3, 0xB3A9, 0x8977, 0xB3AA, 0x8978, 0xB3AB, 0x8979, - 0xB3AC, 0xB5B4, 0xB3AD, 0x897A, 0xB3AE, 0x8981, 0xB3AF, 0x8982, 0xB3B0, 0x8983, 0xB3B1, 0x8984, 0xB3B2, 0x8985, 0xB3B3, 0x8986, - 0xB3B4, 0x8987, 0xB3B5, 0x8988, 0xB3B6, 0x8989, 0xB3B7, 0x898A, 0xB3B8, 0x898B, 0xB3B9, 0x898C, 0xB3BA, 0x898D, 0xB3BB, 0x898E, - 0xB3BC, 0x898F, 0xB3BD, 0x8990, 0xB3BE, 0x8991, 0xB3BF, 0x8992, 0xB3C0, 0x8993, 0xB3C1, 0x8994, 0xB3C2, 0x8995, 0xB3C3, 0x8996, - 0xB3C4, 0xB5B5, 0xB3C5, 0xB5B6, 0xB3C6, 0x8997, 0xB3C7, 0x8998, 0xB3C8, 0xB5B7, 0xB3C9, 0x8999, 0xB3CA, 0x899A, 0xB3CB, 0xB5B8, - 0xB3CC, 0xB5B9, 0xB3CD, 0x899B, 0xB3CE, 0xB5BA, 0xB3CF, 0x899C, 0xB3D0, 0xB5BB, 0xB3D1, 0x899D, 0xB3D2, 0x899E, 0xB3D3, 0x899F, - 0xB3D4, 0xB5BC, 0xB3D5, 0xB5BD, 0xB3D6, 0x89A0, 0xB3D7, 0xB5BE, 0xB3D8, 0x89A1, 0xB3D9, 0xB5BF, 0xB3DA, 0x89A2, 0xB3DB, 0xB5C0, - 0xB3DC, 0x89A3, 0xB3DD, 0xB5C1, 0xB3DE, 0x89A4, 0xB3DF, 0x89A5, 0xB3E0, 0xB5C2, 0xB3E1, 0x89A6, 0xB3E2, 0x89A7, 0xB3E3, 0x89A8, - 0xB3E4, 0xB5C3, 0xB3E5, 0x89A9, 0xB3E6, 0x89AA, 0xB3E7, 0x89AB, 0xB3E8, 0xB5C4, 0xB3E9, 0x89AC, 0xB3EA, 0x89AD, 0xB3EB, 0x89AE, - 0xB3EC, 0x89AF, 0xB3ED, 0x89B0, 0xB3EE, 0x89B1, 0xB3EF, 0x89B2, 0xB3F0, 0x89B3, 0xB3F1, 0x89B4, 0xB3F2, 0x89B5, 0xB3F3, 0x89B6, - 0xB3F4, 0x89B7, 0xB3F5, 0x89B8, 0xB3F6, 0x89B9, 0xB3F7, 0x89BA, 0xB3F8, 0x89BB, 0xB3F9, 0x89BC, 0xB3FA, 0x89BD, 0xB3FB, 0x89BE, - 0xB3FC, 0xB5C5, 0xB3FD, 0x89BF, 0xB3FE, 0x89C0, 0xB3FF, 0x89C1, 0xB400, 0x89C2, 0xB401, 0x89C3, 0xB402, 0x89C4, 0xB403, 0x89C5, - 0xB404, 0x89C6, 0xB405, 0x89C7, 0xB406, 0x89C8, 0xB407, 0x89C9, 0xB408, 0x89CA, 0xB409, 0x89CB, 0xB40A, 0x89CC, 0xB40B, 0x89CD, - 0xB40C, 0x89CE, 0xB40D, 0x89CF, 0xB40E, 0x89D0, 0xB40F, 0x89D1, 0xB410, 0xB5C6, 0xB411, 0x89D2, 0xB412, 0x89D3, 0xB413, 0x89D4, - 0xB414, 0x89D5, 0xB415, 0x89D6, 0xB416, 0x89D7, 0xB417, 0x89D8, 0xB418, 0xB5C7, 0xB419, 0x89D9, 0xB41A, 0x89DA, 0xB41B, 0x89DB, - 0xB41C, 0xB5C8, 0xB41D, 0x89DC, 0xB41E, 0x89DD, 0xB41F, 0x89DE, 0xB420, 0xB5C9, 0xB421, 0x89DF, 0xB422, 0x89E0, 0xB423, 0x89E1, - 0xB424, 0x89E2, 0xB425, 0x89E3, 0xB426, 0x89E4, 0xB427, 0x89E5, 0xB428, 0xB5CA, 0xB429, 0xB5CB, 0xB42A, 0x89E6, 0xB42B, 0xB5CC, - 0xB42C, 0x89E7, 0xB42D, 0x89E8, 0xB42E, 0x89E9, 0xB42F, 0x89EA, 0xB430, 0x89EB, 0xB431, 0x89EC, 0xB432, 0x89ED, 0xB433, 0x89EE, - 0xB434, 0xB5CD, 0xB435, 0x89EF, 0xB436, 0x89F0, 0xB437, 0x89F1, 0xB438, 0x89F2, 0xB439, 0x89F3, 0xB43A, 0x89F4, 0xB43B, 0x89F5, - 0xB43C, 0x89F6, 0xB43D, 0x89F7, 0xB43E, 0x89F8, 0xB43F, 0x89F9, 0xB440, 0x89FA, 0xB441, 0x89FB, 0xB442, 0x89FC, 0xB443, 0x89FD, - 0xB444, 0x89FE, 0xB445, 0x8A41, 0xB446, 0x8A42, 0xB447, 0x8A43, 0xB448, 0x8A44, 0xB449, 0x8A45, 0xB44A, 0x8A46, 0xB44B, 0x8A47, - 0xB44C, 0x8A48, 0xB44D, 0x8A49, 0xB44E, 0x8A4A, 0xB44F, 0x8A4B, 0xB450, 0xB5CE, 0xB451, 0xB5CF, 0xB452, 0x8A4C, 0xB453, 0x8A4D, - 0xB454, 0xB5D0, 0xB455, 0x8A4E, 0xB456, 0x8A4F, 0xB457, 0x8A50, 0xB458, 0xB5D1, 0xB459, 0x8A51, 0xB45A, 0x8A52, 0xB45B, 0x8A53, - 0xB45C, 0x8A54, 0xB45D, 0x8A55, 0xB45E, 0x8A56, 0xB45F, 0x8A57, 0xB460, 0xB5D2, 0xB461, 0xB5D3, 0xB462, 0x8A58, 0xB463, 0xB5D4, - 0xB464, 0x8A59, 0xB465, 0xB5D5, 0xB466, 0x8A5A, 0xB467, 0x8A61, 0xB468, 0x8A62, 0xB469, 0x8A63, 0xB46A, 0x8A64, 0xB46B, 0x8A65, - 0xB46C, 0xB5D6, 0xB46D, 0x8A66, 0xB46E, 0x8A67, 0xB46F, 0x8A68, 0xB470, 0x8A69, 0xB471, 0x8A6A, 0xB472, 0x8A6B, 0xB473, 0x8A6C, - 0xB474, 0x8A6D, 0xB475, 0x8A6E, 0xB476, 0x8A6F, 0xB477, 0x8A70, 0xB478, 0x8A71, 0xB479, 0x8A72, 0xB47A, 0x8A73, 0xB47B, 0x8A74, - 0xB47C, 0x8A75, 0xB47D, 0x8A76, 0xB47E, 0x8A77, 0xB47F, 0x8A78, 0xB480, 0xB5D7, 0xB481, 0x8A79, 0xB482, 0x8A7A, 0xB483, 0x8A81, - 0xB484, 0x8A82, 0xB485, 0x8A83, 0xB486, 0x8A84, 0xB487, 0x8A85, 0xB488, 0xB5D8, 0xB489, 0x8A86, 0xB48A, 0x8A87, 0xB48B, 0x8A88, - 0xB48C, 0x8A89, 0xB48D, 0x8A8A, 0xB48E, 0x8A8B, 0xB48F, 0x8A8C, 0xB490, 0x8A8D, 0xB491, 0x8A8E, 0xB492, 0x8A8F, 0xB493, 0x8A90, - 0xB494, 0x8A91, 0xB495, 0x8A92, 0xB496, 0x8A93, 0xB497, 0x8A94, 0xB498, 0x8A95, 0xB499, 0x8A96, 0xB49A, 0x8A97, 0xB49B, 0x8A98, - 0xB49C, 0x8A99, 0xB49D, 0xB5D9, 0xB49E, 0x8A9A, 0xB49F, 0x8A9B, 0xB4A0, 0x8A9C, 0xB4A1, 0x8A9D, 0xB4A2, 0x8A9E, 0xB4A3, 0x8A9F, - 0xB4A4, 0xB5DA, 0xB4A5, 0x8AA0, 0xB4A6, 0x8AA1, 0xB4A7, 0x8AA2, 0xB4A8, 0xB5DB, 0xB4A9, 0x8AA3, 0xB4AA, 0x8AA4, 0xB4AB, 0x8AA5, - 0xB4AC, 0xB5DC, 0xB4AD, 0x8AA6, 0xB4AE, 0x8AA7, 0xB4AF, 0x8AA8, 0xB4B0, 0x8AA9, 0xB4B1, 0x8AAA, 0xB4B2, 0x8AAB, 0xB4B3, 0x8AAC, - 0xB4B4, 0x8AAD, 0xB4B5, 0xB5DD, 0xB4B6, 0x8AAE, 0xB4B7, 0xB5DE, 0xB4B8, 0x8AAF, 0xB4B9, 0xB5DF, 0xB4BA, 0x8AB0, 0xB4BB, 0x8AB1, - 0xB4BC, 0x8AB2, 0xB4BD, 0x8AB3, 0xB4BE, 0x8AB4, 0xB4BF, 0x8AB5, 0xB4C0, 0xB5E0, 0xB4C1, 0x8AB6, 0xB4C2, 0x8AB7, 0xB4C3, 0x8AB8, - 0xB4C4, 0xB5E1, 0xB4C5, 0x8AB9, 0xB4C6, 0x8ABA, 0xB4C7, 0x8ABB, 0xB4C8, 0xB5E2, 0xB4C9, 0x8ABC, 0xB4CA, 0x8ABD, 0xB4CB, 0x8ABE, - 0xB4CC, 0x8ABF, 0xB4CD, 0x8AC0, 0xB4CE, 0x8AC1, 0xB4CF, 0x8AC2, 0xB4D0, 0xB5E3, 0xB4D1, 0x8AC3, 0xB4D2, 0x8AC4, 0xB4D3, 0x8AC5, - 0xB4D4, 0x8AC6, 0xB4D5, 0xB5E4, 0xB4D6, 0x8AC7, 0xB4D7, 0x8AC8, 0xB4D8, 0x8AC9, 0xB4D9, 0x8ACA, 0xB4DA, 0x8ACB, 0xB4DB, 0x8ACC, - 0xB4DC, 0xB5E5, 0xB4DD, 0xB5E6, 0xB4DE, 0x8ACD, 0xB4DF, 0x8ACE, 0xB4E0, 0xB5E7, 0xB4E1, 0x8ACF, 0xB4E2, 0x8AD0, 0xB4E3, 0xB5E8, - 0xB4E4, 0xB5E9, 0xB4E5, 0x8AD1, 0xB4E6, 0xB5EA, 0xB4E7, 0x8AD2, 0xB4E8, 0x8AD3, 0xB4E9, 0x8AD4, 0xB4EA, 0x8AD5, 0xB4EB, 0x8AD6, - 0xB4EC, 0xB5EB, 0xB4ED, 0xB5EC, 0xB4EE, 0x8AD7, 0xB4EF, 0xB5ED, 0xB4F0, 0x8AD8, 0xB4F1, 0xB5EE, 0xB4F2, 0x8AD9, 0xB4F3, 0x8ADA, - 0xB4F4, 0x8ADB, 0xB4F5, 0x8ADC, 0xB4F6, 0x8ADD, 0xB4F7, 0x8ADE, 0xB4F8, 0xB5EF, 0xB4F9, 0x8ADF, 0xB4FA, 0x8AE0, 0xB4FB, 0x8AE1, - 0xB4FC, 0x8AE2, 0xB4FD, 0x8AE3, 0xB4FE, 0x8AE4, 0xB4FF, 0x8AE5, 0xB500, 0x8AE6, 0xB501, 0x8AE7, 0xB502, 0x8AE8, 0xB503, 0x8AE9, - 0xB504, 0x8AEA, 0xB505, 0x8AEB, 0xB506, 0x8AEC, 0xB507, 0x8AED, 0xB508, 0x8AEE, 0xB509, 0x8AEF, 0xB50A, 0x8AF0, 0xB50B, 0x8AF1, - 0xB50C, 0x8AF2, 0xB50D, 0x8AF3, 0xB50E, 0x8AF4, 0xB50F, 0x8AF5, 0xB510, 0x8AF6, 0xB511, 0x8AF7, 0xB512, 0x8AF8, 0xB513, 0x8AF9, - 0xB514, 0xB5F0, 0xB515, 0xB5F1, 0xB516, 0x8AFA, 0xB517, 0x8AFB, 0xB518, 0xB5F2, 0xB519, 0x8AFC, 0xB51A, 0x8AFD, 0xB51B, 0xB5F3, - 0xB51C, 0xB5F4, 0xB51D, 0x8AFE, 0xB51E, 0x8B41, 0xB51F, 0x8B42, 0xB520, 0x8B43, 0xB521, 0x8B44, 0xB522, 0x8B45, 0xB523, 0x8B46, - 0xB524, 0xB5F5, 0xB525, 0xB5F6, 0xB526, 0x8B47, 0xB527, 0xB5F7, 0xB528, 0xB5F8, 0xB529, 0xB5F9, 0xB52A, 0xB5FA, 0xB52B, 0x8B48, - 0xB52C, 0x8B49, 0xB52D, 0x8B4A, 0xB52E, 0x8B4B, 0xB52F, 0x8B4C, 0xB530, 0xB5FB, 0xB531, 0xB5FC, 0xB532, 0x8B4D, 0xB533, 0x8B4E, - 0xB534, 0xB5FD, 0xB535, 0x8B4F, 0xB536, 0x8B50, 0xB537, 0x8B51, 0xB538, 0xB5FE, 0xB539, 0x8B52, 0xB53A, 0x8B53, 0xB53B, 0x8B54, - 0xB53C, 0x8B55, 0xB53D, 0x8B56, 0xB53E, 0x8B57, 0xB53F, 0x8B58, 0xB540, 0xB6A1, 0xB541, 0xB6A2, 0xB542, 0x8B59, 0xB543, 0xB6A3, - 0xB544, 0xB6A4, 0xB545, 0xB6A5, 0xB546, 0x8B5A, 0xB547, 0x8B61, 0xB548, 0x8B62, 0xB549, 0x8B63, 0xB54A, 0x8B64, 0xB54B, 0xB6A6, - 0xB54C, 0xB6A7, 0xB54D, 0xB6A8, 0xB54E, 0x8B65, 0xB54F, 0x8B66, 0xB550, 0xB6A9, 0xB551, 0x8B67, 0xB552, 0x8B68, 0xB553, 0x8B69, - 0xB554, 0xB6AA, 0xB555, 0x8B6A, 0xB556, 0x8B6B, 0xB557, 0x8B6C, 0xB558, 0x8B6D, 0xB559, 0x8B6E, 0xB55A, 0x8B6F, 0xB55B, 0x8B70, - 0xB55C, 0xB6AB, 0xB55D, 0xB6AC, 0xB55E, 0x8B71, 0xB55F, 0xB6AD, 0xB560, 0xB6AE, 0xB561, 0xB6AF, 0xB562, 0x8B72, 0xB563, 0x8B73, - 0xB564, 0x8B74, 0xB565, 0x8B75, 0xB566, 0x8B76, 0xB567, 0x8B77, 0xB568, 0x8B78, 0xB569, 0x8B79, 0xB56A, 0x8B7A, 0xB56B, 0x8B81, - 0xB56C, 0x8B82, 0xB56D, 0x8B83, 0xB56E, 0x8B84, 0xB56F, 0x8B85, 0xB570, 0x8B86, 0xB571, 0x8B87, 0xB572, 0x8B88, 0xB573, 0x8B89, - 0xB574, 0x8B8A, 0xB575, 0x8B8B, 0xB576, 0x8B8C, 0xB577, 0x8B8D, 0xB578, 0x8B8E, 0xB579, 0x8B8F, 0xB57A, 0x8B90, 0xB57B, 0x8B91, - 0xB57C, 0x8B92, 0xB57D, 0x8B93, 0xB57E, 0x8B94, 0xB57F, 0x8B95, 0xB580, 0x8B96, 0xB581, 0x8B97, 0xB582, 0x8B98, 0xB583, 0x8B99, - 0xB584, 0x8B9A, 0xB585, 0x8B9B, 0xB586, 0x8B9C, 0xB587, 0x8B9D, 0xB588, 0x8B9E, 0xB589, 0x8B9F, 0xB58A, 0x8BA0, 0xB58B, 0x8BA1, - 0xB58C, 0x8BA2, 0xB58D, 0x8BA3, 0xB58E, 0x8BA4, 0xB58F, 0x8BA5, 0xB590, 0x8BA6, 0xB591, 0x8BA7, 0xB592, 0x8BA8, 0xB593, 0x8BA9, - 0xB594, 0x8BAA, 0xB595, 0x8BAB, 0xB596, 0x8BAC, 0xB597, 0x8BAD, 0xB598, 0x8BAE, 0xB599, 0x8BAF, 0xB59A, 0x8BB0, 0xB59B, 0x8BB1, - 0xB59C, 0x8BB2, 0xB59D, 0x8BB3, 0xB59E, 0x8BB4, 0xB59F, 0x8BB5, 0xB5A0, 0xB6B0, 0xB5A1, 0xB6B1, 0xB5A2, 0x8BB6, 0xB5A3, 0x8BB7, - 0xB5A4, 0xB6B2, 0xB5A5, 0x8BB8, 0xB5A6, 0x8BB9, 0xB5A7, 0x8BBA, 0xB5A8, 0xB6B3, 0xB5A9, 0x8BBB, 0xB5AA, 0xB6B4, 0xB5AB, 0xB6B5, - 0xB5AC, 0x8BBC, 0xB5AD, 0x8BBD, 0xB5AE, 0x8BBE, 0xB5AF, 0x8BBF, 0xB5B0, 0xB6B6, 0xB5B1, 0xB6B7, 0xB5B2, 0x8BC0, 0xB5B3, 0xB6B8, - 0xB5B4, 0xB6B9, 0xB5B5, 0xB6BA, 0xB5B6, 0x8BC1, 0xB5B7, 0x8BC2, 0xB5B8, 0x8BC3, 0xB5B9, 0x8BC4, 0xB5BA, 0x8BC5, 0xB5BB, 0xB6BB, - 0xB5BC, 0xB6BC, 0xB5BD, 0xB6BD, 0xB5BE, 0x8BC6, 0xB5BF, 0x8BC7, 0xB5C0, 0xB6BE, 0xB5C1, 0x8BC8, 0xB5C2, 0x8BC9, 0xB5C3, 0x8BCA, - 0xB5C4, 0xB6BF, 0xB5C5, 0x8BCB, 0xB5C6, 0x8BCC, 0xB5C7, 0x8BCD, 0xB5C8, 0x8BCE, 0xB5C9, 0x8BCF, 0xB5CA, 0x8BD0, 0xB5CB, 0x8BD1, - 0xB5CC, 0xB6C0, 0xB5CD, 0xB6C1, 0xB5CE, 0x8BD2, 0xB5CF, 0xB6C2, 0xB5D0, 0xB6C3, 0xB5D1, 0xB6C4, 0xB5D2, 0x8BD3, 0xB5D3, 0x8BD4, - 0xB5D4, 0x8BD5, 0xB5D5, 0x8BD6, 0xB5D6, 0x8BD7, 0xB5D7, 0x8BD8, 0xB5D8, 0xB6C5, 0xB5D9, 0x8BD9, 0xB5DA, 0x8BDA, 0xB5DB, 0x8BDB, - 0xB5DC, 0x8BDC, 0xB5DD, 0x8BDD, 0xB5DE, 0x8BDE, 0xB5DF, 0x8BDF, 0xB5E0, 0x8BE0, 0xB5E1, 0x8BE1, 0xB5E2, 0x8BE2, 0xB5E3, 0x8BE3, - 0xB5E4, 0x8BE4, 0xB5E5, 0x8BE5, 0xB5E6, 0x8BE6, 0xB5E7, 0x8BE7, 0xB5E8, 0x8BE8, 0xB5E9, 0x8BE9, 0xB5EA, 0x8BEA, 0xB5EB, 0x8BEB, - 0xB5EC, 0xB6C6, 0xB5ED, 0x8BEC, 0xB5EE, 0x8BED, 0xB5EF, 0x8BEE, 0xB5F0, 0x8BEF, 0xB5F1, 0x8BF0, 0xB5F2, 0x8BF1, 0xB5F3, 0x8BF2, - 0xB5F4, 0x8BF3, 0xB5F5, 0x8BF4, 0xB5F6, 0x8BF5, 0xB5F7, 0x8BF6, 0xB5F8, 0x8BF7, 0xB5F9, 0x8BF8, 0xB5FA, 0x8BF9, 0xB5FB, 0x8BFA, - 0xB5FC, 0x8BFB, 0xB5FD, 0x8BFC, 0xB5FE, 0x8BFD, 0xB5FF, 0x8BFE, 0xB600, 0x8C41, 0xB601, 0x8C42, 0xB602, 0x8C43, 0xB603, 0x8C44, - 0xB604, 0x8C45, 0xB605, 0x8C46, 0xB606, 0x8C47, 0xB607, 0x8C48, 0xB608, 0x8C49, 0xB609, 0x8C4A, 0xB60A, 0x8C4B, 0xB60B, 0x8C4C, - 0xB60C, 0x8C4D, 0xB60D, 0x8C4E, 0xB60E, 0x8C4F, 0xB60F, 0x8C50, 0xB610, 0xB6C7, 0xB611, 0xB6C8, 0xB612, 0x8C51, 0xB613, 0x8C52, - 0xB614, 0xB6C9, 0xB615, 0x8C53, 0xB616, 0x8C54, 0xB617, 0x8C55, 0xB618, 0xB6CA, 0xB619, 0x8C56, 0xB61A, 0x8C57, 0xB61B, 0x8C58, - 0xB61C, 0x8C59, 0xB61D, 0x8C5A, 0xB61E, 0x8C61, 0xB61F, 0x8C62, 0xB620, 0x8C63, 0xB621, 0x8C64, 0xB622, 0x8C65, 0xB623, 0x8C66, - 0xB624, 0x8C67, 0xB625, 0xB6CB, 0xB626, 0x8C68, 0xB627, 0x8C69, 0xB628, 0x8C6A, 0xB629, 0x8C6B, 0xB62A, 0x8C6C, 0xB62B, 0x8C6D, - 0xB62C, 0xB6CC, 0xB62D, 0x8C6E, 0xB62E, 0x8C6F, 0xB62F, 0x8C70, 0xB630, 0x8C71, 0xB631, 0x8C72, 0xB632, 0x8C73, 0xB633, 0x8C74, - 0xB634, 0xB6CD, 0xB635, 0x8C75, 0xB636, 0x8C76, 0xB637, 0x8C77, 0xB638, 0x8C78, 0xB639, 0x8C79, 0xB63A, 0x8C7A, 0xB63B, 0x8C81, - 0xB63C, 0x8C82, 0xB63D, 0x8C83, 0xB63E, 0x8C84, 0xB63F, 0x8C85, 0xB640, 0x8C86, 0xB641, 0x8C87, 0xB642, 0x8C88, 0xB643, 0x8C89, - 0xB644, 0x8C8A, 0xB645, 0x8C8B, 0xB646, 0x8C8C, 0xB647, 0x8C8D, 0xB648, 0xB6CE, 0xB649, 0x8C8E, 0xB64A, 0x8C8F, 0xB64B, 0x8C90, - 0xB64C, 0x8C91, 0xB64D, 0x8C92, 0xB64E, 0x8C93, 0xB64F, 0x8C94, 0xB650, 0x8C95, 0xB651, 0x8C96, 0xB652, 0x8C97, 0xB653, 0x8C98, - 0xB654, 0x8C99, 0xB655, 0x8C9A, 0xB656, 0x8C9B, 0xB657, 0x8C9C, 0xB658, 0x8C9D, 0xB659, 0x8C9E, 0xB65A, 0x8C9F, 0xB65B, 0x8CA0, - 0xB65C, 0x8CA1, 0xB65D, 0x8CA2, 0xB65E, 0x8CA3, 0xB65F, 0x8CA4, 0xB660, 0x8CA5, 0xB661, 0x8CA6, 0xB662, 0x8CA7, 0xB663, 0x8CA8, - 0xB664, 0xB6CF, 0xB665, 0x8CA9, 0xB666, 0x8CAA, 0xB667, 0x8CAB, 0xB668, 0xB6D0, 0xB669, 0x8CAC, 0xB66A, 0x8CAD, 0xB66B, 0x8CAE, - 0xB66C, 0x8CAF, 0xB66D, 0x8CB0, 0xB66E, 0x8CB1, 0xB66F, 0x8CB2, 0xB670, 0x8CB3, 0xB671, 0x8CB4, 0xB672, 0x8CB5, 0xB673, 0x8CB6, - 0xB674, 0x8CB7, 0xB675, 0x8CB8, 0xB676, 0x8CB9, 0xB677, 0x8CBA, 0xB678, 0x8CBB, 0xB679, 0x8CBC, 0xB67A, 0x8CBD, 0xB67B, 0x8CBE, - 0xB67C, 0x8CBF, 0xB67D, 0x8CC0, 0xB67E, 0x8CC1, 0xB67F, 0x8CC2, 0xB680, 0x8CC3, 0xB681, 0x8CC4, 0xB682, 0x8CC5, 0xB683, 0x8CC6, - 0xB684, 0x8CC7, 0xB685, 0x8CC8, 0xB686, 0x8CC9, 0xB687, 0x8CCA, 0xB688, 0x8CCB, 0xB689, 0x8CCC, 0xB68A, 0x8CCD, 0xB68B, 0x8CCE, - 0xB68C, 0x8CCF, 0xB68D, 0x8CD0, 0xB68E, 0x8CD1, 0xB68F, 0x8CD2, 0xB690, 0x8CD3, 0xB691, 0x8CD4, 0xB692, 0x8CD5, 0xB693, 0x8CD6, - 0xB694, 0x8CD7, 0xB695, 0x8CD8, 0xB696, 0x8CD9, 0xB697, 0x8CDA, 0xB698, 0x8CDB, 0xB699, 0x8CDC, 0xB69A, 0x8CDD, 0xB69B, 0x8CDE, - 0xB69C, 0xB6D1, 0xB69D, 0xB6D2, 0xB69E, 0x8CDF, 0xB69F, 0x8CE0, 0xB6A0, 0xB6D3, 0xB6A1, 0x8CE1, 0xB6A2, 0x8CE2, 0xB6A3, 0x8CE3, - 0xB6A4, 0xB6D4, 0xB6A5, 0x8CE4, 0xB6A6, 0x8CE5, 0xB6A7, 0x8CE6, 0xB6A8, 0x8CE7, 0xB6A9, 0x8CE8, 0xB6AA, 0x8CE9, 0xB6AB, 0xB6D5, - 0xB6AC, 0xB6D6, 0xB6AD, 0x8CEA, 0xB6AE, 0x8CEB, 0xB6AF, 0x8CEC, 0xB6B0, 0x8CED, 0xB6B1, 0xB6D7, 0xB6B2, 0x8CEE, 0xB6B3, 0x8CEF, - 0xB6B4, 0x8CF0, 0xB6B5, 0x8CF1, 0xB6B6, 0x8CF2, 0xB6B7, 0x8CF3, 0xB6B8, 0x8CF4, 0xB6B9, 0x8CF5, 0xB6BA, 0x8CF6, 0xB6BB, 0x8CF7, - 0xB6BC, 0x8CF8, 0xB6BD, 0x8CF9, 0xB6BE, 0x8CFA, 0xB6BF, 0x8CFB, 0xB6C0, 0x8CFC, 0xB6C1, 0x8CFD, 0xB6C2, 0x8CFE, 0xB6C3, 0x8D41, - 0xB6C4, 0x8D42, 0xB6C5, 0x8D43, 0xB6C6, 0x8D44, 0xB6C7, 0x8D45, 0xB6C8, 0x8D46, 0xB6C9, 0x8D47, 0xB6CA, 0x8D48, 0xB6CB, 0x8D49, - 0xB6CC, 0x8D4A, 0xB6CD, 0x8D4B, 0xB6CE, 0x8D4C, 0xB6CF, 0x8D4D, 0xB6D0, 0x8D4E, 0xB6D1, 0x8D4F, 0xB6D2, 0x8D50, 0xB6D3, 0x8D51, - 0xB6D4, 0xB6D8, 0xB6D5, 0x8D52, 0xB6D6, 0x8D53, 0xB6D7, 0x8D54, 0xB6D8, 0x8D55, 0xB6D9, 0x8D56, 0xB6DA, 0x8D57, 0xB6DB, 0x8D58, - 0xB6DC, 0x8D59, 0xB6DD, 0x8D5A, 0xB6DE, 0x8D61, 0xB6DF, 0x8D62, 0xB6E0, 0x8D63, 0xB6E1, 0x8D64, 0xB6E2, 0x8D65, 0xB6E3, 0x8D66, - 0xB6E4, 0x8D67, 0xB6E5, 0x8D68, 0xB6E6, 0x8D69, 0xB6E7, 0x8D6A, 0xB6E8, 0x8D6B, 0xB6E9, 0x8D6C, 0xB6EA, 0x8D6D, 0xB6EB, 0x8D6E, - 0xB6EC, 0x8D6F, 0xB6ED, 0x8D70, 0xB6EE, 0x8D71, 0xB6EF, 0x8D72, 0xB6F0, 0xB6D9, 0xB6F1, 0x8D73, 0xB6F2, 0x8D74, 0xB6F3, 0x8D75, - 0xB6F4, 0xB6DA, 0xB6F5, 0x8D76, 0xB6F6, 0x8D77, 0xB6F7, 0x8D78, 0xB6F8, 0xB6DB, 0xB6F9, 0x8D79, 0xB6FA, 0x8D7A, 0xB6FB, 0x8D81, - 0xB6FC, 0x8D82, 0xB6FD, 0x8D83, 0xB6FE, 0x8D84, 0xB6FF, 0x8D85, 0xB700, 0xB6DC, 0xB701, 0xB6DD, 0xB702, 0x8D86, 0xB703, 0x8D87, - 0xB704, 0x8D88, 0xB705, 0xB6DE, 0xB706, 0x8D89, 0xB707, 0x8D8A, 0xB708, 0x8D8B, 0xB709, 0x8D8C, 0xB70A, 0x8D8D, 0xB70B, 0x8D8E, - 0xB70C, 0x8D8F, 0xB70D, 0x8D90, 0xB70E, 0x8D91, 0xB70F, 0x8D92, 0xB710, 0x8D93, 0xB711, 0x8D94, 0xB712, 0x8D95, 0xB713, 0x8D96, - 0xB714, 0x8D97, 0xB715, 0x8D98, 0xB716, 0x8D99, 0xB717, 0x8D9A, 0xB718, 0x8D9B, 0xB719, 0x8D9C, 0xB71A, 0x8D9D, 0xB71B, 0x8D9E, - 0xB71C, 0x8D9F, 0xB71D, 0x8DA0, 0xB71E, 0x8DA1, 0xB71F, 0x8DA2, 0xB720, 0x8DA3, 0xB721, 0x8DA4, 0xB722, 0x8DA5, 0xB723, 0x8DA6, - 0xB724, 0x8DA7, 0xB725, 0x8DA8, 0xB726, 0x8DA9, 0xB727, 0x8DAA, 0xB728, 0xB6DF, 0xB729, 0xB6E0, 0xB72A, 0x8DAB, 0xB72B, 0x8DAC, - 0xB72C, 0xB6E1, 0xB72D, 0x8DAD, 0xB72E, 0x8DAE, 0xB72F, 0xB6E2, 0xB730, 0xB6E3, 0xB731, 0x8DAF, 0xB732, 0x8DB0, 0xB733, 0x8DB1, - 0xB734, 0x8DB2, 0xB735, 0x8DB3, 0xB736, 0x8DB4, 0xB737, 0x8DB5, 0xB738, 0xB6E4, 0xB739, 0xB6E5, 0xB73A, 0x8DB6, 0xB73B, 0xB6E6, - 0xB73C, 0x8DB7, 0xB73D, 0x8DB8, 0xB73E, 0x8DB9, 0xB73F, 0x8DBA, 0xB740, 0x8DBB, 0xB741, 0x8DBC, 0xB742, 0x8DBD, 0xB743, 0x8DBE, - 0xB744, 0xB6E7, 0xB745, 0x8DBF, 0xB746, 0x8DC0, 0xB747, 0x8DC1, 0xB748, 0xB6E8, 0xB749, 0x8DC2, 0xB74A, 0x8DC3, 0xB74B, 0x8DC4, - 0xB74C, 0xB6E9, 0xB74D, 0x8DC5, 0xB74E, 0x8DC6, 0xB74F, 0x8DC7, 0xB750, 0x8DC8, 0xB751, 0x8DC9, 0xB752, 0x8DCA, 0xB753, 0x8DCB, - 0xB754, 0xB6EA, 0xB755, 0xB6EB, 0xB756, 0x8DCC, 0xB757, 0x8DCD, 0xB758, 0x8DCE, 0xB759, 0x8DCF, 0xB75A, 0x8DD0, 0xB75B, 0x8DD1, - 0xB75C, 0x8DD2, 0xB75D, 0x8DD3, 0xB75E, 0x8DD4, 0xB75F, 0x8DD5, 0xB760, 0xB6EC, 0xB761, 0x8DD6, 0xB762, 0x8DD7, 0xB763, 0x8DD8, - 0xB764, 0xB6ED, 0xB765, 0x8DD9, 0xB766, 0x8DDA, 0xB767, 0x8DDB, 0xB768, 0xB6EE, 0xB769, 0x8DDC, 0xB76A, 0x8DDD, 0xB76B, 0x8DDE, - 0xB76C, 0x8DDF, 0xB76D, 0x8DE0, 0xB76E, 0x8DE1, 0xB76F, 0x8DE2, 0xB770, 0xB6EF, 0xB771, 0xB6F0, 0xB772, 0x8DE3, 0xB773, 0xB6F1, - 0xB774, 0x8DE4, 0xB775, 0xB6F2, 0xB776, 0x8DE5, 0xB777, 0x8DE6, 0xB778, 0x8DE7, 0xB779, 0x8DE8, 0xB77A, 0x8DE9, 0xB77B, 0x8DEA, - 0xB77C, 0xB6F3, 0xB77D, 0xB6F4, 0xB77E, 0x8DEB, 0xB77F, 0x8DEC, 0xB780, 0xB6F5, 0xB781, 0x8DED, 0xB782, 0x8DEE, 0xB783, 0x8DEF, - 0xB784, 0xB6F6, 0xB785, 0x8DF0, 0xB786, 0x8DF1, 0xB787, 0x8DF2, 0xB788, 0x8DF3, 0xB789, 0x8DF4, 0xB78A, 0x8DF5, 0xB78B, 0x8DF6, - 0xB78C, 0xB6F7, 0xB78D, 0xB6F8, 0xB78E, 0x8DF7, 0xB78F, 0xB6F9, 0xB790, 0xB6FA, 0xB791, 0xB6FB, 0xB792, 0xB6FC, 0xB793, 0x8DF8, - 0xB794, 0x8DF9, 0xB795, 0x8DFA, 0xB796, 0xB6FD, 0xB797, 0xB6FE, 0xB798, 0xB7A1, 0xB799, 0xB7A2, 0xB79A, 0x8DFB, 0xB79B, 0x8DFC, - 0xB79C, 0xB7A3, 0xB79D, 0x8DFD, 0xB79E, 0x8DFE, 0xB79F, 0x8E41, 0xB7A0, 0xB7A4, 0xB7A1, 0x8E42, 0xB7A2, 0x8E43, 0xB7A3, 0x8E44, - 0xB7A4, 0x8E45, 0xB7A5, 0x8E46, 0xB7A6, 0x8E47, 0xB7A7, 0x8E48, 0xB7A8, 0xB7A5, 0xB7A9, 0xB7A6, 0xB7AA, 0x8E49, 0xB7AB, 0xB7A7, - 0xB7AC, 0xB7A8, 0xB7AD, 0xB7A9, 0xB7AE, 0x8E4A, 0xB7AF, 0x8E4B, 0xB7B0, 0x8E4C, 0xB7B1, 0x8E4D, 0xB7B2, 0x8E4E, 0xB7B3, 0x8E4F, - 0xB7B4, 0xB7AA, 0xB7B5, 0xB7AB, 0xB7B6, 0x8E50, 0xB7B7, 0x8E51, 0xB7B8, 0xB7AC, 0xB7B9, 0x8E52, 0xB7BA, 0x8E53, 0xB7BB, 0x8E54, - 0xB7BC, 0x8E55, 0xB7BD, 0x8E56, 0xB7BE, 0x8E57, 0xB7BF, 0x8E58, 0xB7C0, 0x8E59, 0xB7C1, 0x8E5A, 0xB7C2, 0x8E61, 0xB7C3, 0x8E62, - 0xB7C4, 0x8E63, 0xB7C5, 0x8E64, 0xB7C6, 0x8E65, 0xB7C7, 0xB7AD, 0xB7C8, 0x8E66, 0xB7C9, 0xB7AE, 0xB7CA, 0x8E67, 0xB7CB, 0x8E68, - 0xB7CC, 0x8E69, 0xB7CD, 0x8E6A, 0xB7CE, 0x8E6B, 0xB7CF, 0x8E6C, 0xB7D0, 0x8E6D, 0xB7D1, 0x8E6E, 0xB7D2, 0x8E6F, 0xB7D3, 0x8E70, - 0xB7D4, 0x8E71, 0xB7D5, 0x8E72, 0xB7D6, 0x8E73, 0xB7D7, 0x8E74, 0xB7D8, 0x8E75, 0xB7D9, 0x8E76, 0xB7DA, 0x8E77, 0xB7DB, 0x8E78, - 0xB7DC, 0x8E79, 0xB7DD, 0x8E7A, 0xB7DE, 0x8E81, 0xB7DF, 0x8E82, 0xB7E0, 0x8E83, 0xB7E1, 0x8E84, 0xB7E2, 0x8E85, 0xB7E3, 0x8E86, - 0xB7E4, 0x8E87, 0xB7E5, 0x8E88, 0xB7E6, 0x8E89, 0xB7E7, 0x8E8A, 0xB7E8, 0x8E8B, 0xB7E9, 0x8E8C, 0xB7EA, 0x8E8D, 0xB7EB, 0x8E8E, - 0xB7EC, 0xB7AF, 0xB7ED, 0xB7B0, 0xB7EE, 0x8E8F, 0xB7EF, 0x8E90, 0xB7F0, 0xB7B1, 0xB7F1, 0x8E91, 0xB7F2, 0x8E92, 0xB7F3, 0x8E93, - 0xB7F4, 0xB7B2, 0xB7F5, 0x8E94, 0xB7F6, 0x8E95, 0xB7F7, 0x8E96, 0xB7F8, 0x8E97, 0xB7F9, 0x8E98, 0xB7FA, 0x8E99, 0xB7FB, 0x8E9A, - 0xB7FC, 0xB7B3, 0xB7FD, 0xB7B4, 0xB7FE, 0x8E9B, 0xB7FF, 0xB7B5, 0xB800, 0xB7B6, 0xB801, 0xB7B7, 0xB802, 0x8E9C, 0xB803, 0x8E9D, - 0xB804, 0x8E9E, 0xB805, 0x8E9F, 0xB806, 0x8EA0, 0xB807, 0xB7B8, 0xB808, 0xB7B9, 0xB809, 0xB7BA, 0xB80A, 0x8EA1, 0xB80B, 0x8EA2, - 0xB80C, 0xB7BB, 0xB80D, 0x8EA3, 0xB80E, 0x8EA4, 0xB80F, 0x8EA5, 0xB810, 0xB7BC, 0xB811, 0x8EA6, 0xB812, 0x8EA7, 0xB813, 0x8EA8, - 0xB814, 0x8EA9, 0xB815, 0x8EAA, 0xB816, 0x8EAB, 0xB817, 0x8EAC, 0xB818, 0xB7BD, 0xB819, 0xB7BE, 0xB81A, 0x8EAD, 0xB81B, 0xB7BF, - 0xB81C, 0x8EAE, 0xB81D, 0xB7C0, 0xB81E, 0x8EAF, 0xB81F, 0x8EB0, 0xB820, 0x8EB1, 0xB821, 0x8EB2, 0xB822, 0x8EB3, 0xB823, 0x8EB4, - 0xB824, 0xB7C1, 0xB825, 0xB7C2, 0xB826, 0x8EB5, 0xB827, 0x8EB6, 0xB828, 0xB7C3, 0xB829, 0x8EB7, 0xB82A, 0x8EB8, 0xB82B, 0x8EB9, - 0xB82C, 0xB7C4, 0xB82D, 0x8EBA, 0xB82E, 0x8EBB, 0xB82F, 0x8EBC, 0xB830, 0x8EBD, 0xB831, 0x8EBE, 0xB832, 0x8EBF, 0xB833, 0x8EC0, - 0xB834, 0xB7C5, 0xB835, 0xB7C6, 0xB836, 0x8EC1, 0xB837, 0xB7C7, 0xB838, 0xB7C8, 0xB839, 0xB7C9, 0xB83A, 0x8EC2, 0xB83B, 0x8EC3, - 0xB83C, 0x8EC4, 0xB83D, 0x8EC5, 0xB83E, 0x8EC6, 0xB83F, 0x8EC7, 0xB840, 0xB7CA, 0xB841, 0x8EC8, 0xB842, 0x8EC9, 0xB843, 0x8ECA, - 0xB844, 0xB7CB, 0xB845, 0x8ECB, 0xB846, 0x8ECC, 0xB847, 0x8ECD, 0xB848, 0x8ECE, 0xB849, 0x8ECF, 0xB84A, 0x8ED0, 0xB84B, 0x8ED1, - 0xB84C, 0x8ED2, 0xB84D, 0x8ED3, 0xB84E, 0x8ED4, 0xB84F, 0x8ED5, 0xB850, 0x8ED6, 0xB851, 0xB7CC, 0xB852, 0x8ED7, 0xB853, 0xB7CD, - 0xB854, 0x8ED8, 0xB855, 0x8ED9, 0xB856, 0x8EDA, 0xB857, 0x8EDB, 0xB858, 0x8EDC, 0xB859, 0x8EDD, 0xB85A, 0x8EDE, 0xB85B, 0x8EDF, - 0xB85C, 0xB7CE, 0xB85D, 0xB7CF, 0xB85E, 0x8EE0, 0xB85F, 0x8EE1, 0xB860, 0xB7D0, 0xB861, 0x8EE2, 0xB862, 0x8EE3, 0xB863, 0x8EE4, - 0xB864, 0xB7D1, 0xB865, 0x8EE5, 0xB866, 0x8EE6, 0xB867, 0x8EE7, 0xB868, 0x8EE8, 0xB869, 0x8EE9, 0xB86A, 0x8EEA, 0xB86B, 0x8EEB, - 0xB86C, 0xB7D2, 0xB86D, 0xB7D3, 0xB86E, 0x8EEC, 0xB86F, 0xB7D4, 0xB870, 0x8EED, 0xB871, 0xB7D5, 0xB872, 0x8EEE, 0xB873, 0x8EEF, - 0xB874, 0x8EF0, 0xB875, 0x8EF1, 0xB876, 0x8EF2, 0xB877, 0x8EF3, 0xB878, 0xB7D6, 0xB879, 0x8EF4, 0xB87A, 0x8EF5, 0xB87B, 0x8EF6, - 0xB87C, 0xB7D7, 0xB87D, 0x8EF7, 0xB87E, 0x8EF8, 0xB87F, 0x8EF9, 0xB880, 0x8EFA, 0xB881, 0x8EFB, 0xB882, 0x8EFC, 0xB883, 0x8EFD, - 0xB884, 0x8EFE, 0xB885, 0x8F41, 0xB886, 0x8F42, 0xB887, 0x8F43, 0xB888, 0x8F44, 0xB889, 0x8F45, 0xB88A, 0x8F46, 0xB88B, 0x8F47, - 0xB88C, 0x8F48, 0xB88D, 0xB7D8, 0xB88E, 0x8F49, 0xB88F, 0x8F4A, 0xB890, 0x8F4B, 0xB891, 0x8F4C, 0xB892, 0x8F4D, 0xB893, 0x8F4E, - 0xB894, 0x8F4F, 0xB895, 0x8F50, 0xB896, 0x8F51, 0xB897, 0x8F52, 0xB898, 0x8F53, 0xB899, 0x8F54, 0xB89A, 0x8F55, 0xB89B, 0x8F56, - 0xB89C, 0x8F57, 0xB89D, 0x8F58, 0xB89E, 0x8F59, 0xB89F, 0x8F5A, 0xB8A0, 0x8F61, 0xB8A1, 0x8F62, 0xB8A2, 0x8F63, 0xB8A3, 0x8F64, - 0xB8A4, 0x8F65, 0xB8A5, 0x8F66, 0xB8A6, 0x8F67, 0xB8A7, 0x8F68, 0xB8A8, 0xB7D9, 0xB8A9, 0x8F69, 0xB8AA, 0x8F6A, 0xB8AB, 0x8F6B, - 0xB8AC, 0x8F6C, 0xB8AD, 0x8F6D, 0xB8AE, 0x8F6E, 0xB8AF, 0x8F6F, 0xB8B0, 0xB7DA, 0xB8B1, 0x8F70, 0xB8B2, 0x8F71, 0xB8B3, 0x8F72, - 0xB8B4, 0xB7DB, 0xB8B5, 0x8F73, 0xB8B6, 0x8F74, 0xB8B7, 0x8F75, 0xB8B8, 0xB7DC, 0xB8B9, 0x8F76, 0xB8BA, 0x8F77, 0xB8BB, 0x8F78, - 0xB8BC, 0x8F79, 0xB8BD, 0x8F7A, 0xB8BE, 0x8F81, 0xB8BF, 0x8F82, 0xB8C0, 0xB7DD, 0xB8C1, 0xB7DE, 0xB8C2, 0x8F83, 0xB8C3, 0xB7DF, - 0xB8C4, 0x8F84, 0xB8C5, 0xB7E0, 0xB8C6, 0x8F85, 0xB8C7, 0x8F86, 0xB8C8, 0x8F87, 0xB8C9, 0x8F88, 0xB8CA, 0x8F89, 0xB8CB, 0x8F8A, - 0xB8CC, 0xB7E1, 0xB8CD, 0x8F8B, 0xB8CE, 0x8F8C, 0xB8CF, 0x8F8D, 0xB8D0, 0xB7E2, 0xB8D1, 0x8F8E, 0xB8D2, 0x8F8F, 0xB8D3, 0x8F90, - 0xB8D4, 0xB7E3, 0xB8D5, 0x8F91, 0xB8D6, 0x8F92, 0xB8D7, 0x8F93, 0xB8D8, 0x8F94, 0xB8D9, 0x8F95, 0xB8DA, 0x8F96, 0xB8DB, 0x8F97, - 0xB8DC, 0x8F98, 0xB8DD, 0xB7E4, 0xB8DE, 0x8F99, 0xB8DF, 0xB7E5, 0xB8E0, 0x8F9A, 0xB8E1, 0xB7E6, 0xB8E2, 0x8F9B, 0xB8E3, 0x8F9C, - 0xB8E4, 0x8F9D, 0xB8E5, 0x8F9E, 0xB8E6, 0x8F9F, 0xB8E7, 0x8FA0, 0xB8E8, 0xB7E7, 0xB8E9, 0xB7E8, 0xB8EA, 0x8FA1, 0xB8EB, 0x8FA2, - 0xB8EC, 0xB7E9, 0xB8ED, 0x8FA3, 0xB8EE, 0x8FA4, 0xB8EF, 0x8FA5, 0xB8F0, 0xB7EA, 0xB8F1, 0x8FA6, 0xB8F2, 0x8FA7, 0xB8F3, 0x8FA8, - 0xB8F4, 0x8FA9, 0xB8F5, 0x8FAA, 0xB8F6, 0x8FAB, 0xB8F7, 0x8FAC, 0xB8F8, 0xB7EB, 0xB8F9, 0xB7EC, 0xB8FA, 0x8FAD, 0xB8FB, 0xB7ED, - 0xB8FC, 0x8FAE, 0xB8FD, 0xB7EE, 0xB8FE, 0x8FAF, 0xB8FF, 0x8FB0, 0xB900, 0x8FB1, 0xB901, 0x8FB2, 0xB902, 0x8FB3, 0xB903, 0x8FB4, - 0xB904, 0xB7EF, 0xB905, 0x8FB5, 0xB906, 0x8FB6, 0xB907, 0x8FB7, 0xB908, 0x8FB8, 0xB909, 0x8FB9, 0xB90A, 0x8FBA, 0xB90B, 0x8FBB, - 0xB90C, 0x8FBC, 0xB90D, 0x8FBD, 0xB90E, 0x8FBE, 0xB90F, 0x8FBF, 0xB910, 0x8FC0, 0xB911, 0x8FC1, 0xB912, 0x8FC2, 0xB913, 0x8FC3, - 0xB914, 0x8FC4, 0xB915, 0x8FC5, 0xB916, 0x8FC6, 0xB917, 0x8FC7, 0xB918, 0xB7F0, 0xB919, 0x8FC8, 0xB91A, 0x8FC9, 0xB91B, 0x8FCA, - 0xB91C, 0x8FCB, 0xB91D, 0x8FCC, 0xB91E, 0x8FCD, 0xB91F, 0x8FCE, 0xB920, 0xB7F1, 0xB921, 0x8FCF, 0xB922, 0x8FD0, 0xB923, 0x8FD1, - 0xB924, 0x8FD2, 0xB925, 0x8FD3, 0xB926, 0x8FD4, 0xB927, 0x8FD5, 0xB928, 0x8FD6, 0xB929, 0x8FD7, 0xB92A, 0x8FD8, 0xB92B, 0x8FD9, - 0xB92C, 0x8FDA, 0xB92D, 0x8FDB, 0xB92E, 0x8FDC, 0xB92F, 0x8FDD, 0xB930, 0x8FDE, 0xB931, 0x8FDF, 0xB932, 0x8FE0, 0xB933, 0x8FE1, - 0xB934, 0x8FE2, 0xB935, 0x8FE3, 0xB936, 0x8FE4, 0xB937, 0x8FE5, 0xB938, 0x8FE6, 0xB939, 0x8FE7, 0xB93A, 0x8FE8, 0xB93B, 0x8FE9, - 0xB93C, 0xB7F2, 0xB93D, 0xB7F3, 0xB93E, 0x8FEA, 0xB93F, 0x8FEB, 0xB940, 0xB7F4, 0xB941, 0x8FEC, 0xB942, 0x8FED, 0xB943, 0x8FEE, - 0xB944, 0xB7F5, 0xB945, 0x8FEF, 0xB946, 0x8FF0, 0xB947, 0x8FF1, 0xB948, 0x8FF2, 0xB949, 0x8FF3, 0xB94A, 0x8FF4, 0xB94B, 0x8FF5, - 0xB94C, 0xB7F6, 0xB94D, 0x8FF6, 0xB94E, 0x8FF7, 0xB94F, 0xB7F7, 0xB950, 0x8FF8, 0xB951, 0xB7F8, 0xB952, 0x8FF9, 0xB953, 0x8FFA, - 0xB954, 0x8FFB, 0xB955, 0x8FFC, 0xB956, 0x8FFD, 0xB957, 0x8FFE, 0xB958, 0xB7F9, 0xB959, 0xB7FA, 0xB95A, 0x9041, 0xB95B, 0x9042, - 0xB95C, 0xB7FB, 0xB95D, 0x9043, 0xB95E, 0x9044, 0xB95F, 0x9045, 0xB960, 0xB7FC, 0xB961, 0x9046, 0xB962, 0x9047, 0xB963, 0x9048, - 0xB964, 0x9049, 0xB965, 0x904A, 0xB966, 0x904B, 0xB967, 0x904C, 0xB968, 0xB7FD, 0xB969, 0xB7FE, 0xB96A, 0x904D, 0xB96B, 0xB8A1, - 0xB96C, 0x904E, 0xB96D, 0xB8A2, 0xB96E, 0x904F, 0xB96F, 0x9050, 0xB970, 0x9051, 0xB971, 0x9052, 0xB972, 0x9053, 0xB973, 0x9054, - 0xB974, 0xB8A3, 0xB975, 0xB8A4, 0xB976, 0x9055, 0xB977, 0x9056, 0xB978, 0xB8A5, 0xB979, 0x9057, 0xB97A, 0x9058, 0xB97B, 0x9059, - 0xB97C, 0xB8A6, 0xB97D, 0x905A, 0xB97E, 0x9061, 0xB97F, 0x9062, 0xB980, 0x9063, 0xB981, 0x9064, 0xB982, 0x9065, 0xB983, 0x9066, - 0xB984, 0xB8A7, 0xB985, 0xB8A8, 0xB986, 0x9067, 0xB987, 0xB8A9, 0xB988, 0x9068, 0xB989, 0xB8AA, 0xB98A, 0xB8AB, 0xB98B, 0x9069, - 0xB98C, 0x906A, 0xB98D, 0xB8AC, 0xB98E, 0xB8AD, 0xB98F, 0x906B, 0xB990, 0x906C, 0xB991, 0x906D, 0xB992, 0x906E, 0xB993, 0x906F, - 0xB994, 0x9070, 0xB995, 0x9071, 0xB996, 0x9072, 0xB997, 0x9073, 0xB998, 0x9074, 0xB999, 0x9075, 0xB99A, 0x9076, 0xB99B, 0x9077, - 0xB99C, 0x9078, 0xB99D, 0x9079, 0xB99E, 0x907A, 0xB99F, 0x9081, 0xB9A0, 0x9082, 0xB9A1, 0x9083, 0xB9A2, 0x9084, 0xB9A3, 0x9085, - 0xB9A4, 0x9086, 0xB9A5, 0x9087, 0xB9A6, 0x9088, 0xB9A7, 0x9089, 0xB9A8, 0x908A, 0xB9A9, 0x908B, 0xB9AA, 0x908C, 0xB9AB, 0x908D, - 0xB9AC, 0xB8AE, 0xB9AD, 0xB8AF, 0xB9AE, 0x908E, 0xB9AF, 0x908F, 0xB9B0, 0xB8B0, 0xB9B1, 0x9090, 0xB9B2, 0x9091, 0xB9B3, 0x9092, - 0xB9B4, 0xB8B1, 0xB9B5, 0x9093, 0xB9B6, 0x9094, 0xB9B7, 0x9095, 0xB9B8, 0x9096, 0xB9B9, 0x9097, 0xB9BA, 0x9098, 0xB9BB, 0x9099, - 0xB9BC, 0xB8B2, 0xB9BD, 0xB8B3, 0xB9BE, 0x909A, 0xB9BF, 0xB8B4, 0xB9C0, 0x909B, 0xB9C1, 0xB8B5, 0xB9C2, 0x909C, 0xB9C3, 0x909D, - 0xB9C4, 0x909E, 0xB9C5, 0x909F, 0xB9C6, 0x90A0, 0xB9C7, 0x90A1, 0xB9C8, 0xB8B6, 0xB9C9, 0xB8B7, 0xB9CA, 0x90A2, 0xB9CB, 0x90A3, - 0xB9CC, 0xB8B8, 0xB9CD, 0x90A4, 0xB9CE, 0xB8B9, 0xB9CF, 0xB8BA, 0xB9D0, 0xB8BB, 0xB9D1, 0xB8BC, 0xB9D2, 0xB8BD, 0xB9D3, 0x90A5, - 0xB9D4, 0x90A6, 0xB9D5, 0x90A7, 0xB9D6, 0x90A8, 0xB9D7, 0x90A9, 0xB9D8, 0xB8BE, 0xB9D9, 0xB8BF, 0xB9DA, 0x90AA, 0xB9DB, 0xB8C0, - 0xB9DC, 0x90AB, 0xB9DD, 0xB8C1, 0xB9DE, 0xB8C2, 0xB9DF, 0x90AC, 0xB9E0, 0x90AD, 0xB9E1, 0xB8C3, 0xB9E2, 0x90AE, 0xB9E3, 0xB8C4, - 0xB9E4, 0xB8C5, 0xB9E5, 0xB8C6, 0xB9E6, 0x90AF, 0xB9E7, 0x90B0, 0xB9E8, 0xB8C7, 0xB9E9, 0x90B1, 0xB9EA, 0x90B2, 0xB9EB, 0x90B3, - 0xB9EC, 0xB8C8, 0xB9ED, 0x90B4, 0xB9EE, 0x90B5, 0xB9EF, 0x90B6, 0xB9F0, 0x90B7, 0xB9F1, 0x90B8, 0xB9F2, 0x90B9, 0xB9F3, 0x90BA, - 0xB9F4, 0xB8C9, 0xB9F5, 0xB8CA, 0xB9F6, 0x90BB, 0xB9F7, 0xB8CB, 0xB9F8, 0xB8CC, 0xB9F9, 0xB8CD, 0xB9FA, 0xB8CE, 0xB9FB, 0x90BC, - 0xB9FC, 0x90BD, 0xB9FD, 0x90BE, 0xB9FE, 0x90BF, 0xB9FF, 0x90C0, 0xBA00, 0xB8CF, 0xBA01, 0xB8D0, 0xBA02, 0x90C1, 0xBA03, 0x90C2, - 0xBA04, 0x90C3, 0xBA05, 0x90C4, 0xBA06, 0x90C5, 0xBA07, 0x90C6, 0xBA08, 0xB8D1, 0xBA09, 0x90C7, 0xBA0A, 0x90C8, 0xBA0B, 0x90C9, - 0xBA0C, 0x90CA, 0xBA0D, 0x90CB, 0xBA0E, 0x90CC, 0xBA0F, 0x90CD, 0xBA10, 0x90CE, 0xBA11, 0x90CF, 0xBA12, 0x90D0, 0xBA13, 0x90D1, - 0xBA14, 0x90D2, 0xBA15, 0xB8D2, 0xBA16, 0x90D3, 0xBA17, 0x90D4, 0xBA18, 0x90D5, 0xBA19, 0x90D6, 0xBA1A, 0x90D7, 0xBA1B, 0x90D8, - 0xBA1C, 0x90D9, 0xBA1D, 0x90DA, 0xBA1E, 0x90DB, 0xBA1F, 0x90DC, 0xBA20, 0x90DD, 0xBA21, 0x90DE, 0xBA22, 0x90DF, 0xBA23, 0x90E0, - 0xBA24, 0x90E1, 0xBA25, 0x90E2, 0xBA26, 0x90E3, 0xBA27, 0x90E4, 0xBA28, 0x90E5, 0xBA29, 0x90E6, 0xBA2A, 0x90E7, 0xBA2B, 0x90E8, - 0xBA2C, 0x90E9, 0xBA2D, 0x90EA, 0xBA2E, 0x90EB, 0xBA2F, 0x90EC, 0xBA30, 0x90ED, 0xBA31, 0x90EE, 0xBA32, 0x90EF, 0xBA33, 0x90F0, - 0xBA34, 0x90F1, 0xBA35, 0x90F2, 0xBA36, 0x90F3, 0xBA37, 0x90F4, 0xBA38, 0xB8D3, 0xBA39, 0xB8D4, 0xBA3A, 0x90F5, 0xBA3B, 0x90F6, - 0xBA3C, 0xB8D5, 0xBA3D, 0x90F7, 0xBA3E, 0x90F8, 0xBA3F, 0x90F9, 0xBA40, 0xB8D6, 0xBA41, 0x90FA, 0xBA42, 0xB8D7, 0xBA43, 0x90FB, - 0xBA44, 0x90FC, 0xBA45, 0x90FD, 0xBA46, 0x90FE, 0xBA47, 0x9141, 0xBA48, 0xB8D8, 0xBA49, 0xB8D9, 0xBA4A, 0x9142, 0xBA4B, 0xB8DA, - 0xBA4C, 0x9143, 0xBA4D, 0xB8DB, 0xBA4E, 0xB8DC, 0xBA4F, 0x9144, 0xBA50, 0x9145, 0xBA51, 0x9146, 0xBA52, 0x9147, 0xBA53, 0xB8DD, - 0xBA54, 0xB8DE, 0xBA55, 0xB8DF, 0xBA56, 0x9148, 0xBA57, 0x9149, 0xBA58, 0xB8E0, 0xBA59, 0x914A, 0xBA5A, 0x914B, 0xBA5B, 0x914C, - 0xBA5C, 0xB8E1, 0xBA5D, 0x914D, 0xBA5E, 0x914E, 0xBA5F, 0x914F, 0xBA60, 0x9150, 0xBA61, 0x9151, 0xBA62, 0x9152, 0xBA63, 0x9153, - 0xBA64, 0xB8E2, 0xBA65, 0xB8E3, 0xBA66, 0x9154, 0xBA67, 0xB8E4, 0xBA68, 0xB8E5, 0xBA69, 0xB8E6, 0xBA6A, 0x9155, 0xBA6B, 0x9156, - 0xBA6C, 0x9157, 0xBA6D, 0x9158, 0xBA6E, 0x9159, 0xBA6F, 0x915A, 0xBA70, 0xB8E7, 0xBA71, 0xB8E8, 0xBA72, 0x9161, 0xBA73, 0x9162, - 0xBA74, 0xB8E9, 0xBA75, 0x9163, 0xBA76, 0x9164, 0xBA77, 0x9165, 0xBA78, 0xB8EA, 0xBA79, 0x9166, 0xBA7A, 0x9167, 0xBA7B, 0x9168, - 0xBA7C, 0x9169, 0xBA7D, 0x916A, 0xBA7E, 0x916B, 0xBA7F, 0x916C, 0xBA80, 0x916D, 0xBA81, 0x916E, 0xBA82, 0x916F, 0xBA83, 0xB8EB, - 0xBA84, 0xB8EC, 0xBA85, 0xB8ED, 0xBA86, 0x9170, 0xBA87, 0xB8EE, 0xBA88, 0x9171, 0xBA89, 0x9172, 0xBA8A, 0x9173, 0xBA8B, 0x9174, - 0xBA8C, 0xB8EF, 0xBA8D, 0x9175, 0xBA8E, 0x9176, 0xBA8F, 0x9177, 0xBA90, 0x9178, 0xBA91, 0x9179, 0xBA92, 0x917A, 0xBA93, 0x9181, - 0xBA94, 0x9182, 0xBA95, 0x9183, 0xBA96, 0x9184, 0xBA97, 0x9185, 0xBA98, 0x9186, 0xBA99, 0x9187, 0xBA9A, 0x9188, 0xBA9B, 0x9189, - 0xBA9C, 0x918A, 0xBA9D, 0x918B, 0xBA9E, 0x918C, 0xBA9F, 0x918D, 0xBAA0, 0x918E, 0xBAA1, 0x918F, 0xBAA2, 0x9190, 0xBAA3, 0x9191, - 0xBAA4, 0x9192, 0xBAA5, 0x9193, 0xBAA6, 0x9194, 0xBAA7, 0x9195, 0xBAA8, 0xB8F0, 0xBAA9, 0xB8F1, 0xBAAA, 0x9196, 0xBAAB, 0xB8F2, - 0xBAAC, 0xB8F3, 0xBAAD, 0x9197, 0xBAAE, 0x9198, 0xBAAF, 0x9199, 0xBAB0, 0xB8F4, 0xBAB1, 0x919A, 0xBAB2, 0xB8F5, 0xBAB3, 0x919B, - 0xBAB4, 0x919C, 0xBAB5, 0x919D, 0xBAB6, 0x919E, 0xBAB7, 0x919F, 0xBAB8, 0xB8F6, 0xBAB9, 0xB8F7, 0xBABA, 0x91A0, 0xBABB, 0xB8F8, - 0xBABC, 0x91A1, 0xBABD, 0xB8F9, 0xBABE, 0x91A2, 0xBABF, 0x91A3, 0xBAC0, 0x91A4, 0xBAC1, 0x91A5, 0xBAC2, 0x91A6, 0xBAC3, 0x91A7, - 0xBAC4, 0xB8FA, 0xBAC5, 0x91A8, 0xBAC6, 0x91A9, 0xBAC7, 0x91AA, 0xBAC8, 0xB8FB, 0xBAC9, 0x91AB, 0xBACA, 0x91AC, 0xBACB, 0x91AD, - 0xBACC, 0x91AE, 0xBACD, 0x91AF, 0xBACE, 0x91B0, 0xBACF, 0x91B1, 0xBAD0, 0x91B2, 0xBAD1, 0x91B3, 0xBAD2, 0x91B4, 0xBAD3, 0x91B5, - 0xBAD4, 0x91B6, 0xBAD5, 0x91B7, 0xBAD6, 0x91B8, 0xBAD7, 0x91B9, 0xBAD8, 0xB8FC, 0xBAD9, 0xB8FD, 0xBADA, 0x91BA, 0xBADB, 0x91BB, - 0xBADC, 0x91BC, 0xBADD, 0x91BD, 0xBADE, 0x91BE, 0xBADF, 0x91BF, 0xBAE0, 0x91C0, 0xBAE1, 0x91C1, 0xBAE2, 0x91C2, 0xBAE3, 0x91C3, - 0xBAE4, 0x91C4, 0xBAE5, 0x91C5, 0xBAE6, 0x91C6, 0xBAE7, 0x91C7, 0xBAE8, 0x91C8, 0xBAE9, 0x91C9, 0xBAEA, 0x91CA, 0xBAEB, 0x91CB, - 0xBAEC, 0x91CC, 0xBAED, 0x91CD, 0xBAEE, 0x91CE, 0xBAEF, 0x91CF, 0xBAF0, 0x91D0, 0xBAF1, 0x91D1, 0xBAF2, 0x91D2, 0xBAF3, 0x91D3, - 0xBAF4, 0x91D4, 0xBAF5, 0x91D5, 0xBAF6, 0x91D6, 0xBAF7, 0x91D7, 0xBAF8, 0x91D8, 0xBAF9, 0x91D9, 0xBAFA, 0x91DA, 0xBAFB, 0x91DB, - 0xBAFC, 0xB8FE, 0xBAFD, 0x91DC, 0xBAFE, 0x91DD, 0xBAFF, 0x91DE, 0xBB00, 0xB9A1, 0xBB01, 0x91DF, 0xBB02, 0x91E0, 0xBB03, 0x91E1, - 0xBB04, 0xB9A2, 0xBB05, 0x91E2, 0xBB06, 0x91E3, 0xBB07, 0x91E4, 0xBB08, 0x91E5, 0xBB09, 0x91E6, 0xBB0A, 0x91E7, 0xBB0B, 0x91E8, - 0xBB0C, 0x91E9, 0xBB0D, 0xB9A3, 0xBB0E, 0x91EA, 0xBB0F, 0xB9A4, 0xBB10, 0x91EB, 0xBB11, 0xB9A5, 0xBB12, 0x91EC, 0xBB13, 0x91ED, - 0xBB14, 0x91EE, 0xBB15, 0x91EF, 0xBB16, 0x91F0, 0xBB17, 0x91F1, 0xBB18, 0xB9A6, 0xBB19, 0x91F2, 0xBB1A, 0x91F3, 0xBB1B, 0x91F4, - 0xBB1C, 0xB9A7, 0xBB1D, 0x91F5, 0xBB1E, 0x91F6, 0xBB1F, 0x91F7, 0xBB20, 0xB9A8, 0xBB21, 0x91F8, 0xBB22, 0x91F9, 0xBB23, 0x91FA, - 0xBB24, 0x91FB, 0xBB25, 0x91FC, 0xBB26, 0x91FD, 0xBB27, 0x91FE, 0xBB28, 0x9241, 0xBB29, 0xB9A9, 0xBB2A, 0x9242, 0xBB2B, 0xB9AA, - 0xBB2C, 0x9243, 0xBB2D, 0x9244, 0xBB2E, 0x9245, 0xBB2F, 0x9246, 0xBB30, 0x9247, 0xBB31, 0x9248, 0xBB32, 0x9249, 0xBB33, 0x924A, - 0xBB34, 0xB9AB, 0xBB35, 0xB9AC, 0xBB36, 0xB9AD, 0xBB37, 0x924B, 0xBB38, 0xB9AE, 0xBB39, 0x924C, 0xBB3A, 0x924D, 0xBB3B, 0xB9AF, - 0xBB3C, 0xB9B0, 0xBB3D, 0xB9B1, 0xBB3E, 0xB9B2, 0xBB3F, 0x924E, 0xBB40, 0x924F, 0xBB41, 0x9250, 0xBB42, 0x9251, 0xBB43, 0x9252, - 0xBB44, 0xB9B3, 0xBB45, 0xB9B4, 0xBB46, 0x9253, 0xBB47, 0xB9B5, 0xBB48, 0x9254, 0xBB49, 0xB9B6, 0xBB4A, 0x9255, 0xBB4B, 0x9256, - 0xBB4C, 0x9257, 0xBB4D, 0xB9B7, 0xBB4E, 0x9258, 0xBB4F, 0xB9B8, 0xBB50, 0xB9B9, 0xBB51, 0x9259, 0xBB52, 0x925A, 0xBB53, 0x9261, - 0xBB54, 0xB9BA, 0xBB55, 0x9262, 0xBB56, 0x9263, 0xBB57, 0x9264, 0xBB58, 0xB9BB, 0xBB59, 0x9265, 0xBB5A, 0x9266, 0xBB5B, 0x9267, - 0xBB5C, 0x9268, 0xBB5D, 0x9269, 0xBB5E, 0x926A, 0xBB5F, 0x926B, 0xBB60, 0x926C, 0xBB61, 0xB9BC, 0xBB62, 0x926D, 0xBB63, 0xB9BD, - 0xBB64, 0x926E, 0xBB65, 0x926F, 0xBB66, 0x9270, 0xBB67, 0x9271, 0xBB68, 0x9272, 0xBB69, 0x9273, 0xBB6A, 0x9274, 0xBB6B, 0x9275, - 0xBB6C, 0xB9BE, 0xBB6D, 0x9276, 0xBB6E, 0x9277, 0xBB6F, 0x9278, 0xBB70, 0x9279, 0xBB71, 0x927A, 0xBB72, 0x9281, 0xBB73, 0x9282, - 0xBB74, 0x9283, 0xBB75, 0x9284, 0xBB76, 0x9285, 0xBB77, 0x9286, 0xBB78, 0x9287, 0xBB79, 0x9288, 0xBB7A, 0x9289, 0xBB7B, 0x928A, - 0xBB7C, 0x928B, 0xBB7D, 0x928C, 0xBB7E, 0x928D, 0xBB7F, 0x928E, 0xBB80, 0x928F, 0xBB81, 0x9290, 0xBB82, 0x9291, 0xBB83, 0x9292, - 0xBB84, 0x9293, 0xBB85, 0x9294, 0xBB86, 0x9295, 0xBB87, 0x9296, 0xBB88, 0xB9BF, 0xBB89, 0x9297, 0xBB8A, 0x9298, 0xBB8B, 0x9299, - 0xBB8C, 0xB9C0, 0xBB8D, 0x929A, 0xBB8E, 0x929B, 0xBB8F, 0x929C, 0xBB90, 0xB9C1, 0xBB91, 0x929D, 0xBB92, 0x929E, 0xBB93, 0x929F, - 0xBB94, 0x92A0, 0xBB95, 0x92A1, 0xBB96, 0x92A2, 0xBB97, 0x92A3, 0xBB98, 0x92A4, 0xBB99, 0x92A5, 0xBB9A, 0x92A6, 0xBB9B, 0x92A7, - 0xBB9C, 0x92A8, 0xBB9D, 0x92A9, 0xBB9E, 0x92AA, 0xBB9F, 0x92AB, 0xBBA0, 0x92AC, 0xBBA1, 0x92AD, 0xBBA2, 0x92AE, 0xBBA3, 0x92AF, - 0xBBA4, 0xB9C2, 0xBBA5, 0x92B0, 0xBBA6, 0x92B1, 0xBBA7, 0x92B2, 0xBBA8, 0xB9C3, 0xBBA9, 0x92B3, 0xBBAA, 0x92B4, 0xBBAB, 0x92B5, - 0xBBAC, 0xB9C4, 0xBBAD, 0x92B6, 0xBBAE, 0x92B7, 0xBBAF, 0x92B8, 0xBBB0, 0x92B9, 0xBBB1, 0x92BA, 0xBBB2, 0x92BB, 0xBBB3, 0x92BC, - 0xBBB4, 0xB9C5, 0xBBB5, 0x92BD, 0xBBB6, 0x92BE, 0xBBB7, 0xB9C6, 0xBBB8, 0x92BF, 0xBBB9, 0x92C0, 0xBBBA, 0x92C1, 0xBBBB, 0x92C2, - 0xBBBC, 0x92C3, 0xBBBD, 0x92C4, 0xBBBE, 0x92C5, 0xBBBF, 0x92C6, 0xBBC0, 0xB9C7, 0xBBC1, 0x92C7, 0xBBC2, 0x92C8, 0xBBC3, 0x92C9, - 0xBBC4, 0xB9C8, 0xBBC5, 0x92CA, 0xBBC6, 0x92CB, 0xBBC7, 0x92CC, 0xBBC8, 0xB9C9, 0xBBC9, 0x92CD, 0xBBCA, 0x92CE, 0xBBCB, 0x92CF, - 0xBBCC, 0x92D0, 0xBBCD, 0x92D1, 0xBBCE, 0x92D2, 0xBBCF, 0x92D3, 0xBBD0, 0xB9CA, 0xBBD1, 0x92D4, 0xBBD2, 0x92D5, 0xBBD3, 0xB9CB, - 0xBBD4, 0x92D6, 0xBBD5, 0x92D7, 0xBBD6, 0x92D8, 0xBBD7, 0x92D9, 0xBBD8, 0x92DA, 0xBBD9, 0x92DB, 0xBBDA, 0x92DC, 0xBBDB, 0x92DD, - 0xBBDC, 0x92DE, 0xBBDD, 0x92DF, 0xBBDE, 0x92E0, 0xBBDF, 0x92E1, 0xBBE0, 0x92E2, 0xBBE1, 0x92E3, 0xBBE2, 0x92E4, 0xBBE3, 0x92E5, - 0xBBE4, 0x92E6, 0xBBE5, 0x92E7, 0xBBE6, 0x92E8, 0xBBE7, 0x92E9, 0xBBE8, 0x92EA, 0xBBE9, 0x92EB, 0xBBEA, 0x92EC, 0xBBEB, 0x92ED, - 0xBBEC, 0x92EE, 0xBBED, 0x92EF, 0xBBEE, 0x92F0, 0xBBEF, 0x92F1, 0xBBF0, 0x92F2, 0xBBF1, 0x92F3, 0xBBF2, 0x92F4, 0xBBF3, 0x92F5, - 0xBBF4, 0x92F6, 0xBBF5, 0x92F7, 0xBBF6, 0x92F8, 0xBBF7, 0x92F9, 0xBBF8, 0xB9CC, 0xBBF9, 0xB9CD, 0xBBFA, 0x92FA, 0xBBFB, 0x92FB, - 0xBBFC, 0xB9CE, 0xBBFD, 0x92FC, 0xBBFE, 0x92FD, 0xBBFF, 0xB9CF, 0xBC00, 0xB9D0, 0xBC01, 0x92FE, 0xBC02, 0xB9D1, 0xBC03, 0x9341, - 0xBC04, 0x9342, 0xBC05, 0x9343, 0xBC06, 0x9344, 0xBC07, 0x9345, 0xBC08, 0xB9D2, 0xBC09, 0xB9D3, 0xBC0A, 0x9346, 0xBC0B, 0xB9D4, - 0xBC0C, 0xB9D5, 0xBC0D, 0xB9D6, 0xBC0E, 0x9347, 0xBC0F, 0xB9D7, 0xBC10, 0x9348, 0xBC11, 0xB9D8, 0xBC12, 0x9349, 0xBC13, 0x934A, - 0xBC14, 0xB9D9, 0xBC15, 0xB9DA, 0xBC16, 0xB9DB, 0xBC17, 0xB9DC, 0xBC18, 0xB9DD, 0xBC19, 0x934B, 0xBC1A, 0x934C, 0xBC1B, 0xB9DE, - 0xBC1C, 0xB9DF, 0xBC1D, 0xB9E0, 0xBC1E, 0xB9E1, 0xBC1F, 0xB9E2, 0xBC20, 0x934D, 0xBC21, 0x934E, 0xBC22, 0x934F, 0xBC23, 0x9350, - 0xBC24, 0xB9E3, 0xBC25, 0xB9E4, 0xBC26, 0x9351, 0xBC27, 0xB9E5, 0xBC28, 0x9352, 0xBC29, 0xB9E6, 0xBC2A, 0x9353, 0xBC2B, 0x9354, - 0xBC2C, 0x9355, 0xBC2D, 0xB9E7, 0xBC2E, 0x9356, 0xBC2F, 0x9357, 0xBC30, 0xB9E8, 0xBC31, 0xB9E9, 0xBC32, 0x9358, 0xBC33, 0x9359, - 0xBC34, 0xB9EA, 0xBC35, 0x935A, 0xBC36, 0x9361, 0xBC37, 0x9362, 0xBC38, 0xB9EB, 0xBC39, 0x9363, 0xBC3A, 0x9364, 0xBC3B, 0x9365, - 0xBC3C, 0x9366, 0xBC3D, 0x9367, 0xBC3E, 0x9368, 0xBC3F, 0x9369, 0xBC40, 0xB9EC, 0xBC41, 0xB9ED, 0xBC42, 0x936A, 0xBC43, 0xB9EE, - 0xBC44, 0xB9EF, 0xBC45, 0xB9F0, 0xBC46, 0x936B, 0xBC47, 0x936C, 0xBC48, 0x936D, 0xBC49, 0xB9F1, 0xBC4A, 0x936E, 0xBC4B, 0x936F, - 0xBC4C, 0xB9F2, 0xBC4D, 0xB9F3, 0xBC4E, 0x9370, 0xBC4F, 0x9371, 0xBC50, 0xB9F4, 0xBC51, 0x9372, 0xBC52, 0x9373, 0xBC53, 0x9374, - 0xBC54, 0x9375, 0xBC55, 0x9376, 0xBC56, 0x9377, 0xBC57, 0x9378, 0xBC58, 0x9379, 0xBC59, 0x937A, 0xBC5A, 0x9381, 0xBC5B, 0x9382, - 0xBC5C, 0x9383, 0xBC5D, 0xB9F5, 0xBC5E, 0x9384, 0xBC5F, 0x9385, 0xBC60, 0x9386, 0xBC61, 0x9387, 0xBC62, 0x9388, 0xBC63, 0x9389, - 0xBC64, 0x938A, 0xBC65, 0x938B, 0xBC66, 0x938C, 0xBC67, 0x938D, 0xBC68, 0x938E, 0xBC69, 0x938F, 0xBC6A, 0x9390, 0xBC6B, 0x9391, - 0xBC6C, 0x9392, 0xBC6D, 0x9393, 0xBC6E, 0x9394, 0xBC6F, 0x9395, 0xBC70, 0x9396, 0xBC71, 0x9397, 0xBC72, 0x9398, 0xBC73, 0x9399, - 0xBC74, 0x939A, 0xBC75, 0x939B, 0xBC76, 0x939C, 0xBC77, 0x939D, 0xBC78, 0x939E, 0xBC79, 0x939F, 0xBC7A, 0x93A0, 0xBC7B, 0x93A1, - 0xBC7C, 0x93A2, 0xBC7D, 0x93A3, 0xBC7E, 0x93A4, 0xBC7F, 0x93A5, 0xBC80, 0x93A6, 0xBC81, 0x93A7, 0xBC82, 0x93A8, 0xBC83, 0x93A9, - 0xBC84, 0xB9F6, 0xBC85, 0xB9F7, 0xBC86, 0x93AA, 0xBC87, 0x93AB, 0xBC88, 0xB9F8, 0xBC89, 0x93AC, 0xBC8A, 0x93AD, 0xBC8B, 0xB9F9, - 0xBC8C, 0xB9FA, 0xBC8D, 0x93AE, 0xBC8E, 0xB9FB, 0xBC8F, 0x93AF, 0xBC90, 0x93B0, 0xBC91, 0x93B1, 0xBC92, 0x93B2, 0xBC93, 0x93B3, - 0xBC94, 0xB9FC, 0xBC95, 0xB9FD, 0xBC96, 0x93B4, 0xBC97, 0xB9FE, 0xBC98, 0x93B5, 0xBC99, 0xBAA1, 0xBC9A, 0xBAA2, 0xBC9B, 0x93B6, - 0xBC9C, 0x93B7, 0xBC9D, 0x93B8, 0xBC9E, 0x93B9, 0xBC9F, 0x93BA, 0xBCA0, 0xBAA3, 0xBCA1, 0xBAA4, 0xBCA2, 0x93BB, 0xBCA3, 0x93BC, - 0xBCA4, 0xBAA5, 0xBCA5, 0x93BD, 0xBCA6, 0x93BE, 0xBCA7, 0xBAA6, 0xBCA8, 0xBAA7, 0xBCA9, 0x93BF, 0xBCAA, 0x93C0, 0xBCAB, 0x93C1, - 0xBCAC, 0x93C2, 0xBCAD, 0x93C3, 0xBCAE, 0x93C4, 0xBCAF, 0x93C5, 0xBCB0, 0xBAA8, 0xBCB1, 0xBAA9, 0xBCB2, 0x93C6, 0xBCB3, 0xBAAA, - 0xBCB4, 0xBAAB, 0xBCB5, 0xBAAC, 0xBCB6, 0x93C7, 0xBCB7, 0x93C8, 0xBCB8, 0x93C9, 0xBCB9, 0x93CA, 0xBCBA, 0x93CB, 0xBCBB, 0x93CC, - 0xBCBC, 0xBAAD, 0xBCBD, 0xBAAE, 0xBCBE, 0x93CD, 0xBCBF, 0x93CE, 0xBCC0, 0xBAAF, 0xBCC1, 0x93CF, 0xBCC2, 0x93D0, 0xBCC3, 0x93D1, - 0xBCC4, 0xBAB0, 0xBCC5, 0x93D2, 0xBCC6, 0x93D3, 0xBCC7, 0x93D4, 0xBCC8, 0x93D5, 0xBCC9, 0x93D6, 0xBCCA, 0x93D7, 0xBCCB, 0x93D8, - 0xBCCC, 0x93D9, 0xBCCD, 0xBAB1, 0xBCCE, 0x93DA, 0xBCCF, 0xBAB2, 0xBCD0, 0xBAB3, 0xBCD1, 0xBAB4, 0xBCD2, 0x93DB, 0xBCD3, 0x93DC, - 0xBCD4, 0x93DD, 0xBCD5, 0xBAB5, 0xBCD6, 0x93DE, 0xBCD7, 0x93DF, 0xBCD8, 0xBAB6, 0xBCD9, 0x93E0, 0xBCDA, 0x93E1, 0xBCDB, 0x93E2, - 0xBCDC, 0xBAB7, 0xBCDD, 0x93E3, 0xBCDE, 0x93E4, 0xBCDF, 0x93E5, 0xBCE0, 0x93E6, 0xBCE1, 0x93E7, 0xBCE2, 0x93E8, 0xBCE3, 0x93E9, - 0xBCE4, 0x93EA, 0xBCE5, 0x93EB, 0xBCE6, 0x93EC, 0xBCE7, 0x93ED, 0xBCE8, 0x93EE, 0xBCE9, 0x93EF, 0xBCEA, 0x93F0, 0xBCEB, 0x93F1, - 0xBCEC, 0x93F2, 0xBCED, 0x93F3, 0xBCEE, 0x93F4, 0xBCEF, 0x93F5, 0xBCF0, 0x93F6, 0xBCF1, 0x93F7, 0xBCF2, 0x93F8, 0xBCF3, 0x93F9, - 0xBCF4, 0xBAB8, 0xBCF5, 0xBAB9, 0xBCF6, 0xBABA, 0xBCF7, 0x93FA, 0xBCF8, 0xBABB, 0xBCF9, 0x93FB, 0xBCFA, 0x93FC, 0xBCFB, 0x93FD, - 0xBCFC, 0xBABC, 0xBCFD, 0x93FE, 0xBCFE, 0x9441, 0xBCFF, 0x9442, 0xBD00, 0x9443, 0xBD01, 0x9444, 0xBD02, 0x9445, 0xBD03, 0x9446, - 0xBD04, 0xBABD, 0xBD05, 0xBABE, 0xBD06, 0x9447, 0xBD07, 0xBABF, 0xBD08, 0x9448, 0xBD09, 0xBAC0, 0xBD0A, 0x9449, 0xBD0B, 0x944A, - 0xBD0C, 0x944B, 0xBD0D, 0x944C, 0xBD0E, 0x944D, 0xBD0F, 0x944E, 0xBD10, 0xBAC1, 0xBD11, 0x944F, 0xBD12, 0x9450, 0xBD13, 0x9451, - 0xBD14, 0xBAC2, 0xBD15, 0x9452, 0xBD16, 0x9453, 0xBD17, 0x9454, 0xBD18, 0x9455, 0xBD19, 0x9456, 0xBD1A, 0x9457, 0xBD1B, 0x9458, - 0xBD1C, 0x9459, 0xBD1D, 0x945A, 0xBD1E, 0x9461, 0xBD1F, 0x9462, 0xBD20, 0x9463, 0xBD21, 0x9464, 0xBD22, 0x9465, 0xBD23, 0x9466, - 0xBD24, 0xBAC3, 0xBD25, 0x9467, 0xBD26, 0x9468, 0xBD27, 0x9469, 0xBD28, 0x946A, 0xBD29, 0x946B, 0xBD2A, 0x946C, 0xBD2B, 0x946D, - 0xBD2C, 0xBAC4, 0xBD2D, 0x946E, 0xBD2E, 0x946F, 0xBD2F, 0x9470, 0xBD30, 0x9471, 0xBD31, 0x9472, 0xBD32, 0x9473, 0xBD33, 0x9474, - 0xBD34, 0x9475, 0xBD35, 0x9476, 0xBD36, 0x9477, 0xBD37, 0x9478, 0xBD38, 0x9479, 0xBD39, 0x947A, 0xBD3A, 0x9481, 0xBD3B, 0x9482, - 0xBD3C, 0x9483, 0xBD3D, 0x9484, 0xBD3E, 0x9485, 0xBD3F, 0x9486, 0xBD40, 0xBAC5, 0xBD41, 0x9487, 0xBD42, 0x9488, 0xBD43, 0x9489, - 0xBD44, 0x948A, 0xBD45, 0x948B, 0xBD46, 0x948C, 0xBD47, 0x948D, 0xBD48, 0xBAC6, 0xBD49, 0xBAC7, 0xBD4A, 0x948E, 0xBD4B, 0x948F, - 0xBD4C, 0xBAC8, 0xBD4D, 0x9490, 0xBD4E, 0x9491, 0xBD4F, 0x9492, 0xBD50, 0xBAC9, 0xBD51, 0x9493, 0xBD52, 0x9494, 0xBD53, 0x9495, - 0xBD54, 0x9496, 0xBD55, 0x9497, 0xBD56, 0x9498, 0xBD57, 0x9499, 0xBD58, 0xBACA, 0xBD59, 0xBACB, 0xBD5A, 0x949A, 0xBD5B, 0x949B, - 0xBD5C, 0x949C, 0xBD5D, 0x949D, 0xBD5E, 0x949E, 0xBD5F, 0x949F, 0xBD60, 0x94A0, 0xBD61, 0x94A1, 0xBD62, 0x94A2, 0xBD63, 0x94A3, - 0xBD64, 0xBACC, 0xBD65, 0x94A4, 0xBD66, 0x94A5, 0xBD67, 0x94A6, 0xBD68, 0xBACD, 0xBD69, 0x94A7, 0xBD6A, 0x94A8, 0xBD6B, 0x94A9, - 0xBD6C, 0x94AA, 0xBD6D, 0x94AB, 0xBD6E, 0x94AC, 0xBD6F, 0x94AD, 0xBD70, 0x94AE, 0xBD71, 0x94AF, 0xBD72, 0x94B0, 0xBD73, 0x94B1, - 0xBD74, 0x94B2, 0xBD75, 0x94B3, 0xBD76, 0x94B4, 0xBD77, 0x94B5, 0xBD78, 0x94B6, 0xBD79, 0x94B7, 0xBD7A, 0x94B8, 0xBD7B, 0x94B9, - 0xBD7C, 0x94BA, 0xBD7D, 0x94BB, 0xBD7E, 0x94BC, 0xBD7F, 0x94BD, 0xBD80, 0xBACE, 0xBD81, 0xBACF, 0xBD82, 0x94BE, 0xBD83, 0x94BF, - 0xBD84, 0xBAD0, 0xBD85, 0x94C0, 0xBD86, 0x94C1, 0xBD87, 0xBAD1, 0xBD88, 0xBAD2, 0xBD89, 0xBAD3, 0xBD8A, 0xBAD4, 0xBD8B, 0x94C2, - 0xBD8C, 0x94C3, 0xBD8D, 0x94C4, 0xBD8E, 0x94C5, 0xBD8F, 0x94C6, 0xBD90, 0xBAD5, 0xBD91, 0xBAD6, 0xBD92, 0x94C7, 0xBD93, 0xBAD7, - 0xBD94, 0x94C8, 0xBD95, 0xBAD8, 0xBD96, 0x94C9, 0xBD97, 0x94CA, 0xBD98, 0x94CB, 0xBD99, 0xBAD9, 0xBD9A, 0xBADA, 0xBD9B, 0x94CC, - 0xBD9C, 0xBADB, 0xBD9D, 0x94CD, 0xBD9E, 0x94CE, 0xBD9F, 0x94CF, 0xBDA0, 0x94D0, 0xBDA1, 0x94D1, 0xBDA2, 0x94D2, 0xBDA3, 0x94D3, - 0xBDA4, 0xBADC, 0xBDA5, 0x94D4, 0xBDA6, 0x94D5, 0xBDA7, 0x94D6, 0xBDA8, 0x94D7, 0xBDA9, 0x94D8, 0xBDAA, 0x94D9, 0xBDAB, 0x94DA, - 0xBDAC, 0x94DB, 0xBDAD, 0x94DC, 0xBDAE, 0x94DD, 0xBDAF, 0x94DE, 0xBDB0, 0xBADD, 0xBDB1, 0x94DF, 0xBDB2, 0x94E0, 0xBDB3, 0x94E1, - 0xBDB4, 0x94E2, 0xBDB5, 0x94E3, 0xBDB6, 0x94E4, 0xBDB7, 0x94E5, 0xBDB8, 0xBADE, 0xBDB9, 0x94E6, 0xBDBA, 0x94E7, 0xBDBB, 0x94E8, - 0xBDBC, 0x94E9, 0xBDBD, 0x94EA, 0xBDBE, 0x94EB, 0xBDBF, 0x94EC, 0xBDC0, 0x94ED, 0xBDC1, 0x94EE, 0xBDC2, 0x94EF, 0xBDC3, 0x94F0, - 0xBDC4, 0x94F1, 0xBDC5, 0x94F2, 0xBDC6, 0x94F3, 0xBDC7, 0x94F4, 0xBDC8, 0x94F5, 0xBDC9, 0x94F6, 0xBDCA, 0x94F7, 0xBDCB, 0x94F8, - 0xBDCC, 0x94F9, 0xBDCD, 0x94FA, 0xBDCE, 0x94FB, 0xBDCF, 0x94FC, 0xBDD0, 0x94FD, 0xBDD1, 0x94FE, 0xBDD2, 0x9541, 0xBDD3, 0x9542, - 0xBDD4, 0xBADF, 0xBDD5, 0xBAE0, 0xBDD6, 0x9543, 0xBDD7, 0x9544, 0xBDD8, 0xBAE1, 0xBDD9, 0x9545, 0xBDDA, 0x9546, 0xBDDB, 0x9547, - 0xBDDC, 0xBAE2, 0xBDDD, 0x9548, 0xBDDE, 0x9549, 0xBDDF, 0x954A, 0xBDE0, 0x954B, 0xBDE1, 0x954C, 0xBDE2, 0x954D, 0xBDE3, 0x954E, - 0xBDE4, 0x954F, 0xBDE5, 0x9550, 0xBDE6, 0x9551, 0xBDE7, 0x9552, 0xBDE8, 0x9553, 0xBDE9, 0xBAE3, 0xBDEA, 0x9554, 0xBDEB, 0x9555, - 0xBDEC, 0x9556, 0xBDED, 0x9557, 0xBDEE, 0x9558, 0xBDEF, 0x9559, 0xBDF0, 0xBAE4, 0xBDF1, 0x955A, 0xBDF2, 0x9561, 0xBDF3, 0x9562, - 0xBDF4, 0xBAE5, 0xBDF5, 0x9563, 0xBDF6, 0x9564, 0xBDF7, 0x9565, 0xBDF8, 0xBAE6, 0xBDF9, 0x9566, 0xBDFA, 0x9567, 0xBDFB, 0x9568, - 0xBDFC, 0x9569, 0xBDFD, 0x956A, 0xBDFE, 0x956B, 0xBDFF, 0x956C, 0xBE00, 0xBAE7, 0xBE01, 0x956D, 0xBE02, 0x956E, 0xBE03, 0xBAE8, - 0xBE04, 0x956F, 0xBE05, 0xBAE9, 0xBE06, 0x9570, 0xBE07, 0x9571, 0xBE08, 0x9572, 0xBE09, 0x9573, 0xBE0A, 0x9574, 0xBE0B, 0x9575, - 0xBE0C, 0xBAEA, 0xBE0D, 0xBAEB, 0xBE0E, 0x9576, 0xBE0F, 0x9577, 0xBE10, 0xBAEC, 0xBE11, 0x9578, 0xBE12, 0x9579, 0xBE13, 0x957A, - 0xBE14, 0xBAED, 0xBE15, 0x9581, 0xBE16, 0x9582, 0xBE17, 0x9583, 0xBE18, 0x9584, 0xBE19, 0x9585, 0xBE1A, 0x9586, 0xBE1B, 0x9587, - 0xBE1C, 0xBAEE, 0xBE1D, 0xBAEF, 0xBE1E, 0x9588, 0xBE1F, 0xBAF0, 0xBE20, 0x9589, 0xBE21, 0x958A, 0xBE22, 0x958B, 0xBE23, 0x958C, - 0xBE24, 0x958D, 0xBE25, 0x958E, 0xBE26, 0x958F, 0xBE27, 0x9590, 0xBE28, 0x9591, 0xBE29, 0x9592, 0xBE2A, 0x9593, 0xBE2B, 0x9594, - 0xBE2C, 0x9595, 0xBE2D, 0x9596, 0xBE2E, 0x9597, 0xBE2F, 0x9598, 0xBE30, 0x9599, 0xBE31, 0x959A, 0xBE32, 0x959B, 0xBE33, 0x959C, - 0xBE34, 0x959D, 0xBE35, 0x959E, 0xBE36, 0x959F, 0xBE37, 0x95A0, 0xBE38, 0x95A1, 0xBE39, 0x95A2, 0xBE3A, 0x95A3, 0xBE3B, 0x95A4, - 0xBE3C, 0x95A5, 0xBE3D, 0x95A6, 0xBE3E, 0x95A7, 0xBE3F, 0x95A8, 0xBE40, 0x95A9, 0xBE41, 0x95AA, 0xBE42, 0x95AB, 0xBE43, 0x95AC, - 0xBE44, 0xBAF1, 0xBE45, 0xBAF2, 0xBE46, 0x95AD, 0xBE47, 0x95AE, 0xBE48, 0xBAF3, 0xBE49, 0x95AF, 0xBE4A, 0x95B0, 0xBE4B, 0x95B1, - 0xBE4C, 0xBAF4, 0xBE4D, 0x95B2, 0xBE4E, 0xBAF5, 0xBE4F, 0x95B3, 0xBE50, 0x95B4, 0xBE51, 0x95B5, 0xBE52, 0x95B6, 0xBE53, 0x95B7, - 0xBE54, 0xBAF6, 0xBE55, 0xBAF7, 0xBE56, 0x95B8, 0xBE57, 0xBAF8, 0xBE58, 0x95B9, 0xBE59, 0xBAF9, 0xBE5A, 0xBAFA, 0xBE5B, 0xBAFB, - 0xBE5C, 0x95BA, 0xBE5D, 0x95BB, 0xBE5E, 0x95BC, 0xBE5F, 0x95BD, 0xBE60, 0xBAFC, 0xBE61, 0xBAFD, 0xBE62, 0x95BE, 0xBE63, 0x95BF, - 0xBE64, 0xBAFE, 0xBE65, 0x95C0, 0xBE66, 0x95C1, 0xBE67, 0x95C2, 0xBE68, 0xBBA1, 0xBE69, 0x95C3, 0xBE6A, 0xBBA2, 0xBE6B, 0x95C4, - 0xBE6C, 0x95C5, 0xBE6D, 0x95C6, 0xBE6E, 0x95C7, 0xBE6F, 0x95C8, 0xBE70, 0xBBA3, 0xBE71, 0xBBA4, 0xBE72, 0x95C9, 0xBE73, 0xBBA5, - 0xBE74, 0xBBA6, 0xBE75, 0xBBA7, 0xBE76, 0x95CA, 0xBE77, 0x95CB, 0xBE78, 0x95CC, 0xBE79, 0x95CD, 0xBE7A, 0x95CE, 0xBE7B, 0xBBA8, - 0xBE7C, 0xBBA9, 0xBE7D, 0xBBAA, 0xBE7E, 0x95CF, 0xBE7F, 0x95D0, 0xBE80, 0xBBAB, 0xBE81, 0x95D1, 0xBE82, 0x95D2, 0xBE83, 0x95D3, - 0xBE84, 0xBBAC, 0xBE85, 0x95D4, 0xBE86, 0x95D5, 0xBE87, 0x95D6, 0xBE88, 0x95D7, 0xBE89, 0x95D8, 0xBE8A, 0x95D9, 0xBE8B, 0x95DA, - 0xBE8C, 0xBBAD, 0xBE8D, 0xBBAE, 0xBE8E, 0x95DB, 0xBE8F, 0xBBAF, 0xBE90, 0xBBB0, 0xBE91, 0xBBB1, 0xBE92, 0x95DC, 0xBE93, 0x95DD, - 0xBE94, 0x95DE, 0xBE95, 0x95DF, 0xBE96, 0x95E0, 0xBE97, 0x95E1, 0xBE98, 0xBBB2, 0xBE99, 0xBBB3, 0xBE9A, 0x95E2, 0xBE9B, 0x95E3, - 0xBE9C, 0x95E4, 0xBE9D, 0x95E5, 0xBE9E, 0x95E6, 0xBE9F, 0x95E7, 0xBEA0, 0x95E8, 0xBEA1, 0x95E9, 0xBEA2, 0x95EA, 0xBEA3, 0x95EB, - 0xBEA4, 0x95EC, 0xBEA5, 0x95ED, 0xBEA6, 0x95EE, 0xBEA7, 0x95EF, 0xBEA8, 0xBBB4, 0xBEA9, 0x95F0, 0xBEAA, 0x95F1, 0xBEAB, 0x95F2, - 0xBEAC, 0x95F3, 0xBEAD, 0x95F4, 0xBEAE, 0x95F5, 0xBEAF, 0x95F6, 0xBEB0, 0x95F7, 0xBEB1, 0x95F8, 0xBEB2, 0x95F9, 0xBEB3, 0x95FA, - 0xBEB4, 0x95FB, 0xBEB5, 0x95FC, 0xBEB6, 0x95FD, 0xBEB7, 0x95FE, 0xBEB8, 0x9641, 0xBEB9, 0x9642, 0xBEBA, 0x9643, 0xBEBB, 0x9644, - 0xBEBC, 0x9645, 0xBEBD, 0x9646, 0xBEBE, 0x9647, 0xBEBF, 0x9648, 0xBEC0, 0x9649, 0xBEC1, 0x964A, 0xBEC2, 0x964B, 0xBEC3, 0x964C, - 0xBEC4, 0x964D, 0xBEC5, 0x964E, 0xBEC6, 0x964F, 0xBEC7, 0x9650, 0xBEC8, 0x9651, 0xBEC9, 0x9652, 0xBECA, 0x9653, 0xBECB, 0x9654, - 0xBECC, 0x9655, 0xBECD, 0x9656, 0xBECE, 0x9657, 0xBECF, 0x9658, 0xBED0, 0xBBB5, 0xBED1, 0xBBB6, 0xBED2, 0x9659, 0xBED3, 0x965A, - 0xBED4, 0xBBB7, 0xBED5, 0x9661, 0xBED6, 0x9662, 0xBED7, 0xBBB8, 0xBED8, 0xBBB9, 0xBED9, 0x9663, 0xBEDA, 0x9664, 0xBEDB, 0x9665, - 0xBEDC, 0x9666, 0xBEDD, 0x9667, 0xBEDE, 0x9668, 0xBEDF, 0x9669, 0xBEE0, 0xBBBA, 0xBEE1, 0x966A, 0xBEE2, 0x966B, 0xBEE3, 0xBBBB, - 0xBEE4, 0xBBBC, 0xBEE5, 0xBBBD, 0xBEE6, 0x966C, 0xBEE7, 0x966D, 0xBEE8, 0x966E, 0xBEE9, 0x966F, 0xBEEA, 0x9670, 0xBEEB, 0x9671, - 0xBEEC, 0xBBBE, 0xBEED, 0x9672, 0xBEEE, 0x9673, 0xBEEF, 0x9674, 0xBEF0, 0x9675, 0xBEF1, 0x9676, 0xBEF2, 0x9677, 0xBEF3, 0x9678, - 0xBEF4, 0x9679, 0xBEF5, 0x967A, 0xBEF6, 0x9681, 0xBEF7, 0x9682, 0xBEF8, 0x9683, 0xBEF9, 0x9684, 0xBEFA, 0x9685, 0xBEFB, 0x9686, - 0xBEFC, 0x9687, 0xBEFD, 0x9688, 0xBEFE, 0x9689, 0xBEFF, 0x968A, 0xBF00, 0x968B, 0xBF01, 0xBBBF, 0xBF02, 0x968C, 0xBF03, 0x968D, - 0xBF04, 0x968E, 0xBF05, 0x968F, 0xBF06, 0x9690, 0xBF07, 0x9691, 0xBF08, 0xBBC0, 0xBF09, 0xBBC1, 0xBF0A, 0x9692, 0xBF0B, 0x9693, - 0xBF0C, 0x9694, 0xBF0D, 0x9695, 0xBF0E, 0x9696, 0xBF0F, 0x9697, 0xBF10, 0x9698, 0xBF11, 0x9699, 0xBF12, 0x969A, 0xBF13, 0x969B, - 0xBF14, 0x969C, 0xBF15, 0x969D, 0xBF16, 0x969E, 0xBF17, 0x969F, 0xBF18, 0xBBC2, 0xBF19, 0xBBC3, 0xBF1A, 0x96A0, 0xBF1B, 0xBBC4, - 0xBF1C, 0xBBC5, 0xBF1D, 0xBBC6, 0xBF1E, 0x96A1, 0xBF1F, 0x96A2, 0xBF20, 0x96A3, 0xBF21, 0x96A4, 0xBF22, 0x96A5, 0xBF23, 0x96A6, - 0xBF24, 0x96A7, 0xBF25, 0x96A8, 0xBF26, 0x96A9, 0xBF27, 0x96AA, 0xBF28, 0x96AB, 0xBF29, 0x96AC, 0xBF2A, 0x96AD, 0xBF2B, 0x96AE, - 0xBF2C, 0x96AF, 0xBF2D, 0x96B0, 0xBF2E, 0x96B1, 0xBF2F, 0x96B2, 0xBF30, 0x96B3, 0xBF31, 0x96B4, 0xBF32, 0x96B5, 0xBF33, 0x96B6, - 0xBF34, 0x96B7, 0xBF35, 0x96B8, 0xBF36, 0x96B9, 0xBF37, 0x96BA, 0xBF38, 0x96BB, 0xBF39, 0x96BC, 0xBF3A, 0x96BD, 0xBF3B, 0x96BE, - 0xBF3C, 0x96BF, 0xBF3D, 0x96C0, 0xBF3E, 0x96C1, 0xBF3F, 0x96C2, 0xBF40, 0xBBC7, 0xBF41, 0xBBC8, 0xBF42, 0x96C3, 0xBF43, 0x96C4, - 0xBF44, 0xBBC9, 0xBF45, 0x96C5, 0xBF46, 0x96C6, 0xBF47, 0x96C7, 0xBF48, 0xBBCA, 0xBF49, 0x96C8, 0xBF4A, 0x96C9, 0xBF4B, 0x96CA, - 0xBF4C, 0x96CB, 0xBF4D, 0x96CC, 0xBF4E, 0x96CD, 0xBF4F, 0x96CE, 0xBF50, 0xBBCB, 0xBF51, 0xBBCC, 0xBF52, 0x96CF, 0xBF53, 0x96D0, - 0xBF54, 0x96D1, 0xBF55, 0xBBCD, 0xBF56, 0x96D2, 0xBF57, 0x96D3, 0xBF58, 0x96D4, 0xBF59, 0x96D5, 0xBF5A, 0x96D6, 0xBF5B, 0x96D7, - 0xBF5C, 0x96D8, 0xBF5D, 0x96D9, 0xBF5E, 0x96DA, 0xBF5F, 0x96DB, 0xBF60, 0x96DC, 0xBF61, 0x96DD, 0xBF62, 0x96DE, 0xBF63, 0x96DF, - 0xBF64, 0x96E0, 0xBF65, 0x96E1, 0xBF66, 0x96E2, 0xBF67, 0x96E3, 0xBF68, 0x96E4, 0xBF69, 0x96E5, 0xBF6A, 0x96E6, 0xBF6B, 0x96E7, - 0xBF6C, 0x96E8, 0xBF6D, 0x96E9, 0xBF6E, 0x96EA, 0xBF6F, 0x96EB, 0xBF70, 0x96EC, 0xBF71, 0x96ED, 0xBF72, 0x96EE, 0xBF73, 0x96EF, - 0xBF74, 0x96F0, 0xBF75, 0x96F1, 0xBF76, 0x96F2, 0xBF77, 0x96F3, 0xBF78, 0x96F4, 0xBF79, 0x96F5, 0xBF7A, 0x96F6, 0xBF7B, 0x96F7, - 0xBF7C, 0x96F8, 0xBF7D, 0x96F9, 0xBF7E, 0x96FA, 0xBF7F, 0x96FB, 0xBF80, 0x96FC, 0xBF81, 0x96FD, 0xBF82, 0x96FE, 0xBF83, 0x9741, - 0xBF84, 0x9742, 0xBF85, 0x9743, 0xBF86, 0x9744, 0xBF87, 0x9745, 0xBF88, 0x9746, 0xBF89, 0x9747, 0xBF8A, 0x9748, 0xBF8B, 0x9749, - 0xBF8C, 0x974A, 0xBF8D, 0x974B, 0xBF8E, 0x974C, 0xBF8F, 0x974D, 0xBF90, 0x974E, 0xBF91, 0x974F, 0xBF92, 0x9750, 0xBF93, 0x9751, - 0xBF94, 0xBBCE, 0xBF95, 0x9752, 0xBF96, 0x9753, 0xBF97, 0x9754, 0xBF98, 0x9755, 0xBF99, 0x9756, 0xBF9A, 0x9757, 0xBF9B, 0x9758, - 0xBF9C, 0x9759, 0xBF9D, 0x975A, 0xBF9E, 0x9761, 0xBF9F, 0x9762, 0xBFA0, 0x9763, 0xBFA1, 0x9764, 0xBFA2, 0x9765, 0xBFA3, 0x9766, - 0xBFA4, 0x9767, 0xBFA5, 0x9768, 0xBFA6, 0x9769, 0xBFA7, 0x976A, 0xBFA8, 0x976B, 0xBFA9, 0x976C, 0xBFAA, 0x976D, 0xBFAB, 0x976E, - 0xBFAC, 0x976F, 0xBFAD, 0x9770, 0xBFAE, 0x9771, 0xBFAF, 0x9772, 0xBFB0, 0xBBCF, 0xBFB1, 0x9773, 0xBFB2, 0x9774, 0xBFB3, 0x9775, - 0xBFB4, 0x9776, 0xBFB5, 0x9777, 0xBFB6, 0x9778, 0xBFB7, 0x9779, 0xBFB8, 0x977A, 0xBFB9, 0x9781, 0xBFBA, 0x9782, 0xBFBB, 0x9783, - 0xBFBC, 0x9784, 0xBFBD, 0x9785, 0xBFBE, 0x9786, 0xBFBF, 0x9787, 0xBFC0, 0x9788, 0xBFC1, 0x9789, 0xBFC2, 0x978A, 0xBFC3, 0x978B, - 0xBFC4, 0x978C, 0xBFC5, 0xBBD0, 0xBFC6, 0x978D, 0xBFC7, 0x978E, 0xBFC8, 0x978F, 0xBFC9, 0x9790, 0xBFCA, 0x9791, 0xBFCB, 0x9792, - 0xBFCC, 0xBBD1, 0xBFCD, 0xBBD2, 0xBFCE, 0x9793, 0xBFCF, 0x9794, 0xBFD0, 0xBBD3, 0xBFD1, 0x9795, 0xBFD2, 0x9796, 0xBFD3, 0x9797, - 0xBFD4, 0xBBD4, 0xBFD5, 0x9798, 0xBFD6, 0x9799, 0xBFD7, 0x979A, 0xBFD8, 0x979B, 0xBFD9, 0x979C, 0xBFDA, 0x979D, 0xBFDB, 0x979E, - 0xBFDC, 0xBBD5, 0xBFDD, 0x979F, 0xBFDE, 0x97A0, 0xBFDF, 0xBBD6, 0xBFE0, 0x97A1, 0xBFE1, 0xBBD7, 0xBFE2, 0x97A2, 0xBFE3, 0x97A3, - 0xBFE4, 0x97A4, 0xBFE5, 0x97A5, 0xBFE6, 0x97A6, 0xBFE7, 0x97A7, 0xBFE8, 0x97A8, 0xBFE9, 0x97A9, 0xBFEA, 0x97AA, 0xBFEB, 0x97AB, - 0xBFEC, 0x97AC, 0xBFED, 0x97AD, 0xBFEE, 0x97AE, 0xBFEF, 0x97AF, 0xBFF0, 0x97B0, 0xBFF1, 0x97B1, 0xBFF2, 0x97B2, 0xBFF3, 0x97B3, - 0xBFF4, 0x97B4, 0xBFF5, 0x97B5, 0xBFF6, 0x97B6, 0xBFF7, 0x97B7, 0xBFF8, 0x97B8, 0xBFF9, 0x97B9, 0xBFFA, 0x97BA, 0xBFFB, 0x97BB, - 0xBFFC, 0x97BC, 0xBFFD, 0x97BD, 0xBFFE, 0x97BE, 0xBFFF, 0x97BF, 0xC000, 0x97C0, 0xC001, 0x97C1, 0xC002, 0x97C2, 0xC003, 0x97C3, - 0xC004, 0x97C4, 0xC005, 0x97C5, 0xC006, 0x97C6, 0xC007, 0x97C7, 0xC008, 0x97C8, 0xC009, 0x97C9, 0xC00A, 0x97CA, 0xC00B, 0x97CB, - 0xC00C, 0x97CC, 0xC00D, 0x97CD, 0xC00E, 0x97CE, 0xC00F, 0x97CF, 0xC010, 0x97D0, 0xC011, 0x97D1, 0xC012, 0x97D2, 0xC013, 0x97D3, - 0xC014, 0x97D4, 0xC015, 0x97D5, 0xC016, 0x97D6, 0xC017, 0x97D7, 0xC018, 0x97D8, 0xC019, 0x97D9, 0xC01A, 0x97DA, 0xC01B, 0x97DB, - 0xC01C, 0x97DC, 0xC01D, 0x97DD, 0xC01E, 0x97DE, 0xC01F, 0x97DF, 0xC020, 0x97E0, 0xC021, 0x97E1, 0xC022, 0x97E2, 0xC023, 0x97E3, - 0xC024, 0x97E4, 0xC025, 0x97E5, 0xC026, 0x97E6, 0xC027, 0x97E7, 0xC028, 0x97E8, 0xC029, 0x97E9, 0xC02A, 0x97EA, 0xC02B, 0x97EB, - 0xC02C, 0x97EC, 0xC02D, 0x97ED, 0xC02E, 0x97EE, 0xC02F, 0x97EF, 0xC030, 0x97F0, 0xC031, 0x97F1, 0xC032, 0x97F2, 0xC033, 0x97F3, - 0xC034, 0x97F4, 0xC035, 0x97F5, 0xC036, 0x97F6, 0xC037, 0x97F7, 0xC038, 0x97F8, 0xC039, 0x97F9, 0xC03A, 0x97FA, 0xC03B, 0x97FB, - 0xC03C, 0xBBD8, 0xC03D, 0x97FC, 0xC03E, 0x97FD, 0xC03F, 0x97FE, 0xC040, 0x9841, 0xC041, 0x9842, 0xC042, 0x9843, 0xC043, 0x9844, - 0xC044, 0x9845, 0xC045, 0x9846, 0xC046, 0x9847, 0xC047, 0x9848, 0xC048, 0x9849, 0xC049, 0x984A, 0xC04A, 0x984B, 0xC04B, 0x984C, - 0xC04C, 0x984D, 0xC04D, 0x984E, 0xC04E, 0x984F, 0xC04F, 0x9850, 0xC050, 0x9851, 0xC051, 0xBBD9, 0xC052, 0x9852, 0xC053, 0x9853, - 0xC054, 0x9854, 0xC055, 0x9855, 0xC056, 0x9856, 0xC057, 0x9857, 0xC058, 0xBBDA, 0xC059, 0x9858, 0xC05A, 0x9859, 0xC05B, 0x985A, - 0xC05C, 0xBBDB, 0xC05D, 0x9861, 0xC05E, 0x9862, 0xC05F, 0x9863, 0xC060, 0xBBDC, 0xC061, 0x9864, 0xC062, 0x9865, 0xC063, 0x9866, - 0xC064, 0x9867, 0xC065, 0x9868, 0xC066, 0x9869, 0xC067, 0x986A, 0xC068, 0xBBDD, 0xC069, 0xBBDE, 0xC06A, 0x986B, 0xC06B, 0x986C, - 0xC06C, 0x986D, 0xC06D, 0x986E, 0xC06E, 0x986F, 0xC06F, 0x9870, 0xC070, 0x9871, 0xC071, 0x9872, 0xC072, 0x9873, 0xC073, 0x9874, - 0xC074, 0x9875, 0xC075, 0x9876, 0xC076, 0x9877, 0xC077, 0x9878, 0xC078, 0x9879, 0xC079, 0x987A, 0xC07A, 0x9881, 0xC07B, 0x9882, - 0xC07C, 0x9883, 0xC07D, 0x9884, 0xC07E, 0x9885, 0xC07F, 0x9886, 0xC080, 0x9887, 0xC081, 0x9888, 0xC082, 0x9889, 0xC083, 0x988A, - 0xC084, 0x988B, 0xC085, 0x988C, 0xC086, 0x988D, 0xC087, 0x988E, 0xC088, 0x988F, 0xC089, 0x9890, 0xC08A, 0x9891, 0xC08B, 0x9892, - 0xC08C, 0x9893, 0xC08D, 0x9894, 0xC08E, 0x9895, 0xC08F, 0x9896, 0xC090, 0xBBDF, 0xC091, 0xBBE0, 0xC092, 0x9897, 0xC093, 0x9898, - 0xC094, 0xBBE1, 0xC095, 0x9899, 0xC096, 0x989A, 0xC097, 0x989B, 0xC098, 0xBBE2, 0xC099, 0x989C, 0xC09A, 0x989D, 0xC09B, 0x989E, - 0xC09C, 0x989F, 0xC09D, 0x98A0, 0xC09E, 0x98A1, 0xC09F, 0x98A2, 0xC0A0, 0xBBE3, 0xC0A1, 0xBBE4, 0xC0A2, 0x98A3, 0xC0A3, 0xBBE5, - 0xC0A4, 0x98A4, 0xC0A5, 0xBBE6, 0xC0A6, 0x98A5, 0xC0A7, 0x98A6, 0xC0A8, 0x98A7, 0xC0A9, 0x98A8, 0xC0AA, 0x98A9, 0xC0AB, 0x98AA, - 0xC0AC, 0xBBE7, 0xC0AD, 0xBBE8, 0xC0AE, 0x98AB, 0xC0AF, 0xBBE9, 0xC0B0, 0xBBEA, 0xC0B1, 0x98AC, 0xC0B2, 0x98AD, 0xC0B3, 0xBBEB, - 0xC0B4, 0xBBEC, 0xC0B5, 0xBBED, 0xC0B6, 0xBBEE, 0xC0B7, 0x98AE, 0xC0B8, 0x98AF, 0xC0B9, 0x98B0, 0xC0BA, 0x98B1, 0xC0BB, 0x98B2, - 0xC0BC, 0xBBEF, 0xC0BD, 0xBBF0, 0xC0BE, 0x98B3, 0xC0BF, 0xBBF1, 0xC0C0, 0xBBF2, 0xC0C1, 0xBBF3, 0xC0C2, 0x98B4, 0xC0C3, 0x98B5, - 0xC0C4, 0x98B6, 0xC0C5, 0xBBF4, 0xC0C6, 0x98B7, 0xC0C7, 0x98B8, 0xC0C8, 0xBBF5, 0xC0C9, 0xBBF6, 0xC0CA, 0x98B9, 0xC0CB, 0x98BA, - 0xC0CC, 0xBBF7, 0xC0CD, 0x98BB, 0xC0CE, 0x98BC, 0xC0CF, 0x98BD, 0xC0D0, 0xBBF8, 0xC0D1, 0x98BE, 0xC0D2, 0x98BF, 0xC0D3, 0x98C0, - 0xC0D4, 0x98C1, 0xC0D5, 0x98C2, 0xC0D6, 0x98C3, 0xC0D7, 0x98C4, 0xC0D8, 0xBBF9, 0xC0D9, 0xBBFA, 0xC0DA, 0x98C5, 0xC0DB, 0xBBFB, - 0xC0DC, 0xBBFC, 0xC0DD, 0xBBFD, 0xC0DE, 0x98C6, 0xC0DF, 0x98C7, 0xC0E0, 0x98C8, 0xC0E1, 0x98C9, 0xC0E2, 0x98CA, 0xC0E3, 0x98CB, - 0xC0E4, 0xBBFE, 0xC0E5, 0xBCA1, 0xC0E6, 0x98CC, 0xC0E7, 0x98CD, 0xC0E8, 0xBCA2, 0xC0E9, 0x98CE, 0xC0EA, 0x98CF, 0xC0EB, 0x98D0, - 0xC0EC, 0xBCA3, 0xC0ED, 0x98D1, 0xC0EE, 0x98D2, 0xC0EF, 0x98D3, 0xC0F0, 0x98D4, 0xC0F1, 0x98D5, 0xC0F2, 0x98D6, 0xC0F3, 0x98D7, - 0xC0F4, 0xBCA4, 0xC0F5, 0xBCA5, 0xC0F6, 0x98D8, 0xC0F7, 0xBCA6, 0xC0F8, 0x98D9, 0xC0F9, 0xBCA7, 0xC0FA, 0x98DA, 0xC0FB, 0x98DB, - 0xC0FC, 0x98DC, 0xC0FD, 0x98DD, 0xC0FE, 0x98DE, 0xC0FF, 0x98DF, 0xC100, 0xBCA8, 0xC101, 0x98E0, 0xC102, 0x98E1, 0xC103, 0x98E2, - 0xC104, 0xBCA9, 0xC105, 0x98E3, 0xC106, 0x98E4, 0xC107, 0x98E5, 0xC108, 0xBCAA, 0xC109, 0x98E6, 0xC10A, 0x98E7, 0xC10B, 0x98E8, - 0xC10C, 0x98E9, 0xC10D, 0x98EA, 0xC10E, 0x98EB, 0xC10F, 0x98EC, 0xC110, 0xBCAB, 0xC111, 0x98ED, 0xC112, 0x98EE, 0xC113, 0x98EF, - 0xC114, 0x98F0, 0xC115, 0xBCAC, 0xC116, 0x98F1, 0xC117, 0x98F2, 0xC118, 0x98F3, 0xC119, 0x98F4, 0xC11A, 0x98F5, 0xC11B, 0x98F6, - 0xC11C, 0xBCAD, 0xC11D, 0xBCAE, 0xC11E, 0xBCAF, 0xC11F, 0xBCB0, 0xC120, 0xBCB1, 0xC121, 0x98F7, 0xC122, 0x98F8, 0xC123, 0xBCB2, - 0xC124, 0xBCB3, 0xC125, 0x98F9, 0xC126, 0xBCB4, 0xC127, 0xBCB5, 0xC128, 0x98FA, 0xC129, 0x98FB, 0xC12A, 0x98FC, 0xC12B, 0x98FD, - 0xC12C, 0xBCB6, 0xC12D, 0xBCB7, 0xC12E, 0x98FE, 0xC12F, 0xBCB8, 0xC130, 0xBCB9, 0xC131, 0xBCBA, 0xC132, 0x9941, 0xC133, 0x9942, - 0xC134, 0x9943, 0xC135, 0x9944, 0xC136, 0xBCBB, 0xC137, 0x9945, 0xC138, 0xBCBC, 0xC139, 0xBCBD, 0xC13A, 0x9946, 0xC13B, 0x9947, - 0xC13C, 0xBCBE, 0xC13D, 0x9948, 0xC13E, 0x9949, 0xC13F, 0x994A, 0xC140, 0xBCBF, 0xC141, 0x994B, 0xC142, 0x994C, 0xC143, 0x994D, - 0xC144, 0x994E, 0xC145, 0x994F, 0xC146, 0x9950, 0xC147, 0x9951, 0xC148, 0xBCC0, 0xC149, 0xBCC1, 0xC14A, 0x9952, 0xC14B, 0xBCC2, - 0xC14C, 0xBCC3, 0xC14D, 0xBCC4, 0xC14E, 0x9953, 0xC14F, 0x9954, 0xC150, 0x9955, 0xC151, 0x9956, 0xC152, 0x9957, 0xC153, 0x9958, - 0xC154, 0xBCC5, 0xC155, 0xBCC6, 0xC156, 0x9959, 0xC157, 0x995A, 0xC158, 0xBCC7, 0xC159, 0x9961, 0xC15A, 0x9962, 0xC15B, 0x9963, - 0xC15C, 0xBCC8, 0xC15D, 0x9964, 0xC15E, 0x9965, 0xC15F, 0x9966, 0xC160, 0x9967, 0xC161, 0x9968, 0xC162, 0x9969, 0xC163, 0x996A, - 0xC164, 0xBCC9, 0xC165, 0xBCCA, 0xC166, 0x996B, 0xC167, 0xBCCB, 0xC168, 0xBCCC, 0xC169, 0xBCCD, 0xC16A, 0x996C, 0xC16B, 0x996D, - 0xC16C, 0x996E, 0xC16D, 0x996F, 0xC16E, 0x9970, 0xC16F, 0x9971, 0xC170, 0xBCCE, 0xC171, 0x9972, 0xC172, 0x9973, 0xC173, 0x9974, - 0xC174, 0xBCCF, 0xC175, 0x9975, 0xC176, 0x9976, 0xC177, 0x9977, 0xC178, 0xBCD0, 0xC179, 0x9978, 0xC17A, 0x9979, 0xC17B, 0x997A, - 0xC17C, 0x9981, 0xC17D, 0x9982, 0xC17E, 0x9983, 0xC17F, 0x9984, 0xC180, 0x9985, 0xC181, 0x9986, 0xC182, 0x9987, 0xC183, 0x9988, - 0xC184, 0x9989, 0xC185, 0xBCD1, 0xC186, 0x998A, 0xC187, 0x998B, 0xC188, 0x998C, 0xC189, 0x998D, 0xC18A, 0x998E, 0xC18B, 0x998F, - 0xC18C, 0xBCD2, 0xC18D, 0xBCD3, 0xC18E, 0xBCD4, 0xC18F, 0x9990, 0xC190, 0xBCD5, 0xC191, 0x9991, 0xC192, 0x9992, 0xC193, 0x9993, - 0xC194, 0xBCD6, 0xC195, 0x9994, 0xC196, 0xBCD7, 0xC197, 0x9995, 0xC198, 0x9996, 0xC199, 0x9997, 0xC19A, 0x9998, 0xC19B, 0x9999, - 0xC19C, 0xBCD8, 0xC19D, 0xBCD9, 0xC19E, 0x999A, 0xC19F, 0xBCDA, 0xC1A0, 0x999B, 0xC1A1, 0xBCDB, 0xC1A2, 0x999C, 0xC1A3, 0x999D, - 0xC1A4, 0x999E, 0xC1A5, 0xBCDC, 0xC1A6, 0x999F, 0xC1A7, 0x99A0, 0xC1A8, 0xBCDD, 0xC1A9, 0xBCDE, 0xC1AA, 0x99A1, 0xC1AB, 0x99A2, - 0xC1AC, 0xBCDF, 0xC1AD, 0x99A3, 0xC1AE, 0x99A4, 0xC1AF, 0x99A5, 0xC1B0, 0xBCE0, 0xC1B1, 0x99A6, 0xC1B2, 0x99A7, 0xC1B3, 0x99A8, - 0xC1B4, 0x99A9, 0xC1B5, 0x99AA, 0xC1B6, 0x99AB, 0xC1B7, 0x99AC, 0xC1B8, 0x99AD, 0xC1B9, 0x99AE, 0xC1BA, 0x99AF, 0xC1BB, 0x99B0, - 0xC1BC, 0x99B1, 0xC1BD, 0xBCE1, 0xC1BE, 0x99B2, 0xC1BF, 0x99B3, 0xC1C0, 0x99B4, 0xC1C1, 0x99B5, 0xC1C2, 0x99B6, 0xC1C3, 0x99B7, - 0xC1C4, 0xBCE2, 0xC1C5, 0x99B8, 0xC1C6, 0x99B9, 0xC1C7, 0x99BA, 0xC1C8, 0xBCE3, 0xC1C9, 0x99BB, 0xC1CA, 0x99BC, 0xC1CB, 0x99BD, - 0xC1CC, 0xBCE4, 0xC1CD, 0x99BE, 0xC1CE, 0x99BF, 0xC1CF, 0x99C0, 0xC1D0, 0x99C1, 0xC1D1, 0x99C2, 0xC1D2, 0x99C3, 0xC1D3, 0x99C4, - 0xC1D4, 0xBCE5, 0xC1D5, 0x99C5, 0xC1D6, 0x99C6, 0xC1D7, 0xBCE6, 0xC1D8, 0xBCE7, 0xC1D9, 0x99C7, 0xC1DA, 0x99C8, 0xC1DB, 0x99C9, - 0xC1DC, 0x99CA, 0xC1DD, 0x99CB, 0xC1DE, 0x99CC, 0xC1DF, 0x99CD, 0xC1E0, 0xBCE8, 0xC1E1, 0x99CE, 0xC1E2, 0x99CF, 0xC1E3, 0x99D0, - 0xC1E4, 0xBCE9, 0xC1E5, 0x99D1, 0xC1E6, 0x99D2, 0xC1E7, 0x99D3, 0xC1E8, 0xBCEA, 0xC1E9, 0x99D4, 0xC1EA, 0x99D5, 0xC1EB, 0x99D6, - 0xC1EC, 0x99D7, 0xC1ED, 0x99D8, 0xC1EE, 0x99D9, 0xC1EF, 0x99DA, 0xC1F0, 0xBCEB, 0xC1F1, 0xBCEC, 0xC1F2, 0x99DB, 0xC1F3, 0xBCED, - 0xC1F4, 0x99DC, 0xC1F5, 0x99DD, 0xC1F6, 0x99DE, 0xC1F7, 0x99DF, 0xC1F8, 0x99E0, 0xC1F9, 0x99E1, 0xC1FA, 0x99E2, 0xC1FB, 0x99E3, - 0xC1FC, 0xBCEE, 0xC1FD, 0xBCEF, 0xC1FE, 0x99E4, 0xC1FF, 0x99E5, 0xC200, 0xBCF0, 0xC201, 0x99E6, 0xC202, 0x99E7, 0xC203, 0x99E8, - 0xC204, 0xBCF1, 0xC205, 0x99E9, 0xC206, 0x99EA, 0xC207, 0x99EB, 0xC208, 0x99EC, 0xC209, 0x99ED, 0xC20A, 0x99EE, 0xC20B, 0x99EF, - 0xC20C, 0xBCF2, 0xC20D, 0xBCF3, 0xC20E, 0x99F0, 0xC20F, 0xBCF4, 0xC210, 0x99F1, 0xC211, 0xBCF5, 0xC212, 0x99F2, 0xC213, 0x99F3, - 0xC214, 0x99F4, 0xC215, 0x99F5, 0xC216, 0x99F6, 0xC217, 0x99F7, 0xC218, 0xBCF6, 0xC219, 0xBCF7, 0xC21A, 0x99F8, 0xC21B, 0x99F9, - 0xC21C, 0xBCF8, 0xC21D, 0x99FA, 0xC21E, 0x99FB, 0xC21F, 0xBCF9, 0xC220, 0xBCFA, 0xC221, 0x99FC, 0xC222, 0x99FD, 0xC223, 0x99FE, - 0xC224, 0x9A41, 0xC225, 0x9A42, 0xC226, 0x9A43, 0xC227, 0x9A44, 0xC228, 0xBCFB, 0xC229, 0xBCFC, 0xC22A, 0x9A45, 0xC22B, 0xBCFD, - 0xC22C, 0x9A46, 0xC22D, 0xBCFE, 0xC22E, 0x9A47, 0xC22F, 0xBDA1, 0xC230, 0x9A48, 0xC231, 0xBDA2, 0xC232, 0xBDA3, 0xC233, 0x9A49, - 0xC234, 0xBDA4, 0xC235, 0x9A4A, 0xC236, 0x9A4B, 0xC237, 0x9A4C, 0xC238, 0x9A4D, 0xC239, 0x9A4E, 0xC23A, 0x9A4F, 0xC23B, 0x9A50, - 0xC23C, 0x9A51, 0xC23D, 0x9A52, 0xC23E, 0x9A53, 0xC23F, 0x9A54, 0xC240, 0x9A55, 0xC241, 0x9A56, 0xC242, 0x9A57, 0xC243, 0x9A58, - 0xC244, 0x9A59, 0xC245, 0x9A5A, 0xC246, 0x9A61, 0xC247, 0x9A62, 0xC248, 0xBDA5, 0xC249, 0x9A63, 0xC24A, 0x9A64, 0xC24B, 0x9A65, - 0xC24C, 0x9A66, 0xC24D, 0x9A67, 0xC24E, 0x9A68, 0xC24F, 0x9A69, 0xC250, 0xBDA6, 0xC251, 0xBDA7, 0xC252, 0x9A6A, 0xC253, 0x9A6B, - 0xC254, 0xBDA8, 0xC255, 0x9A6C, 0xC256, 0x9A6D, 0xC257, 0x9A6E, 0xC258, 0xBDA9, 0xC259, 0x9A6F, 0xC25A, 0x9A70, 0xC25B, 0x9A71, - 0xC25C, 0x9A72, 0xC25D, 0x9A73, 0xC25E, 0x9A74, 0xC25F, 0x9A75, 0xC260, 0xBDAA, 0xC261, 0x9A76, 0xC262, 0x9A77, 0xC263, 0x9A78, - 0xC264, 0x9A79, 0xC265, 0xBDAB, 0xC266, 0x9A7A, 0xC267, 0x9A81, 0xC268, 0x9A82, 0xC269, 0x9A83, 0xC26A, 0x9A84, 0xC26B, 0x9A85, - 0xC26C, 0xBDAC, 0xC26D, 0xBDAD, 0xC26E, 0x9A86, 0xC26F, 0x9A87, 0xC270, 0xBDAE, 0xC271, 0x9A88, 0xC272, 0x9A89, 0xC273, 0x9A8A, - 0xC274, 0xBDAF, 0xC275, 0x9A8B, 0xC276, 0x9A8C, 0xC277, 0x9A8D, 0xC278, 0x9A8E, 0xC279, 0x9A8F, 0xC27A, 0x9A90, 0xC27B, 0x9A91, - 0xC27C, 0xBDB0, 0xC27D, 0xBDB1, 0xC27E, 0x9A92, 0xC27F, 0xBDB2, 0xC280, 0x9A93, 0xC281, 0xBDB3, 0xC282, 0x9A94, 0xC283, 0x9A95, - 0xC284, 0x9A96, 0xC285, 0x9A97, 0xC286, 0x9A98, 0xC287, 0x9A99, 0xC288, 0xBDB4, 0xC289, 0xBDB5, 0xC28A, 0x9A9A, 0xC28B, 0x9A9B, - 0xC28C, 0x9A9C, 0xC28D, 0x9A9D, 0xC28E, 0x9A9E, 0xC28F, 0x9A9F, 0xC290, 0xBDB6, 0xC291, 0x9AA0, 0xC292, 0x9AA1, 0xC293, 0x9AA2, - 0xC294, 0x9AA3, 0xC295, 0x9AA4, 0xC296, 0x9AA5, 0xC297, 0x9AA6, 0xC298, 0xBDB7, 0xC299, 0x9AA7, 0xC29A, 0x9AA8, 0xC29B, 0xBDB8, - 0xC29C, 0x9AA9, 0xC29D, 0xBDB9, 0xC29E, 0x9AAA, 0xC29F, 0x9AAB, 0xC2A0, 0x9AAC, 0xC2A1, 0x9AAD, 0xC2A2, 0x9AAE, 0xC2A3, 0x9AAF, - 0xC2A4, 0xBDBA, 0xC2A5, 0xBDBB, 0xC2A6, 0x9AB0, 0xC2A7, 0x9AB1, 0xC2A8, 0xBDBC, 0xC2A9, 0x9AB2, 0xC2AA, 0x9AB3, 0xC2AB, 0x9AB4, - 0xC2AC, 0xBDBD, 0xC2AD, 0xBDBE, 0xC2AE, 0x9AB5, 0xC2AF, 0x9AB6, 0xC2B0, 0x9AB7, 0xC2B1, 0x9AB8, 0xC2B2, 0x9AB9, 0xC2B3, 0x9ABA, - 0xC2B4, 0xBDBF, 0xC2B5, 0xBDC0, 0xC2B6, 0x9ABB, 0xC2B7, 0xBDC1, 0xC2B8, 0x9ABC, 0xC2B9, 0xBDC2, 0xC2BA, 0x9ABD, 0xC2BB, 0x9ABE, - 0xC2BC, 0x9ABF, 0xC2BD, 0x9AC0, 0xC2BE, 0x9AC1, 0xC2BF, 0x9AC2, 0xC2C0, 0x9AC3, 0xC2C1, 0x9AC4, 0xC2C2, 0x9AC5, 0xC2C3, 0x9AC6, - 0xC2C4, 0x9AC7, 0xC2C5, 0x9AC8, 0xC2C6, 0x9AC9, 0xC2C7, 0x9ACA, 0xC2C8, 0x9ACB, 0xC2C9, 0x9ACC, 0xC2CA, 0x9ACD, 0xC2CB, 0x9ACE, - 0xC2CC, 0x9ACF, 0xC2CD, 0x9AD0, 0xC2CE, 0x9AD1, 0xC2CF, 0x9AD2, 0xC2D0, 0x9AD3, 0xC2D1, 0x9AD4, 0xC2D2, 0x9AD5, 0xC2D3, 0x9AD6, - 0xC2D4, 0x9AD7, 0xC2D5, 0x9AD8, 0xC2D6, 0x9AD9, 0xC2D7, 0x9ADA, 0xC2D8, 0x9ADB, 0xC2D9, 0x9ADC, 0xC2DA, 0x9ADD, 0xC2DB, 0x9ADE, - 0xC2DC, 0xBDC3, 0xC2DD, 0xBDC4, 0xC2DE, 0x9ADF, 0xC2DF, 0x9AE0, 0xC2E0, 0xBDC5, 0xC2E1, 0x9AE1, 0xC2E2, 0x9AE2, 0xC2E3, 0xBDC6, - 0xC2E4, 0xBDC7, 0xC2E5, 0x9AE3, 0xC2E6, 0x9AE4, 0xC2E7, 0x9AE5, 0xC2E8, 0x9AE6, 0xC2E9, 0x9AE7, 0xC2EA, 0x9AE8, 0xC2EB, 0xBDC8, - 0xC2EC, 0xBDC9, 0xC2ED, 0xBDCA, 0xC2EE, 0x9AE9, 0xC2EF, 0xBDCB, 0xC2F0, 0x9AEA, 0xC2F1, 0xBDCC, 0xC2F2, 0x9AEB, 0xC2F3, 0x9AEC, - 0xC2F4, 0x9AED, 0xC2F5, 0x9AEE, 0xC2F6, 0xBDCD, 0xC2F7, 0x9AEF, 0xC2F8, 0xBDCE, 0xC2F9, 0xBDCF, 0xC2FA, 0x9AF0, 0xC2FB, 0xBDD0, - 0xC2FC, 0xBDD1, 0xC2FD, 0x9AF1, 0xC2FE, 0x9AF2, 0xC2FF, 0x9AF3, 0xC300, 0xBDD2, 0xC301, 0x9AF4, 0xC302, 0x9AF5, 0xC303, 0x9AF6, - 0xC304, 0x9AF7, 0xC305, 0x9AF8, 0xC306, 0x9AF9, 0xC307, 0x9AFA, 0xC308, 0xBDD3, 0xC309, 0xBDD4, 0xC30A, 0x9AFB, 0xC30B, 0x9AFC, - 0xC30C, 0xBDD5, 0xC30D, 0xBDD6, 0xC30E, 0x9AFD, 0xC30F, 0x9AFE, 0xC310, 0x9B41, 0xC311, 0x9B42, 0xC312, 0x9B43, 0xC313, 0xBDD7, - 0xC314, 0xBDD8, 0xC315, 0xBDD9, 0xC316, 0x9B44, 0xC317, 0x9B45, 0xC318, 0xBDDA, 0xC319, 0x9B46, 0xC31A, 0x9B47, 0xC31B, 0x9B48, - 0xC31C, 0xBDDB, 0xC31D, 0x9B49, 0xC31E, 0x9B4A, 0xC31F, 0x9B4B, 0xC320, 0x9B4C, 0xC321, 0x9B4D, 0xC322, 0x9B4E, 0xC323, 0x9B4F, - 0xC324, 0xBDDC, 0xC325, 0xBDDD, 0xC326, 0x9B50, 0xC327, 0x9B51, 0xC328, 0xBDDE, 0xC329, 0xBDDF, 0xC32A, 0x9B52, 0xC32B, 0x9B53, - 0xC32C, 0x9B54, 0xC32D, 0x9B55, 0xC32E, 0x9B56, 0xC32F, 0x9B57, 0xC330, 0x9B58, 0xC331, 0x9B59, 0xC332, 0x9B5A, 0xC333, 0x9B61, - 0xC334, 0x9B62, 0xC335, 0x9B63, 0xC336, 0x9B64, 0xC337, 0x9B65, 0xC338, 0x9B66, 0xC339, 0x9B67, 0xC33A, 0x9B68, 0xC33B, 0x9B69, - 0xC33C, 0x9B6A, 0xC33D, 0x9B6B, 0xC33E, 0x9B6C, 0xC33F, 0x9B6D, 0xC340, 0x9B6E, 0xC341, 0x9B6F, 0xC342, 0x9B70, 0xC343, 0x9B71, - 0xC344, 0x9B72, 0xC345, 0xBDE0, 0xC346, 0x9B73, 0xC347, 0x9B74, 0xC348, 0x9B75, 0xC349, 0x9B76, 0xC34A, 0x9B77, 0xC34B, 0x9B78, - 0xC34C, 0x9B79, 0xC34D, 0x9B7A, 0xC34E, 0x9B81, 0xC34F, 0x9B82, 0xC350, 0x9B83, 0xC351, 0x9B84, 0xC352, 0x9B85, 0xC353, 0x9B86, - 0xC354, 0x9B87, 0xC355, 0x9B88, 0xC356, 0x9B89, 0xC357, 0x9B8A, 0xC358, 0x9B8B, 0xC359, 0x9B8C, 0xC35A, 0x9B8D, 0xC35B, 0x9B8E, - 0xC35C, 0x9B8F, 0xC35D, 0x9B90, 0xC35E, 0x9B91, 0xC35F, 0x9B92, 0xC360, 0x9B93, 0xC361, 0x9B94, 0xC362, 0x9B95, 0xC363, 0x9B96, - 0xC364, 0x9B97, 0xC365, 0x9B98, 0xC366, 0x9B99, 0xC367, 0x9B9A, 0xC368, 0xBDE1, 0xC369, 0xBDE2, 0xC36A, 0x9B9B, 0xC36B, 0x9B9C, - 0xC36C, 0xBDE3, 0xC36D, 0x9B9D, 0xC36E, 0x9B9E, 0xC36F, 0x9B9F, 0xC370, 0xBDE4, 0xC371, 0x9BA0, 0xC372, 0xBDE5, 0xC373, 0x9BA1, - 0xC374, 0x9BA2, 0xC375, 0x9BA3, 0xC376, 0x9BA4, 0xC377, 0x9BA5, 0xC378, 0xBDE6, 0xC379, 0xBDE7, 0xC37A, 0x9BA6, 0xC37B, 0x9BA7, - 0xC37C, 0xBDE8, 0xC37D, 0xBDE9, 0xC37E, 0x9BA8, 0xC37F, 0x9BA9, 0xC380, 0x9BAA, 0xC381, 0x9BAB, 0xC382, 0x9BAC, 0xC383, 0x9BAD, - 0xC384, 0xBDEA, 0xC385, 0x9BAE, 0xC386, 0x9BAF, 0xC387, 0x9BB0, 0xC388, 0xBDEB, 0xC389, 0x9BB1, 0xC38A, 0x9BB2, 0xC38B, 0x9BB3, - 0xC38C, 0xBDEC, 0xC38D, 0x9BB4, 0xC38E, 0x9BB5, 0xC38F, 0x9BB6, 0xC390, 0x9BB7, 0xC391, 0x9BB8, 0xC392, 0x9BB9, 0xC393, 0x9BBA, - 0xC394, 0x9BBB, 0xC395, 0x9BBC, 0xC396, 0x9BBD, 0xC397, 0x9BBE, 0xC398, 0x9BBF, 0xC399, 0x9BC0, 0xC39A, 0x9BC1, 0xC39B, 0x9BC2, - 0xC39C, 0x9BC3, 0xC39D, 0x9BC4, 0xC39E, 0x9BC5, 0xC39F, 0x9BC6, 0xC3A0, 0x9BC7, 0xC3A1, 0x9BC8, 0xC3A2, 0x9BC9, 0xC3A3, 0x9BCA, - 0xC3A4, 0x9BCB, 0xC3A5, 0x9BCC, 0xC3A6, 0x9BCD, 0xC3A7, 0x9BCE, 0xC3A8, 0x9BCF, 0xC3A9, 0x9BD0, 0xC3AA, 0x9BD1, 0xC3AB, 0x9BD2, - 0xC3AC, 0x9BD3, 0xC3AD, 0x9BD4, 0xC3AE, 0x9BD5, 0xC3AF, 0x9BD6, 0xC3B0, 0x9BD7, 0xC3B1, 0x9BD8, 0xC3B2, 0x9BD9, 0xC3B3, 0x9BDA, - 0xC3B4, 0x9BDB, 0xC3B5, 0x9BDC, 0xC3B6, 0x9BDD, 0xC3B7, 0x9BDE, 0xC3B8, 0x9BDF, 0xC3B9, 0x9BE0, 0xC3BA, 0x9BE1, 0xC3BB, 0x9BE2, - 0xC3BC, 0x9BE3, 0xC3BD, 0x9BE4, 0xC3BE, 0x9BE5, 0xC3BF, 0x9BE6, 0xC3C0, 0xBDED, 0xC3C1, 0x9BE7, 0xC3C2, 0x9BE8, 0xC3C3, 0x9BE9, - 0xC3C4, 0x9BEA, 0xC3C5, 0x9BEB, 0xC3C6, 0x9BEC, 0xC3C7, 0x9BED, 0xC3C8, 0x9BEE, 0xC3C9, 0x9BEF, 0xC3CA, 0x9BF0, 0xC3CB, 0x9BF1, - 0xC3CC, 0x9BF2, 0xC3CD, 0x9BF3, 0xC3CE, 0x9BF4, 0xC3CF, 0x9BF5, 0xC3D0, 0x9BF6, 0xC3D1, 0x9BF7, 0xC3D2, 0x9BF8, 0xC3D3, 0x9BF9, - 0xC3D4, 0x9BFA, 0xC3D5, 0x9BFB, 0xC3D6, 0x9BFC, 0xC3D7, 0x9BFD, 0xC3D8, 0xBDEE, 0xC3D9, 0xBDEF, 0xC3DA, 0x9BFE, 0xC3DB, 0x9C41, - 0xC3DC, 0xBDF0, 0xC3DD, 0x9C42, 0xC3DE, 0x9C43, 0xC3DF, 0xBDF1, 0xC3E0, 0xBDF2, 0xC3E1, 0x9C44, 0xC3E2, 0xBDF3, 0xC3E3, 0x9C45, - 0xC3E4, 0x9C46, 0xC3E5, 0x9C47, 0xC3E6, 0x9C48, 0xC3E7, 0x9C49, 0xC3E8, 0xBDF4, 0xC3E9, 0xBDF5, 0xC3EA, 0x9C4A, 0xC3EB, 0x9C4B, - 0xC3EC, 0x9C4C, 0xC3ED, 0xBDF6, 0xC3EE, 0x9C4D, 0xC3EF, 0x9C4E, 0xC3F0, 0x9C4F, 0xC3F1, 0x9C50, 0xC3F2, 0x9C51, 0xC3F3, 0x9C52, - 0xC3F4, 0xBDF7, 0xC3F5, 0xBDF8, 0xC3F6, 0x9C53, 0xC3F7, 0x9C54, 0xC3F8, 0xBDF9, 0xC3F9, 0x9C55, 0xC3FA, 0x9C56, 0xC3FB, 0x9C57, - 0xC3FC, 0x9C58, 0xC3FD, 0x9C59, 0xC3FE, 0x9C5A, 0xC3FF, 0x9C61, 0xC400, 0x9C62, 0xC401, 0x9C63, 0xC402, 0x9C64, 0xC403, 0x9C65, - 0xC404, 0x9C66, 0xC405, 0x9C67, 0xC406, 0x9C68, 0xC407, 0x9C69, 0xC408, 0xBDFA, 0xC409, 0x9C6A, 0xC40A, 0x9C6B, 0xC40B, 0x9C6C, - 0xC40C, 0x9C6D, 0xC40D, 0x9C6E, 0xC40E, 0x9C6F, 0xC40F, 0x9C70, 0xC410, 0xBDFB, 0xC411, 0x9C71, 0xC412, 0x9C72, 0xC413, 0x9C73, - 0xC414, 0x9C74, 0xC415, 0x9C75, 0xC416, 0x9C76, 0xC417, 0x9C77, 0xC418, 0x9C78, 0xC419, 0x9C79, 0xC41A, 0x9C7A, 0xC41B, 0x9C81, - 0xC41C, 0x9C82, 0xC41D, 0x9C83, 0xC41E, 0x9C84, 0xC41F, 0x9C85, 0xC420, 0x9C86, 0xC421, 0x9C87, 0xC422, 0x9C88, 0xC423, 0x9C89, - 0xC424, 0xBDFC, 0xC425, 0x9C8A, 0xC426, 0x9C8B, 0xC427, 0x9C8C, 0xC428, 0x9C8D, 0xC429, 0x9C8E, 0xC42A, 0x9C8F, 0xC42B, 0x9C90, - 0xC42C, 0xBDFD, 0xC42D, 0x9C91, 0xC42E, 0x9C92, 0xC42F, 0x9C93, 0xC430, 0xBDFE, 0xC431, 0x9C94, 0xC432, 0x9C95, 0xC433, 0x9C96, - 0xC434, 0xBEA1, 0xC435, 0x9C97, 0xC436, 0x9C98, 0xC437, 0x9C99, 0xC438, 0x9C9A, 0xC439, 0x9C9B, 0xC43A, 0x9C9C, 0xC43B, 0x9C9D, - 0xC43C, 0xBEA2, 0xC43D, 0xBEA3, 0xC43E, 0x9C9E, 0xC43F, 0x9C9F, 0xC440, 0x9CA0, 0xC441, 0x9CA1, 0xC442, 0x9CA2, 0xC443, 0x9CA3, - 0xC444, 0x9CA4, 0xC445, 0x9CA5, 0xC446, 0x9CA6, 0xC447, 0x9CA7, 0xC448, 0xBEA4, 0xC449, 0x9CA8, 0xC44A, 0x9CA9, 0xC44B, 0x9CAA, - 0xC44C, 0x9CAB, 0xC44D, 0x9CAC, 0xC44E, 0x9CAD, 0xC44F, 0x9CAE, 0xC450, 0x9CAF, 0xC451, 0x9CB0, 0xC452, 0x9CB1, 0xC453, 0x9CB2, - 0xC454, 0x9CB3, 0xC455, 0x9CB4, 0xC456, 0x9CB5, 0xC457, 0x9CB6, 0xC458, 0x9CB7, 0xC459, 0x9CB8, 0xC45A, 0x9CB9, 0xC45B, 0x9CBA, - 0xC45C, 0x9CBB, 0xC45D, 0x9CBC, 0xC45E, 0x9CBD, 0xC45F, 0x9CBE, 0xC460, 0x9CBF, 0xC461, 0x9CC0, 0xC462, 0x9CC1, 0xC463, 0x9CC2, - 0xC464, 0xBEA5, 0xC465, 0xBEA6, 0xC466, 0x9CC3, 0xC467, 0x9CC4, 0xC468, 0xBEA7, 0xC469, 0x9CC5, 0xC46A, 0x9CC6, 0xC46B, 0x9CC7, - 0xC46C, 0xBEA8, 0xC46D, 0x9CC8, 0xC46E, 0x9CC9, 0xC46F, 0x9CCA, 0xC470, 0x9CCB, 0xC471, 0x9CCC, 0xC472, 0x9CCD, 0xC473, 0x9CCE, - 0xC474, 0xBEA9, 0xC475, 0xBEAA, 0xC476, 0x9CCF, 0xC477, 0x9CD0, 0xC478, 0x9CD1, 0xC479, 0xBEAB, 0xC47A, 0x9CD2, 0xC47B, 0x9CD3, - 0xC47C, 0x9CD4, 0xC47D, 0x9CD5, 0xC47E, 0x9CD6, 0xC47F, 0x9CD7, 0xC480, 0xBEAC, 0xC481, 0x9CD8, 0xC482, 0x9CD9, 0xC483, 0x9CDA, - 0xC484, 0x9CDB, 0xC485, 0x9CDC, 0xC486, 0x9CDD, 0xC487, 0x9CDE, 0xC488, 0x9CDF, 0xC489, 0x9CE0, 0xC48A, 0x9CE1, 0xC48B, 0x9CE2, - 0xC48C, 0x9CE3, 0xC48D, 0x9CE4, 0xC48E, 0x9CE5, 0xC48F, 0x9CE6, 0xC490, 0x9CE7, 0xC491, 0x9CE8, 0xC492, 0x9CE9, 0xC493, 0x9CEA, - 0xC494, 0xBEAD, 0xC495, 0x9CEB, 0xC496, 0x9CEC, 0xC497, 0x9CED, 0xC498, 0x9CEE, 0xC499, 0x9CEF, 0xC49A, 0x9CF0, 0xC49B, 0x9CF1, - 0xC49C, 0xBEAE, 0xC49D, 0x9CF2, 0xC49E, 0x9CF3, 0xC49F, 0x9CF4, 0xC4A0, 0x9CF5, 0xC4A1, 0x9CF6, 0xC4A2, 0x9CF7, 0xC4A3, 0x9CF8, - 0xC4A4, 0x9CF9, 0xC4A5, 0x9CFA, 0xC4A6, 0x9CFB, 0xC4A7, 0x9CFC, 0xC4A8, 0x9CFD, 0xC4A9, 0x9CFE, 0xC4AA, 0x9D41, 0xC4AB, 0x9D42, - 0xC4AC, 0x9D43, 0xC4AD, 0x9D44, 0xC4AE, 0x9D45, 0xC4AF, 0x9D46, 0xC4B0, 0x9D47, 0xC4B1, 0x9D48, 0xC4B2, 0x9D49, 0xC4B3, 0x9D4A, - 0xC4B4, 0x9D4B, 0xC4B5, 0x9D4C, 0xC4B6, 0x9D4D, 0xC4B7, 0x9D4E, 0xC4B8, 0xBEAF, 0xC4B9, 0x9D4F, 0xC4BA, 0x9D50, 0xC4BB, 0x9D51, - 0xC4BC, 0xBEB0, 0xC4BD, 0x9D52, 0xC4BE, 0x9D53, 0xC4BF, 0x9D54, 0xC4C0, 0x9D55, 0xC4C1, 0x9D56, 0xC4C2, 0x9D57, 0xC4C3, 0x9D58, - 0xC4C4, 0x9D59, 0xC4C5, 0x9D5A, 0xC4C6, 0x9D61, 0xC4C7, 0x9D62, 0xC4C8, 0x9D63, 0xC4C9, 0x9D64, 0xC4CA, 0x9D65, 0xC4CB, 0x9D66, - 0xC4CC, 0x9D67, 0xC4CD, 0x9D68, 0xC4CE, 0x9D69, 0xC4CF, 0x9D6A, 0xC4D0, 0x9D6B, 0xC4D1, 0x9D6C, 0xC4D2, 0x9D6D, 0xC4D3, 0x9D6E, - 0xC4D4, 0x9D6F, 0xC4D5, 0x9D70, 0xC4D6, 0x9D71, 0xC4D7, 0x9D72, 0xC4D8, 0x9D73, 0xC4D9, 0x9D74, 0xC4DA, 0x9D75, 0xC4DB, 0x9D76, - 0xC4DC, 0x9D77, 0xC4DD, 0x9D78, 0xC4DE, 0x9D79, 0xC4DF, 0x9D7A, 0xC4E0, 0x9D81, 0xC4E1, 0x9D82, 0xC4E2, 0x9D83, 0xC4E3, 0x9D84, - 0xC4E4, 0x9D85, 0xC4E5, 0x9D86, 0xC4E6, 0x9D87, 0xC4E7, 0x9D88, 0xC4E8, 0x9D89, 0xC4E9, 0xBEB1, 0xC4EA, 0x9D8A, 0xC4EB, 0x9D8B, - 0xC4EC, 0x9D8C, 0xC4ED, 0x9D8D, 0xC4EE, 0x9D8E, 0xC4EF, 0x9D8F, 0xC4F0, 0xBEB2, 0xC4F1, 0xBEB3, 0xC4F2, 0x9D90, 0xC4F3, 0x9D91, - 0xC4F4, 0xBEB4, 0xC4F5, 0x9D92, 0xC4F6, 0x9D93, 0xC4F7, 0x9D94, 0xC4F8, 0xBEB5, 0xC4F9, 0x9D95, 0xC4FA, 0xBEB6, 0xC4FB, 0x9D96, - 0xC4FC, 0x9D97, 0xC4FD, 0x9D98, 0xC4FE, 0x9D99, 0xC4FF, 0xBEB7, 0xC500, 0xBEB8, 0xC501, 0xBEB9, 0xC502, 0x9D9A, 0xC503, 0x9D9B, - 0xC504, 0x9D9C, 0xC505, 0x9D9D, 0xC506, 0x9D9E, 0xC507, 0x9D9F, 0xC508, 0x9DA0, 0xC509, 0x9DA1, 0xC50A, 0x9DA2, 0xC50B, 0x9DA3, - 0xC50C, 0xBEBA, 0xC50D, 0x9DA4, 0xC50E, 0x9DA5, 0xC50F, 0x9DA6, 0xC510, 0xBEBB, 0xC511, 0x9DA7, 0xC512, 0x9DA8, 0xC513, 0x9DA9, - 0xC514, 0xBEBC, 0xC515, 0x9DAA, 0xC516, 0x9DAB, 0xC517, 0x9DAC, 0xC518, 0x9DAD, 0xC519, 0x9DAE, 0xC51A, 0x9DAF, 0xC51B, 0x9DB0, - 0xC51C, 0xBEBD, 0xC51D, 0x9DB1, 0xC51E, 0x9DB2, 0xC51F, 0x9DB3, 0xC520, 0x9DB4, 0xC521, 0x9DB5, 0xC522, 0x9DB6, 0xC523, 0x9DB7, - 0xC524, 0x9DB8, 0xC525, 0x9DB9, 0xC526, 0x9DBA, 0xC527, 0x9DBB, 0xC528, 0xBEBE, 0xC529, 0xBEBF, 0xC52A, 0x9DBC, 0xC52B, 0x9DBD, - 0xC52C, 0xBEC0, 0xC52D, 0x9DBE, 0xC52E, 0x9DBF, 0xC52F, 0x9DC0, 0xC530, 0xBEC1, 0xC531, 0x9DC1, 0xC532, 0x9DC2, 0xC533, 0x9DC3, - 0xC534, 0x9DC4, 0xC535, 0x9DC5, 0xC536, 0x9DC6, 0xC537, 0x9DC7, 0xC538, 0xBEC2, 0xC539, 0xBEC3, 0xC53A, 0x9DC8, 0xC53B, 0xBEC4, - 0xC53C, 0x9DC9, 0xC53D, 0xBEC5, 0xC53E, 0x9DCA, 0xC53F, 0x9DCB, 0xC540, 0x9DCC, 0xC541, 0x9DCD, 0xC542, 0x9DCE, 0xC543, 0x9DCF, - 0xC544, 0xBEC6, 0xC545, 0xBEC7, 0xC546, 0x9DD0, 0xC547, 0x9DD1, 0xC548, 0xBEC8, 0xC549, 0xBEC9, 0xC54A, 0xBECA, 0xC54B, 0x9DD2, - 0xC54C, 0xBECB, 0xC54D, 0xBECC, 0xC54E, 0xBECD, 0xC54F, 0x9DD3, 0xC550, 0x9DD4, 0xC551, 0x9DD5, 0xC552, 0x9DD6, 0xC553, 0xBECE, - 0xC554, 0xBECF, 0xC555, 0xBED0, 0xC556, 0x9DD7, 0xC557, 0xBED1, 0xC558, 0xBED2, 0xC559, 0xBED3, 0xC55A, 0x9DD8, 0xC55B, 0x9DD9, - 0xC55C, 0x9DDA, 0xC55D, 0xBED4, 0xC55E, 0xBED5, 0xC55F, 0x9DDB, 0xC560, 0xBED6, 0xC561, 0xBED7, 0xC562, 0x9DDC, 0xC563, 0x9DDD, - 0xC564, 0xBED8, 0xC565, 0x9DDE, 0xC566, 0x9DDF, 0xC567, 0x9DE0, 0xC568, 0xBED9, 0xC569, 0x9DE1, 0xC56A, 0x9DE2, 0xC56B, 0x9DE3, - 0xC56C, 0x9DE4, 0xC56D, 0x9DE5, 0xC56E, 0x9DE6, 0xC56F, 0x9DE7, 0xC570, 0xBEDA, 0xC571, 0xBEDB, 0xC572, 0x9DE8, 0xC573, 0xBEDC, - 0xC574, 0xBEDD, 0xC575, 0xBEDE, 0xC576, 0x9DE9, 0xC577, 0x9DEA, 0xC578, 0x9DEB, 0xC579, 0x9DEC, 0xC57A, 0x9DED, 0xC57B, 0x9DEE, - 0xC57C, 0xBEDF, 0xC57D, 0xBEE0, 0xC57E, 0x9DEF, 0xC57F, 0x9DF0, 0xC580, 0xBEE1, 0xC581, 0x9DF1, 0xC582, 0x9DF2, 0xC583, 0x9DF3, - 0xC584, 0xBEE2, 0xC585, 0x9DF4, 0xC586, 0x9DF5, 0xC587, 0xBEE3, 0xC588, 0x9DF6, 0xC589, 0x9DF7, 0xC58A, 0x9DF8, 0xC58B, 0x9DF9, - 0xC58C, 0xBEE4, 0xC58D, 0xBEE5, 0xC58E, 0x9DFA, 0xC58F, 0xBEE6, 0xC590, 0x9DFB, 0xC591, 0xBEE7, 0xC592, 0x9DFC, 0xC593, 0x9DFD, - 0xC594, 0x9DFE, 0xC595, 0xBEE8, 0xC596, 0x9E41, 0xC597, 0xBEE9, 0xC598, 0xBEEA, 0xC599, 0x9E42, 0xC59A, 0x9E43, 0xC59B, 0x9E44, - 0xC59C, 0xBEEB, 0xC59D, 0x9E45, 0xC59E, 0x9E46, 0xC59F, 0x9E47, 0xC5A0, 0xBEEC, 0xC5A1, 0x9E48, 0xC5A2, 0x9E49, 0xC5A3, 0x9E4A, - 0xC5A4, 0x9E4B, 0xC5A5, 0x9E4C, 0xC5A6, 0x9E4D, 0xC5A7, 0x9E4E, 0xC5A8, 0x9E4F, 0xC5A9, 0xBEED, 0xC5AA, 0x9E50, 0xC5AB, 0x9E51, - 0xC5AC, 0x9E52, 0xC5AD, 0x9E53, 0xC5AE, 0x9E54, 0xC5AF, 0x9E55, 0xC5B0, 0x9E56, 0xC5B1, 0x9E57, 0xC5B2, 0x9E58, 0xC5B3, 0x9E59, - 0xC5B4, 0xBEEE, 0xC5B5, 0xBEEF, 0xC5B6, 0x9E5A, 0xC5B7, 0x9E61, 0xC5B8, 0xBEF0, 0xC5B9, 0xBEF1, 0xC5BA, 0x9E62, 0xC5BB, 0xBEF2, - 0xC5BC, 0xBEF3, 0xC5BD, 0xBEF4, 0xC5BE, 0xBEF5, 0xC5BF, 0x9E63, 0xC5C0, 0x9E64, 0xC5C1, 0x9E65, 0xC5C2, 0x9E66, 0xC5C3, 0x9E67, - 0xC5C4, 0xBEF6, 0xC5C5, 0xBEF7, 0xC5C6, 0xBEF8, 0xC5C7, 0xBEF9, 0xC5C8, 0xBEFA, 0xC5C9, 0xBEFB, 0xC5CA, 0xBEFC, 0xC5CB, 0x9E68, - 0xC5CC, 0xBEFD, 0xC5CD, 0x9E69, 0xC5CE, 0xBEFE, 0xC5CF, 0x9E6A, 0xC5D0, 0xBFA1, 0xC5D1, 0xBFA2, 0xC5D2, 0x9E6B, 0xC5D3, 0x9E6C, - 0xC5D4, 0xBFA3, 0xC5D5, 0x9E6D, 0xC5D6, 0x9E6E, 0xC5D7, 0x9E6F, 0xC5D8, 0xBFA4, 0xC5D9, 0x9E70, 0xC5DA, 0x9E71, 0xC5DB, 0x9E72, - 0xC5DC, 0x9E73, 0xC5DD, 0x9E74, 0xC5DE, 0x9E75, 0xC5DF, 0x9E76, 0xC5E0, 0xBFA5, 0xC5E1, 0xBFA6, 0xC5E2, 0x9E77, 0xC5E3, 0xBFA7, - 0xC5E4, 0x9E78, 0xC5E5, 0xBFA8, 0xC5E6, 0x9E79, 0xC5E7, 0x9E7A, 0xC5E8, 0x9E81, 0xC5E9, 0x9E82, 0xC5EA, 0x9E83, 0xC5EB, 0x9E84, - 0xC5EC, 0xBFA9, 0xC5ED, 0xBFAA, 0xC5EE, 0xBFAB, 0xC5EF, 0x9E85, 0xC5F0, 0xBFAC, 0xC5F1, 0x9E86, 0xC5F2, 0x9E87, 0xC5F3, 0x9E88, - 0xC5F4, 0xBFAD, 0xC5F5, 0x9E89, 0xC5F6, 0xBFAE, 0xC5F7, 0xBFAF, 0xC5F8, 0x9E8A, 0xC5F9, 0x9E8B, 0xC5FA, 0x9E8C, 0xC5FB, 0x9E8D, - 0xC5FC, 0xBFB0, 0xC5FD, 0xBFB1, 0xC5FE, 0xBFB2, 0xC5FF, 0xBFB3, 0xC600, 0xBFB4, 0xC601, 0xBFB5, 0xC602, 0x9E8E, 0xC603, 0x9E8F, - 0xC604, 0x9E90, 0xC605, 0xBFB6, 0xC606, 0xBFB7, 0xC607, 0xBFB8, 0xC608, 0xBFB9, 0xC609, 0x9E91, 0xC60A, 0x9E92, 0xC60B, 0x9E93, - 0xC60C, 0xBFBA, 0xC60D, 0x9E94, 0xC60E, 0x9E95, 0xC60F, 0x9E96, 0xC610, 0xBFBB, 0xC611, 0x9E97, 0xC612, 0x9E98, 0xC613, 0x9E99, - 0xC614, 0x9E9A, 0xC615, 0x9E9B, 0xC616, 0x9E9C, 0xC617, 0x9E9D, 0xC618, 0xBFBC, 0xC619, 0xBFBD, 0xC61A, 0x9E9E, 0xC61B, 0xBFBE, - 0xC61C, 0xBFBF, 0xC61D, 0x9E9F, 0xC61E, 0x9EA0, 0xC61F, 0x9EA1, 0xC620, 0x9EA2, 0xC621, 0x9EA3, 0xC622, 0x9EA4, 0xC623, 0x9EA5, - 0xC624, 0xBFC0, 0xC625, 0xBFC1, 0xC626, 0x9EA6, 0xC627, 0x9EA7, 0xC628, 0xBFC2, 0xC629, 0x9EA8, 0xC62A, 0x9EA9, 0xC62B, 0x9EAA, - 0xC62C, 0xBFC3, 0xC62D, 0xBFC4, 0xC62E, 0xBFC5, 0xC62F, 0x9EAB, 0xC630, 0xBFC6, 0xC631, 0x9EAC, 0xC632, 0x9EAD, 0xC633, 0xBFC7, - 0xC634, 0xBFC8, 0xC635, 0xBFC9, 0xC636, 0x9EAE, 0xC637, 0xBFCA, 0xC638, 0x9EAF, 0xC639, 0xBFCB, 0xC63A, 0x9EB0, 0xC63B, 0xBFCC, - 0xC63C, 0x9EB1, 0xC63D, 0x9EB2, 0xC63E, 0x9EB3, 0xC63F, 0x9EB4, 0xC640, 0xBFCD, 0xC641, 0xBFCE, 0xC642, 0x9EB5, 0xC643, 0x9EB6, - 0xC644, 0xBFCF, 0xC645, 0x9EB7, 0xC646, 0x9EB8, 0xC647, 0x9EB9, 0xC648, 0xBFD0, 0xC649, 0x9EBA, 0xC64A, 0x9EBB, 0xC64B, 0x9EBC, - 0xC64C, 0x9EBD, 0xC64D, 0x9EBE, 0xC64E, 0x9EBF, 0xC64F, 0x9EC0, 0xC650, 0xBFD1, 0xC651, 0xBFD2, 0xC652, 0x9EC1, 0xC653, 0xBFD3, - 0xC654, 0xBFD4, 0xC655, 0xBFD5, 0xC656, 0x9EC2, 0xC657, 0x9EC3, 0xC658, 0x9EC4, 0xC659, 0x9EC5, 0xC65A, 0x9EC6, 0xC65B, 0x9EC7, - 0xC65C, 0xBFD6, 0xC65D, 0xBFD7, 0xC65E, 0x9EC8, 0xC65F, 0x9EC9, 0xC660, 0xBFD8, 0xC661, 0x9ECA, 0xC662, 0x9ECB, 0xC663, 0x9ECC, - 0xC664, 0x9ECD, 0xC665, 0x9ECE, 0xC666, 0x9ECF, 0xC667, 0x9ED0, 0xC668, 0x9ED1, 0xC669, 0x9ED2, 0xC66A, 0x9ED3, 0xC66B, 0x9ED4, - 0xC66C, 0xBFD9, 0xC66D, 0x9ED5, 0xC66E, 0x9ED6, 0xC66F, 0xBFDA, 0xC670, 0x9ED7, 0xC671, 0xBFDB, 0xC672, 0x9ED8, 0xC673, 0x9ED9, - 0xC674, 0x9EDA, 0xC675, 0x9EDB, 0xC676, 0x9EDC, 0xC677, 0x9EDD, 0xC678, 0xBFDC, 0xC679, 0xBFDD, 0xC67A, 0x9EDE, 0xC67B, 0x9EDF, - 0xC67C, 0xBFDE, 0xC67D, 0x9EE0, 0xC67E, 0x9EE1, 0xC67F, 0x9EE2, 0xC680, 0xBFDF, 0xC681, 0x9EE3, 0xC682, 0x9EE4, 0xC683, 0x9EE5, - 0xC684, 0x9EE6, 0xC685, 0x9EE7, 0xC686, 0x9EE8, 0xC687, 0x9EE9, 0xC688, 0xBFE0, 0xC689, 0xBFE1, 0xC68A, 0x9EEA, 0xC68B, 0xBFE2, - 0xC68C, 0x9EEB, 0xC68D, 0xBFE3, 0xC68E, 0x9EEC, 0xC68F, 0x9EED, 0xC690, 0x9EEE, 0xC691, 0x9EEF, 0xC692, 0x9EF0, 0xC693, 0x9EF1, - 0xC694, 0xBFE4, 0xC695, 0xBFE5, 0xC696, 0x9EF2, 0xC697, 0x9EF3, 0xC698, 0xBFE6, 0xC699, 0x9EF4, 0xC69A, 0x9EF5, 0xC69B, 0x9EF6, - 0xC69C, 0xBFE7, 0xC69D, 0x9EF7, 0xC69E, 0x9EF8, 0xC69F, 0x9EF9, 0xC6A0, 0x9EFA, 0xC6A1, 0x9EFB, 0xC6A2, 0x9EFC, 0xC6A3, 0x9EFD, - 0xC6A4, 0xBFE8, 0xC6A5, 0xBFE9, 0xC6A6, 0x9EFE, 0xC6A7, 0xBFEA, 0xC6A8, 0x9F41, 0xC6A9, 0xBFEB, 0xC6AA, 0x9F42, 0xC6AB, 0x9F43, - 0xC6AC, 0x9F44, 0xC6AD, 0x9F45, 0xC6AE, 0x9F46, 0xC6AF, 0x9F47, 0xC6B0, 0xBFEC, 0xC6B1, 0xBFED, 0xC6B2, 0x9F48, 0xC6B3, 0x9F49, - 0xC6B4, 0xBFEE, 0xC6B5, 0x9F4A, 0xC6B6, 0x9F4B, 0xC6B7, 0x9F4C, 0xC6B8, 0xBFEF, 0xC6B9, 0xBFF0, 0xC6BA, 0xBFF1, 0xC6BB, 0x9F4D, - 0xC6BC, 0x9F4E, 0xC6BD, 0x9F4F, 0xC6BE, 0x9F50, 0xC6BF, 0x9F51, 0xC6C0, 0xBFF2, 0xC6C1, 0xBFF3, 0xC6C2, 0x9F52, 0xC6C3, 0xBFF4, - 0xC6C4, 0x9F53, 0xC6C5, 0xBFF5, 0xC6C6, 0x9F54, 0xC6C7, 0x9F55, 0xC6C8, 0x9F56, 0xC6C9, 0x9F57, 0xC6CA, 0x9F58, 0xC6CB, 0x9F59, - 0xC6CC, 0xBFF6, 0xC6CD, 0xBFF7, 0xC6CE, 0x9F5A, 0xC6CF, 0x9F61, 0xC6D0, 0xBFF8, 0xC6D1, 0x9F62, 0xC6D2, 0x9F63, 0xC6D3, 0x9F64, - 0xC6D4, 0xBFF9, 0xC6D5, 0x9F65, 0xC6D6, 0x9F66, 0xC6D7, 0x9F67, 0xC6D8, 0x9F68, 0xC6D9, 0x9F69, 0xC6DA, 0x9F6A, 0xC6DB, 0x9F6B, - 0xC6DC, 0xBFFA, 0xC6DD, 0xBFFB, 0xC6DE, 0x9F6C, 0xC6DF, 0x9F6D, 0xC6E0, 0xBFFC, 0xC6E1, 0xBFFD, 0xC6E2, 0x9F6E, 0xC6E3, 0x9F6F, - 0xC6E4, 0x9F70, 0xC6E5, 0x9F71, 0xC6E6, 0x9F72, 0xC6E7, 0x9F73, 0xC6E8, 0xBFFE, 0xC6E9, 0xC0A1, 0xC6EA, 0x9F74, 0xC6EB, 0x9F75, - 0xC6EC, 0xC0A2, 0xC6ED, 0x9F76, 0xC6EE, 0x9F77, 0xC6EF, 0x9F78, 0xC6F0, 0xC0A3, 0xC6F1, 0x9F79, 0xC6F2, 0x9F7A, 0xC6F3, 0x9F81, - 0xC6F4, 0x9F82, 0xC6F5, 0x9F83, 0xC6F6, 0x9F84, 0xC6F7, 0x9F85, 0xC6F8, 0xC0A4, 0xC6F9, 0xC0A5, 0xC6FA, 0x9F86, 0xC6FB, 0x9F87, - 0xC6FC, 0x9F88, 0xC6FD, 0xC0A6, 0xC6FE, 0x9F89, 0xC6FF, 0x9F8A, 0xC700, 0x9F8B, 0xC701, 0x9F8C, 0xC702, 0x9F8D, 0xC703, 0x9F8E, - 0xC704, 0xC0A7, 0xC705, 0xC0A8, 0xC706, 0x9F8F, 0xC707, 0x9F90, 0xC708, 0xC0A9, 0xC709, 0x9F91, 0xC70A, 0x9F92, 0xC70B, 0x9F93, - 0xC70C, 0xC0AA, 0xC70D, 0x9F94, 0xC70E, 0x9F95, 0xC70F, 0x9F96, 0xC710, 0x9F97, 0xC711, 0x9F98, 0xC712, 0x9F99, 0xC713, 0x9F9A, - 0xC714, 0xC0AB, 0xC715, 0xC0AC, 0xC716, 0x9F9B, 0xC717, 0xC0AD, 0xC718, 0x9F9C, 0xC719, 0xC0AE, 0xC71A, 0x9F9D, 0xC71B, 0x9F9E, - 0xC71C, 0x9F9F, 0xC71D, 0x9FA0, 0xC71E, 0x9FA1, 0xC71F, 0x9FA2, 0xC720, 0xC0AF, 0xC721, 0xC0B0, 0xC722, 0x9FA3, 0xC723, 0x9FA4, - 0xC724, 0xC0B1, 0xC725, 0x9FA5, 0xC726, 0x9FA6, 0xC727, 0x9FA7, 0xC728, 0xC0B2, 0xC729, 0x9FA8, 0xC72A, 0x9FA9, 0xC72B, 0x9FAA, - 0xC72C, 0x9FAB, 0xC72D, 0x9FAC, 0xC72E, 0x9FAD, 0xC72F, 0x9FAE, 0xC730, 0xC0B3, 0xC731, 0xC0B4, 0xC732, 0x9FAF, 0xC733, 0xC0B5, - 0xC734, 0x9FB0, 0xC735, 0xC0B6, 0xC736, 0x9FB1, 0xC737, 0xC0B7, 0xC738, 0x9FB2, 0xC739, 0x9FB3, 0xC73A, 0x9FB4, 0xC73B, 0x9FB5, - 0xC73C, 0xC0B8, 0xC73D, 0xC0B9, 0xC73E, 0x9FB6, 0xC73F, 0x9FB7, 0xC740, 0xC0BA, 0xC741, 0x9FB8, 0xC742, 0x9FB9, 0xC743, 0x9FBA, - 0xC744, 0xC0BB, 0xC745, 0x9FBB, 0xC746, 0x9FBC, 0xC747, 0x9FBD, 0xC748, 0x9FBE, 0xC749, 0x9FBF, 0xC74A, 0xC0BC, 0xC74B, 0x9FC0, - 0xC74C, 0xC0BD, 0xC74D, 0xC0BE, 0xC74E, 0x9FC1, 0xC74F, 0xC0BF, 0xC750, 0x9FC2, 0xC751, 0xC0C0, 0xC752, 0xC0C1, 0xC753, 0xC0C2, - 0xC754, 0xC0C3, 0xC755, 0xC0C4, 0xC756, 0xC0C5, 0xC757, 0xC0C6, 0xC758, 0xC0C7, 0xC759, 0x9FC3, 0xC75A, 0x9FC4, 0xC75B, 0x9FC5, - 0xC75C, 0xC0C8, 0xC75D, 0x9FC6, 0xC75E, 0x9FC7, 0xC75F, 0x9FC8, 0xC760, 0xC0C9, 0xC761, 0x9FC9, 0xC762, 0x9FCA, 0xC763, 0x9FCB, - 0xC764, 0x9FCC, 0xC765, 0x9FCD, 0xC766, 0x9FCE, 0xC767, 0x9FCF, 0xC768, 0xC0CA, 0xC769, 0x9FD0, 0xC76A, 0x9FD1, 0xC76B, 0xC0CB, - 0xC76C, 0x9FD2, 0xC76D, 0x9FD3, 0xC76E, 0x9FD4, 0xC76F, 0x9FD5, 0xC770, 0x9FD6, 0xC771, 0x9FD7, 0xC772, 0x9FD8, 0xC773, 0x9FD9, - 0xC774, 0xC0CC, 0xC775, 0xC0CD, 0xC776, 0x9FDA, 0xC777, 0x9FDB, 0xC778, 0xC0CE, 0xC779, 0x9FDC, 0xC77A, 0x9FDD, 0xC77B, 0x9FDE, - 0xC77C, 0xC0CF, 0xC77D, 0xC0D0, 0xC77E, 0xC0D1, 0xC77F, 0x9FDF, 0xC780, 0x9FE0, 0xC781, 0x9FE1, 0xC782, 0x9FE2, 0xC783, 0xC0D2, - 0xC784, 0xC0D3, 0xC785, 0xC0D4, 0xC786, 0x9FE3, 0xC787, 0xC0D5, 0xC788, 0xC0D6, 0xC789, 0xC0D7, 0xC78A, 0xC0D8, 0xC78B, 0x9FE4, - 0xC78C, 0x9FE5, 0xC78D, 0x9FE6, 0xC78E, 0xC0D9, 0xC78F, 0x9FE7, 0xC790, 0xC0DA, 0xC791, 0xC0DB, 0xC792, 0x9FE8, 0xC793, 0x9FE9, - 0xC794, 0xC0DC, 0xC795, 0x9FEA, 0xC796, 0xC0DD, 0xC797, 0xC0DE, 0xC798, 0xC0DF, 0xC799, 0x9FEB, 0xC79A, 0xC0E0, 0xC79B, 0x9FEC, - 0xC79C, 0x9FED, 0xC79D, 0x9FEE, 0xC79E, 0x9FEF, 0xC79F, 0x9FF0, 0xC7A0, 0xC0E1, 0xC7A1, 0xC0E2, 0xC7A2, 0x9FF1, 0xC7A3, 0xC0E3, - 0xC7A4, 0xC0E4, 0xC7A5, 0xC0E5, 0xC7A6, 0xC0E6, 0xC7A7, 0x9FF2, 0xC7A8, 0x9FF3, 0xC7A9, 0x9FF4, 0xC7AA, 0x9FF5, 0xC7AB, 0x9FF6, - 0xC7AC, 0xC0E7, 0xC7AD, 0xC0E8, 0xC7AE, 0x9FF7, 0xC7AF, 0x9FF8, 0xC7B0, 0xC0E9, 0xC7B1, 0x9FF9, 0xC7B2, 0x9FFA, 0xC7B3, 0x9FFB, - 0xC7B4, 0xC0EA, 0xC7B5, 0x9FFC, 0xC7B6, 0x9FFD, 0xC7B7, 0x9FFE, 0xC7B8, 0xA041, 0xC7B9, 0xA042, 0xC7BA, 0xA043, 0xC7BB, 0xA044, - 0xC7BC, 0xC0EB, 0xC7BD, 0xC0EC, 0xC7BE, 0xA045, 0xC7BF, 0xC0ED, 0xC7C0, 0xC0EE, 0xC7C1, 0xC0EF, 0xC7C2, 0xA046, 0xC7C3, 0xA047, - 0xC7C4, 0xA048, 0xC7C5, 0xA049, 0xC7C6, 0xA04A, 0xC7C7, 0xA04B, 0xC7C8, 0xC0F0, 0xC7C9, 0xC0F1, 0xC7CA, 0xA04C, 0xC7CB, 0xA04D, - 0xC7CC, 0xC0F2, 0xC7CD, 0xA04E, 0xC7CE, 0xC0F3, 0xC7CF, 0xA04F, 0xC7D0, 0xC0F4, 0xC7D1, 0xA050, 0xC7D2, 0xA051, 0xC7D3, 0xA052, - 0xC7D4, 0xA053, 0xC7D5, 0xA054, 0xC7D6, 0xA055, 0xC7D7, 0xA056, 0xC7D8, 0xC0F5, 0xC7D9, 0xA057, 0xC7DA, 0xA058, 0xC7DB, 0xA059, - 0xC7DC, 0xA05A, 0xC7DD, 0xC0F6, 0xC7DE, 0xA061, 0xC7DF, 0xA062, 0xC7E0, 0xA063, 0xC7E1, 0xA064, 0xC7E2, 0xA065, 0xC7E3, 0xA066, - 0xC7E4, 0xC0F7, 0xC7E5, 0xA067, 0xC7E6, 0xA068, 0xC7E7, 0xA069, 0xC7E8, 0xC0F8, 0xC7E9, 0xA06A, 0xC7EA, 0xA06B, 0xC7EB, 0xA06C, - 0xC7EC, 0xC0F9, 0xC7ED, 0xA06D, 0xC7EE, 0xA06E, 0xC7EF, 0xA06F, 0xC7F0, 0xA070, 0xC7F1, 0xA071, 0xC7F2, 0xA072, 0xC7F3, 0xA073, - 0xC7F4, 0xA074, 0xC7F5, 0xA075, 0xC7F6, 0xA076, 0xC7F7, 0xA077, 0xC7F8, 0xA078, 0xC7F9, 0xA079, 0xC7FA, 0xA07A, 0xC7FB, 0xA081, - 0xC7FC, 0xA082, 0xC7FD, 0xA083, 0xC7FE, 0xA084, 0xC7FF, 0xA085, 0xC800, 0xC0FA, 0xC801, 0xC0FB, 0xC802, 0xA086, 0xC803, 0xA087, - 0xC804, 0xC0FC, 0xC805, 0xA088, 0xC806, 0xA089, 0xC807, 0xA08A, 0xC808, 0xC0FD, 0xC809, 0xA08B, 0xC80A, 0xC0FE, 0xC80B, 0xA08C, - 0xC80C, 0xA08D, 0xC80D, 0xA08E, 0xC80E, 0xA08F, 0xC80F, 0xA090, 0xC810, 0xC1A1, 0xC811, 0xC1A2, 0xC812, 0xA091, 0xC813, 0xC1A3, - 0xC814, 0xA092, 0xC815, 0xC1A4, 0xC816, 0xC1A5, 0xC817, 0xA093, 0xC818, 0xA094, 0xC819, 0xA095, 0xC81A, 0xA096, 0xC81B, 0xA097, - 0xC81C, 0xC1A6, 0xC81D, 0xC1A7, 0xC81E, 0xA098, 0xC81F, 0xA099, 0xC820, 0xC1A8, 0xC821, 0xA09A, 0xC822, 0xA09B, 0xC823, 0xA09C, - 0xC824, 0xC1A9, 0xC825, 0xA09D, 0xC826, 0xA09E, 0xC827, 0xA09F, 0xC828, 0xA0A0, 0xC829, 0xA0A1, 0xC82A, 0xA0A2, 0xC82B, 0xA0A3, - 0xC82C, 0xC1AA, 0xC82D, 0xC1AB, 0xC82E, 0xA0A4, 0xC82F, 0xC1AC, 0xC830, 0xA0A5, 0xC831, 0xC1AD, 0xC832, 0xA0A6, 0xC833, 0xA0A7, - 0xC834, 0xA0A8, 0xC835, 0xA0A9, 0xC836, 0xA0AA, 0xC837, 0xA0AB, 0xC838, 0xC1AE, 0xC839, 0xA0AC, 0xC83A, 0xA0AD, 0xC83B, 0xA0AE, - 0xC83C, 0xC1AF, 0xC83D, 0xA0AF, 0xC83E, 0xA0B0, 0xC83F, 0xA0B1, 0xC840, 0xC1B0, 0xC841, 0xA0B2, 0xC842, 0xA0B3, 0xC843, 0xA0B4, - 0xC844, 0xA0B5, 0xC845, 0xA0B6, 0xC846, 0xA0B7, 0xC847, 0xA0B8, 0xC848, 0xC1B1, 0xC849, 0xC1B2, 0xC84A, 0xA0B9, 0xC84B, 0xA0BA, - 0xC84C, 0xC1B3, 0xC84D, 0xC1B4, 0xC84E, 0xA0BB, 0xC84F, 0xA0BC, 0xC850, 0xA0BD, 0xC851, 0xA0BE, 0xC852, 0xA0BF, 0xC853, 0xA0C0, - 0xC854, 0xC1B5, 0xC855, 0xA0C1, 0xC856, 0xA0C2, 0xC857, 0xA0C3, 0xC858, 0xA0C4, 0xC859, 0xA0C5, 0xC85A, 0xA0C6, 0xC85B, 0xA0C7, - 0xC85C, 0xA0C8, 0xC85D, 0xA0C9, 0xC85E, 0xA0CA, 0xC85F, 0xA0CB, 0xC860, 0xA0CC, 0xC861, 0xA0CD, 0xC862, 0xA0CE, 0xC863, 0xA0CF, - 0xC864, 0xA0D0, 0xC865, 0xA0D1, 0xC866, 0xA0D2, 0xC867, 0xA0D3, 0xC868, 0xA0D4, 0xC869, 0xA0D5, 0xC86A, 0xA0D6, 0xC86B, 0xA0D7, - 0xC86C, 0xA0D8, 0xC86D, 0xA0D9, 0xC86E, 0xA0DA, 0xC86F, 0xA0DB, 0xC870, 0xC1B6, 0xC871, 0xC1B7, 0xC872, 0xA0DC, 0xC873, 0xA0DD, - 0xC874, 0xC1B8, 0xC875, 0xA0DE, 0xC876, 0xA0DF, 0xC877, 0xA0E0, 0xC878, 0xC1B9, 0xC879, 0xA0E1, 0xC87A, 0xC1BA, 0xC87B, 0xA0E2, - 0xC87C, 0xA0E3, 0xC87D, 0xA0E4, 0xC87E, 0xA0E5, 0xC87F, 0xA0E6, 0xC880, 0xC1BB, 0xC881, 0xC1BC, 0xC882, 0xA0E7, 0xC883, 0xC1BD, - 0xC884, 0xA0E8, 0xC885, 0xC1BE, 0xC886, 0xC1BF, 0xC887, 0xC1C0, 0xC888, 0xA0E9, 0xC889, 0xA0EA, 0xC88A, 0xA0EB, 0xC88B, 0xC1C1, - 0xC88C, 0xC1C2, 0xC88D, 0xC1C3, 0xC88E, 0xA0EC, 0xC88F, 0xA0ED, 0xC890, 0xA0EE, 0xC891, 0xA0EF, 0xC892, 0xA0F0, 0xC893, 0xA0F1, - 0xC894, 0xC1C4, 0xC895, 0xA0F2, 0xC896, 0xA0F3, 0xC897, 0xA0F4, 0xC898, 0xA0F5, 0xC899, 0xA0F6, 0xC89A, 0xA0F7, 0xC89B, 0xA0F8, - 0xC89C, 0xA0F9, 0xC89D, 0xC1C5, 0xC89E, 0xA0FA, 0xC89F, 0xC1C6, 0xC8A0, 0xA0FB, 0xC8A1, 0xC1C7, 0xC8A2, 0xA0FC, 0xC8A3, 0xA0FD, - 0xC8A4, 0xA0FE, 0xC8A5, 0xA141, 0xC8A6, 0xA142, 0xC8A7, 0xA143, 0xC8A8, 0xC1C8, 0xC8A9, 0xA144, 0xC8AA, 0xA145, 0xC8AB, 0xA146, - 0xC8AC, 0xA147, 0xC8AD, 0xA148, 0xC8AE, 0xA149, 0xC8AF, 0xA14A, 0xC8B0, 0xA14B, 0xC8B1, 0xA14C, 0xC8B2, 0xA14D, 0xC8B3, 0xA14E, - 0xC8B4, 0xA14F, 0xC8B5, 0xA150, 0xC8B6, 0xA151, 0xC8B7, 0xA152, 0xC8B8, 0xA153, 0xC8B9, 0xA154, 0xC8BA, 0xA155, 0xC8BB, 0xA156, - 0xC8BC, 0xC1C9, 0xC8BD, 0xC1CA, 0xC8BE, 0xA157, 0xC8BF, 0xA158, 0xC8C0, 0xA159, 0xC8C1, 0xA15A, 0xC8C2, 0xA161, 0xC8C3, 0xA162, - 0xC8C4, 0xC1CB, 0xC8C5, 0xA163, 0xC8C6, 0xA164, 0xC8C7, 0xA165, 0xC8C8, 0xC1CC, 0xC8C9, 0xA166, 0xC8CA, 0xA167, 0xC8CB, 0xA168, - 0xC8CC, 0xC1CD, 0xC8CD, 0xA169, 0xC8CE, 0xA16A, 0xC8CF, 0xA16B, 0xC8D0, 0xA16C, 0xC8D1, 0xA16D, 0xC8D2, 0xA16E, 0xC8D3, 0xA16F, - 0xC8D4, 0xC1CE, 0xC8D5, 0xC1CF, 0xC8D6, 0xA170, 0xC8D7, 0xC1D0, 0xC8D8, 0xA171, 0xC8D9, 0xC1D1, 0xC8DA, 0xA172, 0xC8DB, 0xA173, - 0xC8DC, 0xA174, 0xC8DD, 0xA175, 0xC8DE, 0xA176, 0xC8DF, 0xA177, 0xC8E0, 0xC1D2, 0xC8E1, 0xC1D3, 0xC8E2, 0xA178, 0xC8E3, 0xA179, - 0xC8E4, 0xC1D4, 0xC8E5, 0xA17A, 0xC8E6, 0xA181, 0xC8E7, 0xA182, 0xC8E8, 0xA183, 0xC8E9, 0xA184, 0xC8EA, 0xA185, 0xC8EB, 0xA186, - 0xC8EC, 0xA187, 0xC8ED, 0xA188, 0xC8EE, 0xA189, 0xC8EF, 0xA18A, 0xC8F0, 0xA18B, 0xC8F1, 0xA18C, 0xC8F2, 0xA18D, 0xC8F3, 0xA18E, - 0xC8F4, 0xA18F, 0xC8F5, 0xC1D5, 0xC8F6, 0xA190, 0xC8F7, 0xA191, 0xC8F8, 0xA192, 0xC8F9, 0xA193, 0xC8FA, 0xA194, 0xC8FB, 0xA195, - 0xC8FC, 0xC1D6, 0xC8FD, 0xC1D7, 0xC8FE, 0xA196, 0xC8FF, 0xA197, 0xC900, 0xC1D8, 0xC901, 0xA198, 0xC902, 0xA199, 0xC903, 0xA19A, - 0xC904, 0xC1D9, 0xC905, 0xC1DA, 0xC906, 0xC1DB, 0xC907, 0xA19B, 0xC908, 0xA19C, 0xC909, 0xA19D, 0xC90A, 0xA19E, 0xC90B, 0xA19F, - 0xC90C, 0xC1DC, 0xC90D, 0xC1DD, 0xC90E, 0xA1A0, 0xC90F, 0xC1DE, 0xC910, 0xA241, 0xC911, 0xC1DF, 0xC912, 0xA242, 0xC913, 0xA243, - 0xC914, 0xA244, 0xC915, 0xA245, 0xC916, 0xA246, 0xC917, 0xA247, 0xC918, 0xC1E0, 0xC919, 0xA248, 0xC91A, 0xA249, 0xC91B, 0xA24A, - 0xC91C, 0xA24B, 0xC91D, 0xA24C, 0xC91E, 0xA24D, 0xC91F, 0xA24E, 0xC920, 0xA24F, 0xC921, 0xA250, 0xC922, 0xA251, 0xC923, 0xA252, - 0xC924, 0xA253, 0xC925, 0xA254, 0xC926, 0xA255, 0xC927, 0xA256, 0xC928, 0xA257, 0xC929, 0xA258, 0xC92A, 0xA259, 0xC92B, 0xA25A, - 0xC92C, 0xC1E1, 0xC92D, 0xA261, 0xC92E, 0xA262, 0xC92F, 0xA263, 0xC930, 0xA264, 0xC931, 0xA265, 0xC932, 0xA266, 0xC933, 0xA267, - 0xC934, 0xC1E2, 0xC935, 0xA268, 0xC936, 0xA269, 0xC937, 0xA26A, 0xC938, 0xA26B, 0xC939, 0xA26C, 0xC93A, 0xA26D, 0xC93B, 0xA26E, - 0xC93C, 0xA26F, 0xC93D, 0xA270, 0xC93E, 0xA271, 0xC93F, 0xA272, 0xC940, 0xA273, 0xC941, 0xA274, 0xC942, 0xA275, 0xC943, 0xA276, - 0xC944, 0xA277, 0xC945, 0xA278, 0xC946, 0xA279, 0xC947, 0xA27A, 0xC948, 0xA281, 0xC949, 0xA282, 0xC94A, 0xA283, 0xC94B, 0xA284, - 0xC94C, 0xA285, 0xC94D, 0xA286, 0xC94E, 0xA287, 0xC94F, 0xA288, 0xC950, 0xC1E3, 0xC951, 0xC1E4, 0xC952, 0xA289, 0xC953, 0xA28A, - 0xC954, 0xC1E5, 0xC955, 0xA28B, 0xC956, 0xA28C, 0xC957, 0xA28D, 0xC958, 0xC1E6, 0xC959, 0xA28E, 0xC95A, 0xA28F, 0xC95B, 0xA290, - 0xC95C, 0xA291, 0xC95D, 0xA292, 0xC95E, 0xA293, 0xC95F, 0xA294, 0xC960, 0xC1E7, 0xC961, 0xC1E8, 0xC962, 0xA295, 0xC963, 0xC1E9, - 0xC964, 0xA296, 0xC965, 0xA297, 0xC966, 0xA298, 0xC967, 0xA299, 0xC968, 0xA29A, 0xC969, 0xA29B, 0xC96A, 0xA29C, 0xC96B, 0xA29D, - 0xC96C, 0xC1EA, 0xC96D, 0xA29E, 0xC96E, 0xA29F, 0xC96F, 0xA2A0, 0xC970, 0xC1EB, 0xC971, 0xA341, 0xC972, 0xA342, 0xC973, 0xA343, - 0xC974, 0xC1EC, 0xC975, 0xA344, 0xC976, 0xA345, 0xC977, 0xA346, 0xC978, 0xA347, 0xC979, 0xA348, 0xC97A, 0xA349, 0xC97B, 0xA34A, - 0xC97C, 0xC1ED, 0xC97D, 0xA34B, 0xC97E, 0xA34C, 0xC97F, 0xA34D, 0xC980, 0xA34E, 0xC981, 0xA34F, 0xC982, 0xA350, 0xC983, 0xA351, - 0xC984, 0xA352, 0xC985, 0xA353, 0xC986, 0xA354, 0xC987, 0xA355, 0xC988, 0xC1EE, 0xC989, 0xC1EF, 0xC98A, 0xA356, 0xC98B, 0xA357, - 0xC98C, 0xC1F0, 0xC98D, 0xA358, 0xC98E, 0xA359, 0xC98F, 0xA35A, 0xC990, 0xC1F1, 0xC991, 0xA361, 0xC992, 0xA362, 0xC993, 0xA363, - 0xC994, 0xA364, 0xC995, 0xA365, 0xC996, 0xA366, 0xC997, 0xA367, 0xC998, 0xC1F2, 0xC999, 0xC1F3, 0xC99A, 0xA368, 0xC99B, 0xC1F4, - 0xC99C, 0xA369, 0xC99D, 0xC1F5, 0xC99E, 0xA36A, 0xC99F, 0xA36B, 0xC9A0, 0xA36C, 0xC9A1, 0xA36D, 0xC9A2, 0xA36E, 0xC9A3, 0xA36F, - 0xC9A4, 0xA370, 0xC9A5, 0xA371, 0xC9A6, 0xA372, 0xC9A7, 0xA373, 0xC9A8, 0xA374, 0xC9A9, 0xA375, 0xC9AA, 0xA376, 0xC9AB, 0xA377, - 0xC9AC, 0xA378, 0xC9AD, 0xA379, 0xC9AE, 0xA37A, 0xC9AF, 0xA381, 0xC9B0, 0xA382, 0xC9B1, 0xA383, 0xC9B2, 0xA384, 0xC9B3, 0xA385, - 0xC9B4, 0xA386, 0xC9B5, 0xA387, 0xC9B6, 0xA388, 0xC9B7, 0xA389, 0xC9B8, 0xA38A, 0xC9B9, 0xA38B, 0xC9BA, 0xA38C, 0xC9BB, 0xA38D, - 0xC9BC, 0xA38E, 0xC9BD, 0xA38F, 0xC9BE, 0xA390, 0xC9BF, 0xA391, 0xC9C0, 0xC1F6, 0xC9C1, 0xC1F7, 0xC9C2, 0xA392, 0xC9C3, 0xA393, - 0xC9C4, 0xC1F8, 0xC9C5, 0xA394, 0xC9C6, 0xA395, 0xC9C7, 0xC1F9, 0xC9C8, 0xC1FA, 0xC9C9, 0xA396, 0xC9CA, 0xC1FB, 0xC9CB, 0xA397, - 0xC9CC, 0xA398, 0xC9CD, 0xA399, 0xC9CE, 0xA39A, 0xC9CF, 0xA39B, 0xC9D0, 0xC1FC, 0xC9D1, 0xC1FD, 0xC9D2, 0xA39C, 0xC9D3, 0xC1FE, - 0xC9D4, 0xA39D, 0xC9D5, 0xC2A1, 0xC9D6, 0xC2A2, 0xC9D7, 0xA39E, 0xC9D8, 0xA39F, 0xC9D9, 0xC2A3, 0xC9DA, 0xC2A4, 0xC9DB, 0xA3A0, - 0xC9DC, 0xC2A5, 0xC9DD, 0xC2A6, 0xC9DE, 0xA441, 0xC9DF, 0xA442, 0xC9E0, 0xC2A7, 0xC9E1, 0xA443, 0xC9E2, 0xC2A8, 0xC9E3, 0xA444, - 0xC9E4, 0xC2A9, 0xC9E5, 0xA445, 0xC9E6, 0xA446, 0xC9E7, 0xC2AA, 0xC9E8, 0xA447, 0xC9E9, 0xA448, 0xC9EA, 0xA449, 0xC9EB, 0xA44A, - 0xC9EC, 0xC2AB, 0xC9ED, 0xC2AC, 0xC9EE, 0xA44B, 0xC9EF, 0xC2AD, 0xC9F0, 0xC2AE, 0xC9F1, 0xC2AF, 0xC9F2, 0xA44C, 0xC9F3, 0xA44D, - 0xC9F4, 0xA44E, 0xC9F5, 0xA44F, 0xC9F6, 0xA450, 0xC9F7, 0xA451, 0xC9F8, 0xC2B0, 0xC9F9, 0xC2B1, 0xC9FA, 0xA452, 0xC9FB, 0xA453, - 0xC9FC, 0xC2B2, 0xC9FD, 0xA454, 0xC9FE, 0xA455, 0xC9FF, 0xA456, 0xCA00, 0xC2B3, 0xCA01, 0xA457, 0xCA02, 0xA458, 0xCA03, 0xA459, - 0xCA04, 0xA45A, 0xCA05, 0xA461, 0xCA06, 0xA462, 0xCA07, 0xA463, 0xCA08, 0xC2B4, 0xCA09, 0xC2B5, 0xCA0A, 0xA464, 0xCA0B, 0xC2B6, - 0xCA0C, 0xC2B7, 0xCA0D, 0xC2B8, 0xCA0E, 0xA465, 0xCA0F, 0xA466, 0xCA10, 0xA467, 0xCA11, 0xA468, 0xCA12, 0xA469, 0xCA13, 0xA46A, - 0xCA14, 0xC2B9, 0xCA15, 0xA46B, 0xCA16, 0xA46C, 0xCA17, 0xA46D, 0xCA18, 0xC2BA, 0xCA19, 0xA46E, 0xCA1A, 0xA46F, 0xCA1B, 0xA470, - 0xCA1C, 0xA471, 0xCA1D, 0xA472, 0xCA1E, 0xA473, 0xCA1F, 0xA474, 0xCA20, 0xA475, 0xCA21, 0xA476, 0xCA22, 0xA477, 0xCA23, 0xA478, - 0xCA24, 0xA479, 0xCA25, 0xA47A, 0xCA26, 0xA481, 0xCA27, 0xA482, 0xCA28, 0xA483, 0xCA29, 0xC2BB, 0xCA2A, 0xA484, 0xCA2B, 0xA485, - 0xCA2C, 0xA486, 0xCA2D, 0xA487, 0xCA2E, 0xA488, 0xCA2F, 0xA489, 0xCA30, 0xA48A, 0xCA31, 0xA48B, 0xCA32, 0xA48C, 0xCA33, 0xA48D, - 0xCA34, 0xA48E, 0xCA35, 0xA48F, 0xCA36, 0xA490, 0xCA37, 0xA491, 0xCA38, 0xA492, 0xCA39, 0xA493, 0xCA3A, 0xA494, 0xCA3B, 0xA495, - 0xCA3C, 0xA496, 0xCA3D, 0xA497, 0xCA3E, 0xA498, 0xCA3F, 0xA499, 0xCA40, 0xA49A, 0xCA41, 0xA49B, 0xCA42, 0xA49C, 0xCA43, 0xA49D, - 0xCA44, 0xA49E, 0xCA45, 0xA49F, 0xCA46, 0xA4A0, 0xCA47, 0xA541, 0xCA48, 0xA542, 0xCA49, 0xA543, 0xCA4A, 0xA544, 0xCA4B, 0xA545, - 0xCA4C, 0xC2BC, 0xCA4D, 0xC2BD, 0xCA4E, 0xA546, 0xCA4F, 0xA547, 0xCA50, 0xC2BE, 0xCA51, 0xA548, 0xCA52, 0xA549, 0xCA53, 0xA54A, - 0xCA54, 0xC2BF, 0xCA55, 0xA54B, 0xCA56, 0xA54C, 0xCA57, 0xA54D, 0xCA58, 0xA54E, 0xCA59, 0xA54F, 0xCA5A, 0xA550, 0xCA5B, 0xA551, - 0xCA5C, 0xC2C0, 0xCA5D, 0xC2C1, 0xCA5E, 0xA552, 0xCA5F, 0xC2C2, 0xCA60, 0xC2C3, 0xCA61, 0xC2C4, 0xCA62, 0xA553, 0xCA63, 0xA554, - 0xCA64, 0xA555, 0xCA65, 0xA556, 0xCA66, 0xA557, 0xCA67, 0xA558, 0xCA68, 0xC2C5, 0xCA69, 0xA559, 0xCA6A, 0xA55A, 0xCA6B, 0xA561, - 0xCA6C, 0xA562, 0xCA6D, 0xA563, 0xCA6E, 0xA564, 0xCA6F, 0xA565, 0xCA70, 0xA566, 0xCA71, 0xA567, 0xCA72, 0xA568, 0xCA73, 0xA569, - 0xCA74, 0xA56A, 0xCA75, 0xA56B, 0xCA76, 0xA56C, 0xCA77, 0xA56D, 0xCA78, 0xA56E, 0xCA79, 0xA56F, 0xCA7A, 0xA570, 0xCA7B, 0xA571, - 0xCA7C, 0xA572, 0xCA7D, 0xC2C6, 0xCA7E, 0xA573, 0xCA7F, 0xA574, 0xCA80, 0xA575, 0xCA81, 0xA576, 0xCA82, 0xA577, 0xCA83, 0xA578, - 0xCA84, 0xC2C7, 0xCA85, 0xA579, 0xCA86, 0xA57A, 0xCA87, 0xA581, 0xCA88, 0xA582, 0xCA89, 0xA583, 0xCA8A, 0xA584, 0xCA8B, 0xA585, - 0xCA8C, 0xA586, 0xCA8D, 0xA587, 0xCA8E, 0xA588, 0xCA8F, 0xA589, 0xCA90, 0xA58A, 0xCA91, 0xA58B, 0xCA92, 0xA58C, 0xCA93, 0xA58D, - 0xCA94, 0xA58E, 0xCA95, 0xA58F, 0xCA96, 0xA590, 0xCA97, 0xA591, 0xCA98, 0xC2C8, 0xCA99, 0xA592, 0xCA9A, 0xA593, 0xCA9B, 0xA594, - 0xCA9C, 0xA595, 0xCA9D, 0xA596, 0xCA9E, 0xA597, 0xCA9F, 0xA598, 0xCAA0, 0xA599, 0xCAA1, 0xA59A, 0xCAA2, 0xA59B, 0xCAA3, 0xA59C, - 0xCAA4, 0xA59D, 0xCAA5, 0xA59E, 0xCAA6, 0xA59F, 0xCAA7, 0xA5A0, 0xCAA8, 0xA641, 0xCAA9, 0xA642, 0xCAAA, 0xA643, 0xCAAB, 0xA644, - 0xCAAC, 0xA645, 0xCAAD, 0xA646, 0xCAAE, 0xA647, 0xCAAF, 0xA648, 0xCAB0, 0xA649, 0xCAB1, 0xA64A, 0xCAB2, 0xA64B, 0xCAB3, 0xA64C, - 0xCAB4, 0xA64D, 0xCAB5, 0xA64E, 0xCAB6, 0xA64F, 0xCAB7, 0xA650, 0xCAB8, 0xA651, 0xCAB9, 0xA652, 0xCABA, 0xA653, 0xCABB, 0xA654, - 0xCABC, 0xC2C9, 0xCABD, 0xC2CA, 0xCABE, 0xA655, 0xCABF, 0xA656, 0xCAC0, 0xC2CB, 0xCAC1, 0xA657, 0xCAC2, 0xA658, 0xCAC3, 0xA659, - 0xCAC4, 0xC2CC, 0xCAC5, 0xA65A, 0xCAC6, 0xA661, 0xCAC7, 0xA662, 0xCAC8, 0xA663, 0xCAC9, 0xA664, 0xCACA, 0xA665, 0xCACB, 0xA666, - 0xCACC, 0xC2CD, 0xCACD, 0xC2CE, 0xCACE, 0xA667, 0xCACF, 0xC2CF, 0xCAD0, 0xA668, 0xCAD1, 0xC2D0, 0xCAD2, 0xA669, 0xCAD3, 0xC2D1, - 0xCAD4, 0xA66A, 0xCAD5, 0xA66B, 0xCAD6, 0xA66C, 0xCAD7, 0xA66D, 0xCAD8, 0xC2D2, 0xCAD9, 0xC2D3, 0xCADA, 0xA66E, 0xCADB, 0xA66F, - 0xCADC, 0xA670, 0xCADD, 0xA671, 0xCADE, 0xA672, 0xCADF, 0xA673, 0xCAE0, 0xC2D4, 0xCAE1, 0xA674, 0xCAE2, 0xA675, 0xCAE3, 0xA676, - 0xCAE4, 0xA677, 0xCAE5, 0xA678, 0xCAE6, 0xA679, 0xCAE7, 0xA67A, 0xCAE8, 0xA681, 0xCAE9, 0xA682, 0xCAEA, 0xA683, 0xCAEB, 0xA684, - 0xCAEC, 0xC2D5, 0xCAED, 0xA685, 0xCAEE, 0xA686, 0xCAEF, 0xA687, 0xCAF0, 0xA688, 0xCAF1, 0xA689, 0xCAF2, 0xA68A, 0xCAF3, 0xA68B, - 0xCAF4, 0xC2D6, 0xCAF5, 0xA68C, 0xCAF6, 0xA68D, 0xCAF7, 0xA68E, 0xCAF8, 0xA68F, 0xCAF9, 0xA690, 0xCAFA, 0xA691, 0xCAFB, 0xA692, - 0xCAFC, 0xA693, 0xCAFD, 0xA694, 0xCAFE, 0xA695, 0xCAFF, 0xA696, 0xCB00, 0xA697, 0xCB01, 0xA698, 0xCB02, 0xA699, 0xCB03, 0xA69A, - 0xCB04, 0xA69B, 0xCB05, 0xA69C, 0xCB06, 0xA69D, 0xCB07, 0xA69E, 0xCB08, 0xC2D7, 0xCB09, 0xA69F, 0xCB0A, 0xA6A0, 0xCB0B, 0xA741, - 0xCB0C, 0xA742, 0xCB0D, 0xA743, 0xCB0E, 0xA744, 0xCB0F, 0xA745, 0xCB10, 0xC2D8, 0xCB11, 0xA746, 0xCB12, 0xA747, 0xCB13, 0xA748, - 0xCB14, 0xC2D9, 0xCB15, 0xA749, 0xCB16, 0xA74A, 0xCB17, 0xA74B, 0xCB18, 0xC2DA, 0xCB19, 0xA74C, 0xCB1A, 0xA74D, 0xCB1B, 0xA74E, - 0xCB1C, 0xA74F, 0xCB1D, 0xA750, 0xCB1E, 0xA751, 0xCB1F, 0xA752, 0xCB20, 0xC2DB, 0xCB21, 0xC2DC, 0xCB22, 0xA753, 0xCB23, 0xA754, - 0xCB24, 0xA755, 0xCB25, 0xA756, 0xCB26, 0xA757, 0xCB27, 0xA758, 0xCB28, 0xA759, 0xCB29, 0xA75A, 0xCB2A, 0xA761, 0xCB2B, 0xA762, - 0xCB2C, 0xA763, 0xCB2D, 0xA764, 0xCB2E, 0xA765, 0xCB2F, 0xA766, 0xCB30, 0xA767, 0xCB31, 0xA768, 0xCB32, 0xA769, 0xCB33, 0xA76A, - 0xCB34, 0xA76B, 0xCB35, 0xA76C, 0xCB36, 0xA76D, 0xCB37, 0xA76E, 0xCB38, 0xA76F, 0xCB39, 0xA770, 0xCB3A, 0xA771, 0xCB3B, 0xA772, - 0xCB3C, 0xA773, 0xCB3D, 0xA774, 0xCB3E, 0xA775, 0xCB3F, 0xA776, 0xCB40, 0xA777, 0xCB41, 0xC2DD, 0xCB42, 0xA778, 0xCB43, 0xA779, - 0xCB44, 0xA77A, 0xCB45, 0xA781, 0xCB46, 0xA782, 0xCB47, 0xA783, 0xCB48, 0xC2DE, 0xCB49, 0xC2DF, 0xCB4A, 0xA784, 0xCB4B, 0xA785, - 0xCB4C, 0xC2E0, 0xCB4D, 0xA786, 0xCB4E, 0xA787, 0xCB4F, 0xA788, 0xCB50, 0xC2E1, 0xCB51, 0xA789, 0xCB52, 0xA78A, 0xCB53, 0xA78B, - 0xCB54, 0xA78C, 0xCB55, 0xA78D, 0xCB56, 0xA78E, 0xCB57, 0xA78F, 0xCB58, 0xC2E2, 0xCB59, 0xC2E3, 0xCB5A, 0xA790, 0xCB5B, 0xA791, - 0xCB5C, 0xA792, 0xCB5D, 0xC2E4, 0xCB5E, 0xA793, 0xCB5F, 0xA794, 0xCB60, 0xA795, 0xCB61, 0xA796, 0xCB62, 0xA797, 0xCB63, 0xA798, - 0xCB64, 0xC2E5, 0xCB65, 0xA799, 0xCB66, 0xA79A, 0xCB67, 0xA79B, 0xCB68, 0xA79C, 0xCB69, 0xA79D, 0xCB6A, 0xA79E, 0xCB6B, 0xA79F, - 0xCB6C, 0xA7A0, 0xCB6D, 0xA841, 0xCB6E, 0xA842, 0xCB6F, 0xA843, 0xCB70, 0xA844, 0xCB71, 0xA845, 0xCB72, 0xA846, 0xCB73, 0xA847, - 0xCB74, 0xA848, 0xCB75, 0xA849, 0xCB76, 0xA84A, 0xCB77, 0xA84B, 0xCB78, 0xC2E6, 0xCB79, 0xC2E7, 0xCB7A, 0xA84C, 0xCB7B, 0xA84D, - 0xCB7C, 0xA84E, 0xCB7D, 0xA84F, 0xCB7E, 0xA850, 0xCB7F, 0xA851, 0xCB80, 0xA852, 0xCB81, 0xA853, 0xCB82, 0xA854, 0xCB83, 0xA855, - 0xCB84, 0xA856, 0xCB85, 0xA857, 0xCB86, 0xA858, 0xCB87, 0xA859, 0xCB88, 0xA85A, 0xCB89, 0xA861, 0xCB8A, 0xA862, 0xCB8B, 0xA863, - 0xCB8C, 0xA864, 0xCB8D, 0xA865, 0xCB8E, 0xA866, 0xCB8F, 0xA867, 0xCB90, 0xA868, 0xCB91, 0xA869, 0xCB92, 0xA86A, 0xCB93, 0xA86B, - 0xCB94, 0xA86C, 0xCB95, 0xA86D, 0xCB96, 0xA86E, 0xCB97, 0xA86F, 0xCB98, 0xA870, 0xCB99, 0xA871, 0xCB9A, 0xA872, 0xCB9B, 0xA873, - 0xCB9C, 0xC2E8, 0xCB9D, 0xA874, 0xCB9E, 0xA875, 0xCB9F, 0xA876, 0xCBA0, 0xA877, 0xCBA1, 0xA878, 0xCBA2, 0xA879, 0xCBA3, 0xA87A, - 0xCBA4, 0xA881, 0xCBA5, 0xA882, 0xCBA6, 0xA883, 0xCBA7, 0xA884, 0xCBA8, 0xA885, 0xCBA9, 0xA886, 0xCBAA, 0xA887, 0xCBAB, 0xA888, - 0xCBAC, 0xA889, 0xCBAD, 0xA88A, 0xCBAE, 0xA88B, 0xCBAF, 0xA88C, 0xCBB0, 0xA88D, 0xCBB1, 0xA88E, 0xCBB2, 0xA88F, 0xCBB3, 0xA890, - 0xCBB4, 0xA891, 0xCBB5, 0xA892, 0xCBB6, 0xA893, 0xCBB7, 0xA894, 0xCBB8, 0xC2E9, 0xCBB9, 0xA895, 0xCBBA, 0xA896, 0xCBBB, 0xA897, - 0xCBBC, 0xA898, 0xCBBD, 0xA899, 0xCBBE, 0xA89A, 0xCBBF, 0xA89B, 0xCBC0, 0xA89C, 0xCBC1, 0xA89D, 0xCBC2, 0xA89E, 0xCBC3, 0xA89F, - 0xCBC4, 0xA8A0, 0xCBC5, 0xA941, 0xCBC6, 0xA942, 0xCBC7, 0xA943, 0xCBC8, 0xA944, 0xCBC9, 0xA945, 0xCBCA, 0xA946, 0xCBCB, 0xA947, - 0xCBCC, 0xA948, 0xCBCD, 0xA949, 0xCBCE, 0xA94A, 0xCBCF, 0xA94B, 0xCBD0, 0xA94C, 0xCBD1, 0xA94D, 0xCBD2, 0xA94E, 0xCBD3, 0xA94F, - 0xCBD4, 0xC2EA, 0xCBD5, 0xA950, 0xCBD6, 0xA951, 0xCBD7, 0xA952, 0xCBD8, 0xA953, 0xCBD9, 0xA954, 0xCBDA, 0xA955, 0xCBDB, 0xA956, - 0xCBDC, 0xA957, 0xCBDD, 0xA958, 0xCBDE, 0xA959, 0xCBDF, 0xA95A, 0xCBE0, 0xA961, 0xCBE1, 0xA962, 0xCBE2, 0xA963, 0xCBE3, 0xA964, - 0xCBE4, 0xC2EB, 0xCBE5, 0xA965, 0xCBE6, 0xA966, 0xCBE7, 0xC2EC, 0xCBE8, 0xA967, 0xCBE9, 0xC2ED, 0xCBEA, 0xA968, 0xCBEB, 0xA969, - 0xCBEC, 0xA96A, 0xCBED, 0xA96B, 0xCBEE, 0xA96C, 0xCBEF, 0xA96D, 0xCBF0, 0xA96E, 0xCBF1, 0xA96F, 0xCBF2, 0xA970, 0xCBF3, 0xA971, - 0xCBF4, 0xA972, 0xCBF5, 0xA973, 0xCBF6, 0xA974, 0xCBF7, 0xA975, 0xCBF8, 0xA976, 0xCBF9, 0xA977, 0xCBFA, 0xA978, 0xCBFB, 0xA979, - 0xCBFC, 0xA97A, 0xCBFD, 0xA981, 0xCBFE, 0xA982, 0xCBFF, 0xA983, 0xCC00, 0xA984, 0xCC01, 0xA985, 0xCC02, 0xA986, 0xCC03, 0xA987, - 0xCC04, 0xA988, 0xCC05, 0xA989, 0xCC06, 0xA98A, 0xCC07, 0xA98B, 0xCC08, 0xA98C, 0xCC09, 0xA98D, 0xCC0A, 0xA98E, 0xCC0B, 0xA98F, - 0xCC0C, 0xC2EE, 0xCC0D, 0xC2EF, 0xCC0E, 0xA990, 0xCC0F, 0xA991, 0xCC10, 0xC2F0, 0xCC11, 0xA992, 0xCC12, 0xA993, 0xCC13, 0xA994, - 0xCC14, 0xC2F1, 0xCC15, 0xA995, 0xCC16, 0xA996, 0xCC17, 0xA997, 0xCC18, 0xA998, 0xCC19, 0xA999, 0xCC1A, 0xA99A, 0xCC1B, 0xA99B, - 0xCC1C, 0xC2F2, 0xCC1D, 0xC2F3, 0xCC1E, 0xA99C, 0xCC1F, 0xA99D, 0xCC20, 0xA99E, 0xCC21, 0xC2F4, 0xCC22, 0xC2F5, 0xCC23, 0xA99F, - 0xCC24, 0xA9A0, 0xCC25, 0xAA41, 0xCC26, 0xAA42, 0xCC27, 0xC2F6, 0xCC28, 0xC2F7, 0xCC29, 0xC2F8, 0xCC2A, 0xAA43, 0xCC2B, 0xAA44, - 0xCC2C, 0xC2F9, 0xCC2D, 0xAA45, 0xCC2E, 0xC2FA, 0xCC2F, 0xAA46, 0xCC30, 0xC2FB, 0xCC31, 0xAA47, 0xCC32, 0xAA48, 0xCC33, 0xAA49, - 0xCC34, 0xAA4A, 0xCC35, 0xAA4B, 0xCC36, 0xAA4C, 0xCC37, 0xAA4D, 0xCC38, 0xC2FC, 0xCC39, 0xC2FD, 0xCC3A, 0xAA4E, 0xCC3B, 0xC2FE, - 0xCC3C, 0xC3A1, 0xCC3D, 0xC3A2, 0xCC3E, 0xC3A3, 0xCC3F, 0xAA4F, 0xCC40, 0xAA50, 0xCC41, 0xAA51, 0xCC42, 0xAA52, 0xCC43, 0xAA53, - 0xCC44, 0xC3A4, 0xCC45, 0xC3A5, 0xCC46, 0xAA54, 0xCC47, 0xAA55, 0xCC48, 0xC3A6, 0xCC49, 0xAA56, 0xCC4A, 0xAA57, 0xCC4B, 0xAA58, - 0xCC4C, 0xC3A7, 0xCC4D, 0xAA59, 0xCC4E, 0xAA5A, 0xCC4F, 0xAA61, 0xCC50, 0xAA62, 0xCC51, 0xAA63, 0xCC52, 0xAA64, 0xCC53, 0xAA65, - 0xCC54, 0xC3A8, 0xCC55, 0xC3A9, 0xCC56, 0xAA66, 0xCC57, 0xC3AA, 0xCC58, 0xC3AB, 0xCC59, 0xC3AC, 0xCC5A, 0xAA67, 0xCC5B, 0xAA68, - 0xCC5C, 0xAA69, 0xCC5D, 0xAA6A, 0xCC5E, 0xAA6B, 0xCC5F, 0xAA6C, 0xCC60, 0xC3AD, 0xCC61, 0xAA6D, 0xCC62, 0xAA6E, 0xCC63, 0xAA6F, - 0xCC64, 0xC3AE, 0xCC65, 0xAA70, 0xCC66, 0xC3AF, 0xCC67, 0xAA71, 0xCC68, 0xC3B0, 0xCC69, 0xAA72, 0xCC6A, 0xAA73, 0xCC6B, 0xAA74, - 0xCC6C, 0xAA75, 0xCC6D, 0xAA76, 0xCC6E, 0xAA77, 0xCC6F, 0xAA78, 0xCC70, 0xC3B1, 0xCC71, 0xAA79, 0xCC72, 0xAA7A, 0xCC73, 0xAA81, - 0xCC74, 0xAA82, 0xCC75, 0xC3B2, 0xCC76, 0xAA83, 0xCC77, 0xAA84, 0xCC78, 0xAA85, 0xCC79, 0xAA86, 0xCC7A, 0xAA87, 0xCC7B, 0xAA88, - 0xCC7C, 0xAA89, 0xCC7D, 0xAA8A, 0xCC7E, 0xAA8B, 0xCC7F, 0xAA8C, 0xCC80, 0xAA8D, 0xCC81, 0xAA8E, 0xCC82, 0xAA8F, 0xCC83, 0xAA90, - 0xCC84, 0xAA91, 0xCC85, 0xAA92, 0xCC86, 0xAA93, 0xCC87, 0xAA94, 0xCC88, 0xAA95, 0xCC89, 0xAA96, 0xCC8A, 0xAA97, 0xCC8B, 0xAA98, - 0xCC8C, 0xAA99, 0xCC8D, 0xAA9A, 0xCC8E, 0xAA9B, 0xCC8F, 0xAA9C, 0xCC90, 0xAA9D, 0xCC91, 0xAA9E, 0xCC92, 0xAA9F, 0xCC93, 0xAAA0, - 0xCC94, 0xAB41, 0xCC95, 0xAB42, 0xCC96, 0xAB43, 0xCC97, 0xAB44, 0xCC98, 0xC3B3, 0xCC99, 0xC3B4, 0xCC9A, 0xAB45, 0xCC9B, 0xAB46, - 0xCC9C, 0xC3B5, 0xCC9D, 0xAB47, 0xCC9E, 0xAB48, 0xCC9F, 0xAB49, 0xCCA0, 0xC3B6, 0xCCA1, 0xAB4A, 0xCCA2, 0xAB4B, 0xCCA3, 0xAB4C, - 0xCCA4, 0xAB4D, 0xCCA5, 0xAB4E, 0xCCA6, 0xAB4F, 0xCCA7, 0xAB50, 0xCCA8, 0xC3B7, 0xCCA9, 0xC3B8, 0xCCAA, 0xAB51, 0xCCAB, 0xC3B9, - 0xCCAC, 0xC3BA, 0xCCAD, 0xC3BB, 0xCCAE, 0xAB52, 0xCCAF, 0xAB53, 0xCCB0, 0xAB54, 0xCCB1, 0xAB55, 0xCCB2, 0xAB56, 0xCCB3, 0xAB57, - 0xCCB4, 0xC3BC, 0xCCB5, 0xC3BD, 0xCCB6, 0xAB58, 0xCCB7, 0xAB59, 0xCCB8, 0xC3BE, 0xCCB9, 0xAB5A, 0xCCBA, 0xAB61, 0xCCBB, 0xAB62, - 0xCCBC, 0xC3BF, 0xCCBD, 0xAB63, 0xCCBE, 0xAB64, 0xCCBF, 0xAB65, 0xCCC0, 0xAB66, 0xCCC1, 0xAB67, 0xCCC2, 0xAB68, 0xCCC3, 0xAB69, - 0xCCC4, 0xC3C0, 0xCCC5, 0xC3C1, 0xCCC6, 0xAB6A, 0xCCC7, 0xC3C2, 0xCCC8, 0xAB6B, 0xCCC9, 0xC3C3, 0xCCCA, 0xAB6C, 0xCCCB, 0xAB6D, - 0xCCCC, 0xAB6E, 0xCCCD, 0xAB6F, 0xCCCE, 0xAB70, 0xCCCF, 0xAB71, 0xCCD0, 0xC3C4, 0xCCD1, 0xAB72, 0xCCD2, 0xAB73, 0xCCD3, 0xAB74, - 0xCCD4, 0xC3C5, 0xCCD5, 0xAB75, 0xCCD6, 0xAB76, 0xCCD7, 0xAB77, 0xCCD8, 0xAB78, 0xCCD9, 0xAB79, 0xCCDA, 0xAB7A, 0xCCDB, 0xAB81, - 0xCCDC, 0xAB82, 0xCCDD, 0xAB83, 0xCCDE, 0xAB84, 0xCCDF, 0xAB85, 0xCCE0, 0xAB86, 0xCCE1, 0xAB87, 0xCCE2, 0xAB88, 0xCCE3, 0xAB89, - 0xCCE4, 0xC3C6, 0xCCE5, 0xAB8A, 0xCCE6, 0xAB8B, 0xCCE7, 0xAB8C, 0xCCE8, 0xAB8D, 0xCCE9, 0xAB8E, 0xCCEA, 0xAB8F, 0xCCEB, 0xAB90, - 0xCCEC, 0xC3C7, 0xCCED, 0xAB91, 0xCCEE, 0xAB92, 0xCCEF, 0xAB93, 0xCCF0, 0xC3C8, 0xCCF1, 0xAB94, 0xCCF2, 0xAB95, 0xCCF3, 0xAB96, - 0xCCF4, 0xAB97, 0xCCF5, 0xAB98, 0xCCF6, 0xAB99, 0xCCF7, 0xAB9A, 0xCCF8, 0xAB9B, 0xCCF9, 0xAB9C, 0xCCFA, 0xAB9D, 0xCCFB, 0xAB9E, - 0xCCFC, 0xAB9F, 0xCCFD, 0xABA0, 0xCCFE, 0xAC41, 0xCCFF, 0xAC42, 0xCD00, 0xAC43, 0xCD01, 0xC3C9, 0xCD02, 0xAC44, 0xCD03, 0xAC45, - 0xCD04, 0xAC46, 0xCD05, 0xAC47, 0xCD06, 0xAC48, 0xCD07, 0xAC49, 0xCD08, 0xC3CA, 0xCD09, 0xC3CB, 0xCD0A, 0xAC4A, 0xCD0B, 0xAC4B, - 0xCD0C, 0xC3CC, 0xCD0D, 0xAC4C, 0xCD0E, 0xAC4D, 0xCD0F, 0xAC4E, 0xCD10, 0xC3CD, 0xCD11, 0xAC4F, 0xCD12, 0xAC50, 0xCD13, 0xAC51, - 0xCD14, 0xAC52, 0xCD15, 0xAC53, 0xCD16, 0xAC54, 0xCD17, 0xAC55, 0xCD18, 0xC3CE, 0xCD19, 0xC3CF, 0xCD1A, 0xAC56, 0xCD1B, 0xC3D0, - 0xCD1C, 0xAC57, 0xCD1D, 0xC3D1, 0xCD1E, 0xAC58, 0xCD1F, 0xAC59, 0xCD20, 0xAC5A, 0xCD21, 0xAC61, 0xCD22, 0xAC62, 0xCD23, 0xAC63, - 0xCD24, 0xC3D2, 0xCD25, 0xAC64, 0xCD26, 0xAC65, 0xCD27, 0xAC66, 0xCD28, 0xC3D3, 0xCD29, 0xAC67, 0xCD2A, 0xAC68, 0xCD2B, 0xAC69, - 0xCD2C, 0xC3D4, 0xCD2D, 0xAC6A, 0xCD2E, 0xAC6B, 0xCD2F, 0xAC6C, 0xCD30, 0xAC6D, 0xCD31, 0xAC6E, 0xCD32, 0xAC6F, 0xCD33, 0xAC70, - 0xCD34, 0xAC71, 0xCD35, 0xAC72, 0xCD36, 0xAC73, 0xCD37, 0xAC74, 0xCD38, 0xAC75, 0xCD39, 0xC3D5, 0xCD3A, 0xAC76, 0xCD3B, 0xAC77, - 0xCD3C, 0xAC78, 0xCD3D, 0xAC79, 0xCD3E, 0xAC7A, 0xCD3F, 0xAC81, 0xCD40, 0xAC82, 0xCD41, 0xAC83, 0xCD42, 0xAC84, 0xCD43, 0xAC85, - 0xCD44, 0xAC86, 0xCD45, 0xAC87, 0xCD46, 0xAC88, 0xCD47, 0xAC89, 0xCD48, 0xAC8A, 0xCD49, 0xAC8B, 0xCD4A, 0xAC8C, 0xCD4B, 0xAC8D, - 0xCD4C, 0xAC8E, 0xCD4D, 0xAC8F, 0xCD4E, 0xAC90, 0xCD4F, 0xAC91, 0xCD50, 0xAC92, 0xCD51, 0xAC93, 0xCD52, 0xAC94, 0xCD53, 0xAC95, - 0xCD54, 0xAC96, 0xCD55, 0xAC97, 0xCD56, 0xAC98, 0xCD57, 0xAC99, 0xCD58, 0xAC9A, 0xCD59, 0xAC9B, 0xCD5A, 0xAC9C, 0xCD5B, 0xAC9D, - 0xCD5C, 0xC3D6, 0xCD5D, 0xAC9E, 0xCD5E, 0xAC9F, 0xCD5F, 0xACA0, 0xCD60, 0xC3D7, 0xCD61, 0xAD41, 0xCD62, 0xAD42, 0xCD63, 0xAD43, - 0xCD64, 0xC3D8, 0xCD65, 0xAD44, 0xCD66, 0xAD45, 0xCD67, 0xAD46, 0xCD68, 0xAD47, 0xCD69, 0xAD48, 0xCD6A, 0xAD49, 0xCD6B, 0xAD4A, - 0xCD6C, 0xC3D9, 0xCD6D, 0xC3DA, 0xCD6E, 0xAD4B, 0xCD6F, 0xC3DB, 0xCD70, 0xAD4C, 0xCD71, 0xC3DC, 0xCD72, 0xAD4D, 0xCD73, 0xAD4E, - 0xCD74, 0xAD4F, 0xCD75, 0xAD50, 0xCD76, 0xAD51, 0xCD77, 0xAD52, 0xCD78, 0xC3DD, 0xCD79, 0xAD53, 0xCD7A, 0xAD54, 0xCD7B, 0xAD55, - 0xCD7C, 0xAD56, 0xCD7D, 0xAD57, 0xCD7E, 0xAD58, 0xCD7F, 0xAD59, 0xCD80, 0xAD5A, 0xCD81, 0xAD61, 0xCD82, 0xAD62, 0xCD83, 0xAD63, - 0xCD84, 0xAD64, 0xCD85, 0xAD65, 0xCD86, 0xAD66, 0xCD87, 0xAD67, 0xCD88, 0xC3DE, 0xCD89, 0xAD68, 0xCD8A, 0xAD69, 0xCD8B, 0xAD6A, - 0xCD8C, 0xAD6B, 0xCD8D, 0xAD6C, 0xCD8E, 0xAD6D, 0xCD8F, 0xAD6E, 0xCD90, 0xAD6F, 0xCD91, 0xAD70, 0xCD92, 0xAD71, 0xCD93, 0xAD72, - 0xCD94, 0xC3DF, 0xCD95, 0xC3E0, 0xCD96, 0xAD73, 0xCD97, 0xAD74, 0xCD98, 0xC3E1, 0xCD99, 0xAD75, 0xCD9A, 0xAD76, 0xCD9B, 0xAD77, - 0xCD9C, 0xC3E2, 0xCD9D, 0xAD78, 0xCD9E, 0xAD79, 0xCD9F, 0xAD7A, 0xCDA0, 0xAD81, 0xCDA1, 0xAD82, 0xCDA2, 0xAD83, 0xCDA3, 0xAD84, - 0xCDA4, 0xC3E3, 0xCDA5, 0xC3E4, 0xCDA6, 0xAD85, 0xCDA7, 0xC3E5, 0xCDA8, 0xAD86, 0xCDA9, 0xC3E6, 0xCDAA, 0xAD87, 0xCDAB, 0xAD88, - 0xCDAC, 0xAD89, 0xCDAD, 0xAD8A, 0xCDAE, 0xAD8B, 0xCDAF, 0xAD8C, 0xCDB0, 0xC3E7, 0xCDB1, 0xAD8D, 0xCDB2, 0xAD8E, 0xCDB3, 0xAD8F, - 0xCDB4, 0xAD90, 0xCDB5, 0xAD91, 0xCDB6, 0xAD92, 0xCDB7, 0xAD93, 0xCDB8, 0xAD94, 0xCDB9, 0xAD95, 0xCDBA, 0xAD96, 0xCDBB, 0xAD97, - 0xCDBC, 0xAD98, 0xCDBD, 0xAD99, 0xCDBE, 0xAD9A, 0xCDBF, 0xAD9B, 0xCDC0, 0xAD9C, 0xCDC1, 0xAD9D, 0xCDC2, 0xAD9E, 0xCDC3, 0xAD9F, - 0xCDC4, 0xC3E8, 0xCDC5, 0xADA0, 0xCDC6, 0xAE41, 0xCDC7, 0xAE42, 0xCDC8, 0xAE43, 0xCDC9, 0xAE44, 0xCDCA, 0xAE45, 0xCDCB, 0xAE46, - 0xCDCC, 0xC3E9, 0xCDCD, 0xAE47, 0xCDCE, 0xAE48, 0xCDCF, 0xAE49, 0xCDD0, 0xC3EA, 0xCDD1, 0xAE4A, 0xCDD2, 0xAE4B, 0xCDD3, 0xAE4C, - 0xCDD4, 0xAE4D, 0xCDD5, 0xAE4E, 0xCDD6, 0xAE4F, 0xCDD7, 0xAE50, 0xCDD8, 0xAE51, 0xCDD9, 0xAE52, 0xCDDA, 0xAE53, 0xCDDB, 0xAE54, - 0xCDDC, 0xAE55, 0xCDDD, 0xAE56, 0xCDDE, 0xAE57, 0xCDDF, 0xAE58, 0xCDE0, 0xAE59, 0xCDE1, 0xAE5A, 0xCDE2, 0xAE61, 0xCDE3, 0xAE62, - 0xCDE4, 0xAE63, 0xCDE5, 0xAE64, 0xCDE6, 0xAE65, 0xCDE7, 0xAE66, 0xCDE8, 0xC3EB, 0xCDE9, 0xAE67, 0xCDEA, 0xAE68, 0xCDEB, 0xAE69, - 0xCDEC, 0xC3EC, 0xCDED, 0xAE6A, 0xCDEE, 0xAE6B, 0xCDEF, 0xAE6C, 0xCDF0, 0xC3ED, 0xCDF1, 0xAE6D, 0xCDF2, 0xAE6E, 0xCDF3, 0xAE6F, - 0xCDF4, 0xAE70, 0xCDF5, 0xAE71, 0xCDF6, 0xAE72, 0xCDF7, 0xAE73, 0xCDF8, 0xC3EE, 0xCDF9, 0xC3EF, 0xCDFA, 0xAE74, 0xCDFB, 0xC3F0, - 0xCDFC, 0xAE75, 0xCDFD, 0xC3F1, 0xCDFE, 0xAE76, 0xCDFF, 0xAE77, 0xCE00, 0xAE78, 0xCE01, 0xAE79, 0xCE02, 0xAE7A, 0xCE03, 0xAE81, - 0xCE04, 0xC3F2, 0xCE05, 0xAE82, 0xCE06, 0xAE83, 0xCE07, 0xAE84, 0xCE08, 0xC3F3, 0xCE09, 0xAE85, 0xCE0A, 0xAE86, 0xCE0B, 0xAE87, - 0xCE0C, 0xC3F4, 0xCE0D, 0xAE88, 0xCE0E, 0xAE89, 0xCE0F, 0xAE8A, 0xCE10, 0xAE8B, 0xCE11, 0xAE8C, 0xCE12, 0xAE8D, 0xCE13, 0xAE8E, - 0xCE14, 0xC3F5, 0xCE15, 0xAE8F, 0xCE16, 0xAE90, 0xCE17, 0xAE91, 0xCE18, 0xAE92, 0xCE19, 0xC3F6, 0xCE1A, 0xAE93, 0xCE1B, 0xAE94, - 0xCE1C, 0xAE95, 0xCE1D, 0xAE96, 0xCE1E, 0xAE97, 0xCE1F, 0xAE98, 0xCE20, 0xC3F7, 0xCE21, 0xC3F8, 0xCE22, 0xAE99, 0xCE23, 0xAE9A, - 0xCE24, 0xC3F9, 0xCE25, 0xAE9B, 0xCE26, 0xAE9C, 0xCE27, 0xAE9D, 0xCE28, 0xC3FA, 0xCE29, 0xAE9E, 0xCE2A, 0xAE9F, 0xCE2B, 0xAEA0, - 0xCE2C, 0xAF41, 0xCE2D, 0xAF42, 0xCE2E, 0xAF43, 0xCE2F, 0xAF44, 0xCE30, 0xC3FB, 0xCE31, 0xC3FC, 0xCE32, 0xAF45, 0xCE33, 0xC3FD, - 0xCE34, 0xAF46, 0xCE35, 0xC3FE, 0xCE36, 0xAF47, 0xCE37, 0xAF48, 0xCE38, 0xAF49, 0xCE39, 0xAF4A, 0xCE3A, 0xAF4B, 0xCE3B, 0xAF4C, - 0xCE3C, 0xAF4D, 0xCE3D, 0xAF4E, 0xCE3E, 0xAF4F, 0xCE3F, 0xAF50, 0xCE40, 0xAF51, 0xCE41, 0xAF52, 0xCE42, 0xAF53, 0xCE43, 0xAF54, - 0xCE44, 0xAF55, 0xCE45, 0xAF56, 0xCE46, 0xAF57, 0xCE47, 0xAF58, 0xCE48, 0xAF59, 0xCE49, 0xAF5A, 0xCE4A, 0xAF61, 0xCE4B, 0xAF62, - 0xCE4C, 0xAF63, 0xCE4D, 0xAF64, 0xCE4E, 0xAF65, 0xCE4F, 0xAF66, 0xCE50, 0xAF67, 0xCE51, 0xAF68, 0xCE52, 0xAF69, 0xCE53, 0xAF6A, - 0xCE54, 0xAF6B, 0xCE55, 0xAF6C, 0xCE56, 0xAF6D, 0xCE57, 0xAF6E, 0xCE58, 0xC4A1, 0xCE59, 0xC4A2, 0xCE5A, 0xAF6F, 0xCE5B, 0xAF70, - 0xCE5C, 0xC4A3, 0xCE5D, 0xAF71, 0xCE5E, 0xAF72, 0xCE5F, 0xC4A4, 0xCE60, 0xC4A5, 0xCE61, 0xC4A6, 0xCE62, 0xAF73, 0xCE63, 0xAF74, - 0xCE64, 0xAF75, 0xCE65, 0xAF76, 0xCE66, 0xAF77, 0xCE67, 0xAF78, 0xCE68, 0xC4A7, 0xCE69, 0xC4A8, 0xCE6A, 0xAF79, 0xCE6B, 0xC4A9, - 0xCE6C, 0xAF7A, 0xCE6D, 0xC4AA, 0xCE6E, 0xAF81, 0xCE6F, 0xAF82, 0xCE70, 0xAF83, 0xCE71, 0xAF84, 0xCE72, 0xAF85, 0xCE73, 0xAF86, - 0xCE74, 0xC4AB, 0xCE75, 0xC4AC, 0xCE76, 0xAF87, 0xCE77, 0xAF88, 0xCE78, 0xC4AD, 0xCE79, 0xAF89, 0xCE7A, 0xAF8A, 0xCE7B, 0xAF8B, - 0xCE7C, 0xC4AE, 0xCE7D, 0xAF8C, 0xCE7E, 0xAF8D, 0xCE7F, 0xAF8E, 0xCE80, 0xAF8F, 0xCE81, 0xAF90, 0xCE82, 0xAF91, 0xCE83, 0xAF92, - 0xCE84, 0xC4AF, 0xCE85, 0xC4B0, 0xCE86, 0xAF93, 0xCE87, 0xC4B1, 0xCE88, 0xAF94, 0xCE89, 0xC4B2, 0xCE8A, 0xAF95, 0xCE8B, 0xAF96, - 0xCE8C, 0xAF97, 0xCE8D, 0xAF98, 0xCE8E, 0xAF99, 0xCE8F, 0xAF9A, 0xCE90, 0xC4B3, 0xCE91, 0xC4B4, 0xCE92, 0xAF9B, 0xCE93, 0xAF9C, - 0xCE94, 0xC4B5, 0xCE95, 0xAF9D, 0xCE96, 0xAF9E, 0xCE97, 0xAF9F, 0xCE98, 0xC4B6, 0xCE99, 0xAFA0, 0xCE9A, 0xB041, 0xCE9B, 0xB042, - 0xCE9C, 0xB043, 0xCE9D, 0xB044, 0xCE9E, 0xB045, 0xCE9F, 0xB046, 0xCEA0, 0xC4B7, 0xCEA1, 0xC4B8, 0xCEA2, 0xB047, 0xCEA3, 0xC4B9, - 0xCEA4, 0xC4BA, 0xCEA5, 0xC4BB, 0xCEA6, 0xB048, 0xCEA7, 0xB049, 0xCEA8, 0xB04A, 0xCEA9, 0xB04B, 0xCEAA, 0xB04C, 0xCEAB, 0xB04D, - 0xCEAC, 0xC4BC, 0xCEAD, 0xC4BD, 0xCEAE, 0xB04E, 0xCEAF, 0xB04F, 0xCEB0, 0xB050, 0xCEB1, 0xB051, 0xCEB2, 0xB052, 0xCEB3, 0xB053, - 0xCEB4, 0xB054, 0xCEB5, 0xB055, 0xCEB6, 0xB056, 0xCEB7, 0xB057, 0xCEB8, 0xB058, 0xCEB9, 0xB059, 0xCEBA, 0xB05A, 0xCEBB, 0xB061, - 0xCEBC, 0xB062, 0xCEBD, 0xB063, 0xCEBE, 0xB064, 0xCEBF, 0xB065, 0xCEC0, 0xB066, 0xCEC1, 0xC4BE, 0xCEC2, 0xB067, 0xCEC3, 0xB068, - 0xCEC4, 0xB069, 0xCEC5, 0xB06A, 0xCEC6, 0xB06B, 0xCEC7, 0xB06C, 0xCEC8, 0xB06D, 0xCEC9, 0xB06E, 0xCECA, 0xB06F, 0xCECB, 0xB070, - 0xCECC, 0xB071, 0xCECD, 0xB072, 0xCECE, 0xB073, 0xCECF, 0xB074, 0xCED0, 0xB075, 0xCED1, 0xB076, 0xCED2, 0xB077, 0xCED3, 0xB078, - 0xCED4, 0xB079, 0xCED5, 0xB07A, 0xCED6, 0xB081, 0xCED7, 0xB082, 0xCED8, 0xB083, 0xCED9, 0xB084, 0xCEDA, 0xB085, 0xCEDB, 0xB086, - 0xCEDC, 0xB087, 0xCEDD, 0xB088, 0xCEDE, 0xB089, 0xCEDF, 0xB08A, 0xCEE0, 0xB08B, 0xCEE1, 0xB08C, 0xCEE2, 0xB08D, 0xCEE3, 0xB08E, - 0xCEE4, 0xC4BF, 0xCEE5, 0xC4C0, 0xCEE6, 0xB08F, 0xCEE7, 0xB090, 0xCEE8, 0xC4C1, 0xCEE9, 0xB091, 0xCEEA, 0xB092, 0xCEEB, 0xC4C2, - 0xCEEC, 0xC4C3, 0xCEED, 0xB093, 0xCEEE, 0xB094, 0xCEEF, 0xB095, 0xCEF0, 0xB096, 0xCEF1, 0xB097, 0xCEF2, 0xB098, 0xCEF3, 0xB099, - 0xCEF4, 0xC4C4, 0xCEF5, 0xC4C5, 0xCEF6, 0xB09A, 0xCEF7, 0xC4C6, 0xCEF8, 0xC4C7, 0xCEF9, 0xC4C8, 0xCEFA, 0xB09B, 0xCEFB, 0xB09C, - 0xCEFC, 0xB09D, 0xCEFD, 0xB09E, 0xCEFE, 0xB09F, 0xCEFF, 0xB0A0, 0xCF00, 0xC4C9, 0xCF01, 0xC4CA, 0xCF02, 0xB141, 0xCF03, 0xB142, - 0xCF04, 0xC4CB, 0xCF05, 0xB143, 0xCF06, 0xB144, 0xCF07, 0xB145, 0xCF08, 0xC4CC, 0xCF09, 0xB146, 0xCF0A, 0xB147, 0xCF0B, 0xB148, - 0xCF0C, 0xB149, 0xCF0D, 0xB14A, 0xCF0E, 0xB14B, 0xCF0F, 0xB14C, 0xCF10, 0xC4CD, 0xCF11, 0xC4CE, 0xCF12, 0xB14D, 0xCF13, 0xC4CF, - 0xCF14, 0xB14E, 0xCF15, 0xC4D0, 0xCF16, 0xB14F, 0xCF17, 0xB150, 0xCF18, 0xB151, 0xCF19, 0xB152, 0xCF1A, 0xB153, 0xCF1B, 0xB154, - 0xCF1C, 0xC4D1, 0xCF1D, 0xB155, 0xCF1E, 0xB156, 0xCF1F, 0xB157, 0xCF20, 0xC4D2, 0xCF21, 0xB158, 0xCF22, 0xB159, 0xCF23, 0xB15A, - 0xCF24, 0xC4D3, 0xCF25, 0xB161, 0xCF26, 0xB162, 0xCF27, 0xB163, 0xCF28, 0xB164, 0xCF29, 0xB165, 0xCF2A, 0xB166, 0xCF2B, 0xB167, - 0xCF2C, 0xC4D4, 0xCF2D, 0xC4D5, 0xCF2E, 0xB168, 0xCF2F, 0xC4D6, 0xCF30, 0xC4D7, 0xCF31, 0xC4D8, 0xCF32, 0xB169, 0xCF33, 0xB16A, - 0xCF34, 0xB16B, 0xCF35, 0xB16C, 0xCF36, 0xB16D, 0xCF37, 0xB16E, 0xCF38, 0xC4D9, 0xCF39, 0xB16F, 0xCF3A, 0xB170, 0xCF3B, 0xB171, - 0xCF3C, 0xB172, 0xCF3D, 0xB173, 0xCF3E, 0xB174, 0xCF3F, 0xB175, 0xCF40, 0xB176, 0xCF41, 0xB177, 0xCF42, 0xB178, 0xCF43, 0xB179, - 0xCF44, 0xB17A, 0xCF45, 0xB181, 0xCF46, 0xB182, 0xCF47, 0xB183, 0xCF48, 0xB184, 0xCF49, 0xB185, 0xCF4A, 0xB186, 0xCF4B, 0xB187, - 0xCF4C, 0xB188, 0xCF4D, 0xB189, 0xCF4E, 0xB18A, 0xCF4F, 0xB18B, 0xCF50, 0xB18C, 0xCF51, 0xB18D, 0xCF52, 0xB18E, 0xCF53, 0xB18F, - 0xCF54, 0xC4DA, 0xCF55, 0xC4DB, 0xCF56, 0xB190, 0xCF57, 0xB191, 0xCF58, 0xC4DC, 0xCF59, 0xB192, 0xCF5A, 0xB193, 0xCF5B, 0xB194, - 0xCF5C, 0xC4DD, 0xCF5D, 0xB195, 0xCF5E, 0xB196, 0xCF5F, 0xB197, 0xCF60, 0xB198, 0xCF61, 0xB199, 0xCF62, 0xB19A, 0xCF63, 0xB19B, - 0xCF64, 0xC4DE, 0xCF65, 0xC4DF, 0xCF66, 0xB19C, 0xCF67, 0xC4E0, 0xCF68, 0xB19D, 0xCF69, 0xC4E1, 0xCF6A, 0xB19E, 0xCF6B, 0xB19F, - 0xCF6C, 0xB1A0, 0xCF6D, 0xB241, 0xCF6E, 0xB242, 0xCF6F, 0xB243, 0xCF70, 0xC4E2, 0xCF71, 0xC4E3, 0xCF72, 0xB244, 0xCF73, 0xB245, - 0xCF74, 0xC4E4, 0xCF75, 0xB246, 0xCF76, 0xB247, 0xCF77, 0xB248, 0xCF78, 0xC4E5, 0xCF79, 0xB249, 0xCF7A, 0xB24A, 0xCF7B, 0xB24B, - 0xCF7C, 0xB24C, 0xCF7D, 0xB24D, 0xCF7E, 0xB24E, 0xCF7F, 0xB24F, 0xCF80, 0xC4E6, 0xCF81, 0xB250, 0xCF82, 0xB251, 0xCF83, 0xB252, - 0xCF84, 0xB253, 0xCF85, 0xC4E7, 0xCF86, 0xB254, 0xCF87, 0xB255, 0xCF88, 0xB256, 0xCF89, 0xB257, 0xCF8A, 0xB258, 0xCF8B, 0xB259, - 0xCF8C, 0xC4E8, 0xCF8D, 0xB25A, 0xCF8E, 0xB261, 0xCF8F, 0xB262, 0xCF90, 0xB263, 0xCF91, 0xB264, 0xCF92, 0xB265, 0xCF93, 0xB266, - 0xCF94, 0xB267, 0xCF95, 0xB268, 0xCF96, 0xB269, 0xCF97, 0xB26A, 0xCF98, 0xB26B, 0xCF99, 0xB26C, 0xCF9A, 0xB26D, 0xCF9B, 0xB26E, - 0xCF9C, 0xB26F, 0xCF9D, 0xB270, 0xCF9E, 0xB271, 0xCF9F, 0xB272, 0xCFA0, 0xB273, 0xCFA1, 0xC4E9, 0xCFA2, 0xB274, 0xCFA3, 0xB275, - 0xCFA4, 0xB276, 0xCFA5, 0xB277, 0xCFA6, 0xB278, 0xCFA7, 0xB279, 0xCFA8, 0xC4EA, 0xCFA9, 0xB27A, 0xCFAA, 0xB281, 0xCFAB, 0xB282, - 0xCFAC, 0xB283, 0xCFAD, 0xB284, 0xCFAE, 0xB285, 0xCFAF, 0xB286, 0xCFB0, 0xC4EB, 0xCFB1, 0xB287, 0xCFB2, 0xB288, 0xCFB3, 0xB289, - 0xCFB4, 0xB28A, 0xCFB5, 0xB28B, 0xCFB6, 0xB28C, 0xCFB7, 0xB28D, 0xCFB8, 0xB28E, 0xCFB9, 0xB28F, 0xCFBA, 0xB290, 0xCFBB, 0xB291, - 0xCFBC, 0xB292, 0xCFBD, 0xB293, 0xCFBE, 0xB294, 0xCFBF, 0xB295, 0xCFC0, 0xB296, 0xCFC1, 0xB297, 0xCFC2, 0xB298, 0xCFC3, 0xB299, - 0xCFC4, 0xC4EC, 0xCFC5, 0xB29A, 0xCFC6, 0xB29B, 0xCFC7, 0xB29C, 0xCFC8, 0xB29D, 0xCFC9, 0xB29E, 0xCFCA, 0xB29F, 0xCFCB, 0xB2A0, - 0xCFCC, 0xB341, 0xCFCD, 0xB342, 0xCFCE, 0xB343, 0xCFCF, 0xB344, 0xCFD0, 0xB345, 0xCFD1, 0xB346, 0xCFD2, 0xB347, 0xCFD3, 0xB348, - 0xCFD4, 0xB349, 0xCFD5, 0xB34A, 0xCFD6, 0xB34B, 0xCFD7, 0xB34C, 0xCFD8, 0xB34D, 0xCFD9, 0xB34E, 0xCFDA, 0xB34F, 0xCFDB, 0xB350, - 0xCFDC, 0xB351, 0xCFDD, 0xB352, 0xCFDE, 0xB353, 0xCFDF, 0xB354, 0xCFE0, 0xC4ED, 0xCFE1, 0xC4EE, 0xCFE2, 0xB355, 0xCFE3, 0xB356, - 0xCFE4, 0xC4EF, 0xCFE5, 0xB357, 0xCFE6, 0xB358, 0xCFE7, 0xB359, 0xCFE8, 0xC4F0, 0xCFE9, 0xB35A, 0xCFEA, 0xB361, 0xCFEB, 0xB362, - 0xCFEC, 0xB363, 0xCFED, 0xB364, 0xCFEE, 0xB365, 0xCFEF, 0xB366, 0xCFF0, 0xC4F1, 0xCFF1, 0xC4F2, 0xCFF2, 0xB367, 0xCFF3, 0xC4F3, - 0xCFF4, 0xB368, 0xCFF5, 0xC4F4, 0xCFF6, 0xB369, 0xCFF7, 0xB36A, 0xCFF8, 0xB36B, 0xCFF9, 0xB36C, 0xCFFA, 0xB36D, 0xCFFB, 0xB36E, - 0xCFFC, 0xC4F5, 0xCFFD, 0xB36F, 0xCFFE, 0xB370, 0xCFFF, 0xB371, 0xD000, 0xC4F6, 0xD001, 0xB372, 0xD002, 0xB373, 0xD003, 0xB374, - 0xD004, 0xC4F7, 0xD005, 0xB375, 0xD006, 0xB376, 0xD007, 0xB377, 0xD008, 0xB378, 0xD009, 0xB379, 0xD00A, 0xB37A, 0xD00B, 0xB381, - 0xD00C, 0xB382, 0xD00D, 0xB383, 0xD00E, 0xB384, 0xD00F, 0xB385, 0xD010, 0xB386, 0xD011, 0xC4F8, 0xD012, 0xB387, 0xD013, 0xB388, - 0xD014, 0xB389, 0xD015, 0xB38A, 0xD016, 0xB38B, 0xD017, 0xB38C, 0xD018, 0xC4F9, 0xD019, 0xB38D, 0xD01A, 0xB38E, 0xD01B, 0xB38F, - 0xD01C, 0xB390, 0xD01D, 0xB391, 0xD01E, 0xB392, 0xD01F, 0xB393, 0xD020, 0xB394, 0xD021, 0xB395, 0xD022, 0xB396, 0xD023, 0xB397, - 0xD024, 0xB398, 0xD025, 0xB399, 0xD026, 0xB39A, 0xD027, 0xB39B, 0xD028, 0xB39C, 0xD029, 0xB39D, 0xD02A, 0xB39E, 0xD02B, 0xB39F, - 0xD02C, 0xB3A0, 0xD02D, 0xC4FA, 0xD02E, 0xB441, 0xD02F, 0xB442, 0xD030, 0xB443, 0xD031, 0xB444, 0xD032, 0xB445, 0xD033, 0xB446, - 0xD034, 0xC4FB, 0xD035, 0xC4FC, 0xD036, 0xB447, 0xD037, 0xB448, 0xD038, 0xC4FD, 0xD039, 0xB449, 0xD03A, 0xB44A, 0xD03B, 0xB44B, - 0xD03C, 0xC4FE, 0xD03D, 0xB44C, 0xD03E, 0xB44D, 0xD03F, 0xB44E, 0xD040, 0xB44F, 0xD041, 0xB450, 0xD042, 0xB451, 0xD043, 0xB452, - 0xD044, 0xC5A1, 0xD045, 0xC5A2, 0xD046, 0xB453, 0xD047, 0xC5A3, 0xD048, 0xB454, 0xD049, 0xC5A4, 0xD04A, 0xB455, 0xD04B, 0xB456, - 0xD04C, 0xB457, 0xD04D, 0xB458, 0xD04E, 0xB459, 0xD04F, 0xB45A, 0xD050, 0xC5A5, 0xD051, 0xB461, 0xD052, 0xB462, 0xD053, 0xB463, - 0xD054, 0xC5A6, 0xD055, 0xB464, 0xD056, 0xB465, 0xD057, 0xB466, 0xD058, 0xC5A7, 0xD059, 0xB467, 0xD05A, 0xB468, 0xD05B, 0xB469, - 0xD05C, 0xB46A, 0xD05D, 0xB46B, 0xD05E, 0xB46C, 0xD05F, 0xB46D, 0xD060, 0xC5A8, 0xD061, 0xB46E, 0xD062, 0xB46F, 0xD063, 0xB470, - 0xD064, 0xB471, 0xD065, 0xB472, 0xD066, 0xB473, 0xD067, 0xB474, 0xD068, 0xB475, 0xD069, 0xB476, 0xD06A, 0xB477, 0xD06B, 0xB478, - 0xD06C, 0xC5A9, 0xD06D, 0xC5AA, 0xD06E, 0xB479, 0xD06F, 0xB47A, 0xD070, 0xC5AB, 0xD071, 0xB481, 0xD072, 0xB482, 0xD073, 0xB483, - 0xD074, 0xC5AC, 0xD075, 0xB484, 0xD076, 0xB485, 0xD077, 0xB486, 0xD078, 0xB487, 0xD079, 0xB488, 0xD07A, 0xB489, 0xD07B, 0xB48A, - 0xD07C, 0xC5AD, 0xD07D, 0xC5AE, 0xD07E, 0xB48B, 0xD07F, 0xB48C, 0xD080, 0xB48D, 0xD081, 0xC5AF, 0xD082, 0xB48E, 0xD083, 0xB48F, - 0xD084, 0xB490, 0xD085, 0xB491, 0xD086, 0xB492, 0xD087, 0xB493, 0xD088, 0xB494, 0xD089, 0xB495, 0xD08A, 0xB496, 0xD08B, 0xB497, - 0xD08C, 0xB498, 0xD08D, 0xB499, 0xD08E, 0xB49A, 0xD08F, 0xB49B, 0xD090, 0xB49C, 0xD091, 0xB49D, 0xD092, 0xB49E, 0xD093, 0xB49F, - 0xD094, 0xB4A0, 0xD095, 0xB541, 0xD096, 0xB542, 0xD097, 0xB543, 0xD098, 0xB544, 0xD099, 0xB545, 0xD09A, 0xB546, 0xD09B, 0xB547, - 0xD09C, 0xB548, 0xD09D, 0xB549, 0xD09E, 0xB54A, 0xD09F, 0xB54B, 0xD0A0, 0xB54C, 0xD0A1, 0xB54D, 0xD0A2, 0xB54E, 0xD0A3, 0xB54F, - 0xD0A4, 0xC5B0, 0xD0A5, 0xC5B1, 0xD0A6, 0xB550, 0xD0A7, 0xB551, 0xD0A8, 0xC5B2, 0xD0A9, 0xB552, 0xD0AA, 0xB553, 0xD0AB, 0xB554, - 0xD0AC, 0xC5B3, 0xD0AD, 0xB555, 0xD0AE, 0xB556, 0xD0AF, 0xB557, 0xD0B0, 0xB558, 0xD0B1, 0xB559, 0xD0B2, 0xB55A, 0xD0B3, 0xB561, - 0xD0B4, 0xC5B4, 0xD0B5, 0xC5B5, 0xD0B6, 0xB562, 0xD0B7, 0xC5B6, 0xD0B8, 0xB563, 0xD0B9, 0xC5B7, 0xD0BA, 0xB564, 0xD0BB, 0xB565, - 0xD0BC, 0xB566, 0xD0BD, 0xB567, 0xD0BE, 0xB568, 0xD0BF, 0xB569, 0xD0C0, 0xC5B8, 0xD0C1, 0xC5B9, 0xD0C2, 0xB56A, 0xD0C3, 0xB56B, - 0xD0C4, 0xC5BA, 0xD0C5, 0xB56C, 0xD0C6, 0xB56D, 0xD0C7, 0xB56E, 0xD0C8, 0xC5BB, 0xD0C9, 0xC5BC, 0xD0CA, 0xB56F, 0xD0CB, 0xB570, - 0xD0CC, 0xB571, 0xD0CD, 0xB572, 0xD0CE, 0xB573, 0xD0CF, 0xB574, 0xD0D0, 0xC5BD, 0xD0D1, 0xC5BE, 0xD0D2, 0xB575, 0xD0D3, 0xC5BF, - 0xD0D4, 0xC5C0, 0xD0D5, 0xC5C1, 0xD0D6, 0xB576, 0xD0D7, 0xB577, 0xD0D8, 0xB578, 0xD0D9, 0xB579, 0xD0DA, 0xB57A, 0xD0DB, 0xB581, - 0xD0DC, 0xC5C2, 0xD0DD, 0xC5C3, 0xD0DE, 0xB582, 0xD0DF, 0xB583, 0xD0E0, 0xC5C4, 0xD0E1, 0xB584, 0xD0E2, 0xB585, 0xD0E3, 0xB586, - 0xD0E4, 0xC5C5, 0xD0E5, 0xB587, 0xD0E6, 0xB588, 0xD0E7, 0xB589, 0xD0E8, 0xB58A, 0xD0E9, 0xB58B, 0xD0EA, 0xB58C, 0xD0EB, 0xB58D, - 0xD0EC, 0xC5C6, 0xD0ED, 0xC5C7, 0xD0EE, 0xB58E, 0xD0EF, 0xC5C8, 0xD0F0, 0xC5C9, 0xD0F1, 0xC5CA, 0xD0F2, 0xB58F, 0xD0F3, 0xB590, - 0xD0F4, 0xB591, 0xD0F5, 0xB592, 0xD0F6, 0xB593, 0xD0F7, 0xB594, 0xD0F8, 0xC5CB, 0xD0F9, 0xB595, 0xD0FA, 0xB596, 0xD0FB, 0xB597, - 0xD0FC, 0xB598, 0xD0FD, 0xB599, 0xD0FE, 0xB59A, 0xD0FF, 0xB59B, 0xD100, 0xB59C, 0xD101, 0xB59D, 0xD102, 0xB59E, 0xD103, 0xB59F, - 0xD104, 0xB5A0, 0xD105, 0xB641, 0xD106, 0xB642, 0xD107, 0xB643, 0xD108, 0xB644, 0xD109, 0xB645, 0xD10A, 0xB646, 0xD10B, 0xB647, - 0xD10C, 0xB648, 0xD10D, 0xC5CC, 0xD10E, 0xB649, 0xD10F, 0xB64A, 0xD110, 0xB64B, 0xD111, 0xB64C, 0xD112, 0xB64D, 0xD113, 0xB64E, - 0xD114, 0xB64F, 0xD115, 0xB650, 0xD116, 0xB651, 0xD117, 0xB652, 0xD118, 0xB653, 0xD119, 0xB654, 0xD11A, 0xB655, 0xD11B, 0xB656, - 0xD11C, 0xB657, 0xD11D, 0xB658, 0xD11E, 0xB659, 0xD11F, 0xB65A, 0xD120, 0xB661, 0xD121, 0xB662, 0xD122, 0xB663, 0xD123, 0xB664, - 0xD124, 0xB665, 0xD125, 0xB666, 0xD126, 0xB667, 0xD127, 0xB668, 0xD128, 0xB669, 0xD129, 0xB66A, 0xD12A, 0xB66B, 0xD12B, 0xB66C, - 0xD12C, 0xB66D, 0xD12D, 0xB66E, 0xD12E, 0xB66F, 0xD12F, 0xB670, 0xD130, 0xC5CD, 0xD131, 0xC5CE, 0xD132, 0xB671, 0xD133, 0xB672, - 0xD134, 0xC5CF, 0xD135, 0xB673, 0xD136, 0xB674, 0xD137, 0xB675, 0xD138, 0xC5D0, 0xD139, 0xB676, 0xD13A, 0xC5D1, 0xD13B, 0xB677, - 0xD13C, 0xB678, 0xD13D, 0xB679, 0xD13E, 0xB67A, 0xD13F, 0xB681, 0xD140, 0xC5D2, 0xD141, 0xC5D3, 0xD142, 0xB682, 0xD143, 0xC5D4, - 0xD144, 0xC5D5, 0xD145, 0xC5D6, 0xD146, 0xB683, 0xD147, 0xB684, 0xD148, 0xB685, 0xD149, 0xB686, 0xD14A, 0xB687, 0xD14B, 0xB688, - 0xD14C, 0xC5D7, 0xD14D, 0xC5D8, 0xD14E, 0xB689, 0xD14F, 0xB68A, 0xD150, 0xC5D9, 0xD151, 0xB68B, 0xD152, 0xB68C, 0xD153, 0xB68D, - 0xD154, 0xC5DA, 0xD155, 0xB68E, 0xD156, 0xB68F, 0xD157, 0xB690, 0xD158, 0xB691, 0xD159, 0xB692, 0xD15A, 0xB693, 0xD15B, 0xB694, - 0xD15C, 0xC5DB, 0xD15D, 0xC5DC, 0xD15E, 0xB695, 0xD15F, 0xC5DD, 0xD160, 0xB696, 0xD161, 0xC5DE, 0xD162, 0xB697, 0xD163, 0xB698, - 0xD164, 0xB699, 0xD165, 0xB69A, 0xD166, 0xB69B, 0xD167, 0xB69C, 0xD168, 0xC5DF, 0xD169, 0xB69D, 0xD16A, 0xB69E, 0xD16B, 0xB69F, - 0xD16C, 0xC5E0, 0xD16D, 0xB6A0, 0xD16E, 0xB741, 0xD16F, 0xB742, 0xD170, 0xB743, 0xD171, 0xB744, 0xD172, 0xB745, 0xD173, 0xB746, - 0xD174, 0xB747, 0xD175, 0xB748, 0xD176, 0xB749, 0xD177, 0xB74A, 0xD178, 0xB74B, 0xD179, 0xB74C, 0xD17A, 0xB74D, 0xD17B, 0xB74E, - 0xD17C, 0xC5E1, 0xD17D, 0xB74F, 0xD17E, 0xB750, 0xD17F, 0xB751, 0xD180, 0xB752, 0xD181, 0xB753, 0xD182, 0xB754, 0xD183, 0xB755, - 0xD184, 0xC5E2, 0xD185, 0xB756, 0xD186, 0xB757, 0xD187, 0xB758, 0xD188, 0xC5E3, 0xD189, 0xB759, 0xD18A, 0xB75A, 0xD18B, 0xB761, - 0xD18C, 0xB762, 0xD18D, 0xB763, 0xD18E, 0xB764, 0xD18F, 0xB765, 0xD190, 0xB766, 0xD191, 0xB767, 0xD192, 0xB768, 0xD193, 0xB769, - 0xD194, 0xB76A, 0xD195, 0xB76B, 0xD196, 0xB76C, 0xD197, 0xB76D, 0xD198, 0xB76E, 0xD199, 0xB76F, 0xD19A, 0xB770, 0xD19B, 0xB771, - 0xD19C, 0xB772, 0xD19D, 0xB773, 0xD19E, 0xB774, 0xD19F, 0xB775, 0xD1A0, 0xC5E4, 0xD1A1, 0xC5E5, 0xD1A2, 0xB776, 0xD1A3, 0xB777, - 0xD1A4, 0xC5E6, 0xD1A5, 0xB778, 0xD1A6, 0xB779, 0xD1A7, 0xB77A, 0xD1A8, 0xC5E7, 0xD1A9, 0xB781, 0xD1AA, 0xB782, 0xD1AB, 0xB783, - 0xD1AC, 0xB784, 0xD1AD, 0xB785, 0xD1AE, 0xB786, 0xD1AF, 0xB787, 0xD1B0, 0xC5E8, 0xD1B1, 0xC5E9, 0xD1B2, 0xB788, 0xD1B3, 0xC5EA, - 0xD1B4, 0xB789, 0xD1B5, 0xC5EB, 0xD1B6, 0xB78A, 0xD1B7, 0xB78B, 0xD1B8, 0xB78C, 0xD1B9, 0xB78D, 0xD1BA, 0xC5EC, 0xD1BB, 0xB78E, - 0xD1BC, 0xC5ED, 0xD1BD, 0xB78F, 0xD1BE, 0xB790, 0xD1BF, 0xB791, 0xD1C0, 0xC5EE, 0xD1C1, 0xB792, 0xD1C2, 0xB793, 0xD1C3, 0xB794, - 0xD1C4, 0xB795, 0xD1C5, 0xB796, 0xD1C6, 0xB797, 0xD1C7, 0xB798, 0xD1C8, 0xB799, 0xD1C9, 0xB79A, 0xD1CA, 0xB79B, 0xD1CB, 0xB79C, - 0xD1CC, 0xB79D, 0xD1CD, 0xB79E, 0xD1CE, 0xB79F, 0xD1CF, 0xB7A0, 0xD1D0, 0xB841, 0xD1D1, 0xB842, 0xD1D2, 0xB843, 0xD1D3, 0xB844, - 0xD1D4, 0xB845, 0xD1D5, 0xB846, 0xD1D6, 0xB847, 0xD1D7, 0xB848, 0xD1D8, 0xC5EF, 0xD1D9, 0xB849, 0xD1DA, 0xB84A, 0xD1DB, 0xB84B, - 0xD1DC, 0xB84C, 0xD1DD, 0xB84D, 0xD1DE, 0xB84E, 0xD1DF, 0xB84F, 0xD1E0, 0xB850, 0xD1E1, 0xB851, 0xD1E2, 0xB852, 0xD1E3, 0xB853, - 0xD1E4, 0xB854, 0xD1E5, 0xB855, 0xD1E6, 0xB856, 0xD1E7, 0xB857, 0xD1E8, 0xB858, 0xD1E9, 0xB859, 0xD1EA, 0xB85A, 0xD1EB, 0xB861, - 0xD1EC, 0xB862, 0xD1ED, 0xB863, 0xD1EE, 0xB864, 0xD1EF, 0xB865, 0xD1F0, 0xB866, 0xD1F1, 0xB867, 0xD1F2, 0xB868, 0xD1F3, 0xB869, - 0xD1F4, 0xC5F0, 0xD1F5, 0xB86A, 0xD1F6, 0xB86B, 0xD1F7, 0xB86C, 0xD1F8, 0xC5F1, 0xD1F9, 0xB86D, 0xD1FA, 0xB86E, 0xD1FB, 0xB86F, - 0xD1FC, 0xB870, 0xD1FD, 0xB871, 0xD1FE, 0xB872, 0xD1FF, 0xB873, 0xD200, 0xB874, 0xD201, 0xB875, 0xD202, 0xB876, 0xD203, 0xB877, - 0xD204, 0xB878, 0xD205, 0xB879, 0xD206, 0xB87A, 0xD207, 0xC5F2, 0xD208, 0xB881, 0xD209, 0xC5F3, 0xD20A, 0xB882, 0xD20B, 0xB883, - 0xD20C, 0xB884, 0xD20D, 0xB885, 0xD20E, 0xB886, 0xD20F, 0xB887, 0xD210, 0xC5F4, 0xD211, 0xB888, 0xD212, 0xB889, 0xD213, 0xB88A, - 0xD214, 0xB88B, 0xD215, 0xB88C, 0xD216, 0xB88D, 0xD217, 0xB88E, 0xD218, 0xB88F, 0xD219, 0xB890, 0xD21A, 0xB891, 0xD21B, 0xB892, - 0xD21C, 0xB893, 0xD21D, 0xB894, 0xD21E, 0xB895, 0xD21F, 0xB896, 0xD220, 0xB897, 0xD221, 0xB898, 0xD222, 0xB899, 0xD223, 0xB89A, - 0xD224, 0xB89B, 0xD225, 0xB89C, 0xD226, 0xB89D, 0xD227, 0xB89E, 0xD228, 0xB89F, 0xD229, 0xB8A0, 0xD22A, 0xB941, 0xD22B, 0xB942, - 0xD22C, 0xC5F5, 0xD22D, 0xC5F6, 0xD22E, 0xB943, 0xD22F, 0xB944, 0xD230, 0xC5F7, 0xD231, 0xB945, 0xD232, 0xB946, 0xD233, 0xB947, - 0xD234, 0xC5F8, 0xD235, 0xB948, 0xD236, 0xB949, 0xD237, 0xB94A, 0xD238, 0xB94B, 0xD239, 0xB94C, 0xD23A, 0xB94D, 0xD23B, 0xB94E, - 0xD23C, 0xC5F9, 0xD23D, 0xC5FA, 0xD23E, 0xB94F, 0xD23F, 0xC5FB, 0xD240, 0xB950, 0xD241, 0xC5FC, 0xD242, 0xB951, 0xD243, 0xB952, - 0xD244, 0xB953, 0xD245, 0xB954, 0xD246, 0xB955, 0xD247, 0xB956, 0xD248, 0xC5FD, 0xD249, 0xB957, 0xD24A, 0xB958, 0xD24B, 0xB959, - 0xD24C, 0xB95A, 0xD24D, 0xB961, 0xD24E, 0xB962, 0xD24F, 0xB963, 0xD250, 0xB964, 0xD251, 0xB965, 0xD252, 0xB966, 0xD253, 0xB967, - 0xD254, 0xB968, 0xD255, 0xB969, 0xD256, 0xB96A, 0xD257, 0xB96B, 0xD258, 0xB96C, 0xD259, 0xB96D, 0xD25A, 0xB96E, 0xD25B, 0xB96F, - 0xD25C, 0xC5FE, 0xD25D, 0xB970, 0xD25E, 0xB971, 0xD25F, 0xB972, 0xD260, 0xB973, 0xD261, 0xB974, 0xD262, 0xB975, 0xD263, 0xB976, - 0xD264, 0xC6A1, 0xD265, 0xB977, 0xD266, 0xB978, 0xD267, 0xB979, 0xD268, 0xB97A, 0xD269, 0xB981, 0xD26A, 0xB982, 0xD26B, 0xB983, - 0xD26C, 0xB984, 0xD26D, 0xB985, 0xD26E, 0xB986, 0xD26F, 0xB987, 0xD270, 0xB988, 0xD271, 0xB989, 0xD272, 0xB98A, 0xD273, 0xB98B, - 0xD274, 0xB98C, 0xD275, 0xB98D, 0xD276, 0xB98E, 0xD277, 0xB98F, 0xD278, 0xB990, 0xD279, 0xB991, 0xD27A, 0xB992, 0xD27B, 0xB993, - 0xD27C, 0xB994, 0xD27D, 0xB995, 0xD27E, 0xB996, 0xD27F, 0xB997, 0xD280, 0xC6A2, 0xD281, 0xC6A3, 0xD282, 0xB998, 0xD283, 0xB999, - 0xD284, 0xC6A4, 0xD285, 0xB99A, 0xD286, 0xB99B, 0xD287, 0xB99C, 0xD288, 0xC6A5, 0xD289, 0xB99D, 0xD28A, 0xB99E, 0xD28B, 0xB99F, - 0xD28C, 0xB9A0, 0xD28D, 0xBA41, 0xD28E, 0xBA42, 0xD28F, 0xBA43, 0xD290, 0xC6A6, 0xD291, 0xC6A7, 0xD292, 0xBA44, 0xD293, 0xBA45, - 0xD294, 0xBA46, 0xD295, 0xC6A8, 0xD296, 0xBA47, 0xD297, 0xBA48, 0xD298, 0xBA49, 0xD299, 0xBA4A, 0xD29A, 0xBA4B, 0xD29B, 0xBA4C, - 0xD29C, 0xC6A9, 0xD29D, 0xBA4D, 0xD29E, 0xBA4E, 0xD29F, 0xBA4F, 0xD2A0, 0xC6AA, 0xD2A1, 0xBA50, 0xD2A2, 0xBA51, 0xD2A3, 0xBA52, - 0xD2A4, 0xC6AB, 0xD2A5, 0xBA53, 0xD2A6, 0xBA54, 0xD2A7, 0xBA55, 0xD2A8, 0xBA56, 0xD2A9, 0xBA57, 0xD2AA, 0xBA58, 0xD2AB, 0xBA59, - 0xD2AC, 0xC6AC, 0xD2AD, 0xBA5A, 0xD2AE, 0xBA61, 0xD2AF, 0xBA62, 0xD2B0, 0xBA63, 0xD2B1, 0xC6AD, 0xD2B2, 0xBA64, 0xD2B3, 0xBA65, - 0xD2B4, 0xBA66, 0xD2B5, 0xBA67, 0xD2B6, 0xBA68, 0xD2B7, 0xBA69, 0xD2B8, 0xC6AE, 0xD2B9, 0xC6AF, 0xD2BA, 0xBA6A, 0xD2BB, 0xBA6B, - 0xD2BC, 0xC6B0, 0xD2BD, 0xBA6C, 0xD2BE, 0xBA6D, 0xD2BF, 0xC6B1, 0xD2C0, 0xC6B2, 0xD2C1, 0xBA6E, 0xD2C2, 0xC6B3, 0xD2C3, 0xBA6F, - 0xD2C4, 0xBA70, 0xD2C5, 0xBA71, 0xD2C6, 0xBA72, 0xD2C7, 0xBA73, 0xD2C8, 0xC6B4, 0xD2C9, 0xC6B5, 0xD2CA, 0xBA74, 0xD2CB, 0xC6B6, - 0xD2CC, 0xBA75, 0xD2CD, 0xBA76, 0xD2CE, 0xBA77, 0xD2CF, 0xBA78, 0xD2D0, 0xBA79, 0xD2D1, 0xBA7A, 0xD2D2, 0xBA81, 0xD2D3, 0xBA82, - 0xD2D4, 0xC6B7, 0xD2D5, 0xBA83, 0xD2D6, 0xBA84, 0xD2D7, 0xBA85, 0xD2D8, 0xC6B8, 0xD2D9, 0xBA86, 0xD2DA, 0xBA87, 0xD2DB, 0xBA88, - 0xD2DC, 0xC6B9, 0xD2DD, 0xBA89, 0xD2DE, 0xBA8A, 0xD2DF, 0xBA8B, 0xD2E0, 0xBA8C, 0xD2E1, 0xBA8D, 0xD2E2, 0xBA8E, 0xD2E3, 0xBA8F, - 0xD2E4, 0xC6BA, 0xD2E5, 0xC6BB, 0xD2E6, 0xBA90, 0xD2E7, 0xBA91, 0xD2E8, 0xBA92, 0xD2E9, 0xBA93, 0xD2EA, 0xBA94, 0xD2EB, 0xBA95, - 0xD2EC, 0xBA96, 0xD2ED, 0xBA97, 0xD2EE, 0xBA98, 0xD2EF, 0xBA99, 0xD2F0, 0xC6BC, 0xD2F1, 0xC6BD, 0xD2F2, 0xBA9A, 0xD2F3, 0xBA9B, - 0xD2F4, 0xC6BE, 0xD2F5, 0xBA9C, 0xD2F6, 0xBA9D, 0xD2F7, 0xBA9E, 0xD2F8, 0xC6BF, 0xD2F9, 0xBA9F, 0xD2FA, 0xBAA0, 0xD2FB, 0xBB41, - 0xD2FC, 0xBB42, 0xD2FD, 0xBB43, 0xD2FE, 0xBB44, 0xD2FF, 0xBB45, 0xD300, 0xC6C0, 0xD301, 0xC6C1, 0xD302, 0xBB46, 0xD303, 0xC6C2, - 0xD304, 0xBB47, 0xD305, 0xC6C3, 0xD306, 0xBB48, 0xD307, 0xBB49, 0xD308, 0xBB4A, 0xD309, 0xBB4B, 0xD30A, 0xBB4C, 0xD30B, 0xBB4D, - 0xD30C, 0xC6C4, 0xD30D, 0xC6C5, 0xD30E, 0xC6C6, 0xD30F, 0xBB4E, 0xD310, 0xC6C7, 0xD311, 0xBB4F, 0xD312, 0xBB50, 0xD313, 0xBB51, - 0xD314, 0xC6C8, 0xD315, 0xBB52, 0xD316, 0xC6C9, 0xD317, 0xBB53, 0xD318, 0xBB54, 0xD319, 0xBB55, 0xD31A, 0xBB56, 0xD31B, 0xBB57, - 0xD31C, 0xC6CA, 0xD31D, 0xC6CB, 0xD31E, 0xBB58, 0xD31F, 0xC6CC, 0xD320, 0xC6CD, 0xD321, 0xC6CE, 0xD322, 0xBB59, 0xD323, 0xBB5A, - 0xD324, 0xBB61, 0xD325, 0xC6CF, 0xD326, 0xBB62, 0xD327, 0xBB63, 0xD328, 0xC6D0, 0xD329, 0xC6D1, 0xD32A, 0xBB64, 0xD32B, 0xBB65, - 0xD32C, 0xC6D2, 0xD32D, 0xBB66, 0xD32E, 0xBB67, 0xD32F, 0xBB68, 0xD330, 0xC6D3, 0xD331, 0xBB69, 0xD332, 0xBB6A, 0xD333, 0xBB6B, - 0xD334, 0xBB6C, 0xD335, 0xBB6D, 0xD336, 0xBB6E, 0xD337, 0xBB6F, 0xD338, 0xC6D4, 0xD339, 0xC6D5, 0xD33A, 0xBB70, 0xD33B, 0xC6D6, - 0xD33C, 0xC6D7, 0xD33D, 0xC6D8, 0xD33E, 0xBB71, 0xD33F, 0xBB72, 0xD340, 0xBB73, 0xD341, 0xBB74, 0xD342, 0xBB75, 0xD343, 0xBB76, - 0xD344, 0xC6D9, 0xD345, 0xC6DA, 0xD346, 0xBB77, 0xD347, 0xBB78, 0xD348, 0xBB79, 0xD349, 0xBB7A, 0xD34A, 0xBB81, 0xD34B, 0xBB82, - 0xD34C, 0xBB83, 0xD34D, 0xBB84, 0xD34E, 0xBB85, 0xD34F, 0xBB86, 0xD350, 0xBB87, 0xD351, 0xBB88, 0xD352, 0xBB89, 0xD353, 0xBB8A, - 0xD354, 0xBB8B, 0xD355, 0xBB8C, 0xD356, 0xBB8D, 0xD357, 0xBB8E, 0xD358, 0xBB8F, 0xD359, 0xBB90, 0xD35A, 0xBB91, 0xD35B, 0xBB92, - 0xD35C, 0xBB93, 0xD35D, 0xBB94, 0xD35E, 0xBB95, 0xD35F, 0xBB96, 0xD360, 0xBB97, 0xD361, 0xBB98, 0xD362, 0xBB99, 0xD363, 0xBB9A, - 0xD364, 0xBB9B, 0xD365, 0xBB9C, 0xD366, 0xBB9D, 0xD367, 0xBB9E, 0xD368, 0xBB9F, 0xD369, 0xBBA0, 0xD36A, 0xBC41, 0xD36B, 0xBC42, - 0xD36C, 0xBC43, 0xD36D, 0xBC44, 0xD36E, 0xBC45, 0xD36F, 0xBC46, 0xD370, 0xBC47, 0xD371, 0xBC48, 0xD372, 0xBC49, 0xD373, 0xBC4A, - 0xD374, 0xBC4B, 0xD375, 0xBC4C, 0xD376, 0xBC4D, 0xD377, 0xBC4E, 0xD378, 0xBC4F, 0xD379, 0xBC50, 0xD37A, 0xBC51, 0xD37B, 0xBC52, - 0xD37C, 0xC6DB, 0xD37D, 0xC6DC, 0xD37E, 0xBC53, 0xD37F, 0xBC54, 0xD380, 0xC6DD, 0xD381, 0xBC55, 0xD382, 0xBC56, 0xD383, 0xBC57, - 0xD384, 0xC6DE, 0xD385, 0xBC58, 0xD386, 0xBC59, 0xD387, 0xBC5A, 0xD388, 0xBC61, 0xD389, 0xBC62, 0xD38A, 0xBC63, 0xD38B, 0xBC64, - 0xD38C, 0xC6DF, 0xD38D, 0xC6E0, 0xD38E, 0xBC65, 0xD38F, 0xC6E1, 0xD390, 0xC6E2, 0xD391, 0xC6E3, 0xD392, 0xBC66, 0xD393, 0xBC67, - 0xD394, 0xBC68, 0xD395, 0xBC69, 0xD396, 0xBC6A, 0xD397, 0xBC6B, 0xD398, 0xC6E4, 0xD399, 0xC6E5, 0xD39A, 0xBC6C, 0xD39B, 0xBC6D, - 0xD39C, 0xC6E6, 0xD39D, 0xBC6E, 0xD39E, 0xBC6F, 0xD39F, 0xBC70, 0xD3A0, 0xC6E7, 0xD3A1, 0xBC71, 0xD3A2, 0xBC72, 0xD3A3, 0xBC73, - 0xD3A4, 0xBC74, 0xD3A5, 0xBC75, 0xD3A6, 0xBC76, 0xD3A7, 0xBC77, 0xD3A8, 0xC6E8, 0xD3A9, 0xC6E9, 0xD3AA, 0xBC78, 0xD3AB, 0xC6EA, - 0xD3AC, 0xBC79, 0xD3AD, 0xC6EB, 0xD3AE, 0xBC7A, 0xD3AF, 0xBC81, 0xD3B0, 0xBC82, 0xD3B1, 0xBC83, 0xD3B2, 0xBC84, 0xD3B3, 0xBC85, - 0xD3B4, 0xC6EC, 0xD3B5, 0xBC86, 0xD3B6, 0xBC87, 0xD3B7, 0xBC88, 0xD3B8, 0xC6ED, 0xD3B9, 0xBC89, 0xD3BA, 0xBC8A, 0xD3BB, 0xBC8B, - 0xD3BC, 0xC6EE, 0xD3BD, 0xBC8C, 0xD3BE, 0xBC8D, 0xD3BF, 0xBC8E, 0xD3C0, 0xBC8F, 0xD3C1, 0xBC90, 0xD3C2, 0xBC91, 0xD3C3, 0xBC92, - 0xD3C4, 0xC6EF, 0xD3C5, 0xC6F0, 0xD3C6, 0xBC93, 0xD3C7, 0xBC94, 0xD3C8, 0xC6F1, 0xD3C9, 0xC6F2, 0xD3CA, 0xBC95, 0xD3CB, 0xBC96, - 0xD3CC, 0xBC97, 0xD3CD, 0xBC98, 0xD3CE, 0xBC99, 0xD3CF, 0xBC9A, 0xD3D0, 0xC6F3, 0xD3D1, 0xBC9B, 0xD3D2, 0xBC9C, 0xD3D3, 0xBC9D, - 0xD3D4, 0xBC9E, 0xD3D5, 0xBC9F, 0xD3D6, 0xBCA0, 0xD3D7, 0xBD41, 0xD3D8, 0xC6F4, 0xD3D9, 0xBD42, 0xD3DA, 0xBD43, 0xD3DB, 0xBD44, - 0xD3DC, 0xBD45, 0xD3DD, 0xBD46, 0xD3DE, 0xBD47, 0xD3DF, 0xBD48, 0xD3E0, 0xBD49, 0xD3E1, 0xC6F5, 0xD3E2, 0xBD4A, 0xD3E3, 0xC6F6, - 0xD3E4, 0xBD4B, 0xD3E5, 0xBD4C, 0xD3E6, 0xBD4D, 0xD3E7, 0xBD4E, 0xD3E8, 0xBD4F, 0xD3E9, 0xBD50, 0xD3EA, 0xBD51, 0xD3EB, 0xBD52, - 0xD3EC, 0xC6F7, 0xD3ED, 0xC6F8, 0xD3EE, 0xBD53, 0xD3EF, 0xBD54, 0xD3F0, 0xC6F9, 0xD3F1, 0xBD55, 0xD3F2, 0xBD56, 0xD3F3, 0xBD57, - 0xD3F4, 0xC6FA, 0xD3F5, 0xBD58, 0xD3F6, 0xBD59, 0xD3F7, 0xBD5A, 0xD3F8, 0xBD61, 0xD3F9, 0xBD62, 0xD3FA, 0xBD63, 0xD3FB, 0xBD64, - 0xD3FC, 0xC6FB, 0xD3FD, 0xC6FC, 0xD3FE, 0xBD65, 0xD3FF, 0xC6FD, 0xD400, 0xBD66, 0xD401, 0xC6FE, 0xD402, 0xBD67, 0xD403, 0xBD68, - 0xD404, 0xBD69, 0xD405, 0xBD6A, 0xD406, 0xBD6B, 0xD407, 0xBD6C, 0xD408, 0xC7A1, 0xD409, 0xBD6D, 0xD40A, 0xBD6E, 0xD40B, 0xBD6F, - 0xD40C, 0xBD70, 0xD40D, 0xBD71, 0xD40E, 0xBD72, 0xD40F, 0xBD73, 0xD410, 0xBD74, 0xD411, 0xBD75, 0xD412, 0xBD76, 0xD413, 0xBD77, - 0xD414, 0xBD78, 0xD415, 0xBD79, 0xD416, 0xBD7A, 0xD417, 0xBD81, 0xD418, 0xBD82, 0xD419, 0xBD83, 0xD41A, 0xBD84, 0xD41B, 0xBD85, - 0xD41C, 0xBD86, 0xD41D, 0xC7A2, 0xD41E, 0xBD87, 0xD41F, 0xBD88, 0xD420, 0xBD89, 0xD421, 0xBD8A, 0xD422, 0xBD8B, 0xD423, 0xBD8C, - 0xD424, 0xBD8D, 0xD425, 0xBD8E, 0xD426, 0xBD8F, 0xD427, 0xBD90, 0xD428, 0xBD91, 0xD429, 0xBD92, 0xD42A, 0xBD93, 0xD42B, 0xBD94, - 0xD42C, 0xBD95, 0xD42D, 0xBD96, 0xD42E, 0xBD97, 0xD42F, 0xBD98, 0xD430, 0xBD99, 0xD431, 0xBD9A, 0xD432, 0xBD9B, 0xD433, 0xBD9C, - 0xD434, 0xBD9D, 0xD435, 0xBD9E, 0xD436, 0xBD9F, 0xD437, 0xBDA0, 0xD438, 0xBE41, 0xD439, 0xBE42, 0xD43A, 0xBE43, 0xD43B, 0xBE44, - 0xD43C, 0xBE45, 0xD43D, 0xBE46, 0xD43E, 0xBE47, 0xD43F, 0xBE48, 0xD440, 0xC7A3, 0xD441, 0xBE49, 0xD442, 0xBE4A, 0xD443, 0xBE4B, - 0xD444, 0xC7A4, 0xD445, 0xBE4C, 0xD446, 0xBE4D, 0xD447, 0xBE4E, 0xD448, 0xBE4F, 0xD449, 0xBE50, 0xD44A, 0xBE51, 0xD44B, 0xBE52, - 0xD44C, 0xBE53, 0xD44D, 0xBE54, 0xD44E, 0xBE55, 0xD44F, 0xBE56, 0xD450, 0xBE57, 0xD451, 0xBE58, 0xD452, 0xBE59, 0xD453, 0xBE5A, - 0xD454, 0xBE61, 0xD455, 0xBE62, 0xD456, 0xBE63, 0xD457, 0xBE64, 0xD458, 0xBE65, 0xD459, 0xBE66, 0xD45A, 0xBE67, 0xD45B, 0xBE68, - 0xD45C, 0xC7A5, 0xD45D, 0xBE69, 0xD45E, 0xBE6A, 0xD45F, 0xBE6B, 0xD460, 0xC7A6, 0xD461, 0xBE6C, 0xD462, 0xBE6D, 0xD463, 0xBE6E, - 0xD464, 0xC7A7, 0xD465, 0xBE6F, 0xD466, 0xBE70, 0xD467, 0xBE71, 0xD468, 0xBE72, 0xD469, 0xBE73, 0xD46A, 0xBE74, 0xD46B, 0xBE75, - 0xD46C, 0xBE76, 0xD46D, 0xC7A8, 0xD46E, 0xBE77, 0xD46F, 0xC7A9, 0xD470, 0xBE78, 0xD471, 0xBE79, 0xD472, 0xBE7A, 0xD473, 0xBE81, - 0xD474, 0xBE82, 0xD475, 0xBE83, 0xD476, 0xBE84, 0xD477, 0xBE85, 0xD478, 0xC7AA, 0xD479, 0xC7AB, 0xD47A, 0xBE86, 0xD47B, 0xBE87, - 0xD47C, 0xC7AC, 0xD47D, 0xBE88, 0xD47E, 0xBE89, 0xD47F, 0xC7AD, 0xD480, 0xC7AE, 0xD481, 0xBE8A, 0xD482, 0xC7AF, 0xD483, 0xBE8B, - 0xD484, 0xBE8C, 0xD485, 0xBE8D, 0xD486, 0xBE8E, 0xD487, 0xBE8F, 0xD488, 0xC7B0, 0xD489, 0xC7B1, 0xD48A, 0xBE90, 0xD48B, 0xC7B2, - 0xD48C, 0xBE91, 0xD48D, 0xC7B3, 0xD48E, 0xBE92, 0xD48F, 0xBE93, 0xD490, 0xBE94, 0xD491, 0xBE95, 0xD492, 0xBE96, 0xD493, 0xBE97, - 0xD494, 0xC7B4, 0xD495, 0xBE98, 0xD496, 0xBE99, 0xD497, 0xBE9A, 0xD498, 0xBE9B, 0xD499, 0xBE9C, 0xD49A, 0xBE9D, 0xD49B, 0xBE9E, - 0xD49C, 0xBE9F, 0xD49D, 0xBEA0, 0xD49E, 0xBF41, 0xD49F, 0xBF42, 0xD4A0, 0xBF43, 0xD4A1, 0xBF44, 0xD4A2, 0xBF45, 0xD4A3, 0xBF46, - 0xD4A4, 0xBF47, 0xD4A5, 0xBF48, 0xD4A6, 0xBF49, 0xD4A7, 0xBF4A, 0xD4A8, 0xBF4B, 0xD4A9, 0xC7B5, 0xD4AA, 0xBF4C, 0xD4AB, 0xBF4D, - 0xD4AC, 0xBF4E, 0xD4AD, 0xBF4F, 0xD4AE, 0xBF50, 0xD4AF, 0xBF51, 0xD4B0, 0xBF52, 0xD4B1, 0xBF53, 0xD4B2, 0xBF54, 0xD4B3, 0xBF55, - 0xD4B4, 0xBF56, 0xD4B5, 0xBF57, 0xD4B6, 0xBF58, 0xD4B7, 0xBF59, 0xD4B8, 0xBF5A, 0xD4B9, 0xBF61, 0xD4BA, 0xBF62, 0xD4BB, 0xBF63, - 0xD4BC, 0xBF64, 0xD4BD, 0xBF65, 0xD4BE, 0xBF66, 0xD4BF, 0xBF67, 0xD4C0, 0xBF68, 0xD4C1, 0xBF69, 0xD4C2, 0xBF6A, 0xD4C3, 0xBF6B, - 0xD4C4, 0xBF6C, 0xD4C5, 0xBF6D, 0xD4C6, 0xBF6E, 0xD4C7, 0xBF6F, 0xD4C8, 0xBF70, 0xD4C9, 0xBF71, 0xD4CA, 0xBF72, 0xD4CB, 0xBF73, - 0xD4CC, 0xC7B6, 0xD4CD, 0xBF74, 0xD4CE, 0xBF75, 0xD4CF, 0xBF76, 0xD4D0, 0xC7B7, 0xD4D1, 0xBF77, 0xD4D2, 0xBF78, 0xD4D3, 0xBF79, - 0xD4D4, 0xC7B8, 0xD4D5, 0xBF7A, 0xD4D6, 0xBF81, 0xD4D7, 0xBF82, 0xD4D8, 0xBF83, 0xD4D9, 0xBF84, 0xD4DA, 0xBF85, 0xD4DB, 0xBF86, - 0xD4DC, 0xC7B9, 0xD4DD, 0xBF87, 0xD4DE, 0xBF88, 0xD4DF, 0xC7BA, 0xD4E0, 0xBF89, 0xD4E1, 0xBF8A, 0xD4E2, 0xBF8B, 0xD4E3, 0xBF8C, - 0xD4E4, 0xBF8D, 0xD4E5, 0xBF8E, 0xD4E6, 0xBF8F, 0xD4E7, 0xBF90, 0xD4E8, 0xC7BB, 0xD4E9, 0xBF91, 0xD4EA, 0xBF92, 0xD4EB, 0xBF93, - 0xD4EC, 0xC7BC, 0xD4ED, 0xBF94, 0xD4EE, 0xBF95, 0xD4EF, 0xBF96, 0xD4F0, 0xC7BD, 0xD4F1, 0xBF97, 0xD4F2, 0xBF98, 0xD4F3, 0xBF99, - 0xD4F4, 0xBF9A, 0xD4F5, 0xBF9B, 0xD4F6, 0xBF9C, 0xD4F7, 0xBF9D, 0xD4F8, 0xC7BE, 0xD4F9, 0xBF9E, 0xD4FA, 0xBF9F, 0xD4FB, 0xC7BF, - 0xD4FC, 0xBFA0, 0xD4FD, 0xC7C0, 0xD4FE, 0xC041, 0xD4FF, 0xC042, 0xD500, 0xC043, 0xD501, 0xC044, 0xD502, 0xC045, 0xD503, 0xC046, - 0xD504, 0xC7C1, 0xD505, 0xC047, 0xD506, 0xC048, 0xD507, 0xC049, 0xD508, 0xC7C2, 0xD509, 0xC04A, 0xD50A, 0xC04B, 0xD50B, 0xC04C, - 0xD50C, 0xC7C3, 0xD50D, 0xC04D, 0xD50E, 0xC04E, 0xD50F, 0xC04F, 0xD510, 0xC050, 0xD511, 0xC051, 0xD512, 0xC052, 0xD513, 0xC053, - 0xD514, 0xC7C4, 0xD515, 0xC7C5, 0xD516, 0xC054, 0xD517, 0xC7C6, 0xD518, 0xC055, 0xD519, 0xC056, 0xD51A, 0xC057, 0xD51B, 0xC058, - 0xD51C, 0xC059, 0xD51D, 0xC05A, 0xD51E, 0xC061, 0xD51F, 0xC062, 0xD520, 0xC063, 0xD521, 0xC064, 0xD522, 0xC065, 0xD523, 0xC066, - 0xD524, 0xC067, 0xD525, 0xC068, 0xD526, 0xC069, 0xD527, 0xC06A, 0xD528, 0xC06B, 0xD529, 0xC06C, 0xD52A, 0xC06D, 0xD52B, 0xC06E, - 0xD52C, 0xC06F, 0xD52D, 0xC070, 0xD52E, 0xC071, 0xD52F, 0xC072, 0xD530, 0xC073, 0xD531, 0xC074, 0xD532, 0xC075, 0xD533, 0xC076, - 0xD534, 0xC077, 0xD535, 0xC078, 0xD536, 0xC079, 0xD537, 0xC07A, 0xD538, 0xC081, 0xD539, 0xC082, 0xD53A, 0xC083, 0xD53B, 0xC084, - 0xD53C, 0xC7C7, 0xD53D, 0xC7C8, 0xD53E, 0xC085, 0xD53F, 0xC086, 0xD540, 0xC7C9, 0xD541, 0xC087, 0xD542, 0xC088, 0xD543, 0xC089, - 0xD544, 0xC7CA, 0xD545, 0xC08A, 0xD546, 0xC08B, 0xD547, 0xC08C, 0xD548, 0xC08D, 0xD549, 0xC08E, 0xD54A, 0xC08F, 0xD54B, 0xC090, - 0xD54C, 0xC7CB, 0xD54D, 0xC7CC, 0xD54E, 0xC091, 0xD54F, 0xC7CD, 0xD550, 0xC092, 0xD551, 0xC7CE, 0xD552, 0xC093, 0xD553, 0xC094, - 0xD554, 0xC095, 0xD555, 0xC096, 0xD556, 0xC097, 0xD557, 0xC098, 0xD558, 0xC7CF, 0xD559, 0xC7D0, 0xD55A, 0xC099, 0xD55B, 0xC09A, - 0xD55C, 0xC7D1, 0xD55D, 0xC09B, 0xD55E, 0xC09C, 0xD55F, 0xC09D, 0xD560, 0xC7D2, 0xD561, 0xC09E, 0xD562, 0xC09F, 0xD563, 0xC0A0, - 0xD564, 0xC141, 0xD565, 0xC7D3, 0xD566, 0xC142, 0xD567, 0xC143, 0xD568, 0xC7D4, 0xD569, 0xC7D5, 0xD56A, 0xC144, 0xD56B, 0xC7D6, - 0xD56C, 0xC145, 0xD56D, 0xC7D7, 0xD56E, 0xC146, 0xD56F, 0xC147, 0xD570, 0xC148, 0xD571, 0xC149, 0xD572, 0xC14A, 0xD573, 0xC14B, - 0xD574, 0xC7D8, 0xD575, 0xC7D9, 0xD576, 0xC14C, 0xD577, 0xC14D, 0xD578, 0xC7DA, 0xD579, 0xC14E, 0xD57A, 0xC14F, 0xD57B, 0xC150, - 0xD57C, 0xC7DB, 0xD57D, 0xC151, 0xD57E, 0xC152, 0xD57F, 0xC153, 0xD580, 0xC154, 0xD581, 0xC155, 0xD582, 0xC156, 0xD583, 0xC157, - 0xD584, 0xC7DC, 0xD585, 0xC7DD, 0xD586, 0xC158, 0xD587, 0xC7DE, 0xD588, 0xC7DF, 0xD589, 0xC7E0, 0xD58A, 0xC159, 0xD58B, 0xC15A, - 0xD58C, 0xC161, 0xD58D, 0xC162, 0xD58E, 0xC163, 0xD58F, 0xC164, 0xD590, 0xC7E1, 0xD591, 0xC165, 0xD592, 0xC166, 0xD593, 0xC167, - 0xD594, 0xC168, 0xD595, 0xC169, 0xD596, 0xC16A, 0xD597, 0xC16B, 0xD598, 0xC16C, 0xD599, 0xC16D, 0xD59A, 0xC16E, 0xD59B, 0xC16F, - 0xD59C, 0xC170, 0xD59D, 0xC171, 0xD59E, 0xC172, 0xD59F, 0xC173, 0xD5A0, 0xC174, 0xD5A1, 0xC175, 0xD5A2, 0xC176, 0xD5A3, 0xC177, - 0xD5A4, 0xC178, 0xD5A5, 0xC7E2, 0xD5A6, 0xC179, 0xD5A7, 0xC17A, 0xD5A8, 0xC181, 0xD5A9, 0xC182, 0xD5AA, 0xC183, 0xD5AB, 0xC184, - 0xD5AC, 0xC185, 0xD5AD, 0xC186, 0xD5AE, 0xC187, 0xD5AF, 0xC188, 0xD5B0, 0xC189, 0xD5B1, 0xC18A, 0xD5B2, 0xC18B, 0xD5B3, 0xC18C, - 0xD5B4, 0xC18D, 0xD5B5, 0xC18E, 0xD5B6, 0xC18F, 0xD5B7, 0xC190, 0xD5B8, 0xC191, 0xD5B9, 0xC192, 0xD5BA, 0xC193, 0xD5BB, 0xC194, - 0xD5BC, 0xC195, 0xD5BD, 0xC196, 0xD5BE, 0xC197, 0xD5BF, 0xC198, 0xD5C0, 0xC199, 0xD5C1, 0xC19A, 0xD5C2, 0xC19B, 0xD5C3, 0xC19C, - 0xD5C4, 0xC19D, 0xD5C5, 0xC19E, 0xD5C6, 0xC19F, 0xD5C7, 0xC1A0, 0xD5C8, 0xC7E3, 0xD5C9, 0xC7E4, 0xD5CA, 0xC241, 0xD5CB, 0xC242, - 0xD5CC, 0xC7E5, 0xD5CD, 0xC243, 0xD5CE, 0xC244, 0xD5CF, 0xC245, 0xD5D0, 0xC7E6, 0xD5D1, 0xC246, 0xD5D2, 0xC7E7, 0xD5D3, 0xC247, - 0xD5D4, 0xC248, 0xD5D5, 0xC249, 0xD5D6, 0xC24A, 0xD5D7, 0xC24B, 0xD5D8, 0xC7E8, 0xD5D9, 0xC7E9, 0xD5DA, 0xC24C, 0xD5DB, 0xC7EA, - 0xD5DC, 0xC24D, 0xD5DD, 0xC7EB, 0xD5DE, 0xC24E, 0xD5DF, 0xC24F, 0xD5E0, 0xC250, 0xD5E1, 0xC251, 0xD5E2, 0xC252, 0xD5E3, 0xC253, - 0xD5E4, 0xC7EC, 0xD5E5, 0xC7ED, 0xD5E6, 0xC254, 0xD5E7, 0xC255, 0xD5E8, 0xC7EE, 0xD5E9, 0xC256, 0xD5EA, 0xC257, 0xD5EB, 0xC258, - 0xD5EC, 0xC7EF, 0xD5ED, 0xC259, 0xD5EE, 0xC25A, 0xD5EF, 0xC261, 0xD5F0, 0xC262, 0xD5F1, 0xC263, 0xD5F2, 0xC264, 0xD5F3, 0xC265, - 0xD5F4, 0xC7F0, 0xD5F5, 0xC7F1, 0xD5F6, 0xC266, 0xD5F7, 0xC7F2, 0xD5F8, 0xC267, 0xD5F9, 0xC7F3, 0xD5FA, 0xC268, 0xD5FB, 0xC269, - 0xD5FC, 0xC26A, 0xD5FD, 0xC26B, 0xD5FE, 0xC26C, 0xD5FF, 0xC26D, 0xD600, 0xC7F4, 0xD601, 0xC7F5, 0xD602, 0xC26E, 0xD603, 0xC26F, - 0xD604, 0xC7F6, 0xD605, 0xC270, 0xD606, 0xC271, 0xD607, 0xC272, 0xD608, 0xC7F7, 0xD609, 0xC273, 0xD60A, 0xC274, 0xD60B, 0xC275, - 0xD60C, 0xC276, 0xD60D, 0xC277, 0xD60E, 0xC278, 0xD60F, 0xC279, 0xD610, 0xC7F8, 0xD611, 0xC7F9, 0xD612, 0xC27A, 0xD613, 0xC7FA, - 0xD614, 0xC7FB, 0xD615, 0xC7FC, 0xD616, 0xC281, 0xD617, 0xC282, 0xD618, 0xC283, 0xD619, 0xC284, 0xD61A, 0xC285, 0xD61B, 0xC286, - 0xD61C, 0xC7FD, 0xD61D, 0xC287, 0xD61E, 0xC288, 0xD61F, 0xC289, 0xD620, 0xC7FE, 0xD621, 0xC28A, 0xD622, 0xC28B, 0xD623, 0xC28C, - 0xD624, 0xC8A1, 0xD625, 0xC28D, 0xD626, 0xC28E, 0xD627, 0xC28F, 0xD628, 0xC290, 0xD629, 0xC291, 0xD62A, 0xC292, 0xD62B, 0xC293, - 0xD62C, 0xC294, 0xD62D, 0xC8A2, 0xD62E, 0xC295, 0xD62F, 0xC296, 0xD630, 0xC297, 0xD631, 0xC298, 0xD632, 0xC299, 0xD633, 0xC29A, - 0xD634, 0xC29B, 0xD635, 0xC29C, 0xD636, 0xC29D, 0xD637, 0xC29E, 0xD638, 0xC8A3, 0xD639, 0xC8A4, 0xD63A, 0xC29F, 0xD63B, 0xC2A0, - 0xD63C, 0xC8A5, 0xD63D, 0xC341, 0xD63E, 0xC342, 0xD63F, 0xC343, 0xD640, 0xC8A6, 0xD641, 0xC344, 0xD642, 0xC345, 0xD643, 0xC346, - 0xD644, 0xC347, 0xD645, 0xC8A7, 0xD646, 0xC348, 0xD647, 0xC349, 0xD648, 0xC8A8, 0xD649, 0xC8A9, 0xD64A, 0xC34A, 0xD64B, 0xC8AA, - 0xD64C, 0xC34B, 0xD64D, 0xC8AB, 0xD64E, 0xC34C, 0xD64F, 0xC34D, 0xD650, 0xC34E, 0xD651, 0xC8AC, 0xD652, 0xC34F, 0xD653, 0xC350, - 0xD654, 0xC8AD, 0xD655, 0xC8AE, 0xD656, 0xC351, 0xD657, 0xC352, 0xD658, 0xC8AF, 0xD659, 0xC353, 0xD65A, 0xC354, 0xD65B, 0xC355, - 0xD65C, 0xC8B0, 0xD65D, 0xC356, 0xD65E, 0xC357, 0xD65F, 0xC358, 0xD660, 0xC359, 0xD661, 0xC35A, 0xD662, 0xC361, 0xD663, 0xC362, - 0xD664, 0xC363, 0xD665, 0xC364, 0xD666, 0xC365, 0xD667, 0xC8B1, 0xD668, 0xC366, 0xD669, 0xC8B2, 0xD66A, 0xC367, 0xD66B, 0xC368, - 0xD66C, 0xC369, 0xD66D, 0xC36A, 0xD66E, 0xC36B, 0xD66F, 0xC36C, 0xD670, 0xC8B3, 0xD671, 0xC8B4, 0xD672, 0xC36D, 0xD673, 0xC36E, - 0xD674, 0xC8B5, 0xD675, 0xC36F, 0xD676, 0xC370, 0xD677, 0xC371, 0xD678, 0xC372, 0xD679, 0xC373, 0xD67A, 0xC374, 0xD67B, 0xC375, - 0xD67C, 0xC376, 0xD67D, 0xC377, 0xD67E, 0xC378, 0xD67F, 0xC379, 0xD680, 0xC37A, 0xD681, 0xC381, 0xD682, 0xC382, 0xD683, 0xC8B6, - 0xD684, 0xC383, 0xD685, 0xC8B7, 0xD686, 0xC384, 0xD687, 0xC385, 0xD688, 0xC386, 0xD689, 0xC387, 0xD68A, 0xC388, 0xD68B, 0xC389, - 0xD68C, 0xC8B8, 0xD68D, 0xC8B9, 0xD68E, 0xC38A, 0xD68F, 0xC38B, 0xD690, 0xC8BA, 0xD691, 0xC38C, 0xD692, 0xC38D, 0xD693, 0xC38E, - 0xD694, 0xC8BB, 0xD695, 0xC38F, 0xD696, 0xC390, 0xD697, 0xC391, 0xD698, 0xC392, 0xD699, 0xC393, 0xD69A, 0xC394, 0xD69B, 0xC395, - 0xD69C, 0xC396, 0xD69D, 0xC8BC, 0xD69E, 0xC397, 0xD69F, 0xC8BD, 0xD6A0, 0xC398, 0xD6A1, 0xC8BE, 0xD6A2, 0xC399, 0xD6A3, 0xC39A, - 0xD6A4, 0xC39B, 0xD6A5, 0xC39C, 0xD6A6, 0xC39D, 0xD6A7, 0xC39E, 0xD6A8, 0xC8BF, 0xD6A9, 0xC39F, 0xD6AA, 0xC3A0, 0xD6AB, 0xC441, - 0xD6AC, 0xC8C0, 0xD6AD, 0xC442, 0xD6AE, 0xC443, 0xD6AF, 0xC444, 0xD6B0, 0xC8C1, 0xD6B1, 0xC445, 0xD6B2, 0xC446, 0xD6B3, 0xC447, - 0xD6B4, 0xC448, 0xD6B5, 0xC449, 0xD6B6, 0xC44A, 0xD6B7, 0xC44B, 0xD6B8, 0xC44C, 0xD6B9, 0xC8C2, 0xD6BA, 0xC44D, 0xD6BB, 0xC8C3, - 0xD6BC, 0xC44E, 0xD6BD, 0xC44F, 0xD6BE, 0xC450, 0xD6BF, 0xC451, 0xD6C0, 0xC452, 0xD6C1, 0xC453, 0xD6C2, 0xC454, 0xD6C3, 0xC455, - 0xD6C4, 0xC8C4, 0xD6C5, 0xC8C5, 0xD6C6, 0xC456, 0xD6C7, 0xC457, 0xD6C8, 0xC8C6, 0xD6C9, 0xC458, 0xD6CA, 0xC459, 0xD6CB, 0xC45A, - 0xD6CC, 0xC8C7, 0xD6CD, 0xC461, 0xD6CE, 0xC462, 0xD6CF, 0xC463, 0xD6D0, 0xC464, 0xD6D1, 0xC8C8, 0xD6D2, 0xC465, 0xD6D3, 0xC466, - 0xD6D4, 0xC8C9, 0xD6D5, 0xC467, 0xD6D6, 0xC468, 0xD6D7, 0xC8CA, 0xD6D8, 0xC469, 0xD6D9, 0xC8CB, 0xD6DA, 0xC46A, 0xD6DB, 0xC46B, - 0xD6DC, 0xC46C, 0xD6DD, 0xC46D, 0xD6DE, 0xC46E, 0xD6DF, 0xC46F, 0xD6E0, 0xC8CC, 0xD6E1, 0xC470, 0xD6E2, 0xC471, 0xD6E3, 0xC472, - 0xD6E4, 0xC8CD, 0xD6E5, 0xC473, 0xD6E6, 0xC474, 0xD6E7, 0xC475, 0xD6E8, 0xC8CE, 0xD6E9, 0xC476, 0xD6EA, 0xC477, 0xD6EB, 0xC478, - 0xD6EC, 0xC479, 0xD6ED, 0xC47A, 0xD6EE, 0xC481, 0xD6EF, 0xC482, 0xD6F0, 0xC8CF, 0xD6F1, 0xC483, 0xD6F2, 0xC484, 0xD6F3, 0xC485, - 0xD6F4, 0xC486, 0xD6F5, 0xC8D0, 0xD6F6, 0xC487, 0xD6F7, 0xC488, 0xD6F8, 0xC489, 0xD6F9, 0xC48A, 0xD6FA, 0xC48B, 0xD6FB, 0xC48C, - 0xD6FC, 0xC8D1, 0xD6FD, 0xC8D2, 0xD6FE, 0xC48D, 0xD6FF, 0xC48E, 0xD700, 0xC8D3, 0xD701, 0xC48F, 0xD702, 0xC490, 0xD703, 0xC491, - 0xD704, 0xC8D4, 0xD705, 0xC492, 0xD706, 0xC493, 0xD707, 0xC494, 0xD708, 0xC495, 0xD709, 0xC496, 0xD70A, 0xC497, 0xD70B, 0xC498, - 0xD70C, 0xC499, 0xD70D, 0xC49A, 0xD70E, 0xC49B, 0xD70F, 0xC49C, 0xD710, 0xC49D, 0xD711, 0xC8D5, 0xD712, 0xC49E, 0xD713, 0xC49F, - 0xD714, 0xC4A0, 0xD715, 0xC541, 0xD716, 0xC542, 0xD717, 0xC543, 0xD718, 0xC8D6, 0xD719, 0xC8D7, 0xD71A, 0xC544, 0xD71B, 0xC545, - 0xD71C, 0xC8D8, 0xD71D, 0xC546, 0xD71E, 0xC547, 0xD71F, 0xC548, 0xD720, 0xC8D9, 0xD721, 0xC549, 0xD722, 0xC54A, 0xD723, 0xC54B, - 0xD724, 0xC54C, 0xD725, 0xC54D, 0xD726, 0xC54E, 0xD727, 0xC54F, 0xD728, 0xC8DA, 0xD729, 0xC8DB, 0xD72A, 0xC550, 0xD72B, 0xC8DC, - 0xD72C, 0xC551, 0xD72D, 0xC8DD, 0xD72E, 0xC552, 0xD72F, 0xC553, 0xD730, 0xC554, 0xD731, 0xC555, 0xD732, 0xC556, 0xD733, 0xC557, - 0xD734, 0xC8DE, 0xD735, 0xC8DF, 0xD736, 0xC558, 0xD737, 0xC559, 0xD738, 0xC8E0, 0xD739, 0xC55A, 0xD73A, 0xC561, 0xD73B, 0xC562, - 0xD73C, 0xC8E1, 0xD73D, 0xC563, 0xD73E, 0xC564, 0xD73F, 0xC565, 0xD740, 0xC566, 0xD741, 0xC567, 0xD742, 0xC568, 0xD743, 0xC569, - 0xD744, 0xC8E2, 0xD745, 0xC56A, 0xD746, 0xC56B, 0xD747, 0xC8E3, 0xD748, 0xC56C, 0xD749, 0xC8E4, 0xD74A, 0xC56D, 0xD74B, 0xC56E, - 0xD74C, 0xC56F, 0xD74D, 0xC570, 0xD74E, 0xC571, 0xD74F, 0xC572, 0xD750, 0xC8E5, 0xD751, 0xC8E6, 0xD752, 0xC573, 0xD753, 0xC574, - 0xD754, 0xC8E7, 0xD755, 0xC575, 0xD756, 0xC8E8, 0xD757, 0xC8E9, 0xD758, 0xC8EA, 0xD759, 0xC8EB, 0xD75A, 0xC576, 0xD75B, 0xC577, - 0xD75C, 0xC578, 0xD75D, 0xC579, 0xD75E, 0xC57A, 0xD75F, 0xC581, 0xD760, 0xC8EC, 0xD761, 0xC8ED, 0xD762, 0xC582, 0xD763, 0xC8EE, - 0xD764, 0xC583, 0xD765, 0xC8EF, 0xD766, 0xC584, 0xD767, 0xC585, 0xD768, 0xC586, 0xD769, 0xC8F0, 0xD76A, 0xC587, 0xD76B, 0xC588, - 0xD76C, 0xC8F1, 0xD76D, 0xC589, 0xD76E, 0xC58A, 0xD76F, 0xC58B, 0xD770, 0xC8F2, 0xD771, 0xC58C, 0xD772, 0xC58D, 0xD773, 0xC58E, - 0xD774, 0xC8F3, 0xD775, 0xC58F, 0xD776, 0xC590, 0xD777, 0xC591, 0xD778, 0xC592, 0xD779, 0xC593, 0xD77A, 0xC594, 0xD77B, 0xC595, - 0xD77C, 0xC8F4, 0xD77D, 0xC8F5, 0xD77E, 0xC596, 0xD77F, 0xC597, 0xD780, 0xC598, 0xD781, 0xC8F6, 0xD782, 0xC599, 0xD783, 0xC59A, - 0xD784, 0xC59B, 0xD785, 0xC59C, 0xD786, 0xC59D, 0xD787, 0xC59E, 0xD788, 0xC8F7, 0xD789, 0xC8F8, 0xD78A, 0xC59F, 0xD78B, 0xC5A0, - 0xD78C, 0xC8F9, 0xD78D, 0xC641, 0xD78E, 0xC642, 0xD78F, 0xC643, 0xD790, 0xC8FA, 0xD791, 0xC644, 0xD792, 0xC645, 0xD793, 0xC646, - 0xD794, 0xC647, 0xD795, 0xC648, 0xD796, 0xC649, 0xD797, 0xC64A, 0xD798, 0xC8FB, 0xD799, 0xC8FC, 0xD79A, 0xC64B, 0xD79B, 0xC8FD, - 0xD79C, 0xC64C, 0xD79D, 0xC8FE, 0xD79E, 0xC64D, 0xD79F, 0xC64E, 0xD7A0, 0xC64F, 0xD7A1, 0xC650, 0xD7A2, 0xC651, 0xD7A3, 0xC652, - 0xF900, 0xCBD0, 0xF901, 0xCBD6, 0xF902, 0xCBE7, 0xF903, 0xCDCF, 0xF904, 0xCDE8, 0xF905, 0xCEAD, 0xF906, 0xCFFB, 0xF907, 0xD0A2, - 0xF908, 0xD0B8, 0xF909, 0xD0D0, 0xF90A, 0xD0DD, 0xF90B, 0xD1D4, 0xF90C, 0xD1D5, 0xF90D, 0xD1D8, 0xF90E, 0xD1DB, 0xF90F, 0xD1DC, - 0xF910, 0xD1DD, 0xF911, 0xD1DE, 0xF912, 0xD1DF, 0xF913, 0xD1E0, 0xF914, 0xD1E2, 0xF915, 0xD1E3, 0xF916, 0xD1E4, 0xF917, 0xD1E5, - 0xF918, 0xD1E6, 0xF919, 0xD1E8, 0xF91A, 0xD1E9, 0xF91B, 0xD1EA, 0xF91C, 0xD1EB, 0xF91D, 0xD1ED, 0xF91E, 0xD1EF, 0xF91F, 0xD1F0, - 0xF920, 0xD1F2, 0xF921, 0xD1F6, 0xF922, 0xD1FA, 0xF923, 0xD1FC, 0xF924, 0xD1FD, 0xF925, 0xD1FE, 0xF926, 0xD2A2, 0xF927, 0xD2A3, - 0xF928, 0xD2A7, 0xF929, 0xD2A8, 0xF92A, 0xD2A9, 0xF92B, 0xD2AA, 0xF92C, 0xD2AB, 0xF92D, 0xD2AD, 0xF92E, 0xD2B2, 0xF92F, 0xD2BE, - 0xF930, 0xD2C2, 0xF931, 0xD2C3, 0xF932, 0xD2C4, 0xF933, 0xD2C6, 0xF934, 0xD2C7, 0xF935, 0xD2C8, 0xF936, 0xD2C9, 0xF937, 0xD2CA, - 0xF938, 0xD2CB, 0xF939, 0xD2CD, 0xF93A, 0xD2CE, 0xF93B, 0xD2CF, 0xF93C, 0xD2D0, 0xF93D, 0xD2D1, 0xF93E, 0xD2D2, 0xF93F, 0xD2D3, - 0xF940, 0xD2D4, 0xF941, 0xD2D5, 0xF942, 0xD2D6, 0xF943, 0xD2D7, 0xF944, 0xD2D9, 0xF945, 0xD2DA, 0xF946, 0xD2DE, 0xF947, 0xD2DF, - 0xF948, 0xD2E1, 0xF949, 0xD2E2, 0xF94A, 0xD2E4, 0xF94B, 0xD2E5, 0xF94C, 0xD2E6, 0xF94D, 0xD2E7, 0xF94E, 0xD2E8, 0xF94F, 0xD2E9, - 0xF950, 0xD2EA, 0xF951, 0xD2EB, 0xF952, 0xD2F0, 0xF953, 0xD2F1, 0xF954, 0xD2F2, 0xF955, 0xD2F3, 0xF956, 0xD2F4, 0xF957, 0xD2F5, - 0xF958, 0xD2F7, 0xF959, 0xD2F8, 0xF95A, 0xD4E6, 0xF95B, 0xD4FC, 0xF95C, 0xD5A5, 0xF95D, 0xD5AB, 0xF95E, 0xD5AE, 0xF95F, 0xD6B8, - 0xF960, 0xD6CD, 0xF961, 0xD7CB, 0xF962, 0xD7E4, 0xF963, 0xDBC5, 0xF964, 0xDBE4, 0xF965, 0xDCA5, 0xF966, 0xDDA5, 0xF967, 0xDDD5, - 0xF968, 0xDDF4, 0xF969, 0xDEFC, 0xF96A, 0xDEFE, 0xF96B, 0xDFB3, 0xF96C, 0xDFE1, 0xF96D, 0xDFE8, 0xF96E, 0xE0F1, 0xF96F, 0xE1AD, - 0xF970, 0xE1ED, 0xF971, 0xE3F5, 0xF972, 0xE4A1, 0xF973, 0xE4A9, 0xF974, 0xE5AE, 0xF975, 0xE5B1, 0xF976, 0xE5B2, 0xF977, 0xE5B9, - 0xF978, 0xE5BB, 0xF979, 0xE5BC, 0xF97A, 0xE5C4, 0xF97B, 0xE5CE, 0xF97C, 0xE5D0, 0xF97D, 0xE5D2, 0xF97E, 0xE5D6, 0xF97F, 0xE5FA, - 0xF980, 0xE5FB, 0xF981, 0xE5FC, 0xF982, 0xE5FE, 0xF983, 0xE6A1, 0xF984, 0xE6A4, 0xF985, 0xE6A7, 0xF986, 0xE6AD, 0xF987, 0xE6AF, - 0xF988, 0xE6B0, 0xF989, 0xE6B1, 0xF98A, 0xE6B3, 0xF98B, 0xE6B7, 0xF98C, 0xE6B8, 0xF98D, 0xE6BC, 0xF98E, 0xE6C4, 0xF98F, 0xE6C6, - 0xF990, 0xE6C7, 0xF991, 0xE6CA, 0xF992, 0xE6D2, 0xF993, 0xE6D6, 0xF994, 0xE6D9, 0xF995, 0xE6DC, 0xF996, 0xE6DF, 0xF997, 0xE6E1, - 0xF998, 0xE6E4, 0xF999, 0xE6E5, 0xF99A, 0xE6E6, 0xF99B, 0xE6E8, 0xF99C, 0xE6EA, 0xF99D, 0xE6EB, 0xF99E, 0xE6EC, 0xF99F, 0xE6EF, - 0xF9A0, 0xE6F1, 0xF9A1, 0xE6F2, 0xF9A2, 0xE6F5, 0xF9A3, 0xE6F6, 0xF9A4, 0xE6F7, 0xF9A5, 0xE6F9, 0xF9A6, 0xE7A1, 0xF9A7, 0xE7A6, - 0xF9A8, 0xE7A9, 0xF9A9, 0xE7AA, 0xF9AA, 0xE7AC, 0xF9AB, 0xE7AD, 0xF9AC, 0xE7B0, 0xF9AD, 0xE7BF, 0xF9AE, 0xE7C1, 0xF9AF, 0xE7C6, - 0xF9B0, 0xE7C7, 0xF9B1, 0xE7CB, 0xF9B2, 0xE7CD, 0xF9B3, 0xE7CF, 0xF9B4, 0xE7D0, 0xF9B5, 0xE7D3, 0xF9B6, 0xE7DF, 0xF9B7, 0xE7E4, - 0xF9B8, 0xE7E6, 0xF9B9, 0xE7F7, 0xF9BA, 0xE8E7, 0xF9BB, 0xE8E8, 0xF9BC, 0xE8F0, 0xF9BD, 0xE8F1, 0xF9BE, 0xE8F7, 0xF9BF, 0xE8F9, - 0xF9C0, 0xE8FB, 0xF9C1, 0xE8FE, 0xF9C2, 0xE9A7, 0xF9C3, 0xE9AC, 0xF9C4, 0xE9CC, 0xF9C5, 0xE9F7, 0xF9C6, 0xEAC1, 0xF9C7, 0xEAE5, - 0xF9C8, 0xEAF4, 0xF9C9, 0xEAF7, 0xF9CA, 0xEAFC, 0xF9CB, 0xEAFE, 0xF9CC, 0xEBA4, 0xF9CD, 0xEBA7, 0xF9CE, 0xEBA9, 0xF9CF, 0xEBAA, - 0xF9D0, 0xEBBA, 0xF9D1, 0xEBBB, 0xF9D2, 0xEBBD, 0xF9D3, 0xEBC1, 0xF9D4, 0xEBC2, 0xF9D5, 0xEBC6, 0xF9D6, 0xEBC7, 0xF9D7, 0xEBCC, - 0xF9D8, 0xEBCF, 0xF9D9, 0xEBD0, 0xF9DA, 0xEBD1, 0xF9DB, 0xEBD2, 0xF9DC, 0xEBD8, 0xF9DD, 0xECA6, 0xF9DE, 0xECA7, 0xF9DF, 0xECAA, - 0xF9E0, 0xECAF, 0xF9E1, 0xECB0, 0xF9E2, 0xECB1, 0xF9E3, 0xECB2, 0xF9E4, 0xECB5, 0xF9E5, 0xECB8, 0xF9E6, 0xECBA, 0xF9E7, 0xECC0, - 0xF9E8, 0xECC1, 0xF9E9, 0xECC5, 0xF9EA, 0xECC6, 0xF9EB, 0xECC9, 0xF9EC, 0xECCA, 0xF9ED, 0xECD5, 0xF9EE, 0xECDD, 0xF9EF, 0xECDE, - 0xF9F0, 0xECE1, 0xF9F1, 0xECE4, 0xF9F2, 0xECE7, 0xF9F3, 0xECE8, 0xF9F4, 0xECF7, 0xF9F5, 0xECF8, 0xF9F6, 0xECFA, 0xF9F7, 0xEDA1, - 0xF9F8, 0xEDA2, 0xF9F9, 0xEDA3, 0xF9FA, 0xEDEE, 0xF9FB, 0xEEDB, 0xF9FC, 0xF2BD, 0xF9FD, 0xF2FA, 0xF9FE, 0xF3B1, 0xF9FF, 0xF4A7, - 0xFA00, 0xF4EE, 0xFA01, 0xF6F4, 0xFA02, 0xF6F6, 0xFA03, 0xF7B8, 0xFA04, 0xF7C8, 0xFA05, 0xF7D3, 0xFA06, 0xF8DB, 0xFA07, 0xF8F0, - 0xFA08, 0xFAA1, 0xFA09, 0xFAA2, 0xFA0A, 0xFAE6, 0xFA0B, 0xFCA9, 0xFF01, 0xA3A1, 0xFF02, 0xA3A2, 0xFF03, 0xA3A3, 0xFF04, 0xA3A4, - 0xFF05, 0xA3A5, 0xFF06, 0xA3A6, 0xFF07, 0xA3A7, 0xFF08, 0xA3A8, 0xFF09, 0xA3A9, 0xFF0A, 0xA3AA, 0xFF0B, 0xA3AB, 0xFF0C, 0xA3AC, - 0xFF0D, 0xA3AD, 0xFF0E, 0xA3AE, 0xFF0F, 0xA3AF, 0xFF10, 0xA3B0, 0xFF11, 0xA3B1, 0xFF12, 0xA3B2, 0xFF13, 0xA3B3, 0xFF14, 0xA3B4, - 0xFF15, 0xA3B5, 0xFF16, 0xA3B6, 0xFF17, 0xA3B7, 0xFF18, 0xA3B8, 0xFF19, 0xA3B9, 0xFF1A, 0xA3BA, 0xFF1B, 0xA3BB, 0xFF1C, 0xA3BC, - 0xFF1D, 0xA3BD, 0xFF1E, 0xA3BE, 0xFF1F, 0xA3BF, 0xFF20, 0xA3C0, 0xFF21, 0xA3C1, 0xFF22, 0xA3C2, 0xFF23, 0xA3C3, 0xFF24, 0xA3C4, - 0xFF25, 0xA3C5, 0xFF26, 0xA3C6, 0xFF27, 0xA3C7, 0xFF28, 0xA3C8, 0xFF29, 0xA3C9, 0xFF2A, 0xA3CA, 0xFF2B, 0xA3CB, 0xFF2C, 0xA3CC, - 0xFF2D, 0xA3CD, 0xFF2E, 0xA3CE, 0xFF2F, 0xA3CF, 0xFF30, 0xA3D0, 0xFF31, 0xA3D1, 0xFF32, 0xA3D2, 0xFF33, 0xA3D3, 0xFF34, 0xA3D4, - 0xFF35, 0xA3D5, 0xFF36, 0xA3D6, 0xFF37, 0xA3D7, 0xFF38, 0xA3D8, 0xFF39, 0xA3D9, 0xFF3A, 0xA3DA, 0xFF3B, 0xA3DB, 0xFF3C, 0xA1AC, - 0xFF3D, 0xA3DD, 0xFF3E, 0xA3DE, 0xFF3F, 0xA3DF, 0xFF40, 0xA3E0, 0xFF41, 0xA3E1, 0xFF42, 0xA3E2, 0xFF43, 0xA3E3, 0xFF44, 0xA3E4, - 0xFF45, 0xA3E5, 0xFF46, 0xA3E6, 0xFF47, 0xA3E7, 0xFF48, 0xA3E8, 0xFF49, 0xA3E9, 0xFF4A, 0xA3EA, 0xFF4B, 0xA3EB, 0xFF4C, 0xA3EC, - 0xFF4D, 0xA3ED, 0xFF4E, 0xA3EE, 0xFF4F, 0xA3EF, 0xFF50, 0xA3F0, 0xFF51, 0xA3F1, 0xFF52, 0xA3F2, 0xFF53, 0xA3F3, 0xFF54, 0xA3F4, - 0xFF55, 0xA3F5, 0xFF56, 0xA3F6, 0xFF57, 0xA3F7, 0xFF58, 0xA3F8, 0xFF59, 0xA3F9, 0xFF5A, 0xA3FA, 0xFF5B, 0xA3FB, 0xFF5C, 0xA3FC, - 0xFF5D, 0xA3FD, 0xFF5E, 0xA2A6, 0xFFE0, 0xA1CB, 0xFFE1, 0xA1CC, 0xFFE2, 0xA1FE, 0xFFE3, 0xA3FE, 0xFFE5, 0xA1CD, 0xFFE6, 0xA3DC, - 0, 0 -}; - -static const WCHAR oem2uni949[] = { /* Korean --> Unicode pairs */ - 0x8141, 0xAC02, 0x8142, 0xAC03, 0x8143, 0xAC05, 0x8144, 0xAC06, 0x8145, 0xAC0B, 0x8146, 0xAC0C, 0x8147, 0xAC0D, 0x8148, 0xAC0E, - 0x8149, 0xAC0F, 0x814A, 0xAC18, 0x814B, 0xAC1E, 0x814C, 0xAC1F, 0x814D, 0xAC21, 0x814E, 0xAC22, 0x814F, 0xAC23, 0x8150, 0xAC25, - 0x8151, 0xAC26, 0x8152, 0xAC27, 0x8153, 0xAC28, 0x8154, 0xAC29, 0x8155, 0xAC2A, 0x8156, 0xAC2B, 0x8157, 0xAC2E, 0x8158, 0xAC32, - 0x8159, 0xAC33, 0x815A, 0xAC34, 0x8161, 0xAC35, 0x8162, 0xAC36, 0x8163, 0xAC37, 0x8164, 0xAC3A, 0x8165, 0xAC3B, 0x8166, 0xAC3D, - 0x8167, 0xAC3E, 0x8168, 0xAC3F, 0x8169, 0xAC41, 0x816A, 0xAC42, 0x816B, 0xAC43, 0x816C, 0xAC44, 0x816D, 0xAC45, 0x816E, 0xAC46, - 0x816F, 0xAC47, 0x8170, 0xAC48, 0x8171, 0xAC49, 0x8172, 0xAC4A, 0x8173, 0xAC4C, 0x8174, 0xAC4E, 0x8175, 0xAC4F, 0x8176, 0xAC50, - 0x8177, 0xAC51, 0x8178, 0xAC52, 0x8179, 0xAC53, 0x817A, 0xAC55, 0x8181, 0xAC56, 0x8182, 0xAC57, 0x8183, 0xAC59, 0x8184, 0xAC5A, - 0x8185, 0xAC5B, 0x8186, 0xAC5D, 0x8187, 0xAC5E, 0x8188, 0xAC5F, 0x8189, 0xAC60, 0x818A, 0xAC61, 0x818B, 0xAC62, 0x818C, 0xAC63, - 0x818D, 0xAC64, 0x818E, 0xAC65, 0x818F, 0xAC66, 0x8190, 0xAC67, 0x8191, 0xAC68, 0x8192, 0xAC69, 0x8193, 0xAC6A, 0x8194, 0xAC6B, - 0x8195, 0xAC6C, 0x8196, 0xAC6D, 0x8197, 0xAC6E, 0x8198, 0xAC6F, 0x8199, 0xAC72, 0x819A, 0xAC73, 0x819B, 0xAC75, 0x819C, 0xAC76, - 0x819D, 0xAC79, 0x819E, 0xAC7B, 0x819F, 0xAC7C, 0x81A0, 0xAC7D, 0x81A1, 0xAC7E, 0x81A2, 0xAC7F, 0x81A3, 0xAC82, 0x81A4, 0xAC87, - 0x81A5, 0xAC88, 0x81A6, 0xAC8D, 0x81A7, 0xAC8E, 0x81A8, 0xAC8F, 0x81A9, 0xAC91, 0x81AA, 0xAC92, 0x81AB, 0xAC93, 0x81AC, 0xAC95, - 0x81AD, 0xAC96, 0x81AE, 0xAC97, 0x81AF, 0xAC98, 0x81B0, 0xAC99, 0x81B1, 0xAC9A, 0x81B2, 0xAC9B, 0x81B3, 0xAC9E, 0x81B4, 0xACA2, - 0x81B5, 0xACA3, 0x81B6, 0xACA4, 0x81B7, 0xACA5, 0x81B8, 0xACA6, 0x81B9, 0xACA7, 0x81BA, 0xACAB, 0x81BB, 0xACAD, 0x81BC, 0xACAE, - 0x81BD, 0xACB1, 0x81BE, 0xACB2, 0x81BF, 0xACB3, 0x81C0, 0xACB4, 0x81C1, 0xACB5, 0x81C2, 0xACB6, 0x81C3, 0xACB7, 0x81C4, 0xACBA, - 0x81C5, 0xACBE, 0x81C6, 0xACBF, 0x81C7, 0xACC0, 0x81C8, 0xACC2, 0x81C9, 0xACC3, 0x81CA, 0xACC5, 0x81CB, 0xACC6, 0x81CC, 0xACC7, - 0x81CD, 0xACC9, 0x81CE, 0xACCA, 0x81CF, 0xACCB, 0x81D0, 0xACCD, 0x81D1, 0xACCE, 0x81D2, 0xACCF, 0x81D3, 0xACD0, 0x81D4, 0xACD1, - 0x81D5, 0xACD2, 0x81D6, 0xACD3, 0x81D7, 0xACD4, 0x81D8, 0xACD6, 0x81D9, 0xACD8, 0x81DA, 0xACD9, 0x81DB, 0xACDA, 0x81DC, 0xACDB, - 0x81DD, 0xACDC, 0x81DE, 0xACDD, 0x81DF, 0xACDE, 0x81E0, 0xACDF, 0x81E1, 0xACE2, 0x81E2, 0xACE3, 0x81E3, 0xACE5, 0x81E4, 0xACE6, - 0x81E5, 0xACE9, 0x81E6, 0xACEB, 0x81E7, 0xACED, 0x81E8, 0xACEE, 0x81E9, 0xACF2, 0x81EA, 0xACF4, 0x81EB, 0xACF7, 0x81EC, 0xACF8, - 0x81ED, 0xACF9, 0x81EE, 0xACFA, 0x81EF, 0xACFB, 0x81F0, 0xACFE, 0x81F1, 0xACFF, 0x81F2, 0xAD01, 0x81F3, 0xAD02, 0x81F4, 0xAD03, - 0x81F5, 0xAD05, 0x81F6, 0xAD07, 0x81F7, 0xAD08, 0x81F8, 0xAD09, 0x81F9, 0xAD0A, 0x81FA, 0xAD0B, 0x81FB, 0xAD0E, 0x81FC, 0xAD10, - 0x81FD, 0xAD12, 0x81FE, 0xAD13, 0x8241, 0xAD14, 0x8242, 0xAD15, 0x8243, 0xAD16, 0x8244, 0xAD17, 0x8245, 0xAD19, 0x8246, 0xAD1A, - 0x8247, 0xAD1B, 0x8248, 0xAD1D, 0x8249, 0xAD1E, 0x824A, 0xAD1F, 0x824B, 0xAD21, 0x824C, 0xAD22, 0x824D, 0xAD23, 0x824E, 0xAD24, - 0x824F, 0xAD25, 0x8250, 0xAD26, 0x8251, 0xAD27, 0x8252, 0xAD28, 0x8253, 0xAD2A, 0x8254, 0xAD2B, 0x8255, 0xAD2E, 0x8256, 0xAD2F, - 0x8257, 0xAD30, 0x8258, 0xAD31, 0x8259, 0xAD32, 0x825A, 0xAD33, 0x8261, 0xAD36, 0x8262, 0xAD37, 0x8263, 0xAD39, 0x8264, 0xAD3A, - 0x8265, 0xAD3B, 0x8266, 0xAD3D, 0x8267, 0xAD3E, 0x8268, 0xAD3F, 0x8269, 0xAD40, 0x826A, 0xAD41, 0x826B, 0xAD42, 0x826C, 0xAD43, - 0x826D, 0xAD46, 0x826E, 0xAD48, 0x826F, 0xAD4A, 0x8270, 0xAD4B, 0x8271, 0xAD4C, 0x8272, 0xAD4D, 0x8273, 0xAD4E, 0x8274, 0xAD4F, - 0x8275, 0xAD51, 0x8276, 0xAD52, 0x8277, 0xAD53, 0x8278, 0xAD55, 0x8279, 0xAD56, 0x827A, 0xAD57, 0x8281, 0xAD59, 0x8282, 0xAD5A, - 0x8283, 0xAD5B, 0x8284, 0xAD5C, 0x8285, 0xAD5D, 0x8286, 0xAD5E, 0x8287, 0xAD5F, 0x8288, 0xAD60, 0x8289, 0xAD62, 0x828A, 0xAD64, - 0x828B, 0xAD65, 0x828C, 0xAD66, 0x828D, 0xAD67, 0x828E, 0xAD68, 0x828F, 0xAD69, 0x8290, 0xAD6A, 0x8291, 0xAD6B, 0x8292, 0xAD6E, - 0x8293, 0xAD6F, 0x8294, 0xAD71, 0x8295, 0xAD72, 0x8296, 0xAD77, 0x8297, 0xAD78, 0x8298, 0xAD79, 0x8299, 0xAD7A, 0x829A, 0xAD7E, - 0x829B, 0xAD80, 0x829C, 0xAD83, 0x829D, 0xAD84, 0x829E, 0xAD85, 0x829F, 0xAD86, 0x82A0, 0xAD87, 0x82A1, 0xAD8A, 0x82A2, 0xAD8B, - 0x82A3, 0xAD8D, 0x82A4, 0xAD8E, 0x82A5, 0xAD8F, 0x82A6, 0xAD91, 0x82A7, 0xAD92, 0x82A8, 0xAD93, 0x82A9, 0xAD94, 0x82AA, 0xAD95, - 0x82AB, 0xAD96, 0x82AC, 0xAD97, 0x82AD, 0xAD98, 0x82AE, 0xAD99, 0x82AF, 0xAD9A, 0x82B0, 0xAD9B, 0x82B1, 0xAD9E, 0x82B2, 0xAD9F, - 0x82B3, 0xADA0, 0x82B4, 0xADA1, 0x82B5, 0xADA2, 0x82B6, 0xADA3, 0x82B7, 0xADA5, 0x82B8, 0xADA6, 0x82B9, 0xADA7, 0x82BA, 0xADA8, - 0x82BB, 0xADA9, 0x82BC, 0xADAA, 0x82BD, 0xADAB, 0x82BE, 0xADAC, 0x82BF, 0xADAD, 0x82C0, 0xADAE, 0x82C1, 0xADAF, 0x82C2, 0xADB0, - 0x82C3, 0xADB1, 0x82C4, 0xADB2, 0x82C5, 0xADB3, 0x82C6, 0xADB4, 0x82C7, 0xADB5, 0x82C8, 0xADB6, 0x82C9, 0xADB8, 0x82CA, 0xADB9, - 0x82CB, 0xADBA, 0x82CC, 0xADBB, 0x82CD, 0xADBC, 0x82CE, 0xADBD, 0x82CF, 0xADBE, 0x82D0, 0xADBF, 0x82D1, 0xADC2, 0x82D2, 0xADC3, - 0x82D3, 0xADC5, 0x82D4, 0xADC6, 0x82D5, 0xADC7, 0x82D6, 0xADC9, 0x82D7, 0xADCA, 0x82D8, 0xADCB, 0x82D9, 0xADCC, 0x82DA, 0xADCD, - 0x82DB, 0xADCE, 0x82DC, 0xADCF, 0x82DD, 0xADD2, 0x82DE, 0xADD4, 0x82DF, 0xADD5, 0x82E0, 0xADD6, 0x82E1, 0xADD7, 0x82E2, 0xADD8, - 0x82E3, 0xADD9, 0x82E4, 0xADDA, 0x82E5, 0xADDB, 0x82E6, 0xADDD, 0x82E7, 0xADDE, 0x82E8, 0xADDF, 0x82E9, 0xADE1, 0x82EA, 0xADE2, - 0x82EB, 0xADE3, 0x82EC, 0xADE5, 0x82ED, 0xADE6, 0x82EE, 0xADE7, 0x82EF, 0xADE8, 0x82F0, 0xADE9, 0x82F1, 0xADEA, 0x82F2, 0xADEB, - 0x82F3, 0xADEC, 0x82F4, 0xADED, 0x82F5, 0xADEE, 0x82F6, 0xADEF, 0x82F7, 0xADF0, 0x82F8, 0xADF1, 0x82F9, 0xADF2, 0x82FA, 0xADF3, - 0x82FB, 0xADF4, 0x82FC, 0xADF5, 0x82FD, 0xADF6, 0x82FE, 0xADF7, 0x8341, 0xADFA, 0x8342, 0xADFB, 0x8343, 0xADFD, 0x8344, 0xADFE, - 0x8345, 0xAE02, 0x8346, 0xAE03, 0x8347, 0xAE04, 0x8348, 0xAE05, 0x8349, 0xAE06, 0x834A, 0xAE07, 0x834B, 0xAE0A, 0x834C, 0xAE0C, - 0x834D, 0xAE0E, 0x834E, 0xAE0F, 0x834F, 0xAE10, 0x8350, 0xAE11, 0x8351, 0xAE12, 0x8352, 0xAE13, 0x8353, 0xAE15, 0x8354, 0xAE16, - 0x8355, 0xAE17, 0x8356, 0xAE18, 0x8357, 0xAE19, 0x8358, 0xAE1A, 0x8359, 0xAE1B, 0x835A, 0xAE1C, 0x8361, 0xAE1D, 0x8362, 0xAE1E, - 0x8363, 0xAE1F, 0x8364, 0xAE20, 0x8365, 0xAE21, 0x8366, 0xAE22, 0x8367, 0xAE23, 0x8368, 0xAE24, 0x8369, 0xAE25, 0x836A, 0xAE26, - 0x836B, 0xAE27, 0x836C, 0xAE28, 0x836D, 0xAE29, 0x836E, 0xAE2A, 0x836F, 0xAE2B, 0x8370, 0xAE2C, 0x8371, 0xAE2D, 0x8372, 0xAE2E, - 0x8373, 0xAE2F, 0x8374, 0xAE32, 0x8375, 0xAE33, 0x8376, 0xAE35, 0x8377, 0xAE36, 0x8378, 0xAE39, 0x8379, 0xAE3B, 0x837A, 0xAE3C, - 0x8381, 0xAE3D, 0x8382, 0xAE3E, 0x8383, 0xAE3F, 0x8384, 0xAE42, 0x8385, 0xAE44, 0x8386, 0xAE47, 0x8387, 0xAE48, 0x8388, 0xAE49, - 0x8389, 0xAE4B, 0x838A, 0xAE4F, 0x838B, 0xAE51, 0x838C, 0xAE52, 0x838D, 0xAE53, 0x838E, 0xAE55, 0x838F, 0xAE57, 0x8390, 0xAE58, - 0x8391, 0xAE59, 0x8392, 0xAE5A, 0x8393, 0xAE5B, 0x8394, 0xAE5E, 0x8395, 0xAE62, 0x8396, 0xAE63, 0x8397, 0xAE64, 0x8398, 0xAE66, - 0x8399, 0xAE67, 0x839A, 0xAE6A, 0x839B, 0xAE6B, 0x839C, 0xAE6D, 0x839D, 0xAE6E, 0x839E, 0xAE6F, 0x839F, 0xAE71, 0x83A0, 0xAE72, - 0x83A1, 0xAE73, 0x83A2, 0xAE74, 0x83A3, 0xAE75, 0x83A4, 0xAE76, 0x83A5, 0xAE77, 0x83A6, 0xAE7A, 0x83A7, 0xAE7E, 0x83A8, 0xAE7F, - 0x83A9, 0xAE80, 0x83AA, 0xAE81, 0x83AB, 0xAE82, 0x83AC, 0xAE83, 0x83AD, 0xAE86, 0x83AE, 0xAE87, 0x83AF, 0xAE88, 0x83B0, 0xAE89, - 0x83B1, 0xAE8A, 0x83B2, 0xAE8B, 0x83B3, 0xAE8D, 0x83B4, 0xAE8E, 0x83B5, 0xAE8F, 0x83B6, 0xAE90, 0x83B7, 0xAE91, 0x83B8, 0xAE92, - 0x83B9, 0xAE93, 0x83BA, 0xAE94, 0x83BB, 0xAE95, 0x83BC, 0xAE96, 0x83BD, 0xAE97, 0x83BE, 0xAE98, 0x83BF, 0xAE99, 0x83C0, 0xAE9A, - 0x83C1, 0xAE9B, 0x83C2, 0xAE9C, 0x83C3, 0xAE9D, 0x83C4, 0xAE9E, 0x83C5, 0xAE9F, 0x83C6, 0xAEA0, 0x83C7, 0xAEA1, 0x83C8, 0xAEA2, - 0x83C9, 0xAEA3, 0x83CA, 0xAEA4, 0x83CB, 0xAEA5, 0x83CC, 0xAEA6, 0x83CD, 0xAEA7, 0x83CE, 0xAEA8, 0x83CF, 0xAEA9, 0x83D0, 0xAEAA, - 0x83D1, 0xAEAB, 0x83D2, 0xAEAC, 0x83D3, 0xAEAD, 0x83D4, 0xAEAE, 0x83D5, 0xAEAF, 0x83D6, 0xAEB0, 0x83D7, 0xAEB1, 0x83D8, 0xAEB2, - 0x83D9, 0xAEB3, 0x83DA, 0xAEB4, 0x83DB, 0xAEB5, 0x83DC, 0xAEB6, 0x83DD, 0xAEB7, 0x83DE, 0xAEB8, 0x83DF, 0xAEB9, 0x83E0, 0xAEBA, - 0x83E1, 0xAEBB, 0x83E2, 0xAEBF, 0x83E3, 0xAEC1, 0x83E4, 0xAEC2, 0x83E5, 0xAEC3, 0x83E6, 0xAEC5, 0x83E7, 0xAEC6, 0x83E8, 0xAEC7, - 0x83E9, 0xAEC8, 0x83EA, 0xAEC9, 0x83EB, 0xAECA, 0x83EC, 0xAECB, 0x83ED, 0xAECE, 0x83EE, 0xAED2, 0x83EF, 0xAED3, 0x83F0, 0xAED4, - 0x83F1, 0xAED5, 0x83F2, 0xAED6, 0x83F3, 0xAED7, 0x83F4, 0xAEDA, 0x83F5, 0xAEDB, 0x83F6, 0xAEDD, 0x83F7, 0xAEDE, 0x83F8, 0xAEDF, - 0x83F9, 0xAEE0, 0x83FA, 0xAEE1, 0x83FB, 0xAEE2, 0x83FC, 0xAEE3, 0x83FD, 0xAEE4, 0x83FE, 0xAEE5, 0x8441, 0xAEE6, 0x8442, 0xAEE7, - 0x8443, 0xAEE9, 0x8444, 0xAEEA, 0x8445, 0xAEEC, 0x8446, 0xAEEE, 0x8447, 0xAEEF, 0x8448, 0xAEF0, 0x8449, 0xAEF1, 0x844A, 0xAEF2, - 0x844B, 0xAEF3, 0x844C, 0xAEF5, 0x844D, 0xAEF6, 0x844E, 0xAEF7, 0x844F, 0xAEF9, 0x8450, 0xAEFA, 0x8451, 0xAEFB, 0x8452, 0xAEFD, - 0x8453, 0xAEFE, 0x8454, 0xAEFF, 0x8455, 0xAF00, 0x8456, 0xAF01, 0x8457, 0xAF02, 0x8458, 0xAF03, 0x8459, 0xAF04, 0x845A, 0xAF05, - 0x8461, 0xAF06, 0x8462, 0xAF09, 0x8463, 0xAF0A, 0x8464, 0xAF0B, 0x8465, 0xAF0C, 0x8466, 0xAF0E, 0x8467, 0xAF0F, 0x8468, 0xAF11, - 0x8469, 0xAF12, 0x846A, 0xAF13, 0x846B, 0xAF14, 0x846C, 0xAF15, 0x846D, 0xAF16, 0x846E, 0xAF17, 0x846F, 0xAF18, 0x8470, 0xAF19, - 0x8471, 0xAF1A, 0x8472, 0xAF1B, 0x8473, 0xAF1C, 0x8474, 0xAF1D, 0x8475, 0xAF1E, 0x8476, 0xAF1F, 0x8477, 0xAF20, 0x8478, 0xAF21, - 0x8479, 0xAF22, 0x847A, 0xAF23, 0x8481, 0xAF24, 0x8482, 0xAF25, 0x8483, 0xAF26, 0x8484, 0xAF27, 0x8485, 0xAF28, 0x8486, 0xAF29, - 0x8487, 0xAF2A, 0x8488, 0xAF2B, 0x8489, 0xAF2E, 0x848A, 0xAF2F, 0x848B, 0xAF31, 0x848C, 0xAF33, 0x848D, 0xAF35, 0x848E, 0xAF36, - 0x848F, 0xAF37, 0x8490, 0xAF38, 0x8491, 0xAF39, 0x8492, 0xAF3A, 0x8493, 0xAF3B, 0x8494, 0xAF3E, 0x8495, 0xAF40, 0x8496, 0xAF44, - 0x8497, 0xAF45, 0x8498, 0xAF46, 0x8499, 0xAF47, 0x849A, 0xAF4A, 0x849B, 0xAF4B, 0x849C, 0xAF4C, 0x849D, 0xAF4D, 0x849E, 0xAF4E, - 0x849F, 0xAF4F, 0x84A0, 0xAF51, 0x84A1, 0xAF52, 0x84A2, 0xAF53, 0x84A3, 0xAF54, 0x84A4, 0xAF55, 0x84A5, 0xAF56, 0x84A6, 0xAF57, - 0x84A7, 0xAF58, 0x84A8, 0xAF59, 0x84A9, 0xAF5A, 0x84AA, 0xAF5B, 0x84AB, 0xAF5E, 0x84AC, 0xAF5F, 0x84AD, 0xAF60, 0x84AE, 0xAF61, - 0x84AF, 0xAF62, 0x84B0, 0xAF63, 0x84B1, 0xAF66, 0x84B2, 0xAF67, 0x84B3, 0xAF68, 0x84B4, 0xAF69, 0x84B5, 0xAF6A, 0x84B6, 0xAF6B, - 0x84B7, 0xAF6C, 0x84B8, 0xAF6D, 0x84B9, 0xAF6E, 0x84BA, 0xAF6F, 0x84BB, 0xAF70, 0x84BC, 0xAF71, 0x84BD, 0xAF72, 0x84BE, 0xAF73, - 0x84BF, 0xAF74, 0x84C0, 0xAF75, 0x84C1, 0xAF76, 0x84C2, 0xAF77, 0x84C3, 0xAF78, 0x84C4, 0xAF7A, 0x84C5, 0xAF7B, 0x84C6, 0xAF7C, - 0x84C7, 0xAF7D, 0x84C8, 0xAF7E, 0x84C9, 0xAF7F, 0x84CA, 0xAF81, 0x84CB, 0xAF82, 0x84CC, 0xAF83, 0x84CD, 0xAF85, 0x84CE, 0xAF86, - 0x84CF, 0xAF87, 0x84D0, 0xAF89, 0x84D1, 0xAF8A, 0x84D2, 0xAF8B, 0x84D3, 0xAF8C, 0x84D4, 0xAF8D, 0x84D5, 0xAF8E, 0x84D6, 0xAF8F, - 0x84D7, 0xAF92, 0x84D8, 0xAF93, 0x84D9, 0xAF94, 0x84DA, 0xAF96, 0x84DB, 0xAF97, 0x84DC, 0xAF98, 0x84DD, 0xAF99, 0x84DE, 0xAF9A, - 0x84DF, 0xAF9B, 0x84E0, 0xAF9D, 0x84E1, 0xAF9E, 0x84E2, 0xAF9F, 0x84E3, 0xAFA0, 0x84E4, 0xAFA1, 0x84E5, 0xAFA2, 0x84E6, 0xAFA3, - 0x84E7, 0xAFA4, 0x84E8, 0xAFA5, 0x84E9, 0xAFA6, 0x84EA, 0xAFA7, 0x84EB, 0xAFA8, 0x84EC, 0xAFA9, 0x84ED, 0xAFAA, 0x84EE, 0xAFAB, - 0x84EF, 0xAFAC, 0x84F0, 0xAFAD, 0x84F1, 0xAFAE, 0x84F2, 0xAFAF, 0x84F3, 0xAFB0, 0x84F4, 0xAFB1, 0x84F5, 0xAFB2, 0x84F6, 0xAFB3, - 0x84F7, 0xAFB4, 0x84F8, 0xAFB5, 0x84F9, 0xAFB6, 0x84FA, 0xAFB7, 0x84FB, 0xAFBA, 0x84FC, 0xAFBB, 0x84FD, 0xAFBD, 0x84FE, 0xAFBE, - 0x8541, 0xAFBF, 0x8542, 0xAFC1, 0x8543, 0xAFC2, 0x8544, 0xAFC3, 0x8545, 0xAFC4, 0x8546, 0xAFC5, 0x8547, 0xAFC6, 0x8548, 0xAFCA, - 0x8549, 0xAFCC, 0x854A, 0xAFCF, 0x854B, 0xAFD0, 0x854C, 0xAFD1, 0x854D, 0xAFD2, 0x854E, 0xAFD3, 0x854F, 0xAFD5, 0x8550, 0xAFD6, - 0x8551, 0xAFD7, 0x8552, 0xAFD8, 0x8553, 0xAFD9, 0x8554, 0xAFDA, 0x8555, 0xAFDB, 0x8556, 0xAFDD, 0x8557, 0xAFDE, 0x8558, 0xAFDF, - 0x8559, 0xAFE0, 0x855A, 0xAFE1, 0x8561, 0xAFE2, 0x8562, 0xAFE3, 0x8563, 0xAFE4, 0x8564, 0xAFE5, 0x8565, 0xAFE6, 0x8566, 0xAFE7, - 0x8567, 0xAFEA, 0x8568, 0xAFEB, 0x8569, 0xAFEC, 0x856A, 0xAFED, 0x856B, 0xAFEE, 0x856C, 0xAFEF, 0x856D, 0xAFF2, 0x856E, 0xAFF3, - 0x856F, 0xAFF5, 0x8570, 0xAFF6, 0x8571, 0xAFF7, 0x8572, 0xAFF9, 0x8573, 0xAFFA, 0x8574, 0xAFFB, 0x8575, 0xAFFC, 0x8576, 0xAFFD, - 0x8577, 0xAFFE, 0x8578, 0xAFFF, 0x8579, 0xB002, 0x857A, 0xB003, 0x8581, 0xB005, 0x8582, 0xB006, 0x8583, 0xB007, 0x8584, 0xB008, - 0x8585, 0xB009, 0x8586, 0xB00A, 0x8587, 0xB00B, 0x8588, 0xB00D, 0x8589, 0xB00E, 0x858A, 0xB00F, 0x858B, 0xB011, 0x858C, 0xB012, - 0x858D, 0xB013, 0x858E, 0xB015, 0x858F, 0xB016, 0x8590, 0xB017, 0x8591, 0xB018, 0x8592, 0xB019, 0x8593, 0xB01A, 0x8594, 0xB01B, - 0x8595, 0xB01E, 0x8596, 0xB01F, 0x8597, 0xB020, 0x8598, 0xB021, 0x8599, 0xB022, 0x859A, 0xB023, 0x859B, 0xB024, 0x859C, 0xB025, - 0x859D, 0xB026, 0x859E, 0xB027, 0x859F, 0xB029, 0x85A0, 0xB02A, 0x85A1, 0xB02B, 0x85A2, 0xB02C, 0x85A3, 0xB02D, 0x85A4, 0xB02E, - 0x85A5, 0xB02F, 0x85A6, 0xB030, 0x85A7, 0xB031, 0x85A8, 0xB032, 0x85A9, 0xB033, 0x85AA, 0xB034, 0x85AB, 0xB035, 0x85AC, 0xB036, - 0x85AD, 0xB037, 0x85AE, 0xB038, 0x85AF, 0xB039, 0x85B0, 0xB03A, 0x85B1, 0xB03B, 0x85B2, 0xB03C, 0x85B3, 0xB03D, 0x85B4, 0xB03E, - 0x85B5, 0xB03F, 0x85B6, 0xB040, 0x85B7, 0xB041, 0x85B8, 0xB042, 0x85B9, 0xB043, 0x85BA, 0xB046, 0x85BB, 0xB047, 0x85BC, 0xB049, - 0x85BD, 0xB04B, 0x85BE, 0xB04D, 0x85BF, 0xB04F, 0x85C0, 0xB050, 0x85C1, 0xB051, 0x85C2, 0xB052, 0x85C3, 0xB056, 0x85C4, 0xB058, - 0x85C5, 0xB05A, 0x85C6, 0xB05B, 0x85C7, 0xB05C, 0x85C8, 0xB05E, 0x85C9, 0xB05F, 0x85CA, 0xB060, 0x85CB, 0xB061, 0x85CC, 0xB062, - 0x85CD, 0xB063, 0x85CE, 0xB064, 0x85CF, 0xB065, 0x85D0, 0xB066, 0x85D1, 0xB067, 0x85D2, 0xB068, 0x85D3, 0xB069, 0x85D4, 0xB06A, - 0x85D5, 0xB06B, 0x85D6, 0xB06C, 0x85D7, 0xB06D, 0x85D8, 0xB06E, 0x85D9, 0xB06F, 0x85DA, 0xB070, 0x85DB, 0xB071, 0x85DC, 0xB072, - 0x85DD, 0xB073, 0x85DE, 0xB074, 0x85DF, 0xB075, 0x85E0, 0xB076, 0x85E1, 0xB077, 0x85E2, 0xB078, 0x85E3, 0xB079, 0x85E4, 0xB07A, - 0x85E5, 0xB07B, 0x85E6, 0xB07E, 0x85E7, 0xB07F, 0x85E8, 0xB081, 0x85E9, 0xB082, 0x85EA, 0xB083, 0x85EB, 0xB085, 0x85EC, 0xB086, - 0x85ED, 0xB087, 0x85EE, 0xB088, 0x85EF, 0xB089, 0x85F0, 0xB08A, 0x85F1, 0xB08B, 0x85F2, 0xB08E, 0x85F3, 0xB090, 0x85F4, 0xB092, - 0x85F5, 0xB093, 0x85F6, 0xB094, 0x85F7, 0xB095, 0x85F8, 0xB096, 0x85F9, 0xB097, 0x85FA, 0xB09B, 0x85FB, 0xB09D, 0x85FC, 0xB09E, - 0x85FD, 0xB0A3, 0x85FE, 0xB0A4, 0x8641, 0xB0A5, 0x8642, 0xB0A6, 0x8643, 0xB0A7, 0x8644, 0xB0AA, 0x8645, 0xB0B0, 0x8646, 0xB0B2, - 0x8647, 0xB0B6, 0x8648, 0xB0B7, 0x8649, 0xB0B9, 0x864A, 0xB0BA, 0x864B, 0xB0BB, 0x864C, 0xB0BD, 0x864D, 0xB0BE, 0x864E, 0xB0BF, - 0x864F, 0xB0C0, 0x8650, 0xB0C1, 0x8651, 0xB0C2, 0x8652, 0xB0C3, 0x8653, 0xB0C6, 0x8654, 0xB0CA, 0x8655, 0xB0CB, 0x8656, 0xB0CC, - 0x8657, 0xB0CD, 0x8658, 0xB0CE, 0x8659, 0xB0CF, 0x865A, 0xB0D2, 0x8661, 0xB0D3, 0x8662, 0xB0D5, 0x8663, 0xB0D6, 0x8664, 0xB0D7, - 0x8665, 0xB0D9, 0x8666, 0xB0DA, 0x8667, 0xB0DB, 0x8668, 0xB0DC, 0x8669, 0xB0DD, 0x866A, 0xB0DE, 0x866B, 0xB0DF, 0x866C, 0xB0E1, - 0x866D, 0xB0E2, 0x866E, 0xB0E3, 0x866F, 0xB0E4, 0x8670, 0xB0E6, 0x8671, 0xB0E7, 0x8672, 0xB0E8, 0x8673, 0xB0E9, 0x8674, 0xB0EA, - 0x8675, 0xB0EB, 0x8676, 0xB0EC, 0x8677, 0xB0ED, 0x8678, 0xB0EE, 0x8679, 0xB0EF, 0x867A, 0xB0F0, 0x8681, 0xB0F1, 0x8682, 0xB0F2, - 0x8683, 0xB0F3, 0x8684, 0xB0F4, 0x8685, 0xB0F5, 0x8686, 0xB0F6, 0x8687, 0xB0F7, 0x8688, 0xB0F8, 0x8689, 0xB0F9, 0x868A, 0xB0FA, - 0x868B, 0xB0FB, 0x868C, 0xB0FC, 0x868D, 0xB0FD, 0x868E, 0xB0FE, 0x868F, 0xB0FF, 0x8690, 0xB100, 0x8691, 0xB101, 0x8692, 0xB102, - 0x8693, 0xB103, 0x8694, 0xB104, 0x8695, 0xB105, 0x8696, 0xB106, 0x8697, 0xB107, 0x8698, 0xB10A, 0x8699, 0xB10D, 0x869A, 0xB10E, - 0x869B, 0xB10F, 0x869C, 0xB111, 0x869D, 0xB114, 0x869E, 0xB115, 0x869F, 0xB116, 0x86A0, 0xB117, 0x86A1, 0xB11A, 0x86A2, 0xB11E, - 0x86A3, 0xB11F, 0x86A4, 0xB120, 0x86A5, 0xB121, 0x86A6, 0xB122, 0x86A7, 0xB126, 0x86A8, 0xB127, 0x86A9, 0xB129, 0x86AA, 0xB12A, - 0x86AB, 0xB12B, 0x86AC, 0xB12D, 0x86AD, 0xB12E, 0x86AE, 0xB12F, 0x86AF, 0xB130, 0x86B0, 0xB131, 0x86B1, 0xB132, 0x86B2, 0xB133, - 0x86B3, 0xB136, 0x86B4, 0xB13A, 0x86B5, 0xB13B, 0x86B6, 0xB13C, 0x86B7, 0xB13D, 0x86B8, 0xB13E, 0x86B9, 0xB13F, 0x86BA, 0xB142, - 0x86BB, 0xB143, 0x86BC, 0xB145, 0x86BD, 0xB146, 0x86BE, 0xB147, 0x86BF, 0xB149, 0x86C0, 0xB14A, 0x86C1, 0xB14B, 0x86C2, 0xB14C, - 0x86C3, 0xB14D, 0x86C4, 0xB14E, 0x86C5, 0xB14F, 0x86C6, 0xB152, 0x86C7, 0xB153, 0x86C8, 0xB156, 0x86C9, 0xB157, 0x86CA, 0xB159, - 0x86CB, 0xB15A, 0x86CC, 0xB15B, 0x86CD, 0xB15D, 0x86CE, 0xB15E, 0x86CF, 0xB15F, 0x86D0, 0xB161, 0x86D1, 0xB162, 0x86D2, 0xB163, - 0x86D3, 0xB164, 0x86D4, 0xB165, 0x86D5, 0xB166, 0x86D6, 0xB167, 0x86D7, 0xB168, 0x86D8, 0xB169, 0x86D9, 0xB16A, 0x86DA, 0xB16B, - 0x86DB, 0xB16C, 0x86DC, 0xB16D, 0x86DD, 0xB16E, 0x86DE, 0xB16F, 0x86DF, 0xB170, 0x86E0, 0xB171, 0x86E1, 0xB172, 0x86E2, 0xB173, - 0x86E3, 0xB174, 0x86E4, 0xB175, 0x86E5, 0xB176, 0x86E6, 0xB177, 0x86E7, 0xB17A, 0x86E8, 0xB17B, 0x86E9, 0xB17D, 0x86EA, 0xB17E, - 0x86EB, 0xB17F, 0x86EC, 0xB181, 0x86ED, 0xB183, 0x86EE, 0xB184, 0x86EF, 0xB185, 0x86F0, 0xB186, 0x86F1, 0xB187, 0x86F2, 0xB18A, - 0x86F3, 0xB18C, 0x86F4, 0xB18E, 0x86F5, 0xB18F, 0x86F6, 0xB190, 0x86F7, 0xB191, 0x86F8, 0xB195, 0x86F9, 0xB196, 0x86FA, 0xB197, - 0x86FB, 0xB199, 0x86FC, 0xB19A, 0x86FD, 0xB19B, 0x86FE, 0xB19D, 0x8741, 0xB19E, 0x8742, 0xB19F, 0x8743, 0xB1A0, 0x8744, 0xB1A1, - 0x8745, 0xB1A2, 0x8746, 0xB1A3, 0x8747, 0xB1A4, 0x8748, 0xB1A5, 0x8749, 0xB1A6, 0x874A, 0xB1A7, 0x874B, 0xB1A9, 0x874C, 0xB1AA, - 0x874D, 0xB1AB, 0x874E, 0xB1AC, 0x874F, 0xB1AD, 0x8750, 0xB1AE, 0x8751, 0xB1AF, 0x8752, 0xB1B0, 0x8753, 0xB1B1, 0x8754, 0xB1B2, - 0x8755, 0xB1B3, 0x8756, 0xB1B4, 0x8757, 0xB1B5, 0x8758, 0xB1B6, 0x8759, 0xB1B7, 0x875A, 0xB1B8, 0x8761, 0xB1B9, 0x8762, 0xB1BA, - 0x8763, 0xB1BB, 0x8764, 0xB1BC, 0x8765, 0xB1BD, 0x8766, 0xB1BE, 0x8767, 0xB1BF, 0x8768, 0xB1C0, 0x8769, 0xB1C1, 0x876A, 0xB1C2, - 0x876B, 0xB1C3, 0x876C, 0xB1C4, 0x876D, 0xB1C5, 0x876E, 0xB1C6, 0x876F, 0xB1C7, 0x8770, 0xB1C8, 0x8771, 0xB1C9, 0x8772, 0xB1CA, - 0x8773, 0xB1CB, 0x8774, 0xB1CD, 0x8775, 0xB1CE, 0x8776, 0xB1CF, 0x8777, 0xB1D1, 0x8778, 0xB1D2, 0x8779, 0xB1D3, 0x877A, 0xB1D5, - 0x8781, 0xB1D6, 0x8782, 0xB1D7, 0x8783, 0xB1D8, 0x8784, 0xB1D9, 0x8785, 0xB1DA, 0x8786, 0xB1DB, 0x8787, 0xB1DE, 0x8788, 0xB1E0, - 0x8789, 0xB1E1, 0x878A, 0xB1E2, 0x878B, 0xB1E3, 0x878C, 0xB1E4, 0x878D, 0xB1E5, 0x878E, 0xB1E6, 0x878F, 0xB1E7, 0x8790, 0xB1EA, - 0x8791, 0xB1EB, 0x8792, 0xB1ED, 0x8793, 0xB1EE, 0x8794, 0xB1EF, 0x8795, 0xB1F1, 0x8796, 0xB1F2, 0x8797, 0xB1F3, 0x8798, 0xB1F4, - 0x8799, 0xB1F5, 0x879A, 0xB1F6, 0x879B, 0xB1F7, 0x879C, 0xB1F8, 0x879D, 0xB1FA, 0x879E, 0xB1FC, 0x879F, 0xB1FE, 0x87A0, 0xB1FF, - 0x87A1, 0xB200, 0x87A2, 0xB201, 0x87A3, 0xB202, 0x87A4, 0xB203, 0x87A5, 0xB206, 0x87A6, 0xB207, 0x87A7, 0xB209, 0x87A8, 0xB20A, - 0x87A9, 0xB20D, 0x87AA, 0xB20E, 0x87AB, 0xB20F, 0x87AC, 0xB210, 0x87AD, 0xB211, 0x87AE, 0xB212, 0x87AF, 0xB213, 0x87B0, 0xB216, - 0x87B1, 0xB218, 0x87B2, 0xB21A, 0x87B3, 0xB21B, 0x87B4, 0xB21C, 0x87B5, 0xB21D, 0x87B6, 0xB21E, 0x87B7, 0xB21F, 0x87B8, 0xB221, - 0x87B9, 0xB222, 0x87BA, 0xB223, 0x87BB, 0xB224, 0x87BC, 0xB225, 0x87BD, 0xB226, 0x87BE, 0xB227, 0x87BF, 0xB228, 0x87C0, 0xB229, - 0x87C1, 0xB22A, 0x87C2, 0xB22B, 0x87C3, 0xB22C, 0x87C4, 0xB22D, 0x87C5, 0xB22E, 0x87C6, 0xB22F, 0x87C7, 0xB230, 0x87C8, 0xB231, - 0x87C9, 0xB232, 0x87CA, 0xB233, 0x87CB, 0xB235, 0x87CC, 0xB236, 0x87CD, 0xB237, 0x87CE, 0xB238, 0x87CF, 0xB239, 0x87D0, 0xB23A, - 0x87D1, 0xB23B, 0x87D2, 0xB23D, 0x87D3, 0xB23E, 0x87D4, 0xB23F, 0x87D5, 0xB240, 0x87D6, 0xB241, 0x87D7, 0xB242, 0x87D8, 0xB243, - 0x87D9, 0xB244, 0x87DA, 0xB245, 0x87DB, 0xB246, 0x87DC, 0xB247, 0x87DD, 0xB248, 0x87DE, 0xB249, 0x87DF, 0xB24A, 0x87E0, 0xB24B, - 0x87E1, 0xB24C, 0x87E2, 0xB24D, 0x87E3, 0xB24E, 0x87E4, 0xB24F, 0x87E5, 0xB250, 0x87E6, 0xB251, 0x87E7, 0xB252, 0x87E8, 0xB253, - 0x87E9, 0xB254, 0x87EA, 0xB255, 0x87EB, 0xB256, 0x87EC, 0xB257, 0x87ED, 0xB259, 0x87EE, 0xB25A, 0x87EF, 0xB25B, 0x87F0, 0xB25D, - 0x87F1, 0xB25E, 0x87F2, 0xB25F, 0x87F3, 0xB261, 0x87F4, 0xB262, 0x87F5, 0xB263, 0x87F6, 0xB264, 0x87F7, 0xB265, 0x87F8, 0xB266, - 0x87F9, 0xB267, 0x87FA, 0xB26A, 0x87FB, 0xB26B, 0x87FC, 0xB26C, 0x87FD, 0xB26D, 0x87FE, 0xB26E, 0x8841, 0xB26F, 0x8842, 0xB270, - 0x8843, 0xB271, 0x8844, 0xB272, 0x8845, 0xB273, 0x8846, 0xB276, 0x8847, 0xB277, 0x8848, 0xB278, 0x8849, 0xB279, 0x884A, 0xB27A, - 0x884B, 0xB27B, 0x884C, 0xB27D, 0x884D, 0xB27E, 0x884E, 0xB27F, 0x884F, 0xB280, 0x8850, 0xB281, 0x8851, 0xB282, 0x8852, 0xB283, - 0x8853, 0xB286, 0x8854, 0xB287, 0x8855, 0xB288, 0x8856, 0xB28A, 0x8857, 0xB28B, 0x8858, 0xB28C, 0x8859, 0xB28D, 0x885A, 0xB28E, - 0x8861, 0xB28F, 0x8862, 0xB292, 0x8863, 0xB293, 0x8864, 0xB295, 0x8865, 0xB296, 0x8866, 0xB297, 0x8867, 0xB29B, 0x8868, 0xB29C, - 0x8869, 0xB29D, 0x886A, 0xB29E, 0x886B, 0xB29F, 0x886C, 0xB2A2, 0x886D, 0xB2A4, 0x886E, 0xB2A7, 0x886F, 0xB2A8, 0x8870, 0xB2A9, - 0x8871, 0xB2AB, 0x8872, 0xB2AD, 0x8873, 0xB2AE, 0x8874, 0xB2AF, 0x8875, 0xB2B1, 0x8876, 0xB2B2, 0x8877, 0xB2B3, 0x8878, 0xB2B5, - 0x8879, 0xB2B6, 0x887A, 0xB2B7, 0x8881, 0xB2B8, 0x8882, 0xB2B9, 0x8883, 0xB2BA, 0x8884, 0xB2BB, 0x8885, 0xB2BC, 0x8886, 0xB2BD, - 0x8887, 0xB2BE, 0x8888, 0xB2BF, 0x8889, 0xB2C0, 0x888A, 0xB2C1, 0x888B, 0xB2C2, 0x888C, 0xB2C3, 0x888D, 0xB2C4, 0x888E, 0xB2C5, - 0x888F, 0xB2C6, 0x8890, 0xB2C7, 0x8891, 0xB2CA, 0x8892, 0xB2CB, 0x8893, 0xB2CD, 0x8894, 0xB2CE, 0x8895, 0xB2CF, 0x8896, 0xB2D1, - 0x8897, 0xB2D3, 0x8898, 0xB2D4, 0x8899, 0xB2D5, 0x889A, 0xB2D6, 0x889B, 0xB2D7, 0x889C, 0xB2DA, 0x889D, 0xB2DC, 0x889E, 0xB2DE, - 0x889F, 0xB2DF, 0x88A0, 0xB2E0, 0x88A1, 0xB2E1, 0x88A2, 0xB2E3, 0x88A3, 0xB2E7, 0x88A4, 0xB2E9, 0x88A5, 0xB2EA, 0x88A6, 0xB2F0, - 0x88A7, 0xB2F1, 0x88A8, 0xB2F2, 0x88A9, 0xB2F6, 0x88AA, 0xB2FC, 0x88AB, 0xB2FD, 0x88AC, 0xB2FE, 0x88AD, 0xB302, 0x88AE, 0xB303, - 0x88AF, 0xB305, 0x88B0, 0xB306, 0x88B1, 0xB307, 0x88B2, 0xB309, 0x88B3, 0xB30A, 0x88B4, 0xB30B, 0x88B5, 0xB30C, 0x88B6, 0xB30D, - 0x88B7, 0xB30E, 0x88B8, 0xB30F, 0x88B9, 0xB312, 0x88BA, 0xB316, 0x88BB, 0xB317, 0x88BC, 0xB318, 0x88BD, 0xB319, 0x88BE, 0xB31A, - 0x88BF, 0xB31B, 0x88C0, 0xB31D, 0x88C1, 0xB31E, 0x88C2, 0xB31F, 0x88C3, 0xB320, 0x88C4, 0xB321, 0x88C5, 0xB322, 0x88C6, 0xB323, - 0x88C7, 0xB324, 0x88C8, 0xB325, 0x88C9, 0xB326, 0x88CA, 0xB327, 0x88CB, 0xB328, 0x88CC, 0xB329, 0x88CD, 0xB32A, 0x88CE, 0xB32B, - 0x88CF, 0xB32C, 0x88D0, 0xB32D, 0x88D1, 0xB32E, 0x88D2, 0xB32F, 0x88D3, 0xB330, 0x88D4, 0xB331, 0x88D5, 0xB332, 0x88D6, 0xB333, - 0x88D7, 0xB334, 0x88D8, 0xB335, 0x88D9, 0xB336, 0x88DA, 0xB337, 0x88DB, 0xB338, 0x88DC, 0xB339, 0x88DD, 0xB33A, 0x88DE, 0xB33B, - 0x88DF, 0xB33C, 0x88E0, 0xB33D, 0x88E1, 0xB33E, 0x88E2, 0xB33F, 0x88E3, 0xB340, 0x88E4, 0xB341, 0x88E5, 0xB342, 0x88E6, 0xB343, - 0x88E7, 0xB344, 0x88E8, 0xB345, 0x88E9, 0xB346, 0x88EA, 0xB347, 0x88EB, 0xB348, 0x88EC, 0xB349, 0x88ED, 0xB34A, 0x88EE, 0xB34B, - 0x88EF, 0xB34C, 0x88F0, 0xB34D, 0x88F1, 0xB34E, 0x88F2, 0xB34F, 0x88F3, 0xB350, 0x88F4, 0xB351, 0x88F5, 0xB352, 0x88F6, 0xB353, - 0x88F7, 0xB357, 0x88F8, 0xB359, 0x88F9, 0xB35A, 0x88FA, 0xB35D, 0x88FB, 0xB360, 0x88FC, 0xB361, 0x88FD, 0xB362, 0x88FE, 0xB363, - 0x8941, 0xB366, 0x8942, 0xB368, 0x8943, 0xB36A, 0x8944, 0xB36C, 0x8945, 0xB36D, 0x8946, 0xB36F, 0x8947, 0xB372, 0x8948, 0xB373, - 0x8949, 0xB375, 0x894A, 0xB376, 0x894B, 0xB377, 0x894C, 0xB379, 0x894D, 0xB37A, 0x894E, 0xB37B, 0x894F, 0xB37C, 0x8950, 0xB37D, - 0x8951, 0xB37E, 0x8952, 0xB37F, 0x8953, 0xB382, 0x8954, 0xB386, 0x8955, 0xB387, 0x8956, 0xB388, 0x8957, 0xB389, 0x8958, 0xB38A, - 0x8959, 0xB38B, 0x895A, 0xB38D, 0x8961, 0xB38E, 0x8962, 0xB38F, 0x8963, 0xB391, 0x8964, 0xB392, 0x8965, 0xB393, 0x8966, 0xB395, - 0x8967, 0xB396, 0x8968, 0xB397, 0x8969, 0xB398, 0x896A, 0xB399, 0x896B, 0xB39A, 0x896C, 0xB39B, 0x896D, 0xB39C, 0x896E, 0xB39D, - 0x896F, 0xB39E, 0x8970, 0xB39F, 0x8971, 0xB3A2, 0x8972, 0xB3A3, 0x8973, 0xB3A4, 0x8974, 0xB3A5, 0x8975, 0xB3A6, 0x8976, 0xB3A7, - 0x8977, 0xB3A9, 0x8978, 0xB3AA, 0x8979, 0xB3AB, 0x897A, 0xB3AD, 0x8981, 0xB3AE, 0x8982, 0xB3AF, 0x8983, 0xB3B0, 0x8984, 0xB3B1, - 0x8985, 0xB3B2, 0x8986, 0xB3B3, 0x8987, 0xB3B4, 0x8988, 0xB3B5, 0x8989, 0xB3B6, 0x898A, 0xB3B7, 0x898B, 0xB3B8, 0x898C, 0xB3B9, - 0x898D, 0xB3BA, 0x898E, 0xB3BB, 0x898F, 0xB3BC, 0x8990, 0xB3BD, 0x8991, 0xB3BE, 0x8992, 0xB3BF, 0x8993, 0xB3C0, 0x8994, 0xB3C1, - 0x8995, 0xB3C2, 0x8996, 0xB3C3, 0x8997, 0xB3C6, 0x8998, 0xB3C7, 0x8999, 0xB3C9, 0x899A, 0xB3CA, 0x899B, 0xB3CD, 0x899C, 0xB3CF, - 0x899D, 0xB3D1, 0x899E, 0xB3D2, 0x899F, 0xB3D3, 0x89A0, 0xB3D6, 0x89A1, 0xB3D8, 0x89A2, 0xB3DA, 0x89A3, 0xB3DC, 0x89A4, 0xB3DE, - 0x89A5, 0xB3DF, 0x89A6, 0xB3E1, 0x89A7, 0xB3E2, 0x89A8, 0xB3E3, 0x89A9, 0xB3E5, 0x89AA, 0xB3E6, 0x89AB, 0xB3E7, 0x89AC, 0xB3E9, - 0x89AD, 0xB3EA, 0x89AE, 0xB3EB, 0x89AF, 0xB3EC, 0x89B0, 0xB3ED, 0x89B1, 0xB3EE, 0x89B2, 0xB3EF, 0x89B3, 0xB3F0, 0x89B4, 0xB3F1, - 0x89B5, 0xB3F2, 0x89B6, 0xB3F3, 0x89B7, 0xB3F4, 0x89B8, 0xB3F5, 0x89B9, 0xB3F6, 0x89BA, 0xB3F7, 0x89BB, 0xB3F8, 0x89BC, 0xB3F9, - 0x89BD, 0xB3FA, 0x89BE, 0xB3FB, 0x89BF, 0xB3FD, 0x89C0, 0xB3FE, 0x89C1, 0xB3FF, 0x89C2, 0xB400, 0x89C3, 0xB401, 0x89C4, 0xB402, - 0x89C5, 0xB403, 0x89C6, 0xB404, 0x89C7, 0xB405, 0x89C8, 0xB406, 0x89C9, 0xB407, 0x89CA, 0xB408, 0x89CB, 0xB409, 0x89CC, 0xB40A, - 0x89CD, 0xB40B, 0x89CE, 0xB40C, 0x89CF, 0xB40D, 0x89D0, 0xB40E, 0x89D1, 0xB40F, 0x89D2, 0xB411, 0x89D3, 0xB412, 0x89D4, 0xB413, - 0x89D5, 0xB414, 0x89D6, 0xB415, 0x89D7, 0xB416, 0x89D8, 0xB417, 0x89D9, 0xB419, 0x89DA, 0xB41A, 0x89DB, 0xB41B, 0x89DC, 0xB41D, - 0x89DD, 0xB41E, 0x89DE, 0xB41F, 0x89DF, 0xB421, 0x89E0, 0xB422, 0x89E1, 0xB423, 0x89E2, 0xB424, 0x89E3, 0xB425, 0x89E4, 0xB426, - 0x89E5, 0xB427, 0x89E6, 0xB42A, 0x89E7, 0xB42C, 0x89E8, 0xB42D, 0x89E9, 0xB42E, 0x89EA, 0xB42F, 0x89EB, 0xB430, 0x89EC, 0xB431, - 0x89ED, 0xB432, 0x89EE, 0xB433, 0x89EF, 0xB435, 0x89F0, 0xB436, 0x89F1, 0xB437, 0x89F2, 0xB438, 0x89F3, 0xB439, 0x89F4, 0xB43A, - 0x89F5, 0xB43B, 0x89F6, 0xB43C, 0x89F7, 0xB43D, 0x89F8, 0xB43E, 0x89F9, 0xB43F, 0x89FA, 0xB440, 0x89FB, 0xB441, 0x89FC, 0xB442, - 0x89FD, 0xB443, 0x89FE, 0xB444, 0x8A41, 0xB445, 0x8A42, 0xB446, 0x8A43, 0xB447, 0x8A44, 0xB448, 0x8A45, 0xB449, 0x8A46, 0xB44A, - 0x8A47, 0xB44B, 0x8A48, 0xB44C, 0x8A49, 0xB44D, 0x8A4A, 0xB44E, 0x8A4B, 0xB44F, 0x8A4C, 0xB452, 0x8A4D, 0xB453, 0x8A4E, 0xB455, - 0x8A4F, 0xB456, 0x8A50, 0xB457, 0x8A51, 0xB459, 0x8A52, 0xB45A, 0x8A53, 0xB45B, 0x8A54, 0xB45C, 0x8A55, 0xB45D, 0x8A56, 0xB45E, - 0x8A57, 0xB45F, 0x8A58, 0xB462, 0x8A59, 0xB464, 0x8A5A, 0xB466, 0x8A61, 0xB467, 0x8A62, 0xB468, 0x8A63, 0xB469, 0x8A64, 0xB46A, - 0x8A65, 0xB46B, 0x8A66, 0xB46D, 0x8A67, 0xB46E, 0x8A68, 0xB46F, 0x8A69, 0xB470, 0x8A6A, 0xB471, 0x8A6B, 0xB472, 0x8A6C, 0xB473, - 0x8A6D, 0xB474, 0x8A6E, 0xB475, 0x8A6F, 0xB476, 0x8A70, 0xB477, 0x8A71, 0xB478, 0x8A72, 0xB479, 0x8A73, 0xB47A, 0x8A74, 0xB47B, - 0x8A75, 0xB47C, 0x8A76, 0xB47D, 0x8A77, 0xB47E, 0x8A78, 0xB47F, 0x8A79, 0xB481, 0x8A7A, 0xB482, 0x8A81, 0xB483, 0x8A82, 0xB484, - 0x8A83, 0xB485, 0x8A84, 0xB486, 0x8A85, 0xB487, 0x8A86, 0xB489, 0x8A87, 0xB48A, 0x8A88, 0xB48B, 0x8A89, 0xB48C, 0x8A8A, 0xB48D, - 0x8A8B, 0xB48E, 0x8A8C, 0xB48F, 0x8A8D, 0xB490, 0x8A8E, 0xB491, 0x8A8F, 0xB492, 0x8A90, 0xB493, 0x8A91, 0xB494, 0x8A92, 0xB495, - 0x8A93, 0xB496, 0x8A94, 0xB497, 0x8A95, 0xB498, 0x8A96, 0xB499, 0x8A97, 0xB49A, 0x8A98, 0xB49B, 0x8A99, 0xB49C, 0x8A9A, 0xB49E, - 0x8A9B, 0xB49F, 0x8A9C, 0xB4A0, 0x8A9D, 0xB4A1, 0x8A9E, 0xB4A2, 0x8A9F, 0xB4A3, 0x8AA0, 0xB4A5, 0x8AA1, 0xB4A6, 0x8AA2, 0xB4A7, - 0x8AA3, 0xB4A9, 0x8AA4, 0xB4AA, 0x8AA5, 0xB4AB, 0x8AA6, 0xB4AD, 0x8AA7, 0xB4AE, 0x8AA8, 0xB4AF, 0x8AA9, 0xB4B0, 0x8AAA, 0xB4B1, - 0x8AAB, 0xB4B2, 0x8AAC, 0xB4B3, 0x8AAD, 0xB4B4, 0x8AAE, 0xB4B6, 0x8AAF, 0xB4B8, 0x8AB0, 0xB4BA, 0x8AB1, 0xB4BB, 0x8AB2, 0xB4BC, - 0x8AB3, 0xB4BD, 0x8AB4, 0xB4BE, 0x8AB5, 0xB4BF, 0x8AB6, 0xB4C1, 0x8AB7, 0xB4C2, 0x8AB8, 0xB4C3, 0x8AB9, 0xB4C5, 0x8ABA, 0xB4C6, - 0x8ABB, 0xB4C7, 0x8ABC, 0xB4C9, 0x8ABD, 0xB4CA, 0x8ABE, 0xB4CB, 0x8ABF, 0xB4CC, 0x8AC0, 0xB4CD, 0x8AC1, 0xB4CE, 0x8AC2, 0xB4CF, - 0x8AC3, 0xB4D1, 0x8AC4, 0xB4D2, 0x8AC5, 0xB4D3, 0x8AC6, 0xB4D4, 0x8AC7, 0xB4D6, 0x8AC8, 0xB4D7, 0x8AC9, 0xB4D8, 0x8ACA, 0xB4D9, - 0x8ACB, 0xB4DA, 0x8ACC, 0xB4DB, 0x8ACD, 0xB4DE, 0x8ACE, 0xB4DF, 0x8ACF, 0xB4E1, 0x8AD0, 0xB4E2, 0x8AD1, 0xB4E5, 0x8AD2, 0xB4E7, - 0x8AD3, 0xB4E8, 0x8AD4, 0xB4E9, 0x8AD5, 0xB4EA, 0x8AD6, 0xB4EB, 0x8AD7, 0xB4EE, 0x8AD8, 0xB4F0, 0x8AD9, 0xB4F2, 0x8ADA, 0xB4F3, - 0x8ADB, 0xB4F4, 0x8ADC, 0xB4F5, 0x8ADD, 0xB4F6, 0x8ADE, 0xB4F7, 0x8ADF, 0xB4F9, 0x8AE0, 0xB4FA, 0x8AE1, 0xB4FB, 0x8AE2, 0xB4FC, - 0x8AE3, 0xB4FD, 0x8AE4, 0xB4FE, 0x8AE5, 0xB4FF, 0x8AE6, 0xB500, 0x8AE7, 0xB501, 0x8AE8, 0xB502, 0x8AE9, 0xB503, 0x8AEA, 0xB504, - 0x8AEB, 0xB505, 0x8AEC, 0xB506, 0x8AED, 0xB507, 0x8AEE, 0xB508, 0x8AEF, 0xB509, 0x8AF0, 0xB50A, 0x8AF1, 0xB50B, 0x8AF2, 0xB50C, - 0x8AF3, 0xB50D, 0x8AF4, 0xB50E, 0x8AF5, 0xB50F, 0x8AF6, 0xB510, 0x8AF7, 0xB511, 0x8AF8, 0xB512, 0x8AF9, 0xB513, 0x8AFA, 0xB516, - 0x8AFB, 0xB517, 0x8AFC, 0xB519, 0x8AFD, 0xB51A, 0x8AFE, 0xB51D, 0x8B41, 0xB51E, 0x8B42, 0xB51F, 0x8B43, 0xB520, 0x8B44, 0xB521, - 0x8B45, 0xB522, 0x8B46, 0xB523, 0x8B47, 0xB526, 0x8B48, 0xB52B, 0x8B49, 0xB52C, 0x8B4A, 0xB52D, 0x8B4B, 0xB52E, 0x8B4C, 0xB52F, - 0x8B4D, 0xB532, 0x8B4E, 0xB533, 0x8B4F, 0xB535, 0x8B50, 0xB536, 0x8B51, 0xB537, 0x8B52, 0xB539, 0x8B53, 0xB53A, 0x8B54, 0xB53B, - 0x8B55, 0xB53C, 0x8B56, 0xB53D, 0x8B57, 0xB53E, 0x8B58, 0xB53F, 0x8B59, 0xB542, 0x8B5A, 0xB546, 0x8B61, 0xB547, 0x8B62, 0xB548, - 0x8B63, 0xB549, 0x8B64, 0xB54A, 0x8B65, 0xB54E, 0x8B66, 0xB54F, 0x8B67, 0xB551, 0x8B68, 0xB552, 0x8B69, 0xB553, 0x8B6A, 0xB555, - 0x8B6B, 0xB556, 0x8B6C, 0xB557, 0x8B6D, 0xB558, 0x8B6E, 0xB559, 0x8B6F, 0xB55A, 0x8B70, 0xB55B, 0x8B71, 0xB55E, 0x8B72, 0xB562, - 0x8B73, 0xB563, 0x8B74, 0xB564, 0x8B75, 0xB565, 0x8B76, 0xB566, 0x8B77, 0xB567, 0x8B78, 0xB568, 0x8B79, 0xB569, 0x8B7A, 0xB56A, - 0x8B81, 0xB56B, 0x8B82, 0xB56C, 0x8B83, 0xB56D, 0x8B84, 0xB56E, 0x8B85, 0xB56F, 0x8B86, 0xB570, 0x8B87, 0xB571, 0x8B88, 0xB572, - 0x8B89, 0xB573, 0x8B8A, 0xB574, 0x8B8B, 0xB575, 0x8B8C, 0xB576, 0x8B8D, 0xB577, 0x8B8E, 0xB578, 0x8B8F, 0xB579, 0x8B90, 0xB57A, - 0x8B91, 0xB57B, 0x8B92, 0xB57C, 0x8B93, 0xB57D, 0x8B94, 0xB57E, 0x8B95, 0xB57F, 0x8B96, 0xB580, 0x8B97, 0xB581, 0x8B98, 0xB582, - 0x8B99, 0xB583, 0x8B9A, 0xB584, 0x8B9B, 0xB585, 0x8B9C, 0xB586, 0x8B9D, 0xB587, 0x8B9E, 0xB588, 0x8B9F, 0xB589, 0x8BA0, 0xB58A, - 0x8BA1, 0xB58B, 0x8BA2, 0xB58C, 0x8BA3, 0xB58D, 0x8BA4, 0xB58E, 0x8BA5, 0xB58F, 0x8BA6, 0xB590, 0x8BA7, 0xB591, 0x8BA8, 0xB592, - 0x8BA9, 0xB593, 0x8BAA, 0xB594, 0x8BAB, 0xB595, 0x8BAC, 0xB596, 0x8BAD, 0xB597, 0x8BAE, 0xB598, 0x8BAF, 0xB599, 0x8BB0, 0xB59A, - 0x8BB1, 0xB59B, 0x8BB2, 0xB59C, 0x8BB3, 0xB59D, 0x8BB4, 0xB59E, 0x8BB5, 0xB59F, 0x8BB6, 0xB5A2, 0x8BB7, 0xB5A3, 0x8BB8, 0xB5A5, - 0x8BB9, 0xB5A6, 0x8BBA, 0xB5A7, 0x8BBB, 0xB5A9, 0x8BBC, 0xB5AC, 0x8BBD, 0xB5AD, 0x8BBE, 0xB5AE, 0x8BBF, 0xB5AF, 0x8BC0, 0xB5B2, - 0x8BC1, 0xB5B6, 0x8BC2, 0xB5B7, 0x8BC3, 0xB5B8, 0x8BC4, 0xB5B9, 0x8BC5, 0xB5BA, 0x8BC6, 0xB5BE, 0x8BC7, 0xB5BF, 0x8BC8, 0xB5C1, - 0x8BC9, 0xB5C2, 0x8BCA, 0xB5C3, 0x8BCB, 0xB5C5, 0x8BCC, 0xB5C6, 0x8BCD, 0xB5C7, 0x8BCE, 0xB5C8, 0x8BCF, 0xB5C9, 0x8BD0, 0xB5CA, - 0x8BD1, 0xB5CB, 0x8BD2, 0xB5CE, 0x8BD3, 0xB5D2, 0x8BD4, 0xB5D3, 0x8BD5, 0xB5D4, 0x8BD6, 0xB5D5, 0x8BD7, 0xB5D6, 0x8BD8, 0xB5D7, - 0x8BD9, 0xB5D9, 0x8BDA, 0xB5DA, 0x8BDB, 0xB5DB, 0x8BDC, 0xB5DC, 0x8BDD, 0xB5DD, 0x8BDE, 0xB5DE, 0x8BDF, 0xB5DF, 0x8BE0, 0xB5E0, - 0x8BE1, 0xB5E1, 0x8BE2, 0xB5E2, 0x8BE3, 0xB5E3, 0x8BE4, 0xB5E4, 0x8BE5, 0xB5E5, 0x8BE6, 0xB5E6, 0x8BE7, 0xB5E7, 0x8BE8, 0xB5E8, - 0x8BE9, 0xB5E9, 0x8BEA, 0xB5EA, 0x8BEB, 0xB5EB, 0x8BEC, 0xB5ED, 0x8BED, 0xB5EE, 0x8BEE, 0xB5EF, 0x8BEF, 0xB5F0, 0x8BF0, 0xB5F1, - 0x8BF1, 0xB5F2, 0x8BF2, 0xB5F3, 0x8BF3, 0xB5F4, 0x8BF4, 0xB5F5, 0x8BF5, 0xB5F6, 0x8BF6, 0xB5F7, 0x8BF7, 0xB5F8, 0x8BF8, 0xB5F9, - 0x8BF9, 0xB5FA, 0x8BFA, 0xB5FB, 0x8BFB, 0xB5FC, 0x8BFC, 0xB5FD, 0x8BFD, 0xB5FE, 0x8BFE, 0xB5FF, 0x8C41, 0xB600, 0x8C42, 0xB601, - 0x8C43, 0xB602, 0x8C44, 0xB603, 0x8C45, 0xB604, 0x8C46, 0xB605, 0x8C47, 0xB606, 0x8C48, 0xB607, 0x8C49, 0xB608, 0x8C4A, 0xB609, - 0x8C4B, 0xB60A, 0x8C4C, 0xB60B, 0x8C4D, 0xB60C, 0x8C4E, 0xB60D, 0x8C4F, 0xB60E, 0x8C50, 0xB60F, 0x8C51, 0xB612, 0x8C52, 0xB613, - 0x8C53, 0xB615, 0x8C54, 0xB616, 0x8C55, 0xB617, 0x8C56, 0xB619, 0x8C57, 0xB61A, 0x8C58, 0xB61B, 0x8C59, 0xB61C, 0x8C5A, 0xB61D, - 0x8C61, 0xB61E, 0x8C62, 0xB61F, 0x8C63, 0xB620, 0x8C64, 0xB621, 0x8C65, 0xB622, 0x8C66, 0xB623, 0x8C67, 0xB624, 0x8C68, 0xB626, - 0x8C69, 0xB627, 0x8C6A, 0xB628, 0x8C6B, 0xB629, 0x8C6C, 0xB62A, 0x8C6D, 0xB62B, 0x8C6E, 0xB62D, 0x8C6F, 0xB62E, 0x8C70, 0xB62F, - 0x8C71, 0xB630, 0x8C72, 0xB631, 0x8C73, 0xB632, 0x8C74, 0xB633, 0x8C75, 0xB635, 0x8C76, 0xB636, 0x8C77, 0xB637, 0x8C78, 0xB638, - 0x8C79, 0xB639, 0x8C7A, 0xB63A, 0x8C81, 0xB63B, 0x8C82, 0xB63C, 0x8C83, 0xB63D, 0x8C84, 0xB63E, 0x8C85, 0xB63F, 0x8C86, 0xB640, - 0x8C87, 0xB641, 0x8C88, 0xB642, 0x8C89, 0xB643, 0x8C8A, 0xB644, 0x8C8B, 0xB645, 0x8C8C, 0xB646, 0x8C8D, 0xB647, 0x8C8E, 0xB649, - 0x8C8F, 0xB64A, 0x8C90, 0xB64B, 0x8C91, 0xB64C, 0x8C92, 0xB64D, 0x8C93, 0xB64E, 0x8C94, 0xB64F, 0x8C95, 0xB650, 0x8C96, 0xB651, - 0x8C97, 0xB652, 0x8C98, 0xB653, 0x8C99, 0xB654, 0x8C9A, 0xB655, 0x8C9B, 0xB656, 0x8C9C, 0xB657, 0x8C9D, 0xB658, 0x8C9E, 0xB659, - 0x8C9F, 0xB65A, 0x8CA0, 0xB65B, 0x8CA1, 0xB65C, 0x8CA2, 0xB65D, 0x8CA3, 0xB65E, 0x8CA4, 0xB65F, 0x8CA5, 0xB660, 0x8CA6, 0xB661, - 0x8CA7, 0xB662, 0x8CA8, 0xB663, 0x8CA9, 0xB665, 0x8CAA, 0xB666, 0x8CAB, 0xB667, 0x8CAC, 0xB669, 0x8CAD, 0xB66A, 0x8CAE, 0xB66B, - 0x8CAF, 0xB66C, 0x8CB0, 0xB66D, 0x8CB1, 0xB66E, 0x8CB2, 0xB66F, 0x8CB3, 0xB670, 0x8CB4, 0xB671, 0x8CB5, 0xB672, 0x8CB6, 0xB673, - 0x8CB7, 0xB674, 0x8CB8, 0xB675, 0x8CB9, 0xB676, 0x8CBA, 0xB677, 0x8CBB, 0xB678, 0x8CBC, 0xB679, 0x8CBD, 0xB67A, 0x8CBE, 0xB67B, - 0x8CBF, 0xB67C, 0x8CC0, 0xB67D, 0x8CC1, 0xB67E, 0x8CC2, 0xB67F, 0x8CC3, 0xB680, 0x8CC4, 0xB681, 0x8CC5, 0xB682, 0x8CC6, 0xB683, - 0x8CC7, 0xB684, 0x8CC8, 0xB685, 0x8CC9, 0xB686, 0x8CCA, 0xB687, 0x8CCB, 0xB688, 0x8CCC, 0xB689, 0x8CCD, 0xB68A, 0x8CCE, 0xB68B, - 0x8CCF, 0xB68C, 0x8CD0, 0xB68D, 0x8CD1, 0xB68E, 0x8CD2, 0xB68F, 0x8CD3, 0xB690, 0x8CD4, 0xB691, 0x8CD5, 0xB692, 0x8CD6, 0xB693, - 0x8CD7, 0xB694, 0x8CD8, 0xB695, 0x8CD9, 0xB696, 0x8CDA, 0xB697, 0x8CDB, 0xB698, 0x8CDC, 0xB699, 0x8CDD, 0xB69A, 0x8CDE, 0xB69B, - 0x8CDF, 0xB69E, 0x8CE0, 0xB69F, 0x8CE1, 0xB6A1, 0x8CE2, 0xB6A2, 0x8CE3, 0xB6A3, 0x8CE4, 0xB6A5, 0x8CE5, 0xB6A6, 0x8CE6, 0xB6A7, - 0x8CE7, 0xB6A8, 0x8CE8, 0xB6A9, 0x8CE9, 0xB6AA, 0x8CEA, 0xB6AD, 0x8CEB, 0xB6AE, 0x8CEC, 0xB6AF, 0x8CED, 0xB6B0, 0x8CEE, 0xB6B2, - 0x8CEF, 0xB6B3, 0x8CF0, 0xB6B4, 0x8CF1, 0xB6B5, 0x8CF2, 0xB6B6, 0x8CF3, 0xB6B7, 0x8CF4, 0xB6B8, 0x8CF5, 0xB6B9, 0x8CF6, 0xB6BA, - 0x8CF7, 0xB6BB, 0x8CF8, 0xB6BC, 0x8CF9, 0xB6BD, 0x8CFA, 0xB6BE, 0x8CFB, 0xB6BF, 0x8CFC, 0xB6C0, 0x8CFD, 0xB6C1, 0x8CFE, 0xB6C2, - 0x8D41, 0xB6C3, 0x8D42, 0xB6C4, 0x8D43, 0xB6C5, 0x8D44, 0xB6C6, 0x8D45, 0xB6C7, 0x8D46, 0xB6C8, 0x8D47, 0xB6C9, 0x8D48, 0xB6CA, - 0x8D49, 0xB6CB, 0x8D4A, 0xB6CC, 0x8D4B, 0xB6CD, 0x8D4C, 0xB6CE, 0x8D4D, 0xB6CF, 0x8D4E, 0xB6D0, 0x8D4F, 0xB6D1, 0x8D50, 0xB6D2, - 0x8D51, 0xB6D3, 0x8D52, 0xB6D5, 0x8D53, 0xB6D6, 0x8D54, 0xB6D7, 0x8D55, 0xB6D8, 0x8D56, 0xB6D9, 0x8D57, 0xB6DA, 0x8D58, 0xB6DB, - 0x8D59, 0xB6DC, 0x8D5A, 0xB6DD, 0x8D61, 0xB6DE, 0x8D62, 0xB6DF, 0x8D63, 0xB6E0, 0x8D64, 0xB6E1, 0x8D65, 0xB6E2, 0x8D66, 0xB6E3, - 0x8D67, 0xB6E4, 0x8D68, 0xB6E5, 0x8D69, 0xB6E6, 0x8D6A, 0xB6E7, 0x8D6B, 0xB6E8, 0x8D6C, 0xB6E9, 0x8D6D, 0xB6EA, 0x8D6E, 0xB6EB, - 0x8D6F, 0xB6EC, 0x8D70, 0xB6ED, 0x8D71, 0xB6EE, 0x8D72, 0xB6EF, 0x8D73, 0xB6F1, 0x8D74, 0xB6F2, 0x8D75, 0xB6F3, 0x8D76, 0xB6F5, - 0x8D77, 0xB6F6, 0x8D78, 0xB6F7, 0x8D79, 0xB6F9, 0x8D7A, 0xB6FA, 0x8D81, 0xB6FB, 0x8D82, 0xB6FC, 0x8D83, 0xB6FD, 0x8D84, 0xB6FE, - 0x8D85, 0xB6FF, 0x8D86, 0xB702, 0x8D87, 0xB703, 0x8D88, 0xB704, 0x8D89, 0xB706, 0x8D8A, 0xB707, 0x8D8B, 0xB708, 0x8D8C, 0xB709, - 0x8D8D, 0xB70A, 0x8D8E, 0xB70B, 0x8D8F, 0xB70C, 0x8D90, 0xB70D, 0x8D91, 0xB70E, 0x8D92, 0xB70F, 0x8D93, 0xB710, 0x8D94, 0xB711, - 0x8D95, 0xB712, 0x8D96, 0xB713, 0x8D97, 0xB714, 0x8D98, 0xB715, 0x8D99, 0xB716, 0x8D9A, 0xB717, 0x8D9B, 0xB718, 0x8D9C, 0xB719, - 0x8D9D, 0xB71A, 0x8D9E, 0xB71B, 0x8D9F, 0xB71C, 0x8DA0, 0xB71D, 0x8DA1, 0xB71E, 0x8DA2, 0xB71F, 0x8DA3, 0xB720, 0x8DA4, 0xB721, - 0x8DA5, 0xB722, 0x8DA6, 0xB723, 0x8DA7, 0xB724, 0x8DA8, 0xB725, 0x8DA9, 0xB726, 0x8DAA, 0xB727, 0x8DAB, 0xB72A, 0x8DAC, 0xB72B, - 0x8DAD, 0xB72D, 0x8DAE, 0xB72E, 0x8DAF, 0xB731, 0x8DB0, 0xB732, 0x8DB1, 0xB733, 0x8DB2, 0xB734, 0x8DB3, 0xB735, 0x8DB4, 0xB736, - 0x8DB5, 0xB737, 0x8DB6, 0xB73A, 0x8DB7, 0xB73C, 0x8DB8, 0xB73D, 0x8DB9, 0xB73E, 0x8DBA, 0xB73F, 0x8DBB, 0xB740, 0x8DBC, 0xB741, - 0x8DBD, 0xB742, 0x8DBE, 0xB743, 0x8DBF, 0xB745, 0x8DC0, 0xB746, 0x8DC1, 0xB747, 0x8DC2, 0xB749, 0x8DC3, 0xB74A, 0x8DC4, 0xB74B, - 0x8DC5, 0xB74D, 0x8DC6, 0xB74E, 0x8DC7, 0xB74F, 0x8DC8, 0xB750, 0x8DC9, 0xB751, 0x8DCA, 0xB752, 0x8DCB, 0xB753, 0x8DCC, 0xB756, - 0x8DCD, 0xB757, 0x8DCE, 0xB758, 0x8DCF, 0xB759, 0x8DD0, 0xB75A, 0x8DD1, 0xB75B, 0x8DD2, 0xB75C, 0x8DD3, 0xB75D, 0x8DD4, 0xB75E, - 0x8DD5, 0xB75F, 0x8DD6, 0xB761, 0x8DD7, 0xB762, 0x8DD8, 0xB763, 0x8DD9, 0xB765, 0x8DDA, 0xB766, 0x8DDB, 0xB767, 0x8DDC, 0xB769, - 0x8DDD, 0xB76A, 0x8DDE, 0xB76B, 0x8DDF, 0xB76C, 0x8DE0, 0xB76D, 0x8DE1, 0xB76E, 0x8DE2, 0xB76F, 0x8DE3, 0xB772, 0x8DE4, 0xB774, - 0x8DE5, 0xB776, 0x8DE6, 0xB777, 0x8DE7, 0xB778, 0x8DE8, 0xB779, 0x8DE9, 0xB77A, 0x8DEA, 0xB77B, 0x8DEB, 0xB77E, 0x8DEC, 0xB77F, - 0x8DED, 0xB781, 0x8DEE, 0xB782, 0x8DEF, 0xB783, 0x8DF0, 0xB785, 0x8DF1, 0xB786, 0x8DF2, 0xB787, 0x8DF3, 0xB788, 0x8DF4, 0xB789, - 0x8DF5, 0xB78A, 0x8DF6, 0xB78B, 0x8DF7, 0xB78E, 0x8DF8, 0xB793, 0x8DF9, 0xB794, 0x8DFA, 0xB795, 0x8DFB, 0xB79A, 0x8DFC, 0xB79B, - 0x8DFD, 0xB79D, 0x8DFE, 0xB79E, 0x8E41, 0xB79F, 0x8E42, 0xB7A1, 0x8E43, 0xB7A2, 0x8E44, 0xB7A3, 0x8E45, 0xB7A4, 0x8E46, 0xB7A5, - 0x8E47, 0xB7A6, 0x8E48, 0xB7A7, 0x8E49, 0xB7AA, 0x8E4A, 0xB7AE, 0x8E4B, 0xB7AF, 0x8E4C, 0xB7B0, 0x8E4D, 0xB7B1, 0x8E4E, 0xB7B2, - 0x8E4F, 0xB7B3, 0x8E50, 0xB7B6, 0x8E51, 0xB7B7, 0x8E52, 0xB7B9, 0x8E53, 0xB7BA, 0x8E54, 0xB7BB, 0x8E55, 0xB7BC, 0x8E56, 0xB7BD, - 0x8E57, 0xB7BE, 0x8E58, 0xB7BF, 0x8E59, 0xB7C0, 0x8E5A, 0xB7C1, 0x8E61, 0xB7C2, 0x8E62, 0xB7C3, 0x8E63, 0xB7C4, 0x8E64, 0xB7C5, - 0x8E65, 0xB7C6, 0x8E66, 0xB7C8, 0x8E67, 0xB7CA, 0x8E68, 0xB7CB, 0x8E69, 0xB7CC, 0x8E6A, 0xB7CD, 0x8E6B, 0xB7CE, 0x8E6C, 0xB7CF, - 0x8E6D, 0xB7D0, 0x8E6E, 0xB7D1, 0x8E6F, 0xB7D2, 0x8E70, 0xB7D3, 0x8E71, 0xB7D4, 0x8E72, 0xB7D5, 0x8E73, 0xB7D6, 0x8E74, 0xB7D7, - 0x8E75, 0xB7D8, 0x8E76, 0xB7D9, 0x8E77, 0xB7DA, 0x8E78, 0xB7DB, 0x8E79, 0xB7DC, 0x8E7A, 0xB7DD, 0x8E81, 0xB7DE, 0x8E82, 0xB7DF, - 0x8E83, 0xB7E0, 0x8E84, 0xB7E1, 0x8E85, 0xB7E2, 0x8E86, 0xB7E3, 0x8E87, 0xB7E4, 0x8E88, 0xB7E5, 0x8E89, 0xB7E6, 0x8E8A, 0xB7E7, - 0x8E8B, 0xB7E8, 0x8E8C, 0xB7E9, 0x8E8D, 0xB7EA, 0x8E8E, 0xB7EB, 0x8E8F, 0xB7EE, 0x8E90, 0xB7EF, 0x8E91, 0xB7F1, 0x8E92, 0xB7F2, - 0x8E93, 0xB7F3, 0x8E94, 0xB7F5, 0x8E95, 0xB7F6, 0x8E96, 0xB7F7, 0x8E97, 0xB7F8, 0x8E98, 0xB7F9, 0x8E99, 0xB7FA, 0x8E9A, 0xB7FB, - 0x8E9B, 0xB7FE, 0x8E9C, 0xB802, 0x8E9D, 0xB803, 0x8E9E, 0xB804, 0x8E9F, 0xB805, 0x8EA0, 0xB806, 0x8EA1, 0xB80A, 0x8EA2, 0xB80B, - 0x8EA3, 0xB80D, 0x8EA4, 0xB80E, 0x8EA5, 0xB80F, 0x8EA6, 0xB811, 0x8EA7, 0xB812, 0x8EA8, 0xB813, 0x8EA9, 0xB814, 0x8EAA, 0xB815, - 0x8EAB, 0xB816, 0x8EAC, 0xB817, 0x8EAD, 0xB81A, 0x8EAE, 0xB81C, 0x8EAF, 0xB81E, 0x8EB0, 0xB81F, 0x8EB1, 0xB820, 0x8EB2, 0xB821, - 0x8EB3, 0xB822, 0x8EB4, 0xB823, 0x8EB5, 0xB826, 0x8EB6, 0xB827, 0x8EB7, 0xB829, 0x8EB8, 0xB82A, 0x8EB9, 0xB82B, 0x8EBA, 0xB82D, - 0x8EBB, 0xB82E, 0x8EBC, 0xB82F, 0x8EBD, 0xB830, 0x8EBE, 0xB831, 0x8EBF, 0xB832, 0x8EC0, 0xB833, 0x8EC1, 0xB836, 0x8EC2, 0xB83A, - 0x8EC3, 0xB83B, 0x8EC4, 0xB83C, 0x8EC5, 0xB83D, 0x8EC6, 0xB83E, 0x8EC7, 0xB83F, 0x8EC8, 0xB841, 0x8EC9, 0xB842, 0x8ECA, 0xB843, - 0x8ECB, 0xB845, 0x8ECC, 0xB846, 0x8ECD, 0xB847, 0x8ECE, 0xB848, 0x8ECF, 0xB849, 0x8ED0, 0xB84A, 0x8ED1, 0xB84B, 0x8ED2, 0xB84C, - 0x8ED3, 0xB84D, 0x8ED4, 0xB84E, 0x8ED5, 0xB84F, 0x8ED6, 0xB850, 0x8ED7, 0xB852, 0x8ED8, 0xB854, 0x8ED9, 0xB855, 0x8EDA, 0xB856, - 0x8EDB, 0xB857, 0x8EDC, 0xB858, 0x8EDD, 0xB859, 0x8EDE, 0xB85A, 0x8EDF, 0xB85B, 0x8EE0, 0xB85E, 0x8EE1, 0xB85F, 0x8EE2, 0xB861, - 0x8EE3, 0xB862, 0x8EE4, 0xB863, 0x8EE5, 0xB865, 0x8EE6, 0xB866, 0x8EE7, 0xB867, 0x8EE8, 0xB868, 0x8EE9, 0xB869, 0x8EEA, 0xB86A, - 0x8EEB, 0xB86B, 0x8EEC, 0xB86E, 0x8EED, 0xB870, 0x8EEE, 0xB872, 0x8EEF, 0xB873, 0x8EF0, 0xB874, 0x8EF1, 0xB875, 0x8EF2, 0xB876, - 0x8EF3, 0xB877, 0x8EF4, 0xB879, 0x8EF5, 0xB87A, 0x8EF6, 0xB87B, 0x8EF7, 0xB87D, 0x8EF8, 0xB87E, 0x8EF9, 0xB87F, 0x8EFA, 0xB880, - 0x8EFB, 0xB881, 0x8EFC, 0xB882, 0x8EFD, 0xB883, 0x8EFE, 0xB884, 0x8F41, 0xB885, 0x8F42, 0xB886, 0x8F43, 0xB887, 0x8F44, 0xB888, - 0x8F45, 0xB889, 0x8F46, 0xB88A, 0x8F47, 0xB88B, 0x8F48, 0xB88C, 0x8F49, 0xB88E, 0x8F4A, 0xB88F, 0x8F4B, 0xB890, 0x8F4C, 0xB891, - 0x8F4D, 0xB892, 0x8F4E, 0xB893, 0x8F4F, 0xB894, 0x8F50, 0xB895, 0x8F51, 0xB896, 0x8F52, 0xB897, 0x8F53, 0xB898, 0x8F54, 0xB899, - 0x8F55, 0xB89A, 0x8F56, 0xB89B, 0x8F57, 0xB89C, 0x8F58, 0xB89D, 0x8F59, 0xB89E, 0x8F5A, 0xB89F, 0x8F61, 0xB8A0, 0x8F62, 0xB8A1, - 0x8F63, 0xB8A2, 0x8F64, 0xB8A3, 0x8F65, 0xB8A4, 0x8F66, 0xB8A5, 0x8F67, 0xB8A6, 0x8F68, 0xB8A7, 0x8F69, 0xB8A9, 0x8F6A, 0xB8AA, - 0x8F6B, 0xB8AB, 0x8F6C, 0xB8AC, 0x8F6D, 0xB8AD, 0x8F6E, 0xB8AE, 0x8F6F, 0xB8AF, 0x8F70, 0xB8B1, 0x8F71, 0xB8B2, 0x8F72, 0xB8B3, - 0x8F73, 0xB8B5, 0x8F74, 0xB8B6, 0x8F75, 0xB8B7, 0x8F76, 0xB8B9, 0x8F77, 0xB8BA, 0x8F78, 0xB8BB, 0x8F79, 0xB8BC, 0x8F7A, 0xB8BD, - 0x8F81, 0xB8BE, 0x8F82, 0xB8BF, 0x8F83, 0xB8C2, 0x8F84, 0xB8C4, 0x8F85, 0xB8C6, 0x8F86, 0xB8C7, 0x8F87, 0xB8C8, 0x8F88, 0xB8C9, - 0x8F89, 0xB8CA, 0x8F8A, 0xB8CB, 0x8F8B, 0xB8CD, 0x8F8C, 0xB8CE, 0x8F8D, 0xB8CF, 0x8F8E, 0xB8D1, 0x8F8F, 0xB8D2, 0x8F90, 0xB8D3, - 0x8F91, 0xB8D5, 0x8F92, 0xB8D6, 0x8F93, 0xB8D7, 0x8F94, 0xB8D8, 0x8F95, 0xB8D9, 0x8F96, 0xB8DA, 0x8F97, 0xB8DB, 0x8F98, 0xB8DC, - 0x8F99, 0xB8DE, 0x8F9A, 0xB8E0, 0x8F9B, 0xB8E2, 0x8F9C, 0xB8E3, 0x8F9D, 0xB8E4, 0x8F9E, 0xB8E5, 0x8F9F, 0xB8E6, 0x8FA0, 0xB8E7, - 0x8FA1, 0xB8EA, 0x8FA2, 0xB8EB, 0x8FA3, 0xB8ED, 0x8FA4, 0xB8EE, 0x8FA5, 0xB8EF, 0x8FA6, 0xB8F1, 0x8FA7, 0xB8F2, 0x8FA8, 0xB8F3, - 0x8FA9, 0xB8F4, 0x8FAA, 0xB8F5, 0x8FAB, 0xB8F6, 0x8FAC, 0xB8F7, 0x8FAD, 0xB8FA, 0x8FAE, 0xB8FC, 0x8FAF, 0xB8FE, 0x8FB0, 0xB8FF, - 0x8FB1, 0xB900, 0x8FB2, 0xB901, 0x8FB3, 0xB902, 0x8FB4, 0xB903, 0x8FB5, 0xB905, 0x8FB6, 0xB906, 0x8FB7, 0xB907, 0x8FB8, 0xB908, - 0x8FB9, 0xB909, 0x8FBA, 0xB90A, 0x8FBB, 0xB90B, 0x8FBC, 0xB90C, 0x8FBD, 0xB90D, 0x8FBE, 0xB90E, 0x8FBF, 0xB90F, 0x8FC0, 0xB910, - 0x8FC1, 0xB911, 0x8FC2, 0xB912, 0x8FC3, 0xB913, 0x8FC4, 0xB914, 0x8FC5, 0xB915, 0x8FC6, 0xB916, 0x8FC7, 0xB917, 0x8FC8, 0xB919, - 0x8FC9, 0xB91A, 0x8FCA, 0xB91B, 0x8FCB, 0xB91C, 0x8FCC, 0xB91D, 0x8FCD, 0xB91E, 0x8FCE, 0xB91F, 0x8FCF, 0xB921, 0x8FD0, 0xB922, - 0x8FD1, 0xB923, 0x8FD2, 0xB924, 0x8FD3, 0xB925, 0x8FD4, 0xB926, 0x8FD5, 0xB927, 0x8FD6, 0xB928, 0x8FD7, 0xB929, 0x8FD8, 0xB92A, - 0x8FD9, 0xB92B, 0x8FDA, 0xB92C, 0x8FDB, 0xB92D, 0x8FDC, 0xB92E, 0x8FDD, 0xB92F, 0x8FDE, 0xB930, 0x8FDF, 0xB931, 0x8FE0, 0xB932, - 0x8FE1, 0xB933, 0x8FE2, 0xB934, 0x8FE3, 0xB935, 0x8FE4, 0xB936, 0x8FE5, 0xB937, 0x8FE6, 0xB938, 0x8FE7, 0xB939, 0x8FE8, 0xB93A, - 0x8FE9, 0xB93B, 0x8FEA, 0xB93E, 0x8FEB, 0xB93F, 0x8FEC, 0xB941, 0x8FED, 0xB942, 0x8FEE, 0xB943, 0x8FEF, 0xB945, 0x8FF0, 0xB946, - 0x8FF1, 0xB947, 0x8FF2, 0xB948, 0x8FF3, 0xB949, 0x8FF4, 0xB94A, 0x8FF5, 0xB94B, 0x8FF6, 0xB94D, 0x8FF7, 0xB94E, 0x8FF8, 0xB950, - 0x8FF9, 0xB952, 0x8FFA, 0xB953, 0x8FFB, 0xB954, 0x8FFC, 0xB955, 0x8FFD, 0xB956, 0x8FFE, 0xB957, 0x9041, 0xB95A, 0x9042, 0xB95B, - 0x9043, 0xB95D, 0x9044, 0xB95E, 0x9045, 0xB95F, 0x9046, 0xB961, 0x9047, 0xB962, 0x9048, 0xB963, 0x9049, 0xB964, 0x904A, 0xB965, - 0x904B, 0xB966, 0x904C, 0xB967, 0x904D, 0xB96A, 0x904E, 0xB96C, 0x904F, 0xB96E, 0x9050, 0xB96F, 0x9051, 0xB970, 0x9052, 0xB971, - 0x9053, 0xB972, 0x9054, 0xB973, 0x9055, 0xB976, 0x9056, 0xB977, 0x9057, 0xB979, 0x9058, 0xB97A, 0x9059, 0xB97B, 0x905A, 0xB97D, - 0x9061, 0xB97E, 0x9062, 0xB97F, 0x9063, 0xB980, 0x9064, 0xB981, 0x9065, 0xB982, 0x9066, 0xB983, 0x9067, 0xB986, 0x9068, 0xB988, - 0x9069, 0xB98B, 0x906A, 0xB98C, 0x906B, 0xB98F, 0x906C, 0xB990, 0x906D, 0xB991, 0x906E, 0xB992, 0x906F, 0xB993, 0x9070, 0xB994, - 0x9071, 0xB995, 0x9072, 0xB996, 0x9073, 0xB997, 0x9074, 0xB998, 0x9075, 0xB999, 0x9076, 0xB99A, 0x9077, 0xB99B, 0x9078, 0xB99C, - 0x9079, 0xB99D, 0x907A, 0xB99E, 0x9081, 0xB99F, 0x9082, 0xB9A0, 0x9083, 0xB9A1, 0x9084, 0xB9A2, 0x9085, 0xB9A3, 0x9086, 0xB9A4, - 0x9087, 0xB9A5, 0x9088, 0xB9A6, 0x9089, 0xB9A7, 0x908A, 0xB9A8, 0x908B, 0xB9A9, 0x908C, 0xB9AA, 0x908D, 0xB9AB, 0x908E, 0xB9AE, - 0x908F, 0xB9AF, 0x9090, 0xB9B1, 0x9091, 0xB9B2, 0x9092, 0xB9B3, 0x9093, 0xB9B5, 0x9094, 0xB9B6, 0x9095, 0xB9B7, 0x9096, 0xB9B8, - 0x9097, 0xB9B9, 0x9098, 0xB9BA, 0x9099, 0xB9BB, 0x909A, 0xB9BE, 0x909B, 0xB9C0, 0x909C, 0xB9C2, 0x909D, 0xB9C3, 0x909E, 0xB9C4, - 0x909F, 0xB9C5, 0x90A0, 0xB9C6, 0x90A1, 0xB9C7, 0x90A2, 0xB9CA, 0x90A3, 0xB9CB, 0x90A4, 0xB9CD, 0x90A5, 0xB9D3, 0x90A6, 0xB9D4, - 0x90A7, 0xB9D5, 0x90A8, 0xB9D6, 0x90A9, 0xB9D7, 0x90AA, 0xB9DA, 0x90AB, 0xB9DC, 0x90AC, 0xB9DF, 0x90AD, 0xB9E0, 0x90AE, 0xB9E2, - 0x90AF, 0xB9E6, 0x90B0, 0xB9E7, 0x90B1, 0xB9E9, 0x90B2, 0xB9EA, 0x90B3, 0xB9EB, 0x90B4, 0xB9ED, 0x90B5, 0xB9EE, 0x90B6, 0xB9EF, - 0x90B7, 0xB9F0, 0x90B8, 0xB9F1, 0x90B9, 0xB9F2, 0x90BA, 0xB9F3, 0x90BB, 0xB9F6, 0x90BC, 0xB9FB, 0x90BD, 0xB9FC, 0x90BE, 0xB9FD, - 0x90BF, 0xB9FE, 0x90C0, 0xB9FF, 0x90C1, 0xBA02, 0x90C2, 0xBA03, 0x90C3, 0xBA04, 0x90C4, 0xBA05, 0x90C5, 0xBA06, 0x90C6, 0xBA07, - 0x90C7, 0xBA09, 0x90C8, 0xBA0A, 0x90C9, 0xBA0B, 0x90CA, 0xBA0C, 0x90CB, 0xBA0D, 0x90CC, 0xBA0E, 0x90CD, 0xBA0F, 0x90CE, 0xBA10, - 0x90CF, 0xBA11, 0x90D0, 0xBA12, 0x90D1, 0xBA13, 0x90D2, 0xBA14, 0x90D3, 0xBA16, 0x90D4, 0xBA17, 0x90D5, 0xBA18, 0x90D6, 0xBA19, - 0x90D7, 0xBA1A, 0x90D8, 0xBA1B, 0x90D9, 0xBA1C, 0x90DA, 0xBA1D, 0x90DB, 0xBA1E, 0x90DC, 0xBA1F, 0x90DD, 0xBA20, 0x90DE, 0xBA21, - 0x90DF, 0xBA22, 0x90E0, 0xBA23, 0x90E1, 0xBA24, 0x90E2, 0xBA25, 0x90E3, 0xBA26, 0x90E4, 0xBA27, 0x90E5, 0xBA28, 0x90E6, 0xBA29, - 0x90E7, 0xBA2A, 0x90E8, 0xBA2B, 0x90E9, 0xBA2C, 0x90EA, 0xBA2D, 0x90EB, 0xBA2E, 0x90EC, 0xBA2F, 0x90ED, 0xBA30, 0x90EE, 0xBA31, - 0x90EF, 0xBA32, 0x90F0, 0xBA33, 0x90F1, 0xBA34, 0x90F2, 0xBA35, 0x90F3, 0xBA36, 0x90F4, 0xBA37, 0x90F5, 0xBA3A, 0x90F6, 0xBA3B, - 0x90F7, 0xBA3D, 0x90F8, 0xBA3E, 0x90F9, 0xBA3F, 0x90FA, 0xBA41, 0x90FB, 0xBA43, 0x90FC, 0xBA44, 0x90FD, 0xBA45, 0x90FE, 0xBA46, - 0x9141, 0xBA47, 0x9142, 0xBA4A, 0x9143, 0xBA4C, 0x9144, 0xBA4F, 0x9145, 0xBA50, 0x9146, 0xBA51, 0x9147, 0xBA52, 0x9148, 0xBA56, - 0x9149, 0xBA57, 0x914A, 0xBA59, 0x914B, 0xBA5A, 0x914C, 0xBA5B, 0x914D, 0xBA5D, 0x914E, 0xBA5E, 0x914F, 0xBA5F, 0x9150, 0xBA60, - 0x9151, 0xBA61, 0x9152, 0xBA62, 0x9153, 0xBA63, 0x9154, 0xBA66, 0x9155, 0xBA6A, 0x9156, 0xBA6B, 0x9157, 0xBA6C, 0x9158, 0xBA6D, - 0x9159, 0xBA6E, 0x915A, 0xBA6F, 0x9161, 0xBA72, 0x9162, 0xBA73, 0x9163, 0xBA75, 0x9164, 0xBA76, 0x9165, 0xBA77, 0x9166, 0xBA79, - 0x9167, 0xBA7A, 0x9168, 0xBA7B, 0x9169, 0xBA7C, 0x916A, 0xBA7D, 0x916B, 0xBA7E, 0x916C, 0xBA7F, 0x916D, 0xBA80, 0x916E, 0xBA81, - 0x916F, 0xBA82, 0x9170, 0xBA86, 0x9171, 0xBA88, 0x9172, 0xBA89, 0x9173, 0xBA8A, 0x9174, 0xBA8B, 0x9175, 0xBA8D, 0x9176, 0xBA8E, - 0x9177, 0xBA8F, 0x9178, 0xBA90, 0x9179, 0xBA91, 0x917A, 0xBA92, 0x9181, 0xBA93, 0x9182, 0xBA94, 0x9183, 0xBA95, 0x9184, 0xBA96, - 0x9185, 0xBA97, 0x9186, 0xBA98, 0x9187, 0xBA99, 0x9188, 0xBA9A, 0x9189, 0xBA9B, 0x918A, 0xBA9C, 0x918B, 0xBA9D, 0x918C, 0xBA9E, - 0x918D, 0xBA9F, 0x918E, 0xBAA0, 0x918F, 0xBAA1, 0x9190, 0xBAA2, 0x9191, 0xBAA3, 0x9192, 0xBAA4, 0x9193, 0xBAA5, 0x9194, 0xBAA6, - 0x9195, 0xBAA7, 0x9196, 0xBAAA, 0x9197, 0xBAAD, 0x9198, 0xBAAE, 0x9199, 0xBAAF, 0x919A, 0xBAB1, 0x919B, 0xBAB3, 0x919C, 0xBAB4, - 0x919D, 0xBAB5, 0x919E, 0xBAB6, 0x919F, 0xBAB7, 0x91A0, 0xBABA, 0x91A1, 0xBABC, 0x91A2, 0xBABE, 0x91A3, 0xBABF, 0x91A4, 0xBAC0, - 0x91A5, 0xBAC1, 0x91A6, 0xBAC2, 0x91A7, 0xBAC3, 0x91A8, 0xBAC5, 0x91A9, 0xBAC6, 0x91AA, 0xBAC7, 0x91AB, 0xBAC9, 0x91AC, 0xBACA, - 0x91AD, 0xBACB, 0x91AE, 0xBACC, 0x91AF, 0xBACD, 0x91B0, 0xBACE, 0x91B1, 0xBACF, 0x91B2, 0xBAD0, 0x91B3, 0xBAD1, 0x91B4, 0xBAD2, - 0x91B5, 0xBAD3, 0x91B6, 0xBAD4, 0x91B7, 0xBAD5, 0x91B8, 0xBAD6, 0x91B9, 0xBAD7, 0x91BA, 0xBADA, 0x91BB, 0xBADB, 0x91BC, 0xBADC, - 0x91BD, 0xBADD, 0x91BE, 0xBADE, 0x91BF, 0xBADF, 0x91C0, 0xBAE0, 0x91C1, 0xBAE1, 0x91C2, 0xBAE2, 0x91C3, 0xBAE3, 0x91C4, 0xBAE4, - 0x91C5, 0xBAE5, 0x91C6, 0xBAE6, 0x91C7, 0xBAE7, 0x91C8, 0xBAE8, 0x91C9, 0xBAE9, 0x91CA, 0xBAEA, 0x91CB, 0xBAEB, 0x91CC, 0xBAEC, - 0x91CD, 0xBAED, 0x91CE, 0xBAEE, 0x91CF, 0xBAEF, 0x91D0, 0xBAF0, 0x91D1, 0xBAF1, 0x91D2, 0xBAF2, 0x91D3, 0xBAF3, 0x91D4, 0xBAF4, - 0x91D5, 0xBAF5, 0x91D6, 0xBAF6, 0x91D7, 0xBAF7, 0x91D8, 0xBAF8, 0x91D9, 0xBAF9, 0x91DA, 0xBAFA, 0x91DB, 0xBAFB, 0x91DC, 0xBAFD, - 0x91DD, 0xBAFE, 0x91DE, 0xBAFF, 0x91DF, 0xBB01, 0x91E0, 0xBB02, 0x91E1, 0xBB03, 0x91E2, 0xBB05, 0x91E3, 0xBB06, 0x91E4, 0xBB07, - 0x91E5, 0xBB08, 0x91E6, 0xBB09, 0x91E7, 0xBB0A, 0x91E8, 0xBB0B, 0x91E9, 0xBB0C, 0x91EA, 0xBB0E, 0x91EB, 0xBB10, 0x91EC, 0xBB12, - 0x91ED, 0xBB13, 0x91EE, 0xBB14, 0x91EF, 0xBB15, 0x91F0, 0xBB16, 0x91F1, 0xBB17, 0x91F2, 0xBB19, 0x91F3, 0xBB1A, 0x91F4, 0xBB1B, - 0x91F5, 0xBB1D, 0x91F6, 0xBB1E, 0x91F7, 0xBB1F, 0x91F8, 0xBB21, 0x91F9, 0xBB22, 0x91FA, 0xBB23, 0x91FB, 0xBB24, 0x91FC, 0xBB25, - 0x91FD, 0xBB26, 0x91FE, 0xBB27, 0x9241, 0xBB28, 0x9242, 0xBB2A, 0x9243, 0xBB2C, 0x9244, 0xBB2D, 0x9245, 0xBB2E, 0x9246, 0xBB2F, - 0x9247, 0xBB30, 0x9248, 0xBB31, 0x9249, 0xBB32, 0x924A, 0xBB33, 0x924B, 0xBB37, 0x924C, 0xBB39, 0x924D, 0xBB3A, 0x924E, 0xBB3F, - 0x924F, 0xBB40, 0x9250, 0xBB41, 0x9251, 0xBB42, 0x9252, 0xBB43, 0x9253, 0xBB46, 0x9254, 0xBB48, 0x9255, 0xBB4A, 0x9256, 0xBB4B, - 0x9257, 0xBB4C, 0x9258, 0xBB4E, 0x9259, 0xBB51, 0x925A, 0xBB52, 0x9261, 0xBB53, 0x9262, 0xBB55, 0x9263, 0xBB56, 0x9264, 0xBB57, - 0x9265, 0xBB59, 0x9266, 0xBB5A, 0x9267, 0xBB5B, 0x9268, 0xBB5C, 0x9269, 0xBB5D, 0x926A, 0xBB5E, 0x926B, 0xBB5F, 0x926C, 0xBB60, - 0x926D, 0xBB62, 0x926E, 0xBB64, 0x926F, 0xBB65, 0x9270, 0xBB66, 0x9271, 0xBB67, 0x9272, 0xBB68, 0x9273, 0xBB69, 0x9274, 0xBB6A, - 0x9275, 0xBB6B, 0x9276, 0xBB6D, 0x9277, 0xBB6E, 0x9278, 0xBB6F, 0x9279, 0xBB70, 0x927A, 0xBB71, 0x9281, 0xBB72, 0x9282, 0xBB73, - 0x9283, 0xBB74, 0x9284, 0xBB75, 0x9285, 0xBB76, 0x9286, 0xBB77, 0x9287, 0xBB78, 0x9288, 0xBB79, 0x9289, 0xBB7A, 0x928A, 0xBB7B, - 0x928B, 0xBB7C, 0x928C, 0xBB7D, 0x928D, 0xBB7E, 0x928E, 0xBB7F, 0x928F, 0xBB80, 0x9290, 0xBB81, 0x9291, 0xBB82, 0x9292, 0xBB83, - 0x9293, 0xBB84, 0x9294, 0xBB85, 0x9295, 0xBB86, 0x9296, 0xBB87, 0x9297, 0xBB89, 0x9298, 0xBB8A, 0x9299, 0xBB8B, 0x929A, 0xBB8D, - 0x929B, 0xBB8E, 0x929C, 0xBB8F, 0x929D, 0xBB91, 0x929E, 0xBB92, 0x929F, 0xBB93, 0x92A0, 0xBB94, 0x92A1, 0xBB95, 0x92A2, 0xBB96, - 0x92A3, 0xBB97, 0x92A4, 0xBB98, 0x92A5, 0xBB99, 0x92A6, 0xBB9A, 0x92A7, 0xBB9B, 0x92A8, 0xBB9C, 0x92A9, 0xBB9D, 0x92AA, 0xBB9E, - 0x92AB, 0xBB9F, 0x92AC, 0xBBA0, 0x92AD, 0xBBA1, 0x92AE, 0xBBA2, 0x92AF, 0xBBA3, 0x92B0, 0xBBA5, 0x92B1, 0xBBA6, 0x92B2, 0xBBA7, - 0x92B3, 0xBBA9, 0x92B4, 0xBBAA, 0x92B5, 0xBBAB, 0x92B6, 0xBBAD, 0x92B7, 0xBBAE, 0x92B8, 0xBBAF, 0x92B9, 0xBBB0, 0x92BA, 0xBBB1, - 0x92BB, 0xBBB2, 0x92BC, 0xBBB3, 0x92BD, 0xBBB5, 0x92BE, 0xBBB6, 0x92BF, 0xBBB8, 0x92C0, 0xBBB9, 0x92C1, 0xBBBA, 0x92C2, 0xBBBB, - 0x92C3, 0xBBBC, 0x92C4, 0xBBBD, 0x92C5, 0xBBBE, 0x92C6, 0xBBBF, 0x92C7, 0xBBC1, 0x92C8, 0xBBC2, 0x92C9, 0xBBC3, 0x92CA, 0xBBC5, - 0x92CB, 0xBBC6, 0x92CC, 0xBBC7, 0x92CD, 0xBBC9, 0x92CE, 0xBBCA, 0x92CF, 0xBBCB, 0x92D0, 0xBBCC, 0x92D1, 0xBBCD, 0x92D2, 0xBBCE, - 0x92D3, 0xBBCF, 0x92D4, 0xBBD1, 0x92D5, 0xBBD2, 0x92D6, 0xBBD4, 0x92D7, 0xBBD5, 0x92D8, 0xBBD6, 0x92D9, 0xBBD7, 0x92DA, 0xBBD8, - 0x92DB, 0xBBD9, 0x92DC, 0xBBDA, 0x92DD, 0xBBDB, 0x92DE, 0xBBDC, 0x92DF, 0xBBDD, 0x92E0, 0xBBDE, 0x92E1, 0xBBDF, 0x92E2, 0xBBE0, - 0x92E3, 0xBBE1, 0x92E4, 0xBBE2, 0x92E5, 0xBBE3, 0x92E6, 0xBBE4, 0x92E7, 0xBBE5, 0x92E8, 0xBBE6, 0x92E9, 0xBBE7, 0x92EA, 0xBBE8, - 0x92EB, 0xBBE9, 0x92EC, 0xBBEA, 0x92ED, 0xBBEB, 0x92EE, 0xBBEC, 0x92EF, 0xBBED, 0x92F0, 0xBBEE, 0x92F1, 0xBBEF, 0x92F2, 0xBBF0, - 0x92F3, 0xBBF1, 0x92F4, 0xBBF2, 0x92F5, 0xBBF3, 0x92F6, 0xBBF4, 0x92F7, 0xBBF5, 0x92F8, 0xBBF6, 0x92F9, 0xBBF7, 0x92FA, 0xBBFA, - 0x92FB, 0xBBFB, 0x92FC, 0xBBFD, 0x92FD, 0xBBFE, 0x92FE, 0xBC01, 0x9341, 0xBC03, 0x9342, 0xBC04, 0x9343, 0xBC05, 0x9344, 0xBC06, - 0x9345, 0xBC07, 0x9346, 0xBC0A, 0x9347, 0xBC0E, 0x9348, 0xBC10, 0x9349, 0xBC12, 0x934A, 0xBC13, 0x934B, 0xBC19, 0x934C, 0xBC1A, - 0x934D, 0xBC20, 0x934E, 0xBC21, 0x934F, 0xBC22, 0x9350, 0xBC23, 0x9351, 0xBC26, 0x9352, 0xBC28, 0x9353, 0xBC2A, 0x9354, 0xBC2B, - 0x9355, 0xBC2C, 0x9356, 0xBC2E, 0x9357, 0xBC2F, 0x9358, 0xBC32, 0x9359, 0xBC33, 0x935A, 0xBC35, 0x9361, 0xBC36, 0x9362, 0xBC37, - 0x9363, 0xBC39, 0x9364, 0xBC3A, 0x9365, 0xBC3B, 0x9366, 0xBC3C, 0x9367, 0xBC3D, 0x9368, 0xBC3E, 0x9369, 0xBC3F, 0x936A, 0xBC42, - 0x936B, 0xBC46, 0x936C, 0xBC47, 0x936D, 0xBC48, 0x936E, 0xBC4A, 0x936F, 0xBC4B, 0x9370, 0xBC4E, 0x9371, 0xBC4F, 0x9372, 0xBC51, - 0x9373, 0xBC52, 0x9374, 0xBC53, 0x9375, 0xBC54, 0x9376, 0xBC55, 0x9377, 0xBC56, 0x9378, 0xBC57, 0x9379, 0xBC58, 0x937A, 0xBC59, - 0x9381, 0xBC5A, 0x9382, 0xBC5B, 0x9383, 0xBC5C, 0x9384, 0xBC5E, 0x9385, 0xBC5F, 0x9386, 0xBC60, 0x9387, 0xBC61, 0x9388, 0xBC62, - 0x9389, 0xBC63, 0x938A, 0xBC64, 0x938B, 0xBC65, 0x938C, 0xBC66, 0x938D, 0xBC67, 0x938E, 0xBC68, 0x938F, 0xBC69, 0x9390, 0xBC6A, - 0x9391, 0xBC6B, 0x9392, 0xBC6C, 0x9393, 0xBC6D, 0x9394, 0xBC6E, 0x9395, 0xBC6F, 0x9396, 0xBC70, 0x9397, 0xBC71, 0x9398, 0xBC72, - 0x9399, 0xBC73, 0x939A, 0xBC74, 0x939B, 0xBC75, 0x939C, 0xBC76, 0x939D, 0xBC77, 0x939E, 0xBC78, 0x939F, 0xBC79, 0x93A0, 0xBC7A, - 0x93A1, 0xBC7B, 0x93A2, 0xBC7C, 0x93A3, 0xBC7D, 0x93A4, 0xBC7E, 0x93A5, 0xBC7F, 0x93A6, 0xBC80, 0x93A7, 0xBC81, 0x93A8, 0xBC82, - 0x93A9, 0xBC83, 0x93AA, 0xBC86, 0x93AB, 0xBC87, 0x93AC, 0xBC89, 0x93AD, 0xBC8A, 0x93AE, 0xBC8D, 0x93AF, 0xBC8F, 0x93B0, 0xBC90, - 0x93B1, 0xBC91, 0x93B2, 0xBC92, 0x93B3, 0xBC93, 0x93B4, 0xBC96, 0x93B5, 0xBC98, 0x93B6, 0xBC9B, 0x93B7, 0xBC9C, 0x93B8, 0xBC9D, - 0x93B9, 0xBC9E, 0x93BA, 0xBC9F, 0x93BB, 0xBCA2, 0x93BC, 0xBCA3, 0x93BD, 0xBCA5, 0x93BE, 0xBCA6, 0x93BF, 0xBCA9, 0x93C0, 0xBCAA, - 0x93C1, 0xBCAB, 0x93C2, 0xBCAC, 0x93C3, 0xBCAD, 0x93C4, 0xBCAE, 0x93C5, 0xBCAF, 0x93C6, 0xBCB2, 0x93C7, 0xBCB6, 0x93C8, 0xBCB7, - 0x93C9, 0xBCB8, 0x93CA, 0xBCB9, 0x93CB, 0xBCBA, 0x93CC, 0xBCBB, 0x93CD, 0xBCBE, 0x93CE, 0xBCBF, 0x93CF, 0xBCC1, 0x93D0, 0xBCC2, - 0x93D1, 0xBCC3, 0x93D2, 0xBCC5, 0x93D3, 0xBCC6, 0x93D4, 0xBCC7, 0x93D5, 0xBCC8, 0x93D6, 0xBCC9, 0x93D7, 0xBCCA, 0x93D8, 0xBCCB, - 0x93D9, 0xBCCC, 0x93DA, 0xBCCE, 0x93DB, 0xBCD2, 0x93DC, 0xBCD3, 0x93DD, 0xBCD4, 0x93DE, 0xBCD6, 0x93DF, 0xBCD7, 0x93E0, 0xBCD9, - 0x93E1, 0xBCDA, 0x93E2, 0xBCDB, 0x93E3, 0xBCDD, 0x93E4, 0xBCDE, 0x93E5, 0xBCDF, 0x93E6, 0xBCE0, 0x93E7, 0xBCE1, 0x93E8, 0xBCE2, - 0x93E9, 0xBCE3, 0x93EA, 0xBCE4, 0x93EB, 0xBCE5, 0x93EC, 0xBCE6, 0x93ED, 0xBCE7, 0x93EE, 0xBCE8, 0x93EF, 0xBCE9, 0x93F0, 0xBCEA, - 0x93F1, 0xBCEB, 0x93F2, 0xBCEC, 0x93F3, 0xBCED, 0x93F4, 0xBCEE, 0x93F5, 0xBCEF, 0x93F6, 0xBCF0, 0x93F7, 0xBCF1, 0x93F8, 0xBCF2, - 0x93F9, 0xBCF3, 0x93FA, 0xBCF7, 0x93FB, 0xBCF9, 0x93FC, 0xBCFA, 0x93FD, 0xBCFB, 0x93FE, 0xBCFD, 0x9441, 0xBCFE, 0x9442, 0xBCFF, - 0x9443, 0xBD00, 0x9444, 0xBD01, 0x9445, 0xBD02, 0x9446, 0xBD03, 0x9447, 0xBD06, 0x9448, 0xBD08, 0x9449, 0xBD0A, 0x944A, 0xBD0B, - 0x944B, 0xBD0C, 0x944C, 0xBD0D, 0x944D, 0xBD0E, 0x944E, 0xBD0F, 0x944F, 0xBD11, 0x9450, 0xBD12, 0x9451, 0xBD13, 0x9452, 0xBD15, - 0x9453, 0xBD16, 0x9454, 0xBD17, 0x9455, 0xBD18, 0x9456, 0xBD19, 0x9457, 0xBD1A, 0x9458, 0xBD1B, 0x9459, 0xBD1C, 0x945A, 0xBD1D, - 0x9461, 0xBD1E, 0x9462, 0xBD1F, 0x9463, 0xBD20, 0x9464, 0xBD21, 0x9465, 0xBD22, 0x9466, 0xBD23, 0x9467, 0xBD25, 0x9468, 0xBD26, - 0x9469, 0xBD27, 0x946A, 0xBD28, 0x946B, 0xBD29, 0x946C, 0xBD2A, 0x946D, 0xBD2B, 0x946E, 0xBD2D, 0x946F, 0xBD2E, 0x9470, 0xBD2F, - 0x9471, 0xBD30, 0x9472, 0xBD31, 0x9473, 0xBD32, 0x9474, 0xBD33, 0x9475, 0xBD34, 0x9476, 0xBD35, 0x9477, 0xBD36, 0x9478, 0xBD37, - 0x9479, 0xBD38, 0x947A, 0xBD39, 0x9481, 0xBD3A, 0x9482, 0xBD3B, 0x9483, 0xBD3C, 0x9484, 0xBD3D, 0x9485, 0xBD3E, 0x9486, 0xBD3F, - 0x9487, 0xBD41, 0x9488, 0xBD42, 0x9489, 0xBD43, 0x948A, 0xBD44, 0x948B, 0xBD45, 0x948C, 0xBD46, 0x948D, 0xBD47, 0x948E, 0xBD4A, - 0x948F, 0xBD4B, 0x9490, 0xBD4D, 0x9491, 0xBD4E, 0x9492, 0xBD4F, 0x9493, 0xBD51, 0x9494, 0xBD52, 0x9495, 0xBD53, 0x9496, 0xBD54, - 0x9497, 0xBD55, 0x9498, 0xBD56, 0x9499, 0xBD57, 0x949A, 0xBD5A, 0x949B, 0xBD5B, 0x949C, 0xBD5C, 0x949D, 0xBD5D, 0x949E, 0xBD5E, - 0x949F, 0xBD5F, 0x94A0, 0xBD60, 0x94A1, 0xBD61, 0x94A2, 0xBD62, 0x94A3, 0xBD63, 0x94A4, 0xBD65, 0x94A5, 0xBD66, 0x94A6, 0xBD67, - 0x94A7, 0xBD69, 0x94A8, 0xBD6A, 0x94A9, 0xBD6B, 0x94AA, 0xBD6C, 0x94AB, 0xBD6D, 0x94AC, 0xBD6E, 0x94AD, 0xBD6F, 0x94AE, 0xBD70, - 0x94AF, 0xBD71, 0x94B0, 0xBD72, 0x94B1, 0xBD73, 0x94B2, 0xBD74, 0x94B3, 0xBD75, 0x94B4, 0xBD76, 0x94B5, 0xBD77, 0x94B6, 0xBD78, - 0x94B7, 0xBD79, 0x94B8, 0xBD7A, 0x94B9, 0xBD7B, 0x94BA, 0xBD7C, 0x94BB, 0xBD7D, 0x94BC, 0xBD7E, 0x94BD, 0xBD7F, 0x94BE, 0xBD82, - 0x94BF, 0xBD83, 0x94C0, 0xBD85, 0x94C1, 0xBD86, 0x94C2, 0xBD8B, 0x94C3, 0xBD8C, 0x94C4, 0xBD8D, 0x94C5, 0xBD8E, 0x94C6, 0xBD8F, - 0x94C7, 0xBD92, 0x94C8, 0xBD94, 0x94C9, 0xBD96, 0x94CA, 0xBD97, 0x94CB, 0xBD98, 0x94CC, 0xBD9B, 0x94CD, 0xBD9D, 0x94CE, 0xBD9E, - 0x94CF, 0xBD9F, 0x94D0, 0xBDA0, 0x94D1, 0xBDA1, 0x94D2, 0xBDA2, 0x94D3, 0xBDA3, 0x94D4, 0xBDA5, 0x94D5, 0xBDA6, 0x94D6, 0xBDA7, - 0x94D7, 0xBDA8, 0x94D8, 0xBDA9, 0x94D9, 0xBDAA, 0x94DA, 0xBDAB, 0x94DB, 0xBDAC, 0x94DC, 0xBDAD, 0x94DD, 0xBDAE, 0x94DE, 0xBDAF, - 0x94DF, 0xBDB1, 0x94E0, 0xBDB2, 0x94E1, 0xBDB3, 0x94E2, 0xBDB4, 0x94E3, 0xBDB5, 0x94E4, 0xBDB6, 0x94E5, 0xBDB7, 0x94E6, 0xBDB9, - 0x94E7, 0xBDBA, 0x94E8, 0xBDBB, 0x94E9, 0xBDBC, 0x94EA, 0xBDBD, 0x94EB, 0xBDBE, 0x94EC, 0xBDBF, 0x94ED, 0xBDC0, 0x94EE, 0xBDC1, - 0x94EF, 0xBDC2, 0x94F0, 0xBDC3, 0x94F1, 0xBDC4, 0x94F2, 0xBDC5, 0x94F3, 0xBDC6, 0x94F4, 0xBDC7, 0x94F5, 0xBDC8, 0x94F6, 0xBDC9, - 0x94F7, 0xBDCA, 0x94F8, 0xBDCB, 0x94F9, 0xBDCC, 0x94FA, 0xBDCD, 0x94FB, 0xBDCE, 0x94FC, 0xBDCF, 0x94FD, 0xBDD0, 0x94FE, 0xBDD1, - 0x9541, 0xBDD2, 0x9542, 0xBDD3, 0x9543, 0xBDD6, 0x9544, 0xBDD7, 0x9545, 0xBDD9, 0x9546, 0xBDDA, 0x9547, 0xBDDB, 0x9548, 0xBDDD, - 0x9549, 0xBDDE, 0x954A, 0xBDDF, 0x954B, 0xBDE0, 0x954C, 0xBDE1, 0x954D, 0xBDE2, 0x954E, 0xBDE3, 0x954F, 0xBDE4, 0x9550, 0xBDE5, - 0x9551, 0xBDE6, 0x9552, 0xBDE7, 0x9553, 0xBDE8, 0x9554, 0xBDEA, 0x9555, 0xBDEB, 0x9556, 0xBDEC, 0x9557, 0xBDED, 0x9558, 0xBDEE, - 0x9559, 0xBDEF, 0x955A, 0xBDF1, 0x9561, 0xBDF2, 0x9562, 0xBDF3, 0x9563, 0xBDF5, 0x9564, 0xBDF6, 0x9565, 0xBDF7, 0x9566, 0xBDF9, - 0x9567, 0xBDFA, 0x9568, 0xBDFB, 0x9569, 0xBDFC, 0x956A, 0xBDFD, 0x956B, 0xBDFE, 0x956C, 0xBDFF, 0x956D, 0xBE01, 0x956E, 0xBE02, - 0x956F, 0xBE04, 0x9570, 0xBE06, 0x9571, 0xBE07, 0x9572, 0xBE08, 0x9573, 0xBE09, 0x9574, 0xBE0A, 0x9575, 0xBE0B, 0x9576, 0xBE0E, - 0x9577, 0xBE0F, 0x9578, 0xBE11, 0x9579, 0xBE12, 0x957A, 0xBE13, 0x9581, 0xBE15, 0x9582, 0xBE16, 0x9583, 0xBE17, 0x9584, 0xBE18, - 0x9585, 0xBE19, 0x9586, 0xBE1A, 0x9587, 0xBE1B, 0x9588, 0xBE1E, 0x9589, 0xBE20, 0x958A, 0xBE21, 0x958B, 0xBE22, 0x958C, 0xBE23, - 0x958D, 0xBE24, 0x958E, 0xBE25, 0x958F, 0xBE26, 0x9590, 0xBE27, 0x9591, 0xBE28, 0x9592, 0xBE29, 0x9593, 0xBE2A, 0x9594, 0xBE2B, - 0x9595, 0xBE2C, 0x9596, 0xBE2D, 0x9597, 0xBE2E, 0x9598, 0xBE2F, 0x9599, 0xBE30, 0x959A, 0xBE31, 0x959B, 0xBE32, 0x959C, 0xBE33, - 0x959D, 0xBE34, 0x959E, 0xBE35, 0x959F, 0xBE36, 0x95A0, 0xBE37, 0x95A1, 0xBE38, 0x95A2, 0xBE39, 0x95A3, 0xBE3A, 0x95A4, 0xBE3B, - 0x95A5, 0xBE3C, 0x95A6, 0xBE3D, 0x95A7, 0xBE3E, 0x95A8, 0xBE3F, 0x95A9, 0xBE40, 0x95AA, 0xBE41, 0x95AB, 0xBE42, 0x95AC, 0xBE43, - 0x95AD, 0xBE46, 0x95AE, 0xBE47, 0x95AF, 0xBE49, 0x95B0, 0xBE4A, 0x95B1, 0xBE4B, 0x95B2, 0xBE4D, 0x95B3, 0xBE4F, 0x95B4, 0xBE50, - 0x95B5, 0xBE51, 0x95B6, 0xBE52, 0x95B7, 0xBE53, 0x95B8, 0xBE56, 0x95B9, 0xBE58, 0x95BA, 0xBE5C, 0x95BB, 0xBE5D, 0x95BC, 0xBE5E, - 0x95BD, 0xBE5F, 0x95BE, 0xBE62, 0x95BF, 0xBE63, 0x95C0, 0xBE65, 0x95C1, 0xBE66, 0x95C2, 0xBE67, 0x95C3, 0xBE69, 0x95C4, 0xBE6B, - 0x95C5, 0xBE6C, 0x95C6, 0xBE6D, 0x95C7, 0xBE6E, 0x95C8, 0xBE6F, 0x95C9, 0xBE72, 0x95CA, 0xBE76, 0x95CB, 0xBE77, 0x95CC, 0xBE78, - 0x95CD, 0xBE79, 0x95CE, 0xBE7A, 0x95CF, 0xBE7E, 0x95D0, 0xBE7F, 0x95D1, 0xBE81, 0x95D2, 0xBE82, 0x95D3, 0xBE83, 0x95D4, 0xBE85, - 0x95D5, 0xBE86, 0x95D6, 0xBE87, 0x95D7, 0xBE88, 0x95D8, 0xBE89, 0x95D9, 0xBE8A, 0x95DA, 0xBE8B, 0x95DB, 0xBE8E, 0x95DC, 0xBE92, - 0x95DD, 0xBE93, 0x95DE, 0xBE94, 0x95DF, 0xBE95, 0x95E0, 0xBE96, 0x95E1, 0xBE97, 0x95E2, 0xBE9A, 0x95E3, 0xBE9B, 0x95E4, 0xBE9C, - 0x95E5, 0xBE9D, 0x95E6, 0xBE9E, 0x95E7, 0xBE9F, 0x95E8, 0xBEA0, 0x95E9, 0xBEA1, 0x95EA, 0xBEA2, 0x95EB, 0xBEA3, 0x95EC, 0xBEA4, - 0x95ED, 0xBEA5, 0x95EE, 0xBEA6, 0x95EF, 0xBEA7, 0x95F0, 0xBEA9, 0x95F1, 0xBEAA, 0x95F2, 0xBEAB, 0x95F3, 0xBEAC, 0x95F4, 0xBEAD, - 0x95F5, 0xBEAE, 0x95F6, 0xBEAF, 0x95F7, 0xBEB0, 0x95F8, 0xBEB1, 0x95F9, 0xBEB2, 0x95FA, 0xBEB3, 0x95FB, 0xBEB4, 0x95FC, 0xBEB5, - 0x95FD, 0xBEB6, 0x95FE, 0xBEB7, 0x9641, 0xBEB8, 0x9642, 0xBEB9, 0x9643, 0xBEBA, 0x9644, 0xBEBB, 0x9645, 0xBEBC, 0x9646, 0xBEBD, - 0x9647, 0xBEBE, 0x9648, 0xBEBF, 0x9649, 0xBEC0, 0x964A, 0xBEC1, 0x964B, 0xBEC2, 0x964C, 0xBEC3, 0x964D, 0xBEC4, 0x964E, 0xBEC5, - 0x964F, 0xBEC6, 0x9650, 0xBEC7, 0x9651, 0xBEC8, 0x9652, 0xBEC9, 0x9653, 0xBECA, 0x9654, 0xBECB, 0x9655, 0xBECC, 0x9656, 0xBECD, - 0x9657, 0xBECE, 0x9658, 0xBECF, 0x9659, 0xBED2, 0x965A, 0xBED3, 0x9661, 0xBED5, 0x9662, 0xBED6, 0x9663, 0xBED9, 0x9664, 0xBEDA, - 0x9665, 0xBEDB, 0x9666, 0xBEDC, 0x9667, 0xBEDD, 0x9668, 0xBEDE, 0x9669, 0xBEDF, 0x966A, 0xBEE1, 0x966B, 0xBEE2, 0x966C, 0xBEE6, - 0x966D, 0xBEE7, 0x966E, 0xBEE8, 0x966F, 0xBEE9, 0x9670, 0xBEEA, 0x9671, 0xBEEB, 0x9672, 0xBEED, 0x9673, 0xBEEE, 0x9674, 0xBEEF, - 0x9675, 0xBEF0, 0x9676, 0xBEF1, 0x9677, 0xBEF2, 0x9678, 0xBEF3, 0x9679, 0xBEF4, 0x967A, 0xBEF5, 0x9681, 0xBEF6, 0x9682, 0xBEF7, - 0x9683, 0xBEF8, 0x9684, 0xBEF9, 0x9685, 0xBEFA, 0x9686, 0xBEFB, 0x9687, 0xBEFC, 0x9688, 0xBEFD, 0x9689, 0xBEFE, 0x968A, 0xBEFF, - 0x968B, 0xBF00, 0x968C, 0xBF02, 0x968D, 0xBF03, 0x968E, 0xBF04, 0x968F, 0xBF05, 0x9690, 0xBF06, 0x9691, 0xBF07, 0x9692, 0xBF0A, - 0x9693, 0xBF0B, 0x9694, 0xBF0C, 0x9695, 0xBF0D, 0x9696, 0xBF0E, 0x9697, 0xBF0F, 0x9698, 0xBF10, 0x9699, 0xBF11, 0x969A, 0xBF12, - 0x969B, 0xBF13, 0x969C, 0xBF14, 0x969D, 0xBF15, 0x969E, 0xBF16, 0x969F, 0xBF17, 0x96A0, 0xBF1A, 0x96A1, 0xBF1E, 0x96A2, 0xBF1F, - 0x96A3, 0xBF20, 0x96A4, 0xBF21, 0x96A5, 0xBF22, 0x96A6, 0xBF23, 0x96A7, 0xBF24, 0x96A8, 0xBF25, 0x96A9, 0xBF26, 0x96AA, 0xBF27, - 0x96AB, 0xBF28, 0x96AC, 0xBF29, 0x96AD, 0xBF2A, 0x96AE, 0xBF2B, 0x96AF, 0xBF2C, 0x96B0, 0xBF2D, 0x96B1, 0xBF2E, 0x96B2, 0xBF2F, - 0x96B3, 0xBF30, 0x96B4, 0xBF31, 0x96B5, 0xBF32, 0x96B6, 0xBF33, 0x96B7, 0xBF34, 0x96B8, 0xBF35, 0x96B9, 0xBF36, 0x96BA, 0xBF37, - 0x96BB, 0xBF38, 0x96BC, 0xBF39, 0x96BD, 0xBF3A, 0x96BE, 0xBF3B, 0x96BF, 0xBF3C, 0x96C0, 0xBF3D, 0x96C1, 0xBF3E, 0x96C2, 0xBF3F, - 0x96C3, 0xBF42, 0x96C4, 0xBF43, 0x96C5, 0xBF45, 0x96C6, 0xBF46, 0x96C7, 0xBF47, 0x96C8, 0xBF49, 0x96C9, 0xBF4A, 0x96CA, 0xBF4B, - 0x96CB, 0xBF4C, 0x96CC, 0xBF4D, 0x96CD, 0xBF4E, 0x96CE, 0xBF4F, 0x96CF, 0xBF52, 0x96D0, 0xBF53, 0x96D1, 0xBF54, 0x96D2, 0xBF56, - 0x96D3, 0xBF57, 0x96D4, 0xBF58, 0x96D5, 0xBF59, 0x96D6, 0xBF5A, 0x96D7, 0xBF5B, 0x96D8, 0xBF5C, 0x96D9, 0xBF5D, 0x96DA, 0xBF5E, - 0x96DB, 0xBF5F, 0x96DC, 0xBF60, 0x96DD, 0xBF61, 0x96DE, 0xBF62, 0x96DF, 0xBF63, 0x96E0, 0xBF64, 0x96E1, 0xBF65, 0x96E2, 0xBF66, - 0x96E3, 0xBF67, 0x96E4, 0xBF68, 0x96E5, 0xBF69, 0x96E6, 0xBF6A, 0x96E7, 0xBF6B, 0x96E8, 0xBF6C, 0x96E9, 0xBF6D, 0x96EA, 0xBF6E, - 0x96EB, 0xBF6F, 0x96EC, 0xBF70, 0x96ED, 0xBF71, 0x96EE, 0xBF72, 0x96EF, 0xBF73, 0x96F0, 0xBF74, 0x96F1, 0xBF75, 0x96F2, 0xBF76, - 0x96F3, 0xBF77, 0x96F4, 0xBF78, 0x96F5, 0xBF79, 0x96F6, 0xBF7A, 0x96F7, 0xBF7B, 0x96F8, 0xBF7C, 0x96F9, 0xBF7D, 0x96FA, 0xBF7E, - 0x96FB, 0xBF7F, 0x96FC, 0xBF80, 0x96FD, 0xBF81, 0x96FE, 0xBF82, 0x9741, 0xBF83, 0x9742, 0xBF84, 0x9743, 0xBF85, 0x9744, 0xBF86, - 0x9745, 0xBF87, 0x9746, 0xBF88, 0x9747, 0xBF89, 0x9748, 0xBF8A, 0x9749, 0xBF8B, 0x974A, 0xBF8C, 0x974B, 0xBF8D, 0x974C, 0xBF8E, - 0x974D, 0xBF8F, 0x974E, 0xBF90, 0x974F, 0xBF91, 0x9750, 0xBF92, 0x9751, 0xBF93, 0x9752, 0xBF95, 0x9753, 0xBF96, 0x9754, 0xBF97, - 0x9755, 0xBF98, 0x9756, 0xBF99, 0x9757, 0xBF9A, 0x9758, 0xBF9B, 0x9759, 0xBF9C, 0x975A, 0xBF9D, 0x9761, 0xBF9E, 0x9762, 0xBF9F, - 0x9763, 0xBFA0, 0x9764, 0xBFA1, 0x9765, 0xBFA2, 0x9766, 0xBFA3, 0x9767, 0xBFA4, 0x9768, 0xBFA5, 0x9769, 0xBFA6, 0x976A, 0xBFA7, - 0x976B, 0xBFA8, 0x976C, 0xBFA9, 0x976D, 0xBFAA, 0x976E, 0xBFAB, 0x976F, 0xBFAC, 0x9770, 0xBFAD, 0x9771, 0xBFAE, 0x9772, 0xBFAF, - 0x9773, 0xBFB1, 0x9774, 0xBFB2, 0x9775, 0xBFB3, 0x9776, 0xBFB4, 0x9777, 0xBFB5, 0x9778, 0xBFB6, 0x9779, 0xBFB7, 0x977A, 0xBFB8, - 0x9781, 0xBFB9, 0x9782, 0xBFBA, 0x9783, 0xBFBB, 0x9784, 0xBFBC, 0x9785, 0xBFBD, 0x9786, 0xBFBE, 0x9787, 0xBFBF, 0x9788, 0xBFC0, - 0x9789, 0xBFC1, 0x978A, 0xBFC2, 0x978B, 0xBFC3, 0x978C, 0xBFC4, 0x978D, 0xBFC6, 0x978E, 0xBFC7, 0x978F, 0xBFC8, 0x9790, 0xBFC9, - 0x9791, 0xBFCA, 0x9792, 0xBFCB, 0x9793, 0xBFCE, 0x9794, 0xBFCF, 0x9795, 0xBFD1, 0x9796, 0xBFD2, 0x9797, 0xBFD3, 0x9798, 0xBFD5, - 0x9799, 0xBFD6, 0x979A, 0xBFD7, 0x979B, 0xBFD8, 0x979C, 0xBFD9, 0x979D, 0xBFDA, 0x979E, 0xBFDB, 0x979F, 0xBFDD, 0x97A0, 0xBFDE, - 0x97A1, 0xBFE0, 0x97A2, 0xBFE2, 0x97A3, 0xBFE3, 0x97A4, 0xBFE4, 0x97A5, 0xBFE5, 0x97A6, 0xBFE6, 0x97A7, 0xBFE7, 0x97A8, 0xBFE8, - 0x97A9, 0xBFE9, 0x97AA, 0xBFEA, 0x97AB, 0xBFEB, 0x97AC, 0xBFEC, 0x97AD, 0xBFED, 0x97AE, 0xBFEE, 0x97AF, 0xBFEF, 0x97B0, 0xBFF0, - 0x97B1, 0xBFF1, 0x97B2, 0xBFF2, 0x97B3, 0xBFF3, 0x97B4, 0xBFF4, 0x97B5, 0xBFF5, 0x97B6, 0xBFF6, 0x97B7, 0xBFF7, 0x97B8, 0xBFF8, - 0x97B9, 0xBFF9, 0x97BA, 0xBFFA, 0x97BB, 0xBFFB, 0x97BC, 0xBFFC, 0x97BD, 0xBFFD, 0x97BE, 0xBFFE, 0x97BF, 0xBFFF, 0x97C0, 0xC000, - 0x97C1, 0xC001, 0x97C2, 0xC002, 0x97C3, 0xC003, 0x97C4, 0xC004, 0x97C5, 0xC005, 0x97C6, 0xC006, 0x97C7, 0xC007, 0x97C8, 0xC008, - 0x97C9, 0xC009, 0x97CA, 0xC00A, 0x97CB, 0xC00B, 0x97CC, 0xC00C, 0x97CD, 0xC00D, 0x97CE, 0xC00E, 0x97CF, 0xC00F, 0x97D0, 0xC010, - 0x97D1, 0xC011, 0x97D2, 0xC012, 0x97D3, 0xC013, 0x97D4, 0xC014, 0x97D5, 0xC015, 0x97D6, 0xC016, 0x97D7, 0xC017, 0x97D8, 0xC018, - 0x97D9, 0xC019, 0x97DA, 0xC01A, 0x97DB, 0xC01B, 0x97DC, 0xC01C, 0x97DD, 0xC01D, 0x97DE, 0xC01E, 0x97DF, 0xC01F, 0x97E0, 0xC020, - 0x97E1, 0xC021, 0x97E2, 0xC022, 0x97E3, 0xC023, 0x97E4, 0xC024, 0x97E5, 0xC025, 0x97E6, 0xC026, 0x97E7, 0xC027, 0x97E8, 0xC028, - 0x97E9, 0xC029, 0x97EA, 0xC02A, 0x97EB, 0xC02B, 0x97EC, 0xC02C, 0x97ED, 0xC02D, 0x97EE, 0xC02E, 0x97EF, 0xC02F, 0x97F0, 0xC030, - 0x97F1, 0xC031, 0x97F2, 0xC032, 0x97F3, 0xC033, 0x97F4, 0xC034, 0x97F5, 0xC035, 0x97F6, 0xC036, 0x97F7, 0xC037, 0x97F8, 0xC038, - 0x97F9, 0xC039, 0x97FA, 0xC03A, 0x97FB, 0xC03B, 0x97FC, 0xC03D, 0x97FD, 0xC03E, 0x97FE, 0xC03F, 0x9841, 0xC040, 0x9842, 0xC041, - 0x9843, 0xC042, 0x9844, 0xC043, 0x9845, 0xC044, 0x9846, 0xC045, 0x9847, 0xC046, 0x9848, 0xC047, 0x9849, 0xC048, 0x984A, 0xC049, - 0x984B, 0xC04A, 0x984C, 0xC04B, 0x984D, 0xC04C, 0x984E, 0xC04D, 0x984F, 0xC04E, 0x9850, 0xC04F, 0x9851, 0xC050, 0x9852, 0xC052, - 0x9853, 0xC053, 0x9854, 0xC054, 0x9855, 0xC055, 0x9856, 0xC056, 0x9857, 0xC057, 0x9858, 0xC059, 0x9859, 0xC05A, 0x985A, 0xC05B, - 0x9861, 0xC05D, 0x9862, 0xC05E, 0x9863, 0xC05F, 0x9864, 0xC061, 0x9865, 0xC062, 0x9866, 0xC063, 0x9867, 0xC064, 0x9868, 0xC065, - 0x9869, 0xC066, 0x986A, 0xC067, 0x986B, 0xC06A, 0x986C, 0xC06B, 0x986D, 0xC06C, 0x986E, 0xC06D, 0x986F, 0xC06E, 0x9870, 0xC06F, - 0x9871, 0xC070, 0x9872, 0xC071, 0x9873, 0xC072, 0x9874, 0xC073, 0x9875, 0xC074, 0x9876, 0xC075, 0x9877, 0xC076, 0x9878, 0xC077, - 0x9879, 0xC078, 0x987A, 0xC079, 0x9881, 0xC07A, 0x9882, 0xC07B, 0x9883, 0xC07C, 0x9884, 0xC07D, 0x9885, 0xC07E, 0x9886, 0xC07F, - 0x9887, 0xC080, 0x9888, 0xC081, 0x9889, 0xC082, 0x988A, 0xC083, 0x988B, 0xC084, 0x988C, 0xC085, 0x988D, 0xC086, 0x988E, 0xC087, - 0x988F, 0xC088, 0x9890, 0xC089, 0x9891, 0xC08A, 0x9892, 0xC08B, 0x9893, 0xC08C, 0x9894, 0xC08D, 0x9895, 0xC08E, 0x9896, 0xC08F, - 0x9897, 0xC092, 0x9898, 0xC093, 0x9899, 0xC095, 0x989A, 0xC096, 0x989B, 0xC097, 0x989C, 0xC099, 0x989D, 0xC09A, 0x989E, 0xC09B, - 0x989F, 0xC09C, 0x98A0, 0xC09D, 0x98A1, 0xC09E, 0x98A2, 0xC09F, 0x98A3, 0xC0A2, 0x98A4, 0xC0A4, 0x98A5, 0xC0A6, 0x98A6, 0xC0A7, - 0x98A7, 0xC0A8, 0x98A8, 0xC0A9, 0x98A9, 0xC0AA, 0x98AA, 0xC0AB, 0x98AB, 0xC0AE, 0x98AC, 0xC0B1, 0x98AD, 0xC0B2, 0x98AE, 0xC0B7, - 0x98AF, 0xC0B8, 0x98B0, 0xC0B9, 0x98B1, 0xC0BA, 0x98B2, 0xC0BB, 0x98B3, 0xC0BE, 0x98B4, 0xC0C2, 0x98B5, 0xC0C3, 0x98B6, 0xC0C4, - 0x98B7, 0xC0C6, 0x98B8, 0xC0C7, 0x98B9, 0xC0CA, 0x98BA, 0xC0CB, 0x98BB, 0xC0CD, 0x98BC, 0xC0CE, 0x98BD, 0xC0CF, 0x98BE, 0xC0D1, - 0x98BF, 0xC0D2, 0x98C0, 0xC0D3, 0x98C1, 0xC0D4, 0x98C2, 0xC0D5, 0x98C3, 0xC0D6, 0x98C4, 0xC0D7, 0x98C5, 0xC0DA, 0x98C6, 0xC0DE, - 0x98C7, 0xC0DF, 0x98C8, 0xC0E0, 0x98C9, 0xC0E1, 0x98CA, 0xC0E2, 0x98CB, 0xC0E3, 0x98CC, 0xC0E6, 0x98CD, 0xC0E7, 0x98CE, 0xC0E9, - 0x98CF, 0xC0EA, 0x98D0, 0xC0EB, 0x98D1, 0xC0ED, 0x98D2, 0xC0EE, 0x98D3, 0xC0EF, 0x98D4, 0xC0F0, 0x98D5, 0xC0F1, 0x98D6, 0xC0F2, - 0x98D7, 0xC0F3, 0x98D8, 0xC0F6, 0x98D9, 0xC0F8, 0x98DA, 0xC0FA, 0x98DB, 0xC0FB, 0x98DC, 0xC0FC, 0x98DD, 0xC0FD, 0x98DE, 0xC0FE, - 0x98DF, 0xC0FF, 0x98E0, 0xC101, 0x98E1, 0xC102, 0x98E2, 0xC103, 0x98E3, 0xC105, 0x98E4, 0xC106, 0x98E5, 0xC107, 0x98E6, 0xC109, - 0x98E7, 0xC10A, 0x98E8, 0xC10B, 0x98E9, 0xC10C, 0x98EA, 0xC10D, 0x98EB, 0xC10E, 0x98EC, 0xC10F, 0x98ED, 0xC111, 0x98EE, 0xC112, - 0x98EF, 0xC113, 0x98F0, 0xC114, 0x98F1, 0xC116, 0x98F2, 0xC117, 0x98F3, 0xC118, 0x98F4, 0xC119, 0x98F5, 0xC11A, 0x98F6, 0xC11B, - 0x98F7, 0xC121, 0x98F8, 0xC122, 0x98F9, 0xC125, 0x98FA, 0xC128, 0x98FB, 0xC129, 0x98FC, 0xC12A, 0x98FD, 0xC12B, 0x98FE, 0xC12E, - 0x9941, 0xC132, 0x9942, 0xC133, 0x9943, 0xC134, 0x9944, 0xC135, 0x9945, 0xC137, 0x9946, 0xC13A, 0x9947, 0xC13B, 0x9948, 0xC13D, - 0x9949, 0xC13E, 0x994A, 0xC13F, 0x994B, 0xC141, 0x994C, 0xC142, 0x994D, 0xC143, 0x994E, 0xC144, 0x994F, 0xC145, 0x9950, 0xC146, - 0x9951, 0xC147, 0x9952, 0xC14A, 0x9953, 0xC14E, 0x9954, 0xC14F, 0x9955, 0xC150, 0x9956, 0xC151, 0x9957, 0xC152, 0x9958, 0xC153, - 0x9959, 0xC156, 0x995A, 0xC157, 0x9961, 0xC159, 0x9962, 0xC15A, 0x9963, 0xC15B, 0x9964, 0xC15D, 0x9965, 0xC15E, 0x9966, 0xC15F, - 0x9967, 0xC160, 0x9968, 0xC161, 0x9969, 0xC162, 0x996A, 0xC163, 0x996B, 0xC166, 0x996C, 0xC16A, 0x996D, 0xC16B, 0x996E, 0xC16C, - 0x996F, 0xC16D, 0x9970, 0xC16E, 0x9971, 0xC16F, 0x9972, 0xC171, 0x9973, 0xC172, 0x9974, 0xC173, 0x9975, 0xC175, 0x9976, 0xC176, - 0x9977, 0xC177, 0x9978, 0xC179, 0x9979, 0xC17A, 0x997A, 0xC17B, 0x9981, 0xC17C, 0x9982, 0xC17D, 0x9983, 0xC17E, 0x9984, 0xC17F, - 0x9985, 0xC180, 0x9986, 0xC181, 0x9987, 0xC182, 0x9988, 0xC183, 0x9989, 0xC184, 0x998A, 0xC186, 0x998B, 0xC187, 0x998C, 0xC188, - 0x998D, 0xC189, 0x998E, 0xC18A, 0x998F, 0xC18B, 0x9990, 0xC18F, 0x9991, 0xC191, 0x9992, 0xC192, 0x9993, 0xC193, 0x9994, 0xC195, - 0x9995, 0xC197, 0x9996, 0xC198, 0x9997, 0xC199, 0x9998, 0xC19A, 0x9999, 0xC19B, 0x999A, 0xC19E, 0x999B, 0xC1A0, 0x999C, 0xC1A2, - 0x999D, 0xC1A3, 0x999E, 0xC1A4, 0x999F, 0xC1A6, 0x99A0, 0xC1A7, 0x99A1, 0xC1AA, 0x99A2, 0xC1AB, 0x99A3, 0xC1AD, 0x99A4, 0xC1AE, - 0x99A5, 0xC1AF, 0x99A6, 0xC1B1, 0x99A7, 0xC1B2, 0x99A8, 0xC1B3, 0x99A9, 0xC1B4, 0x99AA, 0xC1B5, 0x99AB, 0xC1B6, 0x99AC, 0xC1B7, - 0x99AD, 0xC1B8, 0x99AE, 0xC1B9, 0x99AF, 0xC1BA, 0x99B0, 0xC1BB, 0x99B1, 0xC1BC, 0x99B2, 0xC1BE, 0x99B3, 0xC1BF, 0x99B4, 0xC1C0, - 0x99B5, 0xC1C1, 0x99B6, 0xC1C2, 0x99B7, 0xC1C3, 0x99B8, 0xC1C5, 0x99B9, 0xC1C6, 0x99BA, 0xC1C7, 0x99BB, 0xC1C9, 0x99BC, 0xC1CA, - 0x99BD, 0xC1CB, 0x99BE, 0xC1CD, 0x99BF, 0xC1CE, 0x99C0, 0xC1CF, 0x99C1, 0xC1D0, 0x99C2, 0xC1D1, 0x99C3, 0xC1D2, 0x99C4, 0xC1D3, - 0x99C5, 0xC1D5, 0x99C6, 0xC1D6, 0x99C7, 0xC1D9, 0x99C8, 0xC1DA, 0x99C9, 0xC1DB, 0x99CA, 0xC1DC, 0x99CB, 0xC1DD, 0x99CC, 0xC1DE, - 0x99CD, 0xC1DF, 0x99CE, 0xC1E1, 0x99CF, 0xC1E2, 0x99D0, 0xC1E3, 0x99D1, 0xC1E5, 0x99D2, 0xC1E6, 0x99D3, 0xC1E7, 0x99D4, 0xC1E9, - 0x99D5, 0xC1EA, 0x99D6, 0xC1EB, 0x99D7, 0xC1EC, 0x99D8, 0xC1ED, 0x99D9, 0xC1EE, 0x99DA, 0xC1EF, 0x99DB, 0xC1F2, 0x99DC, 0xC1F4, - 0x99DD, 0xC1F5, 0x99DE, 0xC1F6, 0x99DF, 0xC1F7, 0x99E0, 0xC1F8, 0x99E1, 0xC1F9, 0x99E2, 0xC1FA, 0x99E3, 0xC1FB, 0x99E4, 0xC1FE, - 0x99E5, 0xC1FF, 0x99E6, 0xC201, 0x99E7, 0xC202, 0x99E8, 0xC203, 0x99E9, 0xC205, 0x99EA, 0xC206, 0x99EB, 0xC207, 0x99EC, 0xC208, - 0x99ED, 0xC209, 0x99EE, 0xC20A, 0x99EF, 0xC20B, 0x99F0, 0xC20E, 0x99F1, 0xC210, 0x99F2, 0xC212, 0x99F3, 0xC213, 0x99F4, 0xC214, - 0x99F5, 0xC215, 0x99F6, 0xC216, 0x99F7, 0xC217, 0x99F8, 0xC21A, 0x99F9, 0xC21B, 0x99FA, 0xC21D, 0x99FB, 0xC21E, 0x99FC, 0xC221, - 0x99FD, 0xC222, 0x99FE, 0xC223, 0x9A41, 0xC224, 0x9A42, 0xC225, 0x9A43, 0xC226, 0x9A44, 0xC227, 0x9A45, 0xC22A, 0x9A46, 0xC22C, - 0x9A47, 0xC22E, 0x9A48, 0xC230, 0x9A49, 0xC233, 0x9A4A, 0xC235, 0x9A4B, 0xC236, 0x9A4C, 0xC237, 0x9A4D, 0xC238, 0x9A4E, 0xC239, - 0x9A4F, 0xC23A, 0x9A50, 0xC23B, 0x9A51, 0xC23C, 0x9A52, 0xC23D, 0x9A53, 0xC23E, 0x9A54, 0xC23F, 0x9A55, 0xC240, 0x9A56, 0xC241, - 0x9A57, 0xC242, 0x9A58, 0xC243, 0x9A59, 0xC244, 0x9A5A, 0xC245, 0x9A61, 0xC246, 0x9A62, 0xC247, 0x9A63, 0xC249, 0x9A64, 0xC24A, - 0x9A65, 0xC24B, 0x9A66, 0xC24C, 0x9A67, 0xC24D, 0x9A68, 0xC24E, 0x9A69, 0xC24F, 0x9A6A, 0xC252, 0x9A6B, 0xC253, 0x9A6C, 0xC255, - 0x9A6D, 0xC256, 0x9A6E, 0xC257, 0x9A6F, 0xC259, 0x9A70, 0xC25A, 0x9A71, 0xC25B, 0x9A72, 0xC25C, 0x9A73, 0xC25D, 0x9A74, 0xC25E, - 0x9A75, 0xC25F, 0x9A76, 0xC261, 0x9A77, 0xC262, 0x9A78, 0xC263, 0x9A79, 0xC264, 0x9A7A, 0xC266, 0x9A81, 0xC267, 0x9A82, 0xC268, - 0x9A83, 0xC269, 0x9A84, 0xC26A, 0x9A85, 0xC26B, 0x9A86, 0xC26E, 0x9A87, 0xC26F, 0x9A88, 0xC271, 0x9A89, 0xC272, 0x9A8A, 0xC273, - 0x9A8B, 0xC275, 0x9A8C, 0xC276, 0x9A8D, 0xC277, 0x9A8E, 0xC278, 0x9A8F, 0xC279, 0x9A90, 0xC27A, 0x9A91, 0xC27B, 0x9A92, 0xC27E, - 0x9A93, 0xC280, 0x9A94, 0xC282, 0x9A95, 0xC283, 0x9A96, 0xC284, 0x9A97, 0xC285, 0x9A98, 0xC286, 0x9A99, 0xC287, 0x9A9A, 0xC28A, - 0x9A9B, 0xC28B, 0x9A9C, 0xC28C, 0x9A9D, 0xC28D, 0x9A9E, 0xC28E, 0x9A9F, 0xC28F, 0x9AA0, 0xC291, 0x9AA1, 0xC292, 0x9AA2, 0xC293, - 0x9AA3, 0xC294, 0x9AA4, 0xC295, 0x9AA5, 0xC296, 0x9AA6, 0xC297, 0x9AA7, 0xC299, 0x9AA8, 0xC29A, 0x9AA9, 0xC29C, 0x9AAA, 0xC29E, - 0x9AAB, 0xC29F, 0x9AAC, 0xC2A0, 0x9AAD, 0xC2A1, 0x9AAE, 0xC2A2, 0x9AAF, 0xC2A3, 0x9AB0, 0xC2A6, 0x9AB1, 0xC2A7, 0x9AB2, 0xC2A9, - 0x9AB3, 0xC2AA, 0x9AB4, 0xC2AB, 0x9AB5, 0xC2AE, 0x9AB6, 0xC2AF, 0x9AB7, 0xC2B0, 0x9AB8, 0xC2B1, 0x9AB9, 0xC2B2, 0x9ABA, 0xC2B3, - 0x9ABB, 0xC2B6, 0x9ABC, 0xC2B8, 0x9ABD, 0xC2BA, 0x9ABE, 0xC2BB, 0x9ABF, 0xC2BC, 0x9AC0, 0xC2BD, 0x9AC1, 0xC2BE, 0x9AC2, 0xC2BF, - 0x9AC3, 0xC2C0, 0x9AC4, 0xC2C1, 0x9AC5, 0xC2C2, 0x9AC6, 0xC2C3, 0x9AC7, 0xC2C4, 0x9AC8, 0xC2C5, 0x9AC9, 0xC2C6, 0x9ACA, 0xC2C7, - 0x9ACB, 0xC2C8, 0x9ACC, 0xC2C9, 0x9ACD, 0xC2CA, 0x9ACE, 0xC2CB, 0x9ACF, 0xC2CC, 0x9AD0, 0xC2CD, 0x9AD1, 0xC2CE, 0x9AD2, 0xC2CF, - 0x9AD3, 0xC2D0, 0x9AD4, 0xC2D1, 0x9AD5, 0xC2D2, 0x9AD6, 0xC2D3, 0x9AD7, 0xC2D4, 0x9AD8, 0xC2D5, 0x9AD9, 0xC2D6, 0x9ADA, 0xC2D7, - 0x9ADB, 0xC2D8, 0x9ADC, 0xC2D9, 0x9ADD, 0xC2DA, 0x9ADE, 0xC2DB, 0x9ADF, 0xC2DE, 0x9AE0, 0xC2DF, 0x9AE1, 0xC2E1, 0x9AE2, 0xC2E2, - 0x9AE3, 0xC2E5, 0x9AE4, 0xC2E6, 0x9AE5, 0xC2E7, 0x9AE6, 0xC2E8, 0x9AE7, 0xC2E9, 0x9AE8, 0xC2EA, 0x9AE9, 0xC2EE, 0x9AEA, 0xC2F0, - 0x9AEB, 0xC2F2, 0x9AEC, 0xC2F3, 0x9AED, 0xC2F4, 0x9AEE, 0xC2F5, 0x9AEF, 0xC2F7, 0x9AF0, 0xC2FA, 0x9AF1, 0xC2FD, 0x9AF2, 0xC2FE, - 0x9AF3, 0xC2FF, 0x9AF4, 0xC301, 0x9AF5, 0xC302, 0x9AF6, 0xC303, 0x9AF7, 0xC304, 0x9AF8, 0xC305, 0x9AF9, 0xC306, 0x9AFA, 0xC307, - 0x9AFB, 0xC30A, 0x9AFC, 0xC30B, 0x9AFD, 0xC30E, 0x9AFE, 0xC30F, 0x9B41, 0xC310, 0x9B42, 0xC311, 0x9B43, 0xC312, 0x9B44, 0xC316, - 0x9B45, 0xC317, 0x9B46, 0xC319, 0x9B47, 0xC31A, 0x9B48, 0xC31B, 0x9B49, 0xC31D, 0x9B4A, 0xC31E, 0x9B4B, 0xC31F, 0x9B4C, 0xC320, - 0x9B4D, 0xC321, 0x9B4E, 0xC322, 0x9B4F, 0xC323, 0x9B50, 0xC326, 0x9B51, 0xC327, 0x9B52, 0xC32A, 0x9B53, 0xC32B, 0x9B54, 0xC32C, - 0x9B55, 0xC32D, 0x9B56, 0xC32E, 0x9B57, 0xC32F, 0x9B58, 0xC330, 0x9B59, 0xC331, 0x9B5A, 0xC332, 0x9B61, 0xC333, 0x9B62, 0xC334, - 0x9B63, 0xC335, 0x9B64, 0xC336, 0x9B65, 0xC337, 0x9B66, 0xC338, 0x9B67, 0xC339, 0x9B68, 0xC33A, 0x9B69, 0xC33B, 0x9B6A, 0xC33C, - 0x9B6B, 0xC33D, 0x9B6C, 0xC33E, 0x9B6D, 0xC33F, 0x9B6E, 0xC340, 0x9B6F, 0xC341, 0x9B70, 0xC342, 0x9B71, 0xC343, 0x9B72, 0xC344, - 0x9B73, 0xC346, 0x9B74, 0xC347, 0x9B75, 0xC348, 0x9B76, 0xC349, 0x9B77, 0xC34A, 0x9B78, 0xC34B, 0x9B79, 0xC34C, 0x9B7A, 0xC34D, - 0x9B81, 0xC34E, 0x9B82, 0xC34F, 0x9B83, 0xC350, 0x9B84, 0xC351, 0x9B85, 0xC352, 0x9B86, 0xC353, 0x9B87, 0xC354, 0x9B88, 0xC355, - 0x9B89, 0xC356, 0x9B8A, 0xC357, 0x9B8B, 0xC358, 0x9B8C, 0xC359, 0x9B8D, 0xC35A, 0x9B8E, 0xC35B, 0x9B8F, 0xC35C, 0x9B90, 0xC35D, - 0x9B91, 0xC35E, 0x9B92, 0xC35F, 0x9B93, 0xC360, 0x9B94, 0xC361, 0x9B95, 0xC362, 0x9B96, 0xC363, 0x9B97, 0xC364, 0x9B98, 0xC365, - 0x9B99, 0xC366, 0x9B9A, 0xC367, 0x9B9B, 0xC36A, 0x9B9C, 0xC36B, 0x9B9D, 0xC36D, 0x9B9E, 0xC36E, 0x9B9F, 0xC36F, 0x9BA0, 0xC371, - 0x9BA1, 0xC373, 0x9BA2, 0xC374, 0x9BA3, 0xC375, 0x9BA4, 0xC376, 0x9BA5, 0xC377, 0x9BA6, 0xC37A, 0x9BA7, 0xC37B, 0x9BA8, 0xC37E, - 0x9BA9, 0xC37F, 0x9BAA, 0xC380, 0x9BAB, 0xC381, 0x9BAC, 0xC382, 0x9BAD, 0xC383, 0x9BAE, 0xC385, 0x9BAF, 0xC386, 0x9BB0, 0xC387, - 0x9BB1, 0xC389, 0x9BB2, 0xC38A, 0x9BB3, 0xC38B, 0x9BB4, 0xC38D, 0x9BB5, 0xC38E, 0x9BB6, 0xC38F, 0x9BB7, 0xC390, 0x9BB8, 0xC391, - 0x9BB9, 0xC392, 0x9BBA, 0xC393, 0x9BBB, 0xC394, 0x9BBC, 0xC395, 0x9BBD, 0xC396, 0x9BBE, 0xC397, 0x9BBF, 0xC398, 0x9BC0, 0xC399, - 0x9BC1, 0xC39A, 0x9BC2, 0xC39B, 0x9BC3, 0xC39C, 0x9BC4, 0xC39D, 0x9BC5, 0xC39E, 0x9BC6, 0xC39F, 0x9BC7, 0xC3A0, 0x9BC8, 0xC3A1, - 0x9BC9, 0xC3A2, 0x9BCA, 0xC3A3, 0x9BCB, 0xC3A4, 0x9BCC, 0xC3A5, 0x9BCD, 0xC3A6, 0x9BCE, 0xC3A7, 0x9BCF, 0xC3A8, 0x9BD0, 0xC3A9, - 0x9BD1, 0xC3AA, 0x9BD2, 0xC3AB, 0x9BD3, 0xC3AC, 0x9BD4, 0xC3AD, 0x9BD5, 0xC3AE, 0x9BD6, 0xC3AF, 0x9BD7, 0xC3B0, 0x9BD8, 0xC3B1, - 0x9BD9, 0xC3B2, 0x9BDA, 0xC3B3, 0x9BDB, 0xC3B4, 0x9BDC, 0xC3B5, 0x9BDD, 0xC3B6, 0x9BDE, 0xC3B7, 0x9BDF, 0xC3B8, 0x9BE0, 0xC3B9, - 0x9BE1, 0xC3BA, 0x9BE2, 0xC3BB, 0x9BE3, 0xC3BC, 0x9BE4, 0xC3BD, 0x9BE5, 0xC3BE, 0x9BE6, 0xC3BF, 0x9BE7, 0xC3C1, 0x9BE8, 0xC3C2, - 0x9BE9, 0xC3C3, 0x9BEA, 0xC3C4, 0x9BEB, 0xC3C5, 0x9BEC, 0xC3C6, 0x9BED, 0xC3C7, 0x9BEE, 0xC3C8, 0x9BEF, 0xC3C9, 0x9BF0, 0xC3CA, - 0x9BF1, 0xC3CB, 0x9BF2, 0xC3CC, 0x9BF3, 0xC3CD, 0x9BF4, 0xC3CE, 0x9BF5, 0xC3CF, 0x9BF6, 0xC3D0, 0x9BF7, 0xC3D1, 0x9BF8, 0xC3D2, - 0x9BF9, 0xC3D3, 0x9BFA, 0xC3D4, 0x9BFB, 0xC3D5, 0x9BFC, 0xC3D6, 0x9BFD, 0xC3D7, 0x9BFE, 0xC3DA, 0x9C41, 0xC3DB, 0x9C42, 0xC3DD, - 0x9C43, 0xC3DE, 0x9C44, 0xC3E1, 0x9C45, 0xC3E3, 0x9C46, 0xC3E4, 0x9C47, 0xC3E5, 0x9C48, 0xC3E6, 0x9C49, 0xC3E7, 0x9C4A, 0xC3EA, - 0x9C4B, 0xC3EB, 0x9C4C, 0xC3EC, 0x9C4D, 0xC3EE, 0x9C4E, 0xC3EF, 0x9C4F, 0xC3F0, 0x9C50, 0xC3F1, 0x9C51, 0xC3F2, 0x9C52, 0xC3F3, - 0x9C53, 0xC3F6, 0x9C54, 0xC3F7, 0x9C55, 0xC3F9, 0x9C56, 0xC3FA, 0x9C57, 0xC3FB, 0x9C58, 0xC3FC, 0x9C59, 0xC3FD, 0x9C5A, 0xC3FE, - 0x9C61, 0xC3FF, 0x9C62, 0xC400, 0x9C63, 0xC401, 0x9C64, 0xC402, 0x9C65, 0xC403, 0x9C66, 0xC404, 0x9C67, 0xC405, 0x9C68, 0xC406, - 0x9C69, 0xC407, 0x9C6A, 0xC409, 0x9C6B, 0xC40A, 0x9C6C, 0xC40B, 0x9C6D, 0xC40C, 0x9C6E, 0xC40D, 0x9C6F, 0xC40E, 0x9C70, 0xC40F, - 0x9C71, 0xC411, 0x9C72, 0xC412, 0x9C73, 0xC413, 0x9C74, 0xC414, 0x9C75, 0xC415, 0x9C76, 0xC416, 0x9C77, 0xC417, 0x9C78, 0xC418, - 0x9C79, 0xC419, 0x9C7A, 0xC41A, 0x9C81, 0xC41B, 0x9C82, 0xC41C, 0x9C83, 0xC41D, 0x9C84, 0xC41E, 0x9C85, 0xC41F, 0x9C86, 0xC420, - 0x9C87, 0xC421, 0x9C88, 0xC422, 0x9C89, 0xC423, 0x9C8A, 0xC425, 0x9C8B, 0xC426, 0x9C8C, 0xC427, 0x9C8D, 0xC428, 0x9C8E, 0xC429, - 0x9C8F, 0xC42A, 0x9C90, 0xC42B, 0x9C91, 0xC42D, 0x9C92, 0xC42E, 0x9C93, 0xC42F, 0x9C94, 0xC431, 0x9C95, 0xC432, 0x9C96, 0xC433, - 0x9C97, 0xC435, 0x9C98, 0xC436, 0x9C99, 0xC437, 0x9C9A, 0xC438, 0x9C9B, 0xC439, 0x9C9C, 0xC43A, 0x9C9D, 0xC43B, 0x9C9E, 0xC43E, - 0x9C9F, 0xC43F, 0x9CA0, 0xC440, 0x9CA1, 0xC441, 0x9CA2, 0xC442, 0x9CA3, 0xC443, 0x9CA4, 0xC444, 0x9CA5, 0xC445, 0x9CA6, 0xC446, - 0x9CA7, 0xC447, 0x9CA8, 0xC449, 0x9CA9, 0xC44A, 0x9CAA, 0xC44B, 0x9CAB, 0xC44C, 0x9CAC, 0xC44D, 0x9CAD, 0xC44E, 0x9CAE, 0xC44F, - 0x9CAF, 0xC450, 0x9CB0, 0xC451, 0x9CB1, 0xC452, 0x9CB2, 0xC453, 0x9CB3, 0xC454, 0x9CB4, 0xC455, 0x9CB5, 0xC456, 0x9CB6, 0xC457, - 0x9CB7, 0xC458, 0x9CB8, 0xC459, 0x9CB9, 0xC45A, 0x9CBA, 0xC45B, 0x9CBB, 0xC45C, 0x9CBC, 0xC45D, 0x9CBD, 0xC45E, 0x9CBE, 0xC45F, - 0x9CBF, 0xC460, 0x9CC0, 0xC461, 0x9CC1, 0xC462, 0x9CC2, 0xC463, 0x9CC3, 0xC466, 0x9CC4, 0xC467, 0x9CC5, 0xC469, 0x9CC6, 0xC46A, - 0x9CC7, 0xC46B, 0x9CC8, 0xC46D, 0x9CC9, 0xC46E, 0x9CCA, 0xC46F, 0x9CCB, 0xC470, 0x9CCC, 0xC471, 0x9CCD, 0xC472, 0x9CCE, 0xC473, - 0x9CCF, 0xC476, 0x9CD0, 0xC477, 0x9CD1, 0xC478, 0x9CD2, 0xC47A, 0x9CD3, 0xC47B, 0x9CD4, 0xC47C, 0x9CD5, 0xC47D, 0x9CD6, 0xC47E, - 0x9CD7, 0xC47F, 0x9CD8, 0xC481, 0x9CD9, 0xC482, 0x9CDA, 0xC483, 0x9CDB, 0xC484, 0x9CDC, 0xC485, 0x9CDD, 0xC486, 0x9CDE, 0xC487, - 0x9CDF, 0xC488, 0x9CE0, 0xC489, 0x9CE1, 0xC48A, 0x9CE2, 0xC48B, 0x9CE3, 0xC48C, 0x9CE4, 0xC48D, 0x9CE5, 0xC48E, 0x9CE6, 0xC48F, - 0x9CE7, 0xC490, 0x9CE8, 0xC491, 0x9CE9, 0xC492, 0x9CEA, 0xC493, 0x9CEB, 0xC495, 0x9CEC, 0xC496, 0x9CED, 0xC497, 0x9CEE, 0xC498, - 0x9CEF, 0xC499, 0x9CF0, 0xC49A, 0x9CF1, 0xC49B, 0x9CF2, 0xC49D, 0x9CF3, 0xC49E, 0x9CF4, 0xC49F, 0x9CF5, 0xC4A0, 0x9CF6, 0xC4A1, - 0x9CF7, 0xC4A2, 0x9CF8, 0xC4A3, 0x9CF9, 0xC4A4, 0x9CFA, 0xC4A5, 0x9CFB, 0xC4A6, 0x9CFC, 0xC4A7, 0x9CFD, 0xC4A8, 0x9CFE, 0xC4A9, - 0x9D41, 0xC4AA, 0x9D42, 0xC4AB, 0x9D43, 0xC4AC, 0x9D44, 0xC4AD, 0x9D45, 0xC4AE, 0x9D46, 0xC4AF, 0x9D47, 0xC4B0, 0x9D48, 0xC4B1, - 0x9D49, 0xC4B2, 0x9D4A, 0xC4B3, 0x9D4B, 0xC4B4, 0x9D4C, 0xC4B5, 0x9D4D, 0xC4B6, 0x9D4E, 0xC4B7, 0x9D4F, 0xC4B9, 0x9D50, 0xC4BA, - 0x9D51, 0xC4BB, 0x9D52, 0xC4BD, 0x9D53, 0xC4BE, 0x9D54, 0xC4BF, 0x9D55, 0xC4C0, 0x9D56, 0xC4C1, 0x9D57, 0xC4C2, 0x9D58, 0xC4C3, - 0x9D59, 0xC4C4, 0x9D5A, 0xC4C5, 0x9D61, 0xC4C6, 0x9D62, 0xC4C7, 0x9D63, 0xC4C8, 0x9D64, 0xC4C9, 0x9D65, 0xC4CA, 0x9D66, 0xC4CB, - 0x9D67, 0xC4CC, 0x9D68, 0xC4CD, 0x9D69, 0xC4CE, 0x9D6A, 0xC4CF, 0x9D6B, 0xC4D0, 0x9D6C, 0xC4D1, 0x9D6D, 0xC4D2, 0x9D6E, 0xC4D3, - 0x9D6F, 0xC4D4, 0x9D70, 0xC4D5, 0x9D71, 0xC4D6, 0x9D72, 0xC4D7, 0x9D73, 0xC4D8, 0x9D74, 0xC4D9, 0x9D75, 0xC4DA, 0x9D76, 0xC4DB, - 0x9D77, 0xC4DC, 0x9D78, 0xC4DD, 0x9D79, 0xC4DE, 0x9D7A, 0xC4DF, 0x9D81, 0xC4E0, 0x9D82, 0xC4E1, 0x9D83, 0xC4E2, 0x9D84, 0xC4E3, - 0x9D85, 0xC4E4, 0x9D86, 0xC4E5, 0x9D87, 0xC4E6, 0x9D88, 0xC4E7, 0x9D89, 0xC4E8, 0x9D8A, 0xC4EA, 0x9D8B, 0xC4EB, 0x9D8C, 0xC4EC, - 0x9D8D, 0xC4ED, 0x9D8E, 0xC4EE, 0x9D8F, 0xC4EF, 0x9D90, 0xC4F2, 0x9D91, 0xC4F3, 0x9D92, 0xC4F5, 0x9D93, 0xC4F6, 0x9D94, 0xC4F7, - 0x9D95, 0xC4F9, 0x9D96, 0xC4FB, 0x9D97, 0xC4FC, 0x9D98, 0xC4FD, 0x9D99, 0xC4FE, 0x9D9A, 0xC502, 0x9D9B, 0xC503, 0x9D9C, 0xC504, - 0x9D9D, 0xC505, 0x9D9E, 0xC506, 0x9D9F, 0xC507, 0x9DA0, 0xC508, 0x9DA1, 0xC509, 0x9DA2, 0xC50A, 0x9DA3, 0xC50B, 0x9DA4, 0xC50D, - 0x9DA5, 0xC50E, 0x9DA6, 0xC50F, 0x9DA7, 0xC511, 0x9DA8, 0xC512, 0x9DA9, 0xC513, 0x9DAA, 0xC515, 0x9DAB, 0xC516, 0x9DAC, 0xC517, - 0x9DAD, 0xC518, 0x9DAE, 0xC519, 0x9DAF, 0xC51A, 0x9DB0, 0xC51B, 0x9DB1, 0xC51D, 0x9DB2, 0xC51E, 0x9DB3, 0xC51F, 0x9DB4, 0xC520, - 0x9DB5, 0xC521, 0x9DB6, 0xC522, 0x9DB7, 0xC523, 0x9DB8, 0xC524, 0x9DB9, 0xC525, 0x9DBA, 0xC526, 0x9DBB, 0xC527, 0x9DBC, 0xC52A, - 0x9DBD, 0xC52B, 0x9DBE, 0xC52D, 0x9DBF, 0xC52E, 0x9DC0, 0xC52F, 0x9DC1, 0xC531, 0x9DC2, 0xC532, 0x9DC3, 0xC533, 0x9DC4, 0xC534, - 0x9DC5, 0xC535, 0x9DC6, 0xC536, 0x9DC7, 0xC537, 0x9DC8, 0xC53A, 0x9DC9, 0xC53C, 0x9DCA, 0xC53E, 0x9DCB, 0xC53F, 0x9DCC, 0xC540, - 0x9DCD, 0xC541, 0x9DCE, 0xC542, 0x9DCF, 0xC543, 0x9DD0, 0xC546, 0x9DD1, 0xC547, 0x9DD2, 0xC54B, 0x9DD3, 0xC54F, 0x9DD4, 0xC550, - 0x9DD5, 0xC551, 0x9DD6, 0xC552, 0x9DD7, 0xC556, 0x9DD8, 0xC55A, 0x9DD9, 0xC55B, 0x9DDA, 0xC55C, 0x9DDB, 0xC55F, 0x9DDC, 0xC562, - 0x9DDD, 0xC563, 0x9DDE, 0xC565, 0x9DDF, 0xC566, 0x9DE0, 0xC567, 0x9DE1, 0xC569, 0x9DE2, 0xC56A, 0x9DE3, 0xC56B, 0x9DE4, 0xC56C, - 0x9DE5, 0xC56D, 0x9DE6, 0xC56E, 0x9DE7, 0xC56F, 0x9DE8, 0xC572, 0x9DE9, 0xC576, 0x9DEA, 0xC577, 0x9DEB, 0xC578, 0x9DEC, 0xC579, - 0x9DED, 0xC57A, 0x9DEE, 0xC57B, 0x9DEF, 0xC57E, 0x9DF0, 0xC57F, 0x9DF1, 0xC581, 0x9DF2, 0xC582, 0x9DF3, 0xC583, 0x9DF4, 0xC585, - 0x9DF5, 0xC586, 0x9DF6, 0xC588, 0x9DF7, 0xC589, 0x9DF8, 0xC58A, 0x9DF9, 0xC58B, 0x9DFA, 0xC58E, 0x9DFB, 0xC590, 0x9DFC, 0xC592, - 0x9DFD, 0xC593, 0x9DFE, 0xC594, 0x9E41, 0xC596, 0x9E42, 0xC599, 0x9E43, 0xC59A, 0x9E44, 0xC59B, 0x9E45, 0xC59D, 0x9E46, 0xC59E, - 0x9E47, 0xC59F, 0x9E48, 0xC5A1, 0x9E49, 0xC5A2, 0x9E4A, 0xC5A3, 0x9E4B, 0xC5A4, 0x9E4C, 0xC5A5, 0x9E4D, 0xC5A6, 0x9E4E, 0xC5A7, - 0x9E4F, 0xC5A8, 0x9E50, 0xC5AA, 0x9E51, 0xC5AB, 0x9E52, 0xC5AC, 0x9E53, 0xC5AD, 0x9E54, 0xC5AE, 0x9E55, 0xC5AF, 0x9E56, 0xC5B0, - 0x9E57, 0xC5B1, 0x9E58, 0xC5B2, 0x9E59, 0xC5B3, 0x9E5A, 0xC5B6, 0x9E61, 0xC5B7, 0x9E62, 0xC5BA, 0x9E63, 0xC5BF, 0x9E64, 0xC5C0, - 0x9E65, 0xC5C1, 0x9E66, 0xC5C2, 0x9E67, 0xC5C3, 0x9E68, 0xC5CB, 0x9E69, 0xC5CD, 0x9E6A, 0xC5CF, 0x9E6B, 0xC5D2, 0x9E6C, 0xC5D3, - 0x9E6D, 0xC5D5, 0x9E6E, 0xC5D6, 0x9E6F, 0xC5D7, 0x9E70, 0xC5D9, 0x9E71, 0xC5DA, 0x9E72, 0xC5DB, 0x9E73, 0xC5DC, 0x9E74, 0xC5DD, - 0x9E75, 0xC5DE, 0x9E76, 0xC5DF, 0x9E77, 0xC5E2, 0x9E78, 0xC5E4, 0x9E79, 0xC5E6, 0x9E7A, 0xC5E7, 0x9E81, 0xC5E8, 0x9E82, 0xC5E9, - 0x9E83, 0xC5EA, 0x9E84, 0xC5EB, 0x9E85, 0xC5EF, 0x9E86, 0xC5F1, 0x9E87, 0xC5F2, 0x9E88, 0xC5F3, 0x9E89, 0xC5F5, 0x9E8A, 0xC5F8, - 0x9E8B, 0xC5F9, 0x9E8C, 0xC5FA, 0x9E8D, 0xC5FB, 0x9E8E, 0xC602, 0x9E8F, 0xC603, 0x9E90, 0xC604, 0x9E91, 0xC609, 0x9E92, 0xC60A, - 0x9E93, 0xC60B, 0x9E94, 0xC60D, 0x9E95, 0xC60E, 0x9E96, 0xC60F, 0x9E97, 0xC611, 0x9E98, 0xC612, 0x9E99, 0xC613, 0x9E9A, 0xC614, - 0x9E9B, 0xC615, 0x9E9C, 0xC616, 0x9E9D, 0xC617, 0x9E9E, 0xC61A, 0x9E9F, 0xC61D, 0x9EA0, 0xC61E, 0x9EA1, 0xC61F, 0x9EA2, 0xC620, - 0x9EA3, 0xC621, 0x9EA4, 0xC622, 0x9EA5, 0xC623, 0x9EA6, 0xC626, 0x9EA7, 0xC627, 0x9EA8, 0xC629, 0x9EA9, 0xC62A, 0x9EAA, 0xC62B, - 0x9EAB, 0xC62F, 0x9EAC, 0xC631, 0x9EAD, 0xC632, 0x9EAE, 0xC636, 0x9EAF, 0xC638, 0x9EB0, 0xC63A, 0x9EB1, 0xC63C, 0x9EB2, 0xC63D, - 0x9EB3, 0xC63E, 0x9EB4, 0xC63F, 0x9EB5, 0xC642, 0x9EB6, 0xC643, 0x9EB7, 0xC645, 0x9EB8, 0xC646, 0x9EB9, 0xC647, 0x9EBA, 0xC649, - 0x9EBB, 0xC64A, 0x9EBC, 0xC64B, 0x9EBD, 0xC64C, 0x9EBE, 0xC64D, 0x9EBF, 0xC64E, 0x9EC0, 0xC64F, 0x9EC1, 0xC652, 0x9EC2, 0xC656, - 0x9EC3, 0xC657, 0x9EC4, 0xC658, 0x9EC5, 0xC659, 0x9EC6, 0xC65A, 0x9EC7, 0xC65B, 0x9EC8, 0xC65E, 0x9EC9, 0xC65F, 0x9ECA, 0xC661, - 0x9ECB, 0xC662, 0x9ECC, 0xC663, 0x9ECD, 0xC664, 0x9ECE, 0xC665, 0x9ECF, 0xC666, 0x9ED0, 0xC667, 0x9ED1, 0xC668, 0x9ED2, 0xC669, - 0x9ED3, 0xC66A, 0x9ED4, 0xC66B, 0x9ED5, 0xC66D, 0x9ED6, 0xC66E, 0x9ED7, 0xC670, 0x9ED8, 0xC672, 0x9ED9, 0xC673, 0x9EDA, 0xC674, - 0x9EDB, 0xC675, 0x9EDC, 0xC676, 0x9EDD, 0xC677, 0x9EDE, 0xC67A, 0x9EDF, 0xC67B, 0x9EE0, 0xC67D, 0x9EE1, 0xC67E, 0x9EE2, 0xC67F, - 0x9EE3, 0xC681, 0x9EE4, 0xC682, 0x9EE5, 0xC683, 0x9EE6, 0xC684, 0x9EE7, 0xC685, 0x9EE8, 0xC686, 0x9EE9, 0xC687, 0x9EEA, 0xC68A, - 0x9EEB, 0xC68C, 0x9EEC, 0xC68E, 0x9EED, 0xC68F, 0x9EEE, 0xC690, 0x9EEF, 0xC691, 0x9EF0, 0xC692, 0x9EF1, 0xC693, 0x9EF2, 0xC696, - 0x9EF3, 0xC697, 0x9EF4, 0xC699, 0x9EF5, 0xC69A, 0x9EF6, 0xC69B, 0x9EF7, 0xC69D, 0x9EF8, 0xC69E, 0x9EF9, 0xC69F, 0x9EFA, 0xC6A0, - 0x9EFB, 0xC6A1, 0x9EFC, 0xC6A2, 0x9EFD, 0xC6A3, 0x9EFE, 0xC6A6, 0x9F41, 0xC6A8, 0x9F42, 0xC6AA, 0x9F43, 0xC6AB, 0x9F44, 0xC6AC, - 0x9F45, 0xC6AD, 0x9F46, 0xC6AE, 0x9F47, 0xC6AF, 0x9F48, 0xC6B2, 0x9F49, 0xC6B3, 0x9F4A, 0xC6B5, 0x9F4B, 0xC6B6, 0x9F4C, 0xC6B7, - 0x9F4D, 0xC6BB, 0x9F4E, 0xC6BC, 0x9F4F, 0xC6BD, 0x9F50, 0xC6BE, 0x9F51, 0xC6BF, 0x9F52, 0xC6C2, 0x9F53, 0xC6C4, 0x9F54, 0xC6C6, - 0x9F55, 0xC6C7, 0x9F56, 0xC6C8, 0x9F57, 0xC6C9, 0x9F58, 0xC6CA, 0x9F59, 0xC6CB, 0x9F5A, 0xC6CE, 0x9F61, 0xC6CF, 0x9F62, 0xC6D1, - 0x9F63, 0xC6D2, 0x9F64, 0xC6D3, 0x9F65, 0xC6D5, 0x9F66, 0xC6D6, 0x9F67, 0xC6D7, 0x9F68, 0xC6D8, 0x9F69, 0xC6D9, 0x9F6A, 0xC6DA, - 0x9F6B, 0xC6DB, 0x9F6C, 0xC6DE, 0x9F6D, 0xC6DF, 0x9F6E, 0xC6E2, 0x9F6F, 0xC6E3, 0x9F70, 0xC6E4, 0x9F71, 0xC6E5, 0x9F72, 0xC6E6, - 0x9F73, 0xC6E7, 0x9F74, 0xC6EA, 0x9F75, 0xC6EB, 0x9F76, 0xC6ED, 0x9F77, 0xC6EE, 0x9F78, 0xC6EF, 0x9F79, 0xC6F1, 0x9F7A, 0xC6F2, - 0x9F81, 0xC6F3, 0x9F82, 0xC6F4, 0x9F83, 0xC6F5, 0x9F84, 0xC6F6, 0x9F85, 0xC6F7, 0x9F86, 0xC6FA, 0x9F87, 0xC6FB, 0x9F88, 0xC6FC, - 0x9F89, 0xC6FE, 0x9F8A, 0xC6FF, 0x9F8B, 0xC700, 0x9F8C, 0xC701, 0x9F8D, 0xC702, 0x9F8E, 0xC703, 0x9F8F, 0xC706, 0x9F90, 0xC707, - 0x9F91, 0xC709, 0x9F92, 0xC70A, 0x9F93, 0xC70B, 0x9F94, 0xC70D, 0x9F95, 0xC70E, 0x9F96, 0xC70F, 0x9F97, 0xC710, 0x9F98, 0xC711, - 0x9F99, 0xC712, 0x9F9A, 0xC713, 0x9F9B, 0xC716, 0x9F9C, 0xC718, 0x9F9D, 0xC71A, 0x9F9E, 0xC71B, 0x9F9F, 0xC71C, 0x9FA0, 0xC71D, - 0x9FA1, 0xC71E, 0x9FA2, 0xC71F, 0x9FA3, 0xC722, 0x9FA4, 0xC723, 0x9FA5, 0xC725, 0x9FA6, 0xC726, 0x9FA7, 0xC727, 0x9FA8, 0xC729, - 0x9FA9, 0xC72A, 0x9FAA, 0xC72B, 0x9FAB, 0xC72C, 0x9FAC, 0xC72D, 0x9FAD, 0xC72E, 0x9FAE, 0xC72F, 0x9FAF, 0xC732, 0x9FB0, 0xC734, - 0x9FB1, 0xC736, 0x9FB2, 0xC738, 0x9FB3, 0xC739, 0x9FB4, 0xC73A, 0x9FB5, 0xC73B, 0x9FB6, 0xC73E, 0x9FB7, 0xC73F, 0x9FB8, 0xC741, - 0x9FB9, 0xC742, 0x9FBA, 0xC743, 0x9FBB, 0xC745, 0x9FBC, 0xC746, 0x9FBD, 0xC747, 0x9FBE, 0xC748, 0x9FBF, 0xC749, 0x9FC0, 0xC74B, - 0x9FC1, 0xC74E, 0x9FC2, 0xC750, 0x9FC3, 0xC759, 0x9FC4, 0xC75A, 0x9FC5, 0xC75B, 0x9FC6, 0xC75D, 0x9FC7, 0xC75E, 0x9FC8, 0xC75F, - 0x9FC9, 0xC761, 0x9FCA, 0xC762, 0x9FCB, 0xC763, 0x9FCC, 0xC764, 0x9FCD, 0xC765, 0x9FCE, 0xC766, 0x9FCF, 0xC767, 0x9FD0, 0xC769, - 0x9FD1, 0xC76A, 0x9FD2, 0xC76C, 0x9FD3, 0xC76D, 0x9FD4, 0xC76E, 0x9FD5, 0xC76F, 0x9FD6, 0xC770, 0x9FD7, 0xC771, 0x9FD8, 0xC772, - 0x9FD9, 0xC773, 0x9FDA, 0xC776, 0x9FDB, 0xC777, 0x9FDC, 0xC779, 0x9FDD, 0xC77A, 0x9FDE, 0xC77B, 0x9FDF, 0xC77F, 0x9FE0, 0xC780, - 0x9FE1, 0xC781, 0x9FE2, 0xC782, 0x9FE3, 0xC786, 0x9FE4, 0xC78B, 0x9FE5, 0xC78C, 0x9FE6, 0xC78D, 0x9FE7, 0xC78F, 0x9FE8, 0xC792, - 0x9FE9, 0xC793, 0x9FEA, 0xC795, 0x9FEB, 0xC799, 0x9FEC, 0xC79B, 0x9FED, 0xC79C, 0x9FEE, 0xC79D, 0x9FEF, 0xC79E, 0x9FF0, 0xC79F, - 0x9FF1, 0xC7A2, 0x9FF2, 0xC7A7, 0x9FF3, 0xC7A8, 0x9FF4, 0xC7A9, 0x9FF5, 0xC7AA, 0x9FF6, 0xC7AB, 0x9FF7, 0xC7AE, 0x9FF8, 0xC7AF, - 0x9FF9, 0xC7B1, 0x9FFA, 0xC7B2, 0x9FFB, 0xC7B3, 0x9FFC, 0xC7B5, 0x9FFD, 0xC7B6, 0x9FFE, 0xC7B7, 0xA041, 0xC7B8, 0xA042, 0xC7B9, - 0xA043, 0xC7BA, 0xA044, 0xC7BB, 0xA045, 0xC7BE, 0xA046, 0xC7C2, 0xA047, 0xC7C3, 0xA048, 0xC7C4, 0xA049, 0xC7C5, 0xA04A, 0xC7C6, - 0xA04B, 0xC7C7, 0xA04C, 0xC7CA, 0xA04D, 0xC7CB, 0xA04E, 0xC7CD, 0xA04F, 0xC7CF, 0xA050, 0xC7D1, 0xA051, 0xC7D2, 0xA052, 0xC7D3, - 0xA053, 0xC7D4, 0xA054, 0xC7D5, 0xA055, 0xC7D6, 0xA056, 0xC7D7, 0xA057, 0xC7D9, 0xA058, 0xC7DA, 0xA059, 0xC7DB, 0xA05A, 0xC7DC, - 0xA061, 0xC7DE, 0xA062, 0xC7DF, 0xA063, 0xC7E0, 0xA064, 0xC7E1, 0xA065, 0xC7E2, 0xA066, 0xC7E3, 0xA067, 0xC7E5, 0xA068, 0xC7E6, - 0xA069, 0xC7E7, 0xA06A, 0xC7E9, 0xA06B, 0xC7EA, 0xA06C, 0xC7EB, 0xA06D, 0xC7ED, 0xA06E, 0xC7EE, 0xA06F, 0xC7EF, 0xA070, 0xC7F0, - 0xA071, 0xC7F1, 0xA072, 0xC7F2, 0xA073, 0xC7F3, 0xA074, 0xC7F4, 0xA075, 0xC7F5, 0xA076, 0xC7F6, 0xA077, 0xC7F7, 0xA078, 0xC7F8, - 0xA079, 0xC7F9, 0xA07A, 0xC7FA, 0xA081, 0xC7FB, 0xA082, 0xC7FC, 0xA083, 0xC7FD, 0xA084, 0xC7FE, 0xA085, 0xC7FF, 0xA086, 0xC802, - 0xA087, 0xC803, 0xA088, 0xC805, 0xA089, 0xC806, 0xA08A, 0xC807, 0xA08B, 0xC809, 0xA08C, 0xC80B, 0xA08D, 0xC80C, 0xA08E, 0xC80D, - 0xA08F, 0xC80E, 0xA090, 0xC80F, 0xA091, 0xC812, 0xA092, 0xC814, 0xA093, 0xC817, 0xA094, 0xC818, 0xA095, 0xC819, 0xA096, 0xC81A, - 0xA097, 0xC81B, 0xA098, 0xC81E, 0xA099, 0xC81F, 0xA09A, 0xC821, 0xA09B, 0xC822, 0xA09C, 0xC823, 0xA09D, 0xC825, 0xA09E, 0xC826, - 0xA09F, 0xC827, 0xA0A0, 0xC828, 0xA0A1, 0xC829, 0xA0A2, 0xC82A, 0xA0A3, 0xC82B, 0xA0A4, 0xC82E, 0xA0A5, 0xC830, 0xA0A6, 0xC832, - 0xA0A7, 0xC833, 0xA0A8, 0xC834, 0xA0A9, 0xC835, 0xA0AA, 0xC836, 0xA0AB, 0xC837, 0xA0AC, 0xC839, 0xA0AD, 0xC83A, 0xA0AE, 0xC83B, - 0xA0AF, 0xC83D, 0xA0B0, 0xC83E, 0xA0B1, 0xC83F, 0xA0B2, 0xC841, 0xA0B3, 0xC842, 0xA0B4, 0xC843, 0xA0B5, 0xC844, 0xA0B6, 0xC845, - 0xA0B7, 0xC846, 0xA0B8, 0xC847, 0xA0B9, 0xC84A, 0xA0BA, 0xC84B, 0xA0BB, 0xC84E, 0xA0BC, 0xC84F, 0xA0BD, 0xC850, 0xA0BE, 0xC851, - 0xA0BF, 0xC852, 0xA0C0, 0xC853, 0xA0C1, 0xC855, 0xA0C2, 0xC856, 0xA0C3, 0xC857, 0xA0C4, 0xC858, 0xA0C5, 0xC859, 0xA0C6, 0xC85A, - 0xA0C7, 0xC85B, 0xA0C8, 0xC85C, 0xA0C9, 0xC85D, 0xA0CA, 0xC85E, 0xA0CB, 0xC85F, 0xA0CC, 0xC860, 0xA0CD, 0xC861, 0xA0CE, 0xC862, - 0xA0CF, 0xC863, 0xA0D0, 0xC864, 0xA0D1, 0xC865, 0xA0D2, 0xC866, 0xA0D3, 0xC867, 0xA0D4, 0xC868, 0xA0D5, 0xC869, 0xA0D6, 0xC86A, - 0xA0D7, 0xC86B, 0xA0D8, 0xC86C, 0xA0D9, 0xC86D, 0xA0DA, 0xC86E, 0xA0DB, 0xC86F, 0xA0DC, 0xC872, 0xA0DD, 0xC873, 0xA0DE, 0xC875, - 0xA0DF, 0xC876, 0xA0E0, 0xC877, 0xA0E1, 0xC879, 0xA0E2, 0xC87B, 0xA0E3, 0xC87C, 0xA0E4, 0xC87D, 0xA0E5, 0xC87E, 0xA0E6, 0xC87F, - 0xA0E7, 0xC882, 0xA0E8, 0xC884, 0xA0E9, 0xC888, 0xA0EA, 0xC889, 0xA0EB, 0xC88A, 0xA0EC, 0xC88E, 0xA0ED, 0xC88F, 0xA0EE, 0xC890, - 0xA0EF, 0xC891, 0xA0F0, 0xC892, 0xA0F1, 0xC893, 0xA0F2, 0xC895, 0xA0F3, 0xC896, 0xA0F4, 0xC897, 0xA0F5, 0xC898, 0xA0F6, 0xC899, - 0xA0F7, 0xC89A, 0xA0F8, 0xC89B, 0xA0F9, 0xC89C, 0xA0FA, 0xC89E, 0xA0FB, 0xC8A0, 0xA0FC, 0xC8A2, 0xA0FD, 0xC8A3, 0xA0FE, 0xC8A4, - 0xA141, 0xC8A5, 0xA142, 0xC8A6, 0xA143, 0xC8A7, 0xA144, 0xC8A9, 0xA145, 0xC8AA, 0xA146, 0xC8AB, 0xA147, 0xC8AC, 0xA148, 0xC8AD, - 0xA149, 0xC8AE, 0xA14A, 0xC8AF, 0xA14B, 0xC8B0, 0xA14C, 0xC8B1, 0xA14D, 0xC8B2, 0xA14E, 0xC8B3, 0xA14F, 0xC8B4, 0xA150, 0xC8B5, - 0xA151, 0xC8B6, 0xA152, 0xC8B7, 0xA153, 0xC8B8, 0xA154, 0xC8B9, 0xA155, 0xC8BA, 0xA156, 0xC8BB, 0xA157, 0xC8BE, 0xA158, 0xC8BF, - 0xA159, 0xC8C0, 0xA15A, 0xC8C1, 0xA161, 0xC8C2, 0xA162, 0xC8C3, 0xA163, 0xC8C5, 0xA164, 0xC8C6, 0xA165, 0xC8C7, 0xA166, 0xC8C9, - 0xA167, 0xC8CA, 0xA168, 0xC8CB, 0xA169, 0xC8CD, 0xA16A, 0xC8CE, 0xA16B, 0xC8CF, 0xA16C, 0xC8D0, 0xA16D, 0xC8D1, 0xA16E, 0xC8D2, - 0xA16F, 0xC8D3, 0xA170, 0xC8D6, 0xA171, 0xC8D8, 0xA172, 0xC8DA, 0xA173, 0xC8DB, 0xA174, 0xC8DC, 0xA175, 0xC8DD, 0xA176, 0xC8DE, - 0xA177, 0xC8DF, 0xA178, 0xC8E2, 0xA179, 0xC8E3, 0xA17A, 0xC8E5, 0xA181, 0xC8E6, 0xA182, 0xC8E7, 0xA183, 0xC8E8, 0xA184, 0xC8E9, - 0xA185, 0xC8EA, 0xA186, 0xC8EB, 0xA187, 0xC8EC, 0xA188, 0xC8ED, 0xA189, 0xC8EE, 0xA18A, 0xC8EF, 0xA18B, 0xC8F0, 0xA18C, 0xC8F1, - 0xA18D, 0xC8F2, 0xA18E, 0xC8F3, 0xA18F, 0xC8F4, 0xA190, 0xC8F6, 0xA191, 0xC8F7, 0xA192, 0xC8F8, 0xA193, 0xC8F9, 0xA194, 0xC8FA, - 0xA195, 0xC8FB, 0xA196, 0xC8FE, 0xA197, 0xC8FF, 0xA198, 0xC901, 0xA199, 0xC902, 0xA19A, 0xC903, 0xA19B, 0xC907, 0xA19C, 0xC908, - 0xA19D, 0xC909, 0xA19E, 0xC90A, 0xA19F, 0xC90B, 0xA1A0, 0xC90E, 0xA1A1, 0x3000, 0xA1A2, 0x3001, 0xA1A3, 0x3002, 0xA1A4, 0x00B7, - 0xA1A5, 0x2025, 0xA1A6, 0x2026, 0xA1A7, 0x00A8, 0xA1A8, 0x3003, 0xA1A9, 0x00AD, 0xA1AA, 0x2015, 0xA1AB, 0x2225, 0xA1AC, 0xFF3C, - 0xA1AD, 0x223C, 0xA1AE, 0x2018, 0xA1AF, 0x2019, 0xA1B0, 0x201C, 0xA1B1, 0x201D, 0xA1B2, 0x3014, 0xA1B3, 0x3015, 0xA1B4, 0x3008, - 0xA1B5, 0x3009, 0xA1B6, 0x300A, 0xA1B7, 0x300B, 0xA1B8, 0x300C, 0xA1B9, 0x300D, 0xA1BA, 0x300E, 0xA1BB, 0x300F, 0xA1BC, 0x3010, - 0xA1BD, 0x3011, 0xA1BE, 0x00B1, 0xA1BF, 0x00D7, 0xA1C0, 0x00F7, 0xA1C1, 0x2260, 0xA1C2, 0x2264, 0xA1C3, 0x2265, 0xA1C4, 0x221E, - 0xA1C5, 0x2234, 0xA1C6, 0x00B0, 0xA1C7, 0x2032, 0xA1C8, 0x2033, 0xA1C9, 0x2103, 0xA1CA, 0x212B, 0xA1CB, 0xFFE0, 0xA1CC, 0xFFE1, - 0xA1CD, 0xFFE5, 0xA1CE, 0x2642, 0xA1CF, 0x2640, 0xA1D0, 0x2220, 0xA1D1, 0x22A5, 0xA1D2, 0x2312, 0xA1D3, 0x2202, 0xA1D4, 0x2207, - 0xA1D5, 0x2261, 0xA1D6, 0x2252, 0xA1D7, 0x00A7, 0xA1D8, 0x203B, 0xA1D9, 0x2606, 0xA1DA, 0x2605, 0xA1DB, 0x25CB, 0xA1DC, 0x25CF, - 0xA1DD, 0x25CE, 0xA1DE, 0x25C7, 0xA1DF, 0x25C6, 0xA1E0, 0x25A1, 0xA1E1, 0x25A0, 0xA1E2, 0x25B3, 0xA1E3, 0x25B2, 0xA1E4, 0x25BD, - 0xA1E5, 0x25BC, 0xA1E6, 0x2192, 0xA1E7, 0x2190, 0xA1E8, 0x2191, 0xA1E9, 0x2193, 0xA1EA, 0x2194, 0xA1EB, 0x3013, 0xA1EC, 0x226A, - 0xA1ED, 0x226B, 0xA1EE, 0x221A, 0xA1EF, 0x223D, 0xA1F0, 0x221D, 0xA1F1, 0x2235, 0xA1F2, 0x222B, 0xA1F3, 0x222C, 0xA1F4, 0x2208, - 0xA1F5, 0x220B, 0xA1F6, 0x2286, 0xA1F7, 0x2287, 0xA1F8, 0x2282, 0xA1F9, 0x2283, 0xA1FA, 0x222A, 0xA1FB, 0x2229, 0xA1FC, 0x2227, - 0xA1FD, 0x2228, 0xA1FE, 0xFFE2, 0xA241, 0xC910, 0xA242, 0xC912, 0xA243, 0xC913, 0xA244, 0xC914, 0xA245, 0xC915, 0xA246, 0xC916, - 0xA247, 0xC917, 0xA248, 0xC919, 0xA249, 0xC91A, 0xA24A, 0xC91B, 0xA24B, 0xC91C, 0xA24C, 0xC91D, 0xA24D, 0xC91E, 0xA24E, 0xC91F, - 0xA24F, 0xC920, 0xA250, 0xC921, 0xA251, 0xC922, 0xA252, 0xC923, 0xA253, 0xC924, 0xA254, 0xC925, 0xA255, 0xC926, 0xA256, 0xC927, - 0xA257, 0xC928, 0xA258, 0xC929, 0xA259, 0xC92A, 0xA25A, 0xC92B, 0xA261, 0xC92D, 0xA262, 0xC92E, 0xA263, 0xC92F, 0xA264, 0xC930, - 0xA265, 0xC931, 0xA266, 0xC932, 0xA267, 0xC933, 0xA268, 0xC935, 0xA269, 0xC936, 0xA26A, 0xC937, 0xA26B, 0xC938, 0xA26C, 0xC939, - 0xA26D, 0xC93A, 0xA26E, 0xC93B, 0xA26F, 0xC93C, 0xA270, 0xC93D, 0xA271, 0xC93E, 0xA272, 0xC93F, 0xA273, 0xC940, 0xA274, 0xC941, - 0xA275, 0xC942, 0xA276, 0xC943, 0xA277, 0xC944, 0xA278, 0xC945, 0xA279, 0xC946, 0xA27A, 0xC947, 0xA281, 0xC948, 0xA282, 0xC949, - 0xA283, 0xC94A, 0xA284, 0xC94B, 0xA285, 0xC94C, 0xA286, 0xC94D, 0xA287, 0xC94E, 0xA288, 0xC94F, 0xA289, 0xC952, 0xA28A, 0xC953, - 0xA28B, 0xC955, 0xA28C, 0xC956, 0xA28D, 0xC957, 0xA28E, 0xC959, 0xA28F, 0xC95A, 0xA290, 0xC95B, 0xA291, 0xC95C, 0xA292, 0xC95D, - 0xA293, 0xC95E, 0xA294, 0xC95F, 0xA295, 0xC962, 0xA296, 0xC964, 0xA297, 0xC965, 0xA298, 0xC966, 0xA299, 0xC967, 0xA29A, 0xC968, - 0xA29B, 0xC969, 0xA29C, 0xC96A, 0xA29D, 0xC96B, 0xA29E, 0xC96D, 0xA29F, 0xC96E, 0xA2A0, 0xC96F, 0xA2A1, 0x21D2, 0xA2A2, 0x21D4, - 0xA2A3, 0x2200, 0xA2A4, 0x2203, 0xA2A5, 0x00B4, 0xA2A6, 0xFF5E, 0xA2A7, 0x02C7, 0xA2A8, 0x02D8, 0xA2A9, 0x02DD, 0xA2AA, 0x02DA, - 0xA2AB, 0x02D9, 0xA2AC, 0x00B8, 0xA2AD, 0x02DB, 0xA2AE, 0x00A1, 0xA2AF, 0x00BF, 0xA2B0, 0x02D0, 0xA2B1, 0x222E, 0xA2B2, 0x2211, - 0xA2B3, 0x220F, 0xA2B4, 0x00A4, 0xA2B5, 0x2109, 0xA2B6, 0x2030, 0xA2B7, 0x25C1, 0xA2B8, 0x25C0, 0xA2B9, 0x25B7, 0xA2BA, 0x25B6, - 0xA2BB, 0x2664, 0xA2BC, 0x2660, 0xA2BD, 0x2661, 0xA2BE, 0x2665, 0xA2BF, 0x2667, 0xA2C0, 0x2663, 0xA2C1, 0x2299, 0xA2C2, 0x25C8, - 0xA2C3, 0x25A3, 0xA2C4, 0x25D0, 0xA2C5, 0x25D1, 0xA2C6, 0x2592, 0xA2C7, 0x25A4, 0xA2C8, 0x25A5, 0xA2C9, 0x25A8, 0xA2CA, 0x25A7, - 0xA2CB, 0x25A6, 0xA2CC, 0x25A9, 0xA2CD, 0x2668, 0xA2CE, 0x260F, 0xA2CF, 0x260E, 0xA2D0, 0x261C, 0xA2D1, 0x261E, 0xA2D2, 0x00B6, - 0xA2D3, 0x2020, 0xA2D4, 0x2021, 0xA2D5, 0x2195, 0xA2D6, 0x2197, 0xA2D7, 0x2199, 0xA2D8, 0x2196, 0xA2D9, 0x2198, 0xA2DA, 0x266D, - 0xA2DB, 0x2669, 0xA2DC, 0x266A, 0xA2DD, 0x266C, 0xA2DE, 0x327F, 0xA2DF, 0x321C, 0xA2E0, 0x2116, 0xA2E1, 0x33C7, 0xA2E2, 0x2122, - 0xA2E3, 0x33C2, 0xA2E4, 0x33D8, 0xA2E5, 0x2121, 0xA2E6, 0x20AC, 0xA2E7, 0x00AE, 0xA341, 0xC971, 0xA342, 0xC972, 0xA343, 0xC973, - 0xA344, 0xC975, 0xA345, 0xC976, 0xA346, 0xC977, 0xA347, 0xC978, 0xA348, 0xC979, 0xA349, 0xC97A, 0xA34A, 0xC97B, 0xA34B, 0xC97D, - 0xA34C, 0xC97E, 0xA34D, 0xC97F, 0xA34E, 0xC980, 0xA34F, 0xC981, 0xA350, 0xC982, 0xA351, 0xC983, 0xA352, 0xC984, 0xA353, 0xC985, - 0xA354, 0xC986, 0xA355, 0xC987, 0xA356, 0xC98A, 0xA357, 0xC98B, 0xA358, 0xC98D, 0xA359, 0xC98E, 0xA35A, 0xC98F, 0xA361, 0xC991, - 0xA362, 0xC992, 0xA363, 0xC993, 0xA364, 0xC994, 0xA365, 0xC995, 0xA366, 0xC996, 0xA367, 0xC997, 0xA368, 0xC99A, 0xA369, 0xC99C, - 0xA36A, 0xC99E, 0xA36B, 0xC99F, 0xA36C, 0xC9A0, 0xA36D, 0xC9A1, 0xA36E, 0xC9A2, 0xA36F, 0xC9A3, 0xA370, 0xC9A4, 0xA371, 0xC9A5, - 0xA372, 0xC9A6, 0xA373, 0xC9A7, 0xA374, 0xC9A8, 0xA375, 0xC9A9, 0xA376, 0xC9AA, 0xA377, 0xC9AB, 0xA378, 0xC9AC, 0xA379, 0xC9AD, - 0xA37A, 0xC9AE, 0xA381, 0xC9AF, 0xA382, 0xC9B0, 0xA383, 0xC9B1, 0xA384, 0xC9B2, 0xA385, 0xC9B3, 0xA386, 0xC9B4, 0xA387, 0xC9B5, - 0xA388, 0xC9B6, 0xA389, 0xC9B7, 0xA38A, 0xC9B8, 0xA38B, 0xC9B9, 0xA38C, 0xC9BA, 0xA38D, 0xC9BB, 0xA38E, 0xC9BC, 0xA38F, 0xC9BD, - 0xA390, 0xC9BE, 0xA391, 0xC9BF, 0xA392, 0xC9C2, 0xA393, 0xC9C3, 0xA394, 0xC9C5, 0xA395, 0xC9C6, 0xA396, 0xC9C9, 0xA397, 0xC9CB, - 0xA398, 0xC9CC, 0xA399, 0xC9CD, 0xA39A, 0xC9CE, 0xA39B, 0xC9CF, 0xA39C, 0xC9D2, 0xA39D, 0xC9D4, 0xA39E, 0xC9D7, 0xA39F, 0xC9D8, - 0xA3A0, 0xC9DB, 0xA3A1, 0xFF01, 0xA3A2, 0xFF02, 0xA3A3, 0xFF03, 0xA3A4, 0xFF04, 0xA3A5, 0xFF05, 0xA3A6, 0xFF06, 0xA3A7, 0xFF07, - 0xA3A8, 0xFF08, 0xA3A9, 0xFF09, 0xA3AA, 0xFF0A, 0xA3AB, 0xFF0B, 0xA3AC, 0xFF0C, 0xA3AD, 0xFF0D, 0xA3AE, 0xFF0E, 0xA3AF, 0xFF0F, - 0xA3B0, 0xFF10, 0xA3B1, 0xFF11, 0xA3B2, 0xFF12, 0xA3B3, 0xFF13, 0xA3B4, 0xFF14, 0xA3B5, 0xFF15, 0xA3B6, 0xFF16, 0xA3B7, 0xFF17, - 0xA3B8, 0xFF18, 0xA3B9, 0xFF19, 0xA3BA, 0xFF1A, 0xA3BB, 0xFF1B, 0xA3BC, 0xFF1C, 0xA3BD, 0xFF1D, 0xA3BE, 0xFF1E, 0xA3BF, 0xFF1F, - 0xA3C0, 0xFF20, 0xA3C1, 0xFF21, 0xA3C2, 0xFF22, 0xA3C3, 0xFF23, 0xA3C4, 0xFF24, 0xA3C5, 0xFF25, 0xA3C6, 0xFF26, 0xA3C7, 0xFF27, - 0xA3C8, 0xFF28, 0xA3C9, 0xFF29, 0xA3CA, 0xFF2A, 0xA3CB, 0xFF2B, 0xA3CC, 0xFF2C, 0xA3CD, 0xFF2D, 0xA3CE, 0xFF2E, 0xA3CF, 0xFF2F, - 0xA3D0, 0xFF30, 0xA3D1, 0xFF31, 0xA3D2, 0xFF32, 0xA3D3, 0xFF33, 0xA3D4, 0xFF34, 0xA3D5, 0xFF35, 0xA3D6, 0xFF36, 0xA3D7, 0xFF37, - 0xA3D8, 0xFF38, 0xA3D9, 0xFF39, 0xA3DA, 0xFF3A, 0xA3DB, 0xFF3B, 0xA3DC, 0xFFE6, 0xA3DD, 0xFF3D, 0xA3DE, 0xFF3E, 0xA3DF, 0xFF3F, - 0xA3E0, 0xFF40, 0xA3E1, 0xFF41, 0xA3E2, 0xFF42, 0xA3E3, 0xFF43, 0xA3E4, 0xFF44, 0xA3E5, 0xFF45, 0xA3E6, 0xFF46, 0xA3E7, 0xFF47, - 0xA3E8, 0xFF48, 0xA3E9, 0xFF49, 0xA3EA, 0xFF4A, 0xA3EB, 0xFF4B, 0xA3EC, 0xFF4C, 0xA3ED, 0xFF4D, 0xA3EE, 0xFF4E, 0xA3EF, 0xFF4F, - 0xA3F0, 0xFF50, 0xA3F1, 0xFF51, 0xA3F2, 0xFF52, 0xA3F3, 0xFF53, 0xA3F4, 0xFF54, 0xA3F5, 0xFF55, 0xA3F6, 0xFF56, 0xA3F7, 0xFF57, - 0xA3F8, 0xFF58, 0xA3F9, 0xFF59, 0xA3FA, 0xFF5A, 0xA3FB, 0xFF5B, 0xA3FC, 0xFF5C, 0xA3FD, 0xFF5D, 0xA3FE, 0xFFE3, 0xA441, 0xC9DE, - 0xA442, 0xC9DF, 0xA443, 0xC9E1, 0xA444, 0xC9E3, 0xA445, 0xC9E5, 0xA446, 0xC9E6, 0xA447, 0xC9E8, 0xA448, 0xC9E9, 0xA449, 0xC9EA, - 0xA44A, 0xC9EB, 0xA44B, 0xC9EE, 0xA44C, 0xC9F2, 0xA44D, 0xC9F3, 0xA44E, 0xC9F4, 0xA44F, 0xC9F5, 0xA450, 0xC9F6, 0xA451, 0xC9F7, - 0xA452, 0xC9FA, 0xA453, 0xC9FB, 0xA454, 0xC9FD, 0xA455, 0xC9FE, 0xA456, 0xC9FF, 0xA457, 0xCA01, 0xA458, 0xCA02, 0xA459, 0xCA03, - 0xA45A, 0xCA04, 0xA461, 0xCA05, 0xA462, 0xCA06, 0xA463, 0xCA07, 0xA464, 0xCA0A, 0xA465, 0xCA0E, 0xA466, 0xCA0F, 0xA467, 0xCA10, - 0xA468, 0xCA11, 0xA469, 0xCA12, 0xA46A, 0xCA13, 0xA46B, 0xCA15, 0xA46C, 0xCA16, 0xA46D, 0xCA17, 0xA46E, 0xCA19, 0xA46F, 0xCA1A, - 0xA470, 0xCA1B, 0xA471, 0xCA1C, 0xA472, 0xCA1D, 0xA473, 0xCA1E, 0xA474, 0xCA1F, 0xA475, 0xCA20, 0xA476, 0xCA21, 0xA477, 0xCA22, - 0xA478, 0xCA23, 0xA479, 0xCA24, 0xA47A, 0xCA25, 0xA481, 0xCA26, 0xA482, 0xCA27, 0xA483, 0xCA28, 0xA484, 0xCA2A, 0xA485, 0xCA2B, - 0xA486, 0xCA2C, 0xA487, 0xCA2D, 0xA488, 0xCA2E, 0xA489, 0xCA2F, 0xA48A, 0xCA30, 0xA48B, 0xCA31, 0xA48C, 0xCA32, 0xA48D, 0xCA33, - 0xA48E, 0xCA34, 0xA48F, 0xCA35, 0xA490, 0xCA36, 0xA491, 0xCA37, 0xA492, 0xCA38, 0xA493, 0xCA39, 0xA494, 0xCA3A, 0xA495, 0xCA3B, - 0xA496, 0xCA3C, 0xA497, 0xCA3D, 0xA498, 0xCA3E, 0xA499, 0xCA3F, 0xA49A, 0xCA40, 0xA49B, 0xCA41, 0xA49C, 0xCA42, 0xA49D, 0xCA43, - 0xA49E, 0xCA44, 0xA49F, 0xCA45, 0xA4A0, 0xCA46, 0xA4A1, 0x3131, 0xA4A2, 0x3132, 0xA4A3, 0x3133, 0xA4A4, 0x3134, 0xA4A5, 0x3135, - 0xA4A6, 0x3136, 0xA4A7, 0x3137, 0xA4A8, 0x3138, 0xA4A9, 0x3139, 0xA4AA, 0x313A, 0xA4AB, 0x313B, 0xA4AC, 0x313C, 0xA4AD, 0x313D, - 0xA4AE, 0x313E, 0xA4AF, 0x313F, 0xA4B0, 0x3140, 0xA4B1, 0x3141, 0xA4B2, 0x3142, 0xA4B3, 0x3143, 0xA4B4, 0x3144, 0xA4B5, 0x3145, - 0xA4B6, 0x3146, 0xA4B7, 0x3147, 0xA4B8, 0x3148, 0xA4B9, 0x3149, 0xA4BA, 0x314A, 0xA4BB, 0x314B, 0xA4BC, 0x314C, 0xA4BD, 0x314D, - 0xA4BE, 0x314E, 0xA4BF, 0x314F, 0xA4C0, 0x3150, 0xA4C1, 0x3151, 0xA4C2, 0x3152, 0xA4C3, 0x3153, 0xA4C4, 0x3154, 0xA4C5, 0x3155, - 0xA4C6, 0x3156, 0xA4C7, 0x3157, 0xA4C8, 0x3158, 0xA4C9, 0x3159, 0xA4CA, 0x315A, 0xA4CB, 0x315B, 0xA4CC, 0x315C, 0xA4CD, 0x315D, - 0xA4CE, 0x315E, 0xA4CF, 0x315F, 0xA4D0, 0x3160, 0xA4D1, 0x3161, 0xA4D2, 0x3162, 0xA4D3, 0x3163, 0xA4D4, 0x3164, 0xA4D5, 0x3165, - 0xA4D6, 0x3166, 0xA4D7, 0x3167, 0xA4D8, 0x3168, 0xA4D9, 0x3169, 0xA4DA, 0x316A, 0xA4DB, 0x316B, 0xA4DC, 0x316C, 0xA4DD, 0x316D, - 0xA4DE, 0x316E, 0xA4DF, 0x316F, 0xA4E0, 0x3170, 0xA4E1, 0x3171, 0xA4E2, 0x3172, 0xA4E3, 0x3173, 0xA4E4, 0x3174, 0xA4E5, 0x3175, - 0xA4E6, 0x3176, 0xA4E7, 0x3177, 0xA4E8, 0x3178, 0xA4E9, 0x3179, 0xA4EA, 0x317A, 0xA4EB, 0x317B, 0xA4EC, 0x317C, 0xA4ED, 0x317D, - 0xA4EE, 0x317E, 0xA4EF, 0x317F, 0xA4F0, 0x3180, 0xA4F1, 0x3181, 0xA4F2, 0x3182, 0xA4F3, 0x3183, 0xA4F4, 0x3184, 0xA4F5, 0x3185, - 0xA4F6, 0x3186, 0xA4F7, 0x3187, 0xA4F8, 0x3188, 0xA4F9, 0x3189, 0xA4FA, 0x318A, 0xA4FB, 0x318B, 0xA4FC, 0x318C, 0xA4FD, 0x318D, - 0xA4FE, 0x318E, 0xA541, 0xCA47, 0xA542, 0xCA48, 0xA543, 0xCA49, 0xA544, 0xCA4A, 0xA545, 0xCA4B, 0xA546, 0xCA4E, 0xA547, 0xCA4F, - 0xA548, 0xCA51, 0xA549, 0xCA52, 0xA54A, 0xCA53, 0xA54B, 0xCA55, 0xA54C, 0xCA56, 0xA54D, 0xCA57, 0xA54E, 0xCA58, 0xA54F, 0xCA59, - 0xA550, 0xCA5A, 0xA551, 0xCA5B, 0xA552, 0xCA5E, 0xA553, 0xCA62, 0xA554, 0xCA63, 0xA555, 0xCA64, 0xA556, 0xCA65, 0xA557, 0xCA66, - 0xA558, 0xCA67, 0xA559, 0xCA69, 0xA55A, 0xCA6A, 0xA561, 0xCA6B, 0xA562, 0xCA6C, 0xA563, 0xCA6D, 0xA564, 0xCA6E, 0xA565, 0xCA6F, - 0xA566, 0xCA70, 0xA567, 0xCA71, 0xA568, 0xCA72, 0xA569, 0xCA73, 0xA56A, 0xCA74, 0xA56B, 0xCA75, 0xA56C, 0xCA76, 0xA56D, 0xCA77, - 0xA56E, 0xCA78, 0xA56F, 0xCA79, 0xA570, 0xCA7A, 0xA571, 0xCA7B, 0xA572, 0xCA7C, 0xA573, 0xCA7E, 0xA574, 0xCA7F, 0xA575, 0xCA80, - 0xA576, 0xCA81, 0xA577, 0xCA82, 0xA578, 0xCA83, 0xA579, 0xCA85, 0xA57A, 0xCA86, 0xA581, 0xCA87, 0xA582, 0xCA88, 0xA583, 0xCA89, - 0xA584, 0xCA8A, 0xA585, 0xCA8B, 0xA586, 0xCA8C, 0xA587, 0xCA8D, 0xA588, 0xCA8E, 0xA589, 0xCA8F, 0xA58A, 0xCA90, 0xA58B, 0xCA91, - 0xA58C, 0xCA92, 0xA58D, 0xCA93, 0xA58E, 0xCA94, 0xA58F, 0xCA95, 0xA590, 0xCA96, 0xA591, 0xCA97, 0xA592, 0xCA99, 0xA593, 0xCA9A, - 0xA594, 0xCA9B, 0xA595, 0xCA9C, 0xA596, 0xCA9D, 0xA597, 0xCA9E, 0xA598, 0xCA9F, 0xA599, 0xCAA0, 0xA59A, 0xCAA1, 0xA59B, 0xCAA2, - 0xA59C, 0xCAA3, 0xA59D, 0xCAA4, 0xA59E, 0xCAA5, 0xA59F, 0xCAA6, 0xA5A0, 0xCAA7, 0xA5A1, 0x2170, 0xA5A2, 0x2171, 0xA5A3, 0x2172, - 0xA5A4, 0x2173, 0xA5A5, 0x2174, 0xA5A6, 0x2175, 0xA5A7, 0x2176, 0xA5A8, 0x2177, 0xA5A9, 0x2178, 0xA5AA, 0x2179, 0xA5B0, 0x2160, - 0xA5B1, 0x2161, 0xA5B2, 0x2162, 0xA5B3, 0x2163, 0xA5B4, 0x2164, 0xA5B5, 0x2165, 0xA5B6, 0x2166, 0xA5B7, 0x2167, 0xA5B8, 0x2168, - 0xA5B9, 0x2169, 0xA5C1, 0x0391, 0xA5C2, 0x0392, 0xA5C3, 0x0393, 0xA5C4, 0x0394, 0xA5C5, 0x0395, 0xA5C6, 0x0396, 0xA5C7, 0x0397, - 0xA5C8, 0x0398, 0xA5C9, 0x0399, 0xA5CA, 0x039A, 0xA5CB, 0x039B, 0xA5CC, 0x039C, 0xA5CD, 0x039D, 0xA5CE, 0x039E, 0xA5CF, 0x039F, - 0xA5D0, 0x03A0, 0xA5D1, 0x03A1, 0xA5D2, 0x03A3, 0xA5D3, 0x03A4, 0xA5D4, 0x03A5, 0xA5D5, 0x03A6, 0xA5D6, 0x03A7, 0xA5D7, 0x03A8, - 0xA5D8, 0x03A9, 0xA5E1, 0x03B1, 0xA5E2, 0x03B2, 0xA5E3, 0x03B3, 0xA5E4, 0x03B4, 0xA5E5, 0x03B5, 0xA5E6, 0x03B6, 0xA5E7, 0x03B7, - 0xA5E8, 0x03B8, 0xA5E9, 0x03B9, 0xA5EA, 0x03BA, 0xA5EB, 0x03BB, 0xA5EC, 0x03BC, 0xA5ED, 0x03BD, 0xA5EE, 0x03BE, 0xA5EF, 0x03BF, - 0xA5F0, 0x03C0, 0xA5F1, 0x03C1, 0xA5F2, 0x03C3, 0xA5F3, 0x03C4, 0xA5F4, 0x03C5, 0xA5F5, 0x03C6, 0xA5F6, 0x03C7, 0xA5F7, 0x03C8, - 0xA5F8, 0x03C9, 0xA641, 0xCAA8, 0xA642, 0xCAA9, 0xA643, 0xCAAA, 0xA644, 0xCAAB, 0xA645, 0xCAAC, 0xA646, 0xCAAD, 0xA647, 0xCAAE, - 0xA648, 0xCAAF, 0xA649, 0xCAB0, 0xA64A, 0xCAB1, 0xA64B, 0xCAB2, 0xA64C, 0xCAB3, 0xA64D, 0xCAB4, 0xA64E, 0xCAB5, 0xA64F, 0xCAB6, - 0xA650, 0xCAB7, 0xA651, 0xCAB8, 0xA652, 0xCAB9, 0xA653, 0xCABA, 0xA654, 0xCABB, 0xA655, 0xCABE, 0xA656, 0xCABF, 0xA657, 0xCAC1, - 0xA658, 0xCAC2, 0xA659, 0xCAC3, 0xA65A, 0xCAC5, 0xA661, 0xCAC6, 0xA662, 0xCAC7, 0xA663, 0xCAC8, 0xA664, 0xCAC9, 0xA665, 0xCACA, - 0xA666, 0xCACB, 0xA667, 0xCACE, 0xA668, 0xCAD0, 0xA669, 0xCAD2, 0xA66A, 0xCAD4, 0xA66B, 0xCAD5, 0xA66C, 0xCAD6, 0xA66D, 0xCAD7, - 0xA66E, 0xCADA, 0xA66F, 0xCADB, 0xA670, 0xCADC, 0xA671, 0xCADD, 0xA672, 0xCADE, 0xA673, 0xCADF, 0xA674, 0xCAE1, 0xA675, 0xCAE2, - 0xA676, 0xCAE3, 0xA677, 0xCAE4, 0xA678, 0xCAE5, 0xA679, 0xCAE6, 0xA67A, 0xCAE7, 0xA681, 0xCAE8, 0xA682, 0xCAE9, 0xA683, 0xCAEA, - 0xA684, 0xCAEB, 0xA685, 0xCAED, 0xA686, 0xCAEE, 0xA687, 0xCAEF, 0xA688, 0xCAF0, 0xA689, 0xCAF1, 0xA68A, 0xCAF2, 0xA68B, 0xCAF3, - 0xA68C, 0xCAF5, 0xA68D, 0xCAF6, 0xA68E, 0xCAF7, 0xA68F, 0xCAF8, 0xA690, 0xCAF9, 0xA691, 0xCAFA, 0xA692, 0xCAFB, 0xA693, 0xCAFC, - 0xA694, 0xCAFD, 0xA695, 0xCAFE, 0xA696, 0xCAFF, 0xA697, 0xCB00, 0xA698, 0xCB01, 0xA699, 0xCB02, 0xA69A, 0xCB03, 0xA69B, 0xCB04, - 0xA69C, 0xCB05, 0xA69D, 0xCB06, 0xA69E, 0xCB07, 0xA69F, 0xCB09, 0xA6A0, 0xCB0A, 0xA6A1, 0x2500, 0xA6A2, 0x2502, 0xA6A3, 0x250C, - 0xA6A4, 0x2510, 0xA6A5, 0x2518, 0xA6A6, 0x2514, 0xA6A7, 0x251C, 0xA6A8, 0x252C, 0xA6A9, 0x2524, 0xA6AA, 0x2534, 0xA6AB, 0x253C, - 0xA6AC, 0x2501, 0xA6AD, 0x2503, 0xA6AE, 0x250F, 0xA6AF, 0x2513, 0xA6B0, 0x251B, 0xA6B1, 0x2517, 0xA6B2, 0x2523, 0xA6B3, 0x2533, - 0xA6B4, 0x252B, 0xA6B5, 0x253B, 0xA6B6, 0x254B, 0xA6B7, 0x2520, 0xA6B8, 0x252F, 0xA6B9, 0x2528, 0xA6BA, 0x2537, 0xA6BB, 0x253F, - 0xA6BC, 0x251D, 0xA6BD, 0x2530, 0xA6BE, 0x2525, 0xA6BF, 0x2538, 0xA6C0, 0x2542, 0xA6C1, 0x2512, 0xA6C2, 0x2511, 0xA6C3, 0x251A, - 0xA6C4, 0x2519, 0xA6C5, 0x2516, 0xA6C6, 0x2515, 0xA6C7, 0x250E, 0xA6C8, 0x250D, 0xA6C9, 0x251E, 0xA6CA, 0x251F, 0xA6CB, 0x2521, - 0xA6CC, 0x2522, 0xA6CD, 0x2526, 0xA6CE, 0x2527, 0xA6CF, 0x2529, 0xA6D0, 0x252A, 0xA6D1, 0x252D, 0xA6D2, 0x252E, 0xA6D3, 0x2531, - 0xA6D4, 0x2532, 0xA6D5, 0x2535, 0xA6D6, 0x2536, 0xA6D7, 0x2539, 0xA6D8, 0x253A, 0xA6D9, 0x253D, 0xA6DA, 0x253E, 0xA6DB, 0x2540, - 0xA6DC, 0x2541, 0xA6DD, 0x2543, 0xA6DE, 0x2544, 0xA6DF, 0x2545, 0xA6E0, 0x2546, 0xA6E1, 0x2547, 0xA6E2, 0x2548, 0xA6E3, 0x2549, - 0xA6E4, 0x254A, 0xA741, 0xCB0B, 0xA742, 0xCB0C, 0xA743, 0xCB0D, 0xA744, 0xCB0E, 0xA745, 0xCB0F, 0xA746, 0xCB11, 0xA747, 0xCB12, - 0xA748, 0xCB13, 0xA749, 0xCB15, 0xA74A, 0xCB16, 0xA74B, 0xCB17, 0xA74C, 0xCB19, 0xA74D, 0xCB1A, 0xA74E, 0xCB1B, 0xA74F, 0xCB1C, - 0xA750, 0xCB1D, 0xA751, 0xCB1E, 0xA752, 0xCB1F, 0xA753, 0xCB22, 0xA754, 0xCB23, 0xA755, 0xCB24, 0xA756, 0xCB25, 0xA757, 0xCB26, - 0xA758, 0xCB27, 0xA759, 0xCB28, 0xA75A, 0xCB29, 0xA761, 0xCB2A, 0xA762, 0xCB2B, 0xA763, 0xCB2C, 0xA764, 0xCB2D, 0xA765, 0xCB2E, - 0xA766, 0xCB2F, 0xA767, 0xCB30, 0xA768, 0xCB31, 0xA769, 0xCB32, 0xA76A, 0xCB33, 0xA76B, 0xCB34, 0xA76C, 0xCB35, 0xA76D, 0xCB36, - 0xA76E, 0xCB37, 0xA76F, 0xCB38, 0xA770, 0xCB39, 0xA771, 0xCB3A, 0xA772, 0xCB3B, 0xA773, 0xCB3C, 0xA774, 0xCB3D, 0xA775, 0xCB3E, - 0xA776, 0xCB3F, 0xA777, 0xCB40, 0xA778, 0xCB42, 0xA779, 0xCB43, 0xA77A, 0xCB44, 0xA781, 0xCB45, 0xA782, 0xCB46, 0xA783, 0xCB47, - 0xA784, 0xCB4A, 0xA785, 0xCB4B, 0xA786, 0xCB4D, 0xA787, 0xCB4E, 0xA788, 0xCB4F, 0xA789, 0xCB51, 0xA78A, 0xCB52, 0xA78B, 0xCB53, - 0xA78C, 0xCB54, 0xA78D, 0xCB55, 0xA78E, 0xCB56, 0xA78F, 0xCB57, 0xA790, 0xCB5A, 0xA791, 0xCB5B, 0xA792, 0xCB5C, 0xA793, 0xCB5E, - 0xA794, 0xCB5F, 0xA795, 0xCB60, 0xA796, 0xCB61, 0xA797, 0xCB62, 0xA798, 0xCB63, 0xA799, 0xCB65, 0xA79A, 0xCB66, 0xA79B, 0xCB67, - 0xA79C, 0xCB68, 0xA79D, 0xCB69, 0xA79E, 0xCB6A, 0xA79F, 0xCB6B, 0xA7A0, 0xCB6C, 0xA7A1, 0x3395, 0xA7A2, 0x3396, 0xA7A3, 0x3397, - 0xA7A4, 0x2113, 0xA7A5, 0x3398, 0xA7A6, 0x33C4, 0xA7A7, 0x33A3, 0xA7A8, 0x33A4, 0xA7A9, 0x33A5, 0xA7AA, 0x33A6, 0xA7AB, 0x3399, - 0xA7AC, 0x339A, 0xA7AD, 0x339B, 0xA7AE, 0x339C, 0xA7AF, 0x339D, 0xA7B0, 0x339E, 0xA7B1, 0x339F, 0xA7B2, 0x33A0, 0xA7B3, 0x33A1, - 0xA7B4, 0x33A2, 0xA7B5, 0x33CA, 0xA7B6, 0x338D, 0xA7B7, 0x338E, 0xA7B8, 0x338F, 0xA7B9, 0x33CF, 0xA7BA, 0x3388, 0xA7BB, 0x3389, - 0xA7BC, 0x33C8, 0xA7BD, 0x33A7, 0xA7BE, 0x33A8, 0xA7BF, 0x33B0, 0xA7C0, 0x33B1, 0xA7C1, 0x33B2, 0xA7C2, 0x33B3, 0xA7C3, 0x33B4, - 0xA7C4, 0x33B5, 0xA7C5, 0x33B6, 0xA7C6, 0x33B7, 0xA7C7, 0x33B8, 0xA7C8, 0x33B9, 0xA7C9, 0x3380, 0xA7CA, 0x3381, 0xA7CB, 0x3382, - 0xA7CC, 0x3383, 0xA7CD, 0x3384, 0xA7CE, 0x33BA, 0xA7CF, 0x33BB, 0xA7D0, 0x33BC, 0xA7D1, 0x33BD, 0xA7D2, 0x33BE, 0xA7D3, 0x33BF, - 0xA7D4, 0x3390, 0xA7D5, 0x3391, 0xA7D6, 0x3392, 0xA7D7, 0x3393, 0xA7D8, 0x3394, 0xA7D9, 0x2126, 0xA7DA, 0x33C0, 0xA7DB, 0x33C1, - 0xA7DC, 0x338A, 0xA7DD, 0x338B, 0xA7DE, 0x338C, 0xA7DF, 0x33D6, 0xA7E0, 0x33C5, 0xA7E1, 0x33AD, 0xA7E2, 0x33AE, 0xA7E3, 0x33AF, - 0xA7E4, 0x33DB, 0xA7E5, 0x33A9, 0xA7E6, 0x33AA, 0xA7E7, 0x33AB, 0xA7E8, 0x33AC, 0xA7E9, 0x33DD, 0xA7EA, 0x33D0, 0xA7EB, 0x33D3, - 0xA7EC, 0x33C3, 0xA7ED, 0x33C9, 0xA7EE, 0x33DC, 0xA7EF, 0x33C6, 0xA841, 0xCB6D, 0xA842, 0xCB6E, 0xA843, 0xCB6F, 0xA844, 0xCB70, - 0xA845, 0xCB71, 0xA846, 0xCB72, 0xA847, 0xCB73, 0xA848, 0xCB74, 0xA849, 0xCB75, 0xA84A, 0xCB76, 0xA84B, 0xCB77, 0xA84C, 0xCB7A, - 0xA84D, 0xCB7B, 0xA84E, 0xCB7C, 0xA84F, 0xCB7D, 0xA850, 0xCB7E, 0xA851, 0xCB7F, 0xA852, 0xCB80, 0xA853, 0xCB81, 0xA854, 0xCB82, - 0xA855, 0xCB83, 0xA856, 0xCB84, 0xA857, 0xCB85, 0xA858, 0xCB86, 0xA859, 0xCB87, 0xA85A, 0xCB88, 0xA861, 0xCB89, 0xA862, 0xCB8A, - 0xA863, 0xCB8B, 0xA864, 0xCB8C, 0xA865, 0xCB8D, 0xA866, 0xCB8E, 0xA867, 0xCB8F, 0xA868, 0xCB90, 0xA869, 0xCB91, 0xA86A, 0xCB92, - 0xA86B, 0xCB93, 0xA86C, 0xCB94, 0xA86D, 0xCB95, 0xA86E, 0xCB96, 0xA86F, 0xCB97, 0xA870, 0xCB98, 0xA871, 0xCB99, 0xA872, 0xCB9A, - 0xA873, 0xCB9B, 0xA874, 0xCB9D, 0xA875, 0xCB9E, 0xA876, 0xCB9F, 0xA877, 0xCBA0, 0xA878, 0xCBA1, 0xA879, 0xCBA2, 0xA87A, 0xCBA3, - 0xA881, 0xCBA4, 0xA882, 0xCBA5, 0xA883, 0xCBA6, 0xA884, 0xCBA7, 0xA885, 0xCBA8, 0xA886, 0xCBA9, 0xA887, 0xCBAA, 0xA888, 0xCBAB, - 0xA889, 0xCBAC, 0xA88A, 0xCBAD, 0xA88B, 0xCBAE, 0xA88C, 0xCBAF, 0xA88D, 0xCBB0, 0xA88E, 0xCBB1, 0xA88F, 0xCBB2, 0xA890, 0xCBB3, - 0xA891, 0xCBB4, 0xA892, 0xCBB5, 0xA893, 0xCBB6, 0xA894, 0xCBB7, 0xA895, 0xCBB9, 0xA896, 0xCBBA, 0xA897, 0xCBBB, 0xA898, 0xCBBC, - 0xA899, 0xCBBD, 0xA89A, 0xCBBE, 0xA89B, 0xCBBF, 0xA89C, 0xCBC0, 0xA89D, 0xCBC1, 0xA89E, 0xCBC2, 0xA89F, 0xCBC3, 0xA8A0, 0xCBC4, - 0xA8A1, 0x00C6, 0xA8A2, 0x00D0, 0xA8A3, 0x00AA, 0xA8A4, 0x0126, 0xA8A6, 0x0132, 0xA8A8, 0x013F, 0xA8A9, 0x0141, 0xA8AA, 0x00D8, - 0xA8AB, 0x0152, 0xA8AC, 0x00BA, 0xA8AD, 0x00DE, 0xA8AE, 0x0166, 0xA8AF, 0x014A, 0xA8B1, 0x3260, 0xA8B2, 0x3261, 0xA8B3, 0x3262, - 0xA8B4, 0x3263, 0xA8B5, 0x3264, 0xA8B6, 0x3265, 0xA8B7, 0x3266, 0xA8B8, 0x3267, 0xA8B9, 0x3268, 0xA8BA, 0x3269, 0xA8BB, 0x326A, - 0xA8BC, 0x326B, 0xA8BD, 0x326C, 0xA8BE, 0x326D, 0xA8BF, 0x326E, 0xA8C0, 0x326F, 0xA8C1, 0x3270, 0xA8C2, 0x3271, 0xA8C3, 0x3272, - 0xA8C4, 0x3273, 0xA8C5, 0x3274, 0xA8C6, 0x3275, 0xA8C7, 0x3276, 0xA8C8, 0x3277, 0xA8C9, 0x3278, 0xA8CA, 0x3279, 0xA8CB, 0x327A, - 0xA8CC, 0x327B, 0xA8CD, 0x24D0, 0xA8CE, 0x24D1, 0xA8CF, 0x24D2, 0xA8D0, 0x24D3, 0xA8D1, 0x24D4, 0xA8D2, 0x24D5, 0xA8D3, 0x24D6, - 0xA8D4, 0x24D7, 0xA8D5, 0x24D8, 0xA8D6, 0x24D9, 0xA8D7, 0x24DA, 0xA8D8, 0x24DB, 0xA8D9, 0x24DC, 0xA8DA, 0x24DD, 0xA8DB, 0x24DE, - 0xA8DC, 0x24DF, 0xA8DD, 0x24E0, 0xA8DE, 0x24E1, 0xA8DF, 0x24E2, 0xA8E0, 0x24E3, 0xA8E1, 0x24E4, 0xA8E2, 0x24E5, 0xA8E3, 0x24E6, - 0xA8E4, 0x24E7, 0xA8E5, 0x24E8, 0xA8E6, 0x24E9, 0xA8E7, 0x2460, 0xA8E8, 0x2461, 0xA8E9, 0x2462, 0xA8EA, 0x2463, 0xA8EB, 0x2464, - 0xA8EC, 0x2465, 0xA8ED, 0x2466, 0xA8EE, 0x2467, 0xA8EF, 0x2468, 0xA8F0, 0x2469, 0xA8F1, 0x246A, 0xA8F2, 0x246B, 0xA8F3, 0x246C, - 0xA8F4, 0x246D, 0xA8F5, 0x246E, 0xA8F6, 0x00BD, 0xA8F7, 0x2153, 0xA8F8, 0x2154, 0xA8F9, 0x00BC, 0xA8FA, 0x00BE, 0xA8FB, 0x215B, - 0xA8FC, 0x215C, 0xA8FD, 0x215D, 0xA8FE, 0x215E, 0xA941, 0xCBC5, 0xA942, 0xCBC6, 0xA943, 0xCBC7, 0xA944, 0xCBC8, 0xA945, 0xCBC9, - 0xA946, 0xCBCA, 0xA947, 0xCBCB, 0xA948, 0xCBCC, 0xA949, 0xCBCD, 0xA94A, 0xCBCE, 0xA94B, 0xCBCF, 0xA94C, 0xCBD0, 0xA94D, 0xCBD1, - 0xA94E, 0xCBD2, 0xA94F, 0xCBD3, 0xA950, 0xCBD5, 0xA951, 0xCBD6, 0xA952, 0xCBD7, 0xA953, 0xCBD8, 0xA954, 0xCBD9, 0xA955, 0xCBDA, - 0xA956, 0xCBDB, 0xA957, 0xCBDC, 0xA958, 0xCBDD, 0xA959, 0xCBDE, 0xA95A, 0xCBDF, 0xA961, 0xCBE0, 0xA962, 0xCBE1, 0xA963, 0xCBE2, - 0xA964, 0xCBE3, 0xA965, 0xCBE5, 0xA966, 0xCBE6, 0xA967, 0xCBE8, 0xA968, 0xCBEA, 0xA969, 0xCBEB, 0xA96A, 0xCBEC, 0xA96B, 0xCBED, - 0xA96C, 0xCBEE, 0xA96D, 0xCBEF, 0xA96E, 0xCBF0, 0xA96F, 0xCBF1, 0xA970, 0xCBF2, 0xA971, 0xCBF3, 0xA972, 0xCBF4, 0xA973, 0xCBF5, - 0xA974, 0xCBF6, 0xA975, 0xCBF7, 0xA976, 0xCBF8, 0xA977, 0xCBF9, 0xA978, 0xCBFA, 0xA979, 0xCBFB, 0xA97A, 0xCBFC, 0xA981, 0xCBFD, - 0xA982, 0xCBFE, 0xA983, 0xCBFF, 0xA984, 0xCC00, 0xA985, 0xCC01, 0xA986, 0xCC02, 0xA987, 0xCC03, 0xA988, 0xCC04, 0xA989, 0xCC05, - 0xA98A, 0xCC06, 0xA98B, 0xCC07, 0xA98C, 0xCC08, 0xA98D, 0xCC09, 0xA98E, 0xCC0A, 0xA98F, 0xCC0B, 0xA990, 0xCC0E, 0xA991, 0xCC0F, - 0xA992, 0xCC11, 0xA993, 0xCC12, 0xA994, 0xCC13, 0xA995, 0xCC15, 0xA996, 0xCC16, 0xA997, 0xCC17, 0xA998, 0xCC18, 0xA999, 0xCC19, - 0xA99A, 0xCC1A, 0xA99B, 0xCC1B, 0xA99C, 0xCC1E, 0xA99D, 0xCC1F, 0xA99E, 0xCC20, 0xA99F, 0xCC23, 0xA9A0, 0xCC24, 0xA9A1, 0x00E6, - 0xA9A2, 0x0111, 0xA9A3, 0x00F0, 0xA9A4, 0x0127, 0xA9A5, 0x0131, 0xA9A6, 0x0133, 0xA9A7, 0x0138, 0xA9A8, 0x0140, 0xA9A9, 0x0142, - 0xA9AA, 0x00F8, 0xA9AB, 0x0153, 0xA9AC, 0x00DF, 0xA9AD, 0x00FE, 0xA9AE, 0x0167, 0xA9AF, 0x014B, 0xA9B0, 0x0149, 0xA9B1, 0x3200, - 0xA9B2, 0x3201, 0xA9B3, 0x3202, 0xA9B4, 0x3203, 0xA9B5, 0x3204, 0xA9B6, 0x3205, 0xA9B7, 0x3206, 0xA9B8, 0x3207, 0xA9B9, 0x3208, - 0xA9BA, 0x3209, 0xA9BB, 0x320A, 0xA9BC, 0x320B, 0xA9BD, 0x320C, 0xA9BE, 0x320D, 0xA9BF, 0x320E, 0xA9C0, 0x320F, 0xA9C1, 0x3210, - 0xA9C2, 0x3211, 0xA9C3, 0x3212, 0xA9C4, 0x3213, 0xA9C5, 0x3214, 0xA9C6, 0x3215, 0xA9C7, 0x3216, 0xA9C8, 0x3217, 0xA9C9, 0x3218, - 0xA9CA, 0x3219, 0xA9CB, 0x321A, 0xA9CC, 0x321B, 0xA9CD, 0x249C, 0xA9CE, 0x249D, 0xA9CF, 0x249E, 0xA9D0, 0x249F, 0xA9D1, 0x24A0, - 0xA9D2, 0x24A1, 0xA9D3, 0x24A2, 0xA9D4, 0x24A3, 0xA9D5, 0x24A4, 0xA9D6, 0x24A5, 0xA9D7, 0x24A6, 0xA9D8, 0x24A7, 0xA9D9, 0x24A8, - 0xA9DA, 0x24A9, 0xA9DB, 0x24AA, 0xA9DC, 0x24AB, 0xA9DD, 0x24AC, 0xA9DE, 0x24AD, 0xA9DF, 0x24AE, 0xA9E0, 0x24AF, 0xA9E1, 0x24B0, - 0xA9E2, 0x24B1, 0xA9E3, 0x24B2, 0xA9E4, 0x24B3, 0xA9E5, 0x24B4, 0xA9E6, 0x24B5, 0xA9E7, 0x2474, 0xA9E8, 0x2475, 0xA9E9, 0x2476, - 0xA9EA, 0x2477, 0xA9EB, 0x2478, 0xA9EC, 0x2479, 0xA9ED, 0x247A, 0xA9EE, 0x247B, 0xA9EF, 0x247C, 0xA9F0, 0x247D, 0xA9F1, 0x247E, - 0xA9F2, 0x247F, 0xA9F3, 0x2480, 0xA9F4, 0x2481, 0xA9F5, 0x2482, 0xA9F6, 0x00B9, 0xA9F7, 0x00B2, 0xA9F8, 0x00B3, 0xA9F9, 0x2074, - 0xA9FA, 0x207F, 0xA9FB, 0x2081, 0xA9FC, 0x2082, 0xA9FD, 0x2083, 0xA9FE, 0x2084, 0xAA41, 0xCC25, 0xAA42, 0xCC26, 0xAA43, 0xCC2A, - 0xAA44, 0xCC2B, 0xAA45, 0xCC2D, 0xAA46, 0xCC2F, 0xAA47, 0xCC31, 0xAA48, 0xCC32, 0xAA49, 0xCC33, 0xAA4A, 0xCC34, 0xAA4B, 0xCC35, - 0xAA4C, 0xCC36, 0xAA4D, 0xCC37, 0xAA4E, 0xCC3A, 0xAA4F, 0xCC3F, 0xAA50, 0xCC40, 0xAA51, 0xCC41, 0xAA52, 0xCC42, 0xAA53, 0xCC43, - 0xAA54, 0xCC46, 0xAA55, 0xCC47, 0xAA56, 0xCC49, 0xAA57, 0xCC4A, 0xAA58, 0xCC4B, 0xAA59, 0xCC4D, 0xAA5A, 0xCC4E, 0xAA61, 0xCC4F, - 0xAA62, 0xCC50, 0xAA63, 0xCC51, 0xAA64, 0xCC52, 0xAA65, 0xCC53, 0xAA66, 0xCC56, 0xAA67, 0xCC5A, 0xAA68, 0xCC5B, 0xAA69, 0xCC5C, - 0xAA6A, 0xCC5D, 0xAA6B, 0xCC5E, 0xAA6C, 0xCC5F, 0xAA6D, 0xCC61, 0xAA6E, 0xCC62, 0xAA6F, 0xCC63, 0xAA70, 0xCC65, 0xAA71, 0xCC67, - 0xAA72, 0xCC69, 0xAA73, 0xCC6A, 0xAA74, 0xCC6B, 0xAA75, 0xCC6C, 0xAA76, 0xCC6D, 0xAA77, 0xCC6E, 0xAA78, 0xCC6F, 0xAA79, 0xCC71, - 0xAA7A, 0xCC72, 0xAA81, 0xCC73, 0xAA82, 0xCC74, 0xAA83, 0xCC76, 0xAA84, 0xCC77, 0xAA85, 0xCC78, 0xAA86, 0xCC79, 0xAA87, 0xCC7A, - 0xAA88, 0xCC7B, 0xAA89, 0xCC7C, 0xAA8A, 0xCC7D, 0xAA8B, 0xCC7E, 0xAA8C, 0xCC7F, 0xAA8D, 0xCC80, 0xAA8E, 0xCC81, 0xAA8F, 0xCC82, - 0xAA90, 0xCC83, 0xAA91, 0xCC84, 0xAA92, 0xCC85, 0xAA93, 0xCC86, 0xAA94, 0xCC87, 0xAA95, 0xCC88, 0xAA96, 0xCC89, 0xAA97, 0xCC8A, - 0xAA98, 0xCC8B, 0xAA99, 0xCC8C, 0xAA9A, 0xCC8D, 0xAA9B, 0xCC8E, 0xAA9C, 0xCC8F, 0xAA9D, 0xCC90, 0xAA9E, 0xCC91, 0xAA9F, 0xCC92, - 0xAAA0, 0xCC93, 0xAAA1, 0x3041, 0xAAA2, 0x3042, 0xAAA3, 0x3043, 0xAAA4, 0x3044, 0xAAA5, 0x3045, 0xAAA6, 0x3046, 0xAAA7, 0x3047, - 0xAAA8, 0x3048, 0xAAA9, 0x3049, 0xAAAA, 0x304A, 0xAAAB, 0x304B, 0xAAAC, 0x304C, 0xAAAD, 0x304D, 0xAAAE, 0x304E, 0xAAAF, 0x304F, - 0xAAB0, 0x3050, 0xAAB1, 0x3051, 0xAAB2, 0x3052, 0xAAB3, 0x3053, 0xAAB4, 0x3054, 0xAAB5, 0x3055, 0xAAB6, 0x3056, 0xAAB7, 0x3057, - 0xAAB8, 0x3058, 0xAAB9, 0x3059, 0xAABA, 0x305A, 0xAABB, 0x305B, 0xAABC, 0x305C, 0xAABD, 0x305D, 0xAABE, 0x305E, 0xAABF, 0x305F, - 0xAAC0, 0x3060, 0xAAC1, 0x3061, 0xAAC2, 0x3062, 0xAAC3, 0x3063, 0xAAC4, 0x3064, 0xAAC5, 0x3065, 0xAAC6, 0x3066, 0xAAC7, 0x3067, - 0xAAC8, 0x3068, 0xAAC9, 0x3069, 0xAACA, 0x306A, 0xAACB, 0x306B, 0xAACC, 0x306C, 0xAACD, 0x306D, 0xAACE, 0x306E, 0xAACF, 0x306F, - 0xAAD0, 0x3070, 0xAAD1, 0x3071, 0xAAD2, 0x3072, 0xAAD3, 0x3073, 0xAAD4, 0x3074, 0xAAD5, 0x3075, 0xAAD6, 0x3076, 0xAAD7, 0x3077, - 0xAAD8, 0x3078, 0xAAD9, 0x3079, 0xAADA, 0x307A, 0xAADB, 0x307B, 0xAADC, 0x307C, 0xAADD, 0x307D, 0xAADE, 0x307E, 0xAADF, 0x307F, - 0xAAE0, 0x3080, 0xAAE1, 0x3081, 0xAAE2, 0x3082, 0xAAE3, 0x3083, 0xAAE4, 0x3084, 0xAAE5, 0x3085, 0xAAE6, 0x3086, 0xAAE7, 0x3087, - 0xAAE8, 0x3088, 0xAAE9, 0x3089, 0xAAEA, 0x308A, 0xAAEB, 0x308B, 0xAAEC, 0x308C, 0xAAED, 0x308D, 0xAAEE, 0x308E, 0xAAEF, 0x308F, - 0xAAF0, 0x3090, 0xAAF1, 0x3091, 0xAAF2, 0x3092, 0xAAF3, 0x3093, 0xAB41, 0xCC94, 0xAB42, 0xCC95, 0xAB43, 0xCC96, 0xAB44, 0xCC97, - 0xAB45, 0xCC9A, 0xAB46, 0xCC9B, 0xAB47, 0xCC9D, 0xAB48, 0xCC9E, 0xAB49, 0xCC9F, 0xAB4A, 0xCCA1, 0xAB4B, 0xCCA2, 0xAB4C, 0xCCA3, - 0xAB4D, 0xCCA4, 0xAB4E, 0xCCA5, 0xAB4F, 0xCCA6, 0xAB50, 0xCCA7, 0xAB51, 0xCCAA, 0xAB52, 0xCCAE, 0xAB53, 0xCCAF, 0xAB54, 0xCCB0, - 0xAB55, 0xCCB1, 0xAB56, 0xCCB2, 0xAB57, 0xCCB3, 0xAB58, 0xCCB6, 0xAB59, 0xCCB7, 0xAB5A, 0xCCB9, 0xAB61, 0xCCBA, 0xAB62, 0xCCBB, - 0xAB63, 0xCCBD, 0xAB64, 0xCCBE, 0xAB65, 0xCCBF, 0xAB66, 0xCCC0, 0xAB67, 0xCCC1, 0xAB68, 0xCCC2, 0xAB69, 0xCCC3, 0xAB6A, 0xCCC6, - 0xAB6B, 0xCCC8, 0xAB6C, 0xCCCA, 0xAB6D, 0xCCCB, 0xAB6E, 0xCCCC, 0xAB6F, 0xCCCD, 0xAB70, 0xCCCE, 0xAB71, 0xCCCF, 0xAB72, 0xCCD1, - 0xAB73, 0xCCD2, 0xAB74, 0xCCD3, 0xAB75, 0xCCD5, 0xAB76, 0xCCD6, 0xAB77, 0xCCD7, 0xAB78, 0xCCD8, 0xAB79, 0xCCD9, 0xAB7A, 0xCCDA, - 0xAB81, 0xCCDB, 0xAB82, 0xCCDC, 0xAB83, 0xCCDD, 0xAB84, 0xCCDE, 0xAB85, 0xCCDF, 0xAB86, 0xCCE0, 0xAB87, 0xCCE1, 0xAB88, 0xCCE2, - 0xAB89, 0xCCE3, 0xAB8A, 0xCCE5, 0xAB8B, 0xCCE6, 0xAB8C, 0xCCE7, 0xAB8D, 0xCCE8, 0xAB8E, 0xCCE9, 0xAB8F, 0xCCEA, 0xAB90, 0xCCEB, - 0xAB91, 0xCCED, 0xAB92, 0xCCEE, 0xAB93, 0xCCEF, 0xAB94, 0xCCF1, 0xAB95, 0xCCF2, 0xAB96, 0xCCF3, 0xAB97, 0xCCF4, 0xAB98, 0xCCF5, - 0xAB99, 0xCCF6, 0xAB9A, 0xCCF7, 0xAB9B, 0xCCF8, 0xAB9C, 0xCCF9, 0xAB9D, 0xCCFA, 0xAB9E, 0xCCFB, 0xAB9F, 0xCCFC, 0xABA0, 0xCCFD, - 0xABA1, 0x30A1, 0xABA2, 0x30A2, 0xABA3, 0x30A3, 0xABA4, 0x30A4, 0xABA5, 0x30A5, 0xABA6, 0x30A6, 0xABA7, 0x30A7, 0xABA8, 0x30A8, - 0xABA9, 0x30A9, 0xABAA, 0x30AA, 0xABAB, 0x30AB, 0xABAC, 0x30AC, 0xABAD, 0x30AD, 0xABAE, 0x30AE, 0xABAF, 0x30AF, 0xABB0, 0x30B0, - 0xABB1, 0x30B1, 0xABB2, 0x30B2, 0xABB3, 0x30B3, 0xABB4, 0x30B4, 0xABB5, 0x30B5, 0xABB6, 0x30B6, 0xABB7, 0x30B7, 0xABB8, 0x30B8, - 0xABB9, 0x30B9, 0xABBA, 0x30BA, 0xABBB, 0x30BB, 0xABBC, 0x30BC, 0xABBD, 0x30BD, 0xABBE, 0x30BE, 0xABBF, 0x30BF, 0xABC0, 0x30C0, - 0xABC1, 0x30C1, 0xABC2, 0x30C2, 0xABC3, 0x30C3, 0xABC4, 0x30C4, 0xABC5, 0x30C5, 0xABC6, 0x30C6, 0xABC7, 0x30C7, 0xABC8, 0x30C8, - 0xABC9, 0x30C9, 0xABCA, 0x30CA, 0xABCB, 0x30CB, 0xABCC, 0x30CC, 0xABCD, 0x30CD, 0xABCE, 0x30CE, 0xABCF, 0x30CF, 0xABD0, 0x30D0, - 0xABD1, 0x30D1, 0xABD2, 0x30D2, 0xABD3, 0x30D3, 0xABD4, 0x30D4, 0xABD5, 0x30D5, 0xABD6, 0x30D6, 0xABD7, 0x30D7, 0xABD8, 0x30D8, - 0xABD9, 0x30D9, 0xABDA, 0x30DA, 0xABDB, 0x30DB, 0xABDC, 0x30DC, 0xABDD, 0x30DD, 0xABDE, 0x30DE, 0xABDF, 0x30DF, 0xABE0, 0x30E0, - 0xABE1, 0x30E1, 0xABE2, 0x30E2, 0xABE3, 0x30E3, 0xABE4, 0x30E4, 0xABE5, 0x30E5, 0xABE6, 0x30E6, 0xABE7, 0x30E7, 0xABE8, 0x30E8, - 0xABE9, 0x30E9, 0xABEA, 0x30EA, 0xABEB, 0x30EB, 0xABEC, 0x30EC, 0xABED, 0x30ED, 0xABEE, 0x30EE, 0xABEF, 0x30EF, 0xABF0, 0x30F0, - 0xABF1, 0x30F1, 0xABF2, 0x30F2, 0xABF3, 0x30F3, 0xABF4, 0x30F4, 0xABF5, 0x30F5, 0xABF6, 0x30F6, 0xAC41, 0xCCFE, 0xAC42, 0xCCFF, - 0xAC43, 0xCD00, 0xAC44, 0xCD02, 0xAC45, 0xCD03, 0xAC46, 0xCD04, 0xAC47, 0xCD05, 0xAC48, 0xCD06, 0xAC49, 0xCD07, 0xAC4A, 0xCD0A, - 0xAC4B, 0xCD0B, 0xAC4C, 0xCD0D, 0xAC4D, 0xCD0E, 0xAC4E, 0xCD0F, 0xAC4F, 0xCD11, 0xAC50, 0xCD12, 0xAC51, 0xCD13, 0xAC52, 0xCD14, - 0xAC53, 0xCD15, 0xAC54, 0xCD16, 0xAC55, 0xCD17, 0xAC56, 0xCD1A, 0xAC57, 0xCD1C, 0xAC58, 0xCD1E, 0xAC59, 0xCD1F, 0xAC5A, 0xCD20, - 0xAC61, 0xCD21, 0xAC62, 0xCD22, 0xAC63, 0xCD23, 0xAC64, 0xCD25, 0xAC65, 0xCD26, 0xAC66, 0xCD27, 0xAC67, 0xCD29, 0xAC68, 0xCD2A, - 0xAC69, 0xCD2B, 0xAC6A, 0xCD2D, 0xAC6B, 0xCD2E, 0xAC6C, 0xCD2F, 0xAC6D, 0xCD30, 0xAC6E, 0xCD31, 0xAC6F, 0xCD32, 0xAC70, 0xCD33, - 0xAC71, 0xCD34, 0xAC72, 0xCD35, 0xAC73, 0xCD36, 0xAC74, 0xCD37, 0xAC75, 0xCD38, 0xAC76, 0xCD3A, 0xAC77, 0xCD3B, 0xAC78, 0xCD3C, - 0xAC79, 0xCD3D, 0xAC7A, 0xCD3E, 0xAC81, 0xCD3F, 0xAC82, 0xCD40, 0xAC83, 0xCD41, 0xAC84, 0xCD42, 0xAC85, 0xCD43, 0xAC86, 0xCD44, - 0xAC87, 0xCD45, 0xAC88, 0xCD46, 0xAC89, 0xCD47, 0xAC8A, 0xCD48, 0xAC8B, 0xCD49, 0xAC8C, 0xCD4A, 0xAC8D, 0xCD4B, 0xAC8E, 0xCD4C, - 0xAC8F, 0xCD4D, 0xAC90, 0xCD4E, 0xAC91, 0xCD4F, 0xAC92, 0xCD50, 0xAC93, 0xCD51, 0xAC94, 0xCD52, 0xAC95, 0xCD53, 0xAC96, 0xCD54, - 0xAC97, 0xCD55, 0xAC98, 0xCD56, 0xAC99, 0xCD57, 0xAC9A, 0xCD58, 0xAC9B, 0xCD59, 0xAC9C, 0xCD5A, 0xAC9D, 0xCD5B, 0xAC9E, 0xCD5D, - 0xAC9F, 0xCD5E, 0xACA0, 0xCD5F, 0xACA1, 0x0410, 0xACA2, 0x0411, 0xACA3, 0x0412, 0xACA4, 0x0413, 0xACA5, 0x0414, 0xACA6, 0x0415, - 0xACA7, 0x0401, 0xACA8, 0x0416, 0xACA9, 0x0417, 0xACAA, 0x0418, 0xACAB, 0x0419, 0xACAC, 0x041A, 0xACAD, 0x041B, 0xACAE, 0x041C, - 0xACAF, 0x041D, 0xACB0, 0x041E, 0xACB1, 0x041F, 0xACB2, 0x0420, 0xACB3, 0x0421, 0xACB4, 0x0422, 0xACB5, 0x0423, 0xACB6, 0x0424, - 0xACB7, 0x0425, 0xACB8, 0x0426, 0xACB9, 0x0427, 0xACBA, 0x0428, 0xACBB, 0x0429, 0xACBC, 0x042A, 0xACBD, 0x042B, 0xACBE, 0x042C, - 0xACBF, 0x042D, 0xACC0, 0x042E, 0xACC1, 0x042F, 0xACD1, 0x0430, 0xACD2, 0x0431, 0xACD3, 0x0432, 0xACD4, 0x0433, 0xACD5, 0x0434, - 0xACD6, 0x0435, 0xACD7, 0x0451, 0xACD8, 0x0436, 0xACD9, 0x0437, 0xACDA, 0x0438, 0xACDB, 0x0439, 0xACDC, 0x043A, 0xACDD, 0x043B, - 0xACDE, 0x043C, 0xACDF, 0x043D, 0xACE0, 0x043E, 0xACE1, 0x043F, 0xACE2, 0x0440, 0xACE3, 0x0441, 0xACE4, 0x0442, 0xACE5, 0x0443, - 0xACE6, 0x0444, 0xACE7, 0x0445, 0xACE8, 0x0446, 0xACE9, 0x0447, 0xACEA, 0x0448, 0xACEB, 0x0449, 0xACEC, 0x044A, 0xACED, 0x044B, - 0xACEE, 0x044C, 0xACEF, 0x044D, 0xACF0, 0x044E, 0xACF1, 0x044F, 0xAD41, 0xCD61, 0xAD42, 0xCD62, 0xAD43, 0xCD63, 0xAD44, 0xCD65, - 0xAD45, 0xCD66, 0xAD46, 0xCD67, 0xAD47, 0xCD68, 0xAD48, 0xCD69, 0xAD49, 0xCD6A, 0xAD4A, 0xCD6B, 0xAD4B, 0xCD6E, 0xAD4C, 0xCD70, - 0xAD4D, 0xCD72, 0xAD4E, 0xCD73, 0xAD4F, 0xCD74, 0xAD50, 0xCD75, 0xAD51, 0xCD76, 0xAD52, 0xCD77, 0xAD53, 0xCD79, 0xAD54, 0xCD7A, - 0xAD55, 0xCD7B, 0xAD56, 0xCD7C, 0xAD57, 0xCD7D, 0xAD58, 0xCD7E, 0xAD59, 0xCD7F, 0xAD5A, 0xCD80, 0xAD61, 0xCD81, 0xAD62, 0xCD82, - 0xAD63, 0xCD83, 0xAD64, 0xCD84, 0xAD65, 0xCD85, 0xAD66, 0xCD86, 0xAD67, 0xCD87, 0xAD68, 0xCD89, 0xAD69, 0xCD8A, 0xAD6A, 0xCD8B, - 0xAD6B, 0xCD8C, 0xAD6C, 0xCD8D, 0xAD6D, 0xCD8E, 0xAD6E, 0xCD8F, 0xAD6F, 0xCD90, 0xAD70, 0xCD91, 0xAD71, 0xCD92, 0xAD72, 0xCD93, - 0xAD73, 0xCD96, 0xAD74, 0xCD97, 0xAD75, 0xCD99, 0xAD76, 0xCD9A, 0xAD77, 0xCD9B, 0xAD78, 0xCD9D, 0xAD79, 0xCD9E, 0xAD7A, 0xCD9F, - 0xAD81, 0xCDA0, 0xAD82, 0xCDA1, 0xAD83, 0xCDA2, 0xAD84, 0xCDA3, 0xAD85, 0xCDA6, 0xAD86, 0xCDA8, 0xAD87, 0xCDAA, 0xAD88, 0xCDAB, - 0xAD89, 0xCDAC, 0xAD8A, 0xCDAD, 0xAD8B, 0xCDAE, 0xAD8C, 0xCDAF, 0xAD8D, 0xCDB1, 0xAD8E, 0xCDB2, 0xAD8F, 0xCDB3, 0xAD90, 0xCDB4, - 0xAD91, 0xCDB5, 0xAD92, 0xCDB6, 0xAD93, 0xCDB7, 0xAD94, 0xCDB8, 0xAD95, 0xCDB9, 0xAD96, 0xCDBA, 0xAD97, 0xCDBB, 0xAD98, 0xCDBC, - 0xAD99, 0xCDBD, 0xAD9A, 0xCDBE, 0xAD9B, 0xCDBF, 0xAD9C, 0xCDC0, 0xAD9D, 0xCDC1, 0xAD9E, 0xCDC2, 0xAD9F, 0xCDC3, 0xADA0, 0xCDC5, - 0xAE41, 0xCDC6, 0xAE42, 0xCDC7, 0xAE43, 0xCDC8, 0xAE44, 0xCDC9, 0xAE45, 0xCDCA, 0xAE46, 0xCDCB, 0xAE47, 0xCDCD, 0xAE48, 0xCDCE, - 0xAE49, 0xCDCF, 0xAE4A, 0xCDD1, 0xAE4B, 0xCDD2, 0xAE4C, 0xCDD3, 0xAE4D, 0xCDD4, 0xAE4E, 0xCDD5, 0xAE4F, 0xCDD6, 0xAE50, 0xCDD7, - 0xAE51, 0xCDD8, 0xAE52, 0xCDD9, 0xAE53, 0xCDDA, 0xAE54, 0xCDDB, 0xAE55, 0xCDDC, 0xAE56, 0xCDDD, 0xAE57, 0xCDDE, 0xAE58, 0xCDDF, - 0xAE59, 0xCDE0, 0xAE5A, 0xCDE1, 0xAE61, 0xCDE2, 0xAE62, 0xCDE3, 0xAE63, 0xCDE4, 0xAE64, 0xCDE5, 0xAE65, 0xCDE6, 0xAE66, 0xCDE7, - 0xAE67, 0xCDE9, 0xAE68, 0xCDEA, 0xAE69, 0xCDEB, 0xAE6A, 0xCDED, 0xAE6B, 0xCDEE, 0xAE6C, 0xCDEF, 0xAE6D, 0xCDF1, 0xAE6E, 0xCDF2, - 0xAE6F, 0xCDF3, 0xAE70, 0xCDF4, 0xAE71, 0xCDF5, 0xAE72, 0xCDF6, 0xAE73, 0xCDF7, 0xAE74, 0xCDFA, 0xAE75, 0xCDFC, 0xAE76, 0xCDFE, - 0xAE77, 0xCDFF, 0xAE78, 0xCE00, 0xAE79, 0xCE01, 0xAE7A, 0xCE02, 0xAE81, 0xCE03, 0xAE82, 0xCE05, 0xAE83, 0xCE06, 0xAE84, 0xCE07, - 0xAE85, 0xCE09, 0xAE86, 0xCE0A, 0xAE87, 0xCE0B, 0xAE88, 0xCE0D, 0xAE89, 0xCE0E, 0xAE8A, 0xCE0F, 0xAE8B, 0xCE10, 0xAE8C, 0xCE11, - 0xAE8D, 0xCE12, 0xAE8E, 0xCE13, 0xAE8F, 0xCE15, 0xAE90, 0xCE16, 0xAE91, 0xCE17, 0xAE92, 0xCE18, 0xAE93, 0xCE1A, 0xAE94, 0xCE1B, - 0xAE95, 0xCE1C, 0xAE96, 0xCE1D, 0xAE97, 0xCE1E, 0xAE98, 0xCE1F, 0xAE99, 0xCE22, 0xAE9A, 0xCE23, 0xAE9B, 0xCE25, 0xAE9C, 0xCE26, - 0xAE9D, 0xCE27, 0xAE9E, 0xCE29, 0xAE9F, 0xCE2A, 0xAEA0, 0xCE2B, 0xAF41, 0xCE2C, 0xAF42, 0xCE2D, 0xAF43, 0xCE2E, 0xAF44, 0xCE2F, - 0xAF45, 0xCE32, 0xAF46, 0xCE34, 0xAF47, 0xCE36, 0xAF48, 0xCE37, 0xAF49, 0xCE38, 0xAF4A, 0xCE39, 0xAF4B, 0xCE3A, 0xAF4C, 0xCE3B, - 0xAF4D, 0xCE3C, 0xAF4E, 0xCE3D, 0xAF4F, 0xCE3E, 0xAF50, 0xCE3F, 0xAF51, 0xCE40, 0xAF52, 0xCE41, 0xAF53, 0xCE42, 0xAF54, 0xCE43, - 0xAF55, 0xCE44, 0xAF56, 0xCE45, 0xAF57, 0xCE46, 0xAF58, 0xCE47, 0xAF59, 0xCE48, 0xAF5A, 0xCE49, 0xAF61, 0xCE4A, 0xAF62, 0xCE4B, - 0xAF63, 0xCE4C, 0xAF64, 0xCE4D, 0xAF65, 0xCE4E, 0xAF66, 0xCE4F, 0xAF67, 0xCE50, 0xAF68, 0xCE51, 0xAF69, 0xCE52, 0xAF6A, 0xCE53, - 0xAF6B, 0xCE54, 0xAF6C, 0xCE55, 0xAF6D, 0xCE56, 0xAF6E, 0xCE57, 0xAF6F, 0xCE5A, 0xAF70, 0xCE5B, 0xAF71, 0xCE5D, 0xAF72, 0xCE5E, - 0xAF73, 0xCE62, 0xAF74, 0xCE63, 0xAF75, 0xCE64, 0xAF76, 0xCE65, 0xAF77, 0xCE66, 0xAF78, 0xCE67, 0xAF79, 0xCE6A, 0xAF7A, 0xCE6C, - 0xAF81, 0xCE6E, 0xAF82, 0xCE6F, 0xAF83, 0xCE70, 0xAF84, 0xCE71, 0xAF85, 0xCE72, 0xAF86, 0xCE73, 0xAF87, 0xCE76, 0xAF88, 0xCE77, - 0xAF89, 0xCE79, 0xAF8A, 0xCE7A, 0xAF8B, 0xCE7B, 0xAF8C, 0xCE7D, 0xAF8D, 0xCE7E, 0xAF8E, 0xCE7F, 0xAF8F, 0xCE80, 0xAF90, 0xCE81, - 0xAF91, 0xCE82, 0xAF92, 0xCE83, 0xAF93, 0xCE86, 0xAF94, 0xCE88, 0xAF95, 0xCE8A, 0xAF96, 0xCE8B, 0xAF97, 0xCE8C, 0xAF98, 0xCE8D, - 0xAF99, 0xCE8E, 0xAF9A, 0xCE8F, 0xAF9B, 0xCE92, 0xAF9C, 0xCE93, 0xAF9D, 0xCE95, 0xAF9E, 0xCE96, 0xAF9F, 0xCE97, 0xAFA0, 0xCE99, - 0xB041, 0xCE9A, 0xB042, 0xCE9B, 0xB043, 0xCE9C, 0xB044, 0xCE9D, 0xB045, 0xCE9E, 0xB046, 0xCE9F, 0xB047, 0xCEA2, 0xB048, 0xCEA6, - 0xB049, 0xCEA7, 0xB04A, 0xCEA8, 0xB04B, 0xCEA9, 0xB04C, 0xCEAA, 0xB04D, 0xCEAB, 0xB04E, 0xCEAE, 0xB04F, 0xCEAF, 0xB050, 0xCEB0, - 0xB051, 0xCEB1, 0xB052, 0xCEB2, 0xB053, 0xCEB3, 0xB054, 0xCEB4, 0xB055, 0xCEB5, 0xB056, 0xCEB6, 0xB057, 0xCEB7, 0xB058, 0xCEB8, - 0xB059, 0xCEB9, 0xB05A, 0xCEBA, 0xB061, 0xCEBB, 0xB062, 0xCEBC, 0xB063, 0xCEBD, 0xB064, 0xCEBE, 0xB065, 0xCEBF, 0xB066, 0xCEC0, - 0xB067, 0xCEC2, 0xB068, 0xCEC3, 0xB069, 0xCEC4, 0xB06A, 0xCEC5, 0xB06B, 0xCEC6, 0xB06C, 0xCEC7, 0xB06D, 0xCEC8, 0xB06E, 0xCEC9, - 0xB06F, 0xCECA, 0xB070, 0xCECB, 0xB071, 0xCECC, 0xB072, 0xCECD, 0xB073, 0xCECE, 0xB074, 0xCECF, 0xB075, 0xCED0, 0xB076, 0xCED1, - 0xB077, 0xCED2, 0xB078, 0xCED3, 0xB079, 0xCED4, 0xB07A, 0xCED5, 0xB081, 0xCED6, 0xB082, 0xCED7, 0xB083, 0xCED8, 0xB084, 0xCED9, - 0xB085, 0xCEDA, 0xB086, 0xCEDB, 0xB087, 0xCEDC, 0xB088, 0xCEDD, 0xB089, 0xCEDE, 0xB08A, 0xCEDF, 0xB08B, 0xCEE0, 0xB08C, 0xCEE1, - 0xB08D, 0xCEE2, 0xB08E, 0xCEE3, 0xB08F, 0xCEE6, 0xB090, 0xCEE7, 0xB091, 0xCEE9, 0xB092, 0xCEEA, 0xB093, 0xCEED, 0xB094, 0xCEEE, - 0xB095, 0xCEEF, 0xB096, 0xCEF0, 0xB097, 0xCEF1, 0xB098, 0xCEF2, 0xB099, 0xCEF3, 0xB09A, 0xCEF6, 0xB09B, 0xCEFA, 0xB09C, 0xCEFB, - 0xB09D, 0xCEFC, 0xB09E, 0xCEFD, 0xB09F, 0xCEFE, 0xB0A0, 0xCEFF, 0xB0A1, 0xAC00, 0xB0A2, 0xAC01, 0xB0A3, 0xAC04, 0xB0A4, 0xAC07, - 0xB0A5, 0xAC08, 0xB0A6, 0xAC09, 0xB0A7, 0xAC0A, 0xB0A8, 0xAC10, 0xB0A9, 0xAC11, 0xB0AA, 0xAC12, 0xB0AB, 0xAC13, 0xB0AC, 0xAC14, - 0xB0AD, 0xAC15, 0xB0AE, 0xAC16, 0xB0AF, 0xAC17, 0xB0B0, 0xAC19, 0xB0B1, 0xAC1A, 0xB0B2, 0xAC1B, 0xB0B3, 0xAC1C, 0xB0B4, 0xAC1D, - 0xB0B5, 0xAC20, 0xB0B6, 0xAC24, 0xB0B7, 0xAC2C, 0xB0B8, 0xAC2D, 0xB0B9, 0xAC2F, 0xB0BA, 0xAC30, 0xB0BB, 0xAC31, 0xB0BC, 0xAC38, - 0xB0BD, 0xAC39, 0xB0BE, 0xAC3C, 0xB0BF, 0xAC40, 0xB0C0, 0xAC4B, 0xB0C1, 0xAC4D, 0xB0C2, 0xAC54, 0xB0C3, 0xAC58, 0xB0C4, 0xAC5C, - 0xB0C5, 0xAC70, 0xB0C6, 0xAC71, 0xB0C7, 0xAC74, 0xB0C8, 0xAC77, 0xB0C9, 0xAC78, 0xB0CA, 0xAC7A, 0xB0CB, 0xAC80, 0xB0CC, 0xAC81, - 0xB0CD, 0xAC83, 0xB0CE, 0xAC84, 0xB0CF, 0xAC85, 0xB0D0, 0xAC86, 0xB0D1, 0xAC89, 0xB0D2, 0xAC8A, 0xB0D3, 0xAC8B, 0xB0D4, 0xAC8C, - 0xB0D5, 0xAC90, 0xB0D6, 0xAC94, 0xB0D7, 0xAC9C, 0xB0D8, 0xAC9D, 0xB0D9, 0xAC9F, 0xB0DA, 0xACA0, 0xB0DB, 0xACA1, 0xB0DC, 0xACA8, - 0xB0DD, 0xACA9, 0xB0DE, 0xACAA, 0xB0DF, 0xACAC, 0xB0E0, 0xACAF, 0xB0E1, 0xACB0, 0xB0E2, 0xACB8, 0xB0E3, 0xACB9, 0xB0E4, 0xACBB, - 0xB0E5, 0xACBC, 0xB0E6, 0xACBD, 0xB0E7, 0xACC1, 0xB0E8, 0xACC4, 0xB0E9, 0xACC8, 0xB0EA, 0xACCC, 0xB0EB, 0xACD5, 0xB0EC, 0xACD7, - 0xB0ED, 0xACE0, 0xB0EE, 0xACE1, 0xB0EF, 0xACE4, 0xB0F0, 0xACE7, 0xB0F1, 0xACE8, 0xB0F2, 0xACEA, 0xB0F3, 0xACEC, 0xB0F4, 0xACEF, - 0xB0F5, 0xACF0, 0xB0F6, 0xACF1, 0xB0F7, 0xACF3, 0xB0F8, 0xACF5, 0xB0F9, 0xACF6, 0xB0FA, 0xACFC, 0xB0FB, 0xACFD, 0xB0FC, 0xAD00, - 0xB0FD, 0xAD04, 0xB0FE, 0xAD06, 0xB141, 0xCF02, 0xB142, 0xCF03, 0xB143, 0xCF05, 0xB144, 0xCF06, 0xB145, 0xCF07, 0xB146, 0xCF09, - 0xB147, 0xCF0A, 0xB148, 0xCF0B, 0xB149, 0xCF0C, 0xB14A, 0xCF0D, 0xB14B, 0xCF0E, 0xB14C, 0xCF0F, 0xB14D, 0xCF12, 0xB14E, 0xCF14, - 0xB14F, 0xCF16, 0xB150, 0xCF17, 0xB151, 0xCF18, 0xB152, 0xCF19, 0xB153, 0xCF1A, 0xB154, 0xCF1B, 0xB155, 0xCF1D, 0xB156, 0xCF1E, - 0xB157, 0xCF1F, 0xB158, 0xCF21, 0xB159, 0xCF22, 0xB15A, 0xCF23, 0xB161, 0xCF25, 0xB162, 0xCF26, 0xB163, 0xCF27, 0xB164, 0xCF28, - 0xB165, 0xCF29, 0xB166, 0xCF2A, 0xB167, 0xCF2B, 0xB168, 0xCF2E, 0xB169, 0xCF32, 0xB16A, 0xCF33, 0xB16B, 0xCF34, 0xB16C, 0xCF35, - 0xB16D, 0xCF36, 0xB16E, 0xCF37, 0xB16F, 0xCF39, 0xB170, 0xCF3A, 0xB171, 0xCF3B, 0xB172, 0xCF3C, 0xB173, 0xCF3D, 0xB174, 0xCF3E, - 0xB175, 0xCF3F, 0xB176, 0xCF40, 0xB177, 0xCF41, 0xB178, 0xCF42, 0xB179, 0xCF43, 0xB17A, 0xCF44, 0xB181, 0xCF45, 0xB182, 0xCF46, - 0xB183, 0xCF47, 0xB184, 0xCF48, 0xB185, 0xCF49, 0xB186, 0xCF4A, 0xB187, 0xCF4B, 0xB188, 0xCF4C, 0xB189, 0xCF4D, 0xB18A, 0xCF4E, - 0xB18B, 0xCF4F, 0xB18C, 0xCF50, 0xB18D, 0xCF51, 0xB18E, 0xCF52, 0xB18F, 0xCF53, 0xB190, 0xCF56, 0xB191, 0xCF57, 0xB192, 0xCF59, - 0xB193, 0xCF5A, 0xB194, 0xCF5B, 0xB195, 0xCF5D, 0xB196, 0xCF5E, 0xB197, 0xCF5F, 0xB198, 0xCF60, 0xB199, 0xCF61, 0xB19A, 0xCF62, - 0xB19B, 0xCF63, 0xB19C, 0xCF66, 0xB19D, 0xCF68, 0xB19E, 0xCF6A, 0xB19F, 0xCF6B, 0xB1A0, 0xCF6C, 0xB1A1, 0xAD0C, 0xB1A2, 0xAD0D, - 0xB1A3, 0xAD0F, 0xB1A4, 0xAD11, 0xB1A5, 0xAD18, 0xB1A6, 0xAD1C, 0xB1A7, 0xAD20, 0xB1A8, 0xAD29, 0xB1A9, 0xAD2C, 0xB1AA, 0xAD2D, - 0xB1AB, 0xAD34, 0xB1AC, 0xAD35, 0xB1AD, 0xAD38, 0xB1AE, 0xAD3C, 0xB1AF, 0xAD44, 0xB1B0, 0xAD45, 0xB1B1, 0xAD47, 0xB1B2, 0xAD49, - 0xB1B3, 0xAD50, 0xB1B4, 0xAD54, 0xB1B5, 0xAD58, 0xB1B6, 0xAD61, 0xB1B7, 0xAD63, 0xB1B8, 0xAD6C, 0xB1B9, 0xAD6D, 0xB1BA, 0xAD70, - 0xB1BB, 0xAD73, 0xB1BC, 0xAD74, 0xB1BD, 0xAD75, 0xB1BE, 0xAD76, 0xB1BF, 0xAD7B, 0xB1C0, 0xAD7C, 0xB1C1, 0xAD7D, 0xB1C2, 0xAD7F, - 0xB1C3, 0xAD81, 0xB1C4, 0xAD82, 0xB1C5, 0xAD88, 0xB1C6, 0xAD89, 0xB1C7, 0xAD8C, 0xB1C8, 0xAD90, 0xB1C9, 0xAD9C, 0xB1CA, 0xAD9D, - 0xB1CB, 0xADA4, 0xB1CC, 0xADB7, 0xB1CD, 0xADC0, 0xB1CE, 0xADC1, 0xB1CF, 0xADC4, 0xB1D0, 0xADC8, 0xB1D1, 0xADD0, 0xB1D2, 0xADD1, - 0xB1D3, 0xADD3, 0xB1D4, 0xADDC, 0xB1D5, 0xADE0, 0xB1D6, 0xADE4, 0xB1D7, 0xADF8, 0xB1D8, 0xADF9, 0xB1D9, 0xADFC, 0xB1DA, 0xADFF, - 0xB1DB, 0xAE00, 0xB1DC, 0xAE01, 0xB1DD, 0xAE08, 0xB1DE, 0xAE09, 0xB1DF, 0xAE0B, 0xB1E0, 0xAE0D, 0xB1E1, 0xAE14, 0xB1E2, 0xAE30, - 0xB1E3, 0xAE31, 0xB1E4, 0xAE34, 0xB1E5, 0xAE37, 0xB1E6, 0xAE38, 0xB1E7, 0xAE3A, 0xB1E8, 0xAE40, 0xB1E9, 0xAE41, 0xB1EA, 0xAE43, - 0xB1EB, 0xAE45, 0xB1EC, 0xAE46, 0xB1ED, 0xAE4A, 0xB1EE, 0xAE4C, 0xB1EF, 0xAE4D, 0xB1F0, 0xAE4E, 0xB1F1, 0xAE50, 0xB1F2, 0xAE54, - 0xB1F3, 0xAE56, 0xB1F4, 0xAE5C, 0xB1F5, 0xAE5D, 0xB1F6, 0xAE5F, 0xB1F7, 0xAE60, 0xB1F8, 0xAE61, 0xB1F9, 0xAE65, 0xB1FA, 0xAE68, - 0xB1FB, 0xAE69, 0xB1FC, 0xAE6C, 0xB1FD, 0xAE70, 0xB1FE, 0xAE78, 0xB241, 0xCF6D, 0xB242, 0xCF6E, 0xB243, 0xCF6F, 0xB244, 0xCF72, - 0xB245, 0xCF73, 0xB246, 0xCF75, 0xB247, 0xCF76, 0xB248, 0xCF77, 0xB249, 0xCF79, 0xB24A, 0xCF7A, 0xB24B, 0xCF7B, 0xB24C, 0xCF7C, - 0xB24D, 0xCF7D, 0xB24E, 0xCF7E, 0xB24F, 0xCF7F, 0xB250, 0xCF81, 0xB251, 0xCF82, 0xB252, 0xCF83, 0xB253, 0xCF84, 0xB254, 0xCF86, - 0xB255, 0xCF87, 0xB256, 0xCF88, 0xB257, 0xCF89, 0xB258, 0xCF8A, 0xB259, 0xCF8B, 0xB25A, 0xCF8D, 0xB261, 0xCF8E, 0xB262, 0xCF8F, - 0xB263, 0xCF90, 0xB264, 0xCF91, 0xB265, 0xCF92, 0xB266, 0xCF93, 0xB267, 0xCF94, 0xB268, 0xCF95, 0xB269, 0xCF96, 0xB26A, 0xCF97, - 0xB26B, 0xCF98, 0xB26C, 0xCF99, 0xB26D, 0xCF9A, 0xB26E, 0xCF9B, 0xB26F, 0xCF9C, 0xB270, 0xCF9D, 0xB271, 0xCF9E, 0xB272, 0xCF9F, - 0xB273, 0xCFA0, 0xB274, 0xCFA2, 0xB275, 0xCFA3, 0xB276, 0xCFA4, 0xB277, 0xCFA5, 0xB278, 0xCFA6, 0xB279, 0xCFA7, 0xB27A, 0xCFA9, - 0xB281, 0xCFAA, 0xB282, 0xCFAB, 0xB283, 0xCFAC, 0xB284, 0xCFAD, 0xB285, 0xCFAE, 0xB286, 0xCFAF, 0xB287, 0xCFB1, 0xB288, 0xCFB2, - 0xB289, 0xCFB3, 0xB28A, 0xCFB4, 0xB28B, 0xCFB5, 0xB28C, 0xCFB6, 0xB28D, 0xCFB7, 0xB28E, 0xCFB8, 0xB28F, 0xCFB9, 0xB290, 0xCFBA, - 0xB291, 0xCFBB, 0xB292, 0xCFBC, 0xB293, 0xCFBD, 0xB294, 0xCFBE, 0xB295, 0xCFBF, 0xB296, 0xCFC0, 0xB297, 0xCFC1, 0xB298, 0xCFC2, - 0xB299, 0xCFC3, 0xB29A, 0xCFC5, 0xB29B, 0xCFC6, 0xB29C, 0xCFC7, 0xB29D, 0xCFC8, 0xB29E, 0xCFC9, 0xB29F, 0xCFCA, 0xB2A0, 0xCFCB, - 0xB2A1, 0xAE79, 0xB2A2, 0xAE7B, 0xB2A3, 0xAE7C, 0xB2A4, 0xAE7D, 0xB2A5, 0xAE84, 0xB2A6, 0xAE85, 0xB2A7, 0xAE8C, 0xB2A8, 0xAEBC, - 0xB2A9, 0xAEBD, 0xB2AA, 0xAEBE, 0xB2AB, 0xAEC0, 0xB2AC, 0xAEC4, 0xB2AD, 0xAECC, 0xB2AE, 0xAECD, 0xB2AF, 0xAECF, 0xB2B0, 0xAED0, - 0xB2B1, 0xAED1, 0xB2B2, 0xAED8, 0xB2B3, 0xAED9, 0xB2B4, 0xAEDC, 0xB2B5, 0xAEE8, 0xB2B6, 0xAEEB, 0xB2B7, 0xAEED, 0xB2B8, 0xAEF4, - 0xB2B9, 0xAEF8, 0xB2BA, 0xAEFC, 0xB2BB, 0xAF07, 0xB2BC, 0xAF08, 0xB2BD, 0xAF0D, 0xB2BE, 0xAF10, 0xB2BF, 0xAF2C, 0xB2C0, 0xAF2D, - 0xB2C1, 0xAF30, 0xB2C2, 0xAF32, 0xB2C3, 0xAF34, 0xB2C4, 0xAF3C, 0xB2C5, 0xAF3D, 0xB2C6, 0xAF3F, 0xB2C7, 0xAF41, 0xB2C8, 0xAF42, - 0xB2C9, 0xAF43, 0xB2CA, 0xAF48, 0xB2CB, 0xAF49, 0xB2CC, 0xAF50, 0xB2CD, 0xAF5C, 0xB2CE, 0xAF5D, 0xB2CF, 0xAF64, 0xB2D0, 0xAF65, - 0xB2D1, 0xAF79, 0xB2D2, 0xAF80, 0xB2D3, 0xAF84, 0xB2D4, 0xAF88, 0xB2D5, 0xAF90, 0xB2D6, 0xAF91, 0xB2D7, 0xAF95, 0xB2D8, 0xAF9C, - 0xB2D9, 0xAFB8, 0xB2DA, 0xAFB9, 0xB2DB, 0xAFBC, 0xB2DC, 0xAFC0, 0xB2DD, 0xAFC7, 0xB2DE, 0xAFC8, 0xB2DF, 0xAFC9, 0xB2E0, 0xAFCB, - 0xB2E1, 0xAFCD, 0xB2E2, 0xAFCE, 0xB2E3, 0xAFD4, 0xB2E4, 0xAFDC, 0xB2E5, 0xAFE8, 0xB2E6, 0xAFE9, 0xB2E7, 0xAFF0, 0xB2E8, 0xAFF1, - 0xB2E9, 0xAFF4, 0xB2EA, 0xAFF8, 0xB2EB, 0xB000, 0xB2EC, 0xB001, 0xB2ED, 0xB004, 0xB2EE, 0xB00C, 0xB2EF, 0xB010, 0xB2F0, 0xB014, - 0xB2F1, 0xB01C, 0xB2F2, 0xB01D, 0xB2F3, 0xB028, 0xB2F4, 0xB044, 0xB2F5, 0xB045, 0xB2F6, 0xB048, 0xB2F7, 0xB04A, 0xB2F8, 0xB04C, - 0xB2F9, 0xB04E, 0xB2FA, 0xB053, 0xB2FB, 0xB054, 0xB2FC, 0xB055, 0xB2FD, 0xB057, 0xB2FE, 0xB059, 0xB341, 0xCFCC, 0xB342, 0xCFCD, - 0xB343, 0xCFCE, 0xB344, 0xCFCF, 0xB345, 0xCFD0, 0xB346, 0xCFD1, 0xB347, 0xCFD2, 0xB348, 0xCFD3, 0xB349, 0xCFD4, 0xB34A, 0xCFD5, - 0xB34B, 0xCFD6, 0xB34C, 0xCFD7, 0xB34D, 0xCFD8, 0xB34E, 0xCFD9, 0xB34F, 0xCFDA, 0xB350, 0xCFDB, 0xB351, 0xCFDC, 0xB352, 0xCFDD, - 0xB353, 0xCFDE, 0xB354, 0xCFDF, 0xB355, 0xCFE2, 0xB356, 0xCFE3, 0xB357, 0xCFE5, 0xB358, 0xCFE6, 0xB359, 0xCFE7, 0xB35A, 0xCFE9, - 0xB361, 0xCFEA, 0xB362, 0xCFEB, 0xB363, 0xCFEC, 0xB364, 0xCFED, 0xB365, 0xCFEE, 0xB366, 0xCFEF, 0xB367, 0xCFF2, 0xB368, 0xCFF4, - 0xB369, 0xCFF6, 0xB36A, 0xCFF7, 0xB36B, 0xCFF8, 0xB36C, 0xCFF9, 0xB36D, 0xCFFA, 0xB36E, 0xCFFB, 0xB36F, 0xCFFD, 0xB370, 0xCFFE, - 0xB371, 0xCFFF, 0xB372, 0xD001, 0xB373, 0xD002, 0xB374, 0xD003, 0xB375, 0xD005, 0xB376, 0xD006, 0xB377, 0xD007, 0xB378, 0xD008, - 0xB379, 0xD009, 0xB37A, 0xD00A, 0xB381, 0xD00B, 0xB382, 0xD00C, 0xB383, 0xD00D, 0xB384, 0xD00E, 0xB385, 0xD00F, 0xB386, 0xD010, - 0xB387, 0xD012, 0xB388, 0xD013, 0xB389, 0xD014, 0xB38A, 0xD015, 0xB38B, 0xD016, 0xB38C, 0xD017, 0xB38D, 0xD019, 0xB38E, 0xD01A, - 0xB38F, 0xD01B, 0xB390, 0xD01C, 0xB391, 0xD01D, 0xB392, 0xD01E, 0xB393, 0xD01F, 0xB394, 0xD020, 0xB395, 0xD021, 0xB396, 0xD022, - 0xB397, 0xD023, 0xB398, 0xD024, 0xB399, 0xD025, 0xB39A, 0xD026, 0xB39B, 0xD027, 0xB39C, 0xD028, 0xB39D, 0xD029, 0xB39E, 0xD02A, - 0xB39F, 0xD02B, 0xB3A0, 0xD02C, 0xB3A1, 0xB05D, 0xB3A2, 0xB07C, 0xB3A3, 0xB07D, 0xB3A4, 0xB080, 0xB3A5, 0xB084, 0xB3A6, 0xB08C, - 0xB3A7, 0xB08D, 0xB3A8, 0xB08F, 0xB3A9, 0xB091, 0xB3AA, 0xB098, 0xB3AB, 0xB099, 0xB3AC, 0xB09A, 0xB3AD, 0xB09C, 0xB3AE, 0xB09F, - 0xB3AF, 0xB0A0, 0xB3B0, 0xB0A1, 0xB3B1, 0xB0A2, 0xB3B2, 0xB0A8, 0xB3B3, 0xB0A9, 0xB3B4, 0xB0AB, 0xB3B5, 0xB0AC, 0xB3B6, 0xB0AD, - 0xB3B7, 0xB0AE, 0xB3B8, 0xB0AF, 0xB3B9, 0xB0B1, 0xB3BA, 0xB0B3, 0xB3BB, 0xB0B4, 0xB3BC, 0xB0B5, 0xB3BD, 0xB0B8, 0xB3BE, 0xB0BC, - 0xB3BF, 0xB0C4, 0xB3C0, 0xB0C5, 0xB3C1, 0xB0C7, 0xB3C2, 0xB0C8, 0xB3C3, 0xB0C9, 0xB3C4, 0xB0D0, 0xB3C5, 0xB0D1, 0xB3C6, 0xB0D4, - 0xB3C7, 0xB0D8, 0xB3C8, 0xB0E0, 0xB3C9, 0xB0E5, 0xB3CA, 0xB108, 0xB3CB, 0xB109, 0xB3CC, 0xB10B, 0xB3CD, 0xB10C, 0xB3CE, 0xB110, - 0xB3CF, 0xB112, 0xB3D0, 0xB113, 0xB3D1, 0xB118, 0xB3D2, 0xB119, 0xB3D3, 0xB11B, 0xB3D4, 0xB11C, 0xB3D5, 0xB11D, 0xB3D6, 0xB123, - 0xB3D7, 0xB124, 0xB3D8, 0xB125, 0xB3D9, 0xB128, 0xB3DA, 0xB12C, 0xB3DB, 0xB134, 0xB3DC, 0xB135, 0xB3DD, 0xB137, 0xB3DE, 0xB138, - 0xB3DF, 0xB139, 0xB3E0, 0xB140, 0xB3E1, 0xB141, 0xB3E2, 0xB144, 0xB3E3, 0xB148, 0xB3E4, 0xB150, 0xB3E5, 0xB151, 0xB3E6, 0xB154, - 0xB3E7, 0xB155, 0xB3E8, 0xB158, 0xB3E9, 0xB15C, 0xB3EA, 0xB160, 0xB3EB, 0xB178, 0xB3EC, 0xB179, 0xB3ED, 0xB17C, 0xB3EE, 0xB180, - 0xB3EF, 0xB182, 0xB3F0, 0xB188, 0xB3F1, 0xB189, 0xB3F2, 0xB18B, 0xB3F3, 0xB18D, 0xB3F4, 0xB192, 0xB3F5, 0xB193, 0xB3F6, 0xB194, - 0xB3F7, 0xB198, 0xB3F8, 0xB19C, 0xB3F9, 0xB1A8, 0xB3FA, 0xB1CC, 0xB3FB, 0xB1D0, 0xB3FC, 0xB1D4, 0xB3FD, 0xB1DC, 0xB3FE, 0xB1DD, - 0xB441, 0xD02E, 0xB442, 0xD02F, 0xB443, 0xD030, 0xB444, 0xD031, 0xB445, 0xD032, 0xB446, 0xD033, 0xB447, 0xD036, 0xB448, 0xD037, - 0xB449, 0xD039, 0xB44A, 0xD03A, 0xB44B, 0xD03B, 0xB44C, 0xD03D, 0xB44D, 0xD03E, 0xB44E, 0xD03F, 0xB44F, 0xD040, 0xB450, 0xD041, - 0xB451, 0xD042, 0xB452, 0xD043, 0xB453, 0xD046, 0xB454, 0xD048, 0xB455, 0xD04A, 0xB456, 0xD04B, 0xB457, 0xD04C, 0xB458, 0xD04D, - 0xB459, 0xD04E, 0xB45A, 0xD04F, 0xB461, 0xD051, 0xB462, 0xD052, 0xB463, 0xD053, 0xB464, 0xD055, 0xB465, 0xD056, 0xB466, 0xD057, - 0xB467, 0xD059, 0xB468, 0xD05A, 0xB469, 0xD05B, 0xB46A, 0xD05C, 0xB46B, 0xD05D, 0xB46C, 0xD05E, 0xB46D, 0xD05F, 0xB46E, 0xD061, - 0xB46F, 0xD062, 0xB470, 0xD063, 0xB471, 0xD064, 0xB472, 0xD065, 0xB473, 0xD066, 0xB474, 0xD067, 0xB475, 0xD068, 0xB476, 0xD069, - 0xB477, 0xD06A, 0xB478, 0xD06B, 0xB479, 0xD06E, 0xB47A, 0xD06F, 0xB481, 0xD071, 0xB482, 0xD072, 0xB483, 0xD073, 0xB484, 0xD075, - 0xB485, 0xD076, 0xB486, 0xD077, 0xB487, 0xD078, 0xB488, 0xD079, 0xB489, 0xD07A, 0xB48A, 0xD07B, 0xB48B, 0xD07E, 0xB48C, 0xD07F, - 0xB48D, 0xD080, 0xB48E, 0xD082, 0xB48F, 0xD083, 0xB490, 0xD084, 0xB491, 0xD085, 0xB492, 0xD086, 0xB493, 0xD087, 0xB494, 0xD088, - 0xB495, 0xD089, 0xB496, 0xD08A, 0xB497, 0xD08B, 0xB498, 0xD08C, 0xB499, 0xD08D, 0xB49A, 0xD08E, 0xB49B, 0xD08F, 0xB49C, 0xD090, - 0xB49D, 0xD091, 0xB49E, 0xD092, 0xB49F, 0xD093, 0xB4A0, 0xD094, 0xB4A1, 0xB1DF, 0xB4A2, 0xB1E8, 0xB4A3, 0xB1E9, 0xB4A4, 0xB1EC, - 0xB4A5, 0xB1F0, 0xB4A6, 0xB1F9, 0xB4A7, 0xB1FB, 0xB4A8, 0xB1FD, 0xB4A9, 0xB204, 0xB4AA, 0xB205, 0xB4AB, 0xB208, 0xB4AC, 0xB20B, - 0xB4AD, 0xB20C, 0xB4AE, 0xB214, 0xB4AF, 0xB215, 0xB4B0, 0xB217, 0xB4B1, 0xB219, 0xB4B2, 0xB220, 0xB4B3, 0xB234, 0xB4B4, 0xB23C, - 0xB4B5, 0xB258, 0xB4B6, 0xB25C, 0xB4B7, 0xB260, 0xB4B8, 0xB268, 0xB4B9, 0xB269, 0xB4BA, 0xB274, 0xB4BB, 0xB275, 0xB4BC, 0xB27C, - 0xB4BD, 0xB284, 0xB4BE, 0xB285, 0xB4BF, 0xB289, 0xB4C0, 0xB290, 0xB4C1, 0xB291, 0xB4C2, 0xB294, 0xB4C3, 0xB298, 0xB4C4, 0xB299, - 0xB4C5, 0xB29A, 0xB4C6, 0xB2A0, 0xB4C7, 0xB2A1, 0xB4C8, 0xB2A3, 0xB4C9, 0xB2A5, 0xB4CA, 0xB2A6, 0xB4CB, 0xB2AA, 0xB4CC, 0xB2AC, - 0xB4CD, 0xB2B0, 0xB4CE, 0xB2B4, 0xB4CF, 0xB2C8, 0xB4D0, 0xB2C9, 0xB4D1, 0xB2CC, 0xB4D2, 0xB2D0, 0xB4D3, 0xB2D2, 0xB4D4, 0xB2D8, - 0xB4D5, 0xB2D9, 0xB4D6, 0xB2DB, 0xB4D7, 0xB2DD, 0xB4D8, 0xB2E2, 0xB4D9, 0xB2E4, 0xB4DA, 0xB2E5, 0xB4DB, 0xB2E6, 0xB4DC, 0xB2E8, - 0xB4DD, 0xB2EB, 0xB4DE, 0xB2EC, 0xB4DF, 0xB2ED, 0xB4E0, 0xB2EE, 0xB4E1, 0xB2EF, 0xB4E2, 0xB2F3, 0xB4E3, 0xB2F4, 0xB4E4, 0xB2F5, - 0xB4E5, 0xB2F7, 0xB4E6, 0xB2F8, 0xB4E7, 0xB2F9, 0xB4E8, 0xB2FA, 0xB4E9, 0xB2FB, 0xB4EA, 0xB2FF, 0xB4EB, 0xB300, 0xB4EC, 0xB301, - 0xB4ED, 0xB304, 0xB4EE, 0xB308, 0xB4EF, 0xB310, 0xB4F0, 0xB311, 0xB4F1, 0xB313, 0xB4F2, 0xB314, 0xB4F3, 0xB315, 0xB4F4, 0xB31C, - 0xB4F5, 0xB354, 0xB4F6, 0xB355, 0xB4F7, 0xB356, 0xB4F8, 0xB358, 0xB4F9, 0xB35B, 0xB4FA, 0xB35C, 0xB4FB, 0xB35E, 0xB4FC, 0xB35F, - 0xB4FD, 0xB364, 0xB4FE, 0xB365, 0xB541, 0xD095, 0xB542, 0xD096, 0xB543, 0xD097, 0xB544, 0xD098, 0xB545, 0xD099, 0xB546, 0xD09A, - 0xB547, 0xD09B, 0xB548, 0xD09C, 0xB549, 0xD09D, 0xB54A, 0xD09E, 0xB54B, 0xD09F, 0xB54C, 0xD0A0, 0xB54D, 0xD0A1, 0xB54E, 0xD0A2, - 0xB54F, 0xD0A3, 0xB550, 0xD0A6, 0xB551, 0xD0A7, 0xB552, 0xD0A9, 0xB553, 0xD0AA, 0xB554, 0xD0AB, 0xB555, 0xD0AD, 0xB556, 0xD0AE, - 0xB557, 0xD0AF, 0xB558, 0xD0B0, 0xB559, 0xD0B1, 0xB55A, 0xD0B2, 0xB561, 0xD0B3, 0xB562, 0xD0B6, 0xB563, 0xD0B8, 0xB564, 0xD0BA, - 0xB565, 0xD0BB, 0xB566, 0xD0BC, 0xB567, 0xD0BD, 0xB568, 0xD0BE, 0xB569, 0xD0BF, 0xB56A, 0xD0C2, 0xB56B, 0xD0C3, 0xB56C, 0xD0C5, - 0xB56D, 0xD0C6, 0xB56E, 0xD0C7, 0xB56F, 0xD0CA, 0xB570, 0xD0CB, 0xB571, 0xD0CC, 0xB572, 0xD0CD, 0xB573, 0xD0CE, 0xB574, 0xD0CF, - 0xB575, 0xD0D2, 0xB576, 0xD0D6, 0xB577, 0xD0D7, 0xB578, 0xD0D8, 0xB579, 0xD0D9, 0xB57A, 0xD0DA, 0xB581, 0xD0DB, 0xB582, 0xD0DE, - 0xB583, 0xD0DF, 0xB584, 0xD0E1, 0xB585, 0xD0E2, 0xB586, 0xD0E3, 0xB587, 0xD0E5, 0xB588, 0xD0E6, 0xB589, 0xD0E7, 0xB58A, 0xD0E8, - 0xB58B, 0xD0E9, 0xB58C, 0xD0EA, 0xB58D, 0xD0EB, 0xB58E, 0xD0EE, 0xB58F, 0xD0F2, 0xB590, 0xD0F3, 0xB591, 0xD0F4, 0xB592, 0xD0F5, - 0xB593, 0xD0F6, 0xB594, 0xD0F7, 0xB595, 0xD0F9, 0xB596, 0xD0FA, 0xB597, 0xD0FB, 0xB598, 0xD0FC, 0xB599, 0xD0FD, 0xB59A, 0xD0FE, - 0xB59B, 0xD0FF, 0xB59C, 0xD100, 0xB59D, 0xD101, 0xB59E, 0xD102, 0xB59F, 0xD103, 0xB5A0, 0xD104, 0xB5A1, 0xB367, 0xB5A2, 0xB369, - 0xB5A3, 0xB36B, 0xB5A4, 0xB36E, 0xB5A5, 0xB370, 0xB5A6, 0xB371, 0xB5A7, 0xB374, 0xB5A8, 0xB378, 0xB5A9, 0xB380, 0xB5AA, 0xB381, - 0xB5AB, 0xB383, 0xB5AC, 0xB384, 0xB5AD, 0xB385, 0xB5AE, 0xB38C, 0xB5AF, 0xB390, 0xB5B0, 0xB394, 0xB5B1, 0xB3A0, 0xB5B2, 0xB3A1, - 0xB5B3, 0xB3A8, 0xB5B4, 0xB3AC, 0xB5B5, 0xB3C4, 0xB5B6, 0xB3C5, 0xB5B7, 0xB3C8, 0xB5B8, 0xB3CB, 0xB5B9, 0xB3CC, 0xB5BA, 0xB3CE, - 0xB5BB, 0xB3D0, 0xB5BC, 0xB3D4, 0xB5BD, 0xB3D5, 0xB5BE, 0xB3D7, 0xB5BF, 0xB3D9, 0xB5C0, 0xB3DB, 0xB5C1, 0xB3DD, 0xB5C2, 0xB3E0, - 0xB5C3, 0xB3E4, 0xB5C4, 0xB3E8, 0xB5C5, 0xB3FC, 0xB5C6, 0xB410, 0xB5C7, 0xB418, 0xB5C8, 0xB41C, 0xB5C9, 0xB420, 0xB5CA, 0xB428, - 0xB5CB, 0xB429, 0xB5CC, 0xB42B, 0xB5CD, 0xB434, 0xB5CE, 0xB450, 0xB5CF, 0xB451, 0xB5D0, 0xB454, 0xB5D1, 0xB458, 0xB5D2, 0xB460, - 0xB5D3, 0xB461, 0xB5D4, 0xB463, 0xB5D5, 0xB465, 0xB5D6, 0xB46C, 0xB5D7, 0xB480, 0xB5D8, 0xB488, 0xB5D9, 0xB49D, 0xB5DA, 0xB4A4, - 0xB5DB, 0xB4A8, 0xB5DC, 0xB4AC, 0xB5DD, 0xB4B5, 0xB5DE, 0xB4B7, 0xB5DF, 0xB4B9, 0xB5E0, 0xB4C0, 0xB5E1, 0xB4C4, 0xB5E2, 0xB4C8, - 0xB5E3, 0xB4D0, 0xB5E4, 0xB4D5, 0xB5E5, 0xB4DC, 0xB5E6, 0xB4DD, 0xB5E7, 0xB4E0, 0xB5E8, 0xB4E3, 0xB5E9, 0xB4E4, 0xB5EA, 0xB4E6, - 0xB5EB, 0xB4EC, 0xB5EC, 0xB4ED, 0xB5ED, 0xB4EF, 0xB5EE, 0xB4F1, 0xB5EF, 0xB4F8, 0xB5F0, 0xB514, 0xB5F1, 0xB515, 0xB5F2, 0xB518, - 0xB5F3, 0xB51B, 0xB5F4, 0xB51C, 0xB5F5, 0xB524, 0xB5F6, 0xB525, 0xB5F7, 0xB527, 0xB5F8, 0xB528, 0xB5F9, 0xB529, 0xB5FA, 0xB52A, - 0xB5FB, 0xB530, 0xB5FC, 0xB531, 0xB5FD, 0xB534, 0xB5FE, 0xB538, 0xB641, 0xD105, 0xB642, 0xD106, 0xB643, 0xD107, 0xB644, 0xD108, - 0xB645, 0xD109, 0xB646, 0xD10A, 0xB647, 0xD10B, 0xB648, 0xD10C, 0xB649, 0xD10E, 0xB64A, 0xD10F, 0xB64B, 0xD110, 0xB64C, 0xD111, - 0xB64D, 0xD112, 0xB64E, 0xD113, 0xB64F, 0xD114, 0xB650, 0xD115, 0xB651, 0xD116, 0xB652, 0xD117, 0xB653, 0xD118, 0xB654, 0xD119, - 0xB655, 0xD11A, 0xB656, 0xD11B, 0xB657, 0xD11C, 0xB658, 0xD11D, 0xB659, 0xD11E, 0xB65A, 0xD11F, 0xB661, 0xD120, 0xB662, 0xD121, - 0xB663, 0xD122, 0xB664, 0xD123, 0xB665, 0xD124, 0xB666, 0xD125, 0xB667, 0xD126, 0xB668, 0xD127, 0xB669, 0xD128, 0xB66A, 0xD129, - 0xB66B, 0xD12A, 0xB66C, 0xD12B, 0xB66D, 0xD12C, 0xB66E, 0xD12D, 0xB66F, 0xD12E, 0xB670, 0xD12F, 0xB671, 0xD132, 0xB672, 0xD133, - 0xB673, 0xD135, 0xB674, 0xD136, 0xB675, 0xD137, 0xB676, 0xD139, 0xB677, 0xD13B, 0xB678, 0xD13C, 0xB679, 0xD13D, 0xB67A, 0xD13E, - 0xB681, 0xD13F, 0xB682, 0xD142, 0xB683, 0xD146, 0xB684, 0xD147, 0xB685, 0xD148, 0xB686, 0xD149, 0xB687, 0xD14A, 0xB688, 0xD14B, - 0xB689, 0xD14E, 0xB68A, 0xD14F, 0xB68B, 0xD151, 0xB68C, 0xD152, 0xB68D, 0xD153, 0xB68E, 0xD155, 0xB68F, 0xD156, 0xB690, 0xD157, - 0xB691, 0xD158, 0xB692, 0xD159, 0xB693, 0xD15A, 0xB694, 0xD15B, 0xB695, 0xD15E, 0xB696, 0xD160, 0xB697, 0xD162, 0xB698, 0xD163, - 0xB699, 0xD164, 0xB69A, 0xD165, 0xB69B, 0xD166, 0xB69C, 0xD167, 0xB69D, 0xD169, 0xB69E, 0xD16A, 0xB69F, 0xD16B, 0xB6A0, 0xD16D, - 0xB6A1, 0xB540, 0xB6A2, 0xB541, 0xB6A3, 0xB543, 0xB6A4, 0xB544, 0xB6A5, 0xB545, 0xB6A6, 0xB54B, 0xB6A7, 0xB54C, 0xB6A8, 0xB54D, - 0xB6A9, 0xB550, 0xB6AA, 0xB554, 0xB6AB, 0xB55C, 0xB6AC, 0xB55D, 0xB6AD, 0xB55F, 0xB6AE, 0xB560, 0xB6AF, 0xB561, 0xB6B0, 0xB5A0, - 0xB6B1, 0xB5A1, 0xB6B2, 0xB5A4, 0xB6B3, 0xB5A8, 0xB6B4, 0xB5AA, 0xB6B5, 0xB5AB, 0xB6B6, 0xB5B0, 0xB6B7, 0xB5B1, 0xB6B8, 0xB5B3, - 0xB6B9, 0xB5B4, 0xB6BA, 0xB5B5, 0xB6BB, 0xB5BB, 0xB6BC, 0xB5BC, 0xB6BD, 0xB5BD, 0xB6BE, 0xB5C0, 0xB6BF, 0xB5C4, 0xB6C0, 0xB5CC, - 0xB6C1, 0xB5CD, 0xB6C2, 0xB5CF, 0xB6C3, 0xB5D0, 0xB6C4, 0xB5D1, 0xB6C5, 0xB5D8, 0xB6C6, 0xB5EC, 0xB6C7, 0xB610, 0xB6C8, 0xB611, - 0xB6C9, 0xB614, 0xB6CA, 0xB618, 0xB6CB, 0xB625, 0xB6CC, 0xB62C, 0xB6CD, 0xB634, 0xB6CE, 0xB648, 0xB6CF, 0xB664, 0xB6D0, 0xB668, - 0xB6D1, 0xB69C, 0xB6D2, 0xB69D, 0xB6D3, 0xB6A0, 0xB6D4, 0xB6A4, 0xB6D5, 0xB6AB, 0xB6D6, 0xB6AC, 0xB6D7, 0xB6B1, 0xB6D8, 0xB6D4, - 0xB6D9, 0xB6F0, 0xB6DA, 0xB6F4, 0xB6DB, 0xB6F8, 0xB6DC, 0xB700, 0xB6DD, 0xB701, 0xB6DE, 0xB705, 0xB6DF, 0xB728, 0xB6E0, 0xB729, - 0xB6E1, 0xB72C, 0xB6E2, 0xB72F, 0xB6E3, 0xB730, 0xB6E4, 0xB738, 0xB6E5, 0xB739, 0xB6E6, 0xB73B, 0xB6E7, 0xB744, 0xB6E8, 0xB748, - 0xB6E9, 0xB74C, 0xB6EA, 0xB754, 0xB6EB, 0xB755, 0xB6EC, 0xB760, 0xB6ED, 0xB764, 0xB6EE, 0xB768, 0xB6EF, 0xB770, 0xB6F0, 0xB771, - 0xB6F1, 0xB773, 0xB6F2, 0xB775, 0xB6F3, 0xB77C, 0xB6F4, 0xB77D, 0xB6F5, 0xB780, 0xB6F6, 0xB784, 0xB6F7, 0xB78C, 0xB6F8, 0xB78D, - 0xB6F9, 0xB78F, 0xB6FA, 0xB790, 0xB6FB, 0xB791, 0xB6FC, 0xB792, 0xB6FD, 0xB796, 0xB6FE, 0xB797, 0xB741, 0xD16E, 0xB742, 0xD16F, - 0xB743, 0xD170, 0xB744, 0xD171, 0xB745, 0xD172, 0xB746, 0xD173, 0xB747, 0xD174, 0xB748, 0xD175, 0xB749, 0xD176, 0xB74A, 0xD177, - 0xB74B, 0xD178, 0xB74C, 0xD179, 0xB74D, 0xD17A, 0xB74E, 0xD17B, 0xB74F, 0xD17D, 0xB750, 0xD17E, 0xB751, 0xD17F, 0xB752, 0xD180, - 0xB753, 0xD181, 0xB754, 0xD182, 0xB755, 0xD183, 0xB756, 0xD185, 0xB757, 0xD186, 0xB758, 0xD187, 0xB759, 0xD189, 0xB75A, 0xD18A, - 0xB761, 0xD18B, 0xB762, 0xD18C, 0xB763, 0xD18D, 0xB764, 0xD18E, 0xB765, 0xD18F, 0xB766, 0xD190, 0xB767, 0xD191, 0xB768, 0xD192, - 0xB769, 0xD193, 0xB76A, 0xD194, 0xB76B, 0xD195, 0xB76C, 0xD196, 0xB76D, 0xD197, 0xB76E, 0xD198, 0xB76F, 0xD199, 0xB770, 0xD19A, - 0xB771, 0xD19B, 0xB772, 0xD19C, 0xB773, 0xD19D, 0xB774, 0xD19E, 0xB775, 0xD19F, 0xB776, 0xD1A2, 0xB777, 0xD1A3, 0xB778, 0xD1A5, - 0xB779, 0xD1A6, 0xB77A, 0xD1A7, 0xB781, 0xD1A9, 0xB782, 0xD1AA, 0xB783, 0xD1AB, 0xB784, 0xD1AC, 0xB785, 0xD1AD, 0xB786, 0xD1AE, - 0xB787, 0xD1AF, 0xB788, 0xD1B2, 0xB789, 0xD1B4, 0xB78A, 0xD1B6, 0xB78B, 0xD1B7, 0xB78C, 0xD1B8, 0xB78D, 0xD1B9, 0xB78E, 0xD1BB, - 0xB78F, 0xD1BD, 0xB790, 0xD1BE, 0xB791, 0xD1BF, 0xB792, 0xD1C1, 0xB793, 0xD1C2, 0xB794, 0xD1C3, 0xB795, 0xD1C4, 0xB796, 0xD1C5, - 0xB797, 0xD1C6, 0xB798, 0xD1C7, 0xB799, 0xD1C8, 0xB79A, 0xD1C9, 0xB79B, 0xD1CA, 0xB79C, 0xD1CB, 0xB79D, 0xD1CC, 0xB79E, 0xD1CD, - 0xB79F, 0xD1CE, 0xB7A0, 0xD1CF, 0xB7A1, 0xB798, 0xB7A2, 0xB799, 0xB7A3, 0xB79C, 0xB7A4, 0xB7A0, 0xB7A5, 0xB7A8, 0xB7A6, 0xB7A9, - 0xB7A7, 0xB7AB, 0xB7A8, 0xB7AC, 0xB7A9, 0xB7AD, 0xB7AA, 0xB7B4, 0xB7AB, 0xB7B5, 0xB7AC, 0xB7B8, 0xB7AD, 0xB7C7, 0xB7AE, 0xB7C9, - 0xB7AF, 0xB7EC, 0xB7B0, 0xB7ED, 0xB7B1, 0xB7F0, 0xB7B2, 0xB7F4, 0xB7B3, 0xB7FC, 0xB7B4, 0xB7FD, 0xB7B5, 0xB7FF, 0xB7B6, 0xB800, - 0xB7B7, 0xB801, 0xB7B8, 0xB807, 0xB7B9, 0xB808, 0xB7BA, 0xB809, 0xB7BB, 0xB80C, 0xB7BC, 0xB810, 0xB7BD, 0xB818, 0xB7BE, 0xB819, - 0xB7BF, 0xB81B, 0xB7C0, 0xB81D, 0xB7C1, 0xB824, 0xB7C2, 0xB825, 0xB7C3, 0xB828, 0xB7C4, 0xB82C, 0xB7C5, 0xB834, 0xB7C6, 0xB835, - 0xB7C7, 0xB837, 0xB7C8, 0xB838, 0xB7C9, 0xB839, 0xB7CA, 0xB840, 0xB7CB, 0xB844, 0xB7CC, 0xB851, 0xB7CD, 0xB853, 0xB7CE, 0xB85C, - 0xB7CF, 0xB85D, 0xB7D0, 0xB860, 0xB7D1, 0xB864, 0xB7D2, 0xB86C, 0xB7D3, 0xB86D, 0xB7D4, 0xB86F, 0xB7D5, 0xB871, 0xB7D6, 0xB878, - 0xB7D7, 0xB87C, 0xB7D8, 0xB88D, 0xB7D9, 0xB8A8, 0xB7DA, 0xB8B0, 0xB7DB, 0xB8B4, 0xB7DC, 0xB8B8, 0xB7DD, 0xB8C0, 0xB7DE, 0xB8C1, - 0xB7DF, 0xB8C3, 0xB7E0, 0xB8C5, 0xB7E1, 0xB8CC, 0xB7E2, 0xB8D0, 0xB7E3, 0xB8D4, 0xB7E4, 0xB8DD, 0xB7E5, 0xB8DF, 0xB7E6, 0xB8E1, - 0xB7E7, 0xB8E8, 0xB7E8, 0xB8E9, 0xB7E9, 0xB8EC, 0xB7EA, 0xB8F0, 0xB7EB, 0xB8F8, 0xB7EC, 0xB8F9, 0xB7ED, 0xB8FB, 0xB7EE, 0xB8FD, - 0xB7EF, 0xB904, 0xB7F0, 0xB918, 0xB7F1, 0xB920, 0xB7F2, 0xB93C, 0xB7F3, 0xB93D, 0xB7F4, 0xB940, 0xB7F5, 0xB944, 0xB7F6, 0xB94C, - 0xB7F7, 0xB94F, 0xB7F8, 0xB951, 0xB7F9, 0xB958, 0xB7FA, 0xB959, 0xB7FB, 0xB95C, 0xB7FC, 0xB960, 0xB7FD, 0xB968, 0xB7FE, 0xB969, - 0xB841, 0xD1D0, 0xB842, 0xD1D1, 0xB843, 0xD1D2, 0xB844, 0xD1D3, 0xB845, 0xD1D4, 0xB846, 0xD1D5, 0xB847, 0xD1D6, 0xB848, 0xD1D7, - 0xB849, 0xD1D9, 0xB84A, 0xD1DA, 0xB84B, 0xD1DB, 0xB84C, 0xD1DC, 0xB84D, 0xD1DD, 0xB84E, 0xD1DE, 0xB84F, 0xD1DF, 0xB850, 0xD1E0, - 0xB851, 0xD1E1, 0xB852, 0xD1E2, 0xB853, 0xD1E3, 0xB854, 0xD1E4, 0xB855, 0xD1E5, 0xB856, 0xD1E6, 0xB857, 0xD1E7, 0xB858, 0xD1E8, - 0xB859, 0xD1E9, 0xB85A, 0xD1EA, 0xB861, 0xD1EB, 0xB862, 0xD1EC, 0xB863, 0xD1ED, 0xB864, 0xD1EE, 0xB865, 0xD1EF, 0xB866, 0xD1F0, - 0xB867, 0xD1F1, 0xB868, 0xD1F2, 0xB869, 0xD1F3, 0xB86A, 0xD1F5, 0xB86B, 0xD1F6, 0xB86C, 0xD1F7, 0xB86D, 0xD1F9, 0xB86E, 0xD1FA, - 0xB86F, 0xD1FB, 0xB870, 0xD1FC, 0xB871, 0xD1FD, 0xB872, 0xD1FE, 0xB873, 0xD1FF, 0xB874, 0xD200, 0xB875, 0xD201, 0xB876, 0xD202, - 0xB877, 0xD203, 0xB878, 0xD204, 0xB879, 0xD205, 0xB87A, 0xD206, 0xB881, 0xD208, 0xB882, 0xD20A, 0xB883, 0xD20B, 0xB884, 0xD20C, - 0xB885, 0xD20D, 0xB886, 0xD20E, 0xB887, 0xD20F, 0xB888, 0xD211, 0xB889, 0xD212, 0xB88A, 0xD213, 0xB88B, 0xD214, 0xB88C, 0xD215, - 0xB88D, 0xD216, 0xB88E, 0xD217, 0xB88F, 0xD218, 0xB890, 0xD219, 0xB891, 0xD21A, 0xB892, 0xD21B, 0xB893, 0xD21C, 0xB894, 0xD21D, - 0xB895, 0xD21E, 0xB896, 0xD21F, 0xB897, 0xD220, 0xB898, 0xD221, 0xB899, 0xD222, 0xB89A, 0xD223, 0xB89B, 0xD224, 0xB89C, 0xD225, - 0xB89D, 0xD226, 0xB89E, 0xD227, 0xB89F, 0xD228, 0xB8A0, 0xD229, 0xB8A1, 0xB96B, 0xB8A2, 0xB96D, 0xB8A3, 0xB974, 0xB8A4, 0xB975, - 0xB8A5, 0xB978, 0xB8A6, 0xB97C, 0xB8A7, 0xB984, 0xB8A8, 0xB985, 0xB8A9, 0xB987, 0xB8AA, 0xB989, 0xB8AB, 0xB98A, 0xB8AC, 0xB98D, - 0xB8AD, 0xB98E, 0xB8AE, 0xB9AC, 0xB8AF, 0xB9AD, 0xB8B0, 0xB9B0, 0xB8B1, 0xB9B4, 0xB8B2, 0xB9BC, 0xB8B3, 0xB9BD, 0xB8B4, 0xB9BF, - 0xB8B5, 0xB9C1, 0xB8B6, 0xB9C8, 0xB8B7, 0xB9C9, 0xB8B8, 0xB9CC, 0xB8B9, 0xB9CE, 0xB8BA, 0xB9CF, 0xB8BB, 0xB9D0, 0xB8BC, 0xB9D1, - 0xB8BD, 0xB9D2, 0xB8BE, 0xB9D8, 0xB8BF, 0xB9D9, 0xB8C0, 0xB9DB, 0xB8C1, 0xB9DD, 0xB8C2, 0xB9DE, 0xB8C3, 0xB9E1, 0xB8C4, 0xB9E3, - 0xB8C5, 0xB9E4, 0xB8C6, 0xB9E5, 0xB8C7, 0xB9E8, 0xB8C8, 0xB9EC, 0xB8C9, 0xB9F4, 0xB8CA, 0xB9F5, 0xB8CB, 0xB9F7, 0xB8CC, 0xB9F8, - 0xB8CD, 0xB9F9, 0xB8CE, 0xB9FA, 0xB8CF, 0xBA00, 0xB8D0, 0xBA01, 0xB8D1, 0xBA08, 0xB8D2, 0xBA15, 0xB8D3, 0xBA38, 0xB8D4, 0xBA39, - 0xB8D5, 0xBA3C, 0xB8D6, 0xBA40, 0xB8D7, 0xBA42, 0xB8D8, 0xBA48, 0xB8D9, 0xBA49, 0xB8DA, 0xBA4B, 0xB8DB, 0xBA4D, 0xB8DC, 0xBA4E, - 0xB8DD, 0xBA53, 0xB8DE, 0xBA54, 0xB8DF, 0xBA55, 0xB8E0, 0xBA58, 0xB8E1, 0xBA5C, 0xB8E2, 0xBA64, 0xB8E3, 0xBA65, 0xB8E4, 0xBA67, - 0xB8E5, 0xBA68, 0xB8E6, 0xBA69, 0xB8E7, 0xBA70, 0xB8E8, 0xBA71, 0xB8E9, 0xBA74, 0xB8EA, 0xBA78, 0xB8EB, 0xBA83, 0xB8EC, 0xBA84, - 0xB8ED, 0xBA85, 0xB8EE, 0xBA87, 0xB8EF, 0xBA8C, 0xB8F0, 0xBAA8, 0xB8F1, 0xBAA9, 0xB8F2, 0xBAAB, 0xB8F3, 0xBAAC, 0xB8F4, 0xBAB0, - 0xB8F5, 0xBAB2, 0xB8F6, 0xBAB8, 0xB8F7, 0xBAB9, 0xB8F8, 0xBABB, 0xB8F9, 0xBABD, 0xB8FA, 0xBAC4, 0xB8FB, 0xBAC8, 0xB8FC, 0xBAD8, - 0xB8FD, 0xBAD9, 0xB8FE, 0xBAFC, 0xB941, 0xD22A, 0xB942, 0xD22B, 0xB943, 0xD22E, 0xB944, 0xD22F, 0xB945, 0xD231, 0xB946, 0xD232, - 0xB947, 0xD233, 0xB948, 0xD235, 0xB949, 0xD236, 0xB94A, 0xD237, 0xB94B, 0xD238, 0xB94C, 0xD239, 0xB94D, 0xD23A, 0xB94E, 0xD23B, - 0xB94F, 0xD23E, 0xB950, 0xD240, 0xB951, 0xD242, 0xB952, 0xD243, 0xB953, 0xD244, 0xB954, 0xD245, 0xB955, 0xD246, 0xB956, 0xD247, - 0xB957, 0xD249, 0xB958, 0xD24A, 0xB959, 0xD24B, 0xB95A, 0xD24C, 0xB961, 0xD24D, 0xB962, 0xD24E, 0xB963, 0xD24F, 0xB964, 0xD250, - 0xB965, 0xD251, 0xB966, 0xD252, 0xB967, 0xD253, 0xB968, 0xD254, 0xB969, 0xD255, 0xB96A, 0xD256, 0xB96B, 0xD257, 0xB96C, 0xD258, - 0xB96D, 0xD259, 0xB96E, 0xD25A, 0xB96F, 0xD25B, 0xB970, 0xD25D, 0xB971, 0xD25E, 0xB972, 0xD25F, 0xB973, 0xD260, 0xB974, 0xD261, - 0xB975, 0xD262, 0xB976, 0xD263, 0xB977, 0xD265, 0xB978, 0xD266, 0xB979, 0xD267, 0xB97A, 0xD268, 0xB981, 0xD269, 0xB982, 0xD26A, - 0xB983, 0xD26B, 0xB984, 0xD26C, 0xB985, 0xD26D, 0xB986, 0xD26E, 0xB987, 0xD26F, 0xB988, 0xD270, 0xB989, 0xD271, 0xB98A, 0xD272, - 0xB98B, 0xD273, 0xB98C, 0xD274, 0xB98D, 0xD275, 0xB98E, 0xD276, 0xB98F, 0xD277, 0xB990, 0xD278, 0xB991, 0xD279, 0xB992, 0xD27A, - 0xB993, 0xD27B, 0xB994, 0xD27C, 0xB995, 0xD27D, 0xB996, 0xD27E, 0xB997, 0xD27F, 0xB998, 0xD282, 0xB999, 0xD283, 0xB99A, 0xD285, - 0xB99B, 0xD286, 0xB99C, 0xD287, 0xB99D, 0xD289, 0xB99E, 0xD28A, 0xB99F, 0xD28B, 0xB9A0, 0xD28C, 0xB9A1, 0xBB00, 0xB9A2, 0xBB04, - 0xB9A3, 0xBB0D, 0xB9A4, 0xBB0F, 0xB9A5, 0xBB11, 0xB9A6, 0xBB18, 0xB9A7, 0xBB1C, 0xB9A8, 0xBB20, 0xB9A9, 0xBB29, 0xB9AA, 0xBB2B, - 0xB9AB, 0xBB34, 0xB9AC, 0xBB35, 0xB9AD, 0xBB36, 0xB9AE, 0xBB38, 0xB9AF, 0xBB3B, 0xB9B0, 0xBB3C, 0xB9B1, 0xBB3D, 0xB9B2, 0xBB3E, - 0xB9B3, 0xBB44, 0xB9B4, 0xBB45, 0xB9B5, 0xBB47, 0xB9B6, 0xBB49, 0xB9B7, 0xBB4D, 0xB9B8, 0xBB4F, 0xB9B9, 0xBB50, 0xB9BA, 0xBB54, - 0xB9BB, 0xBB58, 0xB9BC, 0xBB61, 0xB9BD, 0xBB63, 0xB9BE, 0xBB6C, 0xB9BF, 0xBB88, 0xB9C0, 0xBB8C, 0xB9C1, 0xBB90, 0xB9C2, 0xBBA4, - 0xB9C3, 0xBBA8, 0xB9C4, 0xBBAC, 0xB9C5, 0xBBB4, 0xB9C6, 0xBBB7, 0xB9C7, 0xBBC0, 0xB9C8, 0xBBC4, 0xB9C9, 0xBBC8, 0xB9CA, 0xBBD0, - 0xB9CB, 0xBBD3, 0xB9CC, 0xBBF8, 0xB9CD, 0xBBF9, 0xB9CE, 0xBBFC, 0xB9CF, 0xBBFF, 0xB9D0, 0xBC00, 0xB9D1, 0xBC02, 0xB9D2, 0xBC08, - 0xB9D3, 0xBC09, 0xB9D4, 0xBC0B, 0xB9D5, 0xBC0C, 0xB9D6, 0xBC0D, 0xB9D7, 0xBC0F, 0xB9D8, 0xBC11, 0xB9D9, 0xBC14, 0xB9DA, 0xBC15, - 0xB9DB, 0xBC16, 0xB9DC, 0xBC17, 0xB9DD, 0xBC18, 0xB9DE, 0xBC1B, 0xB9DF, 0xBC1C, 0xB9E0, 0xBC1D, 0xB9E1, 0xBC1E, 0xB9E2, 0xBC1F, - 0xB9E3, 0xBC24, 0xB9E4, 0xBC25, 0xB9E5, 0xBC27, 0xB9E6, 0xBC29, 0xB9E7, 0xBC2D, 0xB9E8, 0xBC30, 0xB9E9, 0xBC31, 0xB9EA, 0xBC34, - 0xB9EB, 0xBC38, 0xB9EC, 0xBC40, 0xB9ED, 0xBC41, 0xB9EE, 0xBC43, 0xB9EF, 0xBC44, 0xB9F0, 0xBC45, 0xB9F1, 0xBC49, 0xB9F2, 0xBC4C, - 0xB9F3, 0xBC4D, 0xB9F4, 0xBC50, 0xB9F5, 0xBC5D, 0xB9F6, 0xBC84, 0xB9F7, 0xBC85, 0xB9F8, 0xBC88, 0xB9F9, 0xBC8B, 0xB9FA, 0xBC8C, - 0xB9FB, 0xBC8E, 0xB9FC, 0xBC94, 0xB9FD, 0xBC95, 0xB9FE, 0xBC97, 0xBA41, 0xD28D, 0xBA42, 0xD28E, 0xBA43, 0xD28F, 0xBA44, 0xD292, - 0xBA45, 0xD293, 0xBA46, 0xD294, 0xBA47, 0xD296, 0xBA48, 0xD297, 0xBA49, 0xD298, 0xBA4A, 0xD299, 0xBA4B, 0xD29A, 0xBA4C, 0xD29B, - 0xBA4D, 0xD29D, 0xBA4E, 0xD29E, 0xBA4F, 0xD29F, 0xBA50, 0xD2A1, 0xBA51, 0xD2A2, 0xBA52, 0xD2A3, 0xBA53, 0xD2A5, 0xBA54, 0xD2A6, - 0xBA55, 0xD2A7, 0xBA56, 0xD2A8, 0xBA57, 0xD2A9, 0xBA58, 0xD2AA, 0xBA59, 0xD2AB, 0xBA5A, 0xD2AD, 0xBA61, 0xD2AE, 0xBA62, 0xD2AF, - 0xBA63, 0xD2B0, 0xBA64, 0xD2B2, 0xBA65, 0xD2B3, 0xBA66, 0xD2B4, 0xBA67, 0xD2B5, 0xBA68, 0xD2B6, 0xBA69, 0xD2B7, 0xBA6A, 0xD2BA, - 0xBA6B, 0xD2BB, 0xBA6C, 0xD2BD, 0xBA6D, 0xD2BE, 0xBA6E, 0xD2C1, 0xBA6F, 0xD2C3, 0xBA70, 0xD2C4, 0xBA71, 0xD2C5, 0xBA72, 0xD2C6, - 0xBA73, 0xD2C7, 0xBA74, 0xD2CA, 0xBA75, 0xD2CC, 0xBA76, 0xD2CD, 0xBA77, 0xD2CE, 0xBA78, 0xD2CF, 0xBA79, 0xD2D0, 0xBA7A, 0xD2D1, - 0xBA81, 0xD2D2, 0xBA82, 0xD2D3, 0xBA83, 0xD2D5, 0xBA84, 0xD2D6, 0xBA85, 0xD2D7, 0xBA86, 0xD2D9, 0xBA87, 0xD2DA, 0xBA88, 0xD2DB, - 0xBA89, 0xD2DD, 0xBA8A, 0xD2DE, 0xBA8B, 0xD2DF, 0xBA8C, 0xD2E0, 0xBA8D, 0xD2E1, 0xBA8E, 0xD2E2, 0xBA8F, 0xD2E3, 0xBA90, 0xD2E6, - 0xBA91, 0xD2E7, 0xBA92, 0xD2E8, 0xBA93, 0xD2E9, 0xBA94, 0xD2EA, 0xBA95, 0xD2EB, 0xBA96, 0xD2EC, 0xBA97, 0xD2ED, 0xBA98, 0xD2EE, - 0xBA99, 0xD2EF, 0xBA9A, 0xD2F2, 0xBA9B, 0xD2F3, 0xBA9C, 0xD2F5, 0xBA9D, 0xD2F6, 0xBA9E, 0xD2F7, 0xBA9F, 0xD2F9, 0xBAA0, 0xD2FA, - 0xBAA1, 0xBC99, 0xBAA2, 0xBC9A, 0xBAA3, 0xBCA0, 0xBAA4, 0xBCA1, 0xBAA5, 0xBCA4, 0xBAA6, 0xBCA7, 0xBAA7, 0xBCA8, 0xBAA8, 0xBCB0, - 0xBAA9, 0xBCB1, 0xBAAA, 0xBCB3, 0xBAAB, 0xBCB4, 0xBAAC, 0xBCB5, 0xBAAD, 0xBCBC, 0xBAAE, 0xBCBD, 0xBAAF, 0xBCC0, 0xBAB0, 0xBCC4, - 0xBAB1, 0xBCCD, 0xBAB2, 0xBCCF, 0xBAB3, 0xBCD0, 0xBAB4, 0xBCD1, 0xBAB5, 0xBCD5, 0xBAB6, 0xBCD8, 0xBAB7, 0xBCDC, 0xBAB8, 0xBCF4, - 0xBAB9, 0xBCF5, 0xBABA, 0xBCF6, 0xBABB, 0xBCF8, 0xBABC, 0xBCFC, 0xBABD, 0xBD04, 0xBABE, 0xBD05, 0xBABF, 0xBD07, 0xBAC0, 0xBD09, - 0xBAC1, 0xBD10, 0xBAC2, 0xBD14, 0xBAC3, 0xBD24, 0xBAC4, 0xBD2C, 0xBAC5, 0xBD40, 0xBAC6, 0xBD48, 0xBAC7, 0xBD49, 0xBAC8, 0xBD4C, - 0xBAC9, 0xBD50, 0xBACA, 0xBD58, 0xBACB, 0xBD59, 0xBACC, 0xBD64, 0xBACD, 0xBD68, 0xBACE, 0xBD80, 0xBACF, 0xBD81, 0xBAD0, 0xBD84, - 0xBAD1, 0xBD87, 0xBAD2, 0xBD88, 0xBAD3, 0xBD89, 0xBAD4, 0xBD8A, 0xBAD5, 0xBD90, 0xBAD6, 0xBD91, 0xBAD7, 0xBD93, 0xBAD8, 0xBD95, - 0xBAD9, 0xBD99, 0xBADA, 0xBD9A, 0xBADB, 0xBD9C, 0xBADC, 0xBDA4, 0xBADD, 0xBDB0, 0xBADE, 0xBDB8, 0xBADF, 0xBDD4, 0xBAE0, 0xBDD5, - 0xBAE1, 0xBDD8, 0xBAE2, 0xBDDC, 0xBAE3, 0xBDE9, 0xBAE4, 0xBDF0, 0xBAE5, 0xBDF4, 0xBAE6, 0xBDF8, 0xBAE7, 0xBE00, 0xBAE8, 0xBE03, - 0xBAE9, 0xBE05, 0xBAEA, 0xBE0C, 0xBAEB, 0xBE0D, 0xBAEC, 0xBE10, 0xBAED, 0xBE14, 0xBAEE, 0xBE1C, 0xBAEF, 0xBE1D, 0xBAF0, 0xBE1F, - 0xBAF1, 0xBE44, 0xBAF2, 0xBE45, 0xBAF3, 0xBE48, 0xBAF4, 0xBE4C, 0xBAF5, 0xBE4E, 0xBAF6, 0xBE54, 0xBAF7, 0xBE55, 0xBAF8, 0xBE57, - 0xBAF9, 0xBE59, 0xBAFA, 0xBE5A, 0xBAFB, 0xBE5B, 0xBAFC, 0xBE60, 0xBAFD, 0xBE61, 0xBAFE, 0xBE64, 0xBB41, 0xD2FB, 0xBB42, 0xD2FC, - 0xBB43, 0xD2FD, 0xBB44, 0xD2FE, 0xBB45, 0xD2FF, 0xBB46, 0xD302, 0xBB47, 0xD304, 0xBB48, 0xD306, 0xBB49, 0xD307, 0xBB4A, 0xD308, - 0xBB4B, 0xD309, 0xBB4C, 0xD30A, 0xBB4D, 0xD30B, 0xBB4E, 0xD30F, 0xBB4F, 0xD311, 0xBB50, 0xD312, 0xBB51, 0xD313, 0xBB52, 0xD315, - 0xBB53, 0xD317, 0xBB54, 0xD318, 0xBB55, 0xD319, 0xBB56, 0xD31A, 0xBB57, 0xD31B, 0xBB58, 0xD31E, 0xBB59, 0xD322, 0xBB5A, 0xD323, - 0xBB61, 0xD324, 0xBB62, 0xD326, 0xBB63, 0xD327, 0xBB64, 0xD32A, 0xBB65, 0xD32B, 0xBB66, 0xD32D, 0xBB67, 0xD32E, 0xBB68, 0xD32F, - 0xBB69, 0xD331, 0xBB6A, 0xD332, 0xBB6B, 0xD333, 0xBB6C, 0xD334, 0xBB6D, 0xD335, 0xBB6E, 0xD336, 0xBB6F, 0xD337, 0xBB70, 0xD33A, - 0xBB71, 0xD33E, 0xBB72, 0xD33F, 0xBB73, 0xD340, 0xBB74, 0xD341, 0xBB75, 0xD342, 0xBB76, 0xD343, 0xBB77, 0xD346, 0xBB78, 0xD347, - 0xBB79, 0xD348, 0xBB7A, 0xD349, 0xBB81, 0xD34A, 0xBB82, 0xD34B, 0xBB83, 0xD34C, 0xBB84, 0xD34D, 0xBB85, 0xD34E, 0xBB86, 0xD34F, - 0xBB87, 0xD350, 0xBB88, 0xD351, 0xBB89, 0xD352, 0xBB8A, 0xD353, 0xBB8B, 0xD354, 0xBB8C, 0xD355, 0xBB8D, 0xD356, 0xBB8E, 0xD357, - 0xBB8F, 0xD358, 0xBB90, 0xD359, 0xBB91, 0xD35A, 0xBB92, 0xD35B, 0xBB93, 0xD35C, 0xBB94, 0xD35D, 0xBB95, 0xD35E, 0xBB96, 0xD35F, - 0xBB97, 0xD360, 0xBB98, 0xD361, 0xBB99, 0xD362, 0xBB9A, 0xD363, 0xBB9B, 0xD364, 0xBB9C, 0xD365, 0xBB9D, 0xD366, 0xBB9E, 0xD367, - 0xBB9F, 0xD368, 0xBBA0, 0xD369, 0xBBA1, 0xBE68, 0xBBA2, 0xBE6A, 0xBBA3, 0xBE70, 0xBBA4, 0xBE71, 0xBBA5, 0xBE73, 0xBBA6, 0xBE74, - 0xBBA7, 0xBE75, 0xBBA8, 0xBE7B, 0xBBA9, 0xBE7C, 0xBBAA, 0xBE7D, 0xBBAB, 0xBE80, 0xBBAC, 0xBE84, 0xBBAD, 0xBE8C, 0xBBAE, 0xBE8D, - 0xBBAF, 0xBE8F, 0xBBB0, 0xBE90, 0xBBB1, 0xBE91, 0xBBB2, 0xBE98, 0xBBB3, 0xBE99, 0xBBB4, 0xBEA8, 0xBBB5, 0xBED0, 0xBBB6, 0xBED1, - 0xBBB7, 0xBED4, 0xBBB8, 0xBED7, 0xBBB9, 0xBED8, 0xBBBA, 0xBEE0, 0xBBBB, 0xBEE3, 0xBBBC, 0xBEE4, 0xBBBD, 0xBEE5, 0xBBBE, 0xBEEC, - 0xBBBF, 0xBF01, 0xBBC0, 0xBF08, 0xBBC1, 0xBF09, 0xBBC2, 0xBF18, 0xBBC3, 0xBF19, 0xBBC4, 0xBF1B, 0xBBC5, 0xBF1C, 0xBBC6, 0xBF1D, - 0xBBC7, 0xBF40, 0xBBC8, 0xBF41, 0xBBC9, 0xBF44, 0xBBCA, 0xBF48, 0xBBCB, 0xBF50, 0xBBCC, 0xBF51, 0xBBCD, 0xBF55, 0xBBCE, 0xBF94, - 0xBBCF, 0xBFB0, 0xBBD0, 0xBFC5, 0xBBD1, 0xBFCC, 0xBBD2, 0xBFCD, 0xBBD3, 0xBFD0, 0xBBD4, 0xBFD4, 0xBBD5, 0xBFDC, 0xBBD6, 0xBFDF, - 0xBBD7, 0xBFE1, 0xBBD8, 0xC03C, 0xBBD9, 0xC051, 0xBBDA, 0xC058, 0xBBDB, 0xC05C, 0xBBDC, 0xC060, 0xBBDD, 0xC068, 0xBBDE, 0xC069, - 0xBBDF, 0xC090, 0xBBE0, 0xC091, 0xBBE1, 0xC094, 0xBBE2, 0xC098, 0xBBE3, 0xC0A0, 0xBBE4, 0xC0A1, 0xBBE5, 0xC0A3, 0xBBE6, 0xC0A5, - 0xBBE7, 0xC0AC, 0xBBE8, 0xC0AD, 0xBBE9, 0xC0AF, 0xBBEA, 0xC0B0, 0xBBEB, 0xC0B3, 0xBBEC, 0xC0B4, 0xBBED, 0xC0B5, 0xBBEE, 0xC0B6, - 0xBBEF, 0xC0BC, 0xBBF0, 0xC0BD, 0xBBF1, 0xC0BF, 0xBBF2, 0xC0C0, 0xBBF3, 0xC0C1, 0xBBF4, 0xC0C5, 0xBBF5, 0xC0C8, 0xBBF6, 0xC0C9, - 0xBBF7, 0xC0CC, 0xBBF8, 0xC0D0, 0xBBF9, 0xC0D8, 0xBBFA, 0xC0D9, 0xBBFB, 0xC0DB, 0xBBFC, 0xC0DC, 0xBBFD, 0xC0DD, 0xBBFE, 0xC0E4, - 0xBC41, 0xD36A, 0xBC42, 0xD36B, 0xBC43, 0xD36C, 0xBC44, 0xD36D, 0xBC45, 0xD36E, 0xBC46, 0xD36F, 0xBC47, 0xD370, 0xBC48, 0xD371, - 0xBC49, 0xD372, 0xBC4A, 0xD373, 0xBC4B, 0xD374, 0xBC4C, 0xD375, 0xBC4D, 0xD376, 0xBC4E, 0xD377, 0xBC4F, 0xD378, 0xBC50, 0xD379, - 0xBC51, 0xD37A, 0xBC52, 0xD37B, 0xBC53, 0xD37E, 0xBC54, 0xD37F, 0xBC55, 0xD381, 0xBC56, 0xD382, 0xBC57, 0xD383, 0xBC58, 0xD385, - 0xBC59, 0xD386, 0xBC5A, 0xD387, 0xBC61, 0xD388, 0xBC62, 0xD389, 0xBC63, 0xD38A, 0xBC64, 0xD38B, 0xBC65, 0xD38E, 0xBC66, 0xD392, - 0xBC67, 0xD393, 0xBC68, 0xD394, 0xBC69, 0xD395, 0xBC6A, 0xD396, 0xBC6B, 0xD397, 0xBC6C, 0xD39A, 0xBC6D, 0xD39B, 0xBC6E, 0xD39D, - 0xBC6F, 0xD39E, 0xBC70, 0xD39F, 0xBC71, 0xD3A1, 0xBC72, 0xD3A2, 0xBC73, 0xD3A3, 0xBC74, 0xD3A4, 0xBC75, 0xD3A5, 0xBC76, 0xD3A6, - 0xBC77, 0xD3A7, 0xBC78, 0xD3AA, 0xBC79, 0xD3AC, 0xBC7A, 0xD3AE, 0xBC81, 0xD3AF, 0xBC82, 0xD3B0, 0xBC83, 0xD3B1, 0xBC84, 0xD3B2, - 0xBC85, 0xD3B3, 0xBC86, 0xD3B5, 0xBC87, 0xD3B6, 0xBC88, 0xD3B7, 0xBC89, 0xD3B9, 0xBC8A, 0xD3BA, 0xBC8B, 0xD3BB, 0xBC8C, 0xD3BD, - 0xBC8D, 0xD3BE, 0xBC8E, 0xD3BF, 0xBC8F, 0xD3C0, 0xBC90, 0xD3C1, 0xBC91, 0xD3C2, 0xBC92, 0xD3C3, 0xBC93, 0xD3C6, 0xBC94, 0xD3C7, - 0xBC95, 0xD3CA, 0xBC96, 0xD3CB, 0xBC97, 0xD3CC, 0xBC98, 0xD3CD, 0xBC99, 0xD3CE, 0xBC9A, 0xD3CF, 0xBC9B, 0xD3D1, 0xBC9C, 0xD3D2, - 0xBC9D, 0xD3D3, 0xBC9E, 0xD3D4, 0xBC9F, 0xD3D5, 0xBCA0, 0xD3D6, 0xBCA1, 0xC0E5, 0xBCA2, 0xC0E8, 0xBCA3, 0xC0EC, 0xBCA4, 0xC0F4, - 0xBCA5, 0xC0F5, 0xBCA6, 0xC0F7, 0xBCA7, 0xC0F9, 0xBCA8, 0xC100, 0xBCA9, 0xC104, 0xBCAA, 0xC108, 0xBCAB, 0xC110, 0xBCAC, 0xC115, - 0xBCAD, 0xC11C, 0xBCAE, 0xC11D, 0xBCAF, 0xC11E, 0xBCB0, 0xC11F, 0xBCB1, 0xC120, 0xBCB2, 0xC123, 0xBCB3, 0xC124, 0xBCB4, 0xC126, - 0xBCB5, 0xC127, 0xBCB6, 0xC12C, 0xBCB7, 0xC12D, 0xBCB8, 0xC12F, 0xBCB9, 0xC130, 0xBCBA, 0xC131, 0xBCBB, 0xC136, 0xBCBC, 0xC138, - 0xBCBD, 0xC139, 0xBCBE, 0xC13C, 0xBCBF, 0xC140, 0xBCC0, 0xC148, 0xBCC1, 0xC149, 0xBCC2, 0xC14B, 0xBCC3, 0xC14C, 0xBCC4, 0xC14D, - 0xBCC5, 0xC154, 0xBCC6, 0xC155, 0xBCC7, 0xC158, 0xBCC8, 0xC15C, 0xBCC9, 0xC164, 0xBCCA, 0xC165, 0xBCCB, 0xC167, 0xBCCC, 0xC168, - 0xBCCD, 0xC169, 0xBCCE, 0xC170, 0xBCCF, 0xC174, 0xBCD0, 0xC178, 0xBCD1, 0xC185, 0xBCD2, 0xC18C, 0xBCD3, 0xC18D, 0xBCD4, 0xC18E, - 0xBCD5, 0xC190, 0xBCD6, 0xC194, 0xBCD7, 0xC196, 0xBCD8, 0xC19C, 0xBCD9, 0xC19D, 0xBCDA, 0xC19F, 0xBCDB, 0xC1A1, 0xBCDC, 0xC1A5, - 0xBCDD, 0xC1A8, 0xBCDE, 0xC1A9, 0xBCDF, 0xC1AC, 0xBCE0, 0xC1B0, 0xBCE1, 0xC1BD, 0xBCE2, 0xC1C4, 0xBCE3, 0xC1C8, 0xBCE4, 0xC1CC, - 0xBCE5, 0xC1D4, 0xBCE6, 0xC1D7, 0xBCE7, 0xC1D8, 0xBCE8, 0xC1E0, 0xBCE9, 0xC1E4, 0xBCEA, 0xC1E8, 0xBCEB, 0xC1F0, 0xBCEC, 0xC1F1, - 0xBCED, 0xC1F3, 0xBCEE, 0xC1FC, 0xBCEF, 0xC1FD, 0xBCF0, 0xC200, 0xBCF1, 0xC204, 0xBCF2, 0xC20C, 0xBCF3, 0xC20D, 0xBCF4, 0xC20F, - 0xBCF5, 0xC211, 0xBCF6, 0xC218, 0xBCF7, 0xC219, 0xBCF8, 0xC21C, 0xBCF9, 0xC21F, 0xBCFA, 0xC220, 0xBCFB, 0xC228, 0xBCFC, 0xC229, - 0xBCFD, 0xC22B, 0xBCFE, 0xC22D, 0xBD41, 0xD3D7, 0xBD42, 0xD3D9, 0xBD43, 0xD3DA, 0xBD44, 0xD3DB, 0xBD45, 0xD3DC, 0xBD46, 0xD3DD, - 0xBD47, 0xD3DE, 0xBD48, 0xD3DF, 0xBD49, 0xD3E0, 0xBD4A, 0xD3E2, 0xBD4B, 0xD3E4, 0xBD4C, 0xD3E5, 0xBD4D, 0xD3E6, 0xBD4E, 0xD3E7, - 0xBD4F, 0xD3E8, 0xBD50, 0xD3E9, 0xBD51, 0xD3EA, 0xBD52, 0xD3EB, 0xBD53, 0xD3EE, 0xBD54, 0xD3EF, 0xBD55, 0xD3F1, 0xBD56, 0xD3F2, - 0xBD57, 0xD3F3, 0xBD58, 0xD3F5, 0xBD59, 0xD3F6, 0xBD5A, 0xD3F7, 0xBD61, 0xD3F8, 0xBD62, 0xD3F9, 0xBD63, 0xD3FA, 0xBD64, 0xD3FB, - 0xBD65, 0xD3FE, 0xBD66, 0xD400, 0xBD67, 0xD402, 0xBD68, 0xD403, 0xBD69, 0xD404, 0xBD6A, 0xD405, 0xBD6B, 0xD406, 0xBD6C, 0xD407, - 0xBD6D, 0xD409, 0xBD6E, 0xD40A, 0xBD6F, 0xD40B, 0xBD70, 0xD40C, 0xBD71, 0xD40D, 0xBD72, 0xD40E, 0xBD73, 0xD40F, 0xBD74, 0xD410, - 0xBD75, 0xD411, 0xBD76, 0xD412, 0xBD77, 0xD413, 0xBD78, 0xD414, 0xBD79, 0xD415, 0xBD7A, 0xD416, 0xBD81, 0xD417, 0xBD82, 0xD418, - 0xBD83, 0xD419, 0xBD84, 0xD41A, 0xBD85, 0xD41B, 0xBD86, 0xD41C, 0xBD87, 0xD41E, 0xBD88, 0xD41F, 0xBD89, 0xD420, 0xBD8A, 0xD421, - 0xBD8B, 0xD422, 0xBD8C, 0xD423, 0xBD8D, 0xD424, 0xBD8E, 0xD425, 0xBD8F, 0xD426, 0xBD90, 0xD427, 0xBD91, 0xD428, 0xBD92, 0xD429, - 0xBD93, 0xD42A, 0xBD94, 0xD42B, 0xBD95, 0xD42C, 0xBD96, 0xD42D, 0xBD97, 0xD42E, 0xBD98, 0xD42F, 0xBD99, 0xD430, 0xBD9A, 0xD431, - 0xBD9B, 0xD432, 0xBD9C, 0xD433, 0xBD9D, 0xD434, 0xBD9E, 0xD435, 0xBD9F, 0xD436, 0xBDA0, 0xD437, 0xBDA1, 0xC22F, 0xBDA2, 0xC231, - 0xBDA3, 0xC232, 0xBDA4, 0xC234, 0xBDA5, 0xC248, 0xBDA6, 0xC250, 0xBDA7, 0xC251, 0xBDA8, 0xC254, 0xBDA9, 0xC258, 0xBDAA, 0xC260, - 0xBDAB, 0xC265, 0xBDAC, 0xC26C, 0xBDAD, 0xC26D, 0xBDAE, 0xC270, 0xBDAF, 0xC274, 0xBDB0, 0xC27C, 0xBDB1, 0xC27D, 0xBDB2, 0xC27F, - 0xBDB3, 0xC281, 0xBDB4, 0xC288, 0xBDB5, 0xC289, 0xBDB6, 0xC290, 0xBDB7, 0xC298, 0xBDB8, 0xC29B, 0xBDB9, 0xC29D, 0xBDBA, 0xC2A4, - 0xBDBB, 0xC2A5, 0xBDBC, 0xC2A8, 0xBDBD, 0xC2AC, 0xBDBE, 0xC2AD, 0xBDBF, 0xC2B4, 0xBDC0, 0xC2B5, 0xBDC1, 0xC2B7, 0xBDC2, 0xC2B9, - 0xBDC3, 0xC2DC, 0xBDC4, 0xC2DD, 0xBDC5, 0xC2E0, 0xBDC6, 0xC2E3, 0xBDC7, 0xC2E4, 0xBDC8, 0xC2EB, 0xBDC9, 0xC2EC, 0xBDCA, 0xC2ED, - 0xBDCB, 0xC2EF, 0xBDCC, 0xC2F1, 0xBDCD, 0xC2F6, 0xBDCE, 0xC2F8, 0xBDCF, 0xC2F9, 0xBDD0, 0xC2FB, 0xBDD1, 0xC2FC, 0xBDD2, 0xC300, - 0xBDD3, 0xC308, 0xBDD4, 0xC309, 0xBDD5, 0xC30C, 0xBDD6, 0xC30D, 0xBDD7, 0xC313, 0xBDD8, 0xC314, 0xBDD9, 0xC315, 0xBDDA, 0xC318, - 0xBDDB, 0xC31C, 0xBDDC, 0xC324, 0xBDDD, 0xC325, 0xBDDE, 0xC328, 0xBDDF, 0xC329, 0xBDE0, 0xC345, 0xBDE1, 0xC368, 0xBDE2, 0xC369, - 0xBDE3, 0xC36C, 0xBDE4, 0xC370, 0xBDE5, 0xC372, 0xBDE6, 0xC378, 0xBDE7, 0xC379, 0xBDE8, 0xC37C, 0xBDE9, 0xC37D, 0xBDEA, 0xC384, - 0xBDEB, 0xC388, 0xBDEC, 0xC38C, 0xBDED, 0xC3C0, 0xBDEE, 0xC3D8, 0xBDEF, 0xC3D9, 0xBDF0, 0xC3DC, 0xBDF1, 0xC3DF, 0xBDF2, 0xC3E0, - 0xBDF3, 0xC3E2, 0xBDF4, 0xC3E8, 0xBDF5, 0xC3E9, 0xBDF6, 0xC3ED, 0xBDF7, 0xC3F4, 0xBDF8, 0xC3F5, 0xBDF9, 0xC3F8, 0xBDFA, 0xC408, - 0xBDFB, 0xC410, 0xBDFC, 0xC424, 0xBDFD, 0xC42C, 0xBDFE, 0xC430, 0xBE41, 0xD438, 0xBE42, 0xD439, 0xBE43, 0xD43A, 0xBE44, 0xD43B, - 0xBE45, 0xD43C, 0xBE46, 0xD43D, 0xBE47, 0xD43E, 0xBE48, 0xD43F, 0xBE49, 0xD441, 0xBE4A, 0xD442, 0xBE4B, 0xD443, 0xBE4C, 0xD445, - 0xBE4D, 0xD446, 0xBE4E, 0xD447, 0xBE4F, 0xD448, 0xBE50, 0xD449, 0xBE51, 0xD44A, 0xBE52, 0xD44B, 0xBE53, 0xD44C, 0xBE54, 0xD44D, - 0xBE55, 0xD44E, 0xBE56, 0xD44F, 0xBE57, 0xD450, 0xBE58, 0xD451, 0xBE59, 0xD452, 0xBE5A, 0xD453, 0xBE61, 0xD454, 0xBE62, 0xD455, - 0xBE63, 0xD456, 0xBE64, 0xD457, 0xBE65, 0xD458, 0xBE66, 0xD459, 0xBE67, 0xD45A, 0xBE68, 0xD45B, 0xBE69, 0xD45D, 0xBE6A, 0xD45E, - 0xBE6B, 0xD45F, 0xBE6C, 0xD461, 0xBE6D, 0xD462, 0xBE6E, 0xD463, 0xBE6F, 0xD465, 0xBE70, 0xD466, 0xBE71, 0xD467, 0xBE72, 0xD468, - 0xBE73, 0xD469, 0xBE74, 0xD46A, 0xBE75, 0xD46B, 0xBE76, 0xD46C, 0xBE77, 0xD46E, 0xBE78, 0xD470, 0xBE79, 0xD471, 0xBE7A, 0xD472, - 0xBE81, 0xD473, 0xBE82, 0xD474, 0xBE83, 0xD475, 0xBE84, 0xD476, 0xBE85, 0xD477, 0xBE86, 0xD47A, 0xBE87, 0xD47B, 0xBE88, 0xD47D, - 0xBE89, 0xD47E, 0xBE8A, 0xD481, 0xBE8B, 0xD483, 0xBE8C, 0xD484, 0xBE8D, 0xD485, 0xBE8E, 0xD486, 0xBE8F, 0xD487, 0xBE90, 0xD48A, - 0xBE91, 0xD48C, 0xBE92, 0xD48E, 0xBE93, 0xD48F, 0xBE94, 0xD490, 0xBE95, 0xD491, 0xBE96, 0xD492, 0xBE97, 0xD493, 0xBE98, 0xD495, - 0xBE99, 0xD496, 0xBE9A, 0xD497, 0xBE9B, 0xD498, 0xBE9C, 0xD499, 0xBE9D, 0xD49A, 0xBE9E, 0xD49B, 0xBE9F, 0xD49C, 0xBEA0, 0xD49D, - 0xBEA1, 0xC434, 0xBEA2, 0xC43C, 0xBEA3, 0xC43D, 0xBEA4, 0xC448, 0xBEA5, 0xC464, 0xBEA6, 0xC465, 0xBEA7, 0xC468, 0xBEA8, 0xC46C, - 0xBEA9, 0xC474, 0xBEAA, 0xC475, 0xBEAB, 0xC479, 0xBEAC, 0xC480, 0xBEAD, 0xC494, 0xBEAE, 0xC49C, 0xBEAF, 0xC4B8, 0xBEB0, 0xC4BC, - 0xBEB1, 0xC4E9, 0xBEB2, 0xC4F0, 0xBEB3, 0xC4F1, 0xBEB4, 0xC4F4, 0xBEB5, 0xC4F8, 0xBEB6, 0xC4FA, 0xBEB7, 0xC4FF, 0xBEB8, 0xC500, - 0xBEB9, 0xC501, 0xBEBA, 0xC50C, 0xBEBB, 0xC510, 0xBEBC, 0xC514, 0xBEBD, 0xC51C, 0xBEBE, 0xC528, 0xBEBF, 0xC529, 0xBEC0, 0xC52C, - 0xBEC1, 0xC530, 0xBEC2, 0xC538, 0xBEC3, 0xC539, 0xBEC4, 0xC53B, 0xBEC5, 0xC53D, 0xBEC6, 0xC544, 0xBEC7, 0xC545, 0xBEC8, 0xC548, - 0xBEC9, 0xC549, 0xBECA, 0xC54A, 0xBECB, 0xC54C, 0xBECC, 0xC54D, 0xBECD, 0xC54E, 0xBECE, 0xC553, 0xBECF, 0xC554, 0xBED0, 0xC555, - 0xBED1, 0xC557, 0xBED2, 0xC558, 0xBED3, 0xC559, 0xBED4, 0xC55D, 0xBED5, 0xC55E, 0xBED6, 0xC560, 0xBED7, 0xC561, 0xBED8, 0xC564, - 0xBED9, 0xC568, 0xBEDA, 0xC570, 0xBEDB, 0xC571, 0xBEDC, 0xC573, 0xBEDD, 0xC574, 0xBEDE, 0xC575, 0xBEDF, 0xC57C, 0xBEE0, 0xC57D, - 0xBEE1, 0xC580, 0xBEE2, 0xC584, 0xBEE3, 0xC587, 0xBEE4, 0xC58C, 0xBEE5, 0xC58D, 0xBEE6, 0xC58F, 0xBEE7, 0xC591, 0xBEE8, 0xC595, - 0xBEE9, 0xC597, 0xBEEA, 0xC598, 0xBEEB, 0xC59C, 0xBEEC, 0xC5A0, 0xBEED, 0xC5A9, 0xBEEE, 0xC5B4, 0xBEEF, 0xC5B5, 0xBEF0, 0xC5B8, - 0xBEF1, 0xC5B9, 0xBEF2, 0xC5BB, 0xBEF3, 0xC5BC, 0xBEF4, 0xC5BD, 0xBEF5, 0xC5BE, 0xBEF6, 0xC5C4, 0xBEF7, 0xC5C5, 0xBEF8, 0xC5C6, - 0xBEF9, 0xC5C7, 0xBEFA, 0xC5C8, 0xBEFB, 0xC5C9, 0xBEFC, 0xC5CA, 0xBEFD, 0xC5CC, 0xBEFE, 0xC5CE, 0xBF41, 0xD49E, 0xBF42, 0xD49F, - 0xBF43, 0xD4A0, 0xBF44, 0xD4A1, 0xBF45, 0xD4A2, 0xBF46, 0xD4A3, 0xBF47, 0xD4A4, 0xBF48, 0xD4A5, 0xBF49, 0xD4A6, 0xBF4A, 0xD4A7, - 0xBF4B, 0xD4A8, 0xBF4C, 0xD4AA, 0xBF4D, 0xD4AB, 0xBF4E, 0xD4AC, 0xBF4F, 0xD4AD, 0xBF50, 0xD4AE, 0xBF51, 0xD4AF, 0xBF52, 0xD4B0, - 0xBF53, 0xD4B1, 0xBF54, 0xD4B2, 0xBF55, 0xD4B3, 0xBF56, 0xD4B4, 0xBF57, 0xD4B5, 0xBF58, 0xD4B6, 0xBF59, 0xD4B7, 0xBF5A, 0xD4B8, - 0xBF61, 0xD4B9, 0xBF62, 0xD4BA, 0xBF63, 0xD4BB, 0xBF64, 0xD4BC, 0xBF65, 0xD4BD, 0xBF66, 0xD4BE, 0xBF67, 0xD4BF, 0xBF68, 0xD4C0, - 0xBF69, 0xD4C1, 0xBF6A, 0xD4C2, 0xBF6B, 0xD4C3, 0xBF6C, 0xD4C4, 0xBF6D, 0xD4C5, 0xBF6E, 0xD4C6, 0xBF6F, 0xD4C7, 0xBF70, 0xD4C8, - 0xBF71, 0xD4C9, 0xBF72, 0xD4CA, 0xBF73, 0xD4CB, 0xBF74, 0xD4CD, 0xBF75, 0xD4CE, 0xBF76, 0xD4CF, 0xBF77, 0xD4D1, 0xBF78, 0xD4D2, - 0xBF79, 0xD4D3, 0xBF7A, 0xD4D5, 0xBF81, 0xD4D6, 0xBF82, 0xD4D7, 0xBF83, 0xD4D8, 0xBF84, 0xD4D9, 0xBF85, 0xD4DA, 0xBF86, 0xD4DB, - 0xBF87, 0xD4DD, 0xBF88, 0xD4DE, 0xBF89, 0xD4E0, 0xBF8A, 0xD4E1, 0xBF8B, 0xD4E2, 0xBF8C, 0xD4E3, 0xBF8D, 0xD4E4, 0xBF8E, 0xD4E5, - 0xBF8F, 0xD4E6, 0xBF90, 0xD4E7, 0xBF91, 0xD4E9, 0xBF92, 0xD4EA, 0xBF93, 0xD4EB, 0xBF94, 0xD4ED, 0xBF95, 0xD4EE, 0xBF96, 0xD4EF, - 0xBF97, 0xD4F1, 0xBF98, 0xD4F2, 0xBF99, 0xD4F3, 0xBF9A, 0xD4F4, 0xBF9B, 0xD4F5, 0xBF9C, 0xD4F6, 0xBF9D, 0xD4F7, 0xBF9E, 0xD4F9, - 0xBF9F, 0xD4FA, 0xBFA0, 0xD4FC, 0xBFA1, 0xC5D0, 0xBFA2, 0xC5D1, 0xBFA3, 0xC5D4, 0xBFA4, 0xC5D8, 0xBFA5, 0xC5E0, 0xBFA6, 0xC5E1, - 0xBFA7, 0xC5E3, 0xBFA8, 0xC5E5, 0xBFA9, 0xC5EC, 0xBFAA, 0xC5ED, 0xBFAB, 0xC5EE, 0xBFAC, 0xC5F0, 0xBFAD, 0xC5F4, 0xBFAE, 0xC5F6, - 0xBFAF, 0xC5F7, 0xBFB0, 0xC5FC, 0xBFB1, 0xC5FD, 0xBFB2, 0xC5FE, 0xBFB3, 0xC5FF, 0xBFB4, 0xC600, 0xBFB5, 0xC601, 0xBFB6, 0xC605, - 0xBFB7, 0xC606, 0xBFB8, 0xC607, 0xBFB9, 0xC608, 0xBFBA, 0xC60C, 0xBFBB, 0xC610, 0xBFBC, 0xC618, 0xBFBD, 0xC619, 0xBFBE, 0xC61B, - 0xBFBF, 0xC61C, 0xBFC0, 0xC624, 0xBFC1, 0xC625, 0xBFC2, 0xC628, 0xBFC3, 0xC62C, 0xBFC4, 0xC62D, 0xBFC5, 0xC62E, 0xBFC6, 0xC630, - 0xBFC7, 0xC633, 0xBFC8, 0xC634, 0xBFC9, 0xC635, 0xBFCA, 0xC637, 0xBFCB, 0xC639, 0xBFCC, 0xC63B, 0xBFCD, 0xC640, 0xBFCE, 0xC641, - 0xBFCF, 0xC644, 0xBFD0, 0xC648, 0xBFD1, 0xC650, 0xBFD2, 0xC651, 0xBFD3, 0xC653, 0xBFD4, 0xC654, 0xBFD5, 0xC655, 0xBFD6, 0xC65C, - 0xBFD7, 0xC65D, 0xBFD8, 0xC660, 0xBFD9, 0xC66C, 0xBFDA, 0xC66F, 0xBFDB, 0xC671, 0xBFDC, 0xC678, 0xBFDD, 0xC679, 0xBFDE, 0xC67C, - 0xBFDF, 0xC680, 0xBFE0, 0xC688, 0xBFE1, 0xC689, 0xBFE2, 0xC68B, 0xBFE3, 0xC68D, 0xBFE4, 0xC694, 0xBFE5, 0xC695, 0xBFE6, 0xC698, - 0xBFE7, 0xC69C, 0xBFE8, 0xC6A4, 0xBFE9, 0xC6A5, 0xBFEA, 0xC6A7, 0xBFEB, 0xC6A9, 0xBFEC, 0xC6B0, 0xBFED, 0xC6B1, 0xBFEE, 0xC6B4, - 0xBFEF, 0xC6B8, 0xBFF0, 0xC6B9, 0xBFF1, 0xC6BA, 0xBFF2, 0xC6C0, 0xBFF3, 0xC6C1, 0xBFF4, 0xC6C3, 0xBFF5, 0xC6C5, 0xBFF6, 0xC6CC, - 0xBFF7, 0xC6CD, 0xBFF8, 0xC6D0, 0xBFF9, 0xC6D4, 0xBFFA, 0xC6DC, 0xBFFB, 0xC6DD, 0xBFFC, 0xC6E0, 0xBFFD, 0xC6E1, 0xBFFE, 0xC6E8, - 0xC041, 0xD4FE, 0xC042, 0xD4FF, 0xC043, 0xD500, 0xC044, 0xD501, 0xC045, 0xD502, 0xC046, 0xD503, 0xC047, 0xD505, 0xC048, 0xD506, - 0xC049, 0xD507, 0xC04A, 0xD509, 0xC04B, 0xD50A, 0xC04C, 0xD50B, 0xC04D, 0xD50D, 0xC04E, 0xD50E, 0xC04F, 0xD50F, 0xC050, 0xD510, - 0xC051, 0xD511, 0xC052, 0xD512, 0xC053, 0xD513, 0xC054, 0xD516, 0xC055, 0xD518, 0xC056, 0xD519, 0xC057, 0xD51A, 0xC058, 0xD51B, - 0xC059, 0xD51C, 0xC05A, 0xD51D, 0xC061, 0xD51E, 0xC062, 0xD51F, 0xC063, 0xD520, 0xC064, 0xD521, 0xC065, 0xD522, 0xC066, 0xD523, - 0xC067, 0xD524, 0xC068, 0xD525, 0xC069, 0xD526, 0xC06A, 0xD527, 0xC06B, 0xD528, 0xC06C, 0xD529, 0xC06D, 0xD52A, 0xC06E, 0xD52B, - 0xC06F, 0xD52C, 0xC070, 0xD52D, 0xC071, 0xD52E, 0xC072, 0xD52F, 0xC073, 0xD530, 0xC074, 0xD531, 0xC075, 0xD532, 0xC076, 0xD533, - 0xC077, 0xD534, 0xC078, 0xD535, 0xC079, 0xD536, 0xC07A, 0xD537, 0xC081, 0xD538, 0xC082, 0xD539, 0xC083, 0xD53A, 0xC084, 0xD53B, - 0xC085, 0xD53E, 0xC086, 0xD53F, 0xC087, 0xD541, 0xC088, 0xD542, 0xC089, 0xD543, 0xC08A, 0xD545, 0xC08B, 0xD546, 0xC08C, 0xD547, - 0xC08D, 0xD548, 0xC08E, 0xD549, 0xC08F, 0xD54A, 0xC090, 0xD54B, 0xC091, 0xD54E, 0xC092, 0xD550, 0xC093, 0xD552, 0xC094, 0xD553, - 0xC095, 0xD554, 0xC096, 0xD555, 0xC097, 0xD556, 0xC098, 0xD557, 0xC099, 0xD55A, 0xC09A, 0xD55B, 0xC09B, 0xD55D, 0xC09C, 0xD55E, - 0xC09D, 0xD55F, 0xC09E, 0xD561, 0xC09F, 0xD562, 0xC0A0, 0xD563, 0xC0A1, 0xC6E9, 0xC0A2, 0xC6EC, 0xC0A3, 0xC6F0, 0xC0A4, 0xC6F8, - 0xC0A5, 0xC6F9, 0xC0A6, 0xC6FD, 0xC0A7, 0xC704, 0xC0A8, 0xC705, 0xC0A9, 0xC708, 0xC0AA, 0xC70C, 0xC0AB, 0xC714, 0xC0AC, 0xC715, - 0xC0AD, 0xC717, 0xC0AE, 0xC719, 0xC0AF, 0xC720, 0xC0B0, 0xC721, 0xC0B1, 0xC724, 0xC0B2, 0xC728, 0xC0B3, 0xC730, 0xC0B4, 0xC731, - 0xC0B5, 0xC733, 0xC0B6, 0xC735, 0xC0B7, 0xC737, 0xC0B8, 0xC73C, 0xC0B9, 0xC73D, 0xC0BA, 0xC740, 0xC0BB, 0xC744, 0xC0BC, 0xC74A, - 0xC0BD, 0xC74C, 0xC0BE, 0xC74D, 0xC0BF, 0xC74F, 0xC0C0, 0xC751, 0xC0C1, 0xC752, 0xC0C2, 0xC753, 0xC0C3, 0xC754, 0xC0C4, 0xC755, - 0xC0C5, 0xC756, 0xC0C6, 0xC757, 0xC0C7, 0xC758, 0xC0C8, 0xC75C, 0xC0C9, 0xC760, 0xC0CA, 0xC768, 0xC0CB, 0xC76B, 0xC0CC, 0xC774, - 0xC0CD, 0xC775, 0xC0CE, 0xC778, 0xC0CF, 0xC77C, 0xC0D0, 0xC77D, 0xC0D1, 0xC77E, 0xC0D2, 0xC783, 0xC0D3, 0xC784, 0xC0D4, 0xC785, - 0xC0D5, 0xC787, 0xC0D6, 0xC788, 0xC0D7, 0xC789, 0xC0D8, 0xC78A, 0xC0D9, 0xC78E, 0xC0DA, 0xC790, 0xC0DB, 0xC791, 0xC0DC, 0xC794, - 0xC0DD, 0xC796, 0xC0DE, 0xC797, 0xC0DF, 0xC798, 0xC0E0, 0xC79A, 0xC0E1, 0xC7A0, 0xC0E2, 0xC7A1, 0xC0E3, 0xC7A3, 0xC0E4, 0xC7A4, - 0xC0E5, 0xC7A5, 0xC0E6, 0xC7A6, 0xC0E7, 0xC7AC, 0xC0E8, 0xC7AD, 0xC0E9, 0xC7B0, 0xC0EA, 0xC7B4, 0xC0EB, 0xC7BC, 0xC0EC, 0xC7BD, - 0xC0ED, 0xC7BF, 0xC0EE, 0xC7C0, 0xC0EF, 0xC7C1, 0xC0F0, 0xC7C8, 0xC0F1, 0xC7C9, 0xC0F2, 0xC7CC, 0xC0F3, 0xC7CE, 0xC0F4, 0xC7D0, - 0xC0F5, 0xC7D8, 0xC0F6, 0xC7DD, 0xC0F7, 0xC7E4, 0xC0F8, 0xC7E8, 0xC0F9, 0xC7EC, 0xC0FA, 0xC800, 0xC0FB, 0xC801, 0xC0FC, 0xC804, - 0xC0FD, 0xC808, 0xC0FE, 0xC80A, 0xC141, 0xD564, 0xC142, 0xD566, 0xC143, 0xD567, 0xC144, 0xD56A, 0xC145, 0xD56C, 0xC146, 0xD56E, - 0xC147, 0xD56F, 0xC148, 0xD570, 0xC149, 0xD571, 0xC14A, 0xD572, 0xC14B, 0xD573, 0xC14C, 0xD576, 0xC14D, 0xD577, 0xC14E, 0xD579, - 0xC14F, 0xD57A, 0xC150, 0xD57B, 0xC151, 0xD57D, 0xC152, 0xD57E, 0xC153, 0xD57F, 0xC154, 0xD580, 0xC155, 0xD581, 0xC156, 0xD582, - 0xC157, 0xD583, 0xC158, 0xD586, 0xC159, 0xD58A, 0xC15A, 0xD58B, 0xC161, 0xD58C, 0xC162, 0xD58D, 0xC163, 0xD58E, 0xC164, 0xD58F, - 0xC165, 0xD591, 0xC166, 0xD592, 0xC167, 0xD593, 0xC168, 0xD594, 0xC169, 0xD595, 0xC16A, 0xD596, 0xC16B, 0xD597, 0xC16C, 0xD598, - 0xC16D, 0xD599, 0xC16E, 0xD59A, 0xC16F, 0xD59B, 0xC170, 0xD59C, 0xC171, 0xD59D, 0xC172, 0xD59E, 0xC173, 0xD59F, 0xC174, 0xD5A0, - 0xC175, 0xD5A1, 0xC176, 0xD5A2, 0xC177, 0xD5A3, 0xC178, 0xD5A4, 0xC179, 0xD5A6, 0xC17A, 0xD5A7, 0xC181, 0xD5A8, 0xC182, 0xD5A9, - 0xC183, 0xD5AA, 0xC184, 0xD5AB, 0xC185, 0xD5AC, 0xC186, 0xD5AD, 0xC187, 0xD5AE, 0xC188, 0xD5AF, 0xC189, 0xD5B0, 0xC18A, 0xD5B1, - 0xC18B, 0xD5B2, 0xC18C, 0xD5B3, 0xC18D, 0xD5B4, 0xC18E, 0xD5B5, 0xC18F, 0xD5B6, 0xC190, 0xD5B7, 0xC191, 0xD5B8, 0xC192, 0xD5B9, - 0xC193, 0xD5BA, 0xC194, 0xD5BB, 0xC195, 0xD5BC, 0xC196, 0xD5BD, 0xC197, 0xD5BE, 0xC198, 0xD5BF, 0xC199, 0xD5C0, 0xC19A, 0xD5C1, - 0xC19B, 0xD5C2, 0xC19C, 0xD5C3, 0xC19D, 0xD5C4, 0xC19E, 0xD5C5, 0xC19F, 0xD5C6, 0xC1A0, 0xD5C7, 0xC1A1, 0xC810, 0xC1A2, 0xC811, - 0xC1A3, 0xC813, 0xC1A4, 0xC815, 0xC1A5, 0xC816, 0xC1A6, 0xC81C, 0xC1A7, 0xC81D, 0xC1A8, 0xC820, 0xC1A9, 0xC824, 0xC1AA, 0xC82C, - 0xC1AB, 0xC82D, 0xC1AC, 0xC82F, 0xC1AD, 0xC831, 0xC1AE, 0xC838, 0xC1AF, 0xC83C, 0xC1B0, 0xC840, 0xC1B1, 0xC848, 0xC1B2, 0xC849, - 0xC1B3, 0xC84C, 0xC1B4, 0xC84D, 0xC1B5, 0xC854, 0xC1B6, 0xC870, 0xC1B7, 0xC871, 0xC1B8, 0xC874, 0xC1B9, 0xC878, 0xC1BA, 0xC87A, - 0xC1BB, 0xC880, 0xC1BC, 0xC881, 0xC1BD, 0xC883, 0xC1BE, 0xC885, 0xC1BF, 0xC886, 0xC1C0, 0xC887, 0xC1C1, 0xC88B, 0xC1C2, 0xC88C, - 0xC1C3, 0xC88D, 0xC1C4, 0xC894, 0xC1C5, 0xC89D, 0xC1C6, 0xC89F, 0xC1C7, 0xC8A1, 0xC1C8, 0xC8A8, 0xC1C9, 0xC8BC, 0xC1CA, 0xC8BD, - 0xC1CB, 0xC8C4, 0xC1CC, 0xC8C8, 0xC1CD, 0xC8CC, 0xC1CE, 0xC8D4, 0xC1CF, 0xC8D5, 0xC1D0, 0xC8D7, 0xC1D1, 0xC8D9, 0xC1D2, 0xC8E0, - 0xC1D3, 0xC8E1, 0xC1D4, 0xC8E4, 0xC1D5, 0xC8F5, 0xC1D6, 0xC8FC, 0xC1D7, 0xC8FD, 0xC1D8, 0xC900, 0xC1D9, 0xC904, 0xC1DA, 0xC905, - 0xC1DB, 0xC906, 0xC1DC, 0xC90C, 0xC1DD, 0xC90D, 0xC1DE, 0xC90F, 0xC1DF, 0xC911, 0xC1E0, 0xC918, 0xC1E1, 0xC92C, 0xC1E2, 0xC934, - 0xC1E3, 0xC950, 0xC1E4, 0xC951, 0xC1E5, 0xC954, 0xC1E6, 0xC958, 0xC1E7, 0xC960, 0xC1E8, 0xC961, 0xC1E9, 0xC963, 0xC1EA, 0xC96C, - 0xC1EB, 0xC970, 0xC1EC, 0xC974, 0xC1ED, 0xC97C, 0xC1EE, 0xC988, 0xC1EF, 0xC989, 0xC1F0, 0xC98C, 0xC1F1, 0xC990, 0xC1F2, 0xC998, - 0xC1F3, 0xC999, 0xC1F4, 0xC99B, 0xC1F5, 0xC99D, 0xC1F6, 0xC9C0, 0xC1F7, 0xC9C1, 0xC1F8, 0xC9C4, 0xC1F9, 0xC9C7, 0xC1FA, 0xC9C8, - 0xC1FB, 0xC9CA, 0xC1FC, 0xC9D0, 0xC1FD, 0xC9D1, 0xC1FE, 0xC9D3, 0xC241, 0xD5CA, 0xC242, 0xD5CB, 0xC243, 0xD5CD, 0xC244, 0xD5CE, - 0xC245, 0xD5CF, 0xC246, 0xD5D1, 0xC247, 0xD5D3, 0xC248, 0xD5D4, 0xC249, 0xD5D5, 0xC24A, 0xD5D6, 0xC24B, 0xD5D7, 0xC24C, 0xD5DA, - 0xC24D, 0xD5DC, 0xC24E, 0xD5DE, 0xC24F, 0xD5DF, 0xC250, 0xD5E0, 0xC251, 0xD5E1, 0xC252, 0xD5E2, 0xC253, 0xD5E3, 0xC254, 0xD5E6, - 0xC255, 0xD5E7, 0xC256, 0xD5E9, 0xC257, 0xD5EA, 0xC258, 0xD5EB, 0xC259, 0xD5ED, 0xC25A, 0xD5EE, 0xC261, 0xD5EF, 0xC262, 0xD5F0, - 0xC263, 0xD5F1, 0xC264, 0xD5F2, 0xC265, 0xD5F3, 0xC266, 0xD5F6, 0xC267, 0xD5F8, 0xC268, 0xD5FA, 0xC269, 0xD5FB, 0xC26A, 0xD5FC, - 0xC26B, 0xD5FD, 0xC26C, 0xD5FE, 0xC26D, 0xD5FF, 0xC26E, 0xD602, 0xC26F, 0xD603, 0xC270, 0xD605, 0xC271, 0xD606, 0xC272, 0xD607, - 0xC273, 0xD609, 0xC274, 0xD60A, 0xC275, 0xD60B, 0xC276, 0xD60C, 0xC277, 0xD60D, 0xC278, 0xD60E, 0xC279, 0xD60F, 0xC27A, 0xD612, - 0xC281, 0xD616, 0xC282, 0xD617, 0xC283, 0xD618, 0xC284, 0xD619, 0xC285, 0xD61A, 0xC286, 0xD61B, 0xC287, 0xD61D, 0xC288, 0xD61E, - 0xC289, 0xD61F, 0xC28A, 0xD621, 0xC28B, 0xD622, 0xC28C, 0xD623, 0xC28D, 0xD625, 0xC28E, 0xD626, 0xC28F, 0xD627, 0xC290, 0xD628, - 0xC291, 0xD629, 0xC292, 0xD62A, 0xC293, 0xD62B, 0xC294, 0xD62C, 0xC295, 0xD62E, 0xC296, 0xD62F, 0xC297, 0xD630, 0xC298, 0xD631, - 0xC299, 0xD632, 0xC29A, 0xD633, 0xC29B, 0xD634, 0xC29C, 0xD635, 0xC29D, 0xD636, 0xC29E, 0xD637, 0xC29F, 0xD63A, 0xC2A0, 0xD63B, - 0xC2A1, 0xC9D5, 0xC2A2, 0xC9D6, 0xC2A3, 0xC9D9, 0xC2A4, 0xC9DA, 0xC2A5, 0xC9DC, 0xC2A6, 0xC9DD, 0xC2A7, 0xC9E0, 0xC2A8, 0xC9E2, - 0xC2A9, 0xC9E4, 0xC2AA, 0xC9E7, 0xC2AB, 0xC9EC, 0xC2AC, 0xC9ED, 0xC2AD, 0xC9EF, 0xC2AE, 0xC9F0, 0xC2AF, 0xC9F1, 0xC2B0, 0xC9F8, - 0xC2B1, 0xC9F9, 0xC2B2, 0xC9FC, 0xC2B3, 0xCA00, 0xC2B4, 0xCA08, 0xC2B5, 0xCA09, 0xC2B6, 0xCA0B, 0xC2B7, 0xCA0C, 0xC2B8, 0xCA0D, - 0xC2B9, 0xCA14, 0xC2BA, 0xCA18, 0xC2BB, 0xCA29, 0xC2BC, 0xCA4C, 0xC2BD, 0xCA4D, 0xC2BE, 0xCA50, 0xC2BF, 0xCA54, 0xC2C0, 0xCA5C, - 0xC2C1, 0xCA5D, 0xC2C2, 0xCA5F, 0xC2C3, 0xCA60, 0xC2C4, 0xCA61, 0xC2C5, 0xCA68, 0xC2C6, 0xCA7D, 0xC2C7, 0xCA84, 0xC2C8, 0xCA98, - 0xC2C9, 0xCABC, 0xC2CA, 0xCABD, 0xC2CB, 0xCAC0, 0xC2CC, 0xCAC4, 0xC2CD, 0xCACC, 0xC2CE, 0xCACD, 0xC2CF, 0xCACF, 0xC2D0, 0xCAD1, - 0xC2D1, 0xCAD3, 0xC2D2, 0xCAD8, 0xC2D3, 0xCAD9, 0xC2D4, 0xCAE0, 0xC2D5, 0xCAEC, 0xC2D6, 0xCAF4, 0xC2D7, 0xCB08, 0xC2D8, 0xCB10, - 0xC2D9, 0xCB14, 0xC2DA, 0xCB18, 0xC2DB, 0xCB20, 0xC2DC, 0xCB21, 0xC2DD, 0xCB41, 0xC2DE, 0xCB48, 0xC2DF, 0xCB49, 0xC2E0, 0xCB4C, - 0xC2E1, 0xCB50, 0xC2E2, 0xCB58, 0xC2E3, 0xCB59, 0xC2E4, 0xCB5D, 0xC2E5, 0xCB64, 0xC2E6, 0xCB78, 0xC2E7, 0xCB79, 0xC2E8, 0xCB9C, - 0xC2E9, 0xCBB8, 0xC2EA, 0xCBD4, 0xC2EB, 0xCBE4, 0xC2EC, 0xCBE7, 0xC2ED, 0xCBE9, 0xC2EE, 0xCC0C, 0xC2EF, 0xCC0D, 0xC2F0, 0xCC10, - 0xC2F1, 0xCC14, 0xC2F2, 0xCC1C, 0xC2F3, 0xCC1D, 0xC2F4, 0xCC21, 0xC2F5, 0xCC22, 0xC2F6, 0xCC27, 0xC2F7, 0xCC28, 0xC2F8, 0xCC29, - 0xC2F9, 0xCC2C, 0xC2FA, 0xCC2E, 0xC2FB, 0xCC30, 0xC2FC, 0xCC38, 0xC2FD, 0xCC39, 0xC2FE, 0xCC3B, 0xC341, 0xD63D, 0xC342, 0xD63E, - 0xC343, 0xD63F, 0xC344, 0xD641, 0xC345, 0xD642, 0xC346, 0xD643, 0xC347, 0xD644, 0xC348, 0xD646, 0xC349, 0xD647, 0xC34A, 0xD64A, - 0xC34B, 0xD64C, 0xC34C, 0xD64E, 0xC34D, 0xD64F, 0xC34E, 0xD650, 0xC34F, 0xD652, 0xC350, 0xD653, 0xC351, 0xD656, 0xC352, 0xD657, - 0xC353, 0xD659, 0xC354, 0xD65A, 0xC355, 0xD65B, 0xC356, 0xD65D, 0xC357, 0xD65E, 0xC358, 0xD65F, 0xC359, 0xD660, 0xC35A, 0xD661, - 0xC361, 0xD662, 0xC362, 0xD663, 0xC363, 0xD664, 0xC364, 0xD665, 0xC365, 0xD666, 0xC366, 0xD668, 0xC367, 0xD66A, 0xC368, 0xD66B, - 0xC369, 0xD66C, 0xC36A, 0xD66D, 0xC36B, 0xD66E, 0xC36C, 0xD66F, 0xC36D, 0xD672, 0xC36E, 0xD673, 0xC36F, 0xD675, 0xC370, 0xD676, - 0xC371, 0xD677, 0xC372, 0xD678, 0xC373, 0xD679, 0xC374, 0xD67A, 0xC375, 0xD67B, 0xC376, 0xD67C, 0xC377, 0xD67D, 0xC378, 0xD67E, - 0xC379, 0xD67F, 0xC37A, 0xD680, 0xC381, 0xD681, 0xC382, 0xD682, 0xC383, 0xD684, 0xC384, 0xD686, 0xC385, 0xD687, 0xC386, 0xD688, - 0xC387, 0xD689, 0xC388, 0xD68A, 0xC389, 0xD68B, 0xC38A, 0xD68E, 0xC38B, 0xD68F, 0xC38C, 0xD691, 0xC38D, 0xD692, 0xC38E, 0xD693, - 0xC38F, 0xD695, 0xC390, 0xD696, 0xC391, 0xD697, 0xC392, 0xD698, 0xC393, 0xD699, 0xC394, 0xD69A, 0xC395, 0xD69B, 0xC396, 0xD69C, - 0xC397, 0xD69E, 0xC398, 0xD6A0, 0xC399, 0xD6A2, 0xC39A, 0xD6A3, 0xC39B, 0xD6A4, 0xC39C, 0xD6A5, 0xC39D, 0xD6A6, 0xC39E, 0xD6A7, - 0xC39F, 0xD6A9, 0xC3A0, 0xD6AA, 0xC3A1, 0xCC3C, 0xC3A2, 0xCC3D, 0xC3A3, 0xCC3E, 0xC3A4, 0xCC44, 0xC3A5, 0xCC45, 0xC3A6, 0xCC48, - 0xC3A7, 0xCC4C, 0xC3A8, 0xCC54, 0xC3A9, 0xCC55, 0xC3AA, 0xCC57, 0xC3AB, 0xCC58, 0xC3AC, 0xCC59, 0xC3AD, 0xCC60, 0xC3AE, 0xCC64, - 0xC3AF, 0xCC66, 0xC3B0, 0xCC68, 0xC3B1, 0xCC70, 0xC3B2, 0xCC75, 0xC3B3, 0xCC98, 0xC3B4, 0xCC99, 0xC3B5, 0xCC9C, 0xC3B6, 0xCCA0, - 0xC3B7, 0xCCA8, 0xC3B8, 0xCCA9, 0xC3B9, 0xCCAB, 0xC3BA, 0xCCAC, 0xC3BB, 0xCCAD, 0xC3BC, 0xCCB4, 0xC3BD, 0xCCB5, 0xC3BE, 0xCCB8, - 0xC3BF, 0xCCBC, 0xC3C0, 0xCCC4, 0xC3C1, 0xCCC5, 0xC3C2, 0xCCC7, 0xC3C3, 0xCCC9, 0xC3C4, 0xCCD0, 0xC3C5, 0xCCD4, 0xC3C6, 0xCCE4, - 0xC3C7, 0xCCEC, 0xC3C8, 0xCCF0, 0xC3C9, 0xCD01, 0xC3CA, 0xCD08, 0xC3CB, 0xCD09, 0xC3CC, 0xCD0C, 0xC3CD, 0xCD10, 0xC3CE, 0xCD18, - 0xC3CF, 0xCD19, 0xC3D0, 0xCD1B, 0xC3D1, 0xCD1D, 0xC3D2, 0xCD24, 0xC3D3, 0xCD28, 0xC3D4, 0xCD2C, 0xC3D5, 0xCD39, 0xC3D6, 0xCD5C, - 0xC3D7, 0xCD60, 0xC3D8, 0xCD64, 0xC3D9, 0xCD6C, 0xC3DA, 0xCD6D, 0xC3DB, 0xCD6F, 0xC3DC, 0xCD71, 0xC3DD, 0xCD78, 0xC3DE, 0xCD88, - 0xC3DF, 0xCD94, 0xC3E0, 0xCD95, 0xC3E1, 0xCD98, 0xC3E2, 0xCD9C, 0xC3E3, 0xCDA4, 0xC3E4, 0xCDA5, 0xC3E5, 0xCDA7, 0xC3E6, 0xCDA9, - 0xC3E7, 0xCDB0, 0xC3E8, 0xCDC4, 0xC3E9, 0xCDCC, 0xC3EA, 0xCDD0, 0xC3EB, 0xCDE8, 0xC3EC, 0xCDEC, 0xC3ED, 0xCDF0, 0xC3EE, 0xCDF8, - 0xC3EF, 0xCDF9, 0xC3F0, 0xCDFB, 0xC3F1, 0xCDFD, 0xC3F2, 0xCE04, 0xC3F3, 0xCE08, 0xC3F4, 0xCE0C, 0xC3F5, 0xCE14, 0xC3F6, 0xCE19, - 0xC3F7, 0xCE20, 0xC3F8, 0xCE21, 0xC3F9, 0xCE24, 0xC3FA, 0xCE28, 0xC3FB, 0xCE30, 0xC3FC, 0xCE31, 0xC3FD, 0xCE33, 0xC3FE, 0xCE35, - 0xC441, 0xD6AB, 0xC442, 0xD6AD, 0xC443, 0xD6AE, 0xC444, 0xD6AF, 0xC445, 0xD6B1, 0xC446, 0xD6B2, 0xC447, 0xD6B3, 0xC448, 0xD6B4, - 0xC449, 0xD6B5, 0xC44A, 0xD6B6, 0xC44B, 0xD6B7, 0xC44C, 0xD6B8, 0xC44D, 0xD6BA, 0xC44E, 0xD6BC, 0xC44F, 0xD6BD, 0xC450, 0xD6BE, - 0xC451, 0xD6BF, 0xC452, 0xD6C0, 0xC453, 0xD6C1, 0xC454, 0xD6C2, 0xC455, 0xD6C3, 0xC456, 0xD6C6, 0xC457, 0xD6C7, 0xC458, 0xD6C9, - 0xC459, 0xD6CA, 0xC45A, 0xD6CB, 0xC461, 0xD6CD, 0xC462, 0xD6CE, 0xC463, 0xD6CF, 0xC464, 0xD6D0, 0xC465, 0xD6D2, 0xC466, 0xD6D3, - 0xC467, 0xD6D5, 0xC468, 0xD6D6, 0xC469, 0xD6D8, 0xC46A, 0xD6DA, 0xC46B, 0xD6DB, 0xC46C, 0xD6DC, 0xC46D, 0xD6DD, 0xC46E, 0xD6DE, - 0xC46F, 0xD6DF, 0xC470, 0xD6E1, 0xC471, 0xD6E2, 0xC472, 0xD6E3, 0xC473, 0xD6E5, 0xC474, 0xD6E6, 0xC475, 0xD6E7, 0xC476, 0xD6E9, - 0xC477, 0xD6EA, 0xC478, 0xD6EB, 0xC479, 0xD6EC, 0xC47A, 0xD6ED, 0xC481, 0xD6EE, 0xC482, 0xD6EF, 0xC483, 0xD6F1, 0xC484, 0xD6F2, - 0xC485, 0xD6F3, 0xC486, 0xD6F4, 0xC487, 0xD6F6, 0xC488, 0xD6F7, 0xC489, 0xD6F8, 0xC48A, 0xD6F9, 0xC48B, 0xD6FA, 0xC48C, 0xD6FB, - 0xC48D, 0xD6FE, 0xC48E, 0xD6FF, 0xC48F, 0xD701, 0xC490, 0xD702, 0xC491, 0xD703, 0xC492, 0xD705, 0xC493, 0xD706, 0xC494, 0xD707, - 0xC495, 0xD708, 0xC496, 0xD709, 0xC497, 0xD70A, 0xC498, 0xD70B, 0xC499, 0xD70C, 0xC49A, 0xD70D, 0xC49B, 0xD70E, 0xC49C, 0xD70F, - 0xC49D, 0xD710, 0xC49E, 0xD712, 0xC49F, 0xD713, 0xC4A0, 0xD714, 0xC4A1, 0xCE58, 0xC4A2, 0xCE59, 0xC4A3, 0xCE5C, 0xC4A4, 0xCE5F, - 0xC4A5, 0xCE60, 0xC4A6, 0xCE61, 0xC4A7, 0xCE68, 0xC4A8, 0xCE69, 0xC4A9, 0xCE6B, 0xC4AA, 0xCE6D, 0xC4AB, 0xCE74, 0xC4AC, 0xCE75, - 0xC4AD, 0xCE78, 0xC4AE, 0xCE7C, 0xC4AF, 0xCE84, 0xC4B0, 0xCE85, 0xC4B1, 0xCE87, 0xC4B2, 0xCE89, 0xC4B3, 0xCE90, 0xC4B4, 0xCE91, - 0xC4B5, 0xCE94, 0xC4B6, 0xCE98, 0xC4B7, 0xCEA0, 0xC4B8, 0xCEA1, 0xC4B9, 0xCEA3, 0xC4BA, 0xCEA4, 0xC4BB, 0xCEA5, 0xC4BC, 0xCEAC, - 0xC4BD, 0xCEAD, 0xC4BE, 0xCEC1, 0xC4BF, 0xCEE4, 0xC4C0, 0xCEE5, 0xC4C1, 0xCEE8, 0xC4C2, 0xCEEB, 0xC4C3, 0xCEEC, 0xC4C4, 0xCEF4, - 0xC4C5, 0xCEF5, 0xC4C6, 0xCEF7, 0xC4C7, 0xCEF8, 0xC4C8, 0xCEF9, 0xC4C9, 0xCF00, 0xC4CA, 0xCF01, 0xC4CB, 0xCF04, 0xC4CC, 0xCF08, - 0xC4CD, 0xCF10, 0xC4CE, 0xCF11, 0xC4CF, 0xCF13, 0xC4D0, 0xCF15, 0xC4D1, 0xCF1C, 0xC4D2, 0xCF20, 0xC4D3, 0xCF24, 0xC4D4, 0xCF2C, - 0xC4D5, 0xCF2D, 0xC4D6, 0xCF2F, 0xC4D7, 0xCF30, 0xC4D8, 0xCF31, 0xC4D9, 0xCF38, 0xC4DA, 0xCF54, 0xC4DB, 0xCF55, 0xC4DC, 0xCF58, - 0xC4DD, 0xCF5C, 0xC4DE, 0xCF64, 0xC4DF, 0xCF65, 0xC4E0, 0xCF67, 0xC4E1, 0xCF69, 0xC4E2, 0xCF70, 0xC4E3, 0xCF71, 0xC4E4, 0xCF74, - 0xC4E5, 0xCF78, 0xC4E6, 0xCF80, 0xC4E7, 0xCF85, 0xC4E8, 0xCF8C, 0xC4E9, 0xCFA1, 0xC4EA, 0xCFA8, 0xC4EB, 0xCFB0, 0xC4EC, 0xCFC4, - 0xC4ED, 0xCFE0, 0xC4EE, 0xCFE1, 0xC4EF, 0xCFE4, 0xC4F0, 0xCFE8, 0xC4F1, 0xCFF0, 0xC4F2, 0xCFF1, 0xC4F3, 0xCFF3, 0xC4F4, 0xCFF5, - 0xC4F5, 0xCFFC, 0xC4F6, 0xD000, 0xC4F7, 0xD004, 0xC4F8, 0xD011, 0xC4F9, 0xD018, 0xC4FA, 0xD02D, 0xC4FB, 0xD034, 0xC4FC, 0xD035, - 0xC4FD, 0xD038, 0xC4FE, 0xD03C, 0xC541, 0xD715, 0xC542, 0xD716, 0xC543, 0xD717, 0xC544, 0xD71A, 0xC545, 0xD71B, 0xC546, 0xD71D, - 0xC547, 0xD71E, 0xC548, 0xD71F, 0xC549, 0xD721, 0xC54A, 0xD722, 0xC54B, 0xD723, 0xC54C, 0xD724, 0xC54D, 0xD725, 0xC54E, 0xD726, - 0xC54F, 0xD727, 0xC550, 0xD72A, 0xC551, 0xD72C, 0xC552, 0xD72E, 0xC553, 0xD72F, 0xC554, 0xD730, 0xC555, 0xD731, 0xC556, 0xD732, - 0xC557, 0xD733, 0xC558, 0xD736, 0xC559, 0xD737, 0xC55A, 0xD739, 0xC561, 0xD73A, 0xC562, 0xD73B, 0xC563, 0xD73D, 0xC564, 0xD73E, - 0xC565, 0xD73F, 0xC566, 0xD740, 0xC567, 0xD741, 0xC568, 0xD742, 0xC569, 0xD743, 0xC56A, 0xD745, 0xC56B, 0xD746, 0xC56C, 0xD748, - 0xC56D, 0xD74A, 0xC56E, 0xD74B, 0xC56F, 0xD74C, 0xC570, 0xD74D, 0xC571, 0xD74E, 0xC572, 0xD74F, 0xC573, 0xD752, 0xC574, 0xD753, - 0xC575, 0xD755, 0xC576, 0xD75A, 0xC577, 0xD75B, 0xC578, 0xD75C, 0xC579, 0xD75D, 0xC57A, 0xD75E, 0xC581, 0xD75F, 0xC582, 0xD762, - 0xC583, 0xD764, 0xC584, 0xD766, 0xC585, 0xD767, 0xC586, 0xD768, 0xC587, 0xD76A, 0xC588, 0xD76B, 0xC589, 0xD76D, 0xC58A, 0xD76E, - 0xC58B, 0xD76F, 0xC58C, 0xD771, 0xC58D, 0xD772, 0xC58E, 0xD773, 0xC58F, 0xD775, 0xC590, 0xD776, 0xC591, 0xD777, 0xC592, 0xD778, - 0xC593, 0xD779, 0xC594, 0xD77A, 0xC595, 0xD77B, 0xC596, 0xD77E, 0xC597, 0xD77F, 0xC598, 0xD780, 0xC599, 0xD782, 0xC59A, 0xD783, - 0xC59B, 0xD784, 0xC59C, 0xD785, 0xC59D, 0xD786, 0xC59E, 0xD787, 0xC59F, 0xD78A, 0xC5A0, 0xD78B, 0xC5A1, 0xD044, 0xC5A2, 0xD045, - 0xC5A3, 0xD047, 0xC5A4, 0xD049, 0xC5A5, 0xD050, 0xC5A6, 0xD054, 0xC5A7, 0xD058, 0xC5A8, 0xD060, 0xC5A9, 0xD06C, 0xC5AA, 0xD06D, - 0xC5AB, 0xD070, 0xC5AC, 0xD074, 0xC5AD, 0xD07C, 0xC5AE, 0xD07D, 0xC5AF, 0xD081, 0xC5B0, 0xD0A4, 0xC5B1, 0xD0A5, 0xC5B2, 0xD0A8, - 0xC5B3, 0xD0AC, 0xC5B4, 0xD0B4, 0xC5B5, 0xD0B5, 0xC5B6, 0xD0B7, 0xC5B7, 0xD0B9, 0xC5B8, 0xD0C0, 0xC5B9, 0xD0C1, 0xC5BA, 0xD0C4, - 0xC5BB, 0xD0C8, 0xC5BC, 0xD0C9, 0xC5BD, 0xD0D0, 0xC5BE, 0xD0D1, 0xC5BF, 0xD0D3, 0xC5C0, 0xD0D4, 0xC5C1, 0xD0D5, 0xC5C2, 0xD0DC, - 0xC5C3, 0xD0DD, 0xC5C4, 0xD0E0, 0xC5C5, 0xD0E4, 0xC5C6, 0xD0EC, 0xC5C7, 0xD0ED, 0xC5C8, 0xD0EF, 0xC5C9, 0xD0F0, 0xC5CA, 0xD0F1, - 0xC5CB, 0xD0F8, 0xC5CC, 0xD10D, 0xC5CD, 0xD130, 0xC5CE, 0xD131, 0xC5CF, 0xD134, 0xC5D0, 0xD138, 0xC5D1, 0xD13A, 0xC5D2, 0xD140, - 0xC5D3, 0xD141, 0xC5D4, 0xD143, 0xC5D5, 0xD144, 0xC5D6, 0xD145, 0xC5D7, 0xD14C, 0xC5D8, 0xD14D, 0xC5D9, 0xD150, 0xC5DA, 0xD154, - 0xC5DB, 0xD15C, 0xC5DC, 0xD15D, 0xC5DD, 0xD15F, 0xC5DE, 0xD161, 0xC5DF, 0xD168, 0xC5E0, 0xD16C, 0xC5E1, 0xD17C, 0xC5E2, 0xD184, - 0xC5E3, 0xD188, 0xC5E4, 0xD1A0, 0xC5E5, 0xD1A1, 0xC5E6, 0xD1A4, 0xC5E7, 0xD1A8, 0xC5E8, 0xD1B0, 0xC5E9, 0xD1B1, 0xC5EA, 0xD1B3, - 0xC5EB, 0xD1B5, 0xC5EC, 0xD1BA, 0xC5ED, 0xD1BC, 0xC5EE, 0xD1C0, 0xC5EF, 0xD1D8, 0xC5F0, 0xD1F4, 0xC5F1, 0xD1F8, 0xC5F2, 0xD207, - 0xC5F3, 0xD209, 0xC5F4, 0xD210, 0xC5F5, 0xD22C, 0xC5F6, 0xD22D, 0xC5F7, 0xD230, 0xC5F8, 0xD234, 0xC5F9, 0xD23C, 0xC5FA, 0xD23D, - 0xC5FB, 0xD23F, 0xC5FC, 0xD241, 0xC5FD, 0xD248, 0xC5FE, 0xD25C, 0xC641, 0xD78D, 0xC642, 0xD78E, 0xC643, 0xD78F, 0xC644, 0xD791, - 0xC645, 0xD792, 0xC646, 0xD793, 0xC647, 0xD794, 0xC648, 0xD795, 0xC649, 0xD796, 0xC64A, 0xD797, 0xC64B, 0xD79A, 0xC64C, 0xD79C, - 0xC64D, 0xD79E, 0xC64E, 0xD79F, 0xC64F, 0xD7A0, 0xC650, 0xD7A1, 0xC651, 0xD7A2, 0xC652, 0xD7A3, 0xC6A1, 0xD264, 0xC6A2, 0xD280, - 0xC6A3, 0xD281, 0xC6A4, 0xD284, 0xC6A5, 0xD288, 0xC6A6, 0xD290, 0xC6A7, 0xD291, 0xC6A8, 0xD295, 0xC6A9, 0xD29C, 0xC6AA, 0xD2A0, - 0xC6AB, 0xD2A4, 0xC6AC, 0xD2AC, 0xC6AD, 0xD2B1, 0xC6AE, 0xD2B8, 0xC6AF, 0xD2B9, 0xC6B0, 0xD2BC, 0xC6B1, 0xD2BF, 0xC6B2, 0xD2C0, - 0xC6B3, 0xD2C2, 0xC6B4, 0xD2C8, 0xC6B5, 0xD2C9, 0xC6B6, 0xD2CB, 0xC6B7, 0xD2D4, 0xC6B8, 0xD2D8, 0xC6B9, 0xD2DC, 0xC6BA, 0xD2E4, - 0xC6BB, 0xD2E5, 0xC6BC, 0xD2F0, 0xC6BD, 0xD2F1, 0xC6BE, 0xD2F4, 0xC6BF, 0xD2F8, 0xC6C0, 0xD300, 0xC6C1, 0xD301, 0xC6C2, 0xD303, - 0xC6C3, 0xD305, 0xC6C4, 0xD30C, 0xC6C5, 0xD30D, 0xC6C6, 0xD30E, 0xC6C7, 0xD310, 0xC6C8, 0xD314, 0xC6C9, 0xD316, 0xC6CA, 0xD31C, - 0xC6CB, 0xD31D, 0xC6CC, 0xD31F, 0xC6CD, 0xD320, 0xC6CE, 0xD321, 0xC6CF, 0xD325, 0xC6D0, 0xD328, 0xC6D1, 0xD329, 0xC6D2, 0xD32C, - 0xC6D3, 0xD330, 0xC6D4, 0xD338, 0xC6D5, 0xD339, 0xC6D6, 0xD33B, 0xC6D7, 0xD33C, 0xC6D8, 0xD33D, 0xC6D9, 0xD344, 0xC6DA, 0xD345, - 0xC6DB, 0xD37C, 0xC6DC, 0xD37D, 0xC6DD, 0xD380, 0xC6DE, 0xD384, 0xC6DF, 0xD38C, 0xC6E0, 0xD38D, 0xC6E1, 0xD38F, 0xC6E2, 0xD390, - 0xC6E3, 0xD391, 0xC6E4, 0xD398, 0xC6E5, 0xD399, 0xC6E6, 0xD39C, 0xC6E7, 0xD3A0, 0xC6E8, 0xD3A8, 0xC6E9, 0xD3A9, 0xC6EA, 0xD3AB, - 0xC6EB, 0xD3AD, 0xC6EC, 0xD3B4, 0xC6ED, 0xD3B8, 0xC6EE, 0xD3BC, 0xC6EF, 0xD3C4, 0xC6F0, 0xD3C5, 0xC6F1, 0xD3C8, 0xC6F2, 0xD3C9, - 0xC6F3, 0xD3D0, 0xC6F4, 0xD3D8, 0xC6F5, 0xD3E1, 0xC6F6, 0xD3E3, 0xC6F7, 0xD3EC, 0xC6F8, 0xD3ED, 0xC6F9, 0xD3F0, 0xC6FA, 0xD3F4, - 0xC6FB, 0xD3FC, 0xC6FC, 0xD3FD, 0xC6FD, 0xD3FF, 0xC6FE, 0xD401, 0xC7A1, 0xD408, 0xC7A2, 0xD41D, 0xC7A3, 0xD440, 0xC7A4, 0xD444, - 0xC7A5, 0xD45C, 0xC7A6, 0xD460, 0xC7A7, 0xD464, 0xC7A8, 0xD46D, 0xC7A9, 0xD46F, 0xC7AA, 0xD478, 0xC7AB, 0xD479, 0xC7AC, 0xD47C, - 0xC7AD, 0xD47F, 0xC7AE, 0xD480, 0xC7AF, 0xD482, 0xC7B0, 0xD488, 0xC7B1, 0xD489, 0xC7B2, 0xD48B, 0xC7B3, 0xD48D, 0xC7B4, 0xD494, - 0xC7B5, 0xD4A9, 0xC7B6, 0xD4CC, 0xC7B7, 0xD4D0, 0xC7B8, 0xD4D4, 0xC7B9, 0xD4DC, 0xC7BA, 0xD4DF, 0xC7BB, 0xD4E8, 0xC7BC, 0xD4EC, - 0xC7BD, 0xD4F0, 0xC7BE, 0xD4F8, 0xC7BF, 0xD4FB, 0xC7C0, 0xD4FD, 0xC7C1, 0xD504, 0xC7C2, 0xD508, 0xC7C3, 0xD50C, 0xC7C4, 0xD514, - 0xC7C5, 0xD515, 0xC7C6, 0xD517, 0xC7C7, 0xD53C, 0xC7C8, 0xD53D, 0xC7C9, 0xD540, 0xC7CA, 0xD544, 0xC7CB, 0xD54C, 0xC7CC, 0xD54D, - 0xC7CD, 0xD54F, 0xC7CE, 0xD551, 0xC7CF, 0xD558, 0xC7D0, 0xD559, 0xC7D1, 0xD55C, 0xC7D2, 0xD560, 0xC7D3, 0xD565, 0xC7D4, 0xD568, - 0xC7D5, 0xD569, 0xC7D6, 0xD56B, 0xC7D7, 0xD56D, 0xC7D8, 0xD574, 0xC7D9, 0xD575, 0xC7DA, 0xD578, 0xC7DB, 0xD57C, 0xC7DC, 0xD584, - 0xC7DD, 0xD585, 0xC7DE, 0xD587, 0xC7DF, 0xD588, 0xC7E0, 0xD589, 0xC7E1, 0xD590, 0xC7E2, 0xD5A5, 0xC7E3, 0xD5C8, 0xC7E4, 0xD5C9, - 0xC7E5, 0xD5CC, 0xC7E6, 0xD5D0, 0xC7E7, 0xD5D2, 0xC7E8, 0xD5D8, 0xC7E9, 0xD5D9, 0xC7EA, 0xD5DB, 0xC7EB, 0xD5DD, 0xC7EC, 0xD5E4, - 0xC7ED, 0xD5E5, 0xC7EE, 0xD5E8, 0xC7EF, 0xD5EC, 0xC7F0, 0xD5F4, 0xC7F1, 0xD5F5, 0xC7F2, 0xD5F7, 0xC7F3, 0xD5F9, 0xC7F4, 0xD600, - 0xC7F5, 0xD601, 0xC7F6, 0xD604, 0xC7F7, 0xD608, 0xC7F8, 0xD610, 0xC7F9, 0xD611, 0xC7FA, 0xD613, 0xC7FB, 0xD614, 0xC7FC, 0xD615, - 0xC7FD, 0xD61C, 0xC7FE, 0xD620, 0xC8A1, 0xD624, 0xC8A2, 0xD62D, 0xC8A3, 0xD638, 0xC8A4, 0xD639, 0xC8A5, 0xD63C, 0xC8A6, 0xD640, - 0xC8A7, 0xD645, 0xC8A8, 0xD648, 0xC8A9, 0xD649, 0xC8AA, 0xD64B, 0xC8AB, 0xD64D, 0xC8AC, 0xD651, 0xC8AD, 0xD654, 0xC8AE, 0xD655, - 0xC8AF, 0xD658, 0xC8B0, 0xD65C, 0xC8B1, 0xD667, 0xC8B2, 0xD669, 0xC8B3, 0xD670, 0xC8B4, 0xD671, 0xC8B5, 0xD674, 0xC8B6, 0xD683, - 0xC8B7, 0xD685, 0xC8B8, 0xD68C, 0xC8B9, 0xD68D, 0xC8BA, 0xD690, 0xC8BB, 0xD694, 0xC8BC, 0xD69D, 0xC8BD, 0xD69F, 0xC8BE, 0xD6A1, - 0xC8BF, 0xD6A8, 0xC8C0, 0xD6AC, 0xC8C1, 0xD6B0, 0xC8C2, 0xD6B9, 0xC8C3, 0xD6BB, 0xC8C4, 0xD6C4, 0xC8C5, 0xD6C5, 0xC8C6, 0xD6C8, - 0xC8C7, 0xD6CC, 0xC8C8, 0xD6D1, 0xC8C9, 0xD6D4, 0xC8CA, 0xD6D7, 0xC8CB, 0xD6D9, 0xC8CC, 0xD6E0, 0xC8CD, 0xD6E4, 0xC8CE, 0xD6E8, - 0xC8CF, 0xD6F0, 0xC8D0, 0xD6F5, 0xC8D1, 0xD6FC, 0xC8D2, 0xD6FD, 0xC8D3, 0xD700, 0xC8D4, 0xD704, 0xC8D5, 0xD711, 0xC8D6, 0xD718, - 0xC8D7, 0xD719, 0xC8D8, 0xD71C, 0xC8D9, 0xD720, 0xC8DA, 0xD728, 0xC8DB, 0xD729, 0xC8DC, 0xD72B, 0xC8DD, 0xD72D, 0xC8DE, 0xD734, - 0xC8DF, 0xD735, 0xC8E0, 0xD738, 0xC8E1, 0xD73C, 0xC8E2, 0xD744, 0xC8E3, 0xD747, 0xC8E4, 0xD749, 0xC8E5, 0xD750, 0xC8E6, 0xD751, - 0xC8E7, 0xD754, 0xC8E8, 0xD756, 0xC8E9, 0xD757, 0xC8EA, 0xD758, 0xC8EB, 0xD759, 0xC8EC, 0xD760, 0xC8ED, 0xD761, 0xC8EE, 0xD763, - 0xC8EF, 0xD765, 0xC8F0, 0xD769, 0xC8F1, 0xD76C, 0xC8F2, 0xD770, 0xC8F3, 0xD774, 0xC8F4, 0xD77C, 0xC8F5, 0xD77D, 0xC8F6, 0xD781, - 0xC8F7, 0xD788, 0xC8F8, 0xD789, 0xC8F9, 0xD78C, 0xC8FA, 0xD790, 0xC8FB, 0xD798, 0xC8FC, 0xD799, 0xC8FD, 0xD79B, 0xC8FE, 0xD79D, - 0xCAA1, 0x4F3D, 0xCAA2, 0x4F73, 0xCAA3, 0x5047, 0xCAA4, 0x50F9, 0xCAA5, 0x52A0, 0xCAA6, 0x53EF, 0xCAA7, 0x5475, 0xCAA8, 0x54E5, - 0xCAA9, 0x5609, 0xCAAA, 0x5AC1, 0xCAAB, 0x5BB6, 0xCAAC, 0x6687, 0xCAAD, 0x67B6, 0xCAAE, 0x67B7, 0xCAAF, 0x67EF, 0xCAB0, 0x6B4C, - 0xCAB1, 0x73C2, 0xCAB2, 0x75C2, 0xCAB3, 0x7A3C, 0xCAB4, 0x82DB, 0xCAB5, 0x8304, 0xCAB6, 0x8857, 0xCAB7, 0x8888, 0xCAB8, 0x8A36, - 0xCAB9, 0x8CC8, 0xCABA, 0x8DCF, 0xCABB, 0x8EFB, 0xCABC, 0x8FE6, 0xCABD, 0x99D5, 0xCABE, 0x523B, 0xCABF, 0x5374, 0xCAC0, 0x5404, - 0xCAC1, 0x606A, 0xCAC2, 0x6164, 0xCAC3, 0x6BBC, 0xCAC4, 0x73CF, 0xCAC5, 0x811A, 0xCAC6, 0x89BA, 0xCAC7, 0x89D2, 0xCAC8, 0x95A3, - 0xCAC9, 0x4F83, 0xCACA, 0x520A, 0xCACB, 0x58BE, 0xCACC, 0x5978, 0xCACD, 0x59E6, 0xCACE, 0x5E72, 0xCACF, 0x5E79, 0xCAD0, 0x61C7, - 0xCAD1, 0x63C0, 0xCAD2, 0x6746, 0xCAD3, 0x67EC, 0xCAD4, 0x687F, 0xCAD5, 0x6F97, 0xCAD6, 0x764E, 0xCAD7, 0x770B, 0xCAD8, 0x78F5, - 0xCAD9, 0x7A08, 0xCADA, 0x7AFF, 0xCADB, 0x7C21, 0xCADC, 0x809D, 0xCADD, 0x826E, 0xCADE, 0x8271, 0xCADF, 0x8AEB, 0xCAE0, 0x9593, - 0xCAE1, 0x4E6B, 0xCAE2, 0x559D, 0xCAE3, 0x66F7, 0xCAE4, 0x6E34, 0xCAE5, 0x78A3, 0xCAE6, 0x7AED, 0xCAE7, 0x845B, 0xCAE8, 0x8910, - 0xCAE9, 0x874E, 0xCAEA, 0x97A8, 0xCAEB, 0x52D8, 0xCAEC, 0x574E, 0xCAED, 0x582A, 0xCAEE, 0x5D4C, 0xCAEF, 0x611F, 0xCAF0, 0x61BE, - 0xCAF1, 0x6221, 0xCAF2, 0x6562, 0xCAF3, 0x67D1, 0xCAF4, 0x6A44, 0xCAF5, 0x6E1B, 0xCAF6, 0x7518, 0xCAF7, 0x75B3, 0xCAF8, 0x76E3, - 0xCAF9, 0x77B0, 0xCAFA, 0x7D3A, 0xCAFB, 0x90AF, 0xCAFC, 0x9451, 0xCAFD, 0x9452, 0xCAFE, 0x9F95, 0xCBA1, 0x5323, 0xCBA2, 0x5CAC, - 0xCBA3, 0x7532, 0xCBA4, 0x80DB, 0xCBA5, 0x9240, 0xCBA6, 0x9598, 0xCBA7, 0x525B, 0xCBA8, 0x5808, 0xCBA9, 0x59DC, 0xCBAA, 0x5CA1, - 0xCBAB, 0x5D17, 0xCBAC, 0x5EB7, 0xCBAD, 0x5F3A, 0xCBAE, 0x5F4A, 0xCBAF, 0x6177, 0xCBB0, 0x6C5F, 0xCBB1, 0x757A, 0xCBB2, 0x7586, - 0xCBB3, 0x7CE0, 0xCBB4, 0x7D73, 0xCBB5, 0x7DB1, 0xCBB6, 0x7F8C, 0xCBB7, 0x8154, 0xCBB8, 0x8221, 0xCBB9, 0x8591, 0xCBBA, 0x8941, - 0xCBBB, 0x8B1B, 0xCBBC, 0x92FC, 0xCBBD, 0x964D, 0xCBBE, 0x9C47, 0xCBBF, 0x4ECB, 0xCBC0, 0x4EF7, 0xCBC1, 0x500B, 0xCBC2, 0x51F1, - 0xCBC3, 0x584F, 0xCBC4, 0x6137, 0xCBC5, 0x613E, 0xCBC6, 0x6168, 0xCBC7, 0x6539, 0xCBC8, 0x69EA, 0xCBC9, 0x6F11, 0xCBCA, 0x75A5, - 0xCBCB, 0x7686, 0xCBCC, 0x76D6, 0xCBCD, 0x7B87, 0xCBCE, 0x82A5, 0xCBCF, 0x84CB, 0xCBD0, 0xF900, 0xCBD1, 0x93A7, 0xCBD2, 0x958B, - 0xCBD3, 0x5580, 0xCBD4, 0x5BA2, 0xCBD5, 0x5751, 0xCBD6, 0xF901, 0xCBD7, 0x7CB3, 0xCBD8, 0x7FB9, 0xCBD9, 0x91B5, 0xCBDA, 0x5028, - 0xCBDB, 0x53BB, 0xCBDC, 0x5C45, 0xCBDD, 0x5DE8, 0xCBDE, 0x62D2, 0xCBDF, 0x636E, 0xCBE0, 0x64DA, 0xCBE1, 0x64E7, 0xCBE2, 0x6E20, - 0xCBE3, 0x70AC, 0xCBE4, 0x795B, 0xCBE5, 0x8DDD, 0xCBE6, 0x8E1E, 0xCBE7, 0xF902, 0xCBE8, 0x907D, 0xCBE9, 0x9245, 0xCBEA, 0x92F8, - 0xCBEB, 0x4E7E, 0xCBEC, 0x4EF6, 0xCBED, 0x5065, 0xCBEE, 0x5DFE, 0xCBEF, 0x5EFA, 0xCBF0, 0x6106, 0xCBF1, 0x6957, 0xCBF2, 0x8171, - 0xCBF3, 0x8654, 0xCBF4, 0x8E47, 0xCBF5, 0x9375, 0xCBF6, 0x9A2B, 0xCBF7, 0x4E5E, 0xCBF8, 0x5091, 0xCBF9, 0x6770, 0xCBFA, 0x6840, - 0xCBFB, 0x5109, 0xCBFC, 0x528D, 0xCBFD, 0x5292, 0xCBFE, 0x6AA2, 0xCCA1, 0x77BC, 0xCCA2, 0x9210, 0xCCA3, 0x9ED4, 0xCCA4, 0x52AB, - 0xCCA5, 0x602F, 0xCCA6, 0x8FF2, 0xCCA7, 0x5048, 0xCCA8, 0x61A9, 0xCCA9, 0x63ED, 0xCCAA, 0x64CA, 0xCCAB, 0x683C, 0xCCAC, 0x6A84, - 0xCCAD, 0x6FC0, 0xCCAE, 0x8188, 0xCCAF, 0x89A1, 0xCCB0, 0x9694, 0xCCB1, 0x5805, 0xCCB2, 0x727D, 0xCCB3, 0x72AC, 0xCCB4, 0x7504, - 0xCCB5, 0x7D79, 0xCCB6, 0x7E6D, 0xCCB7, 0x80A9, 0xCCB8, 0x898B, 0xCCB9, 0x8B74, 0xCCBA, 0x9063, 0xCCBB, 0x9D51, 0xCCBC, 0x6289, - 0xCCBD, 0x6C7A, 0xCCBE, 0x6F54, 0xCCBF, 0x7D50, 0xCCC0, 0x7F3A, 0xCCC1, 0x8A23, 0xCCC2, 0x517C, 0xCCC3, 0x614A, 0xCCC4, 0x7B9D, - 0xCCC5, 0x8B19, 0xCCC6, 0x9257, 0xCCC7, 0x938C, 0xCCC8, 0x4EAC, 0xCCC9, 0x4FD3, 0xCCCA, 0x501E, 0xCCCB, 0x50BE, 0xCCCC, 0x5106, - 0xCCCD, 0x52C1, 0xCCCE, 0x52CD, 0xCCCF, 0x537F, 0xCCD0, 0x5770, 0xCCD1, 0x5883, 0xCCD2, 0x5E9A, 0xCCD3, 0x5F91, 0xCCD4, 0x6176, - 0xCCD5, 0x61AC, 0xCCD6, 0x64CE, 0xCCD7, 0x656C, 0xCCD8, 0x666F, 0xCCD9, 0x66BB, 0xCCDA, 0x66F4, 0xCCDB, 0x6897, 0xCCDC, 0x6D87, - 0xCCDD, 0x7085, 0xCCDE, 0x70F1, 0xCCDF, 0x749F, 0xCCE0, 0x74A5, 0xCCE1, 0x74CA, 0xCCE2, 0x75D9, 0xCCE3, 0x786C, 0xCCE4, 0x78EC, - 0xCCE5, 0x7ADF, 0xCCE6, 0x7AF6, 0xCCE7, 0x7D45, 0xCCE8, 0x7D93, 0xCCE9, 0x8015, 0xCCEA, 0x803F, 0xCCEB, 0x811B, 0xCCEC, 0x8396, - 0xCCED, 0x8B66, 0xCCEE, 0x8F15, 0xCCEF, 0x9015, 0xCCF0, 0x93E1, 0xCCF1, 0x9803, 0xCCF2, 0x9838, 0xCCF3, 0x9A5A, 0xCCF4, 0x9BE8, - 0xCCF5, 0x4FC2, 0xCCF6, 0x5553, 0xCCF7, 0x583A, 0xCCF8, 0x5951, 0xCCF9, 0x5B63, 0xCCFA, 0x5C46, 0xCCFB, 0x60B8, 0xCCFC, 0x6212, - 0xCCFD, 0x6842, 0xCCFE, 0x68B0, 0xCDA1, 0x68E8, 0xCDA2, 0x6EAA, 0xCDA3, 0x754C, 0xCDA4, 0x7678, 0xCDA5, 0x78CE, 0xCDA6, 0x7A3D, - 0xCDA7, 0x7CFB, 0xCDA8, 0x7E6B, 0xCDA9, 0x7E7C, 0xCDAA, 0x8A08, 0xCDAB, 0x8AA1, 0xCDAC, 0x8C3F, 0xCDAD, 0x968E, 0xCDAE, 0x9DC4, - 0xCDAF, 0x53E4, 0xCDB0, 0x53E9, 0xCDB1, 0x544A, 0xCDB2, 0x5471, 0xCDB3, 0x56FA, 0xCDB4, 0x59D1, 0xCDB5, 0x5B64, 0xCDB6, 0x5C3B, - 0xCDB7, 0x5EAB, 0xCDB8, 0x62F7, 0xCDB9, 0x6537, 0xCDBA, 0x6545, 0xCDBB, 0x6572, 0xCDBC, 0x66A0, 0xCDBD, 0x67AF, 0xCDBE, 0x69C1, - 0xCDBF, 0x6CBD, 0xCDC0, 0x75FC, 0xCDC1, 0x7690, 0xCDC2, 0x777E, 0xCDC3, 0x7A3F, 0xCDC4, 0x7F94, 0xCDC5, 0x8003, 0xCDC6, 0x80A1, - 0xCDC7, 0x818F, 0xCDC8, 0x82E6, 0xCDC9, 0x82FD, 0xCDCA, 0x83F0, 0xCDCB, 0x85C1, 0xCDCC, 0x8831, 0xCDCD, 0x88B4, 0xCDCE, 0x8AA5, - 0xCDCF, 0xF903, 0xCDD0, 0x8F9C, 0xCDD1, 0x932E, 0xCDD2, 0x96C7, 0xCDD3, 0x9867, 0xCDD4, 0x9AD8, 0xCDD5, 0x9F13, 0xCDD6, 0x54ED, - 0xCDD7, 0x659B, 0xCDD8, 0x66F2, 0xCDD9, 0x688F, 0xCDDA, 0x7A40, 0xCDDB, 0x8C37, 0xCDDC, 0x9D60, 0xCDDD, 0x56F0, 0xCDDE, 0x5764, - 0xCDDF, 0x5D11, 0xCDE0, 0x6606, 0xCDE1, 0x68B1, 0xCDE2, 0x68CD, 0xCDE3, 0x6EFE, 0xCDE4, 0x7428, 0xCDE5, 0x889E, 0xCDE6, 0x9BE4, - 0xCDE7, 0x6C68, 0xCDE8, 0xF904, 0xCDE9, 0x9AA8, 0xCDEA, 0x4F9B, 0xCDEB, 0x516C, 0xCDEC, 0x5171, 0xCDED, 0x529F, 0xCDEE, 0x5B54, - 0xCDEF, 0x5DE5, 0xCDF0, 0x6050, 0xCDF1, 0x606D, 0xCDF2, 0x62F1, 0xCDF3, 0x63A7, 0xCDF4, 0x653B, 0xCDF5, 0x73D9, 0xCDF6, 0x7A7A, - 0xCDF7, 0x86A3, 0xCDF8, 0x8CA2, 0xCDF9, 0x978F, 0xCDFA, 0x4E32, 0xCDFB, 0x5BE1, 0xCDFC, 0x6208, 0xCDFD, 0x679C, 0xCDFE, 0x74DC, - 0xCEA1, 0x79D1, 0xCEA2, 0x83D3, 0xCEA3, 0x8A87, 0xCEA4, 0x8AB2, 0xCEA5, 0x8DE8, 0xCEA6, 0x904E, 0xCEA7, 0x934B, 0xCEA8, 0x9846, - 0xCEA9, 0x5ED3, 0xCEAA, 0x69E8, 0xCEAB, 0x85FF, 0xCEAC, 0x90ED, 0xCEAD, 0xF905, 0xCEAE, 0x51A0, 0xCEAF, 0x5B98, 0xCEB0, 0x5BEC, - 0xCEB1, 0x6163, 0xCEB2, 0x68FA, 0xCEB3, 0x6B3E, 0xCEB4, 0x704C, 0xCEB5, 0x742F, 0xCEB6, 0x74D8, 0xCEB7, 0x7BA1, 0xCEB8, 0x7F50, - 0xCEB9, 0x83C5, 0xCEBA, 0x89C0, 0xCEBB, 0x8CAB, 0xCEBC, 0x95DC, 0xCEBD, 0x9928, 0xCEBE, 0x522E, 0xCEBF, 0x605D, 0xCEC0, 0x62EC, - 0xCEC1, 0x9002, 0xCEC2, 0x4F8A, 0xCEC3, 0x5149, 0xCEC4, 0x5321, 0xCEC5, 0x58D9, 0xCEC6, 0x5EE3, 0xCEC7, 0x66E0, 0xCEC8, 0x6D38, - 0xCEC9, 0x709A, 0xCECA, 0x72C2, 0xCECB, 0x73D6, 0xCECC, 0x7B50, 0xCECD, 0x80F1, 0xCECE, 0x945B, 0xCECF, 0x5366, 0xCED0, 0x639B, - 0xCED1, 0x7F6B, 0xCED2, 0x4E56, 0xCED3, 0x5080, 0xCED4, 0x584A, 0xCED5, 0x58DE, 0xCED6, 0x602A, 0xCED7, 0x6127, 0xCED8, 0x62D0, - 0xCED9, 0x69D0, 0xCEDA, 0x9B41, 0xCEDB, 0x5B8F, 0xCEDC, 0x7D18, 0xCEDD, 0x80B1, 0xCEDE, 0x8F5F, 0xCEDF, 0x4EA4, 0xCEE0, 0x50D1, - 0xCEE1, 0x54AC, 0xCEE2, 0x55AC, 0xCEE3, 0x5B0C, 0xCEE4, 0x5DA0, 0xCEE5, 0x5DE7, 0xCEE6, 0x652A, 0xCEE7, 0x654E, 0xCEE8, 0x6821, - 0xCEE9, 0x6A4B, 0xCEEA, 0x72E1, 0xCEEB, 0x768E, 0xCEEC, 0x77EF, 0xCEED, 0x7D5E, 0xCEEE, 0x7FF9, 0xCEEF, 0x81A0, 0xCEF0, 0x854E, - 0xCEF1, 0x86DF, 0xCEF2, 0x8F03, 0xCEF3, 0x8F4E, 0xCEF4, 0x90CA, 0xCEF5, 0x9903, 0xCEF6, 0x9A55, 0xCEF7, 0x9BAB, 0xCEF8, 0x4E18, - 0xCEF9, 0x4E45, 0xCEFA, 0x4E5D, 0xCEFB, 0x4EC7, 0xCEFC, 0x4FF1, 0xCEFD, 0x5177, 0xCEFE, 0x52FE, 0xCFA1, 0x5340, 0xCFA2, 0x53E3, - 0xCFA3, 0x53E5, 0xCFA4, 0x548E, 0xCFA5, 0x5614, 0xCFA6, 0x5775, 0xCFA7, 0x57A2, 0xCFA8, 0x5BC7, 0xCFA9, 0x5D87, 0xCFAA, 0x5ED0, - 0xCFAB, 0x61FC, 0xCFAC, 0x62D8, 0xCFAD, 0x6551, 0xCFAE, 0x67B8, 0xCFAF, 0x67E9, 0xCFB0, 0x69CB, 0xCFB1, 0x6B50, 0xCFB2, 0x6BC6, - 0xCFB3, 0x6BEC, 0xCFB4, 0x6C42, 0xCFB5, 0x6E9D, 0xCFB6, 0x7078, 0xCFB7, 0x72D7, 0xCFB8, 0x7396, 0xCFB9, 0x7403, 0xCFBA, 0x77BF, - 0xCFBB, 0x77E9, 0xCFBC, 0x7A76, 0xCFBD, 0x7D7F, 0xCFBE, 0x8009, 0xCFBF, 0x81FC, 0xCFC0, 0x8205, 0xCFC1, 0x820A, 0xCFC2, 0x82DF, - 0xCFC3, 0x8862, 0xCFC4, 0x8B33, 0xCFC5, 0x8CFC, 0xCFC6, 0x8EC0, 0xCFC7, 0x9011, 0xCFC8, 0x90B1, 0xCFC9, 0x9264, 0xCFCA, 0x92B6, - 0xCFCB, 0x99D2, 0xCFCC, 0x9A45, 0xCFCD, 0x9CE9, 0xCFCE, 0x9DD7, 0xCFCF, 0x9F9C, 0xCFD0, 0x570B, 0xCFD1, 0x5C40, 0xCFD2, 0x83CA, - 0xCFD3, 0x97A0, 0xCFD4, 0x97AB, 0xCFD5, 0x9EB4, 0xCFD6, 0x541B, 0xCFD7, 0x7A98, 0xCFD8, 0x7FA4, 0xCFD9, 0x88D9, 0xCFDA, 0x8ECD, - 0xCFDB, 0x90E1, 0xCFDC, 0x5800, 0xCFDD, 0x5C48, 0xCFDE, 0x6398, 0xCFDF, 0x7A9F, 0xCFE0, 0x5BAE, 0xCFE1, 0x5F13, 0xCFE2, 0x7A79, - 0xCFE3, 0x7AAE, 0xCFE4, 0x828E, 0xCFE5, 0x8EAC, 0xCFE6, 0x5026, 0xCFE7, 0x5238, 0xCFE8, 0x52F8, 0xCFE9, 0x5377, 0xCFEA, 0x5708, - 0xCFEB, 0x62F3, 0xCFEC, 0x6372, 0xCFED, 0x6B0A, 0xCFEE, 0x6DC3, 0xCFEF, 0x7737, 0xCFF0, 0x53A5, 0xCFF1, 0x7357, 0xCFF2, 0x8568, - 0xCFF3, 0x8E76, 0xCFF4, 0x95D5, 0xCFF5, 0x673A, 0xCFF6, 0x6AC3, 0xCFF7, 0x6F70, 0xCFF8, 0x8A6D, 0xCFF9, 0x8ECC, 0xCFFA, 0x994B, - 0xCFFB, 0xF906, 0xCFFC, 0x6677, 0xCFFD, 0x6B78, 0xCFFE, 0x8CB4, 0xD0A1, 0x9B3C, 0xD0A2, 0xF907, 0xD0A3, 0x53EB, 0xD0A4, 0x572D, - 0xD0A5, 0x594E, 0xD0A6, 0x63C6, 0xD0A7, 0x69FB, 0xD0A8, 0x73EA, 0xD0A9, 0x7845, 0xD0AA, 0x7ABA, 0xD0AB, 0x7AC5, 0xD0AC, 0x7CFE, - 0xD0AD, 0x8475, 0xD0AE, 0x898F, 0xD0AF, 0x8D73, 0xD0B0, 0x9035, 0xD0B1, 0x95A8, 0xD0B2, 0x52FB, 0xD0B3, 0x5747, 0xD0B4, 0x7547, - 0xD0B5, 0x7B60, 0xD0B6, 0x83CC, 0xD0B7, 0x921E, 0xD0B8, 0xF908, 0xD0B9, 0x6A58, 0xD0BA, 0x514B, 0xD0BB, 0x524B, 0xD0BC, 0x5287, - 0xD0BD, 0x621F, 0xD0BE, 0x68D8, 0xD0BF, 0x6975, 0xD0C0, 0x9699, 0xD0C1, 0x50C5, 0xD0C2, 0x52A4, 0xD0C3, 0x52E4, 0xD0C4, 0x61C3, - 0xD0C5, 0x65A4, 0xD0C6, 0x6839, 0xD0C7, 0x69FF, 0xD0C8, 0x747E, 0xD0C9, 0x7B4B, 0xD0CA, 0x82B9, 0xD0CB, 0x83EB, 0xD0CC, 0x89B2, - 0xD0CD, 0x8B39, 0xD0CE, 0x8FD1, 0xD0CF, 0x9949, 0xD0D0, 0xF909, 0xD0D1, 0x4ECA, 0xD0D2, 0x5997, 0xD0D3, 0x64D2, 0xD0D4, 0x6611, - 0xD0D5, 0x6A8E, 0xD0D6, 0x7434, 0xD0D7, 0x7981, 0xD0D8, 0x79BD, 0xD0D9, 0x82A9, 0xD0DA, 0x887E, 0xD0DB, 0x887F, 0xD0DC, 0x895F, - 0xD0DD, 0xF90A, 0xD0DE, 0x9326, 0xD0DF, 0x4F0B, 0xD0E0, 0x53CA, 0xD0E1, 0x6025, 0xD0E2, 0x6271, 0xD0E3, 0x6C72, 0xD0E4, 0x7D1A, - 0xD0E5, 0x7D66, 0xD0E6, 0x4E98, 0xD0E7, 0x5162, 0xD0E8, 0x77DC, 0xD0E9, 0x80AF, 0xD0EA, 0x4F01, 0xD0EB, 0x4F0E, 0xD0EC, 0x5176, - 0xD0ED, 0x5180, 0xD0EE, 0x55DC, 0xD0EF, 0x5668, 0xD0F0, 0x573B, 0xD0F1, 0x57FA, 0xD0F2, 0x57FC, 0xD0F3, 0x5914, 0xD0F4, 0x5947, - 0xD0F5, 0x5993, 0xD0F6, 0x5BC4, 0xD0F7, 0x5C90, 0xD0F8, 0x5D0E, 0xD0F9, 0x5DF1, 0xD0FA, 0x5E7E, 0xD0FB, 0x5FCC, 0xD0FC, 0x6280, - 0xD0FD, 0x65D7, 0xD0FE, 0x65E3, 0xD1A1, 0x671E, 0xD1A2, 0x671F, 0xD1A3, 0x675E, 0xD1A4, 0x68CB, 0xD1A5, 0x68C4, 0xD1A6, 0x6A5F, - 0xD1A7, 0x6B3A, 0xD1A8, 0x6C23, 0xD1A9, 0x6C7D, 0xD1AA, 0x6C82, 0xD1AB, 0x6DC7, 0xD1AC, 0x7398, 0xD1AD, 0x7426, 0xD1AE, 0x742A, - 0xD1AF, 0x7482, 0xD1B0, 0x74A3, 0xD1B1, 0x7578, 0xD1B2, 0x757F, 0xD1B3, 0x7881, 0xD1B4, 0x78EF, 0xD1B5, 0x7941, 0xD1B6, 0x7947, - 0xD1B7, 0x7948, 0xD1B8, 0x797A, 0xD1B9, 0x7B95, 0xD1BA, 0x7D00, 0xD1BB, 0x7DBA, 0xD1BC, 0x7F88, 0xD1BD, 0x8006, 0xD1BE, 0x802D, - 0xD1BF, 0x808C, 0xD1C0, 0x8A18, 0xD1C1, 0x8B4F, 0xD1C2, 0x8C48, 0xD1C3, 0x8D77, 0xD1C4, 0x9321, 0xD1C5, 0x9324, 0xD1C6, 0x98E2, - 0xD1C7, 0x9951, 0xD1C8, 0x9A0E, 0xD1C9, 0x9A0F, 0xD1CA, 0x9A65, 0xD1CB, 0x9E92, 0xD1CC, 0x7DCA, 0xD1CD, 0x4F76, 0xD1CE, 0x5409, - 0xD1CF, 0x62EE, 0xD1D0, 0x6854, 0xD1D1, 0x91D1, 0xD1D2, 0x55AB, 0xD1D3, 0x513A, 0xD1D4, 0xF90B, 0xD1D5, 0xF90C, 0xD1D6, 0x5A1C, - 0xD1D7, 0x61E6, 0xD1D8, 0xF90D, 0xD1D9, 0x62CF, 0xD1DA, 0x62FF, 0xD1DB, 0xF90E, 0xD1DC, 0xF90F, 0xD1DD, 0xF910, 0xD1DE, 0xF911, - 0xD1DF, 0xF912, 0xD1E0, 0xF913, 0xD1E1, 0x90A3, 0xD1E2, 0xF914, 0xD1E3, 0xF915, 0xD1E4, 0xF916, 0xD1E5, 0xF917, 0xD1E6, 0xF918, - 0xD1E7, 0x8AFE, 0xD1E8, 0xF919, 0xD1E9, 0xF91A, 0xD1EA, 0xF91B, 0xD1EB, 0xF91C, 0xD1EC, 0x6696, 0xD1ED, 0xF91D, 0xD1EE, 0x7156, - 0xD1EF, 0xF91E, 0xD1F0, 0xF91F, 0xD1F1, 0x96E3, 0xD1F2, 0xF920, 0xD1F3, 0x634F, 0xD1F4, 0x637A, 0xD1F5, 0x5357, 0xD1F6, 0xF921, - 0xD1F7, 0x678F, 0xD1F8, 0x6960, 0xD1F9, 0x6E73, 0xD1FA, 0xF922, 0xD1FB, 0x7537, 0xD1FC, 0xF923, 0xD1FD, 0xF924, 0xD1FE, 0xF925, - 0xD2A1, 0x7D0D, 0xD2A2, 0xF926, 0xD2A3, 0xF927, 0xD2A4, 0x8872, 0xD2A5, 0x56CA, 0xD2A6, 0x5A18, 0xD2A7, 0xF928, 0xD2A8, 0xF929, - 0xD2A9, 0xF92A, 0xD2AA, 0xF92B, 0xD2AB, 0xF92C, 0xD2AC, 0x4E43, 0xD2AD, 0xF92D, 0xD2AE, 0x5167, 0xD2AF, 0x5948, 0xD2B0, 0x67F0, - 0xD2B1, 0x8010, 0xD2B2, 0xF92E, 0xD2B3, 0x5973, 0xD2B4, 0x5E74, 0xD2B5, 0x649A, 0xD2B6, 0x79CA, 0xD2B7, 0x5FF5, 0xD2B8, 0x606C, - 0xD2B9, 0x62C8, 0xD2BA, 0x637B, 0xD2BB, 0x5BE7, 0xD2BC, 0x5BD7, 0xD2BD, 0x52AA, 0xD2BE, 0xF92F, 0xD2BF, 0x5974, 0xD2C0, 0x5F29, - 0xD2C1, 0x6012, 0xD2C2, 0xF930, 0xD2C3, 0xF931, 0xD2C4, 0xF932, 0xD2C5, 0x7459, 0xD2C6, 0xF933, 0xD2C7, 0xF934, 0xD2C8, 0xF935, - 0xD2C9, 0xF936, 0xD2CA, 0xF937, 0xD2CB, 0xF938, 0xD2CC, 0x99D1, 0xD2CD, 0xF939, 0xD2CE, 0xF93A, 0xD2CF, 0xF93B, 0xD2D0, 0xF93C, - 0xD2D1, 0xF93D, 0xD2D2, 0xF93E, 0xD2D3, 0xF93F, 0xD2D4, 0xF940, 0xD2D5, 0xF941, 0xD2D6, 0xF942, 0xD2D7, 0xF943, 0xD2D8, 0x6FC3, - 0xD2D9, 0xF944, 0xD2DA, 0xF945, 0xD2DB, 0x81BF, 0xD2DC, 0x8FB2, 0xD2DD, 0x60F1, 0xD2DE, 0xF946, 0xD2DF, 0xF947, 0xD2E0, 0x8166, - 0xD2E1, 0xF948, 0xD2E2, 0xF949, 0xD2E3, 0x5C3F, 0xD2E4, 0xF94A, 0xD2E5, 0xF94B, 0xD2E6, 0xF94C, 0xD2E7, 0xF94D, 0xD2E8, 0xF94E, - 0xD2E9, 0xF94F, 0xD2EA, 0xF950, 0xD2EB, 0xF951, 0xD2EC, 0x5AE9, 0xD2ED, 0x8A25, 0xD2EE, 0x677B, 0xD2EF, 0x7D10, 0xD2F0, 0xF952, - 0xD2F1, 0xF953, 0xD2F2, 0xF954, 0xD2F3, 0xF955, 0xD2F4, 0xF956, 0xD2F5, 0xF957, 0xD2F6, 0x80FD, 0xD2F7, 0xF958, 0xD2F8, 0xF959, - 0xD2F9, 0x5C3C, 0xD2FA, 0x6CE5, 0xD2FB, 0x533F, 0xD2FC, 0x6EBA, 0xD2FD, 0x591A, 0xD2FE, 0x8336, 0xD3A1, 0x4E39, 0xD3A2, 0x4EB6, - 0xD3A3, 0x4F46, 0xD3A4, 0x55AE, 0xD3A5, 0x5718, 0xD3A6, 0x58C7, 0xD3A7, 0x5F56, 0xD3A8, 0x65B7, 0xD3A9, 0x65E6, 0xD3AA, 0x6A80, - 0xD3AB, 0x6BB5, 0xD3AC, 0x6E4D, 0xD3AD, 0x77ED, 0xD3AE, 0x7AEF, 0xD3AF, 0x7C1E, 0xD3B0, 0x7DDE, 0xD3B1, 0x86CB, 0xD3B2, 0x8892, - 0xD3B3, 0x9132, 0xD3B4, 0x935B, 0xD3B5, 0x64BB, 0xD3B6, 0x6FBE, 0xD3B7, 0x737A, 0xD3B8, 0x75B8, 0xD3B9, 0x9054, 0xD3BA, 0x5556, - 0xD3BB, 0x574D, 0xD3BC, 0x61BA, 0xD3BD, 0x64D4, 0xD3BE, 0x66C7, 0xD3BF, 0x6DE1, 0xD3C0, 0x6E5B, 0xD3C1, 0x6F6D, 0xD3C2, 0x6FB9, - 0xD3C3, 0x75F0, 0xD3C4, 0x8043, 0xD3C5, 0x81BD, 0xD3C6, 0x8541, 0xD3C7, 0x8983, 0xD3C8, 0x8AC7, 0xD3C9, 0x8B5A, 0xD3CA, 0x931F, - 0xD3CB, 0x6C93, 0xD3CC, 0x7553, 0xD3CD, 0x7B54, 0xD3CE, 0x8E0F, 0xD3CF, 0x905D, 0xD3D0, 0x5510, 0xD3D1, 0x5802, 0xD3D2, 0x5858, - 0xD3D3, 0x5E62, 0xD3D4, 0x6207, 0xD3D5, 0x649E, 0xD3D6, 0x68E0, 0xD3D7, 0x7576, 0xD3D8, 0x7CD6, 0xD3D9, 0x87B3, 0xD3DA, 0x9EE8, - 0xD3DB, 0x4EE3, 0xD3DC, 0x5788, 0xD3DD, 0x576E, 0xD3DE, 0x5927, 0xD3DF, 0x5C0D, 0xD3E0, 0x5CB1, 0xD3E1, 0x5E36, 0xD3E2, 0x5F85, - 0xD3E3, 0x6234, 0xD3E4, 0x64E1, 0xD3E5, 0x73B3, 0xD3E6, 0x81FA, 0xD3E7, 0x888B, 0xD3E8, 0x8CB8, 0xD3E9, 0x968A, 0xD3EA, 0x9EDB, - 0xD3EB, 0x5B85, 0xD3EC, 0x5FB7, 0xD3ED, 0x60B3, 0xD3EE, 0x5012, 0xD3EF, 0x5200, 0xD3F0, 0x5230, 0xD3F1, 0x5716, 0xD3F2, 0x5835, - 0xD3F3, 0x5857, 0xD3F4, 0x5C0E, 0xD3F5, 0x5C60, 0xD3F6, 0x5CF6, 0xD3F7, 0x5D8B, 0xD3F8, 0x5EA6, 0xD3F9, 0x5F92, 0xD3FA, 0x60BC, - 0xD3FB, 0x6311, 0xD3FC, 0x6389, 0xD3FD, 0x6417, 0xD3FE, 0x6843, 0xD4A1, 0x68F9, 0xD4A2, 0x6AC2, 0xD4A3, 0x6DD8, 0xD4A4, 0x6E21, - 0xD4A5, 0x6ED4, 0xD4A6, 0x6FE4, 0xD4A7, 0x71FE, 0xD4A8, 0x76DC, 0xD4A9, 0x7779, 0xD4AA, 0x79B1, 0xD4AB, 0x7A3B, 0xD4AC, 0x8404, - 0xD4AD, 0x89A9, 0xD4AE, 0x8CED, 0xD4AF, 0x8DF3, 0xD4B0, 0x8E48, 0xD4B1, 0x9003, 0xD4B2, 0x9014, 0xD4B3, 0x9053, 0xD4B4, 0x90FD, - 0xD4B5, 0x934D, 0xD4B6, 0x9676, 0xD4B7, 0x97DC, 0xD4B8, 0x6BD2, 0xD4B9, 0x7006, 0xD4BA, 0x7258, 0xD4BB, 0x72A2, 0xD4BC, 0x7368, - 0xD4BD, 0x7763, 0xD4BE, 0x79BF, 0xD4BF, 0x7BE4, 0xD4C0, 0x7E9B, 0xD4C1, 0x8B80, 0xD4C2, 0x58A9, 0xD4C3, 0x60C7, 0xD4C4, 0x6566, - 0xD4C5, 0x65FD, 0xD4C6, 0x66BE, 0xD4C7, 0x6C8C, 0xD4C8, 0x711E, 0xD4C9, 0x71C9, 0xD4CA, 0x8C5A, 0xD4CB, 0x9813, 0xD4CC, 0x4E6D, - 0xD4CD, 0x7A81, 0xD4CE, 0x4EDD, 0xD4CF, 0x51AC, 0xD4D0, 0x51CD, 0xD4D1, 0x52D5, 0xD4D2, 0x540C, 0xD4D3, 0x61A7, 0xD4D4, 0x6771, - 0xD4D5, 0x6850, 0xD4D6, 0x68DF, 0xD4D7, 0x6D1E, 0xD4D8, 0x6F7C, 0xD4D9, 0x75BC, 0xD4DA, 0x77B3, 0xD4DB, 0x7AE5, 0xD4DC, 0x80F4, - 0xD4DD, 0x8463, 0xD4DE, 0x9285, 0xD4DF, 0x515C, 0xD4E0, 0x6597, 0xD4E1, 0x675C, 0xD4E2, 0x6793, 0xD4E3, 0x75D8, 0xD4E4, 0x7AC7, - 0xD4E5, 0x8373, 0xD4E6, 0xF95A, 0xD4E7, 0x8C46, 0xD4E8, 0x9017, 0xD4E9, 0x982D, 0xD4EA, 0x5C6F, 0xD4EB, 0x81C0, 0xD4EC, 0x829A, - 0xD4ED, 0x9041, 0xD4EE, 0x906F, 0xD4EF, 0x920D, 0xD4F0, 0x5F97, 0xD4F1, 0x5D9D, 0xD4F2, 0x6A59, 0xD4F3, 0x71C8, 0xD4F4, 0x767B, - 0xD4F5, 0x7B49, 0xD4F6, 0x85E4, 0xD4F7, 0x8B04, 0xD4F8, 0x9127, 0xD4F9, 0x9A30, 0xD4FA, 0x5587, 0xD4FB, 0x61F6, 0xD4FC, 0xF95B, - 0xD4FD, 0x7669, 0xD4FE, 0x7F85, 0xD5A1, 0x863F, 0xD5A2, 0x87BA, 0xD5A3, 0x88F8, 0xD5A4, 0x908F, 0xD5A5, 0xF95C, 0xD5A6, 0x6D1B, - 0xD5A7, 0x70D9, 0xD5A8, 0x73DE, 0xD5A9, 0x7D61, 0xD5AA, 0x843D, 0xD5AB, 0xF95D, 0xD5AC, 0x916A, 0xD5AD, 0x99F1, 0xD5AE, 0xF95E, - 0xD5AF, 0x4E82, 0xD5B0, 0x5375, 0xD5B1, 0x6B04, 0xD5B2, 0x6B12, 0xD5B3, 0x703E, 0xD5B4, 0x721B, 0xD5B5, 0x862D, 0xD5B6, 0x9E1E, - 0xD5B7, 0x524C, 0xD5B8, 0x8FA3, 0xD5B9, 0x5D50, 0xD5BA, 0x64E5, 0xD5BB, 0x652C, 0xD5BC, 0x6B16, 0xD5BD, 0x6FEB, 0xD5BE, 0x7C43, - 0xD5BF, 0x7E9C, 0xD5C0, 0x85CD, 0xD5C1, 0x8964, 0xD5C2, 0x89BD, 0xD5C3, 0x62C9, 0xD5C4, 0x81D8, 0xD5C5, 0x881F, 0xD5C6, 0x5ECA, - 0xD5C7, 0x6717, 0xD5C8, 0x6D6A, 0xD5C9, 0x72FC, 0xD5CA, 0x7405, 0xD5CB, 0x746F, 0xD5CC, 0x8782, 0xD5CD, 0x90DE, 0xD5CE, 0x4F86, - 0xD5CF, 0x5D0D, 0xD5D0, 0x5FA0, 0xD5D1, 0x840A, 0xD5D2, 0x51B7, 0xD5D3, 0x63A0, 0xD5D4, 0x7565, 0xD5D5, 0x4EAE, 0xD5D6, 0x5006, - 0xD5D7, 0x5169, 0xD5D8, 0x51C9, 0xD5D9, 0x6881, 0xD5DA, 0x6A11, 0xD5DB, 0x7CAE, 0xD5DC, 0x7CB1, 0xD5DD, 0x7CE7, 0xD5DE, 0x826F, - 0xD5DF, 0x8AD2, 0xD5E0, 0x8F1B, 0xD5E1, 0x91CF, 0xD5E2, 0x4FB6, 0xD5E3, 0x5137, 0xD5E4, 0x52F5, 0xD5E5, 0x5442, 0xD5E6, 0x5EEC, - 0xD5E7, 0x616E, 0xD5E8, 0x623E, 0xD5E9, 0x65C5, 0xD5EA, 0x6ADA, 0xD5EB, 0x6FFE, 0xD5EC, 0x792A, 0xD5ED, 0x85DC, 0xD5EE, 0x8823, - 0xD5EF, 0x95AD, 0xD5F0, 0x9A62, 0xD5F1, 0x9A6A, 0xD5F2, 0x9E97, 0xD5F3, 0x9ECE, 0xD5F4, 0x529B, 0xD5F5, 0x66C6, 0xD5F6, 0x6B77, - 0xD5F7, 0x701D, 0xD5F8, 0x792B, 0xD5F9, 0x8F62, 0xD5FA, 0x9742, 0xD5FB, 0x6190, 0xD5FC, 0x6200, 0xD5FD, 0x6523, 0xD5FE, 0x6F23, - 0xD6A1, 0x7149, 0xD6A2, 0x7489, 0xD6A3, 0x7DF4, 0xD6A4, 0x806F, 0xD6A5, 0x84EE, 0xD6A6, 0x8F26, 0xD6A7, 0x9023, 0xD6A8, 0x934A, - 0xD6A9, 0x51BD, 0xD6AA, 0x5217, 0xD6AB, 0x52A3, 0xD6AC, 0x6D0C, 0xD6AD, 0x70C8, 0xD6AE, 0x88C2, 0xD6AF, 0x5EC9, 0xD6B0, 0x6582, - 0xD6B1, 0x6BAE, 0xD6B2, 0x6FC2, 0xD6B3, 0x7C3E, 0xD6B4, 0x7375, 0xD6B5, 0x4EE4, 0xD6B6, 0x4F36, 0xD6B7, 0x56F9, 0xD6B8, 0xF95F, - 0xD6B9, 0x5CBA, 0xD6BA, 0x5DBA, 0xD6BB, 0x601C, 0xD6BC, 0x73B2, 0xD6BD, 0x7B2D, 0xD6BE, 0x7F9A, 0xD6BF, 0x7FCE, 0xD6C0, 0x8046, - 0xD6C1, 0x901E, 0xD6C2, 0x9234, 0xD6C3, 0x96F6, 0xD6C4, 0x9748, 0xD6C5, 0x9818, 0xD6C6, 0x9F61, 0xD6C7, 0x4F8B, 0xD6C8, 0x6FA7, - 0xD6C9, 0x79AE, 0xD6CA, 0x91B4, 0xD6CB, 0x96B7, 0xD6CC, 0x52DE, 0xD6CD, 0xF960, 0xD6CE, 0x6488, 0xD6CF, 0x64C4, 0xD6D0, 0x6AD3, - 0xD6D1, 0x6F5E, 0xD6D2, 0x7018, 0xD6D3, 0x7210, 0xD6D4, 0x76E7, 0xD6D5, 0x8001, 0xD6D6, 0x8606, 0xD6D7, 0x865C, 0xD6D8, 0x8DEF, - 0xD6D9, 0x8F05, 0xD6DA, 0x9732, 0xD6DB, 0x9B6F, 0xD6DC, 0x9DFA, 0xD6DD, 0x9E75, 0xD6DE, 0x788C, 0xD6DF, 0x797F, 0xD6E0, 0x7DA0, - 0xD6E1, 0x83C9, 0xD6E2, 0x9304, 0xD6E3, 0x9E7F, 0xD6E4, 0x9E93, 0xD6E5, 0x8AD6, 0xD6E6, 0x58DF, 0xD6E7, 0x5F04, 0xD6E8, 0x6727, - 0xD6E9, 0x7027, 0xD6EA, 0x74CF, 0xD6EB, 0x7C60, 0xD6EC, 0x807E, 0xD6ED, 0x5121, 0xD6EE, 0x7028, 0xD6EF, 0x7262, 0xD6F0, 0x78CA, - 0xD6F1, 0x8CC2, 0xD6F2, 0x8CDA, 0xD6F3, 0x8CF4, 0xD6F4, 0x96F7, 0xD6F5, 0x4E86, 0xD6F6, 0x50DA, 0xD6F7, 0x5BEE, 0xD6F8, 0x5ED6, - 0xD6F9, 0x6599, 0xD6FA, 0x71CE, 0xD6FB, 0x7642, 0xD6FC, 0x77AD, 0xD6FD, 0x804A, 0xD6FE, 0x84FC, 0xD7A1, 0x907C, 0xD7A2, 0x9B27, - 0xD7A3, 0x9F8D, 0xD7A4, 0x58D8, 0xD7A5, 0x5A41, 0xD7A6, 0x5C62, 0xD7A7, 0x6A13, 0xD7A8, 0x6DDA, 0xD7A9, 0x6F0F, 0xD7AA, 0x763B, - 0xD7AB, 0x7D2F, 0xD7AC, 0x7E37, 0xD7AD, 0x851E, 0xD7AE, 0x8938, 0xD7AF, 0x93E4, 0xD7B0, 0x964B, 0xD7B1, 0x5289, 0xD7B2, 0x65D2, - 0xD7B3, 0x67F3, 0xD7B4, 0x69B4, 0xD7B5, 0x6D41, 0xD7B6, 0x6E9C, 0xD7B7, 0x700F, 0xD7B8, 0x7409, 0xD7B9, 0x7460, 0xD7BA, 0x7559, - 0xD7BB, 0x7624, 0xD7BC, 0x786B, 0xD7BD, 0x8B2C, 0xD7BE, 0x985E, 0xD7BF, 0x516D, 0xD7C0, 0x622E, 0xD7C1, 0x9678, 0xD7C2, 0x4F96, - 0xD7C3, 0x502B, 0xD7C4, 0x5D19, 0xD7C5, 0x6DEA, 0xD7C6, 0x7DB8, 0xD7C7, 0x8F2A, 0xD7C8, 0x5F8B, 0xD7C9, 0x6144, 0xD7CA, 0x6817, - 0xD7CB, 0xF961, 0xD7CC, 0x9686, 0xD7CD, 0x52D2, 0xD7CE, 0x808B, 0xD7CF, 0x51DC, 0xD7D0, 0x51CC, 0xD7D1, 0x695E, 0xD7D2, 0x7A1C, - 0xD7D3, 0x7DBE, 0xD7D4, 0x83F1, 0xD7D5, 0x9675, 0xD7D6, 0x4FDA, 0xD7D7, 0x5229, 0xD7D8, 0x5398, 0xD7D9, 0x540F, 0xD7DA, 0x550E, - 0xD7DB, 0x5C65, 0xD7DC, 0x60A7, 0xD7DD, 0x674E, 0xD7DE, 0x68A8, 0xD7DF, 0x6D6C, 0xD7E0, 0x7281, 0xD7E1, 0x72F8, 0xD7E2, 0x7406, - 0xD7E3, 0x7483, 0xD7E4, 0xF962, 0xD7E5, 0x75E2, 0xD7E6, 0x7C6C, 0xD7E7, 0x7F79, 0xD7E8, 0x7FB8, 0xD7E9, 0x8389, 0xD7EA, 0x88CF, - 0xD7EB, 0x88E1, 0xD7EC, 0x91CC, 0xD7ED, 0x91D0, 0xD7EE, 0x96E2, 0xD7EF, 0x9BC9, 0xD7F0, 0x541D, 0xD7F1, 0x6F7E, 0xD7F2, 0x71D0, - 0xD7F3, 0x7498, 0xD7F4, 0x85FA, 0xD7F5, 0x8EAA, 0xD7F6, 0x96A3, 0xD7F7, 0x9C57, 0xD7F8, 0x9E9F, 0xD7F9, 0x6797, 0xD7FA, 0x6DCB, - 0xD7FB, 0x7433, 0xD7FC, 0x81E8, 0xD7FD, 0x9716, 0xD7FE, 0x782C, 0xD8A1, 0x7ACB, 0xD8A2, 0x7B20, 0xD8A3, 0x7C92, 0xD8A4, 0x6469, - 0xD8A5, 0x746A, 0xD8A6, 0x75F2, 0xD8A7, 0x78BC, 0xD8A8, 0x78E8, 0xD8A9, 0x99AC, 0xD8AA, 0x9B54, 0xD8AB, 0x9EBB, 0xD8AC, 0x5BDE, - 0xD8AD, 0x5E55, 0xD8AE, 0x6F20, 0xD8AF, 0x819C, 0xD8B0, 0x83AB, 0xD8B1, 0x9088, 0xD8B2, 0x4E07, 0xD8B3, 0x534D, 0xD8B4, 0x5A29, - 0xD8B5, 0x5DD2, 0xD8B6, 0x5F4E, 0xD8B7, 0x6162, 0xD8B8, 0x633D, 0xD8B9, 0x6669, 0xD8BA, 0x66FC, 0xD8BB, 0x6EFF, 0xD8BC, 0x6F2B, - 0xD8BD, 0x7063, 0xD8BE, 0x779E, 0xD8BF, 0x842C, 0xD8C0, 0x8513, 0xD8C1, 0x883B, 0xD8C2, 0x8F13, 0xD8C3, 0x9945, 0xD8C4, 0x9C3B, - 0xD8C5, 0x551C, 0xD8C6, 0x62B9, 0xD8C7, 0x672B, 0xD8C8, 0x6CAB, 0xD8C9, 0x8309, 0xD8CA, 0x896A, 0xD8CB, 0x977A, 0xD8CC, 0x4EA1, - 0xD8CD, 0x5984, 0xD8CE, 0x5FD8, 0xD8CF, 0x5FD9, 0xD8D0, 0x671B, 0xD8D1, 0x7DB2, 0xD8D2, 0x7F54, 0xD8D3, 0x8292, 0xD8D4, 0x832B, - 0xD8D5, 0x83BD, 0xD8D6, 0x8F1E, 0xD8D7, 0x9099, 0xD8D8, 0x57CB, 0xD8D9, 0x59B9, 0xD8DA, 0x5A92, 0xD8DB, 0x5BD0, 0xD8DC, 0x6627, - 0xD8DD, 0x679A, 0xD8DE, 0x6885, 0xD8DF, 0x6BCF, 0xD8E0, 0x7164, 0xD8E1, 0x7F75, 0xD8E2, 0x8CB7, 0xD8E3, 0x8CE3, 0xD8E4, 0x9081, - 0xD8E5, 0x9B45, 0xD8E6, 0x8108, 0xD8E7, 0x8C8A, 0xD8E8, 0x964C, 0xD8E9, 0x9A40, 0xD8EA, 0x9EA5, 0xD8EB, 0x5B5F, 0xD8EC, 0x6C13, - 0xD8ED, 0x731B, 0xD8EE, 0x76F2, 0xD8EF, 0x76DF, 0xD8F0, 0x840C, 0xD8F1, 0x51AA, 0xD8F2, 0x8993, 0xD8F3, 0x514D, 0xD8F4, 0x5195, - 0xD8F5, 0x52C9, 0xD8F6, 0x68C9, 0xD8F7, 0x6C94, 0xD8F8, 0x7704, 0xD8F9, 0x7720, 0xD8FA, 0x7DBF, 0xD8FB, 0x7DEC, 0xD8FC, 0x9762, - 0xD8FD, 0x9EB5, 0xD8FE, 0x6EC5, 0xD9A1, 0x8511, 0xD9A2, 0x51A5, 0xD9A3, 0x540D, 0xD9A4, 0x547D, 0xD9A5, 0x660E, 0xD9A6, 0x669D, - 0xD9A7, 0x6927, 0xD9A8, 0x6E9F, 0xD9A9, 0x76BF, 0xD9AA, 0x7791, 0xD9AB, 0x8317, 0xD9AC, 0x84C2, 0xD9AD, 0x879F, 0xD9AE, 0x9169, - 0xD9AF, 0x9298, 0xD9B0, 0x9CF4, 0xD9B1, 0x8882, 0xD9B2, 0x4FAE, 0xD9B3, 0x5192, 0xD9B4, 0x52DF, 0xD9B5, 0x59C6, 0xD9B6, 0x5E3D, - 0xD9B7, 0x6155, 0xD9B8, 0x6478, 0xD9B9, 0x6479, 0xD9BA, 0x66AE, 0xD9BB, 0x67D0, 0xD9BC, 0x6A21, 0xD9BD, 0x6BCD, 0xD9BE, 0x6BDB, - 0xD9BF, 0x725F, 0xD9C0, 0x7261, 0xD9C1, 0x7441, 0xD9C2, 0x7738, 0xD9C3, 0x77DB, 0xD9C4, 0x8017, 0xD9C5, 0x82BC, 0xD9C6, 0x8305, - 0xD9C7, 0x8B00, 0xD9C8, 0x8B28, 0xD9C9, 0x8C8C, 0xD9CA, 0x6728, 0xD9CB, 0x6C90, 0xD9CC, 0x7267, 0xD9CD, 0x76EE, 0xD9CE, 0x7766, - 0xD9CF, 0x7A46, 0xD9D0, 0x9DA9, 0xD9D1, 0x6B7F, 0xD9D2, 0x6C92, 0xD9D3, 0x5922, 0xD9D4, 0x6726, 0xD9D5, 0x8499, 0xD9D6, 0x536F, - 0xD9D7, 0x5893, 0xD9D8, 0x5999, 0xD9D9, 0x5EDF, 0xD9DA, 0x63CF, 0xD9DB, 0x6634, 0xD9DC, 0x6773, 0xD9DD, 0x6E3A, 0xD9DE, 0x732B, - 0xD9DF, 0x7AD7, 0xD9E0, 0x82D7, 0xD9E1, 0x9328, 0xD9E2, 0x52D9, 0xD9E3, 0x5DEB, 0xD9E4, 0x61AE, 0xD9E5, 0x61CB, 0xD9E6, 0x620A, - 0xD9E7, 0x62C7, 0xD9E8, 0x64AB, 0xD9E9, 0x65E0, 0xD9EA, 0x6959, 0xD9EB, 0x6B66, 0xD9EC, 0x6BCB, 0xD9ED, 0x7121, 0xD9EE, 0x73F7, - 0xD9EF, 0x755D, 0xD9F0, 0x7E46, 0xD9F1, 0x821E, 0xD9F2, 0x8302, 0xD9F3, 0x856A, 0xD9F4, 0x8AA3, 0xD9F5, 0x8CBF, 0xD9F6, 0x9727, - 0xD9F7, 0x9D61, 0xD9F8, 0x58A8, 0xD9F9, 0x9ED8, 0xD9FA, 0x5011, 0xD9FB, 0x520E, 0xD9FC, 0x543B, 0xD9FD, 0x554F, 0xD9FE, 0x6587, - 0xDAA1, 0x6C76, 0xDAA2, 0x7D0A, 0xDAA3, 0x7D0B, 0xDAA4, 0x805E, 0xDAA5, 0x868A, 0xDAA6, 0x9580, 0xDAA7, 0x96EF, 0xDAA8, 0x52FF, - 0xDAA9, 0x6C95, 0xDAAA, 0x7269, 0xDAAB, 0x5473, 0xDAAC, 0x5A9A, 0xDAAD, 0x5C3E, 0xDAAE, 0x5D4B, 0xDAAF, 0x5F4C, 0xDAB0, 0x5FAE, - 0xDAB1, 0x672A, 0xDAB2, 0x68B6, 0xDAB3, 0x6963, 0xDAB4, 0x6E3C, 0xDAB5, 0x6E44, 0xDAB6, 0x7709, 0xDAB7, 0x7C73, 0xDAB8, 0x7F8E, - 0xDAB9, 0x8587, 0xDABA, 0x8B0E, 0xDABB, 0x8FF7, 0xDABC, 0x9761, 0xDABD, 0x9EF4, 0xDABE, 0x5CB7, 0xDABF, 0x60B6, 0xDAC0, 0x610D, - 0xDAC1, 0x61AB, 0xDAC2, 0x654F, 0xDAC3, 0x65FB, 0xDAC4, 0x65FC, 0xDAC5, 0x6C11, 0xDAC6, 0x6CEF, 0xDAC7, 0x739F, 0xDAC8, 0x73C9, - 0xDAC9, 0x7DE1, 0xDACA, 0x9594, 0xDACB, 0x5BC6, 0xDACC, 0x871C, 0xDACD, 0x8B10, 0xDACE, 0x525D, 0xDACF, 0x535A, 0xDAD0, 0x62CD, - 0xDAD1, 0x640F, 0xDAD2, 0x64B2, 0xDAD3, 0x6734, 0xDAD4, 0x6A38, 0xDAD5, 0x6CCA, 0xDAD6, 0x73C0, 0xDAD7, 0x749E, 0xDAD8, 0x7B94, - 0xDAD9, 0x7C95, 0xDADA, 0x7E1B, 0xDADB, 0x818A, 0xDADC, 0x8236, 0xDADD, 0x8584, 0xDADE, 0x8FEB, 0xDADF, 0x96F9, 0xDAE0, 0x99C1, - 0xDAE1, 0x4F34, 0xDAE2, 0x534A, 0xDAE3, 0x53CD, 0xDAE4, 0x53DB, 0xDAE5, 0x62CC, 0xDAE6, 0x642C, 0xDAE7, 0x6500, 0xDAE8, 0x6591, - 0xDAE9, 0x69C3, 0xDAEA, 0x6CEE, 0xDAEB, 0x6F58, 0xDAEC, 0x73ED, 0xDAED, 0x7554, 0xDAEE, 0x7622, 0xDAEF, 0x76E4, 0xDAF0, 0x76FC, - 0xDAF1, 0x78D0, 0xDAF2, 0x78FB, 0xDAF3, 0x792C, 0xDAF4, 0x7D46, 0xDAF5, 0x822C, 0xDAF6, 0x87E0, 0xDAF7, 0x8FD4, 0xDAF8, 0x9812, - 0xDAF9, 0x98EF, 0xDAFA, 0x52C3, 0xDAFB, 0x62D4, 0xDAFC, 0x64A5, 0xDAFD, 0x6E24, 0xDAFE, 0x6F51, 0xDBA1, 0x767C, 0xDBA2, 0x8DCB, - 0xDBA3, 0x91B1, 0xDBA4, 0x9262, 0xDBA5, 0x9AEE, 0xDBA6, 0x9B43, 0xDBA7, 0x5023, 0xDBA8, 0x508D, 0xDBA9, 0x574A, 0xDBAA, 0x59A8, - 0xDBAB, 0x5C28, 0xDBAC, 0x5E47, 0xDBAD, 0x5F77, 0xDBAE, 0x623F, 0xDBAF, 0x653E, 0xDBB0, 0x65B9, 0xDBB1, 0x65C1, 0xDBB2, 0x6609, - 0xDBB3, 0x678B, 0xDBB4, 0x699C, 0xDBB5, 0x6EC2, 0xDBB6, 0x78C5, 0xDBB7, 0x7D21, 0xDBB8, 0x80AA, 0xDBB9, 0x8180, 0xDBBA, 0x822B, - 0xDBBB, 0x82B3, 0xDBBC, 0x84A1, 0xDBBD, 0x868C, 0xDBBE, 0x8A2A, 0xDBBF, 0x8B17, 0xDBC0, 0x90A6, 0xDBC1, 0x9632, 0xDBC2, 0x9F90, - 0xDBC3, 0x500D, 0xDBC4, 0x4FF3, 0xDBC5, 0xF963, 0xDBC6, 0x57F9, 0xDBC7, 0x5F98, 0xDBC8, 0x62DC, 0xDBC9, 0x6392, 0xDBCA, 0x676F, - 0xDBCB, 0x6E43, 0xDBCC, 0x7119, 0xDBCD, 0x76C3, 0xDBCE, 0x80CC, 0xDBCF, 0x80DA, 0xDBD0, 0x88F4, 0xDBD1, 0x88F5, 0xDBD2, 0x8919, - 0xDBD3, 0x8CE0, 0xDBD4, 0x8F29, 0xDBD5, 0x914D, 0xDBD6, 0x966A, 0xDBD7, 0x4F2F, 0xDBD8, 0x4F70, 0xDBD9, 0x5E1B, 0xDBDA, 0x67CF, - 0xDBDB, 0x6822, 0xDBDC, 0x767D, 0xDBDD, 0x767E, 0xDBDE, 0x9B44, 0xDBDF, 0x5E61, 0xDBE0, 0x6A0A, 0xDBE1, 0x7169, 0xDBE2, 0x71D4, - 0xDBE3, 0x756A, 0xDBE4, 0xF964, 0xDBE5, 0x7E41, 0xDBE6, 0x8543, 0xDBE7, 0x85E9, 0xDBE8, 0x98DC, 0xDBE9, 0x4F10, 0xDBEA, 0x7B4F, - 0xDBEB, 0x7F70, 0xDBEC, 0x95A5, 0xDBED, 0x51E1, 0xDBEE, 0x5E06, 0xDBEF, 0x68B5, 0xDBF0, 0x6C3E, 0xDBF1, 0x6C4E, 0xDBF2, 0x6CDB, - 0xDBF3, 0x72AF, 0xDBF4, 0x7BC4, 0xDBF5, 0x8303, 0xDBF6, 0x6CD5, 0xDBF7, 0x743A, 0xDBF8, 0x50FB, 0xDBF9, 0x5288, 0xDBFA, 0x58C1, - 0xDBFB, 0x64D8, 0xDBFC, 0x6A97, 0xDBFD, 0x74A7, 0xDBFE, 0x7656, 0xDCA1, 0x78A7, 0xDCA2, 0x8617, 0xDCA3, 0x95E2, 0xDCA4, 0x9739, - 0xDCA5, 0xF965, 0xDCA6, 0x535E, 0xDCA7, 0x5F01, 0xDCA8, 0x8B8A, 0xDCA9, 0x8FA8, 0xDCAA, 0x8FAF, 0xDCAB, 0x908A, 0xDCAC, 0x5225, - 0xDCAD, 0x77A5, 0xDCAE, 0x9C49, 0xDCAF, 0x9F08, 0xDCB0, 0x4E19, 0xDCB1, 0x5002, 0xDCB2, 0x5175, 0xDCB3, 0x5C5B, 0xDCB4, 0x5E77, - 0xDCB5, 0x661E, 0xDCB6, 0x663A, 0xDCB7, 0x67C4, 0xDCB8, 0x68C5, 0xDCB9, 0x70B3, 0xDCBA, 0x7501, 0xDCBB, 0x75C5, 0xDCBC, 0x79C9, - 0xDCBD, 0x7ADD, 0xDCBE, 0x8F27, 0xDCBF, 0x9920, 0xDCC0, 0x9A08, 0xDCC1, 0x4FDD, 0xDCC2, 0x5821, 0xDCC3, 0x5831, 0xDCC4, 0x5BF6, - 0xDCC5, 0x666E, 0xDCC6, 0x6B65, 0xDCC7, 0x6D11, 0xDCC8, 0x6E7A, 0xDCC9, 0x6F7D, 0xDCCA, 0x73E4, 0xDCCB, 0x752B, 0xDCCC, 0x83E9, - 0xDCCD, 0x88DC, 0xDCCE, 0x8913, 0xDCCF, 0x8B5C, 0xDCD0, 0x8F14, 0xDCD1, 0x4F0F, 0xDCD2, 0x50D5, 0xDCD3, 0x5310, 0xDCD4, 0x535C, - 0xDCD5, 0x5B93, 0xDCD6, 0x5FA9, 0xDCD7, 0x670D, 0xDCD8, 0x798F, 0xDCD9, 0x8179, 0xDCDA, 0x832F, 0xDCDB, 0x8514, 0xDCDC, 0x8907, - 0xDCDD, 0x8986, 0xDCDE, 0x8F39, 0xDCDF, 0x8F3B, 0xDCE0, 0x99A5, 0xDCE1, 0x9C12, 0xDCE2, 0x672C, 0xDCE3, 0x4E76, 0xDCE4, 0x4FF8, - 0xDCE5, 0x5949, 0xDCE6, 0x5C01, 0xDCE7, 0x5CEF, 0xDCE8, 0x5CF0, 0xDCE9, 0x6367, 0xDCEA, 0x68D2, 0xDCEB, 0x70FD, 0xDCEC, 0x71A2, - 0xDCED, 0x742B, 0xDCEE, 0x7E2B, 0xDCEF, 0x84EC, 0xDCF0, 0x8702, 0xDCF1, 0x9022, 0xDCF2, 0x92D2, 0xDCF3, 0x9CF3, 0xDCF4, 0x4E0D, - 0xDCF5, 0x4ED8, 0xDCF6, 0x4FEF, 0xDCF7, 0x5085, 0xDCF8, 0x5256, 0xDCF9, 0x526F, 0xDCFA, 0x5426, 0xDCFB, 0x5490, 0xDCFC, 0x57E0, - 0xDCFD, 0x592B, 0xDCFE, 0x5A66, 0xDDA1, 0x5B5A, 0xDDA2, 0x5B75, 0xDDA3, 0x5BCC, 0xDDA4, 0x5E9C, 0xDDA5, 0xF966, 0xDDA6, 0x6276, - 0xDDA7, 0x6577, 0xDDA8, 0x65A7, 0xDDA9, 0x6D6E, 0xDDAA, 0x6EA5, 0xDDAB, 0x7236, 0xDDAC, 0x7B26, 0xDDAD, 0x7C3F, 0xDDAE, 0x7F36, - 0xDDAF, 0x8150, 0xDDB0, 0x8151, 0xDDB1, 0x819A, 0xDDB2, 0x8240, 0xDDB3, 0x8299, 0xDDB4, 0x83A9, 0xDDB5, 0x8A03, 0xDDB6, 0x8CA0, - 0xDDB7, 0x8CE6, 0xDDB8, 0x8CFB, 0xDDB9, 0x8D74, 0xDDBA, 0x8DBA, 0xDDBB, 0x90E8, 0xDDBC, 0x91DC, 0xDDBD, 0x961C, 0xDDBE, 0x9644, - 0xDDBF, 0x99D9, 0xDDC0, 0x9CE7, 0xDDC1, 0x5317, 0xDDC2, 0x5206, 0xDDC3, 0x5429, 0xDDC4, 0x5674, 0xDDC5, 0x58B3, 0xDDC6, 0x5954, - 0xDDC7, 0x596E, 0xDDC8, 0x5FFF, 0xDDC9, 0x61A4, 0xDDCA, 0x626E, 0xDDCB, 0x6610, 0xDDCC, 0x6C7E, 0xDDCD, 0x711A, 0xDDCE, 0x76C6, - 0xDDCF, 0x7C89, 0xDDD0, 0x7CDE, 0xDDD1, 0x7D1B, 0xDDD2, 0x82AC, 0xDDD3, 0x8CC1, 0xDDD4, 0x96F0, 0xDDD5, 0xF967, 0xDDD6, 0x4F5B, - 0xDDD7, 0x5F17, 0xDDD8, 0x5F7F, 0xDDD9, 0x62C2, 0xDDDA, 0x5D29, 0xDDDB, 0x670B, 0xDDDC, 0x68DA, 0xDDDD, 0x787C, 0xDDDE, 0x7E43, - 0xDDDF, 0x9D6C, 0xDDE0, 0x4E15, 0xDDE1, 0x5099, 0xDDE2, 0x5315, 0xDDE3, 0x532A, 0xDDE4, 0x5351, 0xDDE5, 0x5983, 0xDDE6, 0x5A62, - 0xDDE7, 0x5E87, 0xDDE8, 0x60B2, 0xDDE9, 0x618A, 0xDDEA, 0x6249, 0xDDEB, 0x6279, 0xDDEC, 0x6590, 0xDDED, 0x6787, 0xDDEE, 0x69A7, - 0xDDEF, 0x6BD4, 0xDDF0, 0x6BD6, 0xDDF1, 0x6BD7, 0xDDF2, 0x6BD8, 0xDDF3, 0x6CB8, 0xDDF4, 0xF968, 0xDDF5, 0x7435, 0xDDF6, 0x75FA, - 0xDDF7, 0x7812, 0xDDF8, 0x7891, 0xDDF9, 0x79D5, 0xDDFA, 0x79D8, 0xDDFB, 0x7C83, 0xDDFC, 0x7DCB, 0xDDFD, 0x7FE1, 0xDDFE, 0x80A5, - 0xDEA1, 0x813E, 0xDEA2, 0x81C2, 0xDEA3, 0x83F2, 0xDEA4, 0x871A, 0xDEA5, 0x88E8, 0xDEA6, 0x8AB9, 0xDEA7, 0x8B6C, 0xDEA8, 0x8CBB, - 0xDEA9, 0x9119, 0xDEAA, 0x975E, 0xDEAB, 0x98DB, 0xDEAC, 0x9F3B, 0xDEAD, 0x56AC, 0xDEAE, 0x5B2A, 0xDEAF, 0x5F6C, 0xDEB0, 0x658C, - 0xDEB1, 0x6AB3, 0xDEB2, 0x6BAF, 0xDEB3, 0x6D5C, 0xDEB4, 0x6FF1, 0xDEB5, 0x7015, 0xDEB6, 0x725D, 0xDEB7, 0x73AD, 0xDEB8, 0x8CA7, - 0xDEB9, 0x8CD3, 0xDEBA, 0x983B, 0xDEBB, 0x6191, 0xDEBC, 0x6C37, 0xDEBD, 0x8058, 0xDEBE, 0x9A01, 0xDEBF, 0x4E4D, 0xDEC0, 0x4E8B, - 0xDEC1, 0x4E9B, 0xDEC2, 0x4ED5, 0xDEC3, 0x4F3A, 0xDEC4, 0x4F3C, 0xDEC5, 0x4F7F, 0xDEC6, 0x4FDF, 0xDEC7, 0x50FF, 0xDEC8, 0x53F2, - 0xDEC9, 0x53F8, 0xDECA, 0x5506, 0xDECB, 0x55E3, 0xDECC, 0x56DB, 0xDECD, 0x58EB, 0xDECE, 0x5962, 0xDECF, 0x5A11, 0xDED0, 0x5BEB, - 0xDED1, 0x5BFA, 0xDED2, 0x5C04, 0xDED3, 0x5DF3, 0xDED4, 0x5E2B, 0xDED5, 0x5F99, 0xDED6, 0x601D, 0xDED7, 0x6368, 0xDED8, 0x659C, - 0xDED9, 0x65AF, 0xDEDA, 0x67F6, 0xDEDB, 0x67FB, 0xDEDC, 0x68AD, 0xDEDD, 0x6B7B, 0xDEDE, 0x6C99, 0xDEDF, 0x6CD7, 0xDEE0, 0x6E23, - 0xDEE1, 0x7009, 0xDEE2, 0x7345, 0xDEE3, 0x7802, 0xDEE4, 0x793E, 0xDEE5, 0x7940, 0xDEE6, 0x7960, 0xDEE7, 0x79C1, 0xDEE8, 0x7BE9, - 0xDEE9, 0x7D17, 0xDEEA, 0x7D72, 0xDEEB, 0x8086, 0xDEEC, 0x820D, 0xDEED, 0x838E, 0xDEEE, 0x84D1, 0xDEEF, 0x86C7, 0xDEF0, 0x88DF, - 0xDEF1, 0x8A50, 0xDEF2, 0x8A5E, 0xDEF3, 0x8B1D, 0xDEF4, 0x8CDC, 0xDEF5, 0x8D66, 0xDEF6, 0x8FAD, 0xDEF7, 0x90AA, 0xDEF8, 0x98FC, - 0xDEF9, 0x99DF, 0xDEFA, 0x9E9D, 0xDEFB, 0x524A, 0xDEFC, 0xF969, 0xDEFD, 0x6714, 0xDEFE, 0xF96A, 0xDFA1, 0x5098, 0xDFA2, 0x522A, - 0xDFA3, 0x5C71, 0xDFA4, 0x6563, 0xDFA5, 0x6C55, 0xDFA6, 0x73CA, 0xDFA7, 0x7523, 0xDFA8, 0x759D, 0xDFA9, 0x7B97, 0xDFAA, 0x849C, - 0xDFAB, 0x9178, 0xDFAC, 0x9730, 0xDFAD, 0x4E77, 0xDFAE, 0x6492, 0xDFAF, 0x6BBA, 0xDFB0, 0x715E, 0xDFB1, 0x85A9, 0xDFB2, 0x4E09, - 0xDFB3, 0xF96B, 0xDFB4, 0x6749, 0xDFB5, 0x68EE, 0xDFB6, 0x6E17, 0xDFB7, 0x829F, 0xDFB8, 0x8518, 0xDFB9, 0x886B, 0xDFBA, 0x63F7, - 0xDFBB, 0x6F81, 0xDFBC, 0x9212, 0xDFBD, 0x98AF, 0xDFBE, 0x4E0A, 0xDFBF, 0x50B7, 0xDFC0, 0x50CF, 0xDFC1, 0x511F, 0xDFC2, 0x5546, - 0xDFC3, 0x55AA, 0xDFC4, 0x5617, 0xDFC5, 0x5B40, 0xDFC6, 0x5C19, 0xDFC7, 0x5CE0, 0xDFC8, 0x5E38, 0xDFC9, 0x5E8A, 0xDFCA, 0x5EA0, - 0xDFCB, 0x5EC2, 0xDFCC, 0x60F3, 0xDFCD, 0x6851, 0xDFCE, 0x6A61, 0xDFCF, 0x6E58, 0xDFD0, 0x723D, 0xDFD1, 0x7240, 0xDFD2, 0x72C0, - 0xDFD3, 0x76F8, 0xDFD4, 0x7965, 0xDFD5, 0x7BB1, 0xDFD6, 0x7FD4, 0xDFD7, 0x88F3, 0xDFD8, 0x89F4, 0xDFD9, 0x8A73, 0xDFDA, 0x8C61, - 0xDFDB, 0x8CDE, 0xDFDC, 0x971C, 0xDFDD, 0x585E, 0xDFDE, 0x74BD, 0xDFDF, 0x8CFD, 0xDFE0, 0x55C7, 0xDFE1, 0xF96C, 0xDFE2, 0x7A61, - 0xDFE3, 0x7D22, 0xDFE4, 0x8272, 0xDFE5, 0x7272, 0xDFE6, 0x751F, 0xDFE7, 0x7525, 0xDFE8, 0xF96D, 0xDFE9, 0x7B19, 0xDFEA, 0x5885, - 0xDFEB, 0x58FB, 0xDFEC, 0x5DBC, 0xDFED, 0x5E8F, 0xDFEE, 0x5EB6, 0xDFEF, 0x5F90, 0xDFF0, 0x6055, 0xDFF1, 0x6292, 0xDFF2, 0x637F, - 0xDFF3, 0x654D, 0xDFF4, 0x6691, 0xDFF5, 0x66D9, 0xDFF6, 0x66F8, 0xDFF7, 0x6816, 0xDFF8, 0x68F2, 0xDFF9, 0x7280, 0xDFFA, 0x745E, - 0xDFFB, 0x7B6E, 0xDFFC, 0x7D6E, 0xDFFD, 0x7DD6, 0xDFFE, 0x7F72, 0xE0A1, 0x80E5, 0xE0A2, 0x8212, 0xE0A3, 0x85AF, 0xE0A4, 0x897F, - 0xE0A5, 0x8A93, 0xE0A6, 0x901D, 0xE0A7, 0x92E4, 0xE0A8, 0x9ECD, 0xE0A9, 0x9F20, 0xE0AA, 0x5915, 0xE0AB, 0x596D, 0xE0AC, 0x5E2D, - 0xE0AD, 0x60DC, 0xE0AE, 0x6614, 0xE0AF, 0x6673, 0xE0B0, 0x6790, 0xE0B1, 0x6C50, 0xE0B2, 0x6DC5, 0xE0B3, 0x6F5F, 0xE0B4, 0x77F3, - 0xE0B5, 0x78A9, 0xE0B6, 0x84C6, 0xE0B7, 0x91CB, 0xE0B8, 0x932B, 0xE0B9, 0x4ED9, 0xE0BA, 0x50CA, 0xE0BB, 0x5148, 0xE0BC, 0x5584, - 0xE0BD, 0x5B0B, 0xE0BE, 0x5BA3, 0xE0BF, 0x6247, 0xE0C0, 0x657E, 0xE0C1, 0x65CB, 0xE0C2, 0x6E32, 0xE0C3, 0x717D, 0xE0C4, 0x7401, - 0xE0C5, 0x7444, 0xE0C6, 0x7487, 0xE0C7, 0x74BF, 0xE0C8, 0x766C, 0xE0C9, 0x79AA, 0xE0CA, 0x7DDA, 0xE0CB, 0x7E55, 0xE0CC, 0x7FA8, - 0xE0CD, 0x817A, 0xE0CE, 0x81B3, 0xE0CF, 0x8239, 0xE0D0, 0x861A, 0xE0D1, 0x87EC, 0xE0D2, 0x8A75, 0xE0D3, 0x8DE3, 0xE0D4, 0x9078, - 0xE0D5, 0x9291, 0xE0D6, 0x9425, 0xE0D7, 0x994D, 0xE0D8, 0x9BAE, 0xE0D9, 0x5368, 0xE0DA, 0x5C51, 0xE0DB, 0x6954, 0xE0DC, 0x6CC4, - 0xE0DD, 0x6D29, 0xE0DE, 0x6E2B, 0xE0DF, 0x820C, 0xE0E0, 0x859B, 0xE0E1, 0x893B, 0xE0E2, 0x8A2D, 0xE0E3, 0x8AAA, 0xE0E4, 0x96EA, - 0xE0E5, 0x9F67, 0xE0E6, 0x5261, 0xE0E7, 0x66B9, 0xE0E8, 0x6BB2, 0xE0E9, 0x7E96, 0xE0EA, 0x87FE, 0xE0EB, 0x8D0D, 0xE0EC, 0x9583, - 0xE0ED, 0x965D, 0xE0EE, 0x651D, 0xE0EF, 0x6D89, 0xE0F0, 0x71EE, 0xE0F1, 0xF96E, 0xE0F2, 0x57CE, 0xE0F3, 0x59D3, 0xE0F4, 0x5BAC, - 0xE0F5, 0x6027, 0xE0F6, 0x60FA, 0xE0F7, 0x6210, 0xE0F8, 0x661F, 0xE0F9, 0x665F, 0xE0FA, 0x7329, 0xE0FB, 0x73F9, 0xE0FC, 0x76DB, - 0xE0FD, 0x7701, 0xE0FE, 0x7B6C, 0xE1A1, 0x8056, 0xE1A2, 0x8072, 0xE1A3, 0x8165, 0xE1A4, 0x8AA0, 0xE1A5, 0x9192, 0xE1A6, 0x4E16, - 0xE1A7, 0x52E2, 0xE1A8, 0x6B72, 0xE1A9, 0x6D17, 0xE1AA, 0x7A05, 0xE1AB, 0x7B39, 0xE1AC, 0x7D30, 0xE1AD, 0xF96F, 0xE1AE, 0x8CB0, - 0xE1AF, 0x53EC, 0xE1B0, 0x562F, 0xE1B1, 0x5851, 0xE1B2, 0x5BB5, 0xE1B3, 0x5C0F, 0xE1B4, 0x5C11, 0xE1B5, 0x5DE2, 0xE1B6, 0x6240, - 0xE1B7, 0x6383, 0xE1B8, 0x6414, 0xE1B9, 0x662D, 0xE1BA, 0x68B3, 0xE1BB, 0x6CBC, 0xE1BC, 0x6D88, 0xE1BD, 0x6EAF, 0xE1BE, 0x701F, - 0xE1BF, 0x70A4, 0xE1C0, 0x71D2, 0xE1C1, 0x7526, 0xE1C2, 0x758F, 0xE1C3, 0x758E, 0xE1C4, 0x7619, 0xE1C5, 0x7B11, 0xE1C6, 0x7BE0, - 0xE1C7, 0x7C2B, 0xE1C8, 0x7D20, 0xE1C9, 0x7D39, 0xE1CA, 0x852C, 0xE1CB, 0x856D, 0xE1CC, 0x8607, 0xE1CD, 0x8A34, 0xE1CE, 0x900D, - 0xE1CF, 0x9061, 0xE1D0, 0x90B5, 0xE1D1, 0x92B7, 0xE1D2, 0x97F6, 0xE1D3, 0x9A37, 0xE1D4, 0x4FD7, 0xE1D5, 0x5C6C, 0xE1D6, 0x675F, - 0xE1D7, 0x6D91, 0xE1D8, 0x7C9F, 0xE1D9, 0x7E8C, 0xE1DA, 0x8B16, 0xE1DB, 0x8D16, 0xE1DC, 0x901F, 0xE1DD, 0x5B6B, 0xE1DE, 0x5DFD, - 0xE1DF, 0x640D, 0xE1E0, 0x84C0, 0xE1E1, 0x905C, 0xE1E2, 0x98E1, 0xE1E3, 0x7387, 0xE1E4, 0x5B8B, 0xE1E5, 0x609A, 0xE1E6, 0x677E, - 0xE1E7, 0x6DDE, 0xE1E8, 0x8A1F, 0xE1E9, 0x8AA6, 0xE1EA, 0x9001, 0xE1EB, 0x980C, 0xE1EC, 0x5237, 0xE1ED, 0xF970, 0xE1EE, 0x7051, - 0xE1EF, 0x788E, 0xE1F0, 0x9396, 0xE1F1, 0x8870, 0xE1F2, 0x91D7, 0xE1F3, 0x4FEE, 0xE1F4, 0x53D7, 0xE1F5, 0x55FD, 0xE1F6, 0x56DA, - 0xE1F7, 0x5782, 0xE1F8, 0x58FD, 0xE1F9, 0x5AC2, 0xE1FA, 0x5B88, 0xE1FB, 0x5CAB, 0xE1FC, 0x5CC0, 0xE1FD, 0x5E25, 0xE1FE, 0x6101, - 0xE2A1, 0x620D, 0xE2A2, 0x624B, 0xE2A3, 0x6388, 0xE2A4, 0x641C, 0xE2A5, 0x6536, 0xE2A6, 0x6578, 0xE2A7, 0x6A39, 0xE2A8, 0x6B8A, - 0xE2A9, 0x6C34, 0xE2AA, 0x6D19, 0xE2AB, 0x6F31, 0xE2AC, 0x71E7, 0xE2AD, 0x72E9, 0xE2AE, 0x7378, 0xE2AF, 0x7407, 0xE2B0, 0x74B2, - 0xE2B1, 0x7626, 0xE2B2, 0x7761, 0xE2B3, 0x79C0, 0xE2B4, 0x7A57, 0xE2B5, 0x7AEA, 0xE2B6, 0x7CB9, 0xE2B7, 0x7D8F, 0xE2B8, 0x7DAC, - 0xE2B9, 0x7E61, 0xE2BA, 0x7F9E, 0xE2BB, 0x8129, 0xE2BC, 0x8331, 0xE2BD, 0x8490, 0xE2BE, 0x84DA, 0xE2BF, 0x85EA, 0xE2C0, 0x8896, - 0xE2C1, 0x8AB0, 0xE2C2, 0x8B90, 0xE2C3, 0x8F38, 0xE2C4, 0x9042, 0xE2C5, 0x9083, 0xE2C6, 0x916C, 0xE2C7, 0x9296, 0xE2C8, 0x92B9, - 0xE2C9, 0x968B, 0xE2CA, 0x96A7, 0xE2CB, 0x96A8, 0xE2CC, 0x96D6, 0xE2CD, 0x9700, 0xE2CE, 0x9808, 0xE2CF, 0x9996, 0xE2D0, 0x9AD3, - 0xE2D1, 0x9B1A, 0xE2D2, 0x53D4, 0xE2D3, 0x587E, 0xE2D4, 0x5919, 0xE2D5, 0x5B70, 0xE2D6, 0x5BBF, 0xE2D7, 0x6DD1, 0xE2D8, 0x6F5A, - 0xE2D9, 0x719F, 0xE2DA, 0x7421, 0xE2DB, 0x74B9, 0xE2DC, 0x8085, 0xE2DD, 0x83FD, 0xE2DE, 0x5DE1, 0xE2DF, 0x5F87, 0xE2E0, 0x5FAA, - 0xE2E1, 0x6042, 0xE2E2, 0x65EC, 0xE2E3, 0x6812, 0xE2E4, 0x696F, 0xE2E5, 0x6A53, 0xE2E6, 0x6B89, 0xE2E7, 0x6D35, 0xE2E8, 0x6DF3, - 0xE2E9, 0x73E3, 0xE2EA, 0x76FE, 0xE2EB, 0x77AC, 0xE2EC, 0x7B4D, 0xE2ED, 0x7D14, 0xE2EE, 0x8123, 0xE2EF, 0x821C, 0xE2F0, 0x8340, - 0xE2F1, 0x84F4, 0xE2F2, 0x8563, 0xE2F3, 0x8A62, 0xE2F4, 0x8AC4, 0xE2F5, 0x9187, 0xE2F6, 0x931E, 0xE2F7, 0x9806, 0xE2F8, 0x99B4, - 0xE2F9, 0x620C, 0xE2FA, 0x8853, 0xE2FB, 0x8FF0, 0xE2FC, 0x9265, 0xE2FD, 0x5D07, 0xE2FE, 0x5D27, 0xE3A1, 0x5D69, 0xE3A2, 0x745F, - 0xE3A3, 0x819D, 0xE3A4, 0x8768, 0xE3A5, 0x6FD5, 0xE3A6, 0x62FE, 0xE3A7, 0x7FD2, 0xE3A8, 0x8936, 0xE3A9, 0x8972, 0xE3AA, 0x4E1E, - 0xE3AB, 0x4E58, 0xE3AC, 0x50E7, 0xE3AD, 0x52DD, 0xE3AE, 0x5347, 0xE3AF, 0x627F, 0xE3B0, 0x6607, 0xE3B1, 0x7E69, 0xE3B2, 0x8805, - 0xE3B3, 0x965E, 0xE3B4, 0x4F8D, 0xE3B5, 0x5319, 0xE3B6, 0x5636, 0xE3B7, 0x59CB, 0xE3B8, 0x5AA4, 0xE3B9, 0x5C38, 0xE3BA, 0x5C4E, - 0xE3BB, 0x5C4D, 0xE3BC, 0x5E02, 0xE3BD, 0x5F11, 0xE3BE, 0x6043, 0xE3BF, 0x65BD, 0xE3C0, 0x662F, 0xE3C1, 0x6642, 0xE3C2, 0x67BE, - 0xE3C3, 0x67F4, 0xE3C4, 0x731C, 0xE3C5, 0x77E2, 0xE3C6, 0x793A, 0xE3C7, 0x7FC5, 0xE3C8, 0x8494, 0xE3C9, 0x84CD, 0xE3CA, 0x8996, - 0xE3CB, 0x8A66, 0xE3CC, 0x8A69, 0xE3CD, 0x8AE1, 0xE3CE, 0x8C55, 0xE3CF, 0x8C7A, 0xE3D0, 0x57F4, 0xE3D1, 0x5BD4, 0xE3D2, 0x5F0F, - 0xE3D3, 0x606F, 0xE3D4, 0x62ED, 0xE3D5, 0x690D, 0xE3D6, 0x6B96, 0xE3D7, 0x6E5C, 0xE3D8, 0x7184, 0xE3D9, 0x7BD2, 0xE3DA, 0x8755, - 0xE3DB, 0x8B58, 0xE3DC, 0x8EFE, 0xE3DD, 0x98DF, 0xE3DE, 0x98FE, 0xE3DF, 0x4F38, 0xE3E0, 0x4F81, 0xE3E1, 0x4FE1, 0xE3E2, 0x547B, - 0xE3E3, 0x5A20, 0xE3E4, 0x5BB8, 0xE3E5, 0x613C, 0xE3E6, 0x65B0, 0xE3E7, 0x6668, 0xE3E8, 0x71FC, 0xE3E9, 0x7533, 0xE3EA, 0x795E, - 0xE3EB, 0x7D33, 0xE3EC, 0x814E, 0xE3ED, 0x81E3, 0xE3EE, 0x8398, 0xE3EF, 0x85AA, 0xE3F0, 0x85CE, 0xE3F1, 0x8703, 0xE3F2, 0x8A0A, - 0xE3F3, 0x8EAB, 0xE3F4, 0x8F9B, 0xE3F5, 0xF971, 0xE3F6, 0x8FC5, 0xE3F7, 0x5931, 0xE3F8, 0x5BA4, 0xE3F9, 0x5BE6, 0xE3FA, 0x6089, - 0xE3FB, 0x5BE9, 0xE3FC, 0x5C0B, 0xE3FD, 0x5FC3, 0xE3FE, 0x6C81, 0xE4A1, 0xF972, 0xE4A2, 0x6DF1, 0xE4A3, 0x700B, 0xE4A4, 0x751A, - 0xE4A5, 0x82AF, 0xE4A6, 0x8AF6, 0xE4A7, 0x4EC0, 0xE4A8, 0x5341, 0xE4A9, 0xF973, 0xE4AA, 0x96D9, 0xE4AB, 0x6C0F, 0xE4AC, 0x4E9E, - 0xE4AD, 0x4FC4, 0xE4AE, 0x5152, 0xE4AF, 0x555E, 0xE4B0, 0x5A25, 0xE4B1, 0x5CE8, 0xE4B2, 0x6211, 0xE4B3, 0x7259, 0xE4B4, 0x82BD, - 0xE4B5, 0x83AA, 0xE4B6, 0x86FE, 0xE4B7, 0x8859, 0xE4B8, 0x8A1D, 0xE4B9, 0x963F, 0xE4BA, 0x96C5, 0xE4BB, 0x9913, 0xE4BC, 0x9D09, - 0xE4BD, 0x9D5D, 0xE4BE, 0x580A, 0xE4BF, 0x5CB3, 0xE4C0, 0x5DBD, 0xE4C1, 0x5E44, 0xE4C2, 0x60E1, 0xE4C3, 0x6115, 0xE4C4, 0x63E1, - 0xE4C5, 0x6A02, 0xE4C6, 0x6E25, 0xE4C7, 0x9102, 0xE4C8, 0x9354, 0xE4C9, 0x984E, 0xE4CA, 0x9C10, 0xE4CB, 0x9F77, 0xE4CC, 0x5B89, - 0xE4CD, 0x5CB8, 0xE4CE, 0x6309, 0xE4CF, 0x664F, 0xE4D0, 0x6848, 0xE4D1, 0x773C, 0xE4D2, 0x96C1, 0xE4D3, 0x978D, 0xE4D4, 0x9854, - 0xE4D5, 0x9B9F, 0xE4D6, 0x65A1, 0xE4D7, 0x8B01, 0xE4D8, 0x8ECB, 0xE4D9, 0x95BC, 0xE4DA, 0x5535, 0xE4DB, 0x5CA9, 0xE4DC, 0x5DD6, - 0xE4DD, 0x5EB5, 0xE4DE, 0x6697, 0xE4DF, 0x764C, 0xE4E0, 0x83F4, 0xE4E1, 0x95C7, 0xE4E2, 0x58D3, 0xE4E3, 0x62BC, 0xE4E4, 0x72CE, - 0xE4E5, 0x9D28, 0xE4E6, 0x4EF0, 0xE4E7, 0x592E, 0xE4E8, 0x600F, 0xE4E9, 0x663B, 0xE4EA, 0x6B83, 0xE4EB, 0x79E7, 0xE4EC, 0x9D26, - 0xE4ED, 0x5393, 0xE4EE, 0x54C0, 0xE4EF, 0x57C3, 0xE4F0, 0x5D16, 0xE4F1, 0x611B, 0xE4F2, 0x66D6, 0xE4F3, 0x6DAF, 0xE4F4, 0x788D, - 0xE4F5, 0x827E, 0xE4F6, 0x9698, 0xE4F7, 0x9744, 0xE4F8, 0x5384, 0xE4F9, 0x627C, 0xE4FA, 0x6396, 0xE4FB, 0x6DB2, 0xE4FC, 0x7E0A, - 0xE4FD, 0x814B, 0xE4FE, 0x984D, 0xE5A1, 0x6AFB, 0xE5A2, 0x7F4C, 0xE5A3, 0x9DAF, 0xE5A4, 0x9E1A, 0xE5A5, 0x4E5F, 0xE5A6, 0x503B, - 0xE5A7, 0x51B6, 0xE5A8, 0x591C, 0xE5A9, 0x60F9, 0xE5AA, 0x63F6, 0xE5AB, 0x6930, 0xE5AC, 0x723A, 0xE5AD, 0x8036, 0xE5AE, 0xF974, - 0xE5AF, 0x91CE, 0xE5B0, 0x5F31, 0xE5B1, 0xF975, 0xE5B2, 0xF976, 0xE5B3, 0x7D04, 0xE5B4, 0x82E5, 0xE5B5, 0x846F, 0xE5B6, 0x84BB, - 0xE5B7, 0x85E5, 0xE5B8, 0x8E8D, 0xE5B9, 0xF977, 0xE5BA, 0x4F6F, 0xE5BB, 0xF978, 0xE5BC, 0xF979, 0xE5BD, 0x58E4, 0xE5BE, 0x5B43, - 0xE5BF, 0x6059, 0xE5C0, 0x63DA, 0xE5C1, 0x6518, 0xE5C2, 0x656D, 0xE5C3, 0x6698, 0xE5C4, 0xF97A, 0xE5C5, 0x694A, 0xE5C6, 0x6A23, - 0xE5C7, 0x6D0B, 0xE5C8, 0x7001, 0xE5C9, 0x716C, 0xE5CA, 0x75D2, 0xE5CB, 0x760D, 0xE5CC, 0x79B3, 0xE5CD, 0x7A70, 0xE5CE, 0xF97B, - 0xE5CF, 0x7F8A, 0xE5D0, 0xF97C, 0xE5D1, 0x8944, 0xE5D2, 0xF97D, 0xE5D3, 0x8B93, 0xE5D4, 0x91C0, 0xE5D5, 0x967D, 0xE5D6, 0xF97E, - 0xE5D7, 0x990A, 0xE5D8, 0x5704, 0xE5D9, 0x5FA1, 0xE5DA, 0x65BC, 0xE5DB, 0x6F01, 0xE5DC, 0x7600, 0xE5DD, 0x79A6, 0xE5DE, 0x8A9E, - 0xE5DF, 0x99AD, 0xE5E0, 0x9B5A, 0xE5E1, 0x9F6C, 0xE5E2, 0x5104, 0xE5E3, 0x61B6, 0xE5E4, 0x6291, 0xE5E5, 0x6A8D, 0xE5E6, 0x81C6, - 0xE5E7, 0x5043, 0xE5E8, 0x5830, 0xE5E9, 0x5F66, 0xE5EA, 0x7109, 0xE5EB, 0x8A00, 0xE5EC, 0x8AFA, 0xE5ED, 0x5B7C, 0xE5EE, 0x8616, - 0xE5EF, 0x4FFA, 0xE5F0, 0x513C, 0xE5F1, 0x56B4, 0xE5F2, 0x5944, 0xE5F3, 0x63A9, 0xE5F4, 0x6DF9, 0xE5F5, 0x5DAA, 0xE5F6, 0x696D, - 0xE5F7, 0x5186, 0xE5F8, 0x4E88, 0xE5F9, 0x4F59, 0xE5FA, 0xF97F, 0xE5FB, 0xF980, 0xE5FC, 0xF981, 0xE5FD, 0x5982, 0xE5FE, 0xF982, - 0xE6A1, 0xF983, 0xE6A2, 0x6B5F, 0xE6A3, 0x6C5D, 0xE6A4, 0xF984, 0xE6A5, 0x74B5, 0xE6A6, 0x7916, 0xE6A7, 0xF985, 0xE6A8, 0x8207, - 0xE6A9, 0x8245, 0xE6AA, 0x8339, 0xE6AB, 0x8F3F, 0xE6AC, 0x8F5D, 0xE6AD, 0xF986, 0xE6AE, 0x9918, 0xE6AF, 0xF987, 0xE6B0, 0xF988, - 0xE6B1, 0xF989, 0xE6B2, 0x4EA6, 0xE6B3, 0xF98A, 0xE6B4, 0x57DF, 0xE6B5, 0x5F79, 0xE6B6, 0x6613, 0xE6B7, 0xF98B, 0xE6B8, 0xF98C, - 0xE6B9, 0x75AB, 0xE6BA, 0x7E79, 0xE6BB, 0x8B6F, 0xE6BC, 0xF98D, 0xE6BD, 0x9006, 0xE6BE, 0x9A5B, 0xE6BF, 0x56A5, 0xE6C0, 0x5827, - 0xE6C1, 0x59F8, 0xE6C2, 0x5A1F, 0xE6C3, 0x5BB4, 0xE6C4, 0xF98E, 0xE6C5, 0x5EF6, 0xE6C6, 0xF98F, 0xE6C7, 0xF990, 0xE6C8, 0x6350, - 0xE6C9, 0x633B, 0xE6CA, 0xF991, 0xE6CB, 0x693D, 0xE6CC, 0x6C87, 0xE6CD, 0x6CBF, 0xE6CE, 0x6D8E, 0xE6CF, 0x6D93, 0xE6D0, 0x6DF5, - 0xE6D1, 0x6F14, 0xE6D2, 0xF992, 0xE6D3, 0x70DF, 0xE6D4, 0x7136, 0xE6D5, 0x7159, 0xE6D6, 0xF993, 0xE6D7, 0x71C3, 0xE6D8, 0x71D5, - 0xE6D9, 0xF994, 0xE6DA, 0x784F, 0xE6DB, 0x786F, 0xE6DC, 0xF995, 0xE6DD, 0x7B75, 0xE6DE, 0x7DE3, 0xE6DF, 0xF996, 0xE6E0, 0x7E2F, - 0xE6E1, 0xF997, 0xE6E2, 0x884D, 0xE6E3, 0x8EDF, 0xE6E4, 0xF998, 0xE6E5, 0xF999, 0xE6E6, 0xF99A, 0xE6E7, 0x925B, 0xE6E8, 0xF99B, - 0xE6E9, 0x9CF6, 0xE6EA, 0xF99C, 0xE6EB, 0xF99D, 0xE6EC, 0xF99E, 0xE6ED, 0x6085, 0xE6EE, 0x6D85, 0xE6EF, 0xF99F, 0xE6F0, 0x71B1, - 0xE6F1, 0xF9A0, 0xE6F2, 0xF9A1, 0xE6F3, 0x95B1, 0xE6F4, 0x53AD, 0xE6F5, 0xF9A2, 0xE6F6, 0xF9A3, 0xE6F7, 0xF9A4, 0xE6F8, 0x67D3, - 0xE6F9, 0xF9A5, 0xE6FA, 0x708E, 0xE6FB, 0x7130, 0xE6FC, 0x7430, 0xE6FD, 0x8276, 0xE6FE, 0x82D2, 0xE7A1, 0xF9A6, 0xE7A2, 0x95BB, - 0xE7A3, 0x9AE5, 0xE7A4, 0x9E7D, 0xE7A5, 0x66C4, 0xE7A6, 0xF9A7, 0xE7A7, 0x71C1, 0xE7A8, 0x8449, 0xE7A9, 0xF9A8, 0xE7AA, 0xF9A9, - 0xE7AB, 0x584B, 0xE7AC, 0xF9AA, 0xE7AD, 0xF9AB, 0xE7AE, 0x5DB8, 0xE7AF, 0x5F71, 0xE7B0, 0xF9AC, 0xE7B1, 0x6620, 0xE7B2, 0x668E, - 0xE7B3, 0x6979, 0xE7B4, 0x69AE, 0xE7B5, 0x6C38, 0xE7B6, 0x6CF3, 0xE7B7, 0x6E36, 0xE7B8, 0x6F41, 0xE7B9, 0x6FDA, 0xE7BA, 0x701B, - 0xE7BB, 0x702F, 0xE7BC, 0x7150, 0xE7BD, 0x71DF, 0xE7BE, 0x7370, 0xE7BF, 0xF9AD, 0xE7C0, 0x745B, 0xE7C1, 0xF9AE, 0xE7C2, 0x74D4, - 0xE7C3, 0x76C8, 0xE7C4, 0x7A4E, 0xE7C5, 0x7E93, 0xE7C6, 0xF9AF, 0xE7C7, 0xF9B0, 0xE7C8, 0x82F1, 0xE7C9, 0x8A60, 0xE7CA, 0x8FCE, - 0xE7CB, 0xF9B1, 0xE7CC, 0x9348, 0xE7CD, 0xF9B2, 0xE7CE, 0x9719, 0xE7CF, 0xF9B3, 0xE7D0, 0xF9B4, 0xE7D1, 0x4E42, 0xE7D2, 0x502A, - 0xE7D3, 0xF9B5, 0xE7D4, 0x5208, 0xE7D5, 0x53E1, 0xE7D6, 0x66F3, 0xE7D7, 0x6C6D, 0xE7D8, 0x6FCA, 0xE7D9, 0x730A, 0xE7DA, 0x777F, - 0xE7DB, 0x7A62, 0xE7DC, 0x82AE, 0xE7DD, 0x85DD, 0xE7DE, 0x8602, 0xE7DF, 0xF9B6, 0xE7E0, 0x88D4, 0xE7E1, 0x8A63, 0xE7E2, 0x8B7D, - 0xE7E3, 0x8C6B, 0xE7E4, 0xF9B7, 0xE7E5, 0x92B3, 0xE7E6, 0xF9B8, 0xE7E7, 0x9713, 0xE7E8, 0x9810, 0xE7E9, 0x4E94, 0xE7EA, 0x4F0D, - 0xE7EB, 0x4FC9, 0xE7EC, 0x50B2, 0xE7ED, 0x5348, 0xE7EE, 0x543E, 0xE7EF, 0x5433, 0xE7F0, 0x55DA, 0xE7F1, 0x5862, 0xE7F2, 0x58BA, - 0xE7F3, 0x5967, 0xE7F4, 0x5A1B, 0xE7F5, 0x5BE4, 0xE7F6, 0x609F, 0xE7F7, 0xF9B9, 0xE7F8, 0x61CA, 0xE7F9, 0x6556, 0xE7FA, 0x65FF, - 0xE7FB, 0x6664, 0xE7FC, 0x68A7, 0xE7FD, 0x6C5A, 0xE7FE, 0x6FB3, 0xE8A1, 0x70CF, 0xE8A2, 0x71AC, 0xE8A3, 0x7352, 0xE8A4, 0x7B7D, - 0xE8A5, 0x8708, 0xE8A6, 0x8AA4, 0xE8A7, 0x9C32, 0xE8A8, 0x9F07, 0xE8A9, 0x5C4B, 0xE8AA, 0x6C83, 0xE8AB, 0x7344, 0xE8AC, 0x7389, - 0xE8AD, 0x923A, 0xE8AE, 0x6EAB, 0xE8AF, 0x7465, 0xE8B0, 0x761F, 0xE8B1, 0x7A69, 0xE8B2, 0x7E15, 0xE8B3, 0x860A, 0xE8B4, 0x5140, - 0xE8B5, 0x58C5, 0xE8B6, 0x64C1, 0xE8B7, 0x74EE, 0xE8B8, 0x7515, 0xE8B9, 0x7670, 0xE8BA, 0x7FC1, 0xE8BB, 0x9095, 0xE8BC, 0x96CD, - 0xE8BD, 0x9954, 0xE8BE, 0x6E26, 0xE8BF, 0x74E6, 0xE8C0, 0x7AA9, 0xE8C1, 0x7AAA, 0xE8C2, 0x81E5, 0xE8C3, 0x86D9, 0xE8C4, 0x8778, - 0xE8C5, 0x8A1B, 0xE8C6, 0x5A49, 0xE8C7, 0x5B8C, 0xE8C8, 0x5B9B, 0xE8C9, 0x68A1, 0xE8CA, 0x6900, 0xE8CB, 0x6D63, 0xE8CC, 0x73A9, - 0xE8CD, 0x7413, 0xE8CE, 0x742C, 0xE8CF, 0x7897, 0xE8D0, 0x7DE9, 0xE8D1, 0x7FEB, 0xE8D2, 0x8118, 0xE8D3, 0x8155, 0xE8D4, 0x839E, - 0xE8D5, 0x8C4C, 0xE8D6, 0x962E, 0xE8D7, 0x9811, 0xE8D8, 0x66F0, 0xE8D9, 0x5F80, 0xE8DA, 0x65FA, 0xE8DB, 0x6789, 0xE8DC, 0x6C6A, - 0xE8DD, 0x738B, 0xE8DE, 0x502D, 0xE8DF, 0x5A03, 0xE8E0, 0x6B6A, 0xE8E1, 0x77EE, 0xE8E2, 0x5916, 0xE8E3, 0x5D6C, 0xE8E4, 0x5DCD, - 0xE8E5, 0x7325, 0xE8E6, 0x754F, 0xE8E7, 0xF9BA, 0xE8E8, 0xF9BB, 0xE8E9, 0x50E5, 0xE8EA, 0x51F9, 0xE8EB, 0x582F, 0xE8EC, 0x592D, - 0xE8ED, 0x5996, 0xE8EE, 0x59DA, 0xE8EF, 0x5BE5, 0xE8F0, 0xF9BC, 0xE8F1, 0xF9BD, 0xE8F2, 0x5DA2, 0xE8F3, 0x62D7, 0xE8F4, 0x6416, - 0xE8F5, 0x6493, 0xE8F6, 0x64FE, 0xE8F7, 0xF9BE, 0xE8F8, 0x66DC, 0xE8F9, 0xF9BF, 0xE8FA, 0x6A48, 0xE8FB, 0xF9C0, 0xE8FC, 0x71FF, - 0xE8FD, 0x7464, 0xE8FE, 0xF9C1, 0xE9A1, 0x7A88, 0xE9A2, 0x7AAF, 0xE9A3, 0x7E47, 0xE9A4, 0x7E5E, 0xE9A5, 0x8000, 0xE9A6, 0x8170, - 0xE9A7, 0xF9C2, 0xE9A8, 0x87EF, 0xE9A9, 0x8981, 0xE9AA, 0x8B20, 0xE9AB, 0x9059, 0xE9AC, 0xF9C3, 0xE9AD, 0x9080, 0xE9AE, 0x9952, - 0xE9AF, 0x617E, 0xE9B0, 0x6B32, 0xE9B1, 0x6D74, 0xE9B2, 0x7E1F, 0xE9B3, 0x8925, 0xE9B4, 0x8FB1, 0xE9B5, 0x4FD1, 0xE9B6, 0x50AD, - 0xE9B7, 0x5197, 0xE9B8, 0x52C7, 0xE9B9, 0x57C7, 0xE9BA, 0x5889, 0xE9BB, 0x5BB9, 0xE9BC, 0x5EB8, 0xE9BD, 0x6142, 0xE9BE, 0x6995, - 0xE9BF, 0x6D8C, 0xE9C0, 0x6E67, 0xE9C1, 0x6EB6, 0xE9C2, 0x7194, 0xE9C3, 0x7462, 0xE9C4, 0x7528, 0xE9C5, 0x752C, 0xE9C6, 0x8073, - 0xE9C7, 0x8338, 0xE9C8, 0x84C9, 0xE9C9, 0x8E0A, 0xE9CA, 0x9394, 0xE9CB, 0x93DE, 0xE9CC, 0xF9C4, 0xE9CD, 0x4E8E, 0xE9CE, 0x4F51, - 0xE9CF, 0x5076, 0xE9D0, 0x512A, 0xE9D1, 0x53C8, 0xE9D2, 0x53CB, 0xE9D3, 0x53F3, 0xE9D4, 0x5B87, 0xE9D5, 0x5BD3, 0xE9D6, 0x5C24, - 0xE9D7, 0x611A, 0xE9D8, 0x6182, 0xE9D9, 0x65F4, 0xE9DA, 0x725B, 0xE9DB, 0x7397, 0xE9DC, 0x7440, 0xE9DD, 0x76C2, 0xE9DE, 0x7950, - 0xE9DF, 0x7991, 0xE9E0, 0x79B9, 0xE9E1, 0x7D06, 0xE9E2, 0x7FBD, 0xE9E3, 0x828B, 0xE9E4, 0x85D5, 0xE9E5, 0x865E, 0xE9E6, 0x8FC2, - 0xE9E7, 0x9047, 0xE9E8, 0x90F5, 0xE9E9, 0x91EA, 0xE9EA, 0x9685, 0xE9EB, 0x96E8, 0xE9EC, 0x96E9, 0xE9ED, 0x52D6, 0xE9EE, 0x5F67, - 0xE9EF, 0x65ED, 0xE9F0, 0x6631, 0xE9F1, 0x682F, 0xE9F2, 0x715C, 0xE9F3, 0x7A36, 0xE9F4, 0x90C1, 0xE9F5, 0x980A, 0xE9F6, 0x4E91, - 0xE9F7, 0xF9C5, 0xE9F8, 0x6A52, 0xE9F9, 0x6B9E, 0xE9FA, 0x6F90, 0xE9FB, 0x7189, 0xE9FC, 0x8018, 0xE9FD, 0x82B8, 0xE9FE, 0x8553, - 0xEAA1, 0x904B, 0xEAA2, 0x9695, 0xEAA3, 0x96F2, 0xEAA4, 0x97FB, 0xEAA5, 0x851A, 0xEAA6, 0x9B31, 0xEAA7, 0x4E90, 0xEAA8, 0x718A, - 0xEAA9, 0x96C4, 0xEAAA, 0x5143, 0xEAAB, 0x539F, 0xEAAC, 0x54E1, 0xEAAD, 0x5713, 0xEAAE, 0x5712, 0xEAAF, 0x57A3, 0xEAB0, 0x5A9B, - 0xEAB1, 0x5AC4, 0xEAB2, 0x5BC3, 0xEAB3, 0x6028, 0xEAB4, 0x613F, 0xEAB5, 0x63F4, 0xEAB6, 0x6C85, 0xEAB7, 0x6D39, 0xEAB8, 0x6E72, - 0xEAB9, 0x6E90, 0xEABA, 0x7230, 0xEABB, 0x733F, 0xEABC, 0x7457, 0xEABD, 0x82D1, 0xEABE, 0x8881, 0xEABF, 0x8F45, 0xEAC0, 0x9060, - 0xEAC1, 0xF9C6, 0xEAC2, 0x9662, 0xEAC3, 0x9858, 0xEAC4, 0x9D1B, 0xEAC5, 0x6708, 0xEAC6, 0x8D8A, 0xEAC7, 0x925E, 0xEAC8, 0x4F4D, - 0xEAC9, 0x5049, 0xEACA, 0x50DE, 0xEACB, 0x5371, 0xEACC, 0x570D, 0xEACD, 0x59D4, 0xEACE, 0x5A01, 0xEACF, 0x5C09, 0xEAD0, 0x6170, - 0xEAD1, 0x6690, 0xEAD2, 0x6E2D, 0xEAD3, 0x7232, 0xEAD4, 0x744B, 0xEAD5, 0x7DEF, 0xEAD6, 0x80C3, 0xEAD7, 0x840E, 0xEAD8, 0x8466, - 0xEAD9, 0x853F, 0xEADA, 0x875F, 0xEADB, 0x885B, 0xEADC, 0x8918, 0xEADD, 0x8B02, 0xEADE, 0x9055, 0xEADF, 0x97CB, 0xEAE0, 0x9B4F, - 0xEAE1, 0x4E73, 0xEAE2, 0x4F91, 0xEAE3, 0x5112, 0xEAE4, 0x516A, 0xEAE5, 0xF9C7, 0xEAE6, 0x552F, 0xEAE7, 0x55A9, 0xEAE8, 0x5B7A, - 0xEAE9, 0x5BA5, 0xEAEA, 0x5E7C, 0xEAEB, 0x5E7D, 0xEAEC, 0x5EBE, 0xEAED, 0x60A0, 0xEAEE, 0x60DF, 0xEAEF, 0x6108, 0xEAF0, 0x6109, - 0xEAF1, 0x63C4, 0xEAF2, 0x6538, 0xEAF3, 0x6709, 0xEAF4, 0xF9C8, 0xEAF5, 0x67D4, 0xEAF6, 0x67DA, 0xEAF7, 0xF9C9, 0xEAF8, 0x6961, - 0xEAF9, 0x6962, 0xEAFA, 0x6CB9, 0xEAFB, 0x6D27, 0xEAFC, 0xF9CA, 0xEAFD, 0x6E38, 0xEAFE, 0xF9CB, 0xEBA1, 0x6FE1, 0xEBA2, 0x7336, - 0xEBA3, 0x7337, 0xEBA4, 0xF9CC, 0xEBA5, 0x745C, 0xEBA6, 0x7531, 0xEBA7, 0xF9CD, 0xEBA8, 0x7652, 0xEBA9, 0xF9CE, 0xEBAA, 0xF9CF, - 0xEBAB, 0x7DAD, 0xEBAC, 0x81FE, 0xEBAD, 0x8438, 0xEBAE, 0x88D5, 0xEBAF, 0x8A98, 0xEBB0, 0x8ADB, 0xEBB1, 0x8AED, 0xEBB2, 0x8E30, - 0xEBB3, 0x8E42, 0xEBB4, 0x904A, 0xEBB5, 0x903E, 0xEBB6, 0x907A, 0xEBB7, 0x9149, 0xEBB8, 0x91C9, 0xEBB9, 0x936E, 0xEBBA, 0xF9D0, - 0xEBBB, 0xF9D1, 0xEBBC, 0x5809, 0xEBBD, 0xF9D2, 0xEBBE, 0x6BD3, 0xEBBF, 0x8089, 0xEBC0, 0x80B2, 0xEBC1, 0xF9D3, 0xEBC2, 0xF9D4, - 0xEBC3, 0x5141, 0xEBC4, 0x596B, 0xEBC5, 0x5C39, 0xEBC6, 0xF9D5, 0xEBC7, 0xF9D6, 0xEBC8, 0x6F64, 0xEBC9, 0x73A7, 0xEBCA, 0x80E4, - 0xEBCB, 0x8D07, 0xEBCC, 0xF9D7, 0xEBCD, 0x9217, 0xEBCE, 0x958F, 0xEBCF, 0xF9D8, 0xEBD0, 0xF9D9, 0xEBD1, 0xF9DA, 0xEBD2, 0xF9DB, - 0xEBD3, 0x807F, 0xEBD4, 0x620E, 0xEBD5, 0x701C, 0xEBD6, 0x7D68, 0xEBD7, 0x878D, 0xEBD8, 0xF9DC, 0xEBD9, 0x57A0, 0xEBDA, 0x6069, - 0xEBDB, 0x6147, 0xEBDC, 0x6BB7, 0xEBDD, 0x8ABE, 0xEBDE, 0x9280, 0xEBDF, 0x96B1, 0xEBE0, 0x4E59, 0xEBE1, 0x541F, 0xEBE2, 0x6DEB, - 0xEBE3, 0x852D, 0xEBE4, 0x9670, 0xEBE5, 0x97F3, 0xEBE6, 0x98EE, 0xEBE7, 0x63D6, 0xEBE8, 0x6CE3, 0xEBE9, 0x9091, 0xEBEA, 0x51DD, - 0xEBEB, 0x61C9, 0xEBEC, 0x81BA, 0xEBED, 0x9DF9, 0xEBEE, 0x4F9D, 0xEBEF, 0x501A, 0xEBF0, 0x5100, 0xEBF1, 0x5B9C, 0xEBF2, 0x610F, - 0xEBF3, 0x61FF, 0xEBF4, 0x64EC, 0xEBF5, 0x6905, 0xEBF6, 0x6BC5, 0xEBF7, 0x7591, 0xEBF8, 0x77E3, 0xEBF9, 0x7FA9, 0xEBFA, 0x8264, - 0xEBFB, 0x858F, 0xEBFC, 0x87FB, 0xEBFD, 0x8863, 0xEBFE, 0x8ABC, 0xECA1, 0x8B70, 0xECA2, 0x91AB, 0xECA3, 0x4E8C, 0xECA4, 0x4EE5, - 0xECA5, 0x4F0A, 0xECA6, 0xF9DD, 0xECA7, 0xF9DE, 0xECA8, 0x5937, 0xECA9, 0x59E8, 0xECAA, 0xF9DF, 0xECAB, 0x5DF2, 0xECAC, 0x5F1B, - 0xECAD, 0x5F5B, 0xECAE, 0x6021, 0xECAF, 0xF9E0, 0xECB0, 0xF9E1, 0xECB1, 0xF9E2, 0xECB2, 0xF9E3, 0xECB3, 0x723E, 0xECB4, 0x73E5, - 0xECB5, 0xF9E4, 0xECB6, 0x7570, 0xECB7, 0x75CD, 0xECB8, 0xF9E5, 0xECB9, 0x79FB, 0xECBA, 0xF9E6, 0xECBB, 0x800C, 0xECBC, 0x8033, - 0xECBD, 0x8084, 0xECBE, 0x82E1, 0xECBF, 0x8351, 0xECC0, 0xF9E7, 0xECC1, 0xF9E8, 0xECC2, 0x8CBD, 0xECC3, 0x8CB3, 0xECC4, 0x9087, - 0xECC5, 0xF9E9, 0xECC6, 0xF9EA, 0xECC7, 0x98F4, 0xECC8, 0x990C, 0xECC9, 0xF9EB, 0xECCA, 0xF9EC, 0xECCB, 0x7037, 0xECCC, 0x76CA, - 0xECCD, 0x7FCA, 0xECCE, 0x7FCC, 0xECCF, 0x7FFC, 0xECD0, 0x8B1A, 0xECD1, 0x4EBA, 0xECD2, 0x4EC1, 0xECD3, 0x5203, 0xECD4, 0x5370, - 0xECD5, 0xF9ED, 0xECD6, 0x54BD, 0xECD7, 0x56E0, 0xECD8, 0x59FB, 0xECD9, 0x5BC5, 0xECDA, 0x5F15, 0xECDB, 0x5FCD, 0xECDC, 0x6E6E, - 0xECDD, 0xF9EE, 0xECDE, 0xF9EF, 0xECDF, 0x7D6A, 0xECE0, 0x8335, 0xECE1, 0xF9F0, 0xECE2, 0x8693, 0xECE3, 0x8A8D, 0xECE4, 0xF9F1, - 0xECE5, 0x976D, 0xECE6, 0x9777, 0xECE7, 0xF9F2, 0xECE8, 0xF9F3, 0xECE9, 0x4E00, 0xECEA, 0x4F5A, 0xECEB, 0x4F7E, 0xECEC, 0x58F9, - 0xECED, 0x65E5, 0xECEE, 0x6EA2, 0xECEF, 0x9038, 0xECF0, 0x93B0, 0xECF1, 0x99B9, 0xECF2, 0x4EFB, 0xECF3, 0x58EC, 0xECF4, 0x598A, - 0xECF5, 0x59D9, 0xECF6, 0x6041, 0xECF7, 0xF9F4, 0xECF8, 0xF9F5, 0xECF9, 0x7A14, 0xECFA, 0xF9F6, 0xECFB, 0x834F, 0xECFC, 0x8CC3, - 0xECFD, 0x5165, 0xECFE, 0x5344, 0xEDA1, 0xF9F7, 0xEDA2, 0xF9F8, 0xEDA3, 0xF9F9, 0xEDA4, 0x4ECD, 0xEDA5, 0x5269, 0xEDA6, 0x5B55, - 0xEDA7, 0x82BF, 0xEDA8, 0x4ED4, 0xEDA9, 0x523A, 0xEDAA, 0x54A8, 0xEDAB, 0x59C9, 0xEDAC, 0x59FF, 0xEDAD, 0x5B50, 0xEDAE, 0x5B57, - 0xEDAF, 0x5B5C, 0xEDB0, 0x6063, 0xEDB1, 0x6148, 0xEDB2, 0x6ECB, 0xEDB3, 0x7099, 0xEDB4, 0x716E, 0xEDB5, 0x7386, 0xEDB6, 0x74F7, - 0xEDB7, 0x75B5, 0xEDB8, 0x78C1, 0xEDB9, 0x7D2B, 0xEDBA, 0x8005, 0xEDBB, 0x81EA, 0xEDBC, 0x8328, 0xEDBD, 0x8517, 0xEDBE, 0x85C9, - 0xEDBF, 0x8AEE, 0xEDC0, 0x8CC7, 0xEDC1, 0x96CC, 0xEDC2, 0x4F5C, 0xEDC3, 0x52FA, 0xEDC4, 0x56BC, 0xEDC5, 0x65AB, 0xEDC6, 0x6628, - 0xEDC7, 0x707C, 0xEDC8, 0x70B8, 0xEDC9, 0x7235, 0xEDCA, 0x7DBD, 0xEDCB, 0x828D, 0xEDCC, 0x914C, 0xEDCD, 0x96C0, 0xEDCE, 0x9D72, - 0xEDCF, 0x5B71, 0xEDD0, 0x68E7, 0xEDD1, 0x6B98, 0xEDD2, 0x6F7A, 0xEDD3, 0x76DE, 0xEDD4, 0x5C91, 0xEDD5, 0x66AB, 0xEDD6, 0x6F5B, - 0xEDD7, 0x7BB4, 0xEDD8, 0x7C2A, 0xEDD9, 0x8836, 0xEDDA, 0x96DC, 0xEDDB, 0x4E08, 0xEDDC, 0x4ED7, 0xEDDD, 0x5320, 0xEDDE, 0x5834, - 0xEDDF, 0x58BB, 0xEDE0, 0x58EF, 0xEDE1, 0x596C, 0xEDE2, 0x5C07, 0xEDE3, 0x5E33, 0xEDE4, 0x5E84, 0xEDE5, 0x5F35, 0xEDE6, 0x638C, - 0xEDE7, 0x66B2, 0xEDE8, 0x6756, 0xEDE9, 0x6A1F, 0xEDEA, 0x6AA3, 0xEDEB, 0x6B0C, 0xEDEC, 0x6F3F, 0xEDED, 0x7246, 0xEDEE, 0xF9FA, - 0xEDEF, 0x7350, 0xEDF0, 0x748B, 0xEDF1, 0x7AE0, 0xEDF2, 0x7CA7, 0xEDF3, 0x8178, 0xEDF4, 0x81DF, 0xEDF5, 0x81E7, 0xEDF6, 0x838A, - 0xEDF7, 0x846C, 0xEDF8, 0x8523, 0xEDF9, 0x8594, 0xEDFA, 0x85CF, 0xEDFB, 0x88DD, 0xEDFC, 0x8D13, 0xEDFD, 0x91AC, 0xEDFE, 0x9577, - 0xEEA1, 0x969C, 0xEEA2, 0x518D, 0xEEA3, 0x54C9, 0xEEA4, 0x5728, 0xEEA5, 0x5BB0, 0xEEA6, 0x624D, 0xEEA7, 0x6750, 0xEEA8, 0x683D, - 0xEEA9, 0x6893, 0xEEAA, 0x6E3D, 0xEEAB, 0x6ED3, 0xEEAC, 0x707D, 0xEEAD, 0x7E21, 0xEEAE, 0x88C1, 0xEEAF, 0x8CA1, 0xEEB0, 0x8F09, - 0xEEB1, 0x9F4B, 0xEEB2, 0x9F4E, 0xEEB3, 0x722D, 0xEEB4, 0x7B8F, 0xEEB5, 0x8ACD, 0xEEB6, 0x931A, 0xEEB7, 0x4F47, 0xEEB8, 0x4F4E, - 0xEEB9, 0x5132, 0xEEBA, 0x5480, 0xEEBB, 0x59D0, 0xEEBC, 0x5E95, 0xEEBD, 0x62B5, 0xEEBE, 0x6775, 0xEEBF, 0x696E, 0xEEC0, 0x6A17, - 0xEEC1, 0x6CAE, 0xEEC2, 0x6E1A, 0xEEC3, 0x72D9, 0xEEC4, 0x732A, 0xEEC5, 0x75BD, 0xEEC6, 0x7BB8, 0xEEC7, 0x7D35, 0xEEC8, 0x82E7, - 0xEEC9, 0x83F9, 0xEECA, 0x8457, 0xEECB, 0x85F7, 0xEECC, 0x8A5B, 0xEECD, 0x8CAF, 0xEECE, 0x8E87, 0xEECF, 0x9019, 0xEED0, 0x90B8, - 0xEED1, 0x96CE, 0xEED2, 0x9F5F, 0xEED3, 0x52E3, 0xEED4, 0x540A, 0xEED5, 0x5AE1, 0xEED6, 0x5BC2, 0xEED7, 0x6458, 0xEED8, 0x6575, - 0xEED9, 0x6EF4, 0xEEDA, 0x72C4, 0xEEDB, 0xF9FB, 0xEEDC, 0x7684, 0xEEDD, 0x7A4D, 0xEEDE, 0x7B1B, 0xEEDF, 0x7C4D, 0xEEE0, 0x7E3E, - 0xEEE1, 0x7FDF, 0xEEE2, 0x837B, 0xEEE3, 0x8B2B, 0xEEE4, 0x8CCA, 0xEEE5, 0x8D64, 0xEEE6, 0x8DE1, 0xEEE7, 0x8E5F, 0xEEE8, 0x8FEA, - 0xEEE9, 0x8FF9, 0xEEEA, 0x9069, 0xEEEB, 0x93D1, 0xEEEC, 0x4F43, 0xEEED, 0x4F7A, 0xEEEE, 0x50B3, 0xEEEF, 0x5168, 0xEEF0, 0x5178, - 0xEEF1, 0x524D, 0xEEF2, 0x526A, 0xEEF3, 0x5861, 0xEEF4, 0x587C, 0xEEF5, 0x5960, 0xEEF6, 0x5C08, 0xEEF7, 0x5C55, 0xEEF8, 0x5EDB, - 0xEEF9, 0x609B, 0xEEFA, 0x6230, 0xEEFB, 0x6813, 0xEEFC, 0x6BBF, 0xEEFD, 0x6C08, 0xEEFE, 0x6FB1, 0xEFA1, 0x714E, 0xEFA2, 0x7420, - 0xEFA3, 0x7530, 0xEFA4, 0x7538, 0xEFA5, 0x7551, 0xEFA6, 0x7672, 0xEFA7, 0x7B4C, 0xEFA8, 0x7B8B, 0xEFA9, 0x7BAD, 0xEFAA, 0x7BC6, - 0xEFAB, 0x7E8F, 0xEFAC, 0x8A6E, 0xEFAD, 0x8F3E, 0xEFAE, 0x8F49, 0xEFAF, 0x923F, 0xEFB0, 0x9293, 0xEFB1, 0x9322, 0xEFB2, 0x942B, - 0xEFB3, 0x96FB, 0xEFB4, 0x985A, 0xEFB5, 0x986B, 0xEFB6, 0x991E, 0xEFB7, 0x5207, 0xEFB8, 0x622A, 0xEFB9, 0x6298, 0xEFBA, 0x6D59, - 0xEFBB, 0x7664, 0xEFBC, 0x7ACA, 0xEFBD, 0x7BC0, 0xEFBE, 0x7D76, 0xEFBF, 0x5360, 0xEFC0, 0x5CBE, 0xEFC1, 0x5E97, 0xEFC2, 0x6F38, - 0xEFC3, 0x70B9, 0xEFC4, 0x7C98, 0xEFC5, 0x9711, 0xEFC6, 0x9B8E, 0xEFC7, 0x9EDE, 0xEFC8, 0x63A5, 0xEFC9, 0x647A, 0xEFCA, 0x8776, - 0xEFCB, 0x4E01, 0xEFCC, 0x4E95, 0xEFCD, 0x4EAD, 0xEFCE, 0x505C, 0xEFCF, 0x5075, 0xEFD0, 0x5448, 0xEFD1, 0x59C3, 0xEFD2, 0x5B9A, - 0xEFD3, 0x5E40, 0xEFD4, 0x5EAD, 0xEFD5, 0x5EF7, 0xEFD6, 0x5F81, 0xEFD7, 0x60C5, 0xEFD8, 0x633A, 0xEFD9, 0x653F, 0xEFDA, 0x6574, - 0xEFDB, 0x65CC, 0xEFDC, 0x6676, 0xEFDD, 0x6678, 0xEFDE, 0x67FE, 0xEFDF, 0x6968, 0xEFE0, 0x6A89, 0xEFE1, 0x6B63, 0xEFE2, 0x6C40, - 0xEFE3, 0x6DC0, 0xEFE4, 0x6DE8, 0xEFE5, 0x6E1F, 0xEFE6, 0x6E5E, 0xEFE7, 0x701E, 0xEFE8, 0x70A1, 0xEFE9, 0x738E, 0xEFEA, 0x73FD, - 0xEFEB, 0x753A, 0xEFEC, 0x775B, 0xEFED, 0x7887, 0xEFEE, 0x798E, 0xEFEF, 0x7A0B, 0xEFF0, 0x7A7D, 0xEFF1, 0x7CBE, 0xEFF2, 0x7D8E, - 0xEFF3, 0x8247, 0xEFF4, 0x8A02, 0xEFF5, 0x8AEA, 0xEFF6, 0x8C9E, 0xEFF7, 0x912D, 0xEFF8, 0x914A, 0xEFF9, 0x91D8, 0xEFFA, 0x9266, - 0xEFFB, 0x92CC, 0xEFFC, 0x9320, 0xEFFD, 0x9706, 0xEFFE, 0x9756, 0xF0A1, 0x975C, 0xF0A2, 0x9802, 0xF0A3, 0x9F0E, 0xF0A4, 0x5236, - 0xF0A5, 0x5291, 0xF0A6, 0x557C, 0xF0A7, 0x5824, 0xF0A8, 0x5E1D, 0xF0A9, 0x5F1F, 0xF0AA, 0x608C, 0xF0AB, 0x63D0, 0xF0AC, 0x68AF, - 0xF0AD, 0x6FDF, 0xF0AE, 0x796D, 0xF0AF, 0x7B2C, 0xF0B0, 0x81CD, 0xF0B1, 0x85BA, 0xF0B2, 0x88FD, 0xF0B3, 0x8AF8, 0xF0B4, 0x8E44, - 0xF0B5, 0x918D, 0xF0B6, 0x9664, 0xF0B7, 0x969B, 0xF0B8, 0x973D, 0xF0B9, 0x984C, 0xF0BA, 0x9F4A, 0xF0BB, 0x4FCE, 0xF0BC, 0x5146, - 0xF0BD, 0x51CB, 0xF0BE, 0x52A9, 0xF0BF, 0x5632, 0xF0C0, 0x5F14, 0xF0C1, 0x5F6B, 0xF0C2, 0x63AA, 0xF0C3, 0x64CD, 0xF0C4, 0x65E9, - 0xF0C5, 0x6641, 0xF0C6, 0x66FA, 0xF0C7, 0x66F9, 0xF0C8, 0x671D, 0xF0C9, 0x689D, 0xF0CA, 0x68D7, 0xF0CB, 0x69FD, 0xF0CC, 0x6F15, - 0xF0CD, 0x6F6E, 0xF0CE, 0x7167, 0xF0CF, 0x71E5, 0xF0D0, 0x722A, 0xF0D1, 0x74AA, 0xF0D2, 0x773A, 0xF0D3, 0x7956, 0xF0D4, 0x795A, - 0xF0D5, 0x79DF, 0xF0D6, 0x7A20, 0xF0D7, 0x7A95, 0xF0D8, 0x7C97, 0xF0D9, 0x7CDF, 0xF0DA, 0x7D44, 0xF0DB, 0x7E70, 0xF0DC, 0x8087, - 0xF0DD, 0x85FB, 0xF0DE, 0x86A4, 0xF0DF, 0x8A54, 0xF0E0, 0x8ABF, 0xF0E1, 0x8D99, 0xF0E2, 0x8E81, 0xF0E3, 0x9020, 0xF0E4, 0x906D, - 0xF0E5, 0x91E3, 0xF0E6, 0x963B, 0xF0E7, 0x96D5, 0xF0E8, 0x9CE5, 0xF0E9, 0x65CF, 0xF0EA, 0x7C07, 0xF0EB, 0x8DB3, 0xF0EC, 0x93C3, - 0xF0ED, 0x5B58, 0xF0EE, 0x5C0A, 0xF0EF, 0x5352, 0xF0F0, 0x62D9, 0xF0F1, 0x731D, 0xF0F2, 0x5027, 0xF0F3, 0x5B97, 0xF0F4, 0x5F9E, - 0xF0F5, 0x60B0, 0xF0F6, 0x616B, 0xF0F7, 0x68D5, 0xF0F8, 0x6DD9, 0xF0F9, 0x742E, 0xF0FA, 0x7A2E, 0xF0FB, 0x7D42, 0xF0FC, 0x7D9C, - 0xF0FD, 0x7E31, 0xF0FE, 0x816B, 0xF1A1, 0x8E2A, 0xF1A2, 0x8E35, 0xF1A3, 0x937E, 0xF1A4, 0x9418, 0xF1A5, 0x4F50, 0xF1A6, 0x5750, - 0xF1A7, 0x5DE6, 0xF1A8, 0x5EA7, 0xF1A9, 0x632B, 0xF1AA, 0x7F6A, 0xF1AB, 0x4E3B, 0xF1AC, 0x4F4F, 0xF1AD, 0x4F8F, 0xF1AE, 0x505A, - 0xF1AF, 0x59DD, 0xF1B0, 0x80C4, 0xF1B1, 0x546A, 0xF1B2, 0x5468, 0xF1B3, 0x55FE, 0xF1B4, 0x594F, 0xF1B5, 0x5B99, 0xF1B6, 0x5DDE, - 0xF1B7, 0x5EDA, 0xF1B8, 0x665D, 0xF1B9, 0x6731, 0xF1BA, 0x67F1, 0xF1BB, 0x682A, 0xF1BC, 0x6CE8, 0xF1BD, 0x6D32, 0xF1BE, 0x6E4A, - 0xF1BF, 0x6F8D, 0xF1C0, 0x70B7, 0xF1C1, 0x73E0, 0xF1C2, 0x7587, 0xF1C3, 0x7C4C, 0xF1C4, 0x7D02, 0xF1C5, 0x7D2C, 0xF1C6, 0x7DA2, - 0xF1C7, 0x821F, 0xF1C8, 0x86DB, 0xF1C9, 0x8A3B, 0xF1CA, 0x8A85, 0xF1CB, 0x8D70, 0xF1CC, 0x8E8A, 0xF1CD, 0x8F33, 0xF1CE, 0x9031, - 0xF1CF, 0x914E, 0xF1D0, 0x9152, 0xF1D1, 0x9444, 0xF1D2, 0x99D0, 0xF1D3, 0x7AF9, 0xF1D4, 0x7CA5, 0xF1D5, 0x4FCA, 0xF1D6, 0x5101, - 0xF1D7, 0x51C6, 0xF1D8, 0x57C8, 0xF1D9, 0x5BEF, 0xF1DA, 0x5CFB, 0xF1DB, 0x6659, 0xF1DC, 0x6A3D, 0xF1DD, 0x6D5A, 0xF1DE, 0x6E96, - 0xF1DF, 0x6FEC, 0xF1E0, 0x710C, 0xF1E1, 0x756F, 0xF1E2, 0x7AE3, 0xF1E3, 0x8822, 0xF1E4, 0x9021, 0xF1E5, 0x9075, 0xF1E6, 0x96CB, - 0xF1E7, 0x99FF, 0xF1E8, 0x8301, 0xF1E9, 0x4E2D, 0xF1EA, 0x4EF2, 0xF1EB, 0x8846, 0xF1EC, 0x91CD, 0xF1ED, 0x537D, 0xF1EE, 0x6ADB, - 0xF1EF, 0x696B, 0xF1F0, 0x6C41, 0xF1F1, 0x847A, 0xF1F2, 0x589E, 0xF1F3, 0x618E, 0xF1F4, 0x66FE, 0xF1F5, 0x62EF, 0xF1F6, 0x70DD, - 0xF1F7, 0x7511, 0xF1F8, 0x75C7, 0xF1F9, 0x7E52, 0xF1FA, 0x84B8, 0xF1FB, 0x8B49, 0xF1FC, 0x8D08, 0xF1FD, 0x4E4B, 0xF1FE, 0x53EA, - 0xF2A1, 0x54AB, 0xF2A2, 0x5730, 0xF2A3, 0x5740, 0xF2A4, 0x5FD7, 0xF2A5, 0x6301, 0xF2A6, 0x6307, 0xF2A7, 0x646F, 0xF2A8, 0x652F, - 0xF2A9, 0x65E8, 0xF2AA, 0x667A, 0xF2AB, 0x679D, 0xF2AC, 0x67B3, 0xF2AD, 0x6B62, 0xF2AE, 0x6C60, 0xF2AF, 0x6C9A, 0xF2B0, 0x6F2C, - 0xF2B1, 0x77E5, 0xF2B2, 0x7825, 0xF2B3, 0x7949, 0xF2B4, 0x7957, 0xF2B5, 0x7D19, 0xF2B6, 0x80A2, 0xF2B7, 0x8102, 0xF2B8, 0x81F3, - 0xF2B9, 0x829D, 0xF2BA, 0x82B7, 0xF2BB, 0x8718, 0xF2BC, 0x8A8C, 0xF2BD, 0xF9FC, 0xF2BE, 0x8D04, 0xF2BF, 0x8DBE, 0xF2C0, 0x9072, - 0xF2C1, 0x76F4, 0xF2C2, 0x7A19, 0xF2C3, 0x7A37, 0xF2C4, 0x7E54, 0xF2C5, 0x8077, 0xF2C6, 0x5507, 0xF2C7, 0x55D4, 0xF2C8, 0x5875, - 0xF2C9, 0x632F, 0xF2CA, 0x6422, 0xF2CB, 0x6649, 0xF2CC, 0x664B, 0xF2CD, 0x686D, 0xF2CE, 0x699B, 0xF2CF, 0x6B84, 0xF2D0, 0x6D25, - 0xF2D1, 0x6EB1, 0xF2D2, 0x73CD, 0xF2D3, 0x7468, 0xF2D4, 0x74A1, 0xF2D5, 0x755B, 0xF2D6, 0x75B9, 0xF2D7, 0x76E1, 0xF2D8, 0x771E, - 0xF2D9, 0x778B, 0xF2DA, 0x79E6, 0xF2DB, 0x7E09, 0xF2DC, 0x7E1D, 0xF2DD, 0x81FB, 0xF2DE, 0x852F, 0xF2DF, 0x8897, 0xF2E0, 0x8A3A, - 0xF2E1, 0x8CD1, 0xF2E2, 0x8EEB, 0xF2E3, 0x8FB0, 0xF2E4, 0x9032, 0xF2E5, 0x93AD, 0xF2E6, 0x9663, 0xF2E7, 0x9673, 0xF2E8, 0x9707, - 0xF2E9, 0x4F84, 0xF2EA, 0x53F1, 0xF2EB, 0x59EA, 0xF2EC, 0x5AC9, 0xF2ED, 0x5E19, 0xF2EE, 0x684E, 0xF2EF, 0x74C6, 0xF2F0, 0x75BE, - 0xF2F1, 0x79E9, 0xF2F2, 0x7A92, 0xF2F3, 0x81A3, 0xF2F4, 0x86ED, 0xF2F5, 0x8CEA, 0xF2F6, 0x8DCC, 0xF2F7, 0x8FED, 0xF2F8, 0x659F, - 0xF2F9, 0x6715, 0xF2FA, 0xF9FD, 0xF2FB, 0x57F7, 0xF2FC, 0x6F57, 0xF2FD, 0x7DDD, 0xF2FE, 0x8F2F, 0xF3A1, 0x93F6, 0xF3A2, 0x96C6, - 0xF3A3, 0x5FB5, 0xF3A4, 0x61F2, 0xF3A5, 0x6F84, 0xF3A6, 0x4E14, 0xF3A7, 0x4F98, 0xF3A8, 0x501F, 0xF3A9, 0x53C9, 0xF3AA, 0x55DF, - 0xF3AB, 0x5D6F, 0xF3AC, 0x5DEE, 0xF3AD, 0x6B21, 0xF3AE, 0x6B64, 0xF3AF, 0x78CB, 0xF3B0, 0x7B9A, 0xF3B1, 0xF9FE, 0xF3B2, 0x8E49, - 0xF3B3, 0x8ECA, 0xF3B4, 0x906E, 0xF3B5, 0x6349, 0xF3B6, 0x643E, 0xF3B7, 0x7740, 0xF3B8, 0x7A84, 0xF3B9, 0x932F, 0xF3BA, 0x947F, - 0xF3BB, 0x9F6A, 0xF3BC, 0x64B0, 0xF3BD, 0x6FAF, 0xF3BE, 0x71E6, 0xF3BF, 0x74A8, 0xF3C0, 0x74DA, 0xF3C1, 0x7AC4, 0xF3C2, 0x7C12, - 0xF3C3, 0x7E82, 0xF3C4, 0x7CB2, 0xF3C5, 0x7E98, 0xF3C6, 0x8B9A, 0xF3C7, 0x8D0A, 0xF3C8, 0x947D, 0xF3C9, 0x9910, 0xF3CA, 0x994C, - 0xF3CB, 0x5239, 0xF3CC, 0x5BDF, 0xF3CD, 0x64E6, 0xF3CE, 0x672D, 0xF3CF, 0x7D2E, 0xF3D0, 0x50ED, 0xF3D1, 0x53C3, 0xF3D2, 0x5879, - 0xF3D3, 0x6158, 0xF3D4, 0x6159, 0xF3D5, 0x61FA, 0xF3D6, 0x65AC, 0xF3D7, 0x7AD9, 0xF3D8, 0x8B92, 0xF3D9, 0x8B96, 0xF3DA, 0x5009, - 0xF3DB, 0x5021, 0xF3DC, 0x5275, 0xF3DD, 0x5531, 0xF3DE, 0x5A3C, 0xF3DF, 0x5EE0, 0xF3E0, 0x5F70, 0xF3E1, 0x6134, 0xF3E2, 0x655E, - 0xF3E3, 0x660C, 0xF3E4, 0x6636, 0xF3E5, 0x66A2, 0xF3E6, 0x69CD, 0xF3E7, 0x6EC4, 0xF3E8, 0x6F32, 0xF3E9, 0x7316, 0xF3EA, 0x7621, - 0xF3EB, 0x7A93, 0xF3EC, 0x8139, 0xF3ED, 0x8259, 0xF3EE, 0x83D6, 0xF3EF, 0x84BC, 0xF3F0, 0x50B5, 0xF3F1, 0x57F0, 0xF3F2, 0x5BC0, - 0xF3F3, 0x5BE8, 0xF3F4, 0x5F69, 0xF3F5, 0x63A1, 0xF3F6, 0x7826, 0xF3F7, 0x7DB5, 0xF3F8, 0x83DC, 0xF3F9, 0x8521, 0xF3FA, 0x91C7, - 0xF3FB, 0x91F5, 0xF3FC, 0x518A, 0xF3FD, 0x67F5, 0xF3FE, 0x7B56, 0xF4A1, 0x8CAC, 0xF4A2, 0x51C4, 0xF4A3, 0x59BB, 0xF4A4, 0x60BD, - 0xF4A5, 0x8655, 0xF4A6, 0x501C, 0xF4A7, 0xF9FF, 0xF4A8, 0x5254, 0xF4A9, 0x5C3A, 0xF4AA, 0x617D, 0xF4AB, 0x621A, 0xF4AC, 0x62D3, - 0xF4AD, 0x64F2, 0xF4AE, 0x65A5, 0xF4AF, 0x6ECC, 0xF4B0, 0x7620, 0xF4B1, 0x810A, 0xF4B2, 0x8E60, 0xF4B3, 0x965F, 0xF4B4, 0x96BB, - 0xF4B5, 0x4EDF, 0xF4B6, 0x5343, 0xF4B7, 0x5598, 0xF4B8, 0x5929, 0xF4B9, 0x5DDD, 0xF4BA, 0x64C5, 0xF4BB, 0x6CC9, 0xF4BC, 0x6DFA, - 0xF4BD, 0x7394, 0xF4BE, 0x7A7F, 0xF4BF, 0x821B, 0xF4C0, 0x85A6, 0xF4C1, 0x8CE4, 0xF4C2, 0x8E10, 0xF4C3, 0x9077, 0xF4C4, 0x91E7, - 0xF4C5, 0x95E1, 0xF4C6, 0x9621, 0xF4C7, 0x97C6, 0xF4C8, 0x51F8, 0xF4C9, 0x54F2, 0xF4CA, 0x5586, 0xF4CB, 0x5FB9, 0xF4CC, 0x64A4, - 0xF4CD, 0x6F88, 0xF4CE, 0x7DB4, 0xF4CF, 0x8F1F, 0xF4D0, 0x8F4D, 0xF4D1, 0x9435, 0xF4D2, 0x50C9, 0xF4D3, 0x5C16, 0xF4D4, 0x6CBE, - 0xF4D5, 0x6DFB, 0xF4D6, 0x751B, 0xF4D7, 0x77BB, 0xF4D8, 0x7C3D, 0xF4D9, 0x7C64, 0xF4DA, 0x8A79, 0xF4DB, 0x8AC2, 0xF4DC, 0x581E, - 0xF4DD, 0x59BE, 0xF4DE, 0x5E16, 0xF4DF, 0x6377, 0xF4E0, 0x7252, 0xF4E1, 0x758A, 0xF4E2, 0x776B, 0xF4E3, 0x8ADC, 0xF4E4, 0x8CBC, - 0xF4E5, 0x8F12, 0xF4E6, 0x5EF3, 0xF4E7, 0x6674, 0xF4E8, 0x6DF8, 0xF4E9, 0x807D, 0xF4EA, 0x83C1, 0xF4EB, 0x8ACB, 0xF4EC, 0x9751, - 0xF4ED, 0x9BD6, 0xF4EE, 0xFA00, 0xF4EF, 0x5243, 0xF4F0, 0x66FF, 0xF4F1, 0x6D95, 0xF4F2, 0x6EEF, 0xF4F3, 0x7DE0, 0xF4F4, 0x8AE6, - 0xF4F5, 0x902E, 0xF4F6, 0x905E, 0xF4F7, 0x9AD4, 0xF4F8, 0x521D, 0xF4F9, 0x527F, 0xF4FA, 0x54E8, 0xF4FB, 0x6194, 0xF4FC, 0x6284, - 0xF4FD, 0x62DB, 0xF4FE, 0x68A2, 0xF5A1, 0x6912, 0xF5A2, 0x695A, 0xF5A3, 0x6A35, 0xF5A4, 0x7092, 0xF5A5, 0x7126, 0xF5A6, 0x785D, - 0xF5A7, 0x7901, 0xF5A8, 0x790E, 0xF5A9, 0x79D2, 0xF5AA, 0x7A0D, 0xF5AB, 0x8096, 0xF5AC, 0x8278, 0xF5AD, 0x82D5, 0xF5AE, 0x8349, - 0xF5AF, 0x8549, 0xF5B0, 0x8C82, 0xF5B1, 0x8D85, 0xF5B2, 0x9162, 0xF5B3, 0x918B, 0xF5B4, 0x91AE, 0xF5B5, 0x4FC3, 0xF5B6, 0x56D1, - 0xF5B7, 0x71ED, 0xF5B8, 0x77D7, 0xF5B9, 0x8700, 0xF5BA, 0x89F8, 0xF5BB, 0x5BF8, 0xF5BC, 0x5FD6, 0xF5BD, 0x6751, 0xF5BE, 0x90A8, - 0xF5BF, 0x53E2, 0xF5C0, 0x585A, 0xF5C1, 0x5BF5, 0xF5C2, 0x60A4, 0xF5C3, 0x6181, 0xF5C4, 0x6460, 0xF5C5, 0x7E3D, 0xF5C6, 0x8070, - 0xF5C7, 0x8525, 0xF5C8, 0x9283, 0xF5C9, 0x64AE, 0xF5CA, 0x50AC, 0xF5CB, 0x5D14, 0xF5CC, 0x6700, 0xF5CD, 0x589C, 0xF5CE, 0x62BD, - 0xF5CF, 0x63A8, 0xF5D0, 0x690E, 0xF5D1, 0x6978, 0xF5D2, 0x6A1E, 0xF5D3, 0x6E6B, 0xF5D4, 0x76BA, 0xF5D5, 0x79CB, 0xF5D6, 0x82BB, - 0xF5D7, 0x8429, 0xF5D8, 0x8ACF, 0xF5D9, 0x8DA8, 0xF5DA, 0x8FFD, 0xF5DB, 0x9112, 0xF5DC, 0x914B, 0xF5DD, 0x919C, 0xF5DE, 0x9310, - 0xF5DF, 0x9318, 0xF5E0, 0x939A, 0xF5E1, 0x96DB, 0xF5E2, 0x9A36, 0xF5E3, 0x9C0D, 0xF5E4, 0x4E11, 0xF5E5, 0x755C, 0xF5E6, 0x795D, - 0xF5E7, 0x7AFA, 0xF5E8, 0x7B51, 0xF5E9, 0x7BC9, 0xF5EA, 0x7E2E, 0xF5EB, 0x84C4, 0xF5EC, 0x8E59, 0xF5ED, 0x8E74, 0xF5EE, 0x8EF8, - 0xF5EF, 0x9010, 0xF5F0, 0x6625, 0xF5F1, 0x693F, 0xF5F2, 0x7443, 0xF5F3, 0x51FA, 0xF5F4, 0x672E, 0xF5F5, 0x9EDC, 0xF5F6, 0x5145, - 0xF5F7, 0x5FE0, 0xF5F8, 0x6C96, 0xF5F9, 0x87F2, 0xF5FA, 0x885D, 0xF5FB, 0x8877, 0xF5FC, 0x60B4, 0xF5FD, 0x81B5, 0xF5FE, 0x8403, - 0xF6A1, 0x8D05, 0xF6A2, 0x53D6, 0xF6A3, 0x5439, 0xF6A4, 0x5634, 0xF6A5, 0x5A36, 0xF6A6, 0x5C31, 0xF6A7, 0x708A, 0xF6A8, 0x7FE0, - 0xF6A9, 0x805A, 0xF6AA, 0x8106, 0xF6AB, 0x81ED, 0xF6AC, 0x8DA3, 0xF6AD, 0x9189, 0xF6AE, 0x9A5F, 0xF6AF, 0x9DF2, 0xF6B0, 0x5074, - 0xF6B1, 0x4EC4, 0xF6B2, 0x53A0, 0xF6B3, 0x60FB, 0xF6B4, 0x6E2C, 0xF6B5, 0x5C64, 0xF6B6, 0x4F88, 0xF6B7, 0x5024, 0xF6B8, 0x55E4, - 0xF6B9, 0x5CD9, 0xF6BA, 0x5E5F, 0xF6BB, 0x6065, 0xF6BC, 0x6894, 0xF6BD, 0x6CBB, 0xF6BE, 0x6DC4, 0xF6BF, 0x71BE, 0xF6C0, 0x75D4, - 0xF6C1, 0x75F4, 0xF6C2, 0x7661, 0xF6C3, 0x7A1A, 0xF6C4, 0x7A49, 0xF6C5, 0x7DC7, 0xF6C6, 0x7DFB, 0xF6C7, 0x7F6E, 0xF6C8, 0x81F4, - 0xF6C9, 0x86A9, 0xF6CA, 0x8F1C, 0xF6CB, 0x96C9, 0xF6CC, 0x99B3, 0xF6CD, 0x9F52, 0xF6CE, 0x5247, 0xF6CF, 0x52C5, 0xF6D0, 0x98ED, - 0xF6D1, 0x89AA, 0xF6D2, 0x4E03, 0xF6D3, 0x67D2, 0xF6D4, 0x6F06, 0xF6D5, 0x4FB5, 0xF6D6, 0x5BE2, 0xF6D7, 0x6795, 0xF6D8, 0x6C88, - 0xF6D9, 0x6D78, 0xF6DA, 0x741B, 0xF6DB, 0x7827, 0xF6DC, 0x91DD, 0xF6DD, 0x937C, 0xF6DE, 0x87C4, 0xF6DF, 0x79E4, 0xF6E0, 0x7A31, - 0xF6E1, 0x5FEB, 0xF6E2, 0x4ED6, 0xF6E3, 0x54A4, 0xF6E4, 0x553E, 0xF6E5, 0x58AE, 0xF6E6, 0x59A5, 0xF6E7, 0x60F0, 0xF6E8, 0x6253, - 0xF6E9, 0x62D6, 0xF6EA, 0x6736, 0xF6EB, 0x6955, 0xF6EC, 0x8235, 0xF6ED, 0x9640, 0xF6EE, 0x99B1, 0xF6EF, 0x99DD, 0xF6F0, 0x502C, - 0xF6F1, 0x5353, 0xF6F2, 0x5544, 0xF6F3, 0x577C, 0xF6F4, 0xFA01, 0xF6F5, 0x6258, 0xF6F6, 0xFA02, 0xF6F7, 0x64E2, 0xF6F8, 0x666B, - 0xF6F9, 0x67DD, 0xF6FA, 0x6FC1, 0xF6FB, 0x6FEF, 0xF6FC, 0x7422, 0xF6FD, 0x7438, 0xF6FE, 0x8A17, 0xF7A1, 0x9438, 0xF7A2, 0x5451, - 0xF7A3, 0x5606, 0xF7A4, 0x5766, 0xF7A5, 0x5F48, 0xF7A6, 0x619A, 0xF7A7, 0x6B4E, 0xF7A8, 0x7058, 0xF7A9, 0x70AD, 0xF7AA, 0x7DBB, - 0xF7AB, 0x8A95, 0xF7AC, 0x596A, 0xF7AD, 0x812B, 0xF7AE, 0x63A2, 0xF7AF, 0x7708, 0xF7B0, 0x803D, 0xF7B1, 0x8CAA, 0xF7B2, 0x5854, - 0xF7B3, 0x642D, 0xF7B4, 0x69BB, 0xF7B5, 0x5B95, 0xF7B6, 0x5E11, 0xF7B7, 0x6E6F, 0xF7B8, 0xFA03, 0xF7B9, 0x8569, 0xF7BA, 0x514C, - 0xF7BB, 0x53F0, 0xF7BC, 0x592A, 0xF7BD, 0x6020, 0xF7BE, 0x614B, 0xF7BF, 0x6B86, 0xF7C0, 0x6C70, 0xF7C1, 0x6CF0, 0xF7C2, 0x7B1E, - 0xF7C3, 0x80CE, 0xF7C4, 0x82D4, 0xF7C5, 0x8DC6, 0xF7C6, 0x90B0, 0xF7C7, 0x98B1, 0xF7C8, 0xFA04, 0xF7C9, 0x64C7, 0xF7CA, 0x6FA4, - 0xF7CB, 0x6491, 0xF7CC, 0x6504, 0xF7CD, 0x514E, 0xF7CE, 0x5410, 0xF7CF, 0x571F, 0xF7D0, 0x8A0E, 0xF7D1, 0x615F, 0xF7D2, 0x6876, - 0xF7D3, 0xFA05, 0xF7D4, 0x75DB, 0xF7D5, 0x7B52, 0xF7D6, 0x7D71, 0xF7D7, 0x901A, 0xF7D8, 0x5806, 0xF7D9, 0x69CC, 0xF7DA, 0x817F, - 0xF7DB, 0x892A, 0xF7DC, 0x9000, 0xF7DD, 0x9839, 0xF7DE, 0x5078, 0xF7DF, 0x5957, 0xF7E0, 0x59AC, 0xF7E1, 0x6295, 0xF7E2, 0x900F, - 0xF7E3, 0x9B2A, 0xF7E4, 0x615D, 0xF7E5, 0x7279, 0xF7E6, 0x95D6, 0xF7E7, 0x5761, 0xF7E8, 0x5A46, 0xF7E9, 0x5DF4, 0xF7EA, 0x628A, - 0xF7EB, 0x64AD, 0xF7EC, 0x64FA, 0xF7ED, 0x6777, 0xF7EE, 0x6CE2, 0xF7EF, 0x6D3E, 0xF7F0, 0x722C, 0xF7F1, 0x7436, 0xF7F2, 0x7834, - 0xF7F3, 0x7F77, 0xF7F4, 0x82AD, 0xF7F5, 0x8DDB, 0xF7F6, 0x9817, 0xF7F7, 0x5224, 0xF7F8, 0x5742, 0xF7F9, 0x677F, 0xF7FA, 0x7248, - 0xF7FB, 0x74E3, 0xF7FC, 0x8CA9, 0xF7FD, 0x8FA6, 0xF7FE, 0x9211, 0xF8A1, 0x962A, 0xF8A2, 0x516B, 0xF8A3, 0x53ED, 0xF8A4, 0x634C, - 0xF8A5, 0x4F69, 0xF8A6, 0x5504, 0xF8A7, 0x6096, 0xF8A8, 0x6557, 0xF8A9, 0x6C9B, 0xF8AA, 0x6D7F, 0xF8AB, 0x724C, 0xF8AC, 0x72FD, - 0xF8AD, 0x7A17, 0xF8AE, 0x8987, 0xF8AF, 0x8C9D, 0xF8B0, 0x5F6D, 0xF8B1, 0x6F8E, 0xF8B2, 0x70F9, 0xF8B3, 0x81A8, 0xF8B4, 0x610E, - 0xF8B5, 0x4FBF, 0xF8B6, 0x504F, 0xF8B7, 0x6241, 0xF8B8, 0x7247, 0xF8B9, 0x7BC7, 0xF8BA, 0x7DE8, 0xF8BB, 0x7FE9, 0xF8BC, 0x904D, - 0xF8BD, 0x97AD, 0xF8BE, 0x9A19, 0xF8BF, 0x8CB6, 0xF8C0, 0x576A, 0xF8C1, 0x5E73, 0xF8C2, 0x67B0, 0xF8C3, 0x840D, 0xF8C4, 0x8A55, - 0xF8C5, 0x5420, 0xF8C6, 0x5B16, 0xF8C7, 0x5E63, 0xF8C8, 0x5EE2, 0xF8C9, 0x5F0A, 0xF8CA, 0x6583, 0xF8CB, 0x80BA, 0xF8CC, 0x853D, - 0xF8CD, 0x9589, 0xF8CE, 0x965B, 0xF8CF, 0x4F48, 0xF8D0, 0x5305, 0xF8D1, 0x530D, 0xF8D2, 0x530F, 0xF8D3, 0x5486, 0xF8D4, 0x54FA, - 0xF8D5, 0x5703, 0xF8D6, 0x5E03, 0xF8D7, 0x6016, 0xF8D8, 0x629B, 0xF8D9, 0x62B1, 0xF8DA, 0x6355, 0xF8DB, 0xFA06, 0xF8DC, 0x6CE1, - 0xF8DD, 0x6D66, 0xF8DE, 0x75B1, 0xF8DF, 0x7832, 0xF8E0, 0x80DE, 0xF8E1, 0x812F, 0xF8E2, 0x82DE, 0xF8E3, 0x8461, 0xF8E4, 0x84B2, - 0xF8E5, 0x888D, 0xF8E6, 0x8912, 0xF8E7, 0x900B, 0xF8E8, 0x92EA, 0xF8E9, 0x98FD, 0xF8EA, 0x9B91, 0xF8EB, 0x5E45, 0xF8EC, 0x66B4, - 0xF8ED, 0x66DD, 0xF8EE, 0x7011, 0xF8EF, 0x7206, 0xF8F0, 0xFA07, 0xF8F1, 0x4FF5, 0xF8F2, 0x527D, 0xF8F3, 0x5F6A, 0xF8F4, 0x6153, - 0xF8F5, 0x6753, 0xF8F6, 0x6A19, 0xF8F7, 0x6F02, 0xF8F8, 0x74E2, 0xF8F9, 0x7968, 0xF8FA, 0x8868, 0xF8FB, 0x8C79, 0xF8FC, 0x98C7, - 0xF8FD, 0x98C4, 0xF8FE, 0x9A43, 0xF9A1, 0x54C1, 0xF9A2, 0x7A1F, 0xF9A3, 0x6953, 0xF9A4, 0x8AF7, 0xF9A5, 0x8C4A, 0xF9A6, 0x98A8, - 0xF9A7, 0x99AE, 0xF9A8, 0x5F7C, 0xF9A9, 0x62AB, 0xF9AA, 0x75B2, 0xF9AB, 0x76AE, 0xF9AC, 0x88AB, 0xF9AD, 0x907F, 0xF9AE, 0x9642, - 0xF9AF, 0x5339, 0xF9B0, 0x5F3C, 0xF9B1, 0x5FC5, 0xF9B2, 0x6CCC, 0xF9B3, 0x73CC, 0xF9B4, 0x7562, 0xF9B5, 0x758B, 0xF9B6, 0x7B46, - 0xF9B7, 0x82FE, 0xF9B8, 0x999D, 0xF9B9, 0x4E4F, 0xF9BA, 0x903C, 0xF9BB, 0x4E0B, 0xF9BC, 0x4F55, 0xF9BD, 0x53A6, 0xF9BE, 0x590F, - 0xF9BF, 0x5EC8, 0xF9C0, 0x6630, 0xF9C1, 0x6CB3, 0xF9C2, 0x7455, 0xF9C3, 0x8377, 0xF9C4, 0x8766, 0xF9C5, 0x8CC0, 0xF9C6, 0x9050, - 0xF9C7, 0x971E, 0xF9C8, 0x9C15, 0xF9C9, 0x58D1, 0xF9CA, 0x5B78, 0xF9CB, 0x8650, 0xF9CC, 0x8B14, 0xF9CD, 0x9DB4, 0xF9CE, 0x5BD2, - 0xF9CF, 0x6068, 0xF9D0, 0x608D, 0xF9D1, 0x65F1, 0xF9D2, 0x6C57, 0xF9D3, 0x6F22, 0xF9D4, 0x6FA3, 0xF9D5, 0x701A, 0xF9D6, 0x7F55, - 0xF9D7, 0x7FF0, 0xF9D8, 0x9591, 0xF9D9, 0x9592, 0xF9DA, 0x9650, 0xF9DB, 0x97D3, 0xF9DC, 0x5272, 0xF9DD, 0x8F44, 0xF9DE, 0x51FD, - 0xF9DF, 0x542B, 0xF9E0, 0x54B8, 0xF9E1, 0x5563, 0xF9E2, 0x558A, 0xF9E3, 0x6ABB, 0xF9E4, 0x6DB5, 0xF9E5, 0x7DD8, 0xF9E6, 0x8266, - 0xF9E7, 0x929C, 0xF9E8, 0x9677, 0xF9E9, 0x9E79, 0xF9EA, 0x5408, 0xF9EB, 0x54C8, 0xF9EC, 0x76D2, 0xF9ED, 0x86E4, 0xF9EE, 0x95A4, - 0xF9EF, 0x95D4, 0xF9F0, 0x965C, 0xF9F1, 0x4EA2, 0xF9F2, 0x4F09, 0xF9F3, 0x59EE, 0xF9F4, 0x5AE6, 0xF9F5, 0x5DF7, 0xF9F6, 0x6052, - 0xF9F7, 0x6297, 0xF9F8, 0x676D, 0xF9F9, 0x6841, 0xF9FA, 0x6C86, 0xF9FB, 0x6E2F, 0xF9FC, 0x7F38, 0xF9FD, 0x809B, 0xF9FE, 0x822A, - 0xFAA1, 0xFA08, 0xFAA2, 0xFA09, 0xFAA3, 0x9805, 0xFAA4, 0x4EA5, 0xFAA5, 0x5055, 0xFAA6, 0x54B3, 0xFAA7, 0x5793, 0xFAA8, 0x595A, - 0xFAA9, 0x5B69, 0xFAAA, 0x5BB3, 0xFAAB, 0x61C8, 0xFAAC, 0x6977, 0xFAAD, 0x6D77, 0xFAAE, 0x7023, 0xFAAF, 0x87F9, 0xFAB0, 0x89E3, - 0xFAB1, 0x8A72, 0xFAB2, 0x8AE7, 0xFAB3, 0x9082, 0xFAB4, 0x99ED, 0xFAB5, 0x9AB8, 0xFAB6, 0x52BE, 0xFAB7, 0x6838, 0xFAB8, 0x5016, - 0xFAB9, 0x5E78, 0xFABA, 0x674F, 0xFABB, 0x8347, 0xFABC, 0x884C, 0xFABD, 0x4EAB, 0xFABE, 0x5411, 0xFABF, 0x56AE, 0xFAC0, 0x73E6, - 0xFAC1, 0x9115, 0xFAC2, 0x97FF, 0xFAC3, 0x9909, 0xFAC4, 0x9957, 0xFAC5, 0x9999, 0xFAC6, 0x5653, 0xFAC7, 0x589F, 0xFAC8, 0x865B, - 0xFAC9, 0x8A31, 0xFACA, 0x61B2, 0xFACB, 0x6AF6, 0xFACC, 0x737B, 0xFACD, 0x8ED2, 0xFACE, 0x6B47, 0xFACF, 0x96AA, 0xFAD0, 0x9A57, - 0xFAD1, 0x5955, 0xFAD2, 0x7200, 0xFAD3, 0x8D6B, 0xFAD4, 0x9769, 0xFAD5, 0x4FD4, 0xFAD6, 0x5CF4, 0xFAD7, 0x5F26, 0xFAD8, 0x61F8, - 0xFAD9, 0x665B, 0xFADA, 0x6CEB, 0xFADB, 0x70AB, 0xFADC, 0x7384, 0xFADD, 0x73B9, 0xFADE, 0x73FE, 0xFADF, 0x7729, 0xFAE0, 0x774D, - 0xFAE1, 0x7D43, 0xFAE2, 0x7D62, 0xFAE3, 0x7E23, 0xFAE4, 0x8237, 0xFAE5, 0x8852, 0xFAE6, 0xFA0A, 0xFAE7, 0x8CE2, 0xFAE8, 0x9249, - 0xFAE9, 0x986F, 0xFAEA, 0x5B51, 0xFAEB, 0x7A74, 0xFAEC, 0x8840, 0xFAED, 0x9801, 0xFAEE, 0x5ACC, 0xFAEF, 0x4FE0, 0xFAF0, 0x5354, - 0xFAF1, 0x593E, 0xFAF2, 0x5CFD, 0xFAF3, 0x633E, 0xFAF4, 0x6D79, 0xFAF5, 0x72F9, 0xFAF6, 0x8105, 0xFAF7, 0x8107, 0xFAF8, 0x83A2, - 0xFAF9, 0x92CF, 0xFAFA, 0x9830, 0xFAFB, 0x4EA8, 0xFAFC, 0x5144, 0xFAFD, 0x5211, 0xFAFE, 0x578B, 0xFBA1, 0x5F62, 0xFBA2, 0x6CC2, - 0xFBA3, 0x6ECE, 0xFBA4, 0x7005, 0xFBA5, 0x7050, 0xFBA6, 0x70AF, 0xFBA7, 0x7192, 0xFBA8, 0x73E9, 0xFBA9, 0x7469, 0xFBAA, 0x834A, - 0xFBAB, 0x87A2, 0xFBAC, 0x8861, 0xFBAD, 0x9008, 0xFBAE, 0x90A2, 0xFBAF, 0x93A3, 0xFBB0, 0x99A8, 0xFBB1, 0x516E, 0xFBB2, 0x5F57, - 0xFBB3, 0x60E0, 0xFBB4, 0x6167, 0xFBB5, 0x66B3, 0xFBB6, 0x8559, 0xFBB7, 0x8E4A, 0xFBB8, 0x91AF, 0xFBB9, 0x978B, 0xFBBA, 0x4E4E, - 0xFBBB, 0x4E92, 0xFBBC, 0x547C, 0xFBBD, 0x58D5, 0xFBBE, 0x58FA, 0xFBBF, 0x597D, 0xFBC0, 0x5CB5, 0xFBC1, 0x5F27, 0xFBC2, 0x6236, - 0xFBC3, 0x6248, 0xFBC4, 0x660A, 0xFBC5, 0x6667, 0xFBC6, 0x6BEB, 0xFBC7, 0x6D69, 0xFBC8, 0x6DCF, 0xFBC9, 0x6E56, 0xFBCA, 0x6EF8, - 0xFBCB, 0x6F94, 0xFBCC, 0x6FE0, 0xFBCD, 0x6FE9, 0xFBCE, 0x705D, 0xFBCF, 0x72D0, 0xFBD0, 0x7425, 0xFBD1, 0x745A, 0xFBD2, 0x74E0, - 0xFBD3, 0x7693, 0xFBD4, 0x795C, 0xFBD5, 0x7CCA, 0xFBD6, 0x7E1E, 0xFBD7, 0x80E1, 0xFBD8, 0x82A6, 0xFBD9, 0x846B, 0xFBDA, 0x84BF, - 0xFBDB, 0x864E, 0xFBDC, 0x865F, 0xFBDD, 0x8774, 0xFBDE, 0x8B77, 0xFBDF, 0x8C6A, 0xFBE0, 0x93AC, 0xFBE1, 0x9800, 0xFBE2, 0x9865, - 0xFBE3, 0x60D1, 0xFBE4, 0x6216, 0xFBE5, 0x9177, 0xFBE6, 0x5A5A, 0xFBE7, 0x660F, 0xFBE8, 0x6DF7, 0xFBE9, 0x6E3E, 0xFBEA, 0x743F, - 0xFBEB, 0x9B42, 0xFBEC, 0x5FFD, 0xFBED, 0x60DA, 0xFBEE, 0x7B0F, 0xFBEF, 0x54C4, 0xFBF0, 0x5F18, 0xFBF1, 0x6C5E, 0xFBF2, 0x6CD3, - 0xFBF3, 0x6D2A, 0xFBF4, 0x70D8, 0xFBF5, 0x7D05, 0xFBF6, 0x8679, 0xFBF7, 0x8A0C, 0xFBF8, 0x9D3B, 0xFBF9, 0x5316, 0xFBFA, 0x548C, - 0xFBFB, 0x5B05, 0xFBFC, 0x6A3A, 0xFBFD, 0x706B, 0xFBFE, 0x7575, 0xFCA1, 0x798D, 0xFCA2, 0x79BE, 0xFCA3, 0x82B1, 0xFCA4, 0x83EF, - 0xFCA5, 0x8A71, 0xFCA6, 0x8B41, 0xFCA7, 0x8CA8, 0xFCA8, 0x9774, 0xFCA9, 0xFA0B, 0xFCAA, 0x64F4, 0xFCAB, 0x652B, 0xFCAC, 0x78BA, - 0xFCAD, 0x78BB, 0xFCAE, 0x7A6B, 0xFCAF, 0x4E38, 0xFCB0, 0x559A, 0xFCB1, 0x5950, 0xFCB2, 0x5BA6, 0xFCB3, 0x5E7B, 0xFCB4, 0x60A3, - 0xFCB5, 0x63DB, 0xFCB6, 0x6B61, 0xFCB7, 0x6665, 0xFCB8, 0x6853, 0xFCB9, 0x6E19, 0xFCBA, 0x7165, 0xFCBB, 0x74B0, 0xFCBC, 0x7D08, - 0xFCBD, 0x9084, 0xFCBE, 0x9A69, 0xFCBF, 0x9C25, 0xFCC0, 0x6D3B, 0xFCC1, 0x6ED1, 0xFCC2, 0x733E, 0xFCC3, 0x8C41, 0xFCC4, 0x95CA, - 0xFCC5, 0x51F0, 0xFCC6, 0x5E4C, 0xFCC7, 0x5FA8, 0xFCC8, 0x604D, 0xFCC9, 0x60F6, 0xFCCA, 0x6130, 0xFCCB, 0x614C, 0xFCCC, 0x6643, - 0xFCCD, 0x6644, 0xFCCE, 0x69A5, 0xFCCF, 0x6CC1, 0xFCD0, 0x6E5F, 0xFCD1, 0x6EC9, 0xFCD2, 0x6F62, 0xFCD3, 0x714C, 0xFCD4, 0x749C, - 0xFCD5, 0x7687, 0xFCD6, 0x7BC1, 0xFCD7, 0x7C27, 0xFCD8, 0x8352, 0xFCD9, 0x8757, 0xFCDA, 0x9051, 0xFCDB, 0x968D, 0xFCDC, 0x9EC3, - 0xFCDD, 0x532F, 0xFCDE, 0x56DE, 0xFCDF, 0x5EFB, 0xFCE0, 0x5F8A, 0xFCE1, 0x6062, 0xFCE2, 0x6094, 0xFCE3, 0x61F7, 0xFCE4, 0x6666, - 0xFCE5, 0x6703, 0xFCE6, 0x6A9C, 0xFCE7, 0x6DEE, 0xFCE8, 0x6FAE, 0xFCE9, 0x7070, 0xFCEA, 0x736A, 0xFCEB, 0x7E6A, 0xFCEC, 0x81BE, - 0xFCED, 0x8334, 0xFCEE, 0x86D4, 0xFCEF, 0x8AA8, 0xFCF0, 0x8CC4, 0xFCF1, 0x5283, 0xFCF2, 0x7372, 0xFCF3, 0x5B96, 0xFCF4, 0x6A6B, - 0xFCF5, 0x9404, 0xFCF6, 0x54EE, 0xFCF7, 0x5686, 0xFCF8, 0x5B5D, 0xFCF9, 0x6548, 0xFCFA, 0x6585, 0xFCFB, 0x66C9, 0xFCFC, 0x689F, - 0xFCFD, 0x6D8D, 0xFCFE, 0x6DC6, 0xFDA1, 0x723B, 0xFDA2, 0x80B4, 0xFDA3, 0x9175, 0xFDA4, 0x9A4D, 0xFDA5, 0x4FAF, 0xFDA6, 0x5019, - 0xFDA7, 0x539A, 0xFDA8, 0x540E, 0xFDA9, 0x543C, 0xFDAA, 0x5589, 0xFDAB, 0x55C5, 0xFDAC, 0x5E3F, 0xFDAD, 0x5F8C, 0xFDAE, 0x673D, - 0xFDAF, 0x7166, 0xFDB0, 0x73DD, 0xFDB1, 0x9005, 0xFDB2, 0x52DB, 0xFDB3, 0x52F3, 0xFDB4, 0x5864, 0xFDB5, 0x58CE, 0xFDB6, 0x7104, - 0xFDB7, 0x718F, 0xFDB8, 0x71FB, 0xFDB9, 0x85B0, 0xFDBA, 0x8A13, 0xFDBB, 0x6688, 0xFDBC, 0x85A8, 0xFDBD, 0x55A7, 0xFDBE, 0x6684, - 0xFDBF, 0x714A, 0xFDC0, 0x8431, 0xFDC1, 0x5349, 0xFDC2, 0x5599, 0xFDC3, 0x6BC1, 0xFDC4, 0x5F59, 0xFDC5, 0x5FBD, 0xFDC6, 0x63EE, - 0xFDC7, 0x6689, 0xFDC8, 0x7147, 0xFDC9, 0x8AF1, 0xFDCA, 0x8F1D, 0xFDCB, 0x9EBE, 0xFDCC, 0x4F11, 0xFDCD, 0x643A, 0xFDCE, 0x70CB, - 0xFDCF, 0x7566, 0xFDD0, 0x8667, 0xFDD1, 0x6064, 0xFDD2, 0x8B4E, 0xFDD3, 0x9DF8, 0xFDD4, 0x5147, 0xFDD5, 0x51F6, 0xFDD6, 0x5308, - 0xFDD7, 0x6D36, 0xFDD8, 0x80F8, 0xFDD9, 0x9ED1, 0xFDDA, 0x6615, 0xFDDB, 0x6B23, 0xFDDC, 0x7098, 0xFDDD, 0x75D5, 0xFDDE, 0x5403, - 0xFDDF, 0x5C79, 0xFDE0, 0x7D07, 0xFDE1, 0x8A16, 0xFDE2, 0x6B20, 0xFDE3, 0x6B3D, 0xFDE4, 0x6B46, 0xFDE5, 0x5438, 0xFDE6, 0x6070, - 0xFDE7, 0x6D3D, 0xFDE8, 0x7FD5, 0xFDE9, 0x8208, 0xFDEA, 0x50D6, 0xFDEB, 0x51DE, 0xFDEC, 0x559C, 0xFDED, 0x566B, 0xFDEE, 0x56CD, - 0xFDEF, 0x59EC, 0xFDF0, 0x5B09, 0xFDF1, 0x5E0C, 0xFDF2, 0x6199, 0xFDF3, 0x6198, 0xFDF4, 0x6231, 0xFDF5, 0x665E, 0xFDF6, 0x66E6, - 0xFDF7, 0x7199, 0xFDF8, 0x71B9, 0xFDF9, 0x71BA, 0xFDFA, 0x72A7, 0xFDFB, 0x79A7, 0xFDFC, 0x7A00, 0xFDFD, 0x7FB2, 0xFDFE, 0x8A70, - 0, 0 -}; -#endif - -#if FF_CODE_PAGE == 950 || FF_CODE_PAGE == 0 /* Traditional Chinese */ -static const WCHAR uni2oem950[] = { /* Unicode --> Big5 pairs */ - 0x00A7, 0xA1B1, 0x00AF, 0xA1C2, 0x00B0, 0xA258, 0x00B1, 0xA1D3, 0x00B7, 0xA150, 0x00D7, 0xA1D1, 0x00F7, 0xA1D2, 0x02C7, 0xA3BE, - 0x02C9, 0xA3BC, 0x02CA, 0xA3BD, 0x02CB, 0xA3BF, 0x02CD, 0xA1C5, 0x02D9, 0xA3BB, 0x0391, 0xA344, 0x0392, 0xA345, 0x0393, 0xA346, - 0x0394, 0xA347, 0x0395, 0xA348, 0x0396, 0xA349, 0x0397, 0xA34A, 0x0398, 0xA34B, 0x0399, 0xA34C, 0x039A, 0xA34D, 0x039B, 0xA34E, - 0x039C, 0xA34F, 0x039D, 0xA350, 0x039E, 0xA351, 0x039F, 0xA352, 0x03A0, 0xA353, 0x03A1, 0xA354, 0x03A3, 0xA355, 0x03A4, 0xA356, - 0x03A5, 0xA357, 0x03A6, 0xA358, 0x03A7, 0xA359, 0x03A8, 0xA35A, 0x03A9, 0xA35B, 0x03B1, 0xA35C, 0x03B2, 0xA35D, 0x03B3, 0xA35E, - 0x03B4, 0xA35F, 0x03B5, 0xA360, 0x03B6, 0xA361, 0x03B7, 0xA362, 0x03B8, 0xA363, 0x03B9, 0xA364, 0x03BA, 0xA365, 0x03BB, 0xA366, - 0x03BC, 0xA367, 0x03BD, 0xA368, 0x03BE, 0xA369, 0x03BF, 0xA36A, 0x03C0, 0xA36B, 0x03C1, 0xA36C, 0x03C3, 0xA36D, 0x03C4, 0xA36E, - 0x03C5, 0xA36F, 0x03C6, 0xA370, 0x03C7, 0xA371, 0x03C8, 0xA372, 0x03C9, 0xA373, 0x2013, 0xA156, 0x2014, 0xA158, 0x2018, 0xA1A5, - 0x2019, 0xA1A6, 0x201C, 0xA1A7, 0x201D, 0xA1A8, 0x2025, 0xA14C, 0x2026, 0xA14B, 0x2027, 0xA145, 0x2032, 0xA1AC, 0x2035, 0xA1AB, - 0x203B, 0xA1B0, 0x20AC, 0xA3E1, 0x2103, 0xA24A, 0x2105, 0xA1C1, 0x2109, 0xA24B, 0x2160, 0xA2B9, 0x2161, 0xA2BA, 0x2162, 0xA2BB, - 0x2163, 0xA2BC, 0x2164, 0xA2BD, 0x2165, 0xA2BE, 0x2166, 0xA2BF, 0x2167, 0xA2C0, 0x2168, 0xA2C1, 0x2169, 0xA2C2, 0x2190, 0xA1F6, - 0x2191, 0xA1F4, 0x2192, 0xA1F7, 0x2193, 0xA1F5, 0x2196, 0xA1F8, 0x2197, 0xA1F9, 0x2198, 0xA1FB, 0x2199, 0xA1FA, 0x2215, 0xA241, - 0x221A, 0xA1D4, 0x221E, 0xA1DB, 0x221F, 0xA1E8, 0x2220, 0xA1E7, 0x2223, 0xA1FD, 0x2225, 0xA1FC, 0x2229, 0xA1E4, 0x222A, 0xA1E5, - 0x222B, 0xA1EC, 0x222E, 0xA1ED, 0x2234, 0xA1EF, 0x2235, 0xA1EE, 0x2252, 0xA1DC, 0x2260, 0xA1DA, 0x2261, 0xA1DD, 0x2266, 0xA1D8, - 0x2267, 0xA1D9, 0x2295, 0xA1F2, 0x2299, 0xA1F3, 0x22A5, 0xA1E6, 0x22BF, 0xA1E9, 0x2500, 0xA277, 0x2502, 0xA278, 0x250C, 0xA27A, - 0x2510, 0xA27B, 0x2514, 0xA27C, 0x2518, 0xA27D, 0x251C, 0xA275, 0x2524, 0xA274, 0x252C, 0xA273, 0x2534, 0xA272, 0x253C, 0xA271, - 0x2550, 0xA2A4, 0x2550, 0xF9F9, 0x2551, 0xF9F8, 0x2552, 0xF9E6, 0x2553, 0xF9EF, 0x2554, 0xF9DD, 0x2555, 0xF9E8, 0x2556, 0xF9F1, - 0x2557, 0xF9DF, 0x2558, 0xF9EC, 0x2559, 0xF9F5, 0x255A, 0xF9E3, 0x255B, 0xF9EE, 0x255C, 0xF9F7, 0x255D, 0xF9E5, 0x255E, 0xA2A5, - 0x255E, 0xF9E9, 0x255F, 0xF9F2, 0x2560, 0xF9E0, 0x2561, 0xA2A7, 0x2561, 0xF9EB, 0x2562, 0xF9F4, 0x2563, 0xF9E2, 0x2564, 0xF9E7, - 0x2565, 0xF9F0, 0x2566, 0xF9DE, 0x2567, 0xF9ED, 0x2568, 0xF9F6, 0x2569, 0xF9E4, 0x256A, 0xA2A6, 0x256A, 0xF9EA, 0x256B, 0xF9F3, - 0x256C, 0xF9E1, 0x256D, 0xA27E, 0x256D, 0xF9FA, 0x256E, 0xA2A1, 0x256E, 0xF9FB, 0x256F, 0xA2A3, 0x256F, 0xF9FD, 0x2570, 0xA2A2, - 0x2570, 0xF9FC, 0x2571, 0xA2AC, 0x2572, 0xA2AD, 0x2573, 0xA2AE, 0x2574, 0xA15A, 0x2581, 0xA262, 0x2582, 0xA263, 0x2583, 0xA264, - 0x2584, 0xA265, 0x2585, 0xA266, 0x2586, 0xA267, 0x2587, 0xA268, 0x2588, 0xA269, 0x2589, 0xA270, 0x258A, 0xA26F, 0x258B, 0xA26E, - 0x258C, 0xA26D, 0x258D, 0xA26C, 0x258E, 0xA26B, 0x258F, 0xA26A, 0x2593, 0xF9FE, 0x2594, 0xA276, 0x2595, 0xA279, 0x25A0, 0xA1BD, - 0x25A1, 0xA1BC, 0x25B2, 0xA1B6, 0x25B3, 0xA1B5, 0x25BC, 0xA1BF, 0x25BD, 0xA1BE, 0x25C6, 0xA1BB, 0x25C7, 0xA1BA, 0x25CB, 0xA1B3, - 0x25CE, 0xA1B7, 0x25CF, 0xA1B4, 0x25E2, 0xA2A8, 0x25E3, 0xA2A9, 0x25E4, 0xA2AB, 0x25E5, 0xA2AA, 0x2605, 0xA1B9, 0x2606, 0xA1B8, - 0x2640, 0xA1F0, 0x2642, 0xA1F1, 0x3000, 0xA140, 0x3001, 0xA142, 0x3002, 0xA143, 0x3003, 0xA1B2, 0x3008, 0xA171, 0x3009, 0xA172, - 0x300A, 0xA16D, 0x300B, 0xA16E, 0x300C, 0xA175, 0x300D, 0xA176, 0x300E, 0xA179, 0x300F, 0xA17A, 0x3010, 0xA169, 0x3011, 0xA16A, - 0x3012, 0xA245, 0x3014, 0xA165, 0x3015, 0xA166, 0x301D, 0xA1A9, 0x301E, 0xA1AA, 0x3021, 0xA2C3, 0x3022, 0xA2C4, 0x3023, 0xA2C5, - 0x3024, 0xA2C6, 0x3025, 0xA2C7, 0x3026, 0xA2C8, 0x3027, 0xA2C9, 0x3028, 0xA2CA, 0x3029, 0xA2CB, 0x3105, 0xA374, 0x3106, 0xA375, - 0x3107, 0xA376, 0x3108, 0xA377, 0x3109, 0xA378, 0x310A, 0xA379, 0x310B, 0xA37A, 0x310C, 0xA37B, 0x310D, 0xA37C, 0x310E, 0xA37D, - 0x310F, 0xA37E, 0x3110, 0xA3A1, 0x3111, 0xA3A2, 0x3112, 0xA3A3, 0x3113, 0xA3A4, 0x3114, 0xA3A5, 0x3115, 0xA3A6, 0x3116, 0xA3A7, - 0x3117, 0xA3A8, 0x3118, 0xA3A9, 0x3119, 0xA3AA, 0x311A, 0xA3AB, 0x311B, 0xA3AC, 0x311C, 0xA3AD, 0x311D, 0xA3AE, 0x311E, 0xA3AF, - 0x311F, 0xA3B0, 0x3120, 0xA3B1, 0x3121, 0xA3B2, 0x3122, 0xA3B3, 0x3123, 0xA3B4, 0x3124, 0xA3B5, 0x3125, 0xA3B6, 0x3126, 0xA3B7, - 0x3127, 0xA3B8, 0x3128, 0xA3B9, 0x3129, 0xA3BA, 0x32A3, 0xA1C0, 0x338E, 0xA255, 0x338F, 0xA256, 0x339C, 0xA250, 0x339D, 0xA251, - 0x339E, 0xA252, 0x33A1, 0xA254, 0x33C4, 0xA257, 0x33CE, 0xA253, 0x33D1, 0xA1EB, 0x33D2, 0xA1EA, 0x33D5, 0xA24F, 0x4E00, 0xA440, - 0x4E01, 0xA442, 0x4E03, 0xA443, 0x4E07, 0xC945, 0x4E08, 0xA456, 0x4E09, 0xA454, 0x4E0A, 0xA457, 0x4E0B, 0xA455, 0x4E0C, 0xC946, - 0x4E0D, 0xA4A3, 0x4E0E, 0xC94F, 0x4E0F, 0xC94D, 0x4E10, 0xA4A2, 0x4E11, 0xA4A1, 0x4E14, 0xA542, 0x4E15, 0xA541, 0x4E16, 0xA540, - 0x4E18, 0xA543, 0x4E19, 0xA4FE, 0x4E1E, 0xA5E0, 0x4E1F, 0xA5E1, 0x4E26, 0xA8C3, 0x4E2B, 0xA458, 0x4E2D, 0xA4A4, 0x4E2E, 0xC950, - 0x4E30, 0xA4A5, 0x4E31, 0xC963, 0x4E32, 0xA6EA, 0x4E33, 0xCBB1, 0x4E38, 0xA459, 0x4E39, 0xA4A6, 0x4E3B, 0xA544, 0x4E3C, 0xC964, - 0x4E42, 0xC940, 0x4E43, 0xA444, 0x4E45, 0xA45B, 0x4E47, 0xC947, 0x4E48, 0xA45C, 0x4E4B, 0xA4A7, 0x4E4D, 0xA545, 0x4E4E, 0xA547, - 0x4E4F, 0xA546, 0x4E52, 0xA5E2, 0x4E53, 0xA5E3, 0x4E56, 0xA8C4, 0x4E58, 0xADBC, 0x4E59, 0xA441, 0x4E5C, 0xC941, 0x4E5D, 0xA445, - 0x4E5E, 0xA45E, 0x4E5F, 0xA45D, 0x4E69, 0xA5E4, 0x4E73, 0xA8C5, 0x4E7E, 0xB0AE, 0x4E7F, 0xD44B, 0x4E82, 0xB6C3, 0x4E83, 0xDCB1, - 0x4E84, 0xDCB2, 0x4E86, 0xA446, 0x4E88, 0xA4A9, 0x4E8B, 0xA8C6, 0x4E8C, 0xA447, 0x4E8D, 0xC948, 0x4E8E, 0xA45F, 0x4E91, 0xA4AA, - 0x4E92, 0xA4AC, 0x4E93, 0xC951, 0x4E94, 0xA4AD, 0x4E95, 0xA4AB, 0x4E99, 0xA5E5, 0x4E9B, 0xA8C7, 0x4E9E, 0xA8C8, 0x4E9F, 0xAB45, - 0x4EA1, 0xA460, 0x4EA2, 0xA4AE, 0x4EA4, 0xA5E6, 0x4EA5, 0xA5E8, 0x4EA6, 0xA5E7, 0x4EA8, 0xA6EB, 0x4EAB, 0xA8C9, 0x4EAC, 0xA8CA, - 0x4EAD, 0xAB46, 0x4EAE, 0xAB47, 0x4EB3, 0xADBD, 0x4EB6, 0xDCB3, 0x4EB9, 0xF6D6, 0x4EBA, 0xA448, 0x4EC0, 0xA4B0, 0x4EC1, 0xA4AF, - 0x4EC2, 0xC952, 0x4EC3, 0xA4B1, 0x4EC4, 0xA4B7, 0x4EC6, 0xA4B2, 0x4EC7, 0xA4B3, 0x4EC8, 0xC954, 0x4EC9, 0xC953, 0x4ECA, 0xA4B5, - 0x4ECB, 0xA4B6, 0x4ECD, 0xA4B4, 0x4ED4, 0xA54A, 0x4ED5, 0xA54B, 0x4ED6, 0xA54C, 0x4ED7, 0xA54D, 0x4ED8, 0xA549, 0x4ED9, 0xA550, - 0x4EDA, 0xC96A, 0x4EDC, 0xC966, 0x4EDD, 0xC969, 0x4EDE, 0xA551, 0x4EDF, 0xA561, 0x4EE1, 0xC968, 0x4EE3, 0xA54E, 0x4EE4, 0xA54F, - 0x4EE5, 0xA548, 0x4EE8, 0xC965, 0x4EE9, 0xC967, 0x4EF0, 0xA5F5, 0x4EF1, 0xC9B0, 0x4EF2, 0xA5F2, 0x4EF3, 0xA5F6, 0x4EF4, 0xC9BA, - 0x4EF5, 0xC9AE, 0x4EF6, 0xA5F3, 0x4EF7, 0xC9B2, 0x4EFB, 0xA5F4, 0x4EFD, 0xA5F7, 0x4EFF, 0xA5E9, 0x4F00, 0xC9B1, 0x4F01, 0xA5F8, - 0x4F02, 0xC9B5, 0x4F04, 0xC9B9, 0x4F05, 0xC9B6, 0x4F08, 0xC9B3, 0x4F09, 0xA5EA, 0x4F0A, 0xA5EC, 0x4F0B, 0xA5F9, 0x4F0D, 0xA5EE, - 0x4F0E, 0xC9AB, 0x4F0F, 0xA5F1, 0x4F10, 0xA5EF, 0x4F11, 0xA5F0, 0x4F12, 0xC9BB, 0x4F13, 0xC9B8, 0x4F14, 0xC9AF, 0x4F15, 0xA5ED, - 0x4F18, 0xC9AC, 0x4F19, 0xA5EB, 0x4F1D, 0xC9B4, 0x4F22, 0xC9B7, 0x4F2C, 0xC9AD, 0x4F2D, 0xCA66, 0x4F2F, 0xA742, 0x4F30, 0xA6F4, - 0x4F33, 0xCA67, 0x4F34, 0xA6F1, 0x4F36, 0xA744, 0x4F38, 0xA6F9, 0x4F3A, 0xA6F8, 0x4F3B, 0xCA5B, 0x4F3C, 0xA6FC, 0x4F3D, 0xA6F7, - 0x4F3E, 0xCA60, 0x4F3F, 0xCA68, 0x4F41, 0xCA64, 0x4F43, 0xA6FA, 0x4F46, 0xA6FD, 0x4F47, 0xA6EE, 0x4F48, 0xA747, 0x4F49, 0xCA5D, - 0x4F4C, 0xCBBD, 0x4F4D, 0xA6EC, 0x4F4E, 0xA743, 0x4F4F, 0xA6ED, 0x4F50, 0xA6F5, 0x4F51, 0xA6F6, 0x4F52, 0xCA62, 0x4F53, 0xCA5E, - 0x4F54, 0xA6FB, 0x4F55, 0xA6F3, 0x4F56, 0xCA5A, 0x4F57, 0xA6EF, 0x4F58, 0xCA65, 0x4F59, 0xA745, 0x4F5A, 0xA748, 0x4F5B, 0xA6F2, - 0x4F5C, 0xA740, 0x4F5D, 0xA746, 0x4F5E, 0xA6F0, 0x4F5F, 0xCA63, 0x4F60, 0xA741, 0x4F61, 0xCA69, 0x4F62, 0xCA5C, 0x4F63, 0xA6FE, - 0x4F64, 0xCA5F, 0x4F67, 0xCA61, 0x4F69, 0xA8D8, 0x4F6A, 0xCBBF, 0x4F6B, 0xCBCB, 0x4F6C, 0xA8D0, 0x4F6E, 0xCBCC, 0x4F6F, 0xA8CB, - 0x4F70, 0xA8D5, 0x4F73, 0xA8CE, 0x4F74, 0xCBB9, 0x4F75, 0xA8D6, 0x4F76, 0xCBB8, 0x4F77, 0xCBBC, 0x4F78, 0xCBC3, 0x4F79, 0xCBC1, - 0x4F7A, 0xA8DE, 0x4F7B, 0xA8D9, 0x4F7C, 0xCBB3, 0x4F7D, 0xCBB5, 0x4F7E, 0xA8DB, 0x4F7F, 0xA8CF, 0x4F80, 0xCBB6, 0x4F81, 0xCBC2, - 0x4F82, 0xCBC9, 0x4F83, 0xA8D4, 0x4F84, 0xCBBB, 0x4F85, 0xCBB4, 0x4F86, 0xA8D3, 0x4F87, 0xCBB7, 0x4F88, 0xA8D7, 0x4F89, 0xCBBA, - 0x4F8B, 0xA8D2, 0x4F8D, 0xA8CD, 0x4F8F, 0xA8DC, 0x4F90, 0xCBC4, 0x4F91, 0xA8DD, 0x4F92, 0xCBC8, 0x4F94, 0xCBC6, 0x4F95, 0xCBCA, - 0x4F96, 0xA8DA, 0x4F97, 0xCBBE, 0x4F98, 0xCBB2, 0x4F9A, 0xCBC0, 0x4F9B, 0xA8D1, 0x4F9C, 0xCBC5, 0x4F9D, 0xA8CC, 0x4F9E, 0xCBC7, - 0x4FAE, 0xAB56, 0x4FAF, 0xAB4A, 0x4FB2, 0xCDE0, 0x4FB3, 0xCDE8, 0x4FB5, 0xAB49, 0x4FB6, 0xAB51, 0x4FB7, 0xAB5D, 0x4FB9, 0xCDEE, - 0x4FBA, 0xCDEC, 0x4FBB, 0xCDE7, 0x4FBF, 0xAB4B, 0x4FC0, 0xCDED, 0x4FC1, 0xCDE3, 0x4FC2, 0xAB59, 0x4FC3, 0xAB50, 0x4FC4, 0xAB58, - 0x4FC5, 0xCDDE, 0x4FC7, 0xCDEA, 0x4FC9, 0xCDE1, 0x4FCA, 0xAB54, 0x4FCB, 0xCDE2, 0x4FCD, 0xCDDD, 0x4FCE, 0xAB5B, 0x4FCF, 0xAB4E, - 0x4FD0, 0xAB57, 0x4FD1, 0xAB4D, 0x4FD3, 0xCDDF, 0x4FD4, 0xCDE4, 0x4FD6, 0xCDEB, 0x4FD7, 0xAB55, 0x4FD8, 0xAB52, 0x4FD9, 0xCDE6, - 0x4FDA, 0xAB5A, 0x4FDB, 0xCDE9, 0x4FDC, 0xCDE5, 0x4FDD, 0xAB4F, 0x4FDE, 0xAB5C, 0x4FDF, 0xAB53, 0x4FE0, 0xAB4C, 0x4FE1, 0xAB48, - 0x4FEC, 0xCDEF, 0x4FEE, 0xADD7, 0x4FEF, 0xADC1, 0x4FF1, 0xADD1, 0x4FF3, 0xADD6, 0x4FF4, 0xD0D0, 0x4FF5, 0xD0CF, 0x4FF6, 0xD0D4, - 0x4FF7, 0xD0D5, 0x4FF8, 0xADC4, 0x4FFA, 0xADCD, 0x4FFE, 0xADDA, 0x5000, 0xADCE, 0x5005, 0xD0C9, 0x5006, 0xADC7, 0x5007, 0xD0CA, - 0x5009, 0xADDC, 0x500B, 0xADD3, 0x500C, 0xADBE, 0x500D, 0xADBF, 0x500E, 0xD0DD, 0x500F, 0xB0BF, 0x5011, 0xADCC, 0x5012, 0xADCB, - 0x5013, 0xD0CB, 0x5014, 0xADCF, 0x5015, 0xD45B, 0x5016, 0xADC6, 0x5017, 0xD0D6, 0x5018, 0xADD5, 0x5019, 0xADD4, 0x501A, 0xADCA, - 0x501B, 0xD0CE, 0x501C, 0xD0D7, 0x501E, 0xD0C8, 0x501F, 0xADC9, 0x5020, 0xD0D8, 0x5021, 0xADD2, 0x5022, 0xD0CC, 0x5023, 0xADC0, - 0x5025, 0xADC3, 0x5026, 0xADC2, 0x5027, 0xD0D9, 0x5028, 0xADD0, 0x5029, 0xADC5, 0x502A, 0xADD9, 0x502B, 0xADDB, 0x502C, 0xD0D3, - 0x502D, 0xADD8, 0x502F, 0xD0DB, 0x5030, 0xD0CD, 0x5031, 0xD0DC, 0x5033, 0xD0D1, 0x5035, 0xD0DA, 0x5037, 0xD0D2, 0x503C, 0xADC8, - 0x5040, 0xD463, 0x5041, 0xD457, 0x5043, 0xB0B3, 0x5045, 0xD45C, 0x5046, 0xD462, 0x5047, 0xB0B2, 0x5048, 0xD455, 0x5049, 0xB0B6, - 0x504A, 0xD459, 0x504B, 0xD452, 0x504C, 0xB0B4, 0x504D, 0xD456, 0x504E, 0xB0B9, 0x504F, 0xB0BE, 0x5051, 0xD467, 0x5053, 0xD451, - 0x5055, 0xB0BA, 0x5057, 0xD466, 0x505A, 0xB0B5, 0x505B, 0xD458, 0x505C, 0xB0B1, 0x505D, 0xD453, 0x505E, 0xD44F, 0x505F, 0xD45D, - 0x5060, 0xD450, 0x5061, 0xD44E, 0x5062, 0xD45A, 0x5063, 0xD460, 0x5064, 0xD461, 0x5065, 0xB0B7, 0x5068, 0xD85B, 0x5069, 0xD45E, - 0x506A, 0xD44D, 0x506B, 0xD45F, 0x506D, 0xB0C1, 0x506E, 0xD464, 0x506F, 0xB0C0, 0x5070, 0xD44C, 0x5072, 0xD454, 0x5073, 0xD465, - 0x5074, 0xB0BC, 0x5075, 0xB0BB, 0x5076, 0xB0B8, 0x5077, 0xB0BD, 0x507A, 0xB0AF, 0x507D, 0xB0B0, 0x5080, 0xB3C8, 0x5082, 0xD85E, - 0x5083, 0xD857, 0x5085, 0xB3C5, 0x5087, 0xD85F, 0x508B, 0xD855, 0x508C, 0xD858, 0x508D, 0xB3C4, 0x508E, 0xD859, 0x5091, 0xB3C7, - 0x5092, 0xD85D, 0x5094, 0xD853, 0x5095, 0xD852, 0x5096, 0xB3C9, 0x5098, 0xB3CA, 0x5099, 0xB3C6, 0x509A, 0xB3CB, 0x509B, 0xD851, - 0x509C, 0xD85C, 0x509D, 0xD85A, 0x509E, 0xD854, 0x50A2, 0xB3C3, 0x50A3, 0xD856, 0x50AC, 0xB6CA, 0x50AD, 0xB6C4, 0x50AE, 0xDCB7, - 0x50AF, 0xB6CD, 0x50B0, 0xDCBD, 0x50B1, 0xDCC0, 0x50B2, 0xB6C6, 0x50B3, 0xB6C7, 0x50B4, 0xDCBA, 0x50B5, 0xB6C5, 0x50B6, 0xDCC3, - 0x50B7, 0xB6CB, 0x50B8, 0xDCC4, 0x50BA, 0xDCBF, 0x50BB, 0xB6CC, 0x50BD, 0xDCB4, 0x50BE, 0xB6C9, 0x50BF, 0xDCB5, 0x50C1, 0xDCBE, - 0x50C2, 0xDCBC, 0x50C4, 0xDCB8, 0x50C5, 0xB6C8, 0x50C6, 0xDCB6, 0x50C7, 0xB6CE, 0x50C8, 0xDCBB, 0x50C9, 0xDCC2, 0x50CA, 0xDCB9, - 0x50CB, 0xDCC1, 0x50CE, 0xB9B6, 0x50CF, 0xB9B3, 0x50D1, 0xB9B4, 0x50D3, 0xE0F9, 0x50D4, 0xE0F1, 0x50D5, 0xB9B2, 0x50D6, 0xB9AF, - 0x50D7, 0xE0F2, 0x50DA, 0xB9B1, 0x50DB, 0xE0F5, 0x50DD, 0xE0F7, 0x50E0, 0xE0FE, 0x50E3, 0xE0FD, 0x50E4, 0xE0F8, 0x50E5, 0xB9AE, - 0x50E6, 0xE0F0, 0x50E7, 0xB9AC, 0x50E8, 0xE0F3, 0x50E9, 0xB9B7, 0x50EA, 0xE0F6, 0x50EC, 0xE0FA, 0x50ED, 0xB9B0, 0x50EE, 0xB9AD, - 0x50EF, 0xE0FC, 0x50F0, 0xE0FB, 0x50F1, 0xB9B5, 0x50F3, 0xE0F4, 0x50F5, 0xBBF8, 0x50F6, 0xE4EC, 0x50F8, 0xE4E9, 0x50F9, 0xBBF9, - 0x50FB, 0xBBF7, 0x50FD, 0xE4F0, 0x50FE, 0xE4ED, 0x50FF, 0xE4E6, 0x5100, 0xBBF6, 0x5102, 0xBBFA, 0x5103, 0xE4E7, 0x5104, 0xBBF5, - 0x5105, 0xBBFD, 0x5106, 0xE4EA, 0x5107, 0xE4EB, 0x5108, 0xBBFB, 0x5109, 0xBBFC, 0x510A, 0xE4F1, 0x510B, 0xE4EE, 0x510C, 0xE4EF, - 0x5110, 0xBEAA, 0x5111, 0xE8F8, 0x5112, 0xBEA7, 0x5113, 0xE8F5, 0x5114, 0xBEA9, 0x5115, 0xBEAB, 0x5117, 0xE8F6, 0x5118, 0xBEA8, - 0x511A, 0xE8F7, 0x511C, 0xE8F4, 0x511F, 0xC076, 0x5120, 0xECBD, 0x5121, 0xC077, 0x5122, 0xECBB, 0x5124, 0xECBC, 0x5125, 0xECBA, - 0x5126, 0xECB9, 0x5129, 0xECBE, 0x512A, 0xC075, 0x512D, 0xEFB8, 0x512E, 0xEFB9, 0x5130, 0xE4E8, 0x5131, 0xEFB7, 0x5132, 0xC078, - 0x5133, 0xC35F, 0x5134, 0xF1EB, 0x5135, 0xF1EC, 0x5137, 0xC4D7, 0x5138, 0xC4D8, 0x5139, 0xF5C1, 0x513A, 0xF5C0, 0x513B, 0xC56C, - 0x513C, 0xC56B, 0x513D, 0xF7D0, 0x513F, 0xA449, 0x5140, 0xA461, 0x5141, 0xA4B9, 0x5143, 0xA4B8, 0x5144, 0xA553, 0x5145, 0xA552, - 0x5146, 0xA5FC, 0x5147, 0xA5FB, 0x5148, 0xA5FD, 0x5149, 0xA5FA, 0x514B, 0xA74A, 0x514C, 0xA749, 0x514D, 0xA74B, 0x5152, 0xA8E0, - 0x5154, 0xA8DF, 0x5155, 0xA8E1, 0x5157, 0xAB5E, 0x5159, 0xA259, 0x515A, 0xD0DE, 0x515B, 0xA25A, 0x515C, 0xB0C2, 0x515D, 0xA25C, - 0x515E, 0xA25B, 0x515F, 0xD860, 0x5161, 0xA25D, 0x5162, 0xB9B8, 0x5163, 0xA25E, 0x5165, 0xA44A, 0x5167, 0xA4BA, 0x5168, 0xA5FE, - 0x5169, 0xA8E2, 0x516B, 0xA44B, 0x516C, 0xA4BD, 0x516D, 0xA4BB, 0x516E, 0xA4BC, 0x5171, 0xA640, 0x5175, 0xA74C, 0x5176, 0xA8E4, - 0x5177, 0xA8E3, 0x5178, 0xA8E5, 0x517C, 0xADDD, 0x5180, 0xBEAC, 0x5187, 0xC94E, 0x5189, 0xA554, 0x518A, 0xA555, 0x518D, 0xA641, - 0x518F, 0xCA6A, 0x5191, 0xAB60, 0x5192, 0xAB5F, 0x5193, 0xD0E0, 0x5194, 0xD0DF, 0x5195, 0xB0C3, 0x5197, 0xA4BE, 0x5198, 0xC955, - 0x519E, 0xCBCD, 0x51A0, 0xAB61, 0x51A2, 0xADE0, 0x51A4, 0xADDE, 0x51A5, 0xADDF, 0x51AA, 0xBEAD, 0x51AC, 0xA556, 0x51B0, 0xA642, - 0x51B1, 0xC9BC, 0x51B6, 0xA74D, 0x51B7, 0xA74E, 0x51B9, 0xCA6B, 0x51BC, 0xCBCE, 0x51BD, 0xA8E6, 0x51BE, 0xCBCF, 0x51C4, 0xD0E2, - 0x51C5, 0xD0E3, 0x51C6, 0xADE3, 0x51C8, 0xD0E4, 0x51CA, 0xD0E1, 0x51CB, 0xADE4, 0x51CC, 0xADE2, 0x51CD, 0xADE1, 0x51CE, 0xD0E5, - 0x51D0, 0xD468, 0x51D4, 0xD861, 0x51D7, 0xDCC5, 0x51D8, 0xE140, 0x51DC, 0xBBFE, 0x51DD, 0xBEAE, 0x51DE, 0xE8F9, 0x51E0, 0xA44C, - 0x51E1, 0xA45A, 0x51F0, 0xB0C4, 0x51F1, 0xB3CD, 0x51F3, 0xB9B9, 0x51F5, 0xC942, 0x51F6, 0xA4BF, 0x51F8, 0xA559, 0x51F9, 0xA557, - 0x51FA, 0xA558, 0x51FD, 0xA8E7, 0x5200, 0xA44D, 0x5201, 0xA44E, 0x5203, 0xA462, 0x5206, 0xA4C0, 0x5207, 0xA4C1, 0x5208, 0xA4C2, - 0x5209, 0xC9BE, 0x520A, 0xA55A, 0x520C, 0xC96B, 0x520E, 0xA646, 0x5210, 0xC9BF, 0x5211, 0xA644, 0x5212, 0xA645, 0x5213, 0xC9BD, - 0x5216, 0xA647, 0x5217, 0xA643, 0x521C, 0xCA6C, 0x521D, 0xAAEC, 0x521E, 0xCA6D, 0x5221, 0xCA6E, 0x5224, 0xA750, 0x5225, 0xA74F, - 0x5228, 0xA753, 0x5229, 0xA751, 0x522A, 0xA752, 0x522E, 0xA8ED, 0x5230, 0xA8EC, 0x5231, 0xCBD4, 0x5232, 0xCBD1, 0x5233, 0xCBD2, - 0x5235, 0xCBD0, 0x5236, 0xA8EE, 0x5237, 0xA8EA, 0x5238, 0xA8E9, 0x523A, 0xA8EB, 0x523B, 0xA8E8, 0x5241, 0xA8EF, 0x5243, 0xAB63, - 0x5244, 0xCDF0, 0x5246, 0xCBD3, 0x5247, 0xAB68, 0x5249, 0xCDF1, 0x524A, 0xAB64, 0x524B, 0xAB67, 0x524C, 0xAB66, 0x524D, 0xAB65, - 0x524E, 0xAB62, 0x5252, 0xD0E8, 0x5254, 0xADE7, 0x5255, 0xD0EB, 0x5256, 0xADE5, 0x525A, 0xD0E7, 0x525B, 0xADE8, 0x525C, 0xADE6, - 0x525D, 0xADE9, 0x525E, 0xD0E9, 0x525F, 0xD0EA, 0x5261, 0xD0E6, 0x5262, 0xD0EC, 0x5269, 0xB3D1, 0x526A, 0xB0C5, 0x526B, 0xD469, - 0x526C, 0xD46B, 0x526D, 0xD46A, 0x526E, 0xD46C, 0x526F, 0xB0C6, 0x5272, 0xB3CE, 0x5274, 0xB3CF, 0x5275, 0xB3D0, 0x5277, 0xB6D0, - 0x5278, 0xDCC7, 0x527A, 0xDCC6, 0x527B, 0xDCC8, 0x527C, 0xDCC9, 0x527D, 0xB6D1, 0x527F, 0xB6CF, 0x5280, 0xE141, 0x5281, 0xE142, - 0x5282, 0xB9BB, 0x5283, 0xB9BA, 0x5284, 0xE35A, 0x5287, 0xBC40, 0x5288, 0xBC41, 0x5289, 0xBC42, 0x528A, 0xBC44, 0x528B, 0xE4F2, - 0x528C, 0xE4F3, 0x528D, 0xBC43, 0x5291, 0xBEAF, 0x5293, 0xBEB0, 0x5296, 0xF1ED, 0x5297, 0xF5C3, 0x5298, 0xF5C2, 0x5299, 0xF7D1, - 0x529B, 0xA44F, 0x529F, 0xA55C, 0x52A0, 0xA55B, 0x52A3, 0xA648, 0x52A6, 0xC9C0, 0x52A9, 0xA755, 0x52AA, 0xA756, 0x52AB, 0xA754, - 0x52AC, 0xA757, 0x52AD, 0xCA6F, 0x52AE, 0xCA70, 0x52BB, 0xA8F1, 0x52BC, 0xCBD5, 0x52BE, 0xA8F0, 0x52C0, 0xCDF2, 0x52C1, 0xAB6C, - 0x52C2, 0xCDF3, 0x52C3, 0xAB6B, 0x52C7, 0xAB69, 0x52C9, 0xAB6A, 0x52CD, 0xD0ED, 0x52D2, 0xB0C7, 0x52D3, 0xD46E, 0x52D5, 0xB0CA, - 0x52D6, 0xD46D, 0x52D7, 0xB1E5, 0x52D8, 0xB0C9, 0x52D9, 0xB0C8, 0x52DB, 0xB3D4, 0x52DD, 0xB3D3, 0x52DE, 0xB3D2, 0x52DF, 0xB6D2, - 0x52E2, 0xB6D5, 0x52E3, 0xB6D6, 0x52E4, 0xB6D4, 0x52E6, 0xB6D3, 0x52E9, 0xE143, 0x52EB, 0xE144, 0x52EF, 0xE4F5, 0x52F0, 0xBC45, - 0x52F1, 0xE4F4, 0x52F3, 0xBEB1, 0x52F4, 0xECBF, 0x52F5, 0xC079, 0x52F7, 0xF1EE, 0x52F8, 0xC455, 0x52FA, 0xA463, 0x52FB, 0xA4C3, - 0x52FC, 0xC956, 0x52FE, 0xA4C4, 0x52FF, 0xA4C5, 0x5305, 0xA55D, 0x5306, 0xA55E, 0x5308, 0xA649, 0x5309, 0xCA71, 0x530A, 0xCBD6, - 0x530B, 0xCBD7, 0x530D, 0xAB6D, 0x530E, 0xD0EE, 0x530F, 0xB0CC, 0x5310, 0xB0CB, 0x5311, 0xD863, 0x5312, 0xD862, 0x5315, 0xA450, - 0x5316, 0xA4C6, 0x5317, 0xA55F, 0x5319, 0xB0CD, 0x531A, 0xC943, 0x531C, 0xC96C, 0x531D, 0xA560, 0x531F, 0xC9C2, 0x5320, 0xA64B, - 0x5321, 0xA64A, 0x5322, 0xC9C1, 0x5323, 0xA758, 0x532A, 0xADEA, 0x532D, 0xD46F, 0x532F, 0xB6D7, 0x5330, 0xE145, 0x5331, 0xB9BC, - 0x5334, 0xE8FA, 0x5337, 0xF3FD, 0x5339, 0xA4C7, 0x533C, 0xCBD8, 0x533D, 0xCDF4, 0x533E, 0xB0D0, 0x533F, 0xB0CE, 0x5340, 0xB0CF, - 0x5341, 0xA2CC, 0x5341, 0xA451, 0x5343, 0xA464, 0x5344, 0xA2CD, 0x5345, 0xA2CE, 0x5345, 0xA4CA, 0x5347, 0xA4C9, 0x5348, 0xA4C8, - 0x5349, 0xA563, 0x534A, 0xA562, 0x534C, 0xC96D, 0x534D, 0xC9C3, 0x5351, 0xA8F5, 0x5352, 0xA8F2, 0x5353, 0xA8F4, 0x5354, 0xA8F3, - 0x5357, 0xAB6E, 0x535A, 0xB3D5, 0x535C, 0xA452, 0x535E, 0xA4CB, 0x5360, 0xA565, 0x5361, 0xA564, 0x5363, 0xCA72, 0x5366, 0xA8F6, - 0x536C, 0xC957, 0x536E, 0xA567, 0x536F, 0xA566, 0x5370, 0xA64C, 0x5371, 0xA64D, 0x5372, 0xCA73, 0x5373, 0xA759, 0x5375, 0xA75A, - 0x5377, 0xA8F7, 0x5378, 0xA8F8, 0x5379, 0xA8F9, 0x537B, 0xAB6F, 0x537C, 0xCDF5, 0x537F, 0xADEB, 0x5382, 0xC944, 0x5384, 0xA4CC, - 0x538A, 0xC9C4, 0x538E, 0xCA74, 0x538F, 0xCA75, 0x5392, 0xCBD9, 0x5394, 0xCBDA, 0x5396, 0xCDF7, 0x5397, 0xCDF6, 0x5398, 0xCDF9, - 0x5399, 0xCDF8, 0x539A, 0xAB70, 0x539C, 0xD470, 0x539D, 0xADED, 0x539E, 0xD0EF, 0x539F, 0xADEC, 0x53A4, 0xD864, 0x53A5, 0xB3D6, - 0x53A7, 0xD865, 0x53AC, 0xE146, 0x53AD, 0xB9BD, 0x53B2, 0xBC46, 0x53B4, 0xF1EF, 0x53B9, 0xC958, 0x53BB, 0xA568, 0x53C3, 0xB0D1, - 0x53C8, 0xA453, 0x53C9, 0xA465, 0x53CA, 0xA4CE, 0x53CB, 0xA4CD, 0x53CD, 0xA4CF, 0x53D4, 0xA8FB, 0x53D6, 0xA8FA, 0x53D7, 0xA8FC, - 0x53DB, 0xAB71, 0x53DF, 0xADEE, 0x53E1, 0xE8FB, 0x53E2, 0xC24F, 0x53E3, 0xA466, 0x53E4, 0xA56A, 0x53E5, 0xA579, 0x53E6, 0xA574, - 0x53E8, 0xA56F, 0x53E9, 0xA56E, 0x53EA, 0xA575, 0x53EB, 0xA573, 0x53EC, 0xA56C, 0x53ED, 0xA57A, 0x53EE, 0xA56D, 0x53EF, 0xA569, - 0x53F0, 0xA578, 0x53F1, 0xA577, 0x53F2, 0xA576, 0x53F3, 0xA56B, 0x53F5, 0xA572, 0x53F8, 0xA571, 0x53FB, 0xA57B, 0x53FC, 0xA570, - 0x5401, 0xA653, 0x5403, 0xA659, 0x5404, 0xA655, 0x5406, 0xA65B, 0x5407, 0xC9C5, 0x5408, 0xA658, 0x5409, 0xA64E, 0x540A, 0xA651, - 0x540B, 0xA654, 0x540C, 0xA650, 0x540D, 0xA657, 0x540E, 0xA65A, 0x540F, 0xA64F, 0x5410, 0xA652, 0x5411, 0xA656, 0x5412, 0xA65C, - 0x5418, 0xCA7E, 0x5419, 0xCA7B, 0x541B, 0xA767, 0x541C, 0xCA7C, 0x541D, 0xA75B, 0x541E, 0xA75D, 0x541F, 0xA775, 0x5420, 0xA770, - 0x5424, 0xCAA5, 0x5425, 0xCA7D, 0x5426, 0xA75F, 0x5427, 0xA761, 0x5428, 0xCAA4, 0x5429, 0xA768, 0x542A, 0xCA78, 0x542B, 0xA774, - 0x542C, 0xA776, 0x542D, 0xA75C, 0x542E, 0xA76D, 0x5430, 0xCA76, 0x5431, 0xA773, 0x5433, 0xA764, 0x5435, 0xA76E, 0x5436, 0xA76F, - 0x5437, 0xCA77, 0x5438, 0xA76C, 0x5439, 0xA76A, 0x543B, 0xA76B, 0x543C, 0xA771, 0x543D, 0xCAA1, 0x543E, 0xA75E, 0x5440, 0xA772, - 0x5441, 0xCAA3, 0x5442, 0xA766, 0x5443, 0xA763, 0x5445, 0xCA7A, 0x5446, 0xA762, 0x5447, 0xCAA6, 0x5448, 0xA765, 0x544A, 0xA769, - 0x544E, 0xA760, 0x544F, 0xCAA2, 0x5454, 0xCA79, 0x5460, 0xCBEB, 0x5461, 0xCBEA, 0x5462, 0xA94F, 0x5463, 0xCBED, 0x5464, 0xCBEF, - 0x5465, 0xCBE4, 0x5466, 0xCBE7, 0x5467, 0xCBEE, 0x5468, 0xA950, 0x546B, 0xCBE1, 0x546C, 0xCBE5, 0x546F, 0xCBE9, 0x5470, 0xCE49, - 0x5471, 0xA94B, 0x5472, 0xCE4D, 0x5473, 0xA8FD, 0x5474, 0xCBE6, 0x5475, 0xA8FE, 0x5476, 0xA94C, 0x5477, 0xA945, 0x5478, 0xA941, - 0x547A, 0xCBE2, 0x547B, 0xA944, 0x547C, 0xA949, 0x547D, 0xA952, 0x547E, 0xCBE3, 0x547F, 0xCBDC, 0x5480, 0xA943, 0x5481, 0xCBDD, - 0x5482, 0xCBDF, 0x5484, 0xA946, 0x5486, 0xA948, 0x5487, 0xCBDB, 0x5488, 0xCBE0, 0x548B, 0xA951, 0x548C, 0xA94D, 0x548D, 0xCBE8, - 0x548E, 0xA953, 0x5490, 0xA94A, 0x5491, 0xCBDE, 0x5492, 0xA947, 0x5495, 0xA942, 0x5496, 0xA940, 0x5498, 0xCBEC, 0x549A, 0xA94E, - 0x54A0, 0xCE48, 0x54A1, 0xCDFB, 0x54A2, 0xCE4B, 0x54A5, 0xCDFD, 0x54A6, 0xAB78, 0x54A7, 0xABA8, 0x54A8, 0xAB74, 0x54A9, 0xABA7, - 0x54AA, 0xAB7D, 0x54AB, 0xABA4, 0x54AC, 0xAB72, 0x54AD, 0xCDFC, 0x54AE, 0xCE43, 0x54AF, 0xABA3, 0x54B0, 0xCE4F, 0x54B1, 0xABA5, - 0x54B3, 0xAB79, 0x54B6, 0xCE45, 0x54B7, 0xCE42, 0x54B8, 0xAB77, 0x54BA, 0xCDFA, 0x54BB, 0xABA6, 0x54BC, 0xCE4A, 0x54BD, 0xAB7C, - 0x54BE, 0xCE4C, 0x54BF, 0xABA9, 0x54C0, 0xAB73, 0x54C1, 0xAB7E, 0x54C2, 0xAB7B, 0x54C3, 0xCE40, 0x54C4, 0xABA1, 0x54C5, 0xCE46, - 0x54C6, 0xCE47, 0x54C7, 0xAB7A, 0x54C8, 0xABA2, 0x54C9, 0xAB76, 0x54CE, 0xAB75, 0x54CF, 0xCDFE, 0x54D6, 0xCE44, 0x54DE, 0xCE4E, - 0x54E0, 0xD144, 0x54E1, 0xADFB, 0x54E2, 0xD0F1, 0x54E4, 0xD0F6, 0x54E5, 0xADF4, 0x54E6, 0xAE40, 0x54E7, 0xD0F4, 0x54E8, 0xADEF, - 0x54E9, 0xADF9, 0x54EA, 0xADFE, 0x54EB, 0xD0FB, 0x54ED, 0xADFA, 0x54EE, 0xADFD, 0x54F1, 0xD0FE, 0x54F2, 0xADF5, 0x54F3, 0xD0F5, - 0x54F7, 0xD142, 0x54F8, 0xD143, 0x54FA, 0xADF7, 0x54FB, 0xD141, 0x54FC, 0xADF3, 0x54FD, 0xAE43, 0x54FF, 0xD0F8, 0x5501, 0xADF1, - 0x5503, 0xD146, 0x5504, 0xD0F9, 0x5505, 0xD0FD, 0x5506, 0xADF6, 0x5507, 0xAE42, 0x5508, 0xD0FA, 0x5509, 0xADFC, 0x550A, 0xD140, - 0x550B, 0xD147, 0x550C, 0xD4A1, 0x550E, 0xD145, 0x550F, 0xAE44, 0x5510, 0xADF0, 0x5511, 0xD0FC, 0x5512, 0xD0F3, 0x5514, 0xADF8, - 0x5517, 0xD0F2, 0x551A, 0xD0F7, 0x5526, 0xD0F0, 0x5527, 0xAE41, 0x552A, 0xD477, 0x552C, 0xB0E4, 0x552D, 0xD4A7, 0x552E, 0xB0E2, - 0x552F, 0xB0DF, 0x5530, 0xD47C, 0x5531, 0xB0DB, 0x5532, 0xD4A2, 0x5533, 0xB0E6, 0x5534, 0xD476, 0x5535, 0xD47B, 0x5536, 0xD47A, - 0x5537, 0xADF2, 0x5538, 0xB0E1, 0x5539, 0xD4A5, 0x553B, 0xD4A8, 0x553C, 0xD473, 0x553E, 0xB3E8, 0x5540, 0xD4A9, 0x5541, 0xB0E7, - 0x5543, 0xB0D9, 0x5544, 0xB0D6, 0x5545, 0xD47E, 0x5546, 0xB0D3, 0x5548, 0xD4A6, 0x554A, 0xB0DA, 0x554B, 0xD4AA, 0x554D, 0xD474, - 0x554E, 0xD4A4, 0x554F, 0xB0DD, 0x5550, 0xD475, 0x5551, 0xD478, 0x5552, 0xD47D, 0x5555, 0xB0DE, 0x5556, 0xB0DC, 0x5557, 0xB0E8, - 0x555C, 0xB0E3, 0x555E, 0xB0D7, 0x555F, 0xB1D2, 0x5561, 0xB0D8, 0x5562, 0xD479, 0x5563, 0xB0E5, 0x5564, 0xB0E0, 0x5565, 0xD4A3, - 0x5566, 0xB0D5, 0x556A, 0xB0D4, 0x5575, 0xD471, 0x5576, 0xD472, 0x5577, 0xD86A, 0x557B, 0xB3D7, 0x557C, 0xB3DA, 0x557D, 0xD875, - 0x557E, 0xB3EE, 0x557F, 0xD878, 0x5580, 0xB3D8, 0x5581, 0xD871, 0x5582, 0xB3DE, 0x5583, 0xB3E4, 0x5584, 0xB5BD, 0x5587, 0xB3E2, - 0x5588, 0xD86E, 0x5589, 0xB3EF, 0x558A, 0xB3DB, 0x558B, 0xB3E3, 0x558C, 0xD876, 0x558D, 0xDCD7, 0x558E, 0xD87B, 0x558F, 0xD86F, - 0x5591, 0xD866, 0x5592, 0xD873, 0x5593, 0xD86D, 0x5594, 0xB3E1, 0x5595, 0xD879, 0x5598, 0xB3DD, 0x5599, 0xB3F1, 0x559A, 0xB3EA, - 0x559C, 0xB3DF, 0x559D, 0xB3DC, 0x559F, 0xB3E7, 0x55A1, 0xD87A, 0x55A2, 0xD86C, 0x55A3, 0xD872, 0x55A4, 0xD874, 0x55A5, 0xD868, - 0x55A6, 0xD877, 0x55A7, 0xB3D9, 0x55A8, 0xD867, 0x55AA, 0xB3E0, 0x55AB, 0xB3F0, 0x55AC, 0xB3EC, 0x55AD, 0xD869, 0x55AE, 0xB3E6, - 0x55B1, 0xB3ED, 0x55B2, 0xB3E9, 0x55B3, 0xB3E5, 0x55B5, 0xD870, 0x55BB, 0xB3EB, 0x55BF, 0xDCD5, 0x55C0, 0xDCD1, 0x55C2, 0xDCE0, - 0x55C3, 0xDCCA, 0x55C4, 0xDCD3, 0x55C5, 0xB6E5, 0x55C6, 0xB6E6, 0x55C7, 0xB6DE, 0x55C8, 0xDCDC, 0x55C9, 0xB6E8, 0x55CA, 0xDCCF, - 0x55CB, 0xDCCE, 0x55CC, 0xDCCC, 0x55CD, 0xDCDE, 0x55CE, 0xB6DC, 0x55CF, 0xDCD8, 0x55D0, 0xDCCD, 0x55D1, 0xB6DF, 0x55D2, 0xDCD6, - 0x55D3, 0xB6DA, 0x55D4, 0xDCD2, 0x55D5, 0xDCD9, 0x55D6, 0xDCDB, 0x55D9, 0xDCDF, 0x55DA, 0xB6E3, 0x55DB, 0xDCCB, 0x55DC, 0xB6DD, - 0x55DD, 0xDCD0, 0x55DF, 0xB6D8, 0x55E1, 0xB6E4, 0x55E2, 0xDCDA, 0x55E3, 0xB6E0, 0x55E4, 0xB6E1, 0x55E5, 0xB6E7, 0x55E6, 0xB6DB, - 0x55E7, 0xA25F, 0x55E8, 0xB6D9, 0x55E9, 0xDCD4, 0x55EF, 0xB6E2, 0x55F2, 0xDCDD, 0x55F6, 0xB9CD, 0x55F7, 0xB9C8, 0x55F9, 0xE155, - 0x55FA, 0xE151, 0x55FC, 0xE14B, 0x55FD, 0xB9C2, 0x55FE, 0xB9BE, 0x55FF, 0xE154, 0x5600, 0xB9BF, 0x5601, 0xE14E, 0x5602, 0xE150, - 0x5604, 0xE153, 0x5606, 0xB9C4, 0x5608, 0xB9CB, 0x5609, 0xB9C5, 0x560C, 0xE149, 0x560D, 0xB9C6, 0x560E, 0xB9C7, 0x560F, 0xE14C, - 0x5610, 0xB9CC, 0x5612, 0xE14A, 0x5613, 0xE14F, 0x5614, 0xB9C3, 0x5615, 0xE148, 0x5616, 0xB9C9, 0x5617, 0xB9C1, 0x561B, 0xB9C0, - 0x561C, 0xE14D, 0x561D, 0xE152, 0x561F, 0xB9CA, 0x5627, 0xE147, 0x5629, 0xBC4D, 0x562A, 0xE547, 0x562C, 0xE544, 0x562E, 0xBC47, - 0x562F, 0xBC53, 0x5630, 0xBC54, 0x5632, 0xBC4A, 0x5633, 0xE542, 0x5634, 0xBC4C, 0x5635, 0xE4F9, 0x5636, 0xBC52, 0x5638, 0xE546, - 0x5639, 0xBC49, 0x563A, 0xE548, 0x563B, 0xBC48, 0x563D, 0xE543, 0x563E, 0xE545, 0x563F, 0xBC4B, 0x5640, 0xE541, 0x5641, 0xE4FA, - 0x5642, 0xE4F7, 0x5645, 0xD86B, 0x5646, 0xE4FD, 0x5648, 0xE4F6, 0x5649, 0xE4FC, 0x564A, 0xE4FB, 0x564C, 0xE4F8, 0x564E, 0xBC4F, - 0x5653, 0xBC4E, 0x5657, 0xBC50, 0x5658, 0xE4FE, 0x5659, 0xBEB2, 0x565A, 0xE540, 0x565E, 0xE945, 0x5660, 0xE8FD, 0x5662, 0xBEBE, - 0x5663, 0xE942, 0x5664, 0xBEB6, 0x5665, 0xBEBA, 0x5666, 0xE941, 0x5668, 0xBEB9, 0x5669, 0xBEB5, 0x566A, 0xBEB8, 0x566B, 0xBEB3, - 0x566C, 0xBEBD, 0x566D, 0xE943, 0x566E, 0xE8FE, 0x566F, 0xBEBC, 0x5670, 0xE8FC, 0x5671, 0xBEBB, 0x5672, 0xE944, 0x5673, 0xE940, - 0x5674, 0xBC51, 0x5676, 0xBEBF, 0x5677, 0xE946, 0x5678, 0xBEB7, 0x5679, 0xBEB4, 0x567E, 0xECC6, 0x567F, 0xECC8, 0x5680, 0xC07B, - 0x5681, 0xECC9, 0x5682, 0xECC7, 0x5683, 0xECC5, 0x5684, 0xECC4, 0x5685, 0xC07D, 0x5686, 0xECC3, 0x5687, 0xC07E, 0x568C, 0xECC1, - 0x568D, 0xECC2, 0x568E, 0xC07A, 0x568F, 0xC0A1, 0x5690, 0xC07C, 0x5693, 0xECC0, 0x5695, 0xC250, 0x5697, 0xEFBC, 0x5698, 0xEFBA, - 0x5699, 0xEFBF, 0x569A, 0xEFBD, 0x569C, 0xEFBB, 0x569D, 0xEFBE, 0x56A5, 0xC360, 0x56A6, 0xF1F2, 0x56A7, 0xF1F3, 0x56A8, 0xC456, - 0x56AA, 0xF1F4, 0x56AB, 0xF1F0, 0x56AC, 0xF1F5, 0x56AD, 0xF1F1, 0x56AE, 0xC251, 0x56B2, 0xF3FE, 0x56B3, 0xF441, 0x56B4, 0xC459, - 0x56B5, 0xF440, 0x56B6, 0xC458, 0x56B7, 0xC457, 0x56BC, 0xC45A, 0x56BD, 0xF5C5, 0x56BE, 0xF5C6, 0x56C0, 0xC4DA, 0x56C1, 0xC4D9, - 0x56C2, 0xC4DB, 0x56C3, 0xF5C4, 0x56C5, 0xF6D8, 0x56C6, 0xF6D7, 0x56C8, 0xC56D, 0x56C9, 0xC56F, 0x56CA, 0xC56E, 0x56CB, 0xF6D9, - 0x56CC, 0xC5C8, 0x56CD, 0xF8A6, 0x56D1, 0xC5F1, 0x56D3, 0xF8A5, 0x56D4, 0xF8EE, 0x56D7, 0xC949, 0x56DA, 0xA57D, 0x56DB, 0xA57C, - 0x56DD, 0xA65F, 0x56DE, 0xA65E, 0x56DF, 0xC9C7, 0x56E0, 0xA65D, 0x56E1, 0xC9C6, 0x56E4, 0xA779, 0x56E5, 0xCAA9, 0x56E7, 0xCAA8, - 0x56EA, 0xA777, 0x56EB, 0xA77A, 0x56EE, 0xCAA7, 0x56F0, 0xA778, 0x56F7, 0xCBF0, 0x56F9, 0xCBF1, 0x56FA, 0xA954, 0x56FF, 0xABAA, - 0x5701, 0xD148, 0x5702, 0xD149, 0x5703, 0xAE45, 0x5704, 0xAE46, 0x5707, 0xD4AC, 0x5708, 0xB0E9, 0x5709, 0xB0EB, 0x570A, 0xD4AB, - 0x570B, 0xB0EA, 0x570C, 0xD87C, 0x570D, 0xB3F2, 0x5712, 0xB6E9, 0x5713, 0xB6EA, 0x5714, 0xDCE1, 0x5716, 0xB9CF, 0x5718, 0xB9CE, - 0x571A, 0xE549, 0x571B, 0xE948, 0x571C, 0xE947, 0x571E, 0xF96B, 0x571F, 0xA467, 0x5720, 0xC959, 0x5722, 0xC96E, 0x5723, 0xC96F, - 0x5728, 0xA662, 0x5729, 0xA666, 0x572A, 0xC9C9, 0x572C, 0xA664, 0x572D, 0xA663, 0x572E, 0xC9C8, 0x572F, 0xA665, 0x5730, 0xA661, - 0x5733, 0xA660, 0x5734, 0xC9CA, 0x573B, 0xA7A6, 0x573E, 0xA7A3, 0x5740, 0xA77D, 0x5741, 0xCAAA, 0x5745, 0xCAAB, 0x5747, 0xA7A1, - 0x5749, 0xCAAD, 0x574A, 0xA77B, 0x574B, 0xCAAE, 0x574C, 0xCAAC, 0x574D, 0xA77E, 0x574E, 0xA7A2, 0x574F, 0xA7A5, 0x5750, 0xA7A4, - 0x5751, 0xA77C, 0x5752, 0xCAAF, 0x5761, 0xA959, 0x5762, 0xCBFE, 0x5764, 0xA95B, 0x5766, 0xA95A, 0x5768, 0xCC40, 0x5769, 0xA958, - 0x576A, 0xA957, 0x576B, 0xCBF5, 0x576D, 0xCBF4, 0x576F, 0xCBF2, 0x5770, 0xCBF7, 0x5771, 0xCBF6, 0x5772, 0xCBF3, 0x5773, 0xCBFC, - 0x5774, 0xCBFD, 0x5775, 0xCBFA, 0x5776, 0xCBF8, 0x5777, 0xA956, 0x577B, 0xCBFB, 0x577C, 0xA95C, 0x577D, 0xCC41, 0x5780, 0xCBF9, - 0x5782, 0xABAB, 0x5783, 0xA955, 0x578B, 0xABAC, 0x578C, 0xCE54, 0x578F, 0xCE5A, 0x5793, 0xABB2, 0x5794, 0xCE58, 0x5795, 0xCE5E, - 0x5797, 0xCE55, 0x5798, 0xCE59, 0x5799, 0xCE5B, 0x579A, 0xCE5D, 0x579B, 0xCE57, 0x579D, 0xCE56, 0x579E, 0xCE51, 0x579F, 0xCE52, - 0x57A0, 0xABAD, 0x57A2, 0xABAF, 0x57A3, 0xABAE, 0x57A4, 0xCE53, 0x57A5, 0xCE5C, 0x57AE, 0xABB1, 0x57B5, 0xCE50, 0x57B6, 0xD153, - 0x57B8, 0xD152, 0x57B9, 0xD157, 0x57BA, 0xD14E, 0x57BC, 0xD151, 0x57BD, 0xD150, 0x57BF, 0xD154, 0x57C1, 0xD158, 0x57C2, 0xAE47, - 0x57C3, 0xAE4A, 0x57C6, 0xD14F, 0x57C7, 0xD155, 0x57CB, 0xAE49, 0x57CC, 0xD14A, 0x57CE, 0xABB0, 0x57CF, 0xD4BA, 0x57D0, 0xD156, - 0x57D2, 0xD14D, 0x57D4, 0xAE48, 0x57D5, 0xD14C, 0x57DC, 0xD4B1, 0x57DF, 0xB0EC, 0x57E0, 0xB0F0, 0x57E1, 0xD4C1, 0x57E2, 0xD4AF, - 0x57E3, 0xD4BD, 0x57E4, 0xB0F1, 0x57E5, 0xD4BF, 0x57E7, 0xD4C5, 0x57E9, 0xD4C9, 0x57EC, 0xD4C0, 0x57ED, 0xD4B4, 0x57EE, 0xD4BC, - 0x57F0, 0xD4CA, 0x57F1, 0xD4C8, 0x57F2, 0xD4BE, 0x57F3, 0xD4B9, 0x57F4, 0xD4B2, 0x57F5, 0xD8A6, 0x57F6, 0xD4B0, 0x57F7, 0xB0F5, - 0x57F8, 0xD4B7, 0x57F9, 0xB0F6, 0x57FA, 0xB0F2, 0x57FB, 0xD4AD, 0x57FC, 0xD4C3, 0x57FD, 0xD4B5, 0x5800, 0xD4B3, 0x5801, 0xD4C6, - 0x5802, 0xB0F3, 0x5804, 0xD4CC, 0x5805, 0xB0ED, 0x5806, 0xB0EF, 0x5807, 0xD4BB, 0x5808, 0xD4B6, 0x5809, 0xAE4B, 0x580A, 0xB0EE, - 0x580B, 0xD4B8, 0x580C, 0xD4C7, 0x580D, 0xD4CB, 0x580E, 0xD4C2, 0x5810, 0xD4C4, 0x5814, 0xD4AE, 0x5819, 0xD8A1, 0x581B, 0xD8AA, - 0x581C, 0xD8A9, 0x581D, 0xB3FA, 0x581E, 0xD8A2, 0x5820, 0xB3FB, 0x5821, 0xB3F9, 0x5823, 0xD8A4, 0x5824, 0xB3F6, 0x5825, 0xD8A8, - 0x5827, 0xD8A3, 0x5828, 0xD8A5, 0x5829, 0xD87D, 0x582A, 0xB3F4, 0x582C, 0xD8B2, 0x582D, 0xD8B1, 0x582E, 0xD8AE, 0x582F, 0xB3F3, - 0x5830, 0xB3F7, 0x5831, 0xB3F8, 0x5832, 0xD14B, 0x5833, 0xD8AB, 0x5834, 0xB3F5, 0x5835, 0xB0F4, 0x5836, 0xD8AD, 0x5837, 0xD87E, - 0x5838, 0xD8B0, 0x5839, 0xD8AF, 0x583B, 0xD8B3, 0x583D, 0xDCEF, 0x583F, 0xD8AC, 0x5848, 0xD8A7, 0x5849, 0xDCE7, 0x584A, 0xB6F4, - 0x584B, 0xB6F7, 0x584C, 0xB6F2, 0x584D, 0xDCE6, 0x584E, 0xDCEA, 0x584F, 0xDCE5, 0x5851, 0xB6EC, 0x5852, 0xB6F6, 0x5853, 0xDCE2, - 0x5854, 0xB6F0, 0x5855, 0xDCE9, 0x5857, 0xB6EE, 0x5858, 0xB6ED, 0x5859, 0xDCEC, 0x585A, 0xB6EF, 0x585B, 0xDCEE, 0x585D, 0xDCEB, - 0x585E, 0xB6EB, 0x5862, 0xB6F5, 0x5863, 0xDCF0, 0x5864, 0xDCE4, 0x5865, 0xDCED, 0x5868, 0xDCE3, 0x586B, 0xB6F1, 0x586D, 0xB6F3, - 0x586F, 0xDCE8, 0x5871, 0xDCF1, 0x5874, 0xE15D, 0x5875, 0xB9D0, 0x5876, 0xE163, 0x5879, 0xB9D5, 0x587A, 0xE15F, 0x587B, 0xE166, - 0x587C, 0xE157, 0x587D, 0xB9D7, 0x587E, 0xB9D1, 0x587F, 0xE15C, 0x5880, 0xBC55, 0x5881, 0xE15B, 0x5882, 0xE164, 0x5883, 0xB9D2, - 0x5885, 0xB9D6, 0x5886, 0xE15A, 0x5887, 0xE160, 0x5888, 0xE165, 0x5889, 0xE156, 0x588A, 0xB9D4, 0x588B, 0xE15E, 0x588E, 0xE162, - 0x588F, 0xE168, 0x5890, 0xE158, 0x5891, 0xE161, 0x5893, 0xB9D3, 0x5894, 0xE167, 0x5898, 0xE159, 0x589C, 0xBC59, 0x589D, 0xE54B, - 0x589E, 0xBC57, 0x589F, 0xBC56, 0x58A0, 0xE54D, 0x58A1, 0xE552, 0x58A3, 0xE54E, 0x58A5, 0xE551, 0x58A6, 0xBC5C, 0x58A8, 0xBEA5, - 0x58A9, 0xBC5B, 0x58AB, 0xE54A, 0x58AC, 0xE550, 0x58AE, 0xBC5A, 0x58AF, 0xE54F, 0x58B1, 0xE54C, 0x58B3, 0xBC58, 0x58BA, 0xE94D, - 0x58BB, 0xF9D9, 0x58BC, 0xE94F, 0x58BD, 0xE94A, 0x58BE, 0xBEC1, 0x58BF, 0xE94C, 0x58C1, 0xBEC0, 0x58C2, 0xE94E, 0x58C5, 0xBEC3, - 0x58C6, 0xE950, 0x58C7, 0xBEC2, 0x58C8, 0xE949, 0x58C9, 0xE94B, 0x58CE, 0xC0A5, 0x58CF, 0xECCC, 0x58D1, 0xC0A4, 0x58D2, 0xECCD, - 0x58D3, 0xC0A3, 0x58D4, 0xECCB, 0x58D5, 0xC0A2, 0x58D6, 0xECCA, 0x58D8, 0xC253, 0x58D9, 0xC252, 0x58DA, 0xF1F6, 0x58DB, 0xF1F8, - 0x58DD, 0xF1F7, 0x58DE, 0xC361, 0x58DF, 0xC362, 0x58E2, 0xC363, 0x58E3, 0xF442, 0x58E4, 0xC45B, 0x58E7, 0xF7D3, 0x58E8, 0xF7D2, - 0x58E9, 0xC5F2, 0x58EB, 0xA468, 0x58EC, 0xA4D0, 0x58EF, 0xA7A7, 0x58F4, 0xCE5F, 0x58F9, 0xB3FC, 0x58FA, 0xB3FD, 0x58FC, 0xDCF2, - 0x58FD, 0xB9D8, 0x58FE, 0xE169, 0x58FF, 0xE553, 0x5903, 0xC95A, 0x5906, 0xCAB0, 0x590C, 0xCC42, 0x590D, 0xCE60, 0x590E, 0xD159, - 0x590F, 0xAE4C, 0x5912, 0xF1F9, 0x5914, 0xC4DC, 0x5915, 0xA469, 0x5916, 0xA57E, 0x5917, 0xC970, 0x5919, 0xA667, 0x591A, 0xA668, - 0x591C, 0xA95D, 0x5920, 0xB0F7, 0x5922, 0xB9DA, 0x5924, 0xB9DB, 0x5925, 0xB9D9, 0x5927, 0xA46A, 0x5929, 0xA4D1, 0x592A, 0xA4D3, - 0x592B, 0xA4D2, 0x592C, 0xC95B, 0x592D, 0xA4D4, 0x592E, 0xA5A1, 0x592F, 0xC971, 0x5931, 0xA5A2, 0x5937, 0xA669, 0x5938, 0xA66A, - 0x593C, 0xC9CB, 0x593E, 0xA7A8, 0x5940, 0xCAB1, 0x5944, 0xA961, 0x5945, 0xCC43, 0x5947, 0xA95F, 0x5948, 0xA960, 0x5949, 0xA95E, - 0x594A, 0xD15A, 0x594E, 0xABB6, 0x594F, 0xABB5, 0x5950, 0xABB7, 0x5951, 0xABB4, 0x5953, 0xCE61, 0x5954, 0xA962, 0x5955, 0xABB3, - 0x5957, 0xAE4D, 0x5958, 0xAE4E, 0x595A, 0xAE4F, 0x595C, 0xD4CD, 0x5960, 0xB3FE, 0x5961, 0xD8B4, 0x5962, 0xB0F8, 0x5967, 0xB6F8, - 0x5969, 0xB9DD, 0x596A, 0xB9DC, 0x596B, 0xE16A, 0x596D, 0xBC5D, 0x596E, 0xBEC4, 0x5970, 0xEFC0, 0x5971, 0xF6DA, 0x5972, 0xF7D4, - 0x5973, 0xA46B, 0x5974, 0xA5A3, 0x5976, 0xA5A4, 0x5977, 0xC9D1, 0x5978, 0xA66C, 0x5979, 0xA66F, 0x597B, 0xC9CF, 0x597C, 0xC9CD, - 0x597D, 0xA66E, 0x597E, 0xC9D0, 0x597F, 0xC9D2, 0x5980, 0xC9CC, 0x5981, 0xA671, 0x5982, 0xA670, 0x5983, 0xA66D, 0x5984, 0xA66B, - 0x5985, 0xC9CE, 0x598A, 0xA7B3, 0x598D, 0xA7B0, 0x598E, 0xCAB6, 0x598F, 0xCAB9, 0x5990, 0xCAB8, 0x5992, 0xA7AA, 0x5993, 0xA7B2, - 0x5996, 0xA7AF, 0x5997, 0xCAB5, 0x5998, 0xCAB3, 0x5999, 0xA7AE, 0x599D, 0xA7A9, 0x599E, 0xA7AC, 0x59A0, 0xCAB4, 0x59A1, 0xCABB, - 0x59A2, 0xCAB7, 0x59A3, 0xA7AD, 0x59A4, 0xA7B1, 0x59A5, 0xA7B4, 0x59A6, 0xCAB2, 0x59A7, 0xCABA, 0x59A8, 0xA7AB, 0x59AE, 0xA967, - 0x59AF, 0xA96F, 0x59B1, 0xCC4F, 0x59B2, 0xCC48, 0x59B3, 0xA970, 0x59B4, 0xCC53, 0x59B5, 0xCC44, 0x59B6, 0xCC4B, 0x59B9, 0xA966, - 0x59BA, 0xCC45, 0x59BB, 0xA964, 0x59BC, 0xCC4C, 0x59BD, 0xCC50, 0x59BE, 0xA963, 0x59C0, 0xCC51, 0x59C1, 0xCC4A, 0x59C3, 0xCC4D, - 0x59C5, 0xA972, 0x59C6, 0xA969, 0x59C7, 0xCC54, 0x59C8, 0xCC52, 0x59CA, 0xA96E, 0x59CB, 0xA96C, 0x59CC, 0xCC49, 0x59CD, 0xA96B, - 0x59CE, 0xCC47, 0x59CF, 0xCC46, 0x59D0, 0xA96A, 0x59D1, 0xA968, 0x59D2, 0xA971, 0x59D3, 0xA96D, 0x59D4, 0xA965, 0x59D6, 0xCC4E, - 0x59D8, 0xABB9, 0x59DA, 0xABC0, 0x59DB, 0xCE6F, 0x59DC, 0xABB8, 0x59DD, 0xCE67, 0x59DE, 0xCE63, 0x59E0, 0xCE73, 0x59E1, 0xCE62, - 0x59E3, 0xABBB, 0x59E4, 0xCE6C, 0x59E5, 0xABBE, 0x59E6, 0xABC1, 0x59E8, 0xABBC, 0x59E9, 0xCE70, 0x59EA, 0xABBF, 0x59EC, 0xAE56, - 0x59ED, 0xCE76, 0x59EE, 0xCE64, 0x59F1, 0xCE66, 0x59F2, 0xCE6D, 0x59F3, 0xCE71, 0x59F4, 0xCE75, 0x59F5, 0xCE72, 0x59F6, 0xCE6B, - 0x59F7, 0xCE6E, 0x59FA, 0xCE68, 0x59FB, 0xABC3, 0x59FC, 0xCE6A, 0x59FD, 0xCE69, 0x59FE, 0xCE74, 0x59FF, 0xABBA, 0x5A00, 0xCE65, - 0x5A01, 0xABC2, 0x5A03, 0xABBD, 0x5A09, 0xAE5C, 0x5A0A, 0xD162, 0x5A0C, 0xAE5B, 0x5A0F, 0xD160, 0x5A11, 0xAE50, 0x5A13, 0xAE55, - 0x5A15, 0xD15F, 0x5A16, 0xD15C, 0x5A17, 0xD161, 0x5A18, 0xAE51, 0x5A19, 0xD15B, 0x5A1B, 0xAE54, 0x5A1C, 0xAE52, 0x5A1E, 0xD163, - 0x5A1F, 0xAE53, 0x5A20, 0xAE57, 0x5A23, 0xAE58, 0x5A25, 0xAE5A, 0x5A29, 0xAE59, 0x5A2D, 0xD15D, 0x5A2E, 0xD15E, 0x5A33, 0xD164, - 0x5A35, 0xD4D4, 0x5A36, 0xB0F9, 0x5A37, 0xD8C2, 0x5A38, 0xD4D3, 0x5A39, 0xD4E6, 0x5A3C, 0xB140, 0x5A3E, 0xD4E4, 0x5A40, 0xB0FE, - 0x5A41, 0xB0FA, 0x5A42, 0xD4ED, 0x5A43, 0xD4DD, 0x5A44, 0xD4E0, 0x5A46, 0xB143, 0x5A47, 0xD4EA, 0x5A48, 0xD4E2, 0x5A49, 0xB0FB, - 0x5A4A, 0xB144, 0x5A4C, 0xD4E7, 0x5A4D, 0xD4E5, 0x5A50, 0xD4D6, 0x5A51, 0xD4EB, 0x5A52, 0xD4DF, 0x5A53, 0xD4DA, 0x5A55, 0xD4D0, - 0x5A56, 0xD4EC, 0x5A57, 0xD4DC, 0x5A58, 0xD4CF, 0x5A5A, 0xB142, 0x5A5B, 0xD4E1, 0x5A5C, 0xD4EE, 0x5A5D, 0xD4DE, 0x5A5E, 0xD4D2, - 0x5A5F, 0xD4D7, 0x5A60, 0xD4CE, 0x5A62, 0xB141, 0x5A64, 0xD4DB, 0x5A65, 0xD4D8, 0x5A66, 0xB0FC, 0x5A67, 0xD4D1, 0x5A69, 0xD4E9, - 0x5A6A, 0xB0FD, 0x5A6C, 0xD4D9, 0x5A6D, 0xD4D5, 0x5A70, 0xD4E8, 0x5A77, 0xB440, 0x5A78, 0xD8BB, 0x5A7A, 0xD8B8, 0x5A7B, 0xD8C9, - 0x5A7C, 0xD8BD, 0x5A7D, 0xD8CA, 0x5A7F, 0xB442, 0x5A83, 0xD8C6, 0x5A84, 0xD8C3, 0x5A8A, 0xD8C4, 0x5A8B, 0xD8C7, 0x5A8C, 0xD8CB, - 0x5A8E, 0xD4E3, 0x5A8F, 0xD8CD, 0x5A90, 0xDD47, 0x5A92, 0xB443, 0x5A93, 0xD8CE, 0x5A94, 0xD8B6, 0x5A95, 0xD8C0, 0x5A97, 0xD8C5, - 0x5A9A, 0xB441, 0x5A9B, 0xB444, 0x5A9C, 0xD8CC, 0x5A9D, 0xD8CF, 0x5A9E, 0xD8BA, 0x5A9F, 0xD8B7, 0x5AA2, 0xD8B9, 0x5AA5, 0xD8BE, - 0x5AA6, 0xD8BC, 0x5AA7, 0xB445, 0x5AA9, 0xD8C8, 0x5AAC, 0xD8BF, 0x5AAE, 0xD8C1, 0x5AAF, 0xD8B5, 0x5AB0, 0xDCFA, 0x5AB1, 0xDCF8, - 0x5AB2, 0xB742, 0x5AB3, 0xB740, 0x5AB4, 0xDD43, 0x5AB5, 0xDCF9, 0x5AB6, 0xDD44, 0x5AB7, 0xDD40, 0x5AB8, 0xDCF7, 0x5AB9, 0xDD46, - 0x5ABA, 0xDCF6, 0x5ABB, 0xDCFD, 0x5ABC, 0xB6FE, 0x5ABD, 0xB6FD, 0x5ABE, 0xB6FC, 0x5ABF, 0xDCFB, 0x5AC0, 0xDD41, 0x5AC1, 0xB6F9, - 0x5AC2, 0xB741, 0x5AC4, 0xDCF4, 0x5AC6, 0xDCFE, 0x5AC7, 0xDCF3, 0x5AC8, 0xDCFC, 0x5AC9, 0xB6FA, 0x5ACA, 0xDD42, 0x5ACB, 0xDCF5, - 0x5ACC, 0xB6FB, 0x5ACD, 0xDD45, 0x5AD5, 0xE16E, 0x5AD6, 0xB9E2, 0x5AD7, 0xB9E1, 0x5AD8, 0xB9E3, 0x5AD9, 0xE17A, 0x5ADA, 0xE170, - 0x5ADB, 0xE176, 0x5ADC, 0xE16B, 0x5ADD, 0xE179, 0x5ADE, 0xE178, 0x5ADF, 0xE17C, 0x5AE0, 0xE175, 0x5AE1, 0xB9DE, 0x5AE2, 0xE174, - 0x5AE3, 0xB9E4, 0x5AE5, 0xE16D, 0x5AE6, 0xB9DF, 0x5AE8, 0xE17B, 0x5AE9, 0xB9E0, 0x5AEA, 0xE16F, 0x5AEB, 0xE172, 0x5AEC, 0xE177, - 0x5AED, 0xE171, 0x5AEE, 0xE16C, 0x5AF3, 0xE173, 0x5AF4, 0xE555, 0x5AF5, 0xBC61, 0x5AF6, 0xE558, 0x5AF7, 0xE557, 0x5AF8, 0xE55A, - 0x5AF9, 0xE55C, 0x5AFA, 0xF9DC, 0x5AFB, 0xBC5F, 0x5AFD, 0xE556, 0x5AFF, 0xE554, 0x5B01, 0xE55D, 0x5B02, 0xE55B, 0x5B03, 0xE559, - 0x5B05, 0xE55F, 0x5B07, 0xE55E, 0x5B08, 0xBC63, 0x5B09, 0xBC5E, 0x5B0B, 0xBC60, 0x5B0C, 0xBC62, 0x5B0F, 0xE560, 0x5B10, 0xE957, - 0x5B13, 0xE956, 0x5B14, 0xE955, 0x5B16, 0xE958, 0x5B17, 0xE951, 0x5B19, 0xE952, 0x5B1A, 0xE95A, 0x5B1B, 0xE953, 0x5B1D, 0xBEC5, - 0x5B1E, 0xE95C, 0x5B20, 0xE95B, 0x5B21, 0xE954, 0x5B23, 0xECD1, 0x5B24, 0xC0A8, 0x5B25, 0xECCF, 0x5B26, 0xECD4, 0x5B27, 0xECD3, - 0x5B28, 0xE959, 0x5B2A, 0xC0A7, 0x5B2C, 0xECD2, 0x5B2D, 0xECCE, 0x5B2E, 0xECD6, 0x5B2F, 0xECD5, 0x5B30, 0xC0A6, 0x5B32, 0xECD0, - 0x5B34, 0xBEC6, 0x5B38, 0xC254, 0x5B3C, 0xEFC1, 0x5B3D, 0xF1FA, 0x5B3E, 0xF1FB, 0x5B3F, 0xF1FC, 0x5B40, 0xC45C, 0x5B43, 0xC45D, - 0x5B45, 0xF443, 0x5B47, 0xF5C8, 0x5B48, 0xF5C7, 0x5B4B, 0xF6DB, 0x5B4C, 0xF6DC, 0x5B4D, 0xF7D5, 0x5B4E, 0xF8A7, 0x5B50, 0xA46C, - 0x5B51, 0xA46D, 0x5B53, 0xA46E, 0x5B54, 0xA4D5, 0x5B55, 0xA5A5, 0x5B56, 0xC9D3, 0x5B57, 0xA672, 0x5B58, 0xA673, 0x5B5A, 0xA7B7, - 0x5B5B, 0xA7B8, 0x5B5C, 0xA7B6, 0x5B5D, 0xA7B5, 0x5B5F, 0xA973, 0x5B62, 0xCC55, 0x5B63, 0xA975, 0x5B64, 0xA974, 0x5B65, 0xCC56, - 0x5B69, 0xABC4, 0x5B6B, 0xAE5D, 0x5B6C, 0xD165, 0x5B6E, 0xD4F0, 0x5B70, 0xB145, 0x5B71, 0xB447, 0x5B72, 0xD4EF, 0x5B73, 0xB446, - 0x5B75, 0xB9E5, 0x5B77, 0xE17D, 0x5B78, 0xBEC7, 0x5B7A, 0xC0A9, 0x5B7B, 0xECD7, 0x5B7D, 0xC45E, 0x5B7F, 0xC570, 0x5B81, 0xC972, - 0x5B83, 0xA5A6, 0x5B84, 0xC973, 0x5B85, 0xA676, 0x5B87, 0xA674, 0x5B88, 0xA675, 0x5B89, 0xA677, 0x5B8B, 0xA7BA, 0x5B8C, 0xA7B9, - 0x5B8E, 0xCABC, 0x5B8F, 0xA7BB, 0x5B92, 0xCABD, 0x5B93, 0xCC57, 0x5B95, 0xCC58, 0x5B97, 0xA976, 0x5B98, 0xA978, 0x5B99, 0xA97A, - 0x5B9A, 0xA977, 0x5B9B, 0xA97B, 0x5B9C, 0xA979, 0x5BA2, 0xABC8, 0x5BA3, 0xABC5, 0x5BA4, 0xABC7, 0x5BA5, 0xABC9, 0x5BA6, 0xABC6, - 0x5BA7, 0xD166, 0x5BA8, 0xCE77, 0x5BAC, 0xD168, 0x5BAD, 0xD167, 0x5BAE, 0xAE63, 0x5BB0, 0xAE5F, 0x5BB3, 0xAE60, 0x5BB4, 0xAE62, - 0x5BB5, 0xAE64, 0x5BB6, 0xAE61, 0x5BB8, 0xAE66, 0x5BB9, 0xAE65, 0x5BBF, 0xB14A, 0x5BC0, 0xD4F2, 0x5BC1, 0xD4F1, 0x5BC2, 0xB149, - 0x5BC4, 0xB148, 0x5BC5, 0xB147, 0x5BC6, 0xB14B, 0x5BC7, 0xB146, 0x5BCA, 0xD8D5, 0x5BCB, 0xD8D2, 0x5BCC, 0xB449, 0x5BCD, 0xD8D1, - 0x5BCE, 0xD8D6, 0x5BD0, 0xB44B, 0x5BD1, 0xD8D4, 0x5BD2, 0xB448, 0x5BD3, 0xB44A, 0x5BD4, 0xD8D3, 0x5BD6, 0xDD48, 0x5BD8, 0xDD49, - 0x5BD9, 0xDD4A, 0x5BDE, 0xB9E6, 0x5BDF, 0xB9EE, 0x5BE0, 0xE17E, 0x5BE1, 0xB9E8, 0x5BE2, 0xB9EC, 0x5BE3, 0xE1A1, 0x5BE4, 0xB9ED, - 0x5BE5, 0xB9E9, 0x5BE6, 0xB9EA, 0x5BE7, 0xB9E7, 0x5BE8, 0xB9EB, 0x5BE9, 0xBC66, 0x5BEA, 0xD8D0, 0x5BEB, 0xBC67, 0x5BEC, 0xBC65, - 0x5BEE, 0xBC64, 0x5BEF, 0xE95D, 0x5BF0, 0xBEC8, 0x5BF1, 0xECD8, 0x5BF2, 0xECD9, 0x5BF5, 0xC364, 0x5BF6, 0xC45F, 0x5BF8, 0xA46F, - 0x5BFA, 0xA678, 0x5C01, 0xABCA, 0x5C03, 0xD169, 0x5C04, 0xAE67, 0x5C07, 0xB14E, 0x5C08, 0xB14D, 0x5C09, 0xB14C, 0x5C0A, 0xB44C, - 0x5C0B, 0xB44D, 0x5C0C, 0xD8D7, 0x5C0D, 0xB9EF, 0x5C0E, 0xBEC9, 0x5C0F, 0xA470, 0x5C10, 0xC95C, 0x5C11, 0xA4D6, 0x5C12, 0xC974, - 0x5C15, 0xC9D4, 0x5C16, 0xA679, 0x5C1A, 0xA97C, 0x5C1F, 0xDD4B, 0x5C22, 0xA471, 0x5C24, 0xA4D7, 0x5C25, 0xC9D5, 0x5C28, 0xCABE, - 0x5C2A, 0xCABF, 0x5C2C, 0xA7BC, 0x5C30, 0xD8D8, 0x5C31, 0xB44E, 0x5C33, 0xDD4C, 0x5C37, 0xC0AA, 0x5C38, 0xA472, 0x5C39, 0xA4A8, - 0x5C3A, 0xA4D8, 0x5C3B, 0xC975, 0x5C3C, 0xA5A7, 0x5C3E, 0xA7C0, 0x5C3F, 0xA7BF, 0x5C40, 0xA7BD, 0x5C41, 0xA7BE, 0x5C44, 0xCC59, - 0x5C45, 0xA97E, 0x5C46, 0xA9A1, 0x5C47, 0xCC5A, 0x5C48, 0xA97D, 0x5C4B, 0xABCE, 0x5C4C, 0xCE78, 0x5C4D, 0xABCD, 0x5C4E, 0xABCB, - 0x5C4F, 0xABCC, 0x5C50, 0xAE6A, 0x5C51, 0xAE68, 0x5C54, 0xD16B, 0x5C55, 0xAE69, 0x5C56, 0xD16A, 0x5C58, 0xAE5E, 0x5C59, 0xD4F3, - 0x5C5C, 0xB150, 0x5C5D, 0xB151, 0x5C60, 0xB14F, 0x5C62, 0xB9F0, 0x5C63, 0xE1A2, 0x5C64, 0xBC68, 0x5C65, 0xBC69, 0x5C67, 0xE561, - 0x5C68, 0xC0AB, 0x5C69, 0xEFC2, 0x5C6A, 0xEFC3, 0x5C6C, 0xC4DD, 0x5C6D, 0xF8A8, 0x5C6E, 0xC94B, 0x5C6F, 0xA4D9, 0x5C71, 0xA473, - 0x5C73, 0xC977, 0x5C74, 0xC976, 0x5C79, 0xA67A, 0x5C7A, 0xC9D7, 0x5C7B, 0xC9D8, 0x5C7C, 0xC9D6, 0x5C7E, 0xC9D9, 0x5C86, 0xCAC7, - 0x5C88, 0xCAC2, 0x5C89, 0xCAC4, 0x5C8A, 0xCAC6, 0x5C8B, 0xCAC3, 0x5C8C, 0xA7C4, 0x5C8D, 0xCAC0, 0x5C8F, 0xCAC1, 0x5C90, 0xA7C1, - 0x5C91, 0xA7C2, 0x5C92, 0xCAC5, 0x5C93, 0xCAC8, 0x5C94, 0xA7C3, 0x5C95, 0xCAC9, 0x5C9D, 0xCC68, 0x5C9F, 0xCC62, 0x5CA0, 0xCC5D, - 0x5CA1, 0xA9A3, 0x5CA2, 0xCC65, 0x5CA3, 0xCC63, 0x5CA4, 0xCC5C, 0x5CA5, 0xCC69, 0x5CA6, 0xCC6C, 0x5CA7, 0xCC67, 0x5CA8, 0xCC60, - 0x5CA9, 0xA9A5, 0x5CAA, 0xCC66, 0x5CAB, 0xA9A6, 0x5CAC, 0xCC61, 0x5CAD, 0xCC64, 0x5CAE, 0xCC5B, 0x5CAF, 0xCC5F, 0x5CB0, 0xCC6B, - 0x5CB1, 0xA9A7, 0x5CB3, 0xA9A8, 0x5CB5, 0xCC5E, 0x5CB6, 0xCC6A, 0x5CB7, 0xA9A2, 0x5CB8, 0xA9A4, 0x5CC6, 0xCEAB, 0x5CC7, 0xCEA4, - 0x5CC8, 0xCEAA, 0x5CC9, 0xCEA3, 0x5CCA, 0xCEA5, 0x5CCB, 0xCE7D, 0x5CCC, 0xCE7B, 0x5CCE, 0xCEAC, 0x5CCF, 0xCEA9, 0x5CD0, 0xCE79, - 0x5CD2, 0xABD0, 0x5CD3, 0xCEA7, 0x5CD4, 0xCEA8, 0x5CD6, 0xCEA6, 0x5CD7, 0xCE7C, 0x5CD8, 0xCE7A, 0x5CD9, 0xABCF, 0x5CDA, 0xCEA2, - 0x5CDB, 0xCE7E, 0x5CDE, 0xCEA1, 0x5CDF, 0xCEAD, 0x5CE8, 0xAE6F, 0x5CEA, 0xAE6E, 0x5CEC, 0xD16C, 0x5CED, 0xAE6B, 0x5CEE, 0xD16E, - 0x5CF0, 0xAE70, 0x5CF1, 0xD16F, 0x5CF4, 0xAE73, 0x5CF6, 0xAE71, 0x5CF7, 0xD170, 0x5CF8, 0xCEAE, 0x5CF9, 0xD172, 0x5CFB, 0xAE6D, - 0x5CFD, 0xAE6C, 0x5CFF, 0xD16D, 0x5D00, 0xD171, 0x5D01, 0xAE72, 0x5D06, 0xB153, 0x5D07, 0xB152, 0x5D0B, 0xD4F5, 0x5D0C, 0xD4F9, - 0x5D0D, 0xD4FB, 0x5D0E, 0xB154, 0x5D0F, 0xD4FE, 0x5D11, 0xB158, 0x5D12, 0xD541, 0x5D14, 0xB15A, 0x5D16, 0xB156, 0x5D17, 0xB15E, - 0x5D19, 0xB15B, 0x5D1A, 0xD4F7, 0x5D1B, 0xB155, 0x5D1D, 0xD4F6, 0x5D1E, 0xD4F4, 0x5D1F, 0xD543, 0x5D20, 0xD4F8, 0x5D22, 0xB157, - 0x5D23, 0xD542, 0x5D24, 0xB15C, 0x5D25, 0xD4FD, 0x5D26, 0xD4FC, 0x5D27, 0xB15D, 0x5D28, 0xD4FA, 0x5D29, 0xB159, 0x5D2E, 0xD544, - 0x5D30, 0xD540, 0x5D31, 0xD8E7, 0x5D32, 0xD8EE, 0x5D33, 0xD8E3, 0x5D34, 0xB451, 0x5D35, 0xD8DF, 0x5D36, 0xD8EF, 0x5D37, 0xD8D9, - 0x5D38, 0xD8EC, 0x5D39, 0xD8EA, 0x5D3A, 0xD8E4, 0x5D3C, 0xD8ED, 0x5D3D, 0xD8E6, 0x5D3F, 0xD8DE, 0x5D40, 0xD8F0, 0x5D41, 0xD8DC, - 0x5D42, 0xD8E9, 0x5D43, 0xD8DA, 0x5D45, 0xD8F1, 0x5D47, 0xB452, 0x5D49, 0xD8EB, 0x5D4A, 0xDD4F, 0x5D4B, 0xD8DD, 0x5D4C, 0xB44F, - 0x5D4E, 0xD8E1, 0x5D50, 0xB450, 0x5D51, 0xD8E0, 0x5D52, 0xD8E5, 0x5D55, 0xD8E2, 0x5D59, 0xD8E8, 0x5D5E, 0xDD53, 0x5D62, 0xDD56, - 0x5D63, 0xDD4E, 0x5D65, 0xDD50, 0x5D67, 0xDD55, 0x5D68, 0xDD54, 0x5D69, 0xB743, 0x5D6B, 0xD8DB, 0x5D6C, 0xDD52, 0x5D6F, 0xB744, - 0x5D71, 0xDD4D, 0x5D72, 0xDD51, 0x5D77, 0xE1A9, 0x5D79, 0xE1B0, 0x5D7A, 0xE1A7, 0x5D7C, 0xE1AE, 0x5D7D, 0xE1A5, 0x5D7E, 0xE1AD, - 0x5D7F, 0xE1B1, 0x5D80, 0xE1A4, 0x5D81, 0xE1A8, 0x5D82, 0xE1A3, 0x5D84, 0xB9F1, 0x5D86, 0xE1A6, 0x5D87, 0xB9F2, 0x5D88, 0xE1AC, - 0x5D89, 0xE1AB, 0x5D8A, 0xE1AA, 0x5D8D, 0xE1AF, 0x5D92, 0xE565, 0x5D93, 0xE567, 0x5D94, 0xBC6B, 0x5D95, 0xE568, 0x5D97, 0xE563, - 0x5D99, 0xE562, 0x5D9A, 0xE56C, 0x5D9C, 0xE56A, 0x5D9D, 0xBC6A, 0x5D9E, 0xE56D, 0x5D9F, 0xE564, 0x5DA0, 0xE569, 0x5DA1, 0xE56B, - 0x5DA2, 0xE566, 0x5DA7, 0xE961, 0x5DA8, 0xE966, 0x5DA9, 0xE960, 0x5DAA, 0xE965, 0x5DAC, 0xE95E, 0x5DAD, 0xE968, 0x5DAE, 0xE964, - 0x5DAF, 0xE969, 0x5DB0, 0xE963, 0x5DB1, 0xE95F, 0x5DB2, 0xE967, 0x5DB4, 0xE96A, 0x5DB5, 0xE962, 0x5DB7, 0xECDA, 0x5DB8, 0xC0AF, - 0x5DBA, 0xC0AD, 0x5DBC, 0xC0AC, 0x5DBD, 0xC0AE, 0x5DC0, 0xEFC4, 0x5DC2, 0xF172, 0x5DC3, 0xF1FD, 0x5DC6, 0xF444, 0x5DC7, 0xF445, - 0x5DC9, 0xC460, 0x5DCB, 0xF5C9, 0x5DCD, 0xC4DE, 0x5DCF, 0xF5CA, 0x5DD1, 0xF6DE, 0x5DD2, 0xC572, 0x5DD4, 0xC571, 0x5DD5, 0xF6DD, - 0x5DD6, 0xC5C9, 0x5DD8, 0xF7D6, 0x5DDD, 0xA474, 0x5DDE, 0xA67B, 0x5DDF, 0xC9DA, 0x5DE0, 0xCACA, 0x5DE1, 0xA8B5, 0x5DE2, 0xB15F, - 0x5DE5, 0xA475, 0x5DE6, 0xA5AA, 0x5DE7, 0xA5A9, 0x5DE8, 0xA5A8, 0x5DEB, 0xA7C5, 0x5DEE, 0xAE74, 0x5DF0, 0xDD57, 0x5DF1, 0xA476, - 0x5DF2, 0xA477, 0x5DF3, 0xA478, 0x5DF4, 0xA4DA, 0x5DF7, 0xABD1, 0x5DF9, 0xCEAF, 0x5DFD, 0xB453, 0x5DFE, 0xA479, 0x5DFF, 0xC95D, - 0x5E02, 0xA5AB, 0x5E03, 0xA5AC, 0x5E04, 0xC978, 0x5E06, 0xA67C, 0x5E0A, 0xCACB, 0x5E0C, 0xA7C6, 0x5E0E, 0xCACC, 0x5E11, 0xA9AE, - 0x5E14, 0xCC6E, 0x5E15, 0xA9AC, 0x5E16, 0xA9AB, 0x5E17, 0xCC6D, 0x5E18, 0xA9A9, 0x5E19, 0xCC6F, 0x5E1A, 0xA9AA, 0x5E1B, 0xA9AD, - 0x5E1D, 0xABD2, 0x5E1F, 0xABD4, 0x5E20, 0xCEB3, 0x5E21, 0xCEB0, 0x5E22, 0xCEB1, 0x5E23, 0xCEB2, 0x5E24, 0xCEB4, 0x5E25, 0xABD3, - 0x5E28, 0xD174, 0x5E29, 0xD173, 0x5E2B, 0xAE76, 0x5E2D, 0xAE75, 0x5E33, 0xB162, 0x5E34, 0xD546, 0x5E36, 0xB161, 0x5E37, 0xB163, - 0x5E38, 0xB160, 0x5E3D, 0xB455, 0x5E3E, 0xD545, 0x5E40, 0xB456, 0x5E41, 0xD8F3, 0x5E43, 0xB457, 0x5E44, 0xD8F2, 0x5E45, 0xB454, - 0x5E4A, 0xDD5A, 0x5E4B, 0xDD5C, 0x5E4C, 0xB745, 0x5E4D, 0xDD5B, 0x5E4E, 0xDD59, 0x5E4F, 0xDD58, 0x5E53, 0xE1B4, 0x5E54, 0xB9F7, - 0x5E55, 0xB9F5, 0x5E57, 0xB9F6, 0x5E58, 0xE1B2, 0x5E59, 0xE1B3, 0x5E5B, 0xB9F3, 0x5E5C, 0xE571, 0x5E5D, 0xE56F, 0x5E5F, 0xBC6D, - 0x5E60, 0xE570, 0x5E61, 0xBC6E, 0x5E62, 0xBC6C, 0x5E63, 0xB9F4, 0x5E66, 0xE96D, 0x5E67, 0xE96B, 0x5E68, 0xE96C, 0x5E69, 0xE56E, - 0x5E6A, 0xECDC, 0x5E6B, 0xC0B0, 0x5E6C, 0xECDB, 0x5E6D, 0xEFC5, 0x5E6E, 0xEFC6, 0x5E6F, 0xE96E, 0x5E70, 0xF1FE, 0x5E72, 0xA47A, - 0x5E73, 0xA5AD, 0x5E74, 0xA67E, 0x5E75, 0xC9DB, 0x5E76, 0xA67D, 0x5E78, 0xA9AF, 0x5E79, 0xB746, 0x5E7B, 0xA4DB, 0x5E7C, 0xA5AE, - 0x5E7D, 0xABD5, 0x5E7E, 0xB458, 0x5E80, 0xC979, 0x5E82, 0xC97A, 0x5E84, 0xC9DC, 0x5E87, 0xA7C8, 0x5E88, 0xCAD0, 0x5E89, 0xCACE, - 0x5E8A, 0xA7C9, 0x5E8B, 0xCACD, 0x5E8C, 0xCACF, 0x5E8D, 0xCAD1, 0x5E8F, 0xA7C7, 0x5E95, 0xA9B3, 0x5E96, 0xA9B4, 0x5E97, 0xA9B1, - 0x5E9A, 0xA9B0, 0x5E9B, 0xCEB8, 0x5E9C, 0xA9B2, 0x5EA0, 0xABD6, 0x5EA2, 0xCEB7, 0x5EA3, 0xCEB9, 0x5EA4, 0xCEB6, 0x5EA5, 0xCEBA, - 0x5EA6, 0xABD7, 0x5EA7, 0xAE79, 0x5EA8, 0xD175, 0x5EAA, 0xD177, 0x5EAB, 0xAE77, 0x5EAC, 0xD178, 0x5EAD, 0xAE78, 0x5EAE, 0xD176, - 0x5EB0, 0xCEB5, 0x5EB1, 0xD547, 0x5EB2, 0xD54A, 0x5EB3, 0xD54B, 0x5EB4, 0xD548, 0x5EB5, 0xB167, 0x5EB6, 0xB166, 0x5EB7, 0xB164, - 0x5EB8, 0xB165, 0x5EB9, 0xD549, 0x5EBE, 0xB168, 0x5EC1, 0xB45A, 0x5EC2, 0xB45B, 0x5EC4, 0xB45C, 0x5EC5, 0xDD5D, 0x5EC6, 0xDD5F, - 0x5EC7, 0xDD61, 0x5EC8, 0xB748, 0x5EC9, 0xB747, 0x5ECA, 0xB459, 0x5ECB, 0xDD60, 0x5ECC, 0xDD5E, 0x5ECE, 0xE1B8, 0x5ED1, 0xE1B6, - 0x5ED2, 0xE1BC, 0x5ED3, 0xB9F8, 0x5ED4, 0xE1BD, 0x5ED5, 0xE1BA, 0x5ED6, 0xB9F9, 0x5ED7, 0xE1B7, 0x5ED8, 0xE1B5, 0x5ED9, 0xE1BB, - 0x5EDA, 0xBC70, 0x5EDB, 0xE573, 0x5EDC, 0xE1B9, 0x5EDD, 0xBC72, 0x5EDE, 0xE574, 0x5EDF, 0xBC71, 0x5EE0, 0xBC74, 0x5EE1, 0xE575, - 0x5EE2, 0xBC6F, 0x5EE3, 0xBC73, 0x5EE5, 0xE973, 0x5EE6, 0xE971, 0x5EE7, 0xE970, 0x5EE8, 0xE972, 0x5EE9, 0xE96F, 0x5EEC, 0xC366, - 0x5EEE, 0xF446, 0x5EEF, 0xF447, 0x5EF1, 0xF5CB, 0x5EF2, 0xF6DF, 0x5EF3, 0xC655, 0x5EF6, 0xA9B5, 0x5EF7, 0xA7CA, 0x5EFA, 0xABD8, - 0x5EFE, 0xA47B, 0x5EFF, 0xA4DC, 0x5F01, 0xA5AF, 0x5F02, 0xC9DD, 0x5F04, 0xA7CB, 0x5F05, 0xCAD2, 0x5F07, 0xCEBB, 0x5F08, 0xABD9, - 0x5F0A, 0xB9FA, 0x5F0B, 0xA47C, 0x5F0F, 0xA6A1, 0x5F12, 0xB749, 0x5F13, 0xA47D, 0x5F14, 0xA4DD, 0x5F15, 0xA4DE, 0x5F17, 0xA5B1, - 0x5F18, 0xA5B0, 0x5F1A, 0xC9DE, 0x5F1B, 0xA6A2, 0x5F1D, 0xCAD3, 0x5F1F, 0xA7CC, 0x5F22, 0xCC71, 0x5F23, 0xCC72, 0x5F24, 0xCC73, - 0x5F26, 0xA9B6, 0x5F27, 0xA9B7, 0x5F28, 0xCC70, 0x5F29, 0xA9B8, 0x5F2D, 0xABDA, 0x5F2E, 0xCEBC, 0x5F30, 0xD17A, 0x5F31, 0xAE7A, - 0x5F33, 0xD179, 0x5F35, 0xB169, 0x5F36, 0xD54C, 0x5F37, 0xB16A, 0x5F38, 0xD54D, 0x5F3C, 0xB45D, 0x5F40, 0xDD62, 0x5F43, 0xE1BF, - 0x5F44, 0xE1BE, 0x5F46, 0xB9FB, 0x5F48, 0xBC75, 0x5F49, 0xE576, 0x5F4A, 0xBECA, 0x5F4B, 0xE974, 0x5F4C, 0xC0B1, 0x5F4E, 0xC573, - 0x5F4F, 0xF7D8, 0x5F54, 0xCC74, 0x5F56, 0xCEBD, 0x5F57, 0xB16B, 0x5F58, 0xD8F4, 0x5F59, 0xB74A, 0x5F5D, 0xC255, 0x5F62, 0xA7CE, - 0x5F64, 0xA7CD, 0x5F65, 0xABDB, 0x5F67, 0xD17B, 0x5F69, 0xB16D, 0x5F6A, 0xB343, 0x5F6B, 0xB16E, 0x5F6C, 0xB16C, 0x5F6D, 0xB45E, - 0x5F6F, 0xE1C0, 0x5F70, 0xB9FC, 0x5F71, 0xBC76, 0x5F73, 0xC94C, 0x5F74, 0xC9DF, 0x5F76, 0xCAD5, 0x5F77, 0xA7CF, 0x5F78, 0xCAD4, - 0x5F79, 0xA7D0, 0x5F7C, 0xA9BC, 0x5F7D, 0xCC77, 0x5F7E, 0xCC76, 0x5F7F, 0xA9BB, 0x5F80, 0xA9B9, 0x5F81, 0xA9BA, 0x5F82, 0xCC75, - 0x5F85, 0xABDD, 0x5F86, 0xCEBE, 0x5F87, 0xABE0, 0x5F88, 0xABDC, 0x5F89, 0xABE2, 0x5F8A, 0xABDE, 0x5F8B, 0xABDF, 0x5F8C, 0xABE1, - 0x5F90, 0xAE7D, 0x5F91, 0xAE7C, 0x5F92, 0xAE7B, 0x5F96, 0xD54F, 0x5F97, 0xB16F, 0x5F98, 0xB172, 0x5F99, 0xB170, 0x5F9B, 0xD54E, - 0x5F9C, 0xB175, 0x5F9E, 0xB171, 0x5F9F, 0xD550, 0x5FA0, 0xB174, 0x5FA1, 0xB173, 0x5FA5, 0xD8F6, 0x5FA6, 0xD8F5, 0x5FA8, 0xB461, - 0x5FA9, 0xB45F, 0x5FAA, 0xB460, 0x5FAB, 0xD8F7, 0x5FAC, 0xB74B, 0x5FAD, 0xDD64, 0x5FAE, 0xB74C, 0x5FAF, 0xDD63, 0x5FB2, 0xE577, - 0x5FB5, 0xBC78, 0x5FB6, 0xE1C1, 0x5FB7, 0xBC77, 0x5FB9, 0xB9FD, 0x5FBB, 0xECDE, 0x5FBC, 0xE975, 0x5FBD, 0xC0B2, 0x5FBE, 0xECDD, - 0x5FBF, 0xF240, 0x5FC0, 0xF448, 0x5FC1, 0xF449, 0x5FC3, 0xA4DF, 0x5FC5, 0xA5B2, 0x5FC9, 0xC97B, 0x5FCC, 0xA7D2, 0x5FCD, 0xA7D4, - 0x5FCF, 0xC9E2, 0x5FD0, 0xCAD8, 0x5FD1, 0xCAD7, 0x5FD2, 0xCAD6, 0x5FD4, 0xC9E1, 0x5FD5, 0xC9E0, 0x5FD6, 0xA6A4, 0x5FD7, 0xA7D3, - 0x5FD8, 0xA7D1, 0x5FD9, 0xA6A3, 0x5FDD, 0xA9BD, 0x5FDE, 0xCC78, 0x5FE0, 0xA9BE, 0x5FE1, 0xCADD, 0x5FE3, 0xCADF, 0x5FE4, 0xCADE, - 0x5FE5, 0xCC79, 0x5FE8, 0xCADA, 0x5FEA, 0xA7D8, 0x5FEB, 0xA7D6, 0x5FED, 0xCAD9, 0x5FEE, 0xCADB, 0x5FEF, 0xCAE1, 0x5FF1, 0xA7D5, - 0x5FF3, 0xCADC, 0x5FF4, 0xCAE5, 0x5FF5, 0xA9C0, 0x5FF7, 0xCAE2, 0x5FF8, 0xA7D7, 0x5FFA, 0xCAE0, 0x5FFB, 0xCAE3, 0x5FFD, 0xA9BF, - 0x5FFF, 0xA9C1, 0x6000, 0xCAE4, 0x6009, 0xCCAF, 0x600A, 0xCCA2, 0x600B, 0xCC7E, 0x600C, 0xCCAE, 0x600D, 0xCCA9, 0x600E, 0xABE7, - 0x600F, 0xA9C2, 0x6010, 0xCCAA, 0x6011, 0xCCAD, 0x6012, 0xABE3, 0x6013, 0xCCAC, 0x6014, 0xA9C3, 0x6015, 0xA9C8, 0x6016, 0xA9C6, - 0x6017, 0xCCA3, 0x6019, 0xCC7C, 0x601A, 0xCCA5, 0x601B, 0xA9CD, 0x601C, 0xCCB0, 0x601D, 0xABE4, 0x601E, 0xCCA6, 0x6020, 0xABE5, - 0x6021, 0xA9C9, 0x6022, 0xCCA8, 0x6024, 0xCECD, 0x6025, 0xABE6, 0x6026, 0xCC7B, 0x6027, 0xA9CA, 0x6028, 0xABE8, 0x6029, 0xA9CB, - 0x602A, 0xA9C7, 0x602B, 0xA9CC, 0x602C, 0xCCA7, 0x602D, 0xCC7A, 0x602E, 0xCCAB, 0x602F, 0xA9C4, 0x6032, 0xCC7D, 0x6033, 0xCCA4, - 0x6034, 0xCCA1, 0x6035, 0xA9C5, 0x6037, 0xCEBF, 0x6039, 0xCEC0, 0x6040, 0xCECA, 0x6041, 0xD1A1, 0x6042, 0xCECB, 0x6043, 0xABEE, - 0x6044, 0xCECE, 0x6045, 0xCEC4, 0x6046, 0xABED, 0x6047, 0xCEC6, 0x6049, 0xCEC7, 0x604C, 0xCEC9, 0x604D, 0xABE9, 0x6050, 0xAEA3, - 0x6052, 0xF9DA, 0x6053, 0xCEC5, 0x6054, 0xCEC1, 0x6055, 0xAEA4, 0x6058, 0xCECF, 0x6059, 0xAE7E, 0x605A, 0xD17D, 0x605B, 0xCEC8, - 0x605D, 0xD17C, 0x605E, 0xCEC3, 0x605F, 0xCECC, 0x6062, 0xABEC, 0x6063, 0xAEA1, 0x6064, 0xABF2, 0x6065, 0xAEA2, 0x6066, 0xCED0, - 0x6067, 0xD17E, 0x6068, 0xABEB, 0x6069, 0xAEA6, 0x606A, 0xABF1, 0x606B, 0xABF0, 0x606C, 0xABEF, 0x606D, 0xAEA5, 0x606E, 0xCED1, - 0x606F, 0xAEA7, 0x6070, 0xABEA, 0x6072, 0xCEC2, 0x607F, 0xB176, 0x6080, 0xD1A4, 0x6081, 0xD1A6, 0x6083, 0xD1A8, 0x6084, 0xAEA8, - 0x6085, 0xAEAE, 0x6086, 0xD553, 0x6087, 0xD1AC, 0x6088, 0xD1A3, 0x6089, 0xB178, 0x608A, 0xD551, 0x608C, 0xAEAD, 0x608D, 0xAEAB, - 0x608E, 0xD1AE, 0x6090, 0xD552, 0x6092, 0xD1A5, 0x6094, 0xAEAC, 0x6095, 0xD1A9, 0x6096, 0xAEAF, 0x6097, 0xD1AB, 0x609A, 0xAEAA, - 0x609B, 0xD1AA, 0x609C, 0xD1AD, 0x609D, 0xD1A7, 0x609F, 0xAEA9, 0x60A0, 0xB179, 0x60A2, 0xD1A2, 0x60A3, 0xB177, 0x60A8, 0xB17A, - 0x60B0, 0xD555, 0x60B1, 0xD55E, 0x60B2, 0xB464, 0x60B4, 0xB17C, 0x60B5, 0xB1A3, 0x60B6, 0xB465, 0x60B7, 0xD560, 0x60B8, 0xB1AA, - 0x60B9, 0xD8F9, 0x60BA, 0xD556, 0x60BB, 0xB1A2, 0x60BC, 0xB1A5, 0x60BD, 0xB17E, 0x60BE, 0xD554, 0x60BF, 0xD562, 0x60C0, 0xD565, - 0x60C1, 0xD949, 0x60C3, 0xD563, 0x60C4, 0xD8FD, 0x60C5, 0xB1A1, 0x60C6, 0xB1A8, 0x60C7, 0xB1AC, 0x60C8, 0xD55D, 0x60C9, 0xD8F8, - 0x60CA, 0xD561, 0x60CB, 0xB17B, 0x60CC, 0xD8FA, 0x60CD, 0xD564, 0x60CE, 0xD8FC, 0x60CF, 0xD559, 0x60D1, 0xB462, 0x60D3, 0xD557, - 0x60D4, 0xD558, 0x60D5, 0xB1A7, 0x60D8, 0xB1A6, 0x60D9, 0xD55B, 0x60DA, 0xB1AB, 0x60DB, 0xD55F, 0x60DC, 0xB1A4, 0x60DD, 0xD55C, - 0x60DF, 0xB1A9, 0x60E0, 0xB466, 0x60E1, 0xB463, 0x60E2, 0xD8FB, 0x60E4, 0xD55A, 0x60E6, 0xB17D, 0x60F0, 0xB46B, 0x60F1, 0xB46F, - 0x60F2, 0xD940, 0x60F3, 0xB751, 0x60F4, 0xB46D, 0x60F5, 0xD944, 0x60F6, 0xB471, 0x60F7, 0xDD65, 0x60F8, 0xD946, 0x60F9, 0xB753, - 0x60FA, 0xB469, 0x60FB, 0xB46C, 0x60FC, 0xD947, 0x60FE, 0xD948, 0x60FF, 0xD94E, 0x6100, 0xB473, 0x6101, 0xB754, 0x6103, 0xD94A, - 0x6104, 0xD94F, 0x6105, 0xD943, 0x6106, 0xB75E, 0x6108, 0xB755, 0x6109, 0xB472, 0x610A, 0xD941, 0x610B, 0xD950, 0x610D, 0xB75D, - 0x610E, 0xB470, 0x610F, 0xB74E, 0x6110, 0xD94D, 0x6112, 0xB474, 0x6113, 0xD945, 0x6114, 0xD8FE, 0x6115, 0xB46A, 0x6116, 0xD942, - 0x6118, 0xD94B, 0x611A, 0xB74D, 0x611B, 0xB752, 0x611C, 0xB467, 0x611D, 0xD94C, 0x611F, 0xB750, 0x6123, 0xB468, 0x6127, 0xB75C, - 0x6128, 0xE1C3, 0x6129, 0xDD70, 0x612B, 0xDD68, 0x612C, 0xE1C2, 0x612E, 0xDD6C, 0x612F, 0xDD6E, 0x6132, 0xDD6B, 0x6134, 0xB75B, - 0x6136, 0xDD6A, 0x6137, 0xB75F, 0x613B, 0xE1D2, 0x613E, 0xB75A, 0x613F, 0xBA40, 0x6140, 0xDD71, 0x6141, 0xE1C4, 0x6144, 0xB758, - 0x6145, 0xDD69, 0x6146, 0xDD6D, 0x6147, 0xB9FE, 0x6148, 0xB74F, 0x6149, 0xDD66, 0x614A, 0xDD67, 0x614B, 0xBA41, 0x614C, 0xB757, - 0x614D, 0xB759, 0x614E, 0xB756, 0x614F, 0xDD6F, 0x6152, 0xE1C8, 0x6153, 0xE1C9, 0x6154, 0xE1CE, 0x6155, 0xBC7D, 0x6156, 0xE1D5, - 0x6158, 0xBA47, 0x615A, 0xBA46, 0x615B, 0xE1D0, 0x615D, 0xBC7C, 0x615E, 0xE1C5, 0x615F, 0xBA45, 0x6161, 0xE1D4, 0x6162, 0xBA43, - 0x6163, 0xBA44, 0x6165, 0xE1D1, 0x6166, 0xE5AA, 0x6167, 0xBC7A, 0x6168, 0xB46E, 0x616A, 0xE1D3, 0x616B, 0xBCA3, 0x616C, 0xE1CB, - 0x616E, 0xBC7B, 0x6170, 0xBCA2, 0x6171, 0xE1C6, 0x6172, 0xE1CA, 0x6173, 0xE1C7, 0x6174, 0xE1CD, 0x6175, 0xBA48, 0x6176, 0xBC79, - 0x6177, 0xBA42, 0x6179, 0xE57A, 0x617A, 0xE1CF, 0x617C, 0xBCA1, 0x617E, 0xBCA4, 0x6180, 0xE1CC, 0x6182, 0xBC7E, 0x6183, 0xE579, - 0x6189, 0xE57E, 0x618A, 0xBECE, 0x618B, 0xE578, 0x618C, 0xE9A3, 0x618D, 0xE5A9, 0x618E, 0xBCA8, 0x6190, 0xBCA6, 0x6191, 0xBECC, - 0x6192, 0xE5A6, 0x6193, 0xE5A2, 0x6194, 0xBCAC, 0x6196, 0xE978, 0x619A, 0xBCAA, 0x619B, 0xE5A1, 0x619D, 0xE976, 0x619F, 0xE5A5, - 0x61A1, 0xE5A8, 0x61A2, 0xE57D, 0x61A4, 0xBCAB, 0x61A7, 0xBCA5, 0x61A8, 0xE977, 0x61A9, 0xBECD, 0x61AA, 0xE5A7, 0x61AB, 0xBCA7, - 0x61AC, 0xBCA9, 0x61AD, 0xE5A4, 0x61AE, 0xBCAD, 0x61AF, 0xE5A3, 0x61B0, 0xE57C, 0x61B1, 0xE57B, 0x61B2, 0xBECB, 0x61B3, 0xE5AB, - 0x61B4, 0xE97A, 0x61B5, 0xECE0, 0x61B6, 0xBED0, 0x61B8, 0xE9A2, 0x61BA, 0xE97E, 0x61BC, 0xECE1, 0x61BE, 0xBED1, 0x61BF, 0xE9A1, - 0x61C1, 0xE97C, 0x61C2, 0xC0B4, 0x61C3, 0xECDF, 0x61C5, 0xE979, 0x61C6, 0xE97B, 0x61C7, 0xC0B5, 0x61C8, 0xBED3, 0x61C9, 0xC0B3, - 0x61CA, 0xBED2, 0x61CB, 0xC0B7, 0x61CC, 0xE97D, 0x61CD, 0xBECF, 0x61D6, 0xEFCF, 0x61D8, 0xEFC7, 0x61DE, 0xECE7, 0x61DF, 0xEFC8, - 0x61E0, 0xECE3, 0x61E3, 0xC256, 0x61E4, 0xECE5, 0x61E5, 0xECE4, 0x61E6, 0xC0B6, 0x61E7, 0xECE2, 0x61E8, 0xECE6, 0x61E9, 0xEFD0, - 0x61EA, 0xEFCC, 0x61EB, 0xEFCE, 0x61ED, 0xEFC9, 0x61EE, 0xEFCA, 0x61F0, 0xEFCD, 0x61F1, 0xEFCB, 0x61F2, 0xC367, 0x61F5, 0xC36A, - 0x61F6, 0xC369, 0x61F7, 0xC368, 0x61F8, 0xC461, 0x61F9, 0xF44A, 0x61FA, 0xC462, 0x61FB, 0xF241, 0x61FC, 0xC4DF, 0x61FD, 0xF5CC, - 0x61FE, 0xC4E0, 0x61FF, 0xC574, 0x6200, 0xC5CA, 0x6201, 0xF7D9, 0x6203, 0xF7DA, 0x6204, 0xF7DB, 0x6207, 0xF9BA, 0x6208, 0xA4E0, - 0x6209, 0xC97C, 0x620A, 0xA5B3, 0x620C, 0xA6A6, 0x620D, 0xA6A7, 0x620E, 0xA6A5, 0x6210, 0xA6A8, 0x6211, 0xA7DA, 0x6212, 0xA7D9, - 0x6214, 0xCCB1, 0x6215, 0xA9CF, 0x6216, 0xA9CE, 0x6219, 0xD1AF, 0x621A, 0xB1AD, 0x621B, 0xB1AE, 0x621F, 0xB475, 0x6220, 0xDD72, - 0x6221, 0xB760, 0x6222, 0xB761, 0x6223, 0xDD74, 0x6224, 0xDD76, 0x6225, 0xDD75, 0x6227, 0xE1D7, 0x6229, 0xE1D6, 0x622A, 0xBA49, - 0x622B, 0xE1D8, 0x622D, 0xE5AC, 0x622E, 0xBCAE, 0x6230, 0xBED4, 0x6232, 0xC0B8, 0x6233, 0xC257, 0x6234, 0xC0B9, 0x6236, 0xA4E1, - 0x623A, 0xCAE6, 0x623D, 0xCCB2, 0x623E, 0xA9D1, 0x623F, 0xA9D0, 0x6240, 0xA9D2, 0x6241, 0xABF3, 0x6242, 0xCED2, 0x6243, 0xCED3, - 0x6246, 0xD1B0, 0x6247, 0xAEB0, 0x6248, 0xB1AF, 0x6249, 0xB476, 0x624A, 0xD951, 0x624B, 0xA4E2, 0x624D, 0xA47E, 0x624E, 0xA4E3, - 0x6250, 0xC97D, 0x6251, 0xA5B7, 0x6252, 0xA5B6, 0x6253, 0xA5B4, 0x6254, 0xA5B5, 0x6258, 0xA6AB, 0x6259, 0xC9E9, 0x625A, 0xC9EB, - 0x625B, 0xA6AA, 0x625C, 0xC9E3, 0x625E, 0xC9E4, 0x6260, 0xC9EA, 0x6261, 0xC9E6, 0x6262, 0xC9E8, 0x6263, 0xA6A9, 0x6264, 0xC9E5, - 0x6265, 0xC9EC, 0x6266, 0xC9E7, 0x626D, 0xA7E1, 0x626E, 0xA7EA, 0x626F, 0xA7E8, 0x6270, 0xCAF0, 0x6271, 0xCAED, 0x6272, 0xCAF5, - 0x6273, 0xA7E6, 0x6274, 0xCAF6, 0x6276, 0xA7DF, 0x6277, 0xCAF3, 0x6279, 0xA7E5, 0x627A, 0xCAEF, 0x627B, 0xCAEE, 0x627C, 0xA7E3, - 0x627D, 0xCAF4, 0x627E, 0xA7E4, 0x627F, 0xA9D3, 0x6280, 0xA7DE, 0x6281, 0xCAF1, 0x6283, 0xCAE7, 0x6284, 0xA7DB, 0x6286, 0xA7EE, - 0x6287, 0xCAEC, 0x6288, 0xCAF2, 0x6289, 0xA7E0, 0x628A, 0xA7E2, 0x628C, 0xCAE8, 0x628E, 0xCAE9, 0x628F, 0xCAEA, 0x6291, 0xA7ED, - 0x6292, 0xA7E7, 0x6293, 0xA7EC, 0x6294, 0xCAEB, 0x6295, 0xA7EB, 0x6296, 0xA7DD, 0x6297, 0xA7DC, 0x6298, 0xA7E9, 0x62A8, 0xA9E1, - 0x62A9, 0xCCBE, 0x62AA, 0xCCB7, 0x62AB, 0xA9DC, 0x62AC, 0xA9EF, 0x62AD, 0xCCB3, 0x62AE, 0xCCBA, 0x62AF, 0xCCBC, 0x62B0, 0xCCBF, - 0x62B1, 0xA9EA, 0x62B3, 0xCCBB, 0x62B4, 0xCCB4, 0x62B5, 0xA9E8, 0x62B6, 0xCCB8, 0x62B8, 0xCCC0, 0x62B9, 0xA9D9, 0x62BB, 0xCCBD, - 0x62BC, 0xA9E3, 0x62BD, 0xA9E2, 0x62BE, 0xCCB6, 0x62BF, 0xA9D7, 0x62C2, 0xA9D8, 0x62C4, 0xA9D6, 0x62C6, 0xA9EE, 0x62C7, 0xA9E6, - 0x62C8, 0xA9E0, 0x62C9, 0xA9D4, 0x62CA, 0xCCB9, 0x62CB, 0xA9DF, 0x62CC, 0xA9D5, 0x62CD, 0xA9E7, 0x62CE, 0xA9F0, 0x62CF, 0xCED4, - 0x62D0, 0xA9E4, 0x62D1, 0xCCB5, 0x62D2, 0xA9DA, 0x62D3, 0xA9DD, 0x62D4, 0xA9DE, 0x62D6, 0xA9EC, 0x62D7, 0xA9ED, 0x62D8, 0xA9EB, - 0x62D9, 0xA9E5, 0x62DA, 0xA9E9, 0x62DB, 0xA9DB, 0x62DC, 0xABF4, 0x62EB, 0xCEDA, 0x62EC, 0xAC41, 0x62ED, 0xABF8, 0x62EE, 0xABFA, - 0x62EF, 0xAC40, 0x62F0, 0xCEE6, 0x62F1, 0xABFD, 0x62F2, 0xD1B1, 0x62F3, 0xAEB1, 0x62F4, 0xAC43, 0x62F5, 0xCED7, 0x62F6, 0xCEDF, - 0x62F7, 0xABFE, 0x62F8, 0xCEDE, 0x62F9, 0xCEDB, 0x62FA, 0xCEE3, 0x62FB, 0xCEE5, 0x62FC, 0xABF7, 0x62FD, 0xABFB, 0x62FE, 0xAC42, - 0x62FF, 0xAEB3, 0x6300, 0xCEE0, 0x6301, 0xABF9, 0x6302, 0xAC45, 0x6303, 0xCED9, 0x6307, 0xABFC, 0x6308, 0xAEB2, 0x6309, 0xABF6, - 0x630B, 0xCED6, 0x630C, 0xCEDD, 0x630D, 0xCED5, 0x630E, 0xCED8, 0x630F, 0xCEDC, 0x6310, 0xD1B2, 0x6311, 0xAC44, 0x6313, 0xCEE1, - 0x6314, 0xCEE2, 0x6315, 0xCEE4, 0x6316, 0xABF5, 0x6328, 0xAEC1, 0x6329, 0xD1BE, 0x632A, 0xAEBF, 0x632B, 0xAEC0, 0x632C, 0xD1B4, - 0x632D, 0xD1C4, 0x632F, 0xAEB6, 0x6332, 0xD566, 0x6333, 0xD1C6, 0x6334, 0xD1C0, 0x6336, 0xD1B7, 0x6338, 0xD1C9, 0x6339, 0xD1BA, - 0x633A, 0xAEBC, 0x633B, 0xD57D, 0x633C, 0xD1BD, 0x633D, 0xAEBE, 0x633E, 0xAEB5, 0x6340, 0xD1CB, 0x6341, 0xD1BF, 0x6342, 0xAEB8, - 0x6343, 0xD1B8, 0x6344, 0xD1B5, 0x6345, 0xD1B6, 0x6346, 0xAEB9, 0x6347, 0xD1C5, 0x6348, 0xD1CC, 0x6349, 0xAEBB, 0x634A, 0xD1BC, - 0x634B, 0xD1BB, 0x634C, 0xAEC3, 0x634D, 0xAEC2, 0x634E, 0xAEB4, 0x634F, 0xAEBA, 0x6350, 0xAEBD, 0x6351, 0xD1C8, 0x6354, 0xD1C2, - 0x6355, 0xAEB7, 0x6356, 0xD1B3, 0x6357, 0xD1CA, 0x6358, 0xD1C1, 0x6359, 0xD1C3, 0x635A, 0xD1C7, 0x6365, 0xD567, 0x6367, 0xB1B7, - 0x6368, 0xB1CB, 0x6369, 0xB1CA, 0x636B, 0xB1BF, 0x636D, 0xD579, 0x636E, 0xD575, 0x636F, 0xD572, 0x6370, 0xD5A6, 0x6371, 0xB1BA, - 0x6372, 0xB1B2, 0x6375, 0xD577, 0x6376, 0xB4A8, 0x6377, 0xB1B6, 0x6378, 0xD5A1, 0x637A, 0xB1CC, 0x637B, 0xB1C9, 0x637C, 0xD57B, - 0x637D, 0xD56A, 0x6380, 0xB1C8, 0x6381, 0xD5A3, 0x6382, 0xD569, 0x6383, 0xB1BD, 0x6384, 0xB1C1, 0x6385, 0xD5A2, 0x6387, 0xD573, - 0x6388, 0xB1C2, 0x6389, 0xB1BC, 0x638A, 0xD568, 0x638C, 0xB478, 0x638D, 0xD5A5, 0x638E, 0xD571, 0x638F, 0xB1C7, 0x6390, 0xD574, - 0x6391, 0xD5A4, 0x6392, 0xB1C6, 0x6394, 0xD952, 0x6396, 0xB1B3, 0x6397, 0xD56F, 0x6398, 0xB1B8, 0x6399, 0xB1C3, 0x639B, 0xB1BE, - 0x639C, 0xD578, 0x639D, 0xD56E, 0x639E, 0xD56C, 0x639F, 0xD57E, 0x63A0, 0xB1B0, 0x63A1, 0xB1C4, 0x63A2, 0xB1B4, 0x63A3, 0xB477, - 0x63A4, 0xD57C, 0x63A5, 0xB1B5, 0x63A7, 0xB1B1, 0x63A8, 0xB1C0, 0x63A9, 0xB1BB, 0x63AA, 0xB1B9, 0x63AB, 0xD570, 0x63AC, 0xB1C5, - 0x63AD, 0xD56D, 0x63AE, 0xD57A, 0x63AF, 0xD576, 0x63B0, 0xD954, 0x63B1, 0xD953, 0x63BD, 0xD56B, 0x63BE, 0xD964, 0x63C0, 0xB47A, - 0x63C2, 0xD96A, 0x63C3, 0xD959, 0x63C4, 0xD967, 0x63C5, 0xDD77, 0x63C6, 0xB47D, 0x63C7, 0xD96B, 0x63C8, 0xD96E, 0x63C9, 0xB47C, - 0x63CA, 0xD95C, 0x63CB, 0xD96D, 0x63CC, 0xD96C, 0x63CD, 0xB47E, 0x63CE, 0xD955, 0x63CF, 0xB479, 0x63D0, 0xB4A3, 0x63D2, 0xB4A1, - 0x63D3, 0xD969, 0x63D5, 0xD95F, 0x63D6, 0xB4A5, 0x63D7, 0xD970, 0x63D8, 0xD968, 0x63D9, 0xD971, 0x63DA, 0xB4AD, 0x63DB, 0xB4AB, - 0x63DC, 0xD966, 0x63DD, 0xD965, 0x63DF, 0xD963, 0x63E0, 0xD95D, 0x63E1, 0xB4A4, 0x63E3, 0xB4A2, 0x63E4, 0xD1B9, 0x63E5, 0xD956, - 0x63E7, 0xDDB7, 0x63E8, 0xD957, 0x63E9, 0xB47B, 0x63EA, 0xB4AA, 0x63EB, 0xDD79, 0x63ED, 0xB4A6, 0x63EE, 0xB4A7, 0x63EF, 0xD958, - 0x63F0, 0xD96F, 0x63F1, 0xDD78, 0x63F2, 0xD960, 0x63F3, 0xD95B, 0x63F4, 0xB4A9, 0x63F5, 0xD961, 0x63F6, 0xD95E, 0x63F9, 0xB4AE, - 0x6406, 0xB770, 0x6409, 0xDD7C, 0x640A, 0xDDB1, 0x640B, 0xDDB6, 0x640C, 0xDDAA, 0x640D, 0xB76C, 0x640E, 0xDDBB, 0x640F, 0xB769, - 0x6410, 0xDD7A, 0x6412, 0xDD7B, 0x6413, 0xB762, 0x6414, 0xB76B, 0x6415, 0xDDA4, 0x6416, 0xB76E, 0x6417, 0xB76F, 0x6418, 0xDDA5, - 0x641A, 0xDDB2, 0x641B, 0xDDB8, 0x641C, 0xB76A, 0x641E, 0xB764, 0x641F, 0xDDA3, 0x6420, 0xDD7D, 0x6421, 0xDDBA, 0x6422, 0xDDA8, - 0x6423, 0xDDA9, 0x6424, 0xDD7E, 0x6425, 0xDDB4, 0x6426, 0xDDAB, 0x6427, 0xDDB5, 0x6428, 0xDDAD, 0x642A, 0xB765, 0x642B, 0xE1D9, - 0x642C, 0xB768, 0x642D, 0xB766, 0x642E, 0xDDB9, 0x642F, 0xDDB0, 0x6430, 0xDDAC, 0x6433, 0xDDA1, 0x6434, 0xBA53, 0x6435, 0xDDAF, - 0x6436, 0xB76D, 0x6437, 0xDDA7, 0x6439, 0xDDA6, 0x643D, 0xB767, 0x643E, 0xB763, 0x643F, 0xE1EE, 0x6440, 0xDDB3, 0x6441, 0xDDAE, - 0x6443, 0xDDA2, 0x644B, 0xE1E9, 0x644D, 0xE1DA, 0x644E, 0xE1E5, 0x6450, 0xE1EC, 0x6451, 0xBA51, 0x6452, 0xB4AC, 0x6453, 0xE1EA, - 0x6454, 0xBA4C, 0x6458, 0xBA4B, 0x6459, 0xE1F1, 0x645B, 0xE1DB, 0x645C, 0xE1E8, 0x645D, 0xE1DC, 0x645E, 0xE1E7, 0x645F, 0xBA4F, - 0x6460, 0xE1EB, 0x6461, 0xD962, 0x6465, 0xE1F2, 0x6466, 0xE1E3, 0x6467, 0xBA52, 0x6468, 0xE5BA, 0x6469, 0xBCAF, 0x646B, 0xE1F0, - 0x646C, 0xE1EF, 0x646D, 0xBA54, 0x646E, 0xE5AD, 0x646F, 0xBCB0, 0x6470, 0xE5AE, 0x6472, 0xE1DF, 0x6473, 0xE1E0, 0x6474, 0xE1DD, - 0x6475, 0xE1E2, 0x6476, 0xE1DE, 0x6477, 0xE1F3, 0x6478, 0xBA4E, 0x6479, 0xBCB1, 0x647A, 0xBA50, 0x647B, 0xBA55, 0x647D, 0xE1E1, - 0x647F, 0xE1ED, 0x6482, 0xE1E6, 0x6485, 0xE5B1, 0x6487, 0xBA4A, 0x6488, 0xBCB4, 0x6489, 0xE9AA, 0x648A, 0xE5B6, 0x648B, 0xE5B5, - 0x648C, 0xE5B7, 0x648F, 0xE5B4, 0x6490, 0xBCB5, 0x6492, 0xBCBB, 0x6493, 0xBCB8, 0x6495, 0xBCB9, 0x6496, 0xE5AF, 0x6497, 0xE5B2, - 0x6498, 0xE5BC, 0x6499, 0xBCC1, 0x649A, 0xBCBF, 0x649C, 0xE5B3, 0x649D, 0xD95A, 0x649E, 0xBCB2, 0x649F, 0xE5B9, 0x64A0, 0xE5B0, - 0x64A2, 0xBCC2, 0x64A3, 0xE5B8, 0x64A4, 0xBA4D, 0x64A5, 0xBCB7, 0x64A6, 0xE1E4, 0x64A9, 0xBCBA, 0x64AB, 0xBCBE, 0x64AC, 0xBCC0, - 0x64AD, 0xBCBD, 0x64AE, 0xBCBC, 0x64B0, 0xBCB6, 0x64B1, 0xE5BB, 0x64B2, 0xBCB3, 0x64B3, 0xBCC3, 0x64BB, 0xBED8, 0x64BC, 0xBED9, - 0x64BD, 0xE9A9, 0x64BE, 0xBEE2, 0x64BF, 0xBEDF, 0x64C1, 0xBED6, 0x64C2, 0xBEDD, 0x64C3, 0xE9AB, 0x64C4, 0xBEDB, 0x64C5, 0xBED5, - 0x64C7, 0xBEDC, 0x64C9, 0xE9A8, 0x64CA, 0xC0BB, 0x64CB, 0xBED7, 0x64CD, 0xBEDE, 0x64CE, 0xC0BA, 0x64CF, 0xE9A7, 0x64D0, 0xE9A6, - 0x64D2, 0xBEE0, 0x64D4, 0xBEE1, 0x64D6, 0xE9A5, 0x64D7, 0xE9A4, 0x64D8, 0xC0BC, 0x64D9, 0xE9AE, 0x64DA, 0xBEDA, 0x64DB, 0xE9AC, - 0x64E0, 0xC0BD, 0x64E2, 0xC0C2, 0x64E3, 0xECEA, 0x64E4, 0xECEC, 0x64E6, 0xC0BF, 0x64E8, 0xECED, 0x64E9, 0xECE9, 0x64EB, 0xECEB, - 0x64EC, 0xC0C0, 0x64ED, 0xC0C3, 0x64EF, 0xECE8, 0x64F0, 0xC0BE, 0x64F1, 0xC0C1, 0x64F2, 0xC259, 0x64F3, 0xE9AD, 0x64F4, 0xC258, - 0x64F7, 0xC25E, 0x64F8, 0xEFD4, 0x64FA, 0xC25C, 0x64FB, 0xC25D, 0x64FC, 0xEFD7, 0x64FD, 0xEFD3, 0x64FE, 0xC25A, 0x64FF, 0xEFD1, - 0x6500, 0xC36B, 0x6501, 0xEFD5, 0x6503, 0xEFD6, 0x6504, 0xEFD2, 0x6506, 0xC25B, 0x6507, 0xF242, 0x6509, 0xF245, 0x650C, 0xF246, - 0x650D, 0xF244, 0x650E, 0xF247, 0x650F, 0xC36C, 0x6510, 0xF243, 0x6513, 0xF44E, 0x6514, 0xC464, 0x6515, 0xF44D, 0x6516, 0xF44C, - 0x6517, 0xF44B, 0x6518, 0xC463, 0x6519, 0xC465, 0x651B, 0xF5CD, 0x651C, 0xC4E2, 0x651D, 0xC4E1, 0x6520, 0xF6E1, 0x6521, 0xF6E0, - 0x6522, 0xF6E3, 0x6523, 0xC5CB, 0x6524, 0xC575, 0x6525, 0xF7DD, 0x6526, 0xF6E2, 0x6529, 0xF7DC, 0x652A, 0xC5CD, 0x652B, 0xC5CC, - 0x652C, 0xC5F3, 0x652D, 0xF8A9, 0x652E, 0xF8EF, 0x652F, 0xA4E4, 0x6532, 0xD972, 0x6533, 0xE9AF, 0x6536, 0xA6AC, 0x6537, 0xCAF7, - 0x6538, 0xA7F1, 0x6539, 0xA7EF, 0x653B, 0xA7F0, 0x653D, 0xCCC1, 0x653E, 0xA9F1, 0x653F, 0xAC46, 0x6541, 0xCEE7, 0x6543, 0xCEE8, - 0x6545, 0xAC47, 0x6546, 0xD1CE, 0x6548, 0xAEC4, 0x6549, 0xAEC5, 0x654A, 0xD1CD, 0x654F, 0xB1D3, 0x6551, 0xB1CF, 0x6553, 0xD5A7, - 0x6554, 0xB1D6, 0x6555, 0xB1D5, 0x6556, 0xB1CE, 0x6557, 0xB1D1, 0x6558, 0xB1D4, 0x6559, 0xB1D0, 0x655C, 0xD976, 0x655D, 0xB1CD, - 0x655E, 0xB4AF, 0x6562, 0xB4B1, 0x6563, 0xB4B2, 0x6564, 0xD975, 0x6565, 0xD978, 0x6566, 0xB4B0, 0x6567, 0xD973, 0x6568, 0xD977, - 0x656A, 0xD974, 0x656C, 0xB771, 0x656F, 0xDDBC, 0x6572, 0xBA56, 0x6573, 0xE1F4, 0x6574, 0xBEE3, 0x6575, 0xBCC4, 0x6576, 0xE5BD, - 0x6577, 0xBCC5, 0x6578, 0xBCC6, 0x6579, 0xE5BF, 0x657A, 0xE5BE, 0x657B, 0xE5C0, 0x657C, 0xE9B1, 0x657F, 0xE9B0, 0x6580, 0xECEF, - 0x6581, 0xECEE, 0x6582, 0xC0C4, 0x6583, 0xC0C5, 0x6584, 0xF248, 0x6587, 0xA4E5, 0x658C, 0xD979, 0x6590, 0xB4B4, 0x6591, 0xB4B3, - 0x6592, 0xDDBD, 0x6594, 0xEFD8, 0x6595, 0xC4E3, 0x6596, 0xF7DE, 0x6597, 0xA4E6, 0x6599, 0xAEC6, 0x659B, 0xB1D8, 0x659C, 0xB1D7, - 0x659D, 0xD97A, 0x659E, 0xD97B, 0x659F, 0xB772, 0x65A0, 0xE1F5, 0x65A1, 0xBA57, 0x65A2, 0xE9B2, 0x65A4, 0xA4E7, 0x65A5, 0xA5B8, - 0x65A7, 0xA9F2, 0x65A8, 0xCCC2, 0x65AA, 0xCEE9, 0x65AB, 0xAC48, 0x65AC, 0xB1D9, 0x65AE, 0xD97C, 0x65AF, 0xB4B5, 0x65B0, 0xB773, - 0x65B2, 0xE5C1, 0x65B3, 0xE5C2, 0x65B6, 0xECF0, 0x65B7, 0xC25F, 0x65B8, 0xF8F0, 0x65B9, 0xA4E8, 0x65BB, 0xCCC3, 0x65BC, 0xA9F3, - 0x65BD, 0xAC49, 0x65BF, 0xCEEA, 0x65C1, 0xAEC7, 0x65C2, 0xD1D2, 0x65C3, 0xD1D0, 0x65C4, 0xD1D1, 0x65C5, 0xAEC8, 0x65C6, 0xD1CF, - 0x65CB, 0xB1DB, 0x65CC, 0xB1DC, 0x65CD, 0xD5A8, 0x65CE, 0xB1DD, 0x65CF, 0xB1DA, 0x65D0, 0xD97D, 0x65D2, 0xD97E, 0x65D3, 0xDDBE, - 0x65D6, 0xBA59, 0x65D7, 0xBA58, 0x65DA, 0xECF1, 0x65DB, 0xEFD9, 0x65DD, 0xF24A, 0x65DE, 0xF249, 0x65DF, 0xF44F, 0x65E1, 0xC95E, - 0x65E2, 0xAC4A, 0x65E5, 0xA4E9, 0x65E6, 0xA5B9, 0x65E8, 0xA6AE, 0x65E9, 0xA6AD, 0x65EC, 0xA6AF, 0x65ED, 0xA6B0, 0x65EE, 0xC9EE, - 0x65EF, 0xC9ED, 0x65F0, 0xCAF8, 0x65F1, 0xA7F2, 0x65F2, 0xCAFB, 0x65F3, 0xCAFA, 0x65F4, 0xCAF9, 0x65F5, 0xCAFC, 0x65FA, 0xA9F4, - 0x65FB, 0xCCC9, 0x65FC, 0xCCC5, 0x65FD, 0xCCCE, 0x6600, 0xA9FB, 0x6602, 0xA9F9, 0x6603, 0xCCCA, 0x6604, 0xCCC6, 0x6605, 0xCCCD, - 0x6606, 0xA9F8, 0x6607, 0xAA40, 0x6608, 0xCCC8, 0x6609, 0xCCC4, 0x660A, 0xA9FE, 0x660B, 0xCCCB, 0x660C, 0xA9F7, 0x660D, 0xCCCC, - 0x660E, 0xA9FA, 0x660F, 0xA9FC, 0x6610, 0xCCD0, 0x6611, 0xCCCF, 0x6612, 0xCCC7, 0x6613, 0xA9F6, 0x6614, 0xA9F5, 0x6615, 0xA9FD, - 0x661C, 0xCEEF, 0x661D, 0xCEF5, 0x661F, 0xAC50, 0x6620, 0xAC4D, 0x6621, 0xCEEC, 0x6622, 0xCEF1, 0x6624, 0xAC53, 0x6625, 0xAC4B, - 0x6626, 0xCEF0, 0x6627, 0xAC4E, 0x6628, 0xAC51, 0x662B, 0xCEF3, 0x662D, 0xAC4C, 0x662E, 0xCEF8, 0x662F, 0xAC4F, 0x6631, 0xAC52, - 0x6632, 0xCEED, 0x6633, 0xCEF2, 0x6634, 0xCEF6, 0x6635, 0xCEEE, 0x6636, 0xCEEB, 0x6639, 0xCEF7, 0x663A, 0xCEF4, 0x6641, 0xAED0, - 0x6642, 0xAEC9, 0x6643, 0xAECC, 0x6645, 0xAECF, 0x6647, 0xD1D5, 0x6649, 0xAECA, 0x664A, 0xD1D3, 0x664C, 0xAECE, 0x664F, 0xAECB, - 0x6651, 0xD1D6, 0x6652, 0xAECD, 0x6659, 0xD5AC, 0x665A, 0xB1DF, 0x665B, 0xD5AB, 0x665C, 0xD5AD, 0x665D, 0xB1DE, 0x665E, 0xB1E3, - 0x665F, 0xD1D4, 0x6661, 0xD5AA, 0x6662, 0xD5AE, 0x6664, 0xB1E0, 0x6665, 0xD5A9, 0x6666, 0xB1E2, 0x6668, 0xB1E1, 0x666A, 0xD9A7, - 0x666C, 0xD9A2, 0x666E, 0xB4B6, 0x666F, 0xB4BA, 0x6670, 0xB4B7, 0x6671, 0xD9A5, 0x6672, 0xD9A8, 0x6674, 0xB4B8, 0x6676, 0xB4B9, - 0x6677, 0xB4BE, 0x6678, 0xDDC7, 0x6679, 0xD9A6, 0x667A, 0xB4BC, 0x667B, 0xD9A3, 0x667C, 0xD9A1, 0x667E, 0xB4BD, 0x6680, 0xD9A4, - 0x6684, 0xB779, 0x6686, 0xDDBF, 0x6687, 0xB776, 0x6688, 0xB777, 0x6689, 0xB775, 0x668A, 0xDDC4, 0x668B, 0xDDC3, 0x668C, 0xDDC0, - 0x668D, 0xB77B, 0x6690, 0xDDC2, 0x6691, 0xB4BB, 0x6694, 0xDDC6, 0x6695, 0xDDC1, 0x6696, 0xB778, 0x6697, 0xB774, 0x6698, 0xB77A, - 0x6699, 0xDDC5, 0x669D, 0xBA5C, 0x669F, 0xE1F8, 0x66A0, 0xE1F7, 0x66A1, 0xE1F6, 0x66A2, 0xBA5A, 0x66A8, 0xBA5B, 0x66A9, 0xE5C5, - 0x66AA, 0xE5C8, 0x66AB, 0xBCC8, 0x66AE, 0xBCC7, 0x66AF, 0xE5C9, 0x66B0, 0xE5C4, 0x66B1, 0xBCCA, 0x66B2, 0xE5C6, 0x66B4, 0xBCC9, - 0x66B5, 0xE5C3, 0x66B7, 0xE5C7, 0x66B8, 0xBEE9, 0x66B9, 0xBEE6, 0x66BA, 0xE9BB, 0x66BB, 0xE9BA, 0x66BD, 0xE9B9, 0x66BE, 0xE9B4, - 0x66C0, 0xE9B5, 0x66C4, 0xBEE7, 0x66C6, 0xBEE4, 0x66C7, 0xBEE8, 0x66C8, 0xE9B3, 0x66C9, 0xBEE5, 0x66CA, 0xE9B6, 0x66CB, 0xE9B7, - 0x66CC, 0xE9BC, 0x66CF, 0xE9B8, 0x66D2, 0xECF2, 0x66D6, 0xC0C7, 0x66D8, 0xEFDC, 0x66D9, 0xC0C6, 0x66DA, 0xEFDA, 0x66DB, 0xEFDB, - 0x66DC, 0xC260, 0x66DD, 0xC36E, 0x66DE, 0xF24B, 0x66E0, 0xC36D, 0x66E3, 0xF451, 0x66E4, 0xF452, 0x66E6, 0xC466, 0x66E8, 0xF450, - 0x66E9, 0xC4E4, 0x66EB, 0xF7DF, 0x66EC, 0xC5CE, 0x66ED, 0xF8AA, 0x66EE, 0xF8AB, 0x66F0, 0xA4EA, 0x66F2, 0xA6B1, 0x66F3, 0xA6B2, - 0x66F4, 0xA7F3, 0x66F6, 0xCCD1, 0x66F7, 0xAC54, 0x66F8, 0xAED1, 0x66F9, 0xB1E4, 0x66FC, 0xB0D2, 0x66FE, 0xB4BF, 0x66FF, 0xB4C0, - 0x6700, 0xB3CC, 0x6701, 0xD9A9, 0x6703, 0xB77C, 0x6704, 0xE1FA, 0x6705, 0xE1F9, 0x6708, 0xA4EB, 0x6709, 0xA6B3, 0x670A, 0xCCD2, - 0x670B, 0xAA42, 0x670D, 0xAA41, 0x670F, 0xCEF9, 0x6710, 0xCEFA, 0x6712, 0xD1D7, 0x6713, 0xD1D8, 0x6714, 0xAED2, 0x6715, 0xAED3, - 0x6717, 0xAED4, 0x6718, 0xD5AF, 0x671B, 0xB1E6, 0x671D, 0xB4C2, 0x671F, 0xB4C1, 0x6720, 0xDDC8, 0x6721, 0xDF7A, 0x6722, 0xE1FB, - 0x6723, 0xE9BD, 0x6726, 0xC261, 0x6727, 0xC467, 0x6728, 0xA4EC, 0x672A, 0xA5BC, 0x672B, 0xA5BD, 0x672C, 0xA5BB, 0x672D, 0xA5BE, - 0x672E, 0xA5BA, 0x6731, 0xA6B6, 0x6733, 0xC9F6, 0x6734, 0xA6B5, 0x6735, 0xA6B7, 0x6738, 0xC9F1, 0x6739, 0xC9F0, 0x673A, 0xC9F3, - 0x673B, 0xC9F2, 0x673C, 0xC9F5, 0x673D, 0xA6B4, 0x673E, 0xC9EF, 0x673F, 0xC9F4, 0x6745, 0xCAFD, 0x6746, 0xA7FD, 0x6747, 0xCAFE, - 0x6748, 0xCB43, 0x6749, 0xA7FC, 0x674B, 0xCB47, 0x674C, 0xCB42, 0x674D, 0xCB45, 0x674E, 0xA7F5, 0x674F, 0xA7F6, 0x6750, 0xA7F7, - 0x6751, 0xA7F8, 0x6753, 0xA840, 0x6755, 0xCB41, 0x6756, 0xA7FA, 0x6757, 0xA841, 0x6759, 0xCB40, 0x675A, 0xCB46, 0x675C, 0xA7F9, - 0x675D, 0xCB44, 0x675E, 0xA7FB, 0x675F, 0xA7F4, 0x6760, 0xA7FE, 0x676A, 0xAA57, 0x676C, 0xCCD4, 0x676D, 0xAA43, 0x676F, 0xAA4D, - 0x6770, 0xAA4E, 0x6771, 0xAA46, 0x6772, 0xAA58, 0x6773, 0xAA48, 0x6774, 0xCCDC, 0x6775, 0xAA53, 0x6776, 0xCCD7, 0x6777, 0xAA49, - 0x6778, 0xCCE6, 0x6779, 0xCCE7, 0x677A, 0xCCDF, 0x677B, 0xCCD8, 0x677C, 0xAA56, 0x677D, 0xCCE4, 0x677E, 0xAA51, 0x677F, 0xAA4F, - 0x6781, 0xCCE5, 0x6783, 0xCCE3, 0x6784, 0xCCDB, 0x6785, 0xCCD3, 0x6786, 0xCCDA, 0x6787, 0xAA4A, 0x6789, 0xAA50, 0x678B, 0xAA44, - 0x678C, 0xCCDE, 0x678D, 0xCCDD, 0x678E, 0xCCD5, 0x6790, 0xAA52, 0x6791, 0xCCE1, 0x6792, 0xCCD6, 0x6793, 0xAA55, 0x6794, 0xCCE8, - 0x6795, 0xAA45, 0x6797, 0xAA4C, 0x6798, 0xCCD9, 0x6799, 0xCCE2, 0x679A, 0xAA54, 0x679C, 0xAA47, 0x679D, 0xAA4B, 0x679F, 0xCCE0, - 0x67AE, 0xCF5B, 0x67AF, 0xAC5C, 0x67B0, 0xAC69, 0x67B2, 0xCF56, 0x67B3, 0xCF4C, 0x67B4, 0xAC62, 0x67B5, 0xCF4A, 0x67B6, 0xAC5B, - 0x67B7, 0xCF45, 0x67B8, 0xAC65, 0x67B9, 0xCF52, 0x67BA, 0xCEFE, 0x67BB, 0xCF41, 0x67C0, 0xCF44, 0x67C1, 0xCEFB, 0x67C2, 0xCF51, - 0x67C3, 0xCF61, 0x67C4, 0xAC60, 0x67C5, 0xCF46, 0x67C6, 0xCF58, 0x67C8, 0xCEFD, 0x67C9, 0xCF5F, 0x67CA, 0xCF60, 0x67CB, 0xCF63, - 0x67CC, 0xCF5A, 0x67CD, 0xCF4B, 0x67CE, 0xCF53, 0x67CF, 0xAC66, 0x67D0, 0xAC59, 0x67D1, 0xAC61, 0x67D2, 0xAC6D, 0x67D3, 0xAC56, - 0x67D4, 0xAC58, 0x67D8, 0xCF43, 0x67D9, 0xAC6A, 0x67DA, 0xAC63, 0x67DB, 0xCF5D, 0x67DC, 0xCF40, 0x67DD, 0xAC6C, 0x67DE, 0xAC67, - 0x67DF, 0xCF49, 0x67E2, 0xAC6B, 0x67E3, 0xCF50, 0x67E4, 0xCF48, 0x67E5, 0xAC64, 0x67E6, 0xCF5C, 0x67E7, 0xCF54, 0x67E9, 0xAC5E, - 0x67EA, 0xCF62, 0x67EB, 0xCF47, 0x67EC, 0xAC5A, 0x67ED, 0xCF59, 0x67EE, 0xCF4F, 0x67EF, 0xAC5F, 0x67F0, 0xCF55, 0x67F1, 0xAC57, - 0x67F2, 0xCEFC, 0x67F3, 0xAC68, 0x67F4, 0xAEE3, 0x67F5, 0xAC5D, 0x67F6, 0xCF4E, 0x67F7, 0xCF4D, 0x67F8, 0xCF42, 0x67FA, 0xCF5E, - 0x67FC, 0xCF57, 0x67FF, 0xAC55, 0x6812, 0xD1EC, 0x6813, 0xAEEA, 0x6814, 0xD1ED, 0x6816, 0xD1E1, 0x6817, 0xAEDF, 0x6818, 0xAEEB, - 0x681A, 0xD1DA, 0x681C, 0xD1E3, 0x681D, 0xD1EB, 0x681F, 0xD1D9, 0x6820, 0xD1F4, 0x6821, 0xAED5, 0x6825, 0xD1F3, 0x6826, 0xD1EE, - 0x6828, 0xD1EF, 0x6829, 0xAEDD, 0x682A, 0xAEE8, 0x682B, 0xD1E5, 0x682D, 0xD1E6, 0x682E, 0xD1F0, 0x682F, 0xD1E7, 0x6831, 0xD1E2, - 0x6832, 0xD1DC, 0x6833, 0xD1DD, 0x6834, 0xD1EA, 0x6835, 0xD1E4, 0x6838, 0xAED6, 0x6839, 0xAEDA, 0x683A, 0xD1F2, 0x683B, 0xD1DE, - 0x683C, 0xAEE6, 0x683D, 0xAEE2, 0x6840, 0xAEE5, 0x6841, 0xAEEC, 0x6842, 0xAEDB, 0x6843, 0xAEE7, 0x6844, 0xD1E9, 0x6845, 0xAEE9, - 0x6846, 0xAED8, 0x6848, 0xAED7, 0x6849, 0xD1DB, 0x684B, 0xD1DF, 0x684C, 0xAEE0, 0x684D, 0xD1F1, 0x684E, 0xD1E8, 0x684F, 0xD1E0, - 0x6850, 0xAEE4, 0x6851, 0xAEE1, 0x6853, 0xAED9, 0x6854, 0xAEDC, 0x686B, 0xD5C4, 0x686D, 0xD5B4, 0x686E, 0xD5B5, 0x686F, 0xD5B9, - 0x6871, 0xD5C8, 0x6872, 0xD5C5, 0x6874, 0xD5BE, 0x6875, 0xD5BD, 0x6876, 0xB1ED, 0x6877, 0xD5C1, 0x6878, 0xD5D0, 0x6879, 0xD5B0, - 0x687B, 0xD5D1, 0x687C, 0xD5C3, 0x687D, 0xD5D5, 0x687E, 0xD5C9, 0x687F, 0xB1EC, 0x6880, 0xD5C7, 0x6881, 0xB1E7, 0x6882, 0xB1FC, - 0x6883, 0xB1F2, 0x6885, 0xB1F6, 0x6886, 0xB1F5, 0x6887, 0xD5B1, 0x6889, 0xD5CE, 0x688A, 0xD5D4, 0x688B, 0xD5CC, 0x688C, 0xD5D3, - 0x688F, 0xD5C0, 0x6890, 0xD5B2, 0x6891, 0xD5D2, 0x6892, 0xD5C2, 0x6893, 0xB1EA, 0x6894, 0xB1F7, 0x6896, 0xD5CB, 0x6897, 0xB1F0, - 0x689B, 0xD5CA, 0x689C, 0xD5B3, 0x689D, 0xB1F8, 0x689F, 0xB1FA, 0x68A0, 0xD5CD, 0x68A1, 0xB1FB, 0x68A2, 0xB1E9, 0x68A3, 0xD5BA, - 0x68A4, 0xD5CF, 0x68A7, 0xB1EF, 0x68A8, 0xB1F9, 0x68A9, 0xD5BC, 0x68AA, 0xD5C6, 0x68AB, 0xD5B7, 0x68AC, 0xD5BB, 0x68AD, 0xB1F4, - 0x68AE, 0xD5B6, 0x68AF, 0xB1E8, 0x68B0, 0xB1F1, 0x68B1, 0xB1EE, 0x68B2, 0xD5BF, 0x68B3, 0xAEDE, 0x68B4, 0xD9C0, 0x68B5, 0xB1EB, - 0x68C4, 0xB1F3, 0x68C6, 0xD9C3, 0x68C7, 0xD9D9, 0x68C8, 0xD9CE, 0x68C9, 0xB4D6, 0x68CB, 0xB4D1, 0x68CC, 0xD9BD, 0x68CD, 0xB4D2, - 0x68CE, 0xD9CD, 0x68D0, 0xD9C6, 0x68D1, 0xD9D3, 0x68D2, 0xB4CE, 0x68D3, 0xD9AB, 0x68D4, 0xD9D5, 0x68D5, 0xB4C4, 0x68D6, 0xD9B3, - 0x68D7, 0xB4C7, 0x68D8, 0xB4C6, 0x68DA, 0xB4D7, 0x68DC, 0xD9AD, 0x68DD, 0xD9CF, 0x68DE, 0xD9D0, 0x68DF, 0xB4C9, 0x68E0, 0xB4C5, - 0x68E1, 0xD9BB, 0x68E3, 0xB4D0, 0x68E4, 0xD9B6, 0x68E6, 0xD9D1, 0x68E7, 0xB4CC, 0x68E8, 0xD9C9, 0x68E9, 0xD9D6, 0x68EA, 0xD9B0, - 0x68EB, 0xD9B5, 0x68EC, 0xD9AF, 0x68EE, 0xB4CB, 0x68EF, 0xD9C2, 0x68F0, 0xDDDE, 0x68F1, 0xD9B1, 0x68F2, 0xB4CF, 0x68F3, 0xD9BA, - 0x68F4, 0xD9D2, 0x68F5, 0xB4CA, 0x68F6, 0xD9B7, 0x68F7, 0xD9B4, 0x68F8, 0xD9C5, 0x68F9, 0xB4CD, 0x68FA, 0xB4C3, 0x68FB, 0xB4D9, - 0x68FC, 0xD9C8, 0x68FD, 0xD9C7, 0x6904, 0xD9AC, 0x6905, 0xB4C8, 0x6906, 0xD9D4, 0x6907, 0xD9BC, 0x6908, 0xD9BE, 0x690A, 0xD9CB, - 0x690B, 0xD9CA, 0x690C, 0xD9AA, 0x690D, 0xB4D3, 0x690E, 0xB4D5, 0x690F, 0xD9B2, 0x6910, 0xD9B9, 0x6911, 0xD9C1, 0x6912, 0xB4D4, - 0x6913, 0xD9B8, 0x6914, 0xD9C4, 0x6915, 0xD9D7, 0x6917, 0xD9CC, 0x6925, 0xD9D8, 0x692A, 0xD9AE, 0x692F, 0xDDF2, 0x6930, 0xB7A6, - 0x6932, 0xDDF0, 0x6933, 0xDDDB, 0x6934, 0xDDE0, 0x6935, 0xDDD9, 0x6937, 0xDDEC, 0x6938, 0xDDCB, 0x6939, 0xDDD2, 0x693B, 0xDDEA, - 0x693C, 0xDDF4, 0x693D, 0xDDDC, 0x693F, 0xDDCF, 0x6940, 0xDDE2, 0x6941, 0xDDE7, 0x6942, 0xDDD3, 0x6944, 0xDDE4, 0x6945, 0xDDD0, - 0x6948, 0xDDD7, 0x6949, 0xDDD8, 0x694A, 0xB7A8, 0x694B, 0xDDEB, 0x694C, 0xDDE9, 0x694E, 0xDDCC, 0x694F, 0xDDEE, 0x6951, 0xDDEF, - 0x6952, 0xDDF1, 0x6953, 0xB7AC, 0x6954, 0xB7A4, 0x6956, 0xD5B8, 0x6957, 0xDDD4, 0x6958, 0xDDE6, 0x6959, 0xDDD5, 0x695A, 0xB7A1, - 0x695B, 0xB7B1, 0x695C, 0xDDED, 0x695D, 0xB7AF, 0x695E, 0xB7AB, 0x695F, 0xDDCA, 0x6960, 0xB7A3, 0x6962, 0xDDCD, 0x6963, 0xB7B0, - 0x6965, 0xDDDD, 0x6966, 0xDDC9, 0x6968, 0xB7A9, 0x6969, 0xDDE1, 0x696A, 0xDDD1, 0x696B, 0xB7AA, 0x696C, 0xDDDA, 0x696D, 0xB77E, - 0x696E, 0xB4D8, 0x696F, 0xDDE3, 0x6970, 0xD9BF, 0x6971, 0xDDCE, 0x6974, 0xDDE8, 0x6975, 0xB7A5, 0x6976, 0xDDE5, 0x6977, 0xB7A2, - 0x6978, 0xDDDF, 0x6979, 0xB7AD, 0x697A, 0xDDD6, 0x697B, 0xDDF3, 0x6982, 0xB7A7, 0x6983, 0xDEC6, 0x6986, 0xB7AE, 0x698D, 0xE24A, - 0x698E, 0xE248, 0x6990, 0xE25E, 0x6991, 0xE246, 0x6993, 0xE258, 0x6994, 0xB77D, 0x6995, 0xBA5F, 0x6996, 0xE242, 0x6997, 0xE25D, - 0x6999, 0xE247, 0x699A, 0xE255, 0x699B, 0xBA64, 0x699C, 0xBA5D, 0x699E, 0xE25B, 0x69A0, 0xE240, 0x69A1, 0xE25A, 0x69A3, 0xBA6F, - 0x69A4, 0xE251, 0x69A5, 0xE261, 0x69A6, 0xBA6D, 0x69A7, 0xE249, 0x69A8, 0xBA5E, 0x69A9, 0xE24B, 0x69AA, 0xE259, 0x69AB, 0xBA67, - 0x69AC, 0xE244, 0x69AD, 0xBA6B, 0x69AE, 0xBA61, 0x69AF, 0xE24D, 0x69B0, 0xE243, 0x69B1, 0xE1FC, 0x69B3, 0xE257, 0x69B4, 0xBA68, - 0x69B5, 0xE260, 0x69B6, 0xE1FD, 0x69B7, 0xBA65, 0x69B9, 0xE253, 0x69BB, 0xBA66, 0x69BC, 0xE245, 0x69BD, 0xE250, 0x69BE, 0xE24C, - 0x69BF, 0xE24E, 0x69C1, 0xBA60, 0x69C2, 0xE25F, 0x69C3, 0xBA6E, 0x69C4, 0xE24F, 0x69C6, 0xE262, 0x69C9, 0xE1FE, 0x69CA, 0xE254, - 0x69CB, 0xBA63, 0x69CC, 0xBA6C, 0x69CD, 0xBA6A, 0x69CE, 0xE241, 0x69CF, 0xE256, 0x69D0, 0xBA69, 0x69D3, 0xBA62, 0x69D4, 0xE252, - 0x69D9, 0xE25C, 0x69E2, 0xE5D5, 0x69E4, 0xE5D1, 0x69E5, 0xE5CD, 0x69E6, 0xE5E1, 0x69E7, 0xE5DE, 0x69E8, 0xBCCD, 0x69EB, 0xE5E5, - 0x69EC, 0xE5D4, 0x69ED, 0xBCD8, 0x69EE, 0xE5DB, 0x69F1, 0xE5D0, 0x69F2, 0xE5DA, 0x69F3, 0xBCD5, 0x69F4, 0xE5EE, 0x69F6, 0xE5EB, - 0x69F7, 0xE5DD, 0x69F8, 0xE5CE, 0x69FB, 0xE5E2, 0x69FC, 0xE5E4, 0x69FD, 0xBCD1, 0x69FE, 0xE5D8, 0x69FF, 0xE5D3, 0x6A00, 0xE5CA, - 0x6A01, 0xBCCE, 0x6A02, 0xBCD6, 0x6A04, 0xE5E7, 0x6A05, 0xBCD7, 0x6A06, 0xE5CB, 0x6A07, 0xE5ED, 0x6A08, 0xE5E0, 0x6A09, 0xE5E6, - 0x6A0A, 0xBCD4, 0x6A0D, 0xE5E3, 0x6A0F, 0xE5EA, 0x6A11, 0xBCD9, 0x6A13, 0xBCD3, 0x6A14, 0xE5DC, 0x6A15, 0xE5CF, 0x6A16, 0xE5EF, - 0x6A17, 0xE5CC, 0x6A18, 0xE5E8, 0x6A19, 0xBCD0, 0x6A1B, 0xE5D6, 0x6A1D, 0xE5D7, 0x6A1E, 0xBCCF, 0x6A1F, 0xBCCC, 0x6A20, 0xE5D2, - 0x6A21, 0xBCD2, 0x6A23, 0xBCCB, 0x6A25, 0xE5E9, 0x6A26, 0xE5EC, 0x6A27, 0xE5D9, 0x6A28, 0xE9CA, 0x6A32, 0xE9C2, 0x6A34, 0xE9BE, - 0x6A35, 0xBEF6, 0x6A38, 0xBEEB, 0x6A39, 0xBEF0, 0x6A3A, 0xBEEC, 0x6A3B, 0xE9CC, 0x6A3C, 0xE9D7, 0x6A3D, 0xBEEA, 0x6A3E, 0xE9C4, - 0x6A3F, 0xE9CD, 0x6A40, 0xE5DF, 0x6A41, 0xE9CE, 0x6A44, 0xBEF1, 0x6A46, 0xE9DD, 0x6A47, 0xBEF5, 0x6A48, 0xBEF8, 0x6A49, 0xE9C0, - 0x6A4B, 0xBEF4, 0x6A4D, 0xE9DB, 0x6A4E, 0xE9DC, 0x6A4F, 0xE9D2, 0x6A50, 0xE9D1, 0x6A51, 0xE9C9, 0x6A54, 0xE9D3, 0x6A55, 0xE9DA, - 0x6A56, 0xE9D9, 0x6A58, 0xBEEF, 0x6A59, 0xBEED, 0x6A5A, 0xE9CB, 0x6A5B, 0xE9C8, 0x6A5D, 0xE9C5, 0x6A5E, 0xE9D8, 0x6A5F, 0xBEF7, - 0x6A60, 0xE9D6, 0x6A61, 0xBEF3, 0x6A62, 0xBEF2, 0x6A64, 0xE9D0, 0x6A66, 0xE9BF, 0x6A67, 0xE9C1, 0x6A68, 0xE9C3, 0x6A69, 0xE9D5, - 0x6A6A, 0xE9CF, 0x6A6B, 0xBEEE, 0x6A6D, 0xE9C6, 0x6A6F, 0xE9D4, 0x6A76, 0xE9C7, 0x6A7E, 0xC0CF, 0x6A7F, 0xED45, 0x6A80, 0xC0C8, - 0x6A81, 0xECF5, 0x6A83, 0xED41, 0x6A84, 0xC0CA, 0x6A85, 0xED48, 0x6A87, 0xECFC, 0x6A89, 0xECF7, 0x6A8C, 0xED49, 0x6A8D, 0xECF3, - 0x6A8E, 0xECFE, 0x6A90, 0xC0D1, 0x6A91, 0xED44, 0x6A92, 0xED4A, 0x6A93, 0xECFD, 0x6A94, 0xC0C9, 0x6A95, 0xED40, 0x6A96, 0xECF4, - 0x6A97, 0xC0D0, 0x6A9A, 0xED47, 0x6A9B, 0xECF9, 0x6A9C, 0xC0CC, 0x6A9E, 0xECFB, 0x6A9F, 0xECF8, 0x6AA0, 0xC0D2, 0x6AA1, 0xECFA, - 0x6AA2, 0xC0CB, 0x6AA3, 0xC0CE, 0x6AA4, 0xED43, 0x6AA5, 0xECF6, 0x6AA6, 0xED46, 0x6AA8, 0xED42, 0x6AAC, 0xC263, 0x6AAD, 0xEFE7, - 0x6AAE, 0xC268, 0x6AAF, 0xC269, 0x6AB3, 0xC262, 0x6AB4, 0xEFE6, 0x6AB6, 0xEFE3, 0x6AB7, 0xEFE4, 0x6AB8, 0xC266, 0x6AB9, 0xEFDE, - 0x6ABA, 0xEFE2, 0x6ABB, 0xC265, 0x6ABD, 0xEFDF, 0x6AC2, 0xC267, 0x6AC3, 0xC264, 0x6AC5, 0xEFDD, 0x6AC6, 0xEFE1, 0x6AC7, 0xEFE5, - 0x6ACB, 0xF251, 0x6ACC, 0xF24E, 0x6ACD, 0xF257, 0x6ACF, 0xF256, 0x6AD0, 0xF254, 0x6AD1, 0xF24F, 0x6AD3, 0xC372, 0x6AD9, 0xF250, - 0x6ADA, 0xC371, 0x6ADB, 0xC0CD, 0x6ADC, 0xF253, 0x6ADD, 0xC370, 0x6ADE, 0xF258, 0x6ADF, 0xF252, 0x6AE0, 0xF24D, 0x6AE1, 0xEFE0, - 0x6AE5, 0xC36F, 0x6AE7, 0xF24C, 0x6AE8, 0xF456, 0x6AEA, 0xF455, 0x6AEB, 0xF255, 0x6AEC, 0xC468, 0x6AEE, 0xF459, 0x6AEF, 0xF45A, - 0x6AF0, 0xF454, 0x6AF1, 0xF458, 0x6AF3, 0xF453, 0x6AF8, 0xF5D1, 0x6AF9, 0xF457, 0x6AFA, 0xC4E7, 0x6AFB, 0xC4E5, 0x6AFC, 0xF5CF, - 0x6B00, 0xF5D2, 0x6B02, 0xF5CE, 0x6B03, 0xF5D0, 0x6B04, 0xC4E6, 0x6B08, 0xF6E5, 0x6B09, 0xF6E6, 0x6B0A, 0xC576, 0x6B0B, 0xF6E4, - 0x6B0F, 0xF7E2, 0x6B10, 0xC5CF, 0x6B11, 0xF7E0, 0x6B12, 0xF7E1, 0x6B13, 0xF8AC, 0x6B16, 0xC656, 0x6B17, 0xF8F3, 0x6B18, 0xF8F1, - 0x6B19, 0xF8F2, 0x6B1A, 0xF8F4, 0x6B1E, 0xF9BB, 0x6B20, 0xA4ED, 0x6B21, 0xA6B8, 0x6B23, 0xAA59, 0x6B25, 0xCCE9, 0x6B28, 0xCF64, - 0x6B2C, 0xD1F5, 0x6B2D, 0xD1F7, 0x6B2F, 0xD1F6, 0x6B31, 0xD1F8, 0x6B32, 0xB1FD, 0x6B33, 0xD5D7, 0x6B34, 0xD1F9, 0x6B36, 0xD5D6, - 0x6B37, 0xD5D8, 0x6B38, 0xD5D9, 0x6B39, 0xD9DA, 0x6B3A, 0xB4DB, 0x6B3B, 0xD9DB, 0x6B3C, 0xD9DD, 0x6B3D, 0xB4DC, 0x6B3E, 0xB4DA, - 0x6B3F, 0xD9DC, 0x6B41, 0xDDFA, 0x6B42, 0xDDF8, 0x6B43, 0xDDF7, 0x6B45, 0xDDF6, 0x6B46, 0xDDF5, 0x6B47, 0xB7B2, 0x6B48, 0xDDF9, - 0x6B49, 0xBA70, 0x6B4A, 0xE263, 0x6B4B, 0xE265, 0x6B4C, 0xBA71, 0x6B4D, 0xE264, 0x6B4E, 0xBCDB, 0x6B50, 0xBCDA, 0x6B51, 0xE5F0, - 0x6B54, 0xE9DF, 0x6B55, 0xE9DE, 0x6B56, 0xE9E0, 0x6B59, 0xBEF9, 0x6B5B, 0xED4B, 0x6B5C, 0xC0D3, 0x6B5E, 0xEFE8, 0x6B5F, 0xC26A, - 0x6B60, 0xF259, 0x6B61, 0xC577, 0x6B62, 0xA4EE, 0x6B63, 0xA5BF, 0x6B64, 0xA6B9, 0x6B65, 0xA842, 0x6B66, 0xAA5A, 0x6B67, 0xAA5B, - 0x6B6A, 0xAC6E, 0x6B6D, 0xD1FA, 0x6B72, 0xB7B3, 0x6B76, 0xE6D1, 0x6B77, 0xBEFA, 0x6B78, 0xC26B, 0x6B79, 0xA4EF, 0x6B7B, 0xA6BA, - 0x6B7E, 0xCCEB, 0x6B7F, 0xAA5C, 0x6B80, 0xCCEA, 0x6B82, 0xCF65, 0x6B83, 0xAC6F, 0x6B84, 0xCF66, 0x6B86, 0xAC70, 0x6B88, 0xD1FC, - 0x6B89, 0xAEEE, 0x6B8A, 0xAEED, 0x6B8C, 0xD5DE, 0x6B8D, 0xD5DC, 0x6B8E, 0xD5DD, 0x6B8F, 0xD5DB, 0x6B91, 0xD5DA, 0x6B94, 0xD9DE, - 0x6B95, 0xD9E1, 0x6B96, 0xB4DE, 0x6B97, 0xD9DF, 0x6B98, 0xB4DD, 0x6B99, 0xD9E0, 0x6B9B, 0xDDFB, 0x6B9E, 0xE266, 0x6B9F, 0xE267, - 0x6BA0, 0xE268, 0x6BA2, 0xE5F3, 0x6BA3, 0xE5F2, 0x6BA4, 0xBCDC, 0x6BA5, 0xE5F1, 0x6BA6, 0xE5F4, 0x6BA7, 0xE9E1, 0x6BAA, 0xE9E2, - 0x6BAB, 0xE9E3, 0x6BAD, 0xED4C, 0x6BAE, 0xC0D4, 0x6BAF, 0xC26C, 0x6BB0, 0xF25A, 0x6BB2, 0xC4E8, 0x6BB3, 0xC95F, 0x6BB5, 0xAC71, - 0x6BB6, 0xCF67, 0x6BB7, 0xAEEF, 0x6BBA, 0xB1FE, 0x6BBC, 0xB4DF, 0x6BBD, 0xD9E2, 0x6BBF, 0xB7B5, 0x6BC0, 0xB7B4, 0x6BC3, 0xE269, - 0x6BC4, 0xE26A, 0x6BC5, 0xBCDD, 0x6BC6, 0xBCDE, 0x6BC7, 0xE9E5, 0x6BC8, 0xE9E4, 0x6BC9, 0xEFE9, 0x6BCA, 0xF7E3, 0x6BCB, 0xA4F0, - 0x6BCC, 0xC960, 0x6BCD, 0xA5C0, 0x6BCF, 0xA843, 0x6BD0, 0xCB48, 0x6BD2, 0xAC72, 0x6BD3, 0xB7B6, 0x6BD4, 0xA4F1, 0x6BD6, 0xCF68, - 0x6BD7, 0xAC73, 0x6BD8, 0xCF69, 0x6BDA, 0xC0D5, 0x6BDB, 0xA4F2, 0x6BDE, 0xCCEC, 0x6BE0, 0xCF6A, 0x6BE2, 0xD242, 0x6BE3, 0xD241, - 0x6BE4, 0xD1FE, 0x6BE6, 0xD1FD, 0x6BE7, 0xD243, 0x6BE8, 0xD240, 0x6BEB, 0xB240, 0x6BEC, 0xB241, 0x6BEF, 0xB4E0, 0x6BF0, 0xD9E3, - 0x6BF2, 0xD9E4, 0x6BF3, 0xD9E5, 0x6BF7, 0xDE41, 0x6BF8, 0xDE42, 0x6BF9, 0xDE40, 0x6BFB, 0xDDFD, 0x6BFC, 0xDDFE, 0x6BFD, 0xB7B7, - 0x6BFE, 0xE26B, 0x6BFF, 0xE5F7, 0x6C00, 0xE5F6, 0x6C01, 0xE5F5, 0x6C02, 0xE5F8, 0x6C03, 0xE9E7, 0x6C04, 0xE9E6, 0x6C05, 0xBEFB, - 0x6C06, 0xE9E8, 0x6C08, 0xC0D6, 0x6C09, 0xED4D, 0x6C0B, 0xEFEA, 0x6C0C, 0xF25B, 0x6C0D, 0xF6E7, 0x6C0F, 0xA4F3, 0x6C10, 0xA5C2, - 0x6C11, 0xA5C1, 0x6C13, 0xAA5D, 0x6C14, 0xC961, 0x6C15, 0xC97E, 0x6C16, 0xA6BB, 0x6C18, 0xC9F7, 0x6C19, 0xCB49, 0x6C1A, 0xCB4A, - 0x6C1B, 0xAA5E, 0x6C1D, 0xCCED, 0x6C1F, 0xAC74, 0x6C20, 0xCF6B, 0x6C21, 0xCF6C, 0x6C23, 0xAEF0, 0x6C24, 0xAEF4, 0x6C25, 0xD244, - 0x6C26, 0xAEF3, 0x6C27, 0xAEF1, 0x6C28, 0xAEF2, 0x6C2A, 0xD5DF, 0x6C2B, 0xB242, 0x6C2C, 0xB4E3, 0x6C2E, 0xB4E1, 0x6C2F, 0xB4E2, - 0x6C30, 0xD9E6, 0x6C33, 0xBA72, 0x6C34, 0xA4F4, 0x6C36, 0xC9A1, 0x6C38, 0xA5C3, 0x6C3B, 0xC9A4, 0x6C3E, 0xA5C6, 0x6C3F, 0xC9A3, - 0x6C40, 0xA5C5, 0x6C41, 0xA5C4, 0x6C42, 0xA844, 0x6C43, 0xC9A2, 0x6C46, 0xC9F8, 0x6C4A, 0xC9FC, 0x6C4B, 0xC9FE, 0x6C4C, 0xCA40, - 0x6C4D, 0xA6C5, 0x6C4E, 0xA6C6, 0x6C4F, 0xC9FB, 0x6C50, 0xA6C1, 0x6C52, 0xC9F9, 0x6C54, 0xC9FD, 0x6C55, 0xA6C2, 0x6C57, 0xA6BD, - 0x6C59, 0xA6BE, 0x6C5B, 0xA6C4, 0x6C5C, 0xC9FA, 0x6C5D, 0xA6BC, 0x6C5E, 0xA845, 0x6C5F, 0xA6BF, 0x6C60, 0xA6C0, 0x6C61, 0xA6C3, - 0x6C65, 0xCB5B, 0x6C66, 0xCB59, 0x6C67, 0xCB4C, 0x6C68, 0xA851, 0x6C69, 0xCB53, 0x6C6A, 0xA84C, 0x6C6B, 0xCB4D, 0x6C6D, 0xCB55, - 0x6C6F, 0xCB52, 0x6C70, 0xA84F, 0x6C71, 0xCB51, 0x6C72, 0xA856, 0x6C73, 0xCB5A, 0x6C74, 0xA858, 0x6C76, 0xA85A, 0x6C78, 0xCB4B, - 0x6C7A, 0xA84D, 0x6C7B, 0xCB5C, 0x6C7D, 0xA854, 0x6C7E, 0xA857, 0x6C80, 0xCD45, 0x6C81, 0xA847, 0x6C82, 0xA85E, 0x6C83, 0xA855, - 0x6C84, 0xCB4E, 0x6C85, 0xA84A, 0x6C86, 0xA859, 0x6C87, 0xCB56, 0x6C88, 0xA848, 0x6C89, 0xA849, 0x6C8A, 0xCD43, 0x6C8B, 0xCB4F, - 0x6C8C, 0xA850, 0x6C8D, 0xA85B, 0x6C8E, 0xCB5D, 0x6C8F, 0xCB50, 0x6C90, 0xA84E, 0x6C92, 0xA853, 0x6C93, 0xCCEE, 0x6C94, 0xA85C, - 0x6C95, 0xCB57, 0x6C96, 0xA852, 0x6C98, 0xA85D, 0x6C99, 0xA846, 0x6C9A, 0xCB54, 0x6C9B, 0xA84B, 0x6C9C, 0xCB58, 0x6C9D, 0xCD44, - 0x6CAB, 0xAA6A, 0x6CAC, 0xAA7A, 0x6CAD, 0xCCF5, 0x6CAE, 0xAA71, 0x6CB0, 0xCD4B, 0x6CB1, 0xAA62, 0x6CB3, 0xAA65, 0x6CB4, 0xCD42, - 0x6CB6, 0xCCF3, 0x6CB7, 0xCCF7, 0x6CB8, 0xAA6D, 0x6CB9, 0xAA6F, 0x6CBA, 0xCCFA, 0x6CBB, 0xAA76, 0x6CBC, 0xAA68, 0x6CBD, 0xAA66, - 0x6CBE, 0xAA67, 0x6CBF, 0xAA75, 0x6CC0, 0xCD47, 0x6CC1, 0xAA70, 0x6CC2, 0xCCF9, 0x6CC3, 0xCCFB, 0x6CC4, 0xAA6E, 0x6CC5, 0xAA73, - 0x6CC6, 0xCCFC, 0x6CC7, 0xCD4A, 0x6CC9, 0xAC75, 0x6CCA, 0xAA79, 0x6CCC, 0xAA63, 0x6CCD, 0xCD49, 0x6CCF, 0xCD4D, 0x6CD0, 0xCCF8, - 0x6CD1, 0xCD4F, 0x6CD2, 0xCD40, 0x6CD3, 0xAA6C, 0x6CD4, 0xCCF4, 0x6CD5, 0xAA6B, 0x6CD6, 0xAA7D, 0x6CD7, 0xAA72, 0x6CD9, 0xCCF2, - 0x6CDA, 0xCF75, 0x6CDB, 0xAA78, 0x6CDC, 0xAA7C, 0x6CDD, 0xCD41, 0x6CDE, 0xCD46, 0x6CE0, 0xAA7E, 0x6CE1, 0xAA77, 0x6CE2, 0xAA69, - 0x6CE3, 0xAA5F, 0x6CE5, 0xAA64, 0x6CE7, 0xCCF6, 0x6CE8, 0xAA60, 0x6CE9, 0xCD4E, 0x6CEB, 0xCCF0, 0x6CEC, 0xCCEF, 0x6CED, 0xCCFD, - 0x6CEE, 0xCCF1, 0x6CEF, 0xAA7B, 0x6CF0, 0xAEF5, 0x6CF1, 0xAA74, 0x6CF2, 0xCCFE, 0x6CF3, 0xAA61, 0x6CF5, 0xACA6, 0x6CF9, 0xCD4C, - 0x6D00, 0xCF7C, 0x6D01, 0xCFA1, 0x6D03, 0xCFA4, 0x6D04, 0xCF77, 0x6D07, 0xCFA7, 0x6D08, 0xCFAA, 0x6D09, 0xCFAC, 0x6D0A, 0xCF74, - 0x6D0B, 0xAC76, 0x6D0C, 0xAC7B, 0x6D0D, 0xD249, 0x6D0E, 0xACAD, 0x6D0F, 0xCFA5, 0x6D10, 0xCFAD, 0x6D11, 0xCF7B, 0x6D12, 0xCF73, - 0x6D16, 0xD264, 0x6D17, 0xAC7E, 0x6D18, 0xCFA2, 0x6D19, 0xCF78, 0x6D1A, 0xCF7A, 0x6D1B, 0xACA5, 0x6D1D, 0xCF7D, 0x6D1E, 0xAC7D, - 0x6D1F, 0xCF70, 0x6D20, 0xCFA8, 0x6D22, 0xCFAB, 0x6D25, 0xAC7A, 0x6D27, 0xACA8, 0x6D28, 0xCF6D, 0x6D29, 0xACAA, 0x6D2A, 0xAC78, - 0x6D2B, 0xACAE, 0x6D2C, 0xCFA9, 0x6D2D, 0xCF6F, 0x6D2E, 0xACAB, 0x6D2F, 0xD25E, 0x6D30, 0xCD48, 0x6D31, 0xAC7C, 0x6D32, 0xAC77, - 0x6D33, 0xCF76, 0x6D34, 0xCF6E, 0x6D35, 0xACAC, 0x6D36, 0xACA4, 0x6D37, 0xCFA3, 0x6D38, 0xACA9, 0x6D39, 0xACA7, 0x6D3A, 0xCF79, - 0x6D3B, 0xACA1, 0x6D3C, 0xCF71, 0x6D3D, 0xACA2, 0x6D3E, 0xACA3, 0x6D3F, 0xCF72, 0x6D40, 0xCFA6, 0x6D41, 0xAC79, 0x6D42, 0xCF7E, - 0x6D58, 0xD24C, 0x6D59, 0xAEFD, 0x6D5A, 0xAF43, 0x6D5E, 0xD255, 0x6D5F, 0xD25B, 0x6D60, 0xD257, 0x6D61, 0xD24A, 0x6D62, 0xD24D, - 0x6D63, 0xD246, 0x6D64, 0xD247, 0x6D65, 0xAF4A, 0x6D66, 0xAEFA, 0x6D67, 0xD256, 0x6D68, 0xD25F, 0x6D69, 0xAF45, 0x6D6A, 0xAEF6, - 0x6D6C, 0xAF40, 0x6D6D, 0xD24E, 0x6D6E, 0xAF42, 0x6D6F, 0xD24F, 0x6D70, 0xD259, 0x6D74, 0xAF44, 0x6D75, 0xD268, 0x6D76, 0xD248, - 0x6D77, 0xAEFC, 0x6D78, 0xAEFB, 0x6D79, 0xAF48, 0x6D7A, 0xD245, 0x6D7B, 0xD266, 0x6D7C, 0xD25A, 0x6D7D, 0xD267, 0x6D7E, 0xD261, - 0x6D7F, 0xD253, 0x6D80, 0xD262, 0x6D82, 0xD25C, 0x6D83, 0xD265, 0x6D84, 0xD263, 0x6D85, 0xAF49, 0x6D86, 0xD254, 0x6D87, 0xAEF9, - 0x6D88, 0xAEF8, 0x6D89, 0xAF41, 0x6D8A, 0xAF47, 0x6D8B, 0xD260, 0x6D8C, 0xAF46, 0x6D8D, 0xD251, 0x6D8E, 0xB243, 0x6D90, 0xD269, - 0x6D91, 0xD250, 0x6D92, 0xD24B, 0x6D93, 0xAEFE, 0x6D94, 0xAF4B, 0x6D95, 0xAEF7, 0x6D97, 0xD258, 0x6D98, 0xD25D, 0x6DAA, 0xB265, - 0x6DAB, 0xD5E1, 0x6DAC, 0xD5E5, 0x6DAE, 0xB252, 0x6DAF, 0xB250, 0x6DB2, 0xB247, 0x6DB3, 0xD5E3, 0x6DB4, 0xD5E2, 0x6DB5, 0xB25B, - 0x6DB7, 0xD5E8, 0x6DB8, 0xB255, 0x6DBA, 0xD5FA, 0x6DBB, 0xD647, 0x6DBC, 0xB244, 0x6DBD, 0xD5F7, 0x6DBE, 0xD5F0, 0x6DBF, 0xB267, - 0x6DC0, 0xD5E0, 0x6DC2, 0xD5FC, 0x6DC4, 0xB264, 0x6DC5, 0xB258, 0x6DC6, 0xB263, 0x6DC7, 0xB24E, 0x6DC8, 0xD5EC, 0x6DC9, 0xD5FE, - 0x6DCA, 0xD5F6, 0x6DCB, 0xB24F, 0x6DCC, 0xB249, 0x6DCD, 0xD645, 0x6DCF, 0xD5FD, 0x6DD0, 0xD640, 0x6DD1, 0xB251, 0x6DD2, 0xB259, - 0x6DD3, 0xD642, 0x6DD4, 0xD5EA, 0x6DD5, 0xD5FB, 0x6DD6, 0xD5EF, 0x6DD7, 0xD644, 0x6DD8, 0xB25E, 0x6DD9, 0xB246, 0x6DDA, 0xB25C, - 0x6DDB, 0xD5F4, 0x6DDC, 0xD5F2, 0x6DDD, 0xD5F3, 0x6DDE, 0xB253, 0x6DDF, 0xD5EE, 0x6DE0, 0xD5ED, 0x6DE1, 0xB248, 0x6DE2, 0xD5E7, - 0x6DE3, 0xD646, 0x6DE4, 0xB24A, 0x6DE5, 0xD5F1, 0x6DE6, 0xB268, 0x6DE8, 0xB262, 0x6DE9, 0xD5E6, 0x6DEA, 0xB25F, 0x6DEB, 0xB25D, - 0x6DEC, 0xB266, 0x6DED, 0xD5F8, 0x6DEE, 0xB261, 0x6DEF, 0xD252, 0x6DF0, 0xD5F9, 0x6DF1, 0xB260, 0x6DF2, 0xD641, 0x6DF3, 0xB245, - 0x6DF4, 0xD5F5, 0x6DF5, 0xB257, 0x6DF6, 0xD5E9, 0x6DF7, 0xB256, 0x6DF9, 0xB254, 0x6DFA, 0xB24C, 0x6DFB, 0xB24B, 0x6DFC, 0xD9E7, - 0x6DFD, 0xD643, 0x6E00, 0xD5EB, 0x6E03, 0xD9FC, 0x6E05, 0xB24D, 0x6E19, 0xB541, 0x6E1A, 0xB25A, 0x6E1B, 0xB4EE, 0x6E1C, 0xD9F6, - 0x6E1D, 0xB4FC, 0x6E1F, 0xD9EA, 0x6E20, 0xB4EB, 0x6E21, 0xB4E7, 0x6E22, 0xDA49, 0x6E23, 0xB4ED, 0x6E24, 0xB4F1, 0x6E25, 0xB4EC, - 0x6E26, 0xB4F5, 0x6E27, 0xDA4D, 0x6E28, 0xDA44, 0x6E2B, 0xD9F1, 0x6E2C, 0xB4FA, 0x6E2D, 0xB4F4, 0x6E2E, 0xD9FD, 0x6E2F, 0xB4E4, - 0x6E30, 0xDA4A, 0x6E31, 0xDA43, 0x6E32, 0xB4E8, 0x6E33, 0xD9F7, 0x6E34, 0xB4F7, 0x6E35, 0xDA55, 0x6E36, 0xDA56, 0x6E38, 0xB4E5, - 0x6E39, 0xDA48, 0x6E3A, 0xB4F9, 0x6E3B, 0xD9FB, 0x6E3C, 0xD9ED, 0x6E3D, 0xD9EE, 0x6E3E, 0xB4FD, 0x6E3F, 0xD9F2, 0x6E40, 0xD9F9, - 0x6E41, 0xD9F3, 0x6E43, 0xB4FB, 0x6E44, 0xB544, 0x6E45, 0xD9EF, 0x6E46, 0xD9E8, 0x6E47, 0xD9E9, 0x6E49, 0xD9EB, 0x6E4A, 0xB4EA, - 0x6E4B, 0xD9F8, 0x6E4D, 0xB4F8, 0x6E4E, 0xB542, 0x6E51, 0xD9FA, 0x6E52, 0xDA53, 0x6E53, 0xDA4B, 0x6E54, 0xB4E6, 0x6E55, 0xDA51, - 0x6E56, 0xB4F2, 0x6E58, 0xB4F0, 0x6E5A, 0xDA57, 0x6E5B, 0xB4EF, 0x6E5C, 0xDA41, 0x6E5D, 0xD9F4, 0x6E5E, 0xD9FE, 0x6E5F, 0xB547, - 0x6E60, 0xDA45, 0x6E61, 0xDA42, 0x6E62, 0xD9F0, 0x6E63, 0xB543, 0x6E64, 0xDA4F, 0x6E65, 0xDA4C, 0x6E66, 0xDA54, 0x6E67, 0xB4E9, - 0x6E68, 0xDA40, 0x6E69, 0xB546, 0x6E6B, 0xDA47, 0x6E6E, 0xB4F3, 0x6E6F, 0xB4F6, 0x6E71, 0xDA46, 0x6E72, 0xB545, 0x6E73, 0xD9F5, - 0x6E74, 0xD5E4, 0x6E77, 0xDA50, 0x6E78, 0xDA4E, 0x6E79, 0xDA52, 0x6E88, 0xD9EC, 0x6E89, 0xB540, 0x6E8D, 0xDE61, 0x6E8E, 0xDE60, - 0x6E8F, 0xDE46, 0x6E90, 0xB7BD, 0x6E92, 0xDE5F, 0x6E93, 0xDE49, 0x6E94, 0xDE4A, 0x6E96, 0xB7C7, 0x6E97, 0xDE68, 0x6E98, 0xB7C2, - 0x6E99, 0xDE5E, 0x6E9B, 0xDE43, 0x6E9C, 0xB7C8, 0x6E9D, 0xB7BE, 0x6E9E, 0xDE52, 0x6E9F, 0xDE48, 0x6EA0, 0xDE4B, 0x6EA1, 0xDE63, - 0x6EA2, 0xB7B8, 0x6EA3, 0xDE6A, 0x6EA4, 0xDE62, 0x6EA5, 0xB7C1, 0x6EA6, 0xDE57, 0x6EA7, 0xB7CC, 0x6EAA, 0xB7CB, 0x6EAB, 0xB7C5, - 0x6EAE, 0xDE69, 0x6EAF, 0xB7B9, 0x6EB0, 0xDE55, 0x6EB1, 0xDE4C, 0x6EB2, 0xDE59, 0x6EB3, 0xDE65, 0x6EB4, 0xB7CD, 0x6EB6, 0xB7BB, - 0x6EB7, 0xDE54, 0x6EB9, 0xDE4D, 0x6EBA, 0xB7C4, 0x6EBC, 0xB7C3, 0x6EBD, 0xDE50, 0x6EBE, 0xDE5A, 0x6EBF, 0xDE64, 0x6EC0, 0xDE47, - 0x6EC1, 0xDE51, 0x6EC2, 0xB7BC, 0x6EC3, 0xDE5B, 0x6EC4, 0xB7C9, 0x6EC5, 0xB7C0, 0x6EC6, 0xDE4E, 0x6EC7, 0xB7BF, 0x6EC8, 0xDE45, - 0x6EC9, 0xDE53, 0x6ECA, 0xDE67, 0x6ECB, 0xB4FE, 0x6ECC, 0xBAB0, 0x6ECD, 0xDE56, 0x6ECE, 0xE26C, 0x6ECF, 0xDE58, 0x6ED0, 0xDE66, - 0x6ED1, 0xB7C6, 0x6ED2, 0xDE4F, 0x6ED3, 0xB7BA, 0x6ED4, 0xB7CA, 0x6ED5, 0xBCF0, 0x6ED6, 0xDE44, 0x6ED8, 0xDE5D, 0x6EDC, 0xDE5C, - 0x6EEB, 0xE2AA, 0x6EEC, 0xBAAD, 0x6EED, 0xE27D, 0x6EEE, 0xE2A4, 0x6EEF, 0xBAA2, 0x6EF1, 0xE26E, 0x6EF2, 0xBAAF, 0x6EF4, 0xBA77, - 0x6EF5, 0xE26D, 0x6EF6, 0xE2B0, 0x6EF7, 0xBAB1, 0x6EF8, 0xE271, 0x6EF9, 0xE2A3, 0x6EFB, 0xE273, 0x6EFC, 0xE2B3, 0x6EFD, 0xE2AF, - 0x6EFE, 0xBA75, 0x6EFF, 0xBAA1, 0x6F00, 0xE653, 0x6F01, 0xBAAE, 0x6F02, 0xBA7D, 0x6F03, 0xE26F, 0x6F05, 0xE2AE, 0x6F06, 0xBAA3, - 0x6F07, 0xE2AB, 0x6F08, 0xE2B8, 0x6F09, 0xE275, 0x6F0A, 0xE27E, 0x6F0D, 0xE2B6, 0x6F0E, 0xE2AC, 0x6F0F, 0xBA7C, 0x6F12, 0xE27C, - 0x6F13, 0xBA76, 0x6F14, 0xBA74, 0x6F15, 0xBAA8, 0x6F18, 0xE27A, 0x6F19, 0xE277, 0x6F1A, 0xE278, 0x6F1C, 0xE2B2, 0x6F1E, 0xE2B7, - 0x6F1F, 0xE2B5, 0x6F20, 0xBA7A, 0x6F21, 0xE2B9, 0x6F22, 0xBA7E, 0x6F23, 0xBAA7, 0x6F25, 0xE270, 0x6F26, 0xE5FA, 0x6F27, 0xE279, - 0x6F29, 0xBA78, 0x6F2A, 0xBAAC, 0x6F2B, 0xBAA9, 0x6F2C, 0xBA7B, 0x6F2D, 0xE2A5, 0x6F2E, 0xE274, 0x6F2F, 0xBAAA, 0x6F30, 0xE2A7, - 0x6F31, 0xBAA4, 0x6F32, 0xBAA6, 0x6F33, 0xBA73, 0x6F35, 0xE2A9, 0x6F36, 0xE2A1, 0x6F37, 0xE272, 0x6F38, 0xBAA5, 0x6F39, 0xE2B1, - 0x6F3A, 0xE2B4, 0x6F3B, 0xE27B, 0x6F3C, 0xE2A8, 0x6F3E, 0xBA79, 0x6F3F, 0xBCDF, 0x6F40, 0xE2A6, 0x6F41, 0xE5F9, 0x6F43, 0xE2AD, - 0x6F4E, 0xE276, 0x6F4F, 0xE644, 0x6F50, 0xE64E, 0x6F51, 0xBCE2, 0x6F52, 0xE64D, 0x6F53, 0xE659, 0x6F54, 0xBCE4, 0x6F55, 0xE64B, - 0x6F57, 0xE64F, 0x6F58, 0xBCEF, 0x6F5A, 0xE646, 0x6F5B, 0xBCE7, 0x6F5D, 0xE652, 0x6F5E, 0xE9F0, 0x6F5F, 0xBCF3, 0x6F60, 0xBCF2, - 0x6F61, 0xE654, 0x6F62, 0xE643, 0x6F63, 0xE65E, 0x6F64, 0xBCED, 0x6F66, 0xBCE3, 0x6F67, 0xE657, 0x6F69, 0xE65B, 0x6F6A, 0xE660, - 0x6F6B, 0xE655, 0x6F6C, 0xE649, 0x6F6D, 0xBCE6, 0x6F6E, 0xBCE9, 0x6F6F, 0xBCF1, 0x6F70, 0xBCEC, 0x6F72, 0xE64C, 0x6F73, 0xE2A2, - 0x6F76, 0xE648, 0x6F77, 0xE65F, 0x6F78, 0xBCE8, 0x6F7A, 0xBCEB, 0x6F7B, 0xE661, 0x6F7C, 0xBCE0, 0x6F7D, 0xE656, 0x6F7E, 0xE5FB, - 0x6F7F, 0xE65C, 0x6F80, 0xC0DF, 0x6F82, 0xE64A, 0x6F84, 0xBCE1, 0x6F85, 0xE645, 0x6F86, 0xBCE5, 0x6F87, 0xE5FC, 0x6F88, 0xBAAB, - 0x6F89, 0xE641, 0x6F8B, 0xE65A, 0x6F8C, 0xE642, 0x6F8D, 0xE640, 0x6F8E, 0xBCEA, 0x6F90, 0xE658, 0x6F92, 0xE5FE, 0x6F93, 0xE651, - 0x6F94, 0xE650, 0x6F95, 0xE65D, 0x6F96, 0xE647, 0x6F97, 0xBCEE, 0x6F9E, 0xE9F3, 0x6FA0, 0xBF49, 0x6FA1, 0xBEFE, 0x6FA2, 0xEA40, - 0x6FA3, 0xE9EB, 0x6FA4, 0xBF41, 0x6FA5, 0xE9F7, 0x6FA6, 0xBF48, 0x6FA7, 0xBF43, 0x6FA8, 0xE9F5, 0x6FA9, 0xED4F, 0x6FAA, 0xE9FB, - 0x6FAB, 0xEA42, 0x6FAC, 0xE9FA, 0x6FAD, 0xE9E9, 0x6FAE, 0xE9F8, 0x6FAF, 0xEA44, 0x6FB0, 0xEA46, 0x6FB1, 0xBEFD, 0x6FB2, 0xEA45, - 0x6FB3, 0xBF44, 0x6FB4, 0xBF4A, 0x6FB6, 0xBF47, 0x6FB8, 0xE9FE, 0x6FB9, 0xBF46, 0x6FBA, 0xE9F9, 0x6FBC, 0xE9ED, 0x6FBD, 0xE9F2, - 0x6FBF, 0xE9FD, 0x6FC0, 0xBF45, 0x6FC1, 0xBF42, 0x6FC2, 0xBEFC, 0x6FC3, 0xBF40, 0x6FC4, 0xE9F1, 0x6FC6, 0xE5FD, 0x6FC7, 0xE9EC, - 0x6FC8, 0xE9EF, 0x6FC9, 0xEA41, 0x6FCA, 0xE9F4, 0x6FCB, 0xE9EA, 0x6FCC, 0xED4E, 0x6FCD, 0xEA43, 0x6FCE, 0xE9EE, 0x6FCF, 0xE9FC, - 0x6FD4, 0xED51, 0x6FD5, 0xC0E3, 0x6FD8, 0xC0D7, 0x6FDB, 0xC0DB, 0x6FDC, 0xED53, 0x6FDD, 0xED59, 0x6FDE, 0xED57, 0x6FDF, 0xC0D9, - 0x6FE0, 0xC0DA, 0x6FE1, 0xC0E1, 0x6FE2, 0xED5A, 0x6FE3, 0xED52, 0x6FE4, 0xC0DC, 0x6FE6, 0xED56, 0x6FE7, 0xED55, 0x6FE8, 0xED5B, - 0x6FE9, 0xC0E2, 0x6FEB, 0xC0DD, 0x6FEC, 0xC0E0, 0x6FED, 0xED54, 0x6FEE, 0xC0E4, 0x6FEF, 0xC0DE, 0x6FF0, 0xC0E5, 0x6FF1, 0xC0D8, - 0x6FF2, 0xED58, 0x6FF4, 0xED50, 0x6FF7, 0xEFF7, 0x6FFA, 0xC271, 0x6FFB, 0xEFF4, 0x6FFC, 0xEFF6, 0x6FFE, 0xC26F, 0x6FFF, 0xEFF2, - 0x7000, 0xEFF3, 0x7001, 0xEFEE, 0x7004, 0xE9F6, 0x7005, 0xEFEF, 0x7006, 0xC270, 0x7007, 0xEFEB, 0x7009, 0xC26D, 0x700A, 0xEFF8, - 0x700B, 0xC26E, 0x700C, 0xEFEC, 0x700D, 0xEFED, 0x700E, 0xEFF1, 0x700F, 0xC273, 0x7011, 0xC272, 0x7014, 0xEFF0, 0x7015, 0xC378, - 0x7016, 0xF25F, 0x7017, 0xF265, 0x7018, 0xC379, 0x7019, 0xF25C, 0x701A, 0xC376, 0x701B, 0xC373, 0x701C, 0xF267, 0x701D, 0xC377, - 0x701F, 0xC374, 0x7020, 0xF25E, 0x7021, 0xF261, 0x7022, 0xF262, 0x7023, 0xF263, 0x7024, 0xF266, 0x7026, 0xEFF5, 0x7027, 0xF25D, - 0x7028, 0xC375, 0x7029, 0xF264, 0x702A, 0xF268, 0x702B, 0xF260, 0x702F, 0xF45D, 0x7030, 0xC46A, 0x7031, 0xF460, 0x7032, 0xC46B, - 0x7033, 0xF468, 0x7034, 0xF45F, 0x7035, 0xF45C, 0x7037, 0xF45E, 0x7038, 0xF462, 0x7039, 0xF465, 0x703A, 0xF464, 0x703B, 0xF467, - 0x703C, 0xF45B, 0x703E, 0xC469, 0x703F, 0xF463, 0x7040, 0xF466, 0x7041, 0xF469, 0x7042, 0xF461, 0x7043, 0xF5D3, 0x7044, 0xF5D4, - 0x7045, 0xF5D8, 0x7046, 0xF5D9, 0x7048, 0xF5D6, 0x7049, 0xF5D7, 0x704A, 0xF5D5, 0x704C, 0xC4E9, 0x7051, 0xC578, 0x7052, 0xF6EB, - 0x7055, 0xF6E8, 0x7056, 0xF6E9, 0x7057, 0xF6EA, 0x7058, 0xC579, 0x705A, 0xF7E5, 0x705B, 0xF7E4, 0x705D, 0xF8AF, 0x705E, 0xC5F4, - 0x705F, 0xF8AD, 0x7060, 0xF8B0, 0x7061, 0xF8AE, 0x7062, 0xF8F5, 0x7063, 0xC657, 0x7064, 0xC665, 0x7065, 0xF9A3, 0x7066, 0xF96C, - 0x7068, 0xF9A2, 0x7069, 0xF9D0, 0x706A, 0xF9D1, 0x706B, 0xA4F5, 0x7070, 0xA6C7, 0x7071, 0xCA41, 0x7074, 0xCB5E, 0x7076, 0xA85F, - 0x7078, 0xA862, 0x707A, 0xCB5F, 0x707C, 0xA860, 0x707D, 0xA861, 0x7082, 0xCD58, 0x7083, 0xCD5A, 0x7084, 0xCD55, 0x7085, 0xCD52, - 0x7086, 0xCD54, 0x708A, 0xAAA4, 0x708E, 0xAAA2, 0x7091, 0xCD56, 0x7092, 0xAAA3, 0x7093, 0xCD53, 0x7094, 0xCD50, 0x7095, 0xAAA1, - 0x7096, 0xCD57, 0x7098, 0xCD51, 0x7099, 0xAAA5, 0x709A, 0xCD59, 0x709F, 0xCFAF, 0x70A1, 0xCFB3, 0x70A4, 0xACB7, 0x70A9, 0xCFB6, - 0x70AB, 0xACAF, 0x70AC, 0xACB2, 0x70AD, 0xACB4, 0x70AE, 0xACB6, 0x70AF, 0xACB3, 0x70B0, 0xCFB2, 0x70B1, 0xCFB1, 0x70B3, 0xACB1, - 0x70B4, 0xCFB4, 0x70B5, 0xCFB5, 0x70B7, 0xCFAE, 0x70B8, 0xACB5, 0x70BA, 0xACB0, 0x70BE, 0xCFB0, 0x70C5, 0xD277, 0x70C6, 0xD278, - 0x70C7, 0xD279, 0x70C8, 0xAF50, 0x70CA, 0xAF4C, 0x70CB, 0xD26E, 0x70CD, 0xD276, 0x70CE, 0xD27B, 0x70CF, 0xAF51, 0x70D1, 0xD26C, - 0x70D2, 0xD272, 0x70D3, 0xD26B, 0x70D4, 0xD275, 0x70D7, 0xD271, 0x70D8, 0xAF4D, 0x70D9, 0xAF4F, 0x70DA, 0xD27A, 0x70DC, 0xD26A, - 0x70DD, 0xD26D, 0x70DE, 0xD273, 0x70E0, 0xD274, 0x70E1, 0xD27C, 0x70E2, 0xD270, 0x70E4, 0xAF4E, 0x70EF, 0xB26D, 0x70F0, 0xD64E, - 0x70F3, 0xD650, 0x70F4, 0xD64C, 0x70F6, 0xD658, 0x70F7, 0xD64A, 0x70F8, 0xD657, 0x70F9, 0xB269, 0x70FA, 0xD648, 0x70FB, 0xDA5B, - 0x70FC, 0xD652, 0x70FD, 0xB26C, 0x70FF, 0xD653, 0x7100, 0xD656, 0x7102, 0xD65A, 0x7104, 0xD64F, 0x7106, 0xD654, 0x7109, 0xB26A, - 0x710A, 0xB26B, 0x710B, 0xD659, 0x710C, 0xD64D, 0x710D, 0xD649, 0x710E, 0xD65B, 0x7110, 0xD651, 0x7113, 0xD655, 0x7117, 0xD64B, - 0x7119, 0xB548, 0x711A, 0xB549, 0x711B, 0xDA65, 0x711C, 0xB54F, 0x711E, 0xDA59, 0x711F, 0xDA62, 0x7120, 0xDA58, 0x7121, 0xB54C, - 0x7122, 0xDA60, 0x7123, 0xDA5E, 0x7125, 0xDA5F, 0x7126, 0xB54A, 0x7128, 0xDA63, 0x712E, 0xDA5C, 0x712F, 0xDA5A, 0x7130, 0xB54B, - 0x7131, 0xDA5D, 0x7132, 0xDA61, 0x7136, 0xB54D, 0x713A, 0xDA64, 0x7141, 0xDE70, 0x7142, 0xDE77, 0x7143, 0xDE79, 0x7144, 0xDEA1, - 0x7146, 0xB7DA, 0x7147, 0xDE6B, 0x7149, 0xB7D2, 0x714B, 0xDE7A, 0x714C, 0xB7D7, 0x714D, 0xDEA2, 0x714E, 0xB7CE, 0x7150, 0xDE7D, - 0x7152, 0xDE6D, 0x7153, 0xDE7E, 0x7154, 0xDE6C, 0x7156, 0xB7DC, 0x7158, 0xDE78, 0x7159, 0xB7CF, 0x715A, 0xDEA3, 0x715C, 0xB7D4, - 0x715D, 0xDE71, 0x715E, 0xB7D9, 0x715F, 0xDE7C, 0x7160, 0xDE6F, 0x7161, 0xDE76, 0x7162, 0xDE72, 0x7163, 0xDE6E, 0x7164, 0xB7D1, - 0x7165, 0xB7D8, 0x7166, 0xB7D6, 0x7167, 0xB7D3, 0x7168, 0xB7DB, 0x7169, 0xB7D0, 0x716A, 0xDE75, 0x716C, 0xB7D5, 0x716E, 0xB54E, - 0x7170, 0xDE7B, 0x7172, 0xDE73, 0x7178, 0xDE74, 0x717B, 0xE2C1, 0x717D, 0xBAB4, 0x7180, 0xE2BD, 0x7181, 0xE2C3, 0x7182, 0xE2BF, - 0x7184, 0xBAB6, 0x7185, 0xE2BE, 0x7186, 0xE2C2, 0x7187, 0xE2BA, 0x7189, 0xE2BC, 0x718A, 0xBAB5, 0x718F, 0xE2C0, 0x7190, 0xE2BB, - 0x7192, 0xBAB7, 0x7194, 0xBAB2, 0x7197, 0xE2C4, 0x7199, 0xBAB3, 0x719A, 0xE667, 0x719B, 0xE664, 0x719C, 0xE670, 0x719D, 0xE66A, - 0x719E, 0xE66C, 0x719F, 0xBCF4, 0x71A0, 0xE666, 0x71A1, 0xE66E, 0x71A4, 0xE66D, 0x71A5, 0xE66B, 0x71A7, 0xE671, 0x71A8, 0xBCF7, - 0x71A9, 0xE668, 0x71AA, 0xE66F, 0x71AC, 0xBCF5, 0x71AF, 0xE663, 0x71B0, 0xE665, 0x71B1, 0xBCF6, 0x71B2, 0xE662, 0x71B3, 0xE672, - 0x71B5, 0xE669, 0x71B8, 0xEA4A, 0x71B9, 0xBF51, 0x71BC, 0xEA55, 0x71BD, 0xEA53, 0x71BE, 0xBF4B, 0x71BF, 0xEA49, 0x71C0, 0xEA4C, - 0x71C1, 0xEA4D, 0x71C2, 0xEA48, 0x71C3, 0xBF55, 0x71C4, 0xBF56, 0x71C5, 0xEA47, 0x71C6, 0xEA56, 0x71C7, 0xEA51, 0x71C8, 0xBF4F, - 0x71C9, 0xBF4C, 0x71CA, 0xEA50, 0x71CB, 0xEA4E, 0x71CE, 0xBF52, 0x71CF, 0xEA52, 0x71D0, 0xBF4D, 0x71D2, 0xBF4E, 0x71D4, 0xEA4F, - 0x71D5, 0xBF50, 0x71D6, 0xEA4B, 0x71D8, 0xEA54, 0x71D9, 0xBF53, 0x71DA, 0xEA57, 0x71DB, 0xEA58, 0x71DC, 0xBF54, 0x71DF, 0xC0E7, - 0x71E0, 0xC0EE, 0x71E1, 0xED5C, 0x71E2, 0xED62, 0x71E4, 0xED60, 0x71E5, 0xC0EA, 0x71E6, 0xC0E9, 0x71E7, 0xC0E6, 0x71E8, 0xED5E, - 0x71EC, 0xC0EC, 0x71ED, 0xC0EB, 0x71EE, 0xC0E8, 0x71F0, 0xED61, 0x71F1, 0xED5D, 0x71F2, 0xED5F, 0x71F4, 0xC0ED, 0x71F8, 0xC277, - 0x71F9, 0xEFFB, 0x71FB, 0xC274, 0x71FC, 0xC275, 0x71FD, 0xEFFD, 0x71FE, 0xC276, 0x71FF, 0xEFFA, 0x7201, 0xEFF9, 0x7202, 0xF26C, - 0x7203, 0xEFFC, 0x7205, 0xF26D, 0x7206, 0xC37A, 0x7207, 0xF26B, 0x720A, 0xF26A, 0x720C, 0xF269, 0x720D, 0xC37B, 0x7210, 0xC46C, - 0x7213, 0xF46A, 0x7214, 0xF46B, 0x7219, 0xF5DC, 0x721A, 0xF5DB, 0x721B, 0xC4EA, 0x721D, 0xF5DA, 0x721E, 0xF6EC, 0x721F, 0xF6ED, - 0x7222, 0xF7E6, 0x7223, 0xF8B1, 0x7226, 0xF8F6, 0x7227, 0xF9BC, 0x7228, 0xC679, 0x7229, 0xF9C6, 0x722A, 0xA4F6, 0x722C, 0xAAA6, - 0x722D, 0xAAA7, 0x7230, 0xACB8, 0x7235, 0xC0EF, 0x7236, 0xA4F7, 0x7238, 0xAAA8, 0x7239, 0xAF52, 0x723A, 0xB7DD, 0x723B, 0xA4F8, - 0x723D, 0xB26E, 0x723E, 0xBAB8, 0x723F, 0xC962, 0x7241, 0xCFB7, 0x7242, 0xD27D, 0x7244, 0xE2C5, 0x7246, 0xC0F0, 0x7247, 0xA4F9, - 0x7248, 0xAAA9, 0x7249, 0xCFB8, 0x724A, 0xCFB9, 0x724B, 0xDA66, 0x724C, 0xB550, 0x724F, 0xDEA4, 0x7252, 0xB7DE, 0x7253, 0xE2C6, - 0x7256, 0xBCF8, 0x7258, 0xC37C, 0x7259, 0xA4FA, 0x725A, 0xDA67, 0x725B, 0xA4FB, 0x725D, 0xA6C9, 0x725E, 0xCA42, 0x725F, 0xA6C8, - 0x7260, 0xA865, 0x7261, 0xA864, 0x7262, 0xA863, 0x7263, 0xCB60, 0x7267, 0xAAAA, 0x7269, 0xAAAB, 0x726A, 0xCD5B, 0x726C, 0xCFBA, - 0x726E, 0xCFBD, 0x726F, 0xACBA, 0x7270, 0xCFBB, 0x7272, 0xACB9, 0x7273, 0xCFBC, 0x7274, 0xACBB, 0x7276, 0xD2A2, 0x7277, 0xD2A1, - 0x7278, 0xD27E, 0x7279, 0xAF53, 0x727B, 0xD65D, 0x727C, 0xD65E, 0x727D, 0xB26F, 0x727E, 0xD65C, 0x727F, 0xD65F, 0x7280, 0xB552, - 0x7281, 0xB270, 0x7284, 0xB551, 0x7285, 0xDA6B, 0x7286, 0xDA6A, 0x7288, 0xDA68, 0x7289, 0xDA69, 0x728B, 0xDA6C, 0x728C, 0xDEA6, - 0x728D, 0xDEA5, 0x728E, 0xDEA9, 0x7290, 0xDEA8, 0x7291, 0xDEA7, 0x7292, 0xBAB9, 0x7293, 0xE2C9, 0x7295, 0xE2C8, 0x7296, 0xBABA, - 0x7297, 0xE2C7, 0x7298, 0xE673, 0x729A, 0xE674, 0x729B, 0xBCF9, 0x729D, 0xEA59, 0x729E, 0xEA5A, 0x72A1, 0xF272, 0x72A2, 0xC37D, - 0x72A3, 0xF271, 0x72A4, 0xF270, 0x72A5, 0xF26E, 0x72A6, 0xF26F, 0x72A7, 0xC4EB, 0x72A8, 0xF46C, 0x72A9, 0xF6EE, 0x72AA, 0xF8F7, - 0x72AC, 0xA4FC, 0x72AE, 0xC9A5, 0x72AF, 0xA5C7, 0x72B0, 0xC9A6, 0x72B4, 0xCA43, 0x72B5, 0xCA44, 0x72BA, 0xCB66, 0x72BD, 0xCB62, - 0x72BF, 0xCB61, 0x72C0, 0xAAAC, 0x72C1, 0xCB65, 0x72C2, 0xA867, 0x72C3, 0xCB63, 0x72C4, 0xA866, 0x72C5, 0xCB67, 0x72C6, 0xCB64, - 0x72C9, 0xCD5F, 0x72CA, 0xCFBE, 0x72CB, 0xCD5D, 0x72CC, 0xCD64, 0x72CE, 0xAAAD, 0x72D0, 0xAAB0, 0x72D1, 0xCD65, 0x72D2, 0xCD61, - 0x72D4, 0xCD62, 0x72D6, 0xCD5C, 0x72D7, 0xAAAF, 0x72D8, 0xCD5E, 0x72D9, 0xAAAE, 0x72DA, 0xCD63, 0x72DC, 0xCD60, 0x72DF, 0xCFC2, - 0x72E0, 0xACBD, 0x72E1, 0xACBE, 0x72E3, 0xCFC5, 0x72E4, 0xCFBF, 0x72E6, 0xCFC4, 0x72E8, 0xCFC0, 0x72E9, 0xACBC, 0x72EA, 0xCFC3, - 0x72EB, 0xCFC1, 0x72F3, 0xD2A8, 0x72F4, 0xD2A5, 0x72F6, 0xD2A7, 0x72F7, 0xAF58, 0x72F8, 0xAF57, 0x72F9, 0xAF55, 0x72FA, 0xD2A4, - 0x72FB, 0xD2A9, 0x72FC, 0xAF54, 0x72FD, 0xAF56, 0x72FE, 0xD2A6, 0x72FF, 0xD667, 0x7300, 0xD2A3, 0x7301, 0xD2AA, 0x7307, 0xD662, - 0x7308, 0xD666, 0x730A, 0xD665, 0x730B, 0xDA6E, 0x730C, 0xDA79, 0x730F, 0xD668, 0x7311, 0xD663, 0x7312, 0xDA6D, 0x7313, 0xB274, - 0x7316, 0xB273, 0x7317, 0xD661, 0x7318, 0xD664, 0x7319, 0xB275, 0x731B, 0xB272, 0x731C, 0xB271, 0x731D, 0xD660, 0x731E, 0xD669, - 0x7322, 0xDA70, 0x7323, 0xDA77, 0x7325, 0xB554, 0x7326, 0xDA76, 0x7327, 0xDA73, 0x7329, 0xB556, 0x732D, 0xDA75, 0x7330, 0xDA6F, - 0x7331, 0xDA71, 0x7332, 0xDA74, 0x7333, 0xDA72, 0x7334, 0xB555, 0x7335, 0xDA78, 0x7336, 0xB553, 0x7337, 0xB7DF, 0x733A, 0xDEAD, - 0x733B, 0xDEAC, 0x733C, 0xDEAA, 0x733E, 0xB7E2, 0x733F, 0xB7E1, 0x7340, 0xDEAE, 0x7342, 0xDEAB, 0x7343, 0xE2CA, 0x7344, 0xBABB, - 0x7345, 0xB7E0, 0x7349, 0xDEB0, 0x734A, 0xDEAF, 0x734C, 0xE2CD, 0x734D, 0xE2CB, 0x734E, 0xBCFA, 0x7350, 0xBABC, 0x7351, 0xE2CC, - 0x7352, 0xE676, 0x7357, 0xBCFB, 0x7358, 0xE675, 0x7359, 0xE67E, 0x735A, 0xE67D, 0x735B, 0xE67B, 0x735D, 0xE67A, 0x735E, 0xE677, - 0x735F, 0xE678, 0x7360, 0xE679, 0x7361, 0xE67C, 0x7362, 0xE6A1, 0x7365, 0xEA5F, 0x7366, 0xEA5C, 0x7367, 0xEA5D, 0x7368, 0xBF57, - 0x7369, 0xEA5B, 0x736A, 0xEA61, 0x736B, 0xEA60, 0x736C, 0xEA5E, 0x736E, 0xED64, 0x736F, 0xED65, 0x7370, 0xC0F1, 0x7372, 0xC0F2, - 0x7373, 0xED63, 0x7375, 0xC279, 0x7376, 0xEFFE, 0x7377, 0xC278, 0x7378, 0xC37E, 0x737A, 0xC3A1, 0x737B, 0xC46D, 0x737C, 0xF46E, - 0x737D, 0xF46D, 0x737E, 0xF5DD, 0x737F, 0xF6EF, 0x7380, 0xC57A, 0x7381, 0xF7E8, 0x7382, 0xF7E7, 0x7383, 0xF7E9, 0x7384, 0xA5C8, - 0x7385, 0xCFC6, 0x7386, 0xAF59, 0x7387, 0xB276, 0x7388, 0xD66A, 0x7389, 0xA5C9, 0x738A, 0xC9A7, 0x738B, 0xA4FD, 0x738E, 0xCA45, - 0x7392, 0xCB6C, 0x7393, 0xCB6A, 0x7394, 0xCB6B, 0x7395, 0xCB68, 0x7396, 0xA868, 0x7397, 0xCB69, 0x739D, 0xCD6D, 0x739F, 0xAAB3, - 0x73A0, 0xCD6B, 0x73A1, 0xCD67, 0x73A2, 0xCD6A, 0x73A4, 0xCD66, 0x73A5, 0xAAB5, 0x73A6, 0xCD69, 0x73A8, 0xAAB2, 0x73A9, 0xAAB1, - 0x73AB, 0xAAB4, 0x73AC, 0xCD6C, 0x73AD, 0xCD68, 0x73B2, 0xACC2, 0x73B3, 0xACC5, 0x73B4, 0xCFCE, 0x73B5, 0xCFCD, 0x73B6, 0xCFCC, - 0x73B7, 0xACBF, 0x73B8, 0xCFD5, 0x73B9, 0xCFCB, 0x73BB, 0xACC1, 0x73BC, 0xD2AF, 0x73BE, 0xCFD2, 0x73BF, 0xCFD0, 0x73C0, 0xACC4, - 0x73C2, 0xCFC8, 0x73C3, 0xCFD3, 0x73C5, 0xCFCA, 0x73C6, 0xCFD4, 0x73C7, 0xCFD1, 0x73C8, 0xCFC9, 0x73CA, 0xACC0, 0x73CB, 0xCFD6, - 0x73CC, 0xCFC7, 0x73CD, 0xACC3, 0x73D2, 0xD2B4, 0x73D3, 0xD2AB, 0x73D4, 0xD2B6, 0x73D6, 0xD2AE, 0x73D7, 0xD2B9, 0x73D8, 0xD2BA, - 0x73D9, 0xD2AC, 0x73DA, 0xD2B8, 0x73DB, 0xD2B5, 0x73DC, 0xD2B3, 0x73DD, 0xD2B7, 0x73DE, 0xAF5F, 0x73E0, 0xAF5D, 0x73E3, 0xD2B1, - 0x73E5, 0xD2AD, 0x73E7, 0xD2B0, 0x73E8, 0xD2BB, 0x73E9, 0xD2B2, 0x73EA, 0xAF5E, 0x73EB, 0xCFCF, 0x73ED, 0xAF5A, 0x73EE, 0xAF5C, - 0x73F4, 0xD678, 0x73F5, 0xD66D, 0x73F6, 0xD66B, 0x73F8, 0xD66C, 0x73FA, 0xD673, 0x73FC, 0xD674, 0x73FD, 0xD670, 0x73FE, 0xB27B, - 0x73FF, 0xD675, 0x7400, 0xD672, 0x7401, 0xD66F, 0x7403, 0xB279, 0x7404, 0xD66E, 0x7405, 0xB277, 0x7406, 0xB27A, 0x7407, 0xD671, - 0x7408, 0xD679, 0x7409, 0xAF5B, 0x740A, 0xB278, 0x740B, 0xD677, 0x740C, 0xD676, 0x740D, 0xB27C, 0x7416, 0xDA7E, 0x741A, 0xDAA1, - 0x741B, 0xB560, 0x741D, 0xDAA7, 0x7420, 0xDAA9, 0x7421, 0xDAA2, 0x7422, 0xB55A, 0x7423, 0xDAA6, 0x7424, 0xDAA5, 0x7425, 0xB55B, - 0x7426, 0xB561, 0x7428, 0xB562, 0x7429, 0xDAA8, 0x742A, 0xB558, 0x742B, 0xDA7D, 0x742C, 0xDA7B, 0x742D, 0xDAA3, 0x742E, 0xDA7A, - 0x742F, 0xB55F, 0x7430, 0xDA7C, 0x7431, 0xDAA4, 0x7432, 0xDAAA, 0x7433, 0xB559, 0x7434, 0xB55E, 0x7435, 0xB55C, 0x7436, 0xB55D, - 0x743A, 0xB557, 0x743F, 0xB7E9, 0x7440, 0xDEB7, 0x7441, 0xB7E8, 0x7442, 0xDEBB, 0x7444, 0xDEB1, 0x7446, 0xDEBC, 0x744A, 0xDEB2, - 0x744B, 0xDEB3, 0x744D, 0xDEBD, 0x744E, 0xDEBA, 0x744F, 0xDEB8, 0x7450, 0xDEB9, 0x7451, 0xDEB5, 0x7452, 0xDEB4, 0x7454, 0xDEBE, - 0x7455, 0xB7E5, 0x7457, 0xDEB6, 0x7459, 0xB7EA, 0x745A, 0xB7E4, 0x745B, 0xB7EB, 0x745C, 0xB7EC, 0x745E, 0xB7E7, 0x745F, 0xB7E6, - 0x7462, 0xE2CE, 0x7463, 0xBABE, 0x7464, 0xBABD, 0x7467, 0xE2D3, 0x7469, 0xBCFC, 0x746A, 0xBABF, 0x746D, 0xBAC1, 0x746E, 0xE2D4, - 0x746F, 0xB7E3, 0x7470, 0xBAC0, 0x7471, 0xE2D0, 0x7472, 0xE2D2, 0x7473, 0xE2CF, 0x7475, 0xE2D1, 0x7479, 0xE6AB, 0x747C, 0xE6AA, - 0x747D, 0xE6A7, 0x747E, 0xBD40, 0x747F, 0xEA62, 0x7480, 0xBD41, 0x7481, 0xE6A6, 0x7483, 0xBCFE, 0x7485, 0xE6A8, 0x7486, 0xE6A5, - 0x7487, 0xE6A2, 0x7488, 0xE6A9, 0x7489, 0xE6A3, 0x748A, 0xE6A4, 0x748B, 0xBCFD, 0x7490, 0xED69, 0x7492, 0xEA66, 0x7494, 0xEA65, - 0x7495, 0xEA67, 0x7497, 0xED66, 0x7498, 0xBF5A, 0x749A, 0xEA63, 0x749C, 0xBF58, 0x749E, 0xBF5C, 0x749F, 0xBF5B, 0x74A0, 0xEA64, - 0x74A1, 0xEA68, 0x74A3, 0xBF59, 0x74A5, 0xED6D, 0x74A6, 0xC0F5, 0x74A7, 0xC27A, 0x74A8, 0xC0F6, 0x74A9, 0xC0F3, 0x74AA, 0xED6A, - 0x74AB, 0xED68, 0x74AD, 0xED6B, 0x74AF, 0xED6E, 0x74B0, 0xC0F4, 0x74B1, 0xED6C, 0x74B2, 0xED67, 0x74B5, 0xF042, 0x74B6, 0xF045, - 0x74B7, 0xF275, 0x74B8, 0xF040, 0x74BA, 0xF46F, 0x74BB, 0xF046, 0x74BD, 0xC3A2, 0x74BE, 0xF044, 0x74BF, 0xC27B, 0x74C0, 0xF041, - 0x74C1, 0xF043, 0x74C2, 0xF047, 0x74C3, 0xF276, 0x74C5, 0xF274, 0x74CA, 0xC3A3, 0x74CB, 0xF273, 0x74CF, 0xC46E, 0x74D4, 0xC4ED, - 0x74D5, 0xF6F1, 0x74D6, 0xC4EC, 0x74D7, 0xF6F3, 0x74D8, 0xF6F0, 0x74D9, 0xF6F2, 0x74DA, 0xC5D0, 0x74DB, 0xF8B2, 0x74DC, 0xA5CA, - 0x74DD, 0xCD6E, 0x74DE, 0xD2BC, 0x74DF, 0xD2BD, 0x74E0, 0xB27D, 0x74E1, 0xDEBF, 0x74E2, 0xBF5D, 0x74E3, 0xC3A4, 0x74E4, 0xC57B, - 0x74E5, 0xF8B3, 0x74E6, 0xA5CB, 0x74E8, 0xCD6F, 0x74E9, 0xA260, 0x74EC, 0xCFD7, 0x74EE, 0xCFD8, 0x74F4, 0xD2BE, 0x74F5, 0xD2BF, - 0x74F6, 0xB27E, 0x74F7, 0xB2A1, 0x74FB, 0xDAAB, 0x74FD, 0xDEC2, 0x74FE, 0xDEC1, 0x74FF, 0xDEC0, 0x7500, 0xE2D5, 0x7502, 0xE2D6, - 0x7503, 0xE2D7, 0x7504, 0xBAC2, 0x7507, 0xE6AD, 0x7508, 0xE6AC, 0x750B, 0xEA69, 0x750C, 0xBF5E, 0x750D, 0xBF5F, 0x750F, 0xED72, - 0x7510, 0xED6F, 0x7511, 0xED70, 0x7512, 0xED71, 0x7513, 0xF049, 0x7514, 0xF048, 0x7515, 0xC27C, 0x7516, 0xF277, 0x7517, 0xF5DE, - 0x7518, 0xA5CC, 0x751A, 0xACC6, 0x751C, 0xB2A2, 0x751D, 0xDEC3, 0x751F, 0xA5CD, 0x7521, 0xD2C0, 0x7522, 0xB2A3, 0x7525, 0xB563, - 0x7526, 0xB564, 0x7528, 0xA5CE, 0x7529, 0xA5CF, 0x752A, 0xCA46, 0x752B, 0xA86A, 0x752C, 0xA869, 0x752D, 0xACC7, 0x752E, 0xCFD9, - 0x752F, 0xDAAC, 0x7530, 0xA5D0, 0x7531, 0xA5D1, 0x7532, 0xA5D2, 0x7533, 0xA5D3, 0x7537, 0xA86B, 0x7538, 0xA86C, 0x7539, 0xCB6E, - 0x753A, 0xCB6D, 0x753D, 0xAAB6, 0x753E, 0xCD72, 0x753F, 0xCD70, 0x7540, 0xCD71, 0x7547, 0xCFDA, 0x7548, 0xCFDB, 0x754B, 0xACCB, - 0x754C, 0xACC9, 0x754E, 0xACCA, 0x754F, 0xACC8, 0x7554, 0xAF60, 0x7559, 0xAF64, 0x755A, 0xAF63, 0x755B, 0xD2C1, 0x755C, 0xAF62, - 0x755D, 0xAF61, 0x755F, 0xD2C2, 0x7562, 0xB2A6, 0x7563, 0xD67B, 0x7564, 0xD67A, 0x7565, 0xB2A4, 0x7566, 0xB2A5, 0x756A, 0xB566, - 0x756B, 0xB565, 0x756C, 0xDAAE, 0x756F, 0xDAAD, 0x7570, 0xB2A7, 0x7576, 0xB7ED, 0x7577, 0xDEC5, 0x7578, 0xB7EE, 0x7579, 0xDEC4, - 0x757D, 0xE2D8, 0x757E, 0xE6AE, 0x757F, 0xBD42, 0x7580, 0xEA6A, 0x7584, 0xED73, 0x7586, 0xC3A6, 0x7587, 0xC3A5, 0x758A, 0xC57C, - 0x758B, 0xA5D4, 0x758C, 0xCD73, 0x758F, 0xB2A8, 0x7590, 0xE2D9, 0x7591, 0xBAC3, 0x7594, 0xCB6F, 0x7595, 0xCB70, 0x7598, 0xCD74, - 0x7599, 0xAAB8, 0x759A, 0xAAB9, 0x759D, 0xAAB7, 0x75A2, 0xACCF, 0x75A3, 0xACD0, 0x75A4, 0xACCD, 0x75A5, 0xACCE, 0x75A7, 0xCFDC, - 0x75AA, 0xCFDD, 0x75AB, 0xACCC, 0x75B0, 0xD2C3, 0x75B2, 0xAF68, 0x75B3, 0xAF69, 0x75B5, 0xB2AB, 0x75B6, 0xD2C9, 0x75B8, 0xAF6E, - 0x75B9, 0xAF6C, 0x75BA, 0xD2CA, 0x75BB, 0xD2C5, 0x75BC, 0xAF6B, 0x75BD, 0xAF6A, 0x75BE, 0xAF65, 0x75BF, 0xD2C8, 0x75C0, 0xD2C7, - 0x75C1, 0xD2C4, 0x75C2, 0xAF6D, 0x75C4, 0xD2C6, 0x75C5, 0xAF66, 0x75C7, 0xAF67, 0x75CA, 0xB2AC, 0x75CB, 0xD6A1, 0x75CC, 0xD6A2, - 0x75CD, 0xB2AD, 0x75CE, 0xD67C, 0x75CF, 0xD67E, 0x75D0, 0xD6A4, 0x75D1, 0xD6A3, 0x75D2, 0xD67D, 0x75D4, 0xB2A9, 0x75D5, 0xB2AA, - 0x75D7, 0xDAB6, 0x75D8, 0xB56B, 0x75D9, 0xB56A, 0x75DA, 0xDAB0, 0x75DB, 0xB568, 0x75DD, 0xDAB3, 0x75DE, 0xB56C, 0x75DF, 0xDAB4, - 0x75E0, 0xB56D, 0x75E1, 0xDAB1, 0x75E2, 0xB567, 0x75E3, 0xB569, 0x75E4, 0xDAB5, 0x75E6, 0xDAB2, 0x75E7, 0xDAAF, 0x75ED, 0xDED2, - 0x75EF, 0xDEC7, 0x75F0, 0xB7F0, 0x75F1, 0xB7F3, 0x75F2, 0xB7F2, 0x75F3, 0xB7F7, 0x75F4, 0xB7F6, 0x75F5, 0xDED3, 0x75F6, 0xDED1, - 0x75F7, 0xDECA, 0x75F8, 0xDECE, 0x75F9, 0xDECD, 0x75FA, 0xB7F4, 0x75FB, 0xDED0, 0x75FC, 0xDECC, 0x75FD, 0xDED4, 0x75FE, 0xDECB, - 0x75FF, 0xB7F5, 0x7600, 0xB7EF, 0x7601, 0xB7F1, 0x7603, 0xDEC9, 0x7608, 0xE2DB, 0x7609, 0xBAC7, 0x760A, 0xE2DF, 0x760B, 0xBAC6, - 0x760C, 0xE2DC, 0x760D, 0xBAC5, 0x760F, 0xDEC8, 0x7610, 0xDECF, 0x7611, 0xE2DE, 0x7613, 0xBAC8, 0x7614, 0xE2E0, 0x7615, 0xE2DD, - 0x7616, 0xE2DA, 0x7619, 0xE6B1, 0x761A, 0xE6B5, 0x761B, 0xE6B7, 0x761C, 0xE6B3, 0x761D, 0xE6B2, 0x761E, 0xE6B0, 0x761F, 0xBD45, - 0x7620, 0xBD43, 0x7621, 0xBD48, 0x7622, 0xBD49, 0x7623, 0xE6B4, 0x7624, 0xBD46, 0x7625, 0xE6AF, 0x7626, 0xBD47, 0x7627, 0xBAC4, - 0x7628, 0xE6B6, 0x7629, 0xBD44, 0x762D, 0xEA6C, 0x762F, 0xEA6B, 0x7630, 0xEA73, 0x7631, 0xEA6D, 0x7632, 0xEA72, 0x7633, 0xEA6F, - 0x7634, 0xBF60, 0x7635, 0xEA71, 0x7638, 0xBF61, 0x763A, 0xBF62, 0x763C, 0xEA70, 0x763D, 0xEA6E, 0x7642, 0xC0F8, 0x7643, 0xED74, - 0x7646, 0xC0F7, 0x7647, 0xED77, 0x7648, 0xED75, 0x7649, 0xED76, 0x764C, 0xC0F9, 0x7650, 0xF04D, 0x7652, 0xC2A1, 0x7653, 0xF04E, - 0x7656, 0xC27D, 0x7657, 0xF04F, 0x7658, 0xC27E, 0x7659, 0xF04C, 0x765A, 0xF050, 0x765C, 0xF04A, 0x765F, 0xC3A7, 0x7660, 0xF278, - 0x7661, 0xC3A8, 0x7662, 0xC46F, 0x7664, 0xF04B, 0x7665, 0xC470, 0x7669, 0xC4EE, 0x766A, 0xF5DF, 0x766C, 0xC57E, 0x766D, 0xF6F4, - 0x766E, 0xC57D, 0x7670, 0xF7EA, 0x7671, 0xC5F5, 0x7672, 0xC5F6, 0x7675, 0xF9CC, 0x7678, 0xACD1, 0x7679, 0xCFDE, 0x767B, 0xB56E, - 0x767C, 0xB56F, 0x767D, 0xA5D5, 0x767E, 0xA6CA, 0x767F, 0xCA47, 0x7681, 0xCB71, 0x7682, 0xA86D, 0x7684, 0xAABA, 0x7686, 0xACD2, - 0x7687, 0xACD3, 0x7688, 0xACD4, 0x7689, 0xD6A6, 0x768A, 0xD2CB, 0x768B, 0xAF6F, 0x768E, 0xB2AE, 0x768F, 0xD6A5, 0x7692, 0xDAB8, - 0x7693, 0xB571, 0x7695, 0xDAB7, 0x7696, 0xB570, 0x7699, 0xDED5, 0x769A, 0xBD4A, 0x769B, 0xE6BB, 0x769C, 0xE6B8, 0x769D, 0xE6B9, - 0x769E, 0xE6BA, 0x76A4, 0xED78, 0x76A6, 0xF051, 0x76AA, 0xF471, 0x76AB, 0xF470, 0x76AD, 0xF6F5, 0x76AE, 0xA5D6, 0x76AF, 0xCD75, - 0x76B0, 0xAF70, 0x76B4, 0xB572, 0x76B5, 0xDED6, 0x76B8, 0xE2E1, 0x76BA, 0xBD4B, 0x76BB, 0xEA74, 0x76BD, 0xF052, 0x76BE, 0xF472, - 0x76BF, 0xA5D7, 0x76C2, 0xAABB, 0x76C3, 0xACD7, 0x76C4, 0xCFDF, 0x76C5, 0xACD8, 0x76C6, 0xACD6, 0x76C8, 0xACD5, 0x76C9, 0xD2CC, - 0x76CA, 0xAF71, 0x76CD, 0xAF72, 0x76CE, 0xAF73, 0x76D2, 0xB2B0, 0x76D3, 0xD6A7, 0x76D4, 0xB2AF, 0x76DA, 0xDAB9, 0x76DB, 0xB2B1, - 0x76DC, 0xB573, 0x76DD, 0xDED7, 0x76DE, 0xB7F8, 0x76DF, 0xB7F9, 0x76E1, 0xBAC9, 0x76E3, 0xBACA, 0x76E4, 0xBD4C, 0x76E5, 0xBF64, - 0x76E6, 0xEA75, 0x76E7, 0xBF63, 0x76E9, 0xED79, 0x76EA, 0xC0FA, 0x76EC, 0xF053, 0x76ED, 0xF473, 0x76EE, 0xA5D8, 0x76EF, 0xA86E, - 0x76F0, 0xCD78, 0x76F1, 0xCD77, 0x76F2, 0xAABC, 0x76F3, 0xCD76, 0x76F4, 0xAABD, 0x76F5, 0xCD79, 0x76F7, 0xCFE5, 0x76F8, 0xACDB, - 0x76F9, 0xACDA, 0x76FA, 0xCFE7, 0x76FB, 0xCFE6, 0x76FC, 0xACDF, 0x76FE, 0xACDE, 0x7701, 0xACD9, 0x7703, 0xCFE1, 0x7704, 0xCFE2, - 0x7705, 0xCFE3, 0x7707, 0xACE0, 0x7708, 0xCFE0, 0x7709, 0xACDC, 0x770A, 0xCFE4, 0x770B, 0xACDD, 0x7710, 0xD2CF, 0x7711, 0xD2D3, - 0x7712, 0xD2D1, 0x7713, 0xD2D0, 0x7715, 0xD2D4, 0x7719, 0xD2D5, 0x771A, 0xD2D6, 0x771B, 0xD2CE, 0x771D, 0xD2CD, 0x771F, 0xAF75, - 0x7720, 0xAF76, 0x7722, 0xD2D7, 0x7723, 0xD2D2, 0x7725, 0xD6B0, 0x7727, 0xD2D8, 0x7728, 0xAF77, 0x7729, 0xAF74, 0x772D, 0xD6AA, - 0x772F, 0xD6A9, 0x7731, 0xD6AB, 0x7732, 0xD6AC, 0x7733, 0xD6AE, 0x7734, 0xD6AD, 0x7735, 0xD6B2, 0x7736, 0xB2B5, 0x7737, 0xB2B2, - 0x7738, 0xB2B6, 0x7739, 0xD6A8, 0x773A, 0xB2B7, 0x773B, 0xD6B1, 0x773C, 0xB2B4, 0x773D, 0xD6AF, 0x773E, 0xB2B3, 0x7744, 0xDABC, - 0x7745, 0xDABE, 0x7746, 0xDABA, 0x7747, 0xDABB, 0x774A, 0xDABF, 0x774B, 0xDAC1, 0x774C, 0xDAC2, 0x774D, 0xDABD, 0x774E, 0xDAC0, - 0x774F, 0xB574, 0x7752, 0xDEDB, 0x7754, 0xDEE0, 0x7755, 0xDED8, 0x7756, 0xDEDC, 0x7759, 0xDEE1, 0x775A, 0xDEDD, 0x775B, 0xB7FA, - 0x775C, 0xB843, 0x775E, 0xB7FD, 0x775F, 0xDED9, 0x7760, 0xDEDA, 0x7761, 0xBACE, 0x7762, 0xB846, 0x7763, 0xB7FE, 0x7765, 0xB844, - 0x7766, 0xB7FC, 0x7767, 0xDEDF, 0x7768, 0xB845, 0x7769, 0xDEDE, 0x776A, 0xB841, 0x776B, 0xB7FB, 0x776C, 0xB842, 0x776D, 0xDEE2, - 0x776E, 0xE2E6, 0x776F, 0xE2E8, 0x7779, 0xB840, 0x777C, 0xE2E3, 0x777D, 0xBACC, 0x777E, 0xE2E9, 0x777F, 0xBACD, 0x7780, 0xE2E7, - 0x7781, 0xE2E2, 0x7782, 0xE2E5, 0x7783, 0xE2EA, 0x7784, 0xBACB, 0x7785, 0xE2E4, 0x7787, 0xBD4E, 0x7788, 0xE6BF, 0x7789, 0xE6BE, - 0x778B, 0xBD51, 0x778C, 0xBD4F, 0x778D, 0xE6BC, 0x778E, 0xBD4D, 0x778F, 0xE6BD, 0x7791, 0xBD50, 0x7795, 0xEA7D, 0x7797, 0xEAA1, - 0x7799, 0xEA7E, 0x779A, 0xEA76, 0x779B, 0xEA7A, 0x779C, 0xEA79, 0x779D, 0xEA77, 0x779E, 0xBF66, 0x779F, 0xBF67, 0x77A0, 0xBF65, - 0x77A1, 0xEA78, 0x77A2, 0xEA7B, 0x77A3, 0xEA7C, 0x77A5, 0xBF68, 0x77A7, 0xC140, 0x77A8, 0xEDA3, 0x77AA, 0xC0FC, 0x77AB, 0xED7B, - 0x77AC, 0xC0FE, 0x77AD, 0xC141, 0x77B0, 0xC0FD, 0x77B1, 0xEDA2, 0x77B2, 0xED7C, 0x77B3, 0xC0FB, 0x77B4, 0xEDA1, 0x77B5, 0xED7A, - 0x77B6, 0xED7E, 0x77B7, 0xED7D, 0x77BA, 0xF055, 0x77BB, 0xC2A4, 0x77BC, 0xC2A5, 0x77BD, 0xC2A2, 0x77BF, 0xC2A3, 0x77C2, 0xF054, - 0x77C4, 0xF27B, 0x77C7, 0xC3A9, 0x77C9, 0xF279, 0x77CA, 0xF27A, 0x77CC, 0xF474, 0x77CD, 0xF477, 0x77CE, 0xF475, 0x77CF, 0xF476, - 0x77D0, 0xF5E0, 0x77D3, 0xC4EF, 0x77D4, 0xF7EB, 0x77D5, 0xF8B4, 0x77D7, 0xC5F7, 0x77D8, 0xF8F8, 0x77D9, 0xF8F9, 0x77DA, 0xC666, - 0x77DB, 0xA5D9, 0x77DC, 0xACE1, 0x77DE, 0xDAC3, 0x77E0, 0xDEE3, 0x77E2, 0xA5DA, 0x77E3, 0xA86F, 0x77E5, 0xAABE, 0x77E7, 0xCFE8, - 0x77E8, 0xCFE9, 0x77E9, 0xAF78, 0x77EC, 0xDAC4, 0x77ED, 0xB575, 0x77EE, 0xB847, 0x77EF, 0xC142, 0x77F0, 0xEDA4, 0x77F1, 0xF27C, - 0x77F2, 0xF478, 0x77F3, 0xA5DB, 0x77F7, 0xCDA1, 0x77F8, 0xCD7A, 0x77F9, 0xCD7C, 0x77FA, 0xCD7E, 0x77FB, 0xCD7D, 0x77FC, 0xCD7B, - 0x77FD, 0xAABF, 0x7802, 0xACE2, 0x7803, 0xCFF2, 0x7805, 0xCFED, 0x7806, 0xCFEA, 0x7809, 0xCFF1, 0x780C, 0xACE4, 0x780D, 0xACE5, - 0x780E, 0xCFF0, 0x780F, 0xCFEF, 0x7810, 0xCFEE, 0x7811, 0xCFEB, 0x7812, 0xCFEC, 0x7813, 0xCFF3, 0x7814, 0xACE3, 0x781D, 0xAF7C, - 0x781F, 0xAFA4, 0x7820, 0xAFA3, 0x7821, 0xD2E1, 0x7822, 0xD2DB, 0x7823, 0xD2D9, 0x7825, 0xAFA1, 0x7826, 0xD6B9, 0x7827, 0xAF7A, - 0x7828, 0xD2DE, 0x7829, 0xD2E2, 0x782A, 0xD2E4, 0x782B, 0xD2E0, 0x782C, 0xD2DA, 0x782D, 0xAFA2, 0x782E, 0xD2DF, 0x782F, 0xD2DD, - 0x7830, 0xAF79, 0x7831, 0xD2E5, 0x7832, 0xAFA5, 0x7833, 0xD2E3, 0x7834, 0xAF7D, 0x7835, 0xD2DC, 0x7837, 0xAF7E, 0x7838, 0xAF7B, - 0x7843, 0xB2B9, 0x7845, 0xD6BA, 0x7848, 0xD6B3, 0x7849, 0xD6B5, 0x784A, 0xD6B7, 0x784C, 0xD6B8, 0x784D, 0xD6B6, 0x784E, 0xB2BA, - 0x7850, 0xD6BB, 0x7852, 0xD6B4, 0x785C, 0xDAC8, 0x785D, 0xB576, 0x785E, 0xDAD0, 0x7860, 0xDAC5, 0x7862, 0xDAD1, 0x7864, 0xDAC6, - 0x7865, 0xDAC7, 0x7868, 0xDACF, 0x7869, 0xDACE, 0x786A, 0xDACB, 0x786B, 0xB2B8, 0x786C, 0xB577, 0x786D, 0xDAC9, 0x786E, 0xDACC, - 0x786F, 0xB578, 0x7870, 0xDACD, 0x7871, 0xDACA, 0x7879, 0xDEEE, 0x787B, 0xDEF2, 0x787C, 0xB84E, 0x787E, 0xE2F0, 0x787F, 0xB851, - 0x7880, 0xDEF0, 0x7881, 0xF9D6, 0x7883, 0xDEED, 0x7884, 0xDEE8, 0x7885, 0xDEEA, 0x7886, 0xDEEB, 0x7887, 0xDEE4, 0x7889, 0xB84D, - 0x788C, 0xB84C, 0x788E, 0xB848, 0x788F, 0xDEE7, 0x7891, 0xB84F, 0x7893, 0xB850, 0x7894, 0xDEE6, 0x7895, 0xDEE9, 0x7896, 0xDEF1, - 0x7897, 0xB84A, 0x7898, 0xB84B, 0x7899, 0xDEEF, 0x789A, 0xDEE5, 0x789E, 0xE2F2, 0x789F, 0xBAD0, 0x78A0, 0xE2F4, 0x78A1, 0xDEEC, - 0x78A2, 0xE2F6, 0x78A3, 0xBAD4, 0x78A4, 0xE2F7, 0x78A5, 0xE2F3, 0x78A7, 0xBAD1, 0x78A8, 0xE2EF, 0x78A9, 0xBAD3, 0x78AA, 0xE2EC, - 0x78AB, 0xE2F1, 0x78AC, 0xE2F5, 0x78AD, 0xE2EE, 0x78B0, 0xB849, 0x78B2, 0xE2EB, 0x78B3, 0xBAD2, 0x78B4, 0xE2ED, 0x78BA, 0xBD54, - 0x78BB, 0xE6C1, 0x78BC, 0xBD58, 0x78BE, 0xBD56, 0x78C1, 0xBACF, 0x78C3, 0xE6C8, 0x78C4, 0xE6C9, 0x78C5, 0xBD53, 0x78C8, 0xE6C7, - 0x78C9, 0xE6CA, 0x78CA, 0xBD55, 0x78CB, 0xBD52, 0x78CC, 0xE6C3, 0x78CD, 0xE6C0, 0x78CE, 0xE6C5, 0x78CF, 0xE6C2, 0x78D0, 0xBD59, - 0x78D1, 0xE6C4, 0x78D4, 0xE6C6, 0x78D5, 0xBD57, 0x78DA, 0xBF6A, 0x78DB, 0xEAA8, 0x78DD, 0xEAA2, 0x78DE, 0xEAA6, 0x78DF, 0xEAAC, - 0x78E0, 0xEAAD, 0x78E1, 0xEAA9, 0x78E2, 0xEAAA, 0x78E3, 0xEAA7, 0x78E5, 0xEAA4, 0x78E7, 0xBF6C, 0x78E8, 0xBF69, 0x78E9, 0xEAA3, - 0x78EA, 0xEAA5, 0x78EC, 0xBF6B, 0x78ED, 0xEAAB, 0x78EF, 0xC146, 0x78F2, 0xEDAA, 0x78F3, 0xEDA5, 0x78F4, 0xC145, 0x78F7, 0xC143, - 0x78F9, 0xEDAC, 0x78FA, 0xC144, 0x78FB, 0xEDA8, 0x78FC, 0xEDA9, 0x78FD, 0xEDA6, 0x78FE, 0xEDAD, 0x78FF, 0xF056, 0x7901, 0xC147, - 0x7902, 0xEDA7, 0x7904, 0xEDAE, 0x7905, 0xEDAB, 0x7909, 0xF05A, 0x790C, 0xF057, 0x790E, 0xC2A6, 0x7910, 0xF05B, 0x7911, 0xF05D, - 0x7912, 0xF05C, 0x7913, 0xF058, 0x7914, 0xF059, 0x7917, 0xF2A3, 0x7919, 0xC3AA, 0x791B, 0xF27E, 0x791C, 0xF2A2, 0x791D, 0xF27D, - 0x791E, 0xF2A4, 0x7921, 0xF2A1, 0x7923, 0xF47A, 0x7924, 0xF47D, 0x7925, 0xF479, 0x7926, 0xC471, 0x7927, 0xF47B, 0x7928, 0xF47C, - 0x7929, 0xF47E, 0x792A, 0xC472, 0x792B, 0xC474, 0x792C, 0xC473, 0x792D, 0xF5E1, 0x792F, 0xF5E3, 0x7931, 0xF5E2, 0x7935, 0xF6F6, - 0x7938, 0xF8B5, 0x7939, 0xF8FA, 0x793A, 0xA5DC, 0x793D, 0xCB72, 0x793E, 0xAAC0, 0x793F, 0xCDA3, 0x7940, 0xAAC1, 0x7941, 0xAAC2, - 0x7942, 0xCDA2, 0x7944, 0xCFF8, 0x7945, 0xCFF7, 0x7946, 0xACE6, 0x7947, 0xACE9, 0x7948, 0xACE8, 0x7949, 0xACE7, 0x794A, 0xCFF4, - 0x794B, 0xCFF6, 0x794C, 0xCFF5, 0x794F, 0xD2E8, 0x7950, 0xAFA7, 0x7951, 0xD2EC, 0x7952, 0xD2EB, 0x7953, 0xD2EA, 0x7954, 0xD2E6, - 0x7955, 0xAFA6, 0x7956, 0xAFAA, 0x7957, 0xAFAD, 0x795A, 0xAFAE, 0x795B, 0xD2E7, 0x795C, 0xD2E9, 0x795D, 0xAFAC, 0x795E, 0xAFAB, - 0x795F, 0xAFA9, 0x7960, 0xAFA8, 0x7961, 0xD6C2, 0x7963, 0xD6C0, 0x7964, 0xD6BC, 0x7965, 0xB2BB, 0x7967, 0xD6BD, 0x7968, 0xB2BC, - 0x7969, 0xD6BE, 0x796A, 0xD6BF, 0x796B, 0xD6C1, 0x796D, 0xB2BD, 0x7970, 0xDAD5, 0x7972, 0xDAD4, 0x7973, 0xDAD3, 0x7974, 0xDAD2, - 0x7979, 0xDEF6, 0x797A, 0xB852, 0x797C, 0xDEF3, 0x797D, 0xDEF5, 0x797F, 0xB853, 0x7981, 0xB854, 0x7982, 0xDEF4, 0x7988, 0xE341, - 0x798A, 0xE2F9, 0x798B, 0xE2FA, 0x798D, 0xBAD7, 0x798E, 0xBAD5, 0x798F, 0xBAD6, 0x7990, 0xE343, 0x7992, 0xE342, 0x7993, 0xE2FE, - 0x7994, 0xE2FD, 0x7995, 0xE2FC, 0x7996, 0xE2FB, 0x7997, 0xE340, 0x7998, 0xE2F8, 0x799A, 0xE6CB, 0x799B, 0xE6D0, 0x799C, 0xE6CE, - 0x79A0, 0xE6CD, 0x79A1, 0xE6CC, 0x79A2, 0xE6CF, 0x79A4, 0xEAAE, 0x79A6, 0xBF6D, 0x79A7, 0xC148, 0x79A8, 0xEDB0, 0x79AA, 0xC149, - 0x79AB, 0xEDAF, 0x79AC, 0xF05F, 0x79AD, 0xF05E, 0x79AE, 0xC2A7, 0x79B0, 0xF2A5, 0x79B1, 0xC3AB, 0x79B2, 0xF4A1, 0x79B3, 0xC5A1, - 0x79B4, 0xF6F7, 0x79B6, 0xF8B7, 0x79B7, 0xF8B6, 0x79B8, 0xC9A8, 0x79B9, 0xACEA, 0x79BA, 0xACEB, 0x79BB, 0xD6C3, 0x79BD, 0xB856, - 0x79BE, 0xA5DD, 0x79BF, 0xA872, 0x79C0, 0xA871, 0x79C1, 0xA870, 0x79C5, 0xCDA4, 0x79C8, 0xAAC4, 0x79C9, 0xAAC3, 0x79CB, 0xACEE, - 0x79CD, 0xCFFA, 0x79CE, 0xCFFD, 0x79CF, 0xCFFB, 0x79D1, 0xACEC, 0x79D2, 0xACED, 0x79D5, 0xCFF9, 0x79D6, 0xCFFC, 0x79D8, 0xAFB5, - 0x79DC, 0xD2F3, 0x79DD, 0xD2F5, 0x79DE, 0xD2F4, 0x79DF, 0xAFB2, 0x79E0, 0xD2EF, 0x79E3, 0xAFB0, 0x79E4, 0xAFAF, 0x79E6, 0xAFB3, - 0x79E7, 0xAFB1, 0x79E9, 0xAFB4, 0x79EA, 0xD2F2, 0x79EB, 0xD2ED, 0x79EC, 0xD2EE, 0x79ED, 0xD2F1, 0x79EE, 0xD2F0, 0x79F6, 0xD6C6, - 0x79F7, 0xD6C7, 0x79F8, 0xD6C5, 0x79FA, 0xD6C4, 0x79FB, 0xB2BE, 0x7A00, 0xB57D, 0x7A02, 0xDAD6, 0x7A03, 0xDAD8, 0x7A04, 0xDADA, - 0x7A05, 0xB57C, 0x7A08, 0xB57A, 0x7A0A, 0xDAD7, 0x7A0B, 0xB57B, 0x7A0C, 0xDAD9, 0x7A0D, 0xB579, 0x7A10, 0xDF41, 0x7A11, 0xDEF7, - 0x7A12, 0xDEFA, 0x7A13, 0xDEFE, 0x7A14, 0xB85A, 0x7A15, 0xDEFC, 0x7A17, 0xDEFB, 0x7A18, 0xDEF8, 0x7A19, 0xDEF9, 0x7A1A, 0xB858, - 0x7A1B, 0xDF40, 0x7A1C, 0xB857, 0x7A1E, 0xB85C, 0x7A1F, 0xB85B, 0x7A20, 0xB859, 0x7A22, 0xDEFD, 0x7A26, 0xE349, 0x7A28, 0xE348, - 0x7A2B, 0xE344, 0x7A2E, 0xBAD8, 0x7A2F, 0xE347, 0x7A30, 0xE346, 0x7A31, 0xBAD9, 0x7A37, 0xBD5E, 0x7A39, 0xE6D2, 0x7A3B, 0xBD5F, - 0x7A3C, 0xBD5B, 0x7A3D, 0xBD5D, 0x7A3F, 0xBD5A, 0x7A40, 0xBD5C, 0x7A44, 0xEAAF, 0x7A46, 0xBF70, 0x7A47, 0xEAB1, 0x7A48, 0xEAB0, - 0x7A4A, 0xE345, 0x7A4B, 0xBF72, 0x7A4C, 0xBF71, 0x7A4D, 0xBF6E, 0x7A4E, 0xBF6F, 0x7A54, 0xEDB5, 0x7A56, 0xEDB3, 0x7A57, 0xC14A, - 0x7A58, 0xEDB4, 0x7A5A, 0xEDB6, 0x7A5B, 0xEDB2, 0x7A5C, 0xEDB1, 0x7A5F, 0xF060, 0x7A60, 0xC2AA, 0x7A61, 0xC2A8, 0x7A62, 0xC2A9, - 0x7A67, 0xF2A6, 0x7A68, 0xF2A7, 0x7A69, 0xC3AD, 0x7A6B, 0xC3AC, 0x7A6C, 0xF4A3, 0x7A6D, 0xF4A4, 0x7A6E, 0xF4A2, 0x7A70, 0xF6F8, - 0x7A71, 0xF6F9, 0x7A74, 0xA5DE, 0x7A75, 0xCA48, 0x7A76, 0xA873, 0x7A78, 0xCDA5, 0x7A79, 0xAAC6, 0x7A7A, 0xAAC5, 0x7A7B, 0xCDA6, - 0x7A7E, 0xD040, 0x7A7F, 0xACEF, 0x7A80, 0xCFFE, 0x7A81, 0xACF0, 0x7A84, 0xAFB6, 0x7A85, 0xD2F8, 0x7A86, 0xD2F6, 0x7A87, 0xD2FC, - 0x7A88, 0xAFB7, 0x7A89, 0xD2F7, 0x7A8A, 0xD2FB, 0x7A8B, 0xD2F9, 0x7A8C, 0xD2FA, 0x7A8F, 0xD6C8, 0x7A90, 0xD6CA, 0x7A92, 0xB2BF, - 0x7A94, 0xD6C9, 0x7A95, 0xB2C0, 0x7A96, 0xB5A2, 0x7A97, 0xB5A1, 0x7A98, 0xB57E, 0x7A99, 0xDADB, 0x7A9E, 0xDF44, 0x7A9F, 0xB85D, - 0x7AA0, 0xB85E, 0x7AA2, 0xDF43, 0x7AA3, 0xDF42, 0x7AA8, 0xE34A, 0x7AA9, 0xBADB, 0x7AAA, 0xBADA, 0x7AAB, 0xE34B, 0x7AAC, 0xE34C, - 0x7AAE, 0xBD61, 0x7AAF, 0xBD60, 0x7AB1, 0xEAB5, 0x7AB2, 0xE6D3, 0x7AB3, 0xE6D5, 0x7AB4, 0xE6D4, 0x7AB5, 0xEAB4, 0x7AB6, 0xEAB2, - 0x7AB7, 0xEAB6, 0x7AB8, 0xEAB3, 0x7ABA, 0xBF73, 0x7ABE, 0xEDB7, 0x7ABF, 0xC14B, 0x7AC0, 0xEDB8, 0x7AC1, 0xEDB9, 0x7AC4, 0xC2AB, - 0x7AC5, 0xC2AC, 0x7AC7, 0xC475, 0x7ACA, 0xC5D1, 0x7ACB, 0xA5DF, 0x7AD1, 0xD041, 0x7AD8, 0xD2FD, 0x7AD9, 0xAFB8, 0x7ADF, 0xB3BA, - 0x7AE0, 0xB3B9, 0x7AE3, 0xB5A4, 0x7AE4, 0xDADD, 0x7AE5, 0xB5A3, 0x7AE6, 0xDADC, 0x7AEB, 0xDF45, 0x7AED, 0xBADC, 0x7AEE, 0xE34D, - 0x7AEF, 0xBADD, 0x7AF6, 0xC476, 0x7AF7, 0xF4A5, 0x7AF9, 0xA6CB, 0x7AFA, 0xAAC7, 0x7AFB, 0xCDA7, 0x7AFD, 0xACF2, 0x7AFF, 0xACF1, - 0x7B00, 0xD042, 0x7B01, 0xD043, 0x7B04, 0xD340, 0x7B05, 0xD342, 0x7B06, 0xAFB9, 0x7B08, 0xD344, 0x7B09, 0xD347, 0x7B0A, 0xD345, - 0x7B0E, 0xD346, 0x7B0F, 0xD343, 0x7B10, 0xD2FE, 0x7B11, 0xAFBA, 0x7B12, 0xD348, 0x7B13, 0xD341, 0x7B18, 0xD6D3, 0x7B19, 0xB2C6, - 0x7B1A, 0xD6DC, 0x7B1B, 0xB2C3, 0x7B1D, 0xD6D5, 0x7B1E, 0xB2C7, 0x7B20, 0xB2C1, 0x7B22, 0xD6D0, 0x7B23, 0xD6DD, 0x7B24, 0xD6D1, - 0x7B25, 0xD6CE, 0x7B26, 0xB2C5, 0x7B28, 0xB2C2, 0x7B2A, 0xD6D4, 0x7B2B, 0xD6D7, 0x7B2C, 0xB2C4, 0x7B2D, 0xD6D8, 0x7B2E, 0xB2C8, - 0x7B2F, 0xD6D9, 0x7B30, 0xD6CF, 0x7B31, 0xD6D6, 0x7B32, 0xD6DA, 0x7B33, 0xD6D2, 0x7B34, 0xD6CD, 0x7B35, 0xD6CB, 0x7B38, 0xD6DB, - 0x7B3B, 0xDADF, 0x7B40, 0xDAE4, 0x7B44, 0xDAE0, 0x7B45, 0xDAE6, 0x7B46, 0xB5A7, 0x7B47, 0xD6CC, 0x7B48, 0xDAE1, 0x7B49, 0xB5A5, - 0x7B4A, 0xDADE, 0x7B4B, 0xB5AC, 0x7B4C, 0xDAE2, 0x7B4D, 0xB5AB, 0x7B4E, 0xDAE3, 0x7B4F, 0xB5AD, 0x7B50, 0xB5A8, 0x7B51, 0xB5AE, - 0x7B52, 0xB5A9, 0x7B54, 0xB5AA, 0x7B56, 0xB5A6, 0x7B58, 0xDAE5, 0x7B60, 0xB861, 0x7B61, 0xDF50, 0x7B63, 0xDF53, 0x7B64, 0xDF47, - 0x7B65, 0xDF4C, 0x7B66, 0xDF46, 0x7B67, 0xB863, 0x7B69, 0xDF4A, 0x7B6D, 0xDF48, 0x7B6E, 0xB862, 0x7B70, 0xDF4F, 0x7B71, 0xDF4E, - 0x7B72, 0xDF4B, 0x7B73, 0xDF4D, 0x7B74, 0xDF49, 0x7B75, 0xBAE1, 0x7B76, 0xDF52, 0x7B77, 0xB85F, 0x7B78, 0xDF51, 0x7B82, 0xE35D, - 0x7B84, 0xBAE8, 0x7B85, 0xE358, 0x7B87, 0xBAE7, 0x7B88, 0xE34E, 0x7B8A, 0xE350, 0x7B8B, 0xBAE0, 0x7B8C, 0xE355, 0x7B8D, 0xE354, - 0x7B8E, 0xE357, 0x7B8F, 0xBAE5, 0x7B90, 0xE352, 0x7B91, 0xE351, 0x7B94, 0xBAE4, 0x7B95, 0xBADF, 0x7B96, 0xE353, 0x7B97, 0xBAE2, - 0x7B98, 0xE359, 0x7B99, 0xE35B, 0x7B9B, 0xE356, 0x7B9C, 0xE34F, 0x7B9D, 0xBAE3, 0x7BA0, 0xBD69, 0x7BA1, 0xBADE, 0x7BA4, 0xE35C, - 0x7BAC, 0xE6D9, 0x7BAD, 0xBD62, 0x7BAF, 0xE6DB, 0x7BB1, 0xBD63, 0x7BB4, 0xBD65, 0x7BB5, 0xE6DE, 0x7BB7, 0xE6D6, 0x7BB8, 0xBAE6, - 0x7BB9, 0xE6DC, 0x7BBE, 0xE6D8, 0x7BC0, 0xB860, 0x7BC1, 0xBD68, 0x7BC4, 0xBD64, 0x7BC6, 0xBD66, 0x7BC7, 0xBD67, 0x7BC9, 0xBF76, - 0x7BCA, 0xE6DD, 0x7BCB, 0xE6D7, 0x7BCC, 0xBD6A, 0x7BCE, 0xE6DA, 0x7BD4, 0xEAC0, 0x7BD5, 0xEABB, 0x7BD8, 0xEAC5, 0x7BD9, 0xBF74, - 0x7BDA, 0xEABD, 0x7BDB, 0xBF78, 0x7BDC, 0xEAC3, 0x7BDD, 0xEABA, 0x7BDE, 0xEAB7, 0x7BDF, 0xEAC6, 0x7BE0, 0xC151, 0x7BE1, 0xBF79, - 0x7BE2, 0xEAC2, 0x7BE3, 0xEAB8, 0x7BE4, 0xBF77, 0x7BE5, 0xEABC, 0x7BE6, 0xBF7B, 0x7BE7, 0xEAB9, 0x7BE8, 0xEABE, 0x7BE9, 0xBF7A, - 0x7BEA, 0xEAC1, 0x7BEB, 0xEAC4, 0x7BF0, 0xEDCB, 0x7BF1, 0xEDCC, 0x7BF2, 0xEDBC, 0x7BF3, 0xEDC3, 0x7BF4, 0xEDC1, 0x7BF7, 0xC14F, - 0x7BF8, 0xEDC8, 0x7BF9, 0xEABF, 0x7BFB, 0xEDBF, 0x7BFD, 0xEDC9, 0x7BFE, 0xC14E, 0x7BFF, 0xEDBE, 0x7C00, 0xEDBD, 0x7C01, 0xEDC7, - 0x7C02, 0xEDC4, 0x7C03, 0xEDC6, 0x7C05, 0xEDBA, 0x7C06, 0xEDCA, 0x7C07, 0xC14C, 0x7C09, 0xEDC5, 0x7C0A, 0xEDCE, 0x7C0B, 0xEDC2, - 0x7C0C, 0xC150, 0x7C0D, 0xC14D, 0x7C0E, 0xEDC0, 0x7C0F, 0xEDBB, 0x7C10, 0xEDCD, 0x7C11, 0xBF75, 0x7C19, 0xF063, 0x7C1C, 0xF061, - 0x7C1D, 0xF067, 0x7C1E, 0xC2B0, 0x7C1F, 0xF065, 0x7C20, 0xF064, 0x7C21, 0xC2B2, 0x7C22, 0xF06A, 0x7C23, 0xC2B1, 0x7C25, 0xF06B, - 0x7C26, 0xF068, 0x7C27, 0xC2AE, 0x7C28, 0xF069, 0x7C29, 0xF062, 0x7C2A, 0xC2AF, 0x7C2B, 0xC2AD, 0x7C2C, 0xF2AB, 0x7C2D, 0xF066, - 0x7C30, 0xF06C, 0x7C33, 0xF2A8, 0x7C37, 0xC3B2, 0x7C38, 0xC3B0, 0x7C39, 0xF2AA, 0x7C3B, 0xF2AC, 0x7C3C, 0xF2A9, 0x7C3D, 0xC3B1, - 0x7C3E, 0xC3AE, 0x7C3F, 0xC3AF, 0x7C40, 0xC3B3, 0x7C43, 0xC478, 0x7C45, 0xF4AA, 0x7C47, 0xF4A9, 0x7C48, 0xF4A7, 0x7C49, 0xF4A6, - 0x7C4A, 0xF4A8, 0x7C4C, 0xC477, 0x7C4D, 0xC479, 0x7C50, 0xC4F0, 0x7C53, 0xF5E5, 0x7C54, 0xF5E4, 0x7C57, 0xF6FA, 0x7C59, 0xF6FC, - 0x7C5A, 0xF6FE, 0x7C5B, 0xF6FD, 0x7C5C, 0xF6FB, 0x7C5F, 0xC5A3, 0x7C60, 0xC5A2, 0x7C63, 0xC5D3, 0x7C64, 0xC5D2, 0x7C65, 0xC5D4, - 0x7C66, 0xF7ED, 0x7C67, 0xF7EC, 0x7C69, 0xF8FB, 0x7C6A, 0xF8B8, 0x7C6B, 0xF8FC, 0x7C6C, 0xC658, 0x7C6E, 0xC659, 0x7C6F, 0xF96D, - 0x7C72, 0xC67E, 0x7C73, 0xA6CC, 0x7C75, 0xCDA8, 0x7C78, 0xD045, 0x7C79, 0xD046, 0x7C7A, 0xD044, 0x7C7D, 0xACF3, 0x7C7F, 0xD047, - 0x7C80, 0xD048, 0x7C81, 0xD049, 0x7C84, 0xD349, 0x7C85, 0xD34F, 0x7C88, 0xD34D, 0x7C89, 0xAFBB, 0x7C8A, 0xD34B, 0x7C8C, 0xD34C, - 0x7C8D, 0xD34E, 0x7C91, 0xD34A, 0x7C92, 0xB2C9, 0x7C94, 0xD6DE, 0x7C95, 0xB2CB, 0x7C96, 0xD6E0, 0x7C97, 0xB2CA, 0x7C98, 0xD6DF, - 0x7C9E, 0xDAE8, 0x7C9F, 0xB5AF, 0x7CA1, 0xDAEA, 0x7CA2, 0xDAE7, 0x7CA3, 0xD6E1, 0x7CA5, 0xB5B0, 0x7CA7, 0xF9DB, 0x7CA8, 0xDAE9, - 0x7CAF, 0xDF56, 0x7CB1, 0xB864, 0x7CB2, 0xDF54, 0x7CB3, 0xB865, 0x7CB4, 0xDF55, 0x7CB5, 0xB866, 0x7CB9, 0xBAE9, 0x7CBA, 0xE361, - 0x7CBB, 0xE35E, 0x7CBC, 0xE360, 0x7CBD, 0xBAEA, 0x7CBE, 0xBAEB, 0x7CBF, 0xE35F, 0x7CC5, 0xE6DF, 0x7CC8, 0xE6E0, 0x7CCA, 0xBD6B, - 0x7CCB, 0xE6E2, 0x7CCC, 0xE6E1, 0x7CCE, 0xA261, 0x7CD0, 0xEACA, 0x7CD1, 0xEACB, 0x7CD2, 0xEAC7, 0x7CD4, 0xEAC8, 0x7CD5, 0xBF7C, - 0x7CD6, 0xBF7D, 0x7CD7, 0xEAC9, 0x7CD9, 0xC157, 0x7CDC, 0xC153, 0x7CDD, 0xC158, 0x7CDE, 0xC154, 0x7CDF, 0xC156, 0x7CE0, 0xC152, - 0x7CE2, 0xC155, 0x7CE7, 0xC2B3, 0x7CE8, 0xEDCF, 0x7CEA, 0xF2AE, 0x7CEC, 0xF2AD, 0x7CEE, 0xF4AB, 0x7CEF, 0xC47A, 0x7CF0, 0xC47B, - 0x7CF1, 0xF741, 0x7CF2, 0xF5E6, 0x7CF4, 0xF740, 0x7CF6, 0xF8FD, 0x7CF7, 0xF9A4, 0x7CF8, 0xA6CD, 0x7CFB, 0xA874, 0x7CFD, 0xCDA9, - 0x7CFE, 0xAAC8, 0x7D00, 0xACF6, 0x7D01, 0xD04C, 0x7D02, 0xACF4, 0x7D03, 0xD04A, 0x7D04, 0xACF9, 0x7D05, 0xACF5, 0x7D06, 0xACFA, - 0x7D07, 0xACF8, 0x7D08, 0xD04B, 0x7D09, 0xACF7, 0x7D0A, 0xAFBF, 0x7D0B, 0xAFBE, 0x7D0C, 0xD35A, 0x7D0D, 0xAFC7, 0x7D0E, 0xD353, - 0x7D0F, 0xD359, 0x7D10, 0xAFC3, 0x7D11, 0xD352, 0x7D12, 0xD358, 0x7D13, 0xD356, 0x7D14, 0xAFC2, 0x7D15, 0xAFC4, 0x7D16, 0xD355, - 0x7D17, 0xAFBD, 0x7D18, 0xD354, 0x7D19, 0xAFC8, 0x7D1A, 0xAFC5, 0x7D1B, 0xAFC9, 0x7D1C, 0xAFC6, 0x7D1D, 0xD351, 0x7D1E, 0xD350, - 0x7D1F, 0xD357, 0x7D20, 0xAFC0, 0x7D21, 0xAFBC, 0x7D22, 0xAFC1, 0x7D28, 0xD6F0, 0x7D29, 0xD6E9, 0x7D2B, 0xB5B5, 0x7D2C, 0xD6E8, - 0x7D2E, 0xB2CF, 0x7D2F, 0xB2D6, 0x7D30, 0xB2D3, 0x7D31, 0xB2D9, 0x7D32, 0xB2D8, 0x7D33, 0xB2D4, 0x7D35, 0xD6E2, 0x7D36, 0xD6E5, - 0x7D38, 0xD6E4, 0x7D39, 0xB2D0, 0x7D3A, 0xD6E6, 0x7D3B, 0xD6EF, 0x7D3C, 0xB2D1, 0x7D3D, 0xD6E3, 0x7D3E, 0xD6EC, 0x7D3F, 0xD6ED, - 0x7D40, 0xB2D2, 0x7D41, 0xD6EA, 0x7D42, 0xB2D7, 0x7D43, 0xB2CD, 0x7D44, 0xB2D5, 0x7D45, 0xD6E7, 0x7D46, 0xB2CC, 0x7D47, 0xD6EB, - 0x7D4A, 0xD6EE, 0x7D4E, 0xDAFB, 0x7D4F, 0xDAF2, 0x7D50, 0xB5B2, 0x7D51, 0xDAF9, 0x7D52, 0xDAF6, 0x7D53, 0xDAEE, 0x7D54, 0xDAF7, - 0x7D55, 0xB5B4, 0x7D56, 0xDAEF, 0x7D58, 0xDAEB, 0x7D5B, 0xB86C, 0x7D5C, 0xDAF4, 0x7D5E, 0xB5B1, 0x7D5F, 0xDAFA, 0x7D61, 0xB5B8, - 0x7D62, 0xB5BA, 0x7D63, 0xDAED, 0x7D66, 0xB5B9, 0x7D67, 0xDAF0, 0x7D68, 0xB5B3, 0x7D69, 0xDAF8, 0x7D6A, 0xDAF1, 0x7D6B, 0xDAF5, - 0x7D6D, 0xDAF3, 0x7D6E, 0xB5B6, 0x7D6F, 0xDAEC, 0x7D70, 0xB5BB, 0x7D71, 0xB2CE, 0x7D72, 0xB5B7, 0x7D73, 0xB5BC, 0x7D79, 0xB868, - 0x7D7A, 0xDF5D, 0x7D7B, 0xDF5F, 0x7D7C, 0xDF61, 0x7D7D, 0xDF65, 0x7D7F, 0xDF5B, 0x7D80, 0xDF59, 0x7D81, 0xB86A, 0x7D83, 0xDF60, - 0x7D84, 0xDF64, 0x7D85, 0xDF5C, 0x7D86, 0xDF58, 0x7D88, 0xDF57, 0x7D8C, 0xDF62, 0x7D8D, 0xDF5A, 0x7D8E, 0xDF5E, 0x7D8F, 0xB86B, - 0x7D91, 0xB869, 0x7D92, 0xDF66, 0x7D93, 0xB867, 0x7D94, 0xDF63, 0x7D96, 0xE372, 0x7D9C, 0xBAEE, 0x7D9D, 0xE36A, 0x7D9E, 0xBD78, - 0x7D9F, 0xE374, 0x7DA0, 0xBAF1, 0x7DA1, 0xE378, 0x7DA2, 0xBAF7, 0x7DA3, 0xE365, 0x7DA6, 0xE375, 0x7DA7, 0xE362, 0x7DA9, 0xE377, - 0x7DAA, 0xE366, 0x7DAC, 0xBAFE, 0x7DAD, 0xBAFB, 0x7DAE, 0xE376, 0x7DAF, 0xE370, 0x7DB0, 0xBAED, 0x7DB1, 0xBAF5, 0x7DB2, 0xBAF4, - 0x7DB4, 0xBAF3, 0x7DB5, 0xBAF9, 0x7DB7, 0xE363, 0x7DB8, 0xBAFA, 0x7DB9, 0xE371, 0x7DBA, 0xBAF6, 0x7DBB, 0xBAEC, 0x7DBC, 0xE373, - 0x7DBD, 0xBAEF, 0x7DBE, 0xBAF0, 0x7DBF, 0xBAF8, 0x7DC0, 0xE368, 0x7DC1, 0xE367, 0x7DC2, 0xE364, 0x7DC4, 0xE36C, 0x7DC5, 0xE369, - 0x7DC6, 0xE36D, 0x7DC7, 0xBAFD, 0x7DC9, 0xE379, 0x7DCA, 0xBAF2, 0x7DCB, 0xE36E, 0x7DCC, 0xE36F, 0x7DCE, 0xE36B, 0x7DD2, 0xBAFC, - 0x7DD7, 0xE6E7, 0x7DD8, 0xBD70, 0x7DD9, 0xBD79, 0x7DDA, 0xBD75, 0x7DDB, 0xE6E4, 0x7DDD, 0xBD72, 0x7DDE, 0xBD76, 0x7DDF, 0xE6F0, - 0x7DE0, 0xBD6C, 0x7DE1, 0xE6E8, 0x7DE3, 0xBD74, 0x7DE6, 0xE6EB, 0x7DE7, 0xE6E6, 0x7DE8, 0xBD73, 0x7DE9, 0xBD77, 0x7DEA, 0xE6E5, - 0x7DEC, 0xBD71, 0x7DEE, 0xE6EF, 0x7DEF, 0xBD6E, 0x7DF0, 0xE6EE, 0x7DF1, 0xE6ED, 0x7DF2, 0xBD7A, 0x7DF3, 0xE572, 0x7DF4, 0xBD6D, - 0x7DF6, 0xE6EC, 0x7DF7, 0xE6E3, 0x7DF9, 0xBD7B, 0x7DFA, 0xE6EA, 0x7DFB, 0xBD6F, 0x7E03, 0xE6E9, 0x7E08, 0xBFA2, 0x7E09, 0xBFA7, - 0x7E0A, 0xBF7E, 0x7E0B, 0xEAD8, 0x7E0C, 0xEACF, 0x7E0D, 0xEADB, 0x7E0E, 0xEAD3, 0x7E0F, 0xEAD9, 0x7E10, 0xBFA8, 0x7E11, 0xBFA1, - 0x7E12, 0xEACC, 0x7E13, 0xEAD2, 0x7E14, 0xEADC, 0x7E15, 0xEAD5, 0x7E16, 0xEADA, 0x7E17, 0xEACE, 0x7E1A, 0xEAD6, 0x7E1B, 0xBFA3, - 0x7E1C, 0xEAD4, 0x7E1D, 0xBFA6, 0x7E1E, 0xBFA5, 0x7E1F, 0xEAD0, 0x7E20, 0xEAD1, 0x7E21, 0xEACD, 0x7E22, 0xEAD7, 0x7E23, 0xBFA4, - 0x7E24, 0xEADE, 0x7E25, 0xEADD, 0x7E29, 0xEDDA, 0x7E2A, 0xEDD6, 0x7E2B, 0xC15F, 0x7E2D, 0xEDD0, 0x7E2E, 0xC159, 0x7E2F, 0xC169, - 0x7E30, 0xEDDC, 0x7E31, 0xC161, 0x7E32, 0xC15D, 0x7E33, 0xEDD3, 0x7E34, 0xC164, 0x7E35, 0xC167, 0x7E36, 0xEDDE, 0x7E37, 0xC15C, - 0x7E38, 0xEDD5, 0x7E39, 0xC165, 0x7E3A, 0xEDE0, 0x7E3B, 0xEDDD, 0x7E3C, 0xEDD1, 0x7E3D, 0xC160, 0x7E3E, 0xC15A, 0x7E3F, 0xC168, - 0x7E40, 0xEDD8, 0x7E41, 0xC163, 0x7E42, 0xEDD2, 0x7E43, 0xC15E, 0x7E44, 0xEDDF, 0x7E45, 0xC162, 0x7E46, 0xC15B, 0x7E47, 0xEDD9, - 0x7E48, 0xC166, 0x7E49, 0xEDD7, 0x7E4C, 0xEDDB, 0x7E50, 0xF06E, 0x7E51, 0xF074, 0x7E52, 0xC2B9, 0x7E53, 0xF077, 0x7E54, 0xC2B4, - 0x7E55, 0xC2B5, 0x7E56, 0xF06F, 0x7E57, 0xF076, 0x7E58, 0xF071, 0x7E59, 0xC2BA, 0x7E5A, 0xC2B7, 0x7E5C, 0xF06D, 0x7E5E, 0xC2B6, - 0x7E5F, 0xF073, 0x7E60, 0xF075, 0x7E61, 0xC2B8, 0x7E62, 0xF072, 0x7E63, 0xF070, 0x7E68, 0xF2B8, 0x7E69, 0xC3B7, 0x7E6A, 0xC3B8, - 0x7E6B, 0xC3B4, 0x7E6D, 0xC3B5, 0x7E6F, 0xF2B4, 0x7E70, 0xF2B2, 0x7E72, 0xF2B6, 0x7E73, 0xC3BA, 0x7E74, 0xF2B7, 0x7E75, 0xF2B0, - 0x7E76, 0xF2AF, 0x7E77, 0xF2B3, 0x7E78, 0xF2B1, 0x7E79, 0xC3B6, 0x7E7A, 0xF2B5, 0x7E7B, 0xF4AC, 0x7E7C, 0xC47E, 0x7E7D, 0xC47D, - 0x7E7E, 0xF4AD, 0x7E80, 0xF4AF, 0x7E81, 0xF4AE, 0x7E82, 0xC4A1, 0x7E86, 0xF5EB, 0x7E87, 0xF5E8, 0x7E88, 0xF5E9, 0x7E8A, 0xF5E7, - 0x7E8B, 0xF5EA, 0x7E8C, 0xC4F2, 0x7E8D, 0xF5EC, 0x7E8F, 0xC4F1, 0x7E91, 0xF742, 0x7E93, 0xC5D5, 0x7E94, 0xC5D7, 0x7E95, 0xF7EE, - 0x7E96, 0xC5D6, 0x7E97, 0xF8B9, 0x7E98, 0xF940, 0x7E99, 0xF942, 0x7E9A, 0xF8FE, 0x7E9B, 0xF941, 0x7E9C, 0xC66C, 0x7F36, 0xA6CE, - 0x7F38, 0xACFB, 0x7F39, 0xD26F, 0x7F3A, 0xAFCA, 0x7F3D, 0xB2DA, 0x7F3E, 0xDAFC, 0x7F3F, 0xDAFD, 0x7F43, 0xEADF, 0x7F44, 0xC16A, - 0x7F45, 0xEDE1, 0x7F48, 0xC2BB, 0x7F4A, 0xF2BA, 0x7F4B, 0xF2B9, 0x7F4C, 0xC4A2, 0x7F4D, 0xF5ED, 0x7F4F, 0xF743, 0x7F50, 0xC5F8, - 0x7F51, 0xCA49, 0x7F54, 0xAAC9, 0x7F55, 0xA875, 0x7F58, 0xD04D, 0x7F5B, 0xD360, 0x7F5C, 0xD35B, 0x7F5D, 0xD35F, 0x7F5E, 0xD35D, - 0x7F5F, 0xAFCB, 0x7F60, 0xD35E, 0x7F61, 0xD35C, 0x7F63, 0xD6F1, 0x7F65, 0xDAFE, 0x7F66, 0xDB40, 0x7F67, 0xDF69, 0x7F68, 0xDF6A, - 0x7F69, 0xB86E, 0x7F6A, 0xB86F, 0x7F6B, 0xDF68, 0x7F6C, 0xDF6B, 0x7F6D, 0xDF67, 0x7F6E, 0xB86D, 0x7F70, 0xBB40, 0x7F72, 0xB870, - 0x7F73, 0xE37A, 0x7F75, 0xBD7C, 0x7F76, 0xE6F1, 0x7F77, 0xBD7D, 0x7F79, 0xBFA9, 0x7F7A, 0xEAE2, 0x7F7B, 0xEAE0, 0x7F7C, 0xEAE1, - 0x7F7D, 0xEDE4, 0x7F7E, 0xEDE3, 0x7F7F, 0xEDE2, 0x7F83, 0xF2BB, 0x7F85, 0xC3B9, 0x7F86, 0xF2BC, 0x7F87, 0xF744, 0x7F88, 0xC5F9, - 0x7F89, 0xF8BA, 0x7F8A, 0xA6CF, 0x7F8B, 0xAACB, 0x7F8C, 0xAACA, 0x7F8D, 0xD04F, 0x7F8E, 0xACFC, 0x7F91, 0xD04E, 0x7F92, 0xD362, - 0x7F94, 0xAFCC, 0x7F95, 0xD6F2, 0x7F96, 0xD361, 0x7F9A, 0xB2DC, 0x7F9B, 0xD6F5, 0x7F9C, 0xD6F3, 0x7F9D, 0xD6F4, 0x7F9E, 0xB2DB, - 0x7FA0, 0xDB42, 0x7FA1, 0xDB43, 0x7FA2, 0xDB41, 0x7FA4, 0xB873, 0x7FA5, 0xDF6D, 0x7FA6, 0xDF6C, 0x7FA7, 0xDF6E, 0x7FA8, 0xB872, - 0x7FA9, 0xB871, 0x7FAC, 0xE6F2, 0x7FAD, 0xE6F4, 0x7FAF, 0xBD7E, 0x7FB0, 0xE6F3, 0x7FB1, 0xEAE3, 0x7FB2, 0xBFAA, 0x7FB3, 0xF079, - 0x7FB5, 0xF078, 0x7FB6, 0xC3BB, 0x7FB7, 0xF2BD, 0x7FB8, 0xC3BD, 0x7FB9, 0xC3BC, 0x7FBA, 0xF4B0, 0x7FBB, 0xF5EE, 0x7FBC, 0xC4F3, - 0x7FBD, 0xA6D0, 0x7FBE, 0xD050, 0x7FBF, 0xACFD, 0x7FC0, 0xD365, 0x7FC1, 0xAFCE, 0x7FC2, 0xD364, 0x7FC3, 0xD363, 0x7FC5, 0xAFCD, - 0x7FC7, 0xD6FB, 0x7FC9, 0xD6FD, 0x7FCA, 0xD6F6, 0x7FCB, 0xD6F7, 0x7FCC, 0xB2DD, 0x7FCD, 0xD6F8, 0x7FCE, 0xB2DE, 0x7FCF, 0xD6FC, - 0x7FD0, 0xD6F9, 0x7FD1, 0xD6FA, 0x7FD2, 0xB2DF, 0x7FD4, 0xB5BE, 0x7FD5, 0xB5BF, 0x7FD7, 0xDB44, 0x7FDB, 0xDF6F, 0x7FDC, 0xDF70, - 0x7FDE, 0xE37E, 0x7FDF, 0xBB43, 0x7FE0, 0xBB41, 0x7FE1, 0xBB42, 0x7FE2, 0xE37B, 0x7FE3, 0xE37C, 0x7FE5, 0xE37D, 0x7FE6, 0xE6F9, - 0x7FE8, 0xE6FA, 0x7FE9, 0xBDA1, 0x7FEA, 0xE6F7, 0x7FEB, 0xE6F6, 0x7FEC, 0xE6F8, 0x7FED, 0xE6F5, 0x7FEE, 0xBFAD, 0x7FEF, 0xEAE4, - 0x7FF0, 0xBFAB, 0x7FF1, 0xBFAC, 0x7FF2, 0xEDE6, 0x7FF3, 0xC16B, 0x7FF4, 0xEDE5, 0x7FF5, 0xEFA8, 0x7FF7, 0xF07A, 0x7FF8, 0xF07B, - 0x7FF9, 0xC2BC, 0x7FFB, 0xC2BD, 0x7FFC, 0xC16C, 0x7FFD, 0xF2BE, 0x7FFE, 0xF2BF, 0x7FFF, 0xF4B1, 0x8000, 0xC4A3, 0x8001, 0xA6D1, - 0x8003, 0xA6D2, 0x8004, 0xACFE, 0x8005, 0xAACC, 0x8006, 0xAFCF, 0x8007, 0xD051, 0x800B, 0xB5C0, 0x800C, 0xA6D3, 0x800D, 0xAD41, - 0x800E, 0xD052, 0x800F, 0xD053, 0x8010, 0xAD40, 0x8011, 0xAD42, 0x8012, 0xA6D4, 0x8014, 0xD054, 0x8015, 0xAFD1, 0x8016, 0xD366, - 0x8017, 0xAFD3, 0x8018, 0xAFD0, 0x8019, 0xAFD2, 0x801B, 0xD741, 0x801C, 0xB2E0, 0x801E, 0xD740, 0x801F, 0xD6FE, 0x8021, 0xDF71, - 0x8024, 0xE3A1, 0x8026, 0xBDA2, 0x8028, 0xBFAE, 0x8029, 0xEAE6, 0x802A, 0xEAE5, 0x802C, 0xEDE7, 0x8030, 0xF5EF, 0x8033, 0xA6D5, - 0x8034, 0xCB73, 0x8035, 0xCDAA, 0x8036, 0xAD43, 0x8037, 0xD055, 0x8039, 0xD368, 0x803D, 0xAFD4, 0x803E, 0xD367, 0x803F, 0xAFD5, - 0x8043, 0xD743, 0x8046, 0xB2E2, 0x8047, 0xD742, 0x8048, 0xD744, 0x804A, 0xB2E1, 0x804F, 0xDB46, 0x8050, 0xDB47, 0x8051, 0xDB45, - 0x8052, 0xB5C1, 0x8056, 0xB874, 0x8058, 0xB875, 0x805A, 0xBB45, 0x805C, 0xE3A3, 0x805D, 0xE3A2, 0x805E, 0xBB44, 0x8064, 0xE6FB, - 0x8067, 0xE6FC, 0x806C, 0xEAE7, 0x806F, 0xC170, 0x8070, 0xC16F, 0x8071, 0xC16D, 0x8072, 0xC16E, 0x8073, 0xC171, 0x8075, 0xF07C, - 0x8076, 0xC2BF, 0x8077, 0xC2BE, 0x8078, 0xF2C0, 0x8079, 0xF4B2, 0x807D, 0xC5A5, 0x807E, 0xC5A4, 0x807F, 0xA6D6, 0x8082, 0xD1FB, - 0x8084, 0xB877, 0x8085, 0xB5C2, 0x8086, 0xB876, 0x8087, 0xBB46, 0x8089, 0xA6D7, 0x808A, 0xC9A9, 0x808B, 0xA6D8, 0x808C, 0xA6D9, - 0x808F, 0xCDAB, 0x8090, 0xCB76, 0x8092, 0xCB77, 0x8093, 0xA877, 0x8095, 0xCB74, 0x8096, 0xA876, 0x8098, 0xA879, 0x8099, 0xCB75, - 0x809A, 0xA87B, 0x809B, 0xA87A, 0x809C, 0xCB78, 0x809D, 0xA878, 0x80A1, 0xAAD1, 0x80A2, 0xAACF, 0x80A3, 0xCDAD, 0x80A5, 0xAACE, - 0x80A9, 0xAAD3, 0x80AA, 0xAAD5, 0x80AB, 0xAAD2, 0x80AD, 0xCDB0, 0x80AE, 0xCDAC, 0x80AF, 0xAAD6, 0x80B1, 0xAAD0, 0x80B2, 0xA87C, - 0x80B4, 0xAAD4, 0x80B5, 0xCDAF, 0x80B8, 0xCDAE, 0x80BA, 0xAACD, 0x80C2, 0xD05B, 0x80C3, 0xAD47, 0x80C4, 0xAD48, 0x80C5, 0xD05D, - 0x80C7, 0xD057, 0x80C8, 0xD05A, 0x80C9, 0xD063, 0x80CA, 0xD061, 0x80CC, 0xAD49, 0x80CD, 0xD067, 0x80CE, 0xAD4C, 0x80CF, 0xD064, - 0x80D0, 0xD05C, 0x80D1, 0xD059, 0x80D4, 0xDB49, 0x80D5, 0xD062, 0x80D6, 0xAD44, 0x80D7, 0xD065, 0x80D8, 0xD056, 0x80D9, 0xD05F, - 0x80DA, 0xAD46, 0x80DB, 0xAD4B, 0x80DC, 0xD060, 0x80DD, 0xAD4F, 0x80DE, 0xAD4D, 0x80E0, 0xD058, 0x80E1, 0xAD4A, 0x80E3, 0xD05E, - 0x80E4, 0xAD4E, 0x80E5, 0xAD45, 0x80E6, 0xD066, 0x80ED, 0xAFDA, 0x80EF, 0xAFE3, 0x80F0, 0xAFD8, 0x80F1, 0xAFD6, 0x80F2, 0xD36A, - 0x80F3, 0xAFDE, 0x80F4, 0xAFDB, 0x80F5, 0xD36C, 0x80F8, 0xAFDD, 0x80F9, 0xD36B, 0x80FA, 0xD369, 0x80FB, 0xD36E, 0x80FC, 0xAFE2, - 0x80FD, 0xAFE0, 0x80FE, 0xDB48, 0x8100, 0xD36F, 0x8101, 0xD36D, 0x8102, 0xAFD7, 0x8105, 0xAFD9, 0x8106, 0xAFDC, 0x8108, 0xAFDF, - 0x810A, 0xAFE1, 0x8115, 0xD74E, 0x8116, 0xB2E4, 0x8118, 0xD745, 0x8119, 0xD747, 0x811B, 0xD748, 0x811D, 0xD750, 0x811E, 0xD74C, - 0x811F, 0xD74A, 0x8121, 0xD74D, 0x8122, 0xD751, 0x8123, 0xB2E5, 0x8124, 0xB2E9, 0x8125, 0xD746, 0x8127, 0xD74F, 0x8129, 0xB2E7, - 0x812B, 0xB2E6, 0x812C, 0xD74B, 0x812D, 0xD749, 0x812F, 0xB2E3, 0x8130, 0xB2E8, 0x8139, 0xB5C8, 0x813A, 0xDB51, 0x813D, 0xDB4F, - 0x813E, 0xB5CA, 0x8143, 0xDB4A, 0x8144, 0xDFA1, 0x8146, 0xB5C9, 0x8147, 0xDB4E, 0x814A, 0xDB4B, 0x814B, 0xB5C5, 0x814C, 0xB5CB, - 0x814D, 0xDB50, 0x814E, 0xB5C7, 0x814F, 0xDB4D, 0x8150, 0xBB47, 0x8151, 0xB5C6, 0x8152, 0xDB4C, 0x8153, 0xB5CC, 0x8154, 0xB5C4, - 0x8155, 0xB5C3, 0x815B, 0xDF77, 0x815C, 0xDF75, 0x815E, 0xDF7B, 0x8160, 0xDF73, 0x8161, 0xDFA2, 0x8162, 0xDF78, 0x8164, 0xDF72, - 0x8165, 0xB87B, 0x8166, 0xB8A3, 0x8167, 0xDF7D, 0x8169, 0xDF76, 0x816B, 0xB87E, 0x816E, 0xB87C, 0x816F, 0xDF7E, 0x8170, 0xB879, - 0x8171, 0xB878, 0x8172, 0xDF79, 0x8173, 0xB87D, 0x8174, 0xB5CD, 0x8176, 0xDF7C, 0x8177, 0xDF74, 0x8178, 0xB87A, 0x8179, 0xB8A1, - 0x817A, 0xB8A2, 0x817F, 0xBB4C, 0x8180, 0xBB48, 0x8182, 0xBB4D, 0x8183, 0xE3A6, 0x8186, 0xE3A5, 0x8187, 0xE3A7, 0x8188, 0xBB4A, - 0x8189, 0xE3A4, 0x818A, 0xBB4B, 0x818B, 0xE3AA, 0x818C, 0xE3A9, 0x818D, 0xE3A8, 0x818F, 0xBB49, 0x8195, 0xE741, 0x8197, 0xE744, - 0x8198, 0xBDA8, 0x8199, 0xE743, 0x819A, 0xBDA7, 0x819B, 0xBDA3, 0x819C, 0xBDA4, 0x819D, 0xBDA5, 0x819E, 0xE740, 0x819F, 0xE6FE, - 0x81A0, 0xBDA6, 0x81A2, 0xE742, 0x81A3, 0xE6FD, 0x81A6, 0xEAE9, 0x81A7, 0xEAF3, 0x81A8, 0xBFB1, 0x81A9, 0xBFB0, 0x81AB, 0xEAED, - 0x81AC, 0xEAEF, 0x81AE, 0xEAEA, 0x81B0, 0xEAEE, 0x81B1, 0xEAE8, 0x81B2, 0xEAF1, 0x81B3, 0xBFAF, 0x81B4, 0xEAF0, 0x81B5, 0xEAEC, - 0x81B7, 0xEAF2, 0x81B9, 0xEAEB, 0x81BA, 0xC174, 0x81BB, 0xEDE8, 0x81BC, 0xEDEE, 0x81BD, 0xC178, 0x81BE, 0xC17A, 0x81BF, 0xC177, - 0x81C0, 0xC176, 0x81C2, 0xC175, 0x81C3, 0xC173, 0x81C4, 0xEDE9, 0x81C5, 0xEDEC, 0x81C6, 0xC172, 0x81C7, 0xEDED, 0x81C9, 0xC179, - 0x81CA, 0xEDEB, 0x81CC, 0xEDEA, 0x81CD, 0xC2C0, 0x81CF, 0xC2C1, 0x81D0, 0xF0A1, 0x81D1, 0xF07D, 0x81D2, 0xF07E, 0x81D5, 0xF2C2, - 0x81D7, 0xF2C1, 0x81D8, 0xC3BE, 0x81D9, 0xF4B4, 0x81DA, 0xC4A4, 0x81DB, 0xF4B3, 0x81DD, 0xF5F0, 0x81DE, 0xF745, 0x81DF, 0xC5A6, - 0x81E0, 0xF943, 0x81E1, 0xF944, 0x81E2, 0xC5D8, 0x81E3, 0xA6DA, 0x81E5, 0xAAD7, 0x81E6, 0xDB52, 0x81E7, 0xBB4E, 0x81E8, 0xC17B, - 0x81E9, 0xEDEF, 0x81EA, 0xA6DB, 0x81EC, 0xAFE5, 0x81ED, 0xAFE4, 0x81EE, 0xDB53, 0x81F2, 0xEAF4, 0x81F3, 0xA6DC, 0x81F4, 0xAD50, - 0x81F7, 0xDB54, 0x81F8, 0xDB55, 0x81F9, 0xDB56, 0x81FA, 0xBB4F, 0x81FB, 0xBFB2, 0x81FC, 0xA6DD, 0x81FE, 0xAAD8, 0x81FF, 0xD068, - 0x8200, 0xAFE6, 0x8201, 0xD370, 0x8202, 0xB2EA, 0x8204, 0xDB57, 0x8205, 0xB8A4, 0x8207, 0xBB50, 0x8208, 0xBFB3, 0x8209, 0xC17C, - 0x820A, 0xC2C2, 0x820B, 0xF4B5, 0x820C, 0xA6DE, 0x820D, 0xAAD9, 0x8210, 0xAFE7, 0x8211, 0xD752, 0x8212, 0xB5CE, 0x8214, 0xBB51, - 0x8215, 0xE3AB, 0x8216, 0xE745, 0x821B, 0xA6DF, 0x821C, 0xB5CF, 0x821D, 0xDFA3, 0x821E, 0xBB52, 0x821F, 0xA6E0, 0x8220, 0xCDB1, - 0x8221, 0xD069, 0x8222, 0xAD51, 0x8225, 0xD372, 0x8228, 0xAFEA, 0x822A, 0xAFE8, 0x822B, 0xAFE9, 0x822C, 0xAFEB, 0x822F, 0xD371, - 0x8232, 0xD757, 0x8233, 0xD754, 0x8234, 0xD756, 0x8235, 0xB2EB, 0x8236, 0xB2ED, 0x8237, 0xB2EC, 0x8238, 0xD753, 0x8239, 0xB2EE, - 0x823A, 0xD755, 0x823C, 0xDB58, 0x823D, 0xDB59, 0x823F, 0xDB5A, 0x8240, 0xDFA6, 0x8242, 0xDFA7, 0x8244, 0xDFA5, 0x8245, 0xDFA8, - 0x8247, 0xB8A5, 0x8249, 0xDFA4, 0x824B, 0xBB53, 0x824E, 0xE74A, 0x824F, 0xE746, 0x8250, 0xE749, 0x8251, 0xE74B, 0x8252, 0xE748, - 0x8253, 0xE747, 0x8255, 0xEAF5, 0x8256, 0xEAF6, 0x8257, 0xEAF7, 0x8258, 0xBFB4, 0x8259, 0xBFB5, 0x825A, 0xEDF1, 0x825B, 0xEDF0, - 0x825C, 0xEDF2, 0x825E, 0xF0A3, 0x825F, 0xF0A2, 0x8261, 0xF2C4, 0x8263, 0xF2C5, 0x8264, 0xF2C3, 0x8266, 0xC4A5, 0x8268, 0xF4B6, - 0x8269, 0xF4B7, 0x826B, 0xF746, 0x826C, 0xF7EF, 0x826D, 0xF8BB, 0x826E, 0xA6E1, 0x826F, 0xA87D, 0x8271, 0xC17D, 0x8272, 0xA6E2, - 0x8274, 0xD758, 0x8275, 0xDB5B, 0x8277, 0xC641, 0x8278, 0xCA4A, 0x827C, 0xCA4B, 0x827D, 0xCA4D, 0x827E, 0xA6E3, 0x827F, 0xCA4E, - 0x8280, 0xCA4C, 0x8283, 0xCBA2, 0x8284, 0xCBA3, 0x8285, 0xCB7B, 0x828A, 0xCBA1, 0x828B, 0xA8A1, 0x828D, 0xA8A2, 0x828E, 0xCB7C, - 0x828F, 0xCB7A, 0x8290, 0xCB79, 0x8291, 0xCB7D, 0x8292, 0xA87E, 0x8293, 0xCB7E, 0x8294, 0xD06A, 0x8298, 0xCDB6, 0x8299, 0xAADC, - 0x829A, 0xCDB5, 0x829B, 0xCDB7, 0x829D, 0xAADB, 0x829E, 0xCDBC, 0x829F, 0xAADF, 0x82A0, 0xCDB2, 0x82A1, 0xCDC0, 0x82A2, 0xCDC6, - 0x82A3, 0xAAE6, 0x82A4, 0xCDC3, 0x82A5, 0xAAE3, 0x82A7, 0xCDB9, 0x82A8, 0xCDBF, 0x82A9, 0xCDC1, 0x82AB, 0xCDB4, 0x82AC, 0xAAE2, - 0x82AD, 0xAADD, 0x82AE, 0xCDBA, 0x82AF, 0xAAE4, 0x82B0, 0xAAE7, 0x82B1, 0xAAE1, 0x82B3, 0xAADA, 0x82B4, 0xCDBE, 0x82B5, 0xCDB8, - 0x82B6, 0xCDC5, 0x82B7, 0xAAE9, 0x82B8, 0xAAE5, 0x82B9, 0xAAE0, 0x82BA, 0xCDBD, 0x82BB, 0xAFEC, 0x82BC, 0xCDBB, 0x82BD, 0xAADE, - 0x82BE, 0xAAE8, 0x82C0, 0xCDB3, 0x82C2, 0xCDC2, 0x82C3, 0xCDC4, 0x82D1, 0xAD62, 0x82D2, 0xAD5C, 0x82D3, 0xAD64, 0x82D4, 0xAD61, - 0x82D5, 0xD071, 0x82D6, 0xD074, 0x82D7, 0xAD5D, 0x82D9, 0xD06B, 0x82DB, 0xAD56, 0x82DC, 0xAD60, 0x82DE, 0xAD63, 0x82DF, 0xAD65, - 0x82E0, 0xD0A2, 0x82E1, 0xD077, 0x82E3, 0xAD55, 0x82E4, 0xD0A1, 0x82E5, 0xAD59, 0x82E6, 0xAD57, 0x82E7, 0xAD52, 0x82E8, 0xD06F, - 0x82EA, 0xD07E, 0x82EB, 0xD073, 0x82EC, 0xD076, 0x82ED, 0xD0A5, 0x82EF, 0xAD66, 0x82F0, 0xD07D, 0x82F1, 0xAD5E, 0x82F2, 0xD078, - 0x82F3, 0xD0A4, 0x82F4, 0xD075, 0x82F5, 0xD079, 0x82F6, 0xD07C, 0x82F9, 0xD06D, 0x82FA, 0xD0A3, 0x82FB, 0xD07B, 0x82FE, 0xD06C, - 0x8300, 0xD070, 0x8301, 0xAD5F, 0x8302, 0xAD5A, 0x8303, 0xAD53, 0x8304, 0xAD58, 0x8305, 0xAD54, 0x8306, 0xAD67, 0x8307, 0xD06E, - 0x8308, 0xD3A5, 0x8309, 0xAD5B, 0x830C, 0xD07A, 0x830D, 0xCE41, 0x8316, 0xD3A8, 0x8317, 0xAFFA, 0x8319, 0xD376, 0x831B, 0xD3A3, - 0x831C, 0xD37D, 0x831E, 0xD3B2, 0x8320, 0xD3AA, 0x8322, 0xD37E, 0x8324, 0xD3A9, 0x8325, 0xD378, 0x8326, 0xD37C, 0x8327, 0xD3B5, - 0x8328, 0xAFFD, 0x8329, 0xD3AD, 0x832A, 0xD3A4, 0x832B, 0xAFED, 0x832C, 0xD3B3, 0x832D, 0xD374, 0x832F, 0xD3AC, 0x8331, 0xAFFC, - 0x8332, 0xAFF7, 0x8333, 0xD373, 0x8334, 0xAFF5, 0x8335, 0xAFF4, 0x8336, 0xAFF9, 0x8337, 0xD3AB, 0x8338, 0xAFF1, 0x8339, 0xAFF8, - 0x833A, 0xD072, 0x833B, 0xDB5C, 0x833C, 0xD3A6, 0x833F, 0xD37A, 0x8340, 0xAFFB, 0x8341, 0xD37B, 0x8342, 0xD3A1, 0x8343, 0xAFFE, - 0x8344, 0xD375, 0x8345, 0xD3AF, 0x8347, 0xD3AE, 0x8348, 0xD3B6, 0x8349, 0xAFF3, 0x834A, 0xAFF0, 0x834B, 0xD3B4, 0x834C, 0xD3B0, - 0x834D, 0xD3A7, 0x834E, 0xD3A2, 0x834F, 0xAFF6, 0x8350, 0xAFF2, 0x8351, 0xD377, 0x8352, 0xAFEE, 0x8353, 0xD3B1, 0x8354, 0xAFEF, - 0x8356, 0xD379, 0x8373, 0xD75E, 0x8374, 0xD760, 0x8375, 0xD765, 0x8376, 0xD779, 0x8377, 0xB2FC, 0x8378, 0xB2F2, 0x837A, 0xD75D, - 0x837B, 0xB2FD, 0x837C, 0xB2FE, 0x837D, 0xD768, 0x837E, 0xD76F, 0x837F, 0xD775, 0x8381, 0xD762, 0x8383, 0xD769, 0x8386, 0xB340, - 0x8387, 0xD777, 0x8388, 0xD772, 0x8389, 0xB2FA, 0x838A, 0xB2F8, 0x838B, 0xD76E, 0x838C, 0xD76A, 0x838D, 0xD75C, 0x838E, 0xB2EF, - 0x838F, 0xD761, 0x8390, 0xD759, 0x8392, 0xB2F7, 0x8393, 0xB2F9, 0x8394, 0xD766, 0x8395, 0xD763, 0x8396, 0xB2F4, 0x8397, 0xD773, - 0x8398, 0xB2F1, 0x8399, 0xD764, 0x839A, 0xD77A, 0x839B, 0xD76C, 0x839D, 0xD76B, 0x839E, 0xB2F0, 0x83A0, 0xB2FB, 0x83A2, 0xB2F3, - 0x83A3, 0xD75A, 0x83A4, 0xD75F, 0x83A5, 0xD770, 0x83A6, 0xD776, 0x83A7, 0xB341, 0x83A8, 0xD75B, 0x83A9, 0xD767, 0x83AA, 0xD76D, - 0x83AB, 0xB2F6, 0x83AE, 0xD778, 0x83AF, 0xD771, 0x83B0, 0xD774, 0x83BD, 0xB2F5, 0x83BF, 0xDB6C, 0x83C0, 0xDB60, 0x83C1, 0xB5D7, - 0x83C2, 0xDB7D, 0x83C3, 0xDBA7, 0x83C4, 0xDBAA, 0x83C5, 0xB5D5, 0x83C6, 0xDB68, 0x83C7, 0xDBA3, 0x83C8, 0xDB69, 0x83C9, 0xDB77, - 0x83CA, 0xB5E2, 0x83CB, 0xDB73, 0x83CC, 0xB5DF, 0x83CE, 0xDB74, 0x83CF, 0xDB5D, 0x83D1, 0xDBA4, 0x83D4, 0xB5E8, 0x83D5, 0xDBA1, - 0x83D6, 0xDB75, 0x83D7, 0xDBAC, 0x83D8, 0xDB70, 0x83D9, 0xDFC8, 0x83DB, 0xDBAF, 0x83DC, 0xB5E6, 0x83DD, 0xDB6E, 0x83DE, 0xDB7A, - 0x83DF, 0xB5E9, 0x83E0, 0xB5D4, 0x83E1, 0xDB72, 0x83E2, 0xDBAD, 0x83E3, 0xDB6B, 0x83E4, 0xDB64, 0x83E5, 0xDB6F, 0x83E7, 0xDB63, - 0x83E8, 0xDB61, 0x83E9, 0xB5D0, 0x83EA, 0xDBA5, 0x83EB, 0xDB6A, 0x83EC, 0xDBA8, 0x83EE, 0xDBA9, 0x83EF, 0xB5D8, 0x83F0, 0xB5DD, - 0x83F1, 0xB5D9, 0x83F2, 0xB5E1, 0x83F3, 0xDB7E, 0x83F4, 0xB5DA, 0x83F5, 0xDB76, 0x83F6, 0xDB66, 0x83F8, 0xB5D2, 0x83F9, 0xDB5E, - 0x83FA, 0xDBA2, 0x83FB, 0xDBAB, 0x83FC, 0xDB65, 0x83FD, 0xB5E0, 0x83FE, 0xDBB0, 0x83FF, 0xDB71, 0x8401, 0xDB6D, 0x8403, 0xB5D1, - 0x8404, 0xB5E5, 0x8406, 0xDB7C, 0x8407, 0xB5E7, 0x8409, 0xDB78, 0x840A, 0xB5DC, 0x840B, 0xB5D6, 0x840C, 0xB5DE, 0x840D, 0xB5D3, - 0x840E, 0xB5E4, 0x840F, 0xDB79, 0x8410, 0xDB67, 0x8411, 0xDB7B, 0x8412, 0xDB62, 0x8413, 0xDBA6, 0x841B, 0xDBAE, 0x8423, 0xDB5F, - 0x8429, 0xDFC7, 0x842B, 0xDFDD, 0x842C, 0xB855, 0x842D, 0xDFCC, 0x842F, 0xDFCA, 0x8430, 0xDFB5, 0x8431, 0xB8A9, 0x8432, 0xDFC5, - 0x8433, 0xDFD9, 0x8434, 0xDFC1, 0x8435, 0xB8B1, 0x8436, 0xDFD8, 0x8437, 0xDFBF, 0x8438, 0xB5E3, 0x8439, 0xDFCF, 0x843A, 0xDFC0, - 0x843B, 0xDFD6, 0x843C, 0xB8B0, 0x843D, 0xB8A8, 0x843F, 0xDFAA, 0x8440, 0xDFB2, 0x8442, 0xDFCB, 0x8443, 0xDFC3, 0x8444, 0xDFDC, - 0x8445, 0xDFC6, 0x8446, 0xB8B6, 0x8447, 0xDFD7, 0x8449, 0xB8AD, 0x844B, 0xDFC9, 0x844C, 0xDFD1, 0x844D, 0xDFB6, 0x844E, 0xDFD0, - 0x8450, 0xDFE1, 0x8451, 0xDFB1, 0x8452, 0xDFD2, 0x8454, 0xDFDF, 0x8456, 0xDFAB, 0x8457, 0xB5DB, 0x8459, 0xDFB9, 0x845A, 0xDFB8, - 0x845B, 0xB8AF, 0x845D, 0xDFBC, 0x845E, 0xDFBE, 0x845F, 0xDFCD, 0x8460, 0xDFDE, 0x8461, 0xB8B2, 0x8463, 0xB8B3, 0x8465, 0xDFB0, - 0x8466, 0xB8AB, 0x8467, 0xDFB4, 0x8468, 0xDFDA, 0x8469, 0xB8B4, 0x846B, 0xB8AC, 0x846C, 0xB8AE, 0x846D, 0xB8B5, 0x846E, 0xDFE0, - 0x846F, 0xDFD3, 0x8470, 0xDFCE, 0x8473, 0xDFBB, 0x8474, 0xDFBA, 0x8475, 0xB8AA, 0x8476, 0xDFAC, 0x8477, 0xB8A7, 0x8478, 0xDFC4, - 0x8479, 0xDFAD, 0x847A, 0xDFC2, 0x847D, 0xDFB7, 0x847E, 0xDFDB, 0x8482, 0xB8A6, 0x8486, 0xDFB3, 0x848D, 0xDFAF, 0x848E, 0xDFD5, - 0x848F, 0xDFAE, 0x8490, 0xBB60, 0x8491, 0xE3D3, 0x8494, 0xE3C2, 0x8497, 0xE3AC, 0x8498, 0xE3CA, 0x8499, 0xBB58, 0x849A, 0xE3BB, - 0x849B, 0xE3C5, 0x849C, 0xBB5B, 0x849D, 0xE3BE, 0x849E, 0xBB59, 0x849F, 0xE3AF, 0x84A0, 0xE3CD, 0x84A1, 0xE3AE, 0x84A2, 0xE3C1, - 0x84A4, 0xE3AD, 0x84A7, 0xE3BF, 0x84A8, 0xE3C8, 0x84A9, 0xE3C6, 0x84AA, 0xE3BA, 0x84AB, 0xE3B5, 0x84AC, 0xE3B3, 0x84AE, 0xE3B4, - 0x84AF, 0xE3C7, 0x84B0, 0xE3D2, 0x84B1, 0xE3BC, 0x84B2, 0xBB5A, 0x84B4, 0xE3B7, 0x84B6, 0xE3CB, 0x84B8, 0xBB5D, 0x84B9, 0xE3B6, - 0x84BA, 0xE3B0, 0x84BB, 0xE3C0, 0x84BC, 0xBB61, 0x84BF, 0xBB55, 0x84C0, 0xBB5E, 0x84C1, 0xE3B8, 0x84C2, 0xE3B2, 0x84C4, 0xBB57, - 0x84C5, 0xDFD4, 0x84C6, 0xBB56, 0x84C7, 0xE3C3, 0x84C9, 0xBB54, 0x84CA, 0xBB63, 0x84CB, 0xBB5C, 0x84CC, 0xE3C4, 0x84CD, 0xE3B9, - 0x84CE, 0xE3B1, 0x84CF, 0xE3CC, 0x84D0, 0xE3BD, 0x84D1, 0xBB62, 0x84D2, 0xE3D0, 0x84D3, 0xBB5F, 0x84D4, 0xE3CF, 0x84D6, 0xE3C9, - 0x84D7, 0xE3CE, 0x84DB, 0xE3D1, 0x84E7, 0xE773, 0x84E8, 0xE774, 0x84E9, 0xE767, 0x84EA, 0xE766, 0x84EB, 0xE762, 0x84EC, 0xBDB4, - 0x84EE, 0xBDAC, 0x84EF, 0xE776, 0x84F0, 0xE775, 0x84F1, 0xDFA9, 0x84F2, 0xE75F, 0x84F3, 0xE763, 0x84F4, 0xE75D, 0x84F6, 0xE770, - 0x84F7, 0xE761, 0x84F9, 0xE777, 0x84FA, 0xE75A, 0x84FB, 0xE758, 0x84FC, 0xE764, 0x84FD, 0xE76E, 0x84FE, 0xE769, 0x84FF, 0xBDB6, - 0x8500, 0xE74F, 0x8502, 0xE76D, 0x8506, 0xBDB7, 0x8507, 0xDFBD, 0x8508, 0xE75B, 0x8509, 0xE752, 0x850A, 0xE755, 0x850B, 0xE77B, - 0x850C, 0xE75C, 0x850D, 0xE753, 0x850E, 0xE751, 0x850F, 0xE74E, 0x8511, 0xBDB0, 0x8512, 0xE765, 0x8513, 0xBDAF, 0x8514, 0xBDB3, - 0x8515, 0xE760, 0x8516, 0xE768, 0x8517, 0xBDA9, 0x8518, 0xE778, 0x8519, 0xE77C, 0x851A, 0xBDAB, 0x851C, 0xE757, 0x851D, 0xE76B, - 0x851E, 0xE76F, 0x851F, 0xE754, 0x8520, 0xE779, 0x8521, 0xBDB2, 0x8523, 0xBDB1, 0x8524, 0xE74C, 0x8525, 0xBDB5, 0x8526, 0xE772, - 0x8527, 0xE756, 0x8528, 0xE76A, 0x8529, 0xE750, 0x852A, 0xE75E, 0x852B, 0xE759, 0x852C, 0xBDAD, 0x852D, 0xBDAE, 0x852E, 0xE76C, - 0x852F, 0xE77D, 0x8530, 0xE77A, 0x8531, 0xE771, 0x853B, 0xE74D, 0x853D, 0xBDAA, 0x853E, 0xEB49, 0x8540, 0xEB40, 0x8541, 0xEB43, - 0x8543, 0xBFBB, 0x8544, 0xEB45, 0x8545, 0xEAF9, 0x8546, 0xEB41, 0x8547, 0xEB47, 0x8548, 0xBFB8, 0x8549, 0xBFBC, 0x854A, 0xBFB6, - 0x854D, 0xEAFB, 0x854E, 0xEB4C, 0x8551, 0xEB46, 0x8553, 0xEAFC, 0x8554, 0xEB55, 0x8555, 0xEB4F, 0x8556, 0xEAF8, 0x8557, 0xEE46, - 0x8558, 0xEAFE, 0x8559, 0xBFB7, 0x855B, 0xEB4A, 0x855D, 0xEB54, 0x855E, 0xBFBF, 0x8560, 0xEB51, 0x8561, 0xEAFD, 0x8562, 0xEB44, - 0x8563, 0xEB48, 0x8564, 0xEB42, 0x8565, 0xEB56, 0x8566, 0xEB53, 0x8567, 0xEB50, 0x8568, 0xBFB9, 0x8569, 0xBFBA, 0x856A, 0xBFBE, - 0x856B, 0xEAFA, 0x856C, 0xEB57, 0x856D, 0xBFBD, 0x856E, 0xEB4D, 0x8571, 0xEB4B, 0x8575, 0xEB4E, 0x8576, 0xEE53, 0x8577, 0xEE40, - 0x8578, 0xEE45, 0x8579, 0xEE52, 0x857A, 0xEE44, 0x857B, 0xEDFB, 0x857C, 0xEE41, 0x857E, 0xC1A2, 0x8580, 0xEDF4, 0x8581, 0xEE4D, - 0x8582, 0xEE4F, 0x8583, 0xEDF3, 0x8584, 0xC1A1, 0x8585, 0xEE51, 0x8586, 0xEE49, 0x8587, 0xC1A8, 0x8588, 0xEE50, 0x8589, 0xEE42, - 0x858A, 0xC1AA, 0x858B, 0xEDF9, 0x858C, 0xEB52, 0x858D, 0xEE4A, 0x858E, 0xEE47, 0x858F, 0xEDF5, 0x8590, 0xEE55, 0x8591, 0xC1A4, - 0x8594, 0xC1A5, 0x8595, 0xEDF7, 0x8596, 0xEE48, 0x8598, 0xEE54, 0x8599, 0xEE4B, 0x859A, 0xEDFD, 0x859B, 0xC1A7, 0x859C, 0xC1A3, - 0x859D, 0xEE4C, 0x859E, 0xEDFE, 0x859F, 0xEE56, 0x85A0, 0xEDF8, 0x85A1, 0xEE43, 0x85A2, 0xEE4E, 0x85A3, 0xEDFA, 0x85A4, 0xEDFC, - 0x85A6, 0xC2CB, 0x85A7, 0xEDF6, 0x85A8, 0xC1A9, 0x85A9, 0xC2C4, 0x85AA, 0xC17E, 0x85AF, 0xC1A6, 0x85B0, 0xC2C8, 0x85B1, 0xF0B3, - 0x85B3, 0xF0A9, 0x85B4, 0xF0A4, 0x85B5, 0xF0AA, 0x85B6, 0xF0B4, 0x85B7, 0xF0B8, 0x85B8, 0xF0B7, 0x85B9, 0xC2CA, 0x85BA, 0xC2C9, - 0x85BD, 0xF0AB, 0x85BE, 0xF0B9, 0x85BF, 0xF0AE, 0x85C0, 0xF0A6, 0x85C2, 0xF0A8, 0x85C3, 0xF0A7, 0x85C4, 0xF0AD, 0x85C5, 0xF0B2, - 0x85C6, 0xF0A5, 0x85C7, 0xF0AC, 0x85C8, 0xF0B1, 0x85C9, 0xC2C7, 0x85CB, 0xF0AF, 0x85CD, 0xC2C5, 0x85CE, 0xF0B0, 0x85CF, 0xC2C3, - 0x85D0, 0xC2C6, 0x85D1, 0xF2D5, 0x85D2, 0xF0B5, 0x85D5, 0xC3C2, 0x85D7, 0xF2CD, 0x85D8, 0xF2D1, 0x85D9, 0xF2C9, 0x85DA, 0xF2CC, - 0x85DC, 0xF2D4, 0x85DD, 0xC3C0, 0x85DE, 0xF2D9, 0x85DF, 0xF2D2, 0x85E1, 0xF2CA, 0x85E2, 0xF2DA, 0x85E3, 0xF2D3, 0x85E4, 0xC3C3, - 0x85E5, 0xC3C4, 0x85E6, 0xF2D7, 0x85E8, 0xF2CB, 0x85E9, 0xC3BF, 0x85EA, 0xC3C1, 0x85EB, 0xF2C6, 0x85EC, 0xF2CE, 0x85ED, 0xF2C8, - 0x85EF, 0xF2D8, 0x85F0, 0xF2D6, 0x85F1, 0xF2C7, 0x85F2, 0xF2CF, 0x85F6, 0xF4BE, 0x85F7, 0xC3C5, 0x85F8, 0xF2D0, 0x85F9, 0xC4A7, - 0x85FA, 0xC4A9, 0x85FB, 0xC4A6, 0x85FD, 0xF4C3, 0x85FE, 0xF4BB, 0x85FF, 0xF4B9, 0x8600, 0xF4BD, 0x8601, 0xF4BA, 0x8604, 0xF4BF, - 0x8605, 0xF4C1, 0x8606, 0xC4AA, 0x8607, 0xC4AC, 0x8609, 0xF4C0, 0x860A, 0xC4AD, 0x860B, 0xC4AB, 0x860C, 0xF4C2, 0x8611, 0xC4A8, - 0x8617, 0xC4F4, 0x8618, 0xF5F1, 0x8619, 0xF5F7, 0x861A, 0xC4F6, 0x861B, 0xF4BC, 0x861C, 0xF5F6, 0x861E, 0xF5FD, 0x861F, 0xF5F4, - 0x8620, 0xF5FB, 0x8621, 0xF5FA, 0x8622, 0xF4B8, 0x8623, 0xF5F5, 0x8624, 0xF0B6, 0x8625, 0xF5FE, 0x8626, 0xF5F3, 0x8627, 0xF5F8, - 0x8629, 0xF5FC, 0x862A, 0xF5F2, 0x862C, 0xF74A, 0x862D, 0xC4F5, 0x862E, 0xF5F9, 0x8631, 0xF7F4, 0x8632, 0xF74B, 0x8633, 0xF749, - 0x8634, 0xF747, 0x8635, 0xF748, 0x8636, 0xF74C, 0x8638, 0xC5D9, 0x8639, 0xF7F2, 0x863A, 0xF7F0, 0x863B, 0xF7F5, 0x863C, 0xF7F3, - 0x863E, 0xF7F6, 0x863F, 0xC5DA, 0x8640, 0xF7F1, 0x8643, 0xF8BC, 0x8646, 0xF945, 0x8647, 0xF946, 0x8648, 0xF947, 0x864B, 0xF9C7, - 0x864C, 0xF9BD, 0x864D, 0xCA4F, 0x864E, 0xAAEA, 0x8650, 0xAD68, 0x8652, 0xD3B8, 0x8653, 0xD3B7, 0x8654, 0xB040, 0x8655, 0xB342, - 0x8656, 0xD77C, 0x8659, 0xD77B, 0x865B, 0xB5EA, 0x865C, 0xB8B8, 0x865E, 0xB8B7, 0x865F, 0xB8B9, 0x8661, 0xE3D4, 0x8662, 0xE77E, - 0x8663, 0xEB58, 0x8664, 0xEB5A, 0x8665, 0xEB59, 0x8667, 0xC1AB, 0x8668, 0xEE57, 0x8669, 0xF0BA, 0x866A, 0xF9A5, 0x866B, 0xA6E4, - 0x866D, 0xCDC9, 0x866E, 0xCDCA, 0x866F, 0xCDC8, 0x8670, 0xCDC7, 0x8671, 0xAAEB, 0x8673, 0xD0A9, 0x8674, 0xD0A7, 0x8677, 0xD0A6, - 0x8679, 0xAD69, 0x867A, 0xAD6B, 0x867B, 0xAD6A, 0x867C, 0xD0A8, 0x8685, 0xD3C4, 0x8686, 0xD3C1, 0x8687, 0xD3BF, 0x868A, 0xB041, - 0x868B, 0xD3C2, 0x868C, 0xB046, 0x868D, 0xD3BC, 0x868E, 0xD3CB, 0x8690, 0xD3CD, 0x8691, 0xD3BD, 0x8693, 0xB043, 0x8694, 0xD3CE, - 0x8695, 0xD3C9, 0x8696, 0xD3BB, 0x8697, 0xD3C0, 0x8698, 0xD3CA, 0x8699, 0xD3C6, 0x869A, 0xD3C3, 0x869C, 0xB048, 0x869D, 0xD3CC, - 0x869E, 0xD3BE, 0x86A1, 0xD3C7, 0x86A2, 0xD3B9, 0x86A3, 0xB047, 0x86A4, 0xB044, 0x86A5, 0xD3C5, 0x86A7, 0xD3C8, 0x86A8, 0xD3BA, - 0x86A9, 0xB045, 0x86AA, 0xB042, 0x86AF, 0xB34C, 0x86B0, 0xD7A5, 0x86B1, 0xB34B, 0x86B3, 0xD7A8, 0x86B4, 0xD7AB, 0x86B5, 0xB348, - 0x86B6, 0xB346, 0x86B7, 0xD77E, 0x86B8, 0xD7A9, 0x86B9, 0xD7A7, 0x86BA, 0xD7A4, 0x86BB, 0xD7AC, 0x86BC, 0xD7AD, 0x86BD, 0xD7AF, - 0x86BE, 0xD7B0, 0x86BF, 0xD77D, 0x86C0, 0xB345, 0x86C1, 0xD7A2, 0x86C2, 0xD7A1, 0x86C3, 0xD7AE, 0x86C4, 0xB347, 0x86C5, 0xD7A3, - 0x86C6, 0xB349, 0x86C7, 0xB344, 0x86C8, 0xD7A6, 0x86C9, 0xB34D, 0x86CB, 0xB34A, 0x86CC, 0xD7AA, 0x86D0, 0xB5F1, 0x86D1, 0xDBBF, - 0x86D3, 0xDBB4, 0x86D4, 0xB5EE, 0x86D6, 0xDFE7, 0x86D7, 0xDBBD, 0x86D8, 0xDBB1, 0x86D9, 0xB5EC, 0x86DA, 0xDBB6, 0x86DB, 0xB5EF, - 0x86DC, 0xDBBA, 0x86DD, 0xDBB8, 0x86DE, 0xB5F2, 0x86DF, 0xB5EB, 0x86E2, 0xDBB2, 0x86E3, 0xDBB5, 0x86E4, 0xB5F0, 0x86E6, 0xDBB3, - 0x86E8, 0xDBBE, 0x86E9, 0xDBBC, 0x86EA, 0xDBB7, 0x86EB, 0xDBB9, 0x86EC, 0xDBBB, 0x86ED, 0xB5ED, 0x86F5, 0xDFE8, 0x86F6, 0xDFEE, - 0x86F7, 0xDFE4, 0x86F8, 0xDFEA, 0x86F9, 0xB8BA, 0x86FA, 0xDFE6, 0x86FB, 0xB8C0, 0x86FE, 0xB8BF, 0x8700, 0xB8BE, 0x8701, 0xDFED, - 0x8702, 0xB8C1, 0x8703, 0xB8C2, 0x8704, 0xDFE3, 0x8705, 0xDFF0, 0x8706, 0xB8C3, 0x8707, 0xB8BD, 0x8708, 0xB8BC, 0x8709, 0xDFEC, - 0x870A, 0xB8C4, 0x870B, 0xDFE2, 0x870C, 0xDFE5, 0x870D, 0xDFEF, 0x870E, 0xDFEB, 0x8711, 0xE3F4, 0x8712, 0xE3E9, 0x8713, 0xB8BB, - 0x8718, 0xBB6A, 0x8719, 0xE3DD, 0x871A, 0xE3F2, 0x871B, 0xE3DE, 0x871C, 0xBB65, 0x871E, 0xE3DB, 0x8720, 0xE3E4, 0x8721, 0xE3DC, - 0x8722, 0xBB67, 0x8723, 0xE3D6, 0x8724, 0xE3F1, 0x8725, 0xBB68, 0x8726, 0xE3EE, 0x8727, 0xE3EF, 0x8728, 0xE3D7, 0x8729, 0xBB6D, - 0x872A, 0xE3E6, 0x872C, 0xE3E0, 0x872D, 0xE3E7, 0x872E, 0xE3DA, 0x8730, 0xE3F3, 0x8731, 0xE3EB, 0x8732, 0xE3E5, 0x8733, 0xE3D5, - 0x8734, 0xBB69, 0x8735, 0xE3EC, 0x8737, 0xBB6C, 0x8738, 0xE3F0, 0x873A, 0xE3EA, 0x873B, 0xBB66, 0x873C, 0xE3E8, 0x873E, 0xE3E2, - 0x873F, 0xBB64, 0x8740, 0xE3D9, 0x8741, 0xE3E1, 0x8742, 0xE3ED, 0x8743, 0xE3DF, 0x8746, 0xE3E3, 0x874C, 0xBDC1, 0x874D, 0xDFE9, - 0x874E, 0xE7B2, 0x874F, 0xE7BB, 0x8750, 0xE7B1, 0x8751, 0xE7AD, 0x8752, 0xE7AA, 0x8753, 0xBDC2, 0x8754, 0xE7A8, 0x8755, 0xBB6B, - 0x8756, 0xE7A1, 0x8757, 0xBDC0, 0x8758, 0xE7A7, 0x8759, 0xBDBF, 0x875A, 0xE7AC, 0x875B, 0xE7A9, 0x875C, 0xE7B9, 0x875D, 0xE7B4, - 0x875E, 0xE7AE, 0x875F, 0xE7B3, 0x8760, 0xBDBB, 0x8761, 0xE7AB, 0x8762, 0xE7BE, 0x8763, 0xE7A2, 0x8764, 0xE7A3, 0x8765, 0xE7BA, - 0x8766, 0xBDBC, 0x8767, 0xE7BF, 0x8768, 0xBDBE, 0x8769, 0xE7C0, 0x876A, 0xE7B0, 0x876B, 0xE3D8, 0x876C, 0xE7B6, 0x876D, 0xE7AF, - 0x876E, 0xE7B8, 0x876F, 0xE7B5, 0x8773, 0xE7A6, 0x8774, 0xBDB9, 0x8775, 0xE7BD, 0x8776, 0xBDBA, 0x8777, 0xE7A4, 0x8778, 0xBDBD, - 0x8779, 0xEB64, 0x877A, 0xE7B7, 0x877B, 0xE7BC, 0x8781, 0xEB61, 0x8782, 0xBDB8, 0x8783, 0xBFC0, 0x8784, 0xEB6B, 0x8785, 0xEB67, - 0x8787, 0xEB65, 0x8788, 0xEB60, 0x8789, 0xEB6F, 0x878D, 0xBFC4, 0x878F, 0xEB5C, 0x8790, 0xEB68, 0x8791, 0xEB69, 0x8792, 0xEB5F, - 0x8793, 0xEB5E, 0x8794, 0xEB6C, 0x8796, 0xEB62, 0x8797, 0xEB5D, 0x8798, 0xEB63, 0x879A, 0xEB6E, 0x879B, 0xEB5B, 0x879C, 0xEB6D, - 0x879D, 0xEB6A, 0x879E, 0xBFC2, 0x879F, 0xBFC1, 0x87A2, 0xBFC3, 0x87A3, 0xEB66, 0x87A4, 0xF0CB, 0x87AA, 0xEE59, 0x87AB, 0xC1B1, - 0x87AC, 0xEE5D, 0x87AD, 0xEE5A, 0x87AE, 0xEE61, 0x87AF, 0xEE67, 0x87B0, 0xEE5C, 0x87B2, 0xEE70, 0x87B3, 0xC1AE, 0x87B4, 0xEE6A, - 0x87B5, 0xEE5F, 0x87B6, 0xEE6B, 0x87B7, 0xEE66, 0x87B8, 0xEE6D, 0x87B9, 0xEE5E, 0x87BA, 0xC1B3, 0x87BB, 0xC1B2, 0x87BC, 0xEE60, - 0x87BD, 0xEE6E, 0x87BE, 0xEE58, 0x87BF, 0xEE6C, 0x87C0, 0xC1AC, 0x87C2, 0xEE64, 0x87C3, 0xEE63, 0x87C4, 0xEE68, 0x87C5, 0xEE5B, - 0x87C6, 0xC1B0, 0x87C8, 0xC1B4, 0x87C9, 0xEE62, 0x87CA, 0xEE69, 0x87CB, 0xC1B5, 0x87CC, 0xEE65, 0x87D1, 0xC1AD, 0x87D2, 0xC1AF, - 0x87D3, 0xF0C7, 0x87D4, 0xF0C5, 0x87D7, 0xF0CC, 0x87D8, 0xF0C9, 0x87D9, 0xF0CD, 0x87DB, 0xF0BE, 0x87DC, 0xF0C6, 0x87DD, 0xF0D1, - 0x87DE, 0xEE6F, 0x87DF, 0xF0C2, 0x87E0, 0xC2CF, 0x87E1, 0xE7A5, 0x87E2, 0xF0BD, 0x87E3, 0xF0CA, 0x87E4, 0xF0C4, 0x87E5, 0xF0C1, - 0x87E6, 0xF0BC, 0x87E7, 0xF0BB, 0x87E8, 0xF0D0, 0x87EA, 0xF0C0, 0x87EB, 0xF0BF, 0x87EC, 0xC2CD, 0x87ED, 0xF0C8, 0x87EF, 0xC2CC, - 0x87F2, 0xC2CE, 0x87F3, 0xF0C3, 0x87F4, 0xF0CF, 0x87F6, 0xF2DE, 0x87F7, 0xF2DF, 0x87F9, 0xC3C9, 0x87FA, 0xF2DC, 0x87FB, 0xC3C6, - 0x87FC, 0xF2E4, 0x87FE, 0xC3CA, 0x87FF, 0xF2E6, 0x8800, 0xF2DB, 0x8801, 0xF0CE, 0x8802, 0xF2E8, 0x8803, 0xF2DD, 0x8805, 0xC3C7, - 0x8806, 0xF2E3, 0x8808, 0xF2E5, 0x8809, 0xF2E0, 0x880A, 0xF2E7, 0x880B, 0xF2E2, 0x880C, 0xF2E1, 0x880D, 0xC3C8, 0x8810, 0xF4C5, - 0x8811, 0xF4C6, 0x8813, 0xF4C8, 0x8814, 0xC4AE, 0x8815, 0xC4AF, 0x8816, 0xF4C9, 0x8817, 0xF4C7, 0x8819, 0xF4C4, 0x881B, 0xF642, - 0x881C, 0xF645, 0x881D, 0xF641, 0x881F, 0xC4FA, 0x8820, 0xF643, 0x8821, 0xC4F9, 0x8822, 0xC4F8, 0x8823, 0xC4F7, 0x8824, 0xF644, - 0x8825, 0xF751, 0x8826, 0xF74F, 0x8828, 0xF74E, 0x8829, 0xF640, 0x882A, 0xF750, 0x882B, 0xF646, 0x882C, 0xF74D, 0x882E, 0xF7F9, - 0x882F, 0xF7D7, 0x8830, 0xF7F7, 0x8831, 0xC5DB, 0x8832, 0xF7F8, 0x8833, 0xF7FA, 0x8835, 0xF8BF, 0x8836, 0xC5FA, 0x8837, 0xF8BE, - 0x8838, 0xF8BD, 0x8839, 0xC5FB, 0x883B, 0xC65A, 0x883C, 0xF96E, 0x883D, 0xF9A7, 0x883E, 0xF9A6, 0x883F, 0xF9A8, 0x8840, 0xA6E5, - 0x8841, 0xD0AA, 0x8843, 0xD3CF, 0x8844, 0xD3D0, 0x8848, 0xDBC0, 0x884A, 0xF647, 0x884B, 0xF8C0, 0x884C, 0xA6E6, 0x884D, 0xAD6C, - 0x884E, 0xD0AB, 0x8852, 0xD7B1, 0x8853, 0xB34E, 0x8855, 0xDBC2, 0x8856, 0xDBC1, 0x8857, 0xB5F3, 0x8859, 0xB8C5, 0x885A, 0xE7C1, - 0x885B, 0xBDC3, 0x885D, 0xBDC4, 0x8861, 0xBFC5, 0x8862, 0xC5FC, 0x8863, 0xA6E7, 0x8867, 0xD0AC, 0x8868, 0xAAED, 0x8869, 0xD0AE, - 0x886A, 0xD0AD, 0x886B, 0xAD6D, 0x886D, 0xD3D1, 0x886F, 0xD3D8, 0x8870, 0xB049, 0x8871, 0xD3D6, 0x8872, 0xD3D4, 0x8874, 0xD3DB, - 0x8875, 0xD3D2, 0x8876, 0xD3D3, 0x8877, 0xB04A, 0x8879, 0xB04E, 0x887C, 0xD3DC, 0x887D, 0xB04D, 0x887E, 0xD3DA, 0x887F, 0xD3D7, - 0x8880, 0xD3D5, 0x8881, 0xB04B, 0x8882, 0xB04C, 0x8883, 0xD3D9, 0x8888, 0xB350, 0x8889, 0xD7B2, 0x888B, 0xB355, 0x888C, 0xD7C2, - 0x888D, 0xB354, 0x888E, 0xD7C4, 0x8891, 0xD7B8, 0x8892, 0xB352, 0x8893, 0xD7C3, 0x8895, 0xD7B3, 0x8896, 0xB353, 0x8897, 0xD7BF, - 0x8898, 0xD7BB, 0x8899, 0xD7BD, 0x889A, 0xD7B7, 0x889B, 0xD7BE, 0x889E, 0xB34F, 0x889F, 0xD7BA, 0x88A1, 0xD7B9, 0x88A2, 0xD7B5, - 0x88A4, 0xD7C0, 0x88A7, 0xD7BC, 0x88A8, 0xD7B4, 0x88AA, 0xD7B6, 0x88AB, 0xB351, 0x88AC, 0xD7C1, 0x88B1, 0xB5F6, 0x88B2, 0xDBCD, - 0x88B6, 0xDBC9, 0x88B7, 0xDBCB, 0x88B8, 0xDBC6, 0x88B9, 0xDBC5, 0x88BA, 0xDBC3, 0x88BC, 0xDBCA, 0x88BD, 0xDBCC, 0x88BE, 0xDBC8, - 0x88C0, 0xDBC7, 0x88C1, 0xB5F4, 0x88C2, 0xB5F5, 0x88C9, 0xDBCF, 0x88CA, 0xB8CD, 0x88CB, 0xDFF2, 0x88CC, 0xDFF8, 0x88CD, 0xDFF3, - 0x88CE, 0xDFF4, 0x88CF, 0xF9D8, 0x88D0, 0xDFF9, 0x88D2, 0xB8CF, 0x88D4, 0xB8C7, 0x88D5, 0xB8CE, 0x88D6, 0xDFF1, 0x88D7, 0xDBC4, - 0x88D8, 0xB8CA, 0x88D9, 0xB8C8, 0x88DA, 0xDFF7, 0x88DB, 0xDFF6, 0x88DC, 0xB8C9, 0x88DD, 0xB8CB, 0x88DE, 0xDFF5, 0x88DF, 0xB8C6, - 0x88E1, 0xB8CC, 0x88E7, 0xE3F6, 0x88E8, 0xBB74, 0x88EB, 0xE442, 0x88EC, 0xE441, 0x88EE, 0xE3FB, 0x88EF, 0xBB76, 0x88F0, 0xE440, - 0x88F1, 0xE3F7, 0x88F2, 0xE3F8, 0x88F3, 0xBB6E, 0x88F4, 0xBB70, 0x88F6, 0xE3FD, 0x88F7, 0xE3F5, 0x88F8, 0xBB72, 0x88F9, 0xBB71, - 0x88FA, 0xE3F9, 0x88FB, 0xE3FE, 0x88FC, 0xE3FC, 0x88FD, 0xBB73, 0x88FE, 0xE3FA, 0x8901, 0xDBCE, 0x8902, 0xBB6F, 0x8905, 0xE7C2, - 0x8906, 0xE7C9, 0x8907, 0xBDC6, 0x8909, 0xE7CD, 0x890A, 0xBDCA, 0x890B, 0xE7C5, 0x890C, 0xE7C3, 0x890E, 0xE7CC, 0x8910, 0xBDC5, - 0x8911, 0xE7CB, 0x8912, 0xBDC7, 0x8913, 0xBDC8, 0x8914, 0xE7C4, 0x8915, 0xBDC9, 0x8916, 0xE7CA, 0x8917, 0xE7C6, 0x8918, 0xE7C7, - 0x8919, 0xE7C8, 0x891A, 0xBB75, 0x891E, 0xEB70, 0x891F, 0xEB7C, 0x8921, 0xBFCA, 0x8922, 0xEB77, 0x8923, 0xEB79, 0x8925, 0xBFC8, - 0x8926, 0xEB71, 0x8927, 0xEB75, 0x8929, 0xEB78, 0x892A, 0xBFC6, 0x892B, 0xBFC9, 0x892C, 0xEB7B, 0x892D, 0xEB73, 0x892E, 0xEB74, - 0x892F, 0xEB7A, 0x8930, 0xEB72, 0x8931, 0xEB76, 0x8932, 0xBFC7, 0x8933, 0xEE72, 0x8935, 0xEE71, 0x8936, 0xC1B7, 0x8937, 0xEE77, - 0x8938, 0xC1B9, 0x893B, 0xC1B6, 0x893C, 0xEE73, 0x893D, 0xC1BA, 0x893E, 0xEE74, 0x8941, 0xEE75, 0x8942, 0xEE78, 0x8944, 0xC1B8, - 0x8946, 0xF0D6, 0x8949, 0xF0D9, 0x894B, 0xF0D3, 0x894C, 0xF0D5, 0x894F, 0xF0D4, 0x8950, 0xF0D7, 0x8951, 0xF0D8, 0x8952, 0xEE76, - 0x8953, 0xF0D2, 0x8956, 0xC3CD, 0x8957, 0xF2EC, 0x8958, 0xF2EF, 0x8959, 0xF2F1, 0x895A, 0xF2EA, 0x895B, 0xF2EB, 0x895C, 0xF2EE, - 0x895D, 0xF2F0, 0x895E, 0xC3CE, 0x895F, 0xC3CC, 0x8960, 0xC3CB, 0x8961, 0xF2ED, 0x8962, 0xF2E9, 0x8963, 0xF4CA, 0x8964, 0xC4B0, - 0x8966, 0xF4CB, 0x8969, 0xF649, 0x896A, 0xC4FB, 0x896B, 0xF64B, 0x896C, 0xC4FC, 0x896D, 0xF648, 0x896E, 0xF64A, 0x896F, 0xC5A8, - 0x8971, 0xF752, 0x8972, 0xC5A7, 0x8973, 0xF7FD, 0x8974, 0xF7FC, 0x8976, 0xF7FB, 0x8979, 0xF948, 0x897A, 0xF949, 0x897B, 0xF94B, - 0x897C, 0xF94A, 0x897E, 0xCA50, 0x897F, 0xA6E8, 0x8981, 0xAD6E, 0x8982, 0xD7C5, 0x8983, 0xB5F7, 0x8985, 0xDFFA, 0x8986, 0xC2D0, - 0x8988, 0xF2F2, 0x898B, 0xA8A3, 0x898F, 0xB357, 0x8993, 0xB356, 0x8995, 0xDBD0, 0x8996, 0xB5F8, 0x8997, 0xDBD2, 0x8998, 0xDBD1, - 0x899B, 0xDFFB, 0x899C, 0xB8D0, 0x899D, 0xE443, 0x899E, 0xE446, 0x899F, 0xE445, 0x89A1, 0xE444, 0x89A2, 0xE7CE, 0x89A3, 0xE7D0, - 0x89A4, 0xE7CF, 0x89A6, 0xBFCC, 0x89AA, 0xBFCB, 0x89AC, 0xC1BB, 0x89AD, 0xEE79, 0x89AE, 0xEE7B, 0x89AF, 0xEE7A, 0x89B2, 0xC2D1, - 0x89B6, 0xF2F4, 0x89B7, 0xF2F3, 0x89B9, 0xF4CC, 0x89BA, 0xC4B1, 0x89BD, 0xC4FD, 0x89BE, 0xF754, 0x89BF, 0xF753, 0x89C0, 0xC65B, - 0x89D2, 0xA8A4, 0x89D3, 0xD0AF, 0x89D4, 0xAD6F, 0x89D5, 0xD7C8, 0x89D6, 0xD7C6, 0x89D9, 0xD7C7, 0x89DA, 0xDBD4, 0x89DB, 0xDBD5, - 0x89DC, 0xE043, 0x89DD, 0xDBD3, 0x89DF, 0xDFFC, 0x89E0, 0xE041, 0x89E1, 0xE040, 0x89E2, 0xE042, 0x89E3, 0xB8D1, 0x89E4, 0xDFFE, - 0x89E5, 0xDFFD, 0x89E6, 0xE044, 0x89E8, 0xE449, 0x89E9, 0xE447, 0x89EB, 0xE448, 0x89EC, 0xE7D3, 0x89ED, 0xE7D1, 0x89F0, 0xE7D2, - 0x89F1, 0xEB7D, 0x89F2, 0xEE7C, 0x89F3, 0xEE7D, 0x89F4, 0xC2D2, 0x89F6, 0xF2F5, 0x89F7, 0xF4CD, 0x89F8, 0xC4B2, 0x89FA, 0xF64C, - 0x89FB, 0xF755, 0x89FC, 0xC5A9, 0x89FE, 0xF7FE, 0x89FF, 0xF94C, 0x8A00, 0xA8A5, 0x8A02, 0xAD71, 0x8A03, 0xAD72, 0x8A04, 0xD0B0, - 0x8A07, 0xD0B1, 0x8A08, 0xAD70, 0x8A0A, 0xB054, 0x8A0C, 0xB052, 0x8A0E, 0xB051, 0x8A0F, 0xB058, 0x8A10, 0xB050, 0x8A11, 0xB059, - 0x8A12, 0xD3DD, 0x8A13, 0xB056, 0x8A15, 0xB053, 0x8A16, 0xB057, 0x8A17, 0xB055, 0x8A18, 0xB04F, 0x8A1B, 0xB35F, 0x8A1D, 0xB359, - 0x8A1E, 0xD7CC, 0x8A1F, 0xB35E, 0x8A22, 0xB360, 0x8A23, 0xB35A, 0x8A25, 0xB35B, 0x8A27, 0xD7CA, 0x8A2A, 0xB358, 0x8A2C, 0xD7CB, - 0x8A2D, 0xB35D, 0x8A30, 0xD7C9, 0x8A31, 0xB35C, 0x8A34, 0xB644, 0x8A36, 0xB646, 0x8A39, 0xDBD8, 0x8A3A, 0xB645, 0x8A3B, 0xB5F9, - 0x8A3C, 0xB5FD, 0x8A3E, 0xB8E4, 0x8A3F, 0xE049, 0x8A40, 0xDBDA, 0x8A41, 0xB5FE, 0x8A44, 0xDBDD, 0x8A45, 0xDBDE, 0x8A46, 0xB643, - 0x8A48, 0xDBE0, 0x8A4A, 0xDBE2, 0x8A4C, 0xDBE3, 0x8A4D, 0xDBD7, 0x8A4E, 0xDBD6, 0x8A4F, 0xDBE4, 0x8A50, 0xB642, 0x8A51, 0xDBE1, - 0x8A52, 0xDBDF, 0x8A54, 0xB640, 0x8A55, 0xB5FB, 0x8A56, 0xB647, 0x8A57, 0xDBDB, 0x8A58, 0xDBDC, 0x8A59, 0xDBD9, 0x8A5B, 0xB641, - 0x8A5E, 0xB5FC, 0x8A60, 0xB5FA, 0x8A61, 0xE048, 0x8A62, 0xB8DF, 0x8A63, 0xB8DA, 0x8A66, 0xB8D5, 0x8A68, 0xB8E5, 0x8A69, 0xB8D6, - 0x8A6B, 0xB8D2, 0x8A6C, 0xB8E1, 0x8A6D, 0xB8DE, 0x8A6E, 0xB8E0, 0x8A70, 0xB8D7, 0x8A71, 0xB8DC, 0x8A72, 0xB8D3, 0x8A73, 0xB8D4, - 0x8A74, 0xE050, 0x8A75, 0xE04D, 0x8A76, 0xE045, 0x8A77, 0xE04A, 0x8A79, 0xB8E2, 0x8A7A, 0xE051, 0x8A7B, 0xB8E3, 0x8A7C, 0xB8D9, - 0x8A7F, 0xE047, 0x8A81, 0xE04F, 0x8A82, 0xE04B, 0x8A83, 0xE04E, 0x8A84, 0xE04C, 0x8A85, 0xB8DD, 0x8A86, 0xE046, 0x8A87, 0xB8D8, - 0x8A8B, 0xE44C, 0x8A8C, 0xBB78, 0x8A8D, 0xBB7B, 0x8A8F, 0xE44E, 0x8A91, 0xBBA5, 0x8A92, 0xE44D, 0x8A93, 0xBB7D, 0x8A95, 0xBDCF, - 0x8A96, 0xE44F, 0x8A98, 0xBBA4, 0x8A99, 0xE44B, 0x8A9A, 0xBBA6, 0x8A9E, 0xBB79, 0x8AA0, 0xB8DB, 0x8AA1, 0xBB7C, 0x8AA3, 0xBB7A, - 0x8AA4, 0xBB7E, 0x8AA5, 0xBBA2, 0x8AA6, 0xBB77, 0x8AA7, 0xBBA7, 0x8AA8, 0xBBA3, 0x8AAA, 0xBBA1, 0x8AAB, 0xE44A, 0x8AB0, 0xBDD6, - 0x8AB2, 0xBDD2, 0x8AB6, 0xBDD9, 0x8AB8, 0xE7D6, 0x8AB9, 0xBDDA, 0x8ABA, 0xE7E2, 0x8ABB, 0xE7DB, 0x8ABC, 0xBDCB, 0x8ABD, 0xE7E3, - 0x8ABE, 0xE7DD, 0x8ABF, 0xBDD5, 0x8AC0, 0xE7DE, 0x8AC2, 0xBDD4, 0x8AC3, 0xE7E1, 0x8AC4, 0xBDCE, 0x8AC5, 0xE7DF, 0x8AC6, 0xE7D5, - 0x8AC7, 0xBDCD, 0x8AC8, 0xEBAA, 0x8AC9, 0xBDD3, 0x8ACB, 0xBDD0, 0x8ACD, 0xBDD8, 0x8ACF, 0xE7D4, 0x8AD1, 0xE7D8, 0x8AD2, 0xBDCC, - 0x8AD3, 0xE7D7, 0x8AD4, 0xE7D9, 0x8AD5, 0xE7DA, 0x8AD6, 0xBDD7, 0x8AD7, 0xE7DC, 0x8AD8, 0xE7E0, 0x8AD9, 0xE7E4, 0x8ADB, 0xBDDB, - 0x8ADC, 0xBFD2, 0x8ADD, 0xEBA5, 0x8ADE, 0xEBAB, 0x8ADF, 0xEBA8, 0x8AE0, 0xEB7E, 0x8AE1, 0xEBAC, 0x8AE2, 0xEBA1, 0x8AE4, 0xEBA7, - 0x8AE6, 0xBFCD, 0x8AE7, 0xBFD3, 0x8AE8, 0xEBAD, 0x8AEB, 0xBFCF, 0x8AED, 0xBFD9, 0x8AEE, 0xBFD4, 0x8AEF, 0xEBAF, 0x8AF0, 0xEBA9, - 0x8AF1, 0xBFD0, 0x8AF2, 0xEBA2, 0x8AF3, 0xBFDA, 0x8AF4, 0xEBA3, 0x8AF5, 0xEBA4, 0x8AF6, 0xBFDB, 0x8AF7, 0xBFD8, 0x8AF8, 0xBDD1, - 0x8AFA, 0xBFCE, 0x8AFB, 0xEBB0, 0x8AFC, 0xBFDC, 0x8AFE, 0xBFD5, 0x8AFF, 0xEBAE, 0x8B00, 0xBFD1, 0x8B01, 0xBFD6, 0x8B02, 0xBFD7, - 0x8B04, 0xC1C3, 0x8B05, 0xEEA4, 0x8B06, 0xEEAD, 0x8B07, 0xEEAA, 0x8B08, 0xEEAC, 0x8B0A, 0xC1C0, 0x8B0B, 0xEEA5, 0x8B0D, 0xEEAB, - 0x8B0E, 0xC1BC, 0x8B0F, 0xEEA7, 0x8B10, 0xC1C4, 0x8B11, 0xEEA3, 0x8B12, 0xEEA8, 0x8B13, 0xEEAF, 0x8B14, 0xEBA6, 0x8B15, 0xEEA9, - 0x8B16, 0xEEA2, 0x8B17, 0xC1BD, 0x8B18, 0xEEA1, 0x8B19, 0xC1BE, 0x8B1A, 0xEEB0, 0x8B1B, 0xC1BF, 0x8B1C, 0xEEAE, 0x8B1D, 0xC1C2, - 0x8B1E, 0xEE7E, 0x8B20, 0xC1C1, 0x8B22, 0xEEA6, 0x8B23, 0xF0DC, 0x8B24, 0xF0EA, 0x8B25, 0xF0E5, 0x8B26, 0xF0E7, 0x8B27, 0xF0DB, - 0x8B28, 0xC2D3, 0x8B2A, 0xF0DA, 0x8B2B, 0xC2D6, 0x8B2C, 0xC2D5, 0x8B2E, 0xF0E9, 0x8B2F, 0xF0E1, 0x8B30, 0xF0DE, 0x8B31, 0xF0E4, - 0x8B33, 0xF0DD, 0x8B35, 0xF0DF, 0x8B36, 0xF0E8, 0x8B37, 0xF0E6, 0x8B39, 0xC2D4, 0x8B3A, 0xF0ED, 0x8B3B, 0xF0EB, 0x8B3C, 0xF0E2, - 0x8B3D, 0xF0EC, 0x8B3E, 0xF0E3, 0x8B40, 0xF2F9, 0x8B41, 0xC3CF, 0x8B42, 0xF341, 0x8B45, 0xF64F, 0x8B46, 0xC3D6, 0x8B47, 0xF0E0, - 0x8B48, 0xF2F7, 0x8B49, 0xC3D2, 0x8B4A, 0xF2F8, 0x8B4B, 0xF2FD, 0x8B4E, 0xC3D4, 0x8B4F, 0xC3D5, 0x8B50, 0xF2F6, 0x8B51, 0xF340, - 0x8B52, 0xF342, 0x8B53, 0xF2FA, 0x8B54, 0xF2FC, 0x8B55, 0xF2FE, 0x8B56, 0xF2FB, 0x8B57, 0xF343, 0x8B58, 0xC3D1, 0x8B59, 0xC3D7, - 0x8B5A, 0xC3D3, 0x8B5C, 0xC3D0, 0x8B5D, 0xF4D0, 0x8B5F, 0xC4B7, 0x8B60, 0xF4CE, 0x8B63, 0xF4D2, 0x8B65, 0xF4D3, 0x8B66, 0xC4B5, - 0x8B67, 0xF4D4, 0x8B68, 0xF4D1, 0x8B6A, 0xF4CF, 0x8B6B, 0xC4B8, 0x8B6C, 0xC4B4, 0x8B6D, 0xF4D5, 0x8B6F, 0xC4B6, 0x8B70, 0xC4B3, - 0x8B74, 0xC4FE, 0x8B77, 0xC540, 0x8B78, 0xF64E, 0x8B79, 0xF64D, 0x8B7A, 0xF650, 0x8B7B, 0xF651, 0x8B7D, 0xC541, 0x8B7E, 0xF756, - 0x8B7F, 0xF75B, 0x8B80, 0xC5AA, 0x8B82, 0xF758, 0x8B84, 0xF757, 0x8B85, 0xF75A, 0x8B86, 0xF759, 0x8B88, 0xF843, 0x8B8A, 0xC5DC, - 0x8B8B, 0xF842, 0x8B8C, 0xF840, 0x8B8E, 0xF841, 0x8B92, 0xC5FE, 0x8B93, 0xC5FD, 0x8B94, 0xF8C1, 0x8B95, 0xF8C2, 0x8B96, 0xC640, - 0x8B98, 0xF94D, 0x8B99, 0xF94E, 0x8B9A, 0xC667, 0x8B9C, 0xC66D, 0x8B9E, 0xF9A9, 0x8B9F, 0xF9C8, 0x8C37, 0xA8A6, 0x8C39, 0xD7CD, - 0x8C3B, 0xD7CE, 0x8C3C, 0xE052, 0x8C3D, 0xE450, 0x8C3E, 0xE7E5, 0x8C3F, 0xC1C6, 0x8C41, 0xC1C5, 0x8C42, 0xF0EE, 0x8C43, 0xF344, - 0x8C45, 0xF844, 0x8C46, 0xA8A7, 0x8C47, 0xD3DE, 0x8C48, 0xB05A, 0x8C49, 0xB361, 0x8C4A, 0xE054, 0x8C4B, 0xE053, 0x8C4C, 0xBDDC, - 0x8C4D, 0xE7E6, 0x8C4E, 0xBDDD, 0x8C4F, 0xEEB1, 0x8C50, 0xC2D7, 0x8C54, 0xC676, 0x8C55, 0xA8A8, 0x8C56, 0xCDCB, 0x8C57, 0xD3DF, - 0x8C5A, 0xB362, 0x8C5C, 0xD7CF, 0x8C5D, 0xD7D0, 0x8C5F, 0xDBE5, 0x8C61, 0xB648, 0x8C62, 0xB8E6, 0x8C64, 0xE056, 0x8C65, 0xE055, - 0x8C66, 0xE057, 0x8C68, 0xE451, 0x8C69, 0xE452, 0x8C6A, 0xBBA8, 0x8C6B, 0xBFDD, 0x8C6C, 0xBDDE, 0x8C6D, 0xBFDE, 0x8C6F, 0xEEB5, - 0x8C70, 0xEEB2, 0x8C71, 0xEEB4, 0x8C72, 0xEEB3, 0x8C73, 0xC1C7, 0x8C75, 0xF0EF, 0x8C76, 0xF346, 0x8C77, 0xF345, 0x8C78, 0xCBA4, - 0x8C79, 0xB05C, 0x8C7A, 0xB05B, 0x8C7B, 0xD3E0, 0x8C7D, 0xD7D1, 0x8C80, 0xDBE7, 0x8C81, 0xDBE6, 0x8C82, 0xB649, 0x8C84, 0xE059, - 0x8C85, 0xE05A, 0x8C86, 0xE058, 0x8C89, 0xB8E8, 0x8C8A, 0xB8E7, 0x8C8C, 0xBBAA, 0x8C8D, 0xBBA9, 0x8C8F, 0xE7E7, 0x8C90, 0xEBB3, - 0x8C91, 0xEBB1, 0x8C92, 0xEBB2, 0x8C93, 0xBFDF, 0x8C94, 0xEEB7, 0x8C95, 0xEEB6, 0x8C97, 0xF0F2, 0x8C98, 0xF0F1, 0x8C99, 0xF0F0, - 0x8C9A, 0xF347, 0x8C9C, 0xF9AA, 0x8C9D, 0xA8A9, 0x8C9E, 0xAD73, 0x8CA0, 0xAD74, 0x8CA1, 0xB05D, 0x8CA2, 0xB05E, 0x8CA3, 0xD3E2, - 0x8CA4, 0xD3E1, 0x8CA5, 0xD7D2, 0x8CA7, 0xB368, 0x8CA8, 0xB366, 0x8CA9, 0xB363, 0x8CAA, 0xB367, 0x8CAB, 0xB365, 0x8CAC, 0xB364, - 0x8CAF, 0xB64A, 0x8CB0, 0xDBEA, 0x8CB2, 0xB8ED, 0x8CB3, 0xB64C, 0x8CB4, 0xB651, 0x8CB5, 0xDBEC, 0x8CB6, 0xB653, 0x8CB7, 0xB652, - 0x8CB8, 0xB655, 0x8CB9, 0xDBEB, 0x8CBA, 0xDBE8, 0x8CBB, 0xB64F, 0x8CBC, 0xB64B, 0x8CBD, 0xB64D, 0x8CBE, 0xDBE9, 0x8CBF, 0xB654, - 0x8CC0, 0xB650, 0x8CC1, 0xB64E, 0x8CC2, 0xB8EF, 0x8CC3, 0xB8EE, 0x8CC4, 0xB8EC, 0x8CC5, 0xB8F0, 0x8CC7, 0xB8EA, 0x8CC8, 0xB8EB, - 0x8CCA, 0xB8E9, 0x8CCC, 0xE05B, 0x8CCF, 0xE454, 0x8CD1, 0xBBAC, 0x8CD2, 0xBBAD, 0x8CD3, 0xBBAB, 0x8CD5, 0xE453, 0x8CD7, 0xE455, - 0x8CD9, 0xE7EA, 0x8CDA, 0xE7EC, 0x8CDC, 0xBDE7, 0x8CDD, 0xE7ED, 0x8CDE, 0xBDE0, 0x8CDF, 0xE7E9, 0x8CE0, 0xBDDF, 0x8CE1, 0xBDE9, - 0x8CE2, 0xBDE5, 0x8CE3, 0xBDE6, 0x8CE4, 0xBDE2, 0x8CE5, 0xE7E8, 0x8CE6, 0xBDE1, 0x8CE7, 0xE7EE, 0x8CE8, 0xE7EB, 0x8CEA, 0xBDE8, - 0x8CEC, 0xBDE3, 0x8CED, 0xBDE4, 0x8CEE, 0xEBB5, 0x8CF0, 0xEBB7, 0x8CF1, 0xEBB6, 0x8CF3, 0xEBB8, 0x8CF4, 0xBFE0, 0x8CF5, 0xEBB4, - 0x8CF8, 0xC1CB, 0x8CF9, 0xEEB8, 0x8CFA, 0xC1C8, 0x8CFB, 0xC1CC, 0x8CFC, 0xC1CA, 0x8CFD, 0xC1C9, 0x8CFE, 0xF0F3, 0x8D00, 0xF0F6, - 0x8D02, 0xF0F5, 0x8D04, 0xF0F4, 0x8D05, 0xC2D8, 0x8D06, 0xF348, 0x8D07, 0xF349, 0x8D08, 0xC3D8, 0x8D09, 0xF34A, 0x8D0A, 0xC3D9, - 0x8D0D, 0xC4BA, 0x8D0F, 0xC4B9, 0x8D10, 0xF652, 0x8D13, 0xC542, 0x8D14, 0xF653, 0x8D15, 0xF75C, 0x8D16, 0xC5AB, 0x8D17, 0xC5AC, - 0x8D19, 0xF845, 0x8D1B, 0xC642, 0x8D64, 0xA8AA, 0x8D66, 0xB36A, 0x8D67, 0xB369, 0x8D68, 0xE05C, 0x8D69, 0xE05D, 0x8D6B, 0xBBAE, - 0x8D6C, 0xEBB9, 0x8D6D, 0xBDEA, 0x8D6E, 0xEBBA, 0x8D6F, 0xEEB9, 0x8D70, 0xA8AB, 0x8D72, 0xD0B2, 0x8D73, 0xAD76, 0x8D74, 0xAD75, - 0x8D76, 0xD3E3, 0x8D77, 0xB05F, 0x8D78, 0xD3E4, 0x8D79, 0xD7D5, 0x8D7B, 0xD7D4, 0x8D7D, 0xD7D3, 0x8D80, 0xDBEE, 0x8D81, 0xB658, - 0x8D84, 0xDBED, 0x8D85, 0xB657, 0x8D89, 0xDBEF, 0x8D8A, 0xB656, 0x8D8C, 0xE05F, 0x8D8D, 0xE062, 0x8D8E, 0xE060, 0x8D8F, 0xE061, - 0x8D90, 0xE065, 0x8D91, 0xE05E, 0x8D92, 0xE066, 0x8D93, 0xE063, 0x8D94, 0xE064, 0x8D95, 0xBBB0, 0x8D96, 0xE456, 0x8D99, 0xBBAF, - 0x8D9B, 0xE7F2, 0x8D9C, 0xE7F0, 0x8D9F, 0xBDEB, 0x8DA0, 0xE7EF, 0x8DA1, 0xE7F1, 0x8DA3, 0xBDEC, 0x8DA5, 0xEBBB, 0x8DA7, 0xEBBC, - 0x8DA8, 0xC1CD, 0x8DAA, 0xF34C, 0x8DAB, 0xF34E, 0x8DAC, 0xF34B, 0x8DAD, 0xF34D, 0x8DAE, 0xF4D6, 0x8DAF, 0xF654, 0x8DB2, 0xF96F, - 0x8DB3, 0xA8AC, 0x8DB4, 0xAD77, 0x8DB5, 0xD3E5, 0x8DB6, 0xD3E7, 0x8DB7, 0xD3E6, 0x8DB9, 0xD7D8, 0x8DBA, 0xB36C, 0x8DBC, 0xD7D6, - 0x8DBE, 0xB36B, 0x8DBF, 0xD7D9, 0x8DC1, 0xD7DA, 0x8DC2, 0xD7D7, 0x8DC5, 0xDBFB, 0x8DC6, 0xB660, 0x8DC7, 0xDBF3, 0x8DC8, 0xDBF9, - 0x8DCB, 0xB65B, 0x8DCC, 0xB65E, 0x8DCD, 0xDBF2, 0x8DCE, 0xB659, 0x8DCF, 0xDBF6, 0x8DD0, 0xE06C, 0x8DD1, 0xB65D, 0x8DD3, 0xDBF1, - 0x8DD5, 0xDBF7, 0x8DD6, 0xDBF4, 0x8DD7, 0xDBFA, 0x8DD8, 0xDBF0, 0x8DD9, 0xDBF8, 0x8DDA, 0xB65C, 0x8DDB, 0xB65F, 0x8DDC, 0xDBF5, - 0x8DDD, 0xB65A, 0x8DDF, 0xB8F2, 0x8DE0, 0xE068, 0x8DE1, 0xB8F1, 0x8DE2, 0xE06F, 0x8DE3, 0xE06E, 0x8DE4, 0xB8F8, 0x8DE6, 0xB8F9, - 0x8DE7, 0xE070, 0x8DE8, 0xB8F3, 0x8DE9, 0xE06D, 0x8DEA, 0xB8F7, 0x8DEB, 0xE072, 0x8DEC, 0xE069, 0x8DEE, 0xE06B, 0x8DEF, 0xB8F4, - 0x8DF0, 0xE067, 0x8DF1, 0xE06A, 0x8DF2, 0xE071, 0x8DF3, 0xB8F5, 0x8DF4, 0xE073, 0x8DFA, 0xB8F6, 0x8DFC, 0xBBB1, 0x8DFD, 0xE45B, - 0x8DFE, 0xE461, 0x8DFF, 0xE459, 0x8E00, 0xE462, 0x8E02, 0xE458, 0x8E03, 0xE45D, 0x8E04, 0xE463, 0x8E05, 0xE460, 0x8E06, 0xE45F, - 0x8E07, 0xE45E, 0x8E09, 0xE457, 0x8E0A, 0xE45C, 0x8E0D, 0xE45A, 0x8E0F, 0xBDF1, 0x8E10, 0xBDEE, 0x8E11, 0xE7FB, 0x8E12, 0xE841, - 0x8E13, 0xE843, 0x8E14, 0xE840, 0x8E15, 0xE7F8, 0x8E16, 0xE7FA, 0x8E17, 0xE845, 0x8E18, 0xE842, 0x8E19, 0xE7FC, 0x8E1A, 0xE846, - 0x8E1B, 0xE7F9, 0x8E1C, 0xE844, 0x8E1D, 0xBDEF, 0x8E1E, 0xBDF5, 0x8E1F, 0xBDF3, 0x8E20, 0xE7F3, 0x8E21, 0xBDF4, 0x8E22, 0xBDF0, - 0x8E23, 0xE7F4, 0x8E24, 0xE7F6, 0x8E25, 0xE7F5, 0x8E26, 0xE7FD, 0x8E27, 0xE7FE, 0x8E29, 0xBDF2, 0x8E2B, 0xBDED, 0x8E2E, 0xE7F7, - 0x8E30, 0xEBC6, 0x8E31, 0xBFE2, 0x8E33, 0xEBBD, 0x8E34, 0xBFE3, 0x8E35, 0xBFE6, 0x8E36, 0xEBC2, 0x8E38, 0xEBBF, 0x8E39, 0xBFE5, - 0x8E3C, 0xEBC3, 0x8E3D, 0xEBC4, 0x8E3E, 0xEBBE, 0x8E3F, 0xEBC7, 0x8E40, 0xEBC0, 0x8E41, 0xEBC5, 0x8E42, 0xBFE4, 0x8E44, 0xBFE1, - 0x8E45, 0xEBC1, 0x8E47, 0xEEBF, 0x8E48, 0xC1D0, 0x8E49, 0xC1CE, 0x8E4A, 0xC1D1, 0x8E4B, 0xC1CF, 0x8E4C, 0xEEBE, 0x8E4D, 0xEEBB, - 0x8E4E, 0xEEBA, 0x8E50, 0xEEBD, 0x8E53, 0xEEBC, 0x8E54, 0xF145, 0x8E55, 0xC2DE, 0x8E56, 0xF0FB, 0x8E57, 0xF0FA, 0x8E59, 0xC2D9, - 0x8E5A, 0xF141, 0x8E5B, 0xF140, 0x8E5C, 0xF0F7, 0x8E5D, 0xF143, 0x8E5E, 0xF0FC, 0x8E5F, 0xC2DD, 0x8E60, 0xF0F9, 0x8E61, 0xF142, - 0x8E62, 0xF0F8, 0x8E63, 0xC2DA, 0x8E64, 0xC2DC, 0x8E65, 0xF0FD, 0x8E66, 0xC2DB, 0x8E67, 0xF0FE, 0x8E69, 0xF144, 0x8E6A, 0xF352, - 0x8E6C, 0xC3DE, 0x8E6D, 0xF34F, 0x8E6F, 0xF353, 0x8E72, 0xC3DB, 0x8E73, 0xF351, 0x8E74, 0xC3E0, 0x8E76, 0xC3DD, 0x8E78, 0xF350, - 0x8E7A, 0xC3DF, 0x8E7B, 0xF354, 0x8E7C, 0xC3DA, 0x8E81, 0xC4BC, 0x8E82, 0xC4BE, 0x8E84, 0xF4D9, 0x8E85, 0xC4BD, 0x8E86, 0xF4D7, - 0x8E87, 0xC3DC, 0x8E88, 0xF4D8, 0x8E89, 0xC4BB, 0x8E8A, 0xC543, 0x8E8B, 0xC545, 0x8E8C, 0xF656, 0x8E8D, 0xC544, 0x8E8E, 0xF655, - 0x8E90, 0xF761, 0x8E91, 0xC5AD, 0x8E92, 0xF760, 0x8E93, 0xC5AE, 0x8E94, 0xF75E, 0x8E95, 0xF75D, 0x8E96, 0xF762, 0x8E97, 0xF763, - 0x8E98, 0xF846, 0x8E9A, 0xF75F, 0x8E9D, 0xF8C6, 0x8E9E, 0xF8C3, 0x8E9F, 0xF8C4, 0x8EA0, 0xF8C5, 0x8EA1, 0xC65C, 0x8EA3, 0xF951, - 0x8EA4, 0xF950, 0x8EA5, 0xF94F, 0x8EA6, 0xF970, 0x8EA8, 0xF9BE, 0x8EA9, 0xF9AB, 0x8EAA, 0xC66E, 0x8EAB, 0xA8AD, 0x8EAC, 0xB060, - 0x8EB2, 0xB8FA, 0x8EBA, 0xBDF6, 0x8EBD, 0xEBC8, 0x8EC0, 0xC2DF, 0x8EC2, 0xF355, 0x8EC9, 0xF9AC, 0x8ECA, 0xA8AE, 0x8ECB, 0xAAEE, - 0x8ECC, 0xAD79, 0x8ECD, 0xAD78, 0x8ECF, 0xB063, 0x8ED1, 0xD3E8, 0x8ED2, 0xB061, 0x8ED3, 0xD3E9, 0x8ED4, 0xB062, 0x8ED7, 0xD7DF, - 0x8ED8, 0xD7DB, 0x8EDB, 0xB36D, 0x8EDC, 0xD7DE, 0x8EDD, 0xD7DD, 0x8EDE, 0xD7DC, 0x8EDF, 0xB36E, 0x8EE0, 0xD7E0, 0x8EE1, 0xD7E1, - 0x8EE5, 0xDC43, 0x8EE6, 0xDC41, 0x8EE7, 0xDC45, 0x8EE8, 0xDC46, 0x8EE9, 0xDC4C, 0x8EEB, 0xDC48, 0x8EEC, 0xDC4A, 0x8EEE, 0xDC42, - 0x8EEF, 0xDBFC, 0x8EF1, 0xDC49, 0x8EF4, 0xDC4B, 0x8EF5, 0xDC44, 0x8EF6, 0xDC47, 0x8EF7, 0xDBFD, 0x8EF8, 0xB662, 0x8EF9, 0xDC40, - 0x8EFA, 0xDBFE, 0x8EFB, 0xB661, 0x8EFC, 0xB663, 0x8EFE, 0xB8FD, 0x8EFF, 0xE075, 0x8F00, 0xE077, 0x8F01, 0xE076, 0x8F02, 0xE07B, - 0x8F03, 0xB8FB, 0x8F05, 0xE078, 0x8F06, 0xE074, 0x8F07, 0xE079, 0x8F08, 0xE07A, 0x8F09, 0xB8FC, 0x8F0A, 0xB8FE, 0x8F0B, 0xE07C, - 0x8F0D, 0xE467, 0x8F0E, 0xE466, 0x8F10, 0xE464, 0x8F11, 0xE465, 0x8F12, 0xBBB3, 0x8F13, 0xBBB5, 0x8F14, 0xBBB2, 0x8F15, 0xBBB4, - 0x8F16, 0xE84D, 0x8F17, 0xE84E, 0x8F18, 0xE849, 0x8F1A, 0xE84A, 0x8F1B, 0xBDF8, 0x8F1C, 0xBDFD, 0x8F1D, 0xBDF7, 0x8F1E, 0xBDFE, - 0x8F1F, 0xBDF9, 0x8F20, 0xE84B, 0x8F23, 0xE84C, 0x8F24, 0xE848, 0x8F25, 0xBE40, 0x8F26, 0xBDFB, 0x8F29, 0xBDFA, 0x8F2A, 0xBDFC, - 0x8F2C, 0xE847, 0x8F2E, 0xEBCA, 0x8F2F, 0xBFE8, 0x8F32, 0xEBCC, 0x8F33, 0xBFEA, 0x8F34, 0xEBCF, 0x8F35, 0xEBCB, 0x8F36, 0xEBC9, - 0x8F37, 0xEBCE, 0x8F38, 0xBFE9, 0x8F39, 0xEBCD, 0x8F3B, 0xBFE7, 0x8F3E, 0xC1D3, 0x8F3F, 0xC1D6, 0x8F40, 0xEEC1, 0x8F42, 0xC1D4, - 0x8F43, 0xEEC0, 0x8F44, 0xC1D2, 0x8F45, 0xC1D5, 0x8F46, 0xF146, 0x8F47, 0xF147, 0x8F48, 0xF148, 0x8F49, 0xC2E0, 0x8F4B, 0xF149, - 0x8F4D, 0xC2E1, 0x8F4E, 0xC3E2, 0x8F4F, 0xF358, 0x8F50, 0xF359, 0x8F51, 0xF357, 0x8F52, 0xF356, 0x8F53, 0xF35A, 0x8F54, 0xC3E1, - 0x8F55, 0xF4DD, 0x8F56, 0xF4DB, 0x8F57, 0xF4DC, 0x8F58, 0xF4DE, 0x8F59, 0xF4DA, 0x8F5A, 0xF4DF, 0x8F5B, 0xF658, 0x8F5D, 0xF659, - 0x8F5E, 0xF657, 0x8F5F, 0xC546, 0x8F60, 0xF764, 0x8F61, 0xC5AF, 0x8F62, 0xF765, 0x8F63, 0xF848, 0x8F64, 0xF847, 0x8F9B, 0xA8AF, - 0x8F9C, 0xB664, 0x8F9F, 0xB940, 0x8FA3, 0xBBB6, 0x8FA6, 0xBFEC, 0x8FA8, 0xBFEB, 0x8FAD, 0xC3E3, 0x8FAE, 0xC47C, 0x8FAF, 0xC547, - 0x8FB0, 0xA8B0, 0x8FB1, 0xB064, 0x8FB2, 0xB941, 0x8FB4, 0xF35B, 0x8FBF, 0xCBA6, 0x8FC2, 0xA8B1, 0x8FC4, 0xA8B4, 0x8FC5, 0xA8B3, - 0x8FC6, 0xA8B2, 0x8FC9, 0xCBA5, 0x8FCB, 0xCDCD, 0x8FCD, 0xCDCF, 0x8FCE, 0xAAEF, 0x8FD1, 0xAAF1, 0x8FD2, 0xCDCC, 0x8FD3, 0xCDCE, - 0x8FD4, 0xAAF0, 0x8FD5, 0xCDD1, 0x8FD6, 0xCDD0, 0x8FD7, 0xCDD2, 0x8FE0, 0xD0B6, 0x8FE1, 0xD0B4, 0x8FE2, 0xAD7C, 0x8FE3, 0xD0B3, - 0x8FE4, 0xADA3, 0x8FE5, 0xAD7E, 0x8FE6, 0xAD7B, 0x8FE8, 0xADA4, 0x8FEA, 0xAD7D, 0x8FEB, 0xADA2, 0x8FED, 0xADA1, 0x8FEE, 0xD0B5, - 0x8FF0, 0xAD7A, 0x8FF4, 0xB06A, 0x8FF5, 0xD3EB, 0x8FF6, 0xD3F1, 0x8FF7, 0xB067, 0x8FF8, 0xB06E, 0x8FFA, 0xB069, 0x8FFB, 0xD3EE, - 0x8FFC, 0xD3F0, 0x8FFD, 0xB06C, 0x8FFE, 0xD3EA, 0x8FFF, 0xD3ED, 0x9000, 0xB068, 0x9001, 0xB065, 0x9002, 0xD3EC, 0x9003, 0xB06B, - 0x9004, 0xD3EF, 0x9005, 0xB06D, 0x9006, 0xB066, 0x900B, 0xD7E3, 0x900C, 0xD7E6, 0x900D, 0xB370, 0x900F, 0xB37A, 0x9010, 0xB376, - 0x9011, 0xD7E4, 0x9014, 0xB37E, 0x9015, 0xB377, 0x9016, 0xB37C, 0x9017, 0xB372, 0x9019, 0xB36F, 0x901A, 0xB371, 0x901B, 0xB37D, - 0x901C, 0xD7E5, 0x901D, 0xB375, 0x901E, 0xB378, 0x901F, 0xB374, 0x9020, 0xB379, 0x9021, 0xD7E7, 0x9022, 0xB37B, 0x9023, 0xB373, - 0x9024, 0xD7E2, 0x902D, 0xDC4D, 0x902E, 0xB665, 0x902F, 0xDC4F, 0x9031, 0xB667, 0x9032, 0xB669, 0x9034, 0xDC4E, 0x9035, 0xB666, - 0x9036, 0xB66A, 0x9038, 0xB668, 0x903C, 0xB947, 0x903D, 0xE0A3, 0x903E, 0xB94F, 0x903F, 0xE07E, 0x9041, 0xB950, 0x9042, 0xB945, - 0x9044, 0xE0A1, 0x9047, 0xB94A, 0x9049, 0xE0A2, 0x904A, 0xB943, 0x904B, 0xB942, 0x904D, 0xB94D, 0x904E, 0xB94C, 0x904F, 0xB94B, - 0x9050, 0xB949, 0x9051, 0xB94E, 0x9052, 0xE07D, 0x9053, 0xB944, 0x9054, 0xB946, 0x9055, 0xB948, 0x9058, 0xBBB8, 0x9059, 0xBBBB, - 0x905B, 0xBBBF, 0x905C, 0xBBB9, 0x905D, 0xBBBE, 0x905E, 0xBBBC, 0x9060, 0xBBB7, 0x9062, 0xBBBD, 0x9063, 0xBBBA, 0x9067, 0xE852, - 0x9068, 0xBE43, 0x9069, 0xBE41, 0x906B, 0xE853, 0x906D, 0xBE44, 0x906E, 0xBE42, 0x906F, 0xE851, 0x9070, 0xE850, 0x9072, 0xBFF0, - 0x9073, 0xE84F, 0x9074, 0xBFEE, 0x9075, 0xBFED, 0x9076, 0xEBD0, 0x9077, 0xBE45, 0x9078, 0xBFEF, 0x9079, 0xEBD1, 0x907A, 0xBFF2, - 0x907B, 0xEBD2, 0x907C, 0xBFF1, 0x907D, 0xC1D8, 0x907E, 0xEEC3, 0x907F, 0xC1D7, 0x9080, 0xC1DC, 0x9081, 0xC1DA, 0x9082, 0xC1DB, - 0x9083, 0xC2E3, 0x9084, 0xC1D9, 0x9085, 0xEEC2, 0x9086, 0xEBD3, 0x9087, 0xC2E2, 0x9088, 0xC2E4, 0x908A, 0xC3E4, 0x908B, 0xC3E5, - 0x908D, 0xF4E0, 0x908F, 0xC5DE, 0x9090, 0xC5DD, 0x9091, 0xA8B6, 0x9094, 0xCA55, 0x9095, 0xB06F, 0x9097, 0xCA52, 0x9098, 0xCA53, - 0x9099, 0xCA51, 0x909B, 0xCA54, 0x909E, 0xCBAA, 0x909F, 0xCBA7, 0x90A0, 0xCBAC, 0x90A1, 0xCBA8, 0x90A2, 0xA8B7, 0x90A3, 0xA8BA, - 0x90A5, 0xCBA9, 0x90A6, 0xA8B9, 0x90A7, 0xCBAB, 0x90AA, 0xA8B8, 0x90AF, 0xCDD5, 0x90B0, 0xCDD7, 0x90B1, 0xAAF4, 0x90B2, 0xCDD3, - 0x90B3, 0xCDD6, 0x90B4, 0xCDD4, 0x90B5, 0xAAF2, 0x90B6, 0xAAF5, 0x90B8, 0xAAF3, 0x90BD, 0xD0B8, 0x90BE, 0xD0BC, 0x90BF, 0xD0B9, - 0x90C1, 0xADA7, 0x90C3, 0xADA8, 0x90C5, 0xD0BB, 0x90C7, 0xD0BD, 0x90C8, 0xD0BF, 0x90CA, 0xADA5, 0x90CB, 0xD0BE, 0x90CE, 0xADA6, - 0x90D4, 0xD7EE, 0x90D5, 0xD0BA, 0x90D6, 0xD3F2, 0x90D7, 0xD3FB, 0x90D8, 0xD3F9, 0x90D9, 0xD3F4, 0x90DA, 0xD3F5, 0x90DB, 0xD3FA, - 0x90DC, 0xD3FC, 0x90DD, 0xB071, 0x90DF, 0xD3F7, 0x90E0, 0xD3F3, 0x90E1, 0xB070, 0x90E2, 0xB072, 0x90E3, 0xD3F6, 0x90E4, 0xD3FD, - 0x90E5, 0xD3F8, 0x90E8, 0xB3A1, 0x90E9, 0xD7F1, 0x90EA, 0xD7E9, 0x90EB, 0xD7EF, 0x90EC, 0xD7F0, 0x90ED, 0xB3A2, 0x90EF, 0xD7E8, - 0x90F0, 0xD7EA, 0x90F1, 0xD0B7, 0x90F2, 0xD7EC, 0x90F3, 0xD7ED, 0x90F4, 0xD7EB, 0x90F5, 0xB66C, 0x90F9, 0xDC56, 0x90FA, 0xEBD4, - 0x90FB, 0xDC57, 0x90FC, 0xDC54, 0x90FD, 0xB3A3, 0x90FE, 0xB66E, 0x90FF, 0xDC53, 0x9100, 0xDC59, 0x9101, 0xDC58, 0x9102, 0xB66B, - 0x9103, 0xDC5C, 0x9104, 0xDC52, 0x9105, 0xDC5B, 0x9106, 0xDC50, 0x9107, 0xDC5A, 0x9108, 0xDC55, 0x9109, 0xB66D, 0x910B, 0xE0AA, - 0x910D, 0xE0A5, 0x910E, 0xE0AB, 0x910F, 0xE0A6, 0x9110, 0xE0A4, 0x9111, 0xE0A7, 0x9112, 0xB951, 0x9114, 0xE0A9, 0x9116, 0xE0A8, - 0x9117, 0xB952, 0x9118, 0xBBC1, 0x9119, 0xBBC0, 0x911A, 0xE46E, 0x911B, 0xE471, 0x911C, 0xE469, 0x911D, 0xE46D, 0x911E, 0xBBC2, - 0x911F, 0xE46C, 0x9120, 0xE46A, 0x9121, 0xE470, 0x9122, 0xE46B, 0x9123, 0xE468, 0x9124, 0xE46F, 0x9126, 0xE859, 0x9127, 0xBE48, - 0x9128, 0xF14A, 0x9129, 0xE856, 0x912A, 0xE857, 0x912B, 0xE855, 0x912C, 0xDC51, 0x912D, 0xBE47, 0x912E, 0xE85A, 0x912F, 0xE854, - 0x9130, 0xBE46, 0x9131, 0xBE49, 0x9132, 0xE858, 0x9133, 0xEBD5, 0x9134, 0xBFF3, 0x9135, 0xEBD6, 0x9136, 0xEBD7, 0x9138, 0xEEC4, - 0x9139, 0xC1DD, 0x913A, 0xF14B, 0x913B, 0xF14C, 0x913E, 0xF14D, 0x913F, 0xF35D, 0x9140, 0xF35C, 0x9141, 0xF4E2, 0x9143, 0xF4E1, - 0x9144, 0xF65B, 0x9145, 0xF65C, 0x9146, 0xF65A, 0x9147, 0xF766, 0x9148, 0xC5B0, 0x9149, 0xA8BB, 0x914A, 0xADAA, 0x914B, 0xADA9, - 0x914C, 0xB075, 0x914D, 0xB074, 0x914E, 0xD440, 0x914F, 0xD441, 0x9150, 0xD3FE, 0x9152, 0xB073, 0x9153, 0xD7F5, 0x9155, 0xD7F6, - 0x9156, 0xD7F2, 0x9157, 0xB3A4, 0x9158, 0xD7F3, 0x915A, 0xD7F4, 0x915F, 0xDC5F, 0x9160, 0xDC61, 0x9161, 0xDC5D, 0x9162, 0xDC60, - 0x9163, 0xB66F, 0x9164, 0xDC5E, 0x9165, 0xB670, 0x9168, 0xDD73, 0x9169, 0xB955, 0x916A, 0xB954, 0x916C, 0xB953, 0x916E, 0xE0AC, - 0x916F, 0xE0AD, 0x9172, 0xE473, 0x9173, 0xE475, 0x9174, 0xBBC6, 0x9175, 0xBBC3, 0x9177, 0xBBC5, 0x9178, 0xBBC4, 0x9179, 0xE474, - 0x917A, 0xE472, 0x9180, 0xE861, 0x9181, 0xE85E, 0x9182, 0xE85F, 0x9183, 0xBE4D, 0x9184, 0xE860, 0x9185, 0xE85B, 0x9186, 0xE85C, - 0x9187, 0xBE4A, 0x9189, 0xBE4B, 0x918A, 0xE85D, 0x918B, 0xBE4C, 0x918D, 0xEBDB, 0x918F, 0xEBDC, 0x9190, 0xEBD9, 0x9191, 0xEBDA, - 0x9192, 0xBFF4, 0x9193, 0xEBD8, 0x9199, 0xEEC8, 0x919A, 0xEEC5, 0x919B, 0xEEC7, 0x919C, 0xC1E0, 0x919D, 0xEECB, 0x919E, 0xC1DF, - 0x919F, 0xEEC9, 0x91A0, 0xEECC, 0x91A1, 0xEECA, 0x91A2, 0xEEC6, 0x91A3, 0xC1DE, 0x91A5, 0xF14F, 0x91A7, 0xF150, 0x91A8, 0xF14E, - 0x91AA, 0xF152, 0x91AB, 0xC2E5, 0x91AC, 0xC2E6, 0x91AD, 0xF35F, 0x91AE, 0xC3E7, 0x91AF, 0xF151, 0x91B0, 0xF35E, 0x91B1, 0xC3E6, - 0x91B2, 0xF4E5, 0x91B3, 0xF4E6, 0x91B4, 0xC4BF, 0x91B5, 0xF4E4, 0x91B7, 0xF4E3, 0x91B9, 0xF65D, 0x91BA, 0xC548, 0x91BC, 0xF849, - 0x91BD, 0xF8C8, 0x91BE, 0xF8C7, 0x91C0, 0xC643, 0x91C1, 0xC65D, 0x91C2, 0xF8C9, 0x91C3, 0xF971, 0x91C5, 0xC66F, 0x91C6, 0xA8BC, - 0x91C7, 0xAAF6, 0x91C9, 0xB956, 0x91CB, 0xC4C0, 0x91CC, 0xA8BD, 0x91CD, 0xADAB, 0x91CE, 0xB3A5, 0x91CF, 0xB671, 0x91D0, 0xC2E7, - 0x91D1, 0xAAF7, 0x91D3, 0xD0C1, 0x91D4, 0xD0C0, 0x91D5, 0xD442, 0x91D7, 0xB078, 0x91D8, 0xB076, 0x91D9, 0xB07A, 0x91DA, 0xD444, - 0x91DC, 0xB079, 0x91DD, 0xB077, 0x91E2, 0xD443, 0x91E3, 0xB3A8, 0x91E4, 0xD7FC, 0x91E6, 0xB3A7, 0x91E7, 0xB3A9, 0x91E8, 0xD842, - 0x91E9, 0xB3AB, 0x91EA, 0xD7FE, 0x91EB, 0xD840, 0x91EC, 0xD7F7, 0x91ED, 0xB3AA, 0x91EE, 0xD843, 0x91F1, 0xD7F9, 0x91F3, 0xD7FA, - 0x91F4, 0xD7F8, 0x91F5, 0xB3A6, 0x91F7, 0xD841, 0x91F8, 0xD7FB, 0x91F9, 0xD7FD, 0x91FD, 0xDC6D, 0x91FF, 0xDC6C, 0x9200, 0xDC6A, - 0x9201, 0xDC62, 0x9202, 0xDC71, 0x9203, 0xDC65, 0x9204, 0xDC6F, 0x9205, 0xDC76, 0x9206, 0xDC6E, 0x9207, 0xB679, 0x9209, 0xB675, - 0x920A, 0xDC63, 0x920C, 0xDC69, 0x920D, 0xB677, 0x920F, 0xDC68, 0x9210, 0xB678, 0x9211, 0xB67A, 0x9212, 0xDC6B, 0x9214, 0xB672, - 0x9215, 0xB673, 0x9216, 0xDC77, 0x9217, 0xDC75, 0x9219, 0xDC74, 0x921A, 0xDC66, 0x921C, 0xDC72, 0x921E, 0xB676, 0x9223, 0xB674, - 0x9224, 0xDC73, 0x9225, 0xDC64, 0x9226, 0xDC67, 0x9227, 0xDC70, 0x922D, 0xE4BA, 0x922E, 0xE0B7, 0x9230, 0xE0B0, 0x9231, 0xE0C3, - 0x9232, 0xE0CC, 0x9233, 0xE0B3, 0x9234, 0xB961, 0x9236, 0xE0C0, 0x9237, 0xB957, 0x9238, 0xB959, 0x9239, 0xB965, 0x923A, 0xE0B1, - 0x923D, 0xB95A, 0x923E, 0xB95C, 0x923F, 0xB966, 0x9240, 0xB95B, 0x9245, 0xB964, 0x9246, 0xE0B9, 0x9248, 0xE0AE, 0x9249, 0xB962, - 0x924A, 0xE0B8, 0x924B, 0xB95E, 0x924C, 0xE0CA, 0x924D, 0xB963, 0x924E, 0xE0C8, 0x924F, 0xE0BC, 0x9250, 0xE0C6, 0x9251, 0xB960, - 0x9252, 0xE0AF, 0x9253, 0xE0C9, 0x9254, 0xE0C4, 0x9256, 0xE0CB, 0x9257, 0xB958, 0x925A, 0xB967, 0x925B, 0xB95D, 0x925E, 0xE0B5, - 0x9260, 0xE0BD, 0x9261, 0xE0C1, 0x9263, 0xE0C5, 0x9264, 0xB95F, 0x9265, 0xE0B4, 0x9266, 0xE0B2, 0x9267, 0xE0BE, 0x926C, 0xE0BB, - 0x926D, 0xE0BA, 0x926F, 0xE0BF, 0x9270, 0xE0C2, 0x9272, 0xE0C7, 0x9276, 0xE478, 0x9278, 0xBBC7, 0x9279, 0xE4A4, 0x927A, 0xE47A, - 0x927B, 0xBBCC, 0x927C, 0xBBD0, 0x927D, 0xE4AD, 0x927E, 0xE4B5, 0x927F, 0xE4A6, 0x9280, 0xBBC8, 0x9282, 0xE4AA, 0x9283, 0xE0B6, - 0x9285, 0xBBC9, 0x9286, 0xE4B1, 0x9287, 0xE4B6, 0x9288, 0xE4AE, 0x928A, 0xE4B0, 0x928B, 0xE4B9, 0x928C, 0xE4B2, 0x928D, 0xE47E, - 0x928E, 0xE4A9, 0x9291, 0xBBD1, 0x9293, 0xBBCD, 0x9294, 0xE47C, 0x9295, 0xE4AB, 0x9296, 0xBBCB, 0x9297, 0xE4A5, 0x9298, 0xBBCA, - 0x9299, 0xE4B3, 0x929A, 0xE4A2, 0x929B, 0xE479, 0x929C, 0xBBCE, 0x929D, 0xE4B8, 0x92A0, 0xE47B, 0x92A1, 0xE4AF, 0x92A2, 0xE4AC, - 0x92A3, 0xE4A7, 0x92A4, 0xE477, 0x92A5, 0xE476, 0x92A6, 0xE4A1, 0x92A7, 0xE4B4, 0x92A8, 0xBBCF, 0x92A9, 0xE4B7, 0x92AA, 0xE47D, - 0x92AB, 0xE4A3, 0x92AC, 0xBE52, 0x92B2, 0xBE5A, 0x92B3, 0xBE55, 0x92B4, 0xE8A4, 0x92B5, 0xE8A1, 0x92B6, 0xE867, 0x92B7, 0xBE50, - 0x92B9, 0xF9D7, 0x92BB, 0xBE4F, 0x92BC, 0xBE56, 0x92C0, 0xE865, 0x92C1, 0xBE54, 0x92C2, 0xE871, 0x92C3, 0xE863, 0x92C4, 0xE864, - 0x92C5, 0xBE4E, 0x92C6, 0xE8A3, 0x92C7, 0xBE58, 0x92C8, 0xE874, 0x92C9, 0xE879, 0x92CA, 0xE873, 0x92CB, 0xEBEE, 0x92CC, 0xE86F, - 0x92CD, 0xE877, 0x92CE, 0xE875, 0x92CF, 0xE868, 0x92D0, 0xE862, 0x92D1, 0xE87D, 0x92D2, 0xBE57, 0x92D3, 0xE87E, 0x92D5, 0xE878, - 0x92D7, 0xE86D, 0x92D8, 0xE86B, 0x92D9, 0xE866, 0x92DD, 0xE86E, 0x92DE, 0xE87B, 0x92DF, 0xE86A, 0x92E0, 0xE87A, 0x92E1, 0xE8A2, - 0x92E4, 0xBE53, 0x92E6, 0xE876, 0x92E7, 0xE87C, 0x92E8, 0xE872, 0x92E9, 0xE86C, 0x92EA, 0xBE51, 0x92EE, 0xE4A8, 0x92EF, 0xE870, - 0x92F0, 0xBE59, 0x92F1, 0xE869, 0x92F7, 0xEBF4, 0x92F8, 0xBFF7, 0x92F9, 0xEBF3, 0x92FA, 0xEBF0, 0x92FB, 0xEC44, 0x92FC, 0xBFFB, - 0x92FE, 0xEC41, 0x92FF, 0xEBF8, 0x9300, 0xEC43, 0x9301, 0xEBE9, 0x9302, 0xEBF6, 0x9304, 0xBFFD, 0x9306, 0xEBE1, 0x9308, 0xEBDF, - 0x9309, 0xEC42, 0x930B, 0xEC40, 0x930C, 0xEBFE, 0x930D, 0xEBED, 0x930E, 0xEBEC, 0x930F, 0xEBE2, 0x9310, 0xC040, 0x9312, 0xEBE8, - 0x9313, 0xEBF2, 0x9314, 0xEBFD, 0x9315, 0xC043, 0x9316, 0xEC45, 0x9318, 0xC1E8, 0x9319, 0xC045, 0x931A, 0xBFFE, 0x931B, 0xEBE6, - 0x931D, 0xEBEF, 0x931E, 0xEBDE, 0x931F, 0xEBE0, 0x9320, 0xBFF5, 0x9321, 0xC042, 0x9322, 0xBFFA, 0x9323, 0xEBE7, 0x9324, 0xEBF7, - 0x9325, 0xEBF1, 0x9326, 0xC041, 0x9327, 0xEBDD, 0x9328, 0xC1E3, 0x9329, 0xEBF9, 0x932A, 0xEBFC, 0x932B, 0xBFFC, 0x932D, 0xEBEB, - 0x932E, 0xC044, 0x932F, 0xBFF9, 0x9333, 0xBFF8, 0x9334, 0xEBF5, 0x9335, 0xEBFB, 0x9336, 0xBFF6, 0x9338, 0xEBE4, 0x9339, 0xEBFA, - 0x933C, 0xEBE5, 0x9346, 0xEBEA, 0x9347, 0xEED2, 0x9349, 0xEED7, 0x934A, 0xC1E5, 0x934B, 0xC1E7, 0x934C, 0xEEDD, 0x934D, 0xC1E1, - 0x934E, 0xEEEC, 0x934F, 0xEEE3, 0x9350, 0xEED8, 0x9351, 0xEED9, 0x9352, 0xEEE2, 0x9354, 0xC1EE, 0x9355, 0xEEE1, 0x9356, 0xEED1, - 0x9357, 0xEEE0, 0x9358, 0xEED4, 0x9359, 0xEEED, 0x935A, 0xC1ED, 0x935B, 0xC1EB, 0x935C, 0xEED5, 0x935E, 0xEEE8, 0x9360, 0xEEDA, - 0x9361, 0xEEE7, 0x9363, 0xEEE9, 0x9364, 0xEED0, 0x9365, 0xC1E6, 0x9367, 0xEEEA, 0x936A, 0xEEDE, 0x936C, 0xC1EA, 0x936D, 0xEEDB, - 0x9370, 0xC1EC, 0x9371, 0xEEE4, 0x9375, 0xC1E4, 0x9376, 0xEED6, 0x9377, 0xEEE5, 0x9379, 0xEEDF, 0x937A, 0xEBE3, 0x937B, 0xEEE6, - 0x937C, 0xEED3, 0x937E, 0xC1E9, 0x9380, 0xEEEB, 0x9382, 0xC1E2, 0x9383, 0xEECE, 0x9388, 0xF160, 0x9389, 0xF159, 0x938A, 0xC2E9, - 0x938C, 0xF154, 0x938D, 0xF163, 0x938E, 0xF15B, 0x938F, 0xEEDC, 0x9391, 0xF165, 0x9392, 0xF155, 0x9394, 0xC2E8, 0x9395, 0xF15F, - 0x9396, 0xC2EA, 0x9397, 0xC2F2, 0x9398, 0xC2F0, 0x9399, 0xF161, 0x939A, 0xC2F1, 0x939B, 0xF157, 0x939D, 0xF158, 0x939E, 0xF15D, - 0x939F, 0xF162, 0x93A1, 0xEECD, 0x93A2, 0xC2EB, 0x93A3, 0xF16A, 0x93A4, 0xF167, 0x93A5, 0xF16B, 0x93A6, 0xF15E, 0x93A7, 0xF15A, - 0x93A8, 0xF168, 0x93A9, 0xF36A, 0x93AA, 0xF15C, 0x93AC, 0xC2EE, 0x93AE, 0xC2ED, 0x93AF, 0xEECF, 0x93B0, 0xC2EF, 0x93B1, 0xF164, - 0x93B2, 0xF166, 0x93B3, 0xC2EC, 0x93B4, 0xF169, 0x93B5, 0xF153, 0x93B7, 0xF156, 0x93C0, 0xF373, 0x93C2, 0xF363, 0x93C3, 0xC3EB, - 0x93C4, 0xF371, 0x93C7, 0xF361, 0x93C8, 0xC3EC, 0x93CA, 0xF36C, 0x93CC, 0xF368, 0x93CD, 0xC3F1, 0x93CE, 0xF372, 0x93CF, 0xF362, - 0x93D0, 0xF365, 0x93D1, 0xC3E9, 0x93D2, 0xF374, 0x93D4, 0xF36D, 0x93D5, 0xF370, 0x93D6, 0xC3EF, 0x93D7, 0xC3F4, 0x93D8, 0xC3F2, - 0x93D9, 0xF369, 0x93DA, 0xF364, 0x93DC, 0xC3ED, 0x93DD, 0xC3EE, 0x93DE, 0xF360, 0x93DF, 0xC3EA, 0x93E1, 0xC3E8, 0x93E2, 0xC3F0, - 0x93E3, 0xF36F, 0x93E4, 0xC3F3, 0x93E6, 0xF36B, 0x93E7, 0xF375, 0x93E8, 0xC3F5, 0x93EC, 0xF367, 0x93EE, 0xF36E, 0x93F5, 0xF4F3, - 0x93F6, 0xF542, 0x93F7, 0xF4F5, 0x93F8, 0xF4FC, 0x93F9, 0xF366, 0x93FA, 0xF4FA, 0x93FB, 0xF4E9, 0x93FC, 0xF540, 0x93FD, 0xC4C3, - 0x93FE, 0xF4ED, 0x93FF, 0xF4FE, 0x9400, 0xF4F4, 0x9403, 0xC4C2, 0x9406, 0xF544, 0x9407, 0xF4F6, 0x9409, 0xF4FB, 0x940A, 0xF4FD, - 0x940B, 0xF4E7, 0x940C, 0xF541, 0x940D, 0xF4F2, 0x940E, 0xF4F7, 0x940F, 0xF4EB, 0x9410, 0xF4EF, 0x9411, 0xF543, 0x9412, 0xF4F9, - 0x9413, 0xF4E8, 0x9414, 0xF4EC, 0x9415, 0xF4EE, 0x9416, 0xF4F8, 0x9418, 0xC4C1, 0x9419, 0xF4F1, 0x9420, 0xF4EA, 0x9428, 0xF4F0, - 0x9429, 0xF661, 0x942A, 0xF666, 0x942B, 0xC54F, 0x942C, 0xF668, 0x942E, 0xC549, 0x9430, 0xF664, 0x9431, 0xF66A, 0x9432, 0xC54E, - 0x9433, 0xC54A, 0x9435, 0xC54B, 0x9436, 0xF660, 0x9437, 0xF667, 0x9438, 0xC54D, 0x9439, 0xF665, 0x943A, 0xC54C, 0x943B, 0xF65F, - 0x943C, 0xF663, 0x943D, 0xF662, 0x943F, 0xF65E, 0x9440, 0xF669, 0x9444, 0xC5B1, 0x9445, 0xF76D, 0x9446, 0xF770, 0x9447, 0xF76C, - 0x9448, 0xF76E, 0x9449, 0xF76F, 0x944A, 0xF769, 0x944B, 0xF76A, 0x944C, 0xF767, 0x944F, 0xF76B, 0x9450, 0xF768, 0x9451, 0xC5B2, - 0x9452, 0xC5B3, 0x9455, 0xF84B, 0x9457, 0xF84D, 0x945D, 0xF84C, 0x945E, 0xF84E, 0x9460, 0xC5E0, 0x9462, 0xF84A, 0x9463, 0xC5DF, - 0x9464, 0xC5E1, 0x9468, 0xF8CB, 0x9469, 0xF8CC, 0x946A, 0xC644, 0x946B, 0xF8CA, 0x946D, 0xF953, 0x946E, 0xF952, 0x946F, 0xF954, - 0x9470, 0xC65F, 0x9471, 0xF955, 0x9472, 0xC65E, 0x9473, 0xF956, 0x9474, 0xF972, 0x9475, 0xF975, 0x9476, 0xF974, 0x9477, 0xC668, - 0x9478, 0xF973, 0x947C, 0xC672, 0x947D, 0xC670, 0x947E, 0xC671, 0x947F, 0xC677, 0x9480, 0xF9C0, 0x9481, 0xF9C1, 0x9482, 0xF9BF, - 0x9483, 0xF9C9, 0x9577, 0xAAF8, 0x957A, 0xD844, 0x957B, 0xDC78, 0x957C, 0xE8A5, 0x957D, 0xF376, 0x9580, 0xAAF9, 0x9582, 0xADAC, - 0x9583, 0xB07B, 0x9586, 0xD845, 0x9588, 0xD846, 0x9589, 0xB3AC, 0x958B, 0xB67D, 0x958C, 0xDC7A, 0x958D, 0xDC79, 0x958E, 0xB6A3, - 0x958F, 0xB67C, 0x9590, 0xDC7B, 0x9591, 0xB67E, 0x9592, 0xB6A2, 0x9593, 0xB6A1, 0x9594, 0xB67B, 0x9598, 0xB968, 0x959B, 0xE0D0, - 0x959C, 0xE0CE, 0x959E, 0xE0CF, 0x959F, 0xE0CD, 0x95A1, 0xBBD2, 0x95A3, 0xBBD5, 0x95A4, 0xBBD7, 0x95A5, 0xBBD6, 0x95A8, 0xBBD3, - 0x95A9, 0xBBD4, 0x95AB, 0xE8A7, 0x95AC, 0xE8A6, 0x95AD, 0xBE5B, 0x95AE, 0xE8A8, 0x95B0, 0xE8A9, 0x95B1, 0xBE5C, 0x95B5, 0xEC4D, - 0x95B6, 0xEC4B, 0x95B7, 0xEEF3, 0x95B9, 0xEC49, 0x95BA, 0xEC4A, 0x95BB, 0xC046, 0x95BC, 0xEC46, 0x95BD, 0xEC4E, 0x95BE, 0xEC48, - 0x95BF, 0xEC4C, 0x95C0, 0xEEEF, 0x95C3, 0xEEF1, 0x95C5, 0xEEF2, 0x95C6, 0xC1F3, 0x95C7, 0xEEEE, 0x95C8, 0xC1F2, 0x95C9, 0xEEF0, - 0x95CA, 0xC1EF, 0x95CB, 0xC1F0, 0x95CC, 0xC1F1, 0x95CD, 0xEC47, 0x95D0, 0xC2F5, 0x95D1, 0xF16E, 0x95D2, 0xF16C, 0x95D3, 0xF16D, - 0x95D4, 0xC2F3, 0x95D5, 0xC2F6, 0x95D6, 0xC2F4, 0x95DA, 0xF377, 0x95DB, 0xF378, 0x95DC, 0xC3F6, 0x95DE, 0xF545, 0x95DF, 0xF547, - 0x95E0, 0xF546, 0x95E1, 0xC4C4, 0x95E2, 0xC550, 0x95E3, 0xF66D, 0x95E4, 0xF66C, 0x95E5, 0xF66B, 0x961C, 0xAAFA, 0x961E, 0xC9AA, - 0x9620, 0xCA58, 0x9621, 0xA6E9, 0x9622, 0xCA56, 0x9623, 0xCA59, 0x9624, 0xCA57, 0x9628, 0xCBAE, 0x962A, 0xA8C1, 0x962C, 0xA8C2, - 0x962D, 0xCBB0, 0x962E, 0xA8BF, 0x962F, 0xCBAF, 0x9630, 0xCBAD, 0x9631, 0xA8C0, 0x9632, 0xA8BE, 0x9639, 0xCDD8, 0x963A, 0xCDDB, - 0x963B, 0xAAFD, 0x963C, 0xCDDA, 0x963D, 0xCDD9, 0x963F, 0xAAFC, 0x9640, 0xAAFB, 0x9642, 0xAB40, 0x9643, 0xCDDC, 0x9644, 0xAAFE, - 0x964A, 0xD0C6, 0x964B, 0xADAE, 0x964C, 0xADAF, 0x964D, 0xADB0, 0x964E, 0xD0C7, 0x964F, 0xD0C3, 0x9650, 0xADAD, 0x9651, 0xD0C4, - 0x9653, 0xD0C5, 0x9654, 0xD0C2, 0x9658, 0xB0A4, 0x965B, 0xB0A1, 0x965C, 0xD445, 0x965D, 0xB0A2, 0x965E, 0xB0A5, 0x965F, 0xD446, - 0x9661, 0xB07E, 0x9662, 0xB07C, 0x9663, 0xB07D, 0x9664, 0xB0A3, 0x966A, 0xB3AD, 0x966B, 0xD849, 0x966C, 0xB3B5, 0x966D, 0xD848, - 0x966F, 0xD84B, 0x9670, 0xB3B1, 0x9671, 0xD84A, 0x9672, 0xB6AB, 0x9673, 0xB3AF, 0x9674, 0xB3B2, 0x9675, 0xB3AE, 0x9676, 0xB3B3, - 0x9677, 0xB3B4, 0x9678, 0xB3B0, 0x967C, 0xD847, 0x967D, 0xB6A7, 0x967E, 0xDC7D, 0x9680, 0xDCA3, 0x9683, 0xDCA2, 0x9684, 0xB6AC, - 0x9685, 0xB6A8, 0x9686, 0xB6A9, 0x9687, 0xDC7C, 0x9688, 0xDC7E, 0x9689, 0xDCA1, 0x968A, 0xB6A4, 0x968B, 0xB6A6, 0x968D, 0xB6AA, - 0x968E, 0xB6A5, 0x9691, 0xE0D3, 0x9692, 0xE0D1, 0x9693, 0xE0D2, 0x9694, 0xB96A, 0x9695, 0xB96B, 0x9697, 0xE0D4, 0x9698, 0xB969, - 0x9699, 0xBBD8, 0x969B, 0xBBDA, 0x969C, 0xBBD9, 0x969E, 0xE4BB, 0x96A1, 0xE4BC, 0x96A2, 0xE8AB, 0x96A4, 0xE8AA, 0x96A7, 0xC047, - 0x96A8, 0xC048, 0x96A9, 0xEC4F, 0x96AA, 0xC049, 0x96AC, 0xEEF6, 0x96AE, 0xEEF4, 0x96B0, 0xEEF5, 0x96B1, 0xC1F4, 0x96B3, 0xF16F, - 0x96B4, 0xC3F7, 0x96B8, 0xC1F5, 0x96B9, 0xAB41, 0x96BB, 0xB0A6, 0x96BC, 0xD447, 0x96BF, 0xD84C, 0x96C0, 0xB3B6, 0x96C1, 0xB6AD, - 0x96C2, 0xDCA4, 0x96C3, 0xDCA6, 0x96C4, 0xB6AF, 0x96C5, 0xB6AE, 0x96C6, 0xB6B0, 0x96C7, 0xB6B1, 0x96C8, 0xDCA5, 0x96C9, 0xB96E, - 0x96CA, 0xB96F, 0x96CB, 0xB96D, 0x96CC, 0xBBDB, 0x96CD, 0xB96C, 0x96CE, 0xE0D5, 0x96D2, 0xBBDC, 0x96D3, 0xE8AC, 0x96D4, 0xEC50, - 0x96D5, 0xC04A, 0x96D6, 0xC1F6, 0x96D7, 0xF170, 0x96D8, 0xF174, 0x96D9, 0xC2F9, 0x96DA, 0xF171, 0x96DB, 0xC2FA, 0x96DC, 0xC2F8, - 0x96DD, 0xF175, 0x96DE, 0xC2FB, 0x96DF, 0xF173, 0x96E1, 0xF379, 0x96E2, 0xC2F7, 0x96E3, 0xC3F8, 0x96E5, 0xF8CD, 0x96E8, 0xAB42, - 0x96E9, 0xB3B8, 0x96EA, 0xB3B7, 0x96EF, 0xB6B2, 0x96F0, 0xDCA8, 0x96F1, 0xDCA7, 0x96F2, 0xB6B3, 0x96F5, 0xE0D9, 0x96F6, 0xB973, - 0x96F7, 0xB970, 0x96F8, 0xE0D8, 0x96F9, 0xB972, 0x96FA, 0xE0D6, 0x96FB, 0xB971, 0x96FD, 0xE0D7, 0x96FF, 0xE4BD, 0x9700, 0xBBDD, - 0x9702, 0xE8AF, 0x9704, 0xBE5D, 0x9705, 0xE8AD, 0x9706, 0xBE5E, 0x9707, 0xBE5F, 0x9708, 0xE8AE, 0x9709, 0xBE60, 0x970B, 0xEC51, - 0x970D, 0xC04E, 0x970E, 0xC04B, 0x970F, 0xC050, 0x9710, 0xEC53, 0x9711, 0xC04C, 0x9712, 0xEC52, 0x9713, 0xC04F, 0x9716, 0xC04D, - 0x9718, 0xEEF9, 0x9719, 0xEEFB, 0x971C, 0xC1F7, 0x971D, 0xEEFA, 0x971E, 0xC1F8, 0x971F, 0xEEF8, 0x9720, 0xEEF7, 0x9722, 0xF177, - 0x9723, 0xF176, 0x9724, 0xC2FC, 0x9725, 0xF178, 0x9726, 0xF37E, 0x9727, 0xC3FA, 0x9728, 0xF37D, 0x9729, 0xF37A, 0x972A, 0xC3F9, - 0x972B, 0xF37B, 0x972C, 0xF37C, 0x972E, 0xF548, 0x972F, 0xF549, 0x9730, 0xC4C5, 0x9732, 0xC553, 0x9735, 0xF66E, 0x9738, 0xC551, - 0x9739, 0xC552, 0x973A, 0xF66F, 0x973D, 0xC5B4, 0x973E, 0xC5B5, 0x973F, 0xF771, 0x9742, 0xC645, 0x9743, 0xF8CF, 0x9744, 0xC647, - 0x9746, 0xF8CE, 0x9747, 0xF8D0, 0x9748, 0xC646, 0x9749, 0xF957, 0x974B, 0xF9AD, 0x9752, 0xAB43, 0x9756, 0xB974, 0x9758, 0xE4BE, - 0x975A, 0xE8B0, 0x975B, 0xC051, 0x975C, 0xC052, 0x975E, 0xAB44, 0x9760, 0xBE61, 0x9761, 0xC3FB, 0x9762, 0xADB1, 0x9766, 0xC053, - 0x9768, 0xC5E2, 0x9769, 0xADB2, 0x976A, 0xD84D, 0x976C, 0xDCA9, 0x976E, 0xDCAB, 0x9770, 0xDCAA, 0x9772, 0xE0DD, 0x9773, 0xE0DA, - 0x9774, 0xB975, 0x9776, 0xB976, 0x9777, 0xE0DB, 0x9778, 0xE0DC, 0x977A, 0xE4C0, 0x977B, 0xE4C5, 0x977C, 0xBBDE, 0x977D, 0xE4BF, - 0x977E, 0xE4C1, 0x977F, 0xE4C8, 0x9780, 0xE4C3, 0x9781, 0xE4C7, 0x9782, 0xE4C4, 0x9783, 0xE4C2, 0x9784, 0xE4C6, 0x9785, 0xBBDF, - 0x9788, 0xE8B3, 0x978A, 0xE8B1, 0x978B, 0xBE63, 0x978D, 0xBE62, 0x978E, 0xE8B2, 0x978F, 0xBE64, 0x9794, 0xEC56, 0x9797, 0xEC55, - 0x9798, 0xC054, 0x9799, 0xEC54, 0x979A, 0xEEFC, 0x979C, 0xEEFE, 0x979D, 0xEF41, 0x979E, 0xEF40, 0x97A0, 0xC1F9, 0x97A1, 0xEEFD, - 0x97A2, 0xF1A1, 0x97A3, 0xC2FD, 0x97A4, 0xF17D, 0x97A5, 0xF1A2, 0x97A6, 0xC2FE, 0x97A8, 0xF17B, 0x97AA, 0xF17E, 0x97AB, 0xF17C, - 0x97AC, 0xF179, 0x97AD, 0xC340, 0x97AE, 0xF17A, 0x97B3, 0xF3A1, 0x97B6, 0xF3A3, 0x97B7, 0xF3A2, 0x97B9, 0xF54A, 0x97BB, 0xF54B, - 0x97BF, 0xF670, 0x97C1, 0xC5B7, 0x97C3, 0xC5B6, 0x97C4, 0xF84F, 0x97C5, 0xF850, 0x97C6, 0xC648, 0x97C7, 0xF8D1, 0x97C9, 0xC669, - 0x97CB, 0xADB3, 0x97CC, 0xB6B4, 0x97CD, 0xE4CA, 0x97CE, 0xE4C9, 0x97CF, 0xE8B5, 0x97D0, 0xE8B4, 0x97D3, 0xC1FA, 0x97D4, 0xEF43, - 0x97D5, 0xEF42, 0x97D6, 0xF1A5, 0x97D7, 0xF1A3, 0x97D8, 0xF1A6, 0x97D9, 0xF1A4, 0x97DC, 0xC3FC, 0x97DD, 0xF3A4, 0x97DE, 0xF3A5, - 0x97DF, 0xF3A6, 0x97E1, 0xF671, 0x97E3, 0xF772, 0x97E5, 0xF8D2, 0x97ED, 0xADB4, 0x97F0, 0xEC57, 0x97F1, 0xEF44, 0x97F3, 0xADB5, - 0x97F6, 0xBBE0, 0x97F8, 0xEC58, 0x97F9, 0xC341, 0x97FA, 0xF1A7, 0x97FB, 0xC3FD, 0x97FD, 0xF54C, 0x97FE, 0xF54D, 0x97FF, 0xC554, - 0x9800, 0xF851, 0x9801, 0xADB6, 0x9802, 0xB3BB, 0x9803, 0xB3BC, 0x9804, 0xD84E, 0x9805, 0xB6B5, 0x9806, 0xB6B6, 0x9807, 0xDCAC, - 0x9808, 0xB6B7, 0x980A, 0xB97A, 0x980C, 0xB97C, 0x980D, 0xE0DF, 0x980E, 0xE0E0, 0x980F, 0xE0DE, 0x9810, 0xB977, 0x9811, 0xB978, - 0x9812, 0xB97B, 0x9813, 0xB979, 0x9816, 0xE4CB, 0x9817, 0xBBE1, 0x9818, 0xBBE2, 0x981B, 0xE8BC, 0x981C, 0xBE67, 0x981D, 0xE8B7, - 0x981E, 0xE8B6, 0x9820, 0xE8BB, 0x9821, 0xBE65, 0x9824, 0xC05B, 0x9826, 0xE8B8, 0x9827, 0xE8BD, 0x9828, 0xE8BA, 0x9829, 0xE8B9, - 0x982B, 0xBE66, 0x982D, 0xC059, 0x982F, 0xEC5A, 0x9830, 0xC055, 0x9832, 0xEC5B, 0x9835, 0xEC59, 0x9837, 0xC058, 0x9838, 0xC056, - 0x9839, 0xC05A, 0x983B, 0xC057, 0x9841, 0xEF45, 0x9843, 0xEF4A, 0x9844, 0xEF46, 0x9845, 0xEF49, 0x9846, 0xC1FB, 0x9848, 0xEDD4, - 0x9849, 0xEF48, 0x984A, 0xEF47, 0x984C, 0xC344, 0x984D, 0xC342, 0x984E, 0xC345, 0x984F, 0xC343, 0x9850, 0xF1A8, 0x9851, 0xF1A9, - 0x9852, 0xF1AA, 0x9853, 0xC346, 0x9857, 0xF3AA, 0x9858, 0xC440, 0x9859, 0xF3A8, 0x985B, 0xC441, 0x985C, 0xF3A7, 0x985D, 0xF3A9, - 0x985E, 0xC3FE, 0x985F, 0xF551, 0x9860, 0xF54E, 0x9862, 0xF54F, 0x9863, 0xF550, 0x9864, 0xF672, 0x9865, 0xC556, 0x9867, 0xC555, - 0x9869, 0xF774, 0x986A, 0xF773, 0x986B, 0xC5B8, 0x986F, 0xC5E3, 0x9870, 0xC649, 0x9871, 0xC660, 0x9872, 0xF958, 0x9873, 0xF9AE, - 0x9874, 0xF9AF, 0x98A8, 0xADB7, 0x98A9, 0xDCAD, 0x98AC, 0xE0E1, 0x98AD, 0xE4CC, 0x98AE, 0xE4CD, 0x98AF, 0xBBE3, 0x98B1, 0xBBE4, - 0x98B2, 0xE8BE, 0x98B3, 0xBE68, 0x98B6, 0xC1FC, 0x98B8, 0xF1AB, 0x98BA, 0xC347, 0x98BB, 0xF3AD, 0x98BC, 0xC442, 0x98BD, 0xF3AC, - 0x98BE, 0xF3AE, 0x98BF, 0xF3AB, 0x98C0, 0xF675, 0x98C1, 0xF552, 0x98C2, 0xF553, 0x98C4, 0xC4C6, 0x98C6, 0xF674, 0x98C9, 0xF673, - 0x98CB, 0xF775, 0x98CC, 0xF9B0, 0x98DB, 0xADB8, 0x98DF, 0xADB9, 0x98E2, 0xB0A7, 0x98E3, 0xD448, 0x98E5, 0xD84F, 0x98E7, 0xB6B8, - 0x98E9, 0xB6BB, 0x98EA, 0xB6B9, 0x98EB, 0xDCAE, 0x98ED, 0xB6BD, 0x98EF, 0xB6BA, 0x98F2, 0xB6BC, 0x98F4, 0xB97E, 0x98F6, 0xE0E2, - 0x98F9, 0xE0E3, 0x98FA, 0xE8C0, 0x98FC, 0xB97D, 0x98FD, 0xB9A1, 0x98FE, 0xB9A2, 0x9900, 0xE4CF, 0x9902, 0xE4CE, 0x9903, 0xBBE5, - 0x9905, 0xBBE6, 0x9907, 0xE4D0, 0x9908, 0xE8BF, 0x9909, 0xBBE8, 0x990A, 0xBE69, 0x990C, 0xBBE7, 0x9910, 0xC05C, 0x9911, 0xE8C1, - 0x9912, 0xBE6B, 0x9913, 0xBE6A, 0x9914, 0xE8C2, 0x9915, 0xE8C5, 0x9916, 0xE8C3, 0x9917, 0xE8C4, 0x9918, 0xBE6C, 0x991A, 0xC061, - 0x991B, 0xC05F, 0x991E, 0xC05E, 0x991F, 0xEC5D, 0x9921, 0xC060, 0x9924, 0xEC5C, 0x9925, 0xEF4B, 0x9927, 0xEC5E, 0x9928, 0xC05D, - 0x9929, 0xEC5F, 0x992A, 0xEF4E, 0x992B, 0xEF4C, 0x992C, 0xEF4D, 0x992D, 0xEF52, 0x992E, 0xC34B, 0x992F, 0xEF51, 0x9930, 0xEF54, - 0x9931, 0xEF53, 0x9932, 0xEF50, 0x9933, 0xEF4F, 0x9935, 0xC1FD, 0x993A, 0xF1AE, 0x993C, 0xF1AD, 0x993D, 0xC34A, 0x993E, 0xC348, - 0x993F, 0xC349, 0x9941, 0xF1AC, 0x9943, 0xF3B1, 0x9945, 0xC443, 0x9947, 0xF3B0, 0x9948, 0xF3AF, 0x9949, 0xC444, 0x994B, 0xF558, - 0x994C, 0xF557, 0x994E, 0xF555, 0x9950, 0xF554, 0x9951, 0xC4C8, 0x9952, 0xC4C7, 0x9953, 0xF559, 0x9954, 0xF776, 0x9955, 0xC5B9, - 0x9956, 0xF677, 0x9957, 0xC557, 0x9958, 0xF676, 0x9959, 0xF556, 0x995B, 0xF777, 0x995C, 0xC5E4, 0x995E, 0xC661, 0x995F, 0xF959, - 0x9961, 0xF9B1, 0x9996, 0xADBA, 0x9997, 0xD850, 0x9998, 0xEF55, 0x9999, 0xADBB, 0x999C, 0xE4D2, 0x999D, 0xE4D1, 0x999E, 0xEC60, - 0x99A1, 0xEF57, 0x99A3, 0xEF56, 0x99A5, 0xC34C, 0x99A6, 0xF3B2, 0x99A7, 0xF3B3, 0x99A8, 0xC4C9, 0x99AB, 0xF9B2, 0x99AC, 0xB0A8, - 0x99AD, 0xB6BF, 0x99AE, 0xB6BE, 0x99AF, 0xE0E4, 0x99B0, 0xE0E6, 0x99B1, 0xB9A4, 0x99B2, 0xE0E5, 0x99B3, 0xB9A3, 0x99B4, 0xB9A5, - 0x99B5, 0xE0E7, 0x99B9, 0xE4D4, 0x99BA, 0xE4D6, 0x99BB, 0xE4D5, 0x99BD, 0xE4D8, 0x99C1, 0xBBE9, 0x99C2, 0xE4D7, 0x99C3, 0xE4D3, - 0x99C7, 0xE4D9, 0x99C9, 0xE8CC, 0x99CB, 0xE8CF, 0x99CC, 0xE8D1, 0x99CD, 0xE8C7, 0x99CE, 0xE8CB, 0x99CF, 0xE8C8, 0x99D0, 0xBE6E, - 0x99D1, 0xBE71, 0x99D2, 0xBE73, 0x99D3, 0xE8C9, 0x99D4, 0xE8CA, 0x99D5, 0xBE72, 0x99D6, 0xE8CD, 0x99D7, 0xE8D0, 0x99D8, 0xE8CE, - 0x99D9, 0xBE74, 0x99DB, 0xBE70, 0x99DC, 0xE8C6, 0x99DD, 0xBE6D, 0x99DF, 0xBE6F, 0x99E2, 0xC063, 0x99E3, 0xEC66, 0x99E4, 0xEC64, - 0x99E5, 0xEC63, 0x99E7, 0xEC69, 0x99E9, 0xEC68, 0x99EA, 0xEC67, 0x99EC, 0xEC62, 0x99ED, 0xC062, 0x99EE, 0xEC61, 0x99F0, 0xEC65, - 0x99F1, 0xC064, 0x99F4, 0xEF5A, 0x99F6, 0xEF5E, 0x99F7, 0xEF5B, 0x99F8, 0xEF5D, 0x99F9, 0xEF5C, 0x99FA, 0xEF59, 0x99FB, 0xEF5F, - 0x99FC, 0xEF62, 0x99FD, 0xEF60, 0x99FE, 0xEF61, 0x99FF, 0xC240, 0x9A01, 0xC1FE, 0x9A02, 0xEF58, 0x9A03, 0xEF63, 0x9A04, 0xF1B3, - 0x9A05, 0xF1B6, 0x9A06, 0xF1B8, 0x9A07, 0xF1B7, 0x9A09, 0xF1B1, 0x9A0A, 0xF1B5, 0x9A0B, 0xF1B0, 0x9A0D, 0xF1B2, 0x9A0E, 0xC34D, - 0x9A0F, 0xF1AF, 0x9A11, 0xF1B4, 0x9A14, 0xF3C0, 0x9A15, 0xF3B5, 0x9A16, 0xC445, 0x9A19, 0xC446, 0x9A1A, 0xF3B4, 0x9A1B, 0xF3B9, - 0x9A1C, 0xF3BF, 0x9A1D, 0xF3B7, 0x9A1E, 0xF3BE, 0x9A20, 0xF3BB, 0x9A22, 0xF3BA, 0x9A23, 0xF3BD, 0x9A24, 0xF3B8, 0x9A25, 0xF3B6, - 0x9A27, 0xF3BC, 0x9A29, 0xF560, 0x9A2A, 0xF55E, 0x9A2B, 0xC4CA, 0x9A2C, 0xF55D, 0x9A2D, 0xF563, 0x9A2E, 0xF561, 0x9A30, 0xC4CB, - 0x9A31, 0xF55C, 0x9A32, 0xF55A, 0x9A34, 0xF55B, 0x9A35, 0xC4CD, 0x9A36, 0xF55F, 0x9A37, 0xC4CC, 0x9A38, 0xF562, 0x9A39, 0xF678, - 0x9A3A, 0xF67E, 0x9A3D, 0xF679, 0x9A3E, 0xC55B, 0x9A3F, 0xF6A1, 0x9A40, 0xC55A, 0x9A41, 0xF67D, 0x9A42, 0xF67C, 0x9A43, 0xC559, - 0x9A44, 0xF67B, 0x9A45, 0xC558, 0x9A46, 0xF67A, 0x9A48, 0xF77D, 0x9A49, 0xF7A1, 0x9A4A, 0xF77E, 0x9A4C, 0xF77B, 0x9A4D, 0xC5BB, - 0x9A4E, 0xF778, 0x9A4F, 0xF77C, 0x9A50, 0xF7A3, 0x9A52, 0xF7A2, 0x9A53, 0xF779, 0x9A54, 0xF77A, 0x9A55, 0xC5BA, 0x9A56, 0xF852, - 0x9A57, 0xC5E7, 0x9A59, 0xF853, 0x9A5A, 0xC5E5, 0x9A5B, 0xC5E6, 0x9A5E, 0xF8D3, 0x9A5F, 0xC64A, 0x9A60, 0xF976, 0x9A62, 0xC66A, - 0x9A64, 0xF9B3, 0x9A65, 0xC66B, 0x9A66, 0xF9B4, 0x9A67, 0xF9B5, 0x9A68, 0xF9C3, 0x9A69, 0xF9C2, 0x9A6A, 0xC67A, 0x9A6B, 0xF9CD, - 0x9AA8, 0xB0A9, 0x9AAB, 0xE0E9, 0x9AAD, 0xE0E8, 0x9AAF, 0xBBEA, 0x9AB0, 0xBBEB, 0x9AB1, 0xE4DA, 0x9AB3, 0xE8D2, 0x9AB4, 0xEC6C, - 0x9AB7, 0xBE75, 0x9AB8, 0xC065, 0x9AB9, 0xEC6A, 0x9ABB, 0xEC6D, 0x9ABC, 0xC066, 0x9ABE, 0xEF64, 0x9ABF, 0xEC6B, 0x9AC0, 0xF1B9, - 0x9AC1, 0xC34E, 0x9AC2, 0xF3C1, 0x9AC6, 0xF566, 0x9AC7, 0xF564, 0x9ACA, 0xF565, 0x9ACD, 0xF6A2, 0x9ACF, 0xC55C, 0x9AD0, 0xF7A4, - 0x9AD1, 0xC5EA, 0x9AD2, 0xC5BC, 0x9AD3, 0xC5E8, 0x9AD4, 0xC5E9, 0x9AD5, 0xF8D4, 0x9AD6, 0xC662, 0x9AD8, 0xB0AA, 0x9ADC, 0xF1BA, - 0x9ADF, 0xD449, 0x9AE1, 0xB9A6, 0x9AE3, 0xE4DB, 0x9AE6, 0xBBEC, 0x9AE7, 0xE4DC, 0x9AEB, 0xE8D4, 0x9AEC, 0xE8D3, 0x9AED, 0xC068, - 0x9AEE, 0xBE76, 0x9AEF, 0xBE77, 0x9AF1, 0xE8D7, 0x9AF2, 0xE8D6, 0x9AF3, 0xE8D5, 0x9AF6, 0xEC6E, 0x9AF7, 0xEC71, 0x9AF9, 0xEC70, - 0x9AFA, 0xEC6F, 0x9AFB, 0xC067, 0x9AFC, 0xEF68, 0x9AFD, 0xEF66, 0x9AFE, 0xEF65, 0x9B01, 0xEF67, 0x9B03, 0xC34F, 0x9B04, 0xF1BC, - 0x9B05, 0xF1BD, 0x9B06, 0xC350, 0x9B08, 0xF1BB, 0x9B0A, 0xF3C3, 0x9B0B, 0xF3C2, 0x9B0C, 0xF3C5, 0x9B0D, 0xC447, 0x9B0E, 0xF3C4, - 0x9B10, 0xF567, 0x9B11, 0xF569, 0x9B12, 0xF568, 0x9B15, 0xF6A3, 0x9B16, 0xF6A6, 0x9B17, 0xF6A4, 0x9B18, 0xF6A5, 0x9B19, 0xF7A5, - 0x9B1A, 0xC5BD, 0x9B1E, 0xF854, 0x9B1F, 0xF855, 0x9B20, 0xF856, 0x9B22, 0xC64B, 0x9B23, 0xC663, 0x9B24, 0xF9B6, 0x9B25, 0xB0AB, - 0x9B27, 0xBE78, 0x9B28, 0xC069, 0x9B29, 0xF1BE, 0x9B2B, 0xF7A6, 0x9B2E, 0xF9C4, 0x9B2F, 0xD44A, 0x9B31, 0xC67B, 0x9B32, 0xB0AC, - 0x9B33, 0xEC72, 0x9B35, 0xF1BF, 0x9B37, 0xF3C6, 0x9B3A, 0xF6A7, 0x9B3B, 0xF7A7, 0x9B3C, 0xB0AD, 0x9B3E, 0xE4DD, 0x9B3F, 0xE4DE, - 0x9B41, 0xBBED, 0x9B42, 0xBBEE, 0x9B43, 0xE8D9, 0x9B44, 0xBE7A, 0x9B45, 0xBE79, 0x9B46, 0xE8D8, 0x9B48, 0xEF69, 0x9B4A, 0xF1C0, - 0x9B4B, 0xF1C2, 0x9B4C, 0xF1C1, 0x9B4D, 0xC353, 0x9B4E, 0xC352, 0x9B4F, 0xC351, 0x9B51, 0xC55E, 0x9B52, 0xF6A8, 0x9B54, 0xC55D, - 0x9B55, 0xF7A9, 0x9B56, 0xF7A8, 0x9B58, 0xC64C, 0x9B59, 0xF8D5, 0x9B5A, 0xB3BD, 0x9B5B, 0xE0EA, 0x9B5F, 0xE4E1, 0x9B60, 0xE4DF, - 0x9B61, 0xE4E0, 0x9B64, 0xE8E2, 0x9B66, 0xE8DD, 0x9B67, 0xE8DA, 0x9B68, 0xE8E1, 0x9B6C, 0xE8E3, 0x9B6F, 0xBE7C, 0x9B70, 0xE8E0, - 0x9B71, 0xE8DC, 0x9B74, 0xE8DB, 0x9B75, 0xE8DF, 0x9B76, 0xE8DE, 0x9B77, 0xBE7B, 0x9B7A, 0xEC7D, 0x9B7B, 0xEC78, 0x9B7C, 0xEC76, - 0x9B7D, 0xECA1, 0x9B7E, 0xEC77, 0x9B80, 0xEC73, 0x9B82, 0xEC79, 0x9B85, 0xEC74, 0x9B86, 0xEF72, 0x9B87, 0xEC75, 0x9B88, 0xECA2, - 0x9B90, 0xEC7C, 0x9B91, 0xC06A, 0x9B92, 0xEC7B, 0x9B93, 0xEC7A, 0x9B95, 0xEC7E, 0x9B9A, 0xEF6A, 0x9B9B, 0xEF6D, 0x9B9E, 0xEF6C, - 0x9BA0, 0xEF74, 0x9BA1, 0xEF6F, 0x9BA2, 0xEF73, 0x9BA4, 0xEF71, 0x9BA5, 0xEF70, 0x9BA6, 0xEF6E, 0x9BA8, 0xEF6B, 0x9BAA, 0xC243, - 0x9BAB, 0xC242, 0x9BAD, 0xC244, 0x9BAE, 0xC241, 0x9BAF, 0xEF75, 0x9BB5, 0xF1C8, 0x9BB6, 0xF1CB, 0x9BB8, 0xF1C9, 0x9BB9, 0xF1CD, - 0x9BBD, 0xF1CE, 0x9BBF, 0xF1C6, 0x9BC0, 0xC358, 0x9BC1, 0xF1C7, 0x9BC3, 0xF1C5, 0x9BC4, 0xF1CC, 0x9BC6, 0xF1C4, 0x9BC7, 0xF1C3, - 0x9BC8, 0xC357, 0x9BC9, 0xC355, 0x9BCA, 0xC354, 0x9BD3, 0xF1CA, 0x9BD4, 0xF3CF, 0x9BD5, 0xF3D5, 0x9BD6, 0xC44A, 0x9BD7, 0xF3D0, - 0x9BD9, 0xF3D3, 0x9BDA, 0xF3D7, 0x9BDB, 0xC44B, 0x9BDC, 0xF3D2, 0x9BDE, 0xF3CA, 0x9BE0, 0xF3C9, 0x9BE1, 0xF3D6, 0x9BE2, 0xF3CD, - 0x9BE4, 0xF3CB, 0x9BE5, 0xF3D4, 0x9BE6, 0xF3CC, 0x9BE7, 0xC449, 0x9BE8, 0xC448, 0x9BEA, 0xF3C7, 0x9BEB, 0xF3C8, 0x9BEC, 0xF3D1, - 0x9BF0, 0xF3CE, 0x9BF7, 0xF56C, 0x9BF8, 0xF56F, 0x9BFD, 0xC356, 0x9C05, 0xF56D, 0x9C06, 0xF573, 0x9C07, 0xF571, 0x9C08, 0xF56B, - 0x9C09, 0xF576, 0x9C0B, 0xF56A, 0x9C0D, 0xC4CF, 0x9C0E, 0xF572, 0x9C12, 0xF56E, 0x9C13, 0xC4CE, 0x9C14, 0xF575, 0x9C17, 0xF574, - 0x9C1C, 0xF6AB, 0x9C1D, 0xF6AA, 0x9C21, 0xF6B1, 0x9C23, 0xF6AD, 0x9C24, 0xF6B0, 0x9C25, 0xC560, 0x9C28, 0xF6AE, 0x9C29, 0xF6AF, - 0x9C2B, 0xF6A9, 0x9C2C, 0xF6AC, 0x9C2D, 0xC55F, 0x9C31, 0xC5BF, 0x9C32, 0xF7B4, 0x9C33, 0xF7AF, 0x9C34, 0xF7B3, 0x9C36, 0xF7B6, - 0x9C37, 0xF7B2, 0x9C39, 0xF7AE, 0x9C3B, 0xC5C1, 0x9C3C, 0xF7B1, 0x9C3D, 0xF7B5, 0x9C3E, 0xC5C0, 0x9C3F, 0xF7AC, 0x9C40, 0xF570, - 0x9C41, 0xF7B0, 0x9C44, 0xF7AD, 0x9C46, 0xF7AA, 0x9C48, 0xF7AB, 0x9C49, 0xC5BE, 0x9C4A, 0xF85A, 0x9C4B, 0xF85C, 0x9C4C, 0xF85F, - 0x9C4D, 0xF85B, 0x9C4E, 0xF860, 0x9C50, 0xF859, 0x9C52, 0xF857, 0x9C54, 0xC5EB, 0x9C55, 0xF85D, 0x9C56, 0xC5ED, 0x9C57, 0xC5EC, - 0x9C58, 0xF858, 0x9C59, 0xF85E, 0x9C5E, 0xF8DA, 0x9C5F, 0xC64D, 0x9C60, 0xF8DB, 0x9C62, 0xF8D9, 0x9C63, 0xF8D6, 0x9C66, 0xF8D8, - 0x9C67, 0xF8D7, 0x9C68, 0xF95A, 0x9C6D, 0xF95C, 0x9C6E, 0xF95B, 0x9C71, 0xF979, 0x9C73, 0xF978, 0x9C74, 0xF977, 0x9C75, 0xF97A, - 0x9C77, 0xC673, 0x9C78, 0xC674, 0x9C79, 0xF9CA, 0x9C7A, 0xF9CE, 0x9CE5, 0xB3BE, 0x9CE6, 0xDCAF, 0x9CE7, 0xE0ED, 0x9CE9, 0xB9A7, - 0x9CEA, 0xE0EB, 0x9CED, 0xE0EC, 0x9CF1, 0xE4E2, 0x9CF2, 0xE4E3, 0x9CF3, 0xBBF1, 0x9CF4, 0xBBEF, 0x9CF5, 0xE4E4, 0x9CF6, 0xBBF0, - 0x9CF7, 0xE8E8, 0x9CF9, 0xE8EB, 0x9CFA, 0xE8E5, 0x9CFB, 0xE8EC, 0x9CFC, 0xE8E4, 0x9CFD, 0xE8E6, 0x9CFF, 0xE8E7, 0x9D00, 0xE8EA, - 0x9D03, 0xBEA1, 0x9D04, 0xE8EF, 0x9D05, 0xE8EE, 0x9D06, 0xBE7D, 0x9D07, 0xE8E9, 0x9D08, 0xE8ED, 0x9D09, 0xBE7E, 0x9D10, 0xECAC, - 0x9D12, 0xC06F, 0x9D14, 0xECA7, 0x9D15, 0xC06B, 0x9D17, 0xECA4, 0x9D18, 0xECAA, 0x9D19, 0xECAD, 0x9D1B, 0xC070, 0x9D1D, 0xECA9, - 0x9D1E, 0xECA6, 0x9D1F, 0xECAE, 0x9D20, 0xECA5, 0x9D22, 0xECAB, 0x9D23, 0xC06C, 0x9D25, 0xECA3, 0x9D26, 0xC06D, 0x9D28, 0xC06E, - 0x9D29, 0xECA8, 0x9D2D, 0xEFA9, 0x9D2E, 0xEF7A, 0x9D2F, 0xEF7B, 0x9D30, 0xEF7E, 0x9D31, 0xEF7C, 0x9D33, 0xEF76, 0x9D36, 0xEF79, - 0x9D37, 0xEFA5, 0x9D38, 0xEF7D, 0x9D3B, 0xC245, 0x9D3D, 0xEFA7, 0x9D3E, 0xEFA4, 0x9D3F, 0xC246, 0x9D40, 0xEFA6, 0x9D41, 0xEF77, - 0x9D42, 0xEFA2, 0x9D43, 0xEFA3, 0x9D45, 0xEFA1, 0x9D4A, 0xF1D2, 0x9D4B, 0xF1D4, 0x9D4C, 0xF1D7, 0x9D4F, 0xF1D1, 0x9D51, 0xC359, - 0x9D52, 0xF1D9, 0x9D53, 0xF1D0, 0x9D54, 0xF1DA, 0x9D56, 0xF1D6, 0x9D57, 0xF1D8, 0x9D58, 0xF1DC, 0x9D59, 0xF1D5, 0x9D5A, 0xF1DD, - 0x9D5B, 0xF1D3, 0x9D5C, 0xF1CF, 0x9D5D, 0xC35A, 0x9D5F, 0xF1DB, 0x9D60, 0xC35B, 0x9D61, 0xC44D, 0x9D67, 0xEF78, 0x9D68, 0xF3F1, - 0x9D69, 0xF3E8, 0x9D6A, 0xC44F, 0x9D6B, 0xF3E4, 0x9D6C, 0xC450, 0x9D6F, 0xF3ED, 0x9D70, 0xF3E7, 0x9D71, 0xF3DD, 0x9D72, 0xC44E, - 0x9D73, 0xF3EA, 0x9D74, 0xF3E5, 0x9D75, 0xF3E6, 0x9D77, 0xF3D8, 0x9D78, 0xF3DF, 0x9D79, 0xF3EE, 0x9D7B, 0xF3EB, 0x9D7D, 0xF3E3, - 0x9D7F, 0xF3EF, 0x9D80, 0xF3DE, 0x9D81, 0xF3D9, 0x9D82, 0xF3EC, 0x9D84, 0xF3DB, 0x9D85, 0xF3E9, 0x9D86, 0xF3E0, 0x9D87, 0xF3F0, - 0x9D88, 0xF3DC, 0x9D89, 0xC44C, 0x9D8A, 0xF3DA, 0x9D8B, 0xF3E1, 0x9D8C, 0xF3E2, 0x9D90, 0xF57D, 0x9D92, 0xF57B, 0x9D94, 0xF5A2, - 0x9D96, 0xF5AE, 0x9D97, 0xF5A5, 0x9D98, 0xF57C, 0x9D99, 0xF578, 0x9D9A, 0xF5A7, 0x9D9B, 0xF57E, 0x9D9C, 0xF5A3, 0x9D9D, 0xF57A, - 0x9D9E, 0xF5AA, 0x9D9F, 0xF577, 0x9DA0, 0xF5A1, 0x9DA1, 0xF5A6, 0x9DA2, 0xF5A8, 0x9DA3, 0xF5AB, 0x9DA4, 0xF579, 0x9DA6, 0xF5AF, - 0x9DA7, 0xF5B0, 0x9DA8, 0xF5A9, 0x9DA9, 0xF5AD, 0x9DAA, 0xF5A4, 0x9DAC, 0xF6C1, 0x9DAD, 0xF6C4, 0x9DAF, 0xC561, 0x9DB1, 0xF6C3, - 0x9DB2, 0xF6C8, 0x9DB3, 0xF6C6, 0x9DB4, 0xC562, 0x9DB5, 0xF6BD, 0x9DB6, 0xF6B3, 0x9DB7, 0xF6B2, 0x9DB8, 0xC564, 0x9DB9, 0xF6BF, - 0x9DBA, 0xF6C0, 0x9DBB, 0xF6BC, 0x9DBC, 0xF6B4, 0x9DBE, 0xF6B9, 0x9DBF, 0xF5AC, 0x9DC1, 0xF6B5, 0x9DC2, 0xC563, 0x9DC3, 0xF6BB, - 0x9DC5, 0xF6BA, 0x9DC7, 0xF6B6, 0x9DC8, 0xF6C2, 0x9DCA, 0xF6B7, 0x9DCB, 0xF7BB, 0x9DCC, 0xF6C5, 0x9DCD, 0xF6C7, 0x9DCE, 0xF6BE, - 0x9DCF, 0xF6B8, 0x9DD0, 0xF7BC, 0x9DD1, 0xF7BE, 0x9DD2, 0xF7B8, 0x9DD3, 0xC5C2, 0x9DD5, 0xF7C5, 0x9DD6, 0xF7C3, 0x9DD7, 0xC5C3, - 0x9DD8, 0xF7C2, 0x9DD9, 0xF7C1, 0x9DDA, 0xF7BA, 0x9DDB, 0xF7B7, 0x9DDC, 0xF7BD, 0x9DDD, 0xF7C6, 0x9DDE, 0xF7B9, 0x9DDF, 0xF7BF, - 0x9DE1, 0xF869, 0x9DE2, 0xF86E, 0x9DE3, 0xF864, 0x9DE4, 0xF867, 0x9DE5, 0xC5EE, 0x9DE6, 0xF86B, 0x9DE8, 0xF872, 0x9DE9, 0xF7C0, - 0x9DEB, 0xF865, 0x9DEC, 0xF86F, 0x9DED, 0xF873, 0x9DEE, 0xF86A, 0x9DEF, 0xF863, 0x9DF0, 0xF86D, 0x9DF2, 0xF86C, 0x9DF3, 0xF871, - 0x9DF4, 0xF870, 0x9DF5, 0xF7C4, 0x9DF6, 0xF868, 0x9DF7, 0xF862, 0x9DF8, 0xF866, 0x9DF9, 0xC64E, 0x9DFA, 0xC64F, 0x9DFB, 0xF861, - 0x9DFD, 0xF8E6, 0x9DFE, 0xF8DD, 0x9DFF, 0xF8E5, 0x9E00, 0xF8E2, 0x9E01, 0xF8E3, 0x9E02, 0xF8DC, 0x9E03, 0xF8DF, 0x9E04, 0xF8E7, - 0x9E05, 0xF8E1, 0x9E06, 0xF8E0, 0x9E07, 0xF8DE, 0x9E09, 0xF8E4, 0x9E0B, 0xF95D, 0x9E0D, 0xF95E, 0x9E0F, 0xF960, 0x9E10, 0xF95F, - 0x9E11, 0xF962, 0x9E12, 0xF961, 0x9E13, 0xF97C, 0x9E14, 0xF97B, 0x9E15, 0xF9B7, 0x9E17, 0xF9B8, 0x9E19, 0xF9C5, 0x9E1A, 0xC678, - 0x9E1B, 0xC67C, 0x9E1D, 0xF9CF, 0x9E1E, 0xC67D, 0x9E75, 0xB3BF, 0x9E79, 0xC4D0, 0x9E7A, 0xF6C9, 0x9E7C, 0xC650, 0x9E7D, 0xC651, - 0x9E7F, 0xB3C0, 0x9E80, 0xE0EE, 0x9E82, 0xB9A8, 0x9E83, 0xE8F0, 0x9E86, 0xECB0, 0x9E87, 0xECB1, 0x9E88, 0xECAF, 0x9E89, 0xEFAB, - 0x9E8A, 0xEFAA, 0x9E8B, 0xC247, 0x9E8C, 0xF1DF, 0x9E8D, 0xEFAC, 0x9E8E, 0xF1DE, 0x9E91, 0xF3F3, 0x9E92, 0xC451, 0x9E93, 0xC453, - 0x9E94, 0xF3F2, 0x9E97, 0xC452, 0x9E99, 0xF5B1, 0x9E9A, 0xF5B3, 0x9E9B, 0xF5B2, 0x9E9C, 0xF6CA, 0x9E9D, 0xC565, 0x9E9F, 0xC5EF, - 0x9EA0, 0xF8E8, 0x9EA1, 0xF963, 0x9EA4, 0xF9D2, 0x9EA5, 0xB3C1, 0x9EA7, 0xE4E5, 0x9EA9, 0xBEA2, 0x9EAD, 0xECB3, 0x9EAE, 0xECB2, - 0x9EB0, 0xEFAD, 0x9EB4, 0xC454, 0x9EB5, 0xC4D1, 0x9EB6, 0xF7C7, 0x9EB7, 0xF9CB, 0x9EBB, 0xB3C2, 0x9EBC, 0xBBF2, 0x9EBE, 0xBEA3, - 0x9EC0, 0xF3F4, 0x9EC2, 0xF874, 0x9EC3, 0xB6C0, 0x9EC8, 0xEFAE, 0x9ECC, 0xC664, 0x9ECD, 0xB6C1, 0x9ECE, 0xBEA4, 0x9ECF, 0xC248, - 0x9ED0, 0xF875, 0x9ED1, 0xB6C2, 0x9ED3, 0xE8F1, 0x9ED4, 0xC072, 0x9ED5, 0xECB4, 0x9ED6, 0xECB5, 0x9ED8, 0xC071, 0x9EDA, 0xEFAF, - 0x9EDB, 0xC24C, 0x9EDC, 0xC24A, 0x9EDD, 0xC24B, 0x9EDE, 0xC249, 0x9EDF, 0xF1E0, 0x9EE0, 0xC35C, 0x9EE4, 0xF5B5, 0x9EE5, 0xF5B4, - 0x9EE6, 0xF5B7, 0x9EE7, 0xF5B6, 0x9EE8, 0xC4D2, 0x9EEB, 0xF6CB, 0x9EED, 0xF6CD, 0x9EEE, 0xF6CC, 0x9EEF, 0xC566, 0x9EF0, 0xF7C8, - 0x9EF2, 0xF876, 0x9EF3, 0xF877, 0x9EF4, 0xC5F0, 0x9EF5, 0xF964, 0x9EF6, 0xF97D, 0x9EF7, 0xC675, 0x9EF9, 0xDCB0, 0x9EFA, 0xECB6, - 0x9EFB, 0xEFB0, 0x9EFC, 0xF3F5, 0x9EFD, 0xE0EF, 0x9EFF, 0xEFB1, 0x9F00, 0xF1E2, 0x9F01, 0xF1E1, 0x9F06, 0xF878, 0x9F07, 0xC652, - 0x9F09, 0xF965, 0x9F0A, 0xF97E, 0x9F0E, 0xB9A9, 0x9F0F, 0xE8F2, 0x9F10, 0xE8F3, 0x9F12, 0xECB7, 0x9F13, 0xB9AA, 0x9F15, 0xC35D, - 0x9F16, 0xF1E3, 0x9F18, 0xF6CF, 0x9F19, 0xC567, 0x9F1A, 0xF6D0, 0x9F1B, 0xF6CE, 0x9F1C, 0xF879, 0x9F1E, 0xF8E9, 0x9F20, 0xB9AB, - 0x9F22, 0xEFB4, 0x9F23, 0xEFB3, 0x9F24, 0xEFB2, 0x9F25, 0xF1E4, 0x9F28, 0xF1E8, 0x9F29, 0xF1E7, 0x9F2A, 0xF1E6, 0x9F2B, 0xF1E5, - 0x9F2C, 0xC35E, 0x9F2D, 0xF3F6, 0x9F2E, 0xF5B9, 0x9F2F, 0xC4D3, 0x9F30, 0xF5B8, 0x9F31, 0xF6D1, 0x9F32, 0xF7CB, 0x9F33, 0xF7CA, - 0x9F34, 0xC5C4, 0x9F35, 0xF7C9, 0x9F36, 0xF87C, 0x9F37, 0xF87B, 0x9F38, 0xF87A, 0x9F3B, 0xBBF3, 0x9F3D, 0xECB8, 0x9F3E, 0xC24D, - 0x9F40, 0xF3F7, 0x9F41, 0xF3F8, 0x9F42, 0xF7CC, 0x9F43, 0xF87D, 0x9F46, 0xF8EA, 0x9F47, 0xF966, 0x9F48, 0xF9B9, 0x9F49, 0xF9D4, - 0x9F4A, 0xBBF4, 0x9F4B, 0xC24E, 0x9F4C, 0xF1E9, 0x9F4D, 0xF3F9, 0x9F4E, 0xF6D2, 0x9F4F, 0xF87E, 0x9F52, 0xBEA6, 0x9F54, 0xEFB5, - 0x9F55, 0xF1EA, 0x9F56, 0xF3FA, 0x9F57, 0xF3FB, 0x9F58, 0xF3FC, 0x9F59, 0xF5BE, 0x9F5B, 0xF5BA, 0x9F5C, 0xC568, 0x9F5D, 0xF5BD, - 0x9F5E, 0xF5BC, 0x9F5F, 0xC4D4, 0x9F60, 0xF5BB, 0x9F61, 0xC4D6, 0x9F63, 0xC4D5, 0x9F64, 0xF6D4, 0x9F65, 0xF6D3, 0x9F66, 0xC569, - 0x9F67, 0xC56A, 0x9F6A, 0xC5C6, 0x9F6B, 0xF7CD, 0x9F6C, 0xC5C5, 0x9F6E, 0xF8A3, 0x9F6F, 0xF8A4, 0x9F70, 0xF8A2, 0x9F71, 0xF8A1, - 0x9F72, 0xC654, 0x9F74, 0xF8EB, 0x9F75, 0xF8EC, 0x9F76, 0xF8ED, 0x9F77, 0xC653, 0x9F78, 0xF967, 0x9F79, 0xF96A, 0x9F7A, 0xF969, - 0x9F7B, 0xF968, 0x9F7E, 0xF9D3, 0x9F8D, 0xC073, 0x9F90, 0xC365, 0x9F91, 0xF5BF, 0x9F92, 0xF6D5, 0x9F94, 0xC5C7, 0x9F95, 0xF7CE, - 0x9F98, 0xF9D5, 0x9F9C, 0xC074, 0x9FA0, 0xEFB6, 0x9FA2, 0xF7CF, 0x9FA4, 0xF9A1, 0xFA0C, 0xC94A, 0xFA0D, 0xDDFC, 0xFE30, 0xA14A, - 0xFE31, 0xA157, 0xFE33, 0xA159, 0xFE34, 0xA15B, 0xFE35, 0xA15F, 0xFE36, 0xA160, 0xFE37, 0xA163, 0xFE38, 0xA164, 0xFE39, 0xA167, - 0xFE3A, 0xA168, 0xFE3B, 0xA16B, 0xFE3C, 0xA16C, 0xFE3D, 0xA16F, 0xFE3E, 0xA170, 0xFE3F, 0xA173, 0xFE40, 0xA174, 0xFE41, 0xA177, - 0xFE42, 0xA178, 0xFE43, 0xA17B, 0xFE44, 0xA17C, 0xFE49, 0xA1C6, 0xFE4A, 0xA1C7, 0xFE4B, 0xA1CA, 0xFE4C, 0xA1CB, 0xFE4D, 0xA1C8, - 0xFE4E, 0xA1C9, 0xFE4F, 0xA15C, 0xFE50, 0xA14D, 0xFE51, 0xA14E, 0xFE52, 0xA14F, 0xFE54, 0xA151, 0xFE55, 0xA152, 0xFE56, 0xA153, - 0xFE57, 0xA154, 0xFE59, 0xA17D, 0xFE5A, 0xA17E, 0xFE5B, 0xA1A1, 0xFE5C, 0xA1A2, 0xFE5D, 0xA1A3, 0xFE5E, 0xA1A4, 0xFE5F, 0xA1CC, - 0xFE60, 0xA1CD, 0xFE61, 0xA1CE, 0xFE62, 0xA1DE, 0xFE63, 0xA1DF, 0xFE64, 0xA1E0, 0xFE65, 0xA1E1, 0xFE66, 0xA1E2, 0xFE68, 0xA242, - 0xFE69, 0xA24C, 0xFE6A, 0xA24D, 0xFE6B, 0xA24E, 0xFF01, 0xA149, 0xFF03, 0xA1AD, 0xFF04, 0xA243, 0xFF05, 0xA248, 0xFF06, 0xA1AE, - 0xFF08, 0xA15D, 0xFF09, 0xA15E, 0xFF0A, 0xA1AF, 0xFF0B, 0xA1CF, 0xFF0C, 0xA141, 0xFF0D, 0xA1D0, 0xFF0E, 0xA144, 0xFF0F, 0xA1FE, - 0xFF10, 0xA2AF, 0xFF11, 0xA2B0, 0xFF12, 0xA2B1, 0xFF13, 0xA2B2, 0xFF14, 0xA2B3, 0xFF15, 0xA2B4, 0xFF16, 0xA2B5, 0xFF17, 0xA2B6, - 0xFF18, 0xA2B7, 0xFF19, 0xA2B8, 0xFF1A, 0xA147, 0xFF1B, 0xA146, 0xFF1C, 0xA1D5, 0xFF1D, 0xA1D7, 0xFF1E, 0xA1D6, 0xFF1F, 0xA148, - 0xFF20, 0xA249, 0xFF21, 0xA2CF, 0xFF22, 0xA2D0, 0xFF23, 0xA2D1, 0xFF24, 0xA2D2, 0xFF25, 0xA2D3, 0xFF26, 0xA2D4, 0xFF27, 0xA2D5, - 0xFF28, 0xA2D6, 0xFF29, 0xA2D7, 0xFF2A, 0xA2D8, 0xFF2B, 0xA2D9, 0xFF2C, 0xA2DA, 0xFF2D, 0xA2DB, 0xFF2E, 0xA2DC, 0xFF2F, 0xA2DD, - 0xFF30, 0xA2DE, 0xFF31, 0xA2DF, 0xFF32, 0xA2E0, 0xFF33, 0xA2E1, 0xFF34, 0xA2E2, 0xFF35, 0xA2E3, 0xFF36, 0xA2E4, 0xFF37, 0xA2E5, - 0xFF38, 0xA2E6, 0xFF39, 0xA2E7, 0xFF3A, 0xA2E8, 0xFF3C, 0xA240, 0xFF3F, 0xA1C4, 0xFF41, 0xA2E9, 0xFF42, 0xA2EA, 0xFF43, 0xA2EB, - 0xFF44, 0xA2EC, 0xFF45, 0xA2ED, 0xFF46, 0xA2EE, 0xFF47, 0xA2EF, 0xFF48, 0xA2F0, 0xFF49, 0xA2F1, 0xFF4A, 0xA2F2, 0xFF4B, 0xA2F3, - 0xFF4C, 0xA2F4, 0xFF4D, 0xA2F5, 0xFF4E, 0xA2F6, 0xFF4F, 0xA2F7, 0xFF50, 0xA2F8, 0xFF51, 0xA2F9, 0xFF52, 0xA2FA, 0xFF53, 0xA2FB, - 0xFF54, 0xA2FC, 0xFF55, 0xA2FD, 0xFF56, 0xA2FE, 0xFF57, 0xA340, 0xFF58, 0xA341, 0xFF59, 0xA342, 0xFF5A, 0xA343, 0xFF5B, 0xA161, - 0xFF5C, 0xA155, 0xFF5D, 0xA162, 0xFF5E, 0xA1E3, 0xFFE0, 0xA246, 0xFFE1, 0xA247, 0xFFE3, 0xA1C3, 0xFFE5, 0xA244, 0, 0 -}; - -static const WCHAR oem2uni950[] = { /* Big5 --> Unicode pairs */ - 0xA140, 0x3000, 0xA141, 0xFF0C, 0xA142, 0x3001, 0xA143, 0x3002, 0xA144, 0xFF0E, 0xA145, 0x2027, 0xA146, 0xFF1B, 0xA147, 0xFF1A, - 0xA148, 0xFF1F, 0xA149, 0xFF01, 0xA14A, 0xFE30, 0xA14B, 0x2026, 0xA14C, 0x2025, 0xA14D, 0xFE50, 0xA14E, 0xFE51, 0xA14F, 0xFE52, - 0xA150, 0x00B7, 0xA151, 0xFE54, 0xA152, 0xFE55, 0xA153, 0xFE56, 0xA154, 0xFE57, 0xA155, 0xFF5C, 0xA156, 0x2013, 0xA157, 0xFE31, - 0xA158, 0x2014, 0xA159, 0xFE33, 0xA15A, 0x2574, 0xA15B, 0xFE34, 0xA15C, 0xFE4F, 0xA15D, 0xFF08, 0xA15E, 0xFF09, 0xA15F, 0xFE35, - 0xA160, 0xFE36, 0xA161, 0xFF5B, 0xA162, 0xFF5D, 0xA163, 0xFE37, 0xA164, 0xFE38, 0xA165, 0x3014, 0xA166, 0x3015, 0xA167, 0xFE39, - 0xA168, 0xFE3A, 0xA169, 0x3010, 0xA16A, 0x3011, 0xA16B, 0xFE3B, 0xA16C, 0xFE3C, 0xA16D, 0x300A, 0xA16E, 0x300B, 0xA16F, 0xFE3D, - 0xA170, 0xFE3E, 0xA171, 0x3008, 0xA172, 0x3009, 0xA173, 0xFE3F, 0xA174, 0xFE40, 0xA175, 0x300C, 0xA176, 0x300D, 0xA177, 0xFE41, - 0xA178, 0xFE42, 0xA179, 0x300E, 0xA17A, 0x300F, 0xA17B, 0xFE43, 0xA17C, 0xFE44, 0xA17D, 0xFE59, 0xA17E, 0xFE5A, 0xA1A1, 0xFE5B, - 0xA1A2, 0xFE5C, 0xA1A3, 0xFE5D, 0xA1A4, 0xFE5E, 0xA1A5, 0x2018, 0xA1A6, 0x2019, 0xA1A7, 0x201C, 0xA1A8, 0x201D, 0xA1A9, 0x301D, - 0xA1AA, 0x301E, 0xA1AB, 0x2035, 0xA1AC, 0x2032, 0xA1AD, 0xFF03, 0xA1AE, 0xFF06, 0xA1AF, 0xFF0A, 0xA1B0, 0x203B, 0xA1B1, 0x00A7, - 0xA1B2, 0x3003, 0xA1B3, 0x25CB, 0xA1B4, 0x25CF, 0xA1B5, 0x25B3, 0xA1B6, 0x25B2, 0xA1B7, 0x25CE, 0xA1B8, 0x2606, 0xA1B9, 0x2605, - 0xA1BA, 0x25C7, 0xA1BB, 0x25C6, 0xA1BC, 0x25A1, 0xA1BD, 0x25A0, 0xA1BE, 0x25BD, 0xA1BF, 0x25BC, 0xA1C0, 0x32A3, 0xA1C1, 0x2105, - 0xA1C2, 0x00AF, 0xA1C3, 0xFFE3, 0xA1C4, 0xFF3F, 0xA1C5, 0x02CD, 0xA1C6, 0xFE49, 0xA1C7, 0xFE4A, 0xA1C8, 0xFE4D, 0xA1C9, 0xFE4E, - 0xA1CA, 0xFE4B, 0xA1CB, 0xFE4C, 0xA1CC, 0xFE5F, 0xA1CD, 0xFE60, 0xA1CE, 0xFE61, 0xA1CF, 0xFF0B, 0xA1D0, 0xFF0D, 0xA1D1, 0x00D7, - 0xA1D2, 0x00F7, 0xA1D3, 0x00B1, 0xA1D4, 0x221A, 0xA1D5, 0xFF1C, 0xA1D6, 0xFF1E, 0xA1D7, 0xFF1D, 0xA1D8, 0x2266, 0xA1D9, 0x2267, - 0xA1DA, 0x2260, 0xA1DB, 0x221E, 0xA1DC, 0x2252, 0xA1DD, 0x2261, 0xA1DE, 0xFE62, 0xA1DF, 0xFE63, 0xA1E0, 0xFE64, 0xA1E1, 0xFE65, - 0xA1E2, 0xFE66, 0xA1E3, 0xFF5E, 0xA1E4, 0x2229, 0xA1E5, 0x222A, 0xA1E6, 0x22A5, 0xA1E7, 0x2220, 0xA1E8, 0x221F, 0xA1E9, 0x22BF, - 0xA1EA, 0x33D2, 0xA1EB, 0x33D1, 0xA1EC, 0x222B, 0xA1ED, 0x222E, 0xA1EE, 0x2235, 0xA1EF, 0x2234, 0xA1F0, 0x2640, 0xA1F1, 0x2642, - 0xA1F2, 0x2295, 0xA1F3, 0x2299, 0xA1F4, 0x2191, 0xA1F5, 0x2193, 0xA1F6, 0x2190, 0xA1F7, 0x2192, 0xA1F8, 0x2196, 0xA1F9, 0x2197, - 0xA1FA, 0x2199, 0xA1FB, 0x2198, 0xA1FC, 0x2225, 0xA1FD, 0x2223, 0xA1FE, 0xFF0F, 0xA240, 0xFF3C, 0xA241, 0x2215, 0xA242, 0xFE68, - 0xA243, 0xFF04, 0xA244, 0xFFE5, 0xA245, 0x3012, 0xA246, 0xFFE0, 0xA247, 0xFFE1, 0xA248, 0xFF05, 0xA249, 0xFF20, 0xA24A, 0x2103, - 0xA24B, 0x2109, 0xA24C, 0xFE69, 0xA24D, 0xFE6A, 0xA24E, 0xFE6B, 0xA24F, 0x33D5, 0xA250, 0x339C, 0xA251, 0x339D, 0xA252, 0x339E, - 0xA253, 0x33CE, 0xA254, 0x33A1, 0xA255, 0x338E, 0xA256, 0x338F, 0xA257, 0x33C4, 0xA258, 0x00B0, 0xA259, 0x5159, 0xA25A, 0x515B, - 0xA25B, 0x515E, 0xA25C, 0x515D, 0xA25D, 0x5161, 0xA25E, 0x5163, 0xA25F, 0x55E7, 0xA260, 0x74E9, 0xA261, 0x7CCE, 0xA262, 0x2581, - 0xA263, 0x2582, 0xA264, 0x2583, 0xA265, 0x2584, 0xA266, 0x2585, 0xA267, 0x2586, 0xA268, 0x2587, 0xA269, 0x2588, 0xA26A, 0x258F, - 0xA26B, 0x258E, 0xA26C, 0x258D, 0xA26D, 0x258C, 0xA26E, 0x258B, 0xA26F, 0x258A, 0xA270, 0x2589, 0xA271, 0x253C, 0xA272, 0x2534, - 0xA273, 0x252C, 0xA274, 0x2524, 0xA275, 0x251C, 0xA276, 0x2594, 0xA277, 0x2500, 0xA278, 0x2502, 0xA279, 0x2595, 0xA27A, 0x250C, - 0xA27B, 0x2510, 0xA27C, 0x2514, 0xA27D, 0x2518, 0xA27E, 0x256D, 0xA2A1, 0x256E, 0xA2A2, 0x2570, 0xA2A3, 0x256F, 0xA2A4, 0x2550, - 0xA2A5, 0x255E, 0xA2A6, 0x256A, 0xA2A7, 0x2561, 0xA2A8, 0x25E2, 0xA2A9, 0x25E3, 0xA2AA, 0x25E5, 0xA2AB, 0x25E4, 0xA2AC, 0x2571, - 0xA2AD, 0x2572, 0xA2AE, 0x2573, 0xA2AF, 0xFF10, 0xA2B0, 0xFF11, 0xA2B1, 0xFF12, 0xA2B2, 0xFF13, 0xA2B3, 0xFF14, 0xA2B4, 0xFF15, - 0xA2B5, 0xFF16, 0xA2B6, 0xFF17, 0xA2B7, 0xFF18, 0xA2B8, 0xFF19, 0xA2B9, 0x2160, 0xA2BA, 0x2161, 0xA2BB, 0x2162, 0xA2BC, 0x2163, - 0xA2BD, 0x2164, 0xA2BE, 0x2165, 0xA2BF, 0x2166, 0xA2C0, 0x2167, 0xA2C1, 0x2168, 0xA2C2, 0x2169, 0xA2C3, 0x3021, 0xA2C4, 0x3022, - 0xA2C5, 0x3023, 0xA2C6, 0x3024, 0xA2C7, 0x3025, 0xA2C8, 0x3026, 0xA2C9, 0x3027, 0xA2CA, 0x3028, 0xA2CB, 0x3029, 0xA2CC, 0x5341, - 0xA2CD, 0x5344, 0xA2CE, 0x5345, 0xA2CF, 0xFF21, 0xA2D0, 0xFF22, 0xA2D1, 0xFF23, 0xA2D2, 0xFF24, 0xA2D3, 0xFF25, 0xA2D4, 0xFF26, - 0xA2D5, 0xFF27, 0xA2D6, 0xFF28, 0xA2D7, 0xFF29, 0xA2D8, 0xFF2A, 0xA2D9, 0xFF2B, 0xA2DA, 0xFF2C, 0xA2DB, 0xFF2D, 0xA2DC, 0xFF2E, - 0xA2DD, 0xFF2F, 0xA2DE, 0xFF30, 0xA2DF, 0xFF31, 0xA2E0, 0xFF32, 0xA2E1, 0xFF33, 0xA2E2, 0xFF34, 0xA2E3, 0xFF35, 0xA2E4, 0xFF36, - 0xA2E5, 0xFF37, 0xA2E6, 0xFF38, 0xA2E7, 0xFF39, 0xA2E8, 0xFF3A, 0xA2E9, 0xFF41, 0xA2EA, 0xFF42, 0xA2EB, 0xFF43, 0xA2EC, 0xFF44, - 0xA2ED, 0xFF45, 0xA2EE, 0xFF46, 0xA2EF, 0xFF47, 0xA2F0, 0xFF48, 0xA2F1, 0xFF49, 0xA2F2, 0xFF4A, 0xA2F3, 0xFF4B, 0xA2F4, 0xFF4C, - 0xA2F5, 0xFF4D, 0xA2F6, 0xFF4E, 0xA2F7, 0xFF4F, 0xA2F8, 0xFF50, 0xA2F9, 0xFF51, 0xA2FA, 0xFF52, 0xA2FB, 0xFF53, 0xA2FC, 0xFF54, - 0xA2FD, 0xFF55, 0xA2FE, 0xFF56, 0xA340, 0xFF57, 0xA341, 0xFF58, 0xA342, 0xFF59, 0xA343, 0xFF5A, 0xA344, 0x0391, 0xA345, 0x0392, - 0xA346, 0x0393, 0xA347, 0x0394, 0xA348, 0x0395, 0xA349, 0x0396, 0xA34A, 0x0397, 0xA34B, 0x0398, 0xA34C, 0x0399, 0xA34D, 0x039A, - 0xA34E, 0x039B, 0xA34F, 0x039C, 0xA350, 0x039D, 0xA351, 0x039E, 0xA352, 0x039F, 0xA353, 0x03A0, 0xA354, 0x03A1, 0xA355, 0x03A3, - 0xA356, 0x03A4, 0xA357, 0x03A5, 0xA358, 0x03A6, 0xA359, 0x03A7, 0xA35A, 0x03A8, 0xA35B, 0x03A9, 0xA35C, 0x03B1, 0xA35D, 0x03B2, - 0xA35E, 0x03B3, 0xA35F, 0x03B4, 0xA360, 0x03B5, 0xA361, 0x03B6, 0xA362, 0x03B7, 0xA363, 0x03B8, 0xA364, 0x03B9, 0xA365, 0x03BA, - 0xA366, 0x03BB, 0xA367, 0x03BC, 0xA368, 0x03BD, 0xA369, 0x03BE, 0xA36A, 0x03BF, 0xA36B, 0x03C0, 0xA36C, 0x03C1, 0xA36D, 0x03C3, - 0xA36E, 0x03C4, 0xA36F, 0x03C5, 0xA370, 0x03C6, 0xA371, 0x03C7, 0xA372, 0x03C8, 0xA373, 0x03C9, 0xA374, 0x3105, 0xA375, 0x3106, - 0xA376, 0x3107, 0xA377, 0x3108, 0xA378, 0x3109, 0xA379, 0x310A, 0xA37A, 0x310B, 0xA37B, 0x310C, 0xA37C, 0x310D, 0xA37D, 0x310E, - 0xA37E, 0x310F, 0xA3A1, 0x3110, 0xA3A2, 0x3111, 0xA3A3, 0x3112, 0xA3A4, 0x3113, 0xA3A5, 0x3114, 0xA3A6, 0x3115, 0xA3A7, 0x3116, - 0xA3A8, 0x3117, 0xA3A9, 0x3118, 0xA3AA, 0x3119, 0xA3AB, 0x311A, 0xA3AC, 0x311B, 0xA3AD, 0x311C, 0xA3AE, 0x311D, 0xA3AF, 0x311E, - 0xA3B0, 0x311F, 0xA3B1, 0x3120, 0xA3B2, 0x3121, 0xA3B3, 0x3122, 0xA3B4, 0x3123, 0xA3B5, 0x3124, 0xA3B6, 0x3125, 0xA3B7, 0x3126, - 0xA3B8, 0x3127, 0xA3B9, 0x3128, 0xA3BA, 0x3129, 0xA3BB, 0x02D9, 0xA3BC, 0x02C9, 0xA3BD, 0x02CA, 0xA3BE, 0x02C7, 0xA3BF, 0x02CB, - 0xA3E1, 0x20AC, 0xA440, 0x4E00, 0xA441, 0x4E59, 0xA442, 0x4E01, 0xA443, 0x4E03, 0xA444, 0x4E43, 0xA445, 0x4E5D, 0xA446, 0x4E86, - 0xA447, 0x4E8C, 0xA448, 0x4EBA, 0xA449, 0x513F, 0xA44A, 0x5165, 0xA44B, 0x516B, 0xA44C, 0x51E0, 0xA44D, 0x5200, 0xA44E, 0x5201, - 0xA44F, 0x529B, 0xA450, 0x5315, 0xA451, 0x5341, 0xA452, 0x535C, 0xA453, 0x53C8, 0xA454, 0x4E09, 0xA455, 0x4E0B, 0xA456, 0x4E08, - 0xA457, 0x4E0A, 0xA458, 0x4E2B, 0xA459, 0x4E38, 0xA45A, 0x51E1, 0xA45B, 0x4E45, 0xA45C, 0x4E48, 0xA45D, 0x4E5F, 0xA45E, 0x4E5E, - 0xA45F, 0x4E8E, 0xA460, 0x4EA1, 0xA461, 0x5140, 0xA462, 0x5203, 0xA463, 0x52FA, 0xA464, 0x5343, 0xA465, 0x53C9, 0xA466, 0x53E3, - 0xA467, 0x571F, 0xA468, 0x58EB, 0xA469, 0x5915, 0xA46A, 0x5927, 0xA46B, 0x5973, 0xA46C, 0x5B50, 0xA46D, 0x5B51, 0xA46E, 0x5B53, - 0xA46F, 0x5BF8, 0xA470, 0x5C0F, 0xA471, 0x5C22, 0xA472, 0x5C38, 0xA473, 0x5C71, 0xA474, 0x5DDD, 0xA475, 0x5DE5, 0xA476, 0x5DF1, - 0xA477, 0x5DF2, 0xA478, 0x5DF3, 0xA479, 0x5DFE, 0xA47A, 0x5E72, 0xA47B, 0x5EFE, 0xA47C, 0x5F0B, 0xA47D, 0x5F13, 0xA47E, 0x624D, - 0xA4A1, 0x4E11, 0xA4A2, 0x4E10, 0xA4A3, 0x4E0D, 0xA4A4, 0x4E2D, 0xA4A5, 0x4E30, 0xA4A6, 0x4E39, 0xA4A7, 0x4E4B, 0xA4A8, 0x5C39, - 0xA4A9, 0x4E88, 0xA4AA, 0x4E91, 0xA4AB, 0x4E95, 0xA4AC, 0x4E92, 0xA4AD, 0x4E94, 0xA4AE, 0x4EA2, 0xA4AF, 0x4EC1, 0xA4B0, 0x4EC0, - 0xA4B1, 0x4EC3, 0xA4B2, 0x4EC6, 0xA4B3, 0x4EC7, 0xA4B4, 0x4ECD, 0xA4B5, 0x4ECA, 0xA4B6, 0x4ECB, 0xA4B7, 0x4EC4, 0xA4B8, 0x5143, - 0xA4B9, 0x5141, 0xA4BA, 0x5167, 0xA4BB, 0x516D, 0xA4BC, 0x516E, 0xA4BD, 0x516C, 0xA4BE, 0x5197, 0xA4BF, 0x51F6, 0xA4C0, 0x5206, - 0xA4C1, 0x5207, 0xA4C2, 0x5208, 0xA4C3, 0x52FB, 0xA4C4, 0x52FE, 0xA4C5, 0x52FF, 0xA4C6, 0x5316, 0xA4C7, 0x5339, 0xA4C8, 0x5348, - 0xA4C9, 0x5347, 0xA4CA, 0x5345, 0xA4CB, 0x535E, 0xA4CC, 0x5384, 0xA4CD, 0x53CB, 0xA4CE, 0x53CA, 0xA4CF, 0x53CD, 0xA4D0, 0x58EC, - 0xA4D1, 0x5929, 0xA4D2, 0x592B, 0xA4D3, 0x592A, 0xA4D4, 0x592D, 0xA4D5, 0x5B54, 0xA4D6, 0x5C11, 0xA4D7, 0x5C24, 0xA4D8, 0x5C3A, - 0xA4D9, 0x5C6F, 0xA4DA, 0x5DF4, 0xA4DB, 0x5E7B, 0xA4DC, 0x5EFF, 0xA4DD, 0x5F14, 0xA4DE, 0x5F15, 0xA4DF, 0x5FC3, 0xA4E0, 0x6208, - 0xA4E1, 0x6236, 0xA4E2, 0x624B, 0xA4E3, 0x624E, 0xA4E4, 0x652F, 0xA4E5, 0x6587, 0xA4E6, 0x6597, 0xA4E7, 0x65A4, 0xA4E8, 0x65B9, - 0xA4E9, 0x65E5, 0xA4EA, 0x66F0, 0xA4EB, 0x6708, 0xA4EC, 0x6728, 0xA4ED, 0x6B20, 0xA4EE, 0x6B62, 0xA4EF, 0x6B79, 0xA4F0, 0x6BCB, - 0xA4F1, 0x6BD4, 0xA4F2, 0x6BDB, 0xA4F3, 0x6C0F, 0xA4F4, 0x6C34, 0xA4F5, 0x706B, 0xA4F6, 0x722A, 0xA4F7, 0x7236, 0xA4F8, 0x723B, - 0xA4F9, 0x7247, 0xA4FA, 0x7259, 0xA4FB, 0x725B, 0xA4FC, 0x72AC, 0xA4FD, 0x738B, 0xA4FE, 0x4E19, 0xA540, 0x4E16, 0xA541, 0x4E15, - 0xA542, 0x4E14, 0xA543, 0x4E18, 0xA544, 0x4E3B, 0xA545, 0x4E4D, 0xA546, 0x4E4F, 0xA547, 0x4E4E, 0xA548, 0x4EE5, 0xA549, 0x4ED8, - 0xA54A, 0x4ED4, 0xA54B, 0x4ED5, 0xA54C, 0x4ED6, 0xA54D, 0x4ED7, 0xA54E, 0x4EE3, 0xA54F, 0x4EE4, 0xA550, 0x4ED9, 0xA551, 0x4EDE, - 0xA552, 0x5145, 0xA553, 0x5144, 0xA554, 0x5189, 0xA555, 0x518A, 0xA556, 0x51AC, 0xA557, 0x51F9, 0xA558, 0x51FA, 0xA559, 0x51F8, - 0xA55A, 0x520A, 0xA55B, 0x52A0, 0xA55C, 0x529F, 0xA55D, 0x5305, 0xA55E, 0x5306, 0xA55F, 0x5317, 0xA560, 0x531D, 0xA561, 0x4EDF, - 0xA562, 0x534A, 0xA563, 0x5349, 0xA564, 0x5361, 0xA565, 0x5360, 0xA566, 0x536F, 0xA567, 0x536E, 0xA568, 0x53BB, 0xA569, 0x53EF, - 0xA56A, 0x53E4, 0xA56B, 0x53F3, 0xA56C, 0x53EC, 0xA56D, 0x53EE, 0xA56E, 0x53E9, 0xA56F, 0x53E8, 0xA570, 0x53FC, 0xA571, 0x53F8, - 0xA572, 0x53F5, 0xA573, 0x53EB, 0xA574, 0x53E6, 0xA575, 0x53EA, 0xA576, 0x53F2, 0xA577, 0x53F1, 0xA578, 0x53F0, 0xA579, 0x53E5, - 0xA57A, 0x53ED, 0xA57B, 0x53FB, 0xA57C, 0x56DB, 0xA57D, 0x56DA, 0xA57E, 0x5916, 0xA5A1, 0x592E, 0xA5A2, 0x5931, 0xA5A3, 0x5974, - 0xA5A4, 0x5976, 0xA5A5, 0x5B55, 0xA5A6, 0x5B83, 0xA5A7, 0x5C3C, 0xA5A8, 0x5DE8, 0xA5A9, 0x5DE7, 0xA5AA, 0x5DE6, 0xA5AB, 0x5E02, - 0xA5AC, 0x5E03, 0xA5AD, 0x5E73, 0xA5AE, 0x5E7C, 0xA5AF, 0x5F01, 0xA5B0, 0x5F18, 0xA5B1, 0x5F17, 0xA5B2, 0x5FC5, 0xA5B3, 0x620A, - 0xA5B4, 0x6253, 0xA5B5, 0x6254, 0xA5B6, 0x6252, 0xA5B7, 0x6251, 0xA5B8, 0x65A5, 0xA5B9, 0x65E6, 0xA5BA, 0x672E, 0xA5BB, 0x672C, - 0xA5BC, 0x672A, 0xA5BD, 0x672B, 0xA5BE, 0x672D, 0xA5BF, 0x6B63, 0xA5C0, 0x6BCD, 0xA5C1, 0x6C11, 0xA5C2, 0x6C10, 0xA5C3, 0x6C38, - 0xA5C4, 0x6C41, 0xA5C5, 0x6C40, 0xA5C6, 0x6C3E, 0xA5C7, 0x72AF, 0xA5C8, 0x7384, 0xA5C9, 0x7389, 0xA5CA, 0x74DC, 0xA5CB, 0x74E6, - 0xA5CC, 0x7518, 0xA5CD, 0x751F, 0xA5CE, 0x7528, 0xA5CF, 0x7529, 0xA5D0, 0x7530, 0xA5D1, 0x7531, 0xA5D2, 0x7532, 0xA5D3, 0x7533, - 0xA5D4, 0x758B, 0xA5D5, 0x767D, 0xA5D6, 0x76AE, 0xA5D7, 0x76BF, 0xA5D8, 0x76EE, 0xA5D9, 0x77DB, 0xA5DA, 0x77E2, 0xA5DB, 0x77F3, - 0xA5DC, 0x793A, 0xA5DD, 0x79BE, 0xA5DE, 0x7A74, 0xA5DF, 0x7ACB, 0xA5E0, 0x4E1E, 0xA5E1, 0x4E1F, 0xA5E2, 0x4E52, 0xA5E3, 0x4E53, - 0xA5E4, 0x4E69, 0xA5E5, 0x4E99, 0xA5E6, 0x4EA4, 0xA5E7, 0x4EA6, 0xA5E8, 0x4EA5, 0xA5E9, 0x4EFF, 0xA5EA, 0x4F09, 0xA5EB, 0x4F19, - 0xA5EC, 0x4F0A, 0xA5ED, 0x4F15, 0xA5EE, 0x4F0D, 0xA5EF, 0x4F10, 0xA5F0, 0x4F11, 0xA5F1, 0x4F0F, 0xA5F2, 0x4EF2, 0xA5F3, 0x4EF6, - 0xA5F4, 0x4EFB, 0xA5F5, 0x4EF0, 0xA5F6, 0x4EF3, 0xA5F7, 0x4EFD, 0xA5F8, 0x4F01, 0xA5F9, 0x4F0B, 0xA5FA, 0x5149, 0xA5FB, 0x5147, - 0xA5FC, 0x5146, 0xA5FD, 0x5148, 0xA5FE, 0x5168, 0xA640, 0x5171, 0xA641, 0x518D, 0xA642, 0x51B0, 0xA643, 0x5217, 0xA644, 0x5211, - 0xA645, 0x5212, 0xA646, 0x520E, 0xA647, 0x5216, 0xA648, 0x52A3, 0xA649, 0x5308, 0xA64A, 0x5321, 0xA64B, 0x5320, 0xA64C, 0x5370, - 0xA64D, 0x5371, 0xA64E, 0x5409, 0xA64F, 0x540F, 0xA650, 0x540C, 0xA651, 0x540A, 0xA652, 0x5410, 0xA653, 0x5401, 0xA654, 0x540B, - 0xA655, 0x5404, 0xA656, 0x5411, 0xA657, 0x540D, 0xA658, 0x5408, 0xA659, 0x5403, 0xA65A, 0x540E, 0xA65B, 0x5406, 0xA65C, 0x5412, - 0xA65D, 0x56E0, 0xA65E, 0x56DE, 0xA65F, 0x56DD, 0xA660, 0x5733, 0xA661, 0x5730, 0xA662, 0x5728, 0xA663, 0x572D, 0xA664, 0x572C, - 0xA665, 0x572F, 0xA666, 0x5729, 0xA667, 0x5919, 0xA668, 0x591A, 0xA669, 0x5937, 0xA66A, 0x5938, 0xA66B, 0x5984, 0xA66C, 0x5978, - 0xA66D, 0x5983, 0xA66E, 0x597D, 0xA66F, 0x5979, 0xA670, 0x5982, 0xA671, 0x5981, 0xA672, 0x5B57, 0xA673, 0x5B58, 0xA674, 0x5B87, - 0xA675, 0x5B88, 0xA676, 0x5B85, 0xA677, 0x5B89, 0xA678, 0x5BFA, 0xA679, 0x5C16, 0xA67A, 0x5C79, 0xA67B, 0x5DDE, 0xA67C, 0x5E06, - 0xA67D, 0x5E76, 0xA67E, 0x5E74, 0xA6A1, 0x5F0F, 0xA6A2, 0x5F1B, 0xA6A3, 0x5FD9, 0xA6A4, 0x5FD6, 0xA6A5, 0x620E, 0xA6A6, 0x620C, - 0xA6A7, 0x620D, 0xA6A8, 0x6210, 0xA6A9, 0x6263, 0xA6AA, 0x625B, 0xA6AB, 0x6258, 0xA6AC, 0x6536, 0xA6AD, 0x65E9, 0xA6AE, 0x65E8, - 0xA6AF, 0x65EC, 0xA6B0, 0x65ED, 0xA6B1, 0x66F2, 0xA6B2, 0x66F3, 0xA6B3, 0x6709, 0xA6B4, 0x673D, 0xA6B5, 0x6734, 0xA6B6, 0x6731, - 0xA6B7, 0x6735, 0xA6B8, 0x6B21, 0xA6B9, 0x6B64, 0xA6BA, 0x6B7B, 0xA6BB, 0x6C16, 0xA6BC, 0x6C5D, 0xA6BD, 0x6C57, 0xA6BE, 0x6C59, - 0xA6BF, 0x6C5F, 0xA6C0, 0x6C60, 0xA6C1, 0x6C50, 0xA6C2, 0x6C55, 0xA6C3, 0x6C61, 0xA6C4, 0x6C5B, 0xA6C5, 0x6C4D, 0xA6C6, 0x6C4E, - 0xA6C7, 0x7070, 0xA6C8, 0x725F, 0xA6C9, 0x725D, 0xA6CA, 0x767E, 0xA6CB, 0x7AF9, 0xA6CC, 0x7C73, 0xA6CD, 0x7CF8, 0xA6CE, 0x7F36, - 0xA6CF, 0x7F8A, 0xA6D0, 0x7FBD, 0xA6D1, 0x8001, 0xA6D2, 0x8003, 0xA6D3, 0x800C, 0xA6D4, 0x8012, 0xA6D5, 0x8033, 0xA6D6, 0x807F, - 0xA6D7, 0x8089, 0xA6D8, 0x808B, 0xA6D9, 0x808C, 0xA6DA, 0x81E3, 0xA6DB, 0x81EA, 0xA6DC, 0x81F3, 0xA6DD, 0x81FC, 0xA6DE, 0x820C, - 0xA6DF, 0x821B, 0xA6E0, 0x821F, 0xA6E1, 0x826E, 0xA6E2, 0x8272, 0xA6E3, 0x827E, 0xA6E4, 0x866B, 0xA6E5, 0x8840, 0xA6E6, 0x884C, - 0xA6E7, 0x8863, 0xA6E8, 0x897F, 0xA6E9, 0x9621, 0xA6EA, 0x4E32, 0xA6EB, 0x4EA8, 0xA6EC, 0x4F4D, 0xA6ED, 0x4F4F, 0xA6EE, 0x4F47, - 0xA6EF, 0x4F57, 0xA6F0, 0x4F5E, 0xA6F1, 0x4F34, 0xA6F2, 0x4F5B, 0xA6F3, 0x4F55, 0xA6F4, 0x4F30, 0xA6F5, 0x4F50, 0xA6F6, 0x4F51, - 0xA6F7, 0x4F3D, 0xA6F8, 0x4F3A, 0xA6F9, 0x4F38, 0xA6FA, 0x4F43, 0xA6FB, 0x4F54, 0xA6FC, 0x4F3C, 0xA6FD, 0x4F46, 0xA6FE, 0x4F63, - 0xA740, 0x4F5C, 0xA741, 0x4F60, 0xA742, 0x4F2F, 0xA743, 0x4F4E, 0xA744, 0x4F36, 0xA745, 0x4F59, 0xA746, 0x4F5D, 0xA747, 0x4F48, - 0xA748, 0x4F5A, 0xA749, 0x514C, 0xA74A, 0x514B, 0xA74B, 0x514D, 0xA74C, 0x5175, 0xA74D, 0x51B6, 0xA74E, 0x51B7, 0xA74F, 0x5225, - 0xA750, 0x5224, 0xA751, 0x5229, 0xA752, 0x522A, 0xA753, 0x5228, 0xA754, 0x52AB, 0xA755, 0x52A9, 0xA756, 0x52AA, 0xA757, 0x52AC, - 0xA758, 0x5323, 0xA759, 0x5373, 0xA75A, 0x5375, 0xA75B, 0x541D, 0xA75C, 0x542D, 0xA75D, 0x541E, 0xA75E, 0x543E, 0xA75F, 0x5426, - 0xA760, 0x544E, 0xA761, 0x5427, 0xA762, 0x5446, 0xA763, 0x5443, 0xA764, 0x5433, 0xA765, 0x5448, 0xA766, 0x5442, 0xA767, 0x541B, - 0xA768, 0x5429, 0xA769, 0x544A, 0xA76A, 0x5439, 0xA76B, 0x543B, 0xA76C, 0x5438, 0xA76D, 0x542E, 0xA76E, 0x5435, 0xA76F, 0x5436, - 0xA770, 0x5420, 0xA771, 0x543C, 0xA772, 0x5440, 0xA773, 0x5431, 0xA774, 0x542B, 0xA775, 0x541F, 0xA776, 0x542C, 0xA777, 0x56EA, - 0xA778, 0x56F0, 0xA779, 0x56E4, 0xA77A, 0x56EB, 0xA77B, 0x574A, 0xA77C, 0x5751, 0xA77D, 0x5740, 0xA77E, 0x574D, 0xA7A1, 0x5747, - 0xA7A2, 0x574E, 0xA7A3, 0x573E, 0xA7A4, 0x5750, 0xA7A5, 0x574F, 0xA7A6, 0x573B, 0xA7A7, 0x58EF, 0xA7A8, 0x593E, 0xA7A9, 0x599D, - 0xA7AA, 0x5992, 0xA7AB, 0x59A8, 0xA7AC, 0x599E, 0xA7AD, 0x59A3, 0xA7AE, 0x5999, 0xA7AF, 0x5996, 0xA7B0, 0x598D, 0xA7B1, 0x59A4, - 0xA7B2, 0x5993, 0xA7B3, 0x598A, 0xA7B4, 0x59A5, 0xA7B5, 0x5B5D, 0xA7B6, 0x5B5C, 0xA7B7, 0x5B5A, 0xA7B8, 0x5B5B, 0xA7B9, 0x5B8C, - 0xA7BA, 0x5B8B, 0xA7BB, 0x5B8F, 0xA7BC, 0x5C2C, 0xA7BD, 0x5C40, 0xA7BE, 0x5C41, 0xA7BF, 0x5C3F, 0xA7C0, 0x5C3E, 0xA7C1, 0x5C90, - 0xA7C2, 0x5C91, 0xA7C3, 0x5C94, 0xA7C4, 0x5C8C, 0xA7C5, 0x5DEB, 0xA7C6, 0x5E0C, 0xA7C7, 0x5E8F, 0xA7C8, 0x5E87, 0xA7C9, 0x5E8A, - 0xA7CA, 0x5EF7, 0xA7CB, 0x5F04, 0xA7CC, 0x5F1F, 0xA7CD, 0x5F64, 0xA7CE, 0x5F62, 0xA7CF, 0x5F77, 0xA7D0, 0x5F79, 0xA7D1, 0x5FD8, - 0xA7D2, 0x5FCC, 0xA7D3, 0x5FD7, 0xA7D4, 0x5FCD, 0xA7D5, 0x5FF1, 0xA7D6, 0x5FEB, 0xA7D7, 0x5FF8, 0xA7D8, 0x5FEA, 0xA7D9, 0x6212, - 0xA7DA, 0x6211, 0xA7DB, 0x6284, 0xA7DC, 0x6297, 0xA7DD, 0x6296, 0xA7DE, 0x6280, 0xA7DF, 0x6276, 0xA7E0, 0x6289, 0xA7E1, 0x626D, - 0xA7E2, 0x628A, 0xA7E3, 0x627C, 0xA7E4, 0x627E, 0xA7E5, 0x6279, 0xA7E6, 0x6273, 0xA7E7, 0x6292, 0xA7E8, 0x626F, 0xA7E9, 0x6298, - 0xA7EA, 0x626E, 0xA7EB, 0x6295, 0xA7EC, 0x6293, 0xA7ED, 0x6291, 0xA7EE, 0x6286, 0xA7EF, 0x6539, 0xA7F0, 0x653B, 0xA7F1, 0x6538, - 0xA7F2, 0x65F1, 0xA7F3, 0x66F4, 0xA7F4, 0x675F, 0xA7F5, 0x674E, 0xA7F6, 0x674F, 0xA7F7, 0x6750, 0xA7F8, 0x6751, 0xA7F9, 0x675C, - 0xA7FA, 0x6756, 0xA7FB, 0x675E, 0xA7FC, 0x6749, 0xA7FD, 0x6746, 0xA7FE, 0x6760, 0xA840, 0x6753, 0xA841, 0x6757, 0xA842, 0x6B65, - 0xA843, 0x6BCF, 0xA844, 0x6C42, 0xA845, 0x6C5E, 0xA846, 0x6C99, 0xA847, 0x6C81, 0xA848, 0x6C88, 0xA849, 0x6C89, 0xA84A, 0x6C85, - 0xA84B, 0x6C9B, 0xA84C, 0x6C6A, 0xA84D, 0x6C7A, 0xA84E, 0x6C90, 0xA84F, 0x6C70, 0xA850, 0x6C8C, 0xA851, 0x6C68, 0xA852, 0x6C96, - 0xA853, 0x6C92, 0xA854, 0x6C7D, 0xA855, 0x6C83, 0xA856, 0x6C72, 0xA857, 0x6C7E, 0xA858, 0x6C74, 0xA859, 0x6C86, 0xA85A, 0x6C76, - 0xA85B, 0x6C8D, 0xA85C, 0x6C94, 0xA85D, 0x6C98, 0xA85E, 0x6C82, 0xA85F, 0x7076, 0xA860, 0x707C, 0xA861, 0x707D, 0xA862, 0x7078, - 0xA863, 0x7262, 0xA864, 0x7261, 0xA865, 0x7260, 0xA866, 0x72C4, 0xA867, 0x72C2, 0xA868, 0x7396, 0xA869, 0x752C, 0xA86A, 0x752B, - 0xA86B, 0x7537, 0xA86C, 0x7538, 0xA86D, 0x7682, 0xA86E, 0x76EF, 0xA86F, 0x77E3, 0xA870, 0x79C1, 0xA871, 0x79C0, 0xA872, 0x79BF, - 0xA873, 0x7A76, 0xA874, 0x7CFB, 0xA875, 0x7F55, 0xA876, 0x8096, 0xA877, 0x8093, 0xA878, 0x809D, 0xA879, 0x8098, 0xA87A, 0x809B, - 0xA87B, 0x809A, 0xA87C, 0x80B2, 0xA87D, 0x826F, 0xA87E, 0x8292, 0xA8A1, 0x828B, 0xA8A2, 0x828D, 0xA8A3, 0x898B, 0xA8A4, 0x89D2, - 0xA8A5, 0x8A00, 0xA8A6, 0x8C37, 0xA8A7, 0x8C46, 0xA8A8, 0x8C55, 0xA8A9, 0x8C9D, 0xA8AA, 0x8D64, 0xA8AB, 0x8D70, 0xA8AC, 0x8DB3, - 0xA8AD, 0x8EAB, 0xA8AE, 0x8ECA, 0xA8AF, 0x8F9B, 0xA8B0, 0x8FB0, 0xA8B1, 0x8FC2, 0xA8B2, 0x8FC6, 0xA8B3, 0x8FC5, 0xA8B4, 0x8FC4, - 0xA8B5, 0x5DE1, 0xA8B6, 0x9091, 0xA8B7, 0x90A2, 0xA8B8, 0x90AA, 0xA8B9, 0x90A6, 0xA8BA, 0x90A3, 0xA8BB, 0x9149, 0xA8BC, 0x91C6, - 0xA8BD, 0x91CC, 0xA8BE, 0x9632, 0xA8BF, 0x962E, 0xA8C0, 0x9631, 0xA8C1, 0x962A, 0xA8C2, 0x962C, 0xA8C3, 0x4E26, 0xA8C4, 0x4E56, - 0xA8C5, 0x4E73, 0xA8C6, 0x4E8B, 0xA8C7, 0x4E9B, 0xA8C8, 0x4E9E, 0xA8C9, 0x4EAB, 0xA8CA, 0x4EAC, 0xA8CB, 0x4F6F, 0xA8CC, 0x4F9D, - 0xA8CD, 0x4F8D, 0xA8CE, 0x4F73, 0xA8CF, 0x4F7F, 0xA8D0, 0x4F6C, 0xA8D1, 0x4F9B, 0xA8D2, 0x4F8B, 0xA8D3, 0x4F86, 0xA8D4, 0x4F83, - 0xA8D5, 0x4F70, 0xA8D6, 0x4F75, 0xA8D7, 0x4F88, 0xA8D8, 0x4F69, 0xA8D9, 0x4F7B, 0xA8DA, 0x4F96, 0xA8DB, 0x4F7E, 0xA8DC, 0x4F8F, - 0xA8DD, 0x4F91, 0xA8DE, 0x4F7A, 0xA8DF, 0x5154, 0xA8E0, 0x5152, 0xA8E1, 0x5155, 0xA8E2, 0x5169, 0xA8E3, 0x5177, 0xA8E4, 0x5176, - 0xA8E5, 0x5178, 0xA8E6, 0x51BD, 0xA8E7, 0x51FD, 0xA8E8, 0x523B, 0xA8E9, 0x5238, 0xA8EA, 0x5237, 0xA8EB, 0x523A, 0xA8EC, 0x5230, - 0xA8ED, 0x522E, 0xA8EE, 0x5236, 0xA8EF, 0x5241, 0xA8F0, 0x52BE, 0xA8F1, 0x52BB, 0xA8F2, 0x5352, 0xA8F3, 0x5354, 0xA8F4, 0x5353, - 0xA8F5, 0x5351, 0xA8F6, 0x5366, 0xA8F7, 0x5377, 0xA8F8, 0x5378, 0xA8F9, 0x5379, 0xA8FA, 0x53D6, 0xA8FB, 0x53D4, 0xA8FC, 0x53D7, - 0xA8FD, 0x5473, 0xA8FE, 0x5475, 0xA940, 0x5496, 0xA941, 0x5478, 0xA942, 0x5495, 0xA943, 0x5480, 0xA944, 0x547B, 0xA945, 0x5477, - 0xA946, 0x5484, 0xA947, 0x5492, 0xA948, 0x5486, 0xA949, 0x547C, 0xA94A, 0x5490, 0xA94B, 0x5471, 0xA94C, 0x5476, 0xA94D, 0x548C, - 0xA94E, 0x549A, 0xA94F, 0x5462, 0xA950, 0x5468, 0xA951, 0x548B, 0xA952, 0x547D, 0xA953, 0x548E, 0xA954, 0x56FA, 0xA955, 0x5783, - 0xA956, 0x5777, 0xA957, 0x576A, 0xA958, 0x5769, 0xA959, 0x5761, 0xA95A, 0x5766, 0xA95B, 0x5764, 0xA95C, 0x577C, 0xA95D, 0x591C, - 0xA95E, 0x5949, 0xA95F, 0x5947, 0xA960, 0x5948, 0xA961, 0x5944, 0xA962, 0x5954, 0xA963, 0x59BE, 0xA964, 0x59BB, 0xA965, 0x59D4, - 0xA966, 0x59B9, 0xA967, 0x59AE, 0xA968, 0x59D1, 0xA969, 0x59C6, 0xA96A, 0x59D0, 0xA96B, 0x59CD, 0xA96C, 0x59CB, 0xA96D, 0x59D3, - 0xA96E, 0x59CA, 0xA96F, 0x59AF, 0xA970, 0x59B3, 0xA971, 0x59D2, 0xA972, 0x59C5, 0xA973, 0x5B5F, 0xA974, 0x5B64, 0xA975, 0x5B63, - 0xA976, 0x5B97, 0xA977, 0x5B9A, 0xA978, 0x5B98, 0xA979, 0x5B9C, 0xA97A, 0x5B99, 0xA97B, 0x5B9B, 0xA97C, 0x5C1A, 0xA97D, 0x5C48, - 0xA97E, 0x5C45, 0xA9A1, 0x5C46, 0xA9A2, 0x5CB7, 0xA9A3, 0x5CA1, 0xA9A4, 0x5CB8, 0xA9A5, 0x5CA9, 0xA9A6, 0x5CAB, 0xA9A7, 0x5CB1, - 0xA9A8, 0x5CB3, 0xA9A9, 0x5E18, 0xA9AA, 0x5E1A, 0xA9AB, 0x5E16, 0xA9AC, 0x5E15, 0xA9AD, 0x5E1B, 0xA9AE, 0x5E11, 0xA9AF, 0x5E78, - 0xA9B0, 0x5E9A, 0xA9B1, 0x5E97, 0xA9B2, 0x5E9C, 0xA9B3, 0x5E95, 0xA9B4, 0x5E96, 0xA9B5, 0x5EF6, 0xA9B6, 0x5F26, 0xA9B7, 0x5F27, - 0xA9B8, 0x5F29, 0xA9B9, 0x5F80, 0xA9BA, 0x5F81, 0xA9BB, 0x5F7F, 0xA9BC, 0x5F7C, 0xA9BD, 0x5FDD, 0xA9BE, 0x5FE0, 0xA9BF, 0x5FFD, - 0xA9C0, 0x5FF5, 0xA9C1, 0x5FFF, 0xA9C2, 0x600F, 0xA9C3, 0x6014, 0xA9C4, 0x602F, 0xA9C5, 0x6035, 0xA9C6, 0x6016, 0xA9C7, 0x602A, - 0xA9C8, 0x6015, 0xA9C9, 0x6021, 0xA9CA, 0x6027, 0xA9CB, 0x6029, 0xA9CC, 0x602B, 0xA9CD, 0x601B, 0xA9CE, 0x6216, 0xA9CF, 0x6215, - 0xA9D0, 0x623F, 0xA9D1, 0x623E, 0xA9D2, 0x6240, 0xA9D3, 0x627F, 0xA9D4, 0x62C9, 0xA9D5, 0x62CC, 0xA9D6, 0x62C4, 0xA9D7, 0x62BF, - 0xA9D8, 0x62C2, 0xA9D9, 0x62B9, 0xA9DA, 0x62D2, 0xA9DB, 0x62DB, 0xA9DC, 0x62AB, 0xA9DD, 0x62D3, 0xA9DE, 0x62D4, 0xA9DF, 0x62CB, - 0xA9E0, 0x62C8, 0xA9E1, 0x62A8, 0xA9E2, 0x62BD, 0xA9E3, 0x62BC, 0xA9E4, 0x62D0, 0xA9E5, 0x62D9, 0xA9E6, 0x62C7, 0xA9E7, 0x62CD, - 0xA9E8, 0x62B5, 0xA9E9, 0x62DA, 0xA9EA, 0x62B1, 0xA9EB, 0x62D8, 0xA9EC, 0x62D6, 0xA9ED, 0x62D7, 0xA9EE, 0x62C6, 0xA9EF, 0x62AC, - 0xA9F0, 0x62CE, 0xA9F1, 0x653E, 0xA9F2, 0x65A7, 0xA9F3, 0x65BC, 0xA9F4, 0x65FA, 0xA9F5, 0x6614, 0xA9F6, 0x6613, 0xA9F7, 0x660C, - 0xA9F8, 0x6606, 0xA9F9, 0x6602, 0xA9FA, 0x660E, 0xA9FB, 0x6600, 0xA9FC, 0x660F, 0xA9FD, 0x6615, 0xA9FE, 0x660A, 0xAA40, 0x6607, - 0xAA41, 0x670D, 0xAA42, 0x670B, 0xAA43, 0x676D, 0xAA44, 0x678B, 0xAA45, 0x6795, 0xAA46, 0x6771, 0xAA47, 0x679C, 0xAA48, 0x6773, - 0xAA49, 0x6777, 0xAA4A, 0x6787, 0xAA4B, 0x679D, 0xAA4C, 0x6797, 0xAA4D, 0x676F, 0xAA4E, 0x6770, 0xAA4F, 0x677F, 0xAA50, 0x6789, - 0xAA51, 0x677E, 0xAA52, 0x6790, 0xAA53, 0x6775, 0xAA54, 0x679A, 0xAA55, 0x6793, 0xAA56, 0x677C, 0xAA57, 0x676A, 0xAA58, 0x6772, - 0xAA59, 0x6B23, 0xAA5A, 0x6B66, 0xAA5B, 0x6B67, 0xAA5C, 0x6B7F, 0xAA5D, 0x6C13, 0xAA5E, 0x6C1B, 0xAA5F, 0x6CE3, 0xAA60, 0x6CE8, - 0xAA61, 0x6CF3, 0xAA62, 0x6CB1, 0xAA63, 0x6CCC, 0xAA64, 0x6CE5, 0xAA65, 0x6CB3, 0xAA66, 0x6CBD, 0xAA67, 0x6CBE, 0xAA68, 0x6CBC, - 0xAA69, 0x6CE2, 0xAA6A, 0x6CAB, 0xAA6B, 0x6CD5, 0xAA6C, 0x6CD3, 0xAA6D, 0x6CB8, 0xAA6E, 0x6CC4, 0xAA6F, 0x6CB9, 0xAA70, 0x6CC1, - 0xAA71, 0x6CAE, 0xAA72, 0x6CD7, 0xAA73, 0x6CC5, 0xAA74, 0x6CF1, 0xAA75, 0x6CBF, 0xAA76, 0x6CBB, 0xAA77, 0x6CE1, 0xAA78, 0x6CDB, - 0xAA79, 0x6CCA, 0xAA7A, 0x6CAC, 0xAA7B, 0x6CEF, 0xAA7C, 0x6CDC, 0xAA7D, 0x6CD6, 0xAA7E, 0x6CE0, 0xAAA1, 0x7095, 0xAAA2, 0x708E, - 0xAAA3, 0x7092, 0xAAA4, 0x708A, 0xAAA5, 0x7099, 0xAAA6, 0x722C, 0xAAA7, 0x722D, 0xAAA8, 0x7238, 0xAAA9, 0x7248, 0xAAAA, 0x7267, - 0xAAAB, 0x7269, 0xAAAC, 0x72C0, 0xAAAD, 0x72CE, 0xAAAE, 0x72D9, 0xAAAF, 0x72D7, 0xAAB0, 0x72D0, 0xAAB1, 0x73A9, 0xAAB2, 0x73A8, - 0xAAB3, 0x739F, 0xAAB4, 0x73AB, 0xAAB5, 0x73A5, 0xAAB6, 0x753D, 0xAAB7, 0x759D, 0xAAB8, 0x7599, 0xAAB9, 0x759A, 0xAABA, 0x7684, - 0xAABB, 0x76C2, 0xAABC, 0x76F2, 0xAABD, 0x76F4, 0xAABE, 0x77E5, 0xAABF, 0x77FD, 0xAAC0, 0x793E, 0xAAC1, 0x7940, 0xAAC2, 0x7941, - 0xAAC3, 0x79C9, 0xAAC4, 0x79C8, 0xAAC5, 0x7A7A, 0xAAC6, 0x7A79, 0xAAC7, 0x7AFA, 0xAAC8, 0x7CFE, 0xAAC9, 0x7F54, 0xAACA, 0x7F8C, - 0xAACB, 0x7F8B, 0xAACC, 0x8005, 0xAACD, 0x80BA, 0xAACE, 0x80A5, 0xAACF, 0x80A2, 0xAAD0, 0x80B1, 0xAAD1, 0x80A1, 0xAAD2, 0x80AB, - 0xAAD3, 0x80A9, 0xAAD4, 0x80B4, 0xAAD5, 0x80AA, 0xAAD6, 0x80AF, 0xAAD7, 0x81E5, 0xAAD8, 0x81FE, 0xAAD9, 0x820D, 0xAADA, 0x82B3, - 0xAADB, 0x829D, 0xAADC, 0x8299, 0xAADD, 0x82AD, 0xAADE, 0x82BD, 0xAADF, 0x829F, 0xAAE0, 0x82B9, 0xAAE1, 0x82B1, 0xAAE2, 0x82AC, - 0xAAE3, 0x82A5, 0xAAE4, 0x82AF, 0xAAE5, 0x82B8, 0xAAE6, 0x82A3, 0xAAE7, 0x82B0, 0xAAE8, 0x82BE, 0xAAE9, 0x82B7, 0xAAEA, 0x864E, - 0xAAEB, 0x8671, 0xAAEC, 0x521D, 0xAAED, 0x8868, 0xAAEE, 0x8ECB, 0xAAEF, 0x8FCE, 0xAAF0, 0x8FD4, 0xAAF1, 0x8FD1, 0xAAF2, 0x90B5, - 0xAAF3, 0x90B8, 0xAAF4, 0x90B1, 0xAAF5, 0x90B6, 0xAAF6, 0x91C7, 0xAAF7, 0x91D1, 0xAAF8, 0x9577, 0xAAF9, 0x9580, 0xAAFA, 0x961C, - 0xAAFB, 0x9640, 0xAAFC, 0x963F, 0xAAFD, 0x963B, 0xAAFE, 0x9644, 0xAB40, 0x9642, 0xAB41, 0x96B9, 0xAB42, 0x96E8, 0xAB43, 0x9752, - 0xAB44, 0x975E, 0xAB45, 0x4E9F, 0xAB46, 0x4EAD, 0xAB47, 0x4EAE, 0xAB48, 0x4FE1, 0xAB49, 0x4FB5, 0xAB4A, 0x4FAF, 0xAB4B, 0x4FBF, - 0xAB4C, 0x4FE0, 0xAB4D, 0x4FD1, 0xAB4E, 0x4FCF, 0xAB4F, 0x4FDD, 0xAB50, 0x4FC3, 0xAB51, 0x4FB6, 0xAB52, 0x4FD8, 0xAB53, 0x4FDF, - 0xAB54, 0x4FCA, 0xAB55, 0x4FD7, 0xAB56, 0x4FAE, 0xAB57, 0x4FD0, 0xAB58, 0x4FC4, 0xAB59, 0x4FC2, 0xAB5A, 0x4FDA, 0xAB5B, 0x4FCE, - 0xAB5C, 0x4FDE, 0xAB5D, 0x4FB7, 0xAB5E, 0x5157, 0xAB5F, 0x5192, 0xAB60, 0x5191, 0xAB61, 0x51A0, 0xAB62, 0x524E, 0xAB63, 0x5243, - 0xAB64, 0x524A, 0xAB65, 0x524D, 0xAB66, 0x524C, 0xAB67, 0x524B, 0xAB68, 0x5247, 0xAB69, 0x52C7, 0xAB6A, 0x52C9, 0xAB6B, 0x52C3, - 0xAB6C, 0x52C1, 0xAB6D, 0x530D, 0xAB6E, 0x5357, 0xAB6F, 0x537B, 0xAB70, 0x539A, 0xAB71, 0x53DB, 0xAB72, 0x54AC, 0xAB73, 0x54C0, - 0xAB74, 0x54A8, 0xAB75, 0x54CE, 0xAB76, 0x54C9, 0xAB77, 0x54B8, 0xAB78, 0x54A6, 0xAB79, 0x54B3, 0xAB7A, 0x54C7, 0xAB7B, 0x54C2, - 0xAB7C, 0x54BD, 0xAB7D, 0x54AA, 0xAB7E, 0x54C1, 0xABA1, 0x54C4, 0xABA2, 0x54C8, 0xABA3, 0x54AF, 0xABA4, 0x54AB, 0xABA5, 0x54B1, - 0xABA6, 0x54BB, 0xABA7, 0x54A9, 0xABA8, 0x54A7, 0xABA9, 0x54BF, 0xABAA, 0x56FF, 0xABAB, 0x5782, 0xABAC, 0x578B, 0xABAD, 0x57A0, - 0xABAE, 0x57A3, 0xABAF, 0x57A2, 0xABB0, 0x57CE, 0xABB1, 0x57AE, 0xABB2, 0x5793, 0xABB3, 0x5955, 0xABB4, 0x5951, 0xABB5, 0x594F, - 0xABB6, 0x594E, 0xABB7, 0x5950, 0xABB8, 0x59DC, 0xABB9, 0x59D8, 0xABBA, 0x59FF, 0xABBB, 0x59E3, 0xABBC, 0x59E8, 0xABBD, 0x5A03, - 0xABBE, 0x59E5, 0xABBF, 0x59EA, 0xABC0, 0x59DA, 0xABC1, 0x59E6, 0xABC2, 0x5A01, 0xABC3, 0x59FB, 0xABC4, 0x5B69, 0xABC5, 0x5BA3, - 0xABC6, 0x5BA6, 0xABC7, 0x5BA4, 0xABC8, 0x5BA2, 0xABC9, 0x5BA5, 0xABCA, 0x5C01, 0xABCB, 0x5C4E, 0xABCC, 0x5C4F, 0xABCD, 0x5C4D, - 0xABCE, 0x5C4B, 0xABCF, 0x5CD9, 0xABD0, 0x5CD2, 0xABD1, 0x5DF7, 0xABD2, 0x5E1D, 0xABD3, 0x5E25, 0xABD4, 0x5E1F, 0xABD5, 0x5E7D, - 0xABD6, 0x5EA0, 0xABD7, 0x5EA6, 0xABD8, 0x5EFA, 0xABD9, 0x5F08, 0xABDA, 0x5F2D, 0xABDB, 0x5F65, 0xABDC, 0x5F88, 0xABDD, 0x5F85, - 0xABDE, 0x5F8A, 0xABDF, 0x5F8B, 0xABE0, 0x5F87, 0xABE1, 0x5F8C, 0xABE2, 0x5F89, 0xABE3, 0x6012, 0xABE4, 0x601D, 0xABE5, 0x6020, - 0xABE6, 0x6025, 0xABE7, 0x600E, 0xABE8, 0x6028, 0xABE9, 0x604D, 0xABEA, 0x6070, 0xABEB, 0x6068, 0xABEC, 0x6062, 0xABED, 0x6046, - 0xABEE, 0x6043, 0xABEF, 0x606C, 0xABF0, 0x606B, 0xABF1, 0x606A, 0xABF2, 0x6064, 0xABF3, 0x6241, 0xABF4, 0x62DC, 0xABF5, 0x6316, - 0xABF6, 0x6309, 0xABF7, 0x62FC, 0xABF8, 0x62ED, 0xABF9, 0x6301, 0xABFA, 0x62EE, 0xABFB, 0x62FD, 0xABFC, 0x6307, 0xABFD, 0x62F1, - 0xABFE, 0x62F7, 0xAC40, 0x62EF, 0xAC41, 0x62EC, 0xAC42, 0x62FE, 0xAC43, 0x62F4, 0xAC44, 0x6311, 0xAC45, 0x6302, 0xAC46, 0x653F, - 0xAC47, 0x6545, 0xAC48, 0x65AB, 0xAC49, 0x65BD, 0xAC4A, 0x65E2, 0xAC4B, 0x6625, 0xAC4C, 0x662D, 0xAC4D, 0x6620, 0xAC4E, 0x6627, - 0xAC4F, 0x662F, 0xAC50, 0x661F, 0xAC51, 0x6628, 0xAC52, 0x6631, 0xAC53, 0x6624, 0xAC54, 0x66F7, 0xAC55, 0x67FF, 0xAC56, 0x67D3, - 0xAC57, 0x67F1, 0xAC58, 0x67D4, 0xAC59, 0x67D0, 0xAC5A, 0x67EC, 0xAC5B, 0x67B6, 0xAC5C, 0x67AF, 0xAC5D, 0x67F5, 0xAC5E, 0x67E9, - 0xAC5F, 0x67EF, 0xAC60, 0x67C4, 0xAC61, 0x67D1, 0xAC62, 0x67B4, 0xAC63, 0x67DA, 0xAC64, 0x67E5, 0xAC65, 0x67B8, 0xAC66, 0x67CF, - 0xAC67, 0x67DE, 0xAC68, 0x67F3, 0xAC69, 0x67B0, 0xAC6A, 0x67D9, 0xAC6B, 0x67E2, 0xAC6C, 0x67DD, 0xAC6D, 0x67D2, 0xAC6E, 0x6B6A, - 0xAC6F, 0x6B83, 0xAC70, 0x6B86, 0xAC71, 0x6BB5, 0xAC72, 0x6BD2, 0xAC73, 0x6BD7, 0xAC74, 0x6C1F, 0xAC75, 0x6CC9, 0xAC76, 0x6D0B, - 0xAC77, 0x6D32, 0xAC78, 0x6D2A, 0xAC79, 0x6D41, 0xAC7A, 0x6D25, 0xAC7B, 0x6D0C, 0xAC7C, 0x6D31, 0xAC7D, 0x6D1E, 0xAC7E, 0x6D17, - 0xACA1, 0x6D3B, 0xACA2, 0x6D3D, 0xACA3, 0x6D3E, 0xACA4, 0x6D36, 0xACA5, 0x6D1B, 0xACA6, 0x6CF5, 0xACA7, 0x6D39, 0xACA8, 0x6D27, - 0xACA9, 0x6D38, 0xACAA, 0x6D29, 0xACAB, 0x6D2E, 0xACAC, 0x6D35, 0xACAD, 0x6D0E, 0xACAE, 0x6D2B, 0xACAF, 0x70AB, 0xACB0, 0x70BA, - 0xACB1, 0x70B3, 0xACB2, 0x70AC, 0xACB3, 0x70AF, 0xACB4, 0x70AD, 0xACB5, 0x70B8, 0xACB6, 0x70AE, 0xACB7, 0x70A4, 0xACB8, 0x7230, - 0xACB9, 0x7272, 0xACBA, 0x726F, 0xACBB, 0x7274, 0xACBC, 0x72E9, 0xACBD, 0x72E0, 0xACBE, 0x72E1, 0xACBF, 0x73B7, 0xACC0, 0x73CA, - 0xACC1, 0x73BB, 0xACC2, 0x73B2, 0xACC3, 0x73CD, 0xACC4, 0x73C0, 0xACC5, 0x73B3, 0xACC6, 0x751A, 0xACC7, 0x752D, 0xACC8, 0x754F, - 0xACC9, 0x754C, 0xACCA, 0x754E, 0xACCB, 0x754B, 0xACCC, 0x75AB, 0xACCD, 0x75A4, 0xACCE, 0x75A5, 0xACCF, 0x75A2, 0xACD0, 0x75A3, - 0xACD1, 0x7678, 0xACD2, 0x7686, 0xACD3, 0x7687, 0xACD4, 0x7688, 0xACD5, 0x76C8, 0xACD6, 0x76C6, 0xACD7, 0x76C3, 0xACD8, 0x76C5, - 0xACD9, 0x7701, 0xACDA, 0x76F9, 0xACDB, 0x76F8, 0xACDC, 0x7709, 0xACDD, 0x770B, 0xACDE, 0x76FE, 0xACDF, 0x76FC, 0xACE0, 0x7707, - 0xACE1, 0x77DC, 0xACE2, 0x7802, 0xACE3, 0x7814, 0xACE4, 0x780C, 0xACE5, 0x780D, 0xACE6, 0x7946, 0xACE7, 0x7949, 0xACE8, 0x7948, - 0xACE9, 0x7947, 0xACEA, 0x79B9, 0xACEB, 0x79BA, 0xACEC, 0x79D1, 0xACED, 0x79D2, 0xACEE, 0x79CB, 0xACEF, 0x7A7F, 0xACF0, 0x7A81, - 0xACF1, 0x7AFF, 0xACF2, 0x7AFD, 0xACF3, 0x7C7D, 0xACF4, 0x7D02, 0xACF5, 0x7D05, 0xACF6, 0x7D00, 0xACF7, 0x7D09, 0xACF8, 0x7D07, - 0xACF9, 0x7D04, 0xACFA, 0x7D06, 0xACFB, 0x7F38, 0xACFC, 0x7F8E, 0xACFD, 0x7FBF, 0xACFE, 0x8004, 0xAD40, 0x8010, 0xAD41, 0x800D, - 0xAD42, 0x8011, 0xAD43, 0x8036, 0xAD44, 0x80D6, 0xAD45, 0x80E5, 0xAD46, 0x80DA, 0xAD47, 0x80C3, 0xAD48, 0x80C4, 0xAD49, 0x80CC, - 0xAD4A, 0x80E1, 0xAD4B, 0x80DB, 0xAD4C, 0x80CE, 0xAD4D, 0x80DE, 0xAD4E, 0x80E4, 0xAD4F, 0x80DD, 0xAD50, 0x81F4, 0xAD51, 0x8222, - 0xAD52, 0x82E7, 0xAD53, 0x8303, 0xAD54, 0x8305, 0xAD55, 0x82E3, 0xAD56, 0x82DB, 0xAD57, 0x82E6, 0xAD58, 0x8304, 0xAD59, 0x82E5, - 0xAD5A, 0x8302, 0xAD5B, 0x8309, 0xAD5C, 0x82D2, 0xAD5D, 0x82D7, 0xAD5E, 0x82F1, 0xAD5F, 0x8301, 0xAD60, 0x82DC, 0xAD61, 0x82D4, - 0xAD62, 0x82D1, 0xAD63, 0x82DE, 0xAD64, 0x82D3, 0xAD65, 0x82DF, 0xAD66, 0x82EF, 0xAD67, 0x8306, 0xAD68, 0x8650, 0xAD69, 0x8679, - 0xAD6A, 0x867B, 0xAD6B, 0x867A, 0xAD6C, 0x884D, 0xAD6D, 0x886B, 0xAD6E, 0x8981, 0xAD6F, 0x89D4, 0xAD70, 0x8A08, 0xAD71, 0x8A02, - 0xAD72, 0x8A03, 0xAD73, 0x8C9E, 0xAD74, 0x8CA0, 0xAD75, 0x8D74, 0xAD76, 0x8D73, 0xAD77, 0x8DB4, 0xAD78, 0x8ECD, 0xAD79, 0x8ECC, - 0xAD7A, 0x8FF0, 0xAD7B, 0x8FE6, 0xAD7C, 0x8FE2, 0xAD7D, 0x8FEA, 0xAD7E, 0x8FE5, 0xADA1, 0x8FED, 0xADA2, 0x8FEB, 0xADA3, 0x8FE4, - 0xADA4, 0x8FE8, 0xADA5, 0x90CA, 0xADA6, 0x90CE, 0xADA7, 0x90C1, 0xADA8, 0x90C3, 0xADA9, 0x914B, 0xADAA, 0x914A, 0xADAB, 0x91CD, - 0xADAC, 0x9582, 0xADAD, 0x9650, 0xADAE, 0x964B, 0xADAF, 0x964C, 0xADB0, 0x964D, 0xADB1, 0x9762, 0xADB2, 0x9769, 0xADB3, 0x97CB, - 0xADB4, 0x97ED, 0xADB5, 0x97F3, 0xADB6, 0x9801, 0xADB7, 0x98A8, 0xADB8, 0x98DB, 0xADB9, 0x98DF, 0xADBA, 0x9996, 0xADBB, 0x9999, - 0xADBC, 0x4E58, 0xADBD, 0x4EB3, 0xADBE, 0x500C, 0xADBF, 0x500D, 0xADC0, 0x5023, 0xADC1, 0x4FEF, 0xADC2, 0x5026, 0xADC3, 0x5025, - 0xADC4, 0x4FF8, 0xADC5, 0x5029, 0xADC6, 0x5016, 0xADC7, 0x5006, 0xADC8, 0x503C, 0xADC9, 0x501F, 0xADCA, 0x501A, 0xADCB, 0x5012, - 0xADCC, 0x5011, 0xADCD, 0x4FFA, 0xADCE, 0x5000, 0xADCF, 0x5014, 0xADD0, 0x5028, 0xADD1, 0x4FF1, 0xADD2, 0x5021, 0xADD3, 0x500B, - 0xADD4, 0x5019, 0xADD5, 0x5018, 0xADD6, 0x4FF3, 0xADD7, 0x4FEE, 0xADD8, 0x502D, 0xADD9, 0x502A, 0xADDA, 0x4FFE, 0xADDB, 0x502B, - 0xADDC, 0x5009, 0xADDD, 0x517C, 0xADDE, 0x51A4, 0xADDF, 0x51A5, 0xADE0, 0x51A2, 0xADE1, 0x51CD, 0xADE2, 0x51CC, 0xADE3, 0x51C6, - 0xADE4, 0x51CB, 0xADE5, 0x5256, 0xADE6, 0x525C, 0xADE7, 0x5254, 0xADE8, 0x525B, 0xADE9, 0x525D, 0xADEA, 0x532A, 0xADEB, 0x537F, - 0xADEC, 0x539F, 0xADED, 0x539D, 0xADEE, 0x53DF, 0xADEF, 0x54E8, 0xADF0, 0x5510, 0xADF1, 0x5501, 0xADF2, 0x5537, 0xADF3, 0x54FC, - 0xADF4, 0x54E5, 0xADF5, 0x54F2, 0xADF6, 0x5506, 0xADF7, 0x54FA, 0xADF8, 0x5514, 0xADF9, 0x54E9, 0xADFA, 0x54ED, 0xADFB, 0x54E1, - 0xADFC, 0x5509, 0xADFD, 0x54EE, 0xADFE, 0x54EA, 0xAE40, 0x54E6, 0xAE41, 0x5527, 0xAE42, 0x5507, 0xAE43, 0x54FD, 0xAE44, 0x550F, - 0xAE45, 0x5703, 0xAE46, 0x5704, 0xAE47, 0x57C2, 0xAE48, 0x57D4, 0xAE49, 0x57CB, 0xAE4A, 0x57C3, 0xAE4B, 0x5809, 0xAE4C, 0x590F, - 0xAE4D, 0x5957, 0xAE4E, 0x5958, 0xAE4F, 0x595A, 0xAE50, 0x5A11, 0xAE51, 0x5A18, 0xAE52, 0x5A1C, 0xAE53, 0x5A1F, 0xAE54, 0x5A1B, - 0xAE55, 0x5A13, 0xAE56, 0x59EC, 0xAE57, 0x5A20, 0xAE58, 0x5A23, 0xAE59, 0x5A29, 0xAE5A, 0x5A25, 0xAE5B, 0x5A0C, 0xAE5C, 0x5A09, - 0xAE5D, 0x5B6B, 0xAE5E, 0x5C58, 0xAE5F, 0x5BB0, 0xAE60, 0x5BB3, 0xAE61, 0x5BB6, 0xAE62, 0x5BB4, 0xAE63, 0x5BAE, 0xAE64, 0x5BB5, - 0xAE65, 0x5BB9, 0xAE66, 0x5BB8, 0xAE67, 0x5C04, 0xAE68, 0x5C51, 0xAE69, 0x5C55, 0xAE6A, 0x5C50, 0xAE6B, 0x5CED, 0xAE6C, 0x5CFD, - 0xAE6D, 0x5CFB, 0xAE6E, 0x5CEA, 0xAE6F, 0x5CE8, 0xAE70, 0x5CF0, 0xAE71, 0x5CF6, 0xAE72, 0x5D01, 0xAE73, 0x5CF4, 0xAE74, 0x5DEE, - 0xAE75, 0x5E2D, 0xAE76, 0x5E2B, 0xAE77, 0x5EAB, 0xAE78, 0x5EAD, 0xAE79, 0x5EA7, 0xAE7A, 0x5F31, 0xAE7B, 0x5F92, 0xAE7C, 0x5F91, - 0xAE7D, 0x5F90, 0xAE7E, 0x6059, 0xAEA1, 0x6063, 0xAEA2, 0x6065, 0xAEA3, 0x6050, 0xAEA4, 0x6055, 0xAEA5, 0x606D, 0xAEA6, 0x6069, - 0xAEA7, 0x606F, 0xAEA8, 0x6084, 0xAEA9, 0x609F, 0xAEAA, 0x609A, 0xAEAB, 0x608D, 0xAEAC, 0x6094, 0xAEAD, 0x608C, 0xAEAE, 0x6085, - 0xAEAF, 0x6096, 0xAEB0, 0x6247, 0xAEB1, 0x62F3, 0xAEB2, 0x6308, 0xAEB3, 0x62FF, 0xAEB4, 0x634E, 0xAEB5, 0x633E, 0xAEB6, 0x632F, - 0xAEB7, 0x6355, 0xAEB8, 0x6342, 0xAEB9, 0x6346, 0xAEBA, 0x634F, 0xAEBB, 0x6349, 0xAEBC, 0x633A, 0xAEBD, 0x6350, 0xAEBE, 0x633D, - 0xAEBF, 0x632A, 0xAEC0, 0x632B, 0xAEC1, 0x6328, 0xAEC2, 0x634D, 0xAEC3, 0x634C, 0xAEC4, 0x6548, 0xAEC5, 0x6549, 0xAEC6, 0x6599, - 0xAEC7, 0x65C1, 0xAEC8, 0x65C5, 0xAEC9, 0x6642, 0xAECA, 0x6649, 0xAECB, 0x664F, 0xAECC, 0x6643, 0xAECD, 0x6652, 0xAECE, 0x664C, - 0xAECF, 0x6645, 0xAED0, 0x6641, 0xAED1, 0x66F8, 0xAED2, 0x6714, 0xAED3, 0x6715, 0xAED4, 0x6717, 0xAED5, 0x6821, 0xAED6, 0x6838, - 0xAED7, 0x6848, 0xAED8, 0x6846, 0xAED9, 0x6853, 0xAEDA, 0x6839, 0xAEDB, 0x6842, 0xAEDC, 0x6854, 0xAEDD, 0x6829, 0xAEDE, 0x68B3, - 0xAEDF, 0x6817, 0xAEE0, 0x684C, 0xAEE1, 0x6851, 0xAEE2, 0x683D, 0xAEE3, 0x67F4, 0xAEE4, 0x6850, 0xAEE5, 0x6840, 0xAEE6, 0x683C, - 0xAEE7, 0x6843, 0xAEE8, 0x682A, 0xAEE9, 0x6845, 0xAEEA, 0x6813, 0xAEEB, 0x6818, 0xAEEC, 0x6841, 0xAEED, 0x6B8A, 0xAEEE, 0x6B89, - 0xAEEF, 0x6BB7, 0xAEF0, 0x6C23, 0xAEF1, 0x6C27, 0xAEF2, 0x6C28, 0xAEF3, 0x6C26, 0xAEF4, 0x6C24, 0xAEF5, 0x6CF0, 0xAEF6, 0x6D6A, - 0xAEF7, 0x6D95, 0xAEF8, 0x6D88, 0xAEF9, 0x6D87, 0xAEFA, 0x6D66, 0xAEFB, 0x6D78, 0xAEFC, 0x6D77, 0xAEFD, 0x6D59, 0xAEFE, 0x6D93, - 0xAF40, 0x6D6C, 0xAF41, 0x6D89, 0xAF42, 0x6D6E, 0xAF43, 0x6D5A, 0xAF44, 0x6D74, 0xAF45, 0x6D69, 0xAF46, 0x6D8C, 0xAF47, 0x6D8A, - 0xAF48, 0x6D79, 0xAF49, 0x6D85, 0xAF4A, 0x6D65, 0xAF4B, 0x6D94, 0xAF4C, 0x70CA, 0xAF4D, 0x70D8, 0xAF4E, 0x70E4, 0xAF4F, 0x70D9, - 0xAF50, 0x70C8, 0xAF51, 0x70CF, 0xAF52, 0x7239, 0xAF53, 0x7279, 0xAF54, 0x72FC, 0xAF55, 0x72F9, 0xAF56, 0x72FD, 0xAF57, 0x72F8, - 0xAF58, 0x72F7, 0xAF59, 0x7386, 0xAF5A, 0x73ED, 0xAF5B, 0x7409, 0xAF5C, 0x73EE, 0xAF5D, 0x73E0, 0xAF5E, 0x73EA, 0xAF5F, 0x73DE, - 0xAF60, 0x7554, 0xAF61, 0x755D, 0xAF62, 0x755C, 0xAF63, 0x755A, 0xAF64, 0x7559, 0xAF65, 0x75BE, 0xAF66, 0x75C5, 0xAF67, 0x75C7, - 0xAF68, 0x75B2, 0xAF69, 0x75B3, 0xAF6A, 0x75BD, 0xAF6B, 0x75BC, 0xAF6C, 0x75B9, 0xAF6D, 0x75C2, 0xAF6E, 0x75B8, 0xAF6F, 0x768B, - 0xAF70, 0x76B0, 0xAF71, 0x76CA, 0xAF72, 0x76CD, 0xAF73, 0x76CE, 0xAF74, 0x7729, 0xAF75, 0x771F, 0xAF76, 0x7720, 0xAF77, 0x7728, - 0xAF78, 0x77E9, 0xAF79, 0x7830, 0xAF7A, 0x7827, 0xAF7B, 0x7838, 0xAF7C, 0x781D, 0xAF7D, 0x7834, 0xAF7E, 0x7837, 0xAFA1, 0x7825, - 0xAFA2, 0x782D, 0xAFA3, 0x7820, 0xAFA4, 0x781F, 0xAFA5, 0x7832, 0xAFA6, 0x7955, 0xAFA7, 0x7950, 0xAFA8, 0x7960, 0xAFA9, 0x795F, - 0xAFAA, 0x7956, 0xAFAB, 0x795E, 0xAFAC, 0x795D, 0xAFAD, 0x7957, 0xAFAE, 0x795A, 0xAFAF, 0x79E4, 0xAFB0, 0x79E3, 0xAFB1, 0x79E7, - 0xAFB2, 0x79DF, 0xAFB3, 0x79E6, 0xAFB4, 0x79E9, 0xAFB5, 0x79D8, 0xAFB6, 0x7A84, 0xAFB7, 0x7A88, 0xAFB8, 0x7AD9, 0xAFB9, 0x7B06, - 0xAFBA, 0x7B11, 0xAFBB, 0x7C89, 0xAFBC, 0x7D21, 0xAFBD, 0x7D17, 0xAFBE, 0x7D0B, 0xAFBF, 0x7D0A, 0xAFC0, 0x7D20, 0xAFC1, 0x7D22, - 0xAFC2, 0x7D14, 0xAFC3, 0x7D10, 0xAFC4, 0x7D15, 0xAFC5, 0x7D1A, 0xAFC6, 0x7D1C, 0xAFC7, 0x7D0D, 0xAFC8, 0x7D19, 0xAFC9, 0x7D1B, - 0xAFCA, 0x7F3A, 0xAFCB, 0x7F5F, 0xAFCC, 0x7F94, 0xAFCD, 0x7FC5, 0xAFCE, 0x7FC1, 0xAFCF, 0x8006, 0xAFD0, 0x8018, 0xAFD1, 0x8015, - 0xAFD2, 0x8019, 0xAFD3, 0x8017, 0xAFD4, 0x803D, 0xAFD5, 0x803F, 0xAFD6, 0x80F1, 0xAFD7, 0x8102, 0xAFD8, 0x80F0, 0xAFD9, 0x8105, - 0xAFDA, 0x80ED, 0xAFDB, 0x80F4, 0xAFDC, 0x8106, 0xAFDD, 0x80F8, 0xAFDE, 0x80F3, 0xAFDF, 0x8108, 0xAFE0, 0x80FD, 0xAFE1, 0x810A, - 0xAFE2, 0x80FC, 0xAFE3, 0x80EF, 0xAFE4, 0x81ED, 0xAFE5, 0x81EC, 0xAFE6, 0x8200, 0xAFE7, 0x8210, 0xAFE8, 0x822A, 0xAFE9, 0x822B, - 0xAFEA, 0x8228, 0xAFEB, 0x822C, 0xAFEC, 0x82BB, 0xAFED, 0x832B, 0xAFEE, 0x8352, 0xAFEF, 0x8354, 0xAFF0, 0x834A, 0xAFF1, 0x8338, - 0xAFF2, 0x8350, 0xAFF3, 0x8349, 0xAFF4, 0x8335, 0xAFF5, 0x8334, 0xAFF6, 0x834F, 0xAFF7, 0x8332, 0xAFF8, 0x8339, 0xAFF9, 0x8336, - 0xAFFA, 0x8317, 0xAFFB, 0x8340, 0xAFFC, 0x8331, 0xAFFD, 0x8328, 0xAFFE, 0x8343, 0xB040, 0x8654, 0xB041, 0x868A, 0xB042, 0x86AA, - 0xB043, 0x8693, 0xB044, 0x86A4, 0xB045, 0x86A9, 0xB046, 0x868C, 0xB047, 0x86A3, 0xB048, 0x869C, 0xB049, 0x8870, 0xB04A, 0x8877, - 0xB04B, 0x8881, 0xB04C, 0x8882, 0xB04D, 0x887D, 0xB04E, 0x8879, 0xB04F, 0x8A18, 0xB050, 0x8A10, 0xB051, 0x8A0E, 0xB052, 0x8A0C, - 0xB053, 0x8A15, 0xB054, 0x8A0A, 0xB055, 0x8A17, 0xB056, 0x8A13, 0xB057, 0x8A16, 0xB058, 0x8A0F, 0xB059, 0x8A11, 0xB05A, 0x8C48, - 0xB05B, 0x8C7A, 0xB05C, 0x8C79, 0xB05D, 0x8CA1, 0xB05E, 0x8CA2, 0xB05F, 0x8D77, 0xB060, 0x8EAC, 0xB061, 0x8ED2, 0xB062, 0x8ED4, - 0xB063, 0x8ECF, 0xB064, 0x8FB1, 0xB065, 0x9001, 0xB066, 0x9006, 0xB067, 0x8FF7, 0xB068, 0x9000, 0xB069, 0x8FFA, 0xB06A, 0x8FF4, - 0xB06B, 0x9003, 0xB06C, 0x8FFD, 0xB06D, 0x9005, 0xB06E, 0x8FF8, 0xB06F, 0x9095, 0xB070, 0x90E1, 0xB071, 0x90DD, 0xB072, 0x90E2, - 0xB073, 0x9152, 0xB074, 0x914D, 0xB075, 0x914C, 0xB076, 0x91D8, 0xB077, 0x91DD, 0xB078, 0x91D7, 0xB079, 0x91DC, 0xB07A, 0x91D9, - 0xB07B, 0x9583, 0xB07C, 0x9662, 0xB07D, 0x9663, 0xB07E, 0x9661, 0xB0A1, 0x965B, 0xB0A2, 0x965D, 0xB0A3, 0x9664, 0xB0A4, 0x9658, - 0xB0A5, 0x965E, 0xB0A6, 0x96BB, 0xB0A7, 0x98E2, 0xB0A8, 0x99AC, 0xB0A9, 0x9AA8, 0xB0AA, 0x9AD8, 0xB0AB, 0x9B25, 0xB0AC, 0x9B32, - 0xB0AD, 0x9B3C, 0xB0AE, 0x4E7E, 0xB0AF, 0x507A, 0xB0B0, 0x507D, 0xB0B1, 0x505C, 0xB0B2, 0x5047, 0xB0B3, 0x5043, 0xB0B4, 0x504C, - 0xB0B5, 0x505A, 0xB0B6, 0x5049, 0xB0B7, 0x5065, 0xB0B8, 0x5076, 0xB0B9, 0x504E, 0xB0BA, 0x5055, 0xB0BB, 0x5075, 0xB0BC, 0x5074, - 0xB0BD, 0x5077, 0xB0BE, 0x504F, 0xB0BF, 0x500F, 0xB0C0, 0x506F, 0xB0C1, 0x506D, 0xB0C2, 0x515C, 0xB0C3, 0x5195, 0xB0C4, 0x51F0, - 0xB0C5, 0x526A, 0xB0C6, 0x526F, 0xB0C7, 0x52D2, 0xB0C8, 0x52D9, 0xB0C9, 0x52D8, 0xB0CA, 0x52D5, 0xB0CB, 0x5310, 0xB0CC, 0x530F, - 0xB0CD, 0x5319, 0xB0CE, 0x533F, 0xB0CF, 0x5340, 0xB0D0, 0x533E, 0xB0D1, 0x53C3, 0xB0D2, 0x66FC, 0xB0D3, 0x5546, 0xB0D4, 0x556A, - 0xB0D5, 0x5566, 0xB0D6, 0x5544, 0xB0D7, 0x555E, 0xB0D8, 0x5561, 0xB0D9, 0x5543, 0xB0DA, 0x554A, 0xB0DB, 0x5531, 0xB0DC, 0x5556, - 0xB0DD, 0x554F, 0xB0DE, 0x5555, 0xB0DF, 0x552F, 0xB0E0, 0x5564, 0xB0E1, 0x5538, 0xB0E2, 0x552E, 0xB0E3, 0x555C, 0xB0E4, 0x552C, - 0xB0E5, 0x5563, 0xB0E6, 0x5533, 0xB0E7, 0x5541, 0xB0E8, 0x5557, 0xB0E9, 0x5708, 0xB0EA, 0x570B, 0xB0EB, 0x5709, 0xB0EC, 0x57DF, - 0xB0ED, 0x5805, 0xB0EE, 0x580A, 0xB0EF, 0x5806, 0xB0F0, 0x57E0, 0xB0F1, 0x57E4, 0xB0F2, 0x57FA, 0xB0F3, 0x5802, 0xB0F4, 0x5835, - 0xB0F5, 0x57F7, 0xB0F6, 0x57F9, 0xB0F7, 0x5920, 0xB0F8, 0x5962, 0xB0F9, 0x5A36, 0xB0FA, 0x5A41, 0xB0FB, 0x5A49, 0xB0FC, 0x5A66, - 0xB0FD, 0x5A6A, 0xB0FE, 0x5A40, 0xB140, 0x5A3C, 0xB141, 0x5A62, 0xB142, 0x5A5A, 0xB143, 0x5A46, 0xB144, 0x5A4A, 0xB145, 0x5B70, - 0xB146, 0x5BC7, 0xB147, 0x5BC5, 0xB148, 0x5BC4, 0xB149, 0x5BC2, 0xB14A, 0x5BBF, 0xB14B, 0x5BC6, 0xB14C, 0x5C09, 0xB14D, 0x5C08, - 0xB14E, 0x5C07, 0xB14F, 0x5C60, 0xB150, 0x5C5C, 0xB151, 0x5C5D, 0xB152, 0x5D07, 0xB153, 0x5D06, 0xB154, 0x5D0E, 0xB155, 0x5D1B, - 0xB156, 0x5D16, 0xB157, 0x5D22, 0xB158, 0x5D11, 0xB159, 0x5D29, 0xB15A, 0x5D14, 0xB15B, 0x5D19, 0xB15C, 0x5D24, 0xB15D, 0x5D27, - 0xB15E, 0x5D17, 0xB15F, 0x5DE2, 0xB160, 0x5E38, 0xB161, 0x5E36, 0xB162, 0x5E33, 0xB163, 0x5E37, 0xB164, 0x5EB7, 0xB165, 0x5EB8, - 0xB166, 0x5EB6, 0xB167, 0x5EB5, 0xB168, 0x5EBE, 0xB169, 0x5F35, 0xB16A, 0x5F37, 0xB16B, 0x5F57, 0xB16C, 0x5F6C, 0xB16D, 0x5F69, - 0xB16E, 0x5F6B, 0xB16F, 0x5F97, 0xB170, 0x5F99, 0xB171, 0x5F9E, 0xB172, 0x5F98, 0xB173, 0x5FA1, 0xB174, 0x5FA0, 0xB175, 0x5F9C, - 0xB176, 0x607F, 0xB177, 0x60A3, 0xB178, 0x6089, 0xB179, 0x60A0, 0xB17A, 0x60A8, 0xB17B, 0x60CB, 0xB17C, 0x60B4, 0xB17D, 0x60E6, - 0xB17E, 0x60BD, 0xB1A1, 0x60C5, 0xB1A2, 0x60BB, 0xB1A3, 0x60B5, 0xB1A4, 0x60DC, 0xB1A5, 0x60BC, 0xB1A6, 0x60D8, 0xB1A7, 0x60D5, - 0xB1A8, 0x60C6, 0xB1A9, 0x60DF, 0xB1AA, 0x60B8, 0xB1AB, 0x60DA, 0xB1AC, 0x60C7, 0xB1AD, 0x621A, 0xB1AE, 0x621B, 0xB1AF, 0x6248, - 0xB1B0, 0x63A0, 0xB1B1, 0x63A7, 0xB1B2, 0x6372, 0xB1B3, 0x6396, 0xB1B4, 0x63A2, 0xB1B5, 0x63A5, 0xB1B6, 0x6377, 0xB1B7, 0x6367, - 0xB1B8, 0x6398, 0xB1B9, 0x63AA, 0xB1BA, 0x6371, 0xB1BB, 0x63A9, 0xB1BC, 0x6389, 0xB1BD, 0x6383, 0xB1BE, 0x639B, 0xB1BF, 0x636B, - 0xB1C0, 0x63A8, 0xB1C1, 0x6384, 0xB1C2, 0x6388, 0xB1C3, 0x6399, 0xB1C4, 0x63A1, 0xB1C5, 0x63AC, 0xB1C6, 0x6392, 0xB1C7, 0x638F, - 0xB1C8, 0x6380, 0xB1C9, 0x637B, 0xB1CA, 0x6369, 0xB1CB, 0x6368, 0xB1CC, 0x637A, 0xB1CD, 0x655D, 0xB1CE, 0x6556, 0xB1CF, 0x6551, - 0xB1D0, 0x6559, 0xB1D1, 0x6557, 0xB1D2, 0x555F, 0xB1D3, 0x654F, 0xB1D4, 0x6558, 0xB1D5, 0x6555, 0xB1D6, 0x6554, 0xB1D7, 0x659C, - 0xB1D8, 0x659B, 0xB1D9, 0x65AC, 0xB1DA, 0x65CF, 0xB1DB, 0x65CB, 0xB1DC, 0x65CC, 0xB1DD, 0x65CE, 0xB1DE, 0x665D, 0xB1DF, 0x665A, - 0xB1E0, 0x6664, 0xB1E1, 0x6668, 0xB1E2, 0x6666, 0xB1E3, 0x665E, 0xB1E4, 0x66F9, 0xB1E5, 0x52D7, 0xB1E6, 0x671B, 0xB1E7, 0x6881, - 0xB1E8, 0x68AF, 0xB1E9, 0x68A2, 0xB1EA, 0x6893, 0xB1EB, 0x68B5, 0xB1EC, 0x687F, 0xB1ED, 0x6876, 0xB1EE, 0x68B1, 0xB1EF, 0x68A7, - 0xB1F0, 0x6897, 0xB1F1, 0x68B0, 0xB1F2, 0x6883, 0xB1F3, 0x68C4, 0xB1F4, 0x68AD, 0xB1F5, 0x6886, 0xB1F6, 0x6885, 0xB1F7, 0x6894, - 0xB1F8, 0x689D, 0xB1F9, 0x68A8, 0xB1FA, 0x689F, 0xB1FB, 0x68A1, 0xB1FC, 0x6882, 0xB1FD, 0x6B32, 0xB1FE, 0x6BBA, 0xB240, 0x6BEB, - 0xB241, 0x6BEC, 0xB242, 0x6C2B, 0xB243, 0x6D8E, 0xB244, 0x6DBC, 0xB245, 0x6DF3, 0xB246, 0x6DD9, 0xB247, 0x6DB2, 0xB248, 0x6DE1, - 0xB249, 0x6DCC, 0xB24A, 0x6DE4, 0xB24B, 0x6DFB, 0xB24C, 0x6DFA, 0xB24D, 0x6E05, 0xB24E, 0x6DC7, 0xB24F, 0x6DCB, 0xB250, 0x6DAF, - 0xB251, 0x6DD1, 0xB252, 0x6DAE, 0xB253, 0x6DDE, 0xB254, 0x6DF9, 0xB255, 0x6DB8, 0xB256, 0x6DF7, 0xB257, 0x6DF5, 0xB258, 0x6DC5, - 0xB259, 0x6DD2, 0xB25A, 0x6E1A, 0xB25B, 0x6DB5, 0xB25C, 0x6DDA, 0xB25D, 0x6DEB, 0xB25E, 0x6DD8, 0xB25F, 0x6DEA, 0xB260, 0x6DF1, - 0xB261, 0x6DEE, 0xB262, 0x6DE8, 0xB263, 0x6DC6, 0xB264, 0x6DC4, 0xB265, 0x6DAA, 0xB266, 0x6DEC, 0xB267, 0x6DBF, 0xB268, 0x6DE6, - 0xB269, 0x70F9, 0xB26A, 0x7109, 0xB26B, 0x710A, 0xB26C, 0x70FD, 0xB26D, 0x70EF, 0xB26E, 0x723D, 0xB26F, 0x727D, 0xB270, 0x7281, - 0xB271, 0x731C, 0xB272, 0x731B, 0xB273, 0x7316, 0xB274, 0x7313, 0xB275, 0x7319, 0xB276, 0x7387, 0xB277, 0x7405, 0xB278, 0x740A, - 0xB279, 0x7403, 0xB27A, 0x7406, 0xB27B, 0x73FE, 0xB27C, 0x740D, 0xB27D, 0x74E0, 0xB27E, 0x74F6, 0xB2A1, 0x74F7, 0xB2A2, 0x751C, - 0xB2A3, 0x7522, 0xB2A4, 0x7565, 0xB2A5, 0x7566, 0xB2A6, 0x7562, 0xB2A7, 0x7570, 0xB2A8, 0x758F, 0xB2A9, 0x75D4, 0xB2AA, 0x75D5, - 0xB2AB, 0x75B5, 0xB2AC, 0x75CA, 0xB2AD, 0x75CD, 0xB2AE, 0x768E, 0xB2AF, 0x76D4, 0xB2B0, 0x76D2, 0xB2B1, 0x76DB, 0xB2B2, 0x7737, - 0xB2B3, 0x773E, 0xB2B4, 0x773C, 0xB2B5, 0x7736, 0xB2B6, 0x7738, 0xB2B7, 0x773A, 0xB2B8, 0x786B, 0xB2B9, 0x7843, 0xB2BA, 0x784E, - 0xB2BB, 0x7965, 0xB2BC, 0x7968, 0xB2BD, 0x796D, 0xB2BE, 0x79FB, 0xB2BF, 0x7A92, 0xB2C0, 0x7A95, 0xB2C1, 0x7B20, 0xB2C2, 0x7B28, - 0xB2C3, 0x7B1B, 0xB2C4, 0x7B2C, 0xB2C5, 0x7B26, 0xB2C6, 0x7B19, 0xB2C7, 0x7B1E, 0xB2C8, 0x7B2E, 0xB2C9, 0x7C92, 0xB2CA, 0x7C97, - 0xB2CB, 0x7C95, 0xB2CC, 0x7D46, 0xB2CD, 0x7D43, 0xB2CE, 0x7D71, 0xB2CF, 0x7D2E, 0xB2D0, 0x7D39, 0xB2D1, 0x7D3C, 0xB2D2, 0x7D40, - 0xB2D3, 0x7D30, 0xB2D4, 0x7D33, 0xB2D5, 0x7D44, 0xB2D6, 0x7D2F, 0xB2D7, 0x7D42, 0xB2D8, 0x7D32, 0xB2D9, 0x7D31, 0xB2DA, 0x7F3D, - 0xB2DB, 0x7F9E, 0xB2DC, 0x7F9A, 0xB2DD, 0x7FCC, 0xB2DE, 0x7FCE, 0xB2DF, 0x7FD2, 0xB2E0, 0x801C, 0xB2E1, 0x804A, 0xB2E2, 0x8046, - 0xB2E3, 0x812F, 0xB2E4, 0x8116, 0xB2E5, 0x8123, 0xB2E6, 0x812B, 0xB2E7, 0x8129, 0xB2E8, 0x8130, 0xB2E9, 0x8124, 0xB2EA, 0x8202, - 0xB2EB, 0x8235, 0xB2EC, 0x8237, 0xB2ED, 0x8236, 0xB2EE, 0x8239, 0xB2EF, 0x838E, 0xB2F0, 0x839E, 0xB2F1, 0x8398, 0xB2F2, 0x8378, - 0xB2F3, 0x83A2, 0xB2F4, 0x8396, 0xB2F5, 0x83BD, 0xB2F6, 0x83AB, 0xB2F7, 0x8392, 0xB2F8, 0x838A, 0xB2F9, 0x8393, 0xB2FA, 0x8389, - 0xB2FB, 0x83A0, 0xB2FC, 0x8377, 0xB2FD, 0x837B, 0xB2FE, 0x837C, 0xB340, 0x8386, 0xB341, 0x83A7, 0xB342, 0x8655, 0xB343, 0x5F6A, - 0xB344, 0x86C7, 0xB345, 0x86C0, 0xB346, 0x86B6, 0xB347, 0x86C4, 0xB348, 0x86B5, 0xB349, 0x86C6, 0xB34A, 0x86CB, 0xB34B, 0x86B1, - 0xB34C, 0x86AF, 0xB34D, 0x86C9, 0xB34E, 0x8853, 0xB34F, 0x889E, 0xB350, 0x8888, 0xB351, 0x88AB, 0xB352, 0x8892, 0xB353, 0x8896, - 0xB354, 0x888D, 0xB355, 0x888B, 0xB356, 0x8993, 0xB357, 0x898F, 0xB358, 0x8A2A, 0xB359, 0x8A1D, 0xB35A, 0x8A23, 0xB35B, 0x8A25, - 0xB35C, 0x8A31, 0xB35D, 0x8A2D, 0xB35E, 0x8A1F, 0xB35F, 0x8A1B, 0xB360, 0x8A22, 0xB361, 0x8C49, 0xB362, 0x8C5A, 0xB363, 0x8CA9, - 0xB364, 0x8CAC, 0xB365, 0x8CAB, 0xB366, 0x8CA8, 0xB367, 0x8CAA, 0xB368, 0x8CA7, 0xB369, 0x8D67, 0xB36A, 0x8D66, 0xB36B, 0x8DBE, - 0xB36C, 0x8DBA, 0xB36D, 0x8EDB, 0xB36E, 0x8EDF, 0xB36F, 0x9019, 0xB370, 0x900D, 0xB371, 0x901A, 0xB372, 0x9017, 0xB373, 0x9023, - 0xB374, 0x901F, 0xB375, 0x901D, 0xB376, 0x9010, 0xB377, 0x9015, 0xB378, 0x901E, 0xB379, 0x9020, 0xB37A, 0x900F, 0xB37B, 0x9022, - 0xB37C, 0x9016, 0xB37D, 0x901B, 0xB37E, 0x9014, 0xB3A1, 0x90E8, 0xB3A2, 0x90ED, 0xB3A3, 0x90FD, 0xB3A4, 0x9157, 0xB3A5, 0x91CE, - 0xB3A6, 0x91F5, 0xB3A7, 0x91E6, 0xB3A8, 0x91E3, 0xB3A9, 0x91E7, 0xB3AA, 0x91ED, 0xB3AB, 0x91E9, 0xB3AC, 0x9589, 0xB3AD, 0x966A, - 0xB3AE, 0x9675, 0xB3AF, 0x9673, 0xB3B0, 0x9678, 0xB3B1, 0x9670, 0xB3B2, 0x9674, 0xB3B3, 0x9676, 0xB3B4, 0x9677, 0xB3B5, 0x966C, - 0xB3B6, 0x96C0, 0xB3B7, 0x96EA, 0xB3B8, 0x96E9, 0xB3B9, 0x7AE0, 0xB3BA, 0x7ADF, 0xB3BB, 0x9802, 0xB3BC, 0x9803, 0xB3BD, 0x9B5A, - 0xB3BE, 0x9CE5, 0xB3BF, 0x9E75, 0xB3C0, 0x9E7F, 0xB3C1, 0x9EA5, 0xB3C2, 0x9EBB, 0xB3C3, 0x50A2, 0xB3C4, 0x508D, 0xB3C5, 0x5085, - 0xB3C6, 0x5099, 0xB3C7, 0x5091, 0xB3C8, 0x5080, 0xB3C9, 0x5096, 0xB3CA, 0x5098, 0xB3CB, 0x509A, 0xB3CC, 0x6700, 0xB3CD, 0x51F1, - 0xB3CE, 0x5272, 0xB3CF, 0x5274, 0xB3D0, 0x5275, 0xB3D1, 0x5269, 0xB3D2, 0x52DE, 0xB3D3, 0x52DD, 0xB3D4, 0x52DB, 0xB3D5, 0x535A, - 0xB3D6, 0x53A5, 0xB3D7, 0x557B, 0xB3D8, 0x5580, 0xB3D9, 0x55A7, 0xB3DA, 0x557C, 0xB3DB, 0x558A, 0xB3DC, 0x559D, 0xB3DD, 0x5598, - 0xB3DE, 0x5582, 0xB3DF, 0x559C, 0xB3E0, 0x55AA, 0xB3E1, 0x5594, 0xB3E2, 0x5587, 0xB3E3, 0x558B, 0xB3E4, 0x5583, 0xB3E5, 0x55B3, - 0xB3E6, 0x55AE, 0xB3E7, 0x559F, 0xB3E8, 0x553E, 0xB3E9, 0x55B2, 0xB3EA, 0x559A, 0xB3EB, 0x55BB, 0xB3EC, 0x55AC, 0xB3ED, 0x55B1, - 0xB3EE, 0x557E, 0xB3EF, 0x5589, 0xB3F0, 0x55AB, 0xB3F1, 0x5599, 0xB3F2, 0x570D, 0xB3F3, 0x582F, 0xB3F4, 0x582A, 0xB3F5, 0x5834, - 0xB3F6, 0x5824, 0xB3F7, 0x5830, 0xB3F8, 0x5831, 0xB3F9, 0x5821, 0xB3FA, 0x581D, 0xB3FB, 0x5820, 0xB3FC, 0x58F9, 0xB3FD, 0x58FA, - 0xB3FE, 0x5960, 0xB440, 0x5A77, 0xB441, 0x5A9A, 0xB442, 0x5A7F, 0xB443, 0x5A92, 0xB444, 0x5A9B, 0xB445, 0x5AA7, 0xB446, 0x5B73, - 0xB447, 0x5B71, 0xB448, 0x5BD2, 0xB449, 0x5BCC, 0xB44A, 0x5BD3, 0xB44B, 0x5BD0, 0xB44C, 0x5C0A, 0xB44D, 0x5C0B, 0xB44E, 0x5C31, - 0xB44F, 0x5D4C, 0xB450, 0x5D50, 0xB451, 0x5D34, 0xB452, 0x5D47, 0xB453, 0x5DFD, 0xB454, 0x5E45, 0xB455, 0x5E3D, 0xB456, 0x5E40, - 0xB457, 0x5E43, 0xB458, 0x5E7E, 0xB459, 0x5ECA, 0xB45A, 0x5EC1, 0xB45B, 0x5EC2, 0xB45C, 0x5EC4, 0xB45D, 0x5F3C, 0xB45E, 0x5F6D, - 0xB45F, 0x5FA9, 0xB460, 0x5FAA, 0xB461, 0x5FA8, 0xB462, 0x60D1, 0xB463, 0x60E1, 0xB464, 0x60B2, 0xB465, 0x60B6, 0xB466, 0x60E0, - 0xB467, 0x611C, 0xB468, 0x6123, 0xB469, 0x60FA, 0xB46A, 0x6115, 0xB46B, 0x60F0, 0xB46C, 0x60FB, 0xB46D, 0x60F4, 0xB46E, 0x6168, - 0xB46F, 0x60F1, 0xB470, 0x610E, 0xB471, 0x60F6, 0xB472, 0x6109, 0xB473, 0x6100, 0xB474, 0x6112, 0xB475, 0x621F, 0xB476, 0x6249, - 0xB477, 0x63A3, 0xB478, 0x638C, 0xB479, 0x63CF, 0xB47A, 0x63C0, 0xB47B, 0x63E9, 0xB47C, 0x63C9, 0xB47D, 0x63C6, 0xB47E, 0x63CD, - 0xB4A1, 0x63D2, 0xB4A2, 0x63E3, 0xB4A3, 0x63D0, 0xB4A4, 0x63E1, 0xB4A5, 0x63D6, 0xB4A6, 0x63ED, 0xB4A7, 0x63EE, 0xB4A8, 0x6376, - 0xB4A9, 0x63F4, 0xB4AA, 0x63EA, 0xB4AB, 0x63DB, 0xB4AC, 0x6452, 0xB4AD, 0x63DA, 0xB4AE, 0x63F9, 0xB4AF, 0x655E, 0xB4B0, 0x6566, - 0xB4B1, 0x6562, 0xB4B2, 0x6563, 0xB4B3, 0x6591, 0xB4B4, 0x6590, 0xB4B5, 0x65AF, 0xB4B6, 0x666E, 0xB4B7, 0x6670, 0xB4B8, 0x6674, - 0xB4B9, 0x6676, 0xB4BA, 0x666F, 0xB4BB, 0x6691, 0xB4BC, 0x667A, 0xB4BD, 0x667E, 0xB4BE, 0x6677, 0xB4BF, 0x66FE, 0xB4C0, 0x66FF, - 0xB4C1, 0x671F, 0xB4C2, 0x671D, 0xB4C3, 0x68FA, 0xB4C4, 0x68D5, 0xB4C5, 0x68E0, 0xB4C6, 0x68D8, 0xB4C7, 0x68D7, 0xB4C8, 0x6905, - 0xB4C9, 0x68DF, 0xB4CA, 0x68F5, 0xB4CB, 0x68EE, 0xB4CC, 0x68E7, 0xB4CD, 0x68F9, 0xB4CE, 0x68D2, 0xB4CF, 0x68F2, 0xB4D0, 0x68E3, - 0xB4D1, 0x68CB, 0xB4D2, 0x68CD, 0xB4D3, 0x690D, 0xB4D4, 0x6912, 0xB4D5, 0x690E, 0xB4D6, 0x68C9, 0xB4D7, 0x68DA, 0xB4D8, 0x696E, - 0xB4D9, 0x68FB, 0xB4DA, 0x6B3E, 0xB4DB, 0x6B3A, 0xB4DC, 0x6B3D, 0xB4DD, 0x6B98, 0xB4DE, 0x6B96, 0xB4DF, 0x6BBC, 0xB4E0, 0x6BEF, - 0xB4E1, 0x6C2E, 0xB4E2, 0x6C2F, 0xB4E3, 0x6C2C, 0xB4E4, 0x6E2F, 0xB4E5, 0x6E38, 0xB4E6, 0x6E54, 0xB4E7, 0x6E21, 0xB4E8, 0x6E32, - 0xB4E9, 0x6E67, 0xB4EA, 0x6E4A, 0xB4EB, 0x6E20, 0xB4EC, 0x6E25, 0xB4ED, 0x6E23, 0xB4EE, 0x6E1B, 0xB4EF, 0x6E5B, 0xB4F0, 0x6E58, - 0xB4F1, 0x6E24, 0xB4F2, 0x6E56, 0xB4F3, 0x6E6E, 0xB4F4, 0x6E2D, 0xB4F5, 0x6E26, 0xB4F6, 0x6E6F, 0xB4F7, 0x6E34, 0xB4F8, 0x6E4D, - 0xB4F9, 0x6E3A, 0xB4FA, 0x6E2C, 0xB4FB, 0x6E43, 0xB4FC, 0x6E1D, 0xB4FD, 0x6E3E, 0xB4FE, 0x6ECB, 0xB540, 0x6E89, 0xB541, 0x6E19, - 0xB542, 0x6E4E, 0xB543, 0x6E63, 0xB544, 0x6E44, 0xB545, 0x6E72, 0xB546, 0x6E69, 0xB547, 0x6E5F, 0xB548, 0x7119, 0xB549, 0x711A, - 0xB54A, 0x7126, 0xB54B, 0x7130, 0xB54C, 0x7121, 0xB54D, 0x7136, 0xB54E, 0x716E, 0xB54F, 0x711C, 0xB550, 0x724C, 0xB551, 0x7284, - 0xB552, 0x7280, 0xB553, 0x7336, 0xB554, 0x7325, 0xB555, 0x7334, 0xB556, 0x7329, 0xB557, 0x743A, 0xB558, 0x742A, 0xB559, 0x7433, - 0xB55A, 0x7422, 0xB55B, 0x7425, 0xB55C, 0x7435, 0xB55D, 0x7436, 0xB55E, 0x7434, 0xB55F, 0x742F, 0xB560, 0x741B, 0xB561, 0x7426, - 0xB562, 0x7428, 0xB563, 0x7525, 0xB564, 0x7526, 0xB565, 0x756B, 0xB566, 0x756A, 0xB567, 0x75E2, 0xB568, 0x75DB, 0xB569, 0x75E3, - 0xB56A, 0x75D9, 0xB56B, 0x75D8, 0xB56C, 0x75DE, 0xB56D, 0x75E0, 0xB56E, 0x767B, 0xB56F, 0x767C, 0xB570, 0x7696, 0xB571, 0x7693, - 0xB572, 0x76B4, 0xB573, 0x76DC, 0xB574, 0x774F, 0xB575, 0x77ED, 0xB576, 0x785D, 0xB577, 0x786C, 0xB578, 0x786F, 0xB579, 0x7A0D, - 0xB57A, 0x7A08, 0xB57B, 0x7A0B, 0xB57C, 0x7A05, 0xB57D, 0x7A00, 0xB57E, 0x7A98, 0xB5A1, 0x7A97, 0xB5A2, 0x7A96, 0xB5A3, 0x7AE5, - 0xB5A4, 0x7AE3, 0xB5A5, 0x7B49, 0xB5A6, 0x7B56, 0xB5A7, 0x7B46, 0xB5A8, 0x7B50, 0xB5A9, 0x7B52, 0xB5AA, 0x7B54, 0xB5AB, 0x7B4D, - 0xB5AC, 0x7B4B, 0xB5AD, 0x7B4F, 0xB5AE, 0x7B51, 0xB5AF, 0x7C9F, 0xB5B0, 0x7CA5, 0xB5B1, 0x7D5E, 0xB5B2, 0x7D50, 0xB5B3, 0x7D68, - 0xB5B4, 0x7D55, 0xB5B5, 0x7D2B, 0xB5B6, 0x7D6E, 0xB5B7, 0x7D72, 0xB5B8, 0x7D61, 0xB5B9, 0x7D66, 0xB5BA, 0x7D62, 0xB5BB, 0x7D70, - 0xB5BC, 0x7D73, 0xB5BD, 0x5584, 0xB5BE, 0x7FD4, 0xB5BF, 0x7FD5, 0xB5C0, 0x800B, 0xB5C1, 0x8052, 0xB5C2, 0x8085, 0xB5C3, 0x8155, - 0xB5C4, 0x8154, 0xB5C5, 0x814B, 0xB5C6, 0x8151, 0xB5C7, 0x814E, 0xB5C8, 0x8139, 0xB5C9, 0x8146, 0xB5CA, 0x813E, 0xB5CB, 0x814C, - 0xB5CC, 0x8153, 0xB5CD, 0x8174, 0xB5CE, 0x8212, 0xB5CF, 0x821C, 0xB5D0, 0x83E9, 0xB5D1, 0x8403, 0xB5D2, 0x83F8, 0xB5D3, 0x840D, - 0xB5D4, 0x83E0, 0xB5D5, 0x83C5, 0xB5D6, 0x840B, 0xB5D7, 0x83C1, 0xB5D8, 0x83EF, 0xB5D9, 0x83F1, 0xB5DA, 0x83F4, 0xB5DB, 0x8457, - 0xB5DC, 0x840A, 0xB5DD, 0x83F0, 0xB5DE, 0x840C, 0xB5DF, 0x83CC, 0xB5E0, 0x83FD, 0xB5E1, 0x83F2, 0xB5E2, 0x83CA, 0xB5E3, 0x8438, - 0xB5E4, 0x840E, 0xB5E5, 0x8404, 0xB5E6, 0x83DC, 0xB5E7, 0x8407, 0xB5E8, 0x83D4, 0xB5E9, 0x83DF, 0xB5EA, 0x865B, 0xB5EB, 0x86DF, - 0xB5EC, 0x86D9, 0xB5ED, 0x86ED, 0xB5EE, 0x86D4, 0xB5EF, 0x86DB, 0xB5F0, 0x86E4, 0xB5F1, 0x86D0, 0xB5F2, 0x86DE, 0xB5F3, 0x8857, - 0xB5F4, 0x88C1, 0xB5F5, 0x88C2, 0xB5F6, 0x88B1, 0xB5F7, 0x8983, 0xB5F8, 0x8996, 0xB5F9, 0x8A3B, 0xB5FA, 0x8A60, 0xB5FB, 0x8A55, - 0xB5FC, 0x8A5E, 0xB5FD, 0x8A3C, 0xB5FE, 0x8A41, 0xB640, 0x8A54, 0xB641, 0x8A5B, 0xB642, 0x8A50, 0xB643, 0x8A46, 0xB644, 0x8A34, - 0xB645, 0x8A3A, 0xB646, 0x8A36, 0xB647, 0x8A56, 0xB648, 0x8C61, 0xB649, 0x8C82, 0xB64A, 0x8CAF, 0xB64B, 0x8CBC, 0xB64C, 0x8CB3, - 0xB64D, 0x8CBD, 0xB64E, 0x8CC1, 0xB64F, 0x8CBB, 0xB650, 0x8CC0, 0xB651, 0x8CB4, 0xB652, 0x8CB7, 0xB653, 0x8CB6, 0xB654, 0x8CBF, - 0xB655, 0x8CB8, 0xB656, 0x8D8A, 0xB657, 0x8D85, 0xB658, 0x8D81, 0xB659, 0x8DCE, 0xB65A, 0x8DDD, 0xB65B, 0x8DCB, 0xB65C, 0x8DDA, - 0xB65D, 0x8DD1, 0xB65E, 0x8DCC, 0xB65F, 0x8DDB, 0xB660, 0x8DC6, 0xB661, 0x8EFB, 0xB662, 0x8EF8, 0xB663, 0x8EFC, 0xB664, 0x8F9C, - 0xB665, 0x902E, 0xB666, 0x9035, 0xB667, 0x9031, 0xB668, 0x9038, 0xB669, 0x9032, 0xB66A, 0x9036, 0xB66B, 0x9102, 0xB66C, 0x90F5, - 0xB66D, 0x9109, 0xB66E, 0x90FE, 0xB66F, 0x9163, 0xB670, 0x9165, 0xB671, 0x91CF, 0xB672, 0x9214, 0xB673, 0x9215, 0xB674, 0x9223, - 0xB675, 0x9209, 0xB676, 0x921E, 0xB677, 0x920D, 0xB678, 0x9210, 0xB679, 0x9207, 0xB67A, 0x9211, 0xB67B, 0x9594, 0xB67C, 0x958F, - 0xB67D, 0x958B, 0xB67E, 0x9591, 0xB6A1, 0x9593, 0xB6A2, 0x9592, 0xB6A3, 0x958E, 0xB6A4, 0x968A, 0xB6A5, 0x968E, 0xB6A6, 0x968B, - 0xB6A7, 0x967D, 0xB6A8, 0x9685, 0xB6A9, 0x9686, 0xB6AA, 0x968D, 0xB6AB, 0x9672, 0xB6AC, 0x9684, 0xB6AD, 0x96C1, 0xB6AE, 0x96C5, - 0xB6AF, 0x96C4, 0xB6B0, 0x96C6, 0xB6B1, 0x96C7, 0xB6B2, 0x96EF, 0xB6B3, 0x96F2, 0xB6B4, 0x97CC, 0xB6B5, 0x9805, 0xB6B6, 0x9806, - 0xB6B7, 0x9808, 0xB6B8, 0x98E7, 0xB6B9, 0x98EA, 0xB6BA, 0x98EF, 0xB6BB, 0x98E9, 0xB6BC, 0x98F2, 0xB6BD, 0x98ED, 0xB6BE, 0x99AE, - 0xB6BF, 0x99AD, 0xB6C0, 0x9EC3, 0xB6C1, 0x9ECD, 0xB6C2, 0x9ED1, 0xB6C3, 0x4E82, 0xB6C4, 0x50AD, 0xB6C5, 0x50B5, 0xB6C6, 0x50B2, - 0xB6C7, 0x50B3, 0xB6C8, 0x50C5, 0xB6C9, 0x50BE, 0xB6CA, 0x50AC, 0xB6CB, 0x50B7, 0xB6CC, 0x50BB, 0xB6CD, 0x50AF, 0xB6CE, 0x50C7, - 0xB6CF, 0x527F, 0xB6D0, 0x5277, 0xB6D1, 0x527D, 0xB6D2, 0x52DF, 0xB6D3, 0x52E6, 0xB6D4, 0x52E4, 0xB6D5, 0x52E2, 0xB6D6, 0x52E3, - 0xB6D7, 0x532F, 0xB6D8, 0x55DF, 0xB6D9, 0x55E8, 0xB6DA, 0x55D3, 0xB6DB, 0x55E6, 0xB6DC, 0x55CE, 0xB6DD, 0x55DC, 0xB6DE, 0x55C7, - 0xB6DF, 0x55D1, 0xB6E0, 0x55E3, 0xB6E1, 0x55E4, 0xB6E2, 0x55EF, 0xB6E3, 0x55DA, 0xB6E4, 0x55E1, 0xB6E5, 0x55C5, 0xB6E6, 0x55C6, - 0xB6E7, 0x55E5, 0xB6E8, 0x55C9, 0xB6E9, 0x5712, 0xB6EA, 0x5713, 0xB6EB, 0x585E, 0xB6EC, 0x5851, 0xB6ED, 0x5858, 0xB6EE, 0x5857, - 0xB6EF, 0x585A, 0xB6F0, 0x5854, 0xB6F1, 0x586B, 0xB6F2, 0x584C, 0xB6F3, 0x586D, 0xB6F4, 0x584A, 0xB6F5, 0x5862, 0xB6F6, 0x5852, - 0xB6F7, 0x584B, 0xB6F8, 0x5967, 0xB6F9, 0x5AC1, 0xB6FA, 0x5AC9, 0xB6FB, 0x5ACC, 0xB6FC, 0x5ABE, 0xB6FD, 0x5ABD, 0xB6FE, 0x5ABC, - 0xB740, 0x5AB3, 0xB741, 0x5AC2, 0xB742, 0x5AB2, 0xB743, 0x5D69, 0xB744, 0x5D6F, 0xB745, 0x5E4C, 0xB746, 0x5E79, 0xB747, 0x5EC9, - 0xB748, 0x5EC8, 0xB749, 0x5F12, 0xB74A, 0x5F59, 0xB74B, 0x5FAC, 0xB74C, 0x5FAE, 0xB74D, 0x611A, 0xB74E, 0x610F, 0xB74F, 0x6148, - 0xB750, 0x611F, 0xB751, 0x60F3, 0xB752, 0x611B, 0xB753, 0x60F9, 0xB754, 0x6101, 0xB755, 0x6108, 0xB756, 0x614E, 0xB757, 0x614C, - 0xB758, 0x6144, 0xB759, 0x614D, 0xB75A, 0x613E, 0xB75B, 0x6134, 0xB75C, 0x6127, 0xB75D, 0x610D, 0xB75E, 0x6106, 0xB75F, 0x6137, - 0xB760, 0x6221, 0xB761, 0x6222, 0xB762, 0x6413, 0xB763, 0x643E, 0xB764, 0x641E, 0xB765, 0x642A, 0xB766, 0x642D, 0xB767, 0x643D, - 0xB768, 0x642C, 0xB769, 0x640F, 0xB76A, 0x641C, 0xB76B, 0x6414, 0xB76C, 0x640D, 0xB76D, 0x6436, 0xB76E, 0x6416, 0xB76F, 0x6417, - 0xB770, 0x6406, 0xB771, 0x656C, 0xB772, 0x659F, 0xB773, 0x65B0, 0xB774, 0x6697, 0xB775, 0x6689, 0xB776, 0x6687, 0xB777, 0x6688, - 0xB778, 0x6696, 0xB779, 0x6684, 0xB77A, 0x6698, 0xB77B, 0x668D, 0xB77C, 0x6703, 0xB77D, 0x6994, 0xB77E, 0x696D, 0xB7A1, 0x695A, - 0xB7A2, 0x6977, 0xB7A3, 0x6960, 0xB7A4, 0x6954, 0xB7A5, 0x6975, 0xB7A6, 0x6930, 0xB7A7, 0x6982, 0xB7A8, 0x694A, 0xB7A9, 0x6968, - 0xB7AA, 0x696B, 0xB7AB, 0x695E, 0xB7AC, 0x6953, 0xB7AD, 0x6979, 0xB7AE, 0x6986, 0xB7AF, 0x695D, 0xB7B0, 0x6963, 0xB7B1, 0x695B, - 0xB7B2, 0x6B47, 0xB7B3, 0x6B72, 0xB7B4, 0x6BC0, 0xB7B5, 0x6BBF, 0xB7B6, 0x6BD3, 0xB7B7, 0x6BFD, 0xB7B8, 0x6EA2, 0xB7B9, 0x6EAF, - 0xB7BA, 0x6ED3, 0xB7BB, 0x6EB6, 0xB7BC, 0x6EC2, 0xB7BD, 0x6E90, 0xB7BE, 0x6E9D, 0xB7BF, 0x6EC7, 0xB7C0, 0x6EC5, 0xB7C1, 0x6EA5, - 0xB7C2, 0x6E98, 0xB7C3, 0x6EBC, 0xB7C4, 0x6EBA, 0xB7C5, 0x6EAB, 0xB7C6, 0x6ED1, 0xB7C7, 0x6E96, 0xB7C8, 0x6E9C, 0xB7C9, 0x6EC4, - 0xB7CA, 0x6ED4, 0xB7CB, 0x6EAA, 0xB7CC, 0x6EA7, 0xB7CD, 0x6EB4, 0xB7CE, 0x714E, 0xB7CF, 0x7159, 0xB7D0, 0x7169, 0xB7D1, 0x7164, - 0xB7D2, 0x7149, 0xB7D3, 0x7167, 0xB7D4, 0x715C, 0xB7D5, 0x716C, 0xB7D6, 0x7166, 0xB7D7, 0x714C, 0xB7D8, 0x7165, 0xB7D9, 0x715E, - 0xB7DA, 0x7146, 0xB7DB, 0x7168, 0xB7DC, 0x7156, 0xB7DD, 0x723A, 0xB7DE, 0x7252, 0xB7DF, 0x7337, 0xB7E0, 0x7345, 0xB7E1, 0x733F, - 0xB7E2, 0x733E, 0xB7E3, 0x746F, 0xB7E4, 0x745A, 0xB7E5, 0x7455, 0xB7E6, 0x745F, 0xB7E7, 0x745E, 0xB7E8, 0x7441, 0xB7E9, 0x743F, - 0xB7EA, 0x7459, 0xB7EB, 0x745B, 0xB7EC, 0x745C, 0xB7ED, 0x7576, 0xB7EE, 0x7578, 0xB7EF, 0x7600, 0xB7F0, 0x75F0, 0xB7F1, 0x7601, - 0xB7F2, 0x75F2, 0xB7F3, 0x75F1, 0xB7F4, 0x75FA, 0xB7F5, 0x75FF, 0xB7F6, 0x75F4, 0xB7F7, 0x75F3, 0xB7F8, 0x76DE, 0xB7F9, 0x76DF, - 0xB7FA, 0x775B, 0xB7FB, 0x776B, 0xB7FC, 0x7766, 0xB7FD, 0x775E, 0xB7FE, 0x7763, 0xB840, 0x7779, 0xB841, 0x776A, 0xB842, 0x776C, - 0xB843, 0x775C, 0xB844, 0x7765, 0xB845, 0x7768, 0xB846, 0x7762, 0xB847, 0x77EE, 0xB848, 0x788E, 0xB849, 0x78B0, 0xB84A, 0x7897, - 0xB84B, 0x7898, 0xB84C, 0x788C, 0xB84D, 0x7889, 0xB84E, 0x787C, 0xB84F, 0x7891, 0xB850, 0x7893, 0xB851, 0x787F, 0xB852, 0x797A, - 0xB853, 0x797F, 0xB854, 0x7981, 0xB855, 0x842C, 0xB856, 0x79BD, 0xB857, 0x7A1C, 0xB858, 0x7A1A, 0xB859, 0x7A20, 0xB85A, 0x7A14, - 0xB85B, 0x7A1F, 0xB85C, 0x7A1E, 0xB85D, 0x7A9F, 0xB85E, 0x7AA0, 0xB85F, 0x7B77, 0xB860, 0x7BC0, 0xB861, 0x7B60, 0xB862, 0x7B6E, - 0xB863, 0x7B67, 0xB864, 0x7CB1, 0xB865, 0x7CB3, 0xB866, 0x7CB5, 0xB867, 0x7D93, 0xB868, 0x7D79, 0xB869, 0x7D91, 0xB86A, 0x7D81, - 0xB86B, 0x7D8F, 0xB86C, 0x7D5B, 0xB86D, 0x7F6E, 0xB86E, 0x7F69, 0xB86F, 0x7F6A, 0xB870, 0x7F72, 0xB871, 0x7FA9, 0xB872, 0x7FA8, - 0xB873, 0x7FA4, 0xB874, 0x8056, 0xB875, 0x8058, 0xB876, 0x8086, 0xB877, 0x8084, 0xB878, 0x8171, 0xB879, 0x8170, 0xB87A, 0x8178, - 0xB87B, 0x8165, 0xB87C, 0x816E, 0xB87D, 0x8173, 0xB87E, 0x816B, 0xB8A1, 0x8179, 0xB8A2, 0x817A, 0xB8A3, 0x8166, 0xB8A4, 0x8205, - 0xB8A5, 0x8247, 0xB8A6, 0x8482, 0xB8A7, 0x8477, 0xB8A8, 0x843D, 0xB8A9, 0x8431, 0xB8AA, 0x8475, 0xB8AB, 0x8466, 0xB8AC, 0x846B, - 0xB8AD, 0x8449, 0xB8AE, 0x846C, 0xB8AF, 0x845B, 0xB8B0, 0x843C, 0xB8B1, 0x8435, 0xB8B2, 0x8461, 0xB8B3, 0x8463, 0xB8B4, 0x8469, - 0xB8B5, 0x846D, 0xB8B6, 0x8446, 0xB8B7, 0x865E, 0xB8B8, 0x865C, 0xB8B9, 0x865F, 0xB8BA, 0x86F9, 0xB8BB, 0x8713, 0xB8BC, 0x8708, - 0xB8BD, 0x8707, 0xB8BE, 0x8700, 0xB8BF, 0x86FE, 0xB8C0, 0x86FB, 0xB8C1, 0x8702, 0xB8C2, 0x8703, 0xB8C3, 0x8706, 0xB8C4, 0x870A, - 0xB8C5, 0x8859, 0xB8C6, 0x88DF, 0xB8C7, 0x88D4, 0xB8C8, 0x88D9, 0xB8C9, 0x88DC, 0xB8CA, 0x88D8, 0xB8CB, 0x88DD, 0xB8CC, 0x88E1, - 0xB8CD, 0x88CA, 0xB8CE, 0x88D5, 0xB8CF, 0x88D2, 0xB8D0, 0x899C, 0xB8D1, 0x89E3, 0xB8D2, 0x8A6B, 0xB8D3, 0x8A72, 0xB8D4, 0x8A73, - 0xB8D5, 0x8A66, 0xB8D6, 0x8A69, 0xB8D7, 0x8A70, 0xB8D8, 0x8A87, 0xB8D9, 0x8A7C, 0xB8DA, 0x8A63, 0xB8DB, 0x8AA0, 0xB8DC, 0x8A71, - 0xB8DD, 0x8A85, 0xB8DE, 0x8A6D, 0xB8DF, 0x8A62, 0xB8E0, 0x8A6E, 0xB8E1, 0x8A6C, 0xB8E2, 0x8A79, 0xB8E3, 0x8A7B, 0xB8E4, 0x8A3E, - 0xB8E5, 0x8A68, 0xB8E6, 0x8C62, 0xB8E7, 0x8C8A, 0xB8E8, 0x8C89, 0xB8E9, 0x8CCA, 0xB8EA, 0x8CC7, 0xB8EB, 0x8CC8, 0xB8EC, 0x8CC4, - 0xB8ED, 0x8CB2, 0xB8EE, 0x8CC3, 0xB8EF, 0x8CC2, 0xB8F0, 0x8CC5, 0xB8F1, 0x8DE1, 0xB8F2, 0x8DDF, 0xB8F3, 0x8DE8, 0xB8F4, 0x8DEF, - 0xB8F5, 0x8DF3, 0xB8F6, 0x8DFA, 0xB8F7, 0x8DEA, 0xB8F8, 0x8DE4, 0xB8F9, 0x8DE6, 0xB8FA, 0x8EB2, 0xB8FB, 0x8F03, 0xB8FC, 0x8F09, - 0xB8FD, 0x8EFE, 0xB8FE, 0x8F0A, 0xB940, 0x8F9F, 0xB941, 0x8FB2, 0xB942, 0x904B, 0xB943, 0x904A, 0xB944, 0x9053, 0xB945, 0x9042, - 0xB946, 0x9054, 0xB947, 0x903C, 0xB948, 0x9055, 0xB949, 0x9050, 0xB94A, 0x9047, 0xB94B, 0x904F, 0xB94C, 0x904E, 0xB94D, 0x904D, - 0xB94E, 0x9051, 0xB94F, 0x903E, 0xB950, 0x9041, 0xB951, 0x9112, 0xB952, 0x9117, 0xB953, 0x916C, 0xB954, 0x916A, 0xB955, 0x9169, - 0xB956, 0x91C9, 0xB957, 0x9237, 0xB958, 0x9257, 0xB959, 0x9238, 0xB95A, 0x923D, 0xB95B, 0x9240, 0xB95C, 0x923E, 0xB95D, 0x925B, - 0xB95E, 0x924B, 0xB95F, 0x9264, 0xB960, 0x9251, 0xB961, 0x9234, 0xB962, 0x9249, 0xB963, 0x924D, 0xB964, 0x9245, 0xB965, 0x9239, - 0xB966, 0x923F, 0xB967, 0x925A, 0xB968, 0x9598, 0xB969, 0x9698, 0xB96A, 0x9694, 0xB96B, 0x9695, 0xB96C, 0x96CD, 0xB96D, 0x96CB, - 0xB96E, 0x96C9, 0xB96F, 0x96CA, 0xB970, 0x96F7, 0xB971, 0x96FB, 0xB972, 0x96F9, 0xB973, 0x96F6, 0xB974, 0x9756, 0xB975, 0x9774, - 0xB976, 0x9776, 0xB977, 0x9810, 0xB978, 0x9811, 0xB979, 0x9813, 0xB97A, 0x980A, 0xB97B, 0x9812, 0xB97C, 0x980C, 0xB97D, 0x98FC, - 0xB97E, 0x98F4, 0xB9A1, 0x98FD, 0xB9A2, 0x98FE, 0xB9A3, 0x99B3, 0xB9A4, 0x99B1, 0xB9A5, 0x99B4, 0xB9A6, 0x9AE1, 0xB9A7, 0x9CE9, - 0xB9A8, 0x9E82, 0xB9A9, 0x9F0E, 0xB9AA, 0x9F13, 0xB9AB, 0x9F20, 0xB9AC, 0x50E7, 0xB9AD, 0x50EE, 0xB9AE, 0x50E5, 0xB9AF, 0x50D6, - 0xB9B0, 0x50ED, 0xB9B1, 0x50DA, 0xB9B2, 0x50D5, 0xB9B3, 0x50CF, 0xB9B4, 0x50D1, 0xB9B5, 0x50F1, 0xB9B6, 0x50CE, 0xB9B7, 0x50E9, - 0xB9B8, 0x5162, 0xB9B9, 0x51F3, 0xB9BA, 0x5283, 0xB9BB, 0x5282, 0xB9BC, 0x5331, 0xB9BD, 0x53AD, 0xB9BE, 0x55FE, 0xB9BF, 0x5600, - 0xB9C0, 0x561B, 0xB9C1, 0x5617, 0xB9C2, 0x55FD, 0xB9C3, 0x5614, 0xB9C4, 0x5606, 0xB9C5, 0x5609, 0xB9C6, 0x560D, 0xB9C7, 0x560E, - 0xB9C8, 0x55F7, 0xB9C9, 0x5616, 0xB9CA, 0x561F, 0xB9CB, 0x5608, 0xB9CC, 0x5610, 0xB9CD, 0x55F6, 0xB9CE, 0x5718, 0xB9CF, 0x5716, - 0xB9D0, 0x5875, 0xB9D1, 0x587E, 0xB9D2, 0x5883, 0xB9D3, 0x5893, 0xB9D4, 0x588A, 0xB9D5, 0x5879, 0xB9D6, 0x5885, 0xB9D7, 0x587D, - 0xB9D8, 0x58FD, 0xB9D9, 0x5925, 0xB9DA, 0x5922, 0xB9DB, 0x5924, 0xB9DC, 0x596A, 0xB9DD, 0x5969, 0xB9DE, 0x5AE1, 0xB9DF, 0x5AE6, - 0xB9E0, 0x5AE9, 0xB9E1, 0x5AD7, 0xB9E2, 0x5AD6, 0xB9E3, 0x5AD8, 0xB9E4, 0x5AE3, 0xB9E5, 0x5B75, 0xB9E6, 0x5BDE, 0xB9E7, 0x5BE7, - 0xB9E8, 0x5BE1, 0xB9E9, 0x5BE5, 0xB9EA, 0x5BE6, 0xB9EB, 0x5BE8, 0xB9EC, 0x5BE2, 0xB9ED, 0x5BE4, 0xB9EE, 0x5BDF, 0xB9EF, 0x5C0D, - 0xB9F0, 0x5C62, 0xB9F1, 0x5D84, 0xB9F2, 0x5D87, 0xB9F3, 0x5E5B, 0xB9F4, 0x5E63, 0xB9F5, 0x5E55, 0xB9F6, 0x5E57, 0xB9F7, 0x5E54, - 0xB9F8, 0x5ED3, 0xB9F9, 0x5ED6, 0xB9FA, 0x5F0A, 0xB9FB, 0x5F46, 0xB9FC, 0x5F70, 0xB9FD, 0x5FB9, 0xB9FE, 0x6147, 0xBA40, 0x613F, - 0xBA41, 0x614B, 0xBA42, 0x6177, 0xBA43, 0x6162, 0xBA44, 0x6163, 0xBA45, 0x615F, 0xBA46, 0x615A, 0xBA47, 0x6158, 0xBA48, 0x6175, - 0xBA49, 0x622A, 0xBA4A, 0x6487, 0xBA4B, 0x6458, 0xBA4C, 0x6454, 0xBA4D, 0x64A4, 0xBA4E, 0x6478, 0xBA4F, 0x645F, 0xBA50, 0x647A, - 0xBA51, 0x6451, 0xBA52, 0x6467, 0xBA53, 0x6434, 0xBA54, 0x646D, 0xBA55, 0x647B, 0xBA56, 0x6572, 0xBA57, 0x65A1, 0xBA58, 0x65D7, - 0xBA59, 0x65D6, 0xBA5A, 0x66A2, 0xBA5B, 0x66A8, 0xBA5C, 0x669D, 0xBA5D, 0x699C, 0xBA5E, 0x69A8, 0xBA5F, 0x6995, 0xBA60, 0x69C1, - 0xBA61, 0x69AE, 0xBA62, 0x69D3, 0xBA63, 0x69CB, 0xBA64, 0x699B, 0xBA65, 0x69B7, 0xBA66, 0x69BB, 0xBA67, 0x69AB, 0xBA68, 0x69B4, - 0xBA69, 0x69D0, 0xBA6A, 0x69CD, 0xBA6B, 0x69AD, 0xBA6C, 0x69CC, 0xBA6D, 0x69A6, 0xBA6E, 0x69C3, 0xBA6F, 0x69A3, 0xBA70, 0x6B49, - 0xBA71, 0x6B4C, 0xBA72, 0x6C33, 0xBA73, 0x6F33, 0xBA74, 0x6F14, 0xBA75, 0x6EFE, 0xBA76, 0x6F13, 0xBA77, 0x6EF4, 0xBA78, 0x6F29, - 0xBA79, 0x6F3E, 0xBA7A, 0x6F20, 0xBA7B, 0x6F2C, 0xBA7C, 0x6F0F, 0xBA7D, 0x6F02, 0xBA7E, 0x6F22, 0xBAA1, 0x6EFF, 0xBAA2, 0x6EEF, - 0xBAA3, 0x6F06, 0xBAA4, 0x6F31, 0xBAA5, 0x6F38, 0xBAA6, 0x6F32, 0xBAA7, 0x6F23, 0xBAA8, 0x6F15, 0xBAA9, 0x6F2B, 0xBAAA, 0x6F2F, - 0xBAAB, 0x6F88, 0xBAAC, 0x6F2A, 0xBAAD, 0x6EEC, 0xBAAE, 0x6F01, 0xBAAF, 0x6EF2, 0xBAB0, 0x6ECC, 0xBAB1, 0x6EF7, 0xBAB2, 0x7194, - 0xBAB3, 0x7199, 0xBAB4, 0x717D, 0xBAB5, 0x718A, 0xBAB6, 0x7184, 0xBAB7, 0x7192, 0xBAB8, 0x723E, 0xBAB9, 0x7292, 0xBABA, 0x7296, - 0xBABB, 0x7344, 0xBABC, 0x7350, 0xBABD, 0x7464, 0xBABE, 0x7463, 0xBABF, 0x746A, 0xBAC0, 0x7470, 0xBAC1, 0x746D, 0xBAC2, 0x7504, - 0xBAC3, 0x7591, 0xBAC4, 0x7627, 0xBAC5, 0x760D, 0xBAC6, 0x760B, 0xBAC7, 0x7609, 0xBAC8, 0x7613, 0xBAC9, 0x76E1, 0xBACA, 0x76E3, - 0xBACB, 0x7784, 0xBACC, 0x777D, 0xBACD, 0x777F, 0xBACE, 0x7761, 0xBACF, 0x78C1, 0xBAD0, 0x789F, 0xBAD1, 0x78A7, 0xBAD2, 0x78B3, - 0xBAD3, 0x78A9, 0xBAD4, 0x78A3, 0xBAD5, 0x798E, 0xBAD6, 0x798F, 0xBAD7, 0x798D, 0xBAD8, 0x7A2E, 0xBAD9, 0x7A31, 0xBADA, 0x7AAA, - 0xBADB, 0x7AA9, 0xBADC, 0x7AED, 0xBADD, 0x7AEF, 0xBADE, 0x7BA1, 0xBADF, 0x7B95, 0xBAE0, 0x7B8B, 0xBAE1, 0x7B75, 0xBAE2, 0x7B97, - 0xBAE3, 0x7B9D, 0xBAE4, 0x7B94, 0xBAE5, 0x7B8F, 0xBAE6, 0x7BB8, 0xBAE7, 0x7B87, 0xBAE8, 0x7B84, 0xBAE9, 0x7CB9, 0xBAEA, 0x7CBD, - 0xBAEB, 0x7CBE, 0xBAEC, 0x7DBB, 0xBAED, 0x7DB0, 0xBAEE, 0x7D9C, 0xBAEF, 0x7DBD, 0xBAF0, 0x7DBE, 0xBAF1, 0x7DA0, 0xBAF2, 0x7DCA, - 0xBAF3, 0x7DB4, 0xBAF4, 0x7DB2, 0xBAF5, 0x7DB1, 0xBAF6, 0x7DBA, 0xBAF7, 0x7DA2, 0xBAF8, 0x7DBF, 0xBAF9, 0x7DB5, 0xBAFA, 0x7DB8, - 0xBAFB, 0x7DAD, 0xBAFC, 0x7DD2, 0xBAFD, 0x7DC7, 0xBAFE, 0x7DAC, 0xBB40, 0x7F70, 0xBB41, 0x7FE0, 0xBB42, 0x7FE1, 0xBB43, 0x7FDF, - 0xBB44, 0x805E, 0xBB45, 0x805A, 0xBB46, 0x8087, 0xBB47, 0x8150, 0xBB48, 0x8180, 0xBB49, 0x818F, 0xBB4A, 0x8188, 0xBB4B, 0x818A, - 0xBB4C, 0x817F, 0xBB4D, 0x8182, 0xBB4E, 0x81E7, 0xBB4F, 0x81FA, 0xBB50, 0x8207, 0xBB51, 0x8214, 0xBB52, 0x821E, 0xBB53, 0x824B, - 0xBB54, 0x84C9, 0xBB55, 0x84BF, 0xBB56, 0x84C6, 0xBB57, 0x84C4, 0xBB58, 0x8499, 0xBB59, 0x849E, 0xBB5A, 0x84B2, 0xBB5B, 0x849C, - 0xBB5C, 0x84CB, 0xBB5D, 0x84B8, 0xBB5E, 0x84C0, 0xBB5F, 0x84D3, 0xBB60, 0x8490, 0xBB61, 0x84BC, 0xBB62, 0x84D1, 0xBB63, 0x84CA, - 0xBB64, 0x873F, 0xBB65, 0x871C, 0xBB66, 0x873B, 0xBB67, 0x8722, 0xBB68, 0x8725, 0xBB69, 0x8734, 0xBB6A, 0x8718, 0xBB6B, 0x8755, - 0xBB6C, 0x8737, 0xBB6D, 0x8729, 0xBB6E, 0x88F3, 0xBB6F, 0x8902, 0xBB70, 0x88F4, 0xBB71, 0x88F9, 0xBB72, 0x88F8, 0xBB73, 0x88FD, - 0xBB74, 0x88E8, 0xBB75, 0x891A, 0xBB76, 0x88EF, 0xBB77, 0x8AA6, 0xBB78, 0x8A8C, 0xBB79, 0x8A9E, 0xBB7A, 0x8AA3, 0xBB7B, 0x8A8D, - 0xBB7C, 0x8AA1, 0xBB7D, 0x8A93, 0xBB7E, 0x8AA4, 0xBBA1, 0x8AAA, 0xBBA2, 0x8AA5, 0xBBA3, 0x8AA8, 0xBBA4, 0x8A98, 0xBBA5, 0x8A91, - 0xBBA6, 0x8A9A, 0xBBA7, 0x8AA7, 0xBBA8, 0x8C6A, 0xBBA9, 0x8C8D, 0xBBAA, 0x8C8C, 0xBBAB, 0x8CD3, 0xBBAC, 0x8CD1, 0xBBAD, 0x8CD2, - 0xBBAE, 0x8D6B, 0xBBAF, 0x8D99, 0xBBB0, 0x8D95, 0xBBB1, 0x8DFC, 0xBBB2, 0x8F14, 0xBBB3, 0x8F12, 0xBBB4, 0x8F15, 0xBBB5, 0x8F13, - 0xBBB6, 0x8FA3, 0xBBB7, 0x9060, 0xBBB8, 0x9058, 0xBBB9, 0x905C, 0xBBBA, 0x9063, 0xBBBB, 0x9059, 0xBBBC, 0x905E, 0xBBBD, 0x9062, - 0xBBBE, 0x905D, 0xBBBF, 0x905B, 0xBBC0, 0x9119, 0xBBC1, 0x9118, 0xBBC2, 0x911E, 0xBBC3, 0x9175, 0xBBC4, 0x9178, 0xBBC5, 0x9177, - 0xBBC6, 0x9174, 0xBBC7, 0x9278, 0xBBC8, 0x9280, 0xBBC9, 0x9285, 0xBBCA, 0x9298, 0xBBCB, 0x9296, 0xBBCC, 0x927B, 0xBBCD, 0x9293, - 0xBBCE, 0x929C, 0xBBCF, 0x92A8, 0xBBD0, 0x927C, 0xBBD1, 0x9291, 0xBBD2, 0x95A1, 0xBBD3, 0x95A8, 0xBBD4, 0x95A9, 0xBBD5, 0x95A3, - 0xBBD6, 0x95A5, 0xBBD7, 0x95A4, 0xBBD8, 0x9699, 0xBBD9, 0x969C, 0xBBDA, 0x969B, 0xBBDB, 0x96CC, 0xBBDC, 0x96D2, 0xBBDD, 0x9700, - 0xBBDE, 0x977C, 0xBBDF, 0x9785, 0xBBE0, 0x97F6, 0xBBE1, 0x9817, 0xBBE2, 0x9818, 0xBBE3, 0x98AF, 0xBBE4, 0x98B1, 0xBBE5, 0x9903, - 0xBBE6, 0x9905, 0xBBE7, 0x990C, 0xBBE8, 0x9909, 0xBBE9, 0x99C1, 0xBBEA, 0x9AAF, 0xBBEB, 0x9AB0, 0xBBEC, 0x9AE6, 0xBBED, 0x9B41, - 0xBBEE, 0x9B42, 0xBBEF, 0x9CF4, 0xBBF0, 0x9CF6, 0xBBF1, 0x9CF3, 0xBBF2, 0x9EBC, 0xBBF3, 0x9F3B, 0xBBF4, 0x9F4A, 0xBBF5, 0x5104, - 0xBBF6, 0x5100, 0xBBF7, 0x50FB, 0xBBF8, 0x50F5, 0xBBF9, 0x50F9, 0xBBFA, 0x5102, 0xBBFB, 0x5108, 0xBBFC, 0x5109, 0xBBFD, 0x5105, - 0xBBFE, 0x51DC, 0xBC40, 0x5287, 0xBC41, 0x5288, 0xBC42, 0x5289, 0xBC43, 0x528D, 0xBC44, 0x528A, 0xBC45, 0x52F0, 0xBC46, 0x53B2, - 0xBC47, 0x562E, 0xBC48, 0x563B, 0xBC49, 0x5639, 0xBC4A, 0x5632, 0xBC4B, 0x563F, 0xBC4C, 0x5634, 0xBC4D, 0x5629, 0xBC4E, 0x5653, - 0xBC4F, 0x564E, 0xBC50, 0x5657, 0xBC51, 0x5674, 0xBC52, 0x5636, 0xBC53, 0x562F, 0xBC54, 0x5630, 0xBC55, 0x5880, 0xBC56, 0x589F, - 0xBC57, 0x589E, 0xBC58, 0x58B3, 0xBC59, 0x589C, 0xBC5A, 0x58AE, 0xBC5B, 0x58A9, 0xBC5C, 0x58A6, 0xBC5D, 0x596D, 0xBC5E, 0x5B09, - 0xBC5F, 0x5AFB, 0xBC60, 0x5B0B, 0xBC61, 0x5AF5, 0xBC62, 0x5B0C, 0xBC63, 0x5B08, 0xBC64, 0x5BEE, 0xBC65, 0x5BEC, 0xBC66, 0x5BE9, - 0xBC67, 0x5BEB, 0xBC68, 0x5C64, 0xBC69, 0x5C65, 0xBC6A, 0x5D9D, 0xBC6B, 0x5D94, 0xBC6C, 0x5E62, 0xBC6D, 0x5E5F, 0xBC6E, 0x5E61, - 0xBC6F, 0x5EE2, 0xBC70, 0x5EDA, 0xBC71, 0x5EDF, 0xBC72, 0x5EDD, 0xBC73, 0x5EE3, 0xBC74, 0x5EE0, 0xBC75, 0x5F48, 0xBC76, 0x5F71, - 0xBC77, 0x5FB7, 0xBC78, 0x5FB5, 0xBC79, 0x6176, 0xBC7A, 0x6167, 0xBC7B, 0x616E, 0xBC7C, 0x615D, 0xBC7D, 0x6155, 0xBC7E, 0x6182, - 0xBCA1, 0x617C, 0xBCA2, 0x6170, 0xBCA3, 0x616B, 0xBCA4, 0x617E, 0xBCA5, 0x61A7, 0xBCA6, 0x6190, 0xBCA7, 0x61AB, 0xBCA8, 0x618E, - 0xBCA9, 0x61AC, 0xBCAA, 0x619A, 0xBCAB, 0x61A4, 0xBCAC, 0x6194, 0xBCAD, 0x61AE, 0xBCAE, 0x622E, 0xBCAF, 0x6469, 0xBCB0, 0x646F, - 0xBCB1, 0x6479, 0xBCB2, 0x649E, 0xBCB3, 0x64B2, 0xBCB4, 0x6488, 0xBCB5, 0x6490, 0xBCB6, 0x64B0, 0xBCB7, 0x64A5, 0xBCB8, 0x6493, - 0xBCB9, 0x6495, 0xBCBA, 0x64A9, 0xBCBB, 0x6492, 0xBCBC, 0x64AE, 0xBCBD, 0x64AD, 0xBCBE, 0x64AB, 0xBCBF, 0x649A, 0xBCC0, 0x64AC, - 0xBCC1, 0x6499, 0xBCC2, 0x64A2, 0xBCC3, 0x64B3, 0xBCC4, 0x6575, 0xBCC5, 0x6577, 0xBCC6, 0x6578, 0xBCC7, 0x66AE, 0xBCC8, 0x66AB, - 0xBCC9, 0x66B4, 0xBCCA, 0x66B1, 0xBCCB, 0x6A23, 0xBCCC, 0x6A1F, 0xBCCD, 0x69E8, 0xBCCE, 0x6A01, 0xBCCF, 0x6A1E, 0xBCD0, 0x6A19, - 0xBCD1, 0x69FD, 0xBCD2, 0x6A21, 0xBCD3, 0x6A13, 0xBCD4, 0x6A0A, 0xBCD5, 0x69F3, 0xBCD6, 0x6A02, 0xBCD7, 0x6A05, 0xBCD8, 0x69ED, - 0xBCD9, 0x6A11, 0xBCDA, 0x6B50, 0xBCDB, 0x6B4E, 0xBCDC, 0x6BA4, 0xBCDD, 0x6BC5, 0xBCDE, 0x6BC6, 0xBCDF, 0x6F3F, 0xBCE0, 0x6F7C, - 0xBCE1, 0x6F84, 0xBCE2, 0x6F51, 0xBCE3, 0x6F66, 0xBCE4, 0x6F54, 0xBCE5, 0x6F86, 0xBCE6, 0x6F6D, 0xBCE7, 0x6F5B, 0xBCE8, 0x6F78, - 0xBCE9, 0x6F6E, 0xBCEA, 0x6F8E, 0xBCEB, 0x6F7A, 0xBCEC, 0x6F70, 0xBCED, 0x6F64, 0xBCEE, 0x6F97, 0xBCEF, 0x6F58, 0xBCF0, 0x6ED5, - 0xBCF1, 0x6F6F, 0xBCF2, 0x6F60, 0xBCF3, 0x6F5F, 0xBCF4, 0x719F, 0xBCF5, 0x71AC, 0xBCF6, 0x71B1, 0xBCF7, 0x71A8, 0xBCF8, 0x7256, - 0xBCF9, 0x729B, 0xBCFA, 0x734E, 0xBCFB, 0x7357, 0xBCFC, 0x7469, 0xBCFD, 0x748B, 0xBCFE, 0x7483, 0xBD40, 0x747E, 0xBD41, 0x7480, - 0xBD42, 0x757F, 0xBD43, 0x7620, 0xBD44, 0x7629, 0xBD45, 0x761F, 0xBD46, 0x7624, 0xBD47, 0x7626, 0xBD48, 0x7621, 0xBD49, 0x7622, - 0xBD4A, 0x769A, 0xBD4B, 0x76BA, 0xBD4C, 0x76E4, 0xBD4D, 0x778E, 0xBD4E, 0x7787, 0xBD4F, 0x778C, 0xBD50, 0x7791, 0xBD51, 0x778B, - 0xBD52, 0x78CB, 0xBD53, 0x78C5, 0xBD54, 0x78BA, 0xBD55, 0x78CA, 0xBD56, 0x78BE, 0xBD57, 0x78D5, 0xBD58, 0x78BC, 0xBD59, 0x78D0, - 0xBD5A, 0x7A3F, 0xBD5B, 0x7A3C, 0xBD5C, 0x7A40, 0xBD5D, 0x7A3D, 0xBD5E, 0x7A37, 0xBD5F, 0x7A3B, 0xBD60, 0x7AAF, 0xBD61, 0x7AAE, - 0xBD62, 0x7BAD, 0xBD63, 0x7BB1, 0xBD64, 0x7BC4, 0xBD65, 0x7BB4, 0xBD66, 0x7BC6, 0xBD67, 0x7BC7, 0xBD68, 0x7BC1, 0xBD69, 0x7BA0, - 0xBD6A, 0x7BCC, 0xBD6B, 0x7CCA, 0xBD6C, 0x7DE0, 0xBD6D, 0x7DF4, 0xBD6E, 0x7DEF, 0xBD6F, 0x7DFB, 0xBD70, 0x7DD8, 0xBD71, 0x7DEC, - 0xBD72, 0x7DDD, 0xBD73, 0x7DE8, 0xBD74, 0x7DE3, 0xBD75, 0x7DDA, 0xBD76, 0x7DDE, 0xBD77, 0x7DE9, 0xBD78, 0x7D9E, 0xBD79, 0x7DD9, - 0xBD7A, 0x7DF2, 0xBD7B, 0x7DF9, 0xBD7C, 0x7F75, 0xBD7D, 0x7F77, 0xBD7E, 0x7FAF, 0xBDA1, 0x7FE9, 0xBDA2, 0x8026, 0xBDA3, 0x819B, - 0xBDA4, 0x819C, 0xBDA5, 0x819D, 0xBDA6, 0x81A0, 0xBDA7, 0x819A, 0xBDA8, 0x8198, 0xBDA9, 0x8517, 0xBDAA, 0x853D, 0xBDAB, 0x851A, - 0xBDAC, 0x84EE, 0xBDAD, 0x852C, 0xBDAE, 0x852D, 0xBDAF, 0x8513, 0xBDB0, 0x8511, 0xBDB1, 0x8523, 0xBDB2, 0x8521, 0xBDB3, 0x8514, - 0xBDB4, 0x84EC, 0xBDB5, 0x8525, 0xBDB6, 0x84FF, 0xBDB7, 0x8506, 0xBDB8, 0x8782, 0xBDB9, 0x8774, 0xBDBA, 0x8776, 0xBDBB, 0x8760, - 0xBDBC, 0x8766, 0xBDBD, 0x8778, 0xBDBE, 0x8768, 0xBDBF, 0x8759, 0xBDC0, 0x8757, 0xBDC1, 0x874C, 0xBDC2, 0x8753, 0xBDC3, 0x885B, - 0xBDC4, 0x885D, 0xBDC5, 0x8910, 0xBDC6, 0x8907, 0xBDC7, 0x8912, 0xBDC8, 0x8913, 0xBDC9, 0x8915, 0xBDCA, 0x890A, 0xBDCB, 0x8ABC, - 0xBDCC, 0x8AD2, 0xBDCD, 0x8AC7, 0xBDCE, 0x8AC4, 0xBDCF, 0x8A95, 0xBDD0, 0x8ACB, 0xBDD1, 0x8AF8, 0xBDD2, 0x8AB2, 0xBDD3, 0x8AC9, - 0xBDD4, 0x8AC2, 0xBDD5, 0x8ABF, 0xBDD6, 0x8AB0, 0xBDD7, 0x8AD6, 0xBDD8, 0x8ACD, 0xBDD9, 0x8AB6, 0xBDDA, 0x8AB9, 0xBDDB, 0x8ADB, - 0xBDDC, 0x8C4C, 0xBDDD, 0x8C4E, 0xBDDE, 0x8C6C, 0xBDDF, 0x8CE0, 0xBDE0, 0x8CDE, 0xBDE1, 0x8CE6, 0xBDE2, 0x8CE4, 0xBDE3, 0x8CEC, - 0xBDE4, 0x8CED, 0xBDE5, 0x8CE2, 0xBDE6, 0x8CE3, 0xBDE7, 0x8CDC, 0xBDE8, 0x8CEA, 0xBDE9, 0x8CE1, 0xBDEA, 0x8D6D, 0xBDEB, 0x8D9F, - 0xBDEC, 0x8DA3, 0xBDED, 0x8E2B, 0xBDEE, 0x8E10, 0xBDEF, 0x8E1D, 0xBDF0, 0x8E22, 0xBDF1, 0x8E0F, 0xBDF2, 0x8E29, 0xBDF3, 0x8E1F, - 0xBDF4, 0x8E21, 0xBDF5, 0x8E1E, 0xBDF6, 0x8EBA, 0xBDF7, 0x8F1D, 0xBDF8, 0x8F1B, 0xBDF9, 0x8F1F, 0xBDFA, 0x8F29, 0xBDFB, 0x8F26, - 0xBDFC, 0x8F2A, 0xBDFD, 0x8F1C, 0xBDFE, 0x8F1E, 0xBE40, 0x8F25, 0xBE41, 0x9069, 0xBE42, 0x906E, 0xBE43, 0x9068, 0xBE44, 0x906D, - 0xBE45, 0x9077, 0xBE46, 0x9130, 0xBE47, 0x912D, 0xBE48, 0x9127, 0xBE49, 0x9131, 0xBE4A, 0x9187, 0xBE4B, 0x9189, 0xBE4C, 0x918B, - 0xBE4D, 0x9183, 0xBE4E, 0x92C5, 0xBE4F, 0x92BB, 0xBE50, 0x92B7, 0xBE51, 0x92EA, 0xBE52, 0x92AC, 0xBE53, 0x92E4, 0xBE54, 0x92C1, - 0xBE55, 0x92B3, 0xBE56, 0x92BC, 0xBE57, 0x92D2, 0xBE58, 0x92C7, 0xBE59, 0x92F0, 0xBE5A, 0x92B2, 0xBE5B, 0x95AD, 0xBE5C, 0x95B1, - 0xBE5D, 0x9704, 0xBE5E, 0x9706, 0xBE5F, 0x9707, 0xBE60, 0x9709, 0xBE61, 0x9760, 0xBE62, 0x978D, 0xBE63, 0x978B, 0xBE64, 0x978F, - 0xBE65, 0x9821, 0xBE66, 0x982B, 0xBE67, 0x981C, 0xBE68, 0x98B3, 0xBE69, 0x990A, 0xBE6A, 0x9913, 0xBE6B, 0x9912, 0xBE6C, 0x9918, - 0xBE6D, 0x99DD, 0xBE6E, 0x99D0, 0xBE6F, 0x99DF, 0xBE70, 0x99DB, 0xBE71, 0x99D1, 0xBE72, 0x99D5, 0xBE73, 0x99D2, 0xBE74, 0x99D9, - 0xBE75, 0x9AB7, 0xBE76, 0x9AEE, 0xBE77, 0x9AEF, 0xBE78, 0x9B27, 0xBE79, 0x9B45, 0xBE7A, 0x9B44, 0xBE7B, 0x9B77, 0xBE7C, 0x9B6F, - 0xBE7D, 0x9D06, 0xBE7E, 0x9D09, 0xBEA1, 0x9D03, 0xBEA2, 0x9EA9, 0xBEA3, 0x9EBE, 0xBEA4, 0x9ECE, 0xBEA5, 0x58A8, 0xBEA6, 0x9F52, - 0xBEA7, 0x5112, 0xBEA8, 0x5118, 0xBEA9, 0x5114, 0xBEAA, 0x5110, 0xBEAB, 0x5115, 0xBEAC, 0x5180, 0xBEAD, 0x51AA, 0xBEAE, 0x51DD, - 0xBEAF, 0x5291, 0xBEB0, 0x5293, 0xBEB1, 0x52F3, 0xBEB2, 0x5659, 0xBEB3, 0x566B, 0xBEB4, 0x5679, 0xBEB5, 0x5669, 0xBEB6, 0x5664, - 0xBEB7, 0x5678, 0xBEB8, 0x566A, 0xBEB9, 0x5668, 0xBEBA, 0x5665, 0xBEBB, 0x5671, 0xBEBC, 0x566F, 0xBEBD, 0x566C, 0xBEBE, 0x5662, - 0xBEBF, 0x5676, 0xBEC0, 0x58C1, 0xBEC1, 0x58BE, 0xBEC2, 0x58C7, 0xBEC3, 0x58C5, 0xBEC4, 0x596E, 0xBEC5, 0x5B1D, 0xBEC6, 0x5B34, - 0xBEC7, 0x5B78, 0xBEC8, 0x5BF0, 0xBEC9, 0x5C0E, 0xBECA, 0x5F4A, 0xBECB, 0x61B2, 0xBECC, 0x6191, 0xBECD, 0x61A9, 0xBECE, 0x618A, - 0xBECF, 0x61CD, 0xBED0, 0x61B6, 0xBED1, 0x61BE, 0xBED2, 0x61CA, 0xBED3, 0x61C8, 0xBED4, 0x6230, 0xBED5, 0x64C5, 0xBED6, 0x64C1, - 0xBED7, 0x64CB, 0xBED8, 0x64BB, 0xBED9, 0x64BC, 0xBEDA, 0x64DA, 0xBEDB, 0x64C4, 0xBEDC, 0x64C7, 0xBEDD, 0x64C2, 0xBEDE, 0x64CD, - 0xBEDF, 0x64BF, 0xBEE0, 0x64D2, 0xBEE1, 0x64D4, 0xBEE2, 0x64BE, 0xBEE3, 0x6574, 0xBEE4, 0x66C6, 0xBEE5, 0x66C9, 0xBEE6, 0x66B9, - 0xBEE7, 0x66C4, 0xBEE8, 0x66C7, 0xBEE9, 0x66B8, 0xBEEA, 0x6A3D, 0xBEEB, 0x6A38, 0xBEEC, 0x6A3A, 0xBEED, 0x6A59, 0xBEEE, 0x6A6B, - 0xBEEF, 0x6A58, 0xBEF0, 0x6A39, 0xBEF1, 0x6A44, 0xBEF2, 0x6A62, 0xBEF3, 0x6A61, 0xBEF4, 0x6A4B, 0xBEF5, 0x6A47, 0xBEF6, 0x6A35, - 0xBEF7, 0x6A5F, 0xBEF8, 0x6A48, 0xBEF9, 0x6B59, 0xBEFA, 0x6B77, 0xBEFB, 0x6C05, 0xBEFC, 0x6FC2, 0xBEFD, 0x6FB1, 0xBEFE, 0x6FA1, - 0xBF40, 0x6FC3, 0xBF41, 0x6FA4, 0xBF42, 0x6FC1, 0xBF43, 0x6FA7, 0xBF44, 0x6FB3, 0xBF45, 0x6FC0, 0xBF46, 0x6FB9, 0xBF47, 0x6FB6, - 0xBF48, 0x6FA6, 0xBF49, 0x6FA0, 0xBF4A, 0x6FB4, 0xBF4B, 0x71BE, 0xBF4C, 0x71C9, 0xBF4D, 0x71D0, 0xBF4E, 0x71D2, 0xBF4F, 0x71C8, - 0xBF50, 0x71D5, 0xBF51, 0x71B9, 0xBF52, 0x71CE, 0xBF53, 0x71D9, 0xBF54, 0x71DC, 0xBF55, 0x71C3, 0xBF56, 0x71C4, 0xBF57, 0x7368, - 0xBF58, 0x749C, 0xBF59, 0x74A3, 0xBF5A, 0x7498, 0xBF5B, 0x749F, 0xBF5C, 0x749E, 0xBF5D, 0x74E2, 0xBF5E, 0x750C, 0xBF5F, 0x750D, - 0xBF60, 0x7634, 0xBF61, 0x7638, 0xBF62, 0x763A, 0xBF63, 0x76E7, 0xBF64, 0x76E5, 0xBF65, 0x77A0, 0xBF66, 0x779E, 0xBF67, 0x779F, - 0xBF68, 0x77A5, 0xBF69, 0x78E8, 0xBF6A, 0x78DA, 0xBF6B, 0x78EC, 0xBF6C, 0x78E7, 0xBF6D, 0x79A6, 0xBF6E, 0x7A4D, 0xBF6F, 0x7A4E, - 0xBF70, 0x7A46, 0xBF71, 0x7A4C, 0xBF72, 0x7A4B, 0xBF73, 0x7ABA, 0xBF74, 0x7BD9, 0xBF75, 0x7C11, 0xBF76, 0x7BC9, 0xBF77, 0x7BE4, - 0xBF78, 0x7BDB, 0xBF79, 0x7BE1, 0xBF7A, 0x7BE9, 0xBF7B, 0x7BE6, 0xBF7C, 0x7CD5, 0xBF7D, 0x7CD6, 0xBF7E, 0x7E0A, 0xBFA1, 0x7E11, - 0xBFA2, 0x7E08, 0xBFA3, 0x7E1B, 0xBFA4, 0x7E23, 0xBFA5, 0x7E1E, 0xBFA6, 0x7E1D, 0xBFA7, 0x7E09, 0xBFA8, 0x7E10, 0xBFA9, 0x7F79, - 0xBFAA, 0x7FB2, 0xBFAB, 0x7FF0, 0xBFAC, 0x7FF1, 0xBFAD, 0x7FEE, 0xBFAE, 0x8028, 0xBFAF, 0x81B3, 0xBFB0, 0x81A9, 0xBFB1, 0x81A8, - 0xBFB2, 0x81FB, 0xBFB3, 0x8208, 0xBFB4, 0x8258, 0xBFB5, 0x8259, 0xBFB6, 0x854A, 0xBFB7, 0x8559, 0xBFB8, 0x8548, 0xBFB9, 0x8568, - 0xBFBA, 0x8569, 0xBFBB, 0x8543, 0xBFBC, 0x8549, 0xBFBD, 0x856D, 0xBFBE, 0x856A, 0xBFBF, 0x855E, 0xBFC0, 0x8783, 0xBFC1, 0x879F, - 0xBFC2, 0x879E, 0xBFC3, 0x87A2, 0xBFC4, 0x878D, 0xBFC5, 0x8861, 0xBFC6, 0x892A, 0xBFC7, 0x8932, 0xBFC8, 0x8925, 0xBFC9, 0x892B, - 0xBFCA, 0x8921, 0xBFCB, 0x89AA, 0xBFCC, 0x89A6, 0xBFCD, 0x8AE6, 0xBFCE, 0x8AFA, 0xBFCF, 0x8AEB, 0xBFD0, 0x8AF1, 0xBFD1, 0x8B00, - 0xBFD2, 0x8ADC, 0xBFD3, 0x8AE7, 0xBFD4, 0x8AEE, 0xBFD5, 0x8AFE, 0xBFD6, 0x8B01, 0xBFD7, 0x8B02, 0xBFD8, 0x8AF7, 0xBFD9, 0x8AED, - 0xBFDA, 0x8AF3, 0xBFDB, 0x8AF6, 0xBFDC, 0x8AFC, 0xBFDD, 0x8C6B, 0xBFDE, 0x8C6D, 0xBFDF, 0x8C93, 0xBFE0, 0x8CF4, 0xBFE1, 0x8E44, - 0xBFE2, 0x8E31, 0xBFE3, 0x8E34, 0xBFE4, 0x8E42, 0xBFE5, 0x8E39, 0xBFE6, 0x8E35, 0xBFE7, 0x8F3B, 0xBFE8, 0x8F2F, 0xBFE9, 0x8F38, - 0xBFEA, 0x8F33, 0xBFEB, 0x8FA8, 0xBFEC, 0x8FA6, 0xBFED, 0x9075, 0xBFEE, 0x9074, 0xBFEF, 0x9078, 0xBFF0, 0x9072, 0xBFF1, 0x907C, - 0xBFF2, 0x907A, 0xBFF3, 0x9134, 0xBFF4, 0x9192, 0xBFF5, 0x9320, 0xBFF6, 0x9336, 0xBFF7, 0x92F8, 0xBFF8, 0x9333, 0xBFF9, 0x932F, - 0xBFFA, 0x9322, 0xBFFB, 0x92FC, 0xBFFC, 0x932B, 0xBFFD, 0x9304, 0xBFFE, 0x931A, 0xC040, 0x9310, 0xC041, 0x9326, 0xC042, 0x9321, - 0xC043, 0x9315, 0xC044, 0x932E, 0xC045, 0x9319, 0xC046, 0x95BB, 0xC047, 0x96A7, 0xC048, 0x96A8, 0xC049, 0x96AA, 0xC04A, 0x96D5, - 0xC04B, 0x970E, 0xC04C, 0x9711, 0xC04D, 0x9716, 0xC04E, 0x970D, 0xC04F, 0x9713, 0xC050, 0x970F, 0xC051, 0x975B, 0xC052, 0x975C, - 0xC053, 0x9766, 0xC054, 0x9798, 0xC055, 0x9830, 0xC056, 0x9838, 0xC057, 0x983B, 0xC058, 0x9837, 0xC059, 0x982D, 0xC05A, 0x9839, - 0xC05B, 0x9824, 0xC05C, 0x9910, 0xC05D, 0x9928, 0xC05E, 0x991E, 0xC05F, 0x991B, 0xC060, 0x9921, 0xC061, 0x991A, 0xC062, 0x99ED, - 0xC063, 0x99E2, 0xC064, 0x99F1, 0xC065, 0x9AB8, 0xC066, 0x9ABC, 0xC067, 0x9AFB, 0xC068, 0x9AED, 0xC069, 0x9B28, 0xC06A, 0x9B91, - 0xC06B, 0x9D15, 0xC06C, 0x9D23, 0xC06D, 0x9D26, 0xC06E, 0x9D28, 0xC06F, 0x9D12, 0xC070, 0x9D1B, 0xC071, 0x9ED8, 0xC072, 0x9ED4, - 0xC073, 0x9F8D, 0xC074, 0x9F9C, 0xC075, 0x512A, 0xC076, 0x511F, 0xC077, 0x5121, 0xC078, 0x5132, 0xC079, 0x52F5, 0xC07A, 0x568E, - 0xC07B, 0x5680, 0xC07C, 0x5690, 0xC07D, 0x5685, 0xC07E, 0x5687, 0xC0A1, 0x568F, 0xC0A2, 0x58D5, 0xC0A3, 0x58D3, 0xC0A4, 0x58D1, - 0xC0A5, 0x58CE, 0xC0A6, 0x5B30, 0xC0A7, 0x5B2A, 0xC0A8, 0x5B24, 0xC0A9, 0x5B7A, 0xC0AA, 0x5C37, 0xC0AB, 0x5C68, 0xC0AC, 0x5DBC, - 0xC0AD, 0x5DBA, 0xC0AE, 0x5DBD, 0xC0AF, 0x5DB8, 0xC0B0, 0x5E6B, 0xC0B1, 0x5F4C, 0xC0B2, 0x5FBD, 0xC0B3, 0x61C9, 0xC0B4, 0x61C2, - 0xC0B5, 0x61C7, 0xC0B6, 0x61E6, 0xC0B7, 0x61CB, 0xC0B8, 0x6232, 0xC0B9, 0x6234, 0xC0BA, 0x64CE, 0xC0BB, 0x64CA, 0xC0BC, 0x64D8, - 0xC0BD, 0x64E0, 0xC0BE, 0x64F0, 0xC0BF, 0x64E6, 0xC0C0, 0x64EC, 0xC0C1, 0x64F1, 0xC0C2, 0x64E2, 0xC0C3, 0x64ED, 0xC0C4, 0x6582, - 0xC0C5, 0x6583, 0xC0C6, 0x66D9, 0xC0C7, 0x66D6, 0xC0C8, 0x6A80, 0xC0C9, 0x6A94, 0xC0CA, 0x6A84, 0xC0CB, 0x6AA2, 0xC0CC, 0x6A9C, - 0xC0CD, 0x6ADB, 0xC0CE, 0x6AA3, 0xC0CF, 0x6A7E, 0xC0D0, 0x6A97, 0xC0D1, 0x6A90, 0xC0D2, 0x6AA0, 0xC0D3, 0x6B5C, 0xC0D4, 0x6BAE, - 0xC0D5, 0x6BDA, 0xC0D6, 0x6C08, 0xC0D7, 0x6FD8, 0xC0D8, 0x6FF1, 0xC0D9, 0x6FDF, 0xC0DA, 0x6FE0, 0xC0DB, 0x6FDB, 0xC0DC, 0x6FE4, - 0xC0DD, 0x6FEB, 0xC0DE, 0x6FEF, 0xC0DF, 0x6F80, 0xC0E0, 0x6FEC, 0xC0E1, 0x6FE1, 0xC0E2, 0x6FE9, 0xC0E3, 0x6FD5, 0xC0E4, 0x6FEE, - 0xC0E5, 0x6FF0, 0xC0E6, 0x71E7, 0xC0E7, 0x71DF, 0xC0E8, 0x71EE, 0xC0E9, 0x71E6, 0xC0EA, 0x71E5, 0xC0EB, 0x71ED, 0xC0EC, 0x71EC, - 0xC0ED, 0x71F4, 0xC0EE, 0x71E0, 0xC0EF, 0x7235, 0xC0F0, 0x7246, 0xC0F1, 0x7370, 0xC0F2, 0x7372, 0xC0F3, 0x74A9, 0xC0F4, 0x74B0, - 0xC0F5, 0x74A6, 0xC0F6, 0x74A8, 0xC0F7, 0x7646, 0xC0F8, 0x7642, 0xC0F9, 0x764C, 0xC0FA, 0x76EA, 0xC0FB, 0x77B3, 0xC0FC, 0x77AA, - 0xC0FD, 0x77B0, 0xC0FE, 0x77AC, 0xC140, 0x77A7, 0xC141, 0x77AD, 0xC142, 0x77EF, 0xC143, 0x78F7, 0xC144, 0x78FA, 0xC145, 0x78F4, - 0xC146, 0x78EF, 0xC147, 0x7901, 0xC148, 0x79A7, 0xC149, 0x79AA, 0xC14A, 0x7A57, 0xC14B, 0x7ABF, 0xC14C, 0x7C07, 0xC14D, 0x7C0D, - 0xC14E, 0x7BFE, 0xC14F, 0x7BF7, 0xC150, 0x7C0C, 0xC151, 0x7BE0, 0xC152, 0x7CE0, 0xC153, 0x7CDC, 0xC154, 0x7CDE, 0xC155, 0x7CE2, - 0xC156, 0x7CDF, 0xC157, 0x7CD9, 0xC158, 0x7CDD, 0xC159, 0x7E2E, 0xC15A, 0x7E3E, 0xC15B, 0x7E46, 0xC15C, 0x7E37, 0xC15D, 0x7E32, - 0xC15E, 0x7E43, 0xC15F, 0x7E2B, 0xC160, 0x7E3D, 0xC161, 0x7E31, 0xC162, 0x7E45, 0xC163, 0x7E41, 0xC164, 0x7E34, 0xC165, 0x7E39, - 0xC166, 0x7E48, 0xC167, 0x7E35, 0xC168, 0x7E3F, 0xC169, 0x7E2F, 0xC16A, 0x7F44, 0xC16B, 0x7FF3, 0xC16C, 0x7FFC, 0xC16D, 0x8071, - 0xC16E, 0x8072, 0xC16F, 0x8070, 0xC170, 0x806F, 0xC171, 0x8073, 0xC172, 0x81C6, 0xC173, 0x81C3, 0xC174, 0x81BA, 0xC175, 0x81C2, - 0xC176, 0x81C0, 0xC177, 0x81BF, 0xC178, 0x81BD, 0xC179, 0x81C9, 0xC17A, 0x81BE, 0xC17B, 0x81E8, 0xC17C, 0x8209, 0xC17D, 0x8271, - 0xC17E, 0x85AA, 0xC1A1, 0x8584, 0xC1A2, 0x857E, 0xC1A3, 0x859C, 0xC1A4, 0x8591, 0xC1A5, 0x8594, 0xC1A6, 0x85AF, 0xC1A7, 0x859B, - 0xC1A8, 0x8587, 0xC1A9, 0x85A8, 0xC1AA, 0x858A, 0xC1AB, 0x8667, 0xC1AC, 0x87C0, 0xC1AD, 0x87D1, 0xC1AE, 0x87B3, 0xC1AF, 0x87D2, - 0xC1B0, 0x87C6, 0xC1B1, 0x87AB, 0xC1B2, 0x87BB, 0xC1B3, 0x87BA, 0xC1B4, 0x87C8, 0xC1B5, 0x87CB, 0xC1B6, 0x893B, 0xC1B7, 0x8936, - 0xC1B8, 0x8944, 0xC1B9, 0x8938, 0xC1BA, 0x893D, 0xC1BB, 0x89AC, 0xC1BC, 0x8B0E, 0xC1BD, 0x8B17, 0xC1BE, 0x8B19, 0xC1BF, 0x8B1B, - 0xC1C0, 0x8B0A, 0xC1C1, 0x8B20, 0xC1C2, 0x8B1D, 0xC1C3, 0x8B04, 0xC1C4, 0x8B10, 0xC1C5, 0x8C41, 0xC1C6, 0x8C3F, 0xC1C7, 0x8C73, - 0xC1C8, 0x8CFA, 0xC1C9, 0x8CFD, 0xC1CA, 0x8CFC, 0xC1CB, 0x8CF8, 0xC1CC, 0x8CFB, 0xC1CD, 0x8DA8, 0xC1CE, 0x8E49, 0xC1CF, 0x8E4B, - 0xC1D0, 0x8E48, 0xC1D1, 0x8E4A, 0xC1D2, 0x8F44, 0xC1D3, 0x8F3E, 0xC1D4, 0x8F42, 0xC1D5, 0x8F45, 0xC1D6, 0x8F3F, 0xC1D7, 0x907F, - 0xC1D8, 0x907D, 0xC1D9, 0x9084, 0xC1DA, 0x9081, 0xC1DB, 0x9082, 0xC1DC, 0x9080, 0xC1DD, 0x9139, 0xC1DE, 0x91A3, 0xC1DF, 0x919E, - 0xC1E0, 0x919C, 0xC1E1, 0x934D, 0xC1E2, 0x9382, 0xC1E3, 0x9328, 0xC1E4, 0x9375, 0xC1E5, 0x934A, 0xC1E6, 0x9365, 0xC1E7, 0x934B, - 0xC1E8, 0x9318, 0xC1E9, 0x937E, 0xC1EA, 0x936C, 0xC1EB, 0x935B, 0xC1EC, 0x9370, 0xC1ED, 0x935A, 0xC1EE, 0x9354, 0xC1EF, 0x95CA, - 0xC1F0, 0x95CB, 0xC1F1, 0x95CC, 0xC1F2, 0x95C8, 0xC1F3, 0x95C6, 0xC1F4, 0x96B1, 0xC1F5, 0x96B8, 0xC1F6, 0x96D6, 0xC1F7, 0x971C, - 0xC1F8, 0x971E, 0xC1F9, 0x97A0, 0xC1FA, 0x97D3, 0xC1FB, 0x9846, 0xC1FC, 0x98B6, 0xC1FD, 0x9935, 0xC1FE, 0x9A01, 0xC240, 0x99FF, - 0xC241, 0x9BAE, 0xC242, 0x9BAB, 0xC243, 0x9BAA, 0xC244, 0x9BAD, 0xC245, 0x9D3B, 0xC246, 0x9D3F, 0xC247, 0x9E8B, 0xC248, 0x9ECF, - 0xC249, 0x9EDE, 0xC24A, 0x9EDC, 0xC24B, 0x9EDD, 0xC24C, 0x9EDB, 0xC24D, 0x9F3E, 0xC24E, 0x9F4B, 0xC24F, 0x53E2, 0xC250, 0x5695, - 0xC251, 0x56AE, 0xC252, 0x58D9, 0xC253, 0x58D8, 0xC254, 0x5B38, 0xC255, 0x5F5D, 0xC256, 0x61E3, 0xC257, 0x6233, 0xC258, 0x64F4, - 0xC259, 0x64F2, 0xC25A, 0x64FE, 0xC25B, 0x6506, 0xC25C, 0x64FA, 0xC25D, 0x64FB, 0xC25E, 0x64F7, 0xC25F, 0x65B7, 0xC260, 0x66DC, - 0xC261, 0x6726, 0xC262, 0x6AB3, 0xC263, 0x6AAC, 0xC264, 0x6AC3, 0xC265, 0x6ABB, 0xC266, 0x6AB8, 0xC267, 0x6AC2, 0xC268, 0x6AAE, - 0xC269, 0x6AAF, 0xC26A, 0x6B5F, 0xC26B, 0x6B78, 0xC26C, 0x6BAF, 0xC26D, 0x7009, 0xC26E, 0x700B, 0xC26F, 0x6FFE, 0xC270, 0x7006, - 0xC271, 0x6FFA, 0xC272, 0x7011, 0xC273, 0x700F, 0xC274, 0x71FB, 0xC275, 0x71FC, 0xC276, 0x71FE, 0xC277, 0x71F8, 0xC278, 0x7377, - 0xC279, 0x7375, 0xC27A, 0x74A7, 0xC27B, 0x74BF, 0xC27C, 0x7515, 0xC27D, 0x7656, 0xC27E, 0x7658, 0xC2A1, 0x7652, 0xC2A2, 0x77BD, - 0xC2A3, 0x77BF, 0xC2A4, 0x77BB, 0xC2A5, 0x77BC, 0xC2A6, 0x790E, 0xC2A7, 0x79AE, 0xC2A8, 0x7A61, 0xC2A9, 0x7A62, 0xC2AA, 0x7A60, - 0xC2AB, 0x7AC4, 0xC2AC, 0x7AC5, 0xC2AD, 0x7C2B, 0xC2AE, 0x7C27, 0xC2AF, 0x7C2A, 0xC2B0, 0x7C1E, 0xC2B1, 0x7C23, 0xC2B2, 0x7C21, - 0xC2B3, 0x7CE7, 0xC2B4, 0x7E54, 0xC2B5, 0x7E55, 0xC2B6, 0x7E5E, 0xC2B7, 0x7E5A, 0xC2B8, 0x7E61, 0xC2B9, 0x7E52, 0xC2BA, 0x7E59, - 0xC2BB, 0x7F48, 0xC2BC, 0x7FF9, 0xC2BD, 0x7FFB, 0xC2BE, 0x8077, 0xC2BF, 0x8076, 0xC2C0, 0x81CD, 0xC2C1, 0x81CF, 0xC2C2, 0x820A, - 0xC2C3, 0x85CF, 0xC2C4, 0x85A9, 0xC2C5, 0x85CD, 0xC2C6, 0x85D0, 0xC2C7, 0x85C9, 0xC2C8, 0x85B0, 0xC2C9, 0x85BA, 0xC2CA, 0x85B9, - 0xC2CB, 0x85A6, 0xC2CC, 0x87EF, 0xC2CD, 0x87EC, 0xC2CE, 0x87F2, 0xC2CF, 0x87E0, 0xC2D0, 0x8986, 0xC2D1, 0x89B2, 0xC2D2, 0x89F4, - 0xC2D3, 0x8B28, 0xC2D4, 0x8B39, 0xC2D5, 0x8B2C, 0xC2D6, 0x8B2B, 0xC2D7, 0x8C50, 0xC2D8, 0x8D05, 0xC2D9, 0x8E59, 0xC2DA, 0x8E63, - 0xC2DB, 0x8E66, 0xC2DC, 0x8E64, 0xC2DD, 0x8E5F, 0xC2DE, 0x8E55, 0xC2DF, 0x8EC0, 0xC2E0, 0x8F49, 0xC2E1, 0x8F4D, 0xC2E2, 0x9087, - 0xC2E3, 0x9083, 0xC2E4, 0x9088, 0xC2E5, 0x91AB, 0xC2E6, 0x91AC, 0xC2E7, 0x91D0, 0xC2E8, 0x9394, 0xC2E9, 0x938A, 0xC2EA, 0x9396, - 0xC2EB, 0x93A2, 0xC2EC, 0x93B3, 0xC2ED, 0x93AE, 0xC2EE, 0x93AC, 0xC2EF, 0x93B0, 0xC2F0, 0x9398, 0xC2F1, 0x939A, 0xC2F2, 0x9397, - 0xC2F3, 0x95D4, 0xC2F4, 0x95D6, 0xC2F5, 0x95D0, 0xC2F6, 0x95D5, 0xC2F7, 0x96E2, 0xC2F8, 0x96DC, 0xC2F9, 0x96D9, 0xC2FA, 0x96DB, - 0xC2FB, 0x96DE, 0xC2FC, 0x9724, 0xC2FD, 0x97A3, 0xC2FE, 0x97A6, 0xC340, 0x97AD, 0xC341, 0x97F9, 0xC342, 0x984D, 0xC343, 0x984F, - 0xC344, 0x984C, 0xC345, 0x984E, 0xC346, 0x9853, 0xC347, 0x98BA, 0xC348, 0x993E, 0xC349, 0x993F, 0xC34A, 0x993D, 0xC34B, 0x992E, - 0xC34C, 0x99A5, 0xC34D, 0x9A0E, 0xC34E, 0x9AC1, 0xC34F, 0x9B03, 0xC350, 0x9B06, 0xC351, 0x9B4F, 0xC352, 0x9B4E, 0xC353, 0x9B4D, - 0xC354, 0x9BCA, 0xC355, 0x9BC9, 0xC356, 0x9BFD, 0xC357, 0x9BC8, 0xC358, 0x9BC0, 0xC359, 0x9D51, 0xC35A, 0x9D5D, 0xC35B, 0x9D60, - 0xC35C, 0x9EE0, 0xC35D, 0x9F15, 0xC35E, 0x9F2C, 0xC35F, 0x5133, 0xC360, 0x56A5, 0xC361, 0x58DE, 0xC362, 0x58DF, 0xC363, 0x58E2, - 0xC364, 0x5BF5, 0xC365, 0x9F90, 0xC366, 0x5EEC, 0xC367, 0x61F2, 0xC368, 0x61F7, 0xC369, 0x61F6, 0xC36A, 0x61F5, 0xC36B, 0x6500, - 0xC36C, 0x650F, 0xC36D, 0x66E0, 0xC36E, 0x66DD, 0xC36F, 0x6AE5, 0xC370, 0x6ADD, 0xC371, 0x6ADA, 0xC372, 0x6AD3, 0xC373, 0x701B, - 0xC374, 0x701F, 0xC375, 0x7028, 0xC376, 0x701A, 0xC377, 0x701D, 0xC378, 0x7015, 0xC379, 0x7018, 0xC37A, 0x7206, 0xC37B, 0x720D, - 0xC37C, 0x7258, 0xC37D, 0x72A2, 0xC37E, 0x7378, 0xC3A1, 0x737A, 0xC3A2, 0x74BD, 0xC3A3, 0x74CA, 0xC3A4, 0x74E3, 0xC3A5, 0x7587, - 0xC3A6, 0x7586, 0xC3A7, 0x765F, 0xC3A8, 0x7661, 0xC3A9, 0x77C7, 0xC3AA, 0x7919, 0xC3AB, 0x79B1, 0xC3AC, 0x7A6B, 0xC3AD, 0x7A69, - 0xC3AE, 0x7C3E, 0xC3AF, 0x7C3F, 0xC3B0, 0x7C38, 0xC3B1, 0x7C3D, 0xC3B2, 0x7C37, 0xC3B3, 0x7C40, 0xC3B4, 0x7E6B, 0xC3B5, 0x7E6D, - 0xC3B6, 0x7E79, 0xC3B7, 0x7E69, 0xC3B8, 0x7E6A, 0xC3B9, 0x7F85, 0xC3BA, 0x7E73, 0xC3BB, 0x7FB6, 0xC3BC, 0x7FB9, 0xC3BD, 0x7FB8, - 0xC3BE, 0x81D8, 0xC3BF, 0x85E9, 0xC3C0, 0x85DD, 0xC3C1, 0x85EA, 0xC3C2, 0x85D5, 0xC3C3, 0x85E4, 0xC3C4, 0x85E5, 0xC3C5, 0x85F7, - 0xC3C6, 0x87FB, 0xC3C7, 0x8805, 0xC3C8, 0x880D, 0xC3C9, 0x87F9, 0xC3CA, 0x87FE, 0xC3CB, 0x8960, 0xC3CC, 0x895F, 0xC3CD, 0x8956, - 0xC3CE, 0x895E, 0xC3CF, 0x8B41, 0xC3D0, 0x8B5C, 0xC3D1, 0x8B58, 0xC3D2, 0x8B49, 0xC3D3, 0x8B5A, 0xC3D4, 0x8B4E, 0xC3D5, 0x8B4F, - 0xC3D6, 0x8B46, 0xC3D7, 0x8B59, 0xC3D8, 0x8D08, 0xC3D9, 0x8D0A, 0xC3DA, 0x8E7C, 0xC3DB, 0x8E72, 0xC3DC, 0x8E87, 0xC3DD, 0x8E76, - 0xC3DE, 0x8E6C, 0xC3DF, 0x8E7A, 0xC3E0, 0x8E74, 0xC3E1, 0x8F54, 0xC3E2, 0x8F4E, 0xC3E3, 0x8FAD, 0xC3E4, 0x908A, 0xC3E5, 0x908B, - 0xC3E6, 0x91B1, 0xC3E7, 0x91AE, 0xC3E8, 0x93E1, 0xC3E9, 0x93D1, 0xC3EA, 0x93DF, 0xC3EB, 0x93C3, 0xC3EC, 0x93C8, 0xC3ED, 0x93DC, - 0xC3EE, 0x93DD, 0xC3EF, 0x93D6, 0xC3F0, 0x93E2, 0xC3F1, 0x93CD, 0xC3F2, 0x93D8, 0xC3F3, 0x93E4, 0xC3F4, 0x93D7, 0xC3F5, 0x93E8, - 0xC3F6, 0x95DC, 0xC3F7, 0x96B4, 0xC3F8, 0x96E3, 0xC3F9, 0x972A, 0xC3FA, 0x9727, 0xC3FB, 0x9761, 0xC3FC, 0x97DC, 0xC3FD, 0x97FB, - 0xC3FE, 0x985E, 0xC440, 0x9858, 0xC441, 0x985B, 0xC442, 0x98BC, 0xC443, 0x9945, 0xC444, 0x9949, 0xC445, 0x9A16, 0xC446, 0x9A19, - 0xC447, 0x9B0D, 0xC448, 0x9BE8, 0xC449, 0x9BE7, 0xC44A, 0x9BD6, 0xC44B, 0x9BDB, 0xC44C, 0x9D89, 0xC44D, 0x9D61, 0xC44E, 0x9D72, - 0xC44F, 0x9D6A, 0xC450, 0x9D6C, 0xC451, 0x9E92, 0xC452, 0x9E97, 0xC453, 0x9E93, 0xC454, 0x9EB4, 0xC455, 0x52F8, 0xC456, 0x56A8, - 0xC457, 0x56B7, 0xC458, 0x56B6, 0xC459, 0x56B4, 0xC45A, 0x56BC, 0xC45B, 0x58E4, 0xC45C, 0x5B40, 0xC45D, 0x5B43, 0xC45E, 0x5B7D, - 0xC45F, 0x5BF6, 0xC460, 0x5DC9, 0xC461, 0x61F8, 0xC462, 0x61FA, 0xC463, 0x6518, 0xC464, 0x6514, 0xC465, 0x6519, 0xC466, 0x66E6, - 0xC467, 0x6727, 0xC468, 0x6AEC, 0xC469, 0x703E, 0xC46A, 0x7030, 0xC46B, 0x7032, 0xC46C, 0x7210, 0xC46D, 0x737B, 0xC46E, 0x74CF, - 0xC46F, 0x7662, 0xC470, 0x7665, 0xC471, 0x7926, 0xC472, 0x792A, 0xC473, 0x792C, 0xC474, 0x792B, 0xC475, 0x7AC7, 0xC476, 0x7AF6, - 0xC477, 0x7C4C, 0xC478, 0x7C43, 0xC479, 0x7C4D, 0xC47A, 0x7CEF, 0xC47B, 0x7CF0, 0xC47C, 0x8FAE, 0xC47D, 0x7E7D, 0xC47E, 0x7E7C, - 0xC4A1, 0x7E82, 0xC4A2, 0x7F4C, 0xC4A3, 0x8000, 0xC4A4, 0x81DA, 0xC4A5, 0x8266, 0xC4A6, 0x85FB, 0xC4A7, 0x85F9, 0xC4A8, 0x8611, - 0xC4A9, 0x85FA, 0xC4AA, 0x8606, 0xC4AB, 0x860B, 0xC4AC, 0x8607, 0xC4AD, 0x860A, 0xC4AE, 0x8814, 0xC4AF, 0x8815, 0xC4B0, 0x8964, - 0xC4B1, 0x89BA, 0xC4B2, 0x89F8, 0xC4B3, 0x8B70, 0xC4B4, 0x8B6C, 0xC4B5, 0x8B66, 0xC4B6, 0x8B6F, 0xC4B7, 0x8B5F, 0xC4B8, 0x8B6B, - 0xC4B9, 0x8D0F, 0xC4BA, 0x8D0D, 0xC4BB, 0x8E89, 0xC4BC, 0x8E81, 0xC4BD, 0x8E85, 0xC4BE, 0x8E82, 0xC4BF, 0x91B4, 0xC4C0, 0x91CB, - 0xC4C1, 0x9418, 0xC4C2, 0x9403, 0xC4C3, 0x93FD, 0xC4C4, 0x95E1, 0xC4C5, 0x9730, 0xC4C6, 0x98C4, 0xC4C7, 0x9952, 0xC4C8, 0x9951, - 0xC4C9, 0x99A8, 0xC4CA, 0x9A2B, 0xC4CB, 0x9A30, 0xC4CC, 0x9A37, 0xC4CD, 0x9A35, 0xC4CE, 0x9C13, 0xC4CF, 0x9C0D, 0xC4D0, 0x9E79, - 0xC4D1, 0x9EB5, 0xC4D2, 0x9EE8, 0xC4D3, 0x9F2F, 0xC4D4, 0x9F5F, 0xC4D5, 0x9F63, 0xC4D6, 0x9F61, 0xC4D7, 0x5137, 0xC4D8, 0x5138, - 0xC4D9, 0x56C1, 0xC4DA, 0x56C0, 0xC4DB, 0x56C2, 0xC4DC, 0x5914, 0xC4DD, 0x5C6C, 0xC4DE, 0x5DCD, 0xC4DF, 0x61FC, 0xC4E0, 0x61FE, - 0xC4E1, 0x651D, 0xC4E2, 0x651C, 0xC4E3, 0x6595, 0xC4E4, 0x66E9, 0xC4E5, 0x6AFB, 0xC4E6, 0x6B04, 0xC4E7, 0x6AFA, 0xC4E8, 0x6BB2, - 0xC4E9, 0x704C, 0xC4EA, 0x721B, 0xC4EB, 0x72A7, 0xC4EC, 0x74D6, 0xC4ED, 0x74D4, 0xC4EE, 0x7669, 0xC4EF, 0x77D3, 0xC4F0, 0x7C50, - 0xC4F1, 0x7E8F, 0xC4F2, 0x7E8C, 0xC4F3, 0x7FBC, 0xC4F4, 0x8617, 0xC4F5, 0x862D, 0xC4F6, 0x861A, 0xC4F7, 0x8823, 0xC4F8, 0x8822, - 0xC4F9, 0x8821, 0xC4FA, 0x881F, 0xC4FB, 0x896A, 0xC4FC, 0x896C, 0xC4FD, 0x89BD, 0xC4FE, 0x8B74, 0xC540, 0x8B77, 0xC541, 0x8B7D, - 0xC542, 0x8D13, 0xC543, 0x8E8A, 0xC544, 0x8E8D, 0xC545, 0x8E8B, 0xC546, 0x8F5F, 0xC547, 0x8FAF, 0xC548, 0x91BA, 0xC549, 0x942E, - 0xC54A, 0x9433, 0xC54B, 0x9435, 0xC54C, 0x943A, 0xC54D, 0x9438, 0xC54E, 0x9432, 0xC54F, 0x942B, 0xC550, 0x95E2, 0xC551, 0x9738, - 0xC552, 0x9739, 0xC553, 0x9732, 0xC554, 0x97FF, 0xC555, 0x9867, 0xC556, 0x9865, 0xC557, 0x9957, 0xC558, 0x9A45, 0xC559, 0x9A43, - 0xC55A, 0x9A40, 0xC55B, 0x9A3E, 0xC55C, 0x9ACF, 0xC55D, 0x9B54, 0xC55E, 0x9B51, 0xC55F, 0x9C2D, 0xC560, 0x9C25, 0xC561, 0x9DAF, - 0xC562, 0x9DB4, 0xC563, 0x9DC2, 0xC564, 0x9DB8, 0xC565, 0x9E9D, 0xC566, 0x9EEF, 0xC567, 0x9F19, 0xC568, 0x9F5C, 0xC569, 0x9F66, - 0xC56A, 0x9F67, 0xC56B, 0x513C, 0xC56C, 0x513B, 0xC56D, 0x56C8, 0xC56E, 0x56CA, 0xC56F, 0x56C9, 0xC570, 0x5B7F, 0xC571, 0x5DD4, - 0xC572, 0x5DD2, 0xC573, 0x5F4E, 0xC574, 0x61FF, 0xC575, 0x6524, 0xC576, 0x6B0A, 0xC577, 0x6B61, 0xC578, 0x7051, 0xC579, 0x7058, - 0xC57A, 0x7380, 0xC57B, 0x74E4, 0xC57C, 0x758A, 0xC57D, 0x766E, 0xC57E, 0x766C, 0xC5A1, 0x79B3, 0xC5A2, 0x7C60, 0xC5A3, 0x7C5F, - 0xC5A4, 0x807E, 0xC5A5, 0x807D, 0xC5A6, 0x81DF, 0xC5A7, 0x8972, 0xC5A8, 0x896F, 0xC5A9, 0x89FC, 0xC5AA, 0x8B80, 0xC5AB, 0x8D16, - 0xC5AC, 0x8D17, 0xC5AD, 0x8E91, 0xC5AE, 0x8E93, 0xC5AF, 0x8F61, 0xC5B0, 0x9148, 0xC5B1, 0x9444, 0xC5B2, 0x9451, 0xC5B3, 0x9452, - 0xC5B4, 0x973D, 0xC5B5, 0x973E, 0xC5B6, 0x97C3, 0xC5B7, 0x97C1, 0xC5B8, 0x986B, 0xC5B9, 0x9955, 0xC5BA, 0x9A55, 0xC5BB, 0x9A4D, - 0xC5BC, 0x9AD2, 0xC5BD, 0x9B1A, 0xC5BE, 0x9C49, 0xC5BF, 0x9C31, 0xC5C0, 0x9C3E, 0xC5C1, 0x9C3B, 0xC5C2, 0x9DD3, 0xC5C3, 0x9DD7, - 0xC5C4, 0x9F34, 0xC5C5, 0x9F6C, 0xC5C6, 0x9F6A, 0xC5C7, 0x9F94, 0xC5C8, 0x56CC, 0xC5C9, 0x5DD6, 0xC5CA, 0x6200, 0xC5CB, 0x6523, - 0xC5CC, 0x652B, 0xC5CD, 0x652A, 0xC5CE, 0x66EC, 0xC5CF, 0x6B10, 0xC5D0, 0x74DA, 0xC5D1, 0x7ACA, 0xC5D2, 0x7C64, 0xC5D3, 0x7C63, - 0xC5D4, 0x7C65, 0xC5D5, 0x7E93, 0xC5D6, 0x7E96, 0xC5D7, 0x7E94, 0xC5D8, 0x81E2, 0xC5D9, 0x8638, 0xC5DA, 0x863F, 0xC5DB, 0x8831, - 0xC5DC, 0x8B8A, 0xC5DD, 0x9090, 0xC5DE, 0x908F, 0xC5DF, 0x9463, 0xC5E0, 0x9460, 0xC5E1, 0x9464, 0xC5E2, 0x9768, 0xC5E3, 0x986F, - 0xC5E4, 0x995C, 0xC5E5, 0x9A5A, 0xC5E6, 0x9A5B, 0xC5E7, 0x9A57, 0xC5E8, 0x9AD3, 0xC5E9, 0x9AD4, 0xC5EA, 0x9AD1, 0xC5EB, 0x9C54, - 0xC5EC, 0x9C57, 0xC5ED, 0x9C56, 0xC5EE, 0x9DE5, 0xC5EF, 0x9E9F, 0xC5F0, 0x9EF4, 0xC5F1, 0x56D1, 0xC5F2, 0x58E9, 0xC5F3, 0x652C, - 0xC5F4, 0x705E, 0xC5F5, 0x7671, 0xC5F6, 0x7672, 0xC5F7, 0x77D7, 0xC5F8, 0x7F50, 0xC5F9, 0x7F88, 0xC5FA, 0x8836, 0xC5FB, 0x8839, - 0xC5FC, 0x8862, 0xC5FD, 0x8B93, 0xC5FE, 0x8B92, 0xC640, 0x8B96, 0xC641, 0x8277, 0xC642, 0x8D1B, 0xC643, 0x91C0, 0xC644, 0x946A, - 0xC645, 0x9742, 0xC646, 0x9748, 0xC647, 0x9744, 0xC648, 0x97C6, 0xC649, 0x9870, 0xC64A, 0x9A5F, 0xC64B, 0x9B22, 0xC64C, 0x9B58, - 0xC64D, 0x9C5F, 0xC64E, 0x9DF9, 0xC64F, 0x9DFA, 0xC650, 0x9E7C, 0xC651, 0x9E7D, 0xC652, 0x9F07, 0xC653, 0x9F77, 0xC654, 0x9F72, - 0xC655, 0x5EF3, 0xC656, 0x6B16, 0xC657, 0x7063, 0xC658, 0x7C6C, 0xC659, 0x7C6E, 0xC65A, 0x883B, 0xC65B, 0x89C0, 0xC65C, 0x8EA1, - 0xC65D, 0x91C1, 0xC65E, 0x9472, 0xC65F, 0x9470, 0xC660, 0x9871, 0xC661, 0x995E, 0xC662, 0x9AD6, 0xC663, 0x9B23, 0xC664, 0x9ECC, - 0xC665, 0x7064, 0xC666, 0x77DA, 0xC667, 0x8B9A, 0xC668, 0x9477, 0xC669, 0x97C9, 0xC66A, 0x9A62, 0xC66B, 0x9A65, 0xC66C, 0x7E9C, - 0xC66D, 0x8B9C, 0xC66E, 0x8EAA, 0xC66F, 0x91C5, 0xC670, 0x947D, 0xC671, 0x947E, 0xC672, 0x947C, 0xC673, 0x9C77, 0xC674, 0x9C78, - 0xC675, 0x9EF7, 0xC676, 0x8C54, 0xC677, 0x947F, 0xC678, 0x9E1A, 0xC679, 0x7228, 0xC67A, 0x9A6A, 0xC67B, 0x9B31, 0xC67C, 0x9E1B, - 0xC67D, 0x9E1E, 0xC67E, 0x7C72, 0xC940, 0x4E42, 0xC941, 0x4E5C, 0xC942, 0x51F5, 0xC943, 0x531A, 0xC944, 0x5382, 0xC945, 0x4E07, - 0xC946, 0x4E0C, 0xC947, 0x4E47, 0xC948, 0x4E8D, 0xC949, 0x56D7, 0xC94A, 0xFA0C, 0xC94B, 0x5C6E, 0xC94C, 0x5F73, 0xC94D, 0x4E0F, - 0xC94E, 0x5187, 0xC94F, 0x4E0E, 0xC950, 0x4E2E, 0xC951, 0x4E93, 0xC952, 0x4EC2, 0xC953, 0x4EC9, 0xC954, 0x4EC8, 0xC955, 0x5198, - 0xC956, 0x52FC, 0xC957, 0x536C, 0xC958, 0x53B9, 0xC959, 0x5720, 0xC95A, 0x5903, 0xC95B, 0x592C, 0xC95C, 0x5C10, 0xC95D, 0x5DFF, - 0xC95E, 0x65E1, 0xC95F, 0x6BB3, 0xC960, 0x6BCC, 0xC961, 0x6C14, 0xC962, 0x723F, 0xC963, 0x4E31, 0xC964, 0x4E3C, 0xC965, 0x4EE8, - 0xC966, 0x4EDC, 0xC967, 0x4EE9, 0xC968, 0x4EE1, 0xC969, 0x4EDD, 0xC96A, 0x4EDA, 0xC96B, 0x520C, 0xC96C, 0x531C, 0xC96D, 0x534C, - 0xC96E, 0x5722, 0xC96F, 0x5723, 0xC970, 0x5917, 0xC971, 0x592F, 0xC972, 0x5B81, 0xC973, 0x5B84, 0xC974, 0x5C12, 0xC975, 0x5C3B, - 0xC976, 0x5C74, 0xC977, 0x5C73, 0xC978, 0x5E04, 0xC979, 0x5E80, 0xC97A, 0x5E82, 0xC97B, 0x5FC9, 0xC97C, 0x6209, 0xC97D, 0x6250, - 0xC97E, 0x6C15, 0xC9A1, 0x6C36, 0xC9A2, 0x6C43, 0xC9A3, 0x6C3F, 0xC9A4, 0x6C3B, 0xC9A5, 0x72AE, 0xC9A6, 0x72B0, 0xC9A7, 0x738A, - 0xC9A8, 0x79B8, 0xC9A9, 0x808A, 0xC9AA, 0x961E, 0xC9AB, 0x4F0E, 0xC9AC, 0x4F18, 0xC9AD, 0x4F2C, 0xC9AE, 0x4EF5, 0xC9AF, 0x4F14, - 0xC9B0, 0x4EF1, 0xC9B1, 0x4F00, 0xC9B2, 0x4EF7, 0xC9B3, 0x4F08, 0xC9B4, 0x4F1D, 0xC9B5, 0x4F02, 0xC9B6, 0x4F05, 0xC9B7, 0x4F22, - 0xC9B8, 0x4F13, 0xC9B9, 0x4F04, 0xC9BA, 0x4EF4, 0xC9BB, 0x4F12, 0xC9BC, 0x51B1, 0xC9BD, 0x5213, 0xC9BE, 0x5209, 0xC9BF, 0x5210, - 0xC9C0, 0x52A6, 0xC9C1, 0x5322, 0xC9C2, 0x531F, 0xC9C3, 0x534D, 0xC9C4, 0x538A, 0xC9C5, 0x5407, 0xC9C6, 0x56E1, 0xC9C7, 0x56DF, - 0xC9C8, 0x572E, 0xC9C9, 0x572A, 0xC9CA, 0x5734, 0xC9CB, 0x593C, 0xC9CC, 0x5980, 0xC9CD, 0x597C, 0xC9CE, 0x5985, 0xC9CF, 0x597B, - 0xC9D0, 0x597E, 0xC9D1, 0x5977, 0xC9D2, 0x597F, 0xC9D3, 0x5B56, 0xC9D4, 0x5C15, 0xC9D5, 0x5C25, 0xC9D6, 0x5C7C, 0xC9D7, 0x5C7A, - 0xC9D8, 0x5C7B, 0xC9D9, 0x5C7E, 0xC9DA, 0x5DDF, 0xC9DB, 0x5E75, 0xC9DC, 0x5E84, 0xC9DD, 0x5F02, 0xC9DE, 0x5F1A, 0xC9DF, 0x5F74, - 0xC9E0, 0x5FD5, 0xC9E1, 0x5FD4, 0xC9E2, 0x5FCF, 0xC9E3, 0x625C, 0xC9E4, 0x625E, 0xC9E5, 0x6264, 0xC9E6, 0x6261, 0xC9E7, 0x6266, - 0xC9E8, 0x6262, 0xC9E9, 0x6259, 0xC9EA, 0x6260, 0xC9EB, 0x625A, 0xC9EC, 0x6265, 0xC9ED, 0x65EF, 0xC9EE, 0x65EE, 0xC9EF, 0x673E, - 0xC9F0, 0x6739, 0xC9F1, 0x6738, 0xC9F2, 0x673B, 0xC9F3, 0x673A, 0xC9F4, 0x673F, 0xC9F5, 0x673C, 0xC9F6, 0x6733, 0xC9F7, 0x6C18, - 0xC9F8, 0x6C46, 0xC9F9, 0x6C52, 0xC9FA, 0x6C5C, 0xC9FB, 0x6C4F, 0xC9FC, 0x6C4A, 0xC9FD, 0x6C54, 0xC9FE, 0x6C4B, 0xCA40, 0x6C4C, - 0xCA41, 0x7071, 0xCA42, 0x725E, 0xCA43, 0x72B4, 0xCA44, 0x72B5, 0xCA45, 0x738E, 0xCA46, 0x752A, 0xCA47, 0x767F, 0xCA48, 0x7A75, - 0xCA49, 0x7F51, 0xCA4A, 0x8278, 0xCA4B, 0x827C, 0xCA4C, 0x8280, 0xCA4D, 0x827D, 0xCA4E, 0x827F, 0xCA4F, 0x864D, 0xCA50, 0x897E, - 0xCA51, 0x9099, 0xCA52, 0x9097, 0xCA53, 0x9098, 0xCA54, 0x909B, 0xCA55, 0x9094, 0xCA56, 0x9622, 0xCA57, 0x9624, 0xCA58, 0x9620, - 0xCA59, 0x9623, 0xCA5A, 0x4F56, 0xCA5B, 0x4F3B, 0xCA5C, 0x4F62, 0xCA5D, 0x4F49, 0xCA5E, 0x4F53, 0xCA5F, 0x4F64, 0xCA60, 0x4F3E, - 0xCA61, 0x4F67, 0xCA62, 0x4F52, 0xCA63, 0x4F5F, 0xCA64, 0x4F41, 0xCA65, 0x4F58, 0xCA66, 0x4F2D, 0xCA67, 0x4F33, 0xCA68, 0x4F3F, - 0xCA69, 0x4F61, 0xCA6A, 0x518F, 0xCA6B, 0x51B9, 0xCA6C, 0x521C, 0xCA6D, 0x521E, 0xCA6E, 0x5221, 0xCA6F, 0x52AD, 0xCA70, 0x52AE, - 0xCA71, 0x5309, 0xCA72, 0x5363, 0xCA73, 0x5372, 0xCA74, 0x538E, 0xCA75, 0x538F, 0xCA76, 0x5430, 0xCA77, 0x5437, 0xCA78, 0x542A, - 0xCA79, 0x5454, 0xCA7A, 0x5445, 0xCA7B, 0x5419, 0xCA7C, 0x541C, 0xCA7D, 0x5425, 0xCA7E, 0x5418, 0xCAA1, 0x543D, 0xCAA2, 0x544F, - 0xCAA3, 0x5441, 0xCAA4, 0x5428, 0xCAA5, 0x5424, 0xCAA6, 0x5447, 0xCAA7, 0x56EE, 0xCAA8, 0x56E7, 0xCAA9, 0x56E5, 0xCAAA, 0x5741, - 0xCAAB, 0x5745, 0xCAAC, 0x574C, 0xCAAD, 0x5749, 0xCAAE, 0x574B, 0xCAAF, 0x5752, 0xCAB0, 0x5906, 0xCAB1, 0x5940, 0xCAB2, 0x59A6, - 0xCAB3, 0x5998, 0xCAB4, 0x59A0, 0xCAB5, 0x5997, 0xCAB6, 0x598E, 0xCAB7, 0x59A2, 0xCAB8, 0x5990, 0xCAB9, 0x598F, 0xCABA, 0x59A7, - 0xCABB, 0x59A1, 0xCABC, 0x5B8E, 0xCABD, 0x5B92, 0xCABE, 0x5C28, 0xCABF, 0x5C2A, 0xCAC0, 0x5C8D, 0xCAC1, 0x5C8F, 0xCAC2, 0x5C88, - 0xCAC3, 0x5C8B, 0xCAC4, 0x5C89, 0xCAC5, 0x5C92, 0xCAC6, 0x5C8A, 0xCAC7, 0x5C86, 0xCAC8, 0x5C93, 0xCAC9, 0x5C95, 0xCACA, 0x5DE0, - 0xCACB, 0x5E0A, 0xCACC, 0x5E0E, 0xCACD, 0x5E8B, 0xCACE, 0x5E89, 0xCACF, 0x5E8C, 0xCAD0, 0x5E88, 0xCAD1, 0x5E8D, 0xCAD2, 0x5F05, - 0xCAD3, 0x5F1D, 0xCAD4, 0x5F78, 0xCAD5, 0x5F76, 0xCAD6, 0x5FD2, 0xCAD7, 0x5FD1, 0xCAD8, 0x5FD0, 0xCAD9, 0x5FED, 0xCADA, 0x5FE8, - 0xCADB, 0x5FEE, 0xCADC, 0x5FF3, 0xCADD, 0x5FE1, 0xCADE, 0x5FE4, 0xCADF, 0x5FE3, 0xCAE0, 0x5FFA, 0xCAE1, 0x5FEF, 0xCAE2, 0x5FF7, - 0xCAE3, 0x5FFB, 0xCAE4, 0x6000, 0xCAE5, 0x5FF4, 0xCAE6, 0x623A, 0xCAE7, 0x6283, 0xCAE8, 0x628C, 0xCAE9, 0x628E, 0xCAEA, 0x628F, - 0xCAEB, 0x6294, 0xCAEC, 0x6287, 0xCAED, 0x6271, 0xCAEE, 0x627B, 0xCAEF, 0x627A, 0xCAF0, 0x6270, 0xCAF1, 0x6281, 0xCAF2, 0x6288, - 0xCAF3, 0x6277, 0xCAF4, 0x627D, 0xCAF5, 0x6272, 0xCAF6, 0x6274, 0xCAF7, 0x6537, 0xCAF8, 0x65F0, 0xCAF9, 0x65F4, 0xCAFA, 0x65F3, - 0xCAFB, 0x65F2, 0xCAFC, 0x65F5, 0xCAFD, 0x6745, 0xCAFE, 0x6747, 0xCB40, 0x6759, 0xCB41, 0x6755, 0xCB42, 0x674C, 0xCB43, 0x6748, - 0xCB44, 0x675D, 0xCB45, 0x674D, 0xCB46, 0x675A, 0xCB47, 0x674B, 0xCB48, 0x6BD0, 0xCB49, 0x6C19, 0xCB4A, 0x6C1A, 0xCB4B, 0x6C78, - 0xCB4C, 0x6C67, 0xCB4D, 0x6C6B, 0xCB4E, 0x6C84, 0xCB4F, 0x6C8B, 0xCB50, 0x6C8F, 0xCB51, 0x6C71, 0xCB52, 0x6C6F, 0xCB53, 0x6C69, - 0xCB54, 0x6C9A, 0xCB55, 0x6C6D, 0xCB56, 0x6C87, 0xCB57, 0x6C95, 0xCB58, 0x6C9C, 0xCB59, 0x6C66, 0xCB5A, 0x6C73, 0xCB5B, 0x6C65, - 0xCB5C, 0x6C7B, 0xCB5D, 0x6C8E, 0xCB5E, 0x7074, 0xCB5F, 0x707A, 0xCB60, 0x7263, 0xCB61, 0x72BF, 0xCB62, 0x72BD, 0xCB63, 0x72C3, - 0xCB64, 0x72C6, 0xCB65, 0x72C1, 0xCB66, 0x72BA, 0xCB67, 0x72C5, 0xCB68, 0x7395, 0xCB69, 0x7397, 0xCB6A, 0x7393, 0xCB6B, 0x7394, - 0xCB6C, 0x7392, 0xCB6D, 0x753A, 0xCB6E, 0x7539, 0xCB6F, 0x7594, 0xCB70, 0x7595, 0xCB71, 0x7681, 0xCB72, 0x793D, 0xCB73, 0x8034, - 0xCB74, 0x8095, 0xCB75, 0x8099, 0xCB76, 0x8090, 0xCB77, 0x8092, 0xCB78, 0x809C, 0xCB79, 0x8290, 0xCB7A, 0x828F, 0xCB7B, 0x8285, - 0xCB7C, 0x828E, 0xCB7D, 0x8291, 0xCB7E, 0x8293, 0xCBA1, 0x828A, 0xCBA2, 0x8283, 0xCBA3, 0x8284, 0xCBA4, 0x8C78, 0xCBA5, 0x8FC9, - 0xCBA6, 0x8FBF, 0xCBA7, 0x909F, 0xCBA8, 0x90A1, 0xCBA9, 0x90A5, 0xCBAA, 0x909E, 0xCBAB, 0x90A7, 0xCBAC, 0x90A0, 0xCBAD, 0x9630, - 0xCBAE, 0x9628, 0xCBAF, 0x962F, 0xCBB0, 0x962D, 0xCBB1, 0x4E33, 0xCBB2, 0x4F98, 0xCBB3, 0x4F7C, 0xCBB4, 0x4F85, 0xCBB5, 0x4F7D, - 0xCBB6, 0x4F80, 0xCBB7, 0x4F87, 0xCBB8, 0x4F76, 0xCBB9, 0x4F74, 0xCBBA, 0x4F89, 0xCBBB, 0x4F84, 0xCBBC, 0x4F77, 0xCBBD, 0x4F4C, - 0xCBBE, 0x4F97, 0xCBBF, 0x4F6A, 0xCBC0, 0x4F9A, 0xCBC1, 0x4F79, 0xCBC2, 0x4F81, 0xCBC3, 0x4F78, 0xCBC4, 0x4F90, 0xCBC5, 0x4F9C, - 0xCBC6, 0x4F94, 0xCBC7, 0x4F9E, 0xCBC8, 0x4F92, 0xCBC9, 0x4F82, 0xCBCA, 0x4F95, 0xCBCB, 0x4F6B, 0xCBCC, 0x4F6E, 0xCBCD, 0x519E, - 0xCBCE, 0x51BC, 0xCBCF, 0x51BE, 0xCBD0, 0x5235, 0xCBD1, 0x5232, 0xCBD2, 0x5233, 0xCBD3, 0x5246, 0xCBD4, 0x5231, 0xCBD5, 0x52BC, - 0xCBD6, 0x530A, 0xCBD7, 0x530B, 0xCBD8, 0x533C, 0xCBD9, 0x5392, 0xCBDA, 0x5394, 0xCBDB, 0x5487, 0xCBDC, 0x547F, 0xCBDD, 0x5481, - 0xCBDE, 0x5491, 0xCBDF, 0x5482, 0xCBE0, 0x5488, 0xCBE1, 0x546B, 0xCBE2, 0x547A, 0xCBE3, 0x547E, 0xCBE4, 0x5465, 0xCBE5, 0x546C, - 0xCBE6, 0x5474, 0xCBE7, 0x5466, 0xCBE8, 0x548D, 0xCBE9, 0x546F, 0xCBEA, 0x5461, 0xCBEB, 0x5460, 0xCBEC, 0x5498, 0xCBED, 0x5463, - 0xCBEE, 0x5467, 0xCBEF, 0x5464, 0xCBF0, 0x56F7, 0xCBF1, 0x56F9, 0xCBF2, 0x576F, 0xCBF3, 0x5772, 0xCBF4, 0x576D, 0xCBF5, 0x576B, - 0xCBF6, 0x5771, 0xCBF7, 0x5770, 0xCBF8, 0x5776, 0xCBF9, 0x5780, 0xCBFA, 0x5775, 0xCBFB, 0x577B, 0xCBFC, 0x5773, 0xCBFD, 0x5774, - 0xCBFE, 0x5762, 0xCC40, 0x5768, 0xCC41, 0x577D, 0xCC42, 0x590C, 0xCC43, 0x5945, 0xCC44, 0x59B5, 0xCC45, 0x59BA, 0xCC46, 0x59CF, - 0xCC47, 0x59CE, 0xCC48, 0x59B2, 0xCC49, 0x59CC, 0xCC4A, 0x59C1, 0xCC4B, 0x59B6, 0xCC4C, 0x59BC, 0xCC4D, 0x59C3, 0xCC4E, 0x59D6, - 0xCC4F, 0x59B1, 0xCC50, 0x59BD, 0xCC51, 0x59C0, 0xCC52, 0x59C8, 0xCC53, 0x59B4, 0xCC54, 0x59C7, 0xCC55, 0x5B62, 0xCC56, 0x5B65, - 0xCC57, 0x5B93, 0xCC58, 0x5B95, 0xCC59, 0x5C44, 0xCC5A, 0x5C47, 0xCC5B, 0x5CAE, 0xCC5C, 0x5CA4, 0xCC5D, 0x5CA0, 0xCC5E, 0x5CB5, - 0xCC5F, 0x5CAF, 0xCC60, 0x5CA8, 0xCC61, 0x5CAC, 0xCC62, 0x5C9F, 0xCC63, 0x5CA3, 0xCC64, 0x5CAD, 0xCC65, 0x5CA2, 0xCC66, 0x5CAA, - 0xCC67, 0x5CA7, 0xCC68, 0x5C9D, 0xCC69, 0x5CA5, 0xCC6A, 0x5CB6, 0xCC6B, 0x5CB0, 0xCC6C, 0x5CA6, 0xCC6D, 0x5E17, 0xCC6E, 0x5E14, - 0xCC6F, 0x5E19, 0xCC70, 0x5F28, 0xCC71, 0x5F22, 0xCC72, 0x5F23, 0xCC73, 0x5F24, 0xCC74, 0x5F54, 0xCC75, 0x5F82, 0xCC76, 0x5F7E, - 0xCC77, 0x5F7D, 0xCC78, 0x5FDE, 0xCC79, 0x5FE5, 0xCC7A, 0x602D, 0xCC7B, 0x6026, 0xCC7C, 0x6019, 0xCC7D, 0x6032, 0xCC7E, 0x600B, - 0xCCA1, 0x6034, 0xCCA2, 0x600A, 0xCCA3, 0x6017, 0xCCA4, 0x6033, 0xCCA5, 0x601A, 0xCCA6, 0x601E, 0xCCA7, 0x602C, 0xCCA8, 0x6022, - 0xCCA9, 0x600D, 0xCCAA, 0x6010, 0xCCAB, 0x602E, 0xCCAC, 0x6013, 0xCCAD, 0x6011, 0xCCAE, 0x600C, 0xCCAF, 0x6009, 0xCCB0, 0x601C, - 0xCCB1, 0x6214, 0xCCB2, 0x623D, 0xCCB3, 0x62AD, 0xCCB4, 0x62B4, 0xCCB5, 0x62D1, 0xCCB6, 0x62BE, 0xCCB7, 0x62AA, 0xCCB8, 0x62B6, - 0xCCB9, 0x62CA, 0xCCBA, 0x62AE, 0xCCBB, 0x62B3, 0xCCBC, 0x62AF, 0xCCBD, 0x62BB, 0xCCBE, 0x62A9, 0xCCBF, 0x62B0, 0xCCC0, 0x62B8, - 0xCCC1, 0x653D, 0xCCC2, 0x65A8, 0xCCC3, 0x65BB, 0xCCC4, 0x6609, 0xCCC5, 0x65FC, 0xCCC6, 0x6604, 0xCCC7, 0x6612, 0xCCC8, 0x6608, - 0xCCC9, 0x65FB, 0xCCCA, 0x6603, 0xCCCB, 0x660B, 0xCCCC, 0x660D, 0xCCCD, 0x6605, 0xCCCE, 0x65FD, 0xCCCF, 0x6611, 0xCCD0, 0x6610, - 0xCCD1, 0x66F6, 0xCCD2, 0x670A, 0xCCD3, 0x6785, 0xCCD4, 0x676C, 0xCCD5, 0x678E, 0xCCD6, 0x6792, 0xCCD7, 0x6776, 0xCCD8, 0x677B, - 0xCCD9, 0x6798, 0xCCDA, 0x6786, 0xCCDB, 0x6784, 0xCCDC, 0x6774, 0xCCDD, 0x678D, 0xCCDE, 0x678C, 0xCCDF, 0x677A, 0xCCE0, 0x679F, - 0xCCE1, 0x6791, 0xCCE2, 0x6799, 0xCCE3, 0x6783, 0xCCE4, 0x677D, 0xCCE5, 0x6781, 0xCCE6, 0x6778, 0xCCE7, 0x6779, 0xCCE8, 0x6794, - 0xCCE9, 0x6B25, 0xCCEA, 0x6B80, 0xCCEB, 0x6B7E, 0xCCEC, 0x6BDE, 0xCCED, 0x6C1D, 0xCCEE, 0x6C93, 0xCCEF, 0x6CEC, 0xCCF0, 0x6CEB, - 0xCCF1, 0x6CEE, 0xCCF2, 0x6CD9, 0xCCF3, 0x6CB6, 0xCCF4, 0x6CD4, 0xCCF5, 0x6CAD, 0xCCF6, 0x6CE7, 0xCCF7, 0x6CB7, 0xCCF8, 0x6CD0, - 0xCCF9, 0x6CC2, 0xCCFA, 0x6CBA, 0xCCFB, 0x6CC3, 0xCCFC, 0x6CC6, 0xCCFD, 0x6CED, 0xCCFE, 0x6CF2, 0xCD40, 0x6CD2, 0xCD41, 0x6CDD, - 0xCD42, 0x6CB4, 0xCD43, 0x6C8A, 0xCD44, 0x6C9D, 0xCD45, 0x6C80, 0xCD46, 0x6CDE, 0xCD47, 0x6CC0, 0xCD48, 0x6D30, 0xCD49, 0x6CCD, - 0xCD4A, 0x6CC7, 0xCD4B, 0x6CB0, 0xCD4C, 0x6CF9, 0xCD4D, 0x6CCF, 0xCD4E, 0x6CE9, 0xCD4F, 0x6CD1, 0xCD50, 0x7094, 0xCD51, 0x7098, - 0xCD52, 0x7085, 0xCD53, 0x7093, 0xCD54, 0x7086, 0xCD55, 0x7084, 0xCD56, 0x7091, 0xCD57, 0x7096, 0xCD58, 0x7082, 0xCD59, 0x709A, - 0xCD5A, 0x7083, 0xCD5B, 0x726A, 0xCD5C, 0x72D6, 0xCD5D, 0x72CB, 0xCD5E, 0x72D8, 0xCD5F, 0x72C9, 0xCD60, 0x72DC, 0xCD61, 0x72D2, - 0xCD62, 0x72D4, 0xCD63, 0x72DA, 0xCD64, 0x72CC, 0xCD65, 0x72D1, 0xCD66, 0x73A4, 0xCD67, 0x73A1, 0xCD68, 0x73AD, 0xCD69, 0x73A6, - 0xCD6A, 0x73A2, 0xCD6B, 0x73A0, 0xCD6C, 0x73AC, 0xCD6D, 0x739D, 0xCD6E, 0x74DD, 0xCD6F, 0x74E8, 0xCD70, 0x753F, 0xCD71, 0x7540, - 0xCD72, 0x753E, 0xCD73, 0x758C, 0xCD74, 0x7598, 0xCD75, 0x76AF, 0xCD76, 0x76F3, 0xCD77, 0x76F1, 0xCD78, 0x76F0, 0xCD79, 0x76F5, - 0xCD7A, 0x77F8, 0xCD7B, 0x77FC, 0xCD7C, 0x77F9, 0xCD7D, 0x77FB, 0xCD7E, 0x77FA, 0xCDA1, 0x77F7, 0xCDA2, 0x7942, 0xCDA3, 0x793F, - 0xCDA4, 0x79C5, 0xCDA5, 0x7A78, 0xCDA6, 0x7A7B, 0xCDA7, 0x7AFB, 0xCDA8, 0x7C75, 0xCDA9, 0x7CFD, 0xCDAA, 0x8035, 0xCDAB, 0x808F, - 0xCDAC, 0x80AE, 0xCDAD, 0x80A3, 0xCDAE, 0x80B8, 0xCDAF, 0x80B5, 0xCDB0, 0x80AD, 0xCDB1, 0x8220, 0xCDB2, 0x82A0, 0xCDB3, 0x82C0, - 0xCDB4, 0x82AB, 0xCDB5, 0x829A, 0xCDB6, 0x8298, 0xCDB7, 0x829B, 0xCDB8, 0x82B5, 0xCDB9, 0x82A7, 0xCDBA, 0x82AE, 0xCDBB, 0x82BC, - 0xCDBC, 0x829E, 0xCDBD, 0x82BA, 0xCDBE, 0x82B4, 0xCDBF, 0x82A8, 0xCDC0, 0x82A1, 0xCDC1, 0x82A9, 0xCDC2, 0x82C2, 0xCDC3, 0x82A4, - 0xCDC4, 0x82C3, 0xCDC5, 0x82B6, 0xCDC6, 0x82A2, 0xCDC7, 0x8670, 0xCDC8, 0x866F, 0xCDC9, 0x866D, 0xCDCA, 0x866E, 0xCDCB, 0x8C56, - 0xCDCC, 0x8FD2, 0xCDCD, 0x8FCB, 0xCDCE, 0x8FD3, 0xCDCF, 0x8FCD, 0xCDD0, 0x8FD6, 0xCDD1, 0x8FD5, 0xCDD2, 0x8FD7, 0xCDD3, 0x90B2, - 0xCDD4, 0x90B4, 0xCDD5, 0x90AF, 0xCDD6, 0x90B3, 0xCDD7, 0x90B0, 0xCDD8, 0x9639, 0xCDD9, 0x963D, 0xCDDA, 0x963C, 0xCDDB, 0x963A, - 0xCDDC, 0x9643, 0xCDDD, 0x4FCD, 0xCDDE, 0x4FC5, 0xCDDF, 0x4FD3, 0xCDE0, 0x4FB2, 0xCDE1, 0x4FC9, 0xCDE2, 0x4FCB, 0xCDE3, 0x4FC1, - 0xCDE4, 0x4FD4, 0xCDE5, 0x4FDC, 0xCDE6, 0x4FD9, 0xCDE7, 0x4FBB, 0xCDE8, 0x4FB3, 0xCDE9, 0x4FDB, 0xCDEA, 0x4FC7, 0xCDEB, 0x4FD6, - 0xCDEC, 0x4FBA, 0xCDED, 0x4FC0, 0xCDEE, 0x4FB9, 0xCDEF, 0x4FEC, 0xCDF0, 0x5244, 0xCDF1, 0x5249, 0xCDF2, 0x52C0, 0xCDF3, 0x52C2, - 0xCDF4, 0x533D, 0xCDF5, 0x537C, 0xCDF6, 0x5397, 0xCDF7, 0x5396, 0xCDF8, 0x5399, 0xCDF9, 0x5398, 0xCDFA, 0x54BA, 0xCDFB, 0x54A1, - 0xCDFC, 0x54AD, 0xCDFD, 0x54A5, 0xCDFE, 0x54CF, 0xCE40, 0x54C3, 0xCE41, 0x830D, 0xCE42, 0x54B7, 0xCE43, 0x54AE, 0xCE44, 0x54D6, - 0xCE45, 0x54B6, 0xCE46, 0x54C5, 0xCE47, 0x54C6, 0xCE48, 0x54A0, 0xCE49, 0x5470, 0xCE4A, 0x54BC, 0xCE4B, 0x54A2, 0xCE4C, 0x54BE, - 0xCE4D, 0x5472, 0xCE4E, 0x54DE, 0xCE4F, 0x54B0, 0xCE50, 0x57B5, 0xCE51, 0x579E, 0xCE52, 0x579F, 0xCE53, 0x57A4, 0xCE54, 0x578C, - 0xCE55, 0x5797, 0xCE56, 0x579D, 0xCE57, 0x579B, 0xCE58, 0x5794, 0xCE59, 0x5798, 0xCE5A, 0x578F, 0xCE5B, 0x5799, 0xCE5C, 0x57A5, - 0xCE5D, 0x579A, 0xCE5E, 0x5795, 0xCE5F, 0x58F4, 0xCE60, 0x590D, 0xCE61, 0x5953, 0xCE62, 0x59E1, 0xCE63, 0x59DE, 0xCE64, 0x59EE, - 0xCE65, 0x5A00, 0xCE66, 0x59F1, 0xCE67, 0x59DD, 0xCE68, 0x59FA, 0xCE69, 0x59FD, 0xCE6A, 0x59FC, 0xCE6B, 0x59F6, 0xCE6C, 0x59E4, - 0xCE6D, 0x59F2, 0xCE6E, 0x59F7, 0xCE6F, 0x59DB, 0xCE70, 0x59E9, 0xCE71, 0x59F3, 0xCE72, 0x59F5, 0xCE73, 0x59E0, 0xCE74, 0x59FE, - 0xCE75, 0x59F4, 0xCE76, 0x59ED, 0xCE77, 0x5BA8, 0xCE78, 0x5C4C, 0xCE79, 0x5CD0, 0xCE7A, 0x5CD8, 0xCE7B, 0x5CCC, 0xCE7C, 0x5CD7, - 0xCE7D, 0x5CCB, 0xCE7E, 0x5CDB, 0xCEA1, 0x5CDE, 0xCEA2, 0x5CDA, 0xCEA3, 0x5CC9, 0xCEA4, 0x5CC7, 0xCEA5, 0x5CCA, 0xCEA6, 0x5CD6, - 0xCEA7, 0x5CD3, 0xCEA8, 0x5CD4, 0xCEA9, 0x5CCF, 0xCEAA, 0x5CC8, 0xCEAB, 0x5CC6, 0xCEAC, 0x5CCE, 0xCEAD, 0x5CDF, 0xCEAE, 0x5CF8, - 0xCEAF, 0x5DF9, 0xCEB0, 0x5E21, 0xCEB1, 0x5E22, 0xCEB2, 0x5E23, 0xCEB3, 0x5E20, 0xCEB4, 0x5E24, 0xCEB5, 0x5EB0, 0xCEB6, 0x5EA4, - 0xCEB7, 0x5EA2, 0xCEB8, 0x5E9B, 0xCEB9, 0x5EA3, 0xCEBA, 0x5EA5, 0xCEBB, 0x5F07, 0xCEBC, 0x5F2E, 0xCEBD, 0x5F56, 0xCEBE, 0x5F86, - 0xCEBF, 0x6037, 0xCEC0, 0x6039, 0xCEC1, 0x6054, 0xCEC2, 0x6072, 0xCEC3, 0x605E, 0xCEC4, 0x6045, 0xCEC5, 0x6053, 0xCEC6, 0x6047, - 0xCEC7, 0x6049, 0xCEC8, 0x605B, 0xCEC9, 0x604C, 0xCECA, 0x6040, 0xCECB, 0x6042, 0xCECC, 0x605F, 0xCECD, 0x6024, 0xCECE, 0x6044, - 0xCECF, 0x6058, 0xCED0, 0x6066, 0xCED1, 0x606E, 0xCED2, 0x6242, 0xCED3, 0x6243, 0xCED4, 0x62CF, 0xCED5, 0x630D, 0xCED6, 0x630B, - 0xCED7, 0x62F5, 0xCED8, 0x630E, 0xCED9, 0x6303, 0xCEDA, 0x62EB, 0xCEDB, 0x62F9, 0xCEDC, 0x630F, 0xCEDD, 0x630C, 0xCEDE, 0x62F8, - 0xCEDF, 0x62F6, 0xCEE0, 0x6300, 0xCEE1, 0x6313, 0xCEE2, 0x6314, 0xCEE3, 0x62FA, 0xCEE4, 0x6315, 0xCEE5, 0x62FB, 0xCEE6, 0x62F0, - 0xCEE7, 0x6541, 0xCEE8, 0x6543, 0xCEE9, 0x65AA, 0xCEEA, 0x65BF, 0xCEEB, 0x6636, 0xCEEC, 0x6621, 0xCEED, 0x6632, 0xCEEE, 0x6635, - 0xCEEF, 0x661C, 0xCEF0, 0x6626, 0xCEF1, 0x6622, 0xCEF2, 0x6633, 0xCEF3, 0x662B, 0xCEF4, 0x663A, 0xCEF5, 0x661D, 0xCEF6, 0x6634, - 0xCEF7, 0x6639, 0xCEF8, 0x662E, 0xCEF9, 0x670F, 0xCEFA, 0x6710, 0xCEFB, 0x67C1, 0xCEFC, 0x67F2, 0xCEFD, 0x67C8, 0xCEFE, 0x67BA, - 0xCF40, 0x67DC, 0xCF41, 0x67BB, 0xCF42, 0x67F8, 0xCF43, 0x67D8, 0xCF44, 0x67C0, 0xCF45, 0x67B7, 0xCF46, 0x67C5, 0xCF47, 0x67EB, - 0xCF48, 0x67E4, 0xCF49, 0x67DF, 0xCF4A, 0x67B5, 0xCF4B, 0x67CD, 0xCF4C, 0x67B3, 0xCF4D, 0x67F7, 0xCF4E, 0x67F6, 0xCF4F, 0x67EE, - 0xCF50, 0x67E3, 0xCF51, 0x67C2, 0xCF52, 0x67B9, 0xCF53, 0x67CE, 0xCF54, 0x67E7, 0xCF55, 0x67F0, 0xCF56, 0x67B2, 0xCF57, 0x67FC, - 0xCF58, 0x67C6, 0xCF59, 0x67ED, 0xCF5A, 0x67CC, 0xCF5B, 0x67AE, 0xCF5C, 0x67E6, 0xCF5D, 0x67DB, 0xCF5E, 0x67FA, 0xCF5F, 0x67C9, - 0xCF60, 0x67CA, 0xCF61, 0x67C3, 0xCF62, 0x67EA, 0xCF63, 0x67CB, 0xCF64, 0x6B28, 0xCF65, 0x6B82, 0xCF66, 0x6B84, 0xCF67, 0x6BB6, - 0xCF68, 0x6BD6, 0xCF69, 0x6BD8, 0xCF6A, 0x6BE0, 0xCF6B, 0x6C20, 0xCF6C, 0x6C21, 0xCF6D, 0x6D28, 0xCF6E, 0x6D34, 0xCF6F, 0x6D2D, - 0xCF70, 0x6D1F, 0xCF71, 0x6D3C, 0xCF72, 0x6D3F, 0xCF73, 0x6D12, 0xCF74, 0x6D0A, 0xCF75, 0x6CDA, 0xCF76, 0x6D33, 0xCF77, 0x6D04, - 0xCF78, 0x6D19, 0xCF79, 0x6D3A, 0xCF7A, 0x6D1A, 0xCF7B, 0x6D11, 0xCF7C, 0x6D00, 0xCF7D, 0x6D1D, 0xCF7E, 0x6D42, 0xCFA1, 0x6D01, - 0xCFA2, 0x6D18, 0xCFA3, 0x6D37, 0xCFA4, 0x6D03, 0xCFA5, 0x6D0F, 0xCFA6, 0x6D40, 0xCFA7, 0x6D07, 0xCFA8, 0x6D20, 0xCFA9, 0x6D2C, - 0xCFAA, 0x6D08, 0xCFAB, 0x6D22, 0xCFAC, 0x6D09, 0xCFAD, 0x6D10, 0xCFAE, 0x70B7, 0xCFAF, 0x709F, 0xCFB0, 0x70BE, 0xCFB1, 0x70B1, - 0xCFB2, 0x70B0, 0xCFB3, 0x70A1, 0xCFB4, 0x70B4, 0xCFB5, 0x70B5, 0xCFB6, 0x70A9, 0xCFB7, 0x7241, 0xCFB8, 0x7249, 0xCFB9, 0x724A, - 0xCFBA, 0x726C, 0xCFBB, 0x7270, 0xCFBC, 0x7273, 0xCFBD, 0x726E, 0xCFBE, 0x72CA, 0xCFBF, 0x72E4, 0xCFC0, 0x72E8, 0xCFC1, 0x72EB, - 0xCFC2, 0x72DF, 0xCFC3, 0x72EA, 0xCFC4, 0x72E6, 0xCFC5, 0x72E3, 0xCFC6, 0x7385, 0xCFC7, 0x73CC, 0xCFC8, 0x73C2, 0xCFC9, 0x73C8, - 0xCFCA, 0x73C5, 0xCFCB, 0x73B9, 0xCFCC, 0x73B6, 0xCFCD, 0x73B5, 0xCFCE, 0x73B4, 0xCFCF, 0x73EB, 0xCFD0, 0x73BF, 0xCFD1, 0x73C7, - 0xCFD2, 0x73BE, 0xCFD3, 0x73C3, 0xCFD4, 0x73C6, 0xCFD5, 0x73B8, 0xCFD6, 0x73CB, 0xCFD7, 0x74EC, 0xCFD8, 0x74EE, 0xCFD9, 0x752E, - 0xCFDA, 0x7547, 0xCFDB, 0x7548, 0xCFDC, 0x75A7, 0xCFDD, 0x75AA, 0xCFDE, 0x7679, 0xCFDF, 0x76C4, 0xCFE0, 0x7708, 0xCFE1, 0x7703, - 0xCFE2, 0x7704, 0xCFE3, 0x7705, 0xCFE4, 0x770A, 0xCFE5, 0x76F7, 0xCFE6, 0x76FB, 0xCFE7, 0x76FA, 0xCFE8, 0x77E7, 0xCFE9, 0x77E8, - 0xCFEA, 0x7806, 0xCFEB, 0x7811, 0xCFEC, 0x7812, 0xCFED, 0x7805, 0xCFEE, 0x7810, 0xCFEF, 0x780F, 0xCFF0, 0x780E, 0xCFF1, 0x7809, - 0xCFF2, 0x7803, 0xCFF3, 0x7813, 0xCFF4, 0x794A, 0xCFF5, 0x794C, 0xCFF6, 0x794B, 0xCFF7, 0x7945, 0xCFF8, 0x7944, 0xCFF9, 0x79D5, - 0xCFFA, 0x79CD, 0xCFFB, 0x79CF, 0xCFFC, 0x79D6, 0xCFFD, 0x79CE, 0xCFFE, 0x7A80, 0xD040, 0x7A7E, 0xD041, 0x7AD1, 0xD042, 0x7B00, - 0xD043, 0x7B01, 0xD044, 0x7C7A, 0xD045, 0x7C78, 0xD046, 0x7C79, 0xD047, 0x7C7F, 0xD048, 0x7C80, 0xD049, 0x7C81, 0xD04A, 0x7D03, - 0xD04B, 0x7D08, 0xD04C, 0x7D01, 0xD04D, 0x7F58, 0xD04E, 0x7F91, 0xD04F, 0x7F8D, 0xD050, 0x7FBE, 0xD051, 0x8007, 0xD052, 0x800E, - 0xD053, 0x800F, 0xD054, 0x8014, 0xD055, 0x8037, 0xD056, 0x80D8, 0xD057, 0x80C7, 0xD058, 0x80E0, 0xD059, 0x80D1, 0xD05A, 0x80C8, - 0xD05B, 0x80C2, 0xD05C, 0x80D0, 0xD05D, 0x80C5, 0xD05E, 0x80E3, 0xD05F, 0x80D9, 0xD060, 0x80DC, 0xD061, 0x80CA, 0xD062, 0x80D5, - 0xD063, 0x80C9, 0xD064, 0x80CF, 0xD065, 0x80D7, 0xD066, 0x80E6, 0xD067, 0x80CD, 0xD068, 0x81FF, 0xD069, 0x8221, 0xD06A, 0x8294, - 0xD06B, 0x82D9, 0xD06C, 0x82FE, 0xD06D, 0x82F9, 0xD06E, 0x8307, 0xD06F, 0x82E8, 0xD070, 0x8300, 0xD071, 0x82D5, 0xD072, 0x833A, - 0xD073, 0x82EB, 0xD074, 0x82D6, 0xD075, 0x82F4, 0xD076, 0x82EC, 0xD077, 0x82E1, 0xD078, 0x82F2, 0xD079, 0x82F5, 0xD07A, 0x830C, - 0xD07B, 0x82FB, 0xD07C, 0x82F6, 0xD07D, 0x82F0, 0xD07E, 0x82EA, 0xD0A1, 0x82E4, 0xD0A2, 0x82E0, 0xD0A3, 0x82FA, 0xD0A4, 0x82F3, - 0xD0A5, 0x82ED, 0xD0A6, 0x8677, 0xD0A7, 0x8674, 0xD0A8, 0x867C, 0xD0A9, 0x8673, 0xD0AA, 0x8841, 0xD0AB, 0x884E, 0xD0AC, 0x8867, - 0xD0AD, 0x886A, 0xD0AE, 0x8869, 0xD0AF, 0x89D3, 0xD0B0, 0x8A04, 0xD0B1, 0x8A07, 0xD0B2, 0x8D72, 0xD0B3, 0x8FE3, 0xD0B4, 0x8FE1, - 0xD0B5, 0x8FEE, 0xD0B6, 0x8FE0, 0xD0B7, 0x90F1, 0xD0B8, 0x90BD, 0xD0B9, 0x90BF, 0xD0BA, 0x90D5, 0xD0BB, 0x90C5, 0xD0BC, 0x90BE, - 0xD0BD, 0x90C7, 0xD0BE, 0x90CB, 0xD0BF, 0x90C8, 0xD0C0, 0x91D4, 0xD0C1, 0x91D3, 0xD0C2, 0x9654, 0xD0C3, 0x964F, 0xD0C4, 0x9651, - 0xD0C5, 0x9653, 0xD0C6, 0x964A, 0xD0C7, 0x964E, 0xD0C8, 0x501E, 0xD0C9, 0x5005, 0xD0CA, 0x5007, 0xD0CB, 0x5013, 0xD0CC, 0x5022, - 0xD0CD, 0x5030, 0xD0CE, 0x501B, 0xD0CF, 0x4FF5, 0xD0D0, 0x4FF4, 0xD0D1, 0x5033, 0xD0D2, 0x5037, 0xD0D3, 0x502C, 0xD0D4, 0x4FF6, - 0xD0D5, 0x4FF7, 0xD0D6, 0x5017, 0xD0D7, 0x501C, 0xD0D8, 0x5020, 0xD0D9, 0x5027, 0xD0DA, 0x5035, 0xD0DB, 0x502F, 0xD0DC, 0x5031, - 0xD0DD, 0x500E, 0xD0DE, 0x515A, 0xD0DF, 0x5194, 0xD0E0, 0x5193, 0xD0E1, 0x51CA, 0xD0E2, 0x51C4, 0xD0E3, 0x51C5, 0xD0E4, 0x51C8, - 0xD0E5, 0x51CE, 0xD0E6, 0x5261, 0xD0E7, 0x525A, 0xD0E8, 0x5252, 0xD0E9, 0x525E, 0xD0EA, 0x525F, 0xD0EB, 0x5255, 0xD0EC, 0x5262, - 0xD0ED, 0x52CD, 0xD0EE, 0x530E, 0xD0EF, 0x539E, 0xD0F0, 0x5526, 0xD0F1, 0x54E2, 0xD0F2, 0x5517, 0xD0F3, 0x5512, 0xD0F4, 0x54E7, - 0xD0F5, 0x54F3, 0xD0F6, 0x54E4, 0xD0F7, 0x551A, 0xD0F8, 0x54FF, 0xD0F9, 0x5504, 0xD0FA, 0x5508, 0xD0FB, 0x54EB, 0xD0FC, 0x5511, - 0xD0FD, 0x5505, 0xD0FE, 0x54F1, 0xD140, 0x550A, 0xD141, 0x54FB, 0xD142, 0x54F7, 0xD143, 0x54F8, 0xD144, 0x54E0, 0xD145, 0x550E, - 0xD146, 0x5503, 0xD147, 0x550B, 0xD148, 0x5701, 0xD149, 0x5702, 0xD14A, 0x57CC, 0xD14B, 0x5832, 0xD14C, 0x57D5, 0xD14D, 0x57D2, - 0xD14E, 0x57BA, 0xD14F, 0x57C6, 0xD150, 0x57BD, 0xD151, 0x57BC, 0xD152, 0x57B8, 0xD153, 0x57B6, 0xD154, 0x57BF, 0xD155, 0x57C7, - 0xD156, 0x57D0, 0xD157, 0x57B9, 0xD158, 0x57C1, 0xD159, 0x590E, 0xD15A, 0x594A, 0xD15B, 0x5A19, 0xD15C, 0x5A16, 0xD15D, 0x5A2D, - 0xD15E, 0x5A2E, 0xD15F, 0x5A15, 0xD160, 0x5A0F, 0xD161, 0x5A17, 0xD162, 0x5A0A, 0xD163, 0x5A1E, 0xD164, 0x5A33, 0xD165, 0x5B6C, - 0xD166, 0x5BA7, 0xD167, 0x5BAD, 0xD168, 0x5BAC, 0xD169, 0x5C03, 0xD16A, 0x5C56, 0xD16B, 0x5C54, 0xD16C, 0x5CEC, 0xD16D, 0x5CFF, - 0xD16E, 0x5CEE, 0xD16F, 0x5CF1, 0xD170, 0x5CF7, 0xD171, 0x5D00, 0xD172, 0x5CF9, 0xD173, 0x5E29, 0xD174, 0x5E28, 0xD175, 0x5EA8, - 0xD176, 0x5EAE, 0xD177, 0x5EAA, 0xD178, 0x5EAC, 0xD179, 0x5F33, 0xD17A, 0x5F30, 0xD17B, 0x5F67, 0xD17C, 0x605D, 0xD17D, 0x605A, - 0xD17E, 0x6067, 0xD1A1, 0x6041, 0xD1A2, 0x60A2, 0xD1A3, 0x6088, 0xD1A4, 0x6080, 0xD1A5, 0x6092, 0xD1A6, 0x6081, 0xD1A7, 0x609D, - 0xD1A8, 0x6083, 0xD1A9, 0x6095, 0xD1AA, 0x609B, 0xD1AB, 0x6097, 0xD1AC, 0x6087, 0xD1AD, 0x609C, 0xD1AE, 0x608E, 0xD1AF, 0x6219, - 0xD1B0, 0x6246, 0xD1B1, 0x62F2, 0xD1B2, 0x6310, 0xD1B3, 0x6356, 0xD1B4, 0x632C, 0xD1B5, 0x6344, 0xD1B6, 0x6345, 0xD1B7, 0x6336, - 0xD1B8, 0x6343, 0xD1B9, 0x63E4, 0xD1BA, 0x6339, 0xD1BB, 0x634B, 0xD1BC, 0x634A, 0xD1BD, 0x633C, 0xD1BE, 0x6329, 0xD1BF, 0x6341, - 0xD1C0, 0x6334, 0xD1C1, 0x6358, 0xD1C2, 0x6354, 0xD1C3, 0x6359, 0xD1C4, 0x632D, 0xD1C5, 0x6347, 0xD1C6, 0x6333, 0xD1C7, 0x635A, - 0xD1C8, 0x6351, 0xD1C9, 0x6338, 0xD1CA, 0x6357, 0xD1CB, 0x6340, 0xD1CC, 0x6348, 0xD1CD, 0x654A, 0xD1CE, 0x6546, 0xD1CF, 0x65C6, - 0xD1D0, 0x65C3, 0xD1D1, 0x65C4, 0xD1D2, 0x65C2, 0xD1D3, 0x664A, 0xD1D4, 0x665F, 0xD1D5, 0x6647, 0xD1D6, 0x6651, 0xD1D7, 0x6712, - 0xD1D8, 0x6713, 0xD1D9, 0x681F, 0xD1DA, 0x681A, 0xD1DB, 0x6849, 0xD1DC, 0x6832, 0xD1DD, 0x6833, 0xD1DE, 0x683B, 0xD1DF, 0x684B, - 0xD1E0, 0x684F, 0xD1E1, 0x6816, 0xD1E2, 0x6831, 0xD1E3, 0x681C, 0xD1E4, 0x6835, 0xD1E5, 0x682B, 0xD1E6, 0x682D, 0xD1E7, 0x682F, - 0xD1E8, 0x684E, 0xD1E9, 0x6844, 0xD1EA, 0x6834, 0xD1EB, 0x681D, 0xD1EC, 0x6812, 0xD1ED, 0x6814, 0xD1EE, 0x6826, 0xD1EF, 0x6828, - 0xD1F0, 0x682E, 0xD1F1, 0x684D, 0xD1F2, 0x683A, 0xD1F3, 0x6825, 0xD1F4, 0x6820, 0xD1F5, 0x6B2C, 0xD1F6, 0x6B2F, 0xD1F7, 0x6B2D, - 0xD1F8, 0x6B31, 0xD1F9, 0x6B34, 0xD1FA, 0x6B6D, 0xD1FB, 0x8082, 0xD1FC, 0x6B88, 0xD1FD, 0x6BE6, 0xD1FE, 0x6BE4, 0xD240, 0x6BE8, - 0xD241, 0x6BE3, 0xD242, 0x6BE2, 0xD243, 0x6BE7, 0xD244, 0x6C25, 0xD245, 0x6D7A, 0xD246, 0x6D63, 0xD247, 0x6D64, 0xD248, 0x6D76, - 0xD249, 0x6D0D, 0xD24A, 0x6D61, 0xD24B, 0x6D92, 0xD24C, 0x6D58, 0xD24D, 0x6D62, 0xD24E, 0x6D6D, 0xD24F, 0x6D6F, 0xD250, 0x6D91, - 0xD251, 0x6D8D, 0xD252, 0x6DEF, 0xD253, 0x6D7F, 0xD254, 0x6D86, 0xD255, 0x6D5E, 0xD256, 0x6D67, 0xD257, 0x6D60, 0xD258, 0x6D97, - 0xD259, 0x6D70, 0xD25A, 0x6D7C, 0xD25B, 0x6D5F, 0xD25C, 0x6D82, 0xD25D, 0x6D98, 0xD25E, 0x6D2F, 0xD25F, 0x6D68, 0xD260, 0x6D8B, - 0xD261, 0x6D7E, 0xD262, 0x6D80, 0xD263, 0x6D84, 0xD264, 0x6D16, 0xD265, 0x6D83, 0xD266, 0x6D7B, 0xD267, 0x6D7D, 0xD268, 0x6D75, - 0xD269, 0x6D90, 0xD26A, 0x70DC, 0xD26B, 0x70D3, 0xD26C, 0x70D1, 0xD26D, 0x70DD, 0xD26E, 0x70CB, 0xD26F, 0x7F39, 0xD270, 0x70E2, - 0xD271, 0x70D7, 0xD272, 0x70D2, 0xD273, 0x70DE, 0xD274, 0x70E0, 0xD275, 0x70D4, 0xD276, 0x70CD, 0xD277, 0x70C5, 0xD278, 0x70C6, - 0xD279, 0x70C7, 0xD27A, 0x70DA, 0xD27B, 0x70CE, 0xD27C, 0x70E1, 0xD27D, 0x7242, 0xD27E, 0x7278, 0xD2A1, 0x7277, 0xD2A2, 0x7276, - 0xD2A3, 0x7300, 0xD2A4, 0x72FA, 0xD2A5, 0x72F4, 0xD2A6, 0x72FE, 0xD2A7, 0x72F6, 0xD2A8, 0x72F3, 0xD2A9, 0x72FB, 0xD2AA, 0x7301, - 0xD2AB, 0x73D3, 0xD2AC, 0x73D9, 0xD2AD, 0x73E5, 0xD2AE, 0x73D6, 0xD2AF, 0x73BC, 0xD2B0, 0x73E7, 0xD2B1, 0x73E3, 0xD2B2, 0x73E9, - 0xD2B3, 0x73DC, 0xD2B4, 0x73D2, 0xD2B5, 0x73DB, 0xD2B6, 0x73D4, 0xD2B7, 0x73DD, 0xD2B8, 0x73DA, 0xD2B9, 0x73D7, 0xD2BA, 0x73D8, - 0xD2BB, 0x73E8, 0xD2BC, 0x74DE, 0xD2BD, 0x74DF, 0xD2BE, 0x74F4, 0xD2BF, 0x74F5, 0xD2C0, 0x7521, 0xD2C1, 0x755B, 0xD2C2, 0x755F, - 0xD2C3, 0x75B0, 0xD2C4, 0x75C1, 0xD2C5, 0x75BB, 0xD2C6, 0x75C4, 0xD2C7, 0x75C0, 0xD2C8, 0x75BF, 0xD2C9, 0x75B6, 0xD2CA, 0x75BA, - 0xD2CB, 0x768A, 0xD2CC, 0x76C9, 0xD2CD, 0x771D, 0xD2CE, 0x771B, 0xD2CF, 0x7710, 0xD2D0, 0x7713, 0xD2D1, 0x7712, 0xD2D2, 0x7723, - 0xD2D3, 0x7711, 0xD2D4, 0x7715, 0xD2D5, 0x7719, 0xD2D6, 0x771A, 0xD2D7, 0x7722, 0xD2D8, 0x7727, 0xD2D9, 0x7823, 0xD2DA, 0x782C, - 0xD2DB, 0x7822, 0xD2DC, 0x7835, 0xD2DD, 0x782F, 0xD2DE, 0x7828, 0xD2DF, 0x782E, 0xD2E0, 0x782B, 0xD2E1, 0x7821, 0xD2E2, 0x7829, - 0xD2E3, 0x7833, 0xD2E4, 0x782A, 0xD2E5, 0x7831, 0xD2E6, 0x7954, 0xD2E7, 0x795B, 0xD2E8, 0x794F, 0xD2E9, 0x795C, 0xD2EA, 0x7953, - 0xD2EB, 0x7952, 0xD2EC, 0x7951, 0xD2ED, 0x79EB, 0xD2EE, 0x79EC, 0xD2EF, 0x79E0, 0xD2F0, 0x79EE, 0xD2F1, 0x79ED, 0xD2F2, 0x79EA, - 0xD2F3, 0x79DC, 0xD2F4, 0x79DE, 0xD2F5, 0x79DD, 0xD2F6, 0x7A86, 0xD2F7, 0x7A89, 0xD2F8, 0x7A85, 0xD2F9, 0x7A8B, 0xD2FA, 0x7A8C, - 0xD2FB, 0x7A8A, 0xD2FC, 0x7A87, 0xD2FD, 0x7AD8, 0xD2FE, 0x7B10, 0xD340, 0x7B04, 0xD341, 0x7B13, 0xD342, 0x7B05, 0xD343, 0x7B0F, - 0xD344, 0x7B08, 0xD345, 0x7B0A, 0xD346, 0x7B0E, 0xD347, 0x7B09, 0xD348, 0x7B12, 0xD349, 0x7C84, 0xD34A, 0x7C91, 0xD34B, 0x7C8A, - 0xD34C, 0x7C8C, 0xD34D, 0x7C88, 0xD34E, 0x7C8D, 0xD34F, 0x7C85, 0xD350, 0x7D1E, 0xD351, 0x7D1D, 0xD352, 0x7D11, 0xD353, 0x7D0E, - 0xD354, 0x7D18, 0xD355, 0x7D16, 0xD356, 0x7D13, 0xD357, 0x7D1F, 0xD358, 0x7D12, 0xD359, 0x7D0F, 0xD35A, 0x7D0C, 0xD35B, 0x7F5C, - 0xD35C, 0x7F61, 0xD35D, 0x7F5E, 0xD35E, 0x7F60, 0xD35F, 0x7F5D, 0xD360, 0x7F5B, 0xD361, 0x7F96, 0xD362, 0x7F92, 0xD363, 0x7FC3, - 0xD364, 0x7FC2, 0xD365, 0x7FC0, 0xD366, 0x8016, 0xD367, 0x803E, 0xD368, 0x8039, 0xD369, 0x80FA, 0xD36A, 0x80F2, 0xD36B, 0x80F9, - 0xD36C, 0x80F5, 0xD36D, 0x8101, 0xD36E, 0x80FB, 0xD36F, 0x8100, 0xD370, 0x8201, 0xD371, 0x822F, 0xD372, 0x8225, 0xD373, 0x8333, - 0xD374, 0x832D, 0xD375, 0x8344, 0xD376, 0x8319, 0xD377, 0x8351, 0xD378, 0x8325, 0xD379, 0x8356, 0xD37A, 0x833F, 0xD37B, 0x8341, - 0xD37C, 0x8326, 0xD37D, 0x831C, 0xD37E, 0x8322, 0xD3A1, 0x8342, 0xD3A2, 0x834E, 0xD3A3, 0x831B, 0xD3A4, 0x832A, 0xD3A5, 0x8308, - 0xD3A6, 0x833C, 0xD3A7, 0x834D, 0xD3A8, 0x8316, 0xD3A9, 0x8324, 0xD3AA, 0x8320, 0xD3AB, 0x8337, 0xD3AC, 0x832F, 0xD3AD, 0x8329, - 0xD3AE, 0x8347, 0xD3AF, 0x8345, 0xD3B0, 0x834C, 0xD3B1, 0x8353, 0xD3B2, 0x831E, 0xD3B3, 0x832C, 0xD3B4, 0x834B, 0xD3B5, 0x8327, - 0xD3B6, 0x8348, 0xD3B7, 0x8653, 0xD3B8, 0x8652, 0xD3B9, 0x86A2, 0xD3BA, 0x86A8, 0xD3BB, 0x8696, 0xD3BC, 0x868D, 0xD3BD, 0x8691, - 0xD3BE, 0x869E, 0xD3BF, 0x8687, 0xD3C0, 0x8697, 0xD3C1, 0x8686, 0xD3C2, 0x868B, 0xD3C3, 0x869A, 0xD3C4, 0x8685, 0xD3C5, 0x86A5, - 0xD3C6, 0x8699, 0xD3C7, 0x86A1, 0xD3C8, 0x86A7, 0xD3C9, 0x8695, 0xD3CA, 0x8698, 0xD3CB, 0x868E, 0xD3CC, 0x869D, 0xD3CD, 0x8690, - 0xD3CE, 0x8694, 0xD3CF, 0x8843, 0xD3D0, 0x8844, 0xD3D1, 0x886D, 0xD3D2, 0x8875, 0xD3D3, 0x8876, 0xD3D4, 0x8872, 0xD3D5, 0x8880, - 0xD3D6, 0x8871, 0xD3D7, 0x887F, 0xD3D8, 0x886F, 0xD3D9, 0x8883, 0xD3DA, 0x887E, 0xD3DB, 0x8874, 0xD3DC, 0x887C, 0xD3DD, 0x8A12, - 0xD3DE, 0x8C47, 0xD3DF, 0x8C57, 0xD3E0, 0x8C7B, 0xD3E1, 0x8CA4, 0xD3E2, 0x8CA3, 0xD3E3, 0x8D76, 0xD3E4, 0x8D78, 0xD3E5, 0x8DB5, - 0xD3E6, 0x8DB7, 0xD3E7, 0x8DB6, 0xD3E8, 0x8ED1, 0xD3E9, 0x8ED3, 0xD3EA, 0x8FFE, 0xD3EB, 0x8FF5, 0xD3EC, 0x9002, 0xD3ED, 0x8FFF, - 0xD3EE, 0x8FFB, 0xD3EF, 0x9004, 0xD3F0, 0x8FFC, 0xD3F1, 0x8FF6, 0xD3F2, 0x90D6, 0xD3F3, 0x90E0, 0xD3F4, 0x90D9, 0xD3F5, 0x90DA, - 0xD3F6, 0x90E3, 0xD3F7, 0x90DF, 0xD3F8, 0x90E5, 0xD3F9, 0x90D8, 0xD3FA, 0x90DB, 0xD3FB, 0x90D7, 0xD3FC, 0x90DC, 0xD3FD, 0x90E4, - 0xD3FE, 0x9150, 0xD440, 0x914E, 0xD441, 0x914F, 0xD442, 0x91D5, 0xD443, 0x91E2, 0xD444, 0x91DA, 0xD445, 0x965C, 0xD446, 0x965F, - 0xD447, 0x96BC, 0xD448, 0x98E3, 0xD449, 0x9ADF, 0xD44A, 0x9B2F, 0xD44B, 0x4E7F, 0xD44C, 0x5070, 0xD44D, 0x506A, 0xD44E, 0x5061, - 0xD44F, 0x505E, 0xD450, 0x5060, 0xD451, 0x5053, 0xD452, 0x504B, 0xD453, 0x505D, 0xD454, 0x5072, 0xD455, 0x5048, 0xD456, 0x504D, - 0xD457, 0x5041, 0xD458, 0x505B, 0xD459, 0x504A, 0xD45A, 0x5062, 0xD45B, 0x5015, 0xD45C, 0x5045, 0xD45D, 0x505F, 0xD45E, 0x5069, - 0xD45F, 0x506B, 0xD460, 0x5063, 0xD461, 0x5064, 0xD462, 0x5046, 0xD463, 0x5040, 0xD464, 0x506E, 0xD465, 0x5073, 0xD466, 0x5057, - 0xD467, 0x5051, 0xD468, 0x51D0, 0xD469, 0x526B, 0xD46A, 0x526D, 0xD46B, 0x526C, 0xD46C, 0x526E, 0xD46D, 0x52D6, 0xD46E, 0x52D3, - 0xD46F, 0x532D, 0xD470, 0x539C, 0xD471, 0x5575, 0xD472, 0x5576, 0xD473, 0x553C, 0xD474, 0x554D, 0xD475, 0x5550, 0xD476, 0x5534, - 0xD477, 0x552A, 0xD478, 0x5551, 0xD479, 0x5562, 0xD47A, 0x5536, 0xD47B, 0x5535, 0xD47C, 0x5530, 0xD47D, 0x5552, 0xD47E, 0x5545, - 0xD4A1, 0x550C, 0xD4A2, 0x5532, 0xD4A3, 0x5565, 0xD4A4, 0x554E, 0xD4A5, 0x5539, 0xD4A6, 0x5548, 0xD4A7, 0x552D, 0xD4A8, 0x553B, - 0xD4A9, 0x5540, 0xD4AA, 0x554B, 0xD4AB, 0x570A, 0xD4AC, 0x5707, 0xD4AD, 0x57FB, 0xD4AE, 0x5814, 0xD4AF, 0x57E2, 0xD4B0, 0x57F6, - 0xD4B1, 0x57DC, 0xD4B2, 0x57F4, 0xD4B3, 0x5800, 0xD4B4, 0x57ED, 0xD4B5, 0x57FD, 0xD4B6, 0x5808, 0xD4B7, 0x57F8, 0xD4B8, 0x580B, - 0xD4B9, 0x57F3, 0xD4BA, 0x57CF, 0xD4BB, 0x5807, 0xD4BC, 0x57EE, 0xD4BD, 0x57E3, 0xD4BE, 0x57F2, 0xD4BF, 0x57E5, 0xD4C0, 0x57EC, - 0xD4C1, 0x57E1, 0xD4C2, 0x580E, 0xD4C3, 0x57FC, 0xD4C4, 0x5810, 0xD4C5, 0x57E7, 0xD4C6, 0x5801, 0xD4C7, 0x580C, 0xD4C8, 0x57F1, - 0xD4C9, 0x57E9, 0xD4CA, 0x57F0, 0xD4CB, 0x580D, 0xD4CC, 0x5804, 0xD4CD, 0x595C, 0xD4CE, 0x5A60, 0xD4CF, 0x5A58, 0xD4D0, 0x5A55, - 0xD4D1, 0x5A67, 0xD4D2, 0x5A5E, 0xD4D3, 0x5A38, 0xD4D4, 0x5A35, 0xD4D5, 0x5A6D, 0xD4D6, 0x5A50, 0xD4D7, 0x5A5F, 0xD4D8, 0x5A65, - 0xD4D9, 0x5A6C, 0xD4DA, 0x5A53, 0xD4DB, 0x5A64, 0xD4DC, 0x5A57, 0xD4DD, 0x5A43, 0xD4DE, 0x5A5D, 0xD4DF, 0x5A52, 0xD4E0, 0x5A44, - 0xD4E1, 0x5A5B, 0xD4E2, 0x5A48, 0xD4E3, 0x5A8E, 0xD4E4, 0x5A3E, 0xD4E5, 0x5A4D, 0xD4E6, 0x5A39, 0xD4E7, 0x5A4C, 0xD4E8, 0x5A70, - 0xD4E9, 0x5A69, 0xD4EA, 0x5A47, 0xD4EB, 0x5A51, 0xD4EC, 0x5A56, 0xD4ED, 0x5A42, 0xD4EE, 0x5A5C, 0xD4EF, 0x5B72, 0xD4F0, 0x5B6E, - 0xD4F1, 0x5BC1, 0xD4F2, 0x5BC0, 0xD4F3, 0x5C59, 0xD4F4, 0x5D1E, 0xD4F5, 0x5D0B, 0xD4F6, 0x5D1D, 0xD4F7, 0x5D1A, 0xD4F8, 0x5D20, - 0xD4F9, 0x5D0C, 0xD4FA, 0x5D28, 0xD4FB, 0x5D0D, 0xD4FC, 0x5D26, 0xD4FD, 0x5D25, 0xD4FE, 0x5D0F, 0xD540, 0x5D30, 0xD541, 0x5D12, - 0xD542, 0x5D23, 0xD543, 0x5D1F, 0xD544, 0x5D2E, 0xD545, 0x5E3E, 0xD546, 0x5E34, 0xD547, 0x5EB1, 0xD548, 0x5EB4, 0xD549, 0x5EB9, - 0xD54A, 0x5EB2, 0xD54B, 0x5EB3, 0xD54C, 0x5F36, 0xD54D, 0x5F38, 0xD54E, 0x5F9B, 0xD54F, 0x5F96, 0xD550, 0x5F9F, 0xD551, 0x608A, - 0xD552, 0x6090, 0xD553, 0x6086, 0xD554, 0x60BE, 0xD555, 0x60B0, 0xD556, 0x60BA, 0xD557, 0x60D3, 0xD558, 0x60D4, 0xD559, 0x60CF, - 0xD55A, 0x60E4, 0xD55B, 0x60D9, 0xD55C, 0x60DD, 0xD55D, 0x60C8, 0xD55E, 0x60B1, 0xD55F, 0x60DB, 0xD560, 0x60B7, 0xD561, 0x60CA, - 0xD562, 0x60BF, 0xD563, 0x60C3, 0xD564, 0x60CD, 0xD565, 0x60C0, 0xD566, 0x6332, 0xD567, 0x6365, 0xD568, 0x638A, 0xD569, 0x6382, - 0xD56A, 0x637D, 0xD56B, 0x63BD, 0xD56C, 0x639E, 0xD56D, 0x63AD, 0xD56E, 0x639D, 0xD56F, 0x6397, 0xD570, 0x63AB, 0xD571, 0x638E, - 0xD572, 0x636F, 0xD573, 0x6387, 0xD574, 0x6390, 0xD575, 0x636E, 0xD576, 0x63AF, 0xD577, 0x6375, 0xD578, 0x639C, 0xD579, 0x636D, - 0xD57A, 0x63AE, 0xD57B, 0x637C, 0xD57C, 0x63A4, 0xD57D, 0x633B, 0xD57E, 0x639F, 0xD5A1, 0x6378, 0xD5A2, 0x6385, 0xD5A3, 0x6381, - 0xD5A4, 0x6391, 0xD5A5, 0x638D, 0xD5A6, 0x6370, 0xD5A7, 0x6553, 0xD5A8, 0x65CD, 0xD5A9, 0x6665, 0xD5AA, 0x6661, 0xD5AB, 0x665B, - 0xD5AC, 0x6659, 0xD5AD, 0x665C, 0xD5AE, 0x6662, 0xD5AF, 0x6718, 0xD5B0, 0x6879, 0xD5B1, 0x6887, 0xD5B2, 0x6890, 0xD5B3, 0x689C, - 0xD5B4, 0x686D, 0xD5B5, 0x686E, 0xD5B6, 0x68AE, 0xD5B7, 0x68AB, 0xD5B8, 0x6956, 0xD5B9, 0x686F, 0xD5BA, 0x68A3, 0xD5BB, 0x68AC, - 0xD5BC, 0x68A9, 0xD5BD, 0x6875, 0xD5BE, 0x6874, 0xD5BF, 0x68B2, 0xD5C0, 0x688F, 0xD5C1, 0x6877, 0xD5C2, 0x6892, 0xD5C3, 0x687C, - 0xD5C4, 0x686B, 0xD5C5, 0x6872, 0xD5C6, 0x68AA, 0xD5C7, 0x6880, 0xD5C8, 0x6871, 0xD5C9, 0x687E, 0xD5CA, 0x689B, 0xD5CB, 0x6896, - 0xD5CC, 0x688B, 0xD5CD, 0x68A0, 0xD5CE, 0x6889, 0xD5CF, 0x68A4, 0xD5D0, 0x6878, 0xD5D1, 0x687B, 0xD5D2, 0x6891, 0xD5D3, 0x688C, - 0xD5D4, 0x688A, 0xD5D5, 0x687D, 0xD5D6, 0x6B36, 0xD5D7, 0x6B33, 0xD5D8, 0x6B37, 0xD5D9, 0x6B38, 0xD5DA, 0x6B91, 0xD5DB, 0x6B8F, - 0xD5DC, 0x6B8D, 0xD5DD, 0x6B8E, 0xD5DE, 0x6B8C, 0xD5DF, 0x6C2A, 0xD5E0, 0x6DC0, 0xD5E1, 0x6DAB, 0xD5E2, 0x6DB4, 0xD5E3, 0x6DB3, - 0xD5E4, 0x6E74, 0xD5E5, 0x6DAC, 0xD5E6, 0x6DE9, 0xD5E7, 0x6DE2, 0xD5E8, 0x6DB7, 0xD5E9, 0x6DF6, 0xD5EA, 0x6DD4, 0xD5EB, 0x6E00, - 0xD5EC, 0x6DC8, 0xD5ED, 0x6DE0, 0xD5EE, 0x6DDF, 0xD5EF, 0x6DD6, 0xD5F0, 0x6DBE, 0xD5F1, 0x6DE5, 0xD5F2, 0x6DDC, 0xD5F3, 0x6DDD, - 0xD5F4, 0x6DDB, 0xD5F5, 0x6DF4, 0xD5F6, 0x6DCA, 0xD5F7, 0x6DBD, 0xD5F8, 0x6DED, 0xD5F9, 0x6DF0, 0xD5FA, 0x6DBA, 0xD5FB, 0x6DD5, - 0xD5FC, 0x6DC2, 0xD5FD, 0x6DCF, 0xD5FE, 0x6DC9, 0xD640, 0x6DD0, 0xD641, 0x6DF2, 0xD642, 0x6DD3, 0xD643, 0x6DFD, 0xD644, 0x6DD7, - 0xD645, 0x6DCD, 0xD646, 0x6DE3, 0xD647, 0x6DBB, 0xD648, 0x70FA, 0xD649, 0x710D, 0xD64A, 0x70F7, 0xD64B, 0x7117, 0xD64C, 0x70F4, - 0xD64D, 0x710C, 0xD64E, 0x70F0, 0xD64F, 0x7104, 0xD650, 0x70F3, 0xD651, 0x7110, 0xD652, 0x70FC, 0xD653, 0x70FF, 0xD654, 0x7106, - 0xD655, 0x7113, 0xD656, 0x7100, 0xD657, 0x70F8, 0xD658, 0x70F6, 0xD659, 0x710B, 0xD65A, 0x7102, 0xD65B, 0x710E, 0xD65C, 0x727E, - 0xD65D, 0x727B, 0xD65E, 0x727C, 0xD65F, 0x727F, 0xD660, 0x731D, 0xD661, 0x7317, 0xD662, 0x7307, 0xD663, 0x7311, 0xD664, 0x7318, - 0xD665, 0x730A, 0xD666, 0x7308, 0xD667, 0x72FF, 0xD668, 0x730F, 0xD669, 0x731E, 0xD66A, 0x7388, 0xD66B, 0x73F6, 0xD66C, 0x73F8, - 0xD66D, 0x73F5, 0xD66E, 0x7404, 0xD66F, 0x7401, 0xD670, 0x73FD, 0xD671, 0x7407, 0xD672, 0x7400, 0xD673, 0x73FA, 0xD674, 0x73FC, - 0xD675, 0x73FF, 0xD676, 0x740C, 0xD677, 0x740B, 0xD678, 0x73F4, 0xD679, 0x7408, 0xD67A, 0x7564, 0xD67B, 0x7563, 0xD67C, 0x75CE, - 0xD67D, 0x75D2, 0xD67E, 0x75CF, 0xD6A1, 0x75CB, 0xD6A2, 0x75CC, 0xD6A3, 0x75D1, 0xD6A4, 0x75D0, 0xD6A5, 0x768F, 0xD6A6, 0x7689, - 0xD6A7, 0x76D3, 0xD6A8, 0x7739, 0xD6A9, 0x772F, 0xD6AA, 0x772D, 0xD6AB, 0x7731, 0xD6AC, 0x7732, 0xD6AD, 0x7734, 0xD6AE, 0x7733, - 0xD6AF, 0x773D, 0xD6B0, 0x7725, 0xD6B1, 0x773B, 0xD6B2, 0x7735, 0xD6B3, 0x7848, 0xD6B4, 0x7852, 0xD6B5, 0x7849, 0xD6B6, 0x784D, - 0xD6B7, 0x784A, 0xD6B8, 0x784C, 0xD6B9, 0x7826, 0xD6BA, 0x7845, 0xD6BB, 0x7850, 0xD6BC, 0x7964, 0xD6BD, 0x7967, 0xD6BE, 0x7969, - 0xD6BF, 0x796A, 0xD6C0, 0x7963, 0xD6C1, 0x796B, 0xD6C2, 0x7961, 0xD6C3, 0x79BB, 0xD6C4, 0x79FA, 0xD6C5, 0x79F8, 0xD6C6, 0x79F6, - 0xD6C7, 0x79F7, 0xD6C8, 0x7A8F, 0xD6C9, 0x7A94, 0xD6CA, 0x7A90, 0xD6CB, 0x7B35, 0xD6CC, 0x7B47, 0xD6CD, 0x7B34, 0xD6CE, 0x7B25, - 0xD6CF, 0x7B30, 0xD6D0, 0x7B22, 0xD6D1, 0x7B24, 0xD6D2, 0x7B33, 0xD6D3, 0x7B18, 0xD6D4, 0x7B2A, 0xD6D5, 0x7B1D, 0xD6D6, 0x7B31, - 0xD6D7, 0x7B2B, 0xD6D8, 0x7B2D, 0xD6D9, 0x7B2F, 0xD6DA, 0x7B32, 0xD6DB, 0x7B38, 0xD6DC, 0x7B1A, 0xD6DD, 0x7B23, 0xD6DE, 0x7C94, - 0xD6DF, 0x7C98, 0xD6E0, 0x7C96, 0xD6E1, 0x7CA3, 0xD6E2, 0x7D35, 0xD6E3, 0x7D3D, 0xD6E4, 0x7D38, 0xD6E5, 0x7D36, 0xD6E6, 0x7D3A, - 0xD6E7, 0x7D45, 0xD6E8, 0x7D2C, 0xD6E9, 0x7D29, 0xD6EA, 0x7D41, 0xD6EB, 0x7D47, 0xD6EC, 0x7D3E, 0xD6ED, 0x7D3F, 0xD6EE, 0x7D4A, - 0xD6EF, 0x7D3B, 0xD6F0, 0x7D28, 0xD6F1, 0x7F63, 0xD6F2, 0x7F95, 0xD6F3, 0x7F9C, 0xD6F4, 0x7F9D, 0xD6F5, 0x7F9B, 0xD6F6, 0x7FCA, - 0xD6F7, 0x7FCB, 0xD6F8, 0x7FCD, 0xD6F9, 0x7FD0, 0xD6FA, 0x7FD1, 0xD6FB, 0x7FC7, 0xD6FC, 0x7FCF, 0xD6FD, 0x7FC9, 0xD6FE, 0x801F, - 0xD740, 0x801E, 0xD741, 0x801B, 0xD742, 0x8047, 0xD743, 0x8043, 0xD744, 0x8048, 0xD745, 0x8118, 0xD746, 0x8125, 0xD747, 0x8119, - 0xD748, 0x811B, 0xD749, 0x812D, 0xD74A, 0x811F, 0xD74B, 0x812C, 0xD74C, 0x811E, 0xD74D, 0x8121, 0xD74E, 0x8115, 0xD74F, 0x8127, - 0xD750, 0x811D, 0xD751, 0x8122, 0xD752, 0x8211, 0xD753, 0x8238, 0xD754, 0x8233, 0xD755, 0x823A, 0xD756, 0x8234, 0xD757, 0x8232, - 0xD758, 0x8274, 0xD759, 0x8390, 0xD75A, 0x83A3, 0xD75B, 0x83A8, 0xD75C, 0x838D, 0xD75D, 0x837A, 0xD75E, 0x8373, 0xD75F, 0x83A4, - 0xD760, 0x8374, 0xD761, 0x838F, 0xD762, 0x8381, 0xD763, 0x8395, 0xD764, 0x8399, 0xD765, 0x8375, 0xD766, 0x8394, 0xD767, 0x83A9, - 0xD768, 0x837D, 0xD769, 0x8383, 0xD76A, 0x838C, 0xD76B, 0x839D, 0xD76C, 0x839B, 0xD76D, 0x83AA, 0xD76E, 0x838B, 0xD76F, 0x837E, - 0xD770, 0x83A5, 0xD771, 0x83AF, 0xD772, 0x8388, 0xD773, 0x8397, 0xD774, 0x83B0, 0xD775, 0x837F, 0xD776, 0x83A6, 0xD777, 0x8387, - 0xD778, 0x83AE, 0xD779, 0x8376, 0xD77A, 0x839A, 0xD77B, 0x8659, 0xD77C, 0x8656, 0xD77D, 0x86BF, 0xD77E, 0x86B7, 0xD7A1, 0x86C2, - 0xD7A2, 0x86C1, 0xD7A3, 0x86C5, 0xD7A4, 0x86BA, 0xD7A5, 0x86B0, 0xD7A6, 0x86C8, 0xD7A7, 0x86B9, 0xD7A8, 0x86B3, 0xD7A9, 0x86B8, - 0xD7AA, 0x86CC, 0xD7AB, 0x86B4, 0xD7AC, 0x86BB, 0xD7AD, 0x86BC, 0xD7AE, 0x86C3, 0xD7AF, 0x86BD, 0xD7B0, 0x86BE, 0xD7B1, 0x8852, - 0xD7B2, 0x8889, 0xD7B3, 0x8895, 0xD7B4, 0x88A8, 0xD7B5, 0x88A2, 0xD7B6, 0x88AA, 0xD7B7, 0x889A, 0xD7B8, 0x8891, 0xD7B9, 0x88A1, - 0xD7BA, 0x889F, 0xD7BB, 0x8898, 0xD7BC, 0x88A7, 0xD7BD, 0x8899, 0xD7BE, 0x889B, 0xD7BF, 0x8897, 0xD7C0, 0x88A4, 0xD7C1, 0x88AC, - 0xD7C2, 0x888C, 0xD7C3, 0x8893, 0xD7C4, 0x888E, 0xD7C5, 0x8982, 0xD7C6, 0x89D6, 0xD7C7, 0x89D9, 0xD7C8, 0x89D5, 0xD7C9, 0x8A30, - 0xD7CA, 0x8A27, 0xD7CB, 0x8A2C, 0xD7CC, 0x8A1E, 0xD7CD, 0x8C39, 0xD7CE, 0x8C3B, 0xD7CF, 0x8C5C, 0xD7D0, 0x8C5D, 0xD7D1, 0x8C7D, - 0xD7D2, 0x8CA5, 0xD7D3, 0x8D7D, 0xD7D4, 0x8D7B, 0xD7D5, 0x8D79, 0xD7D6, 0x8DBC, 0xD7D7, 0x8DC2, 0xD7D8, 0x8DB9, 0xD7D9, 0x8DBF, - 0xD7DA, 0x8DC1, 0xD7DB, 0x8ED8, 0xD7DC, 0x8EDE, 0xD7DD, 0x8EDD, 0xD7DE, 0x8EDC, 0xD7DF, 0x8ED7, 0xD7E0, 0x8EE0, 0xD7E1, 0x8EE1, - 0xD7E2, 0x9024, 0xD7E3, 0x900B, 0xD7E4, 0x9011, 0xD7E5, 0x901C, 0xD7E6, 0x900C, 0xD7E7, 0x9021, 0xD7E8, 0x90EF, 0xD7E9, 0x90EA, - 0xD7EA, 0x90F0, 0xD7EB, 0x90F4, 0xD7EC, 0x90F2, 0xD7ED, 0x90F3, 0xD7EE, 0x90D4, 0xD7EF, 0x90EB, 0xD7F0, 0x90EC, 0xD7F1, 0x90E9, - 0xD7F2, 0x9156, 0xD7F3, 0x9158, 0xD7F4, 0x915A, 0xD7F5, 0x9153, 0xD7F6, 0x9155, 0xD7F7, 0x91EC, 0xD7F8, 0x91F4, 0xD7F9, 0x91F1, - 0xD7FA, 0x91F3, 0xD7FB, 0x91F8, 0xD7FC, 0x91E4, 0xD7FD, 0x91F9, 0xD7FE, 0x91EA, 0xD840, 0x91EB, 0xD841, 0x91F7, 0xD842, 0x91E8, - 0xD843, 0x91EE, 0xD844, 0x957A, 0xD845, 0x9586, 0xD846, 0x9588, 0xD847, 0x967C, 0xD848, 0x966D, 0xD849, 0x966B, 0xD84A, 0x9671, - 0xD84B, 0x966F, 0xD84C, 0x96BF, 0xD84D, 0x976A, 0xD84E, 0x9804, 0xD84F, 0x98E5, 0xD850, 0x9997, 0xD851, 0x509B, 0xD852, 0x5095, - 0xD853, 0x5094, 0xD854, 0x509E, 0xD855, 0x508B, 0xD856, 0x50A3, 0xD857, 0x5083, 0xD858, 0x508C, 0xD859, 0x508E, 0xD85A, 0x509D, - 0xD85B, 0x5068, 0xD85C, 0x509C, 0xD85D, 0x5092, 0xD85E, 0x5082, 0xD85F, 0x5087, 0xD860, 0x515F, 0xD861, 0x51D4, 0xD862, 0x5312, - 0xD863, 0x5311, 0xD864, 0x53A4, 0xD865, 0x53A7, 0xD866, 0x5591, 0xD867, 0x55A8, 0xD868, 0x55A5, 0xD869, 0x55AD, 0xD86A, 0x5577, - 0xD86B, 0x5645, 0xD86C, 0x55A2, 0xD86D, 0x5593, 0xD86E, 0x5588, 0xD86F, 0x558F, 0xD870, 0x55B5, 0xD871, 0x5581, 0xD872, 0x55A3, - 0xD873, 0x5592, 0xD874, 0x55A4, 0xD875, 0x557D, 0xD876, 0x558C, 0xD877, 0x55A6, 0xD878, 0x557F, 0xD879, 0x5595, 0xD87A, 0x55A1, - 0xD87B, 0x558E, 0xD87C, 0x570C, 0xD87D, 0x5829, 0xD87E, 0x5837, 0xD8A1, 0x5819, 0xD8A2, 0x581E, 0xD8A3, 0x5827, 0xD8A4, 0x5823, - 0xD8A5, 0x5828, 0xD8A6, 0x57F5, 0xD8A7, 0x5848, 0xD8A8, 0x5825, 0xD8A9, 0x581C, 0xD8AA, 0x581B, 0xD8AB, 0x5833, 0xD8AC, 0x583F, - 0xD8AD, 0x5836, 0xD8AE, 0x582E, 0xD8AF, 0x5839, 0xD8B0, 0x5838, 0xD8B1, 0x582D, 0xD8B2, 0x582C, 0xD8B3, 0x583B, 0xD8B4, 0x5961, - 0xD8B5, 0x5AAF, 0xD8B6, 0x5A94, 0xD8B7, 0x5A9F, 0xD8B8, 0x5A7A, 0xD8B9, 0x5AA2, 0xD8BA, 0x5A9E, 0xD8BB, 0x5A78, 0xD8BC, 0x5AA6, - 0xD8BD, 0x5A7C, 0xD8BE, 0x5AA5, 0xD8BF, 0x5AAC, 0xD8C0, 0x5A95, 0xD8C1, 0x5AAE, 0xD8C2, 0x5A37, 0xD8C3, 0x5A84, 0xD8C4, 0x5A8A, - 0xD8C5, 0x5A97, 0xD8C6, 0x5A83, 0xD8C7, 0x5A8B, 0xD8C8, 0x5AA9, 0xD8C9, 0x5A7B, 0xD8CA, 0x5A7D, 0xD8CB, 0x5A8C, 0xD8CC, 0x5A9C, - 0xD8CD, 0x5A8F, 0xD8CE, 0x5A93, 0xD8CF, 0x5A9D, 0xD8D0, 0x5BEA, 0xD8D1, 0x5BCD, 0xD8D2, 0x5BCB, 0xD8D3, 0x5BD4, 0xD8D4, 0x5BD1, - 0xD8D5, 0x5BCA, 0xD8D6, 0x5BCE, 0xD8D7, 0x5C0C, 0xD8D8, 0x5C30, 0xD8D9, 0x5D37, 0xD8DA, 0x5D43, 0xD8DB, 0x5D6B, 0xD8DC, 0x5D41, - 0xD8DD, 0x5D4B, 0xD8DE, 0x5D3F, 0xD8DF, 0x5D35, 0xD8E0, 0x5D51, 0xD8E1, 0x5D4E, 0xD8E2, 0x5D55, 0xD8E3, 0x5D33, 0xD8E4, 0x5D3A, - 0xD8E5, 0x5D52, 0xD8E6, 0x5D3D, 0xD8E7, 0x5D31, 0xD8E8, 0x5D59, 0xD8E9, 0x5D42, 0xD8EA, 0x5D39, 0xD8EB, 0x5D49, 0xD8EC, 0x5D38, - 0xD8ED, 0x5D3C, 0xD8EE, 0x5D32, 0xD8EF, 0x5D36, 0xD8F0, 0x5D40, 0xD8F1, 0x5D45, 0xD8F2, 0x5E44, 0xD8F3, 0x5E41, 0xD8F4, 0x5F58, - 0xD8F5, 0x5FA6, 0xD8F6, 0x5FA5, 0xD8F7, 0x5FAB, 0xD8F8, 0x60C9, 0xD8F9, 0x60B9, 0xD8FA, 0x60CC, 0xD8FB, 0x60E2, 0xD8FC, 0x60CE, - 0xD8FD, 0x60C4, 0xD8FE, 0x6114, 0xD940, 0x60F2, 0xD941, 0x610A, 0xD942, 0x6116, 0xD943, 0x6105, 0xD944, 0x60F5, 0xD945, 0x6113, - 0xD946, 0x60F8, 0xD947, 0x60FC, 0xD948, 0x60FE, 0xD949, 0x60C1, 0xD94A, 0x6103, 0xD94B, 0x6118, 0xD94C, 0x611D, 0xD94D, 0x6110, - 0xD94E, 0x60FF, 0xD94F, 0x6104, 0xD950, 0x610B, 0xD951, 0x624A, 0xD952, 0x6394, 0xD953, 0x63B1, 0xD954, 0x63B0, 0xD955, 0x63CE, - 0xD956, 0x63E5, 0xD957, 0x63E8, 0xD958, 0x63EF, 0xD959, 0x63C3, 0xD95A, 0x649D, 0xD95B, 0x63F3, 0xD95C, 0x63CA, 0xD95D, 0x63E0, - 0xD95E, 0x63F6, 0xD95F, 0x63D5, 0xD960, 0x63F2, 0xD961, 0x63F5, 0xD962, 0x6461, 0xD963, 0x63DF, 0xD964, 0x63BE, 0xD965, 0x63DD, - 0xD966, 0x63DC, 0xD967, 0x63C4, 0xD968, 0x63D8, 0xD969, 0x63D3, 0xD96A, 0x63C2, 0xD96B, 0x63C7, 0xD96C, 0x63CC, 0xD96D, 0x63CB, - 0xD96E, 0x63C8, 0xD96F, 0x63F0, 0xD970, 0x63D7, 0xD971, 0x63D9, 0xD972, 0x6532, 0xD973, 0x6567, 0xD974, 0x656A, 0xD975, 0x6564, - 0xD976, 0x655C, 0xD977, 0x6568, 0xD978, 0x6565, 0xD979, 0x658C, 0xD97A, 0x659D, 0xD97B, 0x659E, 0xD97C, 0x65AE, 0xD97D, 0x65D0, - 0xD97E, 0x65D2, 0xD9A1, 0x667C, 0xD9A2, 0x666C, 0xD9A3, 0x667B, 0xD9A4, 0x6680, 0xD9A5, 0x6671, 0xD9A6, 0x6679, 0xD9A7, 0x666A, - 0xD9A8, 0x6672, 0xD9A9, 0x6701, 0xD9AA, 0x690C, 0xD9AB, 0x68D3, 0xD9AC, 0x6904, 0xD9AD, 0x68DC, 0xD9AE, 0x692A, 0xD9AF, 0x68EC, - 0xD9B0, 0x68EA, 0xD9B1, 0x68F1, 0xD9B2, 0x690F, 0xD9B3, 0x68D6, 0xD9B4, 0x68F7, 0xD9B5, 0x68EB, 0xD9B6, 0x68E4, 0xD9B7, 0x68F6, - 0xD9B8, 0x6913, 0xD9B9, 0x6910, 0xD9BA, 0x68F3, 0xD9BB, 0x68E1, 0xD9BC, 0x6907, 0xD9BD, 0x68CC, 0xD9BE, 0x6908, 0xD9BF, 0x6970, - 0xD9C0, 0x68B4, 0xD9C1, 0x6911, 0xD9C2, 0x68EF, 0xD9C3, 0x68C6, 0xD9C4, 0x6914, 0xD9C5, 0x68F8, 0xD9C6, 0x68D0, 0xD9C7, 0x68FD, - 0xD9C8, 0x68FC, 0xD9C9, 0x68E8, 0xD9CA, 0x690B, 0xD9CB, 0x690A, 0xD9CC, 0x6917, 0xD9CD, 0x68CE, 0xD9CE, 0x68C8, 0xD9CF, 0x68DD, - 0xD9D0, 0x68DE, 0xD9D1, 0x68E6, 0xD9D2, 0x68F4, 0xD9D3, 0x68D1, 0xD9D4, 0x6906, 0xD9D5, 0x68D4, 0xD9D6, 0x68E9, 0xD9D7, 0x6915, - 0xD9D8, 0x6925, 0xD9D9, 0x68C7, 0xD9DA, 0x6B39, 0xD9DB, 0x6B3B, 0xD9DC, 0x6B3F, 0xD9DD, 0x6B3C, 0xD9DE, 0x6B94, 0xD9DF, 0x6B97, - 0xD9E0, 0x6B99, 0xD9E1, 0x6B95, 0xD9E2, 0x6BBD, 0xD9E3, 0x6BF0, 0xD9E4, 0x6BF2, 0xD9E5, 0x6BF3, 0xD9E6, 0x6C30, 0xD9E7, 0x6DFC, - 0xD9E8, 0x6E46, 0xD9E9, 0x6E47, 0xD9EA, 0x6E1F, 0xD9EB, 0x6E49, 0xD9EC, 0x6E88, 0xD9ED, 0x6E3C, 0xD9EE, 0x6E3D, 0xD9EF, 0x6E45, - 0xD9F0, 0x6E62, 0xD9F1, 0x6E2B, 0xD9F2, 0x6E3F, 0xD9F3, 0x6E41, 0xD9F4, 0x6E5D, 0xD9F5, 0x6E73, 0xD9F6, 0x6E1C, 0xD9F7, 0x6E33, - 0xD9F8, 0x6E4B, 0xD9F9, 0x6E40, 0xD9FA, 0x6E51, 0xD9FB, 0x6E3B, 0xD9FC, 0x6E03, 0xD9FD, 0x6E2E, 0xD9FE, 0x6E5E, 0xDA40, 0x6E68, - 0xDA41, 0x6E5C, 0xDA42, 0x6E61, 0xDA43, 0x6E31, 0xDA44, 0x6E28, 0xDA45, 0x6E60, 0xDA46, 0x6E71, 0xDA47, 0x6E6B, 0xDA48, 0x6E39, - 0xDA49, 0x6E22, 0xDA4A, 0x6E30, 0xDA4B, 0x6E53, 0xDA4C, 0x6E65, 0xDA4D, 0x6E27, 0xDA4E, 0x6E78, 0xDA4F, 0x6E64, 0xDA50, 0x6E77, - 0xDA51, 0x6E55, 0xDA52, 0x6E79, 0xDA53, 0x6E52, 0xDA54, 0x6E66, 0xDA55, 0x6E35, 0xDA56, 0x6E36, 0xDA57, 0x6E5A, 0xDA58, 0x7120, - 0xDA59, 0x711E, 0xDA5A, 0x712F, 0xDA5B, 0x70FB, 0xDA5C, 0x712E, 0xDA5D, 0x7131, 0xDA5E, 0x7123, 0xDA5F, 0x7125, 0xDA60, 0x7122, - 0xDA61, 0x7132, 0xDA62, 0x711F, 0xDA63, 0x7128, 0xDA64, 0x713A, 0xDA65, 0x711B, 0xDA66, 0x724B, 0xDA67, 0x725A, 0xDA68, 0x7288, - 0xDA69, 0x7289, 0xDA6A, 0x7286, 0xDA6B, 0x7285, 0xDA6C, 0x728B, 0xDA6D, 0x7312, 0xDA6E, 0x730B, 0xDA6F, 0x7330, 0xDA70, 0x7322, - 0xDA71, 0x7331, 0xDA72, 0x7333, 0xDA73, 0x7327, 0xDA74, 0x7332, 0xDA75, 0x732D, 0xDA76, 0x7326, 0xDA77, 0x7323, 0xDA78, 0x7335, - 0xDA79, 0x730C, 0xDA7A, 0x742E, 0xDA7B, 0x742C, 0xDA7C, 0x7430, 0xDA7D, 0x742B, 0xDA7E, 0x7416, 0xDAA1, 0x741A, 0xDAA2, 0x7421, - 0xDAA3, 0x742D, 0xDAA4, 0x7431, 0xDAA5, 0x7424, 0xDAA6, 0x7423, 0xDAA7, 0x741D, 0xDAA8, 0x7429, 0xDAA9, 0x7420, 0xDAAA, 0x7432, - 0xDAAB, 0x74FB, 0xDAAC, 0x752F, 0xDAAD, 0x756F, 0xDAAE, 0x756C, 0xDAAF, 0x75E7, 0xDAB0, 0x75DA, 0xDAB1, 0x75E1, 0xDAB2, 0x75E6, - 0xDAB3, 0x75DD, 0xDAB4, 0x75DF, 0xDAB5, 0x75E4, 0xDAB6, 0x75D7, 0xDAB7, 0x7695, 0xDAB8, 0x7692, 0xDAB9, 0x76DA, 0xDABA, 0x7746, - 0xDABB, 0x7747, 0xDABC, 0x7744, 0xDABD, 0x774D, 0xDABE, 0x7745, 0xDABF, 0x774A, 0xDAC0, 0x774E, 0xDAC1, 0x774B, 0xDAC2, 0x774C, - 0xDAC3, 0x77DE, 0xDAC4, 0x77EC, 0xDAC5, 0x7860, 0xDAC6, 0x7864, 0xDAC7, 0x7865, 0xDAC8, 0x785C, 0xDAC9, 0x786D, 0xDACA, 0x7871, - 0xDACB, 0x786A, 0xDACC, 0x786E, 0xDACD, 0x7870, 0xDACE, 0x7869, 0xDACF, 0x7868, 0xDAD0, 0x785E, 0xDAD1, 0x7862, 0xDAD2, 0x7974, - 0xDAD3, 0x7973, 0xDAD4, 0x7972, 0xDAD5, 0x7970, 0xDAD6, 0x7A02, 0xDAD7, 0x7A0A, 0xDAD8, 0x7A03, 0xDAD9, 0x7A0C, 0xDADA, 0x7A04, - 0xDADB, 0x7A99, 0xDADC, 0x7AE6, 0xDADD, 0x7AE4, 0xDADE, 0x7B4A, 0xDADF, 0x7B3B, 0xDAE0, 0x7B44, 0xDAE1, 0x7B48, 0xDAE2, 0x7B4C, - 0xDAE3, 0x7B4E, 0xDAE4, 0x7B40, 0xDAE5, 0x7B58, 0xDAE6, 0x7B45, 0xDAE7, 0x7CA2, 0xDAE8, 0x7C9E, 0xDAE9, 0x7CA8, 0xDAEA, 0x7CA1, - 0xDAEB, 0x7D58, 0xDAEC, 0x7D6F, 0xDAED, 0x7D63, 0xDAEE, 0x7D53, 0xDAEF, 0x7D56, 0xDAF0, 0x7D67, 0xDAF1, 0x7D6A, 0xDAF2, 0x7D4F, - 0xDAF3, 0x7D6D, 0xDAF4, 0x7D5C, 0xDAF5, 0x7D6B, 0xDAF6, 0x7D52, 0xDAF7, 0x7D54, 0xDAF8, 0x7D69, 0xDAF9, 0x7D51, 0xDAFA, 0x7D5F, - 0xDAFB, 0x7D4E, 0xDAFC, 0x7F3E, 0xDAFD, 0x7F3F, 0xDAFE, 0x7F65, 0xDB40, 0x7F66, 0xDB41, 0x7FA2, 0xDB42, 0x7FA0, 0xDB43, 0x7FA1, - 0xDB44, 0x7FD7, 0xDB45, 0x8051, 0xDB46, 0x804F, 0xDB47, 0x8050, 0xDB48, 0x80FE, 0xDB49, 0x80D4, 0xDB4A, 0x8143, 0xDB4B, 0x814A, - 0xDB4C, 0x8152, 0xDB4D, 0x814F, 0xDB4E, 0x8147, 0xDB4F, 0x813D, 0xDB50, 0x814D, 0xDB51, 0x813A, 0xDB52, 0x81E6, 0xDB53, 0x81EE, - 0xDB54, 0x81F7, 0xDB55, 0x81F8, 0xDB56, 0x81F9, 0xDB57, 0x8204, 0xDB58, 0x823C, 0xDB59, 0x823D, 0xDB5A, 0x823F, 0xDB5B, 0x8275, - 0xDB5C, 0x833B, 0xDB5D, 0x83CF, 0xDB5E, 0x83F9, 0xDB5F, 0x8423, 0xDB60, 0x83C0, 0xDB61, 0x83E8, 0xDB62, 0x8412, 0xDB63, 0x83E7, - 0xDB64, 0x83E4, 0xDB65, 0x83FC, 0xDB66, 0x83F6, 0xDB67, 0x8410, 0xDB68, 0x83C6, 0xDB69, 0x83C8, 0xDB6A, 0x83EB, 0xDB6B, 0x83E3, - 0xDB6C, 0x83BF, 0xDB6D, 0x8401, 0xDB6E, 0x83DD, 0xDB6F, 0x83E5, 0xDB70, 0x83D8, 0xDB71, 0x83FF, 0xDB72, 0x83E1, 0xDB73, 0x83CB, - 0xDB74, 0x83CE, 0xDB75, 0x83D6, 0xDB76, 0x83F5, 0xDB77, 0x83C9, 0xDB78, 0x8409, 0xDB79, 0x840F, 0xDB7A, 0x83DE, 0xDB7B, 0x8411, - 0xDB7C, 0x8406, 0xDB7D, 0x83C2, 0xDB7E, 0x83F3, 0xDBA1, 0x83D5, 0xDBA2, 0x83FA, 0xDBA3, 0x83C7, 0xDBA4, 0x83D1, 0xDBA5, 0x83EA, - 0xDBA6, 0x8413, 0xDBA7, 0x83C3, 0xDBA8, 0x83EC, 0xDBA9, 0x83EE, 0xDBAA, 0x83C4, 0xDBAB, 0x83FB, 0xDBAC, 0x83D7, 0xDBAD, 0x83E2, - 0xDBAE, 0x841B, 0xDBAF, 0x83DB, 0xDBB0, 0x83FE, 0xDBB1, 0x86D8, 0xDBB2, 0x86E2, 0xDBB3, 0x86E6, 0xDBB4, 0x86D3, 0xDBB5, 0x86E3, - 0xDBB6, 0x86DA, 0xDBB7, 0x86EA, 0xDBB8, 0x86DD, 0xDBB9, 0x86EB, 0xDBBA, 0x86DC, 0xDBBB, 0x86EC, 0xDBBC, 0x86E9, 0xDBBD, 0x86D7, - 0xDBBE, 0x86E8, 0xDBBF, 0x86D1, 0xDBC0, 0x8848, 0xDBC1, 0x8856, 0xDBC2, 0x8855, 0xDBC3, 0x88BA, 0xDBC4, 0x88D7, 0xDBC5, 0x88B9, - 0xDBC6, 0x88B8, 0xDBC7, 0x88C0, 0xDBC8, 0x88BE, 0xDBC9, 0x88B6, 0xDBCA, 0x88BC, 0xDBCB, 0x88B7, 0xDBCC, 0x88BD, 0xDBCD, 0x88B2, - 0xDBCE, 0x8901, 0xDBCF, 0x88C9, 0xDBD0, 0x8995, 0xDBD1, 0x8998, 0xDBD2, 0x8997, 0xDBD3, 0x89DD, 0xDBD4, 0x89DA, 0xDBD5, 0x89DB, - 0xDBD6, 0x8A4E, 0xDBD7, 0x8A4D, 0xDBD8, 0x8A39, 0xDBD9, 0x8A59, 0xDBDA, 0x8A40, 0xDBDB, 0x8A57, 0xDBDC, 0x8A58, 0xDBDD, 0x8A44, - 0xDBDE, 0x8A45, 0xDBDF, 0x8A52, 0xDBE0, 0x8A48, 0xDBE1, 0x8A51, 0xDBE2, 0x8A4A, 0xDBE3, 0x8A4C, 0xDBE4, 0x8A4F, 0xDBE5, 0x8C5F, - 0xDBE6, 0x8C81, 0xDBE7, 0x8C80, 0xDBE8, 0x8CBA, 0xDBE9, 0x8CBE, 0xDBEA, 0x8CB0, 0xDBEB, 0x8CB9, 0xDBEC, 0x8CB5, 0xDBED, 0x8D84, - 0xDBEE, 0x8D80, 0xDBEF, 0x8D89, 0xDBF0, 0x8DD8, 0xDBF1, 0x8DD3, 0xDBF2, 0x8DCD, 0xDBF3, 0x8DC7, 0xDBF4, 0x8DD6, 0xDBF5, 0x8DDC, - 0xDBF6, 0x8DCF, 0xDBF7, 0x8DD5, 0xDBF8, 0x8DD9, 0xDBF9, 0x8DC8, 0xDBFA, 0x8DD7, 0xDBFB, 0x8DC5, 0xDBFC, 0x8EEF, 0xDBFD, 0x8EF7, - 0xDBFE, 0x8EFA, 0xDC40, 0x8EF9, 0xDC41, 0x8EE6, 0xDC42, 0x8EEE, 0xDC43, 0x8EE5, 0xDC44, 0x8EF5, 0xDC45, 0x8EE7, 0xDC46, 0x8EE8, - 0xDC47, 0x8EF6, 0xDC48, 0x8EEB, 0xDC49, 0x8EF1, 0xDC4A, 0x8EEC, 0xDC4B, 0x8EF4, 0xDC4C, 0x8EE9, 0xDC4D, 0x902D, 0xDC4E, 0x9034, - 0xDC4F, 0x902F, 0xDC50, 0x9106, 0xDC51, 0x912C, 0xDC52, 0x9104, 0xDC53, 0x90FF, 0xDC54, 0x90FC, 0xDC55, 0x9108, 0xDC56, 0x90F9, - 0xDC57, 0x90FB, 0xDC58, 0x9101, 0xDC59, 0x9100, 0xDC5A, 0x9107, 0xDC5B, 0x9105, 0xDC5C, 0x9103, 0xDC5D, 0x9161, 0xDC5E, 0x9164, - 0xDC5F, 0x915F, 0xDC60, 0x9162, 0xDC61, 0x9160, 0xDC62, 0x9201, 0xDC63, 0x920A, 0xDC64, 0x9225, 0xDC65, 0x9203, 0xDC66, 0x921A, - 0xDC67, 0x9226, 0xDC68, 0x920F, 0xDC69, 0x920C, 0xDC6A, 0x9200, 0xDC6B, 0x9212, 0xDC6C, 0x91FF, 0xDC6D, 0x91FD, 0xDC6E, 0x9206, - 0xDC6F, 0x9204, 0xDC70, 0x9227, 0xDC71, 0x9202, 0xDC72, 0x921C, 0xDC73, 0x9224, 0xDC74, 0x9219, 0xDC75, 0x9217, 0xDC76, 0x9205, - 0xDC77, 0x9216, 0xDC78, 0x957B, 0xDC79, 0x958D, 0xDC7A, 0x958C, 0xDC7B, 0x9590, 0xDC7C, 0x9687, 0xDC7D, 0x967E, 0xDC7E, 0x9688, - 0xDCA1, 0x9689, 0xDCA2, 0x9683, 0xDCA3, 0x9680, 0xDCA4, 0x96C2, 0xDCA5, 0x96C8, 0xDCA6, 0x96C3, 0xDCA7, 0x96F1, 0xDCA8, 0x96F0, - 0xDCA9, 0x976C, 0xDCAA, 0x9770, 0xDCAB, 0x976E, 0xDCAC, 0x9807, 0xDCAD, 0x98A9, 0xDCAE, 0x98EB, 0xDCAF, 0x9CE6, 0xDCB0, 0x9EF9, - 0xDCB1, 0x4E83, 0xDCB2, 0x4E84, 0xDCB3, 0x4EB6, 0xDCB4, 0x50BD, 0xDCB5, 0x50BF, 0xDCB6, 0x50C6, 0xDCB7, 0x50AE, 0xDCB8, 0x50C4, - 0xDCB9, 0x50CA, 0xDCBA, 0x50B4, 0xDCBB, 0x50C8, 0xDCBC, 0x50C2, 0xDCBD, 0x50B0, 0xDCBE, 0x50C1, 0xDCBF, 0x50BA, 0xDCC0, 0x50B1, - 0xDCC1, 0x50CB, 0xDCC2, 0x50C9, 0xDCC3, 0x50B6, 0xDCC4, 0x50B8, 0xDCC5, 0x51D7, 0xDCC6, 0x527A, 0xDCC7, 0x5278, 0xDCC8, 0x527B, - 0xDCC9, 0x527C, 0xDCCA, 0x55C3, 0xDCCB, 0x55DB, 0xDCCC, 0x55CC, 0xDCCD, 0x55D0, 0xDCCE, 0x55CB, 0xDCCF, 0x55CA, 0xDCD0, 0x55DD, - 0xDCD1, 0x55C0, 0xDCD2, 0x55D4, 0xDCD3, 0x55C4, 0xDCD4, 0x55E9, 0xDCD5, 0x55BF, 0xDCD6, 0x55D2, 0xDCD7, 0x558D, 0xDCD8, 0x55CF, - 0xDCD9, 0x55D5, 0xDCDA, 0x55E2, 0xDCDB, 0x55D6, 0xDCDC, 0x55C8, 0xDCDD, 0x55F2, 0xDCDE, 0x55CD, 0xDCDF, 0x55D9, 0xDCE0, 0x55C2, - 0xDCE1, 0x5714, 0xDCE2, 0x5853, 0xDCE3, 0x5868, 0xDCE4, 0x5864, 0xDCE5, 0x584F, 0xDCE6, 0x584D, 0xDCE7, 0x5849, 0xDCE8, 0x586F, - 0xDCE9, 0x5855, 0xDCEA, 0x584E, 0xDCEB, 0x585D, 0xDCEC, 0x5859, 0xDCED, 0x5865, 0xDCEE, 0x585B, 0xDCEF, 0x583D, 0xDCF0, 0x5863, - 0xDCF1, 0x5871, 0xDCF2, 0x58FC, 0xDCF3, 0x5AC7, 0xDCF4, 0x5AC4, 0xDCF5, 0x5ACB, 0xDCF6, 0x5ABA, 0xDCF7, 0x5AB8, 0xDCF8, 0x5AB1, - 0xDCF9, 0x5AB5, 0xDCFA, 0x5AB0, 0xDCFB, 0x5ABF, 0xDCFC, 0x5AC8, 0xDCFD, 0x5ABB, 0xDCFE, 0x5AC6, 0xDD40, 0x5AB7, 0xDD41, 0x5AC0, - 0xDD42, 0x5ACA, 0xDD43, 0x5AB4, 0xDD44, 0x5AB6, 0xDD45, 0x5ACD, 0xDD46, 0x5AB9, 0xDD47, 0x5A90, 0xDD48, 0x5BD6, 0xDD49, 0x5BD8, - 0xDD4A, 0x5BD9, 0xDD4B, 0x5C1F, 0xDD4C, 0x5C33, 0xDD4D, 0x5D71, 0xDD4E, 0x5D63, 0xDD4F, 0x5D4A, 0xDD50, 0x5D65, 0xDD51, 0x5D72, - 0xDD52, 0x5D6C, 0xDD53, 0x5D5E, 0xDD54, 0x5D68, 0xDD55, 0x5D67, 0xDD56, 0x5D62, 0xDD57, 0x5DF0, 0xDD58, 0x5E4F, 0xDD59, 0x5E4E, - 0xDD5A, 0x5E4A, 0xDD5B, 0x5E4D, 0xDD5C, 0x5E4B, 0xDD5D, 0x5EC5, 0xDD5E, 0x5ECC, 0xDD5F, 0x5EC6, 0xDD60, 0x5ECB, 0xDD61, 0x5EC7, - 0xDD62, 0x5F40, 0xDD63, 0x5FAF, 0xDD64, 0x5FAD, 0xDD65, 0x60F7, 0xDD66, 0x6149, 0xDD67, 0x614A, 0xDD68, 0x612B, 0xDD69, 0x6145, - 0xDD6A, 0x6136, 0xDD6B, 0x6132, 0xDD6C, 0x612E, 0xDD6D, 0x6146, 0xDD6E, 0x612F, 0xDD6F, 0x614F, 0xDD70, 0x6129, 0xDD71, 0x6140, - 0xDD72, 0x6220, 0xDD73, 0x9168, 0xDD74, 0x6223, 0xDD75, 0x6225, 0xDD76, 0x6224, 0xDD77, 0x63C5, 0xDD78, 0x63F1, 0xDD79, 0x63EB, - 0xDD7A, 0x6410, 0xDD7B, 0x6412, 0xDD7C, 0x6409, 0xDD7D, 0x6420, 0xDD7E, 0x6424, 0xDDA1, 0x6433, 0xDDA2, 0x6443, 0xDDA3, 0x641F, - 0xDDA4, 0x6415, 0xDDA5, 0x6418, 0xDDA6, 0x6439, 0xDDA7, 0x6437, 0xDDA8, 0x6422, 0xDDA9, 0x6423, 0xDDAA, 0x640C, 0xDDAB, 0x6426, - 0xDDAC, 0x6430, 0xDDAD, 0x6428, 0xDDAE, 0x6441, 0xDDAF, 0x6435, 0xDDB0, 0x642F, 0xDDB1, 0x640A, 0xDDB2, 0x641A, 0xDDB3, 0x6440, - 0xDDB4, 0x6425, 0xDDB5, 0x6427, 0xDDB6, 0x640B, 0xDDB7, 0x63E7, 0xDDB8, 0x641B, 0xDDB9, 0x642E, 0xDDBA, 0x6421, 0xDDBB, 0x640E, - 0xDDBC, 0x656F, 0xDDBD, 0x6592, 0xDDBE, 0x65D3, 0xDDBF, 0x6686, 0xDDC0, 0x668C, 0xDDC1, 0x6695, 0xDDC2, 0x6690, 0xDDC3, 0x668B, - 0xDDC4, 0x668A, 0xDDC5, 0x6699, 0xDDC6, 0x6694, 0xDDC7, 0x6678, 0xDDC8, 0x6720, 0xDDC9, 0x6966, 0xDDCA, 0x695F, 0xDDCB, 0x6938, - 0xDDCC, 0x694E, 0xDDCD, 0x6962, 0xDDCE, 0x6971, 0xDDCF, 0x693F, 0xDDD0, 0x6945, 0xDDD1, 0x696A, 0xDDD2, 0x6939, 0xDDD3, 0x6942, - 0xDDD4, 0x6957, 0xDDD5, 0x6959, 0xDDD6, 0x697A, 0xDDD7, 0x6948, 0xDDD8, 0x6949, 0xDDD9, 0x6935, 0xDDDA, 0x696C, 0xDDDB, 0x6933, - 0xDDDC, 0x693D, 0xDDDD, 0x6965, 0xDDDE, 0x68F0, 0xDDDF, 0x6978, 0xDDE0, 0x6934, 0xDDE1, 0x6969, 0xDDE2, 0x6940, 0xDDE3, 0x696F, - 0xDDE4, 0x6944, 0xDDE5, 0x6976, 0xDDE6, 0x6958, 0xDDE7, 0x6941, 0xDDE8, 0x6974, 0xDDE9, 0x694C, 0xDDEA, 0x693B, 0xDDEB, 0x694B, - 0xDDEC, 0x6937, 0xDDED, 0x695C, 0xDDEE, 0x694F, 0xDDEF, 0x6951, 0xDDF0, 0x6932, 0xDDF1, 0x6952, 0xDDF2, 0x692F, 0xDDF3, 0x697B, - 0xDDF4, 0x693C, 0xDDF5, 0x6B46, 0xDDF6, 0x6B45, 0xDDF7, 0x6B43, 0xDDF8, 0x6B42, 0xDDF9, 0x6B48, 0xDDFA, 0x6B41, 0xDDFB, 0x6B9B, - 0xDDFC, 0xFA0D, 0xDDFD, 0x6BFB, 0xDDFE, 0x6BFC, 0xDE40, 0x6BF9, 0xDE41, 0x6BF7, 0xDE42, 0x6BF8, 0xDE43, 0x6E9B, 0xDE44, 0x6ED6, - 0xDE45, 0x6EC8, 0xDE46, 0x6E8F, 0xDE47, 0x6EC0, 0xDE48, 0x6E9F, 0xDE49, 0x6E93, 0xDE4A, 0x6E94, 0xDE4B, 0x6EA0, 0xDE4C, 0x6EB1, - 0xDE4D, 0x6EB9, 0xDE4E, 0x6EC6, 0xDE4F, 0x6ED2, 0xDE50, 0x6EBD, 0xDE51, 0x6EC1, 0xDE52, 0x6E9E, 0xDE53, 0x6EC9, 0xDE54, 0x6EB7, - 0xDE55, 0x6EB0, 0xDE56, 0x6ECD, 0xDE57, 0x6EA6, 0xDE58, 0x6ECF, 0xDE59, 0x6EB2, 0xDE5A, 0x6EBE, 0xDE5B, 0x6EC3, 0xDE5C, 0x6EDC, - 0xDE5D, 0x6ED8, 0xDE5E, 0x6E99, 0xDE5F, 0x6E92, 0xDE60, 0x6E8E, 0xDE61, 0x6E8D, 0xDE62, 0x6EA4, 0xDE63, 0x6EA1, 0xDE64, 0x6EBF, - 0xDE65, 0x6EB3, 0xDE66, 0x6ED0, 0xDE67, 0x6ECA, 0xDE68, 0x6E97, 0xDE69, 0x6EAE, 0xDE6A, 0x6EA3, 0xDE6B, 0x7147, 0xDE6C, 0x7154, - 0xDE6D, 0x7152, 0xDE6E, 0x7163, 0xDE6F, 0x7160, 0xDE70, 0x7141, 0xDE71, 0x715D, 0xDE72, 0x7162, 0xDE73, 0x7172, 0xDE74, 0x7178, - 0xDE75, 0x716A, 0xDE76, 0x7161, 0xDE77, 0x7142, 0xDE78, 0x7158, 0xDE79, 0x7143, 0xDE7A, 0x714B, 0xDE7B, 0x7170, 0xDE7C, 0x715F, - 0xDE7D, 0x7150, 0xDE7E, 0x7153, 0xDEA1, 0x7144, 0xDEA2, 0x714D, 0xDEA3, 0x715A, 0xDEA4, 0x724F, 0xDEA5, 0x728D, 0xDEA6, 0x728C, - 0xDEA7, 0x7291, 0xDEA8, 0x7290, 0xDEA9, 0x728E, 0xDEAA, 0x733C, 0xDEAB, 0x7342, 0xDEAC, 0x733B, 0xDEAD, 0x733A, 0xDEAE, 0x7340, - 0xDEAF, 0x734A, 0xDEB0, 0x7349, 0xDEB1, 0x7444, 0xDEB2, 0x744A, 0xDEB3, 0x744B, 0xDEB4, 0x7452, 0xDEB5, 0x7451, 0xDEB6, 0x7457, - 0xDEB7, 0x7440, 0xDEB8, 0x744F, 0xDEB9, 0x7450, 0xDEBA, 0x744E, 0xDEBB, 0x7442, 0xDEBC, 0x7446, 0xDEBD, 0x744D, 0xDEBE, 0x7454, - 0xDEBF, 0x74E1, 0xDEC0, 0x74FF, 0xDEC1, 0x74FE, 0xDEC2, 0x74FD, 0xDEC3, 0x751D, 0xDEC4, 0x7579, 0xDEC5, 0x7577, 0xDEC6, 0x6983, - 0xDEC7, 0x75EF, 0xDEC8, 0x760F, 0xDEC9, 0x7603, 0xDECA, 0x75F7, 0xDECB, 0x75FE, 0xDECC, 0x75FC, 0xDECD, 0x75F9, 0xDECE, 0x75F8, - 0xDECF, 0x7610, 0xDED0, 0x75FB, 0xDED1, 0x75F6, 0xDED2, 0x75ED, 0xDED3, 0x75F5, 0xDED4, 0x75FD, 0xDED5, 0x7699, 0xDED6, 0x76B5, - 0xDED7, 0x76DD, 0xDED8, 0x7755, 0xDED9, 0x775F, 0xDEDA, 0x7760, 0xDEDB, 0x7752, 0xDEDC, 0x7756, 0xDEDD, 0x775A, 0xDEDE, 0x7769, - 0xDEDF, 0x7767, 0xDEE0, 0x7754, 0xDEE1, 0x7759, 0xDEE2, 0x776D, 0xDEE3, 0x77E0, 0xDEE4, 0x7887, 0xDEE5, 0x789A, 0xDEE6, 0x7894, - 0xDEE7, 0x788F, 0xDEE8, 0x7884, 0xDEE9, 0x7895, 0xDEEA, 0x7885, 0xDEEB, 0x7886, 0xDEEC, 0x78A1, 0xDEED, 0x7883, 0xDEEE, 0x7879, - 0xDEEF, 0x7899, 0xDEF0, 0x7880, 0xDEF1, 0x7896, 0xDEF2, 0x787B, 0xDEF3, 0x797C, 0xDEF4, 0x7982, 0xDEF5, 0x797D, 0xDEF6, 0x7979, - 0xDEF7, 0x7A11, 0xDEF8, 0x7A18, 0xDEF9, 0x7A19, 0xDEFA, 0x7A12, 0xDEFB, 0x7A17, 0xDEFC, 0x7A15, 0xDEFD, 0x7A22, 0xDEFE, 0x7A13, - 0xDF40, 0x7A1B, 0xDF41, 0x7A10, 0xDF42, 0x7AA3, 0xDF43, 0x7AA2, 0xDF44, 0x7A9E, 0xDF45, 0x7AEB, 0xDF46, 0x7B66, 0xDF47, 0x7B64, - 0xDF48, 0x7B6D, 0xDF49, 0x7B74, 0xDF4A, 0x7B69, 0xDF4B, 0x7B72, 0xDF4C, 0x7B65, 0xDF4D, 0x7B73, 0xDF4E, 0x7B71, 0xDF4F, 0x7B70, - 0xDF50, 0x7B61, 0xDF51, 0x7B78, 0xDF52, 0x7B76, 0xDF53, 0x7B63, 0xDF54, 0x7CB2, 0xDF55, 0x7CB4, 0xDF56, 0x7CAF, 0xDF57, 0x7D88, - 0xDF58, 0x7D86, 0xDF59, 0x7D80, 0xDF5A, 0x7D8D, 0xDF5B, 0x7D7F, 0xDF5C, 0x7D85, 0xDF5D, 0x7D7A, 0xDF5E, 0x7D8E, 0xDF5F, 0x7D7B, - 0xDF60, 0x7D83, 0xDF61, 0x7D7C, 0xDF62, 0x7D8C, 0xDF63, 0x7D94, 0xDF64, 0x7D84, 0xDF65, 0x7D7D, 0xDF66, 0x7D92, 0xDF67, 0x7F6D, - 0xDF68, 0x7F6B, 0xDF69, 0x7F67, 0xDF6A, 0x7F68, 0xDF6B, 0x7F6C, 0xDF6C, 0x7FA6, 0xDF6D, 0x7FA5, 0xDF6E, 0x7FA7, 0xDF6F, 0x7FDB, - 0xDF70, 0x7FDC, 0xDF71, 0x8021, 0xDF72, 0x8164, 0xDF73, 0x8160, 0xDF74, 0x8177, 0xDF75, 0x815C, 0xDF76, 0x8169, 0xDF77, 0x815B, - 0xDF78, 0x8162, 0xDF79, 0x8172, 0xDF7A, 0x6721, 0xDF7B, 0x815E, 0xDF7C, 0x8176, 0xDF7D, 0x8167, 0xDF7E, 0x816F, 0xDFA1, 0x8144, - 0xDFA2, 0x8161, 0xDFA3, 0x821D, 0xDFA4, 0x8249, 0xDFA5, 0x8244, 0xDFA6, 0x8240, 0xDFA7, 0x8242, 0xDFA8, 0x8245, 0xDFA9, 0x84F1, - 0xDFAA, 0x843F, 0xDFAB, 0x8456, 0xDFAC, 0x8476, 0xDFAD, 0x8479, 0xDFAE, 0x848F, 0xDFAF, 0x848D, 0xDFB0, 0x8465, 0xDFB1, 0x8451, - 0xDFB2, 0x8440, 0xDFB3, 0x8486, 0xDFB4, 0x8467, 0xDFB5, 0x8430, 0xDFB6, 0x844D, 0xDFB7, 0x847D, 0xDFB8, 0x845A, 0xDFB9, 0x8459, - 0xDFBA, 0x8474, 0xDFBB, 0x8473, 0xDFBC, 0x845D, 0xDFBD, 0x8507, 0xDFBE, 0x845E, 0xDFBF, 0x8437, 0xDFC0, 0x843A, 0xDFC1, 0x8434, - 0xDFC2, 0x847A, 0xDFC3, 0x8443, 0xDFC4, 0x8478, 0xDFC5, 0x8432, 0xDFC6, 0x8445, 0xDFC7, 0x8429, 0xDFC8, 0x83D9, 0xDFC9, 0x844B, - 0xDFCA, 0x842F, 0xDFCB, 0x8442, 0xDFCC, 0x842D, 0xDFCD, 0x845F, 0xDFCE, 0x8470, 0xDFCF, 0x8439, 0xDFD0, 0x844E, 0xDFD1, 0x844C, - 0xDFD2, 0x8452, 0xDFD3, 0x846F, 0xDFD4, 0x84C5, 0xDFD5, 0x848E, 0xDFD6, 0x843B, 0xDFD7, 0x8447, 0xDFD8, 0x8436, 0xDFD9, 0x8433, - 0xDFDA, 0x8468, 0xDFDB, 0x847E, 0xDFDC, 0x8444, 0xDFDD, 0x842B, 0xDFDE, 0x8460, 0xDFDF, 0x8454, 0xDFE0, 0x846E, 0xDFE1, 0x8450, - 0xDFE2, 0x870B, 0xDFE3, 0x8704, 0xDFE4, 0x86F7, 0xDFE5, 0x870C, 0xDFE6, 0x86FA, 0xDFE7, 0x86D6, 0xDFE8, 0x86F5, 0xDFE9, 0x874D, - 0xDFEA, 0x86F8, 0xDFEB, 0x870E, 0xDFEC, 0x8709, 0xDFED, 0x8701, 0xDFEE, 0x86F6, 0xDFEF, 0x870D, 0xDFF0, 0x8705, 0xDFF1, 0x88D6, - 0xDFF2, 0x88CB, 0xDFF3, 0x88CD, 0xDFF4, 0x88CE, 0xDFF5, 0x88DE, 0xDFF6, 0x88DB, 0xDFF7, 0x88DA, 0xDFF8, 0x88CC, 0xDFF9, 0x88D0, - 0xDFFA, 0x8985, 0xDFFB, 0x899B, 0xDFFC, 0x89DF, 0xDFFD, 0x89E5, 0xDFFE, 0x89E4, 0xE040, 0x89E1, 0xE041, 0x89E0, 0xE042, 0x89E2, - 0xE043, 0x89DC, 0xE044, 0x89E6, 0xE045, 0x8A76, 0xE046, 0x8A86, 0xE047, 0x8A7F, 0xE048, 0x8A61, 0xE049, 0x8A3F, 0xE04A, 0x8A77, - 0xE04B, 0x8A82, 0xE04C, 0x8A84, 0xE04D, 0x8A75, 0xE04E, 0x8A83, 0xE04F, 0x8A81, 0xE050, 0x8A74, 0xE051, 0x8A7A, 0xE052, 0x8C3C, - 0xE053, 0x8C4B, 0xE054, 0x8C4A, 0xE055, 0x8C65, 0xE056, 0x8C64, 0xE057, 0x8C66, 0xE058, 0x8C86, 0xE059, 0x8C84, 0xE05A, 0x8C85, - 0xE05B, 0x8CCC, 0xE05C, 0x8D68, 0xE05D, 0x8D69, 0xE05E, 0x8D91, 0xE05F, 0x8D8C, 0xE060, 0x8D8E, 0xE061, 0x8D8F, 0xE062, 0x8D8D, - 0xE063, 0x8D93, 0xE064, 0x8D94, 0xE065, 0x8D90, 0xE066, 0x8D92, 0xE067, 0x8DF0, 0xE068, 0x8DE0, 0xE069, 0x8DEC, 0xE06A, 0x8DF1, - 0xE06B, 0x8DEE, 0xE06C, 0x8DD0, 0xE06D, 0x8DE9, 0xE06E, 0x8DE3, 0xE06F, 0x8DE2, 0xE070, 0x8DE7, 0xE071, 0x8DF2, 0xE072, 0x8DEB, - 0xE073, 0x8DF4, 0xE074, 0x8F06, 0xE075, 0x8EFF, 0xE076, 0x8F01, 0xE077, 0x8F00, 0xE078, 0x8F05, 0xE079, 0x8F07, 0xE07A, 0x8F08, - 0xE07B, 0x8F02, 0xE07C, 0x8F0B, 0xE07D, 0x9052, 0xE07E, 0x903F, 0xE0A1, 0x9044, 0xE0A2, 0x9049, 0xE0A3, 0x903D, 0xE0A4, 0x9110, - 0xE0A5, 0x910D, 0xE0A6, 0x910F, 0xE0A7, 0x9111, 0xE0A8, 0x9116, 0xE0A9, 0x9114, 0xE0AA, 0x910B, 0xE0AB, 0x910E, 0xE0AC, 0x916E, - 0xE0AD, 0x916F, 0xE0AE, 0x9248, 0xE0AF, 0x9252, 0xE0B0, 0x9230, 0xE0B1, 0x923A, 0xE0B2, 0x9266, 0xE0B3, 0x9233, 0xE0B4, 0x9265, - 0xE0B5, 0x925E, 0xE0B6, 0x9283, 0xE0B7, 0x922E, 0xE0B8, 0x924A, 0xE0B9, 0x9246, 0xE0BA, 0x926D, 0xE0BB, 0x926C, 0xE0BC, 0x924F, - 0xE0BD, 0x9260, 0xE0BE, 0x9267, 0xE0BF, 0x926F, 0xE0C0, 0x9236, 0xE0C1, 0x9261, 0xE0C2, 0x9270, 0xE0C3, 0x9231, 0xE0C4, 0x9254, - 0xE0C5, 0x9263, 0xE0C6, 0x9250, 0xE0C7, 0x9272, 0xE0C8, 0x924E, 0xE0C9, 0x9253, 0xE0CA, 0x924C, 0xE0CB, 0x9256, 0xE0CC, 0x9232, - 0xE0CD, 0x959F, 0xE0CE, 0x959C, 0xE0CF, 0x959E, 0xE0D0, 0x959B, 0xE0D1, 0x9692, 0xE0D2, 0x9693, 0xE0D3, 0x9691, 0xE0D4, 0x9697, - 0xE0D5, 0x96CE, 0xE0D6, 0x96FA, 0xE0D7, 0x96FD, 0xE0D8, 0x96F8, 0xE0D9, 0x96F5, 0xE0DA, 0x9773, 0xE0DB, 0x9777, 0xE0DC, 0x9778, - 0xE0DD, 0x9772, 0xE0DE, 0x980F, 0xE0DF, 0x980D, 0xE0E0, 0x980E, 0xE0E1, 0x98AC, 0xE0E2, 0x98F6, 0xE0E3, 0x98F9, 0xE0E4, 0x99AF, - 0xE0E5, 0x99B2, 0xE0E6, 0x99B0, 0xE0E7, 0x99B5, 0xE0E8, 0x9AAD, 0xE0E9, 0x9AAB, 0xE0EA, 0x9B5B, 0xE0EB, 0x9CEA, 0xE0EC, 0x9CED, - 0xE0ED, 0x9CE7, 0xE0EE, 0x9E80, 0xE0EF, 0x9EFD, 0xE0F0, 0x50E6, 0xE0F1, 0x50D4, 0xE0F2, 0x50D7, 0xE0F3, 0x50E8, 0xE0F4, 0x50F3, - 0xE0F5, 0x50DB, 0xE0F6, 0x50EA, 0xE0F7, 0x50DD, 0xE0F8, 0x50E4, 0xE0F9, 0x50D3, 0xE0FA, 0x50EC, 0xE0FB, 0x50F0, 0xE0FC, 0x50EF, - 0xE0FD, 0x50E3, 0xE0FE, 0x50E0, 0xE140, 0x51D8, 0xE141, 0x5280, 0xE142, 0x5281, 0xE143, 0x52E9, 0xE144, 0x52EB, 0xE145, 0x5330, - 0xE146, 0x53AC, 0xE147, 0x5627, 0xE148, 0x5615, 0xE149, 0x560C, 0xE14A, 0x5612, 0xE14B, 0x55FC, 0xE14C, 0x560F, 0xE14D, 0x561C, - 0xE14E, 0x5601, 0xE14F, 0x5613, 0xE150, 0x5602, 0xE151, 0x55FA, 0xE152, 0x561D, 0xE153, 0x5604, 0xE154, 0x55FF, 0xE155, 0x55F9, - 0xE156, 0x5889, 0xE157, 0x587C, 0xE158, 0x5890, 0xE159, 0x5898, 0xE15A, 0x5886, 0xE15B, 0x5881, 0xE15C, 0x587F, 0xE15D, 0x5874, - 0xE15E, 0x588B, 0xE15F, 0x587A, 0xE160, 0x5887, 0xE161, 0x5891, 0xE162, 0x588E, 0xE163, 0x5876, 0xE164, 0x5882, 0xE165, 0x5888, - 0xE166, 0x587B, 0xE167, 0x5894, 0xE168, 0x588F, 0xE169, 0x58FE, 0xE16A, 0x596B, 0xE16B, 0x5ADC, 0xE16C, 0x5AEE, 0xE16D, 0x5AE5, - 0xE16E, 0x5AD5, 0xE16F, 0x5AEA, 0xE170, 0x5ADA, 0xE171, 0x5AED, 0xE172, 0x5AEB, 0xE173, 0x5AF3, 0xE174, 0x5AE2, 0xE175, 0x5AE0, - 0xE176, 0x5ADB, 0xE177, 0x5AEC, 0xE178, 0x5ADE, 0xE179, 0x5ADD, 0xE17A, 0x5AD9, 0xE17B, 0x5AE8, 0xE17C, 0x5ADF, 0xE17D, 0x5B77, - 0xE17E, 0x5BE0, 0xE1A1, 0x5BE3, 0xE1A2, 0x5C63, 0xE1A3, 0x5D82, 0xE1A4, 0x5D80, 0xE1A5, 0x5D7D, 0xE1A6, 0x5D86, 0xE1A7, 0x5D7A, - 0xE1A8, 0x5D81, 0xE1A9, 0x5D77, 0xE1AA, 0x5D8A, 0xE1AB, 0x5D89, 0xE1AC, 0x5D88, 0xE1AD, 0x5D7E, 0xE1AE, 0x5D7C, 0xE1AF, 0x5D8D, - 0xE1B0, 0x5D79, 0xE1B1, 0x5D7F, 0xE1B2, 0x5E58, 0xE1B3, 0x5E59, 0xE1B4, 0x5E53, 0xE1B5, 0x5ED8, 0xE1B6, 0x5ED1, 0xE1B7, 0x5ED7, - 0xE1B8, 0x5ECE, 0xE1B9, 0x5EDC, 0xE1BA, 0x5ED5, 0xE1BB, 0x5ED9, 0xE1BC, 0x5ED2, 0xE1BD, 0x5ED4, 0xE1BE, 0x5F44, 0xE1BF, 0x5F43, - 0xE1C0, 0x5F6F, 0xE1C1, 0x5FB6, 0xE1C2, 0x612C, 0xE1C3, 0x6128, 0xE1C4, 0x6141, 0xE1C5, 0x615E, 0xE1C6, 0x6171, 0xE1C7, 0x6173, - 0xE1C8, 0x6152, 0xE1C9, 0x6153, 0xE1CA, 0x6172, 0xE1CB, 0x616C, 0xE1CC, 0x6180, 0xE1CD, 0x6174, 0xE1CE, 0x6154, 0xE1CF, 0x617A, - 0xE1D0, 0x615B, 0xE1D1, 0x6165, 0xE1D2, 0x613B, 0xE1D3, 0x616A, 0xE1D4, 0x6161, 0xE1D5, 0x6156, 0xE1D6, 0x6229, 0xE1D7, 0x6227, - 0xE1D8, 0x622B, 0xE1D9, 0x642B, 0xE1DA, 0x644D, 0xE1DB, 0x645B, 0xE1DC, 0x645D, 0xE1DD, 0x6474, 0xE1DE, 0x6476, 0xE1DF, 0x6472, - 0xE1E0, 0x6473, 0xE1E1, 0x647D, 0xE1E2, 0x6475, 0xE1E3, 0x6466, 0xE1E4, 0x64A6, 0xE1E5, 0x644E, 0xE1E6, 0x6482, 0xE1E7, 0x645E, - 0xE1E8, 0x645C, 0xE1E9, 0x644B, 0xE1EA, 0x6453, 0xE1EB, 0x6460, 0xE1EC, 0x6450, 0xE1ED, 0x647F, 0xE1EE, 0x643F, 0xE1EF, 0x646C, - 0xE1F0, 0x646B, 0xE1F1, 0x6459, 0xE1F2, 0x6465, 0xE1F3, 0x6477, 0xE1F4, 0x6573, 0xE1F5, 0x65A0, 0xE1F6, 0x66A1, 0xE1F7, 0x66A0, - 0xE1F8, 0x669F, 0xE1F9, 0x6705, 0xE1FA, 0x6704, 0xE1FB, 0x6722, 0xE1FC, 0x69B1, 0xE1FD, 0x69B6, 0xE1FE, 0x69C9, 0xE240, 0x69A0, - 0xE241, 0x69CE, 0xE242, 0x6996, 0xE243, 0x69B0, 0xE244, 0x69AC, 0xE245, 0x69BC, 0xE246, 0x6991, 0xE247, 0x6999, 0xE248, 0x698E, - 0xE249, 0x69A7, 0xE24A, 0x698D, 0xE24B, 0x69A9, 0xE24C, 0x69BE, 0xE24D, 0x69AF, 0xE24E, 0x69BF, 0xE24F, 0x69C4, 0xE250, 0x69BD, - 0xE251, 0x69A4, 0xE252, 0x69D4, 0xE253, 0x69B9, 0xE254, 0x69CA, 0xE255, 0x699A, 0xE256, 0x69CF, 0xE257, 0x69B3, 0xE258, 0x6993, - 0xE259, 0x69AA, 0xE25A, 0x69A1, 0xE25B, 0x699E, 0xE25C, 0x69D9, 0xE25D, 0x6997, 0xE25E, 0x6990, 0xE25F, 0x69C2, 0xE260, 0x69B5, - 0xE261, 0x69A5, 0xE262, 0x69C6, 0xE263, 0x6B4A, 0xE264, 0x6B4D, 0xE265, 0x6B4B, 0xE266, 0x6B9E, 0xE267, 0x6B9F, 0xE268, 0x6BA0, - 0xE269, 0x6BC3, 0xE26A, 0x6BC4, 0xE26B, 0x6BFE, 0xE26C, 0x6ECE, 0xE26D, 0x6EF5, 0xE26E, 0x6EF1, 0xE26F, 0x6F03, 0xE270, 0x6F25, - 0xE271, 0x6EF8, 0xE272, 0x6F37, 0xE273, 0x6EFB, 0xE274, 0x6F2E, 0xE275, 0x6F09, 0xE276, 0x6F4E, 0xE277, 0x6F19, 0xE278, 0x6F1A, - 0xE279, 0x6F27, 0xE27A, 0x6F18, 0xE27B, 0x6F3B, 0xE27C, 0x6F12, 0xE27D, 0x6EED, 0xE27E, 0x6F0A, 0xE2A1, 0x6F36, 0xE2A2, 0x6F73, - 0xE2A3, 0x6EF9, 0xE2A4, 0x6EEE, 0xE2A5, 0x6F2D, 0xE2A6, 0x6F40, 0xE2A7, 0x6F30, 0xE2A8, 0x6F3C, 0xE2A9, 0x6F35, 0xE2AA, 0x6EEB, - 0xE2AB, 0x6F07, 0xE2AC, 0x6F0E, 0xE2AD, 0x6F43, 0xE2AE, 0x6F05, 0xE2AF, 0x6EFD, 0xE2B0, 0x6EF6, 0xE2B1, 0x6F39, 0xE2B2, 0x6F1C, - 0xE2B3, 0x6EFC, 0xE2B4, 0x6F3A, 0xE2B5, 0x6F1F, 0xE2B6, 0x6F0D, 0xE2B7, 0x6F1E, 0xE2B8, 0x6F08, 0xE2B9, 0x6F21, 0xE2BA, 0x7187, - 0xE2BB, 0x7190, 0xE2BC, 0x7189, 0xE2BD, 0x7180, 0xE2BE, 0x7185, 0xE2BF, 0x7182, 0xE2C0, 0x718F, 0xE2C1, 0x717B, 0xE2C2, 0x7186, - 0xE2C3, 0x7181, 0xE2C4, 0x7197, 0xE2C5, 0x7244, 0xE2C6, 0x7253, 0xE2C7, 0x7297, 0xE2C8, 0x7295, 0xE2C9, 0x7293, 0xE2CA, 0x7343, - 0xE2CB, 0x734D, 0xE2CC, 0x7351, 0xE2CD, 0x734C, 0xE2CE, 0x7462, 0xE2CF, 0x7473, 0xE2D0, 0x7471, 0xE2D1, 0x7475, 0xE2D2, 0x7472, - 0xE2D3, 0x7467, 0xE2D4, 0x746E, 0xE2D5, 0x7500, 0xE2D6, 0x7502, 0xE2D7, 0x7503, 0xE2D8, 0x757D, 0xE2D9, 0x7590, 0xE2DA, 0x7616, - 0xE2DB, 0x7608, 0xE2DC, 0x760C, 0xE2DD, 0x7615, 0xE2DE, 0x7611, 0xE2DF, 0x760A, 0xE2E0, 0x7614, 0xE2E1, 0x76B8, 0xE2E2, 0x7781, - 0xE2E3, 0x777C, 0xE2E4, 0x7785, 0xE2E5, 0x7782, 0xE2E6, 0x776E, 0xE2E7, 0x7780, 0xE2E8, 0x776F, 0xE2E9, 0x777E, 0xE2EA, 0x7783, - 0xE2EB, 0x78B2, 0xE2EC, 0x78AA, 0xE2ED, 0x78B4, 0xE2EE, 0x78AD, 0xE2EF, 0x78A8, 0xE2F0, 0x787E, 0xE2F1, 0x78AB, 0xE2F2, 0x789E, - 0xE2F3, 0x78A5, 0xE2F4, 0x78A0, 0xE2F5, 0x78AC, 0xE2F6, 0x78A2, 0xE2F7, 0x78A4, 0xE2F8, 0x7998, 0xE2F9, 0x798A, 0xE2FA, 0x798B, - 0xE2FB, 0x7996, 0xE2FC, 0x7995, 0xE2FD, 0x7994, 0xE2FE, 0x7993, 0xE340, 0x7997, 0xE341, 0x7988, 0xE342, 0x7992, 0xE343, 0x7990, - 0xE344, 0x7A2B, 0xE345, 0x7A4A, 0xE346, 0x7A30, 0xE347, 0x7A2F, 0xE348, 0x7A28, 0xE349, 0x7A26, 0xE34A, 0x7AA8, 0xE34B, 0x7AAB, - 0xE34C, 0x7AAC, 0xE34D, 0x7AEE, 0xE34E, 0x7B88, 0xE34F, 0x7B9C, 0xE350, 0x7B8A, 0xE351, 0x7B91, 0xE352, 0x7B90, 0xE353, 0x7B96, - 0xE354, 0x7B8D, 0xE355, 0x7B8C, 0xE356, 0x7B9B, 0xE357, 0x7B8E, 0xE358, 0x7B85, 0xE359, 0x7B98, 0xE35A, 0x5284, 0xE35B, 0x7B99, - 0xE35C, 0x7BA4, 0xE35D, 0x7B82, 0xE35E, 0x7CBB, 0xE35F, 0x7CBF, 0xE360, 0x7CBC, 0xE361, 0x7CBA, 0xE362, 0x7DA7, 0xE363, 0x7DB7, - 0xE364, 0x7DC2, 0xE365, 0x7DA3, 0xE366, 0x7DAA, 0xE367, 0x7DC1, 0xE368, 0x7DC0, 0xE369, 0x7DC5, 0xE36A, 0x7D9D, 0xE36B, 0x7DCE, - 0xE36C, 0x7DC4, 0xE36D, 0x7DC6, 0xE36E, 0x7DCB, 0xE36F, 0x7DCC, 0xE370, 0x7DAF, 0xE371, 0x7DB9, 0xE372, 0x7D96, 0xE373, 0x7DBC, - 0xE374, 0x7D9F, 0xE375, 0x7DA6, 0xE376, 0x7DAE, 0xE377, 0x7DA9, 0xE378, 0x7DA1, 0xE379, 0x7DC9, 0xE37A, 0x7F73, 0xE37B, 0x7FE2, - 0xE37C, 0x7FE3, 0xE37D, 0x7FE5, 0xE37E, 0x7FDE, 0xE3A1, 0x8024, 0xE3A2, 0x805D, 0xE3A3, 0x805C, 0xE3A4, 0x8189, 0xE3A5, 0x8186, - 0xE3A6, 0x8183, 0xE3A7, 0x8187, 0xE3A8, 0x818D, 0xE3A9, 0x818C, 0xE3AA, 0x818B, 0xE3AB, 0x8215, 0xE3AC, 0x8497, 0xE3AD, 0x84A4, - 0xE3AE, 0x84A1, 0xE3AF, 0x849F, 0xE3B0, 0x84BA, 0xE3B1, 0x84CE, 0xE3B2, 0x84C2, 0xE3B3, 0x84AC, 0xE3B4, 0x84AE, 0xE3B5, 0x84AB, - 0xE3B6, 0x84B9, 0xE3B7, 0x84B4, 0xE3B8, 0x84C1, 0xE3B9, 0x84CD, 0xE3BA, 0x84AA, 0xE3BB, 0x849A, 0xE3BC, 0x84B1, 0xE3BD, 0x84D0, - 0xE3BE, 0x849D, 0xE3BF, 0x84A7, 0xE3C0, 0x84BB, 0xE3C1, 0x84A2, 0xE3C2, 0x8494, 0xE3C3, 0x84C7, 0xE3C4, 0x84CC, 0xE3C5, 0x849B, - 0xE3C6, 0x84A9, 0xE3C7, 0x84AF, 0xE3C8, 0x84A8, 0xE3C9, 0x84D6, 0xE3CA, 0x8498, 0xE3CB, 0x84B6, 0xE3CC, 0x84CF, 0xE3CD, 0x84A0, - 0xE3CE, 0x84D7, 0xE3CF, 0x84D4, 0xE3D0, 0x84D2, 0xE3D1, 0x84DB, 0xE3D2, 0x84B0, 0xE3D3, 0x8491, 0xE3D4, 0x8661, 0xE3D5, 0x8733, - 0xE3D6, 0x8723, 0xE3D7, 0x8728, 0xE3D8, 0x876B, 0xE3D9, 0x8740, 0xE3DA, 0x872E, 0xE3DB, 0x871E, 0xE3DC, 0x8721, 0xE3DD, 0x8719, - 0xE3DE, 0x871B, 0xE3DF, 0x8743, 0xE3E0, 0x872C, 0xE3E1, 0x8741, 0xE3E2, 0x873E, 0xE3E3, 0x8746, 0xE3E4, 0x8720, 0xE3E5, 0x8732, - 0xE3E6, 0x872A, 0xE3E7, 0x872D, 0xE3E8, 0x873C, 0xE3E9, 0x8712, 0xE3EA, 0x873A, 0xE3EB, 0x8731, 0xE3EC, 0x8735, 0xE3ED, 0x8742, - 0xE3EE, 0x8726, 0xE3EF, 0x8727, 0xE3F0, 0x8738, 0xE3F1, 0x8724, 0xE3F2, 0x871A, 0xE3F3, 0x8730, 0xE3F4, 0x8711, 0xE3F5, 0x88F7, - 0xE3F6, 0x88E7, 0xE3F7, 0x88F1, 0xE3F8, 0x88F2, 0xE3F9, 0x88FA, 0xE3FA, 0x88FE, 0xE3FB, 0x88EE, 0xE3FC, 0x88FC, 0xE3FD, 0x88F6, - 0xE3FE, 0x88FB, 0xE440, 0x88F0, 0xE441, 0x88EC, 0xE442, 0x88EB, 0xE443, 0x899D, 0xE444, 0x89A1, 0xE445, 0x899F, 0xE446, 0x899E, - 0xE447, 0x89E9, 0xE448, 0x89EB, 0xE449, 0x89E8, 0xE44A, 0x8AAB, 0xE44B, 0x8A99, 0xE44C, 0x8A8B, 0xE44D, 0x8A92, 0xE44E, 0x8A8F, - 0xE44F, 0x8A96, 0xE450, 0x8C3D, 0xE451, 0x8C68, 0xE452, 0x8C69, 0xE453, 0x8CD5, 0xE454, 0x8CCF, 0xE455, 0x8CD7, 0xE456, 0x8D96, - 0xE457, 0x8E09, 0xE458, 0x8E02, 0xE459, 0x8DFF, 0xE45A, 0x8E0D, 0xE45B, 0x8DFD, 0xE45C, 0x8E0A, 0xE45D, 0x8E03, 0xE45E, 0x8E07, - 0xE45F, 0x8E06, 0xE460, 0x8E05, 0xE461, 0x8DFE, 0xE462, 0x8E00, 0xE463, 0x8E04, 0xE464, 0x8F10, 0xE465, 0x8F11, 0xE466, 0x8F0E, - 0xE467, 0x8F0D, 0xE468, 0x9123, 0xE469, 0x911C, 0xE46A, 0x9120, 0xE46B, 0x9122, 0xE46C, 0x911F, 0xE46D, 0x911D, 0xE46E, 0x911A, - 0xE46F, 0x9124, 0xE470, 0x9121, 0xE471, 0x911B, 0xE472, 0x917A, 0xE473, 0x9172, 0xE474, 0x9179, 0xE475, 0x9173, 0xE476, 0x92A5, - 0xE477, 0x92A4, 0xE478, 0x9276, 0xE479, 0x929B, 0xE47A, 0x927A, 0xE47B, 0x92A0, 0xE47C, 0x9294, 0xE47D, 0x92AA, 0xE47E, 0x928D, - 0xE4A1, 0x92A6, 0xE4A2, 0x929A, 0xE4A3, 0x92AB, 0xE4A4, 0x9279, 0xE4A5, 0x9297, 0xE4A6, 0x927F, 0xE4A7, 0x92A3, 0xE4A8, 0x92EE, - 0xE4A9, 0x928E, 0xE4AA, 0x9282, 0xE4AB, 0x9295, 0xE4AC, 0x92A2, 0xE4AD, 0x927D, 0xE4AE, 0x9288, 0xE4AF, 0x92A1, 0xE4B0, 0x928A, - 0xE4B1, 0x9286, 0xE4B2, 0x928C, 0xE4B3, 0x9299, 0xE4B4, 0x92A7, 0xE4B5, 0x927E, 0xE4B6, 0x9287, 0xE4B7, 0x92A9, 0xE4B8, 0x929D, - 0xE4B9, 0x928B, 0xE4BA, 0x922D, 0xE4BB, 0x969E, 0xE4BC, 0x96A1, 0xE4BD, 0x96FF, 0xE4BE, 0x9758, 0xE4BF, 0x977D, 0xE4C0, 0x977A, - 0xE4C1, 0x977E, 0xE4C2, 0x9783, 0xE4C3, 0x9780, 0xE4C4, 0x9782, 0xE4C5, 0x977B, 0xE4C6, 0x9784, 0xE4C7, 0x9781, 0xE4C8, 0x977F, - 0xE4C9, 0x97CE, 0xE4CA, 0x97CD, 0xE4CB, 0x9816, 0xE4CC, 0x98AD, 0xE4CD, 0x98AE, 0xE4CE, 0x9902, 0xE4CF, 0x9900, 0xE4D0, 0x9907, - 0xE4D1, 0x999D, 0xE4D2, 0x999C, 0xE4D3, 0x99C3, 0xE4D4, 0x99B9, 0xE4D5, 0x99BB, 0xE4D6, 0x99BA, 0xE4D7, 0x99C2, 0xE4D8, 0x99BD, - 0xE4D9, 0x99C7, 0xE4DA, 0x9AB1, 0xE4DB, 0x9AE3, 0xE4DC, 0x9AE7, 0xE4DD, 0x9B3E, 0xE4DE, 0x9B3F, 0xE4DF, 0x9B60, 0xE4E0, 0x9B61, - 0xE4E1, 0x9B5F, 0xE4E2, 0x9CF1, 0xE4E3, 0x9CF2, 0xE4E4, 0x9CF5, 0xE4E5, 0x9EA7, 0xE4E6, 0x50FF, 0xE4E7, 0x5103, 0xE4E8, 0x5130, - 0xE4E9, 0x50F8, 0xE4EA, 0x5106, 0xE4EB, 0x5107, 0xE4EC, 0x50F6, 0xE4ED, 0x50FE, 0xE4EE, 0x510B, 0xE4EF, 0x510C, 0xE4F0, 0x50FD, - 0xE4F1, 0x510A, 0xE4F2, 0x528B, 0xE4F3, 0x528C, 0xE4F4, 0x52F1, 0xE4F5, 0x52EF, 0xE4F6, 0x5648, 0xE4F7, 0x5642, 0xE4F8, 0x564C, - 0xE4F9, 0x5635, 0xE4FA, 0x5641, 0xE4FB, 0x564A, 0xE4FC, 0x5649, 0xE4FD, 0x5646, 0xE4FE, 0x5658, 0xE540, 0x565A, 0xE541, 0x5640, - 0xE542, 0x5633, 0xE543, 0x563D, 0xE544, 0x562C, 0xE545, 0x563E, 0xE546, 0x5638, 0xE547, 0x562A, 0xE548, 0x563A, 0xE549, 0x571A, - 0xE54A, 0x58AB, 0xE54B, 0x589D, 0xE54C, 0x58B1, 0xE54D, 0x58A0, 0xE54E, 0x58A3, 0xE54F, 0x58AF, 0xE550, 0x58AC, 0xE551, 0x58A5, - 0xE552, 0x58A1, 0xE553, 0x58FF, 0xE554, 0x5AFF, 0xE555, 0x5AF4, 0xE556, 0x5AFD, 0xE557, 0x5AF7, 0xE558, 0x5AF6, 0xE559, 0x5B03, - 0xE55A, 0x5AF8, 0xE55B, 0x5B02, 0xE55C, 0x5AF9, 0xE55D, 0x5B01, 0xE55E, 0x5B07, 0xE55F, 0x5B05, 0xE560, 0x5B0F, 0xE561, 0x5C67, - 0xE562, 0x5D99, 0xE563, 0x5D97, 0xE564, 0x5D9F, 0xE565, 0x5D92, 0xE566, 0x5DA2, 0xE567, 0x5D93, 0xE568, 0x5D95, 0xE569, 0x5DA0, - 0xE56A, 0x5D9C, 0xE56B, 0x5DA1, 0xE56C, 0x5D9A, 0xE56D, 0x5D9E, 0xE56E, 0x5E69, 0xE56F, 0x5E5D, 0xE570, 0x5E60, 0xE571, 0x5E5C, - 0xE572, 0x7DF3, 0xE573, 0x5EDB, 0xE574, 0x5EDE, 0xE575, 0x5EE1, 0xE576, 0x5F49, 0xE577, 0x5FB2, 0xE578, 0x618B, 0xE579, 0x6183, - 0xE57A, 0x6179, 0xE57B, 0x61B1, 0xE57C, 0x61B0, 0xE57D, 0x61A2, 0xE57E, 0x6189, 0xE5A1, 0x619B, 0xE5A2, 0x6193, 0xE5A3, 0x61AF, - 0xE5A4, 0x61AD, 0xE5A5, 0x619F, 0xE5A6, 0x6192, 0xE5A7, 0x61AA, 0xE5A8, 0x61A1, 0xE5A9, 0x618D, 0xE5AA, 0x6166, 0xE5AB, 0x61B3, - 0xE5AC, 0x622D, 0xE5AD, 0x646E, 0xE5AE, 0x6470, 0xE5AF, 0x6496, 0xE5B0, 0x64A0, 0xE5B1, 0x6485, 0xE5B2, 0x6497, 0xE5B3, 0x649C, - 0xE5B4, 0x648F, 0xE5B5, 0x648B, 0xE5B6, 0x648A, 0xE5B7, 0x648C, 0xE5B8, 0x64A3, 0xE5B9, 0x649F, 0xE5BA, 0x6468, 0xE5BB, 0x64B1, - 0xE5BC, 0x6498, 0xE5BD, 0x6576, 0xE5BE, 0x657A, 0xE5BF, 0x6579, 0xE5C0, 0x657B, 0xE5C1, 0x65B2, 0xE5C2, 0x65B3, 0xE5C3, 0x66B5, - 0xE5C4, 0x66B0, 0xE5C5, 0x66A9, 0xE5C6, 0x66B2, 0xE5C7, 0x66B7, 0xE5C8, 0x66AA, 0xE5C9, 0x66AF, 0xE5CA, 0x6A00, 0xE5CB, 0x6A06, - 0xE5CC, 0x6A17, 0xE5CD, 0x69E5, 0xE5CE, 0x69F8, 0xE5CF, 0x6A15, 0xE5D0, 0x69F1, 0xE5D1, 0x69E4, 0xE5D2, 0x6A20, 0xE5D3, 0x69FF, - 0xE5D4, 0x69EC, 0xE5D5, 0x69E2, 0xE5D6, 0x6A1B, 0xE5D7, 0x6A1D, 0xE5D8, 0x69FE, 0xE5D9, 0x6A27, 0xE5DA, 0x69F2, 0xE5DB, 0x69EE, - 0xE5DC, 0x6A14, 0xE5DD, 0x69F7, 0xE5DE, 0x69E7, 0xE5DF, 0x6A40, 0xE5E0, 0x6A08, 0xE5E1, 0x69E6, 0xE5E2, 0x69FB, 0xE5E3, 0x6A0D, - 0xE5E4, 0x69FC, 0xE5E5, 0x69EB, 0xE5E6, 0x6A09, 0xE5E7, 0x6A04, 0xE5E8, 0x6A18, 0xE5E9, 0x6A25, 0xE5EA, 0x6A0F, 0xE5EB, 0x69F6, - 0xE5EC, 0x6A26, 0xE5ED, 0x6A07, 0xE5EE, 0x69F4, 0xE5EF, 0x6A16, 0xE5F0, 0x6B51, 0xE5F1, 0x6BA5, 0xE5F2, 0x6BA3, 0xE5F3, 0x6BA2, - 0xE5F4, 0x6BA6, 0xE5F5, 0x6C01, 0xE5F6, 0x6C00, 0xE5F7, 0x6BFF, 0xE5F8, 0x6C02, 0xE5F9, 0x6F41, 0xE5FA, 0x6F26, 0xE5FB, 0x6F7E, - 0xE5FC, 0x6F87, 0xE5FD, 0x6FC6, 0xE5FE, 0x6F92, 0xE640, 0x6F8D, 0xE641, 0x6F89, 0xE642, 0x6F8C, 0xE643, 0x6F62, 0xE644, 0x6F4F, - 0xE645, 0x6F85, 0xE646, 0x6F5A, 0xE647, 0x6F96, 0xE648, 0x6F76, 0xE649, 0x6F6C, 0xE64A, 0x6F82, 0xE64B, 0x6F55, 0xE64C, 0x6F72, - 0xE64D, 0x6F52, 0xE64E, 0x6F50, 0xE64F, 0x6F57, 0xE650, 0x6F94, 0xE651, 0x6F93, 0xE652, 0x6F5D, 0xE653, 0x6F00, 0xE654, 0x6F61, - 0xE655, 0x6F6B, 0xE656, 0x6F7D, 0xE657, 0x6F67, 0xE658, 0x6F90, 0xE659, 0x6F53, 0xE65A, 0x6F8B, 0xE65B, 0x6F69, 0xE65C, 0x6F7F, - 0xE65D, 0x6F95, 0xE65E, 0x6F63, 0xE65F, 0x6F77, 0xE660, 0x6F6A, 0xE661, 0x6F7B, 0xE662, 0x71B2, 0xE663, 0x71AF, 0xE664, 0x719B, - 0xE665, 0x71B0, 0xE666, 0x71A0, 0xE667, 0x719A, 0xE668, 0x71A9, 0xE669, 0x71B5, 0xE66A, 0x719D, 0xE66B, 0x71A5, 0xE66C, 0x719E, - 0xE66D, 0x71A4, 0xE66E, 0x71A1, 0xE66F, 0x71AA, 0xE670, 0x719C, 0xE671, 0x71A7, 0xE672, 0x71B3, 0xE673, 0x7298, 0xE674, 0x729A, - 0xE675, 0x7358, 0xE676, 0x7352, 0xE677, 0x735E, 0xE678, 0x735F, 0xE679, 0x7360, 0xE67A, 0x735D, 0xE67B, 0x735B, 0xE67C, 0x7361, - 0xE67D, 0x735A, 0xE67E, 0x7359, 0xE6A1, 0x7362, 0xE6A2, 0x7487, 0xE6A3, 0x7489, 0xE6A4, 0x748A, 0xE6A5, 0x7486, 0xE6A6, 0x7481, - 0xE6A7, 0x747D, 0xE6A8, 0x7485, 0xE6A9, 0x7488, 0xE6AA, 0x747C, 0xE6AB, 0x7479, 0xE6AC, 0x7508, 0xE6AD, 0x7507, 0xE6AE, 0x757E, - 0xE6AF, 0x7625, 0xE6B0, 0x761E, 0xE6B1, 0x7619, 0xE6B2, 0x761D, 0xE6B3, 0x761C, 0xE6B4, 0x7623, 0xE6B5, 0x761A, 0xE6B6, 0x7628, - 0xE6B7, 0x761B, 0xE6B8, 0x769C, 0xE6B9, 0x769D, 0xE6BA, 0x769E, 0xE6BB, 0x769B, 0xE6BC, 0x778D, 0xE6BD, 0x778F, 0xE6BE, 0x7789, - 0xE6BF, 0x7788, 0xE6C0, 0x78CD, 0xE6C1, 0x78BB, 0xE6C2, 0x78CF, 0xE6C3, 0x78CC, 0xE6C4, 0x78D1, 0xE6C5, 0x78CE, 0xE6C6, 0x78D4, - 0xE6C7, 0x78C8, 0xE6C8, 0x78C3, 0xE6C9, 0x78C4, 0xE6CA, 0x78C9, 0xE6CB, 0x799A, 0xE6CC, 0x79A1, 0xE6CD, 0x79A0, 0xE6CE, 0x799C, - 0xE6CF, 0x79A2, 0xE6D0, 0x799B, 0xE6D1, 0x6B76, 0xE6D2, 0x7A39, 0xE6D3, 0x7AB2, 0xE6D4, 0x7AB4, 0xE6D5, 0x7AB3, 0xE6D6, 0x7BB7, - 0xE6D7, 0x7BCB, 0xE6D8, 0x7BBE, 0xE6D9, 0x7BAC, 0xE6DA, 0x7BCE, 0xE6DB, 0x7BAF, 0xE6DC, 0x7BB9, 0xE6DD, 0x7BCA, 0xE6DE, 0x7BB5, - 0xE6DF, 0x7CC5, 0xE6E0, 0x7CC8, 0xE6E1, 0x7CCC, 0xE6E2, 0x7CCB, 0xE6E3, 0x7DF7, 0xE6E4, 0x7DDB, 0xE6E5, 0x7DEA, 0xE6E6, 0x7DE7, - 0xE6E7, 0x7DD7, 0xE6E8, 0x7DE1, 0xE6E9, 0x7E03, 0xE6EA, 0x7DFA, 0xE6EB, 0x7DE6, 0xE6EC, 0x7DF6, 0xE6ED, 0x7DF1, 0xE6EE, 0x7DF0, - 0xE6EF, 0x7DEE, 0xE6F0, 0x7DDF, 0xE6F1, 0x7F76, 0xE6F2, 0x7FAC, 0xE6F3, 0x7FB0, 0xE6F4, 0x7FAD, 0xE6F5, 0x7FED, 0xE6F6, 0x7FEB, - 0xE6F7, 0x7FEA, 0xE6F8, 0x7FEC, 0xE6F9, 0x7FE6, 0xE6FA, 0x7FE8, 0xE6FB, 0x8064, 0xE6FC, 0x8067, 0xE6FD, 0x81A3, 0xE6FE, 0x819F, - 0xE740, 0x819E, 0xE741, 0x8195, 0xE742, 0x81A2, 0xE743, 0x8199, 0xE744, 0x8197, 0xE745, 0x8216, 0xE746, 0x824F, 0xE747, 0x8253, - 0xE748, 0x8252, 0xE749, 0x8250, 0xE74A, 0x824E, 0xE74B, 0x8251, 0xE74C, 0x8524, 0xE74D, 0x853B, 0xE74E, 0x850F, 0xE74F, 0x8500, - 0xE750, 0x8529, 0xE751, 0x850E, 0xE752, 0x8509, 0xE753, 0x850D, 0xE754, 0x851F, 0xE755, 0x850A, 0xE756, 0x8527, 0xE757, 0x851C, - 0xE758, 0x84FB, 0xE759, 0x852B, 0xE75A, 0x84FA, 0xE75B, 0x8508, 0xE75C, 0x850C, 0xE75D, 0x84F4, 0xE75E, 0x852A, 0xE75F, 0x84F2, - 0xE760, 0x8515, 0xE761, 0x84F7, 0xE762, 0x84EB, 0xE763, 0x84F3, 0xE764, 0x84FC, 0xE765, 0x8512, 0xE766, 0x84EA, 0xE767, 0x84E9, - 0xE768, 0x8516, 0xE769, 0x84FE, 0xE76A, 0x8528, 0xE76B, 0x851D, 0xE76C, 0x852E, 0xE76D, 0x8502, 0xE76E, 0x84FD, 0xE76F, 0x851E, - 0xE770, 0x84F6, 0xE771, 0x8531, 0xE772, 0x8526, 0xE773, 0x84E7, 0xE774, 0x84E8, 0xE775, 0x84F0, 0xE776, 0x84EF, 0xE777, 0x84F9, - 0xE778, 0x8518, 0xE779, 0x8520, 0xE77A, 0x8530, 0xE77B, 0x850B, 0xE77C, 0x8519, 0xE77D, 0x852F, 0xE77E, 0x8662, 0xE7A1, 0x8756, - 0xE7A2, 0x8763, 0xE7A3, 0x8764, 0xE7A4, 0x8777, 0xE7A5, 0x87E1, 0xE7A6, 0x8773, 0xE7A7, 0x8758, 0xE7A8, 0x8754, 0xE7A9, 0x875B, - 0xE7AA, 0x8752, 0xE7AB, 0x8761, 0xE7AC, 0x875A, 0xE7AD, 0x8751, 0xE7AE, 0x875E, 0xE7AF, 0x876D, 0xE7B0, 0x876A, 0xE7B1, 0x8750, - 0xE7B2, 0x874E, 0xE7B3, 0x875F, 0xE7B4, 0x875D, 0xE7B5, 0x876F, 0xE7B6, 0x876C, 0xE7B7, 0x877A, 0xE7B8, 0x876E, 0xE7B9, 0x875C, - 0xE7BA, 0x8765, 0xE7BB, 0x874F, 0xE7BC, 0x877B, 0xE7BD, 0x8775, 0xE7BE, 0x8762, 0xE7BF, 0x8767, 0xE7C0, 0x8769, 0xE7C1, 0x885A, - 0xE7C2, 0x8905, 0xE7C3, 0x890C, 0xE7C4, 0x8914, 0xE7C5, 0x890B, 0xE7C6, 0x8917, 0xE7C7, 0x8918, 0xE7C8, 0x8919, 0xE7C9, 0x8906, - 0xE7CA, 0x8916, 0xE7CB, 0x8911, 0xE7CC, 0x890E, 0xE7CD, 0x8909, 0xE7CE, 0x89A2, 0xE7CF, 0x89A4, 0xE7D0, 0x89A3, 0xE7D1, 0x89ED, - 0xE7D2, 0x89F0, 0xE7D3, 0x89EC, 0xE7D4, 0x8ACF, 0xE7D5, 0x8AC6, 0xE7D6, 0x8AB8, 0xE7D7, 0x8AD3, 0xE7D8, 0x8AD1, 0xE7D9, 0x8AD4, - 0xE7DA, 0x8AD5, 0xE7DB, 0x8ABB, 0xE7DC, 0x8AD7, 0xE7DD, 0x8ABE, 0xE7DE, 0x8AC0, 0xE7DF, 0x8AC5, 0xE7E0, 0x8AD8, 0xE7E1, 0x8AC3, - 0xE7E2, 0x8ABA, 0xE7E3, 0x8ABD, 0xE7E4, 0x8AD9, 0xE7E5, 0x8C3E, 0xE7E6, 0x8C4D, 0xE7E7, 0x8C8F, 0xE7E8, 0x8CE5, 0xE7E9, 0x8CDF, - 0xE7EA, 0x8CD9, 0xE7EB, 0x8CE8, 0xE7EC, 0x8CDA, 0xE7ED, 0x8CDD, 0xE7EE, 0x8CE7, 0xE7EF, 0x8DA0, 0xE7F0, 0x8D9C, 0xE7F1, 0x8DA1, - 0xE7F2, 0x8D9B, 0xE7F3, 0x8E20, 0xE7F4, 0x8E23, 0xE7F5, 0x8E25, 0xE7F6, 0x8E24, 0xE7F7, 0x8E2E, 0xE7F8, 0x8E15, 0xE7F9, 0x8E1B, - 0xE7FA, 0x8E16, 0xE7FB, 0x8E11, 0xE7FC, 0x8E19, 0xE7FD, 0x8E26, 0xE7FE, 0x8E27, 0xE840, 0x8E14, 0xE841, 0x8E12, 0xE842, 0x8E18, - 0xE843, 0x8E13, 0xE844, 0x8E1C, 0xE845, 0x8E17, 0xE846, 0x8E1A, 0xE847, 0x8F2C, 0xE848, 0x8F24, 0xE849, 0x8F18, 0xE84A, 0x8F1A, - 0xE84B, 0x8F20, 0xE84C, 0x8F23, 0xE84D, 0x8F16, 0xE84E, 0x8F17, 0xE84F, 0x9073, 0xE850, 0x9070, 0xE851, 0x906F, 0xE852, 0x9067, - 0xE853, 0x906B, 0xE854, 0x912F, 0xE855, 0x912B, 0xE856, 0x9129, 0xE857, 0x912A, 0xE858, 0x9132, 0xE859, 0x9126, 0xE85A, 0x912E, - 0xE85B, 0x9185, 0xE85C, 0x9186, 0xE85D, 0x918A, 0xE85E, 0x9181, 0xE85F, 0x9182, 0xE860, 0x9184, 0xE861, 0x9180, 0xE862, 0x92D0, - 0xE863, 0x92C3, 0xE864, 0x92C4, 0xE865, 0x92C0, 0xE866, 0x92D9, 0xE867, 0x92B6, 0xE868, 0x92CF, 0xE869, 0x92F1, 0xE86A, 0x92DF, - 0xE86B, 0x92D8, 0xE86C, 0x92E9, 0xE86D, 0x92D7, 0xE86E, 0x92DD, 0xE86F, 0x92CC, 0xE870, 0x92EF, 0xE871, 0x92C2, 0xE872, 0x92E8, - 0xE873, 0x92CA, 0xE874, 0x92C8, 0xE875, 0x92CE, 0xE876, 0x92E6, 0xE877, 0x92CD, 0xE878, 0x92D5, 0xE879, 0x92C9, 0xE87A, 0x92E0, - 0xE87B, 0x92DE, 0xE87C, 0x92E7, 0xE87D, 0x92D1, 0xE87E, 0x92D3, 0xE8A1, 0x92B5, 0xE8A2, 0x92E1, 0xE8A3, 0x92C6, 0xE8A4, 0x92B4, - 0xE8A5, 0x957C, 0xE8A6, 0x95AC, 0xE8A7, 0x95AB, 0xE8A8, 0x95AE, 0xE8A9, 0x95B0, 0xE8AA, 0x96A4, 0xE8AB, 0x96A2, 0xE8AC, 0x96D3, - 0xE8AD, 0x9705, 0xE8AE, 0x9708, 0xE8AF, 0x9702, 0xE8B0, 0x975A, 0xE8B1, 0x978A, 0xE8B2, 0x978E, 0xE8B3, 0x9788, 0xE8B4, 0x97D0, - 0xE8B5, 0x97CF, 0xE8B6, 0x981E, 0xE8B7, 0x981D, 0xE8B8, 0x9826, 0xE8B9, 0x9829, 0xE8BA, 0x9828, 0xE8BB, 0x9820, 0xE8BC, 0x981B, - 0xE8BD, 0x9827, 0xE8BE, 0x98B2, 0xE8BF, 0x9908, 0xE8C0, 0x98FA, 0xE8C1, 0x9911, 0xE8C2, 0x9914, 0xE8C3, 0x9916, 0xE8C4, 0x9917, - 0xE8C5, 0x9915, 0xE8C6, 0x99DC, 0xE8C7, 0x99CD, 0xE8C8, 0x99CF, 0xE8C9, 0x99D3, 0xE8CA, 0x99D4, 0xE8CB, 0x99CE, 0xE8CC, 0x99C9, - 0xE8CD, 0x99D6, 0xE8CE, 0x99D8, 0xE8CF, 0x99CB, 0xE8D0, 0x99D7, 0xE8D1, 0x99CC, 0xE8D2, 0x9AB3, 0xE8D3, 0x9AEC, 0xE8D4, 0x9AEB, - 0xE8D5, 0x9AF3, 0xE8D6, 0x9AF2, 0xE8D7, 0x9AF1, 0xE8D8, 0x9B46, 0xE8D9, 0x9B43, 0xE8DA, 0x9B67, 0xE8DB, 0x9B74, 0xE8DC, 0x9B71, - 0xE8DD, 0x9B66, 0xE8DE, 0x9B76, 0xE8DF, 0x9B75, 0xE8E0, 0x9B70, 0xE8E1, 0x9B68, 0xE8E2, 0x9B64, 0xE8E3, 0x9B6C, 0xE8E4, 0x9CFC, - 0xE8E5, 0x9CFA, 0xE8E6, 0x9CFD, 0xE8E7, 0x9CFF, 0xE8E8, 0x9CF7, 0xE8E9, 0x9D07, 0xE8EA, 0x9D00, 0xE8EB, 0x9CF9, 0xE8EC, 0x9CFB, - 0xE8ED, 0x9D08, 0xE8EE, 0x9D05, 0xE8EF, 0x9D04, 0xE8F0, 0x9E83, 0xE8F1, 0x9ED3, 0xE8F2, 0x9F0F, 0xE8F3, 0x9F10, 0xE8F4, 0x511C, - 0xE8F5, 0x5113, 0xE8F6, 0x5117, 0xE8F7, 0x511A, 0xE8F8, 0x5111, 0xE8F9, 0x51DE, 0xE8FA, 0x5334, 0xE8FB, 0x53E1, 0xE8FC, 0x5670, - 0xE8FD, 0x5660, 0xE8FE, 0x566E, 0xE940, 0x5673, 0xE941, 0x5666, 0xE942, 0x5663, 0xE943, 0x566D, 0xE944, 0x5672, 0xE945, 0x565E, - 0xE946, 0x5677, 0xE947, 0x571C, 0xE948, 0x571B, 0xE949, 0x58C8, 0xE94A, 0x58BD, 0xE94B, 0x58C9, 0xE94C, 0x58BF, 0xE94D, 0x58BA, - 0xE94E, 0x58C2, 0xE94F, 0x58BC, 0xE950, 0x58C6, 0xE951, 0x5B17, 0xE952, 0x5B19, 0xE953, 0x5B1B, 0xE954, 0x5B21, 0xE955, 0x5B14, - 0xE956, 0x5B13, 0xE957, 0x5B10, 0xE958, 0x5B16, 0xE959, 0x5B28, 0xE95A, 0x5B1A, 0xE95B, 0x5B20, 0xE95C, 0x5B1E, 0xE95D, 0x5BEF, - 0xE95E, 0x5DAC, 0xE95F, 0x5DB1, 0xE960, 0x5DA9, 0xE961, 0x5DA7, 0xE962, 0x5DB5, 0xE963, 0x5DB0, 0xE964, 0x5DAE, 0xE965, 0x5DAA, - 0xE966, 0x5DA8, 0xE967, 0x5DB2, 0xE968, 0x5DAD, 0xE969, 0x5DAF, 0xE96A, 0x5DB4, 0xE96B, 0x5E67, 0xE96C, 0x5E68, 0xE96D, 0x5E66, - 0xE96E, 0x5E6F, 0xE96F, 0x5EE9, 0xE970, 0x5EE7, 0xE971, 0x5EE6, 0xE972, 0x5EE8, 0xE973, 0x5EE5, 0xE974, 0x5F4B, 0xE975, 0x5FBC, - 0xE976, 0x619D, 0xE977, 0x61A8, 0xE978, 0x6196, 0xE979, 0x61C5, 0xE97A, 0x61B4, 0xE97B, 0x61C6, 0xE97C, 0x61C1, 0xE97D, 0x61CC, - 0xE97E, 0x61BA, 0xE9A1, 0x61BF, 0xE9A2, 0x61B8, 0xE9A3, 0x618C, 0xE9A4, 0x64D7, 0xE9A5, 0x64D6, 0xE9A6, 0x64D0, 0xE9A7, 0x64CF, - 0xE9A8, 0x64C9, 0xE9A9, 0x64BD, 0xE9AA, 0x6489, 0xE9AB, 0x64C3, 0xE9AC, 0x64DB, 0xE9AD, 0x64F3, 0xE9AE, 0x64D9, 0xE9AF, 0x6533, - 0xE9B0, 0x657F, 0xE9B1, 0x657C, 0xE9B2, 0x65A2, 0xE9B3, 0x66C8, 0xE9B4, 0x66BE, 0xE9B5, 0x66C0, 0xE9B6, 0x66CA, 0xE9B7, 0x66CB, - 0xE9B8, 0x66CF, 0xE9B9, 0x66BD, 0xE9BA, 0x66BB, 0xE9BB, 0x66BA, 0xE9BC, 0x66CC, 0xE9BD, 0x6723, 0xE9BE, 0x6A34, 0xE9BF, 0x6A66, - 0xE9C0, 0x6A49, 0xE9C1, 0x6A67, 0xE9C2, 0x6A32, 0xE9C3, 0x6A68, 0xE9C4, 0x6A3E, 0xE9C5, 0x6A5D, 0xE9C6, 0x6A6D, 0xE9C7, 0x6A76, - 0xE9C8, 0x6A5B, 0xE9C9, 0x6A51, 0xE9CA, 0x6A28, 0xE9CB, 0x6A5A, 0xE9CC, 0x6A3B, 0xE9CD, 0x6A3F, 0xE9CE, 0x6A41, 0xE9CF, 0x6A6A, - 0xE9D0, 0x6A64, 0xE9D1, 0x6A50, 0xE9D2, 0x6A4F, 0xE9D3, 0x6A54, 0xE9D4, 0x6A6F, 0xE9D5, 0x6A69, 0xE9D6, 0x6A60, 0xE9D7, 0x6A3C, - 0xE9D8, 0x6A5E, 0xE9D9, 0x6A56, 0xE9DA, 0x6A55, 0xE9DB, 0x6A4D, 0xE9DC, 0x6A4E, 0xE9DD, 0x6A46, 0xE9DE, 0x6B55, 0xE9DF, 0x6B54, - 0xE9E0, 0x6B56, 0xE9E1, 0x6BA7, 0xE9E2, 0x6BAA, 0xE9E3, 0x6BAB, 0xE9E4, 0x6BC8, 0xE9E5, 0x6BC7, 0xE9E6, 0x6C04, 0xE9E7, 0x6C03, - 0xE9E8, 0x6C06, 0xE9E9, 0x6FAD, 0xE9EA, 0x6FCB, 0xE9EB, 0x6FA3, 0xE9EC, 0x6FC7, 0xE9ED, 0x6FBC, 0xE9EE, 0x6FCE, 0xE9EF, 0x6FC8, - 0xE9F0, 0x6F5E, 0xE9F1, 0x6FC4, 0xE9F2, 0x6FBD, 0xE9F3, 0x6F9E, 0xE9F4, 0x6FCA, 0xE9F5, 0x6FA8, 0xE9F6, 0x7004, 0xE9F7, 0x6FA5, - 0xE9F8, 0x6FAE, 0xE9F9, 0x6FBA, 0xE9FA, 0x6FAC, 0xE9FB, 0x6FAA, 0xE9FC, 0x6FCF, 0xE9FD, 0x6FBF, 0xE9FE, 0x6FB8, 0xEA40, 0x6FA2, - 0xEA41, 0x6FC9, 0xEA42, 0x6FAB, 0xEA43, 0x6FCD, 0xEA44, 0x6FAF, 0xEA45, 0x6FB2, 0xEA46, 0x6FB0, 0xEA47, 0x71C5, 0xEA48, 0x71C2, - 0xEA49, 0x71BF, 0xEA4A, 0x71B8, 0xEA4B, 0x71D6, 0xEA4C, 0x71C0, 0xEA4D, 0x71C1, 0xEA4E, 0x71CB, 0xEA4F, 0x71D4, 0xEA50, 0x71CA, - 0xEA51, 0x71C7, 0xEA52, 0x71CF, 0xEA53, 0x71BD, 0xEA54, 0x71D8, 0xEA55, 0x71BC, 0xEA56, 0x71C6, 0xEA57, 0x71DA, 0xEA58, 0x71DB, - 0xEA59, 0x729D, 0xEA5A, 0x729E, 0xEA5B, 0x7369, 0xEA5C, 0x7366, 0xEA5D, 0x7367, 0xEA5E, 0x736C, 0xEA5F, 0x7365, 0xEA60, 0x736B, - 0xEA61, 0x736A, 0xEA62, 0x747F, 0xEA63, 0x749A, 0xEA64, 0x74A0, 0xEA65, 0x7494, 0xEA66, 0x7492, 0xEA67, 0x7495, 0xEA68, 0x74A1, - 0xEA69, 0x750B, 0xEA6A, 0x7580, 0xEA6B, 0x762F, 0xEA6C, 0x762D, 0xEA6D, 0x7631, 0xEA6E, 0x763D, 0xEA6F, 0x7633, 0xEA70, 0x763C, - 0xEA71, 0x7635, 0xEA72, 0x7632, 0xEA73, 0x7630, 0xEA74, 0x76BB, 0xEA75, 0x76E6, 0xEA76, 0x779A, 0xEA77, 0x779D, 0xEA78, 0x77A1, - 0xEA79, 0x779C, 0xEA7A, 0x779B, 0xEA7B, 0x77A2, 0xEA7C, 0x77A3, 0xEA7D, 0x7795, 0xEA7E, 0x7799, 0xEAA1, 0x7797, 0xEAA2, 0x78DD, - 0xEAA3, 0x78E9, 0xEAA4, 0x78E5, 0xEAA5, 0x78EA, 0xEAA6, 0x78DE, 0xEAA7, 0x78E3, 0xEAA8, 0x78DB, 0xEAA9, 0x78E1, 0xEAAA, 0x78E2, - 0xEAAB, 0x78ED, 0xEAAC, 0x78DF, 0xEAAD, 0x78E0, 0xEAAE, 0x79A4, 0xEAAF, 0x7A44, 0xEAB0, 0x7A48, 0xEAB1, 0x7A47, 0xEAB2, 0x7AB6, - 0xEAB3, 0x7AB8, 0xEAB4, 0x7AB5, 0xEAB5, 0x7AB1, 0xEAB6, 0x7AB7, 0xEAB7, 0x7BDE, 0xEAB8, 0x7BE3, 0xEAB9, 0x7BE7, 0xEABA, 0x7BDD, - 0xEABB, 0x7BD5, 0xEABC, 0x7BE5, 0xEABD, 0x7BDA, 0xEABE, 0x7BE8, 0xEABF, 0x7BF9, 0xEAC0, 0x7BD4, 0xEAC1, 0x7BEA, 0xEAC2, 0x7BE2, - 0xEAC3, 0x7BDC, 0xEAC4, 0x7BEB, 0xEAC5, 0x7BD8, 0xEAC6, 0x7BDF, 0xEAC7, 0x7CD2, 0xEAC8, 0x7CD4, 0xEAC9, 0x7CD7, 0xEACA, 0x7CD0, - 0xEACB, 0x7CD1, 0xEACC, 0x7E12, 0xEACD, 0x7E21, 0xEACE, 0x7E17, 0xEACF, 0x7E0C, 0xEAD0, 0x7E1F, 0xEAD1, 0x7E20, 0xEAD2, 0x7E13, - 0xEAD3, 0x7E0E, 0xEAD4, 0x7E1C, 0xEAD5, 0x7E15, 0xEAD6, 0x7E1A, 0xEAD7, 0x7E22, 0xEAD8, 0x7E0B, 0xEAD9, 0x7E0F, 0xEADA, 0x7E16, - 0xEADB, 0x7E0D, 0xEADC, 0x7E14, 0xEADD, 0x7E25, 0xEADE, 0x7E24, 0xEADF, 0x7F43, 0xEAE0, 0x7F7B, 0xEAE1, 0x7F7C, 0xEAE2, 0x7F7A, - 0xEAE3, 0x7FB1, 0xEAE4, 0x7FEF, 0xEAE5, 0x802A, 0xEAE6, 0x8029, 0xEAE7, 0x806C, 0xEAE8, 0x81B1, 0xEAE9, 0x81A6, 0xEAEA, 0x81AE, - 0xEAEB, 0x81B9, 0xEAEC, 0x81B5, 0xEAED, 0x81AB, 0xEAEE, 0x81B0, 0xEAEF, 0x81AC, 0xEAF0, 0x81B4, 0xEAF1, 0x81B2, 0xEAF2, 0x81B7, - 0xEAF3, 0x81A7, 0xEAF4, 0x81F2, 0xEAF5, 0x8255, 0xEAF6, 0x8256, 0xEAF7, 0x8257, 0xEAF8, 0x8556, 0xEAF9, 0x8545, 0xEAFA, 0x856B, - 0xEAFB, 0x854D, 0xEAFC, 0x8553, 0xEAFD, 0x8561, 0xEAFE, 0x8558, 0xEB40, 0x8540, 0xEB41, 0x8546, 0xEB42, 0x8564, 0xEB43, 0x8541, - 0xEB44, 0x8562, 0xEB45, 0x8544, 0xEB46, 0x8551, 0xEB47, 0x8547, 0xEB48, 0x8563, 0xEB49, 0x853E, 0xEB4A, 0x855B, 0xEB4B, 0x8571, - 0xEB4C, 0x854E, 0xEB4D, 0x856E, 0xEB4E, 0x8575, 0xEB4F, 0x8555, 0xEB50, 0x8567, 0xEB51, 0x8560, 0xEB52, 0x858C, 0xEB53, 0x8566, - 0xEB54, 0x855D, 0xEB55, 0x8554, 0xEB56, 0x8565, 0xEB57, 0x856C, 0xEB58, 0x8663, 0xEB59, 0x8665, 0xEB5A, 0x8664, 0xEB5B, 0x879B, - 0xEB5C, 0x878F, 0xEB5D, 0x8797, 0xEB5E, 0x8793, 0xEB5F, 0x8792, 0xEB60, 0x8788, 0xEB61, 0x8781, 0xEB62, 0x8796, 0xEB63, 0x8798, - 0xEB64, 0x8779, 0xEB65, 0x8787, 0xEB66, 0x87A3, 0xEB67, 0x8785, 0xEB68, 0x8790, 0xEB69, 0x8791, 0xEB6A, 0x879D, 0xEB6B, 0x8784, - 0xEB6C, 0x8794, 0xEB6D, 0x879C, 0xEB6E, 0x879A, 0xEB6F, 0x8789, 0xEB70, 0x891E, 0xEB71, 0x8926, 0xEB72, 0x8930, 0xEB73, 0x892D, - 0xEB74, 0x892E, 0xEB75, 0x8927, 0xEB76, 0x8931, 0xEB77, 0x8922, 0xEB78, 0x8929, 0xEB79, 0x8923, 0xEB7A, 0x892F, 0xEB7B, 0x892C, - 0xEB7C, 0x891F, 0xEB7D, 0x89F1, 0xEB7E, 0x8AE0, 0xEBA1, 0x8AE2, 0xEBA2, 0x8AF2, 0xEBA3, 0x8AF4, 0xEBA4, 0x8AF5, 0xEBA5, 0x8ADD, - 0xEBA6, 0x8B14, 0xEBA7, 0x8AE4, 0xEBA8, 0x8ADF, 0xEBA9, 0x8AF0, 0xEBAA, 0x8AC8, 0xEBAB, 0x8ADE, 0xEBAC, 0x8AE1, 0xEBAD, 0x8AE8, - 0xEBAE, 0x8AFF, 0xEBAF, 0x8AEF, 0xEBB0, 0x8AFB, 0xEBB1, 0x8C91, 0xEBB2, 0x8C92, 0xEBB3, 0x8C90, 0xEBB4, 0x8CF5, 0xEBB5, 0x8CEE, - 0xEBB6, 0x8CF1, 0xEBB7, 0x8CF0, 0xEBB8, 0x8CF3, 0xEBB9, 0x8D6C, 0xEBBA, 0x8D6E, 0xEBBB, 0x8DA5, 0xEBBC, 0x8DA7, 0xEBBD, 0x8E33, - 0xEBBE, 0x8E3E, 0xEBBF, 0x8E38, 0xEBC0, 0x8E40, 0xEBC1, 0x8E45, 0xEBC2, 0x8E36, 0xEBC3, 0x8E3C, 0xEBC4, 0x8E3D, 0xEBC5, 0x8E41, - 0xEBC6, 0x8E30, 0xEBC7, 0x8E3F, 0xEBC8, 0x8EBD, 0xEBC9, 0x8F36, 0xEBCA, 0x8F2E, 0xEBCB, 0x8F35, 0xEBCC, 0x8F32, 0xEBCD, 0x8F39, - 0xEBCE, 0x8F37, 0xEBCF, 0x8F34, 0xEBD0, 0x9076, 0xEBD1, 0x9079, 0xEBD2, 0x907B, 0xEBD3, 0x9086, 0xEBD4, 0x90FA, 0xEBD5, 0x9133, - 0xEBD6, 0x9135, 0xEBD7, 0x9136, 0xEBD8, 0x9193, 0xEBD9, 0x9190, 0xEBDA, 0x9191, 0xEBDB, 0x918D, 0xEBDC, 0x918F, 0xEBDD, 0x9327, - 0xEBDE, 0x931E, 0xEBDF, 0x9308, 0xEBE0, 0x931F, 0xEBE1, 0x9306, 0xEBE2, 0x930F, 0xEBE3, 0x937A, 0xEBE4, 0x9338, 0xEBE5, 0x933C, - 0xEBE6, 0x931B, 0xEBE7, 0x9323, 0xEBE8, 0x9312, 0xEBE9, 0x9301, 0xEBEA, 0x9346, 0xEBEB, 0x932D, 0xEBEC, 0x930E, 0xEBED, 0x930D, - 0xEBEE, 0x92CB, 0xEBEF, 0x931D, 0xEBF0, 0x92FA, 0xEBF1, 0x9325, 0xEBF2, 0x9313, 0xEBF3, 0x92F9, 0xEBF4, 0x92F7, 0xEBF5, 0x9334, - 0xEBF6, 0x9302, 0xEBF7, 0x9324, 0xEBF8, 0x92FF, 0xEBF9, 0x9329, 0xEBFA, 0x9339, 0xEBFB, 0x9335, 0xEBFC, 0x932A, 0xEBFD, 0x9314, - 0xEBFE, 0x930C, 0xEC40, 0x930B, 0xEC41, 0x92FE, 0xEC42, 0x9309, 0xEC43, 0x9300, 0xEC44, 0x92FB, 0xEC45, 0x9316, 0xEC46, 0x95BC, - 0xEC47, 0x95CD, 0xEC48, 0x95BE, 0xEC49, 0x95B9, 0xEC4A, 0x95BA, 0xEC4B, 0x95B6, 0xEC4C, 0x95BF, 0xEC4D, 0x95B5, 0xEC4E, 0x95BD, - 0xEC4F, 0x96A9, 0xEC50, 0x96D4, 0xEC51, 0x970B, 0xEC52, 0x9712, 0xEC53, 0x9710, 0xEC54, 0x9799, 0xEC55, 0x9797, 0xEC56, 0x9794, - 0xEC57, 0x97F0, 0xEC58, 0x97F8, 0xEC59, 0x9835, 0xEC5A, 0x982F, 0xEC5B, 0x9832, 0xEC5C, 0x9924, 0xEC5D, 0x991F, 0xEC5E, 0x9927, - 0xEC5F, 0x9929, 0xEC60, 0x999E, 0xEC61, 0x99EE, 0xEC62, 0x99EC, 0xEC63, 0x99E5, 0xEC64, 0x99E4, 0xEC65, 0x99F0, 0xEC66, 0x99E3, - 0xEC67, 0x99EA, 0xEC68, 0x99E9, 0xEC69, 0x99E7, 0xEC6A, 0x9AB9, 0xEC6B, 0x9ABF, 0xEC6C, 0x9AB4, 0xEC6D, 0x9ABB, 0xEC6E, 0x9AF6, - 0xEC6F, 0x9AFA, 0xEC70, 0x9AF9, 0xEC71, 0x9AF7, 0xEC72, 0x9B33, 0xEC73, 0x9B80, 0xEC74, 0x9B85, 0xEC75, 0x9B87, 0xEC76, 0x9B7C, - 0xEC77, 0x9B7E, 0xEC78, 0x9B7B, 0xEC79, 0x9B82, 0xEC7A, 0x9B93, 0xEC7B, 0x9B92, 0xEC7C, 0x9B90, 0xEC7D, 0x9B7A, 0xEC7E, 0x9B95, - 0xECA1, 0x9B7D, 0xECA2, 0x9B88, 0xECA3, 0x9D25, 0xECA4, 0x9D17, 0xECA5, 0x9D20, 0xECA6, 0x9D1E, 0xECA7, 0x9D14, 0xECA8, 0x9D29, - 0xECA9, 0x9D1D, 0xECAA, 0x9D18, 0xECAB, 0x9D22, 0xECAC, 0x9D10, 0xECAD, 0x9D19, 0xECAE, 0x9D1F, 0xECAF, 0x9E88, 0xECB0, 0x9E86, - 0xECB1, 0x9E87, 0xECB2, 0x9EAE, 0xECB3, 0x9EAD, 0xECB4, 0x9ED5, 0xECB5, 0x9ED6, 0xECB6, 0x9EFA, 0xECB7, 0x9F12, 0xECB8, 0x9F3D, - 0xECB9, 0x5126, 0xECBA, 0x5125, 0xECBB, 0x5122, 0xECBC, 0x5124, 0xECBD, 0x5120, 0xECBE, 0x5129, 0xECBF, 0x52F4, 0xECC0, 0x5693, - 0xECC1, 0x568C, 0xECC2, 0x568D, 0xECC3, 0x5686, 0xECC4, 0x5684, 0xECC5, 0x5683, 0xECC6, 0x567E, 0xECC7, 0x5682, 0xECC8, 0x567F, - 0xECC9, 0x5681, 0xECCA, 0x58D6, 0xECCB, 0x58D4, 0xECCC, 0x58CF, 0xECCD, 0x58D2, 0xECCE, 0x5B2D, 0xECCF, 0x5B25, 0xECD0, 0x5B32, - 0xECD1, 0x5B23, 0xECD2, 0x5B2C, 0xECD3, 0x5B27, 0xECD4, 0x5B26, 0xECD5, 0x5B2F, 0xECD6, 0x5B2E, 0xECD7, 0x5B7B, 0xECD8, 0x5BF1, - 0xECD9, 0x5BF2, 0xECDA, 0x5DB7, 0xECDB, 0x5E6C, 0xECDC, 0x5E6A, 0xECDD, 0x5FBE, 0xECDE, 0x5FBB, 0xECDF, 0x61C3, 0xECE0, 0x61B5, - 0xECE1, 0x61BC, 0xECE2, 0x61E7, 0xECE3, 0x61E0, 0xECE4, 0x61E5, 0xECE5, 0x61E4, 0xECE6, 0x61E8, 0xECE7, 0x61DE, 0xECE8, 0x64EF, - 0xECE9, 0x64E9, 0xECEA, 0x64E3, 0xECEB, 0x64EB, 0xECEC, 0x64E4, 0xECED, 0x64E8, 0xECEE, 0x6581, 0xECEF, 0x6580, 0xECF0, 0x65B6, - 0xECF1, 0x65DA, 0xECF2, 0x66D2, 0xECF3, 0x6A8D, 0xECF4, 0x6A96, 0xECF5, 0x6A81, 0xECF6, 0x6AA5, 0xECF7, 0x6A89, 0xECF8, 0x6A9F, - 0xECF9, 0x6A9B, 0xECFA, 0x6AA1, 0xECFB, 0x6A9E, 0xECFC, 0x6A87, 0xECFD, 0x6A93, 0xECFE, 0x6A8E, 0xED40, 0x6A95, 0xED41, 0x6A83, - 0xED42, 0x6AA8, 0xED43, 0x6AA4, 0xED44, 0x6A91, 0xED45, 0x6A7F, 0xED46, 0x6AA6, 0xED47, 0x6A9A, 0xED48, 0x6A85, 0xED49, 0x6A8C, - 0xED4A, 0x6A92, 0xED4B, 0x6B5B, 0xED4C, 0x6BAD, 0xED4D, 0x6C09, 0xED4E, 0x6FCC, 0xED4F, 0x6FA9, 0xED50, 0x6FF4, 0xED51, 0x6FD4, - 0xED52, 0x6FE3, 0xED53, 0x6FDC, 0xED54, 0x6FED, 0xED55, 0x6FE7, 0xED56, 0x6FE6, 0xED57, 0x6FDE, 0xED58, 0x6FF2, 0xED59, 0x6FDD, - 0xED5A, 0x6FE2, 0xED5B, 0x6FE8, 0xED5C, 0x71E1, 0xED5D, 0x71F1, 0xED5E, 0x71E8, 0xED5F, 0x71F2, 0xED60, 0x71E4, 0xED61, 0x71F0, - 0xED62, 0x71E2, 0xED63, 0x7373, 0xED64, 0x736E, 0xED65, 0x736F, 0xED66, 0x7497, 0xED67, 0x74B2, 0xED68, 0x74AB, 0xED69, 0x7490, - 0xED6A, 0x74AA, 0xED6B, 0x74AD, 0xED6C, 0x74B1, 0xED6D, 0x74A5, 0xED6E, 0x74AF, 0xED6F, 0x7510, 0xED70, 0x7511, 0xED71, 0x7512, - 0xED72, 0x750F, 0xED73, 0x7584, 0xED74, 0x7643, 0xED75, 0x7648, 0xED76, 0x7649, 0xED77, 0x7647, 0xED78, 0x76A4, 0xED79, 0x76E9, - 0xED7A, 0x77B5, 0xED7B, 0x77AB, 0xED7C, 0x77B2, 0xED7D, 0x77B7, 0xED7E, 0x77B6, 0xEDA1, 0x77B4, 0xEDA2, 0x77B1, 0xEDA3, 0x77A8, - 0xEDA4, 0x77F0, 0xEDA5, 0x78F3, 0xEDA6, 0x78FD, 0xEDA7, 0x7902, 0xEDA8, 0x78FB, 0xEDA9, 0x78FC, 0xEDAA, 0x78F2, 0xEDAB, 0x7905, - 0xEDAC, 0x78F9, 0xEDAD, 0x78FE, 0xEDAE, 0x7904, 0xEDAF, 0x79AB, 0xEDB0, 0x79A8, 0xEDB1, 0x7A5C, 0xEDB2, 0x7A5B, 0xEDB3, 0x7A56, - 0xEDB4, 0x7A58, 0xEDB5, 0x7A54, 0xEDB6, 0x7A5A, 0xEDB7, 0x7ABE, 0xEDB8, 0x7AC0, 0xEDB9, 0x7AC1, 0xEDBA, 0x7C05, 0xEDBB, 0x7C0F, - 0xEDBC, 0x7BF2, 0xEDBD, 0x7C00, 0xEDBE, 0x7BFF, 0xEDBF, 0x7BFB, 0xEDC0, 0x7C0E, 0xEDC1, 0x7BF4, 0xEDC2, 0x7C0B, 0xEDC3, 0x7BF3, - 0xEDC4, 0x7C02, 0xEDC5, 0x7C09, 0xEDC6, 0x7C03, 0xEDC7, 0x7C01, 0xEDC8, 0x7BF8, 0xEDC9, 0x7BFD, 0xEDCA, 0x7C06, 0xEDCB, 0x7BF0, - 0xEDCC, 0x7BF1, 0xEDCD, 0x7C10, 0xEDCE, 0x7C0A, 0xEDCF, 0x7CE8, 0xEDD0, 0x7E2D, 0xEDD1, 0x7E3C, 0xEDD2, 0x7E42, 0xEDD3, 0x7E33, - 0xEDD4, 0x9848, 0xEDD5, 0x7E38, 0xEDD6, 0x7E2A, 0xEDD7, 0x7E49, 0xEDD8, 0x7E40, 0xEDD9, 0x7E47, 0xEDDA, 0x7E29, 0xEDDB, 0x7E4C, - 0xEDDC, 0x7E30, 0xEDDD, 0x7E3B, 0xEDDE, 0x7E36, 0xEDDF, 0x7E44, 0xEDE0, 0x7E3A, 0xEDE1, 0x7F45, 0xEDE2, 0x7F7F, 0xEDE3, 0x7F7E, - 0xEDE4, 0x7F7D, 0xEDE5, 0x7FF4, 0xEDE6, 0x7FF2, 0xEDE7, 0x802C, 0xEDE8, 0x81BB, 0xEDE9, 0x81C4, 0xEDEA, 0x81CC, 0xEDEB, 0x81CA, - 0xEDEC, 0x81C5, 0xEDED, 0x81C7, 0xEDEE, 0x81BC, 0xEDEF, 0x81E9, 0xEDF0, 0x825B, 0xEDF1, 0x825A, 0xEDF2, 0x825C, 0xEDF3, 0x8583, - 0xEDF4, 0x8580, 0xEDF5, 0x858F, 0xEDF6, 0x85A7, 0xEDF7, 0x8595, 0xEDF8, 0x85A0, 0xEDF9, 0x858B, 0xEDFA, 0x85A3, 0xEDFB, 0x857B, - 0xEDFC, 0x85A4, 0xEDFD, 0x859A, 0xEDFE, 0x859E, 0xEE40, 0x8577, 0xEE41, 0x857C, 0xEE42, 0x8589, 0xEE43, 0x85A1, 0xEE44, 0x857A, - 0xEE45, 0x8578, 0xEE46, 0x8557, 0xEE47, 0x858E, 0xEE48, 0x8596, 0xEE49, 0x8586, 0xEE4A, 0x858D, 0xEE4B, 0x8599, 0xEE4C, 0x859D, - 0xEE4D, 0x8581, 0xEE4E, 0x85A2, 0xEE4F, 0x8582, 0xEE50, 0x8588, 0xEE51, 0x8585, 0xEE52, 0x8579, 0xEE53, 0x8576, 0xEE54, 0x8598, - 0xEE55, 0x8590, 0xEE56, 0x859F, 0xEE57, 0x8668, 0xEE58, 0x87BE, 0xEE59, 0x87AA, 0xEE5A, 0x87AD, 0xEE5B, 0x87C5, 0xEE5C, 0x87B0, - 0xEE5D, 0x87AC, 0xEE5E, 0x87B9, 0xEE5F, 0x87B5, 0xEE60, 0x87BC, 0xEE61, 0x87AE, 0xEE62, 0x87C9, 0xEE63, 0x87C3, 0xEE64, 0x87C2, - 0xEE65, 0x87CC, 0xEE66, 0x87B7, 0xEE67, 0x87AF, 0xEE68, 0x87C4, 0xEE69, 0x87CA, 0xEE6A, 0x87B4, 0xEE6B, 0x87B6, 0xEE6C, 0x87BF, - 0xEE6D, 0x87B8, 0xEE6E, 0x87BD, 0xEE6F, 0x87DE, 0xEE70, 0x87B2, 0xEE71, 0x8935, 0xEE72, 0x8933, 0xEE73, 0x893C, 0xEE74, 0x893E, - 0xEE75, 0x8941, 0xEE76, 0x8952, 0xEE77, 0x8937, 0xEE78, 0x8942, 0xEE79, 0x89AD, 0xEE7A, 0x89AF, 0xEE7B, 0x89AE, 0xEE7C, 0x89F2, - 0xEE7D, 0x89F3, 0xEE7E, 0x8B1E, 0xEEA1, 0x8B18, 0xEEA2, 0x8B16, 0xEEA3, 0x8B11, 0xEEA4, 0x8B05, 0xEEA5, 0x8B0B, 0xEEA6, 0x8B22, - 0xEEA7, 0x8B0F, 0xEEA8, 0x8B12, 0xEEA9, 0x8B15, 0xEEAA, 0x8B07, 0xEEAB, 0x8B0D, 0xEEAC, 0x8B08, 0xEEAD, 0x8B06, 0xEEAE, 0x8B1C, - 0xEEAF, 0x8B13, 0xEEB0, 0x8B1A, 0xEEB1, 0x8C4F, 0xEEB2, 0x8C70, 0xEEB3, 0x8C72, 0xEEB4, 0x8C71, 0xEEB5, 0x8C6F, 0xEEB6, 0x8C95, - 0xEEB7, 0x8C94, 0xEEB8, 0x8CF9, 0xEEB9, 0x8D6F, 0xEEBA, 0x8E4E, 0xEEBB, 0x8E4D, 0xEEBC, 0x8E53, 0xEEBD, 0x8E50, 0xEEBE, 0x8E4C, - 0xEEBF, 0x8E47, 0xEEC0, 0x8F43, 0xEEC1, 0x8F40, 0xEEC2, 0x9085, 0xEEC3, 0x907E, 0xEEC4, 0x9138, 0xEEC5, 0x919A, 0xEEC6, 0x91A2, - 0xEEC7, 0x919B, 0xEEC8, 0x9199, 0xEEC9, 0x919F, 0xEECA, 0x91A1, 0xEECB, 0x919D, 0xEECC, 0x91A0, 0xEECD, 0x93A1, 0xEECE, 0x9383, - 0xEECF, 0x93AF, 0xEED0, 0x9364, 0xEED1, 0x9356, 0xEED2, 0x9347, 0xEED3, 0x937C, 0xEED4, 0x9358, 0xEED5, 0x935C, 0xEED6, 0x9376, - 0xEED7, 0x9349, 0xEED8, 0x9350, 0xEED9, 0x9351, 0xEEDA, 0x9360, 0xEEDB, 0x936D, 0xEEDC, 0x938F, 0xEEDD, 0x934C, 0xEEDE, 0x936A, - 0xEEDF, 0x9379, 0xEEE0, 0x9357, 0xEEE1, 0x9355, 0xEEE2, 0x9352, 0xEEE3, 0x934F, 0xEEE4, 0x9371, 0xEEE5, 0x9377, 0xEEE6, 0x937B, - 0xEEE7, 0x9361, 0xEEE8, 0x935E, 0xEEE9, 0x9363, 0xEEEA, 0x9367, 0xEEEB, 0x9380, 0xEEEC, 0x934E, 0xEEED, 0x9359, 0xEEEE, 0x95C7, - 0xEEEF, 0x95C0, 0xEEF0, 0x95C9, 0xEEF1, 0x95C3, 0xEEF2, 0x95C5, 0xEEF3, 0x95B7, 0xEEF4, 0x96AE, 0xEEF5, 0x96B0, 0xEEF6, 0x96AC, - 0xEEF7, 0x9720, 0xEEF8, 0x971F, 0xEEF9, 0x9718, 0xEEFA, 0x971D, 0xEEFB, 0x9719, 0xEEFC, 0x979A, 0xEEFD, 0x97A1, 0xEEFE, 0x979C, - 0xEF40, 0x979E, 0xEF41, 0x979D, 0xEF42, 0x97D5, 0xEF43, 0x97D4, 0xEF44, 0x97F1, 0xEF45, 0x9841, 0xEF46, 0x9844, 0xEF47, 0x984A, - 0xEF48, 0x9849, 0xEF49, 0x9845, 0xEF4A, 0x9843, 0xEF4B, 0x9925, 0xEF4C, 0x992B, 0xEF4D, 0x992C, 0xEF4E, 0x992A, 0xEF4F, 0x9933, - 0xEF50, 0x9932, 0xEF51, 0x992F, 0xEF52, 0x992D, 0xEF53, 0x9931, 0xEF54, 0x9930, 0xEF55, 0x9998, 0xEF56, 0x99A3, 0xEF57, 0x99A1, - 0xEF58, 0x9A02, 0xEF59, 0x99FA, 0xEF5A, 0x99F4, 0xEF5B, 0x99F7, 0xEF5C, 0x99F9, 0xEF5D, 0x99F8, 0xEF5E, 0x99F6, 0xEF5F, 0x99FB, - 0xEF60, 0x99FD, 0xEF61, 0x99FE, 0xEF62, 0x99FC, 0xEF63, 0x9A03, 0xEF64, 0x9ABE, 0xEF65, 0x9AFE, 0xEF66, 0x9AFD, 0xEF67, 0x9B01, - 0xEF68, 0x9AFC, 0xEF69, 0x9B48, 0xEF6A, 0x9B9A, 0xEF6B, 0x9BA8, 0xEF6C, 0x9B9E, 0xEF6D, 0x9B9B, 0xEF6E, 0x9BA6, 0xEF6F, 0x9BA1, - 0xEF70, 0x9BA5, 0xEF71, 0x9BA4, 0xEF72, 0x9B86, 0xEF73, 0x9BA2, 0xEF74, 0x9BA0, 0xEF75, 0x9BAF, 0xEF76, 0x9D33, 0xEF77, 0x9D41, - 0xEF78, 0x9D67, 0xEF79, 0x9D36, 0xEF7A, 0x9D2E, 0xEF7B, 0x9D2F, 0xEF7C, 0x9D31, 0xEF7D, 0x9D38, 0xEF7E, 0x9D30, 0xEFA1, 0x9D45, - 0xEFA2, 0x9D42, 0xEFA3, 0x9D43, 0xEFA4, 0x9D3E, 0xEFA5, 0x9D37, 0xEFA6, 0x9D40, 0xEFA7, 0x9D3D, 0xEFA8, 0x7FF5, 0xEFA9, 0x9D2D, - 0xEFAA, 0x9E8A, 0xEFAB, 0x9E89, 0xEFAC, 0x9E8D, 0xEFAD, 0x9EB0, 0xEFAE, 0x9EC8, 0xEFAF, 0x9EDA, 0xEFB0, 0x9EFB, 0xEFB1, 0x9EFF, - 0xEFB2, 0x9F24, 0xEFB3, 0x9F23, 0xEFB4, 0x9F22, 0xEFB5, 0x9F54, 0xEFB6, 0x9FA0, 0xEFB7, 0x5131, 0xEFB8, 0x512D, 0xEFB9, 0x512E, - 0xEFBA, 0x5698, 0xEFBB, 0x569C, 0xEFBC, 0x5697, 0xEFBD, 0x569A, 0xEFBE, 0x569D, 0xEFBF, 0x5699, 0xEFC0, 0x5970, 0xEFC1, 0x5B3C, - 0xEFC2, 0x5C69, 0xEFC3, 0x5C6A, 0xEFC4, 0x5DC0, 0xEFC5, 0x5E6D, 0xEFC6, 0x5E6E, 0xEFC7, 0x61D8, 0xEFC8, 0x61DF, 0xEFC9, 0x61ED, - 0xEFCA, 0x61EE, 0xEFCB, 0x61F1, 0xEFCC, 0x61EA, 0xEFCD, 0x61F0, 0xEFCE, 0x61EB, 0xEFCF, 0x61D6, 0xEFD0, 0x61E9, 0xEFD1, 0x64FF, - 0xEFD2, 0x6504, 0xEFD3, 0x64FD, 0xEFD4, 0x64F8, 0xEFD5, 0x6501, 0xEFD6, 0x6503, 0xEFD7, 0x64FC, 0xEFD8, 0x6594, 0xEFD9, 0x65DB, - 0xEFDA, 0x66DA, 0xEFDB, 0x66DB, 0xEFDC, 0x66D8, 0xEFDD, 0x6AC5, 0xEFDE, 0x6AB9, 0xEFDF, 0x6ABD, 0xEFE0, 0x6AE1, 0xEFE1, 0x6AC6, - 0xEFE2, 0x6ABA, 0xEFE3, 0x6AB6, 0xEFE4, 0x6AB7, 0xEFE5, 0x6AC7, 0xEFE6, 0x6AB4, 0xEFE7, 0x6AAD, 0xEFE8, 0x6B5E, 0xEFE9, 0x6BC9, - 0xEFEA, 0x6C0B, 0xEFEB, 0x7007, 0xEFEC, 0x700C, 0xEFED, 0x700D, 0xEFEE, 0x7001, 0xEFEF, 0x7005, 0xEFF0, 0x7014, 0xEFF1, 0x700E, - 0xEFF2, 0x6FFF, 0xEFF3, 0x7000, 0xEFF4, 0x6FFB, 0xEFF5, 0x7026, 0xEFF6, 0x6FFC, 0xEFF7, 0x6FF7, 0xEFF8, 0x700A, 0xEFF9, 0x7201, - 0xEFFA, 0x71FF, 0xEFFB, 0x71F9, 0xEFFC, 0x7203, 0xEFFD, 0x71FD, 0xEFFE, 0x7376, 0xF040, 0x74B8, 0xF041, 0x74C0, 0xF042, 0x74B5, - 0xF043, 0x74C1, 0xF044, 0x74BE, 0xF045, 0x74B6, 0xF046, 0x74BB, 0xF047, 0x74C2, 0xF048, 0x7514, 0xF049, 0x7513, 0xF04A, 0x765C, - 0xF04B, 0x7664, 0xF04C, 0x7659, 0xF04D, 0x7650, 0xF04E, 0x7653, 0xF04F, 0x7657, 0xF050, 0x765A, 0xF051, 0x76A6, 0xF052, 0x76BD, - 0xF053, 0x76EC, 0xF054, 0x77C2, 0xF055, 0x77BA, 0xF056, 0x78FF, 0xF057, 0x790C, 0xF058, 0x7913, 0xF059, 0x7914, 0xF05A, 0x7909, - 0xF05B, 0x7910, 0xF05C, 0x7912, 0xF05D, 0x7911, 0xF05E, 0x79AD, 0xF05F, 0x79AC, 0xF060, 0x7A5F, 0xF061, 0x7C1C, 0xF062, 0x7C29, - 0xF063, 0x7C19, 0xF064, 0x7C20, 0xF065, 0x7C1F, 0xF066, 0x7C2D, 0xF067, 0x7C1D, 0xF068, 0x7C26, 0xF069, 0x7C28, 0xF06A, 0x7C22, - 0xF06B, 0x7C25, 0xF06C, 0x7C30, 0xF06D, 0x7E5C, 0xF06E, 0x7E50, 0xF06F, 0x7E56, 0xF070, 0x7E63, 0xF071, 0x7E58, 0xF072, 0x7E62, - 0xF073, 0x7E5F, 0xF074, 0x7E51, 0xF075, 0x7E60, 0xF076, 0x7E57, 0xF077, 0x7E53, 0xF078, 0x7FB5, 0xF079, 0x7FB3, 0xF07A, 0x7FF7, - 0xF07B, 0x7FF8, 0xF07C, 0x8075, 0xF07D, 0x81D1, 0xF07E, 0x81D2, 0xF0A1, 0x81D0, 0xF0A2, 0x825F, 0xF0A3, 0x825E, 0xF0A4, 0x85B4, - 0xF0A5, 0x85C6, 0xF0A6, 0x85C0, 0xF0A7, 0x85C3, 0xF0A8, 0x85C2, 0xF0A9, 0x85B3, 0xF0AA, 0x85B5, 0xF0AB, 0x85BD, 0xF0AC, 0x85C7, - 0xF0AD, 0x85C4, 0xF0AE, 0x85BF, 0xF0AF, 0x85CB, 0xF0B0, 0x85CE, 0xF0B1, 0x85C8, 0xF0B2, 0x85C5, 0xF0B3, 0x85B1, 0xF0B4, 0x85B6, - 0xF0B5, 0x85D2, 0xF0B6, 0x8624, 0xF0B7, 0x85B8, 0xF0B8, 0x85B7, 0xF0B9, 0x85BE, 0xF0BA, 0x8669, 0xF0BB, 0x87E7, 0xF0BC, 0x87E6, - 0xF0BD, 0x87E2, 0xF0BE, 0x87DB, 0xF0BF, 0x87EB, 0xF0C0, 0x87EA, 0xF0C1, 0x87E5, 0xF0C2, 0x87DF, 0xF0C3, 0x87F3, 0xF0C4, 0x87E4, - 0xF0C5, 0x87D4, 0xF0C6, 0x87DC, 0xF0C7, 0x87D3, 0xF0C8, 0x87ED, 0xF0C9, 0x87D8, 0xF0CA, 0x87E3, 0xF0CB, 0x87A4, 0xF0CC, 0x87D7, - 0xF0CD, 0x87D9, 0xF0CE, 0x8801, 0xF0CF, 0x87F4, 0xF0D0, 0x87E8, 0xF0D1, 0x87DD, 0xF0D2, 0x8953, 0xF0D3, 0x894B, 0xF0D4, 0x894F, - 0xF0D5, 0x894C, 0xF0D6, 0x8946, 0xF0D7, 0x8950, 0xF0D8, 0x8951, 0xF0D9, 0x8949, 0xF0DA, 0x8B2A, 0xF0DB, 0x8B27, 0xF0DC, 0x8B23, - 0xF0DD, 0x8B33, 0xF0DE, 0x8B30, 0xF0DF, 0x8B35, 0xF0E0, 0x8B47, 0xF0E1, 0x8B2F, 0xF0E2, 0x8B3C, 0xF0E3, 0x8B3E, 0xF0E4, 0x8B31, - 0xF0E5, 0x8B25, 0xF0E6, 0x8B37, 0xF0E7, 0x8B26, 0xF0E8, 0x8B36, 0xF0E9, 0x8B2E, 0xF0EA, 0x8B24, 0xF0EB, 0x8B3B, 0xF0EC, 0x8B3D, - 0xF0ED, 0x8B3A, 0xF0EE, 0x8C42, 0xF0EF, 0x8C75, 0xF0F0, 0x8C99, 0xF0F1, 0x8C98, 0xF0F2, 0x8C97, 0xF0F3, 0x8CFE, 0xF0F4, 0x8D04, - 0xF0F5, 0x8D02, 0xF0F6, 0x8D00, 0xF0F7, 0x8E5C, 0xF0F8, 0x8E62, 0xF0F9, 0x8E60, 0xF0FA, 0x8E57, 0xF0FB, 0x8E56, 0xF0FC, 0x8E5E, - 0xF0FD, 0x8E65, 0xF0FE, 0x8E67, 0xF140, 0x8E5B, 0xF141, 0x8E5A, 0xF142, 0x8E61, 0xF143, 0x8E5D, 0xF144, 0x8E69, 0xF145, 0x8E54, - 0xF146, 0x8F46, 0xF147, 0x8F47, 0xF148, 0x8F48, 0xF149, 0x8F4B, 0xF14A, 0x9128, 0xF14B, 0x913A, 0xF14C, 0x913B, 0xF14D, 0x913E, - 0xF14E, 0x91A8, 0xF14F, 0x91A5, 0xF150, 0x91A7, 0xF151, 0x91AF, 0xF152, 0x91AA, 0xF153, 0x93B5, 0xF154, 0x938C, 0xF155, 0x9392, - 0xF156, 0x93B7, 0xF157, 0x939B, 0xF158, 0x939D, 0xF159, 0x9389, 0xF15A, 0x93A7, 0xF15B, 0x938E, 0xF15C, 0x93AA, 0xF15D, 0x939E, - 0xF15E, 0x93A6, 0xF15F, 0x9395, 0xF160, 0x9388, 0xF161, 0x9399, 0xF162, 0x939F, 0xF163, 0x938D, 0xF164, 0x93B1, 0xF165, 0x9391, - 0xF166, 0x93B2, 0xF167, 0x93A4, 0xF168, 0x93A8, 0xF169, 0x93B4, 0xF16A, 0x93A3, 0xF16B, 0x93A5, 0xF16C, 0x95D2, 0xF16D, 0x95D3, - 0xF16E, 0x95D1, 0xF16F, 0x96B3, 0xF170, 0x96D7, 0xF171, 0x96DA, 0xF172, 0x5DC2, 0xF173, 0x96DF, 0xF174, 0x96D8, 0xF175, 0x96DD, - 0xF176, 0x9723, 0xF177, 0x9722, 0xF178, 0x9725, 0xF179, 0x97AC, 0xF17A, 0x97AE, 0xF17B, 0x97A8, 0xF17C, 0x97AB, 0xF17D, 0x97A4, - 0xF17E, 0x97AA, 0xF1A1, 0x97A2, 0xF1A2, 0x97A5, 0xF1A3, 0x97D7, 0xF1A4, 0x97D9, 0xF1A5, 0x97D6, 0xF1A6, 0x97D8, 0xF1A7, 0x97FA, - 0xF1A8, 0x9850, 0xF1A9, 0x9851, 0xF1AA, 0x9852, 0xF1AB, 0x98B8, 0xF1AC, 0x9941, 0xF1AD, 0x993C, 0xF1AE, 0x993A, 0xF1AF, 0x9A0F, - 0xF1B0, 0x9A0B, 0xF1B1, 0x9A09, 0xF1B2, 0x9A0D, 0xF1B3, 0x9A04, 0xF1B4, 0x9A11, 0xF1B5, 0x9A0A, 0xF1B6, 0x9A05, 0xF1B7, 0x9A07, - 0xF1B8, 0x9A06, 0xF1B9, 0x9AC0, 0xF1BA, 0x9ADC, 0xF1BB, 0x9B08, 0xF1BC, 0x9B04, 0xF1BD, 0x9B05, 0xF1BE, 0x9B29, 0xF1BF, 0x9B35, - 0xF1C0, 0x9B4A, 0xF1C1, 0x9B4C, 0xF1C2, 0x9B4B, 0xF1C3, 0x9BC7, 0xF1C4, 0x9BC6, 0xF1C5, 0x9BC3, 0xF1C6, 0x9BBF, 0xF1C7, 0x9BC1, - 0xF1C8, 0x9BB5, 0xF1C9, 0x9BB8, 0xF1CA, 0x9BD3, 0xF1CB, 0x9BB6, 0xF1CC, 0x9BC4, 0xF1CD, 0x9BB9, 0xF1CE, 0x9BBD, 0xF1CF, 0x9D5C, - 0xF1D0, 0x9D53, 0xF1D1, 0x9D4F, 0xF1D2, 0x9D4A, 0xF1D3, 0x9D5B, 0xF1D4, 0x9D4B, 0xF1D5, 0x9D59, 0xF1D6, 0x9D56, 0xF1D7, 0x9D4C, - 0xF1D8, 0x9D57, 0xF1D9, 0x9D52, 0xF1DA, 0x9D54, 0xF1DB, 0x9D5F, 0xF1DC, 0x9D58, 0xF1DD, 0x9D5A, 0xF1DE, 0x9E8E, 0xF1DF, 0x9E8C, - 0xF1E0, 0x9EDF, 0xF1E1, 0x9F01, 0xF1E2, 0x9F00, 0xF1E3, 0x9F16, 0xF1E4, 0x9F25, 0xF1E5, 0x9F2B, 0xF1E6, 0x9F2A, 0xF1E7, 0x9F29, - 0xF1E8, 0x9F28, 0xF1E9, 0x9F4C, 0xF1EA, 0x9F55, 0xF1EB, 0x5134, 0xF1EC, 0x5135, 0xF1ED, 0x5296, 0xF1EE, 0x52F7, 0xF1EF, 0x53B4, - 0xF1F0, 0x56AB, 0xF1F1, 0x56AD, 0xF1F2, 0x56A6, 0xF1F3, 0x56A7, 0xF1F4, 0x56AA, 0xF1F5, 0x56AC, 0xF1F6, 0x58DA, 0xF1F7, 0x58DD, - 0xF1F8, 0x58DB, 0xF1F9, 0x5912, 0xF1FA, 0x5B3D, 0xF1FB, 0x5B3E, 0xF1FC, 0x5B3F, 0xF1FD, 0x5DC3, 0xF1FE, 0x5E70, 0xF240, 0x5FBF, - 0xF241, 0x61FB, 0xF242, 0x6507, 0xF243, 0x6510, 0xF244, 0x650D, 0xF245, 0x6509, 0xF246, 0x650C, 0xF247, 0x650E, 0xF248, 0x6584, - 0xF249, 0x65DE, 0xF24A, 0x65DD, 0xF24B, 0x66DE, 0xF24C, 0x6AE7, 0xF24D, 0x6AE0, 0xF24E, 0x6ACC, 0xF24F, 0x6AD1, 0xF250, 0x6AD9, - 0xF251, 0x6ACB, 0xF252, 0x6ADF, 0xF253, 0x6ADC, 0xF254, 0x6AD0, 0xF255, 0x6AEB, 0xF256, 0x6ACF, 0xF257, 0x6ACD, 0xF258, 0x6ADE, - 0xF259, 0x6B60, 0xF25A, 0x6BB0, 0xF25B, 0x6C0C, 0xF25C, 0x7019, 0xF25D, 0x7027, 0xF25E, 0x7020, 0xF25F, 0x7016, 0xF260, 0x702B, - 0xF261, 0x7021, 0xF262, 0x7022, 0xF263, 0x7023, 0xF264, 0x7029, 0xF265, 0x7017, 0xF266, 0x7024, 0xF267, 0x701C, 0xF268, 0x702A, - 0xF269, 0x720C, 0xF26A, 0x720A, 0xF26B, 0x7207, 0xF26C, 0x7202, 0xF26D, 0x7205, 0xF26E, 0x72A5, 0xF26F, 0x72A6, 0xF270, 0x72A4, - 0xF271, 0x72A3, 0xF272, 0x72A1, 0xF273, 0x74CB, 0xF274, 0x74C5, 0xF275, 0x74B7, 0xF276, 0x74C3, 0xF277, 0x7516, 0xF278, 0x7660, - 0xF279, 0x77C9, 0xF27A, 0x77CA, 0xF27B, 0x77C4, 0xF27C, 0x77F1, 0xF27D, 0x791D, 0xF27E, 0x791B, 0xF2A1, 0x7921, 0xF2A2, 0x791C, - 0xF2A3, 0x7917, 0xF2A4, 0x791E, 0xF2A5, 0x79B0, 0xF2A6, 0x7A67, 0xF2A7, 0x7A68, 0xF2A8, 0x7C33, 0xF2A9, 0x7C3C, 0xF2AA, 0x7C39, - 0xF2AB, 0x7C2C, 0xF2AC, 0x7C3B, 0xF2AD, 0x7CEC, 0xF2AE, 0x7CEA, 0xF2AF, 0x7E76, 0xF2B0, 0x7E75, 0xF2B1, 0x7E78, 0xF2B2, 0x7E70, - 0xF2B3, 0x7E77, 0xF2B4, 0x7E6F, 0xF2B5, 0x7E7A, 0xF2B6, 0x7E72, 0xF2B7, 0x7E74, 0xF2B8, 0x7E68, 0xF2B9, 0x7F4B, 0xF2BA, 0x7F4A, - 0xF2BB, 0x7F83, 0xF2BC, 0x7F86, 0xF2BD, 0x7FB7, 0xF2BE, 0x7FFD, 0xF2BF, 0x7FFE, 0xF2C0, 0x8078, 0xF2C1, 0x81D7, 0xF2C2, 0x81D5, - 0xF2C3, 0x8264, 0xF2C4, 0x8261, 0xF2C5, 0x8263, 0xF2C6, 0x85EB, 0xF2C7, 0x85F1, 0xF2C8, 0x85ED, 0xF2C9, 0x85D9, 0xF2CA, 0x85E1, - 0xF2CB, 0x85E8, 0xF2CC, 0x85DA, 0xF2CD, 0x85D7, 0xF2CE, 0x85EC, 0xF2CF, 0x85F2, 0xF2D0, 0x85F8, 0xF2D1, 0x85D8, 0xF2D2, 0x85DF, - 0xF2D3, 0x85E3, 0xF2D4, 0x85DC, 0xF2D5, 0x85D1, 0xF2D6, 0x85F0, 0xF2D7, 0x85E6, 0xF2D8, 0x85EF, 0xF2D9, 0x85DE, 0xF2DA, 0x85E2, - 0xF2DB, 0x8800, 0xF2DC, 0x87FA, 0xF2DD, 0x8803, 0xF2DE, 0x87F6, 0xF2DF, 0x87F7, 0xF2E0, 0x8809, 0xF2E1, 0x880C, 0xF2E2, 0x880B, - 0xF2E3, 0x8806, 0xF2E4, 0x87FC, 0xF2E5, 0x8808, 0xF2E6, 0x87FF, 0xF2E7, 0x880A, 0xF2E8, 0x8802, 0xF2E9, 0x8962, 0xF2EA, 0x895A, - 0xF2EB, 0x895B, 0xF2EC, 0x8957, 0xF2ED, 0x8961, 0xF2EE, 0x895C, 0xF2EF, 0x8958, 0xF2F0, 0x895D, 0xF2F1, 0x8959, 0xF2F2, 0x8988, - 0xF2F3, 0x89B7, 0xF2F4, 0x89B6, 0xF2F5, 0x89F6, 0xF2F6, 0x8B50, 0xF2F7, 0x8B48, 0xF2F8, 0x8B4A, 0xF2F9, 0x8B40, 0xF2FA, 0x8B53, - 0xF2FB, 0x8B56, 0xF2FC, 0x8B54, 0xF2FD, 0x8B4B, 0xF2FE, 0x8B55, 0xF340, 0x8B51, 0xF341, 0x8B42, 0xF342, 0x8B52, 0xF343, 0x8B57, - 0xF344, 0x8C43, 0xF345, 0x8C77, 0xF346, 0x8C76, 0xF347, 0x8C9A, 0xF348, 0x8D06, 0xF349, 0x8D07, 0xF34A, 0x8D09, 0xF34B, 0x8DAC, - 0xF34C, 0x8DAA, 0xF34D, 0x8DAD, 0xF34E, 0x8DAB, 0xF34F, 0x8E6D, 0xF350, 0x8E78, 0xF351, 0x8E73, 0xF352, 0x8E6A, 0xF353, 0x8E6F, - 0xF354, 0x8E7B, 0xF355, 0x8EC2, 0xF356, 0x8F52, 0xF357, 0x8F51, 0xF358, 0x8F4F, 0xF359, 0x8F50, 0xF35A, 0x8F53, 0xF35B, 0x8FB4, - 0xF35C, 0x9140, 0xF35D, 0x913F, 0xF35E, 0x91B0, 0xF35F, 0x91AD, 0xF360, 0x93DE, 0xF361, 0x93C7, 0xF362, 0x93CF, 0xF363, 0x93C2, - 0xF364, 0x93DA, 0xF365, 0x93D0, 0xF366, 0x93F9, 0xF367, 0x93EC, 0xF368, 0x93CC, 0xF369, 0x93D9, 0xF36A, 0x93A9, 0xF36B, 0x93E6, - 0xF36C, 0x93CA, 0xF36D, 0x93D4, 0xF36E, 0x93EE, 0xF36F, 0x93E3, 0xF370, 0x93D5, 0xF371, 0x93C4, 0xF372, 0x93CE, 0xF373, 0x93C0, - 0xF374, 0x93D2, 0xF375, 0x93E7, 0xF376, 0x957D, 0xF377, 0x95DA, 0xF378, 0x95DB, 0xF379, 0x96E1, 0xF37A, 0x9729, 0xF37B, 0x972B, - 0xF37C, 0x972C, 0xF37D, 0x9728, 0xF37E, 0x9726, 0xF3A1, 0x97B3, 0xF3A2, 0x97B7, 0xF3A3, 0x97B6, 0xF3A4, 0x97DD, 0xF3A5, 0x97DE, - 0xF3A6, 0x97DF, 0xF3A7, 0x985C, 0xF3A8, 0x9859, 0xF3A9, 0x985D, 0xF3AA, 0x9857, 0xF3AB, 0x98BF, 0xF3AC, 0x98BD, 0xF3AD, 0x98BB, - 0xF3AE, 0x98BE, 0xF3AF, 0x9948, 0xF3B0, 0x9947, 0xF3B1, 0x9943, 0xF3B2, 0x99A6, 0xF3B3, 0x99A7, 0xF3B4, 0x9A1A, 0xF3B5, 0x9A15, - 0xF3B6, 0x9A25, 0xF3B7, 0x9A1D, 0xF3B8, 0x9A24, 0xF3B9, 0x9A1B, 0xF3BA, 0x9A22, 0xF3BB, 0x9A20, 0xF3BC, 0x9A27, 0xF3BD, 0x9A23, - 0xF3BE, 0x9A1E, 0xF3BF, 0x9A1C, 0xF3C0, 0x9A14, 0xF3C1, 0x9AC2, 0xF3C2, 0x9B0B, 0xF3C3, 0x9B0A, 0xF3C4, 0x9B0E, 0xF3C5, 0x9B0C, - 0xF3C6, 0x9B37, 0xF3C7, 0x9BEA, 0xF3C8, 0x9BEB, 0xF3C9, 0x9BE0, 0xF3CA, 0x9BDE, 0xF3CB, 0x9BE4, 0xF3CC, 0x9BE6, 0xF3CD, 0x9BE2, - 0xF3CE, 0x9BF0, 0xF3CF, 0x9BD4, 0xF3D0, 0x9BD7, 0xF3D1, 0x9BEC, 0xF3D2, 0x9BDC, 0xF3D3, 0x9BD9, 0xF3D4, 0x9BE5, 0xF3D5, 0x9BD5, - 0xF3D6, 0x9BE1, 0xF3D7, 0x9BDA, 0xF3D8, 0x9D77, 0xF3D9, 0x9D81, 0xF3DA, 0x9D8A, 0xF3DB, 0x9D84, 0xF3DC, 0x9D88, 0xF3DD, 0x9D71, - 0xF3DE, 0x9D80, 0xF3DF, 0x9D78, 0xF3E0, 0x9D86, 0xF3E1, 0x9D8B, 0xF3E2, 0x9D8C, 0xF3E3, 0x9D7D, 0xF3E4, 0x9D6B, 0xF3E5, 0x9D74, - 0xF3E6, 0x9D75, 0xF3E7, 0x9D70, 0xF3E8, 0x9D69, 0xF3E9, 0x9D85, 0xF3EA, 0x9D73, 0xF3EB, 0x9D7B, 0xF3EC, 0x9D82, 0xF3ED, 0x9D6F, - 0xF3EE, 0x9D79, 0xF3EF, 0x9D7F, 0xF3F0, 0x9D87, 0xF3F1, 0x9D68, 0xF3F2, 0x9E94, 0xF3F3, 0x9E91, 0xF3F4, 0x9EC0, 0xF3F5, 0x9EFC, - 0xF3F6, 0x9F2D, 0xF3F7, 0x9F40, 0xF3F8, 0x9F41, 0xF3F9, 0x9F4D, 0xF3FA, 0x9F56, 0xF3FB, 0x9F57, 0xF3FC, 0x9F58, 0xF3FD, 0x5337, - 0xF3FE, 0x56B2, 0xF440, 0x56B5, 0xF441, 0x56B3, 0xF442, 0x58E3, 0xF443, 0x5B45, 0xF444, 0x5DC6, 0xF445, 0x5DC7, 0xF446, 0x5EEE, - 0xF447, 0x5EEF, 0xF448, 0x5FC0, 0xF449, 0x5FC1, 0xF44A, 0x61F9, 0xF44B, 0x6517, 0xF44C, 0x6516, 0xF44D, 0x6515, 0xF44E, 0x6513, - 0xF44F, 0x65DF, 0xF450, 0x66E8, 0xF451, 0x66E3, 0xF452, 0x66E4, 0xF453, 0x6AF3, 0xF454, 0x6AF0, 0xF455, 0x6AEA, 0xF456, 0x6AE8, - 0xF457, 0x6AF9, 0xF458, 0x6AF1, 0xF459, 0x6AEE, 0xF45A, 0x6AEF, 0xF45B, 0x703C, 0xF45C, 0x7035, 0xF45D, 0x702F, 0xF45E, 0x7037, - 0xF45F, 0x7034, 0xF460, 0x7031, 0xF461, 0x7042, 0xF462, 0x7038, 0xF463, 0x703F, 0xF464, 0x703A, 0xF465, 0x7039, 0xF466, 0x7040, - 0xF467, 0x703B, 0xF468, 0x7033, 0xF469, 0x7041, 0xF46A, 0x7213, 0xF46B, 0x7214, 0xF46C, 0x72A8, 0xF46D, 0x737D, 0xF46E, 0x737C, - 0xF46F, 0x74BA, 0xF470, 0x76AB, 0xF471, 0x76AA, 0xF472, 0x76BE, 0xF473, 0x76ED, 0xF474, 0x77CC, 0xF475, 0x77CE, 0xF476, 0x77CF, - 0xF477, 0x77CD, 0xF478, 0x77F2, 0xF479, 0x7925, 0xF47A, 0x7923, 0xF47B, 0x7927, 0xF47C, 0x7928, 0xF47D, 0x7924, 0xF47E, 0x7929, - 0xF4A1, 0x79B2, 0xF4A2, 0x7A6E, 0xF4A3, 0x7A6C, 0xF4A4, 0x7A6D, 0xF4A5, 0x7AF7, 0xF4A6, 0x7C49, 0xF4A7, 0x7C48, 0xF4A8, 0x7C4A, - 0xF4A9, 0x7C47, 0xF4AA, 0x7C45, 0xF4AB, 0x7CEE, 0xF4AC, 0x7E7B, 0xF4AD, 0x7E7E, 0xF4AE, 0x7E81, 0xF4AF, 0x7E80, 0xF4B0, 0x7FBA, - 0xF4B1, 0x7FFF, 0xF4B2, 0x8079, 0xF4B3, 0x81DB, 0xF4B4, 0x81D9, 0xF4B5, 0x820B, 0xF4B6, 0x8268, 0xF4B7, 0x8269, 0xF4B8, 0x8622, - 0xF4B9, 0x85FF, 0xF4BA, 0x8601, 0xF4BB, 0x85FE, 0xF4BC, 0x861B, 0xF4BD, 0x8600, 0xF4BE, 0x85F6, 0xF4BF, 0x8604, 0xF4C0, 0x8609, - 0xF4C1, 0x8605, 0xF4C2, 0x860C, 0xF4C3, 0x85FD, 0xF4C4, 0x8819, 0xF4C5, 0x8810, 0xF4C6, 0x8811, 0xF4C7, 0x8817, 0xF4C8, 0x8813, - 0xF4C9, 0x8816, 0xF4CA, 0x8963, 0xF4CB, 0x8966, 0xF4CC, 0x89B9, 0xF4CD, 0x89F7, 0xF4CE, 0x8B60, 0xF4CF, 0x8B6A, 0xF4D0, 0x8B5D, - 0xF4D1, 0x8B68, 0xF4D2, 0x8B63, 0xF4D3, 0x8B65, 0xF4D4, 0x8B67, 0xF4D5, 0x8B6D, 0xF4D6, 0x8DAE, 0xF4D7, 0x8E86, 0xF4D8, 0x8E88, - 0xF4D9, 0x8E84, 0xF4DA, 0x8F59, 0xF4DB, 0x8F56, 0xF4DC, 0x8F57, 0xF4DD, 0x8F55, 0xF4DE, 0x8F58, 0xF4DF, 0x8F5A, 0xF4E0, 0x908D, - 0xF4E1, 0x9143, 0xF4E2, 0x9141, 0xF4E3, 0x91B7, 0xF4E4, 0x91B5, 0xF4E5, 0x91B2, 0xF4E6, 0x91B3, 0xF4E7, 0x940B, 0xF4E8, 0x9413, - 0xF4E9, 0x93FB, 0xF4EA, 0x9420, 0xF4EB, 0x940F, 0xF4EC, 0x9414, 0xF4ED, 0x93FE, 0xF4EE, 0x9415, 0xF4EF, 0x9410, 0xF4F0, 0x9428, - 0xF4F1, 0x9419, 0xF4F2, 0x940D, 0xF4F3, 0x93F5, 0xF4F4, 0x9400, 0xF4F5, 0x93F7, 0xF4F6, 0x9407, 0xF4F7, 0x940E, 0xF4F8, 0x9416, - 0xF4F9, 0x9412, 0xF4FA, 0x93FA, 0xF4FB, 0x9409, 0xF4FC, 0x93F8, 0xF4FD, 0x940A, 0xF4FE, 0x93FF, 0xF540, 0x93FC, 0xF541, 0x940C, - 0xF542, 0x93F6, 0xF543, 0x9411, 0xF544, 0x9406, 0xF545, 0x95DE, 0xF546, 0x95E0, 0xF547, 0x95DF, 0xF548, 0x972E, 0xF549, 0x972F, - 0xF54A, 0x97B9, 0xF54B, 0x97BB, 0xF54C, 0x97FD, 0xF54D, 0x97FE, 0xF54E, 0x9860, 0xF54F, 0x9862, 0xF550, 0x9863, 0xF551, 0x985F, - 0xF552, 0x98C1, 0xF553, 0x98C2, 0xF554, 0x9950, 0xF555, 0x994E, 0xF556, 0x9959, 0xF557, 0x994C, 0xF558, 0x994B, 0xF559, 0x9953, - 0xF55A, 0x9A32, 0xF55B, 0x9A34, 0xF55C, 0x9A31, 0xF55D, 0x9A2C, 0xF55E, 0x9A2A, 0xF55F, 0x9A36, 0xF560, 0x9A29, 0xF561, 0x9A2E, - 0xF562, 0x9A38, 0xF563, 0x9A2D, 0xF564, 0x9AC7, 0xF565, 0x9ACA, 0xF566, 0x9AC6, 0xF567, 0x9B10, 0xF568, 0x9B12, 0xF569, 0x9B11, - 0xF56A, 0x9C0B, 0xF56B, 0x9C08, 0xF56C, 0x9BF7, 0xF56D, 0x9C05, 0xF56E, 0x9C12, 0xF56F, 0x9BF8, 0xF570, 0x9C40, 0xF571, 0x9C07, - 0xF572, 0x9C0E, 0xF573, 0x9C06, 0xF574, 0x9C17, 0xF575, 0x9C14, 0xF576, 0x9C09, 0xF577, 0x9D9F, 0xF578, 0x9D99, 0xF579, 0x9DA4, - 0xF57A, 0x9D9D, 0xF57B, 0x9D92, 0xF57C, 0x9D98, 0xF57D, 0x9D90, 0xF57E, 0x9D9B, 0xF5A1, 0x9DA0, 0xF5A2, 0x9D94, 0xF5A3, 0x9D9C, - 0xF5A4, 0x9DAA, 0xF5A5, 0x9D97, 0xF5A6, 0x9DA1, 0xF5A7, 0x9D9A, 0xF5A8, 0x9DA2, 0xF5A9, 0x9DA8, 0xF5AA, 0x9D9E, 0xF5AB, 0x9DA3, - 0xF5AC, 0x9DBF, 0xF5AD, 0x9DA9, 0xF5AE, 0x9D96, 0xF5AF, 0x9DA6, 0xF5B0, 0x9DA7, 0xF5B1, 0x9E99, 0xF5B2, 0x9E9B, 0xF5B3, 0x9E9A, - 0xF5B4, 0x9EE5, 0xF5B5, 0x9EE4, 0xF5B6, 0x9EE7, 0xF5B7, 0x9EE6, 0xF5B8, 0x9F30, 0xF5B9, 0x9F2E, 0xF5BA, 0x9F5B, 0xF5BB, 0x9F60, - 0xF5BC, 0x9F5E, 0xF5BD, 0x9F5D, 0xF5BE, 0x9F59, 0xF5BF, 0x9F91, 0xF5C0, 0x513A, 0xF5C1, 0x5139, 0xF5C2, 0x5298, 0xF5C3, 0x5297, - 0xF5C4, 0x56C3, 0xF5C5, 0x56BD, 0xF5C6, 0x56BE, 0xF5C7, 0x5B48, 0xF5C8, 0x5B47, 0xF5C9, 0x5DCB, 0xF5CA, 0x5DCF, 0xF5CB, 0x5EF1, - 0xF5CC, 0x61FD, 0xF5CD, 0x651B, 0xF5CE, 0x6B02, 0xF5CF, 0x6AFC, 0xF5D0, 0x6B03, 0xF5D1, 0x6AF8, 0xF5D2, 0x6B00, 0xF5D3, 0x7043, - 0xF5D4, 0x7044, 0xF5D5, 0x704A, 0xF5D6, 0x7048, 0xF5D7, 0x7049, 0xF5D8, 0x7045, 0xF5D9, 0x7046, 0xF5DA, 0x721D, 0xF5DB, 0x721A, - 0xF5DC, 0x7219, 0xF5DD, 0x737E, 0xF5DE, 0x7517, 0xF5DF, 0x766A, 0xF5E0, 0x77D0, 0xF5E1, 0x792D, 0xF5E2, 0x7931, 0xF5E3, 0x792F, - 0xF5E4, 0x7C54, 0xF5E5, 0x7C53, 0xF5E6, 0x7CF2, 0xF5E7, 0x7E8A, 0xF5E8, 0x7E87, 0xF5E9, 0x7E88, 0xF5EA, 0x7E8B, 0xF5EB, 0x7E86, - 0xF5EC, 0x7E8D, 0xF5ED, 0x7F4D, 0xF5EE, 0x7FBB, 0xF5EF, 0x8030, 0xF5F0, 0x81DD, 0xF5F1, 0x8618, 0xF5F2, 0x862A, 0xF5F3, 0x8626, - 0xF5F4, 0x861F, 0xF5F5, 0x8623, 0xF5F6, 0x861C, 0xF5F7, 0x8619, 0xF5F8, 0x8627, 0xF5F9, 0x862E, 0xF5FA, 0x8621, 0xF5FB, 0x8620, - 0xF5FC, 0x8629, 0xF5FD, 0x861E, 0xF5FE, 0x8625, 0xF640, 0x8829, 0xF641, 0x881D, 0xF642, 0x881B, 0xF643, 0x8820, 0xF644, 0x8824, - 0xF645, 0x881C, 0xF646, 0x882B, 0xF647, 0x884A, 0xF648, 0x896D, 0xF649, 0x8969, 0xF64A, 0x896E, 0xF64B, 0x896B, 0xF64C, 0x89FA, - 0xF64D, 0x8B79, 0xF64E, 0x8B78, 0xF64F, 0x8B45, 0xF650, 0x8B7A, 0xF651, 0x8B7B, 0xF652, 0x8D10, 0xF653, 0x8D14, 0xF654, 0x8DAF, - 0xF655, 0x8E8E, 0xF656, 0x8E8C, 0xF657, 0x8F5E, 0xF658, 0x8F5B, 0xF659, 0x8F5D, 0xF65A, 0x9146, 0xF65B, 0x9144, 0xF65C, 0x9145, - 0xF65D, 0x91B9, 0xF65E, 0x943F, 0xF65F, 0x943B, 0xF660, 0x9436, 0xF661, 0x9429, 0xF662, 0x943D, 0xF663, 0x943C, 0xF664, 0x9430, - 0xF665, 0x9439, 0xF666, 0x942A, 0xF667, 0x9437, 0xF668, 0x942C, 0xF669, 0x9440, 0xF66A, 0x9431, 0xF66B, 0x95E5, 0xF66C, 0x95E4, - 0xF66D, 0x95E3, 0xF66E, 0x9735, 0xF66F, 0x973A, 0xF670, 0x97BF, 0xF671, 0x97E1, 0xF672, 0x9864, 0xF673, 0x98C9, 0xF674, 0x98C6, - 0xF675, 0x98C0, 0xF676, 0x9958, 0xF677, 0x9956, 0xF678, 0x9A39, 0xF679, 0x9A3D, 0xF67A, 0x9A46, 0xF67B, 0x9A44, 0xF67C, 0x9A42, - 0xF67D, 0x9A41, 0xF67E, 0x9A3A, 0xF6A1, 0x9A3F, 0xF6A2, 0x9ACD, 0xF6A3, 0x9B15, 0xF6A4, 0x9B17, 0xF6A5, 0x9B18, 0xF6A6, 0x9B16, - 0xF6A7, 0x9B3A, 0xF6A8, 0x9B52, 0xF6A9, 0x9C2B, 0xF6AA, 0x9C1D, 0xF6AB, 0x9C1C, 0xF6AC, 0x9C2C, 0xF6AD, 0x9C23, 0xF6AE, 0x9C28, - 0xF6AF, 0x9C29, 0xF6B0, 0x9C24, 0xF6B1, 0x9C21, 0xF6B2, 0x9DB7, 0xF6B3, 0x9DB6, 0xF6B4, 0x9DBC, 0xF6B5, 0x9DC1, 0xF6B6, 0x9DC7, - 0xF6B7, 0x9DCA, 0xF6B8, 0x9DCF, 0xF6B9, 0x9DBE, 0xF6BA, 0x9DC5, 0xF6BB, 0x9DC3, 0xF6BC, 0x9DBB, 0xF6BD, 0x9DB5, 0xF6BE, 0x9DCE, - 0xF6BF, 0x9DB9, 0xF6C0, 0x9DBA, 0xF6C1, 0x9DAC, 0xF6C2, 0x9DC8, 0xF6C3, 0x9DB1, 0xF6C4, 0x9DAD, 0xF6C5, 0x9DCC, 0xF6C6, 0x9DB3, - 0xF6C7, 0x9DCD, 0xF6C8, 0x9DB2, 0xF6C9, 0x9E7A, 0xF6CA, 0x9E9C, 0xF6CB, 0x9EEB, 0xF6CC, 0x9EEE, 0xF6CD, 0x9EED, 0xF6CE, 0x9F1B, - 0xF6CF, 0x9F18, 0xF6D0, 0x9F1A, 0xF6D1, 0x9F31, 0xF6D2, 0x9F4E, 0xF6D3, 0x9F65, 0xF6D4, 0x9F64, 0xF6D5, 0x9F92, 0xF6D6, 0x4EB9, - 0xF6D7, 0x56C6, 0xF6D8, 0x56C5, 0xF6D9, 0x56CB, 0xF6DA, 0x5971, 0xF6DB, 0x5B4B, 0xF6DC, 0x5B4C, 0xF6DD, 0x5DD5, 0xF6DE, 0x5DD1, - 0xF6DF, 0x5EF2, 0xF6E0, 0x6521, 0xF6E1, 0x6520, 0xF6E2, 0x6526, 0xF6E3, 0x6522, 0xF6E4, 0x6B0B, 0xF6E5, 0x6B08, 0xF6E6, 0x6B09, - 0xF6E7, 0x6C0D, 0xF6E8, 0x7055, 0xF6E9, 0x7056, 0xF6EA, 0x7057, 0xF6EB, 0x7052, 0xF6EC, 0x721E, 0xF6ED, 0x721F, 0xF6EE, 0x72A9, - 0xF6EF, 0x737F, 0xF6F0, 0x74D8, 0xF6F1, 0x74D5, 0xF6F2, 0x74D9, 0xF6F3, 0x74D7, 0xF6F4, 0x766D, 0xF6F5, 0x76AD, 0xF6F6, 0x7935, - 0xF6F7, 0x79B4, 0xF6F8, 0x7A70, 0xF6F9, 0x7A71, 0xF6FA, 0x7C57, 0xF6FB, 0x7C5C, 0xF6FC, 0x7C59, 0xF6FD, 0x7C5B, 0xF6FE, 0x7C5A, - 0xF740, 0x7CF4, 0xF741, 0x7CF1, 0xF742, 0x7E91, 0xF743, 0x7F4F, 0xF744, 0x7F87, 0xF745, 0x81DE, 0xF746, 0x826B, 0xF747, 0x8634, - 0xF748, 0x8635, 0xF749, 0x8633, 0xF74A, 0x862C, 0xF74B, 0x8632, 0xF74C, 0x8636, 0xF74D, 0x882C, 0xF74E, 0x8828, 0xF74F, 0x8826, - 0xF750, 0x882A, 0xF751, 0x8825, 0xF752, 0x8971, 0xF753, 0x89BF, 0xF754, 0x89BE, 0xF755, 0x89FB, 0xF756, 0x8B7E, 0xF757, 0x8B84, - 0xF758, 0x8B82, 0xF759, 0x8B86, 0xF75A, 0x8B85, 0xF75B, 0x8B7F, 0xF75C, 0x8D15, 0xF75D, 0x8E95, 0xF75E, 0x8E94, 0xF75F, 0x8E9A, - 0xF760, 0x8E92, 0xF761, 0x8E90, 0xF762, 0x8E96, 0xF763, 0x8E97, 0xF764, 0x8F60, 0xF765, 0x8F62, 0xF766, 0x9147, 0xF767, 0x944C, - 0xF768, 0x9450, 0xF769, 0x944A, 0xF76A, 0x944B, 0xF76B, 0x944F, 0xF76C, 0x9447, 0xF76D, 0x9445, 0xF76E, 0x9448, 0xF76F, 0x9449, - 0xF770, 0x9446, 0xF771, 0x973F, 0xF772, 0x97E3, 0xF773, 0x986A, 0xF774, 0x9869, 0xF775, 0x98CB, 0xF776, 0x9954, 0xF777, 0x995B, - 0xF778, 0x9A4E, 0xF779, 0x9A53, 0xF77A, 0x9A54, 0xF77B, 0x9A4C, 0xF77C, 0x9A4F, 0xF77D, 0x9A48, 0xF77E, 0x9A4A, 0xF7A1, 0x9A49, - 0xF7A2, 0x9A52, 0xF7A3, 0x9A50, 0xF7A4, 0x9AD0, 0xF7A5, 0x9B19, 0xF7A6, 0x9B2B, 0xF7A7, 0x9B3B, 0xF7A8, 0x9B56, 0xF7A9, 0x9B55, - 0xF7AA, 0x9C46, 0xF7AB, 0x9C48, 0xF7AC, 0x9C3F, 0xF7AD, 0x9C44, 0xF7AE, 0x9C39, 0xF7AF, 0x9C33, 0xF7B0, 0x9C41, 0xF7B1, 0x9C3C, - 0xF7B2, 0x9C37, 0xF7B3, 0x9C34, 0xF7B4, 0x9C32, 0xF7B5, 0x9C3D, 0xF7B6, 0x9C36, 0xF7B7, 0x9DDB, 0xF7B8, 0x9DD2, 0xF7B9, 0x9DDE, - 0xF7BA, 0x9DDA, 0xF7BB, 0x9DCB, 0xF7BC, 0x9DD0, 0xF7BD, 0x9DDC, 0xF7BE, 0x9DD1, 0xF7BF, 0x9DDF, 0xF7C0, 0x9DE9, 0xF7C1, 0x9DD9, - 0xF7C2, 0x9DD8, 0xF7C3, 0x9DD6, 0xF7C4, 0x9DF5, 0xF7C5, 0x9DD5, 0xF7C6, 0x9DDD, 0xF7C7, 0x9EB6, 0xF7C8, 0x9EF0, 0xF7C9, 0x9F35, - 0xF7CA, 0x9F33, 0xF7CB, 0x9F32, 0xF7CC, 0x9F42, 0xF7CD, 0x9F6B, 0xF7CE, 0x9F95, 0xF7CF, 0x9FA2, 0xF7D0, 0x513D, 0xF7D1, 0x5299, - 0xF7D2, 0x58E8, 0xF7D3, 0x58E7, 0xF7D4, 0x5972, 0xF7D5, 0x5B4D, 0xF7D6, 0x5DD8, 0xF7D7, 0x882F, 0xF7D8, 0x5F4F, 0xF7D9, 0x6201, - 0xF7DA, 0x6203, 0xF7DB, 0x6204, 0xF7DC, 0x6529, 0xF7DD, 0x6525, 0xF7DE, 0x6596, 0xF7DF, 0x66EB, 0xF7E0, 0x6B11, 0xF7E1, 0x6B12, - 0xF7E2, 0x6B0F, 0xF7E3, 0x6BCA, 0xF7E4, 0x705B, 0xF7E5, 0x705A, 0xF7E6, 0x7222, 0xF7E7, 0x7382, 0xF7E8, 0x7381, 0xF7E9, 0x7383, - 0xF7EA, 0x7670, 0xF7EB, 0x77D4, 0xF7EC, 0x7C67, 0xF7ED, 0x7C66, 0xF7EE, 0x7E95, 0xF7EF, 0x826C, 0xF7F0, 0x863A, 0xF7F1, 0x8640, - 0xF7F2, 0x8639, 0xF7F3, 0x863C, 0xF7F4, 0x8631, 0xF7F5, 0x863B, 0xF7F6, 0x863E, 0xF7F7, 0x8830, 0xF7F8, 0x8832, 0xF7F9, 0x882E, - 0xF7FA, 0x8833, 0xF7FB, 0x8976, 0xF7FC, 0x8974, 0xF7FD, 0x8973, 0xF7FE, 0x89FE, 0xF840, 0x8B8C, 0xF841, 0x8B8E, 0xF842, 0x8B8B, - 0xF843, 0x8B88, 0xF844, 0x8C45, 0xF845, 0x8D19, 0xF846, 0x8E98, 0xF847, 0x8F64, 0xF848, 0x8F63, 0xF849, 0x91BC, 0xF84A, 0x9462, - 0xF84B, 0x9455, 0xF84C, 0x945D, 0xF84D, 0x9457, 0xF84E, 0x945E, 0xF84F, 0x97C4, 0xF850, 0x97C5, 0xF851, 0x9800, 0xF852, 0x9A56, - 0xF853, 0x9A59, 0xF854, 0x9B1E, 0xF855, 0x9B1F, 0xF856, 0x9B20, 0xF857, 0x9C52, 0xF858, 0x9C58, 0xF859, 0x9C50, 0xF85A, 0x9C4A, - 0xF85B, 0x9C4D, 0xF85C, 0x9C4B, 0xF85D, 0x9C55, 0xF85E, 0x9C59, 0xF85F, 0x9C4C, 0xF860, 0x9C4E, 0xF861, 0x9DFB, 0xF862, 0x9DF7, - 0xF863, 0x9DEF, 0xF864, 0x9DE3, 0xF865, 0x9DEB, 0xF866, 0x9DF8, 0xF867, 0x9DE4, 0xF868, 0x9DF6, 0xF869, 0x9DE1, 0xF86A, 0x9DEE, - 0xF86B, 0x9DE6, 0xF86C, 0x9DF2, 0xF86D, 0x9DF0, 0xF86E, 0x9DE2, 0xF86F, 0x9DEC, 0xF870, 0x9DF4, 0xF871, 0x9DF3, 0xF872, 0x9DE8, - 0xF873, 0x9DED, 0xF874, 0x9EC2, 0xF875, 0x9ED0, 0xF876, 0x9EF2, 0xF877, 0x9EF3, 0xF878, 0x9F06, 0xF879, 0x9F1C, 0xF87A, 0x9F38, - 0xF87B, 0x9F37, 0xF87C, 0x9F36, 0xF87D, 0x9F43, 0xF87E, 0x9F4F, 0xF8A1, 0x9F71, 0xF8A2, 0x9F70, 0xF8A3, 0x9F6E, 0xF8A4, 0x9F6F, - 0xF8A5, 0x56D3, 0xF8A6, 0x56CD, 0xF8A7, 0x5B4E, 0xF8A8, 0x5C6D, 0xF8A9, 0x652D, 0xF8AA, 0x66ED, 0xF8AB, 0x66EE, 0xF8AC, 0x6B13, - 0xF8AD, 0x705F, 0xF8AE, 0x7061, 0xF8AF, 0x705D, 0xF8B0, 0x7060, 0xF8B1, 0x7223, 0xF8B2, 0x74DB, 0xF8B3, 0x74E5, 0xF8B4, 0x77D5, - 0xF8B5, 0x7938, 0xF8B6, 0x79B7, 0xF8B7, 0x79B6, 0xF8B8, 0x7C6A, 0xF8B9, 0x7E97, 0xF8BA, 0x7F89, 0xF8BB, 0x826D, 0xF8BC, 0x8643, - 0xF8BD, 0x8838, 0xF8BE, 0x8837, 0xF8BF, 0x8835, 0xF8C0, 0x884B, 0xF8C1, 0x8B94, 0xF8C2, 0x8B95, 0xF8C3, 0x8E9E, 0xF8C4, 0x8E9F, - 0xF8C5, 0x8EA0, 0xF8C6, 0x8E9D, 0xF8C7, 0x91BE, 0xF8C8, 0x91BD, 0xF8C9, 0x91C2, 0xF8CA, 0x946B, 0xF8CB, 0x9468, 0xF8CC, 0x9469, - 0xF8CD, 0x96E5, 0xF8CE, 0x9746, 0xF8CF, 0x9743, 0xF8D0, 0x9747, 0xF8D1, 0x97C7, 0xF8D2, 0x97E5, 0xF8D3, 0x9A5E, 0xF8D4, 0x9AD5, - 0xF8D5, 0x9B59, 0xF8D6, 0x9C63, 0xF8D7, 0x9C67, 0xF8D8, 0x9C66, 0xF8D9, 0x9C62, 0xF8DA, 0x9C5E, 0xF8DB, 0x9C60, 0xF8DC, 0x9E02, - 0xF8DD, 0x9DFE, 0xF8DE, 0x9E07, 0xF8DF, 0x9E03, 0xF8E0, 0x9E06, 0xF8E1, 0x9E05, 0xF8E2, 0x9E00, 0xF8E3, 0x9E01, 0xF8E4, 0x9E09, - 0xF8E5, 0x9DFF, 0xF8E6, 0x9DFD, 0xF8E7, 0x9E04, 0xF8E8, 0x9EA0, 0xF8E9, 0x9F1E, 0xF8EA, 0x9F46, 0xF8EB, 0x9F74, 0xF8EC, 0x9F75, - 0xF8ED, 0x9F76, 0xF8EE, 0x56D4, 0xF8EF, 0x652E, 0xF8F0, 0x65B8, 0xF8F1, 0x6B18, 0xF8F2, 0x6B19, 0xF8F3, 0x6B17, 0xF8F4, 0x6B1A, - 0xF8F5, 0x7062, 0xF8F6, 0x7226, 0xF8F7, 0x72AA, 0xF8F8, 0x77D8, 0xF8F9, 0x77D9, 0xF8FA, 0x7939, 0xF8FB, 0x7C69, 0xF8FC, 0x7C6B, - 0xF8FD, 0x7CF6, 0xF8FE, 0x7E9A, 0xF940, 0x7E98, 0xF941, 0x7E9B, 0xF942, 0x7E99, 0xF943, 0x81E0, 0xF944, 0x81E1, 0xF945, 0x8646, - 0xF946, 0x8647, 0xF947, 0x8648, 0xF948, 0x8979, 0xF949, 0x897A, 0xF94A, 0x897C, 0xF94B, 0x897B, 0xF94C, 0x89FF, 0xF94D, 0x8B98, - 0xF94E, 0x8B99, 0xF94F, 0x8EA5, 0xF950, 0x8EA4, 0xF951, 0x8EA3, 0xF952, 0x946E, 0xF953, 0x946D, 0xF954, 0x946F, 0xF955, 0x9471, - 0xF956, 0x9473, 0xF957, 0x9749, 0xF958, 0x9872, 0xF959, 0x995F, 0xF95A, 0x9C68, 0xF95B, 0x9C6E, 0xF95C, 0x9C6D, 0xF95D, 0x9E0B, - 0xF95E, 0x9E0D, 0xF95F, 0x9E10, 0xF960, 0x9E0F, 0xF961, 0x9E12, 0xF962, 0x9E11, 0xF963, 0x9EA1, 0xF964, 0x9EF5, 0xF965, 0x9F09, - 0xF966, 0x9F47, 0xF967, 0x9F78, 0xF968, 0x9F7B, 0xF969, 0x9F7A, 0xF96A, 0x9F79, 0xF96B, 0x571E, 0xF96C, 0x7066, 0xF96D, 0x7C6F, - 0xF96E, 0x883C, 0xF96F, 0x8DB2, 0xF970, 0x8EA6, 0xF971, 0x91C3, 0xF972, 0x9474, 0xF973, 0x9478, 0xF974, 0x9476, 0xF975, 0x9475, - 0xF976, 0x9A60, 0xF977, 0x9C74, 0xF978, 0x9C73, 0xF979, 0x9C71, 0xF97A, 0x9C75, 0xF97B, 0x9E14, 0xF97C, 0x9E13, 0xF97D, 0x9EF6, - 0xF97E, 0x9F0A, 0xF9A1, 0x9FA4, 0xF9A2, 0x7068, 0xF9A3, 0x7065, 0xF9A4, 0x7CF7, 0xF9A5, 0x866A, 0xF9A6, 0x883E, 0xF9A7, 0x883D, - 0xF9A8, 0x883F, 0xF9A9, 0x8B9E, 0xF9AA, 0x8C9C, 0xF9AB, 0x8EA9, 0xF9AC, 0x8EC9, 0xF9AD, 0x974B, 0xF9AE, 0x9873, 0xF9AF, 0x9874, - 0xF9B0, 0x98CC, 0xF9B1, 0x9961, 0xF9B2, 0x99AB, 0xF9B3, 0x9A64, 0xF9B4, 0x9A66, 0xF9B5, 0x9A67, 0xF9B6, 0x9B24, 0xF9B7, 0x9E15, - 0xF9B8, 0x9E17, 0xF9B9, 0x9F48, 0xF9BA, 0x6207, 0xF9BB, 0x6B1E, 0xF9BC, 0x7227, 0xF9BD, 0x864C, 0xF9BE, 0x8EA8, 0xF9BF, 0x9482, - 0xF9C0, 0x9480, 0xF9C1, 0x9481, 0xF9C2, 0x9A69, 0xF9C3, 0x9A68, 0xF9C4, 0x9B2E, 0xF9C5, 0x9E19, 0xF9C6, 0x7229, 0xF9C7, 0x864B, - 0xF9C8, 0x8B9F, 0xF9C9, 0x9483, 0xF9CA, 0x9C79, 0xF9CB, 0x9EB7, 0xF9CC, 0x7675, 0xF9CD, 0x9A6B, 0xF9CE, 0x9C7A, 0xF9CF, 0x9E1D, - 0xF9D0, 0x7069, 0xF9D1, 0x706A, 0xF9D2, 0x9EA4, 0xF9D3, 0x9F7E, 0xF9D4, 0x9F49, 0xF9D5, 0x9F98, 0xF9D6, 0x7881, 0xF9D7, 0x92B9, - 0xF9D8, 0x88CF, 0xF9D9, 0x58BB, 0xF9DA, 0x6052, 0xF9DB, 0x7CA7, 0xF9DC, 0x5AFA, 0xF9DD, 0x2554, 0xF9DE, 0x2566, 0xF9DF, 0x2557, - 0xF9E0, 0x2560, 0xF9E1, 0x256C, 0xF9E2, 0x2563, 0xF9E3, 0x255A, 0xF9E4, 0x2569, 0xF9E5, 0x255D, 0xF9E6, 0x2552, 0xF9E7, 0x2564, - 0xF9E8, 0x2555, 0xF9E9, 0x255E, 0xF9EA, 0x256A, 0xF9EB, 0x2561, 0xF9EC, 0x2558, 0xF9ED, 0x2567, 0xF9EE, 0x255B, 0xF9EF, 0x2553, - 0xF9F0, 0x2565, 0xF9F1, 0x2556, 0xF9F2, 0x255F, 0xF9F3, 0x256B, 0xF9F4, 0x2562, 0xF9F5, 0x2559, 0xF9F6, 0x2568, 0xF9F7, 0x255C, - 0xF9F8, 0x2551, 0xF9F9, 0x2550, 0xF9FA, 0x256D, 0xF9FB, 0x256E, 0xF9FC, 0x2570, 0xF9FD, 0x256F, 0xF9FE, 0x2593, 0, 0 -}; -#endif - -#if FF_CODE_PAGE == 437 || FF_CODE_PAGE == 0 -static const WCHAR uc437[] = { /* CP437(U.S.) to Unicode conversion table */ - 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, - 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192, - 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, - 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, - 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, - 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, - 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, - 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 -}; -#endif -#if FF_CODE_PAGE == 720 || FF_CODE_PAGE == 0 -static const WCHAR uc720[] = { /* CP720(Arabic) to Unicode conversion table */ - 0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9, 0x0621, 0x0622, 0x0623, 0x0624, 0x00A3, 0x0625, 0x0626, 0x0627, - 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x00AB, 0x00BB, - 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, - 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, - 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, - 0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x00B5, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A, - 0x2261, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, 0x0650, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 -}; -#endif -#if FF_CODE_PAGE == 737 || FF_CODE_PAGE == 0 -static const WCHAR uc737[] = { /* CP737(Greek) to Unicode conversion table */ - 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0, - 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8, - 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, - 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, - 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, - 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, - 0x03C9, 0x03AC, 0x03AD, 0x03AE, 0x03CA, 0x03AF, 0x03CC, 0x03CD, 0x03CB, 0x03CE, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, 0x038E, - 0x038F, 0x00B1, 0x2265, 0x2264, 0x03AA, 0x03AB, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 -}; -#endif -#if FF_CODE_PAGE == 771 || FF_CODE_PAGE == 0 -static const WCHAR uc771[] = { /* CP771(KBL) to Unicode conversion table */ - 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, - 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, - 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, - 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510, - 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, - 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x0104, 0x0105, 0x010C, 0x010D, - 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F, - 0x0118, 0x0119, 0x0116, 0x0117, 0x012E, 0x012F, 0x0160, 0x0161, 0x0172, 0x0173, 0x016A, 0x016B, 0x017D, 0x017E, 0x25A0, 0x00A0 -}; -#endif -#if FF_CODE_PAGE == 775 || FF_CODE_PAGE == 0 -static const WCHAR uc775[] = { /* CP775(Baltic) to Unicode conversion table */ - 0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107, 0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5, - 0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A, 0x015B, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x00A4, - 0x0100, 0x012A, 0x00F3, 0x017B, 0x017C, 0x017A, 0x201D, 0x00A6, 0x00A9, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x0141, 0x00AB, 0x00BB, - 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0104, 0x010C, 0x0118, 0x0116, 0x2563, 0x2551, 0x2557, 0x255D, 0x012E, 0x0160, 0x2510, - 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0172, 0x016A, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x017D, - 0x0105, 0x010D, 0x0119, 0x0117, 0x012F, 0x0161, 0x0173, 0x016B, 0x017E, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, - 0x00D3, 0x00DF, 0x014C, 0x0143, 0x00F5, 0x00D5, 0x00B5, 0x0144, 0x0136, 0x0137, 0x013B, 0x013C, 0x0146, 0x0112, 0x0145, 0x2019, - 0x00AD, 0x00B1, 0x201C, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x201E, 0x00B0, 0x2219, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0 -}; -#endif -#if FF_CODE_PAGE == 850 || FF_CODE_PAGE == 0 -static const WCHAR uc850[] = { /* CP850(Latin 1) to Unicode conversion table */ - 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, - 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192, - 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, - 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510, - 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, - 0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580, - 0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE, 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4, - 0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0 -}; -#endif -#if FF_CODE_PAGE == 852 || FF_CODE_PAGE == 0 -static const WCHAR uc852[] = { /* CP852(Latin 2) to Unicode conversion table */ - 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7, 0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106, - 0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A, 0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D, - 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E, 0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB, - 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x011A, 0x015E, 0x2563, 0x2551, 0x2557, 0x255D, 0x017B, 0x017C, 0x2510, - 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0102, 0x0103, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, - 0x0111, 0x0110, 0x010E, 0x00CB, 0x010F, 0x0147, 0x00CD, 0x00CE, 0x011B, 0x2518, 0x250C, 0x2588, 0x2584, 0x0162, 0x016E, 0x2580, - 0x00D3, 0x00DF, 0x00D4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161, 0x0154, 0x00DA, 0x0155, 0x0170, 0x00FD, 0x00DD, 0x0163, 0x00B4, - 0x00AD, 0x02DD, 0x02DB, 0x02C7, 0x02D8, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x02D9, 0x0171, 0x0158, 0x0159, 0x25A0, 0x00A0 -}; -#endif -#if FF_CODE_PAGE == 855 || FF_CODE_PAGE == 0 -static const WCHAR uc855[] = { /* CP855(Cyrillic) to Unicode conversion table */ - 0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404, 0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408, - 0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C, 0x045E, 0x040E, 0x045F, 0x040F, 0x044E, 0x042E, 0x044A, 0x042A, - 0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414, 0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00AB, 0x00BB, - 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438, 0x0418, 0x2563, 0x2551, 0x2557, 0x255D, 0x0439, 0x0419, 0x2510, - 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x043A, 0x041A, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, - 0x043B, 0x041B, 0x043C, 0x041C, 0x043D, 0x041D, 0x043E, 0x041E, 0x043F, 0x2518, 0x250C, 0x2588, 0x2584, 0x041F, 0x044F, 0x2580, - 0x042F, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443, 0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044C, 0x042C, 0x2116, - 0x00AD, 0x044B, 0x042B, 0x0437, 0x0417, 0x0448, 0x0428, 0x044D, 0x042D, 0x0449, 0x0429, 0x0447, 0x0427, 0x00A7, 0x25A0, 0x00A0 -}; -#endif -#if FF_CODE_PAGE == 857 || FF_CODE_PAGE == 0 -static const WCHAR uc857[] = { /* CP857(Turkish) to Unicode conversion table */ - 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5, - 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x0130, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x015E, 0x015F, - 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x011E, 0x011F, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, - 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510, - 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, - 0x00BA, 0x00AA, 0x00CA, 0x00CB, 0x00C8, 0x0000, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580, - 0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x0000, 0x00D7, 0x00DA, 0x00DB, 0x00D9, 0x00EC, 0x00FF, 0x00AF, 0x00B4, - 0x00AD, 0x00B1, 0x0000, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0 -}; -#endif -#if FF_CODE_PAGE == 860 || FF_CODE_PAGE == 0 -static const WCHAR uc860[] = { /* CP860(Portuguese) to Unicode conversion table */ - 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E3, 0x00E0, 0x00C1, 0x00E7, 0x00EA, 0x00CA, 0x00E8, 0x00CD, 0x00D4, 0x00EC, 0x00C3, 0x00C2, - 0x00C9, 0x00C0, 0x00C8, 0x00F4, 0x00F5, 0x00F2, 0x00DA, 0x00F9, 0x00CC, 0x00D5, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x20A7, 0x00D3, - 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00D2, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, - 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510, - 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, - 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, - 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, - 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 -}; -#endif -#if FF_CODE_PAGE == 861 || FF_CODE_PAGE == 0 -static const WCHAR uc861[] = { /* CP861(Icelandic) to Unicode conversion table */ - 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00D0, 0x00F0, 0x00DE, 0x00C4, 0x00C5, - 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00FE, 0x00FB, 0x00DD, 0x00FD, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192, - 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00C1, 0x00CD, 0x00D3, 0x00DA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, - 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, - 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, - 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, - 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, - 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 -}; -#endif -#if FF_CODE_PAGE == 862 || FF_CODE_PAGE == 0 -static const WCHAR uc862[] = { /* CP862(Hebrew) to Unicode conversion table */ - 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, - 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192, - 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, - 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, - 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, - 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, - 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, - 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 -}; -#endif -#if FF_CODE_PAGE == 863 || FF_CODE_PAGE == 0 -static const WCHAR uc863[] = { /* CP863(Canadian French) to Unicode conversion table */ - 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00C2, 0x00E0, 0x00B6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x2017, 0x00C0, - 0x00C9, 0x00C8, 0x00CA, 0x00F4, 0x00CB, 0x00CF, 0x00FB, 0x00F9, 0x00A4, 0x00D4, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x00DB, 0x0192, - 0x00A6, 0x00B4, 0x00F3, 0x00FA, 0x00A8, 0x00BB, 0x00B3, 0x00AF, 0x00CE, 0x3210, 0x00AC, 0x00BD, 0x00BC, 0x00BE, 0x00AB, 0x00BB, - 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, - 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, - 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, - 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2219, - 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 -}; -#endif -#if FF_CODE_PAGE == 864 || FF_CODE_PAGE == 0 -static const WCHAR uc864[] = { /* CP864(Arabic) to Unicode conversion table */ - 0x00B0, 0x00B7, 0x2219, 0x221A, 0x2592, 0x2500, 0x2502, 0x253C, 0x2524, 0x252C, 0x251C, 0x2534, 0x2510, 0x250C, 0x2514, 0x2518, - 0x03B2, 0x221E, 0x03C6, 0x00B1, 0x00BD, 0x00BC, 0x2248, 0x00AB, 0x00BB, 0xFEF7, 0xFEF8, 0x0000, 0x0000, 0xFEFB, 0xFEFC, 0x0000, - 0x00A0, 0x00AD, 0xFE82, 0x00A3, 0x00A4, 0xFE84, 0x0000, 0x20AC, 0xFE8E, 0xFE8F, 0xFE95, 0xFE99, 0x060C, 0xFE9D, 0xFEA1, 0xFEA5, - 0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, 0x0668, 0x0669, 0xFED1, 0x061B, 0xFEB1, 0xFEB5, 0xFEB9, 0x061F, - 0x00A2, 0xFE80, 0xFE81, 0xFE83, 0xFE85, 0xFECA, 0xFE8B, 0xFE8D, 0xFE91, 0xFE93, 0xFE97, 0xFE9B, 0xFE9F, 0xFEA3, 0xFEA7, 0xFEA9, - 0xFEAB, 0xFEAD, 0xFEAF, 0xFEB3, 0xFEB7, 0xFEBB, 0xFEBF, 0xFEC1, 0xFEC5, 0xFECB, 0xFECF, 0x00A6, 0x00AC, 0x00F7, 0x00D7, 0xFEC9, - 0x0640, 0xFED3, 0xFED7, 0xFEDB, 0xFEDF, 0xFEE3, 0xFEE7, 0xFEEB, 0xFEED, 0xFEEF, 0xFEF3, 0xFEBD, 0xFECC, 0xFECE, 0xFECD, 0xFEE1, - 0xFE7D, 0x0651, 0xFEE5, 0xFEE9, 0xFEEC, 0xFEF0, 0xFEF2, 0xFED0, 0xFED5, 0xFEF5, 0xFEF6, 0xFEDD, 0xFED9, 0xFEF1, 0x25A0, 0x0000 -}; -#endif -#if FF_CODE_PAGE == 865 || FF_CODE_PAGE == 0 -static const WCHAR uc865[] = { /* CP865(Nordic) to Unicode conversion table */ - 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, - 0x00C5, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192, - 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00A4, - 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510, - 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, - 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, - 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, - 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 -}; -#endif -#if FF_CODE_PAGE == 866 || FF_CODE_PAGE == 0 -static const WCHAR uc866[] = { /* CP866(Russian) to Unicode conversion table */ - 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, - 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, - 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, - 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, - 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, - 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, - 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F, - 0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0 -}; -#endif -#if FF_CODE_PAGE == 869 || FF_CODE_PAGE == 0 -static const WCHAR uc869[] = { /* CP869(Greek 2) to Unicode conversion table */ - 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x0386, 0x00B7, 0x00B7, 0x00AC, 0x00A6, 0x2018, 0x2019, 0x0388, 0x2015, 0x0389, - 0x038A, 0x03AA, 0x038C, 0x00B7, 0x00B7, 0x038E, 0x03AB, 0x00A9, 0x038F, 0x00B2, 0x00B3, 0x03AC, 0x00A3, 0x03AD, 0x03AE, 0x03AF, - 0x03CA, 0x0390, 0x03CC, 0x03CD, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x00BD, 0x0398, 0x0399, 0x00AB, 0x00BB, - 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x039A, 0x039B, 0x039C, 0x039D, 0x2563, 0x2551, 0x2557, 0x255D, 0x039E, 0x039F, 0x2510, - 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0A30, 0x03A1, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x03A3, - 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x2518, 0x250C, 0x2588, 0x2584, 0x03B4, 0x03B5, 0x2580, - 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x0384, - 0x00AD, 0x00B1, 0x03C5, 0x03C6, 0x03C7, 0x00A7, 0x03C8, 0x0385, 0x00B0, 0x00A8, 0x03C9, 0x03CB, 0x03B0, 0x03CE, 0x25A0, 0x00A0 -}; -#endif - - - - -/*------------------------------------------------------------------------*/ -/* OEM <==> Unicode conversions for static code page configuration */ -/* SBCS fixed code page */ -/*------------------------------------------------------------------------*/ - -#if FF_CODE_PAGE != 0 && FF_CODE_PAGE < 900 -WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */ - DWORD uni, /* UTF-16 encoded character to be converted */ - WORD cp /* Code page for the conversion */ -) -{ - WCHAR c = 0; - const WCHAR *p = CVTBL(uc, FF_CODE_PAGE); - - - if (uni < 0x80) { /* ASCII? */ - c = (WCHAR)uni; - - } else { /* Non-ASCII */ - if (uni < 0x10000 && cp == FF_CODE_PAGE) { /* Is it in BMP and valid code page? */ - for (c = 0; c < 0x80 && uni != p[c]; c++) ; - c = (c + 0x80) & 0xFF; - } - } - - return c; -} - -WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */ - WCHAR oem, /* OEM code to be converted */ - WORD cp /* Code page for the conversion */ -) -{ - WCHAR c = 0; - const WCHAR *p = CVTBL(uc, FF_CODE_PAGE); - - - if (oem < 0x80) { /* ASCII? */ - c = oem; - - } else { /* Extended char */ - if (cp == FF_CODE_PAGE) { /* Is it a valid code page? */ - if (oem < 0x100) c = p[oem - 0x80]; - } - } - - return c; -} - -#endif - - - -/*------------------------------------------------------------------------*/ -/* OEM <==> Unicode conversions for static code page configuration */ -/* DBCS fixed code page */ -/*------------------------------------------------------------------------*/ - -#if FF_CODE_PAGE >= 900 -WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */ - DWORD uni, /* UTF-16 encoded character to be converted */ - WORD cp /* Code page for the conversion */ -) -{ - const WCHAR *p; - WCHAR c = 0, uc; - UINT i = 0, n, li, hi; - - - if (uni < 0x80) { /* ASCII? */ - c = (WCHAR)uni; - - } else { /* Non-ASCII */ - if (uni < 0x10000 && cp == FF_CODE_PAGE) { /* Is it in BMP and valid code page? */ - uc = (WCHAR)uni; - p = CVTBL(uni2oem, FF_CODE_PAGE); - hi = sizeof CVTBL(uni2oem, FF_CODE_PAGE) / 4 - 1; - li = 0; - for (n = 16; n; n--) { - i = li + (hi - li) / 2; - if (uc == p[i * 2]) break; - if (uc > p[i * 2]) { - li = i; - } else { - hi = i; - } - } - if (n != 0) c = p[i * 2 + 1]; - } - } - - return c; -} - - -WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */ - WCHAR oem, /* OEM code to be converted */ - WORD cp /* Code page for the conversion */ -) -{ - const WCHAR *p; - WCHAR c = 0; - UINT i = 0, n, li, hi; - - - if (oem < 0x80) { /* ASCII? */ - c = oem; - - } else { /* Extended char */ - if (cp == FF_CODE_PAGE) { /* Is it valid code page? */ - p = CVTBL(oem2uni, FF_CODE_PAGE); - hi = sizeof CVTBL(oem2uni, FF_CODE_PAGE) / 4 - 1; - li = 0; - for (n = 16; n; n--) { - i = li + (hi - li) / 2; - if (oem == p[i * 2]) break; - if (oem > p[i * 2]) { - li = i; - } else { - hi = i; - } - } - if (n != 0) c = p[i * 2 + 1]; - } - } - - return c; -} -#endif - - - -/*------------------------------------------------------------------------*/ -/* OEM <==> Unicode conversions for dynamic code page configuration */ -/*------------------------------------------------------------------------*/ - -#if FF_CODE_PAGE == 0 - -static const WORD cp_code[] = { 437, 720, 737, 771, 775, 850, 852, 855, 857, 860, 861, 862, 863, 864, 865, 866, 869, 0}; -static const WCHAR* const cp_table[] = {uc437, uc720, uc737, uc771, uc775, uc850, uc852, uc855, uc857, uc860, uc861, uc862, uc863, uc864, uc865, uc866, uc869, 0}; - - -WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */ - DWORD uni, /* UTF-16 encoded character to be converted */ - WORD cp /* Code page for the conversion */ -) -{ - const WCHAR *p; - WCHAR c = 0, uc; - UINT i, n, li, hi; - - - if (uni < 0x80) { /* ASCII? */ - c = (WCHAR)uni; - - } else { /* Non-ASCII */ - if (uni < 0x10000) { /* Is it in BMP? */ - uc = (WCHAR)uni; - p = 0; - if (cp < 900) { /* SBCS */ - for (i = 0; cp_code[i] != 0 && cp_code[i] != cp; i++) ; /* Get conversion table */ - p = cp_table[i]; - if (p) { /* Is it valid code page ? */ - for (c = 0; c < 0x80 && uc != p[c]; c++) ; /* Find OEM code in the table */ - c = (c + 0x80) & 0xFF; - } - } else { /* DBCS */ - switch (cp) { /* Get conversion table */ - case 932 : p = uni2oem932; hi = sizeof uni2oem932 / 4 - 1; break; - case 936 : p = uni2oem936; hi = sizeof uni2oem936 / 4 - 1; break; - case 949 : p = uni2oem949; hi = sizeof uni2oem949 / 4 - 1; break; - case 950 : p = uni2oem950; hi = sizeof uni2oem950 / 4 - 1; break; - } - if (p) { /* Is it valid code page? */ - li = 0; - for (n = 16; n; n--) { /* Find OEM code */ - i = li + (hi - li) / 2; - if (uc == p[i * 2]) break; - if (uc > p[i * 2]) { - li = i; - } else { - hi = i; - } - } - if (n != 0) c = p[i * 2 + 1]; - } - } - } - } - - return c; -} - - -WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */ - WCHAR oem, /* OEM code to be converted (DBC if >=0x100) */ - WORD cp /* Code page for the conversion */ -) -{ - const WCHAR *p; - WCHAR c = 0; - UINT i, n, li, hi; - - - if (oem < 0x80) { /* ASCII? */ - c = oem; - - } else { /* Extended char */ - p = 0; - if (cp < 900) { /* SBCS */ - for (i = 0; cp_code[i] != 0 && cp_code[i] != cp; i++) ; /* Get table */ - p = cp_table[i]; - if (p) { /* Is it a valid CP ? */ - if (oem < 0x100) c = p[oem - 0x80]; - } - } else { /* DBCS */ - switch (cp) { - case 932 : p = oem2uni932; hi = sizeof oem2uni932 / 4 - 1; break; - case 936 : p = oem2uni936; hi = sizeof oem2uni936 / 4 - 1; break; - case 949 : p = oem2uni949; hi = sizeof oem2uni949 / 4 - 1; break; - case 950 : p = oem2uni950; hi = sizeof oem2uni950 / 4 - 1; break; - } - if (p) { - li = 0; - for (n = 16; n; n--) { - i = li + (hi - li) / 2; - if (oem == p[i * 2]) break; - if (oem > p[i * 2]) { - li = i; - } else { - hi = i; - } - } - if (n != 0) c = p[i * 2 + 1]; - } - } - } - - return c; -} -#endif - - - -/*------------------------------------------------------------------------*/ -/* Unicode up-case conversion */ -/*------------------------------------------------------------------------*/ - -DWORD ff_wtoupper ( /* Returns up-converted code point */ - DWORD uni /* Unicode code point to be up-converted */ -) -{ - const WORD *p; - WORD uc, bc, nc, cmd; - static const WORD cvt1[] = { /* Compressed up conversion table for U+0000 - U+0FFF */ - /* Basic Latin */ - 0x0061,0x031A, - /* Latin-1 Supplement */ - 0x00E0,0x0317, - 0x00F8,0x0307, - 0x00FF,0x0001,0x0178, - /* Latin Extended-A */ - 0x0100,0x0130, - 0x0132,0x0106, - 0x0139,0x0110, - 0x014A,0x012E, - 0x0179,0x0106, - /* Latin Extended-B */ - 0x0180,0x004D,0x0243,0x0181,0x0182,0x0182,0x0184,0x0184,0x0186,0x0187,0x0187,0x0189,0x018A,0x018B,0x018B,0x018D,0x018E,0x018F,0x0190,0x0191,0x0191,0x0193,0x0194,0x01F6,0x0196,0x0197,0x0198,0x0198,0x023D,0x019B,0x019C,0x019D,0x0220,0x019F,0x01A0,0x01A0,0x01A2,0x01A2,0x01A4,0x01A4,0x01A6,0x01A7,0x01A7,0x01A9,0x01AA,0x01AB,0x01AC,0x01AC,0x01AE,0x01AF,0x01AF,0x01B1,0x01B2,0x01B3,0x01B3,0x01B5,0x01B5,0x01B7,0x01B8,0x01B8,0x01BA,0x01BB,0x01BC,0x01BC,0x01BE,0x01F7,0x01C0,0x01C1,0x01C2,0x01C3,0x01C4,0x01C5,0x01C4,0x01C7,0x01C8,0x01C7,0x01CA,0x01CB,0x01CA, - 0x01CD,0x0110, - 0x01DD,0x0001,0x018E, - 0x01DE,0x0112, - 0x01F3,0x0003,0x01F1,0x01F4,0x01F4, - 0x01F8,0x0128, - 0x0222,0x0112, - 0x023A,0x0009,0x2C65,0x023B,0x023B,0x023D,0x2C66,0x023F,0x0240,0x0241,0x0241, - 0x0246,0x010A, - /* IPA Extensions */ - 0x0253,0x0040,0x0181,0x0186,0x0255,0x0189,0x018A,0x0258,0x018F,0x025A,0x0190,0x025C,0x025D,0x025E,0x025F,0x0193,0x0261,0x0262,0x0194,0x0264,0x0265,0x0266,0x0267,0x0197,0x0196,0x026A,0x2C62,0x026C,0x026D,0x026E,0x019C,0x0270,0x0271,0x019D,0x0273,0x0274,0x019F,0x0276,0x0277,0x0278,0x0279,0x027A,0x027B,0x027C,0x2C64,0x027E,0x027F,0x01A6,0x0281,0x0282,0x01A9,0x0284,0x0285,0x0286,0x0287,0x01AE,0x0244,0x01B1,0x01B2,0x0245,0x028D,0x028E,0x028F,0x0290,0x0291,0x01B7, - /* Greek, Coptic */ - 0x037B,0x0003,0x03FD,0x03FE,0x03FF, - 0x03AC,0x0004,0x0386,0x0388,0x0389,0x038A, - 0x03B1,0x0311, - 0x03C2,0x0002,0x03A3,0x03A3, - 0x03C4,0x0308, - 0x03CC,0x0003,0x038C,0x038E,0x038F, - 0x03D8,0x0118, - 0x03F2,0x000A,0x03F9,0x03F3,0x03F4,0x03F5,0x03F6,0x03F7,0x03F7,0x03F9,0x03FA,0x03FA, - /* Cyrillic */ - 0x0430,0x0320, - 0x0450,0x0710, - 0x0460,0x0122, - 0x048A,0x0136, - 0x04C1,0x010E, - 0x04CF,0x0001,0x04C0, - 0x04D0,0x0144, - /* Armenian */ - 0x0561,0x0426, - - 0x0000 /* EOT */ - }; - static const WORD cvt2[] = { /* Compressed up conversion table for U+1000 - U+FFFF */ - /* Phonetic Extensions */ - 0x1D7D,0x0001,0x2C63, - /* Latin Extended Additional */ - 0x1E00,0x0196, - 0x1EA0,0x015A, - /* Greek Extended */ - 0x1F00,0x0608, - 0x1F10,0x0606, - 0x1F20,0x0608, - 0x1F30,0x0608, - 0x1F40,0x0606, - 0x1F51,0x0007,0x1F59,0x1F52,0x1F5B,0x1F54,0x1F5D,0x1F56,0x1F5F, - 0x1F60,0x0608, - 0x1F70,0x000E,0x1FBA,0x1FBB,0x1FC8,0x1FC9,0x1FCA,0x1FCB,0x1FDA,0x1FDB,0x1FF8,0x1FF9,0x1FEA,0x1FEB,0x1FFA,0x1FFB, - 0x1F80,0x0608, - 0x1F90,0x0608, - 0x1FA0,0x0608, - 0x1FB0,0x0004,0x1FB8,0x1FB9,0x1FB2,0x1FBC, - 0x1FCC,0x0001,0x1FC3, - 0x1FD0,0x0602, - 0x1FE0,0x0602, - 0x1FE5,0x0001,0x1FEC, - 0x1FF3,0x0001,0x1FFC, - /* Letterlike Symbols */ - 0x214E,0x0001,0x2132, - /* Number forms */ - 0x2170,0x0210, - 0x2184,0x0001,0x2183, - /* Enclosed Alphanumerics */ - 0x24D0,0x051A, - 0x2C30,0x042F, - /* Latin Extended-C */ - 0x2C60,0x0102, - 0x2C67,0x0106, 0x2C75,0x0102, - /* Coptic */ - 0x2C80,0x0164, - /* Georgian Supplement */ - 0x2D00,0x0826, - /* Full-width */ - 0xFF41,0x031A, - - 0x0000 /* EOT */ - }; - - - if (uni < 0x10000) { /* Is it in BMP? */ - uc = (WORD)uni; - p = uc < 0x1000 ? cvt1 : cvt2; - for (;;) { - bc = *p++; /* Get the block base */ - if (bc == 0 || uc < bc) break; /* Not matched? */ - nc = *p++; cmd = nc >> 8; nc &= 0xFF; /* Get processing command and block size */ - if (uc < bc + nc) { /* In the block? */ - switch (cmd) { - case 0: uc = p[uc - bc]; break; /* Table conversion */ - case 1: uc -= (uc - bc) & 1; break; /* Case pairs */ - case 2: uc -= 16; break; /* Shift -16 */ - case 3: uc -= 32; break; /* Shift -32 */ - case 4: uc -= 48; break; /* Shift -48 */ - case 5: uc -= 26; break; /* Shift -26 */ - case 6: uc += 8; break; /* Shift +8 */ - case 7: uc -= 80; break; /* Shift -80 */ - case 8: uc -= 0x1C60; break; /* Shift -0x1C60 */ - } - break; - } - if (cmd == 0) p += nc; /* Skip table if needed */ - } - uni = uc; - } - - return uni; -} - - -#endif /* #if FF_USE_LFN */ diff --git a/third-party/fatfs-0.1.3/integer.h b/third-party/fatfs-0.1.3/integer.h deleted file mode 100644 index 98250da7..00000000 --- a/third-party/fatfs-0.1.3/integer.h +++ /dev/null @@ -1,38 +0,0 @@ -/*-------------------------------------------*/ -/* Integer type definitions for FatFs module */ -/*-------------------------------------------*/ - -#ifndef FF_INTEGER -#define FF_INTEGER - -#ifdef _WIN32 /* FatFs development platform */ - -#define _TCHAR_DEFINED - -#include -typedef unsigned __int64 QWORD; - -#else /* Embedded platform */ - -/* These types MUST be 16-bit or 32-bit */ -typedef int INT; -typedef unsigned int UINT; - -/* This type MUST be 8-bit */ -typedef unsigned char BYTE; - -/* These types MUST be 16-bit */ -typedef short SHORT; -typedef unsigned short WORD; -typedef unsigned short WCHAR; - -/* These types MUST be 32-bit */ -typedef long LONG; -typedef unsigned long DWORD; - -/* This type MUST be 64-bit (Remove this for ANSI C (C89) compatibility) */ -typedef unsigned long long QWORD; - -#endif - -#endif diff --git a/third-party/fatfs-0.1.3/port/fsata_controller/diskio.h b/third-party/fatfs-0.1.3/port/fsata_controller/diskio.h deleted file mode 100644 index 1fa4400e..00000000 --- a/third-party/fatfs-0.1.3/port/fsata_controller/diskio.h +++ /dev/null @@ -1,80 +0,0 @@ -/*-----------------------------------------------------------------------/ -/ Low level disk interface modlue include file (C)ChaN, 2014 / -/-----------------------------------------------------------------------*/ - -#ifndef _DISKIO_DEFINED -#define _DISKIO_DEFINED - -#ifdef __cplusplus -extern "C" { -#endif - -#include "integer.h" - - -/* Status of Disk Functions */ -typedef BYTE DSTATUS; - -/* Results of Disk Functions */ -typedef enum { - RES_OK = 0, /* 0: Successful */ - RES_ERROR, /* 1: R/W Error */ - RES_WRPRT, /* 2: Write Protected */ - RES_NOTRDY, /* 3: Not Ready */ - RES_PARERR /* 4: Invalid Parameter */ -} DRESULT; - - -/*---------------------------------------*/ -/* Prototypes for disk control functions */ - - -DSTATUS disk_initialize (BYTE pdrv); -DSTATUS disk_status (BYTE pdrv); -DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count); -DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count); -DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff); - - -/* Disk Status Bits (DSTATUS) */ - -#define STA_NOINIT 0x01 /* Drive not initialized */ -#define STA_NODISK 0x02 /* No medium in the drive */ -#define STA_PROTECT 0x04 /* Write protected */ - - -/* Command code for disk_ioctrl fucntion */ - -/* Generic command (Used by FatFs) */ -#define CTRL_SYNC 0 /* Complete pending write process (needed at FF_FS_READONLY == 0) */ -#define GET_SECTOR_COUNT 1 /* Get media size (needed at FF_USE_MKFS == 1) */ -#define GET_SECTOR_SIZE 2 /* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */ -#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */ -#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */ - -/* Generic command (Not used by FatFs) */ -#define CTRL_POWER 5 /* Get/Set power status */ -#define CTRL_LOCK 6 /* Lock/Unlock media removal */ -#define CTRL_EJECT 7 /* Eject media */ -#define CTRL_FORMAT 8 /* Create physical format on the media */ - -/* MMC/SDC specific ioctl command */ -#define MMC_GET_TYPE 10 /* Get card type */ -#define MMC_GET_CSD 11 /* Get CSD */ -#define MMC_GET_CID 12 /* Get CID */ -#define MMC_GET_OCR 13 /* Get OCR */ -#define MMC_GET_SDSTAT 14 /* Get SD status */ -#define ISDIO_READ 55 /* Read data form SD iSDIO register */ -#define ISDIO_WRITE 56 /* Write data to SD iSDIO register */ -#define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */ - -/* ATA/CF specific ioctl command */ -#define ATA_GET_REV 20 /* Get F/W revision */ -#define ATA_GET_MODEL 21 /* Get model name */ -#define ATA_GET_SN 22 /* Get serial number */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/third-party/fatfs-0.1.3/port/fsata_pcie/diskio.h b/third-party/fatfs-0.1.3/port/fsata_pcie/diskio.h deleted file mode 100644 index 1fa4400e..00000000 --- a/third-party/fatfs-0.1.3/port/fsata_pcie/diskio.h +++ /dev/null @@ -1,80 +0,0 @@ -/*-----------------------------------------------------------------------/ -/ Low level disk interface modlue include file (C)ChaN, 2014 / -/-----------------------------------------------------------------------*/ - -#ifndef _DISKIO_DEFINED -#define _DISKIO_DEFINED - -#ifdef __cplusplus -extern "C" { -#endif - -#include "integer.h" - - -/* Status of Disk Functions */ -typedef BYTE DSTATUS; - -/* Results of Disk Functions */ -typedef enum { - RES_OK = 0, /* 0: Successful */ - RES_ERROR, /* 1: R/W Error */ - RES_WRPRT, /* 2: Write Protected */ - RES_NOTRDY, /* 3: Not Ready */ - RES_PARERR /* 4: Invalid Parameter */ -} DRESULT; - - -/*---------------------------------------*/ -/* Prototypes for disk control functions */ - - -DSTATUS disk_initialize (BYTE pdrv); -DSTATUS disk_status (BYTE pdrv); -DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count); -DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count); -DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff); - - -/* Disk Status Bits (DSTATUS) */ - -#define STA_NOINIT 0x01 /* Drive not initialized */ -#define STA_NODISK 0x02 /* No medium in the drive */ -#define STA_PROTECT 0x04 /* Write protected */ - - -/* Command code for disk_ioctrl fucntion */ - -/* Generic command (Used by FatFs) */ -#define CTRL_SYNC 0 /* Complete pending write process (needed at FF_FS_READONLY == 0) */ -#define GET_SECTOR_COUNT 1 /* Get media size (needed at FF_USE_MKFS == 1) */ -#define GET_SECTOR_SIZE 2 /* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */ -#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */ -#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */ - -/* Generic command (Not used by FatFs) */ -#define CTRL_POWER 5 /* Get/Set power status */ -#define CTRL_LOCK 6 /* Lock/Unlock media removal */ -#define CTRL_EJECT 7 /* Eject media */ -#define CTRL_FORMAT 8 /* Create physical format on the media */ - -/* MMC/SDC specific ioctl command */ -#define MMC_GET_TYPE 10 /* Get card type */ -#define MMC_GET_CSD 11 /* Get CSD */ -#define MMC_GET_CID 12 /* Get CID */ -#define MMC_GET_OCR 13 /* Get OCR */ -#define MMC_GET_SDSTAT 14 /* Get SD status */ -#define ISDIO_READ 55 /* Read data form SD iSDIO register */ -#define ISDIO_WRITE 56 /* Write data to SD iSDIO register */ -#define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */ - -/* ATA/CF specific ioctl command */ -#define ATA_GET_REV 20 /* Get F/W revision */ -#define ATA_GET_MODEL 21 /* Get model name */ -#define ATA_GET_SN 22 /* Get serial number */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/third-party/fatfs-0.1.4/Kconfig b/third-party/fatfs-0.1.4/Kconfig new file mode 100644 index 00000000..31cd44f7 --- /dev/null +++ b/third-party/fatfs-0.1.4/Kconfig @@ -0,0 +1 @@ +source "$STANDALONE_DIR/third-party/fatfs-0.1.4/Kconfig" \ No newline at end of file diff --git a/third-party/fatfs-0.1.4/fatfs.mk b/third-party/fatfs-0.1.4/fatfs.mk new file mode 100644 index 00000000..ef810a6e --- /dev/null +++ b/third-party/fatfs-0.1.4/fatfs.mk @@ -0,0 +1,24 @@ +FATFS_OS_DIR := $(FREERTOS_SDK_ROOT)/third-party/fatfs-0.1.4 +FATFS_BM_DIR := $(STANDALONE_DIR)/third-party/fatfs-0.1.4 + +include $(FATFS_BM_DIR)/fatfs.mk + +ifdef CONFIG_USE_FREERTOS + INC_DIR += $(FATFS_OS_DIR)/osal + SRC_DIR += $(FATFS_OS_DIR)/osal + + ifdef CONFIG_FATFS_FSATA + INC_DIR += $(FATFS_OS_DIR)/port/fsata_controller + SRC_DIR += $(FATFS_OS_DIR)/port/fsata_controller + endif + + ifdef CONFIG_FATFS_FSATA_PCIE + INC_DIR += $(FATFS_OS_DIR)/port/fsata_pcie + SRC_DIR += $(FATFS_OS_DIR)/port/fsata_pcie + endif + + ifdef CONFIG_FATFS_USB + INC_DIR += $(FATFS_OS_DIR)/port/fusb + SRC_DIR += $(FATFS_OS_DIR)/port/fusb + endif +endif #CONFIG_USE_FREERTOS \ No newline at end of file diff --git a/third-party/fatfs-0.1.3/ffsystem.c b/third-party/fatfs-0.1.4/osal/ffsystem.c similarity index 55% rename from third-party/fatfs-0.1.3/ffsystem.c rename to third-party/fatfs-0.1.4/osal/ffsystem.c index 2e70709f..06098af3 100644 --- a/third-party/fatfs-0.1.3/ffsystem.c +++ b/third-party/fatfs-0.1.4/osal/ffsystem.c @@ -1,37 +1,88 @@ /*------------------------------------------------------------------------*/ /* Sample Code of OS Dependent Functions for FatFs */ -/* (C)ChaN, 2017 */ +/* (C)ChaN, 2018 */ /*------------------------------------------------------------------------*/ +#include #include #include "ff.h" +#include "fassert.h" +#include "sdkconfig.h" +#ifdef CONFIG_FATFS_ALLOC_PREFER_MEMP +#include "fmemory_pool.h" +#endif + +#ifdef CONFIG_FATFS_ALLOC_PREFER_MEMP +#define FATFS_MEMP_TOTAL_SIZE (CONFIG_FATFS_MEMP_SIZE * SZ_1M) +static FMemp ff_memp; +static u8 memp_buf[FATFS_MEMP_TOTAL_SIZE] __attribute((aligned(64))); + +void ff_mempinit(void) +{ + /* create memory pool to support dynamic memory allocation */ + FASSERT (FT_SUCCESS == FMempInit(&ff_memp, &memp_buf[0], &memp_buf[0] + FATFS_MEMP_TOTAL_SIZE)); +} +#endif -#if FF_USE_LFN == 3 /* Dynamic memory allocation */ /*------------------------------------------------------------------------*/ /* Allocate a memory block */ /*------------------------------------------------------------------------*/ -void* ff_memalloc ( /* Returns pointer to the allocated memory block (null on not enough core) */ +void* ff_memalloc ( /* Returns pointer to the allocated memory block (null if not enough core) */ UINT msize /* Number of bytes to allocate */ ) { - return pvPortMalloc(msize); /* Allocate a new memory block with Freertos API */ + void *result = NULL; + +#ifdef CONFIG_FATFS_ALLOC_PREFER_MEMP + result = FMempMalloc(&ff_memp, msize); +#else + result = malloc(msize); /* Allocate a new memory block with POSIX API */ +#endif + if (NULL != result){ + memset(result, 0, msize); + } + + return result; } +void* ff_memalign( /* Returns pointer to the allocated memory block (null if not enough core) */ + UINT msize, /* Number of bytes to allocate */ + UINT align /* Alignment */ +) +{ + void *result = NULL; + +#ifdef CONFIG_FATFS_ALLOC_PREFER_MEMP + result = FMempMallocAlign(&ff_memp, msize, align); +#else + #error "allocate aligned memory is not supported !!!" + result = malloc(msize); /* Allocate a new memory block with POSIX API */ +#endif + + if (NULL != result){ + memset(result, 0, msize); + } + + return result; +} /*------------------------------------------------------------------------*/ /* Free a memory block */ /*------------------------------------------------------------------------*/ void ff_memfree ( - void* mblock /* Pointer to the memory block to free (nothing to do for null) */ + void* mblock /* Pointer to the memory block to free (nothing to do if null) */ ) { - vPortFree(mblock); /* Free the memory block with Freertos API */ +#ifdef CONFIG_FATFS_ALLOC_PREFER_MEMP + FMempFree(&ff_memp, mblock); +#else + free(mblock); /* Free the memory block with POSIX API */ +#endif } -#endif #if FF_FS_REENTRANT /* Mutal exclusion */ @@ -44,14 +95,12 @@ void ff_memfree ( / When a 0 is returned, the f_mount() function fails with FR_INT_ERR. */ -//const osMutexDef_t Mutex[FF_VOLUMES]; /* CMSIS-RTOS */ - - int ff_cre_syncobj ( /* 1:Function succeeded, 0:Could not create the sync object */ BYTE vol, /* Corresponding volume (logical drive number) */ FF_SYNC_t* sobj /* Pointer to return the created sync object */ ) { + /* FreeRTOS */ *sobj = xSemaphoreCreateMutex(); return (int)(*sobj != NULL); } @@ -69,7 +118,8 @@ int ff_del_syncobj ( /* 1:Function succeeded, 0:Could not delete due to an error FF_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */ ) { - vSemaphoreDelete(sobj); + /* FreeRTOS */ + vSemaphoreDelete(sobj); return 1; } @@ -85,6 +135,7 @@ int ff_req_grant ( /* 1:Got a grant to access the volume, 0:Could not get a gran FF_SYNC_t sobj /* Sync object to wait */ ) { + /* FreeRTOS */ return (int)(xSemaphoreTake(sobj, FF_FS_TIMEOUT) == pdTRUE); } @@ -99,8 +150,50 @@ void ff_rel_grant ( FF_SYNC_t sobj /* Sync object to be signaled */ ) { + /* FreeRTOS */ xSemaphoreGive(sobj); } #endif +DWORD get_fattime(void) /* TODO: impl file time with RTC */ +{ + return ((DWORD)(2022 - 1980) << 25) /* bit31:25, Year origin from the 1980 (0..127, e.g. 37 for 2017) */ + | ((DWORD)(11) << 21) /* bit24:21, Month (1..12) */ + | ((DWORD)2 << 16) /* bit20:16, Day of the month (1..31) */ + | (WORD)(9 << 11) /* bit15:11, Hour (0..23) */ + | (WORD)(3 << 5) /* bit10:5, Minute (0..59) */ + | (WORD)(15 >> 1); /* bit4:0, Second / 2 (0..29, e.g. 25 for 50) */ +} + + +void ff_systimer_start(void) +{ + /* no need to start systimer */ +} + +QWORD ff_systimer_get_tick(void) +{ + return (QWORD)xTaskGetTickCount(); +} + +void ff_systimer_tick_to_time(QWORD ticks, DWORD *sec, DWORD *msec) +{ + + if (sec) + { + *sec = (DWORD)(ticks / (u32)configTICK_RATE_HZ); + } + + if (msec) + { + *msec = (DWORD)(ticks % (DWORD)configTICK_RATE_HZ / + (((DWORD)configTICK_RATE_HZ * 1 + 999) / 1000)); + } + +} + +void ff_systimer_stop(void) +{ + /* no need to stop systimer */ +} \ No newline at end of file diff --git a/third-party/fatfs-0.1.3/port/fsata_controller/diskio.c b/third-party/fatfs-0.1.4/port/fsata_controller/diskio_sata_controller.c similarity index 38% rename from third-party/fatfs-0.1.3/port/fsata_controller/diskio.c rename to third-party/fatfs-0.1.4/port/fsata_controller/diskio_sata_controller.c index d0fb4910..72448b13 100644 --- a/third-party/fatfs-0.1.3/port/fsata_controller/diskio.c +++ b/third-party/fatfs-0.1.4/port/fsata_controller/diskio_sata_controller.c @@ -12,7 +12,7 @@ #include "fdebug.h" #include "finterrupt.h" #include "ff.h" -#include "diskio.h" /* FatFs lower layer API */ +#include "diskio.h" /* FatFs lower layer API */ #include "fsata.h" #include "fsata_hw.h" @@ -27,36 +27,52 @@ static u8 mem[50000] __attribute__((aligned(1024))) = {0}; #define ADDR_ALIGNMENT 1024 -static FSataCtrl sata_device[FSATA_INSTANCE_NUM];//最多支持16个ahci控制器,可以自行定义个数 +static FSataCtrl sata_device[FSATA_NUM];//最多支持16个ahci控制器,可以自行定义个数 static boolean sata_ok = FALSE; -static u32 host_num = 0; /* sata host */ +static u32 host_num = 0; /* sata host */ static u32 port_num = 0; /* sata link port */ /*-----------------------------------------------------------------------*/ /* Get Drive Status */ /*-----------------------------------------------------------------------*/ +typedef struct +{ + DWORD id; + DWORD sector_sz; + DWORD sector_cnt; + FSataCtrl sata; + boolean init_ok; + BYTE pdrv; +} ff_sata_disk; + +static ff_sata_disk sata_disk = +{ + .pdrv = FF_DRV_NOT_USED, + .init_ok = FALSE, +}; -DSTATUS -disk_status( - BYTE pdrv /* Physical drive nmuber to identify the drive */ +DSTATUS sata_disk_status( + BYTE pdrv /* Physical drive nmuber to identify the drive */ ) { - DSTATUS status = STA_NOINIT; + DSTATUS status = STA_NOINIT; - if (FT_COMPONENT_IS_READY == sata_device[host_num].is_ready) - status &= ~STA_NOINIT; /* 假设Sata处于插入状态 */ + if (FT_COMPONENT_IS_READY == sata_device[host_num].is_ready) + { + status &= ~STA_NOINIT; /* 假设Sata处于插入状态 */ + } - return status; + return status; } static int FSataInit(void) -{ +{ u32 instance_id = 0; - u32 port = 0; - u32 port_mem_count = 0; - u8 link_success = 0; + u32 port = 0; + u32 port_mem_count = 0; + u8 link_success = 0; const FSataConfig *config_p = NULL; FSataCtrl *instance_p; @@ -65,100 +81,104 @@ static int FSataInit(void) if (sata_ok == TRUE) { - FSATA_WARN("sata already init\r\n"); + FSATA_WARN("Sata already init.\r\n"); return 0; } - for (instance_id = 0; instance_id < FSATA_INSTANCE_NUM; instance_id++) - { + for (instance_id = 0; instance_id < FSATA_NUM; instance_id++) + { host_valid = FALSE; - config_p = FSataLookupConfig(instance_id, FSATA_TYPE_CONTROLLER); - if(config_p != NULL) + config_p = FSataLookupConfig(instance_id, FSATA_TYPE_CONTROLLER); + if (config_p != NULL) { ret = FSataCfgInitialize(&sata_device[instance_id], config_p); if (FSATA_SUCCESS != ret) { - FSATA_ERROR("init sata failed, ret: 0x%x", ret); + FSATA_ERROR("Init sata failed, ret: 0x%x.", ret); continue; } - FSATA_DEBUG("plat ahci host[%d] base_addr = 0x%x", instance_id, sata_device[instance_id].config.base_addr); - FSATA_DEBUG("plat ahci host[%d] irq_num = %d", instance_id, sata_device[instance_id].config.irq_num); - } + FSATA_DEBUG("Plat ahci host[%d] base_addr = 0x%x.", instance_id, sata_device[instance_id].config.base_addr); + FSATA_DEBUG("Plat ahci host[%d] irq_num = %d.", instance_id, sata_device[instance_id].config.irq_num); + } else { - continue; - } + continue; + } - instance_p = &sata_device[instance_id]; + instance_p = &sata_device[instance_id]; - /* init ahci controller and port */ - ret = FSataAhciInit(instance_p); - if (FSATA_SUCCESS != ret) - { - FSataCfgDeInitialize(instance_p); - FSATA_ERROR("FSataAhciInit sata failed, ret: 0x%x", ret); - continue; - } + /* init ahci controller and port */ + ret = FSataAhciInit(instance_p); + if (FSATA_SUCCESS != ret) + { + FSataCfgDeInitialize(instance_p); + FSATA_ERROR("FSataAhciInit sata failed, ret: 0x%x.", ret); + continue; + } - FSATA_DEBUG("instance_p->n_ports = %d\n", instance_p->n_ports); + FSATA_DEBUG("instance_p->n_ports = %d.\n", instance_p->n_ports); for (port = 0; port < instance_p->n_ports; port++) - { - u32 port_map = instance_p->port_map; - if (!(port_map & BIT(port))) - continue; + { + u32 port_map = instance_p->port_map; + if (!(port_map & BIT(port))) + { + continue; + } /* command list address must be 1K-byte aligned */ ret = FSataAhciPortStart(instance_p, port, (uintptr)mem + PALIGN_UP(FSATA_AHCI_PORT_PRIV_DMA_SZ, ADDR_ALIGNMENT) * port_mem_count); port_mem_count++; - if (FSATA_SUCCESS != ret) - { - FSATA_ERROR("FSataAhciPortStart %d-%d failed, ret: 0x%x", instance_id, port, ret); - continue; - } - - ret = FSataAhciReadInfo(instance_p, port); - if (FSATA_SUCCESS != ret) - { - FSataCfgDeInitialize(instance_p); - FSATA_ERROR("FSataAhciReadInfo %d-%d failed, ret: 0x%x", instance_id, port, ret); - continue; - } - if(FSATA_SUCCESS == ret) + if (FSATA_SUCCESS != ret) + { + FSATA_ERROR("FSataAhciPortStart %d-%d failed, ret: 0x%x.", instance_id, port, ret); + continue; + } + + ret = FSataAhciReadInfo(instance_p, port); + if (FSATA_SUCCESS != ret) + { + FSataCfgDeInitialize(instance_p); + FSATA_ERROR("FSataAhciReadInfo %d-%d failed, ret: 0x%x.", instance_id, port, ret); + continue; + } + if (FSATA_SUCCESS == ret) { host_valid = TRUE; } - } - - } - + } + + } + sata_ok = TRUE; - /* get host number and port number which link success */ - for(host_num = 0; host_num < FSATA_INSTANCE_NUM; host_num++) + /* get host number and port number which link success */ + for (host_num = 0; host_num < FSATA_NUM; host_num++) { for (port_num = 0; port_num < sata_device[host_num].n_ports; port_num++) { if (!(sata_device[host_num].link_port_map & BIT(port_num))) { - printf("host_num %d port_num %d is not link\n", host_num, port_num); + FSATA_ERROR("host_num %d port_num %d is not link.\n", host_num, port_num); continue; } else { - printf("host_num %d port_num %d is link\n", host_num, port_num); + FSATA_INFO("host_num %d port_num %d is link.\n", host_num, port_num); link_success = 1; break; } } - if(link_success == 1) + if (link_success == 1) + { break; + } } - if(link_success != 1) + if (link_success != 1) { - FSATA_ERROR("Sata host port link failed\n"); + FSATA_ERROR("Sata host port link failed.\n"); return -1; } @@ -170,120 +190,138 @@ static int FSataInit(void) /* Inidialize a Drive */ /*-----------------------------------------------------------------------*/ -DSTATUS disk_initialize ( - BYTE pdrv /* Physical drive nmuber to identify the drive */ +DSTATUS sata_disk_initialize( + BYTE pdrv /* Physical drive nmuber to identify the drive */ ) { - DSTATUS status = STA_NOINIT; + DSTATUS status = STA_NOINIT; if (FSATA_SUCCESS == FSataInit()) - { - status &= ~STA_NOINIT; - FSATA_INFO("init sata driver ok"); - } - else - { - FSATA_ERROR("init sata driver failed"); - } - - return status; -} - + { + status &= ~STA_NOINIT; + FSATA_INFO("Init sata driver successfully."); + } + else + { + FSATA_ERROR("Init sata driver failed."); + } + return status; +} /*-----------------------------------------------------------------------*/ /* Read Sector(s) */ /*-----------------------------------------------------------------------*/ -DRESULT disk_read ( - BYTE pdrv, /* Physical drive nmuber to identify the drive */ - BYTE *buff, /* Data buffer to store read data */ - DWORD sector, /* Start sector in LBA */ - UINT count /* Number of sectors to read */ +DRESULT sata_disk_read( + BYTE pdrv, /* Physical drive nmuber to identify the drive */ + BYTE *buff, /* Data buffer to store read data */ + DWORD sector, /* Start sector in LBA */ + UINT count /* Number of sectors to read */ ) { - DRESULT status = RES_OK; - BYTE *io_buf = buff; - UINT err = FSATA_SUCCESS; + DRESULT status = RES_OK; + BYTE *io_buf = buff; + UINT err = FSATA_SUCCESS; - err = FSataReadWrite(&sata_device[host_num], port_num, sector, count, io_buf, FALSE, FALSE); + err = FSataReadWrite(&sata_device[host_num], port_num, sector, count, io_buf, FALSE, FALSE); - if (FSATA_SUCCESS != err) - { - FSATA_ERROR("read sata controller sector [%d-%d] failed: 0x%x", sector, sector + count, err); - status = RES_ERROR; - } + if (FSATA_SUCCESS != err) + { + FSATA_ERROR("Read sata controller sector [%d-%d] failed: 0x%x.", sector, sector + count, err); + status = RES_ERROR; + } - return status; + return status; } /*-----------------------------------------------------------------------*/ /* Write Sector(s) */ /*-----------------------------------------------------------------------*/ -DRESULT disk_write ( - BYTE pdrv, /* Physical drive nmuber to identify the drive */ - const BYTE *buff, /* Data to be written */ - DWORD sector, /* Start sector in LBA */ - UINT count /* Number of sectors to write */ +DRESULT sata_disk_write( + BYTE pdrv, /* Physical drive nmuber to identify the drive */ + const BYTE *buff, /* Data to be written */ + DWORD sector, /* Start sector in LBA */ + UINT count /* Number of sectors to write */ ) { - DRESULT status = RES_OK; - const BYTE *io_buf = buff; - UINT err = FSATA_SUCCESS; - - err = FSataReadWrite(&sata_device[host_num], port_num, sector, count, (u8 *)io_buf, FALSE, TRUE); - - if (FSATA_SUCCESS != err) - { - FSATA_ERROR("write sata controller sector [%d-%d] failed: 0x%x", sector, sector + count, err); - status = RES_ERROR; - } - - return status; + DRESULT status = RES_OK; + const BYTE *io_buf = buff; + UINT err = FSATA_SUCCESS; + + err = FSataReadWrite(&sata_device[host_num], port_num, sector, count, (u8 *)io_buf, FALSE, TRUE); + + if (FSATA_SUCCESS != err) + { + FSATA_ERROR("Write sata controller sector [%d-%d] failed: 0x%x.", sector, sector + count, err); + status = RES_ERROR; + } + + return status; } /*-----------------------------------------------------------------------*/ /* Miscellaneous Functions */ /*-----------------------------------------------------------------------*/ -DRESULT disk_ioctl ( - BYTE pdrv, /* Physical drive nmuber (0..) */ - BYTE cmd, /* Control code */ - void *buff /* Buffer to send/receive control data */ +DRESULT sata_disk_ioctl( + BYTE pdrv, /* Physical drive nmuber (0..) */ + BYTE cmd, /* Control code */ + void *buff /* Buffer to send/receive control data */ ) { - DRESULT res = RES_ERROR; - - switch (cmd) - { - /* 确保磁盘驱动器已经完成了写处理,当磁盘I/O有一个写回缓存, - 立即刷新原扇区,只读配置下不适用此命令 */ - case CTRL_SYNC: - res = RES_OK; - break; - /* 所有可用的扇区数目(逻辑寻址即LBA寻址方式) */ - case GET_SECTOR_COUNT: - *((DWORD *)buff) = sata_device[host_num].port[port_num].dev_info.lba512; - res = RES_OK; - break; - /* 返回磁盘扇区大小, 只用于f_mkfs() */ - case GET_SECTOR_SIZE: - res = RES_PARERR; - break; - /* 每个扇区有多少个字节 */ - case GET_BLOCK_SIZE: - *((DWORD *)buff) = sata_device[host_num].port[port_num].dev_info.blksz; - res = RES_OK; - break; - case CTRL_TRIM: - res = RES_PARERR; - break; - } - - FSATA_INFO("cmd %d, buff: %p", cmd, *((DWORD*) buff)); - return res; + DRESULT res = RES_ERROR; + + switch (cmd) + { + /* 确保磁盘驱动器已经完成了写处理,当磁盘I/O有一个写回缓存, + 立即刷新原扇区,只读配置下不适用此命令 */ + case CTRL_SYNC: + res = RES_OK; + break; + /* 所有可用的扇区数目(逻辑寻址即LBA寻址方式) */ + case GET_SECTOR_COUNT: + *((DWORD *)buff) = sata_device[host_num].port[port_num].dev_info.lba512; + res = RES_OK; + break; + /* 返回磁盘扇区大小, 只用于f_mkfs() */ + case GET_SECTOR_SIZE: + res = RES_PARERR; + break; + /* 每个扇区有多少个字节 */ + case GET_BLOCK_SIZE: + *((DWORD *)buff) = sata_device[host_num].port[port_num].dev_info.blksz; + res = RES_OK; + break; + case CTRL_TRIM: + res = RES_PARERR; + break; + } + + FSATA_INFO("cmd %d, buff: %p", cmd, *((DWORD *) buff)); + return res; } +static const ff_diskio_driver_t sata_disk_drv = +{ + .init = &sata_disk_initialize, + .status = &sata_disk_status, + .read = &sata_disk_read, + .write = &sata_disk_write, + .ioctl = &sata_disk_ioctl +}; + +void ff_diskio_register_sata(BYTE pdrv) +{ + ff_sata_disk *disk = &sata_disk; + + disk->id = FSATA0_ID; + disk->init_ok = FALSE; + disk->pdrv = pdrv; /* assign volume for sata disk */ + ff_diskio_register(pdrv, &sata_disk_drv); + + FSATA_INFO("Create sata disk as driver-%d.", disk->pdrv); +} diff --git a/third-party/fatfs-0.1.3/port/fsata_pcie/diskio.c b/third-party/fatfs-0.1.4/port/fsata_pcie/diskio_sata_pcie.c similarity index 33% rename from third-party/fatfs-0.1.3/port/fsata_pcie/diskio.c rename to third-party/fatfs-0.1.4/port/fsata_pcie/diskio_sata_pcie.c index 27d10ccf..5fa1ce5f 100644 --- a/third-party/fatfs-0.1.3/port/fsata_pcie/diskio.c +++ b/third-party/fatfs-0.1.4/port/fsata_pcie/diskio_sata_pcie.c @@ -14,7 +14,7 @@ #include "fdebug.h" #include "finterrupt.h" #include "ff.h" -#include "diskio.h" /* FatFs lower layer API */ +#include "diskio.h" /* FatFs lower layer API */ #include "fpcie.h" #include "fpcie_common.h" #include "fsata.h" @@ -29,7 +29,7 @@ /* 64位需要预留给内存池更大的空间 */ static u8 mem[50000] __attribute__((aligned(1024))) = {0}; -#define PCI_CLASS_STORAGE_SATA_AHCI 0x010601 +#define PCI_CLASS_STORAGE_SATA_AHCI 0x010601 #define SATA_HOST_MAX_NUM PLAT_AHCI_HOST_MAX_COUNT @@ -40,24 +40,42 @@ static s32 sata_host_count = 0; static boolean sata_ok = FALSE; -static s32 host_num = 0; /* sata host */ +static s32 host_num = 0; /* sata host */ static u32 port_num = 0; /* sata link port */ static FPcie pcie_obj = {0}; + +typedef struct +{ + DWORD id; + DWORD sector_sz; + DWORD sector_cnt; + FSataCtrl sata; + boolean init_ok; + BYTE pdrv; +} ff_sata_pcie_disk; + +static ff_sata_pcie_disk sata_pcie_disk = +{ + .pdrv = FF_DRV_NOT_USED, + .init_ok = FALSE, +}; /*-----------------------------------------------------------------------*/ /* Get Drive Status */ /*-----------------------------------------------------------------------*/ -DSTATUS disk_status ( - BYTE pdrv /* Physical drive nmuber to identify the drive */ +DSTATUS sata_pcie_disk_status( + BYTE pdrv /* Physical drive nmuber to identify the drive */ ) { - DSTATUS status = STA_NOINIT; + DSTATUS status = STA_NOINIT; - if (FT_COMPONENT_IS_READY == sata_device[host_num].is_ready) - status &= ~STA_NOINIT; /* 假设Sata处于插入状态 */ + if (FT_COMPONENT_IS_READY == sata_device[host_num].is_ready) + { + status &= ~STA_NOINIT; /* 假设Sata处于插入状态 */ + } - return status; + return status; } static void FSataPcieIrqHandler(void *param) @@ -65,194 +83,200 @@ static void FSataPcieIrqHandler(void *param) FSataIrqHandler(0, param); } -static void PCieIntxInit(FPcie* instance_p) +static void PCieIntxInit(FPcie *instance_p) { - InterruptSetPriority(FT_PCI_INTA_IRQ_NUM, 0); - - InterruptInstall(FT_PCI_INTA_IRQ_NUM, (IrqHandler)FPcieIntxIrqHandler, instance_p, "pcieInta"); - InterruptUmask(FT_PCI_INTA_IRQ_NUM); - InterruptSetPriority(FT_PCI_INTB_IRQ_NUM, 0); - InterruptInstall(FT_PCI_INTB_IRQ_NUM, (IrqHandler)FPcieIntxIrqHandler, instance_p, "pcieIntB"); - InterruptUmask(FT_PCI_INTB_IRQ_NUM); - InterruptSetPriority(FT_PCI_INTC_IRQ_NUM, 0); - InterruptInstall(FT_PCI_INTC_IRQ_NUM, (IrqHandler)FPcieIntxIrqHandler, instance_p, "pcieIntC"); - InterruptUmask(FT_PCI_INTC_IRQ_NUM); - InterruptSetPriority(FT_PCI_INTD_IRQ_NUM, 0); - InterruptInstall(FT_PCI_INTD_IRQ_NUM, (IrqHandler)FPcieIntxIrqHandler, instance_p, "pcieIntD"); - InterruptUmask(FT_PCI_INTD_IRQ_NUM); + InterruptSetPriority(FPCI_INTA_IRQ_NUM, 0); + + InterruptInstall(FPCI_INTA_IRQ_NUM, (IrqHandler)FPcieIntxIrqHandler, instance_p, "pcieInta"); + InterruptUmask(FPCI_INTA_IRQ_NUM); + InterruptSetPriority(FPCI_INTB_IRQ_NUM, 0); + InterruptInstall(FPCI_INTB_IRQ_NUM, (IrqHandler)FPcieIntxIrqHandler, instance_p, "pcieIntB"); + InterruptUmask(FPCI_INTB_IRQ_NUM); + InterruptSetPriority(FPCI_INTC_IRQ_NUM, 0); + InterruptInstall(FPCI_INTC_IRQ_NUM, (IrqHandler)FPcieIntxIrqHandler, instance_p, "pcieIntC"); + InterruptUmask(FPCI_INTC_IRQ_NUM); + InterruptSetPriority(FPCI_INTD_IRQ_NUM, 0); + InterruptInstall(FPCI_INTD_IRQ_NUM, (IrqHandler)FPcieIntxIrqHandler, instance_p, "pcieIntD"); + InterruptUmask(FPCI_INTD_IRQ_NUM); } static void FPcieInit() -{ - /* 第一步初始化pcie_obj这个实例,初始化mem,io资源成员 */ - FPcieCfgInitialize(&pcie_obj, FPcieLookupConfig(FT_PCIE0_ID)); +{ + /* 第一步初始化pcie_obj这个实例,初始化mem,io资源成员 */ + FPcieCfgInitialize(&pcie_obj, FPcieLookupConfig(FPCIE0_ID)); FSATA_DEBUG("\n"); - FSATA_DEBUG(" PCI:\n"); - FSATA_DEBUG(" B:D:F VID:PID parent_BDF class_code\n"); + FSATA_DEBUG(" PCI:\n"); + FSATA_DEBUG(" B:D:F VID:PID parent_BDF class_code\n"); FPcieScanBus(&pcie_obj, 0, 0xffffffff); - PCieIntxInit(&pcie_obj); + PCieIntxInit(&pcie_obj); } -static uintptr_t SataPcieIrqInstall(FSataCtrl* ahci_ctl, u32 bdf) +static uintptr_t SataPcieIrqInstall(FSataCtrl *ahci_ctl, u32 bdf) { - int ret = FT_SUCCESS; - - FPcieIntxFun intx_fun; + int ret = FT_SUCCESS; + + FPcieIntxFun intx_fun; intx_fun.IntxCallBack = FSataPcieIrqHandler; - intx_fun.args = ahci_ctl; - intx_fun.bdf = bdf; + intx_fun.args = ahci_ctl; + intx_fun.bdf = bdf; ret = FPcieIntxRegiterIrqHandler(&pcie_obj, bdf, &intx_fun); - if(ret != FT_SUCCESS) + if (ret != FT_SUCCESS) { return ret; } - return 0; + return 0; } static int FSataInit(void) { - int ret; - s32 host = 0; - u32 port = 0; - u32 bdf; - u32 class; - u16 pci_command; - const u32 class_code = PCI_CLASS_STORAGE_SATA_AHCI; - uintptr bar_addr = 0; - u16 vid, did; + int ret; + s32 host = 0; + u32 port = 0; + u32 bdf; + u32 class; + u16 pci_command; + const u32 class_code = PCI_CLASS_STORAGE_SATA_AHCI; + uintptr bar_addr = 0; + u16 vid, did; u32 port_mem_count = 0; - u8 link_success = 0; + u8 link_success = 0; const FSataConfig *config_p = NULL; FSataCtrl *instance_p; FError status = FSATA_SUCCESS; - FPcie *pcie = &pcie_obj; + FPcie *pcie = &pcie_obj; - if (sata_ok == TRUE) + if (sata_ok == TRUE) { - FSATA_WARN("sata already init\r\n"); + FSATA_WARN("Sata already init.\r\n"); return 0; } - for(host = 0; host < SATA_HOST_MAX_NUM; host++) + for (host = 0; host < SATA_HOST_MAX_NUM; host++) { - instance_p = &sata_device[host]; - memset(instance_p, 0, sizeof(*instance_p)); + instance_p = &sata_device[host]; + memset(instance_p, 0, sizeof(*instance_p)); config_p = FSataLookupConfig(host, FSATA_TYPE_PCIE); status = FSataCfgInitialize(&sata_device[host], config_p); if (FSATA_SUCCESS != status) { - FSATA_ERROR("init sata failed, status: 0x%x", status); + FSATA_ERROR("Init sata failed, status: 0x%x.", status); continue; } - } + } - /* find host from pcie instance */ - for(host = 0; host < pcie->scaned_bdf_count; host++) - { - bdf = pcie->scaned_bdf_array[host]; - FPcieEcamReadConfig32bit(pcie->config.ecam, bdf, FPCI_CLASS_REVISION, &class) ; + /* find host from pcie instance */ + for (host = 0; host < pcie->scaned_bdf_count; host++) + { + bdf = pcie->scaned_bdf_array[host]; + FPcieEcamReadConfig32bit(pcie->config.ecam, bdf, FPCI_CLASS_REVISION, &class) ; class = (class) >> 8 ; - if(class == class_code) - { - FPcieEcamReadConfig16bit(pcie->config.ecam, bdf, FPCIE_VENDOR_REG, &vid) ; - FPcieEcamReadConfig16bit(pcie->config.ecam, bdf, FPCIE_DEVICE_ID_REG, &did); + if (class == class_code) + { + FPcieEcamReadConfig16bit(pcie->config.ecam, bdf, FPCIE_VENDOR_REG, &vid) ; + FPcieEcamReadConfig16bit(pcie->config.ecam, bdf, FPCIE_DEVICE_ID_REG, &did); + + FSATA_DEBUG("AHCI-PCI HOST found !!!, b.d.f = %x.%x.%x\n", FPCIE_BUS(bdf), FPCIE_DEV(bdf), FPCIE_FUNC(bdf)); - FSATA_DEBUG("AHCI-PCI HOST found !!!, b.d.f = %x.%x.%x\n", FPCIE_BUS(bdf), FPCIE_DEV(bdf), FPCIE_FUNC(bdf)); - - FPcieEcamReadConfig32bit(pcie->config.ecam, bdf, FPCIE_BASE_ADDRESS_5, (u32*)&bar_addr); - FSATA_DEBUG("FSataPcieIntrInstall BarAddress %p", bar_addr); + FPcieEcamReadConfig32bit(pcie->config.ecam, bdf, FPCIE_BASE_ADDRESS_5, (u32 *)&bar_addr); + FSATA_DEBUG("FSataPcieIntrInstall BarAddress %p.", bar_addr); - if (0x0 == bar_addr) + if (0x0 == bar_addr) { - FSATA_ERROR("Bar address: 0x%lx", bar_addr); + FSATA_ERROR("Bar address: 0x%lx.", bar_addr); return -1; } - FPcieEcamReadConfig16bit(pcie->config.ecam, bdf, FPCIE_COMMAND_REG, &pci_command); - pci_command |= FPCIE_COMMAND_MASTER; - FPcieEcamWriteConfig16bit(pcie->config.ecam, bdf, FPCIE_COMMAND_REG, pci_command); - - SataPcieIrqInstall(&sata_device[sata_host_count] ,bdf); - sata_device[sata_host_count].config.base_addr = bar_addr; - FSATA_DEBUG("sata_device[%d].config.base_addr = 0x%x\n", sata_host_count, sata_device[sata_host_count].config.base_addr); - sata_host_count++; - if(sata_host_count >= SATA_HOST_MAX_NUM) + FPcieEcamReadConfig16bit(pcie->config.ecam, bdf, FPCIE_COMMAND_REG, &pci_command); + pci_command |= FPCIE_COMMAND_MASTER; + FPcieEcamWriteConfig16bit(pcie->config.ecam, bdf, FPCIE_COMMAND_REG, pci_command); + + SataPcieIrqInstall(&sata_device[sata_host_count], bdf); + sata_device[sata_host_count].config.base_addr = bar_addr; + FSATA_DEBUG("sata_device[%d].config.base_addr = 0x%x.\n", sata_host_count, sata_device[sata_host_count].config.base_addr); + sata_host_count++; + if (sata_host_count >= SATA_HOST_MAX_NUM) + { break; - } - } - - FSATA_DEBUG("scaned %d ahci host\n", sata_host_count); - - for(host = 0; host < sata_host_count; host++) - { - instance_p = &sata_device[host]; - - /* Initialization */ - status = FSataAhciInit(instance_p); - if (FSATA_SUCCESS != status) - { - FSataCfgDeInitialize(instance_p); - FSATA_ERROR("FSataAhciInit sata failed, ret: 0x%x", status); - continue; - } - - for (port = 0; port < instance_p->n_ports; port++) - { - u32 port_map = instance_p->port_map; - if (!(port_map & BIT(port))) - continue; - - /* command list address must be 1K-byte aligned */ + } + } + } + + FSATA_DEBUG("Scaned %d ahci host.\n", sata_host_count); + + for (host = 0; host < sata_host_count; host++) + { + instance_p = &sata_device[host]; + + /* Initialization */ + status = FSataAhciInit(instance_p); + if (FSATA_SUCCESS != status) + { + FSataCfgDeInitialize(instance_p); + FSATA_ERROR("FSataAhciInit sata failed, ret: 0x%x.", status); + continue; + } + + for (port = 0; port < instance_p->n_ports; port++) + { + u32 port_map = instance_p->port_map; + if (!(port_map & BIT(port))) + { + continue; + } + + /* command list address must be 1K-byte aligned */ ret = FSataAhciPortStart(instance_p, port, (uintptr)mem + PALIGN_UP(FSATA_AHCI_PORT_PRIV_DMA_SZ, ADDR_ALIGNMENT) * port_mem_count); - - port_mem_count++; - if (FSATA_SUCCESS != ret) - { - FSATA_ERROR("FSataAhciPortStart port %d failed, ret: 0x%x", port, ret); - continue; - } - - status = FSataAhciReadInfo(instance_p, port); - if (FSATA_SUCCESS != status) - { - FSataCfgDeInitialize(instance_p); - FSATA_ERROR("FSataAhciReadInfo failed, ret: 0x%x", status); - continue; - } - - } - } - + + port_mem_count++; + if (FSATA_SUCCESS != ret) + { + FSATA_ERROR("FSataAhciPortStart port %d failed, ret: 0x%x.", port, ret); + continue; + } + + status = FSataAhciReadInfo(instance_p, port); + if (FSATA_SUCCESS != status) + { + FSataCfgDeInitialize(instance_p); + FSATA_ERROR("FSataAhciReadInfo failed, ret: 0x%x.", status); + continue; + } + + } + } + sata_ok = TRUE; - /* get host number and port number which link success */ - for(host_num = 0; host_num < sata_host_count; host_num++) + /* get host number and port number which link success */ + for (host_num = 0; host_num < sata_host_count; host_num++) { for (port_num = 0; port_num < sata_device[host_num].n_ports; port_num++) { if (!(sata_device[host_num].link_port_map & BIT(port_num))) { - printf("host_num %d port_num %d is not link\n", host_num, port_num); + FSATA_DEBUG("host_num %d port_num %d is not link.\n", host_num, port_num); continue; } else { - printf("host_num %d port_num %d is link\n", host_num, port_num); + FSATA_DEBUG("host_num %d port_num %d is link.\n", host_num, port_num); link_success = 1; break; } } - if(link_success == 1) + if (link_success == 1) + { break; + } } - if(link_success != 1) + if (link_success != 1) { - FSATA_ERROR("Sata host port link failed\n"); + FSATA_ERROR("Sata host port link failed.\n"); return -1; } @@ -264,29 +288,29 @@ static int FSataInit(void) /* Inidialize a Drive */ /*-----------------------------------------------------------------------*/ -DSTATUS disk_initialize ( - BYTE pdrv /* Physical drive nmuber to identify the drive */ +DSTATUS sata_pcie_disk_initialize( + BYTE pdrv /* Physical drive nmuber to identify the drive */ ) { - DSTATUS status = STA_NOINIT; + DSTATUS status = STA_NOINIT; static u8 flag = 0; if (flag == 0) { FPcieInit(); flag = 1; } - + if (FSATA_SUCCESS == FSataInit()) - { - status &= ~STA_NOINIT; - FSATA_INFO("init sata driver ok"); - } - else - { - FSATA_ERROR("init sata driver failed"); - } - - return status; + { + status &= ~STA_NOINIT; + FSATA_INFO("Init sata driver successfully."); + } + else + { + FSATA_ERROR("Init sata driver failed."); + } + + return status; } @@ -295,98 +319,116 @@ DSTATUS disk_initialize ( /* Read Sector(s) */ /*-----------------------------------------------------------------------*/ -DRESULT disk_read ( - BYTE pdrv, /* Physical drive nmuber to identify the drive */ - BYTE *buff, /* Data buffer to store read data */ - DWORD sector, /* Start sector in LBA */ - UINT count /* Number of sectors to read */ +DRESULT sata_pcie_disk_read( + BYTE pdrv, /* Physical drive nmuber to identify the drive */ + BYTE *buff, /* Data buffer to store read data */ + DWORD sector, /* Start sector in LBA */ + UINT count /* Number of sectors to read */ ) { - DRESULT status = RES_OK; - BYTE *io_buf = buff; - UINT err = FSATA_SUCCESS; + DRESULT status = RES_OK; + BYTE *io_buf = buff; + UINT err = FSATA_SUCCESS; - err = FSataReadWrite(&sata_device[host_num], port_num, sector, count, io_buf, FALSE, FALSE); + err = FSataReadWrite(&sata_device[host_num], port_num, sector, count, io_buf, FALSE, FALSE); - if (FSATA_SUCCESS != err) - { - FSATA_ERROR("read pcie sata sector [%d-%d] failed: 0x%x", sector, sector + count, err); - status = RES_ERROR; - } + if (FSATA_SUCCESS != err) + { + FSATA_ERROR("Read pcie sata sector [%d-%d] failed: 0x%x.", sector, sector + count, err); + status = RES_ERROR; + } - return status; + return status; } /*-----------------------------------------------------------------------*/ /* Write Sector(s) */ /*-----------------------------------------------------------------------*/ -DRESULT disk_write ( - BYTE pdrv, /* Physical drive nmuber to identify the drive */ - const BYTE *buff, /* Data to be written */ - DWORD sector, /* Start sector in LBA */ - UINT count /* Number of sectors to write */ +DRESULT sata_pcie_disk_write( + BYTE pdrv, /* Physical drive nmuber to identify the drive */ + const BYTE *buff, /* Data to be written */ + DWORD sector, /* Start sector in LBA */ + UINT count /* Number of sectors to write */ ) { - DRESULT status = RES_OK; - const BYTE *io_buf = buff; - UINT err = FSATA_SUCCESS; - - err = FSataReadWrite(&sata_device[host_num], port_num, sector, count, (u8 *)io_buf, FALSE, TRUE); - - if (FSATA_SUCCESS != err) - { - FSATA_ERROR("write pcie sata sector [%d-%d] failed: 0x%x", sector, sector + count, err); - status = RES_ERROR; - } - - return status; + DRESULT status = RES_OK; + const BYTE *io_buf = buff; + UINT err = FSATA_SUCCESS; + + err = FSataReadWrite(&sata_device[host_num], port_num, sector, count, (u8 *)io_buf, FALSE, TRUE); + + if (FSATA_SUCCESS != err) + { + FSATA_ERROR("Write pcie sata sector [%d-%d] failed: 0x%x.", sector, sector + count, err); + status = RES_ERROR; + } + + return status; } /*-----------------------------------------------------------------------*/ /* Miscellaneous Functions */ /*-----------------------------------------------------------------------*/ -DRESULT disk_ioctl ( - BYTE pdrv, /* Physical drive nmuber (0..) */ - BYTE cmd, /* Control code */ - void *buff /* Buffer to send/receive control data */ +DRESULT sata_pcie_disk_ioctl( + BYTE pdrv, /* Physical drive nmuber (0..) */ + BYTE cmd, /* Control code */ + void *buff /* Buffer to send/receive control data */ ) { - DRESULT res = RES_ERROR; - - switch (cmd) - { - /* 确保磁盘驱动器已经完成了写处理,当磁盘I/O有一个写回缓存, - 立即刷新原扇区,只读配置下不适用此命令 */ - case CTRL_SYNC: - res = RES_OK; - break; - /* 所有可用的扇区数目(逻辑寻址即LBA寻址方式) */ - case GET_SECTOR_COUNT: - *((DWORD *)buff) = sata_device[host_num].port[port_num].dev_info.lba512; - res = RES_OK; /* 最多使用1000个sector */ - break; - /* 返回磁盘扇区大小, 只用于f_mkfs() */ - case GET_SECTOR_SIZE: - res = RES_PARERR; - break; - /* 每个扇区有多少个字节 */ - case GET_BLOCK_SIZE: - *((DWORD *)buff) = sata_device[host_num].port[port_num].dev_info.blksz; - res = RES_OK; - break; - case CTRL_TRIM: - res = RES_PARERR; - break; - } - - FSATA_INFO("cmd %d, buff: %p", cmd, *((DWORD*) buff)); - return res; + DRESULT res = RES_ERROR; + + switch (cmd) + { + /* 确保磁盘驱动器已经完成了写处理,当磁盘I/O有一个写回缓存, + 立即刷新原扇区,只读配置下不适用此命令 */ + case CTRL_SYNC: + res = RES_OK; + break; + /* 所有可用的扇区数目(逻辑寻址即LBA寻址方式) */ + case GET_SECTOR_COUNT: + *((DWORD *)buff) = sata_device[host_num].port[port_num].dev_info.lba512; + res = RES_OK; /* 最多使用1000个sector */ + break; + /* 返回磁盘扇区大小, 只用于f_mkfs() */ + case GET_SECTOR_SIZE: + res = RES_PARERR; + break; + /* 每个扇区有多少个字节 */ + case GET_BLOCK_SIZE: + *((DWORD *)buff) = sata_device[host_num].port[port_num].dev_info.blksz; + res = RES_OK; + break; + case CTRL_TRIM: + res = RES_PARERR; + break; + } + + FSATA_INFO("cmd %d, buff: %p", cmd, *((DWORD *) buff)); + return res; } +static const ff_diskio_driver_t sata_pcie_disk_drv = +{ + .init = &sata_pcie_disk_initialize, + .status = &sata_pcie_disk_status, + .read = &sata_pcie_disk_read, + .write = &sata_pcie_disk_write, + .ioctl = &sata_pcie_disk_ioctl +}; + +void ff_diskio_register_sata_pcie(BYTE pdrv) +{ + ff_sata_pcie_disk *disk = &sata_pcie_disk; + disk->id = FSATA0_ID; + disk->init_ok = FALSE; + disk->pdrv = pdrv; /* assign volume for sata pcie disk */ + ff_diskio_register(pdrv, &sata_pcie_disk_drv); + FSATA_INFO("Create sata pcie disk as driver-%d.", disk->pdrv); +} diff --git a/third-party/fatfs-0.1.4/port/fusb/diskio_usb.c b/third-party/fatfs-0.1.4/port/fusb/diskio_usb.c new file mode 100644 index 00000000..3865a9ac --- /dev/null +++ b/third-party/fatfs-0.1.4/port/fusb/diskio_usb.c @@ -0,0 +1,342 @@ +/*-----------------------------------------------------------------------*/ +/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2016 */ +/*-----------------------------------------------------------------------*/ +/* If a working storage control module is available, it should be */ +/* attached to the FatFs via a glue function rather than modifying it. */ +/* This is an example of glue functions to attach various exsisting */ +/* storage control modules to the FatFs module with a defined API. */ +/*-----------------------------------------------------------------------*/ + +#include +#include +#include "fparameters.h" +#include "fdebug.h" +#include "fkernel.h" +#include "fparameters.h" +#include "fassert.h" +#include "fcache.h" +#include "finterrupt.h" +#include "fcpu_info.h" +#include "diskio.h" +#include "ffconf.h" +#include "ff.h" +#include "fmemory_pool.h" +#include "sdkconfig.h" + +#include "usbh_core.h" +#include "usbh_msc.h" + +#define FF_DEBUG_TAG "DISKIO-USB" +#define FF_ERROR(format, ...) FT_DEBUG_PRINT_E(FF_DEBUG_TAG, format, ##__VA_ARGS__) +#define FF_INFO(format, ...) FT_DEBUG_PRINT_I(FF_DEBUG_TAG, format, ##__VA_ARGS__) +#define FF_DEBUG(format, ...) FT_DEBUG_PRINT_D(FF_DEBUG_TAG, format, ##__VA_ARGS__) +#define FF_WARN(format, ...) FT_DEBUG_PRINT_W(FF_DEBUG_TAG, format, ##__VA_ARGS__) + +#define FUSB_MEMP_TOTAL_SIZE SZ_1M +#define FUSB_FATFS_ID FUSB3_ID_0 + +static FMemp memp; +static u8 memp_buf[FUSB_MEMP_TOTAL_SIZE]; +FASSERT_STATIC(FUSB_FATFS_ID < FUSB3_NUM); + +static const u32 usb_irq_num[FUSB3_NUM] = +{ + [FUSB3_ID_0] = FUSB3_0_IRQ_NUM, + [FUSB3_ID_1] = FUSB3_1_IRQ_NUM +}; + +static const uintptr xhci_base_addr[FUSB3_NUM] = +{ + [FUSB3_ID_0] = FUSB3_0_BASE_ADDR + FUSB3_XHCI_OFFSET, + [FUSB3_ID_1] = FUSB3_1_BASE_ADDR + FUSB3_XHCI_OFFSET +}; + +typedef struct +{ + DWORD id; + boolean init_ok; + BYTE pdrv; + const TCHAR *disk_name; +} ff_usb_disk; + +static ff_usb_disk usb_disk = +{ + .pdrv = FF_DRV_NOT_USED, + .init_ok = FALSE, + .disk_name = "/dev/sda" +}; + +/*****************************************************************************/ +extern void USBH_IRQHandler(void); + +static void UsbHcInterrruptHandler(s32 vector, void *param) +{ + USBH_IRQHandler(); +} + +static void UsbHcSetupInterrupt(void) +{ + u32 cpu_id; + u32 irq_num = usb_irq_num[FUSB_FATFS_ID]; + u32 irq_priority = 13U; + + GetCpuId(&cpu_id); + InterruptSetTargetCpus(irq_num, cpu_id); + + InterruptSetPriority(irq_num, irq_priority); + + /* register intr callback */ + InterruptInstall(irq_num, + UsbHcInterrruptHandler, + NULL, + NULL); + + /* enable irq */ + InterruptUmask(irq_num); +} + +void UsbHcSetupMemp(void) +{ + if (FT_COMPONENT_IS_READY != memp.is_ready) + { + USB_ASSERT(FT_SUCCESS == FMempInit(&memp, &memp_buf[0], &memp_buf[0] + FUSB_MEMP_TOTAL_SIZE)); + } +} + +/* implement cherryusb weak functions */ +void usb_hc_low_level_init(void) +{ + UsbHcSetupMemp(); + UsbHcSetupInterrupt(); +} + +unsigned long usb_hc_get_register_base(void) +{ + return xhci_base_addr[FUSB_FATFS_ID]; +} + +void *usb_hc_malloc(size_t size) +{ + return usb_hc_malloc_align(sizeof(void *), size); +} + +void *usb_hc_malloc_align(size_t align, size_t size) +{ + void *result = FMempMallocAlign(&memp, size, align); + + if (result) + { + memset(result, 0U, size); + } + + return result; +} + +void usb_hc_free(void *ptr) +{ + if (NULL != ptr) + { + FMempFree(&memp, ptr); + } +} + +void usb_assert(const char *filename, int linenum) +{ + FAssert(filename, linenum, 0xff); +} + +void usb_hc_dcache_invalidate(void *addr, unsigned long len) +{ + FCacheDCacheInvalidateRange((uintptr)addr, len); +} +/*****************************************/ + +/*-----------------------------------------------------------------------*/ +/* Get Drive Status */ +/*-----------------------------------------------------------------------*/ + +static DSTATUS usb_disk_status( + BYTE pdrv /* Physical drive nmuber to identify the drive */ +) +{ + DSTATUS status = STA_NOINIT; + ff_usb_disk *disk = &usb_disk; + + if (disk->init_ok) + { + status &= ~STA_NOINIT; + } + + return status; +} + +/*-----------------------------------------------------------------------*/ +/* Inidialize a Drive */ +/*-----------------------------------------------------------------------*/ + +static DSTATUS usb_disk_initialize( + BYTE pdrv /* Physical drive nmuber to identify the drive */ +) +{ + DSTATUS status = STA_NOINIT; + ff_usb_disk *disk = &usb_disk; + int retries = 10000; + + if (FF_DRV_NOT_USED == disk->pdrv) + { + return STA_NOINIT; + } + + if (FALSE == disk->init_ok) + { + (void)usbh_initialize(); /* start a task to emurate usb hub and attached usb disk */ + while (TRUE) + { + if (NULL != usbh_find_class_instance(disk->disk_name)) + { + break; + } + + if (retries-- < 0) + { + FF_ERROR("Init cherryusb host failed or usb disk device not found !!!"); + return STA_NOINIT; + } + + vTaskDelay(10); /* may need to wait while for usb disk emuration */ + } + + disk->init_ok = TRUE; + } + + status &= ~STA_NOINIT; + return status; +} + +/*-----------------------------------------------------------------------*/ +/* Read Sector(s) */ +/*-----------------------------------------------------------------------*/ + +static DRESULT usb_disk_read( + BYTE pdrv, /* Physical drive nmuber to identify the drive */ + BYTE *buff, /* Data buffer to store read data */ + DWORD sector, /* Start sector in LBA */ + UINT count /* Number of sectors to read */ +) +{ + DRESULT status = RES_OK; + ff_usb_disk *disk = &usb_disk; + struct usbh_msc *msc_class = (struct usbh_msc *)usbh_find_class_instance(disk->disk_name); + + if (msc_class) + { + if (0 > usbh_msc_scsi_read10(msc_class, sector, buff, count)) + { + FF_ERROR("Read usb sector [%d-%d] failed: 0x%x.", sector, sector + count); + status = RES_ERROR; + } + } + else + { + status = RES_PARERR; + } + + return status; +} + +/*-----------------------------------------------------------------------*/ +/* Write Sector(s) */ +/*-----------------------------------------------------------------------*/ + +static DRESULT usb_disk_write( + BYTE pdrv, /* Physical drive nmuber to identify the drive */ + const BYTE *buff, /* Data to be written */ + DWORD sector, /* Start sector in LBA */ + UINT count /* Number of sectors to write */ +) +{ + DRESULT status = RES_OK; + ff_usb_disk *disk = &usb_disk; + struct usbh_msc *msc_class = (struct usbh_msc *)usbh_find_class_instance(disk->disk_name); + + if (msc_class) + { + if (0 > usbh_msc_scsi_write10(msc_class, sector, buff, count)) + { + FF_ERROR("Write usb sector [%d-%d] failed: 0x%x.", sector, sector + count); + status = RES_ERROR; + } + } + else + { + status = RES_PARERR; + } + + return status; +} + +/*-----------------------------------------------------------------------*/ +/* Miscellaneous Functions */ +/*-----------------------------------------------------------------------*/ + +DRESULT usb_disk_ioctl( + BYTE pdrv, /* Physical drive nmuber (0..) */ + BYTE cmd, /* Control code */ + void *buff /* Buffer to send/receive control data */ +) +{ + DRESULT res; + ff_usb_disk *disk = &usb_disk; + struct usbh_msc *msc_class = (struct usbh_msc *)usbh_find_class_instance(disk->disk_name); + + res = RES_PARERR; + if (NULL == msc_class) + { + return res; + } + + switch (cmd) + { + case CTRL_SYNC: /* Nothing to do */ + res = RES_OK; + break; + + case GET_SECTOR_COUNT: /* Get number of sectors on the drive */ + *(DWORD *)buff = msc_class->blocknum; + res = RES_OK; + break; + + case GET_SECTOR_SIZE: /* Get size of sector for generic read/write */ + *(WORD *)buff = msc_class->blocksize; + res = RES_OK; + break; + + case GET_BLOCK_SIZE: + *(DWORD *)buff = 1; /* This is not flash storage that can be erase by command, return 1 */ + res = RES_OK; + break; + } + + return res; +} + +static const ff_diskio_driver_t usb_disk_drv = +{ + .init = &usb_disk_initialize, + .status = &usb_disk_status, + .read = &usb_disk_read, + .write = &usb_disk_write, + .ioctl = &usb_disk_ioctl +}; + +void ff_diskio_register_usb(BYTE pdrv) +{ + ff_usb_disk *disk = &usb_disk; + + disk->id = FUSB_FATFS_ID; + disk->init_ok = FALSE; + disk->pdrv = pdrv; /* assign volume for usb disk */ + ff_diskio_register(pdrv, &usb_disk_drv); + + FF_INFO("Create usb disk as driver-%d.", disk->pdrv); +} \ No newline at end of file diff --git a/third-party/freertos/Kconfig b/third-party/freertos/Kconfig new file mode 100644 index 00000000..a04ab000 --- /dev/null +++ b/third-party/freertos/Kconfig @@ -0,0 +1,198 @@ + + + config FREERTOS_OPTIMIZED_SCHEDULER + bool "Enable FreeRTOS platform optimized scheduler" + default y + help + On most platforms there are instructions can speedup the ready task + searching. Enabling this option the FreeRTOS with this instructions + support will be built. + + config FREERTOS_HZ + int "Tick rate (Hz)" + range 1 10000 + default 1000 + help + Select the tick rate at which FreeRTOS does pre-emptive context switching. + + config FREERTOS_MAX_PRIORITIES + int "Max task priority" + range 1 32 + default 32 + help + Sets the maximum priority that can be assigned to a task. Tasks can be assigned a priority + from zero, which is the lowest priority, to (FREERTOS_MAX_PRIORITIES - 1), which is the highest + priority. + + config FREERTOS_KERNEL_INTERRUPT_PRIORITIES + int "Kernel interrupt priority" + range 1 13 + default 13 + help + Sets the interrupt priority used by the tick interrupt, and must always be set to the + lowest possible interrupt priority. + + config FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES + int "Max api call interrupt priority" + range 1 15 + default 11 + help + Sets the highest interrupt priority from which interrupt-safe FreeRTOS API functions can + be called. + + + config FREERTOS_THREAD_LOCAL_STORAGE_POINTERS + int "Number of thread local storage pointers" + range 1 256 + default 1 + help + FreeRTOS has the ability to store per-thread pointers in the task + control block. This controls the number of pointers available. + + This value must be at least 1. Index 0 is reserved for use by the pthreads API + thread-local-storage. Other indexes can be used for any desired purpose. + + + config FREERTOS_MINIMAL_TASK_STACKSIZE + int "Minimal Task stack size" + range 768 32768 + default 1024 + help + The idle task has its own stack, sized in bytes. The default size is enough for most uses. Size can be + reduced to 768 bytes if no (or simple) FreeRTOS idle hooks are used and pthread local storage or FreeRTOS + local storage cleanup callbacks are not used. + + The stack size may need to be increased above the default if the app installs idle or thread local storage + cleanup hooks that use a lot of stack memory. + + + config FREERTOS_MAX_TASK_NAME_LEN + int "Maximum task name length" + range 1 256 + default 32 + help + Changes the maximum task name length. Each task allocated will + include this many bytes for a task name. Using a shorter value + saves a small amount of RAM, a longer value allows more complex + names. + + For most uses, the default of 16 is OK. + + + config FREERTOS_TIMER_TASK_PRIORITY + int "FreeRTOS timer task priority" + range 1 25 + default 1 + help + The timer service task (primarily) makes use of existing FreeRTOS features, allowing timer + functionality to be added to an application with minimal impact on the size of the application's + executable binary. + + Use this constant to define the priority that the timer task will run at. + + config FREERTOS_TIMER_TASK_STACK_DEPTH + int "FreeRTOS timer task stack size" + range 1536 32768 + default 2048 + help + The timer service task (primarily) makes use of existing FreeRTOS features, allowing timer + functionality to be added to an application with minimal impact on the size of the application's + executable binary. + + Use this constant to define the size (in bytes) of the stack allocated for the timer task. + + config FREERTOS_TIMER_QUEUE_LENGTH + int "FreeRTOS timer queue length" + range 5 20 + default 10 + help + FreeRTOS provides a set of timer related API functions. Many of these functions use a standard + FreeRTOS queue to send commands to the timer service task. The queue used for this purpose is + called the 'timer command queue'. The 'timer command queue' is private to the FreeRTOS timer + implementation, and cannot be accessed directly. + + For most uses the default value of 10 is OK. + + config FREERTOS_QUEUE_REGISTRY_SIZE + int "FreeRTOS queue registry size" + range 0 20 + default 0 + help + FreeRTOS uses the queue registry as a means for kernel aware debuggers to locate queues, semaphores, + and mutexes. The registry allows for a textual name to be associated with a queue for easy identification + within a debugging GUI. A value of 0 will disable queue registry functionality, and a value larger than 0 + will specify the number of queues/semaphores/mutexes that the registry can hold. + + config FREERTOS_GENERATE_RUN_TIME_STATS + bool "Enable FreeRTOS to collect run time stats" + default y + select FREERTOS_USE_TRACE_FACILITY + select FREERTOS_USE_STATS_FORMATTING_FUNCTIONS + help + If enabled, configGENERATE_RUN_TIME_STATS will be defined as 1 in + FreeRTOS. This will allow FreeRTOS to collect information regarding the + usage of processor time amongst FreeRTOS tasks. + The function vTaskGetRunTimeStats() will also be available + if FREERTOS_USE_STATS_FORMATTING_FUNCTIONS and + FREERTOS_USE_TRACE_FACILITY are enabled. vTaskGetRunTimeStats() will + display the run time of each task as a % of the total run time of all + CPUs (task run time / no of CPUs) / (total run time / 100 ) + + config FREERTOS_USE_TRACE_FACILITY + bool "Enable FreeRTOS trace facility" + default n + help + If enabled, configUSE_TRACE_FACILITY will be defined as 1 in FreeRTOS. + This will allow the usage of trace facility functions such as + uxTaskGetSystemState(). + + config FREERTOS_USE_STATS_FORMATTING_FUNCTIONS + bool "Enable FreeRTOS stats formatting functions" + depends on FREERTOS_USE_TRACE_FACILITY + default n + help + If enabled, configUSE_STATS_FORMATTING_FUNCTIONS will be defined as 1 in + FreeRTOS. This will allow the usage of stats formatting functions such + as vTaskList(). + + config FREERTOS_USE_TICKLESS_IDLE + bool "Tickless idle support" + default n + help + If power management support is enabled, FreeRTOS will be able to put + the system into light sleep mode when no tasks need to run for a number + of ticks. This number can be set using FREERTOS_IDLE_TIME_BEFORE_SLEEP option. + This feature is also known as "automatic light sleep". + + Note that timers created using APIs may prevent the system from + entering sleep mode, even when no tasks need to run. + To skip unnecessary wake-up initialize a timer with the "skip_unhandled_events" option as true. + + If disabled, automatic light sleep support will be disabled. + + config FREERTOS_IDLE_TIME_BEFORE_SLEEP + int "Minimum number of ticks to enter sleep mode for" + depends on FREERTOS_USE_TICKLESS_IDLE + default 3 + range 2 4294967295 + # Minimal value is 2 because of a check in FreeRTOS.h (search configEXPECTED_IDLE_TIME_BEFORE_SLEEP) + help + FreeRTOS will enter light sleep mode if no tasks need to run for this number + of ticks. + + config FREERTOS_TOTAL_HEAP_SIZE + int "Total amount of RAM available in the FreeRTOS heap, unit kbytes" + range 1 65535 + default 10240 + help + Set the total amount of RAM available in the FreeRTOS heap, unit kbytes, less than RAM_SIZE_MB. + + + config FREERTOS_TASK_FPU_SUPPORT + int "Use floating point support" + default 1 + range 1 2 + help + If set to 1, tasks are created without an FPU context and must call vPortTaskUsesFPU() to give + themselves an FPU context before using any FPU instructions. + If set to 2, all tasks will have an FPU context by default. \ No newline at end of file diff --git a/third-party/freertos/portable/GCC/ft_platform/aarch32/FreeRTOSConfig.h b/third-party/freertos/portable/GCC/ft_platform/FreeRTOSConfig.h similarity index 62% rename from third-party/freertos/portable/GCC/ft_platform/aarch32/FreeRTOSConfig.h rename to third-party/freertos/portable/GCC/ft_platform/FreeRTOSConfig.h index bf267016..dce41b97 100644 --- a/third-party/freertos/portable/GCC/ft_platform/aarch32/FreeRTOSConfig.h +++ b/third-party/freertos/portable/GCC/ft_platform/FreeRTOSConfig.h @@ -28,9 +28,10 @@ #ifndef FREERTOS_CONFIG_H #define FREERTOS_CONFIG_H -#if !defined(__ASSEMBLER__) -#include "fparameters.h" -#include "finterrupt.h" +#include "sdkconfig.h" +#if !defined(__ASSEMBLER__) + #include "fparameters.h" + #include "finterrupt.h" #endif /*----------------------------------------------------------- @@ -67,22 +68,35 @@ * */ -/* 在不安全group1 中,16 is steps ,3 是其中等级*/ -#define configKERNEL_INTERRUPT_PRIORITY IRQ_PRIORITY_VALUE_11 -/* 在不安全group1 中 ,0x8 ~0xb 不可以使用安全api(优先级越低越高)*/ -#define configMAX_API_CALL_INTERRUPT_PRIORITY IRQ_PRIORITY_VALUE_11 +/* the interrupt priority used by the tick interrupt */ +#define configKERNEL_INTERRUPT_PRIORITY ( CONFIG_FREERTOS_KERNEL_INTERRUPT_PRIORITIES ) +/* the highest interrupt priority from which interrupt-safe FreeRTOS API functions can be called */ +#define configMAX_API_CALL_INTERRUPT_PRIORITY ( CONFIG_FREERTOS_MAX_API_CALL_INTERRUPT_PRIORITIES ) -#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 //Method to select the next task -#define configUSE_TICKLESS_IDLE 0 //disable tickless mode -#define configTICK_RATE_HZ ((TickType_t)1000) //system timer rate 1ms -#define configUSE_PREEMPTION 1 //preemption task +#ifdef CONFIG_FREERTOS_OPTIMIZED_SCHEDULER + #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 +#endif + +#ifdef CONFIG_FREERTOS_USE_TICKLESS_IDLE + #define configUSE_TICKLESS_IDLE 1 + #define configEXPECTED_IDLE_TIME_BEFORE_SLEEP CONFIG_FREERTOS_IDLE_TIME_BEFORE_SLEEP +#endif + +#define configTICK_RATE_HZ ( CONFIG_FREERTOS_HZ ) +#define configUSE_PREEMPTION 1 #define configUSE_IDLE_HOOK 1 #define configUSE_TICK_HOOK 1 -#define configMAX_PRIORITIES (7) -#define configMINIMAL_STACK_SIZE ((unsigned short)1024) //min task stack size 100*4 bytes -#define configTOTAL_HEAP_SIZE (10 * 1024 * 1024) //total heap size -#define configMAX_TASK_NAME_LEN (32) -#define configUSE_TRACE_FACILITY 1 //启用可视化跟踪调试 +#define configMAX_PRIORITIES ( CONFIG_FREERTOS_MAX_PRIORITIES ) +#define configMINIMAL_STACK_SIZE ( CONFIG_FREERTOS_MINIMAL_TASK_STACKSIZE ) +#define configTOTAL_HEAP_SIZE ( CONFIG_FREERTOS_TOTAL_HEAP_SIZE * 1024) +#define configMAX_TASK_NAME_LEN ( CONFIG_FREERTOS_MAX_TASK_NAME_LEN ) +#ifdef CONFIG_FREERTOS_USE_TRACE_FACILITY + #define configUSE_TRACE_FACILITY 1 /* Used by uxTaskGetSystemState(), and other trace facility functions */ +#endif + +#define configUSE_TASK_FPU_SUPPORT (CONFIG_FREERTOS_TASK_FPU_SUPPORT) + + /* 与宏 configUSE_TRACE_FACILITY 同时为 1 时会编译下面 3 个函数 * prvWriteNameToBuffer() * vTaskList(), @@ -91,7 +105,7 @@ #define configUSE_16_BIT_TICKS 0 //use 32 bit ticktype #define configIDLE_SHOULD_YIELD 1 //idle task would not yield for task with same priority #define configUSE_MUTEXES 1 -#define configQUEUE_REGISTRY_SIZE 8 //max queue and semp member +#define configQUEUE_REGISTRY_SIZE ( CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE ) #define configCHECK_FOR_STACK_OVERFLOW 0 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_MALLOC_FAILED_HOOK 1 @@ -101,25 +115,15 @@ #define configSUPPORT_STATIC_ALLOCATION 1 //use dynamic memory allocation #define configSUPPORT_DYNAMIC_ALLOCATION 1 -/* Include the query-heap CLI command to query the free heap space. */ -#define configINCLUDE_QUERY_HEAP_COMMAND 1 - /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 //disable co-routines #define configMAX_CO_ROUTINE_PRIORITIES (2) /* Software timer definitions. */ -#define configUSE_TIMERS 1 //use software timer -#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES - 1) -#define configTIMER_QUEUE_LENGTH 5 -#define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE * 2) - -/* If configUSE_TASK_FPU_SUPPORT is set to 1 (or undefined) then each task will -be created without an FPU context, and a task must call vTaskUsesFPU() before -making use of any FPU registers. If configUSE_TASK_FPU_SUPPORT is set to 2 then -tasks are created with an FPU context by default, and calling vTaskUsesFPU() has -no effect. */ -#define configUSE_TASK_FPU_SUPPORT 1 +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY ( CONFIG_FREERTOS_TIMER_TASK_PRIORITY ) +#define configTIMER_QUEUE_LENGTH ( CONFIG_FREERTOS_TIMER_QUEUE_LENGTH ) +#define configTIMER_TASK_STACK_DEPTH ( CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH ) /* Set the following definitions to 1 to include the API function, or zero to exclude the API function. */ @@ -137,23 +141,29 @@ to exclude the API function. */ #define INCLUDE_xTaskGetHandle 1 #define INCLUDE_xSemaphoreGetMutexHolder 1 -#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5 +#define configNUM_THREAD_LOCAL_STORAGE_POINTERS ( CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS ) #define INCLUDE_xTaskGetIdleTaskHandle 1 /* This demo makes use of one or more example stats formatting functions. These format the raw data provided by the uxTaskGetSystemState() function in to human readable ASCII form. See the notes in the implementation of vTaskList() within FreeRTOS/Source/tasks.c for limitations. */ -#define configUSE_STATS_FORMATTING_FUNCTIONS 1 +#ifdef CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS + #define configUSE_STATS_FORMATTING_FUNCTIONS 1 /* Used by vTaskList() */ +#endif + /* Run time stats are not generated. portCONFIGURE_TIMER_FOR_RUN_TIME_STATS and portGET_RUN_TIME_COUNTER_VALUE must be defined if configGENERATE_RUN_TIME_STATS is set to 1. */ -#define configGENERATE_RUN_TIME_STATS 1 //启用运行时间统计功能 +#ifdef CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS + #define configGENERATE_RUN_TIME_STATS 1 +#endif + #ifndef __ASSEMBLER__ // skip when preprocess asm -extern volatile unsigned int gCpuRuntime; -#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() (gCpuRuntime = 0ul) -#define portGET_RUN_TIME_COUNTER_VALUE() gCpuRuntime + extern volatile unsigned int gCpuRuntime; + #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() (gCpuRuntime = 0ul) + #define portGET_RUN_TIME_COUNTER_VALUE() gCpuRuntime #endif /* The size of the global output buffer that is available for use when there @@ -177,13 +187,6 @@ header file. */ } while (0); -/* If configTASK_RETURN_ADDRESS is not defined then a task that attempts to -return from its implementing function will end up in a "task exit error" -function - which contains a call to configASSERT(). However this can give GCC -some problems when it tries to unwind the stack, as the exit error function has -nothing to return to. To avoid this define configTASK_RETURN_ADDRESS to 0. */ -#define configTASK_RETURN_ADDRESS NULL - /****** Hardware specific settings. *******************************************/ /* @@ -193,7 +196,6 @@ nothing to return to. To avoid this define configTASK_RETURN_ADDRESS to 0. */ * be installed as the peripheral's interrupt handler. */ - #define configSETUP_TICK_INTERRUPT() \ do \ { \ @@ -209,52 +211,27 @@ nothing to return to. To avoid this define configTASK_RETURN_ADDRESS to 0. */ vClearTickInterrupt(); \ }while (0) -#define FreeRTOS_IRQ_Handler IRQHandler -#define FreeRTOS_SWI_Handler SWIHandler -#define configINTERRUPT_CONTROLLER_BASE_ADDRESS (0x71800000) +#ifdef CONFIG_TARGET_ARMV8_AARCH32 + #define FreeRTOS_IRQ_Handler IRQHandler + #define FreeRTOS_SWI_Handler SWIHandler +#endif + +#ifdef CONFIG_TARGET_ARMV8_AARCH64 + #define FreeRTOS_IRQ_Handler IRQInterruptHandler + #define FreeRTOS_SWI_Handler SynchronousInterruptHandler +#endif + +/* The following constant describe the hardware, and are correct for the +QEMU-Virt. */ +#define configINTERRUPT_CONTROLLER_BASE_ADDRESS (GICV3_DISTRIBUTOR_BASE_ADDR) #define configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET (0x2000UL) #define configUNIQUE_INTERRUPT_PRIORITIES 16 -/****** Network configuration settings - only used when the lwIP example is -built. See the page that documents this demo on the http://www.FreeRTOS.org -website for more information. ***********************************************/ - -/* The priority for the task that unblocked by the MAC interrupt to process -received packets. */ -#define configMAC_INPUT_TASK_PRIORITY (configMAX_PRIORITIES - 1) - -/* The priority of the task that runs the lwIP stack. */ -#define configLWIP_TASK_PRIORITY (configMAX_PRIORITIES - 2) - -/* The priority of the task that uses lwIP sockets to provide a simple command -line interface. */ -#define configCLI_TASK_PRIORITY (tskIDLE_PRIORITY) - -/* MAC address configuration. */ -#define configMAC_ADDR0 0x00 -#define configMAC_ADDR1 0x13 -#define configMAC_ADDR2 0x14 -#define configMAC_ADDR3 0x15 -#define configMAC_ADDR4 0x15 -#define configMAC_ADDR5 0x16 - -/* IP address configuration. */ -#define configIP_ADDR0 172 -#define configIP_ADDR1 25 -#define configIP_ADDR2 218 -#define configIP_ADDR3 200 - -/* Netmask configuration. */ -#define configNET_MASK0 255 -#define configNET_MASK1 255 -#define configNET_MASK2 255 -#define configNET_MASK3 0 - -#if !defined(__ASSEMBLER__) -void vPrintString(const char *pcString); -void vPrintStringAndNumber(const char *pcString, uint32_t ulValue); -void vPrintf(const char *format, ...); +#if !defined(__ASSEMBLER__) + void vPrintString(const char *pcString); + void vPrintStringAndNumber(const char *pcString, uint32_t ulValue); + void vPrintf(const char *format, ...); #endif #endif /* FREERTOS_CONFIG_H */ diff --git a/third-party/freertos/portable/GCC/ft_platform/aarch32/port.c b/third-party/freertos/portable/GCC/ft_platform/aarch32/port.c index 98a87b88..3b5e1c13 100644 --- a/third-party/freertos/portable/GCC/ft_platform/aarch32/port.c +++ b/third-party/freertos/portable/GCC/ft_platform/aarch32/port.c @@ -28,56 +28,56 @@ /* Standard includes. */ #include #include +#include #include "faarch32.h" - /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" #ifndef configINTERRUPT_CONTROLLER_BASE_ADDRESS -#error configINTERRUPT_CONTROLLER_BASE_ADDRESS must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html + #error configINTERRUPT_CONTROLLER_BASE_ADDRESS must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html #endif #ifndef configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET -#error configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html + #error configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html #endif #ifndef configUNIQUE_INTERRUPT_PRIORITIES -#error configUNIQUE_INTERRUPT_PRIORITIES must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html + #error configUNIQUE_INTERRUPT_PRIORITIES must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html #endif #ifndef configSETUP_TICK_INTERRUPT -#error configSETUP_TICK_INTERRUPT() must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html + #error configSETUP_TICK_INTERRUPT() must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html #endif /* configSETUP_TICK_INTERRUPT */ #ifndef configMAX_API_CALL_INTERRUPT_PRIORITY -#error configMAX_API_CALL_INTERRUPT_PRIORITY must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html + #error configMAX_API_CALL_INTERRUPT_PRIORITY must be defined. See https://www.FreeRTOS.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html #endif #if configMAX_API_CALL_INTERRUPT_PRIORITY == 0 -#error configMAX_API_CALL_INTERRUPT_PRIORITY must not be set to 0 + #error configMAX_API_CALL_INTERRUPT_PRIORITY must not be set to 0 #endif #if configMAX_API_CALL_INTERRUPT_PRIORITY > configUNIQUE_INTERRUPT_PRIORITIES -#error configMAX_API_CALL_INTERRUPT_PRIORITY must be less than or equal to configUNIQUE_INTERRUPT_PRIORITIES as the lower the numeric priority value the higher the logical interrupt priority + #error configMAX_API_CALL_INTERRUPT_PRIORITY must be less than or equal to configUNIQUE_INTERRUPT_PRIORITIES as the lower the numeric priority value the higher the logical interrupt priority #endif #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 -/* Check the configuration. */ -#if (configMAX_PRIORITIES > 32) -#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice. -#endif + /* Check the configuration. */ + #if (configMAX_PRIORITIES > 32) + #error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice. + #endif #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ /* In case security extensions are implemented. */ #if configMAX_API_CALL_INTERRUPT_PRIORITY <= (configUNIQUE_INTERRUPT_PRIORITIES / 2) -#error configMAX_API_CALL_INTERRUPT_PRIORITY must be greater than ( configUNIQUE_INTERRUPT_PRIORITIES / 2 ) + #error configMAX_API_CALL_INTERRUPT_PRIORITY must be greater than ( configUNIQUE_INTERRUPT_PRIORITIES / 2 ) #endif /* Some vendor specific files default configCLEAR_TICK_INTERRUPT() in portmacro.h. */ #ifndef configCLEAR_TICK_INTERRUPT -#define configCLEAR_TICK_INTERRUPT() + #define configCLEAR_TICK_INTERRUPT() #endif /* A critical section is exited when the critical section nesting count reaches @@ -86,7 +86,7 @@ this value. */ /* In all GICs 255 can be written to the priority mask register to unmask all (but the lowest) interrupt priority. */ -#define portUNMASK_VALUE (0xF0UL) +#define portUNMASK_VALUE (0xFFUL) /* Tasks are not created with a floating point context, but can be given a floating point context after they have been created. A variable is stored as @@ -116,26 +116,26 @@ mode. */ determined priority level. Sometimes it is necessary to turn interrupt off in the CPU itself before modifying certain hardware registers. */ #define portCPU_IRQ_DISABLE() \ - __asm volatile("CPSID i" :: \ - : "memory"); \ - __asm volatile("DSB"); \ - __asm volatile("ISB"); + __asm volatile("CPSID i" :: \ + : "memory"); \ + __asm volatile("DSB"); \ + __asm volatile("ISB"); #define portCPU_IRQ_ENABLE() \ - __asm volatile("CPSIE i" :: \ - : "memory"); \ - __asm volatile("DSB"); \ - __asm volatile("ISB"); + __asm volatile("CPSIE i" :: \ + : "memory"); \ + __asm volatile("DSB"); \ + __asm volatile("ISB"); /* Macro to unmask all interrupt priorities. */ #define portCLEAR_INTERRUPT_MASK() \ - { \ - portCPU_IRQ_DISABLE(); \ - sys_icc_pmr_set(portUNMASK_VALUE); \ - __asm volatile("DSB \n" \ - "ISB \n"); \ - portCPU_IRQ_ENABLE(); \ - } + { \ + portCPU_IRQ_DISABLE(); \ + sys_icc_pmr_set(portUNMASK_VALUE); \ + __asm volatile("DSB \n" \ + "ISB \n"); \ + portCPU_IRQ_ENABLE(); \ + } /* Hardware specifics used when sanity checking the configuration. */ #define portINTERRUPT_PRIORITY_REGISTER_OFFSET (0x400UL + 32UL) // @@ -146,9 +146,9 @@ the CPU itself before modifying certain hardware registers. */ prvTaskExitError() in case it messes up unwinding of the stack in the debugger. */ #ifdef configTASK_RETURN_ADDRESS -#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS + #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS #else -#define portTASK_RETURN_ADDRESS prvTaskExitError + #define portTASK_RETURN_ADDRESS prvTaskExitError #endif /* The space on the stack required to hold the FPU registers. This is 32 64-bit @@ -209,11 +209,13 @@ volatile uint32_t ulPortYieldRequired = pdFALSE; if the nesting depth is 0. */ volatile uint32_t ulPortInterruptNesting = 0UL; + +#define PRIORITY_TRANSLATE_SET(x) ((((x)>> 1) | 0x80) & 0xff) + +#define PRIORITY_TRANSLATE_GET(x) (((x)<< 1) & 0xff) + /* Used in the asm file. */ -// __attribute__((used)) const uint32_t ulICCIAR = portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS; -// __attribute__((used)) const uint32_t ulICCEOIR = portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS; -// __attribute__((used)) const uint32_t ulICCPMR = portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS; -__attribute__((used)) const uint32_t ulMaxAPIPriorityMask = (configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT); +__attribute__((used)) const uint32_t ulMaxAPIPriorityMask = PRIORITY_TRANSLATE_SET(configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT); /*-----------------------------------------------------------*/ @@ -222,230 +224,229 @@ __attribute__((used)) const uint32_t ulMaxAPIPriorityMask = (configMAX_API_CALL_ */ StackType_t *pxPortInitialiseStack(StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters) { - /* Setup the initial stack of the task. The stack is set exactly as - expected by the portRESTORE_CONTEXT() macro. - - The fist real value on the stack is the status register, which is set for - system mode, with interrupts enabled. A few NULLs are added first to ensure - GDB does not try decoding a non-existent return address. */ - *pxTopOfStack = (StackType_t)NULL; - pxTopOfStack--; - *pxTopOfStack = (StackType_t)NULL; - pxTopOfStack--; - *pxTopOfStack = (StackType_t)NULL; - pxTopOfStack--; - *pxTopOfStack = (StackType_t)portINITIAL_SPSR; - - if (((uint32_t)pxCode & portTHUMB_MODE_ADDRESS) != 0x00UL) - { - /* The task will start in THUMB mode. */ - *pxTopOfStack |= portTHUMB_MODE_BIT; - } - - pxTopOfStack--; - - /* Next the return address, which in this case is the start of the task. */ - *pxTopOfStack = (StackType_t)pxCode; - pxTopOfStack--; - - /* Next all the registers other than the stack pointer. */ - *pxTopOfStack = (StackType_t)portTASK_RETURN_ADDRESS; /* R14 */ - pxTopOfStack--; - *pxTopOfStack = (StackType_t)0x12121212; /* R12 */ - pxTopOfStack--; - *pxTopOfStack = (StackType_t)0x11111111; /* R11 */ - pxTopOfStack--; - *pxTopOfStack = (StackType_t)0x10101010; /* R10 */ - pxTopOfStack--; - *pxTopOfStack = (StackType_t)0x09090909; /* R9 */ - pxTopOfStack--; - *pxTopOfStack = (StackType_t)0x08080808; /* R8 */ - pxTopOfStack--; - *pxTopOfStack = (StackType_t)0x07070707; /* R7 */ - pxTopOfStack--; - *pxTopOfStack = (StackType_t)0x06060606; /* R6 */ - pxTopOfStack--; - *pxTopOfStack = (StackType_t)0x05050505; /* R5 */ - pxTopOfStack--; - *pxTopOfStack = (StackType_t)0x04040404; /* R4 */ - pxTopOfStack--; - *pxTopOfStack = (StackType_t)0x03030303; /* R3 */ - pxTopOfStack--; - *pxTopOfStack = (StackType_t)0x02020202; /* R2 */ - pxTopOfStack--; - *pxTopOfStack = (StackType_t)0x01010101; /* R1 */ - pxTopOfStack--; - *pxTopOfStack = (StackType_t)pvParameters; /* R0 */ - pxTopOfStack--; - - /* The task will start with a critical nesting count of 0 as interrupts are - enabled. */ - *pxTopOfStack = portNO_CRITICAL_NESTING; + /* Setup the initial stack of the task. The stack is set exactly as + expected by the portRESTORE_CONTEXT() macro. + The fist real value on the stack is the status register, which is set for + system mode, with interrupts enabled. A few NULLs are added first to ensure + GDB does not try decoding a non-existent return address. */ + *pxTopOfStack = (StackType_t)NULL; + pxTopOfStack--; + *pxTopOfStack = (StackType_t)NULL; + pxTopOfStack--; + *pxTopOfStack = (StackType_t)NULL; + pxTopOfStack--; + *pxTopOfStack = (StackType_t)portINITIAL_SPSR; + + if (((uint32_t)pxCode & portTHUMB_MODE_ADDRESS) != 0x00UL) + { + /* The task will start in THUMB mode. */ + *pxTopOfStack |= portTHUMB_MODE_BIT; + } + + pxTopOfStack--; + + /* Next the return address, which in this case is the start of the task. */ + *pxTopOfStack = (StackType_t)pxCode; + pxTopOfStack--; + + /* Next all the registers other than the stack pointer. */ + *pxTopOfStack = (StackType_t)portTASK_RETURN_ADDRESS; /* R14 */ + pxTopOfStack--; + *pxTopOfStack = (StackType_t)0x12121212; /* R12 */ + pxTopOfStack--; + *pxTopOfStack = (StackType_t)0x11111111; /* R11 */ + pxTopOfStack--; + *pxTopOfStack = (StackType_t)0x10101010; /* R10 */ + pxTopOfStack--; + *pxTopOfStack = (StackType_t)0x09090909; /* R9 */ + pxTopOfStack--; + *pxTopOfStack = (StackType_t)0x08080808; /* R8 */ + pxTopOfStack--; + *pxTopOfStack = (StackType_t)0x07070707; /* R7 */ + pxTopOfStack--; + *pxTopOfStack = (StackType_t)0x06060606; /* R6 */ + pxTopOfStack--; + *pxTopOfStack = (StackType_t)0x05050505; /* R5 */ + pxTopOfStack--; + *pxTopOfStack = (StackType_t)0x04040404; /* R4 */ + pxTopOfStack--; + *pxTopOfStack = (StackType_t)0x03030303; /* R3 */ + pxTopOfStack--; + *pxTopOfStack = (StackType_t)0x02020202; /* R2 */ + pxTopOfStack--; + *pxTopOfStack = (StackType_t)0x01010101; /* R1 */ + pxTopOfStack--; + *pxTopOfStack = (StackType_t)pvParameters; /* R0 */ + pxTopOfStack--; + + /* The task will start with a critical nesting count of 0 as interrupts are + enabled. */ + *pxTopOfStack = portNO_CRITICAL_NESTING; #if (configUSE_TASK_FPU_SUPPORT == 1) - { - /* The task will start without a floating point context. A task that - uses the floating point hardware must call vPortTaskUsesFPU() before - executing any floating point instructions. */ - pxTopOfStack--; - *pxTopOfStack = portNO_FLOATING_POINT_CONTEXT; - } + { + /* The task will start without a floating point context. A task that + uses the floating point hardware must call vPortTaskUsesFPU() before + executing any floating point instructions. */ + pxTopOfStack--; + *pxTopOfStack = portNO_FLOATING_POINT_CONTEXT; + } #elif (configUSE_TASK_FPU_SUPPORT == 2) - { - /* The task will start with a floating point context. Leave enough - space for the registers - and ensure they are initialised to 0. */ - pxTopOfStack -= portFPU_REGISTER_WORDS; - memset(pxTopOfStack, 0x00, portFPU_REGISTER_WORDS * sizeof(StackType_t)); - - pxTopOfStack--; - *pxTopOfStack = pdTRUE; - ulPortTaskHasFPUContext = pdTRUE; - } + { + /* The task will start with a floating point context. Leave enough + space for the registers - and ensure they are initialised to 0. */ + pxTopOfStack -= portFPU_REGISTER_WORDS; + memset(pxTopOfStack, 0x00, portFPU_REGISTER_WORDS * sizeof(StackType_t)); + + pxTopOfStack--; + *pxTopOfStack = pdTRUE; + ulPortTaskHasFPUContext = pdTRUE; + } #else - { + { #error Invalid configUSE_TASK_FPU_SUPPORT setting - configUSE_TASK_FPU_SUPPORT must be set to 1, 2, or left undefined. - } + } #endif - return pxTopOfStack; + return pxTopOfStack; } /*-----------------------------------------------------------*/ static void prvTaskExitError(void) { - /* A function that implements a task must not exit or attempt to return to - its caller as there is nothing to return to. If a task wants to exit it - should instead call vTaskDelete( NULL ). - - Artificially force an assert() to be triggered if configASSERT() is - defined, then stop here so application writers can catch the error. */ - configASSERT(ulPortInterruptNesting == ~0UL); - portDISABLE_INTERRUPTS(); - for (;;) - ; + /* A function that implements a task must not exit or attempt to return to + its caller as there is nothing to return to. If a task wants to exit it + should instead call vTaskDelete( NULL ). + + Artificially force an assert() to be triggered if configASSERT() is + defined, then stop here so application writers can catch the error. */ + configASSERT(ulPortInterruptNesting == ~0UL); + portDISABLE_INTERRUPTS(); + for (;;) + ; } /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler(void) { - uint32_t ulAPSR; - - /* Only continue if the CPU is not in User mode. The CPU must be in a - Privileged mode for the scheduler to start. */ - __asm volatile("MRS %0, APSR" - : "=r"(ulAPSR)::"memory"); - - ulAPSR &= portAPSR_MODE_BITS_MASK; - - configASSERT(ulAPSR != portAPSR_USER_MODE); - - if (ulAPSR != portAPSR_USER_MODE) - { - /* Only continue if the binary point value is set to its lowest possible - setting. See the comments in vPortValidateInterruptPriority() below for - more information. */ - - configASSERT((sys_icc_bpr_get() & portBINARY_POINT_BITS) <= portMAX_BINARY_POINT_VALUE); - - if ((sys_icc_bpr_get() & portBINARY_POINT_BITS) <= portMAX_BINARY_POINT_VALUE) - { - /* Interrupts are turned off in the CPU itself to ensure tick does - not execute while the scheduler is being started. Interrupts are - automatically turned back on in the CPU when the first task starts - executing. */ - portCPU_IRQ_DISABLE(); - - /* Start the timer that generates the tick ISR. */ - configSETUP_TICK_INTERRUPT(); - - /* Start the first task executing. */ - vPortRestoreTaskContext(); - } - } - - /* Will only get here if vTaskStartScheduler() was called with the CPU in - a non-privileged mode or the binary point register was not set to its lowest - possible value. prvTaskExitError() is referenced to prevent a compiler - warning about it being defined but not referenced in the case that the user - defines their own exit address. */ - (void)prvTaskExitError; - return 0; + uint32_t ulAPSR; + + /* Only continue if the CPU is not in User mode. The CPU must be in a + Privileged mode for the scheduler to start. */ + __asm volatile("MRS %0, APSR" + : "=r"(ulAPSR)::"memory"); + + ulAPSR &= portAPSR_MODE_BITS_MASK; + + configASSERT(ulAPSR != portAPSR_USER_MODE); + + if (ulAPSR != portAPSR_USER_MODE) + { + /* Only continue if the binary point value is set to its lowest possible + setting. See the comments in vPortValidateInterruptPriority() below for + more information. */ + + configASSERT((sys_icc_bpr_get() & portBINARY_POINT_BITS) <= portMAX_BINARY_POINT_VALUE); + + if ((sys_icc_bpr_get() & portBINARY_POINT_BITS) <= portMAX_BINARY_POINT_VALUE) + { + /* Interrupts are turned off in the CPU itself to ensure tick does + not execute while the scheduler is being started. Interrupts are + automatically turned back on in the CPU when the first task starts + executing. */ + portCPU_IRQ_DISABLE(); + + /* Start the timer that generates the tick ISR. */ + configSETUP_TICK_INTERRUPT(); + + /* Start the first task executing. */ + vPortRestoreTaskContext(); + } + } + + /* Will only get here if vTaskStartScheduler() was called with the CPU in + a non-privileged mode or the binary point register was not set to its lowest + possible value. prvTaskExitError() is referenced to prevent a compiler + warning about it being defined but not referenced in the case that the user + defines their own exit address. */ + (void)prvTaskExitError; + return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler(void) { - /* Not implemented in ports where there is nothing to return to. - Artificially force an assert. */ - configASSERT(ulCriticalNesting == 1000UL); + /* Not implemented in ports where there is nothing to return to. + Artificially force an assert. */ + configASSERT(ulCriticalNesting == 1000UL); } /*-----------------------------------------------------------*/ void vPortEnterCritical(void) { - /* Mask interrupts up to the max syscall interrupt priority. */ - ulPortSetInterruptMask(); - - /* Now interrupts are disabled ulCriticalNesting can be accessed - directly. Increment ulCriticalNesting to keep a count of how many times - portENTER_CRITICAL() has been called. */ - ulCriticalNesting++; - - /* This is not the interrupt safe version of the enter critical function so - assert() if it is being called from an interrupt context. Only API - functions that end in "FromISR" can be used in an interrupt. Only assert if - the critical nesting count is 1 to protect against recursive calls if the - assert function also uses a critical section. */ - if (ulCriticalNesting == 1) - { - configASSERT(ulPortInterruptNesting == 0); - } + /* Mask interrupts up to the max syscall interrupt priority. */ + ulPortSetInterruptMask(); + + /* Now interrupts are disabled ulCriticalNesting can be accessed + directly. Increment ulCriticalNesting to keep a count of how many times + portENTER_CRITICAL() has been called. */ + ulCriticalNesting++; + + /* This is not the interrupt safe version of the enter critical function so + assert() if it is being called from an interrupt context. Only API + functions that end in "FromISR" can be used in an interrupt. Only assert if + the critical nesting count is 1 to protect against recursive calls if the + assert function also uses a critical section. */ + if (ulCriticalNesting == 1) + { + configASSERT(ulPortInterruptNesting == 0); + } } /*-----------------------------------------------------------*/ void vPortExitCritical(void) { - if (ulCriticalNesting > portNO_CRITICAL_NESTING) - { - /* Decrement the nesting count as the critical section is being - exited. */ - ulCriticalNesting--; - - /* If the nesting level has reached zero then all interrupt - priorities must be re-enabled. */ - if (ulCriticalNesting == portNO_CRITICAL_NESTING) - { - /* Critical nesting has reached zero so all interrupt priorities - should be unmasked. */ - portCLEAR_INTERRUPT_MASK(); - } - } + if (ulCriticalNesting > portNO_CRITICAL_NESTING) + { + /* Decrement the nesting count as the critical section is being + exited. */ + ulCriticalNesting--; + + /* If the nesting level has reached zero then all interrupt + priorities must be re-enabled. */ + if (ulCriticalNesting == portNO_CRITICAL_NESTING) + { + /* Critical nesting has reached zero so all interrupt priorities + should be unmasked. */ + portCLEAR_INTERRUPT_MASK(); + } + } } /*-----------------------------------------------------------*/ void FreeRTOS_Tick_Handler(void) { - /* Set interrupt mask before altering scheduler structures. The tick - handler runs at the lowest priority, so interrupts cannot already be masked, - so there is no need to save and restore the current mask value. It is - necessary to turn off interrupts in the CPU itself while the ICCPMR is being - updated. */ - portCPU_IRQ_DISABLE(); - sys_icc_pmr_set((uint32_t)(configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT)); - // portICCPMR_PRIORITY_MASK_REGISTER = (uint32_t)(configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT); - __asm volatile("dsb \n" - "isb \n" :: - : "memory"); - portCPU_IRQ_ENABLE(); - /* Increment the RTOS tick. */ - if (xTaskIncrementTick() != pdFALSE) - { - ulPortYieldRequired = pdTRUE; - } - - /* Ensure all interrupt priorities are active again. */ - portCLEAR_INTERRUPT_MASK(); - configCLEAR_TICK_INTERRUPT(); + /* Set interrupt mask before altering scheduler structures. The tick + handler runs at the lowest priority, so interrupts cannot already be masked, + so there is no need to save and restore the current mask value. It is + necessary to turn off interrupts in the CPU itself while the ICCPMR is being + updated. */ + portCPU_IRQ_DISABLE(); + sys_icc_pmr_set((uint32_t)(configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT)); + // portICCPMR_PRIORITY_MASK_REGISTER = (uint32_t)(configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT); + __asm volatile("dsb \n" + "isb \n" :: + : "memory"); + portCPU_IRQ_ENABLE(); + /* Increment the RTOS tick. */ + if (xTaskIncrementTick() != pdFALSE) + { + ulPortYieldRequired = pdTRUE; + } + + /* Ensure all interrupt priorities are active again. */ + portCLEAR_INTERRUPT_MASK(); + configCLEAR_TICK_INTERRUPT(); } /*-----------------------------------------------------------*/ @@ -453,15 +454,15 @@ void FreeRTOS_Tick_Handler(void) void vPortTaskUsesFPU(void) { - uint32_t ulInitialFPSCR = 0; + uint32_t ulInitialFPSCR = 0; - /* A task is registering the fact that it needs an FPU context. Set the - FPU flag (which is saved as part of the task context). */ - ulPortTaskHasFPUContext = pdTRUE; + /* A task is registering the fact that it needs an FPU context. Set the + FPU flag (which is saved as part of the task context). */ + ulPortTaskHasFPUContext = pdTRUE; - /* Initialise the floating point status register. */ - __asm volatile("FMXR FPSCR, %0" ::"r"(ulInitialFPSCR) - : "memory"); + /* Initialise the floating point status register. */ + __asm volatile("FMXR FPSCR, %0" ::"r"(ulInitialFPSCR) + : "memory"); } #endif /* configUSE_TASK_FPU_SUPPORT */ @@ -469,37 +470,61 @@ void vPortTaskUsesFPU(void) void vPortClearInterruptMask(uint32_t ulNewMaskValue) { - if (ulNewMaskValue == pdFALSE) - { - portCLEAR_INTERRUPT_MASK(); - } + if (ulNewMaskValue == pdFALSE) + { + portCLEAR_INTERRUPT_MASK(); + } } /*-----------------------------------------------------------*/ +/*-----------------------------------------------------------*/ +/* +Set current interrupt priority mask and translate, ICC_PMR +• The value is right-shifted by one bit. +• Bit [7] of the value is set to 1. +*/ +void vPortSetPriorityMask(uint32_t value) +{ + uint32_t priority = PRIORITY_TRANSLATE_SET(value); + sys_icc_pmr_set(priority); +} + +/* Get current interrupt priority mask and translate, ICC_PMR, priority << portPRIORITY_SHIFT */ +uint32_t vPortGetPriorityMask(void) +{ + return PRIORITY_TRANSLATE_GET(sys_icc_pmr_get()); +} + +/* Get current interrupt priority and translate, ICC_RPR, priority << portPRIORITY_SHIFT */ +uint32_t vPortGetCurrentPriority(void) +{ + return PRIORITY_TRANSLATE_GET(sys_icc_rpr_get()); +} + + + uint32_t ulPortSetInterruptMask(void) { - uint32_t ulReturn; - - /* Interrupt in the CPU must be turned off while the ICCPMR is being - updated. */ - portCPU_IRQ_DISABLE(); - if (sys_icc_pmr_get() == (uint32_t)(configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT)) - { - /* Interrupts were already masked. */ - ulReturn = pdTRUE; - } - else - { - ulReturn = pdFALSE; - sys_icc_pmr_set((uint32_t)(configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT)); - // portICCPMR_PRIORITY_MASK_REGISTER = (uint32_t)(configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT); - __asm volatile("dsb \n" - "isb \n" :: - : "memory"); - } - portCPU_IRQ_ENABLE(); - - return ulReturn; + uint32_t ulReturn; + + /* Interrupt in the CPU must be turned off while the ICCPMR is being + updated. */ + portCPU_IRQ_DISABLE(); + if (vPortGetPriorityMask() == (uint32_t)(configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT)) + { + /* Interrupts were already masked. */ + ulReturn = pdTRUE; + } + else + { + ulReturn = pdFALSE; + vPortSetPriorityMask((uint32_t)(configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT)); + __asm volatile("dsb \n" + "isb \n" :: + : "memory"); + } + portCPU_IRQ_ENABLE(); + return ulReturn; } /*-----------------------------------------------------------*/ @@ -507,33 +532,33 @@ uint32_t ulPortSetInterruptMask(void) void vPortValidateInterruptPriority(void) { - /* The following assertion will fail if a service routine (ISR) for - an interrupt that has been assigned a priority above - configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API - function. ISR safe FreeRTOS API functions must *only* be called - from interrupts that have been assigned a priority at or below - configMAX_SYSCALL_INTERRUPT_PRIORITY. - - Numerically low interrupt priority numbers represent logically high - interrupt priorities, therefore the priority of the interrupt must - be set to a value equal to or numerically *higher* than - configMAX_SYSCALL_INTERRUPT_PRIORITY. - - FreeRTOS maintains separate thread and ISR API functions to ensure - interrupt entry is as fast and simple as possible. */ - configASSERT(sys_icc_rpr_get() >= (uint32_t)(configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT)); - - /* Priority grouping: The interrupt controller (GIC) allows the bits - that define each interrupt's priority to be split between bits that - define the interrupt's pre-emption priority bits and bits that define - the interrupt's sub-priority. For simplicity all bits must be defined - to be pre-emption priority bits. The following assertion will fail if - this is not the case (if some bits represent a sub-priority). - - The priority grouping is configured by the GIC's binary point register - (ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest - possible value (which may be above 0). */ - configASSERT((sys_icc_bpr_get() & portBINARY_POINT_BITS) <= portMAX_BINARY_POINT_VALUE); + /* The following assertion will fail if a service routine (ISR) for + an interrupt that has been assigned a priority above + configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API + function. ISR safe FreeRTOS API functions must *only* be called + from interrupts that have been assigned a priority at or below + configMAX_SYSCALL_INTERRUPT_PRIORITY. + + Numerically low interrupt priority numbers represent logically high + interrupt priorities, therefore the priority of the interrupt must + be set to a value equal to or numerically *higher* than + configMAX_SYSCALL_INTERRUPT_PRIORITY. + + FreeRTOS maintains separate thread and ISR API functions to ensure + interrupt entry is as fast and simple as possible. */ + configASSERT(vPortGetCurrentPriority() >= (uint32_t)(configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT)); + + /* Priority grouping: The interrupt controller (GIC) allows the bits + that define each interrupt's priority to be split between bits that + define the interrupt's pre-emption priority bits and bits that define + the interrupt's sub-priority. For simplicity all bits must be defined + to be pre-emption priority bits. The following assertion will fail if + this is not the case (if some bits represent a sub-priority). + + The priority grouping is configured by the GIC's binary point register + (ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest + possible value (which may be above 0). */ + configASSERT((sys_icc_bpr_get() & portBINARY_POINT_BITS) <= portMAX_BINARY_POINT_VALUE); } #endif /* configASSERT_DEFINED */ diff --git a/third-party/freertos/portable/GCC/ft_platform/aarch32/portASM.S b/third-party/freertos/portable/GCC/ft_platform/aarch32/portASM.S index 9ecf83e4..77bf3a9e 100644 --- a/third-party/freertos/portable/GCC/ft_platform/aarch32/portASM.S +++ b/third-party/freertos/portable/GCC/ft_platform/aarch32/portASM.S @@ -73,6 +73,7 @@ FMRXNE R1, FPSCR VPUSHNE {D0-D15} VPUSHNE {D16-D31} + PUSHNE {R1} diff --git a/third-party/freertos/portable/GCC/ft_platform/aarch32/portmacro.h b/third-party/freertos/portable/GCC/ft_platform/aarch32/portmacro.h index bbf98f73..2af406a2 100644 --- a/third-party/freertos/portable/GCC/ft_platform/aarch32/portmacro.h +++ b/third-party/freertos/portable/GCC/ft_platform/aarch32/portmacro.h @@ -52,11 +52,11 @@ extern "C" #define portSTACK_TYPE uint32_t #define portBASE_TYPE long - typedef portSTACK_TYPE StackType_t; - typedef long BaseType_t; - typedef unsigned long UBaseType_t; +typedef portSTACK_TYPE StackType_t; +typedef long BaseType_t; +typedef unsigned long UBaseType_t; - typedef uint32_t TickType_t; +typedef uint32_t TickType_t; #define portMAX_DELAY (TickType_t)0xffffffffUL /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do @@ -76,28 +76,28 @@ not need to be guarded with a critical section. */ /* Called at the end of an ISR that can cause a context switch. */ #define portEND_SWITCHING_ISR(xSwitchRequired) \ - { \ - extern uint32_t ulPortYieldRequired; \ + { \ + extern uint32_t ulPortYieldRequired; \ \ - if (xSwitchRequired != pdFALSE) \ - { \ - ulPortYieldRequired = pdTRUE; \ - } \ - } + if (xSwitchRequired != pdFALSE) \ + { \ + ulPortYieldRequired = pdTRUE; \ + } \ + } #define portYIELD_FROM_ISR(x) portEND_SWITCHING_ISR(x) #define portYIELD() __asm volatile("SWI 0" :: \ - : "memory"); + : "memory"); - /*----------------------------------------------------------- - * Critical section control - *----------------------------------------------------------*/ +/*----------------------------------------------------------- +* Critical section control +*----------------------------------------------------------*/ - extern void vPortEnterCritical(void); - extern void vPortExitCritical(void); - extern uint32_t ulPortSetInterruptMask(void); - extern void vPortClearInterruptMask(uint32_t ulNewMaskValue); - extern void vPortInstallFreeRTOSVectorTable(void); +extern void vPortEnterCritical(void); +extern void vPortExitCritical(void); +extern uint32_t ulPortSetInterruptMask(void); +extern void vPortClearInterruptMask(uint32_t ulNewMaskValue); +extern void vPortInstallFreeRTOSVectorTable(void); /* These macros do not globally disable/enable interrupts. They do mask off interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */ @@ -105,8 +105,6 @@ interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */ #define portEXIT_CRITICAL() vPortExitCritical(); #define portDISABLE_INTERRUPTS() ulPortSetInterruptMask() #define portENABLE_INTERRUPTS() vPortClearInterruptMask(0) -#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask() -#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x) /*-----------------------------------------------------------*/ @@ -116,9 +114,9 @@ macros is used. */ #define portTASK_FUNCTION_PROTO(vFunction, pvParameters) void vFunction(void *pvParameters) #define portTASK_FUNCTION(vFunction, pvParameters) void vFunction(void *pvParameters) - /* Prototype of the FreeRTOS tick handler. This must be installed as the +/* Prototype of the FreeRTOS tick handler. This must be installed as the handler for whichever peripheral is used to generate the RTOS tick. */ - void FreeRTOS_Tick_Handler(void); +void FreeRTOS_Tick_Handler(void); /* If configUSE_TASK_FPU_SUPPORT is set to 1 (or left undefined) then tasks are created without an FPU context and must call vPortTaskUsesFPU() to give @@ -126,10 +124,10 @@ themselves an FPU context before using any FPU instructions. If configUSE_TASK_FPU_SUPPORT is set to 2 then all tasks will have an FPU context by default. */ #if (configUSE_TASK_FPU_SUPPORT != 2) - void vPortTaskUsesFPU(void); +void vPortTaskUsesFPU(void); #else /* Each task has an FPU context already, so define this function away to - nothing to prevent it being called accidentally. */ + nothing to prevent it being called accidentally. */ #define vPortTaskUsesFPU() #endif #define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU() @@ -148,14 +146,14 @@ by default. */ #define portRECORD_READY_PRIORITY(uxPriority, uxReadyPriorities) (uxReadyPriorities) |= (1UL << (uxPriority)) #define portRESET_READY_PRIORITY(uxPriority, uxReadyPriorities) (uxReadyPriorities) &= ~(1UL << (uxPriority)) - /*-----------------------------------------------------------*/ +/*-----------------------------------------------------------*/ #define portGET_HIGHEST_PRIORITY(uxTopPriority, uxReadyPriorities) uxTopPriority = (31UL - (uint32_t)__builtin_clz(uxReadyPriorities)) #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ #ifdef configASSERT - void vPortValidateInterruptPriority(void); +void vPortValidateInterruptPriority(void); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif /* configASSERT */ @@ -169,22 +167,22 @@ by default. */ /* The number of bits to shift for an interrupt priority is dependent on the number of bits implemented by the interrupt controller. */ #if configUNIQUE_INTERRUPT_PRIORITIES == 16 -#define portPRIORITY_SHIFT 4 -#define portMAX_BINARY_POINT_VALUE 3 + #define portPRIORITY_SHIFT 4 + #define portMAX_BINARY_POINT_VALUE 3 #elif configUNIQUE_INTERRUPT_PRIORITIES == 32 -#define portPRIORITY_SHIFT 3 -#define portMAX_BINARY_POINT_VALUE 2 + #define portPRIORITY_SHIFT 3 + #define portMAX_BINARY_POINT_VALUE 2 #elif configUNIQUE_INTERRUPT_PRIORITIES == 64 -#define portPRIORITY_SHIFT 2 -#define portMAX_BINARY_POINT_VALUE 1 + #define portPRIORITY_SHIFT 2 + #define portMAX_BINARY_POINT_VALUE 1 #elif configUNIQUE_INTERRUPT_PRIORITIES == 128 -#define portPRIORITY_SHIFT 1 -#define portMAX_BINARY_POINT_VALUE 0 + #define portPRIORITY_SHIFT 1 + #define portMAX_BINARY_POINT_VALUE 0 #elif configUNIQUE_INTERRUPT_PRIORITIES == 256 -#define portPRIORITY_SHIFT 0 -#define portMAX_BINARY_POINT_VALUE 0 + #define portPRIORITY_SHIFT 0 + #define portMAX_BINARY_POINT_VALUE 0 #else -#error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware + #error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware #endif /* Interrupt controller access addresses. */ @@ -196,6 +194,6 @@ number of bits implemented by the interrupt controller. */ #define portMEMORY_BARRIER() __asm volatile("" :: \ - : "memory") + : "memory") #endif /* PORTMACRO_H */ diff --git a/third-party/freertos/portable/GCC/ft_platform/aarch64/FreeRTOSConfig.h b/third-party/freertos/portable/GCC/ft_platform/aarch64/FreeRTOSConfig.h deleted file mode 100644 index 594e8dd2..00000000 --- a/third-party/freertos/portable/GCC/ft_platform/aarch64/FreeRTOSConfig.h +++ /dev/null @@ -1,201 +0,0 @@ -/* - * FreeRTOS Kernel V10.0.1 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://www.FreeRTOS.org - * http://aws.amazon.com/freertos - * - * 1 tab == 4 spaces! - */ - -#ifndef FREERTOS_CONFIG_H -#define FREERTOS_CONFIG_H - -#include "finterrupt.h" - -/*----------------------------------------------------------- - * Application specific definitions. - * - * These definitions should be adjusted for your particular hardware and - * application requirements. - * - * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE - * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. - * - * See http://www.freertos.org/a00110.html. - *----------------------------------------------------------*/ - -/* - * The FreeRTOS Cortex-A port implements a full interrupt nesting model. - * - * Interrupts that are assigned a priority at or below - * configMAX_API_CALL_INTERRUPT_PRIORITY (which counter-intuitively in the ARM - * generic interrupt controller [GIC] means a priority that has a numerical - * value above configMAX_API_CALL_INTERRUPT_PRIORITY) can call FreeRTOS safe API - * functions and will nest. - * - * Interrupts that are assigned a priority above - * configMAX_API_CALL_INTERRUPT_PRIORITY (which in the GIC means a numerical - * value below configMAX_API_CALL_INTERRUPT_PRIORITY) cannot call any FreeRTOS - * API functions, will nest, and will not be masked by FreeRTOS critical - * sections (although it is necessary for interrupts to be globally disabled - * extremely briefly as the interrupt mask is updated in the GIC). - * - * FreeRTOS functions that can be called from an interrupt are those that end in - * "FromISR". FreeRTOS maintains a separate interrupt safe API to enable - * interrupt entry to be shorter, faster, simpler and smaller. - * - * For the purpose of setting configMAX_API_CALL_INTERRUPT_PRIORITY 255 - * represents the lowest priority. - */ - -/* 在不安全group1 中,16 is steps ,3 是其中等级*/ -#define configKERNEL_INTERRUPT_PRIORITY IRQ_PRIORITY_VALUE_11 -/* 在不安全group1 中 ,0x8 ~0xb 不可以使用安全api(优先级越低越高)*/ -#define configMAX_API_CALL_INTERRUPT_PRIORITY IRQ_PRIORITY_VALUE_11 - - -#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 -#define configUSE_TICKLESS_IDLE 0 -#define configTICK_RATE_HZ ((TickType_t)1000) -#define configUSE_PREEMPTION 1 -#define configUSE_IDLE_HOOK 1 -#define configUSE_TICK_HOOK 1 -#define configMAX_PRIORITIES (8) -#define configMINIMAL_STACK_SIZE ((unsigned short)1024) -#define configTOTAL_HEAP_SIZE (1024 * 1024 * 12) -#define configMAX_TASK_NAME_LEN (32) -#define configUSE_16_BIT_TICKS 0 -#define configIDLE_SHOULD_YIELD 1 -#define configUSE_MUTEXES 1 -#define configQUEUE_REGISTRY_SIZE 8 -#define configCHECK_FOR_STACK_OVERFLOW 1 -#define configUSE_RECURSIVE_MUTEXES 1 -#define configUSE_APPLICATION_TASK_TAG 0 -#define configUSE_COUNTING_SEMAPHORES 1 -#define configUSE_QUEUE_SETS 1 - -/* This demo creates RTOS objects using both static and dynamic allocation. */ -#define configSUPPORT_STATIC_ALLOCATION 1 -#define configSUPPORT_DYNAMIC_ALLOCATION 1 /* Defaults to 1 anyway. */ - -/* Co-routine definitions. */ -#define configUSE_CO_ROUTINES 0 -#define configMAX_CO_ROUTINE_PRIORITIES (2) - -/* Software timer definitions. */ -#define configUSE_TIMERS 1 -#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES - 1) -#define configTIMER_QUEUE_LENGTH 5 -#define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE * 2) - -/* Set the following definitions to 1 to include the API function, or zero -to exclude the API function. */ -#define INCLUDE_vTaskPrioritySet 1 -#define INCLUDE_uxTaskPriorityGet 1 -#define INCLUDE_vTaskDelete 1 -#define INCLUDE_vTaskCleanUpResources 1 -#define INCLUDE_vTaskSuspend 1 -#define INCLUDE_vTaskDelayUntil 1 -#define INCLUDE_vTaskDelay 1 -#define INCLUDE_xTimerPendFunctionCall 1 -#define INCLUDE_eTaskGetState 1 -#define INCLUDE_xTaskAbortDelay 1 -#define INCLUDE_xTaskGetHandle 1 - -#define INCLUDE_xSemaphoreGetMutexHolder 1 -#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5 -#define INCLUDE_xTaskGetIdleTaskHandle 1 - -/* This demo makes use of one or more example stats formatting functions. These -format the raw data provided by the uxTaskGetSystemState() function in to human -readable ASCII form. See the notes in the implementation of vTaskList() within -FreeRTOS/Source/tasks.c for limitations. */ -#define configUSE_STATS_FORMATTING_FUNCTIONS 1 - -/* Run time stats are not generated. portCONFIGURE_TIMER_FOR_RUN_TIME_STATS and -portGET_RUN_TIME_COUNTER_VALUE must be defined if configGENERATE_RUN_TIME_STATS -is set to 1. */ -#define configGENERATE_RUN_TIME_STATS 1 //启用运行时间统计功能 -extern volatile unsigned int gCpuRuntime; -#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() (gCpuRuntime = 0ul) -#define portGET_RUN_TIME_COUNTER_VALUE() gCpuRuntime - -/* The size of the global output buffer that is available for use when there -are multiple command interpreters running at once (for example, one on a UART -and one on TCP/IP). This is done to prevent an output buffer being defined by -each implementation - which would waste RAM. In this case, there is only one -command interpreter running. */ -#define configCOMMAND_INT_MAX_OUTPUT_SIZE 2096 - -/* Normal assert() semantics without relying on the provision of an assert.h -header file. */ -void vMainAssertCalled(const char *pcFileName, uint32_t ulLineNumber); -#define configASSERT(x) \ - if ((x) == 0) \ - { \ - vMainAssertCalled(__FILE__, __LINE__); \ - } - -/* If configTASK_RETURN_ADDRESS is not defined then a task that attempts to -return from its implementing function will end up in a "task exit error" -function - which contains a call to configASSERT(). However this can give GCC -some problems when it tries to unwind the stack, as the exit error function has -nothing to return to. To avoid this define configTASK_RETURN_ADDRESS to 0. */ -#define configTASK_RETURN_ADDRESS NULL - -/* Bump up the priority of recmuCONTROLLING_TASK_PRIORITY to prevent false -positive errors being reported considering the priority of other tasks in the -system. */ -#define recmuCONTROLLING_TASK_PRIORITY (configMAX_PRIORITIES - 2) - -/****** Hardware specific settings. *******************************************/ - -/* - * The application must provide a function that configures a peripheral to - * create the FreeRTOS tick interrupt, then define configSETUP_TICK_INTERRUPT() - * in FreeRTOSConfig.h to call the function. This file contains a function - * that is suitable for use on the Zynq MPU. FreeRTOS_Tick_Handler() must - * be installed as the peripheral's interrupt handler. - */ -void vConfigureTickInterrupt(void); -#define configSETUP_TICK_INTERRUPT() vConfigureTickInterrupt() - -void vClearTickInterrupt(void); -#define configCLEAR_TICK_INTERRUPT() vClearTickInterrupt() - -/* The following constant describe the hardware, and are correct for the -QEMU-Virt. */ -#define configINTERRUPT_CONTROLLER_BASE_ADDRESS (GICV3_DISTRIBUTOR_BASEADDRESS) -#define configUNIQUE_INTERRUPT_PRIORITIES 16 - -#define fabs(x) __builtin_fabs(x) - -#define configUSE_TRACE_FACILITY 1 - - -#define FreeRTOS_IRQ_Handler IRQInterruptHandler -#define FreeRTOS_SWI_Handler SynchronousInterruptHandler - -void vPrintString(const char *pcString); -void vPrintStringAndNumber(const char *pcString, uint32_t ulValue); -void vPrintf(const char *format, ...); - -#endif /* FREERTOS_CONFIG_H */ diff --git a/third-party/freertos/portable/GCC/ft_platform/aarch64/port.c b/third-party/freertos/portable/GCC/ft_platform/aarch64/port.c index a3371d43..30d55b89 100644 --- a/third-party/freertos/portable/GCC/ft_platform/aarch64/port.c +++ b/third-party/freertos/portable/GCC/ft_platform/aarch64/port.c @@ -28,6 +28,7 @@ /* Standard includes. */ #include #include +#include /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" @@ -35,41 +36,41 @@ #include "finterrupt.h" #include "fgic_cpu_interface.h" #ifndef configUNIQUE_INTERRUPT_PRIORITIES -#error configUNIQUE_INTERRUPT_PRIORITIES must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html + #error configUNIQUE_INTERRUPT_PRIORITIES must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html #endif #ifndef configSETUP_TICK_INTERRUPT -#error configSETUP_TICK_INTERRUPT() must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html + #error configSETUP_TICK_INTERRUPT() must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html #endif /* configSETUP_TICK_INTERRUPT */ #ifndef configMAX_API_CALL_INTERRUPT_PRIORITY -#error configMAX_API_CALL_INTERRUPT_PRIORITY must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html + #error configMAX_API_CALL_INTERRUPT_PRIORITY must be defined. See http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html #endif #if configMAX_API_CALL_INTERRUPT_PRIORITY == 0 -#error configMAX_API_CALL_INTERRUPT_PRIORITY must not be set to 0 + #error configMAX_API_CALL_INTERRUPT_PRIORITY must not be set to 0 #endif #if configMAX_API_CALL_INTERRUPT_PRIORITY > configUNIQUE_INTERRUPT_PRIORITIES -#error configMAX_API_CALL_INTERRUPT_PRIORITY must be less than or equal to configUNIQUE_INTERRUPT_PRIORITIES as the lower the numeric priority value the higher the logical interrupt priority + #error configMAX_API_CALL_INTERRUPT_PRIORITY must be less than or equal to configUNIQUE_INTERRUPT_PRIORITIES as the lower the numeric priority value the higher the logical interrupt priority #endif #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 -/* Check the configuration. */ -#if (configMAX_PRIORITIES > 32) -#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice. -#endif + /* Check the configuration. */ + #if (configMAX_PRIORITIES > 32) + #error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice. + #endif #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ /* In case security extensions are implemented. */ #if configMAX_API_CALL_INTERRUPT_PRIORITY <= (configUNIQUE_INTERRUPT_PRIORITIES / 2) -#error configMAX_API_CALL_INTERRUPT_PRIORITY must be greater than ( configUNIQUE_INTERRUPT_PRIORITIES / 2 ) + #error configMAX_API_CALL_INTERRUPT_PRIORITY must be greater than ( configUNIQUE_INTERRUPT_PRIORITIES / 2 ) #endif /* Some vendor specific files default configCLEAR_TICK_INTERRUPT() in portmacro.h. */ #ifndef configCLEAR_TICK_INTERRUPT -#define configCLEAR_TICK_INTERRUPT() + #define configCLEAR_TICK_INTERRUPT() #endif /* A critical section is exited when the critical section nesting count reaches @@ -78,7 +79,7 @@ this value. */ /* In all GICs 255 can be written to the priority mask register to unmask all (but the lowest) interrupt priority. */ -#define portUNMASK_VALUE (0xF0UL) +#define portUNMASK_VALUE (0xFFUL) /* Tasks are not created with a floating point context, but can be given a floating point context after they have been created. A variable is stored as @@ -92,12 +93,12 @@ context. */ #define portSP_EL0 ((StackType_t)0x00) #if defined(GUEST) -#define portEL1 ((StackType_t)0x04) -#define portINITIAL_PSTATE (portEL1 | portSP_EL0) + #define portEL1 ((StackType_t)0x04) + #define portINITIAL_PSTATE (portEL1 | portSP_EL0) #else -#define portEL3 ((StackType_t)0x0c) -/* At the time of writing, the BSP only supports EL3. */ -#define portINITIAL_PSTATE (portEL3 | portSP_EL0) + #define portEL3 ((StackType_t)0x0c) + /* At the time of writing, the BSP only supports EL3. */ + #define portINITIAL_PSTATE (portEL3 | portSP_EL0) #endif /* Used by portASSERT_IF_INTERRUPT_PRIORITY_INVALID() when ensuring the binary @@ -112,13 +113,13 @@ point is zero. */ /* Macro to unmask all interrupt priorities. */ #define portCLEAR_INTERRUPT_MASK() \ - { \ - portDISABLE_INTERRUPTS(); \ - InterruptSetPriorityMask(portUNMASK_VALUE); \ - __asm volatile("DSB SY \n" \ - "ISB SY \n"); \ - portENABLE_INTERRUPTS(); \ - } + { \ + portDISABLE_INTERRUPTS(); \ + InterruptSetPriorityMask(portUNMASK_VALUE); \ + __asm volatile("DSB SY \n" \ + "ISB SY \n"); \ + portENABLE_INTERRUPTS(); \ + } /* Hardware specifics used when sanity checking the configuration. */ #define portINTERRUPT_PRIORITY_REGISTER_OFFSET (0x400UL + 32UL) // @@ -153,8 +154,16 @@ uint64_t ullPortYieldRequired = pdFALSE; if the nesting depth is 0. */ uint64_t ullPortInterruptNesting = pdFALSE; +/* The space on the stack required to hold the FPU registers. This is 32 128-bit + * registers, that means (64 * 8) 64 double words */ +#define portFPU_REGISTER_DOUBLE_WORDS ( 64 ) + +#define PRIORITY_TRANSLATE_SET(x) ((((x)>> 1) | 0x80) & 0xff) + +#define PRIORITY_TRANSLATE_GET(x) (((x)<< 1) & 0xff) + /* Used in the ASM code. */ -__attribute__((used)) const uint64_t ullMaxAPIPriorityMask = (configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT); +__attribute__((used)) const uint64_t ullMaxAPIPriorityMask = PRIORITY_TRANSLATE_SET(configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT); /*-----------------------------------------------------------*/ @@ -163,308 +172,350 @@ __attribute__((used)) const uint64_t ullMaxAPIPriorityMask = (configMAX_API_CALL */ StackType_t *pxPortInitialiseStack(StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters) { - /* Setup the initial stack of the task. The stack is set exactly as - expected by the portRESTORE_CONTEXT() macro. */ - - /* First all the general purpose registers. */ - pxTopOfStack--; - *pxTopOfStack = 0x0101010101010101ULL; /* R1 */ - pxTopOfStack--; - *pxTopOfStack = (StackType_t)pvParameters; /* R0 */ - pxTopOfStack--; - *pxTopOfStack = 0x0303030303030303ULL; /* R3 */ - pxTopOfStack--; - *pxTopOfStack = 0x0202020202020202ULL; /* R2 */ - pxTopOfStack--; - *pxTopOfStack = 0x0505050505050505ULL; /* R5 */ - pxTopOfStack--; - *pxTopOfStack = 0x0404040404040404ULL; /* R4 */ - pxTopOfStack--; - *pxTopOfStack = 0x0707070707070707ULL; /* R7 */ - pxTopOfStack--; - *pxTopOfStack = 0x0606060606060606ULL; /* R6 */ - pxTopOfStack--; - *pxTopOfStack = 0x0909090909090909ULL; /* R9 */ - pxTopOfStack--; - *pxTopOfStack = 0x0808080808080808ULL; /* R8 */ - pxTopOfStack--; - *pxTopOfStack = 0x1111111111111111ULL; /* R11 */ - pxTopOfStack--; - *pxTopOfStack = 0x1010101010101010ULL; /* R10 */ - pxTopOfStack--; - *pxTopOfStack = 0x1313131313131313ULL; /* R13 */ - pxTopOfStack--; - *pxTopOfStack = 0x1212121212121212ULL; /* R12 */ - pxTopOfStack--; - *pxTopOfStack = 0x1515151515151515ULL; /* R15 */ - pxTopOfStack--; - *pxTopOfStack = 0x1414141414141414ULL; /* R14 */ - pxTopOfStack--; - *pxTopOfStack = 0x1717171717171717ULL; /* R17 */ - pxTopOfStack--; - *pxTopOfStack = 0x1616161616161616ULL; /* R16 */ - pxTopOfStack--; - *pxTopOfStack = 0x1919191919191919ULL; /* R19 */ - pxTopOfStack--; - *pxTopOfStack = 0x1818181818181818ULL; /* R18 */ - pxTopOfStack--; - *pxTopOfStack = 0x2121212121212121ULL; /* R21 */ - pxTopOfStack--; - *pxTopOfStack = 0x2020202020202020ULL; /* R20 */ - pxTopOfStack--; - *pxTopOfStack = 0x2323232323232323ULL; /* R23 */ - pxTopOfStack--; - *pxTopOfStack = 0x2222222222222222ULL; /* R22 */ - pxTopOfStack--; - *pxTopOfStack = 0x2525252525252525ULL; /* R25 */ - pxTopOfStack--; - *pxTopOfStack = 0x2424242424242424ULL; /* R24 */ - pxTopOfStack--; - *pxTopOfStack = 0x2727272727272727ULL; /* R27 */ - pxTopOfStack--; - *pxTopOfStack = 0x2626262626262626ULL; /* R26 */ - pxTopOfStack--; - *pxTopOfStack = 0x2929292929292929ULL; /* R29 */ - pxTopOfStack--; - *pxTopOfStack = 0x2828282828282828ULL; /* R28 */ - pxTopOfStack--; - *pxTopOfStack = (StackType_t)0x00; /* XZR - has no effect, used so there are an even number of registers. */ - pxTopOfStack--; - *pxTopOfStack = (StackType_t)0x00; /* R30 - procedure call link register. */ - pxTopOfStack--; - - *pxTopOfStack = portINITIAL_PSTATE; - pxTopOfStack--; - - *pxTopOfStack = (StackType_t)pxCode; /* Exception return address. */ - pxTopOfStack--; - - /* The task will start with a critical nesting count of 0 as interrupts are - enabled. */ - *pxTopOfStack = portNO_CRITICAL_NESTING; - pxTopOfStack--; - - /* The task will start without a floating point context. A task that uses - the floating point hardware must call vPortTaskUsesFPU() before executing - any floating point instructions. */ - *pxTopOfStack = portNO_FLOATING_POINT_CONTEXT; - - return pxTopOfStack; + /* Setup the initial stack of the task. The stack is set exactly as + expected by the portRESTORE_CONTEXT() macro. */ + + /* First all the general purpose registers. */ + pxTopOfStack--; + *pxTopOfStack = 0x0101010101010101ULL; /* R1 */ + pxTopOfStack--; + *pxTopOfStack = (StackType_t)pvParameters; /* R0 */ + pxTopOfStack--; + *pxTopOfStack = 0x0303030303030303ULL; /* R3 */ + pxTopOfStack--; + *pxTopOfStack = 0x0202020202020202ULL; /* R2 */ + pxTopOfStack--; + *pxTopOfStack = 0x0505050505050505ULL; /* R5 */ + pxTopOfStack--; + *pxTopOfStack = 0x0404040404040404ULL; /* R4 */ + pxTopOfStack--; + *pxTopOfStack = 0x0707070707070707ULL; /* R7 */ + pxTopOfStack--; + *pxTopOfStack = 0x0606060606060606ULL; /* R6 */ + pxTopOfStack--; + *pxTopOfStack = 0x0909090909090909ULL; /* R9 */ + pxTopOfStack--; + *pxTopOfStack = 0x0808080808080808ULL; /* R8 */ + pxTopOfStack--; + *pxTopOfStack = 0x1111111111111111ULL; /* R11 */ + pxTopOfStack--; + *pxTopOfStack = 0x1010101010101010ULL; /* R10 */ + pxTopOfStack--; + *pxTopOfStack = 0x1313131313131313ULL; /* R13 */ + pxTopOfStack--; + *pxTopOfStack = 0x1212121212121212ULL; /* R12 */ + pxTopOfStack--; + *pxTopOfStack = 0x1515151515151515ULL; /* R15 */ + pxTopOfStack--; + *pxTopOfStack = 0x1414141414141414ULL; /* R14 */ + pxTopOfStack--; + *pxTopOfStack = 0x1717171717171717ULL; /* R17 */ + pxTopOfStack--; + *pxTopOfStack = 0x1616161616161616ULL; /* R16 */ + pxTopOfStack--; + *pxTopOfStack = 0x1919191919191919ULL; /* R19 */ + pxTopOfStack--; + *pxTopOfStack = 0x1818181818181818ULL; /* R18 */ + pxTopOfStack--; + *pxTopOfStack = 0x2121212121212121ULL; /* R21 */ + pxTopOfStack--; + *pxTopOfStack = 0x2020202020202020ULL; /* R20 */ + pxTopOfStack--; + *pxTopOfStack = 0x2323232323232323ULL; /* R23 */ + pxTopOfStack--; + *pxTopOfStack = 0x2222222222222222ULL; /* R22 */ + pxTopOfStack--; + *pxTopOfStack = 0x2525252525252525ULL; /* R25 */ + pxTopOfStack--; + *pxTopOfStack = 0x2424242424242424ULL; /* R24 */ + pxTopOfStack--; + *pxTopOfStack = 0x2727272727272727ULL; /* R27 */ + pxTopOfStack--; + *pxTopOfStack = 0x2626262626262626ULL; /* R26 */ + pxTopOfStack--; + *pxTopOfStack = 0x2929292929292929ULL; /* R29 */ + pxTopOfStack--; + *pxTopOfStack = 0x2828282828282828ULL; /* R28 */ + pxTopOfStack--; + *pxTopOfStack = (StackType_t)0x00; /* XZR - has no effect, used so there are an even number of registers. */ + pxTopOfStack--; + *pxTopOfStack = (StackType_t)0x00; /* R30 - procedure call link register. */ + pxTopOfStack--; + + *pxTopOfStack = portINITIAL_PSTATE; + pxTopOfStack--; + + *pxTopOfStack = (StackType_t)pxCode; /* Exception return address. */ + pxTopOfStack--; + +#if( configUSE_TASK_FPU_SUPPORT == 1 ) + { + /* The task will start with a critical nesting count of 0 as interrupts are + enabled. */ + *pxTopOfStack = portNO_CRITICAL_NESTING; + /* The task will start without a floating point context. A task that uses + the floating point hardware must call vPortTaskUsesFPU() before executing + any floating point instructions. */ + pxTopOfStack--; + *pxTopOfStack = portNO_FLOATING_POINT_CONTEXT; + } +#elif( configUSE_TASK_FPU_SUPPORT == 2 ) + { + /* The task will start with a floating point context. Leave enough + * space for the registers - and ensure they are initialised to 0. */ + pxTopOfStack -= (portFPU_REGISTER_DOUBLE_WORDS - 1); + memset(pxTopOfStack, 0x00, portFPU_REGISTER_DOUBLE_WORDS * sizeof(StackType_t)); + + /* The task will start with a critical nesting count of 0 as interrupts are + enabled. */ + pxTopOfStack--; + *pxTopOfStack = portNO_CRITICAL_NESTING; + pxTopOfStack--; + *pxTopOfStack = pdTRUE; + ullPortTaskHasFPUContext = pdTRUE; + } +#else + { +#error Invalid configUSE_TASK_FPU_SUPPORT setting - configUSE_TASK_FPU_SUPPORT must be set to 1, 2, or left undefined. + } +#endif + + return pxTopOfStack; } /*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler(void) { - uint32_t ulAPSR; + uint32_t ulAPSR; #if (configASSERT_DEFINED == 1) - { - volatile uint32_t ulOriginalPriority; - volatile uint8_t *const pucFirstUserPriorityRegister = (volatile uint8_t *const)(configINTERRUPT_CONTROLLER_BASE_ADDRESS + portINTERRUPT_PRIORITY_REGISTER_OFFSET); - volatile uint8_t ucMaxPriorityValue; - if(pucFirstUserPriorityRegister != 0) - { - /* Determine how many priority bits are implemented in the GIC. - Save the interrupt priority value that is about to be clobbered. */ - ulOriginalPriority = *pucFirstUserPriorityRegister; - /* Determine the number of priority bits available. First write to - all possible bits. */ - *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; - - /* Read the value back to see how many bits stuck. */ - ucMaxPriorityValue = *pucFirstUserPriorityRegister; - - if(ucMaxPriorityValue != 0) - { - /* Shift to the least significant bits. */ - while ((ucMaxPriorityValue & portBIT_0_SET) != portBIT_0_SET) - { - ucMaxPriorityValue >>= (uint8_t)0x01; - } - /* Sanity check configUNIQUE_INTERRUPT_PRIORITIES matches the read - value. */ - configASSERT(ucMaxPriorityValue >= portLOWEST_INTERRUPT_PRIORITY); - } - - /* Restore the clobbered interrupt priority register to its original - value. */ - *pucFirstUserPriorityRegister = ulOriginalPriority; - } - - } + { + volatile uint32_t ulOriginalPriority; + volatile uint8_t *const pucFirstUserPriorityRegister = (volatile uint8_t *const)(configINTERRUPT_CONTROLLER_BASE_ADDRESS + portINTERRUPT_PRIORITY_REGISTER_OFFSET); + volatile uint8_t ucMaxPriorityValue; + if (pucFirstUserPriorityRegister != 0) + { + /* Determine how many priority bits are implemented in the GIC. + Save the interrupt priority value that is about to be clobbered. */ + ulOriginalPriority = *pucFirstUserPriorityRegister; + /* Determine the number of priority bits available. First write to + all possible bits. */ + *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; + + /* Read the value back to see how many bits stuck. */ + ucMaxPriorityValue = *pucFirstUserPriorityRegister; + + if (ucMaxPriorityValue != 0) + { + /* Shift to the least significant bits. */ + while ((ucMaxPriorityValue & portBIT_0_SET) != portBIT_0_SET) + { + ucMaxPriorityValue >>= (uint8_t)0x01; + } + /* Sanity check configUNIQUE_INTERRUPT_PRIORITIES matches the read + value. */ + configASSERT(ucMaxPriorityValue >= portLOWEST_INTERRUPT_PRIORITY); + } + + /* Restore the clobbered interrupt priority register to its original + value. */ + *pucFirstUserPriorityRegister = ulOriginalPriority; + } + + } #endif /* conifgASSERT_DEFINED */ - /* At the time of writing, the BSP only supports EL1. */ - __asm volatile("MRS %0, CurrentEL" - : "=r"(ulAPSR)); - ulAPSR &= portAPSR_MODE_BITS_MASK; + /* At the time of writing, the BSP only supports EL1. */ + __asm volatile("MRS %0, CurrentEL" + : "=r"(ulAPSR)); + ulAPSR &= portAPSR_MODE_BITS_MASK; #if defined(GUEST) - configASSERT(ulAPSR == portEL1); - if (ulAPSR == portEL1) + configASSERT(ulAPSR == portEL1); + if (ulAPSR == portEL1) #else - configASSERT(ulAPSR == portEL3); - if (ulAPSR == portEL3) + configASSERT(ulAPSR == portEL3); + if (ulAPSR == portEL3) #endif - { - /* Only continue if the binary point value is set to its lowest possible - setting. See the comments in vPortValidateInterruptPriority() below for - more information. */ - // configASSERT((portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS) <= portMAX_BINARY_POINT_VALUE); - configASSERT((FGicGetICC_BPR1() & portBINARY_POINT_BITS) <= portMAX_BINARY_POINT_VALUE); - - // if ((portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS) <= portMAX_BINARY_POINT_VALUE) - if ((FGicGetICC_BPR1() & portBINARY_POINT_BITS) <= portMAX_BINARY_POINT_VALUE) - { - /* Interrupts are turned off in the CPU itself to ensure a tick does - not execute while the scheduler is being started. Interrupts are - automatically turned back on in the CPU when the first task starts - executing. */ - portDISABLE_INTERRUPTS(); - - /* Start the timer that generates the tick ISR. */ - configSETUP_TICK_INTERRUPT(); - /* Start the first task executing. */ - vPortRestoreTaskContext(); - } - } - - return 0; + { + /* Only continue if the binary point value is set to its lowest possible + setting. See the comments in vPortValidateInterruptPriority() below for + more information. */ + // configASSERT((portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS) <= portMAX_BINARY_POINT_VALUE); + configASSERT((FGicGetICC_BPR1() & portBINARY_POINT_BITS) <= portMAX_BINARY_POINT_VALUE); + + // if ((portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS) <= portMAX_BINARY_POINT_VALUE) + if ((FGicGetICC_BPR1() & portBINARY_POINT_BITS) <= portMAX_BINARY_POINT_VALUE) + { + /* Interrupts are turned off in the CPU itself to ensure a tick does + not execute while the scheduler is being started. Interrupts are + automatically turned back on in the CPU when the first task starts + executing. */ + portDISABLE_INTERRUPTS(); + + /* Start the timer that generates the tick ISR. */ + configSETUP_TICK_INTERRUPT(); + /* Start the first task executing. */ + vPortRestoreTaskContext(); + } + } + + return 0; } /*-----------------------------------------------------------*/ void vPortEndScheduler(void) { - /* Not implemented in ports where there is nothing to return to. - Artificially force an assert. */ - configASSERT(ullCriticalNesting == 1000ULL); + /* Not implemented in ports where there is nothing to return to. + Artificially force an assert. */ + configASSERT(ullCriticalNesting == 1000ULL); } /*-----------------------------------------------------------*/ void vPortEnterCritical(void) { - /* Mask interrupts up to the max syscall interrupt priority. */ - uxPortSetInterruptMask(); - - /* Now interrupts are disabled ullCriticalNesting can be accessed - directly. Increment ullCriticalNesting to keep a count of how many times - portENTER_CRITICAL() has been called. */ - ullCriticalNesting++; - - /* This is not the interrupt safe version of the enter critical function so - assert() if it is being called from an interrupt context. Only API - functions that end in "FromISR" can be used in an interrupt. Only assert if - the critical nesting count is 1 to protect against recursive calls if the - assert function also uses a critical section. */ - if (ullCriticalNesting == 1ULL) - { - configASSERT(ullPortInterruptNesting == 0); - } + /* Mask interrupts up to the max syscall interrupt priority. */ + uxPortSetInterruptMask(); + + /* Now interrupts are disabled ullCriticalNesting can be accessed + directly. Increment ullCriticalNesting to keep a count of how many times + portENTER_CRITICAL() has been called. */ + ullCriticalNesting++; + + /* This is not the interrupt safe version of the enter critical function so + assert() if it is being called from an interrupt context. Only API + functions that end in "FromISR" can be used in an interrupt. Only assert if + the critical nesting count is 1 to protect against recursive calls if the + assert function also uses a critical section. */ + if (ullCriticalNesting == 1ULL) + { + configASSERT(ullPortInterruptNesting == 0); + } } /*-----------------------------------------------------------*/ void vPortExitCritical(void) { - if (ullCriticalNesting > portNO_CRITICAL_NESTING) - { - /* Decrement the nesting count as the critical section is being - exited. */ - ullCriticalNesting--; - - /* If the nesting level has reached zero then all interrupt - priorities must be re-enabled. */ - if (ullCriticalNesting == portNO_CRITICAL_NESTING) - { - /* Critical nesting has reached zero so all interrupt priorities - should be unmasked. */ - portCLEAR_INTERRUPT_MASK(); - } - } + if (ullCriticalNesting > portNO_CRITICAL_NESTING) + { + /* Decrement the nesting count as the critical section is being + exited. */ + ullCriticalNesting--; + + /* If the nesting level has reached zero then all interrupt + priorities must be re-enabled. */ + if (ullCriticalNesting == portNO_CRITICAL_NESTING) + { + /* Critical nesting has reached zero so all interrupt priorities + should be unmasked. */ + portCLEAR_INTERRUPT_MASK(); + } + } } /*-----------------------------------------------------------*/ void FreeRTOS_Tick_Handler(void) { -/* Interrupts should not be enabled before this point. */ + /* Interrupts should not be enabled before this point. */ #if (configASSERT_DEFINED == 1) - { - uint32_t ulMaskBits; + { + uint32_t ulMaskBits; - __asm volatile("mrs %0, daif" - : "=r"(ulMaskBits)::"memory"); - configASSERT((ulMaskBits & portDAIF_I) != 0); - } + __asm volatile("mrs %0, daif" + : "=r"(ulMaskBits)::"memory"); + configASSERT((ulMaskBits & portDAIF_I) != 0); + } #endif /* configASSERT_DEFINED */ - /* Set interrupt mask before altering scheduler structures. The tick - handler runs at the lowest priority, so interrupts cannot already be masked, - so there is no need to save and restore the current mask value. It is - necessary to turn off interrupts in the CPU itself while the ICCPMR is being - updated. */ - - InterruptSetPriorityMask(configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT); - __asm volatile("dsb sy \n" - "isb sy \n" :: - : "memory"); - - /* Ok to enable interrupts after the interrupt source has been cleared. */ - configCLEAR_TICK_INTERRUPT(); - portENABLE_INTERRUPTS(); - - /* Increment the RTOS tick. */ - if (xTaskIncrementTick() != pdFALSE) - { - ullPortYieldRequired = pdTRUE; - } - - /* Ensure all interrupt priorities are active again. */ - portCLEAR_INTERRUPT_MASK(); + /* Set interrupt mask before altering scheduler structures. The tick + handler runs at the lowest priority, so interrupts cannot already be masked, + so there is no need to save and restore the current mask value. It is + necessary to turn off interrupts in the CPU itself while the ICCPMR is being + updated. */ + + InterruptSetPriorityMask(configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT); + __asm volatile("dsb sy \n" + "isb sy \n" :: + : "memory"); + + /* Ok to enable interrupts after the interrupt source has been cleared. */ + configCLEAR_TICK_INTERRUPT(); + portENABLE_INTERRUPTS(); + + /* Increment the RTOS tick. */ + if (xTaskIncrementTick() != pdFALSE) + { + ullPortYieldRequired = pdTRUE; + } + + /* Ensure all interrupt priorities are active again. */ + portCLEAR_INTERRUPT_MASK(); } /*-----------------------------------------------------------*/ void vPortTaskUsesFPU(void) { - /* A task is registering the fact that it needs an FPU context. Set the - FPU flag (which is saved as part of the task context). */ - ullPortTaskHasFPUContext = pdTRUE; - printf("ullPortTaskHasFPUContext %x \r\n", ullPortTaskHasFPUContext); - /* Consider initialising the FPSR here - but probably not necessary in - AArch64. */ + /* A task is registering the fact that it needs an FPU context. Set the + FPU flag (which is saved as part of the task context). */ + ullPortTaskHasFPUContext = pdTRUE; + /* Consider initialising the FPSR here - but probably not necessary in + AArch64. */ } /*-----------------------------------------------------------*/ void vPortClearInterruptMask(UBaseType_t uxNewMaskValue) { - if (uxNewMaskValue == pdFALSE) - { - portCLEAR_INTERRUPT_MASK(); - } + if (uxNewMaskValue == pdFALSE) + { + portCLEAR_INTERRUPT_MASK(); + } } /*-----------------------------------------------------------*/ +/* +Set current interrupt priority mask and translate, ICC_PMR +• The value is right-shifted by one bit. +• Bit [7] of the value is set to 1. +*/ +void vPortSetPriorityMask(uint32_t value) +{ + uint32_t priority = PRIORITY_TRANSLATE_SET(value); + InterruptSetPriorityMask(priority); +} + +/* Get current interrupt priority mask and translate, ICC_PMR, priority << portPRIORITY_SHIFT */ +uint32_t vPortGetPriorityMask(void) +{ + return PRIORITY_TRANSLATE_GET(InterruptGetPriorityMask()); +} + +/* Get current interrupt priority and translate, ICC_RPR, priority << portPRIORITY_SHIFT */ +uint32_t vPortGetCurrentPriority(void) +{ + return PRIORITY_TRANSLATE_GET(FGicGetICC_RPR()); +} + UBaseType_t uxPortSetInterruptMask(void) { - uint32_t ulReturn; - - /* Interrupt in the CPU must be turned off while the ICCPMR is being - updated. */ - portDISABLE_INTERRUPTS(); - if (FGicGetICC_PMR() == (uint32_t)(configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT)) - { - /* Interrupts were already masked. */ - ulReturn = pdTRUE; - } - else - { - ulReturn = pdFALSE; - InterruptSetPriorityMask(configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT); - // portICCPMR_PRIORITY_MASK_REGISTER = (uint32_t)(configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT); - __asm volatile("dsb sy \n" - "isb sy \n" :: - : "memory"); - } - portENABLE_INTERRUPTS(); - - return ulReturn; + uint32_t ulReturn; + + /* Interrupt in the CPU must be turned off while the ICCPMR is being + updated. */ + portDISABLE_INTERRUPTS(); + if (vPortGetPriorityMask() == (uint32_t)(configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT)) + { + /* Interrupts were already masked. */ + ulReturn = pdTRUE; + } + else + { + ulReturn = pdFALSE; + vPortSetPriorityMask(configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT); + __asm volatile("dsb sy \n" + "isb sy \n" :: + : "memory"); + } + portENABLE_INTERRUPTS(); + return ulReturn; } /*-----------------------------------------------------------*/ @@ -472,33 +523,33 @@ UBaseType_t uxPortSetInterruptMask(void) void vPortValidateInterruptPriority(void) { - /* The following assertion will fail if a service routine (ISR) for - an interrupt that has been assigned a priority above - configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API - function. ISR safe FreeRTOS API functions must *only* be called - from interrupts that have been assigned a priority at or below - configMAX_SYSCALL_INTERRUPT_PRIORITY. - - Numerically low interrupt priority numbers represent logically high - interrupt priorities, therefore the priority of the interrupt must - be set to a value equal to or numerically *higher* than - configMAX_SYSCALL_INTERRUPT_PRIORITY. - - FreeRTOS maintains separate thread and ISR API functions to ensure - interrupt entry is as fast and simple as possible. */ - configASSERT(FGicGetICC_RPR() >= (uint32_t)(configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT)); - - /* Priority grouping: The interrupt controller (GIC) allows the bits - that define each interrupt's priority to be split between bits that - define the interrupt's pre-emption priority bits and bits that define - the interrupt's sub-priority. For simplicity all bits must be defined - to be pre-emption priority bits. The following assertion will fail if - this is not the case (if some bits represent a sub-priority). - - The priority grouping is configured by the GIC's binary point register - (ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest - possible value (which may be above 0). */ - configASSERT((FGicGetICC_BPR1() & portBINARY_POINT_BITS) <= portMAX_BINARY_POINT_VALUE); + /* The following assertion will fail if a service routine (ISR) for + an interrupt that has been assigned a priority above + configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API + function. ISR safe FreeRTOS API functions must *only* be called + from interrupts that have been assigned a priority at or below + configMAX_SYSCALL_INTERRUPT_PRIORITY. + + Numerically low interrupt priority numbers represent logically high + interrupt priorities, therefore the priority of the interrupt must + be set to a value equal to or numerically *higher* than + configMAX_SYSCALL_INTERRUPT_PRIORITY. + + FreeRTOS maintains separate thread and ISR API functions to ensure + interrupt entry is as fast and simple as possible. */ + configASSERT(vPortGetCurrentPriority() >= (uint32_t)(configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT)); + + /* Priority grouping: The interrupt controller (GIC) allows the bits + that define each interrupt's priority to be split between bits that + define the interrupt's pre-emption priority bits and bits that define + the interrupt's sub-priority. For simplicity all bits must be defined + to be pre-emption priority bits. The following assertion will fail if + this is not the case (if some bits represent a sub-priority). + + The priority grouping is configured by the GIC's binary point register + (ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest + possible value (which may be above 0). */ + configASSERT((FGicGetICC_BPR1() & portBINARY_POINT_BITS) <= portMAX_BINARY_POINT_VALUE); } #endif /* configASSERT_DEFINED */ diff --git a/third-party/freertos/portable/GCC/ft_platform/aarch64/portASM.S b/third-party/freertos/portable/GCC/ft_platform/aarch64/portASM.S index 05365174..834fffc9 100644 --- a/third-party/freertos/portable/GCC/ft_platform/aarch64/portASM.S +++ b/third-party/freertos/portable/GCC/ft_platform/aarch64/portASM.S @@ -25,48 +25,8 @@ * 1 tab == 4 spaces! */ - #define ICC_AP0R0_EL1 S3_0_C12_C8_4 -#define ICC_AP0R1_EL1 S3_0_C12_C8_5 -#define ICC_AP0R2_EL1 S3_0_C12_C8_6 -#define ICC_AP0R3_EL1 S3_0_C12_C8_7 - -#define ICC_AP1R0_EL1 S3_0_C12_C9_0 -#define ICC_AP1R1_EL1 S3_0_C12_C9_1 -#define ICC_AP1R2_EL1 S3_0_C12_C9_2 -#define ICC_AP1R3_EL1 S3_0_C12_C9_3 - -#define ICC_ASGI1R_EL1 S3_0_C12_C11_6 - -#define ICC_BPR0_EL1 S3_0_C12_C8_3 -#define ICC_BPR1_EL1 S3_0_C12_C12_3 - -#define ICC_CTLR_EL1 S3_0_C12_C12_4 -#define ICC_CTLR_EL3 S3_6_C12_C12_4 - -#define ICC_DIR_EL1 S3_0_C12_C11_1 - -#define ICC_EOIR0_EL1 S3_0_C12_C8_1 -#define ICC_EOIR1_EL1 S3_0_C12_C12_1 - -#define ICC_HPPIR0_EL1 S3_0_C12_C8_2 -#define ICC_HPPIR1_EL1 S3_0_C12_C12_2 - -#define ICC_IAR0_EL1 S3_0_C12_C8_0 -#define ICC_IAR1_EL1 S3_0_C12_C12_0 - -#define ICC_IGRPEN0_EL1 S3_0_C12_C12_6 -#define ICC_IGRPEN1_EL1 S3_0_C12_C12_7 -#define ICC_IGRPEN1_EL3 S3_6_C12_C12_7 - -#define ICC_PMR_EL1 S3_0_C4_C6_0 -#define ICC_RPR_EL1 S3_0_C12_C11_3 - -#define ICC_SGI0R_EL1 S3_0_C12_C11_7 -#define ICC_SGI1R_EL1 S3_0_C12_C11_5 - -#define ICC_SRE_EL1 S3_0_C12_C12_5 -#define ICC_SRE_EL2 S3_4_C12_C9_5 -#define ICC_SRE_EL3 S3_6_C12_C12_5 +#define ICC_EOIR1_EL1 S3_0_C12_C12_1 +#define ICC_IAR1_EL1 S3_0_C12_C12_0 .text diff --git a/third-party/freertos/portable/GCC/ft_platform/aarch64/portAsm_debug.c b/third-party/freertos/portable/GCC/ft_platform/aarch64/portAsm_debug.c index 318e8a88..ee0f4d89 100644 --- a/third-party/freertos/portable/GCC/ft_platform/aarch64/portAsm_debug.c +++ b/third-party/freertos/portable/GCC/ft_platform/aarch64/portAsm_debug.c @@ -1,32 +1,34 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: portAsm_debug.c * Date: 2022-02-24 13:42:19 * LastEditTime: 2022-03-21 17:03:36 - * Description:  This file is for - * - * Modify History: - * Ver   Who        Date         Changes - * ----- ------     --------    -------------------------------------- + * Description:  This file is for the port asm debug functions + * + * Modify History: + * Ver   Who         Date         Changes + * ----- ------      --------    -------------------------------------- + * 1.0 wangxiaodong 2021/12/14 first release + * 1.1 wangxiaodong 2022/8/9 adapt E2000D */ #include -void test_value(void * x0 ,void * x1,void * x2 ,void * x3) +void test_value(void *x0, void *x1, void *x2, void *x3) { - printf("x2 %p \r\n",x2) ; + printf("x2 %p \r\n", x2) ; while (1) ; } \ No newline at end of file diff --git a/third-party/freertos/portable/GCC/ft_platform/aarch64/portmacro.h b/third-party/freertos/portable/GCC/ft_platform/aarch64/portmacro.h index 6b84fab1..9ede21f4 100644 --- a/third-party/freertos/portable/GCC/ft_platform/aarch64/portmacro.h +++ b/third-party/freertos/portable/GCC/ft_platform/aarch64/portmacro.h @@ -52,11 +52,11 @@ extern "C" #define portSTACK_TYPE size_t #define portBASE_TYPE long - typedef portSTACK_TYPE StackType_t; - typedef portBASE_TYPE BaseType_t; - typedef uint64_t UBaseType_t; +typedef portSTACK_TYPE StackType_t; +typedef portBASE_TYPE BaseType_t; +typedef uint64_t UBaseType_t; - typedef uint64_t TickType_t; +typedef uint64_t TickType_t; #define portMAX_DELAY ((TickType_t)0xffffffffffffffff) /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do @@ -77,51 +77,49 @@ not need to be guarded with a critical section. */ /* Called at the end of an ISR that can cause a context switch. */ #define portEND_SWITCHING_ISR(xSwitchRequired) \ - { \ - extern uint64_t ullPortYieldRequired; \ + { \ + extern uint64_t ullPortYieldRequired; \ \ - if (xSwitchRequired != pdFALSE) \ - { \ - ullPortYieldRequired = pdTRUE; \ - } \ - } + if (xSwitchRequired != pdFALSE) \ + { \ + ullPortYieldRequired = pdTRUE; \ + } \ + } #define portYIELD_FROM_ISR(x) portEND_SWITCHING_ISR(x) #if defined(GUEST) #define portYIELD() __asm volatile("SVC 0" :: \ - : "memory") + : "memory") #else #define portYIELD() __asm volatile("SMC 0" :: \ - : "memory") + : "memory") #endif - /*----------------------------------------------------------- - * Critical section control - *----------------------------------------------------------*/ +/*----------------------------------------------------------- +* Critical section control +*----------------------------------------------------------*/ - extern void vPortEnterCritical(void); - extern void vPortExitCritical(void); - extern UBaseType_t uxPortSetInterruptMask(void); - extern void vPortClearInterruptMask(UBaseType_t uxNewMaskValue); - extern void vPortInstallFreeRTOSVectorTable(void); +extern void vPortEnterCritical(void); +extern void vPortExitCritical(void); +extern UBaseType_t uxPortSetInterruptMask(void); +extern void vPortClearInterruptMask(UBaseType_t uxNewMaskValue); +extern void vPortInstallFreeRTOSVectorTable(void); #define portDISABLE_INTERRUPTS() \ - __asm volatile("MSR DAIFSET, #2" :: \ - : "memory"); \ - __asm volatile("DSB SY"); \ - __asm volatile("ISB SY"); + __asm volatile("MSR DAIFSET, #2" :: \ + : "memory"); \ + __asm volatile("DSB SY"); \ + __asm volatile("ISB SY"); #define portENABLE_INTERRUPTS() \ - __asm volatile("MSR DAIFCLR, #2" :: \ - : "memory"); \ - __asm volatile("DSB SY"); \ - __asm volatile("ISB SY"); + __asm volatile("MSR DAIFCLR, #2" :: \ + : "memory"); \ + __asm volatile("DSB SY"); \ + __asm volatile("ISB SY"); /* These macros do not globally disable/enable interrupts. They do mask off interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */ #define portENTER_CRITICAL() vPortEnterCritical(); #define portEXIT_CRITICAL() vPortExitCritical(); -#define portSET_INTERRUPT_MASK_FROM_ISR() uxPortSetInterruptMask() -#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x) /*-----------------------------------------------------------*/ @@ -131,13 +129,13 @@ macros is used. */ #define portTASK_FUNCTION_PROTO(vFunction, pvParameters) void vFunction(void *pvParameters) #define portTASK_FUNCTION(vFunction, pvParameters) void vFunction(void *pvParameters) - /* Prototype of the FreeRTOS tick handler. This must be installed as the +/* Prototype of the FreeRTOS tick handler. This must be installed as the handler for whichever peripheral is used to generate the RTOS tick. */ - void FreeRTOS_Tick_Handler(void); +void FreeRTOS_Tick_Handler(void); - /* Any task that uses the floating point unit MUST call vPortTaskUsesFPU() +/* Any task that uses the floating point unit MUST call vPortTaskUsesFPU() before any floating point instructions are executed. */ - void vPortTaskUsesFPU(void); +void vPortTaskUsesFPU(void); #define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU() #define portLOWEST_INTERRUPT_PRIORITY (((uint32_t)configUNIQUE_INTERRUPT_PRIORITIES) - 1UL) @@ -154,14 +152,14 @@ before any floating point instructions are executed. */ #define portRECORD_READY_PRIORITY(uxPriority, uxReadyPriorities) (uxReadyPriorities) |= (1UL << (uxPriority)) #define portRESET_READY_PRIORITY(uxPriority, uxReadyPriorities) (uxReadyPriorities) &= ~(1UL << (uxPriority)) - /*-----------------------------------------------------------*/ +/*-----------------------------------------------------------*/ #define portGET_HIGHEST_PRIORITY(uxTopPriority, uxReadyPriorities) uxTopPriority = (31 - __builtin_clz(uxReadyPriorities)) #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ #ifdef configASSERT - void vPortValidateInterruptPriority(void); +void vPortValidateInterruptPriority(void); #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #endif /* configASSERT */ @@ -175,22 +173,22 @@ before any floating point instructions are executed. */ /* The number of bits to shift for an interrupt priority is dependent on the number of bits implemented by the interrupt controller. */ #if configUNIQUE_INTERRUPT_PRIORITIES == 16 -#define portPRIORITY_SHIFT 4 -#define portMAX_BINARY_POINT_VALUE 3 + #define portPRIORITY_SHIFT 4 + #define portMAX_BINARY_POINT_VALUE 3 #elif configUNIQUE_INTERRUPT_PRIORITIES == 32 -#define portPRIORITY_SHIFT 3 -#define portMAX_BINARY_POINT_VALUE 2 + #define portPRIORITY_SHIFT 3 + #define portMAX_BINARY_POINT_VALUE 2 #elif configUNIQUE_INTERRUPT_PRIORITIES == 64 -#define portPRIORITY_SHIFT 2 -#define portMAX_BINARY_POINT_VALUE 1 + #define portPRIORITY_SHIFT 2 + #define portMAX_BINARY_POINT_VALUE 1 #elif configUNIQUE_INTERRUPT_PRIORITIES == 128 -#define portPRIORITY_SHIFT 1 -#define portMAX_BINARY_POINT_VALUE 0 + #define portPRIORITY_SHIFT 1 + #define portMAX_BINARY_POINT_VALUE 0 #elif configUNIQUE_INTERRUPT_PRIORITIES == 256 -#define portPRIORITY_SHIFT 0 -#define portMAX_BINARY_POINT_VALUE 0 + #define portPRIORITY_SHIFT 0 + #define portMAX_BINARY_POINT_VALUE 0 #else -#error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware + #error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware #endif /* Interrupt controller access addresses. */ @@ -200,12 +198,4 @@ number of bits implemented by the interrupt controller. */ #define portICCBPR_BINARY_POINT_OFFSET (0x08) #define portICCRPR_RUNNING_PRIORITY_OFFSET (0x14) -// #define portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS (GIC_GICC_BASE) -// #define portICCPMR_PRIORITY_MASK_REGISTER (*((volatile uint32_t *)(portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET))) -// #define portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS (portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET) -// #define portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS (portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCEOIR_END_OF_INTERRUPT_OFFSET) -// #define portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS (portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET) -// #define portICCBPR_BINARY_POINT_REGISTER (*((const volatile uint32_t *)(portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCBPR_BINARY_POINT_OFFSET))) -// #define portICCRPR_RUNNING_PRIORITY_REGISTER (*((const volatile uint32_t *)(portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCRPR_RUNNING_PRIORITY_OFFSET))) - #endif /* PORTMACRO_H */ diff --git a/third-party/freertos/portable/freertos_configs.c b/third-party/freertos/portable/freertos_configs.c index f5c8f4e6..64587790 100644 --- a/third-party/freertos/portable/freertos_configs.c +++ b/third-party/freertos/portable/freertos_configs.c @@ -1,24 +1,29 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: freertos_configs.c * Date: 2022-02-24 13:42:19 * LastEditTime: 2022-03-21 17:03:31 - * Description:  This file is for - * - * Modify History: + * Description:  This file is for the freertos config functions + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2021/9/26 first release + * 1.1 wangxiaodong 2021/12/24 adapt new standalone + * 1.2 wangxiaodong 2022/6/20 v0.1.0 + * 2.0 wangxiaodong 2022/8/9 adapt E2000D + * 2.1 liuzhihong 2023/1/12 improve lwip functions */ #include "FreeRTOS.h" @@ -34,18 +39,20 @@ #include "fexception.h" #include "fprintf.h" +static volatile u32 is_in_irq = 0 ; + void vMainAssertCalled(const char *pcFileName, uint32_t ulLineNumber) { - printf("Assert Error is %s : %d \r\n", pcFileName, ulLineNumber); + printf("Assert Error is %s : %d .\r\n", pcFileName, ulLineNumber); for (;;) ; } void vApplicationMallocFailedHook(void) { - u32 cpu_id; + u32 cpu_id; GetCpuId(&cpu_id); - printf("cpu %d Malloc Failed\r\n",cpu_id); + printf("CPU %d Malloc Failed.\r\n", cpu_id); while (1) ; } @@ -64,7 +71,7 @@ void vApplicationIdleHook(void) u32 PlatformGetGicDistBase(void) { - return GICV3_BASEADDRESS; + return GICV3_BASE_ADDR; } static u32 cntfrq; /* System frequency */ @@ -75,7 +82,7 @@ void vConfigureTickInterrupt(void) GenericTimerStop(); /* Get system frequency */ cntfrq = GenericTimerFrequecy(); - + /* Set tick rate */ GenericTimerCompare(cntfrq / configTICK_RATE_HZ); GenericTimerInterruptEnable(); @@ -97,10 +104,10 @@ volatile unsigned int gCpuRuntime; void vApplicationInterruptHandler(uint32_t ulICCIAR) { int ulInterruptID; - + is_in_irq ++; /* Interrupts cannot be re-enabled until the source of the interrupt is - cleared. The ID of the interrupt is obtained by bitwise ANDing the ICCIAR - value with 0x3FF. */ + cleared. The ID of the interrupt is obtained by bitwise ANDing the ICCIAR + value with 0x3FF. */ ulInterruptID = ulICCIAR & 0x3FFUL; /* call handler function */ @@ -114,106 +121,120 @@ void vApplicationInterruptHandler(uint32_t ulICCIAR) { FExceptionInterruptHandler((void *)(uintptr)ulInterruptID); } + is_in_irq --; +} + + +/** + * @name: vApplicationInIrq + * @msg: Used to indicate whether you are currently in an interrupt + * @return {int} 1:is in an irq ,0 is not in + * @note: + */ + +int vApplicationInIrq(void) +{ + return is_in_irq; } static InterruptDrvType finterrupt; void vApplicationInitIrq(void) { - InterruptInit(&finterrupt,INTERRUPT_DRV_INTS_ID,INTERRUPT_ROLE_MASTER); + InterruptInit(&finterrupt, INTERRUPT_DRV_INTS_ID, INTERRUPT_ROLE_MASTER); } void vApplicationStackOverflowHook(xTaskHandle pxTask, signed char *pcTaskName) { - (void) pxTask; - (void) pcTaskName; + (void) pxTask; + (void) pcTaskName; + + taskDISABLE_INTERRUPTS(); + FASSERT(FALSE); - taskDISABLE_INTERRUPTS(); - FASSERT(FALSE); - } /* configSUPPORT_STATIC_ALLOCATION is set to 1, so the application must provide an * implementation of vApplicationGetIdleTaskMemory() to provide the memory that is * used by the Idle task. */ -void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ) +void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize) { - /* If the buffers to be provided to the Idle task are declared inside this - * function then they must be declared static - otherwise they will be allocated on - * the stack and so not exists after this function exits. */ - static StaticTask_t xIdleTaskTCB; - static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; - - /* Pass out a pointer to the StaticTask_t structure in which the Idle task's - state will be stored. */ - *ppxIdleTaskTCBBuffer = &xIdleTaskTCB; - - /* Pass out the array that will be used as the Idle task's stack. */ - *ppxIdleTaskStackBuffer = uxIdleTaskStack; - - /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. - Note that, as the array is necessarily of type StackType_t, - configMINIMAL_STACK_SIZE is specified in words, not bytes. */ - *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; + /* If the buffers to be provided to the Idle task are declared inside this + * function then they must be declared static - otherwise they will be allocated on + * the stack and so not exists after this function exits. */ + static StaticTask_t xIdleTaskTCB; + static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; + + /* Pass out a pointer to the StaticTask_t structure in which the Idle task's + state will be stored. */ + *ppxIdleTaskTCBBuffer = &xIdleTaskTCB; + + /* Pass out the array that will be used as the Idle task's stack. */ + *ppxIdleTaskStackBuffer = uxIdleTaskStack; + + /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. + Note that, as the array is necessarily of type StackType_t, + configMINIMAL_STACK_SIZE is specified in words, not bytes. */ + *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; } /* configSUPPORT_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the * application must provide an implementation of `vApplicationGetTimerTaskMemory() * to provide the memory that is used by the Timer service task. */ -void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ) +void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize) { - /* If the buffers to be provided to the Timer task are declared inside this - * function then they must be declared static - otherwise they will be allocated on - * the stack and so not exists after this function exits. */ - static StaticTask_t xTimerTaskTCB; - static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ]; - - /* Pass out a pointer to the StaticTask_t structure in which the Timer - task's state will be stored. */ - *ppxTimerTaskTCBBuffer = &xTimerTaskTCB; - - /* Pass out the array that will be used as the Timer task's stack. */ - *ppxTimerTaskStackBuffer = uxTimerTaskStack; - - /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer. - Note that, as the array is necessarily of type StackType_t, - configTIMER_TASK_STACK_DEPTH is specified in words, not bytes. */ - *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; + /* If the buffers to be provided to the Timer task are declared inside this + * function then they must be declared static - otherwise they will be allocated on + * the stack and so not exists after this function exits. */ + static StaticTask_t xTimerTaskTCB; + static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ]; + + /* Pass out a pointer to the StaticTask_t structure in which the Timer + task's state will be stored. */ + *ppxTimerTaskTCBBuffer = &xTimerTaskTCB; + + /* Pass out the array that will be used as the Timer task's stack. */ + *ppxTimerTaskStackBuffer = uxTimerTaskStack; + + /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer. + Note that, as the array is necessarily of type StackType_t, + configTIMER_TASK_STACK_DEPTH is specified in words, not bytes. */ + *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; } -void vPrintString( const char *pcString ) +void vPrintString(const char *pcString) { - /* Print the string, using a critical section as a crude method of mutual - exclusion. */ - taskENTER_CRITICAL(); - { - printf( "%s\r\n", pcString ); - } - taskEXIT_CRITICAL(); + /* Print the string, using a critical section as a crude method of mutual + exclusion. */ + taskENTER_CRITICAL(); + { + printf("%s\r\n", pcString); + } + taskEXIT_CRITICAL(); } -void vPrintStringAndNumber( const char *pcString, uint32_t ulValue ) +void vPrintStringAndNumber(const char *pcString, uint32_t ulValue) { - /* Print the string, using a critical section as a crude method of mutual - exclusion. */ - taskENTER_CRITICAL(); - { - printf( "%s %lu\r\n", pcString, ulValue ); - } - taskEXIT_CRITICAL(); + /* Print the string, using a critical section as a crude method of mutual + exclusion. */ + taskENTER_CRITICAL(); + { + printf("%s %lu\r\n", pcString, ulValue); + } + taskEXIT_CRITICAL(); } void vPrintf(const char *format, ...) { - /* Print the string, using a critical section as a crude method of mutual exclusion. */ - taskENTER_CRITICAL(); - { - va_list args; - va_start(args, format); - vprintf(format, args); - va_end(args); - } - taskEXIT_CRITICAL(); + /* Print the string, using a critical section as a crude method of mutual exclusion. */ + taskENTER_CRITICAL(); + { + va_list args; + va_start(args, format); + vprintf(format, args); + va_end(args); + } + taskEXIT_CRITICAL(); } diff --git a/third-party/letter-shell-3.1/port/cmd/cmd_bootelf.c b/third-party/letter-shell-3.1/port/cmd/cmd_bootelf.c index 5fc8e66a..0a145b03 100644 --- a/third-party/letter-shell-3.1/port/cmd/cmd_bootelf.c +++ b/third-party/letter-shell-3.1/port/cmd/cmd_bootelf.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: cmd_bootelf.c * Date: 2022-02-24 18:24:53 * LastEditTime: 2022-03-21 17:03:44 - * Description:  This file is for - * - * Modify History: + * Description:  This file is for the bootelf command functions + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/3/25 first release */ #include @@ -30,8 +31,8 @@ static unsigned long image_load_addr = 0x80100000; static void BootelfCmdUsage() { - printf("usage:\r\n"); - printf(" bootelf [-p|-s] [address] \r\n"); + printf("usage:\r\n"); + printf(" bootelf [-p|-s] [address] \r\n"); printf(" load ELF image at [address] via program headers (-p)\r\n"); printf(" or via section headers (-s)\r\n"); } @@ -39,71 +40,83 @@ static void BootelfCmdUsage() static int BootelfCmdEntry(int argc, char *argv[]) { unsigned long addr; /* Address of the ELF image */ - unsigned long rc = 0; /* Return value from user code */ + unsigned long rc = 0; /* Return value from user code */ unsigned long load_flg = 0; - char *sload = NULL; + char *sload = NULL; - if(argc < 2) - { - BootelfCmdUsage(); + if (argc < 2) + { + BootelfCmdUsage(); return -1; - } + } + + /* Consume 'bootelf' */ + argc--; + argv++; - /* Consume 'bootelf' */ - argc--; argv++; - - /* Check for flag. */ - if (argc >= 1 && (argv[0][0] == '-' && (argv[0][1] == 'p' || argv[0][1] == 's'))) + /* Check for flag. */ + if (argc >= 1 && (argv[0][0] == '-' && (argv[0][1] == 'p' || argv[0][1] == 's'))) { - sload = argv[0]; - /* Consume flag. */ - argc--; argv++; - } + sload = argv[0]; + /* Consume flag. */ + argc--; + argv++; + } - if (argc >= 1 && (argv[0][0] == '-' && (argv[0][1] == 'l'))) + if (argc >= 1 && (argv[0][0] == '-' && (argv[0][1] == 'l'))) { - /* Consume flag. */ - argc--; argv++; - load_flg = 1; - } + /* Consume flag. */ + argc--; + argv++; + load_flg = 1; + } - /* Check for address. */ - if (argc >= 1 && strict_strtoul(argv[0], 16, &addr) == 0) + /* Check for address. */ + if (argc >= 1 && strict_strtoul(argv[0], 16, &addr) == 0) { - /* Consume address */ - argc--; argv++; - } + /* Consume address */ + argc--; + argv++; + } else { - addr = image_load_addr; + addr = image_load_addr; + } + + if (!ElfIsImageValid(addr)) + { + return 1; } - if (!ElfIsImageValid(addr)) - return 1; + if (sload && sload[1] == 'p') + { + addr = ElfLoadElfImagePhdr(addr); + } + else + { + addr = ElfLoadElfImageShdr(addr); + } - if (sload && sload[1] == 'p') - addr = ElfLoadElfImagePhdr(addr); - else - addr = ElfLoadElfImageShdr(addr); - - /* - * pass address parameter as argv[0] (aka command name), - * and all remaining args - */ - if (load_flg == 1 ) + /* + * pass address parameter as argv[0] (aka command name), + * and all remaining args + */ + if (load_flg == 1) { - printf("## Load application at 0x%08lx ...\n", addr); - }else{ - printf("## Starting application at 0x%08lx ...\n", addr); - rc = ElfExecBootElf((void *)addr, argc, argv); - } + printf("## Load application at 0x%08lx ...\n", addr); + } + else + { + printf("## Starting application at 0x%08lx ...\n", addr); + rc = ElfExecBootElf((void *)addr, argc, argv); + } - printf("## Application terminated, rc = 0x%lx\n", rc); + printf("## Application terminated, rc = 0x%lx.\n", rc); return (int)rc; } -SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), +SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), bootelf, BootelfCmdEntry, Boot from an ELF image in memory); diff --git a/third-party/letter-shell-3.1/port/cmd/cmd_codeloader.c b/third-party/letter-shell-3.1/port/cmd/cmd_codeloader.c index d3e4bf38..ec540a40 100644 --- a/third-party/letter-shell-3.1/port/cmd/cmd_codeloader.c +++ b/third-party/letter-shell-3.1/port/cmd/cmd_codeloader.c @@ -1,12 +1,26 @@ /* - * @Author: your name - * @Date: 2021-09-06 17:11:48 - * @LastEditTime: 2022-02-10 15:01:05 - * @LastEditors: Please set LastEditors - * @Description: In User Settings Edit - * @FilePath: \phytium-standalone-sdk\third-party\letter-shell-3.1\port\cmd\cmd_codelode.c + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: cmd_md.c + * Date: 2022-02-24 18:24:53 + * LastEditTime: 2022-03-21 17:03:53 + * Description:  This file is for the codeloader command functions + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/3/25 first release */ - #include #include "../src/shell.h" #include "strto.h" @@ -16,65 +30,71 @@ static unsigned long image_load_addr = 0x80100000; static void LoadElfCmdUsage() { - printf("usage:\r\n"); - printf(" loadelf [-p|-s] [address] \r\n"); - printf(" load ELF image at [address] via program headers (-p)\r\n"); - printf(" or via section headers (-s)\r\n"); + printf("usage:\r\n"); + printf(" loadelf [-p|-s] [address] \r\n"); + printf(" load ELF image at [address] via program headers (-p)\r\n"); + printf(" or via section headers (-s)\r\n"); } static int LoadElfCmdEntry(int argc, char *argv[]) { - unsigned long addr; /* Address of the ELF image */ - unsigned long rc; /* Return value from user code */ - unsigned long load_flg = 0; - char *sload = NULL; + unsigned long addr; /* Address of the ELF image */ + unsigned long rc; /* Return value from user code */ + unsigned long load_flg = 0; + char *sload = NULL; - if (argc < 2) - { - LoadElfCmdUsage(); - return -1; - } - /* Consume 'LoadElf' */ - argc--; - argv++; + if (argc < 2) + { + LoadElfCmdUsage(); + return -1; + } + /* Consume 'LoadElf' */ + argc--; + argv++; - /* Check for flag. */ - if (argc >= 1 && (argv[0][0] == '-' && (argv[0][1] == 'p' || argv[0][1] == 's'))) - { - sload = argv[0]; - /* Consume flag. */ - argc--; - argv++; - } + /* Check for flag. */ + if (argc >= 1 && (argv[0][0] == '-' && (argv[0][1] == 'p' || argv[0][1] == 's'))) + { + sload = argv[0]; + /* Consume flag. */ + argc--; + argv++; + } - /* Check for address. */ - if (argc >= 1 && strict_strtoul(argv[0], 16, &addr) == 0) - { - /* Consume address */ - argc--; - argv++; - } - else - { - addr = image_load_addr; - } + /* Check for address. */ + if (argc >= 1 && strict_strtoul(argv[0], 16, &addr) == 0) + { + /* Consume address */ + argc--; + argv++; + } + else + { + addr = image_load_addr; + } - if (!ElfIsImageValid(addr)) - return 1; + if (!ElfIsImageValid(addr)) + { + return 1; + } - if (sload && sload[1] == 'p') - addr = ElfLoadElfImagePhdr(addr); - else - addr = ElfLoadElfImageShdr(addr); + if (sload && sload[1] == 'p') + { + addr = ElfLoadElfImagePhdr(addr); + } + else + { + addr = ElfLoadElfImageShdr(addr); + } - /* - * pass address parameter as argv[0] (aka command name), - * and all remaining args - */ - printf("## Load application at 0x%08lx ...\n", addr); + /* + * pass address parameter as argv[0] (aka command name), + * and all remaining args + */ + printf("## Load application at 0x%08lx ...\n", addr); - return 0; + return 0; } SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), - loadelf, LoadElfCmdEntry, Load from an ELF image in memory); \ No newline at end of file + loadelf, LoadElfCmdEntry, Load from an ELF image in memory); \ No newline at end of file diff --git a/third-party/letter-shell-3.1/port/cmd/cmd_echo.c b/third-party/letter-shell-3.1/port/cmd/cmd_echo.c index 477b2720..53456aff 100644 --- a/third-party/letter-shell-3.1/port/cmd/cmd_echo.c +++ b/third-party/letter-shell-3.1/port/cmd/cmd_echo.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: cmd_echo.c * Date: 2022-02-24 18:24:53 * LastEditTime: 2022-03-21 17:03:49 - * Description:  This file is for - * - * Modify History: + * Description:  This file is for the echo command functions + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/3/25 first release */ #include @@ -30,8 +31,8 @@ static void EchoCmdUsage() { - printf("usage:\r\n"); - printf(" echo [str] [str] \r\n"); + printf("usage:\r\n"); + printf(" echo [str] [str] \r\n"); printf(" printf to shell\r\n"); } @@ -39,11 +40,11 @@ static int EchoCmdEntry(int argc, char *argv[]) { int loop; - if(argc < 2) - { - EchoCmdUsage(); + if (argc < 2) + { + EchoCmdUsage(); return -1; - } + } for (loop = 1; loop < argc; loop++) { diff --git a/third-party/letter-shell-3.1/port/cmd/cmd_md.c b/third-party/letter-shell-3.1/port/cmd/cmd_md.c index 9860fb6e..13d99dd6 100644 --- a/third-party/letter-shell-3.1/port/cmd/cmd_md.c +++ b/third-party/letter-shell-3.1/port/cmd/cmd_md.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: cmd_md.c * Date: 2022-02-24 18:24:53 * LastEditTime: 2022-03-21 17:03:53 - * Description:  This file is for - * - * Modify History: + * Description:  This file is for the md command functions + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/3/25 first release */ #include @@ -30,121 +31,133 @@ static void MdCmdUsage() { - printf("usage:\r\n"); - printf(" md [-b|-w|-l|-q] address [-c count]\r\n"); + printf("usage:\r\n"); + printf(" md [-b|-w|-l|-q] address [-c count]\r\n"); } static int MdCmdEntry(int argc, char *argv[]) { - uintptr addr = 0; - char buf[16]; - int n = 64, size = 1; - int i, len; - u8 b; - u16 w; - u32 l; - u64 q; + uintptr addr = 0; + char buf[16]; + int n = 64, size = 1; + int i, len; + u8 b; + u16 w; + u32 l; + u64 q; - if (argc < 2) - { - MdCmdUsage(); - return -1; - } + if (argc < 2) + { + MdCmdUsage(); + return -1; + } - for (i = 1; i < argc; i++) - { - if (!strcmp(argv[i], "-b")) - size = 1; - else if (!strcmp(argv[i], "-w")) - size = 2; - else if (!strcmp(argv[i], "-l")) - size = 4; - else if (!strcmp(argv[i], "-q")) - size = 8; - else if (!strcmp(argv[i], "-c") && (argc > i + 1)) - { - n = strtoul(argv[i + 1], NULL, 0); - i++; - } - else if (*argv[i] == '-') - { - MdCmdUsage(); - return (-1); - } - else if (*argv[i] != '-' && strcmp(argv[i], "-") != 0) - { - addr = strtoul(argv[i], NULL, 0); - } - } + for (i = 1; i < argc; i++) + { + if (!strcmp(argv[i], "-b")) + { + size = 1; + } + else if (!strcmp(argv[i], "-w")) + { + size = 2; + } + else if (!strcmp(argv[i], "-l")) + { + size = 4; + } + else if (!strcmp(argv[i], "-q")) + { + size = 8; + } + else if (!strcmp(argv[i], "-c") && (argc > i + 1)) + { + n = strtoul(argv[i + 1], NULL, 0); + i++; + } + else if (*argv[i] == '-') + { + MdCmdUsage(); + return (-1); + } + else if (*argv[i] != '-' && strcmp(argv[i], "-") != 0) + { + addr = strtoul(argv[i], NULL, 0); + } + } - if (size == 1) - { - addr &= ~((uintptr)0x0); - } - else if (size == 2) - { - addr &= ~((uintptr)0x1); - } - else if (size == 4) - { - addr &= ~((uintptr)0x3); - } - else if (size == 8) - { - addr &= ~((uintptr)0x7); - } - n = n * size; + if (size == 1) + { + addr &= ~((uintptr)0x0); + } + else if (size == 2) + { + addr &= ~((uintptr)0x1); + } + else if (size == 4) + { + addr &= ~((uintptr)0x3); + } + else if (size == 8) + { + addr &= ~((uintptr)0x7); + } + n = n * size; - while (n > 0) - { - len = (n > 16) ? 16 : n; - printf("%08lx: ", addr); - if (size == 1) - { - for (i = 0; i < len; i += size) - { - FtOut8((uintptr)(&buf[i]), (b = FtIn8(addr + i))); - printf(" %02lx", b); - } - } - else if (size == 2) - { - for (i = 0; i < len; i += size) - { - FtOut16((uintptr)(&buf[i]), (w = FtIn16(addr + i))); - printf(" %04lx", w); - } - } - else if (size == 4) - { - for (i = 0; i < len; i += size) - { - FtOut32((uintptr)(&buf[i]), (l = FtIn32(addr + i))); - printf(" %08lx", l); - } - } - else if (size == 8) - { - for (i = 0; i < len; i += size) - { - FtOut64((uintptr)(&buf[i]), (q = FtIn64(addr + i))); - printf(" %016llx", q); - } - } - printf("%*s", (16 - len) * 2 + (16 - len) / size + 4, ""); - for (i = 0; i < len; i++) - { - if ((buf[i] < 0x20) || (buf[i] > 0x7e)) - printf("."); - else - printf("%c", buf[i]); - } - addr += len; - n -= len; - printf("\r\n"); - } + while (n > 0) + { + len = (n > 16) ? 16 : n; + printf("%08lx: ", addr); + if (size == 1) + { + for (i = 0; i < len; i += size) + { + FtOut8((uintptr)(&buf[i]), (b = FtIn8(addr + i))); + printf(" %02lx", b); + } + } + else if (size == 2) + { + for (i = 0; i < len; i += size) + { + FtOut16((uintptr)(&buf[i]), (w = FtIn16(addr + i))); + printf(" %04lx", w); + } + } + else if (size == 4) + { + for (i = 0; i < len; i += size) + { + FtOut32((uintptr)(&buf[i]), (l = FtIn32(addr + i))); + printf(" %08lx", l); + } + } + else if (size == 8) + { + for (i = 0; i < len; i += size) + { + FtOut64((uintptr)(&buf[i]), (q = FtIn64(addr + i))); + printf(" %016llx", q); + } + } + printf("%*s", (16 - len) * 2 + (16 - len) / size + 4, ""); + for (i = 0; i < len; i++) + { + if ((buf[i] < 0x20) || (buf[i] > 0x7e)) + { + printf("."); + } + else + { + printf("%c", buf[i]); + } + } + addr += len; + n -= len; + printf("\r\n"); + } - return 0; + return 0; } SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), md, MdCmdEntry, dump a memory region); \ No newline at end of file diff --git a/third-party/letter-shell-3.1/port/cmd/cmd_mw.c b/third-party/letter-shell-3.1/port/cmd/cmd_mw.c index 477ebd54..ce0d2412 100644 --- a/third-party/letter-shell-3.1/port/cmd/cmd_mw.c +++ b/third-party/letter-shell-3.1/port/cmd/cmd_mw.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: cmd_mw.c * Date: 2022-02-24 18:24:53 * LastEditTime: 2022-03-21 17:03:57 - * Description:  This file is for - * - * Modify History: + * Description:  This file is for the mw command functions + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/3/25 first release */ #include @@ -30,97 +31,117 @@ static void MwUsage() { - printf("usage:\r\n"); - printf(" mw [-b|-w|-l|-q] address value [-c count]\r\n"); + printf("usage:\r\n"); + printf(" mw [-b|-w|-l|-q] address value [-c count]\r\n"); } static int MwCmdEntry(int argc, char **argv) { - uintptr addr = 0; - u64 value = 0; - int size = 1, n = 1; - int index = 0; - int i; + uintptr addr = 0; + u64 value = 0; + int size = 1, n = 1; + int index = 0; + int i; - if (argc < 3) - { - MwUsage(); - return -1; - } + if (argc < 3) + { + MwUsage(); + return -1; + } - for (i = 1; i < argc; i++) - { - if (!strcmp(argv[i], "-b")) - size = 1; - else if (!strcmp(argv[i], "-w")) - size = 2; - else if (!strcmp(argv[i], "-l")) - size = 4; - else if (!strcmp(argv[i], "-q")) - size = 8; - else if (!strcmp(argv[i], "-c") && (argc > i + 1)) - { - n = strtoul(argv[i + 1], NULL, 0); - if (n == 0) - { - printf("mw: the writing count is zero by '-c %s'", argv[i + 1]); - return -1; - } - i++; - } - else if (*argv[i] == '-') - { - MwUsage(); - return -1; - } - else if (*argv[i] != '-' && strcmp(argv[i], "-") != 0) - { - if (index == 0) - addr = strtoul(argv[i], NULL, 0); - else if (index == 1) - value = strtoull(argv[i], NULL, 0); - else if (index >= 2) - { - printf("mw: invalid paramter '%s'\r\n", argv[i]); - printf("try 'help mw' for more information.\r\n"); - return (-1); - } - index++; - } - } + for (i = 1; i < argc; i++) + { + if (!strcmp(argv[i], "-b")) + { + size = 1; + } + else if (!strcmp(argv[i], "-w")) + { + size = 2; + } + else if (!strcmp(argv[i], "-l")) + { + size = 4; + } + else if (!strcmp(argv[i], "-q")) + { + size = 8; + } + else if (!strcmp(argv[i], "-c") && (argc > i + 1)) + { + n = strtoul(argv[i + 1], NULL, 0); + if (n == 0) + { + printf("mw: the writing count is zero by '-c %s'.", argv[i + 1]); + return -1; + } + i++; + } + else if (*argv[i] == '-') + { + MwUsage(); + return -1; + } + else if (*argv[i] != '-' && strcmp(argv[i], "-") != 0) + { + if (index == 0) + { + addr = strtoul(argv[i], NULL, 0); + } + else if (index == 1) + { + value = strtoull(argv[i], NULL, 0); + } + else if (index >= 2) + { + printf("mw: invalid paramter '%s'\r\n", argv[i]); + printf("try 'help mw' for more information.\r\n"); + return (-1); + } + index++; + } + } - if (size == 1) - { - addr &= ~((uintptr)0x0); - } - else if (size == 2) - { - addr &= ~((uintptr)0x1); - } - else if (size == 4) - { - addr &= ~((uintptr)0x3); - } - else if (size == 8) - { - addr &= ~((uintptr)0x7); - } - n = n * size; + if (size == 1) + { + addr &= ~((uintptr)0x0); + } + else if (size == 2) + { + addr &= ~((uintptr)0x1); + } + else if (size == 4) + { + addr &= ~((uintptr)0x3); + } + else if (size == 8) + { + addr &= ~((uintptr)0x7); + } + n = n * size; - for (i = 0; i < n; i += size) - { - if (size == 1) - FtOut8((uintptr)(addr + i), (u8)value); - else if (size == 2) - FtOut16((uintptr)(addr + i), (u16)value); - else if (size == 4) - FtOut32((uintptr)(addr + i), (u32)value); - else if (size == 8) - FtOut64((uintptr)(addr + i), (u64)value); - } - printf("write done.\r\n"); + for (i = 0; i < n; i += size) + { + if (size == 1) + { + FtOut8((uintptr)(addr + i), (u8)value); + } + else if (size == 2) + { + FtOut16((uintptr)(addr + i), (u16)value); + } + else if (size == 4) + { + FtOut32((uintptr)(addr + i), (u32)value); + } + else if (size == 8) + { + FtOut64((uintptr)(addr + i), (u64)value); + } + } + printf("Write done.\r\n"); - return 0; + return 0; } SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), mw, MwCmdEntry, write values to memory region); \ No newline at end of file diff --git a/third-party/letter-shell-3.1/port/cmd/cmd_os_stats.c b/third-party/letter-shell-3.1/port/cmd/cmd_ps.c similarity index 71% rename from third-party/letter-shell-3.1/port/cmd/cmd_os_stats.c rename to third-party/letter-shell-3.1/port/cmd/cmd_ps.c index 52270073..f165834b 100644 --- a/third-party/letter-shell-3.1/port/cmd/cmd_os_stats.c +++ b/third-party/letter-shell-3.1/port/cmd/cmd_ps.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: cmd_os_stats.c * Date: 2022-02-25 08:34:53 * LastEditTime: 2022-02-25 08:34:53 - * Description:  This file is for - * - * Modify History: -* Ver   Who        Date         Changes - * ----- ------     --------    -------------------------------------- + * Description:  This file is for the ps command functions + * + * Modify History: +* Ver    Who         Date         Changes + * -----  ------      --------    -------------------------------------- + * 1.0 wangxiaodong 2022/11/24 first release */ #include "FreeRTOS.h" #include "task.h" @@ -35,18 +36,18 @@ static int DisplayTaskStats(int argc, char *argv[]) memset(CPU_RunInfo, 0, PS_LENGTH); /*信息缓冲区清零*/ vTaskList((char *)&CPU_RunInfo); //获取任务运行时间信息 - printf("---------------------------------------------\r\n"); - printf("task_name\ttask_state\tpriority\tstack\ttask_num\r\n"); - printf("%s", CPU_RunInfo); + printf("---------------------------------------------\r\n"); + printf("task_name\ttask_state\tpriority\tstack\ttask_num\r\n"); + printf("%s", CPU_RunInfo); printf("---------------------------------------------\r\n"); memset(CPU_RunInfo, 0, PS_LENGTH); //信息缓冲区清零 vTaskGetRunTimeStats((char *)&CPU_RunInfo); - printf("task_name\trun_time_count\tusage_rate\r\n"); - printf("%s", CPU_RunInfo); - printf("---------------------------------------------\r\n\n"); + printf("task_name\trun_time_count\tusage_rate\r\n"); + printf("%s", CPU_RunInfo); + printf("---------------------------------------------\r\n\n"); return 0; } diff --git a/third-party/letter-shell-3.1/port/cmd/cmd_reboot.c b/third-party/letter-shell-3.1/port/cmd/cmd_reboot.c index edb079d3..2b63c167 100644 --- a/third-party/letter-shell-3.1/port/cmd/cmd_reboot.c +++ b/third-party/letter-shell-3.1/port/cmd/cmd_reboot.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: cmd_reboot.c * Date: 2022-02-24 18:24:53 * LastEditTime: 2022-03-21 17:04:01 - * Description:  This file is for - * - * Modify History: + * Description:  This file is for the reboot command functions + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/3/25 first release */ #include "../src/shell.h" @@ -30,5 +31,5 @@ int RebootCmdEntry() PsciCpuReset(); return 0; } -SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), reboot, +SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), reboot, RebootCmdEntry, reboot board by psci); \ No newline at end of file diff --git a/third-party/letter-shell-3.1/port/cmd/cmd_rw.c b/third-party/letter-shell-3.1/port/cmd/cmd_rw.c index e762f85c..bfd99218 100644 --- a/third-party/letter-shell-3.1/port/cmd/cmd_rw.c +++ b/third-party/letter-shell-3.1/port/cmd/cmd_rw.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: cmd_rw.c * Date: 2022-02-24 18:24:53 * LastEditTime: 2022-03-21 17:04:05 - * Description:  This file is for - * - * Modify History: + * Description:  This file is for the rw command functions + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/3/25 first release */ #include @@ -32,113 +33,129 @@ static int RwWriteRegister(u32 reg_addr, u32 reg_val, u32 bit_width) { - if (bit_width > 4) - return -1; - - if (4 == bit_width) - FtOut32((uintptr)reg_addr, reg_val); - else if (2 == bit_width) - FtOut16((uintptr)reg_addr, (u16)reg_val); - else if (1 == bit_width) - FtOut8((uintptr)reg_addr, (u8)reg_val); - - return 0; + if (bit_width > 4) + { + return -1; + } + + if (4 == bit_width) + { + FtOut32((uintptr)reg_addr, reg_val); + } + else if (2 == bit_width) + { + FtOut16((uintptr)reg_addr, (u16)reg_val); + } + else if (1 == bit_width) + { + FtOut8((uintptr)reg_addr, (u8)reg_val); + } + + return 0; } static int RwReadRegister(u32 reg_addr, u32 *reg_val_p, u32 bit_width, u32 len) { - if ((bit_width > 4) || (NULL == reg_val_p)) - return -1; - - if (4 == bit_width) - *reg_val_p = FtIn32(reg_addr); - else if (2 == bit_width) - *reg_val_p = FtIn16(reg_addr); - else if (1 == bit_width) - *reg_val_p = FtIn8(reg_addr); - - if (1 < len) - { - FtDumpHexByte((u8 *)(uintptr)reg_addr, len); - } - - return 0; + if ((bit_width > 4) || (NULL == reg_val_p)) + { + return -1; + } + + if (4 == bit_width) + { + *reg_val_p = FtIn32(reg_addr); + } + else if (2 == bit_width) + { + *reg_val_p = FtIn16(reg_addr); + } + else if (1 == bit_width) + { + *reg_val_p = FtIn8(reg_addr); + } + + if (1 < len) + { + FtDumpHexByte((u8 *)(uintptr)reg_addr, len); + } + + return 0; } static void RwCmdUsage() { - printf("usage:\r\n"); - printf(" rw [-w|-r] address register_val \r\n"); - printf(" rw -w [bit width] [address] [value]: write bits to address with value\r\n"); - printf(" rw -r [bit width] [address] [cnt=1]: read bits from address and print, by default read 1 bits\r\n"); + printf("usage:\r\n"); + printf(" rw [-w|-r] address register_val \r\n"); + printf(" rw -w [bit width] [address] [value]: write bits to address with value\r\n"); + printf(" rw -r [bit width] [address] [cnt=1]: read bits from address and print, by default read 1 bits\r\n"); } static int RwCmdEntry(int argc, char *argv[]) { - int ret = 0; - u32 reg_addr = 0; - u32 reg_val = 0; - u32 bit_width = 0; - u32 read_cnt = 1; - - if (argc < 4) - { - RwCmdUsage(); - return -1; - } - - if (!strcmp(argv[1], "-w")) - { - if (argc < 5) - { - RwCmdUsage(); - return -2; - } - - bit_width = strtoul(argv[2], NULL, 0); - reg_addr = strtoul(argv[3], NULL, 0); - reg_val = strtoul(argv[4], NULL, 0); - ret = RwWriteRegister(reg_addr, reg_val, bit_width); - - if (0 != ret) - { - printf("write failed: %d\r\n", ret); - } - else - { - LSUserPrintf("set 0x%x = 0x%x\r\n", reg_addr, reg_val); - } - } - else if (!strcmp(argv[1], "-r")) - { - if (argc < 4) - { - RwCmdUsage(); - return -3; - } - - bit_width = strtoul(argv[2], NULL, 0); - reg_addr = strtoul(argv[3], NULL, 0); - reg_val = 0; - - if (argc = 4) - { - read_cnt = strtoul(argv[4], NULL, 0); - } - - ret = RwReadRegister(reg_addr, ®_val, bit_width, read_cnt); - - if (0 != ret) - { - printf("read failed: %d\r\n", ret); - } - else - { - LSUserPrintf("get 0x%x = 0x%x\r\n", reg_addr, reg_val); - LSUserSetResult(reg_val); - } - } - - return ret; + int ret = 0; + u32 reg_addr = 0; + u32 reg_val = 0; + u32 bit_width = 0; + u32 read_cnt = 1; + + if (argc < 4) + { + RwCmdUsage(); + return -1; + } + + if (!strcmp(argv[1], "-w")) + { + if (argc < 5) + { + RwCmdUsage(); + return -2; + } + + bit_width = strtoul(argv[2], NULL, 0); + reg_addr = strtoul(argv[3], NULL, 0); + reg_val = strtoul(argv[4], NULL, 0); + ret = RwWriteRegister(reg_addr, reg_val, bit_width); + + if (0 != ret) + { + printf("Write failed: %d.\r\n", ret); + } + else + { + LSUserPrintf("Set 0x%x = 0x%x.\r\n", reg_addr, reg_val); + } + } + else if (!strcmp(argv[1], "-r")) + { + if (argc < 4) + { + RwCmdUsage(); + return -3; + } + + bit_width = strtoul(argv[2], NULL, 0); + reg_addr = strtoul(argv[3], NULL, 0); + reg_val = 0; + + if (argc = 4) + { + read_cnt = strtoul(argv[4], NULL, 0); + } + + ret = RwReadRegister(reg_addr, ®_val, bit_width, read_cnt); + + if (0 != ret) + { + printf("Read failed: %d.\r\n", ret); + } + else + { + LSUserPrintf("Get 0x%x = 0x%x.\r\n", reg_addr, reg_val); + LSUserSetResult(reg_val); + } + } + + return ret; } SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), rw, RwCmdEntry, read or write register value); \ No newline at end of file diff --git a/third-party/letter-shell-3.1/port/cmd/cmd_sleep.c b/third-party/letter-shell-3.1/port/cmd/cmd_sleep.c index af1c27cf..bffd3262 100644 --- a/third-party/letter-shell-3.1/port/cmd/cmd_sleep.c +++ b/third-party/letter-shell-3.1/port/cmd/cmd_sleep.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: cmd_sleep.c * Date: 2022-02-24 18:24:53 * LastEditTime: 2022-03-21 17:04:10 - * Description:  This file is for - * - * Modify History: + * Description:  This file is for the sleep command functions + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/3/25 first release */ #include @@ -31,8 +32,8 @@ static void SleepCmdUsage() { - printf("usage:\r\n"); - printf(" sleep [-s | -m | -u] [num] \r\n"); + printf("usage:\r\n"); + printf(" sleep [-s | -m | -u] [num] \r\n"); printf(" sleep for num of seconds (-s), mill-seconds(-m), micro-seconds (-u)\r\n"); } @@ -42,21 +43,21 @@ static int SleepCmdEntry(int argc, char *argv[]) if (argc < 3) { - SleepCmdUsage(); + SleepCmdUsage(); return -1; - } + } - if(!strcmp(argv[1], "-s")) + if (!strcmp(argv[1], "-s")) { time = strtoul(argv[2], NULL, 0); fsleep_seconds(time); } - else if(!strcmp(argv[1], "-m")) + else if (!strcmp(argv[1], "-m")) { time = strtoul(argv[2], NULL, 0); fsleep_millisec(time); } - else if(!strcmp(argv[1], "-u")) + else if (!strcmp(argv[1], "-u")) { time = strtoul(argv[2], NULL, 0); fsleep_microsec(time); diff --git a/third-party/letter-shell-3.1/port/cmd/cmd_version.c b/third-party/letter-shell-3.1/port/cmd/cmd_version.c index 5a1c3eea..dd18ec17 100644 --- a/third-party/letter-shell-3.1/port/cmd/cmd_version.c +++ b/third-party/letter-shell-3.1/port/cmd/cmd_version.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: cmd_version.c * Date: 2022-02-24 18:24:53 * LastEditTime: 2022-03-21 17:04:14 - * Description:  This file is for - * - * Modify History: + * Description:  This file is for the version command functions + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/3/25 first release */ #include @@ -33,5 +34,5 @@ static int VersionCmdEntry(int argc, char *argv[]) LSUShowVersion(); return 0; } -SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), version, +SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), version, VersionCmdEntry, show version of cur shell); \ No newline at end of file diff --git a/third-party/letter-shell-3.1/port/pl011/fpl011_os_port.c b/third-party/letter-shell-3.1/port/pl011/fpl011_os_port.c index f80831f0..2e6c7e5e 100644 --- a/third-party/letter-shell-3.1/port/pl011/fpl011_os_port.c +++ b/third-party/letter-shell-3.1/port/pl011/fpl011_os_port.c @@ -1,24 +1,26 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: fpl011_os_port.c * Date: 2022-02-24 21:42:27 * LastEditTime: 2022-02-24 21:42:27 - * Description:  This file is for - * - * Modify History: - * Ver   Who        Date         Changes - * ----- ------     --------    -------------------------------------- + * Description:  This file is for letter shell port to serial pl011 + * + * Modify History: + * Ver   Who         Date         Changes + * ----- ------      --------    -------------------------------------- + * 1.0 huanghe 2022/4/21 first release + * 1.1 wangxiaodong 2022/6/20 improve functions,adapt E2000 */ @@ -35,15 +37,15 @@ static char data[64]; #ifdef CONFIG_DEFAULT_LETTER_SHELL_USE_UART1 -#define LETTER_SHELL_UART_ID UART1_ID + #define LETTER_SHELL_UART_ID UART1_ID #endif #ifdef CONFIG_DEFAULT_LETTER_SHELL_USE_UART0 -#define LETTER_SHELL_UART_ID UART0_ID + #define LETTER_SHELL_UART_ID UART0_ID #endif #ifdef CONFIG_DEFAULT_LETTER_SHELL_USE_UART2 -#define LETTER_SHELL_UART_ID UART2_ID + #define LETTER_SHELL_UART_ID UART2_ID #endif extern void FtFreertosUartIntrInit(FtFreertosUart *uart_p); @@ -56,7 +58,7 @@ extern void FtFreertosUartIntrInit(FtFreertosUart *uart_p); void LSUserShellWrite(char data) { // FtFreertosUartBlcokingSend(&os_uart1, &data, 1); - FPl011Send(&os_uart1.bsp_uart,&data, 1); + FPl011Send(&os_uart1.bsp_uart, &data, 1); } /** @@ -74,14 +76,14 @@ signed char LSUserShellRead(char *data) void LSSerialConfig(void) { - FtFreertosUartConfig config = + FtFreertosUartConfig config = { .uart_instance = LETTER_SHELL_UART_ID, /* select uart global object */ .isr_priority = IRQ_PRIORITY_VALUE_13, /* irq Priority */ - .isr_event_mask = (RTOS_UART_ISR_OEIM_MASK|RTOS_UART_ISR_BEIM_MASK|RTOS_UART_ISR_PEIM_MASK|RTOS_UART_ISR_FEIM_MASK|RTOS_UART_ISR_RTIM_MASK|RTOS_UART_ISR_RXIM_MASK), + .isr_event_mask = (RTOS_UART_ISR_OEIM_MASK | RTOS_UART_ISR_BEIM_MASK | RTOS_UART_ISR_PEIM_MASK | RTOS_UART_ISR_FEIM_MASK | RTOS_UART_ISR_RTIM_MASK | RTOS_UART_ISR_RXIM_MASK), .uart_baudrate = 115200 }; - FtFreertosUartInit(&os_uart1,&config); + FtFreertosUartInit(&os_uart1, &config); } void LSSerialWaitLoop(void) diff --git a/third-party/letter-shell-3.1/port/shell_port.c b/third-party/letter-shell-3.1/port/shell_port.c index 7c3fde20..bf8dc97d 100644 --- a/third-party/letter-shell-3.1/port/shell_port.c +++ b/third-party/letter-shell-3.1/port/shell_port.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: shell_port.c * Date: 2022-02-24 22:03:27 * LastEditTime: 2022-02-24 22:03:28 - * Description:  This file is for - * - * Modify History: + * Description:  This file is for the shell port related functions + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/3/25 first release */ #include "shell.h" @@ -40,7 +41,7 @@ extern void LSSerialConfig(); extern void LSSerialWaitLoop(); -void LSUserShellTaskCreate( void * args) +void LSUserShellTaskCreate(void *args) { BaseType_t ret; LSSerialConfig(); @@ -50,14 +51,14 @@ void LSUserShellTaskCreate( void * args) shellInit(&shell_object, shell_buffer, 4096); - ret = xTaskCreate((TaskFunction_t )LSSerialWaitLoop, /* 任务入口函数 */ - (const char* )"LSSerialWaitLoop",/* 任务名字 */ - (uint16_t )1024, /* 任务栈大小 */ - (void* )NULL,/* 任务入口函数参数 */ - (UBaseType_t )2, /* 任务的优先级 */ - NULL); /* 任务控制块指针 */ + ret = xTaskCreate((TaskFunction_t)LSSerialWaitLoop, /* 任务入口函数 */ + (const char *)"LSSerialWaitLoop",/* 任务名字 */ + (uint16_t)1024, /* 任务栈大小 */ + (void *)NULL,/* 任务入口函数参数 */ + (UBaseType_t)2, /* 任务的优先级 */ + NULL); /* 任务控制块指针 */ - FASSERT_MSG(ret == pdPASS,"LSUserShellTask create is failed"); + FASSERT_MSG(ret == pdPASS, "LSUserShellTask create is failed"); vTaskDelete(NULL); } @@ -69,12 +70,12 @@ void LSUserShellTaskCreate( void * args) */ BaseType_t LSUserShellTask(void) { - return xTaskCreate((TaskFunction_t )LSUserShellTaskCreate, /* 任务入口函数 */ - (const char* )"LSUserShellTaskCreate",/* 任务名字 */ - (uint16_t )1024, /* 任务栈大小 */ - (void* )NULL,/* 任务入口函数参数 */ - (UBaseType_t )2, /* 任务的优先级 */ - NULL); /* 任务控制块指针 */ + return xTaskCreate((TaskFunction_t)LSUserShellTaskCreate, /* 任务入口函数 */ + (const char *)"LSUserShellTaskCreate",/* 任务名字 */ + (uint16_t)1024, /* 任务栈大小 */ + (void *)NULL,/* 任务入口函数参数 */ + (UBaseType_t)2, /* 任务的优先级 */ + NULL); /* 任务控制块指针 */ } @@ -91,7 +92,7 @@ int LSUserGetLastRet(void) /** * @name: 通过letter shell执行一行命令 - * @msg: + * @msg: * @return {*} * @param {char} *cmd */ diff --git a/third-party/letter-shell-3.1/port/shell_port.h b/third-party/letter-shell-3.1/port/shell_port.h index 744d08d7..dc680467 100644 --- a/third-party/letter-shell-3.1/port/shell_port.h +++ b/third-party/letter-shell-3.1/port/shell_port.h @@ -1,35 +1,41 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: shell_port.h * Date: 2022-02-24 22:03:34 * LastEditTime: 2022-02-24 22:03:34 - * Description:  This file is for - * - * Modify History: + * Description:  This file is for the shell port related functions definition + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/3/25 first release */ -#ifndef THIRD_LETTER_SHELL_OS_PORT_H -#define THIRD_LETTER_SHELL_OS_PORT_H +#ifndef SHELL_PORT_H +#define SHELL_PORT_H #include "shell.h" #include "ftypes.h" #include "FreeRTOS.h" #include "task.h" +#ifdef __cplusplus +extern "C" +{ +#endif + extern Shell shell; BaseType_t LSUserShellTask(void); void LSUserExec(const char *cmd); @@ -45,4 +51,8 @@ void LSUShowVersion(void); printf(format, ##__VA_ARGS__); \ } +#ifdef __cplusplus +} +#endif + #endif diff --git a/third-party/lwip-2.1.2/FILES b/third-party/lwip-2.1.2/FILES deleted file mode 100644 index 0be0741d..00000000 --- a/third-party/lwip-2.1.2/FILES +++ /dev/null @@ -1,15 +0,0 @@ -api/ - The code for the high-level wrapper API. Not needed if - you use the lowel-level call-back/raw API. - -apps/ - Higher layer applications that are specifically programmed - with the lwIP low-level raw API. - -core/ - The core of the TPC/IP stack; protocol implementations, - memory and buffer management, and the low-level raw API. - -include/ - lwIP include files. - -netif/ - Generic network interface device drivers are kept here. - -For more information on the various subdirectories, check the FILES -file in each directory. diff --git a/third-party/lwip-2.1.2/Kconfig b/third-party/lwip-2.1.2/Kconfig index 4109d99d..da113996 100644 --- a/third-party/lwip-2.1.2/Kconfig +++ b/third-party/lwip-2.1.2/Kconfig @@ -1,981 +1,94 @@ -menu "LWIP Configuration" - source "$(FREERTOS_SDK_ROOT)/third-party/lwip-2.1.2/ports/Kconfig" - config LWIP_LOCAL_HOSTNAME - string "Local netif hostname" - default 'phytium' - help - The default name this device will report to other devices on the network. - -# Lwip Memory config - menu "memory configuration" - choice LWIP_USE_MEMORY_TYPE - prompt "Select memory type" - default LWIP_USE_MEM_POOL - help - If LWIP_USE_MEM_POOL is selected, MEMP_MEM_MALLOC will be activated. - If LWIP_USE_MEM_HEAP is selected ,lwip memory heap will be activated - - config LWIP_USE_MEM_POOL - bool "use mem pool" - config LWIP_USE_MEM_HEAP - bool "the size of the heap memory" - endchoice - - if LWIP_USE_MEM_HEAP - config MEM_SIZE - int "Memory pool Size (MB)" - range 1 16 - default 1 - endif - - if LWIP_USE_MEM_POOL - config MEMP_NUM_PBUF - int "the number of memp struct pbufs" - range 16 1024 - default 64 - endif - - config MEM_ALIGNMENT - int "alignment of the CPU" - range 16 1024 - default 64 - - endmenu - -# Network Interfaces options - menu "NETWORK_INTERFACE_OPTIONS" - config LWIP_NETIF_API - bool "Enable usage of standard POSIX APIs in LWIP" - default n - help - If this feature is enabled, standard POSIX APIs: if_indextoname(), if_nametoindex() - could be used to convert network interface index to name - - config LWIP_NETIF_STATUS_CALLBACK - bool "Enable status callback for network interfaces" - default n - help - Enable callbacks when the network interface is up/down and addresses are changed. - - endmenu +menu "LWIP Freertos Port Configuration" -# LOOPIF options - menu "LOOPIF" - menuconfig LWIP_NETIF_LOOPBACK - bool "Support per-interface loopback" - default y + choice LWIP_GMAC_CTRL_TYPE + prompt "Gmac Drivers" + default LWIP_FGMAC help - Enabling this option means that if a packet is sent with a destination - address equal to the interface's own IP address, it will "loop back" and - be received by this interface. - Disabling this option disables support of loopback interface in lwIP + Select Gmac Driver for Lwip - config LWIP_LOOPBACK_MAX_PBUFS - int "Max queued loopback packets per interface" - range 0 16 - default 8 - depends on LWIP_NETIF_LOOPBACK - help - Configure the maximum number of packets which can be queued for - loopback on a given interface. Reducing this number may cause packets - to be dropped, but will avoid filling memory with queued packet data. - endmenu -# SLIPIF options - - menu "SLIPIF" - menuconfig LWIP_SLIP_SUPPORT - bool "Enable SLIP support (new/experimental)" - default n - help - Enable SLIP stack. Now only SLIP over serial is possible. - - SLIP over serial support is experimental and unsupported. - - config LWIP_SLIP_DEBUG_ON - bool "Enable SLIP debug log output" - depends on LWIP_SLIP_SUPPORT - default n - help - Enable SLIP debug log output - endmenu - - menu "Pbuf options" - config PBUF_POOL_BUFSIZE - int "the size of each pbuf in the pbuf pool (KB)" - range 2 64 - default 2 - help - the size of each pbuf in the pbuf pool. The default is - designed to accommodate single full size TCP frame in one pbuf, including - TCP_MSS, IP header, and link header. - - endmenu + config LWIP_FXMAC + select FREERTOS_USE_XMAC + bool "FXMAC" + + config LWIP_FGMAC + select FREERTOS_USE_GMAC + bool "FGMAC" -# Internal Memory Pool Size - menu "Internal Memory Pool Sizes" + endchoice # LWIP_GMAC_CTRL_TYPE + source "$(STANDALONE_DIR)/third-party/lwip-2.1.2/Kconfig" - config PBUF_POOL_SIZE - int "the number of buffers in the pbuf pool (KB)" - default 1 - help - the number of buffers in the pbuf pool. - endmenu - - - config LWIP_MAX_SOCKETS - int "Max number of open sockets" - range 1 16 - default 10 - help - Sockets take up a certain amount of memory, and allowing fewer - sockets to be open at the same time conserves memory. Specify - the maximum amount of sockets here. The valid value is from 1 - to 16. - - menu "LWIP RAW API" - - config LWIP_MAX_RAW_PCBS - int "Maximum LWIP RAW PCBs" - range 1 1024 - default 16 - help - The maximum number of simultaneously active LWIP - RAW protocol control blocks. The practical maximum - limit is determined by available heap memory at runtime. - - endmenu # LWIP RAW API - - - menu "TCP" - - config LWIP_MAX_ACTIVE_TCP - int "Maximum active TCP Connections" - range 1 1024 - default 16 - help - The maximum number of simultaneously active TCP - connections. The practical maximum limit is - determined by available heap memory at runtime. - - Changing this value by itself does not substantially - change the memory usage of LWIP, except for preventing - new TCP connections after the limit is reached. - - config LWIP_MAX_LISTENING_TCP - int "Maximum listening TCP Connections" - range 1 1024 - default 16 - help - The maximum number of simultaneously listening TCP - connections. The practical maximum limit is - determined by available heap memory at runtime. - - Changing this value by itself does not substantially - change the memory usage of LWIP, except for preventing - new listening TCP connections after the limit is reached. - - config LWIP_TCP_HIGH_SPEED_RETRANSMISSION - bool "TCP high speed retransmissions" - default y - help - Speed up the TCP retransmission interval. If disabled, - it is recommended to change the number of SYN retransmissions to 6, - and TCP initial rto time to 3000. - - config LWIP_TCP_MAXRTX - int "Maximum number of retransmissions of data segments" - default 12 - range 3 12 - help - Set maximum number of retransmissions of data segments. - - config LWIP_TCP_SYNMAXRTX - int "Maximum number of retransmissions of SYN segments" - default 6 if !LWIP_TCP_HIGH_SPEED_RETRANSMISSION - default 12 if LWIP_TCP_HIGH_SPEED_RETRANSMISSION - range 3 12 - help - Set maximum number of retransmissions of SYN segments. - - config LWIP_TCP_MSS - int "Maximum Segment Size (MSS)" - default 1440 - range 536 1460 - help - Set maximum segment size for TCP transmission. - - Can be set lower to save RAM, the default value 1460(ipv4)/1440(ipv6) will give best throughput. - IPv4 TCP_MSS Range: 576 <= TCP_MSS <= 1460 - IPv6 TCP_MSS Range: 1220<= TCP_mSS <= 1440 - - config LWIP_TCP_TMR_INTERVAL - int "TCP timer interval(ms)" - default 250 - help - Set TCP timer interval in milliseconds. - - Can be used to speed connections on bad networks. - A lower value will redeliver unacked packets faster. - - config LWIP_TCP_MSL - int "Maximum segment lifetime (MSL)" - default 60000 - help - Set maximum segment lifetime in in milliseconds. - - config LWIP_TCP_SND_BUF_DEFAULT - int "Default send buffer size" - default 5744 # 4 * default MSS - range 2440 65535 if !LWIP_WND_SCALE - range 2440 1024000 if LWIP_WND_SCALE - help - Set default send buffer size for new TCP sockets. - - Per-socket send buffer size can be changed at runtime - with lwip_setsockopt(s, TCP_SNDBUF, ...). - - This value must be at least 2x the MSS size, and the default - is 4x the default MSS size. - - Setting a smaller default SNDBUF size can save some RAM, but - will decrease performance. - - config LWIP_TCP_WND_DEFAULT - int "Default receive window size" - default 5744 # 4 * default MSS - range 2440 65535 if !LWIP_WND_SCALE - range 2440 1024000 if LWIP_WND_SCALE + menu "Tcp/ip task resource configuration" + config LWIP_TCPIP_TASK_STACK_SIZE + int "TCP/IP Task Stack Size" + default 3072 + # for high log levels, tcpip_adapter API calls can end up + # a few calls deep and logging there can trigger a stack overflow + range 2048 65536 + help + Configure TCP/IP task stack size, used by LWIP to process multi-threaded TCP/IP operations. + Setting this stack too small will result in stack overflow crashes. + + config LWIP_TCPIP_TASK_PRIO + int "TCP/IP Task priority" + default 6 help - Set default TCP receive window size for new TCP sockets. - - Per-socket receive window size can be changed at runtime - with lwip_setsockopt(s, TCP_WINDOW, ...). - - Setting a smaller default receive window size can save some RAM, - but will significantly decrease performance. + Configure TCP/IP task priority, used by LWIP to process multi-threaded TCP/IP operations. - config LWIP_TCP_RECVMBOX_SIZE - int "Default TCP receive mail box size" - default 6 + config LWIP_TCPIP_RECVMBOX_SIZE + int "TCPIP task receive mail box size" + default 32 range 6 64 if !LWIP_WND_SCALE range 6 1024 if LWIP_WND_SCALE help - Set TCP receive mail box size. Generally bigger value means higher throughput - but more memory. The recommended value is: LWIP_TCP_WND_DEFAULT/TCP_MSS + 2, e.g. if - LWIP_TCP_WND_DEFAULT=14360, TCP_MSS=1436, then the recommended receive mail box size is - (14360/1436 + 2) = 12. - - TCP receive mail box is a per socket mail box, when the application receives packets - from TCP socket, LWIP core firstly posts the packets to TCP receive mail box and the - application then fetches the packets from mail box. It means LWIP can caches maximum - LWIP_TCP_RECCVMBOX_SIZE packets for each TCP socket, so the maximum possible cached TCP packets - for all TCP sockets is LWIP_TCP_RECCVMBOX_SIZE multiples the maximum TCP socket number. In other - words, the bigger LWIP_TCP_RECVMBOX_SIZE means more memory. - On the other hand, if the receiv mail box is too small, the mail box may be full. If the - mail box is full, the LWIP drops the packets. So generally we need to make sure the TCP - receive mail box is big enough to avoid packet drop between LWIP core and application. + Set TCPIP task receive mail box size. Generally bigger value means higher throughput + but more memory. The value should be bigger than UDP/TCP mail box size. + endmenu - config LWIP_TCP_QUEUE_OOSEQ - bool "Queue incoming out-of-order segments" + + menu "lwip port thread Configuration" + config LWIP_PORT_USE_RECEIVE_THREAD + bool "Use Rx Thread" default y - help - Queue incoming out-of-order segments for later use. - - Disable this option to save some RAM during TCP sessions, at the expense - of increased retransmissions if segments arrive out of order. - - config LWIP_TCP_SACK_OUT - bool "Support sending selective acknowledgements" - default n - depends on LWIP_TCP_QUEUE_OOSEQ - help - TCP will support sending selective acknowledgements (SACKs). - - - choice LWIP_TCP_OVERSIZE - prompt "Pre-allocate transmit PBUF size" - default LWIP_TCP_OVERSIZE_MSS - help - Allows enabling "oversize" allocation of TCP transmission pbufs ahead of time, - which can reduce the length of pbuf chains used for transmission. - - This will not make a difference to sockets where Nagle's algorithm - is disabled. - - Default value of MSS is fine for most applications, 25% MSS may save - some RAM when only transmitting small amounts of data. Disabled will - have worst performance and fragmentation characteristics, but uses - least RAM overall. - - config LWIP_TCP_OVERSIZE_MSS - bool "MSS" - config LWIP_TCP_OVERSIZE_QUARTER_MSS - bool "25% MSS" - config LWIP_TCP_OVERSIZE_DISABLE - bool "Disabled" - - endchoice - endmenu # TCP - - menu "UDP" - - config LWIP_MAX_UDP_PCBS - int "Maximum active UDP control blocks" - range 1 1024 - default 16 - help - The maximum number of active UDP "connections" (ie - UDP sockets sending/receiving data). - The practical maximum limit is determined by available - heap memory at runtime. - - config LWIP_UDP_RECVMBOX_SIZE - int "Default UDP receive mail box size" - default 6 - range 6 64 - help - Set UDP receive mail box size. The recommended value is 6. - - UDP receive mail box is a per socket mail box, when the application receives packets - from UDP socket, LWIP core firstly posts the packets to UDP receive mail box and the - application then fetches the packets from mail box. It means LWIP can caches maximum - UDP_RECCVMBOX_SIZE packets for each UDP socket, so the maximum possible cached UDP packets - for all UDP sockets is UDP_RECCVMBOX_SIZE multiples the maximum UDP socket number. In other - words, the bigger UDP_RECVMBOX_SIZE means more memory. - On the other hand, if the receiv mail box is too small, the mail box may be full. If the - mail box is full, the LWIP drops the packets. So generally we need to make sure the UDP - receive mail box is big enough to avoid packet drop between LWIP core and application. - - - # UDP options - config LWIP_NETBUF_RECVINFO - bool "Enable IP_PKTINFO option" - default n - help - Enabling this option allows checking for the destination address - of a received IPv4 Packet. - - - endmenu # UDP - -# IP options - menu "IPv4" - config USE_IPV4_ONLY - bool "Only use IPv4 packets" - default n - help - If this switch is enabled, ipv6 cannot be used simultaneously - config LWIP_IP4_REASSEMBLY - bool "Enable reassembly incoming fragmented IP4 packets" - default n - help - Enabling this option allows reassemblying incoming fragmented IP4 packets. - - config LWIP_IP4_FRAG - bool "Enable fragment outgoing IP4 packets" - default y - help - Enabling this option allows fragmenting outgoing IP4 packets if their size - exceeds MTU. - - config LWIP_IP_FORWARD - bool "Enable IP forwarding" - default n - help - Enabling this option allows packets forwarding across multiple interfaces. - - config LWIP_IPV4_NAPT - bool "Enable NAT (new/experimental)" - depends on LWIP_IP_FORWARD - select LWIP_L2_TO_L3_COPY - default n - help - Enabling this option allows Network Address and Port Translation. - - config IP_REASS_MAX_PBUFS - int "Total maximum amount of pbufs waiting to be reassembled" - default 16 - range 1 45 - help - Total maximum amount of pbufs waiting to be reassembled. - Since the received pbufs are enqueued, be sure to configure - PBUF_POOL_SIZE > IP_REASS_MAX_PBUFS so that the stack is still able to receive - packets even if the maximum amount of fragments is enqueued for reassembly! - - endmenu # IP - -# ICMP - menu "ICMP" - - config LWIP_ICMP - bool "ICMP: Enable ICMP" + if LWIP_PORT_USE_RECEIVE_THREAD + config LWIP_PORT_RECEIVE_THREAD_STACKSIZE + int "the stack size of the receive thread" + default 2048 if TARGET_ARMV8_AARCH64 + default 1024 + config LWIP_PORT_RECEIVE_THREAD_PRIORITY + int "the stack priority of the receive thread" + default 5 + endif + + config LWIP_PORT_USE_LINK_DETECT_THREAD + bool "Use Link detect Thread" default y - help - Enable ICMP module for check network stability - - config LWIP_MULTICAST_PING - bool "Respond to multicast pings" - default n - depends on LWIP_ICMP6 || LWIP_ICMP - - config LWIP_BROADCAST_PING - bool "Respond to broadcast pings" - default n - depends on LWIP_ICMP - - endmenu # ICMP - -# DHCP options - menu "DHCP" - config LWIP_DHCP_ENABLE - bool "Enable DHCP module." - default n - - config LWIP_DHCP_DOES_ARP_CHECK - bool "DHCP: Perform ARP check on any offered address" - default y - help - Enabling this option performs a check (via ARP request) if the offered IP address - is not already in use by another host on the network. - - config LWIP_DHCP_GET_NTP_SRV - bool "Request NTP servers from DHCP" - default n - help - If enabled, LWIP will add 'NTP' to Parameter-Request Option sent via DHCP-request. - DHCP server might reply with an NTP server address in option 42. - SNTP callback for such replies should be set accordingly (see sntp_servermode_dhcp() func.) - - config LWIP_DHCP_DISABLE_CLIENT_ID - bool "DHCP: Disable Use of HW address as client identification" - default n - help - This option could be used to disable DHCP client identification with its MAC address. - (Client id is used by DHCP servers to uniquely identify clients and are included - in the DHCP packets as an option 61) - Set this option to "y" in order to exclude option 61 from DHCP packets. - - config LWIP_DHCP_RESTORE_LAST_IP - bool "DHCP: Restore last IP obtained from DHCP server" - default n - help - When this option is enabled, DHCP client tries to re-obtain last valid IP address obtained from DHCP - server. Last valid DHCP configuration is stored in nvs and restored after reset/power-up. If IP is still - available, there is no need for sending discovery message to DHCP server and save some time. - - config LWIP_DHCP_MAX_NTP_SERVERS - int "Maximum number of NTP servers aquired via DHCP" - default 1 - range 1 16 - depends on LWIP_DHCP_GET_NTP_SRV - help - Set maximum number of NTP servers aquired via DHCP-offer. - Should be less or equal to "Maximum number of NTP servers", any extra servers would be just ignored. - - config LWIP_DHCP_OPTIONS_LEN - int "DHCP total option length" - default 68 if LWIP_DHCP_DISABLE_VENDOR_CLASS_ID - default 108 if !LWIP_DHCP_DISABLE_VENDOR_CLASS_ID - range 68 255 - help - Set total length of outgoing DHCP option msg. Generally bigger value means it can carry more - options and values. If your code meets LWIP_ASSERT due to option value is too long. - Please increase the LWIP_DHCP_OPTIONS_LEN value. - - - config LWIP_DHCP_DISABLE_VENDOR_CLASS_ID - bool "DHCP: Disable Use of vendor class identification" - default y - help - This option could be used to disable DHCP client vendor class identification. - Set this option to "y" in order to exclude option 60 from DHCP packets. - endmenu # DHCP - -# AUTOIP options + if LWIP_PORT_USE_LINK_DETECT_THREAD + config LWIP_PORT_LINK_DETECT_STACKSIZE + int "the stack size of the mac link detect thread" + default 2048 if TARGET_ARMV8_AARCH64 + default 1024 + config LWIP_PORT_LINK_DETECT_PRIORITY + int "the stack priority of the mac link detect thread" + default 5 + endif - menu "AUTOIP" - menuconfig LWIP_AUTOIP - bool "Enable IPV4 Link-Local Addressing (AUTOIP)" - default n - help - Enabling this option allows the device to self-assign an address - in the 169.256/16 range if none is assigned statically or via DHCP. - - See RFC 3927. - - config LWIP_AUTOIP_TRIES - int "DHCP Probes before self-assigning IPv4 LL address" - range 1 100 - default 2 - depends on LWIP_AUTOIP - help - DHCP client will send this many probes before self-assigning a - link local address. - - From LWIP help: "This can be set as low as 1 to get an AutoIP - address very quickly, but you should be prepared to handle a - changing IP address when DHCP overrides AutoIP." - - config LWIP_AUTOIP_MAX_CONFLICTS - int "Max IP conflicts before rate limiting" - range 1 100 - default 9 - depends on LWIP_AUTOIP - help - If the AUTOIP functionality detects this many IP conflicts while - self-assigning an address, it will go into a rate limited mode. - - config LWIP_AUTOIP_RATE_LIMIT_INTERVAL - int "Rate limited interval (seconds)" - range 5 120 - default 20 - depends on LWIP_AUTOIP - help - If rate limiting self-assignment requests, wait this long between - each request. - endmenu # AUTOIP - -# DNS options - menu "DNS" - config LWIP_DNS_SUPPORT_MDNS_QUERIES - bool "Enable mDNS queries in resolving host name" - default y - help - If this feature is enabled, standard API such as gethostbyname - support .local addresses by sending one shot multicast mDNS - query - endmenu # DNS - - -# TCP options - menu "TCP options" - config LWIP_TCP_WND_DEFAULT - int "Default receive window size" - default 5744 # 4 * default MSS - range 2440 65535 if !LWIP_WND_SCALE - range 2440 1024000 if LWIP_WND_SCALE - help - Set default TCP receive window size for new TCP sockets. - - Per-socket receive window size can be changed at runtime - with lwip_setsockopt(s, TCP_WINDOW, ...). - - Setting a smaller default receive window size can save some RAM, - but will significantly decrease performance. - - config LWIP_TCP_MAXRTX - int "Maximum number of retransmissions of data segments" - default 12 - range 3 12 - help - Set maximum number of retransmissions of data segments. - - config LWIP_TCP_SYNMAXRTX - int "Maximum number of retransmissions of SYN segments" - default 6 if !LWIP_TCP_HIGH_SPEED_RETRANSMISSION - default 12 if LWIP_TCP_HIGH_SPEED_RETRANSMISSION - range 3 12 - help - Set maximum number of retransmissions of SYN segments. - - config LWIP_TCP_QUEUE_OOSEQ - bool "Queue incoming out-of-order segments" - default y - help - Queue incoming out-of-order segments for later use. - - Disable this option to save some RAM during TCP sessions, at the expense - of increased retransmissions if segments arrive out of order. - - - config LWIP_TCP_SACK_OUT - bool "Support sending selective acknowledgements" - default n - depends on LWIP_TCP_QUEUE_OOSEQ - help - TCP will support sending selective acknowledgements (SACKs). - - config LWIP_TCP_MSS - int "Maximum Segment Size (MSS)" - default 1440 - range 536 1460 - help - Set maximum segment size for TCP transmission. - - Can be set lower to save RAM, the default value 1460(ipv4)/1440(ipv6) will give best throughput. - IPv4 TCP_MSS Range: 576 <= TCP_MSS <= 1460 - IPv6 TCP_MSS Range: 1220<= TCP_mSS <= 1440 - - config LWIP_WND_SCALE - bool "Support TCP window scale" - depends on SPIRAM_TRY_ALLOCATE_WIFI_LWIP - default n - help - Enable this feature to support TCP window scaling. - - - config LWIP_TCP_SND_BUF_DEFAULT - int "Default send buffer size" - default 5744 # 4 * default MSS - range 2440 65535 if !LWIP_WND_SCALE - range 2440 1024000 if LWIP_WND_SCALE - help - Set default send buffer size for new TCP sockets. - - Per-socket send buffer size can be changed at runtime - with lwip_setsockopt(s, TCP_SNDBUF, ...). - - This value must be at least 2x the MSS size, and the default - is 4x the default MSS size. - - Setting a smaller default SNDBUF size can save some RAM, but - will decrease performance. - - config LWIP_TCP_RTO_TIME - int "Default TCP rto time" - default 3000 if !LWIP_TCP_HIGH_SPEED_RETRANSMISSION - default 1500 if LWIP_TCP_HIGH_SPEED_RETRANSMISSION - help - Set default TCP rto time for a reasonable initial rto. - In bad network environment, recommend set value of rto time to 1500. - endmenu # TCP options - -# Platform specific locking - - config LWIP_TCPIP_CORE_LOCKING - bool "Enable tcpip core locking" - default n - help - If Enable tcpip core locking,Creates a global mutex that is held - during TCPIP thread operations.Can be locked by client code to perform - lwIP operations without changing into TCPIP thread using callbacks. - See LOCK_TCPIP_CORE() and UNLOCK_TCPIP_CORE(). - - If disable tcpip core locking,TCP IP will perform tasks through context switching. - - -# socket - menu "socket" - config LWIP_SO_LINGER - bool "Enable SO_LINGER processing" - default n - help - Enabling this option allows SO_LINGER processing. - l_onoff = 1,l_linger can set the timeout. - - If l_linger=0, When a connection is closed, TCP will terminate the connection. - This means that TCP will discard any data packets stored in the socket send buffer - and send an RST to the peer. - - If l_linger!=0,Then closesocket() calls to block the process until - the remaining data packets has been sent or timed out. - - config LWIP_SO_REUSE - bool "Enable SO_REUSEADDR option" - default y - help - Enabling this option allows binding to a port which remains in - TIME_WAIT. - - config LWIP_SO_REUSE_RXTOALL - bool "SO_REUSEADDR copies broadcast/multicast to all matches" - depends on LWIP_SO_REUSE - default y - help - Enabling this option means that any incoming broadcast or multicast - packet will be copied to all of the local sockets that it matches - (may be more than one if SO_REUSEADDR is set on the socket.) - - This increases memory overhead as the packets need to be copied, - however they are only copied per matching socket. You can safely - disable it if you don't plan to receive broadcast or multicast - traffic on more than one socket at a time. - endmenu # TCP options - -# Statistics options - config LWIP_STATS - bool "Enable LWIP statistics" - default n - help - Enabling this option allows LWIP statistics - - -# PPP options - menu "PPP" - menuconfig LWIP_PPP_SUPPORT - bool "Enable PPP support (new/experimental)" - default n - help - Enable PPP stack. Now only PPP over serial is possible. - - PPP over serial support is experimental and unsupported. - - config LWIP_PPP_ENABLE_IPV6 - bool "Enable IPV6 support for PPP connections (IPV6CP)" - depends on LWIP_PPP_SUPPORT && LWIP_IPV6 - default y - help - Enable IPV6 support in PPP for the local link between the DTE (processor) and DCE (modem). - There are some modems which do not support the IPV6 addressing in the local link. - If they are requested for IPV6CP negotiation, they may time out. - This would in turn fail the configuration for the whole link. - If your modem is not responding correctly to PPP Phase Network, try to disable IPV6 support. - - config LWIP_IPV6_MEMP_NUM_ND6_QUEUE - int "Max number of IPv6 packets to queue during MAC resolution" - depends on LWIP_IPV6 - range 3 20 - default 3 - help - Config max number of IPv6 packets to queue during MAC resolution. - - config LWIP_IPV6_ND6_NUM_NEIGHBORS - int "Max number of entries in IPv6 neighbor cache" - depends on LWIP_IPV6 - range 3 10 - default 5 - help - Config max number of entries in IPv6 neighbor cache - - config LWIP_PPP_NOTIFY_PHASE_SUPPORT - bool "Enable Notify Phase Callback" - depends on LWIP_PPP_SUPPORT - default n - help - Enable to set a callback which is called on change of the internal PPP state machine. - - config LWIP_PPP_PAP_SUPPORT - bool "Enable PAP support" - depends on LWIP_PPP_SUPPORT - default n - help - Enable Password Authentication Protocol (PAP) support - - config LWIP_PPP_CHAP_SUPPORT - bool "Enable CHAP support" - depends on LWIP_PPP_SUPPORT - default n - help - Enable Challenge Handshake Authentication Protocol (CHAP) support - - config LWIP_PPP_MSCHAP_SUPPORT - bool "Enable MSCHAP support" - depends on LWIP_PPP_SUPPORT - default n - help - Enable Microsoft version of the Challenge-Handshake Authentication Protocol (MSCHAP) support - - config LWIP_PPP_MPPE_SUPPORT - bool "Enable MPPE support" - depends on LWIP_PPP_SUPPORT - default n - help - Enable Microsoft Point-to-Point Encryption (MPPE) support - - config LWIP_ENABLE_LCP_ECHO - bool "Enable LCP ECHO" - depends on LWIP_PPP_SUPPORT - default n - help - Enable LCP echo keepalive requests - - config LWIP_LCP_ECHOINTERVAL - int "Echo interval (s)" - range 0 1000000 - depends on LWIP_ENABLE_LCP_ECHO - default 3 - help - Interval in seconds between keepalive LCP echo requests, 0 to disable. - - config LWIP_LCP_MAXECHOFAILS - int "Maximum echo failures" - range 0 100000 - depends on LWIP_ENABLE_LCP_ECHO - default 3 - help - Number of consecutive unanswered echo requests before failure is indicated. - - config LWIP_PPP_DEBUG_ON - bool "Enable PPP debug log output" - depends on LWIP_PPP_SUPPORT - default n - help - Enable PPP debug log output - endmenu # PPP - -# Checksums - - menu "Checksums" - - config LWIP_CHECKSUM_CHECK_IP - bool "Enable LWIP IP checksums" - default n - help - Enable checksum checking for received IP messages - - config LWIP_CHECKSUM_CHECK_UDP - bool "Enable LWIP UDP checksums" - default n - help - Enable checksum checking for received UDP messages - - config LWIP_CHECKSUM_CHECK_ICMP - bool "Enable LWIP ICMP checksums" + config LWIP_PORT_DHCP_THREAD + bool "Use dhcp thread" default y - help - Enable checksum checking for received ICMP messages - - endmenu # Checksums - -# ipv6 - menu "ipv6" - config LWIP_IPV6 - bool "Enable IPv6" - default y - help - Enable IPv6 function. If not use IPv6 function, set this option to n. - If disabling LWIP_IPV6 then some other components (coap and asio) will - no longer be available. - - config LWIP_IPV6_AUTOCONFIG - bool "Enable IPV6 stateless address autoconfiguration (SLAAC)" - depends on LWIP_IPV6 - default n - help - Enabling this option allows the devices to IPV6 stateless address autoconfiguration (SLAAC). - - See RFC 4862. - - config LWIP_IPV6_NUM_ADDRESSES - int "Number of IPv6 addresses on each network interface" - depends on LWIP_IPV6 - default 3 - help - The maximum number of IPv6 addresses on each interface. Any additional - addresses will be discarded. - - config LWIP_IPV6_FORWARD - bool "Enable IPv6 forwarding between interfaces" - depends on LWIP_IPV6 - default n - help - Forwarding IPv6 packets between interfaces is only required when acting as - a router. - - config LWIP_IPV6_RDNSS_MAX_DNS_SERVERS - int "Use IPv6 Router Advertisement Recursive DNS Server Option" - depends on LWIP_IPV6_AUTOCONFIG - default 0 - help - Use IPv6 Router Advertisement Recursive DNS Server Option (as per RFC 6106) to - copy a defined maximum number of DNS servers to the DNS module. - Set this option to a number of desired DNS servers advertised in the RA protocol. - This feature is disabled when set to 0. - - config LWIP_IPV6_DHCP6 - bool "Enable DHCPv6 stateless address autoconfiguration" - depends on LWIP_IPV6_AUTOCONFIG - default n - help - Enable DHCPv6 for IPv6 stateless address autoconfiguration. - Note that the dhcpv6 client has to be started using dhcp6_enable_stateless(netif); - Note that the stateful address autoconfiguration is not supported. - - config LWIP_IP6_FRAG - bool "Enable fragment outgoing IP6 packets" - default y - depends on LWIP_IPV6 - help - Enabling this option allows fragmenting outgoing IP6 packets if their size - exceeds MTU. - - config LWIP_IP6_REASSEMBLY - bool "Enable reassembly incoming fragmented IP6 packets" - default n - depends on LWIP_IPV6 - help - Enabling this option allows reassemblying incoming fragmented IP6 packets. - endmenu - - - -#defbug - - menuconfig LWIP_DEBUG - bool "Enable LWIP Debug" - default n - help - Enabling this option allows different kinds of lwIP debug output. - - All lwIP debug features increase the size of the final binary. - - config LWIP_NETIF_DEBUG - bool "Enable netif debug messages" - depends on LWIP_DEBUG - default n - - config LWIP_PBUF_DEBUG - bool "Enable pbuf debug messages" - depends on LWIP_DEBUG - default n - - config LWIP_ETHARP_DEBUG - bool "Enable etharp debug messages" - depends on LWIP_DEBUG - default n - - config LWIP_API_LIB_DEBUG - bool "Enable api lib debug messages" - depends on LWIP_DEBUG - default n - - config LWIP_SOCKETS_DEBUG - bool "Enable socket debug messages" - depends on LWIP_DEBUG - default n - - config LWIP_IP_DEBUG - bool "Enable IP debug messages" - depends on LWIP_DEBUG - default n - - config LWIP_ICMP_DEBUG - bool "Enable ICMP debug messages" - depends on LWIP_DEBUG && LWIP_ICMP - default n - - config LWIP_DHCP_DEBUG - bool "Enable DHCP debug messages" - depends on LWIP_DEBUG - default n - - config LWIP_IP6_DEBUG - bool "Enable IP6 debug messages" - depends on LWIP_DEBUG - default n - - config LWIP_ICMP6_DEBUG - bool "Enable ICMP6 debug messages" - depends on LWIP_DEBUG - default n - - config LWIP_TCP_DEBUG - bool "Enable TCP debug messages" - depends on LWIP_DEBUG - default n - - config LWIP_SNTP_DEBUG - bool "Enable SNTP debug messages" - depends on LWIP_DEBUG - default n - - config LWIP_DNS_DEBUG - bool "Enable DNS debug messages" - depends on LWIP_DEBUG - default n + if LWIP_PORT_DHCP_THREAD + config LWIP_PORT_DHCP_STACKSIZE + int "the stack size of the dhcp thread" + default 4096 if TARGET_ARMV8_AARCH64 + default 2048 + config LWIP_PORT_DHCP_PRIORITY + int "the stack priority of the dhcp thread" + default 5 + endif + endmenu +endmenu \ No newline at end of file diff --git a/third-party/lwip-2.1.2/api/api_lib.c b/third-party/lwip-2.1.2/api/api_lib.c deleted file mode 100644 index e03b8b74..00000000 --- a/third-party/lwip-2.1.2/api/api_lib.c +++ /dev/null @@ -1,1367 +0,0 @@ -/** - * @file - * Sequential API External module - * - * @defgroup netconn Netconn API - * @ingroup sequential_api - * Thread-safe, to be called from non-TCPIP threads only. - * TX/RX handling based on @ref netbuf (containing @ref pbuf) - * to avoid copying data around. - * - * @defgroup netconn_common Common functions - * @ingroup netconn - * For use with TCP and UDP - * - * @defgroup netconn_tcp TCP only - * @ingroup netconn - * TCP only functions - * - * @defgroup netconn_udp UDP only - * @ingroup netconn - * UDP only functions - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - */ - -/* This is the part of the API that is linked with - the application */ - -#include "lwip/opt.h" - -#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/api.h" -#include "lwip/memp.h" - -#include "lwip/ip.h" -#include "lwip/raw.h" -#include "lwip/udp.h" -#include "lwip/priv/api_msg.h" -#include "lwip/priv/tcp_priv.h" -#include "lwip/priv/tcpip_priv.h" - -#ifdef LWIP_HOOK_FILENAME -#include LWIP_HOOK_FILENAME -#endif - -#include - -#define API_MSG_VAR_REF(name) API_VAR_REF(name) -#define API_MSG_VAR_DECLARE(name) API_VAR_DECLARE(struct api_msg, name) -#define API_MSG_VAR_ALLOC(name) API_VAR_ALLOC(struct api_msg, MEMP_API_MSG, name, ERR_MEM) -#define API_MSG_VAR_ALLOC_RETURN_NULL(name) API_VAR_ALLOC(struct api_msg, MEMP_API_MSG, name, NULL) -#define API_MSG_VAR_FREE(name) API_VAR_FREE(MEMP_API_MSG, name) - -#if TCP_LISTEN_BACKLOG -/* need to allocate API message for accept so empty message pool does not result in event loss - * see bug #47512: MPU_COMPATIBLE may fail on empty pool */ -#define API_MSG_VAR_ALLOC_ACCEPT(msg) API_MSG_VAR_ALLOC(msg) -#define API_MSG_VAR_FREE_ACCEPT(msg) API_MSG_VAR_FREE(msg) -#else /* TCP_LISTEN_BACKLOG */ -#define API_MSG_VAR_ALLOC_ACCEPT(msg) -#define API_MSG_VAR_FREE_ACCEPT(msg) -#endif /* TCP_LISTEN_BACKLOG */ - -#if LWIP_NETCONN_FULLDUPLEX -#define NETCONN_RECVMBOX_WAITABLE(conn) (sys_mbox_valid(&(conn)->recvmbox) && (((conn)->flags & NETCONN_FLAG_MBOXINVALID) == 0)) -#define NETCONN_ACCEPTMBOX_WAITABLE(conn) (sys_mbox_valid(&(conn)->acceptmbox) && (((conn)->flags & (NETCONN_FLAG_MBOXCLOSED|NETCONN_FLAG_MBOXINVALID)) == 0)) -#define NETCONN_MBOX_WAITING_INC(conn) SYS_ARCH_INC(conn->mbox_threads_waiting, 1) -#define NETCONN_MBOX_WAITING_DEC(conn) SYS_ARCH_DEC(conn->mbox_threads_waiting, 1) -#else /* LWIP_NETCONN_FULLDUPLEX */ -#define NETCONN_RECVMBOX_WAITABLE(conn) sys_mbox_valid(&(conn)->recvmbox) -#define NETCONN_ACCEPTMBOX_WAITABLE(conn) (sys_mbox_valid(&(conn)->acceptmbox) && (((conn)->flags & NETCONN_FLAG_MBOXCLOSED) == 0)) -#define NETCONN_MBOX_WAITING_INC(conn) -#define NETCONN_MBOX_WAITING_DEC(conn) -#endif /* LWIP_NETCONN_FULLDUPLEX */ - -static err_t netconn_close_shutdown(struct netconn *conn, u8_t how); - -/** - * Call the lower part of a netconn_* function - * This function is then running in the thread context - * of tcpip_thread and has exclusive access to lwIP core code. - * - * @param fn function to call - * @param apimsg a struct containing the function to call and its parameters - * @return ERR_OK if the function was called, another err_t if not - */ -static err_t -netconn_apimsg(tcpip_callback_fn fn, struct api_msg *apimsg) -{ - err_t err; - -#ifdef LWIP_DEBUG - /* catch functions that don't set err */ - apimsg->err = ERR_VAL; -#endif /* LWIP_DEBUG */ - -#if LWIP_NETCONN_SEM_PER_THREAD - apimsg->op_completed_sem = LWIP_NETCONN_THREAD_SEM_GET(); -#endif /* LWIP_NETCONN_SEM_PER_THREAD */ - - err = tcpip_send_msg_wait_sem(fn, apimsg, LWIP_API_MSG_SEM(apimsg)); - if (err == ERR_OK) { - return apimsg->err; - } - return err; -} - -/** - * Create a new netconn (of a specific type) that has a callback function. - * The corresponding pcb is also created. - * - * @param t the type of 'connection' to create (@see enum netconn_type) - * @param proto the IP protocol for RAW IP pcbs - * @param callback a function to call on status changes (RX available, TX'ed) - * @return a newly allocated struct netconn or - * NULL on memory error - */ -struct netconn * -netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, netconn_callback callback) -{ - struct netconn *conn; - API_MSG_VAR_DECLARE(msg); - API_MSG_VAR_ALLOC_RETURN_NULL(msg); - - conn = netconn_alloc(t, callback); - if (conn != NULL) { - err_t err; - - API_MSG_VAR_REF(msg).msg.n.proto = proto; - API_MSG_VAR_REF(msg).conn = conn; - err = netconn_apimsg(lwip_netconn_do_newconn, &API_MSG_VAR_REF(msg)); - if (err != ERR_OK) { - LWIP_ASSERT("freeing conn without freeing pcb", conn->pcb.tcp == NULL); - LWIP_ASSERT("conn has no recvmbox", sys_mbox_valid(&conn->recvmbox)); -#if LWIP_TCP - LWIP_ASSERT("conn->acceptmbox shouldn't exist", !sys_mbox_valid(&conn->acceptmbox)); -#endif /* LWIP_TCP */ -#if !LWIP_NETCONN_SEM_PER_THREAD - LWIP_ASSERT("conn has no op_completed", sys_sem_valid(&conn->op_completed)); - sys_sem_free(&conn->op_completed); -#endif /* !LWIP_NETCONN_SEM_PER_THREAD */ - sys_mbox_free(&conn->recvmbox); - memp_free(MEMP_NETCONN, conn); - API_MSG_VAR_FREE(msg); - return NULL; - } - } - API_MSG_VAR_FREE(msg); - return conn; -} - -/** - * @ingroup netconn_common - * Close a netconn 'connection' and free all its resources but not the netconn itself. - * UDP and RAW connection are completely closed, TCP pcbs might still be in a waitstate - * after this returns. - * - * @param conn the netconn to delete - * @return ERR_OK if the connection was deleted - */ -err_t -netconn_prepare_delete(struct netconn *conn) -{ - err_t err; - API_MSG_VAR_DECLARE(msg); - - /* No ASSERT here because possible to get a (conn == NULL) if we got an accept error */ - if (conn == NULL) { - return ERR_OK; - } - - API_MSG_VAR_ALLOC(msg); - API_MSG_VAR_REF(msg).conn = conn; -#if LWIP_SO_SNDTIMEO || LWIP_SO_LINGER - /* get the time we started, which is later compared to - sys_now() + conn->send_timeout */ - API_MSG_VAR_REF(msg).msg.sd.time_started = sys_now(); -#else /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */ -#if LWIP_TCP - API_MSG_VAR_REF(msg).msg.sd.polls_left = - ((LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT + TCP_SLOW_INTERVAL - 1) / TCP_SLOW_INTERVAL) + 1; -#endif /* LWIP_TCP */ -#endif /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */ - err = netconn_apimsg(lwip_netconn_do_delconn, &API_MSG_VAR_REF(msg)); - API_MSG_VAR_FREE(msg); - - if (err != ERR_OK) { - return err; - } - return ERR_OK; -} - -/** - * @ingroup netconn_common - * Close a netconn 'connection' and free its resources. - * UDP and RAW connection are completely closed, TCP pcbs might still be in a waitstate - * after this returns. - * - * @param conn the netconn to delete - * @return ERR_OK if the connection was deleted - */ -err_t -netconn_delete(struct netconn *conn) -{ - err_t err; - - /* No ASSERT here because possible to get a (conn == NULL) if we got an accept error */ - if (conn == NULL) { - return ERR_OK; - } - -#if LWIP_NETCONN_FULLDUPLEX - if (conn->flags & NETCONN_FLAG_MBOXINVALID) { - /* Already called netconn_prepare_delete() before */ - err = ERR_OK; - } else -#endif /* LWIP_NETCONN_FULLDUPLEX */ - { - err = netconn_prepare_delete(conn); - } - if (err == ERR_OK) { - netconn_free(conn); - } - return err; -} - -/** - * Get the local or remote IP address and port of a netconn. - * For RAW netconns, this returns the protocol instead of a port! - * - * @param conn the netconn to query - * @param addr a pointer to which to save the IP address - * @param port a pointer to which to save the port (or protocol for RAW) - * @param local 1 to get the local IP address, 0 to get the remote one - * @return ERR_CONN for invalid connections - * ERR_OK if the information was retrieved - */ -err_t -netconn_getaddr(struct netconn *conn, ip_addr_t *addr, u16_t *port, u8_t local) -{ - API_MSG_VAR_DECLARE(msg); - err_t err; - - LWIP_ERROR("netconn_getaddr: invalid conn", (conn != NULL), return ERR_ARG;); - LWIP_ERROR("netconn_getaddr: invalid addr", (addr != NULL), return ERR_ARG;); - LWIP_ERROR("netconn_getaddr: invalid port", (port != NULL), return ERR_ARG;); - - API_MSG_VAR_ALLOC(msg); - API_MSG_VAR_REF(msg).conn = conn; - API_MSG_VAR_REF(msg).msg.ad.local = local; -#if LWIP_MPU_COMPATIBLE - err = netconn_apimsg(lwip_netconn_do_getaddr, &API_MSG_VAR_REF(msg)); - *addr = msg->msg.ad.ipaddr; - *port = msg->msg.ad.port; -#else /* LWIP_MPU_COMPATIBLE */ - msg.msg.ad.ipaddr = addr; - msg.msg.ad.port = port; - err = netconn_apimsg(lwip_netconn_do_getaddr, &msg); -#endif /* LWIP_MPU_COMPATIBLE */ - API_MSG_VAR_FREE(msg); - - return err; -} - -/** - * @ingroup netconn_common - * Bind a netconn to a specific local IP address and port. - * Binding one netconn twice might not always be checked correctly! - * - * @param conn the netconn to bind - * @param addr the local IP address to bind the netconn to - * (use IP4_ADDR_ANY/IP6_ADDR_ANY to bind to all addresses) - * @param port the local port to bind the netconn to (not used for RAW) - * @return ERR_OK if bound, any other err_t on failure - */ -err_t -netconn_bind(struct netconn *conn, const ip_addr_t *addr, u16_t port) -{ - API_MSG_VAR_DECLARE(msg); - err_t err; - - LWIP_ERROR("netconn_bind: invalid conn", (conn != NULL), return ERR_ARG;); - -#if LWIP_IPV4 - /* Don't propagate NULL pointer (IP_ADDR_ANY alias) to subsequent functions */ - if (addr == NULL) { - addr = IP4_ADDR_ANY; - } -#endif /* LWIP_IPV4 */ - -#if LWIP_IPV4 && LWIP_IPV6 - /* "Socket API like" dual-stack support: If IP to bind to is IP6_ADDR_ANY, - * and NETCONN_FLAG_IPV6_V6ONLY is 0, use IP_ANY_TYPE to bind - */ - if ((netconn_get_ipv6only(conn) == 0) && - ip_addr_cmp(addr, IP6_ADDR_ANY)) { - addr = IP_ANY_TYPE; - } -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - - API_MSG_VAR_ALLOC(msg); - API_MSG_VAR_REF(msg).conn = conn; - API_MSG_VAR_REF(msg).msg.bc.ipaddr = API_MSG_VAR_REF(addr); - API_MSG_VAR_REF(msg).msg.bc.port = port; - err = netconn_apimsg(lwip_netconn_do_bind, &API_MSG_VAR_REF(msg)); - API_MSG_VAR_FREE(msg); - - return err; -} - -/** - * @ingroup netconn_common - * Bind a netconn to a specific interface and port. - * Binding one netconn twice might not always be checked correctly! - * - * @param conn the netconn to bind - * @param if_idx the local interface index to bind the netconn to - * @return ERR_OK if bound, any other err_t on failure - */ -err_t -netconn_bind_if(struct netconn *conn, u8_t if_idx) -{ - API_MSG_VAR_DECLARE(msg); - err_t err; - - LWIP_ERROR("netconn_bind_if: invalid conn", (conn != NULL), return ERR_ARG;); - - API_MSG_VAR_ALLOC(msg); - API_MSG_VAR_REF(msg).conn = conn; - API_MSG_VAR_REF(msg).msg.bc.if_idx = if_idx; - err = netconn_apimsg(lwip_netconn_do_bind_if, &API_MSG_VAR_REF(msg)); - API_MSG_VAR_FREE(msg); - - return err; -} - -/** - * @ingroup netconn_common - * Connect a netconn to a specific remote IP address and port. - * - * @param conn the netconn to connect - * @param addr the remote IP address to connect to - * @param port the remote port to connect to (no used for RAW) - * @return ERR_OK if connected, return value of tcp_/udp_/raw_connect otherwise - */ -err_t -netconn_connect(struct netconn *conn, const ip_addr_t *addr, u16_t port) -{ - API_MSG_VAR_DECLARE(msg); - err_t err; - - LWIP_ERROR("netconn_connect: invalid conn", (conn != NULL), return ERR_ARG;); - -#if LWIP_IPV4 - /* Don't propagate NULL pointer (IP_ADDR_ANY alias) to subsequent functions */ - if (addr == NULL) { - addr = IP4_ADDR_ANY; - } -#endif /* LWIP_IPV4 */ - - API_MSG_VAR_ALLOC(msg); - API_MSG_VAR_REF(msg).conn = conn; - API_MSG_VAR_REF(msg).msg.bc.ipaddr = API_MSG_VAR_REF(addr); - API_MSG_VAR_REF(msg).msg.bc.port = port; - err = netconn_apimsg(lwip_netconn_do_connect, &API_MSG_VAR_REF(msg)); - API_MSG_VAR_FREE(msg); - - return err; -} - -/** - * @ingroup netconn_udp - * Disconnect a netconn from its current peer (only valid for UDP netconns). - * - * @param conn the netconn to disconnect - * @return See @ref err_t - */ -err_t -netconn_disconnect(struct netconn *conn) -{ - API_MSG_VAR_DECLARE(msg); - err_t err; - - LWIP_ERROR("netconn_disconnect: invalid conn", (conn != NULL), return ERR_ARG;); - - API_MSG_VAR_ALLOC(msg); - API_MSG_VAR_REF(msg).conn = conn; - err = netconn_apimsg(lwip_netconn_do_disconnect, &API_MSG_VAR_REF(msg)); - API_MSG_VAR_FREE(msg); - - return err; -} - -/** - * @ingroup netconn_tcp - * Set a TCP netconn into listen mode - * - * @param conn the tcp netconn to set to listen mode - * @param backlog the listen backlog, only used if TCP_LISTEN_BACKLOG==1 - * @return ERR_OK if the netconn was set to listen (UDP and RAW netconns - * don't return any error (yet?)) - */ -err_t -netconn_listen_with_backlog(struct netconn *conn, u8_t backlog) -{ -#if LWIP_TCP - API_MSG_VAR_DECLARE(msg); - err_t err; - - /* This does no harm. If TCP_LISTEN_BACKLOG is off, backlog is unused. */ - LWIP_UNUSED_ARG(backlog); - - LWIP_ERROR("netconn_listen: invalid conn", (conn != NULL), return ERR_ARG;); - - API_MSG_VAR_ALLOC(msg); - API_MSG_VAR_REF(msg).conn = conn; -#if TCP_LISTEN_BACKLOG - API_MSG_VAR_REF(msg).msg.lb.backlog = backlog; -#endif /* TCP_LISTEN_BACKLOG */ - err = netconn_apimsg(lwip_netconn_do_listen, &API_MSG_VAR_REF(msg)); - API_MSG_VAR_FREE(msg); - - return err; -#else /* LWIP_TCP */ - LWIP_UNUSED_ARG(conn); - LWIP_UNUSED_ARG(backlog); - return ERR_ARG; -#endif /* LWIP_TCP */ -} - -/** - * @ingroup netconn_tcp - * Accept a new connection on a TCP listening netconn. - * - * @param conn the TCP listen netconn - * @param new_conn pointer where the new connection is stored - * @return ERR_OK if a new connection has been received or an error - * code otherwise - */ -err_t -netconn_accept(struct netconn *conn, struct netconn **new_conn) -{ -#if LWIP_TCP - err_t err; - void *accept_ptr; - struct netconn *newconn; -#if TCP_LISTEN_BACKLOG - API_MSG_VAR_DECLARE(msg); -#endif /* TCP_LISTEN_BACKLOG */ - - LWIP_ERROR("netconn_accept: invalid pointer", (new_conn != NULL), return ERR_ARG;); - *new_conn = NULL; - LWIP_ERROR("netconn_accept: invalid conn", (conn != NULL), return ERR_ARG;); - - /* NOTE: Although the opengroup spec says a pending error shall be returned to - send/recv/getsockopt(SO_ERROR) only, we return it for listening - connections also, to handle embedded-system errors */ - err = netconn_err(conn); - if (err != ERR_OK) { - /* return pending error */ - return err; - } - if (!NETCONN_ACCEPTMBOX_WAITABLE(conn)) { - /* don't accept if closed: this might block the application task - waiting on acceptmbox forever! */ - return ERR_CLSD; - } - - API_MSG_VAR_ALLOC_ACCEPT(msg); - - NETCONN_MBOX_WAITING_INC(conn); - if (netconn_is_nonblocking(conn)) { - if (sys_arch_mbox_tryfetch(&conn->acceptmbox, &accept_ptr) == SYS_ARCH_TIMEOUT) { - API_MSG_VAR_FREE_ACCEPT(msg); - NETCONN_MBOX_WAITING_DEC(conn); - return ERR_WOULDBLOCK; - } - } else { -#if LWIP_SO_RCVTIMEO - if (sys_arch_mbox_fetch(&conn->acceptmbox, &accept_ptr, conn->recv_timeout) == SYS_ARCH_TIMEOUT) { - API_MSG_VAR_FREE_ACCEPT(msg); - NETCONN_MBOX_WAITING_DEC(conn); - return ERR_TIMEOUT; - } -#else - sys_arch_mbox_fetch(&conn->acceptmbox, &accept_ptr, 0); -#endif /* LWIP_SO_RCVTIMEO*/ - } - NETCONN_MBOX_WAITING_DEC(conn); -#if LWIP_NETCONN_FULLDUPLEX - if (conn->flags & NETCONN_FLAG_MBOXINVALID) { - if (lwip_netconn_is_deallocated_msg(accept_ptr)) { - /* the netconn has been closed from another thread */ - API_MSG_VAR_FREE_ACCEPT(msg); - return ERR_CONN; - } - } -#endif - - /* Register event with callback */ - API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0); - - if (lwip_netconn_is_err_msg(accept_ptr, &err)) { - /* a connection has been aborted: e.g. out of pcbs or out of netconns during accept */ - API_MSG_VAR_FREE_ACCEPT(msg); - return err; - } - if (accept_ptr == NULL) { - /* connection has been aborted */ - API_MSG_VAR_FREE_ACCEPT(msg); - return ERR_CLSD; - } - newconn = (struct netconn *)accept_ptr; -#if TCP_LISTEN_BACKLOG - /* Let the stack know that we have accepted the connection. */ - API_MSG_VAR_REF(msg).conn = newconn; - /* don't care for the return value of lwip_netconn_do_recv */ - netconn_apimsg(lwip_netconn_do_accepted, &API_MSG_VAR_REF(msg)); - API_MSG_VAR_FREE(msg); -#endif /* TCP_LISTEN_BACKLOG */ - - *new_conn = newconn; - /* don't set conn->last_err: it's only ERR_OK, anyway */ - return ERR_OK; -#else /* LWIP_TCP */ - LWIP_UNUSED_ARG(conn); - LWIP_UNUSED_ARG(new_conn); - return ERR_ARG; -#endif /* LWIP_TCP */ -} - -/** - * @ingroup netconn_common - * Receive data: actual implementation that doesn't care whether pbuf or netbuf - * is received (this is internal, it's just here for describing common errors) - * - * @param conn the netconn from which to receive data - * @param new_buf pointer where a new pbuf/netbuf is stored when received data - * @param apiflags flags that control function behaviour. For now only: - * - NETCONN_DONTBLOCK: only read data that is available now, don't wait for more data - * @return ERR_OK if data has been received, an error code otherwise (timeout, - * memory error or another error) - * ERR_CONN if not connected - * ERR_CLSD if TCP connection has been closed - * ERR_WOULDBLOCK if the netconn is nonblocking but would block to wait for data - * ERR_TIMEOUT if the netconn has a receive timeout and no data was received - */ -static err_t -netconn_recv_data(struct netconn *conn, void **new_buf, u8_t apiflags) -{ - void *buf = NULL; - u16_t len; - - LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;); - *new_buf = NULL; - LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL), return ERR_ARG;); - - if (!NETCONN_RECVMBOX_WAITABLE(conn)) { - err_t err = netconn_err(conn); - if (err != ERR_OK) { - /* return pending error */ - return err; - } - return ERR_CONN; - } - - NETCONN_MBOX_WAITING_INC(conn); - if (netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK) || - (conn->flags & NETCONN_FLAG_MBOXCLOSED) || (conn->pending_err != ERR_OK)) { - if (sys_arch_mbox_tryfetch(&conn->recvmbox, &buf) == SYS_ARCH_TIMEOUT) { - err_t err; - NETCONN_MBOX_WAITING_DEC(conn); - err = netconn_err(conn); - if (err != ERR_OK) { - /* return pending error */ - return err; - } - if (conn->flags & NETCONN_FLAG_MBOXCLOSED) { - return ERR_CONN; - } - return ERR_WOULDBLOCK; - } - } else { -#if LWIP_SO_RCVTIMEO - if (sys_arch_mbox_fetch(&conn->recvmbox, &buf, conn->recv_timeout) == SYS_ARCH_TIMEOUT) { - NETCONN_MBOX_WAITING_DEC(conn); - return ERR_TIMEOUT; - } -#else - sys_arch_mbox_fetch(&conn->recvmbox, &buf, 0); -#endif /* LWIP_SO_RCVTIMEO*/ - } - NETCONN_MBOX_WAITING_DEC(conn); -#if LWIP_NETCONN_FULLDUPLEX - if (conn->flags & NETCONN_FLAG_MBOXINVALID) { - if (lwip_netconn_is_deallocated_msg(buf)) { - /* the netconn has been closed from another thread */ - API_MSG_VAR_FREE_ACCEPT(msg); - return ERR_CONN; - } - } -#endif - -#if LWIP_TCP -#if (LWIP_UDP || LWIP_RAW) - if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) -#endif /* (LWIP_UDP || LWIP_RAW) */ - { - err_t err; - /* Check if this is an error message or a pbuf */ - if (lwip_netconn_is_err_msg(buf, &err)) { - /* new_buf has been zeroed above already */ - if (err == ERR_CLSD) { - /* connection closed translates to ERR_OK with *new_buf == NULL */ - return ERR_OK; - } - return err; - } - len = ((struct pbuf *)buf)->tot_len; - } -#endif /* LWIP_TCP */ -#if LWIP_TCP && (LWIP_UDP || LWIP_RAW) - else -#endif /* LWIP_TCP && (LWIP_UDP || LWIP_RAW) */ -#if (LWIP_UDP || LWIP_RAW) - { - LWIP_ASSERT("buf != NULL", buf != NULL); - len = netbuf_len((struct netbuf *)buf); - } -#endif /* (LWIP_UDP || LWIP_RAW) */ - -#if LWIP_SO_RCVBUF - SYS_ARCH_DEC(conn->recv_avail, len); -#endif /* LWIP_SO_RCVBUF */ - /* Register event with callback */ - API_EVENT(conn, NETCONN_EVT_RCVMINUS, len); - - LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_recv_data: received %p, len=%"U16_F"\n", buf, len)); - - *new_buf = buf; - /* don't set conn->last_err: it's only ERR_OK, anyway */ - return ERR_OK; -} - -#if LWIP_TCP -static err_t -netconn_tcp_recvd_msg(struct netconn *conn, size_t len, struct api_msg *msg) -{ - LWIP_ERROR("netconn_recv_tcp_pbuf: invalid conn", (conn != NULL) && - NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP, return ERR_ARG;); - - msg->conn = conn; - msg->msg.r.len = len; - - return netconn_apimsg(lwip_netconn_do_recv, msg); -} - -err_t -netconn_tcp_recvd(struct netconn *conn, size_t len) -{ - err_t err; - API_MSG_VAR_DECLARE(msg); - LWIP_ERROR("netconn_recv_tcp_pbuf: invalid conn", (conn != NULL) && - NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP, return ERR_ARG;); - - API_MSG_VAR_ALLOC(msg); - err = netconn_tcp_recvd_msg(conn, len, &API_VAR_REF(msg)); - API_MSG_VAR_FREE(msg); - return err; -} - -static err_t -netconn_recv_data_tcp(struct netconn *conn, struct pbuf **new_buf, u8_t apiflags) -{ - err_t err; - struct pbuf *buf; - API_MSG_VAR_DECLARE(msg); -#if LWIP_MPU_COMPATIBLE - msg = NULL; -#endif - - if (!NETCONN_RECVMBOX_WAITABLE(conn)) { - /* This only happens when calling this function more than once *after* receiving FIN */ - return ERR_CONN; - } - if (netconn_is_flag_set(conn, NETCONN_FIN_RX_PENDING)) { - netconn_clear_flags(conn, NETCONN_FIN_RX_PENDING); - goto handle_fin; - } - - if (!(apiflags & NETCONN_NOAUTORCVD)) { - /* need to allocate API message here so empty message pool does not result in event loss - * see bug #47512: MPU_COMPATIBLE may fail on empty pool */ - API_MSG_VAR_ALLOC(msg); - } - - err = netconn_recv_data(conn, (void **)new_buf, apiflags); - if (err != ERR_OK) { - if (!(apiflags & NETCONN_NOAUTORCVD)) { - API_MSG_VAR_FREE(msg); - } - return err; - } - buf = *new_buf; - if (!(apiflags & NETCONN_NOAUTORCVD)) { - /* Let the stack know that we have taken the data. */ - u16_t len = buf ? buf->tot_len : 1; - /* don't care for the return value of lwip_netconn_do_recv */ - /* @todo: this should really be fixed, e.g. by retrying in poll on error */ - netconn_tcp_recvd_msg(conn, len, &API_VAR_REF(msg)); - API_MSG_VAR_FREE(msg); - } - - /* If we are closed, we indicate that we no longer wish to use the socket */ - if (buf == NULL) { - if (apiflags & NETCONN_NOFIN) { - /* received a FIN but the caller cannot handle it right now: - re-enqueue it and return "no data" */ - netconn_set_flags(conn, NETCONN_FIN_RX_PENDING); - return ERR_WOULDBLOCK; - } else { -handle_fin: - API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0); - if (conn->pcb.ip == NULL) { - /* race condition: RST during recv */ - err = netconn_err(conn); - if (err != ERR_OK) { - return err; - } - return ERR_RST; - } - /* RX side is closed, so deallocate the recvmbox */ - netconn_close_shutdown(conn, NETCONN_SHUT_RD); - /* Don' store ERR_CLSD as conn->err since we are only half-closed */ - return ERR_CLSD; - } - } - return err; -} - -/** - * @ingroup netconn_tcp - * Receive data (in form of a pbuf) from a TCP netconn - * - * @param conn the netconn from which to receive data - * @param new_buf pointer where a new pbuf is stored when received data - * @return ERR_OK if data has been received, an error code otherwise (timeout, - * memory error or another error, @see netconn_recv_data) - * ERR_ARG if conn is not a TCP netconn - */ -err_t -netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf) -{ - LWIP_ERROR("netconn_recv_tcp_pbuf: invalid conn", (conn != NULL) && - NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP, return ERR_ARG;); - - return netconn_recv_data_tcp(conn, new_buf, 0); -} - -/** - * @ingroup netconn_tcp - * Receive data (in form of a pbuf) from a TCP netconn - * - * @param conn the netconn from which to receive data - * @param new_buf pointer where a new pbuf is stored when received data - * @param apiflags flags that control function behaviour. For now only: - * - NETCONN_DONTBLOCK: only read data that is available now, don't wait for more data - * @return ERR_OK if data has been received, an error code otherwise (timeout, - * memory error or another error, @see netconn_recv_data) - * ERR_ARG if conn is not a TCP netconn - */ -err_t -netconn_recv_tcp_pbuf_flags(struct netconn *conn, struct pbuf **new_buf, u8_t apiflags) -{ - LWIP_ERROR("netconn_recv_tcp_pbuf: invalid conn", (conn != NULL) && - NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP, return ERR_ARG;); - - return netconn_recv_data_tcp(conn, new_buf, apiflags); -} -#endif /* LWIP_TCP */ - -/** - * Receive data (in form of a netbuf) from a UDP or RAW netconn - * - * @param conn the netconn from which to receive data - * @param new_buf pointer where a new netbuf is stored when received data - * @return ERR_OK if data has been received, an error code otherwise (timeout, - * memory error or another error) - * ERR_ARG if conn is not a UDP/RAW netconn - */ -err_t -netconn_recv_udp_raw_netbuf(struct netconn *conn, struct netbuf **new_buf) -{ - LWIP_ERROR("netconn_recv_udp_raw_netbuf: invalid conn", (conn != NULL) && - NETCONNTYPE_GROUP(netconn_type(conn)) != NETCONN_TCP, return ERR_ARG;); - - return netconn_recv_data(conn, (void **)new_buf, 0); -} - -/** - * Receive data (in form of a netbuf) from a UDP or RAW netconn - * - * @param conn the netconn from which to receive data - * @param new_buf pointer where a new netbuf is stored when received data - * @param apiflags flags that control function behaviour. For now only: - * - NETCONN_DONTBLOCK: only read data that is available now, don't wait for more data - * @return ERR_OK if data has been received, an error code otherwise (timeout, - * memory error or another error) - * ERR_ARG if conn is not a UDP/RAW netconn - */ -err_t -netconn_recv_udp_raw_netbuf_flags(struct netconn *conn, struct netbuf **new_buf, u8_t apiflags) -{ - LWIP_ERROR("netconn_recv_udp_raw_netbuf: invalid conn", (conn != NULL) && - NETCONNTYPE_GROUP(netconn_type(conn)) != NETCONN_TCP, return ERR_ARG;); - - return netconn_recv_data(conn, (void **)new_buf, apiflags); -} - -/** - * @ingroup netconn_common - * Receive data (in form of a netbuf containing a packet buffer) from a netconn - * - * @param conn the netconn from which to receive data - * @param new_buf pointer where a new netbuf is stored when received data - * @return ERR_OK if data has been received, an error code otherwise (timeout, - * memory error or another error) - */ -err_t -netconn_recv(struct netconn *conn, struct netbuf **new_buf) -{ -#if LWIP_TCP - struct netbuf *buf = NULL; - err_t err; -#endif /* LWIP_TCP */ - - LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;); - *new_buf = NULL; - LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL), return ERR_ARG;); - -#if LWIP_TCP -#if (LWIP_UDP || LWIP_RAW) - if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) -#endif /* (LWIP_UDP || LWIP_RAW) */ - { - struct pbuf *p = NULL; - /* This is not a listening netconn, since recvmbox is set */ - - buf = (struct netbuf *)memp_malloc(MEMP_NETBUF); - if (buf == NULL) { - return ERR_MEM; - } - - err = netconn_recv_data_tcp(conn, &p, 0); - if (err != ERR_OK) { - memp_free(MEMP_NETBUF, buf); - return err; - } - LWIP_ASSERT("p != NULL", p != NULL); - - buf->p = p; - buf->ptr = p; - buf->port = 0; - ip_addr_set_zero(&buf->addr); - *new_buf = buf; - /* don't set conn->last_err: it's only ERR_OK, anyway */ - return ERR_OK; - } -#endif /* LWIP_TCP */ -#if LWIP_TCP && (LWIP_UDP || LWIP_RAW) - else -#endif /* LWIP_TCP && (LWIP_UDP || LWIP_RAW) */ - { -#if (LWIP_UDP || LWIP_RAW) - return netconn_recv_data(conn, (void **)new_buf, 0); -#endif /* (LWIP_UDP || LWIP_RAW) */ - } -} - -/** - * @ingroup netconn_udp - * Send data (in form of a netbuf) to a specific remote IP address and port. - * Only to be used for UDP and RAW netconns (not TCP). - * - * @param conn the netconn over which to send data - * @param buf a netbuf containing the data to send - * @param addr the remote IP address to which to send the data - * @param port the remote port to which to send the data - * @return ERR_OK if data was sent, any other err_t on error - */ -err_t -netconn_sendto(struct netconn *conn, struct netbuf *buf, const ip_addr_t *addr, u16_t port) -{ - if (buf != NULL) { - ip_addr_set(&buf->addr, addr); - buf->port = port; - return netconn_send(conn, buf); - } - return ERR_VAL; -} - -/** - * @ingroup netconn_udp - * Send data over a UDP or RAW netconn (that is already connected). - * - * @param conn the UDP or RAW netconn over which to send data - * @param buf a netbuf containing the data to send - * @return ERR_OK if data was sent, any other err_t on error - */ -err_t -netconn_send(struct netconn *conn, struct netbuf *buf) -{ - API_MSG_VAR_DECLARE(msg); - err_t err; - - LWIP_ERROR("netconn_send: invalid conn", (conn != NULL), return ERR_ARG;); - - LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %"U16_F" bytes\n", buf->p->tot_len)); - - API_MSG_VAR_ALLOC(msg); - API_MSG_VAR_REF(msg).conn = conn; - API_MSG_VAR_REF(msg).msg.b = buf; - err = netconn_apimsg(lwip_netconn_do_send, &API_MSG_VAR_REF(msg)); - API_MSG_VAR_FREE(msg); - - return err; -} - -/** - * @ingroup netconn_tcp - * Send data over a TCP netconn. - * - * @param conn the TCP netconn over which to send data - * @param dataptr pointer to the application buffer that contains the data to send - * @param size size of the application data to send - * @param apiflags combination of following flags : - * - NETCONN_COPY: data will be copied into memory belonging to the stack - * - NETCONN_MORE: for TCP connection, PSH flag will be set on last segment sent - * - NETCONN_DONTBLOCK: only write the data if all data can be written at once - * @param bytes_written pointer to a location that receives the number of written bytes - * @return ERR_OK if data was sent, any other err_t on error - */ -err_t -netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size, - u8_t apiflags, size_t *bytes_written) -{ - struct netvector vector; - vector.ptr = dataptr; - vector.len = size; - return netconn_write_vectors_partly(conn, &vector, 1, apiflags, bytes_written); -} - -/** - * Send vectorized data atomically over a TCP netconn. - * - * @param conn the TCP netconn over which to send data - * @param vectors array of vectors containing data to send - * @param vectorcnt number of vectors in the array - * @param apiflags combination of following flags : - * - NETCONN_COPY: data will be copied into memory belonging to the stack - * - NETCONN_MORE: for TCP connection, PSH flag will be set on last segment sent - * - NETCONN_DONTBLOCK: only write the data if all data can be written at once - * @param bytes_written pointer to a location that receives the number of written bytes - * @return ERR_OK if data was sent, any other err_t on error - */ -err_t -netconn_write_vectors_partly(struct netconn *conn, struct netvector *vectors, u16_t vectorcnt, - u8_t apiflags, size_t *bytes_written) -{ - API_MSG_VAR_DECLARE(msg); - err_t err; - u8_t dontblock; - size_t size; - int i; - - LWIP_ERROR("netconn_write: invalid conn", (conn != NULL), return ERR_ARG;); - LWIP_ERROR("netconn_write: invalid conn->type", (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP), return ERR_VAL;); - dontblock = netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK); -#if LWIP_SO_SNDTIMEO - if (conn->send_timeout != 0) { - dontblock = 1; - } -#endif /* LWIP_SO_SNDTIMEO */ - if (dontblock && !bytes_written) { - /* This implies netconn_write() cannot be used for non-blocking send, since - it has no way to return the number of bytes written. */ - return ERR_VAL; - } - - /* sum up the total size */ - size = 0; - for (i = 0; i < vectorcnt; i++) { - size += vectors[i].len; - if (size < vectors[i].len) { - /* overflow */ - return ERR_VAL; - } - } - if (size == 0) { - return ERR_OK; - } else if (size > SSIZE_MAX) { - ssize_t limited; - /* this is required by the socket layer (cannot send full size_t range) */ - if (!bytes_written) { - return ERR_VAL; - } - /* limit the amount of data to send */ - limited = SSIZE_MAX; - size = (size_t)limited; - } - - API_MSG_VAR_ALLOC(msg); - /* non-blocking write sends as much */ - API_MSG_VAR_REF(msg).conn = conn; - API_MSG_VAR_REF(msg).msg.w.vector = vectors; - API_MSG_VAR_REF(msg).msg.w.vector_cnt = vectorcnt; - API_MSG_VAR_REF(msg).msg.w.vector_off = 0; - API_MSG_VAR_REF(msg).msg.w.apiflags = apiflags; - API_MSG_VAR_REF(msg).msg.w.len = size; - API_MSG_VAR_REF(msg).msg.w.offset = 0; -#if LWIP_SO_SNDTIMEO - if (conn->send_timeout != 0) { - /* get the time we started, which is later compared to - sys_now() + conn->send_timeout */ - API_MSG_VAR_REF(msg).msg.w.time_started = sys_now(); - } else { - API_MSG_VAR_REF(msg).msg.w.time_started = 0; - } -#endif /* LWIP_SO_SNDTIMEO */ - - /* For locking the core: this _can_ be delayed on low memory/low send buffer, - but if it is, this is done inside api_msg.c:do_write(), so we can use the - non-blocking version here. */ - err = netconn_apimsg(lwip_netconn_do_write, &API_MSG_VAR_REF(msg)); - if (err == ERR_OK) { - if (bytes_written != NULL) { - *bytes_written = API_MSG_VAR_REF(msg).msg.w.offset; - } - /* for blocking, check all requested bytes were written, NOTE: send_timeout is - treated as dontblock (see dontblock assignment above) */ - if (!dontblock) { - LWIP_ASSERT("do_write failed to write all bytes", API_MSG_VAR_REF(msg).msg.w.offset == size); - } - } - API_MSG_VAR_FREE(msg); - - return err; -} - -/** - * @ingroup netconn_tcp - * Close or shutdown a TCP netconn (doesn't delete it). - * - * @param conn the TCP netconn to close or shutdown - * @param how fully close or only shutdown one side? - * @return ERR_OK if the netconn was closed, any other err_t on error - */ -static err_t -netconn_close_shutdown(struct netconn *conn, u8_t how) -{ - API_MSG_VAR_DECLARE(msg); - err_t err; - LWIP_UNUSED_ARG(how); - - LWIP_ERROR("netconn_close: invalid conn", (conn != NULL), return ERR_ARG;); - - API_MSG_VAR_ALLOC(msg); - API_MSG_VAR_REF(msg).conn = conn; -#if LWIP_TCP - /* shutting down both ends is the same as closing */ - API_MSG_VAR_REF(msg).msg.sd.shut = how; -#if LWIP_SO_SNDTIMEO || LWIP_SO_LINGER - /* get the time we started, which is later compared to - sys_now() + conn->send_timeout */ - API_MSG_VAR_REF(msg).msg.sd.time_started = sys_now(); -#else /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */ - API_MSG_VAR_REF(msg).msg.sd.polls_left = - ((LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT + TCP_SLOW_INTERVAL - 1) / TCP_SLOW_INTERVAL) + 1; -#endif /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */ -#endif /* LWIP_TCP */ - err = netconn_apimsg(lwip_netconn_do_close, &API_MSG_VAR_REF(msg)); - API_MSG_VAR_FREE(msg); - - return err; -} - -/** - * @ingroup netconn_tcp - * Close a TCP netconn (doesn't delete it). - * - * @param conn the TCP netconn to close - * @return ERR_OK if the netconn was closed, any other err_t on error - */ -err_t -netconn_close(struct netconn *conn) -{ - /* shutting down both ends is the same as closing */ - return netconn_close_shutdown(conn, NETCONN_SHUT_RDWR); -} - -/** - * @ingroup netconn_common - * Get and reset pending error on a netconn - * - * @param conn the netconn to get the error from - * @return and pending error or ERR_OK if no error was pending - */ -err_t -netconn_err(struct netconn *conn) -{ - err_t err; - SYS_ARCH_DECL_PROTECT(lev); - if (conn == NULL) { - return ERR_OK; - } - SYS_ARCH_PROTECT(lev); - err = conn->pending_err; - conn->pending_err = ERR_OK; - SYS_ARCH_UNPROTECT(lev); - return err; -} - -/** - * @ingroup netconn_tcp - * Shut down one or both sides of a TCP netconn (doesn't delete it). - * - * @param conn the TCP netconn to shut down - * @param shut_rx shut down the RX side (no more read possible after this) - * @param shut_tx shut down the TX side (no more write possible after this) - * @return ERR_OK if the netconn was closed, any other err_t on error - */ -err_t -netconn_shutdown(struct netconn *conn, u8_t shut_rx, u8_t shut_tx) -{ - return netconn_close_shutdown(conn, (u8_t)((shut_rx ? NETCONN_SHUT_RD : 0) | (shut_tx ? NETCONN_SHUT_WR : 0))); -} - -#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) -/** - * @ingroup netconn_udp - * Join multicast groups for UDP netconns. - * - * @param conn the UDP netconn for which to change multicast addresses - * @param multiaddr IP address of the multicast group to join or leave - * @param netif_addr the IP address of the network interface on which to send - * the igmp message - * @param join_or_leave flag whether to send a join- or leave-message - * @return ERR_OK if the action was taken, any err_t on error - */ -err_t -netconn_join_leave_group(struct netconn *conn, - const ip_addr_t *multiaddr, - const ip_addr_t *netif_addr, - enum netconn_igmp join_or_leave) -{ - API_MSG_VAR_DECLARE(msg); - err_t err; - - LWIP_ERROR("netconn_join_leave_group: invalid conn", (conn != NULL), return ERR_ARG;); - - API_MSG_VAR_ALLOC(msg); - -#if LWIP_IPV4 - /* Don't propagate NULL pointer (IP_ADDR_ANY alias) to subsequent functions */ - if (multiaddr == NULL) { - multiaddr = IP4_ADDR_ANY; - } - if (netif_addr == NULL) { - netif_addr = IP4_ADDR_ANY; - } -#endif /* LWIP_IPV4 */ - - API_MSG_VAR_REF(msg).conn = conn; - API_MSG_VAR_REF(msg).msg.jl.multiaddr = API_MSG_VAR_REF(multiaddr); - API_MSG_VAR_REF(msg).msg.jl.netif_addr = API_MSG_VAR_REF(netif_addr); - API_MSG_VAR_REF(msg).msg.jl.join_or_leave = join_or_leave; - err = netconn_apimsg(lwip_netconn_do_join_leave_group, &API_MSG_VAR_REF(msg)); - API_MSG_VAR_FREE(msg); - - return err; -} -/** - * @ingroup netconn_udp - * Join multicast groups for UDP netconns. - * - * @param conn the UDP netconn for which to change multicast addresses - * @param multiaddr IP address of the multicast group to join or leave - * @param if_idx the index of the netif - * @param join_or_leave flag whether to send a join- or leave-message - * @return ERR_OK if the action was taken, any err_t on error - */ -err_t -netconn_join_leave_group_netif(struct netconn *conn, - const ip_addr_t *multiaddr, - u8_t if_idx, - enum netconn_igmp join_or_leave) -{ - API_MSG_VAR_DECLARE(msg); - err_t err; - - LWIP_ERROR("netconn_join_leave_group: invalid conn", (conn != NULL), return ERR_ARG;); - - API_MSG_VAR_ALLOC(msg); - -#if LWIP_IPV4 - /* Don't propagate NULL pointer (IP_ADDR_ANY alias) to subsequent functions */ - if (multiaddr == NULL) { - multiaddr = IP4_ADDR_ANY; - } - if (if_idx == NETIF_NO_INDEX) { - return ERR_IF; - } -#endif /* LWIP_IPV4 */ - - API_MSG_VAR_REF(msg).conn = conn; - API_MSG_VAR_REF(msg).msg.jl.multiaddr = API_MSG_VAR_REF(multiaddr); - API_MSG_VAR_REF(msg).msg.jl.if_idx = if_idx; - API_MSG_VAR_REF(msg).msg.jl.join_or_leave = join_or_leave; - err = netconn_apimsg(lwip_netconn_do_join_leave_group_netif, &API_MSG_VAR_REF(msg)); - API_MSG_VAR_FREE(msg); - - return err; -} -#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ - -#if LWIP_DNS -/** - * @ingroup netconn_common - * Execute a DNS query, only one IP address is returned - * - * @param name a string representation of the DNS host name to query - * @param addr a preallocated ip_addr_t where to store the resolved IP address - * @param dns_addrtype IP address type (IPv4 / IPv6) - * @return ERR_OK: resolving succeeded - * ERR_MEM: memory error, try again later - * ERR_ARG: dns client not initialized or invalid hostname - * ERR_VAL: dns server response was invalid - */ -#if LWIP_IPV4 && LWIP_IPV6 -err_t -netconn_gethostbyname_addrtype(const char *name, ip_addr_t *addr, u8_t dns_addrtype) -#else -err_t -netconn_gethostbyname(const char *name, ip_addr_t *addr) -#endif -{ - API_VAR_DECLARE(struct dns_api_msg, msg); -#if !LWIP_MPU_COMPATIBLE - sys_sem_t sem; -#endif /* LWIP_MPU_COMPATIBLE */ - err_t err; - err_t cberr; - - LWIP_ERROR("netconn_gethostbyname: invalid name", (name != NULL), return ERR_ARG;); - LWIP_ERROR("netconn_gethostbyname: invalid addr", (addr != NULL), return ERR_ARG;); -#if LWIP_MPU_COMPATIBLE - if (strlen(name) >= DNS_MAX_NAME_LENGTH) { - return ERR_ARG; - } -#endif - -#ifdef LWIP_HOOK_NETCONN_EXTERNAL_RESOLVE -#if LWIP_IPV4 && LWIP_IPV6 - if (LWIP_HOOK_NETCONN_EXTERNAL_RESOLVE(name, addr, dns_addrtype, &err)) { -#else - if (LWIP_HOOK_NETCONN_EXTERNAL_RESOLVE(name, addr, NETCONN_DNS_DEFAULT, &err)) { -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - return err; - } -#endif /* LWIP_HOOK_NETCONN_EXTERNAL_RESOLVE */ - - API_VAR_ALLOC(struct dns_api_msg, MEMP_DNS_API_MSG, msg, ERR_MEM); -#if LWIP_MPU_COMPATIBLE - strncpy(API_VAR_REF(msg).name, name, DNS_MAX_NAME_LENGTH - 1); - API_VAR_REF(msg).name[DNS_MAX_NAME_LENGTH - 1] = 0; -#else /* LWIP_MPU_COMPATIBLE */ - msg.err = &err; - msg.sem = &sem; - API_VAR_REF(msg).addr = API_VAR_REF(addr); - API_VAR_REF(msg).name = name; -#endif /* LWIP_MPU_COMPATIBLE */ -#if LWIP_IPV4 && LWIP_IPV6 - API_VAR_REF(msg).dns_addrtype = dns_addrtype; -#endif /* LWIP_IPV4 && LWIP_IPV6 */ -#if LWIP_NETCONN_SEM_PER_THREAD - API_VAR_REF(msg).sem = LWIP_NETCONN_THREAD_SEM_GET(); -#else /* LWIP_NETCONN_SEM_PER_THREAD*/ - err = sys_sem_new(API_EXPR_REF(API_VAR_REF(msg).sem), 0); - if (err != ERR_OK) { - API_VAR_FREE(MEMP_DNS_API_MSG, msg); - return err; - } -#endif /* LWIP_NETCONN_SEM_PER_THREAD */ - - cberr = tcpip_send_msg_wait_sem(lwip_netconn_do_gethostbyname, &API_VAR_REF(msg), API_EXPR_REF(API_VAR_REF(msg).sem)); -#if !LWIP_NETCONN_SEM_PER_THREAD - sys_sem_free(API_EXPR_REF(API_VAR_REF(msg).sem)); -#endif /* !LWIP_NETCONN_SEM_PER_THREAD */ - if (cberr != ERR_OK) { - API_VAR_FREE(MEMP_DNS_API_MSG, msg); - return cberr; - } - -#if LWIP_MPU_COMPATIBLE - *addr = msg->addr; - err = msg->err; -#endif /* LWIP_MPU_COMPATIBLE */ - - API_VAR_FREE(MEMP_DNS_API_MSG, msg); - return err; -} -#endif /* LWIP_DNS*/ - -#if LWIP_NETCONN_SEM_PER_THREAD -void -netconn_thread_init(void) -{ - sys_sem_t *sem = LWIP_NETCONN_THREAD_SEM_GET(); - if ((sem == NULL) || !sys_sem_valid(sem)) { - /* call alloc only once */ - LWIP_NETCONN_THREAD_SEM_ALLOC(); - LWIP_ASSERT("LWIP_NETCONN_THREAD_SEM_ALLOC() failed", sys_sem_valid(LWIP_NETCONN_THREAD_SEM_GET())); - } -} - -void -netconn_thread_cleanup(void) -{ - sys_sem_t *sem = LWIP_NETCONN_THREAD_SEM_GET(); - if ((sem != NULL) && sys_sem_valid(sem)) { - /* call free only once */ - LWIP_NETCONN_THREAD_SEM_FREE(); - } -} -#endif /* LWIP_NETCONN_SEM_PER_THREAD */ - -#endif /* LWIP_NETCONN */ diff --git a/third-party/lwip-2.1.2/api/api_msg.c b/third-party/lwip-2.1.2/api/api_msg.c deleted file mode 100644 index 39531024..00000000 --- a/third-party/lwip-2.1.2/api/api_msg.c +++ /dev/null @@ -1,2173 +0,0 @@ -/** - * @file - * Sequential API Internal module - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#include "lwip/opt.h" - -#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/priv/api_msg.h" - -#include "lwip/ip.h" -#include "lwip/ip_addr.h" -#include "lwip/udp.h" -#include "lwip/tcp.h" -#include "lwip/raw.h" - -#include "lwip/memp.h" -#include "lwip/igmp.h" -#include "lwip/dns.h" -#include "lwip/mld6.h" -#include "lwip/priv/tcpip_priv.h" - -#include - -/* netconns are polled once per second (e.g. continue write on memory error) */ -#define NETCONN_TCP_POLL_INTERVAL 2 - -#define SET_NONBLOCKING_CONNECT(conn, val) do { if (val) { \ - netconn_set_flags(conn, NETCONN_FLAG_IN_NONBLOCKING_CONNECT); \ -} else { \ - netconn_clear_flags(conn, NETCONN_FLAG_IN_NONBLOCKING_CONNECT); }} while(0) -#define IN_NONBLOCKING_CONNECT(conn) netconn_is_flag_set(conn, NETCONN_FLAG_IN_NONBLOCKING_CONNECT) - -#if LWIP_NETCONN_FULLDUPLEX -#define NETCONN_MBOX_VALID(conn, mbox) (sys_mbox_valid(mbox) && ((conn->flags & NETCONN_FLAG_MBOXINVALID) == 0)) -#else -#define NETCONN_MBOX_VALID(conn, mbox) sys_mbox_valid(mbox) -#endif - -/* forward declarations */ -#if LWIP_TCP -#if LWIP_TCPIP_CORE_LOCKING -#define WRITE_DELAYED , 1 -#define WRITE_DELAYED_PARAM , u8_t delayed -#else /* LWIP_TCPIP_CORE_LOCKING */ -#define WRITE_DELAYED -#define WRITE_DELAYED_PARAM -#endif /* LWIP_TCPIP_CORE_LOCKING */ -static err_t lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM); -static err_t lwip_netconn_do_close_internal(struct netconn *conn WRITE_DELAYED_PARAM); -#endif - -static void netconn_drain(struct netconn *conn); - -#if LWIP_TCPIP_CORE_LOCKING -#define TCPIP_APIMSG_ACK(m) -#else /* LWIP_TCPIP_CORE_LOCKING */ -#define TCPIP_APIMSG_ACK(m) do { sys_sem_signal(LWIP_API_MSG_SEM(m)); } while(0) -#endif /* LWIP_TCPIP_CORE_LOCKING */ - -#if LWIP_NETCONN_FULLDUPLEX -const u8_t netconn_deleted = 0; - -int -lwip_netconn_is_deallocated_msg(void *msg) -{ - if (msg == &netconn_deleted) { - return 1; - } - return 0; -} -#endif /* LWIP_NETCONN_FULLDUPLEX */ - -#if LWIP_TCP -const u8_t netconn_aborted = 0; -const u8_t netconn_reset = 0; -const u8_t netconn_closed = 0; - -/** Translate an error to a unique void* passed via an mbox */ -static void * -lwip_netconn_err_to_msg(err_t err) -{ - switch (err) { - case ERR_ABRT: - return LWIP_CONST_CAST(void *, &netconn_aborted); - case ERR_RST: - return LWIP_CONST_CAST(void *, &netconn_reset); - case ERR_CLSD: - return LWIP_CONST_CAST(void *, &netconn_closed); - default: - LWIP_ASSERT("unhandled error", err == ERR_OK); - return NULL; - } -} - -int -lwip_netconn_is_err_msg(void *msg, err_t *err) -{ - LWIP_ASSERT("err != NULL", err != NULL); - - if (msg == &netconn_aborted) { - *err = ERR_ABRT; - return 1; - } else if (msg == &netconn_reset) { - *err = ERR_RST; - return 1; - } else if (msg == &netconn_closed) { - *err = ERR_CLSD; - return 1; - } - return 0; -} -#endif /* LWIP_TCP */ - - -#if LWIP_RAW -/** - * Receive callback function for RAW netconns. - * Doesn't 'eat' the packet, only copies it and sends it to - * conn->recvmbox - * - * @see raw.h (struct raw_pcb.recv) for parameters and return value - */ -static u8_t -recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p, - const ip_addr_t *addr) -{ - struct pbuf *q; - struct netbuf *buf; - struct netconn *conn; - - LWIP_UNUSED_ARG(addr); - conn = (struct netconn *)arg; - - if ((conn != NULL) && NETCONN_MBOX_VALID(conn, &conn->recvmbox)) { -#if LWIP_SO_RCVBUF - int recv_avail; - SYS_ARCH_GET(conn->recv_avail, recv_avail); - if ((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize) { - return 0; - } -#endif /* LWIP_SO_RCVBUF */ - /* copy the whole packet into new pbufs */ - q = pbuf_clone(PBUF_RAW, PBUF_RAM, p); - if (q != NULL) { - u16_t len; - buf = (struct netbuf *)memp_malloc(MEMP_NETBUF); - if (buf == NULL) { - pbuf_free(q); - return 0; - } - - buf->p = q; - buf->ptr = q; - ip_addr_copy(buf->addr, *ip_current_src_addr()); - buf->port = pcb->protocol; - - len = q->tot_len; - if (sys_mbox_trypost(&conn->recvmbox, buf) != ERR_OK) { - netbuf_delete(buf); - return 0; - } else { -#if LWIP_SO_RCVBUF - SYS_ARCH_INC(conn->recv_avail, len); -#endif /* LWIP_SO_RCVBUF */ - /* Register event with callback */ - API_EVENT(conn, NETCONN_EVT_RCVPLUS, len); - } - } - } - - return 0; /* do not eat the packet */ -} -#endif /* LWIP_RAW*/ - -#if LWIP_UDP -/** - * Receive callback function for UDP netconns. - * Posts the packet to conn->recvmbox or deletes it on memory error. - * - * @see udp.h (struct udp_pcb.recv) for parameters - */ -static void -recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, - const ip_addr_t *addr, u16_t port) -{ - struct netbuf *buf; - struct netconn *conn; - u16_t len; -#if LWIP_SO_RCVBUF - int recv_avail; -#endif /* LWIP_SO_RCVBUF */ - - LWIP_UNUSED_ARG(pcb); /* only used for asserts... */ - LWIP_ASSERT("recv_udp must have a pcb argument", pcb != NULL); - LWIP_ASSERT("recv_udp must have an argument", arg != NULL); - conn = (struct netconn *)arg; - - if (conn == NULL) { - pbuf_free(p); - return; - } - - LWIP_ASSERT("recv_udp: recv for wrong pcb!", conn->pcb.udp == pcb); - -#if LWIP_SO_RCVBUF - SYS_ARCH_GET(conn->recv_avail, recv_avail); - if (!NETCONN_MBOX_VALID(conn, &conn->recvmbox) || - ((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize)) { -#else /* LWIP_SO_RCVBUF */ - if (!NETCONN_MBOX_VALID(conn, &conn->recvmbox)) { -#endif /* LWIP_SO_RCVBUF */ - pbuf_free(p); - return; - } - - buf = (struct netbuf *)memp_malloc(MEMP_NETBUF); - if (buf == NULL) { - pbuf_free(p); - return; - } else { - buf->p = p; - buf->ptr = p; - ip_addr_set(&buf->addr, addr); - buf->port = port; -#if LWIP_NETBUF_RECVINFO - if (conn->flags & NETCONN_FLAG_PKTINFO) { - /* get the UDP header - always in the first pbuf, ensured by udp_input */ - const struct udp_hdr *udphdr = (const struct udp_hdr *)ip_next_header_ptr(); - buf->flags = NETBUF_FLAG_DESTADDR; - ip_addr_set(&buf->toaddr, ip_current_dest_addr()); - buf->toport_chksum = udphdr->dest; - } -#endif /* LWIP_NETBUF_RECVINFO */ - } - - len = p->tot_len; - if (sys_mbox_trypost(&conn->recvmbox, buf) != ERR_OK) { - netbuf_delete(buf); - return; - } else { -#if LWIP_SO_RCVBUF - SYS_ARCH_INC(conn->recv_avail, len); -#endif /* LWIP_SO_RCVBUF */ - /* Register event with callback */ - API_EVENT(conn, NETCONN_EVT_RCVPLUS, len); - } -} -#endif /* LWIP_UDP */ - -#if LWIP_TCP -/** - * Receive callback function for TCP netconns. - * Posts the packet to conn->recvmbox, but doesn't delete it on errors. - * - * @see tcp.h (struct tcp_pcb.recv) for parameters and return value - */ -static err_t -recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) -{ - struct netconn *conn; - u16_t len; - void *msg; - - LWIP_UNUSED_ARG(pcb); - LWIP_ASSERT("recv_tcp must have a pcb argument", pcb != NULL); - LWIP_ASSERT("recv_tcp must have an argument", arg != NULL); - LWIP_ASSERT("err != ERR_OK unhandled", err == ERR_OK); - LWIP_UNUSED_ARG(err); /* for LWIP_NOASSERT */ - conn = (struct netconn *)arg; - - if (conn == NULL) { - return ERR_VAL; - } - LWIP_ASSERT("recv_tcp: recv for wrong pcb!", conn->pcb.tcp == pcb); - - if (!NETCONN_MBOX_VALID(conn, &conn->recvmbox)) { - /* recvmbox already deleted */ - if (p != NULL) { - tcp_recved(pcb, p->tot_len); - pbuf_free(p); - } - return ERR_OK; - } - /* Unlike for UDP or RAW pcbs, don't check for available space - using recv_avail since that could break the connection - (data is already ACKed) */ - - if (p != NULL) { - msg = p; - len = p->tot_len; - } else { - msg = LWIP_CONST_CAST(void *, &netconn_closed); - len = 0; - } - - if (sys_mbox_trypost(&conn->recvmbox, msg) != ERR_OK) { - /* don't deallocate p: it is presented to us later again from tcp_fasttmr! */ - return ERR_MEM; - } else { -#if LWIP_SO_RCVBUF - SYS_ARCH_INC(conn->recv_avail, len); -#endif /* LWIP_SO_RCVBUF */ - /* Register event with callback */ - API_EVENT(conn, NETCONN_EVT_RCVPLUS, len); - } - - return ERR_OK; -} - -/** - * Poll callback function for TCP netconns. - * Wakes up an application thread that waits for a connection to close - * or data to be sent. The application thread then takes the - * appropriate action to go on. - * - * Signals the conn->sem. - * netconn_close waits for conn->sem if closing failed. - * - * @see tcp.h (struct tcp_pcb.poll) for parameters and return value - */ -static err_t -poll_tcp(void *arg, struct tcp_pcb *pcb) -{ - struct netconn *conn = (struct netconn *)arg; - - LWIP_UNUSED_ARG(pcb); - LWIP_ASSERT("conn != NULL", (conn != NULL)); - - if (conn->state == NETCONN_WRITE) { - lwip_netconn_do_writemore(conn WRITE_DELAYED); - } else if (conn->state == NETCONN_CLOSE) { -#if !LWIP_SO_SNDTIMEO && !LWIP_SO_LINGER - if (conn->current_msg && conn->current_msg->msg.sd.polls_left) { - conn->current_msg->msg.sd.polls_left--; - } -#endif /* !LWIP_SO_SNDTIMEO && !LWIP_SO_LINGER */ - lwip_netconn_do_close_internal(conn WRITE_DELAYED); - } - /* @todo: implement connect timeout here? */ - - /* Did a nonblocking write fail before? Then check available write-space. */ - if (conn->flags & NETCONN_FLAG_CHECK_WRITESPACE) { - /* If the queued byte- or pbuf-count drops below the configured low-water limit, - let select mark this pcb as writable again. */ - if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT) && - (tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT)) { - netconn_clear_flags(conn, NETCONN_FLAG_CHECK_WRITESPACE); - API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); - } - } - - return ERR_OK; -} - -/** - * Sent callback function for TCP netconns. - * Signals the conn->sem and calls API_EVENT. - * netconn_write waits for conn->sem if send buffer is low. - * - * @see tcp.h (struct tcp_pcb.sent) for parameters and return value - */ -static err_t -sent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len) -{ - struct netconn *conn = (struct netconn *)arg; - - LWIP_UNUSED_ARG(pcb); - LWIP_ASSERT("conn != NULL", (conn != NULL)); - - if (conn) { - if (conn->state == NETCONN_WRITE) { - lwip_netconn_do_writemore(conn WRITE_DELAYED); - } else if (conn->state == NETCONN_CLOSE) { - lwip_netconn_do_close_internal(conn WRITE_DELAYED); - } - - /* If the queued byte- or pbuf-count drops below the configured low-water limit, - let select mark this pcb as writable again. */ - if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT) && - (tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT)) { - netconn_clear_flags(conn, NETCONN_FLAG_CHECK_WRITESPACE); - API_EVENT(conn, NETCONN_EVT_SENDPLUS, len); - } - } - - return ERR_OK; -} - -/** - * Error callback function for TCP netconns. - * Signals conn->sem, posts to all conn mboxes and calls API_EVENT. - * The application thread has then to decide what to do. - * - * @see tcp.h (struct tcp_pcb.err) for parameters - */ -static void -err_tcp(void *arg, err_t err) -{ - struct netconn *conn; - enum netconn_state old_state; - void *mbox_msg; - SYS_ARCH_DECL_PROTECT(lev); - - conn = (struct netconn *)arg; - LWIP_ASSERT("conn != NULL", (conn != NULL)); - - SYS_ARCH_PROTECT(lev); - - /* when err is called, the pcb is deallocated, so delete the reference */ - conn->pcb.tcp = NULL; - /* store pending error */ - conn->pending_err = err; - /* prevent application threads from blocking on 'recvmbox'/'acceptmbox' */ - conn->flags |= NETCONN_FLAG_MBOXCLOSED; - - /* reset conn->state now before waking up other threads */ - old_state = conn->state; - conn->state = NETCONN_NONE; - - SYS_ARCH_UNPROTECT(lev); - - /* Notify the user layer about a connection error. Used to signal select. */ - API_EVENT(conn, NETCONN_EVT_ERROR, 0); - /* Try to release selects pending on 'read' or 'write', too. - They will get an error if they actually try to read or write. */ - API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); - API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); - - mbox_msg = lwip_netconn_err_to_msg(err); - /* pass error message to recvmbox to wake up pending recv */ - if (NETCONN_MBOX_VALID(conn, &conn->recvmbox)) { - /* use trypost to prevent deadlock */ - sys_mbox_trypost(&conn->recvmbox, mbox_msg); - } - /* pass error message to acceptmbox to wake up pending accept */ - if (NETCONN_MBOX_VALID(conn, &conn->acceptmbox)) { - /* use trypost to preven deadlock */ - sys_mbox_trypost(&conn->acceptmbox, mbox_msg); - } - - if ((old_state == NETCONN_WRITE) || (old_state == NETCONN_CLOSE) || - (old_state == NETCONN_CONNECT)) { - /* calling lwip_netconn_do_writemore/lwip_netconn_do_close_internal is not necessary - since the pcb has already been deleted! */ - int was_nonblocking_connect = IN_NONBLOCKING_CONNECT(conn); - SET_NONBLOCKING_CONNECT(conn, 0); - - if (!was_nonblocking_connect) { - sys_sem_t *op_completed_sem; - /* set error return code */ - LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL); - if (old_state == NETCONN_CLOSE) { - /* let close succeed: the connection is closed after all... */ - conn->current_msg->err = ERR_OK; - } else { - /* Write and connect fail */ - conn->current_msg->err = err; - } - op_completed_sem = LWIP_API_MSG_SEM(conn->current_msg); - LWIP_ASSERT("inavlid op_completed_sem", sys_sem_valid(op_completed_sem)); - conn->current_msg = NULL; - /* wake up the waiting task */ - sys_sem_signal(op_completed_sem); - } else { - /* @todo: test what happens for error on nonblocking connect */ - } - } else { - LWIP_ASSERT("conn->current_msg == NULL", conn->current_msg == NULL); - } -} - -/** - * Setup a tcp_pcb with the correct callback function pointers - * and their arguments. - * - * @param conn the TCP netconn to setup - */ -static void -setup_tcp(struct netconn *conn) -{ - struct tcp_pcb *pcb; - - pcb = conn->pcb.tcp; - tcp_arg(pcb, conn); - tcp_recv(pcb, recv_tcp); - tcp_sent(pcb, sent_tcp); - tcp_poll(pcb, poll_tcp, NETCONN_TCP_POLL_INTERVAL); - tcp_err(pcb, err_tcp); -} - -/** - * Accept callback function for TCP netconns. - * Allocates a new netconn and posts that to conn->acceptmbox. - * - * @see tcp.h (struct tcp_pcb_listen.accept) for parameters and return value - */ -static err_t -accept_function(void *arg, struct tcp_pcb *newpcb, err_t err) -{ - struct netconn *newconn; - struct netconn *conn = (struct netconn *)arg; - - if (conn == NULL) { - return ERR_VAL; - } - if (!NETCONN_MBOX_VALID(conn, &conn->acceptmbox)) { - LWIP_DEBUGF(API_MSG_DEBUG, ("accept_function: acceptmbox already deleted\n")); - return ERR_VAL; - } - - if (newpcb == NULL) { - /* out-of-pcbs during connect: pass on this error to the application */ - if (sys_mbox_trypost(&conn->acceptmbox, lwip_netconn_err_to_msg(ERR_ABRT)) == ERR_OK) { - /* Register event with callback */ - API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); - } - return ERR_VAL; - } - LWIP_ASSERT("expect newpcb == NULL or err == ERR_OK", err == ERR_OK); - LWIP_UNUSED_ARG(err); /* for LWIP_NOASSERT */ - - LWIP_DEBUGF(API_MSG_DEBUG, ("accept_function: newpcb->state: %s\n", tcp_debug_state_str(newpcb->state))); - - /* We have to set the callback here even though - * the new socket is unknown. newconn->socket is marked as -1. */ - newconn = netconn_alloc(conn->type, conn->callback); - if (newconn == NULL) { - /* outof netconns: pass on this error to the application */ - if (sys_mbox_trypost(&conn->acceptmbox, lwip_netconn_err_to_msg(ERR_ABRT)) == ERR_OK) { - /* Register event with callback */ - API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); - } - return ERR_MEM; - } - newconn->pcb.tcp = newpcb; - setup_tcp(newconn); - - /* handle backlog counter */ - tcp_backlog_delayed(newpcb); - - if (sys_mbox_trypost(&conn->acceptmbox, newconn) != ERR_OK) { - /* When returning != ERR_OK, the pcb is aborted in tcp_process(), - so do nothing here! */ - /* remove all references to this netconn from the pcb */ - struct tcp_pcb *pcb = newconn->pcb.tcp; - tcp_arg(pcb, NULL); - tcp_recv(pcb, NULL); - tcp_sent(pcb, NULL); - tcp_poll(pcb, NULL, 0); - tcp_err(pcb, NULL); - /* remove reference from to the pcb from this netconn */ - newconn->pcb.tcp = NULL; - /* no need to drain since we know the recvmbox is empty. */ - sys_mbox_free(&newconn->recvmbox); - sys_mbox_set_invalid(&newconn->recvmbox); - netconn_free(newconn); - return ERR_MEM; - } else { - /* Register event with callback */ - API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); - } - - return ERR_OK; -} -#endif /* LWIP_TCP */ - -/** - * Create a new pcb of a specific type. - * Called from lwip_netconn_do_newconn(). - * - * @param msg the api_msg describing the connection type - */ -static void -pcb_new(struct api_msg *msg) -{ - enum lwip_ip_addr_type iptype = IPADDR_TYPE_V4; - - LWIP_ASSERT("pcb_new: pcb already allocated", msg->conn->pcb.tcp == NULL); - -#if LWIP_IPV6 && LWIP_IPV4 - /* IPv6: Dual-stack by default, unless netconn_set_ipv6only() is called */ - if (NETCONNTYPE_ISIPV6(netconn_type(msg->conn))) { - iptype = IPADDR_TYPE_ANY; - } -#endif - - /* Allocate a PCB for this connection */ - switch (NETCONNTYPE_GROUP(msg->conn->type)) { -#if LWIP_RAW - case NETCONN_RAW: - msg->conn->pcb.raw = raw_new_ip_type(iptype, msg->msg.n.proto); - if (msg->conn->pcb.raw != NULL) { -#if LWIP_IPV6 - /* ICMPv6 packets should always have checksum calculated by the stack as per RFC 3542 chapter 3.1 */ - if (NETCONNTYPE_ISIPV6(msg->conn->type) && msg->conn->pcb.raw->protocol == IP6_NEXTH_ICMP6) { - msg->conn->pcb.raw->chksum_reqd = 1; - msg->conn->pcb.raw->chksum_offset = 2; - } -#endif /* LWIP_IPV6 */ - raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn); - } - break; -#endif /* LWIP_RAW */ -#if LWIP_UDP - case NETCONN_UDP: - msg->conn->pcb.udp = udp_new_ip_type(iptype); - if (msg->conn->pcb.udp != NULL) { -#if LWIP_UDPLITE - if (NETCONNTYPE_ISUDPLITE(msg->conn->type)) { - udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE); - } -#endif /* LWIP_UDPLITE */ - if (NETCONNTYPE_ISUDPNOCHKSUM(msg->conn->type)) { - udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM); - } - udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn); - } - break; -#endif /* LWIP_UDP */ -#if LWIP_TCP - case NETCONN_TCP: - msg->conn->pcb.tcp = tcp_new_ip_type(iptype); - if (msg->conn->pcb.tcp != NULL) { - setup_tcp(msg->conn); - } - break; -#endif /* LWIP_TCP */ - default: - /* Unsupported netconn type, e.g. protocol disabled */ - msg->err = ERR_VAL; - return; - } - if (msg->conn->pcb.ip == NULL) { - msg->err = ERR_MEM; - } -} - -/** - * Create a new pcb of a specific type inside a netconn. - * Called from netconn_new_with_proto_and_callback. - * - * @param m the api_msg describing the connection type - */ -void -lwip_netconn_do_newconn(void *m) -{ - struct api_msg *msg = (struct api_msg *)m; - - msg->err = ERR_OK; - if (msg->conn->pcb.tcp == NULL) { - pcb_new(msg); - } - /* Else? This "new" connection already has a PCB allocated. */ - /* Is this an error condition? Should it be deleted? */ - /* We currently just are happy and return. */ - - TCPIP_APIMSG_ACK(msg); -} - -/** - * Create a new netconn (of a specific type) that has a callback function. - * The corresponding pcb is NOT created! - * - * @param t the type of 'connection' to create (@see enum netconn_type) - * @param callback a function to call on status changes (RX available, TX'ed) - * @return a newly allocated struct netconn or - * NULL on memory error - */ -struct netconn * -netconn_alloc(enum netconn_type t, netconn_callback callback) -{ - struct netconn *conn; - int size; - u8_t init_flags = 0; - - conn = (struct netconn *)memp_malloc(MEMP_NETCONN); - if (conn == NULL) { - return NULL; - } - - conn->pending_err = ERR_OK; - conn->type = t; - conn->pcb.tcp = NULL; - - /* If all sizes are the same, every compiler should optimize this switch to nothing */ - switch (NETCONNTYPE_GROUP(t)) { -#if LWIP_RAW - case NETCONN_RAW: - size = DEFAULT_RAW_RECVMBOX_SIZE; - break; -#endif /* LWIP_RAW */ -#if LWIP_UDP - case NETCONN_UDP: - size = DEFAULT_UDP_RECVMBOX_SIZE; -#if LWIP_NETBUF_RECVINFO - init_flags |= NETCONN_FLAG_PKTINFO; -#endif /* LWIP_NETBUF_RECVINFO */ - break; -#endif /* LWIP_UDP */ -#if LWIP_TCP - case NETCONN_TCP: - size = DEFAULT_TCP_RECVMBOX_SIZE; - break; -#endif /* LWIP_TCP */ - default: - LWIP_ASSERT("netconn_alloc: undefined netconn_type", 0); - goto free_and_return; - } - - if (sys_mbox_new(&conn->recvmbox, size) != ERR_OK) { - goto free_and_return; - } -#if !LWIP_NETCONN_SEM_PER_THREAD - if (sys_sem_new(&conn->op_completed, 0) != ERR_OK) { - sys_mbox_free(&conn->recvmbox); - goto free_and_return; - } -#endif - -#if LWIP_TCP - sys_mbox_set_invalid(&conn->acceptmbox); -#endif - conn->state = NETCONN_NONE; -#if LWIP_SOCKET - /* initialize socket to -1 since 0 is a valid socket */ - conn->socket = -1; -#endif /* LWIP_SOCKET */ - conn->callback = callback; -#if LWIP_TCP - conn->current_msg = NULL; -#endif /* LWIP_TCP */ -#if LWIP_SO_SNDTIMEO - conn->send_timeout = 0; -#endif /* LWIP_SO_SNDTIMEO */ -#if LWIP_SO_RCVTIMEO - conn->recv_timeout = 0; -#endif /* LWIP_SO_RCVTIMEO */ -#if LWIP_SO_RCVBUF - conn->recv_bufsize = RECV_BUFSIZE_DEFAULT; - conn->recv_avail = 0; -#endif /* LWIP_SO_RCVBUF */ -#if LWIP_SO_LINGER - conn->linger = -1; -#endif /* LWIP_SO_LINGER */ - conn->flags = init_flags; - return conn; -free_and_return: - memp_free(MEMP_NETCONN, conn); - return NULL; -} - -/** - * Delete a netconn and all its resources. - * The pcb is NOT freed (since we might not be in the right thread context do this). - * - * @param conn the netconn to free - */ -void -netconn_free(struct netconn *conn) -{ - LWIP_ASSERT("PCB must be deallocated outside this function", conn->pcb.tcp == NULL); - -#if LWIP_NETCONN_FULLDUPLEX - /* in fullduplex, netconn is drained here */ - netconn_drain(conn); -#endif /* LWIP_NETCONN_FULLDUPLEX */ - - LWIP_ASSERT("recvmbox must be deallocated before calling this function", - !sys_mbox_valid(&conn->recvmbox)); -#if LWIP_TCP - LWIP_ASSERT("acceptmbox must be deallocated before calling this function", - !sys_mbox_valid(&conn->acceptmbox)); -#endif /* LWIP_TCP */ - -#if !LWIP_NETCONN_SEM_PER_THREAD - sys_sem_free(&conn->op_completed); - sys_sem_set_invalid(&conn->op_completed); -#endif - - memp_free(MEMP_NETCONN, conn); -} - -/** - * Delete rcvmbox and acceptmbox of a netconn and free the left-over data in - * these mboxes - * - * @param conn the netconn to free - * @bytes_drained bytes drained from recvmbox - * @accepts_drained pending connections drained from acceptmbox - */ -static void -netconn_drain(struct netconn *conn) -{ - void *mem; - - /* This runs when mbox and netconn are marked as closed, - so we don't need to lock against rx packets */ -#if LWIP_NETCONN_FULLDUPLEX - LWIP_ASSERT("netconn marked closed", conn->flags & NETCONN_FLAG_MBOXINVALID); -#endif /* LWIP_NETCONN_FULLDUPLEX */ - - /* Delete and drain the recvmbox. */ - if (sys_mbox_valid(&conn->recvmbox)) { - while (sys_mbox_tryfetch(&conn->recvmbox, &mem) != SYS_MBOX_EMPTY) { -#if LWIP_NETCONN_FULLDUPLEX - if (!lwip_netconn_is_deallocated_msg(mem)) -#endif /* LWIP_NETCONN_FULLDUPLEX */ - { -#if LWIP_TCP - if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) { - err_t err; - if (!lwip_netconn_is_err_msg(mem, &err)) { - pbuf_free((struct pbuf *)mem); - } - } else -#endif /* LWIP_TCP */ - { - netbuf_delete((struct netbuf *)mem); - } - } - } - sys_mbox_free(&conn->recvmbox); - sys_mbox_set_invalid(&conn->recvmbox); - } - - /* Delete and drain the acceptmbox. */ -#if LWIP_TCP - if (sys_mbox_valid(&conn->acceptmbox)) { - while (sys_mbox_tryfetch(&conn->acceptmbox, &mem) != SYS_MBOX_EMPTY) { -#if LWIP_NETCONN_FULLDUPLEX - if (!lwip_netconn_is_deallocated_msg(mem)) -#endif /* LWIP_NETCONN_FULLDUPLEX */ - { - err_t err; - if (!lwip_netconn_is_err_msg(mem, &err)) { - struct netconn *newconn = (struct netconn *)mem; - /* Only tcp pcbs have an acceptmbox, so no need to check conn->type */ - /* pcb might be set to NULL already by err_tcp() */ - /* drain recvmbox */ - netconn_drain(newconn); - if (newconn->pcb.tcp != NULL) { - tcp_abort(newconn->pcb.tcp); - newconn->pcb.tcp = NULL; - } - netconn_free(newconn); - } - } - } - sys_mbox_free(&conn->acceptmbox); - sys_mbox_set_invalid(&conn->acceptmbox); - } -#endif /* LWIP_TCP */ -} - -#if LWIP_NETCONN_FULLDUPLEX -static void -netconn_mark_mbox_invalid(struct netconn *conn) -{ - int i, num_waiting; - void *msg = LWIP_CONST_CAST(void *, &netconn_deleted); - - /* Prevent new calls/threads from reading from the mbox */ - conn->flags |= NETCONN_FLAG_MBOXINVALID; - - SYS_ARCH_LOCKED(num_waiting = conn->mbox_threads_waiting); - for (i = 0; i < num_waiting; i++) { - if (sys_mbox_valid_val(conn->recvmbox)) { - sys_mbox_trypost(&conn->recvmbox, msg); - } else { - sys_mbox_trypost(&conn->acceptmbox, msg); - } - } -} -#endif /* LWIP_NETCONN_FULLDUPLEX */ - -#if LWIP_TCP -/** - * Internal helper function to close a TCP netconn: since this sometimes - * doesn't work at the first attempt, this function is called from multiple - * places. - * - * @param conn the TCP netconn to close - */ -static err_t -lwip_netconn_do_close_internal(struct netconn *conn WRITE_DELAYED_PARAM) -{ - err_t err; - u8_t shut, shut_rx, shut_tx, shut_close; - u8_t close_finished = 0; - struct tcp_pcb *tpcb; -#if LWIP_SO_LINGER - u8_t linger_wait_required = 0; -#endif /* LWIP_SO_LINGER */ - - LWIP_ASSERT("invalid conn", (conn != NULL)); - LWIP_ASSERT("this is for tcp netconns only", (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP)); - LWIP_ASSERT("conn must be in state NETCONN_CLOSE", (conn->state == NETCONN_CLOSE)); - LWIP_ASSERT("pcb already closed", (conn->pcb.tcp != NULL)); - LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL); - - tpcb = conn->pcb.tcp; - shut = conn->current_msg->msg.sd.shut; - shut_rx = shut & NETCONN_SHUT_RD; - shut_tx = shut & NETCONN_SHUT_WR; - /* shutting down both ends is the same as closing - (also if RD or WR side was shut down before already) */ - if (shut == NETCONN_SHUT_RDWR) { - shut_close = 1; - } else if (shut_rx && - ((tpcb->state == FIN_WAIT_1) || - (tpcb->state == FIN_WAIT_2) || - (tpcb->state == CLOSING))) { - shut_close = 1; - } else if (shut_tx && ((tpcb->flags & TF_RXCLOSED) != 0)) { - shut_close = 1; - } else { - shut_close = 0; - } - - /* Set back some callback pointers */ - if (shut_close) { - tcp_arg(tpcb, NULL); - } - if (tpcb->state == LISTEN) { - tcp_accept(tpcb, NULL); - } else { - /* some callbacks have to be reset if tcp_close is not successful */ - if (shut_rx) { - tcp_recv(tpcb, NULL); - tcp_accept(tpcb, NULL); - } - if (shut_tx) { - tcp_sent(tpcb, NULL); - } - if (shut_close) { - tcp_poll(tpcb, NULL, 0); - tcp_err(tpcb, NULL); - } - } - /* Try to close the connection */ - if (shut_close) { -#if LWIP_SO_LINGER - /* check linger possibilites before calling tcp_close */ - err = ERR_OK; - /* linger enabled/required at all? (i.e. is there untransmitted data left?) */ - if ((conn->linger >= 0) && (conn->pcb.tcp->unsent || conn->pcb.tcp->unacked)) { - if ((conn->linger == 0)) { - /* data left but linger prevents waiting */ - tcp_abort(tpcb); - tpcb = NULL; - } else if (conn->linger > 0) { - /* data left and linger says we should wait */ - if (netconn_is_nonblocking(conn)) { - /* data left on a nonblocking netconn -> cannot linger */ - err = ERR_WOULDBLOCK; - } else if ((s32_t)(sys_now() - conn->current_msg->msg.sd.time_started) >= - (conn->linger * 1000)) { - /* data left but linger timeout has expired (this happens on further - calls to this function through poll_tcp */ - tcp_abort(tpcb); - tpcb = NULL; - } else { - /* data left -> need to wait for ACK after successful close */ - linger_wait_required = 1; - } - } - } - if ((err == ERR_OK) && (tpcb != NULL)) -#endif /* LWIP_SO_LINGER */ - { - err = tcp_close(tpcb); - } - } else { - err = tcp_shutdown(tpcb, shut_rx, shut_tx); - } - if (err == ERR_OK) { - close_finished = 1; -#if LWIP_SO_LINGER - if (linger_wait_required) { - /* wait for ACK of all unsent/unacked data by just getting called again */ - close_finished = 0; - err = ERR_INPROGRESS; - } -#endif /* LWIP_SO_LINGER */ - } else { - if (err == ERR_MEM) { - /* Closing failed because of memory shortage, try again later. Even for - nonblocking netconns, we have to wait since no standard socket application - is prepared for close failing because of resource shortage. - Check the timeout: this is kind of an lwip addition to the standard sockets: - we wait for some time when failing to allocate a segment for the FIN */ -#if LWIP_SO_SNDTIMEO || LWIP_SO_LINGER - s32_t close_timeout = LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT; -#if LWIP_SO_SNDTIMEO - if (conn->send_timeout > 0) { - close_timeout = conn->send_timeout; - } -#endif /* LWIP_SO_SNDTIMEO */ -#if LWIP_SO_LINGER - if (conn->linger >= 0) { - /* use linger timeout (seconds) */ - close_timeout = conn->linger * 1000U; - } -#endif - if ((s32_t)(sys_now() - conn->current_msg->msg.sd.time_started) >= close_timeout) { -#else /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */ - if (conn->current_msg->msg.sd.polls_left == 0) { -#endif /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */ - close_finished = 1; - if (shut_close) { - /* in this case, we want to RST the connection */ - tcp_abort(tpcb); - err = ERR_OK; - } - } - } else { - /* Closing failed for a non-memory error: give up */ - close_finished = 1; - } - } - if (close_finished) { - /* Closing done (succeeded, non-memory error, nonblocking error or timeout) */ - sys_sem_t *op_completed_sem = LWIP_API_MSG_SEM(conn->current_msg); - conn->current_msg->err = err; - conn->current_msg = NULL; - conn->state = NETCONN_NONE; - if (err == ERR_OK) { - if (shut_close) { - /* Set back some callback pointers as conn is going away */ - conn->pcb.tcp = NULL; - /* Trigger select() in socket layer. Make sure everybody notices activity - on the connection, error first! */ - API_EVENT(conn, NETCONN_EVT_ERROR, 0); - } - if (shut_rx) { - API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); - } - if (shut_tx) { - API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); - } - } -#if LWIP_TCPIP_CORE_LOCKING - if (delayed) -#endif - { - /* wake up the application task */ - sys_sem_signal(op_completed_sem); - } - return ERR_OK; - } - if (!close_finished) { - /* Closing failed and we want to wait: restore some of the callbacks */ - /* Closing of listen pcb will never fail! */ - LWIP_ASSERT("Closing a listen pcb may not fail!", (tpcb->state != LISTEN)); - if (shut_tx) { - tcp_sent(tpcb, sent_tcp); - } - /* when waiting for close, set up poll interval to 500ms */ - tcp_poll(tpcb, poll_tcp, 1); - tcp_err(tpcb, err_tcp); - tcp_arg(tpcb, conn); - /* don't restore recv callback: we don't want to receive any more data */ - } - /* If closing didn't succeed, we get called again either - from poll_tcp or from sent_tcp */ - LWIP_ASSERT("err != ERR_OK", err != ERR_OK); - return err; -} -#endif /* LWIP_TCP */ - -/** - * Delete the pcb inside a netconn. - * Called from netconn_delete. - * - * @param m the api_msg pointing to the connection - */ -void -lwip_netconn_do_delconn(void *m) -{ - struct api_msg *msg = (struct api_msg *)m; - - enum netconn_state state = msg->conn->state; - LWIP_ASSERT("netconn state error", /* this only happens for TCP netconns */ - (state == NETCONN_NONE) || (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP)); -#if LWIP_NETCONN_FULLDUPLEX - /* In full duplex mode, blocking write/connect is aborted with ERR_CLSD */ - if (state != NETCONN_NONE) { - if ((state == NETCONN_WRITE) || - ((state == NETCONN_CONNECT) && !IN_NONBLOCKING_CONNECT(msg->conn))) { - /* close requested, abort running write/connect */ - sys_sem_t *op_completed_sem; - LWIP_ASSERT("msg->conn->current_msg != NULL", msg->conn->current_msg != NULL); - op_completed_sem = LWIP_API_MSG_SEM(msg->conn->current_msg); - msg->conn->current_msg->err = ERR_CLSD; - msg->conn->current_msg = NULL; - msg->conn->state = NETCONN_NONE; - sys_sem_signal(op_completed_sem); - } - } -#else /* LWIP_NETCONN_FULLDUPLEX */ - if (((state != NETCONN_NONE) && - (state != NETCONN_LISTEN) && - (state != NETCONN_CONNECT)) || - ((state == NETCONN_CONNECT) && !IN_NONBLOCKING_CONNECT(msg->conn))) { - /* This means either a blocking write or blocking connect is running - (nonblocking write returns and sets state to NONE) */ - msg->err = ERR_INPROGRESS; - } else -#endif /* LWIP_NETCONN_FULLDUPLEX */ - { - LWIP_ASSERT("blocking connect in progress", - (state != NETCONN_CONNECT) || IN_NONBLOCKING_CONNECT(msg->conn)); - msg->err = ERR_OK; -#if LWIP_NETCONN_FULLDUPLEX - /* Mark mboxes invalid */ - netconn_mark_mbox_invalid(msg->conn); -#else /* LWIP_NETCONN_FULLDUPLEX */ - netconn_drain(msg->conn); -#endif /* LWIP_NETCONN_FULLDUPLEX */ - - if (msg->conn->pcb.tcp != NULL) { - - switch (NETCONNTYPE_GROUP(msg->conn->type)) { -#if LWIP_RAW - case NETCONN_RAW: - raw_remove(msg->conn->pcb.raw); - break; -#endif /* LWIP_RAW */ -#if LWIP_UDP - case NETCONN_UDP: - msg->conn->pcb.udp->recv_arg = NULL; - udp_remove(msg->conn->pcb.udp); - break; -#endif /* LWIP_UDP */ -#if LWIP_TCP - case NETCONN_TCP: - LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL); - msg->conn->state = NETCONN_CLOSE; - msg->msg.sd.shut = NETCONN_SHUT_RDWR; - msg->conn->current_msg = msg; -#if LWIP_TCPIP_CORE_LOCKING - if (lwip_netconn_do_close_internal(msg->conn, 0) != ERR_OK) { - LWIP_ASSERT("state!", msg->conn->state == NETCONN_CLOSE); - UNLOCK_TCPIP_CORE(); - sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 0); - LOCK_TCPIP_CORE(); - LWIP_ASSERT("state!", msg->conn->state == NETCONN_NONE); - } -#else /* LWIP_TCPIP_CORE_LOCKING */ - lwip_netconn_do_close_internal(msg->conn); -#endif /* LWIP_TCPIP_CORE_LOCKING */ - /* API_EVENT is called inside lwip_netconn_do_close_internal, before releasing - the application thread, so we can return at this point! */ - return; -#endif /* LWIP_TCP */ - default: - break; - } - msg->conn->pcb.tcp = NULL; - } - /* tcp netconns don't come here! */ - - /* @todo: this lets select make the socket readable and writable, - which is wrong! errfd instead? */ - API_EVENT(msg->conn, NETCONN_EVT_RCVPLUS, 0); - API_EVENT(msg->conn, NETCONN_EVT_SENDPLUS, 0); - } - if (sys_sem_valid(LWIP_API_MSG_SEM(msg))) { - TCPIP_APIMSG_ACK(msg); - } -} - -/** - * Bind a pcb contained in a netconn - * Called from netconn_bind. - * - * @param m the api_msg pointing to the connection and containing - * the IP address and port to bind to - */ -void -lwip_netconn_do_bind(void *m) -{ - struct api_msg *msg = (struct api_msg *)m; - err_t err; - - if (msg->conn->pcb.tcp != NULL) { - switch (NETCONNTYPE_GROUP(msg->conn->type)) { -#if LWIP_RAW - case NETCONN_RAW: - err = raw_bind(msg->conn->pcb.raw, API_EXPR_REF(msg->msg.bc.ipaddr)); - break; -#endif /* LWIP_RAW */ -#if LWIP_UDP - case NETCONN_UDP: - err = udp_bind(msg->conn->pcb.udp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port); - break; -#endif /* LWIP_UDP */ -#if LWIP_TCP - case NETCONN_TCP: - err = tcp_bind(msg->conn->pcb.tcp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port); - break; -#endif /* LWIP_TCP */ - default: - err = ERR_VAL; - break; - } - } else { - err = ERR_VAL; - } - msg->err = err; - TCPIP_APIMSG_ACK(msg); -} -/** - * Bind a pcb contained in a netconn to an interface - * Called from netconn_bind_if. - * - * @param m the api_msg pointing to the connection and containing - * the IP address and port to bind to - */ -void -lwip_netconn_do_bind_if(void *m) -{ - struct netif *netif; - struct api_msg *msg = (struct api_msg *)m; - err_t err; - - netif = netif_get_by_index(msg->msg.bc.if_idx); - - if ((netif != NULL) && (msg->conn->pcb.tcp != NULL)) { - err = ERR_OK; - switch (NETCONNTYPE_GROUP(msg->conn->type)) { -#if LWIP_RAW - case NETCONN_RAW: - raw_bind_netif(msg->conn->pcb.raw, netif); - break; -#endif /* LWIP_RAW */ -#if LWIP_UDP - case NETCONN_UDP: - udp_bind_netif(msg->conn->pcb.udp, netif); - break; -#endif /* LWIP_UDP */ -#if LWIP_TCP - case NETCONN_TCP: - tcp_bind_netif(msg->conn->pcb.tcp, netif); - break; -#endif /* LWIP_TCP */ - default: - err = ERR_VAL; - break; - } - } else { - err = ERR_VAL; - } - msg->err = err; - TCPIP_APIMSG_ACK(msg); -} - -#if LWIP_TCP -/** - * TCP callback function if a connection (opened by tcp_connect/lwip_netconn_do_connect) has - * been established (or reset by the remote host). - * - * @see tcp.h (struct tcp_pcb.connected) for parameters and return values - */ -static err_t -lwip_netconn_do_connected(void *arg, struct tcp_pcb *pcb, err_t err) -{ - struct netconn *conn; - int was_blocking; - sys_sem_t *op_completed_sem = NULL; - - LWIP_UNUSED_ARG(pcb); - - conn = (struct netconn *)arg; - - if (conn == NULL) { - return ERR_VAL; - } - - LWIP_ASSERT("conn->state == NETCONN_CONNECT", conn->state == NETCONN_CONNECT); - LWIP_ASSERT("(conn->current_msg != NULL) || conn->in_non_blocking_connect", - (conn->current_msg != NULL) || IN_NONBLOCKING_CONNECT(conn)); - - if (conn->current_msg != NULL) { - conn->current_msg->err = err; - op_completed_sem = LWIP_API_MSG_SEM(conn->current_msg); - } - if ((NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) && (err == ERR_OK)) { - setup_tcp(conn); - } - was_blocking = !IN_NONBLOCKING_CONNECT(conn); - SET_NONBLOCKING_CONNECT(conn, 0); - LWIP_ASSERT("blocking connect state error", - (was_blocking && op_completed_sem != NULL) || - (!was_blocking && op_completed_sem == NULL)); - conn->current_msg = NULL; - conn->state = NETCONN_NONE; - API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); - - if (was_blocking) { - sys_sem_signal(op_completed_sem); - } - return ERR_OK; -} -#endif /* LWIP_TCP */ - -/** - * Connect a pcb contained inside a netconn - * Called from netconn_connect. - * - * @param m the api_msg pointing to the connection and containing - * the IP address and port to connect to - */ -void -lwip_netconn_do_connect(void *m) -{ - struct api_msg *msg = (struct api_msg *)m; - err_t err; - - if (msg->conn->pcb.tcp == NULL) { - /* This may happen when calling netconn_connect() a second time */ - err = ERR_CLSD; - } else { - switch (NETCONNTYPE_GROUP(msg->conn->type)) { -#if LWIP_RAW - case NETCONN_RAW: - err = raw_connect(msg->conn->pcb.raw, API_EXPR_REF(msg->msg.bc.ipaddr)); - break; -#endif /* LWIP_RAW */ -#if LWIP_UDP - case NETCONN_UDP: - err = udp_connect(msg->conn->pcb.udp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port); - break; -#endif /* LWIP_UDP */ -#if LWIP_TCP - case NETCONN_TCP: - /* Prevent connect while doing any other action. */ - if (msg->conn->state == NETCONN_CONNECT) { - err = ERR_ALREADY; - } else if (msg->conn->state != NETCONN_NONE) { - err = ERR_ISCONN; - } else { - setup_tcp(msg->conn); - err = tcp_connect(msg->conn->pcb.tcp, API_EXPR_REF(msg->msg.bc.ipaddr), - msg->msg.bc.port, lwip_netconn_do_connected); - if (err == ERR_OK) { - u8_t non_blocking = netconn_is_nonblocking(msg->conn); - msg->conn->state = NETCONN_CONNECT; - SET_NONBLOCKING_CONNECT(msg->conn, non_blocking); - if (non_blocking) { - err = ERR_INPROGRESS; - } else { - msg->conn->current_msg = msg; - /* sys_sem_signal() is called from lwip_netconn_do_connected (or err_tcp()), - when the connection is established! */ -#if LWIP_TCPIP_CORE_LOCKING - LWIP_ASSERT("state!", msg->conn->state == NETCONN_CONNECT); - UNLOCK_TCPIP_CORE(); - sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 0); - LOCK_TCPIP_CORE(); - LWIP_ASSERT("state!", msg->conn->state != NETCONN_CONNECT); -#endif /* LWIP_TCPIP_CORE_LOCKING */ - return; - } - } - } - break; -#endif /* LWIP_TCP */ - default: - LWIP_ERROR("Invalid netconn type", 0, do { - err = ERR_VAL; - } while (0)); - break; - } - } - msg->err = err; - /* For all other protocols, netconn_connect() calls netconn_apimsg(), - so use TCPIP_APIMSG_ACK() here. */ - TCPIP_APIMSG_ACK(msg); -} - -/** - * Disconnect a pcb contained inside a netconn - * Only used for UDP netconns. - * Called from netconn_disconnect. - * - * @param m the api_msg pointing to the connection to disconnect - */ -void -lwip_netconn_do_disconnect(void *m) -{ - struct api_msg *msg = (struct api_msg *)m; - -#if LWIP_UDP - if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) { - udp_disconnect(msg->conn->pcb.udp); - msg->err = ERR_OK; - } else -#endif /* LWIP_UDP */ - { - msg->err = ERR_VAL; - } - TCPIP_APIMSG_ACK(msg); -} - -#if LWIP_TCP -/** - * Set a TCP pcb contained in a netconn into listen mode - * Called from netconn_listen. - * - * @param m the api_msg pointing to the connection - */ -void -lwip_netconn_do_listen(void *m) -{ - struct api_msg *msg = (struct api_msg *)m; - err_t err; - - if (msg->conn->pcb.tcp != NULL) { - if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) { - if (msg->conn->state == NETCONN_NONE) { - struct tcp_pcb *lpcb; - if (msg->conn->pcb.tcp->state != CLOSED) { - /* connection is not closed, cannot listen */ - err = ERR_VAL; - } else { - u8_t backlog; -#if TCP_LISTEN_BACKLOG - backlog = msg->msg.lb.backlog; -#else /* TCP_LISTEN_BACKLOG */ - backlog = TCP_DEFAULT_LISTEN_BACKLOG; -#endif /* TCP_LISTEN_BACKLOG */ -#if LWIP_IPV4 && LWIP_IPV6 - /* "Socket API like" dual-stack support: If IP to listen to is IP6_ADDR_ANY, - * and NETCONN_FLAG_IPV6_V6ONLY is NOT set, use IP_ANY_TYPE to listen - */ - if (ip_addr_cmp(&msg->conn->pcb.ip->local_ip, IP6_ADDR_ANY) && - (netconn_get_ipv6only(msg->conn) == 0)) { - /* change PCB type to IPADDR_TYPE_ANY */ - IP_SET_TYPE_VAL(msg->conn->pcb.tcp->local_ip, IPADDR_TYPE_ANY); - IP_SET_TYPE_VAL(msg->conn->pcb.tcp->remote_ip, IPADDR_TYPE_ANY); - } -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - - lpcb = tcp_listen_with_backlog_and_err(msg->conn->pcb.tcp, backlog, &err); - - if (lpcb == NULL) { - /* in this case, the old pcb is still allocated */ - } else { - /* delete the recvmbox and allocate the acceptmbox */ - if (sys_mbox_valid(&msg->conn->recvmbox)) { - /** @todo: should we drain the recvmbox here? */ - sys_mbox_free(&msg->conn->recvmbox); - sys_mbox_set_invalid(&msg->conn->recvmbox); - } - err = ERR_OK; - if (!sys_mbox_valid(&msg->conn->acceptmbox)) { - err = sys_mbox_new(&msg->conn->acceptmbox, DEFAULT_ACCEPTMBOX_SIZE); - } - if (err == ERR_OK) { - msg->conn->state = NETCONN_LISTEN; - msg->conn->pcb.tcp = lpcb; - tcp_arg(msg->conn->pcb.tcp, msg->conn); - tcp_accept(msg->conn->pcb.tcp, accept_function); - } else { - /* since the old pcb is already deallocated, free lpcb now */ - tcp_close(lpcb); - msg->conn->pcb.tcp = NULL; - } - } - } - } else if (msg->conn->state == NETCONN_LISTEN) { - /* already listening, allow updating of the backlog */ - err = ERR_OK; - tcp_backlog_set(msg->conn->pcb.tcp, msg->msg.lb.backlog); - } else { - err = ERR_CONN; - } - } else { - err = ERR_ARG; - } - } else { - err = ERR_CONN; - } - msg->err = err; - TCPIP_APIMSG_ACK(msg); -} -#endif /* LWIP_TCP */ - -/** - * Send some data on a RAW or UDP pcb contained in a netconn - * Called from netconn_send - * - * @param m the api_msg pointing to the connection - */ -void -lwip_netconn_do_send(void *m) -{ - struct api_msg *msg = (struct api_msg *)m; - - err_t err = netconn_err(msg->conn); - if (err == ERR_OK) { - if (msg->conn->pcb.tcp != NULL) { - switch (NETCONNTYPE_GROUP(msg->conn->type)) { -#if LWIP_RAW - case NETCONN_RAW: - if (ip_addr_isany(&msg->msg.b->addr) || IP_IS_ANY_TYPE_VAL(msg->msg.b->addr)) { - err = raw_send(msg->conn->pcb.raw, msg->msg.b->p); - } else { - err = raw_sendto(msg->conn->pcb.raw, msg->msg.b->p, &msg->msg.b->addr); - } - break; -#endif -#if LWIP_UDP - case NETCONN_UDP: -#if LWIP_CHECKSUM_ON_COPY - if (ip_addr_isany(&msg->msg.b->addr) || IP_IS_ANY_TYPE_VAL(msg->msg.b->addr)) { - err = udp_send_chksum(msg->conn->pcb.udp, msg->msg.b->p, - msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum); - } else { - err = udp_sendto_chksum(msg->conn->pcb.udp, msg->msg.b->p, - &msg->msg.b->addr, msg->msg.b->port, - msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum); - } -#else /* LWIP_CHECKSUM_ON_COPY */ - if (ip_addr_isany_val(msg->msg.b->addr) || IP_IS_ANY_TYPE_VAL(msg->msg.b->addr)) { - err = udp_send(msg->conn->pcb.udp, msg->msg.b->p); - } else { - err = udp_sendto(msg->conn->pcb.udp, msg->msg.b->p, &msg->msg.b->addr, msg->msg.b->port); - } -#endif /* LWIP_CHECKSUM_ON_COPY */ - break; -#endif /* LWIP_UDP */ - default: - err = ERR_CONN; - break; - } - } else { - err = ERR_CONN; - } - } - msg->err = err; - TCPIP_APIMSG_ACK(msg); -} - -#if LWIP_TCP -/** - * Indicate data has been received from a TCP pcb contained in a netconn - * Called from netconn_recv - * - * @param m the api_msg pointing to the connection - */ -void -lwip_netconn_do_recv(void *m) -{ - struct api_msg *msg = (struct api_msg *)m; - - msg->err = ERR_OK; - if (msg->conn->pcb.tcp != NULL) { - if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) { - size_t remaining = msg->msg.r.len; - do { - u16_t recved = (u16_t)((remaining > 0xffff) ? 0xffff : remaining); - tcp_recved(msg->conn->pcb.tcp, recved); - remaining -= recved; - } while (remaining != 0); - } - } - TCPIP_APIMSG_ACK(msg); -} - -#if TCP_LISTEN_BACKLOG -/** Indicate that a TCP pcb has been accepted - * Called from netconn_accept - * - * @param m the api_msg pointing to the connection - */ -void -lwip_netconn_do_accepted(void *m) -{ - struct api_msg *msg = (struct api_msg *)m; - - msg->err = ERR_OK; - if (msg->conn->pcb.tcp != NULL) { - if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) { - tcp_backlog_accepted(msg->conn->pcb.tcp); - } - } - TCPIP_APIMSG_ACK(msg); -} -#endif /* TCP_LISTEN_BACKLOG */ - -/** - * See if more data needs to be written from a previous call to netconn_write. - * Called initially from lwip_netconn_do_write. If the first call can't send all data - * (because of low memory or empty send-buffer), this function is called again - * from sent_tcp() or poll_tcp() to send more data. If all data is sent, the - * blocking application thread (waiting in netconn_write) is released. - * - * @param conn netconn (that is currently in state NETCONN_WRITE) to process - * @return ERR_OK - * ERR_MEM if LWIP_TCPIP_CORE_LOCKING=1 and sending hasn't yet finished - */ -static err_t -lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM) -{ - err_t err; - const void *dataptr; - u16_t len, available; - u8_t write_finished = 0; - size_t diff; - u8_t dontblock; - u8_t apiflags; - u8_t write_more; - - LWIP_ASSERT("conn != NULL", conn != NULL); - LWIP_ASSERT("conn->state == NETCONN_WRITE", (conn->state == NETCONN_WRITE)); - LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL); - LWIP_ASSERT("conn->pcb.tcp != NULL", conn->pcb.tcp != NULL); - LWIP_ASSERT("conn->current_msg->msg.w.offset < conn->current_msg->msg.w.len", - conn->current_msg->msg.w.offset < conn->current_msg->msg.w.len); - LWIP_ASSERT("conn->current_msg->msg.w.vector_cnt > 0", conn->current_msg->msg.w.vector_cnt > 0); - - apiflags = conn->current_msg->msg.w.apiflags; - dontblock = netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK); - -#if LWIP_SO_SNDTIMEO - if ((conn->send_timeout != 0) && - ((s32_t)(sys_now() - conn->current_msg->msg.w.time_started) >= conn->send_timeout)) { - write_finished = 1; - if (conn->current_msg->msg.w.offset == 0) { - /* nothing has been written */ - err = ERR_WOULDBLOCK; - } else { - /* partial write */ - err = ERR_OK; - } - } else -#endif /* LWIP_SO_SNDTIMEO */ - { - do { - dataptr = (const u8_t *)conn->current_msg->msg.w.vector->ptr + conn->current_msg->msg.w.vector_off; - diff = conn->current_msg->msg.w.vector->len - conn->current_msg->msg.w.vector_off; - if (diff > 0xffffUL) { /* max_u16_t */ - len = 0xffff; - apiflags |= TCP_WRITE_FLAG_MORE; - } else { - len = (u16_t)diff; - } - available = tcp_sndbuf(conn->pcb.tcp); - if (available < len) { - /* don't try to write more than sendbuf */ - len = available; - if (dontblock) { - if (!len) { - /* set error according to partial write or not */ - err = (conn->current_msg->msg.w.offset == 0) ? ERR_WOULDBLOCK : ERR_OK; - goto err_mem; - } - } else { - apiflags |= TCP_WRITE_FLAG_MORE; - } - } - LWIP_ASSERT("lwip_netconn_do_writemore: invalid length!", - ((conn->current_msg->msg.w.vector_off + len) <= conn->current_msg->msg.w.vector->len)); - /* we should loop around for more sending in the following cases: - 1) We couldn't finish the current vector because of 16-bit size limitations. - tcp_write() and tcp_sndbuf() both are limited to 16-bit sizes - 2) We are sending the remainder of the current vector and have more */ - if ((len == 0xffff && diff > 0xffffUL) || - (len == (u16_t)diff && conn->current_msg->msg.w.vector_cnt > 1)) { - write_more = 1; - apiflags |= TCP_WRITE_FLAG_MORE; - } else { - write_more = 0; - } - err = tcp_write(conn->pcb.tcp, dataptr, len, apiflags); - if (err == ERR_OK) { - conn->current_msg->msg.w.offset += len; - conn->current_msg->msg.w.vector_off += len; - /* check if current vector is finished */ - if (conn->current_msg->msg.w.vector_off == conn->current_msg->msg.w.vector->len) { - conn->current_msg->msg.w.vector_cnt--; - /* if we have additional vectors, move on to them */ - if (conn->current_msg->msg.w.vector_cnt > 0) { - conn->current_msg->msg.w.vector++; - conn->current_msg->msg.w.vector_off = 0; - } - } - } - } while (write_more && err == ERR_OK); - /* if OK or memory error, check available space */ - if ((err == ERR_OK) || (err == ERR_MEM)) { -err_mem: - if (dontblock && (conn->current_msg->msg.w.offset < conn->current_msg->msg.w.len)) { - /* non-blocking write did not write everything: mark the pcb non-writable - and let poll_tcp check writable space to mark the pcb writable again */ - API_EVENT(conn, NETCONN_EVT_SENDMINUS, 0); - conn->flags |= NETCONN_FLAG_CHECK_WRITESPACE; - } else if ((tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT) || - (tcp_sndqueuelen(conn->pcb.tcp) >= TCP_SNDQUEUELOWAT)) { - /* The queued byte- or pbuf-count exceeds the configured low-water limit, - let select mark this pcb as non-writable. */ - API_EVENT(conn, NETCONN_EVT_SENDMINUS, 0); - } - } - - if (err == ERR_OK) { - err_t out_err; - if ((conn->current_msg->msg.w.offset == conn->current_msg->msg.w.len) || dontblock) { - /* return sent length (caller reads length from msg.w.offset) */ - write_finished = 1; - } - out_err = tcp_output(conn->pcb.tcp); - if (out_err == ERR_RTE) { - /* If tcp_output fails because no route is found, - don't try writing any more but return the error - to the application thread. */ - err = out_err; - write_finished = 1; - } - } else if (err == ERR_MEM) { - /* If ERR_MEM, we wait for sent_tcp or poll_tcp to be called. - For blocking sockets, we do NOT return to the application - thread, since ERR_MEM is only a temporary error! Non-blocking - will remain non-writable until sent_tcp/poll_tcp is called */ - - /* tcp_write returned ERR_MEM, try tcp_output anyway */ - err_t out_err = tcp_output(conn->pcb.tcp); - if (out_err == ERR_RTE) { - /* If tcp_output fails because no route is found, - don't try writing any more but return the error - to the application thread. */ - err = out_err; - write_finished = 1; - } else if (dontblock) { - /* non-blocking write is done on ERR_MEM, set error according - to partial write or not */ - err = (conn->current_msg->msg.w.offset == 0) ? ERR_WOULDBLOCK : ERR_OK; - write_finished = 1; - } - } else { - /* On errors != ERR_MEM, we don't try writing any more but return - the error to the application thread. */ - write_finished = 1; - } - } - if (write_finished) { - /* everything was written: set back connection state - and back to application task */ - sys_sem_t *op_completed_sem = LWIP_API_MSG_SEM(conn->current_msg); - conn->current_msg->err = err; - conn->current_msg = NULL; - conn->state = NETCONN_NONE; -#if LWIP_TCPIP_CORE_LOCKING - if (delayed) -#endif - { - sys_sem_signal(op_completed_sem); - } - } -#if LWIP_TCPIP_CORE_LOCKING - else { - return ERR_MEM; - } -#endif - return ERR_OK; -} -#endif /* LWIP_TCP */ - -/** - * Send some data on a TCP pcb contained in a netconn - * Called from netconn_write - * - * @param m the api_msg pointing to the connection - */ -void -lwip_netconn_do_write(void *m) -{ - struct api_msg *msg = (struct api_msg *)m; - - err_t err = netconn_err(msg->conn); - if (err == ERR_OK) { - if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) { -#if LWIP_TCP - if (msg->conn->state != NETCONN_NONE) { - /* netconn is connecting, closing or in blocking write */ - err = ERR_INPROGRESS; - } else if (msg->conn->pcb.tcp != NULL) { - msg->conn->state = NETCONN_WRITE; - /* set all the variables used by lwip_netconn_do_writemore */ - LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL); - LWIP_ASSERT("msg->msg.w.len != 0", msg->msg.w.len != 0); - msg->conn->current_msg = msg; -#if LWIP_TCPIP_CORE_LOCKING - if (lwip_netconn_do_writemore(msg->conn, 0) != ERR_OK) { - LWIP_ASSERT("state!", msg->conn->state == NETCONN_WRITE); - UNLOCK_TCPIP_CORE(); - sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 0); - LOCK_TCPIP_CORE(); - LWIP_ASSERT("state!", msg->conn->state != NETCONN_WRITE); - } -#else /* LWIP_TCPIP_CORE_LOCKING */ - lwip_netconn_do_writemore(msg->conn); -#endif /* LWIP_TCPIP_CORE_LOCKING */ - /* for both cases: if lwip_netconn_do_writemore was called, don't ACK the APIMSG - since lwip_netconn_do_writemore ACKs it! */ - return; - } else { - err = ERR_CONN; - } -#else /* LWIP_TCP */ - err = ERR_VAL; -#endif /* LWIP_TCP */ -#if (LWIP_UDP || LWIP_RAW) - } else { - err = ERR_VAL; -#endif /* (LWIP_UDP || LWIP_RAW) */ - } - } - msg->err = err; - TCPIP_APIMSG_ACK(msg); -} - -/** - * Return a connection's local or remote address - * Called from netconn_getaddr - * - * @param m the api_msg pointing to the connection - */ -void -lwip_netconn_do_getaddr(void *m) -{ - struct api_msg *msg = (struct api_msg *)m; - - if (msg->conn->pcb.ip != NULL) { - if (msg->msg.ad.local) { - ip_addr_copy(API_EXPR_DEREF(msg->msg.ad.ipaddr), - msg->conn->pcb.ip->local_ip); - } else { - ip_addr_copy(API_EXPR_DEREF(msg->msg.ad.ipaddr), - msg->conn->pcb.ip->remote_ip); - } - - msg->err = ERR_OK; - switch (NETCONNTYPE_GROUP(msg->conn->type)) { -#if LWIP_RAW - case NETCONN_RAW: - if (msg->msg.ad.local) { - API_EXPR_DEREF(msg->msg.ad.port) = msg->conn->pcb.raw->protocol; - } else { - /* return an error as connecting is only a helper for upper layers */ - msg->err = ERR_CONN; - } - break; -#endif /* LWIP_RAW */ -#if LWIP_UDP - case NETCONN_UDP: - if (msg->msg.ad.local) { - API_EXPR_DEREF(msg->msg.ad.port) = msg->conn->pcb.udp->local_port; - } else { - if ((msg->conn->pcb.udp->flags & UDP_FLAGS_CONNECTED) == 0) { - msg->err = ERR_CONN; - } else { - API_EXPR_DEREF(msg->msg.ad.port) = msg->conn->pcb.udp->remote_port; - } - } - break; -#endif /* LWIP_UDP */ -#if LWIP_TCP - case NETCONN_TCP: - if ((msg->msg.ad.local == 0) && - ((msg->conn->pcb.tcp->state == CLOSED) || (msg->conn->pcb.tcp->state == LISTEN))) { - /* pcb is not connected and remote name is requested */ - msg->err = ERR_CONN; - } else { - API_EXPR_DEREF(msg->msg.ad.port) = (msg->msg.ad.local ? msg->conn->pcb.tcp->local_port : msg->conn->pcb.tcp->remote_port); - } - break; -#endif /* LWIP_TCP */ - default: - LWIP_ASSERT("invalid netconn_type", 0); - break; - } - } else { - msg->err = ERR_CONN; - } - TCPIP_APIMSG_ACK(msg); -} - -/** - * Close or half-shutdown a TCP pcb contained in a netconn - * Called from netconn_close - * In contrast to closing sockets, the netconn is not deallocated. - * - * @param m the api_msg pointing to the connection - */ -void -lwip_netconn_do_close(void *m) -{ - struct api_msg *msg = (struct api_msg *)m; - -#if LWIP_TCP - enum netconn_state state = msg->conn->state; - /* First check if this is a TCP netconn and if it is in a correct state - (LISTEN doesn't support half shutdown) */ - if ((msg->conn->pcb.tcp != NULL) && - (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) && - ((msg->msg.sd.shut == NETCONN_SHUT_RDWR) || (state != NETCONN_LISTEN))) { - /* Check if we are in a connected state */ - if (state == NETCONN_CONNECT) { - /* TCP connect in progress: cannot shutdown */ - msg->err = ERR_CONN; - } else if (state == NETCONN_WRITE) { -#if LWIP_NETCONN_FULLDUPLEX - if (msg->msg.sd.shut & NETCONN_SHUT_WR) { - /* close requested, abort running write */ - sys_sem_t *write_completed_sem; - LWIP_ASSERT("msg->conn->current_msg != NULL", msg->conn->current_msg != NULL); - write_completed_sem = LWIP_API_MSG_SEM(msg->conn->current_msg); - msg->conn->current_msg->err = ERR_CLSD; - msg->conn->current_msg = NULL; - msg->conn->state = NETCONN_NONE; - state = NETCONN_NONE; - sys_sem_signal(write_completed_sem); - } else { - LWIP_ASSERT("msg->msg.sd.shut == NETCONN_SHUT_RD", msg->msg.sd.shut == NETCONN_SHUT_RD); - /* In this case, let the write continue and do not interfere with - conn->current_msg or conn->state! */ - msg->err = tcp_shutdown(msg->conn->pcb.tcp, 1, 0); - } - } - if (state == NETCONN_NONE) { -#else /* LWIP_NETCONN_FULLDUPLEX */ - msg->err = ERR_INPROGRESS; - } else { -#endif /* LWIP_NETCONN_FULLDUPLEX */ - if (msg->msg.sd.shut & NETCONN_SHUT_RD) { -#if LWIP_NETCONN_FULLDUPLEX - /* Mark mboxes invalid */ - netconn_mark_mbox_invalid(msg->conn); -#else /* LWIP_NETCONN_FULLDUPLEX */ - netconn_drain(msg->conn); -#endif /* LWIP_NETCONN_FULLDUPLEX */ - } - LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL); - msg->conn->state = NETCONN_CLOSE; - msg->conn->current_msg = msg; -#if LWIP_TCPIP_CORE_LOCKING - if (lwip_netconn_do_close_internal(msg->conn, 0) != ERR_OK) { - LWIP_ASSERT("state!", msg->conn->state == NETCONN_CLOSE); - UNLOCK_TCPIP_CORE(); - sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 0); - LOCK_TCPIP_CORE(); - LWIP_ASSERT("state!", msg->conn->state == NETCONN_NONE); - } -#else /* LWIP_TCPIP_CORE_LOCKING */ - lwip_netconn_do_close_internal(msg->conn); -#endif /* LWIP_TCPIP_CORE_LOCKING */ - /* for tcp netconns, lwip_netconn_do_close_internal ACKs the message */ - return; - } - } else -#endif /* LWIP_TCP */ - { - msg->err = ERR_CONN; - } - TCPIP_APIMSG_ACK(msg); -} - -#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) -/** - * Join multicast groups for UDP netconns. - * Called from netconn_join_leave_group - * - * @param m the api_msg pointing to the connection - */ -void -lwip_netconn_do_join_leave_group(void *m) -{ - struct api_msg *msg = (struct api_msg *)m; - - msg->err = ERR_CONN; - if (msg->conn->pcb.tcp != NULL) { - if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) { -#if LWIP_UDP -#if LWIP_IPV6 && LWIP_IPV6_MLD - if (NETCONNTYPE_ISIPV6(msg->conn->type)) { - if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { - msg->err = mld6_joingroup(ip_2_ip6(API_EXPR_REF(msg->msg.jl.netif_addr)), - ip_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr))); - } else { - msg->err = mld6_leavegroup(ip_2_ip6(API_EXPR_REF(msg->msg.jl.netif_addr)), - ip_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr))); - } - } else -#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ - { -#if LWIP_IGMP - if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { - msg->err = igmp_joingroup(ip_2_ip4(API_EXPR_REF(msg->msg.jl.netif_addr)), - ip_2_ip4(API_EXPR_REF(msg->msg.jl.multiaddr))); - } else { - msg->err = igmp_leavegroup(ip_2_ip4(API_EXPR_REF(msg->msg.jl.netif_addr)), - ip_2_ip4(API_EXPR_REF(msg->msg.jl.multiaddr))); - } -#endif /* LWIP_IGMP */ - } -#endif /* LWIP_UDP */ -#if (LWIP_TCP || LWIP_RAW) - } else { - msg->err = ERR_VAL; -#endif /* (LWIP_TCP || LWIP_RAW) */ - } - } - TCPIP_APIMSG_ACK(msg); -} -/** - * Join multicast groups for UDP netconns. - * Called from netconn_join_leave_group_netif - * - * @param m the api_msg pointing to the connection - */ -void -lwip_netconn_do_join_leave_group_netif(void *m) -{ - struct api_msg *msg = (struct api_msg *)m; - struct netif *netif; - - netif = netif_get_by_index(msg->msg.jl.if_idx); - if (netif == NULL) { - msg->err = ERR_IF; - goto done; - } - - msg->err = ERR_CONN; - if (msg->conn->pcb.tcp != NULL) { - if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) { -#if LWIP_UDP -#if LWIP_IPV6 && LWIP_IPV6_MLD - if (NETCONNTYPE_ISIPV6(msg->conn->type)) { - if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { - msg->err = mld6_joingroup_netif(netif, - ip_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr))); - } else { - msg->err = mld6_leavegroup_netif(netif, - ip_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr))); - } - } else -#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ - { -#if LWIP_IGMP - if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { - msg->err = igmp_joingroup_netif(netif, - ip_2_ip4(API_EXPR_REF(msg->msg.jl.multiaddr))); - } else { - msg->err = igmp_leavegroup_netif(netif, - ip_2_ip4(API_EXPR_REF(msg->msg.jl.multiaddr))); - } -#endif /* LWIP_IGMP */ - } -#endif /* LWIP_UDP */ -#if (LWIP_TCP || LWIP_RAW) - } else { - msg->err = ERR_VAL; -#endif /* (LWIP_TCP || LWIP_RAW) */ - } - } - -done: - TCPIP_APIMSG_ACK(msg); -} -#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ - -#if LWIP_DNS -/** - * Callback function that is called when DNS name is resolved - * (or on timeout). A waiting application thread is waked up by - * signaling the semaphore. - */ -static void -lwip_netconn_do_dns_found(const char *name, const ip_addr_t *ipaddr, void *arg) -{ - struct dns_api_msg *msg = (struct dns_api_msg *)arg; - - /* we trust the internal implementation to be correct :-) */ - LWIP_UNUSED_ARG(name); - - if (ipaddr == NULL) { - /* timeout or memory error */ - API_EXPR_DEREF(msg->err) = ERR_VAL; - } else { - /* address was resolved */ - API_EXPR_DEREF(msg->err) = ERR_OK; - API_EXPR_DEREF(msg->addr) = *ipaddr; - } - /* wake up the application task waiting in netconn_gethostbyname */ - sys_sem_signal(API_EXPR_REF_SEM(msg->sem)); -} - -/** - * Execute a DNS query - * Called from netconn_gethostbyname - * - * @param arg the dns_api_msg pointing to the query - */ -void -lwip_netconn_do_gethostbyname(void *arg) -{ - struct dns_api_msg *msg = (struct dns_api_msg *)arg; - u8_t addrtype = -#if LWIP_IPV4 && LWIP_IPV6 - msg->dns_addrtype; -#else - LWIP_DNS_ADDRTYPE_DEFAULT; -#endif - - API_EXPR_DEREF(msg->err) = dns_gethostbyname_addrtype(msg->name, - API_EXPR_REF(msg->addr), lwip_netconn_do_dns_found, msg, addrtype); -#if LWIP_TCPIP_CORE_LOCKING - /* For core locking, only block if we need to wait for answer/timeout */ - if (API_EXPR_DEREF(msg->err) == ERR_INPROGRESS) { - UNLOCK_TCPIP_CORE(); - sys_sem_wait(API_EXPR_REF_SEM(msg->sem)); - LOCK_TCPIP_CORE(); - LWIP_ASSERT("do_gethostbyname still in progress!!", API_EXPR_DEREF(msg->err) != ERR_INPROGRESS); - } -#else /* LWIP_TCPIP_CORE_LOCKING */ - if (API_EXPR_DEREF(msg->err) != ERR_INPROGRESS) { - /* on error or immediate success, wake up the application - * task waiting in netconn_gethostbyname */ - sys_sem_signal(API_EXPR_REF_SEM(msg->sem)); - } -#endif /* LWIP_TCPIP_CORE_LOCKING */ -} -#endif /* LWIP_DNS */ - -#endif /* LWIP_NETCONN */ diff --git a/third-party/lwip-2.1.2/api/err.c b/third-party/lwip-2.1.2/api/err.c deleted file mode 100644 index dd2b62da..00000000 --- a/third-party/lwip-2.1.2/api/err.c +++ /dev/null @@ -1,115 +0,0 @@ -/** - * @file - * Error Management module - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#include "lwip/err.h" -#include "lwip/def.h" -#include "lwip/sys.h" - -#include "lwip/errno.h" - -#if !NO_SYS -/** Table to quickly map an lwIP error (err_t) to a socket error - * by using -err as an index */ -static const int err_to_errno_table[] = { - 0, /* ERR_OK 0 No error, everything OK. */ - ENOMEM, /* ERR_MEM -1 Out of memory error. */ - ENOBUFS, /* ERR_BUF -2 Buffer error. */ - EWOULDBLOCK, /* ERR_TIMEOUT -3 Timeout */ - EHOSTUNREACH, /* ERR_RTE -4 Routing problem. */ - EINPROGRESS, /* ERR_INPROGRESS -5 Operation in progress */ - EINVAL, /* ERR_VAL -6 Illegal value. */ - EWOULDBLOCK, /* ERR_WOULDBLOCK -7 Operation would block. */ - EADDRINUSE, /* ERR_USE -8 Address in use. */ - EALREADY, /* ERR_ALREADY -9 Already connecting. */ - EISCONN, /* ERR_ISCONN -10 Conn already established.*/ - ENOTCONN, /* ERR_CONN -11 Not connected. */ - -1, /* ERR_IF -12 Low-level netif error */ - ECONNABORTED, /* ERR_ABRT -13 Connection aborted. */ - ECONNRESET, /* ERR_RST -14 Connection reset. */ - ENOTCONN, /* ERR_CLSD -15 Connection closed. */ - EIO /* ERR_ARG -16 Illegal argument. */ -}; - -int -err_to_errno(err_t err) -{ - if ((err > 0) || (-err >= (err_t)LWIP_ARRAYSIZE(err_to_errno_table))) { - return EIO; - } - return err_to_errno_table[-err]; -} -#endif /* !NO_SYS */ - -#ifdef LWIP_DEBUG - -static const char *err_strerr[] = { - "Ok.", /* ERR_OK 0 */ - "Out of memory error.", /* ERR_MEM -1 */ - "Buffer error.", /* ERR_BUF -2 */ - "Timeout.", /* ERR_TIMEOUT -3 */ - "Routing problem.", /* ERR_RTE -4 */ - "Operation in progress.", /* ERR_INPROGRESS -5 */ - "Illegal value.", /* ERR_VAL -6 */ - "Operation would block.", /* ERR_WOULDBLOCK -7 */ - "Address in use.", /* ERR_USE -8 */ - "Already connecting.", /* ERR_ALREADY -9 */ - "Already connected.", /* ERR_ISCONN -10 */ - "Not connected.", /* ERR_CONN -11 */ - "Low-level netif error.", /* ERR_IF -12 */ - "Connection aborted.", /* ERR_ABRT -13 */ - "Connection reset.", /* ERR_RST -14 */ - "Connection closed.", /* ERR_CLSD -15 */ - "Illegal argument." /* ERR_ARG -16 */ -}; - -/** - * Convert an lwip internal error to a string representation. - * - * @param err an lwip internal err_t - * @return a string representation for err - */ -const char * -lwip_strerr(err_t err) -{ - if ((err > 0) || (-err >= (err_t)LWIP_ARRAYSIZE(err_strerr))) { - return "Unknown error."; - } - return err_strerr[-err]; -} - -#endif /* LWIP_DEBUG */ diff --git a/third-party/lwip-2.1.2/api/if_api.c b/third-party/lwip-2.1.2/api/if_api.c deleted file mode 100644 index 8e094d09..00000000 --- a/third-party/lwip-2.1.2/api/if_api.c +++ /dev/null @@ -1,102 +0,0 @@ -/** - * @file - * Interface Identification APIs from: - * RFC 3493: Basic Socket Interface Extensions for IPv6 - * Section 4: Interface Identification - * - * @defgroup if_api Interface Identification API - * @ingroup socket - */ - -/* - * Copyright (c) 2017 Joel Cunningham, Garmin International, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Joel Cunningham - * - */ -#include "lwip/opt.h" - -#if LWIP_SOCKET - -#include "lwip/errno.h" -#include "lwip/if_api.h" -#include "lwip/netifapi.h" -#include "lwip/priv/sockets_priv.h" - -/** - * @ingroup if_api - * Maps an interface index to its corresponding name. - * @param ifindex interface index - * @param ifname shall point to a buffer of at least {IF_NAMESIZE} bytes - * @return If ifindex is an interface index, then the function shall return the - * value supplied in ifname, which points to a buffer now containing the interface name. - * Otherwise, the function shall return a NULL pointer. - */ -char * -lwip_if_indextoname(unsigned int ifindex, char *ifname) -{ -#if LWIP_NETIF_API - if (ifindex <= 0xff) { - err_t err = netifapi_netif_index_to_name((u8_t)ifindex, ifname); - if (!err && ifname[0] != '\0') { - return ifname; - } - } -#else /* LWIP_NETIF_API */ - LWIP_UNUSED_ARG(ifindex); - LWIP_UNUSED_ARG(ifname); -#endif /* LWIP_NETIF_API */ - set_errno(ENXIO); - return NULL; -} - -/** - * @ingroup if_api - * Returs the interface index corresponding to name ifname. - * @param ifname Interface name - * @return The corresponding index if ifname is the name of an interface; - * otherwise, zero. - */ -unsigned int -lwip_if_nametoindex(const char *ifname) -{ -#if LWIP_NETIF_API - err_t err; - u8_t idx; - - err = netifapi_netif_name_to_index(ifname, &idx); - if (!err) { - return idx; - } -#else /* LWIP_NETIF_API */ - LWIP_UNUSED_ARG(ifname); -#endif /* LWIP_NETIF_API */ - return 0; /* invalid index */ -} - -#endif /* LWIP_SOCKET */ diff --git a/third-party/lwip-2.1.2/api/netbuf.c b/third-party/lwip-2.1.2/api/netbuf.c deleted file mode 100644 index 3b910de1..00000000 --- a/third-party/lwip-2.1.2/api/netbuf.c +++ /dev/null @@ -1,250 +0,0 @@ -/** - * @file - * Network buffer management - * - * @defgroup netbuf Network buffers - * @ingroup netconn - * Network buffer descriptor for @ref netconn. Based on @ref pbuf internally - * to avoid copying data around.\n - * Buffers must not be shared accross multiple threads, all functions except - * netbuf_new() and netbuf_delete() are not thread-safe. - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#include "lwip/opt.h" - -#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/netbuf.h" -#include "lwip/memp.h" - -#include - -/** - * @ingroup netbuf - * Create (allocate) and initialize a new netbuf. - * The netbuf doesn't yet contain a packet buffer! - * - * @return a pointer to a new netbuf - * NULL on lack of memory - */ -struct -netbuf *netbuf_new(void) -{ - struct netbuf *buf; - - buf = (struct netbuf *)memp_malloc(MEMP_NETBUF); - if (buf != NULL) { - memset(buf, 0, sizeof(struct netbuf)); - } - return buf; -} - -/** - * @ingroup netbuf - * Deallocate a netbuf allocated by netbuf_new(). - * - * @param buf pointer to a netbuf allocated by netbuf_new() - */ -void -netbuf_delete(struct netbuf *buf) -{ - if (buf != NULL) { - if (buf->p != NULL) { - pbuf_free(buf->p); - buf->p = buf->ptr = NULL; - } - memp_free(MEMP_NETBUF, buf); - } -} - -/** - * @ingroup netbuf - * Allocate memory for a packet buffer for a given netbuf. - * - * @param buf the netbuf for which to allocate a packet buffer - * @param size the size of the packet buffer to allocate - * @return pointer to the allocated memory - * NULL if no memory could be allocated - */ -void * -netbuf_alloc(struct netbuf *buf, u16_t size) -{ - LWIP_ERROR("netbuf_alloc: invalid buf", (buf != NULL), return NULL;); - - /* Deallocate any previously allocated memory. */ - if (buf->p != NULL) { - pbuf_free(buf->p); - } - buf->p = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM); - if (buf->p == NULL) { - return NULL; - } - LWIP_ASSERT("check that first pbuf can hold size", - (buf->p->len >= size)); - buf->ptr = buf->p; - return buf->p->payload; -} - -/** - * @ingroup netbuf - * Free the packet buffer included in a netbuf - * - * @param buf pointer to the netbuf which contains the packet buffer to free - */ -void -netbuf_free(struct netbuf *buf) -{ - LWIP_ERROR("netbuf_free: invalid buf", (buf != NULL), return;); - if (buf->p != NULL) { - pbuf_free(buf->p); - } - buf->p = buf->ptr = NULL; -#if LWIP_CHECKSUM_ON_COPY - buf->flags = 0; - buf->toport_chksum = 0; -#endif /* LWIP_CHECKSUM_ON_COPY */ -} - -/** - * @ingroup netbuf - * Let a netbuf reference existing (non-volatile) data. - * - * @param buf netbuf which should reference the data - * @param dataptr pointer to the data to reference - * @param size size of the data - * @return ERR_OK if data is referenced - * ERR_MEM if data couldn't be referenced due to lack of memory - */ -err_t -netbuf_ref(struct netbuf *buf, const void *dataptr, u16_t size) -{ - LWIP_ERROR("netbuf_ref: invalid buf", (buf != NULL), return ERR_ARG;); - if (buf->p != NULL) { - pbuf_free(buf->p); - } - buf->p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_REF); - if (buf->p == NULL) { - buf->ptr = NULL; - return ERR_MEM; - } - ((struct pbuf_rom *)buf->p)->payload = dataptr; - buf->p->len = buf->p->tot_len = size; - buf->ptr = buf->p; - return ERR_OK; -} - -/** - * @ingroup netbuf - * Chain one netbuf to another (@see pbuf_chain) - * - * @param head the first netbuf - * @param tail netbuf to chain after head, freed by this function, may not be reference after returning - */ -void -netbuf_chain(struct netbuf *head, struct netbuf *tail) -{ - LWIP_ERROR("netbuf_chain: invalid head", (head != NULL), return;); - LWIP_ERROR("netbuf_chain: invalid tail", (tail != NULL), return;); - pbuf_cat(head->p, tail->p); - head->ptr = head->p; - memp_free(MEMP_NETBUF, tail); -} - -/** - * @ingroup netbuf - * Get the data pointer and length of the data inside a netbuf. - * - * @param buf netbuf to get the data from - * @param dataptr pointer to a void pointer where to store the data pointer - * @param len pointer to an u16_t where the length of the data is stored - * @return ERR_OK if the information was retrieved, - * ERR_BUF on error. - */ -err_t -netbuf_data(struct netbuf *buf, void **dataptr, u16_t *len) -{ - LWIP_ERROR("netbuf_data: invalid buf", (buf != NULL), return ERR_ARG;); - LWIP_ERROR("netbuf_data: invalid dataptr", (dataptr != NULL), return ERR_ARG;); - LWIP_ERROR("netbuf_data: invalid len", (len != NULL), return ERR_ARG;); - - if (buf->ptr == NULL) { - return ERR_BUF; - } - *dataptr = buf->ptr->payload; - *len = buf->ptr->len; - return ERR_OK; -} - -/** - * @ingroup netbuf - * Move the current data pointer of a packet buffer contained in a netbuf - * to the next part. - * The packet buffer itself is not modified. - * - * @param buf the netbuf to modify - * @return -1 if there is no next part - * 1 if moved to the next part but now there is no next part - * 0 if moved to the next part and there are still more parts - */ -s8_t -netbuf_next(struct netbuf *buf) -{ - LWIP_ERROR("netbuf_next: invalid buf", (buf != NULL), return -1;); - if (buf->ptr->next == NULL) { - return -1; - } - buf->ptr = buf->ptr->next; - if (buf->ptr->next == NULL) { - return 1; - } - return 0; -} - -/** - * @ingroup netbuf - * Move the current data pointer of a packet buffer contained in a netbuf - * to the beginning of the packet. - * The packet buffer itself is not modified. - * - * @param buf the netbuf to modify - */ -void -netbuf_first(struct netbuf *buf) -{ - LWIP_ERROR("netbuf_first: invalid buf", (buf != NULL), return;); - buf->ptr = buf->p; -} - -#endif /* LWIP_NETCONN */ diff --git a/third-party/lwip-2.1.2/api/netdb.c b/third-party/lwip-2.1.2/api/netdb.c deleted file mode 100644 index 87714259..00000000 --- a/third-party/lwip-2.1.2/api/netdb.c +++ /dev/null @@ -1,414 +0,0 @@ -/** - * @file - * API functions for name resolving - * - * @defgroup netdbapi NETDB API - * @ingroup socket - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Simon Goldschmidt - * - */ - -#include "lwip/netdb.h" - -#if LWIP_DNS && LWIP_SOCKET - -#include "lwip/err.h" -#include "lwip/mem.h" -#include "lwip/memp.h" -#include "lwip/ip_addr.h" -#include "lwip/api.h" -#include "lwip/dns.h" - -#include /* memset */ -#include /* atoi */ - -/** helper struct for gethostbyname_r to access the char* buffer */ -struct gethostbyname_r_helper { - ip_addr_t *addr_list[2]; - ip_addr_t addr; - char *aliases; -}; - -/** h_errno is exported in netdb.h for access by applications. */ -#if LWIP_DNS_API_DECLARE_H_ERRNO -int h_errno; -#endif /* LWIP_DNS_API_DECLARE_H_ERRNO */ - -/** define "hostent" variables storage: 0 if we use a static (but unprotected) - * set of variables for lwip_gethostbyname, 1 if we use a local storage */ -#ifndef LWIP_DNS_API_HOSTENT_STORAGE -#define LWIP_DNS_API_HOSTENT_STORAGE 0 -#endif - -/** define "hostent" variables storage */ -#if LWIP_DNS_API_HOSTENT_STORAGE -#define HOSTENT_STORAGE -#else -#define HOSTENT_STORAGE static -#endif /* LWIP_DNS_API_STATIC_HOSTENT */ - -/** - * Returns an entry containing addresses of address family AF_INET - * for the host with name name. - * Due to dns_gethostbyname limitations, only one address is returned. - * - * @param name the hostname to resolve - * @return an entry containing addresses of address family AF_INET - * for the host with name name - */ -struct hostent * -lwip_gethostbyname(const char *name) -{ - err_t err; - ip_addr_t addr; - - /* buffer variables for lwip_gethostbyname() */ - HOSTENT_STORAGE struct hostent s_hostent; - HOSTENT_STORAGE char *s_aliases; - HOSTENT_STORAGE ip_addr_t s_hostent_addr; - HOSTENT_STORAGE ip_addr_t *s_phostent_addr[2]; - HOSTENT_STORAGE char s_hostname[DNS_MAX_NAME_LENGTH + 1]; - - /* query host IP address */ - err = netconn_gethostbyname(name, &addr); - if (err != ERR_OK) { - LWIP_DEBUGF(DNS_DEBUG, ("lwip_gethostbyname(%s) failed, err=%d\n", name, err)); - h_errno = HOST_NOT_FOUND; - return NULL; - } - - /* fill hostent */ - s_hostent_addr = addr; - s_phostent_addr[0] = &s_hostent_addr; - s_phostent_addr[1] = NULL; - strncpy(s_hostname, name, DNS_MAX_NAME_LENGTH); - s_hostname[DNS_MAX_NAME_LENGTH] = 0; - s_hostent.h_name = s_hostname; - s_aliases = NULL; - s_hostent.h_aliases = &s_aliases; - s_hostent.h_addrtype = AF_INET; - s_hostent.h_length = sizeof(ip_addr_t); - s_hostent.h_addr_list = (char **)&s_phostent_addr; - -#if DNS_DEBUG - /* dump hostent */ - LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_name == %s\n", s_hostent.h_name)); - LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases == %p\n", (void *)s_hostent.h_aliases)); - /* h_aliases are always empty */ - LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addrtype == %d\n", s_hostent.h_addrtype)); - LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_length == %d\n", s_hostent.h_length)); - LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list == %p\n", (void *)s_hostent.h_addr_list)); - if (s_hostent.h_addr_list != NULL) { - u8_t idx; - for (idx = 0; s_hostent.h_addr_list[idx]; idx++) { - LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i] == %p\n", idx, s_hostent.h_addr_list[idx])); - LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i]-> == %s\n", idx, ipaddr_ntoa((ip_addr_t *)s_hostent.h_addr_list[idx]))); - } - } -#endif /* DNS_DEBUG */ - -#if LWIP_DNS_API_HOSTENT_STORAGE - /* this function should return the "per-thread" hostent after copy from s_hostent */ - return sys_thread_hostent(&s_hostent); -#else - return &s_hostent; -#endif /* LWIP_DNS_API_HOSTENT_STORAGE */ -} - -/** - * Thread-safe variant of lwip_gethostbyname: instead of using a static - * buffer, this function takes buffer and errno pointers as arguments - * and uses these for the result. - * - * @param name the hostname to resolve - * @param ret pre-allocated struct where to store the result - * @param buf pre-allocated buffer where to store additional data - * @param buflen the size of buf - * @param result pointer to a hostent pointer that is set to ret on success - * and set to zero on error - * @param h_errnop pointer to an int where to store errors (instead of modifying - * the global h_errno) - * @return 0 on success, non-zero on error, additional error information - * is stored in *h_errnop instead of h_errno to be thread-safe - */ -int -lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf, - size_t buflen, struct hostent **result, int *h_errnop) -{ - err_t err; - struct gethostbyname_r_helper *h; - char *hostname; - size_t namelen; - int lh_errno; - - if (h_errnop == NULL) { - /* ensure h_errnop is never NULL */ - h_errnop = &lh_errno; - } - - if (result == NULL) { - /* not all arguments given */ - *h_errnop = EINVAL; - return -1; - } - /* first thing to do: set *result to nothing */ - *result = NULL; - if ((name == NULL) || (ret == NULL) || (buf == NULL)) { - /* not all arguments given */ - *h_errnop = EINVAL; - return -1; - } - - namelen = strlen(name); - if (buflen < (sizeof(struct gethostbyname_r_helper) + LWIP_MEM_ALIGN_BUFFER(namelen + 1))) { - /* buf can't hold the data needed + a copy of name */ - *h_errnop = ERANGE; - return -1; - } - - h = (struct gethostbyname_r_helper *)LWIP_MEM_ALIGN(buf); - hostname = ((char *)h) + sizeof(struct gethostbyname_r_helper); - - /* query host IP address */ - err = netconn_gethostbyname(name, &h->addr); - if (err != ERR_OK) { - LWIP_DEBUGF(DNS_DEBUG, ("lwip_gethostbyname(%s) failed, err=%d\n", name, err)); - *h_errnop = HOST_NOT_FOUND; - return -1; - } - - /* copy the hostname into buf */ - MEMCPY(hostname, name, namelen); - hostname[namelen] = 0; - - /* fill hostent */ - h->addr_list[0] = &h->addr; - h->addr_list[1] = NULL; - h->aliases = NULL; - ret->h_name = hostname; - ret->h_aliases = &h->aliases; - ret->h_addrtype = AF_INET; - ret->h_length = sizeof(ip_addr_t); - ret->h_addr_list = (char **)&h->addr_list; - - /* set result != NULL */ - *result = ret; - - /* return success */ - return 0; -} - -/** - * Frees one or more addrinfo structures returned by getaddrinfo(), along with - * any additional storage associated with those structures. If the ai_next field - * of the structure is not null, the entire list of structures is freed. - * - * @param ai struct addrinfo to free - */ -void -lwip_freeaddrinfo(struct addrinfo *ai) -{ - struct addrinfo *next; - - while (ai != NULL) { - next = ai->ai_next; - memp_free(MEMP_NETDB, ai); - ai = next; - } -} - -/** - * Translates the name of a service location (for example, a host name) and/or - * a service name and returns a set of socket addresses and associated - * information to be used in creating a socket with which to address the - * specified service. - * Memory for the result is allocated internally and must be freed by calling - * lwip_freeaddrinfo()! - * - * Due to a limitation in dns_gethostbyname, only the first address of a - * host is returned. - * Also, service names are not supported (only port numbers)! - * - * @param nodename descriptive name or address string of the host - * (may be NULL -> local address) - * @param servname port number as string of NULL - * @param hints structure containing input values that set socktype and protocol - * @param res pointer to a pointer where to store the result (set to NULL on failure) - * @return 0 on success, non-zero on failure - * - * @todo: implement AI_V4MAPPED, AI_ADDRCONFIG - */ -int -lwip_getaddrinfo(const char *nodename, const char *servname, - const struct addrinfo *hints, struct addrinfo **res) -{ - err_t err; - ip_addr_t addr; - struct addrinfo *ai; - struct sockaddr_storage *sa = NULL; - int port_nr = 0; - size_t total_size; - size_t namelen = 0; - int ai_family; - - if (res == NULL) { - return EAI_FAIL; - } - *res = NULL; - if ((nodename == NULL) && (servname == NULL)) { - return EAI_NONAME; - } - - if (hints != NULL) { - ai_family = hints->ai_family; - if ((ai_family != AF_UNSPEC) -#if LWIP_IPV4 - && (ai_family != AF_INET) -#endif /* LWIP_IPV4 */ -#if LWIP_IPV6 - && (ai_family != AF_INET6) -#endif /* LWIP_IPV6 */ - ) { - return EAI_FAMILY; - } - } else { - ai_family = AF_UNSPEC; - } - - if (servname != NULL) { - /* service name specified: convert to port number - * @todo?: currently, only ASCII integers (port numbers) are supported (AI_NUMERICSERV)! */ - port_nr = atoi(servname); - if ((port_nr <= 0) || (port_nr > 0xffff)) { - return EAI_SERVICE; - } - } - - if (nodename != NULL) { - /* service location specified, try to resolve */ - if ((hints != NULL) && (hints->ai_flags & AI_NUMERICHOST)) { - /* no DNS lookup, just parse for an address string */ - if (!ipaddr_aton(nodename, &addr)) { - return EAI_NONAME; - } -#if LWIP_IPV4 && LWIP_IPV6 - if ((IP_IS_V6_VAL(addr) && ai_family == AF_INET) || - (IP_IS_V4_VAL(addr) && ai_family == AF_INET6)) { - return EAI_NONAME; - } -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - } else { -#if LWIP_IPV4 && LWIP_IPV6 - /* AF_UNSPEC: prefer IPv4 */ - u8_t type = NETCONN_DNS_IPV4_IPV6; - if (ai_family == AF_INET) { - type = NETCONN_DNS_IPV4; - } else if (ai_family == AF_INET6) { - type = NETCONN_DNS_IPV6; - } -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - err = netconn_gethostbyname_addrtype(nodename, &addr, type); - if (err != ERR_OK) { - return EAI_FAIL; - } - } - } else { - /* service location specified, use loopback address */ - if ((hints != NULL) && (hints->ai_flags & AI_PASSIVE)) { - ip_addr_set_any_val(ai_family == AF_INET6, addr); - } else { - ip_addr_set_loopback_val(ai_family == AF_INET6, addr); - } - } - - total_size = sizeof(struct addrinfo) + sizeof(struct sockaddr_storage); - if (nodename != NULL) { - namelen = strlen(nodename); - if (namelen > DNS_MAX_NAME_LENGTH) { - /* invalid name length */ - return EAI_FAIL; - } - LWIP_ASSERT("namelen is too long", total_size + namelen + 1 > total_size); - total_size += namelen + 1; - } - /* If this fails, please report to lwip-devel! :-) */ - LWIP_ASSERT("total_size <= NETDB_ELEM_SIZE: please report this!", - total_size <= NETDB_ELEM_SIZE); - ai = (struct addrinfo *)memp_malloc(MEMP_NETDB); - if (ai == NULL) { - return EAI_MEMORY; - } - memset(ai, 0, total_size); - /* cast through void* to get rid of alignment warnings */ - sa = (struct sockaddr_storage *)(void *)((u8_t *)ai + sizeof(struct addrinfo)); - if (IP_IS_V6_VAL(addr)) { -#if LWIP_IPV6 - struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)sa; - /* set up sockaddr */ - inet6_addr_from_ip6addr(&sa6->sin6_addr, ip_2_ip6(&addr)); - sa6->sin6_family = AF_INET6; - sa6->sin6_len = sizeof(struct sockaddr_in6); - sa6->sin6_port = lwip_htons((u16_t)port_nr); - sa6->sin6_scope_id = ip6_addr_zone(ip_2_ip6(&addr)); - ai->ai_family = AF_INET6; -#endif /* LWIP_IPV6 */ - } else { -#if LWIP_IPV4 - struct sockaddr_in *sa4 = (struct sockaddr_in *)sa; - /* set up sockaddr */ - inet_addr_from_ip4addr(&sa4->sin_addr, ip_2_ip4(&addr)); - sa4->sin_family = AF_INET; - sa4->sin_len = sizeof(struct sockaddr_in); - sa4->sin_port = lwip_htons((u16_t)port_nr); - ai->ai_family = AF_INET; -#endif /* LWIP_IPV4 */ - } - - /* set up addrinfo */ - if (hints != NULL) { - /* copy socktype & protocol from hints if specified */ - ai->ai_socktype = hints->ai_socktype; - ai->ai_protocol = hints->ai_protocol; - } - if (nodename != NULL) { - /* copy nodename to canonname if specified */ - ai->ai_canonname = ((char *)ai + sizeof(struct addrinfo) + sizeof(struct sockaddr_storage)); - MEMCPY(ai->ai_canonname, nodename, namelen); - ai->ai_canonname[namelen] = 0; - } - ai->ai_addrlen = sizeof(struct sockaddr_storage); - ai->ai_addr = (struct sockaddr *)sa; - - *res = ai; - - return 0; -} - -#endif /* LWIP_DNS && LWIP_SOCKET */ diff --git a/third-party/lwip-2.1.2/api/netifapi.c b/third-party/lwip-2.1.2/api/netifapi.c deleted file mode 100644 index 25957cd5..00000000 --- a/third-party/lwip-2.1.2/api/netifapi.c +++ /dev/null @@ -1,380 +0,0 @@ -/** - * @file - * Network Interface Sequential API module - * - * @defgroup netifapi NETIF API - * @ingroup sequential_api - * Thread-safe functions to be called from non-TCPIP threads - * - * @defgroup netifapi_netif NETIF related - * @ingroup netifapi - * To be called from non-TCPIP threads - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#include "lwip/opt.h" - -#if LWIP_NETIF_API /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/etharp.h" -#include "lwip/netifapi.h" -#include "lwip/memp.h" -#include "lwip/priv/tcpip_priv.h" - -#include /* strncpy */ - -#define NETIFAPI_VAR_REF(name) API_VAR_REF(name) -#define NETIFAPI_VAR_DECLARE(name) API_VAR_DECLARE(struct netifapi_msg, name) -#define NETIFAPI_VAR_ALLOC(name) API_VAR_ALLOC(struct netifapi_msg, MEMP_NETIFAPI_MSG, name, ERR_MEM) -#define NETIFAPI_VAR_FREE(name) API_VAR_FREE(MEMP_NETIFAPI_MSG, name) - -/** - * Call netif_add() inside the tcpip_thread context. - */ -static err_t -netifapi_do_netif_add(struct tcpip_api_call_data *m) -{ - /* cast through void* to silence alignment warnings. - * We know it works because the structs have been instantiated as struct netifapi_msg */ - struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m; - - if (!netif_add( msg->netif, -#if LWIP_IPV4 - API_EXPR_REF(msg->msg.add.ipaddr), - API_EXPR_REF(msg->msg.add.netmask), - API_EXPR_REF(msg->msg.add.gw), -#endif /* LWIP_IPV4 */ - msg->msg.add.state, - msg->msg.add.init, - msg->msg.add.input)) { - return ERR_IF; - } else { - return ERR_OK; - } -} - -#if LWIP_IPV4 -/** - * Call netif_set_addr() inside the tcpip_thread context. - */ -static err_t -netifapi_do_netif_set_addr(struct tcpip_api_call_data *m) -{ - /* cast through void* to silence alignment warnings. - * We know it works because the structs have been instantiated as struct netifapi_msg */ - struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m; - - netif_set_addr( msg->netif, - API_EXPR_REF(msg->msg.add.ipaddr), - API_EXPR_REF(msg->msg.add.netmask), - API_EXPR_REF(msg->msg.add.gw)); - return ERR_OK; -} -#endif /* LWIP_IPV4 */ - -/** -* Call netif_name_to_index() inside the tcpip_thread context. -*/ -static err_t -netifapi_do_name_to_index(struct tcpip_api_call_data *m) -{ - /* cast through void* to silence alignment warnings. - * We know it works because the structs have been instantiated as struct netifapi_msg */ - struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m; - - msg->msg.ifs.index = netif_name_to_index(msg->msg.ifs.name); - return ERR_OK; -} - -/** -* Call netif_index_to_name() inside the tcpip_thread context. -*/ -static err_t -netifapi_do_index_to_name(struct tcpip_api_call_data *m) -{ - /* cast through void* to silence alignment warnings. - * We know it works because the structs have been instantiated as struct netifapi_msg */ - struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m; - - if (!netif_index_to_name(msg->msg.ifs.index, msg->msg.ifs.name)) { - /* return failure via empty name */ - msg->msg.ifs.name[0] = '\0'; - } - return ERR_OK; -} - -/** - * Call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) inside the - * tcpip_thread context. - */ -static err_t -netifapi_do_netif_common(struct tcpip_api_call_data *m) -{ - /* cast through void* to silence alignment warnings. - * We know it works because the structs have been instantiated as struct netifapi_msg */ - struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m; - - if (msg->msg.common.errtfunc != NULL) { - return msg->msg.common.errtfunc(msg->netif); - } else { - msg->msg.common.voidfunc(msg->netif); - return ERR_OK; - } -} - -#if LWIP_ARP && LWIP_IPV4 -/** - * @ingroup netifapi_arp - * Add or update an entry in the ARP cache. - * For an update, ipaddr is used to find the cache entry. - * - * @param ipaddr IPv4 address of cache entry - * @param ethaddr hardware address mapped to ipaddr - * @param type type of ARP cache entry - * @return ERR_OK: entry added/updated, else error from err_t - */ -err_t -netifapi_arp_add(const ip4_addr_t *ipaddr, struct eth_addr *ethaddr, enum netifapi_arp_entry type) -{ - err_t err; - - /* We only support permanent entries currently */ - LWIP_UNUSED_ARG(type); - -#if ETHARP_SUPPORT_STATIC_ENTRIES && LWIP_TCPIP_CORE_LOCKING - LOCK_TCPIP_CORE(); - err = etharp_add_static_entry(ipaddr, ethaddr); - UNLOCK_TCPIP_CORE(); -#else - /* @todo add new vars to struct netifapi_msg and create a 'do' func */ - LWIP_UNUSED_ARG(ipaddr); - LWIP_UNUSED_ARG(ethaddr); - err = ERR_VAL; -#endif /* ETHARP_SUPPORT_STATIC_ENTRIES && LWIP_TCPIP_CORE_LOCKING */ - - return err; -} - -/** - * @ingroup netifapi_arp - * Remove an entry in the ARP cache identified by ipaddr - * - * @param ipaddr IPv4 address of cache entry - * @param type type of ARP cache entry - * @return ERR_OK: entry removed, else error from err_t - */ -err_t -netifapi_arp_remove(const ip4_addr_t *ipaddr, enum netifapi_arp_entry type) -{ - err_t err; - - /* We only support permanent entries currently */ - LWIP_UNUSED_ARG(type); - -#if ETHARP_SUPPORT_STATIC_ENTRIES && LWIP_TCPIP_CORE_LOCKING - LOCK_TCPIP_CORE(); - err = etharp_remove_static_entry(ipaddr); - UNLOCK_TCPIP_CORE(); -#else - /* @todo add new vars to struct netifapi_msg and create a 'do' func */ - LWIP_UNUSED_ARG(ipaddr); - err = ERR_VAL; -#endif /* ETHARP_SUPPORT_STATIC_ENTRIES && LWIP_TCPIP_CORE_LOCKING */ - - return err; -} -#endif /* LWIP_ARP && LWIP_IPV4 */ - -/** - * @ingroup netifapi_netif - * Call netif_add() in a thread-safe way by running that function inside the - * tcpip_thread context. - * - * @note for params @see netif_add() - */ -err_t -netifapi_netif_add(struct netif *netif, -#if LWIP_IPV4 - const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw, -#endif /* LWIP_IPV4 */ - void *state, netif_init_fn init, netif_input_fn input) -{ - err_t err; - NETIFAPI_VAR_DECLARE(msg); - NETIFAPI_VAR_ALLOC(msg); - -#if LWIP_IPV4 - if (ipaddr == NULL) { - ipaddr = IP4_ADDR_ANY4; - } - if (netmask == NULL) { - netmask = IP4_ADDR_ANY4; - } - if (gw == NULL) { - gw = IP4_ADDR_ANY4; - } -#endif /* LWIP_IPV4 */ - - NETIFAPI_VAR_REF(msg).netif = netif; -#if LWIP_IPV4 - NETIFAPI_VAR_REF(msg).msg.add.ipaddr = NETIFAPI_VAR_REF(ipaddr); - NETIFAPI_VAR_REF(msg).msg.add.netmask = NETIFAPI_VAR_REF(netmask); - NETIFAPI_VAR_REF(msg).msg.add.gw = NETIFAPI_VAR_REF(gw); -#endif /* LWIP_IPV4 */ - NETIFAPI_VAR_REF(msg).msg.add.state = state; - NETIFAPI_VAR_REF(msg).msg.add.init = init; - NETIFAPI_VAR_REF(msg).msg.add.input = input; - err = tcpip_api_call(netifapi_do_netif_add, &API_VAR_REF(msg).call); - NETIFAPI_VAR_FREE(msg); - return err; -} - -#if LWIP_IPV4 -/** - * @ingroup netifapi_netif - * Call netif_set_addr() in a thread-safe way by running that function inside the - * tcpip_thread context. - * - * @note for params @see netif_set_addr() - */ -err_t -netifapi_netif_set_addr(struct netif *netif, - const ip4_addr_t *ipaddr, - const ip4_addr_t *netmask, - const ip4_addr_t *gw) -{ - err_t err; - NETIFAPI_VAR_DECLARE(msg); - NETIFAPI_VAR_ALLOC(msg); - - if (ipaddr == NULL) { - ipaddr = IP4_ADDR_ANY4; - } - if (netmask == NULL) { - netmask = IP4_ADDR_ANY4; - } - if (gw == NULL) { - gw = IP4_ADDR_ANY4; - } - - NETIFAPI_VAR_REF(msg).netif = netif; - NETIFAPI_VAR_REF(msg).msg.add.ipaddr = NETIFAPI_VAR_REF(ipaddr); - NETIFAPI_VAR_REF(msg).msg.add.netmask = NETIFAPI_VAR_REF(netmask); - NETIFAPI_VAR_REF(msg).msg.add.gw = NETIFAPI_VAR_REF(gw); - err = tcpip_api_call(netifapi_do_netif_set_addr, &API_VAR_REF(msg).call); - NETIFAPI_VAR_FREE(msg); - return err; -} -#endif /* LWIP_IPV4 */ - -/** - * call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) in a thread-safe - * way by running that function inside the tcpip_thread context. - * - * @note use only for functions where there is only "netif" parameter. - */ -err_t -netifapi_netif_common(struct netif *netif, netifapi_void_fn voidfunc, - netifapi_errt_fn errtfunc) -{ - err_t err; - NETIFAPI_VAR_DECLARE(msg); - NETIFAPI_VAR_ALLOC(msg); - - NETIFAPI_VAR_REF(msg).netif = netif; - NETIFAPI_VAR_REF(msg).msg.common.voidfunc = voidfunc; - NETIFAPI_VAR_REF(msg).msg.common.errtfunc = errtfunc; - err = tcpip_api_call(netifapi_do_netif_common, &API_VAR_REF(msg).call); - NETIFAPI_VAR_FREE(msg); - return err; -} - -/** -* @ingroup netifapi_netif -* Call netif_name_to_index() in a thread-safe way by running that function inside the -* tcpip_thread context. -* -* @param name the interface name of the netif -* @param idx output index of the found netif -*/ -err_t -netifapi_netif_name_to_index(const char *name, u8_t *idx) -{ - err_t err; - NETIFAPI_VAR_DECLARE(msg); - NETIFAPI_VAR_ALLOC(msg); - - *idx = 0; - -#if LWIP_MPU_COMPATIBLE - strncpy(NETIFAPI_VAR_REF(msg).msg.ifs.name, name, NETIF_NAMESIZE - 1); - NETIFAPI_VAR_REF(msg).msg.ifs.name[NETIF_NAMESIZE - 1] = '\0'; -#else - NETIFAPI_VAR_REF(msg).msg.ifs.name = LWIP_CONST_CAST(char *, name); -#endif /* LWIP_MPU_COMPATIBLE */ - err = tcpip_api_call(netifapi_do_name_to_index, &API_VAR_REF(msg).call); - if (!err) { - *idx = NETIFAPI_VAR_REF(msg).msg.ifs.index; - } - NETIFAPI_VAR_FREE(msg); - return err; -} - -/** -* @ingroup netifapi_netif -* Call netif_index_to_name() in a thread-safe way by running that function inside the -* tcpip_thread context. -* -* @param idx the interface index of the netif -* @param name output name of the found netif, empty '\0' string if netif not found. -* name should be of at least NETIF_NAMESIZE bytes -*/ -err_t -netifapi_netif_index_to_name(u8_t idx, char *name) -{ - err_t err; - NETIFAPI_VAR_DECLARE(msg); - NETIFAPI_VAR_ALLOC(msg); - - NETIFAPI_VAR_REF(msg).msg.ifs.index = idx; -#if !LWIP_MPU_COMPATIBLE - NETIFAPI_VAR_REF(msg).msg.ifs.name = name; -#endif /* LWIP_MPU_COMPATIBLE */ - err = tcpip_api_call(netifapi_do_index_to_name, &API_VAR_REF(msg).call); -#if LWIP_MPU_COMPATIBLE - if (!err) { - strncpy(name, NETIFAPI_VAR_REF(msg).msg.ifs.name, NETIF_NAMESIZE - 1); - name[NETIF_NAMESIZE - 1] = '\0'; - } -#endif /* LWIP_MPU_COMPATIBLE */ - NETIFAPI_VAR_FREE(msg); - return err; -} - -#endif /* LWIP_NETIF_API */ diff --git a/third-party/lwip-2.1.2/api/sockets.c b/third-party/lwip-2.1.2/api/sockets.c deleted file mode 100644 index cb7df914..00000000 --- a/third-party/lwip-2.1.2/api/sockets.c +++ /dev/null @@ -1,4160 +0,0 @@ -/** - * @file - * Sockets BSD-Like API module - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - * Improved by Marc Boucher and David Haas - * - */ - -#include "lwip/opt.h" - -#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/sockets.h" -#include "lwip/priv/sockets_priv.h" -#include "lwip/api.h" -#include "lwip/igmp.h" -#include "lwip/inet.h" -#include "lwip/tcp.h" -#include "lwip/raw.h" -#include "lwip/udp.h" -#include "lwip/memp.h" -#include "lwip/pbuf.h" -#include "lwip/netif.h" -#include "lwip/priv/tcpip_priv.h" -#include "lwip/mld6.h" -#if LWIP_CHECKSUM_ON_COPY -#include "lwip/inet_chksum.h" -#endif - -#if LWIP_COMPAT_SOCKETS == 2 && LWIP_POSIX_SOCKETS_IO_NAMES -#include -#endif - -#include - -#ifdef LWIP_HOOK_FILENAME -#include LWIP_HOOK_FILENAME -#endif - -/* If the netconn API is not required publicly, then we include the necessary - files here to get the implementation */ -#if !LWIP_NETCONN -#undef LWIP_NETCONN -#define LWIP_NETCONN 1 -#include "api_msg.c" -#include "api_lib.c" -#include "netbuf.c" -#undef LWIP_NETCONN -#define LWIP_NETCONN 0 -#endif - -#define API_SELECT_CB_VAR_REF(name) API_VAR_REF(name) -#define API_SELECT_CB_VAR_DECLARE(name) API_VAR_DECLARE(struct lwip_select_cb, name) -#define API_SELECT_CB_VAR_ALLOC(name, retblock) API_VAR_ALLOC_EXT(struct lwip_select_cb, MEMP_SELECT_CB, name, retblock) -#define API_SELECT_CB_VAR_FREE(name) API_VAR_FREE(MEMP_SELECT_CB, name) - -#if LWIP_IPV4 -#define IP4ADDR_PORT_TO_SOCKADDR(sin, ipaddr, port) do { \ - (sin)->sin_len = sizeof(struct sockaddr_in); \ - (sin)->sin_family = AF_INET; \ - (sin)->sin_port = lwip_htons((port)); \ - inet_addr_from_ip4addr(&(sin)->sin_addr, ipaddr); \ - memset((sin)->sin_zero, 0, SIN_ZERO_LEN); }while(0) -#define SOCKADDR4_TO_IP4ADDR_PORT(sin, ipaddr, port) do { \ - inet_addr_to_ip4addr(ip_2_ip4(ipaddr), &((sin)->sin_addr)); \ - (port) = lwip_ntohs((sin)->sin_port); }while(0) -#endif /* LWIP_IPV4 */ - -#if LWIP_IPV6 -#define IP6ADDR_PORT_TO_SOCKADDR(sin6, ipaddr, port) do { \ - (sin6)->sin6_len = sizeof(struct sockaddr_in6); \ - (sin6)->sin6_family = AF_INET6; \ - (sin6)->sin6_port = lwip_htons((port)); \ - (sin6)->sin6_flowinfo = 0; \ - inet6_addr_from_ip6addr(&(sin6)->sin6_addr, ipaddr); \ - (sin6)->sin6_scope_id = ip6_addr_zone(ipaddr); }while(0) -#define SOCKADDR6_TO_IP6ADDR_PORT(sin6, ipaddr, port) do { \ - inet6_addr_to_ip6addr(ip_2_ip6(ipaddr), &((sin6)->sin6_addr)); \ - if (ip6_addr_has_scope(ip_2_ip6(ipaddr), IP6_UNKNOWN)) { \ - ip6_addr_set_zone(ip_2_ip6(ipaddr), (u8_t)((sin6)->sin6_scope_id)); \ - } \ - (port) = lwip_ntohs((sin6)->sin6_port); }while(0) -#endif /* LWIP_IPV6 */ - -#if LWIP_IPV4 && LWIP_IPV6 -static void sockaddr_to_ipaddr_port(const struct sockaddr *sockaddr, ip_addr_t *ipaddr, u16_t *port); - -#define IS_SOCK_ADDR_LEN_VALID(namelen) (((namelen) == sizeof(struct sockaddr_in)) || \ - ((namelen) == sizeof(struct sockaddr_in6))) -#define IS_SOCK_ADDR_TYPE_VALID(name) (((name)->sa_family == AF_INET) || \ - ((name)->sa_family == AF_INET6)) -#define SOCK_ADDR_TYPE_MATCH(name, sock) \ - ((((name)->sa_family == AF_INET) && !(NETCONNTYPE_ISIPV6((sock)->conn->type))) || \ - (((name)->sa_family == AF_INET6) && (NETCONNTYPE_ISIPV6((sock)->conn->type)))) -#define IPADDR_PORT_TO_SOCKADDR(sockaddr, ipaddr, port) do { \ - if (IP_IS_ANY_TYPE_VAL(*ipaddr) || IP_IS_V6_VAL(*ipaddr)) { \ - IP6ADDR_PORT_TO_SOCKADDR((struct sockaddr_in6*)(void*)(sockaddr), ip_2_ip6(ipaddr), port); \ - } else { \ - IP4ADDR_PORT_TO_SOCKADDR((struct sockaddr_in*)(void*)(sockaddr), ip_2_ip4(ipaddr), port); \ - } } while(0) -#define SOCKADDR_TO_IPADDR_PORT(sockaddr, ipaddr, port) sockaddr_to_ipaddr_port(sockaddr, ipaddr, &(port)) -#define DOMAIN_TO_NETCONN_TYPE(domain, type) (((domain) == AF_INET) ? \ - (type) : (enum netconn_type)((type) | NETCONN_TYPE_IPV6)) -#elif LWIP_IPV6 /* LWIP_IPV4 && LWIP_IPV6 */ -#define IS_SOCK_ADDR_LEN_VALID(namelen) ((namelen) == sizeof(struct sockaddr_in6)) -#define IS_SOCK_ADDR_TYPE_VALID(name) ((name)->sa_family == AF_INET6) -#define SOCK_ADDR_TYPE_MATCH(name, sock) 1 -#define IPADDR_PORT_TO_SOCKADDR(sockaddr, ipaddr, port) \ - IP6ADDR_PORT_TO_SOCKADDR((struct sockaddr_in6*)(void*)(sockaddr), ip_2_ip6(ipaddr), port) -#define SOCKADDR_TO_IPADDR_PORT(sockaddr, ipaddr, port) \ - SOCKADDR6_TO_IP6ADDR_PORT((const struct sockaddr_in6*)(const void*)(sockaddr), ipaddr, port) -#define DOMAIN_TO_NETCONN_TYPE(domain, netconn_type) (netconn_type) -#else /*-> LWIP_IPV4: LWIP_IPV4 && LWIP_IPV6 */ -#define IS_SOCK_ADDR_LEN_VALID(namelen) ((namelen) == sizeof(struct sockaddr_in)) -#define IS_SOCK_ADDR_TYPE_VALID(name) ((name)->sa_family == AF_INET) -#define SOCK_ADDR_TYPE_MATCH(name, sock) 1 -#define IPADDR_PORT_TO_SOCKADDR(sockaddr, ipaddr, port) \ - IP4ADDR_PORT_TO_SOCKADDR((struct sockaddr_in*)(void*)(sockaddr), ip_2_ip4(ipaddr), port) -#define SOCKADDR_TO_IPADDR_PORT(sockaddr, ipaddr, port) \ - SOCKADDR4_TO_IP4ADDR_PORT((const struct sockaddr_in*)(const void*)(sockaddr), ipaddr, port) -#define DOMAIN_TO_NETCONN_TYPE(domain, netconn_type) (netconn_type) -#endif /* LWIP_IPV6 */ - -#define IS_SOCK_ADDR_TYPE_VALID_OR_UNSPEC(name) (((name)->sa_family == AF_UNSPEC) || \ - IS_SOCK_ADDR_TYPE_VALID(name)) -#define SOCK_ADDR_TYPE_MATCH_OR_UNSPEC(name, sock) (((name)->sa_family == AF_UNSPEC) || \ - SOCK_ADDR_TYPE_MATCH(name, sock)) -#define IS_SOCK_ADDR_ALIGNED(name) ((((mem_ptr_t)(name)) % 4) == 0) - - -#define LWIP_SOCKOPT_CHECK_OPTLEN(sock, optlen, opttype) do { if ((optlen) < sizeof(opttype)) { done_socket(sock); return EINVAL; }}while(0) -#define LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, opttype) do { \ - LWIP_SOCKOPT_CHECK_OPTLEN(sock, optlen, opttype); \ - if ((sock)->conn == NULL) { done_socket(sock); return EINVAL; } }while(0) -#define LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, opttype) do { \ - LWIP_SOCKOPT_CHECK_OPTLEN(sock, optlen, opttype); \ - if (((sock)->conn == NULL) || ((sock)->conn->pcb.tcp == NULL)) { done_socket(sock); return EINVAL; } }while(0) -#define LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, opttype, netconntype) do { \ - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, opttype); \ - if (NETCONNTYPE_GROUP(netconn_type((sock)->conn)) != netconntype) { done_socket(sock); return ENOPROTOOPT; } }while(0) - - -#define LWIP_SETGETSOCKOPT_DATA_VAR_REF(name) API_VAR_REF(name) -#define LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(name) API_VAR_DECLARE(struct lwip_setgetsockopt_data, name) -#define LWIP_SETGETSOCKOPT_DATA_VAR_FREE(name) API_VAR_FREE(MEMP_SOCKET_SETGETSOCKOPT_DATA, name) -#if LWIP_MPU_COMPATIBLE -#define LWIP_SETGETSOCKOPT_DATA_VAR_ALLOC(name, sock) do { \ - name = (struct lwip_setgetsockopt_data *)memp_malloc(MEMP_SOCKET_SETGETSOCKOPT_DATA); \ - if (name == NULL) { \ - sock_set_errno(sock, ENOMEM); \ - done_socket(sock); \ - return -1; \ - } }while(0) -#else /* LWIP_MPU_COMPATIBLE */ -#define LWIP_SETGETSOCKOPT_DATA_VAR_ALLOC(name, sock) -#endif /* LWIP_MPU_COMPATIBLE */ - -#if LWIP_SO_SNDRCVTIMEO_NONSTANDARD -#define LWIP_SO_SNDRCVTIMEO_OPTTYPE int -#define LWIP_SO_SNDRCVTIMEO_SET(optval, val) (*(int *)(optval) = (val)) -#define LWIP_SO_SNDRCVTIMEO_GET_MS(optval) ((long)*(const int*)(optval)) -#else -#define LWIP_SO_SNDRCVTIMEO_OPTTYPE struct timeval -#define LWIP_SO_SNDRCVTIMEO_SET(optval, val) do { \ - u32_t loc = (val); \ - ((struct timeval *)(optval))->tv_sec = (long)((loc) / 1000U); \ - ((struct timeval *)(optval))->tv_usec = (long)(((loc) % 1000U) * 1000U); }while(0) -#define LWIP_SO_SNDRCVTIMEO_GET_MS(optval) ((((const struct timeval *)(optval))->tv_sec * 1000) + (((const struct timeval *)(optval))->tv_usec / 1000)) -#endif - - -/** A struct sockaddr replacement that has the same alignment as sockaddr_in/ - * sockaddr_in6 if instantiated. - */ -union sockaddr_aligned { - struct sockaddr sa; -#if LWIP_IPV6 - struct sockaddr_in6 sin6; -#endif /* LWIP_IPV6 */ -#if LWIP_IPV4 - struct sockaddr_in sin; -#endif /* LWIP_IPV4 */ -}; - -/* Define the number of IPv4 multicast memberships, default is one per socket */ -#ifndef LWIP_SOCKET_MAX_MEMBERSHIPS -#define LWIP_SOCKET_MAX_MEMBERSHIPS NUM_SOCKETS -#endif - -#if LWIP_IGMP -/* This is to keep track of IP_ADD_MEMBERSHIP calls to drop the membership when - a socket is closed */ -struct lwip_socket_multicast_pair { - /** the socket */ - struct lwip_sock *sock; - /** the interface address */ - ip4_addr_t if_addr; - /** the group address */ - ip4_addr_t multi_addr; -}; - -static struct lwip_socket_multicast_pair socket_ipv4_multicast_memberships[LWIP_SOCKET_MAX_MEMBERSHIPS]; - -static int lwip_socket_register_membership(int s, const ip4_addr_t *if_addr, const ip4_addr_t *multi_addr); -static void lwip_socket_unregister_membership(int s, const ip4_addr_t *if_addr, const ip4_addr_t *multi_addr); -static void lwip_socket_drop_registered_memberships(int s); -#endif /* LWIP_IGMP */ - -#if LWIP_IPV6_MLD -/* This is to keep track of IP_JOIN_GROUP calls to drop the membership when - a socket is closed */ -struct lwip_socket_multicast_mld6_pair { - /** the socket */ - struct lwip_sock *sock; - /** the interface index */ - u8_t if_idx; - /** the group address */ - ip6_addr_t multi_addr; -}; - -static struct lwip_socket_multicast_mld6_pair socket_ipv6_multicast_memberships[LWIP_SOCKET_MAX_MEMBERSHIPS]; - -static int lwip_socket_register_mld6_membership(int s, unsigned int if_idx, const ip6_addr_t *multi_addr); -static void lwip_socket_unregister_mld6_membership(int s, unsigned int if_idx, const ip6_addr_t *multi_addr); -static void lwip_socket_drop_registered_mld6_memberships(int s); -#endif /* LWIP_IPV6_MLD */ - -/** The global array of available sockets */ -static struct lwip_sock sockets[NUM_SOCKETS]; - -#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL -#if LWIP_TCPIP_CORE_LOCKING -/* protect the select_cb_list using core lock */ -#define LWIP_SOCKET_SELECT_DECL_PROTECT(lev) -#define LWIP_SOCKET_SELECT_PROTECT(lev) LOCK_TCPIP_CORE() -#define LWIP_SOCKET_SELECT_UNPROTECT(lev) UNLOCK_TCPIP_CORE() -#else /* LWIP_TCPIP_CORE_LOCKING */ -/* protect the select_cb_list using SYS_LIGHTWEIGHT_PROT */ -#define LWIP_SOCKET_SELECT_DECL_PROTECT(lev) SYS_ARCH_DECL_PROTECT(lev) -#define LWIP_SOCKET_SELECT_PROTECT(lev) SYS_ARCH_PROTECT(lev) -#define LWIP_SOCKET_SELECT_UNPROTECT(lev) SYS_ARCH_UNPROTECT(lev) -/** This counter is increased from lwip_select when the list is changed - and checked in select_check_waiters to see if it has changed. */ -static volatile int select_cb_ctr; -#endif /* LWIP_TCPIP_CORE_LOCKING */ -/** The global list of tasks waiting for select */ -static struct lwip_select_cb *select_cb_list; -#endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */ - -#define sock_set_errno(sk, e) do { \ - const int sockerr = (e); \ - set_errno(sockerr); \ -} while (0) - -/* Forward declaration of some functions */ -#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL -static void event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len); -#define DEFAULT_SOCKET_EVENTCB event_callback -static void select_check_waiters(int s, int has_recvevent, int has_sendevent, int has_errevent); -#else -#define DEFAULT_SOCKET_EVENTCB NULL -#endif -#if !LWIP_TCPIP_CORE_LOCKING -static void lwip_getsockopt_callback(void *arg); -static void lwip_setsockopt_callback(void *arg); -#endif -static int lwip_getsockopt_impl(int s, int level, int optname, void *optval, socklen_t *optlen); -static int lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_t optlen); -static int free_socket_locked(struct lwip_sock *sock, int is_tcp, struct netconn **conn, - union lwip_sock_lastdata *lastdata); -static void free_socket_free_elements(int is_tcp, struct netconn *conn, union lwip_sock_lastdata *lastdata); - -#if LWIP_IPV4 && LWIP_IPV6 -static void -sockaddr_to_ipaddr_port(const struct sockaddr *sockaddr, ip_addr_t *ipaddr, u16_t *port) -{ - if ((sockaddr->sa_family) == AF_INET6) { - SOCKADDR6_TO_IP6ADDR_PORT((const struct sockaddr_in6 *)(const void *)(sockaddr), ipaddr, *port); - ipaddr->type = IPADDR_TYPE_V6; - } else { - SOCKADDR4_TO_IP4ADDR_PORT((const struct sockaddr_in *)(const void *)(sockaddr), ipaddr, *port); - ipaddr->type = IPADDR_TYPE_V4; - } -} -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - -/** LWIP_NETCONN_SEM_PER_THREAD==1: initialize thread-local semaphore */ -void -lwip_socket_thread_init(void) -{ - netconn_thread_init(); -} - -/** LWIP_NETCONN_SEM_PER_THREAD==1: destroy thread-local semaphore */ -void -lwip_socket_thread_cleanup(void) -{ - netconn_thread_cleanup(); -} - -#if LWIP_NETCONN_FULLDUPLEX -/* Thread-safe increment of sock->fd_used, with overflow check */ -static int -sock_inc_used(struct lwip_sock *sock) -{ - int ret; - SYS_ARCH_DECL_PROTECT(lev); - - LWIP_ASSERT("sock != NULL", sock != NULL); - - SYS_ARCH_PROTECT(lev); - if (sock->fd_free_pending) { - /* prevent new usage of this socket if free is pending */ - ret = 0; - } else { - ++sock->fd_used; - ret = 1; - LWIP_ASSERT("sock->fd_used != 0", sock->fd_used != 0); - } - SYS_ARCH_UNPROTECT(lev); - return ret; -} - -/* Like sock_inc_used(), but called under SYS_ARCH_PROTECT lock. */ -static int -sock_inc_used_locked(struct lwip_sock *sock) -{ - LWIP_ASSERT("sock != NULL", sock != NULL); - - if (sock->fd_free_pending) { - LWIP_ASSERT("sock->fd_used != 0", sock->fd_used != 0); - return 0; - } - - ++sock->fd_used; - LWIP_ASSERT("sock->fd_used != 0", sock->fd_used != 0); - return 1; -} - -/* In full-duplex mode,sock->fd_used != 0 prevents a socket descriptor from being - * released (and possibly reused) when used from more than one thread - * (e.g. read-while-write or close-while-write, etc) - * This function is called at the end of functions using (try)get_socket*(). - */ -static void -done_socket(struct lwip_sock *sock) -{ - int freed = 0; - int is_tcp = 0; - struct netconn *conn = NULL; - union lwip_sock_lastdata lastdata; - SYS_ARCH_DECL_PROTECT(lev); - LWIP_ASSERT("sock != NULL", sock != NULL); - - SYS_ARCH_PROTECT(lev); - LWIP_ASSERT("sock->fd_used > 0", sock->fd_used > 0); - if (--sock->fd_used == 0) { - if (sock->fd_free_pending) { - /* free the socket */ - sock->fd_used = 1; - is_tcp = sock->fd_free_pending & LWIP_SOCK_FD_FREE_TCP; - freed = free_socket_locked(sock, is_tcp, &conn, &lastdata); - } - } - SYS_ARCH_UNPROTECT(lev); - - if (freed) { - free_socket_free_elements(is_tcp, conn, &lastdata); - } -} - -#else /* LWIP_NETCONN_FULLDUPLEX */ -#define sock_inc_used(sock) 1 -#define sock_inc_used_locked(sock) 1 -#define done_socket(sock) -#endif /* LWIP_NETCONN_FULLDUPLEX */ - -/* Translate a socket 'int' into a pointer (only fails if the index is invalid) */ -static struct lwip_sock * -tryget_socket_unconn_nouse(int fd) -{ - int s = fd - LWIP_SOCKET_OFFSET; - if ((s < 0) || (s >= NUM_SOCKETS)) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("tryget_socket_unconn(%d): invalid\n", fd)); - return NULL; - } - return &sockets[s]; -} - -struct lwip_sock * -lwip_socket_dbg_get_socket(int fd) -{ - return tryget_socket_unconn_nouse(fd); -} - -/* Translate a socket 'int' into a pointer (only fails if the index is invalid) */ -static struct lwip_sock * -tryget_socket_unconn(int fd) -{ - struct lwip_sock *ret = tryget_socket_unconn_nouse(fd); - if (ret != NULL) { - if (!sock_inc_used(ret)) { - return NULL; - } - } - return ret; -} - -/* Like tryget_socket_unconn(), but called under SYS_ARCH_PROTECT lock. */ -static struct lwip_sock * -tryget_socket_unconn_locked(int fd) -{ - struct lwip_sock *ret = tryget_socket_unconn_nouse(fd); - if (ret != NULL) { - if (!sock_inc_used_locked(ret)) { - return NULL; - } - } - return ret; -} - -/** - * Same as get_socket but doesn't set errno - * - * @param fd externally used socket index - * @return struct lwip_sock for the socket or NULL if not found - */ -static struct lwip_sock * -tryget_socket(int fd) -{ - struct lwip_sock *sock = tryget_socket_unconn(fd); - if (sock != NULL) { - if (sock->conn) { - return sock; - } - done_socket(sock); - } - return NULL; -} - -/** - * Map a externally used socket index to the internal socket representation. - * - * @param fd externally used socket index - * @return struct lwip_sock for the socket or NULL if not found - */ -static struct lwip_sock * -get_socket(int fd) -{ - struct lwip_sock *sock = tryget_socket(fd); - if (!sock) { - if ((fd < LWIP_SOCKET_OFFSET) || (fd >= (LWIP_SOCKET_OFFSET + NUM_SOCKETS))) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): invalid\n", fd)); - } - set_errno(EBADF); - return NULL; - } - return sock; -} - -/** - * Allocate a new socket for a given netconn. - * - * @param newconn the netconn for which to allocate a socket - * @param accepted 1 if socket has been created by accept(), - * 0 if socket has been created by socket() - * @return the index of the new socket; -1 on error - */ -static int -alloc_socket(struct netconn *newconn, int accepted) -{ - int i; - SYS_ARCH_DECL_PROTECT(lev); - LWIP_UNUSED_ARG(accepted); - - /* allocate a new socket identifier */ - for (i = 0; i < NUM_SOCKETS; ++i) { - /* Protect socket array */ - SYS_ARCH_PROTECT(lev); - if (!sockets[i].conn) { -#if LWIP_NETCONN_FULLDUPLEX - if (sockets[i].fd_used) { - SYS_ARCH_UNPROTECT(lev); - continue; - } - sockets[i].fd_used = 1; - sockets[i].fd_free_pending = 0; -#endif - sockets[i].conn = newconn; - /* The socket is not yet known to anyone, so no need to protect - after having marked it as used. */ - SYS_ARCH_UNPROTECT(lev); - sockets[i].lastdata.pbuf = NULL; -#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL - LWIP_ASSERT("sockets[i].select_waiting == 0", sockets[i].select_waiting == 0); - sockets[i].rcvevent = 0; - /* TCP sendbuf is empty, but the socket is not yet writable until connected - * (unless it has been created by accept()). */ - sockets[i].sendevent = (NETCONNTYPE_GROUP(newconn->type) == NETCONN_TCP ? (accepted != 0) : 1); - sockets[i].errevent = 0; -#endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */ - return i + LWIP_SOCKET_OFFSET; - } - SYS_ARCH_UNPROTECT(lev); - } - return -1; -} - -/** Free a socket (under lock) - * - * @param sock the socket to free - * @param is_tcp != 0 for TCP sockets, used to free lastdata - * @param conn the socekt's netconn is stored here, must be freed externally - * @param lastdata lastdata is stored here, must be freed externally - */ -static int -free_socket_locked(struct lwip_sock *sock, int is_tcp, struct netconn **conn, - union lwip_sock_lastdata *lastdata) -{ -#if LWIP_NETCONN_FULLDUPLEX - LWIP_ASSERT("sock->fd_used > 0", sock->fd_used > 0); - sock->fd_used--; - if (sock->fd_used > 0) { - sock->fd_free_pending = LWIP_SOCK_FD_FREE_FREE | (is_tcp ? LWIP_SOCK_FD_FREE_TCP : 0); - return 0; - } -#else /* LWIP_NETCONN_FULLDUPLEX */ - LWIP_UNUSED_ARG(is_tcp); -#endif /* LWIP_NETCONN_FULLDUPLEX */ - - *lastdata = sock->lastdata; - sock->lastdata.pbuf = NULL; - *conn = sock->conn; - sock->conn = NULL; - return 1; -} - -/** Free a socket's leftover members. - */ -static void -free_socket_free_elements(int is_tcp, struct netconn *conn, union lwip_sock_lastdata *lastdata) -{ - if (lastdata->pbuf != NULL) { - if (is_tcp) { - pbuf_free(lastdata->pbuf); - } else { - netbuf_delete(lastdata->netbuf); - } - } - if (conn != NULL) { - /* netconn_prepare_delete() has already been called, here we only free the conn */ - netconn_delete(conn); - } -} - -/** Free a socket. The socket's netconn must have been - * delete before! - * - * @param sock the socket to free - * @param is_tcp != 0 for TCP sockets, used to free lastdata - */ -static void -free_socket(struct lwip_sock *sock, int is_tcp) -{ - int freed; - struct netconn *conn; - union lwip_sock_lastdata lastdata; - SYS_ARCH_DECL_PROTECT(lev); - - /* Protect socket array */ - SYS_ARCH_PROTECT(lev); - - freed = free_socket_locked(sock, is_tcp, &conn, &lastdata); - SYS_ARCH_UNPROTECT(lev); - /* don't use 'sock' after this line, as another task might have allocated it */ - - if (freed) { - free_socket_free_elements(is_tcp, conn, &lastdata); - } -} - -/* Below this, the well-known socket functions are implemented. - * Use google.com or opengroup.org to get a good description :-) - * - * Exceptions are documented! - */ - -int -lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) -{ - struct lwip_sock *sock, *nsock; - struct netconn *newconn; - ip_addr_t naddr; - u16_t port = 0; - int newsock; - err_t err; - int recvevent; - SYS_ARCH_DECL_PROTECT(lev); - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d)...\n", s)); - sock = get_socket(s); - if (!sock) { - return -1; - } - - /* wait for a new connection */ - err = netconn_accept(sock->conn, &newconn); - if (err != ERR_OK) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_acept failed, err=%d\n", s, err)); - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { - sock_set_errno(sock, EOPNOTSUPP); - } else if (err == ERR_CLSD) { - sock_set_errno(sock, EINVAL); - } else { - sock_set_errno(sock, err_to_errno(err)); - } - done_socket(sock); - return -1; - } - LWIP_ASSERT("newconn != NULL", newconn != NULL); - - newsock = alloc_socket(newconn, 1); - if (newsock == -1) { - netconn_delete(newconn); - sock_set_errno(sock, ENFILE); - done_socket(sock); - return -1; - } - LWIP_ASSERT("invalid socket index", (newsock >= LWIP_SOCKET_OFFSET) && (newsock < NUM_SOCKETS + LWIP_SOCKET_OFFSET)); - nsock = &sockets[newsock - LWIP_SOCKET_OFFSET]; - - /* See event_callback: If data comes in right away after an accept, even - * though the server task might not have created a new socket yet. - * In that case, newconn->socket is counted down (newconn->socket--), - * so nsock->rcvevent is >= 1 here! - */ - SYS_ARCH_PROTECT(lev); - recvevent = (s16_t)(-1 - newconn->socket); - newconn->socket = newsock; - SYS_ARCH_UNPROTECT(lev); - - if (newconn->callback) { - LOCK_TCPIP_CORE(); - while (recvevent > 0) { - recvevent--; - newconn->callback(newconn, NETCONN_EVT_RCVPLUS, 0); - } - UNLOCK_TCPIP_CORE(); - } - - /* Note that POSIX only requires us to check addr is non-NULL. addrlen must - * not be NULL if addr is valid. - */ - if ((addr != NULL) && (addrlen != NULL)) { - union sockaddr_aligned tempaddr; - /* get the IP address and port of the remote host */ - err = netconn_peer(newconn, &naddr, &port); - if (err != ERR_OK) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_peer failed, err=%d\n", s, err)); - netconn_delete(newconn); - free_socket(nsock, 1); - sock_set_errno(sock, err_to_errno(err)); - done_socket(sock); - return -1; - } - - IPADDR_PORT_TO_SOCKADDR(&tempaddr, &naddr, port); - if (*addrlen > tempaddr.sa.sa_len) { - *addrlen = tempaddr.sa.sa_len; - } - MEMCPY(addr, &tempaddr, *addrlen); - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d addr=", s, newsock)); - ip_addr_debug_print_val(SOCKETS_DEBUG, naddr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", port)); - } else { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d", s, newsock)); - } - - sock_set_errno(sock, 0); - done_socket(sock); - done_socket(nsock); - return newsock; -} - -int -lwip_bind(int s, const struct sockaddr *name, socklen_t namelen) -{ - struct lwip_sock *sock; - ip_addr_t local_addr; - u16_t local_port; - err_t err; - - sock = get_socket(s); - if (!sock) { - return -1; - } - - if (!SOCK_ADDR_TYPE_MATCH(name, sock)) { - /* sockaddr does not match socket type (IPv4/IPv6) */ - sock_set_errno(sock, err_to_errno(ERR_VAL)); - done_socket(sock); - return -1; - } - - /* check size, family and alignment of 'name' */ - LWIP_ERROR("lwip_bind: invalid address", (IS_SOCK_ADDR_LEN_VALID(namelen) && - IS_SOCK_ADDR_TYPE_VALID(name) && IS_SOCK_ADDR_ALIGNED(name)), - sock_set_errno(sock, err_to_errno(ERR_ARG)); done_socket(sock); return -1;); - LWIP_UNUSED_ARG(namelen); - - SOCKADDR_TO_IPADDR_PORT(name, &local_addr, local_port); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d, addr=", s)); - ip_addr_debug_print_val(SOCKETS_DEBUG, local_addr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", local_port)); - -#if LWIP_IPV4 && LWIP_IPV6 - /* Dual-stack: Unmap IPv4 mapped IPv6 addresses */ - if (IP_IS_V6_VAL(local_addr) && ip6_addr_isipv4mappedipv6(ip_2_ip6(&local_addr))) { - unmap_ipv4_mapped_ipv6(ip_2_ip4(&local_addr), ip_2_ip6(&local_addr)); - IP_SET_TYPE_VAL(local_addr, IPADDR_TYPE_V4); - } -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - - err = netconn_bind(sock->conn, &local_addr, local_port); - - if (err != ERR_OK) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) failed, err=%d\n", s, err)); - sock_set_errno(sock, err_to_errno(err)); - done_socket(sock); - return -1; - } - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) succeeded\n", s)); - sock_set_errno(sock, 0); - done_socket(sock); - return 0; -} - -int -lwip_close(int s) -{ - struct lwip_sock *sock; - int is_tcp = 0; - err_t err; - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_close(%d)\n", s)); - - sock = get_socket(s); - if (!sock) { - return -1; - } - - if (sock->conn != NULL) { - is_tcp = NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP; - } else { - LWIP_ASSERT("sock->lastdata == NULL", sock->lastdata.pbuf == NULL); - } - -#if LWIP_IGMP - /* drop all possibly joined IGMP memberships */ - lwip_socket_drop_registered_memberships(s); -#endif /* LWIP_IGMP */ -#if LWIP_IPV6_MLD - /* drop all possibly joined MLD6 memberships */ - lwip_socket_drop_registered_mld6_memberships(s); -#endif /* LWIP_IPV6_MLD */ - - err = netconn_prepare_delete(sock->conn); - if (err != ERR_OK) { - sock_set_errno(sock, err_to_errno(err)); - done_socket(sock); - return -1; - } - - free_socket(sock, is_tcp); - set_errno(0); - return 0; -} - -int -lwip_connect(int s, const struct sockaddr *name, socklen_t namelen) -{ - struct lwip_sock *sock; - err_t err; - - sock = get_socket(s); - if (!sock) { - return -1; - } - - if (!SOCK_ADDR_TYPE_MATCH_OR_UNSPEC(name, sock)) { - /* sockaddr does not match socket type (IPv4/IPv6) */ - sock_set_errno(sock, err_to_errno(ERR_VAL)); - done_socket(sock); - return -1; - } - - LWIP_UNUSED_ARG(namelen); - if (name->sa_family == AF_UNSPEC) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, AF_UNSPEC)\n", s)); - err = netconn_disconnect(sock->conn); - } else { - ip_addr_t remote_addr; - u16_t remote_port; - - /* check size, family and alignment of 'name' */ - LWIP_ERROR("lwip_connect: invalid address", IS_SOCK_ADDR_LEN_VALID(namelen) && - IS_SOCK_ADDR_TYPE_VALID_OR_UNSPEC(name) && IS_SOCK_ADDR_ALIGNED(name), - sock_set_errno(sock, err_to_errno(ERR_ARG)); done_socket(sock); return -1;); - - SOCKADDR_TO_IPADDR_PORT(name, &remote_addr, remote_port); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, addr=", s)); - ip_addr_debug_print_val(SOCKETS_DEBUG, remote_addr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", remote_port)); - -#if LWIP_IPV4 && LWIP_IPV6 - /* Dual-stack: Unmap IPv4 mapped IPv6 addresses */ - if (IP_IS_V6_VAL(remote_addr) && ip6_addr_isipv4mappedipv6(ip_2_ip6(&remote_addr))) { - unmap_ipv4_mapped_ipv6(ip_2_ip4(&remote_addr), ip_2_ip6(&remote_addr)); - IP_SET_TYPE_VAL(remote_addr, IPADDR_TYPE_V4); - } -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - - err = netconn_connect(sock->conn, &remote_addr, remote_port); - } - - if (err != ERR_OK) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) failed, err=%d\n", s, err)); - sock_set_errno(sock, err_to_errno(err)); - done_socket(sock); - return -1; - } - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) succeeded\n", s)); - sock_set_errno(sock, 0); - done_socket(sock); - return 0; -} - -/** - * Set a socket into listen mode. - * The socket may not have been used for another connection previously. - * - * @param s the socket to set to listening mode - * @param backlog (ATTENTION: needs TCP_LISTEN_BACKLOG=1) - * @return 0 on success, non-zero on failure - */ -int -lwip_listen(int s, int backlog) -{ - struct lwip_sock *sock; - err_t err; - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d, backlog=%d)\n", s, backlog)); - - sock = get_socket(s); - if (!sock) { - return -1; - } - - /* limit the "backlog" parameter to fit in an u8_t */ - backlog = LWIP_MIN(LWIP_MAX(backlog, 0), 0xff); - - err = netconn_listen_with_backlog(sock->conn, (u8_t)backlog); - - if (err != ERR_OK) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d) failed, err=%d\n", s, err)); - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { - sock_set_errno(sock, EOPNOTSUPP); - } else { - sock_set_errno(sock, err_to_errno(err)); - } - done_socket(sock); - return -1; - } - - sock_set_errno(sock, 0); - done_socket(sock); - return 0; -} - -#if LWIP_TCP -/* Helper function to loop over receiving pbufs from netconn - * until "len" bytes are received or we're otherwise done. - * Keeps sock->lastdata for peeking or partly copying. - */ -static ssize_t -lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags) -{ - u8_t apiflags = NETCONN_NOAUTORCVD; - ssize_t recvd = 0; - ssize_t recv_left = (len <= SSIZE_MAX) ? (ssize_t)len : SSIZE_MAX; - - LWIP_ASSERT("no socket given", sock != NULL); - LWIP_ASSERT("this should be checked internally", NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP); - - if (flags & MSG_DONTWAIT) { - apiflags |= NETCONN_DONTBLOCK; - } - - do { - struct pbuf *p; - err_t err; - u16_t copylen; - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recv_tcp: top while sock->lastdata=%p\n", (void *)sock->lastdata.pbuf)); - /* Check if there is data left from the last recv operation. */ - if (sock->lastdata.pbuf) { - p = sock->lastdata.pbuf; - } else { - /* No data was left from the previous operation, so we try to get - some from the network. */ - err = netconn_recv_tcp_pbuf_flags(sock->conn, &p, apiflags); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recv_tcp: netconn_recv err=%d, pbuf=%p\n", - err, (void *)p)); - - if (err != ERR_OK) { - if (recvd > 0) { - /* already received data, return that (this trusts in getting the same error from - netconn layer again next time netconn_recv is called) */ - goto lwip_recv_tcp_done; - } - /* We should really do some error checking here. */ - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recv_tcp: p == NULL, error is \"%s\"!\n", - lwip_strerr(err))); - sock_set_errno(sock, err_to_errno(err)); - if (err == ERR_CLSD) { - return 0; - } else { - return -1; - } - } - LWIP_ASSERT("p != NULL", p != NULL); - sock->lastdata.pbuf = p; - } - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recv_tcp: buflen=%"U16_F" recv_left=%d off=%d\n", - p->tot_len, (int)recv_left, (int)recvd)); - - if (recv_left > p->tot_len) { - copylen = p->tot_len; - } else { - copylen = (u16_t)recv_left; - } - if (recvd + copylen < recvd) { - /* overflow */ - copylen = (u16_t)(SSIZE_MAX - recvd); - } - - /* copy the contents of the received buffer into - the supplied memory pointer mem */ - pbuf_copy_partial(p, (u8_t *)mem + recvd, copylen, 0); - - recvd += copylen; - - /* TCP combines multiple pbufs for one recv */ - LWIP_ASSERT("invalid copylen, len would underflow", recv_left >= copylen); - recv_left -= copylen; - - /* Unless we peek the incoming message... */ - if ((flags & MSG_PEEK) == 0) { - /* ... check if there is data left in the pbuf */ - LWIP_ASSERT("invalid copylen", p->tot_len >= copylen); - if (p->tot_len - copylen > 0) { - /* If so, it should be saved in the sock structure for the next recv call. - We store the pbuf but hide/free the consumed data: */ - sock->lastdata.pbuf = pbuf_free_header(p, copylen); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recv_tcp: lastdata now pbuf=%p\n", (void *)sock->lastdata.pbuf)); - } else { - sock->lastdata.pbuf = NULL; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recv_tcp: deleting pbuf=%p\n", (void *)p)); - pbuf_free(p); - } - } - /* once we have some data to return, only add more if we don't need to wait */ - apiflags |= NETCONN_DONTBLOCK | NETCONN_NOFIN; - /* @todo: do we need to support peeking more than one pbuf? */ - } while ((recv_left > 0) && !(flags & MSG_PEEK)); -lwip_recv_tcp_done: - if ((recvd > 0) && !(flags & MSG_PEEK)) { - /* ensure window update after copying all data */ - netconn_tcp_recvd(sock->conn, (size_t)recvd); - } - sock_set_errno(sock, 0); - return recvd; -} -#endif - -/* Convert a netbuf's address data to struct sockaddr */ -static int -lwip_sock_make_addr(struct netconn *conn, ip_addr_t *fromaddr, u16_t port, - struct sockaddr *from, socklen_t *fromlen) -{ - int truncated = 0; - union sockaddr_aligned saddr; - - LWIP_UNUSED_ARG(conn); - - LWIP_ASSERT("fromaddr != NULL", fromaddr != NULL); - LWIP_ASSERT("from != NULL", from != NULL); - LWIP_ASSERT("fromlen != NULL", fromlen != NULL); - -#if LWIP_IPV4 && LWIP_IPV6 - /* Dual-stack: Map IPv4 addresses to IPv4 mapped IPv6 */ - if (NETCONNTYPE_ISIPV6(netconn_type(conn)) && IP_IS_V4(fromaddr)) { - ip4_2_ipv4_mapped_ipv6(ip_2_ip6(fromaddr), ip_2_ip4(fromaddr)); - IP_SET_TYPE(fromaddr, IPADDR_TYPE_V6); - } -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - - IPADDR_PORT_TO_SOCKADDR(&saddr, fromaddr, port); - if (*fromlen < saddr.sa.sa_len) { - truncated = 1; - } else if (*fromlen > saddr.sa.sa_len) { - *fromlen = saddr.sa.sa_len; - } - MEMCPY(from, &saddr, *fromlen); - return truncated; -} - -#if LWIP_TCP -/* Helper function to get a tcp socket's remote address info */ -static int -lwip_recv_tcp_from(struct lwip_sock *sock, struct sockaddr *from, socklen_t *fromlen, const char *dbg_fn, int dbg_s, ssize_t dbg_ret) -{ - if (sock == NULL) { - return 0; - } - LWIP_UNUSED_ARG(dbg_fn); - LWIP_UNUSED_ARG(dbg_s); - LWIP_UNUSED_ARG(dbg_ret); - -#if !SOCKETS_DEBUG - if (from && fromlen) -#endif /* !SOCKETS_DEBUG */ - { - /* get remote addr/port from tcp_pcb */ - u16_t port; - ip_addr_t tmpaddr; - netconn_getaddr(sock->conn, &tmpaddr, &port, 0); - LWIP_DEBUGF(SOCKETS_DEBUG, ("%s(%d): addr=", dbg_fn, dbg_s)); - ip_addr_debug_print_val(SOCKETS_DEBUG, tmpaddr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F" len=%d\n", port, (int)dbg_ret)); - if (from && fromlen) { - return lwip_sock_make_addr(sock->conn, &tmpaddr, port, from, fromlen); - } - } - return 0; -} -#endif - -/* Helper function to receive a netbuf from a udp or raw netconn. - * Keeps sock->lastdata for peeking. - */ -static err_t -lwip_recvfrom_udp_raw(struct lwip_sock *sock, int flags, struct msghdr *msg, u16_t *datagram_len, int dbg_s) -{ - struct netbuf *buf; - u8_t apiflags; - err_t err; - u16_t buflen, copylen, copied; - int i; - - LWIP_UNUSED_ARG(dbg_s); - LWIP_ERROR("lwip_recvfrom_udp_raw: invalid arguments", (msg->msg_iov != NULL) || (msg->msg_iovlen <= 0), return ERR_ARG;); - - if (flags & MSG_DONTWAIT) { - apiflags = NETCONN_DONTBLOCK; - } else { - apiflags = 0; - } - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom_udp_raw[UDP/RAW]: top sock->lastdata=%p\n", (void *)sock->lastdata.netbuf)); - /* Check if there is data left from the last recv operation. */ - buf = sock->lastdata.netbuf; - if (buf == NULL) { - /* No data was left from the previous operation, so we try to get - some from the network. */ - err = netconn_recv_udp_raw_netbuf_flags(sock->conn, &buf, apiflags); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom_udp_raw[UDP/RAW]: netconn_recv err=%d, netbuf=%p\n", - err, (void *)buf)); - - if (err != ERR_OK) { - return err; - } - LWIP_ASSERT("buf != NULL", buf != NULL); - sock->lastdata.netbuf = buf; - } - buflen = buf->p->tot_len; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom_udp_raw: buflen=%"U16_F"\n", buflen)); - - copied = 0; - /* copy the pbuf payload into the iovs */ - for (i = 0; (i < msg->msg_iovlen) && (copied < buflen); i++) { - u16_t len_left = (u16_t)(buflen - copied); - if (msg->msg_iov[i].iov_len > len_left) { - copylen = len_left; - } else { - copylen = (u16_t)msg->msg_iov[i].iov_len; - } - - /* copy the contents of the received buffer into - the supplied memory buffer */ - pbuf_copy_partial(buf->p, (u8_t *)msg->msg_iov[i].iov_base, copylen, copied); - copied = (u16_t)(copied + copylen); - } - - /* Check to see from where the data was.*/ -#if !SOCKETS_DEBUG - if (msg->msg_name && msg->msg_namelen) -#endif /* !SOCKETS_DEBUG */ - { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom_udp_raw(%d): addr=", dbg_s)); - ip_addr_debug_print_val(SOCKETS_DEBUG, *netbuf_fromaddr(buf)); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F" len=%d\n", netbuf_fromport(buf), copied)); - if (msg->msg_name && msg->msg_namelen) { - lwip_sock_make_addr(sock->conn, netbuf_fromaddr(buf), netbuf_fromport(buf), - (struct sockaddr *)msg->msg_name, &msg->msg_namelen); - } - } - - /* Initialize flag output */ - msg->msg_flags = 0; - - if (msg->msg_control) { - u8_t wrote_msg = 0; -#if LWIP_NETBUF_RECVINFO - /* Check if packet info was recorded */ - if (buf->flags & NETBUF_FLAG_DESTADDR) { - if (IP_IS_V4(&buf->toaddr)) { -#if LWIP_IPV4 - if (msg->msg_controllen >= CMSG_SPACE(sizeof(struct in_pktinfo))) { - struct cmsghdr *chdr = CMSG_FIRSTHDR(msg); /* This will always return a header!! */ - struct in_pktinfo *pkti = (struct in_pktinfo *)CMSG_DATA(chdr); - chdr->cmsg_level = IPPROTO_IP; - chdr->cmsg_type = IP_PKTINFO; - chdr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); - pkti->ipi_ifindex = buf->p->if_idx; - inet_addr_from_ip4addr(&pkti->ipi_addr, ip_2_ip4(netbuf_destaddr(buf))); - msg->msg_controllen = CMSG_SPACE(sizeof(struct in_pktinfo)); - wrote_msg = 1; - } else { - msg->msg_flags |= MSG_CTRUNC; - } -#endif /* LWIP_IPV4 */ - } - } -#endif /* LWIP_NETBUF_RECVINFO */ - - if (!wrote_msg) { - msg->msg_controllen = 0; - } - } - - /* If we don't peek the incoming message: zero lastdata pointer and free the netbuf */ - if ((flags & MSG_PEEK) == 0) { - sock->lastdata.netbuf = NULL; - netbuf_delete(buf); - } - if (datagram_len) { - *datagram_len = buflen; - } - return ERR_OK; -} - -ssize_t -lwip_recvfrom(int s, void *mem, size_t len, int flags, - struct sockaddr *from, socklen_t *fromlen) -{ - struct lwip_sock *sock; - ssize_t ret; - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d, %p, %"SZT_F", 0x%x, ..)\n", s, mem, len, flags)); - sock = get_socket(s); - if (!sock) { - return -1; - } -#if LWIP_TCP - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { - ret = lwip_recv_tcp(sock, mem, len, flags); - lwip_recv_tcp_from(sock, from, fromlen, "lwip_recvfrom", s, ret); - done_socket(sock); - return ret; - } else -#endif - { - u16_t datagram_len = 0; - struct iovec vec; - struct msghdr msg; - err_t err; - vec.iov_base = mem; - vec.iov_len = len; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = 0; - msg.msg_iov = &vec; - msg.msg_iovlen = 1; - msg.msg_name = from; - msg.msg_namelen = (fromlen ? *fromlen : 0); - err = lwip_recvfrom_udp_raw(sock, flags, &msg, &datagram_len, s); - if (err != ERR_OK) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom[UDP/RAW](%d): buf == NULL, error is \"%s\"!\n", - s, lwip_strerr(err))); - sock_set_errno(sock, err_to_errno(err)); - done_socket(sock); - return -1; - } - ret = (ssize_t)LWIP_MIN(LWIP_MIN(len, datagram_len), SSIZE_MAX); - if (fromlen) { - *fromlen = msg.msg_namelen; - } - } - - sock_set_errno(sock, 0); - done_socket(sock); - return ret; -} - -ssize_t -lwip_read(int s, void *mem, size_t len) -{ - return lwip_recvfrom(s, mem, len, 0, NULL, NULL); -} - -ssize_t -lwip_readv(int s, const struct iovec *iov, int iovcnt) -{ - struct msghdr msg; - - msg.msg_name = NULL; - msg.msg_namelen = 0; - /* Hack: we have to cast via number to cast from 'const' pointer to non-const. - Blame the opengroup standard for this inconsistency. */ - msg.msg_iov = LWIP_CONST_CAST(struct iovec *, iov); - msg.msg_iovlen = iovcnt; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = 0; - return lwip_recvmsg(s, &msg, 0); -} - -ssize_t -lwip_recv(int s, void *mem, size_t len, int flags) -{ - return lwip_recvfrom(s, mem, len, flags, NULL, NULL); -} - -ssize_t -lwip_recvmsg(int s, struct msghdr *message, int flags) -{ - struct lwip_sock *sock; - int i; - ssize_t buflen; - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvmsg(%d, message=%p, flags=0x%x)\n", s, (void *)message, flags)); - LWIP_ERROR("lwip_recvmsg: invalid message pointer", message != NULL, return ERR_ARG;); - LWIP_ERROR("lwip_recvmsg: unsupported flags", (flags & ~(MSG_PEEK|MSG_DONTWAIT)) == 0, - set_errno(EOPNOTSUPP); return -1;); - - if ((message->msg_iovlen <= 0) || (message->msg_iovlen > IOV_MAX)) { - set_errno(EMSGSIZE); - return -1; - } - - sock = get_socket(s); - if (!sock) { - return -1; - } - - /* check for valid vectors */ - buflen = 0; - for (i = 0; i < message->msg_iovlen; i++) { - if ((message->msg_iov[i].iov_base == NULL) || ((ssize_t)message->msg_iov[i].iov_len <= 0) || - ((size_t)(ssize_t)message->msg_iov[i].iov_len != message->msg_iov[i].iov_len) || - ((ssize_t)(buflen + (ssize_t)message->msg_iov[i].iov_len) <= 0)) { - sock_set_errno(sock, err_to_errno(ERR_VAL)); - done_socket(sock); - return -1; - } - buflen = (ssize_t)(buflen + (ssize_t)message->msg_iov[i].iov_len); - } - - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { -#if LWIP_TCP - int recv_flags = flags; - message->msg_flags = 0; - /* recv the data */ - buflen = 0; - for (i = 0; i < message->msg_iovlen; i++) { - /* try to receive into this vector's buffer */ - ssize_t recvd_local = lwip_recv_tcp(sock, message->msg_iov[i].iov_base, message->msg_iov[i].iov_len, recv_flags); - if (recvd_local > 0) { - /* sum up received bytes */ - buflen += recvd_local; - } - if ((recvd_local < 0) || (recvd_local < (int)message->msg_iov[i].iov_len) || - (flags & MSG_PEEK)) { - /* returned prematurely (or peeking, which might actually be limitated to the first iov) */ - if (buflen <= 0) { - /* nothing received at all, propagate the error */ - buflen = recvd_local; - } - break; - } - /* pass MSG_DONTWAIT to lwip_recv_tcp() to prevent waiting for more data */ - recv_flags |= MSG_DONTWAIT; - } - if (buflen > 0) { - /* reset socket error since we have received something */ - sock_set_errno(sock, 0); - } - /* " If the socket is connected, the msg_name and msg_namelen members shall be ignored." */ - done_socket(sock); - return buflen; -#else /* LWIP_TCP */ - sock_set_errno(sock, err_to_errno(ERR_ARG)); - done_socket(sock); - return -1; -#endif /* LWIP_TCP */ - } - /* else, UDP and RAW NETCONNs */ -#if LWIP_UDP || LWIP_RAW - { - u16_t datagram_len = 0; - err_t err; - err = lwip_recvfrom_udp_raw(sock, flags, message, &datagram_len, s); - if (err != ERR_OK) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvmsg[UDP/RAW](%d): buf == NULL, error is \"%s\"!\n", - s, lwip_strerr(err))); - sock_set_errno(sock, err_to_errno(err)); - done_socket(sock); - return -1; - } - if (datagram_len > buflen) { - message->msg_flags |= MSG_TRUNC; - } - - sock_set_errno(sock, 0); - done_socket(sock); - return (int)datagram_len; - } -#else /* LWIP_UDP || LWIP_RAW */ - sock_set_errno(sock, err_to_errno(ERR_ARG)); - done_socket(sock); - return -1; -#endif /* LWIP_UDP || LWIP_RAW */ -} - -ssize_t -lwip_send(int s, const void *data, size_t size, int flags) -{ - struct lwip_sock *sock; - err_t err; - u8_t write_flags; - size_t written; - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d, data=%p, size=%"SZT_F", flags=0x%x)\n", - s, data, size, flags)); - - sock = get_socket(s); - if (!sock) { - return -1; - } - - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { -#if (LWIP_UDP || LWIP_RAW) - done_socket(sock); - return lwip_sendto(s, data, size, flags, NULL, 0); -#else /* (LWIP_UDP || LWIP_RAW) */ - sock_set_errno(sock, err_to_errno(ERR_ARG)); - done_socket(sock); - return -1; -#endif /* (LWIP_UDP || LWIP_RAW) */ - } - - write_flags = (u8_t)(NETCONN_COPY | - ((flags & MSG_MORE) ? NETCONN_MORE : 0) | - ((flags & MSG_DONTWAIT) ? NETCONN_DONTBLOCK : 0)); - written = 0; - err = netconn_write_partly(sock->conn, data, size, write_flags, &written); - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d written=%"SZT_F"\n", s, err, written)); - sock_set_errno(sock, err_to_errno(err)); - done_socket(sock); - /* casting 'written' to ssize_t is OK here since the netconn API limits it to SSIZE_MAX */ - return (err == ERR_OK ? (ssize_t)written : -1); -} - -ssize_t -lwip_sendmsg(int s, const struct msghdr *msg, int flags) -{ - struct lwip_sock *sock; -#if LWIP_TCP - u8_t write_flags; - size_t written; -#endif - err_t err = ERR_OK; - - sock = get_socket(s); - if (!sock) { - return -1; - } - - LWIP_ERROR("lwip_sendmsg: invalid msghdr", msg != NULL, - sock_set_errno(sock, err_to_errno(ERR_ARG)); done_socket(sock); return -1;); - LWIP_ERROR("lwip_sendmsg: invalid msghdr iov", msg->msg_iov != NULL, - sock_set_errno(sock, err_to_errno(ERR_ARG)); done_socket(sock); return -1;); - LWIP_ERROR("lwip_sendmsg: maximum iovs exceeded", (msg->msg_iovlen > 0) && (msg->msg_iovlen <= IOV_MAX), - sock_set_errno(sock, EMSGSIZE); done_socket(sock); return -1;); - LWIP_ERROR("lwip_sendmsg: unsupported flags", (flags & ~(MSG_DONTWAIT | MSG_MORE)) == 0, - sock_set_errno(sock, EOPNOTSUPP); done_socket(sock); return -1;); - - LWIP_UNUSED_ARG(msg->msg_control); - LWIP_UNUSED_ARG(msg->msg_controllen); - LWIP_UNUSED_ARG(msg->msg_flags); - - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { -#if LWIP_TCP - write_flags = (u8_t)(NETCONN_COPY | - ((flags & MSG_MORE) ? NETCONN_MORE : 0) | - ((flags & MSG_DONTWAIT) ? NETCONN_DONTBLOCK : 0)); - - written = 0; - err = netconn_write_vectors_partly(sock->conn, (struct netvector *)msg->msg_iov, (u16_t)msg->msg_iovlen, write_flags, &written); - sock_set_errno(sock, err_to_errno(err)); - done_socket(sock); - /* casting 'written' to ssize_t is OK here since the netconn API limits it to SSIZE_MAX */ - return (err == ERR_OK ? (ssize_t)written : -1); -#else /* LWIP_TCP */ - sock_set_errno(sock, err_to_errno(ERR_ARG)); - done_socket(sock); - return -1; -#endif /* LWIP_TCP */ - } - /* else, UDP and RAW NETCONNs */ -#if LWIP_UDP || LWIP_RAW - { - struct netbuf chain_buf; - int i; - ssize_t size = 0; - - LWIP_UNUSED_ARG(flags); - LWIP_ERROR("lwip_sendmsg: invalid msghdr name", (((msg->msg_name == NULL) && (msg->msg_namelen == 0)) || - IS_SOCK_ADDR_LEN_VALID(msg->msg_namelen)), - sock_set_errno(sock, err_to_errno(ERR_ARG)); done_socket(sock); return -1;); - - /* initialize chain buffer with destination */ - memset(&chain_buf, 0, sizeof(struct netbuf)); - if (msg->msg_name) { - u16_t remote_port; - SOCKADDR_TO_IPADDR_PORT((const struct sockaddr *)msg->msg_name, &chain_buf.addr, remote_port); - netbuf_fromport(&chain_buf) = remote_port; - } -#if LWIP_NETIF_TX_SINGLE_PBUF - for (i = 0; i < msg->msg_iovlen; i++) { - size += msg->msg_iov[i].iov_len; - if ((msg->msg_iov[i].iov_len > INT_MAX) || (size < (int)msg->msg_iov[i].iov_len)) { - /* overflow */ - goto sendmsg_emsgsize; - } - } - if (size > 0xFFFF) { - /* overflow */ - goto sendmsg_emsgsize; - } - /* Allocate a new netbuf and copy the data into it. */ - if (netbuf_alloc(&chain_buf, (u16_t)size) == NULL) { - err = ERR_MEM; - } else { - /* flatten the IO vectors */ - size_t offset = 0; - for (i = 0; i < msg->msg_iovlen; i++) { - MEMCPY(&((u8_t *)chain_buf.p->payload)[offset], msg->msg_iov[i].iov_base, msg->msg_iov[i].iov_len); - offset += msg->msg_iov[i].iov_len; - } -#if LWIP_CHECKSUM_ON_COPY - { - /* This can be improved by using LWIP_CHKSUM_COPY() and aggregating the checksum for each IO vector */ - u16_t chksum = ~inet_chksum_pbuf(chain_buf.p); - netbuf_set_chksum(&chain_buf, chksum); - } -#endif /* LWIP_CHECKSUM_ON_COPY */ - err = ERR_OK; - } -#else /* LWIP_NETIF_TX_SINGLE_PBUF */ - /* create a chained netbuf from the IO vectors. NOTE: we assemble a pbuf chain - manually to avoid having to allocate, chain, and delete a netbuf for each iov */ - for (i = 0; i < msg->msg_iovlen; i++) { - struct pbuf *p; - if (msg->msg_iov[i].iov_len > 0xFFFF) { - /* overflow */ - goto sendmsg_emsgsize; - } - p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_REF); - if (p == NULL) { - err = ERR_MEM; /* let netbuf_delete() cleanup chain_buf */ - break; - } - p->payload = msg->msg_iov[i].iov_base; - p->len = p->tot_len = (u16_t)msg->msg_iov[i].iov_len; - /* netbuf empty, add new pbuf */ - if (chain_buf.p == NULL) { - chain_buf.p = chain_buf.ptr = p; - /* add pbuf to existing pbuf chain */ - } else { - if (chain_buf.p->tot_len + p->len > 0xffff) { - /* overflow */ - pbuf_free(p); - goto sendmsg_emsgsize; - } - pbuf_cat(chain_buf.p, p); - } - } - /* save size of total chain */ - if (err == ERR_OK) { - size = netbuf_len(&chain_buf); - } -#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ - - if (err == ERR_OK) { -#if LWIP_IPV4 && LWIP_IPV6 - /* Dual-stack: Unmap IPv4 mapped IPv6 addresses */ - if (IP_IS_V6_VAL(chain_buf.addr) && ip6_addr_isipv4mappedipv6(ip_2_ip6(&chain_buf.addr))) { - unmap_ipv4_mapped_ipv6(ip_2_ip4(&chain_buf.addr), ip_2_ip6(&chain_buf.addr)); - IP_SET_TYPE_VAL(chain_buf.addr, IPADDR_TYPE_V4); - } -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - - /* send the data */ - err = netconn_send(sock->conn, &chain_buf); - } - - /* deallocated the buffer */ - netbuf_free(&chain_buf); - - sock_set_errno(sock, err_to_errno(err)); - done_socket(sock); - return (err == ERR_OK ? size : -1); -sendmsg_emsgsize: - sock_set_errno(sock, EMSGSIZE); - netbuf_free(&chain_buf); - done_socket(sock); - return -1; - } -#else /* LWIP_UDP || LWIP_RAW */ - sock_set_errno(sock, err_to_errno(ERR_ARG)); - done_socket(sock); - return -1; -#endif /* LWIP_UDP || LWIP_RAW */ -} - -ssize_t -lwip_sendto(int s, const void *data, size_t size, int flags, - const struct sockaddr *to, socklen_t tolen) -{ - struct lwip_sock *sock; - err_t err; - u16_t short_size; - u16_t remote_port; - struct netbuf buf; - - sock = get_socket(s); - if (!sock) { - return -1; - } - - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { -#if LWIP_TCP - done_socket(sock); - return lwip_send(s, data, size, flags); -#else /* LWIP_TCP */ - LWIP_UNUSED_ARG(flags); - sock_set_errno(sock, err_to_errno(ERR_ARG)); - done_socket(sock); - return -1; -#endif /* LWIP_TCP */ - } - - if (size > LWIP_MIN(0xFFFF, SSIZE_MAX)) { - /* cannot fit into one datagram (at least for us) */ - sock_set_errno(sock, EMSGSIZE); - done_socket(sock); - return -1; - } - short_size = (u16_t)size; - LWIP_ERROR("lwip_sendto: invalid address", (((to == NULL) && (tolen == 0)) || - (IS_SOCK_ADDR_LEN_VALID(tolen) && - ((to != NULL) && (IS_SOCK_ADDR_TYPE_VALID(to) && IS_SOCK_ADDR_ALIGNED(to))))), - sock_set_errno(sock, err_to_errno(ERR_ARG)); done_socket(sock); return -1;); - LWIP_UNUSED_ARG(tolen); - - /* initialize a buffer */ - buf.p = buf.ptr = NULL; -#if LWIP_CHECKSUM_ON_COPY - buf.flags = 0; -#endif /* LWIP_CHECKSUM_ON_COPY */ - if (to) { - SOCKADDR_TO_IPADDR_PORT(to, &buf.addr, remote_port); - } else { - remote_port = 0; - ip_addr_set_any(NETCONNTYPE_ISIPV6(netconn_type(sock->conn)), &buf.addr); - } - netbuf_fromport(&buf) = remote_port; - - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_sendto(%d, data=%p, short_size=%"U16_F", flags=0x%x to=", - s, data, short_size, flags)); - ip_addr_debug_print_val(SOCKETS_DEBUG, buf.addr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", remote_port)); - - /* make the buffer point to the data that should be sent */ -#if LWIP_NETIF_TX_SINGLE_PBUF - /* Allocate a new netbuf and copy the data into it. */ - if (netbuf_alloc(&buf, short_size) == NULL) { - err = ERR_MEM; - } else { -#if LWIP_CHECKSUM_ON_COPY - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_RAW) { - u16_t chksum = LWIP_CHKSUM_COPY(buf.p->payload, data, short_size); - netbuf_set_chksum(&buf, chksum); - } else -#endif /* LWIP_CHECKSUM_ON_COPY */ - { - MEMCPY(buf.p->payload, data, short_size); - } - err = ERR_OK; - } -#else /* LWIP_NETIF_TX_SINGLE_PBUF */ - err = netbuf_ref(&buf, data, short_size); -#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ - if (err == ERR_OK) { -#if LWIP_IPV4 && LWIP_IPV6 - /* Dual-stack: Unmap IPv4 mapped IPv6 addresses */ - if (IP_IS_V6_VAL(buf.addr) && ip6_addr_isipv4mappedipv6(ip_2_ip6(&buf.addr))) { - unmap_ipv4_mapped_ipv6(ip_2_ip4(&buf.addr), ip_2_ip6(&buf.addr)); - IP_SET_TYPE_VAL(buf.addr, IPADDR_TYPE_V4); - } -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - - /* send the data */ - err = netconn_send(sock->conn, &buf); - } - - /* deallocated the buffer */ - netbuf_free(&buf); - - sock_set_errno(sock, err_to_errno(err)); - done_socket(sock); - return (err == ERR_OK ? short_size : -1); -} - -int -lwip_socket(int domain, int type, int protocol) -{ - struct netconn *conn; - int i; - - LWIP_UNUSED_ARG(domain); /* @todo: check this */ - - /* create a netconn */ - switch (type) { - case SOCK_RAW: - conn = netconn_new_with_proto_and_callback(DOMAIN_TO_NETCONN_TYPE(domain, NETCONN_RAW), - (u8_t)protocol, DEFAULT_SOCKET_EVENTCB); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_RAW, %d) = ", - domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); - break; - case SOCK_DGRAM: - conn = netconn_new_with_callback(DOMAIN_TO_NETCONN_TYPE(domain, - ((protocol == IPPROTO_UDPLITE) ? NETCONN_UDPLITE : NETCONN_UDP)), - DEFAULT_SOCKET_EVENTCB); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_DGRAM, %d) = ", - domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); -#if LWIP_NETBUF_RECVINFO - if (conn) { - /* netconn layer enables pktinfo by default, sockets default to off */ - conn->flags &= ~NETCONN_FLAG_PKTINFO; - } -#endif /* LWIP_NETBUF_RECVINFO */ - break; - case SOCK_STREAM: - conn = netconn_new_with_callback(DOMAIN_TO_NETCONN_TYPE(domain, NETCONN_TCP), DEFAULT_SOCKET_EVENTCB); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_STREAM, %d) = ", - domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); - break; - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%d, %d/UNKNOWN, %d) = -1\n", - domain, type, protocol)); - set_errno(EINVAL); - return -1; - } - - if (!conn) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("-1 / ENOBUFS (could not create netconn)\n")); - set_errno(ENOBUFS); - return -1; - } - - i = alloc_socket(conn, 0); - - if (i == -1) { - netconn_delete(conn); - set_errno(ENFILE); - return -1; - } - conn->socket = i; - done_socket(&sockets[i - LWIP_SOCKET_OFFSET]); - LWIP_DEBUGF(SOCKETS_DEBUG, ("%d\n", i)); - set_errno(0); - return i; -} - -ssize_t -lwip_write(int s, const void *data, size_t size) -{ - return lwip_send(s, data, size, 0); -} - -ssize_t -lwip_writev(int s, const struct iovec *iov, int iovcnt) -{ - struct msghdr msg; - - msg.msg_name = NULL; - msg.msg_namelen = 0; - /* Hack: we have to cast via number to cast from 'const' pointer to non-const. - Blame the opengroup standard for this inconsistency. */ - msg.msg_iov = LWIP_CONST_CAST(struct iovec *, iov); - msg.msg_iovlen = iovcnt; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = 0; - return lwip_sendmsg(s, &msg, 0); -} - -#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL -/* Add select_cb to select_cb_list. */ -static void -lwip_link_select_cb(struct lwip_select_cb *select_cb) -{ - LWIP_SOCKET_SELECT_DECL_PROTECT(lev); - - /* Protect the select_cb_list */ - LWIP_SOCKET_SELECT_PROTECT(lev); - - /* Put this select_cb on top of list */ - select_cb->next = select_cb_list; - if (select_cb_list != NULL) { - select_cb_list->prev = select_cb; - } - select_cb_list = select_cb; -#if !LWIP_TCPIP_CORE_LOCKING - /* Increasing this counter tells select_check_waiters that the list has changed. */ - select_cb_ctr++; -#endif - - /* Now we can safely unprotect */ - LWIP_SOCKET_SELECT_UNPROTECT(lev); -} - -/* Remove select_cb from select_cb_list. */ -static void -lwip_unlink_select_cb(struct lwip_select_cb *select_cb) -{ - LWIP_SOCKET_SELECT_DECL_PROTECT(lev); - - /* Take us off the list */ - LWIP_SOCKET_SELECT_PROTECT(lev); - if (select_cb->next != NULL) { - select_cb->next->prev = select_cb->prev; - } - if (select_cb_list == select_cb) { - LWIP_ASSERT("select_cb->prev == NULL", select_cb->prev == NULL); - select_cb_list = select_cb->next; - } else { - LWIP_ASSERT("select_cb->prev != NULL", select_cb->prev != NULL); - select_cb->prev->next = select_cb->next; - } -#if !LWIP_TCPIP_CORE_LOCKING - /* Increasing this counter tells select_check_waiters that the list has changed. */ - select_cb_ctr++; -#endif - LWIP_SOCKET_SELECT_UNPROTECT(lev); -} -#endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */ - -#if LWIP_SOCKET_SELECT -/** - * Go through the readset and writeset lists and see which socket of the sockets - * set in the sets has events. On return, readset, writeset and exceptset have - * the sockets enabled that had events. - * - * @param maxfdp1 the highest socket index in the sets - * @param readset_in set of sockets to check for read events - * @param writeset_in set of sockets to check for write events - * @param exceptset_in set of sockets to check for error events - * @param readset_out set of sockets that had read events - * @param writeset_out set of sockets that had write events - * @param exceptset_out set os sockets that had error events - * @return number of sockets that had events (read/write/exception) (>= 0) - */ -static int -lwip_selscan(int maxfdp1, fd_set *readset_in, fd_set *writeset_in, fd_set *exceptset_in, - fd_set *readset_out, fd_set *writeset_out, fd_set *exceptset_out) -{ - int i, nready = 0; - fd_set lreadset, lwriteset, lexceptset; - struct lwip_sock *sock; - SYS_ARCH_DECL_PROTECT(lev); - - FD_ZERO(&lreadset); - FD_ZERO(&lwriteset); - FD_ZERO(&lexceptset); - - /* Go through each socket in each list to count number of sockets which - currently match */ - for (i = LWIP_SOCKET_OFFSET; i < maxfdp1; i++) { - /* if this FD is not in the set, continue */ - if (!(readset_in && FD_ISSET(i, readset_in)) && - !(writeset_in && FD_ISSET(i, writeset_in)) && - !(exceptset_in && FD_ISSET(i, exceptset_in))) { - continue; - } - /* First get the socket's status (protected)... */ - SYS_ARCH_PROTECT(lev); - sock = tryget_socket_unconn_locked(i); - if (sock != NULL) { - void *lastdata = sock->lastdata.pbuf; - s16_t rcvevent = sock->rcvevent; - u16_t sendevent = sock->sendevent; - u16_t errevent = sock->errevent; - SYS_ARCH_UNPROTECT(lev); - - /* ... then examine it: */ - /* See if netconn of this socket is ready for read */ - if (readset_in && FD_ISSET(i, readset_in) && ((lastdata != NULL) || (rcvevent > 0))) { - FD_SET(i, &lreadset); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for reading\n", i)); - nready++; - } - /* See if netconn of this socket is ready for write */ - if (writeset_in && FD_ISSET(i, writeset_in) && (sendevent != 0)) { - FD_SET(i, &lwriteset); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for writing\n", i)); - nready++; - } - /* See if netconn of this socket had an error */ - if (exceptset_in && FD_ISSET(i, exceptset_in) && (errevent != 0)) { - FD_SET(i, &lexceptset); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for exception\n", i)); - nready++; - } - done_socket(sock); - } else { - SYS_ARCH_UNPROTECT(lev); - /* no a valid open socket */ - return -1; - } - } - /* copy local sets to the ones provided as arguments */ - *readset_out = lreadset; - *writeset_out = lwriteset; - *exceptset_out = lexceptset; - - LWIP_ASSERT("nready >= 0", nready >= 0); - return nready; -} - -#if LWIP_NETCONN_FULLDUPLEX -/* Mark all of the set sockets in one of the three fdsets passed to select as used. - * All sockets are marked (and later unmarked), whether they are open or not. - * This is OK as lwip_selscan aborts select when non-open sockets are found. - */ -static void -lwip_select_inc_sockets_used_set(int maxfdp, fd_set *fdset, fd_set *used_sockets) -{ - SYS_ARCH_DECL_PROTECT(lev); - if (fdset) { - int i; - for (i = LWIP_SOCKET_OFFSET; i < maxfdp; i++) { - /* if this FD is in the set, lock it (unless already done) */ - if (FD_ISSET(i, fdset) && !FD_ISSET(i, used_sockets)) { - struct lwip_sock *sock; - SYS_ARCH_PROTECT(lev); - sock = tryget_socket_unconn_locked(i); - if (sock != NULL) { - /* leave the socket used until released by lwip_select_dec_sockets_used */ - FD_SET(i, used_sockets); - } - SYS_ARCH_UNPROTECT(lev); - } - } - } -} - -/* Mark all sockets passed to select as used to prevent them from being freed - * from other threads while select is running. - * Marked sockets are added to 'used_sockets' to mark them only once an be able - * to unmark them correctly. - */ -static void -lwip_select_inc_sockets_used(int maxfdp, fd_set *fdset1, fd_set *fdset2, fd_set *fdset3, fd_set *used_sockets) -{ - FD_ZERO(used_sockets); - lwip_select_inc_sockets_used_set(maxfdp, fdset1, used_sockets); - lwip_select_inc_sockets_used_set(maxfdp, fdset2, used_sockets); - lwip_select_inc_sockets_used_set(maxfdp, fdset3, used_sockets); -} - -/* Let go all sockets that were marked as used when starting select */ -static void -lwip_select_dec_sockets_used(int maxfdp, fd_set *used_sockets) -{ - int i; - for (i = LWIP_SOCKET_OFFSET; i < maxfdp; i++) { - /* if this FD is not in the set, continue */ - if (FD_ISSET(i, used_sockets)) { - struct lwip_sock *sock = tryget_socket_unconn_nouse(i); - LWIP_ASSERT("socket gone at the end of select", sock != NULL); - if (sock != NULL) { - done_socket(sock); - } - } - } -} -#else /* LWIP_NETCONN_FULLDUPLEX */ -#define lwip_select_inc_sockets_used(maxfdp1, readset, writeset, exceptset, used_sockets) -#define lwip_select_dec_sockets_used(maxfdp1, used_sockets) -#endif /* LWIP_NETCONN_FULLDUPLEX */ - -int -lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, - struct timeval *timeout) -{ - u32_t waitres = 0; - int nready; - fd_set lreadset, lwriteset, lexceptset; - u32_t msectimeout; - int i; - int maxfdp2; -#if LWIP_NETCONN_SEM_PER_THREAD - int waited = 0; -#endif -#if LWIP_NETCONN_FULLDUPLEX - fd_set used_sockets; -#endif - SYS_ARCH_DECL_PROTECT(lev); - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select(%d, %p, %p, %p, tvsec=%"S32_F" tvusec=%"S32_F")\n", - maxfdp1, (void *)readset, (void *) writeset, (void *) exceptset, - timeout ? (s32_t)timeout->tv_sec : (s32_t) - 1, - timeout ? (s32_t)timeout->tv_usec : (s32_t) - 1)); - - if ((maxfdp1 < 0) || (maxfdp1 > LWIP_SELECT_MAXNFDS)) { - set_errno(EINVAL); - return -1; - } - - lwip_select_inc_sockets_used(maxfdp1, readset, writeset, exceptset, &used_sockets); - - /* Go through each socket in each list to count number of sockets which - currently match */ - nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset); - - if (nready < 0) { - /* one of the sockets in one of the fd_sets was invalid */ - set_errno(EBADF); - lwip_select_dec_sockets_used(maxfdp1, &used_sockets); - return -1; - } else if (nready > 0) { - /* one or more sockets are set, no need to wait */ - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready)); - } else { - /* If we don't have any current events, then suspend if we are supposed to */ - if (timeout && timeout->tv_sec == 0 && timeout->tv_usec == 0) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: no timeout, returning 0\n")); - /* This is OK as the local fdsets are empty and nready is zero, - or we would have returned earlier. */ - } else { - /* None ready: add our semaphore to list: - We don't actually need any dynamic memory. Our entry on the - list is only valid while we are in this function, so it's ok - to use local variables (unless we're running in MPU compatible - mode). */ - API_SELECT_CB_VAR_DECLARE(select_cb); - API_SELECT_CB_VAR_ALLOC(select_cb, set_errno(ENOMEM); lwip_select_dec_sockets_used(maxfdp1, &used_sockets); return -1); - memset(&API_SELECT_CB_VAR_REF(select_cb), 0, sizeof(struct lwip_select_cb)); - - API_SELECT_CB_VAR_REF(select_cb).readset = readset; - API_SELECT_CB_VAR_REF(select_cb).writeset = writeset; - API_SELECT_CB_VAR_REF(select_cb).exceptset = exceptset; -#if LWIP_NETCONN_SEM_PER_THREAD - API_SELECT_CB_VAR_REF(select_cb).sem = LWIP_NETCONN_THREAD_SEM_GET(); -#else /* LWIP_NETCONN_SEM_PER_THREAD */ - if (sys_sem_new(&API_SELECT_CB_VAR_REF(select_cb).sem, 0) != ERR_OK) { - /* failed to create semaphore */ - set_errno(ENOMEM); - lwip_select_dec_sockets_used(maxfdp1, &used_sockets); - API_SELECT_CB_VAR_FREE(select_cb); - return -1; - } -#endif /* LWIP_NETCONN_SEM_PER_THREAD */ - - lwip_link_select_cb(&API_SELECT_CB_VAR_REF(select_cb)); - - /* Increase select_waiting for each socket we are interested in */ - maxfdp2 = maxfdp1; - for (i = LWIP_SOCKET_OFFSET; i < maxfdp1; i++) { - if ((readset && FD_ISSET(i, readset)) || - (writeset && FD_ISSET(i, writeset)) || - (exceptset && FD_ISSET(i, exceptset))) { - struct lwip_sock *sock; - SYS_ARCH_PROTECT(lev); - sock = tryget_socket_unconn_locked(i); - if (sock != NULL) { - sock->select_waiting++; - if (sock->select_waiting == 0) { - /* overflow - too many threads waiting */ - sock->select_waiting--; - nready = -1; - maxfdp2 = i; - SYS_ARCH_UNPROTECT(lev); - done_socket(sock); - set_errno(EBUSY); - break; - } - SYS_ARCH_UNPROTECT(lev); - done_socket(sock); - } else { - /* Not a valid socket */ - nready = -1; - maxfdp2 = i; - SYS_ARCH_UNPROTECT(lev); - set_errno(EBADF); - break; - } - } - } - - if (nready >= 0) { - /* Call lwip_selscan again: there could have been events between - the last scan (without us on the list) and putting us on the list! */ - nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset); - if (!nready) { - /* Still none ready, just wait to be woken */ - if (timeout == 0) { - /* Wait forever */ - msectimeout = 0; - } else { - long msecs_long = ((timeout->tv_sec * 1000) + ((timeout->tv_usec + 500) / 1000)); - if (msecs_long <= 0) { - /* Wait 1ms at least (0 means wait forever) */ - msectimeout = 1; - } else { - msectimeout = (u32_t)msecs_long; - } - } - - waitres = sys_arch_sem_wait(SELECT_SEM_PTR(API_SELECT_CB_VAR_REF(select_cb).sem), msectimeout); -#if LWIP_NETCONN_SEM_PER_THREAD - waited = 1; -#endif - } - } - - /* Decrease select_waiting for each socket we are interested in */ - for (i = LWIP_SOCKET_OFFSET; i < maxfdp2; i++) { - if ((readset && FD_ISSET(i, readset)) || - (writeset && FD_ISSET(i, writeset)) || - (exceptset && FD_ISSET(i, exceptset))) { - struct lwip_sock *sock; - SYS_ARCH_PROTECT(lev); - sock = tryget_socket_unconn_locked(i); - if (sock != NULL) { - /* for now, handle select_waiting==0... */ - LWIP_ASSERT("sock->select_waiting > 0", sock->select_waiting > 0); - if (sock->select_waiting > 0) { - sock->select_waiting--; - } - SYS_ARCH_UNPROTECT(lev); - done_socket(sock); - } else { - SYS_ARCH_UNPROTECT(lev); - /* Not a valid socket */ - nready = -1; - set_errno(EBADF); - } - } - } - - lwip_unlink_select_cb(&API_SELECT_CB_VAR_REF(select_cb)); - -#if LWIP_NETCONN_SEM_PER_THREAD - if (API_SELECT_CB_VAR_REF(select_cb).sem_signalled && (!waited || (waitres == SYS_ARCH_TIMEOUT))) { - /* don't leave the thread-local semaphore signalled */ - sys_arch_sem_wait(API_SELECT_CB_VAR_REF(select_cb).sem, 1); - } -#else /* LWIP_NETCONN_SEM_PER_THREAD */ - sys_sem_free(&API_SELECT_CB_VAR_REF(select_cb).sem); -#endif /* LWIP_NETCONN_SEM_PER_THREAD */ - API_SELECT_CB_VAR_FREE(select_cb); - - if (nready < 0) { - /* This happens when a socket got closed while waiting */ - lwip_select_dec_sockets_used(maxfdp1, &used_sockets); - return -1; - } - - if (waitres == SYS_ARCH_TIMEOUT) { - /* Timeout */ - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: timeout expired\n")); - /* This is OK as the local fdsets are empty and nready is zero, - or we would have returned earlier. */ - } else { - /* See what's set now after waiting */ - nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready)); - } - } - } - - lwip_select_dec_sockets_used(maxfdp1, &used_sockets); - set_errno(0); - if (readset) { - *readset = lreadset; - } - if (writeset) { - *writeset = lwriteset; - } - if (exceptset) { - *exceptset = lexceptset; - } - return nready; -} -#endif /* LWIP_SOCKET_SELECT */ - -#if LWIP_SOCKET_POLL -/** Options for the lwip_pollscan function. */ -enum lwip_pollscan_opts -{ - /** Clear revents in each struct pollfd. */ - LWIP_POLLSCAN_CLEAR = 1, - - /** Increment select_waiting in each struct lwip_sock. */ - LWIP_POLLSCAN_INC_WAIT = 2, - - /** Decrement select_waiting in each struct lwip_sock. */ - LWIP_POLLSCAN_DEC_WAIT = 4 -}; - -/** - * Update revents in each struct pollfd. - * Optionally update select_waiting in struct lwip_sock. - * - * @param fds array of structures to update - * @param nfds number of structures in fds - * @param opts what to update and how - * @return number of structures that have revents != 0 - */ -static int -lwip_pollscan(struct pollfd *fds, nfds_t nfds, enum lwip_pollscan_opts opts) -{ - int nready = 0; - nfds_t fdi; - struct lwip_sock *sock; - SYS_ARCH_DECL_PROTECT(lev); - - /* Go through each struct pollfd in the array. */ - for (fdi = 0; fdi < nfds; fdi++) { - if ((opts & LWIP_POLLSCAN_CLEAR) != 0) { - fds[fdi].revents = 0; - } - - /* Negative fd means the caller wants us to ignore this struct. - POLLNVAL means we already detected that the fd is invalid; - if another thread has since opened a new socket with that fd, - we must not use that socket. */ - if (fds[fdi].fd >= 0 && (fds[fdi].revents & POLLNVAL) == 0) { - /* First get the socket's status (protected)... */ - SYS_ARCH_PROTECT(lev); - sock = tryget_socket_unconn_locked(fds[fdi].fd); - if (sock != NULL) { - void* lastdata = sock->lastdata.pbuf; - s16_t rcvevent = sock->rcvevent; - u16_t sendevent = sock->sendevent; - u16_t errevent = sock->errevent; - - if ((opts & LWIP_POLLSCAN_INC_WAIT) != 0) { - sock->select_waiting++; - if (sock->select_waiting == 0) { - /* overflow - too many threads waiting */ - sock->select_waiting--; - nready = -1; - SYS_ARCH_UNPROTECT(lev); - done_socket(sock); - break; - } - } else if ((opts & LWIP_POLLSCAN_DEC_WAIT) != 0) { - /* for now, handle select_waiting==0... */ - LWIP_ASSERT("sock->select_waiting > 0", sock->select_waiting > 0); - if (sock->select_waiting > 0) { - sock->select_waiting--; - } - } - SYS_ARCH_UNPROTECT(lev); - done_socket(sock); - - /* ... then examine it: */ - /* See if netconn of this socket is ready for read */ - if ((fds[fdi].events & POLLIN) != 0 && ((lastdata != NULL) || (rcvevent > 0))) { - fds[fdi].revents |= POLLIN; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_pollscan: fd=%d ready for reading\n", fds[fdi].fd)); - } - /* See if netconn of this socket is ready for write */ - if ((fds[fdi].events & POLLOUT) != 0 && (sendevent != 0)) { - fds[fdi].revents |= POLLOUT; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_pollscan: fd=%d ready for writing\n", fds[fdi].fd)); - } - /* See if netconn of this socket had an error */ - if (errevent != 0) { - /* POLLERR is output only. */ - fds[fdi].revents |= POLLERR; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_pollscan: fd=%d ready for exception\n", fds[fdi].fd)); - } - } else { - /* Not a valid socket */ - SYS_ARCH_UNPROTECT(lev); - /* POLLNVAL is output only. */ - fds[fdi].revents |= POLLNVAL; - return -1; - } - } - - /* Will return the number of structures that have events, - not the number of events. */ - if (fds[fdi].revents != 0) { - nready++; - } - } - - LWIP_ASSERT("nready >= 0", nready >= 0); - return nready; -} - -#if LWIP_NETCONN_FULLDUPLEX -/* Mark all sockets as used. - * - * All sockets are marked (and later unmarked), whether they are open or not. - * This is OK as lwip_pollscan aborts select when non-open sockets are found. - */ -static void -lwip_poll_inc_sockets_used(struct pollfd *fds, nfds_t nfds) -{ - nfds_t fdi; - - if(fds) { - /* Go through each struct pollfd in the array. */ - for (fdi = 0; fdi < nfds; fdi++) { - /* Increase the reference counter */ - tryget_socket_unconn(fds[fdi].fd); - } - } -} - -/* Let go all sockets that were marked as used when starting poll */ -static void -lwip_poll_dec_sockets_used(struct pollfd *fds, nfds_t nfds) -{ - nfds_t fdi; - - if(fds) { - /* Go through each struct pollfd in the array. */ - for (fdi = 0; fdi < nfds; fdi++) { - struct lwip_sock *sock = tryget_socket_unconn_nouse(fds[fdi].fd); - if (sock != NULL) { - done_socket(sock); - } - } - } -} -#else /* LWIP_NETCONN_FULLDUPLEX */ -#define lwip_poll_inc_sockets_used(fds, nfds) -#define lwip_poll_dec_sockets_used(fds, nfds) -#endif /* LWIP_NETCONN_FULLDUPLEX */ - -int -lwip_poll(struct pollfd *fds, nfds_t nfds, int timeout) -{ - u32_t waitres = 0; - int nready; - u32_t msectimeout; -#if LWIP_NETCONN_SEM_PER_THREAD - int waited = 0; -#endif - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_poll(%p, %d, %d)\n", - (void*)fds, (int)nfds, timeout)); - LWIP_ERROR("lwip_poll: invalid fds", ((fds != NULL && nfds > 0) || (fds == NULL && nfds == 0)), - set_errno(EINVAL); return -1;); - - lwip_poll_inc_sockets_used(fds, nfds); - - /* Go through each struct pollfd to count number of structures - which currently match */ - nready = lwip_pollscan(fds, nfds, LWIP_POLLSCAN_CLEAR); - - if (nready < 0) { - lwip_poll_dec_sockets_used(fds, nfds); - return -1; - } - - /* If we don't have any current events, then suspend if we are supposed to */ - if (!nready) { - API_SELECT_CB_VAR_DECLARE(select_cb); - - if (timeout == 0) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_poll: no timeout, returning 0\n")); - goto return_success; - } - API_SELECT_CB_VAR_ALLOC(select_cb, set_errno(EAGAIN); lwip_poll_dec_sockets_used(fds, nfds); return -1); - memset(&API_SELECT_CB_VAR_REF(select_cb), 0, sizeof(struct lwip_select_cb)); - - /* None ready: add our semaphore to list: - We don't actually need any dynamic memory. Our entry on the - list is only valid while we are in this function, so it's ok - to use local variables. */ - - API_SELECT_CB_VAR_REF(select_cb).poll_fds = fds; - API_SELECT_CB_VAR_REF(select_cb).poll_nfds = nfds; -#if LWIP_NETCONN_SEM_PER_THREAD - API_SELECT_CB_VAR_REF(select_cb).sem = LWIP_NETCONN_THREAD_SEM_GET(); -#else /* LWIP_NETCONN_SEM_PER_THREAD */ - if (sys_sem_new(&API_SELECT_CB_VAR_REF(select_cb).sem, 0) != ERR_OK) { - /* failed to create semaphore */ - set_errno(EAGAIN); - lwip_poll_dec_sockets_used(fds, nfds); - API_SELECT_CB_VAR_FREE(select_cb); - return -1; - } -#endif /* LWIP_NETCONN_SEM_PER_THREAD */ - - lwip_link_select_cb(&API_SELECT_CB_VAR_REF(select_cb)); - - /* Increase select_waiting for each socket we are interested in. - Also, check for events again: there could have been events between - the last scan (without us on the list) and putting us on the list! */ - nready = lwip_pollscan(fds, nfds, LWIP_POLLSCAN_INC_WAIT); - - if (!nready) { - /* Still none ready, just wait to be woken */ - if (timeout < 0) { - /* Wait forever */ - msectimeout = 0; - } else { - /* timeout == 0 would have been handled earlier. */ - LWIP_ASSERT("timeout > 0", timeout > 0); - msectimeout = timeout; - } - waitres = sys_arch_sem_wait(SELECT_SEM_PTR(API_SELECT_CB_VAR_REF(select_cb).sem), msectimeout); -#if LWIP_NETCONN_SEM_PER_THREAD - waited = 1; -#endif - } - - /* Decrease select_waiting for each socket we are interested in, - and check which events occurred while we waited. */ - nready = lwip_pollscan(fds, nfds, LWIP_POLLSCAN_DEC_WAIT); - - lwip_unlink_select_cb(&API_SELECT_CB_VAR_REF(select_cb)); - -#if LWIP_NETCONN_SEM_PER_THREAD - if (select_cb.sem_signalled && (!waited || (waitres == SYS_ARCH_TIMEOUT))) { - /* don't leave the thread-local semaphore signalled */ - sys_arch_sem_wait(API_SELECT_CB_VAR_REF(select_cb).sem, 1); - } -#else /* LWIP_NETCONN_SEM_PER_THREAD */ - sys_sem_free(&API_SELECT_CB_VAR_REF(select_cb).sem); -#endif /* LWIP_NETCONN_SEM_PER_THREAD */ - API_SELECT_CB_VAR_FREE(select_cb); - - if (nready < 0) { - /* This happens when a socket got closed while waiting */ - lwip_poll_dec_sockets_used(fds, nfds); - return -1; - } - - if (waitres == SYS_ARCH_TIMEOUT) { - /* Timeout */ - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_poll: timeout expired\n")); - goto return_success; - } - } - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_poll: nready=%d\n", nready)); -return_success: - lwip_poll_dec_sockets_used(fds, nfds); - set_errno(0); - return nready; -} - -/** - * Check whether event_callback should wake up a thread waiting in - * lwip_poll. - */ -static int -lwip_poll_should_wake(const struct lwip_select_cb *scb, int fd, int has_recvevent, int has_sendevent, int has_errevent) -{ - nfds_t fdi; - for (fdi = 0; fdi < scb->poll_nfds; fdi++) { - const struct pollfd *pollfd = &scb->poll_fds[fdi]; - if (pollfd->fd == fd) { - /* Do not update pollfd->revents right here; - that would be a data race because lwip_pollscan - accesses revents without protecting. */ - if (has_recvevent && (pollfd->events & POLLIN) != 0) { - return 1; - } - if (has_sendevent && (pollfd->events & POLLOUT) != 0) { - return 1; - } - if (has_errevent) { - /* POLLERR is output only. */ - return 1; - } - } - } - return 0; -} -#endif /* LWIP_SOCKET_POLL */ - -#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL -/** - * Callback registered in the netconn layer for each socket-netconn. - * Processes recvevent (data available) and wakes up tasks waiting for select. - * - * @note for LWIP_TCPIP_CORE_LOCKING any caller of this function - * must have the core lock held when signaling the following events - * as they might cause select_list_cb to be checked: - * NETCONN_EVT_RCVPLUS - * NETCONN_EVT_SENDPLUS - * NETCONN_EVT_ERROR - * This requirement will be asserted in select_check_waiters() - */ -static void -event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len) -{ - int s, check_waiters; - struct lwip_sock *sock; - SYS_ARCH_DECL_PROTECT(lev); - - LWIP_UNUSED_ARG(len); - - /* Get socket */ - if (conn) { - s = conn->socket; - if (s < 0) { - /* Data comes in right away after an accept, even though - * the server task might not have created a new socket yet. - * Just count down (or up) if that's the case and we - * will use the data later. Note that only receive events - * can happen before the new socket is set up. */ - SYS_ARCH_PROTECT(lev); - if (conn->socket < 0) { - if (evt == NETCONN_EVT_RCVPLUS) { - /* conn->socket is -1 on initialization - lwip_accept adjusts sock->recvevent if conn->socket < -1 */ - conn->socket--; - } - SYS_ARCH_UNPROTECT(lev); - return; - } - s = conn->socket; - SYS_ARCH_UNPROTECT(lev); - } - - sock = get_socket(s); - if (!sock) { - return; - } - } else { - return; - } - - check_waiters = 1; - SYS_ARCH_PROTECT(lev); - /* Set event as required */ - switch (evt) { - case NETCONN_EVT_RCVPLUS: - sock->rcvevent++; - if (sock->rcvevent > 1) { - check_waiters = 0; - } - break; - case NETCONN_EVT_RCVMINUS: - sock->rcvevent--; - check_waiters = 0; - break; - case NETCONN_EVT_SENDPLUS: - if (sock->sendevent) { - check_waiters = 0; - } - sock->sendevent = 1; - break; - case NETCONN_EVT_SENDMINUS: - sock->sendevent = 0; - check_waiters = 0; - break; - case NETCONN_EVT_ERROR: - sock->errevent = 1; - break; - default: - LWIP_ASSERT("unknown event", 0); - break; - } - - if (sock->select_waiting && check_waiters) { - /* Save which events are active */ - int has_recvevent, has_sendevent, has_errevent; - has_recvevent = sock->rcvevent > 0; - has_sendevent = sock->sendevent != 0; - has_errevent = sock->errevent != 0; - SYS_ARCH_UNPROTECT(lev); - /* Check any select calls waiting on this socket */ - select_check_waiters(s, has_recvevent, has_sendevent, has_errevent); - } else { - SYS_ARCH_UNPROTECT(lev); - } - done_socket(sock); -} - -/** - * Check if any select waiters are waiting on this socket and its events - * - * @note on synchronization of select_cb_list: - * LWIP_TCPIP_CORE_LOCKING: the select_cb_list must only be accessed while holding - * the core lock. We do a single pass through the list and signal any waiters. - * Core lock should already be held when calling here!!!! - - * !LWIP_TCPIP_CORE_LOCKING: we use SYS_ARCH_PROTECT but unlock on each iteration - * of the loop, thus creating a possibility where a thread could modify the - * select_cb_list during our UNPROTECT/PROTECT. We use a generational counter to - * detect this change and restart the list walk. The list is expected to be small - */ -static void select_check_waiters(int s, int has_recvevent, int has_sendevent, int has_errevent) -{ - struct lwip_select_cb *scb; -#if !LWIP_TCPIP_CORE_LOCKING - int last_select_cb_ctr; - SYS_ARCH_DECL_PROTECT(lev); -#endif /* !LWIP_TCPIP_CORE_LOCKING */ - - LWIP_ASSERT_CORE_LOCKED(); - -#if !LWIP_TCPIP_CORE_LOCKING - SYS_ARCH_PROTECT(lev); -again: - /* remember the state of select_cb_list to detect changes */ - last_select_cb_ctr = select_cb_ctr; -#endif /* !LWIP_TCPIP_CORE_LOCKING */ - for (scb = select_cb_list; scb != NULL; scb = scb->next) { - if (scb->sem_signalled == 0) { - /* semaphore not signalled yet */ - int do_signal = 0; -#if LWIP_SOCKET_POLL - if (scb->poll_fds != NULL) { - do_signal = lwip_poll_should_wake(scb, s, has_recvevent, has_sendevent, has_errevent); - } -#endif /* LWIP_SOCKET_POLL */ -#if LWIP_SOCKET_SELECT && LWIP_SOCKET_POLL - else -#endif /* LWIP_SOCKET_SELECT && LWIP_SOCKET_POLL */ -#if LWIP_SOCKET_SELECT - { - /* Test this select call for our socket */ - if (has_recvevent) { - if (scb->readset && FD_ISSET(s, scb->readset)) { - do_signal = 1; - } - } - if (has_sendevent) { - if (!do_signal && scb->writeset && FD_ISSET(s, scb->writeset)) { - do_signal = 1; - } - } - if (has_errevent) { - if (!do_signal && scb->exceptset && FD_ISSET(s, scb->exceptset)) { - do_signal = 1; - } - } - } -#endif /* LWIP_SOCKET_SELECT */ - if (do_signal) { - scb->sem_signalled = 1; - /* For !LWIP_TCPIP_CORE_LOCKING, we don't call SYS_ARCH_UNPROTECT() before signaling - the semaphore, as this might lead to the select thread taking itself off the list, - invalidating the semaphore. */ - sys_sem_signal(SELECT_SEM_PTR(scb->sem)); - } - } -#if LWIP_TCPIP_CORE_LOCKING - } -#else - /* unlock interrupts with each step */ - SYS_ARCH_UNPROTECT(lev); - /* this makes sure interrupt protection time is short */ - SYS_ARCH_PROTECT(lev); - if (last_select_cb_ctr != select_cb_ctr) { - /* someone has changed select_cb_list, restart at the beginning */ - goto again; - } - /* remember the state of select_cb_list to detect changes */ - last_select_cb_ctr = select_cb_ctr; - } - SYS_ARCH_UNPROTECT(lev); -#endif -} -#endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */ - -/** - * Close one end of a full-duplex connection. - */ -int -lwip_shutdown(int s, int how) -{ - struct lwip_sock *sock; - err_t err; - u8_t shut_rx = 0, shut_tx = 0; - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_shutdown(%d, how=%d)\n", s, how)); - - sock = get_socket(s); - if (!sock) { - return -1; - } - - if (sock->conn != NULL) { - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { - sock_set_errno(sock, EOPNOTSUPP); - done_socket(sock); - return -1; - } - } else { - sock_set_errno(sock, ENOTCONN); - done_socket(sock); - return -1; - } - - if (how == SHUT_RD) { - shut_rx = 1; - } else if (how == SHUT_WR) { - shut_tx = 1; - } else if (how == SHUT_RDWR) { - shut_rx = 1; - shut_tx = 1; - } else { - sock_set_errno(sock, EINVAL); - done_socket(sock); - return -1; - } - err = netconn_shutdown(sock->conn, shut_rx, shut_tx); - - sock_set_errno(sock, err_to_errno(err)); - done_socket(sock); - return (err == ERR_OK ? 0 : -1); -} - -static int -lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen, u8_t local) -{ - struct lwip_sock *sock; - union sockaddr_aligned saddr; - ip_addr_t naddr; - u16_t port; - err_t err; - - sock = get_socket(s); - if (!sock) { - return -1; - } - - /* get the IP address and port */ - err = netconn_getaddr(sock->conn, &naddr, &port, local); - if (err != ERR_OK) { - sock_set_errno(sock, err_to_errno(err)); - done_socket(sock); - return -1; - } - -#if LWIP_IPV4 && LWIP_IPV6 - /* Dual-stack: Map IPv4 addresses to IPv4 mapped IPv6 */ - if (NETCONNTYPE_ISIPV6(netconn_type(sock->conn)) && - IP_IS_V4_VAL(naddr)) { - ip4_2_ipv4_mapped_ipv6(ip_2_ip6(&naddr), ip_2_ip4(&naddr)); - IP_SET_TYPE_VAL(naddr, IPADDR_TYPE_V6); - } -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - - IPADDR_PORT_TO_SOCKADDR(&saddr, &naddr, port); - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getaddrname(%d, addr=", s)); - ip_addr_debug_print_val(SOCKETS_DEBUG, naddr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", port)); - - if (*namelen > saddr.sa.sa_len) { - *namelen = saddr.sa.sa_len; - } - MEMCPY(name, &saddr, *namelen); - - sock_set_errno(sock, 0); - done_socket(sock); - return 0; -} - -int -lwip_getpeername(int s, struct sockaddr *name, socklen_t *namelen) -{ - return lwip_getaddrname(s, name, namelen, 0); -} - -int -lwip_getsockname(int s, struct sockaddr *name, socklen_t *namelen) -{ - return lwip_getaddrname(s, name, namelen, 1); -} - -int -lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) -{ - int err; - struct lwip_sock *sock = get_socket(s); -#if !LWIP_TCPIP_CORE_LOCKING - err_t cberr; - LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(data); -#endif /* !LWIP_TCPIP_CORE_LOCKING */ - - if (!sock) { - return -1; - } - - if ((NULL == optval) || (NULL == optlen)) { - sock_set_errno(sock, EFAULT); - done_socket(sock); - return -1; - } - -#if LWIP_TCPIP_CORE_LOCKING - /* core-locking can just call the -impl function */ - LOCK_TCPIP_CORE(); - err = lwip_getsockopt_impl(s, level, optname, optval, optlen); - UNLOCK_TCPIP_CORE(); - -#else /* LWIP_TCPIP_CORE_LOCKING */ - -#if LWIP_MPU_COMPATIBLE - /* MPU_COMPATIBLE copies the optval data, so check for max size here */ - if (*optlen > LWIP_SETGETSOCKOPT_MAXOPTLEN) { - sock_set_errno(sock, ENOBUFS); - done_socket(sock); - return -1; - } -#endif /* LWIP_MPU_COMPATIBLE */ - - LWIP_SETGETSOCKOPT_DATA_VAR_ALLOC(data, sock); - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).s = s; - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).level = level; - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optname = optname; - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optlen = *optlen; -#if !LWIP_MPU_COMPATIBLE - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optval.p = optval; -#endif /* !LWIP_MPU_COMPATIBLE */ - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).err = 0; -#if LWIP_NETCONN_SEM_PER_THREAD - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem = LWIP_NETCONN_THREAD_SEM_GET(); -#else - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem = &sock->conn->op_completed; -#endif - cberr = tcpip_callback(lwip_getsockopt_callback, &LWIP_SETGETSOCKOPT_DATA_VAR_REF(data)); - if (cberr != ERR_OK) { - LWIP_SETGETSOCKOPT_DATA_VAR_FREE(data); - sock_set_errno(sock, err_to_errno(cberr)); - done_socket(sock); - return -1; - } - sys_arch_sem_wait((sys_sem_t *)(LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem), 0); - - /* write back optlen and optval */ - *optlen = LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optlen; -#if LWIP_MPU_COMPATIBLE - MEMCPY(optval, LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optval, - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optlen); -#endif /* LWIP_MPU_COMPATIBLE */ - - /* maybe lwip_getsockopt_internal has changed err */ - err = LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).err; - LWIP_SETGETSOCKOPT_DATA_VAR_FREE(data); -#endif /* LWIP_TCPIP_CORE_LOCKING */ - - sock_set_errno(sock, err); - done_socket(sock); - return err ? -1 : 0; -} - -#if !LWIP_TCPIP_CORE_LOCKING -/** lwip_getsockopt_callback: only used without CORE_LOCKING - * to get into the tcpip_thread - */ -static void -lwip_getsockopt_callback(void *arg) -{ - struct lwip_setgetsockopt_data *data; - LWIP_ASSERT("arg != NULL", arg != NULL); - data = (struct lwip_setgetsockopt_data *)arg; - - data->err = lwip_getsockopt_impl(data->s, data->level, data->optname, -#if LWIP_MPU_COMPATIBLE - data->optval, -#else /* LWIP_MPU_COMPATIBLE */ - data->optval.p, -#endif /* LWIP_MPU_COMPATIBLE */ - &data->optlen); - - sys_sem_signal((sys_sem_t *)(data->completed_sem)); -} -#endif /* LWIP_TCPIP_CORE_LOCKING */ - -static int -lwip_sockopt_to_ipopt(int optname) -{ - /* Map SO_* values to our internal SOF_* values - * We should not rely on #defines in socket.h - * being in sync with ip.h. - */ - switch (optname) { - case SO_BROADCAST: - return SOF_BROADCAST; - case SO_KEEPALIVE: - return SOF_KEEPALIVE; - case SO_REUSEADDR: - return SOF_REUSEADDR; - default: - LWIP_ASSERT("Unknown socket option", 0); - return 0; - } -} - -/** lwip_getsockopt_impl: the actual implementation of getsockopt: - * same argument as lwip_getsockopt, either called directly or through callback - */ -static int -lwip_getsockopt_impl(int s, int level, int optname, void *optval, socklen_t *optlen) -{ - int err = 0; - struct lwip_sock *sock = tryget_socket(s); - if (!sock) { - return EBADF; - } - -#ifdef LWIP_HOOK_SOCKETS_GETSOCKOPT - if (LWIP_HOOK_SOCKETS_GETSOCKOPT(s, sock, level, optname, optval, optlen, &err)) { - return err; - } -#endif - - switch (level) { - - /* Level: SOL_SOCKET */ - case SOL_SOCKET: - switch (optname) { - -#if LWIP_TCP - case SO_ACCEPTCONN: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, int); - if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_TCP) { - done_socket(sock); - return ENOPROTOOPT; - } - if ((sock->conn->pcb.tcp != NULL) && (sock->conn->pcb.tcp->state == LISTEN)) { - *(int *)optval = 1; - } else { - *(int *)optval = 0; - } - break; -#endif /* LWIP_TCP */ - - /* The option flags */ - case SO_BROADCAST: - case SO_KEEPALIVE: -#if SO_REUSE - case SO_REUSEADDR: -#endif /* SO_REUSE */ - if ((optname == SO_BROADCAST) && - (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP)) { - done_socket(sock); - return ENOPROTOOPT; - } - - optname = lwip_sockopt_to_ipopt(optname); - - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, int); - *(int *)optval = ip_get_option(sock->conn->pcb.ip, optname); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, optname=0x%x, ..) = %s\n", - s, optname, (*(int *)optval ? "on" : "off"))); - break; - - case SO_TYPE: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, int); - switch (NETCONNTYPE_GROUP(netconn_type(sock->conn))) { - case NETCONN_RAW: - *(int *)optval = SOCK_RAW; - break; - case NETCONN_TCP: - *(int *)optval = SOCK_STREAM; - break; - case NETCONN_UDP: - *(int *)optval = SOCK_DGRAM; - break; - default: /* unrecognized socket type */ - *(int *)optval = netconn_type(sock->conn); - LWIP_DEBUGF(SOCKETS_DEBUG, - ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE): unrecognized socket type %d\n", - s, *(int *)optval)); - } /* switch (netconn_type(sock->conn)) */ - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE) = %d\n", - s, *(int *)optval)); - break; - - case SO_ERROR: - LWIP_SOCKOPT_CHECK_OPTLEN(sock, *optlen, int); - *(int *)optval = err_to_errno(netconn_err(sock->conn)); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_ERROR) = %d\n", - s, *(int *)optval)); - break; - -#if LWIP_SO_SNDTIMEO - case SO_SNDTIMEO: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, LWIP_SO_SNDRCVTIMEO_OPTTYPE); - LWIP_SO_SNDRCVTIMEO_SET(optval, netconn_get_sendtimeout(sock->conn)); - break; -#endif /* LWIP_SO_SNDTIMEO */ -#if LWIP_SO_RCVTIMEO - case SO_RCVTIMEO: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, LWIP_SO_SNDRCVTIMEO_OPTTYPE); - LWIP_SO_SNDRCVTIMEO_SET(optval, netconn_get_recvtimeout(sock->conn)); - break; -#endif /* LWIP_SO_RCVTIMEO */ -#if LWIP_SO_RCVBUF - case SO_RCVBUF: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, int); - *(int *)optval = netconn_get_recvbufsize(sock->conn); - break; -#endif /* LWIP_SO_RCVBUF */ -#if LWIP_SO_LINGER - case SO_LINGER: { - s16_t conn_linger; - struct linger *linger = (struct linger *)optval; - LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, struct linger); - conn_linger = sock->conn->linger; - if (conn_linger >= 0) { - linger->l_onoff = 1; - linger->l_linger = (int)conn_linger; - } else { - linger->l_onoff = 0; - linger->l_linger = 0; - } - } - break; -#endif /* LWIP_SO_LINGER */ -#if LWIP_UDP - case SO_NO_CHECK: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, *optlen, int, NETCONN_UDP); -#if LWIP_UDPLITE - if (udp_is_flag_set(sock->conn->pcb.udp, UDP_FLAGS_UDPLITE)) { - /* this flag is only available for UDP, not for UDP lite */ - done_socket(sock); - return EAFNOSUPPORT; - } -#endif /* LWIP_UDPLITE */ - *(int *)optval = udp_is_flag_set(sock->conn->pcb.udp, UDP_FLAGS_NOCHKSUM) ? 1 : 0; - break; -#endif /* LWIP_UDP*/ - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - break; - } /* switch (optname) */ - break; - - /* Level: IPPROTO_IP */ - case IPPROTO_IP: - switch (optname) { - case IP_TTL: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, int); - *(int *)optval = sock->conn->pcb.ip->ttl; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TTL) = %d\n", - s, *(int *)optval)); - break; - case IP_TOS: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, int); - *(int *)optval = sock->conn->pcb.ip->tos; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TOS) = %d\n", - s, *(int *)optval)); - break; -#if LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS && LWIP_UDP - case IP_MULTICAST_TTL: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, u8_t); - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) { - done_socket(sock); - return ENOPROTOOPT; - } - *(u8_t *)optval = udp_get_multicast_ttl(sock->conn->pcb.udp); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_TTL) = %d\n", - s, *(int *)optval)); - break; - case IP_MULTICAST_IF: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, struct in_addr); - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) { - done_socket(sock); - return ENOPROTOOPT; - } - inet_addr_from_ip4addr((struct in_addr *)optval, udp_get_multicast_netif_addr(sock->conn->pcb.udp)); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_IF) = 0x%"X32_F"\n", - s, *(u32_t *)optval)); - break; - case IP_MULTICAST_LOOP: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, u8_t); - if ((sock->conn->pcb.udp->flags & UDP_FLAGS_MULTICAST_LOOP) != 0) { - *(u8_t *)optval = 1; - } else { - *(u8_t *)optval = 0; - } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_LOOP) = %d\n", - s, *(int *)optval)); - break; -#endif /* LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS && LWIP_UDP */ - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - break; - } /* switch (optname) */ - break; - -#if LWIP_TCP - /* Level: IPPROTO_TCP */ - case IPPROTO_TCP: - /* Special case: all IPPROTO_TCP option take an int */ - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, *optlen, int, NETCONN_TCP); - if (sock->conn->pcb.tcp->state == LISTEN) { - done_socket(sock); - return EINVAL; - } - switch (optname) { - case TCP_NODELAY: - *(int *)optval = tcp_nagle_disabled(sock->conn->pcb.tcp); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_NODELAY) = %s\n", - s, (*(int *)optval) ? "on" : "off") ); - break; - case TCP_KEEPALIVE: - *(int *)optval = (int)sock->conn->pcb.tcp->keep_idle; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_KEEPALIVE) = %d\n", - s, *(int *)optval)); - break; - -#if LWIP_TCP_KEEPALIVE - case TCP_KEEPIDLE: - *(int *)optval = (int)(sock->conn->pcb.tcp->keep_idle / 1000); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_KEEPIDLE) = %d\n", - s, *(int *)optval)); - break; - case TCP_KEEPINTVL: - *(int *)optval = (int)(sock->conn->pcb.tcp->keep_intvl / 1000); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_KEEPINTVL) = %d\n", - s, *(int *)optval)); - break; - case TCP_KEEPCNT: - *(int *)optval = (int)sock->conn->pcb.tcp->keep_cnt; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_KEEPCNT) = %d\n", - s, *(int *)optval)); - break; -#endif /* LWIP_TCP_KEEPALIVE */ - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - break; - } /* switch (optname) */ - break; -#endif /* LWIP_TCP */ - -#if LWIP_IPV6 - /* Level: IPPROTO_IPV6 */ - case IPPROTO_IPV6: - switch (optname) { - case IPV6_V6ONLY: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, int); - *(int *)optval = (netconn_get_ipv6only(sock->conn) ? 1 : 0); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IPV6, IPV6_V6ONLY) = %d\n", - s, *(int *)optval)); - break; - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IPV6, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - break; - } /* switch (optname) */ - break; -#endif /* LWIP_IPV6 */ - -#if LWIP_UDP && LWIP_UDPLITE - /* Level: IPPROTO_UDPLITE */ - case IPPROTO_UDPLITE: - /* Special case: all IPPROTO_UDPLITE option take an int */ - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, int); - /* If this is no UDP lite socket, ignore any options. */ - if (!NETCONNTYPE_ISUDPLITE(netconn_type(sock->conn))) { - done_socket(sock); - return ENOPROTOOPT; - } - switch (optname) { - case UDPLITE_SEND_CSCOV: - *(int *)optval = sock->conn->pcb.udp->chksum_len_tx; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV) = %d\n", - s, (*(int *)optval)) ); - break; - case UDPLITE_RECV_CSCOV: - *(int *)optval = sock->conn->pcb.udp->chksum_len_rx; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV) = %d\n", - s, (*(int *)optval)) ); - break; - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - break; - } /* switch (optname) */ - break; -#endif /* LWIP_UDP */ - /* Level: IPPROTO_RAW */ - case IPPROTO_RAW: - switch (optname) { -#if LWIP_IPV6 && LWIP_RAW - case IPV6_CHECKSUM: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, *optlen, int, NETCONN_RAW); - if (sock->conn->pcb.raw->chksum_reqd == 0) { - *(int *)optval = -1; - } else { - *(int *)optval = sock->conn->pcb.raw->chksum_offset; - } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_RAW, IPV6_CHECKSUM) = %d\n", - s, (*(int *)optval)) ); - break; -#endif /* LWIP_IPV6 && LWIP_RAW */ - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_RAW, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - break; - } /* switch (optname) */ - break; - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", - s, level, optname)); - err = ENOPROTOOPT; - break; - } /* switch (level) */ - - done_socket(sock); - return err; -} - -int -lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen) -{ - int err = 0; - struct lwip_sock *sock = get_socket(s); -#if !LWIP_TCPIP_CORE_LOCKING - err_t cberr; - LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(data); -#endif /* !LWIP_TCPIP_CORE_LOCKING */ - - if (!sock) { - return -1; - } - - if (NULL == optval) { - sock_set_errno(sock, EFAULT); - done_socket(sock); - return -1; - } - -#if LWIP_TCPIP_CORE_LOCKING - /* core-locking can just call the -impl function */ - LOCK_TCPIP_CORE(); - err = lwip_setsockopt_impl(s, level, optname, optval, optlen); - UNLOCK_TCPIP_CORE(); - -#else /* LWIP_TCPIP_CORE_LOCKING */ - -#if LWIP_MPU_COMPATIBLE - /* MPU_COMPATIBLE copies the optval data, so check for max size here */ - if (optlen > LWIP_SETGETSOCKOPT_MAXOPTLEN) { - sock_set_errno(sock, ENOBUFS); - done_socket(sock); - return -1; - } -#endif /* LWIP_MPU_COMPATIBLE */ - - LWIP_SETGETSOCKOPT_DATA_VAR_ALLOC(data, sock); - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).s = s; - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).level = level; - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optname = optname; - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optlen = optlen; -#if LWIP_MPU_COMPATIBLE - MEMCPY(LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optval, optval, optlen); -#else /* LWIP_MPU_COMPATIBLE */ - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optval.pc = (const void *)optval; -#endif /* LWIP_MPU_COMPATIBLE */ - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).err = 0; -#if LWIP_NETCONN_SEM_PER_THREAD - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem = LWIP_NETCONN_THREAD_SEM_GET(); -#else - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem = &sock->conn->op_completed; -#endif - cberr = tcpip_callback(lwip_setsockopt_callback, &LWIP_SETGETSOCKOPT_DATA_VAR_REF(data)); - if (cberr != ERR_OK) { - LWIP_SETGETSOCKOPT_DATA_VAR_FREE(data); - sock_set_errno(sock, err_to_errno(cberr)); - done_socket(sock); - return -1; - } - sys_arch_sem_wait((sys_sem_t *)(LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem), 0); - - /* maybe lwip_getsockopt_internal has changed err */ - err = LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).err; - LWIP_SETGETSOCKOPT_DATA_VAR_FREE(data); -#endif /* LWIP_TCPIP_CORE_LOCKING */ - - sock_set_errno(sock, err); - done_socket(sock); - return err ? -1 : 0; -} - -#if !LWIP_TCPIP_CORE_LOCKING -/** lwip_setsockopt_callback: only used without CORE_LOCKING - * to get into the tcpip_thread - */ -static void -lwip_setsockopt_callback(void *arg) -{ - struct lwip_setgetsockopt_data *data; - LWIP_ASSERT("arg != NULL", arg != NULL); - data = (struct lwip_setgetsockopt_data *)arg; - - data->err = lwip_setsockopt_impl(data->s, data->level, data->optname, -#if LWIP_MPU_COMPATIBLE - data->optval, -#else /* LWIP_MPU_COMPATIBLE */ - data->optval.pc, -#endif /* LWIP_MPU_COMPATIBLE */ - data->optlen); - - sys_sem_signal((sys_sem_t *)(data->completed_sem)); -} -#endif /* LWIP_TCPIP_CORE_LOCKING */ - -/** lwip_setsockopt_impl: the actual implementation of setsockopt: - * same argument as lwip_setsockopt, either called directly or through callback - */ -static int -lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_t optlen) -{ - int err = 0; - struct lwip_sock *sock = tryget_socket(s); - if (!sock) { - return EBADF; - } - -#ifdef LWIP_HOOK_SOCKETS_SETSOCKOPT - if (LWIP_HOOK_SOCKETS_SETSOCKOPT(s, sock, level, optname, optval, optlen, &err)) { - return err; - } -#endif - - switch (level) { - - /* Level: SOL_SOCKET */ - case SOL_SOCKET: - switch (optname) { - - /* SO_ACCEPTCONN is get-only */ - - /* The option flags */ - case SO_BROADCAST: - case SO_KEEPALIVE: -#if SO_REUSE - case SO_REUSEADDR: -#endif /* SO_REUSE */ - if ((optname == SO_BROADCAST) && - (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP)) { - done_socket(sock); - return ENOPROTOOPT; - } - - optname = lwip_sockopt_to_ipopt(optname); - - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, int); - if (*(const int *)optval) { - ip_set_option(sock->conn->pcb.ip, optname); - } else { - ip_reset_option(sock->conn->pcb.ip, optname); - } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, optname=0x%x, ..) -> %s\n", - s, optname, (*(const int *)optval ? "on" : "off"))); - break; - - /* SO_TYPE is get-only */ - /* SO_ERROR is get-only */ - -#if LWIP_SO_SNDTIMEO - case SO_SNDTIMEO: { - long ms_long; - LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, LWIP_SO_SNDRCVTIMEO_OPTTYPE); - ms_long = LWIP_SO_SNDRCVTIMEO_GET_MS(optval); - if (ms_long < 0) { - done_socket(sock); - return EINVAL; - } - netconn_set_sendtimeout(sock->conn, ms_long); - break; - } -#endif /* LWIP_SO_SNDTIMEO */ -#if LWIP_SO_RCVTIMEO - case SO_RCVTIMEO: { - long ms_long; - LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, LWIP_SO_SNDRCVTIMEO_OPTTYPE); - ms_long = LWIP_SO_SNDRCVTIMEO_GET_MS(optval); - if (ms_long < 0) { - done_socket(sock); - return EINVAL; - } - netconn_set_recvtimeout(sock->conn, (u32_t)ms_long); - break; - } -#endif /* LWIP_SO_RCVTIMEO */ -#if LWIP_SO_RCVBUF - case SO_RCVBUF: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, int); - netconn_set_recvbufsize(sock->conn, *(const int *)optval); - break; -#endif /* LWIP_SO_RCVBUF */ -#if LWIP_SO_LINGER - case SO_LINGER: { - const struct linger *linger = (const struct linger *)optval; - LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, struct linger); - if (linger->l_onoff) { - int lingersec = linger->l_linger; - if (lingersec < 0) { - done_socket(sock); - return EINVAL; - } - if (lingersec > 0xFFFF) { - lingersec = 0xFFFF; - } - sock->conn->linger = (s16_t)lingersec; - } else { - sock->conn->linger = -1; - } - } - break; -#endif /* LWIP_SO_LINGER */ -#if LWIP_UDP - case SO_NO_CHECK: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_UDP); -#if LWIP_UDPLITE - if (udp_is_flag_set(sock->conn->pcb.udp, UDP_FLAGS_UDPLITE)) { - /* this flag is only available for UDP, not for UDP lite */ - done_socket(sock); - return EAFNOSUPPORT; - } -#endif /* LWIP_UDPLITE */ - if (*(const int *)optval) { - udp_set_flags(sock->conn->pcb.udp, UDP_FLAGS_NOCHKSUM); - } else { - udp_clear_flags(sock->conn->pcb.udp, UDP_FLAGS_NOCHKSUM); - } - break; -#endif /* LWIP_UDP */ - case SO_BINDTODEVICE: { - const struct ifreq *iface; - struct netif *n = NULL; - - LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, struct ifreq); - - iface = (const struct ifreq *)optval; - if (iface->ifr_name[0] != 0) { - n = netif_find(iface->ifr_name); - if (n == NULL) { - done_socket(sock); - return ENODEV; - } - } - - switch (NETCONNTYPE_GROUP(netconn_type(sock->conn))) { -#if LWIP_TCP - case NETCONN_TCP: - tcp_bind_netif(sock->conn->pcb.tcp, n); - break; -#endif -#if LWIP_UDP - case NETCONN_UDP: - udp_bind_netif(sock->conn->pcb.udp, n); - break; -#endif -#if LWIP_RAW - case NETCONN_RAW: - raw_bind_netif(sock->conn->pcb.raw, n); - break; -#endif - default: - LWIP_ASSERT("Unhandled netconn type in SO_BINDTODEVICE", 0); - break; - } - } - break; - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - break; - } /* switch (optname) */ - break; - - /* Level: IPPROTO_IP */ - case IPPROTO_IP: - switch (optname) { - case IP_TTL: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, int); - sock->conn->pcb.ip->ttl = (u8_t)(*(const int *)optval); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TTL, ..) -> %d\n", - s, sock->conn->pcb.ip->ttl)); - break; - case IP_TOS: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, int); - sock->conn->pcb.ip->tos = (u8_t)(*(const int *)optval); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TOS, ..)-> %d\n", - s, sock->conn->pcb.ip->tos)); - break; -#if LWIP_NETBUF_RECVINFO - case IP_PKTINFO: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_UDP); - if (*(const int *)optval) { - sock->conn->flags |= NETCONN_FLAG_PKTINFO; - } else { - sock->conn->flags &= ~NETCONN_FLAG_PKTINFO; - } - break; -#endif /* LWIP_NETBUF_RECVINFO */ -#if LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS && LWIP_UDP - case IP_MULTICAST_TTL: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, u8_t, NETCONN_UDP); - udp_set_multicast_ttl(sock->conn->pcb.udp, (u8_t)(*(const u8_t *)optval)); - break; - case IP_MULTICAST_IF: { - ip4_addr_t if_addr; - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, struct in_addr, NETCONN_UDP); - inet_addr_to_ip4addr(&if_addr, (const struct in_addr *)optval); - udp_set_multicast_netif_addr(sock->conn->pcb.udp, &if_addr); - } - break; - case IP_MULTICAST_LOOP: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, u8_t, NETCONN_UDP); - if (*(const u8_t *)optval) { - udp_set_flags(sock->conn->pcb.udp, UDP_FLAGS_MULTICAST_LOOP); - } else { - udp_clear_flags(sock->conn->pcb.udp, UDP_FLAGS_MULTICAST_LOOP); - } - break; -#endif /* LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS && LWIP_UDP */ -#if LWIP_IGMP - case IP_ADD_MEMBERSHIP: - case IP_DROP_MEMBERSHIP: { - /* If this is a TCP or a RAW socket, ignore these options. */ - err_t igmp_err; - const struct ip_mreq *imr = (const struct ip_mreq *)optval; - ip4_addr_t if_addr; - ip4_addr_t multi_addr; - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, struct ip_mreq, NETCONN_UDP); - inet_addr_to_ip4addr(&if_addr, &imr->imr_interface); - inet_addr_to_ip4addr(&multi_addr, &imr->imr_multiaddr); - if (optname == IP_ADD_MEMBERSHIP) { - if (!lwip_socket_register_membership(s, &if_addr, &multi_addr)) { - /* cannot track membership (out of memory) */ - err = ENOMEM; - igmp_err = ERR_OK; - } else { - igmp_err = igmp_joingroup(&if_addr, &multi_addr); - } - } else { - igmp_err = igmp_leavegroup(&if_addr, &multi_addr); - lwip_socket_unregister_membership(s, &if_addr, &multi_addr); - } - if (igmp_err != ERR_OK) { - err = EADDRNOTAVAIL; - } - } - break; -#endif /* LWIP_IGMP */ - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - break; - } /* switch (optname) */ - break; - -#if LWIP_TCP - /* Level: IPPROTO_TCP */ - case IPPROTO_TCP: - /* Special case: all IPPROTO_TCP option take an int */ - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_TCP); - if (sock->conn->pcb.tcp->state == LISTEN) { - done_socket(sock); - return EINVAL; - } - switch (optname) { - case TCP_NODELAY: - if (*(const int *)optval) { - tcp_nagle_disable(sock->conn->pcb.tcp); - } else { - tcp_nagle_enable(sock->conn->pcb.tcp); - } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_NODELAY) -> %s\n", - s, (*(const int *)optval) ? "on" : "off") ); - break; - case TCP_KEEPALIVE: - sock->conn->pcb.tcp->keep_idle = (u32_t)(*(const int *)optval); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPALIVE) -> %"U32_F"\n", - s, sock->conn->pcb.tcp->keep_idle)); - break; - -#if LWIP_TCP_KEEPALIVE - case TCP_KEEPIDLE: - sock->conn->pcb.tcp->keep_idle = 1000 * (u32_t)(*(const int *)optval); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPIDLE) -> %"U32_F"\n", - s, sock->conn->pcb.tcp->keep_idle)); - break; - case TCP_KEEPINTVL: - sock->conn->pcb.tcp->keep_intvl = 1000 * (u32_t)(*(const int *)optval); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPINTVL) -> %"U32_F"\n", - s, sock->conn->pcb.tcp->keep_intvl)); - break; - case TCP_KEEPCNT: - sock->conn->pcb.tcp->keep_cnt = (u32_t)(*(const int *)optval); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPCNT) -> %"U32_F"\n", - s, sock->conn->pcb.tcp->keep_cnt)); - break; -#endif /* LWIP_TCP_KEEPALIVE */ - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - break; - } /* switch (optname) */ - break; -#endif /* LWIP_TCP*/ - -#if LWIP_IPV6 - /* Level: IPPROTO_IPV6 */ - case IPPROTO_IPV6: - switch (optname) { - case IPV6_V6ONLY: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, int); - if (*(const int *)optval) { - netconn_set_ipv6only(sock->conn, 1); - } else { - netconn_set_ipv6only(sock->conn, 0); - } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IPV6, IPV6_V6ONLY, ..) -> %d\n", - s, (netconn_get_ipv6only(sock->conn) ? 1 : 0))); - break; -#if LWIP_IPV6_MLD - case IPV6_JOIN_GROUP: - case IPV6_LEAVE_GROUP: { - /* If this is a TCP or a RAW socket, ignore these options. */ - err_t mld6_err; - struct netif *netif; - ip6_addr_t multi_addr; - const struct ipv6_mreq *imr = (const struct ipv6_mreq *)optval; - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, struct ipv6_mreq, NETCONN_UDP); - inet6_addr_to_ip6addr(&multi_addr, &imr->ipv6mr_multiaddr); - LWIP_ASSERT("Invalid netif index", imr->ipv6mr_interface <= 0xFFu); - netif = netif_get_by_index((u8_t)imr->ipv6mr_interface); - if (netif == NULL) { - err = EADDRNOTAVAIL; - break; - } - - if (optname == IPV6_JOIN_GROUP) { - if (!lwip_socket_register_mld6_membership(s, imr->ipv6mr_interface, &multi_addr)) { - /* cannot track membership (out of memory) */ - err = ENOMEM; - mld6_err = ERR_OK; - } else { - mld6_err = mld6_joingroup_netif(netif, &multi_addr); - } - } else { - mld6_err = mld6_leavegroup_netif(netif, &multi_addr); - lwip_socket_unregister_mld6_membership(s, imr->ipv6mr_interface, &multi_addr); - } - if (mld6_err != ERR_OK) { - err = EADDRNOTAVAIL; - } - } - break; -#endif /* LWIP_IPV6_MLD */ - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IPV6, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - break; - } /* switch (optname) */ - break; -#endif /* LWIP_IPV6 */ - -#if LWIP_UDP && LWIP_UDPLITE - /* Level: IPPROTO_UDPLITE */ - case IPPROTO_UDPLITE: - /* Special case: all IPPROTO_UDPLITE option take an int */ - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, int); - /* If this is no UDP lite socket, ignore any options. */ - if (!NETCONNTYPE_ISUDPLITE(netconn_type(sock->conn))) { - done_socket(sock); - return ENOPROTOOPT; - } - switch (optname) { - case UDPLITE_SEND_CSCOV: - if ((*(const int *)optval != 0) && ((*(const int *)optval < 8) || (*(const int *)optval > 0xffff))) { - /* don't allow illegal values! */ - sock->conn->pcb.udp->chksum_len_tx = 8; - } else { - sock->conn->pcb.udp->chksum_len_tx = (u16_t) * (const int *)optval; - } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV) -> %d\n", - s, (*(const int *)optval)) ); - break; - case UDPLITE_RECV_CSCOV: - if ((*(const int *)optval != 0) && ((*(const int *)optval < 8) || (*(const int *)optval > 0xffff))) { - /* don't allow illegal values! */ - sock->conn->pcb.udp->chksum_len_rx = 8; - } else { - sock->conn->pcb.udp->chksum_len_rx = (u16_t) * (const int *)optval; - } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV) -> %d\n", - s, (*(const int *)optval)) ); - break; - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - break; - } /* switch (optname) */ - break; -#endif /* LWIP_UDP */ - /* Level: IPPROTO_RAW */ - case IPPROTO_RAW: - switch (optname) { -#if LWIP_IPV6 && LWIP_RAW - case IPV6_CHECKSUM: - /* It should not be possible to disable the checksum generation with ICMPv6 - * as per RFC 3542 chapter 3.1 */ - if (sock->conn->pcb.raw->protocol == IPPROTO_ICMPV6) { - done_socket(sock); - return EINVAL; - } - - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_RAW); - if (*(const int *)optval < 0) { - sock->conn->pcb.raw->chksum_reqd = 0; - } else if (*(const int *)optval & 1) { - /* Per RFC3542, odd offsets are not allowed */ - done_socket(sock); - return EINVAL; - } else { - sock->conn->pcb.raw->chksum_reqd = 1; - sock->conn->pcb.raw->chksum_offset = (u16_t) * (const int *)optval; - } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_RAW, IPV6_CHECKSUM, ..) -> %d\n", - s, sock->conn->pcb.raw->chksum_reqd)); - break; -#endif /* LWIP_IPV6 && LWIP_RAW */ - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_RAW, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - break; - } /* switch (optname) */ - break; - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", - s, level, optname)); - err = ENOPROTOOPT; - break; - } /* switch (level) */ - - done_socket(sock); - return err; -} - -int -lwip_ioctl(int s, long cmd, void *argp) -{ - struct lwip_sock *sock = get_socket(s); - u8_t val; -#if LWIP_SO_RCVBUF - int recv_avail; -#endif /* LWIP_SO_RCVBUF */ - - if (!sock) { - return -1; - } - - switch (cmd) { -#if LWIP_SO_RCVBUF || LWIP_FIONREAD_LINUXMODE - case FIONREAD: - if (!argp) { - sock_set_errno(sock, EINVAL); - done_socket(sock); - return -1; - } -#if LWIP_FIONREAD_LINUXMODE - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { - struct netbuf *nb; - if (sock->lastdata.netbuf) { - nb = sock->lastdata.netbuf; - *((int *)argp) = nb->p->tot_len; - } else { - struct netbuf *rxbuf; - err_t err = netconn_recv_udp_raw_netbuf_flags(sock->conn, &rxbuf, NETCONN_DONTBLOCK); - if (err != ERR_OK) { - *((int *)argp) = 0; - } else { - sock->lastdata.netbuf = rxbuf; - *((int *)argp) = rxbuf->p->tot_len; - } - } - done_socket(sock); - return 0; - } -#endif /* LWIP_FIONREAD_LINUXMODE */ - -#if LWIP_SO_RCVBUF - /* we come here if either LWIP_FIONREAD_LINUXMODE==0 or this is a TCP socket */ - SYS_ARCH_GET(sock->conn->recv_avail, recv_avail); - if (recv_avail < 0) { - recv_avail = 0; - } - - /* Check if there is data left from the last recv operation. /maq 041215 */ - if (sock->lastdata.netbuf) { - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { - recv_avail += sock->lastdata.pbuf->tot_len; - } else { - recv_avail += sock->lastdata.netbuf->p->tot_len; - } - } - *((int *)argp) = recv_avail; - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONREAD, %p) = %"U16_F"\n", s, argp, *((u16_t *)argp))); - sock_set_errno(sock, 0); - done_socket(sock); - return 0; -#else /* LWIP_SO_RCVBUF */ - break; -#endif /* LWIP_SO_RCVBUF */ -#endif /* LWIP_SO_RCVBUF || LWIP_FIONREAD_LINUXMODE */ - - case (long)FIONBIO: - val = 0; - if (argp && *(int *)argp) { - val = 1; - } - netconn_set_nonblocking(sock->conn, val); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONBIO, %d)\n", s, val)); - sock_set_errno(sock, 0); - done_socket(sock); - return 0; - - default: - break; - } /* switch (cmd) */ - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, UNIMPL: 0x%lx, %p)\n", s, cmd, argp)); - sock_set_errno(sock, ENOSYS); /* not yet implemented */ - done_socket(sock); - return -1; -} - -/** A minimal implementation of fcntl. - * Currently only the commands F_GETFL and F_SETFL are implemented. - * The flag O_NONBLOCK and access modes are supported for F_GETFL, only - * the flag O_NONBLOCK is implemented for F_SETFL. - */ -int -lwip_fcntl(int s, int cmd, int val) -{ - struct lwip_sock *sock = get_socket(s); - int ret = -1; - int op_mode = 0; - - if (!sock) { - return -1; - } - - switch (cmd) { - case F_GETFL: - ret = netconn_is_nonblocking(sock->conn) ? O_NONBLOCK : 0; - sock_set_errno(sock, 0); - - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { -#if LWIP_TCPIP_CORE_LOCKING - LOCK_TCPIP_CORE(); -#else - SYS_ARCH_DECL_PROTECT(lev); - /* the proper thing to do here would be to get into the tcpip_thread, - but locking should be OK as well since we only *read* some flags */ - SYS_ARCH_PROTECT(lev); -#endif -#if LWIP_TCP - if (sock->conn->pcb.tcp) { - if (!(sock->conn->pcb.tcp->flags & TF_RXCLOSED)) { - op_mode |= O_RDONLY; - } - if (!(sock->conn->pcb.tcp->flags & TF_FIN)) { - op_mode |= O_WRONLY; - } - } -#endif -#if LWIP_TCPIP_CORE_LOCKING - UNLOCK_TCPIP_CORE(); -#else - SYS_ARCH_UNPROTECT(lev); -#endif - } else { - op_mode |= O_RDWR; - } - - /* ensure O_RDWR for (O_RDONLY|O_WRONLY) != O_RDWR cases */ - ret |= (op_mode == (O_RDONLY | O_WRONLY)) ? O_RDWR : op_mode; - - break; - case F_SETFL: - /* Bits corresponding to the file access mode and the file creation flags [..] that are set in arg shall be ignored */ - val &= ~(O_RDONLY | O_WRONLY | O_RDWR); - if ((val & ~O_NONBLOCK) == 0) { - /* only O_NONBLOCK, all other bits are zero */ - netconn_set_nonblocking(sock->conn, val & O_NONBLOCK); - ret = 0; - sock_set_errno(sock, 0); - } else { - sock_set_errno(sock, ENOSYS); /* not yet implemented */ - } - break; - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_fcntl(%d, UNIMPL: %d, %d)\n", s, cmd, val)); - sock_set_errno(sock, ENOSYS); /* not yet implemented */ - break; - } - done_socket(sock); - return ret; -} - -#if LWIP_COMPAT_SOCKETS == 2 && LWIP_POSIX_SOCKETS_IO_NAMES -int -fcntl(int s, int cmd, ...) -{ - va_list ap; - int val; - - va_start(ap, cmd); - val = va_arg(ap, int); - va_end(ap); - return lwip_fcntl(s, cmd, val); -} -#endif - -const char * -lwip_inet_ntop(int af, const void *src, char *dst, socklen_t size) -{ - const char *ret = NULL; - int size_int = (int)size; - if (size_int < 0) { - set_errno(ENOSPC); - return NULL; - } - switch (af) { -#if LWIP_IPV4 - case AF_INET: - ret = ip4addr_ntoa_r((const ip4_addr_t *)src, dst, size_int); - if (ret == NULL) { - set_errno(ENOSPC); - } - break; -#endif -#if LWIP_IPV6 - case AF_INET6: - ret = ip6addr_ntoa_r((const ip6_addr_t *)src, dst, size_int); - if (ret == NULL) { - set_errno(ENOSPC); - } - break; -#endif - default: - set_errno(EAFNOSUPPORT); - break; - } - return ret; -} - -int -lwip_inet_pton(int af, const char *src, void *dst) -{ - int err; - switch (af) { -#if LWIP_IPV4 - case AF_INET: - err = ip4addr_aton(src, (ip4_addr_t *)dst); - break; -#endif -#if LWIP_IPV6 - case AF_INET6: { - /* convert into temporary variable since ip6_addr_t might be larger - than in6_addr when scopes are enabled */ - ip6_addr_t addr; - err = ip6addr_aton(src, &addr); - if (err) { - memcpy(dst, &addr.addr, sizeof(addr.addr)); - } - break; - } -#endif - default: - err = -1; - set_errno(EAFNOSUPPORT); - break; - } - return err; -} - -#if LWIP_IGMP -/** Register a new IGMP membership. On socket close, the membership is dropped automatically. - * - * ATTENTION: this function is called from tcpip_thread (or under CORE_LOCK). - * - * @return 1 on success, 0 on failure - */ -static int -lwip_socket_register_membership(int s, const ip4_addr_t *if_addr, const ip4_addr_t *multi_addr) -{ - struct lwip_sock *sock = get_socket(s); - int i; - - if (!sock) { - return 0; - } - - for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) { - if (socket_ipv4_multicast_memberships[i].sock == NULL) { - socket_ipv4_multicast_memberships[i].sock = sock; - ip4_addr_copy(socket_ipv4_multicast_memberships[i].if_addr, *if_addr); - ip4_addr_copy(socket_ipv4_multicast_memberships[i].multi_addr, *multi_addr); - done_socket(sock); - return 1; - } - } - done_socket(sock); - return 0; -} - -/** Unregister a previously registered membership. This prevents dropping the membership - * on socket close. - * - * ATTENTION: this function is called from tcpip_thread (or under CORE_LOCK). - */ -static void -lwip_socket_unregister_membership(int s, const ip4_addr_t *if_addr, const ip4_addr_t *multi_addr) -{ - struct lwip_sock *sock = get_socket(s); - int i; - - if (!sock) { - return; - } - - for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) { - if ((socket_ipv4_multicast_memberships[i].sock == sock) && - ip4_addr_cmp(&socket_ipv4_multicast_memberships[i].if_addr, if_addr) && - ip4_addr_cmp(&socket_ipv4_multicast_memberships[i].multi_addr, multi_addr)) { - socket_ipv4_multicast_memberships[i].sock = NULL; - ip4_addr_set_zero(&socket_ipv4_multicast_memberships[i].if_addr); - ip4_addr_set_zero(&socket_ipv4_multicast_memberships[i].multi_addr); - break; - } - } - done_socket(sock); -} - -/** Drop all memberships of a socket that were not dropped explicitly via setsockopt. - * - * ATTENTION: this function is NOT called from tcpip_thread (or under CORE_LOCK). - */ -static void -lwip_socket_drop_registered_memberships(int s) -{ - struct lwip_sock *sock = get_socket(s); - int i; - - if (!sock) { - return; - } - - for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) { - if (socket_ipv4_multicast_memberships[i].sock == sock) { - ip_addr_t multi_addr, if_addr; - ip_addr_copy_from_ip4(multi_addr, socket_ipv4_multicast_memberships[i].multi_addr); - ip_addr_copy_from_ip4(if_addr, socket_ipv4_multicast_memberships[i].if_addr); - socket_ipv4_multicast_memberships[i].sock = NULL; - ip4_addr_set_zero(&socket_ipv4_multicast_memberships[i].if_addr); - ip4_addr_set_zero(&socket_ipv4_multicast_memberships[i].multi_addr); - - netconn_join_leave_group(sock->conn, &multi_addr, &if_addr, NETCONN_LEAVE); - } - } - done_socket(sock); -} -#endif /* LWIP_IGMP */ - -#if LWIP_IPV6_MLD -/** Register a new MLD6 membership. On socket close, the membership is dropped automatically. - * - * ATTENTION: this function is called from tcpip_thread (or under CORE_LOCK). - * - * @return 1 on success, 0 on failure - */ -static int -lwip_socket_register_mld6_membership(int s, unsigned int if_idx, const ip6_addr_t *multi_addr) -{ - struct lwip_sock *sock = get_socket(s); - int i; - - if (!sock) { - return 0; - } - - for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) { - if (socket_ipv6_multicast_memberships[i].sock == NULL) { - socket_ipv6_multicast_memberships[i].sock = sock; - socket_ipv6_multicast_memberships[i].if_idx = (u8_t)if_idx; - ip6_addr_copy(socket_ipv6_multicast_memberships[i].multi_addr, *multi_addr); - done_socket(sock); - return 1; - } - } - done_socket(sock); - return 0; -} - -/** Unregister a previously registered MLD6 membership. This prevents dropping the membership - * on socket close. - * - * ATTENTION: this function is called from tcpip_thread (or under CORE_LOCK). - */ -static void -lwip_socket_unregister_mld6_membership(int s, unsigned int if_idx, const ip6_addr_t *multi_addr) -{ - struct lwip_sock *sock = get_socket(s); - int i; - - if (!sock) { - return; - } - - for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) { - if ((socket_ipv6_multicast_memberships[i].sock == sock) && - (socket_ipv6_multicast_memberships[i].if_idx == if_idx) && - ip6_addr_cmp(&socket_ipv6_multicast_memberships[i].multi_addr, multi_addr)) { - socket_ipv6_multicast_memberships[i].sock = NULL; - socket_ipv6_multicast_memberships[i].if_idx = NETIF_NO_INDEX; - ip6_addr_set_zero(&socket_ipv6_multicast_memberships[i].multi_addr); - break; - } - } - done_socket(sock); -} - -/** Drop all MLD6 memberships of a socket that were not dropped explicitly via setsockopt. - * - * ATTENTION: this function is NOT called from tcpip_thread (or under CORE_LOCK). - */ -static void -lwip_socket_drop_registered_mld6_memberships(int s) -{ - struct lwip_sock *sock = get_socket(s); - int i; - - if (!sock) { - return; - } - - for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) { - if (socket_ipv6_multicast_memberships[i].sock == sock) { - ip_addr_t multi_addr; - u8_t if_idx; - - ip_addr_copy_from_ip6(multi_addr, socket_ipv6_multicast_memberships[i].multi_addr); - if_idx = socket_ipv6_multicast_memberships[i].if_idx; - - socket_ipv6_multicast_memberships[i].sock = NULL; - socket_ipv6_multicast_memberships[i].if_idx = NETIF_NO_INDEX; - ip6_addr_set_zero(&socket_ipv6_multicast_memberships[i].multi_addr); - - netconn_join_leave_group_netif(sock->conn, &multi_addr, if_idx, NETCONN_LEAVE); - } - } - done_socket(sock); -} -#endif /* LWIP_IPV6_MLD */ - -#endif /* LWIP_SOCKET */ diff --git a/third-party/lwip-2.1.2/api/tcpip.c b/third-party/lwip-2.1.2/api/tcpip.c deleted file mode 100644 index 8ce5e48b..00000000 --- a/third-party/lwip-2.1.2/api/tcpip.c +++ /dev/null @@ -1,661 +0,0 @@ -/** - * @file - * Sequential API Main thread module - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#include "lwip/opt.h" - -#if !NO_SYS /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/priv/tcpip_priv.h" -#include "lwip/sys.h" -#include "lwip/memp.h" -#include "lwip/mem.h" -#include "lwip/init.h" -#include "lwip/ip.h" -#include "lwip/pbuf.h" -#include "lwip/etharp.h" -#include "netif/ethernet.h" - -#define TCPIP_MSG_VAR_REF(name) API_VAR_REF(name) -#define TCPIP_MSG_VAR_DECLARE(name) API_VAR_DECLARE(struct tcpip_msg, name) -#define TCPIP_MSG_VAR_ALLOC(name) API_VAR_ALLOC(struct tcpip_msg, MEMP_TCPIP_MSG_API, name, ERR_MEM) -#define TCPIP_MSG_VAR_FREE(name) API_VAR_FREE(MEMP_TCPIP_MSG_API, name) - -/* global variables */ -static tcpip_init_done_fn tcpip_init_done; -static void *tcpip_init_done_arg; -static sys_mbox_t tcpip_mbox; - -#if LWIP_TCPIP_CORE_LOCKING -/** The global semaphore to lock the stack. */ -sys_mutex_t lock_tcpip_core; -#endif /* LWIP_TCPIP_CORE_LOCKING */ - -static void tcpip_thread_handle_msg(struct tcpip_msg *msg); - -#if !LWIP_TIMERS -/* wait for a message with timers disabled (e.g. pass a timer-check trigger into tcpip_thread) */ -#define TCPIP_MBOX_FETCH(mbox, msg) sys_mbox_fetch(mbox, msg) -#else /* !LWIP_TIMERS */ -/* wait for a message, timeouts are processed while waiting */ -#define TCPIP_MBOX_FETCH(mbox, msg) tcpip_timeouts_mbox_fetch(mbox, msg) -/** - * Wait (forever) for a message to arrive in an mbox. - * While waiting, timeouts are processed. - * - * @param mbox the mbox to fetch the message from - * @param msg the place to store the message - */ -static void -tcpip_timeouts_mbox_fetch(sys_mbox_t *mbox, void **msg) -{ - u32_t sleeptime, res; - -again: - LWIP_ASSERT_CORE_LOCKED(); - - sleeptime = sys_timeouts_sleeptime(); - if (sleeptime == SYS_TIMEOUTS_SLEEPTIME_INFINITE) { - UNLOCK_TCPIP_CORE(); - sys_arch_mbox_fetch(mbox, msg, 0); - LOCK_TCPIP_CORE(); - return; - } else if (sleeptime == 0) { - sys_check_timeouts(); - /* We try again to fetch a message from the mbox. */ - goto again; - } - - UNLOCK_TCPIP_CORE(); - res = sys_arch_mbox_fetch(mbox, msg, sleeptime); - LOCK_TCPIP_CORE(); - if (res == SYS_ARCH_TIMEOUT) { - /* If a SYS_ARCH_TIMEOUT value is returned, a timeout occurred - before a message could be fetched. */ - sys_check_timeouts(); - /* We try again to fetch a message from the mbox. */ - goto again; - } -} -#endif /* !LWIP_TIMERS */ - -/** - * The main lwIP thread. This thread has exclusive access to lwIP core functions - * (unless access to them is not locked). Other threads communicate with this - * thread using message boxes. - * - * It also starts all the timers to make sure they are running in the right - * thread context. - * - * @param arg unused argument - */ -static void -tcpip_thread(void *arg) -{ - struct tcpip_msg *msg; - LWIP_UNUSED_ARG(arg); - - LWIP_MARK_TCPIP_THREAD(); - - LOCK_TCPIP_CORE(); - if (tcpip_init_done != NULL) { - tcpip_init_done(tcpip_init_done_arg); - } - - while (1) { /* MAIN Loop */ - LWIP_TCPIP_THREAD_ALIVE(); - /* wait for a message, timeouts are processed while waiting */ - TCPIP_MBOX_FETCH(&tcpip_mbox, (void **)&msg); - if (msg == NULL) { - LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: NULL\n")); - LWIP_ASSERT("tcpip_thread: invalid message", 0); - continue; - } - tcpip_thread_handle_msg(msg); - } -} - -/* Handle a single tcpip_msg - * This is in its own function for access by tests only. - */ -static void -tcpip_thread_handle_msg(struct tcpip_msg *msg) -{ - switch (msg->type) { -#if !LWIP_TCPIP_CORE_LOCKING - case TCPIP_MSG_API: - LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", (void *)msg)); - msg->msg.api_msg.function(msg->msg.api_msg.msg); - break; - case TCPIP_MSG_API_CALL: - LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API CALL message %p\n", (void *)msg)); - msg->msg.api_call.arg->err = msg->msg.api_call.function(msg->msg.api_call.arg); - sys_sem_signal(msg->msg.api_call.sem); - break; -#endif /* !LWIP_TCPIP_CORE_LOCKING */ - -#if !LWIP_TCPIP_CORE_LOCKING_INPUT - case TCPIP_MSG_INPKT: - LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: PACKET %p\n", (void *)msg)); - if (msg->msg.inp.input_fn(msg->msg.inp.p, msg->msg.inp.netif) != ERR_OK) { - pbuf_free(msg->msg.inp.p); - } - memp_free(MEMP_TCPIP_MSG_INPKT, msg); - break; -#endif /* !LWIP_TCPIP_CORE_LOCKING_INPUT */ - -#if LWIP_TCPIP_TIMEOUT && LWIP_TIMERS - case TCPIP_MSG_TIMEOUT: - LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: TIMEOUT %p\n", (void *)msg)); - sys_timeout(msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg); - memp_free(MEMP_TCPIP_MSG_API, msg); - break; - case TCPIP_MSG_UNTIMEOUT: - LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: UNTIMEOUT %p\n", (void *)msg)); - sys_untimeout(msg->msg.tmo.h, msg->msg.tmo.arg); - memp_free(MEMP_TCPIP_MSG_API, msg); - break; -#endif /* LWIP_TCPIP_TIMEOUT && LWIP_TIMERS */ - - case TCPIP_MSG_CALLBACK: - LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg)); - msg->msg.cb.function(msg->msg.cb.ctx); - memp_free(MEMP_TCPIP_MSG_API, msg); - break; - - case TCPIP_MSG_CALLBACK_STATIC: - LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK_STATIC %p\n", (void *)msg)); - msg->msg.cb.function(msg->msg.cb.ctx); - break; - - default: - LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: %d\n", msg->type)); - LWIP_ASSERT("tcpip_thread: invalid message", 0); - break; - } -} - -#ifdef TCPIP_THREAD_TEST -/** Work on queued items in single-threaded test mode */ -int -tcpip_thread_poll_one(void) -{ - int ret = 0; - struct tcpip_msg *msg; - - if (sys_arch_mbox_tryfetch(&tcpip_mbox, (void **)&msg) != SYS_ARCH_TIMEOUT) { - LOCK_TCPIP_CORE(); - if (msg != NULL) { - tcpip_thread_handle_msg(msg); - ret = 1; - } - UNLOCK_TCPIP_CORE(); - } - return ret; -} -#endif - -/** - * Pass a received packet to tcpip_thread for input processing - * - * @param p the received packet - * @param inp the network interface on which the packet was received - * @param input_fn input function to call - */ -err_t -tcpip_inpkt(struct pbuf *p, struct netif *inp, netif_input_fn input_fn) -{ -#if LWIP_TCPIP_CORE_LOCKING_INPUT - err_t ret; - LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_inpkt: PACKET %p/%p\n", (void *)p, (void *)inp)); - LOCK_TCPIP_CORE(); - ret = input_fn(p, inp); - UNLOCK_TCPIP_CORE(); - return ret; -#else /* LWIP_TCPIP_CORE_LOCKING_INPUT */ - struct tcpip_msg *msg; - - LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(tcpip_mbox)); - - msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_INPKT); - if (msg == NULL) { - return ERR_MEM; - } - - msg->type = TCPIP_MSG_INPKT; - msg->msg.inp.p = p; - msg->msg.inp.netif = inp; - msg->msg.inp.input_fn = input_fn; - if (sys_mbox_trypost(&tcpip_mbox, msg) != ERR_OK) { - memp_free(MEMP_TCPIP_MSG_INPKT, msg); - return ERR_MEM; - } - return ERR_OK; -#endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */ -} - -/** - * @ingroup lwip_os - * Pass a received packet to tcpip_thread for input processing with - * ethernet_input or ip_input. Don't call directly, pass to netif_add() - * and call netif->input(). - * - * @param p the received packet, p->payload pointing to the Ethernet header or - * to an IP header (if inp doesn't have NETIF_FLAG_ETHARP or - * NETIF_FLAG_ETHERNET flags) - * @param inp the network interface on which the packet was received - */ -err_t -tcpip_input(struct pbuf *p, struct netif *inp) -{ -#if LWIP_ETHERNET - if (inp->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) { - return tcpip_inpkt(p, inp, ethernet_input); - } else -#endif /* LWIP_ETHERNET */ - return tcpip_inpkt(p, inp, ip_input); -} - -/** - * @ingroup lwip_os - * Call a specific function in the thread context of - * tcpip_thread for easy access synchronization. - * A function called in that way may access lwIP core code - * without fearing concurrent access. - * Blocks until the request is posted. - * Must not be called from interrupt context! - * - * @param function the function to call - * @param ctx parameter passed to f - * @return ERR_OK if the function was called, another err_t if not - * - * @see tcpip_try_callback - */ -err_t -tcpip_callback(tcpip_callback_fn function, void *ctx) -{ - struct tcpip_msg *msg; - - LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(tcpip_mbox)); - - msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API); - if (msg == NULL) { - return ERR_MEM; - } - - msg->type = TCPIP_MSG_CALLBACK; - msg->msg.cb.function = function; - msg->msg.cb.ctx = ctx; - - sys_mbox_post(&tcpip_mbox, msg); - return ERR_OK; -} - -/** - * @ingroup lwip_os - * Call a specific function in the thread context of - * tcpip_thread for easy access synchronization. - * A function called in that way may access lwIP core code - * without fearing concurrent access. - * Does NOT block when the request cannot be posted because the - * tcpip_mbox is full, but returns ERR_MEM instead. - * Can be called from interrupt context. - * - * @param function the function to call - * @param ctx parameter passed to f - * @return ERR_OK if the function was called, another err_t if not - * - * @see tcpip_callback - */ -err_t -tcpip_try_callback(tcpip_callback_fn function, void *ctx) -{ - struct tcpip_msg *msg; - - LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(tcpip_mbox)); - - msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API); - if (msg == NULL) { - return ERR_MEM; - } - - msg->type = TCPIP_MSG_CALLBACK; - msg->msg.cb.function = function; - msg->msg.cb.ctx = ctx; - - if (sys_mbox_trypost(&tcpip_mbox, msg) != ERR_OK) { - memp_free(MEMP_TCPIP_MSG_API, msg); - return ERR_MEM; - } - return ERR_OK; -} - -#if LWIP_TCPIP_TIMEOUT && LWIP_TIMERS -/** - * call sys_timeout in tcpip_thread - * - * @param msecs time in milliseconds for timeout - * @param h function to be called on timeout - * @param arg argument to pass to timeout function h - * @return ERR_MEM on memory error, ERR_OK otherwise - */ -err_t -tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg) -{ - struct tcpip_msg *msg; - - LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(tcpip_mbox)); - - msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API); - if (msg == NULL) { - return ERR_MEM; - } - - msg->type = TCPIP_MSG_TIMEOUT; - msg->msg.tmo.msecs = msecs; - msg->msg.tmo.h = h; - msg->msg.tmo.arg = arg; - sys_mbox_post(&tcpip_mbox, msg); - return ERR_OK; -} - -/** - * call sys_untimeout in tcpip_thread - * - * @param h function to be called on timeout - * @param arg argument to pass to timeout function h - * @return ERR_MEM on memory error, ERR_OK otherwise - */ -err_t -tcpip_untimeout(sys_timeout_handler h, void *arg) -{ - struct tcpip_msg *msg; - - LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(tcpip_mbox)); - - msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API); - if (msg == NULL) { - return ERR_MEM; - } - - msg->type = TCPIP_MSG_UNTIMEOUT; - msg->msg.tmo.h = h; - msg->msg.tmo.arg = arg; - sys_mbox_post(&tcpip_mbox, msg); - return ERR_OK; -} -#endif /* LWIP_TCPIP_TIMEOUT && LWIP_TIMERS */ - - -/** - * Sends a message to TCPIP thread to call a function. Caller thread blocks on - * on a provided semaphore, which ist NOT automatically signalled by TCPIP thread, - * this has to be done by the user. - * It is recommended to use LWIP_TCPIP_CORE_LOCKING since this is the way - * with least runtime overhead. - * - * @param fn function to be called from TCPIP thread - * @param apimsg argument to API function - * @param sem semaphore to wait on - * @return ERR_OK if the function was called, another err_t if not - */ -err_t -tcpip_send_msg_wait_sem(tcpip_callback_fn fn, void *apimsg, sys_sem_t *sem) -{ -#if LWIP_TCPIP_CORE_LOCKING - LWIP_UNUSED_ARG(sem); - LOCK_TCPIP_CORE(); - fn(apimsg); - UNLOCK_TCPIP_CORE(); - return ERR_OK; -#else /* LWIP_TCPIP_CORE_LOCKING */ - TCPIP_MSG_VAR_DECLARE(msg); - - LWIP_ASSERT("semaphore not initialized", sys_sem_valid(sem)); - LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(tcpip_mbox)); - - TCPIP_MSG_VAR_ALLOC(msg); - TCPIP_MSG_VAR_REF(msg).type = TCPIP_MSG_API; - TCPIP_MSG_VAR_REF(msg).msg.api_msg.function = fn; - TCPIP_MSG_VAR_REF(msg).msg.api_msg.msg = apimsg; - sys_mbox_post(&tcpip_mbox, &TCPIP_MSG_VAR_REF(msg)); - sys_arch_sem_wait(sem, 0); - TCPIP_MSG_VAR_FREE(msg); - return ERR_OK; -#endif /* LWIP_TCPIP_CORE_LOCKING */ -} - -/** - * Synchronously calls function in TCPIP thread and waits for its completion. - * It is recommended to use LWIP_TCPIP_CORE_LOCKING (preferred) or - * LWIP_NETCONN_SEM_PER_THREAD. - * If not, a semaphore is created and destroyed on every call which is usually - * an expensive/slow operation. - * @param fn Function to call - * @param call Call parameters - * @return Return value from tcpip_api_call_fn - */ -err_t -tcpip_api_call(tcpip_api_call_fn fn, struct tcpip_api_call_data *call) -{ -#if LWIP_TCPIP_CORE_LOCKING - err_t err; - LOCK_TCPIP_CORE(); - err = fn(call); - UNLOCK_TCPIP_CORE(); - return err; -#else /* LWIP_TCPIP_CORE_LOCKING */ - TCPIP_MSG_VAR_DECLARE(msg); - -#if !LWIP_NETCONN_SEM_PER_THREAD - err_t err = sys_sem_new(&call->sem, 0); - if (err != ERR_OK) { - return err; - } -#endif /* LWIP_NETCONN_SEM_PER_THREAD */ - - LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(tcpip_mbox)); - - TCPIP_MSG_VAR_ALLOC(msg); - TCPIP_MSG_VAR_REF(msg).type = TCPIP_MSG_API_CALL; - TCPIP_MSG_VAR_REF(msg).msg.api_call.arg = call; - TCPIP_MSG_VAR_REF(msg).msg.api_call.function = fn; -#if LWIP_NETCONN_SEM_PER_THREAD - TCPIP_MSG_VAR_REF(msg).msg.api_call.sem = LWIP_NETCONN_THREAD_SEM_GET(); -#else /* LWIP_NETCONN_SEM_PER_THREAD */ - TCPIP_MSG_VAR_REF(msg).msg.api_call.sem = &call->sem; -#endif /* LWIP_NETCONN_SEM_PER_THREAD */ - sys_mbox_post(&tcpip_mbox, &TCPIP_MSG_VAR_REF(msg)); - sys_arch_sem_wait(TCPIP_MSG_VAR_REF(msg).msg.api_call.sem, 0); - TCPIP_MSG_VAR_FREE(msg); - -#if !LWIP_NETCONN_SEM_PER_THREAD - sys_sem_free(&call->sem); -#endif /* LWIP_NETCONN_SEM_PER_THREAD */ - - return call->err; -#endif /* LWIP_TCPIP_CORE_LOCKING */ -} - -/** - * @ingroup lwip_os - * Allocate a structure for a static callback message and initialize it. - * The message has a special type such that lwIP never frees it. - * This is intended to be used to send "static" messages from interrupt context, - * e.g. the message is allocated once and posted several times from an IRQ - * using tcpip_callbackmsg_trycallback(). - * Example usage: Trigger execution of an ethernet IRQ DPC routine in lwIP thread context. - * - * @param function the function to call - * @param ctx parameter passed to function - * @return a struct pointer to pass to tcpip_callbackmsg_trycallback(). - * - * @see tcpip_callbackmsg_trycallback() - * @see tcpip_callbackmsg_delete() - */ -struct tcpip_callback_msg * -tcpip_callbackmsg_new(tcpip_callback_fn function, void *ctx) -{ - struct tcpip_msg *msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API); - if (msg == NULL) { - return NULL; - } - msg->type = TCPIP_MSG_CALLBACK_STATIC; - msg->msg.cb.function = function; - msg->msg.cb.ctx = ctx; - return (struct tcpip_callback_msg *)msg; -} - -/** - * @ingroup lwip_os - * Free a callback message allocated by tcpip_callbackmsg_new(). - * - * @param msg the message to free - * - * @see tcpip_callbackmsg_new() - */ -void -tcpip_callbackmsg_delete(struct tcpip_callback_msg *msg) -{ - memp_free(MEMP_TCPIP_MSG_API, msg); -} - -/** - * @ingroup lwip_os - * Try to post a callback-message to the tcpip_thread tcpip_mbox. - * - * @param msg pointer to the message to post - * @return sys_mbox_trypost() return code - * - * @see tcpip_callbackmsg_new() - */ -err_t -tcpip_callbackmsg_trycallback(struct tcpip_callback_msg *msg) -{ - LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(tcpip_mbox)); - return sys_mbox_trypost(&tcpip_mbox, msg); -} - -/** - * @ingroup lwip_os - * Try to post a callback-message to the tcpip_thread mbox. - * Same as @ref tcpip_callbackmsg_trycallback but calls sys_mbox_trypost_fromisr(), - * mainly to help FreeRTOS, where calls differ between task level and ISR level. - * - * @param msg pointer to the message to post - * @return sys_mbox_trypost_fromisr() return code (without change, so this - * knowledge can be used to e.g. propagate "bool needs_scheduling") - * - * @see tcpip_callbackmsg_new() - */ -err_t -tcpip_callbackmsg_trycallback_fromisr(struct tcpip_callback_msg *msg) -{ - LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(tcpip_mbox)); - return sys_mbox_trypost_fromisr(&tcpip_mbox, msg); -} - -/** - * @ingroup lwip_os - * Initialize this module: - * - initialize all sub modules - * - start the tcpip_thread - * - * @param initfunc a function to call when tcpip_thread is running and finished initializing - * @param arg argument to pass to initfunc - */ -void -tcpip_init(tcpip_init_done_fn initfunc, void *arg) -{ - - lwip_init(); - - tcpip_init_done = initfunc; - tcpip_init_done_arg = arg; - if (sys_mbox_new(&tcpip_mbox, TCPIP_MBOX_SIZE) != ERR_OK) { - LWIP_ASSERT("failed to create tcpip_thread mbox", 0); - } - -#if LWIP_TCPIP_CORE_LOCKING - if (sys_mutex_new(&lock_tcpip_core) != ERR_OK) { - LWIP_ASSERT("failed to create lock_tcpip_core", 0); - } -#endif /* LWIP_TCPIP_CORE_LOCKING */ - - sys_thread_new(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO); - -} - -/** - * Simple callback function used with tcpip_callback to free a pbuf - * (pbuf_free has a wrong signature for tcpip_callback) - * - * @param p The pbuf (chain) to be dereferenced. - */ -static void -pbuf_free_int(void *p) -{ - struct pbuf *q = (struct pbuf *)p; - pbuf_free(q); -} - -/** - * A simple wrapper function that allows you to free a pbuf from interrupt context. - * - * @param p The pbuf (chain) to be dereferenced. - * @return ERR_OK if callback could be enqueued, an err_t if not - */ -err_t -pbuf_free_callback(struct pbuf *p) -{ - return tcpip_try_callback(pbuf_free_int, p); -} - -/** - * A simple wrapper function that allows you to free heap memory from - * interrupt context. - * - * @param m the heap memory to free - * @return ERR_OK if callback could be enqueued, an err_t if not - */ -err_t -mem_free_callback(void *m) -{ - return tcpip_try_callback(mem_free, m); -} - -#endif /* !NO_SYS */ diff --git a/third-party/lwip-2.1.2/apps/ping/ping.c b/third-party/lwip-2.1.2/apps/ping/ping.c deleted file mode 100644 index fd8b0e26..00000000 --- a/third-party/lwip-2.1.2/apps/ping/ping.c +++ /dev/null @@ -1,482 +0,0 @@ -/** - * @file - * Ping sender module - * - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -/** - * This is an example of a "ping" sender (with raw API and socket API). - * It can be used as a start point to maintain opened a network connection, or - * like a network "watchdog" for your device. - * - */ - -#include "lwip/opt.h" -#include "strto.h" -#if LWIP_RAW /* don't build if not configured for use in lwipopts.h */ - -#include "ping.h" - -#include "lwip/mem.h" -#include "lwip/raw.h" -#include "lwip/icmp.h" -#include "lwip/netif.h" -#include "lwip/sys.h" -#include "lwip/timeouts.h" -#include "lwip/inet_chksum.h" -#include "lwip/prot/ip4.h" - -#if PING_USE_SOCKETS -#include "lwip/sockets.h" -#include -#include "lwip/inet.h" -#include -#endif /* PING_USE_SOCKETS */ - -#include "../src/shell.h" - - -/** - * PING_DEBUG: Enable debugging for PING. - */ -#ifndef PING_DEBUG -#define PING_DEBUG LWIP_DBG_ON -#endif - -/** ping receive timeout - in milliseconds */ -#ifndef PING_RCV_TIMEO -#define PING_RCV_TIMEO 1000 -#endif - -/** ping delay - in milliseconds */ -#ifndef PING_DELAY -#define PING_DELAY 1000 -#endif - -/** ping identifier - must fit on a u16_t */ -#ifndef PING_ID -#define PING_ID 0xAFAF -#endif - -/** ping additional data size to include in the packet */ -#ifndef PING_DATA_SIZE -#define PING_DATA_SIZE 32 -#endif - -/** ping result action - no default action */ -#ifndef PING_RESULT -#define PING_RESULT(ping_ok) -#endif - -/* ping variables */ -static const ip_addr_t* ping_target; -static u16_t ping_seq_num; -#ifdef LWIP_DEBUG -static u32_t ping_time; -#endif /* LWIP_DEBUG */ -#if !PING_USE_SOCKETS -static struct raw_pcb *ping_pcb; -#endif /* PING_USE_SOCKETS */ - -/** Prepare a echo ICMP request */ -static void -ping_prepare_echo( struct icmp_echo_hdr *iecho, u16_t len) -{ - size_t i; - size_t data_len = len - sizeof(struct icmp_echo_hdr); - - ICMPH_TYPE_SET(iecho, ICMP_ECHO); - ICMPH_CODE_SET(iecho, 0); - iecho->chksum = 0; - iecho->id = PING_ID; - iecho->seqno = lwip_htons(++ping_seq_num); - - /* fill the additional data buffer with some data */ - for(i = 0; i < data_len; i++) { - ((char*)iecho)[sizeof(struct icmp_echo_hdr) + i] = (char)i; - } - - iecho->chksum = inet_chksum(iecho, len); -} - -#if PING_USE_SOCKETS - -/* Ping using the socket ip */ -static err_t -ping_send(int s, const ip_addr_t *addr) -{ - int err; - struct icmp_echo_hdr *iecho; - struct sockaddr_storage to; - size_t ping_size = sizeof(struct icmp_echo_hdr) + PING_DATA_SIZE; - LWIP_ASSERT("ping_size is too big", ping_size <= 0xffff); - -#if LWIP_IPV6 - if(IP_IS_V6(addr) && !ip6_addr_isipv4mappedipv6(ip_2_ip6(addr))) { - /* todo: support ICMP6 echo */ - return ERR_VAL; - } -#endif /* LWIP_IPV6 */ - - iecho = (struct icmp_echo_hdr *)mem_malloc((mem_size_t)ping_size); - if (!iecho) { - return ERR_MEM; - } - - ping_prepare_echo(iecho, (u16_t)ping_size); - -#if LWIP_IPV4 - if(IP_IS_V4(addr)) { - struct sockaddr_in *to4 = (struct sockaddr_in*)&to; - to4->sin_len = sizeof(to4); - to4->sin_family = AF_INET; - inet_addr_from_ip4addr(&to4->sin_addr, ip_2_ip4(addr)); - } -#endif /* LWIP_IPV4 */ - -#if LWIP_IPV6 - if(IP_IS_V6(addr)) { - struct sockaddr_in6 *to6 = (struct sockaddr_in6*)&to; - to6->sin6_len = sizeof(to6); - to6->sin6_family = AF_INET6; - inet6_addr_from_ip6addr(&to6->sin6_addr, ip_2_ip6(addr)); - } -#endif /* LWIP_IPV6 */ - - err = lwip_sendto(s, iecho, ping_size, 0, (struct sockaddr*)&to, sizeof(to)); - - mem_free(iecho); - - return (err ? ERR_OK : ERR_VAL); -} - -void -ping_recv(int s) -{ - char buf[64]; - int len; - struct sockaddr_storage from; - int fromlen = sizeof(from); - - while((len = lwip_recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr*)&from, (socklen_t*)&fromlen)) > 0) { - if (len >= (int)(sizeof(struct ip_hdr)+sizeof(struct icmp_echo_hdr))) { - ip_addr_t fromaddr; - memset(&fromaddr, 0, sizeof(fromaddr)); - -#if LWIP_IPV4 - if(from.ss_family == AF_INET) { - struct sockaddr_in *from4 = (struct sockaddr_in*)&from; - inet_addr_to_ip4addr(ip_2_ip4(&fromaddr), &from4->sin_addr); - IP_SET_TYPE_VAL(fromaddr, IPADDR_TYPE_V4); - } -#endif /* LWIP_IPV4 */ - -#if LWIP_IPV6 - if(from.ss_family == AF_INET6) { - struct sockaddr_in6 *from6 = (struct sockaddr_in6*)&from; - inet6_addr_to_ip6addr(ip_2_ip6(&fromaddr), &from6->sin6_addr); - IP_SET_TYPE_VAL(fromaddr, IPADDR_TYPE_V6); - } -#endif /* LWIP_IPV6 */ - - /* todo: support ICMP6 echo */ -#if LWIP_IPV4 - if (IP_IS_V4_VAL(fromaddr)) { - struct ip_hdr *iphdr; - struct icmp_echo_hdr *iecho; - - iphdr = (struct ip_hdr *)buf; - iecho = (struct icmp_echo_hdr *)(buf + (IPH_HL(iphdr) * 4)); - if ((iecho->id == PING_ID) && (iecho->seqno == lwip_htons(ping_seq_num))) - { - LWIP_DEBUGF( PING_DEBUG, ("ping: recv ")); - ip_addr_debug_print_val(PING_DEBUG, fromaddr); - LWIP_DEBUGF( PING_DEBUG, (" %"U32_F" ms\n", (sys_now() - ping_time))); - - /* do some ping result processing */ - PING_RESULT((ICMPH_TYPE(iecho) == ICMP_ER)); - return; - } - else - { - // LWIP_DEBUGF( PING_DEBUG, ("ping: drop\n")); - } - } -#endif /* LWIP_IPV4 */ - } - fromlen = sizeof(from); - } - - if (len == 0) { - LWIP_DEBUGF( PING_DEBUG, ("ping: recv - %"U32_F" ms - timeout\n", (sys_now()-ping_time))); - } - - /* do some ping result processing */ - PING_RESULT(0); -} - -static void -ping_thread(void *arg) -{ - int s; - int ret; - u32 times = 0,cnt = 0; - -#if LWIP_SO_SNDRCVTIMEO_NONSTANDARD - int timeout = PING_RCV_TIMEO; -#else - struct timeval timeout; - timeout.tv_sec = PING_RCV_TIMEO/1000; - timeout.tv_usec = (PING_RCV_TIMEO%1000)*1000; -#endif - - times = *(u32*)(arg); - - if(times == 0) - { - times = 4; - } - printf("times: %d\n", times); -#if LWIP_IPV6 - if(IP_IS_V4(ping_target) || ip6_addr_isipv4mappedipv6(ip_2_ip6(ping_target))) { - s = lwip_socket(AF_INET6, SOCK_RAW, IP_PROTO_ICMP); - } else { - s = lwip_socket(AF_INET6, SOCK_RAW, IP6_NEXTH_ICMP6); - } -#else - printf("start to lwip_socket \r\n"); - s = lwip_socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP); -#endif - if (s < 0) { - vTaskDelete(NULL); - return; - } - ret = lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); - LWIP_ASSERT("setting receive timeout failed", ret == 0); - LWIP_UNUSED_ARG(ret); - while (1) - { - if(cnt ++ > times) - { - break; - } - if (ping_send(s, ping_target) == ERR_OK) { - LWIP_DEBUGF( PING_DEBUG, ("ping: send ")); - ip_addr_debug_print(PING_DEBUG, ping_target); - LWIP_DEBUGF( PING_DEBUG, ("\n")); - -#ifdef LWIP_DEBUG - ping_time = sys_now(); -#endif /* LWIP_DEBUG */ - ping_recv(s); - } else { - LWIP_DEBUGF( PING_DEBUG, ("ping: send ")); - ip_addr_debug_print(PING_DEBUG, ping_target); - LWIP_DEBUGF( PING_DEBUG, (" - error\n")); - } - sys_msleep(PING_DELAY); - } - printf("ping test is over \r\n"); - lwip_close(s); - vTaskDelete(NULL); -} - -#else /* PING_USE_SOCKETS */ - -/* Ping using the raw ip */ -static u8_t -ping_recv(void *arg, struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *addr) -{ - struct icmp_echo_hdr *iecho; - LWIP_UNUSED_ARG(arg); - LWIP_UNUSED_ARG(pcb); - LWIP_UNUSED_ARG(addr); - LWIP_ASSERT("p != NULL", p != NULL); - - printf("ping ping_recv \r\n"); - - if ((p->tot_len >= (PBUF_IP_HLEN + sizeof(struct icmp_echo_hdr))) && - pbuf_remove_header(p, PBUF_IP_HLEN) == 0) { - iecho = (struct icmp_echo_hdr *)p->payload; - - if ((iecho->id == PING_ID) && (iecho->seqno == lwip_htons(ping_seq_num))) { - /* 接收到对方返回的数据包,ping成功,显示延时 */ - printf("ping success: recv %d ms\r\n", (sys_now()-ping_time)); - ip_addr_debug_print(PING_DEBUG, addr); - - /* do some ping result processing */ - PING_RESULT(1); - pbuf_free(p); - return 1; /* eat the packet */ - } - /* not eaten, restore original packet */ - pbuf_add_header(p, PBUF_IP_HLEN); - } - - return 0; /* don't eat the packet */ -} - -static void -ping_send(struct raw_pcb *raw, const ip_addr_t *addr) -{ - struct pbuf *p; - struct icmp_echo_hdr *iecho; - size_t ping_size = sizeof(struct icmp_echo_hdr) + PING_DATA_SIZE; - - LWIP_DEBUGF( PING_DEBUG, ("ping: send ")); - ip_addr_debug_print(PING_DEBUG, addr); - LWIP_DEBUGF( PING_DEBUG, ("\n")); - LWIP_ASSERT("ping_size <= 0xffff", ping_size <= 0xffff); - - p = pbuf_alloc(PBUF_IP, (u16_t)ping_size, PBUF_RAM); - if (!p) { - return; - } - if ((p->len == p->tot_len) && (p->next == NULL)) { - iecho = (struct icmp_echo_hdr *)p->payload; - - ping_prepare_echo(iecho, (u16_t)ping_size); - - raw_sendto(raw, p, addr); -#ifdef LWIP_DEBUG - ping_time = sys_now(); -#endif /* LWIP_DEBUG */ - } - pbuf_free(p); -} - -static void -ping_timeout(void *arg) -{ - struct raw_pcb *pcb = (struct raw_pcb*)arg; - - LWIP_ASSERT("ping_timeout: no pcb given!", pcb != NULL); - - ping_send(pcb, ping_target); - - sys_timeout(PING_DELAY, ping_timeout, pcb); -} - -static void -ping_raw_init(void) -{ - ping_pcb = raw_new(IP_PROTO_ICMP); - LWIP_ASSERT("ping_pcb != NULL", ping_pcb != NULL); - - raw_recv(ping_pcb, ping_recv, NULL); - raw_bind(ping_pcb, IP_ADDR_ANY); - sys_timeout(PING_DELAY, ping_timeout, ping_pcb); -} - -void -ping_send_now(void) -{ - LWIP_ASSERT("ping_pcb != NULL", ping_pcb != NULL); - ping_send(ping_pcb, ping_target); -} - -#endif /* PING_USE_SOCKETS */ - -void -ping_init(const ip_addr_t* ping_addr,u32 cnt) -{ - ping_target = ping_addr; - sys_thread_t ret; - static u32 times = 0; - times = cnt; -#if PING_USE_SOCKETS - ret = sys_thread_new("ping_thread", ping_thread, ×, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO); -#else /* PING_USE_SOCKETS */ - - ping_raw_init(); -#endif /* PING_USE_SOCKETS */ - printf("sys_thread_new is %p \r\n",ret); -} - -void -ping_deinit(void) -{ - -} - - -static ip_addr_t target_addr; -static int ping(int argc, char *argv[]) -{ - u32 id = 0; - u32 type = 0; - struct sockaddr_in *h = NULL; - struct in_addr ina; - char *target_name; - int times = 4; - - if (argc == 1) - { - printf("Please input: ping \n"); - return -1; - } - else - { - target_name = argv[1]; - } - - if(argc == 3) - { - times = (u32)simple_strtoul(argv[2], NULL, 10); - } - - printf("%s\n", target_name); - -#if LWIP_IPV4 - if (inet_aton(target_name, &target_addr) == 0) - { - printf("ping: unknown host %s\n", target_name); - return -1; - } -#else - if (inet6_aton(target_name, &target_addr) == 0) - { - printf("ping: unknown host %s\n", target_name); - return -1; - } - -#endif - - ping_init(&target_addr,times); - - return 0; - -} - - -SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), ping, ping, processing ping task); - - -#endif \ No newline at end of file diff --git a/third-party/lwip-2.1.2/apps/ping/ping.h b/third-party/lwip-2.1.2/apps/ping/ping.h deleted file mode 100644 index 23bc5aa8..00000000 --- a/third-party/lwip-2.1.2/apps/ping/ping.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef LWIP_PING_H -#define LWIP_PING_H - -#include "lwip/ip_addr.h" - -/** - * PING_USE_SOCKETS: Set to 1 to use sockets, otherwise the raw api is used - */ -#ifndef PING_USE_SOCKETS -#define PING_USE_SOCKETS LWIP_SOCKET -#endif - -void -ping_init(const ip_addr_t* ping_addr,u32 cnt); -void ping_deinit(); - -#if !PING_USE_SOCKETS -void ping_send_now(void); -#endif /* !PING_USE_SOCKETS */ - -#endif /* LWIP_PING_H */ diff --git a/third-party/lwip-2.1.2/apps/tftp/tftp.c b/third-party/lwip-2.1.2/apps/tftp/tftp.c deleted file mode 100644 index 4a0dd5cd..00000000 --- a/third-party/lwip-2.1.2/apps/tftp/tftp.c +++ /dev/null @@ -1,614 +0,0 @@ -/** - * - * @file tftp.c - * - * @author Logan Gunthorpe - * Dirk Ziegelmeier - * - * @brief Trivial File Transfer Protocol (RFC 1350) - * - * Copyright (c) Deltatee Enterprises Ltd. 2013 - * All rights reserved. - * - */ - -/* - * Redistribution and use in source and binary forms, with or without - * modification,are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Author: Logan Gunthorpe - * Dirk Ziegelmeier - * - */ - -/** - * @defgroup tftp TFTP client/server - * @ingroup apps - * - * This is simple TFTP client/server for the lwIP raw API. - * You need to increase MEMP_NUM_SYS_TIMEOUT by one if you use TFTP! - */ -#include -#include "fdebug.h" -#include "tftp_client.h" -#include "tftp_server.h" - -#if LWIP_UDP - -#include "lwip/udp.h" -#include "lwip/timeouts.h" -#include "lwip/debug.h" - -#if LWIP_IPV4 -#define ip4_addr_eq(addr1, addr2) ((addr1)->addr == (addr2)->addr) -#define ip_addr_eq(addr1, addr2) ip4_addr_eq(addr1, addr2) - -#else -#define ip_addr_eq(addr1, addr2) ip6_addr_eq(addr1, addr2) -#endif - -#define TFTP_MAX_PAYLOAD_SIZE 512 -#define TFTP_HEADER_LENGTH 4 - -/* TFTP报文的头两个字节表示操作码,共有5种操作码 */ -/* 读请求和写请求功能码的数据报文格式是一样的,报文格式为请求包, - 还有数据包、确认包和差错包 */ -#define TFTP_RRQ 1 /* 读请求,即下载 */ -#define TFTP_WRQ 2 /* 写请求,即上传 */ -#define TFTP_DATA 3 /* 表示数据包 */ -#define TFTP_ACK 4 /* 确认码 */ -#define TFTP_ERROR 5 /* 错误 */ - -enum tftp_error -{ - TFTP_ERROR_FILE_NOT_FOUND = 1, - TFTP_ERROR_ACCESS_VIOLATION = 2, - TFTP_ERROR_DISK_FULL = 3, - TFTP_ERROR_ILLEGAL_OPERATION = 4, - TFTP_ERROR_UNKNOWN_TRFR_ID = 5, - TFTP_ERROR_FILE_EXISTS = 6, - TFTP_ERROR_NO_SUCH_USER = 7 -}; - -struct tftp_state -{ - const struct tftp_context *ctx; - void *handle; - struct pbuf *last_data; - struct udp_pcb *upcb; - ip_addr_t addr; - u16_t port; - int timer; - int last_pkt; - u16_t blknum; - u8_t retries; - u8_t mode_write; - u8_t tftp_mode; -}; - -static struct tftp_state tftp_state; - -static void tftp_tmr(void *arg); - -static void -close_handle(void) -{ - tftp_state.port = 0; - ip_addr_set_any(0, &tftp_state.addr); - - if (tftp_state.last_data != NULL) - { - pbuf_free(tftp_state.last_data); - tftp_state.last_data = NULL; - } - - sys_untimeout(tftp_tmr, NULL); - - if (tftp_state.handle) - { - tftp_state.ctx->close(tftp_state.handle); - tftp_state.handle = NULL; - LWIP_DEBUGF(TFTP_DEBUG | LWIP_DBG_STATE, ("tftp: closing\n")); - } -} - -static struct pbuf * -init_packet(u16_t opcode, u16_t extra, size_t size) -{ - /* 申请空间 */ - struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, (u16_t)(TFTP_HEADER_LENGTH + size), PBUF_RAM); - u16_t *payload; - - if (p != NULL) - { - /* 填充包内容 */ - payload = (u16_t *)p->payload; - payload[0] = PP_HTONS(opcode); - payload[1] = lwip_htons(extra); - } - - return p; -} - -static err_t -send_request(const ip_addr_t *addr, u16_t port, u16_t opcode, const char *fname, const char *mode) -{ - size_t fname_length = strlen(fname) + 1; - size_t mode_length = strlen(mode) + 1; - struct pbuf *p = init_packet(opcode, 0, fname_length + mode_length - 2); - char *payload; - err_t ret; - - if (p == NULL) - { - return ERR_MEM; - } - - payload = (char *)p->payload; - MEMCPY(payload + 2, fname, fname_length); - MEMCPY(payload + 2 + fname_length, mode, mode_length); - - ret = udp_sendto(tftp_state.upcb, p, addr, port); - pbuf_free(p); - return ret; -} - -static err_t -send_error(const ip_addr_t *addr, u16_t port, enum tftp_error code, const char *str) -{ - int str_length = strlen(str); - struct pbuf *p; - u16_t *payload; - err_t ret; - - p = init_packet(TFTP_ERROR, code, str_length + 1); - if (p == NULL) - { - return ERR_MEM; - } - - payload = (u16_t *)p->payload; - MEMCPY(&payload[2], str, str_length + 1); - - ret = udp_sendto(tftp_state.upcb, p, addr, port); - pbuf_free(p); - return ret; -} - -static err_t -send_ack(const ip_addr_t *addr, u16_t port, u16_t blknum) -{ - struct pbuf *p; - err_t ret; - - p = init_packet(TFTP_ACK, blknum, 0); - if (p == NULL) - { - return ERR_MEM; - } - - ret = udp_sendto(tftp_state.upcb, p, addr, port); - pbuf_free(p); - return ret; -} - -static err_t -resend_data(const ip_addr_t *addr, u16_t port) -{ - err_t ret; - struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, tftp_state.last_data->len, PBUF_RAM); - if (p == NULL) - { - return ERR_MEM; - } - - ret = pbuf_copy(p, tftp_state.last_data); - if (ret != ERR_OK) - { - pbuf_free(p); - return ret; - } - - ret = udp_sendto(tftp_state.upcb, p, addr, port); - pbuf_free(p); - return ret; -} - -static void -send_data(const ip_addr_t *addr, u16_t port) -{ - u16_t *payload; - int ret; - - /* 不需重传,清除上次发送的数据包 */ - if (tftp_state.last_data != NULL) - { - pbuf_free(tftp_state.last_data); - } - - tftp_state.last_data = init_packet(TFTP_DATA, tftp_state.blknum, TFTP_MAX_PAYLOAD_SIZE); - if (tftp_state.last_data == NULL) - { - return; - } - - payload = (u16_t *)tftp_state.last_data->payload; - - /* 将内容读进包中 */ - ret = tftp_state.ctx->read(tftp_state.handle, &payload[2], TFTP_MAX_PAYLOAD_SIZE); - if (ret < 0) - { - send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "Error occurred while reading the file."); - close_handle(); - return; - } - - pbuf_realloc(tftp_state.last_data, (u16_t)(TFTP_HEADER_LENGTH + ret)); - resend_data(addr, port); -} - -static void -tftp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) -{ - u16_t *sbuf = (u16_t *)p->payload; - int opcode; - - LWIP_UNUSED_ARG(arg); - LWIP_UNUSED_ARG(upcb); - - if (((tftp_state.port != 0) && (port != tftp_state.port)) || - (!ip_addr_isany_val(tftp_state.addr) && !ip_addr_eq(&tftp_state.addr, addr))) - { - send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "Only one connection at a time is supported"); - pbuf_free(p); - return; - } - - opcode = sbuf[0]; - - tftp_state.last_pkt = tftp_state.timer; - tftp_state.retries = 0; - - switch (opcode) - { - case PP_HTONS(TFTP_RRQ): /* fall through */ - case PP_HTONS(TFTP_WRQ): - { - const char tftp_null = 0; - char filename[TFTP_MAX_FILENAME_LEN + 1]; - char mode[TFTP_MAX_MODE_LEN + 1]; - u16_t filename_end_offset; - u16_t mode_end_offset; - - if (tftp_state.handle != NULL) - { - send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "Only one connection at a time is supported"); - break; - } - - if ((tftp_state.tftp_mode & LWIP_TFTP_MODE_SERVER) == 0) - { - send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "TFTP server not enabled"); - break; - } - - sys_timeout(TFTP_TIMER_MSECS, tftp_tmr, NULL); - - /* find \0 in pbuf -> end of filename string */ - filename_end_offset = pbuf_memfind(p, &tftp_null, sizeof(tftp_null), 2); - if ((u16_t)(filename_end_offset - 1) > sizeof(filename)) - { - send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "Filename too long/not NULL terminated"); - break; - } - pbuf_copy_partial(p, filename, filename_end_offset - 1, 2); - - /* find \0 in pbuf -> end of mode string */ - mode_end_offset = pbuf_memfind(p, &tftp_null, sizeof(tftp_null), filename_end_offset + 1); - if ((u16_t)(mode_end_offset - filename_end_offset) > sizeof(mode)) - { - send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "Mode too long/not NULL terminated"); - break; - } - pbuf_copy_partial(p, mode, mode_end_offset - filename_end_offset, filename_end_offset + 1); - - tftp_state.handle = tftp_state.ctx->open(filename, mode, opcode == PP_HTONS(TFTP_WRQ)); - tftp_state.blknum = 1; - - if (!tftp_state.handle) - { - send_error(addr, port, TFTP_ERROR_FILE_NOT_FOUND, "Unable to open requested file."); - break; - } - - LWIP_DEBUGF(TFTP_DEBUG | LWIP_DBG_STATE, ("tftp: %s request from ", (opcode == PP_HTONS(TFTP_WRQ)) ? "write" : "read")); - ip_addr_debug_print(TFTP_DEBUG | LWIP_DBG_STATE, addr); - LWIP_DEBUGF(TFTP_DEBUG | LWIP_DBG_STATE, (" for '%s' mode '%s'\n", filename, mode)); - - ip_addr_copy(tftp_state.addr, *addr); - tftp_state.port = port; - - if (opcode == PP_HTONS(TFTP_WRQ)) - { - tftp_state.mode_write = 1; - send_ack(addr, port, 0); - } - else - { - tftp_state.mode_write = 0; - send_data(addr, port); - } - - break; - } - - case PP_HTONS(TFTP_DATA): - { - int ret; - u16_t blknum; - - if (tftp_state.handle == NULL) - { - send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "No connection"); - break; - } - - if (tftp_state.mode_write != 1) - { - send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "Not a write connection"); - break; - } - - blknum = lwip_ntohs(sbuf[1]); - if (blknum == tftp_state.blknum) - { - pbuf_remove_header(p, TFTP_HEADER_LENGTH); - ret = tftp_state.ctx->write(tftp_state.handle, p); - if (ret < 0) - { - send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "error writing file"); - close_handle(); - } - else - { - send_ack(addr, port, blknum); - } - - if (p->tot_len < TFTP_MAX_PAYLOAD_SIZE) - { - close_handle(); - } - else - { - tftp_state.blknum++; - } - } - else if ((u16_t)(blknum + 1) == tftp_state.blknum) - { - /* retransmit of previous block, ack again (casting to u16_t to care for overflow) */ - send_ack(addr, port, blknum); - } - else - { - send_error(addr, port, TFTP_ERROR_UNKNOWN_TRFR_ID, "Wrong block number"); - } - break; - } - - case PP_HTONS(TFTP_ACK): - { - u16_t blknum; - int lastpkt; - - if (tftp_state.handle == NULL) - { - send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "No connection"); - break; - } - - if (tftp_state.mode_write != 0) - { - send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "Not a read connection"); - break; - } - - blknum = lwip_ntohs(sbuf[1]); - if (blknum != tftp_state.blknum) - { - send_error(addr, port, TFTP_ERROR_UNKNOWN_TRFR_ID, "Wrong block number"); - break; - } - - lastpkt = 0; - - if (tftp_state.last_data != NULL) - { - lastpkt = tftp_state.last_data->tot_len != (TFTP_MAX_PAYLOAD_SIZE + TFTP_HEADER_LENGTH); - } - - if (!lastpkt) - { - tftp_state.blknum++; - send_data(addr, port); - } - else - { - close_handle(); - } - - break; - } - case PP_HTONS(TFTP_ERROR): - if (tftp_state.handle != NULL) - { - pbuf_remove_header(p, TFTP_HEADER_LENGTH); - tftp_state.ctx->error(tftp_state.handle, sbuf[1], (const char *)p->payload, p->len); - close_handle(); - } - break; - default: - send_error(addr, port, TFTP_ERROR_ILLEGAL_OPERATION, "Unknown operation"); - break; - } - - pbuf_free(p); -} - -static void -tftp_tmr(void *arg) -{ - LWIP_UNUSED_ARG(arg); - - tftp_state.timer++; - - if (tftp_state.handle == NULL) - { - return; - } - - sys_timeout(TFTP_TIMER_MSECS, tftp_tmr, NULL); - - if ((tftp_state.timer - tftp_state.last_pkt) > (TFTP_TIMEOUT_MSECS / TFTP_TIMER_MSECS)) - { - if ((tftp_state.last_data != NULL) && (tftp_state.retries < TFTP_MAX_RETRIES)) - { - LWIP_DEBUGF(TFTP_DEBUG | LWIP_DBG_STATE, ("tftp: timeout, retrying\n")); - resend_data(&tftp_state.addr, tftp_state.port); - tftp_state.retries++; - } - else - { - LWIP_DEBUGF(TFTP_DEBUG | LWIP_DBG_STATE, ("tftp: timeout\n")); - close_handle(); - } - } -} - -/** - * Initialize TFTP client/server. - * @param mode TFTP mode (client/server) - * @param ctx TFTP callback struct - */ -err_t tftp_init_common(u8_t mode, const struct tftp_context *ctx) -{ - err_t ret; - - /* LWIP_ASSERT_CORE_LOCKED(); is checked by udp_new() */ - struct udp_pcb *pcb = udp_new_ip_type(IPADDR_TYPE_ANY); - if (pcb == NULL) - { - return ERR_MEM; - } - - ret = udp_bind(pcb, IP_ANY_TYPE, TFTP_PORT); - if (ret != ERR_OK) - { - udp_remove(pcb); - return ret; - } - - tftp_state.handle = NULL; - tftp_state.port = 0; - tftp_state.ctx = ctx; - tftp_state.timer = 0; - tftp_state.last_data = NULL; /* last data, 为了符合tftp的重传机制 */ - tftp_state.upcb = pcb; - tftp_state.tftp_mode = mode; - - /* 注册接收回调函数 */ - udp_recv(pcb, tftp_recv, NULL); - - return ERR_OK; -} - -/** @ingroup tftp - * Initialize TFTP server. - * @param ctx TFTP callback struct - */ -err_t tftp_init_server(const struct tftp_context *ctx) -{ - return tftp_init_common(LWIP_TFTP_MODE_SERVER, ctx); -} - -/** @ingroup tftp - * Initialize TFTP client. - * @param ctx TFTP callback struct - */ -err_t tftp_init_client(const struct tftp_context *ctx) -{ - return tftp_init_common(LWIP_TFTP_MODE_CLIENT, ctx); -} - -/** @ingroup tftp - * Deinitialize ("turn off") TFTP client/server. - */ -void tftp_cleanup(void) -{ - LWIP_ASSERT("Cleanup called on non-initialized TFTP", tftp_state.upcb != NULL); - udp_remove(tftp_state.upcb); - close_handle(); - memset(&tftp_state, 0, sizeof(tftp_state)); -} - -static const char * -mode_to_string(enum tftp_transfer_mode mode) -{ - if (mode == TFTP_MODE_OCTET) - { - return "octet"; - } - if (mode == TFTP_MODE_NETASCII) - { - return "netascii"; - } - if (mode == TFTP_MODE_BINARY) - { - return "binary"; - } - return NULL; -} - -err_t tftp_get(void *handle, const ip_addr_t *addr, u16_t port, const char *fname, enum tftp_transfer_mode mode) -{ - LWIP_ERROR("TFTP client is not enabled (tftp_init)", (tftp_state.tftp_mode & LWIP_TFTP_MODE_CLIENT) != 0, return ERR_VAL); - LWIP_ERROR("tftp_get: invalid file name", fname != NULL, return ERR_VAL); - LWIP_ERROR("tftp_get: invalid mode", mode <= TFTP_MODE_BINARY, return ERR_VAL); - - tftp_state.handle = handle; - tftp_state.blknum = 1; - tftp_state.mode_write = 1; /* We want to receive data */ - return send_request(addr, port, TFTP_RRQ, fname, mode_to_string(mode)); -} - -err_t tftp_put(void *handle, const ip_addr_t *addr, u16_t port, const char *fname, enum tftp_transfer_mode mode) -{ - LWIP_ERROR("TFTP client is not enabled (tftp_init)", (tftp_state.tftp_mode & LWIP_TFTP_MODE_CLIENT) != 0, return ERR_VAL); - LWIP_ERROR("tftp_put: invalid file name", fname != NULL, return ERR_VAL); - LWIP_ERROR("tftp_put: invalid mode", mode <= TFTP_MODE_BINARY, return ERR_VAL); - - tftp_state.handle = handle; - tftp_state.blknum = 1; - tftp_state.mode_write = 0; /* We want to send data */ - return send_request(addr, port, TFTP_WRQ, fname, mode_to_string(mode)); -} - -#endif /* LWIP_UDP */ diff --git a/third-party/lwip-2.1.2/apps/tftp/tftp_client.h b/third-party/lwip-2.1.2/apps/tftp/tftp_client.h deleted file mode 100644 index 753b3459..00000000 --- a/third-party/lwip-2.1.2/apps/tftp/tftp_client.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright : (C) 2022 Phytium Information Technology, Inc. - * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * - * FilePath: tftp_client.h - * Date: 2022-04-02 16:18:06 - * LastEditTime: 2022-04-22 17:07:46 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- - */ -/** - * - * @file tftp_client.h - * TFTP client header - * - */ - -/* - * Redistribution and use in source and binary forms, with or without - * modification,are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#ifndef LWIP_HDR_APPS_TFTP_CLIENT_H -#define LWIP_HDR_APPS_TFTP_CLIENT_H - -#include "tftp_common.h" - -enum tftp_transfer_mode { - TFTP_MODE_OCTET, - TFTP_MODE_NETASCII, - TFTP_MODE_BINARY /* used in old versions only */ -}; - -err_t tftp_init_client(const struct tftp_context* ctx); -err_t tftp_get(void* handle, const ip_addr_t *addr, u16_t port, const char* fname, enum tftp_transfer_mode mode); -err_t tftp_put(void* handle, const ip_addr_t *addr, u16_t port, const char* fname, enum tftp_transfer_mode mode); - -#endif /* LWIP_HDR_APPS_TFTP_CLIENT_H */ diff --git a/third-party/lwip-2.1.2/apps/tftp/tftp_common.h b/third-party/lwip-2.1.2/apps/tftp/tftp_common.h deleted file mode 100644 index 08deb1bc..00000000 --- a/third-party/lwip-2.1.2/apps/tftp/tftp_common.h +++ /dev/null @@ -1,108 +0,0 @@ -/** - * - * @file tftp_common.h - * - * @author Logan Gunthorpe - * - * @brief Trivial File Transfer Protocol (RFC 1350) - * - * Copyright (c) Deltatee Enterprises Ltd. 2013 - * All rights reserved. - * - */ - -/* - * Redistribution and use in source and binary forms, with or without - * modification,are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Author: Logan Gunthorpe - * - */ - -#ifndef LWIP_HDR_APPS_TFTP_COMMON_H -#define LWIP_HDR_APPS_TFTP_COMMON_H - -#include "tftp_opts.h" -#include "lwip/err.h" -#include "lwip/pbuf.h" -#include "lwip/ip_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** @ingroup tftp - * TFTP context containing callback functions for TFTP transfers - */ -struct tftp_context { - /** - * Open file for read/write (server mode only). - * @param fname Filename - * @param mode Mode string from TFTP RFC 1350 (netascii, octet, mail) - * @param write Flag indicating read (0) or write (!= 0) access - * @returns File handle supplied to other functions - */ - void* (*open)(const char* fname, const char* mode, u8_t write); - /** - * Close file handle - * @param handle File handle returned by open()/tftp_put()/tftp_get() - */ - void (*close)(void* handle); - /** - * Read from file - * @param handle File handle returned by open()/tftp_put()/tftp_get() - * @param buf Target buffer to copy read data to - * @param bytes Number of bytes to copy to buf - * @returns >= 0: Success; < 0: Error - */ - int (*read)(void* handle, void* buf, int bytes); - /** - * Write to file - * @param handle File handle returned by open()/tftp_put()/tftp_get() - * @param pbuf PBUF adjusted such that payload pointer points - * to the beginning of write data. In other words, - * TFTP headers are stripped off. - * @returns >= 0: Success; < 0: Error - */ - int (*write)(void* handle, struct pbuf* p); - /** - * Error indication from client or response from server - * @param handle File handle set by open()/tftp_get()/tftp_put() - * @param err error code from client or server - * @param msg error message from client or server - * @param size size of msg - */ - void (*error)(void* handle, int err, const char* msg, int size); -}; - -#define LWIP_TFTP_MODE_SERVER 0x01 -#define LWIP_TFTP_MODE_CLIENT 0x02 -#define LWIP_TFTP_MODE_CLIENTSERVER (LWIP_TFTP_MODE_SERVER | LWIP_TFTP_MODE_CLIENT) - -err_t tftp_init_common(u8_t mode, const struct tftp_context* ctx); -void tftp_cleanup(void); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_APPS_TFTP_COMMON_H */ diff --git a/third-party/lwip-2.1.2/apps/tftp/tftp_opts.h b/third-party/lwip-2.1.2/apps/tftp/tftp_opts.h deleted file mode 100644 index 509fabd6..00000000 --- a/third-party/lwip-2.1.2/apps/tftp/tftp_opts.h +++ /dev/null @@ -1,106 +0,0 @@ -/** - * - * @file tftp_opts.h - * - * @author Logan Gunthorpe - * - * @brief Trivial File Transfer Protocol (RFC 1350) implementation options - * - * Copyright (c) Deltatee Enterprises Ltd. 2013 - * All rights reserved. - * - */ - -/* - * Redistribution and use in source and binary forms, with or without - * modification,are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Author: Logan Gunthorpe - * - */ - -#ifndef LWIP_HDR_APPS_TFTP_OPTS_H -#define LWIP_HDR_APPS_TFTP_OPTS_H - -#include "lwip/opt.h" -#include "lwip/prot/iana.h" - -/** - * @defgroup tftp_opts Options - * @ingroup tftp - * @{ - */ - -/** - * Enable TFTP debug messages - */ -#if !defined TFTP_DEBUG || defined __DOXYGEN__ -#define TFTP_DEBUG LWIP_DBG_OFF -#endif - -/** - * TFTP server port - */ -#if !defined TFTP_PORT || defined __DOXYGEN__ -#define TFTP_PORT LWIP_IANA_PORT_TFTP -#endif - -/** - * TFTP timeout - */ -#if !defined TFTP_TIMEOUT_MSECS || defined __DOXYGEN__ -#define TFTP_TIMEOUT_MSECS 10000 -#endif - -/** - * Max. number of retries when a file is read from server - */ -#if !defined TFTP_MAX_RETRIES || defined __DOXYGEN__ -#define TFTP_MAX_RETRIES 5 -#endif - -/** - * TFTP timer cyclic interval - */ -#if !defined TFTP_TIMER_MSECS || defined __DOXYGEN__ -#define TFTP_TIMER_MSECS (TFTP_TIMEOUT_MSECS / 10) -#endif - -/** - * Max. length of TFTP filename - */ -#if !defined TFTP_MAX_FILENAME_LEN || defined __DOXYGEN__ -#define TFTP_MAX_FILENAME_LEN 20 -#endif - -/** - * Max. length of TFTP mode - */ -#if !defined TFTP_MAX_MODE_LEN || defined __DOXYGEN__ -#define TFTP_MAX_MODE_LEN 10 -#endif - -/** - * @} - */ - -#endif /* LWIP_HDR_APPS_TFTP_OPTS_H */ diff --git a/third-party/lwip-2.1.2/apps/tftp/tftp_server.h b/third-party/lwip-2.1.2/apps/tftp/tftp_server.h deleted file mode 100644 index c2577cd2..00000000 --- a/third-party/lwip-2.1.2/apps/tftp/tftp_server.h +++ /dev/null @@ -1,42 +0,0 @@ -/** - * - * @file tftp_server.h - * TFTP server header - * - */ - -/* - * Redistribution and use in source and binary forms, with or without - * modification,are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#ifndef LWIP_HDR_APPS_TFTP_SERVER_H -#define LWIP_HDR_APPS_TFTP_SERVER_H - -#include "tftp_common.h" - -err_t tftp_init_server(const struct tftp_context* ctx); - -#endif /* LWIP_HDR_APPS_TFTP_SERVER_H */ diff --git a/third-party/lwip-2.1.2/core/altcp.c b/third-party/lwip-2.1.2/core/altcp.c deleted file mode 100644 index d46d6cdb..00000000 --- a/third-party/lwip-2.1.2/core/altcp.c +++ /dev/null @@ -1,681 +0,0 @@ -/** - * @file - * @defgroup altcp Application layered TCP Functions - * @ingroup altcp_api - * - * This file contains the common functions for altcp to work. - * For more details see @ref altcp_api. - */ - -/** - * @defgroup altcp_api Application layered TCP Introduction - * @ingroup callbackstyle_api - * - * Overview - * -------- - * altcp (application layered TCP connection API; to be used from TCPIP thread) - * is an abstraction layer that prevents applications linking hard against the - * @ref tcp.h functions while providing the same functionality. It is used to - * e.g. add SSL/TLS (see LWIP_ALTCP_TLS) or proxy-connect support to an application - * written for the tcp callback API without that application knowing the - * protocol details. - * - * * This interface mimics the tcp callback API to the application while preventing - * direct linking (much like virtual functions). - * * This way, an application can make use of other application layer protocols - * on top of TCP without knowing the details (e.g. TLS, proxy connection). - * * This is achieved by simply including "lwip/altcp.h" instead of "lwip/tcp.h", - * replacing "struct tcp_pcb" with "struct altcp_pcb" and prefixing all functions - * with "altcp_" instead of "tcp_". - * - * With altcp support disabled (LWIP_ALTCP==0), applications written against the - * altcp API can still be compiled but are directly linked against the tcp.h - * callback API and then cannot use layered protocols. To minimize code changes - * in this case, the use of altcp_allocators is strongly suggested. - * - * Usage - * ----- - * To make use of this API from an existing tcp raw API application: - * * Include "lwip/altcp.h" instead of "lwip/tcp.h" - * * Replace "struct tcp_pcb" with "struct altcp_pcb" - * * Prefix all called tcp API functions with "altcp_" instead of "tcp_" to link - * against the altcp functions - * * @ref altcp_new (and @ref altcp_new_ip_type/@ref altcp_new_ip6) take - * an @ref altcp_allocator_t as an argument, whereas the original tcp API - * functions take no arguments. - * * An @ref altcp_allocator_t allocator is an object that holds a pointer to an - * allocator object and a corresponding state (e.g. for TLS, the corresponding - * state may hold certificates or keys). This way, the application does not - * even need to know if it uses TLS or pure TCP, this is handled at runtime - * by passing a specific allocator. - * * An application can alternatively bind hard to the altcp_tls API by calling - * @ref altcp_tls_new or @ref altcp_tls_wrap. - * * The TLS layer is not directly implemented by lwIP, but a port to mbedTLS is - * provided. - * * Another altcp layer is proxy-connect to use TLS behind a HTTP proxy (see - * @ref altcp_proxyconnect.h) - * - * altcp_allocator_t - * ----------------- - * An altcp allocator is created by the application by combining an allocator - * callback function and a corresponding state, e.g.:\code{.c} - * static const unsigned char cert[] = {0x2D, ... (see mbedTLS doc for how to create this)}; - * struct altcp_tls_config * conf = altcp_tls_create_config_client(cert, sizeof(cert)); - * altcp_allocator_t tls_allocator = { - * altcp_tls_alloc, conf - * }; - * \endcode - * - * - * struct altcp_tls_config - * ----------------------- - * The struct altcp_tls_config holds state that is needed to create new TLS client - * or server connections (e.g. certificates and private keys). - * - * It is not defined by lwIP itself but by the TLS port (e.g. altcp_tls to mbedTLS - * adaption). However, the parameters used to create it are defined in @ref - * altcp_tls.h (see @ref altcp_tls_create_config_server_privkey_cert for servers - * and @ref altcp_tls_create_config_client/@ref altcp_tls_create_config_client_2wayauth - * for clients). - * - * For mbedTLS, ensure that certificates can be parsed by 'mbedtls_x509_crt_parse()' and - * private keys can be parsed by 'mbedtls_pk_parse_key()'. - */ - -/* - * Copyright (c) 2017 Simon Goldschmidt - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Simon Goldschmidt - * - */ - -#include "lwip/opt.h" - -#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/altcp.h" -#include "lwip/priv/altcp_priv.h" -#include "lwip/altcp_tcp.h" -#include "lwip/tcp.h" -#include "lwip/mem.h" - -#include - -extern const struct altcp_functions altcp_tcp_functions; - -/** - * For altcp layer implementations only: allocate a new struct altcp_pcb from the pool - * and zero the memory - */ -struct altcp_pcb * -altcp_alloc(void) -{ - struct altcp_pcb *ret = (struct altcp_pcb *)memp_malloc(MEMP_ALTCP_PCB); - if (ret != NULL) { - memset(ret, 0, sizeof(struct altcp_pcb)); - } - return ret; -} - -/** - * For altcp layer implementations only: return a struct altcp_pcb to the pool - */ -void -altcp_free(struct altcp_pcb *conn) -{ - if (conn) { - if (conn->fns && conn->fns->dealloc) { - conn->fns->dealloc(conn); - } - memp_free(MEMP_ALTCP_PCB, conn); - } -} - -/** - * @ingroup altcp - * altcp_new_ip6: @ref altcp_new for IPv6 - */ -struct altcp_pcb * -altcp_new_ip6(altcp_allocator_t *allocator) -{ - return altcp_new_ip_type(allocator, IPADDR_TYPE_V6); -} - -/** - * @ingroup altcp - * altcp_new: @ref altcp_new for IPv4 - */ -struct altcp_pcb * -altcp_new(altcp_allocator_t *allocator) -{ - return altcp_new_ip_type(allocator, IPADDR_TYPE_V4); -} - -/** - * @ingroup altcp - * altcp_new_ip_type: called by applications to allocate a new pcb with the help of an - * allocator function. - * - * @param allocator allocator function and argument - * @param ip_type IP version of the pcb (@ref lwip_ip_addr_type) - * @return a new altcp_pcb or NULL on error - */ -struct altcp_pcb * -altcp_new_ip_type(altcp_allocator_t *allocator, u8_t ip_type) -{ - struct altcp_pcb *conn; - if (allocator == NULL) { - /* no allocator given, create a simple TCP connection */ - return altcp_tcp_new_ip_type(ip_type); - } - if (allocator->alloc == NULL) { - /* illegal allocator */ - return NULL; - } - conn = allocator->alloc(allocator->arg, ip_type); - if (conn == NULL) { - /* allocation failed */ - return NULL; - } - return conn; -} - -/** - * @ingroup altcp - * @see tcp_arg() - */ -void -altcp_arg(struct altcp_pcb *conn, void *arg) -{ - if (conn) { - conn->arg = arg; - } -} - -/** - * @ingroup altcp - * @see tcp_accept() - */ -void -altcp_accept(struct altcp_pcb *conn, altcp_accept_fn accept) -{ - if (conn != NULL) { - conn->accept = accept; - } -} - -/** - * @ingroup altcp - * @see tcp_recv() - */ -void -altcp_recv(struct altcp_pcb *conn, altcp_recv_fn recv) -{ - if (conn) { - conn->recv = recv; - } -} - -/** - * @ingroup altcp - * @see tcp_sent() - */ -void -altcp_sent(struct altcp_pcb *conn, altcp_sent_fn sent) -{ - if (conn) { - conn->sent = sent; - } -} - -/** - * @ingroup altcp - * @see tcp_poll() - */ -void -altcp_poll(struct altcp_pcb *conn, altcp_poll_fn poll, u8_t interval) -{ - if (conn) { - conn->poll = poll; - conn->pollinterval = interval; - if (conn->fns && conn->fns->set_poll) { - conn->fns->set_poll(conn, interval); - } - } -} - -/** - * @ingroup altcp - * @see tcp_err() - */ -void -altcp_err(struct altcp_pcb *conn, altcp_err_fn err) -{ - if (conn) { - conn->err = err; - } -} - -/* Generic functions calling the "virtual" ones */ - -/** - * @ingroup altcp - * @see tcp_recved() - */ -void -altcp_recved(struct altcp_pcb *conn, u16_t len) -{ - if (conn && conn->fns && conn->fns->recved) { - conn->fns->recved(conn, len); - } -} - -/** - * @ingroup altcp - * @see tcp_bind() - */ -err_t -altcp_bind(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port) -{ - if (conn && conn->fns && conn->fns->bind) { - return conn->fns->bind(conn, ipaddr, port); - } - return ERR_VAL; -} - -/** - * @ingroup altcp - * @see tcp_connect() - */ -err_t -altcp_connect(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port, altcp_connected_fn connected) -{ - if (conn && conn->fns && conn->fns->connect) { - return conn->fns->connect(conn, ipaddr, port, connected); - } - return ERR_VAL; -} - -/** - * @ingroup altcp - * @see tcp_listen_with_backlog_and_err() - */ -struct altcp_pcb * -altcp_listen_with_backlog_and_err(struct altcp_pcb *conn, u8_t backlog, err_t *err) -{ - if (conn && conn->fns && conn->fns->listen) { - return conn->fns->listen(conn, backlog, err); - } - return NULL; -} - -/** - * @ingroup altcp - * @see tcp_abort() - */ -void -altcp_abort(struct altcp_pcb *conn) -{ - if (conn && conn->fns && conn->fns->abort) { - conn->fns->abort(conn); - } -} - -/** - * @ingroup altcp - * @see tcp_close() - */ -err_t -altcp_close(struct altcp_pcb *conn) -{ - if (conn && conn->fns && conn->fns->close) { - return conn->fns->close(conn); - } - return ERR_VAL; -} - -/** - * @ingroup altcp - * @see tcp_shutdown() - */ -err_t -altcp_shutdown(struct altcp_pcb *conn, int shut_rx, int shut_tx) -{ - if (conn && conn->fns && conn->fns->shutdown) { - return conn->fns->shutdown(conn, shut_rx, shut_tx); - } - return ERR_VAL; -} - -/** - * @ingroup altcp - * @see tcp_write() - */ -err_t -altcp_write(struct altcp_pcb *conn, const void *dataptr, u16_t len, u8_t apiflags) -{ - if (conn && conn->fns && conn->fns->write) { - return conn->fns->write(conn, dataptr, len, apiflags); - } - return ERR_VAL; -} - -/** - * @ingroup altcp - * @see tcp_output() - */ -err_t -altcp_output(struct altcp_pcb *conn) -{ - if (conn && conn->fns && conn->fns->output) { - return conn->fns->output(conn); - } - return ERR_VAL; -} - -/** - * @ingroup altcp - * @see tcp_mss() - */ -u16_t -altcp_mss(struct altcp_pcb *conn) -{ - if (conn && conn->fns && conn->fns->mss) { - return conn->fns->mss(conn); - } - return 0; -} - -/** - * @ingroup altcp - * @see tcp_sndbuf() - */ -u16_t -altcp_sndbuf(struct altcp_pcb *conn) -{ - if (conn && conn->fns && conn->fns->sndbuf) { - return conn->fns->sndbuf(conn); - } - return 0; -} - -/** - * @ingroup altcp - * @see tcp_sndqueuelen() - */ -u16_t -altcp_sndqueuelen(struct altcp_pcb *conn) -{ - if (conn && conn->fns && conn->fns->sndqueuelen) { - return conn->fns->sndqueuelen(conn); - } - return 0; -} - -void -altcp_nagle_disable(struct altcp_pcb *conn) -{ - if (conn && conn->fns && conn->fns->nagle_disable) { - conn->fns->nagle_disable(conn); - } -} - -void -altcp_nagle_enable(struct altcp_pcb *conn) -{ - if (conn && conn->fns && conn->fns->nagle_enable) { - conn->fns->nagle_enable(conn); - } -} - -int -altcp_nagle_disabled(struct altcp_pcb *conn) -{ - if (conn && conn->fns && conn->fns->nagle_disabled) { - return conn->fns->nagle_disabled(conn); - } - return 0; -} - -/** - * @ingroup altcp - * @see tcp_setprio() - */ -void -altcp_setprio(struct altcp_pcb *conn, u8_t prio) -{ - if (conn && conn->fns && conn->fns->setprio) { - conn->fns->setprio(conn, prio); - } -} - -err_t -altcp_get_tcp_addrinfo(struct altcp_pcb *conn, int local, ip_addr_t *addr, u16_t *port) -{ - if (conn && conn->fns && conn->fns->addrinfo) { - return conn->fns->addrinfo(conn, local, addr, port); - } - return ERR_VAL; -} - -ip_addr_t * -altcp_get_ip(struct altcp_pcb *conn, int local) -{ - if (conn && conn->fns && conn->fns->getip) { - return conn->fns->getip(conn, local); - } - return NULL; -} - -u16_t -altcp_get_port(struct altcp_pcb *conn, int local) -{ - if (conn && conn->fns && conn->fns->getport) { - return conn->fns->getport(conn, local); - } - return 0; -} - -#ifdef LWIP_DEBUG -enum tcp_state -altcp_dbg_get_tcp_state(struct altcp_pcb *conn) -{ - if (conn && conn->fns && conn->fns->dbg_get_tcp_state) { - return conn->fns->dbg_get_tcp_state(conn); - } - return CLOSED; -} -#endif - -/* Default implementations for the "virtual" functions */ - -void -altcp_default_set_poll(struct altcp_pcb *conn, u8_t interval) -{ - if (conn && conn->inner_conn) { - altcp_poll(conn->inner_conn, conn->poll, interval); - } -} - -void -altcp_default_recved(struct altcp_pcb *conn, u16_t len) -{ - if (conn && conn->inner_conn) { - altcp_recved(conn->inner_conn, len); - } -} - -err_t -altcp_default_bind(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port) -{ - if (conn && conn->inner_conn) { - return altcp_bind(conn->inner_conn, ipaddr, port); - } - return ERR_VAL; -} - -err_t -altcp_default_shutdown(struct altcp_pcb *conn, int shut_rx, int shut_tx) -{ - if (conn) { - if (shut_rx && shut_tx && conn->fns && conn->fns->close) { - /* default shutdown for both sides is close */ - return conn->fns->close(conn); - } - if (conn->inner_conn) { - return altcp_shutdown(conn->inner_conn, shut_rx, shut_tx); - } - } - return ERR_VAL; -} - -err_t -altcp_default_write(struct altcp_pcb *conn, const void *dataptr, u16_t len, u8_t apiflags) -{ - if (conn && conn->inner_conn) { - return altcp_write(conn->inner_conn, dataptr, len, apiflags); - } - return ERR_VAL; -} - -err_t -altcp_default_output(struct altcp_pcb *conn) -{ - if (conn && conn->inner_conn) { - return altcp_output(conn->inner_conn); - } - return ERR_VAL; -} - -u16_t -altcp_default_mss(struct altcp_pcb *conn) -{ - if (conn && conn->inner_conn) { - return altcp_mss(conn->inner_conn); - } - return 0; -} - -u16_t -altcp_default_sndbuf(struct altcp_pcb *conn) -{ - if (conn && conn->inner_conn) { - return altcp_sndbuf(conn->inner_conn); - } - return 0; -} - -u16_t -altcp_default_sndqueuelen(struct altcp_pcb *conn) -{ - if (conn && conn->inner_conn) { - return altcp_sndqueuelen(conn->inner_conn); - } - return 0; -} - -void -altcp_default_nagle_disable(struct altcp_pcb *conn) -{ - if (conn && conn->inner_conn) { - altcp_nagle_disable(conn->inner_conn); - } -} - -void -altcp_default_nagle_enable(struct altcp_pcb *conn) -{ - if (conn && conn->inner_conn) { - altcp_nagle_enable(conn->inner_conn); - } -} - -int -altcp_default_nagle_disabled(struct altcp_pcb *conn) -{ - if (conn && conn->inner_conn) { - return altcp_nagle_disabled(conn->inner_conn); - } - return 0; -} - -void -altcp_default_setprio(struct altcp_pcb *conn, u8_t prio) -{ - if (conn && conn->inner_conn) { - altcp_setprio(conn->inner_conn, prio); - } -} - -void -altcp_default_dealloc(struct altcp_pcb *conn) -{ - LWIP_UNUSED_ARG(conn); - /* nothing to do */ -} - -err_t -altcp_default_get_tcp_addrinfo(struct altcp_pcb *conn, int local, ip_addr_t *addr, u16_t *port) -{ - if (conn && conn->inner_conn) { - return altcp_get_tcp_addrinfo(conn->inner_conn, local, addr, port); - } - return ERR_VAL; -} - -ip_addr_t * -altcp_default_get_ip(struct altcp_pcb *conn, int local) -{ - if (conn && conn->inner_conn) { - return altcp_get_ip(conn->inner_conn, local); - } - return NULL; -} - -u16_t -altcp_default_get_port(struct altcp_pcb *conn, int local) -{ - if (conn && conn->inner_conn) { - return altcp_get_port(conn->inner_conn, local); - } - return 0; -} - -#ifdef LWIP_DEBUG -enum tcp_state -altcp_default_dbg_get_tcp_state(struct altcp_pcb *conn) -{ - if (conn && conn->inner_conn) { - return altcp_dbg_get_tcp_state(conn->inner_conn); - } - return CLOSED; -} -#endif - - -#endif /* LWIP_ALTCP */ diff --git a/third-party/lwip-2.1.2/core/altcp_alloc.c b/third-party/lwip-2.1.2/core/altcp_alloc.c deleted file mode 100644 index cd619bc1..00000000 --- a/third-party/lwip-2.1.2/core/altcp_alloc.c +++ /dev/null @@ -1,87 +0,0 @@ -/** - * @file - * Application layered TCP connection API (to be used from TCPIP thread)\n - * This interface mimics the tcp callback API to the application while preventing - * direct linking (much like virtual functions). - * This way, an application can make use of other application layer protocols - * on top of TCP without knowing the details (e.g. TLS, proxy connection). - * - * This file contains allocation implementation that combine several layers. - */ - -/* - * Copyright (c) 2017 Simon Goldschmidt - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Simon Goldschmidt - * - */ - -#include "lwip/opt.h" - -#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/altcp.h" -#include "lwip/altcp_tcp.h" -#include "lwip/altcp_tls.h" -#include "lwip/priv/altcp_priv.h" -#include "lwip/mem.h" - -#include - -#if LWIP_ALTCP_TLS - -/** This standard allocator function creates an altcp pcb for - * TLS over TCP */ -struct altcp_pcb * -altcp_tls_new(struct altcp_tls_config *config, u8_t ip_type) -{ - struct altcp_pcb *inner_conn, *ret; - LWIP_UNUSED_ARG(ip_type); - - inner_conn = altcp_tcp_new_ip_type(ip_type); - if (inner_conn == NULL) { - return NULL; - } - ret = altcp_tls_wrap(config, inner_conn); - if (ret == NULL) { - altcp_close(inner_conn); - } - return ret; -} - -/** This standard allocator function creates an altcp pcb for - * TLS over TCP */ -struct altcp_pcb * -altcp_tls_alloc(void *arg, u8_t ip_type) -{ - return altcp_tls_new((struct altcp_tls_config *)arg, ip_type); -} - -#endif /* LWIP_ALTCP_TLS */ - -#endif /* LWIP_ALTCP */ diff --git a/third-party/lwip-2.1.2/core/altcp_tcp.c b/third-party/lwip-2.1.2/core/altcp_tcp.c deleted file mode 100644 index b715f045..00000000 --- a/third-party/lwip-2.1.2/core/altcp_tcp.c +++ /dev/null @@ -1,543 +0,0 @@ -/** - * @file - * Application layered TCP connection API (to be used from TCPIP thread)\n - * This interface mimics the tcp callback API to the application while preventing - * direct linking (much like virtual functions). - * This way, an application can make use of other application layer protocols - * on top of TCP without knowing the details (e.g. TLS, proxy connection). - * - * This file contains the base implementation calling into tcp. - */ - -/* - * Copyright (c) 2017 Simon Goldschmidt - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Simon Goldschmidt - * - */ - -#include "lwip/opt.h" - -#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/altcp.h" -#include "lwip/altcp_tcp.h" -#include "lwip/priv/altcp_priv.h" -#include "lwip/tcp.h" -#include "lwip/mem.h" - -#include - -#define ALTCP_TCP_ASSERT_CONN(conn) do { \ - LWIP_ASSERT("conn->inner_conn == NULL", (conn)->inner_conn == NULL); \ - LWIP_UNUSED_ARG(conn); /* for LWIP_NOASSERT */ } while(0) -#define ALTCP_TCP_ASSERT_CONN_PCB(conn, tpcb) do { \ - LWIP_ASSERT("pcb mismatch", (conn)->state == tpcb); \ - LWIP_UNUSED_ARG(tpcb); /* for LWIP_NOASSERT */ \ - ALTCP_TCP_ASSERT_CONN(conn); } while(0) - - -/* Variable prototype, the actual declaration is at the end of this file - since it contains pointers to static functions declared here */ -extern const struct altcp_functions altcp_tcp_functions; - -static void altcp_tcp_setup(struct altcp_pcb *conn, struct tcp_pcb *tpcb); - -/* callback functions for TCP */ -static err_t -altcp_tcp_accept(void *arg, struct tcp_pcb *new_tpcb, err_t err) -{ - struct altcp_pcb *listen_conn = (struct altcp_pcb *)arg; - if (listen_conn && listen_conn->accept) { - /* create a new altcp_conn to pass to the next 'accept' callback */ - struct altcp_pcb *new_conn = altcp_alloc(); - if (new_conn == NULL) { - return ERR_MEM; - } - altcp_tcp_setup(new_conn, new_tpcb); - return listen_conn->accept(listen_conn->arg, new_conn, err); - } - return ERR_ARG; -} - -static err_t -altcp_tcp_connected(void *arg, struct tcp_pcb *tpcb, err_t err) -{ - struct altcp_pcb *conn = (struct altcp_pcb *)arg; - if (conn) { - ALTCP_TCP_ASSERT_CONN_PCB(conn, tpcb); - if (conn->connected) { - return conn->connected(conn->arg, conn, err); - } - } - return ERR_OK; -} - -static err_t -altcp_tcp_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) -{ - struct altcp_pcb *conn = (struct altcp_pcb *)arg; - if (conn) { - ALTCP_TCP_ASSERT_CONN_PCB(conn, tpcb); - if (conn->recv) { - return conn->recv(conn->arg, conn, p, err); - } - } - if (p != NULL) { - /* prevent memory leaks */ - pbuf_free(p); - } - return ERR_OK; -} - -static err_t -altcp_tcp_sent(void *arg, struct tcp_pcb *tpcb, u16_t len) -{ - struct altcp_pcb *conn = (struct altcp_pcb *)arg; - if (conn) { - ALTCP_TCP_ASSERT_CONN_PCB(conn, tpcb); - if (conn->sent) { - return conn->sent(conn->arg, conn, len); - } - } - return ERR_OK; -} - -static err_t -altcp_tcp_poll(void *arg, struct tcp_pcb *tpcb) -{ - struct altcp_pcb *conn = (struct altcp_pcb *)arg; - if (conn) { - ALTCP_TCP_ASSERT_CONN_PCB(conn, tpcb); - if (conn->poll) { - return conn->poll(conn->arg, conn); - } - } - return ERR_OK; -} - -static void -altcp_tcp_err(void *arg, err_t err) -{ - struct altcp_pcb *conn = (struct altcp_pcb *)arg; - if (conn) { - conn->state = NULL; /* already freed */ - if (conn->err) { - conn->err(conn->arg, err); - } - altcp_free(conn); - } -} - -/* setup functions */ - -static void -altcp_tcp_remove_callbacks(struct tcp_pcb *tpcb) -{ - tcp_arg(tpcb, NULL); - tcp_recv(tpcb, NULL); - tcp_sent(tpcb, NULL); - tcp_err(tpcb, NULL); - tcp_poll(tpcb, NULL, tpcb->pollinterval); -} - -static void -altcp_tcp_setup_callbacks(struct altcp_pcb *conn, struct tcp_pcb *tpcb) -{ - tcp_arg(tpcb, conn); - tcp_recv(tpcb, altcp_tcp_recv); - tcp_sent(tpcb, altcp_tcp_sent); - tcp_err(tpcb, altcp_tcp_err); - /* tcp_poll is set when interval is set by application */ - /* listen is set totally different :-) */ -} - -static void -altcp_tcp_setup(struct altcp_pcb *conn, struct tcp_pcb *tpcb) -{ - altcp_tcp_setup_callbacks(conn, tpcb); - conn->state = tpcb; - conn->fns = &altcp_tcp_functions; -} - -struct altcp_pcb * -altcp_tcp_new_ip_type(u8_t ip_type) -{ - /* Allocate the tcp pcb first to invoke the priority handling code - if we're out of pcbs */ - struct tcp_pcb *tpcb = tcp_new_ip_type(ip_type); - if (tpcb != NULL) { - struct altcp_pcb *ret = altcp_alloc(); - if (ret != NULL) { - altcp_tcp_setup(ret, tpcb); - return ret; - } else { - /* altcp_pcb allocation failed -> free the tcp_pcb too */ - tcp_close(tpcb); - } - } - return NULL; -} - -/** altcp_tcp allocator function fitting to @ref altcp_allocator_t / @ref altcp_new. -* -* arg pointer is not used for TCP. -*/ -struct altcp_pcb * -altcp_tcp_alloc(void *arg, u8_t ip_type) -{ - LWIP_UNUSED_ARG(arg); - return altcp_tcp_new_ip_type(ip_type); -} - -struct altcp_pcb * -altcp_tcp_wrap(struct tcp_pcb *tpcb) -{ - if (tpcb != NULL) { - struct altcp_pcb *ret = altcp_alloc(); - if (ret != NULL) { - altcp_tcp_setup(ret, tpcb); - return ret; - } - } - return NULL; -} - - -/* "virtual" functions calling into tcp */ -static void -altcp_tcp_set_poll(struct altcp_pcb *conn, u8_t interval) -{ - if (conn != NULL) { - struct tcp_pcb *pcb = (struct tcp_pcb *)conn->state; - ALTCP_TCP_ASSERT_CONN(conn); - tcp_poll(pcb, altcp_tcp_poll, interval); - } -} - -static void -altcp_tcp_recved(struct altcp_pcb *conn, u16_t len) -{ - if (conn != NULL) { - struct tcp_pcb *pcb = (struct tcp_pcb *)conn->state; - ALTCP_TCP_ASSERT_CONN(conn); - tcp_recved(pcb, len); - } -} - -static err_t -altcp_tcp_bind(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port) -{ - struct tcp_pcb *pcb; - if (conn == NULL) { - return ERR_VAL; - } - ALTCP_TCP_ASSERT_CONN(conn); - pcb = (struct tcp_pcb *)conn->state; - return tcp_bind(pcb, ipaddr, port); -} - -static err_t -altcp_tcp_connect(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port, altcp_connected_fn connected) -{ - struct tcp_pcb *pcb; - if (conn == NULL) { - return ERR_VAL; - } - ALTCP_TCP_ASSERT_CONN(conn); - conn->connected = connected; - pcb = (struct tcp_pcb *)conn->state; - return tcp_connect(pcb, ipaddr, port, altcp_tcp_connected); -} - -static struct altcp_pcb * -altcp_tcp_listen(struct altcp_pcb *conn, u8_t backlog, err_t *err) -{ - struct tcp_pcb *pcb; - struct tcp_pcb *lpcb; - if (conn == NULL) { - return NULL; - } - ALTCP_TCP_ASSERT_CONN(conn); - pcb = (struct tcp_pcb *)conn->state; - lpcb = tcp_listen_with_backlog_and_err(pcb, backlog, err); - if (lpcb != NULL) { - conn->state = lpcb; - tcp_accept(lpcb, altcp_tcp_accept); - return conn; - } - return NULL; -} - -static void -altcp_tcp_abort(struct altcp_pcb *conn) -{ - if (conn != NULL) { - struct tcp_pcb *pcb = (struct tcp_pcb *)conn->state; - ALTCP_TCP_ASSERT_CONN(conn); - if (pcb) { - tcp_abort(pcb); - } - } -} - -static err_t -altcp_tcp_close(struct altcp_pcb *conn) -{ - struct tcp_pcb *pcb; - if (conn == NULL) { - return ERR_VAL; - } - ALTCP_TCP_ASSERT_CONN(conn); - pcb = (struct tcp_pcb *)conn->state; - if (pcb) { - err_t err; - tcp_poll_fn oldpoll = pcb->poll; - altcp_tcp_remove_callbacks(pcb); - err = tcp_close(pcb); - if (err != ERR_OK) { - /* not closed, set up all callbacks again */ - altcp_tcp_setup_callbacks(conn, pcb); - /* poll callback is not included in the above */ - tcp_poll(pcb, oldpoll, pcb->pollinterval); - return err; - } - conn->state = NULL; /* unsafe to reference pcb after tcp_close(). */ - } - altcp_free(conn); - return ERR_OK; -} - -static err_t -altcp_tcp_shutdown(struct altcp_pcb *conn, int shut_rx, int shut_tx) -{ - struct tcp_pcb *pcb; - if (conn == NULL) { - return ERR_VAL; - } - ALTCP_TCP_ASSERT_CONN(conn); - pcb = (struct tcp_pcb *)conn->state; - return tcp_shutdown(pcb, shut_rx, shut_tx); -} - -static err_t -altcp_tcp_write(struct altcp_pcb *conn, const void *dataptr, u16_t len, u8_t apiflags) -{ - struct tcp_pcb *pcb; - if (conn == NULL) { - return ERR_VAL; - } - ALTCP_TCP_ASSERT_CONN(conn); - pcb = (struct tcp_pcb *)conn->state; - return tcp_write(pcb, dataptr, len, apiflags); -} - -static err_t -altcp_tcp_output(struct altcp_pcb *conn) -{ - struct tcp_pcb *pcb; - if (conn == NULL) { - return ERR_VAL; - } - ALTCP_TCP_ASSERT_CONN(conn); - pcb = (struct tcp_pcb *)conn->state; - return tcp_output(pcb); -} - -static u16_t -altcp_tcp_mss(struct altcp_pcb *conn) -{ - struct tcp_pcb *pcb; - if (conn == NULL) { - return 0; - } - ALTCP_TCP_ASSERT_CONN(conn); - pcb = (struct tcp_pcb *)conn->state; - return tcp_mss(pcb); -} - -static u16_t -altcp_tcp_sndbuf(struct altcp_pcb *conn) -{ - struct tcp_pcb *pcb; - if (conn == NULL) { - return 0; - } - ALTCP_TCP_ASSERT_CONN(conn); - pcb = (struct tcp_pcb *)conn->state; - return tcp_sndbuf(pcb); -} - -static u16_t -altcp_tcp_sndqueuelen(struct altcp_pcb *conn) -{ - struct tcp_pcb *pcb; - if (conn == NULL) { - return 0; - } - ALTCP_TCP_ASSERT_CONN(conn); - pcb = (struct tcp_pcb *)conn->state; - return tcp_sndqueuelen(pcb); -} - -static void -altcp_tcp_nagle_disable(struct altcp_pcb *conn) -{ - if (conn && conn->state) { - struct tcp_pcb *pcb = (struct tcp_pcb *)conn->state; - ALTCP_TCP_ASSERT_CONN(conn); - tcp_nagle_disable(pcb); - } -} - -static void -altcp_tcp_nagle_enable(struct altcp_pcb *conn) -{ - if (conn && conn->state) { - struct tcp_pcb *pcb = (struct tcp_pcb *)conn->state; - ALTCP_TCP_ASSERT_CONN(conn); - tcp_nagle_enable(pcb); - } -} - -static int -altcp_tcp_nagle_disabled(struct altcp_pcb *conn) -{ - if (conn && conn->state) { - struct tcp_pcb *pcb = (struct tcp_pcb *)conn->state; - ALTCP_TCP_ASSERT_CONN(conn); - return tcp_nagle_disabled(pcb); - } - return 0; -} - -static void -altcp_tcp_setprio(struct altcp_pcb *conn, u8_t prio) -{ - if (conn != NULL) { - struct tcp_pcb *pcb = (struct tcp_pcb *)conn->state; - ALTCP_TCP_ASSERT_CONN(conn); - tcp_setprio(pcb, prio); - } -} - -static void -altcp_tcp_dealloc(struct altcp_pcb *conn) -{ - LWIP_UNUSED_ARG(conn); - ALTCP_TCP_ASSERT_CONN(conn); - /* no private state to clean up */ -} - -static err_t -altcp_tcp_get_tcp_addrinfo(struct altcp_pcb *conn, int local, ip_addr_t *addr, u16_t *port) -{ - if (conn) { - struct tcp_pcb *pcb = (struct tcp_pcb *)conn->state; - ALTCP_TCP_ASSERT_CONN(conn); - return tcp_tcp_get_tcp_addrinfo(pcb, local, addr, port); - } - return ERR_VAL; -} - -static ip_addr_t * -altcp_tcp_get_ip(struct altcp_pcb *conn, int local) -{ - if (conn) { - struct tcp_pcb *pcb = (struct tcp_pcb *)conn->state; - ALTCP_TCP_ASSERT_CONN(conn); - if (pcb) { - if (local) { - return &pcb->local_ip; - } else { - return &pcb->remote_ip; - } - } - } - return NULL; -} - -static u16_t -altcp_tcp_get_port(struct altcp_pcb *conn, int local) -{ - if (conn) { - struct tcp_pcb *pcb = (struct tcp_pcb *)conn->state; - ALTCP_TCP_ASSERT_CONN(conn); - if (pcb) { - if (local) { - return pcb->local_port; - } else { - return pcb->remote_port; - } - } - } - return 0; -} - -#ifdef LWIP_DEBUG -static enum tcp_state -altcp_tcp_dbg_get_tcp_state(struct altcp_pcb *conn) -{ - if (conn) { - struct tcp_pcb *pcb = (struct tcp_pcb *)conn->state; - ALTCP_TCP_ASSERT_CONN(conn); - if (pcb) { - return pcb->state; - } - } - return CLOSED; -} -#endif -const struct altcp_functions altcp_tcp_functions = { - altcp_tcp_set_poll, - altcp_tcp_recved, - altcp_tcp_bind, - altcp_tcp_connect, - altcp_tcp_listen, - altcp_tcp_abort, - altcp_tcp_close, - altcp_tcp_shutdown, - altcp_tcp_write, - altcp_tcp_output, - altcp_tcp_mss, - altcp_tcp_sndbuf, - altcp_tcp_sndqueuelen, - altcp_tcp_nagle_disable, - altcp_tcp_nagle_enable, - altcp_tcp_nagle_disabled, - altcp_tcp_setprio, - altcp_tcp_dealloc, - altcp_tcp_get_tcp_addrinfo, - altcp_tcp_get_ip, - altcp_tcp_get_port -#ifdef LWIP_DEBUG - , altcp_tcp_dbg_get_tcp_state -#endif -}; - -#endif /* LWIP_ALTCP */ diff --git a/third-party/lwip-2.1.2/core/def.c b/third-party/lwip-2.1.2/core/def.c deleted file mode 100644 index 9da36fee..00000000 --- a/third-party/lwip-2.1.2/core/def.c +++ /dev/null @@ -1,240 +0,0 @@ -/** - * @file - * Common functions used throughout the stack. - * - * These are reference implementations of the byte swapping functions. - * Again with the aim of being simple, correct and fully portable. - * Byte swapping is the second thing you would want to optimize. You will - * need to port it to your architecture and in your cc.h: - * - * \#define lwip_htons(x) your_htons - * \#define lwip_htonl(x) your_htonl - * - * Note lwip_ntohs() and lwip_ntohl() are merely references to the htonx counterparts. - * - * If you \#define them to htons() and htonl(), you should - * \#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS to prevent lwIP from - * defining htonx/ntohx compatibility macros. - - * @defgroup sys_nonstandard Non-standard functions - * @ingroup sys_layer - * lwIP provides default implementations for non-standard functions. - * These can be mapped to OS functions to reduce code footprint if desired. - * All defines related to this section must not be placed in lwipopts.h, - * but in arch/cc.h! - * These options cannot be \#defined in lwipopts.h since they are not options - * of lwIP itself, but options of the lwIP port to your system. - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Simon Goldschmidt - * - */ - -#include "lwip/opt.h" -#include "lwip/def.h" - -#include - -#if BYTE_ORDER == LITTLE_ENDIAN - -#if !defined(lwip_htons) -/** - * Convert an u16_t from host- to network byte order. - * - * @param n u16_t in host byte order - * @return n in network byte order - */ -u16_t -lwip_htons(u16_t n) -{ - return PP_HTONS(n); -} -#endif /* lwip_htons */ - -#if !defined(lwip_htonl) -/** - * Convert an u32_t from host- to network byte order. - * - * @param n u32_t in host byte order - * @return n in network byte order - */ -u32_t -lwip_htonl(u32_t n) -{ - return PP_HTONL(n); -} -#endif /* lwip_htonl */ - -#endif /* BYTE_ORDER == LITTLE_ENDIAN */ - -#ifndef lwip_strnstr -/** - * @ingroup sys_nonstandard - * lwIP default implementation for strnstr() non-standard function. - * This can be \#defined to strnstr() depending on your platform port. - */ -char * -lwip_strnstr(const char *buffer, const char *token, size_t n) -{ - const char *p; - size_t tokenlen = strlen(token); - if (tokenlen == 0) { - return LWIP_CONST_CAST(char *, buffer); - } - for (p = buffer; *p && (p + tokenlen <= buffer + n); p++) { - if ((*p == *token) && (strncmp(p, token, tokenlen) == 0)) { - return LWIP_CONST_CAST(char *, p); - } - } - return NULL; -} -#endif - -#ifndef lwip_stricmp -/** - * @ingroup sys_nonstandard - * lwIP default implementation for stricmp() non-standard function. - * This can be \#defined to stricmp() depending on your platform port. - */ -int -lwip_stricmp(const char *str1, const char *str2) -{ - char c1, c2; - - do { - c1 = *str1++; - c2 = *str2++; - if (c1 != c2) { - char c1_upc = c1 | 0x20; - if ((c1_upc >= 'a') && (c1_upc <= 'z')) { - /* characters are not equal an one is in the alphabet range: - downcase both chars and check again */ - char c2_upc = c2 | 0x20; - if (c1_upc != c2_upc) { - /* still not equal */ - /* don't care for < or > */ - return 1; - } - } else { - /* characters are not equal but none is in the alphabet range */ - return 1; - } - } - } while (c1 != 0); - return 0; -} -#endif - -#ifndef lwip_strnicmp -/** - * @ingroup sys_nonstandard - * lwIP default implementation for strnicmp() non-standard function. - * This can be \#defined to strnicmp() depending on your platform port. - */ -int -lwip_strnicmp(const char *str1, const char *str2, size_t len) -{ - char c1, c2; - - do { - c1 = *str1++; - c2 = *str2++; - if (c1 != c2) { - char c1_upc = c1 | 0x20; - if ((c1_upc >= 'a') && (c1_upc <= 'z')) { - /* characters are not equal an one is in the alphabet range: - downcase both chars and check again */ - char c2_upc = c2 | 0x20; - if (c1_upc != c2_upc) { - /* still not equal */ - /* don't care for < or > */ - return 1; - } - } else { - /* characters are not equal but none is in the alphabet range */ - return 1; - } - } - len--; - } while ((len != 0) && (c1 != 0)); - return 0; -} -#endif - -#ifndef lwip_itoa -/** - * @ingroup sys_nonstandard - * lwIP default implementation for itoa() non-standard function. - * This can be \#defined to itoa() or snprintf(result, bufsize, "%d", number) depending on your platform port. - */ -void -lwip_itoa(char *result, size_t bufsize, int number) -{ - char *res = result; - char *tmp = result + bufsize - 1; - int n = (number >= 0) ? number : -number; - - /* handle invalid bufsize */ - if (bufsize < 2) { - if (bufsize == 1) { - *result = 0; - } - return; - } - - /* First, add sign */ - if (number < 0) { - *res++ = '-'; - } - /* Then create the string from the end and stop if buffer full, - and ensure output string is zero terminated */ - *tmp = 0; - while ((n != 0) && (tmp > res)) { - char val = (char)('0' + (n % 10)); - tmp--; - *tmp = val; - n = n / 10; - } - if (n) { - /* buffer is too small */ - *result = 0; - return; - } - if (*tmp == 0) { - /* Nothing added? */ - *res++ = '0'; - *res++ = 0; - return; - } - /* move from temporary buffer to output buffer (sign is not moved) */ - memmove(res, tmp, (size_t)((result + bufsize) - tmp)); -} -#endif diff --git a/third-party/lwip-2.1.2/core/dns.c b/third-party/lwip-2.1.2/core/dns.c deleted file mode 100644 index 9d2f61ed..00000000 --- a/third-party/lwip-2.1.2/core/dns.c +++ /dev/null @@ -1,1631 +0,0 @@ -/** - * @file - * DNS - host name to IP address resolver. - * - * @defgroup dns DNS - * @ingroup callbackstyle_api - * - * Implements a DNS host name to IP address resolver. - * - * The lwIP DNS resolver functions are used to lookup a host name and - * map it to a numerical IP address. It maintains a list of resolved - * hostnames that can be queried with the dns_lookup() function. - * New hostnames can be resolved using the dns_query() function. - * - * The lwIP version of the resolver also adds a non-blocking version of - * gethostbyname() that will work with a raw API application. This function - * checks for an IP address string first and converts it if it is valid. - * gethostbyname() then does a dns_lookup() to see if the name is - * already in the table. If so, the IP is returned. If not, a query is - * issued and the function returns with a ERR_INPROGRESS status. The app - * using the dns client must then go into a waiting state. - * - * Once a hostname has been resolved (or found to be non-existent), - * the resolver code calls a specified callback function (which - * must be implemented by the module that uses the resolver). - * - * Multicast DNS queries are supported for names ending on ".local". - * However, only "One-Shot Multicast DNS Queries" are supported (RFC 6762 - * chapter 5.1), this is not a fully compliant implementation of continuous - * mDNS querying! - * - * All functions must be called from TCPIP thread. - * - * @see DNS_MAX_SERVERS - * @see LWIP_DHCP_MAX_DNS_SERVERS - * @see @ref netconn_common for thread-safe access. - */ - -/* - * Port to lwIP from uIP - * by Jim Pettinato April 2007 - * - * security fixes and more by Simon Goldschmidt - * - * uIP version Copyright (c) 2002-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/*----------------------------------------------------------------------------- - * RFC 1035 - Domain names - implementation and specification - * RFC 2181 - Clarifications to the DNS Specification - *----------------------------------------------------------------------------*/ - -/** @todo: define good default values (rfc compliance) */ -/** @todo: improve answer parsing, more checkings... */ -/** @todo: check RFC1035 - 7.3. Processing responses */ -/** @todo: one-shot mDNS: dual-stack fallback to another IP version */ - -/*----------------------------------------------------------------------------- - * Includes - *----------------------------------------------------------------------------*/ - -#include "lwip/opt.h" - -#if LWIP_DNS /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/def.h" -#include "lwip/udp.h" -#include "lwip/mem.h" -#include "lwip/memp.h" -#include "lwip/dns.h" -#include "lwip/prot/dns.h" - -#include - -/** Random generator function to create random TXIDs and source ports for queries */ -#ifndef DNS_RAND_TXID -#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_XID) != 0) -#define DNS_RAND_TXID LWIP_RAND -#else -static u16_t dns_txid; -#define DNS_RAND_TXID() (++dns_txid) -#endif -#endif - -/** Limits the source port to be >= 1024 by default */ -#ifndef DNS_PORT_ALLOWED -#define DNS_PORT_ALLOWED(port) ((port) >= 1024) -#endif - -/** DNS resource record max. TTL (one week as default) */ -#ifndef DNS_MAX_TTL -#define DNS_MAX_TTL 604800 -#elif DNS_MAX_TTL > 0x7FFFFFFF -#error DNS_MAX_TTL must be a positive 32-bit value -#endif - -#if DNS_TABLE_SIZE > 255 -#error DNS_TABLE_SIZE must fit into an u8_t -#endif -#if DNS_MAX_SERVERS > 255 -#error DNS_MAX_SERVERS must fit into an u8_t -#endif - -/* The number of parallel requests (i.e. calls to dns_gethostbyname - * that cannot be answered from the DNS table. - * This is set to the table size by default. - */ -#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING) != 0) -#ifndef DNS_MAX_REQUESTS -#define DNS_MAX_REQUESTS DNS_TABLE_SIZE -#else -#if DNS_MAX_REQUESTS > 255 -#error DNS_MAX_REQUESTS must fit into an u8_t -#endif -#endif -#else -/* In this configuration, both arrays have to have the same size and are used - * like one entry (used/free) */ -#define DNS_MAX_REQUESTS DNS_TABLE_SIZE -#endif - -/* The number of UDP source ports used in parallel */ -#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) != 0) -#ifndef DNS_MAX_SOURCE_PORTS -#define DNS_MAX_SOURCE_PORTS DNS_MAX_REQUESTS -#else -#if DNS_MAX_SOURCE_PORTS > 255 -#error DNS_MAX_SOURCE_PORTS must fit into an u8_t -#endif -#endif -#else -#ifdef DNS_MAX_SOURCE_PORTS -#undef DNS_MAX_SOURCE_PORTS -#endif -#define DNS_MAX_SOURCE_PORTS 1 -#endif - -#if LWIP_IPV4 && LWIP_IPV6 -#define LWIP_DNS_ADDRTYPE_IS_IPV6(t) (((t) == LWIP_DNS_ADDRTYPE_IPV6_IPV4) || ((t) == LWIP_DNS_ADDRTYPE_IPV6)) -#define LWIP_DNS_ADDRTYPE_MATCH_IP(t, ip) (IP_IS_V6_VAL(ip) ? LWIP_DNS_ADDRTYPE_IS_IPV6(t) : (!LWIP_DNS_ADDRTYPE_IS_IPV6(t))) -#define LWIP_DNS_ADDRTYPE_ARG(x) , x -#define LWIP_DNS_ADDRTYPE_ARG_OR_ZERO(x) x -#define LWIP_DNS_SET_ADDRTYPE(x, y) do { x = y; } while(0) -#else -#if LWIP_IPV6 -#define LWIP_DNS_ADDRTYPE_IS_IPV6(t) 1 -#else -#define LWIP_DNS_ADDRTYPE_IS_IPV6(t) 0 -#endif -#define LWIP_DNS_ADDRTYPE_MATCH_IP(t, ip) 1 -#define LWIP_DNS_ADDRTYPE_ARG(x) -#define LWIP_DNS_ADDRTYPE_ARG_OR_ZERO(x) 0 -#define LWIP_DNS_SET_ADDRTYPE(x, y) -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - -#if LWIP_DNS_SUPPORT_MDNS_QUERIES -#define LWIP_DNS_ISMDNS_ARG(x) , x -#else -#define LWIP_DNS_ISMDNS_ARG(x) -#endif - -/** DNS query message structure. - No packing needed: only used locally on the stack. */ -struct dns_query { - /* DNS query record starts with either a domain name or a pointer - to a name already present somewhere in the packet. */ - u16_t type; - u16_t cls; -}; -#define SIZEOF_DNS_QUERY 4 - -/** DNS answer message structure. - No packing needed: only used locally on the stack. */ -struct dns_answer { - /* DNS answer record starts with either a domain name or a pointer - to a name already present somewhere in the packet. */ - u16_t type; - u16_t cls; - u32_t ttl; - u16_t len; -}; -#define SIZEOF_DNS_ANSWER 10 -/* maximum allowed size for the struct due to non-packed */ -#define SIZEOF_DNS_ANSWER_ASSERT 12 - -/* DNS table entry states */ -typedef enum { - DNS_STATE_UNUSED = 0, - DNS_STATE_NEW = 1, - DNS_STATE_ASKING = 2, - DNS_STATE_DONE = 3 -} dns_state_enum_t; - -/** DNS table entry */ -struct dns_table_entry { - u32_t ttl; - ip_addr_t ipaddr; - u16_t txid; - u8_t state; - u8_t server_idx; - u8_t tmr; - u8_t retries; - u8_t seqno; -#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) != 0) - u8_t pcb_idx; -#endif - char name[DNS_MAX_NAME_LENGTH]; -#if LWIP_IPV4 && LWIP_IPV6 - u8_t reqaddrtype; -#endif /* LWIP_IPV4 && LWIP_IPV6 */ -#if LWIP_DNS_SUPPORT_MDNS_QUERIES - u8_t is_mdns; -#endif -}; - -/** DNS request table entry: used when dns_gehostbyname cannot answer the - * request from the DNS table */ -struct dns_req_entry { - /* pointer to callback on DNS query done */ - dns_found_callback found; - /* argument passed to the callback function */ - void *arg; -#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING) != 0) - u8_t dns_table_idx; -#endif -#if LWIP_IPV4 && LWIP_IPV6 - u8_t reqaddrtype; -#endif /* LWIP_IPV4 && LWIP_IPV6 */ -}; - -#if DNS_LOCAL_HOSTLIST - -#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC -/** Local host-list. For hostnames in this list, no - * external name resolution is performed */ -static struct local_hostlist_entry *local_hostlist_dynamic; -#else /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ - -/** Defining this allows the local_hostlist_static to be placed in a different - * linker section (e.g. FLASH) */ -#ifndef DNS_LOCAL_HOSTLIST_STORAGE_PRE -#define DNS_LOCAL_HOSTLIST_STORAGE_PRE static -#endif /* DNS_LOCAL_HOSTLIST_STORAGE_PRE */ -/** Defining this allows the local_hostlist_static to be placed in a different - * linker section (e.g. FLASH) */ -#ifndef DNS_LOCAL_HOSTLIST_STORAGE_POST -#define DNS_LOCAL_HOSTLIST_STORAGE_POST -#endif /* DNS_LOCAL_HOSTLIST_STORAGE_POST */ -DNS_LOCAL_HOSTLIST_STORAGE_PRE struct local_hostlist_entry local_hostlist_static[] - DNS_LOCAL_HOSTLIST_STORAGE_POST = DNS_LOCAL_HOSTLIST_INIT; - -#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ - -static void dns_init_local(void); -static err_t dns_lookup_local(const char *hostname, ip_addr_t *addr LWIP_DNS_ADDRTYPE_ARG(u8_t dns_addrtype)); -#endif /* DNS_LOCAL_HOSTLIST */ - - -/* forward declarations */ -static void dns_recv(void *s, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port); -static void dns_check_entries(void); -static void dns_call_found(u8_t idx, ip_addr_t *addr); - -/*----------------------------------------------------------------------------- - * Globals - *----------------------------------------------------------------------------*/ - -/* DNS variables */ -static struct udp_pcb *dns_pcbs[DNS_MAX_SOURCE_PORTS]; -#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) != 0) -static u8_t dns_last_pcb_idx; -#endif -static u8_t dns_seqno; -static struct dns_table_entry dns_table[DNS_TABLE_SIZE]; -static struct dns_req_entry dns_requests[DNS_MAX_REQUESTS]; -static ip_addr_t dns_servers[DNS_MAX_SERVERS]; - -#if LWIP_IPV4 -const ip_addr_t dns_mquery_v4group = DNS_MQUERY_IPV4_GROUP_INIT; -#endif /* LWIP_IPV4 */ -#if LWIP_IPV6 -const ip_addr_t dns_mquery_v6group = DNS_MQUERY_IPV6_GROUP_INIT; -#endif /* LWIP_IPV6 */ - -/** - * Initialize the resolver: set up the UDP pcb and configure the default server - * (if DNS_SERVER_ADDRESS is set). - */ -void -dns_init(void) -{ -#ifdef DNS_SERVER_ADDRESS - /* initialize default DNS server address */ - ip_addr_t dnsserver; - DNS_SERVER_ADDRESS(&dnsserver); - dns_setserver(0, &dnsserver); -#endif /* DNS_SERVER_ADDRESS */ - - LWIP_ASSERT("sanity check SIZEOF_DNS_QUERY", - sizeof(struct dns_query) == SIZEOF_DNS_QUERY); - LWIP_ASSERT("sanity check SIZEOF_DNS_ANSWER", - sizeof(struct dns_answer) <= SIZEOF_DNS_ANSWER_ASSERT); - - LWIP_DEBUGF(DNS_DEBUG, ("dns_init: initializing\n")); - - /* if dns client not yet initialized... */ -#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) == 0) - if (dns_pcbs[0] == NULL) { - dns_pcbs[0] = udp_new_ip_type(IPADDR_TYPE_ANY); - LWIP_ASSERT("dns_pcbs[0] != NULL", dns_pcbs[0] != NULL); - - /* initialize DNS table not needed (initialized to zero since it is a - * global variable) */ - LWIP_ASSERT("For implicit initialization to work, DNS_STATE_UNUSED needs to be 0", - DNS_STATE_UNUSED == 0); - - /* initialize DNS client */ - udp_bind(dns_pcbs[0], IP_ANY_TYPE, 0); - udp_recv(dns_pcbs[0], dns_recv, NULL); - } -#endif - -#if DNS_LOCAL_HOSTLIST - dns_init_local(); -#endif -} - -/** - * @ingroup dns - * Initialize one of the DNS servers. - * - * @param numdns the index of the DNS server to set must be < DNS_MAX_SERVERS - * @param dnsserver IP address of the DNS server to set - */ -void -dns_setserver(u8_t numdns, const ip_addr_t *dnsserver) -{ - if (numdns < DNS_MAX_SERVERS) { - if (dnsserver != NULL) { - dns_servers[numdns] = (*dnsserver); - } else { - dns_servers[numdns] = *IP_ADDR_ANY; - } - } -} - -/** - * @ingroup dns - * Obtain one of the currently configured DNS server. - * - * @param numdns the index of the DNS server - * @return IP address of the indexed DNS server or "ip_addr_any" if the DNS - * server has not been configured. - */ -const ip_addr_t * -dns_getserver(u8_t numdns) -{ - if (numdns < DNS_MAX_SERVERS) { - return &dns_servers[numdns]; - } else { - return IP_ADDR_ANY; - } -} - -/** - * The DNS resolver client timer - handle retries and timeouts and should - * be called every DNS_TMR_INTERVAL milliseconds (every second by default). - */ -void -dns_tmr(void) -{ - LWIP_DEBUGF(DNS_DEBUG, ("dns_tmr: dns_check_entries\n")); - dns_check_entries(); -} - -#if DNS_LOCAL_HOSTLIST -static void -dns_init_local(void) -{ -#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC && defined(DNS_LOCAL_HOSTLIST_INIT) - size_t i; - struct local_hostlist_entry *entry; - /* Dynamic: copy entries from DNS_LOCAL_HOSTLIST_INIT to list */ - struct local_hostlist_entry local_hostlist_init[] = DNS_LOCAL_HOSTLIST_INIT; - size_t namelen; - for (i = 0; i < LWIP_ARRAYSIZE(local_hostlist_init); i++) { - struct local_hostlist_entry *init_entry = &local_hostlist_init[i]; - LWIP_ASSERT("invalid host name (NULL)", init_entry->name != NULL); - namelen = strlen(init_entry->name); - LWIP_ASSERT("namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN", namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN); - entry = (struct local_hostlist_entry *)memp_malloc(MEMP_LOCALHOSTLIST); - LWIP_ASSERT("mem-error in dns_init_local", entry != NULL); - if (entry != NULL) { - char *entry_name = (char *)entry + sizeof(struct local_hostlist_entry); - MEMCPY(entry_name, init_entry->name, namelen); - entry_name[namelen] = 0; - entry->name = entry_name; - entry->addr = init_entry->addr; - entry->next = local_hostlist_dynamic; - local_hostlist_dynamic = entry; - } - } -#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC && defined(DNS_LOCAL_HOSTLIST_INIT) */ -} - -/** - * @ingroup dns - * Iterate the local host-list for a hostname. - * - * @param iterator_fn a function that is called for every entry in the local host-list - * @param iterator_arg 3rd argument passed to iterator_fn - * @return the number of entries in the local host-list - */ -size_t -dns_local_iterate(dns_found_callback iterator_fn, void *iterator_arg) -{ - size_t i; -#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC - struct local_hostlist_entry *entry = local_hostlist_dynamic; - i = 0; - while (entry != NULL) { - if (iterator_fn != NULL) { - iterator_fn(entry->name, &entry->addr, iterator_arg); - } - i++; - entry = entry->next; - } -#else /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ - for (i = 0; i < LWIP_ARRAYSIZE(local_hostlist_static); i++) { - if (iterator_fn != NULL) { - iterator_fn(local_hostlist_static[i].name, &local_hostlist_static[i].addr, iterator_arg); - } - } -#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ - return i; -} - -/** - * @ingroup dns - * Scans the local host-list for a hostname. - * - * @param hostname Hostname to look for in the local host-list - * @param addr the first IP address for the hostname in the local host-list or - * IPADDR_NONE if not found. - * @param dns_addrtype - LWIP_DNS_ADDRTYPE_IPV4_IPV6: try to resolve IPv4 (ATTENTION: no fallback here!) - * - LWIP_DNS_ADDRTYPE_IPV6_IPV4: try to resolve IPv6 (ATTENTION: no fallback here!) - * - LWIP_DNS_ADDRTYPE_IPV4: try to resolve IPv4 only - * - LWIP_DNS_ADDRTYPE_IPV6: try to resolve IPv6 only - * @return ERR_OK if found, ERR_ARG if not found - */ -err_t -dns_local_lookup(const char *hostname, ip_addr_t *addr, u8_t dns_addrtype) -{ - LWIP_UNUSED_ARG(dns_addrtype); - return dns_lookup_local(hostname, addr LWIP_DNS_ADDRTYPE_ARG(dns_addrtype)); -} - -/* Internal implementation for dns_local_lookup and dns_lookup */ -static err_t -dns_lookup_local(const char *hostname, ip_addr_t *addr LWIP_DNS_ADDRTYPE_ARG(u8_t dns_addrtype)) -{ -#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC - struct local_hostlist_entry *entry = local_hostlist_dynamic; - while (entry != NULL) { - if ((lwip_stricmp(entry->name, hostname) == 0) && - LWIP_DNS_ADDRTYPE_MATCH_IP(dns_addrtype, entry->addr)) { - if (addr) { - ip_addr_copy(*addr, entry->addr); - } - return ERR_OK; - } - entry = entry->next; - } -#else /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ - size_t i; - for (i = 0; i < LWIP_ARRAYSIZE(local_hostlist_static); i++) { - if ((lwip_stricmp(local_hostlist_static[i].name, hostname) == 0) && - LWIP_DNS_ADDRTYPE_MATCH_IP(dns_addrtype, local_hostlist_static[i].addr)) { - if (addr) { - ip_addr_copy(*addr, local_hostlist_static[i].addr); - } - return ERR_OK; - } - } -#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ - return ERR_ARG; -} - -#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC -/** - * @ingroup dns - * Remove all entries from the local host-list for a specific hostname - * and/or IP address - * - * @param hostname hostname for which entries shall be removed from the local - * host-list - * @param addr address for which entries shall be removed from the local host-list - * @return the number of removed entries - */ -int -dns_local_removehost(const char *hostname, const ip_addr_t *addr) -{ - int removed = 0; - struct local_hostlist_entry *entry = local_hostlist_dynamic; - struct local_hostlist_entry *last_entry = NULL; - while (entry != NULL) { - if (((hostname == NULL) || !lwip_stricmp(entry->name, hostname)) && - ((addr == NULL) || ip_addr_cmp(&entry->addr, addr))) { - struct local_hostlist_entry *free_entry; - if (last_entry != NULL) { - last_entry->next = entry->next; - } else { - local_hostlist_dynamic = entry->next; - } - free_entry = entry; - entry = entry->next; - memp_free(MEMP_LOCALHOSTLIST, free_entry); - removed++; - } else { - last_entry = entry; - entry = entry->next; - } - } - return removed; -} - -/** - * @ingroup dns - * Add a hostname/IP address pair to the local host-list. - * Duplicates are not checked. - * - * @param hostname hostname of the new entry - * @param addr IP address of the new entry - * @return ERR_OK if succeeded or ERR_MEM on memory error - */ -err_t -dns_local_addhost(const char *hostname, const ip_addr_t *addr) -{ - struct local_hostlist_entry *entry; - size_t namelen; - char *entry_name; - LWIP_ASSERT("invalid host name (NULL)", hostname != NULL); - namelen = strlen(hostname); - LWIP_ASSERT("namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN", namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN); - entry = (struct local_hostlist_entry *)memp_malloc(MEMP_LOCALHOSTLIST); - if (entry == NULL) { - return ERR_MEM; - } - entry_name = (char *)entry + sizeof(struct local_hostlist_entry); - MEMCPY(entry_name, hostname, namelen); - entry_name[namelen] = 0; - entry->name = entry_name; - ip_addr_copy(entry->addr, *addr); - entry->next = local_hostlist_dynamic; - local_hostlist_dynamic = entry; - return ERR_OK; -} -#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC*/ -#endif /* DNS_LOCAL_HOSTLIST */ - -/** - * @ingroup dns - * Look up a hostname in the array of known hostnames. - * - * @note This function only looks in the internal array of known - * hostnames, it does not send out a query for the hostname if none - * was found. The function dns_enqueue() can be used to send a query - * for a hostname. - * - * @param name the hostname to look up - * @param addr the hostname's IP address, as u32_t (instead of ip_addr_t to - * better check for failure: != IPADDR_NONE) or IPADDR_NONE if the hostname - * was not found in the cached dns_table. - * @return ERR_OK if found, ERR_ARG if not found - */ -static err_t -dns_lookup(const char *name, ip_addr_t *addr LWIP_DNS_ADDRTYPE_ARG(u8_t dns_addrtype)) -{ - u8_t i; -#if DNS_LOCAL_HOSTLIST - if (dns_lookup_local(name, addr LWIP_DNS_ADDRTYPE_ARG(dns_addrtype)) == ERR_OK) { - return ERR_OK; - } -#endif /* DNS_LOCAL_HOSTLIST */ -#ifdef DNS_LOOKUP_LOCAL_EXTERN - if (DNS_LOOKUP_LOCAL_EXTERN(name, addr, LWIP_DNS_ADDRTYPE_ARG_OR_ZERO(dns_addrtype)) == ERR_OK) { - return ERR_OK; - } -#endif /* DNS_LOOKUP_LOCAL_EXTERN */ - - /* Walk through name list, return entry if found. If not, return NULL. */ - for (i = 0; i < DNS_TABLE_SIZE; ++i) { - if ((dns_table[i].state == DNS_STATE_DONE) && - (lwip_strnicmp(name, dns_table[i].name, sizeof(dns_table[i].name)) == 0) && - LWIP_DNS_ADDRTYPE_MATCH_IP(dns_addrtype, dns_table[i].ipaddr)) { - LWIP_DEBUGF(DNS_DEBUG, ("dns_lookup: \"%s\": found = ", name)); - ip_addr_debug_print_val(DNS_DEBUG, dns_table[i].ipaddr); - LWIP_DEBUGF(DNS_DEBUG, ("\n")); - if (addr) { - ip_addr_copy(*addr, dns_table[i].ipaddr); - } - return ERR_OK; - } - } - - return ERR_ARG; -} - -/** - * Compare the "dotted" name "query" with the encoded name "response" - * to make sure an answer from the DNS server matches the current dns_table - * entry (otherwise, answers might arrive late for hostname not on the list - * any more). - * - * For now, this function compares case-insensitive to cope with all kinds of - * servers. This also means that "dns 0x20 bit encoding" must be checked - * externally, if we want to implement it. - * Currently, the request is sent exactly as passed in by he user request. - * - * @param query hostname (not encoded) from the dns_table - * @param p pbuf containing the encoded hostname in the DNS response - * @param start_offset offset into p where the name starts - * @return 0xFFFF: names differ, other: names equal -> offset behind name - */ -static u16_t -dns_compare_name(const char *query, struct pbuf *p, u16_t start_offset) -{ - int n; - u16_t response_offset = start_offset; - - do { - n = pbuf_try_get_at(p, response_offset); - if ((n < 0) || (response_offset == 0xFFFF)) { - /* error or overflow */ - return 0xFFFF; - } - response_offset++; - /** @see RFC 1035 - 4.1.4. Message compression */ - if ((n & 0xc0) == 0xc0) { - /* Compressed name: cannot be equal since we don't send them */ - return 0xFFFF; - } else { - /* Not compressed name */ - while (n > 0) { - int c = pbuf_try_get_at(p, response_offset); - if (c < 0) { - return 0xFFFF; - } - if (lwip_tolower((*query)) != lwip_tolower((u8_t)c)) { - return 0xFFFF; - } - if (response_offset == 0xFFFF) { - /* would overflow */ - return 0xFFFF; - } - response_offset++; - ++query; - --n; - } - ++query; - } - n = pbuf_try_get_at(p, response_offset); - if (n < 0) { - return 0xFFFF; - } - } while (n != 0); - - if (response_offset == 0xFFFF) { - /* would overflow */ - return 0xFFFF; - } - return (u16_t)(response_offset + 1); -} - -/** - * Walk through a compact encoded DNS name and return the end of the name. - * - * @param p pbuf containing the name - * @param query_idx start index into p pointing to encoded DNS name in the DNS server response - * @return index to end of the name - */ -static u16_t -dns_skip_name(struct pbuf *p, u16_t query_idx) -{ - int n; - u16_t offset = query_idx; - - do { - n = pbuf_try_get_at(p, offset++); - if ((n < 0) || (offset == 0)) { - return 0xFFFF; - } - /** @see RFC 1035 - 4.1.4. Message compression */ - if ((n & 0xc0) == 0xc0) { - /* Compressed name: since we only want to skip it (not check it), stop here */ - break; - } else { - /* Not compressed name */ - if (offset + n >= p->tot_len) { - return 0xFFFF; - } - offset = (u16_t)(offset + n); - } - n = pbuf_try_get_at(p, offset); - if (n < 0) { - return 0xFFFF; - } - } while (n != 0); - - if (offset == 0xFFFF) { - return 0xFFFF; - } - return (u16_t)(offset + 1); -} - -/** - * Send a DNS query packet. - * - * @param idx the DNS table entry index for which to send a request - * @return ERR_OK if packet is sent; an err_t indicating the problem otherwise - */ -static err_t -dns_send(u8_t idx) -{ - err_t err; - struct dns_hdr hdr; - struct dns_query qry; - struct pbuf *p; - u16_t query_idx, copy_len; - const char *hostname, *hostname_part; - u8_t n; - u8_t pcb_idx; - struct dns_table_entry *entry = &dns_table[idx]; - - LWIP_DEBUGF(DNS_DEBUG, ("dns_send: dns_servers[%"U16_F"] \"%s\": request\n", - (u16_t)(entry->server_idx), entry->name)); - LWIP_ASSERT("dns server out of array", entry->server_idx < DNS_MAX_SERVERS); - if (ip_addr_isany_val(dns_servers[entry->server_idx]) -#if LWIP_DNS_SUPPORT_MDNS_QUERIES - && !entry->is_mdns -#endif - ) { - /* DNS server not valid anymore, e.g. PPP netif has been shut down */ - /* call specified callback function if provided */ - dns_call_found(idx, NULL); - /* flush this entry */ - entry->state = DNS_STATE_UNUSED; - return ERR_OK; - } - - /* if here, we have either a new query or a retry on a previous query to process */ - p = pbuf_alloc(PBUF_TRANSPORT, (u16_t)(SIZEOF_DNS_HDR + strlen(entry->name) + 2 + - SIZEOF_DNS_QUERY), PBUF_RAM); - if (p != NULL) { - const ip_addr_t *dst; - u16_t dst_port; - /* fill dns header */ - memset(&hdr, 0, SIZEOF_DNS_HDR); - hdr.id = lwip_htons(entry->txid); - hdr.flags1 = DNS_FLAG1_RD; - hdr.numquestions = PP_HTONS(1); - pbuf_take(p, &hdr, SIZEOF_DNS_HDR); - hostname = entry->name; - --hostname; - - /* convert hostname into suitable query format. */ - query_idx = SIZEOF_DNS_HDR; - do { - ++hostname; - hostname_part = hostname; - for (n = 0; *hostname != '.' && *hostname != 0; ++hostname) { - ++n; - } - copy_len = (u16_t)(hostname - hostname_part); - if (query_idx + n + 1 > 0xFFFF) { - /* u16_t overflow */ - goto overflow_return; - } - pbuf_put_at(p, query_idx, n); - pbuf_take_at(p, hostname_part, copy_len, (u16_t)(query_idx + 1)); - query_idx = (u16_t)(query_idx + n + 1); - } while (*hostname != 0); - pbuf_put_at(p, query_idx, 0); - query_idx++; - - /* fill dns query */ - if (LWIP_DNS_ADDRTYPE_IS_IPV6(entry->reqaddrtype)) { - qry.type = PP_HTONS(DNS_RRTYPE_AAAA); - } else { - qry.type = PP_HTONS(DNS_RRTYPE_A); - } - qry.cls = PP_HTONS(DNS_RRCLASS_IN); - pbuf_take_at(p, &qry, SIZEOF_DNS_QUERY, query_idx); - -#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) != 0) - pcb_idx = entry->pcb_idx; -#else - pcb_idx = 0; -#endif - /* send dns packet */ - LWIP_DEBUGF(DNS_DEBUG, ("sending DNS request ID %d for name \"%s\" to server %d\r\n", - entry->txid, entry->name, entry->server_idx)); -#if LWIP_DNS_SUPPORT_MDNS_QUERIES - if (entry->is_mdns) { - dst_port = DNS_MQUERY_PORT; -#if LWIP_IPV6 - if (LWIP_DNS_ADDRTYPE_IS_IPV6(entry->reqaddrtype)) { - dst = &dns_mquery_v6group; - } -#endif -#if LWIP_IPV4 && LWIP_IPV6 - else -#endif -#if LWIP_IPV4 - { - dst = &dns_mquery_v4group; - } -#endif - } else -#endif /* LWIP_DNS_SUPPORT_MDNS_QUERIES */ - { - dst_port = DNS_SERVER_PORT; - dst = &dns_servers[entry->server_idx]; - } - err = udp_sendto(dns_pcbs[pcb_idx], p, dst, dst_port); - - /* free pbuf */ - pbuf_free(p); - } else { - err = ERR_MEM; - } - - return err; -overflow_return: - pbuf_free(p); - return ERR_VAL; -} - -#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) != 0) -static struct udp_pcb * -dns_alloc_random_port(void) -{ - err_t err; - struct udp_pcb *pcb; - - pcb = udp_new_ip_type(IPADDR_TYPE_ANY); - if (pcb == NULL) { - /* out of memory, have to reuse an existing pcb */ - return NULL; - } - do { - u16_t port = (u16_t)DNS_RAND_TXID(); - if (DNS_PORT_ALLOWED(port)) { - err = udp_bind(pcb, IP_ANY_TYPE, port); - } else { - /* this port is not allowed, try again */ - err = ERR_USE; - } - } while (err == ERR_USE); - if (err != ERR_OK) { - udp_remove(pcb); - return NULL; - } - udp_recv(pcb, dns_recv, NULL); - return pcb; -} - -/** - * dns_alloc_pcb() - allocates a new pcb (or reuses an existing one) to be used - * for sending a request - * - * @return an index into dns_pcbs - */ -static u8_t -dns_alloc_pcb(void) -{ - u8_t i; - u8_t idx; - - for (i = 0; i < DNS_MAX_SOURCE_PORTS; i++) { - if (dns_pcbs[i] == NULL) { - break; - } - } - if (i < DNS_MAX_SOURCE_PORTS) { - dns_pcbs[i] = dns_alloc_random_port(); - if (dns_pcbs[i] != NULL) { - /* succeeded */ - dns_last_pcb_idx = i; - return i; - } - } - /* if we come here, creating a new UDP pcb failed, so we have to use - an already existing one (so overflow is no issue) */ - for (i = 0, idx = (u8_t)(dns_last_pcb_idx + 1); i < DNS_MAX_SOURCE_PORTS; i++, idx++) { - if (idx >= DNS_MAX_SOURCE_PORTS) { - idx = 0; - } - if (dns_pcbs[idx] != NULL) { - dns_last_pcb_idx = idx; - return idx; - } - } - return DNS_MAX_SOURCE_PORTS; -} -#endif /* ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) != 0) */ - -/** - * dns_call_found() - call the found callback and check if there are duplicate - * entries for the given hostname. If there are any, their found callback will - * be called and they will be removed. - * - * @param idx dns table index of the entry that is resolved or removed - * @param addr IP address for the hostname (or NULL on error or memory shortage) - */ -static void -dns_call_found(u8_t idx, ip_addr_t *addr) -{ -#if ((LWIP_DNS_SECURE & (LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING | LWIP_DNS_SECURE_RAND_SRC_PORT)) != 0) - u8_t i; -#endif - -#if LWIP_IPV4 && LWIP_IPV6 - if (addr != NULL) { - /* check that address type matches the request and adapt the table entry */ - if (IP_IS_V6_VAL(*addr)) { - LWIP_ASSERT("invalid response", LWIP_DNS_ADDRTYPE_IS_IPV6(dns_table[idx].reqaddrtype)); - dns_table[idx].reqaddrtype = LWIP_DNS_ADDRTYPE_IPV6; - } else { - LWIP_ASSERT("invalid response", !LWIP_DNS_ADDRTYPE_IS_IPV6(dns_table[idx].reqaddrtype)); - dns_table[idx].reqaddrtype = LWIP_DNS_ADDRTYPE_IPV4; - } - } -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - -#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING) != 0) - for (i = 0; i < DNS_MAX_REQUESTS; i++) { - if (dns_requests[i].found && (dns_requests[i].dns_table_idx == idx)) { - (*dns_requests[i].found)(dns_table[idx].name, addr, dns_requests[i].arg); - /* flush this entry */ - dns_requests[i].found = NULL; - } - } -#else - if (dns_requests[idx].found) { - (*dns_requests[idx].found)(dns_table[idx].name, addr, dns_requests[idx].arg); - } - dns_requests[idx].found = NULL; -#endif -#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) != 0) - /* close the pcb used unless other request are using it */ - for (i = 0; i < DNS_MAX_REQUESTS; i++) { - if (i == idx) { - continue; /* only check other requests */ - } - if (dns_table[i].state == DNS_STATE_ASKING) { - if (dns_table[i].pcb_idx == dns_table[idx].pcb_idx) { - /* another request is still using the same pcb */ - dns_table[idx].pcb_idx = DNS_MAX_SOURCE_PORTS; - break; - } - } - } - if (dns_table[idx].pcb_idx < DNS_MAX_SOURCE_PORTS) { - /* if we come here, the pcb is not used any more and can be removed */ - udp_remove(dns_pcbs[dns_table[idx].pcb_idx]); - dns_pcbs[dns_table[idx].pcb_idx] = NULL; - dns_table[idx].pcb_idx = DNS_MAX_SOURCE_PORTS; - } -#endif -} - -/* Create a query transmission ID that is unique for all outstanding queries */ -static u16_t -dns_create_txid(void) -{ - u16_t txid; - u8_t i; - -again: - txid = (u16_t)DNS_RAND_TXID(); - - /* check whether the ID is unique */ - for (i = 0; i < DNS_TABLE_SIZE; i++) { - if ((dns_table[i].state == DNS_STATE_ASKING) && - (dns_table[i].txid == txid)) { - /* ID already used by another pending query */ - goto again; - } - } - - return txid; -} - -/** - * Check whether there are other backup DNS servers available to try - */ -static u8_t -dns_backupserver_available(struct dns_table_entry *pentry) -{ - u8_t ret = 0; - - if (pentry) { - if ((pentry->server_idx + 1 < DNS_MAX_SERVERS) && !ip_addr_isany_val(dns_servers[pentry->server_idx + 1])) { - ret = 1; - } - } - - return ret; -} - -/** - * dns_check_entry() - see if entry has not yet been queried and, if so, sends out a query. - * Check an entry in the dns_table: - * - send out query for new entries - * - retry old pending entries on timeout (also with different servers) - * - remove completed entries from the table if their TTL has expired - * - * @param i index of the dns_table entry to check - */ -static void -dns_check_entry(u8_t i) -{ - err_t err; - struct dns_table_entry *entry = &dns_table[i]; - - LWIP_ASSERT("array index out of bounds", i < DNS_TABLE_SIZE); - - switch (entry->state) { - case DNS_STATE_NEW: - /* initialize new entry */ - entry->txid = dns_create_txid(); - entry->state = DNS_STATE_ASKING; - entry->server_idx = 0; - entry->tmr = 1; - entry->retries = 0; - - /* send DNS packet for this entry */ - err = dns_send(i); - if (err != ERR_OK) { - LWIP_DEBUGF(DNS_DEBUG | LWIP_DBG_LEVEL_WARNING, - ("dns_send returned error: %s\n", lwip_strerr(err))); - } - break; - case DNS_STATE_ASKING: - if (--entry->tmr == 0) { - if (++entry->retries == DNS_MAX_RETRIES) { - if (dns_backupserver_available(entry) -#if LWIP_DNS_SUPPORT_MDNS_QUERIES - && !entry->is_mdns -#endif /* LWIP_DNS_SUPPORT_MDNS_QUERIES */ - ) { - /* change of server */ - entry->server_idx++; - entry->tmr = 1; - entry->retries = 0; - } else { - LWIP_DEBUGF(DNS_DEBUG, ("dns_check_entry: \"%s\": timeout\n", entry->name)); - /* call specified callback function if provided */ - dns_call_found(i, NULL); - /* flush this entry */ - entry->state = DNS_STATE_UNUSED; - break; - } - } else { - /* wait longer for the next retry */ - entry->tmr = entry->retries; - } - - /* send DNS packet for this entry */ - err = dns_send(i); - if (err != ERR_OK) { - LWIP_DEBUGF(DNS_DEBUG | LWIP_DBG_LEVEL_WARNING, - ("dns_send returned error: %s\n", lwip_strerr(err))); - } - } - break; - case DNS_STATE_DONE: - /* if the time to live is nul */ - if ((entry->ttl == 0) || (--entry->ttl == 0)) { - LWIP_DEBUGF(DNS_DEBUG, ("dns_check_entry: \"%s\": flush\n", entry->name)); - /* flush this entry, there cannot be any related pending entries in this state */ - entry->state = DNS_STATE_UNUSED; - } - break; - case DNS_STATE_UNUSED: - /* nothing to do */ - break; - default: - LWIP_ASSERT("unknown dns_table entry state:", 0); - break; - } -} - -/** - * Call dns_check_entry for each entry in dns_table - check all entries. - */ -static void -dns_check_entries(void) -{ - u8_t i; - - for (i = 0; i < DNS_TABLE_SIZE; ++i) { - dns_check_entry(i); - } -} - -/** - * Save TTL and call dns_call_found for correct response. - */ -static void -dns_correct_response(u8_t idx, u32_t ttl) -{ - struct dns_table_entry *entry = &dns_table[idx]; - - entry->state = DNS_STATE_DONE; - - LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": response = ", entry->name)); - ip_addr_debug_print_val(DNS_DEBUG, entry->ipaddr); - LWIP_DEBUGF(DNS_DEBUG, ("\n")); - - /* read the answer resource record's TTL, and maximize it if needed */ - entry->ttl = ttl; - if (entry->ttl > DNS_MAX_TTL) { - entry->ttl = DNS_MAX_TTL; - } - dns_call_found(idx, &entry->ipaddr); - - if (entry->ttl == 0) { - /* RFC 883, page 29: "Zero values are - interpreted to mean that the RR can only be used for the - transaction in progress, and should not be cached." - -> flush this entry now */ - /* entry reused during callback? */ - if (entry->state == DNS_STATE_DONE) { - entry->state = DNS_STATE_UNUSED; - } - } -} - -/** - * Receive input function for DNS response packets arriving for the dns UDP pcb. - */ -static void -dns_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) -{ - u8_t i; - u16_t txid; - u16_t res_idx; - struct dns_hdr hdr; - struct dns_answer ans; - struct dns_query qry; - u16_t nquestions, nanswers; - - LWIP_UNUSED_ARG(arg); - LWIP_UNUSED_ARG(pcb); - LWIP_UNUSED_ARG(port); - - /* is the dns message big enough ? */ - if (p->tot_len < (SIZEOF_DNS_HDR + SIZEOF_DNS_QUERY)) { - LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: pbuf too small\n")); - /* free pbuf and return */ - goto ignore_packet; - } - - /* copy dns payload inside static buffer for processing */ - if (pbuf_copy_partial(p, &hdr, SIZEOF_DNS_HDR, 0) == SIZEOF_DNS_HDR) { - /* Match the ID in the DNS header with the name table. */ - txid = lwip_htons(hdr.id); - for (i = 0; i < DNS_TABLE_SIZE; i++) { - struct dns_table_entry *entry = &dns_table[i]; - if ((entry->state == DNS_STATE_ASKING) && - (entry->txid == txid)) { - - /* We only care about the question(s) and the answers. The authrr - and the extrarr are simply discarded. */ - nquestions = lwip_htons(hdr.numquestions); - nanswers = lwip_htons(hdr.numanswers); - - /* Check for correct response. */ - if ((hdr.flags1 & DNS_FLAG1_RESPONSE) == 0) { - LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": not a response\n", entry->name)); - goto ignore_packet; /* ignore this packet */ - } - if (nquestions != 1) { - LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": response not match to query\n", entry->name)); - goto ignore_packet; /* ignore this packet */ - } - -#if LWIP_DNS_SUPPORT_MDNS_QUERIES - if (!entry->is_mdns) -#endif /* LWIP_DNS_SUPPORT_MDNS_QUERIES */ - { - /* Check whether response comes from the same network address to which the - question was sent. (RFC 5452) */ - if (!ip_addr_cmp(addr, &dns_servers[entry->server_idx])) { - goto ignore_packet; /* ignore this packet */ - } - } - - /* Check if the name in the "question" part match with the name in the entry and - skip it if equal. */ - res_idx = dns_compare_name(entry->name, p, SIZEOF_DNS_HDR); - if (res_idx == 0xFFFF) { - LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": response not match to query\n", entry->name)); - goto ignore_packet; /* ignore this packet */ - } - - /* check if "question" part matches the request */ - if (pbuf_copy_partial(p, &qry, SIZEOF_DNS_QUERY, res_idx) != SIZEOF_DNS_QUERY) { - goto ignore_packet; /* ignore this packet */ - } - if ((qry.cls != PP_HTONS(DNS_RRCLASS_IN)) || - (LWIP_DNS_ADDRTYPE_IS_IPV6(entry->reqaddrtype) && (qry.type != PP_HTONS(DNS_RRTYPE_AAAA))) || - (!LWIP_DNS_ADDRTYPE_IS_IPV6(entry->reqaddrtype) && (qry.type != PP_HTONS(DNS_RRTYPE_A)))) { - LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": response not match to query\n", entry->name)); - goto ignore_packet; /* ignore this packet */ - } - /* skip the rest of the "question" part */ - if (res_idx + SIZEOF_DNS_QUERY > 0xFFFF) { - goto ignore_packet; - } - res_idx = (u16_t)(res_idx + SIZEOF_DNS_QUERY); - - /* Check for error. If so, call callback to inform. */ - if (hdr.flags2 & DNS_FLAG2_ERR_MASK) { - LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": error in flags\n", entry->name)); - - /* if there is another backup DNS server to try - * then don't stop the DNS request - */ - if (dns_backupserver_available(entry)) { - /* avoid retrying the same server */ - entry->retries = DNS_MAX_RETRIES-1; - entry->tmr = 1; - - /* contact next available server for this entry */ - dns_check_entry(i); - - goto ignore_packet; - } - } else { - while ((nanswers > 0) && (res_idx < p->tot_len)) { - /* skip answer resource record's host name */ - res_idx = dns_skip_name(p, res_idx); - if (res_idx == 0xFFFF) { - goto ignore_packet; /* ignore this packet */ - } - - /* Check for IP address type and Internet class. Others are discarded. */ - if (pbuf_copy_partial(p, &ans, SIZEOF_DNS_ANSWER, res_idx) != SIZEOF_DNS_ANSWER) { - goto ignore_packet; /* ignore this packet */ - } - if (res_idx + SIZEOF_DNS_ANSWER > 0xFFFF) { - goto ignore_packet; - } - res_idx = (u16_t)(res_idx + SIZEOF_DNS_ANSWER); - - if (ans.cls == PP_HTONS(DNS_RRCLASS_IN)) { -#if LWIP_IPV4 - if ((ans.type == PP_HTONS(DNS_RRTYPE_A)) && (ans.len == PP_HTONS(sizeof(ip4_addr_t)))) { -#if LWIP_IPV4 && LWIP_IPV6 - if (!LWIP_DNS_ADDRTYPE_IS_IPV6(entry->reqaddrtype)) -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - { - ip4_addr_t ip4addr; - /* read the IP address after answer resource record's header */ - if (pbuf_copy_partial(p, &ip4addr, sizeof(ip4_addr_t), res_idx) != sizeof(ip4_addr_t)) { - goto ignore_packet; /* ignore this packet */ - } - ip_addr_copy_from_ip4(dns_table[i].ipaddr, ip4addr); - pbuf_free(p); - /* handle correct response */ - dns_correct_response(i, lwip_ntohl(ans.ttl)); - return; - } - } -#endif /* LWIP_IPV4 */ -#if LWIP_IPV6 - if ((ans.type == PP_HTONS(DNS_RRTYPE_AAAA)) && (ans.len == PP_HTONS(sizeof(ip6_addr_p_t)))) { -#if LWIP_IPV4 && LWIP_IPV6 - if (LWIP_DNS_ADDRTYPE_IS_IPV6(entry->reqaddrtype)) -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - { - ip6_addr_p_t ip6addr; - /* read the IP address after answer resource record's header */ - if (pbuf_copy_partial(p, &ip6addr, sizeof(ip6_addr_p_t), res_idx) != sizeof(ip6_addr_p_t)) { - goto ignore_packet; /* ignore this packet */ - } - /* @todo: scope ip6addr? Might be required for link-local addresses at least? */ - ip_addr_copy_from_ip6_packed(dns_table[i].ipaddr, ip6addr); - pbuf_free(p); - /* handle correct response */ - dns_correct_response(i, lwip_ntohl(ans.ttl)); - return; - } - } -#endif /* LWIP_IPV6 */ - } - /* skip this answer */ - if ((int)(res_idx + lwip_htons(ans.len)) > 0xFFFF) { - goto ignore_packet; /* ignore this packet */ - } - res_idx = (u16_t)(res_idx + lwip_htons(ans.len)); - --nanswers; - } -#if LWIP_IPV4 && LWIP_IPV6 - if ((entry->reqaddrtype == LWIP_DNS_ADDRTYPE_IPV4_IPV6) || - (entry->reqaddrtype == LWIP_DNS_ADDRTYPE_IPV6_IPV4)) { - if (entry->reqaddrtype == LWIP_DNS_ADDRTYPE_IPV4_IPV6) { - /* IPv4 failed, try IPv6 */ - dns_table[i].reqaddrtype = LWIP_DNS_ADDRTYPE_IPV6; - } else { - /* IPv6 failed, try IPv4 */ - dns_table[i].reqaddrtype = LWIP_DNS_ADDRTYPE_IPV4; - } - pbuf_free(p); - dns_table[i].state = DNS_STATE_NEW; - dns_check_entry(i); - return; - } -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": error in response\n", entry->name)); - } - /* call callback to indicate error, clean up memory and return */ - pbuf_free(p); - dns_call_found(i, NULL); - dns_table[i].state = DNS_STATE_UNUSED; - return; - } - } - } - -ignore_packet: - /* deallocate memory and return */ - pbuf_free(p); - return; -} - -/** - * Queues a new hostname to resolve and sends out a DNS query for that hostname - * - * @param name the hostname that is to be queried - * @param hostnamelen length of the hostname - * @param found a callback function to be called on success, failure or timeout - * @param callback_arg argument to pass to the callback function - * @return err_t return code. - */ -static err_t -dns_enqueue(const char *name, size_t hostnamelen, dns_found_callback found, - void *callback_arg LWIP_DNS_ADDRTYPE_ARG(u8_t dns_addrtype) LWIP_DNS_ISMDNS_ARG(u8_t is_mdns)) -{ - u8_t i; - u8_t lseq, lseqi; - struct dns_table_entry *entry = NULL; - size_t namelen; - struct dns_req_entry *req; - -#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING) != 0) - u8_t r; - /* check for duplicate entries */ - for (i = 0; i < DNS_TABLE_SIZE; i++) { - if ((dns_table[i].state == DNS_STATE_ASKING) && - (lwip_strnicmp(name, dns_table[i].name, sizeof(dns_table[i].name)) == 0)) { -#if LWIP_IPV4 && LWIP_IPV6 - if (dns_table[i].reqaddrtype != dns_addrtype) { - /* requested address types don't match - this can lead to 2 concurrent requests, but mixing the address types - for the same host should not be that common */ - continue; - } -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - /* this is a duplicate entry, find a free request entry */ - for (r = 0; r < DNS_MAX_REQUESTS; r++) { - if (dns_requests[r].found == 0) { - dns_requests[r].found = found; - dns_requests[r].arg = callback_arg; - dns_requests[r].dns_table_idx = i; - LWIP_DNS_SET_ADDRTYPE(dns_requests[r].reqaddrtype, dns_addrtype); - LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": duplicate request\n", name)); - return ERR_INPROGRESS; - } - } - } - } - /* no duplicate entries found */ -#endif - - /* search an unused entry, or the oldest one */ - lseq = 0; - lseqi = DNS_TABLE_SIZE; - for (i = 0; i < DNS_TABLE_SIZE; ++i) { - entry = &dns_table[i]; - /* is it an unused entry ? */ - if (entry->state == DNS_STATE_UNUSED) { - break; - } - /* check if this is the oldest completed entry */ - if (entry->state == DNS_STATE_DONE) { - u8_t age = (u8_t)(dns_seqno - entry->seqno); - if (age > lseq) { - lseq = age; - lseqi = i; - } - } - } - - /* if we don't have found an unused entry, use the oldest completed one */ - if (i == DNS_TABLE_SIZE) { - if ((lseqi >= DNS_TABLE_SIZE) || (dns_table[lseqi].state != DNS_STATE_DONE)) { - /* no entry can be used now, table is full */ - LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": DNS entries table is full\n", name)); - return ERR_MEM; - } else { - /* use the oldest completed one */ - i = lseqi; - entry = &dns_table[i]; - } - } - -#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING) != 0) - /* find a free request entry */ - req = NULL; - for (r = 0; r < DNS_MAX_REQUESTS; r++) { - if (dns_requests[r].found == NULL) { - req = &dns_requests[r]; - break; - } - } - if (req == NULL) { - /* no request entry can be used now, table is full */ - LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": DNS request entries table is full\n", name)); - return ERR_MEM; - } - req->dns_table_idx = i; -#else - /* in this configuration, the entry index is the same as the request index */ - req = &dns_requests[i]; -#endif - - /* use this entry */ - LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": use DNS entry %"U16_F"\n", name, (u16_t)(i))); - - /* fill the entry */ - entry->state = DNS_STATE_NEW; - entry->seqno = dns_seqno; - LWIP_DNS_SET_ADDRTYPE(entry->reqaddrtype, dns_addrtype); - LWIP_DNS_SET_ADDRTYPE(req->reqaddrtype, dns_addrtype); - req->found = found; - req->arg = callback_arg; - namelen = LWIP_MIN(hostnamelen, DNS_MAX_NAME_LENGTH - 1); - MEMCPY(entry->name, name, namelen); - entry->name[namelen] = 0; - -#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) != 0) - entry->pcb_idx = dns_alloc_pcb(); - if (entry->pcb_idx >= DNS_MAX_SOURCE_PORTS) { - /* failed to get a UDP pcb */ - LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": failed to allocate a pcb\n", name)); - entry->state = DNS_STATE_UNUSED; - req->found = NULL; - return ERR_MEM; - } - LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": use DNS pcb %"U16_F"\n", name, (u16_t)(entry->pcb_idx))); -#endif - -#if LWIP_DNS_SUPPORT_MDNS_QUERIES - entry->is_mdns = is_mdns; -#endif - - dns_seqno++; - - /* force to send query without waiting timer */ - dns_check_entry(i); - - /* dns query is enqueued */ - return ERR_INPROGRESS; -} - -/** - * @ingroup dns - * Resolve a hostname (string) into an IP address. - * NON-BLOCKING callback version for use with raw API!!! - * - * Returns immediately with one of err_t return codes: - * - ERR_OK if hostname is a valid IP address string or the host - * name is already in the local names table. - * - ERR_INPROGRESS enqueue a request to be sent to the DNS server - * for resolution if no errors are present. - * - ERR_ARG: dns client not initialized or invalid hostname - * - * @param hostname the hostname that is to be queried - * @param addr pointer to a ip_addr_t where to store the address if it is already - * cached in the dns_table (only valid if ERR_OK is returned!) - * @param found a callback function to be called on success, failure or timeout (only if - * ERR_INPROGRESS is returned!) - * @param callback_arg argument to pass to the callback function - * @return a err_t return code. - */ -err_t -dns_gethostbyname(const char *hostname, ip_addr_t *addr, dns_found_callback found, - void *callback_arg) -{ - return dns_gethostbyname_addrtype(hostname, addr, found, callback_arg, LWIP_DNS_ADDRTYPE_DEFAULT); -} - -/** - * @ingroup dns - * Like dns_gethostbyname, but returned address type can be controlled: - * @param hostname the hostname that is to be queried - * @param addr pointer to a ip_addr_t where to store the address if it is already - * cached in the dns_table (only valid if ERR_OK is returned!) - * @param found a callback function to be called on success, failure or timeout (only if - * ERR_INPROGRESS is returned!) - * @param callback_arg argument to pass to the callback function - * @param dns_addrtype - LWIP_DNS_ADDRTYPE_IPV4_IPV6: try to resolve IPv4 first, try IPv6 if IPv4 fails only - * - LWIP_DNS_ADDRTYPE_IPV6_IPV4: try to resolve IPv6 first, try IPv4 if IPv6 fails only - * - LWIP_DNS_ADDRTYPE_IPV4: try to resolve IPv4 only - * - LWIP_DNS_ADDRTYPE_IPV6: try to resolve IPv6 only - */ -err_t -dns_gethostbyname_addrtype(const char *hostname, ip_addr_t *addr, dns_found_callback found, - void *callback_arg, u8_t dns_addrtype) -{ - size_t hostnamelen; -#if LWIP_DNS_SUPPORT_MDNS_QUERIES - u8_t is_mdns; -#endif - /* not initialized or no valid server yet, or invalid addr pointer - * or invalid hostname or invalid hostname length */ - if ((addr == NULL) || - (!hostname) || (!hostname[0])) { - return ERR_ARG; - } -#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) == 0) - if (dns_pcbs[0] == NULL) { - return ERR_ARG; - } -#endif - hostnamelen = strlen(hostname); - if (hostnamelen >= DNS_MAX_NAME_LENGTH) { - LWIP_DEBUGF(DNS_DEBUG, ("dns_gethostbyname: name too long to resolve")); - return ERR_ARG; - } - - -#if LWIP_HAVE_LOOPIF - if (strcmp(hostname, "localhost") == 0) { - ip_addr_set_loopback(LWIP_DNS_ADDRTYPE_IS_IPV6(dns_addrtype), addr); - return ERR_OK; - } -#endif /* LWIP_HAVE_LOOPIF */ - - /* host name already in octet notation? set ip addr and return ERR_OK */ - if (ipaddr_aton(hostname, addr)) { -#if LWIP_IPV4 && LWIP_IPV6 - if ((IP_IS_V6(addr) && (dns_addrtype != LWIP_DNS_ADDRTYPE_IPV4)) || - (IP_IS_V4(addr) && (dns_addrtype != LWIP_DNS_ADDRTYPE_IPV6))) -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - { - return ERR_OK; - } - } - /* already have this address cached? */ - if (dns_lookup(hostname, addr LWIP_DNS_ADDRTYPE_ARG(dns_addrtype)) == ERR_OK) { - return ERR_OK; - } -#if LWIP_IPV4 && LWIP_IPV6 - if ((dns_addrtype == LWIP_DNS_ADDRTYPE_IPV4_IPV6) || (dns_addrtype == LWIP_DNS_ADDRTYPE_IPV6_IPV4)) { - /* fallback to 2nd IP type and try again to lookup */ - u8_t fallback; - if (dns_addrtype == LWIP_DNS_ADDRTYPE_IPV4_IPV6) { - fallback = LWIP_DNS_ADDRTYPE_IPV6; - } else { - fallback = LWIP_DNS_ADDRTYPE_IPV4; - } - if (dns_lookup(hostname, addr LWIP_DNS_ADDRTYPE_ARG(fallback)) == ERR_OK) { - return ERR_OK; - } - } -#else /* LWIP_IPV4 && LWIP_IPV6 */ - LWIP_UNUSED_ARG(dns_addrtype); -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - -#if LWIP_DNS_SUPPORT_MDNS_QUERIES - if (strstr(hostname, ".local") == &hostname[hostnamelen] - 6) { - is_mdns = 1; - } else { - is_mdns = 0; - } - - if (!is_mdns) -#endif /* LWIP_DNS_SUPPORT_MDNS_QUERIES */ - { - /* prevent calling found callback if no server is set, return error instead */ - if (ip_addr_isany_val(dns_servers[0])) { - return ERR_VAL; - } - } - - /* queue query with specified callback */ - return dns_enqueue(hostname, hostnamelen, found, callback_arg LWIP_DNS_ADDRTYPE_ARG(dns_addrtype) - LWIP_DNS_ISMDNS_ARG(is_mdns)); -} - -#endif /* LWIP_DNS */ diff --git a/third-party/lwip-2.1.2/core/inet_chksum.c b/third-party/lwip-2.1.2/core/inet_chksum.c deleted file mode 100644 index 818c68f4..00000000 --- a/third-party/lwip-2.1.2/core/inet_chksum.c +++ /dev/null @@ -1,608 +0,0 @@ -/** - * @file - * Internet checksum functions.\n - * - * These are some reference implementations of the checksum algorithm, with the - * aim of being simple, correct and fully portable. Checksumming is the - * first thing you would want to optimize for your platform. If you create - * your own version, link it in and in your cc.h put: - * - * \#define LWIP_CHKSUM your_checksum_routine - * - * Or you can select from the implementations below by defining - * LWIP_CHKSUM_ALGORITHM to 1, 2 or 3. - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#include "lwip/opt.h" - -#include "lwip/inet_chksum.h" -#include "lwip/def.h" -#include "lwip/ip_addr.h" - -#include - -#ifndef LWIP_CHKSUM -# define LWIP_CHKSUM lwip_standard_chksum -# ifndef LWIP_CHKSUM_ALGORITHM -# define LWIP_CHKSUM_ALGORITHM 2 -# endif -u16_t lwip_standard_chksum(const void *dataptr, int len); -#endif -/* If none set: */ -#ifndef LWIP_CHKSUM_ALGORITHM -# define LWIP_CHKSUM_ALGORITHM 0 -#endif - -#if (LWIP_CHKSUM_ALGORITHM == 1) /* Version #1 */ -/** - * lwip checksum - * - * @param dataptr points to start of data to be summed at any boundary - * @param len length of data to be summed - * @return host order (!) lwip checksum (non-inverted Internet sum) - * - * @note accumulator size limits summable length to 64k - * @note host endianess is irrelevant (p3 RFC1071) - */ -u16_t -lwip_standard_chksum(const void *dataptr, int len) -{ - u32_t acc; - u16_t src; - const u8_t *octetptr; - - acc = 0; - /* dataptr may be at odd or even addresses */ - octetptr = (const u8_t *)dataptr; - while (len > 1) { - /* declare first octet as most significant - thus assume network order, ignoring host order */ - src = (*octetptr) << 8; - octetptr++; - /* declare second octet as least significant */ - src |= (*octetptr); - octetptr++; - acc += src; - len -= 2; - } - if (len > 0) { - /* accumulate remaining octet */ - src = (*octetptr) << 8; - acc += src; - } - /* add deferred carry bits */ - acc = (acc >> 16) + (acc & 0x0000ffffUL); - if ((acc & 0xffff0000UL) != 0) { - acc = (acc >> 16) + (acc & 0x0000ffffUL); - } - /* This maybe a little confusing: reorder sum using lwip_htons() - instead of lwip_ntohs() since it has a little less call overhead. - The caller must invert bits for Internet sum ! */ - return lwip_htons((u16_t)acc); -} -#endif - -#if (LWIP_CHKSUM_ALGORITHM == 2) /* Alternative version #2 */ -/* - * Curt McDowell - * Broadcom Corp. - * csm@broadcom.com - * - * IP checksum two bytes at a time with support for - * unaligned buffer. - * Works for len up to and including 0x20000. - * by Curt McDowell, Broadcom Corp. 12/08/2005 - * - * @param dataptr points to start of data to be summed at any boundary - * @param len length of data to be summed - * @return host order (!) lwip checksum (non-inverted Internet sum) - */ -u16_t -lwip_standard_chksum(const void *dataptr, int len) -{ - const u8_t *pb = (const u8_t *)dataptr; - const u16_t *ps; - u16_t t = 0; - u32_t sum = 0; - int odd = ((mem_ptr_t)pb & 1); - - /* Get aligned to u16_t */ - if (odd && len > 0) { - ((u8_t *)&t)[1] = *pb++; - len--; - } - - /* Add the bulk of the data */ - ps = (const u16_t *)(const void *)pb; - while (len > 1) { - sum += *ps++; - len -= 2; - } - - /* Consume left-over byte, if any */ - if (len > 0) { - ((u8_t *)&t)[0] = *(const u8_t *)ps; - } - - /* Add end bytes */ - sum += t; - - /* Fold 32-bit sum to 16 bits - calling this twice is probably faster than if statements... */ - sum = FOLD_U32T(sum); - sum = FOLD_U32T(sum); - - /* Swap if alignment was odd */ - if (odd) { - sum = SWAP_BYTES_IN_WORD(sum); - } - - return (u16_t)sum; -} -#endif - -#if (LWIP_CHKSUM_ALGORITHM == 3) /* Alternative version #3 */ -/** - * An optimized checksum routine. Basically, it uses loop-unrolling on - * the checksum loop, treating the head and tail bytes specially, whereas - * the inner loop acts on 8 bytes at a time. - * - * @arg start of buffer to be checksummed. May be an odd byte address. - * @len number of bytes in the buffer to be checksummed. - * @return host order (!) lwip checksum (non-inverted Internet sum) - * - * by Curt McDowell, Broadcom Corp. December 8th, 2005 - */ -u16_t -lwip_standard_chksum(const void *dataptr, int len) -{ - const u8_t *pb = (const u8_t *)dataptr; - const u16_t *ps; - u16_t t = 0; - const u32_t *pl; - u32_t sum = 0, tmp; - /* starts at odd byte address? */ - int odd = ((mem_ptr_t)pb & 1); - - if (odd && len > 0) { - ((u8_t *)&t)[1] = *pb++; - len--; - } - - ps = (const u16_t *)(const void *)pb; - - if (((mem_ptr_t)ps & 3) && len > 1) { - sum += *ps++; - len -= 2; - } - - pl = (const u32_t *)(const void *)ps; - - while (len > 7) { - tmp = sum + *pl++; /* ping */ - if (tmp < sum) { - tmp++; /* add back carry */ - } - - sum = tmp + *pl++; /* pong */ - if (sum < tmp) { - sum++; /* add back carry */ - } - - len -= 8; - } - - /* make room in upper bits */ - sum = FOLD_U32T(sum); - - ps = (const u16_t *)pl; - - /* 16-bit aligned word remaining? */ - while (len > 1) { - sum += *ps++; - len -= 2; - } - - /* dangling tail byte remaining? */ - if (len > 0) { /* include odd byte */ - ((u8_t *)&t)[0] = *(const u8_t *)ps; - } - - sum += t; /* add end bytes */ - - /* Fold 32-bit sum to 16 bits - calling this twice is probably faster than if statements... */ - sum = FOLD_U32T(sum); - sum = FOLD_U32T(sum); - - if (odd) { - sum = SWAP_BYTES_IN_WORD(sum); - } - - return (u16_t)sum; -} -#endif - -/** Parts of the pseudo checksum which are common to IPv4 and IPv6 */ -static u16_t -inet_cksum_pseudo_base(struct pbuf *p, u8_t proto, u16_t proto_len, u32_t acc) -{ - struct pbuf *q; - int swapped = 0; - - /* iterate through all pbuf in chain */ - for (q = p; q != NULL; q = q->next) { - LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n", - (void *)q, (void *)q->next)); - acc += LWIP_CHKSUM(q->payload, q->len); - /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/ - /* just executing this next line is probably faster that the if statement needed - to check whether we really need to execute it, and does no harm */ - acc = FOLD_U32T(acc); - if (q->len % 2 != 0) { - swapped = !swapped; - acc = SWAP_BYTES_IN_WORD(acc); - } - /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/ - } - - if (swapped) { - acc = SWAP_BYTES_IN_WORD(acc); - } - - acc += (u32_t)lwip_htons((u16_t)proto); - acc += (u32_t)lwip_htons(proto_len); - - /* Fold 32-bit sum to 16 bits - calling this twice is probably faster than if statements... */ - acc = FOLD_U32T(acc); - acc = FOLD_U32T(acc); - LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc)); - return (u16_t)~(acc & 0xffffUL); -} - -#if LWIP_IPV4 -/* inet_chksum_pseudo: - * - * Calculates the IPv4 pseudo Internet checksum used by TCP and UDP for a pbuf chain. - * IP addresses are expected to be in network byte order. - * - * @param p chain of pbufs over that a checksum should be calculated (ip data part) - * @param src source ip address (used for checksum of pseudo header) - * @param dst destination ip address (used for checksum of pseudo header) - * @param proto ip protocol (used for checksum of pseudo header) - * @param proto_len length of the ip data part (used for checksum of pseudo header) - * @return checksum (as u16_t) to be saved directly in the protocol header - */ -u16_t -inet_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len, - const ip4_addr_t *src, const ip4_addr_t *dest) -{ - u32_t acc; - u32_t addr; - - addr = ip4_addr_get_u32(src); - acc = (addr & 0xffffUL); - acc = (u32_t)(acc + ((addr >> 16) & 0xffffUL)); - addr = ip4_addr_get_u32(dest); - acc = (u32_t)(acc + (addr & 0xffffUL)); - acc = (u32_t)(acc + ((addr >> 16) & 0xffffUL)); - /* fold down to 16 bits */ - acc = FOLD_U32T(acc); - acc = FOLD_U32T(acc); - - return inet_cksum_pseudo_base(p, proto, proto_len, acc); -} -#endif /* LWIP_IPV4 */ - -#if LWIP_IPV6 -/** - * Calculates the checksum with IPv6 pseudo header used by TCP and UDP for a pbuf chain. - * IPv6 addresses are expected to be in network byte order. - * - * @param p chain of pbufs over that a checksum should be calculated (ip data part) - * @param proto ipv6 protocol/next header (used for checksum of pseudo header) - * @param proto_len length of the ipv6 payload (used for checksum of pseudo header) - * @param src source ipv6 address (used for checksum of pseudo header) - * @param dest destination ipv6 address (used for checksum of pseudo header) - * @return checksum (as u16_t) to be saved directly in the protocol header - */ -u16_t -ip6_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len, - const ip6_addr_t *src, const ip6_addr_t *dest) -{ - u32_t acc = 0; - u32_t addr; - u8_t addr_part; - - for (addr_part = 0; addr_part < 4; addr_part++) { - addr = src->addr[addr_part]; - acc = (u32_t)(acc + (addr & 0xffffUL)); - acc = (u32_t)(acc + ((addr >> 16) & 0xffffUL)); - addr = dest->addr[addr_part]; - acc = (u32_t)(acc + (addr & 0xffffUL)); - acc = (u32_t)(acc + ((addr >> 16) & 0xffffUL)); - } - /* fold down to 16 bits */ - acc = FOLD_U32T(acc); - acc = FOLD_U32T(acc); - - return inet_cksum_pseudo_base(p, proto, proto_len, acc); -} -#endif /* LWIP_IPV6 */ - -/* ip_chksum_pseudo: - * - * Calculates the IPv4 or IPv6 pseudo Internet checksum used by TCP and UDP for a pbuf chain. - * IP addresses are expected to be in network byte order. - * - * @param p chain of pbufs over that a checksum should be calculated (ip data part) - * @param src source ip address (used for checksum of pseudo header) - * @param dst destination ip address (used for checksum of pseudo header) - * @param proto ip protocol (used for checksum of pseudo header) - * @param proto_len length of the ip data part (used for checksum of pseudo header) - * @return checksum (as u16_t) to be saved directly in the protocol header - */ -u16_t -ip_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len, - const ip_addr_t *src, const ip_addr_t *dest) -{ -#if LWIP_IPV6 - if (IP_IS_V6(dest)) { - return ip6_chksum_pseudo(p, proto, proto_len, ip_2_ip6(src), ip_2_ip6(dest)); - } -#endif /* LWIP_IPV6 */ -#if LWIP_IPV4 && LWIP_IPV6 - else -#endif /* LWIP_IPV4 && LWIP_IPV6 */ -#if LWIP_IPV4 - { - return inet_chksum_pseudo(p, proto, proto_len, ip_2_ip4(src), ip_2_ip4(dest)); - } -#endif /* LWIP_IPV4 */ -} - -/** Parts of the pseudo checksum which are common to IPv4 and IPv6 */ -static u16_t -inet_cksum_pseudo_partial_base(struct pbuf *p, u8_t proto, u16_t proto_len, - u16_t chksum_len, u32_t acc) -{ - struct pbuf *q; - int swapped = 0; - u16_t chklen; - - /* iterate through all pbuf in chain */ - for (q = p; (q != NULL) && (chksum_len > 0); q = q->next) { - LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n", - (void *)q, (void *)q->next)); - chklen = q->len; - if (chklen > chksum_len) { - chklen = chksum_len; - } - acc += LWIP_CHKSUM(q->payload, chklen); - chksum_len = (u16_t)(chksum_len - chklen); - LWIP_ASSERT("delete me", chksum_len < 0x7fff); - /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/ - /* fold the upper bit down */ - acc = FOLD_U32T(acc); - if (q->len % 2 != 0) { - swapped = !swapped; - acc = SWAP_BYTES_IN_WORD(acc); - } - /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/ - } - - if (swapped) { - acc = SWAP_BYTES_IN_WORD(acc); - } - - acc += (u32_t)lwip_htons((u16_t)proto); - acc += (u32_t)lwip_htons(proto_len); - - /* Fold 32-bit sum to 16 bits - calling this twice is probably faster than if statements... */ - acc = FOLD_U32T(acc); - acc = FOLD_U32T(acc); - LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc)); - return (u16_t)~(acc & 0xffffUL); -} - -#if LWIP_IPV4 -/* inet_chksum_pseudo_partial: - * - * Calculates the IPv4 pseudo Internet checksum used by TCP and UDP for a pbuf chain. - * IP addresses are expected to be in network byte order. - * - * @param p chain of pbufs over that a checksum should be calculated (ip data part) - * @param src source ip address (used for checksum of pseudo header) - * @param dst destination ip address (used for checksum of pseudo header) - * @param proto ip protocol (used for checksum of pseudo header) - * @param proto_len length of the ip data part (used for checksum of pseudo header) - * @return checksum (as u16_t) to be saved directly in the protocol header - */ -u16_t -inet_chksum_pseudo_partial(struct pbuf *p, u8_t proto, u16_t proto_len, - u16_t chksum_len, const ip4_addr_t *src, const ip4_addr_t *dest) -{ - u32_t acc; - u32_t addr; - - addr = ip4_addr_get_u32(src); - acc = (addr & 0xffffUL); - acc = (u32_t)(acc + ((addr >> 16) & 0xffffUL)); - addr = ip4_addr_get_u32(dest); - acc = (u32_t)(acc + (addr & 0xffffUL)); - acc = (u32_t)(acc + ((addr >> 16) & 0xffffUL)); - /* fold down to 16 bits */ - acc = FOLD_U32T(acc); - acc = FOLD_U32T(acc); - - return inet_cksum_pseudo_partial_base(p, proto, proto_len, chksum_len, acc); -} -#endif /* LWIP_IPV4 */ - -#if LWIP_IPV6 -/** - * Calculates the checksum with IPv6 pseudo header used by TCP and UDP for a pbuf chain. - * IPv6 addresses are expected to be in network byte order. Will only compute for a - * portion of the payload. - * - * @param p chain of pbufs over that a checksum should be calculated (ip data part) - * @param proto ipv6 protocol/next header (used for checksum of pseudo header) - * @param proto_len length of the ipv6 payload (used for checksum of pseudo header) - * @param chksum_len number of payload bytes used to compute chksum - * @param src source ipv6 address (used for checksum of pseudo header) - * @param dest destination ipv6 address (used for checksum of pseudo header) - * @return checksum (as u16_t) to be saved directly in the protocol header - */ -u16_t -ip6_chksum_pseudo_partial(struct pbuf *p, u8_t proto, u16_t proto_len, - u16_t chksum_len, const ip6_addr_t *src, const ip6_addr_t *dest) -{ - u32_t acc = 0; - u32_t addr; - u8_t addr_part; - - for (addr_part = 0; addr_part < 4; addr_part++) { - addr = src->addr[addr_part]; - acc = (u32_t)(acc + (addr & 0xffffUL)); - acc = (u32_t)(acc + ((addr >> 16) & 0xffffUL)); - addr = dest->addr[addr_part]; - acc = (u32_t)(acc + (addr & 0xffffUL)); - acc = (u32_t)(acc + ((addr >> 16) & 0xffffUL)); - } - /* fold down to 16 bits */ - acc = FOLD_U32T(acc); - acc = FOLD_U32T(acc); - - return inet_cksum_pseudo_partial_base(p, proto, proto_len, chksum_len, acc); -} -#endif /* LWIP_IPV6 */ - -/* ip_chksum_pseudo_partial: - * - * Calculates the IPv4 or IPv6 pseudo Internet checksum used by TCP and UDP for a pbuf chain. - * - * @param p chain of pbufs over that a checksum should be calculated (ip data part) - * @param src source ip address (used for checksum of pseudo header) - * @param dst destination ip address (used for checksum of pseudo header) - * @param proto ip protocol (used for checksum of pseudo header) - * @param proto_len length of the ip data part (used for checksum of pseudo header) - * @return checksum (as u16_t) to be saved directly in the protocol header - */ -u16_t -ip_chksum_pseudo_partial(struct pbuf *p, u8_t proto, u16_t proto_len, - u16_t chksum_len, const ip_addr_t *src, const ip_addr_t *dest) -{ -#if LWIP_IPV6 - if (IP_IS_V6(dest)) { - return ip6_chksum_pseudo_partial(p, proto, proto_len, chksum_len, ip_2_ip6(src), ip_2_ip6(dest)); - } -#endif /* LWIP_IPV6 */ -#if LWIP_IPV4 && LWIP_IPV6 - else -#endif /* LWIP_IPV4 && LWIP_IPV6 */ -#if LWIP_IPV4 - { - return inet_chksum_pseudo_partial(p, proto, proto_len, chksum_len, ip_2_ip4(src), ip_2_ip4(dest)); - } -#endif /* LWIP_IPV4 */ -} - -/* inet_chksum: - * - * Calculates the Internet checksum over a portion of memory. Used primarily for IP - * and ICMP. - * - * @param dataptr start of the buffer to calculate the checksum (no alignment needed) - * @param len length of the buffer to calculate the checksum - * @return checksum (as u16_t) to be saved directly in the protocol header - */ - -u16_t -inet_chksum(const void *dataptr, u16_t len) -{ - return (u16_t)~(unsigned int)LWIP_CHKSUM(dataptr, len); -} - -/** - * Calculate a checksum over a chain of pbufs (without pseudo-header, much like - * inet_chksum only pbufs are used). - * - * @param p pbuf chain over that the checksum should be calculated - * @return checksum (as u16_t) to be saved directly in the protocol header - */ -u16_t -inet_chksum_pbuf(struct pbuf *p) -{ - u32_t acc; - struct pbuf *q; - int swapped = 0; - - acc = 0; - for (q = p; q != NULL; q = q->next) { - acc += LWIP_CHKSUM(q->payload, q->len); - acc = FOLD_U32T(acc); - if (q->len % 2 != 0) { - swapped = !swapped; - acc = SWAP_BYTES_IN_WORD(acc); - } - } - - if (swapped) { - acc = SWAP_BYTES_IN_WORD(acc); - } - return (u16_t)~(acc & 0xffffUL); -} - -/* These are some implementations for LWIP_CHKSUM_COPY, which copies data - * like MEMCPY but generates a checksum at the same time. Since this is a - * performance-sensitive function, you might want to create your own version - * in assembly targeted at your hardware by defining it in lwipopts.h: - * #define LWIP_CHKSUM_COPY(dst, src, len) your_chksum_copy(dst, src, len) - */ - -#if (LWIP_CHKSUM_COPY_ALGORITHM == 1) /* Version #1 */ -/** Safe but slow: first call MEMCPY, then call LWIP_CHKSUM. - * For architectures with big caches, data might still be in cache when - * generating the checksum after copying. - */ -u16_t -lwip_chksum_copy(void *dst, const void *src, u16_t len) -{ - MEMCPY(dst, src, len); - return LWIP_CHKSUM(dst, len); -} -#endif /* (LWIP_CHKSUM_COPY_ALGORITHM == 1) */ diff --git a/third-party/lwip-2.1.2/core/init.c b/third-party/lwip-2.1.2/core/init.c deleted file mode 100644 index d4211d39..00000000 --- a/third-party/lwip-2.1.2/core/init.c +++ /dev/null @@ -1,381 +0,0 @@ -/** - * @file - * Modules initialization - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - */ - -#include "lwip/opt.h" - -#include "lwip/init.h" -#include "lwip/stats.h" -#include "lwip/sys.h" -#include "lwip/mem.h" -#include "lwip/memp.h" -#include "lwip/pbuf.h" -#include "lwip/netif.h" -#include "lwip/sockets.h" -#include "lwip/ip.h" -#include "lwip/raw.h" -#include "lwip/udp.h" -#include "lwip/priv/tcp_priv.h" -#include "lwip/igmp.h" -#include "lwip/dns.h" -#include "lwip/timeouts.h" -#include "lwip/etharp.h" -#include "lwip/ip6.h" -#include "lwip/nd6.h" -#include "lwip/mld6.h" -#include "lwip/api.h" - -#include "netif/ppp/ppp_opts.h" -#include "netif/ppp/ppp_impl.h" - -#ifndef LWIP_SKIP_PACKING_CHECK - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct packed_struct_test { - PACK_STRUCT_FLD_8(u8_t dummy1); - PACK_STRUCT_FIELD(u32_t dummy2); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif -#define PACKED_STRUCT_TEST_EXPECTED_SIZE 5 - -#endif - -/* Compile-time sanity checks for configuration errors. - * These can be done independently of LWIP_DEBUG, without penalty. - */ -#ifndef BYTE_ORDER -#error "BYTE_ORDER is not defined, you have to define it in your cc.h" -#endif -#if (!IP_SOF_BROADCAST && IP_SOF_BROADCAST_RECV) -#error "If you want to use broadcast filter per pcb on recv operations, you have to define IP_SOF_BROADCAST=1 in your lwipopts.h" -#endif -#if (!LWIP_UDP && LWIP_UDPLITE) -#error "If you want to use UDP Lite, you have to define LWIP_UDP=1 in your lwipopts.h" -#endif -#if (!LWIP_UDP && LWIP_DHCP) -#error "If you want to use DHCP, you have to define LWIP_UDP=1 in your lwipopts.h" -#endif -#if (!LWIP_UDP && !LWIP_RAW && LWIP_MULTICAST_TX_OPTIONS) -#error "If you want to use LWIP_MULTICAST_TX_OPTIONS, you have to define LWIP_UDP=1 and/or LWIP_RAW=1 in your lwipopts.h" -#endif -#if (!LWIP_UDP && LWIP_DNS) -#error "If you want to use DNS, you have to define LWIP_UDP=1 in your lwipopts.h" -#endif -#if !MEMP_MEM_MALLOC /* MEMP_NUM_* checks are disabled when not using the pool allocator */ -#if (LWIP_ARP && ARP_QUEUEING && (MEMP_NUM_ARP_QUEUE<=0)) -#error "If you want to use ARP Queueing, you have to define MEMP_NUM_ARP_QUEUE>=1 in your lwipopts.h" -#endif -#if (LWIP_RAW && (MEMP_NUM_RAW_PCB<=0)) -#error "If you want to use RAW, you have to define MEMP_NUM_RAW_PCB>=1 in your lwipopts.h" -#endif -#if (LWIP_UDP && (MEMP_NUM_UDP_PCB<=0)) -#error "If you want to use UDP, you have to define MEMP_NUM_UDP_PCB>=1 in your lwipopts.h" -#endif -#if (LWIP_TCP && (MEMP_NUM_TCP_PCB<=0)) -#error "If you want to use TCP, you have to define MEMP_NUM_TCP_PCB>=1 in your lwipopts.h" -#endif -#if (LWIP_IGMP && (MEMP_NUM_IGMP_GROUP<=1)) -#error "If you want to use IGMP, you have to define MEMP_NUM_IGMP_GROUP>1 in your lwipopts.h" -#endif -#if (LWIP_IGMP && !LWIP_MULTICAST_TX_OPTIONS) -#error "If you want to use IGMP, you have to define LWIP_MULTICAST_TX_OPTIONS==1 in your lwipopts.h" -#endif -#if (LWIP_IGMP && !LWIP_IPV4) -#error "IGMP needs LWIP_IPV4 enabled in your lwipopts.h" -#endif -#if ((LWIP_NETCONN || LWIP_SOCKET) && (MEMP_NUM_TCPIP_MSG_API<=0)) -#error "If you want to use Sequential API, you have to define MEMP_NUM_TCPIP_MSG_API>=1 in your lwipopts.h" -#endif -/* There must be sufficient timeouts, taking into account requirements of the subsystems. */ -#if LWIP_TIMERS && (MEMP_NUM_SYS_TIMEOUT < LWIP_NUM_SYS_TIMEOUT_INTERNAL) -#error "MEMP_NUM_SYS_TIMEOUT is too low to accomodate all required timeouts" -#endif -#if (IP_REASSEMBLY && (MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS)) -#error "MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS doesn't make sense since each struct ip_reassdata must hold 2 pbufs at least!" -#endif -#endif /* !MEMP_MEM_MALLOC */ -#if LWIP_WND_SCALE -#if (LWIP_TCP && (TCP_WND > 0xffffffff)) -#error "If you want to use TCP, TCP_WND must fit in an u32_t, so, you have to reduce it in your lwipopts.h" -#endif -#if (LWIP_TCP && (TCP_RCV_SCALE > 14)) -#error "The maximum valid window scale value is 14!" -#endif -#if (LWIP_TCP && (TCP_WND > (0xFFFFU << TCP_RCV_SCALE))) -#error "TCP_WND is bigger than the configured LWIP_WND_SCALE allows!" -#endif -#if (LWIP_TCP && ((TCP_WND >> TCP_RCV_SCALE) == 0)) -#error "TCP_WND is too small for the configured LWIP_WND_SCALE (results in zero window)!" -#endif -#else /* LWIP_WND_SCALE */ -#if (LWIP_TCP && (TCP_WND > 0xffff)) -#error "If you want to use TCP, TCP_WND must fit in an u16_t, so, you have to reduce it in your lwipopts.h (or enable window scaling)" -#endif -#endif /* LWIP_WND_SCALE */ -#if (LWIP_TCP && (TCP_SND_QUEUELEN > 0xffff)) -#error "If you want to use TCP, TCP_SND_QUEUELEN must fit in an u16_t, so, you have to reduce it in your lwipopts.h" -#endif -#if (LWIP_TCP && (TCP_SND_QUEUELEN < 2)) -#error "TCP_SND_QUEUELEN must be at least 2 for no-copy TCP writes to work" -#endif -#if (LWIP_TCP && ((TCP_MAXRTX > 12) || (TCP_SYNMAXRTX > 12))) -#error "If you want to use TCP, TCP_MAXRTX and TCP_SYNMAXRTX must less or equal to 12 (due to tcp_backoff table), so, you have to reduce them in your lwipopts.h" -#endif -#if (LWIP_TCP && TCP_LISTEN_BACKLOG && ((TCP_DEFAULT_LISTEN_BACKLOG < 0) || (TCP_DEFAULT_LISTEN_BACKLOG > 0xff))) -#error "If you want to use TCP backlog, TCP_DEFAULT_LISTEN_BACKLOG must fit into an u8_t" -#endif -#if (LWIP_TCP && LWIP_TCP_SACK_OUT && !TCP_QUEUE_OOSEQ) -#error "To use LWIP_TCP_SACK_OUT, TCP_QUEUE_OOSEQ needs to be enabled" -#endif -#if (LWIP_TCP && LWIP_TCP_SACK_OUT && (LWIP_TCP_MAX_SACK_NUM < 1)) -#error "LWIP_TCP_MAX_SACK_NUM must be greater than 0" -#endif -#if (LWIP_NETIF_API && (NO_SYS==1)) -#error "If you want to use NETIF API, you have to define NO_SYS=0 in your lwipopts.h" -#endif -#if ((LWIP_SOCKET || LWIP_NETCONN) && (NO_SYS==1)) -#error "If you want to use Sequential API, you have to define NO_SYS=0 in your lwipopts.h" -#endif -#if (LWIP_PPP_API && (NO_SYS==1)) -#error "If you want to use PPP API, you have to define NO_SYS=0 in your lwipopts.h" -#endif -#if (LWIP_PPP_API && (PPP_SUPPORT==0)) -#error "If you want to use PPP API, you have to enable PPP_SUPPORT in your lwipopts.h" -#endif -#if (((!LWIP_DHCP) || (!LWIP_AUTOIP)) && LWIP_DHCP_AUTOIP_COOP) -#error "If you want to use DHCP/AUTOIP cooperation mode, you have to define LWIP_DHCP=1 and LWIP_AUTOIP=1 in your lwipopts.h" -#endif -#if (((!LWIP_DHCP) || (!LWIP_ARP)) && DHCP_DOES_ARP_CHECK) -#error "If you want to use DHCP ARP checking, you have to define LWIP_DHCP=1 and LWIP_ARP=1 in your lwipopts.h" -#endif -#if (!LWIP_ARP && LWIP_AUTOIP) -#error "If you want to use AUTOIP, you have to define LWIP_ARP=1 in your lwipopts.h" -#endif -#if (LWIP_TCP && ((LWIP_EVENT_API && LWIP_CALLBACK_API) || (!LWIP_EVENT_API && !LWIP_CALLBACK_API))) -#error "One and exactly one of LWIP_EVENT_API and LWIP_CALLBACK_API has to be enabled in your lwipopts.h" -#endif -#if (LWIP_ALTCP && LWIP_EVENT_API) -#error "The application layered tcp API does not work with LWIP_EVENT_API" -#endif -#if (MEM_LIBC_MALLOC && MEM_USE_POOLS) -#error "MEM_LIBC_MALLOC and MEM_USE_POOLS may not both be simultaneously enabled in your lwipopts.h" -#endif -#if (MEM_USE_POOLS && !MEMP_USE_CUSTOM_POOLS) -#error "MEM_USE_POOLS requires custom pools (MEMP_USE_CUSTOM_POOLS) to be enabled in your lwipopts.h" -#endif -#if (PBUF_POOL_BUFSIZE <= MEM_ALIGNMENT) -#error "PBUF_POOL_BUFSIZE must be greater than MEM_ALIGNMENT or the offset may take the full first pbuf" -#endif -#if (DNS_LOCAL_HOSTLIST && !DNS_LOCAL_HOSTLIST_IS_DYNAMIC && !(defined(DNS_LOCAL_HOSTLIST_INIT))) -#error "you have to define define DNS_LOCAL_HOSTLIST_INIT {{'host1', 0x123}, {'host2', 0x234}} to initialize DNS_LOCAL_HOSTLIST" -#endif -#if PPP_SUPPORT && !PPPOS_SUPPORT && !PPPOE_SUPPORT && !PPPOL2TP_SUPPORT -#error "PPP_SUPPORT needs at least one of PPPOS_SUPPORT, PPPOE_SUPPORT or PPPOL2TP_SUPPORT turned on" -#endif -#if PPP_SUPPORT && !PPP_IPV4_SUPPORT && !PPP_IPV6_SUPPORT -#error "PPP_SUPPORT needs PPP_IPV4_SUPPORT and/or PPP_IPV6_SUPPORT turned on" -#endif -#if PPP_SUPPORT && PPP_IPV4_SUPPORT && !LWIP_IPV4 -#error "PPP_IPV4_SUPPORT needs LWIP_IPV4 turned on" -#endif -#if PPP_SUPPORT && PPP_IPV6_SUPPORT && !LWIP_IPV6 -#error "PPP_IPV6_SUPPORT needs LWIP_IPV6 turned on" -#endif -#if !LWIP_ETHERNET && (LWIP_ARP || PPPOE_SUPPORT) -#error "LWIP_ETHERNET needs to be turned on for LWIP_ARP or PPPOE_SUPPORT" -#endif -#if LWIP_TCPIP_CORE_LOCKING_INPUT && !LWIP_TCPIP_CORE_LOCKING -#error "When using LWIP_TCPIP_CORE_LOCKING_INPUT, LWIP_TCPIP_CORE_LOCKING must be enabled, too" -#endif -#if LWIP_TCP && LWIP_NETIF_TX_SINGLE_PBUF && !TCP_OVERSIZE -#error "LWIP_NETIF_TX_SINGLE_PBUF needs TCP_OVERSIZE enabled to create single-pbuf TCP packets" -#endif -#if LWIP_NETCONN && LWIP_TCP -#if NETCONN_COPY != TCP_WRITE_FLAG_COPY -#error "NETCONN_COPY != TCP_WRITE_FLAG_COPY" -#endif -#if NETCONN_MORE != TCP_WRITE_FLAG_MORE -#error "NETCONN_MORE != TCP_WRITE_FLAG_MORE" -#endif -#endif /* LWIP_NETCONN && LWIP_TCP */ -#if LWIP_SOCKET -#endif /* LWIP_SOCKET */ - - -/* Compile-time checks for deprecated options. - */ -#ifdef MEMP_NUM_TCPIP_MSG -#error "MEMP_NUM_TCPIP_MSG option is deprecated. Remove it from your lwipopts.h." -#endif -#ifdef TCP_REXMIT_DEBUG -#error "TCP_REXMIT_DEBUG option is deprecated. Remove it from your lwipopts.h." -#endif -#ifdef RAW_STATS -#error "RAW_STATS option is deprecated. Remove it from your lwipopts.h." -#endif -#ifdef ETHARP_QUEUE_FIRST -#error "ETHARP_QUEUE_FIRST option is deprecated. Remove it from your lwipopts.h." -#endif -#ifdef ETHARP_ALWAYS_INSERT -#error "ETHARP_ALWAYS_INSERT option is deprecated. Remove it from your lwipopts.h." -#endif -#if !NO_SYS && LWIP_TCPIP_CORE_LOCKING && LWIP_COMPAT_MUTEX && !defined(LWIP_COMPAT_MUTEX_ALLOWED) -#error "LWIP_COMPAT_MUTEX cannot prevent priority inversion. It is recommended to implement priority-aware mutexes. (Define LWIP_COMPAT_MUTEX_ALLOWED to disable this error.)" -#endif - -#ifndef LWIP_DISABLE_TCP_SANITY_CHECKS -#define LWIP_DISABLE_TCP_SANITY_CHECKS 0 -#endif -#ifndef LWIP_DISABLE_MEMP_SANITY_CHECKS -#define LWIP_DISABLE_MEMP_SANITY_CHECKS 0 -#endif - -/* MEMP sanity checks */ -#if MEMP_MEM_MALLOC -#if !LWIP_DISABLE_MEMP_SANITY_CHECKS -#if LWIP_NETCONN || LWIP_SOCKET -#if !MEMP_NUM_NETCONN && LWIP_SOCKET -#error "lwip_sanity_check: WARNING: MEMP_NUM_NETCONN cannot be 0 when using sockets!" -#endif -#else /* MEMP_MEM_MALLOC */ -#if MEMP_NUM_NETCONN > (MEMP_NUM_TCP_PCB+MEMP_NUM_TCP_PCB_LISTEN+MEMP_NUM_UDP_PCB+MEMP_NUM_RAW_PCB) -#error "lwip_sanity_check: WARNING: MEMP_NUM_NETCONN should be less than the sum of MEMP_NUM_{TCP,RAW,UDP}_PCB+MEMP_NUM_TCP_PCB_LISTEN. If you know what you are doing, define LWIP_DISABLE_MEMP_SANITY_CHECKS to 1 to disable this error." -#endif -#endif /* LWIP_NETCONN || LWIP_SOCKET */ -#endif /* !LWIP_DISABLE_MEMP_SANITY_CHECKS */ -#if MEM_USE_POOLS -#error "MEMP_MEM_MALLOC and MEM_USE_POOLS cannot be enabled at the same time" -#endif -#ifdef LWIP_HOOK_MEMP_AVAILABLE -#error "LWIP_HOOK_MEMP_AVAILABLE doesn't make sense with MEMP_MEM_MALLOC" -#endif -#endif /* MEMP_MEM_MALLOC */ - -/* TCP sanity checks */ -#if !LWIP_DISABLE_TCP_SANITY_CHECKS -#if LWIP_TCP -#if !MEMP_MEM_MALLOC && (MEMP_NUM_TCP_SEG < TCP_SND_QUEUELEN) -#error "lwip_sanity_check: WARNING: MEMP_NUM_TCP_SEG should be at least as big as TCP_SND_QUEUELEN. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." -#endif -#if TCP_SND_BUF < (2 * TCP_MSS) -#error "lwip_sanity_check: WARNING: TCP_SND_BUF must be at least as much as (2 * TCP_MSS) for things to work smoothly. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." -#endif -#if TCP_SND_QUEUELEN < (2 * (TCP_SND_BUF / TCP_MSS)) -#error "lwip_sanity_check: WARNING: TCP_SND_QUEUELEN must be at least as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." -#endif -#if TCP_SNDLOWAT >= TCP_SND_BUF -#error "lwip_sanity_check: WARNING: TCP_SNDLOWAT must be less than TCP_SND_BUF. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." -#endif -#if TCP_SNDLOWAT >= (0xFFFF - (4 * TCP_MSS)) -#error "lwip_sanity_check: WARNING: TCP_SNDLOWAT must at least be 4*MSS below u16_t overflow!" -#endif -#if TCP_SNDQUEUELOWAT >= TCP_SND_QUEUELEN -#error "lwip_sanity_check: WARNING: TCP_SNDQUEUELOWAT must be less than TCP_SND_QUEUELEN. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." -#endif -#if !MEMP_MEM_MALLOC && PBUF_POOL_SIZE && (PBUF_POOL_BUFSIZE <= (PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN)) -#error "lwip_sanity_check: WARNING: PBUF_POOL_BUFSIZE does not provide enough space for protocol headers. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." -#endif -#if !MEMP_MEM_MALLOC && PBUF_POOL_SIZE && (TCP_WND > (PBUF_POOL_SIZE * (PBUF_POOL_BUFSIZE - (PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN)))) -#error "lwip_sanity_check: WARNING: TCP_WND is larger than space provided by PBUF_POOL_SIZE * (PBUF_POOL_BUFSIZE - protocol headers). If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." -#endif -#if TCP_WND < TCP_MSS -#error "lwip_sanity_check: WARNING: TCP_WND is smaller than MSS. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." -#endif -#endif /* LWIP_TCP */ -#endif /* !LWIP_DISABLE_TCP_SANITY_CHECKS */ - -/** - * @ingroup lwip_nosys - * Initialize all modules. - * Use this in NO_SYS mode. Use tcpip_init() otherwise. - */ -void -lwip_init(void) -{ -#ifndef LWIP_SKIP_CONST_CHECK - int a = 0; - LWIP_UNUSED_ARG(a); - LWIP_ASSERT("LWIP_CONST_CAST not implemented correctly. Check your lwIP port.", LWIP_CONST_CAST(void *, &a) == &a); -#endif -#ifndef LWIP_SKIP_PACKING_CHECK - LWIP_ASSERT("Struct packing not implemented correctly. Check your lwIP port.", sizeof(struct packed_struct_test) == PACKED_STRUCT_TEST_EXPECTED_SIZE); -#endif - - /* Modules initialization */ - stats_init(); -#if !NO_SYS - sys_init(); -#endif /* !NO_SYS */ - mem_init(); - memp_init(); - pbuf_init(); - netif_init(); - -#if LWIP_IPV4 - ip_init(); -#if LWIP_ARP - etharp_init(); -#endif /* LWIP_ARP */ -#endif /* LWIP_IPV4 */ -#if LWIP_RAW - raw_init(); -#endif /* LWIP_RAW */ -#if LWIP_UDP - udp_init(); -#endif /* LWIP_UDP */ -#if LWIP_TCP - tcp_init(); -#endif /* LWIP_TCP */ -#if LWIP_IGMP - igmp_init(); -#endif /* LWIP_IGMP */ -#if LWIP_DNS - dns_init(); -#endif /* LWIP_DNS */ -#if PPP_SUPPORT - ppp_init(); -#endif - -#if LWIP_TIMERS - sys_timeouts_init(); -#endif /* LWIP_TIMERS */ -} diff --git a/third-party/lwip-2.1.2/core/ip.c b/third-party/lwip-2.1.2/core/ip.c deleted file mode 100644 index 18514cf3..00000000 --- a/third-party/lwip-2.1.2/core/ip.c +++ /dev/null @@ -1,167 +0,0 @@ -/** - * @file - * Common IPv4 and IPv6 code - * - * @defgroup ip IP - * @ingroup callbackstyle_api - * - * @defgroup ip4 IPv4 - * @ingroup ip - * - * @defgroup ip6 IPv6 - * @ingroup ip - * - * @defgroup ipaddr IP address handling - * @ingroup infrastructure - * - * @defgroup ip4addr IPv4 only - * @ingroup ipaddr - * - * @defgroup ip6addr IPv6 only - * @ingroup ipaddr - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#include "lwip/opt.h" - -#if LWIP_IPV4 || LWIP_IPV6 - -#include "lwip/ip_addr.h" -#include "lwip/ip.h" - -/** Global data for both IPv4 and IPv6 */ -struct ip_globals ip_data; - -#if LWIP_IPV4 && LWIP_IPV6 - -const ip_addr_t ip_addr_any_type = IPADDR_ANY_TYPE_INIT; - -/** - * @ingroup ipaddr - * Convert numeric IP address (both versions) into ASCII representation. - * returns ptr to static buffer; not reentrant! - * - * @param addr ip address in network order to convert - * @return pointer to a global static (!) buffer that holds the ASCII - * representation of addr - */ -char *ipaddr_ntoa(const ip_addr_t *addr) -{ - if (addr == NULL) { - return NULL; - } - if (IP_IS_V6(addr)) { - return ip6addr_ntoa(ip_2_ip6(addr)); - } else { - return ip4addr_ntoa(ip_2_ip4(addr)); - } -} - -/** - * @ingroup ipaddr - * Same as ipaddr_ntoa, but reentrant since a user-supplied buffer is used. - * - * @param addr ip address in network order to convert - * @param buf target buffer where the string is stored - * @param buflen length of buf - * @return either pointer to buf which now holds the ASCII - * representation of addr or NULL if buf was too small - */ -char *ipaddr_ntoa_r(const ip_addr_t *addr, char *buf, int buflen) -{ - if (addr == NULL) { - return NULL; - } - if (IP_IS_V6(addr)) { - return ip6addr_ntoa_r(ip_2_ip6(addr), buf, buflen); - } else { - return ip4addr_ntoa_r(ip_2_ip4(addr), buf, buflen); - } -} - -/** - * @ingroup ipaddr - * Convert IP address string (both versions) to numeric. - * The version is auto-detected from the string. - * - * @param cp IP address string to convert - * @param addr conversion result is stored here - * @return 1 on success, 0 on error - */ -int -ipaddr_aton(const char *cp, ip_addr_t *addr) -{ - if (cp != NULL) { - const char *c; - for (c = cp; *c != 0; c++) { - if (*c == ':') { - /* contains a colon: IPv6 address */ - if (addr) { - IP_SET_TYPE_VAL(*addr, IPADDR_TYPE_V6); - } - return ip6addr_aton(cp, ip_2_ip6(addr)); - } else if (*c == '.') { - /* contains a dot: IPv4 address */ - break; - } - } - /* call ip4addr_aton as fallback or if IPv4 was found */ - if (addr) { - IP_SET_TYPE_VAL(*addr, IPADDR_TYPE_V4); - } - return ip4addr_aton(cp, ip_2_ip4(addr)); - } - return 0; -} - -/** - * @ingroup lwip_nosys - * If both IP versions are enabled, this function can dispatch packets to the correct one. - * Don't call directly, pass to netif_add() and call netif->input(). - */ -err_t -ip_input(struct pbuf *p, struct netif *inp) -{ - if (p != NULL) { - if (IP_HDR_GET_VERSION(p->payload) == 6) { - return ip6_input(p, inp); - } - return ip4_input(p, inp); - } - return ERR_VAL; -} - -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - -#endif /* LWIP_IPV4 || LWIP_IPV6 */ diff --git a/third-party/lwip-2.1.2/core/ipv4/autoip.c b/third-party/lwip-2.1.2/core/ipv4/autoip.c deleted file mode 100644 index 9f7139bc..00000000 --- a/third-party/lwip-2.1.2/core/ipv4/autoip.c +++ /dev/null @@ -1,527 +0,0 @@ -/** - * @file - * AutoIP Automatic LinkLocal IP Configuration - * - * This is a AutoIP implementation for the lwIP TCP/IP stack. It aims to conform - * with RFC 3927. - * - * @defgroup autoip AUTOIP - * @ingroup ip4 - * AUTOIP related functions - * USAGE: - * - * define @ref LWIP_AUTOIP 1 in your lwipopts.h - * Options: - * AUTOIP_TMR_INTERVAL msecs, - * I recommend a value of 100. The value must divide 1000 with a remainder almost 0. - * Possible values are 1000, 500, 333, 250, 200, 166, 142, 125, 111, 100 .... - * - * Without DHCP: - * - Call autoip_start() after netif_add(). - * - * With DHCP: - * - define @ref LWIP_DHCP_AUTOIP_COOP 1 in your lwipopts.h. - * - Configure your DHCP Client. - * - * @see netifapi_autoip - */ - -/* - * - * Copyright (c) 2007 Dominik Spies - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Dominik Spies - */ - -#include "lwip/opt.h" - -#if LWIP_IPV4 && LWIP_AUTOIP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/mem.h" -/* #include "lwip/udp.h" */ -#include "lwip/ip_addr.h" -#include "lwip/netif.h" -#include "lwip/autoip.h" -#include "lwip/etharp.h" -#include "lwip/prot/autoip.h" - -#include - -/** Pseudo random macro based on netif informations. - * You could use "rand()" from the C Library if you define LWIP_AUTOIP_RAND in lwipopts.h */ -#ifndef LWIP_AUTOIP_RAND -#define LWIP_AUTOIP_RAND(netif) ( (((u32_t)((netif->hwaddr[5]) & 0xff) << 24) | \ - ((u32_t)((netif->hwaddr[3]) & 0xff) << 16) | \ - ((u32_t)((netif->hwaddr[2]) & 0xff) << 8) | \ - ((u32_t)((netif->hwaddr[4]) & 0xff))) + \ - (netif_autoip_data(netif)? netif_autoip_data(netif)->tried_llipaddr : 0)) -#endif /* LWIP_AUTOIP_RAND */ - -/** - * Macro that generates the initial IP address to be tried by AUTOIP. - * If you want to override this, define it to something else in lwipopts.h. - */ -#ifndef LWIP_AUTOIP_CREATE_SEED_ADDR -#define LWIP_AUTOIP_CREATE_SEED_ADDR(netif) \ - lwip_htonl(AUTOIP_RANGE_START + ((u32_t)(((u8_t)(netif->hwaddr[4])) | \ - ((u32_t)((u8_t)(netif->hwaddr[5]))) << 8))) -#endif /* LWIP_AUTOIP_CREATE_SEED_ADDR */ - -/* static functions */ -static err_t autoip_arp_announce(struct netif *netif); -static void autoip_start_probing(struct netif *netif); - -/** - * @ingroup autoip - * Set a statically allocated struct autoip to work with. - * Using this prevents autoip_start to allocate it using mem_malloc. - * - * @param netif the netif for which to set the struct autoip - * @param autoip (uninitialised) autoip struct allocated by the application - */ -void -autoip_set_struct(struct netif *netif, struct autoip *autoip) -{ - LWIP_ASSERT_CORE_LOCKED(); - LWIP_ASSERT("netif != NULL", netif != NULL); - LWIP_ASSERT("autoip != NULL", autoip != NULL); - LWIP_ASSERT("netif already has a struct autoip set", - netif_autoip_data(netif) == NULL); - - /* clear data structure */ - memset(autoip, 0, sizeof(struct autoip)); - /* autoip->state = AUTOIP_STATE_OFF; */ - netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_AUTOIP, autoip); -} - -/** Restart AutoIP client and check the next address (conflict detected) - * - * @param netif The netif under AutoIP control - */ -static void -autoip_restart(struct netif *netif) -{ - struct autoip *autoip = netif_autoip_data(netif); - autoip->tried_llipaddr++; - autoip_start(netif); -} - -/** - * Handle a IP address conflict after an ARP conflict detection - */ -static void -autoip_handle_arp_conflict(struct netif *netif) -{ - struct autoip *autoip = netif_autoip_data(netif); - - /* RFC3927, 2.5 "Conflict Detection and Defense" allows two options where - a) means retreat on the first conflict and - b) allows to keep an already configured address when having only one - conflict in 10 seconds - We use option b) since it helps to improve the chance that one of the two - conflicting hosts may be able to retain its address. */ - - if (autoip->lastconflict > 0) { - /* retreat, there was a conflicting ARP in the last DEFEND_INTERVAL seconds */ - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, - ("autoip_handle_arp_conflict(): we are defending, but in DEFEND_INTERVAL, retreating\n")); - - /* Active TCP sessions are aborted when removing the ip addresss */ - autoip_restart(netif); - } else { - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, - ("autoip_handle_arp_conflict(): we are defend, send ARP Announce\n")); - autoip_arp_announce(netif); - autoip->lastconflict = DEFEND_INTERVAL * AUTOIP_TICKS_PER_SECOND; - } -} - -/** - * Create an IP-Address out of range 169.254.1.0 to 169.254.254.255 - * - * @param netif network interface on which create the IP-Address - * @param ipaddr ip address to initialize - */ -static void -autoip_create_addr(struct netif *netif, ip4_addr_t *ipaddr) -{ - struct autoip *autoip = netif_autoip_data(netif); - - /* Here we create an IP-Address out of range 169.254.1.0 to 169.254.254.255 - * compliant to RFC 3927 Section 2.1 - * We have 254 * 256 possibilities */ - - u32_t addr = lwip_ntohl(LWIP_AUTOIP_CREATE_SEED_ADDR(netif)); - addr += autoip->tried_llipaddr; - addr = AUTOIP_NET | (addr & 0xffff); - /* Now, 169.254.0.0 <= addr <= 169.254.255.255 */ - - if (addr < AUTOIP_RANGE_START) { - addr += AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1; - } - if (addr > AUTOIP_RANGE_END) { - addr -= AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1; - } - LWIP_ASSERT("AUTOIP address not in range", (addr >= AUTOIP_RANGE_START) && - (addr <= AUTOIP_RANGE_END)); - ip4_addr_set_u32(ipaddr, lwip_htonl(addr)); - - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, - ("autoip_create_addr(): tried_llipaddr=%"U16_F", %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - (u16_t)(autoip->tried_llipaddr), ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), - ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr))); -} - -/** - * Sends an ARP probe from a network interface - * - * @param netif network interface used to send the probe - */ -static err_t -autoip_arp_probe(struct netif *netif) -{ - struct autoip *autoip = netif_autoip_data(netif); - /* this works because netif->ip_addr is ANY */ - return etharp_request(netif, &autoip->llipaddr); -} - -/** - * Sends an ARP announce from a network interface - * - * @param netif network interface used to send the announce - */ -static err_t -autoip_arp_announce(struct netif *netif) -{ - return etharp_gratuitous(netif); -} - -/** - * Configure interface for use with current LL IP-Address - * - * @param netif network interface to configure with current LL IP-Address - */ -static err_t -autoip_bind(struct netif *netif) -{ - struct autoip *autoip = netif_autoip_data(netif); - ip4_addr_t sn_mask, gw_addr; - - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, - ("autoip_bind(netif=%p) %c%c%"U16_F" %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num, - ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr), - ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr))); - - IP4_ADDR(&sn_mask, 255, 255, 0, 0); - IP4_ADDR(&gw_addr, 0, 0, 0, 0); - - netif_set_addr(netif, &autoip->llipaddr, &sn_mask, &gw_addr); - /* interface is used by routing now that an address is set */ - - return ERR_OK; -} - -/** - * @ingroup autoip - * Start AutoIP client - * - * @param netif network interface on which start the AutoIP client - */ -err_t -autoip_start(struct netif *netif) -{ - struct autoip *autoip = netif_autoip_data(netif); - err_t result = ERR_OK; - - LWIP_ASSERT_CORE_LOCKED(); - LWIP_ERROR("netif is not up, old style port?", netif_is_up(netif), return ERR_ARG;); - - /* Set IP-Address, Netmask and Gateway to 0 to make sure that - * ARP Packets are formed correctly - */ - netif_set_addr(netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4); - - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, - ("autoip_start(netif=%p) %c%c%"U16_F"\n", (void *)netif, netif->name[0], - netif->name[1], (u16_t)netif->num)); - if (autoip == NULL) { - /* no AutoIP client attached yet? */ - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, - ("autoip_start(): starting new AUTOIP client\n")); - autoip = (struct autoip *)mem_calloc(1, sizeof(struct autoip)); - if (autoip == NULL) { - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, - ("autoip_start(): could not allocate autoip\n")); - return ERR_MEM; - } - /* store this AutoIP client in the netif */ - netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_AUTOIP, autoip); - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_start(): allocated autoip")); - } else { - autoip->state = AUTOIP_STATE_OFF; - autoip->ttw = 0; - autoip->sent_num = 0; - ip4_addr_set_zero(&autoip->llipaddr); - autoip->lastconflict = 0; - } - - autoip_create_addr(netif, &(autoip->llipaddr)); - autoip_start_probing(netif); - - return result; -} - -static void -autoip_start_probing(struct netif *netif) -{ - struct autoip *autoip = netif_autoip_data(netif); - - autoip->state = AUTOIP_STATE_PROBING; - autoip->sent_num = 0; - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, - ("autoip_start_probing(): changing state to PROBING: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr), - ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr))); - - /* time to wait to first probe, this is randomly - * chosen out of 0 to PROBE_WAIT seconds. - * compliant to RFC 3927 Section 2.2.1 - */ - autoip->ttw = (u16_t)(LWIP_AUTOIP_RAND(netif) % (PROBE_WAIT * AUTOIP_TICKS_PER_SECOND)); - - /* - * if we tried more then MAX_CONFLICTS we must limit our rate for - * acquiring and probing address - * compliant to RFC 3927 Section 2.2.1 - */ - if (autoip->tried_llipaddr > MAX_CONFLICTS) { - autoip->ttw = RATE_LIMIT_INTERVAL * AUTOIP_TICKS_PER_SECOND; - } -} - -/** - * Handle a possible change in the network configuration. - * - * If there is an AutoIP address configured, take the interface down - * and begin probing with the same address. - */ -void -autoip_network_changed(struct netif *netif) -{ - struct autoip *autoip = netif_autoip_data(netif); - - if (autoip && (autoip->state != AUTOIP_STATE_OFF)) { - autoip_start_probing(netif); - } -} - -/** - * @ingroup autoip - * Stop AutoIP client - * - * @param netif network interface on which stop the AutoIP client - */ -err_t -autoip_stop(struct netif *netif) -{ - struct autoip *autoip = netif_autoip_data(netif); - - LWIP_ASSERT_CORE_LOCKED(); - if (autoip != NULL) { - autoip->state = AUTOIP_STATE_OFF; - if (ip4_addr_islinklocal(netif_ip4_addr(netif))) { - netif_set_addr(netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4); - } - } - return ERR_OK; -} - -/** - * Has to be called in loop every AUTOIP_TMR_INTERVAL milliseconds - */ -void -autoip_tmr(void) -{ - struct netif *netif; - /* loop through netif's */ - NETIF_FOREACH(netif) { - struct autoip *autoip = netif_autoip_data(netif); - /* only act on AutoIP configured interfaces */ - if (autoip != NULL) { - if (autoip->lastconflict > 0) { - autoip->lastconflict--; - } - - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, - ("autoip_tmr() AutoIP-State: %"U16_F", ttw=%"U16_F"\n", - (u16_t)(autoip->state), autoip->ttw)); - - if (autoip->ttw > 0) { - autoip->ttw--; - } - - switch (autoip->state) { - case AUTOIP_STATE_PROBING: - if (autoip->ttw == 0) { - if (autoip->sent_num >= PROBE_NUM) { - /* Switch to ANNOUNCING: now we can bind to an IP address and use it */ - autoip->state = AUTOIP_STATE_ANNOUNCING; - autoip_bind(netif); - /* autoip_bind() calls netif_set_addr(): this triggers a gratuitous ARP - which counts as an announcement */ - autoip->sent_num = 1; - autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND; - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, - ("autoip_tmr(): changing state to ANNOUNCING: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr), - ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr))); - } else { - autoip_arp_probe(netif); - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_tmr() PROBING Sent Probe\n")); - autoip->sent_num++; - if (autoip->sent_num == PROBE_NUM) { - /* calculate time to wait to for announce */ - autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND; - } else { - /* calculate time to wait to next probe */ - autoip->ttw = (u16_t)((LWIP_AUTOIP_RAND(netif) % - ((PROBE_MAX - PROBE_MIN) * AUTOIP_TICKS_PER_SECOND) ) + - PROBE_MIN * AUTOIP_TICKS_PER_SECOND); - } - } - } - break; - - case AUTOIP_STATE_ANNOUNCING: - if (autoip->ttw == 0) { - autoip_arp_announce(netif); - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_tmr() ANNOUNCING Sent Announce\n")); - autoip->ttw = ANNOUNCE_INTERVAL * AUTOIP_TICKS_PER_SECOND; - autoip->sent_num++; - - if (autoip->sent_num >= ANNOUNCE_NUM) { - autoip->state = AUTOIP_STATE_BOUND; - autoip->sent_num = 0; - autoip->ttw = 0; - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, - ("autoip_tmr(): changing state to BOUND: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr), - ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr))); - } - } - break; - - default: - /* nothing to do in other states */ - break; - } - } - } -} - -/** - * Handles every incoming ARP Packet, called by etharp_input(). - * - * @param netif network interface to use for autoip processing - * @param hdr Incoming ARP packet - */ -void -autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr) -{ - struct autoip *autoip = netif_autoip_data(netif); - - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_arp_reply()\n")); - if ((autoip != NULL) && (autoip->state != AUTOIP_STATE_OFF)) { - /* when ip.src == llipaddr && hw.src != netif->hwaddr - * - * when probing ip.dst == llipaddr && hw.src != netif->hwaddr - * we have a conflict and must solve it - */ - ip4_addr_t sipaddr, dipaddr; - struct eth_addr netifaddr; - SMEMCPY(netifaddr.addr, netif->hwaddr, ETH_HWADDR_LEN); - - /* Copy struct ip4_addr_wordaligned to aligned ip4_addr, to support compilers without - * structure packing (not using structure copy which breaks strict-aliasing rules). - */ - IPADDR_WORDALIGNED_COPY_TO_IP4_ADDR_T(&sipaddr, &hdr->sipaddr); - IPADDR_WORDALIGNED_COPY_TO_IP4_ADDR_T(&dipaddr, &hdr->dipaddr); - - if (autoip->state == AUTOIP_STATE_PROBING) { - /* RFC 3927 Section 2.2.1: - * from beginning to after ANNOUNCE_WAIT - * seconds we have a conflict if - * ip.src == llipaddr OR - * ip.dst == llipaddr && hw.src != own hwaddr - */ - if ((ip4_addr_cmp(&sipaddr, &autoip->llipaddr)) || - (ip4_addr_isany_val(sipaddr) && - ip4_addr_cmp(&dipaddr, &autoip->llipaddr) && - !eth_addr_cmp(&netifaddr, &hdr->shwaddr))) { - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING, - ("autoip_arp_reply(): Probe Conflict detected\n")); - autoip_restart(netif); - } - } else { - /* RFC 3927 Section 2.5: - * in any state we have a conflict if - * ip.src == llipaddr && hw.src != own hwaddr - */ - if (ip4_addr_cmp(&sipaddr, &autoip->llipaddr) && - !eth_addr_cmp(&netifaddr, &hdr->shwaddr)) { - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING, - ("autoip_arp_reply(): Conflicting ARP-Packet detected\n")); - autoip_handle_arp_conflict(netif); - } - } - } -} - -/** check if AutoIP supplied netif->ip_addr - * - * @param netif the netif to check - * @return 1 if AutoIP supplied netif->ip_addr (state BOUND or ANNOUNCING), - * 0 otherwise - */ -u8_t -autoip_supplied_address(const struct netif *netif) -{ - if ((netif != NULL) && (netif_autoip_data(netif) != NULL)) { - struct autoip *autoip = netif_autoip_data(netif); - return (autoip->state == AUTOIP_STATE_BOUND) || (autoip->state == AUTOIP_STATE_ANNOUNCING); - } - return 0; -} - -u8_t -autoip_accept_packet(struct netif *netif, const ip4_addr_t *addr) -{ - struct autoip *autoip = netif_autoip_data(netif); - return (autoip != NULL) && ip4_addr_cmp(addr, &(autoip->llipaddr)); -} - -#endif /* LWIP_IPV4 && LWIP_AUTOIP */ diff --git a/third-party/lwip-2.1.2/core/ipv4/dhcp.c b/third-party/lwip-2.1.2/core/ipv4/dhcp.c deleted file mode 100644 index 534574fe..00000000 --- a/third-party/lwip-2.1.2/core/ipv4/dhcp.c +++ /dev/null @@ -1,1990 +0,0 @@ -/** - * @file - * Dynamic Host Configuration Protocol client - * - * @defgroup dhcp4 DHCPv4 - * @ingroup ip4 - * DHCP (IPv4) related functions - * This is a DHCP client for the lwIP TCP/IP stack. It aims to conform - * with RFC 2131 and RFC 2132. - * - * @todo: - * - Support for interfaces other than Ethernet (SLIP, PPP, ...) - * - * Options: - * @ref DHCP_COARSE_TIMER_SECS (recommended 60 which is a minute) - * @ref DHCP_FINE_TIMER_MSECS (recommended 500 which equals TCP coarse timer) - * - * dhcp_start() starts a DHCP client instance which - * configures the interface by obtaining an IP address lease and maintaining it. - * - * Use dhcp_release() to end the lease and use dhcp_stop() - * to remove the DHCP client. - * - * @see LWIP_HOOK_DHCP_APPEND_OPTIONS - * @see LWIP_HOOK_DHCP_PARSE_OPTION - * - * @see netifapi_dhcp4 - */ - -/* - * Copyright (c) 2001-2004 Leon Woestenberg - * Copyright (c) 2001-2004 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * The Swedish Institute of Computer Science and Adam Dunkels - * are specifically granted permission to redistribute this - * source code. - * - * Author: Leon Woestenberg - * - */ - -#include "lwip/opt.h" - -#if LWIP_IPV4 && LWIP_DHCP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/stats.h" -#include "lwip/mem.h" -#include "lwip/udp.h" -#include "lwip/ip_addr.h" -#include "lwip/netif.h" -#include "lwip/def.h" -#include "lwip/dhcp.h" -#include "lwip/autoip.h" -#include "lwip/dns.h" -#include "lwip/etharp.h" -#include "lwip/prot/dhcp.h" -#include "lwip/prot/iana.h" - -#include - -#ifdef LWIP_HOOK_FILENAME -#include LWIP_HOOK_FILENAME -#endif -#ifndef LWIP_HOOK_DHCP_APPEND_OPTIONS -#define LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, state, msg, msg_type, options_len_ptr) -#endif -#ifndef LWIP_HOOK_DHCP_PARSE_OPTION -#define LWIP_HOOK_DHCP_PARSE_OPTION(netif, dhcp, state, msg, msg_type, option, len, pbuf, offset) do { LWIP_UNUSED_ARG(msg); } while(0) -#endif - -/** DHCP_CREATE_RAND_XID: if this is set to 1, the xid is created using - * LWIP_RAND() (this overrides DHCP_GLOBAL_XID) - */ -#ifndef DHCP_CREATE_RAND_XID -#define DHCP_CREATE_RAND_XID 1 -#endif - -/** Default for DHCP_GLOBAL_XID is 0xABCD0000 - * This can be changed by defining DHCP_GLOBAL_XID and DHCP_GLOBAL_XID_HEADER, e.g. - * \#define DHCP_GLOBAL_XID_HEADER "stdlib.h" - * \#define DHCP_GLOBAL_XID rand() - */ -#ifdef DHCP_GLOBAL_XID_HEADER -#include DHCP_GLOBAL_XID_HEADER /* include optional starting XID generation prototypes */ -#endif - -/** DHCP_OPTION_MAX_MSG_SIZE is set to the MTU - * MTU is checked to be big enough in dhcp_start */ -#define DHCP_MAX_MSG_LEN(netif) (netif->mtu) -#define DHCP_MAX_MSG_LEN_MIN_REQUIRED 576 -/** Minimum length for reply before packet is parsed */ -#define DHCP_MIN_REPLY_LEN 44 - -#define REBOOT_TRIES 2 - -#if LWIP_DNS && LWIP_DHCP_MAX_DNS_SERVERS -#if DNS_MAX_SERVERS > LWIP_DHCP_MAX_DNS_SERVERS -#define LWIP_DHCP_PROVIDE_DNS_SERVERS LWIP_DHCP_MAX_DNS_SERVERS -#else -#define LWIP_DHCP_PROVIDE_DNS_SERVERS DNS_MAX_SERVERS -#endif -#else -#define LWIP_DHCP_PROVIDE_DNS_SERVERS 0 -#endif - -/** Option handling: options are parsed in dhcp_parse_reply - * and saved in an array where other functions can load them from. - * This might be moved into the struct dhcp (not necessarily since - * lwIP is single-threaded and the array is only used while in recv - * callback). */ -enum dhcp_option_idx { - DHCP_OPTION_IDX_OVERLOAD = 0, - DHCP_OPTION_IDX_MSG_TYPE, - DHCP_OPTION_IDX_SERVER_ID, - DHCP_OPTION_IDX_LEASE_TIME, - DHCP_OPTION_IDX_T1, - DHCP_OPTION_IDX_T2, - DHCP_OPTION_IDX_SUBNET_MASK, - DHCP_OPTION_IDX_ROUTER, -#if LWIP_DHCP_PROVIDE_DNS_SERVERS - DHCP_OPTION_IDX_DNS_SERVER, - DHCP_OPTION_IDX_DNS_SERVER_LAST = DHCP_OPTION_IDX_DNS_SERVER + LWIP_DHCP_PROVIDE_DNS_SERVERS - 1, -#endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS */ -#if LWIP_DHCP_GET_NTP_SRV - DHCP_OPTION_IDX_NTP_SERVER, - DHCP_OPTION_IDX_NTP_SERVER_LAST = DHCP_OPTION_IDX_NTP_SERVER + LWIP_DHCP_MAX_NTP_SERVERS - 1, -#endif /* LWIP_DHCP_GET_NTP_SRV */ - DHCP_OPTION_IDX_MAX -}; - -/** Holds the decoded option values, only valid while in dhcp_recv. - @todo: move this into struct dhcp? */ -u32_t dhcp_rx_options_val[DHCP_OPTION_IDX_MAX]; -/** Holds a flag which option was received and is contained in dhcp_rx_options_val, - only valid while in dhcp_recv. - @todo: move this into struct dhcp? */ -u8_t dhcp_rx_options_given[DHCP_OPTION_IDX_MAX]; - -static u8_t dhcp_discover_request_options[] = { - DHCP_OPTION_SUBNET_MASK, - DHCP_OPTION_ROUTER, - DHCP_OPTION_BROADCAST -#if LWIP_DHCP_PROVIDE_DNS_SERVERS - , DHCP_OPTION_DNS_SERVER -#endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS */ -#if LWIP_DHCP_GET_NTP_SRV - , DHCP_OPTION_NTP -#endif /* LWIP_DHCP_GET_NTP_SRV */ -}; - -#ifdef DHCP_GLOBAL_XID -static u32_t xid; -static u8_t xid_initialised; -#endif /* DHCP_GLOBAL_XID */ - -#define dhcp_option_given(dhcp, idx) (dhcp_rx_options_given[idx] != 0) -#define dhcp_got_option(dhcp, idx) (dhcp_rx_options_given[idx] = 1) -#define dhcp_clear_option(dhcp, idx) (dhcp_rx_options_given[idx] = 0) -#define dhcp_clear_all_options(dhcp) (memset(dhcp_rx_options_given, 0, sizeof(dhcp_rx_options_given))) -#define dhcp_get_option_value(dhcp, idx) (dhcp_rx_options_val[idx]) -#define dhcp_set_option_value(dhcp, idx, val) (dhcp_rx_options_val[idx] = (val)) - -static struct udp_pcb *dhcp_pcb; -static u8_t dhcp_pcb_refcount; - -/* DHCP client state machine functions */ -static err_t dhcp_discover(struct netif *netif); -static err_t dhcp_select(struct netif *netif); -static void dhcp_bind(struct netif *netif); -#if DHCP_DOES_ARP_CHECK -static err_t dhcp_decline(struct netif *netif); -#endif /* DHCP_DOES_ARP_CHECK */ -static err_t dhcp_rebind(struct netif *netif); -static err_t dhcp_reboot(struct netif *netif); -static void dhcp_set_state(struct dhcp *dhcp, u8_t new_state); - -/* receive, unfold, parse and free incoming messages */ -static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port); - -/* set the DHCP timers */ -static void dhcp_timeout(struct netif *netif); -static void dhcp_t1_timeout(struct netif *netif); -static void dhcp_t2_timeout(struct netif *netif); - -/* build outgoing messages */ -/* create a DHCP message, fill in common headers */ -static struct pbuf *dhcp_create_msg(struct netif *netif, struct dhcp *dhcp, u8_t message_type, u16_t *options_out_len); -/* add a DHCP option (type, then length in bytes) */ -static u16_t dhcp_option(u16_t options_out_len, u8_t *options, u8_t option_type, u8_t option_len); -/* add option values */ -static u16_t dhcp_option_byte(u16_t options_out_len, u8_t *options, u8_t value); -static u16_t dhcp_option_short(u16_t options_out_len, u8_t *options, u16_t value); -static u16_t dhcp_option_long(u16_t options_out_len, u8_t *options, u32_t value); -#if LWIP_NETIF_HOSTNAME -static u16_t dhcp_option_hostname(u16_t options_out_len, u8_t *options, struct netif *netif); -#endif /* LWIP_NETIF_HOSTNAME */ -/* always add the DHCP options trailer to end and pad */ -static void dhcp_option_trailer(u16_t options_out_len, u8_t *options, struct pbuf *p_out); - -/** Ensure DHCP PCB is allocated and bound */ -static err_t -dhcp_inc_pcb_refcount(void) -{ - if (dhcp_pcb_refcount == 0) { - LWIP_ASSERT("dhcp_inc_pcb_refcount(): memory leak", dhcp_pcb == NULL); - - /* allocate UDP PCB */ - dhcp_pcb = udp_new(); - - if (dhcp_pcb == NULL) { - return ERR_MEM; - } - - ip_set_option(dhcp_pcb, SOF_BROADCAST); - - /* set up local and remote port for the pcb -> listen on all interfaces on all src/dest IPs */ - udp_bind(dhcp_pcb, IP4_ADDR_ANY, LWIP_IANA_PORT_DHCP_CLIENT); - udp_connect(dhcp_pcb, IP4_ADDR_ANY, LWIP_IANA_PORT_DHCP_SERVER); - udp_recv(dhcp_pcb, dhcp_recv, NULL); - } - - dhcp_pcb_refcount++; - - return ERR_OK; -} - -/** Free DHCP PCB if the last netif stops using it */ -static void -dhcp_dec_pcb_refcount(void) -{ - LWIP_ASSERT("dhcp_pcb_refcount(): refcount error", (dhcp_pcb_refcount > 0)); - dhcp_pcb_refcount--; - - if (dhcp_pcb_refcount == 0) { - udp_remove(dhcp_pcb); - dhcp_pcb = NULL; - } -} - -/** - * Back-off the DHCP client (because of a received NAK response). - * - * Back-off the DHCP client because of a received NAK. Receiving a - * NAK means the client asked for something non-sensible, for - * example when it tries to renew a lease obtained on another network. - * - * We clear any existing set IP address and restart DHCP negotiation - * afresh (as per RFC2131 3.2.3). - * - * @param netif the netif under DHCP control - */ -static void -dhcp_handle_nak(struct netif *netif) -{ - struct dhcp *dhcp = netif_dhcp_data(netif); - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_handle_nak(netif=%p) %c%c%"U16_F"\n", - (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); - /* Change to a defined state - set this before assigning the address - to ensure the callback can use dhcp_supplied_address() */ - dhcp_set_state(dhcp, DHCP_STATE_BACKING_OFF); - /* remove IP address from interface (must no longer be used, as per RFC2131) */ - netif_set_addr(netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4); - /* We can immediately restart discovery */ - dhcp_discover(netif); -} - -#if DHCP_DOES_ARP_CHECK -/** - * Checks if the offered IP address is already in use. - * - * It does so by sending an ARP request for the offered address and - * entering CHECKING state. If no ARP reply is received within a small - * interval, the address is assumed to be free for use by us. - * - * @param netif the netif under DHCP control - */ -static void -dhcp_check(struct netif *netif) -{ - struct dhcp *dhcp = netif_dhcp_data(netif); - err_t result; - u16_t msecs; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_check(netif=%p) %c%c\n", (void *)netif, (s16_t)netif->name[0], - (s16_t)netif->name[1])); - dhcp_set_state(dhcp, DHCP_STATE_CHECKING); - /* create an ARP query for the offered IP address, expecting that no host - responds, as the IP address should not be in use. */ - result = etharp_query(netif, &dhcp->offered_ip_addr, NULL); - if (result != ERR_OK) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("dhcp_check: could not perform ARP query\n")); - } - if (dhcp->tries < 255) { - dhcp->tries++; - } - msecs = 500; - dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_check(): set request timeout %"U16_F" msecs\n", msecs)); -} -#endif /* DHCP_DOES_ARP_CHECK */ - -/** - * Remember the configuration offered by a DHCP server. - * - * @param netif the netif under DHCP control - */ -static void -dhcp_handle_offer(struct netif *netif, struct dhcp_msg *msg_in) -{ - struct dhcp *dhcp = netif_dhcp_data(netif); - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_handle_offer(netif=%p) %c%c%"U16_F"\n", - (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); - /* obtain the server address */ - if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_SERVER_ID)) { - dhcp->request_timeout = 0; /* stop timer */ - - ip_addr_set_ip4_u32(&dhcp->server_ip_addr, lwip_htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_SERVER_ID))); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_handle_offer(): server 0x%08"X32_F"\n", - ip4_addr_get_u32(ip_2_ip4(&dhcp->server_ip_addr)))); - /* remember offered address */ - ip4_addr_copy(dhcp->offered_ip_addr, msg_in->yiaddr); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_handle_offer(): offer for 0x%08"X32_F"\n", - ip4_addr_get_u32(&dhcp->offered_ip_addr))); - - dhcp_select(netif); - } else { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, - ("dhcp_handle_offer(netif=%p) did not get server ID!\n", (void *)netif)); - } -} - -/** - * Select a DHCP server offer out of all offers. - * - * Simply select the first offer received. - * - * @param netif the netif under DHCP control - * @return lwIP specific error (see error.h) - */ -static err_t -dhcp_select(struct netif *netif) -{ - struct dhcp *dhcp; - err_t result; - u16_t msecs; - u8_t i; - struct pbuf *p_out; - u16_t options_out_len; - - LWIP_ERROR("dhcp_select: netif != NULL", (netif != NULL), return ERR_ARG;); - dhcp = netif_dhcp_data(netif); - LWIP_ERROR("dhcp_select: dhcp != NULL", (dhcp != NULL), return ERR_VAL;); - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_select(netif=%p) %c%c%"U16_F"\n", (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); - dhcp_set_state(dhcp, DHCP_STATE_REQUESTING); - - /* create and initialize the DHCP message header */ - p_out = dhcp_create_msg(netif, dhcp, DHCP_REQUEST, &options_out_len); - if (p_out != NULL) { - struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload; - options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); - options_out_len = dhcp_option_short(options_out_len, msg_out->options, DHCP_MAX_MSG_LEN(netif)); - - /* MUST request the offered IP address */ - options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_REQUESTED_IP, 4); - options_out_len = dhcp_option_long(options_out_len, msg_out->options, lwip_ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr))); - - options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_SERVER_ID, 4); - options_out_len = dhcp_option_long(options_out_len, msg_out->options, lwip_ntohl(ip4_addr_get_u32(ip_2_ip4(&dhcp->server_ip_addr)))); - - options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_PARAMETER_REQUEST_LIST, LWIP_ARRAYSIZE(dhcp_discover_request_options)); - for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) { - options_out_len = dhcp_option_byte(options_out_len, msg_out->options, dhcp_discover_request_options[i]); - } - -#if LWIP_NETIF_HOSTNAME - options_out_len = dhcp_option_hostname(options_out_len, msg_out->options, netif); -#endif /* LWIP_NETIF_HOSTNAME */ - - LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, DHCP_STATE_REQUESTING, msg_out, DHCP_REQUEST, &options_out_len); - dhcp_option_trailer(options_out_len, msg_out->options, p_out); - - /* send broadcast to any DHCP server */ - result = udp_sendto_if_src(dhcp_pcb, p_out, IP_ADDR_BROADCAST, LWIP_IANA_PORT_DHCP_SERVER, netif, IP4_ADDR_ANY); - pbuf_free(p_out); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_select: REQUESTING\n")); - } else { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("dhcp_select: could not allocate DHCP request\n")); - result = ERR_MEM; - } - if (dhcp->tries < 255) { - dhcp->tries++; - } - msecs = (u16_t)((dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000); - dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_select(): set request timeout %"U16_F" msecs\n", msecs)); - return result; -} - -/** - * The DHCP timer that checks for lease renewal/rebind timeouts. - * Must be called once a minute (see @ref DHCP_COARSE_TIMER_SECS). - */ -void -dhcp_coarse_tmr(void) -{ - struct netif *netif; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_coarse_tmr()\n")); - /* iterate through all network interfaces */ - NETIF_FOREACH(netif) { - /* only act on DHCP configured interfaces */ - struct dhcp *dhcp = netif_dhcp_data(netif); - if ((dhcp != NULL) && (dhcp->state != DHCP_STATE_OFF)) { - /* compare lease time to expire timeout */ - if (dhcp->t0_timeout && (++dhcp->lease_used == dhcp->t0_timeout)) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t0 timeout\n")); - /* this clients' lease time has expired */ - dhcp_release_and_stop(netif); - dhcp_start(netif); - /* timer is active (non zero), and triggers (zeroes) now? */ - } else if (dhcp->t2_rebind_time && (dhcp->t2_rebind_time-- == 1)) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t2 timeout\n")); - /* this clients' rebind timeout triggered */ - dhcp_t2_timeout(netif); - /* timer is active (non zero), and triggers (zeroes) now */ - } else if (dhcp->t1_renew_time && (dhcp->t1_renew_time-- == 1)) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t1 timeout\n")); - /* this clients' renewal timeout triggered */ - dhcp_t1_timeout(netif); - } - } - } -} - -/** - * DHCP transaction timeout handling (this function must be called every 500ms, - * see @ref DHCP_FINE_TIMER_MSECS). - * - * A DHCP server is expected to respond within a short period of time. - * This timer checks whether an outstanding DHCP request is timed out. - */ -void -dhcp_fine_tmr(void) -{ - struct netif *netif; - /* loop through netif's */ - NETIF_FOREACH(netif) { - struct dhcp *dhcp = netif_dhcp_data(netif); - /* only act on DHCP configured interfaces */ - if (dhcp != NULL) { - /* timer is active (non zero), and is about to trigger now */ - if (dhcp->request_timeout > 1) { - dhcp->request_timeout--; - } else if (dhcp->request_timeout == 1) { - dhcp->request_timeout--; - /* { dhcp->request_timeout == 0 } */ - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_fine_tmr(): request timeout\n")); - /* this client's request timeout triggered */ - dhcp_timeout(netif); - } - } - } -} - -/** - * A DHCP negotiation transaction, or ARP request, has timed out. - * - * The timer that was started with the DHCP or ARP request has - * timed out, indicating no response was received in time. - * - * @param netif the netif under DHCP control - */ -static void -dhcp_timeout(struct netif *netif) -{ - struct dhcp *dhcp = netif_dhcp_data(netif); - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_timeout()\n")); - /* back-off period has passed, or server selection timed out */ - if ((dhcp->state == DHCP_STATE_BACKING_OFF) || (dhcp->state == DHCP_STATE_SELECTING)) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_timeout(): restarting discovery\n")); - dhcp_discover(netif); - /* receiving the requested lease timed out */ - } else if (dhcp->state == DHCP_STATE_REQUESTING) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REQUESTING, DHCP request timed out\n")); - if (dhcp->tries <= 5) { - dhcp_select(netif); - } else { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REQUESTING, releasing, restarting\n")); - dhcp_release_and_stop(netif); - dhcp_start(netif); - } -#if DHCP_DOES_ARP_CHECK - /* received no ARP reply for the offered address (which is good) */ - } else if (dhcp->state == DHCP_STATE_CHECKING) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): CHECKING, ARP request timed out\n")); - if (dhcp->tries <= 1) { - dhcp_check(netif); - /* no ARP replies on the offered address, - looks like the IP address is indeed free */ - } else { - /* bind the interface to the offered address */ - dhcp_bind(netif); - } -#endif /* DHCP_DOES_ARP_CHECK */ - } else if (dhcp->state == DHCP_STATE_REBOOTING) { - if (dhcp->tries < REBOOT_TRIES) { - dhcp_reboot(netif); - } else { - dhcp_discover(netif); - } - } -} - -/** - * The renewal period has timed out. - * - * @param netif the netif under DHCP control - */ -static void -dhcp_t1_timeout(struct netif *netif) -{ - struct dhcp *dhcp = netif_dhcp_data(netif); - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_t1_timeout()\n")); - if ((dhcp->state == DHCP_STATE_REQUESTING) || (dhcp->state == DHCP_STATE_BOUND) || - (dhcp->state == DHCP_STATE_RENEWING)) { - /* just retry to renew - note that the rebind timer (t2) will - * eventually time-out if renew tries fail. */ - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, - ("dhcp_t1_timeout(): must renew\n")); - /* This slightly different to RFC2131: DHCPREQUEST will be sent from state - DHCP_STATE_RENEWING, not DHCP_STATE_BOUND */ - dhcp_renew(netif); - /* Calculate next timeout */ - if (((dhcp->t2_timeout - dhcp->lease_used) / 2) >= ((60 + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS)) { - dhcp->t1_renew_time = (u16_t)((dhcp->t2_timeout - dhcp->lease_used) / 2); - } - } -} - -/** - * The rebind period has timed out. - * - * @param netif the netif under DHCP control - */ -static void -dhcp_t2_timeout(struct netif *netif) -{ - struct dhcp *dhcp = netif_dhcp_data(netif); - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_t2_timeout()\n")); - if ((dhcp->state == DHCP_STATE_REQUESTING) || (dhcp->state == DHCP_STATE_BOUND) || - (dhcp->state == DHCP_STATE_RENEWING) || (dhcp->state == DHCP_STATE_REBINDING)) { - /* just retry to rebind */ - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, - ("dhcp_t2_timeout(): must rebind\n")); - /* This slightly different to RFC2131: DHCPREQUEST will be sent from state - DHCP_STATE_REBINDING, not DHCP_STATE_BOUND */ - dhcp_rebind(netif); - /* Calculate next timeout */ - if (((dhcp->t0_timeout - dhcp->lease_used) / 2) >= ((60 + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS)) { - dhcp->t2_rebind_time = (u16_t)((dhcp->t0_timeout - dhcp->lease_used) / 2); - } - } -} - -/** - * Handle a DHCP ACK packet - * - * @param netif the netif under DHCP control - */ -static void -dhcp_handle_ack(struct netif *netif, struct dhcp_msg *msg_in) -{ - struct dhcp *dhcp = netif_dhcp_data(netif); - -#if LWIP_DHCP_PROVIDE_DNS_SERVERS || LWIP_DHCP_GET_NTP_SRV - u8_t n; -#endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS || LWIP_DHCP_GET_NTP_SRV */ -#if LWIP_DHCP_GET_NTP_SRV - ip4_addr_t ntp_server_addrs[LWIP_DHCP_MAX_NTP_SERVERS]; -#endif - - /* clear options we might not get from the ACK */ - ip4_addr_set_zero(&dhcp->offered_sn_mask); - ip4_addr_set_zero(&dhcp->offered_gw_addr); -#if LWIP_DHCP_BOOTP_FILE - ip4_addr_set_zero(&dhcp->offered_si_addr); -#endif /* LWIP_DHCP_BOOTP_FILE */ - - /* lease time given? */ - if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_LEASE_TIME)) { - /* remember offered lease time */ - dhcp->offered_t0_lease = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_LEASE_TIME); - } - /* renewal period given? */ - if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_T1)) { - /* remember given renewal period */ - dhcp->offered_t1_renew = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_T1); - } else { - /* calculate safe periods for renewal */ - dhcp->offered_t1_renew = dhcp->offered_t0_lease / 2; - } - - /* renewal period given? */ - if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_T2)) { - /* remember given rebind period */ - dhcp->offered_t2_rebind = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_T2); - } else { - /* calculate safe periods for rebinding (offered_t0_lease * 0.875 -> 87.5%)*/ - dhcp->offered_t2_rebind = (dhcp->offered_t0_lease * 7U) / 8U; - } - - /* (y)our internet address */ - ip4_addr_copy(dhcp->offered_ip_addr, msg_in->yiaddr); - -#if LWIP_DHCP_BOOTP_FILE - /* copy boot server address, - boot file name copied in dhcp_parse_reply if not overloaded */ - ip4_addr_copy(dhcp->offered_si_addr, msg_in->siaddr); -#endif /* LWIP_DHCP_BOOTP_FILE */ - - /* subnet mask given? */ - if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_SUBNET_MASK)) { - /* remember given subnet mask */ - ip4_addr_set_u32(&dhcp->offered_sn_mask, lwip_htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_SUBNET_MASK))); - dhcp->subnet_mask_given = 1; - } else { - dhcp->subnet_mask_given = 0; - } - - /* gateway router */ - if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_ROUTER)) { - ip4_addr_set_u32(&dhcp->offered_gw_addr, lwip_htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_ROUTER))); - } - -#if LWIP_DHCP_GET_NTP_SRV - /* NTP servers */ - for (n = 0; (n < LWIP_DHCP_MAX_NTP_SERVERS) && dhcp_option_given(dhcp, DHCP_OPTION_IDX_NTP_SERVER + n); n++) { - ip4_addr_set_u32(&ntp_server_addrs[n], lwip_htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_NTP_SERVER + n))); - } - dhcp_set_ntp_servers(n, ntp_server_addrs); -#endif /* LWIP_DHCP_GET_NTP_SRV */ - -#if LWIP_DHCP_PROVIDE_DNS_SERVERS - /* DNS servers */ - for (n = 0; (n < LWIP_DHCP_PROVIDE_DNS_SERVERS) && dhcp_option_given(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n); n++) { - ip_addr_t dns_addr; - ip_addr_set_ip4_u32_val(dns_addr, lwip_htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n))); - dns_setserver(n, &dns_addr); - } -#endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS */ -} - -/** - * @ingroup dhcp4 - * Set a statically allocated struct dhcp to work with. - * Using this prevents dhcp_start to allocate it using mem_malloc. - * - * @param netif the netif for which to set the struct dhcp - * @param dhcp (uninitialised) dhcp struct allocated by the application - */ -void -dhcp_set_struct(struct netif *netif, struct dhcp *dhcp) -{ - LWIP_ASSERT_CORE_LOCKED(); - LWIP_ASSERT("netif != NULL", netif != NULL); - LWIP_ASSERT("dhcp != NULL", dhcp != NULL); - LWIP_ASSERT("netif already has a struct dhcp set", netif_dhcp_data(netif) == NULL); - - /* clear data structure */ - memset(dhcp, 0, sizeof(struct dhcp)); - /* dhcp_set_state(&dhcp, DHCP_STATE_OFF); */ - netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP, dhcp); -} - -/** - * @ingroup dhcp4 - * Removes a struct dhcp from a netif. - * - * ATTENTION: Only use this when not using dhcp_set_struct() to allocate the - * struct dhcp since the memory is passed back to the heap. - * - * @param netif the netif from which to remove the struct dhcp - */ -void dhcp_cleanup(struct netif *netif) -{ - LWIP_ASSERT_CORE_LOCKED(); - LWIP_ASSERT("netif != NULL", netif != NULL); - - if (netif_dhcp_data(netif) != NULL) { - mem_free(netif_dhcp_data(netif)); - netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP, NULL); - } -} - -/** - * @ingroup dhcp4 - * Start DHCP negotiation for a network interface. - * - * If no DHCP client instance was attached to this interface, - * a new client is created first. If a DHCP client instance - * was already present, it restarts negotiation. - * - * @param netif The lwIP network interface - * @return lwIP error code - * - ERR_OK - No error - * - ERR_MEM - Out of memory - */ -err_t -dhcp_start(struct netif *netif) -{ - struct dhcp *dhcp; - err_t result; - - LWIP_ASSERT_CORE_LOCKED(); - LWIP_ERROR("netif != NULL", (netif != NULL), return ERR_ARG;); - LWIP_ERROR("netif is not up, old style port?", netif_is_up(netif), return ERR_ARG;); - dhcp = netif_dhcp_data(netif); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_start(netif=%p) %c%c%"U16_F"\n", (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); - - /* check MTU of the netif */ - if (netif->mtu < DHCP_MAX_MSG_LEN_MIN_REQUIRED) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): Cannot use this netif with DHCP: MTU is too small\n")); - return ERR_MEM; - } - - /* no DHCP client attached yet? */ - if (dhcp == NULL) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): mallocing new DHCP client\n")); - dhcp = (struct dhcp *)mem_malloc(sizeof(struct dhcp)); - if (dhcp == NULL) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): could not allocate dhcp\n")); - return ERR_MEM; - } - - /* store this dhcp client in the netif */ - netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP, dhcp); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): allocated dhcp")); - /* already has DHCP client attached */ - } else { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_start(): restarting DHCP configuration\n")); - - if (dhcp->pcb_allocated != 0) { - dhcp_dec_pcb_refcount(); /* free DHCP PCB if not needed any more */ - } - /* dhcp is cleared below, no need to reset flag*/ - } - - /* clear data structure */ - memset(dhcp, 0, sizeof(struct dhcp)); - /* dhcp_set_state(&dhcp, DHCP_STATE_OFF); */ - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): starting DHCP configuration\n")); - - if (dhcp_inc_pcb_refcount() != ERR_OK) { /* ensure DHCP PCB is allocated */ - return ERR_MEM; - } - dhcp->pcb_allocated = 1; - - if (!netif_is_link_up(netif)) { - /* set state INIT and wait for dhcp_network_changed() to call dhcp_discover() */ - dhcp_set_state(dhcp, DHCP_STATE_INIT); - return ERR_OK; - } - - /* (re)start the DHCP negotiation */ - result = dhcp_discover(netif); - if (result != ERR_OK) { - /* free resources allocated above */ - dhcp_release_and_stop(netif); - return ERR_MEM; - } - return result; -} - -/** - * @ingroup dhcp4 - * Inform a DHCP server of our manual configuration. - * - * This informs DHCP servers of our fixed IP address configuration - * by sending an INFORM message. It does not involve DHCP address - * configuration, it is just here to be nice to the network. - * - * @param netif The lwIP network interface - */ -void -dhcp_inform(struct netif *netif) -{ - struct dhcp dhcp; - struct pbuf *p_out; - u16_t options_out_len; - - LWIP_ASSERT_CORE_LOCKED(); - LWIP_ERROR("netif != NULL", (netif != NULL), return;); - - if (dhcp_inc_pcb_refcount() != ERR_OK) { /* ensure DHCP PCB is allocated */ - return; - } - - memset(&dhcp, 0, sizeof(struct dhcp)); - dhcp_set_state(&dhcp, DHCP_STATE_INFORMING); - - /* create and initialize the DHCP message header */ - p_out = dhcp_create_msg(netif, &dhcp, DHCP_INFORM, &options_out_len); - if (p_out != NULL) { - struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload; - options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); - options_out_len = dhcp_option_short(options_out_len, msg_out->options, DHCP_MAX_MSG_LEN(netif)); - - LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, &dhcp, DHCP_STATE_INFORMING, msg_out, DHCP_INFORM, &options_out_len); - dhcp_option_trailer(options_out_len, msg_out->options, p_out); - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_inform: INFORMING\n")); - - udp_sendto_if(dhcp_pcb, p_out, IP_ADDR_BROADCAST, LWIP_IANA_PORT_DHCP_SERVER, netif); - - pbuf_free(p_out); - } else { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_inform: could not allocate DHCP request\n")); - } - - dhcp_dec_pcb_refcount(); /* delete DHCP PCB if not needed any more */ -} - -/** Handle a possible change in the network configuration. - * - * This enters the REBOOTING state to verify that the currently bound - * address is still valid. - */ -void -dhcp_network_changed(struct netif *netif) -{ - struct dhcp *dhcp = netif_dhcp_data(netif); - - if (!dhcp) { - return; - } - switch (dhcp->state) { - case DHCP_STATE_REBINDING: - case DHCP_STATE_RENEWING: - case DHCP_STATE_BOUND: - case DHCP_STATE_REBOOTING: - dhcp->tries = 0; - dhcp_reboot(netif); - break; - case DHCP_STATE_OFF: - /* stay off */ - break; - default: - LWIP_ASSERT("invalid dhcp->state", dhcp->state <= DHCP_STATE_BACKING_OFF); - /* INIT/REQUESTING/CHECKING/BACKING_OFF restart with new 'rid' because the - state changes, SELECTING: continue with current 'rid' as we stay in the - same state */ -#if LWIP_DHCP_AUTOIP_COOP - if (dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) { - autoip_stop(netif); - dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF; - } -#endif /* LWIP_DHCP_AUTOIP_COOP */ - /* ensure we start with short timeouts, even if already discovering */ - dhcp->tries = 0; - dhcp_discover(netif); - break; - } -} - -#if DHCP_DOES_ARP_CHECK -/** - * Match an ARP reply with the offered IP address: - * check whether the offered IP address is not in use using ARP - * - * @param netif the network interface on which the reply was received - * @param addr The IP address we received a reply from - */ -void -dhcp_arp_reply(struct netif *netif, const ip4_addr_t *addr) -{ - struct dhcp *dhcp; - - LWIP_ERROR("netif != NULL", (netif != NULL), return;); - dhcp = netif_dhcp_data(netif); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_arp_reply()\n")); - /* is a DHCP client doing an ARP check? */ - if ((dhcp != NULL) && (dhcp->state == DHCP_STATE_CHECKING)) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_arp_reply(): CHECKING, arp reply for 0x%08"X32_F"\n", - ip4_addr_get_u32(addr))); - /* did a host respond with the address we - were offered by the DHCP server? */ - if (ip4_addr_cmp(addr, &dhcp->offered_ip_addr)) { - /* we will not accept the offered address */ - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING, - ("dhcp_arp_reply(): arp reply matched with offered address, declining\n")); - dhcp_decline(netif); - } - } -} - -/** - * Decline an offered lease. - * - * Tell the DHCP server we do not accept the offered address. - * One reason to decline the lease is when we find out the address - * is already in use by another host (through ARP). - * - * @param netif the netif under DHCP control - */ -static err_t -dhcp_decline(struct netif *netif) -{ - struct dhcp *dhcp = netif_dhcp_data(netif); - err_t result; - u16_t msecs; - struct pbuf *p_out; - u16_t options_out_len; - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_decline()\n")); - dhcp_set_state(dhcp, DHCP_STATE_BACKING_OFF); - /* create and initialize the DHCP message header */ - p_out = dhcp_create_msg(netif, dhcp, DHCP_DECLINE, &options_out_len); - if (p_out != NULL) { - struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload; - options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_REQUESTED_IP, 4); - options_out_len = dhcp_option_long(options_out_len, msg_out->options, lwip_ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr))); - - LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, DHCP_STATE_BACKING_OFF, msg_out, DHCP_DECLINE, &options_out_len); - dhcp_option_trailer(options_out_len, msg_out->options, p_out); - - /* per section 4.4.4, broadcast DECLINE messages */ - result = udp_sendto_if_src(dhcp_pcb, p_out, IP_ADDR_BROADCAST, LWIP_IANA_PORT_DHCP_SERVER, netif, IP4_ADDR_ANY); - pbuf_free(p_out); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_decline: BACKING OFF\n")); - } else { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, - ("dhcp_decline: could not allocate DHCP request\n")); - result = ERR_MEM; - } - if (dhcp->tries < 255) { - dhcp->tries++; - } - msecs = 10 * 1000; - dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_decline(): set request timeout %"U16_F" msecs\n", msecs)); - return result; -} -#endif /* DHCP_DOES_ARP_CHECK */ - - -/** - * Start the DHCP process, discover a DHCP server. - * - * @param netif the netif under DHCP control - */ -static err_t -dhcp_discover(struct netif *netif) -{ - struct dhcp *dhcp = netif_dhcp_data(netif); - err_t result = ERR_OK; - u16_t msecs; - u8_t i; - struct pbuf *p_out; - u16_t options_out_len; - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover()\n")); - - ip4_addr_set_any(&dhcp->offered_ip_addr); - dhcp_set_state(dhcp, DHCP_STATE_SELECTING); - /* create and initialize the DHCP message header */ - p_out = dhcp_create_msg(netif, dhcp, DHCP_DISCOVER, &options_out_len); - if (p_out != NULL) { - struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: making request\n")); - - options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); - options_out_len = dhcp_option_short(options_out_len, msg_out->options, DHCP_MAX_MSG_LEN(netif)); - - options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_PARAMETER_REQUEST_LIST, LWIP_ARRAYSIZE(dhcp_discover_request_options)); - for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) { - options_out_len = dhcp_option_byte(options_out_len, msg_out->options, dhcp_discover_request_options[i]); - } - LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, DHCP_STATE_SELECTING, msg_out, DHCP_DISCOVER, &options_out_len); - dhcp_option_trailer(options_out_len, msg_out->options, p_out); - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: sendto(DISCOVER, IP_ADDR_BROADCAST, LWIP_IANA_PORT_DHCP_SERVER)\n")); - udp_sendto_if_src(dhcp_pcb, p_out, IP_ADDR_BROADCAST, LWIP_IANA_PORT_DHCP_SERVER, netif, IP4_ADDR_ANY); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: deleting()ing\n")); - pbuf_free(p_out); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover: SELECTING\n")); - } else { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_discover: could not allocate DHCP request\n")); - } - if (dhcp->tries < 255) { - dhcp->tries++; - } -#if LWIP_DHCP_AUTOIP_COOP - if (dhcp->tries >= LWIP_DHCP_AUTOIP_COOP_TRIES && dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_OFF) { - dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_ON; - autoip_start(netif); - } -#endif /* LWIP_DHCP_AUTOIP_COOP */ - msecs = (u16_t)((dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000); - dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover(): set request timeout %"U16_F" msecs\n", msecs)); - return result; -} - - -/** - * Bind the interface to the offered IP address. - * - * @param netif network interface to bind to the offered address - */ -static void -dhcp_bind(struct netif *netif) -{ - u32_t timeout; - struct dhcp *dhcp; - ip4_addr_t sn_mask, gw_addr; - LWIP_ERROR("dhcp_bind: netif != NULL", (netif != NULL), return;); - dhcp = netif_dhcp_data(netif); - LWIP_ERROR("dhcp_bind: dhcp != NULL", (dhcp != NULL), return;); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(netif=%p) %c%c%"U16_F"\n", (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); - - /* reset time used of lease */ - dhcp->lease_used = 0; - - if (dhcp->offered_t0_lease != 0xffffffffUL) { - /* set renewal period timer */ - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t0 renewal timer %"U32_F" secs\n", dhcp->offered_t0_lease)); - timeout = (dhcp->offered_t0_lease + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS; - if (timeout > 0xffff) { - timeout = 0xffff; - } - dhcp->t0_timeout = (u16_t)timeout; - if (dhcp->t0_timeout == 0) { - dhcp->t0_timeout = 1; - } - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t0_lease * 1000)); - } - - /* temporary DHCP lease? */ - if (dhcp->offered_t1_renew != 0xffffffffUL) { - /* set renewal period timer */ - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t1 renewal timer %"U32_F" secs\n", dhcp->offered_t1_renew)); - timeout = (dhcp->offered_t1_renew + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS; - if (timeout > 0xffff) { - timeout = 0xffff; - } - dhcp->t1_timeout = (u16_t)timeout; - if (dhcp->t1_timeout == 0) { - dhcp->t1_timeout = 1; - } - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t1_renew * 1000)); - dhcp->t1_renew_time = dhcp->t1_timeout; - } - /* set renewal period timer */ - if (dhcp->offered_t2_rebind != 0xffffffffUL) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t2 rebind timer %"U32_F" secs\n", dhcp->offered_t2_rebind)); - timeout = (dhcp->offered_t2_rebind + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS; - if (timeout > 0xffff) { - timeout = 0xffff; - } - dhcp->t2_timeout = (u16_t)timeout; - if (dhcp->t2_timeout == 0) { - dhcp->t2_timeout = 1; - } - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t2_rebind * 1000)); - dhcp->t2_rebind_time = dhcp->t2_timeout; - } - - /* If we have sub 1 minute lease, t2 and t1 will kick in at the same time. */ - if ((dhcp->t1_timeout >= dhcp->t2_timeout) && (dhcp->t2_timeout > 0)) { - dhcp->t1_timeout = 0; - } - - if (dhcp->subnet_mask_given) { - /* copy offered network mask */ - ip4_addr_copy(sn_mask, dhcp->offered_sn_mask); - } else { - /* subnet mask not given, choose a safe subnet mask given the network class */ - u8_t first_octet = ip4_addr1(&dhcp->offered_ip_addr); - if (first_octet <= 127) { - ip4_addr_set_u32(&sn_mask, PP_HTONL(0xff000000UL)); - } else if (first_octet >= 192) { - ip4_addr_set_u32(&sn_mask, PP_HTONL(0xffffff00UL)); - } else { - ip4_addr_set_u32(&sn_mask, PP_HTONL(0xffff0000UL)); - } - } - - ip4_addr_copy(gw_addr, dhcp->offered_gw_addr); - /* gateway address not given? */ - if (ip4_addr_isany_val(gw_addr)) { - /* copy network address */ - ip4_addr_get_network(&gw_addr, &dhcp->offered_ip_addr, &sn_mask); - /* use first host address on network as gateway */ - ip4_addr_set_u32(&gw_addr, ip4_addr_get_u32(&gw_addr) | PP_HTONL(0x00000001UL)); - } - -#if LWIP_DHCP_AUTOIP_COOP - if (dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) { - autoip_stop(netif); - dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF; - } -#endif /* LWIP_DHCP_AUTOIP_COOP */ - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_bind(): IP: 0x%08"X32_F" SN: 0x%08"X32_F" GW: 0x%08"X32_F"\n", - ip4_addr_get_u32(&dhcp->offered_ip_addr), ip4_addr_get_u32(&sn_mask), ip4_addr_get_u32(&gw_addr))); - /* netif is now bound to DHCP leased address - set this before assigning the address - to ensure the callback can use dhcp_supplied_address() */ - dhcp_set_state(dhcp, DHCP_STATE_BOUND); - - netif_set_addr(netif, &dhcp->offered_ip_addr, &sn_mask, &gw_addr); - /* interface is used by routing now that an address is set */ -} - -/** - * @ingroup dhcp4 - * Renew an existing DHCP lease at the involved DHCP server. - * - * @param netif network interface which must renew its lease - */ -err_t -dhcp_renew(struct netif *netif) -{ - struct dhcp *dhcp = netif_dhcp_data(netif); - err_t result; - u16_t msecs; - u8_t i; - struct pbuf *p_out; - u16_t options_out_len; - - LWIP_ASSERT_CORE_LOCKED(); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_renew()\n")); - dhcp_set_state(dhcp, DHCP_STATE_RENEWING); - - /* create and initialize the DHCP message header */ - p_out = dhcp_create_msg(netif, dhcp, DHCP_REQUEST, &options_out_len); - if (p_out != NULL) { - struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload; - options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); - options_out_len = dhcp_option_short(options_out_len, msg_out->options, DHCP_MAX_MSG_LEN(netif)); - - options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_PARAMETER_REQUEST_LIST, LWIP_ARRAYSIZE(dhcp_discover_request_options)); - for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) { - options_out_len = dhcp_option_byte(options_out_len, msg_out->options, dhcp_discover_request_options[i]); - } - -#if LWIP_NETIF_HOSTNAME - options_out_len = dhcp_option_hostname(options_out_len, msg_out->options, netif); -#endif /* LWIP_NETIF_HOSTNAME */ - - LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, DHCP_STATE_RENEWING, msg_out, DHCP_REQUEST, &options_out_len); - dhcp_option_trailer(options_out_len, msg_out->options, p_out); - - result = udp_sendto_if(dhcp_pcb, p_out, &dhcp->server_ip_addr, LWIP_IANA_PORT_DHCP_SERVER, netif); - pbuf_free(p_out); - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_renew: RENEWING\n")); - } else { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_renew: could not allocate DHCP request\n")); - result = ERR_MEM; - } - if (dhcp->tries < 255) { - dhcp->tries++; - } - /* back-off on retries, but to a maximum of 20 seconds */ - msecs = (u16_t)(dhcp->tries < 10 ? dhcp->tries * 2000 : 20 * 1000); - dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_renew(): set request timeout %"U16_F" msecs\n", msecs)); - return result; -} - -/** - * Rebind with a DHCP server for an existing DHCP lease. - * - * @param netif network interface which must rebind with a DHCP server - */ -static err_t -dhcp_rebind(struct netif *netif) -{ - struct dhcp *dhcp = netif_dhcp_data(netif); - err_t result; - u16_t msecs; - u8_t i; - struct pbuf *p_out; - u16_t options_out_len; - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind()\n")); - dhcp_set_state(dhcp, DHCP_STATE_REBINDING); - - /* create and initialize the DHCP message header */ - p_out = dhcp_create_msg(netif, dhcp, DHCP_REQUEST, &options_out_len); - if (p_out != NULL) { - struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload; - options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); - options_out_len = dhcp_option_short(options_out_len, msg_out->options, DHCP_MAX_MSG_LEN(netif)); - - options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_PARAMETER_REQUEST_LIST, LWIP_ARRAYSIZE(dhcp_discover_request_options)); - for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) { - options_out_len = dhcp_option_byte(options_out_len, msg_out->options, dhcp_discover_request_options[i]); - } - -#if LWIP_NETIF_HOSTNAME - options_out_len = dhcp_option_hostname(options_out_len, msg_out->options, netif); -#endif /* LWIP_NETIF_HOSTNAME */ - - LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, DHCP_STATE_REBINDING, msg_out, DHCP_DISCOVER, &options_out_len); - dhcp_option_trailer(options_out_len, msg_out->options, p_out); - - /* broadcast to server */ - result = udp_sendto_if(dhcp_pcb, p_out, IP_ADDR_BROADCAST, LWIP_IANA_PORT_DHCP_SERVER, netif); - pbuf_free(p_out); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind: REBINDING\n")); - } else { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_rebind: could not allocate DHCP request\n")); - result = ERR_MEM; - } - if (dhcp->tries < 255) { - dhcp->tries++; - } - msecs = (u16_t)(dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000); - dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind(): set request timeout %"U16_F" msecs\n", msecs)); - return result; -} - -/** - * Enter REBOOTING state to verify an existing lease - * - * @param netif network interface which must reboot - */ -static err_t -dhcp_reboot(struct netif *netif) -{ - struct dhcp *dhcp = netif_dhcp_data(netif); - err_t result; - u16_t msecs; - u8_t i; - struct pbuf *p_out; - u16_t options_out_len; - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot()\n")); - dhcp_set_state(dhcp, DHCP_STATE_REBOOTING); - - /* create and initialize the DHCP message header */ - p_out = dhcp_create_msg(netif, dhcp, DHCP_REQUEST, &options_out_len); - if (p_out != NULL) { - struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload; - options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); - options_out_len = dhcp_option_short(options_out_len, msg_out->options, DHCP_MAX_MSG_LEN_MIN_REQUIRED); - - options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_REQUESTED_IP, 4); - options_out_len = dhcp_option_long(options_out_len, msg_out->options, lwip_ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr))); - - options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_PARAMETER_REQUEST_LIST, LWIP_ARRAYSIZE(dhcp_discover_request_options)); - for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) { - options_out_len = dhcp_option_byte(options_out_len, msg_out->options, dhcp_discover_request_options[i]); - } - -#if LWIP_NETIF_HOSTNAME - options_out_len = dhcp_option_hostname(options_out_len, msg_out->options, netif); -#endif /* LWIP_NETIF_HOSTNAME */ - - LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, DHCP_STATE_REBOOTING, msg_out, DHCP_REQUEST, &options_out_len); - dhcp_option_trailer(options_out_len, msg_out->options, p_out); - - /* broadcast to server */ - result = udp_sendto_if(dhcp_pcb, p_out, IP_ADDR_BROADCAST, LWIP_IANA_PORT_DHCP_SERVER, netif); - pbuf_free(p_out); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot: REBOOTING\n")); - } else { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_reboot: could not allocate DHCP request\n")); - result = ERR_MEM; - } - if (dhcp->tries < 255) { - dhcp->tries++; - } - msecs = (u16_t)(dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000); - dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot(): set request timeout %"U16_F" msecs\n", msecs)); - return result; -} - -/** - * @ingroup dhcp4 - * Release a DHCP lease and stop DHCP statemachine (and AUTOIP if LWIP_DHCP_AUTOIP_COOP). - * - * @param netif network interface - */ -void -dhcp_release_and_stop(struct netif *netif) -{ - struct dhcp *dhcp = netif_dhcp_data(netif); - ip_addr_t server_ip_addr; - - LWIP_ASSERT_CORE_LOCKED(); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_release_and_stop()\n")); - if (dhcp == NULL) { - return; - } - - /* already off? -> nothing to do */ - if (dhcp->state == DHCP_STATE_OFF) { - return; - } - - ip_addr_copy(server_ip_addr, dhcp->server_ip_addr); - - /* clean old DHCP offer */ - ip_addr_set_zero_ip4(&dhcp->server_ip_addr); - ip4_addr_set_zero(&dhcp->offered_ip_addr); - ip4_addr_set_zero(&dhcp->offered_sn_mask); - ip4_addr_set_zero(&dhcp->offered_gw_addr); -#if LWIP_DHCP_BOOTP_FILE - ip4_addr_set_zero(&dhcp->offered_si_addr); -#endif /* LWIP_DHCP_BOOTP_FILE */ - dhcp->offered_t0_lease = dhcp->offered_t1_renew = dhcp->offered_t2_rebind = 0; - dhcp->t1_renew_time = dhcp->t2_rebind_time = dhcp->lease_used = dhcp->t0_timeout = 0; - - /* send release message when current IP was assigned via DHCP */ - if (dhcp_supplied_address(netif)) { - /* create and initialize the DHCP message header */ - struct pbuf *p_out; - u16_t options_out_len; - p_out = dhcp_create_msg(netif, dhcp, DHCP_RELEASE, &options_out_len); - if (p_out != NULL) { - struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload; - options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_SERVER_ID, 4); - options_out_len = dhcp_option_long(options_out_len, msg_out->options, lwip_ntohl(ip4_addr_get_u32(ip_2_ip4(&server_ip_addr)))); - - LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, dhcp->state, msg_out, DHCP_RELEASE, &options_out_len); - dhcp_option_trailer(options_out_len, msg_out->options, p_out); - - udp_sendto_if(dhcp_pcb, p_out, &server_ip_addr, LWIP_IANA_PORT_DHCP_SERVER, netif); - pbuf_free(p_out); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_release: RELEASED, DHCP_STATE_OFF\n")); - } else { - /* sending release failed, but that's not a problem since the correct behaviour of dhcp does not rely on release */ - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_release: could not allocate DHCP request\n")); - } - } - - /* remove IP address from interface (prevents routing from selecting this interface) */ - netif_set_addr(netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4); - -#if LWIP_DHCP_AUTOIP_COOP - if (dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) { - autoip_stop(netif); - dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF; - } -#endif /* LWIP_DHCP_AUTOIP_COOP */ - - dhcp_set_state(dhcp, DHCP_STATE_OFF); - - if (dhcp->pcb_allocated != 0) { - dhcp_dec_pcb_refcount(); /* free DHCP PCB if not needed any more */ - dhcp->pcb_allocated = 0; - } -} - -/** - * @ingroup dhcp4 - * This function calls dhcp_release_and_stop() internally. - * @deprecated Use dhcp_release_and_stop() instead. - */ -err_t -dhcp_release(struct netif *netif) -{ - dhcp_release_and_stop(netif); - return ERR_OK; -} - -/** - * @ingroup dhcp4 - * This function calls dhcp_release_and_stop() internally. - * @deprecated Use dhcp_release_and_stop() instead. - */ -void -dhcp_stop(struct netif *netif) -{ - dhcp_release_and_stop(netif); -} - -/* - * Set the DHCP state of a DHCP client. - * - * If the state changed, reset the number of tries. - */ -static void -dhcp_set_state(struct dhcp *dhcp, u8_t new_state) -{ - if (new_state != dhcp->state) { - dhcp->state = new_state; - dhcp->tries = 0; - dhcp->request_timeout = 0; - } -} - -/* - * Concatenate an option type and length field to the outgoing - * DHCP message. - * - */ -static u16_t -dhcp_option(u16_t options_out_len, u8_t *options, u8_t option_type, u8_t option_len) -{ - LWIP_ASSERT("dhcp_option: options_out_len + 2 + option_len <= DHCP_OPTIONS_LEN", options_out_len + 2U + option_len <= DHCP_OPTIONS_LEN); - options[options_out_len++] = option_type; - options[options_out_len++] = option_len; - return options_out_len; -} -/* - * Concatenate a single byte to the outgoing DHCP message. - * - */ -static u16_t -dhcp_option_byte(u16_t options_out_len, u8_t *options, u8_t value) -{ - LWIP_ASSERT("dhcp_option_byte: options_out_len < DHCP_OPTIONS_LEN", options_out_len < DHCP_OPTIONS_LEN); - options[options_out_len++] = value; - return options_out_len; -} - -static u16_t -dhcp_option_short(u16_t options_out_len, u8_t *options, u16_t value) -{ - LWIP_ASSERT("dhcp_option_short: options_out_len + 2 <= DHCP_OPTIONS_LEN", options_out_len + 2U <= DHCP_OPTIONS_LEN); - options[options_out_len++] = (u8_t)((value & 0xff00U) >> 8); - options[options_out_len++] = (u8_t) (value & 0x00ffU); - return options_out_len; -} - -static u16_t -dhcp_option_long(u16_t options_out_len, u8_t *options, u32_t value) -{ - LWIP_ASSERT("dhcp_option_long: options_out_len + 4 <= DHCP_OPTIONS_LEN", options_out_len + 4U <= DHCP_OPTIONS_LEN); - options[options_out_len++] = (u8_t)((value & 0xff000000UL) >> 24); - options[options_out_len++] = (u8_t)((value & 0x00ff0000UL) >> 16); - options[options_out_len++] = (u8_t)((value & 0x0000ff00UL) >> 8); - options[options_out_len++] = (u8_t)((value & 0x000000ffUL)); - return options_out_len; -} - -#if LWIP_NETIF_HOSTNAME -static u16_t -dhcp_option_hostname(u16_t options_out_len, u8_t *options, struct netif *netif) -{ - if (netif->hostname != NULL) { - size_t namelen = strlen(netif->hostname); - if (namelen > 0) { - size_t len; - const char *p = netif->hostname; - /* Shrink len to available bytes (need 2 bytes for OPTION_HOSTNAME - and 1 byte for trailer) */ - size_t available = DHCP_OPTIONS_LEN - options_out_len - 3; - LWIP_ASSERT("DHCP: hostname is too long!", namelen <= available); - len = LWIP_MIN(namelen, available); - LWIP_ASSERT("DHCP: hostname is too long!", len <= 0xFF); - options_out_len = dhcp_option(options_out_len, options, DHCP_OPTION_HOSTNAME, (u8_t)len); - while (len--) { - options_out_len = dhcp_option_byte(options_out_len, options, *p++); - } - } - } - return options_out_len; -} -#endif /* LWIP_NETIF_HOSTNAME */ - -/** - * Extract the DHCP message and the DHCP options. - * - * Extract the DHCP message and the DHCP options, each into a contiguous - * piece of memory. As a DHCP message is variable sized by its options, - * and also allows overriding some fields for options, the easy approach - * is to first unfold the options into a contiguous piece of memory, and - * use that further on. - * - */ -static err_t -dhcp_parse_reply(struct pbuf *p, struct dhcp *dhcp) -{ - u8_t *options; - u16_t offset; - u16_t offset_max; - u16_t options_idx; - u16_t options_idx_max; - struct pbuf *q; - int parse_file_as_options = 0; - int parse_sname_as_options = 0; - struct dhcp_msg *msg_in; -#if LWIP_DHCP_BOOTP_FILE - int file_overloaded = 0; -#endif - - LWIP_UNUSED_ARG(dhcp); - - /* clear received options */ - dhcp_clear_all_options(dhcp); - /* check that beginning of dhcp_msg (up to and including chaddr) is in first pbuf */ - if (p->len < DHCP_SNAME_OFS) { - return ERR_BUF; - } - msg_in = (struct dhcp_msg *)p->payload; -#if LWIP_DHCP_BOOTP_FILE - /* clear boot file name */ - dhcp->boot_file_name[0] = 0; -#endif /* LWIP_DHCP_BOOTP_FILE */ - - /* parse options */ - - /* start with options field */ - options_idx = DHCP_OPTIONS_OFS; - /* parse options to the end of the received packet */ - options_idx_max = p->tot_len; -again: - q = p; - while ((q != NULL) && (options_idx >= q->len)) { - options_idx = (u16_t)(options_idx - q->len); - options_idx_max = (u16_t)(options_idx_max - q->len); - q = q->next; - } - if (q == NULL) { - return ERR_BUF; - } - offset = options_idx; - offset_max = options_idx_max; - options = (u8_t *)q->payload; - /* at least 1 byte to read and no end marker, then at least 3 bytes to read? */ - while ((q != NULL) && (offset < offset_max) && (options[offset] != DHCP_OPTION_END)) { - u8_t op = options[offset]; - u8_t len; - u8_t decode_len = 0; - int decode_idx = -1; - u16_t val_offset = (u16_t)(offset + 2); - if (val_offset < offset) { - /* overflow */ - return ERR_BUF; - } - /* len byte might be in the next pbuf */ - if ((offset + 1) < q->len) { - len = options[offset + 1]; - } else { - len = (q->next != NULL ? ((u8_t *)q->next->payload)[0] : 0); - } - /* LWIP_DEBUGF(DHCP_DEBUG, ("msg_offset=%"U16_F", q->len=%"U16_F, msg_offset, q->len)); */ - decode_len = len; - switch (op) { - /* case(DHCP_OPTION_END): handled above */ - case (DHCP_OPTION_PAD): - /* special option: no len encoded */ - decode_len = len = 0; - /* will be increased below */ - break; - case (DHCP_OPTION_SUBNET_MASK): - LWIP_ERROR("len == 4", len == 4, return ERR_VAL;); - decode_idx = DHCP_OPTION_IDX_SUBNET_MASK; - break; - case (DHCP_OPTION_ROUTER): - decode_len = 4; /* only copy the first given router */ - LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;); - decode_idx = DHCP_OPTION_IDX_ROUTER; - break; -#if LWIP_DHCP_PROVIDE_DNS_SERVERS - case (DHCP_OPTION_DNS_SERVER): - /* special case: there might be more than one server */ - LWIP_ERROR("len %% 4 == 0", len % 4 == 0, return ERR_VAL;); - /* limit number of DNS servers */ - decode_len = LWIP_MIN(len, 4 * DNS_MAX_SERVERS); - LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;); - decode_idx = DHCP_OPTION_IDX_DNS_SERVER; - break; -#endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS */ - case (DHCP_OPTION_LEASE_TIME): - LWIP_ERROR("len == 4", len == 4, return ERR_VAL;); - decode_idx = DHCP_OPTION_IDX_LEASE_TIME; - break; -#if LWIP_DHCP_GET_NTP_SRV - case (DHCP_OPTION_NTP): - /* special case: there might be more than one server */ - LWIP_ERROR("len %% 4 == 0", len % 4 == 0, return ERR_VAL;); - /* limit number of NTP servers */ - decode_len = LWIP_MIN(len, 4 * LWIP_DHCP_MAX_NTP_SERVERS); - LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;); - decode_idx = DHCP_OPTION_IDX_NTP_SERVER; - break; -#endif /* LWIP_DHCP_GET_NTP_SRV*/ - case (DHCP_OPTION_OVERLOAD): - LWIP_ERROR("len == 1", len == 1, return ERR_VAL;); - /* decode overload only in options, not in file/sname: invalid packet */ - LWIP_ERROR("overload in file/sname", options_idx == DHCP_OPTIONS_OFS, return ERR_VAL;); - decode_idx = DHCP_OPTION_IDX_OVERLOAD; - break; - case (DHCP_OPTION_MESSAGE_TYPE): - LWIP_ERROR("len == 1", len == 1, return ERR_VAL;); - decode_idx = DHCP_OPTION_IDX_MSG_TYPE; - break; - case (DHCP_OPTION_SERVER_ID): - LWIP_ERROR("len == 4", len == 4, return ERR_VAL;); - decode_idx = DHCP_OPTION_IDX_SERVER_ID; - break; - case (DHCP_OPTION_T1): - LWIP_ERROR("len == 4", len == 4, return ERR_VAL;); - decode_idx = DHCP_OPTION_IDX_T1; - break; - case (DHCP_OPTION_T2): - LWIP_ERROR("len == 4", len == 4, return ERR_VAL;); - decode_idx = DHCP_OPTION_IDX_T2; - break; - default: - decode_len = 0; - LWIP_DEBUGF(DHCP_DEBUG, ("skipping option %"U16_F" in options\n", (u16_t)op)); - LWIP_HOOK_DHCP_PARSE_OPTION(ip_current_netif(), dhcp, dhcp->state, msg_in, - dhcp_option_given(dhcp, DHCP_OPTION_IDX_MSG_TYPE) ? (u8_t)dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE) : 0, - op, len, q, val_offset); - break; - } - if (op == DHCP_OPTION_PAD) { - offset++; - } else { - if (offset + len + 2 > 0xFFFF) { - /* overflow */ - return ERR_BUF; - } - offset = (u16_t)(offset + len + 2); - if (decode_len > 0) { - u32_t value = 0; - u16_t copy_len; -decode_next: - LWIP_ASSERT("check decode_idx", decode_idx >= 0 && decode_idx < DHCP_OPTION_IDX_MAX); - if (!dhcp_option_given(dhcp, decode_idx)) { - copy_len = LWIP_MIN(decode_len, 4); - if (pbuf_copy_partial(q, &value, copy_len, val_offset) != copy_len) { - return ERR_BUF; - } - if (decode_len > 4) { - /* decode more than one u32_t */ - u16_t next_val_offset; - LWIP_ERROR("decode_len %% 4 == 0", decode_len % 4 == 0, return ERR_VAL;); - dhcp_got_option(dhcp, decode_idx); - dhcp_set_option_value(dhcp, decode_idx, lwip_htonl(value)); - decode_len = (u8_t)(decode_len - 4); - next_val_offset = (u16_t)(val_offset + 4); - if (next_val_offset < val_offset) { - /* overflow */ - return ERR_BUF; - } - val_offset = next_val_offset; - decode_idx++; - goto decode_next; - } else if (decode_len == 4) { - value = lwip_ntohl(value); - } else { - LWIP_ERROR("invalid decode_len", decode_len == 1, return ERR_VAL;); - value = ((u8_t *)&value)[0]; - } - dhcp_got_option(dhcp, decode_idx); - dhcp_set_option_value(dhcp, decode_idx, value); - } - } - } - if (offset >= q->len) { - offset = (u16_t)(offset - q->len); - offset_max = (u16_t)(offset_max - q->len); - if (offset < offset_max) { - q = q->next; - LWIP_ERROR("next pbuf was null", q != NULL, return ERR_VAL;); - options = (u8_t *)q->payload; - } else { - /* We've run out of bytes, probably no end marker. Don't proceed. */ - return ERR_BUF; - } - } - } - /* is this an overloaded message? */ - if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_OVERLOAD)) { - u32_t overload = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_OVERLOAD); - dhcp_clear_option(dhcp, DHCP_OPTION_IDX_OVERLOAD); - if (overload == DHCP_OVERLOAD_FILE) { - parse_file_as_options = 1; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded file field\n")); - } else if (overload == DHCP_OVERLOAD_SNAME) { - parse_sname_as_options = 1; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded sname field\n")); - } else if (overload == DHCP_OVERLOAD_SNAME_FILE) { - parse_sname_as_options = 1; - parse_file_as_options = 1; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded sname and file field\n")); - } else { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("invalid overload option: %d\n", (int)overload)); - } - } - if (parse_file_as_options) { - /* if both are overloaded, parse file first and then sname (RFC 2131 ch. 4.1) */ - parse_file_as_options = 0; - options_idx = DHCP_FILE_OFS; - options_idx_max = DHCP_FILE_OFS + DHCP_FILE_LEN; -#if LWIP_DHCP_BOOTP_FILE - file_overloaded = 1; -#endif - goto again; - } else if (parse_sname_as_options) { - parse_sname_as_options = 0; - options_idx = DHCP_SNAME_OFS; - options_idx_max = DHCP_SNAME_OFS + DHCP_SNAME_LEN; - goto again; - } -#if LWIP_DHCP_BOOTP_FILE - if (!file_overloaded) { - /* only do this for ACK messages */ - if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_MSG_TYPE) && - (dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE) == DHCP_ACK)) - /* copy bootp file name, don't care for sname (server hostname) */ - if (pbuf_copy_partial(p, dhcp->boot_file_name, DHCP_FILE_LEN-1, DHCP_FILE_OFS) != (DHCP_FILE_LEN-1)) { - return ERR_BUF; - } - /* make sure the string is really NULL-terminated */ - dhcp->boot_file_name[DHCP_FILE_LEN-1] = 0; - } -#endif /* LWIP_DHCP_BOOTP_FILE */ - return ERR_OK; -} - -/** - * If an incoming DHCP message is in response to us, then trigger the state machine - */ -static void -dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) -{ - struct netif *netif = ip_current_input_netif(); - struct dhcp *dhcp = netif_dhcp_data(netif); - struct dhcp_msg *reply_msg = (struct dhcp_msg *)p->payload; - u8_t msg_type; - u8_t i; - struct dhcp_msg *msg_in; - - LWIP_UNUSED_ARG(arg); - - /* Caught DHCP message from netif that does not have DHCP enabled? -> not interested */ - if ((dhcp == NULL) || (dhcp->pcb_allocated == 0)) { - goto free_pbuf_and_return; - } - - LWIP_ASSERT("invalid server address type", IP_IS_V4(addr)); - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_recv(pbuf = %p) from DHCP server %"U16_F".%"U16_F".%"U16_F".%"U16_F" port %"U16_F"\n", (void *)p, - ip4_addr1_16(ip_2_ip4(addr)), ip4_addr2_16(ip_2_ip4(addr)), ip4_addr3_16(ip_2_ip4(addr)), ip4_addr4_16(ip_2_ip4(addr)), port)); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("pbuf->len = %"U16_F"\n", p->len)); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("pbuf->tot_len = %"U16_F"\n", p->tot_len)); - /* prevent warnings about unused arguments */ - LWIP_UNUSED_ARG(pcb); - LWIP_UNUSED_ARG(addr); - LWIP_UNUSED_ARG(port); - - if (p->len < DHCP_MIN_REPLY_LEN) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("DHCP reply message or pbuf too short\n")); - goto free_pbuf_and_return; - } - - if (reply_msg->op != DHCP_BOOTREPLY) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("not a DHCP reply message, but type %"U16_F"\n", (u16_t)reply_msg->op)); - goto free_pbuf_and_return; - } - /* iterate through hardware address and match against DHCP message */ - for (i = 0; i < netif->hwaddr_len && i < LWIP_MIN(DHCP_CHADDR_LEN, NETIF_MAX_HWADDR_LEN); i++) { - if (netif->hwaddr[i] != reply_msg->chaddr[i]) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, - ("netif->hwaddr[%"U16_F"]==%02"X16_F" != reply_msg->chaddr[%"U16_F"]==%02"X16_F"\n", - (u16_t)i, (u16_t)netif->hwaddr[i], (u16_t)i, (u16_t)reply_msg->chaddr[i])); - goto free_pbuf_and_return; - } - } - /* match transaction ID against what we expected */ - if (lwip_ntohl(reply_msg->xid) != dhcp->xid) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, - ("transaction id mismatch reply_msg->xid(%"X32_F")!=dhcp->xid(%"X32_F")\n", lwip_ntohl(reply_msg->xid), dhcp->xid)); - goto free_pbuf_and_return; - } - /* option fields could be unfold? */ - if (dhcp_parse_reply(p, dhcp) != ERR_OK) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, - ("problem unfolding DHCP message - too short on memory?\n")); - goto free_pbuf_and_return; - } - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("searching DHCP_OPTION_MESSAGE_TYPE\n")); - /* obtain pointer to DHCP message type */ - if (!dhcp_option_given(dhcp, DHCP_OPTION_IDX_MSG_TYPE)) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("DHCP_OPTION_MESSAGE_TYPE option not found\n")); - goto free_pbuf_and_return; - } - - msg_in = (struct dhcp_msg *)p->payload; - /* read DHCP message type */ - msg_type = (u8_t)dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE); - /* message type is DHCP ACK? */ - if (msg_type == DHCP_ACK) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_ACK received\n")); - /* in requesting state? */ - if (dhcp->state == DHCP_STATE_REQUESTING) { - dhcp_handle_ack(netif, msg_in); -#if DHCP_DOES_ARP_CHECK - if ((netif->flags & NETIF_FLAG_ETHARP) != 0) { - /* check if the acknowledged lease address is already in use */ - dhcp_check(netif); - } else { - /* bind interface to the acknowledged lease address */ - dhcp_bind(netif); - } -#else - /* bind interface to the acknowledged lease address */ - dhcp_bind(netif); -#endif - } - /* already bound to the given lease address? */ - else if ((dhcp->state == DHCP_STATE_REBOOTING) || (dhcp->state == DHCP_STATE_REBINDING) || - (dhcp->state == DHCP_STATE_RENEWING)) { - dhcp_handle_ack(netif, msg_in); - dhcp_bind(netif); - } - } - /* received a DHCP_NAK in appropriate state? */ - else if ((msg_type == DHCP_NAK) && - ((dhcp->state == DHCP_STATE_REBOOTING) || (dhcp->state == DHCP_STATE_REQUESTING) || - (dhcp->state == DHCP_STATE_REBINDING) || (dhcp->state == DHCP_STATE_RENEWING ))) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_NAK received\n")); - dhcp_handle_nak(netif); - } - /* received a DHCP_OFFER in DHCP_STATE_SELECTING state? */ - else if ((msg_type == DHCP_OFFER) && (dhcp->state == DHCP_STATE_SELECTING)) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_OFFER received in DHCP_STATE_SELECTING state\n")); - /* remember offered lease */ - dhcp_handle_offer(netif, msg_in); - } - -free_pbuf_and_return: - pbuf_free(p); -} - -/** - * Create a DHCP request, fill in common headers - * - * @param netif the netif under DHCP control - * @param dhcp dhcp control struct - * @param message_type message type of the request - */ -static struct pbuf * -dhcp_create_msg(struct netif *netif, struct dhcp *dhcp, u8_t message_type, u16_t *options_out_len) -{ - u16_t i; - struct pbuf *p_out; - struct dhcp_msg *msg_out; - u16_t options_out_len_loc; - -#ifndef DHCP_GLOBAL_XID - /** default global transaction identifier starting value (easy to match - * with a packet analyser). We simply increment for each new request. - * Predefine DHCP_GLOBAL_XID to a better value or a function call to generate one - * at runtime, any supporting function prototypes can be defined in DHCP_GLOBAL_XID_HEADER */ -#if DHCP_CREATE_RAND_XID && defined(LWIP_RAND) - static u32_t xid; -#else /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */ - static u32_t xid = 0xABCD0000; -#endif /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */ -#else - if (!xid_initialised) { - xid = DHCP_GLOBAL_XID; - xid_initialised = !xid_initialised; - } -#endif - LWIP_ERROR("dhcp_create_msg: netif != NULL", (netif != NULL), return NULL;); - LWIP_ERROR("dhcp_create_msg: dhcp != NULL", (dhcp != NULL), return NULL;); - p_out = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcp_msg), PBUF_RAM); - if (p_out == NULL) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, - ("dhcp_create_msg(): could not allocate pbuf\n")); - return NULL; - } - LWIP_ASSERT("dhcp_create_msg: check that first pbuf can hold struct dhcp_msg", - (p_out->len >= sizeof(struct dhcp_msg))); - - /* DHCP_REQUEST should reuse 'xid' from DHCPOFFER */ - if ((message_type != DHCP_REQUEST) || (dhcp->state == DHCP_STATE_REBOOTING)) { - /* reuse transaction identifier in retransmissions */ - if (dhcp->tries == 0) { -#if DHCP_CREATE_RAND_XID && defined(LWIP_RAND) - xid = LWIP_RAND(); -#else /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */ - xid++; -#endif /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */ - } - dhcp->xid = xid; - } - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, - ("transaction id xid(%"X32_F")\n", xid)); - - msg_out = (struct dhcp_msg *)p_out->payload; - memset(msg_out, 0, sizeof(struct dhcp_msg)); - - msg_out->op = DHCP_BOOTREQUEST; - /* @todo: make link layer independent */ - msg_out->htype = LWIP_IANA_HWTYPE_ETHERNET; - msg_out->hlen = netif->hwaddr_len; - msg_out->xid = lwip_htonl(dhcp->xid); - /* we don't need the broadcast flag since we can receive unicast traffic - before being fully configured! */ - /* set ciaddr to netif->ip_addr based on message_type and state */ - if ((message_type == DHCP_INFORM) || (message_type == DHCP_DECLINE) || (message_type == DHCP_RELEASE) || - ((message_type == DHCP_REQUEST) && /* DHCP_STATE_BOUND not used for sending! */ - ((dhcp->state == DHCP_STATE_RENEWING) || dhcp->state == DHCP_STATE_REBINDING))) { - ip4_addr_copy(msg_out->ciaddr, *netif_ip4_addr(netif)); - } - for (i = 0; i < LWIP_MIN(DHCP_CHADDR_LEN, NETIF_MAX_HWADDR_LEN); i++) { - /* copy netif hardware address (padded with zeroes through memset already) */ - msg_out->chaddr[i] = netif->hwaddr[i]; - } - msg_out->cookie = PP_HTONL(DHCP_MAGIC_COOKIE); - /* Add option MESSAGE_TYPE */ - options_out_len_loc = dhcp_option(0, msg_out->options, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN); - options_out_len_loc = dhcp_option_byte(options_out_len_loc, msg_out->options, message_type); - if (options_out_len) { - *options_out_len = options_out_len_loc; - } - return p_out; -} - -/** - * Add a DHCP message trailer - * - * Adds the END option to the DHCP message, and if - * necessary, up to three padding bytes. - */ -static void -dhcp_option_trailer(u16_t options_out_len, u8_t *options, struct pbuf *p_out) -{ - options[options_out_len++] = DHCP_OPTION_END; - /* packet is too small, or not 4 byte aligned? */ - while (((options_out_len < DHCP_MIN_OPTIONS_LEN) || (options_out_len & 3)) && - (options_out_len < DHCP_OPTIONS_LEN)) { - /* add a fill/padding byte */ - options[options_out_len++] = 0; - } - /* shrink the pbuf to the actual content length */ - pbuf_realloc(p_out, (u16_t)(sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + options_out_len)); -} - -/** check if DHCP supplied netif->ip_addr - * - * @param netif the netif to check - * @return 1 if DHCP supplied netif->ip_addr (states BOUND or RENEWING), - * 0 otherwise - */ -u8_t -dhcp_supplied_address(const struct netif *netif) -{ - if ((netif != NULL) && (netif_dhcp_data(netif) != NULL)) { - struct dhcp *dhcp = netif_dhcp_data(netif); - return (dhcp->state == DHCP_STATE_BOUND) || (dhcp->state == DHCP_STATE_RENEWING) || - (dhcp->state == DHCP_STATE_REBINDING); - } - return 0; -} - -#endif /* LWIP_IPV4 && LWIP_DHCP */ diff --git a/third-party/lwip-2.1.2/core/ipv4/etharp.c b/third-party/lwip-2.1.2/core/ipv4/etharp.c deleted file mode 100644 index 442aac08..00000000 --- a/third-party/lwip-2.1.2/core/ipv4/etharp.c +++ /dev/null @@ -1,1204 +0,0 @@ -/** - * @file - * Address Resolution Protocol module for IP over Ethernet - * - * Functionally, ARP is divided into two parts. The first maps an IP address - * to a physical address when sending a packet, and the second part answers - * requests from other machines for our physical address. - * - * This implementation complies with RFC 826 (Ethernet ARP). It supports - * Gratuitious ARP from RFC3220 (IP Mobility Support for IPv4) section 4.6 - * if an interface calls etharp_gratuitous(our_netif) upon address change. - */ - -/* - * Copyright (c) 2001-2003 Swedish Institute of Computer Science. - * Copyright (c) 2003-2004 Leon Woestenberg - * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#include "lwip/opt.h" - -#if LWIP_IPV4 && LWIP_ARP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/etharp.h" -#include "lwip/stats.h" -#include "lwip/snmp.h" -#include "lwip/dhcp.h" -#include "lwip/autoip.h" -#include "lwip/prot/iana.h" -#include "netif/ethernet.h" - -#include - -#ifdef LWIP_HOOK_FILENAME -#include LWIP_HOOK_FILENAME -#endif - -/** Re-request a used ARP entry 1 minute before it would expire to prevent - * breaking a steadily used connection because the ARP entry timed out. */ -#define ARP_AGE_REREQUEST_USED_UNICAST (ARP_MAXAGE - 30) -#define ARP_AGE_REREQUEST_USED_BROADCAST (ARP_MAXAGE - 15) - -/** the time an ARP entry stays pending after first request, - * for ARP_TMR_INTERVAL = 1000, this is - * 10 seconds. - * - * @internal Keep this number at least 2, otherwise it might - * run out instantly if the timeout occurs directly after a request. - */ -#define ARP_MAXPENDING 5 - -/** ARP states */ -enum etharp_state { - ETHARP_STATE_EMPTY = 0, - ETHARP_STATE_PENDING, - ETHARP_STATE_STABLE, - ETHARP_STATE_STABLE_REREQUESTING_1, - ETHARP_STATE_STABLE_REREQUESTING_2 -#if ETHARP_SUPPORT_STATIC_ENTRIES - , ETHARP_STATE_STATIC -#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ -}; - -struct etharp_entry { -#if ARP_QUEUEING - /** Pointer to queue of pending outgoing packets on this ARP entry. */ - struct etharp_q_entry *q; -#else /* ARP_QUEUEING */ - /** Pointer to a single pending outgoing packet on this ARP entry. */ - struct pbuf *q; -#endif /* ARP_QUEUEING */ - ip4_addr_t ipaddr; - struct netif *netif; - struct eth_addr ethaddr; - u16_t ctime; - u8_t state; -}; - -static struct etharp_entry arp_table[ARP_TABLE_SIZE]; - -#if !LWIP_NETIF_HWADDRHINT -static netif_addr_idx_t etharp_cached_entry; -#endif /* !LWIP_NETIF_HWADDRHINT */ - -/** Try hard to create a new entry - we want the IP address to appear in - the cache (even if this means removing an active entry or so). */ -#define ETHARP_FLAG_TRY_HARD 1 -#define ETHARP_FLAG_FIND_ONLY 2 -#if ETHARP_SUPPORT_STATIC_ENTRIES -#define ETHARP_FLAG_STATIC_ENTRY 4 -#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ - -#if LWIP_NETIF_HWADDRHINT -#define ETHARP_SET_ADDRHINT(netif, addrhint) do { if (((netif) != NULL) && ((netif)->hints != NULL)) { \ - (netif)->hints->addr_hint = (addrhint); }} while(0) -#else /* LWIP_NETIF_HWADDRHINT */ -#define ETHARP_SET_ADDRHINT(netif, addrhint) (etharp_cached_entry = (addrhint)) -#endif /* LWIP_NETIF_HWADDRHINT */ - - -/* Check for maximum ARP_TABLE_SIZE */ -#if (ARP_TABLE_SIZE > NETIF_ADDR_IDX_MAX) -#error "ARP_TABLE_SIZE must fit in an s16_t, you have to reduce it in your lwipopts.h" -#endif - - -static err_t etharp_request_dst(struct netif *netif, const ip4_addr_t *ipaddr, const struct eth_addr *hw_dst_addr); -static err_t etharp_raw(struct netif *netif, - const struct eth_addr *ethsrc_addr, const struct eth_addr *ethdst_addr, - const struct eth_addr *hwsrc_addr, const ip4_addr_t *ipsrc_addr, - const struct eth_addr *hwdst_addr, const ip4_addr_t *ipdst_addr, - const u16_t opcode); - -#if ARP_QUEUEING -/** - * Free a complete queue of etharp entries - * - * @param q a qeueue of etharp_q_entry's to free - */ -static void -free_etharp_q(struct etharp_q_entry *q) -{ - struct etharp_q_entry *r; - LWIP_ASSERT("q != NULL", q != NULL); - while (q) { - r = q; - q = q->next; - LWIP_ASSERT("r->p != NULL", (r->p != NULL)); - pbuf_free(r->p); - memp_free(MEMP_ARP_QUEUE, r); - } -} -#else /* ARP_QUEUEING */ - -/** Compatibility define: free the queued pbuf */ -#define free_etharp_q(q) pbuf_free(q) - -#endif /* ARP_QUEUEING */ - -/** Clean up ARP table entries */ -static void -etharp_free_entry(int i) -{ - /* remove from SNMP ARP index tree */ - mib2_remove_arp_entry(arp_table[i].netif, &arp_table[i].ipaddr); - /* and empty packet queue */ - if (arp_table[i].q != NULL) { - /* remove all queued packets */ - LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_free_entry: freeing entry %"U16_F", packet queue %p.\n", (u16_t)i, (void *)(arp_table[i].q))); - free_etharp_q(arp_table[i].q); - arp_table[i].q = NULL; - } - /* recycle entry for re-use */ - arp_table[i].state = ETHARP_STATE_EMPTY; -#ifdef LWIP_DEBUG - /* for debugging, clean out the complete entry */ - arp_table[i].ctime = 0; - arp_table[i].netif = NULL; - ip4_addr_set_zero(&arp_table[i].ipaddr); - arp_table[i].ethaddr = ethzero; -#endif /* LWIP_DEBUG */ -} - -/** - * Clears expired entries in the ARP table. - * - * This function should be called every ARP_TMR_INTERVAL milliseconds (1 second), - * in order to expire entries in the ARP table. - */ -void -etharp_tmr(void) -{ - int i; - - LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer\n")); - /* remove expired entries from the ARP table */ - for (i = 0; i < ARP_TABLE_SIZE; ++i) { - u8_t state = arp_table[i].state; - if (state != ETHARP_STATE_EMPTY -#if ETHARP_SUPPORT_STATIC_ENTRIES - && (state != ETHARP_STATE_STATIC) -#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ - ) { - arp_table[i].ctime++; - if ((arp_table[i].ctime >= ARP_MAXAGE) || - ((arp_table[i].state == ETHARP_STATE_PENDING) && - (arp_table[i].ctime >= ARP_MAXPENDING))) { - /* pending or stable entry has become old! */ - LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired %s entry %d.\n", - arp_table[i].state >= ETHARP_STATE_STABLE ? "stable" : "pending", i)); - /* clean up entries that have just been expired */ - etharp_free_entry(i); - } else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING_1) { - /* Don't send more than one request every 2 seconds. */ - arp_table[i].state = ETHARP_STATE_STABLE_REREQUESTING_2; - } else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING_2) { - /* Reset state to stable, so that the next transmitted packet will - re-send an ARP request. */ - arp_table[i].state = ETHARP_STATE_STABLE; - } else if (arp_table[i].state == ETHARP_STATE_PENDING) { - /* still pending, resend an ARP query */ - etharp_request(arp_table[i].netif, &arp_table[i].ipaddr); - } - } - } -} - -/** - * Search the ARP table for a matching or new entry. - * - * If an IP address is given, return a pending or stable ARP entry that matches - * the address. If no match is found, create a new entry with this address set, - * but in state ETHARP_EMPTY. The caller must check and possibly change the - * state of the returned entry. - * - * If ipaddr is NULL, return a initialized new entry in state ETHARP_EMPTY. - * - * In all cases, attempt to create new entries from an empty entry. If no - * empty entries are available and ETHARP_FLAG_TRY_HARD flag is set, recycle - * old entries. Heuristic choose the least important entry for recycling. - * - * @param ipaddr IP address to find in ARP cache, or to add if not found. - * @param flags See @ref etharp_state - * @param netif netif related to this address (used for NETIF_HWADDRHINT) - * - * @return The ARP entry index that matched or is created, ERR_MEM if no - * entry is found or could be recycled. - */ -static s16_t -etharp_find_entry(const ip4_addr_t *ipaddr, u8_t flags, struct netif *netif) -{ - s16_t old_pending = ARP_TABLE_SIZE, old_stable = ARP_TABLE_SIZE; - s16_t empty = ARP_TABLE_SIZE; - s16_t i = 0; - /* oldest entry with packets on queue */ - s16_t old_queue = ARP_TABLE_SIZE; - /* its age */ - u16_t age_queue = 0, age_pending = 0, age_stable = 0; - - LWIP_UNUSED_ARG(netif); - - /** - * a) do a search through the cache, remember candidates - * b) select candidate entry - * c) create new entry - */ - - /* a) in a single search sweep, do all of this - * 1) remember the first empty entry (if any) - * 2) remember the oldest stable entry (if any) - * 3) remember the oldest pending entry without queued packets (if any) - * 4) remember the oldest pending entry with queued packets (if any) - * 5) search for a matching IP entry, either pending or stable - * until 5 matches, or all entries are searched for. - */ - - for (i = 0; i < ARP_TABLE_SIZE; ++i) { - u8_t state = arp_table[i].state; - /* no empty entry found yet and now we do find one? */ - if ((empty == ARP_TABLE_SIZE) && (state == ETHARP_STATE_EMPTY)) { - LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_find_entry: found empty entry %d\n", (int)i)); - /* remember first empty entry */ - empty = i; - } else if (state != ETHARP_STATE_EMPTY) { - LWIP_ASSERT("state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE", - state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE); - /* if given, does IP address match IP address in ARP entry? */ - if (ipaddr && ip4_addr_cmp(ipaddr, &arp_table[i].ipaddr) -#if ETHARP_TABLE_MATCH_NETIF - && ((netif == NULL) || (netif == arp_table[i].netif)) -#endif /* ETHARP_TABLE_MATCH_NETIF */ - ) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: found matching entry %d\n", (int)i)); - /* found exact IP address match, simply bail out */ - return i; - } - /* pending entry? */ - if (state == ETHARP_STATE_PENDING) { - /* pending with queued packets? */ - if (arp_table[i].q != NULL) { - if (arp_table[i].ctime >= age_queue) { - old_queue = i; - age_queue = arp_table[i].ctime; - } - } else - /* pending without queued packets? */ - { - if (arp_table[i].ctime >= age_pending) { - old_pending = i; - age_pending = arp_table[i].ctime; - } - } - /* stable entry? */ - } else if (state >= ETHARP_STATE_STABLE) { -#if ETHARP_SUPPORT_STATIC_ENTRIES - /* don't record old_stable for static entries since they never expire */ - if (state < ETHARP_STATE_STATIC) -#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ - { - /* remember entry with oldest stable entry in oldest, its age in maxtime */ - if (arp_table[i].ctime >= age_stable) { - old_stable = i; - age_stable = arp_table[i].ctime; - } - } - } - } - } - /* { we have no match } => try to create a new entry */ - - /* don't create new entry, only search? */ - if (((flags & ETHARP_FLAG_FIND_ONLY) != 0) || - /* or no empty entry found and not allowed to recycle? */ - ((empty == ARP_TABLE_SIZE) && ((flags & ETHARP_FLAG_TRY_HARD) == 0))) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: no empty entry found and not allowed to recycle\n")); - return (s16_t)ERR_MEM; - } - - /* b) choose the least destructive entry to recycle: - * 1) empty entry - * 2) oldest stable entry - * 3) oldest pending entry without queued packets - * 4) oldest pending entry with queued packets - * - * { ETHARP_FLAG_TRY_HARD is set at this point } - */ - - /* 1) empty entry available? */ - if (empty < ARP_TABLE_SIZE) { - i = empty; - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting empty entry %d\n", (int)i)); - } else { - /* 2) found recyclable stable entry? */ - if (old_stable < ARP_TABLE_SIZE) { - /* recycle oldest stable*/ - i = old_stable; - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest stable entry %d\n", (int)i)); - /* no queued packets should exist on stable entries */ - LWIP_ASSERT("arp_table[i].q == NULL", arp_table[i].q == NULL); - /* 3) found recyclable pending entry without queued packets? */ - } else if (old_pending < ARP_TABLE_SIZE) { - /* recycle oldest pending */ - i = old_pending; - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest pending entry %d (without queue)\n", (int)i)); - /* 4) found recyclable pending entry with queued packets? */ - } else if (old_queue < ARP_TABLE_SIZE) { - /* recycle oldest pending (queued packets are free in etharp_free_entry) */ - i = old_queue; - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest pending entry %d, freeing packet queue %p\n", (int)i, (void *)(arp_table[i].q))); - /* no empty or recyclable entries found */ - } else { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: no empty or recyclable entries found\n")); - return (s16_t)ERR_MEM; - } - - /* { empty or recyclable entry found } */ - LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE); - etharp_free_entry(i); - } - - LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE); - LWIP_ASSERT("arp_table[i].state == ETHARP_STATE_EMPTY", - arp_table[i].state == ETHARP_STATE_EMPTY); - - /* IP address given? */ - if (ipaddr != NULL) { - /* set IP address */ - ip4_addr_copy(arp_table[i].ipaddr, *ipaddr); - } - arp_table[i].ctime = 0; -#if ETHARP_TABLE_MATCH_NETIF - arp_table[i].netif = netif; -#endif /* ETHARP_TABLE_MATCH_NETIF */ - return (s16_t)i; -} - -/** - * Update (or insert) a IP/MAC address pair in the ARP cache. - * - * If a pending entry is resolved, any queued packets will be sent - * at this point. - * - * @param netif netif related to this entry (used for NETIF_ADDRHINT) - * @param ipaddr IP address of the inserted ARP entry. - * @param ethaddr Ethernet address of the inserted ARP entry. - * @param flags See @ref etharp_state - * - * @return - * - ERR_OK Successfully updated ARP cache. - * - ERR_MEM If we could not add a new ARP entry when ETHARP_FLAG_TRY_HARD was set. - * - ERR_ARG Non-unicast address given, those will not appear in ARP cache. - * - * @see pbuf_free() - */ -static err_t -etharp_update_arp_entry(struct netif *netif, const ip4_addr_t *ipaddr, struct eth_addr *ethaddr, u8_t flags) -{ - s16_t i; - LWIP_ASSERT("netif->hwaddr_len == ETH_HWADDR_LEN", netif->hwaddr_len == ETH_HWADDR_LEN); - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n", - ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr), - (u16_t)ethaddr->addr[0], (u16_t)ethaddr->addr[1], (u16_t)ethaddr->addr[2], - (u16_t)ethaddr->addr[3], (u16_t)ethaddr->addr[4], (u16_t)ethaddr->addr[5])); - /* non-unicast address? */ - if (ip4_addr_isany(ipaddr) || - ip4_addr_isbroadcast(ipaddr, netif) || - ip4_addr_ismulticast(ipaddr)) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: will not add non-unicast IP address to ARP cache\n")); - return ERR_ARG; - } - /* find or create ARP entry */ - i = etharp_find_entry(ipaddr, flags, netif); - /* bail out if no entry could be found */ - if (i < 0) { - return (err_t)i; - } - -#if ETHARP_SUPPORT_STATIC_ENTRIES - if (flags & ETHARP_FLAG_STATIC_ENTRY) { - /* record static type */ - arp_table[i].state = ETHARP_STATE_STATIC; - } else if (arp_table[i].state == ETHARP_STATE_STATIC) { - /* found entry is a static type, don't overwrite it */ - return ERR_VAL; - } else -#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ - { - /* mark it stable */ - arp_table[i].state = ETHARP_STATE_STABLE; - } - - /* record network interface */ - arp_table[i].netif = netif; - /* insert in SNMP ARP index tree */ - mib2_add_arp_entry(netif, &arp_table[i].ipaddr); - - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: updating stable entry %"S16_F"\n", i)); - /* update address */ - SMEMCPY(&arp_table[i].ethaddr, ethaddr, ETH_HWADDR_LEN); - /* reset time stamp */ - arp_table[i].ctime = 0; - /* this is where we will send out queued packets! */ -#if ARP_QUEUEING - while (arp_table[i].q != NULL) { - struct pbuf *p; - /* remember remainder of queue */ - struct etharp_q_entry *q = arp_table[i].q; - /* pop first item off the queue */ - arp_table[i].q = q->next; - /* get the packet pointer */ - p = q->p; - /* now queue entry can be freed */ - memp_free(MEMP_ARP_QUEUE, q); -#else /* ARP_QUEUEING */ - if (arp_table[i].q != NULL) { - struct pbuf *p = arp_table[i].q; - arp_table[i].q = NULL; -#endif /* ARP_QUEUEING */ - /* send the queued IP packet */ - ethernet_output(netif, p, (struct eth_addr *)(netif->hwaddr), ethaddr, ETHTYPE_IP); - /* free the queued IP packet */ - pbuf_free(p); - } - return ERR_OK; -} - -#if ETHARP_SUPPORT_STATIC_ENTRIES -/** Add a new static entry to the ARP table. If an entry exists for the - * specified IP address, this entry is overwritten. - * If packets are queued for the specified IP address, they are sent out. - * - * @param ipaddr IP address for the new static entry - * @param ethaddr ethernet address for the new static entry - * @return See return values of etharp_add_static_entry - */ -err_t -etharp_add_static_entry(const ip4_addr_t *ipaddr, struct eth_addr *ethaddr) -{ - struct netif *netif; - LWIP_ASSERT_CORE_LOCKED(); - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_add_static_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n", - ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr), - (u16_t)ethaddr->addr[0], (u16_t)ethaddr->addr[1], (u16_t)ethaddr->addr[2], - (u16_t)ethaddr->addr[3], (u16_t)ethaddr->addr[4], (u16_t)ethaddr->addr[5])); - - netif = ip4_route(ipaddr); - if (netif == NULL) { - return ERR_RTE; - } - - return etharp_update_arp_entry(netif, ipaddr, ethaddr, ETHARP_FLAG_TRY_HARD | ETHARP_FLAG_STATIC_ENTRY); -} - -/** Remove a static entry from the ARP table previously added with a call to - * etharp_add_static_entry. - * - * @param ipaddr IP address of the static entry to remove - * @return ERR_OK: entry removed - * ERR_MEM: entry wasn't found - * ERR_ARG: entry wasn't a static entry but a dynamic one - */ -err_t -etharp_remove_static_entry(const ip4_addr_t *ipaddr) -{ - s16_t i; - LWIP_ASSERT_CORE_LOCKED(); - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_remove_static_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr))); - - /* find or create ARP entry */ - i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY, NULL); - /* bail out if no entry could be found */ - if (i < 0) { - return (err_t)i; - } - - if (arp_table[i].state != ETHARP_STATE_STATIC) { - /* entry wasn't a static entry, cannot remove it */ - return ERR_ARG; - } - /* entry found, free it */ - etharp_free_entry(i); - return ERR_OK; -} -#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ - -/** - * Remove all ARP table entries of the specified netif. - * - * @param netif points to a network interface - */ -void -etharp_cleanup_netif(struct netif *netif) -{ - int i; - - for (i = 0; i < ARP_TABLE_SIZE; ++i) { - u8_t state = arp_table[i].state; - if ((state != ETHARP_STATE_EMPTY) && (arp_table[i].netif == netif)) { - etharp_free_entry(i); - } - } -} - -/** - * Finds (stable) ethernet/IP address pair from ARP table - * using interface and IP address index. - * @note the addresses in the ARP table are in network order! - * - * @param netif points to interface index - * @param ipaddr points to the (network order) IP address index - * @param eth_ret points to return pointer - * @param ip_ret points to return pointer - * @return table index if found, -1 otherwise - */ -ssize_t -etharp_find_addr(struct netif *netif, const ip4_addr_t *ipaddr, - struct eth_addr **eth_ret, const ip4_addr_t **ip_ret) -{ - s16_t i; - - LWIP_ASSERT("eth_ret != NULL && ip_ret != NULL", - eth_ret != NULL && ip_ret != NULL); - - LWIP_UNUSED_ARG(netif); - - i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY, netif); - if ((i >= 0) && (arp_table[i].state >= ETHARP_STATE_STABLE)) { - *eth_ret = &arp_table[i].ethaddr; - *ip_ret = &arp_table[i].ipaddr; - return i; - } - return -1; -} - -/** - * Possibility to iterate over stable ARP table entries - * - * @param i entry number, 0 to ARP_TABLE_SIZE - * @param ipaddr return value: IP address - * @param netif return value: points to interface - * @param eth_ret return value: ETH address - * @return 1 on valid index, 0 otherwise - */ -int -etharp_get_entry(size_t i, ip4_addr_t **ipaddr, struct netif **netif, struct eth_addr **eth_ret) -{ - LWIP_ASSERT("ipaddr != NULL", ipaddr != NULL); - LWIP_ASSERT("netif != NULL", netif != NULL); - LWIP_ASSERT("eth_ret != NULL", eth_ret != NULL); - - if ((i < ARP_TABLE_SIZE) && (arp_table[i].state >= ETHARP_STATE_STABLE)) { - *ipaddr = &arp_table[i].ipaddr; - *netif = arp_table[i].netif; - *eth_ret = &arp_table[i].ethaddr; - return 1; - } else { - return 0; - } -} - -/** - * Responds to ARP requests to us. Upon ARP replies to us, add entry to cache - * send out queued IP packets. Updates cache with snooped address pairs. - * - * Should be called for incoming ARP packets. The pbuf in the argument - * is freed by this function. - * - * @param p The ARP packet that arrived on netif. Is freed by this function. - * @param netif The lwIP network interface on which the ARP packet pbuf arrived. - * - * @see pbuf_free() - */ -void -etharp_input(struct pbuf *p, struct netif *netif) -{ - struct etharp_hdr *hdr; - /* these are aligned properly, whereas the ARP header fields might not be */ - ip4_addr_t sipaddr, dipaddr; - u8_t for_us; - - LWIP_ASSERT_CORE_LOCKED(); - - LWIP_ERROR("netif != NULL", (netif != NULL), return;); - - hdr = (struct etharp_hdr *)p->payload; - - /* RFC 826 "Packet Reception": */ - if ((hdr->hwtype != PP_HTONS(LWIP_IANA_HWTYPE_ETHERNET)) || - (hdr->hwlen != ETH_HWADDR_LEN) || - (hdr->protolen != sizeof(ip4_addr_t)) || - (hdr->proto != PP_HTONS(ETHTYPE_IP))) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, - ("etharp_input: packet dropped, wrong hw type, hwlen, proto, protolen or ethernet type (%"U16_F"/%"U16_F"/%"U16_F"/%"U16_F")\n", - hdr->hwtype, (u16_t)hdr->hwlen, hdr->proto, (u16_t)hdr->protolen)); - ETHARP_STATS_INC(etharp.proterr); - ETHARP_STATS_INC(etharp.drop); - pbuf_free(p); - return; - } - ETHARP_STATS_INC(etharp.recv); - -#if LWIP_AUTOIP - /* We have to check if a host already has configured our random - * created link local address and continuously check if there is - * a host with this IP-address so we can detect collisions */ - autoip_arp_reply(netif, hdr); -#endif /* LWIP_AUTOIP */ - - /* Copy struct ip4_addr_wordaligned to aligned ip4_addr, to support compilers without - * structure packing (not using structure copy which breaks strict-aliasing rules). */ - IPADDR_WORDALIGNED_COPY_TO_IP4_ADDR_T(&sipaddr, &hdr->sipaddr); - IPADDR_WORDALIGNED_COPY_TO_IP4_ADDR_T(&dipaddr, &hdr->dipaddr); - - /* this interface is not configured? */ - if (ip4_addr_isany_val(*netif_ip4_addr(netif))) { - for_us = 0; - } else { - /* ARP packet directed to us? */ - for_us = (u8_t)ip4_addr_cmp(&dipaddr, netif_ip4_addr(netif)); - } - - /* ARP message directed to us? - -> add IP address in ARP cache; assume requester wants to talk to us, - can result in directly sending the queued packets for this host. - ARP message not directed to us? - -> update the source IP address in the cache, if present */ - etharp_update_arp_entry(netif, &sipaddr, &(hdr->shwaddr), - for_us ? ETHARP_FLAG_TRY_HARD : ETHARP_FLAG_FIND_ONLY); - - /* now act on the message itself */ - switch (hdr->opcode) { - /* ARP request? */ - case PP_HTONS(ARP_REQUEST): - /* ARP request. If it asked for our address, we send out a - * reply. In any case, we time-stamp any existing ARP entry, - * and possibly send out an IP packet that was queued on it. */ - - LWIP_DEBUGF (ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_input: incoming ARP request\n")); - /* ARP request for our address? */ - if (for_us) { - /* send ARP response */ - etharp_raw(netif, - (struct eth_addr *)netif->hwaddr, &hdr->shwaddr, - (struct eth_addr *)netif->hwaddr, netif_ip4_addr(netif), - &hdr->shwaddr, &sipaddr, - ARP_REPLY); - /* we are not configured? */ - } else if (ip4_addr_isany_val(*netif_ip4_addr(netif))) { - /* { for_us == 0 and netif->ip_addr.addr == 0 } */ - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_input: we are unconfigured, ARP request ignored.\n")); - /* request was not directed to us */ - } else { - /* { for_us == 0 and netif->ip_addr.addr != 0 } */ - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_input: ARP request was not for us.\n")); - } - break; - case PP_HTONS(ARP_REPLY): - /* ARP reply. We already updated the ARP cache earlier. */ - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_input: incoming ARP reply\n")); -#if (LWIP_DHCP && DHCP_DOES_ARP_CHECK) - /* DHCP wants to know about ARP replies from any host with an - * IP address also offered to us by the DHCP server. We do not - * want to take a duplicate IP address on a single network. - * @todo How should we handle redundant (fail-over) interfaces? */ - dhcp_arp_reply(netif, &sipaddr); -#endif /* (LWIP_DHCP && DHCP_DOES_ARP_CHECK) */ - break; - default: - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_input: ARP unknown opcode type %"S16_F"\n", lwip_htons(hdr->opcode))); - ETHARP_STATS_INC(etharp.err); - break; - } - /* free ARP packet */ - pbuf_free(p); -} - -/** Just a small helper function that sends a pbuf to an ethernet address - * in the arp_table specified by the index 'arp_idx'. - */ -static err_t -etharp_output_to_arp_index(struct netif *netif, struct pbuf *q, netif_addr_idx_t arp_idx) -{ - LWIP_ASSERT("arp_table[arp_idx].state >= ETHARP_STATE_STABLE", - arp_table[arp_idx].state >= ETHARP_STATE_STABLE); - /* if arp table entry is about to expire: re-request it, - but only if its state is ETHARP_STATE_STABLE to prevent flooding the - network with ARP requests if this address is used frequently. */ - if (arp_table[arp_idx].state == ETHARP_STATE_STABLE) { - if (arp_table[arp_idx].ctime >= ARP_AGE_REREQUEST_USED_BROADCAST) { - /* issue a standard request using broadcast */ - if (etharp_request(netif, &arp_table[arp_idx].ipaddr) == ERR_OK) { - arp_table[arp_idx].state = ETHARP_STATE_STABLE_REREQUESTING_1; - } - } else if (arp_table[arp_idx].ctime >= ARP_AGE_REREQUEST_USED_UNICAST) { - /* issue a unicast request (for 15 seconds) to prevent unnecessary broadcast */ - if (etharp_request_dst(netif, &arp_table[arp_idx].ipaddr, &arp_table[arp_idx].ethaddr) == ERR_OK) { - arp_table[arp_idx].state = ETHARP_STATE_STABLE_REREQUESTING_1; - } - } - } - - return ethernet_output(netif, q, (struct eth_addr *)(netif->hwaddr), &arp_table[arp_idx].ethaddr, ETHTYPE_IP); -} - -/** - * Resolve and fill-in Ethernet address header for outgoing IP packet. - * - * For IP multicast and broadcast, corresponding Ethernet addresses - * are selected and the packet is transmitted on the link. - * - * For unicast addresses, the packet is submitted to etharp_query(). In - * case the IP address is outside the local network, the IP address of - * the gateway is used. - * - * @param netif The lwIP network interface which the IP packet will be sent on. - * @param q The pbuf(s) containing the IP packet to be sent. - * @param ipaddr The IP address of the packet destination. - * - * @return - * - ERR_RTE No route to destination (no gateway to external networks), - * or the return type of either etharp_query() or ethernet_output(). - */ -err_t -etharp_output(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr) -{ - const struct eth_addr *dest; - struct eth_addr mcastaddr; - const ip4_addr_t *dst_addr = ipaddr; - - LWIP_ASSERT_CORE_LOCKED(); - LWIP_ASSERT("netif != NULL", netif != NULL); - LWIP_ASSERT("q != NULL", q != NULL); - LWIP_ASSERT("ipaddr != NULL", ipaddr != NULL); - - /* Determine on destination hardware address. Broadcasts and multicasts - * are special, other IP addresses are looked up in the ARP table. */ - - /* broadcast destination IP address? */ - if (ip4_addr_isbroadcast(ipaddr, netif)) { - /* broadcast on Ethernet also */ - dest = (const struct eth_addr *)ðbroadcast; - /* multicast destination IP address? */ - } else if (ip4_addr_ismulticast(ipaddr)) { - /* Hash IP multicast address to MAC address.*/ - mcastaddr.addr[0] = LL_IP4_MULTICAST_ADDR_0; - mcastaddr.addr[1] = LL_IP4_MULTICAST_ADDR_1; - mcastaddr.addr[2] = LL_IP4_MULTICAST_ADDR_2; - mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f; - mcastaddr.addr[4] = ip4_addr3(ipaddr); - mcastaddr.addr[5] = ip4_addr4(ipaddr); - /* destination Ethernet address is multicast */ - dest = &mcastaddr; - /* unicast destination IP address? */ - } else { - netif_addr_idx_t i; - /* outside local network? if so, this can neither be a global broadcast nor - a subnet broadcast. */ - if (!ip4_addr_netcmp(ipaddr, netif_ip4_addr(netif), netif_ip4_netmask(netif)) && - !ip4_addr_islinklocal(ipaddr)) { -#if LWIP_AUTOIP - struct ip_hdr *iphdr = LWIP_ALIGNMENT_CAST(struct ip_hdr *, q->payload); - /* According to RFC 3297, chapter 2.6.2 (Forwarding Rules), a packet with - a link-local source address must always be "directly to its destination - on the same physical link. The host MUST NOT send the packet to any - router for forwarding". */ - if (!ip4_addr_islinklocal(&iphdr->src)) -#endif /* LWIP_AUTOIP */ - { -#ifdef LWIP_HOOK_ETHARP_GET_GW - /* For advanced routing, a single default gateway might not be enough, so get - the IP address of the gateway to handle the current destination address. */ - dst_addr = LWIP_HOOK_ETHARP_GET_GW(netif, ipaddr); - if (dst_addr == NULL) -#endif /* LWIP_HOOK_ETHARP_GET_GW */ - { - /* interface has default gateway? */ - if (!ip4_addr_isany_val(*netif_ip4_gw(netif))) { - /* send to hardware address of default gateway IP address */ - dst_addr = netif_ip4_gw(netif); - /* no default gateway available */ - } else { - /* no route to destination error (default gateway missing) */ - return ERR_RTE; - } - } - } - } -#if LWIP_NETIF_HWADDRHINT - if (netif->hints != NULL) { - /* per-pcb cached entry was given */ - netif_addr_idx_t etharp_cached_entry = netif->hints->addr_hint; - if (etharp_cached_entry < ARP_TABLE_SIZE) { -#endif /* LWIP_NETIF_HWADDRHINT */ - if ((arp_table[etharp_cached_entry].state >= ETHARP_STATE_STABLE) && -#if ETHARP_TABLE_MATCH_NETIF - (arp_table[etharp_cached_entry].netif == netif) && -#endif - (ip4_addr_cmp(dst_addr, &arp_table[etharp_cached_entry].ipaddr))) { - /* the per-pcb-cached entry is stable and the right one! */ - ETHARP_STATS_INC(etharp.cachehit); - return etharp_output_to_arp_index(netif, q, etharp_cached_entry); - } -#if LWIP_NETIF_HWADDRHINT - } - } -#endif /* LWIP_NETIF_HWADDRHINT */ - - /* find stable entry: do this here since this is a critical path for - throughput and etharp_find_entry() is kind of slow */ - for (i = 0; i < ARP_TABLE_SIZE; i++) { - if ((arp_table[i].state >= ETHARP_STATE_STABLE) && -#if ETHARP_TABLE_MATCH_NETIF - (arp_table[i].netif == netif) && -#endif - (ip4_addr_cmp(dst_addr, &arp_table[i].ipaddr))) { - /* found an existing, stable entry */ - ETHARP_SET_ADDRHINT(netif, i); - return etharp_output_to_arp_index(netif, q, i); - } - } - /* no stable entry found, use the (slower) query function: - queue on destination Ethernet address belonging to ipaddr */ - return etharp_query(netif, dst_addr, q); - } - - /* continuation for multicast/broadcast destinations */ - /* obtain source Ethernet address of the given interface */ - /* send packet directly on the link */ - return ethernet_output(netif, q, (struct eth_addr *)(netif->hwaddr), dest, ETHTYPE_IP); -} - -/** - * Send an ARP request for the given IP address and/or queue a packet. - * - * If the IP address was not yet in the cache, a pending ARP cache entry - * is added and an ARP request is sent for the given address. The packet - * is queued on this entry. - * - * If the IP address was already pending in the cache, a new ARP request - * is sent for the given address. The packet is queued on this entry. - * - * If the IP address was already stable in the cache, and a packet is - * given, it is directly sent and no ARP request is sent out. - * - * If the IP address was already stable in the cache, and no packet is - * given, an ARP request is sent out. - * - * @param netif The lwIP network interface on which ipaddr - * must be queried for. - * @param ipaddr The IP address to be resolved. - * @param q If non-NULL, a pbuf that must be delivered to the IP address. - * q is not freed by this function. - * - * @note q must only be ONE packet, not a packet queue! - * - * @return - * - ERR_BUF Could not make room for Ethernet header. - * - ERR_MEM Hardware address unknown, and no more ARP entries available - * to query for address or queue the packet. - * - ERR_MEM Could not queue packet due to memory shortage. - * - ERR_RTE No route to destination (no gateway to external networks). - * - ERR_ARG Non-unicast address given, those will not appear in ARP cache. - * - */ -err_t -etharp_query(struct netif *netif, const ip4_addr_t *ipaddr, struct pbuf *q) -{ - struct eth_addr *srcaddr = (struct eth_addr *)netif->hwaddr; - err_t result = ERR_MEM; - int is_new_entry = 0; - s16_t i_err; - netif_addr_idx_t i; - - /* non-unicast address? */ - if (ip4_addr_isbroadcast(ipaddr, netif) || - ip4_addr_ismulticast(ipaddr) || - ip4_addr_isany(ipaddr)) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: will not add non-unicast IP address to ARP cache\n")); - return ERR_ARG; - } - - /* find entry in ARP cache, ask to create entry if queueing packet */ - i_err = etharp_find_entry(ipaddr, ETHARP_FLAG_TRY_HARD, netif); - - /* could not find or create entry? */ - if (i_err < 0) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not create ARP entry\n")); - if (q) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: packet dropped\n")); - ETHARP_STATS_INC(etharp.memerr); - } - return (err_t)i_err; - } - LWIP_ASSERT("type overflow", (size_t)i_err < NETIF_ADDR_IDX_MAX); - i = (netif_addr_idx_t)i_err; - - /* mark a fresh entry as pending (we just sent a request) */ - if (arp_table[i].state == ETHARP_STATE_EMPTY) { - is_new_entry = 1; - arp_table[i].state = ETHARP_STATE_PENDING; - /* record network interface for re-sending arp request in etharp_tmr */ - arp_table[i].netif = netif; - } - - /* { i is either a STABLE or (new or existing) PENDING entry } */ - LWIP_ASSERT("arp_table[i].state == PENDING or STABLE", - ((arp_table[i].state == ETHARP_STATE_PENDING) || - (arp_table[i].state >= ETHARP_STATE_STABLE))); - - /* do we have a new entry? or an implicit query request? */ - if (is_new_entry || (q == NULL)) { - /* try to resolve it; send out ARP request */ - result = etharp_request(netif, ipaddr); - if (result != ERR_OK) { - /* ARP request couldn't be sent */ - /* We don't re-send arp request in etharp_tmr, but we still queue packets, - since this failure could be temporary, and the next packet calling - etharp_query again could lead to sending the queued packets. */ - } - if (q == NULL) { - return result; - } - } - - /* packet given? */ - LWIP_ASSERT("q != NULL", q != NULL); - /* stable entry? */ - if (arp_table[i].state >= ETHARP_STATE_STABLE) { - /* we have a valid IP->Ethernet address mapping */ - ETHARP_SET_ADDRHINT(netif, i); - /* send the packet */ - result = ethernet_output(netif, q, srcaddr, &(arp_table[i].ethaddr), ETHTYPE_IP); - /* pending entry? (either just created or already pending */ - } else if (arp_table[i].state == ETHARP_STATE_PENDING) { - /* entry is still pending, queue the given packet 'q' */ - struct pbuf *p; - int copy_needed = 0; - /* IF q includes a pbuf that must be copied, copy the whole chain into a - * new PBUF_RAM. See the definition of PBUF_NEEDS_COPY for details. */ - p = q; - while (p) { - LWIP_ASSERT("no packet queues allowed!", (p->len != p->tot_len) || (p->next == 0)); - if (PBUF_NEEDS_COPY(p)) { - copy_needed = 1; - break; - } - p = p->next; - } - if (copy_needed) { - /* copy the whole packet into new pbufs */ - p = pbuf_clone(PBUF_LINK, PBUF_RAM, q); - } else { - /* referencing the old pbuf is enough */ - p = q; - pbuf_ref(p); - } - /* packet could be taken over? */ - if (p != NULL) { - /* queue packet ... */ -#if ARP_QUEUEING - struct etharp_q_entry *new_entry; - /* allocate a new arp queue entry */ - new_entry = (struct etharp_q_entry *)memp_malloc(MEMP_ARP_QUEUE); - if (new_entry != NULL) { - unsigned int qlen = 0; - new_entry->next = 0; - new_entry->p = p; - if (arp_table[i].q != NULL) { - /* queue was already existent, append the new entry to the end */ - struct etharp_q_entry *r; - r = arp_table[i].q; - qlen++; - while (r->next != NULL) { - r = r->next; - qlen++; - } - r->next = new_entry; - } else { - /* queue did not exist, first item in queue */ - arp_table[i].q = new_entry; - } -#if ARP_QUEUE_LEN - if (qlen >= ARP_QUEUE_LEN) { - struct etharp_q_entry *old; - old = arp_table[i].q; - arp_table[i].q = arp_table[i].q->next; - pbuf_free(old->p); - memp_free(MEMP_ARP_QUEUE, old); - } -#endif - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"U16_F"\n", (void *)q, i)); - result = ERR_OK; - } else { - /* the pool MEMP_ARP_QUEUE is empty */ - pbuf_free(p); - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q)); - result = ERR_MEM; - } -#else /* ARP_QUEUEING */ - /* always queue one packet per ARP request only, freeing a previously queued packet */ - if (arp_table[i].q != NULL) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: dropped previously queued packet %p for ARP entry %"U16_F"\n", (void *)q, (u16_t)i)); - pbuf_free(arp_table[i].q); - } - arp_table[i].q = p; - result = ERR_OK; - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"U16_F"\n", (void *)q, (u16_t)i)); -#endif /* ARP_QUEUEING */ - } else { - ETHARP_STATS_INC(etharp.memerr); - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q)); - result = ERR_MEM; - } - } - return result; -} - -/** - * Send a raw ARP packet (opcode and all addresses can be modified) - * - * @param netif the lwip network interface on which to send the ARP packet - * @param ethsrc_addr the source MAC address for the ethernet header - * @param ethdst_addr the destination MAC address for the ethernet header - * @param hwsrc_addr the source MAC address for the ARP protocol header - * @param ipsrc_addr the source IP address for the ARP protocol header - * @param hwdst_addr the destination MAC address for the ARP protocol header - * @param ipdst_addr the destination IP address for the ARP protocol header - * @param opcode the type of the ARP packet - * @return ERR_OK if the ARP packet has been sent - * ERR_MEM if the ARP packet couldn't be allocated - * any other err_t on failure - */ -static err_t -etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr, - const struct eth_addr *ethdst_addr, - const struct eth_addr *hwsrc_addr, const ip4_addr_t *ipsrc_addr, - const struct eth_addr *hwdst_addr, const ip4_addr_t *ipdst_addr, - const u16_t opcode) -{ - struct pbuf *p; - err_t result = ERR_OK; - struct etharp_hdr *hdr; - - LWIP_ASSERT("netif != NULL", netif != NULL); - - /* allocate a pbuf for the outgoing ARP request packet */ - p = pbuf_alloc(PBUF_LINK, SIZEOF_ETHARP_HDR, PBUF_RAM); - /* could allocate a pbuf for an ARP request? */ - if (p == NULL) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, - ("etharp_raw: could not allocate pbuf for ARP request.\n")); - ETHARP_STATS_INC(etharp.memerr); - return ERR_MEM; - } - LWIP_ASSERT("check that first pbuf can hold struct etharp_hdr", - (p->len >= SIZEOF_ETHARP_HDR)); - - hdr = (struct etharp_hdr *)p->payload; - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_raw: sending raw ARP packet.\n")); - hdr->opcode = lwip_htons(opcode); - - LWIP_ASSERT("netif->hwaddr_len must be the same as ETH_HWADDR_LEN for etharp!", - (netif->hwaddr_len == ETH_HWADDR_LEN)); - - /* Write the ARP MAC-Addresses */ - SMEMCPY(&hdr->shwaddr, hwsrc_addr, ETH_HWADDR_LEN); - SMEMCPY(&hdr->dhwaddr, hwdst_addr, ETH_HWADDR_LEN); - /* Copy struct ip4_addr_wordaligned to aligned ip4_addr, to support compilers without - * structure packing. */ - IPADDR_WORDALIGNED_COPY_FROM_IP4_ADDR_T(&hdr->sipaddr, ipsrc_addr); - IPADDR_WORDALIGNED_COPY_FROM_IP4_ADDR_T(&hdr->dipaddr, ipdst_addr); - - hdr->hwtype = PP_HTONS(LWIP_IANA_HWTYPE_ETHERNET); - hdr->proto = PP_HTONS(ETHTYPE_IP); - /* set hwlen and protolen */ - hdr->hwlen = ETH_HWADDR_LEN; - hdr->protolen = sizeof(ip4_addr_t); - - /* send ARP query */ -#if LWIP_AUTOIP - /* If we are using Link-Local, all ARP packets that contain a Link-Local - * 'sender IP address' MUST be sent using link-layer broadcast instead of - * link-layer unicast. (See RFC3927 Section 2.5, last paragraph) */ - if (ip4_addr_islinklocal(ipsrc_addr)) { - ethernet_output(netif, p, ethsrc_addr, ðbroadcast, ETHTYPE_ARP); - } else -#endif /* LWIP_AUTOIP */ - { - ethernet_output(netif, p, ethsrc_addr, ethdst_addr, ETHTYPE_ARP); - } - - ETHARP_STATS_INC(etharp.xmit); - /* free ARP query packet */ - pbuf_free(p); - p = NULL; - /* could not allocate pbuf for ARP request */ - - return result; -} - -/** - * Send an ARP request packet asking for ipaddr to a specific eth address. - * Used to send unicast request to refresh the ARP table just before an entry - * times out - * - * @param netif the lwip network interface on which to send the request - * @param ipaddr the IP address for which to ask - * @param hw_dst_addr the ethernet address to send this packet to - * @return ERR_OK if the request has been sent - * ERR_MEM if the ARP packet couldn't be allocated - * any other err_t on failure - */ -static err_t -etharp_request_dst(struct netif *netif, const ip4_addr_t *ipaddr, const struct eth_addr *hw_dst_addr) -{ - return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, hw_dst_addr, - (struct eth_addr *)netif->hwaddr, netif_ip4_addr(netif), ðzero, - ipaddr, ARP_REQUEST); -} - -/** - * Send an ARP request packet asking for ipaddr. - * - * @param netif the lwip network interface on which to send the request - * @param ipaddr the IP address for which to ask - * @return ERR_OK if the request has been sent - * ERR_MEM if the ARP packet couldn't be allocated - * any other err_t on failure - */ -err_t -etharp_request(struct netif *netif, const ip4_addr_t *ipaddr) -{ - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_request: sending ARP request.\n")); - return etharp_request_dst(netif, ipaddr, ðbroadcast); -} - -#endif /* LWIP_IPV4 && LWIP_ARP */ diff --git a/third-party/lwip-2.1.2/core/ipv4/icmp.c b/third-party/lwip-2.1.2/core/ipv4/icmp.c deleted file mode 100644 index 9dcdf6c8..00000000 --- a/third-party/lwip-2.1.2/core/ipv4/icmp.c +++ /dev/null @@ -1,404 +0,0 @@ -/** - * @file - * ICMP - Internet Control Message Protocol - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -/* Some ICMP messages should be passed to the transport protocols. This - is not implemented. */ - -#include "lwip/opt.h" - -#if LWIP_IPV4 && LWIP_ICMP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/icmp.h" -#include "lwip/inet_chksum.h" -#include "lwip/ip.h" -#include "lwip/def.h" -#include "lwip/stats.h" - -#include - -#ifdef LWIP_HOOK_FILENAME -#include LWIP_HOOK_FILENAME -#endif - -/** Small optimization: set to 0 if incoming PBUF_POOL pbuf always can be - * used to modify and send a response packet (and to 1 if this is not the case, - * e.g. when link header is stripped off when receiving) */ -#ifndef LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN -#define LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN 1 -#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */ - -/* The amount of data from the original packet to return in a dest-unreachable */ -#define ICMP_DEST_UNREACH_DATASIZE 8 - -static void icmp_send_response(struct pbuf *p, u8_t type, u8_t code); - -/** - * Processes ICMP input packets, called from ip_input(). - * - * Currently only processes icmp echo requests and sends - * out the echo response. - * - * @param p the icmp echo request packet, p->payload pointing to the icmp header - * @param inp the netif on which this packet was received - */ -void -icmp_input(struct pbuf *p, struct netif *inp) -{ - u8_t type; -#ifdef LWIP_DEBUG - u8_t code; -#endif /* LWIP_DEBUG */ - struct icmp_echo_hdr *iecho; - const struct ip_hdr *iphdr_in; - u16_t hlen; - const ip4_addr_t *src; - - ICMP_STATS_INC(icmp.recv); - MIB2_STATS_INC(mib2.icmpinmsgs); - - iphdr_in = ip4_current_header(); - hlen = IPH_HL_BYTES(iphdr_in); - if (hlen < IP_HLEN) { - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short IP header (%"S16_F" bytes) received\n", hlen)); - goto lenerr; - } - if (p->len < sizeof(u16_t) * 2) { - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short ICMP (%"U16_F" bytes) received\n", p->tot_len)); - goto lenerr; - } - - type = *((u8_t *)p->payload); -#ifdef LWIP_DEBUG - code = *(((u8_t *)p->payload) + 1); - /* if debug is enabled but debug statement below is somehow disabled: */ - LWIP_UNUSED_ARG(code); -#endif /* LWIP_DEBUG */ - switch (type) { - case ICMP_ER: - /* This is OK, echo reply might have been parsed by a raw PCB - (as obviously, an echo request has been sent, too). */ - MIB2_STATS_INC(mib2.icmpinechoreps); - break; - case ICMP_ECHO: - MIB2_STATS_INC(mib2.icmpinechos); - src = ip4_current_dest_addr(); - /* multicast destination address? */ - if (ip4_addr_ismulticast(ip4_current_dest_addr())) { -#if LWIP_MULTICAST_PING - /* For multicast, use address of receiving interface as source address */ - src = netif_ip4_addr(inp); -#else /* LWIP_MULTICAST_PING */ - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: Not echoing to multicast pings\n")); - goto icmperr; -#endif /* LWIP_MULTICAST_PING */ - } - /* broadcast destination address? */ - if (ip4_addr_isbroadcast(ip4_current_dest_addr(), ip_current_netif())) { -#if LWIP_BROADCAST_PING - /* For broadcast, use address of receiving interface as source address */ - src = netif_ip4_addr(inp); -#else /* LWIP_BROADCAST_PING */ - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: Not echoing to broadcast pings\n")); - goto icmperr; -#endif /* LWIP_BROADCAST_PING */ - } - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ping\n")); - if (p->tot_len < sizeof(struct icmp_echo_hdr)) { - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: bad ICMP echo received\n")); - goto lenerr; - } -#if CHECKSUM_CHECK_ICMP - IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_ICMP) { - if (inet_chksum_pbuf(p) != 0) { - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo\n")); - pbuf_free(p); - ICMP_STATS_INC(icmp.chkerr); - MIB2_STATS_INC(mib2.icmpinerrors); - return; - } - } -#endif -#if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN - if (pbuf_add_header(p, hlen + PBUF_LINK_HLEN + PBUF_LINK_ENCAPSULATION_HLEN)) { - /* p is not big enough to contain link headers - * allocate a new one and copy p into it - */ - struct pbuf *r; - u16_t alloc_len = (u16_t)(p->tot_len + hlen); - if (alloc_len < p->tot_len) { - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: allocating new pbuf failed (tot_len overflow)\n")); - goto icmperr; - } - /* allocate new packet buffer with space for link headers */ - r = pbuf_alloc(PBUF_LINK, alloc_len, PBUF_RAM); - if (r == NULL) { - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: allocating new pbuf failed alloc_len is %d \n",alloc_len)); - goto icmperr; - } - if (r->len < hlen + sizeof(struct icmp_echo_hdr)) { - LWIP_DEBUGF(ICMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("first pbuf cannot hold the ICMP header")); - pbuf_free(r); - goto icmperr; - } - /* copy the ip header */ - MEMCPY(r->payload, iphdr_in, hlen); - /* switch r->payload back to icmp header (cannot fail) */ - if (pbuf_remove_header(r, hlen)) { - LWIP_ASSERT("icmp_input: moving r->payload to icmp header failed\n", 0); - pbuf_free(r); - goto icmperr; - } - /* copy the rest of the packet without ip header */ - if (pbuf_copy(r, p) != ERR_OK) { - LWIP_DEBUGF(ICMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("icmp_input: copying to new pbuf failed")); - pbuf_free(r); - goto icmperr; - } - /* free the original p */ - pbuf_free(p); - /* we now have an identical copy of p that has room for link headers */ - p = r; - } else { - /* restore p->payload to point to icmp header (cannot fail) */ - if (pbuf_remove_header(p, hlen + PBUF_LINK_HLEN + PBUF_LINK_ENCAPSULATION_HLEN)) { - LWIP_ASSERT("icmp_input: restoring original p->payload failed\n", 0); - goto icmperr; - } - } -#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */ - /* At this point, all checks are OK. */ - /* We generate an answer by switching the dest and src ip addresses, - * setting the icmp type to ECHO_RESPONSE and updating the checksum. */ - iecho = (struct icmp_echo_hdr *)p->payload; - if (pbuf_add_header(p, hlen)) { - LWIP_DEBUGF(ICMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("Can't move over header in packet")); - } else { - err_t ret; - struct ip_hdr *iphdr = (struct ip_hdr *)p->payload; - ip4_addr_copy(iphdr->src, *src); - ip4_addr_copy(iphdr->dest, *ip4_current_src_addr()); - ICMPH_TYPE_SET(iecho, ICMP_ER); -#if CHECKSUM_GEN_ICMP - IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_ICMP) { - /* adjust the checksum */ - if (iecho->chksum > PP_HTONS(0xffffU - (ICMP_ECHO << 8))) { - iecho->chksum = (u16_t)(iecho->chksum + PP_HTONS((u16_t)(ICMP_ECHO << 8)) + 1); - } else { - iecho->chksum = (u16_t)(iecho->chksum + PP_HTONS(ICMP_ECHO << 8)); - } - } -#if LWIP_CHECKSUM_CTRL_PER_NETIF - else { - iecho->chksum = 0; - } -#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */ -#else /* CHECKSUM_GEN_ICMP */ - iecho->chksum = 0; -#endif /* CHECKSUM_GEN_ICMP */ - - /* Set the correct TTL and recalculate the header checksum. */ - IPH_TTL_SET(iphdr, ICMP_TTL); - IPH_CHKSUM_SET(iphdr, 0); -#if CHECKSUM_GEN_IP - IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_IP) { - IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, hlen)); - } -#endif /* CHECKSUM_GEN_IP */ - - ICMP_STATS_INC(icmp.xmit); - /* increase number of messages attempted to send */ - MIB2_STATS_INC(mib2.icmpoutmsgs); - /* increase number of echo replies attempted to send */ - MIB2_STATS_INC(mib2.icmpoutechoreps); - - /* send an ICMP packet */ - ret = ip4_output_if(p, src, LWIP_IP_HDRINCL, - ICMP_TTL, 0, IP_PROTO_ICMP, inp); - if (ret != ERR_OK) { - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ip_output_if returned an error: %s\n", lwip_strerr(ret))); - } - } - break; - default: - if (type == ICMP_DUR) { - MIB2_STATS_INC(mib2.icmpindestunreachs); - } else if (type == ICMP_TE) { - MIB2_STATS_INC(mib2.icmpintimeexcds); - } else if (type == ICMP_PP) { - MIB2_STATS_INC(mib2.icmpinparmprobs); - } else if (type == ICMP_SQ) { - MIB2_STATS_INC(mib2.icmpinsrcquenchs); - } else if (type == ICMP_RD) { - MIB2_STATS_INC(mib2.icmpinredirects); - } else if (type == ICMP_TS) { - MIB2_STATS_INC(mib2.icmpintimestamps); - } else if (type == ICMP_TSR) { - MIB2_STATS_INC(mib2.icmpintimestampreps); - } else if (type == ICMP_AM) { - MIB2_STATS_INC(mib2.icmpinaddrmasks); - } else if (type == ICMP_AMR) { - MIB2_STATS_INC(mib2.icmpinaddrmaskreps); - } - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type %"S16_F" code %"S16_F" not supported.\n", - (s16_t)type, (s16_t)code)); - ICMP_STATS_INC(icmp.proterr); - ICMP_STATS_INC(icmp.drop); - } - pbuf_free(p); - return; -lenerr: - pbuf_free(p); - ICMP_STATS_INC(icmp.lenerr); - MIB2_STATS_INC(mib2.icmpinerrors); - return; -#if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN || !LWIP_MULTICAST_PING || !LWIP_BROADCAST_PING -icmperr: - pbuf_free(p); - ICMP_STATS_INC(icmp.err); - MIB2_STATS_INC(mib2.icmpinerrors); - return; -#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN || !LWIP_MULTICAST_PING || !LWIP_BROADCAST_PING */ -} - -/** - * Send an icmp 'destination unreachable' packet, called from ip_input() if - * the transport layer protocol is unknown and from udp_input() if the local - * port is not bound. - * - * @param p the input packet for which the 'unreachable' should be sent, - * p->payload pointing to the IP header - * @param t type of the 'unreachable' packet - */ -void -icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t) -{ - MIB2_STATS_INC(mib2.icmpoutdestunreachs); - icmp_send_response(p, ICMP_DUR, t); -} - -#if IP_FORWARD || IP_REASSEMBLY -/** - * Send a 'time exceeded' packet, called from ip_forward() if TTL is 0. - * - * @param p the input packet for which the 'time exceeded' should be sent, - * p->payload pointing to the IP header - * @param t type of the 'time exceeded' packet - */ -void -icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t) -{ - MIB2_STATS_INC(mib2.icmpouttimeexcds); - icmp_send_response(p, ICMP_TE, t); -} - -#endif /* IP_FORWARD || IP_REASSEMBLY */ - -/** - * Send an icmp packet in response to an incoming packet. - * - * @param p the input packet for which the 'unreachable' should be sent, - * p->payload pointing to the IP header - * @param type Type of the ICMP header - * @param code Code of the ICMP header - */ -static void -icmp_send_response(struct pbuf *p, u8_t type, u8_t code) -{ - struct pbuf *q; - struct ip_hdr *iphdr; - /* we can use the echo header here */ - struct icmp_echo_hdr *icmphdr; - ip4_addr_t iphdr_src; - struct netif *netif; - - /* increase number of messages attempted to send */ - MIB2_STATS_INC(mib2.icmpoutmsgs); - - /* ICMP header + IP header + 8 bytes of data */ - q = pbuf_alloc(PBUF_IP, sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE, - PBUF_RAM); - if (q == NULL) { - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded: failed to allocate pbuf for ICMP packet.\n")); - MIB2_STATS_INC(mib2.icmpouterrors); - return; - } - LWIP_ASSERT("check that first pbuf can hold icmp message", - (q->len >= (sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE))); - - iphdr = (struct ip_hdr *)p->payload; - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded from ")); - ip4_addr_debug_print_val(ICMP_DEBUG, iphdr->src); - LWIP_DEBUGF(ICMP_DEBUG, (" to ")); - ip4_addr_debug_print_val(ICMP_DEBUG, iphdr->dest); - LWIP_DEBUGF(ICMP_DEBUG, ("\n")); - - icmphdr = (struct icmp_echo_hdr *)q->payload; - icmphdr->type = type; - icmphdr->code = code; - icmphdr->id = 0; - icmphdr->seqno = 0; - - /* copy fields from original packet */ - SMEMCPY((u8_t *)q->payload + sizeof(struct icmp_echo_hdr), (u8_t *)p->payload, - IP_HLEN + ICMP_DEST_UNREACH_DATASIZE); - - ip4_addr_copy(iphdr_src, iphdr->src); -#ifdef LWIP_HOOK_IP4_ROUTE_SRC - { - ip4_addr_t iphdr_dst; - ip4_addr_copy(iphdr_dst, iphdr->dest); - netif = ip4_route_src(&iphdr_dst, &iphdr_src); - } -#else - netif = ip4_route(&iphdr_src); -#endif - if (netif != NULL) { - /* calculate checksum */ - icmphdr->chksum = 0; -#if CHECKSUM_GEN_ICMP - IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP) { - icmphdr->chksum = inet_chksum(icmphdr, q->len); - } -#endif - ICMP_STATS_INC(icmp.xmit); - ip4_output_if(q, NULL, &iphdr_src, ICMP_TTL, 0, IP_PROTO_ICMP, netif); - } - pbuf_free(q); -} - -#endif /* LWIP_IPV4 && LWIP_ICMP */ diff --git a/third-party/lwip-2.1.2/core/ipv4/igmp.c b/third-party/lwip-2.1.2/core/ipv4/igmp.c deleted file mode 100644 index b655aa3a..00000000 --- a/third-party/lwip-2.1.2/core/ipv4/igmp.c +++ /dev/null @@ -1,801 +0,0 @@ -/** - * @file - * IGMP - Internet Group Management Protocol - * - * @defgroup igmp IGMP - * @ingroup ip4 - * To be called from TCPIP thread - */ - -/* - * Copyright (c) 2002 CITEL Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of CITEL Technologies Ltd nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY CITEL TECHNOLOGIES AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL CITEL TECHNOLOGIES OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is a contribution to the lwIP TCP/IP stack. - * The Swedish Institute of Computer Science and Adam Dunkels - * are specifically granted permission to redistribute this - * source code. -*/ - -/*------------------------------------------------------------- -Note 1) -Although the rfc requires V1 AND V2 capability -we will only support v2 since now V1 is very old (August 1989) -V1 can be added if required - -a debug print and statistic have been implemented to -show this up. -------------------------------------------------------------- -------------------------------------------------------------- -Note 2) -A query for a specific group address (as opposed to ALLHOSTS) -has now been implemented as I am unsure if it is required - -a debug print and statistic have been implemented to -show this up. -------------------------------------------------------------- -------------------------------------------------------------- -Note 3) -The router alert rfc 2113 is implemented in outgoing packets -but not checked rigorously incoming -------------------------------------------------------------- -Steve Reynolds -------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------- - * RFC 988 - Host extensions for IP multicasting - V0 - * RFC 1054 - Host extensions for IP multicasting - - * RFC 1112 - Host extensions for IP multicasting - V1 - * RFC 2236 - Internet Group Management Protocol, Version 2 - V2 <- this code is based on this RFC (it's the "de facto" standard) - * RFC 3376 - Internet Group Management Protocol, Version 3 - V3 - * RFC 4604 - Using Internet Group Management Protocol Version 3... - V3+ - * RFC 2113 - IP Router Alert Option - - *----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------- - * Includes - *----------------------------------------------------------------------------*/ - -#include "lwip/opt.h" - -#if LWIP_IPV4 && LWIP_IGMP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/igmp.h" -#include "lwip/debug.h" -#include "lwip/def.h" -#include "lwip/mem.h" -#include "lwip/ip.h" -#include "lwip/inet_chksum.h" -#include "lwip/netif.h" -#include "lwip/stats.h" -#include "lwip/prot/igmp.h" - -#include - -static struct igmp_group *igmp_lookup_group(struct netif *ifp, const ip4_addr_t *addr); -static err_t igmp_remove_group(struct netif *netif, struct igmp_group *group); -static void igmp_timeout(struct netif *netif, struct igmp_group *group); -static void igmp_start_timer(struct igmp_group *group, u8_t max_time); -static void igmp_delaying_member(struct igmp_group *group, u8_t maxresp); -static err_t igmp_ip_output_if(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, struct netif *netif); -static void igmp_send(struct netif *netif, struct igmp_group *group, u8_t type); - -static ip4_addr_t allsystems; -static ip4_addr_t allrouters; - -/** - * Initialize the IGMP module - */ -void -igmp_init(void) -{ - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_init: initializing\n")); - - IP4_ADDR(&allsystems, 224, 0, 0, 1); - IP4_ADDR(&allrouters, 224, 0, 0, 2); -} - -/** - * Start IGMP processing on interface - * - * @param netif network interface on which start IGMP processing - */ -err_t -igmp_start(struct netif *netif) -{ - struct igmp_group *group; - - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_start: starting IGMP processing on if %p\n", (void *)netif)); - - group = igmp_lookup_group(netif, &allsystems); - - if (group != NULL) { - group->group_state = IGMP_GROUP_IDLE_MEMBER; - group->use++; - - /* Allow the igmp messages at the MAC level */ - if (netif->igmp_mac_filter != NULL) { - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_start: igmp_mac_filter(ADD ")); - ip4_addr_debug_print_val(IGMP_DEBUG, allsystems); - LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", (void *)netif)); - netif->igmp_mac_filter(netif, &allsystems, NETIF_ADD_MAC_FILTER); - } - - return ERR_OK; - } - - return ERR_MEM; -} - -/** - * Stop IGMP processing on interface - * - * @param netif network interface on which stop IGMP processing - */ -err_t -igmp_stop(struct netif *netif) -{ - struct igmp_group *group = netif_igmp_data(netif); - - netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_IGMP, NULL); - - while (group != NULL) { - struct igmp_group *next = group->next; /* avoid use-after-free below */ - - /* disable the group at the MAC level */ - if (netif->igmp_mac_filter != NULL) { - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_stop: igmp_mac_filter(DEL ")); - ip4_addr_debug_print_val(IGMP_DEBUG, group->group_address); - LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", (void *)netif)); - netif->igmp_mac_filter(netif, &(group->group_address), NETIF_DEL_MAC_FILTER); - } - - /* free group */ - memp_free(MEMP_IGMP_GROUP, group); - - /* move to "next" */ - group = next; - } - return ERR_OK; -} - -/** - * Report IGMP memberships for this interface - * - * @param netif network interface on which report IGMP memberships - */ -void -igmp_report_groups(struct netif *netif) -{ - struct igmp_group *group = netif_igmp_data(netif); - - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_report_groups: sending IGMP reports on if %p\n", (void *)netif)); - - /* Skip the first group in the list, it is always the allsystems group added in igmp_start() */ - if (group != NULL) { - group = group->next; - } - - while (group != NULL) { - igmp_delaying_member(group, IGMP_JOIN_DELAYING_MEMBER_TMR); - group = group->next; - } -} - -/** - * Search for a group in the netif's igmp group list - * - * @param ifp the network interface for which to look - * @param addr the group ip address to search for - * @return a struct igmp_group* if the group has been found, - * NULL if the group wasn't found. - */ -struct igmp_group * -igmp_lookfor_group(struct netif *ifp, const ip4_addr_t *addr) -{ - struct igmp_group *group = netif_igmp_data(ifp); - - while (group != NULL) { - if (ip4_addr_cmp(&(group->group_address), addr)) { - return group; - } - group = group->next; - } - - /* to be clearer, we return NULL here instead of - * 'group' (which is also NULL at this point). - */ - return NULL; -} - -/** - * Search for a specific igmp group and create a new one if not found- - * - * @param ifp the network interface for which to look - * @param addr the group ip address to search - * @return a struct igmp_group*, - * NULL on memory error. - */ -static struct igmp_group * -igmp_lookup_group(struct netif *ifp, const ip4_addr_t *addr) -{ - struct igmp_group *group; - struct igmp_group *list_head = netif_igmp_data(ifp); - - /* Search if the group already exists */ - group = igmp_lookfor_group(ifp, addr); - if (group != NULL) { - /* Group already exists. */ - return group; - } - - /* Group doesn't exist yet, create a new one */ - group = (struct igmp_group *)memp_malloc(MEMP_IGMP_GROUP); - if (group != NULL) { - ip4_addr_set(&(group->group_address), addr); - group->timer = 0; /* Not running */ - group->group_state = IGMP_GROUP_NON_MEMBER; - group->last_reporter_flag = 0; - group->use = 0; - - /* Ensure allsystems group is always first in list */ - if (list_head == NULL) { - /* this is the first entry in linked list */ - LWIP_ASSERT("igmp_lookup_group: first group must be allsystems", - (ip4_addr_cmp(addr, &allsystems) != 0)); - group->next = NULL; - netif_set_client_data(ifp, LWIP_NETIF_CLIENT_DATA_INDEX_IGMP, group); - } else { - /* append _after_ first entry */ - LWIP_ASSERT("igmp_lookup_group: all except first group must not be allsystems", - (ip4_addr_cmp(addr, &allsystems) == 0)); - group->next = list_head->next; - list_head->next = group; - } - } - - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_lookup_group: %sallocated a new group with address ", (group ? "" : "impossible to "))); - ip4_addr_debug_print(IGMP_DEBUG, addr); - LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", (void *)ifp)); - - return group; -} - -/** - * Remove a group from netif's igmp group list, but don't free it yet - * - * @param group the group to remove from the netif's igmp group list - * @return ERR_OK if group was removed from the list, an err_t otherwise - */ -static err_t -igmp_remove_group(struct netif *netif, struct igmp_group *group) -{ - err_t err = ERR_OK; - struct igmp_group *tmp_group; - - /* Skip the first group in the list, it is always the allsystems group added in igmp_start() */ - for (tmp_group = netif_igmp_data(netif); tmp_group != NULL; tmp_group = tmp_group->next) { - if (tmp_group->next == group) { - tmp_group->next = group->next; - break; - } - } - /* Group not found in netif's igmp group list */ - if (tmp_group == NULL) { - err = ERR_ARG; - } - - return err; -} - -/** - * Called from ip_input() if a new IGMP packet is received. - * - * @param p received igmp packet, p->payload pointing to the igmp header - * @param inp network interface on which the packet was received - * @param dest destination ip address of the igmp packet - */ -void -igmp_input(struct pbuf *p, struct netif *inp, const ip4_addr_t *dest) -{ - struct igmp_msg *igmp; - struct igmp_group *group; - struct igmp_group *groupref; - - IGMP_STATS_INC(igmp.recv); - - /* Note that the length CAN be greater than 8 but only 8 are used - All are included in the checksum */ - if (p->len < IGMP_MINLEN) { - pbuf_free(p); - IGMP_STATS_INC(igmp.lenerr); - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: length error\n")); - return; - } - - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: message from ")); - ip4_addr_debug_print_val(IGMP_DEBUG, ip4_current_header()->src); - LWIP_DEBUGF(IGMP_DEBUG, (" to address ")); - ip4_addr_debug_print_val(IGMP_DEBUG, ip4_current_header()->dest); - LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", (void *)inp)); - - /* Now calculate and check the checksum */ - igmp = (struct igmp_msg *)p->payload; - if (inet_chksum(igmp, p->len)) { - pbuf_free(p); - IGMP_STATS_INC(igmp.chkerr); - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: checksum error\n")); - return; - } - - /* Packet is ok so find an existing group */ - group = igmp_lookfor_group(inp, dest); /* use the destination IP address of incoming packet */ - - /* If group can be found or create... */ - if (!group) { - pbuf_free(p); - IGMP_STATS_INC(igmp.drop); - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP frame not for us\n")); - return; - } - - /* NOW ACT ON THE INCOMING MESSAGE TYPE... */ - switch (igmp->igmp_msgtype) { - case IGMP_MEMB_QUERY: - /* IGMP_MEMB_QUERY to the "all systems" address ? */ - if ((ip4_addr_cmp(dest, &allsystems)) && ip4_addr_isany(&igmp->igmp_group_address)) { - /* THIS IS THE GENERAL QUERY */ - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: General IGMP_MEMB_QUERY on \"ALL SYSTEMS\" address (224.0.0.1) [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp))); - - if (igmp->igmp_maxresp == 0) { - IGMP_STATS_INC(igmp.rx_v1); - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: got an all hosts query with time== 0 - this is V1 and not implemented - treat as v2\n")); - igmp->igmp_maxresp = IGMP_V1_DELAYING_MEMBER_TMR; - } else { - IGMP_STATS_INC(igmp.rx_general); - } - - groupref = netif_igmp_data(inp); - - /* Do not send messages on the all systems group address! */ - /* Skip the first group in the list, it is always the allsystems group added in igmp_start() */ - if (groupref != NULL) { - groupref = groupref->next; - } - - while (groupref) { - igmp_delaying_member(groupref, igmp->igmp_maxresp); - groupref = groupref->next; - } - } else { - /* IGMP_MEMB_QUERY to a specific group ? */ - if (!ip4_addr_isany(&igmp->igmp_group_address)) { - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP_MEMB_QUERY to a specific group ")); - ip4_addr_debug_print_val(IGMP_DEBUG, igmp->igmp_group_address); - if (ip4_addr_cmp(dest, &allsystems)) { - ip4_addr_t groupaddr; - LWIP_DEBUGF(IGMP_DEBUG, (" using \"ALL SYSTEMS\" address (224.0.0.1) [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp))); - /* we first need to re-look for the group since we used dest last time */ - ip4_addr_copy(groupaddr, igmp->igmp_group_address); - group = igmp_lookfor_group(inp, &groupaddr); - } else { - LWIP_DEBUGF(IGMP_DEBUG, (" with the group address as destination [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp))); - } - - if (group != NULL) { - IGMP_STATS_INC(igmp.rx_group); - igmp_delaying_member(group, igmp->igmp_maxresp); - } else { - IGMP_STATS_INC(igmp.drop); - } - } else { - IGMP_STATS_INC(igmp.proterr); - } - } - break; - case IGMP_V2_MEMB_REPORT: - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP_V2_MEMB_REPORT\n")); - IGMP_STATS_INC(igmp.rx_report); - if (group->group_state == IGMP_GROUP_DELAYING_MEMBER) { - /* This is on a specific group we have already looked up */ - group->timer = 0; /* stopped */ - group->group_state = IGMP_GROUP_IDLE_MEMBER; - group->last_reporter_flag = 0; - } - break; - default: - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: unexpected msg %d in state %d on group %p on if %p\n", - igmp->igmp_msgtype, group->group_state, (void *)&group, (void *)inp)); - IGMP_STATS_INC(igmp.proterr); - break; - } - - pbuf_free(p); - return; -} - -/** - * @ingroup igmp - * Join a group on one network interface. - * - * @param ifaddr ip address of the network interface which should join a new group - * @param groupaddr the ip address of the group which to join - * @return ERR_OK if group was joined on the netif(s), an err_t otherwise - */ -err_t -igmp_joingroup(const ip4_addr_t *ifaddr, const ip4_addr_t *groupaddr) -{ - err_t err = ERR_VAL; /* no matching interface */ - struct netif *netif; - - LWIP_ASSERT_CORE_LOCKED(); - - /* make sure it is multicast address */ - LWIP_ERROR("igmp_joingroup: attempt to join non-multicast address", ip4_addr_ismulticast(groupaddr), return ERR_VAL;); - LWIP_ERROR("igmp_joingroup: attempt to join allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;); - - /* loop through netif's */ - NETIF_FOREACH(netif) { - /* Should we join this interface ? */ - if ((netif->flags & NETIF_FLAG_IGMP) && ((ip4_addr_isany(ifaddr) || ip4_addr_cmp(netif_ip4_addr(netif), ifaddr)))) { - err = igmp_joingroup_netif(netif, groupaddr); - if (err != ERR_OK) { - /* Return an error even if some network interfaces are joined */ - /** @todo undo any other netif already joined */ - return err; - } - } - } - - return err; -} - -/** - * @ingroup igmp - * Join a group on one network interface. - * - * @param netif the network interface which should join a new group - * @param groupaddr the ip address of the group which to join - * @return ERR_OK if group was joined on the netif, an err_t otherwise - */ -err_t -igmp_joingroup_netif(struct netif *netif, const ip4_addr_t *groupaddr) -{ - struct igmp_group *group; - - LWIP_ASSERT_CORE_LOCKED(); - - /* make sure it is multicast address */ - LWIP_ERROR("igmp_joingroup_netif: attempt to join non-multicast address", ip4_addr_ismulticast(groupaddr), return ERR_VAL;); - LWIP_ERROR("igmp_joingroup_netif: attempt to join allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;); - - /* make sure it is an igmp-enabled netif */ - LWIP_ERROR("igmp_joingroup_netif: attempt to join on non-IGMP netif", netif->flags & NETIF_FLAG_IGMP, return ERR_VAL;); - - /* find group or create a new one if not found */ - group = igmp_lookup_group(netif, groupaddr); - - if (group != NULL) { - /* This should create a new group, check the state to make sure */ - if (group->group_state != IGMP_GROUP_NON_MEMBER) { - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup_netif: join to group not in state IGMP_GROUP_NON_MEMBER\n")); - } else { - /* OK - it was new group */ - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup_netif: join to new group: ")); - ip4_addr_debug_print(IGMP_DEBUG, groupaddr); - LWIP_DEBUGF(IGMP_DEBUG, ("\n")); - - /* If first use of the group, allow the group at the MAC level */ - if ((group->use == 0) && (netif->igmp_mac_filter != NULL)) { - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup_netif: igmp_mac_filter(ADD ")); - ip4_addr_debug_print(IGMP_DEBUG, groupaddr); - LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", (void *)netif)); - netif->igmp_mac_filter(netif, groupaddr, NETIF_ADD_MAC_FILTER); - } - - IGMP_STATS_INC(igmp.tx_join); - igmp_send(netif, group, IGMP_V2_MEMB_REPORT); - - igmp_start_timer(group, IGMP_JOIN_DELAYING_MEMBER_TMR); - - /* Need to work out where this timer comes from */ - group->group_state = IGMP_GROUP_DELAYING_MEMBER; - } - /* Increment group use */ - group->use++; - /* Join on this interface */ - return ERR_OK; - } else { - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup_netif: Not enough memory to join to group\n")); - return ERR_MEM; - } -} - -/** - * @ingroup igmp - * Leave a group on one network interface. - * - * @param ifaddr ip address of the network interface which should leave a group - * @param groupaddr the ip address of the group which to leave - * @return ERR_OK if group was left on the netif(s), an err_t otherwise - */ -err_t -igmp_leavegroup(const ip4_addr_t *ifaddr, const ip4_addr_t *groupaddr) -{ - err_t err = ERR_VAL; /* no matching interface */ - struct netif *netif; - - LWIP_ASSERT_CORE_LOCKED(); - - /* make sure it is multicast address */ - LWIP_ERROR("igmp_leavegroup: attempt to leave non-multicast address", ip4_addr_ismulticast(groupaddr), return ERR_VAL;); - LWIP_ERROR("igmp_leavegroup: attempt to leave allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;); - - /* loop through netif's */ - NETIF_FOREACH(netif) { - /* Should we leave this interface ? */ - if ((netif->flags & NETIF_FLAG_IGMP) && ((ip4_addr_isany(ifaddr) || ip4_addr_cmp(netif_ip4_addr(netif), ifaddr)))) { - err_t res = igmp_leavegroup_netif(netif, groupaddr); - if (err != ERR_OK) { - /* Store this result if we have not yet gotten a success */ - err = res; - } - } - } - - return err; -} - -/** - * @ingroup igmp - * Leave a group on one network interface. - * - * @param netif the network interface which should leave a group - * @param groupaddr the ip address of the group which to leave - * @return ERR_OK if group was left on the netif, an err_t otherwise - */ -err_t -igmp_leavegroup_netif(struct netif *netif, const ip4_addr_t *groupaddr) -{ - struct igmp_group *group; - - LWIP_ASSERT_CORE_LOCKED(); - - /* make sure it is multicast address */ - LWIP_ERROR("igmp_leavegroup_netif: attempt to leave non-multicast address", ip4_addr_ismulticast(groupaddr), return ERR_VAL;); - LWIP_ERROR("igmp_leavegroup_netif: attempt to leave allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;); - - /* make sure it is an igmp-enabled netif */ - LWIP_ERROR("igmp_leavegroup_netif: attempt to leave on non-IGMP netif", netif->flags & NETIF_FLAG_IGMP, return ERR_VAL;); - - /* find group */ - group = igmp_lookfor_group(netif, groupaddr); - - if (group != NULL) { - /* Only send a leave if the flag is set according to the state diagram */ - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup_netif: Leaving group: ")); - ip4_addr_debug_print(IGMP_DEBUG, groupaddr); - LWIP_DEBUGF(IGMP_DEBUG, ("\n")); - - /* If there is no other use of the group */ - if (group->use <= 1) { - /* Remove the group from the list */ - igmp_remove_group(netif, group); - - /* If we are the last reporter for this group */ - if (group->last_reporter_flag) { - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup_netif: sending leaving group\n")); - IGMP_STATS_INC(igmp.tx_leave); - igmp_send(netif, group, IGMP_LEAVE_GROUP); - } - - /* Disable the group at the MAC level */ - if (netif->igmp_mac_filter != NULL) { - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup_netif: igmp_mac_filter(DEL ")); - ip4_addr_debug_print(IGMP_DEBUG, groupaddr); - LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", (void *)netif)); - netif->igmp_mac_filter(netif, groupaddr, NETIF_DEL_MAC_FILTER); - } - - /* Free group struct */ - memp_free(MEMP_IGMP_GROUP, group); - } else { - /* Decrement group use */ - group->use--; - } - return ERR_OK; - } else { - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup_netif: not member of group\n")); - return ERR_VAL; - } -} - -/** - * The igmp timer function (both for NO_SYS=1 and =0) - * Should be called every IGMP_TMR_INTERVAL milliseconds (100 ms is default). - */ -void -igmp_tmr(void) -{ - struct netif *netif; - - NETIF_FOREACH(netif) { - struct igmp_group *group = netif_igmp_data(netif); - - while (group != NULL) { - if (group->timer > 0) { - group->timer--; - if (group->timer == 0) { - igmp_timeout(netif, group); - } - } - group = group->next; - } - } -} - -/** - * Called if a timeout for one group is reached. - * Sends a report for this group. - * - * @param group an igmp_group for which a timeout is reached - */ -static void -igmp_timeout(struct netif *netif, struct igmp_group *group) -{ - /* If the state is IGMP_GROUP_DELAYING_MEMBER then we send a report for this group - (unless it is the allsystems group) */ - if ((group->group_state == IGMP_GROUP_DELAYING_MEMBER) && - (!(ip4_addr_cmp(&(group->group_address), &allsystems)))) { - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_timeout: report membership for group with address ")); - ip4_addr_debug_print_val(IGMP_DEBUG, group->group_address); - LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", (void *)netif)); - - group->group_state = IGMP_GROUP_IDLE_MEMBER; - - IGMP_STATS_INC(igmp.tx_report); - igmp_send(netif, group, IGMP_V2_MEMB_REPORT); - } -} - -/** - * Start a timer for an igmp group - * - * @param group the igmp_group for which to start a timer - * @param max_time the time in multiples of IGMP_TMR_INTERVAL (decrease with - * every call to igmp_tmr()) - */ -static void -igmp_start_timer(struct igmp_group *group, u8_t max_time) -{ -#ifdef LWIP_RAND - group->timer = (u16_t)(max_time > 2 ? (LWIP_RAND() % max_time) : 1); -#else /* LWIP_RAND */ - /* ATTENTION: use this only if absolutely necessary! */ - group->timer = max_time / 2; -#endif /* LWIP_RAND */ - - if (group->timer == 0) { - group->timer = 1; - } -} - -/** - * Delaying membership report for a group if necessary - * - * @param group the igmp_group for which "delaying" membership report - * @param maxresp query delay - */ -static void -igmp_delaying_member(struct igmp_group *group, u8_t maxresp) -{ - if ((group->group_state == IGMP_GROUP_IDLE_MEMBER) || - ((group->group_state == IGMP_GROUP_DELAYING_MEMBER) && - ((group->timer == 0) || (maxresp < group->timer)))) { - igmp_start_timer(group, maxresp); - group->group_state = IGMP_GROUP_DELAYING_MEMBER; - } -} - - -/** - * Sends an IP packet on a network interface. This function constructs the IP header - * and calculates the IP header checksum. If the source IP address is NULL, - * the IP address of the outgoing network interface is filled in as source address. - * - * @param p the packet to send (p->payload points to the data, e.g. next - protocol header; if dest == LWIP_IP_HDRINCL, p already includes an - IP header and p->payload points to that IP header) - * @param src the source IP address to send from (if src == IP4_ADDR_ANY, the - * IP address of the netif used to send is used as source address) - * @param dest the destination IP address to send the packet to - * @param netif the netif on which to send this packet - * @return ERR_OK if the packet was sent OK - * ERR_BUF if p doesn't have enough space for IP/LINK headers - * returns errors returned by netif->output - */ -static err_t -igmp_ip_output_if(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, struct netif *netif) -{ - /* This is the "router alert" option */ - u16_t ra[2]; - ra[0] = PP_HTONS(ROUTER_ALERT); - ra[1] = 0x0000; /* Router shall examine packet */ - IGMP_STATS_INC(igmp.xmit); - return ip4_output_if_opt(p, src, dest, IGMP_TTL, 0, IP_PROTO_IGMP, netif, ra, ROUTER_ALERTLEN); -} - -/** - * Send an igmp packet to a specific group. - * - * @param group the group to which to send the packet - * @param type the type of igmp packet to send - */ -static void -igmp_send(struct netif *netif, struct igmp_group *group, u8_t type) -{ - struct pbuf *p = NULL; - struct igmp_msg *igmp = NULL; - ip4_addr_t src = *IP4_ADDR_ANY4; - ip4_addr_t *dest = NULL; - - /* IP header + "router alert" option + IGMP header */ - p = pbuf_alloc(PBUF_TRANSPORT, IGMP_MINLEN, PBUF_RAM); - - if (p) { - igmp = (struct igmp_msg *)p->payload; - LWIP_ASSERT("igmp_send: check that first pbuf can hold struct igmp_msg", - (p->len >= sizeof(struct igmp_msg))); - ip4_addr_copy(src, *netif_ip4_addr(netif)); - - if (type == IGMP_V2_MEMB_REPORT) { - dest = &(group->group_address); - ip4_addr_copy(igmp->igmp_group_address, group->group_address); - group->last_reporter_flag = 1; /* Remember we were the last to report */ - } else { - if (type == IGMP_LEAVE_GROUP) { - dest = &allrouters; - ip4_addr_copy(igmp->igmp_group_address, group->group_address); - } - } - - if ((type == IGMP_V2_MEMB_REPORT) || (type == IGMP_LEAVE_GROUP)) { - igmp->igmp_msgtype = type; - igmp->igmp_maxresp = 0; - igmp->igmp_checksum = 0; - igmp->igmp_checksum = inet_chksum(igmp, IGMP_MINLEN); - - igmp_ip_output_if(p, &src, dest, netif); - } - - pbuf_free(p); - } else { - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_send: not enough memory for igmp_send\n")); - IGMP_STATS_INC(igmp.memerr); - } -} - -#endif /* LWIP_IPV4 && LWIP_IGMP */ diff --git a/third-party/lwip-2.1.2/core/ipv4/ip4.c b/third-party/lwip-2.1.2/core/ipv4/ip4.c deleted file mode 100644 index 26c26a91..00000000 --- a/third-party/lwip-2.1.2/core/ipv4/ip4.c +++ /dev/null @@ -1,1132 +0,0 @@ -/** - * @file - * This is the IPv4 layer implementation for incoming and outgoing IP traffic. - * - * @see ip_frag.c - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#include "lwip/opt.h" - -#if LWIP_IPV4 - -#include "lwip/ip.h" -#include "lwip/def.h" -#include "lwip/mem.h" -#include "lwip/ip4_frag.h" -#include "lwip/inet_chksum.h" -#include "lwip/netif.h" -#include "lwip/icmp.h" -#include "lwip/igmp.h" -#include "lwip/priv/raw_priv.h" -#include "lwip/udp.h" -#include "lwip/priv/tcp_priv.h" -#include "lwip/autoip.h" -#include "lwip/stats.h" -#include "lwip/prot/iana.h" - -#include - -#ifdef LWIP_HOOK_FILENAME -#include LWIP_HOOK_FILENAME -#endif - -/** Set this to 0 in the rare case of wanting to call an extra function to - * generate the IP checksum (in contrast to calculating it on-the-fly). */ -#ifndef LWIP_INLINE_IP_CHKSUM -#if LWIP_CHECKSUM_CTRL_PER_NETIF -#define LWIP_INLINE_IP_CHKSUM 0 -#else /* LWIP_CHECKSUM_CTRL_PER_NETIF */ -#define LWIP_INLINE_IP_CHKSUM 1 -#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */ -#endif - -#if LWIP_INLINE_IP_CHKSUM && CHECKSUM_GEN_IP -#define CHECKSUM_GEN_IP_INLINE 1 -#else -#define CHECKSUM_GEN_IP_INLINE 0 -#endif - -#if LWIP_DHCP || defined(LWIP_IP_ACCEPT_UDP_PORT) -#define IP_ACCEPT_LINK_LAYER_ADDRESSING 1 - -/** Some defines for DHCP to let link-layer-addressed packets through while the - * netif is down. - * To use this in your own application/protocol, define LWIP_IP_ACCEPT_UDP_PORT(port) - * to return 1 if the port is accepted and 0 if the port is not accepted. - */ -#if LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) -/* accept DHCP client port and custom port */ -#define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) (((port) == PP_NTOHS(LWIP_IANA_PORT_DHCP_CLIENT)) \ - || (LWIP_IP_ACCEPT_UDP_PORT(port))) -#elif defined(LWIP_IP_ACCEPT_UDP_PORT) /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */ -/* accept custom port only */ -#define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) (LWIP_IP_ACCEPT_UDP_PORT(port)) -#else /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */ -/* accept DHCP client port only */ -#define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) ((port) == PP_NTOHS(LWIP_IANA_PORT_DHCP_CLIENT)) -#endif /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */ - -#else /* LWIP_DHCP */ -#define IP_ACCEPT_LINK_LAYER_ADDRESSING 0 -#endif /* LWIP_DHCP */ - -/** The IP header ID of the next outgoing IP packet */ -static u16_t ip_id; - -#if LWIP_MULTICAST_TX_OPTIONS -/** The default netif used for multicast */ -static struct netif *ip4_default_multicast_netif; - -/** - * @ingroup ip4 - * Set a default netif for IPv4 multicast. */ -void -ip4_set_default_multicast_netif(struct netif *default_multicast_netif) -{ - ip4_default_multicast_netif = default_multicast_netif; -} -#endif /* LWIP_MULTICAST_TX_OPTIONS */ - -#ifdef LWIP_HOOK_IP4_ROUTE_SRC -/** - * Source based IPv4 routing must be fully implemented in - * LWIP_HOOK_IP4_ROUTE_SRC(). This function only provides the parameters. - */ -struct netif * -ip4_route_src(const ip4_addr_t *src, const ip4_addr_t *dest) -{ - if (src != NULL) { - /* when src==NULL, the hook is called from ip4_route(dest) */ - struct netif *netif = LWIP_HOOK_IP4_ROUTE_SRC(src, dest); - if (netif != NULL) { - return netif; - } - } - return ip4_route(dest); -} -#endif /* LWIP_HOOK_IP4_ROUTE_SRC */ - -/** - * Finds the appropriate network interface for a given IP address. It - * searches the list of network interfaces linearly. A match is found - * if the masked IP address of the network interface equals the masked - * IP address given to the function. - * - * @param dest the destination IP address for which to find the route - * @return the netif on which to send to reach dest - */ -struct netif * -ip4_route(const ip4_addr_t *dest) -{ -#if !LWIP_SINGLE_NETIF - struct netif *netif; - - LWIP_ASSERT_CORE_LOCKED(); - -#if LWIP_MULTICAST_TX_OPTIONS - /* Use administratively selected interface for multicast by default */ - if (ip4_addr_ismulticast(dest) && ip4_default_multicast_netif) { - return ip4_default_multicast_netif; - } -#endif /* LWIP_MULTICAST_TX_OPTIONS */ - - /* bug #54569: in case LWIP_SINGLE_NETIF=1 and LWIP_DEBUGF() disabled, the following loop is optimized away */ - LWIP_UNUSED_ARG(dest); - - /* iterate through netifs */ - NETIF_FOREACH(netif) { - /* is the netif up, does it have a link and a valid address? */ - if (netif_is_up(netif) && netif_is_link_up(netif) && !ip4_addr_isany_val(*netif_ip4_addr(netif))) { - /* network mask matches? */ - if (ip4_addr_netcmp(dest, netif_ip4_addr(netif), netif_ip4_netmask(netif))) { - /* return netif on which to forward IP packet */ - return netif; - } - /* gateway matches on a non broadcast interface? (i.e. peer in a point to point interface) */ - if (((netif->flags & NETIF_FLAG_BROADCAST) == 0) && ip4_addr_cmp(dest, netif_ip4_gw(netif))) { - /* return netif on which to forward IP packet */ - return netif; - } - } - } - -#if LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF - /* loopif is disabled, looopback traffic is passed through any netif */ - if (ip4_addr_isloopback(dest)) { - /* don't check for link on loopback traffic */ - if (netif_default != NULL && netif_is_up(netif_default)) { - return netif_default; - } - /* default netif is not up, just use any netif for loopback traffic */ - NETIF_FOREACH(netif) { - if (netif_is_up(netif)) { - return netif; - } - } - return NULL; - } -#endif /* LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF */ - -#ifdef LWIP_HOOK_IP4_ROUTE_SRC - netif = LWIP_HOOK_IP4_ROUTE_SRC(NULL, dest); - if (netif != NULL) { - return netif; - } -#elif defined(LWIP_HOOK_IP4_ROUTE) - netif = LWIP_HOOK_IP4_ROUTE(dest); - if (netif != NULL) { - return netif; - } -#endif -#endif /* !LWIP_SINGLE_NETIF */ - - if ((netif_default == NULL) || !netif_is_up(netif_default) || !netif_is_link_up(netif_default) || - ip4_addr_isany_val(*netif_ip4_addr(netif_default)) || ip4_addr_isloopback(dest)) { - /* No matching netif found and default netif is not usable. - If this is not good enough for you, use LWIP_HOOK_IP4_ROUTE() */ - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip4_route: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); - IP_STATS_INC(ip.rterr); - MIB2_STATS_INC(mib2.ipoutnoroutes); - return NULL; - } - - return netif_default; -} - -#if IP_FORWARD -/** - * Determine whether an IP address is in a reserved set of addresses - * that may not be forwarded, or whether datagrams to that destination - * may be forwarded. - * @param p the packet to forward - * @return 1: can forward 0: discard - */ -static int -ip4_canforward(struct pbuf *p) -{ - u32_t addr = lwip_htonl(ip4_addr_get_u32(ip4_current_dest_addr())); - -#ifdef LWIP_HOOK_IP4_CANFORWARD - int ret = LWIP_HOOK_IP4_CANFORWARD(p, addr); - if (ret >= 0) { - return ret; - } -#endif /* LWIP_HOOK_IP4_CANFORWARD */ - - if (p->flags & PBUF_FLAG_LLBCAST) { - /* don't route link-layer broadcasts */ - return 0; - } - if ((p->flags & PBUF_FLAG_LLMCAST) || IP_MULTICAST(addr)) { - /* don't route link-layer multicasts (use LWIP_HOOK_IP4_CANFORWARD instead) */ - return 0; - } - if (IP_EXPERIMENTAL(addr)) { - return 0; - } - if (IP_CLASSA(addr)) { - u32_t net = addr & IP_CLASSA_NET; - if ((net == 0) || (net == ((u32_t)IP_LOOPBACKNET << IP_CLASSA_NSHIFT))) { - /* don't route loopback packets */ - return 0; - } - } - return 1; -} - -/** - * Forwards an IP packet. It finds an appropriate route for the - * packet, decrements the TTL value of the packet, adjusts the - * checksum and outputs the packet on the appropriate interface. - * - * @param p the packet to forward (p->payload points to IP header) - * @param iphdr the IP header of the input packet - * @param inp the netif on which this packet was received - */ -static void -ip4_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp) -{ - struct netif *netif; - - PERF_START; - LWIP_UNUSED_ARG(inp); - - if (!ip4_canforward(p)) { - goto return_noroute; - } - - /* RFC3927 2.7: do not forward link-local addresses */ - if (ip4_addr_islinklocal(ip4_current_dest_addr())) { - LWIP_DEBUGF(IP_DEBUG, ("ip4_forward: not forwarding LLA %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - ip4_addr1_16(ip4_current_dest_addr()), ip4_addr2_16(ip4_current_dest_addr()), - ip4_addr3_16(ip4_current_dest_addr()), ip4_addr4_16(ip4_current_dest_addr()))); - goto return_noroute; - } - - /* Find network interface where to forward this IP packet to. */ - netif = ip4_route_src(ip4_current_src_addr(), ip4_current_dest_addr()); - if (netif == NULL) { - LWIP_DEBUGF(IP_DEBUG, ("ip4_forward: no forwarding route for %"U16_F".%"U16_F".%"U16_F".%"U16_F" found\n", - ip4_addr1_16(ip4_current_dest_addr()), ip4_addr2_16(ip4_current_dest_addr()), - ip4_addr3_16(ip4_current_dest_addr()), ip4_addr4_16(ip4_current_dest_addr()))); - /* @todo: send ICMP_DUR_NET? */ - goto return_noroute; - } -#if !IP_FORWARD_ALLOW_TX_ON_RX_NETIF - /* Do not forward packets onto the same network interface on which - * they arrived. */ - if (netif == inp) { - LWIP_DEBUGF(IP_DEBUG, ("ip4_forward: not bouncing packets back on incoming interface.\n")); - goto return_noroute; - } -#endif /* IP_FORWARD_ALLOW_TX_ON_RX_NETIF */ - - /* decrement TTL */ - IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1); - /* send ICMP if TTL == 0 */ - if (IPH_TTL(iphdr) == 0) { - MIB2_STATS_INC(mib2.ipinhdrerrors); -#if LWIP_ICMP - /* Don't send ICMP messages in response to ICMP messages */ - if (IPH_PROTO(iphdr) != IP_PROTO_ICMP) { - icmp_time_exceeded(p, ICMP_TE_TTL); - } -#endif /* LWIP_ICMP */ - return; - } - - /* Incrementally update the IP checksum. */ - if (IPH_CHKSUM(iphdr) >= PP_HTONS(0xffffU - 0x100)) { - IPH_CHKSUM_SET(iphdr, (u16_t)(IPH_CHKSUM(iphdr) + PP_HTONS(0x100) + 1)); - } else { - IPH_CHKSUM_SET(iphdr, (u16_t)(IPH_CHKSUM(iphdr) + PP_HTONS(0x100))); - } - - LWIP_DEBUGF(IP_DEBUG, ("ip4_forward: forwarding packet to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - ip4_addr1_16(ip4_current_dest_addr()), ip4_addr2_16(ip4_current_dest_addr()), - ip4_addr3_16(ip4_current_dest_addr()), ip4_addr4_16(ip4_current_dest_addr()))); - - IP_STATS_INC(ip.fw); - MIB2_STATS_INC(mib2.ipforwdatagrams); - IP_STATS_INC(ip.xmit); - - PERF_STOP("ip4_forward"); - /* don't fragment if interface has mtu set to 0 [loopif] */ - if (netif->mtu && (p->tot_len > netif->mtu)) { - if ((IPH_OFFSET(iphdr) & PP_NTOHS(IP_DF)) == 0) { -#if IP_FRAG - ip4_frag(p, netif, ip4_current_dest_addr()); -#else /* IP_FRAG */ - /* @todo: send ICMP Destination Unreachable code 13 "Communication administratively prohibited"? */ -#endif /* IP_FRAG */ - } else { -#if LWIP_ICMP - /* send ICMP Destination Unreachable code 4: "Fragmentation Needed and DF Set" */ - icmp_dest_unreach(p, ICMP_DUR_FRAG); -#endif /* LWIP_ICMP */ - } - return; - } - /* transmit pbuf on chosen interface */ - netif->output(netif, p, ip4_current_dest_addr()); - return; -return_noroute: - MIB2_STATS_INC(mib2.ipoutnoroutes); -} -#endif /* IP_FORWARD */ - -/** Return true if the current input packet should be accepted on this netif */ -static int -ip4_input_accept(struct netif *netif) -{ - LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest 0x%"X32_F" netif->ip_addr 0x%"X32_F" (0x%"X32_F", 0x%"X32_F", 0x%"X32_F")\n", - ip4_addr_get_u32(ip4_current_dest_addr()), ip4_addr_get_u32(netif_ip4_addr(netif)), - ip4_addr_get_u32(ip4_current_dest_addr()) & ip4_addr_get_u32(netif_ip4_netmask(netif)), - ip4_addr_get_u32(netif_ip4_addr(netif)) & ip4_addr_get_u32(netif_ip4_netmask(netif)), - ip4_addr_get_u32(ip4_current_dest_addr()) & ~ip4_addr_get_u32(netif_ip4_netmask(netif)))); - - /* interface is up and configured? */ - if ((netif_is_up(netif)) && (!ip4_addr_isany_val(*netif_ip4_addr(netif)))) { - /* unicast to this interface address? */ - if (ip4_addr_cmp(ip4_current_dest_addr(), netif_ip4_addr(netif)) || - /* or broadcast on this interface network address? */ - ip4_addr_isbroadcast(ip4_current_dest_addr(), netif) -#if LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF - || (ip4_addr_get_u32(ip4_current_dest_addr()) == PP_HTONL(IPADDR_LOOPBACK)) -#endif /* LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF */ - ) { - LWIP_DEBUGF(IP_DEBUG, ("ip4_input: packet accepted on interface %c%c\n", - netif->name[0], netif->name[1])); - /* accept on this netif */ - return 1; - } -#if LWIP_AUTOIP - /* connections to link-local addresses must persist after changing - the netif's address (RFC3927 ch. 1.9) */ - if (autoip_accept_packet(netif, ip4_current_dest_addr())) { - LWIP_DEBUGF(IP_DEBUG, ("ip4_input: LLA packet accepted on interface %c%c\n", - netif->name[0], netif->name[1])); - /* accept on this netif */ - return 1; - } -#endif /* LWIP_AUTOIP */ - } - return 0; -} - -/** - * This function is called by the network interface device driver when - * an IP packet is received. The function does the basic checks of the - * IP header such as packet size being at least larger than the header - * size etc. If the packet was not destined for us, the packet is - * forwarded (using ip_forward). The IP checksum is always checked. - * - * Finally, the packet is sent to the upper layer protocol input function. - * - * @param p the received IP packet (p->payload points to IP header) - * @param inp the netif on which this packet was received - * @return ERR_OK if the packet was processed (could return ERR_* if it wasn't - * processed, but currently always returns ERR_OK) - */ -err_t -ip4_input(struct pbuf *p, struct netif *inp) -{ - const struct ip_hdr *iphdr; - struct netif *netif; - u16_t iphdr_hlen; - u16_t iphdr_len; -#if IP_ACCEPT_LINK_LAYER_ADDRESSING || LWIP_IGMP - int check_ip_src = 1; -#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING || LWIP_IGMP */ -#if LWIP_RAW - raw_input_state_t raw_status; -#endif /* LWIP_RAW */ - - LWIP_ASSERT_CORE_LOCKED(); - - IP_STATS_INC(ip.recv); - MIB2_STATS_INC(mib2.ipinreceives); - - /* identify the IP header */ - iphdr = (struct ip_hdr *)p->payload; - if (IPH_V(iphdr) != 4) { - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_WARNING, ("IP packet dropped due to bad version number %"U16_F"\n", (u16_t)IPH_V(iphdr))); - ip4_debug_print(p); - pbuf_free(p); - IP_STATS_INC(ip.err); - IP_STATS_INC(ip.drop); - MIB2_STATS_INC(mib2.ipinhdrerrors); - return ERR_OK; - } - -#ifdef LWIP_HOOK_IP4_INPUT - if (LWIP_HOOK_IP4_INPUT(p, inp)) { - /* the packet has been eaten */ - return ERR_OK; - } -#endif - - /* obtain IP header length in bytes */ - iphdr_hlen = IPH_HL_BYTES(iphdr); - /* obtain ip length in bytes */ - iphdr_len = lwip_ntohs(IPH_LEN(iphdr)); - - /* Trim pbuf. This is especially required for packets < 60 bytes. */ - if (iphdr_len < p->tot_len) { - pbuf_realloc(p, iphdr_len); - } - - /* header length exceeds first pbuf length, or ip length exceeds total pbuf length? */ - if ((iphdr_hlen > p->len) || (iphdr_len > p->tot_len) || (iphdr_hlen < IP_HLEN)) { - if (iphdr_hlen < IP_HLEN) { - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("ip4_input: short IP header (%"U16_F" bytes) received, IP packet dropped\n", iphdr_hlen)); - } - if (iphdr_hlen > p->len) { - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("IP header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet dropped.\n", - iphdr_hlen, p->len)); - } - if (iphdr_len > p->tot_len) { - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("IP (len %"U16_F") is longer than pbuf (len %"U16_F"), IP packet dropped.\n", - iphdr_len, p->tot_len)); - } - /* free (drop) packet pbufs */ - pbuf_free(p); - IP_STATS_INC(ip.lenerr); - IP_STATS_INC(ip.drop); - MIB2_STATS_INC(mib2.ipindiscards); - return ERR_OK; - } - - /* verify checksum */ -#if CHECKSUM_CHECK_IP - IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_IP) { - if (inet_chksum(iphdr, iphdr_hlen) != 0) { - - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("Checksum (0x%"X16_F") failed, IP packet dropped.\n", inet_chksum(iphdr, iphdr_hlen))); - ip4_debug_print(p); - pbuf_free(p); - IP_STATS_INC(ip.chkerr); - IP_STATS_INC(ip.drop); - MIB2_STATS_INC(mib2.ipinhdrerrors); - return ERR_OK; - } - } -#endif - - /* copy IP addresses to aligned ip_addr_t */ - ip_addr_copy_from_ip4(ip_data.current_iphdr_dest, iphdr->dest); - ip_addr_copy_from_ip4(ip_data.current_iphdr_src, iphdr->src); - - /* match packet against an interface, i.e. is this packet for us? */ - if (ip4_addr_ismulticast(ip4_current_dest_addr())) { -#if LWIP_IGMP - if ((inp->flags & NETIF_FLAG_IGMP) && (igmp_lookfor_group(inp, ip4_current_dest_addr()))) { - /* IGMP snooping switches need 0.0.0.0 to be allowed as source address (RFC 4541) */ - ip4_addr_t allsystems; - IP4_ADDR(&allsystems, 224, 0, 0, 1); - if (ip4_addr_cmp(ip4_current_dest_addr(), &allsystems) && - ip4_addr_isany(ip4_current_src_addr())) { - check_ip_src = 0; - } - netif = inp; - } else { - netif = NULL; - } -#else /* LWIP_IGMP */ - if ((netif_is_up(inp)) && (!ip4_addr_isany_val(*netif_ip4_addr(inp)))) { - netif = inp; - } else { - netif = NULL; - } -#endif /* LWIP_IGMP */ - } else { - /* start trying with inp. if that's not acceptable, start walking the - list of configured netifs. */ - if (ip4_input_accept(inp)) { - netif = inp; - } else { - netif = NULL; -#if !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF - /* Packets sent to the loopback address must not be accepted on an - * interface that does not have the loopback address assigned to it, - * unless a non-loopback interface is used for loopback traffic. */ - if (!ip4_addr_isloopback(ip4_current_dest_addr())) -#endif /* !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF */ - { -#if !LWIP_SINGLE_NETIF - NETIF_FOREACH(netif) { - if (netif == inp) { - /* we checked that before already */ - continue; - } - if (ip4_input_accept(netif)) { - break; - } - } -#endif /* !LWIP_SINGLE_NETIF */ - } - } - } - -#if IP_ACCEPT_LINK_LAYER_ADDRESSING - /* Pass DHCP messages regardless of destination address. DHCP traffic is addressed - * using link layer addressing (such as Ethernet MAC) so we must not filter on IP. - * According to RFC 1542 section 3.1.1, referred by RFC 2131). - * - * If you want to accept private broadcast communication while a netif is down, - * define LWIP_IP_ACCEPT_UDP_PORT(dst_port), e.g.: - * - * #define LWIP_IP_ACCEPT_UDP_PORT(dst_port) ((dst_port) == PP_NTOHS(12345)) - */ - if (netif == NULL) { - /* remote port is DHCP server? */ - if (IPH_PROTO(iphdr) == IP_PROTO_UDP) { - const struct udp_hdr *udphdr = (const struct udp_hdr *)((const u8_t *)iphdr + iphdr_hlen); - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip4_input: UDP packet to DHCP client port %"U16_F"\n", - lwip_ntohs(udphdr->dest))); - if (IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(udphdr->dest)) { - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip4_input: DHCP packet accepted.\n")); - netif = inp; - check_ip_src = 0; - } - } - } -#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */ - - /* broadcast or multicast packet source address? Compliant with RFC 1122: 3.2.1.3 */ -#if LWIP_IGMP || IP_ACCEPT_LINK_LAYER_ADDRESSING - if (check_ip_src -#if IP_ACCEPT_LINK_LAYER_ADDRESSING - /* DHCP servers need 0.0.0.0 to be allowed as source address (RFC 1.1.2.2: 3.2.1.3/a) */ - && !ip4_addr_isany_val(*ip4_current_src_addr()) -#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */ - ) -#endif /* LWIP_IGMP || IP_ACCEPT_LINK_LAYER_ADDRESSING */ - { - if ((ip4_addr_isbroadcast(ip4_current_src_addr(), inp)) || - (ip4_addr_ismulticast(ip4_current_src_addr()))) { - /* packet source is not valid */ - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("ip4_input: packet source is not valid.\n")); - /* free (drop) packet pbufs */ - pbuf_free(p); - IP_STATS_INC(ip.drop); - MIB2_STATS_INC(mib2.ipinaddrerrors); - MIB2_STATS_INC(mib2.ipindiscards); - return ERR_OK; - } - } - - /* packet not for us? */ - if (netif == NULL) { - /* packet not for us, route or discard */ - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip4_input: packet not for us.\n")); -#if IP_FORWARD - /* non-broadcast packet? */ - if (!ip4_addr_isbroadcast(ip4_current_dest_addr(), inp)) { - /* try to forward IP packet on (other) interfaces */ - ip4_forward(p, (struct ip_hdr *)p->payload, inp); - } else -#endif /* IP_FORWARD */ - { - IP_STATS_INC(ip.drop); - MIB2_STATS_INC(mib2.ipinaddrerrors); - MIB2_STATS_INC(mib2.ipindiscards); - } - pbuf_free(p); - return ERR_OK; - } - /* packet consists of multiple fragments? */ - if ((IPH_OFFSET(iphdr) & PP_HTONS(IP_OFFMASK | IP_MF)) != 0) { -#if IP_REASSEMBLY /* packet fragment reassembly code present? */ - LWIP_DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04"X16_F" tot_len=%"U16_F" len=%"U16_F" MF=%"U16_F" offset=%"U16_F"), calling ip4_reass()\n", - lwip_ntohs(IPH_ID(iphdr)), p->tot_len, lwip_ntohs(IPH_LEN(iphdr)), (u16_t)!!(IPH_OFFSET(iphdr) & PP_HTONS(IP_MF)), (u16_t)((lwip_ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK) * 8))); - /* reassemble the packet*/ - p = ip4_reass(p); - /* packet not fully reassembled yet? */ - if (p == NULL) { - return ERR_OK; - } - iphdr = (const struct ip_hdr *)p->payload; -#else /* IP_REASSEMBLY == 0, no packet fragment reassembly code present */ - pbuf_free(p); - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since it was fragmented (0x%"X16_F") (while IP_REASSEMBLY == 0).\n", - lwip_ntohs(IPH_OFFSET(iphdr)))); - IP_STATS_INC(ip.opterr); - IP_STATS_INC(ip.drop); - /* unsupported protocol feature */ - MIB2_STATS_INC(mib2.ipinunknownprotos); - return ERR_OK; -#endif /* IP_REASSEMBLY */ - } - -#if IP_OPTIONS_ALLOWED == 0 /* no support for IP options in the IP header? */ - -#if LWIP_IGMP - /* there is an extra "router alert" option in IGMP messages which we allow for but do not police */ - if ((iphdr_hlen > IP_HLEN) && (IPH_PROTO(iphdr) != IP_PROTO_IGMP)) { -#else - if (iphdr_hlen > IP_HLEN) { -#endif /* LWIP_IGMP */ - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since there were IP options (while IP_OPTIONS_ALLOWED == 0).\n")); - pbuf_free(p); - IP_STATS_INC(ip.opterr); - IP_STATS_INC(ip.drop); - /* unsupported protocol feature */ - MIB2_STATS_INC(mib2.ipinunknownprotos); - return ERR_OK; - } -#endif /* IP_OPTIONS_ALLOWED == 0 */ - - /* send to upper layers */ - LWIP_DEBUGF(IP_DEBUG, ("ip4_input: \n")); - ip4_debug_print(p); - LWIP_DEBUGF(IP_DEBUG, ("ip4_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len)); - - ip_data.current_netif = netif; - ip_data.current_input_netif = inp; - ip_data.current_ip4_header = iphdr; - ip_data.current_ip_header_tot_len = IPH_HL_BYTES(iphdr); - -#if LWIP_RAW - /* raw input did not eat the packet? */ - raw_status = raw_input(p, inp); - if (raw_status != RAW_INPUT_EATEN) -#endif /* LWIP_RAW */ - { - pbuf_remove_header(p, iphdr_hlen); /* Move to payload, no check necessary. */ - - switch (IPH_PROTO(iphdr)) { -#if LWIP_UDP - case IP_PROTO_UDP: -#if LWIP_UDPLITE - case IP_PROTO_UDPLITE: -#endif /* LWIP_UDPLITE */ - MIB2_STATS_INC(mib2.ipindelivers); - udp_input(p, inp); - break; -#endif /* LWIP_UDP */ -#if LWIP_TCP - case IP_PROTO_TCP: - MIB2_STATS_INC(mib2.ipindelivers); - tcp_input(p, inp); - break; -#endif /* LWIP_TCP */ -#if LWIP_ICMP - case IP_PROTO_ICMP: - MIB2_STATS_INC(mib2.ipindelivers); - icmp_input(p, inp); - break; -#endif /* LWIP_ICMP */ -#if LWIP_IGMP - case IP_PROTO_IGMP: - igmp_input(p, inp, ip4_current_dest_addr()); - break; -#endif /* LWIP_IGMP */ - default: -#if LWIP_RAW - if (raw_status == RAW_INPUT_DELIVERED) { - MIB2_STATS_INC(mib2.ipindelivers); - } else -#endif /* LWIP_RAW */ - { -#if LWIP_ICMP - /* send ICMP destination protocol unreachable unless is was a broadcast */ - if (!ip4_addr_isbroadcast(ip4_current_dest_addr(), netif) && - !ip4_addr_ismulticast(ip4_current_dest_addr())) { - pbuf_header_force(p, (s16_t)iphdr_hlen); /* Move to ip header, no check necessary. */ - icmp_dest_unreach(p, ICMP_DUR_PROTO); - } -#endif /* LWIP_ICMP */ - - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("Unsupported transport protocol %"U16_F"\n", (u16_t)IPH_PROTO(iphdr))); - - IP_STATS_INC(ip.proterr); - IP_STATS_INC(ip.drop); - MIB2_STATS_INC(mib2.ipinunknownprotos); - } - pbuf_free(p); - break; - } - } - - /* @todo: this is not really necessary... */ - ip_data.current_netif = NULL; - ip_data.current_input_netif = NULL; - ip_data.current_ip4_header = NULL; - ip_data.current_ip_header_tot_len = 0; - ip4_addr_set_any(ip4_current_src_addr()); - ip4_addr_set_any(ip4_current_dest_addr()); - - return ERR_OK; -} - -/** - * Sends an IP packet on a network interface. This function constructs - * the IP header and calculates the IP header checksum. If the source - * IP address is NULL, the IP address of the outgoing network - * interface is filled in as source address. - * If the destination IP address is LWIP_IP_HDRINCL, p is assumed to already - * include an IP header and p->payload points to it instead of the data. - * - * @param p the packet to send (p->payload points to the data, e.g. next - protocol header; if dest == LWIP_IP_HDRINCL, p already includes an - IP header and p->payload points to that IP header) - * @param src the source IP address to send from (if src == IP4_ADDR_ANY, the - * IP address of the netif used to send is used as source address) - * @param dest the destination IP address to send the packet to - * @param ttl the TTL value to be set in the IP header - * @param tos the TOS value to be set in the IP header - * @param proto the PROTOCOL to be set in the IP header - * @param netif the netif on which to send this packet - * @return ERR_OK if the packet was sent OK - * ERR_BUF if p doesn't have enough space for IP/LINK headers - * returns errors returned by netif->output - * - * @note ip_id: RFC791 "some host may be able to simply use - * unique identifiers independent of destination" - */ -err_t -ip4_output_if(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, - u8_t ttl, u8_t tos, - u8_t proto, struct netif *netif) -{ -#if IP_OPTIONS_SEND - return ip4_output_if_opt(p, src, dest, ttl, tos, proto, netif, NULL, 0); -} - -/** - * Same as ip_output_if() but with the possibility to include IP options: - * - * @ param ip_options pointer to the IP options, copied into the IP header - * @ param optlen length of ip_options - */ -err_t -ip4_output_if_opt(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options, - u16_t optlen) -{ -#endif /* IP_OPTIONS_SEND */ - const ip4_addr_t *src_used = src; - if (dest != LWIP_IP_HDRINCL) { - if (ip4_addr_isany(src)) { - src_used = netif_ip4_addr(netif); - } - } - -#if IP_OPTIONS_SEND - return ip4_output_if_opt_src(p, src_used, dest, ttl, tos, proto, netif, - ip_options, optlen); -#else /* IP_OPTIONS_SEND */ - return ip4_output_if_src(p, src_used, dest, ttl, tos, proto, netif); -#endif /* IP_OPTIONS_SEND */ -} - -/** - * Same as ip_output_if() but 'src' address is not replaced by netif address - * when it is 'any'. - */ -err_t -ip4_output_if_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, - u8_t ttl, u8_t tos, - u8_t proto, struct netif *netif) -{ -#if IP_OPTIONS_SEND - return ip4_output_if_opt_src(p, src, dest, ttl, tos, proto, netif, NULL, 0); -} - -/** - * Same as ip_output_if_opt() but 'src' address is not replaced by netif address - * when it is 'any'. - */ -err_t -ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options, - u16_t optlen) -{ -#endif /* IP_OPTIONS_SEND */ - struct ip_hdr *iphdr; - ip4_addr_t dest_addr; -#if CHECKSUM_GEN_IP_INLINE - u32_t chk_sum = 0; -#endif /* CHECKSUM_GEN_IP_INLINE */ - - LWIP_ASSERT_CORE_LOCKED(); - LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p); - - MIB2_STATS_INC(mib2.ipoutrequests); - - /* Should the IP header be generated or is it already included in p? */ - if (dest != LWIP_IP_HDRINCL) { - u16_t ip_hlen = IP_HLEN; -#if IP_OPTIONS_SEND - u16_t optlen_aligned = 0; - if (optlen != 0) { -#if CHECKSUM_GEN_IP_INLINE - int i; -#endif /* CHECKSUM_GEN_IP_INLINE */ - if (optlen > (IP_HLEN_MAX - IP_HLEN)) { - /* optlen too long */ - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip4_output_if_opt: optlen too long\n")); - IP_STATS_INC(ip.err); - MIB2_STATS_INC(mib2.ipoutdiscards); - return ERR_VAL; - } - /* round up to a multiple of 4 */ - optlen_aligned = (u16_t)((optlen + 3) & ~3); - ip_hlen = (u16_t)(ip_hlen + optlen_aligned); - /* First write in the IP options */ - if (pbuf_add_header(p, optlen_aligned)) { - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip4_output_if_opt: not enough room for IP options in pbuf\n")); - IP_STATS_INC(ip.err); - MIB2_STATS_INC(mib2.ipoutdiscards); - return ERR_BUF; - } - MEMCPY(p->payload, ip_options, optlen); - if (optlen < optlen_aligned) { - /* zero the remaining bytes */ - memset(((char *)p->payload) + optlen, 0, (size_t)(optlen_aligned - optlen)); - } -#if CHECKSUM_GEN_IP_INLINE - for (i = 0; i < optlen_aligned / 2; i++) { - chk_sum += ((u16_t *)p->payload)[i]; - } -#endif /* CHECKSUM_GEN_IP_INLINE */ - } -#endif /* IP_OPTIONS_SEND */ - /* generate IP header */ - if (pbuf_add_header(p, IP_HLEN)) { - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip4_output: not enough room for IP header in pbuf\n")); - - IP_STATS_INC(ip.err); - MIB2_STATS_INC(mib2.ipoutdiscards); - return ERR_BUF; - } - - iphdr = (struct ip_hdr *)p->payload; - LWIP_ASSERT("check that first pbuf can hold struct ip_hdr", - (p->len >= sizeof(struct ip_hdr))); - - IPH_TTL_SET(iphdr, ttl); - IPH_PROTO_SET(iphdr, proto); -#if CHECKSUM_GEN_IP_INLINE - chk_sum += PP_NTOHS(proto | (ttl << 8)); -#endif /* CHECKSUM_GEN_IP_INLINE */ - - /* dest cannot be NULL here */ - ip4_addr_copy(iphdr->dest, *dest); -#if CHECKSUM_GEN_IP_INLINE - chk_sum += ip4_addr_get_u32(&iphdr->dest) & 0xFFFF; - chk_sum += ip4_addr_get_u32(&iphdr->dest) >> 16; -#endif /* CHECKSUM_GEN_IP_INLINE */ - - IPH_VHL_SET(iphdr, 4, ip_hlen / 4); - IPH_TOS_SET(iphdr, tos); -#if CHECKSUM_GEN_IP_INLINE - chk_sum += PP_NTOHS(tos | (iphdr->_v_hl << 8)); -#endif /* CHECKSUM_GEN_IP_INLINE */ - IPH_LEN_SET(iphdr, lwip_htons(p->tot_len)); -#if CHECKSUM_GEN_IP_INLINE - chk_sum += iphdr->_len; -#endif /* CHECKSUM_GEN_IP_INLINE */ - IPH_OFFSET_SET(iphdr, 0); - IPH_ID_SET(iphdr, lwip_htons(ip_id)); -#if CHECKSUM_GEN_IP_INLINE - chk_sum += iphdr->_id; -#endif /* CHECKSUM_GEN_IP_INLINE */ - ++ip_id; - - if (src == NULL) { - ip4_addr_copy(iphdr->src, *IP4_ADDR_ANY4); - } else { - /* src cannot be NULL here */ - ip4_addr_copy(iphdr->src, *src); - } - -#if CHECKSUM_GEN_IP_INLINE - chk_sum += ip4_addr_get_u32(&iphdr->src) & 0xFFFF; - chk_sum += ip4_addr_get_u32(&iphdr->src) >> 16; - chk_sum = (chk_sum >> 16) + (chk_sum & 0xFFFF); - chk_sum = (chk_sum >> 16) + chk_sum; - chk_sum = ~chk_sum; - IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) { - iphdr->_chksum = (u16_t)chk_sum; /* network order */ - } -#if LWIP_CHECKSUM_CTRL_PER_NETIF - else { - IPH_CHKSUM_SET(iphdr, 0); - } -#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF*/ -#else /* CHECKSUM_GEN_IP_INLINE */ - IPH_CHKSUM_SET(iphdr, 0); -#if CHECKSUM_GEN_IP - IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) { - IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, ip_hlen)); - } -#endif /* CHECKSUM_GEN_IP */ -#endif /* CHECKSUM_GEN_IP_INLINE */ - } else { - /* IP header already included in p */ - if (p->len < IP_HLEN) { - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip4_output: LWIP_IP_HDRINCL but pbuf is too short\n")); - IP_STATS_INC(ip.err); - MIB2_STATS_INC(mib2.ipoutdiscards); - return ERR_BUF; - } - iphdr = (struct ip_hdr *)p->payload; - ip4_addr_copy(dest_addr, iphdr->dest); - dest = &dest_addr; - } - - IP_STATS_INC(ip.xmit); - - LWIP_DEBUGF(IP_DEBUG, ("ip4_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], (u16_t)netif->num)); - ip4_debug_print(p); - -#if ENABLE_LOOPBACK - if (ip4_addr_cmp(dest, netif_ip4_addr(netif)) -#if !LWIP_HAVE_LOOPIF - || ip4_addr_isloopback(dest) -#endif /* !LWIP_HAVE_LOOPIF */ - ) { - /* Packet to self, enqueue it for loopback */ - LWIP_DEBUGF(IP_DEBUG, ("netif_loop_output()")); - return netif_loop_output(netif, p); - } -#if LWIP_MULTICAST_TX_OPTIONS - if ((p->flags & PBUF_FLAG_MCASTLOOP) != 0) { - netif_loop_output(netif, p); - } -#endif /* LWIP_MULTICAST_TX_OPTIONS */ -#endif /* ENABLE_LOOPBACK */ -#if IP_FRAG - /* don't fragment if interface has mtu set to 0 [loopif] */ - if (netif->mtu && (p->tot_len > netif->mtu)) { - return ip4_frag(p, netif, dest); - } -#endif /* IP_FRAG */ - - LWIP_DEBUGF(IP_DEBUG, ("ip4_output_if: call netif->output()\n")); - return netif->output(netif, p, dest); -} - -/** - * Simple interface to ip_output_if. It finds the outgoing network - * interface and calls upon ip_output_if to do the actual work. - * - * @param p the packet to send (p->payload points to the data, e.g. next - protocol header; if dest == LWIP_IP_HDRINCL, p already includes an - IP header and p->payload points to that IP header) - * @param src the source IP address to send from (if src == IP4_ADDR_ANY, the - * IP address of the netif used to send is used as source address) - * @param dest the destination IP address to send the packet to - * @param ttl the TTL value to be set in the IP header - * @param tos the TOS value to be set in the IP header - * @param proto the PROTOCOL to be set in the IP header - * - * @return ERR_RTE if no route is found - * see ip_output_if() for more return values - */ -err_t -ip4_output(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto) -{ - struct netif *netif; - - LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p); - - if ((netif = ip4_route_src(src, dest)) == NULL) { - LWIP_DEBUGF(IP_DEBUG, ("ip4_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); - IP_STATS_INC(ip.rterr); - return ERR_RTE; - } - - return ip4_output_if(p, src, dest, ttl, tos, proto, netif); -} - -#if LWIP_NETIF_USE_HINTS -/** Like ip_output, but takes and addr_hint pointer that is passed on to netif->addr_hint - * before calling ip_output_if. - * - * @param p the packet to send (p->payload points to the data, e.g. next - protocol header; if dest == LWIP_IP_HDRINCL, p already includes an - IP header and p->payload points to that IP header) - * @param src the source IP address to send from (if src == IP4_ADDR_ANY, the - * IP address of the netif used to send is used as source address) - * @param dest the destination IP address to send the packet to - * @param ttl the TTL value to be set in the IP header - * @param tos the TOS value to be set in the IP header - * @param proto the PROTOCOL to be set in the IP header - * @param netif_hint netif output hint pointer set to netif->hint before - * calling ip_output_if() - * - * @return ERR_RTE if no route is found - * see ip_output_if() for more return values - */ -err_t -ip4_output_hinted(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, struct netif_hint *netif_hint) -{ - struct netif *netif; - err_t err; - - LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p); - - if ((netif = ip4_route_src(src, dest)) == NULL) { - LWIP_DEBUGF(IP_DEBUG, ("ip4_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); - IP_STATS_INC(ip.rterr); - return ERR_RTE; - } - - NETIF_SET_HINTS(netif, netif_hint); - err = ip4_output_if(p, src, dest, ttl, tos, proto, netif); - NETIF_RESET_HINTS(netif); - - return err; -} -#endif /* LWIP_NETIF_USE_HINTS*/ - -#if IP_DEBUG -/* Print an IP header by using LWIP_DEBUGF - * @param p an IP packet, p->payload pointing to the IP header - */ -void -ip4_debug_print(struct pbuf *p) -{ - struct ip_hdr *iphdr = (struct ip_hdr *)p->payload; - - LWIP_DEBUGF(IP_DEBUG, ("IP header:\n")); - LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(IP_DEBUG, ("|%2"S16_F" |%2"S16_F" | 0x%02"X16_F" | %5"U16_F" | (v, hl, tos, len)\n", - (u16_t)IPH_V(iphdr), - (u16_t)IPH_HL(iphdr), - (u16_t)IPH_TOS(iphdr), - lwip_ntohs(IPH_LEN(iphdr)))); - LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(IP_DEBUG, ("| %5"U16_F" |%"U16_F"%"U16_F"%"U16_F"| %4"U16_F" | (id, flags, offset)\n", - lwip_ntohs(IPH_ID(iphdr)), - (u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) >> 15 & 1), - (u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) >> 14 & 1), - (u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) >> 13 & 1), - (u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK))); - LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | 0x%04"X16_F" | (ttl, proto, chksum)\n", - (u16_t)IPH_TTL(iphdr), - (u16_t)IPH_PROTO(iphdr), - lwip_ntohs(IPH_CHKSUM(iphdr)))); - LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (src)\n", - ip4_addr1_16_val(iphdr->src), - ip4_addr2_16_val(iphdr->src), - ip4_addr3_16_val(iphdr->src), - ip4_addr4_16_val(iphdr->src))); - LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (dest)\n", - ip4_addr1_16_val(iphdr->dest), - ip4_addr2_16_val(iphdr->dest), - ip4_addr3_16_val(iphdr->dest), - ip4_addr4_16_val(iphdr->dest))); - LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); -} -#endif /* IP_DEBUG */ - -#endif /* LWIP_IPV4 */ diff --git a/third-party/lwip-2.1.2/core/ipv4/ip4_addr.c b/third-party/lwip-2.1.2/core/ipv4/ip4_addr.c deleted file mode 100644 index 33204d11..00000000 --- a/third-party/lwip-2.1.2/core/ipv4/ip4_addr.c +++ /dev/null @@ -1,321 +0,0 @@ -/** - * @file - * This is the IPv4 address tools implementation. - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#include "lwip/opt.h" - -#if LWIP_IPV4 - -#include "lwip/ip_addr.h" -#include "lwip/netif.h" - -/* used by IP4_ADDR_ANY and IP_ADDR_BROADCAST in ip_addr.h */ -const ip_addr_t ip_addr_any = IPADDR4_INIT(IPADDR_ANY); -const ip_addr_t ip_addr_broadcast = IPADDR4_INIT(IPADDR_BROADCAST); - -/** - * Determine if an address is a broadcast address on a network interface - * - * @param addr address to be checked - * @param netif the network interface against which the address is checked - * @return returns non-zero if the address is a broadcast address - */ -u8_t -ip4_addr_isbroadcast_u32(u32_t addr, const struct netif *netif) -{ - ip4_addr_t ipaddr; - ip4_addr_set_u32(&ipaddr, addr); - - /* all ones (broadcast) or all zeroes (old skool broadcast) */ - if ((~addr == IPADDR_ANY) || - (addr == IPADDR_ANY)) { - return 1; - /* no broadcast support on this network interface? */ - } else if ((netif->flags & NETIF_FLAG_BROADCAST) == 0) { - /* the given address cannot be a broadcast address - * nor can we check against any broadcast addresses */ - return 0; - /* address matches network interface address exactly? => no broadcast */ - } else if (addr == ip4_addr_get_u32(netif_ip4_addr(netif))) { - return 0; - /* on the same (sub) network... */ - } else if (ip4_addr_netcmp(&ipaddr, netif_ip4_addr(netif), netif_ip4_netmask(netif)) - /* ...and host identifier bits are all ones? =>... */ - && ((addr & ~ip4_addr_get_u32(netif_ip4_netmask(netif))) == - (IPADDR_BROADCAST & ~ip4_addr_get_u32(netif_ip4_netmask(netif))))) { - /* => network broadcast address */ - return 1; - } else { - return 0; - } -} - -/** Checks if a netmask is valid (starting with ones, then only zeros) - * - * @param netmask the IPv4 netmask to check (in network byte order!) - * @return 1 if the netmask is valid, 0 if it is not - */ -u8_t -ip4_addr_netmask_valid(u32_t netmask) -{ - u32_t mask; - u32_t nm_hostorder = lwip_htonl(netmask); - - /* first, check for the first zero */ - for (mask = 1UL << 31 ; mask != 0; mask >>= 1) { - if ((nm_hostorder & mask) == 0) { - break; - } - } - /* then check that there is no one */ - for (; mask != 0; mask >>= 1) { - if ((nm_hostorder & mask) != 0) { - /* there is a one after the first zero -> invalid */ - return 0; - } - } - /* no one after the first zero -> valid */ - return 1; -} - -/** - * Ascii internet address interpretation routine. - * The value returned is in network order. - * - * @param cp IP address in ascii representation (e.g. "127.0.0.1") - * @return ip address in network order - */ -u32_t -ipaddr_addr(const char *cp) -{ - ip4_addr_t val; - - if (ip4addr_aton(cp, &val)) { - return ip4_addr_get_u32(&val); - } - return (IPADDR_NONE); -} - -/** - * Check whether "cp" is a valid ascii representation - * of an Internet address and convert to a binary address. - * Returns 1 if the address is valid, 0 if not. - * This replaces inet_addr, the return value from which - * cannot distinguish between failure and a local broadcast address. - * - * @param cp IP address in ascii representation (e.g. "127.0.0.1") - * @param addr pointer to which to save the ip address in network order - * @return 1 if cp could be converted to addr, 0 on failure - */ -int -ip4addr_aton(const char *cp, ip4_addr_t *addr) -{ - u32_t val; - u8_t base; - char c; - u32_t parts[4]; - u32_t *pp = parts; - - c = *cp; - for (;;) { - /* - * Collect number up to ``.''. - * Values are specified as for C: - * 0x=hex, 0=octal, 1-9=decimal. - */ - if (!lwip_isdigit(c)) { - return 0; - } - val = 0; - base = 10; - if (c == '0') { - c = *++cp; - if (c == 'x' || c == 'X') { - base = 16; - c = *++cp; - } else { - base = 8; - } - } - for (;;) { - if (lwip_isdigit(c)) { - val = (val * base) + (u32_t)(c - '0'); - c = *++cp; - } else if (base == 16 && lwip_isxdigit(c)) { - val = (val << 4) | (u32_t)(c + 10 - (lwip_islower(c) ? 'a' : 'A')); - c = *++cp; - } else { - break; - } - } - if (c == '.') { - /* - * Internet format: - * a.b.c.d - * a.b.c (with c treated as 16 bits) - * a.b (with b treated as 24 bits) - */ - if (pp >= parts + 3) { - return 0; - } - *pp++ = val; - c = *++cp; - } else { - break; - } - } - /* - * Check for trailing characters. - */ - if (c != '\0' && !lwip_isspace(c)) { - return 0; - } - /* - * Concoct the address according to - * the number of parts specified. - */ - switch (pp - parts + 1) { - - case 0: - return 0; /* initial nondigit */ - - case 1: /* a -- 32 bits */ - break; - - case 2: /* a.b -- 8.24 bits */ - if (val > 0xffffffUL) { - return 0; - } - if (parts[0] > 0xff) { - return 0; - } - val |= parts[0] << 24; - break; - - case 3: /* a.b.c -- 8.8.16 bits */ - if (val > 0xffff) { - return 0; - } - if ((parts[0] > 0xff) || (parts[1] > 0xff)) { - return 0; - } - val |= (parts[0] << 24) | (parts[1] << 16); - break; - - case 4: /* a.b.c.d -- 8.8.8.8 bits */ - if (val > 0xff) { - return 0; - } - if ((parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff)) { - return 0; - } - val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); - break; - default: - LWIP_ASSERT("unhandled", 0); - break; - } - if (addr) { - ip4_addr_set_u32(addr, lwip_htonl(val)); - } - return 1; -} - -/** - * Convert numeric IP address into decimal dotted ASCII representation. - * returns ptr to static buffer; not reentrant! - * - * @param addr ip address in network order to convert - * @return pointer to a global static (!) buffer that holds the ASCII - * representation of addr - */ -char * -ip4addr_ntoa(const ip4_addr_t *addr) -{ - static char str[IP4ADDR_STRLEN_MAX]; - return ip4addr_ntoa_r(addr, str, IP4ADDR_STRLEN_MAX); -} - -/** - * Same as ip4addr_ntoa, but reentrant since a user-supplied buffer is used. - * - * @param addr ip address in network order to convert - * @param buf target buffer where the string is stored - * @param buflen length of buf - * @return either pointer to buf which now holds the ASCII - * representation of addr or NULL if buf was too small - */ -char * -ip4addr_ntoa_r(const ip4_addr_t *addr, char *buf, int buflen) -{ - u32_t s_addr; - char inv[3]; - char *rp; - u8_t *ap; - u8_t rem; - u8_t n; - u8_t i; - int len = 0; - - s_addr = ip4_addr_get_u32(addr); - - rp = buf; - ap = (u8_t *)&s_addr; - for (n = 0; n < 4; n++) { - i = 0; - do { - rem = *ap % (u8_t)10; - *ap /= (u8_t)10; - inv[i++] = (char)('0' + rem); - } while (*ap); - while (i--) { - if (len++ >= buflen) { - return NULL; - } - *rp++ = inv[i]; - } - if (len++ >= buflen) { - return NULL; - } - *rp++ = '.'; - ap++; - } - *--rp = 0; - return buf; -} - -#endif /* LWIP_IPV4 */ diff --git a/third-party/lwip-2.1.2/core/ipv4/ip4_frag.c b/third-party/lwip-2.1.2/core/ipv4/ip4_frag.c deleted file mode 100644 index a445530e..00000000 --- a/third-party/lwip-2.1.2/core/ipv4/ip4_frag.c +++ /dev/null @@ -1,894 +0,0 @@ -/** - * @file - * This is the IPv4 packet segmentation and reassembly implementation. - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Jani Monoses - * Simon Goldschmidt - * original reassembly code by Adam Dunkels - * - */ - -#include "lwip/opt.h" - -#if LWIP_IPV4 - -#include "lwip/ip4_frag.h" -#include "lwip/def.h" -#include "lwip/inet_chksum.h" -#include "lwip/netif.h" -#include "lwip/stats.h" -#include "lwip/icmp.h" - -#include - -#if IP_REASSEMBLY -/** - * The IP reassembly code currently has the following limitations: - * - IP header options are not supported - * - fragments must not overlap (e.g. due to different routes), - * currently, overlapping or duplicate fragments are thrown away - * if IP_REASS_CHECK_OVERLAP=1 (the default)! - * - * @todo: work with IP header options - */ - -/** Setting this to 0, you can turn off checking the fragments for overlapping - * regions. The code gets a little smaller. Only use this if you know that - * overlapping won't occur on your network! */ -#ifndef IP_REASS_CHECK_OVERLAP -#define IP_REASS_CHECK_OVERLAP 1 -#endif /* IP_REASS_CHECK_OVERLAP */ - -/** Set to 0 to prevent freeing the oldest datagram when the reassembly buffer is - * full (IP_REASS_MAX_PBUFS pbufs are enqueued). The code gets a little smaller. - * Datagrams will be freed by timeout only. Especially useful when MEMP_NUM_REASSDATA - * is set to 1, so one datagram can be reassembled at a time, only. */ -#ifndef IP_REASS_FREE_OLDEST -#define IP_REASS_FREE_OLDEST 1 -#endif /* IP_REASS_FREE_OLDEST */ - -#define IP_REASS_FLAG_LASTFRAG 0x01 - -#define IP_REASS_VALIDATE_TELEGRAM_FINISHED 1 -#define IP_REASS_VALIDATE_PBUF_QUEUED 0 -#define IP_REASS_VALIDATE_PBUF_DROPPED -1 - -/** This is a helper struct which holds the starting - * offset and the ending offset of this fragment to - * easily chain the fragments. - * It has the same packing requirements as the IP header, since it replaces - * the IP header in memory in incoming fragments (after copying it) to keep - * track of the various fragments. (-> If the IP header doesn't need packing, - * this struct doesn't need packing, too.) - */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ip_reass_helper { - PACK_STRUCT_FIELD(struct pbuf *next_pbuf); - PACK_STRUCT_FIELD(u16_t start); - PACK_STRUCT_FIELD(u16_t end); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#define IP_ADDRESSES_AND_ID_MATCH(iphdrA, iphdrB) \ - (ip4_addr_cmp(&(iphdrA)->src, &(iphdrB)->src) && \ - ip4_addr_cmp(&(iphdrA)->dest, &(iphdrB)->dest) && \ - IPH_ID(iphdrA) == IPH_ID(iphdrB)) ? 1 : 0 - -/* global variables */ -static struct ip_reassdata *reassdatagrams; -static u16_t ip_reass_pbufcount; - -/* function prototypes */ -static void ip_reass_dequeue_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev); -static int ip_reass_free_complete_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev); - -/** - * Reassembly timer base function - * for both NO_SYS == 0 and 1 (!). - * - * Should be called every 1000 msec (defined by IP_TMR_INTERVAL). - */ -void -ip_reass_tmr(void) -{ - struct ip_reassdata *r, *prev = NULL; - - r = reassdatagrams; - while (r != NULL) { - /* Decrement the timer. Once it reaches 0, - * clean up the incomplete fragment assembly */ - if (r->timer > 0) { - r->timer--; - LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass_tmr: timer dec %"U16_F"\n", (u16_t)r->timer)); - prev = r; - r = r->next; - } else { - /* reassembly timed out */ - struct ip_reassdata *tmp; - LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass_tmr: timer timed out\n")); - tmp = r; - /* get the next pointer before freeing */ - r = r->next; - /* free the helper struct and all enqueued pbufs */ - ip_reass_free_complete_datagram(tmp, prev); - } - } -} - -/** - * Free a datagram (struct ip_reassdata) and all its pbufs. - * Updates the total count of enqueued pbufs (ip_reass_pbufcount), - * SNMP counters and sends an ICMP time exceeded packet. - * - * @param ipr datagram to free - * @param prev the previous datagram in the linked list - * @return the number of pbufs freed - */ -static int -ip_reass_free_complete_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev) -{ - u16_t pbufs_freed = 0; - u16_t clen; - struct pbuf *p; - struct ip_reass_helper *iprh; - - LWIP_ASSERT("prev != ipr", prev != ipr); - if (prev != NULL) { - LWIP_ASSERT("prev->next == ipr", prev->next == ipr); - } - - MIB2_STATS_INC(mib2.ipreasmfails); -#if LWIP_ICMP - iprh = (struct ip_reass_helper *)ipr->p->payload; - if (iprh->start == 0) { - /* The first fragment was received, send ICMP time exceeded. */ - /* First, de-queue the first pbuf from r->p. */ - p = ipr->p; - ipr->p = iprh->next_pbuf; - /* Then, copy the original header into it. */ - SMEMCPY(p->payload, &ipr->iphdr, IP_HLEN); - icmp_time_exceeded(p, ICMP_TE_FRAG); - clen = pbuf_clen(p); - LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff); - pbufs_freed = (u16_t)(pbufs_freed + clen); - pbuf_free(p); - } -#endif /* LWIP_ICMP */ - - /* First, free all received pbufs. The individual pbufs need to be released - separately as they have not yet been chained */ - p = ipr->p; - while (p != NULL) { - struct pbuf *pcur; - iprh = (struct ip_reass_helper *)p->payload; - pcur = p; - /* get the next pointer before freeing */ - p = iprh->next_pbuf; - clen = pbuf_clen(pcur); - LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff); - pbufs_freed = (u16_t)(pbufs_freed + clen); - pbuf_free(pcur); - } - /* Then, unchain the struct ip_reassdata from the list and free it. */ - ip_reass_dequeue_datagram(ipr, prev); - LWIP_ASSERT("ip_reass_pbufcount >= pbufs_freed", ip_reass_pbufcount >= pbufs_freed); - ip_reass_pbufcount = (u16_t)(ip_reass_pbufcount - pbufs_freed); - - return pbufs_freed; -} - -#if IP_REASS_FREE_OLDEST -/** - * Free the oldest datagram to make room for enqueueing new fragments. - * The datagram 'fraghdr' belongs to is not freed! - * - * @param fraghdr IP header of the current fragment - * @param pbufs_needed number of pbufs needed to enqueue - * (used for freeing other datagrams if not enough space) - * @return the number of pbufs freed - */ -static int -ip_reass_remove_oldest_datagram(struct ip_hdr *fraghdr, int pbufs_needed) -{ - /* @todo Can't we simply remove the last datagram in the - * linked list behind reassdatagrams? - */ - struct ip_reassdata *r, *oldest, *prev, *oldest_prev; - int pbufs_freed = 0, pbufs_freed_current; - int other_datagrams; - - /* Free datagrams until being allowed to enqueue 'pbufs_needed' pbufs, - * but don't free the datagram that 'fraghdr' belongs to! */ - do { - oldest = NULL; - prev = NULL; - oldest_prev = NULL; - other_datagrams = 0; - r = reassdatagrams; - while (r != NULL) { - if (!IP_ADDRESSES_AND_ID_MATCH(&r->iphdr, fraghdr)) { - /* Not the same datagram as fraghdr */ - other_datagrams++; - if (oldest == NULL) { - oldest = r; - oldest_prev = prev; - } else if (r->timer <= oldest->timer) { - /* older than the previous oldest */ - oldest = r; - oldest_prev = prev; - } - } - if (r->next != NULL) { - prev = r; - } - r = r->next; - } - if (oldest != NULL) { - pbufs_freed_current = ip_reass_free_complete_datagram(oldest, oldest_prev); - pbufs_freed += pbufs_freed_current; - } - } while ((pbufs_freed < pbufs_needed) && (other_datagrams > 1)); - return pbufs_freed; -} -#endif /* IP_REASS_FREE_OLDEST */ - -/** - * Enqueues a new fragment into the fragment queue - * @param fraghdr points to the new fragments IP hdr - * @param clen number of pbufs needed to enqueue (used for freeing other datagrams if not enough space) - * @return A pointer to the queue location into which the fragment was enqueued - */ -static struct ip_reassdata * -ip_reass_enqueue_new_datagram(struct ip_hdr *fraghdr, int clen) -{ - struct ip_reassdata *ipr; -#if ! IP_REASS_FREE_OLDEST - LWIP_UNUSED_ARG(clen); -#endif - - /* No matching previous fragment found, allocate a new reassdata struct */ - ipr = (struct ip_reassdata *)memp_malloc(MEMP_REASSDATA); - if (ipr == NULL) { -#if IP_REASS_FREE_OLDEST - if (ip_reass_remove_oldest_datagram(fraghdr, clen) >= clen) { - ipr = (struct ip_reassdata *)memp_malloc(MEMP_REASSDATA); - } - if (ipr == NULL) -#endif /* IP_REASS_FREE_OLDEST */ - { - IPFRAG_STATS_INC(ip_frag.memerr); - LWIP_DEBUGF(IP_REASS_DEBUG, ("Failed to alloc reassdata struct\n")); - return NULL; - } - } - memset(ipr, 0, sizeof(struct ip_reassdata)); - ipr->timer = IP_REASS_MAXAGE; - - /* enqueue the new structure to the front of the list */ - ipr->next = reassdatagrams; - reassdatagrams = ipr; - /* copy the ip header for later tests and input */ - /* @todo: no ip options supported? */ - SMEMCPY(&(ipr->iphdr), fraghdr, IP_HLEN); - return ipr; -} - -/** - * Dequeues a datagram from the datagram queue. Doesn't deallocate the pbufs. - * @param ipr points to the queue entry to dequeue - */ -static void -ip_reass_dequeue_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev) -{ - /* dequeue the reass struct */ - if (reassdatagrams == ipr) { - /* it was the first in the list */ - reassdatagrams = ipr->next; - } else { - /* it wasn't the first, so it must have a valid 'prev' */ - LWIP_ASSERT("sanity check linked list", prev != NULL); - prev->next = ipr->next; - } - - /* now we can free the ip_reassdata struct */ - memp_free(MEMP_REASSDATA, ipr); -} - -/** - * Chain a new pbuf into the pbuf list that composes the datagram. The pbuf list - * will grow over time as new pbufs are rx. - * Also checks that the datagram passes basic continuity checks (if the last - * fragment was received at least once). - * @param ipr points to the reassembly state - * @param new_p points to the pbuf for the current fragment - * @param is_last is 1 if this pbuf has MF==0 (ipr->flags not updated yet) - * @return see IP_REASS_VALIDATE_* defines - */ -static int -ip_reass_chain_frag_into_datagram_and_validate(struct ip_reassdata *ipr, struct pbuf *new_p, int is_last) -{ - struct ip_reass_helper *iprh, *iprh_tmp, *iprh_prev = NULL; - struct pbuf *q; - u16_t offset, len; - u8_t hlen; - struct ip_hdr *fraghdr; - int valid = 1; - - /* Extract length and fragment offset from current fragment */ - fraghdr = (struct ip_hdr *)new_p->payload; - len = lwip_ntohs(IPH_LEN(fraghdr)); - hlen = IPH_HL_BYTES(fraghdr); - if (hlen > len) { - /* invalid datagram */ - return IP_REASS_VALIDATE_PBUF_DROPPED; - } - len = (u16_t)(len - hlen); - offset = IPH_OFFSET_BYTES(fraghdr); - - /* overwrite the fragment's ip header from the pbuf with our helper struct, - * and setup the embedded helper structure. */ - /* make sure the struct ip_reass_helper fits into the IP header */ - LWIP_ASSERT("sizeof(struct ip_reass_helper) <= IP_HLEN", - sizeof(struct ip_reass_helper) <= IP_HLEN); - iprh = (struct ip_reass_helper *)new_p->payload; - iprh->next_pbuf = NULL; - iprh->start = offset; - iprh->end = (u16_t)(offset + len); - if (iprh->end < offset) { - /* u16_t overflow, cannot handle this */ - return IP_REASS_VALIDATE_PBUF_DROPPED; - } - - /* Iterate through until we either get to the end of the list (append), - * or we find one with a larger offset (insert). */ - for (q = ipr->p; q != NULL;) { - iprh_tmp = (struct ip_reass_helper *)q->payload; - if (iprh->start < iprh_tmp->start) { - /* the new pbuf should be inserted before this */ - iprh->next_pbuf = q; - if (iprh_prev != NULL) { - /* not the fragment with the lowest offset */ -#if IP_REASS_CHECK_OVERLAP - if ((iprh->start < iprh_prev->end) || (iprh->end > iprh_tmp->start)) { - /* fragment overlaps with previous or following, throw away */ - return IP_REASS_VALIDATE_PBUF_DROPPED; - } -#endif /* IP_REASS_CHECK_OVERLAP */ - iprh_prev->next_pbuf = new_p; - if (iprh_prev->end != iprh->start) { - /* There is a fragment missing between the current - * and the previous fragment */ - valid = 0; - } - } else { -#if IP_REASS_CHECK_OVERLAP - if (iprh->end > iprh_tmp->start) { - /* fragment overlaps with following, throw away */ - return IP_REASS_VALIDATE_PBUF_DROPPED; - } -#endif /* IP_REASS_CHECK_OVERLAP */ - /* fragment with the lowest offset */ - ipr->p = new_p; - } - break; - } else if (iprh->start == iprh_tmp->start) { - /* received the same datagram twice: no need to keep the datagram */ - return IP_REASS_VALIDATE_PBUF_DROPPED; -#if IP_REASS_CHECK_OVERLAP - } else if (iprh->start < iprh_tmp->end) { - /* overlap: no need to keep the new datagram */ - return IP_REASS_VALIDATE_PBUF_DROPPED; -#endif /* IP_REASS_CHECK_OVERLAP */ - } else { - /* Check if the fragments received so far have no holes. */ - if (iprh_prev != NULL) { - if (iprh_prev->end != iprh_tmp->start) { - /* There is a fragment missing between the current - * and the previous fragment */ - valid = 0; - } - } - } - q = iprh_tmp->next_pbuf; - iprh_prev = iprh_tmp; - } - - /* If q is NULL, then we made it to the end of the list. Determine what to do now */ - if (q == NULL) { - if (iprh_prev != NULL) { - /* this is (for now), the fragment with the highest offset: - * chain it to the last fragment */ -#if IP_REASS_CHECK_OVERLAP - LWIP_ASSERT("check fragments don't overlap", iprh_prev->end <= iprh->start); -#endif /* IP_REASS_CHECK_OVERLAP */ - iprh_prev->next_pbuf = new_p; - if (iprh_prev->end != iprh->start) { - valid = 0; - } - } else { -#if IP_REASS_CHECK_OVERLAP - LWIP_ASSERT("no previous fragment, this must be the first fragment!", - ipr->p == NULL); -#endif /* IP_REASS_CHECK_OVERLAP */ - /* this is the first fragment we ever received for this ip datagram */ - ipr->p = new_p; - } - } - - /* At this point, the validation part begins: */ - /* If we already received the last fragment */ - if (is_last || ((ipr->flags & IP_REASS_FLAG_LASTFRAG) != 0)) { - /* and had no holes so far */ - if (valid) { - /* then check if the rest of the fragments is here */ - /* Check if the queue starts with the first datagram */ - if ((ipr->p == NULL) || (((struct ip_reass_helper *)ipr->p->payload)->start != 0)) { - valid = 0; - } else { - /* and check that there are no holes after this datagram */ - iprh_prev = iprh; - q = iprh->next_pbuf; - while (q != NULL) { - iprh = (struct ip_reass_helper *)q->payload; - if (iprh_prev->end != iprh->start) { - valid = 0; - break; - } - iprh_prev = iprh; - q = iprh->next_pbuf; - } - /* if still valid, all fragments are received - * (because to the MF==0 already arrived */ - if (valid) { - LWIP_ASSERT("sanity check", ipr->p != NULL); - LWIP_ASSERT("sanity check", - ((struct ip_reass_helper *)ipr->p->payload) != iprh); - LWIP_ASSERT("validate_datagram:next_pbuf!=NULL", - iprh->next_pbuf == NULL); - } - } - } - /* If valid is 0 here, there are some fragments missing in the middle - * (since MF == 0 has already arrived). Such datagrams simply time out if - * no more fragments are received... */ - return valid ? IP_REASS_VALIDATE_TELEGRAM_FINISHED : IP_REASS_VALIDATE_PBUF_QUEUED; - } - /* If we come here, not all fragments were received, yet! */ - return IP_REASS_VALIDATE_PBUF_QUEUED; /* not yet valid! */ -} - -/** - * Reassembles incoming IP fragments into an IP datagram. - * - * @param p points to a pbuf chain of the fragment - * @return NULL if reassembly is incomplete, ? otherwise - */ -struct pbuf * -ip4_reass(struct pbuf *p) -{ - struct pbuf *r; - struct ip_hdr *fraghdr; - struct ip_reassdata *ipr; - struct ip_reass_helper *iprh; - u16_t offset, len, clen; - u8_t hlen; - int valid; - int is_last; - - IPFRAG_STATS_INC(ip_frag.recv); - MIB2_STATS_INC(mib2.ipreasmreqds); - - fraghdr = (struct ip_hdr *)p->payload; - - if (IPH_HL_BYTES(fraghdr) != IP_HLEN) { - LWIP_DEBUGF(IP_REASS_DEBUG, ("ip4_reass: IP options currently not supported!\n")); - IPFRAG_STATS_INC(ip_frag.err); - goto nullreturn; - } - - offset = IPH_OFFSET_BYTES(fraghdr); - len = lwip_ntohs(IPH_LEN(fraghdr)); - hlen = IPH_HL_BYTES(fraghdr); - if (hlen > len) { - /* invalid datagram */ - goto nullreturn; - } - len = (u16_t)(len - hlen); - - /* Check if we are allowed to enqueue more datagrams. */ - clen = pbuf_clen(p); - if ((ip_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS) { -#if IP_REASS_FREE_OLDEST - if (!ip_reass_remove_oldest_datagram(fraghdr, clen) || - ((ip_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS)) -#endif /* IP_REASS_FREE_OLDEST */ - { - /* No datagram could be freed and still too many pbufs enqueued */ - LWIP_DEBUGF(IP_REASS_DEBUG, ("ip4_reass: Overflow condition: pbufct=%d, clen=%d, MAX=%d\n", - ip_reass_pbufcount, clen, IP_REASS_MAX_PBUFS)); - IPFRAG_STATS_INC(ip_frag.memerr); - /* @todo: send ICMP time exceeded here? */ - /* drop this pbuf */ - goto nullreturn; - } - } - - /* Look for the datagram the fragment belongs to in the current datagram queue, - * remembering the previous in the queue for later dequeueing. */ - for (ipr = reassdatagrams; ipr != NULL; ipr = ipr->next) { - /* Check if the incoming fragment matches the one currently present - in the reassembly buffer. If so, we proceed with copying the - fragment into the buffer. */ - if (IP_ADDRESSES_AND_ID_MATCH(&ipr->iphdr, fraghdr)) { - LWIP_DEBUGF(IP_REASS_DEBUG, ("ip4_reass: matching previous fragment ID=%"X16_F"\n", - lwip_ntohs(IPH_ID(fraghdr)))); - IPFRAG_STATS_INC(ip_frag.cachehit); - break; - } - } - - if (ipr == NULL) { - /* Enqueue a new datagram into the datagram queue */ - ipr = ip_reass_enqueue_new_datagram(fraghdr, clen); - /* Bail if unable to enqueue */ - if (ipr == NULL) { - goto nullreturn; - } - } else { - if (((lwip_ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) == 0) && - ((lwip_ntohs(IPH_OFFSET(&ipr->iphdr)) & IP_OFFMASK) != 0)) { - /* ipr->iphdr is not the header from the first fragment, but fraghdr is - * -> copy fraghdr into ipr->iphdr since we want to have the header - * of the first fragment (for ICMP time exceeded and later, for copying - * all options, if supported)*/ - SMEMCPY(&ipr->iphdr, fraghdr, IP_HLEN); - } - } - - /* At this point, we have either created a new entry or pointing - * to an existing one */ - - /* check for 'no more fragments', and update queue entry*/ - is_last = (IPH_OFFSET(fraghdr) & PP_NTOHS(IP_MF)) == 0; - if (is_last) { - u16_t datagram_len = (u16_t)(offset + len); - if ((datagram_len < offset) || (datagram_len > (0xFFFF - IP_HLEN))) { - /* u16_t overflow, cannot handle this */ - goto nullreturn_ipr; - } - } - /* find the right place to insert this pbuf */ - /* @todo: trim pbufs if fragments are overlapping */ - valid = ip_reass_chain_frag_into_datagram_and_validate(ipr, p, is_last); - if (valid == IP_REASS_VALIDATE_PBUF_DROPPED) { - goto nullreturn_ipr; - } - /* if we come here, the pbuf has been enqueued */ - - /* Track the current number of pbufs current 'in-flight', in order to limit - the number of fragments that may be enqueued at any one time - (overflow checked by testing against IP_REASS_MAX_PBUFS) */ - ip_reass_pbufcount = (u16_t)(ip_reass_pbufcount + clen); - if (is_last) { - u16_t datagram_len = (u16_t)(offset + len); - ipr->datagram_len = datagram_len; - ipr->flags |= IP_REASS_FLAG_LASTFRAG; - LWIP_DEBUGF(IP_REASS_DEBUG, - ("ip4_reass: last fragment seen, total len %"S16_F"\n", - ipr->datagram_len)); - } - - if (valid == IP_REASS_VALIDATE_TELEGRAM_FINISHED) { - struct ip_reassdata *ipr_prev; - /* the totally last fragment (flag more fragments = 0) was received at least - * once AND all fragments are received */ - u16_t datagram_len = (u16_t)(ipr->datagram_len + IP_HLEN); - - /* save the second pbuf before copying the header over the pointer */ - r = ((struct ip_reass_helper *)ipr->p->payload)->next_pbuf; - - /* copy the original ip header back to the first pbuf */ - fraghdr = (struct ip_hdr *)(ipr->p->payload); - SMEMCPY(fraghdr, &ipr->iphdr, IP_HLEN); - IPH_LEN_SET(fraghdr, lwip_htons(datagram_len)); - IPH_OFFSET_SET(fraghdr, 0); - IPH_CHKSUM_SET(fraghdr, 0); - /* @todo: do we need to set/calculate the correct checksum? */ -#if CHECKSUM_GEN_IP - IF__NETIF_CHECKSUM_ENABLED(ip_current_input_netif(), NETIF_CHECKSUM_GEN_IP) { - IPH_CHKSUM_SET(fraghdr, inet_chksum(fraghdr, IP_HLEN)); - } -#endif /* CHECKSUM_GEN_IP */ - - p = ipr->p; - - /* chain together the pbufs contained within the reass_data list. */ - while (r != NULL) { - iprh = (struct ip_reass_helper *)r->payload; - - /* hide the ip header for every succeeding fragment */ - pbuf_remove_header(r, IP_HLEN); - pbuf_cat(p, r); - r = iprh->next_pbuf; - } - - /* find the previous entry in the linked list */ - if (ipr == reassdatagrams) { - ipr_prev = NULL; - } else { - for (ipr_prev = reassdatagrams; ipr_prev != NULL; ipr_prev = ipr_prev->next) { - if (ipr_prev->next == ipr) { - break; - } - } - } - - /* release the sources allocate for the fragment queue entry */ - ip_reass_dequeue_datagram(ipr, ipr_prev); - - /* and adjust the number of pbufs currently queued for reassembly. */ - clen = pbuf_clen(p); - LWIP_ASSERT("ip_reass_pbufcount >= clen", ip_reass_pbufcount >= clen); - ip_reass_pbufcount = (u16_t)(ip_reass_pbufcount - clen); - - MIB2_STATS_INC(mib2.ipreasmoks); - - /* Return the pbuf chain */ - return p; - } - /* the datagram is not (yet?) reassembled completely */ - LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass_pbufcount: %d out\n", ip_reass_pbufcount)); - return NULL; - -nullreturn_ipr: - LWIP_ASSERT("ipr != NULL", ipr != NULL); - if (ipr->p == NULL) { - /* dropped pbuf after creating a new datagram entry: remove the entry, too */ - LWIP_ASSERT("not firstalthough just enqueued", ipr == reassdatagrams); - ip_reass_dequeue_datagram(ipr, NULL); - } - -nullreturn: - LWIP_DEBUGF(IP_REASS_DEBUG, ("ip4_reass: nullreturn\n")); - IPFRAG_STATS_INC(ip_frag.drop); - pbuf_free(p); - return NULL; -} -#endif /* IP_REASSEMBLY */ - -#if IP_FRAG -#if !LWIP_NETIF_TX_SINGLE_PBUF -/** Allocate a new struct pbuf_custom_ref */ -static struct pbuf_custom_ref * -ip_frag_alloc_pbuf_custom_ref(void) -{ - return (struct pbuf_custom_ref *)memp_malloc(MEMP_FRAG_PBUF); -} - -/** Free a struct pbuf_custom_ref */ -static void -ip_frag_free_pbuf_custom_ref(struct pbuf_custom_ref *p) -{ - LWIP_ASSERT("p != NULL", p != NULL); - memp_free(MEMP_FRAG_PBUF, p); -} - -/** Free-callback function to free a 'struct pbuf_custom_ref', called by - * pbuf_free. */ -static void -ipfrag_free_pbuf_custom(struct pbuf *p) -{ - struct pbuf_custom_ref *pcr = (struct pbuf_custom_ref *)p; - LWIP_ASSERT("pcr != NULL", pcr != NULL); - LWIP_ASSERT("pcr == p", (void *)pcr == (void *)p); - if (pcr->original != NULL) { - pbuf_free(pcr->original); - } - ip_frag_free_pbuf_custom_ref(pcr); -} -#endif /* !LWIP_NETIF_TX_SINGLE_PBUF */ - -/** - * Fragment an IP datagram if too large for the netif. - * - * Chop the datagram in MTU sized chunks and send them in order - * by pointing PBUF_REFs into p. - * - * @param p ip packet to send - * @param netif the netif on which to send - * @param dest destination ip address to which to send - * - * @return ERR_OK if sent successfully, err_t otherwise - */ -err_t -ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest) -{ - struct pbuf *rambuf; -#if !LWIP_NETIF_TX_SINGLE_PBUF - struct pbuf *newpbuf; - u16_t newpbuflen = 0; - u16_t left_to_copy; -#endif - struct ip_hdr *original_iphdr; - struct ip_hdr *iphdr; - const u16_t nfb = (u16_t)((netif->mtu - IP_HLEN) / 8); - u16_t left, fragsize; - u16_t ofo; - int last; - u16_t poff = IP_HLEN; - u16_t tmp; - int mf_set; - - original_iphdr = (struct ip_hdr *)p->payload; - iphdr = original_iphdr; - if (IPH_HL_BYTES(iphdr) != IP_HLEN) { - /* ip4_frag() does not support IP options */ - return ERR_VAL; - } - LWIP_ERROR("ip4_frag(): pbuf too short", p->len >= IP_HLEN, return ERR_VAL); - - /* Save original offset */ - tmp = lwip_ntohs(IPH_OFFSET(iphdr)); - ofo = tmp & IP_OFFMASK; - /* already fragmented? if so, the last fragment we create must have MF, too */ - mf_set = tmp & IP_MF; - - left = (u16_t)(p->tot_len - IP_HLEN); - - while (left) { - /* Fill this fragment */ - fragsize = LWIP_MIN(left, (u16_t)(nfb * 8)); - -#if LWIP_NETIF_TX_SINGLE_PBUF - rambuf = pbuf_alloc(PBUF_IP, fragsize, PBUF_RAM); - if (rambuf == NULL) { - goto memerr; - } - LWIP_ASSERT("this needs a pbuf in one piece!", - (rambuf->len == rambuf->tot_len) && (rambuf->next == NULL)); - poff += pbuf_copy_partial(p, rambuf->payload, fragsize, poff); - /* make room for the IP header */ - if (pbuf_add_header(rambuf, IP_HLEN)) { - pbuf_free(rambuf); - goto memerr; - } - /* fill in the IP header */ - SMEMCPY(rambuf->payload, original_iphdr, IP_HLEN); - iphdr = (struct ip_hdr *)rambuf->payload; -#else /* LWIP_NETIF_TX_SINGLE_PBUF */ - /* When not using a static buffer, create a chain of pbufs. - * The first will be a PBUF_RAM holding the link and IP header. - * The rest will be PBUF_REFs mirroring the pbuf chain to be fragged, - * but limited to the size of an mtu. - */ - rambuf = pbuf_alloc(PBUF_LINK, IP_HLEN, PBUF_RAM); - if (rambuf == NULL) { - goto memerr; - } - LWIP_ASSERT("this needs a pbuf in one piece!", - (rambuf->len >= (IP_HLEN))); - SMEMCPY(rambuf->payload, original_iphdr, IP_HLEN); - iphdr = (struct ip_hdr *)rambuf->payload; - - left_to_copy = fragsize; - while (left_to_copy) { - struct pbuf_custom_ref *pcr; - u16_t plen = (u16_t)(p->len - poff); - LWIP_ASSERT("p->len >= poff", p->len >= poff); - newpbuflen = LWIP_MIN(left_to_copy, plen); - /* Is this pbuf already empty? */ - if (!newpbuflen) { - poff = 0; - p = p->next; - continue; - } - pcr = ip_frag_alloc_pbuf_custom_ref(); - if (pcr == NULL) { - pbuf_free(rambuf); - goto memerr; - } - /* Mirror this pbuf, although we might not need all of it. */ - newpbuf = pbuf_alloced_custom(PBUF_RAW, newpbuflen, PBUF_REF, &pcr->pc, - (u8_t *)p->payload + poff, newpbuflen); - if (newpbuf == NULL) { - ip_frag_free_pbuf_custom_ref(pcr); - pbuf_free(rambuf); - goto memerr; - } - pbuf_ref(p); - pcr->original = p; - pcr->pc.custom_free_function = ipfrag_free_pbuf_custom; - - /* Add it to end of rambuf's chain, but using pbuf_cat, not pbuf_chain - * so that it is removed when pbuf_dechain is later called on rambuf. - */ - pbuf_cat(rambuf, newpbuf); - left_to_copy = (u16_t)(left_to_copy - newpbuflen); - if (left_to_copy) { - poff = 0; - p = p->next; - } - } - poff = (u16_t)(poff + newpbuflen); -#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ - - /* Correct header */ - last = (left <= netif->mtu - IP_HLEN); - - /* Set new offset and MF flag */ - tmp = (IP_OFFMASK & (ofo)); - if (!last || mf_set) { - /* the last fragment has MF set if the input frame had it */ - tmp = tmp | IP_MF; - } - IPH_OFFSET_SET(iphdr, lwip_htons(tmp)); - IPH_LEN_SET(iphdr, lwip_htons((u16_t)(fragsize + IP_HLEN))); - IPH_CHKSUM_SET(iphdr, 0); -#if CHECKSUM_GEN_IP - IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) { - IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN)); - } -#endif /* CHECKSUM_GEN_IP */ - - /* No need for separate header pbuf - we allowed room for it in rambuf - * when allocated. - */ - netif->output(netif, rambuf, dest); - IPFRAG_STATS_INC(ip_frag.xmit); - - /* Unfortunately we can't reuse rambuf - the hardware may still be - * using the buffer. Instead we free it (and the ensuing chain) and - * recreate it next time round the loop. If we're lucky the hardware - * will have already sent the packet, the free will really free, and - * there will be zero memory penalty. - */ - - pbuf_free(rambuf); - left = (u16_t)(left - fragsize); - ofo = (u16_t)(ofo + nfb); - } - MIB2_STATS_INC(mib2.ipfragoks); - return ERR_OK; -memerr: - MIB2_STATS_INC(mib2.ipfragfails); - return ERR_MEM; -} -#endif /* IP_FRAG */ - -#endif /* LWIP_IPV4 */ diff --git a/third-party/lwip-2.1.2/core/ipv6/dhcp6.c b/third-party/lwip-2.1.2/core/ipv6/dhcp6.c deleted file mode 100644 index 7cf98a52..00000000 --- a/third-party/lwip-2.1.2/core/ipv6/dhcp6.c +++ /dev/null @@ -1,812 +0,0 @@ -/** - * @file - * - * @defgroup dhcp6 DHCPv6 - * @ingroup ip6 - * DHCPv6 client: IPv6 address autoconfiguration as per - * RFC 3315 (stateful DHCPv6) and - * RFC 3736 (stateless DHCPv6). - * - * For now, only stateless DHCPv6 is implemented! - * - * TODO: - * - enable/disable API to not always start when RA is received - * - stateful DHCPv6 (for now, only stateless DHCPv6 for DNS and NTP servers works) - * - create Client Identifier? - * - only start requests if a valid local address is available on the netif - * - only start information requests if required (not for every RA) - * - * dhcp6_enable_stateful() enables stateful DHCPv6 for a netif (stateless disabled)\n - * dhcp6_enable_stateless() enables stateless DHCPv6 for a netif (stateful disabled)\n - * dhcp6_disable() disable DHCPv6 for a netif - * - * When enabled, requests are only issued after receipt of RA with the - * corresponding bits set. - */ - -/* - * Copyright (c) 2018 Simon Goldschmidt - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Simon Goldschmidt - */ - -#include "lwip/opt.h" - -#if LWIP_IPV6 && LWIP_IPV6_DHCP6 /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/dhcp6.h" -#include "lwip/prot/dhcp6.h" -#include "lwip/def.h" -#include "lwip/udp.h" -#include "lwip/dns.h" - -#include - -#ifdef LWIP_HOOK_FILENAME -#include LWIP_HOOK_FILENAME -#endif -#ifndef LWIP_HOOK_DHCP6_APPEND_OPTIONS -#define LWIP_HOOK_DHCP6_APPEND_OPTIONS(netif, dhcp6, state, msg, msg_type, options_len_ptr, max_len) -#endif -#ifndef LWIP_HOOK_DHCP6_PARSE_OPTION -#define LWIP_HOOK_DHCP6_PARSE_OPTION(netif, dhcp6, state, msg, msg_type, option, len, pbuf, offset) do { LWIP_UNUSED_ARG(msg); } while(0) -#endif - -#if LWIP_DNS && LWIP_DHCP6_MAX_DNS_SERVERS -#if DNS_MAX_SERVERS > LWIP_DHCP6_MAX_DNS_SERVERS -#define LWIP_DHCP6_PROVIDE_DNS_SERVERS LWIP_DHCP6_MAX_DNS_SERVERS -#else -#define LWIP_DHCP6_PROVIDE_DNS_SERVERS DNS_MAX_SERVERS -#endif -#else -#define LWIP_DHCP6_PROVIDE_DNS_SERVERS 0 -#endif - - -/** Option handling: options are parsed in dhcp6_parse_reply - * and saved in an array where other functions can load them from. - * This might be moved into the struct dhcp6 (not necessarily since - * lwIP is single-threaded and the array is only used while in recv - * callback). */ -enum dhcp6_option_idx { - DHCP6_OPTION_IDX_CLI_ID = 0, - DHCP6_OPTION_IDX_SERVER_ID, -#if LWIP_DHCP6_PROVIDE_DNS_SERVERS - DHCP6_OPTION_IDX_DNS_SERVER, - DHCP6_OPTION_IDX_DOMAIN_LIST, -#endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS */ -#if LWIP_DHCP6_GET_NTP_SRV - DHCP6_OPTION_IDX_NTP_SERVER, -#endif /* LWIP_DHCP_GET_NTP_SRV */ - DHCP6_OPTION_IDX_MAX -}; - -struct dhcp6_option_info { - u8_t option_given; - u16_t val_start; - u16_t val_length; -}; - -/** Holds the decoded option info, only valid while in dhcp6_recv. */ -struct dhcp6_option_info dhcp6_rx_options[DHCP6_OPTION_IDX_MAX]; - -#define dhcp6_option_given(dhcp6, idx) (dhcp6_rx_options[idx].option_given != 0) -#define dhcp6_got_option(dhcp6, idx) (dhcp6_rx_options[idx].option_given = 1) -#define dhcp6_clear_option(dhcp6, idx) (dhcp6_rx_options[idx].option_given = 0) -#define dhcp6_clear_all_options(dhcp6) (memset(dhcp6_rx_options, 0, sizeof(dhcp6_rx_options))) -#define dhcp6_get_option_start(dhcp6, idx) (dhcp6_rx_options[idx].val_start) -#define dhcp6_get_option_length(dhcp6, idx) (dhcp6_rx_options[idx].val_length) -#define dhcp6_set_option(dhcp6, idx, start, len) do { dhcp6_rx_options[idx].val_start = (start); dhcp6_rx_options[idx].val_length = (len); }while(0) - - -const ip_addr_t dhcp6_All_DHCP6_Relay_Agents_and_Servers = IPADDR6_INIT_HOST(0xFF020000, 0, 0, 0x00010002); -const ip_addr_t dhcp6_All_DHCP6_Servers = IPADDR6_INIT_HOST(0xFF020000, 0, 0, 0x00010003); - -static struct udp_pcb *dhcp6_pcb; -static u8_t dhcp6_pcb_refcount; - - -/* receive, unfold, parse and free incoming messages */ -static void dhcp6_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port); - -/** Ensure DHCP PCB is allocated and bound */ -static err_t -dhcp6_inc_pcb_refcount(void) -{ - if (dhcp6_pcb_refcount == 0) { - LWIP_ASSERT("dhcp6_inc_pcb_refcount(): memory leak", dhcp6_pcb == NULL); - - /* allocate UDP PCB */ - dhcp6_pcb = udp_new_ip6(); - - if (dhcp6_pcb == NULL) { - return ERR_MEM; - } - - ip_set_option(dhcp6_pcb, SOF_BROADCAST); - - /* set up local and remote port for the pcb -> listen on all interfaces on all src/dest IPs */ - udp_bind(dhcp6_pcb, IP6_ADDR_ANY, DHCP6_CLIENT_PORT); - udp_recv(dhcp6_pcb, dhcp6_recv, NULL); - } - - dhcp6_pcb_refcount++; - - return ERR_OK; -} - -/** Free DHCP PCB if the last netif stops using it */ -static void -dhcp6_dec_pcb_refcount(void) -{ - LWIP_ASSERT("dhcp6_pcb_refcount(): refcount error", (dhcp6_pcb_refcount > 0)); - dhcp6_pcb_refcount--; - - if (dhcp6_pcb_refcount == 0) { - udp_remove(dhcp6_pcb); - dhcp6_pcb = NULL; - } -} - -/** - * @ingroup dhcp6 - * Set a statically allocated struct dhcp6 to work with. - * Using this prevents dhcp6_start to allocate it using mem_malloc. - * - * @param netif the netif for which to set the struct dhcp - * @param dhcp6 (uninitialised) dhcp6 struct allocated by the application - */ -void -dhcp6_set_struct(struct netif *netif, struct dhcp6 *dhcp6) -{ - LWIP_ASSERT("netif != NULL", netif != NULL); - LWIP_ASSERT("dhcp6 != NULL", dhcp6 != NULL); - LWIP_ASSERT("netif already has a struct dhcp6 set", netif_dhcp6_data(netif) == NULL); - - /* clear data structure */ - memset(dhcp6, 0, sizeof(struct dhcp6)); - /* dhcp6_set_state(&dhcp, DHCP6_STATE_OFF); */ - netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP6, dhcp6); -} - -/** - * @ingroup dhcp6 - * Removes a struct dhcp6 from a netif. - * - * ATTENTION: Only use this when not using dhcp6_set_struct() to allocate the - * struct dhcp6 since the memory is passed back to the heap. - * - * @param netif the netif from which to remove the struct dhcp - */ -void dhcp6_cleanup(struct netif *netif) -{ - LWIP_ASSERT("netif != NULL", netif != NULL); - - if (netif_dhcp6_data(netif) != NULL) { - mem_free(netif_dhcp6_data(netif)); - netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP6, NULL); - } -} - -static struct dhcp6* -dhcp6_get_struct(struct netif *netif, const char *dbg_requester) -{ - struct dhcp6 *dhcp6 = netif_dhcp6_data(netif); - if (dhcp6 == NULL) { - LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("%s: mallocing new DHCPv6 client\n", dbg_requester)); - dhcp6 = (struct dhcp6 *)mem_malloc(sizeof(struct dhcp6)); - if (dhcp6 == NULL) { - LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("%s: could not allocate dhcp6\n", dbg_requester)); - return NULL; - } - - /* clear data structure, this implies DHCP6_STATE_OFF */ - memset(dhcp6, 0, sizeof(struct dhcp6)); - /* store this dhcp6 client in the netif */ - netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP6, dhcp6); - } else { - /* already has DHCP6 client attached */ - LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("%s: using existing DHCPv6 client\n", dbg_requester)); - } - - if (!dhcp6->pcb_allocated) { - if (dhcp6_inc_pcb_refcount() != ERR_OK) { /* ensure DHCP6 PCB is allocated */ - mem_free(dhcp6); - netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP6, NULL); - return NULL; - } - LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("%s: allocated dhcp6", dbg_requester)); - dhcp6->pcb_allocated = 1; - } - return dhcp6; -} - -/* - * Set the DHCPv6 state - * If the state changed, reset the number of tries. - */ -static void -dhcp6_set_state(struct dhcp6 *dhcp6, u8_t new_state, const char *dbg_caller) -{ - LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("DHCPv6 state: %d -> %d (%s)\n", - dhcp6->state, new_state, dbg_caller)); - if (new_state != dhcp6->state) { - dhcp6->state = new_state; - dhcp6->tries = 0; - dhcp6->request_timeout = 0; - } -} - -static int -dhcp6_stateless_enabled(struct dhcp6 *dhcp6) -{ - if ((dhcp6->state == DHCP6_STATE_STATELESS_IDLE) || - (dhcp6->state == DHCP6_STATE_REQUESTING_CONFIG)) { - return 1; - } - return 0; -} - -/*static int -dhcp6_stateful_enabled(struct dhcp6 *dhcp6) -{ - if (dhcp6->state == DHCP6_STATE_OFF) { - return 0; - } - if (dhcp6_stateless_enabled(dhcp6)) { - return 0; - } - return 1; -}*/ - -/** - * @ingroup dhcp6 - * Enable stateful DHCPv6 on this netif - * Requests are sent on receipt of an RA message with the - * ND6_RA_FLAG_MANAGED_ADDR_CONFIG flag set. - * - * A struct dhcp6 will be allocated for this netif if not - * set via @ref dhcp6_set_struct before. - * - * @todo: stateful DHCPv6 not supported, yet - */ -err_t -dhcp6_enable_stateful(struct netif *netif) -{ - LWIP_UNUSED_ARG(netif); - LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("stateful dhcp6 not implemented yet")); - return ERR_VAL; -} - -/** - * @ingroup dhcp6 - * Enable stateless DHCPv6 on this netif - * Requests are sent on receipt of an RA message with the - * ND6_RA_FLAG_OTHER_CONFIG flag set. - * - * A struct dhcp6 will be allocated for this netif if not - * set via @ref dhcp6_set_struct before. - */ -err_t -dhcp6_enable_stateless(struct netif *netif) -{ - struct dhcp6 *dhcp6; - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp6_enable_stateless(netif=%p) %c%c%"U16_F"\n", (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); - - dhcp6 = dhcp6_get_struct(netif, "dhcp6_enable_stateless()"); - if (dhcp6 == NULL) { - return ERR_MEM; - } - if (dhcp6_stateless_enabled(dhcp6)) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp6_enable_stateless(): stateless DHCPv6 already enabled")); - return ERR_OK; - } else if (dhcp6->state != DHCP6_STATE_OFF) { - /* stateful running */ - /* @todo: stop stateful once it is implemented */ - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp6_enable_stateless(): switching from stateful to stateless DHCPv6")); - } - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp6_enable_stateless(): stateless DHCPv6 enabled\n")); - dhcp6_set_state(dhcp6, DHCP6_STATE_STATELESS_IDLE, "dhcp6_enable_stateless"); - return ERR_OK; -} - -/** - * @ingroup dhcp6 - * Disable stateful or stateless DHCPv6 on this netif - * Requests are sent on receipt of an RA message with the - * ND6_RA_FLAG_OTHER_CONFIG flag set. - */ -void -dhcp6_disable(struct netif *netif) -{ - struct dhcp6 *dhcp6; - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp6_disable(netif=%p) %c%c%"U16_F"\n", (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); - - dhcp6 = netif_dhcp6_data(netif); - if (dhcp6 != NULL) { - if (dhcp6->state != DHCP6_STATE_OFF) { - LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("dhcp6_disable(): DHCPv6 disabled (old state: %s)\n", - (dhcp6_stateless_enabled(dhcp6) ? "stateless" : "stateful"))); - dhcp6_set_state(dhcp6, DHCP6_STATE_OFF, "dhcp6_disable"); - if (dhcp6->pcb_allocated != 0) { - dhcp6_dec_pcb_refcount(); /* free DHCPv6 PCB if not needed any more */ - dhcp6->pcb_allocated = 0; - } - } - } -} - -/** - * Create a DHCPv6 request, fill in common headers - * - * @param netif the netif under DHCPv6 control - * @param dhcp6 dhcp6 control struct - * @param message_type message type of the request - * @param opt_len_alloc option length to allocate - * @param options_out_len option length on exit - * @return a pbuf for the message - */ -static struct pbuf * -dhcp6_create_msg(struct netif *netif, struct dhcp6 *dhcp6, u8_t message_type, - u16_t opt_len_alloc, u16_t *options_out_len) -{ - struct pbuf *p_out; - struct dhcp6_msg *msg_out; - - LWIP_ERROR("dhcp6_create_msg: netif != NULL", (netif != NULL), return NULL;); - LWIP_ERROR("dhcp6_create_msg: dhcp6 != NULL", (dhcp6 != NULL), return NULL;); - p_out = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcp6_msg) + opt_len_alloc, PBUF_RAM); - if (p_out == NULL) { - LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, - ("dhcp6_create_msg(): could not allocate pbuf\n")); - return NULL; - } - LWIP_ASSERT("dhcp6_create_msg: check that first pbuf can hold struct dhcp6_msg", - (p_out->len >= sizeof(struct dhcp6_msg) + opt_len_alloc)); - - /* @todo: limit new xid for certain message types? */ - /* reuse transaction identifier in retransmissions */ - if (dhcp6->tries == 0) { - dhcp6->xid = LWIP_RAND() & 0xFFFFFF; - } - - LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, - ("transaction id xid(%"X32_F")\n", dhcp6->xid)); - - msg_out = (struct dhcp6_msg *)p_out->payload; - memset(msg_out, 0, sizeof(struct dhcp6_msg) + opt_len_alloc); - - msg_out->msgtype = message_type; - msg_out->transaction_id[0] = (u8_t)(dhcp6->xid >> 16); - msg_out->transaction_id[1] = (u8_t)(dhcp6->xid >> 8); - msg_out->transaction_id[2] = (u8_t)dhcp6->xid; - *options_out_len = 0; - return p_out; -} - -static u16_t -dhcp6_option_short(u16_t options_out_len, u8_t *options, u16_t value) -{ - options[options_out_len++] = (u8_t)((value & 0xff00U) >> 8); - options[options_out_len++] = (u8_t) (value & 0x00ffU); - return options_out_len; -} - -static u16_t -dhcp6_option_optionrequest(u16_t options_out_len, u8_t *options, const u16_t *req_options, - u16_t num_req_options, u16_t max_len) -{ - size_t i; - u16_t ret; - - LWIP_ASSERT("dhcp6_option_optionrequest: options_out_len + sizeof(struct dhcp6_msg) + addlen <= max_len", - sizeof(struct dhcp6_msg) + options_out_len + 4U + (2U * num_req_options) <= max_len); - LWIP_UNUSED_ARG(max_len); - - ret = dhcp6_option_short(options_out_len, options, DHCP6_OPTION_ORO); - ret = dhcp6_option_short(ret, options, 2 * num_req_options); - for (i = 0; i < num_req_options; i++) { - ret = dhcp6_option_short(ret, options, req_options[i]); - } - return ret; -} - -/* All options are added, shrink the pbuf to the required size */ -static void -dhcp6_msg_finalize(u16_t options_out_len, struct pbuf *p_out) -{ - /* shrink the pbuf to the actual content length */ - pbuf_realloc(p_out, (u16_t)(sizeof(struct dhcp6_msg) + options_out_len)); -} - - -#if LWIP_IPV6_DHCP6_STATELESS -static void -dhcp6_information_request(struct netif *netif, struct dhcp6 *dhcp6) -{ - const u16_t requested_options[] = {DHCP6_OPTION_DNS_SERVERS, DHCP6_OPTION_DOMAIN_LIST, DHCP6_OPTION_SNTP_SERVERS}; - u16_t msecs; - struct pbuf *p_out; - u16_t options_out_len; - LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("dhcp6_information_request()\n")); - /* create and initialize the DHCP message header */ - p_out = dhcp6_create_msg(netif, dhcp6, DHCP6_INFOREQUEST, 4 + sizeof(requested_options), &options_out_len); - if (p_out != NULL) { - err_t err; - struct dhcp6_msg *msg_out = (struct dhcp6_msg *)p_out->payload; - u8_t *options = (u8_t *)(msg_out + 1); - LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("dhcp6_information_request: making request\n")); - - options_out_len = dhcp6_option_optionrequest(options_out_len, options, requested_options, - LWIP_ARRAYSIZE(requested_options), p_out->len); - LWIP_HOOK_DHCP6_APPEND_OPTIONS(netif, dhcp6, DHCP6_STATE_REQUESTING_CONFIG, msg_out, - DHCP6_INFOREQUEST, options_out_len, p_out->len); - dhcp6_msg_finalize(options_out_len, p_out); - - err = udp_sendto_if(dhcp6_pcb, p_out, &dhcp6_All_DHCP6_Relay_Agents_and_Servers, DHCP6_SERVER_PORT, netif); - pbuf_free(p_out); - LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp6_information_request: INFOREQUESTING -> %d\n", (int)err)); - LWIP_UNUSED_ARG(err); - } else { - LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp6_information_request: could not allocate DHCP6 request\n")); - } - dhcp6_set_state(dhcp6, DHCP6_STATE_REQUESTING_CONFIG, "dhcp6_information_request"); - if (dhcp6->tries < 255) { - dhcp6->tries++; - } - msecs = (u16_t)((dhcp6->tries < 6 ? 1 << dhcp6->tries : 60) * 1000); - dhcp6->request_timeout = (u16_t)((msecs + DHCP6_TIMER_MSECS - 1) / DHCP6_TIMER_MSECS); - LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp6_information_request(): set request timeout %"U16_F" msecs\n", msecs)); -} - -static err_t -dhcp6_request_config(struct netif *netif, struct dhcp6 *dhcp6) -{ - /* stateless mode enabled and no request running? */ - if (dhcp6->state == DHCP6_STATE_STATELESS_IDLE) { - /* send Information-request and wait for answer; setup receive timeout */ - dhcp6_information_request(netif, dhcp6); - } - - return ERR_OK; -} - -static void -dhcp6_abort_config_request(struct dhcp6 *dhcp6) -{ - if (dhcp6->state == DHCP6_STATE_REQUESTING_CONFIG) { - /* abort running request */ - dhcp6_set_state(dhcp6, DHCP6_STATE_STATELESS_IDLE, "dhcp6_abort_config_request"); - } -} - -/* Handle a REPLY to INFOREQUEST - * This parses DNS and NTP server addresses from the reply. - */ -static void -dhcp6_handle_config_reply(struct netif *netif, struct pbuf *p_msg_in) -{ - struct dhcp6 *dhcp6 = netif_dhcp6_data(netif); - - LWIP_UNUSED_ARG(dhcp6); - LWIP_UNUSED_ARG(p_msg_in); - -#if LWIP_DHCP6_PROVIDE_DNS_SERVERS - if (dhcp6_option_given(dhcp6, DHCP6_OPTION_IDX_DNS_SERVER)) { - ip_addr_t dns_addr; - ip6_addr_t *dns_addr6; - u16_t op_start = dhcp6_get_option_start(dhcp6, DHCP6_OPTION_IDX_DNS_SERVER); - u16_t op_len = dhcp6_get_option_length(dhcp6, DHCP6_OPTION_IDX_DNS_SERVER); - u16_t idx; - u8_t n; - - memset(&dns_addr, 0, sizeof(dns_addr)); - dns_addr6 = ip_2_ip6(&dns_addr); - for (n = 0, idx = op_start; (idx < op_start + op_len) && (n < LWIP_DHCP6_PROVIDE_DNS_SERVERS); - n++, idx += sizeof(struct ip6_addr_packed)) { - u16_t copied = pbuf_copy_partial(p_msg_in, dns_addr6, sizeof(struct ip6_addr_packed), idx); - if (copied != sizeof(struct ip6_addr_packed)) { - /* pbuf length mismatch */ - return; - } - ip6_addr_assign_zone(dns_addr6, IP6_UNKNOWN, netif); - /* @todo: do we need a different offset than DHCP(v4)? */ - dns_setserver(n, &dns_addr); - } - } - /* @ todo: parse and set Domain Search List */ -#endif /* LWIP_DHCP6_PROVIDE_DNS_SERVERS */ - -#if LWIP_DHCP6_GET_NTP_SRV - if (dhcp6_option_given(dhcp6, DHCP6_OPTION_IDX_NTP_SERVER)) { - ip_addr_t ntp_server_addrs[LWIP_DHCP6_MAX_NTP_SERVERS]; - u16_t op_start = dhcp6_get_option_start(dhcp6, DHCP6_OPTION_IDX_NTP_SERVER); - u16_t op_len = dhcp6_get_option_length(dhcp6, DHCP6_OPTION_IDX_NTP_SERVER); - u16_t idx; - u8_t n; - - for (n = 0, idx = op_start; (idx < op_start + op_len) && (n < LWIP_DHCP6_MAX_NTP_SERVERS); - n++, idx += sizeof(struct ip6_addr_packed)) { - u16_t copied; - ip6_addr_t *ntp_addr6 = ip_2_ip6(&ntp_server_addrs[n]); - ip_addr_set_zero_ip6(&ntp_server_addrs[n]); - copied = pbuf_copy_partial(p_msg_in, ntp_addr6, sizeof(struct ip6_addr_packed), idx); - if (copied != sizeof(struct ip6_addr_packed)) { - /* pbuf length mismatch */ - return; - } - ip6_addr_assign_zone(ntp_addr6, IP6_UNKNOWN, netif); - } - dhcp6_set_ntp_servers(n, ntp_server_addrs); - } -#endif /* LWIP_DHCP6_GET_NTP_SRV */ -} -#endif /* LWIP_IPV6_DHCP6_STATELESS */ - -/** This function is called from nd6 module when an RA messsage is received - * It triggers DHCPv6 requests (if enabled). - */ -void -dhcp6_nd6_ra_trigger(struct netif *netif, u8_t managed_addr_config, u8_t other_config) -{ - struct dhcp6 *dhcp6; - - LWIP_ASSERT("netif != NULL", netif != NULL); - dhcp6 = netif_dhcp6_data(netif); - - LWIP_UNUSED_ARG(managed_addr_config); - LWIP_UNUSED_ARG(other_config); - LWIP_UNUSED_ARG(dhcp6); - -#if LWIP_IPV6_DHCP6_STATELESS - if (dhcp6 != NULL) { - if (dhcp6_stateless_enabled(dhcp6)) { - if (other_config) { - dhcp6_request_config(netif, dhcp6); - } else { - dhcp6_abort_config_request(dhcp6); - } - } - } -#endif /* LWIP_IPV6_DHCP6_STATELESS */ -} - -/** - * Parse the DHCPv6 message and extract the DHCPv6 options. - * - * Extract the DHCPv6 options (offset + length) so that we can later easily - * check for them or extract the contents. - */ -static err_t -dhcp6_parse_reply(struct pbuf *p, struct dhcp6 *dhcp6) -{ - u16_t offset; - u16_t offset_max; - u16_t options_idx; - struct dhcp6_msg *msg_in; - - LWIP_UNUSED_ARG(dhcp6); - - /* clear received options */ - dhcp6_clear_all_options(dhcp6); - msg_in = (struct dhcp6_msg *)p->payload; - - /* parse options */ - - options_idx = sizeof(struct dhcp6_msg); - /* parse options to the end of the received packet */ - offset_max = p->tot_len; - - offset = options_idx; - /* at least 4 byte to read? */ - while ((offset + 4 <= offset_max)) { - u8_t op_len_buf[4]; - u8_t *op_len; - u16_t op; - u16_t len; - u16_t val_offset = (u16_t)(offset + 4); - if (val_offset < offset) { - /* overflow */ - return ERR_BUF; - } - /* copy option + length, might be split accross pbufs */ - op_len = (u8_t *)pbuf_get_contiguous(p, op_len_buf, 4, 4, offset); - if (op_len == NULL) { - /* failed to get option and length */ - return ERR_VAL; - } - op = (op_len[0] << 8) | op_len[1]; - len = (op_len[2] << 8) | op_len[3]; - offset = val_offset + len; - if (offset < val_offset) { - /* overflow */ - return ERR_BUF; - } - - switch (op) { - case (DHCP6_OPTION_CLIENTID): - dhcp6_got_option(dhcp6, DHCP6_OPTION_IDX_CLI_ID); - dhcp6_set_option(dhcp6, DHCP6_OPTION_IDX_CLI_ID, val_offset, len); - break; - case (DHCP6_OPTION_SERVERID): - dhcp6_got_option(dhcp6, DHCP6_OPTION_IDX_SERVER_ID); - dhcp6_set_option(dhcp6, DHCP6_OPTION_IDX_SERVER_ID, val_offset, len); - break; -#if LWIP_DHCP6_PROVIDE_DNS_SERVERS - case (DHCP6_OPTION_DNS_SERVERS): - dhcp6_got_option(dhcp6, DHCP6_OPTION_IDX_DNS_SERVER); - dhcp6_set_option(dhcp6, DHCP6_OPTION_IDX_DNS_SERVER, val_offset, len); - break; - case (DHCP6_OPTION_DOMAIN_LIST): - dhcp6_got_option(dhcp6, DHCP6_OPTION_IDX_DOMAIN_LIST); - dhcp6_set_option(dhcp6, DHCP6_OPTION_IDX_DOMAIN_LIST, val_offset, len); - break; -#endif /* LWIP_DHCP6_PROVIDE_DNS_SERVERS */ -#if LWIP_DHCP6_GET_NTP_SRV - case (DHCP6_OPTION_SNTP_SERVERS): - dhcp6_got_option(dhcp6, DHCP6_OPTION_IDX_NTP_SERVER); - dhcp6_set_option(dhcp6, DHCP6_OPTION_IDX_NTP_SERVER, val_offset, len); - break; -#endif /* LWIP_DHCP6_GET_NTP_SRV*/ - default: - LWIP_DEBUGF(DHCP6_DEBUG, ("skipping option %"U16_F" in options\n", op)); - LWIP_HOOK_DHCP6_PARSE_OPTION(ip_current_netif(), dhcp6, dhcp6->state, msg_in, - msg_in->msgtype, op, len, q, val_offset); - break; - } - } - return ERR_OK; -} - -static void -dhcp6_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) -{ - struct netif *netif = ip_current_input_netif(); - struct dhcp6 *dhcp6 = netif_dhcp6_data(netif); - struct dhcp6_msg *reply_msg = (struct dhcp6_msg *)p->payload; - u8_t msg_type; - u32_t xid; - - LWIP_UNUSED_ARG(arg); - - /* Caught DHCPv6 message from netif that does not have DHCPv6 enabled? -> not interested */ - if ((dhcp6 == NULL) || (dhcp6->pcb_allocated == 0)) { - goto free_pbuf_and_return; - } - - LWIP_ERROR("invalid server address type", IP_IS_V6(addr), goto free_pbuf_and_return;); - - LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("dhcp6_recv(pbuf = %p) from DHCPv6 server %s port %"U16_F"\n", (void *)p, - ipaddr_ntoa(addr), port)); - LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("pbuf->len = %"U16_F"\n", p->len)); - LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("pbuf->tot_len = %"U16_F"\n", p->tot_len)); - /* prevent warnings about unused arguments */ - LWIP_UNUSED_ARG(pcb); - LWIP_UNUSED_ARG(addr); - LWIP_UNUSED_ARG(port); - - if (p->len < sizeof(struct dhcp6_msg)) { - LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("DHCPv6 reply message or pbuf too short\n")); - goto free_pbuf_and_return; - } - - /* match transaction ID against what we expected */ - xid = reply_msg->transaction_id[0] << 16; - xid |= reply_msg->transaction_id[1] << 8; - xid |= reply_msg->transaction_id[2]; - if (xid != dhcp6->xid) { - LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, - ("transaction id mismatch reply_msg->xid(%"X32_F")!= dhcp6->xid(%"X32_F")\n", xid, dhcp6->xid)); - goto free_pbuf_and_return; - } - /* option fields could be unfold? */ - if (dhcp6_parse_reply(p, dhcp6) != ERR_OK) { - LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, - ("problem unfolding DHCPv6 message - too short on memory?\n")); - goto free_pbuf_and_return; - } - - /* read DHCP message type */ - msg_type = reply_msg->msgtype; - /* message type is DHCP6 REPLY? */ - if (msg_type == DHCP6_REPLY) { - LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("DHCP6_REPLY received\n")); -#if LWIP_IPV6_DHCP6_STATELESS - /* in info-requesting state? */ - if (dhcp6->state == DHCP6_STATE_REQUESTING_CONFIG) { - dhcp6_set_state(dhcp6, DHCP6_STATE_STATELESS_IDLE, "dhcp6_recv"); - dhcp6_handle_config_reply(netif, p); - } else -#endif /* LWIP_IPV6_DHCP6_STATELESS */ - { - /* @todo: handle reply in other states? */ - } - } else { - /* @todo: handle other message types */ - } - -free_pbuf_and_return: - pbuf_free(p); -} - -/** - * A DHCPv6 request has timed out. - * - * The timer that was started with the DHCPv6 request has - * timed out, indicating no response was received in time. - */ -static void -dhcp6_timeout(struct netif *netif, struct dhcp6 *dhcp6) -{ - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp6_timeout()\n")); - - LWIP_UNUSED_ARG(netif); - LWIP_UNUSED_ARG(dhcp6); - -#if LWIP_IPV6_DHCP6_STATELESS - /* back-off period has passed, or server selection timed out */ - if (dhcp6->state == DHCP6_STATE_REQUESTING_CONFIG) { - LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("dhcp6_timeout(): retrying information request\n")); - dhcp6_information_request(netif, dhcp6); - } -#endif /* LWIP_IPV6_DHCP6_STATELESS */ -} - -/** - * DHCPv6 timeout handling (this function must be called every 500ms, - * see @ref DHCP6_TIMER_MSECS). - * - * A DHCPv6 server is expected to respond within a short period of time. - * This timer checks whether an outstanding DHCPv6 request is timed out. - */ -void -dhcp6_tmr(void) -{ - struct netif *netif; - /* loop through netif's */ - NETIF_FOREACH(netif) { - struct dhcp6 *dhcp6 = netif_dhcp6_data(netif); - /* only act on DHCPv6 configured interfaces */ - if (dhcp6 != NULL) { - /* timer is active (non zero), and is about to trigger now */ - if (dhcp6->request_timeout > 1) { - dhcp6->request_timeout--; - } else if (dhcp6->request_timeout == 1) { - dhcp6->request_timeout--; - /* { dhcp6->request_timeout == 0 } */ - LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp6_tmr(): request timeout\n")); - /* this client's request timeout triggered */ - dhcp6_timeout(netif, dhcp6); - } - } - } -} - -#endif /* LWIP_IPV6 && LWIP_IPV6_DHCP6 */ diff --git a/third-party/lwip-2.1.2/core/ipv6/ethip6.c b/third-party/lwip-2.1.2/core/ipv6/ethip6.c deleted file mode 100644 index fec8b28a..00000000 --- a/third-party/lwip-2.1.2/core/ipv6/ethip6.c +++ /dev/null @@ -1,123 +0,0 @@ -/** - * @file - * - * Ethernet output for IPv6. Uses ND tables for link-layer addressing. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -#include "lwip/opt.h" - -#if LWIP_IPV6 && LWIP_ETHERNET - -#include "lwip/ethip6.h" -#include "lwip/nd6.h" -#include "lwip/pbuf.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#include "lwip/inet_chksum.h" -#include "lwip/netif.h" -#include "lwip/icmp6.h" -#include "lwip/prot/ethernet.h" -#include "netif/ethernet.h" - -#include - -/** - * Resolve and fill-in Ethernet address header for outgoing IPv6 packet. - * - * For IPv6 multicast, corresponding Ethernet addresses - * are selected and the packet is transmitted on the link. - * - * For unicast addresses, ask the ND6 module what to do. It will either let us - * send the the packet right away, or queue the packet for later itself, unless - * an error occurs. - * - * @todo anycast addresses - * - * @param netif The lwIP network interface which the IP packet will be sent on. - * @param q The pbuf(s) containing the IP packet to be sent. - * @param ip6addr The IP address of the packet destination. - * - * @return - * - ERR_OK or the return value of @ref nd6_get_next_hop_addr_or_queue. - */ -err_t -ethip6_output(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr) -{ - struct eth_addr dest; - const u8_t *hwaddr; - err_t result; - - LWIP_ASSERT_CORE_LOCKED(); - - /* The destination IP address must be properly zoned from here on down. */ - IP6_ADDR_ZONECHECK_NETIF(ip6addr, netif); - - /* multicast destination IP address? */ - if (ip6_addr_ismulticast(ip6addr)) { - /* Hash IP multicast address to MAC address.*/ - dest.addr[0] = 0x33; - dest.addr[1] = 0x33; - dest.addr[2] = ((const u8_t *)(&(ip6addr->addr[3])))[0]; - dest.addr[3] = ((const u8_t *)(&(ip6addr->addr[3])))[1]; - dest.addr[4] = ((const u8_t *)(&(ip6addr->addr[3])))[2]; - dest.addr[5] = ((const u8_t *)(&(ip6addr->addr[3])))[3]; - - /* Send out. */ - return ethernet_output(netif, q, (const struct eth_addr*)(netif->hwaddr), &dest, ETHTYPE_IPV6); - } - - /* We have a unicast destination IP address */ - /* @todo anycast? */ - - /* Ask ND6 what to do with the packet. */ - result = nd6_get_next_hop_addr_or_queue(netif, q, ip6addr, &hwaddr); - if (result != ERR_OK) { - return result; - } - - /* If no hardware address is returned, nd6 has queued the packet for later. */ - if (hwaddr == NULL) { - return ERR_OK; - } - - /* Send out the packet using the returned hardware address. */ - SMEMCPY(dest.addr, hwaddr, 6); - return ethernet_output(netif, q, (const struct eth_addr*)(netif->hwaddr), &dest, ETHTYPE_IPV6); -} - -#endif /* LWIP_IPV6 && LWIP_ETHERNET */ diff --git a/third-party/lwip-2.1.2/core/ipv6/icmp6.c b/third-party/lwip-2.1.2/core/ipv6/icmp6.c deleted file mode 100644 index 167738a0..00000000 --- a/third-party/lwip-2.1.2/core/ipv6/icmp6.c +++ /dev/null @@ -1,425 +0,0 @@ -/** - * @file - * - * IPv6 version of ICMP, as per RFC 4443. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -#include "lwip/opt.h" - -#if LWIP_ICMP6 && LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/icmp6.h" -#include "lwip/prot/icmp6.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#include "lwip/inet_chksum.h" -#include "lwip/pbuf.h" -#include "lwip/netif.h" -#include "lwip/nd6.h" -#include "lwip/mld6.h" -#include "lwip/ip.h" -#include "lwip/stats.h" - -#include - -#if LWIP_ICMP6_DATASIZE == 0 -#undef LWIP_ICMP6_DATASIZE -#define LWIP_ICMP6_DATASIZE 8 -#endif - -/* Forward declarations */ -static void icmp6_send_response(struct pbuf *p, u8_t code, u32_t data, u8_t type); -static void icmp6_send_response_with_addrs(struct pbuf *p, u8_t code, u32_t data, - u8_t type, const ip6_addr_t *src_addr, const ip6_addr_t *dest_addr); -static void icmp6_send_response_with_addrs_and_netif(struct pbuf *p, u8_t code, u32_t data, - u8_t type, const ip6_addr_t *src_addr, const ip6_addr_t *dest_addr, struct netif *netif); - - -/** - * Process an input ICMPv6 message. Called by ip6_input. - * - * Will generate a reply for echo requests. Other messages are forwarded - * to nd6_input, or mld6_input. - * - * @param p the mld packet, p->payload pointing to the icmpv6 header - * @param inp the netif on which this packet was received - */ -void -icmp6_input(struct pbuf *p, struct netif *inp) -{ - struct icmp6_hdr *icmp6hdr; - struct pbuf *r; - const ip6_addr_t *reply_src; - - ICMP6_STATS_INC(icmp6.recv); - - /* Check that ICMPv6 header fits in payload */ - if (p->len < sizeof(struct icmp6_hdr)) { - /* drop short packets */ - pbuf_free(p); - ICMP6_STATS_INC(icmp6.lenerr); - ICMP6_STATS_INC(icmp6.drop); - return; - } - - icmp6hdr = (struct icmp6_hdr *)p->payload; - -#if CHECKSUM_CHECK_ICMP6 - IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_ICMP6) { - if (ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->tot_len, ip6_current_src_addr(), - ip6_current_dest_addr()) != 0) { - /* Checksum failed */ - pbuf_free(p); - ICMP6_STATS_INC(icmp6.chkerr); - ICMP6_STATS_INC(icmp6.drop); - return; - } - } -#endif /* CHECKSUM_CHECK_ICMP6 */ - - switch (icmp6hdr->type) { - case ICMP6_TYPE_NA: /* Neighbor advertisement */ - case ICMP6_TYPE_NS: /* Neighbor solicitation */ - case ICMP6_TYPE_RA: /* Router advertisement */ - case ICMP6_TYPE_RD: /* Redirect */ - case ICMP6_TYPE_PTB: /* Packet too big */ - nd6_input(p, inp); - return; - case ICMP6_TYPE_RS: -#if LWIP_IPV6_FORWARD - /* @todo implement router functionality */ -#endif - break; -#if LWIP_IPV6_MLD - case ICMP6_TYPE_MLQ: - case ICMP6_TYPE_MLR: - case ICMP6_TYPE_MLD: - mld6_input(p, inp); - return; -#endif - case ICMP6_TYPE_EREQ: -#if !LWIP_MULTICAST_PING - /* multicast destination address? */ - if (ip6_addr_ismulticast(ip6_current_dest_addr())) { - /* drop */ - pbuf_free(p); - ICMP6_STATS_INC(icmp6.drop); - return; - } -#endif /* LWIP_MULTICAST_PING */ - - /* Allocate reply. */ - r = pbuf_alloc(PBUF_IP, p->tot_len, PBUF_RAM); - if (r == NULL) { - /* drop */ - pbuf_free(p); - ICMP6_STATS_INC(icmp6.memerr); - return; - } - - /* Copy echo request. */ - if (pbuf_copy(r, p) != ERR_OK) { - /* drop */ - pbuf_free(p); - pbuf_free(r); - ICMP6_STATS_INC(icmp6.err); - return; - } - - /* Determine reply source IPv6 address. */ -#if LWIP_MULTICAST_PING - if (ip6_addr_ismulticast(ip6_current_dest_addr())) { - reply_src = ip_2_ip6(ip6_select_source_address(inp, ip6_current_src_addr())); - if (reply_src == NULL) { - /* drop */ - pbuf_free(p); - pbuf_free(r); - ICMP6_STATS_INC(icmp6.rterr); - return; - } - } - else -#endif /* LWIP_MULTICAST_PING */ - { - reply_src = ip6_current_dest_addr(); - } - - /* Set fields in reply. */ - ((struct icmp6_echo_hdr *)(r->payload))->type = ICMP6_TYPE_EREP; - ((struct icmp6_echo_hdr *)(r->payload))->chksum = 0; -#if CHECKSUM_GEN_ICMP6 - IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_ICMP6) { - ((struct icmp6_echo_hdr *)(r->payload))->chksum = ip6_chksum_pseudo(r, - IP6_NEXTH_ICMP6, r->tot_len, reply_src, ip6_current_src_addr()); - } -#endif /* CHECKSUM_GEN_ICMP6 */ - - /* Send reply. */ - ICMP6_STATS_INC(icmp6.xmit); - ip6_output_if(r, reply_src, ip6_current_src_addr(), - LWIP_ICMP6_HL, 0, IP6_NEXTH_ICMP6, inp); - pbuf_free(r); - - break; - default: - ICMP6_STATS_INC(icmp6.proterr); - ICMP6_STATS_INC(icmp6.drop); - break; - } - - pbuf_free(p); -} - - -/** - * Send an icmpv6 'destination unreachable' packet. - * - * This function must be used only in direct response to a packet that is being - * received right now. Otherwise, address zones would be lost. - * - * @param p the input packet for which the 'unreachable' should be sent, - * p->payload pointing to the IPv6 header - * @param c ICMPv6 code for the unreachable type - */ -void -icmp6_dest_unreach(struct pbuf *p, enum icmp6_dur_code c) -{ - icmp6_send_response(p, c, 0, ICMP6_TYPE_DUR); -} - -/** - * Send an icmpv6 'packet too big' packet. - * - * This function must be used only in direct response to a packet that is being - * received right now. Otherwise, address zones would be lost. - * - * @param p the input packet for which the 'packet too big' should be sent, - * p->payload pointing to the IPv6 header - * @param mtu the maximum mtu that we can accept - */ -void -icmp6_packet_too_big(struct pbuf *p, u32_t mtu) -{ - icmp6_send_response(p, 0, mtu, ICMP6_TYPE_PTB); -} - -/** - * Send an icmpv6 'time exceeded' packet. - * - * This function must be used only in direct response to a packet that is being - * received right now. Otherwise, address zones would be lost. - * - * @param p the input packet for which the 'time exceeded' should be sent, - * p->payload pointing to the IPv6 header - * @param c ICMPv6 code for the time exceeded type - */ -void -icmp6_time_exceeded(struct pbuf *p, enum icmp6_te_code c) -{ - icmp6_send_response(p, c, 0, ICMP6_TYPE_TE); -} - -/** - * Send an icmpv6 'time exceeded' packet, with explicit source and destination - * addresses. - * - * This function may be used to send a response sometime after receiving the - * packet for which this response is meant. The provided source and destination - * addresses are used primarily to retain their zone information. - * - * @param p the input packet for which the 'time exceeded' should be sent, - * p->payload pointing to the IPv6 header - * @param c ICMPv6 code for the time exceeded type - * @param src_addr source address of the original packet, with zone information - * @param dest_addr destination address of the original packet, with zone - * information - */ -void -icmp6_time_exceeded_with_addrs(struct pbuf *p, enum icmp6_te_code c, - const ip6_addr_t *src_addr, const ip6_addr_t *dest_addr) -{ - icmp6_send_response_with_addrs(p, c, 0, ICMP6_TYPE_TE, src_addr, dest_addr); -} - -/** - * Send an icmpv6 'parameter problem' packet. - * - * This function must be used only in direct response to a packet that is being - * received right now. Otherwise, address zones would be lost and the calculated - * offset would be wrong (calculated against ip6_current_header()). - * - * @param p the input packet for which the 'param problem' should be sent, - * p->payload pointing to the IP header - * @param c ICMPv6 code for the param problem type - * @param pointer the pointer to the byte where the parameter is found - */ -void -icmp6_param_problem(struct pbuf *p, enum icmp6_pp_code c, const void *pointer) -{ - u32_t pointer_u32 = (u32_t)((const u8_t *)pointer - (const u8_t *)ip6_current_header()); - icmp6_send_response(p, c, pointer_u32, ICMP6_TYPE_PP); -} - -/** - * Send an ICMPv6 packet in response to an incoming packet. - * The packet is sent *to* ip_current_src_addr() on ip_current_netif(). - * - * @param p the input packet for which the response should be sent, - * p->payload pointing to the IPv6 header - * @param code Code of the ICMPv6 header - * @param data Additional 32-bit parameter in the ICMPv6 header - * @param type Type of the ICMPv6 header - */ -static void -icmp6_send_response(struct pbuf *p, u8_t code, u32_t data, u8_t type) -{ - const struct ip6_addr *reply_src, *reply_dest; - struct netif *netif = ip_current_netif(); - - LWIP_ASSERT("icmpv6 packet not a direct response", netif != NULL); - reply_dest = ip6_current_src_addr(); - - /* Select an address to use as source. */ - reply_src = ip_2_ip6(ip6_select_source_address(netif, reply_dest)); - if (reply_src == NULL) { - ICMP6_STATS_INC(icmp6.rterr); - return; - } - icmp6_send_response_with_addrs_and_netif(p, code, data, type, reply_src, reply_dest, netif); -} - -/** - * Send an ICMPv6 packet in response to an incoming packet. - * - * Call this function if the packet is NOT sent as a direct response to an - * incoming packet, but rather sometime later (e.g. for a fragment reassembly - * timeout). The caller must provide the zoned source and destination addresses - * from the original packet with the src_addr and dest_addr parameters. The - * reason for this approach is that while the addresses themselves are part of - * the original packet, their zone information is not, thus possibly resulting - * in a link-local response being sent over the wrong link. - * - * @param p the input packet for which the response should be sent, - * p->payload pointing to the IPv6 header - * @param code Code of the ICMPv6 header - * @param data Additional 32-bit parameter in the ICMPv6 header - * @param type Type of the ICMPv6 header - * @param src_addr original source address - * @param dest_addr original destination address - */ -static void -icmp6_send_response_with_addrs(struct pbuf *p, u8_t code, u32_t data, u8_t type, - const ip6_addr_t *src_addr, const ip6_addr_t *dest_addr) -{ - const struct ip6_addr *reply_src, *reply_dest; - struct netif *netif; - - /* Get the destination address and netif for this ICMP message. */ - LWIP_ASSERT("must provide both source and destination", src_addr != NULL); - LWIP_ASSERT("must provide both source and destination", dest_addr != NULL); - - /* Special case, as ip6_current_xxx is either NULL, or points - to a different packet than the one that expired. */ - IP6_ADDR_ZONECHECK(src_addr); - IP6_ADDR_ZONECHECK(dest_addr); - /* Swap source and destination for the reply. */ - reply_dest = src_addr; - reply_src = dest_addr; - netif = ip6_route(reply_src, reply_dest); - if (netif == NULL) { - ICMP6_STATS_INC(icmp6.rterr); - return; - } - icmp6_send_response_with_addrs_and_netif(p, code, data, type, reply_src, - reply_dest, netif); -} - -/** - * Send an ICMPv6 packet (with srd/dst address and netif given). - * - * @param p the input packet for which the response should be sent, - * p->payload pointing to the IPv6 header - * @param code Code of the ICMPv6 header - * @param data Additional 32-bit parameter in the ICMPv6 header - * @param type Type of the ICMPv6 header - * @param reply_src source address of the packet to send - * @param reply_dest destination address of the packet to send - * @param netif netif to send the packet - */ -static void -icmp6_send_response_with_addrs_and_netif(struct pbuf *p, u8_t code, u32_t data, u8_t type, - const ip6_addr_t *reply_src, const ip6_addr_t *reply_dest, struct netif *netif) -{ - struct pbuf *q; - struct icmp6_hdr *icmp6hdr; - - /* ICMPv6 header + IPv6 header + data */ - q = pbuf_alloc(PBUF_IP, sizeof(struct icmp6_hdr) + IP6_HLEN + LWIP_ICMP6_DATASIZE, - PBUF_RAM); - if (q == NULL) { - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded: failed to allocate pbuf for ICMPv6 packet.\n")); - ICMP6_STATS_INC(icmp6.memerr); - return; - } - LWIP_ASSERT("check that first pbuf can hold icmp 6message", - (q->len >= (sizeof(struct icmp6_hdr) + IP6_HLEN + LWIP_ICMP6_DATASIZE))); - - icmp6hdr = (struct icmp6_hdr *)q->payload; - icmp6hdr->type = type; - icmp6hdr->code = code; - icmp6hdr->data = lwip_htonl(data); - - /* copy fields from original packet */ - SMEMCPY((u8_t *)q->payload + sizeof(struct icmp6_hdr), (u8_t *)p->payload, - IP6_HLEN + LWIP_ICMP6_DATASIZE); - - /* calculate checksum */ - icmp6hdr->chksum = 0; -#if CHECKSUM_GEN_ICMP6 - IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP6) { - icmp6hdr->chksum = ip6_chksum_pseudo(q, IP6_NEXTH_ICMP6, q->tot_len, - reply_src, reply_dest); - } -#endif /* CHECKSUM_GEN_ICMP6 */ - - ICMP6_STATS_INC(icmp6.xmit); - ip6_output_if(q, reply_src, reply_dest, LWIP_ICMP6_HL, 0, IP6_NEXTH_ICMP6, netif); - pbuf_free(q); -} - -#endif /* LWIP_ICMP6 && LWIP_IPV6 */ diff --git a/third-party/lwip-2.1.2/core/ipv6/inet6.c b/third-party/lwip-2.1.2/core/ipv6/inet6.c deleted file mode 100644 index d9a992c2..00000000 --- a/third-party/lwip-2.1.2/core/ipv6/inet6.c +++ /dev/null @@ -1,53 +0,0 @@ -/** - * @file - * - * INET v6 addresses. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -#include "lwip/opt.h" - -#if LWIP_IPV6 && LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/def.h" -#include "lwip/inet.h" - -/** This variable is initialized by the system to contain the wildcard IPv6 address. - */ -const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; - -#endif /* LWIP_IPV6 */ diff --git a/third-party/lwip-2.1.2/core/ipv6/ip6.c b/third-party/lwip-2.1.2/core/ipv6/ip6.c deleted file mode 100644 index eda11dc8..00000000 --- a/third-party/lwip-2.1.2/core/ipv6/ip6.c +++ /dev/null @@ -1,1492 +0,0 @@ -/** - * @file - * - * IPv6 layer. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -#include "lwip/opt.h" - -#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/def.h" -#include "lwip/mem.h" -#include "lwip/netif.h" -#include "lwip/ip.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#include "lwip/ip6_frag.h" -#include "lwip/icmp6.h" -#include "lwip/priv/raw_priv.h" -#include "lwip/udp.h" -#include "lwip/priv/tcp_priv.h" -#include "lwip/dhcp6.h" -#include "lwip/nd6.h" -#include "lwip/mld6.h" -#include "lwip/debug.h" -#include "lwip/stats.h" - -#ifdef LWIP_HOOK_FILENAME -#include LWIP_HOOK_FILENAME -#endif - -/** - * Finds the appropriate network interface for a given IPv6 address. It tries to select - * a netif following a sequence of heuristics: - * 1) if there is only 1 netif, return it - * 2) if the destination is a zoned address, match its zone to a netif - * 3) if the either the source or destination address is a scoped address, - * match the source address's zone (if set) or address (if not) to a netif - * 4) tries to match the destination subnet to a configured address - * 5) tries to find a router-announced route - * 6) tries to match the (unscoped) source address to the netif - * 7) returns the default netif, if configured - * - * Note that each of the two given addresses may or may not be properly zoned. - * - * @param src the source IPv6 address, if known - * @param dest the destination IPv6 address for which to find the route - * @return the netif on which to send to reach dest - */ -struct netif * -ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest) -{ -#if LWIP_SINGLE_NETIF - LWIP_UNUSED_ARG(src); - LWIP_UNUSED_ARG(dest); -#else /* LWIP_SINGLE_NETIF */ - struct netif *netif; - s8_t i; - - LWIP_ASSERT_CORE_LOCKED(); - - /* If single netif configuration, fast return. */ - if ((netif_list != NULL) && (netif_list->next == NULL)) { - if (!netif_is_up(netif_list) || !netif_is_link_up(netif_list) || - (ip6_addr_has_zone(dest) && !ip6_addr_test_zone(dest, netif_list))) { - return NULL; - } - return netif_list; - } - -#if LWIP_IPV6_SCOPES - /* Special processing for zoned destination addresses. This includes link- - * local unicast addresses and interface/link-local multicast addresses. Use - * the zone to find a matching netif. If the address is not zoned, then there - * is technically no "wrong" netif to choose, and we leave routing to other - * rules; in most cases this should be the scoped-source rule below. */ - if (ip6_addr_has_zone(dest)) { - IP6_ADDR_ZONECHECK(dest); - /* Find a netif based on the zone. For custom mappings, one zone may map - * to multiple netifs, so find one that can actually send a packet. */ - NETIF_FOREACH(netif) { - if (ip6_addr_test_zone(dest, netif) && - netif_is_up(netif) && netif_is_link_up(netif)) { - return netif; - } - } - /* No matching netif found. Do no try to route to a different netif, - * as that would be a zone violation, resulting in any packets sent to - * that netif being dropped on output. */ - return NULL; - } -#endif /* LWIP_IPV6_SCOPES */ - - /* Special processing for scoped source and destination addresses. If we get - * here, the destination address does not have a zone, so either way we need - * to look at the source address, which may or may not have a zone. If it - * does, the zone is restrictive: there is (typically) only one matching - * netif for it, and we should avoid routing to any other netif as that would - * result in guaranteed zone violations. For scoped source addresses that do - * not have a zone, use (only) a netif that has that source address locally - * assigned. This case also applies to the loopback source address, which has - * an implied link-local scope. If only the destination address is scoped - * (but, again, not zoned), we still want to use only the source address to - * determine its zone because that's most likely what the user/application - * wants, regardless of whether the source address is scoped. Finally, some - * of this story also applies if scoping is disabled altogether. */ -#if LWIP_IPV6_SCOPES - if (ip6_addr_has_scope(dest, IP6_UNKNOWN) || - ip6_addr_has_scope(src, IP6_UNICAST) || -#else /* LWIP_IPV6_SCOPES */ - if (ip6_addr_islinklocal(dest) || ip6_addr_ismulticast_iflocal(dest) || - ip6_addr_ismulticast_linklocal(dest) || ip6_addr_islinklocal(src) || -#endif /* LWIP_IPV6_SCOPES */ - ip6_addr_isloopback(src)) { -#if LWIP_IPV6_SCOPES - if (ip6_addr_has_zone(src)) { - /* Find a netif matching the source zone (relatively cheap). */ - NETIF_FOREACH(netif) { - if (netif_is_up(netif) && netif_is_link_up(netif) && - ip6_addr_test_zone(src, netif)) { - return netif; - } - } - } else -#endif /* LWIP_IPV6_SCOPES */ - { - /* Find a netif matching the source address (relatively expensive). */ - NETIF_FOREACH(netif) { - if (!netif_is_up(netif) || !netif_is_link_up(netif)) { - continue; - } - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && - ip6_addr_cmp_zoneless(src, netif_ip6_addr(netif, i))) { - return netif; - } - } - } - } - /* Again, do not use any other netif in this case, as that could result in - * zone boundary violations. */ - return NULL; - } - - /* We come here only if neither source nor destination is scoped. */ - IP6_ADDR_ZONECHECK(src); - -#ifdef LWIP_HOOK_IP6_ROUTE - netif = LWIP_HOOK_IP6_ROUTE(src, dest); - if (netif != NULL) { - return netif; - } -#endif - - /* See if the destination subnet matches a configured address. In accordance - * with RFC 5942, dynamically configured addresses do not have an implied - * local subnet, and thus should be considered /128 assignments. However, as - * such, the destination address may still match a local address, and so we - * still need to check for exact matches here. By (lwIP) policy, statically - * configured addresses do always have an implied local /64 subnet. */ - NETIF_FOREACH(netif) { - if (!netif_is_up(netif) || !netif_is_link_up(netif)) { - continue; - } - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && - ip6_addr_netcmp(dest, netif_ip6_addr(netif, i)) && - (netif_ip6_addr_isstatic(netif, i) || - ip6_addr_nethostcmp(dest, netif_ip6_addr(netif, i)))) { - return netif; - } - } - } - - /* Get the netif for a suitable router-announced route. */ - netif = nd6_find_route(dest); - if (netif != NULL) { - return netif; - } - - /* Try with the netif that matches the source address. Given the earlier rule - * for scoped source addresses, this applies to unscoped addresses only. */ - if (!ip6_addr_isany(src)) { - NETIF_FOREACH(netif) { - if (!netif_is_up(netif) || !netif_is_link_up(netif)) { - continue; - } - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && - ip6_addr_cmp(src, netif_ip6_addr(netif, i))) { - return netif; - } - } - } - } - -#if LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF - /* loopif is disabled, loopback traffic is passed through any netif */ - if (ip6_addr_isloopback(dest)) { - /* don't check for link on loopback traffic */ - if (netif_default != NULL && netif_is_up(netif_default)) { - return netif_default; - } - /* default netif is not up, just use any netif for loopback traffic */ - NETIF_FOREACH(netif) { - if (netif_is_up(netif)) { - return netif; - } - } - return NULL; - } -#endif /* LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF */ -#endif /* !LWIP_SINGLE_NETIF */ - - /* no matching netif found, use default netif, if up */ - if ((netif_default == NULL) || !netif_is_up(netif_default) || !netif_is_link_up(netif_default)) { - return NULL; - } - return netif_default; -} - -/** - * @ingroup ip6 - * Select the best IPv6 source address for a given destination IPv6 address. - * - * This implementation follows RFC 6724 Sec. 5 to the following extent: - * - Rules 1, 2, 3: fully implemented - * - Rules 4, 5, 5.5: not applicable - * - Rule 6: not implemented - * - Rule 7: not applicable - * - Rule 8: limited to "prefer /64 subnet match over non-match" - * - * For Rule 2, we deliberately deviate from RFC 6724 Sec. 3.1 by considering - * ULAs to be of smaller scope than global addresses, to avoid that a preferred - * ULA is picked over a deprecated global address when given a global address - * as destination, as that would likely result in broken two-way communication. - * - * As long as temporary addresses are not supported (as used in Rule 7), a - * proper implementation of Rule 8 would obviate the need to implement Rule 6. - * - * @param netif the netif on which to send a packet - * @param dest the destination we are trying to reach (possibly not properly - * zoned) - * @return the most suitable source address to use, or NULL if no suitable - * source address is found - */ -const ip_addr_t * -ip6_select_source_address(struct netif *netif, const ip6_addr_t *dest) -{ - const ip_addr_t *best_addr; - const ip6_addr_t *cand_addr; - s8_t dest_scope, cand_scope; - s8_t best_scope = IP6_MULTICAST_SCOPE_RESERVED; - u8_t i, cand_pref, cand_bits; - u8_t best_pref = 0; - u8_t best_bits = 0; - - /* Start by determining the scope of the given destination address. These - * tests are hopefully (roughly) in order of likeliness to match. */ - if (ip6_addr_isglobal(dest)) { - dest_scope = IP6_MULTICAST_SCOPE_GLOBAL; - } else if (ip6_addr_islinklocal(dest) || ip6_addr_isloopback(dest)) { - dest_scope = IP6_MULTICAST_SCOPE_LINK_LOCAL; - } else if (ip6_addr_isuniquelocal(dest)) { - dest_scope = IP6_MULTICAST_SCOPE_ORGANIZATION_LOCAL; - } else if (ip6_addr_ismulticast(dest)) { - dest_scope = ip6_addr_multicast_scope(dest); - } else if (ip6_addr_issitelocal(dest)) { - dest_scope = IP6_MULTICAST_SCOPE_SITE_LOCAL; - } else { - /* no match, consider scope global */ - dest_scope = IP6_MULTICAST_SCOPE_GLOBAL; - } - - best_addr = NULL; - - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - /* Consider only valid (= preferred and deprecated) addresses. */ - if (!ip6_addr_isvalid(netif_ip6_addr_state(netif, i))) { - continue; - } - /* Determine the scope of this candidate address. Same ordering idea. */ - cand_addr = netif_ip6_addr(netif, i); - if (ip6_addr_isglobal(cand_addr)) { - cand_scope = IP6_MULTICAST_SCOPE_GLOBAL; - } else if (ip6_addr_islinklocal(cand_addr)) { - cand_scope = IP6_MULTICAST_SCOPE_LINK_LOCAL; - } else if (ip6_addr_isuniquelocal(cand_addr)) { - cand_scope = IP6_MULTICAST_SCOPE_ORGANIZATION_LOCAL; - } else if (ip6_addr_issitelocal(cand_addr)) { - cand_scope = IP6_MULTICAST_SCOPE_SITE_LOCAL; - } else { - /* no match, treat as low-priority global scope */ - cand_scope = IP6_MULTICAST_SCOPE_RESERVEDF; - } - cand_pref = ip6_addr_ispreferred(netif_ip6_addr_state(netif, i)); - /* @todo compute the actual common bits, for longest matching prefix. */ - /* We cannot count on the destination address having a proper zone - * assignment, so do not compare zones in this case. */ - cand_bits = ip6_addr_netcmp_zoneless(cand_addr, dest); /* just 1 or 0 for now */ - if (cand_bits && ip6_addr_nethostcmp(cand_addr, dest)) { - return netif_ip_addr6(netif, i); /* Rule 1 */ - } - if ((best_addr == NULL) || /* no alternative yet */ - ((cand_scope < best_scope) && (cand_scope >= dest_scope)) || - ((cand_scope > best_scope) && (best_scope < dest_scope)) || /* Rule 2 */ - ((cand_scope == best_scope) && ((cand_pref > best_pref) || /* Rule 3 */ - ((cand_pref == best_pref) && (cand_bits > best_bits))))) { /* Rule 8 */ - /* We found a new "winning" candidate. */ - best_addr = netif_ip_addr6(netif, i); - best_scope = cand_scope; - best_pref = cand_pref; - best_bits = cand_bits; - } - } - - return best_addr; /* may be NULL */ -} - -#if LWIP_IPV6_FORWARD -/** - * Forwards an IPv6 packet. It finds an appropriate route for the - * packet, decrements the HL value of the packet, and outputs - * the packet on the appropriate interface. - * - * @param p the packet to forward (p->payload points to IP header) - * @param iphdr the IPv6 header of the input packet - * @param inp the netif on which this packet was received - */ -static void -ip6_forward(struct pbuf *p, struct ip6_hdr *iphdr, struct netif *inp) -{ - struct netif *netif; - - /* do not forward link-local or loopback addresses */ - if (ip6_addr_islinklocal(ip6_current_dest_addr()) || - ip6_addr_isloopback(ip6_current_dest_addr())) { - LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: not forwarding link-local address.\n")); - IP6_STATS_INC(ip6.rterr); - IP6_STATS_INC(ip6.drop); - return; - } - - /* Find network interface where to forward this IP packet to. */ - netif = ip6_route(IP6_ADDR_ANY6, ip6_current_dest_addr()); - if (netif == NULL) { - LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: no route for %"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F"\n", - IP6_ADDR_BLOCK1(ip6_current_dest_addr()), - IP6_ADDR_BLOCK2(ip6_current_dest_addr()), - IP6_ADDR_BLOCK3(ip6_current_dest_addr()), - IP6_ADDR_BLOCK4(ip6_current_dest_addr()), - IP6_ADDR_BLOCK5(ip6_current_dest_addr()), - IP6_ADDR_BLOCK6(ip6_current_dest_addr()), - IP6_ADDR_BLOCK7(ip6_current_dest_addr()), - IP6_ADDR_BLOCK8(ip6_current_dest_addr()))); -#if LWIP_ICMP6 - /* Don't send ICMP messages in response to ICMP messages */ - if (IP6H_NEXTH(iphdr) != IP6_NEXTH_ICMP6) { - icmp6_dest_unreach(p, ICMP6_DUR_NO_ROUTE); - } -#endif /* LWIP_ICMP6 */ - IP6_STATS_INC(ip6.rterr); - IP6_STATS_INC(ip6.drop); - return; - } -#if LWIP_IPV6_SCOPES - /* Do not forward packets with a zoned (e.g., link-local) source address - * outside of their zone. We determined the zone a bit earlier, so we know - * that the address is properly zoned here, so we can safely use has_zone. - * Also skip packets with a loopback source address (link-local implied). */ - if ((ip6_addr_has_zone(ip6_current_src_addr()) && - !ip6_addr_test_zone(ip6_current_src_addr(), netif)) || - ip6_addr_isloopback(ip6_current_src_addr())) { - LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: not forwarding packet beyond its source address zone.\n")); - IP6_STATS_INC(ip6.rterr); - IP6_STATS_INC(ip6.drop); - return; - } -#endif /* LWIP_IPV6_SCOPES */ - /* Do not forward packets onto the same network interface on which - * they arrived. */ - if (netif == inp) { - LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: not bouncing packets back on incoming interface.\n")); - IP6_STATS_INC(ip6.rterr); - IP6_STATS_INC(ip6.drop); - return; - } - - /* decrement HL */ - IP6H_HOPLIM_SET(iphdr, IP6H_HOPLIM(iphdr) - 1); - /* send ICMP6 if HL == 0 */ - if (IP6H_HOPLIM(iphdr) == 0) { -#if LWIP_ICMP6 - /* Don't send ICMP messages in response to ICMP messages */ - if (IP6H_NEXTH(iphdr) != IP6_NEXTH_ICMP6) { - icmp6_time_exceeded(p, ICMP6_TE_HL); - } -#endif /* LWIP_ICMP6 */ - IP6_STATS_INC(ip6.drop); - return; - } - - if (netif->mtu && (p->tot_len > netif->mtu)) { -#if LWIP_ICMP6 - /* Don't send ICMP messages in response to ICMP messages */ - if (IP6H_NEXTH(iphdr) != IP6_NEXTH_ICMP6) { - icmp6_packet_too_big(p, netif->mtu); - } -#endif /* LWIP_ICMP6 */ - IP6_STATS_INC(ip6.drop); - return; - } - - LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: forwarding packet to %"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F"\n", - IP6_ADDR_BLOCK1(ip6_current_dest_addr()), - IP6_ADDR_BLOCK2(ip6_current_dest_addr()), - IP6_ADDR_BLOCK3(ip6_current_dest_addr()), - IP6_ADDR_BLOCK4(ip6_current_dest_addr()), - IP6_ADDR_BLOCK5(ip6_current_dest_addr()), - IP6_ADDR_BLOCK6(ip6_current_dest_addr()), - IP6_ADDR_BLOCK7(ip6_current_dest_addr()), - IP6_ADDR_BLOCK8(ip6_current_dest_addr()))); - - /* transmit pbuf on chosen interface */ - netif->output_ip6(netif, p, ip6_current_dest_addr()); - IP6_STATS_INC(ip6.fw); - IP6_STATS_INC(ip6.xmit); - return; -} -#endif /* LWIP_IPV6_FORWARD */ - -/** Return true if the current input packet should be accepted on this netif */ -static int -ip6_input_accept(struct netif *netif) -{ - /* interface is up? */ - if (netif_is_up(netif)) { - u8_t i; - /* unicast to this interface address? address configured? */ - /* If custom scopes are used, the destination zone will be tested as - * part of the local-address comparison, but we need to test the source - * scope as well (e.g., is this interface on the same link?). */ - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && - ip6_addr_cmp(ip6_current_dest_addr(), netif_ip6_addr(netif, i)) -#if IPV6_CUSTOM_SCOPES - && (!ip6_addr_has_zone(ip6_current_src_addr()) || - ip6_addr_test_zone(ip6_current_src_addr(), netif)) -#endif /* IPV6_CUSTOM_SCOPES */ - ) { - /* accept on this netif */ - return 1; - } - } - } - return 0; -} - -/** - * This function is called by the network interface device driver when - * an IPv6 packet is received. The function does the basic checks of the - * IP header such as packet size being at least larger than the header - * size etc. If the packet was not destined for us, the packet is - * forwarded (using ip6_forward). - * - * Finally, the packet is sent to the upper layer protocol input function. - * - * @param p the received IPv6 packet (p->payload points to IPv6 header) - * @param inp the netif on which this packet was received - * @return ERR_OK if the packet was processed (could return ERR_* if it wasn't - * processed, but currently always returns ERR_OK) - */ -err_t -ip6_input(struct pbuf *p, struct netif *inp) -{ - struct ip6_hdr *ip6hdr; - struct netif *netif; - const u8_t *nexth; - u16_t hlen, hlen_tot; /* the current header length */ -#if 0 /*IP_ACCEPT_LINK_LAYER_ADDRESSING*/ - @todo - int check_ip_src=1; -#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */ -#if LWIP_RAW - raw_input_state_t raw_status; -#endif /* LWIP_RAW */ - - LWIP_ASSERT_CORE_LOCKED(); - - IP6_STATS_INC(ip6.recv); - - /* identify the IP header */ - ip6hdr = (struct ip6_hdr *)p->payload; - if (IP6H_V(ip6hdr) != 6) { - LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_WARNING, ("IPv6 packet dropped due to bad version number %"U32_F"\n", - IP6H_V(ip6hdr))); - pbuf_free(p); - IP6_STATS_INC(ip6.err); - IP6_STATS_INC(ip6.drop); - return ERR_OK; - } - -#ifdef LWIP_HOOK_IP6_INPUT - if (LWIP_HOOK_IP6_INPUT(p, inp)) { - /* the packet has been eaten */ - return ERR_OK; - } -#endif - - /* header length exceeds first pbuf length, or ip length exceeds total pbuf length? */ - if ((IP6_HLEN > p->len) || (IP6H_PLEN(ip6hdr) > (p->tot_len - IP6_HLEN))) { - if (IP6_HLEN > p->len) { - LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("IPv6 header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet dropped.\n", - (u16_t)IP6_HLEN, p->len)); - } - if ((IP6H_PLEN(ip6hdr) + IP6_HLEN) > p->tot_len) { - LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("IPv6 (plen %"U16_F") is longer than pbuf (len %"U16_F"), IP packet dropped.\n", - (u16_t)(IP6H_PLEN(ip6hdr) + IP6_HLEN), p->tot_len)); - } - /* free (drop) packet pbufs */ - pbuf_free(p); - IP6_STATS_INC(ip6.lenerr); - IP6_STATS_INC(ip6.drop); - return ERR_OK; - } - - /* Trim pbuf. This should have been done at the netif layer, - * but we'll do it anyway just to be sure that its done. */ - pbuf_realloc(p, (u16_t)(IP6_HLEN + IP6H_PLEN(ip6hdr))); - - /* copy IP addresses to aligned ip6_addr_t */ - ip_addr_copy_from_ip6_packed(ip_data.current_iphdr_dest, ip6hdr->dest); - ip_addr_copy_from_ip6_packed(ip_data.current_iphdr_src, ip6hdr->src); - - /* Don't accept virtual IPv4 mapped IPv6 addresses. - * Don't accept multicast source addresses. */ - if (ip6_addr_isipv4mappedipv6(ip_2_ip6(&ip_data.current_iphdr_dest)) || - ip6_addr_isipv4mappedipv6(ip_2_ip6(&ip_data.current_iphdr_src)) || - ip6_addr_ismulticast(ip_2_ip6(&ip_data.current_iphdr_src))) { - /* free (drop) packet pbufs */ - pbuf_free(p); - IP6_STATS_INC(ip6.err); - IP6_STATS_INC(ip6.drop); - return ERR_OK; - } - - /* Set the appropriate zone identifier on the addresses. */ - ip6_addr_assign_zone(ip_2_ip6(&ip_data.current_iphdr_dest), IP6_UNKNOWN, inp); - ip6_addr_assign_zone(ip_2_ip6(&ip_data.current_iphdr_src), IP6_UNICAST, inp); - - /* current header pointer. */ - ip_data.current_ip6_header = ip6hdr; - - /* In netif, used in case we need to send ICMPv6 packets back. */ - ip_data.current_netif = inp; - ip_data.current_input_netif = inp; - - /* match packet against an interface, i.e. is this packet for us? */ - if (ip6_addr_ismulticast(ip6_current_dest_addr())) { - /* Always joined to multicast if-local and link-local all-nodes group. */ - if (ip6_addr_isallnodes_iflocal(ip6_current_dest_addr()) || - ip6_addr_isallnodes_linklocal(ip6_current_dest_addr())) { - netif = inp; - } -#if LWIP_IPV6_MLD - else if (mld6_lookfor_group(inp, ip6_current_dest_addr())) { - netif = inp; - } -#else /* LWIP_IPV6_MLD */ - else if (ip6_addr_issolicitednode(ip6_current_dest_addr())) { - u8_t i; - /* Filter solicited node packets when MLD is not enabled - * (for Neighbor discovery). */ - netif = NULL; - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (ip6_addr_isvalid(netif_ip6_addr_state(inp, i)) && - ip6_addr_cmp_solicitednode(ip6_current_dest_addr(), netif_ip6_addr(inp, i))) { - netif = inp; - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: solicited node packet accepted on interface %c%c\n", - netif->name[0], netif->name[1])); - break; - } - } - } -#endif /* LWIP_IPV6_MLD */ - else { - netif = NULL; - } - } else { - /* start trying with inp. if that's not acceptable, start walking the - list of configured netifs. */ - if (ip6_input_accept(inp)) { - netif = inp; - } else { - netif = NULL; -#if !IPV6_CUSTOM_SCOPES - /* Shortcut: stop looking for other interfaces if either the source or - * the destination has a scope constrained to this interface. Custom - * scopes may break the 1:1 link/interface mapping, however. */ - if (ip6_addr_islinklocal(ip6_current_dest_addr()) || - ip6_addr_islinklocal(ip6_current_src_addr())) { - goto netif_found; - } -#endif /* !IPV6_CUSTOM_SCOPES */ -#if !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF - /* The loopback address is to be considered link-local. Packets to it - * should be dropped on other interfaces, as per RFC 4291 Sec. 2.5.3. - * Its implied scope means packets *from* the loopback address should - * not be accepted on other interfaces, either. These requirements - * cannot be implemented in the case that loopback traffic is sent - * across a non-loopback interface, however. */ - if (ip6_addr_isloopback(ip6_current_dest_addr()) || - ip6_addr_isloopback(ip6_current_src_addr())) { - goto netif_found; - } -#endif /* !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF */ -#if !LWIP_SINGLE_NETIF - NETIF_FOREACH(netif) { - if (netif == inp) { - /* we checked that before already */ - continue; - } - if (ip6_input_accept(netif)) { - break; - } - } -#endif /* !LWIP_SINGLE_NETIF */ - } -netif_found: - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet accepted on interface %c%c\n", - netif ? netif->name[0] : 'X', netif? netif->name[1] : 'X')); - } - - /* "::" packet source address? (used in duplicate address detection) */ - if (ip6_addr_isany(ip6_current_src_addr()) && - (!ip6_addr_issolicitednode(ip6_current_dest_addr()))) { - /* packet source is not valid */ - /* free (drop) packet pbufs */ - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with src ANY_ADDRESS dropped\n")); - pbuf_free(p); - IP6_STATS_INC(ip6.drop); - goto ip6_input_cleanup; - } - - /* packet not for us? */ - if (netif == NULL) { - /* packet not for us, route or discard */ - LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_TRACE, ("ip6_input: packet not for us.\n")); -#if LWIP_IPV6_FORWARD - /* non-multicast packet? */ - if (!ip6_addr_ismulticast(ip6_current_dest_addr())) { - /* try to forward IP packet on (other) interfaces */ - ip6_forward(p, ip6hdr, inp); - } -#endif /* LWIP_IPV6_FORWARD */ - pbuf_free(p); - goto ip6_input_cleanup; - } - - /* current netif pointer. */ - ip_data.current_netif = netif; - - /* Save next header type. */ - nexth = &IP6H_NEXTH(ip6hdr); - - /* Init header length. */ - hlen = hlen_tot = IP6_HLEN; - - /* Move to payload. */ - pbuf_remove_header(p, IP6_HLEN); - - /* Process known option extension headers, if present. */ - while (*nexth != IP6_NEXTH_NONE) - { - switch (*nexth) { - case IP6_NEXTH_HOPBYHOP: - { - s32_t opt_offset; - struct ip6_hbh_hdr *hbh_hdr; - struct ip6_opt_hdr *opt_hdr; - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Hop-by-Hop options header\n")); - - /* Get and check the header length, while staying in packet bounds. */ - hbh_hdr = (struct ip6_hbh_hdr *)p->payload; - - /* Get next header type. */ - nexth = &IP6_HBH_NEXTH(hbh_hdr); - - /* Get the header length. */ - hlen = (u16_t)(8 * (1 + hbh_hdr->_hlen)); - - if ((p->len < 8) || (hlen > p->len)) { - LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n", - hlen, p->len)); - /* free (drop) packet pbufs */ - pbuf_free(p); - IP6_STATS_INC(ip6.lenerr); - IP6_STATS_INC(ip6.drop); - goto ip6_input_cleanup; - } - - hlen_tot = (u16_t)(hlen_tot + hlen); - - /* The extended option header starts right after Hop-by-Hop header. */ - opt_offset = IP6_HBH_HLEN; - while (opt_offset < hlen) - { - s32_t opt_dlen = 0; - - opt_hdr = (struct ip6_opt_hdr *)((u8_t *)hbh_hdr + opt_offset); - - switch (IP6_OPT_TYPE(opt_hdr)) { - /* @todo: process IPV6 Hop-by-Hop option data */ - case IP6_PAD1_OPTION: - /* PAD1 option doesn't have length and value field */ - opt_dlen = -1; - break; - case IP6_PADN_OPTION: - opt_dlen = IP6_OPT_DLEN(opt_hdr); - break; - case IP6_ROUTER_ALERT_OPTION: - opt_dlen = IP6_OPT_DLEN(opt_hdr); - break; - case IP6_JUMBO_OPTION: - opt_dlen = IP6_OPT_DLEN(opt_hdr); - break; - default: - /* Check 2 MSB of Hop-by-Hop header type. */ - switch (IP6_OPT_TYPE_ACTION(opt_hdr)) { - case 1: - /* Discard the packet. */ - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with invalid Hop-by-Hop option type dropped.\n")); - pbuf_free(p); - IP6_STATS_INC(ip6.drop); - goto ip6_input_cleanup; - case 2: - /* Send ICMP Parameter Problem */ - icmp6_param_problem(p, ICMP6_PP_OPTION, opt_hdr); - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with invalid Hop-by-Hop option type dropped.\n")); - pbuf_free(p); - IP6_STATS_INC(ip6.drop); - goto ip6_input_cleanup; - case 3: - /* Send ICMP Parameter Problem if destination address is not a multicast address */ - if (!ip6_addr_ismulticast(ip6_current_dest_addr())) { - icmp6_param_problem(p, ICMP6_PP_OPTION, opt_hdr); - } - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with invalid Hop-by-Hop option type dropped.\n")); - pbuf_free(p); - IP6_STATS_INC(ip6.drop); - goto ip6_input_cleanup; - default: - /* Skip over this option. */ - opt_dlen = IP6_OPT_DLEN(opt_hdr); - break; - } - break; - } - - /* Adjust the offset to move to the next extended option header */ - opt_offset = opt_offset + IP6_OPT_HLEN + opt_dlen; - } - pbuf_remove_header(p, hlen); - break; - } - case IP6_NEXTH_DESTOPTS: - { - s32_t opt_offset; - struct ip6_dest_hdr *dest_hdr; - struct ip6_opt_hdr *opt_hdr; - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Destination options header\n")); - - dest_hdr = (struct ip6_dest_hdr *)p->payload; - - /* Get next header type. */ - nexth = &IP6_DEST_NEXTH(dest_hdr); - - /* Get the header length. */ - hlen = 8 * (1 + dest_hdr->_hlen); - if ((p->len < 8) || (hlen > p->len)) { - LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n", - hlen, p->len)); - /* free (drop) packet pbufs */ - pbuf_free(p); - IP6_STATS_INC(ip6.lenerr); - IP6_STATS_INC(ip6.drop); - goto ip6_input_cleanup; - } - - hlen_tot = (u16_t)(hlen_tot + hlen); - - /* The extended option header starts right after Destination header. */ - opt_offset = IP6_DEST_HLEN; - while (opt_offset < hlen) - { - s32_t opt_dlen = 0; - - opt_hdr = (struct ip6_opt_hdr *)((u8_t *)dest_hdr + opt_offset); - - switch (IP6_OPT_TYPE(opt_hdr)) - { - /* @todo: process IPV6 Destination option data */ - case IP6_PAD1_OPTION: - /* PAD1 option deosn't have length and value field */ - opt_dlen = -1; - break; - case IP6_PADN_OPTION: - opt_dlen = IP6_OPT_DLEN(opt_hdr); - break; - case IP6_ROUTER_ALERT_OPTION: - opt_dlen = IP6_OPT_DLEN(opt_hdr); - break; - case IP6_JUMBO_OPTION: - opt_dlen = IP6_OPT_DLEN(opt_hdr); - break; - case IP6_HOME_ADDRESS_OPTION: - opt_dlen = IP6_OPT_DLEN(opt_hdr); - break; - default: - /* Check 2 MSB of Destination header type. */ - switch (IP6_OPT_TYPE_ACTION(opt_hdr)) - { - case 1: - /* Discard the packet. */ - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with invalid destination option type dropped.\n")); - pbuf_free(p); - IP6_STATS_INC(ip6.drop); - goto ip6_input_cleanup; - case 2: - /* Send ICMP Parameter Problem */ - icmp6_param_problem(p, ICMP6_PP_OPTION, opt_hdr); - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with invalid destination option type dropped.\n")); - pbuf_free(p); - IP6_STATS_INC(ip6.drop); - goto ip6_input_cleanup; - case 3: - /* Send ICMP Parameter Problem if destination address is not a multicast address */ - if (!ip6_addr_ismulticast(ip6_current_dest_addr())) { - icmp6_param_problem(p, ICMP6_PP_OPTION, opt_hdr); - } - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with invalid destination option type dropped.\n")); - pbuf_free(p); - IP6_STATS_INC(ip6.drop); - goto ip6_input_cleanup; - default: - /* Skip over this option. */ - opt_dlen = IP6_OPT_DLEN(opt_hdr); - break; - } - break; - } - - /* Adjust the offset to move to the next extended option header */ - opt_offset = opt_offset + IP6_OPT_HLEN + opt_dlen; - } - - pbuf_remove_header(p, hlen); - break; - } - case IP6_NEXTH_ROUTING: - { - struct ip6_rout_hdr *rout_hdr; - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Routing header\n")); - - rout_hdr = (struct ip6_rout_hdr *)p->payload; - - /* Get next header type. */ - nexth = &IP6_ROUT_NEXTH(rout_hdr); - - /* Get the header length. */ - hlen = 8 * (1 + rout_hdr->_hlen); - - if ((p->len < 8) || (hlen > p->len)) { - LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n", - hlen, p->len)); - /* free (drop) packet pbufs */ - pbuf_free(p); - IP6_STATS_INC(ip6.lenerr); - IP6_STATS_INC(ip6.drop); - goto ip6_input_cleanup; - } - - /* Skip over this header. */ - hlen_tot = (u16_t)(hlen_tot + hlen); - - /* if segment left value is 0 in routing header, ignore the option */ - if (IP6_ROUT_SEG_LEFT(rout_hdr)) { - /* The length field of routing option header must be even */ - if (rout_hdr->_hlen & 0x1) { - /* Discard and send parameter field error */ - icmp6_param_problem(p, ICMP6_PP_FIELD, &rout_hdr->_hlen); - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with invalid routing type dropped\n")); - pbuf_free(p); - IP6_STATS_INC(ip6.drop); - goto ip6_input_cleanup; - } - - switch (IP6_ROUT_TYPE(rout_hdr)) - { - /* TODO: process routing by the type */ - case IP6_ROUT_TYPE2: - break; - case IP6_ROUT_RPL: - break; - default: - /* Discard unrecognized routing type and send parameter field error */ - icmp6_param_problem(p, ICMP6_PP_FIELD, &IP6_ROUT_TYPE(rout_hdr)); - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with invalid routing type dropped\n")); - pbuf_free(p); - IP6_STATS_INC(ip6.drop); - goto ip6_input_cleanup; - } - } - - pbuf_remove_header(p, hlen); - break; - } - case IP6_NEXTH_FRAGMENT: - { - struct ip6_frag_hdr *frag_hdr; - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Fragment header\n")); - - frag_hdr = (struct ip6_frag_hdr *)p->payload; - - /* Get next header type. */ - nexth = &IP6_FRAG_NEXTH(frag_hdr); - - /* Fragment Header length. */ - hlen = 8; - - /* Make sure this header fits in current pbuf. */ - if (hlen > p->len) { - LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n", - hlen, p->len)); - /* free (drop) packet pbufs */ - pbuf_free(p); - IP6_FRAG_STATS_INC(ip6_frag.lenerr); - IP6_FRAG_STATS_INC(ip6_frag.drop); - goto ip6_input_cleanup; - } - - hlen_tot = (u16_t)(hlen_tot + hlen); - - /* check payload length is multiple of 8 octets when mbit is set */ - if (IP6_FRAG_MBIT(frag_hdr) && (IP6H_PLEN(ip6hdr) & 0x7)) { - /* ipv6 payload length is not multiple of 8 octets */ - icmp6_param_problem(p, ICMP6_PP_FIELD, LWIP_PACKED_CAST(const void *, &ip6hdr->_plen)); - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with invalid payload length dropped\n")); - pbuf_free(p); - IP6_STATS_INC(ip6.drop); - goto ip6_input_cleanup; - } - - /* Offset == 0 and more_fragments == 0? */ - if ((frag_hdr->_fragment_offset & - PP_HTONS(IP6_FRAG_OFFSET_MASK | IP6_FRAG_MORE_FLAG)) == 0) { - /* This is a 1-fragment packet. Skip this header and continue. */ - pbuf_remove_header(p, hlen); - } else { -#if LWIP_IPV6_REASS - /* reassemble the packet */ - ip_data.current_ip_header_tot_len = hlen_tot; - p = ip6_reass(p); - /* packet not fully reassembled yet? */ - if (p == NULL) { - goto ip6_input_cleanup; - } - - /* Returned p point to IPv6 header. - * Update all our variables and pointers and continue. */ - ip6hdr = (struct ip6_hdr *)p->payload; - nexth = &IP6H_NEXTH(ip6hdr); - hlen = hlen_tot = IP6_HLEN; - pbuf_remove_header(p, IP6_HLEN); - -#else /* LWIP_IPV6_REASS */ - /* free (drop) packet pbufs */ - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Fragment header dropped (with LWIP_IPV6_REASS==0)\n")); - pbuf_free(p); - IP6_STATS_INC(ip6.opterr); - IP6_STATS_INC(ip6.drop); - goto ip6_input_cleanup; -#endif /* LWIP_IPV6_REASS */ - } - break; - } - default: - goto options_done; - } - - if (*nexth == IP6_NEXTH_HOPBYHOP) { - /* Hop-by-Hop header comes only as a first option */ - icmp6_param_problem(p, ICMP6_PP_HEADER, nexth); - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Hop-by-Hop options header dropped (only valid as a first option)\n")); - pbuf_free(p); - IP6_STATS_INC(ip6.drop); - goto ip6_input_cleanup; - } - } - -options_done: - - /* send to upper layers */ - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: \n")); - ip6_debug_print(p); - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len)); - - ip_data.current_ip_header_tot_len = hlen_tot; - -#if LWIP_RAW - /* p points to IPv6 header again for raw_input. */ - pbuf_add_header_force(p, hlen_tot); - /* raw input did not eat the packet? */ - raw_status = raw_input(p, inp); - if (raw_status != RAW_INPUT_EATEN) - { - /* Point to payload. */ - pbuf_remove_header(p, hlen_tot); -#else /* LWIP_RAW */ - { -#endif /* LWIP_RAW */ - switch (*nexth) { - case IP6_NEXTH_NONE: - pbuf_free(p); - break; -#if LWIP_UDP - case IP6_NEXTH_UDP: -#if LWIP_UDPLITE - case IP6_NEXTH_UDPLITE: -#endif /* LWIP_UDPLITE */ - udp_input(p, inp); - break; -#endif /* LWIP_UDP */ -#if LWIP_TCP - case IP6_NEXTH_TCP: - tcp_input(p, inp); - break; -#endif /* LWIP_TCP */ -#if LWIP_ICMP6 - case IP6_NEXTH_ICMP6: - icmp6_input(p, inp); - break; -#endif /* LWIP_ICMP */ - default: -#if LWIP_RAW - if (raw_status == RAW_INPUT_DELIVERED) { - /* @todo: ipv6 mib in-delivers? */ - } else -#endif /* LWIP_RAW */ - { -#if LWIP_ICMP6 - /* p points to IPv6 header again for raw_input. */ - pbuf_add_header_force(p, hlen_tot); - /* send ICMP parameter problem unless it was a multicast or ICMPv6 */ - if ((!ip6_addr_ismulticast(ip6_current_dest_addr())) && - (IP6H_NEXTH(ip6hdr) != IP6_NEXTH_ICMP6)) { - icmp6_param_problem(p, ICMP6_PP_HEADER, nexth); - } -#endif /* LWIP_ICMP */ - LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_input: Unsupported transport protocol %"U16_F"\n", (u16_t)IP6H_NEXTH(ip6hdr))); - IP6_STATS_INC(ip6.proterr); - IP6_STATS_INC(ip6.drop); - } - pbuf_free(p); - break; - } - } - -ip6_input_cleanup: - ip_data.current_netif = NULL; - ip_data.current_input_netif = NULL; - ip_data.current_ip6_header = NULL; - ip_data.current_ip_header_tot_len = 0; - ip6_addr_set_zero(ip6_current_src_addr()); - ip6_addr_set_zero(ip6_current_dest_addr()); - - return ERR_OK; -} - - -/** - * Sends an IPv6 packet on a network interface. This function constructs - * the IPv6 header. If the source IPv6 address is NULL, the IPv6 "ANY" address is - * used as source (usually during network startup). If the source IPv6 address it - * IP6_ADDR_ANY, the most appropriate IPv6 address of the outgoing network - * interface is filled in as source address. If the destination IPv6 address is - * LWIP_IP_HDRINCL, p is assumed to already include an IPv6 header and - * p->payload points to it instead of the data. - * - * @param p the packet to send (p->payload points to the data, e.g. next - protocol header; if dest == LWIP_IP_HDRINCL, p already includes an - IPv6 header and p->payload points to that IPv6 header) - * @param src the source IPv6 address to send from (if src == IP6_ADDR_ANY, an - * IP address of the netif is selected and used as source address. - * if src == NULL, IP6_ADDR_ANY is used as source) (src is possibly not - * properly zoned) - * @param dest the destination IPv6 address to send the packet to (possibly not - * properly zoned) - * @param hl the Hop Limit value to be set in the IPv6 header - * @param tc the Traffic Class value to be set in the IPv6 header - * @param nexth the Next Header to be set in the IPv6 header - * @param netif the netif on which to send this packet - * @return ERR_OK if the packet was sent OK - * ERR_BUF if p doesn't have enough space for IPv6/LINK headers - * returns errors returned by netif->output_ip6 - */ -err_t -ip6_output_if(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest, - u8_t hl, u8_t tc, - u8_t nexth, struct netif *netif) -{ - const ip6_addr_t *src_used = src; - if (dest != LWIP_IP_HDRINCL) { - if (src != NULL && ip6_addr_isany(src)) { - src_used = ip_2_ip6(ip6_select_source_address(netif, dest)); - if ((src_used == NULL) || ip6_addr_isany(src_used)) { - /* No appropriate source address was found for this packet. */ - LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_output: No suitable source address for packet.\n")); - IP6_STATS_INC(ip6.rterr); - return ERR_RTE; - } - } - } - return ip6_output_if_src(p, src_used, dest, hl, tc, nexth, netif); -} - -/** - * Same as ip6_output_if() but 'src' address is not replaced by netif address - * when it is 'any'. - */ -err_t -ip6_output_if_src(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest, - u8_t hl, u8_t tc, - u8_t nexth, struct netif *netif) -{ - struct ip6_hdr *ip6hdr; - ip6_addr_t dest_addr; - - LWIP_ASSERT_CORE_LOCKED(); - LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p); - - /* Should the IPv6 header be generated or is it already included in p? */ - if (dest != LWIP_IP_HDRINCL) { -#if LWIP_IPV6_SCOPES - /* If the destination address is scoped but lacks a zone, add a zone now, - * based on the outgoing interface. The lower layers (e.g., nd6) absolutely - * require addresses to be properly zoned for correctness. In some cases, - * earlier attempts will have been made to add a zone to the destination, - * but this function is the only one that is called in all (other) cases, - * so we must do this here. */ - if (ip6_addr_lacks_zone(dest, IP6_UNKNOWN)) { - ip6_addr_copy(dest_addr, *dest); - ip6_addr_assign_zone(&dest_addr, IP6_UNKNOWN, netif); - dest = &dest_addr; - } -#endif /* LWIP_IPV6_SCOPES */ - - /* generate IPv6 header */ - if (pbuf_add_header(p, IP6_HLEN)) { - LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_output: not enough room for IPv6 header in pbuf\n")); - IP6_STATS_INC(ip6.err); - return ERR_BUF; - } - - ip6hdr = (struct ip6_hdr *)p->payload; - LWIP_ASSERT("check that first pbuf can hold struct ip6_hdr", - (p->len >= sizeof(struct ip6_hdr))); - - IP6H_HOPLIM_SET(ip6hdr, hl); - IP6H_NEXTH_SET(ip6hdr, nexth); - - /* dest cannot be NULL here */ - ip6_addr_copy_to_packed(ip6hdr->dest, *dest); - - IP6H_VTCFL_SET(ip6hdr, 6, tc, 0); - IP6H_PLEN_SET(ip6hdr, (u16_t)(p->tot_len - IP6_HLEN)); - - if (src == NULL) { - src = IP6_ADDR_ANY6; - } - /* src cannot be NULL here */ - ip6_addr_copy_to_packed(ip6hdr->src, *src); - - } else { - /* IP header already included in p */ - ip6hdr = (struct ip6_hdr *)p->payload; - ip6_addr_copy_from_packed(dest_addr, ip6hdr->dest); - ip6_addr_assign_zone(&dest_addr, IP6_UNKNOWN, netif); - dest = &dest_addr; - } - - IP6_STATS_INC(ip6.xmit); - - LWIP_DEBUGF(IP6_DEBUG, ("ip6_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], (u16_t)netif->num)); - ip6_debug_print(p); - -#if ENABLE_LOOPBACK - { - int i; -#if !LWIP_HAVE_LOOPIF - if (ip6_addr_isloopback(dest)) { - return netif_loop_output(netif, p); - } -#endif /* !LWIP_HAVE_LOOPIF */ - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && - ip6_addr_cmp(dest, netif_ip6_addr(netif, i))) { - /* Packet to self, enqueue it for loopback */ - LWIP_DEBUGF(IP6_DEBUG, ("netif_loop_output()\n")); - return netif_loop_output(netif, p); - } - } - } -#if LWIP_MULTICAST_TX_OPTIONS - if ((p->flags & PBUF_FLAG_MCASTLOOP) != 0) { - netif_loop_output(netif, p); - } -#endif /* LWIP_MULTICAST_TX_OPTIONS */ -#endif /* ENABLE_LOOPBACK */ -#if LWIP_IPV6_FRAG - /* don't fragment if interface has mtu set to 0 [loopif] */ - if (netif_mtu6(netif) && (p->tot_len > nd6_get_destination_mtu(dest, netif))) { - return ip6_frag(p, netif, dest); - } -#endif /* LWIP_IPV6_FRAG */ - - LWIP_DEBUGF(IP6_DEBUG, ("netif->output_ip6()\n")); - return netif->output_ip6(netif, p, dest); -} - -/** - * Simple interface to ip6_output_if. It finds the outgoing network - * interface and calls upon ip6_output_if to do the actual work. - * - * @param p the packet to send (p->payload points to the data, e.g. next - protocol header; if dest == LWIP_IP_HDRINCL, p already includes an - IPv6 header and p->payload points to that IPv6 header) - * @param src the source IPv6 address to send from (if src == IP6_ADDR_ANY, an - * IP address of the netif is selected and used as source address. - * if src == NULL, IP6_ADDR_ANY is used as source) - * @param dest the destination IPv6 address to send the packet to - * @param hl the Hop Limit value to be set in the IPv6 header - * @param tc the Traffic Class value to be set in the IPv6 header - * @param nexth the Next Header to be set in the IPv6 header - * - * @return ERR_RTE if no route is found - * see ip_output_if() for more return values - */ -err_t -ip6_output(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest, - u8_t hl, u8_t tc, u8_t nexth) -{ - struct netif *netif; - struct ip6_hdr *ip6hdr; - ip6_addr_t src_addr, dest_addr; - - LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p); - - if (dest != LWIP_IP_HDRINCL) { - netif = ip6_route(src, dest); - } else { - /* IP header included in p, read addresses. */ - ip6hdr = (struct ip6_hdr *)p->payload; - ip6_addr_copy_from_packed(src_addr, ip6hdr->src); - ip6_addr_copy_from_packed(dest_addr, ip6hdr->dest); - netif = ip6_route(&src_addr, &dest_addr); - } - - if (netif == NULL) { - LWIP_DEBUGF(IP6_DEBUG, ("ip6_output: no route for %"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F"\n", - IP6_ADDR_BLOCK1(dest), - IP6_ADDR_BLOCK2(dest), - IP6_ADDR_BLOCK3(dest), - IP6_ADDR_BLOCK4(dest), - IP6_ADDR_BLOCK5(dest), - IP6_ADDR_BLOCK6(dest), - IP6_ADDR_BLOCK7(dest), - IP6_ADDR_BLOCK8(dest))); - IP6_STATS_INC(ip6.rterr); - return ERR_RTE; - } - - return ip6_output_if(p, src, dest, hl, tc, nexth, netif); -} - - -#if LWIP_NETIF_USE_HINTS -/** Like ip6_output, but takes and addr_hint pointer that is passed on to netif->addr_hint - * before calling ip6_output_if. - * - * @param p the packet to send (p->payload points to the data, e.g. next - protocol header; if dest == LWIP_IP_HDRINCL, p already includes an - IPv6 header and p->payload points to that IPv6 header) - * @param src the source IPv6 address to send from (if src == IP6_ADDR_ANY, an - * IP address of the netif is selected and used as source address. - * if src == NULL, IP6_ADDR_ANY is used as source) - * @param dest the destination IPv6 address to send the packet to - * @param hl the Hop Limit value to be set in the IPv6 header - * @param tc the Traffic Class value to be set in the IPv6 header - * @param nexth the Next Header to be set in the IPv6 header - * @param netif_hint netif output hint pointer set to netif->hint before - * calling ip_output_if() - * - * @return ERR_RTE if no route is found - * see ip_output_if() for more return values - */ -err_t -ip6_output_hinted(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest, - u8_t hl, u8_t tc, u8_t nexth, struct netif_hint *netif_hint) -{ - struct netif *netif; - struct ip6_hdr *ip6hdr; - ip6_addr_t src_addr, dest_addr; - err_t err; - - LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p); - - if (dest != LWIP_IP_HDRINCL) { - netif = ip6_route(src, dest); - } else { - /* IP header included in p, read addresses. */ - ip6hdr = (struct ip6_hdr *)p->payload; - ip6_addr_copy_from_packed(src_addr, ip6hdr->src); - ip6_addr_copy_from_packed(dest_addr, ip6hdr->dest); - netif = ip6_route(&src_addr, &dest_addr); - } - - if (netif == NULL) { - LWIP_DEBUGF(IP6_DEBUG, ("ip6_output: no route for %"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F"\n", - IP6_ADDR_BLOCK1(dest), - IP6_ADDR_BLOCK2(dest), - IP6_ADDR_BLOCK3(dest), - IP6_ADDR_BLOCK4(dest), - IP6_ADDR_BLOCK5(dest), - IP6_ADDR_BLOCK6(dest), - IP6_ADDR_BLOCK7(dest), - IP6_ADDR_BLOCK8(dest))); - IP6_STATS_INC(ip6.rterr); - return ERR_RTE; - } - - NETIF_SET_HINTS(netif, netif_hint); - err = ip6_output_if(p, src, dest, hl, tc, nexth, netif); - NETIF_RESET_HINTS(netif); - - return err; -} -#endif /* LWIP_NETIF_USE_HINTS*/ - -#if LWIP_IPV6_MLD -/** - * Add a hop-by-hop options header with a router alert option and padding. - * - * Used by MLD when sending a Multicast listener report/done message. - * - * @param p the packet to which we will prepend the options header - * @param nexth the next header protocol number (e.g. IP6_NEXTH_ICMP6) - * @param value the value of the router alert option data (e.g. IP6_ROUTER_ALERT_VALUE_MLD) - * @return ERR_OK if hop-by-hop header was added, ERR_* otherwise - */ -err_t -ip6_options_add_hbh_ra(struct pbuf *p, u8_t nexth, u8_t value) -{ - u8_t *opt_data; - u32_t offset = 0; - struct ip6_hbh_hdr *hbh_hdr; - struct ip6_opt_hdr *opt_hdr; - - /* fixed 4 bytes for router alert option and 2 bytes padding */ - const u8_t hlen = (sizeof(struct ip6_opt_hdr) * 2) + IP6_ROUTER_ALERT_DLEN; - /* Move pointer to make room for hop-by-hop options header. */ - if (pbuf_add_header(p, sizeof(struct ip6_hbh_hdr) + hlen)) { - LWIP_DEBUGF(IP6_DEBUG, ("ip6_options: no space for options header\n")); - IP6_STATS_INC(ip6.err); - return ERR_BUF; - } - - /* Set fields of Hop-by-Hop header */ - hbh_hdr = (struct ip6_hbh_hdr *)p->payload; - IP6_HBH_NEXTH(hbh_hdr) = nexth; - hbh_hdr->_hlen = 0; - offset = IP6_HBH_HLEN; - - /* Set router alert options to Hop-by-Hop extended option header */ - opt_hdr = (struct ip6_opt_hdr *)((u8_t *)hbh_hdr + offset); - IP6_OPT_TYPE(opt_hdr) = IP6_ROUTER_ALERT_OPTION; - IP6_OPT_DLEN(opt_hdr) = IP6_ROUTER_ALERT_DLEN; - offset += IP6_OPT_HLEN; - - /* Set router alert option data */ - opt_data = (u8_t *)hbh_hdr + offset; - opt_data[0] = value; - opt_data[1] = 0; - offset += IP6_OPT_DLEN(opt_hdr); - - /* add 2 bytes padding to make 8 bytes Hop-by-Hop header length */ - opt_hdr = (struct ip6_opt_hdr *)((u8_t *)hbh_hdr + offset); - IP6_OPT_TYPE(opt_hdr) = IP6_PADN_OPTION; - IP6_OPT_DLEN(opt_hdr) = 0; - - return ERR_OK; -} -#endif /* LWIP_IPV6_MLD */ - -#if IP6_DEBUG -/* Print an IPv6 header by using LWIP_DEBUGF - * @param p an IPv6 packet, p->payload pointing to the IPv6 header - */ -void -ip6_debug_print(struct pbuf *p) -{ - struct ip6_hdr *ip6hdr = (struct ip6_hdr *)p->payload; - - LWIP_DEBUGF(IP6_DEBUG, ("IPv6 header:\n")); - LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(IP6_DEBUG, ("| %2"U16_F" | %3"U16_F" | %7"U32_F" | (ver, class, flow)\n", - IP6H_V(ip6hdr), - IP6H_TC(ip6hdr), - IP6H_FL(ip6hdr))); - LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(IP6_DEBUG, ("| %5"U16_F" | %3"U16_F" | %3"U16_F" | (plen, nexth, hopl)\n", - IP6H_PLEN(ip6hdr), - IP6H_NEXTH(ip6hdr), - IP6H_HOPLIM(ip6hdr))); - LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" | (src)\n", - IP6_ADDR_BLOCK1(&(ip6hdr->src)), - IP6_ADDR_BLOCK2(&(ip6hdr->src)), - IP6_ADDR_BLOCK3(&(ip6hdr->src)), - IP6_ADDR_BLOCK4(&(ip6hdr->src)))); - LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" |\n", - IP6_ADDR_BLOCK5(&(ip6hdr->src)), - IP6_ADDR_BLOCK6(&(ip6hdr->src)), - IP6_ADDR_BLOCK7(&(ip6hdr->src)), - IP6_ADDR_BLOCK8(&(ip6hdr->src)))); - LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" | (dest)\n", - IP6_ADDR_BLOCK1(&(ip6hdr->dest)), - IP6_ADDR_BLOCK2(&(ip6hdr->dest)), - IP6_ADDR_BLOCK3(&(ip6hdr->dest)), - IP6_ADDR_BLOCK4(&(ip6hdr->dest)))); - LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" |\n", - IP6_ADDR_BLOCK5(&(ip6hdr->dest)), - IP6_ADDR_BLOCK6(&(ip6hdr->dest)), - IP6_ADDR_BLOCK7(&(ip6hdr->dest)), - IP6_ADDR_BLOCK8(&(ip6hdr->dest)))); - LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n")); -} -#endif /* IP6_DEBUG */ - -#endif /* LWIP_IPV6 */ diff --git a/third-party/lwip-2.1.2/core/ipv6/ip6_addr.c b/third-party/lwip-2.1.2/core/ipv6/ip6_addr.c deleted file mode 100644 index 687c02f7..00000000 --- a/third-party/lwip-2.1.2/core/ipv6/ip6_addr.c +++ /dev/null @@ -1,343 +0,0 @@ -/** - * @file - * - * IPv6 addresses. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * Functions for handling IPv6 addresses. - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -#include "lwip/opt.h" - -#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/ip_addr.h" -#include "lwip/def.h" - -#include - -#if LWIP_IPV4 -#include "lwip/ip4_addr.h" /* for ip6addr_aton to handle IPv4-mapped addresses */ -#endif /* LWIP_IPV4 */ - -/* used by IP6_ADDR_ANY(6) in ip6_addr.h */ -const ip_addr_t ip6_addr_any = IPADDR6_INIT(0ul, 0ul, 0ul, 0ul); - -#define lwip_xchar(i) ((char)((i) < 10 ? '0' + (i) : 'A' + (i) - 10)) - -/** - * Check whether "cp" is a valid ascii representation - * of an IPv6 address and convert to a binary address. - * Returns 1 if the address is valid, 0 if not. - * - * @param cp IPv6 address in ascii representation (e.g. "FF01::1") - * @param addr pointer to which to save the ip address in network order - * @return 1 if cp could be converted to addr, 0 on failure - */ -int -ip6addr_aton(const char *cp, ip6_addr_t *addr) -{ - u32_t addr_index, zero_blocks, current_block_index, current_block_value; - const char *s; -#if LWIP_IPV4 - int check_ipv4_mapped = 0; -#endif /* LWIP_IPV4 */ - - /* Count the number of colons, to count the number of blocks in a "::" sequence - zero_blocks may be 1 even if there are no :: sequences */ - zero_blocks = 8; - for (s = cp; *s != 0; s++) { - if (*s == ':') { - zero_blocks--; -#if LWIP_IPV4 - } else if (*s == '.') { - if ((zero_blocks == 5) ||(zero_blocks == 2)) { - check_ipv4_mapped = 1; - /* last block could be the start of an IPv4 address */ - zero_blocks--; - } else { - /* invalid format */ - return 0; - } - break; -#endif /* LWIP_IPV4 */ - } else if (!lwip_isxdigit(*s)) { - break; - } - } - - /* parse each block */ - addr_index = 0; - current_block_index = 0; - current_block_value = 0; - for (s = cp; *s != 0; s++) { - if (*s == ':') { - if (addr) { - if (current_block_index & 0x1) { - addr->addr[addr_index++] |= current_block_value; - } - else { - addr->addr[addr_index] = current_block_value << 16; - } - } - current_block_index++; -#if LWIP_IPV4 - if (check_ipv4_mapped) { - if (current_block_index == 6) { - ip4_addr_t ip4; - int ret = ip4addr_aton(s + 1, &ip4); - if (ret) { - if (addr) { - addr->addr[3] = lwip_htonl(ip4.addr); - current_block_index++; - goto fix_byte_order_and_return; - } - return 1; - } - } - } -#endif /* LWIP_IPV4 */ - current_block_value = 0; - if (current_block_index > 7) { - /* address too long! */ - return 0; - } - if (s[1] == ':') { - if (s[2] == ':') { - /* invalid format: three successive colons */ - return 0; - } - s++; - /* "::" found, set zeros */ - while (zero_blocks > 0) { - zero_blocks--; - if (current_block_index & 0x1) { - addr_index++; - } else { - if (addr) { - addr->addr[addr_index] = 0; - } - } - current_block_index++; - if (current_block_index > 7) { - /* address too long! */ - return 0; - } - } - } - } else if (lwip_isxdigit(*s)) { - /* add current digit */ - current_block_value = (current_block_value << 4) + - (lwip_isdigit(*s) ? (u32_t)(*s - '0') : - (u32_t)(10 + (lwip_islower(*s) ? *s - 'a' : *s - 'A'))); - } else { - /* unexpected digit, space? CRLF? */ - break; - } - } - - if (addr) { - if (current_block_index & 0x1) { - addr->addr[addr_index++] |= current_block_value; - } - else { - addr->addr[addr_index] = current_block_value << 16; - } -#if LWIP_IPV4 -fix_byte_order_and_return: -#endif - /* convert to network byte order. */ - for (addr_index = 0; addr_index < 4; addr_index++) { - addr->addr[addr_index] = lwip_htonl(addr->addr[addr_index]); - } - - ip6_addr_clear_zone(addr); - } - - if (current_block_index != 7) { - return 0; - } - - return 1; -} - -/** - * Convert numeric IPv6 address into ASCII representation. - * returns ptr to static buffer; not reentrant! - * - * @param addr ip6 address in network order to convert - * @return pointer to a global static (!) buffer that holds the ASCII - * representation of addr - */ -char * -ip6addr_ntoa(const ip6_addr_t *addr) -{ - static char str[40]; - return ip6addr_ntoa_r(addr, str, 40); -} - -/** - * Same as ipaddr_ntoa, but reentrant since a user-supplied buffer is used. - * - * @param addr ip6 address in network order to convert - * @param buf target buffer where the string is stored - * @param buflen length of buf - * @return either pointer to buf which now holds the ASCII - * representation of addr or NULL if buf was too small - */ -char * -ip6addr_ntoa_r(const ip6_addr_t *addr, char *buf, int buflen) -{ - u32_t current_block_index, current_block_value, next_block_value; - s32_t i; - u8_t zero_flag, empty_block_flag; - -#if LWIP_IPV4 - if (ip6_addr_isipv4mappedipv6(addr)) { - /* This is an IPv4 mapped address */ - ip4_addr_t addr4; - char *ret; -#define IP4MAPPED_HEADER "::FFFF:" - char *buf_ip4 = buf + sizeof(IP4MAPPED_HEADER) - 1; - int buflen_ip4 = buflen - sizeof(IP4MAPPED_HEADER) + 1; - if (buflen < (int)sizeof(IP4MAPPED_HEADER)) { - return NULL; - } - memcpy(buf, IP4MAPPED_HEADER, sizeof(IP4MAPPED_HEADER)); - addr4.addr = addr->addr[3]; - ret = ip4addr_ntoa_r(&addr4, buf_ip4, buflen_ip4); - if (ret != buf_ip4) { - return NULL; - } - return buf; - } -#endif /* LWIP_IPV4 */ - i = 0; - empty_block_flag = 0; /* used to indicate a zero chain for "::' */ - - for (current_block_index = 0; current_block_index < 8; current_block_index++) { - /* get the current 16-bit block */ - current_block_value = lwip_htonl(addr->addr[current_block_index >> 1]); - if ((current_block_index & 0x1) == 0) { - current_block_value = current_block_value >> 16; - } - current_block_value &= 0xffff; - - /* Check for empty block. */ - if (current_block_value == 0) { - if (current_block_index == 7 && empty_block_flag == 1) { - /* special case, we must render a ':' for the last block. */ - buf[i++] = ':'; - if (i >= buflen) { - return NULL; - } - break; - } - if (empty_block_flag == 0) { - /* generate empty block "::", but only if more than one contiguous zero block, - * according to current formatting suggestions RFC 5952. */ - next_block_value = lwip_htonl(addr->addr[(current_block_index + 1) >> 1]); - if ((current_block_index & 0x1) == 0x01) { - next_block_value = next_block_value >> 16; - } - next_block_value &= 0xffff; - if (next_block_value == 0) { - empty_block_flag = 1; - buf[i++] = ':'; - if (i >= buflen) { - return NULL; - } - continue; /* move on to next block. */ - } - } else if (empty_block_flag == 1) { - /* move on to next block. */ - continue; - } - } else if (empty_block_flag == 1) { - /* Set this flag value so we don't produce multiple empty blocks. */ - empty_block_flag = 2; - } - - if (current_block_index > 0) { - buf[i++] = ':'; - if (i >= buflen) { - return NULL; - } - } - - if ((current_block_value & 0xf000) == 0) { - zero_flag = 1; - } else { - buf[i++] = lwip_xchar(((current_block_value & 0xf000) >> 12)); - zero_flag = 0; - if (i >= buflen) { - return NULL; - } - } - - if (((current_block_value & 0xf00) == 0) && (zero_flag)) { - /* do nothing */ - } else { - buf[i++] = lwip_xchar(((current_block_value & 0xf00) >> 8)); - zero_flag = 0; - if (i >= buflen) { - return NULL; - } - } - - if (((current_block_value & 0xf0) == 0) && (zero_flag)) { - /* do nothing */ - } - else { - buf[i++] = lwip_xchar(((current_block_value & 0xf0) >> 4)); - zero_flag = 0; - if (i >= buflen) { - return NULL; - } - } - - buf[i++] = lwip_xchar((current_block_value & 0xf)); - if (i >= buflen) { - return NULL; - } - } - - buf[i] = 0; - - return buf; -} - -#endif /* LWIP_IPV6 */ diff --git a/third-party/lwip-2.1.2/core/ipv6/ip6_frag.c b/third-party/lwip-2.1.2/core/ipv6/ip6_frag.c deleted file mode 100644 index d6c5d223..00000000 --- a/third-party/lwip-2.1.2/core/ipv6/ip6_frag.c +++ /dev/null @@ -1,862 +0,0 @@ -/** - * @file - * - * IPv6 fragmentation and reassembly. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -#include "lwip/opt.h" -#include "lwip/ip6_frag.h" -#include "lwip/ip6.h" -#include "lwip/icmp6.h" -#include "lwip/nd6.h" -#include "lwip/ip.h" - -#include "lwip/pbuf.h" -#include "lwip/memp.h" -#include "lwip/stats.h" - -#include - -#if LWIP_IPV6 && LWIP_IPV6_REASS /* don't build if not configured for use in lwipopts.h */ - - -/** Setting this to 0, you can turn off checking the fragments for overlapping - * regions. The code gets a little smaller. Only use this if you know that - * overlapping won't occur on your network! */ -#ifndef IP_REASS_CHECK_OVERLAP -#define IP_REASS_CHECK_OVERLAP 1 -#endif /* IP_REASS_CHECK_OVERLAP */ - -/** Set to 0 to prevent freeing the oldest datagram when the reassembly buffer is - * full (IP_REASS_MAX_PBUFS pbufs are enqueued). The code gets a little smaller. - * Datagrams will be freed by timeout only. Especially useful when MEMP_NUM_REASSDATA - * is set to 1, so one datagram can be reassembled at a time, only. */ -#ifndef IP_REASS_FREE_OLDEST -#define IP_REASS_FREE_OLDEST 1 -#endif /* IP_REASS_FREE_OLDEST */ - -#if IPV6_FRAG_COPYHEADER -/* The number of bytes we need to "borrow" from (i.e., overwrite in) the header - * that precedes the fragment header for reassembly pruposes. */ -#define IPV6_FRAG_REQROOM ((s16_t)(sizeof(struct ip6_reass_helper) - IP6_FRAG_HLEN)) -#endif - -#define IP_REASS_FLAG_LASTFRAG 0x01 - -/** This is a helper struct which holds the starting - * offset and the ending offset of this fragment to - * easily chain the fragments. - * It has the same packing requirements as the IPv6 header, since it replaces - * the Fragment Header in memory in incoming fragments to keep - * track of the various fragments. - */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ip6_reass_helper { - PACK_STRUCT_FIELD(struct pbuf *next_pbuf); - PACK_STRUCT_FIELD(u16_t start); - PACK_STRUCT_FIELD(u16_t end); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/* static variables */ -static struct ip6_reassdata *reassdatagrams; -static u16_t ip6_reass_pbufcount; - -/* Forward declarations. */ -static void ip6_reass_free_complete_datagram(struct ip6_reassdata *ipr); -#if IP_REASS_FREE_OLDEST -static void ip6_reass_remove_oldest_datagram(struct ip6_reassdata *ipr, int pbufs_needed); -#endif /* IP_REASS_FREE_OLDEST */ - -void -ip6_reass_tmr(void) -{ - struct ip6_reassdata *r, *tmp; - -#if !IPV6_FRAG_COPYHEADER - LWIP_ASSERT("sizeof(struct ip6_reass_helper) <= IP6_FRAG_HLEN, set IPV6_FRAG_COPYHEADER to 1", - sizeof(struct ip6_reass_helper) <= IP6_FRAG_HLEN); -#endif /* !IPV6_FRAG_COPYHEADER */ - - r = reassdatagrams; - while (r != NULL) { - /* Decrement the timer. Once it reaches 0, - * clean up the incomplete fragment assembly */ - if (r->timer > 0) { - r->timer--; - r = r->next; - } else { - /* reassembly timed out */ - tmp = r; - /* get the next pointer before freeing */ - r = r->next; - /* free the helper struct and all enqueued pbufs */ - ip6_reass_free_complete_datagram(tmp); - } - } -} - -/** - * Free a datagram (struct ip6_reassdata) and all its pbufs. - * Updates the total count of enqueued pbufs (ip6_reass_pbufcount), - * sends an ICMP time exceeded packet. - * - * @param ipr datagram to free - */ -static void -ip6_reass_free_complete_datagram(struct ip6_reassdata *ipr) -{ - struct ip6_reassdata *prev; - u16_t pbufs_freed = 0; - u16_t clen; - struct pbuf *p; - struct ip6_reass_helper *iprh; - -#if LWIP_ICMP6 - iprh = (struct ip6_reass_helper *)ipr->p->payload; - if (iprh->start == 0) { - /* The first fragment was received, send ICMP time exceeded. */ - /* First, de-queue the first pbuf from r->p. */ - p = ipr->p; - ipr->p = iprh->next_pbuf; - /* Restore the part that we've overwritten with our helper structure, or we - * might send garbage (and disclose a pointer) in the ICMPv6 reply. */ - MEMCPY(p->payload, ipr->orig_hdr, sizeof(iprh)); - /* Then, move back to the original ipv6 header (we are now pointing to Fragment header). - This cannot fail since we already checked when receiving this fragment. */ - if (pbuf_header_force(p, (s16_t)((u8_t*)p->payload - (u8_t*)ipr->iphdr))) { - LWIP_ASSERT("ip6_reass_free: moving p->payload to ip6 header failed\n", 0); - } - else { - /* Reconstruct the zoned source and destination addresses, so that we do - * not end up sending the ICMP response over the wrong link. */ - ip6_addr_t src_addr, dest_addr; - ip6_addr_copy_from_packed(src_addr, IPV6_FRAG_SRC(ipr)); - ip6_addr_set_zone(&src_addr, ipr->src_zone); - ip6_addr_copy_from_packed(dest_addr, IPV6_FRAG_DEST(ipr)); - ip6_addr_set_zone(&dest_addr, ipr->dest_zone); - /* Send the actual ICMP response. */ - icmp6_time_exceeded_with_addrs(p, ICMP6_TE_FRAG, &src_addr, &dest_addr); - } - clen = pbuf_clen(p); - LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff); - pbufs_freed = (u16_t)(pbufs_freed + clen); - pbuf_free(p); - } -#endif /* LWIP_ICMP6 */ - - /* First, free all received pbufs. The individual pbufs need to be released - separately as they have not yet been chained */ - p = ipr->p; - while (p != NULL) { - struct pbuf *pcur; - iprh = (struct ip6_reass_helper *)p->payload; - pcur = p; - /* get the next pointer before freeing */ - p = iprh->next_pbuf; - clen = pbuf_clen(pcur); - LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff); - pbufs_freed = (u16_t)(pbufs_freed + clen); - pbuf_free(pcur); - } - - /* Then, unchain the struct ip6_reassdata from the list and free it. */ - if (ipr == reassdatagrams) { - reassdatagrams = ipr->next; - } else { - prev = reassdatagrams; - while (prev != NULL) { - if (prev->next == ipr) { - break; - } - prev = prev->next; - } - if (prev != NULL) { - prev->next = ipr->next; - } - } - memp_free(MEMP_IP6_REASSDATA, ipr); - - /* Finally, update number of pbufs in reassembly queue */ - LWIP_ASSERT("ip_reass_pbufcount >= clen", ip6_reass_pbufcount >= pbufs_freed); - ip6_reass_pbufcount = (u16_t)(ip6_reass_pbufcount - pbufs_freed); -} - -#if IP_REASS_FREE_OLDEST -/** - * Free the oldest datagram to make room for enqueueing new fragments. - * The datagram ipr is not freed! - * - * @param ipr ip6_reassdata for the current fragment - * @param pbufs_needed number of pbufs needed to enqueue - * (used for freeing other datagrams if not enough space) - */ -static void -ip6_reass_remove_oldest_datagram(struct ip6_reassdata *ipr, int pbufs_needed) -{ - struct ip6_reassdata *r, *oldest; - - /* Free datagrams until being allowed to enqueue 'pbufs_needed' pbufs, - * but don't free the current datagram! */ - do { - r = oldest = reassdatagrams; - while (r != NULL) { - if (r != ipr) { - if (r->timer <= oldest->timer) { - /* older than the previous oldest */ - oldest = r; - } - } - r = r->next; - } - if (oldest == ipr) { - /* nothing to free, ipr is the only element on the list */ - return; - } - if (oldest != NULL) { - ip6_reass_free_complete_datagram(oldest); - } - } while (((ip6_reass_pbufcount + pbufs_needed) > IP_REASS_MAX_PBUFS) && (reassdatagrams != NULL)); -} -#endif /* IP_REASS_FREE_OLDEST */ - -/** - * Reassembles incoming IPv6 fragments into an IPv6 datagram. - * - * @param p points to the IPv6 Fragment Header - * @return NULL if reassembly is incomplete, pbuf pointing to - * IPv6 Header if reassembly is complete - */ -struct pbuf * -ip6_reass(struct pbuf *p) -{ - struct ip6_reassdata *ipr, *ipr_prev; - struct ip6_reass_helper *iprh, *iprh_tmp, *iprh_prev=NULL; - struct ip6_frag_hdr *frag_hdr; - u16_t offset, len, start, end; - ptrdiff_t hdrdiff; - u16_t clen; - u8_t valid = 1; - struct pbuf *q, *next_pbuf; - - IP6_FRAG_STATS_INC(ip6_frag.recv); - - /* ip6_frag_hdr must be in the first pbuf, not chained. Checked by caller. */ - LWIP_ASSERT("IPv6 fragment header does not fit in first pbuf", - p->len >= sizeof(struct ip6_frag_hdr)); - - frag_hdr = (struct ip6_frag_hdr *) p->payload; - - clen = pbuf_clen(p); - - offset = lwip_ntohs(frag_hdr->_fragment_offset); - - /* Calculate fragment length from IPv6 payload length. - * Adjust for headers before Fragment Header. - * And finally adjust by Fragment Header length. */ - len = lwip_ntohs(ip6_current_header()->_plen); - hdrdiff = (u8_t*)p->payload - (const u8_t*)ip6_current_header(); - LWIP_ASSERT("not a valid pbuf (ip6_input check missing?)", hdrdiff <= 0xFFFF); - LWIP_ASSERT("not a valid pbuf (ip6_input check missing?)", hdrdiff >= IP6_HLEN); - hdrdiff -= IP6_HLEN; - hdrdiff += IP6_FRAG_HLEN; - if (hdrdiff > len) { - IP6_FRAG_STATS_INC(ip6_frag.proterr); - goto nullreturn; - } - len = (u16_t)(len - hdrdiff); - start = (offset & IP6_FRAG_OFFSET_MASK); - if (start > (0xFFFF - len)) { - /* u16_t overflow, cannot handle this */ - IP6_FRAG_STATS_INC(ip6_frag.proterr); - goto nullreturn; - } - - /* Look for the datagram the fragment belongs to in the current datagram queue, - * remembering the previous in the queue for later dequeueing. */ - for (ipr = reassdatagrams, ipr_prev = NULL; ipr != NULL; ipr = ipr->next) { - /* Check if the incoming fragment matches the one currently present - in the reassembly buffer. If so, we proceed with copying the - fragment into the buffer. */ - if ((frag_hdr->_identification == ipr->identification) && - ip6_addr_cmp_packed(ip6_current_src_addr(), &(IPV6_FRAG_SRC(ipr)), ipr->src_zone) && - ip6_addr_cmp_packed(ip6_current_dest_addr(), &(IPV6_FRAG_DEST(ipr)), ipr->dest_zone)) { - IP6_FRAG_STATS_INC(ip6_frag.cachehit); - break; - } - ipr_prev = ipr; - } - - if (ipr == NULL) { - /* Enqueue a new datagram into the datagram queue */ - ipr = (struct ip6_reassdata *)memp_malloc(MEMP_IP6_REASSDATA); - if (ipr == NULL) { -#if IP_REASS_FREE_OLDEST - /* Make room and try again. */ - ip6_reass_remove_oldest_datagram(ipr, clen); - ipr = (struct ip6_reassdata *)memp_malloc(MEMP_IP6_REASSDATA); - if (ipr != NULL) { - /* re-search ipr_prev since it might have been removed */ - for (ipr_prev = reassdatagrams; ipr_prev != NULL; ipr_prev = ipr_prev->next) { - if (ipr_prev->next == ipr) { - break; - } - } - } else -#endif /* IP_REASS_FREE_OLDEST */ - { - IP6_FRAG_STATS_INC(ip6_frag.memerr); - goto nullreturn; - } - } - - memset(ipr, 0, sizeof(struct ip6_reassdata)); - ipr->timer = IPV6_REASS_MAXAGE; - - /* enqueue the new structure to the front of the list */ - ipr->next = reassdatagrams; - reassdatagrams = ipr; - - /* Use the current IPv6 header for src/dest address reference. - * Eventually, we will replace it when we get the first fragment - * (it might be this one, in any case, it is done later). */ - /* need to use the none-const pointer here: */ - ipr->iphdr = ip_data.current_ip6_header; -#if IPV6_FRAG_COPYHEADER - MEMCPY(&ipr->src, &ip6_current_header()->src, sizeof(ipr->src)); - MEMCPY(&ipr->dest, &ip6_current_header()->dest, sizeof(ipr->dest)); -#endif /* IPV6_FRAG_COPYHEADER */ -#if LWIP_IPV6_SCOPES - /* Also store the address zone information. - * @todo It is possible that due to netif destruction and recreation, the - * stored zones end up resolving to a different interface. In that case, we - * risk sending a "time exceeded" ICMP response over the wrong link. - * Ideally, netif destruction would clean up matching pending reassembly - * structures, but custom zone mappings would make that non-trivial. */ - ipr->src_zone = ip6_addr_zone(ip6_current_src_addr()); - ipr->dest_zone = ip6_addr_zone(ip6_current_dest_addr()); -#endif /* LWIP_IPV6_SCOPES */ - /* copy the fragmented packet id. */ - ipr->identification = frag_hdr->_identification; - - /* copy the nexth field */ - ipr->nexth = frag_hdr->_nexth; - } - - /* Check if we are allowed to enqueue more datagrams. */ - if ((ip6_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS) { -#if IP_REASS_FREE_OLDEST - ip6_reass_remove_oldest_datagram(ipr, clen); - if ((ip6_reass_pbufcount + clen) <= IP_REASS_MAX_PBUFS) { - /* re-search ipr_prev since it might have been removed */ - for (ipr_prev = reassdatagrams; ipr_prev != NULL; ipr_prev = ipr_prev->next) { - if (ipr_prev->next == ipr) { - break; - } - } - } else -#endif /* IP_REASS_FREE_OLDEST */ - { - /* @todo: send ICMPv6 time exceeded here? */ - /* drop this pbuf */ - IP6_FRAG_STATS_INC(ip6_frag.memerr); - goto nullreturn; - } - } - - /* Overwrite Fragment Header with our own helper struct. */ -#if IPV6_FRAG_COPYHEADER - if (IPV6_FRAG_REQROOM > 0) { - /* Make room for struct ip6_reass_helper (only required if sizeof(void*) > 4). - This cannot fail since we already checked when receiving this fragment. */ - u8_t hdrerr = pbuf_header_force(p, IPV6_FRAG_REQROOM); - LWIP_UNUSED_ARG(hdrerr); /* in case of LWIP_NOASSERT */ - LWIP_ASSERT("no room for struct ip6_reass_helper", hdrerr == 0); - } -#else /* IPV6_FRAG_COPYHEADER */ - LWIP_ASSERT("sizeof(struct ip6_reass_helper) <= IP6_FRAG_HLEN, set IPV6_FRAG_COPYHEADER to 1", - sizeof(struct ip6_reass_helper) <= IP6_FRAG_HLEN); -#endif /* IPV6_FRAG_COPYHEADER */ - - /* Prepare the pointer to the helper structure, and its initial values. - * Do not yet write to the structure itself, as we still have to make a - * backup of the original data, and we should not do that until we know for - * sure that we are going to add this packet to the list. */ - iprh = (struct ip6_reass_helper *)p->payload; - next_pbuf = NULL; - end = (u16_t)(start + len); - - /* find the right place to insert this pbuf */ - /* Iterate through until we either get to the end of the list (append), - * or we find on with a larger offset (insert). */ - for (q = ipr->p; q != NULL;) { - iprh_tmp = (struct ip6_reass_helper*)q->payload; - if (start < iprh_tmp->start) { -#if IP_REASS_CHECK_OVERLAP - if (end > iprh_tmp->start) { - /* fragment overlaps with following, throw away */ - IP6_FRAG_STATS_INC(ip6_frag.proterr); - goto nullreturn; - } - if (iprh_prev != NULL) { - if (start < iprh_prev->end) { - /* fragment overlaps with previous, throw away */ - IP6_FRAG_STATS_INC(ip6_frag.proterr); - goto nullreturn; - } - } -#endif /* IP_REASS_CHECK_OVERLAP */ - /* the new pbuf should be inserted before this */ - next_pbuf = q; - if (iprh_prev != NULL) { - /* not the fragment with the lowest offset */ - iprh_prev->next_pbuf = p; - } else { - /* fragment with the lowest offset */ - ipr->p = p; - } - break; - } else if (start == iprh_tmp->start) { - /* received the same datagram twice: no need to keep the datagram */ - goto nullreturn; -#if IP_REASS_CHECK_OVERLAP - } else if (start < iprh_tmp->end) { - /* overlap: no need to keep the new datagram */ - IP6_FRAG_STATS_INC(ip6_frag.proterr); - goto nullreturn; -#endif /* IP_REASS_CHECK_OVERLAP */ - } else { - /* Check if the fragments received so far have no gaps. */ - if (iprh_prev != NULL) { - if (iprh_prev->end != iprh_tmp->start) { - /* There is a fragment missing between the current - * and the previous fragment */ - valid = 0; - } - } - } - q = iprh_tmp->next_pbuf; - iprh_prev = iprh_tmp; - } - - /* If q is NULL, then we made it to the end of the list. Determine what to do now */ - if (q == NULL) { - if (iprh_prev != NULL) { - /* this is (for now), the fragment with the highest offset: - * chain it to the last fragment */ -#if IP_REASS_CHECK_OVERLAP - LWIP_ASSERT("check fragments don't overlap", iprh_prev->end <= start); -#endif /* IP_REASS_CHECK_OVERLAP */ - iprh_prev->next_pbuf = p; - if (iprh_prev->end != start) { - valid = 0; - } - } else { -#if IP_REASS_CHECK_OVERLAP - LWIP_ASSERT("no previous fragment, this must be the first fragment!", - ipr->p == NULL); -#endif /* IP_REASS_CHECK_OVERLAP */ - /* this is the first fragment we ever received for this ip datagram */ - ipr->p = p; - } - } - - /* Track the current number of pbufs current 'in-flight', in order to limit - the number of fragments that may be enqueued at any one time */ - ip6_reass_pbufcount = (u16_t)(ip6_reass_pbufcount + clen); - - /* Remember IPv6 header if this is the first fragment. */ - if (start == 0) { - /* need to use the none-const pointer here: */ - ipr->iphdr = ip_data.current_ip6_header; - /* Make a backup of the part of the packet data that we are about to - * overwrite, so that we can restore the original later. */ - MEMCPY(ipr->orig_hdr, p->payload, sizeof(*iprh)); - /* For IPV6_FRAG_COPYHEADER there is no need to copy src/dst again, as they - * will be the same as they were. With LWIP_IPV6_SCOPES, the same applies - * to the source/destination zones. */ - } - /* Only after the backup do we get to fill in the actual helper structure. */ - iprh->next_pbuf = next_pbuf; - iprh->start = start; - iprh->end = end; - - /* If this is the last fragment, calculate total packet length. */ - if ((offset & IP6_FRAG_MORE_FLAG) == 0) { - ipr->datagram_len = iprh->end; - } - - /* Additional validity tests: we have received first and last fragment. */ - iprh_tmp = (struct ip6_reass_helper*)ipr->p->payload; - if (iprh_tmp->start != 0) { - valid = 0; - } - if (ipr->datagram_len == 0) { - valid = 0; - } - - /* Final validity test: no gaps between current and last fragment. */ - iprh_prev = iprh; - q = iprh->next_pbuf; - while ((q != NULL) && valid) { - iprh = (struct ip6_reass_helper*)q->payload; - if (iprh_prev->end != iprh->start) { - valid = 0; - break; - } - iprh_prev = iprh; - q = iprh->next_pbuf; - } - - if (valid) { - /* All fragments have been received */ - struct ip6_hdr* iphdr_ptr; - - /* chain together the pbufs contained within the ip6_reassdata list. */ - iprh = (struct ip6_reass_helper*) ipr->p->payload; - while (iprh != NULL) { - next_pbuf = iprh->next_pbuf; - if (next_pbuf != NULL) { - /* Save next helper struct (will be hidden in next step). */ - iprh_tmp = (struct ip6_reass_helper*)next_pbuf->payload; - - /* hide the fragment header for every succeeding fragment */ - pbuf_remove_header(next_pbuf, IP6_FRAG_HLEN); -#if IPV6_FRAG_COPYHEADER - if (IPV6_FRAG_REQROOM > 0) { - /* hide the extra bytes borrowed from ip6_hdr for struct ip6_reass_helper */ - u8_t hdrerr = pbuf_remove_header(next_pbuf, IPV6_FRAG_REQROOM); - LWIP_UNUSED_ARG(hdrerr); /* in case of LWIP_NOASSERT */ - LWIP_ASSERT("no room for struct ip6_reass_helper", hdrerr == 0); - } -#endif - pbuf_cat(ipr->p, next_pbuf); - } - else { - iprh_tmp = NULL; - } - - iprh = iprh_tmp; - } - - /* Get the first pbuf. */ - p = ipr->p; - -#if IPV6_FRAG_COPYHEADER - if (IPV6_FRAG_REQROOM > 0) { - u8_t hdrerr; - /* Restore (only) the bytes that we overwrote beyond the fragment header. - * Those bytes may belong to either the IPv6 header or an extension - * header placed before the fragment header. */ - MEMCPY(p->payload, ipr->orig_hdr, IPV6_FRAG_REQROOM); - /* get back room for struct ip6_reass_helper (only required if sizeof(void*) > 4) */ - hdrerr = pbuf_remove_header(p, IPV6_FRAG_REQROOM); - LWIP_UNUSED_ARG(hdrerr); /* in case of LWIP_NOASSERT */ - LWIP_ASSERT("no room for struct ip6_reass_helper", hdrerr == 0); - } -#endif - - /* We need to get rid of the fragment header itself, which is somewhere in - * the middle of the packet (but still in the first pbuf of the chain). - * Getting rid of the header is required by RFC 2460 Sec. 4.5 and necessary - * in order to be able to reassemble packets that are close to full size - * (i.e., around 65535 bytes). We simply move up all the headers before the - * fragment header, including the IPv6 header, and adjust the payload start - * accordingly. This works because all these headers are in the first pbuf - * of the chain, and because the caller adjusts all its pointers on - * successful reassembly. */ - MEMMOVE((u8_t*)ipr->iphdr + sizeof(struct ip6_frag_hdr), ipr->iphdr, - (size_t)((u8_t*)p->payload - (u8_t*)ipr->iphdr)); - - /* This is where the IPv6 header is now. */ - iphdr_ptr = (struct ip6_hdr*)((u8_t*)ipr->iphdr + - sizeof(struct ip6_frag_hdr)); - - /* Adjust datagram length by adding header lengths. */ - ipr->datagram_len = (u16_t)(ipr->datagram_len + ((u8_t*)p->payload - (u8_t*)iphdr_ptr) - - IP6_HLEN); - - /* Set payload length in ip header. */ - iphdr_ptr->_plen = lwip_htons(ipr->datagram_len); - - /* With the fragment header gone, we now need to adjust the next-header - * field of whatever header was originally before it. Since the packet made - * it through the original header processing routines at least up to the - * fragment header, we do not need any further sanity checks here. */ - if (IP6H_NEXTH(iphdr_ptr) == IP6_NEXTH_FRAGMENT) { - iphdr_ptr->_nexth = ipr->nexth; - } else { - u8_t *ptr = (u8_t *)iphdr_ptr + IP6_HLEN; - while (*ptr != IP6_NEXTH_FRAGMENT) { - ptr += 8 * (1 + ptr[1]); - } - *ptr = ipr->nexth; - } - - /* release the resources allocated for the fragment queue entry */ - if (reassdatagrams == ipr) { - /* it was the first in the list */ - reassdatagrams = ipr->next; - } else { - /* it wasn't the first, so it must have a valid 'prev' */ - LWIP_ASSERT("sanity check linked list", ipr_prev != NULL); - ipr_prev->next = ipr->next; - } - memp_free(MEMP_IP6_REASSDATA, ipr); - - /* adjust the number of pbufs currently queued for reassembly. */ - clen = pbuf_clen(p); - LWIP_ASSERT("ip6_reass_pbufcount >= clen", ip6_reass_pbufcount >= clen); - ip6_reass_pbufcount = (u16_t)(ip6_reass_pbufcount - clen); - - /* Move pbuf back to IPv6 header. This should never fail. */ - if (pbuf_header_force(p, (s16_t)((u8_t*)p->payload - (u8_t*)iphdr_ptr))) { - LWIP_ASSERT("ip6_reass: moving p->payload to ip6 header failed\n", 0); - pbuf_free(p); - return NULL; - } - - /* Return the pbuf chain */ - return p; - } - /* the datagram is not (yet?) reassembled completely */ - return NULL; - -nullreturn: - IP6_FRAG_STATS_INC(ip6_frag.drop); - pbuf_free(p); - return NULL; -} - -#endif /* LWIP_IPV6 && LWIP_IPV6_REASS */ - -#if LWIP_IPV6 && LWIP_IPV6_FRAG - -#if !LWIP_NETIF_TX_SINGLE_PBUF -/** Allocate a new struct pbuf_custom_ref */ -static struct pbuf_custom_ref* -ip6_frag_alloc_pbuf_custom_ref(void) -{ - return (struct pbuf_custom_ref*)memp_malloc(MEMP_FRAG_PBUF); -} - -/** Free a struct pbuf_custom_ref */ -static void -ip6_frag_free_pbuf_custom_ref(struct pbuf_custom_ref* p) -{ - LWIP_ASSERT("p != NULL", p != NULL); - memp_free(MEMP_FRAG_PBUF, p); -} - -/** Free-callback function to free a 'struct pbuf_custom_ref', called by - * pbuf_free. */ -static void -ip6_frag_free_pbuf_custom(struct pbuf *p) -{ - struct pbuf_custom_ref *pcr = (struct pbuf_custom_ref*)p; - LWIP_ASSERT("pcr != NULL", pcr != NULL); - LWIP_ASSERT("pcr == p", (void*)pcr == (void*)p); - if (pcr->original != NULL) { - pbuf_free(pcr->original); - } - ip6_frag_free_pbuf_custom_ref(pcr); -} -#endif /* !LWIP_NETIF_TX_SINGLE_PBUF */ - -/** - * Fragment an IPv6 datagram if too large for the netif or path MTU. - * - * Chop the datagram in MTU sized chunks and send them in order - * by pointing PBUF_REFs into p - * - * @param p ipv6 packet to send - * @param netif the netif on which to send - * @param dest destination ipv6 address to which to send - * - * @return ERR_OK if sent successfully, err_t otherwise - */ -err_t -ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest) -{ - struct ip6_hdr *original_ip6hdr; - struct ip6_hdr *ip6hdr; - struct ip6_frag_hdr *frag_hdr; - struct pbuf *rambuf; -#if !LWIP_NETIF_TX_SINGLE_PBUF - struct pbuf *newpbuf; - u16_t newpbuflen = 0; - u16_t left_to_copy; -#endif - static u32_t identification; - u16_t left, cop; - const u16_t mtu = nd6_get_destination_mtu(dest, netif); - const u16_t nfb = (u16_t)((mtu - (IP6_HLEN + IP6_FRAG_HLEN)) & IP6_FRAG_OFFSET_MASK); - u16_t fragment_offset = 0; - u16_t last; - u16_t poff = IP6_HLEN; - - identification++; - - original_ip6hdr = (struct ip6_hdr *)p->payload; - - /* @todo we assume there are no options in the unfragmentable part (IPv6 header). */ - LWIP_ASSERT("p->tot_len >= IP6_HLEN", p->tot_len >= IP6_HLEN); - left = (u16_t)(p->tot_len - IP6_HLEN); - - while (left) { - last = (left <= nfb); - - /* Fill this fragment */ - cop = last ? left : nfb; - -#if LWIP_NETIF_TX_SINGLE_PBUF - rambuf = pbuf_alloc(PBUF_IP, cop + IP6_FRAG_HLEN, PBUF_RAM); - if (rambuf == NULL) { - IP6_FRAG_STATS_INC(ip6_frag.memerr); - return ERR_MEM; - } - LWIP_ASSERT("this needs a pbuf in one piece!", - (rambuf->len == rambuf->tot_len) && (rambuf->next == NULL)); - poff += pbuf_copy_partial(p, (u8_t*)rambuf->payload + IP6_FRAG_HLEN, cop, poff); - /* make room for the IP header */ - if (pbuf_add_header(rambuf, IP6_HLEN)) { - pbuf_free(rambuf); - IP6_FRAG_STATS_INC(ip6_frag.memerr); - return ERR_MEM; - } - /* fill in the IP header */ - SMEMCPY(rambuf->payload, original_ip6hdr, IP6_HLEN); - ip6hdr = (struct ip6_hdr *)rambuf->payload; - frag_hdr = (struct ip6_frag_hdr *)((u8_t*)rambuf->payload + IP6_HLEN); -#else - /* When not using a static buffer, create a chain of pbufs. - * The first will be a PBUF_RAM holding the link, IPv6, and Fragment header. - * The rest will be PBUF_REFs mirroring the pbuf chain to be fragged, - * but limited to the size of an mtu. - */ - rambuf = pbuf_alloc(PBUF_LINK, IP6_HLEN + IP6_FRAG_HLEN, PBUF_RAM); - if (rambuf == NULL) { - IP6_FRAG_STATS_INC(ip6_frag.memerr); - return ERR_MEM; - } - LWIP_ASSERT("this needs a pbuf in one piece!", - (p->len >= (IP6_HLEN))); - SMEMCPY(rambuf->payload, original_ip6hdr, IP6_HLEN); - ip6hdr = (struct ip6_hdr *)rambuf->payload; - frag_hdr = (struct ip6_frag_hdr *)((u8_t*)rambuf->payload + IP6_HLEN); - - /* Can just adjust p directly for needed offset. */ - p->payload = (u8_t *)p->payload + poff; - p->len = (u16_t)(p->len - poff); - p->tot_len = (u16_t)(p->tot_len - poff); - - left_to_copy = cop; - while (left_to_copy) { - struct pbuf_custom_ref *pcr; - newpbuflen = (left_to_copy < p->len) ? left_to_copy : p->len; - /* Is this pbuf already empty? */ - if (!newpbuflen) { - p = p->next; - continue; - } - pcr = ip6_frag_alloc_pbuf_custom_ref(); - if (pcr == NULL) { - pbuf_free(rambuf); - IP6_FRAG_STATS_INC(ip6_frag.memerr); - return ERR_MEM; - } - /* Mirror this pbuf, although we might not need all of it. */ - newpbuf = pbuf_alloced_custom(PBUF_RAW, newpbuflen, PBUF_REF, &pcr->pc, p->payload, newpbuflen); - if (newpbuf == NULL) { - ip6_frag_free_pbuf_custom_ref(pcr); - pbuf_free(rambuf); - IP6_FRAG_STATS_INC(ip6_frag.memerr); - return ERR_MEM; - } - pbuf_ref(p); - pcr->original = p; - pcr->pc.custom_free_function = ip6_frag_free_pbuf_custom; - - /* Add it to end of rambuf's chain, but using pbuf_cat, not pbuf_chain - * so that it is removed when pbuf_dechain is later called on rambuf. - */ - pbuf_cat(rambuf, newpbuf); - left_to_copy = (u16_t)(left_to_copy - newpbuflen); - if (left_to_copy) { - p = p->next; - } - } - poff = newpbuflen; -#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ - - /* Set headers */ - frag_hdr->_nexth = original_ip6hdr->_nexth; - frag_hdr->reserved = 0; - frag_hdr->_fragment_offset = lwip_htons((u16_t)((fragment_offset & IP6_FRAG_OFFSET_MASK) | (last ? 0 : IP6_FRAG_MORE_FLAG))); - frag_hdr->_identification = lwip_htonl(identification); - - IP6H_NEXTH_SET(ip6hdr, IP6_NEXTH_FRAGMENT); - IP6H_PLEN_SET(ip6hdr, (u16_t)(cop + IP6_FRAG_HLEN)); - - /* No need for separate header pbuf - we allowed room for it in rambuf - * when allocated. - */ - IP6_FRAG_STATS_INC(ip6_frag.xmit); - netif->output_ip6(netif, rambuf, dest); - - /* Unfortunately we can't reuse rambuf - the hardware may still be - * using the buffer. Instead we free it (and the ensuing chain) and - * recreate it next time round the loop. If we're lucky the hardware - * will have already sent the packet, the free will really free, and - * there will be zero memory penalty. - */ - - pbuf_free(rambuf); - left = (u16_t)(left - cop); - fragment_offset = (u16_t)(fragment_offset + cop); - } - return ERR_OK; -} - -#endif /* LWIP_IPV6 && LWIP_IPV6_FRAG */ diff --git a/third-party/lwip-2.1.2/core/ipv6/mld6.c b/third-party/lwip-2.1.2/core/ipv6/mld6.c deleted file mode 100644 index 6387d468..00000000 --- a/third-party/lwip-2.1.2/core/ipv6/mld6.c +++ /dev/null @@ -1,626 +0,0 @@ -/** - * @file - * Multicast listener discovery - * - * @defgroup mld6 MLD6 - * @ingroup ip6 - * Multicast listener discovery for IPv6. Aims to be compliant with RFC 2710. - * No support for MLDv2.\n - * Note: The allnodes (ff01::1, ff02::1) group is assumed be received by your - * netif since it must always be received for correct IPv6 operation (e.g. SLAAC). - * Ensure the netif filters are configured accordingly!\n - * The netif flags also need NETIF_FLAG_MLD6 flag set to enable MLD6 on a - * netif ("netif->flags |= NETIF_FLAG_MLD6;").\n - * To be called from TCPIP thread. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -/* Based on igmp.c implementation of igmp v2 protocol */ - -#include "lwip/opt.h" - -#if LWIP_IPV6 && LWIP_IPV6_MLD /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/mld6.h" -#include "lwip/prot/mld6.h" -#include "lwip/icmp6.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#include "lwip/ip.h" -#include "lwip/inet_chksum.h" -#include "lwip/pbuf.h" -#include "lwip/netif.h" -#include "lwip/memp.h" -#include "lwip/stats.h" - -#include - - -/* - * MLD constants - */ -#define MLD6_HL 1 -#define MLD6_JOIN_DELAYING_MEMBER_TMR_MS (500) - -#define MLD6_GROUP_NON_MEMBER 0 -#define MLD6_GROUP_DELAYING_MEMBER 1 -#define MLD6_GROUP_IDLE_MEMBER 2 - -/* Forward declarations. */ -static struct mld_group *mld6_new_group(struct netif *ifp, const ip6_addr_t *addr); -static err_t mld6_remove_group(struct netif *netif, struct mld_group *group); -static void mld6_delayed_report(struct mld_group *group, u16_t maxresp); -static void mld6_send(struct netif *netif, struct mld_group *group, u8_t type); - - -/** - * Stop MLD processing on interface - * - * @param netif network interface on which stop MLD processing - */ -err_t -mld6_stop(struct netif *netif) -{ - struct mld_group *group = netif_mld6_data(netif); - - netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_MLD6, NULL); - - while (group != NULL) { - struct mld_group *next = group->next; /* avoid use-after-free below */ - - /* disable the group at the MAC level */ - if (netif->mld_mac_filter != NULL) { - netif->mld_mac_filter(netif, &(group->group_address), NETIF_DEL_MAC_FILTER); - } - - /* free group */ - memp_free(MEMP_MLD6_GROUP, group); - - /* move to "next" */ - group = next; - } - return ERR_OK; -} - -/** - * Report MLD memberships for this interface - * - * @param netif network interface on which report MLD memberships - */ -void -mld6_report_groups(struct netif *netif) -{ - struct mld_group *group = netif_mld6_data(netif); - - while (group != NULL) { - mld6_delayed_report(group, MLD6_JOIN_DELAYING_MEMBER_TMR_MS); - group = group->next; - } -} - -/** - * Search for a group that is joined on a netif - * - * @param ifp the network interface for which to look - * @param addr the group ipv6 address to search for - * @return a struct mld_group* if the group has been found, - * NULL if the group wasn't found. - */ -struct mld_group * -mld6_lookfor_group(struct netif *ifp, const ip6_addr_t *addr) -{ - struct mld_group *group = netif_mld6_data(ifp); - - while (group != NULL) { - if (ip6_addr_cmp(&(group->group_address), addr)) { - return group; - } - group = group->next; - } - - return NULL; -} - - -/** - * create a new group - * - * @param ifp the network interface for which to create - * @param addr the new group ipv6 - * @return a struct mld_group*, - * NULL on memory error. - */ -static struct mld_group * -mld6_new_group(struct netif *ifp, const ip6_addr_t *addr) -{ - struct mld_group *group; - - group = (struct mld_group *)memp_malloc(MEMP_MLD6_GROUP); - if (group != NULL) { - ip6_addr_set(&(group->group_address), addr); - group->timer = 0; /* Not running */ - group->group_state = MLD6_GROUP_IDLE_MEMBER; - group->last_reporter_flag = 0; - group->use = 0; - group->next = netif_mld6_data(ifp); - - netif_set_client_data(ifp, LWIP_NETIF_CLIENT_DATA_INDEX_MLD6, group); - } - - return group; -} - -/** - * Remove a group from the mld_group_list, but do not free it yet - * - * @param group the group to remove - * @return ERR_OK if group was removed from the list, an err_t otherwise - */ -static err_t -mld6_remove_group(struct netif *netif, struct mld_group *group) -{ - err_t err = ERR_OK; - - /* Is it the first group? */ - if (netif_mld6_data(netif) == group) { - netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_MLD6, group->next); - } else { - /* look for group further down the list */ - struct mld_group *tmpGroup; - for (tmpGroup = netif_mld6_data(netif); tmpGroup != NULL; tmpGroup = tmpGroup->next) { - if (tmpGroup->next == group) { - tmpGroup->next = group->next; - break; - } - } - /* Group not find group */ - if (tmpGroup == NULL) { - err = ERR_ARG; - } - } - - return err; -} - - -/** - * Process an input MLD message. Called by icmp6_input. - * - * @param p the mld packet, p->payload pointing to the icmpv6 header - * @param inp the netif on which this packet was received - */ -void -mld6_input(struct pbuf *p, struct netif *inp) -{ - struct mld_header *mld_hdr; - struct mld_group *group; - - MLD6_STATS_INC(mld6.recv); - - /* Check that mld header fits in packet. */ - if (p->len < sizeof(struct mld_header)) { - /* @todo debug message */ - pbuf_free(p); - MLD6_STATS_INC(mld6.lenerr); - MLD6_STATS_INC(mld6.drop); - return; - } - - mld_hdr = (struct mld_header *)p->payload; - - switch (mld_hdr->type) { - case ICMP6_TYPE_MLQ: /* Multicast listener query. */ - /* Is it a general query? */ - if (ip6_addr_isallnodes_linklocal(ip6_current_dest_addr()) && - ip6_addr_isany(&(mld_hdr->multicast_address))) { - MLD6_STATS_INC(mld6.rx_general); - /* Report all groups, except all nodes group, and if-local groups. */ - group = netif_mld6_data(inp); - while (group != NULL) { - if ((!(ip6_addr_ismulticast_iflocal(&(group->group_address)))) && - (!(ip6_addr_isallnodes_linklocal(&(group->group_address))))) { - mld6_delayed_report(group, mld_hdr->max_resp_delay); - } - group = group->next; - } - } else { - /* Have we joined this group? - * We use IP6 destination address to have a memory aligned copy. - * mld_hdr->multicast_address should be the same. */ - MLD6_STATS_INC(mld6.rx_group); - group = mld6_lookfor_group(inp, ip6_current_dest_addr()); - if (group != NULL) { - /* Schedule a report. */ - mld6_delayed_report(group, mld_hdr->max_resp_delay); - } - } - break; /* ICMP6_TYPE_MLQ */ - case ICMP6_TYPE_MLR: /* Multicast listener report. */ - /* Have we joined this group? - * We use IP6 destination address to have a memory aligned copy. - * mld_hdr->multicast_address should be the same. */ - MLD6_STATS_INC(mld6.rx_report); - group = mld6_lookfor_group(inp, ip6_current_dest_addr()); - if (group != NULL) { - /* If we are waiting to report, cancel it. */ - if (group->group_state == MLD6_GROUP_DELAYING_MEMBER) { - group->timer = 0; /* stopped */ - group->group_state = MLD6_GROUP_IDLE_MEMBER; - group->last_reporter_flag = 0; - } - } - break; /* ICMP6_TYPE_MLR */ - case ICMP6_TYPE_MLD: /* Multicast listener done. */ - /* Do nothing, router will query us. */ - break; /* ICMP6_TYPE_MLD */ - default: - MLD6_STATS_INC(mld6.proterr); - MLD6_STATS_INC(mld6.drop); - break; - } - - pbuf_free(p); -} - -/** - * @ingroup mld6 - * Join a group on one or all network interfaces. - * - * If the group is to be joined on all interfaces, the given group address must - * not have a zone set (i.e., it must have its zone index set to IP6_NO_ZONE). - * If the group is to be joined on one particular interface, the given group - * address may or may not have a zone set. - * - * @param srcaddr ipv6 address (zoned) of the network interface which should - * join a new group. If IP6_ADDR_ANY6, join on all netifs - * @param groupaddr the ipv6 address of the group to join (possibly but not - * necessarily zoned) - * @return ERR_OK if group was joined on the netif(s), an err_t otherwise - */ -err_t -mld6_joingroup(const ip6_addr_t *srcaddr, const ip6_addr_t *groupaddr) -{ - err_t err = ERR_VAL; /* no matching interface */ - struct netif *netif; - - LWIP_ASSERT_CORE_LOCKED(); - - /* loop through netif's */ - NETIF_FOREACH(netif) { - /* Should we join this interface ? */ - if (ip6_addr_isany(srcaddr) || - netif_get_ip6_addr_match(netif, srcaddr) >= 0) { - err = mld6_joingroup_netif(netif, groupaddr); - if (err != ERR_OK) { - return err; - } - } - } - - return err; -} - -/** - * @ingroup mld6 - * Join a group on a network interface. - * - * @param netif the network interface which should join a new group. - * @param groupaddr the ipv6 address of the group to join (possibly but not - * necessarily zoned) - * @return ERR_OK if group was joined on the netif, an err_t otherwise - */ -err_t -mld6_joingroup_netif(struct netif *netif, const ip6_addr_t *groupaddr) -{ - struct mld_group *group; -#if LWIP_IPV6_SCOPES - ip6_addr_t ip6addr; - - /* If the address has a particular scope but no zone set, use the netif to - * set one now. Within the mld6 module, all addresses are properly zoned. */ - if (ip6_addr_lacks_zone(groupaddr, IP6_MULTICAST)) { - ip6_addr_set(&ip6addr, groupaddr); - ip6_addr_assign_zone(&ip6addr, IP6_MULTICAST, netif); - groupaddr = &ip6addr; - } - IP6_ADDR_ZONECHECK_NETIF(groupaddr, netif); -#endif /* LWIP_IPV6_SCOPES */ - - LWIP_ASSERT_CORE_LOCKED(); - - /* find group or create a new one if not found */ - group = mld6_lookfor_group(netif, groupaddr); - - if (group == NULL) { - /* Joining a new group. Create a new group entry. */ - group = mld6_new_group(netif, groupaddr); - if (group == NULL) { - return ERR_MEM; - } - - /* Activate this address on the MAC layer. */ - if (netif->mld_mac_filter != NULL) { - netif->mld_mac_filter(netif, groupaddr, NETIF_ADD_MAC_FILTER); - } - - /* Report our membership. */ - MLD6_STATS_INC(mld6.tx_report); - mld6_send(netif, group, ICMP6_TYPE_MLR); - mld6_delayed_report(group, MLD6_JOIN_DELAYING_MEMBER_TMR_MS); - } - - /* Increment group use */ - group->use++; - return ERR_OK; -} - -/** - * @ingroup mld6 - * Leave a group on a network interface. - * - * Zoning of address follows the same rules as @ref mld6_joingroup. - * - * @param srcaddr ipv6 address (zoned) of the network interface which should - * leave the group. If IP6_ADDR_ANY6, leave on all netifs - * @param groupaddr the ipv6 address of the group to leave (possibly, but not - * necessarily zoned) - * @return ERR_OK if group was left on the netif(s), an err_t otherwise - */ -err_t -mld6_leavegroup(const ip6_addr_t *srcaddr, const ip6_addr_t *groupaddr) -{ - err_t err = ERR_VAL; /* no matching interface */ - struct netif *netif; - - LWIP_ASSERT_CORE_LOCKED(); - - /* loop through netif's */ - NETIF_FOREACH(netif) { - /* Should we leave this interface ? */ - if (ip6_addr_isany(srcaddr) || - netif_get_ip6_addr_match(netif, srcaddr) >= 0) { - err_t res = mld6_leavegroup_netif(netif, groupaddr); - if (err != ERR_OK) { - /* Store this result if we have not yet gotten a success */ - err = res; - } - } - } - - return err; -} - -/** - * @ingroup mld6 - * Leave a group on a network interface. - * - * @param netif the network interface which should leave the group. - * @param groupaddr the ipv6 address of the group to leave (possibly, but not - * necessarily zoned) - * @return ERR_OK if group was left on the netif, an err_t otherwise - */ -err_t -mld6_leavegroup_netif(struct netif *netif, const ip6_addr_t *groupaddr) -{ - struct mld_group *group; -#if LWIP_IPV6_SCOPES - ip6_addr_t ip6addr; - - if (ip6_addr_lacks_zone(groupaddr, IP6_MULTICAST)) { - ip6_addr_set(&ip6addr, groupaddr); - ip6_addr_assign_zone(&ip6addr, IP6_MULTICAST, netif); - groupaddr = &ip6addr; - } - IP6_ADDR_ZONECHECK_NETIF(groupaddr, netif); -#endif /* LWIP_IPV6_SCOPES */ - - LWIP_ASSERT_CORE_LOCKED(); - - /* find group */ - group = mld6_lookfor_group(netif, groupaddr); - - if (group != NULL) { - /* Leave if there is no other use of the group */ - if (group->use <= 1) { - /* Remove the group from the list */ - mld6_remove_group(netif, group); - - /* If we are the last reporter for this group */ - if (group->last_reporter_flag) { - MLD6_STATS_INC(mld6.tx_leave); - mld6_send(netif, group, ICMP6_TYPE_MLD); - } - - /* Disable the group at the MAC level */ - if (netif->mld_mac_filter != NULL) { - netif->mld_mac_filter(netif, groupaddr, NETIF_DEL_MAC_FILTER); - } - - /* free group struct */ - memp_free(MEMP_MLD6_GROUP, group); - } else { - /* Decrement group use */ - group->use--; - } - - /* Left group */ - return ERR_OK; - } - - /* Group not found */ - return ERR_VAL; -} - - -/** - * Periodic timer for mld processing. Must be called every - * MLD6_TMR_INTERVAL milliseconds (100). - * - * When a delaying member expires, a membership report is sent. - */ -void -mld6_tmr(void) -{ - struct netif *netif; - - NETIF_FOREACH(netif) { - struct mld_group *group = netif_mld6_data(netif); - - while (group != NULL) { - if (group->timer > 0) { - group->timer--; - if (group->timer == 0) { - /* If the state is MLD6_GROUP_DELAYING_MEMBER then we send a report for this group */ - if (group->group_state == MLD6_GROUP_DELAYING_MEMBER) { - MLD6_STATS_INC(mld6.tx_report); - mld6_send(netif, group, ICMP6_TYPE_MLR); - group->group_state = MLD6_GROUP_IDLE_MEMBER; - } - } - } - group = group->next; - } - } -} - -/** - * Schedule a delayed membership report for a group - * - * @param group the mld_group for which "delaying" membership report - * should be sent - * @param maxresp_in the max resp delay provided in the query - */ -static void -mld6_delayed_report(struct mld_group *group, u16_t maxresp_in) -{ - /* Convert maxresp from milliseconds to tmr ticks */ - u16_t maxresp = maxresp_in / MLD6_TMR_INTERVAL; - if (maxresp == 0) { - maxresp = 1; - } - -#ifdef LWIP_RAND - /* Randomize maxresp. (if LWIP_RAND is supported) */ - maxresp = (u16_t)(LWIP_RAND() % maxresp); - if (maxresp == 0) { - maxresp = 1; - } -#endif /* LWIP_RAND */ - - /* Apply timer value if no report has been scheduled already. */ - if ((group->group_state == MLD6_GROUP_IDLE_MEMBER) || - ((group->group_state == MLD6_GROUP_DELAYING_MEMBER) && - ((group->timer == 0) || (maxresp < group->timer)))) { - group->timer = maxresp; - group->group_state = MLD6_GROUP_DELAYING_MEMBER; - } -} - -/** - * Send a MLD message (report or done). - * - * An IPv6 hop-by-hop options header with a router alert option - * is prepended. - * - * @param group the group to report or quit - * @param type ICMP6_TYPE_MLR (report) or ICMP6_TYPE_MLD (done) - */ -static void -mld6_send(struct netif *netif, struct mld_group *group, u8_t type) -{ - struct mld_header *mld_hdr; - struct pbuf *p; - const ip6_addr_t *src_addr; - - /* Allocate a packet. Size is MLD header + IPv6 Hop-by-hop options header. */ - p = pbuf_alloc(PBUF_IP, sizeof(struct mld_header) + MLD6_HBH_HLEN, PBUF_RAM); - if (p == NULL) { - MLD6_STATS_INC(mld6.memerr); - return; - } - - /* Move to make room for Hop-by-hop options header. */ - if (pbuf_remove_header(p, MLD6_HBH_HLEN)) { - pbuf_free(p); - MLD6_STATS_INC(mld6.lenerr); - return; - } - - /* Select our source address. */ - if (!ip6_addr_isvalid(netif_ip6_addr_state(netif, 0))) { - /* This is a special case, when we are performing duplicate address detection. - * We must join the multicast group, but we don't have a valid address yet. */ - src_addr = IP6_ADDR_ANY6; - } else { - /* Use link-local address as source address. */ - src_addr = netif_ip6_addr(netif, 0); - } - - /* MLD message header pointer. */ - mld_hdr = (struct mld_header *)p->payload; - - /* Set fields. */ - mld_hdr->type = type; - mld_hdr->code = 0; - mld_hdr->chksum = 0; - mld_hdr->max_resp_delay = 0; - mld_hdr->reserved = 0; - ip6_addr_copy_to_packed(mld_hdr->multicast_address, group->group_address); - -#if CHECKSUM_GEN_ICMP6 - IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP6) { - mld_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, - src_addr, &(group->group_address)); - } -#endif /* CHECKSUM_GEN_ICMP6 */ - - /* Add hop-by-hop headers options: router alert with MLD value. */ - ip6_options_add_hbh_ra(p, IP6_NEXTH_ICMP6, IP6_ROUTER_ALERT_VALUE_MLD); - - if (type == ICMP6_TYPE_MLR) { - /* Remember we were the last to report */ - group->last_reporter_flag = 1; - } - - /* Send the packet out. */ - MLD6_STATS_INC(mld6.xmit); - ip6_output_if(p, (ip6_addr_isany(src_addr)) ? NULL : src_addr, &(group->group_address), - MLD6_HL, 0, IP6_NEXTH_HOPBYHOP, netif); - pbuf_free(p); -} - -#endif /* LWIP_IPV6 */ diff --git a/third-party/lwip-2.1.2/core/ipv6/nd6.c b/third-party/lwip-2.1.2/core/ipv6/nd6.c deleted file mode 100644 index db0c132e..00000000 --- a/third-party/lwip-2.1.2/core/ipv6/nd6.c +++ /dev/null @@ -1,2434 +0,0 @@ -/** - * @file - * - * Neighbor discovery and stateless address autoconfiguration for IPv6. - * Aims to be compliant with RFC 4861 (Neighbor discovery) and RFC 4862 - * (Address autoconfiguration). - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -#include "lwip/opt.h" - -#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/nd6.h" -#include "lwip/priv/nd6_priv.h" -#include "lwip/prot/nd6.h" -#include "lwip/prot/icmp6.h" -#include "lwip/pbuf.h" -#include "lwip/mem.h" -#include "lwip/memp.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#include "lwip/inet_chksum.h" -#include "lwip/netif.h" -#include "lwip/icmp6.h" -#include "lwip/mld6.h" -#include "lwip/dhcp6.h" -#include "lwip/ip.h" -#include "lwip/stats.h" -#include "lwip/dns.h" - -#include - -#ifdef LWIP_HOOK_FILENAME -#include LWIP_HOOK_FILENAME -#endif - -#if LWIP_IPV6_DUP_DETECT_ATTEMPTS > IP6_ADDR_TENTATIVE_COUNT_MASK -#error LWIP_IPV6_DUP_DETECT_ATTEMPTS > IP6_ADDR_TENTATIVE_COUNT_MASK -#endif - -/* Router tables. */ -struct nd6_neighbor_cache_entry neighbor_cache[LWIP_ND6_NUM_NEIGHBORS]; -struct nd6_destination_cache_entry destination_cache[LWIP_ND6_NUM_DESTINATIONS]; -struct nd6_prefix_list_entry prefix_list[LWIP_ND6_NUM_PREFIXES]; -struct nd6_router_list_entry default_router_list[LWIP_ND6_NUM_ROUTERS]; - -/* Default values, can be updated by a RA message. */ -u32_t reachable_time = LWIP_ND6_REACHABLE_TIME; -u32_t retrans_timer = LWIP_ND6_RETRANS_TIMER; /* @todo implement this value in timer */ - -/* Index for cache entries. */ -static u8_t nd6_cached_neighbor_index; -static netif_addr_idx_t nd6_cached_destination_index; - -/* Multicast address holder. */ -static ip6_addr_t multicast_address; - -static u8_t nd6_tmr_rs_reduction; - -/* Static buffer to parse RA packet options */ -union ra_options { - struct lladdr_option lladdr; - struct mtu_option mtu; - struct prefix_option prefix; -#if LWIP_ND6_RDNSS_MAX_DNS_SERVERS - struct rdnss_option rdnss; -#endif -}; -static union ra_options nd6_ra_buffer; - -/* Forward declarations. */ -static s8_t nd6_find_neighbor_cache_entry(const ip6_addr_t *ip6addr); -static s8_t nd6_new_neighbor_cache_entry(void); -static void nd6_free_neighbor_cache_entry(s8_t i); -static s16_t nd6_find_destination_cache_entry(const ip6_addr_t *ip6addr); -static s16_t nd6_new_destination_cache_entry(void); -static int nd6_is_prefix_in_netif(const ip6_addr_t *ip6addr, struct netif *netif); -static s8_t nd6_select_router(const ip6_addr_t *ip6addr, struct netif *netif); -static s8_t nd6_get_router(const ip6_addr_t *router_addr, struct netif *netif); -static s8_t nd6_new_router(const ip6_addr_t *router_addr, struct netif *netif); -static s8_t nd6_get_onlink_prefix(const ip6_addr_t *prefix, struct netif *netif); -static s8_t nd6_new_onlink_prefix(const ip6_addr_t *prefix, struct netif *netif); -static s8_t nd6_get_next_hop_entry(const ip6_addr_t *ip6addr, struct netif *netif); -static err_t nd6_queue_packet(s8_t neighbor_index, struct pbuf *q); - -#define ND6_SEND_FLAG_MULTICAST_DEST 0x01 -#define ND6_SEND_FLAG_ALLNODES_DEST 0x02 -#define ND6_SEND_FLAG_ANY_SRC 0x04 -static void nd6_send_ns(struct netif *netif, const ip6_addr_t *target_addr, u8_t flags); -static void nd6_send_na(struct netif *netif, const ip6_addr_t *target_addr, u8_t flags); -static void nd6_send_neighbor_cache_probe(struct nd6_neighbor_cache_entry *entry, u8_t flags); -#if LWIP_IPV6_SEND_ROUTER_SOLICIT -static err_t nd6_send_rs(struct netif *netif); -#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ - -#if LWIP_ND6_QUEUEING -static void nd6_free_q(struct nd6_q_entry *q); -#else /* LWIP_ND6_QUEUEING */ -#define nd6_free_q(q) pbuf_free(q) -#endif /* LWIP_ND6_QUEUEING */ -static void nd6_send_q(s8_t i); - - -/** - * A local address has been determined to be a duplicate. Take the appropriate - * action(s) on the address and the interface as a whole. - * - * @param netif the netif that owns the address - * @param addr_idx the index of the address detected to be a duplicate - */ -static void -nd6_duplicate_addr_detected(struct netif *netif, s8_t addr_idx) -{ - - /* Mark the address as duplicate, but leave its lifetimes alone. If this was - * a manually assigned address, it will remain in existence as duplicate, and - * as such be unusable for any practical purposes until manual intervention. - * If this was an autogenerated address, the address will follow normal - * expiration rules, and thus disappear once its valid lifetime expires. */ - netif_ip6_addr_set_state(netif, addr_idx, IP6_ADDR_DUPLICATED); - -#if LWIP_IPV6_AUTOCONFIG - /* If the affected address was the link-local address that we use to generate - * all other addresses, then we should not continue to use those derived - * addresses either, so mark them as duplicate as well. For autoconfig-only - * setups, this will make the interface effectively unusable, approaching the - * intention of RFC 4862 Sec. 5.4.5. @todo implement the full requirements */ - if (addr_idx == 0) { - s8_t i; - for (i = 1; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (!ip6_addr_isinvalid(netif_ip6_addr_state(netif, i)) && - !netif_ip6_addr_isstatic(netif, i)) { - netif_ip6_addr_set_state(netif, i, IP6_ADDR_DUPLICATED); - } - } - } -#endif /* LWIP_IPV6_AUTOCONFIG */ -} - -#if LWIP_IPV6_AUTOCONFIG -/** - * We received a router advertisement that contains a prefix with the - * autoconfiguration flag set. Add or update an associated autogenerated - * address. - * - * @param netif the netif on which the router advertisement arrived - * @param prefix_opt a pointer to the prefix option data - * @param prefix_addr an aligned copy of the prefix address - */ -static void -nd6_process_autoconfig_prefix(struct netif *netif, - struct prefix_option *prefix_opt, const ip6_addr_t *prefix_addr) -{ - ip6_addr_t ip6addr; - u32_t valid_life, pref_life; - u8_t addr_state; - s8_t i, free_idx; - - /* The caller already checks RFC 4862 Sec. 5.5.3 points (a) and (b). We do - * the rest, starting with checks for (c) and (d) here. */ - valid_life = lwip_htonl(prefix_opt->valid_lifetime); - pref_life = lwip_htonl(prefix_opt->preferred_lifetime); - if (pref_life > valid_life || prefix_opt->prefix_length != 64) { - return; /* silently ignore this prefix for autoconfiguration purposes */ - } - - /* If an autogenerated address already exists for this prefix, update its - * lifetimes. An address is considered autogenerated if 1) it is not static - * (i.e., manually assigned), and 2) there is an advertised autoconfiguration - * prefix for it (the one we are processing here). This does not necessarily - * exclude the possibility that the address was actually assigned by, say, - * DHCPv6. If that distinction becomes important in the future, more state - * must be kept. As explained elsewhere we also update lifetimes of tentative - * and duplicate addresses. Skip address slot 0 (the link-local address). */ - for (i = 1; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - addr_state = netif_ip6_addr_state(netif, i); - if (!ip6_addr_isinvalid(addr_state) && !netif_ip6_addr_isstatic(netif, i) && - ip6_addr_netcmp(prefix_addr, netif_ip6_addr(netif, i))) { - /* Update the valid lifetime, as per RFC 4862 Sec. 5.5.3 point (e). - * The valid lifetime will never drop to zero as a result of this. */ - u32_t remaining_life = netif_ip6_addr_valid_life(netif, i); - if (valid_life > ND6_2HRS || valid_life > remaining_life) { - netif_ip6_addr_set_valid_life(netif, i, valid_life); - } else if (remaining_life > ND6_2HRS) { - netif_ip6_addr_set_valid_life(netif, i, ND6_2HRS); - } - LWIP_ASSERT("bad valid lifetime", !netif_ip6_addr_isstatic(netif, i)); - /* Update the preferred lifetime. No bounds checks are needed here. In - * rare cases the advertisement may un-deprecate the address, though. - * Deprecation is left to the timer code where it is handled anyway. */ - if (pref_life > 0 && addr_state == IP6_ADDR_DEPRECATED) { - netif_ip6_addr_set_state(netif, i, IP6_ADDR_PREFERRED); - } - netif_ip6_addr_set_pref_life(netif, i, pref_life); - return; /* there should be at most one matching address */ - } - } - - /* No autogenerated address exists for this prefix yet. See if we can add a - * new one. However, if IPv6 autoconfiguration is administratively disabled, - * do not generate new addresses, but do keep updating lifetimes for existing - * addresses. Also, when adding new addresses, we must protect explicitly - * against a valid lifetime of zero, because again, we use that as a special - * value. The generated address would otherwise expire immediately anyway. - * Finally, the original link-local address must be usable at all. We start - * creating addresses even if the link-local address is still in tentative - * state though, and deal with the fallout of that upon DAD collision. */ - addr_state = netif_ip6_addr_state(netif, 0); - if (!netif->ip6_autoconfig_enabled || valid_life == IP6_ADDR_LIFE_STATIC || - ip6_addr_isinvalid(addr_state) || ip6_addr_isduplicated(addr_state)) { - return; - } - - /* Construct the new address that we intend to use, and then see if that - * address really does not exist. It might have been added manually, after - * all. As a side effect, find a free slot. Note that we cannot use - * netif_add_ip6_address() here, as it would return ERR_OK if the address - * already did exist, resulting in that address being given lifetimes. */ - IP6_ADDR(&ip6addr, prefix_addr->addr[0], prefix_addr->addr[1], - netif_ip6_addr(netif, 0)->addr[2], netif_ip6_addr(netif, 0)->addr[3]); - ip6_addr_assign_zone(&ip6addr, IP6_UNICAST, netif); - - free_idx = 0; - for (i = 1; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (!ip6_addr_isinvalid(netif_ip6_addr_state(netif, i))) { - if (ip6_addr_cmp(&ip6addr, netif_ip6_addr(netif, i))) { - return; /* formed address already exists */ - } - } else if (free_idx == 0) { - free_idx = i; - } - } - if (free_idx == 0) { - return; /* no address slots available, try again on next advertisement */ - } - - /* Assign the new address to the interface. */ - ip_addr_copy_from_ip6(netif->ip6_addr[free_idx], ip6addr); - netif_ip6_addr_set_valid_life(netif, free_idx, valid_life); - netif_ip6_addr_set_pref_life(netif, free_idx, pref_life); - netif_ip6_addr_set_state(netif, free_idx, IP6_ADDR_TENTATIVE); -} -#endif /* LWIP_IPV6_AUTOCONFIG */ - -/** - * Process an incoming neighbor discovery message - * - * @param p the nd packet, p->payload pointing to the icmpv6 header - * @param inp the netif on which this packet was received - */ -void -nd6_input(struct pbuf *p, struct netif *inp) -{ - u8_t msg_type; - s8_t i; - s16_t dest_idx; - - ND6_STATS_INC(nd6.recv); - - msg_type = *((u8_t *)p->payload); - switch (msg_type) { - case ICMP6_TYPE_NA: /* Neighbor Advertisement. */ - { - struct na_header *na_hdr; - struct lladdr_option *lladdr_opt; - ip6_addr_t target_address; - - /* Check that na header fits in packet. */ - if (p->len < (sizeof(struct na_header))) { - /* @todo debug message */ - pbuf_free(p); - ND6_STATS_INC(nd6.lenerr); - ND6_STATS_INC(nd6.drop); - return; - } - - na_hdr = (struct na_header *)p->payload; - - /* Create an aligned, zoned copy of the target address. */ - ip6_addr_copy_from_packed(target_address, na_hdr->target_address); - ip6_addr_assign_zone(&target_address, IP6_UNICAST, inp); - - /* Check a subset of the other RFC 4861 Sec. 7.1.2 requirements. */ - if (IP6H_HOPLIM(ip6_current_header()) != ND6_HOPLIM || na_hdr->code != 0 || - ip6_addr_ismulticast(&target_address)) { - pbuf_free(p); - ND6_STATS_INC(nd6.proterr); - ND6_STATS_INC(nd6.drop); - return; - } - - /* @todo RFC MUST: if IP destination is multicast, Solicited flag is zero */ - /* @todo RFC MUST: all included options have a length greater than zero */ - - /* Unsolicited NA?*/ - if (ip6_addr_ismulticast(ip6_current_dest_addr())) { - /* This is an unsolicited NA. - * link-layer changed? - * part of DAD mechanism? */ - -#if LWIP_IPV6_DUP_DETECT_ATTEMPTS - /* If the target address matches this netif, it is a DAD response. */ - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (!ip6_addr_isinvalid(netif_ip6_addr_state(inp, i)) && - !ip6_addr_isduplicated(netif_ip6_addr_state(inp, i)) && - ip6_addr_cmp(&target_address, netif_ip6_addr(inp, i))) { - /* We are using a duplicate address. */ - nd6_duplicate_addr_detected(inp, i); - - pbuf_free(p); - return; - } - } -#endif /* LWIP_IPV6_DUP_DETECT_ATTEMPTS */ - - /* Check that link-layer address option also fits in packet. */ - if (p->len < (sizeof(struct na_header) + 2)) { - /* @todo debug message */ - pbuf_free(p); - ND6_STATS_INC(nd6.lenerr); - ND6_STATS_INC(nd6.drop); - return; - } - - lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct na_header)); - - if (p->len < (sizeof(struct na_header) + (lladdr_opt->length << 3))) { - /* @todo debug message */ - pbuf_free(p); - ND6_STATS_INC(nd6.lenerr); - ND6_STATS_INC(nd6.drop); - return; - } - - /* This is an unsolicited NA, most likely there was a LLADDR change. */ - i = nd6_find_neighbor_cache_entry(&target_address); - if (i >= 0) { - if (na_hdr->flags & ND6_FLAG_OVERRIDE) { - MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len); - } - } - } else { - /* This is a solicited NA. - * neighbor address resolution response? - * neighbor unreachability detection response? */ - - /* Find the cache entry corresponding to this na. */ - i = nd6_find_neighbor_cache_entry(&target_address); - if (i < 0) { - /* We no longer care about this target address. drop it. */ - pbuf_free(p); - return; - } - - /* Update cache entry. */ - if ((na_hdr->flags & ND6_FLAG_OVERRIDE) || - (neighbor_cache[i].state == ND6_INCOMPLETE)) { - /* Check that link-layer address option also fits in packet. */ - if (p->len < (sizeof(struct na_header) + 2)) { - /* @todo debug message */ - pbuf_free(p); - ND6_STATS_INC(nd6.lenerr); - ND6_STATS_INC(nd6.drop); - return; - } - - lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct na_header)); - - if (p->len < (sizeof(struct na_header) + (lladdr_opt->length << 3))) { - /* @todo debug message */ - pbuf_free(p); - ND6_STATS_INC(nd6.lenerr); - ND6_STATS_INC(nd6.drop); - return; - } - - MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len); - } - - neighbor_cache[i].netif = inp; - neighbor_cache[i].state = ND6_REACHABLE; - neighbor_cache[i].counter.reachable_time = reachable_time; - - /* Send queued packets, if any. */ - if (neighbor_cache[i].q != NULL) { - nd6_send_q(i); - } - } - - break; /* ICMP6_TYPE_NA */ - } - case ICMP6_TYPE_NS: /* Neighbor solicitation. */ - { - struct ns_header *ns_hdr; - struct lladdr_option *lladdr_opt; - ip6_addr_t target_address; - u8_t accepted; - - /* Check that ns header fits in packet. */ - if (p->len < sizeof(struct ns_header)) { - /* @todo debug message */ - pbuf_free(p); - ND6_STATS_INC(nd6.lenerr); - ND6_STATS_INC(nd6.drop); - return; - } - - ns_hdr = (struct ns_header *)p->payload; - - /* Create an aligned, zoned copy of the target address. */ - ip6_addr_copy_from_packed(target_address, ns_hdr->target_address); - ip6_addr_assign_zone(&target_address, IP6_UNICAST, inp); - - /* Check a subset of the other RFC 4861 Sec. 7.1.1 requirements. */ - if (IP6H_HOPLIM(ip6_current_header()) != ND6_HOPLIM || ns_hdr->code != 0 || - ip6_addr_ismulticast(&target_address)) { - pbuf_free(p); - ND6_STATS_INC(nd6.proterr); - ND6_STATS_INC(nd6.drop); - return; - } - - /* @todo RFC MUST: all included options have a length greater than zero */ - /* @todo RFC MUST: if IP source is 'any', destination is solicited-node multicast address */ - /* @todo RFC MUST: if IP source is 'any', there is no source LL address option */ - - /* Check if there is a link-layer address provided. Only point to it if in this buffer. */ - if (p->len >= (sizeof(struct ns_header) + 2)) { - lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct ns_header)); - if (p->len < (sizeof(struct ns_header) + (lladdr_opt->length << 3))) { - lladdr_opt = NULL; - } - } else { - lladdr_opt = NULL; - } - - /* Check if the target address is configured on the receiving netif. */ - accepted = 0; - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; ++i) { - if ((ip6_addr_isvalid(netif_ip6_addr_state(inp, i)) || - (ip6_addr_istentative(netif_ip6_addr_state(inp, i)) && - ip6_addr_isany(ip6_current_src_addr()))) && - ip6_addr_cmp(&target_address, netif_ip6_addr(inp, i))) { - accepted = 1; - break; - } - } - - /* NS not for us? */ - if (!accepted) { - pbuf_free(p); - return; - } - - /* Check for ANY address in src (DAD algorithm). */ - if (ip6_addr_isany(ip6_current_src_addr())) { - /* Sender is validating this address. */ - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; ++i) { - if (!ip6_addr_isinvalid(netif_ip6_addr_state(inp, i)) && - ip6_addr_cmp(&target_address, netif_ip6_addr(inp, i))) { - /* Send a NA back so that the sender does not use this address. */ - nd6_send_na(inp, netif_ip6_addr(inp, i), ND6_FLAG_OVERRIDE | ND6_SEND_FLAG_ALLNODES_DEST); - if (ip6_addr_istentative(netif_ip6_addr_state(inp, i))) { - /* We shouldn't use this address either. */ - nd6_duplicate_addr_detected(inp, i); - } - } - } - } else { - /* Sender is trying to resolve our address. */ - /* Verify that they included their own link-layer address. */ - if (lladdr_opt == NULL) { - /* Not a valid message. */ - pbuf_free(p); - ND6_STATS_INC(nd6.proterr); - ND6_STATS_INC(nd6.drop); - return; - } - - i = nd6_find_neighbor_cache_entry(ip6_current_src_addr()); - if (i>= 0) { - /* We already have a record for the solicitor. */ - if (neighbor_cache[i].state == ND6_INCOMPLETE) { - neighbor_cache[i].netif = inp; - MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len); - - /* Delay probe in case we get confirmation of reachability from upper layer (TCP). */ - neighbor_cache[i].state = ND6_DELAY; - neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME / ND6_TMR_INTERVAL; - } - } else { - /* Add their IPv6 address and link-layer address to neighbor cache. - * We will need it at least to send a unicast NA message, but most - * likely we will also be communicating with this node soon. */ - i = nd6_new_neighbor_cache_entry(); - if (i < 0) { - /* We couldn't assign a cache entry for this neighbor. - * we won't be able to reply. drop it. */ - pbuf_free(p); - ND6_STATS_INC(nd6.memerr); - return; - } - neighbor_cache[i].netif = inp; - MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len); - ip6_addr_set(&(neighbor_cache[i].next_hop_address), ip6_current_src_addr()); - - /* Receiving a message does not prove reachability: only in one direction. - * Delay probe in case we get confirmation of reachability from upper layer (TCP). */ - neighbor_cache[i].state = ND6_DELAY; - neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME / ND6_TMR_INTERVAL; - } - - /* Send back a NA for us. Allocate the reply pbuf. */ - nd6_send_na(inp, &target_address, ND6_FLAG_SOLICITED | ND6_FLAG_OVERRIDE); - } - - break; /* ICMP6_TYPE_NS */ - } - case ICMP6_TYPE_RA: /* Router Advertisement. */ - { - struct ra_header *ra_hdr; - u8_t *buffer; /* Used to copy options. */ - u16_t offset; -#if LWIP_ND6_RDNSS_MAX_DNS_SERVERS - /* There can be multiple RDNSS options per RA */ - u8_t rdnss_server_idx = 0; -#endif /* LWIP_ND6_RDNSS_MAX_DNS_SERVERS */ - - /* Check that RA header fits in packet. */ - if (p->len < sizeof(struct ra_header)) { - /* @todo debug message */ - pbuf_free(p); - ND6_STATS_INC(nd6.lenerr); - ND6_STATS_INC(nd6.drop); - return; - } - - ra_hdr = (struct ra_header *)p->payload; - - /* Check a subset of the other RFC 4861 Sec. 6.1.2 requirements. */ - if (!ip6_addr_islinklocal(ip6_current_src_addr()) || - IP6H_HOPLIM(ip6_current_header()) != ND6_HOPLIM || ra_hdr->code != 0) { - pbuf_free(p); - ND6_STATS_INC(nd6.proterr); - ND6_STATS_INC(nd6.drop); - return; - } - - /* @todo RFC MUST: all included options have a length greater than zero */ - - /* If we are sending RS messages, stop. */ -#if LWIP_IPV6_SEND_ROUTER_SOLICIT - /* ensure at least one solicitation is sent (see RFC 4861, ch. 6.3.7) */ - if ((inp->rs_count < LWIP_ND6_MAX_MULTICAST_SOLICIT) || - (nd6_send_rs(inp) == ERR_OK)) { - inp->rs_count = 0; - } else { - inp->rs_count = 1; - } -#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ - - /* Get the matching default router entry. */ - i = nd6_get_router(ip6_current_src_addr(), inp); - if (i < 0) { - /* Create a new router entry. */ - i = nd6_new_router(ip6_current_src_addr(), inp); - } - - if (i < 0) { - /* Could not create a new router entry. */ - pbuf_free(p); - ND6_STATS_INC(nd6.memerr); - return; - } - - /* Re-set invalidation timer. */ - default_router_list[i].invalidation_timer = lwip_htons(ra_hdr->router_lifetime); - - /* Re-set default timer values. */ -#if LWIP_ND6_ALLOW_RA_UPDATES - if (ra_hdr->retrans_timer > 0) { - retrans_timer = lwip_htonl(ra_hdr->retrans_timer); - } - if (ra_hdr->reachable_time > 0) { - reachable_time = lwip_htonl(ra_hdr->reachable_time); - } -#endif /* LWIP_ND6_ALLOW_RA_UPDATES */ - - /* @todo set default hop limit... */ - /* ra_hdr->current_hop_limit;*/ - - /* Update flags in local entry (incl. preference). */ - default_router_list[i].flags = ra_hdr->flags; - -#if LWIP_IPV6_DHCP6 - /* Trigger DHCPv6 if enabled */ - dhcp6_nd6_ra_trigger(inp, ra_hdr->flags & ND6_RA_FLAG_MANAGED_ADDR_CONFIG, - ra_hdr->flags & ND6_RA_FLAG_OTHER_CONFIG); -#endif - - /* Offset to options. */ - offset = sizeof(struct ra_header); - - /* Process each option. */ - while ((p->tot_len - offset) >= 2) { - u8_t option_type; - u16_t option_len; - int option_len8 = pbuf_try_get_at(p, offset + 1); - if (option_len8 <= 0) { - /* read beyond end or zero length */ - goto lenerr_drop_free_return; - } - option_len = ((u8_t)option_len8) << 3; - if (option_len > p->tot_len - offset) { - /* short packet (option does not fit in) */ - goto lenerr_drop_free_return; - } - if (p->len == p->tot_len) { - /* no need to copy from contiguous pbuf */ - buffer = &((u8_t*)p->payload)[offset]; - } else { - /* check if this option fits into our buffer */ - if (option_len > sizeof(nd6_ra_buffer)) { - option_type = pbuf_get_at(p, offset); - /* invalid option length */ - if (option_type != ND6_OPTION_TYPE_RDNSS) { - goto lenerr_drop_free_return; - } - /* we allow RDNSS option to be longer - we'll just drop some servers */ - option_len = sizeof(nd6_ra_buffer); - } - buffer = (u8_t*)&nd6_ra_buffer; - option_len = pbuf_copy_partial(p, &nd6_ra_buffer, option_len, offset); - } - option_type = buffer[0]; - switch (option_type) { - case ND6_OPTION_TYPE_SOURCE_LLADDR: - { - struct lladdr_option *lladdr_opt; - if (option_len < sizeof(struct lladdr_option)) { - goto lenerr_drop_free_return; - } - lladdr_opt = (struct lladdr_option *)buffer; - if ((default_router_list[i].neighbor_entry != NULL) && - (default_router_list[i].neighbor_entry->state == ND6_INCOMPLETE)) { - SMEMCPY(default_router_list[i].neighbor_entry->lladdr, lladdr_opt->addr, inp->hwaddr_len); - default_router_list[i].neighbor_entry->state = ND6_REACHABLE; - default_router_list[i].neighbor_entry->counter.reachable_time = reachable_time; - } - break; - } - case ND6_OPTION_TYPE_MTU: - { - struct mtu_option *mtu_opt; - u32_t mtu32; - if (option_len < sizeof(struct mtu_option)) { - goto lenerr_drop_free_return; - } - mtu_opt = (struct mtu_option *)buffer; - mtu32 = lwip_htonl(mtu_opt->mtu); - if ((mtu32 >= 1280) && (mtu32 <= 0xffff)) { -#if LWIP_ND6_ALLOW_RA_UPDATES - if (inp->mtu) { - /* don't set the mtu for IPv6 higher than the netif driver supports */ - inp->mtu6 = LWIP_MIN(inp->mtu, (u16_t)mtu32); - } else { - inp->mtu6 = (u16_t)mtu32; - } -#endif /* LWIP_ND6_ALLOW_RA_UPDATES */ - } - break; - } - case ND6_OPTION_TYPE_PREFIX_INFO: - { - struct prefix_option *prefix_opt; - ip6_addr_t prefix_addr; - if (option_len < sizeof(struct prefix_option)) { - goto lenerr_drop_free_return; - } - - prefix_opt = (struct prefix_option *)buffer; - - /* Get a memory-aligned copy of the prefix. */ - ip6_addr_copy_from_packed(prefix_addr, prefix_opt->prefix); - ip6_addr_assign_zone(&prefix_addr, IP6_UNICAST, inp); - - if (!ip6_addr_islinklocal(&prefix_addr)) { - if ((prefix_opt->flags & ND6_PREFIX_FLAG_ON_LINK) && - (prefix_opt->prefix_length == 64)) { - /* Add to on-link prefix list. */ - u32_t valid_life; - s8_t prefix; - - valid_life = lwip_htonl(prefix_opt->valid_lifetime); - - /* find cache entry for this prefix. */ - prefix = nd6_get_onlink_prefix(&prefix_addr, inp); - if (prefix < 0 && valid_life > 0) { - /* Create a new cache entry. */ - prefix = nd6_new_onlink_prefix(&prefix_addr, inp); - } - if (prefix >= 0) { - prefix_list[prefix].invalidation_timer = valid_life; - } - } -#if LWIP_IPV6_AUTOCONFIG - if (prefix_opt->flags & ND6_PREFIX_FLAG_AUTONOMOUS) { - /* Perform processing for autoconfiguration. */ - nd6_process_autoconfig_prefix(inp, prefix_opt, &prefix_addr); - } -#endif /* LWIP_IPV6_AUTOCONFIG */ - } - - break; - } - case ND6_OPTION_TYPE_ROUTE_INFO: - /* @todo implement preferred routes. - struct route_option * route_opt; - route_opt = (struct route_option *)buffer;*/ - - break; -#if LWIP_ND6_RDNSS_MAX_DNS_SERVERS - case ND6_OPTION_TYPE_RDNSS: - { - u8_t num, n; - u16_t copy_offset = offset + SIZEOF_RDNSS_OPTION_BASE; - struct rdnss_option * rdnss_opt; - if (option_len < SIZEOF_RDNSS_OPTION_BASE) { - goto lenerr_drop_free_return; - } - - rdnss_opt = (struct rdnss_option *)buffer; - num = (rdnss_opt->length - 1) / 2; - for (n = 0; (rdnss_server_idx < DNS_MAX_SERVERS) && (n < num); n++) { - ip_addr_t rdnss_address; - - /* Copy directly from pbuf to get an aligned, zoned copy of the prefix. */ - if (pbuf_copy_partial(p, &rdnss_address, sizeof(ip6_addr_p_t), copy_offset) == sizeof(ip6_addr_p_t)) { - IP_SET_TYPE_VAL(rdnss_address, IPADDR_TYPE_V6); - ip6_addr_assign_zone(ip_2_ip6(&rdnss_address), IP6_UNKNOWN, inp); - - if (htonl(rdnss_opt->lifetime) > 0) { - /* TODO implement Lifetime > 0 */ - dns_setserver(rdnss_server_idx++, &rdnss_address); - } else { - /* TODO implement DNS removal in dns.c */ - u8_t s; - for (s = 0; s < DNS_MAX_SERVERS; s++) { - const ip_addr_t *addr = dns_getserver(s); - if(ip_addr_cmp(addr, &rdnss_address)) { - dns_setserver(s, NULL); - } - } - } - } - } - break; - } -#endif /* LWIP_ND6_RDNSS_MAX_DNS_SERVERS */ - default: - /* Unrecognized option, abort. */ - ND6_STATS_INC(nd6.proterr); - break; - } - /* option length is checked earlier to be non-zero to make sure loop ends */ - offset += 8 * (u8_t)option_len8; - } - - break; /* ICMP6_TYPE_RA */ - } - case ICMP6_TYPE_RD: /* Redirect */ - { - struct redirect_header *redir_hdr; - struct lladdr_option *lladdr_opt; - ip6_addr_t destination_address, target_address; - - /* Check that Redir header fits in packet. */ - if (p->len < sizeof(struct redirect_header)) { - /* @todo debug message */ - pbuf_free(p); - ND6_STATS_INC(nd6.lenerr); - ND6_STATS_INC(nd6.drop); - return; - } - - redir_hdr = (struct redirect_header *)p->payload; - - /* Create an aligned, zoned copy of the destination address. */ - ip6_addr_copy_from_packed(destination_address, redir_hdr->destination_address); - ip6_addr_assign_zone(&destination_address, IP6_UNICAST, inp); - - /* Check a subset of the other RFC 4861 Sec. 8.1 requirements. */ - if (!ip6_addr_islinklocal(ip6_current_src_addr()) || - IP6H_HOPLIM(ip6_current_header()) != ND6_HOPLIM || - redir_hdr->code != 0 || ip6_addr_ismulticast(&destination_address)) { - pbuf_free(p); - ND6_STATS_INC(nd6.proterr); - ND6_STATS_INC(nd6.drop); - return; - } - - /* @todo RFC MUST: IP source address equals first-hop router for destination_address */ - /* @todo RFC MUST: ICMP target address is either link-local address or same as destination_address */ - /* @todo RFC MUST: all included options have a length greater than zero */ - - if (p->len >= (sizeof(struct redirect_header) + 2)) { - lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct redirect_header)); - if (p->len < (sizeof(struct redirect_header) + (lladdr_opt->length << 3))) { - lladdr_opt = NULL; - } - } else { - lladdr_opt = NULL; - } - - /* Find dest address in cache */ - dest_idx = nd6_find_destination_cache_entry(&destination_address); - if (dest_idx < 0) { - /* Destination not in cache, drop packet. */ - pbuf_free(p); - return; - } - - /* Create an aligned, zoned copy of the target address. */ - ip6_addr_copy_from_packed(target_address, redir_hdr->target_address); - ip6_addr_assign_zone(&target_address, IP6_UNICAST, inp); - - /* Set the new target address. */ - ip6_addr_copy(destination_cache[dest_idx].next_hop_addr, target_address); - - /* If Link-layer address of other router is given, try to add to neighbor cache. */ - if (lladdr_opt != NULL) { - if (lladdr_opt->type == ND6_OPTION_TYPE_TARGET_LLADDR) { - i = nd6_find_neighbor_cache_entry(&target_address); - if (i < 0) { - i = nd6_new_neighbor_cache_entry(); - if (i >= 0) { - neighbor_cache[i].netif = inp; - MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len); - ip6_addr_copy(neighbor_cache[i].next_hop_address, target_address); - - /* Receiving a message does not prove reachability: only in one direction. - * Delay probe in case we get confirmation of reachability from upper layer (TCP). */ - neighbor_cache[i].state = ND6_DELAY; - neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME / ND6_TMR_INTERVAL; - } - } - if (i >= 0) { - if (neighbor_cache[i].state == ND6_INCOMPLETE) { - MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len); - /* Receiving a message does not prove reachability: only in one direction. - * Delay probe in case we get confirmation of reachability from upper layer (TCP). */ - neighbor_cache[i].state = ND6_DELAY; - neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME / ND6_TMR_INTERVAL; - } - } - } - } - break; /* ICMP6_TYPE_RD */ - } - case ICMP6_TYPE_PTB: /* Packet too big */ - { - struct icmp6_hdr *icmp6hdr; /* Packet too big message */ - struct ip6_hdr *ip6hdr; /* IPv6 header of the packet which caused the error */ - u32_t pmtu; - ip6_addr_t destination_address; - - /* Check that ICMPv6 header + IPv6 header fit in payload */ - if (p->len < (sizeof(struct icmp6_hdr) + IP6_HLEN)) { - /* drop short packets */ - pbuf_free(p); - ND6_STATS_INC(nd6.lenerr); - ND6_STATS_INC(nd6.drop); - return; - } - - icmp6hdr = (struct icmp6_hdr *)p->payload; - ip6hdr = (struct ip6_hdr *)((u8_t*)p->payload + sizeof(struct icmp6_hdr)); - - /* Create an aligned, zoned copy of the destination address. */ - ip6_addr_copy_from_packed(destination_address, ip6hdr->dest); - ip6_addr_assign_zone(&destination_address, IP6_UNKNOWN, inp); - - /* Look for entry in destination cache. */ - dest_idx = nd6_find_destination_cache_entry(&destination_address); - if (dest_idx < 0) { - /* Destination not in cache, drop packet. */ - pbuf_free(p); - return; - } - - /* Change the Path MTU. */ - pmtu = lwip_htonl(icmp6hdr->data); - destination_cache[dest_idx].pmtu = (u16_t)LWIP_MIN(pmtu, 0xFFFF); - - break; /* ICMP6_TYPE_PTB */ - } - - default: - ND6_STATS_INC(nd6.proterr); - ND6_STATS_INC(nd6.drop); - break; /* default */ - } - - pbuf_free(p); - return; -lenerr_drop_free_return: - ND6_STATS_INC(nd6.lenerr); - ND6_STATS_INC(nd6.drop); - pbuf_free(p); -} - - -/** - * Periodic timer for Neighbor discovery functions: - * - * - Update neighbor reachability states - * - Update destination cache entries age - * - Update invalidation timers of default routers and on-link prefixes - * - Update lifetimes of our addresses - * - Perform duplicate address detection (DAD) for our addresses - * - Send router solicitations - */ -void -nd6_tmr(void) -{ - s8_t i; - struct netif *netif; - - /* Process neighbor entries. */ - for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { - switch (neighbor_cache[i].state) { - case ND6_INCOMPLETE: - if ((neighbor_cache[i].counter.probes_sent >= LWIP_ND6_MAX_MULTICAST_SOLICIT) && - (!neighbor_cache[i].isrouter)) { - /* Retries exceeded. */ - nd6_free_neighbor_cache_entry(i); - } else { - /* Send a NS for this entry. */ - neighbor_cache[i].counter.probes_sent++; - nd6_send_neighbor_cache_probe(&neighbor_cache[i], ND6_SEND_FLAG_MULTICAST_DEST); - } - break; - case ND6_REACHABLE: - /* Send queued packets, if any are left. Should have been sent already. */ - if (neighbor_cache[i].q != NULL) { - nd6_send_q(i); - } - if (neighbor_cache[i].counter.reachable_time <= ND6_TMR_INTERVAL) { - /* Change to stale state. */ - neighbor_cache[i].state = ND6_STALE; - neighbor_cache[i].counter.stale_time = 0; - } else { - neighbor_cache[i].counter.reachable_time -= ND6_TMR_INTERVAL; - } - break; - case ND6_STALE: - neighbor_cache[i].counter.stale_time++; - break; - case ND6_DELAY: - if (neighbor_cache[i].counter.delay_time <= 1) { - /* Change to PROBE state. */ - neighbor_cache[i].state = ND6_PROBE; - neighbor_cache[i].counter.probes_sent = 0; - } else { - neighbor_cache[i].counter.delay_time--; - } - break; - case ND6_PROBE: - if ((neighbor_cache[i].counter.probes_sent >= LWIP_ND6_MAX_MULTICAST_SOLICIT) && - (!neighbor_cache[i].isrouter)) { - /* Retries exceeded. */ - nd6_free_neighbor_cache_entry(i); - } else { - /* Send a NS for this entry. */ - neighbor_cache[i].counter.probes_sent++; - nd6_send_neighbor_cache_probe(&neighbor_cache[i], 0); - } - break; - case ND6_NO_ENTRY: - default: - /* Do nothing. */ - break; - } - } - - /* Process destination entries. */ - for (i = 0; i < LWIP_ND6_NUM_DESTINATIONS; i++) { - destination_cache[i].age++; - } - - /* Process router entries. */ - for (i = 0; i < LWIP_ND6_NUM_ROUTERS; i++) { - if (default_router_list[i].neighbor_entry != NULL) { - /* Active entry. */ - if (default_router_list[i].invalidation_timer <= ND6_TMR_INTERVAL / 1000) { - /* No more than 1 second remaining. Clear this entry. Also clear any of - * its destination cache entries, as per RFC 4861 Sec. 5.3 and 6.3.5. */ - s8_t j; - for (j = 0; j < LWIP_ND6_NUM_DESTINATIONS; j++) { - if (ip6_addr_cmp(&destination_cache[j].next_hop_addr, - &default_router_list[i].neighbor_entry->next_hop_address)) { - ip6_addr_set_any(&destination_cache[j].destination_addr); - } - } - default_router_list[i].neighbor_entry->isrouter = 0; - default_router_list[i].neighbor_entry = NULL; - default_router_list[i].invalidation_timer = 0; - default_router_list[i].flags = 0; - } else { - default_router_list[i].invalidation_timer -= ND6_TMR_INTERVAL / 1000; - } - } - } - - /* Process prefix entries. */ - for (i = 0; i < LWIP_ND6_NUM_PREFIXES; i++) { - if (prefix_list[i].netif != NULL) { - if (prefix_list[i].invalidation_timer <= ND6_TMR_INTERVAL / 1000) { - /* Entry timed out, remove it */ - prefix_list[i].invalidation_timer = 0; - prefix_list[i].netif = NULL; - } else { - prefix_list[i].invalidation_timer -= ND6_TMR_INTERVAL / 1000; - } - } - } - - /* Process our own addresses, updating address lifetimes and/or DAD state. */ - NETIF_FOREACH(netif) { - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; ++i) { - u8_t addr_state; -#if LWIP_IPV6_ADDRESS_LIFETIMES - /* Step 1: update address lifetimes (valid and preferred). */ - addr_state = netif_ip6_addr_state(netif, i); - /* RFC 4862 is not entirely clear as to whether address lifetimes affect - * tentative addresses, and is even less clear as to what should happen - * with duplicate addresses. We choose to track and update lifetimes for - * both those types, although for different reasons: - * - for tentative addresses, the line of thought of Sec. 5.7 combined - * with the potentially long period that an address may be in tentative - * state (due to the interface being down) suggests that lifetimes - * should be independent of external factors which would include DAD; - * - for duplicate addresses, retiring them early could result in a new - * but unwanted attempt at marking them as valid, while retiring them - * late/never could clog up address slots on the netif. - * As a result, we may end up expiring addresses of either type here. - */ - if (!ip6_addr_isinvalid(addr_state) && - !netif_ip6_addr_isstatic(netif, i)) { - u32_t life = netif_ip6_addr_valid_life(netif, i); - if (life <= ND6_TMR_INTERVAL / 1000) { - /* The address has expired. */ - netif_ip6_addr_set_valid_life(netif, i, 0); - netif_ip6_addr_set_pref_life(netif, i, 0); - netif_ip6_addr_set_state(netif, i, IP6_ADDR_INVALID); - } else { - if (!ip6_addr_life_isinfinite(life)) { - life -= ND6_TMR_INTERVAL / 1000; - LWIP_ASSERT("bad valid lifetime", life != IP6_ADDR_LIFE_STATIC); - netif_ip6_addr_set_valid_life(netif, i, life); - } - /* The address is still here. Update the preferred lifetime too. */ - life = netif_ip6_addr_pref_life(netif, i); - if (life <= ND6_TMR_INTERVAL / 1000) { - /* This case must also trigger if 'life' was already zero, so as to - * deal correctly with advertised preferred-lifetime reductions. */ - netif_ip6_addr_set_pref_life(netif, i, 0); - if (addr_state == IP6_ADDR_PREFERRED) - netif_ip6_addr_set_state(netif, i, IP6_ADDR_DEPRECATED); - } else if (!ip6_addr_life_isinfinite(life)) { - life -= ND6_TMR_INTERVAL / 1000; - netif_ip6_addr_set_pref_life(netif, i, life); - } - } - } - /* The address state may now have changed, so reobtain it next. */ -#endif /* LWIP_IPV6_ADDRESS_LIFETIMES */ - /* Step 2: update DAD state. */ - addr_state = netif_ip6_addr_state(netif, i); - if (ip6_addr_istentative(addr_state)) { - if ((addr_state & IP6_ADDR_TENTATIVE_COUNT_MASK) >= LWIP_IPV6_DUP_DETECT_ATTEMPTS) { - /* No NA received in response. Mark address as valid. For dynamic - * addresses with an expired preferred lifetime, the state is set to - * deprecated right away. That should almost never happen, though. */ - addr_state = IP6_ADDR_PREFERRED; -#if LWIP_IPV6_ADDRESS_LIFETIMES - if (!netif_ip6_addr_isstatic(netif, i) && - netif_ip6_addr_pref_life(netif, i) == 0) { - addr_state = IP6_ADDR_DEPRECATED; - } -#endif /* LWIP_IPV6_ADDRESS_LIFETIMES */ - netif_ip6_addr_set_state(netif, i, addr_state); - } else if (netif_is_up(netif) && netif_is_link_up(netif)) { - /* tentative: set next state by increasing by one */ - netif_ip6_addr_set_state(netif, i, addr_state + 1); - /* Send a NS for this address. Use the unspecified address as source - * address in all cases (RFC 4862 Sec. 5.4.2), not in the least - * because as it is, we only consider multicast replies for DAD. */ - nd6_send_ns(netif, netif_ip6_addr(netif, i), - ND6_SEND_FLAG_MULTICAST_DEST | ND6_SEND_FLAG_ANY_SRC); - } - } - } - } - -#if LWIP_IPV6_SEND_ROUTER_SOLICIT - /* Send router solicitation messages, if necessary. */ - if (!nd6_tmr_rs_reduction) { - nd6_tmr_rs_reduction = (ND6_RTR_SOLICITATION_INTERVAL / ND6_TMR_INTERVAL) - 1; - NETIF_FOREACH(netif) { - if ((netif->rs_count > 0) && netif_is_up(netif) && - netif_is_link_up(netif) && - !ip6_addr_isinvalid(netif_ip6_addr_state(netif, 0)) && - !ip6_addr_isduplicated(netif_ip6_addr_state(netif, 0))) { - if (nd6_send_rs(netif) == ERR_OK) { - netif->rs_count--; - } - } - } - } else { - nd6_tmr_rs_reduction--; - } -#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ - -} - -/** Send a neighbor solicitation message for a specific neighbor cache entry - * - * @param entry the neightbor cache entry for wich to send the message - * @param flags one of ND6_SEND_FLAG_* - */ -static void -nd6_send_neighbor_cache_probe(struct nd6_neighbor_cache_entry *entry, u8_t flags) -{ - nd6_send_ns(entry->netif, &entry->next_hop_address, flags); -} - -/** - * Send a neighbor solicitation message - * - * @param netif the netif on which to send the message - * @param target_addr the IPv6 target address for the ND message - * @param flags one of ND6_SEND_FLAG_* - */ -static void -nd6_send_ns(struct netif *netif, const ip6_addr_t *target_addr, u8_t flags) -{ - struct ns_header *ns_hdr; - struct pbuf *p; - const ip6_addr_t *src_addr; - u16_t lladdr_opt_len; - - LWIP_ASSERT("target address is required", target_addr != NULL); - - if (!(flags & ND6_SEND_FLAG_ANY_SRC) && - ip6_addr_isvalid(netif_ip6_addr_state(netif,0))) { - /* Use link-local address as source address. */ - src_addr = netif_ip6_addr(netif, 0); - /* calculate option length (in 8-byte-blocks) */ - lladdr_opt_len = ((netif->hwaddr_len + 2) + 7) >> 3; - } else { - src_addr = IP6_ADDR_ANY6; - /* Option "MUST NOT be included when the source IP address is the unspecified address." */ - lladdr_opt_len = 0; - } - - /* Allocate a packet. */ - p = pbuf_alloc(PBUF_IP, sizeof(struct ns_header) + (lladdr_opt_len << 3), PBUF_RAM); - if (p == NULL) { - ND6_STATS_INC(nd6.memerr); - return; - } - - /* Set fields. */ - ns_hdr = (struct ns_header *)p->payload; - - ns_hdr->type = ICMP6_TYPE_NS; - ns_hdr->code = 0; - ns_hdr->chksum = 0; - ns_hdr->reserved = 0; - ip6_addr_copy_to_packed(ns_hdr->target_address, *target_addr); - - if (lladdr_opt_len != 0) { - struct lladdr_option *lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct ns_header)); - lladdr_opt->type = ND6_OPTION_TYPE_SOURCE_LLADDR; - lladdr_opt->length = (u8_t)lladdr_opt_len; - SMEMCPY(lladdr_opt->addr, netif->hwaddr, netif->hwaddr_len); - } - - /* Generate the solicited node address for the target address. */ - if (flags & ND6_SEND_FLAG_MULTICAST_DEST) { - ip6_addr_set_solicitednode(&multicast_address, target_addr->addr[3]); - ip6_addr_assign_zone(&multicast_address, IP6_MULTICAST, netif); - target_addr = &multicast_address; - } - -#if CHECKSUM_GEN_ICMP6 - IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP6) { - ns_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr, - target_addr); - } -#endif /* CHECKSUM_GEN_ICMP6 */ - - /* Send the packet out. */ - ND6_STATS_INC(nd6.xmit); - ip6_output_if(p, (src_addr == IP6_ADDR_ANY6) ? NULL : src_addr, target_addr, - ND6_HOPLIM, 0, IP6_NEXTH_ICMP6, netif); - pbuf_free(p); -} - -/** - * Send a neighbor advertisement message - * - * @param netif the netif on which to send the message - * @param target_addr the IPv6 target address for the ND message - * @param flags one of ND6_SEND_FLAG_* - */ -static void -nd6_send_na(struct netif *netif, const ip6_addr_t *target_addr, u8_t flags) -{ - struct na_header *na_hdr; - struct lladdr_option *lladdr_opt; - struct pbuf *p; - const ip6_addr_t *src_addr; - const ip6_addr_t *dest_addr; - u16_t lladdr_opt_len; - - LWIP_ASSERT("target address is required", target_addr != NULL); - - /* Use link-local address as source address. */ - /* src_addr = netif_ip6_addr(netif, 0); */ - /* Use target address as source address. */ - src_addr = target_addr; - - /* Allocate a packet. */ - lladdr_opt_len = ((netif->hwaddr_len + 2) >> 3) + (((netif->hwaddr_len + 2) & 0x07) ? 1 : 0); - p = pbuf_alloc(PBUF_IP, sizeof(struct na_header) + (lladdr_opt_len << 3), PBUF_RAM); - if (p == NULL) { - ND6_STATS_INC(nd6.memerr); - return; - } - - /* Set fields. */ - na_hdr = (struct na_header *)p->payload; - lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct na_header)); - - na_hdr->type = ICMP6_TYPE_NA; - na_hdr->code = 0; - na_hdr->chksum = 0; - na_hdr->flags = flags & 0xf0; - na_hdr->reserved[0] = 0; - na_hdr->reserved[1] = 0; - na_hdr->reserved[2] = 0; - ip6_addr_copy_to_packed(na_hdr->target_address, *target_addr); - - lladdr_opt->type = ND6_OPTION_TYPE_TARGET_LLADDR; - lladdr_opt->length = (u8_t)lladdr_opt_len; - SMEMCPY(lladdr_opt->addr, netif->hwaddr, netif->hwaddr_len); - - /* Generate the solicited node address for the target address. */ - if (flags & ND6_SEND_FLAG_MULTICAST_DEST) { - ip6_addr_set_solicitednode(&multicast_address, target_addr->addr[3]); - ip6_addr_assign_zone(&multicast_address, IP6_MULTICAST, netif); - dest_addr = &multicast_address; - } else if (flags & ND6_SEND_FLAG_ALLNODES_DEST) { - ip6_addr_set_allnodes_linklocal(&multicast_address); - ip6_addr_assign_zone(&multicast_address, IP6_MULTICAST, netif); - dest_addr = &multicast_address; - } else { - dest_addr = ip6_current_src_addr(); - } - -#if CHECKSUM_GEN_ICMP6 - IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP6) { - na_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr, - dest_addr); - } -#endif /* CHECKSUM_GEN_ICMP6 */ - - /* Send the packet out. */ - ND6_STATS_INC(nd6.xmit); - ip6_output_if(p, src_addr, dest_addr, - ND6_HOPLIM, 0, IP6_NEXTH_ICMP6, netif); - pbuf_free(p); -} - -#if LWIP_IPV6_SEND_ROUTER_SOLICIT -/** - * Send a router solicitation message - * - * @param netif the netif on which to send the message - */ -static err_t -nd6_send_rs(struct netif *netif) -{ - struct rs_header *rs_hdr; - struct lladdr_option *lladdr_opt; - struct pbuf *p; - const ip6_addr_t *src_addr; - err_t err; - u16_t lladdr_opt_len = 0; - - /* Link-local source address, or unspecified address? */ - if (ip6_addr_isvalid(netif_ip6_addr_state(netif, 0))) { - src_addr = netif_ip6_addr(netif, 0); - } else { - src_addr = IP6_ADDR_ANY6; - } - - /* Generate the all routers target address. */ - ip6_addr_set_allrouters_linklocal(&multicast_address); - ip6_addr_assign_zone(&multicast_address, IP6_MULTICAST, netif); - - /* Allocate a packet. */ - if (src_addr != IP6_ADDR_ANY6) { - lladdr_opt_len = ((netif->hwaddr_len + 2) >> 3) + (((netif->hwaddr_len + 2) & 0x07) ? 1 : 0); - } - p = pbuf_alloc(PBUF_IP, sizeof(struct rs_header) + (lladdr_opt_len << 3), PBUF_RAM); - if (p == NULL) { - ND6_STATS_INC(nd6.memerr); - return ERR_BUF; - } - - /* Set fields. */ - rs_hdr = (struct rs_header *)p->payload; - - rs_hdr->type = ICMP6_TYPE_RS; - rs_hdr->code = 0; - rs_hdr->chksum = 0; - rs_hdr->reserved = 0; - - if (src_addr != IP6_ADDR_ANY6) { - /* Include our hw address. */ - lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct rs_header)); - lladdr_opt->type = ND6_OPTION_TYPE_SOURCE_LLADDR; - lladdr_opt->length = (u8_t)lladdr_opt_len; - SMEMCPY(lladdr_opt->addr, netif->hwaddr, netif->hwaddr_len); - } - -#if CHECKSUM_GEN_ICMP6 - IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP6) { - rs_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr, - &multicast_address); - } -#endif /* CHECKSUM_GEN_ICMP6 */ - - /* Send the packet out. */ - ND6_STATS_INC(nd6.xmit); - - err = ip6_output_if(p, (src_addr == IP6_ADDR_ANY6) ? NULL : src_addr, &multicast_address, - ND6_HOPLIM, 0, IP6_NEXTH_ICMP6, netif); - pbuf_free(p); - - return err; -} -#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ - -/** - * Search for a neighbor cache entry - * - * @param ip6addr the IPv6 address of the neighbor - * @return The neighbor cache entry index that matched, -1 if no - * entry is found - */ -static s8_t -nd6_find_neighbor_cache_entry(const ip6_addr_t *ip6addr) -{ - s8_t i; - for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { - if (ip6_addr_cmp(ip6addr, &(neighbor_cache[i].next_hop_address))) { - return i; - } - } - return -1; -} - -/** - * Create a new neighbor cache entry. - * - * If no unused entry is found, will try to recycle an old entry - * according to ad-hoc "age" heuristic. - * - * @return The neighbor cache entry index that was created, -1 if no - * entry could be created - */ -static s8_t -nd6_new_neighbor_cache_entry(void) -{ - s8_t i; - s8_t j; - u32_t time; - - - /* First, try to find an empty entry. */ - for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { - if (neighbor_cache[i].state == ND6_NO_ENTRY) { - return i; - } - } - - /* We need to recycle an entry. in general, do not recycle if it is a router. */ - - /* Next, try to find a Stale entry. */ - for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { - if ((neighbor_cache[i].state == ND6_STALE) && - (!neighbor_cache[i].isrouter)) { - nd6_free_neighbor_cache_entry(i); - return i; - } - } - - /* Next, try to find a Probe entry. */ - for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { - if ((neighbor_cache[i].state == ND6_PROBE) && - (!neighbor_cache[i].isrouter)) { - nd6_free_neighbor_cache_entry(i); - return i; - } - } - - /* Next, try to find a Delayed entry. */ - for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { - if ((neighbor_cache[i].state == ND6_DELAY) && - (!neighbor_cache[i].isrouter)) { - nd6_free_neighbor_cache_entry(i); - return i; - } - } - - /* Next, try to find the oldest reachable entry. */ - time = 0xfffffffful; - j = -1; - for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { - if ((neighbor_cache[i].state == ND6_REACHABLE) && - (!neighbor_cache[i].isrouter)) { - if (neighbor_cache[i].counter.reachable_time < time) { - j = i; - time = neighbor_cache[i].counter.reachable_time; - } - } - } - if (j >= 0) { - nd6_free_neighbor_cache_entry(j); - return j; - } - - /* Next, find oldest incomplete entry without queued packets. */ - time = 0; - j = -1; - for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { - if ( - (neighbor_cache[i].q == NULL) && - (neighbor_cache[i].state == ND6_INCOMPLETE) && - (!neighbor_cache[i].isrouter)) { - if (neighbor_cache[i].counter.probes_sent >= time) { - j = i; - time = neighbor_cache[i].counter.probes_sent; - } - } - } - if (j >= 0) { - nd6_free_neighbor_cache_entry(j); - return j; - } - - /* Next, find oldest incomplete entry with queued packets. */ - time = 0; - j = -1; - for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { - if ((neighbor_cache[i].state == ND6_INCOMPLETE) && - (!neighbor_cache[i].isrouter)) { - if (neighbor_cache[i].counter.probes_sent >= time) { - j = i; - time = neighbor_cache[i].counter.probes_sent; - } - } - } - if (j >= 0) { - nd6_free_neighbor_cache_entry(j); - return j; - } - - /* No more entries to try. */ - return -1; -} - -/** - * Will free any resources associated with a neighbor cache - * entry, and will mark it as unused. - * - * @param i the neighbor cache entry index to free - */ -static void -nd6_free_neighbor_cache_entry(s8_t i) -{ - if ((i < 0) || (i >= LWIP_ND6_NUM_NEIGHBORS)) { - return; - } - if (neighbor_cache[i].isrouter) { - /* isrouter needs to be cleared before deleting a neighbor cache entry */ - return; - } - - /* Free any queued packets. */ - if (neighbor_cache[i].q != NULL) { - nd6_free_q(neighbor_cache[i].q); - neighbor_cache[i].q = NULL; - } - - neighbor_cache[i].state = ND6_NO_ENTRY; - neighbor_cache[i].isrouter = 0; - neighbor_cache[i].netif = NULL; - neighbor_cache[i].counter.reachable_time = 0; - ip6_addr_set_zero(&(neighbor_cache[i].next_hop_address)); -} - -/** - * Search for a destination cache entry - * - * @param ip6addr the IPv6 address of the destination - * @return The destination cache entry index that matched, -1 if no - * entry is found - */ -static s16_t -nd6_find_destination_cache_entry(const ip6_addr_t *ip6addr) -{ - s16_t i; - - IP6_ADDR_ZONECHECK(ip6addr); - - for (i = 0; i < LWIP_ND6_NUM_DESTINATIONS; i++) { - if (ip6_addr_cmp(ip6addr, &(destination_cache[i].destination_addr))) { - return i; - } - } - return -1; -} - -/** - * Create a new destination cache entry. If no unused entry is found, - * will recycle oldest entry. - * - * @return The destination cache entry index that was created, -1 if no - * entry was created - */ -static s16_t -nd6_new_destination_cache_entry(void) -{ - s16_t i, j; - u32_t age; - - /* Find an empty entry. */ - for (i = 0; i < LWIP_ND6_NUM_DESTINATIONS; i++) { - if (ip6_addr_isany(&(destination_cache[i].destination_addr))) { - return i; - } - } - - /* Find oldest entry. */ - age = 0; - j = LWIP_ND6_NUM_DESTINATIONS - 1; - for (i = 0; i < LWIP_ND6_NUM_DESTINATIONS; i++) { - if (destination_cache[i].age > age) { - j = i; - } - } - - return j; -} - -/** - * Clear the destination cache. - * - * This operation may be necessary for consistency in the light of changing - * local addresses and/or use of the gateway hook. - */ -void -nd6_clear_destination_cache(void) -{ - int i; - - for (i = 0; i < LWIP_ND6_NUM_DESTINATIONS; i++) { - ip6_addr_set_any(&destination_cache[i].destination_addr); - } -} - -/** - * Determine whether an address matches an on-link prefix or the subnet of a - * statically assigned address. - * - * @param ip6addr the IPv6 address to match - * @return 1 if the address is on-link, 0 otherwise - */ -static int -nd6_is_prefix_in_netif(const ip6_addr_t *ip6addr, struct netif *netif) -{ - s8_t i; - - /* Check to see if the address matches an on-link prefix. */ - for (i = 0; i < LWIP_ND6_NUM_PREFIXES; i++) { - if ((prefix_list[i].netif == netif) && - (prefix_list[i].invalidation_timer > 0) && - ip6_addr_netcmp(ip6addr, &(prefix_list[i].prefix))) { - return 1; - } - } - /* Check to see if address prefix matches a manually configured (= static) - * address. Static addresses have an implied /64 subnet assignment. Dynamic - * addresses (from autoconfiguration) have no implied subnet assignment, and - * are thus effectively /128 assignments. See RFC 5942 for more on this. */ - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && - netif_ip6_addr_isstatic(netif, i) && - ip6_addr_netcmp(ip6addr, netif_ip6_addr(netif, i))) { - return 1; - } - } - return 0; -} - -/** - * Select a default router for a destination. - * - * This function is used both for routing and for finding a next-hop target for - * a packet. In the former case, the given netif is NULL, and the returned - * router entry must be for a netif suitable for sending packets (up, link up). - * In the latter case, the given netif is not NULL and restricts router choice. - * - * @param ip6addr the destination address - * @param netif the netif for the outgoing packet, if known - * @return the default router entry index, or -1 if no suitable - * router is found - */ -static s8_t -nd6_select_router(const ip6_addr_t *ip6addr, struct netif *netif) -{ - struct netif *router_netif; - s8_t i, j, valid_router; - static s8_t last_router; - - LWIP_UNUSED_ARG(ip6addr); /* @todo match preferred routes!! (must implement ND6_OPTION_TYPE_ROUTE_INFO) */ - - /* @todo: implement default router preference */ - - /* Look for valid routers. A reachable router is preferred. */ - valid_router = -1; - for (i = 0; i < LWIP_ND6_NUM_ROUTERS; i++) { - /* Is the router netif both set and apppropriate? */ - if (default_router_list[i].neighbor_entry != NULL) { - router_netif = default_router_list[i].neighbor_entry->netif; - if ((router_netif != NULL) && (netif != NULL ? netif == router_netif : - (netif_is_up(router_netif) && netif_is_link_up(router_netif)))) { - /* Is the router valid, i.e., reachable or probably reachable as per - * RFC 4861 Sec. 6.3.6? Note that we will never return a router that - * has no neighbor cache entry, due to the netif association tests. */ - if (default_router_list[i].neighbor_entry->state != ND6_INCOMPLETE) { - /* Is the router known to be reachable? */ - if (default_router_list[i].neighbor_entry->state == ND6_REACHABLE) { - return i; /* valid and reachable - done! */ - } else if (valid_router < 0) { - valid_router = i; /* valid but not known to be reachable */ - } - } - } - } - } - if (valid_router >= 0) { - return valid_router; - } - - /* Look for any router for which we have any information at all. */ - /* last_router is used for round-robin selection of incomplete routers, as - * recommended in RFC 4861 Sec. 6.3.6 point (2). Advance only when picking a - * route, to select the same router as next-hop target in the common case. */ - if ((netif == NULL) && (++last_router >= LWIP_ND6_NUM_ROUTERS)) { - last_router = 0; - } - i = last_router; - for (j = 0; j < LWIP_ND6_NUM_ROUTERS; j++) { - if (default_router_list[i].neighbor_entry != NULL) { - router_netif = default_router_list[i].neighbor_entry->netif; - if ((router_netif != NULL) && (netif != NULL ? netif == router_netif : - (netif_is_up(router_netif) && netif_is_link_up(router_netif)))) { - return i; - } - } - if (++i >= LWIP_ND6_NUM_ROUTERS) { - i = 0; - } - } - - /* no suitable router found. */ - return -1; -} - -/** - * Find a router-announced route to the given destination. This route may be - * based on an on-link prefix or a default router. - * - * If a suitable route is found, the returned netif is guaranteed to be in a - * suitable state (up, link up) to be used for packet transmission. - * - * @param ip6addr the destination IPv6 address - * @return the netif to use for the destination, or NULL if none found - */ -struct netif * -nd6_find_route(const ip6_addr_t *ip6addr) -{ - struct netif *netif; - s8_t i; - - /* @todo decide if it makes sense to check the destination cache first */ - - /* Check if there is a matching on-link prefix. There may be multiple - * matches. Pick the first one that is associated with a suitable netif. */ - for (i = 0; i < LWIP_ND6_NUM_PREFIXES; ++i) { - netif = prefix_list[i].netif; - if ((netif != NULL) && ip6_addr_netcmp(&prefix_list[i].prefix, ip6addr) && - netif_is_up(netif) && netif_is_link_up(netif)) { - return netif; - } - } - - /* No on-link prefix match. Find a router that can forward the packet. */ - i = nd6_select_router(ip6addr, NULL); - if (i >= 0) { - LWIP_ASSERT("selected router must have a neighbor entry", - default_router_list[i].neighbor_entry != NULL); - return default_router_list[i].neighbor_entry->netif; - } - - return NULL; -} - -/** - * Find an entry for a default router. - * - * @param router_addr the IPv6 address of the router - * @param netif the netif on which the router is found, if known - * @return the index of the router entry, or -1 if not found - */ -static s8_t -nd6_get_router(const ip6_addr_t *router_addr, struct netif *netif) -{ - s8_t i; - - IP6_ADDR_ZONECHECK_NETIF(router_addr, netif); - - /* Look for router. */ - for (i = 0; i < LWIP_ND6_NUM_ROUTERS; i++) { - if ((default_router_list[i].neighbor_entry != NULL) && - ((netif != NULL) ? netif == default_router_list[i].neighbor_entry->netif : 1) && - ip6_addr_cmp(router_addr, &(default_router_list[i].neighbor_entry->next_hop_address))) { - return i; - } - } - - /* router not found. */ - return -1; -} - -/** - * Create a new entry for a default router. - * - * @param router_addr the IPv6 address of the router - * @param netif the netif on which the router is connected, if known - * @return the index on the router table, or -1 if could not be created - */ -static s8_t -nd6_new_router(const ip6_addr_t *router_addr, struct netif *netif) -{ - s8_t router_index; - s8_t free_router_index; - s8_t neighbor_index; - - IP6_ADDR_ZONECHECK_NETIF(router_addr, netif); - - /* Do we have a neighbor entry for this router? */ - neighbor_index = nd6_find_neighbor_cache_entry(router_addr); - if (neighbor_index < 0) { - /* Create a neighbor entry for this router. */ - neighbor_index = nd6_new_neighbor_cache_entry(); - if (neighbor_index < 0) { - /* Could not create neighbor entry for this router. */ - return -1; - } - ip6_addr_set(&(neighbor_cache[neighbor_index].next_hop_address), router_addr); - neighbor_cache[neighbor_index].netif = netif; - neighbor_cache[neighbor_index].q = NULL; - neighbor_cache[neighbor_index].state = ND6_INCOMPLETE; - neighbor_cache[neighbor_index].counter.probes_sent = 1; - nd6_send_neighbor_cache_probe(&neighbor_cache[neighbor_index], ND6_SEND_FLAG_MULTICAST_DEST); - } - - /* Mark neighbor as router. */ - neighbor_cache[neighbor_index].isrouter = 1; - - /* Look for empty entry. */ - free_router_index = LWIP_ND6_NUM_ROUTERS; - for (router_index = LWIP_ND6_NUM_ROUTERS - 1; router_index >= 0; router_index--) { - /* check if router already exists (this is a special case for 2 netifs on the same subnet - - e.g. wifi and cable) */ - if(default_router_list[router_index].neighbor_entry == &(neighbor_cache[neighbor_index])){ - return router_index; - } - if (default_router_list[router_index].neighbor_entry == NULL) { - /* remember lowest free index to create a new entry */ - free_router_index = router_index; - } - } - if (free_router_index < LWIP_ND6_NUM_ROUTERS) { - default_router_list[free_router_index].neighbor_entry = &(neighbor_cache[neighbor_index]); - return free_router_index; - } - - /* Could not create a router entry. */ - - /* Mark neighbor entry as not-router. Entry might be useful as neighbor still. */ - neighbor_cache[neighbor_index].isrouter = 0; - - /* router not found. */ - return -1; -} - -/** - * Find the cached entry for an on-link prefix. - * - * @param prefix the IPv6 prefix that is on-link - * @param netif the netif on which the prefix is on-link - * @return the index on the prefix table, or -1 if not found - */ -static s8_t -nd6_get_onlink_prefix(const ip6_addr_t *prefix, struct netif *netif) -{ - s8_t i; - - /* Look for prefix in list. */ - for (i = 0; i < LWIP_ND6_NUM_PREFIXES; ++i) { - if ((ip6_addr_netcmp(&(prefix_list[i].prefix), prefix)) && - (prefix_list[i].netif == netif)) { - return i; - } - } - - /* Entry not available. */ - return -1; -} - -/** - * Creates a new entry for an on-link prefix. - * - * @param prefix the IPv6 prefix that is on-link - * @param netif the netif on which the prefix is on-link - * @return the index on the prefix table, or -1 if not created - */ -static s8_t -nd6_new_onlink_prefix(const ip6_addr_t *prefix, struct netif *netif) -{ - s8_t i; - - /* Create new entry. */ - for (i = 0; i < LWIP_ND6_NUM_PREFIXES; ++i) { - if ((prefix_list[i].netif == NULL) || - (prefix_list[i].invalidation_timer == 0)) { - /* Found empty prefix entry. */ - prefix_list[i].netif = netif; - ip6_addr_set(&(prefix_list[i].prefix), prefix); - return i; - } - } - - /* Entry not available. */ - return -1; -} - -/** - * Determine the next hop for a destination. Will determine if the - * destination is on-link, else a suitable on-link router is selected. - * - * The last entry index is cached for fast entry search. - * - * @param ip6addr the destination address - * @param netif the netif on which the packet will be sent - * @return the neighbor cache entry for the next hop, ERR_RTE if no - * suitable next hop was found, ERR_MEM if no cache entry - * could be created - */ -static s8_t -nd6_get_next_hop_entry(const ip6_addr_t *ip6addr, struct netif *netif) -{ -#ifdef LWIP_HOOK_ND6_GET_GW - const ip6_addr_t *next_hop_addr; -#endif /* LWIP_HOOK_ND6_GET_GW */ - s8_t i; - s16_t dst_idx; - - IP6_ADDR_ZONECHECK_NETIF(ip6addr, netif); - -#if LWIP_NETIF_HWADDRHINT - if (netif->hints != NULL) { - /* per-pcb cached entry was given */ - netif_addr_idx_t addr_hint = netif->hints->addr_hint; - if (addr_hint < LWIP_ND6_NUM_DESTINATIONS) { - nd6_cached_destination_index = addr_hint; - } - } -#endif /* LWIP_NETIF_HWADDRHINT */ - - /* Look for ip6addr in destination cache. */ - if (ip6_addr_cmp(ip6addr, &(destination_cache[nd6_cached_destination_index].destination_addr))) { - /* the cached entry index is the right one! */ - /* do nothing. */ - ND6_STATS_INC(nd6.cachehit); - } else { - /* Search destination cache. */ - dst_idx = nd6_find_destination_cache_entry(ip6addr); - if (dst_idx >= 0) { - /* found destination entry. make it our new cached index. */ - LWIP_ASSERT("type overflow", (size_t)dst_idx < NETIF_ADDR_IDX_MAX); - nd6_cached_destination_index = (netif_addr_idx_t)dst_idx; - } else { - /* Not found. Create a new destination entry. */ - dst_idx = nd6_new_destination_cache_entry(); - if (dst_idx >= 0) { - /* got new destination entry. make it our new cached index. */ - LWIP_ASSERT("type overflow", (size_t)dst_idx < NETIF_ADDR_IDX_MAX); - nd6_cached_destination_index = (netif_addr_idx_t)dst_idx; - } else { - /* Could not create a destination cache entry. */ - return ERR_MEM; - } - - /* Copy dest address to destination cache. */ - ip6_addr_set(&(destination_cache[nd6_cached_destination_index].destination_addr), ip6addr); - - /* Now find the next hop. is it a neighbor? */ - if (ip6_addr_islinklocal(ip6addr) || - nd6_is_prefix_in_netif(ip6addr, netif)) { - /* Destination in local link. */ - destination_cache[nd6_cached_destination_index].pmtu = netif_mtu6(netif); - ip6_addr_copy(destination_cache[nd6_cached_destination_index].next_hop_addr, destination_cache[nd6_cached_destination_index].destination_addr); -#ifdef LWIP_HOOK_ND6_GET_GW - } else if ((next_hop_addr = LWIP_HOOK_ND6_GET_GW(netif, ip6addr)) != NULL) { - /* Next hop for destination provided by hook function. */ - destination_cache[nd6_cached_destination_index].pmtu = netif->mtu; - ip6_addr_set(&destination_cache[nd6_cached_destination_index].next_hop_addr, next_hop_addr); -#endif /* LWIP_HOOK_ND6_GET_GW */ - } else { - /* We need to select a router. */ - i = nd6_select_router(ip6addr, netif); - if (i < 0) { - /* No router found. */ - ip6_addr_set_any(&(destination_cache[nd6_cached_destination_index].destination_addr)); - return ERR_RTE; - } - destination_cache[nd6_cached_destination_index].pmtu = netif_mtu6(netif); /* Start with netif mtu, correct through ICMPv6 if necessary */ - ip6_addr_copy(destination_cache[nd6_cached_destination_index].next_hop_addr, default_router_list[i].neighbor_entry->next_hop_address); - } - } - } - -#if LWIP_NETIF_HWADDRHINT - if (netif->hints != NULL) { - /* per-pcb cached entry was given */ - netif->hints->addr_hint = nd6_cached_destination_index; - } -#endif /* LWIP_NETIF_HWADDRHINT */ - - /* Look in neighbor cache for the next-hop address. */ - if (ip6_addr_cmp(&(destination_cache[nd6_cached_destination_index].next_hop_addr), - &(neighbor_cache[nd6_cached_neighbor_index].next_hop_address))) { - /* Cache hit. */ - /* Do nothing. */ - ND6_STATS_INC(nd6.cachehit); - } else { - i = nd6_find_neighbor_cache_entry(&(destination_cache[nd6_cached_destination_index].next_hop_addr)); - if (i >= 0) { - /* Found a matching record, make it new cached entry. */ - nd6_cached_neighbor_index = i; - } else { - /* Neighbor not in cache. Make a new entry. */ - i = nd6_new_neighbor_cache_entry(); - if (i >= 0) { - /* got new neighbor entry. make it our new cached index. */ - nd6_cached_neighbor_index = i; - } else { - /* Could not create a neighbor cache entry. */ - return ERR_MEM; - } - - /* Initialize fields. */ - ip6_addr_copy(neighbor_cache[i].next_hop_address, - destination_cache[nd6_cached_destination_index].next_hop_addr); - neighbor_cache[i].isrouter = 0; - neighbor_cache[i].netif = netif; - neighbor_cache[i].state = ND6_INCOMPLETE; - neighbor_cache[i].counter.probes_sent = 1; - nd6_send_neighbor_cache_probe(&neighbor_cache[i], ND6_SEND_FLAG_MULTICAST_DEST); - } - } - - /* Reset this destination's age. */ - destination_cache[nd6_cached_destination_index].age = 0; - - return nd6_cached_neighbor_index; -} - -/** - * Queue a packet for a neighbor. - * - * @param neighbor_index the index in the neighbor cache table - * @param q packet to be queued - * @return ERR_OK if succeeded, ERR_MEM if out of memory - */ -static err_t -nd6_queue_packet(s8_t neighbor_index, struct pbuf *q) -{ - err_t result = ERR_MEM; - struct pbuf *p; - int copy_needed = 0; -#if LWIP_ND6_QUEUEING - struct nd6_q_entry *new_entry, *r; -#endif /* LWIP_ND6_QUEUEING */ - - if ((neighbor_index < 0) || (neighbor_index >= LWIP_ND6_NUM_NEIGHBORS)) { - return ERR_ARG; - } - - /* IF q includes a pbuf that must be copied, we have to copy the whole chain - * into a new PBUF_RAM. See the definition of PBUF_NEEDS_COPY for details. */ - p = q; - while (p) { - if (PBUF_NEEDS_COPY(p)) { - copy_needed = 1; - break; - } - p = p->next; - } - if (copy_needed) { - /* copy the whole packet into new pbufs */ - p = pbuf_clone(PBUF_LINK, PBUF_RAM, q); - while ((p == NULL) && (neighbor_cache[neighbor_index].q != NULL)) { - /* Free oldest packet (as per RFC recommendation) */ -#if LWIP_ND6_QUEUEING - r = neighbor_cache[neighbor_index].q; - neighbor_cache[neighbor_index].q = r->next; - r->next = NULL; - nd6_free_q(r); -#else /* LWIP_ND6_QUEUEING */ - pbuf_free(neighbor_cache[neighbor_index].q); - neighbor_cache[neighbor_index].q = NULL; -#endif /* LWIP_ND6_QUEUEING */ - p = pbuf_clone(PBUF_LINK, PBUF_RAM, q); - } - } else { - /* referencing the old pbuf is enough */ - p = q; - pbuf_ref(p); - } - /* packet was copied/ref'd? */ - if (p != NULL) { - /* queue packet ... */ -#if LWIP_ND6_QUEUEING - /* allocate a new nd6 queue entry */ - new_entry = (struct nd6_q_entry *)memp_malloc(MEMP_ND6_QUEUE); - if ((new_entry == NULL) && (neighbor_cache[neighbor_index].q != NULL)) { - /* Free oldest packet (as per RFC recommendation) */ - r = neighbor_cache[neighbor_index].q; - neighbor_cache[neighbor_index].q = r->next; - r->next = NULL; - nd6_free_q(r); - new_entry = (struct nd6_q_entry *)memp_malloc(MEMP_ND6_QUEUE); - } - if (new_entry != NULL) { - new_entry->next = NULL; - new_entry->p = p; - if (neighbor_cache[neighbor_index].q != NULL) { - /* queue was already existent, append the new entry to the end */ - r = neighbor_cache[neighbor_index].q; - while (r->next != NULL) { - r = r->next; - } - r->next = new_entry; - } else { - /* queue did not exist, first item in queue */ - neighbor_cache[neighbor_index].q = new_entry; - } - LWIP_DEBUGF(LWIP_DBG_TRACE, ("ipv6: queued packet %p on neighbor entry %"S16_F"\n", (void *)p, (s16_t)neighbor_index)); - result = ERR_OK; - } else { - /* the pool MEMP_ND6_QUEUE is empty */ - pbuf_free(p); - LWIP_DEBUGF(LWIP_DBG_TRACE, ("ipv6: could not queue a copy of packet %p (out of memory)\n", (void *)p)); - /* { result == ERR_MEM } through initialization */ - } -#else /* LWIP_ND6_QUEUEING */ - /* Queue a single packet. If an older packet is already queued, free it as per RFC. */ - if (neighbor_cache[neighbor_index].q != NULL) { - pbuf_free(neighbor_cache[neighbor_index].q); - } - neighbor_cache[neighbor_index].q = p; - LWIP_DEBUGF(LWIP_DBG_TRACE, ("ipv6: queued packet %p on neighbor entry %"S16_F"\n", (void *)p, (s16_t)neighbor_index)); - result = ERR_OK; -#endif /* LWIP_ND6_QUEUEING */ - } else { - LWIP_DEBUGF(LWIP_DBG_TRACE, ("ipv6: could not queue a copy of packet %p (out of memory)\n", (void *)q)); - /* { result == ERR_MEM } through initialization */ - } - - return result; -} - -#if LWIP_ND6_QUEUEING -/** - * Free a complete queue of nd6 q entries - * - * @param q a queue of nd6_q_entry to free - */ -static void -nd6_free_q(struct nd6_q_entry *q) -{ - struct nd6_q_entry *r; - LWIP_ASSERT("q != NULL", q != NULL); - LWIP_ASSERT("q->p != NULL", q->p != NULL); - while (q) { - r = q; - q = q->next; - LWIP_ASSERT("r->p != NULL", (r->p != NULL)); - pbuf_free(r->p); - memp_free(MEMP_ND6_QUEUE, r); - } -} -#endif /* LWIP_ND6_QUEUEING */ - -/** - * Send queued packets for a neighbor - * - * @param i the neighbor to send packets to - */ -static void -nd6_send_q(s8_t i) -{ - struct ip6_hdr *ip6hdr; - ip6_addr_t dest; -#if LWIP_ND6_QUEUEING - struct nd6_q_entry *q; -#endif /* LWIP_ND6_QUEUEING */ - - if ((i < 0) || (i >= LWIP_ND6_NUM_NEIGHBORS)) { - return; - } - -#if LWIP_ND6_QUEUEING - while (neighbor_cache[i].q != NULL) { - /* remember first in queue */ - q = neighbor_cache[i].q; - /* pop first item off the queue */ - neighbor_cache[i].q = q->next; - /* Get ipv6 header. */ - ip6hdr = (struct ip6_hdr *)(q->p->payload); - /* Create an aligned copy. */ - ip6_addr_copy_from_packed(dest, ip6hdr->dest); - /* Restore the zone, if applicable. */ - ip6_addr_assign_zone(&dest, IP6_UNKNOWN, neighbor_cache[i].netif); - /* send the queued IPv6 packet */ - (neighbor_cache[i].netif)->output_ip6(neighbor_cache[i].netif, q->p, &dest); - /* free the queued IP packet */ - pbuf_free(q->p); - /* now queue entry can be freed */ - memp_free(MEMP_ND6_QUEUE, q); - } -#else /* LWIP_ND6_QUEUEING */ - if (neighbor_cache[i].q != NULL) { - /* Get ipv6 header. */ - ip6hdr = (struct ip6_hdr *)(neighbor_cache[i].q->payload); - /* Create an aligned copy. */ - ip6_addr_copy_from_packed(dest, ip6hdr->dest); - /* Restore the zone, if applicable. */ - ip6_addr_assign_zone(&dest, IP6_UNKNOWN, neighbor_cache[i].netif); - /* send the queued IPv6 packet */ - (neighbor_cache[i].netif)->output_ip6(neighbor_cache[i].netif, neighbor_cache[i].q, &dest); - /* free the queued IP packet */ - pbuf_free(neighbor_cache[i].q); - neighbor_cache[i].q = NULL; - } -#endif /* LWIP_ND6_QUEUEING */ -} - -/** - * A packet is to be transmitted to a specific IPv6 destination on a specific - * interface. Check if we can find the hardware address of the next hop to use - * for the packet. If so, give the hardware address to the caller, which should - * use it to send the packet right away. Otherwise, enqueue the packet for - * later transmission while looking up the hardware address, if possible. - * - * As such, this function returns one of three different possible results: - * - * - ERR_OK with a non-NULL 'hwaddrp': the caller should send the packet now. - * - ERR_OK with a NULL 'hwaddrp': the packet has been enqueued for later. - * - not ERR_OK: something went wrong; forward the error upward in the stack. - * - * @param netif The lwIP network interface on which the IP packet will be sent. - * @param q The pbuf(s) containing the IP packet to be sent. - * @param ip6addr The destination IPv6 address of the packet. - * @param hwaddrp On success, filled with a pointer to a HW address or NULL (meaning - * the packet has been queued). - * @return - * - ERR_OK on success, ERR_RTE if no route was found for the packet, - * or ERR_MEM if low memory conditions prohibit sending the packet at all. - */ -err_t -nd6_get_next_hop_addr_or_queue(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr, const u8_t **hwaddrp) -{ - s8_t i; - - /* Get next hop record. */ - i = nd6_get_next_hop_entry(ip6addr, netif); - if (i < 0) { - /* failed to get a next hop neighbor record. */ - return i; - } - - /* Now that we have a destination record, send or queue the packet. */ - if (neighbor_cache[i].state == ND6_STALE) { - /* Switch to delay state. */ - neighbor_cache[i].state = ND6_DELAY; - neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME / ND6_TMR_INTERVAL; - } - /* @todo should we send or queue if PROBE? send for now, to let unicast NS pass. */ - if ((neighbor_cache[i].state == ND6_REACHABLE) || - (neighbor_cache[i].state == ND6_DELAY) || - (neighbor_cache[i].state == ND6_PROBE)) { - - /* Tell the caller to send out the packet now. */ - *hwaddrp = neighbor_cache[i].lladdr; - return ERR_OK; - } - - /* We should queue packet on this interface. */ - *hwaddrp = NULL; - return nd6_queue_packet(i, q); -} - - -/** - * Get the Path MTU for a destination. - * - * @param ip6addr the destination address - * @param netif the netif on which the packet will be sent - * @return the Path MTU, if known, or the netif default MTU - */ -u16_t -nd6_get_destination_mtu(const ip6_addr_t *ip6addr, struct netif *netif) -{ - s16_t i; - - i = nd6_find_destination_cache_entry(ip6addr); - if (i >= 0) { - if (destination_cache[i].pmtu > 0) { - return destination_cache[i].pmtu; - } - } - - if (netif != NULL) { - return netif_mtu6(netif); - } - - return 1280; /* Minimum MTU */ -} - - -#if LWIP_ND6_TCP_REACHABILITY_HINTS -/** - * Provide the Neighbor discovery process with a hint that a - * destination is reachable. Called by tcp_receive when ACKs are - * received or sent (as per RFC). This is useful to avoid sending - * NS messages every 30 seconds. - * - * @param ip6addr the destination address which is know to be reachable - * by an upper layer protocol (TCP) - */ -void -nd6_reachability_hint(const ip6_addr_t *ip6addr) -{ - s8_t i; - s16_t dst_idx; - - /* Find destination in cache. */ - if (ip6_addr_cmp(ip6addr, &(destination_cache[nd6_cached_destination_index].destination_addr))) { - dst_idx = nd6_cached_destination_index; - ND6_STATS_INC(nd6.cachehit); - } else { - dst_idx = nd6_find_destination_cache_entry(ip6addr); - } - if (dst_idx < 0) { - return; - } - - /* Find next hop neighbor in cache. */ - if (ip6_addr_cmp(&(destination_cache[dst_idx].next_hop_addr), &(neighbor_cache[nd6_cached_neighbor_index].next_hop_address))) { - i = nd6_cached_neighbor_index; - ND6_STATS_INC(nd6.cachehit); - } else { - i = nd6_find_neighbor_cache_entry(&(destination_cache[dst_idx].next_hop_addr)); - } - if (i < 0) { - return; - } - - /* For safety: don't set as reachable if we don't have a LL address yet. Misuse protection. */ - if (neighbor_cache[i].state == ND6_INCOMPLETE || neighbor_cache[i].state == ND6_NO_ENTRY) { - return; - } - - /* Set reachability state. */ - neighbor_cache[i].state = ND6_REACHABLE; - neighbor_cache[i].counter.reachable_time = reachable_time; -} -#endif /* LWIP_ND6_TCP_REACHABILITY_HINTS */ - -/** - * Remove all prefix, neighbor_cache and router entries of the specified netif. - * - * @param netif points to a network interface - */ -void -nd6_cleanup_netif(struct netif *netif) -{ - u8_t i; - s8_t router_index; - for (i = 0; i < LWIP_ND6_NUM_PREFIXES; i++) { - if (prefix_list[i].netif == netif) { - prefix_list[i].netif = NULL; - } - } - for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { - if (neighbor_cache[i].netif == netif) { - for (router_index = 0; router_index < LWIP_ND6_NUM_ROUTERS; router_index++) { - if (default_router_list[router_index].neighbor_entry == &neighbor_cache[i]) { - default_router_list[router_index].neighbor_entry = NULL; - default_router_list[router_index].flags = 0; - } - } - neighbor_cache[i].isrouter = 0; - nd6_free_neighbor_cache_entry(i); - } - } - /* Clear the destination cache, since many entries may now have become - * invalid for one of several reasons. As destination cache entries have no - * netif association, use a sledgehammer approach (this can be improved). */ - nd6_clear_destination_cache(); -} - -#if LWIP_IPV6_MLD -/** - * The state of a local IPv6 address entry is about to change. If needed, join - * or leave the solicited-node multicast group for the address. - * - * @param netif The netif that owns the address. - * @param addr_idx The index of the address. - * @param new_state The new (IP6_ADDR_) state for the address. - */ -void -nd6_adjust_mld_membership(struct netif *netif, s8_t addr_idx, u8_t new_state) -{ - u8_t old_state, old_member, new_member; - - old_state = netif_ip6_addr_state(netif, addr_idx); - - /* Determine whether we were, and should be, a member of the solicited-node - * multicast group for this address. For tentative addresses, the group is - * not joined until the address enters the TENTATIVE_1 (or VALID) state. */ - old_member = (old_state != IP6_ADDR_INVALID && old_state != IP6_ADDR_DUPLICATED && old_state != IP6_ADDR_TENTATIVE); - new_member = (new_state != IP6_ADDR_INVALID && new_state != IP6_ADDR_DUPLICATED && new_state != IP6_ADDR_TENTATIVE); - - if (old_member != new_member) { - ip6_addr_set_solicitednode(&multicast_address, netif_ip6_addr(netif, addr_idx)->addr[3]); - ip6_addr_assign_zone(&multicast_address, IP6_MULTICAST, netif); - - if (new_member) { - mld6_joingroup_netif(netif, &multicast_address); - } else { - mld6_leavegroup_netif(netif, &multicast_address); - } - } -} -#endif /* LWIP_IPV6_MLD */ - -/** Netif was added, set up, or reconnected (link up) */ -void -nd6_restart_netif(struct netif *netif) -{ -#if LWIP_IPV6_SEND_ROUTER_SOLICIT - /* Send Router Solicitation messages (see RFC 4861, ch. 6.3.7). */ - netif->rs_count = LWIP_ND6_MAX_MULTICAST_SOLICIT; -#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ -} - -#endif /* LWIP_IPV6 */ diff --git a/third-party/lwip-2.1.2/core/mem.c b/third-party/lwip-2.1.2/core/mem.c deleted file mode 100644 index a15997ce..00000000 --- a/third-party/lwip-2.1.2/core/mem.c +++ /dev/null @@ -1,1017 +0,0 @@ -/** - * @file - * Dynamic memory manager - * - * This is a lightweight replacement for the standard C library malloc(). - * - * If you want to use the standard C library malloc() instead, define - * MEM_LIBC_MALLOC to 1 in your lwipopts.h - * - * To let mem_malloc() use pools (prevents fragmentation and is much faster than - * a heap but might waste some memory), define MEM_USE_POOLS to 1, define - * MEMP_USE_CUSTOM_POOLS to 1 and create a file "lwippools.h" that includes a list - * of pools like this (more pools can be added between _START and _END): - * - * Define three pools with sizes 256, 512, and 1512 bytes - * LWIP_MALLOC_MEMPOOL_START - * LWIP_MALLOC_MEMPOOL(20, 256) - * LWIP_MALLOC_MEMPOOL(10, 512) - * LWIP_MALLOC_MEMPOOL(5, 1512) - * LWIP_MALLOC_MEMPOOL_END - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * Simon Goldschmidt - * - */ - -#include "lwip/opt.h" -#include "lwip/mem.h" -#include "lwip/def.h" -#include "lwip/sys.h" -#include "lwip/stats.h" -#include "lwip/err.h" - -#include - -#if MEM_LIBC_MALLOC -#include /* for malloc()/free() */ -#endif - -/* This is overridable for tests only... */ -#ifndef LWIP_MEM_ILLEGAL_FREE -#define LWIP_MEM_ILLEGAL_FREE(msg) LWIP_ASSERT(msg, 0) -#endif - -#define MEM_STATS_INC_LOCKED(x) SYS_ARCH_LOCKED(MEM_STATS_INC(x)) -#define MEM_STATS_INC_USED_LOCKED(x, y) SYS_ARCH_LOCKED(MEM_STATS_INC_USED(x, y)) -#define MEM_STATS_DEC_USED_LOCKED(x, y) SYS_ARCH_LOCKED(MEM_STATS_DEC_USED(x, y)) - -#if MEM_OVERFLOW_CHECK -#define MEM_SANITY_OFFSET MEM_SANITY_REGION_BEFORE_ALIGNED -#define MEM_SANITY_OVERHEAD (MEM_SANITY_REGION_BEFORE_ALIGNED + MEM_SANITY_REGION_AFTER_ALIGNED) -#else -#define MEM_SANITY_OFFSET 0 -#define MEM_SANITY_OVERHEAD 0 -#endif - -#if MEM_OVERFLOW_CHECK || MEMP_OVERFLOW_CHECK -/** - * Check if a mep element was victim of an overflow or underflow - * (e.g. the restricted area after/before it has been altered) - * - * @param p the mem element to check - * @param size allocated size of the element - * @param descr1 description of the element source shown on error - * @param descr2 description of the element source shown on error - */ -void -mem_overflow_check_raw(void *p, size_t size, const char *descr1, const char *descr2) -{ -#if MEM_SANITY_REGION_AFTER_ALIGNED || MEM_SANITY_REGION_BEFORE_ALIGNED - u16_t k; - u8_t *m; - -#if MEM_SANITY_REGION_AFTER_ALIGNED > 0 - m = (u8_t *)p + size; - for (k = 0; k < MEM_SANITY_REGION_AFTER_ALIGNED; k++) { - if (m[k] != 0xcd) { - char errstr[128]; - snprintf(errstr, sizeof(errstr), "detected mem overflow in %s%s", descr1, descr2); - LWIP_ASSERT(errstr, 0); - } - } -#endif /* MEM_SANITY_REGION_AFTER_ALIGNED > 0 */ - -#if MEM_SANITY_REGION_BEFORE_ALIGNED > 0 - m = (u8_t *)p - MEM_SANITY_REGION_BEFORE_ALIGNED; - for (k = 0; k < MEM_SANITY_REGION_BEFORE_ALIGNED; k++) { - if (m[k] != 0xcd) { - char errstr[128]; - snprintf(errstr, sizeof(errstr), "detected mem underflow in %s%s", descr1, descr2); - LWIP_ASSERT(errstr, 0); - } - } -#endif /* MEM_SANITY_REGION_BEFORE_ALIGNED > 0 */ -#else - LWIP_UNUSED_ARG(p); - LWIP_UNUSED_ARG(desc); - LWIP_UNUSED_ARG(descr); -#endif -} - -/** - * Initialize the restricted area of a mem element. - */ -void -mem_overflow_init_raw(void *p, size_t size) -{ -#if MEM_SANITY_REGION_BEFORE_ALIGNED > 0 || MEM_SANITY_REGION_AFTER_ALIGNED > 0 - u8_t *m; -#if MEM_SANITY_REGION_BEFORE_ALIGNED > 0 - m = (u8_t *)p - MEM_SANITY_REGION_BEFORE_ALIGNED; - memset(m, 0xcd, MEM_SANITY_REGION_BEFORE_ALIGNED); -#endif -#if MEM_SANITY_REGION_AFTER_ALIGNED > 0 - m = (u8_t *)p + size; - memset(m, 0xcd, MEM_SANITY_REGION_AFTER_ALIGNED); -#endif -#else /* MEM_SANITY_REGION_BEFORE_ALIGNED > 0 || MEM_SANITY_REGION_AFTER_ALIGNED > 0 */ - LWIP_UNUSED_ARG(p); - LWIP_UNUSED_ARG(desc); -#endif /* MEM_SANITY_REGION_BEFORE_ALIGNED > 0 || MEM_SANITY_REGION_AFTER_ALIGNED > 0 */ -} -#endif /* MEM_OVERFLOW_CHECK || MEMP_OVERFLOW_CHECK */ - -#if MEM_LIBC_MALLOC || MEM_USE_POOLS - -/** mem_init is not used when using pools instead of a heap or using - * C library malloc(). - */ -void -mem_init(void) -{ -} - -/** mem_trim is not used when using pools instead of a heap or using - * C library malloc(): we can't free part of a pool element and the stack - * support mem_trim() to return a different pointer - */ -void * -mem_trim(void *mem, mem_size_t size) -{ - LWIP_UNUSED_ARG(size); - return mem; -} -#endif /* MEM_LIBC_MALLOC || MEM_USE_POOLS */ - -#if MEM_LIBC_MALLOC -/* lwIP heap implemented using C library malloc() */ - -/* in case C library malloc() needs extra protection, - * allow these defines to be overridden. - */ -#ifndef mem_clib_free -#define mem_clib_free free -#endif -#ifndef mem_clib_malloc -#define mem_clib_malloc malloc -#endif -#ifndef mem_clib_calloc -#define mem_clib_calloc calloc -#endif - -#if LWIP_STATS && MEM_STATS -#define MEM_LIBC_STATSHELPER_SIZE LWIP_MEM_ALIGN_SIZE(sizeof(mem_size_t)) -#else -#define MEM_LIBC_STATSHELPER_SIZE 0 -#endif - -/** - * Allocate a block of memory with a minimum of 'size' bytes. - * - * @param size is the minimum size of the requested block in bytes. - * @return pointer to allocated memory or NULL if no free memory was found. - * - * Note that the returned value must always be aligned (as defined by MEM_ALIGNMENT). - */ -void * -mem_malloc(mem_size_t size) -{ - void *ret = mem_clib_malloc(size + MEM_LIBC_STATSHELPER_SIZE); - if (ret == NULL) { - MEM_STATS_INC_LOCKED(err); - } else { - LWIP_ASSERT("malloc() must return aligned memory", LWIP_MEM_ALIGN(ret) == ret); -#if LWIP_STATS && MEM_STATS - *(mem_size_t *)ret = size; - ret = (u8_t *)ret + MEM_LIBC_STATSHELPER_SIZE; - MEM_STATS_INC_USED_LOCKED(used, size); -#endif - } - return ret; -} - -/** Put memory back on the heap - * - * @param rmem is the pointer as returned by a previous call to mem_malloc() - */ -void -mem_free(void *rmem) -{ - LWIP_ASSERT("rmem != NULL", (rmem != NULL)); - LWIP_ASSERT("rmem == MEM_ALIGN(rmem)", (rmem == LWIP_MEM_ALIGN(rmem))); -#if LWIP_STATS && MEM_STATS - rmem = (u8_t *)rmem - MEM_LIBC_STATSHELPER_SIZE; - MEM_STATS_DEC_USED_LOCKED(used, *(mem_size_t *)rmem); -#endif - mem_clib_free(rmem); -} - -#elif MEM_USE_POOLS - -/* lwIP heap implemented with different sized pools */ - -/** - * Allocate memory: determine the smallest pool that is big enough - * to contain an element of 'size' and get an element from that pool. - * - * @param size the size in bytes of the memory needed - * @return a pointer to the allocated memory or NULL if the pool is empty - */ -void * -mem_malloc(mem_size_t size) -{ - void *ret; - struct memp_malloc_helper *element = NULL; - memp_t poolnr; - mem_size_t required_size = size + LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper)); - - for (poolnr = MEMP_POOL_FIRST; poolnr <= MEMP_POOL_LAST; poolnr = (memp_t)(poolnr + 1)) { - /* is this pool big enough to hold an element of the required size - plus a struct memp_malloc_helper that saves the pool this element came from? */ - if (required_size <= memp_pools[poolnr]->size) { - element = (struct memp_malloc_helper *)memp_malloc(poolnr); - if (element == NULL) { - /* No need to DEBUGF or ASSERT: This error is already taken care of in memp.c */ -#if MEM_USE_POOLS_TRY_BIGGER_POOL - /** Try a bigger pool if this one is empty! */ - if (poolnr < MEMP_POOL_LAST) { - continue; - } -#endif /* MEM_USE_POOLS_TRY_BIGGER_POOL */ - MEM_STATS_INC_LOCKED(err); - return NULL; - } - break; - } - } - if (poolnr > MEMP_POOL_LAST) { - LWIP_ASSERT("mem_malloc(): no pool is that big!", 0); - MEM_STATS_INC_LOCKED(err); - return NULL; - } - - /* save the pool number this element came from */ - element->poolnr = poolnr; - /* and return a pointer to the memory directly after the struct memp_malloc_helper */ - ret = (u8_t *)element + LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper)); - -#if MEMP_OVERFLOW_CHECK || (LWIP_STATS && MEM_STATS) - /* truncating to u16_t is safe because struct memp_desc::size is u16_t */ - element->size = (u16_t)size; - MEM_STATS_INC_USED_LOCKED(used, element->size); -#endif /* MEMP_OVERFLOW_CHECK || (LWIP_STATS && MEM_STATS) */ -#if MEMP_OVERFLOW_CHECK - /* initialize unused memory (diff between requested size and selected pool's size) */ - memset((u8_t *)ret + size, 0xcd, memp_pools[poolnr]->size - size); -#endif /* MEMP_OVERFLOW_CHECK */ - return ret; -} - -/** - * Free memory previously allocated by mem_malloc. Loads the pool number - * and calls memp_free with that pool number to put the element back into - * its pool - * - * @param rmem the memory element to free - */ -void -mem_free(void *rmem) -{ - struct memp_malloc_helper *hmem; - - LWIP_ASSERT("rmem != NULL", (rmem != NULL)); - LWIP_ASSERT("rmem == MEM_ALIGN(rmem)", (rmem == LWIP_MEM_ALIGN(rmem))); - - /* get the original struct memp_malloc_helper */ - /* cast through void* to get rid of alignment warnings */ - hmem = (struct memp_malloc_helper *)(void *)((u8_t *)rmem - LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper))); - - LWIP_ASSERT("hmem != NULL", (hmem != NULL)); - LWIP_ASSERT("hmem == MEM_ALIGN(hmem)", (hmem == LWIP_MEM_ALIGN(hmem))); - LWIP_ASSERT("hmem->poolnr < MEMP_MAX", (hmem->poolnr < MEMP_MAX)); - - MEM_STATS_DEC_USED_LOCKED(used, hmem->size); -#if MEMP_OVERFLOW_CHECK - { - u16_t i; - LWIP_ASSERT("MEM_USE_POOLS: invalid chunk size", - hmem->size <= memp_pools[hmem->poolnr]->size); - /* check that unused memory remained untouched (diff between requested size and selected pool's size) */ - for (i = hmem->size; i < memp_pools[hmem->poolnr]->size; i++) { - u8_t data = *((u8_t *)rmem + i); - LWIP_ASSERT("MEM_USE_POOLS: mem overflow detected", data == 0xcd); - } - } -#endif /* MEMP_OVERFLOW_CHECK */ - - /* and put it in the pool we saved earlier */ - memp_free(hmem->poolnr, hmem); -} - -#else /* MEM_USE_POOLS */ -/* lwIP replacement for your libc malloc() */ - -/** - * The heap is made up as a list of structs of this type. - * This does not have to be aligned since for getting its size, - * we only use the macro SIZEOF_STRUCT_MEM, which automatically aligns. - */ -struct mem { - /** index (-> ram[next]) of the next struct */ - mem_size_t next; - /** index (-> ram[prev]) of the previous struct */ - mem_size_t prev; - /** 1: this area is used; 0: this area is unused */ - u8_t used; -#if MEM_OVERFLOW_CHECK - /** this keeps track of the user allocation size for guard checks */ - mem_size_t user_size; -#endif -}; - -/** All allocated blocks will be MIN_SIZE bytes big, at least! - * MIN_SIZE can be overridden to suit your needs. Smaller values save space, - * larger values could prevent too small blocks to fragment the RAM too much. */ -#ifndef MIN_SIZE -#define MIN_SIZE 12 -#endif /* MIN_SIZE */ -/* some alignment macros: we define them here for better source code layout */ -#define MIN_SIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(MIN_SIZE) -#define SIZEOF_STRUCT_MEM LWIP_MEM_ALIGN_SIZE(sizeof(struct mem)) -#define MEM_SIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(MEM_SIZE) - -/** If you want to relocate the heap to external memory, simply define - * LWIP_RAM_HEAP_POINTER as a void-pointer to that location. - * If so, make sure the memory at that location is big enough (see below on - * how that space is calculated). */ -#ifndef LWIP_RAM_HEAP_POINTER -/** the heap. we need one struct mem at the end and some room for alignment */ -LWIP_DECLARE_MEMORY_ALIGNED(ram_heap, MEM_SIZE_ALIGNED + (2U * SIZEOF_STRUCT_MEM)); -#define LWIP_RAM_HEAP_POINTER ram_heap -#endif /* LWIP_RAM_HEAP_POINTER */ - -/** pointer to the heap (ram_heap): for alignment, ram is now a pointer instead of an array */ -static u8_t *ram; -/** the last entry, always unused! */ -static struct mem *ram_end; - -/** concurrent access protection */ -#if !NO_SYS -static sys_mutex_t mem_mutex; -#endif - -#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT - -static volatile u8_t mem_free_count; - -/* Allow mem_free from other (e.g. interrupt) context */ -#define LWIP_MEM_FREE_DECL_PROTECT() SYS_ARCH_DECL_PROTECT(lev_free) -#define LWIP_MEM_FREE_PROTECT() SYS_ARCH_PROTECT(lev_free) -#define LWIP_MEM_FREE_UNPROTECT() SYS_ARCH_UNPROTECT(lev_free) -#define LWIP_MEM_ALLOC_DECL_PROTECT() SYS_ARCH_DECL_PROTECT(lev_alloc) -#define LWIP_MEM_ALLOC_PROTECT() SYS_ARCH_PROTECT(lev_alloc) -#define LWIP_MEM_ALLOC_UNPROTECT() SYS_ARCH_UNPROTECT(lev_alloc) -#define LWIP_MEM_LFREE_VOLATILE volatile - -#else /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ - -/* Protect the heap only by using a mutex */ -#define LWIP_MEM_FREE_DECL_PROTECT() -#define LWIP_MEM_FREE_PROTECT() sys_mutex_lock(&mem_mutex) -#define LWIP_MEM_FREE_UNPROTECT() sys_mutex_unlock(&mem_mutex) -/* mem_malloc is protected using mutex AND LWIP_MEM_ALLOC_PROTECT */ -#define LWIP_MEM_ALLOC_DECL_PROTECT() -#define LWIP_MEM_ALLOC_PROTECT() -#define LWIP_MEM_ALLOC_UNPROTECT() -#define LWIP_MEM_LFREE_VOLATILE - -#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ - -/** pointer to the lowest free block, this is used for faster search */ -static struct mem * LWIP_MEM_LFREE_VOLATILE lfree; - -#if MEM_SANITY_CHECK -static void mem_sanity(void); -#define MEM_SANITY() mem_sanity() -#else -#define MEM_SANITY() -#endif - -#if MEM_OVERFLOW_CHECK -static void -mem_overflow_init_element(struct mem *mem, mem_size_t user_size) -{ - void *p = (u8_t *)mem + SIZEOF_STRUCT_MEM + MEM_SANITY_OFFSET; - mem->user_size = user_size; - mem_overflow_init_raw(p, user_size); -} - -static void -mem_overflow_check_element(struct mem *mem) -{ - void *p = (u8_t *)mem + SIZEOF_STRUCT_MEM + MEM_SANITY_OFFSET; - mem_overflow_check_raw(p, mem->user_size, "heap", ""); -} -#else /* MEM_OVERFLOW_CHECK */ -#define mem_overflow_init_element(mem, size) -#define mem_overflow_check_element(mem) -#endif /* MEM_OVERFLOW_CHECK */ - -static struct mem * -ptr_to_mem(mem_size_t ptr) -{ - return (struct mem *)(void *)&ram[ptr]; -} - -static mem_size_t -mem_to_ptr(void *mem) -{ - return (mem_size_t)((u8_t *)mem - ram); -} - -/** - * "Plug holes" by combining adjacent empty struct mems. - * After this function is through, there should not exist - * one empty struct mem pointing to another empty struct mem. - * - * @param mem this points to a struct mem which just has been freed - * @internal this function is only called by mem_free() and mem_trim() - * - * This assumes access to the heap is protected by the calling function - * already. - */ -static void -plug_holes(struct mem *mem) -{ - struct mem *nmem; - struct mem *pmem; - - LWIP_ASSERT("plug_holes: mem >= ram", (u8_t *)mem >= ram); - LWIP_ASSERT("plug_holes: mem < ram_end", (u8_t *)mem < (u8_t *)ram_end); - LWIP_ASSERT("plug_holes: mem->used == 0", mem->used == 0); - - /* plug hole forward */ - LWIP_ASSERT("plug_holes: mem->next <= MEM_SIZE_ALIGNED", mem->next <= MEM_SIZE_ALIGNED); - - nmem = ptr_to_mem(mem->next); - if (mem != nmem && nmem->used == 0 && (u8_t *)nmem != (u8_t *)ram_end) { - /* if mem->next is unused and not end of ram, combine mem and mem->next */ - if (lfree == nmem) { - lfree = mem; - } - mem->next = nmem->next; - if (nmem->next != MEM_SIZE_ALIGNED) { - ptr_to_mem(nmem->next)->prev = mem_to_ptr(mem); - } - } - - /* plug hole backward */ - pmem = ptr_to_mem(mem->prev); - if (pmem != mem && pmem->used == 0) { - /* if mem->prev is unused, combine mem and mem->prev */ - if (lfree == mem) { - lfree = pmem; - } - pmem->next = mem->next; - if (mem->next != MEM_SIZE_ALIGNED) { - ptr_to_mem(mem->next)->prev = mem_to_ptr(pmem); - } - } -} - -/** - * Zero the heap and initialize start, end and lowest-free - */ -void -mem_init(void) -{ - struct mem *mem; - - LWIP_ASSERT("Sanity check alignment", - (SIZEOF_STRUCT_MEM & (MEM_ALIGNMENT - 1)) == 0); - - /* align the heap */ - ram = (u8_t *)LWIP_MEM_ALIGN(LWIP_RAM_HEAP_POINTER); - /* initialize the start of the heap */ - mem = (struct mem *)(void *)ram; - mem->next = MEM_SIZE_ALIGNED; - mem->prev = 0; - mem->used = 0; - /* initialize the end of the heap */ - ram_end = ptr_to_mem(MEM_SIZE_ALIGNED); - ram_end->used = 1; - ram_end->next = MEM_SIZE_ALIGNED; - ram_end->prev = MEM_SIZE_ALIGNED; - MEM_SANITY(); - - /* initialize the lowest-free pointer to the start of the heap */ - lfree = (struct mem *)(void *)ram; - - MEM_STATS_AVAIL(avail, MEM_SIZE_ALIGNED); - - if (sys_mutex_new(&mem_mutex) != ERR_OK) { - LWIP_ASSERT("failed to create mem_mutex", 0); - } -} - -/* Check if a struct mem is correctly linked. - * If not, double-free is a possible reason. - */ -static int -mem_link_valid(struct mem *mem) -{ - struct mem *nmem, *pmem; - mem_size_t rmem_idx; - rmem_idx = mem_to_ptr(mem); - nmem = ptr_to_mem(mem->next); - pmem = ptr_to_mem(mem->prev); - if ((mem->next > MEM_SIZE_ALIGNED) || (mem->prev > MEM_SIZE_ALIGNED) || - ((mem->prev != rmem_idx) && (pmem->next != rmem_idx)) || - ((nmem != ram_end) && (nmem->prev != rmem_idx))) { - return 0; - } - return 1; -} - -#if MEM_SANITY_CHECK -static void -mem_sanity(void) -{ - struct mem *mem; - u8_t last_used; - - /* begin with first element here */ - mem = (struct mem *)ram; - LWIP_ASSERT("heap element used valid", (mem->used == 0) || (mem->used == 1)); - last_used = mem->used; - LWIP_ASSERT("heap element prev ptr valid", mem->prev == 0); - LWIP_ASSERT("heap element next ptr valid", mem->next <= MEM_SIZE_ALIGNED); - LWIP_ASSERT("heap element next ptr aligned", LWIP_MEM_ALIGN(ptr_to_mem(mem->next) == ptr_to_mem(mem->next))); - - /* check all elements before the end of the heap */ - for (mem = ptr_to_mem(mem->next); - ((u8_t *)mem > ram) && (mem < ram_end); - mem = ptr_to_mem(mem->next)) { - LWIP_ASSERT("heap element aligned", LWIP_MEM_ALIGN(mem) == mem); - LWIP_ASSERT("heap element prev ptr valid", mem->prev <= MEM_SIZE_ALIGNED); - LWIP_ASSERT("heap element next ptr valid", mem->next <= MEM_SIZE_ALIGNED); - LWIP_ASSERT("heap element prev ptr aligned", LWIP_MEM_ALIGN(ptr_to_mem(mem->prev) == ptr_to_mem(mem->prev))); - LWIP_ASSERT("heap element next ptr aligned", LWIP_MEM_ALIGN(ptr_to_mem(mem->next) == ptr_to_mem(mem->next))); - - if (last_used == 0) { - /* 2 unused elements in a row? */ - LWIP_ASSERT("heap element unused?", mem->used == 1); - } else { - LWIP_ASSERT("heap element unused member", (mem->used == 0) || (mem->used == 1)); - } - - LWIP_ASSERT("heap element link valid", mem_link_valid(mem)); - - /* used/unused altering */ - last_used = mem->used; - } - LWIP_ASSERT("heap end ptr sanity", mem == ptr_to_mem(MEM_SIZE_ALIGNED)); - LWIP_ASSERT("heap element used valid", mem->used == 1); - LWIP_ASSERT("heap element prev ptr valid", mem->prev == MEM_SIZE_ALIGNED); - LWIP_ASSERT("heap element next ptr valid", mem->next == MEM_SIZE_ALIGNED); -} -#endif /* MEM_SANITY_CHECK */ - -/** - * Put a struct mem back on the heap - * - * @param rmem is the data portion of a struct mem as returned by a previous - * call to mem_malloc() - */ -void -mem_free(void *rmem) -{ - struct mem *mem; - LWIP_MEM_FREE_DECL_PROTECT(); - - if (rmem == NULL) { - LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("mem_free(p == NULL) was called.\n")); - return; - } - if ((((mem_ptr_t)rmem) & (MEM_ALIGNMENT - 1)) != 0) { - LWIP_MEM_ILLEGAL_FREE("mem_free: sanity check alignment"); - LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("mem_free: sanity check alignment\n")); - /* protect mem stats from concurrent access */ - MEM_STATS_INC_LOCKED(illegal); - return; - } - - /* Get the corresponding struct mem: */ - /* cast through void* to get rid of alignment warnings */ - mem = (struct mem *)(void *)((u8_t *)rmem - (SIZEOF_STRUCT_MEM + MEM_SANITY_OFFSET)); - - if ((u8_t *)mem < ram || (u8_t *)rmem + MIN_SIZE_ALIGNED > (u8_t *)ram_end) { - LWIP_MEM_ILLEGAL_FREE("mem_free: illegal memory"); - LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("mem_free: illegal memory\n")); - /* protect mem stats from concurrent access */ - MEM_STATS_INC_LOCKED(illegal); - return; - } -#if MEM_OVERFLOW_CHECK - mem_overflow_check_element(mem); -#endif - /* protect the heap from concurrent access */ - LWIP_MEM_FREE_PROTECT(); - /* mem has to be in a used state */ - if (!mem->used) { - LWIP_MEM_ILLEGAL_FREE("mem_free: illegal memory: double free"); - LWIP_MEM_FREE_UNPROTECT(); - LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("mem_free: illegal memory: double free?\n")); - /* protect mem stats from concurrent access */ - MEM_STATS_INC_LOCKED(illegal); - return; - } - - if (!mem_link_valid(mem)) { - LWIP_MEM_ILLEGAL_FREE("mem_free: illegal memory: non-linked: double free"); - LWIP_MEM_FREE_UNPROTECT(); - LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("mem_free: illegal memory: non-linked: double free?\n")); - /* protect mem stats from concurrent access */ - MEM_STATS_INC_LOCKED(illegal); - return; - } - - /* mem is now unused. */ - mem->used = 0; - - if (mem < lfree) { - /* the newly freed struct is now the lowest */ - lfree = mem; - } - - MEM_STATS_DEC_USED(used, mem->next - (mem_size_t)(((u8_t *)mem - ram))); - - /* finally, see if prev or next are free also */ - plug_holes(mem); - MEM_SANITY(); -#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT - mem_free_count = 1; -#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ - LWIP_MEM_FREE_UNPROTECT(); -} - -/** - * Shrink memory returned by mem_malloc(). - * - * @param rmem pointer to memory allocated by mem_malloc the is to be shrinked - * @param new_size required size after shrinking (needs to be smaller than or - * equal to the previous size) - * @return for compatibility reasons: is always == rmem, at the moment - * or NULL if newsize is > old size, in which case rmem is NOT touched - * or freed! - */ -void * -mem_trim(void *rmem, mem_size_t new_size) -{ - mem_size_t size, newsize; - mem_size_t ptr, ptr2; - struct mem *mem, *mem2; - /* use the FREE_PROTECT here: it protects with sem OR SYS_ARCH_PROTECT */ - LWIP_MEM_FREE_DECL_PROTECT(); - - /* Expand the size of the allocated memory region so that we can - adjust for alignment. */ - newsize = (mem_size_t)LWIP_MEM_ALIGN_SIZE(new_size); - if (newsize < MIN_SIZE_ALIGNED) { - /* every data block must be at least MIN_SIZE_ALIGNED long */ - newsize = MIN_SIZE_ALIGNED; - } -#if MEM_OVERFLOW_CHECK - newsize += MEM_SANITY_REGION_BEFORE_ALIGNED + MEM_SANITY_REGION_AFTER_ALIGNED; -#endif - if ((newsize > MEM_SIZE_ALIGNED) || (newsize < new_size)) { - return NULL; - } - - LWIP_ASSERT("mem_trim: legal memory", (u8_t *)rmem >= (u8_t *)ram && - (u8_t *)rmem < (u8_t *)ram_end); - - if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) { - LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("mem_trim: illegal memory\n")); - /* protect mem stats from concurrent access */ - MEM_STATS_INC_LOCKED(illegal); - return rmem; - } - /* Get the corresponding struct mem ... */ - /* cast through void* to get rid of alignment warnings */ - mem = (struct mem *)(void *)((u8_t *)rmem - (SIZEOF_STRUCT_MEM + MEM_SANITY_OFFSET)); -#if MEM_OVERFLOW_CHECK - mem_overflow_check_element(mem); -#endif - /* ... and its offset pointer */ - ptr = mem_to_ptr(mem); - - size = (mem_size_t)((mem_size_t)(mem->next - ptr) - (SIZEOF_STRUCT_MEM + MEM_SANITY_OVERHEAD)); - LWIP_ASSERT("mem_trim can only shrink memory", newsize <= size); - if (newsize > size) { - /* not supported */ - return NULL; - } - if (newsize == size) { - /* No change in size, simply return */ - return rmem; - } - - /* protect the heap from concurrent access */ - LWIP_MEM_FREE_PROTECT(); - - mem2 = ptr_to_mem(mem->next); - if (mem2->used == 0) { - /* The next struct is unused, we can simply move it at little */ - mem_size_t next; - LWIP_ASSERT("invalid next ptr", mem->next != MEM_SIZE_ALIGNED); - /* remember the old next pointer */ - next = mem2->next; - /* create new struct mem which is moved directly after the shrinked mem */ - ptr2 = (mem_size_t)(ptr + SIZEOF_STRUCT_MEM + newsize); - if (lfree == mem2) { - lfree = ptr_to_mem(ptr2); - } - mem2 = ptr_to_mem(ptr2); - mem2->used = 0; - /* restore the next pointer */ - mem2->next = next; - /* link it back to mem */ - mem2->prev = ptr; - /* link mem to it */ - mem->next = ptr2; - /* last thing to restore linked list: as we have moved mem2, - * let 'mem2->next->prev' point to mem2 again. but only if mem2->next is not - * the end of the heap */ - if (mem2->next != MEM_SIZE_ALIGNED) { - ptr_to_mem(mem2->next)->prev = ptr2; - } - MEM_STATS_DEC_USED(used, (size - newsize)); - /* no need to plug holes, we've already done that */ - } else if (newsize + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED <= size) { - /* Next struct is used but there's room for another struct mem with - * at least MIN_SIZE_ALIGNED of data. - * Old size ('size') must be big enough to contain at least 'newsize' plus a struct mem - * ('SIZEOF_STRUCT_MEM') with some data ('MIN_SIZE_ALIGNED'). - * @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty - * region that couldn't hold data, but when mem->next gets freed, - * the 2 regions would be combined, resulting in more free memory */ - ptr2 = (mem_size_t)(ptr + SIZEOF_STRUCT_MEM + newsize); - LWIP_ASSERT("invalid next ptr", mem->next != MEM_SIZE_ALIGNED); - mem2 = ptr_to_mem(ptr2); - if (mem2 < lfree) { - lfree = mem2; - } - mem2->used = 0; - mem2->next = mem->next; - mem2->prev = ptr; - mem->next = ptr2; - if (mem2->next != MEM_SIZE_ALIGNED) { - ptr_to_mem(mem2->next)->prev = ptr2; - } - MEM_STATS_DEC_USED(used, (size - newsize)); - /* the original mem->next is used, so no need to plug holes! */ - } - /* else { - next struct mem is used but size between mem and mem2 is not big enough - to create another struct mem - -> don't do anyhting. - -> the remaining space stays unused since it is too small - } */ -#if MEM_OVERFLOW_CHECK - mem_overflow_init_element(mem, new_size); -#endif - MEM_SANITY(); -#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT - mem_free_count = 1; -#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ - LWIP_MEM_FREE_UNPROTECT(); - return rmem; -} - -/** - * Allocate a block of memory with a minimum of 'size' bytes. - * - * @param size_in is the minimum size of the requested block in bytes. - * @return pointer to allocated memory or NULL if no free memory was found. - * - * Note that the returned value will always be aligned (as defined by MEM_ALIGNMENT). - */ -void * -mem_malloc(mem_size_t size_in) -{ - mem_size_t ptr, ptr2, size; - struct mem *mem, *mem2; -#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT - u8_t local_mem_free_count = 0; -#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ - LWIP_MEM_ALLOC_DECL_PROTECT(); - - if (size_in == 0) { - return NULL; - } - - /* Expand the size of the allocated memory region so that we can - adjust for alignment. */ - size = (mem_size_t)LWIP_MEM_ALIGN_SIZE(size_in); - if (size < MIN_SIZE_ALIGNED) { - /* every data block must be at least MIN_SIZE_ALIGNED long */ - size = MIN_SIZE_ALIGNED; - } -#if MEM_OVERFLOW_CHECK - size += MEM_SANITY_REGION_BEFORE_ALIGNED + MEM_SANITY_REGION_AFTER_ALIGNED; -#endif - if ((size > MEM_SIZE_ALIGNED) || (size < size_in)) { - return NULL; - } - - /* protect the heap from concurrent access */ - sys_mutex_lock(&mem_mutex); - LWIP_MEM_ALLOC_PROTECT(); -#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT - /* run as long as a mem_free disturbed mem_malloc or mem_trim */ - do { - local_mem_free_count = 0; -#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ - - /* Scan through the heap searching for a free block that is big enough, - * beginning with the lowest free block. - */ - for (ptr = mem_to_ptr(lfree); ptr < MEM_SIZE_ALIGNED - size; - ptr = ptr_to_mem(ptr)->next) { - mem = ptr_to_mem(ptr); -#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT - mem_free_count = 0; - LWIP_MEM_ALLOC_UNPROTECT(); - /* allow mem_free or mem_trim to run */ - LWIP_MEM_ALLOC_PROTECT(); - if (mem_free_count != 0) { - /* If mem_free or mem_trim have run, we have to restart since they - could have altered our current struct mem. */ - local_mem_free_count = 1; - break; - } -#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ - - if ((!mem->used) && - (mem->next - (ptr + SIZEOF_STRUCT_MEM)) >= size) { - /* mem is not used and at least perfect fit is possible: - * mem->next - (ptr + SIZEOF_STRUCT_MEM) gives us the 'user data size' of mem */ - - if (mem->next - (ptr + SIZEOF_STRUCT_MEM) >= (size + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED)) { - /* (in addition to the above, we test if another struct mem (SIZEOF_STRUCT_MEM) containing - * at least MIN_SIZE_ALIGNED of data also fits in the 'user data space' of 'mem') - * -> split large block, create empty remainder, - * remainder must be large enough to contain MIN_SIZE_ALIGNED data: if - * mem->next - (ptr + (2*SIZEOF_STRUCT_MEM)) == size, - * struct mem would fit in but no data between mem2 and mem2->next - * @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty - * region that couldn't hold data, but when mem->next gets freed, - * the 2 regions would be combined, resulting in more free memory - */ - ptr2 = (mem_size_t)(ptr + SIZEOF_STRUCT_MEM + size); - LWIP_ASSERT("invalid next ptr",ptr2 != MEM_SIZE_ALIGNED); - /* create mem2 struct */ - mem2 = ptr_to_mem(ptr2); - mem2->used = 0; - mem2->next = mem->next; - mem2->prev = ptr; - /* and insert it between mem and mem->next */ - mem->next = ptr2; - mem->used = 1; - - if (mem2->next != MEM_SIZE_ALIGNED) { - ptr_to_mem(mem2->next)->prev = ptr2; - } - MEM_STATS_INC_USED(used, (size + SIZEOF_STRUCT_MEM)); - } else { - /* (a mem2 struct does no fit into the user data space of mem and mem->next will always - * be used at this point: if not we have 2 unused structs in a row, plug_holes should have - * take care of this). - * -> near fit or exact fit: do not split, no mem2 creation - * also can't move mem->next directly behind mem, since mem->next - * will always be used at this point! - */ - mem->used = 1; - MEM_STATS_INC_USED(used, mem->next - mem_to_ptr(mem)); - } -#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT -mem_malloc_adjust_lfree: -#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ - if (mem == lfree) { - struct mem *cur = lfree; - /* Find next free block after mem and update lowest free pointer */ - while (cur->used && cur != ram_end) { -#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT - mem_free_count = 0; - LWIP_MEM_ALLOC_UNPROTECT(); - /* prevent high interrupt latency... */ - LWIP_MEM_ALLOC_PROTECT(); - if (mem_free_count != 0) { - /* If mem_free or mem_trim have run, we have to restart since they - could have altered our current struct mem or lfree. */ - goto mem_malloc_adjust_lfree; - } -#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ - cur = ptr_to_mem(cur->next); - } - lfree = cur; - LWIP_ASSERT("mem_malloc: !lfree->used", ((lfree == ram_end) || (!lfree->used))); - } - LWIP_MEM_ALLOC_UNPROTECT(); - sys_mutex_unlock(&mem_mutex); - LWIP_ASSERT("mem_malloc: allocated memory not above ram_end.", - (mem_ptr_t)mem + SIZEOF_STRUCT_MEM + size <= (mem_ptr_t)ram_end); - LWIP_ASSERT("mem_malloc: allocated memory properly aligned.", - ((mem_ptr_t)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0); - LWIP_ASSERT("mem_malloc: sanity check alignment", - (((mem_ptr_t)mem) & (MEM_ALIGNMENT - 1)) == 0); - -#if MEM_OVERFLOW_CHECK - mem_overflow_init_element(mem, size_in); -#endif - MEM_SANITY(); - return (u8_t *)mem + SIZEOF_STRUCT_MEM + MEM_SANITY_OFFSET; - } - } -#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT - /* if we got interrupted by a mem_free, try again */ - } while (local_mem_free_count != 0); -#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ - MEM_STATS_INC(err); - LWIP_MEM_ALLOC_UNPROTECT(); - sys_mutex_unlock(&mem_mutex); - LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("mem_malloc: could not allocate %"S16_F" bytes\n", (s16_t)size)); - return NULL; -} - -#endif /* MEM_USE_POOLS */ - -#if MEM_LIBC_MALLOC && (!LWIP_STATS || !MEM_STATS) -void * -mem_calloc(mem_size_t count, mem_size_t size) -{ - return mem_clib_calloc(count, size); -} - -#else /* MEM_LIBC_MALLOC && (!LWIP_STATS || !MEM_STATS) */ -/** - * Contiguously allocates enough space for count objects that are size bytes - * of memory each and returns a pointer to the allocated memory. - * - * The allocated memory is filled with bytes of value zero. - * - * @param count number of objects to allocate - * @param size size of the objects to allocate - * @return pointer to allocated memory / NULL pointer if there is an error - */ -void * -mem_calloc(mem_size_t count, mem_size_t size) -{ - void *p; - size_t alloc_size = (size_t)count * (size_t)size; - - if ((size_t)(mem_size_t)alloc_size != alloc_size) { - LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("mem_calloc: could not allocate %"SZT_F" bytes\n", alloc_size)); - return NULL; - } - - /* allocate 'count' objects of size 'size' */ - p = mem_malloc((mem_size_t)alloc_size); - if (p) { - /* zero the memory */ - memset(p, 0, alloc_size); - } - return p; -} -#endif /* MEM_LIBC_MALLOC && (!LWIP_STATS || !MEM_STATS) */ diff --git a/third-party/lwip-2.1.2/core/memp.c b/third-party/lwip-2.1.2/core/memp.c deleted file mode 100644 index 352ce5a5..00000000 --- a/third-party/lwip-2.1.2/core/memp.c +++ /dev/null @@ -1,447 +0,0 @@ -/** - * @file - * Dynamic pool memory manager - * - * lwIP has dedicated pools for many structures (netconn, protocol control blocks, - * packet buffers, ...). All these pools are managed here. - * - * @defgroup mempool Memory pools - * @ingroup infrastructure - * Custom memory pools - - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#include "lwip/opt.h" - -#include "lwip/memp.h" -#include "lwip/sys.h" -#include "lwip/stats.h" - -#include - -/* Make sure we include everything we need for size calculation required by memp_std.h */ -#include "lwip/pbuf.h" -#include "lwip/raw.h" -#include "lwip/udp.h" -#include "lwip/tcp.h" -#include "lwip/priv/tcp_priv.h" -#include "lwip/altcp.h" -#include "lwip/ip4_frag.h" -#include "lwip/netbuf.h" -#include "lwip/api.h" -#include "lwip/priv/tcpip_priv.h" -#include "lwip/priv/api_msg.h" -#include "lwip/priv/sockets_priv.h" -#include "lwip/etharp.h" -#include "lwip/igmp.h" -#include "lwip/timeouts.h" -/* needed by default MEMP_NUM_SYS_TIMEOUT */ -#include "netif/ppp/ppp_opts.h" -#include "lwip/netdb.h" -#include "lwip/dns.h" -#include "lwip/priv/nd6_priv.h" -#include "lwip/ip6_frag.h" -#include "lwip/mld6.h" - -#define LWIP_MEMPOOL(name,num,size,desc) LWIP_MEMPOOL_DECLARE(name,num,size,desc) -#include "lwip/priv/memp_std.h" - -const struct memp_desc *const memp_pools[MEMP_MAX] = { -#define LWIP_MEMPOOL(name,num,size,desc) &memp_ ## name, -#include "lwip/priv/memp_std.h" -}; - -#ifdef LWIP_HOOK_FILENAME -#include LWIP_HOOK_FILENAME -#endif - -#if MEMP_MEM_MALLOC && MEMP_OVERFLOW_CHECK >= 2 -#undef MEMP_OVERFLOW_CHECK -/* MEMP_OVERFLOW_CHECK >= 2 does not work with MEMP_MEM_MALLOC, use 1 instead */ -#define MEMP_OVERFLOW_CHECK 1 -#endif - -#if MEMP_SANITY_CHECK && !MEMP_MEM_MALLOC -/** - * Check that memp-lists don't form a circle, using "Floyd's cycle-finding algorithm". - */ -static int -memp_sanity(const struct memp_desc *desc) -{ - struct memp *t, *h; - - t = *desc->tab; - if (t != NULL) { - for (h = t->next; (t != NULL) && (h != NULL); t = t->next, - h = ((h->next != NULL) ? h->next->next : NULL)) { - if (t == h) { - return 0; - } - } - } - - return 1; -} -#endif /* MEMP_SANITY_CHECK && !MEMP_MEM_MALLOC */ - -#if MEMP_OVERFLOW_CHECK -/** - * Check if a memp element was victim of an overflow or underflow - * (e.g. the restricted area after/before it has been altered) - * - * @param p the memp element to check - * @param desc the pool p comes from - */ -static void -memp_overflow_check_element(struct memp *p, const struct memp_desc *desc) -{ - mem_overflow_check_raw((u8_t *)p + MEMP_SIZE, desc->size, "pool ", desc->desc); -} - -/** - * Initialize the restricted area of on memp element. - */ -static void -memp_overflow_init_element(struct memp *p, const struct memp_desc *desc) -{ - mem_overflow_init_raw((u8_t *)p + MEMP_SIZE, desc->size); -} - -#if MEMP_OVERFLOW_CHECK >= 2 -/** - * Do an overflow check for all elements in every pool. - * - * @see memp_overflow_check_element for a description of the check - */ -static void -memp_overflow_check_all(void) -{ - u16_t i, j; - struct memp *p; - SYS_ARCH_DECL_PROTECT(old_level); - SYS_ARCH_PROTECT(old_level); - - for (i = 0; i < MEMP_MAX; ++i) { - p = (struct memp *)LWIP_MEM_ALIGN(memp_pools[i]->base); - for (j = 0; j < memp_pools[i]->num; ++j) { - memp_overflow_check_element(p, memp_pools[i]); - p = LWIP_ALIGNMENT_CAST(struct memp *, ((u8_t *)p + MEMP_SIZE + memp_pools[i]->size + MEM_SANITY_REGION_AFTER_ALIGNED)); - } - } - SYS_ARCH_UNPROTECT(old_level); -} -#endif /* MEMP_OVERFLOW_CHECK >= 2 */ -#endif /* MEMP_OVERFLOW_CHECK */ - -/** - * Initialize custom memory pool. - * Related functions: memp_malloc_pool, memp_free_pool - * - * @param desc pool to initialize - */ -void -memp_init_pool(const struct memp_desc *desc) -{ -#if MEMP_MEM_MALLOC - LWIP_UNUSED_ARG(desc); -#else - int i; - struct memp *memp; - - *desc->tab = NULL; - memp = (struct memp *)LWIP_MEM_ALIGN(desc->base); -#if MEMP_MEM_INIT - /* force memset on pool memory */ - memset(memp, 0, (size_t)desc->num * (MEMP_SIZE + desc->size -#if MEMP_OVERFLOW_CHECK - + MEM_SANITY_REGION_AFTER_ALIGNED -#endif - )); -#endif - /* create a linked list of memp elements */ - for (i = 0; i < desc->num; ++i) { - memp->next = *desc->tab; - *desc->tab = memp; -#if MEMP_OVERFLOW_CHECK - memp_overflow_init_element(memp, desc); -#endif /* MEMP_OVERFLOW_CHECK */ - /* cast through void* to get rid of alignment warnings */ - memp = (struct memp *)(void *)((u8_t *)memp + MEMP_SIZE + desc->size -#if MEMP_OVERFLOW_CHECK - + MEM_SANITY_REGION_AFTER_ALIGNED -#endif - ); - } -#if MEMP_STATS - desc->stats->avail = desc->num; -#endif /* MEMP_STATS */ -#endif /* !MEMP_MEM_MALLOC */ - -#if MEMP_STATS && (defined(LWIP_DEBUG) || LWIP_STATS_DISPLAY) - desc->stats->name = desc->desc; -#endif /* MEMP_STATS && (defined(LWIP_DEBUG) || LWIP_STATS_DISPLAY) */ -} - -/** - * Initializes lwIP built-in pools. - * Related functions: memp_malloc, memp_free - * - * Carves out memp_memory into linked lists for each pool-type. - */ -void -memp_init(void) -{ - u16_t i; - - /* for every pool: */ - for (i = 0; i < LWIP_ARRAYSIZE(memp_pools); i++) { - memp_init_pool(memp_pools[i]); - -#if LWIP_STATS && MEMP_STATS - lwip_stats.memp[i] = memp_pools[i]->stats; -#endif - } - -#if MEMP_OVERFLOW_CHECK >= 2 - /* check everything a first time to see if it worked */ - memp_overflow_check_all(); -#endif /* MEMP_OVERFLOW_CHECK >= 2 */ -} - -static void * -#if !MEMP_OVERFLOW_CHECK -do_memp_malloc_pool(const struct memp_desc *desc) -#else -do_memp_malloc_pool_fn(const struct memp_desc *desc, const char *file, const int line) -#endif -{ - struct memp *memp; - SYS_ARCH_DECL_PROTECT(old_level); - -#if MEMP_MEM_MALLOC - memp = (struct memp *)mem_malloc(MEMP_SIZE + MEMP_ALIGN_SIZE(desc->size)); - SYS_ARCH_PROTECT(old_level); -#else /* MEMP_MEM_MALLOC */ - SYS_ARCH_PROTECT(old_level); - - memp = *desc->tab; -#endif /* MEMP_MEM_MALLOC */ - - if (memp != NULL) { -#if !MEMP_MEM_MALLOC -#if MEMP_OVERFLOW_CHECK == 1 - memp_overflow_check_element(memp, desc); -#endif /* MEMP_OVERFLOW_CHECK */ - - *desc->tab = memp->next; -#if MEMP_OVERFLOW_CHECK - memp->next = NULL; -#endif /* MEMP_OVERFLOW_CHECK */ -#endif /* !MEMP_MEM_MALLOC */ -#if MEMP_OVERFLOW_CHECK - memp->file = file; - memp->line = line; -#if MEMP_MEM_MALLOC - memp_overflow_init_element(memp, desc); -#endif /* MEMP_MEM_MALLOC */ -#endif /* MEMP_OVERFLOW_CHECK */ - LWIP_ASSERT("memp_malloc: memp properly aligned", - ((mem_ptr_t)memp % MEM_ALIGNMENT) == 0); -#if MEMP_STATS - desc->stats->used++; - if (desc->stats->used > desc->stats->max) { - desc->stats->max = desc->stats->used; - } -#endif - SYS_ARCH_UNPROTECT(old_level); - /* cast through u8_t* to get rid of alignment warnings */ - return ((u8_t *)memp + MEMP_SIZE); - } else { -#if MEMP_STATS - desc->stats->err++; -#endif - SYS_ARCH_UNPROTECT(old_level); - LWIP_DEBUGF(MEMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("memp_malloc: out of memory in pool %s\n", desc->desc)); - } - - return NULL; -} - -/** - * Get an element from a custom pool. - * - * @param desc the pool to get an element from - * - * @return a pointer to the allocated memory or a NULL pointer on error - */ -void * -#if !MEMP_OVERFLOW_CHECK -memp_malloc_pool(const struct memp_desc *desc) -#else -memp_malloc_pool_fn(const struct memp_desc *desc, const char *file, const int line) -#endif -{ - LWIP_ASSERT("invalid pool desc", desc != NULL); - if (desc == NULL) { - return NULL; - } - -#if !MEMP_OVERFLOW_CHECK - return do_memp_malloc_pool(desc); -#else - return do_memp_malloc_pool_fn(desc, file, line); -#endif -} - -/** - * Get an element from a specific pool. - * - * @param type the pool to get an element from - * - * @return a pointer to the allocated memory or a NULL pointer on error - */ -void * -#if !MEMP_OVERFLOW_CHECK -memp_malloc(memp_t type) -#else -memp_malloc_fn(memp_t type, const char *file, const int line) -#endif -{ - void *memp; - LWIP_ERROR("memp_malloc: type < MEMP_MAX", (type < MEMP_MAX), return NULL;); - -#if MEMP_OVERFLOW_CHECK >= 2 - memp_overflow_check_all(); -#endif /* MEMP_OVERFLOW_CHECK >= 2 */ - -#if !MEMP_OVERFLOW_CHECK - memp = do_memp_malloc_pool(memp_pools[type]); -#else - memp = do_memp_malloc_pool_fn(memp_pools[type], file, line); -#endif - - return memp; -} - -static void -do_memp_free_pool(const struct memp_desc *desc, void *mem) -{ - struct memp *memp; - SYS_ARCH_DECL_PROTECT(old_level); - - LWIP_ASSERT("memp_free: mem properly aligned", - ((mem_ptr_t)mem % MEM_ALIGNMENT) == 0); - - /* cast through void* to get rid of alignment warnings */ - memp = (struct memp *)(void *)((u8_t *)mem - MEMP_SIZE); - - SYS_ARCH_PROTECT(old_level); - -#if MEMP_OVERFLOW_CHECK == 1 - memp_overflow_check_element(memp, desc); -#endif /* MEMP_OVERFLOW_CHECK */ - -#if MEMP_STATS - desc->stats->used--; -#endif - -#if MEMP_MEM_MALLOC - LWIP_UNUSED_ARG(desc); - SYS_ARCH_UNPROTECT(old_level); - mem_free(memp); -#else /* MEMP_MEM_MALLOC */ - memp->next = *desc->tab; - *desc->tab = memp; - -#if MEMP_SANITY_CHECK - LWIP_ASSERT("memp sanity", memp_sanity(desc)); -#endif /* MEMP_SANITY_CHECK */ - - SYS_ARCH_UNPROTECT(old_level); -#endif /* !MEMP_MEM_MALLOC */ -} - -/** - * Put a custom pool element back into its pool. - * - * @param desc the pool where to put mem - * @param mem the memp element to free - */ -void -memp_free_pool(const struct memp_desc *desc, void *mem) -{ - LWIP_ASSERT("invalid pool desc", desc != NULL); - if ((desc == NULL) || (mem == NULL)) { - return; - } - - do_memp_free_pool(desc, mem); -} - -/** - * Put an element back into its pool. - * - * @param type the pool where to put mem - * @param mem the memp element to free - */ -void -memp_free(memp_t type, void *mem) -{ -#ifdef LWIP_HOOK_MEMP_AVAILABLE - struct memp *old_first; -#endif - - LWIP_ERROR("memp_free: type < MEMP_MAX", (type < MEMP_MAX), return;); - - if (mem == NULL) { - return; - } - -#if MEMP_OVERFLOW_CHECK >= 2 - memp_overflow_check_all(); -#endif /* MEMP_OVERFLOW_CHECK >= 2 */ - -#ifdef LWIP_HOOK_MEMP_AVAILABLE - old_first = *memp_pools[type]->tab; -#endif - - do_memp_free_pool(memp_pools[type], mem); - -#ifdef LWIP_HOOK_MEMP_AVAILABLE - if (old_first == NULL) { - LWIP_HOOK_MEMP_AVAILABLE(type); - } -#endif -} diff --git a/third-party/lwip-2.1.2/core/netif.c b/third-party/lwip-2.1.2/core/netif.c deleted file mode 100644 index bed14400..00000000 --- a/third-party/lwip-2.1.2/core/netif.c +++ /dev/null @@ -1,1803 +0,0 @@ -/** - * @file - * lwIP network interface abstraction - * - * @defgroup netif Network interface (NETIF) - * @ingroup callbackstyle_api - * - * @defgroup netif_ip4 IPv4 address handling - * @ingroup netif - * - * @defgroup netif_ip6 IPv6 address handling - * @ingroup netif - * - * @defgroup netif_cd Client data handling - * Store data (void*) on a netif for application usage. - * @see @ref LWIP_NUM_NETIF_CLIENT_DATA - * @ingroup netif - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - */ - -#include "lwip/opt.h" - -#include /* memset */ -#include /* atoi */ - -#include "lwip/def.h" -#include "lwip/ip_addr.h" -#include "lwip/ip6_addr.h" -#include "lwip/netif.h" -#include "lwip/priv/tcp_priv.h" -#include "lwip/udp.h" -#include "lwip/priv/raw_priv.h" -#include "lwip/snmp.h" -#include "lwip/igmp.h" -#include "lwip/etharp.h" -#include "lwip/stats.h" -#include "lwip/sys.h" -#include "lwip/ip.h" -#if ENABLE_LOOPBACK -#if LWIP_NETIF_LOOPBACK_MULTITHREADING -#include "lwip/tcpip.h" -#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */ -#endif /* ENABLE_LOOPBACK */ - -#include "netif/ethernet.h" - -#if LWIP_AUTOIP -#include "lwip/autoip.h" -#endif /* LWIP_AUTOIP */ -#if LWIP_DHCP -#include "lwip/dhcp.h" -#endif /* LWIP_DHCP */ -#if LWIP_IPV6_DHCP6 -#include "lwip/dhcp6.h" -#endif /* LWIP_IPV6_DHCP6 */ -#if LWIP_IPV6_MLD -#include "lwip/mld6.h" -#endif /* LWIP_IPV6_MLD */ -#if LWIP_IPV6 -#include "lwip/nd6.h" -#endif - -#if LWIP_NETIF_STATUS_CALLBACK -#define NETIF_STATUS_CALLBACK(n) do{ if (n->status_callback) { (n->status_callback)(n); }}while(0) -#else -#define NETIF_STATUS_CALLBACK(n) -#endif /* LWIP_NETIF_STATUS_CALLBACK */ - -#if LWIP_NETIF_LINK_CALLBACK -#define NETIF_LINK_CALLBACK(n) do{ if (n->link_callback) { (n->link_callback)(n); }}while(0) -#else -#define NETIF_LINK_CALLBACK(n) -#endif /* LWIP_NETIF_LINK_CALLBACK */ - -#if LWIP_NETIF_EXT_STATUS_CALLBACK -static netif_ext_callback_t *ext_callback; -#endif - -#if !LWIP_SINGLE_NETIF -struct netif *netif_list; -#endif /* !LWIP_SINGLE_NETIF */ -struct netif *netif_default; - -#define netif_index_to_num(index) ((index) - 1) -static u8_t netif_num; - -#if LWIP_NUM_NETIF_CLIENT_DATA > 0 -static u8_t netif_client_id; -#endif - -#define NETIF_REPORT_TYPE_IPV4 0x01 -#define NETIF_REPORT_TYPE_IPV6 0x02 -static void netif_issue_reports(struct netif *netif, u8_t report_type); - -#if LWIP_IPV6 -static err_t netif_null_output_ip6(struct netif *netif, struct pbuf *p, const ip6_addr_t *ipaddr); -#endif /* LWIP_IPV6 */ -#if LWIP_IPV4 -static err_t netif_null_output_ip4(struct netif *netif, struct pbuf *p, const ip4_addr_t *ipaddr); -#endif /* LWIP_IPV4 */ - -#if LWIP_HAVE_LOOPIF -#if LWIP_IPV4 -static err_t netif_loop_output_ipv4(struct netif *netif, struct pbuf *p, const ip4_addr_t *addr); -#endif -#if LWIP_IPV6 -static err_t netif_loop_output_ipv6(struct netif *netif, struct pbuf *p, const ip6_addr_t *addr); -#endif - - -static struct netif loop_netif; - -/** - * Initialize a lwip network interface structure for a loopback interface - * - * @param netif the lwip network interface structure for this loopif - * @return ERR_OK if the loopif is initialized - * ERR_MEM if private data couldn't be allocated - */ -static err_t -netif_loopif_init(struct netif *netif) -{ - LWIP_ASSERT("netif_loopif_init: invalid netif", netif != NULL); - - /* initialize the snmp variables and counters inside the struct netif - * ifSpeed: no assumption can be made! - */ - MIB2_INIT_NETIF(netif, snmp_ifType_softwareLoopback, 0); - - netif->name[0] = 'l'; - netif->name[1] = 'o'; -#if LWIP_IPV4 - netif->output = netif_loop_output_ipv4; -#endif -#if LWIP_IPV6 - netif->output_ip6 = netif_loop_output_ipv6; -#endif -#if LWIP_LOOPIF_MULTICAST - netif_set_flags(netif, NETIF_FLAG_IGMP); -#endif - NETIF_SET_CHECKSUM_CTRL(netif, NETIF_CHECKSUM_DISABLE_ALL); - return ERR_OK; -} -#endif /* LWIP_HAVE_LOOPIF */ - -void -netif_init(void) -{ -#if LWIP_HAVE_LOOPIF -#if LWIP_IPV4 -#define LOOPIF_ADDRINIT &loop_ipaddr, &loop_netmask, &loop_gw, - ip4_addr_t loop_ipaddr, loop_netmask, loop_gw; - IP4_ADDR(&loop_gw, 127, 0, 0, 1); - IP4_ADDR(&loop_ipaddr, 127, 0, 0, 1); - IP4_ADDR(&loop_netmask, 255, 0, 0, 0); -#else /* LWIP_IPV4 */ -#define LOOPIF_ADDRINIT -#endif /* LWIP_IPV4 */ - -#if NO_SYS - netif_add(&loop_netif, LOOPIF_ADDRINIT NULL, netif_loopif_init, ip_input); -#else /* NO_SYS */ - netif_add(&loop_netif, LOOPIF_ADDRINIT NULL, netif_loopif_init, tcpip_input); -#endif /* NO_SYS */ - -#if LWIP_IPV6 - IP_ADDR6_HOST(loop_netif.ip6_addr, 0, 0, 0, 0x00000001UL); - loop_netif.ip6_addr_state[0] = IP6_ADDR_VALID; -#endif /* LWIP_IPV6 */ - - netif_set_link_up(&loop_netif); - netif_set_up(&loop_netif); - -#endif /* LWIP_HAVE_LOOPIF */ -} - -/** - * @ingroup lwip_nosys - * Forwards a received packet for input processing with - * ethernet_input() or ip_input() depending on netif flags. - * Don't call directly, pass to netif_add() and call - * netif->input(). - * Only works if the netif driver correctly sets - * NETIF_FLAG_ETHARP and/or NETIF_FLAG_ETHERNET flag! - */ -err_t -netif_input(struct pbuf *p, struct netif *inp) -{ - LWIP_ASSERT_CORE_LOCKED(); - - LWIP_ASSERT("netif_input: invalid pbuf", p != NULL); - LWIP_ASSERT("netif_input: invalid netif", inp != NULL); - -#if LWIP_ETHERNET - if (inp->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) { - return ethernet_input(p, inp); - } else -#endif /* LWIP_ETHERNET */ - return ip_input(p, inp); -} - -/** - * @ingroup netif - * Add a network interface to the list of lwIP netifs. - * - * Same as @ref netif_add but without IPv4 addresses - */ -struct netif * -netif_add_noaddr(struct netif *netif, void *state, netif_init_fn init, netif_input_fn input) -{ - return netif_add(netif, -#if LWIP_IPV4 - NULL, NULL, NULL, -#endif /* LWIP_IPV4*/ - state, init, input); -} - -/** - * @ingroup netif - * Add a network interface to the list of lwIP netifs. - * - * @param netif a pre-allocated netif structure - * @param ipaddr IP address for the new netif - * @param netmask network mask for the new netif - * @param gw default gateway IP address for the new netif - * @param state opaque data passed to the new netif - * @param init callback function that initializes the interface - * @param input callback function that is called to pass - * ingress packets up in the protocol layer stack.\n - * It is recommended to use a function that passes the input directly - * to the stack (netif_input(), NO_SYS=1 mode) or via sending a - * message to TCPIP thread (tcpip_input(), NO_SYS=0 mode).\n - * These functions use netif flags NETIF_FLAG_ETHARP and NETIF_FLAG_ETHERNET - * to decide whether to forward to ethernet_input() or ip_input(). - * In other words, the functions only work when the netif - * driver is implemented correctly!\n - * Most members of struct netif should be be initialized by the - * netif init function = netif driver (init parameter of this function).\n - * IPv6: Don't forget to call netif_create_ip6_linklocal_address() after - * setting the MAC address in struct netif.hwaddr - * (IPv6 requires a link-local address). - * - * @return netif, or NULL if failed. - */ -struct netif * -netif_add(struct netif *netif, -#if LWIP_IPV4 - const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw, -#endif /* LWIP_IPV4 */ - void *state, netif_init_fn init, netif_input_fn input) -{ -#if LWIP_IPV6 - s8_t i; -#endif - - LWIP_ASSERT_CORE_LOCKED(); - -#if LWIP_SINGLE_NETIF - if (netif_default != NULL) { - LWIP_ASSERT("single netif already set", 0); - return NULL; - } -#endif - - LWIP_ERROR("netif_add: invalid netif", netif != NULL, return NULL); - LWIP_ERROR("netif_add: No init function given", init != NULL, return NULL); - -#if LWIP_IPV4 - if (ipaddr == NULL) { - ipaddr = ip_2_ip4(IP4_ADDR_ANY); - } - if (netmask == NULL) { - netmask = ip_2_ip4(IP4_ADDR_ANY); - } - if (gw == NULL) { - gw = ip_2_ip4(IP4_ADDR_ANY); - } - - /* reset new interface configuration state */ - ip_addr_set_zero_ip4(&netif->ip_addr); - ip_addr_set_zero_ip4(&netif->netmask); - ip_addr_set_zero_ip4(&netif->gw); - netif->output = netif_null_output_ip4; -#endif /* LWIP_IPV4 */ -#if LWIP_IPV6 - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - ip_addr_set_zero_ip6(&netif->ip6_addr[i]); - netif->ip6_addr_state[i] = IP6_ADDR_INVALID; -#if LWIP_IPV6_ADDRESS_LIFETIMES - netif->ip6_addr_valid_life[i] = IP6_ADDR_LIFE_STATIC; - netif->ip6_addr_pref_life[i] = IP6_ADDR_LIFE_STATIC; -#endif /* LWIP_IPV6_ADDRESS_LIFETIMES */ - } - netif->output_ip6 = netif_null_output_ip6; -#endif /* LWIP_IPV6 */ - NETIF_SET_CHECKSUM_CTRL(netif, NETIF_CHECKSUM_ENABLE_ALL); - netif->mtu = 0; - netif->flags = 0; -#ifdef netif_get_client_data - memset(netif->client_data, 0, sizeof(netif->client_data)); -#endif /* LWIP_NUM_NETIF_CLIENT_DATA */ -#if LWIP_IPV6 -#if LWIP_IPV6_AUTOCONFIG - /* IPv6 address autoconfiguration not enabled by default */ - netif->ip6_autoconfig_enabled = 0; -#endif /* LWIP_IPV6_AUTOCONFIG */ - nd6_restart_netif(netif); -#endif /* LWIP_IPV6 */ -#if LWIP_NETIF_STATUS_CALLBACK - netif->status_callback = NULL; -#endif /* LWIP_NETIF_STATUS_CALLBACK */ -#if LWIP_NETIF_LINK_CALLBACK - netif->link_callback = NULL; -#endif /* LWIP_NETIF_LINK_CALLBACK */ -#if LWIP_IGMP - netif->igmp_mac_filter = NULL; -#endif /* LWIP_IGMP */ -#if LWIP_IPV6 && LWIP_IPV6_MLD - netif->mld_mac_filter = NULL; -#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ -#if ENABLE_LOOPBACK - netif->loop_first = NULL; - netif->loop_last = NULL; -#endif /* ENABLE_LOOPBACK */ - - /* remember netif specific state information data */ - netif->state = state; - netif->num = netif_num; - netif->input = input; - - NETIF_RESET_HINTS(netif); -#if ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS - netif->loop_cnt_current = 0; -#endif /* ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS */ - -#if LWIP_IPV4 - netif_set_addr(netif, ipaddr, netmask, gw); -#endif /* LWIP_IPV4 */ - - /* call user specified initialization function for netif */ - if (init(netif) != ERR_OK) { - return NULL; - } -#if LWIP_IPV6 && LWIP_ND6_ALLOW_RA_UPDATES - /* Initialize the MTU for IPv6 to the one set by the netif driver. - This can be updated later by RA. */ - netif->mtu6 = netif->mtu; -#endif /* LWIP_IPV6 && LWIP_ND6_ALLOW_RA_UPDATES */ - -#if !LWIP_SINGLE_NETIF - /* Assign a unique netif number in the range [0..254], so that (num+1) can - serve as an interface index that fits in a u8_t. - We assume that the new netif has not yet been added to the list here. - This algorithm is O(n^2), but that should be OK for lwIP. - */ - { - struct netif *netif2; - int num_netifs; - do { - if (netif->num == 255) { - netif->num = 0; - } - num_netifs = 0; - for (netif2 = netif_list; netif2 != NULL; netif2 = netif2->next) { - LWIP_ASSERT("netif already added", netif2 != netif); - num_netifs++; - LWIP_ASSERT("too many netifs, max. supported number is 255", num_netifs <= 255); - if (netif2->num == netif->num) { - netif->num++; - break; - } - } - } while (netif2 != NULL); - } - if (netif->num == 254) { - netif_num = 0; - } else { - netif_num = (u8_t)(netif->num + 1); - } - - /* add this netif to the list */ - netif->next = netif_list; - netif_list = netif; -#endif /* "LWIP_SINGLE_NETIF */ - mib2_netif_added(netif); - -#if LWIP_IGMP - /* start IGMP processing */ - if (netif->flags & NETIF_FLAG_IGMP) { - igmp_start(netif); - } -#endif /* LWIP_IGMP */ - - LWIP_DEBUGF(NETIF_DEBUG, ("netif: added interface %c%c IP", - netif->name[0], netif->name[1])); -#if LWIP_IPV4 - LWIP_DEBUGF(NETIF_DEBUG, (" addr ")); - ip4_addr_debug_print(NETIF_DEBUG, ipaddr); - LWIP_DEBUGF(NETIF_DEBUG, (" netmask ")); - ip4_addr_debug_print(NETIF_DEBUG, netmask); - LWIP_DEBUGF(NETIF_DEBUG, (" gw ")); - ip4_addr_debug_print(NETIF_DEBUG, gw); -#endif /* LWIP_IPV4 */ - LWIP_DEBUGF(NETIF_DEBUG, ("\n")); - - netif_invoke_ext_callback(netif, LWIP_NSC_NETIF_ADDED, NULL); - - return netif; -} - -static void -netif_do_ip_addr_changed(const ip_addr_t *old_addr, const ip_addr_t *new_addr) -{ -#if LWIP_TCP - tcp_netif_ip_addr_changed(old_addr, new_addr); -#endif /* LWIP_TCP */ -#if LWIP_UDP - udp_netif_ip_addr_changed(old_addr, new_addr); -#endif /* LWIP_UDP */ -#if LWIP_RAW - raw_netif_ip_addr_changed(old_addr, new_addr); -#endif /* LWIP_RAW */ -} - -#if LWIP_IPV4 -static int -netif_do_set_ipaddr(struct netif *netif, const ip4_addr_t *ipaddr, ip_addr_t *old_addr) -{ - LWIP_ASSERT("invalid pointer", ipaddr != NULL); - LWIP_ASSERT("invalid pointer", old_addr != NULL); - - /* address is actually being changed? */ - if (ip4_addr_cmp(ipaddr, netif_ip4_addr(netif)) == 0) { - ip_addr_t new_addr; - *ip_2_ip4(&new_addr) = *ipaddr; - IP_SET_TYPE_VAL(new_addr, IPADDR_TYPE_V4); - - ip_addr_copy(*old_addr, *netif_ip_addr4(netif)); - - LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: netif address being changed\n")); - - - - netif_do_ip_addr_changed(old_addr, &new_addr); - - mib2_remove_ip4(netif); - mib2_remove_route_ip4(0, netif); - /* set new IP address to netif */ - ip4_addr_set(ip_2_ip4(&netif->ip_addr), ipaddr); - IP_SET_TYPE_VAL(netif->ip_addr, IPADDR_TYPE_V4); - mib2_add_ip4(netif); - mib2_add_route_ip4(0, netif); - - netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV4); - LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE, ("netif_do_set_ipaddr: ip of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - netif->name[0], netif->name[1], - ip4_addr1_16(netif_ip4_addr(netif)), - ip4_addr2_16(netif_ip4_addr(netif)), - ip4_addr3_16(netif_ip4_addr(netif)), - ip4_addr4_16(netif_ip4_addr(netif)))); - NETIF_STATUS_CALLBACK(netif); - return 1; /* address changed */ - } - return 0; /* address unchanged */ -} - -/** - * @ingroup netif_ip4 - * Change the IP address of a network interface - * - * @param netif the network interface to change - * @param ipaddr the new IP address - * - * @note call netif_set_addr() if you also want to change netmask and - * default gateway - */ -void -netif_set_ipaddr(struct netif *netif, const ip4_addr_t *ipaddr) -{ - ip_addr_t old_addr; - - LWIP_ERROR("netif_set_ipaddr: invalid netif", netif != NULL, return); - - /* Don't propagate NULL pointer (IPv4 ANY) to subsequent functions */ - if (ipaddr == NULL) { - ipaddr = IP4_ADDR_ANY4; - } - - LWIP_ASSERT_CORE_LOCKED(); - - if (netif_do_set_ipaddr(netif, ipaddr, &old_addr)) { -#if LWIP_NETIF_EXT_STATUS_CALLBACK - netif_ext_callback_args_t args; - args.ipv4_changed.old_address = &old_addr; - netif_invoke_ext_callback(netif, LWIP_NSC_IPV4_ADDRESS_CHANGED, &args); -#endif - } -} - -static int -netif_do_set_netmask(struct netif *netif, const ip4_addr_t *netmask, ip_addr_t *old_nm) -{ - /* address is actually being changed? */ - if (ip4_addr_cmp(netmask, netif_ip4_netmask(netif)) == 0) { -#if LWIP_NETIF_EXT_STATUS_CALLBACK - LWIP_ASSERT("invalid pointer", old_nm != NULL); - ip_addr_copy(*old_nm, *netif_ip_netmask4(netif)); -#else - LWIP_UNUSED_ARG(old_nm); -#endif - mib2_remove_route_ip4(0, netif); - /* set new netmask to netif */ - ip4_addr_set(ip_2_ip4(&netif->netmask), netmask); - IP_SET_TYPE_VAL(netif->netmask, IPADDR_TYPE_V4); - mib2_add_route_ip4(0, netif); - LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: netmask of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - netif->name[0], netif->name[1], - ip4_addr1_16(netif_ip4_netmask(netif)), - ip4_addr2_16(netif_ip4_netmask(netif)), - ip4_addr3_16(netif_ip4_netmask(netif)), - ip4_addr4_16(netif_ip4_netmask(netif)))); - return 1; /* netmask changed */ - } - return 0; /* netmask unchanged */ -} - -/** - * @ingroup netif_ip4 - * Change the netmask of a network interface - * - * @param netif the network interface to change - * @param netmask the new netmask - * - * @note call netif_set_addr() if you also want to change ip address and - * default gateway - */ -void -netif_set_netmask(struct netif *netif, const ip4_addr_t *netmask) -{ -#if LWIP_NETIF_EXT_STATUS_CALLBACK - ip_addr_t old_nm_val; - ip_addr_t *old_nm = &old_nm_val; -#else - ip_addr_t *old_nm = NULL; -#endif - LWIP_ASSERT_CORE_LOCKED(); - - LWIP_ERROR("netif_set_netmask: invalid netif", netif != NULL, return); - - /* Don't propagate NULL pointer (IPv4 ANY) to subsequent functions */ - if (netmask == NULL) { - netmask = IP4_ADDR_ANY4; - } - - if (netif_do_set_netmask(netif, netmask, old_nm)) { -#if LWIP_NETIF_EXT_STATUS_CALLBACK - netif_ext_callback_args_t args; - args.ipv4_changed.old_netmask = old_nm; - netif_invoke_ext_callback(netif, LWIP_NSC_IPV4_NETMASK_CHANGED, &args); -#endif - } -} - -static int -netif_do_set_gw(struct netif *netif, const ip4_addr_t *gw, ip_addr_t *old_gw) -{ - /* address is actually being changed? */ - if (ip4_addr_cmp(gw, netif_ip4_gw(netif)) == 0) { -#if LWIP_NETIF_EXT_STATUS_CALLBACK - LWIP_ASSERT("invalid pointer", old_gw != NULL); - ip_addr_copy(*old_gw, *netif_ip_gw4(netif)); -#else - LWIP_UNUSED_ARG(old_gw); -#endif - - ip4_addr_set(ip_2_ip4(&netif->gw), gw); - IP_SET_TYPE_VAL(netif->gw, IPADDR_TYPE_V4); - LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: GW address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - netif->name[0], netif->name[1], - ip4_addr1_16(netif_ip4_gw(netif)), - ip4_addr2_16(netif_ip4_gw(netif)), - ip4_addr3_16(netif_ip4_gw(netif)), - ip4_addr4_16(netif_ip4_gw(netif)))); - return 1; /* gateway changed */ - } - return 0; /* gateway unchanged */ -} - -/** - * @ingroup netif_ip4 - * Change the default gateway for a network interface - * - * @param netif the network interface to change - * @param gw the new default gateway - * - * @note call netif_set_addr() if you also want to change ip address and netmask - */ -void -netif_set_gw(struct netif *netif, const ip4_addr_t *gw) -{ -#if LWIP_NETIF_EXT_STATUS_CALLBACK - ip_addr_t old_gw_val; - ip_addr_t *old_gw = &old_gw_val; -#else - ip_addr_t *old_gw = NULL; -#endif - LWIP_ASSERT_CORE_LOCKED(); - - LWIP_ERROR("netif_set_gw: invalid netif", netif != NULL, return); - - /* Don't propagate NULL pointer (IPv4 ANY) to subsequent functions */ - if (gw == NULL) { - gw = IP4_ADDR_ANY4; - } - - if (netif_do_set_gw(netif, gw, old_gw)) { -#if LWIP_NETIF_EXT_STATUS_CALLBACK - netif_ext_callback_args_t args; - args.ipv4_changed.old_gw = old_gw; - netif_invoke_ext_callback(netif, LWIP_NSC_IPV4_GATEWAY_CHANGED, &args); -#endif - } -} - -/** - * @ingroup netif_ip4 - * Change IP address configuration for a network interface (including netmask - * and default gateway). - * - * @param netif the network interface to change - * @param ipaddr the new IP address - * @param netmask the new netmask - * @param gw the new default gateway - */ -void -netif_set_addr(struct netif *netif, const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, - const ip4_addr_t *gw) -{ -#if LWIP_NETIF_EXT_STATUS_CALLBACK - netif_nsc_reason_t change_reason = LWIP_NSC_NONE; - netif_ext_callback_args_t cb_args; - ip_addr_t old_nm_val; - ip_addr_t old_gw_val; - ip_addr_t *old_nm = &old_nm_val; - ip_addr_t *old_gw = &old_gw_val; -#else - ip_addr_t *old_nm = NULL; - ip_addr_t *old_gw = NULL; -#endif - ip_addr_t old_addr; - int remove; - - LWIP_ASSERT_CORE_LOCKED(); - - /* Don't propagate NULL pointer (IPv4 ANY) to subsequent functions */ - if (ipaddr == NULL) { - ipaddr = IP4_ADDR_ANY4; - } - if (netmask == NULL) { - netmask = IP4_ADDR_ANY4; - } - if (gw == NULL) { - gw = IP4_ADDR_ANY4; - } - - remove = ip4_addr_isany(ipaddr); - if (remove) { - /* when removing an address, we have to remove it *before* changing netmask/gw - to ensure that tcp RST segment can be sent correctly */ - if (netif_do_set_ipaddr(netif, ipaddr, &old_addr)) { -#if LWIP_NETIF_EXT_STATUS_CALLBACK - change_reason |= LWIP_NSC_IPV4_ADDRESS_CHANGED; - cb_args.ipv4_changed.old_address = &old_addr; -#endif - } - } - if (netif_do_set_netmask(netif, netmask, old_nm)) { -#if LWIP_NETIF_EXT_STATUS_CALLBACK - change_reason |= LWIP_NSC_IPV4_NETMASK_CHANGED; - cb_args.ipv4_changed.old_netmask = old_nm; -#endif - } - if (netif_do_set_gw(netif, gw, old_gw)) { -#if LWIP_NETIF_EXT_STATUS_CALLBACK - change_reason |= LWIP_NSC_IPV4_GATEWAY_CHANGED; - cb_args.ipv4_changed.old_gw = old_gw; -#endif - } - if (!remove) { - /* set ipaddr last to ensure netmask/gw have been set when status callback is called */ - if (netif_do_set_ipaddr(netif, ipaddr, &old_addr)) { -#if LWIP_NETIF_EXT_STATUS_CALLBACK - change_reason |= LWIP_NSC_IPV4_ADDRESS_CHANGED; - cb_args.ipv4_changed.old_address = &old_addr; -#endif - } - } - -#if LWIP_NETIF_EXT_STATUS_CALLBACK - if (change_reason != LWIP_NSC_NONE) { - change_reason |= LWIP_NSC_IPV4_SETTINGS_CHANGED; - netif_invoke_ext_callback(netif, change_reason, &cb_args); - } -#endif -} -#endif /* LWIP_IPV4*/ - -/** - * @ingroup netif - * Remove a network interface from the list of lwIP netifs. - * - * @param netif the network interface to remove - */ -void -netif_remove(struct netif *netif) -{ -#if LWIP_IPV6 - int i; -#endif - - LWIP_ASSERT_CORE_LOCKED(); - - if (netif == NULL) { - return; - } - - netif_invoke_ext_callback(netif, LWIP_NSC_NETIF_REMOVED, NULL); - -#if LWIP_IPV4 - if (!ip4_addr_isany_val(*netif_ip4_addr(netif))) { - netif_do_ip_addr_changed(netif_ip_addr4(netif), NULL); - } - -#if LWIP_IGMP - /* stop IGMP processing */ - if (netif->flags & NETIF_FLAG_IGMP) { - igmp_stop(netif); - } -#endif /* LWIP_IGMP */ -#endif /* LWIP_IPV4*/ - -#if LWIP_IPV6 - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i))) { - netif_do_ip_addr_changed(netif_ip_addr6(netif, i), NULL); - } - } -#if LWIP_IPV6_MLD - /* stop MLD processing */ - mld6_stop(netif); -#endif /* LWIP_IPV6_MLD */ -#endif /* LWIP_IPV6 */ - if (netif_is_up(netif)) { - /* set netif down before removing (call callback function) */ - netif_set_down(netif); - } - - mib2_remove_ip4(netif); - - /* this netif is default? */ - if (netif_default == netif) { - /* reset default netif */ - netif_set_default(NULL); - } -#if !LWIP_SINGLE_NETIF - /* is it the first netif? */ - if (netif_list == netif) { - netif_list = netif->next; - } else { - /* look for netif further down the list */ - struct netif *tmp_netif; - NETIF_FOREACH(tmp_netif) { - if (tmp_netif->next == netif) { - tmp_netif->next = netif->next; - break; - } - } - if (tmp_netif == NULL) { - return; /* netif is not on the list */ - } - } -#endif /* !LWIP_SINGLE_NETIF */ - mib2_netif_removed(netif); -#if LWIP_NETIF_REMOVE_CALLBACK - if (netif->remove_callback) { - netif->remove_callback(netif); - } -#endif /* LWIP_NETIF_REMOVE_CALLBACK */ - LWIP_DEBUGF( NETIF_DEBUG, ("netif_remove: removed netif\n") ); -} - -/** - * @ingroup netif - * Set a network interface as the default network interface - * (used to output all packets for which no specific route is found) - * - * @param netif the default network interface - */ -void -netif_set_default(struct netif *netif) -{ - LWIP_ASSERT_CORE_LOCKED(); - - if (netif == NULL) { - /* remove default route */ - mib2_remove_route_ip4(1, netif); - } else { - /* install default route */ - mib2_add_route_ip4(1, netif); - } - netif_default = netif; - LWIP_DEBUGF(NETIF_DEBUG, ("netif: setting default interface %c%c\n", - netif ? netif->name[0] : '\'', netif ? netif->name[1] : '\'')); -} - -/** - * @ingroup netif - * Bring an interface up, available for processing - * traffic. - */ -void -netif_set_up(struct netif *netif) -{ - LWIP_ASSERT_CORE_LOCKED(); - - LWIP_ERROR("netif_set_up: invalid netif", netif != NULL, return); - - if (!(netif->flags & NETIF_FLAG_UP)) { - netif_set_flags(netif, NETIF_FLAG_UP); - - MIB2_COPY_SYSUPTIME_TO(&netif->ts); - - NETIF_STATUS_CALLBACK(netif); - -#if LWIP_NETIF_EXT_STATUS_CALLBACK - { - netif_ext_callback_args_t args; - args.status_changed.state = 1; - netif_invoke_ext_callback(netif, LWIP_NSC_STATUS_CHANGED, &args); - } -#endif - - netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV4 | NETIF_REPORT_TYPE_IPV6); -#if LWIP_IPV6 - nd6_restart_netif(netif); -#endif /* LWIP_IPV6 */ - } -} - -/** Send ARP/IGMP/MLD/RS events, e.g. on link-up/netif-up or addr-change - */ -static void -netif_issue_reports(struct netif *netif, u8_t report_type) -{ - LWIP_ASSERT("netif_issue_reports: invalid netif", netif != NULL); - - /* Only send reports when both link and admin states are up */ - if (!(netif->flags & NETIF_FLAG_LINK_UP) || - !(netif->flags & NETIF_FLAG_UP)) { - return; - } - -#if LWIP_IPV4 - if ((report_type & NETIF_REPORT_TYPE_IPV4) && - !ip4_addr_isany_val(*netif_ip4_addr(netif))) { -#if LWIP_ARP - /* For Ethernet network interfaces, we would like to send a "gratuitous ARP" */ - if (netif->flags & (NETIF_FLAG_ETHARP)) { - etharp_gratuitous(netif); - } -#endif /* LWIP_ARP */ - -#if LWIP_IGMP - /* resend IGMP memberships */ - if (netif->flags & NETIF_FLAG_IGMP) { - igmp_report_groups(netif); - } -#endif /* LWIP_IGMP */ - } -#endif /* LWIP_IPV4 */ - -#if LWIP_IPV6 - if (report_type & NETIF_REPORT_TYPE_IPV6) { -#if LWIP_IPV6_MLD - /* send mld memberships */ - mld6_report_groups(netif); -#endif /* LWIP_IPV6_MLD */ - } -#endif /* LWIP_IPV6 */ -} - -/** - * @ingroup netif - * Bring an interface down, disabling any traffic processing. - */ -void -netif_set_down(struct netif *netif) -{ - LWIP_ASSERT_CORE_LOCKED(); - - LWIP_ERROR("netif_set_down: invalid netif", netif != NULL, return); - - if (netif->flags & NETIF_FLAG_UP) { -#if LWIP_NETIF_EXT_STATUS_CALLBACK - { - netif_ext_callback_args_t args; - args.status_changed.state = 0; - netif_invoke_ext_callback(netif, LWIP_NSC_STATUS_CHANGED, &args); - } -#endif - - netif_clear_flags(netif, NETIF_FLAG_UP); - MIB2_COPY_SYSUPTIME_TO(&netif->ts); - -#if LWIP_IPV4 && LWIP_ARP - if (netif->flags & NETIF_FLAG_ETHARP) { - etharp_cleanup_netif(netif); - } -#endif /* LWIP_IPV4 && LWIP_ARP */ - -#if LWIP_IPV6 - nd6_cleanup_netif(netif); -#endif /* LWIP_IPV6 */ - - NETIF_STATUS_CALLBACK(netif); - } -} - -#if LWIP_NETIF_STATUS_CALLBACK -/** - * @ingroup netif - * Set callback to be called when interface is brought up/down or address is changed while up - */ -void -netif_set_status_callback(struct netif *netif, netif_status_callback_fn status_callback) -{ - LWIP_ASSERT_CORE_LOCKED(); - - if (netif) { - netif->status_callback = status_callback; - } -} -#endif /* LWIP_NETIF_STATUS_CALLBACK */ - -#if LWIP_NETIF_REMOVE_CALLBACK -/** - * @ingroup netif - * Set callback to be called when the interface has been removed - */ -void -netif_set_remove_callback(struct netif *netif, netif_status_callback_fn remove_callback) -{ - LWIP_ASSERT_CORE_LOCKED(); - - if (netif) { - netif->remove_callback = remove_callback; - } -} -#endif /* LWIP_NETIF_REMOVE_CALLBACK */ - -/** - * @ingroup netif - * Called by a driver when its link goes up - */ -void -netif_set_link_up(struct netif *netif) -{ - LWIP_ASSERT_CORE_LOCKED(); - - LWIP_ERROR("netif_set_link_up: invalid netif", netif != NULL, return); - - if (!(netif->flags & NETIF_FLAG_LINK_UP)) { - netif_set_flags(netif, NETIF_FLAG_LINK_UP); - -#if LWIP_DHCP - dhcp_network_changed(netif); -#endif /* LWIP_DHCP */ - -#if LWIP_AUTOIP - autoip_network_changed(netif); -#endif /* LWIP_AUTOIP */ - - netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV4 | NETIF_REPORT_TYPE_IPV6); -#if LWIP_IPV6 - nd6_restart_netif(netif); -#endif /* LWIP_IPV6 */ - - NETIF_LINK_CALLBACK(netif); -#if LWIP_NETIF_EXT_STATUS_CALLBACK - { - netif_ext_callback_args_t args; - args.link_changed.state = 1; - netif_invoke_ext_callback(netif, LWIP_NSC_LINK_CHANGED, &args); - } -#endif - } -} - -/** - * @ingroup netif - * Called by a driver when its link goes down - */ -void -netif_set_link_down(struct netif *netif) -{ - LWIP_ASSERT_CORE_LOCKED(); - - LWIP_ERROR("netif_set_link_down: invalid netif", netif != NULL, return); - - if (netif->flags & NETIF_FLAG_LINK_UP) { - netif_clear_flags(netif, NETIF_FLAG_LINK_UP); - NETIF_LINK_CALLBACK(netif); -#if LWIP_NETIF_EXT_STATUS_CALLBACK - { - netif_ext_callback_args_t args; - args.link_changed.state = 0; - netif_invoke_ext_callback(netif, LWIP_NSC_LINK_CHANGED, &args); - } -#endif - } -} - -#if LWIP_NETIF_LINK_CALLBACK -/** - * @ingroup netif - * Set callback to be called when link is brought up/down - */ -void -netif_set_link_callback(struct netif *netif, netif_status_callback_fn link_callback) -{ - LWIP_ASSERT_CORE_LOCKED(); - - if (netif) { - netif->link_callback = link_callback; - } -} -#endif /* LWIP_NETIF_LINK_CALLBACK */ - -#if ENABLE_LOOPBACK -/** - * @ingroup netif - * Send an IP packet to be received on the same netif (loopif-like). - * The pbuf is simply copied and handed back to netif->input. - * In multithreaded mode, this is done directly since netif->input must put - * the packet on a queue. - * In callback mode, the packet is put on an internal queue and is fed to - * netif->input by netif_poll(). - * - * @param netif the lwip network interface structure - * @param p the (IP) packet to 'send' - * @return ERR_OK if the packet has been sent - * ERR_MEM if the pbuf used to copy the packet couldn't be allocated - */ -err_t -netif_loop_output(struct netif *netif, struct pbuf *p) -{ - struct pbuf *r; - err_t err; - struct pbuf *last; -#if LWIP_LOOPBACK_MAX_PBUFS - u16_t clen = 0; -#endif /* LWIP_LOOPBACK_MAX_PBUFS */ - /* If we have a loopif, SNMP counters are adjusted for it, - * if not they are adjusted for 'netif'. */ -#if MIB2_STATS -#if LWIP_HAVE_LOOPIF - struct netif *stats_if = &loop_netif; -#else /* LWIP_HAVE_LOOPIF */ - struct netif *stats_if = netif; -#endif /* LWIP_HAVE_LOOPIF */ -#endif /* MIB2_STATS */ -#if LWIP_NETIF_LOOPBACK_MULTITHREADING - u8_t schedule_poll = 0; -#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */ - SYS_ARCH_DECL_PROTECT(lev); - - LWIP_ASSERT("netif_loop_output: invalid netif", netif != NULL); - LWIP_ASSERT("netif_loop_output: invalid pbuf", p != NULL); - - /* Allocate a new pbuf */ - r = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM); - if (r == NULL) { - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.drop); - MIB2_STATS_NETIF_INC(stats_if, ifoutdiscards); - return ERR_MEM; - } -#if LWIP_LOOPBACK_MAX_PBUFS - clen = pbuf_clen(r); - /* check for overflow or too many pbuf on queue */ - if (((netif->loop_cnt_current + clen) < netif->loop_cnt_current) || - ((netif->loop_cnt_current + clen) > LWIP_MIN(LWIP_LOOPBACK_MAX_PBUFS, 0xFFFF))) { - pbuf_free(r); - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.drop); - MIB2_STATS_NETIF_INC(stats_if, ifoutdiscards); - return ERR_MEM; - } - netif->loop_cnt_current = (u16_t)(netif->loop_cnt_current + clen); -#endif /* LWIP_LOOPBACK_MAX_PBUFS */ - - /* Copy the whole pbuf queue p into the single pbuf r */ - if ((err = pbuf_copy(r, p)) != ERR_OK) { - pbuf_free(r); - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.drop); - MIB2_STATS_NETIF_INC(stats_if, ifoutdiscards); - return err; - } - - /* Put the packet on a linked list which gets emptied through calling - netif_poll(). */ - - /* let last point to the last pbuf in chain r */ - for (last = r; last->next != NULL; last = last->next) { - /* nothing to do here, just get to the last pbuf */ - } - - SYS_ARCH_PROTECT(lev); - if (netif->loop_first != NULL) { - LWIP_ASSERT("if first != NULL, last must also be != NULL", netif->loop_last != NULL); - netif->loop_last->next = r; - netif->loop_last = last; - } else { - netif->loop_first = r; - netif->loop_last = last; -#if LWIP_NETIF_LOOPBACK_MULTITHREADING - /* No existing packets queued, schedule poll */ - schedule_poll = 1; -#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */ - } - SYS_ARCH_UNPROTECT(lev); - - LINK_STATS_INC(link.xmit); - MIB2_STATS_NETIF_ADD(stats_if, ifoutoctets, p->tot_len); - MIB2_STATS_NETIF_INC(stats_if, ifoutucastpkts); - -#if LWIP_NETIF_LOOPBACK_MULTITHREADING - /* For multithreading environment, schedule a call to netif_poll */ - if (schedule_poll) { - tcpip_try_callback((tcpip_callback_fn)netif_poll, netif); - } -#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */ - - return ERR_OK; -} - -#if LWIP_HAVE_LOOPIF -#if LWIP_IPV4 -static err_t -netif_loop_output_ipv4(struct netif *netif, struct pbuf *p, const ip4_addr_t *addr) -{ - LWIP_UNUSED_ARG(addr); - return netif_loop_output(netif, p); -} -#endif /* LWIP_IPV4 */ - -#if LWIP_IPV6 -static err_t -netif_loop_output_ipv6(struct netif *netif, struct pbuf *p, const ip6_addr_t *addr) -{ - LWIP_UNUSED_ARG(addr); - return netif_loop_output(netif, p); -} -#endif /* LWIP_IPV6 */ -#endif /* LWIP_HAVE_LOOPIF */ - - -/** - * Call netif_poll() in the main loop of your application. This is to prevent - * reentering non-reentrant functions like tcp_input(). Packets passed to - * netif_loop_output() are put on a list that is passed to netif->input() by - * netif_poll(). - */ -void -netif_poll(struct netif *netif) -{ - /* If we have a loopif, SNMP counters are adjusted for it, - * if not they are adjusted for 'netif'. */ -#if MIB2_STATS -#if LWIP_HAVE_LOOPIF - struct netif *stats_if = &loop_netif; -#else /* LWIP_HAVE_LOOPIF */ - struct netif *stats_if = netif; -#endif /* LWIP_HAVE_LOOPIF */ -#endif /* MIB2_STATS */ - SYS_ARCH_DECL_PROTECT(lev); - - LWIP_ASSERT("netif_poll: invalid netif", netif != NULL); - - /* Get a packet from the list. With SYS_LIGHTWEIGHT_PROT=1, this is protected */ - SYS_ARCH_PROTECT(lev); - while (netif->loop_first != NULL) { - struct pbuf *in, *in_end; -#if LWIP_LOOPBACK_MAX_PBUFS - u8_t clen = 1; -#endif /* LWIP_LOOPBACK_MAX_PBUFS */ - - in = in_end = netif->loop_first; - while (in_end->len != in_end->tot_len) { - LWIP_ASSERT("bogus pbuf: len != tot_len but next == NULL!", in_end->next != NULL); - in_end = in_end->next; -#if LWIP_LOOPBACK_MAX_PBUFS - clen++; -#endif /* LWIP_LOOPBACK_MAX_PBUFS */ - } -#if LWIP_LOOPBACK_MAX_PBUFS - /* adjust the number of pbufs on queue */ - LWIP_ASSERT("netif->loop_cnt_current underflow", - ((netif->loop_cnt_current - clen) < netif->loop_cnt_current)); - netif->loop_cnt_current = (u16_t)(netif->loop_cnt_current - clen); -#endif /* LWIP_LOOPBACK_MAX_PBUFS */ - - /* 'in_end' now points to the last pbuf from 'in' */ - if (in_end == netif->loop_last) { - /* this was the last pbuf in the list */ - netif->loop_first = netif->loop_last = NULL; - } else { - /* pop the pbuf off the list */ - netif->loop_first = in_end->next; - LWIP_ASSERT("should not be null since first != last!", netif->loop_first != NULL); - } - /* De-queue the pbuf from its successors on the 'loop_' list. */ - in_end->next = NULL; - SYS_ARCH_UNPROTECT(lev); - - in->if_idx = netif_get_index(netif); - - LINK_STATS_INC(link.recv); - MIB2_STATS_NETIF_ADD(stats_if, ifinoctets, in->tot_len); - MIB2_STATS_NETIF_INC(stats_if, ifinucastpkts); - /* loopback packets are always IP packets! */ - if (ip_input(in, netif) != ERR_OK) { - pbuf_free(in); - } - SYS_ARCH_PROTECT(lev); - } - SYS_ARCH_UNPROTECT(lev); -} - -#if !LWIP_NETIF_LOOPBACK_MULTITHREADING -/** - * Calls netif_poll() for every netif on the netif_list. - */ -void -netif_poll_all(void) -{ - struct netif *netif; - /* loop through netifs */ - NETIF_FOREACH(netif) { - netif_poll(netif); - } -} -#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */ -#endif /* ENABLE_LOOPBACK */ - -#if LWIP_NUM_NETIF_CLIENT_DATA > 0 -/** - * @ingroup netif_cd - * Allocate an index to store data in client_data member of struct netif. - * Returned value is an index in mentioned array. - * @see LWIP_NUM_NETIF_CLIENT_DATA - */ -u8_t -netif_alloc_client_data_id(void) -{ - u8_t result = netif_client_id; - netif_client_id++; - - LWIP_ASSERT_CORE_LOCKED(); - -#if LWIP_NUM_NETIF_CLIENT_DATA > 256 -#error LWIP_NUM_NETIF_CLIENT_DATA must be <= 256 -#endif - LWIP_ASSERT("Increase LWIP_NUM_NETIF_CLIENT_DATA in lwipopts.h", result < LWIP_NUM_NETIF_CLIENT_DATA); - return (u8_t)(result + LWIP_NETIF_CLIENT_DATA_INDEX_MAX); -} -#endif - -#if LWIP_IPV6 -/** - * @ingroup netif_ip6 - * Change an IPv6 address of a network interface - * - * @param netif the network interface to change - * @param addr_idx index of the IPv6 address - * @param addr6 the new IPv6 address - * - * @note call netif_ip6_addr_set_state() to set the address valid/temptative - */ -void -netif_ip6_addr_set(struct netif *netif, s8_t addr_idx, const ip6_addr_t *addr6) -{ - LWIP_ASSERT_CORE_LOCKED(); - - LWIP_ASSERT("netif_ip6_addr_set: invalid netif", netif != NULL); - LWIP_ASSERT("netif_ip6_addr_set: invalid addr6", addr6 != NULL); - - netif_ip6_addr_set_parts(netif, addr_idx, addr6->addr[0], addr6->addr[1], - addr6->addr[2], addr6->addr[3]); -} - -/* - * Change an IPv6 address of a network interface (internal version taking 4 * u32_t) - * - * @param netif the network interface to change - * @param addr_idx index of the IPv6 address - * @param i0 word0 of the new IPv6 address - * @param i1 word1 of the new IPv6 address - * @param i2 word2 of the new IPv6 address - * @param i3 word3 of the new IPv6 address - */ -void -netif_ip6_addr_set_parts(struct netif *netif, s8_t addr_idx, u32_t i0, u32_t i1, u32_t i2, u32_t i3) -{ - ip_addr_t old_addr; - ip_addr_t new_ipaddr; - LWIP_ASSERT_CORE_LOCKED(); - LWIP_ASSERT("netif != NULL", netif != NULL); - LWIP_ASSERT("invalid index", addr_idx < LWIP_IPV6_NUM_ADDRESSES); - - ip6_addr_copy(*ip_2_ip6(&old_addr), *netif_ip6_addr(netif, addr_idx)); - IP_SET_TYPE_VAL(old_addr, IPADDR_TYPE_V6); - - /* address is actually being changed? */ - if ((ip_2_ip6(&old_addr)->addr[0] != i0) || (ip_2_ip6(&old_addr)->addr[1] != i1) || - (ip_2_ip6(&old_addr)->addr[2] != i2) || (ip_2_ip6(&old_addr)->addr[3] != i3)) { - LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_ip6_addr_set: netif address being changed\n")); - - IP_ADDR6(&new_ipaddr, i0, i1, i2, i3); - ip6_addr_assign_zone(ip_2_ip6(&new_ipaddr), IP6_UNICAST, netif); - - if (ip6_addr_isvalid(netif_ip6_addr_state(netif, addr_idx))) { - netif_do_ip_addr_changed(netif_ip_addr6(netif, addr_idx), &new_ipaddr); - } - /* @todo: remove/readd mib2 ip6 entries? */ - - ip_addr_copy(netif->ip6_addr[addr_idx], new_ipaddr); - - if (ip6_addr_isvalid(netif_ip6_addr_state(netif, addr_idx))) { - netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV6); - NETIF_STATUS_CALLBACK(netif); - } - -#if LWIP_NETIF_EXT_STATUS_CALLBACK - { - netif_ext_callback_args_t args; - args.ipv6_set.addr_index = addr_idx; - args.ipv6_set.old_address = &old_addr; - netif_invoke_ext_callback(netif, LWIP_NSC_IPV6_SET, &args); - } -#endif - } - - LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: IPv6 address %d of interface %c%c set to %s/0x%"X8_F"\n", - addr_idx, netif->name[0], netif->name[1], ip6addr_ntoa(netif_ip6_addr(netif, addr_idx)), - netif_ip6_addr_state(netif, addr_idx))); -} - -/** - * @ingroup netif_ip6 - * Change the state of an IPv6 address of a network interface - * (INVALID, TEMPTATIVE, PREFERRED, DEPRECATED, where TEMPTATIVE - * includes the number of checks done, see ip6_addr.h) - * - * @param netif the network interface to change - * @param addr_idx index of the IPv6 address - * @param state the new IPv6 address state - */ -void -netif_ip6_addr_set_state(struct netif *netif, s8_t addr_idx, u8_t state) -{ - u8_t old_state; - LWIP_ASSERT_CORE_LOCKED(); - LWIP_ASSERT("netif != NULL", netif != NULL); - LWIP_ASSERT("invalid index", addr_idx < LWIP_IPV6_NUM_ADDRESSES); - - old_state = netif_ip6_addr_state(netif, addr_idx); - /* state is actually being changed? */ - if (old_state != state) { - u8_t old_valid = old_state & IP6_ADDR_VALID; - u8_t new_valid = state & IP6_ADDR_VALID; - LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_ip6_addr_set_state: netif address state being changed\n")); - -#if LWIP_IPV6_MLD - /* Reevaluate solicited-node multicast group membership. */ - if (netif->flags & NETIF_FLAG_MLD6) { - nd6_adjust_mld_membership(netif, addr_idx, state); - } -#endif /* LWIP_IPV6_MLD */ - - if (old_valid && !new_valid) { - /* address about to be removed by setting invalid */ - netif_do_ip_addr_changed(netif_ip_addr6(netif, addr_idx), NULL); - /* @todo: remove mib2 ip6 entries? */ - } - netif->ip6_addr_state[addr_idx] = state; - - if (!old_valid && new_valid) { - /* address added by setting valid */ - /* This is a good moment to check that the address is properly zoned. */ - IP6_ADDR_ZONECHECK_NETIF(netif_ip6_addr(netif, addr_idx), netif); - /* @todo: add mib2 ip6 entries? */ - netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV6); - } - if ((old_state & ~IP6_ADDR_TENTATIVE_COUNT_MASK) != - (state & ~IP6_ADDR_TENTATIVE_COUNT_MASK)) { - /* address state has changed -> call the callback function */ - NETIF_STATUS_CALLBACK(netif); - } - -#if LWIP_NETIF_EXT_STATUS_CALLBACK - { - netif_ext_callback_args_t args; - args.ipv6_addr_state_changed.addr_index = addr_idx; - args.ipv6_addr_state_changed.old_state = old_state; - args.ipv6_addr_state_changed.address = netif_ip_addr6(netif, addr_idx); - netif_invoke_ext_callback(netif, LWIP_NSC_IPV6_ADDR_STATE_CHANGED, &args); - } -#endif - } - LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: IPv6 address %d of interface %c%c set to %s/0x%"X8_F"\n", - addr_idx, netif->name[0], netif->name[1], ip6addr_ntoa(netif_ip6_addr(netif, addr_idx)), - netif_ip6_addr_state(netif, addr_idx))); -} - -/** - * Checks if a specific local address is present on the netif and returns its - * index. Depending on its state, it may or may not be assigned to the - * interface (as per RFC terminology). - * - * The given address may or may not be zoned (i.e., have a zone index other - * than IP6_NO_ZONE). If the address is zoned, it must have the correct zone - * for the given netif, or no match will be found. - * - * @param netif the netif to check - * @param ip6addr the IPv6 address to find - * @return >= 0: address found, this is its index - * -1: address not found on this netif - */ -s8_t -netif_get_ip6_addr_match(struct netif *netif, const ip6_addr_t *ip6addr) -{ - s8_t i; - - LWIP_ASSERT_CORE_LOCKED(); - - LWIP_ASSERT("netif_get_ip6_addr_match: invalid netif", netif != NULL); - LWIP_ASSERT("netif_get_ip6_addr_match: invalid ip6addr", ip6addr != NULL); - -#if LWIP_IPV6_SCOPES - if (ip6_addr_has_zone(ip6addr) && !ip6_addr_test_zone(ip6addr, netif)) { - return -1; /* wrong zone, no match */ - } -#endif /* LWIP_IPV6_SCOPES */ - - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (!ip6_addr_isinvalid(netif_ip6_addr_state(netif, i)) && - ip6_addr_cmp_zoneless(netif_ip6_addr(netif, i), ip6addr)) { - return i; - } - } - return -1; -} - -/** - * @ingroup netif_ip6 - * Create a link-local IPv6 address on a netif (stored in slot 0) - * - * @param netif the netif to create the address on - * @param from_mac_48bit if != 0, assume hwadr is a 48-bit MAC address (std conversion) - * if == 0, use hwaddr directly as interface ID - */ -void -netif_create_ip6_linklocal_address(struct netif *netif, u8_t from_mac_48bit) -{ - u8_t i, addr_index; - - LWIP_ASSERT_CORE_LOCKED(); - - LWIP_ASSERT("netif_create_ip6_linklocal_address: invalid netif", netif != NULL); - - /* Link-local prefix. */ - ip_2_ip6(&netif->ip6_addr[0])->addr[0] = PP_HTONL(0xfe800000ul); - ip_2_ip6(&netif->ip6_addr[0])->addr[1] = 0; - - /* Generate interface ID. */ - if (from_mac_48bit) { - /* Assume hwaddr is a 48-bit IEEE 802 MAC. Convert to EUI-64 address. Complement Group bit. */ - ip_2_ip6(&netif->ip6_addr[0])->addr[2] = lwip_htonl((((u32_t)(netif->hwaddr[0] ^ 0x02)) << 24) | - ((u32_t)(netif->hwaddr[1]) << 16) | - ((u32_t)(netif->hwaddr[2]) << 8) | - (0xff)); - ip_2_ip6(&netif->ip6_addr[0])->addr[3] = lwip_htonl((u32_t)(0xfeul << 24) | - ((u32_t)(netif->hwaddr[3]) << 16) | - ((u32_t)(netif->hwaddr[4]) << 8) | - (netif->hwaddr[5])); - } else { - /* Use hwaddr directly as interface ID. */ - ip_2_ip6(&netif->ip6_addr[0])->addr[2] = 0; - ip_2_ip6(&netif->ip6_addr[0])->addr[3] = 0; - - addr_index = 3; - for (i = 0; (i < 8) && (i < netif->hwaddr_len); i++) { - if (i == 4) { - addr_index--; - } - ip_2_ip6(&netif->ip6_addr[0])->addr[addr_index] |= lwip_htonl(((u32_t)(netif->hwaddr[netif->hwaddr_len - i - 1])) << (8 * (i & 0x03))); - } - } - - /* Set a link-local zone. Even though the zone is implied by the owning - * netif, setting the zone anyway has two important conceptual advantages: - * 1) it avoids the need for a ton of exceptions in internal code, allowing - * e.g. ip6_addr_cmp() to be used on local addresses; - * 2) the properly zoned address is visible externally, e.g. when any outside - * code enumerates available addresses or uses one to bind a socket. - * Any external code unaware of address scoping is likely to just ignore the - * zone field, so this should not create any compatibility problems. */ - ip6_addr_assign_zone(ip_2_ip6(&netif->ip6_addr[0]), IP6_UNICAST, netif); - - /* Set address state. */ -#if LWIP_IPV6_DUP_DETECT_ATTEMPTS - /* Will perform duplicate address detection (DAD). */ - netif_ip6_addr_set_state(netif, 0, IP6_ADDR_TENTATIVE); -#else - /* Consider address valid. */ - netif_ip6_addr_set_state(netif, 0, IP6_ADDR_PREFERRED); -#endif /* LWIP_IPV6_AUTOCONFIG */ -} - -/** - * @ingroup netif_ip6 - * This function allows for the easy addition of a new IPv6 address to an interface. - * It takes care of finding an empty slot and then sets the address tentative - * (to make sure that all the subsequent processing happens). - * - * @param netif netif to add the address on - * @param ip6addr address to add - * @param chosen_idx if != NULL, the chosen IPv6 address index will be stored here - */ -err_t -netif_add_ip6_address(struct netif *netif, const ip6_addr_t *ip6addr, s8_t *chosen_idx) -{ - s8_t i; - - LWIP_ASSERT_CORE_LOCKED(); - - LWIP_ASSERT("netif_add_ip6_address: invalid netif", netif != NULL); - LWIP_ASSERT("netif_add_ip6_address: invalid ip6addr", ip6addr != NULL); - - i = netif_get_ip6_addr_match(netif, ip6addr); - if (i >= 0) { - /* Address already added */ - if (chosen_idx != NULL) { - *chosen_idx = i; - } - return ERR_OK; - } - - /* Find a free slot. The first one is reserved for link-local addresses. */ - for (i = ip6_addr_islinklocal(ip6addr) ? 0 : 1; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (ip6_addr_isinvalid(netif_ip6_addr_state(netif, i))) { - ip_addr_copy_from_ip6(netif->ip6_addr[i], *ip6addr); - ip6_addr_assign_zone(ip_2_ip6(&netif->ip6_addr[i]), IP6_UNICAST, netif); - netif_ip6_addr_set_state(netif, i, IP6_ADDR_TENTATIVE); - if (chosen_idx != NULL) { - *chosen_idx = i; - } - return ERR_OK; - } - } - - if (chosen_idx != NULL) { - *chosen_idx = -1; - } - return ERR_VAL; -} - -/** Dummy IPv6 output function for netifs not supporting IPv6 - */ -static err_t -netif_null_output_ip6(struct netif *netif, struct pbuf *p, const ip6_addr_t *ipaddr) -{ - LWIP_UNUSED_ARG(netif); - LWIP_UNUSED_ARG(p); - LWIP_UNUSED_ARG(ipaddr); - - return ERR_IF; -} -#endif /* LWIP_IPV6 */ - -#if LWIP_IPV4 -/** Dummy IPv4 output function for netifs not supporting IPv4 - */ -static err_t -netif_null_output_ip4(struct netif *netif, struct pbuf *p, const ip4_addr_t *ipaddr) -{ - LWIP_UNUSED_ARG(netif); - LWIP_UNUSED_ARG(p); - LWIP_UNUSED_ARG(ipaddr); - - return ERR_IF; -} -#endif /* LWIP_IPV4 */ - -/** -* @ingroup netif -* Return the interface index for the netif with name -* or NETIF_NO_INDEX if not found/on error -* -* @param name the name of the netif -*/ -u8_t -netif_name_to_index(const char *name) -{ - struct netif *netif = netif_find(name); - if (netif != NULL) { - return netif_get_index(netif); - } - /* No name found, return invalid index */ - return NETIF_NO_INDEX; -} - -/** -* @ingroup netif -* Return the interface name for the netif matching index -* or NULL if not found/on error -* -* @param idx the interface index of the netif -* @param name char buffer of at least NETIF_NAMESIZE bytes -*/ -char * -netif_index_to_name(u8_t idx, char *name) -{ - struct netif *netif = netif_get_by_index(idx); - - if (netif != NULL) { - name[0] = netif->name[0]; - name[1] = netif->name[1]; - lwip_itoa(&name[2], NETIF_NAMESIZE - 2, netif_index_to_num(idx)); - return name; - } - return NULL; -} - -/** -* @ingroup netif -* Return the interface for the netif index -* -* @param idx index of netif to find -*/ -struct netif * -netif_get_by_index(u8_t idx) -{ - struct netif *netif; - - LWIP_ASSERT_CORE_LOCKED(); - - if (idx != NETIF_NO_INDEX) { - NETIF_FOREACH(netif) { - if (idx == netif_get_index(netif)) { - return netif; /* found! */ - } - } - } - - return NULL; -} - -/** - * @ingroup netif - * Find a network interface by searching for its name - * - * @param name the name of the netif (like netif->name) plus concatenated number - * in ascii representation (e.g. 'en0') - */ -struct netif * -netif_find(const char *name) -{ - struct netif *netif; - u8_t num; - - LWIP_ASSERT_CORE_LOCKED(); - - if (name == NULL) { - return NULL; - } - - num = (u8_t)atoi(&name[2]); - - NETIF_FOREACH(netif) { - if (num == netif->num && - name[0] == netif->name[0] && - name[1] == netif->name[1]) { - LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: found %c%c\n", name[0], name[1])); - return netif; - } - } - LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: didn't find %c%c\n", name[0], name[1])); - return NULL; -} - -#if LWIP_NETIF_EXT_STATUS_CALLBACK -/** - * @ingroup netif - * Add extended netif events listener - * @param callback pointer to listener structure - * @param fn callback function - */ -void -netif_add_ext_callback(netif_ext_callback_t *callback, netif_ext_callback_fn fn) -{ - LWIP_ASSERT_CORE_LOCKED(); - LWIP_ASSERT("callback must be != NULL", callback != NULL); - LWIP_ASSERT("fn must be != NULL", fn != NULL); - - callback->callback_fn = fn; - callback->next = ext_callback; - ext_callback = callback; -} - -/** - * @ingroup netif - * Remove extended netif events listener - * @param callback pointer to listener structure - */ -void -netif_remove_ext_callback(netif_ext_callback_t* callback) -{ - netif_ext_callback_t *last, *iter; - - LWIP_ASSERT_CORE_LOCKED(); - LWIP_ASSERT("callback must be != NULL", callback != NULL); - - if (ext_callback == NULL) { - return; - } - - if (callback == ext_callback) { - ext_callback = ext_callback->next; - } else { - last = ext_callback; - for (iter = ext_callback->next; iter != NULL; last = iter, iter = iter->next) { - if (iter == callback) { - LWIP_ASSERT("last != NULL", last != NULL); - last->next = callback->next; - callback->next = NULL; - return; - } - } - } -} - -/** - * Invoke extended netif status event - * @param netif netif that is affected by change - * @param reason change reason - * @param args depends on reason, see reason description - */ -void -netif_invoke_ext_callback(struct netif *netif, netif_nsc_reason_t reason, const netif_ext_callback_args_t *args) -{ - netif_ext_callback_t *callback = ext_callback; - - LWIP_ASSERT("netif must be != NULL", netif != NULL); - - while (callback != NULL) { - callback->callback_fn(netif, reason, args); - callback = callback->next; - } -} -#endif /* LWIP_NETIF_EXT_STATUS_CALLBACK */ diff --git a/third-party/lwip-2.1.2/core/pbuf.c b/third-party/lwip-2.1.2/core/pbuf.c deleted file mode 100644 index a209e0ca..00000000 --- a/third-party/lwip-2.1.2/core/pbuf.c +++ /dev/null @@ -1,1514 +0,0 @@ -/** - * @file - * Packet buffer management - */ - -/** - * @defgroup pbuf Packet buffers (PBUF) - * @ingroup infrastructure - * - * Packets are built from the pbuf data structure. It supports dynamic - * memory allocation for packet contents or can reference externally - * managed packet contents both in RAM and ROM. Quick allocation for - * incoming packets is provided through pools with fixed sized pbufs. - * - * A packet may span over multiple pbufs, chained as a singly linked - * list. This is called a "pbuf chain". - * - * Multiple packets may be queued, also using this singly linked list. - * This is called a "packet queue". - * - * So, a packet queue consists of one or more pbuf chains, each of - * which consist of one or more pbufs. CURRENTLY, PACKET QUEUES ARE - * NOT SUPPORTED!!! Use helper structs to queue multiple packets. - * - * The differences between a pbuf chain and a packet queue are very - * precise but subtle. - * - * The last pbuf of a packet has a ->tot_len field that equals the - * ->len field. It can be found by traversing the list. If the last - * pbuf of a packet has a ->next field other than NULL, more packets - * are on the queue. - * - * Therefore, looping through a pbuf of a single packet, has an - * loop end condition (tot_len == p->len), NOT (next == NULL). - * - * Example of custom pbuf usage: @ref zerocopyrx - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#include "lwip/opt.h" - -#include "lwip/pbuf.h" -#include "lwip/stats.h" -#include "lwip/def.h" -#include "lwip/mem.h" -#include "lwip/memp.h" -#include "lwip/sys.h" -#include "lwip/netif.h" -#if LWIP_TCP && TCP_QUEUE_OOSEQ -#include "lwip/priv/tcp_priv.h" -#endif -#if LWIP_CHECKSUM_ON_COPY -#include "lwip/inet_chksum.h" -#endif - -#include - -#define SIZEOF_STRUCT_PBUF LWIP_MEM_ALIGN_SIZE(sizeof(struct pbuf)) -/* Since the pool is created in memp, PBUF_POOL_BUFSIZE will be automatically - aligned there. Therefore, PBUF_POOL_BUFSIZE_ALIGNED can be used here. */ -#define PBUF_POOL_BUFSIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE) - -static const struct pbuf * -pbuf_skip_const(const struct pbuf *in, u16_t in_offset, u16_t *out_offset); - -#if !LWIP_TCP || !TCP_QUEUE_OOSEQ || !PBUF_POOL_FREE_OOSEQ -#define PBUF_POOL_IS_EMPTY() -#else /* !LWIP_TCP || !TCP_QUEUE_OOSEQ || !PBUF_POOL_FREE_OOSEQ */ - -#if !NO_SYS -#ifndef PBUF_POOL_FREE_OOSEQ_QUEUE_CALL -#include "lwip/tcpip.h" -#define PBUF_POOL_FREE_OOSEQ_QUEUE_CALL() do { \ - if (tcpip_try_callback(pbuf_free_ooseq_callback, NULL) != ERR_OK) { \ - SYS_ARCH_PROTECT(old_level); \ - pbuf_free_ooseq_pending = 0; \ - SYS_ARCH_UNPROTECT(old_level); \ - } } while(0) -#endif /* PBUF_POOL_FREE_OOSEQ_QUEUE_CALL */ -#endif /* !NO_SYS */ - -volatile u8_t pbuf_free_ooseq_pending; -#define PBUF_POOL_IS_EMPTY() pbuf_pool_is_empty() - -/** - * Attempt to reclaim some memory from queued out-of-sequence TCP segments - * if we run out of pool pbufs. It's better to give priority to new packets - * if we're running out. - * - * This must be done in the correct thread context therefore this function - * can only be used with NO_SYS=0 and through tcpip_callback. - */ -#if !NO_SYS -static -#endif /* !NO_SYS */ -void -pbuf_free_ooseq(void) -{ - struct tcp_pcb *pcb; - SYS_ARCH_SET(pbuf_free_ooseq_pending, 0); - - for (pcb = tcp_active_pcbs; NULL != pcb; pcb = pcb->next) { - if (pcb->ooseq != NULL) { - /** Free the ooseq pbufs of one PCB only */ - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free_ooseq: freeing out-of-sequence pbufs\n")); - tcp_free_ooseq(pcb); - return; - } - } -} - -#if !NO_SYS -/** - * Just a callback function for tcpip_callback() that calls pbuf_free_ooseq(). - */ -static void -pbuf_free_ooseq_callback(void *arg) -{ - LWIP_UNUSED_ARG(arg); - pbuf_free_ooseq(); -} -#endif /* !NO_SYS */ - -/** Queue a call to pbuf_free_ooseq if not already queued. */ -static void -pbuf_pool_is_empty(void) -{ -#ifndef PBUF_POOL_FREE_OOSEQ_QUEUE_CALL - SYS_ARCH_SET(pbuf_free_ooseq_pending, 1); -#else /* PBUF_POOL_FREE_OOSEQ_QUEUE_CALL */ - u8_t queued; - SYS_ARCH_DECL_PROTECT(old_level); - SYS_ARCH_PROTECT(old_level); - queued = pbuf_free_ooseq_pending; - pbuf_free_ooseq_pending = 1; - SYS_ARCH_UNPROTECT(old_level); - - if (!queued) { - /* queue a call to pbuf_free_ooseq if not already queued */ - PBUF_POOL_FREE_OOSEQ_QUEUE_CALL(); - } -#endif /* PBUF_POOL_FREE_OOSEQ_QUEUE_CALL */ -} -#endif /* !LWIP_TCP || !TCP_QUEUE_OOSEQ || !PBUF_POOL_FREE_OOSEQ */ - -/* Initialize members of struct pbuf after allocation */ -static void -pbuf_init_alloced_pbuf(struct pbuf *p, void *payload, u16_t tot_len, u16_t len, pbuf_type type, u8_t flags) -{ - p->next = NULL; - p->payload = payload; - p->tot_len = tot_len; - p->len = len; - p->type_internal = (u8_t)type; - p->flags = flags; - p->ref = 1; - p->if_idx = NETIF_NO_INDEX; -} - -/** - * @ingroup pbuf - * Allocates a pbuf of the given type (possibly a chain for PBUF_POOL type). - * - * The actual memory allocated for the pbuf is determined by the - * layer at which the pbuf is allocated and the requested size - * (from the size parameter). - * - * @param layer header size - * @param length size of the pbuf's payload - * @param type this parameter decides how and where the pbuf - * should be allocated as follows: - * - * - PBUF_RAM: buffer memory for pbuf is allocated as one large - * chunk. This includes protocol headers as well. - * - PBUF_ROM: no buffer memory is allocated for the pbuf, even for - * protocol headers. Additional headers must be prepended - * by allocating another pbuf and chain in to the front of - * the ROM pbuf. It is assumed that the memory used is really - * similar to ROM in that it is immutable and will not be - * changed. Memory which is dynamic should generally not - * be attached to PBUF_ROM pbufs. Use PBUF_REF instead. - * - PBUF_REF: no buffer memory is allocated for the pbuf, even for - * protocol headers. It is assumed that the pbuf is only - * being used in a single thread. If the pbuf gets queued, - * then pbuf_take should be called to copy the buffer. - * - PBUF_POOL: the pbuf is allocated as a pbuf chain, with pbufs from - * the pbuf pool that is allocated during pbuf_init(). - * - * @return the allocated pbuf. If multiple pbufs where allocated, this - * is the first pbuf of a pbuf chain. - */ -struct pbuf * -pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type) -{ - struct pbuf *p; - u16_t offset = (u16_t)layer; - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F")\n", length)); - - switch (type) { - case PBUF_REF: /* fall through */ - case PBUF_ROM: - p = pbuf_alloc_reference(NULL, length, type); - break; - case PBUF_POOL: { - struct pbuf *q, *last; - u16_t rem_len; /* remaining length */ - p = NULL; - last = NULL; - rem_len = length; - do { - u16_t qlen; - q = (struct pbuf *)memp_malloc(MEMP_PBUF_POOL); - if (q == NULL) { - PBUF_POOL_IS_EMPTY(); - /* free chain so far allocated */ - if (p) { - pbuf_free(p); - } - /* bail out unsuccessfully */ - return NULL; - } - qlen = LWIP_MIN(rem_len, (u16_t)(PBUF_POOL_BUFSIZE_ALIGNED - LWIP_MEM_ALIGN_SIZE(offset))); - pbuf_init_alloced_pbuf(q, LWIP_MEM_ALIGN((void *)((u8_t *)q + SIZEOF_STRUCT_PBUF + offset)), - rem_len, qlen, type, 0); - LWIP_ASSERT("pbuf_alloc: pbuf q->payload properly aligned", - ((mem_ptr_t)q->payload % MEM_ALIGNMENT) == 0); - LWIP_ASSERT("PBUF_POOL_BUFSIZE must be bigger than MEM_ALIGNMENT", - (PBUF_POOL_BUFSIZE_ALIGNED - LWIP_MEM_ALIGN_SIZE(offset)) > 0 ); - if (p == NULL) { - /* allocated head of pbuf chain (into p) */ - p = q; - } else { - /* make previous pbuf point to this pbuf */ - last->next = q; - } - last = q; - rem_len = (u16_t)(rem_len - qlen); - offset = 0; - } while (rem_len > 0); - break; - } - case PBUF_RAM: { - u16_t payload_len = (u16_t)(LWIP_MEM_ALIGN_SIZE(offset) + LWIP_MEM_ALIGN_SIZE(length)); - mem_size_t alloc_len = (mem_size_t)(LWIP_MEM_ALIGN_SIZE(SIZEOF_STRUCT_PBUF) + payload_len); - - /* bug #50040: Check for integer overflow when calculating alloc_len */ - if ((payload_len < LWIP_MEM_ALIGN_SIZE(length)) || - (alloc_len < LWIP_MEM_ALIGN_SIZE(length))) { - return NULL; - } - - /* If pbuf is to be allocated in RAM, allocate memory for it. */ - p = (struct pbuf *)mem_malloc(alloc_len); - if (p == NULL) { - return NULL; - } - pbuf_init_alloced_pbuf(p, LWIP_MEM_ALIGN((void *)((u8_t *)p + SIZEOF_STRUCT_PBUF + offset)), - length, length, type, 0); - LWIP_ASSERT("pbuf_alloc: pbuf->payload properly aligned", - ((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0); - break; - } - default: - LWIP_ASSERT("pbuf_alloc: erroneous type", 0); - return NULL; - } - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F") == %p\n", length, (void *)p)); - return p; -} - -/** - * @ingroup pbuf - * Allocates a pbuf for referenced data. - * Referenced data can be volatile (PBUF_REF) or long-lived (PBUF_ROM). - * - * The actual memory allocated for the pbuf is determined by the - * layer at which the pbuf is allocated and the requested size - * (from the size parameter). - * - * @param payload referenced payload - * @param length size of the pbuf's payload - * @param type this parameter decides how and where the pbuf - * should be allocated as follows: - * - * - PBUF_ROM: It is assumed that the memory used is really - * similar to ROM in that it is immutable and will not be - * changed. Memory which is dynamic should generally not - * be attached to PBUF_ROM pbufs. Use PBUF_REF instead. - * - PBUF_REF: It is assumed that the pbuf is only - * being used in a single thread. If the pbuf gets queued, - * then pbuf_take should be called to copy the buffer. - * - * @return the allocated pbuf. - */ -struct pbuf * -pbuf_alloc_reference(void *payload, u16_t length, pbuf_type type) -{ - struct pbuf *p; - LWIP_ASSERT("invalid pbuf_type", (type == PBUF_REF) || (type == PBUF_ROM)); - /* only allocate memory for the pbuf structure */ - p = (struct pbuf *)memp_malloc(MEMP_PBUF); - if (p == NULL) { - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("pbuf_alloc_reference: Could not allocate MEMP_PBUF for PBUF_%s.\n", - (type == PBUF_ROM) ? "ROM" : "REF")); - return NULL; - } - pbuf_init_alloced_pbuf(p, payload, length, length, type, 0); - return p; -} - - -#if LWIP_SUPPORT_CUSTOM_PBUF -/** - * @ingroup pbuf - * Initialize a custom pbuf (already allocated). - * Example of custom pbuf usage: @ref zerocopyrx - * - * @param l header size - * @param length size of the pbuf's payload - * @param type type of the pbuf (only used to treat the pbuf accordingly, as - * this function allocates no memory) - * @param p pointer to the custom pbuf to initialize (already allocated) - * @param payload_mem pointer to the buffer that is used for payload and headers, - * must be at least big enough to hold 'length' plus the header size, - * may be NULL if set later. - * ATTENTION: The caller is responsible for correct alignment of this buffer!! - * @param payload_mem_len the size of the 'payload_mem' buffer, must be at least - * big enough to hold 'length' plus the header size - */ -struct pbuf * -pbuf_alloced_custom(pbuf_layer l, u16_t length, pbuf_type type, struct pbuf_custom *p, - void *payload_mem, u16_t payload_mem_len) -{ - u16_t offset = (u16_t)l; - void *payload; - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloced_custom(length=%"U16_F")\n", length)); - - if (LWIP_MEM_ALIGN_SIZE(offset) + length > payload_mem_len) { - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_WARNING, ("pbuf_alloced_custom(length=%"U16_F") buffer too short\n", length)); - return NULL; - } - - if (payload_mem != NULL) { - payload = (u8_t *)payload_mem + LWIP_MEM_ALIGN_SIZE(offset); - } else { - payload = NULL; - } - pbuf_init_alloced_pbuf(&p->pbuf, payload, length, length, type, PBUF_FLAG_IS_CUSTOM); - return &p->pbuf; -} -#endif /* LWIP_SUPPORT_CUSTOM_PBUF */ - -/** - * @ingroup pbuf - * Shrink a pbuf chain to a desired length. - * - * @param p pbuf to shrink. - * @param new_len desired new length of pbuf chain - * - * Depending on the desired length, the first few pbufs in a chain might - * be skipped and left unchanged. The new last pbuf in the chain will be - * resized, and any remaining pbufs will be freed. - * - * @note If the pbuf is ROM/REF, only the ->tot_len and ->len fields are adjusted. - * @note May not be called on a packet queue. - * - * @note Despite its name, pbuf_realloc cannot grow the size of a pbuf (chain). - */ -void -pbuf_realloc(struct pbuf *p, u16_t new_len) -{ - struct pbuf *q; - u16_t rem_len; /* remaining length */ - u16_t shrink; - - LWIP_ASSERT("pbuf_realloc: p != NULL", p != NULL); - - /* desired length larger than current length? */ - if (new_len >= p->tot_len) { - /* enlarging not yet supported */ - return; - } - - /* the pbuf chain grows by (new_len - p->tot_len) bytes - * (which may be negative in case of shrinking) */ - shrink = (u16_t)(p->tot_len - new_len); - - /* first, step over any pbufs that should remain in the chain */ - rem_len = new_len; - q = p; - /* should this pbuf be kept? */ - while (rem_len > q->len) { - /* decrease remaining length by pbuf length */ - rem_len = (u16_t)(rem_len - q->len); - /* decrease total length indicator */ - q->tot_len = (u16_t)(q->tot_len - shrink); - /* proceed to next pbuf in chain */ - q = q->next; - LWIP_ASSERT("pbuf_realloc: q != NULL", q != NULL); - } - /* we have now reached the new last pbuf (in q) */ - /* rem_len == desired length for pbuf q */ - - /* shrink allocated memory for PBUF_RAM */ - /* (other types merely adjust their length fields */ - if (pbuf_match_allocsrc(q, PBUF_TYPE_ALLOC_SRC_MASK_STD_HEAP) && (rem_len != q->len) -#if LWIP_SUPPORT_CUSTOM_PBUF - && ((q->flags & PBUF_FLAG_IS_CUSTOM) == 0) -#endif /* LWIP_SUPPORT_CUSTOM_PBUF */ - ) { - /* reallocate and adjust the length of the pbuf that will be split */ - q = (struct pbuf *)mem_trim(q, (mem_size_t)(((u8_t *)q->payload - (u8_t *)q) + rem_len)); - LWIP_ASSERT("mem_trim returned q == NULL", q != NULL); - } - /* adjust length fields for new last pbuf */ - q->len = rem_len; - q->tot_len = q->len; - - /* any remaining pbufs in chain? */ - if (q->next != NULL) { - /* free remaining pbufs in chain */ - pbuf_free(q->next); - } - /* q is last packet in chain */ - q->next = NULL; - -} - -/** - * Adjusts the payload pointer to reveal headers in the payload. - * @see pbuf_add_header. - * - * @param p pbuf to change the header size. - * @param header_size_increment Number of bytes to increment header size. - * @param force Allow 'header_size_increment > 0' for PBUF_REF/PBUF_ROM types - * - * @return non-zero on failure, zero on success. - * - */ -static u8_t -pbuf_add_header_impl(struct pbuf *p, size_t header_size_increment, u8_t force) -{ - u16_t type_internal; - void *payload; - u16_t increment_magnitude; - - LWIP_ASSERT("p != NULL", p != NULL); - if ((p == NULL) || (header_size_increment > 0xFFFF)) { - return 1; - } - if (header_size_increment == 0) { - return 0; - } - - increment_magnitude = (u16_t)header_size_increment; - /* Do not allow tot_len to wrap as a result. */ - if ((u16_t)(increment_magnitude + p->tot_len) < increment_magnitude) { - return 1; - } - - type_internal = p->type_internal; - - /* pbuf types containing payloads? */ - if (type_internal & PBUF_TYPE_FLAG_STRUCT_DATA_CONTIGUOUS) { - /* set new payload pointer */ - payload = (u8_t *)p->payload - header_size_increment; - /* boundary check fails? */ - if ((u8_t *)payload < (u8_t *)p + SIZEOF_STRUCT_PBUF) { - LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_TRACE, - ("pbuf_add_header: failed as %p < %p (not enough space for new header size)\n", - (void *)payload, (void *)((u8_t *)p + SIZEOF_STRUCT_PBUF))); - /* bail out unsuccessfully */ - return 1; - } - /* pbuf types referring to external payloads? */ - } else { - /* hide a header in the payload? */ - if (force) { - payload = (u8_t *)p->payload - header_size_increment; - } else { - /* cannot expand payload to front (yet!) - * bail out unsuccessfully */ - return 1; - } - } - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_add_header: old %p new %p (%"U16_F")\n", - (void *)p->payload, (void *)payload, increment_magnitude)); - - /* modify pbuf fields */ - p->payload = payload; - p->len = (u16_t)(p->len + increment_magnitude); - p->tot_len = (u16_t)(p->tot_len + increment_magnitude); - - - return 0; -} - -/** - * Adjusts the payload pointer to reveal headers in the payload. - * - * Adjusts the ->payload pointer so that space for a header - * appears in the pbuf payload. - * - * The ->payload, ->tot_len and ->len fields are adjusted. - * - * @param p pbuf to change the header size. - * @param header_size_increment Number of bytes to increment header size which - * increases the size of the pbuf. New space is on the front. - * If header_size_increment is 0, this function does nothing and returns successful. - * - * PBUF_ROM and PBUF_REF type buffers cannot have their sizes increased, so - * the call will fail. A check is made that the increase in header size does - * not move the payload pointer in front of the start of the buffer. - * - * @return non-zero on failure, zero on success. - * - */ -u8_t -pbuf_add_header(struct pbuf *p, size_t header_size_increment) -{ - return pbuf_add_header_impl(p, header_size_increment, 0); -} - -/** - * Same as @ref pbuf_add_header but does not check if 'header_size > 0' is allowed. - * This is used internally only, to allow PBUF_REF for RX. - */ -u8_t -pbuf_add_header_force(struct pbuf *p, size_t header_size_increment) -{ - return pbuf_add_header_impl(p, header_size_increment, 1); -} - -/** - * Adjusts the payload pointer to hide headers in the payload. - * - * Adjusts the ->payload pointer so that space for a header - * disappears in the pbuf payload. - * - * The ->payload, ->tot_len and ->len fields are adjusted. - * - * @param p pbuf to change the header size. - * @param header_size_decrement Number of bytes to decrement header size which - * decreases the size of the pbuf. - * If header_size_decrement is 0, this function does nothing and returns successful. - * @return non-zero on failure, zero on success. - * - */ -u8_t -pbuf_remove_header(struct pbuf *p, size_t header_size_decrement) -{ - void *payload; - u16_t increment_magnitude; - - LWIP_ASSERT("p != NULL", p != NULL); - if ((p == NULL) || (header_size_decrement > 0xFFFF)) { - return 1; - } - if (header_size_decrement == 0) { - return 0; - } - - increment_magnitude = (u16_t)header_size_decrement; - /* Check that we aren't going to move off the end of the pbuf */ - LWIP_ERROR("increment_magnitude <= p->len", (increment_magnitude <= p->len), return 1;); - - /* remember current payload pointer */ - payload = p->payload; - LWIP_UNUSED_ARG(payload); /* only used in LWIP_DEBUGF below */ - - /* increase payload pointer (guarded by length check above) */ - p->payload = (u8_t *)p->payload + header_size_decrement; - /* modify pbuf length fields */ - p->len = (u16_t)(p->len - increment_magnitude); - p->tot_len = (u16_t)(p->tot_len - increment_magnitude); - - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_remove_header: old %p new %p (%"U16_F")\n", - (void *)payload, (void *)p->payload, increment_magnitude)); - - return 0; -} - -static u8_t -pbuf_header_impl(struct pbuf *p, s16_t header_size_increment, u8_t force) -{ - if (header_size_increment < 0) { - return pbuf_remove_header(p, (size_t) - header_size_increment); - } else { - return pbuf_add_header_impl(p, (size_t)header_size_increment, force); - } -} - -/** - * Adjusts the payload pointer to hide or reveal headers in the payload. - * - * Adjusts the ->payload pointer so that space for a header - * (dis)appears in the pbuf payload. - * - * The ->payload, ->tot_len and ->len fields are adjusted. - * - * @param p pbuf to change the header size. - * @param header_size_increment Number of bytes to increment header size which - * increases the size of the pbuf. New space is on the front. - * (Using a negative value decreases the header size.) - * If header_size_increment is 0, this function does nothing and returns successful. - * - * PBUF_ROM and PBUF_REF type buffers cannot have their sizes increased, so - * the call will fail. A check is made that the increase in header size does - * not move the payload pointer in front of the start of the buffer. - * @return non-zero on failure, zero on success. - * - */ -u8_t -pbuf_header(struct pbuf *p, s16_t header_size_increment) -{ - return pbuf_header_impl(p, header_size_increment, 0); -} - -/** - * Same as pbuf_header but does not check if 'header_size > 0' is allowed. - * This is used internally only, to allow PBUF_REF for RX. - */ -u8_t -pbuf_header_force(struct pbuf *p, s16_t header_size_increment) -{ - return pbuf_header_impl(p, header_size_increment, 1); -} - -/** Similar to pbuf_header(-size) but de-refs header pbufs for (size >= p->len) - * - * @param q pbufs to operate on - * @param size The number of bytes to remove from the beginning of the pbuf list. - * While size >= p->len, pbufs are freed. - * ATTENTION: this is the opposite direction as @ref pbuf_header, but - * takes an u16_t not s16_t! - * @return the new head pbuf - */ -struct pbuf * -pbuf_free_header(struct pbuf *q, u16_t size) -{ - struct pbuf *p = q; - u16_t free_left = size; - while (free_left && p) { - if (free_left >= p->len) { - struct pbuf *f = p; - free_left = (u16_t)(free_left - p->len); - p = p->next; - f->next = 0; - pbuf_free(f); - } else { - pbuf_remove_header(p, free_left); - free_left = 0; - } - } - return p; -} - -/** - * @ingroup pbuf - * Dereference a pbuf chain or queue and deallocate any no-longer-used - * pbufs at the head of this chain or queue. - * - * Decrements the pbuf reference count. If it reaches zero, the pbuf is - * deallocated. - * - * For a pbuf chain, this is repeated for each pbuf in the chain, - * up to the first pbuf which has a non-zero reference count after - * decrementing. So, when all reference counts are one, the whole - * chain is free'd. - * - * @param p The pbuf (chain) to be dereferenced. - * - * @return the number of pbufs that were de-allocated - * from the head of the chain. - * - * @note MUST NOT be called on a packet queue (Not verified to work yet). - * @note the reference counter of a pbuf equals the number of pointers - * that refer to the pbuf (or into the pbuf). - * - * @internal examples: - * - * Assuming existing chains a->b->c with the following reference - * counts, calling pbuf_free(a) results in: - * - * 1->2->3 becomes ...1->3 - * 3->3->3 becomes 2->3->3 - * 1->1->2 becomes ......1 - * 2->1->1 becomes 1->1->1 - * 1->1->1 becomes ....... - * - */ -u8_t -pbuf_free(struct pbuf *p) -{ - u8_t alloc_src; - struct pbuf *q; - u8_t count; - - if (p == NULL) { - LWIP_ASSERT("p != NULL", p != NULL); - /* if assertions are disabled, proceed with debug output */ - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("pbuf_free(p == NULL) was called.\n")); - return 0; - } - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free(%p)\n", (void *)p)); - - PERF_START; - - count = 0; - /* de-allocate all consecutive pbufs from the head of the chain that - * obtain a zero reference count after decrementing*/ - while (p != NULL) { - LWIP_PBUF_REF_T ref; - SYS_ARCH_DECL_PROTECT(old_level); - /* Since decrementing ref cannot be guaranteed to be a single machine operation - * we must protect it. We put the new ref into a local variable to prevent - * further protection. */ - SYS_ARCH_PROTECT(old_level); - /* all pbufs in a chain are referenced at least once */ - LWIP_ASSERT("pbuf_free: p->ref > 0", p->ref > 0); - /* decrease reference count (number of pointers to pbuf) */ - ref = --(p->ref); - SYS_ARCH_UNPROTECT(old_level); - /* this pbuf is no longer referenced to? */ - if (ref == 0) { - /* remember next pbuf in chain for next iteration */ - q = p->next; - LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free: deallocating %p\n", (void *)p)); - alloc_src = pbuf_get_allocsrc(p); -#if LWIP_SUPPORT_CUSTOM_PBUF - /* is this a custom pbuf? */ - if ((p->flags & PBUF_FLAG_IS_CUSTOM) != 0) { - struct pbuf_custom *pc = (struct pbuf_custom *)p; - LWIP_ASSERT("pc->custom_free_function != NULL", pc->custom_free_function != NULL); - pc->custom_free_function(p); - } else -#endif /* LWIP_SUPPORT_CUSTOM_PBUF */ - { - /* is this a pbuf from the pool? */ - if (alloc_src == PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF_POOL) { - memp_free(MEMP_PBUF_POOL, p); - /* is this a ROM or RAM referencing pbuf? */ - } else if (alloc_src == PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF) { - memp_free(MEMP_PBUF, p); - /* type == PBUF_RAM */ - } else if (alloc_src == PBUF_TYPE_ALLOC_SRC_MASK_STD_HEAP) { - mem_free(p); - } else { - /* @todo: support freeing other types */ - LWIP_ASSERT("invalid pbuf type", 0); - } - } - count++; - /* proceed to next pbuf */ - p = q; - /* p->ref > 0, this pbuf is still referenced to */ - /* (and so the remaining pbufs in chain as well) */ - } else { - LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free: %p has ref %"U16_F", ending here.\n", (void *)p, (u16_t)ref)); - /* stop walking through the chain */ - p = NULL; - } - } - PERF_STOP("pbuf_free"); - /* return number of de-allocated pbufs */ - return count; -} - -/** - * Count number of pbufs in a chain - * - * @param p first pbuf of chain - * @return the number of pbufs in a chain - */ -u16_t -pbuf_clen(const struct pbuf *p) -{ - u16_t len; - - len = 0; - while (p != NULL) { - ++len; - p = p->next; - } - return len; -} - -/** - * @ingroup pbuf - * Increment the reference count of the pbuf. - * - * @param p pbuf to increase reference counter of - * - */ -void -pbuf_ref(struct pbuf *p) -{ - /* pbuf given? */ - if (p != NULL) { - SYS_ARCH_SET(p->ref, (LWIP_PBUF_REF_T)(p->ref + 1)); - LWIP_ASSERT("pbuf ref overflow", p->ref > 0); - } -} - -/** - * @ingroup pbuf - * Concatenate two pbufs (each may be a pbuf chain) and take over - * the caller's reference of the tail pbuf. - * - * @note The caller MAY NOT reference the tail pbuf afterwards. - * Use pbuf_chain() for that purpose. - * - * This function explicitly does not check for tot_len overflow to prevent - * failing to queue too long pbufs. This can produce invalid pbufs, so - * handle with care! - * - * @see pbuf_chain() - */ -void -pbuf_cat(struct pbuf *h, struct pbuf *t) -{ - struct pbuf *p; - - LWIP_ERROR("(h != NULL) && (t != NULL) (programmer violates API)", - ((h != NULL) && (t != NULL)), return;); - - /* proceed to last pbuf of chain */ - for (p = h; p->next != NULL; p = p->next) { - /* add total length of second chain to all totals of first chain */ - p->tot_len = (u16_t)(p->tot_len + t->tot_len); - } - /* { p is last pbuf of first h chain, p->next == NULL } */ - LWIP_ASSERT("p->tot_len == p->len (of last pbuf in chain)", p->tot_len == p->len); - LWIP_ASSERT("p->next == NULL", p->next == NULL); - /* add total length of second chain to last pbuf total of first chain */ - p->tot_len = (u16_t)(p->tot_len + t->tot_len); - /* chain last pbuf of head (p) with first of tail (t) */ - p->next = t; - /* p->next now references t, but the caller will drop its reference to t, - * so netto there is no change to the reference count of t. - */ -} - -/** - * @ingroup pbuf - * Chain two pbufs (or pbuf chains) together. - * - * The caller MUST call pbuf_free(t) once it has stopped - * using it. Use pbuf_cat() instead if you no longer use t. - * - * @param h head pbuf (chain) - * @param t tail pbuf (chain) - * @note The pbufs MUST belong to the same packet. - * @note MAY NOT be called on a packet queue. - * - * The ->tot_len fields of all pbufs of the head chain are adjusted. - * The ->next field of the last pbuf of the head chain is adjusted. - * The ->ref field of the first pbuf of the tail chain is adjusted. - * - */ -void -pbuf_chain(struct pbuf *h, struct pbuf *t) -{ - pbuf_cat(h, t); - /* t is now referenced by h */ - pbuf_ref(t); - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_chain: %p references %p\n", (void *)h, (void *)t)); -} - -/** - * Dechains the first pbuf from its succeeding pbufs in the chain. - * - * Makes p->tot_len field equal to p->len. - * @param p pbuf to dechain - * @return remainder of the pbuf chain, or NULL if it was de-allocated. - * @note May not be called on a packet queue. - */ -struct pbuf * -pbuf_dechain(struct pbuf *p) -{ - struct pbuf *q; - u8_t tail_gone = 1; - /* tail */ - q = p->next; - /* pbuf has successor in chain? */ - if (q != NULL) { - /* assert tot_len invariant: (p->tot_len == p->len + (p->next? p->next->tot_len: 0) */ - LWIP_ASSERT("p->tot_len == p->len + q->tot_len", q->tot_len == p->tot_len - p->len); - /* enforce invariant if assertion is disabled */ - q->tot_len = (u16_t)(p->tot_len - p->len); - /* decouple pbuf from remainder */ - p->next = NULL; - /* total length of pbuf p is its own length only */ - p->tot_len = p->len; - /* q is no longer referenced by p, free it */ - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_dechain: unreferencing %p\n", (void *)q)); - tail_gone = pbuf_free(q); - if (tail_gone > 0) { - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, - ("pbuf_dechain: deallocated %p (as it is no longer referenced)\n", (void *)q)); - } - /* return remaining tail or NULL if deallocated */ - } - /* assert tot_len invariant: (p->tot_len == p->len + (p->next? p->next->tot_len: 0) */ - LWIP_ASSERT("p->tot_len == p->len", p->tot_len == p->len); - return ((tail_gone > 0) ? NULL : q); -} - -/** - * @ingroup pbuf - * Create PBUF_RAM copies of pbufs. - * - * Used to queue packets on behalf of the lwIP stack, such as - * ARP based queueing. - * - * @note You MUST explicitly use p = pbuf_take(p); - * - * @note Only one packet is copied, no packet queue! - * - * @param p_to pbuf destination of the copy - * @param p_from pbuf source of the copy - * - * @return ERR_OK if pbuf was copied - * ERR_ARG if one of the pbufs is NULL or p_to is not big - * enough to hold p_from - */ -err_t -pbuf_copy(struct pbuf *p_to, const struct pbuf *p_from) -{ - size_t offset_to = 0, offset_from = 0, len; - - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy(%p, %p)\n", - (const void *)p_to, (const void *)p_from)); - - /* is the target big enough to hold the source? */ - LWIP_ERROR("pbuf_copy: target not big enough to hold source", ((p_to != NULL) && - (p_from != NULL) && (p_to->tot_len >= p_from->tot_len)), return ERR_ARG;); - - /* iterate through pbuf chain */ - do { - /* copy one part of the original chain */ - if ((p_to->len - offset_to) >= (p_from->len - offset_from)) { - /* complete current p_from fits into current p_to */ - len = p_from->len - offset_from; - } else { - /* current p_from does not fit into current p_to */ - len = p_to->len - offset_to; - } - MEMCPY((u8_t *)p_to->payload + offset_to, (u8_t *)p_from->payload + offset_from, len); - offset_to += len; - offset_from += len; - LWIP_ASSERT("offset_to <= p_to->len", offset_to <= p_to->len); - LWIP_ASSERT("offset_from <= p_from->len", offset_from <= p_from->len); - if (offset_from >= p_from->len) { - /* on to next p_from (if any) */ - offset_from = 0; - p_from = p_from->next; - } - if (offset_to == p_to->len) { - /* on to next p_to (if any) */ - offset_to = 0; - p_to = p_to->next; - LWIP_ERROR("p_to != NULL", (p_to != NULL) || (p_from == NULL), return ERR_ARG;); - } - - if ((p_from != NULL) && (p_from->len == p_from->tot_len)) { - /* don't copy more than one packet! */ - LWIP_ERROR("pbuf_copy() does not allow packet queues!", - (p_from->next == NULL), return ERR_VAL;); - } - if ((p_to != NULL) && (p_to->len == p_to->tot_len)) { - /* don't copy more than one packet! */ - LWIP_ERROR("pbuf_copy() does not allow packet queues!", - (p_to->next == NULL), return ERR_VAL;); - } - } while (p_from); - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy: end of chain reached.\n")); - return ERR_OK; -} - -/** - * @ingroup pbuf - * Copy (part of) the contents of a packet buffer - * to an application supplied buffer. - * - * @param buf the pbuf from which to copy data - * @param dataptr the application supplied buffer - * @param len length of data to copy (dataptr must be big enough). No more - * than buf->tot_len will be copied, irrespective of len - * @param offset offset into the packet buffer from where to begin copying len bytes - * @return the number of bytes copied, or 0 on failure - */ -u16_t -pbuf_copy_partial(const struct pbuf *buf, void *dataptr, u16_t len, u16_t offset) -{ - const struct pbuf *p; - u16_t left = 0; - u16_t buf_copy_len; - u16_t copied_total = 0; - - LWIP_ERROR("pbuf_copy_partial: invalid buf", (buf != NULL), return 0;); - LWIP_ERROR("pbuf_copy_partial: invalid dataptr", (dataptr != NULL), return 0;); - - /* Note some systems use byte copy if dataptr or one of the pbuf payload pointers are unaligned. */ - for (p = buf; len != 0 && p != NULL; p = p->next) { - if ((offset != 0) && (offset >= p->len)) { - /* don't copy from this buffer -> on to the next */ - offset = (u16_t)(offset - p->len); - } else { - /* copy from this buffer. maybe only partially. */ - buf_copy_len = (u16_t)(p->len - offset); - if (buf_copy_len > len) { - buf_copy_len = len; - } - /* copy the necessary parts of the buffer */ - MEMCPY(&((char *)dataptr)[left], &((char *)p->payload)[offset], buf_copy_len); - copied_total = (u16_t)(copied_total + buf_copy_len); - left = (u16_t)(left + buf_copy_len); - len = (u16_t)(len - buf_copy_len); - offset = 0; - } - } - return copied_total; -} - -/** - * @ingroup pbuf - * Get part of a pbuf's payload as contiguous memory. The returned memory is - * either a pointer into the pbuf's payload or, if split over multiple pbufs, - * a copy into the user-supplied buffer. - * - * @param p the pbuf from which to copy data - * @param buffer the application supplied buffer - * @param bufsize size of the application supplied buffer - * @param len length of data to copy (dataptr must be big enough). No more - * than buf->tot_len will be copied, irrespective of len - * @param offset offset into the packet buffer from where to begin copying len bytes - * @return the number of bytes copied, or 0 on failure - */ -void * -pbuf_get_contiguous(const struct pbuf *p, void *buffer, size_t bufsize, u16_t len, u16_t offset) -{ - const struct pbuf *q; - u16_t out_offset; - - LWIP_ERROR("pbuf_get_contiguous: invalid buf", (p != NULL), return NULL;); - LWIP_ERROR("pbuf_get_contiguous: invalid dataptr", (buffer != NULL), return NULL;); - LWIP_ERROR("pbuf_get_contiguous: invalid dataptr", (bufsize >= len), return NULL;); - - q = pbuf_skip_const(p, offset, &out_offset); - if (q != NULL) { - if (q->len >= (out_offset + len)) { - /* all data in this pbuf, return zero-copy */ - return (u8_t *)q->payload + out_offset; - } - /* need to copy */ - if (pbuf_copy_partial(q, buffer, len, out_offset) != len) { - /* copying failed: pbuf is too short */ - return NULL; - } - return buffer; - } - /* pbuf is too short (offset does not fit in) */ - return NULL; -} - -#if LWIP_TCP && TCP_QUEUE_OOSEQ && LWIP_WND_SCALE -/** - * This method modifies a 'pbuf chain', so that its total length is - * smaller than 64K. The remainder of the original pbuf chain is stored - * in *rest. - * This function never creates new pbufs, but splits an existing chain - * in two parts. The tot_len of the modified packet queue will likely be - * smaller than 64K. - * 'packet queues' are not supported by this function. - * - * @param p the pbuf queue to be split - * @param rest pointer to store the remainder (after the first 64K) - */ -void pbuf_split_64k(struct pbuf *p, struct pbuf **rest) -{ - *rest = NULL; - if ((p != NULL) && (p->next != NULL)) { - u16_t tot_len_front = p->len; - struct pbuf *i = p; - struct pbuf *r = p->next; - - /* continue until the total length (summed up as u16_t) overflows */ - while ((r != NULL) && ((u16_t)(tot_len_front + r->len) >= tot_len_front)) { - tot_len_front = (u16_t)(tot_len_front + r->len); - i = r; - r = r->next; - } - /* i now points to last packet of the first segment. Set next - pointer to NULL */ - i->next = NULL; - - if (r != NULL) { - /* Update the tot_len field in the first part */ - for (i = p; i != NULL; i = i->next) { - i->tot_len = (u16_t)(i->tot_len - r->tot_len); - LWIP_ASSERT("tot_len/len mismatch in last pbuf", - (i->next != NULL) || (i->tot_len == i->len)); - } - if (p->flags & PBUF_FLAG_TCP_FIN) { - r->flags |= PBUF_FLAG_TCP_FIN; - } - - /* tot_len field in rest does not need modifications */ - /* reference counters do not need modifications */ - *rest = r; - } - } -} -#endif /* LWIP_TCP && TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ - -/* Actual implementation of pbuf_skip() but returning const pointer... */ -static const struct pbuf * -pbuf_skip_const(const struct pbuf *in, u16_t in_offset, u16_t *out_offset) -{ - u16_t offset_left = in_offset; - const struct pbuf *q = in; - - /* get the correct pbuf */ - while ((q != NULL) && (q->len <= offset_left)) { - offset_left = (u16_t)(offset_left - q->len); - q = q->next; - } - if (out_offset != NULL) { - *out_offset = offset_left; - } - return q; -} - -/** - * @ingroup pbuf - * Skip a number of bytes at the start of a pbuf - * - * @param in input pbuf - * @param in_offset offset to skip - * @param out_offset resulting offset in the returned pbuf - * @return the pbuf in the queue where the offset is - */ -struct pbuf * -pbuf_skip(struct pbuf *in, u16_t in_offset, u16_t *out_offset) -{ - const struct pbuf *out = pbuf_skip_const(in, in_offset, out_offset); - return LWIP_CONST_CAST(struct pbuf *, out); -} - -/** - * @ingroup pbuf - * Copy application supplied data into a pbuf. - * This function can only be used to copy the equivalent of buf->tot_len data. - * - * @param buf pbuf to fill with data - * @param dataptr application supplied data buffer - * @param len length of the application supplied data buffer - * - * @return ERR_OK if successful, ERR_MEM if the pbuf is not big enough - */ -err_t -pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len) -{ - struct pbuf *p; - size_t buf_copy_len; - size_t total_copy_len = len; - size_t copied_total = 0; - - LWIP_ERROR("pbuf_take: invalid buf", (buf != NULL), return ERR_ARG;); - LWIP_ERROR("pbuf_take: invalid dataptr", (dataptr != NULL), return ERR_ARG;); - LWIP_ERROR("pbuf_take: buf not large enough", (buf->tot_len >= len), return ERR_MEM;); - - if ((buf == NULL) || (dataptr == NULL) || (buf->tot_len < len)) { - return ERR_ARG; - } - - /* Note some systems use byte copy if dataptr or one of the pbuf payload pointers are unaligned. */ - for (p = buf; total_copy_len != 0; p = p->next) { - LWIP_ASSERT("pbuf_take: invalid pbuf", p != NULL); - buf_copy_len = total_copy_len; - if (buf_copy_len > p->len) { - /* this pbuf cannot hold all remaining data */ - buf_copy_len = p->len; - } - /* copy the necessary parts of the buffer */ - MEMCPY(p->payload, &((const char *)dataptr)[copied_total], buf_copy_len); - total_copy_len -= buf_copy_len; - copied_total += buf_copy_len; - } - LWIP_ASSERT("did not copy all data", total_copy_len == 0 && copied_total == len); - return ERR_OK; -} - -/** - * @ingroup pbuf - * Same as pbuf_take() but puts data at an offset - * - * @param buf pbuf to fill with data - * @param dataptr application supplied data buffer - * @param len length of the application supplied data buffer - * @param offset offset in pbuf where to copy dataptr to - * - * @return ERR_OK if successful, ERR_MEM if the pbuf is not big enough - */ -err_t -pbuf_take_at(struct pbuf *buf, const void *dataptr, u16_t len, u16_t offset) -{ - u16_t target_offset; - struct pbuf *q = pbuf_skip(buf, offset, &target_offset); - - /* return requested data if pbuf is OK */ - if ((q != NULL) && (q->tot_len >= target_offset + len)) { - u16_t remaining_len = len; - const u8_t *src_ptr = (const u8_t *)dataptr; - /* copy the part that goes into the first pbuf */ - u16_t first_copy_len; - LWIP_ASSERT("check pbuf_skip result", target_offset < q->len); - first_copy_len = (u16_t)LWIP_MIN(q->len - target_offset, len); - MEMCPY(((u8_t *)q->payload) + target_offset, dataptr, first_copy_len); - remaining_len = (u16_t)(remaining_len - first_copy_len); - src_ptr += first_copy_len; - if (remaining_len > 0) { - return pbuf_take(q->next, src_ptr, remaining_len); - } - return ERR_OK; - } - return ERR_MEM; -} - -/** - * @ingroup pbuf - * Creates a single pbuf out of a queue of pbufs. - * - * @remark: Either the source pbuf 'p' is freed by this function or the original - * pbuf 'p' is returned, therefore the caller has to check the result! - * - * @param p the source pbuf - * @param layer pbuf_layer of the new pbuf - * - * @return a new, single pbuf (p->next is NULL) - * or the old pbuf if allocation fails - */ -struct pbuf * -pbuf_coalesce(struct pbuf *p, pbuf_layer layer) -{ - struct pbuf *q; - if (p->next == NULL) { - return p; - } - q = pbuf_clone(layer, PBUF_RAM, p); - if (q == NULL) { - /* @todo: what do we do now? */ - return p; - } - pbuf_free(p); - return q; -} - -/** - * @ingroup pbuf - * Allocates a new pbuf of same length (via pbuf_alloc()) and copies the source - * pbuf into this new pbuf (using pbuf_copy()). - * - * @param layer pbuf_layer of the new pbuf - * @param type this parameter decides how and where the pbuf should be allocated - * (@see pbuf_alloc()) - * @param p the source pbuf - * - * @return a new pbuf or NULL if allocation fails - */ -struct pbuf * -pbuf_clone(pbuf_layer layer, pbuf_type type, struct pbuf *p) -{ - struct pbuf *q; - err_t err; - q = pbuf_alloc(layer, p->tot_len, type); - if (q == NULL) { - return NULL; - } - err = pbuf_copy(q, p); - LWIP_UNUSED_ARG(err); /* in case of LWIP_NOASSERT */ - LWIP_ASSERT("pbuf_copy failed", err == ERR_OK); - return q; -} - -#if LWIP_CHECKSUM_ON_COPY -/** - * Copies data into a single pbuf (*not* into a pbuf queue!) and updates - * the checksum while copying - * - * @param p the pbuf to copy data into - * @param start_offset offset of p->payload where to copy the data to - * @param dataptr data to copy into the pbuf - * @param len length of data to copy into the pbuf - * @param chksum pointer to the checksum which is updated - * @return ERR_OK if successful, another error if the data does not fit - * within the (first) pbuf (no pbuf queues!) - */ -err_t -pbuf_fill_chksum(struct pbuf *p, u16_t start_offset, const void *dataptr, - u16_t len, u16_t *chksum) -{ - u32_t acc; - u16_t copy_chksum; - char *dst_ptr; - LWIP_ASSERT("p != NULL", p != NULL); - LWIP_ASSERT("dataptr != NULL", dataptr != NULL); - LWIP_ASSERT("chksum != NULL", chksum != NULL); - LWIP_ASSERT("len != 0", len != 0); - - if ((start_offset >= p->len) || (start_offset + len > p->len)) { - return ERR_ARG; - } - - dst_ptr = ((char *)p->payload) + start_offset; - copy_chksum = LWIP_CHKSUM_COPY(dst_ptr, dataptr, len); - if ((start_offset & 1) != 0) { - copy_chksum = SWAP_BYTES_IN_WORD(copy_chksum); - } - acc = *chksum; - acc += copy_chksum; - *chksum = FOLD_U32T(acc); - return ERR_OK; -} -#endif /* LWIP_CHECKSUM_ON_COPY */ - -/** - * @ingroup pbuf - * Get one byte from the specified position in a pbuf - * WARNING: returns zero for offset >= p->tot_len - * - * @param p pbuf to parse - * @param offset offset into p of the byte to return - * @return byte at an offset into p OR ZERO IF 'offset' >= p->tot_len - */ -u8_t -pbuf_get_at(const struct pbuf *p, u16_t offset) -{ - int ret = pbuf_try_get_at(p, offset); - if (ret >= 0) { - return (u8_t)ret; - } - return 0; -} - -/** - * @ingroup pbuf - * Get one byte from the specified position in a pbuf - * - * @param p pbuf to parse - * @param offset offset into p of the byte to return - * @return byte at an offset into p [0..0xFF] OR negative if 'offset' >= p->tot_len - */ -int -pbuf_try_get_at(const struct pbuf *p, u16_t offset) -{ - u16_t q_idx; - const struct pbuf *q = pbuf_skip_const(p, offset, &q_idx); - - /* return requested data if pbuf is OK */ - if ((q != NULL) && (q->len > q_idx)) { - return ((u8_t *)q->payload)[q_idx]; - } - return -1; -} - -/** - * @ingroup pbuf - * Put one byte to the specified position in a pbuf - * WARNING: silently ignores offset >= p->tot_len - * - * @param p pbuf to fill - * @param offset offset into p of the byte to write - * @param data byte to write at an offset into p - */ -void -pbuf_put_at(struct pbuf *p, u16_t offset, u8_t data) -{ - u16_t q_idx; - struct pbuf *q = pbuf_skip(p, offset, &q_idx); - - /* write requested data if pbuf is OK */ - if ((q != NULL) && (q->len > q_idx)) { - ((u8_t *)q->payload)[q_idx] = data; - } -} - -/** - * @ingroup pbuf - * Compare pbuf contents at specified offset with memory s2, both of length n - * - * @param p pbuf to compare - * @param offset offset into p at which to start comparing - * @param s2 buffer to compare - * @param n length of buffer to compare - * @return zero if equal, nonzero otherwise - * (0xffff if p is too short, diffoffset+1 otherwise) - */ -u16_t -pbuf_memcmp(const struct pbuf *p, u16_t offset, const void *s2, u16_t n) -{ - u16_t start = offset; - const struct pbuf *q = p; - u16_t i; - - /* pbuf long enough to perform check? */ - if (p->tot_len < (offset + n)) { - return 0xffff; - } - - /* get the correct pbuf from chain. We know it succeeds because of p->tot_len check above. */ - while ((q != NULL) && (q->len <= start)) { - start = (u16_t)(start - q->len); - q = q->next; - } - - /* return requested data if pbuf is OK */ - for (i = 0; i < n; i++) { - /* We know pbuf_get_at() succeeds because of p->tot_len check above. */ - u8_t a = pbuf_get_at(q, (u16_t)(start + i)); - u8_t b = ((const u8_t *)s2)[i]; - if (a != b) { - return (u16_t)LWIP_MIN(i + 1, 0xFFFF); - } - } - return 0; -} - -/** - * @ingroup pbuf - * Find occurrence of mem (with length mem_len) in pbuf p, starting at offset - * start_offset. - * - * @param p pbuf to search, maximum length is 0xFFFE since 0xFFFF is used as - * return value 'not found' - * @param mem search for the contents of this buffer - * @param mem_len length of 'mem' - * @param start_offset offset into p at which to start searching - * @return 0xFFFF if substr was not found in p or the index where it was found - */ -u16_t -pbuf_memfind(const struct pbuf *p, const void *mem, u16_t mem_len, u16_t start_offset) -{ - u16_t i; - u16_t max_cmp_start = (u16_t)(p->tot_len - mem_len); - if (p->tot_len >= mem_len + start_offset) { - for (i = start_offset; i <= max_cmp_start; i++) { - u16_t plus = pbuf_memcmp(p, i, mem, mem_len); - if (plus == 0) { - return i; - } - } - } - return 0xFFFF; -} - -/** - * Find occurrence of substr with length substr_len in pbuf p, start at offset - * start_offset - * WARNING: in contrast to strstr(), this one does not stop at the first \0 in - * the pbuf/source string! - * - * @param p pbuf to search, maximum length is 0xFFFE since 0xFFFF is used as - * return value 'not found' - * @param substr string to search for in p, maximum length is 0xFFFE - * @return 0xFFFF if substr was not found in p or the index where it was found - */ -u16_t -pbuf_strstr(const struct pbuf *p, const char *substr) -{ - size_t substr_len; - if ((substr == NULL) || (substr[0] == 0) || (p->tot_len == 0xFFFF)) { - return 0xFFFF; - } - substr_len = strlen(substr); - if (substr_len >= 0xFFFF) { - return 0xFFFF; - } - return pbuf_memfind(p, substr, (u16_t)substr_len, 0); -} diff --git a/third-party/lwip-2.1.2/core/raw.c b/third-party/lwip-2.1.2/core/raw.c deleted file mode 100644 index 3b34544b..00000000 --- a/third-party/lwip-2.1.2/core/raw.c +++ /dev/null @@ -1,671 +0,0 @@ -/** - * @file - * Implementation of raw protocol PCBs for low-level handling of - * different types of protocols besides (or overriding) those - * already available in lwIP.\n - * See also @ref raw_raw - * - * @defgroup raw_raw RAW - * @ingroup callbackstyle_api - * Implementation of raw protocol PCBs for low-level handling of - * different types of protocols besides (or overriding) those - * already available in lwIP.\n - * @see @ref api - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#include "lwip/opt.h" - -#if LWIP_RAW /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/def.h" -#include "lwip/memp.h" -#include "lwip/ip_addr.h" -#include "lwip/netif.h" -#include "lwip/raw.h" -#include "lwip/priv/raw_priv.h" -#include "lwip/stats.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#include "lwip/inet_chksum.h" - -#include - -/** The list of RAW PCBs */ -static struct raw_pcb *raw_pcbs; - -static u8_t -raw_input_local_match(struct raw_pcb *pcb, u8_t broadcast) -{ - LWIP_UNUSED_ARG(broadcast); /* in IPv6 only case */ - - /* check if PCB is bound to specific netif */ - if ((pcb->netif_idx != NETIF_NO_INDEX) && - (pcb->netif_idx != netif_get_index(ip_data.current_input_netif))) { - return 0; - } - -#if LWIP_IPV4 && LWIP_IPV6 - /* Dual-stack: PCBs listening to any IP type also listen to any IP address */ - if (IP_IS_ANY_TYPE_VAL(pcb->local_ip)) { -#if IP_SOF_BROADCAST_RECV - if ((broadcast != 0) && !ip_get_option(pcb, SOF_BROADCAST)) { - return 0; - } -#endif /* IP_SOF_BROADCAST_RECV */ - return 1; - } -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - - /* Only need to check PCB if incoming IP version matches PCB IP version */ - if (IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ip_current_dest_addr())) { -#if LWIP_IPV4 - /* Special case: IPv4 broadcast: receive all broadcasts - * Note: broadcast variable can only be 1 if it is an IPv4 broadcast */ - if (broadcast != 0) { -#if IP_SOF_BROADCAST_RECV - if (ip_get_option(pcb, SOF_BROADCAST)) -#endif /* IP_SOF_BROADCAST_RECV */ - { - if (ip4_addr_isany(ip_2_ip4(&pcb->local_ip))) { - return 1; - } - } - } else -#endif /* LWIP_IPV4 */ - /* Handle IPv4 and IPv6: catch all or exact match */ - if (ip_addr_isany(&pcb->local_ip) || - ip_addr_cmp(&pcb->local_ip, ip_current_dest_addr())) { - return 1; - } - } - - return 0; -} - -/** - * Determine if in incoming IP packet is covered by a RAW PCB - * and if so, pass it to a user-provided receive callback function. - * - * Given an incoming IP datagram (as a chain of pbufs) this function - * finds a corresponding RAW PCB and calls the corresponding receive - * callback function. - * - * @param p pbuf to be demultiplexed to a RAW PCB. - * @param inp network interface on which the datagram was received. - * @return - 1 if the packet has been eaten by a RAW PCB receive - * callback function. The caller MAY NOT not reference the - * packet any longer, and MAY NOT call pbuf_free(). - * @return - 0 if packet is not eaten (pbuf is still referenced by the - * caller). - * - */ -raw_input_state_t -raw_input(struct pbuf *p, struct netif *inp) -{ - struct raw_pcb *pcb, *prev; - s16_t proto; - raw_input_state_t ret = RAW_INPUT_NONE; - u8_t broadcast = ip_addr_isbroadcast(ip_current_dest_addr(), ip_current_netif()); - - LWIP_UNUSED_ARG(inp); - -#if LWIP_IPV6 -#if LWIP_IPV4 - if (IP_HDR_GET_VERSION(p->payload) == 6) -#endif /* LWIP_IPV4 */ - { - struct ip6_hdr *ip6hdr = (struct ip6_hdr *)p->payload; - proto = IP6H_NEXTH(ip6hdr); - } -#if LWIP_IPV4 - else -#endif /* LWIP_IPV4 */ -#endif /* LWIP_IPV6 */ -#if LWIP_IPV4 - { - proto = IPH_PROTO((struct ip_hdr *)p->payload); - } -#endif /* LWIP_IPV4 */ - - prev = NULL; - pcb = raw_pcbs; - /* loop through all raw pcbs until the packet is eaten by one */ - /* this allows multiple pcbs to match against the packet by design */ - while (pcb != NULL) { - if ((pcb->protocol == proto) && raw_input_local_match(pcb, broadcast) && - (((pcb->flags & RAW_FLAGS_CONNECTED) == 0) || - ip_addr_cmp(&pcb->remote_ip, ip_current_src_addr()))) { - /* receive callback function available? */ - if (pcb->recv != NULL) { - u8_t eaten; -#ifndef LWIP_NOASSERT - void *old_payload = p->payload; -#endif - ret = RAW_INPUT_DELIVERED; - /* the receive callback function did not eat the packet? */ - eaten = pcb->recv(pcb->recv_arg, pcb, p, ip_current_src_addr()); - if (eaten != 0) { - /* receive function ate the packet */ - p = NULL; - if (prev != NULL) { - /* move the pcb to the front of raw_pcbs so that is - found faster next time */ - prev->next = pcb->next; - pcb->next = raw_pcbs; - raw_pcbs = pcb; - } - return RAW_INPUT_EATEN; - } else { - /* sanity-check that the receive callback did not alter the pbuf */ - LWIP_ASSERT("raw pcb recv callback altered pbuf payload pointer without eating packet", - p->payload == old_payload); - } - } - /* no receive callback function was set for this raw PCB */ - } - /* drop the packet */ - prev = pcb; - pcb = pcb->next; - } - return ret; -} - -/** - * @ingroup raw_raw - * Bind a RAW PCB. - * - * @param pcb RAW PCB to be bound with a local address ipaddr. - * @param ipaddr local IP address to bind with. Use IP4_ADDR_ANY to - * bind to all local interfaces. - * - * @return lwIP error code. - * - ERR_OK. Successful. No error occurred. - * - ERR_USE. The specified IP address is already bound to by - * another RAW PCB. - * - * @see raw_disconnect() - */ -err_t -raw_bind(struct raw_pcb *pcb, const ip_addr_t *ipaddr) -{ - LWIP_ASSERT_CORE_LOCKED(); - if ((pcb == NULL) || (ipaddr == NULL)) { - return ERR_VAL; - } - ip_addr_set_ipaddr(&pcb->local_ip, ipaddr); -#if LWIP_IPV6 && LWIP_IPV6_SCOPES - /* If the given IP address should have a zone but doesn't, assign one now. - * This is legacy support: scope-aware callers should always provide properly - * zoned source addresses. */ - if (IP_IS_V6(&pcb->local_ip) && - ip6_addr_lacks_zone(ip_2_ip6(&pcb->local_ip), IP6_UNKNOWN)) { - ip6_addr_select_zone(ip_2_ip6(&pcb->local_ip), ip_2_ip6(&pcb->local_ip)); - } -#endif /* LWIP_IPV6 && LWIP_IPV6_SCOPES */ - return ERR_OK; -} - -/** - * @ingroup raw_raw - * Bind an RAW PCB to a specific netif. - * After calling this function, all packets received via this PCB - * are guaranteed to have come in via the specified netif, and all - * outgoing packets will go out via the specified netif. - * - * @param pcb RAW PCB to be bound with netif. - * @param netif netif to bind to. Can be NULL. - * - * @see raw_disconnect() - */ -void -raw_bind_netif(struct raw_pcb *pcb, const struct netif *netif) -{ - LWIP_ASSERT_CORE_LOCKED(); - if (netif != NULL) { - pcb->netif_idx = netif_get_index(netif); - } else { - pcb->netif_idx = NETIF_NO_INDEX; - } -} - -/** - * @ingroup raw_raw - * Connect an RAW PCB. This function is required by upper layers - * of lwip. Using the raw api you could use raw_sendto() instead - * - * This will associate the RAW PCB with the remote address. - * - * @param pcb RAW PCB to be connected with remote address ipaddr and port. - * @param ipaddr remote IP address to connect with. - * - * @return lwIP error code - * - * @see raw_disconnect() and raw_sendto() - */ -err_t -raw_connect(struct raw_pcb *pcb, const ip_addr_t *ipaddr) -{ - LWIP_ASSERT_CORE_LOCKED(); - if ((pcb == NULL) || (ipaddr == NULL)) { - return ERR_VAL; - } - ip_addr_set_ipaddr(&pcb->remote_ip, ipaddr); -#if LWIP_IPV6 && LWIP_IPV6_SCOPES - /* If the given IP address should have a zone but doesn't, assign one now, - * using the bound address to make a more informed decision when possible. */ - if (IP_IS_V6(&pcb->remote_ip) && - ip6_addr_lacks_zone(ip_2_ip6(&pcb->remote_ip), IP6_UNKNOWN)) { - ip6_addr_select_zone(ip_2_ip6(&pcb->remote_ip), ip_2_ip6(&pcb->local_ip)); - } -#endif /* LWIP_IPV6 && LWIP_IPV6_SCOPES */ - raw_set_flags(pcb, RAW_FLAGS_CONNECTED); - return ERR_OK; -} - -/** - * @ingroup raw_raw - * Disconnect a RAW PCB. - * - * @param pcb the raw pcb to disconnect. - */ -void -raw_disconnect(struct raw_pcb *pcb) -{ - LWIP_ASSERT_CORE_LOCKED(); - /* reset remote address association */ -#if LWIP_IPV4 && LWIP_IPV6 - if (IP_IS_ANY_TYPE_VAL(pcb->local_ip)) { - ip_addr_copy(pcb->remote_ip, *IP_ANY_TYPE); - } else { -#endif - ip_addr_set_any(IP_IS_V6_VAL(pcb->remote_ip), &pcb->remote_ip); -#if LWIP_IPV4 && LWIP_IPV6 - } -#endif - pcb->netif_idx = NETIF_NO_INDEX; - /* mark PCB as unconnected */ - raw_clear_flags(pcb, RAW_FLAGS_CONNECTED); -} - -/** - * @ingroup raw_raw - * Set the callback function for received packets that match the - * raw PCB's protocol and binding. - * - * The callback function MUST either - * - eat the packet by calling pbuf_free() and returning non-zero. The - * packet will not be passed to other raw PCBs or other protocol layers. - * - not free the packet, and return zero. The packet will be matched - * against further PCBs and/or forwarded to another protocol layers. - */ -void -raw_recv(struct raw_pcb *pcb, raw_recv_fn recv, void *recv_arg) -{ - LWIP_ASSERT_CORE_LOCKED(); - /* remember recv() callback and user data */ - pcb->recv = recv; - pcb->recv_arg = recv_arg; -} - -/** - * @ingroup raw_raw - * Send the raw IP packet to the given address. An IP header will be prepended - * to the packet, unless the RAW_FLAGS_HDRINCL flag is set on the PCB. In that - * case, the packet must include an IP header, which will then be sent as is. - * - * @param pcb the raw pcb which to send - * @param p the IP payload to send - * @param ipaddr the destination address of the IP packet - * - */ -err_t -raw_sendto(struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *ipaddr) -{ - struct netif *netif; - const ip_addr_t *src_ip; - - if ((pcb == NULL) || (ipaddr == NULL) || !IP_ADDR_PCB_VERSION_MATCH(pcb, ipaddr)) { - return ERR_VAL; - } - - LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_sendto\n")); - - if (pcb->netif_idx != NETIF_NO_INDEX) { - netif = netif_get_by_index(pcb->netif_idx); - } else { -#if LWIP_MULTICAST_TX_OPTIONS - netif = NULL; - if (ip_addr_ismulticast(ipaddr)) { - /* For multicast-destined packets, use the user-provided interface index to - * determine the outgoing interface, if an interface index is set and a - * matching netif can be found. Otherwise, fall back to regular routing. */ - netif = netif_get_by_index(pcb->mcast_ifindex); - } - - if (netif == NULL) -#endif /* LWIP_MULTICAST_TX_OPTIONS */ - { - netif = ip_route(&pcb->local_ip, ipaddr); - } - } - - if (netif == NULL) { - LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: No route to ")); - ip_addr_debug_print(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ipaddr); - return ERR_RTE; - } - - if (ip_addr_isany(&pcb->local_ip) || ip_addr_ismulticast(&pcb->local_ip)) { - /* use outgoing network interface IP address as source address */ - src_ip = ip_netif_get_local_ip(netif, ipaddr); -#if LWIP_IPV6 - if (src_ip == NULL) { - return ERR_RTE; - } -#endif /* LWIP_IPV6 */ - } else { - /* use RAW PCB local IP address as source address */ - src_ip = &pcb->local_ip; - } - - return raw_sendto_if_src(pcb, p, ipaddr, netif, src_ip); -} - -/** - * @ingroup raw_raw - * Send the raw IP packet to the given address, using a particular outgoing - * netif and source IP address. An IP header will be prepended to the packet, - * unless the RAW_FLAGS_HDRINCL flag is set on the PCB. In that case, the - * packet must include an IP header, which will then be sent as is. - * - * @param pcb RAW PCB used to send the data - * @param p chain of pbufs to be sent - * @param dst_ip destination IP address - * @param netif the netif used for sending - * @param src_ip source IP address - */ -err_t -raw_sendto_if_src(struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip, - struct netif *netif, const ip_addr_t *src_ip) -{ - err_t err; - struct pbuf *q; /* q will be sent down the stack */ - u16_t header_size; - u8_t ttl; - - LWIP_ASSERT_CORE_LOCKED(); - - if ((pcb == NULL) || (dst_ip == NULL) || (netif == NULL) || (src_ip == NULL) || - !IP_ADDR_PCB_VERSION_MATCH(pcb, src_ip) || !IP_ADDR_PCB_VERSION_MATCH(pcb, dst_ip)) { - return ERR_VAL; - } - - header_size = ( -#if LWIP_IPV4 && LWIP_IPV6 - IP_IS_V6(dst_ip) ? IP6_HLEN : IP_HLEN); -#elif LWIP_IPV4 - IP_HLEN); -#else - IP6_HLEN); -#endif - - /* Handle the HDRINCL option as an exception: none of the code below applies - * to this case, and sending the packet needs to be done differently too. */ - if (pcb->flags & RAW_FLAGS_HDRINCL) { - /* A full header *must* be present in the first pbuf of the chain, as the - * output routines may access its fields directly. */ - if (p->len < header_size) { - return ERR_VAL; - } - /* @todo multicast loop support, if at all desired for this scenario.. */ - NETIF_SET_HINTS(netif, &pcb->netif_hints); - err = ip_output_if_hdrincl(p, src_ip, dst_ip, netif); - NETIF_RESET_HINTS(netif); - return err; - } - - /* packet too large to add an IP header without causing an overflow? */ - if ((u16_t)(p->tot_len + header_size) < p->tot_len) { - return ERR_MEM; - } - /* not enough space to add an IP header to first pbuf in given p chain? */ - if (pbuf_add_header(p, header_size)) { - /* allocate header in new pbuf */ - q = pbuf_alloc(PBUF_IP, 0, PBUF_RAM); - /* new header pbuf could not be allocated? */ - if (q == NULL) { - LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("raw_sendto: could not allocate header\n")); - return ERR_MEM; - } - if (p->tot_len != 0) { - /* chain header q in front of given pbuf p */ - pbuf_chain(q, p); - } - /* { first pbuf q points to header pbuf } */ - LWIP_DEBUGF(RAW_DEBUG, ("raw_sendto: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p)); - } else { - /* first pbuf q equals given pbuf */ - q = p; - if (pbuf_remove_header(q, header_size)) { - LWIP_ASSERT("Can't restore header we just removed!", 0); - return ERR_MEM; - } - } - -#if IP_SOF_BROADCAST - if (IP_IS_V4(dst_ip)) { - /* broadcast filter? */ - if (!ip_get_option(pcb, SOF_BROADCAST) && ip_addr_isbroadcast(dst_ip, netif)) { - LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb)); - /* free any temporary header pbuf allocated by pbuf_header() */ - if (q != p) { - pbuf_free(q); - } - return ERR_VAL; - } - } -#endif /* IP_SOF_BROADCAST */ - - /* Multicast Loop? */ -#if LWIP_MULTICAST_TX_OPTIONS - if (((pcb->flags & RAW_FLAGS_MULTICAST_LOOP) != 0) && ip_addr_ismulticast(dst_ip)) { - q->flags |= PBUF_FLAG_MCASTLOOP; - } -#endif /* LWIP_MULTICAST_TX_OPTIONS */ - -#if LWIP_IPV6 - /* If requested, based on the IPV6_CHECKSUM socket option per RFC3542, - compute the checksum and update the checksum in the payload. */ - if (IP_IS_V6(dst_ip) && pcb->chksum_reqd) { - u16_t chksum = ip6_chksum_pseudo(p, pcb->protocol, p->tot_len, ip_2_ip6(src_ip), ip_2_ip6(dst_ip)); - LWIP_ASSERT("Checksum must fit into first pbuf", p->len >= (pcb->chksum_offset + 2)); - SMEMCPY(((u8_t *)p->payload) + pcb->chksum_offset, &chksum, sizeof(u16_t)); - } -#endif - - /* Determine TTL to use */ -#if LWIP_MULTICAST_TX_OPTIONS - ttl = (ip_addr_ismulticast(dst_ip) ? raw_get_multicast_ttl(pcb) : pcb->ttl); -#else /* LWIP_MULTICAST_TX_OPTIONS */ - ttl = pcb->ttl; -#endif /* LWIP_MULTICAST_TX_OPTIONS */ - - NETIF_SET_HINTS(netif, &pcb->netif_hints); - err = ip_output_if(q, src_ip, dst_ip, ttl, pcb->tos, pcb->protocol, netif); - NETIF_RESET_HINTS(netif); - - /* did we chain a header earlier? */ - if (q != p) { - /* free the header */ - pbuf_free(q); - } - return err; -} - -/** - * @ingroup raw_raw - * Send the raw IP packet to the address given by raw_connect() - * - * @param pcb the raw pcb which to send - * @param p the IP payload to send - * - */ -err_t -raw_send(struct raw_pcb *pcb, struct pbuf *p) -{ - return raw_sendto(pcb, p, &pcb->remote_ip); -} - -/** - * @ingroup raw_raw - * Remove an RAW PCB. - * - * @param pcb RAW PCB to be removed. The PCB is removed from the list of - * RAW PCB's and the data structure is freed from memory. - * - * @see raw_new() - */ -void -raw_remove(struct raw_pcb *pcb) -{ - struct raw_pcb *pcb2; - LWIP_ASSERT_CORE_LOCKED(); - /* pcb to be removed is first in list? */ - if (raw_pcbs == pcb) { - /* make list start at 2nd pcb */ - raw_pcbs = raw_pcbs->next; - /* pcb not 1st in list */ - } else { - for (pcb2 = raw_pcbs; pcb2 != NULL; pcb2 = pcb2->next) { - /* find pcb in raw_pcbs list */ - if (pcb2->next != NULL && pcb2->next == pcb) { - /* remove pcb from list */ - pcb2->next = pcb->next; - break; - } - } - } - memp_free(MEMP_RAW_PCB, pcb); -} - -/** - * @ingroup raw_raw - * Create a RAW PCB. - * - * @return The RAW PCB which was created. NULL if the PCB data structure - * could not be allocated. - * - * @param proto the protocol number of the IPs payload (e.g. IP_PROTO_ICMP) - * - * @see raw_remove() - */ -struct raw_pcb * -raw_new(u8_t proto) -{ - struct raw_pcb *pcb; - - LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_new\n")); - LWIP_ASSERT_CORE_LOCKED(); - - pcb = (struct raw_pcb *)memp_malloc(MEMP_RAW_PCB); - /* could allocate RAW PCB? */ - if (pcb != NULL) { - /* initialize PCB to all zeroes */ - memset(pcb, 0, sizeof(struct raw_pcb)); - pcb->protocol = proto; - pcb->ttl = RAW_TTL; -#if LWIP_MULTICAST_TX_OPTIONS - raw_set_multicast_ttl(pcb, RAW_TTL); -#endif /* LWIP_MULTICAST_TX_OPTIONS */ - pcb->next = raw_pcbs; - raw_pcbs = pcb; - } - return pcb; -} - -/** - * @ingroup raw_raw - * Create a RAW PCB for specific IP type. - * - * @return The RAW PCB which was created. NULL if the PCB data structure - * could not be allocated. - * - * @param type IP address type, see @ref lwip_ip_addr_type definitions. - * If you want to listen to IPv4 and IPv6 (dual-stack) packets, - * supply @ref IPADDR_TYPE_ANY as argument and bind to @ref IP_ANY_TYPE. - * @param proto the protocol number (next header) of the IPv6 packet payload - * (e.g. IP6_NEXTH_ICMP6) - * - * @see raw_remove() - */ -struct raw_pcb * -raw_new_ip_type(u8_t type, u8_t proto) -{ - struct raw_pcb *pcb; - LWIP_ASSERT_CORE_LOCKED(); - pcb = raw_new(proto); -#if LWIP_IPV4 && LWIP_IPV6 - if (pcb != NULL) { - IP_SET_TYPE_VAL(pcb->local_ip, type); - IP_SET_TYPE_VAL(pcb->remote_ip, type); - } -#else /* LWIP_IPV4 && LWIP_IPV6 */ - LWIP_UNUSED_ARG(type); -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - return pcb; -} - -/** This function is called from netif.c when address is changed - * - * @param old_addr IP address of the netif before change - * @param new_addr IP address of the netif after change - */ -void raw_netif_ip_addr_changed(const ip_addr_t *old_addr, const ip_addr_t *new_addr) -{ - struct raw_pcb *rpcb; - - if (!ip_addr_isany(old_addr) && !ip_addr_isany(new_addr)) { - for (rpcb = raw_pcbs; rpcb != NULL; rpcb = rpcb->next) { - /* PCB bound to current local interface address? */ - if (ip_addr_cmp(&rpcb->local_ip, old_addr)) { - /* The PCB is bound to the old ipaddr and - * is set to bound to the new one instead */ - ip_addr_copy(rpcb->local_ip, *new_addr); - } - } - } -} - -#endif /* LWIP_RAW */ diff --git a/third-party/lwip-2.1.2/core/stats.c b/third-party/lwip-2.1.2/core/stats.c deleted file mode 100644 index 34e9b270..00000000 --- a/third-party/lwip-2.1.2/core/stats.c +++ /dev/null @@ -1,169 +0,0 @@ -/** - * @file - * Statistics module - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#include "lwip/opt.h" - -#if LWIP_STATS /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/def.h" -#include "lwip/stats.h" -#include "lwip/mem.h" -#include "lwip/debug.h" - -#include - -struct stats_ lwip_stats; - -void -stats_init(void) -{ -#ifdef LWIP_DEBUG -#if MEM_STATS - lwip_stats.mem.name = "MEM"; -#endif /* MEM_STATS */ -#endif /* LWIP_DEBUG */ -} - -#if LWIP_STATS_DISPLAY -void -stats_display_proto(struct stats_proto *proto, const char *name) -{ - LWIP_PLATFORM_DIAG(("\n%s\n\t", name)); - LWIP_PLATFORM_DIAG(("xmit: %"STAT_COUNTER_F"\n\t", proto->xmit)); - LWIP_PLATFORM_DIAG(("recv: %"STAT_COUNTER_F"\n\t", proto->recv)); - LWIP_PLATFORM_DIAG(("fw: %"STAT_COUNTER_F"\n\t", proto->fw)); - LWIP_PLATFORM_DIAG(("drop: %"STAT_COUNTER_F"\n\t", proto->drop)); - LWIP_PLATFORM_DIAG(("chkerr: %"STAT_COUNTER_F"\n\t", proto->chkerr)); - LWIP_PLATFORM_DIAG(("lenerr: %"STAT_COUNTER_F"\n\t", proto->lenerr)); - LWIP_PLATFORM_DIAG(("memerr: %"STAT_COUNTER_F"\n\t", proto->memerr)); - LWIP_PLATFORM_DIAG(("rterr: %"STAT_COUNTER_F"\n\t", proto->rterr)); - LWIP_PLATFORM_DIAG(("proterr: %"STAT_COUNTER_F"\n\t", proto->proterr)); - LWIP_PLATFORM_DIAG(("opterr: %"STAT_COUNTER_F"\n\t", proto->opterr)); - LWIP_PLATFORM_DIAG(("err: %"STAT_COUNTER_F"\n\t", proto->err)); - LWIP_PLATFORM_DIAG(("cachehit: %"STAT_COUNTER_F"\n", proto->cachehit)); -} - -#if IGMP_STATS || MLD6_STATS -void -stats_display_igmp(struct stats_igmp *igmp, const char *name) -{ - LWIP_PLATFORM_DIAG(("\n%s\n\t", name)); - LWIP_PLATFORM_DIAG(("xmit: %"STAT_COUNTER_F"\n\t", igmp->xmit)); - LWIP_PLATFORM_DIAG(("recv: %"STAT_COUNTER_F"\n\t", igmp->recv)); - LWIP_PLATFORM_DIAG(("drop: %"STAT_COUNTER_F"\n\t", igmp->drop)); - LWIP_PLATFORM_DIAG(("chkerr: %"STAT_COUNTER_F"\n\t", igmp->chkerr)); - LWIP_PLATFORM_DIAG(("lenerr: %"STAT_COUNTER_F"\n\t", igmp->lenerr)); - LWIP_PLATFORM_DIAG(("memerr: %"STAT_COUNTER_F"\n\t", igmp->memerr)); - LWIP_PLATFORM_DIAG(("proterr: %"STAT_COUNTER_F"\n\t", igmp->proterr)); - LWIP_PLATFORM_DIAG(("rx_v1: %"STAT_COUNTER_F"\n\t", igmp->rx_v1)); - LWIP_PLATFORM_DIAG(("rx_group: %"STAT_COUNTER_F"\n\t", igmp->rx_group)); - LWIP_PLATFORM_DIAG(("rx_general: %"STAT_COUNTER_F"\n\t", igmp->rx_general)); - LWIP_PLATFORM_DIAG(("rx_report: %"STAT_COUNTER_F"\n\t", igmp->rx_report)); - LWIP_PLATFORM_DIAG(("tx_join: %"STAT_COUNTER_F"\n\t", igmp->tx_join)); - LWIP_PLATFORM_DIAG(("tx_leave: %"STAT_COUNTER_F"\n\t", igmp->tx_leave)); - LWIP_PLATFORM_DIAG(("tx_report: %"STAT_COUNTER_F"\n", igmp->tx_report)); -} -#endif /* IGMP_STATS || MLD6_STATS */ - -#if MEM_STATS || MEMP_STATS -void -stats_display_mem(struct stats_mem *mem, const char *name) -{ - LWIP_PLATFORM_DIAG(("\nMEM %s\n\t", name)); - LWIP_PLATFORM_DIAG(("avail: %"MEM_SIZE_F"\n\t", mem->avail)); - LWIP_PLATFORM_DIAG(("used: %"MEM_SIZE_F"\n\t", mem->used)); - LWIP_PLATFORM_DIAG(("max: %"MEM_SIZE_F"\n\t", mem->max)); - LWIP_PLATFORM_DIAG(("err: %"STAT_COUNTER_F"\n", mem->err)); -} - -#if MEMP_STATS -void -stats_display_memp(struct stats_mem *mem, int idx) -{ - if (idx < MEMP_MAX) { - stats_display_mem(mem, mem->name); - } -} -#endif /* MEMP_STATS */ -#endif /* MEM_STATS || MEMP_STATS */ - -#if SYS_STATS -void -stats_display_sys(struct stats_sys *sys) -{ - LWIP_PLATFORM_DIAG(("\nSYS\n\t")); - LWIP_PLATFORM_DIAG(("sem.used: %"STAT_COUNTER_F"\n\t", sys->sem.used)); - LWIP_PLATFORM_DIAG(("sem.max: %"STAT_COUNTER_F"\n\t", sys->sem.max)); - LWIP_PLATFORM_DIAG(("sem.err: %"STAT_COUNTER_F"\n\t", sys->sem.err)); - LWIP_PLATFORM_DIAG(("mutex.used: %"STAT_COUNTER_F"\n\t", sys->mutex.used)); - LWIP_PLATFORM_DIAG(("mutex.max: %"STAT_COUNTER_F"\n\t", sys->mutex.max)); - LWIP_PLATFORM_DIAG(("mutex.err: %"STAT_COUNTER_F"\n\t", sys->mutex.err)); - LWIP_PLATFORM_DIAG(("mbox.used: %"STAT_COUNTER_F"\n\t", sys->mbox.used)); - LWIP_PLATFORM_DIAG(("mbox.max: %"STAT_COUNTER_F"\n\t", sys->mbox.max)); - LWIP_PLATFORM_DIAG(("mbox.err: %"STAT_COUNTER_F"\n", sys->mbox.err)); -} -#endif /* SYS_STATS */ - -void -stats_display(void) -{ - s16_t i; - - LINK_STATS_DISPLAY(); - ETHARP_STATS_DISPLAY(); - IPFRAG_STATS_DISPLAY(); - IP6_FRAG_STATS_DISPLAY(); - IP_STATS_DISPLAY(); - ND6_STATS_DISPLAY(); - IP6_STATS_DISPLAY(); - IGMP_STATS_DISPLAY(); - MLD6_STATS_DISPLAY(); - ICMP_STATS_DISPLAY(); - ICMP6_STATS_DISPLAY(); - UDP_STATS_DISPLAY(); - TCP_STATS_DISPLAY(); - MEM_STATS_DISPLAY(); - for (i = 0; i < MEMP_MAX; i++) { - MEMP_STATS_DISPLAY(i); - } - SYS_STATS_DISPLAY(); -} -#endif /* LWIP_STATS_DISPLAY */ - -#endif /* LWIP_STATS */ - diff --git a/third-party/lwip-2.1.2/core/sys.c b/third-party/lwip-2.1.2/core/sys.c deleted file mode 100644 index 5f08352b..00000000 --- a/third-party/lwip-2.1.2/core/sys.c +++ /dev/null @@ -1,148 +0,0 @@ -/** - * @file - * lwIP Operating System abstraction - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -/** - * @defgroup sys_layer Porting (system abstraction layer) - * @ingroup lwip - * - * @defgroup sys_os OS abstraction layer - * @ingroup sys_layer - * No need to implement functions in this section in NO_SYS mode. - * The OS-specific code should be implemented in arch/sys_arch.h - * and sys_arch.c of your port. - * - * The operating system emulation layer provides a common interface - * between the lwIP code and the underlying operating system kernel. The - * general idea is that porting lwIP to new architectures requires only - * small changes to a few header files and a new sys_arch - * implementation. It is also possible to do a sys_arch implementation - * that does not rely on any underlying operating system. - * - * The sys_arch provides semaphores, mailboxes and mutexes to lwIP. For the full - * lwIP functionality, multiple threads support can be implemented in the - * sys_arch, but this is not required for the basic lwIP - * functionality. Timer scheduling is implemented in lwIP, but can be implemented - * by the sys_arch port (LWIP_TIMERS_CUSTOM==1). - * - * In addition to the source file providing the functionality of sys_arch, - * the OS emulation layer must provide several header files defining - * macros used throughout lwip. The files required and the macros they - * must define are listed below the sys_arch description. - * - * Since lwIP 1.4.0, semaphore, mutexes and mailbox functions are prototyped in a way that - * allows both using pointers or actual OS structures to be used. This way, memory - * required for such types can be either allocated in place (globally or on the - * stack) or on the heap (allocated internally in the "*_new()" functions). - * - * Note: - * ----- - * Be careful with using mem_malloc() in sys_arch. When malloc() refers to - * mem_malloc() you can run into a circular function call problem. In mem.c - * mem_init() tries to allocate a semaphore using mem_malloc, which of course - * can't be performed when sys_arch uses mem_malloc. - * - * @defgroup sys_sem Semaphores - * @ingroup sys_os - * Semaphores can be either counting or binary - lwIP works with both - * kinds. - * Semaphores are represented by the type "sys_sem_t" which is typedef'd - * in the sys_arch.h file. Mailboxes are equivalently represented by the - * type "sys_mbox_t". Mutexes are represented by the type "sys_mutex_t". - * lwIP does not place any restrictions on how these types are represented - * internally. - * - * @defgroup sys_mutex Mutexes - * @ingroup sys_os - * Mutexes are recommended to correctly handle priority inversion, - * especially if you use LWIP_CORE_LOCKING . - * - * @defgroup sys_mbox Mailboxes - * @ingroup sys_os - * Mailboxes should be implemented as a queue which allows multiple messages - * to be posted (implementing as a rendez-vous point where only one message can be - * posted at a time can have a highly negative impact on performance). A message - * in a mailbox is just a pointer, nothing more. - * - * @defgroup sys_time Time - * @ingroup sys_layer - * - * @defgroup sys_prot Critical sections - * @ingroup sys_layer - * Used to protect short regions of code against concurrent access. - * - Your system is a bare-metal system (probably with an RTOS) - * and interrupts are under your control: - * Implement this as LockInterrupts() / UnlockInterrupts() - * - Your system uses an RTOS with deferred interrupt handling from a - * worker thread: Implement as a global mutex or lock/unlock scheduler - * - Your system uses a high-level OS with e.g. POSIX signals: - * Implement as a global mutex - * - * @defgroup sys_misc Misc - * @ingroup sys_os - */ - -#include "lwip/opt.h" - -#include "lwip/sys.h" - -/* Most of the functions defined in sys.h must be implemented in the - * architecture-dependent file sys_arch.c */ - -#if !NO_SYS - -#ifndef sys_msleep -/** - * Sleep for some ms. Timeouts are NOT processed while sleeping. - * - * @param ms number of milliseconds to sleep - */ -void -sys_msleep(u32_t ms) -{ - if (ms > 0) { - sys_sem_t delaysem; - err_t err = sys_sem_new(&delaysem, 0); - if (err == ERR_OK) { - sys_arch_sem_wait(&delaysem, ms); - sys_sem_free(&delaysem); - } - } -} -#endif /* sys_msleep */ - -#endif /* !NO_SYS */ diff --git a/third-party/lwip-2.1.2/core/tcp.c b/third-party/lwip-2.1.2/core/tcp.c deleted file mode 100644 index bd7d64ec..00000000 --- a/third-party/lwip-2.1.2/core/tcp.c +++ /dev/null @@ -1,2686 +0,0 @@ -/** - * @file - * Transmission Control Protocol for IP - * See also @ref tcp_raw - * - * @defgroup tcp_raw TCP - * @ingroup callbackstyle_api - * Transmission Control Protocol for IP\n - * @see @ref api - * - * Common functions for the TCP implementation, such as functions - * for manipulating the data structures and the TCP timer functions. TCP functions - * related to input and output is found in tcp_in.c and tcp_out.c respectively.\n - * - * TCP connection setup - * -------------------- - * The functions used for setting up connections is similar to that of - * the sequential API and of the BSD socket API. A new TCP connection - * identifier (i.e., a protocol control block - PCB) is created with the - * tcp_new() function. This PCB can then be either set to listen for new - * incoming connections or be explicitly connected to another host. - * - tcp_new() - * - tcp_bind() - * - tcp_listen() and tcp_listen_with_backlog() - * - tcp_accept() - * - tcp_connect() - * - * Sending TCP data - * ---------------- - * TCP data is sent by enqueueing the data with a call to tcp_write() and - * triggering to send by calling tcp_output(). When the data is successfully - * transmitted to the remote host, the application will be notified with a - * call to a specified callback function. - * - tcp_write() - * - tcp_output() - * - tcp_sent() - * - * Receiving TCP data - * ------------------ - * TCP data reception is callback based - an application specified - * callback function is called when new data arrives. When the - * application has taken the data, it has to call the tcp_recved() - * function to indicate that TCP can advertise increase the receive - * window. - * - tcp_recv() - * - tcp_recved() - * - * Application polling - * ------------------- - * When a connection is idle (i.e., no data is either transmitted or - * received), lwIP will repeatedly poll the application by calling a - * specified callback function. This can be used either as a watchdog - * timer for killing connections that have stayed idle for too long, or - * as a method of waiting for memory to become available. For instance, - * if a call to tcp_write() has failed because memory wasn't available, - * the application may use the polling functionality to call tcp_write() - * again when the connection has been idle for a while. - * - tcp_poll() - * - * Closing and aborting connections - * -------------------------------- - * - tcp_close() - * - tcp_abort() - * - tcp_err() - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#include "lwip/opt.h" - -#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/def.h" -#include "lwip/mem.h" -#include "lwip/memp.h" -#include "lwip/tcp.h" -#include "lwip/priv/tcp_priv.h" -#include "lwip/debug.h" -#include "lwip/stats.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#include "lwip/nd6.h" - -#include - -#ifdef LWIP_HOOK_FILENAME -#include LWIP_HOOK_FILENAME -#endif - -#ifndef TCP_LOCAL_PORT_RANGE_START -/* From http://www.iana.org/assignments/port-numbers: - "The Dynamic and/or Private Ports are those from 49152 through 65535" */ -#define TCP_LOCAL_PORT_RANGE_START 0xc000 -#define TCP_LOCAL_PORT_RANGE_END 0xffff -#define TCP_ENSURE_LOCAL_PORT_RANGE(port) ((u16_t)(((port) & (u16_t)~TCP_LOCAL_PORT_RANGE_START) + TCP_LOCAL_PORT_RANGE_START)) -#endif - -#if LWIP_TCP_KEEPALIVE -#define TCP_KEEP_DUR(pcb) ((pcb)->keep_cnt * (pcb)->keep_intvl) -#define TCP_KEEP_INTVL(pcb) ((pcb)->keep_intvl) -#else /* LWIP_TCP_KEEPALIVE */ -#define TCP_KEEP_DUR(pcb) TCP_MAXIDLE -#define TCP_KEEP_INTVL(pcb) TCP_KEEPINTVL_DEFAULT -#endif /* LWIP_TCP_KEEPALIVE */ - -/* As initial send MSS, we use TCP_MSS but limit it to 536. */ -#if TCP_MSS > 536 -#define INITIAL_MSS 536 -#else -#define INITIAL_MSS TCP_MSS -#endif - -static const char *const tcp_state_str[] = { - "CLOSED", - "LISTEN", - "SYN_SENT", - "SYN_RCVD", - "ESTABLISHED", - "FIN_WAIT_1", - "FIN_WAIT_2", - "CLOSE_WAIT", - "CLOSING", - "LAST_ACK", - "TIME_WAIT" -}; - -/* last local TCP port */ -static u16_t tcp_port = TCP_LOCAL_PORT_RANGE_START; - -/* Incremented every coarse grained timer shot (typically every 500 ms). */ -u32_t tcp_ticks; -static const u8_t tcp_backoff[13] = -{ 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7}; -/* Times per slowtmr hits */ -static const u8_t tcp_persist_backoff[7] = { 3, 6, 12, 24, 48, 96, 120 }; - -/* The TCP PCB lists. */ - -/** List of all TCP PCBs bound but not yet (connected || listening) */ -struct tcp_pcb *tcp_bound_pcbs; -/** List of all TCP PCBs in LISTEN state */ -union tcp_listen_pcbs_t tcp_listen_pcbs; -/** List of all TCP PCBs that are in a state in which - * they accept or send data. */ -struct tcp_pcb *tcp_active_pcbs; -/** List of all TCP PCBs in TIME-WAIT state */ -struct tcp_pcb *tcp_tw_pcbs; - -/** An array with all (non-temporary) PCB lists, mainly used for smaller code size */ -struct tcp_pcb **const tcp_pcb_lists[] = {&tcp_listen_pcbs.pcbs, &tcp_bound_pcbs, - &tcp_active_pcbs, &tcp_tw_pcbs -}; - -u8_t tcp_active_pcbs_changed; - -/** Timer counter to handle calling slow-timer from tcp_tmr() */ -static u8_t tcp_timer; -static u8_t tcp_timer_ctr; -static u16_t tcp_new_port(void); - -static err_t tcp_close_shutdown_fin(struct tcp_pcb *pcb); -#if LWIP_TCP_PCB_NUM_EXT_ARGS -static void tcp_ext_arg_invoke_callbacks_destroyed(struct tcp_pcb_ext_args *ext_args); -#endif - -/** - * Initialize this module. - */ -void -tcp_init(void) -{ -#ifdef LWIP_RAND - tcp_port = TCP_ENSURE_LOCAL_PORT_RANGE(LWIP_RAND()); -#endif /* LWIP_RAND */ -} - -/** Free a tcp pcb */ -void -tcp_free(struct tcp_pcb *pcb) -{ - LWIP_ASSERT("tcp_free: LISTEN", pcb->state != LISTEN); -#if LWIP_TCP_PCB_NUM_EXT_ARGS - tcp_ext_arg_invoke_callbacks_destroyed(pcb->ext_args); -#endif - memp_free(MEMP_TCP_PCB, pcb); -} - -/** Free a tcp listen pcb */ -static void -tcp_free_listen(struct tcp_pcb *pcb) -{ - LWIP_ASSERT("tcp_free_listen: !LISTEN", pcb->state != LISTEN); -#if LWIP_TCP_PCB_NUM_EXT_ARGS - tcp_ext_arg_invoke_callbacks_destroyed(pcb->ext_args); -#endif - memp_free(MEMP_TCP_PCB_LISTEN, pcb); -} - -/** - * Called periodically to dispatch TCP timers. - */ -void -tcp_tmr(void) -{ - /* Call tcp_fasttmr() every 250 ms */ - tcp_fasttmr(); - - if (++tcp_timer & 1) { - /* Call tcp_slowtmr() every 500 ms, i.e., every other timer - tcp_tmr() is called. */ - tcp_slowtmr(); - } -} - -#if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG -/** Called when a listen pcb is closed. Iterates one pcb list and removes the - * closed listener pcb from pcb->listener if matching. - */ -static void -tcp_remove_listener(struct tcp_pcb *list, struct tcp_pcb_listen *lpcb) -{ - struct tcp_pcb *pcb; - - LWIP_ASSERT("tcp_remove_listener: invalid listener", lpcb != NULL); - - for (pcb = list; pcb != NULL; pcb = pcb->next) { - if (pcb->listener == lpcb) { - pcb->listener = NULL; - } - } -} -#endif - -/** Called when a listen pcb is closed. Iterates all pcb lists and removes the - * closed listener pcb from pcb->listener if matching. - */ -static void -tcp_listen_closed(struct tcp_pcb *pcb) -{ -#if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG - size_t i; - LWIP_ASSERT("pcb != NULL", pcb != NULL); - LWIP_ASSERT("pcb->state == LISTEN", pcb->state == LISTEN); - for (i = 1; i < LWIP_ARRAYSIZE(tcp_pcb_lists); i++) { - tcp_remove_listener(*tcp_pcb_lists[i], (struct tcp_pcb_listen *)pcb); - } -#endif - LWIP_UNUSED_ARG(pcb); -} - -#if TCP_LISTEN_BACKLOG -/** @ingroup tcp_raw - * Delay accepting a connection in respect to the listen backlog: - * the number of outstanding connections is increased until - * tcp_backlog_accepted() is called. - * - * ATTENTION: the caller is responsible for calling tcp_backlog_accepted() - * or else the backlog feature will get out of sync! - * - * @param pcb the connection pcb which is not fully accepted yet - */ -void -tcp_backlog_delayed(struct tcp_pcb *pcb) -{ - LWIP_ASSERT("pcb != NULL", pcb != NULL); - LWIP_ASSERT_CORE_LOCKED(); - if ((pcb->flags & TF_BACKLOGPEND) == 0) { - if (pcb->listener != NULL) { - pcb->listener->accepts_pending++; - LWIP_ASSERT("accepts_pending != 0", pcb->listener->accepts_pending != 0); - tcp_set_flags(pcb, TF_BACKLOGPEND); - } - } -} - -/** @ingroup tcp_raw - * A delayed-accept a connection is accepted (or closed/aborted): decreases - * the number of outstanding connections after calling tcp_backlog_delayed(). - * - * ATTENTION: the caller is responsible for calling tcp_backlog_accepted() - * or else the backlog feature will get out of sync! - * - * @param pcb the connection pcb which is now fully accepted (or closed/aborted) - */ -void -tcp_backlog_accepted(struct tcp_pcb *pcb) -{ - LWIP_ASSERT("pcb != NULL", pcb != NULL); - LWIP_ASSERT_CORE_LOCKED(); - if ((pcb->flags & TF_BACKLOGPEND) != 0) { - if (pcb->listener != NULL) { - LWIP_ASSERT("accepts_pending != 0", pcb->listener->accepts_pending != 0); - pcb->listener->accepts_pending--; - tcp_clear_flags(pcb, TF_BACKLOGPEND); - } - } -} -#endif /* TCP_LISTEN_BACKLOG */ - -/** - * Closes the TX side of a connection held by the PCB. - * For tcp_close(), a RST is sent if the application didn't receive all data - * (tcp_recved() not called for all data passed to recv callback). - * - * Listening pcbs are freed and may not be referenced any more. - * Connection pcbs are freed if not yet connected and may not be referenced - * any more. If a connection is established (at least SYN received or in - * a closing state), the connection is closed, and put in a closing state. - * The pcb is then automatically freed in tcp_slowtmr(). It is therefore - * unsafe to reference it. - * - * @param pcb the tcp_pcb to close - * @return ERR_OK if connection has been closed - * another err_t if closing failed and pcb is not freed - */ -static err_t -tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data) -{ - LWIP_ASSERT("tcp_close_shutdown: invalid pcb", pcb != NULL); - - if (rst_on_unacked_data && ((pcb->state == ESTABLISHED) || (pcb->state == CLOSE_WAIT))) { - if ((pcb->refused_data != NULL) || (pcb->rcv_wnd != TCP_WND_MAX(pcb))) { - /* Not all data received by application, send RST to tell the remote - side about this. */ - LWIP_ASSERT("pcb->flags & TF_RXCLOSED", pcb->flags & TF_RXCLOSED); - - /* don't call tcp_abort here: we must not deallocate the pcb since - that might not be expected when calling tcp_close */ - tcp_rst(pcb, pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip, - pcb->local_port, pcb->remote_port); - - tcp_pcb_purge(pcb); - TCP_RMV_ACTIVE(pcb); - /* Deallocate the pcb since we already sent a RST for it */ - if (tcp_input_pcb == pcb) { - /* prevent using a deallocated pcb: free it from tcp_input later */ - tcp_trigger_input_pcb_close(); - } else { - tcp_free(pcb); - } - return ERR_OK; - } - } - - /* - states which free the pcb are handled here, - - states which send FIN and change state are handled in tcp_close_shutdown_fin() */ - switch (pcb->state) { - case CLOSED: - /* Closing a pcb in the CLOSED state might seem erroneous, - * however, it is in this state once allocated and as yet unused - * and the user needs some way to free it should the need arise. - * Calling tcp_close() with a pcb that has already been closed, (i.e. twice) - * or for a pcb that has been used and then entered the CLOSED state - * is erroneous, but this should never happen as the pcb has in those cases - * been freed, and so any remaining handles are bogus. */ - if (pcb->local_port != 0) { - TCP_RMV(&tcp_bound_pcbs, pcb); - } - tcp_free(pcb); - break; - case LISTEN: - tcp_listen_closed(pcb); - tcp_pcb_remove(&tcp_listen_pcbs.pcbs, pcb); - tcp_free_listen(pcb); - break; - case SYN_SENT: - TCP_PCB_REMOVE_ACTIVE(pcb); - tcp_free(pcb); - MIB2_STATS_INC(mib2.tcpattemptfails); - break; - default: - return tcp_close_shutdown_fin(pcb); - } - return ERR_OK; -} - -static err_t -tcp_close_shutdown_fin(struct tcp_pcb *pcb) -{ - err_t err; - LWIP_ASSERT("pcb != NULL", pcb != NULL); - - switch (pcb->state) { - case SYN_RCVD: - err = tcp_send_fin(pcb); - if (err == ERR_OK) { - tcp_backlog_accepted(pcb); - MIB2_STATS_INC(mib2.tcpattemptfails); - pcb->state = FIN_WAIT_1; - } - break; - case ESTABLISHED: - err = tcp_send_fin(pcb); - if (err == ERR_OK) { - MIB2_STATS_INC(mib2.tcpestabresets); - pcb->state = FIN_WAIT_1; - } - break; - case CLOSE_WAIT: - err = tcp_send_fin(pcb); - if (err == ERR_OK) { - MIB2_STATS_INC(mib2.tcpestabresets); - pcb->state = LAST_ACK; - } - break; - default: - /* Has already been closed, do nothing. */ - return ERR_OK; - } - - if (err == ERR_OK) { - /* To ensure all data has been sent when tcp_close returns, we have - to make sure tcp_output doesn't fail. - Since we don't really have to ensure all data has been sent when tcp_close - returns (unsent data is sent from tcp timer functions, also), we don't care - for the return value of tcp_output for now. */ - tcp_output(pcb); - } else if (err == ERR_MEM) { - /* Mark this pcb for closing. Closing is retried from tcp_tmr. */ - tcp_set_flags(pcb, TF_CLOSEPEND); - /* We have to return ERR_OK from here to indicate to the callers that this - pcb should not be used any more as it will be freed soon via tcp_tmr. - This is OK here since sending FIN does not guarantee a time frime for - actually freeing the pcb, either (it is left in closure states for - remote ACK or timeout) */ - return ERR_OK; - } - return err; -} - -/** - * @ingroup tcp_raw - * Closes the connection held by the PCB. - * - * Listening pcbs are freed and may not be referenced any more. - * Connection pcbs are freed if not yet connected and may not be referenced - * any more. If a connection is established (at least SYN received or in - * a closing state), the connection is closed, and put in a closing state. - * The pcb is then automatically freed in tcp_slowtmr(). It is therefore - * unsafe to reference it (unless an error is returned). - * - * The function may return ERR_MEM if no memory - * was available for closing the connection. If so, the application - * should wait and try again either by using the acknowledgment - * callback or the polling functionality. If the close succeeds, the - * function returns ERR_OK. - * - * @param pcb the tcp_pcb to close - * @return ERR_OK if connection has been closed - * another err_t if closing failed and pcb is not freed - */ -err_t -tcp_close(struct tcp_pcb *pcb) -{ - LWIP_ASSERT_CORE_LOCKED(); - - LWIP_ERROR("tcp_close: invalid pcb", pcb != NULL, return ERR_ARG); - LWIP_DEBUGF(TCP_DEBUG, ("tcp_close: closing in ")); - - tcp_debug_print_state(pcb->state); - - if (pcb->state != LISTEN) { - /* Set a flag not to receive any more data... */ - tcp_set_flags(pcb, TF_RXCLOSED); - } - /* ... and close */ - return tcp_close_shutdown(pcb, 1); -} - -/** - * @ingroup tcp_raw - * Causes all or part of a full-duplex connection of this PCB to be shut down. - * This doesn't deallocate the PCB unless shutting down both sides! - * Shutting down both sides is the same as calling tcp_close, so if it succeds - * (i.e. returns ER_OK), the PCB must not be referenced any more! - * - * @param pcb PCB to shutdown - * @param shut_rx shut down receive side if this is != 0 - * @param shut_tx shut down send side if this is != 0 - * @return ERR_OK if shutdown succeeded (or the PCB has already been shut down) - * another err_t on error. - */ -err_t -tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx) -{ - LWIP_ASSERT_CORE_LOCKED(); - - LWIP_ERROR("tcp_shutdown: invalid pcb", pcb != NULL, return ERR_ARG); - - if (pcb->state == LISTEN) { - return ERR_CONN; - } - if (shut_rx) { - /* shut down the receive side: set a flag not to receive any more data... */ - tcp_set_flags(pcb, TF_RXCLOSED); - if (shut_tx) { - /* shutting down the tx AND rx side is the same as closing for the raw API */ - return tcp_close_shutdown(pcb, 1); - } - /* ... and free buffered data */ - if (pcb->refused_data != NULL) { - pbuf_free(pcb->refused_data); - pcb->refused_data = NULL; - } - } - if (shut_tx) { - /* This can't happen twice since if it succeeds, the pcb's state is changed. - Only close in these states as the others directly deallocate the PCB */ - switch (pcb->state) { - case SYN_RCVD: - case ESTABLISHED: - case CLOSE_WAIT: - return tcp_close_shutdown(pcb, (u8_t)shut_rx); - default: - /* Not (yet?) connected, cannot shutdown the TX side as that would bring us - into CLOSED state, where the PCB is deallocated. */ - return ERR_CONN; - } - } - return ERR_OK; -} - -/** - * Abandons a connection and optionally sends a RST to the remote - * host. Deletes the local protocol control block. This is done when - * a connection is killed because of shortage of memory. - * - * @param pcb the tcp_pcb to abort - * @param reset boolean to indicate whether a reset should be sent - */ -void -tcp_abandon(struct tcp_pcb *pcb, int reset) -{ - u32_t seqno, ackno; -#if LWIP_CALLBACK_API - tcp_err_fn errf; -#endif /* LWIP_CALLBACK_API */ - void *errf_arg; - - LWIP_ASSERT_CORE_LOCKED(); - - LWIP_ERROR("tcp_abandon: invalid pcb", pcb != NULL, return); - - /* pcb->state LISTEN not allowed here */ - LWIP_ASSERT("don't call tcp_abort/tcp_abandon for listen-pcbs", - pcb->state != LISTEN); - /* Figure out on which TCP PCB list we are, and remove us. If we - are in an active state, call the receive function associated with - the PCB with a NULL argument, and send an RST to the remote end. */ - if (pcb->state == TIME_WAIT) { - tcp_pcb_remove(&tcp_tw_pcbs, pcb); - tcp_free(pcb); - } else { - int send_rst = 0; - u16_t local_port = 0; - enum tcp_state last_state; - seqno = pcb->snd_nxt; - ackno = pcb->rcv_nxt; -#if LWIP_CALLBACK_API - errf = pcb->errf; -#endif /* LWIP_CALLBACK_API */ - errf_arg = pcb->callback_arg; - if (pcb->state == CLOSED) { - if (pcb->local_port != 0) { - /* bound, not yet opened */ - TCP_RMV(&tcp_bound_pcbs, pcb); - } - } else { - send_rst = reset; - local_port = pcb->local_port; - TCP_PCB_REMOVE_ACTIVE(pcb); - } - if (pcb->unacked != NULL) { - tcp_segs_free(pcb->unacked); - } - if (pcb->unsent != NULL) { - tcp_segs_free(pcb->unsent); - } -#if TCP_QUEUE_OOSEQ - if (pcb->ooseq != NULL) { - tcp_segs_free(pcb->ooseq); - } -#endif /* TCP_QUEUE_OOSEQ */ - tcp_backlog_accepted(pcb); - if (send_rst) { - LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_abandon: sending RST\n")); - tcp_rst(pcb, seqno, ackno, &pcb->local_ip, &pcb->remote_ip, local_port, pcb->remote_port); - } - last_state = pcb->state; - tcp_free(pcb); - TCP_EVENT_ERR(last_state, errf, errf_arg, ERR_ABRT); - } -} - -/** - * @ingroup tcp_raw - * Aborts the connection by sending a RST (reset) segment to the remote - * host. The pcb is deallocated. This function never fails. - * - * ATTENTION: When calling this from one of the TCP callbacks, make - * sure you always return ERR_ABRT (and never return ERR_ABRT otherwise - * or you will risk accessing deallocated memory or memory leaks! - * - * @param pcb the tcp pcb to abort - */ -void -tcp_abort(struct tcp_pcb *pcb) -{ - tcp_abandon(pcb, 1); -} - -/** - * @ingroup tcp_raw - * Binds the connection to a local port number and IP address. If the - * IP address is not given (i.e., ipaddr == IP_ANY_TYPE), the connection is - * bound to all local IP addresses. - * If another connection is bound to the same port, the function will - * return ERR_USE, otherwise ERR_OK is returned. - * - * @param pcb the tcp_pcb to bind (no check is done whether this pcb is - * already bound!) - * @param ipaddr the local ip address to bind to (use IPx_ADDR_ANY to bind - * to any local address - * @param port the local port to bind to - * @return ERR_USE if the port is already in use - * ERR_VAL if bind failed because the PCB is not in a valid state - * ERR_OK if bound - */ -err_t -tcp_bind(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port) -{ - int i; - int max_pcb_list = NUM_TCP_PCB_LISTS; - struct tcp_pcb *cpcb; -#if LWIP_IPV6 && LWIP_IPV6_SCOPES - ip_addr_t zoned_ipaddr; -#endif /* LWIP_IPV6 && LWIP_IPV6_SCOPES */ - - LWIP_ASSERT_CORE_LOCKED(); - -#if LWIP_IPV4 - /* Don't propagate NULL pointer (IPv4 ANY) to subsequent functions */ - if (ipaddr == NULL) { - ipaddr = IP4_ADDR_ANY; - } -#else /* LWIP_IPV4 */ - LWIP_ERROR("tcp_bind: invalid ipaddr", ipaddr != NULL, return ERR_ARG); -#endif /* LWIP_IPV4 */ - - LWIP_ERROR("tcp_bind: invalid pcb", pcb != NULL, return ERR_ARG); - - LWIP_ERROR("tcp_bind: can only bind in state CLOSED", pcb->state == CLOSED, return ERR_VAL); - -#if SO_REUSE - /* Unless the REUSEADDR flag is set, - we have to check the pcbs in TIME-WAIT state, also. - We do not dump TIME_WAIT pcb's; they can still be matched by incoming - packets using both local and remote IP addresses and ports to distinguish. - */ - if (ip_get_option(pcb, SOF_REUSEADDR)) { - max_pcb_list = NUM_TCP_PCB_LISTS_NO_TIME_WAIT; - } -#endif /* SO_REUSE */ - -#if LWIP_IPV6 && LWIP_IPV6_SCOPES - /* If the given IP address should have a zone but doesn't, assign one now. - * This is legacy support: scope-aware callers should always provide properly - * zoned source addresses. Do the zone selection before the address-in-use - * check below; as such we have to make a temporary copy of the address. */ - if (IP_IS_V6(ipaddr) && ip6_addr_lacks_zone(ip_2_ip6(ipaddr), IP6_UNICAST)) { - ip_addr_copy(zoned_ipaddr, *ipaddr); - ip6_addr_select_zone(ip_2_ip6(&zoned_ipaddr), ip_2_ip6(&zoned_ipaddr)); - ipaddr = &zoned_ipaddr; - } -#endif /* LWIP_IPV6 && LWIP_IPV6_SCOPES */ - - if (port == 0) { - port = tcp_new_port(); - if (port == 0) { - return ERR_BUF; - } - } else { - /* Check if the address already is in use (on all lists) */ - for (i = 0; i < max_pcb_list; i++) { - for (cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) { - if (cpcb->local_port == port) { -#if SO_REUSE - /* Omit checking for the same port if both pcbs have REUSEADDR set. - For SO_REUSEADDR, the duplicate-check for a 5-tuple is done in - tcp_connect. */ - if (!ip_get_option(pcb, SOF_REUSEADDR) || - !ip_get_option(cpcb, SOF_REUSEADDR)) -#endif /* SO_REUSE */ - { - /* @todo: check accept_any_ip_version */ - if ((IP_IS_V6(ipaddr) == IP_IS_V6_VAL(cpcb->local_ip)) && - (ip_addr_isany(&cpcb->local_ip) || - ip_addr_isany(ipaddr) || - ip_addr_cmp(&cpcb->local_ip, ipaddr))) { - return ERR_USE; - } - } - } - } - } - } - - if (!ip_addr_isany(ipaddr) -#if LWIP_IPV4 && LWIP_IPV6 - || (IP_GET_TYPE(ipaddr) != IP_GET_TYPE(&pcb->local_ip)) -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - ) { - ip_addr_set(&pcb->local_ip, ipaddr); - } - pcb->local_port = port; - TCP_REG(&tcp_bound_pcbs, pcb); - LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: bind to port %"U16_F"\n", port)); - return ERR_OK; -} - -/** - * @ingroup tcp_raw - * Binds the connection to a netif and IP address. - * After calling this function, all packets received via this PCB - * are guaranteed to have come in via the specified netif, and all - * outgoing packets will go out via the specified netif. - * - * @param pcb the tcp_pcb to bind. - * @param netif the netif to bind to. Can be NULL. - */ -void -tcp_bind_netif(struct tcp_pcb *pcb, const struct netif *netif) -{ - LWIP_ASSERT_CORE_LOCKED(); - if (netif != NULL) { - pcb->netif_idx = netif_get_index(netif); - } else { - pcb->netif_idx = NETIF_NO_INDEX; - } -} - -#if LWIP_CALLBACK_API -/** - * Default accept callback if no accept callback is specified by the user. - */ -static err_t -tcp_accept_null(void *arg, struct tcp_pcb *pcb, err_t err) -{ - LWIP_UNUSED_ARG(arg); - LWIP_UNUSED_ARG(err); - - LWIP_ASSERT("tcp_accept_null: invalid pcb", pcb != NULL); - - tcp_abort(pcb); - - return ERR_ABRT; -} -#endif /* LWIP_CALLBACK_API */ - -/** - * @ingroup tcp_raw - * Set the state of the connection to be LISTEN, which means that it - * is able to accept incoming connections. The protocol control block - * is reallocated in order to consume less memory. Setting the - * connection to LISTEN is an irreversible process. - * When an incoming connection is accepted, the function specified with - * the tcp_accept() function will be called. The pcb has to be bound - * to a local port with the tcp_bind() function. - * - * The tcp_listen() function returns a new connection identifier, and - * the one passed as an argument to the function will be - * deallocated. The reason for this behavior is that less memory is - * needed for a connection that is listening, so tcp_listen() will - * reclaim the memory needed for the original connection and allocate a - * new smaller memory block for the listening connection. - * - * tcp_listen() may return NULL if no memory was available for the - * listening connection. If so, the memory associated with the pcb - * passed as an argument to tcp_listen() will not be deallocated. - * - * The backlog limits the number of outstanding connections - * in the listen queue to the value specified by the backlog argument. - * To use it, your need to set TCP_LISTEN_BACKLOG=1 in your lwipopts.h. - * - * @param pcb the original tcp_pcb - * @param backlog the incoming connections queue limit - * @return tcp_pcb used for listening, consumes less memory. - * - * @note The original tcp_pcb is freed. This function therefore has to be - * called like this: - * tpcb = tcp_listen_with_backlog(tpcb, backlog); - */ -struct tcp_pcb * -tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog) -{ - LWIP_ASSERT_CORE_LOCKED(); - return tcp_listen_with_backlog_and_err(pcb, backlog, NULL); -} - -/** - * @ingroup tcp_raw - * Set the state of the connection to be LISTEN, which means that it - * is able to accept incoming connections. The protocol control block - * is reallocated in order to consume less memory. Setting the - * connection to LISTEN is an irreversible process. - * - * @param pcb the original tcp_pcb - * @param backlog the incoming connections queue limit - * @param err when NULL is returned, this contains the error reason - * @return tcp_pcb used for listening, consumes less memory. - * - * @note The original tcp_pcb is freed. This function therefore has to be - * called like this: - * tpcb = tcp_listen_with_backlog_and_err(tpcb, backlog, &err); - */ -struct tcp_pcb * -tcp_listen_with_backlog_and_err(struct tcp_pcb *pcb, u8_t backlog, err_t *err) -{ - struct tcp_pcb_listen *lpcb = NULL; - err_t res; - - LWIP_UNUSED_ARG(backlog); - - LWIP_ASSERT_CORE_LOCKED(); - - LWIP_ERROR("tcp_listen_with_backlog_and_err: invalid pcb", pcb != NULL, res = ERR_ARG; goto done); - LWIP_ERROR("tcp_listen_with_backlog_and_err: pcb already connected", pcb->state == CLOSED, res = ERR_CLSD; goto done); - - /* already listening? */ - if (pcb->state == LISTEN) { - lpcb = (struct tcp_pcb_listen *)pcb; - res = ERR_ALREADY; - goto done; - } -#if SO_REUSE - if (ip_get_option(pcb, SOF_REUSEADDR)) { - /* Since SOF_REUSEADDR allows reusing a local address before the pcb's usage - is declared (listen-/connection-pcb), we have to make sure now that - this port is only used once for every local IP. */ - for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { - if ((lpcb->local_port == pcb->local_port) && - ip_addr_cmp(&lpcb->local_ip, &pcb->local_ip)) { - /* this address/port is already used */ - lpcb = NULL; - res = ERR_USE; - goto done; - } - } - } -#endif /* SO_REUSE */ - lpcb = (struct tcp_pcb_listen *)memp_malloc(MEMP_TCP_PCB_LISTEN); - if (lpcb == NULL) { - res = ERR_MEM; - goto done; - } - lpcb->callback_arg = pcb->callback_arg; - lpcb->local_port = pcb->local_port; - lpcb->state = LISTEN; - lpcb->prio = pcb->prio; - lpcb->so_options = pcb->so_options; - lpcb->netif_idx = NETIF_NO_INDEX; - lpcb->ttl = pcb->ttl; - lpcb->tos = pcb->tos; -#if LWIP_IPV4 && LWIP_IPV6 - IP_SET_TYPE_VAL(lpcb->remote_ip, pcb->local_ip.type); -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - ip_addr_copy(lpcb->local_ip, pcb->local_ip); - if (pcb->local_port != 0) { - TCP_RMV(&tcp_bound_pcbs, pcb); - } -#if LWIP_TCP_PCB_NUM_EXT_ARGS - /* copy over ext_args to listening pcb */ - memcpy(&lpcb->ext_args, &pcb->ext_args, sizeof(pcb->ext_args)); -#endif - tcp_free(pcb); -#if LWIP_CALLBACK_API - lpcb->accept = tcp_accept_null; -#endif /* LWIP_CALLBACK_API */ -#if TCP_LISTEN_BACKLOG - lpcb->accepts_pending = 0; - tcp_backlog_set(lpcb, backlog); -#endif /* TCP_LISTEN_BACKLOG */ - TCP_REG(&tcp_listen_pcbs.pcbs, (struct tcp_pcb *)lpcb); - res = ERR_OK; -done: - if (err != NULL) { - *err = res; - } - return (struct tcp_pcb *)lpcb; -} - -/** - * Update the state that tracks the available window space to advertise. - * - * Returns how much extra window would be advertised if we sent an - * update now. - */ -u32_t -tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb) -{ - u32_t new_right_edge; - - LWIP_ASSERT("tcp_update_rcv_ann_wnd: invalid pcb", pcb != NULL); - new_right_edge = pcb->rcv_nxt + pcb->rcv_wnd; - - if (TCP_SEQ_GEQ(new_right_edge, pcb->rcv_ann_right_edge + LWIP_MIN((TCP_WND / 2), pcb->mss))) { - /* we can advertise more window */ - pcb->rcv_ann_wnd = pcb->rcv_wnd; - return new_right_edge - pcb->rcv_ann_right_edge; - } else { - if (TCP_SEQ_GT(pcb->rcv_nxt, pcb->rcv_ann_right_edge)) { - /* Can happen due to other end sending out of advertised window, - * but within actual available (but not yet advertised) window */ - pcb->rcv_ann_wnd = 0; - } else { - /* keep the right edge of window constant */ - u32_t new_rcv_ann_wnd = pcb->rcv_ann_right_edge - pcb->rcv_nxt; -#if !LWIP_WND_SCALE - LWIP_ASSERT("new_rcv_ann_wnd <= 0xffff", new_rcv_ann_wnd <= 0xffff); -#endif - pcb->rcv_ann_wnd = (tcpwnd_size_t)new_rcv_ann_wnd; - } - return 0; - } -} - -/** - * @ingroup tcp_raw - * This function should be called by the application when it has - * processed the data. The purpose is to advertise a larger window - * when the data has been processed. - * - * @param pcb the tcp_pcb for which data is read - * @param len the amount of bytes that have been read by the application - */ -void -tcp_recved(struct tcp_pcb *pcb, u16_t len) -{ - u32_t wnd_inflation; - tcpwnd_size_t rcv_wnd; - - LWIP_ASSERT_CORE_LOCKED(); - - LWIP_ERROR("tcp_recved: invalid pcb", pcb != NULL, return); - - /* pcb->state LISTEN not allowed here */ - LWIP_ASSERT("don't call tcp_recved for listen-pcbs", - pcb->state != LISTEN); - - rcv_wnd = (tcpwnd_size_t)(pcb->rcv_wnd + len); - if ((rcv_wnd > TCP_WND_MAX(pcb)) || (rcv_wnd < pcb->rcv_wnd)) { - /* window got too big or tcpwnd_size_t overflow */ - LWIP_DEBUGF(TCP_DEBUG, ("tcp_recved: window got too big or tcpwnd_size_t overflow\n")); - pcb->rcv_wnd = TCP_WND_MAX(pcb); - } else { - pcb->rcv_wnd = rcv_wnd; - } - - wnd_inflation = tcp_update_rcv_ann_wnd(pcb); - - /* If the change in the right edge of window is significant (default - * watermark is TCP_WND/4), then send an explicit update now. - * Otherwise wait for a packet to be sent in the normal course of - * events (or more window to be available later) */ - if (wnd_inflation >= TCP_WND_UPDATE_THRESHOLD) { - tcp_ack_now(pcb); - tcp_output(pcb); - } - - LWIP_DEBUGF(TCP_DEBUG, ("tcp_recved: received %"U16_F" bytes, wnd %"TCPWNDSIZE_F" (%"TCPWNDSIZE_F").\n", - len, pcb->rcv_wnd, (u16_t)(TCP_WND_MAX(pcb) - pcb->rcv_wnd))); -} - -/** - * Allocate a new local TCP port. - * - * @return a new (free) local TCP port number - */ -static u16_t -tcp_new_port(void) -{ - u8_t i; - u16_t n = 0; - struct tcp_pcb *pcb; - -again: - tcp_port++; - if (tcp_port == TCP_LOCAL_PORT_RANGE_END) { - tcp_port = TCP_LOCAL_PORT_RANGE_START; - } - /* Check all PCB lists. */ - for (i = 0; i < NUM_TCP_PCB_LISTS; i++) { - for (pcb = *tcp_pcb_lists[i]; pcb != NULL; pcb = pcb->next) { - if (pcb->local_port == tcp_port) { - n++; - if (n > (TCP_LOCAL_PORT_RANGE_END - TCP_LOCAL_PORT_RANGE_START)) { - return 0; - } - goto again; - } - } - } - return tcp_port; -} - -/** - * @ingroup tcp_raw - * Connects to another host. The function given as the "connected" - * argument will be called when the connection has been established. - * Sets up the pcb to connect to the remote host and sends the - * initial SYN segment which opens the connection. - * - * The tcp_connect() function returns immediately; it does not wait for - * the connection to be properly setup. Instead, it will call the - * function specified as the fourth argument (the "connected" argument) - * when the connection is established. If the connection could not be - * properly established, either because the other host refused the - * connection or because the other host didn't answer, the "err" - * callback function of this pcb (registered with tcp_err, see below) - * will be called. - * - * The tcp_connect() function can return ERR_MEM if no memory is - * available for enqueueing the SYN segment. If the SYN indeed was - * enqueued successfully, the tcp_connect() function returns ERR_OK. - * - * @param pcb the tcp_pcb used to establish the connection - * @param ipaddr the remote ip address to connect to - * @param port the remote tcp port to connect to - * @param connected callback function to call when connected (on error, - the err calback will be called) - * @return ERR_VAL if invalid arguments are given - * ERR_OK if connect request has been sent - * other err_t values if connect request couldn't be sent - */ -err_t -tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port, - tcp_connected_fn connected) -{ - struct netif *netif = NULL; - err_t ret; - u32_t iss; - u16_t old_local_port; - - LWIP_ASSERT_CORE_LOCKED(); - - LWIP_ERROR("tcp_connect: invalid pcb", pcb != NULL, return ERR_ARG); - LWIP_ERROR("tcp_connect: invalid ipaddr", ipaddr != NULL, return ERR_ARG); - - LWIP_ERROR("tcp_connect: can only connect from state CLOSED", pcb->state == CLOSED, return ERR_ISCONN); - - LWIP_DEBUGF(TCP_DEBUG, ("tcp_connect to port %"U16_F"\n", port)); - ip_addr_set(&pcb->remote_ip, ipaddr); - pcb->remote_port = port; - - if (pcb->netif_idx != NETIF_NO_INDEX) { - netif = netif_get_by_index(pcb->netif_idx); - } else { - /* check if we have a route to the remote host */ - netif = ip_route(&pcb->local_ip, &pcb->remote_ip); - } - if (netif == NULL) { - /* Don't even try to send a SYN packet if we have no route since that will fail. */ - return ERR_RTE; - } - - /* check if local IP has been assigned to pcb, if not, get one */ - if (ip_addr_isany(&pcb->local_ip)) { - const ip_addr_t *local_ip = ip_netif_get_local_ip(netif, ipaddr); - if (local_ip == NULL) { - return ERR_RTE; - } - ip_addr_copy(pcb->local_ip, *local_ip); - } - -#if LWIP_IPV6 && LWIP_IPV6_SCOPES - /* If the given IP address should have a zone but doesn't, assign one now. - * Given that we already have the target netif, this is easy and cheap. */ - if (IP_IS_V6(&pcb->remote_ip) && - ip6_addr_lacks_zone(ip_2_ip6(&pcb->remote_ip), IP6_UNICAST)) { - ip6_addr_assign_zone(ip_2_ip6(&pcb->remote_ip), IP6_UNICAST, netif); - } -#endif /* LWIP_IPV6 && LWIP_IPV6_SCOPES */ - - old_local_port = pcb->local_port; - if (pcb->local_port == 0) { - pcb->local_port = tcp_new_port(); - if (pcb->local_port == 0) { - return ERR_BUF; - } - } else { -#if SO_REUSE - if (ip_get_option(pcb, SOF_REUSEADDR)) { - /* Since SOF_REUSEADDR allows reusing a local address, we have to make sure - now that the 5-tuple is unique. */ - struct tcp_pcb *cpcb; - int i; - /* Don't check listen- and bound-PCBs, check active- and TIME-WAIT PCBs. */ - for (i = 2; i < NUM_TCP_PCB_LISTS; i++) { - for (cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) { - if ((cpcb->local_port == pcb->local_port) && - (cpcb->remote_port == port) && - ip_addr_cmp(&cpcb->local_ip, &pcb->local_ip) && - ip_addr_cmp(&cpcb->remote_ip, ipaddr)) { - /* linux returns EISCONN here, but ERR_USE should be OK for us */ - return ERR_USE; - } - } - } - } -#endif /* SO_REUSE */ - } - - iss = tcp_next_iss(pcb); - pcb->rcv_nxt = 0; - pcb->snd_nxt = iss; - pcb->lastack = iss - 1; - pcb->snd_wl2 = iss - 1; - pcb->snd_lbb = iss - 1; - /* Start with a window that does not need scaling. When window scaling is - enabled and used, the window is enlarged when both sides agree on scaling. */ - pcb->rcv_wnd = pcb->rcv_ann_wnd = TCPWND_MIN16(TCP_WND); - pcb->rcv_ann_right_edge = pcb->rcv_nxt; - pcb->snd_wnd = TCP_WND; - /* As initial send MSS, we use TCP_MSS but limit it to 536. - The send MSS is updated when an MSS option is received. */ - pcb->mss = INITIAL_MSS; -#if TCP_CALCULATE_EFF_SEND_MSS - pcb->mss = tcp_eff_send_mss_netif(pcb->mss, netif, &pcb->remote_ip); -#endif /* TCP_CALCULATE_EFF_SEND_MSS */ - pcb->cwnd = 1; -#if LWIP_CALLBACK_API - pcb->connected = connected; -#else /* LWIP_CALLBACK_API */ - LWIP_UNUSED_ARG(connected); -#endif /* LWIP_CALLBACK_API */ - - /* Send a SYN together with the MSS option. */ - ret = tcp_enqueue_flags(pcb, TCP_SYN); - if (ret == ERR_OK) { - /* SYN segment was enqueued, changed the pcbs state now */ - pcb->state = SYN_SENT; - if (old_local_port != 0) { - TCP_RMV(&tcp_bound_pcbs, pcb); - } - TCP_REG_ACTIVE(pcb); - MIB2_STATS_INC(mib2.tcpactiveopens); - - tcp_output(pcb); - } - return ret; -} - -/** - * Called every 500 ms and implements the retransmission timer and the timer that - * removes PCBs that have been in TIME-WAIT for enough time. It also increments - * various timers such as the inactivity timer in each PCB. - * - * Automatically called from tcp_tmr(). - */ -void -tcp_slowtmr(void) -{ - struct tcp_pcb *pcb, *prev; - tcpwnd_size_t eff_wnd; - u8_t pcb_remove; /* flag if a PCB should be removed */ - u8_t pcb_reset; /* flag if a RST should be sent when removing */ - err_t err; - - err = ERR_OK; - - ++tcp_ticks; - ++tcp_timer_ctr; - -tcp_slowtmr_start: - /* Steps through all of the active PCBs. */ - prev = NULL; - pcb = tcp_active_pcbs; - if (pcb == NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: no active pcbs\n")); - } - while (pcb != NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: processing active pcb\n")); - LWIP_ASSERT("tcp_slowtmr: active pcb->state != CLOSED\n", pcb->state != CLOSED); - LWIP_ASSERT("tcp_slowtmr: active pcb->state != LISTEN\n", pcb->state != LISTEN); - LWIP_ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT\n", pcb->state != TIME_WAIT); - if (pcb->last_timer == tcp_timer_ctr) { - /* skip this pcb, we have already processed it */ - prev = pcb; - pcb = pcb->next; - continue; - } - pcb->last_timer = tcp_timer_ctr; - - pcb_remove = 0; - pcb_reset = 0; - - if (pcb->state == SYN_SENT && pcb->nrtx >= TCP_SYNMAXRTX) { - ++pcb_remove; - LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max SYN retries reached\n")); - } else if (pcb->nrtx >= TCP_MAXRTX) { - ++pcb_remove; - LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max DATA retries reached\n")); - } else { - if (pcb->persist_backoff > 0) { - LWIP_ASSERT("tcp_slowtimr: persist ticking with in-flight data", pcb->unacked == NULL); - LWIP_ASSERT("tcp_slowtimr: persist ticking with empty send buffer", pcb->unsent != NULL); - if (pcb->persist_probe >= TCP_MAXRTX) { - ++pcb_remove; /* max probes reached */ - } else { - u8_t backoff_cnt = tcp_persist_backoff[pcb->persist_backoff - 1]; - if (pcb->persist_cnt < backoff_cnt) { - pcb->persist_cnt++; - } - if (pcb->persist_cnt >= backoff_cnt) { - int next_slot = 1; /* increment timer to next slot */ - /* If snd_wnd is zero, send 1 byte probes */ - if (pcb->snd_wnd == 0) { - if (tcp_zero_window_probe(pcb) != ERR_OK) { - next_slot = 0; /* try probe again with current slot */ - } - /* snd_wnd not fully closed, split unsent head and fill window */ - } else { - if (tcp_split_unsent_seg(pcb, (u16_t)pcb->snd_wnd) == ERR_OK) { - if (tcp_output(pcb) == ERR_OK) { - /* sending will cancel persist timer, else retry with current slot */ - next_slot = 0; - } - } - } - if (next_slot) { - pcb->persist_cnt = 0; - if (pcb->persist_backoff < sizeof(tcp_persist_backoff)) { - pcb->persist_backoff++; - } - } - } - } - } else { - /* Increase the retransmission timer if it is running */ - if ((pcb->rtime >= 0) && (pcb->rtime < 0x7FFF)) { - ++pcb->rtime; - } - - if (pcb->rtime >= pcb->rto) { - /* Time for a retransmission. */ - LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_slowtmr: rtime %"S16_F - " pcb->rto %"S16_F"\n", - pcb->rtime, pcb->rto)); - /* If prepare phase fails but we have unsent data but no unacked data, - still execute the backoff calculations below, as this means we somehow - failed to send segment. */ - if ((tcp_rexmit_rto_prepare(pcb) == ERR_OK) || ((pcb->unacked == NULL) && (pcb->unsent != NULL))) { - /* Double retransmission time-out unless we are trying to - * connect to somebody (i.e., we are in SYN_SENT). */ - if (pcb->state != SYN_SENT) { - u8_t backoff_idx = LWIP_MIN(pcb->nrtx, sizeof(tcp_backoff) - 1); - int calc_rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[backoff_idx]; - pcb->rto = (s16_t)LWIP_MIN(calc_rto, 0x7FFF); - } - - /* Reset the retransmission timer. */ - pcb->rtime = 0; - - /* Reduce congestion window and ssthresh. */ - eff_wnd = LWIP_MIN(pcb->cwnd, pcb->snd_wnd); - pcb->ssthresh = eff_wnd >> 1; - if (pcb->ssthresh < (tcpwnd_size_t)(pcb->mss << 1)) { - pcb->ssthresh = (tcpwnd_size_t)(pcb->mss << 1); - } - pcb->cwnd = pcb->mss; - LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: cwnd %"TCPWNDSIZE_F - " ssthresh %"TCPWNDSIZE_F"\n", - pcb->cwnd, pcb->ssthresh)); - pcb->bytes_acked = 0; - - /* The following needs to be called AFTER cwnd is set to one - mss - STJ */ - tcp_rexmit_rto_commit(pcb); - } - } - } - } - /* Check if this PCB has stayed too long in FIN-WAIT-2 */ - if (pcb->state == FIN_WAIT_2) { - /* If this PCB is in FIN_WAIT_2 because of SHUT_WR don't let it time out. */ - if (pcb->flags & TF_RXCLOSED) { - /* PCB was fully closed (either through close() or SHUT_RDWR): - normal FIN-WAIT timeout handling. */ - if ((u32_t)(tcp_ticks - pcb->tmr) > - TCP_FIN_WAIT_TIMEOUT / TCP_SLOW_INTERVAL) { - ++pcb_remove; - LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in FIN-WAIT-2\n")); - } - } - } - - /* Check if KEEPALIVE should be sent */ - if (ip_get_option(pcb, SOF_KEEPALIVE) && - ((pcb->state == ESTABLISHED) || - (pcb->state == CLOSE_WAIT))) { - if ((u32_t)(tcp_ticks - pcb->tmr) > - (pcb->keep_idle + TCP_KEEP_DUR(pcb)) / TCP_SLOW_INTERVAL) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: KEEPALIVE timeout. Aborting connection to ")); - ip_addr_debug_print_val(TCP_DEBUG, pcb->remote_ip); - LWIP_DEBUGF(TCP_DEBUG, ("\n")); - - ++pcb_remove; - ++pcb_reset; - } else if ((u32_t)(tcp_ticks - pcb->tmr) > - (pcb->keep_idle + pcb->keep_cnt_sent * TCP_KEEP_INTVL(pcb)) - / TCP_SLOW_INTERVAL) { - err = tcp_keepalive(pcb); - if (err == ERR_OK) { - pcb->keep_cnt_sent++; - } - } - } - - /* If this PCB has queued out of sequence data, but has been - inactive for too long, will drop the data (it will eventually - be retransmitted). */ -#if TCP_QUEUE_OOSEQ - if (pcb->ooseq != NULL && - (tcp_ticks - pcb->tmr >= (u32_t)pcb->rto * TCP_OOSEQ_TIMEOUT)) { - LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: dropping OOSEQ queued data\n")); - tcp_free_ooseq(pcb); - } -#endif /* TCP_QUEUE_OOSEQ */ - - /* Check if this PCB has stayed too long in SYN-RCVD */ - if (pcb->state == SYN_RCVD) { - if ((u32_t)(tcp_ticks - pcb->tmr) > - TCP_SYN_RCVD_TIMEOUT / TCP_SLOW_INTERVAL) { - ++pcb_remove; - LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in SYN-RCVD\n")); - } - } - - /* Check if this PCB has stayed too long in LAST-ACK */ - if (pcb->state == LAST_ACK) { - if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) { - ++pcb_remove; - LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in LAST-ACK\n")); - } - } - - /* If the PCB should be removed, do it. */ - if (pcb_remove) { - struct tcp_pcb *pcb2; -#if LWIP_CALLBACK_API - tcp_err_fn err_fn = pcb->errf; -#endif /* LWIP_CALLBACK_API */ - void *err_arg; - enum tcp_state last_state; - tcp_pcb_purge(pcb); - /* Remove PCB from tcp_active_pcbs list. */ - if (prev != NULL) { - LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs); - prev->next = pcb->next; - } else { - /* This PCB was the first. */ - LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_active_pcbs", tcp_active_pcbs == pcb); - tcp_active_pcbs = pcb->next; - } - - if (pcb_reset) { - tcp_rst(pcb, pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip, - pcb->local_port, pcb->remote_port); - } - - err_arg = pcb->callback_arg; - last_state = pcb->state; - pcb2 = pcb; - pcb = pcb->next; - tcp_free(pcb2); - - tcp_active_pcbs_changed = 0; - TCP_EVENT_ERR(last_state, err_fn, err_arg, ERR_ABRT); - if (tcp_active_pcbs_changed) { - goto tcp_slowtmr_start; - } - } else { - /* get the 'next' element now and work with 'prev' below (in case of abort) */ - prev = pcb; - pcb = pcb->next; - - /* We check if we should poll the connection. */ - ++prev->polltmr; - if (prev->polltmr >= prev->pollinterval) { - prev->polltmr = 0; - LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: polling application\n")); - tcp_active_pcbs_changed = 0; - TCP_EVENT_POLL(prev, err); - if (tcp_active_pcbs_changed) { - goto tcp_slowtmr_start; - } - /* if err == ERR_ABRT, 'prev' is already deallocated */ - if (err == ERR_OK) { - tcp_output(prev); - } - } - } - } - - - /* Steps through all of the TIME-WAIT PCBs. */ - prev = NULL; - pcb = tcp_tw_pcbs; - while (pcb != NULL) { - LWIP_ASSERT("tcp_slowtmr: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); - pcb_remove = 0; - - /* Check if this PCB has stayed long enough in TIME-WAIT */ - if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) { - ++pcb_remove; - } - - /* If the PCB should be removed, do it. */ - if (pcb_remove) { - struct tcp_pcb *pcb2; - tcp_pcb_purge(pcb); - /* Remove PCB from tcp_tw_pcbs list. */ - if (prev != NULL) { - LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_tw_pcbs", pcb != tcp_tw_pcbs); - prev->next = pcb->next; - } else { - /* This PCB was the first. */ - LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_tw_pcbs", tcp_tw_pcbs == pcb); - tcp_tw_pcbs = pcb->next; - } - pcb2 = pcb; - pcb = pcb->next; - tcp_free(pcb2); - } else { - prev = pcb; - pcb = pcb->next; - } - } -} - -/** - * Is called every TCP_FAST_INTERVAL (250 ms) and process data previously - * "refused" by upper layer (application) and sends delayed ACKs or pending FINs. - * - * Automatically called from tcp_tmr(). - */ -void -tcp_fasttmr(void) -{ - struct tcp_pcb *pcb; - - ++tcp_timer_ctr; - -tcp_fasttmr_start: - pcb = tcp_active_pcbs; - - while (pcb != NULL) { - if (pcb->last_timer != tcp_timer_ctr) { - struct tcp_pcb *next; - pcb->last_timer = tcp_timer_ctr; - /* send delayed ACKs */ - if (pcb->flags & TF_ACK_DELAY) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n")); - tcp_ack_now(pcb); - tcp_output(pcb); - tcp_clear_flags(pcb, TF_ACK_DELAY | TF_ACK_NOW); - } - /* send pending FIN */ - if (pcb->flags & TF_CLOSEPEND) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: pending FIN\n")); - tcp_clear_flags(pcb, TF_CLOSEPEND); - tcp_close_shutdown_fin(pcb); - } - - next = pcb->next; - - /* If there is data which was previously "refused" by upper layer */ - if (pcb->refused_data != NULL) { - tcp_active_pcbs_changed = 0; - tcp_process_refused_data(pcb); - if (tcp_active_pcbs_changed) { - /* application callback has changed the pcb list: restart the loop */ - goto tcp_fasttmr_start; - } - } - pcb = next; - } else { - pcb = pcb->next; - } - } -} - -/** Call tcp_output for all active pcbs that have TF_NAGLEMEMERR set */ -void -tcp_txnow(void) -{ - struct tcp_pcb *pcb; - - for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { - if (pcb->flags & TF_NAGLEMEMERR) { - tcp_output(pcb); - } - } -} - -/** Pass pcb->refused_data to the recv callback */ -err_t -tcp_process_refused_data(struct tcp_pcb *pcb) -{ -#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE - struct pbuf *rest; -#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ - - LWIP_ERROR("tcp_process_refused_data: invalid pcb", pcb != NULL, return ERR_ARG); - -#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE - while (pcb->refused_data != NULL) -#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ - { - err_t err; - u8_t refused_flags = pcb->refused_data->flags; - /* set pcb->refused_data to NULL in case the callback frees it and then - closes the pcb */ - struct pbuf *refused_data = pcb->refused_data; -#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE - pbuf_split_64k(refused_data, &rest); - pcb->refused_data = rest; -#else /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ - pcb->refused_data = NULL; -#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ - /* Notify again application with data previously received. */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: notify kept packet\n")); - TCP_EVENT_RECV(pcb, refused_data, ERR_OK, err); - if (err == ERR_OK) { - /* did refused_data include a FIN? */ - if ((refused_flags & PBUF_FLAG_TCP_FIN) -#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE - && (rest == NULL) -#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ - ) { - /* correct rcv_wnd as the application won't call tcp_recved() - for the FIN's seqno */ - if (pcb->rcv_wnd != TCP_WND_MAX(pcb)) { - pcb->rcv_wnd++; - } - TCP_EVENT_CLOSED(pcb, err); - if (err == ERR_ABRT) { - return ERR_ABRT; - } - } - } else if (err == ERR_ABRT) { - /* if err == ERR_ABRT, 'pcb' is already deallocated */ - /* Drop incoming packets because pcb is "full" (only if the incoming - segment contains data). */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: drop incoming packets, because pcb is \"full\"\n")); - return ERR_ABRT; - } else { - /* data is still refused, pbuf is still valid (go on for ACK-only packets) */ -#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE - if (rest != NULL) { - pbuf_cat(refused_data, rest); - } -#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ - pcb->refused_data = refused_data; - return ERR_INPROGRESS; - } - } - return ERR_OK; -} - -/** - * Deallocates a list of TCP segments (tcp_seg structures). - * - * @param seg tcp_seg list of TCP segments to free - */ -void -tcp_segs_free(struct tcp_seg *seg) -{ - while (seg != NULL) { - struct tcp_seg *next = seg->next; - tcp_seg_free(seg); - seg = next; - } -} - -/** - * Frees a TCP segment (tcp_seg structure). - * - * @param seg single tcp_seg to free - */ -void -tcp_seg_free(struct tcp_seg *seg) -{ - if (seg != NULL) { - if (seg->p != NULL) { - pbuf_free(seg->p); -#if TCP_DEBUG - seg->p = NULL; -#endif /* TCP_DEBUG */ - } - memp_free(MEMP_TCP_SEG, seg); - } -} - -/** - * @ingroup tcp - * Sets the priority of a connection. - * - * @param pcb the tcp_pcb to manipulate - * @param prio new priority - */ -void -tcp_setprio(struct tcp_pcb *pcb, u8_t prio) -{ - LWIP_ASSERT_CORE_LOCKED(); - - LWIP_ERROR("tcp_setprio: invalid pcb", pcb != NULL, return); - - pcb->prio = prio; -} - -#if TCP_QUEUE_OOSEQ -/** - * Returns a copy of the given TCP segment. - * The pbuf and data are not copied, only the pointers - * - * @param seg the old tcp_seg - * @return a copy of seg - */ -struct tcp_seg * -tcp_seg_copy(struct tcp_seg *seg) -{ - struct tcp_seg *cseg; - - LWIP_ASSERT("tcp_seg_copy: invalid seg", seg != NULL); - - cseg = (struct tcp_seg *)memp_malloc(MEMP_TCP_SEG); - if (cseg == NULL) { - return NULL; - } - SMEMCPY((u8_t *)cseg, (const u8_t *)seg, sizeof(struct tcp_seg)); - pbuf_ref(cseg->p); - return cseg; -} -#endif /* TCP_QUEUE_OOSEQ */ - -#if LWIP_CALLBACK_API -/** - * Default receive callback that is called if the user didn't register - * a recv callback for the pcb. - */ -err_t -tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) -{ - LWIP_UNUSED_ARG(arg); - - LWIP_ERROR("tcp_recv_null: invalid pcb", pcb != NULL, return ERR_ARG); - - if (p != NULL) { - tcp_recved(pcb, p->tot_len); - pbuf_free(p); - } else if (err == ERR_OK) { - return tcp_close(pcb); - } - return ERR_OK; -} -#endif /* LWIP_CALLBACK_API */ - -/** - * Kills the oldest active connection that has a lower priority than 'prio'. - * - * @param prio minimum priority - */ -static void -tcp_kill_prio(u8_t prio) -{ - struct tcp_pcb *pcb, *inactive; - u32_t inactivity; - u8_t mprio; - - mprio = LWIP_MIN(TCP_PRIO_MAX, prio); - - /* We want to kill connections with a lower prio, so bail out if - * supplied prio is 0 - there can never be a lower prio - */ - if (mprio == 0) { - return; - } - - /* We only want kill connections with a lower prio, so decrement prio by one - * and start searching for oldest connection with same or lower priority than mprio. - * We want to find the connections with the lowest possible prio, and among - * these the one with the longest inactivity time. - */ - mprio--; - - inactivity = 0; - inactive = NULL; - for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { - /* lower prio is always a kill candidate */ - if ((pcb->prio < mprio) || - /* longer inactivity is also a kill candidate */ - ((pcb->prio == mprio) && ((u32_t)(tcp_ticks - pcb->tmr) >= inactivity))) { - inactivity = tcp_ticks - pcb->tmr; - inactive = pcb; - mprio = pcb->prio; - } - } - if (inactive != NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_prio: killing oldest PCB %p (%"S32_F")\n", - (void *)inactive, inactivity)); - tcp_abort(inactive); - } -} - -/** - * Kills the oldest connection that is in specific state. - * Called from tcp_alloc() for LAST_ACK and CLOSING if no more connections are available. - */ -static void -tcp_kill_state(enum tcp_state state) -{ - struct tcp_pcb *pcb, *inactive; - u32_t inactivity; - - LWIP_ASSERT("invalid state", (state == CLOSING) || (state == LAST_ACK)); - - inactivity = 0; - inactive = NULL; - /* Go through the list of active pcbs and get the oldest pcb that is in state - CLOSING/LAST_ACK. */ - for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { - if (pcb->state == state) { - if ((u32_t)(tcp_ticks - pcb->tmr) >= inactivity) { - inactivity = tcp_ticks - pcb->tmr; - inactive = pcb; - } - } - } - if (inactive != NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_closing: killing oldest %s PCB %p (%"S32_F")\n", - tcp_state_str[state], (void *)inactive, inactivity)); - /* Don't send a RST, since no data is lost. */ - tcp_abandon(inactive, 0); - } -} - -/** - * Kills the oldest connection that is in TIME_WAIT state. - * Called from tcp_alloc() if no more connections are available. - */ -static void -tcp_kill_timewait(void) -{ - struct tcp_pcb *pcb, *inactive; - u32_t inactivity; - - inactivity = 0; - inactive = NULL; - /* Go through the list of TIME_WAIT pcbs and get the oldest pcb. */ - for (pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { - if ((u32_t)(tcp_ticks - pcb->tmr) >= inactivity) { - inactivity = tcp_ticks - pcb->tmr; - inactive = pcb; - } - } - if (inactive != NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_timewait: killing oldest TIME-WAIT PCB %p (%"S32_F")\n", - (void *)inactive, inactivity)); - tcp_abort(inactive); - } -} - -/* Called when allocating a pcb fails. - * In this case, we want to handle all pcbs that want to close first: if we can - * now send the FIN (which failed before), the pcb might be in a state that is - * OK for us to now free it. - */ -static void -tcp_handle_closepend(void) -{ - struct tcp_pcb *pcb = tcp_active_pcbs; - - while (pcb != NULL) { - struct tcp_pcb *next = pcb->next; - /* send pending FIN */ - if (pcb->flags & TF_CLOSEPEND) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_handle_closepend: pending FIN\n")); - tcp_clear_flags(pcb, TF_CLOSEPEND); - tcp_close_shutdown_fin(pcb); - } - pcb = next; - } -} - -/** - * Allocate a new tcp_pcb structure. - * - * @param prio priority for the new pcb - * @return a new tcp_pcb that initially is in state CLOSED - */ -struct tcp_pcb * -tcp_alloc(u8_t prio) -{ - struct tcp_pcb *pcb; - - LWIP_ASSERT_CORE_LOCKED(); - - pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB); - if (pcb == NULL) { - /* Try to send FIN for all pcbs stuck in TF_CLOSEPEND first */ - tcp_handle_closepend(); - - /* Try killing oldest connection in TIME-WAIT. */ - LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest TIME-WAIT connection\n")); - tcp_kill_timewait(); - /* Try to allocate a tcp_pcb again. */ - pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB); - if (pcb == NULL) { - /* Try killing oldest connection in LAST-ACK (these wouldn't go to TIME-WAIT). */ - LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest LAST-ACK connection\n")); - tcp_kill_state(LAST_ACK); - /* Try to allocate a tcp_pcb again. */ - pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB); - if (pcb == NULL) { - /* Try killing oldest connection in CLOSING. */ - LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest CLOSING connection\n")); - tcp_kill_state(CLOSING); - /* Try to allocate a tcp_pcb again. */ - pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB); - if (pcb == NULL) { - /* Try killing oldest active connection with lower priority than the new one. */ - LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing oldest connection with prio lower than %d\n", prio)); - tcp_kill_prio(prio); - /* Try to allocate a tcp_pcb again. */ - pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB); - if (pcb != NULL) { - /* adjust err stats: memp_malloc failed multiple times before */ - MEMP_STATS_DEC(err, MEMP_TCP_PCB); - } - } - if (pcb != NULL) { - /* adjust err stats: memp_malloc failed multiple times before */ - MEMP_STATS_DEC(err, MEMP_TCP_PCB); - } - } - if (pcb != NULL) { - /* adjust err stats: memp_malloc failed multiple times before */ - MEMP_STATS_DEC(err, MEMP_TCP_PCB); - } - } - if (pcb != NULL) { - /* adjust err stats: memp_malloc failed above */ - MEMP_STATS_DEC(err, MEMP_TCP_PCB); - } - } - if (pcb != NULL) { - /* zero out the whole pcb, so there is no need to initialize members to zero */ - memset(pcb, 0, sizeof(struct tcp_pcb)); - pcb->prio = prio; - pcb->snd_buf = TCP_SND_BUF; - /* Start with a window that does not need scaling. When window scaling is - enabled and used, the window is enlarged when both sides agree on scaling. */ - pcb->rcv_wnd = pcb->rcv_ann_wnd = TCPWND_MIN16(TCP_WND); - pcb->ttl = TCP_TTL; - /* As initial send MSS, we use TCP_MSS but limit it to 536. - The send MSS is updated when an MSS option is received. */ - pcb->mss = INITIAL_MSS; - pcb->rto = 3000 / TCP_SLOW_INTERVAL; - pcb->sv = 3000 / TCP_SLOW_INTERVAL; - pcb->rtime = -1; - pcb->cwnd = 1; - pcb->tmr = tcp_ticks; - pcb->last_timer = tcp_timer_ctr; - - /* RFC 5681 recommends setting ssthresh abritrarily high and gives an example - of using the largest advertised receive window. We've seen complications with - receiving TCPs that use window scaling and/or window auto-tuning where the - initial advertised window is very small and then grows rapidly once the - connection is established. To avoid these complications, we set ssthresh to the - largest effective cwnd (amount of in-flight data) that the sender can have. */ - pcb->ssthresh = TCP_SND_BUF; - -#if LWIP_CALLBACK_API - pcb->recv = tcp_recv_null; -#endif /* LWIP_CALLBACK_API */ - - /* Init KEEPALIVE timer */ - pcb->keep_idle = TCP_KEEPIDLE_DEFAULT; - -#if LWIP_TCP_KEEPALIVE - pcb->keep_intvl = TCP_KEEPINTVL_DEFAULT; - pcb->keep_cnt = TCP_KEEPCNT_DEFAULT; -#endif /* LWIP_TCP_KEEPALIVE */ - } - return pcb; -} - -/** - * @ingroup tcp_raw - * Creates a new TCP protocol control block but doesn't place it on - * any of the TCP PCB lists. - * The pcb is not put on any list until binding using tcp_bind(). - * If memory is not available for creating the new pcb, NULL is returned. - * - * @internal: Maybe there should be a idle TCP PCB list where these - * PCBs are put on. Port reservation using tcp_bind() is implemented but - * allocated pcbs that are not bound can't be killed automatically if wanting - * to allocate a pcb with higher prio (@see tcp_kill_prio()) - * - * @return a new tcp_pcb that initially is in state CLOSED - */ -struct tcp_pcb * -tcp_new(void) -{ - return tcp_alloc(TCP_PRIO_NORMAL); -} - -/** - * @ingroup tcp_raw - * Creates a new TCP protocol control block but doesn't - * place it on any of the TCP PCB lists. - * The pcb is not put on any list until binding using tcp_bind(). - * - * @param type IP address type, see @ref lwip_ip_addr_type definitions. - * If you want to listen to IPv4 and IPv6 (dual-stack) connections, - * supply @ref IPADDR_TYPE_ANY as argument and bind to @ref IP_ANY_TYPE. - * @return a new tcp_pcb that initially is in state CLOSED - */ -struct tcp_pcb * -tcp_new_ip_type(u8_t type) -{ - struct tcp_pcb *pcb; - pcb = tcp_alloc(TCP_PRIO_NORMAL); -#if LWIP_IPV4 && LWIP_IPV6 - if (pcb != NULL) { - IP_SET_TYPE_VAL(pcb->local_ip, type); - IP_SET_TYPE_VAL(pcb->remote_ip, type); - } -#else - LWIP_UNUSED_ARG(type); -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - return pcb; -} - -/** - * @ingroup tcp_raw - * Specifies the program specific state that should be passed to all - * other callback functions. The "pcb" argument is the current TCP - * connection control block, and the "arg" argument is the argument - * that will be passed to the callbacks. - * - * @param pcb tcp_pcb to set the callback argument - * @param arg void pointer argument to pass to callback functions - */ -void -tcp_arg(struct tcp_pcb *pcb, void *arg) -{ - LWIP_ASSERT_CORE_LOCKED(); - /* This function is allowed to be called for both listen pcbs and - connection pcbs. */ - if (pcb != NULL) { - pcb->callback_arg = arg; - } -} -#if LWIP_CALLBACK_API - -/** - * @ingroup tcp_raw - * Sets the callback function that will be called when new data - * arrives. The callback function will be passed a NULL pbuf to - * indicate that the remote host has closed the connection. If the - * callback function returns ERR_OK or ERR_ABRT it must have - * freed the pbuf, otherwise it must not have freed it. - * - * @param pcb tcp_pcb to set the recv callback - * @param recv callback function to call for this pcb when data is received - */ -void -tcp_recv(struct tcp_pcb *pcb, tcp_recv_fn recv) -{ - LWIP_ASSERT_CORE_LOCKED(); - if (pcb != NULL) { - LWIP_ASSERT("invalid socket state for recv callback", pcb->state != LISTEN); - pcb->recv = recv; - } -} - -/** - * @ingroup tcp_raw - * Specifies the callback function that should be called when data has - * successfully been received (i.e., acknowledged) by the remote - * host. The len argument passed to the callback function gives the - * amount bytes that was acknowledged by the last acknowledgment. - * - * @param pcb tcp_pcb to set the sent callback - * @param sent callback function to call for this pcb when data is successfully sent - */ -void -tcp_sent(struct tcp_pcb *pcb, tcp_sent_fn sent) -{ - LWIP_ASSERT_CORE_LOCKED(); - if (pcb != NULL) { - LWIP_ASSERT("invalid socket state for sent callback", pcb->state != LISTEN); - pcb->sent = sent; - } -} - -/** - * @ingroup tcp_raw - * Used to specify the function that should be called when a fatal error - * has occurred on the connection. - * - * If a connection is aborted because of an error, the application is - * alerted of this event by the err callback. Errors that might abort a - * connection are when there is a shortage of memory. The callback - * function to be called is set using the tcp_err() function. - * - * @note The corresponding pcb is already freed when this callback is called! - * - * @param pcb tcp_pcb to set the err callback - * @param err callback function to call for this pcb when a fatal error - * has occurred on the connection - */ -void -tcp_err(struct tcp_pcb *pcb, tcp_err_fn err) -{ - LWIP_ASSERT_CORE_LOCKED(); - if (pcb != NULL) { - LWIP_ASSERT("invalid socket state for err callback", pcb->state != LISTEN); - pcb->errf = err; - } -} - -/** - * @ingroup tcp_raw - * Used for specifying the function that should be called when a - * LISTENing connection has been connected to another host. - * - * @param pcb tcp_pcb to set the accept callback - * @param accept callback function to call for this pcb when LISTENing - * connection has been connected to another host - */ -void -tcp_accept(struct tcp_pcb *pcb, tcp_accept_fn accept) -{ - LWIP_ASSERT_CORE_LOCKED(); - if ((pcb != NULL) && (pcb->state == LISTEN)) { - struct tcp_pcb_listen *lpcb = (struct tcp_pcb_listen *)pcb; - lpcb->accept = accept; - } -} -#endif /* LWIP_CALLBACK_API */ - - -/** - * @ingroup tcp_raw - * Specifies the polling interval and the callback function that should - * be called to poll the application. The interval is specified in - * number of TCP coarse grained timer shots, which typically occurs - * twice a second. An interval of 10 means that the application would - * be polled every 5 seconds. - * - * When a connection is idle (i.e., no data is either transmitted or - * received), lwIP will repeatedly poll the application by calling a - * specified callback function. This can be used either as a watchdog - * timer for killing connections that have stayed idle for too long, or - * as a method of waiting for memory to become available. For instance, - * if a call to tcp_write() has failed because memory wasn't available, - * the application may use the polling functionality to call tcp_write() - * again when the connection has been idle for a while. - */ -void -tcp_poll(struct tcp_pcb *pcb, tcp_poll_fn poll, u8_t interval) -{ - LWIP_ASSERT_CORE_LOCKED(); - - LWIP_ERROR("tcp_poll: invalid pcb", pcb != NULL, return); - LWIP_ASSERT("invalid socket state for poll", pcb->state != LISTEN); - -#if LWIP_CALLBACK_API - pcb->poll = poll; -#else /* LWIP_CALLBACK_API */ - LWIP_UNUSED_ARG(poll); -#endif /* LWIP_CALLBACK_API */ - pcb->pollinterval = interval; -} - -/** - * Purges a TCP PCB. Removes any buffered data and frees the buffer memory - * (pcb->ooseq, pcb->unsent and pcb->unacked are freed). - * - * @param pcb tcp_pcb to purge. The pcb itself is not deallocated! - */ -void -tcp_pcb_purge(struct tcp_pcb *pcb) -{ - LWIP_ERROR("tcp_pcb_purge: invalid pcb", pcb != NULL, return); - - if (pcb->state != CLOSED && - pcb->state != TIME_WAIT && - pcb->state != LISTEN) { - - LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge\n")); - - tcp_backlog_accepted(pcb); - - if (pcb->refused_data != NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->refused_data\n")); - pbuf_free(pcb->refused_data); - pcb->refused_data = NULL; - } - if (pcb->unsent != NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: not all data sent\n")); - } - if (pcb->unacked != NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->unacked\n")); - } -#if TCP_QUEUE_OOSEQ - if (pcb->ooseq != NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->ooseq\n")); - tcp_free_ooseq(pcb); - } -#endif /* TCP_QUEUE_OOSEQ */ - - /* Stop the retransmission timer as it will expect data on unacked - queue if it fires */ - pcb->rtime = -1; - - tcp_segs_free(pcb->unsent); - tcp_segs_free(pcb->unacked); - pcb->unacked = pcb->unsent = NULL; -#if TCP_OVERSIZE - pcb->unsent_oversize = 0; -#endif /* TCP_OVERSIZE */ - } -} - -/** - * Purges the PCB and removes it from a PCB list. Any delayed ACKs are sent first. - * - * @param pcblist PCB list to purge. - * @param pcb tcp_pcb to purge. The pcb itself is NOT deallocated! - */ -void -tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb) -{ - LWIP_ASSERT("tcp_pcb_remove: invalid pcb", pcb != NULL); - LWIP_ASSERT("tcp_pcb_remove: invalid pcblist", pcblist != NULL); - - TCP_RMV(pcblist, pcb); - - tcp_pcb_purge(pcb); - - /* if there is an outstanding delayed ACKs, send it */ - if ((pcb->state != TIME_WAIT) && - (pcb->state != LISTEN) && - (pcb->flags & TF_ACK_DELAY)) { - tcp_ack_now(pcb); - tcp_output(pcb); - } - - if (pcb->state != LISTEN) { - LWIP_ASSERT("unsent segments leaking", pcb->unsent == NULL); - LWIP_ASSERT("unacked segments leaking", pcb->unacked == NULL); -#if TCP_QUEUE_OOSEQ - LWIP_ASSERT("ooseq segments leaking", pcb->ooseq == NULL); -#endif /* TCP_QUEUE_OOSEQ */ - } - - pcb->state = CLOSED; - /* reset the local port to prevent the pcb from being 'bound' */ - pcb->local_port = 0; - - LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane()); -} - -/** - * Calculates a new initial sequence number for new connections. - * - * @return u32_t pseudo random sequence number - */ -u32_t -tcp_next_iss(struct tcp_pcb *pcb) -{ -#ifdef LWIP_HOOK_TCP_ISN - LWIP_ASSERT("tcp_next_iss: invalid pcb", pcb != NULL); - return LWIP_HOOK_TCP_ISN(&pcb->local_ip, pcb->local_port, &pcb->remote_ip, pcb->remote_port); -#else /* LWIP_HOOK_TCP_ISN */ - static u32_t iss = 6510; - - LWIP_ASSERT("tcp_next_iss: invalid pcb", pcb != NULL); - LWIP_UNUSED_ARG(pcb); - - iss += tcp_ticks; /* XXX */ - return iss; -#endif /* LWIP_HOOK_TCP_ISN */ -} - -#if TCP_CALCULATE_EFF_SEND_MSS -/** - * Calculates the effective send mss that can be used for a specific IP address - * by calculating the minimum of TCP_MSS and the mtu (if set) of the target - * netif (if not NULL). - */ -u16_t -tcp_eff_send_mss_netif(u16_t sendmss, struct netif *outif, const ip_addr_t *dest) -{ - u16_t mss_s; - u16_t mtu; - - LWIP_UNUSED_ARG(dest); /* in case IPv6 is disabled */ - - LWIP_ASSERT("tcp_eff_send_mss_netif: invalid dst_ip", dest != NULL); - -#if LWIP_IPV6 -#if LWIP_IPV4 - if (IP_IS_V6(dest)) -#endif /* LWIP_IPV4 */ - { - /* First look in destination cache, to see if there is a Path MTU. */ - mtu = nd6_get_destination_mtu(ip_2_ip6(dest), outif); - } -#if LWIP_IPV4 - else -#endif /* LWIP_IPV4 */ -#endif /* LWIP_IPV6 */ -#if LWIP_IPV4 - { - if (outif == NULL) { - return sendmss; - } - mtu = outif->mtu; - } -#endif /* LWIP_IPV4 */ - - if (mtu != 0) { - u16_t offset; -#if LWIP_IPV6 -#if LWIP_IPV4 - if (IP_IS_V6(dest)) -#endif /* LWIP_IPV4 */ - { - offset = IP6_HLEN + TCP_HLEN; - } -#if LWIP_IPV4 - else -#endif /* LWIP_IPV4 */ -#endif /* LWIP_IPV6 */ -#if LWIP_IPV4 - { - offset = IP_HLEN + TCP_HLEN; - } -#endif /* LWIP_IPV4 */ - mss_s = (mtu > offset) ? (u16_t)(mtu - offset) : 0; - /* RFC 1122, chap 4.2.2.6: - * Eff.snd.MSS = min(SendMSS+20, MMS_S) - TCPhdrsize - IPoptionsize - * We correct for TCP options in tcp_write(), and don't support IP options. - */ - sendmss = LWIP_MIN(sendmss, mss_s); - } - return sendmss; -} -#endif /* TCP_CALCULATE_EFF_SEND_MSS */ - -/** Helper function for tcp_netif_ip_addr_changed() that iterates a pcb list */ -static void -tcp_netif_ip_addr_changed_pcblist(const ip_addr_t *old_addr, struct tcp_pcb *pcb_list) -{ - struct tcp_pcb *pcb; - pcb = pcb_list; - - LWIP_ASSERT("tcp_netif_ip_addr_changed_pcblist: invalid old_addr", old_addr != NULL); - - while (pcb != NULL) { - /* PCB bound to current local interface address? */ - if (ip_addr_cmp(&pcb->local_ip, old_addr) -#if LWIP_AUTOIP - /* connections to link-local addresses must persist (RFC3927 ch. 1.9) */ - && (!IP_IS_V4_VAL(pcb->local_ip) || !ip4_addr_islinklocal(ip_2_ip4(&pcb->local_ip))) -#endif /* LWIP_AUTOIP */ - ) { - /* this connection must be aborted */ - struct tcp_pcb *next = pcb->next; - LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: aborting TCP pcb %p\n", (void *)pcb)); - tcp_abort(pcb); - pcb = next; - } else { - pcb = pcb->next; - } - } -} - -/** This function is called from netif.c when address is changed or netif is removed - * - * @param old_addr IP address of the netif before change - * @param new_addr IP address of the netif after change or NULL if netif has been removed - */ -void -tcp_netif_ip_addr_changed(const ip_addr_t *old_addr, const ip_addr_t *new_addr) -{ - struct tcp_pcb_listen *lpcb; - - if (!ip_addr_isany(old_addr)) { - tcp_netif_ip_addr_changed_pcblist(old_addr, tcp_active_pcbs); - tcp_netif_ip_addr_changed_pcblist(old_addr, tcp_bound_pcbs); - - if (!ip_addr_isany(new_addr)) { - /* PCB bound to current local interface address? */ - for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { - /* PCB bound to current local interface address? */ - if (ip_addr_cmp(&lpcb->local_ip, old_addr)) { - /* The PCB is listening to the old ipaddr and - * is set to listen to the new one instead */ - ip_addr_copy(lpcb->local_ip, *new_addr); - } - } - } - } -} - -const char * -tcp_debug_state_str(enum tcp_state s) -{ - return tcp_state_str[s]; -} - -err_t -tcp_tcp_get_tcp_addrinfo(struct tcp_pcb *pcb, int local, ip_addr_t *addr, u16_t *port) -{ - if (pcb) { - if (local) { - if (addr) { - *addr = pcb->local_ip; - } - if (port) { - *port = pcb->local_port; - } - } else { - if (addr) { - *addr = pcb->remote_ip; - } - if (port) { - *port = pcb->remote_port; - } - } - return ERR_OK; - } - return ERR_VAL; -} - -#if TCP_QUEUE_OOSEQ -/* Free all ooseq pbufs (and possibly reset SACK state) */ -void -tcp_free_ooseq(struct tcp_pcb *pcb) -{ - if (pcb->ooseq) { - tcp_segs_free(pcb->ooseq); - pcb->ooseq = NULL; -#if LWIP_TCP_SACK_OUT - memset(pcb->rcv_sacks, 0, sizeof(pcb->rcv_sacks)); -#endif /* LWIP_TCP_SACK_OUT */ - } -} -#endif /* TCP_QUEUE_OOSEQ */ - -#if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG -/** - * Print a tcp header for debugging purposes. - * - * @param tcphdr pointer to a struct tcp_hdr - */ -void -tcp_debug_print(struct tcp_hdr *tcphdr) -{ - LWIP_DEBUGF(TCP_DEBUG, ("TCP header:\n")); - LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(TCP_DEBUG, ("| %5"U16_F" | %5"U16_F" | (src port, dest port)\n", - lwip_ntohs(tcphdr->src), lwip_ntohs(tcphdr->dest))); - LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(TCP_DEBUG, ("| %010"U32_F" | (seq no)\n", - lwip_ntohl(tcphdr->seqno))); - LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(TCP_DEBUG, ("| %010"U32_F" | (ack no)\n", - lwip_ntohl(tcphdr->ackno))); - LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(TCP_DEBUG, ("| %2"U16_F" | |%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"| %5"U16_F" | (hdrlen, flags (", - TCPH_HDRLEN(tcphdr), - (u16_t)(TCPH_FLAGS(tcphdr) >> 5 & 1), - (u16_t)(TCPH_FLAGS(tcphdr) >> 4 & 1), - (u16_t)(TCPH_FLAGS(tcphdr) >> 3 & 1), - (u16_t)(TCPH_FLAGS(tcphdr) >> 2 & 1), - (u16_t)(TCPH_FLAGS(tcphdr) >> 1 & 1), - (u16_t)(TCPH_FLAGS(tcphdr) & 1), - lwip_ntohs(tcphdr->wnd))); - tcp_debug_print_flags(TCPH_FLAGS(tcphdr)); - LWIP_DEBUGF(TCP_DEBUG, ("), win)\n")); - LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(TCP_DEBUG, ("| 0x%04"X16_F" | %5"U16_F" | (chksum, urgp)\n", - lwip_ntohs(tcphdr->chksum), lwip_ntohs(tcphdr->urgp))); - LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); -} - -/** - * Print a tcp state for debugging purposes. - * - * @param s enum tcp_state to print - */ -void -tcp_debug_print_state(enum tcp_state s) -{ - LWIP_DEBUGF(TCP_DEBUG, ("State: %s\n", tcp_state_str[s])); -} - -/** - * Print tcp flags for debugging purposes. - * - * @param flags tcp flags, all active flags are printed - */ -void -tcp_debug_print_flags(u8_t flags) -{ - if (flags & TCP_FIN) { - LWIP_DEBUGF(TCP_DEBUG, ("FIN ")); - } - if (flags & TCP_SYN) { - LWIP_DEBUGF(TCP_DEBUG, ("SYN ")); - } - if (flags & TCP_RST) { - LWIP_DEBUGF(TCP_DEBUG, ("RST ")); - } - if (flags & TCP_PSH) { - LWIP_DEBUGF(TCP_DEBUG, ("PSH ")); - } - if (flags & TCP_ACK) { - LWIP_DEBUGF(TCP_DEBUG, ("ACK ")); - } - if (flags & TCP_URG) { - LWIP_DEBUGF(TCP_DEBUG, ("URG ")); - } - if (flags & TCP_ECE) { - LWIP_DEBUGF(TCP_DEBUG, ("ECE ")); - } - if (flags & TCP_CWR) { - LWIP_DEBUGF(TCP_DEBUG, ("CWR ")); - } - LWIP_DEBUGF(TCP_DEBUG, ("\n")); -} - -/** - * Print all tcp_pcbs in every list for debugging purposes. - */ -void -tcp_debug_print_pcbs(void) -{ - struct tcp_pcb *pcb; - struct tcp_pcb_listen *pcbl; - - LWIP_DEBUGF(TCP_DEBUG, ("Active PCB states:\n")); - for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { - LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ", - pcb->local_port, pcb->remote_port, - pcb->snd_nxt, pcb->rcv_nxt)); - tcp_debug_print_state(pcb->state); - } - - LWIP_DEBUGF(TCP_DEBUG, ("Listen PCB states:\n")); - for (pcbl = tcp_listen_pcbs.listen_pcbs; pcbl != NULL; pcbl = pcbl->next) { - LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F" ", pcbl->local_port)); - tcp_debug_print_state(pcbl->state); - } - - LWIP_DEBUGF(TCP_DEBUG, ("TIME-WAIT PCB states:\n")); - for (pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { - LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ", - pcb->local_port, pcb->remote_port, - pcb->snd_nxt, pcb->rcv_nxt)); - tcp_debug_print_state(pcb->state); - } -} - -/** - * Check state consistency of the tcp_pcb lists. - */ -s16_t -tcp_pcbs_sane(void) -{ - struct tcp_pcb *pcb; - for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { - LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != CLOSED", pcb->state != CLOSED); - LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != LISTEN", pcb->state != LISTEN); - LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT); - } - for (pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { - LWIP_ASSERT("tcp_pcbs_sane: tw pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); - } - return 1; -} -#endif /* TCP_DEBUG */ - -#if LWIP_TCP_PCB_NUM_EXT_ARGS -/** - * @defgroup tcp_raw_extargs ext arguments - * @ingroup tcp_raw - * Additional data storage per tcp pcb\n - * @see @ref tcp_raw - * - * When LWIP_TCP_PCB_NUM_EXT_ARGS is > 0, every tcp pcb (including listen pcb) - * includes a number of additional argument entries in an array. - * - * To support memory management, in addition to a 'void *', callbacks can be - * provided to manage transition from listening pcbs to connections and to - * deallocate memory when a pcb is deallocated (see struct @ref tcp_ext_arg_callbacks). - * - * After allocating this index, use @ref tcp_ext_arg_set and @ref tcp_ext_arg_get - * to store and load arguments from this index for a given pcb. - */ - -static u8_t tcp_ext_arg_id; - -/** - * @ingroup tcp_raw_extargs - * Allocate an index to store data in ext_args member of struct tcp_pcb. - * Returned value is an index in mentioned array. - * The index is *global* over all pcbs! - * - * When @ref LWIP_TCP_PCB_NUM_EXT_ARGS is > 0, every tcp pcb (including listen pcb) - * includes a number of additional argument entries in an array. - * - * To support memory management, in addition to a 'void *', callbacks can be - * provided to manage transition from listening pcbs to connections and to - * deallocate memory when a pcb is deallocated (see struct @ref tcp_ext_arg_callbacks). - * - * After allocating this index, use @ref tcp_ext_arg_set and @ref tcp_ext_arg_get - * to store and load arguments from this index for a given pcb. - * - * @return a unique index into struct tcp_pcb.ext_args - */ -u8_t -tcp_ext_arg_alloc_id(void) -{ - u8_t result = tcp_ext_arg_id; - tcp_ext_arg_id++; - - LWIP_ASSERT_CORE_LOCKED(); - -#if LWIP_TCP_PCB_NUM_EXT_ARGS >= 255 -#error LWIP_TCP_PCB_NUM_EXT_ARGS -#endif - LWIP_ASSERT("Increase LWIP_TCP_PCB_NUM_EXT_ARGS in lwipopts.h", result < LWIP_TCP_PCB_NUM_EXT_ARGS); - return result; -} - -/** - * @ingroup tcp_raw_extargs - * Set callbacks for a given index of ext_args on the specified pcb. - * - * @param pcb tcp_pcb for which to set the callback - * @param id ext_args index to set (allocated via @ref tcp_ext_arg_alloc_id) - * @param callbacks callback table (const since it is referenced, not copied!) - */ -void -tcp_ext_arg_set_callbacks(struct tcp_pcb *pcb, uint8_t id, const struct tcp_ext_arg_callbacks * const callbacks) -{ - LWIP_ASSERT("pcb != NULL", pcb != NULL); - LWIP_ASSERT("id < LWIP_TCP_PCB_NUM_EXT_ARGS", id < LWIP_TCP_PCB_NUM_EXT_ARGS); - LWIP_ASSERT("callbacks != NULL", callbacks != NULL); - - LWIP_ASSERT_CORE_LOCKED(); - - pcb->ext_args[id].callbacks = callbacks; -} - -/** - * @ingroup tcp_raw_extargs - * Set data for a given index of ext_args on the specified pcb. - * - * @param pcb tcp_pcb for which to set the data - * @param id ext_args index to set (allocated via @ref tcp_ext_arg_alloc_id) - * @param arg data pointer to set - */ -void tcp_ext_arg_set(struct tcp_pcb *pcb, uint8_t id, void *arg) -{ - LWIP_ASSERT("pcb != NULL", pcb != NULL); - LWIP_ASSERT("id < LWIP_TCP_PCB_NUM_EXT_ARGS", id < LWIP_TCP_PCB_NUM_EXT_ARGS); - - LWIP_ASSERT_CORE_LOCKED(); - - pcb->ext_args[id].data = arg; -} - -/** - * @ingroup tcp_raw_extargs - * Set data for a given index of ext_args on the specified pcb. - * - * @param pcb tcp_pcb for which to set the data - * @param id ext_args index to set (allocated via @ref tcp_ext_arg_alloc_id) - * @return data pointer at the given index - */ -void *tcp_ext_arg_get(const struct tcp_pcb *pcb, uint8_t id) -{ - LWIP_ASSERT("pcb != NULL", pcb != NULL); - LWIP_ASSERT("id < LWIP_TCP_PCB_NUM_EXT_ARGS", id < LWIP_TCP_PCB_NUM_EXT_ARGS); - - LWIP_ASSERT_CORE_LOCKED(); - - return pcb->ext_args[id].data; -} - -/** This function calls the "destroy" callback for all ext_args once a pcb is - * freed. - */ -static void -tcp_ext_arg_invoke_callbacks_destroyed(struct tcp_pcb_ext_args *ext_args) -{ - int i; - LWIP_ASSERT("ext_args != NULL", ext_args != NULL); - - for (i = 0; i < LWIP_TCP_PCB_NUM_EXT_ARGS; i++) { - if (ext_args[i].callbacks != NULL) { - if (ext_args[i].callbacks->destroy != NULL) { - ext_args[i].callbacks->destroy((u8_t)i, ext_args[i].data); - } - } - } -} - -/** This function calls the "passive_open" callback for all ext_args if a connection - * is in the process of being accepted. This is called just after the SYN is - * received and before a SYN/ACK is sent, to allow to modify the very first - * segment sent even on passive open. Naturally, the "accepted" callback of the - * pcb has not been called yet! - */ -err_t -tcp_ext_arg_invoke_callbacks_passive_open(struct tcp_pcb_listen *lpcb, struct tcp_pcb *cpcb) -{ - int i; - LWIP_ASSERT("lpcb != NULL", lpcb != NULL); - LWIP_ASSERT("cpcb != NULL", cpcb != NULL); - - for (i = 0; i < LWIP_TCP_PCB_NUM_EXT_ARGS; i++) { - if (lpcb->ext_args[i].callbacks != NULL) { - if (lpcb->ext_args[i].callbacks->passive_open != NULL) { - err_t err = lpcb->ext_args[i].callbacks->passive_open((u8_t)i, lpcb, cpcb); - if (err != ERR_OK) { - return err; - } - } - } - } - return ERR_OK; -} -#endif /* LWIP_TCP_PCB_NUM_EXT_ARGS */ - -#endif /* LWIP_TCP */ diff --git a/third-party/lwip-2.1.2/core/tcp_in.c b/third-party/lwip-2.1.2/core/tcp_in.c deleted file mode 100644 index 428a6f48..00000000 --- a/third-party/lwip-2.1.2/core/tcp_in.c +++ /dev/null @@ -1,2178 +0,0 @@ -/** - * @file - * Transmission Control Protocol, incoming traffic - * - * The input processing functions of the TCP layer. - * - * These functions are generally called in the order (ip_input() ->) - * tcp_input() -> * tcp_process() -> tcp_receive() (-> application). - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#include "lwip/opt.h" - -#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/priv/tcp_priv.h" -#include "lwip/def.h" -#include "lwip/ip_addr.h" -#include "lwip/netif.h" -#include "lwip/mem.h" -#include "lwip/memp.h" -#include "lwip/inet_chksum.h" -#include "lwip/stats.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#if LWIP_ND6_TCP_REACHABILITY_HINTS -#include "lwip/nd6.h" -#endif /* LWIP_ND6_TCP_REACHABILITY_HINTS */ - -#include - -#ifdef LWIP_HOOK_FILENAME -#include LWIP_HOOK_FILENAME -#endif - -/** Initial CWND calculation as defined RFC 2581 */ -#define LWIP_TCP_CALC_INITIAL_CWND(mss) ((tcpwnd_size_t)LWIP_MIN((4U * (mss)), LWIP_MAX((2U * (mss)), 4380U))) - -/* These variables are global to all functions involved in the input - processing of TCP segments. They are set by the tcp_input() - function. */ -static struct tcp_seg inseg; -static struct tcp_hdr *tcphdr; -static u16_t tcphdr_optlen; -static u16_t tcphdr_opt1len; -static u8_t *tcphdr_opt2; -static u16_t tcp_optidx; -static u32_t seqno, ackno; -static tcpwnd_size_t recv_acked; -static u16_t tcplen; -static u8_t flags; - -static u8_t recv_flags; -static struct pbuf *recv_data; - -struct tcp_pcb *tcp_input_pcb; - -/* Forward declarations. */ -static err_t tcp_process(struct tcp_pcb *pcb); -static void tcp_receive(struct tcp_pcb *pcb); -static void tcp_parseopt(struct tcp_pcb *pcb); - -static void tcp_listen_input(struct tcp_pcb_listen *pcb); -static void tcp_timewait_input(struct tcp_pcb *pcb); - -static int tcp_input_delayed_close(struct tcp_pcb *pcb); - -#if LWIP_TCP_SACK_OUT -static void tcp_add_sack(struct tcp_pcb *pcb, u32_t left, u32_t right); -static void tcp_remove_sacks_lt(struct tcp_pcb *pcb, u32_t seq); -#if defined(TCP_OOSEQ_BYTES_LIMIT) || defined(TCP_OOSEQ_PBUFS_LIMIT) -static void tcp_remove_sacks_gt(struct tcp_pcb *pcb, u32_t seq); -#endif /* TCP_OOSEQ_BYTES_LIMIT || TCP_OOSEQ_PBUFS_LIMIT */ -#endif /* LWIP_TCP_SACK_OUT */ - -/** - * The initial input processing of TCP. It verifies the TCP header, demultiplexes - * the segment between the PCBs and passes it on to tcp_process(), which implements - * the TCP finite state machine. This function is called by the IP layer (in - * ip_input()). - * - * @param p received TCP segment to process (p->payload pointing to the TCP header) - * @param inp network interface on which this segment was received - */ -void -tcp_input(struct pbuf *p, struct netif *inp) -{ - struct tcp_pcb *pcb, *prev; - struct tcp_pcb_listen *lpcb; -#if SO_REUSE - struct tcp_pcb *lpcb_prev = NULL; - struct tcp_pcb_listen *lpcb_any = NULL; -#endif /* SO_REUSE */ - u8_t hdrlen_bytes; - err_t err; - - LWIP_UNUSED_ARG(inp); - LWIP_ASSERT_CORE_LOCKED(); - LWIP_ASSERT("tcp_input: invalid pbuf", p != NULL); - - PERF_START; - - TCP_STATS_INC(tcp.recv); - MIB2_STATS_INC(mib2.tcpinsegs); - - tcphdr = (struct tcp_hdr *)p->payload; - -#if TCP_INPUT_DEBUG - tcp_debug_print(tcphdr); -#endif - - /* Check that TCP header fits in payload */ - if (p->len < TCP_HLEN) { - /* drop short packets */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet (%"U16_F" bytes) discarded\n", p->tot_len)); - TCP_STATS_INC(tcp.lenerr); - goto dropped; - } - - /* Don't even process incoming broadcasts/multicasts. */ - if (ip_addr_isbroadcast(ip_current_dest_addr(), ip_current_netif()) || - ip_addr_ismulticast(ip_current_dest_addr())) { - TCP_STATS_INC(tcp.proterr); - goto dropped; - } - -#if CHECKSUM_CHECK_TCP - IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_TCP) { - /* Verify TCP checksum. */ - u16_t chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len, - ip_current_src_addr(), ip_current_dest_addr()); - if (chksum != 0) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04"X16_F"\n", - chksum)); - tcp_debug_print(tcphdr); - TCP_STATS_INC(tcp.chkerr); - goto dropped; - } - } -#endif /* CHECKSUM_CHECK_TCP */ - - /* sanity-check header length */ - hdrlen_bytes = TCPH_HDRLEN_BYTES(tcphdr); - if ((hdrlen_bytes < TCP_HLEN) || (hdrlen_bytes > p->tot_len)) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: invalid header length (%"U16_F")\n", (u16_t)hdrlen_bytes)); - TCP_STATS_INC(tcp.lenerr); - goto dropped; - } - - /* Move the payload pointer in the pbuf so that it points to the - TCP data instead of the TCP header. */ - tcphdr_optlen = (u16_t)(hdrlen_bytes - TCP_HLEN); - tcphdr_opt2 = NULL; - if (p->len >= hdrlen_bytes) { - /* all options are in the first pbuf */ - tcphdr_opt1len = tcphdr_optlen; - pbuf_remove_header(p, hdrlen_bytes); /* cannot fail */ - } else { - u16_t opt2len; - /* TCP header fits into first pbuf, options don't - data is in the next pbuf */ - /* there must be a next pbuf, due to hdrlen_bytes sanity check above */ - LWIP_ASSERT("p->next != NULL", p->next != NULL); - - /* advance over the TCP header (cannot fail) */ - pbuf_remove_header(p, TCP_HLEN); - - /* determine how long the first and second parts of the options are */ - tcphdr_opt1len = p->len; - opt2len = (u16_t)(tcphdr_optlen - tcphdr_opt1len); - - /* options continue in the next pbuf: set p to zero length and hide the - options in the next pbuf (adjusting p->tot_len) */ - pbuf_remove_header(p, tcphdr_opt1len); - - /* check that the options fit in the second pbuf */ - if (opt2len > p->next->len) { - /* drop short packets */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: options overflow second pbuf (%"U16_F" bytes)\n", p->next->len)); - TCP_STATS_INC(tcp.lenerr); - goto dropped; - } - - /* remember the pointer to the second part of the options */ - tcphdr_opt2 = (u8_t *)p->next->payload; - - /* advance p->next to point after the options, and manually - adjust p->tot_len to keep it consistent with the changed p->next */ - pbuf_remove_header(p->next, opt2len); - p->tot_len = (u16_t)(p->tot_len - opt2len); - - LWIP_ASSERT("p->len == 0", p->len == 0); - LWIP_ASSERT("p->tot_len == p->next->tot_len", p->tot_len == p->next->tot_len); - } - - /* Convert fields in TCP header to host byte order. */ - tcphdr->src = lwip_ntohs(tcphdr->src); - tcphdr->dest = lwip_ntohs(tcphdr->dest); - seqno = tcphdr->seqno = lwip_ntohl(tcphdr->seqno); - ackno = tcphdr->ackno = lwip_ntohl(tcphdr->ackno); - tcphdr->wnd = lwip_ntohs(tcphdr->wnd); - - flags = TCPH_FLAGS(tcphdr); - tcplen = p->tot_len; - if (flags & (TCP_FIN | TCP_SYN)) { - tcplen++; - if (tcplen < p->tot_len) { - /* u16_t overflow, cannot handle this */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: length u16_t overflow, cannot handle this\n")); - TCP_STATS_INC(tcp.lenerr); - goto dropped; - } - } - - /* Demultiplex an incoming segment. First, we check if it is destined - for an active connection. */ - prev = NULL; - - for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { - LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED); - LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT); - LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN); - - /* check if PCB is bound to specific netif */ - if ((pcb->netif_idx != NETIF_NO_INDEX) && - (pcb->netif_idx != netif_get_index(ip_data.current_input_netif))) { - prev = pcb; - continue; - } - - if (pcb->remote_port == tcphdr->src && - pcb->local_port == tcphdr->dest && - ip_addr_cmp(&pcb->remote_ip, ip_current_src_addr()) && - ip_addr_cmp(&pcb->local_ip, ip_current_dest_addr())) { - /* Move this PCB to the front of the list so that subsequent - lookups will be faster (we exploit locality in TCP segment - arrivals). */ - LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb); - if (prev != NULL) { - prev->next = pcb->next; - pcb->next = tcp_active_pcbs; - tcp_active_pcbs = pcb; - } else { - TCP_STATS_INC(tcp.cachehit); - } - LWIP_ASSERT("tcp_input: pcb->next != pcb (after cache)", pcb->next != pcb); - break; - } - prev = pcb; - } - - if (pcb == NULL) { - /* If it did not go to an active connection, we check the connections - in the TIME-WAIT state. */ - for (pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { - LWIP_ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); - - /* check if PCB is bound to specific netif */ - if ((pcb->netif_idx != NETIF_NO_INDEX) && - (pcb->netif_idx != netif_get_index(ip_data.current_input_netif))) { - continue; - } - - if (pcb->remote_port == tcphdr->src && - pcb->local_port == tcphdr->dest && - ip_addr_cmp(&pcb->remote_ip, ip_current_src_addr()) && - ip_addr_cmp(&pcb->local_ip, ip_current_dest_addr())) { - /* We don't really care enough to move this PCB to the front - of the list since we are not very likely to receive that - many segments for connections in TIME-WAIT. */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for TIME_WAITing connection.\n")); -#ifdef LWIP_HOOK_TCP_INPACKET_PCB - if (LWIP_HOOK_TCP_INPACKET_PCB(pcb, tcphdr, tcphdr_optlen, tcphdr_opt1len, - tcphdr_opt2, p) == ERR_OK) -#endif - { - tcp_timewait_input(pcb); - } - pbuf_free(p); - return; - } - } - - /* Finally, if we still did not get a match, we check all PCBs that - are LISTENing for incoming connections. */ - prev = NULL; - for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { - /* check if PCB is bound to specific netif */ - if ((lpcb->netif_idx != NETIF_NO_INDEX) && - (lpcb->netif_idx != netif_get_index(ip_data.current_input_netif))) { - prev = (struct tcp_pcb *)lpcb; - continue; - } - - if (lpcb->local_port == tcphdr->dest) { - if (IP_IS_ANY_TYPE_VAL(lpcb->local_ip)) { - /* found an ANY TYPE (IPv4/IPv6) match */ -#if SO_REUSE - lpcb_any = lpcb; - lpcb_prev = prev; -#else /* SO_REUSE */ - break; -#endif /* SO_REUSE */ - } else if (IP_ADDR_PCB_VERSION_MATCH_EXACT(lpcb, ip_current_dest_addr())) { - if (ip_addr_cmp(&lpcb->local_ip, ip_current_dest_addr())) { - /* found an exact match */ - break; - } else if (ip_addr_isany(&lpcb->local_ip)) { - /* found an ANY-match */ -#if SO_REUSE - lpcb_any = lpcb; - lpcb_prev = prev; -#else /* SO_REUSE */ - break; -#endif /* SO_REUSE */ - } - } - } - prev = (struct tcp_pcb *)lpcb; - } -#if SO_REUSE - /* first try specific local IP */ - if (lpcb == NULL) { - /* only pass to ANY if no specific local IP has been found */ - lpcb = lpcb_any; - prev = lpcb_prev; - } -#endif /* SO_REUSE */ - if (lpcb != NULL) { - /* Move this PCB to the front of the list so that subsequent - lookups will be faster (we exploit locality in TCP segment - arrivals). */ - if (prev != NULL) { - ((struct tcp_pcb_listen *)prev)->next = lpcb->next; - /* our successor is the remainder of the listening list */ - lpcb->next = tcp_listen_pcbs.listen_pcbs; - /* put this listening pcb at the head of the listening list */ - tcp_listen_pcbs.listen_pcbs = lpcb; - } else { - TCP_STATS_INC(tcp.cachehit); - } - - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n")); -#ifdef LWIP_HOOK_TCP_INPACKET_PCB - if (LWIP_HOOK_TCP_INPACKET_PCB((struct tcp_pcb *)lpcb, tcphdr, tcphdr_optlen, - tcphdr_opt1len, tcphdr_opt2, p) == ERR_OK) -#endif - { - tcp_listen_input(lpcb); - } - pbuf_free(p); - return; - } - } - -#if TCP_INPUT_DEBUG - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("+-+-+-+-+-+-+-+-+-+-+-+-+-+- tcp_input: flags ")); - tcp_debug_print_flags(TCPH_FLAGS(tcphdr)); - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n")); -#endif /* TCP_INPUT_DEBUG */ - - -#ifdef LWIP_HOOK_TCP_INPACKET_PCB - if ((pcb != NULL) && LWIP_HOOK_TCP_INPACKET_PCB(pcb, tcphdr, tcphdr_optlen, - tcphdr_opt1len, tcphdr_opt2, p) != ERR_OK) { - pbuf_free(p); - return; - } -#endif - if (pcb != NULL) { - /* The incoming segment belongs to a connection. */ -#if TCP_INPUT_DEBUG - tcp_debug_print_state(pcb->state); -#endif /* TCP_INPUT_DEBUG */ - - /* Set up a tcp_seg structure. */ - inseg.next = NULL; - inseg.len = p->tot_len; - inseg.p = p; - inseg.tcphdr = tcphdr; - - recv_data = NULL; - recv_flags = 0; - recv_acked = 0; - - if (flags & TCP_PSH) { - p->flags |= PBUF_FLAG_PUSH; - } - - /* If there is data which was previously "refused" by upper layer */ - if (pcb->refused_data != NULL) { - if ((tcp_process_refused_data(pcb) == ERR_ABRT) || - ((pcb->refused_data != NULL) && (tcplen > 0))) { - /* pcb has been aborted or refused data is still refused and the new - segment contains data */ - if (pcb->rcv_ann_wnd == 0) { - /* this is a zero-window probe, we respond to it with current RCV.NXT - and drop the data segment */ - tcp_send_empty_ack(pcb); - } - TCP_STATS_INC(tcp.drop); - MIB2_STATS_INC(mib2.tcpinerrs); - goto aborted; - } - } - tcp_input_pcb = pcb; - err = tcp_process(pcb); - /* A return value of ERR_ABRT means that tcp_abort() was called - and that the pcb has been freed. If so, we don't do anything. */ - if (err != ERR_ABRT) { - if (recv_flags & TF_RESET) { - /* TF_RESET means that the connection was reset by the other - end. We then call the error callback to inform the - application that the connection is dead before we - deallocate the PCB. */ - TCP_EVENT_ERR(pcb->state, pcb->errf, pcb->callback_arg, ERR_RST); - tcp_pcb_remove(&tcp_active_pcbs, pcb); - tcp_free(pcb); - } else { - err = ERR_OK; - /* If the application has registered a "sent" function to be - called when new send buffer space is available, we call it - now. */ - if (recv_acked > 0) { - u16_t acked16; -#if LWIP_WND_SCALE - /* recv_acked is u32_t but the sent callback only takes a u16_t, - so we might have to call it multiple times. */ - u32_t acked = recv_acked; - while (acked > 0) { - acked16 = (u16_t)LWIP_MIN(acked, 0xffffu); - acked -= acked16; -#else - { - acked16 = recv_acked; -#endif - TCP_EVENT_SENT(pcb, (u16_t)acked16, err); - if (err == ERR_ABRT) { - goto aborted; - } - } - recv_acked = 0; - } - if (tcp_input_delayed_close(pcb)) { - goto aborted; - } -#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE - while (recv_data != NULL) { - struct pbuf *rest = NULL; - pbuf_split_64k(recv_data, &rest); -#else /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ - if (recv_data != NULL) { -#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ - - LWIP_ASSERT("pcb->refused_data == NULL", pcb->refused_data == NULL); - if (pcb->flags & TF_RXCLOSED) { - /* received data although already closed -> abort (send RST) to - notify the remote host that not all data has been processed */ - pbuf_free(recv_data); -#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE - if (rest != NULL) { - pbuf_free(rest); - } -#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ - tcp_abort(pcb); - goto aborted; - } - - /* Notify application that data has been received. */ - TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err); - if (err == ERR_ABRT) { -#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE - if (rest != NULL) { - pbuf_free(rest); - } -#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ - goto aborted; - } - - /* If the upper layer can't receive this data, store it */ - if (err != ERR_OK) { -#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE - if (rest != NULL) { - pbuf_cat(recv_data, rest); - } -#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ - pcb->refused_data = recv_data; - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: keep incoming packet, because pcb is \"full\"\n")); -#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE - break; - } else { - /* Upper layer received the data, go on with the rest if > 64K */ - recv_data = rest; -#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ - } - } - - /* If a FIN segment was received, we call the callback - function with a NULL buffer to indicate EOF. */ - if (recv_flags & TF_GOT_FIN) { - if (pcb->refused_data != NULL) { - /* Delay this if we have refused data. */ - pcb->refused_data->flags |= PBUF_FLAG_TCP_FIN; - } else { - /* correct rcv_wnd as the application won't call tcp_recved() - for the FIN's seqno */ - if (pcb->rcv_wnd != TCP_WND_MAX(pcb)) { - pcb->rcv_wnd++; - } - TCP_EVENT_CLOSED(pcb, err); - if (err == ERR_ABRT) { - goto aborted; - } - } - } - - tcp_input_pcb = NULL; - if (tcp_input_delayed_close(pcb)) { - goto aborted; - } - /* Try to send something out. */ - tcp_output(pcb); -#if TCP_INPUT_DEBUG -#if TCP_DEBUG - tcp_debug_print_state(pcb->state); -#endif /* TCP_DEBUG */ -#endif /* TCP_INPUT_DEBUG */ - } - } - /* Jump target if pcb has been aborted in a callback (by calling tcp_abort()). - Below this line, 'pcb' may not be dereferenced! */ -aborted: - tcp_input_pcb = NULL; - recv_data = NULL; - - /* give up our reference to inseg.p */ - if (inseg.p != NULL) { - pbuf_free(inseg.p); - inseg.p = NULL; - } - } else { - /* If no matching PCB was found, send a TCP RST (reset) to the - sender. */ - LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, resetting.\n")); - if (!(TCPH_FLAGS(tcphdr) & TCP_RST)) { - TCP_STATS_INC(tcp.proterr); - TCP_STATS_INC(tcp.drop); - tcp_rst(NULL, ackno, seqno + tcplen, ip_current_dest_addr(), - ip_current_src_addr(), tcphdr->dest, tcphdr->src); - } - pbuf_free(p); - } - - LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane()); - PERF_STOP("tcp_input"); - return; -dropped: - TCP_STATS_INC(tcp.drop); - MIB2_STATS_INC(mib2.tcpinerrs); - pbuf_free(p); -} - -/** Called from tcp_input to check for TF_CLOSED flag. This results in closing - * and deallocating a pcb at the correct place to ensure noone references it - * any more. - * @returns 1 if the pcb has been closed and deallocated, 0 otherwise - */ -static int -tcp_input_delayed_close(struct tcp_pcb *pcb) -{ - LWIP_ASSERT("tcp_input_delayed_close: invalid pcb", pcb != NULL); - - if (recv_flags & TF_CLOSED) { - /* The connection has been closed and we will deallocate the - PCB. */ - if (!(pcb->flags & TF_RXCLOSED)) { - /* Connection closed although the application has only shut down the - tx side: call the PCB's err callback and indicate the closure to - ensure the application doesn't continue using the PCB. */ - TCP_EVENT_ERR(pcb->state, pcb->errf, pcb->callback_arg, ERR_CLSD); - } - tcp_pcb_remove(&tcp_active_pcbs, pcb); - tcp_free(pcb); - return 1; - } - return 0; -} - -/** - * Called by tcp_input() when a segment arrives for a listening - * connection (from tcp_input()). - * - * @param pcb the tcp_pcb_listen for which a segment arrived - * - * @note the segment which arrived is saved in global variables, therefore only the pcb - * involved is passed as a parameter to this function - */ -static void -tcp_listen_input(struct tcp_pcb_listen *pcb) -{ - struct tcp_pcb *npcb; - u32_t iss; - err_t rc; - - if (flags & TCP_RST) { - /* An incoming RST should be ignored. Return. */ - return; - } - - LWIP_ASSERT("tcp_listen_input: invalid pcb", pcb != NULL); - - /* In the LISTEN state, we check for incoming SYN segments, - creates a new PCB, and responds with a SYN|ACK. */ - if (flags & TCP_ACK) { - /* For incoming segments with the ACK flag set, respond with a - RST. */ - LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n")); - tcp_rst((const struct tcp_pcb *)pcb, ackno, seqno + tcplen, ip_current_dest_addr(), - ip_current_src_addr(), tcphdr->dest, tcphdr->src); - } else if (flags & TCP_SYN) { - LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %"U16_F" -> %"U16_F".\n", tcphdr->src, tcphdr->dest)); -#if TCP_LISTEN_BACKLOG - if (pcb->accepts_pending >= pcb->backlog) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: listen backlog exceeded for port %"U16_F"\n", tcphdr->dest)); - return; - } -#endif /* TCP_LISTEN_BACKLOG */ - npcb = tcp_alloc(pcb->prio); - /* If a new PCB could not be created (probably due to lack of memory), - we don't do anything, but rely on the sender will retransmit the - SYN at a time when we have more memory available. */ - if (npcb == NULL) { - err_t err; - LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: could not allocate PCB\n")); - TCP_STATS_INC(tcp.memerr); - TCP_EVENT_ACCEPT(pcb, NULL, pcb->callback_arg, ERR_MEM, err); - LWIP_UNUSED_ARG(err); /* err not useful here */ - return; - } -#if TCP_LISTEN_BACKLOG - pcb->accepts_pending++; - tcp_set_flags(npcb, TF_BACKLOGPEND); -#endif /* TCP_LISTEN_BACKLOG */ - /* Set up the new PCB. */ - ip_addr_copy(npcb->local_ip, *ip_current_dest_addr()); - ip_addr_copy(npcb->remote_ip, *ip_current_src_addr()); - npcb->local_port = pcb->local_port; - npcb->remote_port = tcphdr->src; - npcb->state = SYN_RCVD; - npcb->rcv_nxt = seqno + 1; - npcb->rcv_ann_right_edge = npcb->rcv_nxt; - iss = tcp_next_iss(npcb); - npcb->snd_wl2 = iss; - npcb->snd_nxt = iss; - npcb->lastack = iss; - npcb->snd_lbb = iss; - npcb->snd_wl1 = seqno - 1;/* initialise to seqno-1 to force window update */ - npcb->callback_arg = pcb->callback_arg; -#if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG - npcb->listener = pcb; -#endif /* LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG */ - /* inherit socket options */ - npcb->so_options = pcb->so_options & SOF_INHERITED; - npcb->netif_idx = pcb->netif_idx; - /* Register the new PCB so that we can begin receiving segments - for it. */ - TCP_REG_ACTIVE(npcb); - - /* Parse any options in the SYN. */ - tcp_parseopt(npcb); - npcb->snd_wnd = tcphdr->wnd; - npcb->snd_wnd_max = npcb->snd_wnd; - -#if TCP_CALCULATE_EFF_SEND_MSS - npcb->mss = tcp_eff_send_mss(npcb->mss, &npcb->local_ip, &npcb->remote_ip); -#endif /* TCP_CALCULATE_EFF_SEND_MSS */ - - MIB2_STATS_INC(mib2.tcppassiveopens); - -#if LWIP_TCP_PCB_NUM_EXT_ARGS - if (tcp_ext_arg_invoke_callbacks_passive_open(pcb, npcb) != ERR_OK) { - tcp_abandon(npcb, 0); - return; - } -#endif - - /* Send a SYN|ACK together with the MSS option. */ - rc = tcp_enqueue_flags(npcb, TCP_SYN | TCP_ACK); - if (rc != ERR_OK) { - tcp_abandon(npcb, 0); - return; - } - tcp_output(npcb); - } - return; -} - -/** - * Called by tcp_input() when a segment arrives for a connection in - * TIME_WAIT. - * - * @param pcb the tcp_pcb for which a segment arrived - * - * @note the segment which arrived is saved in global variables, therefore only the pcb - * involved is passed as a parameter to this function - */ -static void -tcp_timewait_input(struct tcp_pcb *pcb) -{ - /* RFC 1337: in TIME_WAIT, ignore RST and ACK FINs + any 'acceptable' segments */ - /* RFC 793 3.9 Event Processing - Segment Arrives: - * - first check sequence number - we skip that one in TIME_WAIT (always - * acceptable since we only send ACKs) - * - second check the RST bit (... return) */ - if (flags & TCP_RST) { - return; - } - - LWIP_ASSERT("tcp_timewait_input: invalid pcb", pcb != NULL); - - /* - fourth, check the SYN bit, */ - if (flags & TCP_SYN) { - /* If an incoming segment is not acceptable, an acknowledgment - should be sent in reply */ - if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd)) { - /* If the SYN is in the window it is an error, send a reset */ - tcp_rst(pcb, ackno, seqno + tcplen, ip_current_dest_addr(), - ip_current_src_addr(), tcphdr->dest, tcphdr->src); - return; - } - } else if (flags & TCP_FIN) { - /* - eighth, check the FIN bit: Remain in the TIME-WAIT state. - Restart the 2 MSL time-wait timeout.*/ - pcb->tmr = tcp_ticks; - } - - if ((tcplen > 0)) { - /* Acknowledge data, FIN or out-of-window SYN */ - tcp_ack_now(pcb); - tcp_output(pcb); - } - return; -} - -/** - * Implements the TCP state machine. Called by tcp_input. In some - * states tcp_receive() is called to receive data. The tcp_seg - * argument will be freed by the caller (tcp_input()) unless the - * recv_data pointer in the pcb is set. - * - * @param pcb the tcp_pcb for which a segment arrived - * - * @note the segment which arrived is saved in global variables, therefore only the pcb - * involved is passed as a parameter to this function - */ -static err_t -tcp_process(struct tcp_pcb *pcb) -{ - struct tcp_seg *rseg; - u8_t acceptable = 0; - err_t err; - - err = ERR_OK; - - LWIP_ASSERT("tcp_process: invalid pcb", pcb != NULL); - - /* Process incoming RST segments. */ - if (flags & TCP_RST) { - /* First, determine if the reset is acceptable. */ - if (pcb->state == SYN_SENT) { - /* "In the SYN-SENT state (a RST received in response to an initial SYN), - the RST is acceptable if the ACK field acknowledges the SYN." */ - if (ackno == pcb->snd_nxt) { - acceptable = 1; - } - } else { - /* "In all states except SYN-SENT, all reset (RST) segments are validated - by checking their SEQ-fields." */ - if (seqno == pcb->rcv_nxt) { - acceptable = 1; - } else if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, - pcb->rcv_nxt + pcb->rcv_wnd)) { - /* If the sequence number is inside the window, we send a challenge ACK - and wait for a re-send with matching sequence number. - This follows RFC 5961 section 3.2 and addresses CVE-2004-0230 - (RST spoofing attack), which is present in RFC 793 RST handling. */ - tcp_ack_now(pcb); - } - } - - if (acceptable) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n")); - LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED); - recv_flags |= TF_RESET; - tcp_clear_flags(pcb, TF_ACK_DELAY); - return ERR_RST; - } else { - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n", - seqno, pcb->rcv_nxt)); - LWIP_DEBUGF(TCP_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n", - seqno, pcb->rcv_nxt)); - return ERR_OK; - } - } - - if ((flags & TCP_SYN) && (pcb->state != SYN_SENT && pcb->state != SYN_RCVD)) { - /* Cope with new connection attempt after remote end crashed */ - tcp_ack_now(pcb); - return ERR_OK; - } - - if ((pcb->flags & TF_RXCLOSED) == 0) { - /* Update the PCB (in)activity timer unless rx is closed (see tcp_shutdown) */ - pcb->tmr = tcp_ticks; - } - pcb->keep_cnt_sent = 0; - pcb->persist_probe = 0; - - tcp_parseopt(pcb); - - /* Do different things depending on the TCP state. */ - switch (pcb->state) { - case SYN_SENT: - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %"U32_F" pcb->snd_nxt %"U32_F" unacked %"U32_F"\n", ackno, - pcb->snd_nxt, lwip_ntohl(pcb->unacked->tcphdr->seqno))); - /* received SYN ACK with expected sequence number? */ - if ((flags & TCP_ACK) && (flags & TCP_SYN) - && (ackno == pcb->lastack + 1)) { - pcb->rcv_nxt = seqno + 1; - pcb->rcv_ann_right_edge = pcb->rcv_nxt; - pcb->lastack = ackno; - pcb->snd_wnd = tcphdr->wnd; - pcb->snd_wnd_max = pcb->snd_wnd; - pcb->snd_wl1 = seqno - 1; /* initialise to seqno - 1 to force window update */ - pcb->state = ESTABLISHED; - -#if TCP_CALCULATE_EFF_SEND_MSS - pcb->mss = tcp_eff_send_mss(pcb->mss, &pcb->local_ip, &pcb->remote_ip); -#endif /* TCP_CALCULATE_EFF_SEND_MSS */ - - pcb->cwnd = LWIP_TCP_CALC_INITIAL_CWND(pcb->mss); - LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_process (SENT): cwnd %"TCPWNDSIZE_F - " ssthresh %"TCPWNDSIZE_F"\n", - pcb->cwnd, pcb->ssthresh)); - LWIP_ASSERT("pcb->snd_queuelen > 0", (pcb->snd_queuelen > 0)); - --pcb->snd_queuelen; - LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %"TCPWNDSIZE_F"\n", (tcpwnd_size_t)pcb->snd_queuelen)); - rseg = pcb->unacked; - if (rseg == NULL) { - /* might happen if tcp_output fails in tcp_rexmit_rto() - in which case the segment is on the unsent list */ - rseg = pcb->unsent; - LWIP_ASSERT("no segment to free", rseg != NULL); - pcb->unsent = rseg->next; - } else { - pcb->unacked = rseg->next; - } - tcp_seg_free(rseg); - - /* If there's nothing left to acknowledge, stop the retransmit - timer, otherwise reset it to start again */ - if (pcb->unacked == NULL) { - pcb->rtime = -1; - } else { - pcb->rtime = 0; - pcb->nrtx = 0; - } - - /* Call the user specified function to call when successfully - * connected. */ - TCP_EVENT_CONNECTED(pcb, ERR_OK, err); - if (err == ERR_ABRT) { - return ERR_ABRT; - } - tcp_ack_now(pcb); - } - /* received ACK? possibly a half-open connection */ - else if (flags & TCP_ACK) { - /* send a RST to bring the other side in a non-synchronized state. */ - tcp_rst(pcb, ackno, seqno + tcplen, ip_current_dest_addr(), - ip_current_src_addr(), tcphdr->dest, tcphdr->src); - /* Resend SYN immediately (don't wait for rto timeout) to establish - connection faster, but do not send more SYNs than we otherwise would - have, or we might get caught in a loop on loopback interfaces. */ - if (pcb->nrtx < TCP_SYNMAXRTX) { - pcb->rtime = 0; - tcp_rexmit_rto(pcb); - } - } - break; - case SYN_RCVD: - if (flags & TCP_ACK) { - /* expected ACK number? */ - if (TCP_SEQ_BETWEEN(ackno, pcb->lastack + 1, pcb->snd_nxt)) { - pcb->state = ESTABLISHED; - LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); -#if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG - if (pcb->listener == NULL) { - /* listen pcb might be closed by now */ - err = ERR_VAL; - } else -#endif /* LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG */ - { -#if LWIP_CALLBACK_API - LWIP_ASSERT("pcb->listener->accept != NULL", pcb->listener->accept != NULL); -#endif - tcp_backlog_accepted(pcb); - /* Call the accept function. */ - TCP_EVENT_ACCEPT(pcb->listener, pcb, pcb->callback_arg, ERR_OK, err); - } - if (err != ERR_OK) { - /* If the accept function returns with an error, we abort - * the connection. */ - /* Already aborted? */ - if (err != ERR_ABRT) { - tcp_abort(pcb); - } - return ERR_ABRT; - } - /* If there was any data contained within this ACK, - * we'd better pass it on to the application as well. */ - tcp_receive(pcb); - - /* Prevent ACK for SYN to generate a sent event */ - if (recv_acked != 0) { - recv_acked--; - } - - pcb->cwnd = LWIP_TCP_CALC_INITIAL_CWND(pcb->mss); - LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_process (SYN_RCVD): cwnd %"TCPWNDSIZE_F - " ssthresh %"TCPWNDSIZE_F"\n", - pcb->cwnd, pcb->ssthresh)); - - if (recv_flags & TF_GOT_FIN) { - tcp_ack_now(pcb); - pcb->state = CLOSE_WAIT; - } - } else { - /* incorrect ACK number, send RST */ - tcp_rst(pcb, ackno, seqno + tcplen, ip_current_dest_addr(), - ip_current_src_addr(), tcphdr->dest, tcphdr->src); - } - } else if ((flags & TCP_SYN) && (seqno == pcb->rcv_nxt - 1)) { - /* Looks like another copy of the SYN - retransmit our SYN-ACK */ - tcp_rexmit(pcb); - } - break; - case CLOSE_WAIT: - /* FALLTHROUGH */ - case ESTABLISHED: - tcp_receive(pcb); - if (recv_flags & TF_GOT_FIN) { /* passive close */ - tcp_ack_now(pcb); - pcb->state = CLOSE_WAIT; - } - break; - case FIN_WAIT_1: - tcp_receive(pcb); - if (recv_flags & TF_GOT_FIN) { - if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt) && - pcb->unsent == NULL) { - LWIP_DEBUGF(TCP_DEBUG, - ("TCP connection closed: FIN_WAIT_1 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); - tcp_ack_now(pcb); - tcp_pcb_purge(pcb); - TCP_RMV_ACTIVE(pcb); - pcb->state = TIME_WAIT; - TCP_REG(&tcp_tw_pcbs, pcb); - } else { - tcp_ack_now(pcb); - pcb->state = CLOSING; - } - } else if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt) && - pcb->unsent == NULL) { - pcb->state = FIN_WAIT_2; - } - break; - case FIN_WAIT_2: - tcp_receive(pcb); - if (recv_flags & TF_GOT_FIN) { - LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: FIN_WAIT_2 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); - tcp_ack_now(pcb); - tcp_pcb_purge(pcb); - TCP_RMV_ACTIVE(pcb); - pcb->state = TIME_WAIT; - TCP_REG(&tcp_tw_pcbs, pcb); - } - break; - case CLOSING: - tcp_receive(pcb); - if ((flags & TCP_ACK) && ackno == pcb->snd_nxt && pcb->unsent == NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: CLOSING %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); - tcp_pcb_purge(pcb); - TCP_RMV_ACTIVE(pcb); - pcb->state = TIME_WAIT; - TCP_REG(&tcp_tw_pcbs, pcb); - } - break; - case LAST_ACK: - tcp_receive(pcb); - if ((flags & TCP_ACK) && ackno == pcb->snd_nxt && pcb->unsent == NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: LAST_ACK %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); - /* bugfix #21699: don't set pcb->state to CLOSED here or we risk leaking segments */ - recv_flags |= TF_CLOSED; - } - break; - default: - break; - } - return ERR_OK; -} - -#if TCP_QUEUE_OOSEQ -/** - * Insert segment into the list (segments covered with new one will be deleted) - * - * Called from tcp_receive() - */ -static void -tcp_oos_insert_segment(struct tcp_seg *cseg, struct tcp_seg *next) -{ - struct tcp_seg *old_seg; - - LWIP_ASSERT("tcp_oos_insert_segment: invalid cseg", cseg != NULL); - - if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) { - /* received segment overlaps all following segments */ - tcp_segs_free(next); - next = NULL; - } else { - /* delete some following segments - oos queue may have segments with FIN flag */ - while (next && - TCP_SEQ_GEQ((seqno + cseg->len), - (next->tcphdr->seqno + next->len))) { - /* cseg with FIN already processed */ - if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) { - TCPH_SET_FLAG(cseg->tcphdr, TCP_FIN); - } - old_seg = next; - next = next->next; - tcp_seg_free(old_seg); - } - if (next && - TCP_SEQ_GT(seqno + cseg->len, next->tcphdr->seqno)) { - /* We need to trim the incoming segment. */ - cseg->len = (u16_t)(next->tcphdr->seqno - seqno); - pbuf_realloc(cseg->p, cseg->len); - } - } - cseg->next = next; -} -#endif /* TCP_QUEUE_OOSEQ */ - -/** Remove segments from a list if the incoming ACK acknowledges them */ -static struct tcp_seg * -tcp_free_acked_segments(struct tcp_pcb *pcb, struct tcp_seg *seg_list, const char *dbg_list_name, - struct tcp_seg *dbg_other_seg_list) -{ - struct tcp_seg *next; - u16_t clen; - - LWIP_UNUSED_ARG(dbg_list_name); - LWIP_UNUSED_ARG(dbg_other_seg_list); - - while (seg_list != NULL && - TCP_SEQ_LEQ(lwip_ntohl(seg_list->tcphdr->seqno) + - TCP_TCPLEN(seg_list), ackno)) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->%s\n", - lwip_ntohl(seg_list->tcphdr->seqno), - lwip_ntohl(seg_list->tcphdr->seqno) + TCP_TCPLEN(seg_list), - dbg_list_name)); - - next = seg_list; - seg_list = seg_list->next; - - clen = pbuf_clen(next->p); - LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"TCPWNDSIZE_F" ... ", - (tcpwnd_size_t)pcb->snd_queuelen)); - LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= clen)); - - pcb->snd_queuelen = (u16_t)(pcb->snd_queuelen - clen); - recv_acked = (tcpwnd_size_t)(recv_acked + next->len); - tcp_seg_free(next); - - LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"TCPWNDSIZE_F" (after freeing %s)\n", - (tcpwnd_size_t)pcb->snd_queuelen, - dbg_list_name)); - if (pcb->snd_queuelen != 0) { - LWIP_ASSERT("tcp_receive: valid queue length", - seg_list != NULL || dbg_other_seg_list != NULL); - } - } - return seg_list; -} - -/** - * Called by tcp_process. Checks if the given segment is an ACK for outstanding - * data, and if so frees the memory of the buffered data. Next, it places the - * segment on any of the receive queues (pcb->recved or pcb->ooseq). If the segment - * is buffered, the pbuf is referenced by pbuf_ref so that it will not be freed until - * it has been removed from the buffer. - * - * If the incoming segment constitutes an ACK for a segment that was used for RTT - * estimation, the RTT is estimated here as well. - * - * Called from tcp_process(). - */ -static void -tcp_receive(struct tcp_pcb *pcb) -{ - s16_t m; - u32_t right_wnd_edge; - int found_dupack = 0; - - LWIP_ASSERT("tcp_receive: invalid pcb", pcb != NULL); - LWIP_ASSERT("tcp_receive: wrong state", pcb->state >= ESTABLISHED); - - if (flags & TCP_ACK) { - right_wnd_edge = pcb->snd_wnd + pcb->snd_wl2; - - /* Update window. */ - if (TCP_SEQ_LT(pcb->snd_wl1, seqno) || - (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) || - (pcb->snd_wl2 == ackno && (u32_t)SND_WND_SCALE(pcb, tcphdr->wnd) > pcb->snd_wnd)) { - pcb->snd_wnd = SND_WND_SCALE(pcb, tcphdr->wnd); - /* keep track of the biggest window announced by the remote host to calculate - the maximum segment size */ - if (pcb->snd_wnd_max < pcb->snd_wnd) { - pcb->snd_wnd_max = pcb->snd_wnd; - } - pcb->snd_wl1 = seqno; - pcb->snd_wl2 = ackno; - LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: window update %"TCPWNDSIZE_F"\n", pcb->snd_wnd)); -#if TCP_WND_DEBUG - } else { - if (pcb->snd_wnd != (tcpwnd_size_t)SND_WND_SCALE(pcb, tcphdr->wnd)) { - LWIP_DEBUGF(TCP_WND_DEBUG, - ("tcp_receive: no window update lastack %"U32_F" ackno %" - U32_F" wl1 %"U32_F" seqno %"U32_F" wl2 %"U32_F"\n", - pcb->lastack, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2)); - } -#endif /* TCP_WND_DEBUG */ - } - - /* (From Stevens TCP/IP Illustrated Vol II, p970.) Its only a - * duplicate ack if: - * 1) It doesn't ACK new data - * 2) length of received packet is zero (i.e. no payload) - * 3) the advertised window hasn't changed - * 4) There is outstanding unacknowledged data (retransmission timer running) - * 5) The ACK is == biggest ACK sequence number so far seen (snd_una) - * - * If it passes all five, should process as a dupack: - * a) dupacks < 3: do nothing - * b) dupacks == 3: fast retransmit - * c) dupacks > 3: increase cwnd - * - * If it only passes 1-3, should reset dupack counter (and add to - * stats, which we don't do in lwIP) - * - * If it only passes 1, should reset dupack counter - * - */ - - /* Clause 1 */ - if (TCP_SEQ_LEQ(ackno, pcb->lastack)) { - /* Clause 2 */ - if (tcplen == 0) { - /* Clause 3 */ - if (pcb->snd_wl2 + pcb->snd_wnd == right_wnd_edge) { - /* Clause 4 */ - if (pcb->rtime >= 0) { - /* Clause 5 */ - if (pcb->lastack == ackno) { - found_dupack = 1; - if ((u8_t)(pcb->dupacks + 1) > pcb->dupacks) { - ++pcb->dupacks; - } - if (pcb->dupacks > 3) { - /* Inflate the congestion window */ - TCP_WND_INC(pcb->cwnd, pcb->mss); - } - if (pcb->dupacks >= 3) { - /* Do fast retransmit (checked via TF_INFR, not via dupacks count) */ - tcp_rexmit_fast(pcb); - } - } - } - } - } - /* If Clause (1) or more is true, but not a duplicate ack, reset - * count of consecutive duplicate acks */ - if (!found_dupack) { - pcb->dupacks = 0; - } - } else if (TCP_SEQ_BETWEEN(ackno, pcb->lastack + 1, pcb->snd_nxt)) { - /* We come here when the ACK acknowledges new data. */ - tcpwnd_size_t acked; - - /* Reset the "IN Fast Retransmit" flag, since we are no longer - in fast retransmit. Also reset the congestion window to the - slow start threshold. */ - if (pcb->flags & TF_INFR) { - tcp_clear_flags(pcb, TF_INFR); - pcb->cwnd = pcb->ssthresh; - pcb->bytes_acked = 0; - } - - /* Reset the number of retransmissions. */ - pcb->nrtx = 0; - - /* Reset the retransmission time-out. */ - pcb->rto = (s16_t)((pcb->sa >> 3) + pcb->sv); - - /* Record how much data this ACK acks */ - acked = (tcpwnd_size_t)(ackno - pcb->lastack); - - /* Reset the fast retransmit variables. */ - pcb->dupacks = 0; - pcb->lastack = ackno; - - /* Update the congestion control variables (cwnd and - ssthresh). */ - if (pcb->state >= ESTABLISHED) { - if (pcb->cwnd < pcb->ssthresh) { - tcpwnd_size_t increase; - /* limit to 1 SMSS segment during period following RTO */ - u8_t num_seg = (pcb->flags & TF_RTO) ? 1 : 2; - /* RFC 3465, section 2.2 Slow Start */ - increase = LWIP_MIN(acked, (tcpwnd_size_t)(num_seg * pcb->mss)); - TCP_WND_INC(pcb->cwnd, increase); - LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %"TCPWNDSIZE_F"\n", pcb->cwnd)); - } else { - /* RFC 3465, section 2.1 Congestion Avoidance */ - TCP_WND_INC(pcb->bytes_acked, acked); - if (pcb->bytes_acked >= pcb->cwnd) { - pcb->bytes_acked = (tcpwnd_size_t)(pcb->bytes_acked - pcb->cwnd); - TCP_WND_INC(pcb->cwnd, pcb->mss); - } - LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %"TCPWNDSIZE_F"\n", pcb->cwnd)); - } - } - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: ACK for %"U32_F", unacked->seqno %"U32_F":%"U32_F"\n", - ackno, - pcb->unacked != NULL ? - lwip_ntohl(pcb->unacked->tcphdr->seqno) : 0, - pcb->unacked != NULL ? - lwip_ntohl(pcb->unacked->tcphdr->seqno) + TCP_TCPLEN(pcb->unacked) : 0)); - - /* Remove segment from the unacknowledged list if the incoming - ACK acknowledges them. */ - pcb->unacked = tcp_free_acked_segments(pcb, pcb->unacked, "unacked", pcb->unsent); - /* We go through the ->unsent list to see if any of the segments - on the list are acknowledged by the ACK. This may seem - strange since an "unsent" segment shouldn't be acked. The - rationale is that lwIP puts all outstanding segments on the - ->unsent list after a retransmission, so these segments may - in fact have been sent once. */ - pcb->unsent = tcp_free_acked_segments(pcb, pcb->unsent, "unsent", pcb->unacked); - - /* If there's nothing left to acknowledge, stop the retransmit - timer, otherwise reset it to start again */ - if (pcb->unacked == NULL) { - pcb->rtime = -1; - } else { - pcb->rtime = 0; - } - - pcb->polltmr = 0; - -#if TCP_OVERSIZE - if (pcb->unsent == NULL) { - pcb->unsent_oversize = 0; - } -#endif /* TCP_OVERSIZE */ - -#if LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS - if (ip_current_is_v6()) { - /* Inform neighbor reachability of forward progress. */ - nd6_reachability_hint(ip6_current_src_addr()); - } -#endif /* LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS*/ - - pcb->snd_buf = (tcpwnd_size_t)(pcb->snd_buf + recv_acked); - /* check if this ACK ends our retransmission of in-flight data */ - if (pcb->flags & TF_RTO) { - /* RTO is done if - 1) both queues are empty or - 2) unacked is empty and unsent head contains data not part of RTO or - 3) unacked head contains data not part of RTO */ - if (pcb->unacked == NULL) { - if ((pcb->unsent == NULL) || - (TCP_SEQ_LEQ(pcb->rto_end, lwip_ntohl(pcb->unsent->tcphdr->seqno)))) { - tcp_clear_flags(pcb, TF_RTO); - } - } else if (TCP_SEQ_LEQ(pcb->rto_end, lwip_ntohl(pcb->unacked->tcphdr->seqno))) { - tcp_clear_flags(pcb, TF_RTO); - } - } - /* End of ACK for new data processing. */ - } else { - /* Out of sequence ACK, didn't really ack anything */ - tcp_send_empty_ack(pcb); - } - - LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: pcb->rttest %"U32_F" rtseq %"U32_F" ackno %"U32_F"\n", - pcb->rttest, pcb->rtseq, ackno)); - - /* RTT estimation calculations. This is done by checking if the - incoming segment acknowledges the segment we use to take a - round-trip time measurement. */ - if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) { - /* diff between this shouldn't exceed 32K since this are tcp timer ticks - and a round-trip shouldn't be that long... */ - m = (s16_t)(tcp_ticks - pcb->rttest); - - LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %"U16_F" ticks (%"U16_F" msec).\n", - m, (u16_t)(m * TCP_SLOW_INTERVAL))); - - /* This is taken directly from VJs original code in his paper */ - m = (s16_t)(m - (pcb->sa >> 3)); - pcb->sa = (s16_t)(pcb->sa + m); - if (m < 0) { - m = (s16_t) - m; - } - m = (s16_t)(m - (pcb->sv >> 2)); - pcb->sv = (s16_t)(pcb->sv + m); - pcb->rto = (s16_t)((pcb->sa >> 3) + pcb->sv); - - LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %"U16_F" (%"U16_F" milliseconds)\n", - pcb->rto, (u16_t)(pcb->rto * TCP_SLOW_INTERVAL))); - - pcb->rttest = 0; - } - } - - /* If the incoming segment contains data, we must process it - further unless the pcb already received a FIN. - (RFC 793, chapter 3.9, "SEGMENT ARRIVES" in states CLOSE-WAIT, CLOSING, - LAST-ACK and TIME-WAIT: "Ignore the segment text.") */ - if ((tcplen > 0) && (pcb->state < CLOSE_WAIT)) { - /* This code basically does three things: - - +) If the incoming segment contains data that is the next - in-sequence data, this data is passed to the application. This - might involve trimming the first edge of the data. The rcv_nxt - variable and the advertised window are adjusted. - - +) If the incoming segment has data that is above the next - sequence number expected (->rcv_nxt), the segment is placed on - the ->ooseq queue. This is done by finding the appropriate - place in the ->ooseq queue (which is ordered by sequence - number) and trim the segment in both ends if needed. An - immediate ACK is sent to indicate that we received an - out-of-sequence segment. - - +) Finally, we check if the first segment on the ->ooseq queue - now is in sequence (i.e., if rcv_nxt >= ooseq->seqno). If - rcv_nxt > ooseq->seqno, we must trim the first edge of the - segment on ->ooseq before we adjust rcv_nxt. The data in the - segments that are now on sequence are chained onto the - incoming segment so that we only need to call the application - once. - */ - - /* First, we check if we must trim the first edge. We have to do - this if the sequence number of the incoming segment is less - than rcv_nxt, and the sequence number plus the length of the - segment is larger than rcv_nxt. */ - /* if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)) { - if (TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {*/ - if (TCP_SEQ_BETWEEN(pcb->rcv_nxt, seqno + 1, seqno + tcplen - 1)) { - /* Trimming the first edge is done by pushing the payload - pointer in the pbuf downwards. This is somewhat tricky since - we do not want to discard the full contents of the pbuf up to - the new starting point of the data since we have to keep the - TCP header which is present in the first pbuf in the chain. - - What is done is really quite a nasty hack: the first pbuf in - the pbuf chain is pointed to by inseg.p. Since we need to be - able to deallocate the whole pbuf, we cannot change this - inseg.p pointer to point to any of the later pbufs in the - chain. Instead, we point the ->payload pointer in the first - pbuf to data in one of the later pbufs. We also set the - inseg.data pointer to point to the right place. This way, the - ->p pointer will still point to the first pbuf, but the - ->p->payload pointer will point to data in another pbuf. - - After we are done with adjusting the pbuf pointers we must - adjust the ->data pointer in the seg and the segment - length.*/ - - struct pbuf *p = inseg.p; - u32_t off32 = pcb->rcv_nxt - seqno; - u16_t new_tot_len, off; - LWIP_ASSERT("inseg.p != NULL", inseg.p); - LWIP_ASSERT("insane offset!", (off32 < 0xffff)); - off = (u16_t)off32; - LWIP_ASSERT("pbuf too short!", (((s32_t)inseg.p->tot_len) >= off)); - inseg.len -= off; - new_tot_len = (u16_t)(inseg.p->tot_len - off); - while (p->len < off) { - off -= p->len; - /* all pbufs up to and including this one have len==0, so tot_len is equal */ - p->tot_len = new_tot_len; - p->len = 0; - p = p->next; - } - /* cannot fail... */ - pbuf_remove_header(p, off); - inseg.tcphdr->seqno = seqno = pcb->rcv_nxt; - } else { - if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)) { - /* the whole segment is < rcv_nxt */ - /* must be a duplicate of a packet that has already been correctly handled */ - - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %"U32_F"\n", seqno)); - tcp_ack_now(pcb); - } - } - - /* The sequence number must be within the window (above rcv_nxt - and below rcv_nxt + rcv_wnd) in order to be further - processed. */ - if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, - pcb->rcv_nxt + pcb->rcv_wnd - 1)) { - if (pcb->rcv_nxt == seqno) { - /* The incoming segment is the next in sequence. We check if - we have to trim the end of the segment and update rcv_nxt - and pass the data to the application. */ - tcplen = TCP_TCPLEN(&inseg); - - if (tcplen > pcb->rcv_wnd) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, - ("tcp_receive: other end overran receive window" - "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n", - seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd)); - if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { - /* Must remove the FIN from the header as we're trimming - * that byte of sequence-space from the packet */ - TCPH_FLAGS_SET(inseg.tcphdr, TCPH_FLAGS(inseg.tcphdr) & ~(unsigned int)TCP_FIN); - } - /* Adjust length of segment to fit in the window. */ - TCPWND_CHECK16(pcb->rcv_wnd); - inseg.len = (u16_t)pcb->rcv_wnd; - if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) { - inseg.len -= 1; - } - pbuf_realloc(inseg.p, inseg.len); - tcplen = TCP_TCPLEN(&inseg); - LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n", - (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd)); - } -#if TCP_QUEUE_OOSEQ - /* Received in-sequence data, adjust ooseq data if: - - FIN has been received or - - inseq overlaps with ooseq */ - if (pcb->ooseq != NULL) { - if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, - ("tcp_receive: received in-order FIN, binning ooseq queue\n")); - /* Received in-order FIN means anything that was received - * out of order must now have been received in-order, so - * bin the ooseq queue */ - while (pcb->ooseq != NULL) { - struct tcp_seg *old_ooseq = pcb->ooseq; - pcb->ooseq = pcb->ooseq->next; - tcp_seg_free(old_ooseq); - } - } else { - struct tcp_seg *next = pcb->ooseq; - /* Remove all segments on ooseq that are covered by inseg already. - * FIN is copied from ooseq to inseg if present. */ - while (next && - TCP_SEQ_GEQ(seqno + tcplen, - next->tcphdr->seqno + next->len)) { - struct tcp_seg *tmp; - /* inseg cannot have FIN here (already processed above) */ - if ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0 && - (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) == 0) { - TCPH_SET_FLAG(inseg.tcphdr, TCP_FIN); - tcplen = TCP_TCPLEN(&inseg); - } - tmp = next; - next = next->next; - tcp_seg_free(tmp); - } - /* Now trim right side of inseg if it overlaps with the first - * segment on ooseq */ - if (next && - TCP_SEQ_GT(seqno + tcplen, - next->tcphdr->seqno)) { - /* inseg cannot have FIN here (already processed above) */ - inseg.len = (u16_t)(next->tcphdr->seqno - seqno); - if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) { - inseg.len -= 1; - } - pbuf_realloc(inseg.p, inseg.len); - tcplen = TCP_TCPLEN(&inseg); - LWIP_ASSERT("tcp_receive: segment not trimmed correctly to ooseq queue\n", - (seqno + tcplen) == next->tcphdr->seqno); - } - pcb->ooseq = next; - } - } -#endif /* TCP_QUEUE_OOSEQ */ - - pcb->rcv_nxt = seqno + tcplen; - - /* Update the receiver's (our) window. */ - LWIP_ASSERT("tcp_receive: tcplen > rcv_wnd\n", pcb->rcv_wnd >= tcplen); - pcb->rcv_wnd -= tcplen; - - tcp_update_rcv_ann_wnd(pcb); - - /* If there is data in the segment, we make preparations to - pass this up to the application. The ->recv_data variable - is used for holding the pbuf that goes to the - application. The code for reassembling out-of-sequence data - chains its data on this pbuf as well. - - If the segment was a FIN, we set the TF_GOT_FIN flag that will - be used to indicate to the application that the remote side has - closed its end of the connection. */ - if (inseg.p->tot_len > 0) { - recv_data = inseg.p; - /* Since this pbuf now is the responsibility of the - application, we delete our reference to it so that we won't - (mistakingly) deallocate it. */ - inseg.p = NULL; - } - if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN.\n")); - recv_flags |= TF_GOT_FIN; - } - -#if TCP_QUEUE_OOSEQ - /* We now check if we have segments on the ->ooseq queue that - are now in sequence. */ - while (pcb->ooseq != NULL && - pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) { - - struct tcp_seg *cseg = pcb->ooseq; - seqno = pcb->ooseq->tcphdr->seqno; - - pcb->rcv_nxt += TCP_TCPLEN(cseg); - LWIP_ASSERT("tcp_receive: ooseq tcplen > rcv_wnd\n", - pcb->rcv_wnd >= TCP_TCPLEN(cseg)); - pcb->rcv_wnd -= TCP_TCPLEN(cseg); - - tcp_update_rcv_ann_wnd(pcb); - - if (cseg->p->tot_len > 0) { - /* Chain this pbuf onto the pbuf that we will pass to - the application. */ - /* With window scaling, this can overflow recv_data->tot_len, but - that's not a problem since we explicitly fix that before passing - recv_data to the application. */ - if (recv_data) { - pbuf_cat(recv_data, cseg->p); - } else { - recv_data = cseg->p; - } - cseg->p = NULL; - } - if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN.\n")); - recv_flags |= TF_GOT_FIN; - if (pcb->state == ESTABLISHED) { /* force passive close or we can move to active close */ - pcb->state = CLOSE_WAIT; - } - } - - pcb->ooseq = cseg->next; - tcp_seg_free(cseg); - } -#if LWIP_TCP_SACK_OUT - if (pcb->flags & TF_SACK) { - if (pcb->ooseq != NULL) { - /* Some segments may have been removed from ooseq, let's remove all SACKs that - describe anything before the new beginning of that list. */ - tcp_remove_sacks_lt(pcb, pcb->ooseq->tcphdr->seqno); - } else if (LWIP_TCP_SACK_VALID(pcb, 0)) { - /* ooseq has been cleared. Nothing to SACK */ - memset(pcb->rcv_sacks, 0, sizeof(pcb->rcv_sacks)); - } - } -#endif /* LWIP_TCP_SACK_OUT */ -#endif /* TCP_QUEUE_OOSEQ */ - - - /* Acknowledge the segment(s). */ - tcp_ack(pcb); - -#if LWIP_TCP_SACK_OUT - if (LWIP_TCP_SACK_VALID(pcb, 0)) { - /* Normally the ACK for the data received could be piggy-backed on a data packet, - but lwIP currently does not support including SACKs in data packets. So we force - it to respond with an empty ACK packet (only if there is at least one SACK to be sent). - NOTE: tcp_send_empty_ack() on success clears the ACK flags (set by tcp_ack()) */ - tcp_send_empty_ack(pcb); - } -#endif /* LWIP_TCP_SACK_OUT */ - -#if LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS - if (ip_current_is_v6()) { - /* Inform neighbor reachability of forward progress. */ - nd6_reachability_hint(ip6_current_src_addr()); - } -#endif /* LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS*/ - - } else { - /* We get here if the incoming segment is out-of-sequence. */ - -#if TCP_QUEUE_OOSEQ - /* We queue the segment on the ->ooseq queue. */ - if (pcb->ooseq == NULL) { - pcb->ooseq = tcp_seg_copy(&inseg); -#if LWIP_TCP_SACK_OUT - if (pcb->flags & TF_SACK) { - /* All the SACKs should be invalid, so we can simply store the most recent one: */ - pcb->rcv_sacks[0].left = seqno; - pcb->rcv_sacks[0].right = seqno + inseg.len; - } -#endif /* LWIP_TCP_SACK_OUT */ - } else { - /* If the queue is not empty, we walk through the queue and - try to find a place where the sequence number of the - incoming segment is between the sequence numbers of the - previous and the next segment on the ->ooseq queue. That is - the place where we put the incoming segment. If needed, we - trim the second edges of the previous and the incoming - segment so that it will fit into the sequence. - - If the incoming segment has the same sequence number as a - segment on the ->ooseq queue, we discard the segment that - contains less data. */ - -#if LWIP_TCP_SACK_OUT - /* This is the left edge of the lowest possible SACK range. - It may start before the newly received segment (possibly adjusted below). */ - u32_t sackbeg = TCP_SEQ_LT(seqno, pcb->ooseq->tcphdr->seqno) ? seqno : pcb->ooseq->tcphdr->seqno; -#endif /* LWIP_TCP_SACK_OUT */ - struct tcp_seg *next, *prev = NULL; - for (next = pcb->ooseq; next != NULL; next = next->next) { - if (seqno == next->tcphdr->seqno) { - /* The sequence number of the incoming segment is the - same as the sequence number of the segment on - ->ooseq. We check the lengths to see which one to - discard. */ - if (inseg.len > next->len) { - /* The incoming segment is larger than the old - segment. We replace some segments with the new - one. */ - struct tcp_seg *cseg = tcp_seg_copy(&inseg); - if (cseg != NULL) { - if (prev != NULL) { - prev->next = cseg; - } else { - pcb->ooseq = cseg; - } - tcp_oos_insert_segment(cseg, next); - } - break; - } else { - /* Either the lengths are the same or the incoming - segment was smaller than the old one; in either - case, we ditch the incoming segment. */ - break; - } - } else { - if (prev == NULL) { - if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) { - /* The sequence number of the incoming segment is lower - than the sequence number of the first segment on the - queue. We put the incoming segment first on the - queue. */ - struct tcp_seg *cseg = tcp_seg_copy(&inseg); - if (cseg != NULL) { - pcb->ooseq = cseg; - tcp_oos_insert_segment(cseg, next); - } - break; - } - } else { - /*if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) && - TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {*/ - if (TCP_SEQ_BETWEEN(seqno, prev->tcphdr->seqno + 1, next->tcphdr->seqno - 1)) { - /* The sequence number of the incoming segment is in - between the sequence numbers of the previous and - the next segment on ->ooseq. We trim trim the previous - segment, delete next segments that included in received segment - and trim received, if needed. */ - struct tcp_seg *cseg = tcp_seg_copy(&inseg); - if (cseg != NULL) { - if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) { - /* We need to trim the prev segment. */ - prev->len = (u16_t)(seqno - prev->tcphdr->seqno); - pbuf_realloc(prev->p, prev->len); - } - prev->next = cseg; - tcp_oos_insert_segment(cseg, next); - } - break; - } - } - -#if LWIP_TCP_SACK_OUT - /* The new segment goes after the 'next' one. If there is a "hole" in sequence numbers - between 'prev' and the beginning of 'next', we want to move sackbeg. */ - if (prev != NULL && prev->tcphdr->seqno + prev->len != next->tcphdr->seqno) { - sackbeg = next->tcphdr->seqno; - } -#endif /* LWIP_TCP_SACK_OUT */ - - /* We don't use 'prev' below, so let's set it to current 'next'. - This way even if we break the loop below, 'prev' will be pointing - at the segment right in front of the newly added one. */ - prev = next; - - /* If the "next" segment is the last segment on the - ooseq queue, we add the incoming segment to the end - of the list. */ - if (next->next == NULL && - TCP_SEQ_GT(seqno, next->tcphdr->seqno)) { - if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) { - /* segment "next" already contains all data */ - break; - } - next->next = tcp_seg_copy(&inseg); - if (next->next != NULL) { - if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) { - /* We need to trim the last segment. */ - next->len = (u16_t)(seqno - next->tcphdr->seqno); - pbuf_realloc(next->p, next->len); - } - /* check if the remote side overruns our receive window */ - if (TCP_SEQ_GT((u32_t)tcplen + seqno, pcb->rcv_nxt + (u32_t)pcb->rcv_wnd)) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, - ("tcp_receive: other end overran receive window" - "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n", - seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd)); - if (TCPH_FLAGS(next->next->tcphdr) & TCP_FIN) { - /* Must remove the FIN from the header as we're trimming - * that byte of sequence-space from the packet */ - TCPH_FLAGS_SET(next->next->tcphdr, TCPH_FLAGS(next->next->tcphdr) & ~TCP_FIN); - } - /* Adjust length of segment to fit in the window. */ - next->next->len = (u16_t)(pcb->rcv_nxt + pcb->rcv_wnd - seqno); - pbuf_realloc(next->next->p, next->next->len); - tcplen = TCP_TCPLEN(next->next); - LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n", - (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd)); - } - } - break; - } - } - } - -#if LWIP_TCP_SACK_OUT - if (pcb->flags & TF_SACK) { - if (prev == NULL) { - /* The new segment is at the beginning. sackbeg should already be set properly. - We need to find the right edge. */ - next = pcb->ooseq; - } else if (prev->next != NULL) { - /* The new segment was added after 'prev'. If there is a "hole" between 'prev' and 'prev->next', - we need to move sackbeg. After that we should find the right edge. */ - next = prev->next; - if (prev->tcphdr->seqno + prev->len != next->tcphdr->seqno) { - sackbeg = next->tcphdr->seqno; - } - } else { - next = NULL; - } - if (next != NULL) { - u32_t sackend = next->tcphdr->seqno; - for ( ; (next != NULL) && (sackend == next->tcphdr->seqno); next = next->next) { - sackend += next->len; - } - tcp_add_sack(pcb, sackbeg, sackend); - } - } -#endif /* LWIP_TCP_SACK_OUT */ - } -#if defined(TCP_OOSEQ_BYTES_LIMIT) || defined(TCP_OOSEQ_PBUFS_LIMIT) - { - /* Check that the data on ooseq doesn't exceed one of the limits - and throw away everything above that limit. */ -#ifdef TCP_OOSEQ_BYTES_LIMIT - const u32_t ooseq_max_blen = TCP_OOSEQ_BYTES_LIMIT(pcb); - u32_t ooseq_blen = 0; -#endif -#ifdef TCP_OOSEQ_PBUFS_LIMIT - const u16_t ooseq_max_qlen = TCP_OOSEQ_PBUFS_LIMIT(pcb); - u16_t ooseq_qlen = 0; -#endif - struct tcp_seg *next, *prev = NULL; - for (next = pcb->ooseq; next != NULL; prev = next, next = next->next) { - struct pbuf *p = next->p; - int stop_here = 0; -#ifdef TCP_OOSEQ_BYTES_LIMIT - ooseq_blen += p->tot_len; - if (ooseq_blen > ooseq_max_blen) { - stop_here = 1; - } -#endif -#ifdef TCP_OOSEQ_PBUFS_LIMIT - ooseq_qlen += pbuf_clen(p); - if (ooseq_qlen > ooseq_max_qlen) { - stop_here = 1; - } -#endif - if (stop_here) { -#if LWIP_TCP_SACK_OUT - if (pcb->flags & TF_SACK) { - /* Let's remove all SACKs from next's seqno up. */ - tcp_remove_sacks_gt(pcb, next->tcphdr->seqno); - } -#endif /* LWIP_TCP_SACK_OUT */ - /* too much ooseq data, dump this and everything after it */ - tcp_segs_free(next); - if (prev == NULL) { - /* first ooseq segment is too much, dump the whole queue */ - pcb->ooseq = NULL; - } else { - /* just dump 'next' and everything after it */ - prev->next = NULL; - } - break; - } - } - } -#endif /* TCP_OOSEQ_BYTES_LIMIT || TCP_OOSEQ_PBUFS_LIMIT */ -#endif /* TCP_QUEUE_OOSEQ */ - - /* We send the ACK packet after we've (potentially) dealt with SACKs, - so they can be included in the acknowledgment. */ - tcp_send_empty_ack(pcb); - } - } else { - /* The incoming segment is not within the window. */ - tcp_send_empty_ack(pcb); - } - } else { - /* Segments with length 0 is taken care of here. Segments that - fall out of the window are ACKed. */ - if (!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd - 1)) { - tcp_ack_now(pcb); - } - } -} - -static u8_t -tcp_get_next_optbyte(void) -{ - u16_t optidx = tcp_optidx++; - if ((tcphdr_opt2 == NULL) || (optidx < tcphdr_opt1len)) { - u8_t *opts = (u8_t *)tcphdr + TCP_HLEN; - return opts[optidx]; - } else { - u8_t idx = (u8_t)(optidx - tcphdr_opt1len); - return tcphdr_opt2[idx]; - } -} - -/** - * Parses the options contained in the incoming segment. - * - * Called from tcp_listen_input() and tcp_process(). - * Currently, only the MSS option is supported! - * - * @param pcb the tcp_pcb for which a segment arrived - */ -static void -tcp_parseopt(struct tcp_pcb *pcb) -{ - u8_t data; - u16_t mss; -#if LWIP_TCP_TIMESTAMPS - u32_t tsval; -#endif - - LWIP_ASSERT("tcp_parseopt: invalid pcb", pcb != NULL); - - /* Parse the TCP MSS option, if present. */ - if (tcphdr_optlen != 0) { - for (tcp_optidx = 0; tcp_optidx < tcphdr_optlen; ) { - u8_t opt = tcp_get_next_optbyte(); - switch (opt) { - case LWIP_TCP_OPT_EOL: - /* End of options. */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: EOL\n")); - return; - case LWIP_TCP_OPT_NOP: - /* NOP option. */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: NOP\n")); - break; - case LWIP_TCP_OPT_MSS: - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: MSS\n")); - if (tcp_get_next_optbyte() != LWIP_TCP_OPT_LEN_MSS || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_MSS) > tcphdr_optlen) { - /* Bad length */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); - return; - } - /* An MSS option with the right option length. */ - mss = (u16_t)(tcp_get_next_optbyte() << 8); - mss |= tcp_get_next_optbyte(); - /* Limit the mss to the configured TCP_MSS and prevent division by zero */ - pcb->mss = ((mss > TCP_MSS) || (mss == 0)) ? TCP_MSS : mss; - break; -#if LWIP_WND_SCALE - case LWIP_TCP_OPT_WS: - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: WND_SCALE\n")); - if (tcp_get_next_optbyte() != LWIP_TCP_OPT_LEN_WS || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_WS) > tcphdr_optlen) { - /* Bad length */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); - return; - } - /* An WND_SCALE option with the right option length. */ - data = tcp_get_next_optbyte(); - /* If syn was received with wnd scale option, - activate wnd scale opt, but only if this is not a retransmission */ - if ((flags & TCP_SYN) && !(pcb->flags & TF_WND_SCALE)) { - pcb->snd_scale = data; - if (pcb->snd_scale > 14U) { - pcb->snd_scale = 14U; - } - pcb->rcv_scale = TCP_RCV_SCALE; - tcp_set_flags(pcb, TF_WND_SCALE); - /* window scaling is enabled, we can use the full receive window */ - LWIP_ASSERT("window not at default value", pcb->rcv_wnd == TCPWND_MIN16(TCP_WND)); - LWIP_ASSERT("window not at default value", pcb->rcv_ann_wnd == TCPWND_MIN16(TCP_WND)); - pcb->rcv_wnd = pcb->rcv_ann_wnd = TCP_WND; - } - break; -#endif /* LWIP_WND_SCALE */ -#if LWIP_TCP_TIMESTAMPS - case LWIP_TCP_OPT_TS: - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: TS\n")); - if (tcp_get_next_optbyte() != LWIP_TCP_OPT_LEN_TS || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_TS) > tcphdr_optlen) { - /* Bad length */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); - return; - } - /* TCP timestamp option with valid length */ - tsval = tcp_get_next_optbyte(); - tsval |= (tcp_get_next_optbyte() << 8); - tsval |= (tcp_get_next_optbyte() << 16); - tsval |= (tcp_get_next_optbyte() << 24); - if (flags & TCP_SYN) { - pcb->ts_recent = lwip_ntohl(tsval); - /* Enable sending timestamps in every segment now that we know - the remote host supports it. */ - tcp_set_flags(pcb, TF_TIMESTAMP); - } else if (TCP_SEQ_BETWEEN(pcb->ts_lastacksent, seqno, seqno + tcplen)) { - pcb->ts_recent = lwip_ntohl(tsval); - } - /* Advance to next option (6 bytes already read) */ - tcp_optidx += LWIP_TCP_OPT_LEN_TS - 6; - break; -#endif /* LWIP_TCP_TIMESTAMPS */ -#if LWIP_TCP_SACK_OUT - case LWIP_TCP_OPT_SACK_PERM: - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: SACK_PERM\n")); - if (tcp_get_next_optbyte() != LWIP_TCP_OPT_LEN_SACK_PERM || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_SACK_PERM) > tcphdr_optlen) { - /* Bad length */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); - return; - } - /* TCP SACK_PERM option with valid length */ - if (flags & TCP_SYN) { - /* We only set it if we receive it in a SYN (or SYN+ACK) packet */ - tcp_set_flags(pcb, TF_SACK); - } - break; -#endif /* LWIP_TCP_SACK_OUT */ - default: - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: other\n")); - data = tcp_get_next_optbyte(); - if (data < 2) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); - /* If the length field is zero, the options are malformed - and we don't process them further. */ - return; - } - /* All other options have a length field, so that we easily - can skip past them. */ - tcp_optidx += data - 2; - } - } - } -} - -void -tcp_trigger_input_pcb_close(void) -{ - recv_flags |= TF_CLOSED; -} - -#if LWIP_TCP_SACK_OUT -/** - * Called by tcp_receive() to add new SACK entry. - * - * The new SACK entry will be placed at the beginning of rcv_sacks[], as the newest one. - * Existing SACK entries will be "pushed back", to preserve their order. - * This is the behavior described in RFC 2018, section 4. - * - * @param pcb the tcp_pcb for which a segment arrived - * @param left the left side of the SACK (the first sequence number) - * @param right the right side of the SACK (the first sequence number past this SACK) - */ -static void -tcp_add_sack(struct tcp_pcb *pcb, u32_t left, u32_t right) -{ - u8_t i; - u8_t unused_idx; - - if ((pcb->flags & TF_SACK) == 0 || !TCP_SEQ_LT(left, right)) { - return; - } - - /* First, let's remove all SACKs that are no longer needed (because they overlap with the newest one), - while moving all other SACKs forward. - We run this loop for all entries, until we find the first invalid one. - There is no point checking after that. */ - for (i = unused_idx = 0; (i < LWIP_TCP_MAX_SACK_NUM) && LWIP_TCP_SACK_VALID(pcb, i); ++i) { - /* We only want to use SACK at [i] if it doesn't overlap with left:right range. - It does not overlap if its right side is before the newly added SACK, - or if its left side is after the newly added SACK. - NOTE: The equality should not really happen, but it doesn't hurt. */ - if (TCP_SEQ_LEQ(pcb->rcv_sacks[i].right, left) || TCP_SEQ_LEQ(right, pcb->rcv_sacks[i].left)) { - if (unused_idx != i) { - /* We don't need to copy if it's already in the right spot */ - pcb->rcv_sacks[unused_idx] = pcb->rcv_sacks[i]; - } - ++unused_idx; - } - } - - /* Now 'unused_idx' is the index of the first invalid SACK entry, - anywhere between 0 (no valid entries) and LWIP_TCP_MAX_SACK_NUM (all entries are valid). - We want to clear this and all following SACKs. - However, we will be adding another one in the front (and shifting everything else back). - So let's just iterate from the back, and set each entry to the one to the left if it's valid, - or to 0 if it is not. */ - for (i = LWIP_TCP_MAX_SACK_NUM - 1; i > 0; --i) { - /* [i] is the index we are setting, and the value should be at index [i-1], - or 0 if that index is unused (>= unused_idx). */ - if (i - 1 >= unused_idx) { - /* [i-1] is unused. Let's clear [i]. */ - pcb->rcv_sacks[i].left = pcb->rcv_sacks[i].right = 0; - } else { - pcb->rcv_sacks[i] = pcb->rcv_sacks[i - 1]; - } - } - - /* And now we can store the newest SACK */ - pcb->rcv_sacks[0].left = left; - pcb->rcv_sacks[0].right = right; -} - -/** - * Called to remove a range of SACKs. - * - * SACK entries will be removed or adjusted to not acknowledge any sequence - * numbers that are less than 'seq' passed. It not only invalidates entries, - * but also moves all entries that are still valid to the beginning. - * - * @param pcb the tcp_pcb to modify - * @param seq the lowest sequence number to keep in SACK entries - */ -static void -tcp_remove_sacks_lt(struct tcp_pcb *pcb, u32_t seq) -{ - u8_t i; - u8_t unused_idx; - - /* We run this loop for all entries, until we find the first invalid one. - There is no point checking after that. */ - for (i = unused_idx = 0; (i < LWIP_TCP_MAX_SACK_NUM) && LWIP_TCP_SACK_VALID(pcb, i); ++i) { - /* We only want to use SACK at index [i] if its right side is > 'seq'. */ - if (TCP_SEQ_GT(pcb->rcv_sacks[i].right, seq)) { - if (unused_idx != i) { - /* We only copy it if it's not in the right spot already. */ - pcb->rcv_sacks[unused_idx] = pcb->rcv_sacks[i]; - } - /* NOTE: It is possible that its left side is < 'seq', in which case we should adjust it. */ - if (TCP_SEQ_LT(pcb->rcv_sacks[unused_idx].left, seq)) { - pcb->rcv_sacks[unused_idx].left = seq; - } - ++unused_idx; - } - } - - /* We also need to invalidate everything from 'unused_idx' till the end */ - for (i = unused_idx; i < LWIP_TCP_MAX_SACK_NUM; ++i) { - pcb->rcv_sacks[i].left = pcb->rcv_sacks[i].right = 0; - } -} - -#if defined(TCP_OOSEQ_BYTES_LIMIT) || defined(TCP_OOSEQ_PBUFS_LIMIT) -/** - * Called to remove a range of SACKs. - * - * SACK entries will be removed or adjusted to not acknowledge any sequence - * numbers that are greater than (or equal to) 'seq' passed. It not only invalidates entries, - * but also moves all entries that are still valid to the beginning. - * - * @param pcb the tcp_pcb to modify - * @param seq the highest sequence number to keep in SACK entries - */ -static void -tcp_remove_sacks_gt(struct tcp_pcb *pcb, u32_t seq) -{ - u8_t i; - u8_t unused_idx; - - /* We run this loop for all entries, until we find the first invalid one. - There is no point checking after that. */ - for (i = unused_idx = 0; (i < LWIP_TCP_MAX_SACK_NUM) && LWIP_TCP_SACK_VALID(pcb, i); ++i) { - /* We only want to use SACK at index [i] if its left side is < 'seq'. */ - if (TCP_SEQ_LT(pcb->rcv_sacks[i].left, seq)) { - if (unused_idx != i) { - /* We only copy it if it's not in the right spot already. */ - pcb->rcv_sacks[unused_idx] = pcb->rcv_sacks[i]; - } - /* NOTE: It is possible that its right side is > 'seq', in which case we should adjust it. */ - if (TCP_SEQ_GT(pcb->rcv_sacks[unused_idx].right, seq)) { - pcb->rcv_sacks[unused_idx].right = seq; - } - ++unused_idx; - } - } - - /* We also need to invalidate everything from 'unused_idx' till the end */ - for (i = unused_idx; i < LWIP_TCP_MAX_SACK_NUM; ++i) { - pcb->rcv_sacks[i].left = pcb->rcv_sacks[i].right = 0; - } -} -#endif /* TCP_OOSEQ_BYTES_LIMIT || TCP_OOSEQ_PBUFS_LIMIT */ - -#endif /* LWIP_TCP_SACK_OUT */ - -#endif /* LWIP_TCP */ diff --git a/third-party/lwip-2.1.2/core/tcp_out.c b/third-party/lwip-2.1.2/core/tcp_out.c deleted file mode 100644 index 724df109..00000000 --- a/third-party/lwip-2.1.2/core/tcp_out.c +++ /dev/null @@ -1,2190 +0,0 @@ -/** - * @file - * Transmission Control Protocol, outgoing traffic - * - * The output functions of TCP. - * - * There are two distinct ways for TCP segments to get sent: - * - queued data: these are segments transferring data or segments containing - * SYN or FIN (which both count as one sequence number). They are created as - * struct @ref pbuf together with a struct tcp_seg and enqueue to the - * unsent list of the pcb. They are sent by tcp_output: - * - @ref tcp_write : creates data segments - * - @ref tcp_split_unsent_seg : splits a data segment - * - @ref tcp_enqueue_flags : creates SYN-only or FIN-only segments - * - @ref tcp_output / tcp_output_segment : finalize the tcp header - * (e.g. sequence numbers, options, checksum) and output to IP - * - the various tcp_rexmit functions shuffle around segments between the - * unsent an unacked lists to retransmit them - * - tcp_create_segment and tcp_pbuf_prealloc allocate pbuf and - * segment for these functions - * - direct send: these segments don't contain data but control the connection - * behaviour. They are created as pbuf only and sent directly without - * enqueueing them: - * - @ref tcp_send_empty_ack sends an ACK-only segment - * - @ref tcp_rst sends a RST segment - * - @ref tcp_keepalive sends a keepalive segment - * - @ref tcp_zero_window_probe sends a window probe segment - * - tcp_output_alloc_header allocates a header-only pbuf for these functions - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#include "lwip/opt.h" - -#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/priv/tcp_priv.h" -#include "lwip/def.h" -#include "lwip/mem.h" -#include "lwip/memp.h" -#include "lwip/ip_addr.h" -#include "lwip/netif.h" -#include "lwip/inet_chksum.h" -#include "lwip/stats.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#if LWIP_TCP_TIMESTAMPS -#include "lwip/sys.h" -#endif - -#include - -#ifdef LWIP_HOOK_FILENAME -#include LWIP_HOOK_FILENAME -#endif - -/* Allow to add custom TCP header options by defining this hook */ -#ifdef LWIP_HOOK_TCP_OUT_TCPOPT_LENGTH -#define LWIP_TCP_OPT_LENGTH_SEGMENT(flags, pcb) LWIP_HOOK_TCP_OUT_TCPOPT_LENGTH(pcb, LWIP_TCP_OPT_LENGTH(flags)) -#else -#define LWIP_TCP_OPT_LENGTH_SEGMENT(flags, pcb) LWIP_TCP_OPT_LENGTH(flags) -#endif - -/* Define some copy-macros for checksum-on-copy so that the code looks - nicer by preventing too many ifdef's. */ -#if TCP_CHECKSUM_ON_COPY -#define TCP_DATA_COPY(dst, src, len, seg) do { \ - tcp_seg_add_chksum(LWIP_CHKSUM_COPY(dst, src, len), \ - len, &seg->chksum, &seg->chksum_swapped); \ - seg->flags |= TF_SEG_DATA_CHECKSUMMED; } while(0) -#define TCP_DATA_COPY2(dst, src, len, chksum, chksum_swapped) \ - tcp_seg_add_chksum(LWIP_CHKSUM_COPY(dst, src, len), len, chksum, chksum_swapped); -#else /* TCP_CHECKSUM_ON_COPY*/ -#define TCP_DATA_COPY(dst, src, len, seg) MEMCPY(dst, src, len) -#define TCP_DATA_COPY2(dst, src, len, chksum, chksum_swapped) MEMCPY(dst, src, len) -#endif /* TCP_CHECKSUM_ON_COPY*/ - -/** Define this to 1 for an extra check that the output checksum is valid - * (usefule when the checksum is generated by the application, not the stack) */ -#ifndef TCP_CHECKSUM_ON_COPY_SANITY_CHECK -#define TCP_CHECKSUM_ON_COPY_SANITY_CHECK 0 -#endif -/* Allow to override the failure of sanity check from warning to e.g. hard failure */ -#if TCP_CHECKSUM_ON_COPY_SANITY_CHECK -#ifndef TCP_CHECKSUM_ON_COPY_SANITY_CHECK_FAIL -#define TCP_CHECKSUM_ON_COPY_SANITY_CHECK_FAIL(msg) LWIP_DEBUGF(TCP_DEBUG | LWIP_DBG_LEVEL_WARNING, msg) -#endif -#endif - -#if TCP_OVERSIZE -/** The size of segment pbufs created when TCP_OVERSIZE is enabled */ -#ifndef TCP_OVERSIZE_CALC_LENGTH -#define TCP_OVERSIZE_CALC_LENGTH(length) ((length) + TCP_OVERSIZE) -#endif -#endif - -/* Forward declarations.*/ -static err_t tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif); - -/* tcp_route: common code that returns a fixed bound netif or calls ip_route */ -static struct netif * -tcp_route(const struct tcp_pcb *pcb, const ip_addr_t *src, const ip_addr_t *dst) -{ - LWIP_UNUSED_ARG(src); /* in case IPv4-only and source-based routing is disabled */ - - if ((pcb != NULL) && (pcb->netif_idx != NETIF_NO_INDEX)) { - return netif_get_by_index(pcb->netif_idx); - } else { - return ip_route(src, dst); - } -} - -/** - * Create a TCP segment with prefilled header. - * - * Called by @ref tcp_write, @ref tcp_enqueue_flags and @ref tcp_split_unsent_seg - * - * @param pcb Protocol control block for the TCP connection. - * @param p pbuf that is used to hold the TCP header. - * @param hdrflags TCP flags for header. - * @param seqno TCP sequence number of this packet - * @param optflags options to include in TCP header - * @return a new tcp_seg pointing to p, or NULL. - * The TCP header is filled in except ackno and wnd. - * p is freed on failure. - */ -static struct tcp_seg * -tcp_create_segment(const struct tcp_pcb *pcb, struct pbuf *p, u8_t hdrflags, u32_t seqno, u8_t optflags) -{ - struct tcp_seg *seg; - u8_t optlen; - - LWIP_ASSERT("tcp_create_segment: invalid pcb", pcb != NULL); - LWIP_ASSERT("tcp_create_segment: invalid pbuf", p != NULL); - - optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(optflags, pcb); - - if ((seg = (struct tcp_seg *)memp_malloc(MEMP_TCP_SEG)) == NULL) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_create_segment: no memory.\n")); - pbuf_free(p); - return NULL; - } - seg->flags = optflags; - seg->next = NULL; - seg->p = p; - LWIP_ASSERT("p->tot_len >= optlen", p->tot_len >= optlen); - seg->len = p->tot_len - optlen; -#if TCP_OVERSIZE_DBGCHECK - seg->oversize_left = 0; -#endif /* TCP_OVERSIZE_DBGCHECK */ -#if TCP_CHECKSUM_ON_COPY - seg->chksum = 0; - seg->chksum_swapped = 0; - /* check optflags */ - LWIP_ASSERT("invalid optflags passed: TF_SEG_DATA_CHECKSUMMED", - (optflags & TF_SEG_DATA_CHECKSUMMED) == 0); -#endif /* TCP_CHECKSUM_ON_COPY */ - - /* build TCP header */ - if (pbuf_add_header(p, TCP_HLEN)) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_create_segment: no room for TCP header in pbuf.\n")); - TCP_STATS_INC(tcp.err); - tcp_seg_free(seg); - return NULL; - } - seg->tcphdr = (struct tcp_hdr *)seg->p->payload; - seg->tcphdr->src = lwip_htons(pcb->local_port); - seg->tcphdr->dest = lwip_htons(pcb->remote_port); - seg->tcphdr->seqno = lwip_htonl(seqno); - /* ackno is set in tcp_output */ - TCPH_HDRLEN_FLAGS_SET(seg->tcphdr, (5 + optlen / 4), hdrflags); - /* wnd and chksum are set in tcp_output */ - seg->tcphdr->urgp = 0; - return seg; -} - -/** - * Allocate a PBUF_RAM pbuf, perhaps with extra space at the end. - * - * This function is like pbuf_alloc(layer, length, PBUF_RAM) except - * there may be extra bytes available at the end. - * - * Called by @ref tcp_write - * - * @param layer flag to define header size. - * @param length size of the pbuf's payload. - * @param max_length maximum usable size of payload+oversize. - * @param oversize pointer to a u16_t that will receive the number of usable tail bytes. - * @param pcb The TCP connection that will enqueue the pbuf. - * @param apiflags API flags given to tcp_write. - * @param first_seg true when this pbuf will be used in the first enqueued segment. - */ -#if TCP_OVERSIZE -static struct pbuf * -tcp_pbuf_prealloc(pbuf_layer layer, u16_t length, u16_t max_length, - u16_t *oversize, const struct tcp_pcb *pcb, u8_t apiflags, - u8_t first_seg) -{ - struct pbuf *p; - u16_t alloc = length; - - LWIP_ASSERT("tcp_pbuf_prealloc: invalid oversize", oversize != NULL); - LWIP_ASSERT("tcp_pbuf_prealloc: invalid pcb", pcb != NULL); - -#if LWIP_NETIF_TX_SINGLE_PBUF - LWIP_UNUSED_ARG(max_length); - LWIP_UNUSED_ARG(pcb); - LWIP_UNUSED_ARG(apiflags); - LWIP_UNUSED_ARG(first_seg); - alloc = max_length; -#else /* LWIP_NETIF_TX_SINGLE_PBUF */ - if (length < max_length) { - /* Should we allocate an oversized pbuf, or just the minimum - * length required? If tcp_write is going to be called again - * before this segment is transmitted, we want the oversized - * buffer. If the segment will be transmitted immediately, we can - * save memory by allocating only length. We use a simple - * heuristic based on the following information: - * - * Did the user set TCP_WRITE_FLAG_MORE? - * - * Will the Nagle algorithm defer transmission of this segment? - */ - if ((apiflags & TCP_WRITE_FLAG_MORE) || - (!(pcb->flags & TF_NODELAY) && - (!first_seg || - pcb->unsent != NULL || - pcb->unacked != NULL))) { - alloc = LWIP_MIN(max_length, LWIP_MEM_ALIGN_SIZE(TCP_OVERSIZE_CALC_LENGTH(length))); - } - } -#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ - p = pbuf_alloc(layer, alloc, PBUF_RAM); - if (p == NULL) { - return NULL; - } - LWIP_ASSERT("need unchained pbuf", p->next == NULL); - *oversize = p->len - length; - /* trim p->len to the currently used size */ - p->len = p->tot_len = length; - return p; -} -#else /* TCP_OVERSIZE */ -#define tcp_pbuf_prealloc(layer, length, mx, os, pcb, api, fst) pbuf_alloc((layer), (length), PBUF_RAM) -#endif /* TCP_OVERSIZE */ - -#if TCP_CHECKSUM_ON_COPY -/** Add a checksum of newly added data to the segment. - * - * Called by tcp_write and tcp_split_unsent_seg. - */ -static void -tcp_seg_add_chksum(u16_t chksum, u16_t len, u16_t *seg_chksum, - u8_t *seg_chksum_swapped) -{ - u32_t helper; - /* add chksum to old chksum and fold to u16_t */ - helper = chksum + *seg_chksum; - chksum = FOLD_U32T(helper); - if ((len & 1) != 0) { - *seg_chksum_swapped = 1 - *seg_chksum_swapped; - chksum = SWAP_BYTES_IN_WORD(chksum); - } - *seg_chksum = chksum; -} -#endif /* TCP_CHECKSUM_ON_COPY */ - -/** Checks if tcp_write is allowed or not (checks state, snd_buf and snd_queuelen). - * - * @param pcb the tcp pcb to check for - * @param len length of data to send (checked agains snd_buf) - * @return ERR_OK if tcp_write is allowed to proceed, another err_t otherwise - */ -static err_t -tcp_write_checks(struct tcp_pcb *pcb, u16_t len) -{ - LWIP_ASSERT("tcp_write_checks: invalid pcb", pcb != NULL); - - /* connection is in invalid state for data transmission? */ - if ((pcb->state != ESTABLISHED) && - (pcb->state != CLOSE_WAIT) && - (pcb->state != SYN_SENT) && - (pcb->state != SYN_RCVD)) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_STATE | LWIP_DBG_LEVEL_SEVERE, ("tcp_write() called in invalid state\n")); - return ERR_CONN; - } else if (len == 0) { - return ERR_OK; - } - - /* fail on too much data */ - if (len > pcb->snd_buf) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("tcp_write: too much data (len=%"U16_F" > snd_buf=%"TCPWNDSIZE_F")\n", - len, pcb->snd_buf)); - tcp_set_flags(pcb, TF_NAGLEMEMERR); - return ERR_MEM; - } - - LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: queuelen: %"TCPWNDSIZE_F"\n", (tcpwnd_size_t)pcb->snd_queuelen)); - - /* If total number of pbufs on the unsent/unacked queues exceeds the - * configured maximum, return an error */ - /* check for configured max queuelen and possible overflow */ - if (pcb->snd_queuelen >= LWIP_MIN(TCP_SND_QUEUELEN, (TCP_SNDQUEUELEN_OVERFLOW + 1))) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("tcp_write: too long queue %"U16_F" (max %"U16_F")\n", - pcb->snd_queuelen, (u16_t)TCP_SND_QUEUELEN)); - TCP_STATS_INC(tcp.memerr); - tcp_set_flags(pcb, TF_NAGLEMEMERR); - return ERR_MEM; - } - if (pcb->snd_queuelen != 0) { - LWIP_ASSERT("tcp_write: pbufs on queue => at least one queue non-empty", - pcb->unacked != NULL || pcb->unsent != NULL); - } else { - LWIP_ASSERT("tcp_write: no pbufs on queue => both queues empty", - pcb->unacked == NULL && pcb->unsent == NULL); - } - return ERR_OK; -} - -/** - * @ingroup tcp_raw - * Write data for sending (but does not send it immediately). - * - * It waits in the expectation of more data being sent soon (as - * it can send them more efficiently by combining them together). - * To prompt the system to send data now, call tcp_output() after - * calling tcp_write(). - * - * This function enqueues the data pointed to by the argument dataptr. The length of - * the data is passed as the len parameter. The apiflags can be one or more of: - * - TCP_WRITE_FLAG_COPY: indicates whether the new memory should be allocated - * for the data to be copied into. If this flag is not given, no new memory - * should be allocated and the data should only be referenced by pointer. This - * also means that the memory behind dataptr must not change until the data is - * ACKed by the remote host - * - TCP_WRITE_FLAG_MORE: indicates that more data follows. If this is omitted, - * the PSH flag is set in the last segment created by this call to tcp_write. - * If this flag is given, the PSH flag is not set. - * - * The tcp_write() function will fail and return ERR_MEM if the length - * of the data exceeds the current send buffer size or if the length of - * the queue of outgoing segment is larger than the upper limit defined - * in lwipopts.h. The number of bytes available in the output queue can - * be retrieved with the tcp_sndbuf() function. - * - * The proper way to use this function is to call the function with at - * most tcp_sndbuf() bytes of data. If the function returns ERR_MEM, - * the application should wait until some of the currently enqueued - * data has been successfully received by the other host and try again. - * - * @param pcb Protocol control block for the TCP connection to enqueue data for. - * @param arg Pointer to the data to be enqueued for sending. - * @param len Data length in bytes - * @param apiflags combination of following flags : - * - TCP_WRITE_FLAG_COPY (0x01) data will be copied into memory belonging to the stack - * - TCP_WRITE_FLAG_MORE (0x02) for TCP connection, PSH flag will not be set on last segment sent, - * @return ERR_OK if enqueued, another err_t on error - */ -err_t -tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) -{ - struct pbuf *concat_p = NULL; - struct tcp_seg *last_unsent = NULL, *seg = NULL, *prev_seg = NULL, *queue = NULL; - u16_t pos = 0; /* position in 'arg' data */ - u16_t queuelen; - u8_t optlen; - u8_t optflags = 0; -#if TCP_OVERSIZE - u16_t oversize = 0; - u16_t oversize_used = 0; -#if TCP_OVERSIZE_DBGCHECK - u16_t oversize_add = 0; -#endif /* TCP_OVERSIZE_DBGCHECK*/ -#endif /* TCP_OVERSIZE */ - u16_t extendlen = 0; -#if TCP_CHECKSUM_ON_COPY - u16_t concat_chksum = 0; - u8_t concat_chksum_swapped = 0; - u16_t concat_chksummed = 0; -#endif /* TCP_CHECKSUM_ON_COPY */ - err_t err; - u16_t mss_local; - - LWIP_ERROR("tcp_write: invalid pcb", pcb != NULL, return ERR_ARG); - - /* don't allocate segments bigger than half the maximum window we ever received */ - mss_local = LWIP_MIN(pcb->mss, TCPWND_MIN16(pcb->snd_wnd_max / 2)); - mss_local = mss_local ? mss_local : pcb->mss; - - LWIP_ASSERT_CORE_LOCKED(); - -#if LWIP_NETIF_TX_SINGLE_PBUF - /* Always copy to try to create single pbufs for TX */ - apiflags |= TCP_WRITE_FLAG_COPY; -#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ - - LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_write(pcb=%p, data=%p, len=%"U16_F", apiflags=%"U16_F")\n", - (void *)pcb, arg, len, (u16_t)apiflags)); - LWIP_ERROR("tcp_write: arg == NULL (programmer violates API)", - arg != NULL, return ERR_ARG;); - - err = tcp_write_checks(pcb, len); - if (err != ERR_OK) { - return err; - } - queuelen = pcb->snd_queuelen; - -#if LWIP_TCP_TIMESTAMPS - if ((pcb->flags & TF_TIMESTAMP)) { - /* Make sure the timestamp option is only included in data segments if we - agreed about it with the remote host. */ - optflags = TF_SEG_OPTS_TS; - optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(TF_SEG_OPTS_TS, pcb); - /* ensure that segments can hold at least one data byte... */ - mss_local = LWIP_MAX(mss_local, LWIP_TCP_OPT_LEN_TS + 1); - } else -#endif /* LWIP_TCP_TIMESTAMPS */ - { - optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(0, pcb); - } - - - /* - * TCP segmentation is done in three phases with increasing complexity: - * - * 1. Copy data directly into an oversized pbuf. - * 2. Chain a new pbuf to the end of pcb->unsent. - * 3. Create new segments. - * - * We may run out of memory at any point. In that case we must - * return ERR_MEM and not change anything in pcb. Therefore, all - * changes are recorded in local variables and committed at the end - * of the function. Some pcb fields are maintained in local copies: - * - * queuelen = pcb->snd_queuelen - * oversize = pcb->unsent_oversize - * - * These variables are set consistently by the phases: - * - * seg points to the last segment tampered with. - * - * pos records progress as data is segmented. - */ - - /* Find the tail of the unsent queue. */ - if (pcb->unsent != NULL) { - u16_t space; - u16_t unsent_optlen; - - /* @todo: this could be sped up by keeping last_unsent in the pcb */ - for (last_unsent = pcb->unsent; last_unsent->next != NULL; - last_unsent = last_unsent->next); - - /* Usable space at the end of the last unsent segment */ - unsent_optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(last_unsent->flags, pcb); - LWIP_ASSERT("mss_local is too small", mss_local >= last_unsent->len + unsent_optlen); - space = mss_local - (last_unsent->len + unsent_optlen); - - /* - * Phase 1: Copy data directly into an oversized pbuf. - * - * The number of bytes copied is recorded in the oversize_used - * variable. The actual copying is done at the bottom of the - * function. - */ -#if TCP_OVERSIZE -#if TCP_OVERSIZE_DBGCHECK - /* check that pcb->unsent_oversize matches last_unsent->oversize_left */ - LWIP_ASSERT("unsent_oversize mismatch (pcb vs. last_unsent)", - pcb->unsent_oversize == last_unsent->oversize_left); -#endif /* TCP_OVERSIZE_DBGCHECK */ - oversize = pcb->unsent_oversize; - if (oversize > 0) { - LWIP_ASSERT("inconsistent oversize vs. space", oversize <= space); - seg = last_unsent; - oversize_used = LWIP_MIN(space, LWIP_MIN(oversize, len)); - pos += oversize_used; - oversize -= oversize_used; - space -= oversize_used; - } - /* now we are either finished or oversize is zero */ - LWIP_ASSERT("inconsistent oversize vs. len", (oversize == 0) || (pos == len)); -#endif /* TCP_OVERSIZE */ - -#if !LWIP_NETIF_TX_SINGLE_PBUF - /* - * Phase 2: Chain a new pbuf to the end of pcb->unsent. - * - * As an exception when NOT copying the data, if the given data buffer - * directly follows the last unsent data buffer in memory, extend the last - * ROM pbuf reference to the buffer, thus saving a ROM pbuf allocation. - * - * We don't extend segments containing SYN/FIN flags or options - * (len==0). The new pbuf is kept in concat_p and pbuf_cat'ed at - * the end. - * - * This phase is skipped for LWIP_NETIF_TX_SINGLE_PBUF as we could only execute - * it after rexmit puts a segment from unacked to unsent and at this point, - * oversize info is lost. - */ - if ((pos < len) && (space > 0) && (last_unsent->len > 0)) { - u16_t seglen = LWIP_MIN(space, len - pos); - seg = last_unsent; - - /* Create a pbuf with a copy or reference to seglen bytes. We - * can use PBUF_RAW here since the data appears in the middle of - * a segment. A header will never be prepended. */ - if (apiflags & TCP_WRITE_FLAG_COPY) { - /* Data is copied */ - if ((concat_p = tcp_pbuf_prealloc(PBUF_RAW, seglen, space, &oversize, pcb, apiflags, 1)) == NULL) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("tcp_write : could not allocate memory for pbuf copy size %"U16_F"\n", - seglen)); - goto memerr; - } -#if TCP_OVERSIZE_DBGCHECK - oversize_add = oversize; -#endif /* TCP_OVERSIZE_DBGCHECK */ - TCP_DATA_COPY2(concat_p->payload, (const u8_t *)arg + pos, seglen, &concat_chksum, &concat_chksum_swapped); -#if TCP_CHECKSUM_ON_COPY - concat_chksummed += seglen; -#endif /* TCP_CHECKSUM_ON_COPY */ - queuelen += pbuf_clen(concat_p); - } else { - /* Data is not copied */ - /* If the last unsent pbuf is of type PBUF_ROM, try to extend it. */ - struct pbuf *p; - for (p = last_unsent->p; p->next != NULL; p = p->next); - if (((p->type_internal & (PBUF_TYPE_FLAG_STRUCT_DATA_CONTIGUOUS | PBUF_TYPE_FLAG_DATA_VOLATILE)) == 0) && - (const u8_t *)p->payload + p->len == (const u8_t *)arg) { - LWIP_ASSERT("tcp_write: ROM pbufs cannot be oversized", pos == 0); - extendlen = seglen; - } else { - if ((concat_p = pbuf_alloc(PBUF_RAW, seglen, PBUF_ROM)) == NULL) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("tcp_write: could not allocate memory for zero-copy pbuf\n")); - goto memerr; - } - /* reference the non-volatile payload data */ - ((struct pbuf_rom *)concat_p)->payload = (const u8_t *)arg + pos; - queuelen += pbuf_clen(concat_p); - } -#if TCP_CHECKSUM_ON_COPY - /* calculate the checksum of nocopy-data */ - tcp_seg_add_chksum(~inet_chksum((const u8_t *)arg + pos, seglen), seglen, - &concat_chksum, &concat_chksum_swapped); - concat_chksummed += seglen; -#endif /* TCP_CHECKSUM_ON_COPY */ - } - - pos += seglen; - } -#endif /* !LWIP_NETIF_TX_SINGLE_PBUF */ - } else { -#if TCP_OVERSIZE - LWIP_ASSERT("unsent_oversize mismatch (pcb->unsent is NULL)", - pcb->unsent_oversize == 0); -#endif /* TCP_OVERSIZE */ - } - - /* - * Phase 3: Create new segments. - * - * The new segments are chained together in the local 'queue' - * variable, ready to be appended to pcb->unsent. - */ - while (pos < len) { - struct pbuf *p; - u16_t left = len - pos; - u16_t max_len = mss_local - optlen; - u16_t seglen = LWIP_MIN(left, max_len); -#if TCP_CHECKSUM_ON_COPY - u16_t chksum = 0; - u8_t chksum_swapped = 0; -#endif /* TCP_CHECKSUM_ON_COPY */ - - if (apiflags & TCP_WRITE_FLAG_COPY) { - /* If copy is set, memory should be allocated and data copied - * into pbuf */ - if ((p = tcp_pbuf_prealloc(PBUF_TRANSPORT, seglen + optlen, mss_local, &oversize, pcb, apiflags, queue == NULL)) == NULL) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_write : could not allocate memory for pbuf copy size %"U16_F"\n", seglen)); - goto memerr; - } - LWIP_ASSERT("tcp_write: check that first pbuf can hold the complete seglen", - (p->len >= seglen)); - TCP_DATA_COPY2((char *)p->payload + optlen, (const u8_t *)arg + pos, seglen, &chksum, &chksum_swapped); - } else { - /* Copy is not set: First allocate a pbuf for holding the data. - * Since the referenced data is available at least until it is - * sent out on the link (as it has to be ACKed by the remote - * party) we can safely use PBUF_ROM instead of PBUF_REF here. - */ - struct pbuf *p2; -#if TCP_OVERSIZE - LWIP_ASSERT("oversize == 0", oversize == 0); -#endif /* TCP_OVERSIZE */ - if ((p2 = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_ROM)) == NULL) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_write: could not allocate memory for zero-copy pbuf\n")); - goto memerr; - } -#if TCP_CHECKSUM_ON_COPY - /* calculate the checksum of nocopy-data */ - chksum = ~inet_chksum((const u8_t *)arg + pos, seglen); - if (seglen & 1) { - chksum_swapped = 1; - chksum = SWAP_BYTES_IN_WORD(chksum); - } -#endif /* TCP_CHECKSUM_ON_COPY */ - /* reference the non-volatile payload data */ - ((struct pbuf_rom *)p2)->payload = (const u8_t *)arg + pos; - - /* Second, allocate a pbuf for the headers. */ - if ((p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) { - /* If allocation fails, we have to deallocate the data pbuf as - * well. */ - pbuf_free(p2); - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_write: could not allocate memory for header pbuf\n")); - goto memerr; - } - /* Concatenate the headers and data pbufs together. */ - pbuf_cat(p/*header*/, p2/*data*/); - } - - queuelen += pbuf_clen(p); - - /* Now that there are more segments queued, we check again if the - * length of the queue exceeds the configured maximum or - * overflows. */ - if (queuelen > LWIP_MIN(TCP_SND_QUEUELEN, TCP_SNDQUEUELEN_OVERFLOW)) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_write: queue too long %"U16_F" (%d)\n", - queuelen, (int)TCP_SND_QUEUELEN)); - pbuf_free(p); - goto memerr; - } - - if ((seg = tcp_create_segment(pcb, p, 0, pcb->snd_lbb + pos, optflags)) == NULL) { - goto memerr; - } -#if TCP_OVERSIZE_DBGCHECK - seg->oversize_left = oversize; -#endif /* TCP_OVERSIZE_DBGCHECK */ -#if TCP_CHECKSUM_ON_COPY - seg->chksum = chksum; - seg->chksum_swapped = chksum_swapped; - seg->flags |= TF_SEG_DATA_CHECKSUMMED; -#endif /* TCP_CHECKSUM_ON_COPY */ - - /* first segment of to-be-queued data? */ - if (queue == NULL) { - queue = seg; - } else { - /* Attach the segment to the end of the queued segments */ - LWIP_ASSERT("prev_seg != NULL", prev_seg != NULL); - prev_seg->next = seg; - } - /* remember last segment of to-be-queued data for next iteration */ - prev_seg = seg; - - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE, ("tcp_write: queueing %"U32_F":%"U32_F"\n", - lwip_ntohl(seg->tcphdr->seqno), - lwip_ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg))); - - pos += seglen; - } - - /* - * All three segmentation phases were successful. We can commit the - * transaction. - */ -#if TCP_OVERSIZE_DBGCHECK - if ((last_unsent != NULL) && (oversize_add != 0)) { - last_unsent->oversize_left += oversize_add; - } -#endif /* TCP_OVERSIZE_DBGCHECK */ - - /* - * Phase 1: If data has been added to the preallocated tail of - * last_unsent, we update the length fields of the pbuf chain. - */ -#if TCP_OVERSIZE - if (oversize_used > 0) { - struct pbuf *p; - /* Bump tot_len of whole chain, len of tail */ - for (p = last_unsent->p; p; p = p->next) { - p->tot_len += oversize_used; - if (p->next == NULL) { - TCP_DATA_COPY((char *)p->payload + p->len, arg, oversize_used, last_unsent); - p->len += oversize_used; - } - } - last_unsent->len += oversize_used; -#if TCP_OVERSIZE_DBGCHECK - LWIP_ASSERT("last_unsent->oversize_left >= oversize_used", - last_unsent->oversize_left >= oversize_used); - last_unsent->oversize_left -= oversize_used; -#endif /* TCP_OVERSIZE_DBGCHECK */ - } - pcb->unsent_oversize = oversize; -#endif /* TCP_OVERSIZE */ - - /* - * Phase 2: concat_p can be concatenated onto last_unsent->p, unless we - * determined that the last ROM pbuf can be extended to include the new data. - */ - if (concat_p != NULL) { - LWIP_ASSERT("tcp_write: cannot concatenate when pcb->unsent is empty", - (last_unsent != NULL)); - pbuf_cat(last_unsent->p, concat_p); - last_unsent->len += concat_p->tot_len; - } else if (extendlen > 0) { - struct pbuf *p; - LWIP_ASSERT("tcp_write: extension of reference requires reference", - last_unsent != NULL && last_unsent->p != NULL); - for (p = last_unsent->p; p->next != NULL; p = p->next) { - p->tot_len += extendlen; - } - p->tot_len += extendlen; - p->len += extendlen; - last_unsent->len += extendlen; - } - -#if TCP_CHECKSUM_ON_COPY - if (concat_chksummed) { - LWIP_ASSERT("tcp_write: concat checksum needs concatenated data", - concat_p != NULL || extendlen > 0); - /*if concat checksumm swapped - swap it back */ - if (concat_chksum_swapped) { - concat_chksum = SWAP_BYTES_IN_WORD(concat_chksum); - } - tcp_seg_add_chksum(concat_chksum, concat_chksummed, &last_unsent->chksum, - &last_unsent->chksum_swapped); - last_unsent->flags |= TF_SEG_DATA_CHECKSUMMED; - } -#endif /* TCP_CHECKSUM_ON_COPY */ - - /* - * Phase 3: Append queue to pcb->unsent. Queue may be NULL, but that - * is harmless - */ - if (last_unsent == NULL) { - pcb->unsent = queue; - } else { - last_unsent->next = queue; - } - - /* - * Finally update the pcb state. - */ - pcb->snd_lbb += len; - pcb->snd_buf -= len; - pcb->snd_queuelen = queuelen; - - LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: %"S16_F" (after enqueued)\n", - pcb->snd_queuelen)); - if (pcb->snd_queuelen != 0) { - LWIP_ASSERT("tcp_write: valid queue length", - pcb->unacked != NULL || pcb->unsent != NULL); - } - - /* Set the PSH flag in the last segment that we enqueued. */ - if (seg != NULL && seg->tcphdr != NULL && ((apiflags & TCP_WRITE_FLAG_MORE) == 0)) { - TCPH_SET_FLAG(seg->tcphdr, TCP_PSH); - } - - return ERR_OK; -memerr: - tcp_set_flags(pcb, TF_NAGLEMEMERR); - TCP_STATS_INC(tcp.memerr); - - if (concat_p != NULL) { - pbuf_free(concat_p); - } - if (queue != NULL) { - tcp_segs_free(queue); - } - if (pcb->snd_queuelen != 0) { - LWIP_ASSERT("tcp_write: valid queue length", pcb->unacked != NULL || - pcb->unsent != NULL); - } - LWIP_DEBUGF(TCP_QLEN_DEBUG | LWIP_DBG_STATE, ("tcp_write: %"S16_F" (with mem err)\n", pcb->snd_queuelen)); - return ERR_MEM; -} - -/** - * Split segment on the head of the unsent queue. If return is not - * ERR_OK, existing head remains intact - * - * The split is accomplished by creating a new TCP segment and pbuf - * which holds the remainder payload after the split. The original - * pbuf is trimmed to new length. This allows splitting of read-only - * pbufs - * - * @param pcb the tcp_pcb for which to split the unsent head - * @param split the amount of payload to remain in the head - */ -err_t -tcp_split_unsent_seg(struct tcp_pcb *pcb, u16_t split) -{ - struct tcp_seg *seg = NULL, *useg = NULL; - struct pbuf *p = NULL; - u8_t optlen; - u8_t optflags; - u8_t split_flags; - u8_t remainder_flags; - u16_t remainder; - u16_t offset; -#if TCP_CHECKSUM_ON_COPY - u16_t chksum = 0; - u8_t chksum_swapped = 0; - struct pbuf *q; -#endif /* TCP_CHECKSUM_ON_COPY */ - - LWIP_ASSERT("tcp_split_unsent_seg: invalid pcb", pcb != NULL); - - useg = pcb->unsent; - if (useg == NULL) { - return ERR_MEM; - } - - if (split == 0) { - LWIP_ASSERT("Can't split segment into length 0", 0); - return ERR_VAL; - } - - if (useg->len <= split) { - return ERR_OK; - } - - LWIP_ASSERT("split <= mss", split <= pcb->mss); - LWIP_ASSERT("useg->len > 0", useg->len > 0); - - /* We should check that we don't exceed TCP_SND_QUEUELEN but we need - * to split this packet so we may actually exceed the max value by - * one! - */ - LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue: split_unsent_seg: %u\n", (unsigned int)pcb->snd_queuelen)); - - optflags = useg->flags; -#if TCP_CHECKSUM_ON_COPY - /* Remove since checksum is not stored until after tcp_create_segment() */ - optflags &= ~TF_SEG_DATA_CHECKSUMMED; -#endif /* TCP_CHECKSUM_ON_COPY */ - optlen = LWIP_TCP_OPT_LENGTH(optflags); - remainder = useg->len - split; - - /* Create new pbuf for the remainder of the split */ - p = pbuf_alloc(PBUF_TRANSPORT, remainder + optlen, PBUF_RAM); - if (p == NULL) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("tcp_split_unsent_seg: could not allocate memory for pbuf remainder %u\n", remainder)); - goto memerr; - } - - /* Offset into the original pbuf is past TCP/IP headers, options, and split amount */ - offset = useg->p->tot_len - useg->len + split; - /* Copy remainder into new pbuf, headers and options will not be filled out */ - if (pbuf_copy_partial(useg->p, (u8_t *)p->payload + optlen, remainder, offset ) != remainder) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("tcp_split_unsent_seg: could not copy pbuf remainder %u\n", remainder)); - goto memerr; - } -#if TCP_CHECKSUM_ON_COPY - /* calculate the checksum on remainder data */ - tcp_seg_add_chksum(~inet_chksum((const u8_t *)p->payload + optlen, remainder), remainder, - &chksum, &chksum_swapped); -#endif /* TCP_CHECKSUM_ON_COPY */ - - /* Options are created when calling tcp_output() */ - - /* Migrate flags from original segment */ - split_flags = TCPH_FLAGS(useg->tcphdr); - remainder_flags = 0; /* ACK added in tcp_output() */ - - if (split_flags & TCP_PSH) { - split_flags &= ~TCP_PSH; - remainder_flags |= TCP_PSH; - } - if (split_flags & TCP_FIN) { - split_flags &= ~TCP_FIN; - remainder_flags |= TCP_FIN; - } - /* SYN should be left on split, RST should not be present with data */ - - seg = tcp_create_segment(pcb, p, remainder_flags, lwip_ntohl(useg->tcphdr->seqno) + split, optflags); - if (seg == NULL) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("tcp_split_unsent_seg: could not create new TCP segment\n")); - goto memerr; - } - -#if TCP_CHECKSUM_ON_COPY - seg->chksum = chksum; - seg->chksum_swapped = chksum_swapped; - seg->flags |= TF_SEG_DATA_CHECKSUMMED; -#endif /* TCP_CHECKSUM_ON_COPY */ - - /* Remove this segment from the queue since trimming it may free pbufs */ - pcb->snd_queuelen -= pbuf_clen(useg->p); - - /* Trim the original pbuf into our split size. At this point our remainder segment must be setup - successfully because we are modifying the original segment */ - pbuf_realloc(useg->p, useg->p->tot_len - remainder); - useg->len -= remainder; - TCPH_SET_FLAG(useg->tcphdr, split_flags); -#if TCP_OVERSIZE_DBGCHECK - /* By trimming, realloc may have actually shrunk the pbuf, so clear oversize_left */ - useg->oversize_left = 0; -#endif /* TCP_OVERSIZE_DBGCHECK */ - - /* Add back to the queue with new trimmed pbuf */ - pcb->snd_queuelen += pbuf_clen(useg->p); - -#if TCP_CHECKSUM_ON_COPY - /* The checksum on the split segment is now incorrect. We need to re-run it over the split */ - useg->chksum = 0; - useg->chksum_swapped = 0; - q = useg->p; - offset = q->tot_len - useg->len; /* Offset due to exposed headers */ - - /* Advance to the pbuf where the offset ends */ - while (q != NULL && offset > q->len) { - offset -= q->len; - q = q->next; - } - LWIP_ASSERT("Found start of payload pbuf", q != NULL); - /* Checksum the first payload pbuf accounting for offset, then other pbufs are all payload */ - for (; q != NULL; offset = 0, q = q->next) { - tcp_seg_add_chksum(~inet_chksum((const u8_t *)q->payload + offset, q->len - offset), q->len - offset, - &useg->chksum, &useg->chksum_swapped); - } -#endif /* TCP_CHECKSUM_ON_COPY */ - - /* Update number of segments on the queues. Note that length now may - * exceed TCP_SND_QUEUELEN! We don't have to touch pcb->snd_buf - * because the total amount of data is constant when packet is split */ - pcb->snd_queuelen += pbuf_clen(seg->p); - - /* Finally insert remainder into queue after split (which stays head) */ - seg->next = useg->next; - useg->next = seg; - -#if TCP_OVERSIZE - /* If remainder is last segment on the unsent, ensure we clear the oversize amount - * because the remainder is always sized to the exact remaining amount */ - if (seg->next == NULL) { - pcb->unsent_oversize = 0; - } -#endif /* TCP_OVERSIZE */ - - return ERR_OK; -memerr: - TCP_STATS_INC(tcp.memerr); - - LWIP_ASSERT("seg == NULL", seg == NULL); - if (p != NULL) { - pbuf_free(p); - } - - return ERR_MEM; -} - -/** - * Called by tcp_close() to send a segment including FIN flag but not data. - * This FIN may be added to an existing segment or a new, otherwise empty - * segment is enqueued. - * - * @param pcb the tcp_pcb over which to send a segment - * @return ERR_OK if sent, another err_t otherwise - */ -err_t -tcp_send_fin(struct tcp_pcb *pcb) -{ - LWIP_ASSERT("tcp_send_fin: invalid pcb", pcb != NULL); - - /* first, try to add the fin to the last unsent segment */ - if (pcb->unsent != NULL) { - struct tcp_seg *last_unsent; - for (last_unsent = pcb->unsent; last_unsent->next != NULL; - last_unsent = last_unsent->next); - - if ((TCPH_FLAGS(last_unsent->tcphdr) & (TCP_SYN | TCP_FIN | TCP_RST)) == 0) { - /* no SYN/FIN/RST flag in the header, we can add the FIN flag */ - TCPH_SET_FLAG(last_unsent->tcphdr, TCP_FIN); - tcp_set_flags(pcb, TF_FIN); - return ERR_OK; - } - } - /* no data, no length, flags, copy=1, no optdata */ - return tcp_enqueue_flags(pcb, TCP_FIN); -} - -/** - * Enqueue SYN or FIN for transmission. - * - * Called by @ref tcp_connect, tcp_listen_input, and @ref tcp_close - * (via @ref tcp_send_fin) - * - * @param pcb Protocol control block for the TCP connection. - * @param flags TCP header flags to set in the outgoing segment. - */ -err_t -tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags) -{ - struct pbuf *p; - struct tcp_seg *seg; - u8_t optflags = 0; - u8_t optlen = 0; - - LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue_flags: queuelen: %"U16_F"\n", (u16_t)pcb->snd_queuelen)); - - LWIP_ASSERT("tcp_enqueue_flags: need either TCP_SYN or TCP_FIN in flags (programmer violates API)", - (flags & (TCP_SYN | TCP_FIN)) != 0); - LWIP_ASSERT("tcp_enqueue_flags: invalid pcb", pcb != NULL); - - /* No need to check pcb->snd_queuelen if only SYN or FIN are allowed! */ - - /* Get options for this segment. This is a special case since this is the - only place where a SYN can be sent. */ - if (flags & TCP_SYN) { - optflags = TF_SEG_OPTS_MSS; -#if LWIP_WND_SCALE - if ((pcb->state != SYN_RCVD) || (pcb->flags & TF_WND_SCALE)) { - /* In a (sent in state SYN_RCVD), the window scale option may only - be sent if we received a window scale option from the remote host. */ - optflags |= TF_SEG_OPTS_WND_SCALE; - } -#endif /* LWIP_WND_SCALE */ -#if LWIP_TCP_SACK_OUT - if ((pcb->state != SYN_RCVD) || (pcb->flags & TF_SACK)) { - /* In a (sent in state SYN_RCVD), the SACK_PERM option may only - be sent if we received a SACK_PERM option from the remote host. */ - optflags |= TF_SEG_OPTS_SACK_PERM; - } -#endif /* LWIP_TCP_SACK_OUT */ - } -#if LWIP_TCP_TIMESTAMPS - if ((pcb->flags & TF_TIMESTAMP) || ((flags & TCP_SYN) && (pcb->state != SYN_RCVD))) { - /* Make sure the timestamp option is only included in data segments if we - agreed about it with the remote host (and in active open SYN segments). */ - optflags |= TF_SEG_OPTS_TS; - } -#endif /* LWIP_TCP_TIMESTAMPS */ - optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(optflags, pcb); - - /* Allocate pbuf with room for TCP header + options */ - if ((p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) { - tcp_set_flags(pcb, TF_NAGLEMEMERR); - TCP_STATS_INC(tcp.memerr); - return ERR_MEM; - } - LWIP_ASSERT("tcp_enqueue_flags: check that first pbuf can hold optlen", - (p->len >= optlen)); - - /* Allocate memory for tcp_seg, and fill in fields. */ - if ((seg = tcp_create_segment(pcb, p, flags, pcb->snd_lbb, optflags)) == NULL) { - tcp_set_flags(pcb, TF_NAGLEMEMERR); - TCP_STATS_INC(tcp.memerr); - return ERR_MEM; - } - LWIP_ASSERT("seg->tcphdr not aligned", ((mem_ptr_t)seg->tcphdr % LWIP_MIN(MEM_ALIGNMENT, 4)) == 0); - LWIP_ASSERT("tcp_enqueue_flags: invalid segment length", seg->len == 0); - - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE, - ("tcp_enqueue_flags: queueing %"U32_F":%"U32_F" (0x%"X16_F")\n", - lwip_ntohl(seg->tcphdr->seqno), - lwip_ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg), - (u16_t)flags)); - - /* Now append seg to pcb->unsent queue */ - if (pcb->unsent == NULL) { - pcb->unsent = seg; - } else { - struct tcp_seg *useg; - for (useg = pcb->unsent; useg->next != NULL; useg = useg->next); - useg->next = seg; - } -#if TCP_OVERSIZE - /* The new unsent tail has no space */ - pcb->unsent_oversize = 0; -#endif /* TCP_OVERSIZE */ - - /* SYN and FIN bump the sequence number */ - if ((flags & TCP_SYN) || (flags & TCP_FIN)) { - pcb->snd_lbb++; - /* optlen does not influence snd_buf */ - } - if (flags & TCP_FIN) { - tcp_set_flags(pcb, TF_FIN); - } - - /* update number of segments on the queues */ - pcb->snd_queuelen += pbuf_clen(seg->p); - LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue_flags: %"S16_F" (after enqueued)\n", pcb->snd_queuelen)); - if (pcb->snd_queuelen != 0) { - LWIP_ASSERT("tcp_enqueue_flags: invalid queue length", - pcb->unacked != NULL || pcb->unsent != NULL); - } - - return ERR_OK; -} - -#if LWIP_TCP_TIMESTAMPS -/* Build a timestamp option (12 bytes long) at the specified options pointer) - * - * @param pcb tcp_pcb - * @param opts option pointer where to store the timestamp option - */ -static void -tcp_build_timestamp_option(const struct tcp_pcb *pcb, u32_t *opts) -{ - LWIP_ASSERT("tcp_build_timestamp_option: invalid pcb", pcb != NULL); - - /* Pad with two NOP options to make everything nicely aligned */ - opts[0] = PP_HTONL(0x0101080A); - opts[1] = lwip_htonl(sys_now()); - opts[2] = lwip_htonl(pcb->ts_recent); -} -#endif - -#if LWIP_TCP_SACK_OUT -/** - * Calculates the number of SACK entries that should be generated. - * It takes into account whether TF_SACK flag is set, - * the number of SACK entries in tcp_pcb that are valid, - * as well as the available options size. - * - * @param pcb tcp_pcb - * @param optlen the length of other TCP options (in bytes) - * @return the number of SACK ranges that can be used - */ -static u8_t -tcp_get_num_sacks(const struct tcp_pcb *pcb, u8_t optlen) -{ - u8_t num_sacks = 0; - - LWIP_ASSERT("tcp_get_num_sacks: invalid pcb", pcb != NULL); - - if (pcb->flags & TF_SACK) { - u8_t i; - - /* The first SACK takes up 12 bytes (it includes SACK header and two NOP options), - each additional one - 8 bytes. */ - optlen += 12; - - /* Max options size = 40, number of SACK array entries = LWIP_TCP_MAX_SACK_NUM */ - for (i = 0; (i < LWIP_TCP_MAX_SACK_NUM) && (optlen <= TCP_MAX_OPTION_BYTES) && - LWIP_TCP_SACK_VALID(pcb, i); ++i) { - ++num_sacks; - optlen += 8; - } - } - - return num_sacks; -} - -/** Build a SACK option (12 or more bytes long) at the specified options pointer) - * - * @param pcb tcp_pcb - * @param opts option pointer where to store the SACK option - * @param num_sacks the number of SACKs to store - */ -static void -tcp_build_sack_option(const struct tcp_pcb *pcb, u32_t *opts, u8_t num_sacks) -{ - u8_t i; - - LWIP_ASSERT("tcp_build_sack_option: invalid pcb", pcb != NULL); - LWIP_ASSERT("tcp_build_sack_option: invalid opts", opts != NULL); - - /* Pad with two NOP options to make everything nicely aligned. - We add the length (of just the SACK option, not the NOPs in front of it), - which is 2B of header, plus 8B for each SACK. */ - *(opts++) = PP_HTONL(0x01010500 + 2 + num_sacks * 8); - - for (i = 0; i < num_sacks; ++i) { - *(opts++) = lwip_htonl(pcb->rcv_sacks[i].left); - *(opts++) = lwip_htonl(pcb->rcv_sacks[i].right); - } -} - -#endif - -#if LWIP_WND_SCALE -/** Build a window scale option (3 bytes long) at the specified options pointer) - * - * @param opts option pointer where to store the window scale option - */ -static void -tcp_build_wnd_scale_option(u32_t *opts) -{ - LWIP_ASSERT("tcp_build_wnd_scale_option: invalid opts", opts != NULL); - - /* Pad with one NOP option to make everything nicely aligned */ - opts[0] = PP_HTONL(0x01030300 | TCP_RCV_SCALE); -} -#endif - -/** - * @ingroup tcp_raw - * Find out what we can send and send it - * - * @param pcb Protocol control block for the TCP connection to send data - * @return ERR_OK if data has been sent or nothing to send - * another err_t on error - */ -err_t -tcp_output(struct tcp_pcb *pcb) -{ - struct tcp_seg *seg, *useg; - u32_t wnd, snd_nxt; - err_t err; - struct netif *netif; -#if TCP_CWND_DEBUG - s16_t i = 0; -#endif /* TCP_CWND_DEBUG */ - - LWIP_ASSERT_CORE_LOCKED(); - - LWIP_ASSERT("tcp_output: invalid pcb", pcb != NULL); - /* pcb->state LISTEN not allowed here */ - LWIP_ASSERT("don't call tcp_output for listen-pcbs", - pcb->state != LISTEN); - - /* First, check if we are invoked by the TCP input processing - code. If so, we do not output anything. Instead, we rely on the - input processing code to call us when input processing is done - with. */ - if (tcp_input_pcb == pcb) { - return ERR_OK; - } - - wnd = LWIP_MIN(pcb->snd_wnd, pcb->cwnd); - - seg = pcb->unsent; - - if (seg == NULL) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: nothing to send (%p)\n", - (void *)pcb->unsent)); - LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"TCPWNDSIZE_F - ", cwnd %"TCPWNDSIZE_F", wnd %"U32_F - ", seg == NULL, ack %"U32_F"\n", - pcb->snd_wnd, pcb->cwnd, wnd, pcb->lastack)); - - /* If the TF_ACK_NOW flag is set and the ->unsent queue is empty, construct - * an empty ACK segment and send it. */ - if (pcb->flags & TF_ACK_NOW) { - return tcp_send_empty_ack(pcb); - } - /* nothing to send: shortcut out of here */ - goto output_done; - } else { - LWIP_DEBUGF(TCP_CWND_DEBUG, - ("tcp_output: snd_wnd %"TCPWNDSIZE_F", cwnd %"TCPWNDSIZE_F", wnd %"U32_F - ", effwnd %"U32_F", seq %"U32_F", ack %"U32_F"\n", - pcb->snd_wnd, pcb->cwnd, wnd, - lwip_ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len, - lwip_ntohl(seg->tcphdr->seqno), pcb->lastack)); - } - - netif = tcp_route(pcb, &pcb->local_ip, &pcb->remote_ip); - if (netif == NULL) { - return ERR_RTE; - } - - /* If we don't have a local IP address, we get one from netif */ - if (ip_addr_isany(&pcb->local_ip)) { - const ip_addr_t *local_ip = ip_netif_get_local_ip(netif, &pcb->remote_ip); - if (local_ip == NULL) { - return ERR_RTE; - } - ip_addr_copy(pcb->local_ip, *local_ip); - } - - /* Handle the current segment not fitting within the window */ - if (lwip_ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > wnd) { - /* We need to start the persistent timer when the next unsent segment does not fit - * within the remaining (could be 0) send window and RTO timer is not running (we - * have no in-flight data). If window is still too small after persist timer fires, - * then we split the segment. We don't consider the congestion window since a cwnd - * smaller than 1 SMSS implies in-flight data - */ - if (wnd == pcb->snd_wnd && pcb->unacked == NULL && pcb->persist_backoff == 0) { - pcb->persist_cnt = 0; - pcb->persist_backoff = 1; - pcb->persist_probe = 0; - } - /* We need an ACK, but can't send data now, so send an empty ACK */ - if (pcb->flags & TF_ACK_NOW) { - return tcp_send_empty_ack(pcb); - } - goto output_done; - } - /* Stop persist timer, above conditions are not active */ - pcb->persist_backoff = 0; - - /* useg should point to last segment on unacked queue */ - useg = pcb->unacked; - if (useg != NULL) { - for (; useg->next != NULL; useg = useg->next); - } - /* data available and window allows it to be sent? */ - while (seg != NULL && - lwip_ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) { - LWIP_ASSERT("RST not expected here!", - (TCPH_FLAGS(seg->tcphdr) & TCP_RST) == 0); - /* Stop sending if the nagle algorithm would prevent it - * Don't stop: - * - if tcp_write had a memory error before (prevent delayed ACK timeout) or - * - if FIN was already enqueued for this PCB (SYN is always alone in a segment - - * either seg->next != NULL or pcb->unacked == NULL; - * RST is no sent using tcp_write/tcp_output. - */ - if ((tcp_do_output_nagle(pcb) == 0) && - ((pcb->flags & (TF_NAGLEMEMERR | TF_FIN)) == 0)) { - break; - } -#if TCP_CWND_DEBUG - LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"TCPWNDSIZE_F", cwnd %"TCPWNDSIZE_F", wnd %"U32_F", effwnd %"U32_F", seq %"U32_F", ack %"U32_F", i %"S16_F"\n", - pcb->snd_wnd, pcb->cwnd, wnd, - lwip_ntohl(seg->tcphdr->seqno) + seg->len - - pcb->lastack, - lwip_ntohl(seg->tcphdr->seqno), pcb->lastack, i)); - ++i; -#endif /* TCP_CWND_DEBUG */ - - if (pcb->state != SYN_SENT) { - TCPH_SET_FLAG(seg->tcphdr, TCP_ACK); - } - - err = tcp_output_segment(seg, pcb, netif); - if (err != ERR_OK) { - /* segment could not be sent, for whatever reason */ - tcp_set_flags(pcb, TF_NAGLEMEMERR); - return err; - } -#if TCP_OVERSIZE_DBGCHECK - seg->oversize_left = 0; -#endif /* TCP_OVERSIZE_DBGCHECK */ - pcb->unsent = seg->next; - if (pcb->state != SYN_SENT) { - tcp_clear_flags(pcb, TF_ACK_DELAY | TF_ACK_NOW); - } - snd_nxt = lwip_ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg); - if (TCP_SEQ_LT(pcb->snd_nxt, snd_nxt)) { - pcb->snd_nxt = snd_nxt; - } - /* put segment on unacknowledged list if length > 0 */ - if (TCP_TCPLEN(seg) > 0) { - seg->next = NULL; - /* unacked list is empty? */ - if (pcb->unacked == NULL) { - pcb->unacked = seg; - useg = seg; - /* unacked list is not empty? */ - } else { - /* In the case of fast retransmit, the packet should not go to the tail - * of the unacked queue, but rather somewhere before it. We need to check for - * this case. -STJ Jul 27, 2004 */ - if (TCP_SEQ_LT(lwip_ntohl(seg->tcphdr->seqno), lwip_ntohl(useg->tcphdr->seqno))) { - /* add segment to before tail of unacked list, keeping the list sorted */ - struct tcp_seg **cur_seg = &(pcb->unacked); - while (*cur_seg && - TCP_SEQ_LT(lwip_ntohl((*cur_seg)->tcphdr->seqno), lwip_ntohl(seg->tcphdr->seqno))) { - cur_seg = &((*cur_seg)->next ); - } - seg->next = (*cur_seg); - (*cur_seg) = seg; - } else { - /* add segment to tail of unacked list */ - useg->next = seg; - useg = useg->next; - } - } - /* do not queue empty segments on the unacked list */ - } else { - tcp_seg_free(seg); - } - seg = pcb->unsent; - } -#if TCP_OVERSIZE - if (pcb->unsent == NULL) { - /* last unsent has been removed, reset unsent_oversize */ - pcb->unsent_oversize = 0; - } -#endif /* TCP_OVERSIZE */ - -output_done: - tcp_clear_flags(pcb, TF_NAGLEMEMERR); - return ERR_OK; -} - -/** Check if a segment's pbufs are used by someone else than TCP. - * This can happen on retransmission if the pbuf of this segment is still - * referenced by the netif driver due to deferred transmission. - * This is the case (only!) if someone down the TX call path called - * pbuf_ref() on one of the pbufs! - * - * @arg seg the tcp segment to check - * @return 1 if ref != 1, 0 if ref == 1 - */ -static int -tcp_output_segment_busy(const struct tcp_seg *seg) -{ - LWIP_ASSERT("tcp_output_segment_busy: invalid seg", seg != NULL); - - /* We only need to check the first pbuf here: - If a pbuf is queued for transmission, a driver calls pbuf_ref(), - which only changes the ref count of the first pbuf */ - if (seg->p->ref != 1) { - /* other reference found */ - return 1; - } - /* no other references found */ - return 0; -} - -/** - * Called by tcp_output() to actually send a TCP segment over IP. - * - * @param seg the tcp_seg to send - * @param pcb the tcp_pcb for the TCP connection used to send the segment - * @param netif the netif used to send the segment - */ -static err_t -tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif) -{ - err_t err; - u16_t len; - u32_t *opts; -#if TCP_CHECKSUM_ON_COPY - int seg_chksum_was_swapped = 0; -#endif - - LWIP_ASSERT("tcp_output_segment: invalid seg", seg != NULL); - LWIP_ASSERT("tcp_output_segment: invalid pcb", pcb != NULL); - LWIP_ASSERT("tcp_output_segment: invalid netif", netif != NULL); - - if (tcp_output_segment_busy(seg)) { - /* This should not happen: rexmit functions should have checked this. - However, since this function modifies p->len, we must not continue in this case. */ - LWIP_DEBUGF(TCP_RTO_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_output_segment: segment busy\n")); - return ERR_OK; - } - - /* The TCP header has already been constructed, but the ackno and - wnd fields remain. */ - seg->tcphdr->ackno = lwip_htonl(pcb->rcv_nxt); - - /* advertise our receive window size in this TCP segment */ -#if LWIP_WND_SCALE - if (seg->flags & TF_SEG_OPTS_WND_SCALE) { - /* The Window field in a SYN segment itself (the only type where we send - the window scale option) is never scaled. */ - seg->tcphdr->wnd = lwip_htons(TCPWND_MIN16(pcb->rcv_ann_wnd)); - } else -#endif /* LWIP_WND_SCALE */ - { - seg->tcphdr->wnd = lwip_htons(TCPWND_MIN16(RCV_WND_SCALE(pcb, pcb->rcv_ann_wnd))); - } - - pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd; - - /* Add any requested options. NB MSS option is only set on SYN - packets, so ignore it here */ - /* cast through void* to get rid of alignment warnings */ - opts = (u32_t *)(void *)(seg->tcphdr + 1); - if (seg->flags & TF_SEG_OPTS_MSS) { - u16_t mss; -#if TCP_CALCULATE_EFF_SEND_MSS - mss = tcp_eff_send_mss_netif(TCP_MSS, netif, &pcb->remote_ip); -#else /* TCP_CALCULATE_EFF_SEND_MSS */ - mss = TCP_MSS; -#endif /* TCP_CALCULATE_EFF_SEND_MSS */ - *opts = TCP_BUILD_MSS_OPTION(mss); - opts += 1; - } -#if LWIP_TCP_TIMESTAMPS - pcb->ts_lastacksent = pcb->rcv_nxt; - - if (seg->flags & TF_SEG_OPTS_TS) { - tcp_build_timestamp_option(pcb, opts); - opts += 3; - } -#endif -#if LWIP_WND_SCALE - if (seg->flags & TF_SEG_OPTS_WND_SCALE) { - tcp_build_wnd_scale_option(opts); - opts += 1; - } -#endif -#if LWIP_TCP_SACK_OUT - if (seg->flags & TF_SEG_OPTS_SACK_PERM) { - /* Pad with two NOP options to make everything nicely aligned - * NOTE: When we send both timestamp and SACK_PERM options, - * we could use the first two NOPs before the timestamp to store SACK_PERM option, - * but that would complicate the code. - */ - *(opts++) = PP_HTONL(0x01010402); - } -#endif - - /* Set retransmission timer running if it is not currently enabled - This must be set before checking the route. */ - if (pcb->rtime < 0) { - pcb->rtime = 0; - } - - if (pcb->rttest == 0) { - pcb->rttest = tcp_ticks; - pcb->rtseq = lwip_ntohl(seg->tcphdr->seqno); - - LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_output_segment: rtseq %"U32_F"\n", pcb->rtseq)); - } - LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output_segment: %"U32_F":%"U32_F"\n", - lwip_htonl(seg->tcphdr->seqno), lwip_htonl(seg->tcphdr->seqno) + - seg->len)); - - len = (u16_t)((u8_t *)seg->tcphdr - (u8_t *)seg->p->payload); - if (len == 0) { - /** Exclude retransmitted segments from this count. */ - MIB2_STATS_INC(mib2.tcpoutsegs); - } - - seg->p->len -= len; - seg->p->tot_len -= len; - - seg->p->payload = seg->tcphdr; - - seg->tcphdr->chksum = 0; - -#ifdef LWIP_HOOK_TCP_OUT_ADD_TCPOPTS - opts = LWIP_HOOK_TCP_OUT_ADD_TCPOPTS(seg->p, seg->tcphdr, pcb, opts); -#endif - LWIP_ASSERT("options not filled", (u8_t *)opts == ((u8_t *)(seg->tcphdr + 1)) + LWIP_TCP_OPT_LENGTH_SEGMENT(seg->flags, pcb)); - -#if CHECKSUM_GEN_TCP - IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) { -#if TCP_CHECKSUM_ON_COPY - u32_t acc; -#if TCP_CHECKSUM_ON_COPY_SANITY_CHECK - u16_t chksum_slow = ip_chksum_pseudo(seg->p, IP_PROTO_TCP, - seg->p->tot_len, &pcb->local_ip, &pcb->remote_ip); -#endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */ - if ((seg->flags & TF_SEG_DATA_CHECKSUMMED) == 0) { - LWIP_ASSERT("data included but not checksummed", - seg->p->tot_len == TCPH_HDRLEN_BYTES(seg->tcphdr)); - } - - /* rebuild TCP header checksum (TCP header changes for retransmissions!) */ - acc = ip_chksum_pseudo_partial(seg->p, IP_PROTO_TCP, - seg->p->tot_len, TCPH_HDRLEN_BYTES(seg->tcphdr), &pcb->local_ip, &pcb->remote_ip); - /* add payload checksum */ - if (seg->chksum_swapped) { - seg_chksum_was_swapped = 1; - seg->chksum = SWAP_BYTES_IN_WORD(seg->chksum); - seg->chksum_swapped = 0; - } - acc = (u16_t)~acc + seg->chksum; - seg->tcphdr->chksum = (u16_t)~FOLD_U32T(acc); -#if TCP_CHECKSUM_ON_COPY_SANITY_CHECK - if (chksum_slow != seg->tcphdr->chksum) { - TCP_CHECKSUM_ON_COPY_SANITY_CHECK_FAIL( - ("tcp_output_segment: calculated checksum is %"X16_F" instead of %"X16_F"\n", - seg->tcphdr->chksum, chksum_slow)); - seg->tcphdr->chksum = chksum_slow; - } -#endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */ -#else /* TCP_CHECKSUM_ON_COPY */ - seg->tcphdr->chksum = ip_chksum_pseudo(seg->p, IP_PROTO_TCP, - seg->p->tot_len, &pcb->local_ip, &pcb->remote_ip); -#endif /* TCP_CHECKSUM_ON_COPY */ - } -#endif /* CHECKSUM_GEN_TCP */ - TCP_STATS_INC(tcp.xmit); - - NETIF_SET_HINTS(netif, &(pcb->netif_hints)); - err = ip_output_if(seg->p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, - pcb->tos, IP_PROTO_TCP, netif); - NETIF_RESET_HINTS(netif); - -#if TCP_CHECKSUM_ON_COPY - if (seg_chksum_was_swapped) { - /* if data is added to this segment later, chksum needs to be swapped, - so restore this now */ - seg->chksum = SWAP_BYTES_IN_WORD(seg->chksum); - seg->chksum_swapped = 1; - } -#endif - - return err; -} - -/** - * Requeue all unacked segments for retransmission - * - * Called by tcp_slowtmr() for slow retransmission. - * - * @param pcb the tcp_pcb for which to re-enqueue all unacked segments - */ -err_t -tcp_rexmit_rto_prepare(struct tcp_pcb *pcb) -{ - struct tcp_seg *seg; - - LWIP_ASSERT("tcp_rexmit_rto_prepare: invalid pcb", pcb != NULL); - - if (pcb->unacked == NULL) { - return ERR_VAL; - } - - /* Move all unacked segments to the head of the unsent queue. - However, give up if any of the unsent pbufs are still referenced by the - netif driver due to deferred transmission. No point loading the link further - if it is struggling to flush its buffered writes. */ - for (seg = pcb->unacked; seg->next != NULL; seg = seg->next) { - if (tcp_output_segment_busy(seg)) { - LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_rexmit_rto: segment busy\n")); - return ERR_VAL; - } - } - if (tcp_output_segment_busy(seg)) { - LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_rexmit_rto: segment busy\n")); - return ERR_VAL; - } - /* concatenate unsent queue after unacked queue */ - seg->next = pcb->unsent; -#if TCP_OVERSIZE_DBGCHECK - /* if last unsent changed, we need to update unsent_oversize */ - if (pcb->unsent == NULL) { - pcb->unsent_oversize = seg->oversize_left; - } -#endif /* TCP_OVERSIZE_DBGCHECK */ - /* unsent queue is the concatenated queue (of unacked, unsent) */ - pcb->unsent = pcb->unacked; - /* unacked queue is now empty */ - pcb->unacked = NULL; - - /* Mark RTO in-progress */ - tcp_set_flags(pcb, TF_RTO); - /* Record the next byte following retransmit */ - pcb->rto_end = lwip_ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg); - /* Don't take any RTT measurements after retransmitting. */ - pcb->rttest = 0; - - return ERR_OK; -} - -/** - * Requeue all unacked segments for retransmission - * - * Called by tcp_slowtmr() for slow retransmission. - * - * @param pcb the tcp_pcb for which to re-enqueue all unacked segments - */ -void -tcp_rexmit_rto_commit(struct tcp_pcb *pcb) -{ - LWIP_ASSERT("tcp_rexmit_rto_commit: invalid pcb", pcb != NULL); - - /* increment number of retransmissions */ - if (pcb->nrtx < 0xFF) { - ++pcb->nrtx; - } - /* Do the actual retransmission */ - tcp_output(pcb); -} - -/** - * Requeue all unacked segments for retransmission - * - * Called by tcp_process() only, tcp_slowtmr() needs to do some things between - * "prepare" and "commit". - * - * @param pcb the tcp_pcb for which to re-enqueue all unacked segments - */ -void -tcp_rexmit_rto(struct tcp_pcb *pcb) -{ - LWIP_ASSERT("tcp_rexmit_rto: invalid pcb", pcb != NULL); - - if (tcp_rexmit_rto_prepare(pcb) == ERR_OK) { - tcp_rexmit_rto_commit(pcb); - } -} - -/** - * Requeue the first unacked segment for retransmission - * - * Called by tcp_receive() for fast retransmit. - * - * @param pcb the tcp_pcb for which to retransmit the first unacked segment - */ -err_t -tcp_rexmit(struct tcp_pcb *pcb) -{ - struct tcp_seg *seg; - struct tcp_seg **cur_seg; - - LWIP_ASSERT("tcp_rexmit: invalid pcb", pcb != NULL); - - if (pcb->unacked == NULL) { - return ERR_VAL; - } - - seg = pcb->unacked; - - /* Give up if the segment is still referenced by the netif driver - due to deferred transmission. */ - if (tcp_output_segment_busy(seg)) { - LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_rexmit busy\n")); - return ERR_VAL; - } - - /* Move the first unacked segment to the unsent queue */ - /* Keep the unsent queue sorted. */ - pcb->unacked = seg->next; - - cur_seg = &(pcb->unsent); - while (*cur_seg && - TCP_SEQ_LT(lwip_ntohl((*cur_seg)->tcphdr->seqno), lwip_ntohl(seg->tcphdr->seqno))) { - cur_seg = &((*cur_seg)->next ); - } - seg->next = *cur_seg; - *cur_seg = seg; -#if TCP_OVERSIZE - if (seg->next == NULL) { - /* the retransmitted segment is last in unsent, so reset unsent_oversize */ - pcb->unsent_oversize = 0; - } -#endif /* TCP_OVERSIZE */ - - if (pcb->nrtx < 0xFF) { - ++pcb->nrtx; - } - - /* Don't take any rtt measurements after retransmitting. */ - pcb->rttest = 0; - - /* Do the actual retransmission. */ - MIB2_STATS_INC(mib2.tcpretranssegs); - /* No need to call tcp_output: we are always called from tcp_input() - and thus tcp_output directly returns. */ - return ERR_OK; -} - - -/** - * Handle retransmission after three dupacks received - * - * @param pcb the tcp_pcb for which to retransmit the first unacked segment - */ -void -tcp_rexmit_fast(struct tcp_pcb *pcb) -{ - LWIP_ASSERT("tcp_rexmit_fast: invalid pcb", pcb != NULL); - - if (pcb->unacked != NULL && !(pcb->flags & TF_INFR)) { - /* This is fast retransmit. Retransmit the first unacked segment. */ - LWIP_DEBUGF(TCP_FR_DEBUG, - ("tcp_receive: dupacks %"U16_F" (%"U32_F - "), fast retransmit %"U32_F"\n", - (u16_t)pcb->dupacks, pcb->lastack, - lwip_ntohl(pcb->unacked->tcphdr->seqno))); - if (tcp_rexmit(pcb) == ERR_OK) { - /* Set ssthresh to half of the minimum of the current - * cwnd and the advertised window */ - pcb->ssthresh = LWIP_MIN(pcb->cwnd, pcb->snd_wnd) / 2; - - /* The minimum value for ssthresh should be 2 MSS */ - if (pcb->ssthresh < (2U * pcb->mss)) { - LWIP_DEBUGF(TCP_FR_DEBUG, - ("tcp_receive: The minimum value for ssthresh %"TCPWNDSIZE_F - " should be min 2 mss %"U16_F"...\n", - pcb->ssthresh, (u16_t)(2 * pcb->mss))); - pcb->ssthresh = 2 * pcb->mss; - } - - pcb->cwnd = pcb->ssthresh + 3 * pcb->mss; - tcp_set_flags(pcb, TF_INFR); - - /* Reset the retransmission timer to prevent immediate rto retransmissions */ - pcb->rtime = 0; - } - } -} - -static struct pbuf * -tcp_output_alloc_header_common(u32_t ackno, u16_t optlen, u16_t datalen, - u32_t seqno_be /* already in network byte order */, - u16_t src_port, u16_t dst_port, u8_t flags, u16_t wnd) -{ - struct tcp_hdr *tcphdr; - struct pbuf *p; - - p = pbuf_alloc(PBUF_IP, TCP_HLEN + optlen + datalen, PBUF_RAM); - if (p != NULL) { - LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr", - (p->len >= TCP_HLEN + optlen)); - tcphdr = (struct tcp_hdr *)p->payload; - tcphdr->src = lwip_htons(src_port); - tcphdr->dest = lwip_htons(dst_port); - tcphdr->seqno = seqno_be; - tcphdr->ackno = lwip_htonl(ackno); - TCPH_HDRLEN_FLAGS_SET(tcphdr, (5 + optlen / 4), flags); - tcphdr->wnd = lwip_htons(wnd); - tcphdr->chksum = 0; - tcphdr->urgp = 0; - } - return p; -} - -/** Allocate a pbuf and create a tcphdr at p->payload, used for output - * functions other than the default tcp_output -> tcp_output_segment - * (e.g. tcp_send_empty_ack, etc.) - * - * @param pcb tcp pcb for which to send a packet (used to initialize tcp_hdr) - * @param optlen length of header-options - * @param datalen length of tcp data to reserve in pbuf - * @param seqno_be seqno in network byte order (big-endian) - * @return pbuf with p->payload being the tcp_hdr - */ -static struct pbuf * -tcp_output_alloc_header(struct tcp_pcb *pcb, u16_t optlen, u16_t datalen, - u32_t seqno_be /* already in network byte order */) -{ - struct pbuf *p; - - LWIP_ASSERT("tcp_output_alloc_header: invalid pcb", pcb != NULL); - - p = tcp_output_alloc_header_common(pcb->rcv_nxt, optlen, datalen, - seqno_be, pcb->local_port, pcb->remote_port, TCP_ACK, - TCPWND_MIN16(RCV_WND_SCALE(pcb, pcb->rcv_ann_wnd))); - if (p != NULL) { - /* If we're sending a packet, update the announced right window edge */ - pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd; - } - return p; -} - -/* Fill in options for control segments */ -static void -tcp_output_fill_options(const struct tcp_pcb *pcb, struct pbuf *p, u8_t optflags, u8_t num_sacks) -{ - struct tcp_hdr *tcphdr; - u32_t *opts; - u16_t sacks_len = 0; - - LWIP_ASSERT("tcp_output_fill_options: invalid pbuf", p != NULL); - - tcphdr = (struct tcp_hdr *)p->payload; - opts = (u32_t *)(void *)(tcphdr + 1); - - /* NB. MSS and window scale options are only sent on SYNs, so ignore them here */ - -#if LWIP_TCP_TIMESTAMPS - if (optflags & TF_SEG_OPTS_TS) { - tcp_build_timestamp_option(pcb, opts); - opts += 3; - } -#endif - -#if LWIP_TCP_SACK_OUT - if (pcb && (num_sacks > 0)) { - tcp_build_sack_option(pcb, opts, num_sacks); - /* 1 word for SACKs header (including 2xNOP), and 2 words for each SACK */ - sacks_len = 1 + num_sacks * 2; - opts += sacks_len; - } -#else - LWIP_UNUSED_ARG(num_sacks); -#endif - -#ifdef LWIP_HOOK_TCP_OUT_ADD_TCPOPTS - opts = LWIP_HOOK_TCP_OUT_ADD_TCPOPTS(p, tcphdr, pcb, opts); -#endif - - LWIP_UNUSED_ARG(pcb); - LWIP_UNUSED_ARG(sacks_len); - LWIP_ASSERT("options not filled", (u8_t *)opts == ((u8_t *)(tcphdr + 1)) + sacks_len * 4 + LWIP_TCP_OPT_LENGTH_SEGMENT(optflags, pcb)); - LWIP_UNUSED_ARG(optflags); /* for LWIP_NOASSERT */ - LWIP_UNUSED_ARG(opts); /* for LWIP_NOASSERT */ -} - -/** Output a control segment pbuf to IP. - * - * Called from tcp_rst, tcp_send_empty_ack, tcp_keepalive and tcp_zero_window_probe, - * this function combines selecting a netif for transmission, generating the tcp - * header checksum and calling ip_output_if while handling netif hints and stats. - */ -static err_t -tcp_output_control_segment(const struct tcp_pcb *pcb, struct pbuf *p, - const ip_addr_t *src, const ip_addr_t *dst) -{ - err_t err; - struct netif *netif; - - LWIP_ASSERT("tcp_output_control_segment: invalid pbuf", p != NULL); - - netif = tcp_route(pcb, src, dst); - if (netif == NULL) { - err = ERR_RTE; - } else { - u8_t ttl, tos; -#if CHECKSUM_GEN_TCP - IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) { - struct tcp_hdr *tcphdr = (struct tcp_hdr *)p->payload; - tcphdr->chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len, - src, dst); - } -#endif - if (pcb != NULL) { - NETIF_SET_HINTS(netif, LWIP_CONST_CAST(struct netif_hint*, &(pcb->netif_hints))); - ttl = pcb->ttl; - tos = pcb->tos; - } else { - /* Send output with hardcoded TTL/HL since we have no access to the pcb */ - ttl = TCP_TTL; - tos = 0; - } - TCP_STATS_INC(tcp.xmit); - err = ip_output_if(p, src, dst, ttl, tos, IP_PROTO_TCP, netif); - NETIF_RESET_HINTS(netif); - } - pbuf_free(p); - return err; -} - -/** - * Send a TCP RESET packet (empty segment with RST flag set) either to - * abort a connection or to show that there is no matching local connection - * for a received segment. - * - * Called by tcp_abort() (to abort a local connection), tcp_input() (if no - * matching local pcb was found), tcp_listen_input() (if incoming segment - * has ACK flag set) and tcp_process() (received segment in the wrong state) - * - * Since a RST segment is in most cases not sent for an active connection, - * tcp_rst() has a number of arguments that are taken from a tcp_pcb for - * most other segment output functions. - * - * @param pcb TCP pcb (may be NULL if no pcb is available) - * @param seqno the sequence number to use for the outgoing segment - * @param ackno the acknowledge number to use for the outgoing segment - * @param local_ip the local IP address to send the segment from - * @param remote_ip the remote IP address to send the segment to - * @param local_port the local TCP port to send the segment from - * @param remote_port the remote TCP port to send the segment to - */ -void -tcp_rst(const struct tcp_pcb *pcb, u32_t seqno, u32_t ackno, - const ip_addr_t *local_ip, const ip_addr_t *remote_ip, - u16_t local_port, u16_t remote_port) -{ - struct pbuf *p; - u16_t wnd; - u8_t optlen; - - LWIP_ASSERT("tcp_rst: invalid local_ip", local_ip != NULL); - LWIP_ASSERT("tcp_rst: invalid remote_ip", remote_ip != NULL); - - optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(0, pcb); - -#if LWIP_WND_SCALE - wnd = PP_HTONS(((TCP_WND >> TCP_RCV_SCALE) & 0xFFFF)); -#else - wnd = PP_HTONS(TCP_WND); -#endif - - p = tcp_output_alloc_header_common(ackno, optlen, 0, lwip_htonl(seqno), local_port, - remote_port, TCP_RST | TCP_ACK, wnd); - if (p == NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_rst: could not allocate memory for pbuf\n")); - return; - } - tcp_output_fill_options(pcb, p, 0, optlen); - - MIB2_STATS_INC(mib2.tcpoutrsts); - - tcp_output_control_segment(pcb, p, local_ip, remote_ip); - LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %"U32_F" ackno %"U32_F".\n", seqno, ackno)); -} - -/** - * Send an ACK without data. - * - * @param pcb Protocol control block for the TCP connection to send the ACK - */ -err_t -tcp_send_empty_ack(struct tcp_pcb *pcb) -{ - err_t err; - struct pbuf *p; - u8_t optlen, optflags = 0; - u8_t num_sacks = 0; - - LWIP_ASSERT("tcp_send_empty_ack: invalid pcb", pcb != NULL); - -#if LWIP_TCP_TIMESTAMPS - if (pcb->flags & TF_TIMESTAMP) { - optflags = TF_SEG_OPTS_TS; - } -#endif - optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(optflags, pcb); - -#if LWIP_TCP_SACK_OUT - /* For now, SACKs are only sent with empty ACKs */ - if ((num_sacks = tcp_get_num_sacks(pcb, optlen)) > 0) { - optlen += 4 + num_sacks * 8; /* 4 bytes for header (including 2*NOP), plus 8B for each SACK */ - } -#endif - - p = tcp_output_alloc_header(pcb, optlen, 0, lwip_htonl(pcb->snd_nxt)); - if (p == NULL) { - /* let tcp_fasttmr retry sending this ACK */ - tcp_set_flags(pcb, TF_ACK_DELAY | TF_ACK_NOW); - LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: (ACK) could not allocate pbuf\n")); - return ERR_BUF; - } - tcp_output_fill_options(pcb, p, optflags, num_sacks); - -#if LWIP_TCP_TIMESTAMPS - pcb->ts_lastacksent = pcb->rcv_nxt; -#endif - - LWIP_DEBUGF(TCP_OUTPUT_DEBUG, - ("tcp_output: sending ACK for %"U32_F"\n", pcb->rcv_nxt)); - err = tcp_output_control_segment(pcb, p, &pcb->local_ip, &pcb->remote_ip); - if (err != ERR_OK) { - /* let tcp_fasttmr retry sending this ACK */ - tcp_set_flags(pcb, TF_ACK_DELAY | TF_ACK_NOW); - } else { - /* remove ACK flags from the PCB, as we sent an empty ACK now */ - tcp_clear_flags(pcb, TF_ACK_DELAY | TF_ACK_NOW); - } - - return err; -} - -/** - * Send keepalive packets to keep a connection active although - * no data is sent over it. - * - * Called by tcp_slowtmr() - * - * @param pcb the tcp_pcb for which to send a keepalive packet - */ -err_t -tcp_keepalive(struct tcp_pcb *pcb) -{ - err_t err; - struct pbuf *p; - u8_t optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(0, pcb); - - LWIP_ASSERT("tcp_keepalive: invalid pcb", pcb != NULL); - - LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: sending KEEPALIVE probe to ")); - ip_addr_debug_print_val(TCP_DEBUG, pcb->remote_ip); - LWIP_DEBUGF(TCP_DEBUG, ("\n")); - - LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: tcp_ticks %"U32_F" pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n", - tcp_ticks, pcb->tmr, (u16_t)pcb->keep_cnt_sent)); - - p = tcp_output_alloc_header(pcb, optlen, 0, lwip_htonl(pcb->snd_nxt - 1)); - if (p == NULL) { - LWIP_DEBUGF(TCP_DEBUG, - ("tcp_keepalive: could not allocate memory for pbuf\n")); - return ERR_MEM; - } - tcp_output_fill_options(pcb, p, 0, optlen); - err = tcp_output_control_segment(pcb, p, &pcb->local_ip, &pcb->remote_ip); - - LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: seqno %"U32_F" ackno %"U32_F" err %d.\n", - pcb->snd_nxt - 1, pcb->rcv_nxt, (int)err)); - return err; -} - -/** - * Send persist timer zero-window probes to keep a connection active - * when a window update is lost. - * - * Called by tcp_slowtmr() - * - * @param pcb the tcp_pcb for which to send a zero-window probe packet - */ -err_t -tcp_zero_window_probe(struct tcp_pcb *pcb) -{ - err_t err; - struct pbuf *p; - struct tcp_hdr *tcphdr; - struct tcp_seg *seg; - u16_t len; - u8_t is_fin; - u32_t snd_nxt; - u8_t optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(0, pcb); - - LWIP_ASSERT("tcp_zero_window_probe: invalid pcb", pcb != NULL); - - LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: sending ZERO WINDOW probe to ")); - ip_addr_debug_print_val(TCP_DEBUG, pcb->remote_ip); - LWIP_DEBUGF(TCP_DEBUG, ("\n")); - - LWIP_DEBUGF(TCP_DEBUG, - ("tcp_zero_window_probe: tcp_ticks %"U32_F - " pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n", - tcp_ticks, pcb->tmr, (u16_t)pcb->keep_cnt_sent)); - - /* Only consider unsent, persist timer should be off when there is data in-flight */ - seg = pcb->unsent; - if (seg == NULL) { - /* Not expected, persist timer should be off when the send buffer is empty */ - return ERR_OK; - } - - /* increment probe count. NOTE: we record probe even if it fails - to actually transmit due to an error. This ensures memory exhaustion/ - routing problem doesn't leave a zero-window pcb as an indefinite zombie. - RTO mechanism has similar behavior, see pcb->nrtx */ - if (pcb->persist_probe < 0xFF) { - ++pcb->persist_probe; - } - - is_fin = ((TCPH_FLAGS(seg->tcphdr) & TCP_FIN) != 0) && (seg->len == 0); - /* we want to send one seqno: either FIN or data (no options) */ - len = is_fin ? 0 : 1; - - p = tcp_output_alloc_header(pcb, optlen, len, seg->tcphdr->seqno); - if (p == NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: no memory for pbuf\n")); - return ERR_MEM; - } - tcphdr = (struct tcp_hdr *)p->payload; - - if (is_fin) { - /* FIN segment, no data */ - TCPH_FLAGS_SET(tcphdr, TCP_ACK | TCP_FIN); - } else { - /* Data segment, copy in one byte from the head of the unacked queue */ - char *d = ((char *)p->payload + TCP_HLEN); - /* Depending on whether the segment has already been sent (unacked) or not - (unsent), seg->p->payload points to the IP header or TCP header. - Ensure we copy the first TCP data byte: */ - pbuf_copy_partial(seg->p, d, 1, seg->p->tot_len - seg->len); - } - - /* The byte may be acknowledged without the window being opened. */ - snd_nxt = lwip_ntohl(seg->tcphdr->seqno) + 1; - if (TCP_SEQ_LT(pcb->snd_nxt, snd_nxt)) { - pcb->snd_nxt = snd_nxt; - } - tcp_output_fill_options(pcb, p, 0, optlen); - - err = tcp_output_control_segment(pcb, p, &pcb->local_ip, &pcb->remote_ip); - - LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: seqno %"U32_F - " ackno %"U32_F" err %d.\n", - pcb->snd_nxt - 1, pcb->rcv_nxt, (int)err)); - return err; -} -#endif /* LWIP_TCP */ diff --git a/third-party/lwip-2.1.2/core/timeouts.c b/third-party/lwip-2.1.2/core/timeouts.c deleted file mode 100644 index f37acfec..00000000 --- a/third-party/lwip-2.1.2/core/timeouts.c +++ /dev/null @@ -1,451 +0,0 @@ -/** - * @file - * Stack-internal timers implementation. - * This file includes timer callbacks for stack-internal timers as well as - * functions to set up or stop timers and check for expired timers. - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * Simon Goldschmidt - * - */ - -#include "lwip/opt.h" - -#include "lwip/timeouts.h" -#include "lwip/priv/tcp_priv.h" - -#include "lwip/def.h" -#include "lwip/memp.h" -#include "lwip/priv/tcpip_priv.h" - -#include "lwip/ip4_frag.h" -#include "lwip/etharp.h" -#include "lwip/dhcp.h" -#include "lwip/autoip.h" -#include "lwip/igmp.h" -#include "lwip/dns.h" -#include "lwip/nd6.h" -#include "lwip/ip6_frag.h" -#include "lwip/mld6.h" -#include "lwip/dhcp6.h" -#include "lwip/sys.h" -#include "lwip/pbuf.h" - -#if LWIP_DEBUG_TIMERNAMES -#define HANDLER(x) x, #x -#else /* LWIP_DEBUG_TIMERNAMES */ -#define HANDLER(x) x -#endif /* LWIP_DEBUG_TIMERNAMES */ - -#define LWIP_MAX_TIMEOUT 0x7fffffff - -/* Check if timer's expiry time is greater than time and care about u32_t wraparounds */ -#define TIME_LESS_THAN(t, compare_to) ( (((u32_t)((t)-(compare_to))) > LWIP_MAX_TIMEOUT) ? 1 : 0 ) - -/** This array contains all stack-internal cyclic timers. To get the number of - * timers, use LWIP_ARRAYSIZE() */ -const struct lwip_cyclic_timer lwip_cyclic_timers[] = { -#if LWIP_TCP - /* The TCP timer is a special case: it does not have to run always and - is triggered to start from TCP using tcp_timer_needed() */ - {TCP_TMR_INTERVAL, HANDLER(tcp_tmr)}, -#endif /* LWIP_TCP */ -#if LWIP_IPV4 -#if IP_REASSEMBLY - {IP_TMR_INTERVAL, HANDLER(ip_reass_tmr)}, -#endif /* IP_REASSEMBLY */ -#if LWIP_ARP - {ARP_TMR_INTERVAL, HANDLER(etharp_tmr)}, -#endif /* LWIP_ARP */ -#if LWIP_DHCP - {DHCP_COARSE_TIMER_MSECS, HANDLER(dhcp_coarse_tmr)}, - {DHCP_FINE_TIMER_MSECS, HANDLER(dhcp_fine_tmr)}, -#endif /* LWIP_DHCP */ -#if LWIP_AUTOIP - {AUTOIP_TMR_INTERVAL, HANDLER(autoip_tmr)}, -#endif /* LWIP_AUTOIP */ -#if LWIP_IGMP - {IGMP_TMR_INTERVAL, HANDLER(igmp_tmr)}, -#endif /* LWIP_IGMP */ -#endif /* LWIP_IPV4 */ -#if LWIP_DNS - {DNS_TMR_INTERVAL, HANDLER(dns_tmr)}, -#endif /* LWIP_DNS */ -#if LWIP_IPV6 - {ND6_TMR_INTERVAL, HANDLER(nd6_tmr)}, -#if LWIP_IPV6_REASS - {IP6_REASS_TMR_INTERVAL, HANDLER(ip6_reass_tmr)}, -#endif /* LWIP_IPV6_REASS */ -#if LWIP_IPV6_MLD - {MLD6_TMR_INTERVAL, HANDLER(mld6_tmr)}, -#endif /* LWIP_IPV6_MLD */ -#if LWIP_IPV6_DHCP6 - {DHCP6_TIMER_MSECS, HANDLER(dhcp6_tmr)}, -#endif /* LWIP_IPV6_DHCP6 */ -#endif /* LWIP_IPV6 */ -}; -const int lwip_num_cyclic_timers = LWIP_ARRAYSIZE(lwip_cyclic_timers); - -#if LWIP_TIMERS && !LWIP_TIMERS_CUSTOM - -/** The one and only timeout list */ -static struct sys_timeo *next_timeout; - -static u32_t current_timeout_due_time; - -#if LWIP_TESTMODE -struct sys_timeo** -sys_timeouts_get_next_timeout(void) -{ - return &next_timeout; -} -#endif - -#if LWIP_TCP -/** global variable that shows if the tcp timer is currently scheduled or not */ -static int tcpip_tcp_timer_active; - -/** - * Timer callback function that calls tcp_tmr() and reschedules itself. - * - * @param arg unused argument - */ -static void -tcpip_tcp_timer(void *arg) -{ - LWIP_UNUSED_ARG(arg); - - /* call TCP timer handler */ - tcp_tmr(); - /* timer still needed? */ - if (tcp_active_pcbs || tcp_tw_pcbs) { - /* restart timer */ - sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL); - } else { - /* disable timer */ - tcpip_tcp_timer_active = 0; - } -} - -/** - * Called from TCP_REG when registering a new PCB: - * the reason is to have the TCP timer only running when - * there are active (or time-wait) PCBs. - */ -void -tcp_timer_needed(void) -{ - LWIP_ASSERT_CORE_LOCKED(); - - /* timer is off but needed again? */ - if (!tcpip_tcp_timer_active && (tcp_active_pcbs || tcp_tw_pcbs)) { - /* enable and start timer */ - tcpip_tcp_timer_active = 1; - sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL); - } -} -#endif /* LWIP_TCP */ - -static void -#if LWIP_DEBUG_TIMERNAMES -sys_timeout_abs(u32_t abs_time, sys_timeout_handler handler, void *arg, const char *handler_name) -#else /* LWIP_DEBUG_TIMERNAMES */ -sys_timeout_abs(u32_t abs_time, sys_timeout_handler handler, void *arg) -#endif -{ - struct sys_timeo *timeout, *t; - - timeout = (struct sys_timeo *)memp_malloc(MEMP_SYS_TIMEOUT); - if (timeout == NULL) { - LWIP_ASSERT("sys_timeout: timeout != NULL, pool MEMP_SYS_TIMEOUT is empty", timeout != NULL); - return; - } - - timeout->next = NULL; - timeout->h = handler; - timeout->arg = arg; - timeout->time = abs_time; - -#if LWIP_DEBUG_TIMERNAMES - timeout->handler_name = handler_name; - LWIP_DEBUGF(TIMERS_DEBUG, ("sys_timeout: %p abs_time=%"U32_F" handler=%s arg=%p\n", - (void *)timeout, abs_time, handler_name, (void *)arg)); -#endif /* LWIP_DEBUG_TIMERNAMES */ - - if (next_timeout == NULL) { - next_timeout = timeout; - return; - } - if (TIME_LESS_THAN(timeout->time, next_timeout->time)) { - timeout->next = next_timeout; - next_timeout = timeout; - } else { - for (t = next_timeout; t != NULL; t = t->next) { - if ((t->next == NULL) || TIME_LESS_THAN(timeout->time, t->next->time)) { - timeout->next = t->next; - t->next = timeout; - break; - } - } - } -} - -/** - * Timer callback function that calls cyclic->handler() and reschedules itself. - * - * @param arg unused argument - */ -#if !LWIP_TESTMODE -static -#endif -void -lwip_cyclic_timer(void *arg) -{ - u32_t now; - u32_t next_timeout_time; - const struct lwip_cyclic_timer *cyclic = (const struct lwip_cyclic_timer *)arg; - -#if LWIP_DEBUG_TIMERNAMES - LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: %s()\n", cyclic->handler_name)); -#endif - cyclic->handler(); - - now = sys_now(); - next_timeout_time = (u32_t)(current_timeout_due_time + cyclic->interval_ms); /* overflow handled by TIME_LESS_THAN macro */ - if (TIME_LESS_THAN(next_timeout_time, now)) { - /* timer would immediately expire again -> "overload" -> restart without any correction */ -#if LWIP_DEBUG_TIMERNAMES - sys_timeout_abs((u32_t)(now + cyclic->interval_ms), lwip_cyclic_timer, arg, cyclic->handler_name); -#else - sys_timeout_abs((u32_t)(now + cyclic->interval_ms), lwip_cyclic_timer, arg); -#endif - - } else { - /* correct cyclic interval with handler execution delay and sys_check_timeouts jitter */ -#if LWIP_DEBUG_TIMERNAMES - sys_timeout_abs(next_timeout_time, lwip_cyclic_timer, arg, cyclic->handler_name); -#else - sys_timeout_abs(next_timeout_time, lwip_cyclic_timer, arg); -#endif - } -} - -/** Initialize this module */ -void sys_timeouts_init(void) -{ - size_t i; - /* tcp_tmr() at index 0 is started on demand */ - for (i = (LWIP_TCP ? 1 : 0); i < LWIP_ARRAYSIZE(lwip_cyclic_timers); i++) { - /* we have to cast via size_t to get rid of const warning - (this is OK as cyclic_timer() casts back to const* */ - sys_timeout(lwip_cyclic_timers[i].interval_ms, lwip_cyclic_timer, LWIP_CONST_CAST(void *, &lwip_cyclic_timers[i])); - } -} - -/** - * Create a one-shot timer (aka timeout). Timeouts are processed in the - * following cases: - * - while waiting for a message using sys_timeouts_mbox_fetch() - * - by calling sys_check_timeouts() (NO_SYS==1 only) - * - * @param msecs time in milliseconds after that the timer should expire - * @param handler callback function to call when msecs have elapsed - * @param arg argument to pass to the callback function - */ -#if LWIP_DEBUG_TIMERNAMES -void -sys_timeout_debug(u32_t msecs, sys_timeout_handler handler, void *arg, const char *handler_name) -#else /* LWIP_DEBUG_TIMERNAMES */ -void -sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg) -#endif /* LWIP_DEBUG_TIMERNAMES */ -{ - u32_t next_timeout_time; - - LWIP_ASSERT_CORE_LOCKED(); - - LWIP_ASSERT("Timeout time too long, max is LWIP_UINT32_MAX/4 msecs", msecs <= (LWIP_UINT32_MAX / 4)); - - next_timeout_time = (u32_t)(sys_now() + msecs); /* overflow handled by TIME_LESS_THAN macro */ - -#if LWIP_DEBUG_TIMERNAMES - sys_timeout_abs(next_timeout_time, handler, arg, handler_name); -#else - sys_timeout_abs(next_timeout_time, handler, arg); -#endif -} - -/** - * Go through timeout list (for this task only) and remove the first matching - * entry (subsequent entries remain untouched), even though the timeout has not - * triggered yet. - * - * @param handler callback function that would be called by the timeout - * @param arg callback argument that would be passed to handler -*/ -void -sys_untimeout(sys_timeout_handler handler, void *arg) -{ - struct sys_timeo *prev_t, *t; - - LWIP_ASSERT_CORE_LOCKED(); - - if (next_timeout == NULL) { - return; - } - - for (t = next_timeout, prev_t = NULL; t != NULL; prev_t = t, t = t->next) { - if ((t->h == handler) && (t->arg == arg)) { - /* We have a match */ - /* Unlink from previous in list */ - if (prev_t == NULL) { - next_timeout = t->next; - } else { - prev_t->next = t->next; - } - memp_free(MEMP_SYS_TIMEOUT, t); - return; - } - } - return; -} - -/** - * @ingroup lwip_nosys - * Handle timeouts for NO_SYS==1 (i.e. without using - * tcpip_thread/sys_timeouts_mbox_fetch(). Uses sys_now() to call timeout - * handler functions when timeouts expire. - * - * Must be called periodically from your main loop. - */ -void -sys_check_timeouts(void) -{ - u32_t now; - - LWIP_ASSERT_CORE_LOCKED(); - - /* Process only timers expired at the start of the function. */ - now = sys_now(); - - do { - struct sys_timeo *tmptimeout; - sys_timeout_handler handler; - void *arg; - - PBUF_CHECK_FREE_OOSEQ(); - - tmptimeout = next_timeout; - if (tmptimeout == NULL) { - return; - } - - if (TIME_LESS_THAN(now, tmptimeout->time)) { - return; - } - - /* Timeout has expired */ - next_timeout = tmptimeout->next; - handler = tmptimeout->h; - arg = tmptimeout->arg; - current_timeout_due_time = tmptimeout->time; -#if LWIP_DEBUG_TIMERNAMES - if (handler != NULL) { - LWIP_DEBUGF(TIMERS_DEBUG, ("sct calling h=%s t=%"U32_F" arg=%p\n", - tmptimeout->handler_name, sys_now() - tmptimeout->time, arg)); - } -#endif /* LWIP_DEBUG_TIMERNAMES */ - memp_free(MEMP_SYS_TIMEOUT, tmptimeout); - if (handler != NULL) { - handler(arg); - } - LWIP_TCPIP_THREAD_ALIVE(); - - /* Repeat until all expired timers have been called */ - } while (1); -} - -/** Rebase the timeout times to the current time. - * This is necessary if sys_check_timeouts() hasn't been called for a long - * time (e.g. while saving energy) to prevent all timer functions of that - * period being called. - */ -void -sys_restart_timeouts(void) -{ - u32_t now; - u32_t base; - struct sys_timeo *t; - - if (next_timeout == NULL) { - return; - } - - now = sys_now(); - base = next_timeout->time; - - for (t = next_timeout; t != NULL; t = t->next) { - t->time = (t->time - base) + now; - } -} - -/** Return the time left before the next timeout is due. If no timeouts are - * enqueued, returns 0xffffffff - */ -u32_t -sys_timeouts_sleeptime(void) -{ - u32_t now; - - LWIP_ASSERT_CORE_LOCKED(); - - if (next_timeout == NULL) { - return SYS_TIMEOUTS_SLEEPTIME_INFINITE; - } - now = sys_now(); - if (TIME_LESS_THAN(next_timeout->time, now)) { - return 0; - } else { - u32_t ret = (u32_t)(next_timeout->time - now); - LWIP_ASSERT("invalid sleeptime", ret <= LWIP_MAX_TIMEOUT); - return ret; - } -} - -#else /* LWIP_TIMERS && !LWIP_TIMERS_CUSTOM */ -/* Satisfy the TCP code which calls this function */ -void -tcp_timer_needed(void) -{ -} -#endif /* LWIP_TIMERS && !LWIP_TIMERS_CUSTOM */ diff --git a/third-party/lwip-2.1.2/core/udp.c b/third-party/lwip-2.1.2/core/udp.c deleted file mode 100644 index 9d2cb4af..00000000 --- a/third-party/lwip-2.1.2/core/udp.c +++ /dev/null @@ -1,1314 +0,0 @@ -/** - * @file - * User Datagram Protocol module\n - * The code for the User Datagram Protocol UDP & UDPLite (RFC 3828).\n - * See also @ref udp_raw - * - * @defgroup udp_raw UDP - * @ingroup callbackstyle_api - * User Datagram Protocol module\n - * @see @ref api - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -/* @todo Check the use of '(struct udp_pcb).chksum_len_rx'! - */ - -#include "lwip/opt.h" - -#if LWIP_UDP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/udp.h" -#include "lwip/def.h" -#include "lwip/memp.h" -#include "lwip/inet_chksum.h" -#include "lwip/ip_addr.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#include "lwip/netif.h" -#include "lwip/icmp.h" -#include "lwip/icmp6.h" -#include "lwip/stats.h" -#include "lwip/snmp.h" -#include "lwip/dhcp.h" - -#include - -#ifndef UDP_LOCAL_PORT_RANGE_START -/* From http://www.iana.org/assignments/port-numbers: - "The Dynamic and/or Private Ports are those from 49152 through 65535" */ -#define UDP_LOCAL_PORT_RANGE_START 0xc000 -#define UDP_LOCAL_PORT_RANGE_END 0xffff -#define UDP_ENSURE_LOCAL_PORT_RANGE(port) ((u16_t)(((port) & (u16_t)~UDP_LOCAL_PORT_RANGE_START) + UDP_LOCAL_PORT_RANGE_START)) -#endif - -/* last local UDP port */ -static u16_t udp_port = UDP_LOCAL_PORT_RANGE_START; - -/* The list of UDP PCBs */ -/* exported in udp.h (was static) */ -struct udp_pcb *udp_pcbs; - -/** - * Initialize this module. - */ -void -udp_init(void) -{ -#ifdef LWIP_RAND - udp_port = UDP_ENSURE_LOCAL_PORT_RANGE(LWIP_RAND()); -#endif /* LWIP_RAND */ -} - -/** - * Allocate a new local UDP port. - * - * @return a new (free) local UDP port number - */ -static u16_t -udp_new_port(void) -{ - u16_t n = 0; - struct udp_pcb *pcb; - -again: - if (udp_port++ == UDP_LOCAL_PORT_RANGE_END) { - udp_port = UDP_LOCAL_PORT_RANGE_START; - } - /* Check all PCBs. */ - for (pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) { - if (pcb->local_port == udp_port) { - if (++n > (UDP_LOCAL_PORT_RANGE_END - UDP_LOCAL_PORT_RANGE_START)) { - return 0; - } - goto again; - } - } - return udp_port; -} - -/** Common code to see if the current input packet matches the pcb - * (current input packet is accessed via ip(4/6)_current_* macros) - * - * @param pcb pcb to check - * @param inp network interface on which the datagram was received (only used for IPv4) - * @param broadcast 1 if his is an IPv4 broadcast (global or subnet-only), 0 otherwise (only used for IPv4) - * @return 1 on match, 0 otherwise - */ -static u8_t -udp_input_local_match(struct udp_pcb *pcb, struct netif *inp, u8_t broadcast) -{ - LWIP_UNUSED_ARG(inp); /* in IPv6 only case */ - LWIP_UNUSED_ARG(broadcast); /* in IPv6 only case */ - - LWIP_ASSERT("udp_input_local_match: invalid pcb", pcb != NULL); - LWIP_ASSERT("udp_input_local_match: invalid netif", inp != NULL); - - /* check if PCB is bound to specific netif */ - if ((pcb->netif_idx != NETIF_NO_INDEX) && - (pcb->netif_idx != netif_get_index(ip_data.current_input_netif))) { - return 0; - } - - /* Dual-stack: PCBs listening to any IP type also listen to any IP address */ - if (IP_IS_ANY_TYPE_VAL(pcb->local_ip)) { -#if LWIP_IPV4 && IP_SOF_BROADCAST_RECV - if ((broadcast != 0) && !ip_get_option(pcb, SOF_BROADCAST)) { - return 0; - } -#endif /* LWIP_IPV4 && IP_SOF_BROADCAST_RECV */ - return 1; - } - - /* Only need to check PCB if incoming IP version matches PCB IP version */ - if (IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ip_current_dest_addr())) { -#if LWIP_IPV4 - /* Special case: IPv4 broadcast: all or broadcasts in my subnet - * Note: broadcast variable can only be 1 if it is an IPv4 broadcast */ - if (broadcast != 0) { -#if IP_SOF_BROADCAST_RECV - if (ip_get_option(pcb, SOF_BROADCAST)) -#endif /* IP_SOF_BROADCAST_RECV */ - { - if (ip4_addr_isany(ip_2_ip4(&pcb->local_ip)) || - ((ip4_current_dest_addr()->addr == IPADDR_BROADCAST)) || - ip4_addr_netcmp(ip_2_ip4(&pcb->local_ip), ip4_current_dest_addr(), netif_ip4_netmask(inp))) { - return 1; - } - } - } else -#endif /* LWIP_IPV4 */ - /* Handle IPv4 and IPv6: all or exact match */ - if (ip_addr_isany(&pcb->local_ip) || ip_addr_cmp(&pcb->local_ip, ip_current_dest_addr())) { - return 1; - } - } - - return 0; -} - -/** - * Process an incoming UDP datagram. - * - * Given an incoming UDP datagram (as a chain of pbufs) this function - * finds a corresponding UDP PCB and hands over the pbuf to the pcbs - * recv function. If no pcb is found or the datagram is incorrect, the - * pbuf is freed. - * - * @param p pbuf to be demultiplexed to a UDP PCB (p->payload pointing to the UDP header) - * @param inp network interface on which the datagram was received. - * - */ -void -udp_input(struct pbuf *p, struct netif *inp) -{ - struct udp_hdr *udphdr; - struct udp_pcb *pcb, *prev; - struct udp_pcb *uncon_pcb; - u16_t src, dest; - u8_t broadcast; - u8_t for_us = 0; - - LWIP_UNUSED_ARG(inp); - - LWIP_ASSERT_CORE_LOCKED(); - - LWIP_ASSERT("udp_input: invalid pbuf", p != NULL); - LWIP_ASSERT("udp_input: invalid netif", inp != NULL); - - PERF_START; - - UDP_STATS_INC(udp.recv); - - /* Check minimum length (UDP header) */ - if (p->len < UDP_HLEN) { - /* drop short packets */ - LWIP_DEBUGF(UDP_DEBUG, - ("udp_input: short UDP datagram (%"U16_F" bytes) discarded\n", p->tot_len)); - UDP_STATS_INC(udp.lenerr); - UDP_STATS_INC(udp.drop); - MIB2_STATS_INC(mib2.udpinerrors); - pbuf_free(p); - goto end; - } - - udphdr = (struct udp_hdr *)p->payload; - - /* is broadcast packet ? */ - broadcast = ip_addr_isbroadcast(ip_current_dest_addr(), ip_current_netif()); - - LWIP_DEBUGF(UDP_DEBUG, ("udp_input: received datagram of length %"U16_F"\n", p->tot_len)); - - /* convert src and dest ports to host byte order */ - src = lwip_ntohs(udphdr->src); - dest = lwip_ntohs(udphdr->dest); - - udp_debug_print(udphdr); - - /* print the UDP source and destination */ - LWIP_DEBUGF(UDP_DEBUG, ("udp (")); - ip_addr_debug_print_val(UDP_DEBUG, *ip_current_dest_addr()); - LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F") <-- (", lwip_ntohs(udphdr->dest))); - ip_addr_debug_print_val(UDP_DEBUG, *ip_current_src_addr()); - LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F")\n", lwip_ntohs(udphdr->src))); - - pcb = NULL; - prev = NULL; - uncon_pcb = NULL; - /* Iterate through the UDP pcb list for a matching pcb. - * 'Perfect match' pcbs (connected to the remote port & ip address) are - * preferred. If no perfect match is found, the first unconnected pcb that - * matches the local port and ip address gets the datagram. */ - for (pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) { - /* print the PCB local and remote address */ - LWIP_DEBUGF(UDP_DEBUG, ("pcb (")); - ip_addr_debug_print_val(UDP_DEBUG, pcb->local_ip); - LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F") <-- (", pcb->local_port)); - ip_addr_debug_print_val(UDP_DEBUG, pcb->remote_ip); - LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F")\n", pcb->remote_port)); - - /* compare PCB local addr+port to UDP destination addr+port */ - if ((pcb->local_port == dest) && - (udp_input_local_match(pcb, inp, broadcast) != 0)) { - if ((pcb->flags & UDP_FLAGS_CONNECTED) == 0) { - if (uncon_pcb == NULL) { - /* the first unconnected matching PCB */ - uncon_pcb = pcb; -#if LWIP_IPV4 - } else if (broadcast && ip4_current_dest_addr()->addr == IPADDR_BROADCAST) { - /* global broadcast address (only valid for IPv4; match was checked before) */ - if (!IP_IS_V4_VAL(uncon_pcb->local_ip) || !ip4_addr_cmp(ip_2_ip4(&uncon_pcb->local_ip), netif_ip4_addr(inp))) { - /* uncon_pcb does not match the input netif, check this pcb */ - if (IP_IS_V4_VAL(pcb->local_ip) && ip4_addr_cmp(ip_2_ip4(&pcb->local_ip), netif_ip4_addr(inp))) { - /* better match */ - uncon_pcb = pcb; - } - } -#endif /* LWIP_IPV4 */ - } -#if SO_REUSE - else if (!ip_addr_isany(&pcb->local_ip)) { - /* prefer specific IPs over catch-all */ - uncon_pcb = pcb; - } -#endif /* SO_REUSE */ - } - - /* compare PCB remote addr+port to UDP source addr+port */ - if ((pcb->remote_port == src) && - (ip_addr_isany_val(pcb->remote_ip) || - ip_addr_cmp(&pcb->remote_ip, ip_current_src_addr()))) { - /* the first fully matching PCB */ - if (prev != NULL) { - /* move the pcb to the front of udp_pcbs so that is - found faster next time */ - prev->next = pcb->next; - pcb->next = udp_pcbs; - udp_pcbs = pcb; - } else { - UDP_STATS_INC(udp.cachehit); - } - break; - } - } - - prev = pcb; - } - /* no fully matching pcb found? then look for an unconnected pcb */ - if (pcb == NULL) { - pcb = uncon_pcb; - } - - /* Check checksum if this is a match or if it was directed at us. */ - if (pcb != NULL) { - for_us = 1; - } else { -#if LWIP_IPV6 - if (ip_current_is_v6()) { - for_us = netif_get_ip6_addr_match(inp, ip6_current_dest_addr()) >= 0; - } -#endif /* LWIP_IPV6 */ -#if LWIP_IPV4 - if (!ip_current_is_v6()) { - for_us = ip4_addr_cmp(netif_ip4_addr(inp), ip4_current_dest_addr()); - } -#endif /* LWIP_IPV4 */ - } - - if (for_us) { - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: calculating checksum\n")); -#if CHECKSUM_CHECK_UDP - IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_UDP) { -#if LWIP_UDPLITE - if (ip_current_header_proto() == IP_PROTO_UDPLITE) { - /* Do the UDP Lite checksum */ - u16_t chklen = lwip_ntohs(udphdr->len); - if (chklen < sizeof(struct udp_hdr)) { - if (chklen == 0) { - /* For UDP-Lite, checksum length of 0 means checksum - over the complete packet (See RFC 3828 chap. 3.1) */ - chklen = p->tot_len; - } else { - /* At least the UDP-Lite header must be covered by the - checksum! (Again, see RFC 3828 chap. 3.1) */ - goto chkerr; - } - } - if (ip_chksum_pseudo_partial(p, IP_PROTO_UDPLITE, - p->tot_len, chklen, - ip_current_src_addr(), ip_current_dest_addr()) != 0) { - goto chkerr; - } - } else -#endif /* LWIP_UDPLITE */ - { - if (udphdr->chksum != 0) { - if (ip_chksum_pseudo(p, IP_PROTO_UDP, p->tot_len, - ip_current_src_addr(), - ip_current_dest_addr()) != 0) { - goto chkerr; - } - } - } - } -#endif /* CHECKSUM_CHECK_UDP */ - if (pbuf_remove_header(p, UDP_HLEN)) { - /* Can we cope with this failing? Just assert for now */ - LWIP_ASSERT("pbuf_remove_header failed\n", 0); - UDP_STATS_INC(udp.drop); - MIB2_STATS_INC(mib2.udpinerrors); - pbuf_free(p); - goto end; - } - - if (pcb != NULL) { - MIB2_STATS_INC(mib2.udpindatagrams); -#if SO_REUSE && SO_REUSE_RXTOALL - if (ip_get_option(pcb, SOF_REUSEADDR) && - (broadcast || ip_addr_ismulticast(ip_current_dest_addr()))) { - /* pass broadcast- or multicast packets to all multicast pcbs - if SOF_REUSEADDR is set on the first match */ - struct udp_pcb *mpcb; - for (mpcb = udp_pcbs; mpcb != NULL; mpcb = mpcb->next) { - if (mpcb != pcb) { - /* compare PCB local addr+port to UDP destination addr+port */ - if ((mpcb->local_port == dest) && - (udp_input_local_match(mpcb, inp, broadcast) != 0)) { - /* pass a copy of the packet to all local matches */ - if (mpcb->recv != NULL) { - struct pbuf *q; - q = pbuf_clone(PBUF_RAW, PBUF_POOL, p); - if (q != NULL) { - mpcb->recv(mpcb->recv_arg, mpcb, q, ip_current_src_addr(), src); - } - } - } - } - } - } -#endif /* SO_REUSE && SO_REUSE_RXTOALL */ - /* callback */ - if (pcb->recv != NULL) { - /* now the recv function is responsible for freeing p */ - pcb->recv(pcb->recv_arg, pcb, p, ip_current_src_addr(), src); - } else { - /* no recv function registered? then we have to free the pbuf! */ - pbuf_free(p); - goto end; - } - } else { - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: not for us.\n")); - -#if LWIP_ICMP || LWIP_ICMP6 - /* No match was found, send ICMP destination port unreachable unless - destination address was broadcast/multicast. */ - if (!broadcast && !ip_addr_ismulticast(ip_current_dest_addr())) { - /* move payload pointer back to ip header */ - pbuf_header_force(p, (s16_t)(ip_current_header_tot_len() + UDP_HLEN)); - icmp_port_unreach(ip_current_is_v6(), p); - } -#endif /* LWIP_ICMP || LWIP_ICMP6 */ - UDP_STATS_INC(udp.proterr); - UDP_STATS_INC(udp.drop); - MIB2_STATS_INC(mib2.udpnoports); - pbuf_free(p); - } - } else { - pbuf_free(p); - } -end: - PERF_STOP("udp_input"); - return; -#if CHECKSUM_CHECK_UDP -chkerr: - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("udp_input: UDP (or UDP Lite) datagram discarded due to failing checksum\n")); - UDP_STATS_INC(udp.chkerr); - UDP_STATS_INC(udp.drop); - MIB2_STATS_INC(mib2.udpinerrors); - pbuf_free(p); - PERF_STOP("udp_input"); -#endif /* CHECKSUM_CHECK_UDP */ -} - -/** - * @ingroup udp_raw - * Sends the pbuf p using UDP. The pbuf is not deallocated. - * - * - * @param pcb UDP PCB used to send the data. - * @param p chain of pbuf's to be sent. - * - * The datagram will be sent to the current remote_ip & remote_port - * stored in pcb. If the pcb is not bound to a port, it will - * automatically be bound to a random port. - * - * @return lwIP error code. - * - ERR_OK. Successful. No error occurred. - * - ERR_MEM. Out of memory. - * - ERR_RTE. Could not find route to destination address. - * - ERR_VAL. No PCB or PCB is dual-stack - * - More errors could be returned by lower protocol layers. - * - * @see udp_disconnect() udp_sendto() - */ -err_t -udp_send(struct udp_pcb *pcb, struct pbuf *p) -{ - LWIP_ERROR("udp_send: invalid pcb", pcb != NULL, return ERR_ARG); - LWIP_ERROR("udp_send: invalid pbuf", p != NULL, return ERR_ARG); - - if (IP_IS_ANY_TYPE_VAL(pcb->remote_ip)) { - return ERR_VAL; - } - - /* send to the packet using remote ip and port stored in the pcb */ - return udp_sendto(pcb, p, &pcb->remote_ip, pcb->remote_port); -} - -#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP -/** @ingroup udp_raw - * Same as udp_send() but with checksum - */ -err_t -udp_send_chksum(struct udp_pcb *pcb, struct pbuf *p, - u8_t have_chksum, u16_t chksum) -{ - LWIP_ERROR("udp_send_chksum: invalid pcb", pcb != NULL, return ERR_ARG); - LWIP_ERROR("udp_send_chksum: invalid pbuf", p != NULL, return ERR_ARG); - - if (IP_IS_ANY_TYPE_VAL(pcb->remote_ip)) { - return ERR_VAL; - } - - /* send to the packet using remote ip and port stored in the pcb */ - return udp_sendto_chksum(pcb, p, &pcb->remote_ip, pcb->remote_port, - have_chksum, chksum); -} -#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ - -/** - * @ingroup udp_raw - * Send data to a specified address using UDP. - * - * @param pcb UDP PCB used to send the data. - * @param p chain of pbuf's to be sent. - * @param dst_ip Destination IP address. - * @param dst_port Destination UDP port. - * - * dst_ip & dst_port are expected to be in the same byte order as in the pcb. - * - * If the PCB already has a remote address association, it will - * be restored after the data is sent. - * - * @return lwIP error code (@see udp_send for possible error codes) - * - * @see udp_disconnect() udp_send() - */ -err_t -udp_sendto(struct udp_pcb *pcb, struct pbuf *p, - const ip_addr_t *dst_ip, u16_t dst_port) -{ -#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP - return udp_sendto_chksum(pcb, p, dst_ip, dst_port, 0, 0); -} - -/** @ingroup udp_raw - * Same as udp_sendto(), but with checksum */ -err_t -udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip, - u16_t dst_port, u8_t have_chksum, u16_t chksum) -{ -#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ - struct netif *netif; - - LWIP_ERROR("udp_sendto: invalid pcb", pcb != NULL, return ERR_ARG); - LWIP_ERROR("udp_sendto: invalid pbuf", p != NULL, return ERR_ARG); - LWIP_ERROR("udp_sendto: invalid dst_ip", dst_ip != NULL, return ERR_ARG); - - if (!IP_ADDR_PCB_VERSION_MATCH(pcb, dst_ip)) { - return ERR_VAL; - } - - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send\n")); - - if (pcb->netif_idx != NETIF_NO_INDEX) { - netif = netif_get_by_index(pcb->netif_idx); - } else { -#if LWIP_MULTICAST_TX_OPTIONS - netif = NULL; - if (ip_addr_ismulticast(dst_ip)) { - /* For IPv6, the interface to use for packets with a multicast destination - * is specified using an interface index. The same approach may be used for - * IPv4 as well, in which case it overrides the IPv4 multicast override - * address below. Here we have to look up the netif by going through the - * list, but by doing so we skip a route lookup. If the interface index has - * gone stale, we fall through and do the regular route lookup after all. */ - if (pcb->mcast_ifindex != NETIF_NO_INDEX) { - netif = netif_get_by_index(pcb->mcast_ifindex); - } -#if LWIP_IPV4 - else -#if LWIP_IPV6 - if (IP_IS_V4(dst_ip)) -#endif /* LWIP_IPV6 */ - { - /* IPv4 does not use source-based routing by default, so we use an - administratively selected interface for multicast by default. - However, this can be overridden by setting an interface address - in pcb->mcast_ip4 that is used for routing. If this routing lookup - fails, we try regular routing as though no override was set. */ - if (!ip4_addr_isany_val(pcb->mcast_ip4) && - !ip4_addr_cmp(&pcb->mcast_ip4, IP4_ADDR_BROADCAST)) { - netif = ip4_route_src(ip_2_ip4(&pcb->local_ip), &pcb->mcast_ip4); - } - } -#endif /* LWIP_IPV4 */ - } - - if (netif == NULL) -#endif /* LWIP_MULTICAST_TX_OPTIONS */ - { - /* find the outgoing network interface for this packet */ - netif = ip_route(&pcb->local_ip, dst_ip); - } - } - - /* no outgoing network interface could be found? */ - if (netif == NULL) { - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: No route to ")); - ip_addr_debug_print(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, dst_ip); - LWIP_DEBUGF(UDP_DEBUG, ("\n")); - UDP_STATS_INC(udp.rterr); - return ERR_RTE; - } -#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP - return udp_sendto_if_chksum(pcb, p, dst_ip, dst_port, netif, have_chksum, chksum); -#else /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ - return udp_sendto_if(pcb, p, dst_ip, dst_port, netif); -#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ -} - -/** - * @ingroup udp_raw - * Send data to a specified address using UDP. - * The netif used for sending can be specified. - * - * This function exists mainly for DHCP, to be able to send UDP packets - * on a netif that is still down. - * - * @param pcb UDP PCB used to send the data. - * @param p chain of pbuf's to be sent. - * @param dst_ip Destination IP address. - * @param dst_port Destination UDP port. - * @param netif the netif used for sending. - * - * dst_ip & dst_port are expected to be in the same byte order as in the pcb. - * - * @return lwIP error code (@see udp_send for possible error codes) - * - * @see udp_disconnect() udp_send() - */ -err_t -udp_sendto_if(struct udp_pcb *pcb, struct pbuf *p, - const ip_addr_t *dst_ip, u16_t dst_port, struct netif *netif) -{ -#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP - return udp_sendto_if_chksum(pcb, p, dst_ip, dst_port, netif, 0, 0); -} - -/** Same as udp_sendto_if(), but with checksum */ -err_t -udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip, - u16_t dst_port, struct netif *netif, u8_t have_chksum, - u16_t chksum) -{ -#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ - const ip_addr_t *src_ip; - - LWIP_ERROR("udp_sendto_if: invalid pcb", pcb != NULL, return ERR_ARG); - LWIP_ERROR("udp_sendto_if: invalid pbuf", p != NULL, return ERR_ARG); - LWIP_ERROR("udp_sendto_if: invalid dst_ip", dst_ip != NULL, return ERR_ARG); - LWIP_ERROR("udp_sendto_if: invalid netif", netif != NULL, return ERR_ARG); - - if (!IP_ADDR_PCB_VERSION_MATCH(pcb, dst_ip)) { - return ERR_VAL; - } - - /* PCB local address is IP_ANY_ADDR or multicast? */ -#if LWIP_IPV6 - if (IP_IS_V6(dst_ip)) { - if (ip6_addr_isany(ip_2_ip6(&pcb->local_ip)) || - ip6_addr_ismulticast(ip_2_ip6(&pcb->local_ip))) { - src_ip = ip6_select_source_address(netif, ip_2_ip6(dst_ip)); - if (src_ip == NULL) { - /* No suitable source address was found. */ - return ERR_RTE; - } - } else { - /* use UDP PCB local IPv6 address as source address, if still valid. */ - if (netif_get_ip6_addr_match(netif, ip_2_ip6(&pcb->local_ip)) < 0) { - /* Address isn't valid anymore. */ - return ERR_RTE; - } - src_ip = &pcb->local_ip; - } - } -#endif /* LWIP_IPV6 */ -#if LWIP_IPV4 && LWIP_IPV6 - else -#endif /* LWIP_IPV4 && LWIP_IPV6 */ -#if LWIP_IPV4 - if (ip4_addr_isany(ip_2_ip4(&pcb->local_ip)) || - ip4_addr_ismulticast(ip_2_ip4(&pcb->local_ip))) { - /* if the local_ip is any or multicast - * use the outgoing network interface IP address as source address */ - src_ip = netif_ip_addr4(netif); - } else { - /* check if UDP PCB local IP address is correct - * this could be an old address if netif->ip_addr has changed */ - if (!ip4_addr_cmp(ip_2_ip4(&(pcb->local_ip)), netif_ip4_addr(netif))) { - /* local_ip doesn't match, drop the packet */ - return ERR_RTE; - } - /* use UDP PCB local IP address as source address */ - src_ip = &pcb->local_ip; - } -#endif /* LWIP_IPV4 */ -#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP - return udp_sendto_if_src_chksum(pcb, p, dst_ip, dst_port, netif, have_chksum, chksum, src_ip); -#else /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ - return udp_sendto_if_src(pcb, p, dst_ip, dst_port, netif, src_ip); -#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ -} - -/** @ingroup udp_raw - * Same as @ref udp_sendto_if, but with source address */ -err_t -udp_sendto_if_src(struct udp_pcb *pcb, struct pbuf *p, - const ip_addr_t *dst_ip, u16_t dst_port, struct netif *netif, const ip_addr_t *src_ip) -{ -#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP - return udp_sendto_if_src_chksum(pcb, p, dst_ip, dst_port, netif, 0, 0, src_ip); -} - -/** Same as udp_sendto_if_src(), but with checksum */ -err_t -udp_sendto_if_src_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip, - u16_t dst_port, struct netif *netif, u8_t have_chksum, - u16_t chksum, const ip_addr_t *src_ip) -{ -#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ - struct udp_hdr *udphdr; - err_t err; - struct pbuf *q; /* q will be sent down the stack */ - u8_t ip_proto; - u8_t ttl; - - LWIP_ASSERT_CORE_LOCKED(); - - LWIP_ERROR("udp_sendto_if_src: invalid pcb", pcb != NULL, return ERR_ARG); - LWIP_ERROR("udp_sendto_if_src: invalid pbuf", p != NULL, return ERR_ARG); - LWIP_ERROR("udp_sendto_if_src: invalid dst_ip", dst_ip != NULL, return ERR_ARG); - LWIP_ERROR("udp_sendto_if_src: invalid src_ip", src_ip != NULL, return ERR_ARG); - LWIP_ERROR("udp_sendto_if_src: invalid netif", netif != NULL, return ERR_ARG); - - if (!IP_ADDR_PCB_VERSION_MATCH(pcb, src_ip) || - !IP_ADDR_PCB_VERSION_MATCH(pcb, dst_ip)) { - return ERR_VAL; - } - -#if LWIP_IPV4 && IP_SOF_BROADCAST - /* broadcast filter? */ - if (!ip_get_option(pcb, SOF_BROADCAST) && -#if LWIP_IPV6 - IP_IS_V4(dst_ip) && -#endif /* LWIP_IPV6 */ - ip_addr_isbroadcast(dst_ip, netif)) { - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("udp_sendto_if: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb)); - return ERR_VAL; - } -#endif /* LWIP_IPV4 && IP_SOF_BROADCAST */ - - /* if the PCB is not yet bound to a port, bind it here */ - if (pcb->local_port == 0) { - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send: not yet bound to a port, binding now\n")); - err = udp_bind(pcb, &pcb->local_ip, pcb->local_port); - if (err != ERR_OK) { - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: forced port bind failed\n")); - return err; - } - } - - /* packet too large to add a UDP header without causing an overflow? */ - if ((u16_t)(p->tot_len + UDP_HLEN) < p->tot_len) { - return ERR_MEM; - } - /* not enough space to add an UDP header to first pbuf in given p chain? */ - if (pbuf_add_header(p, UDP_HLEN)) { - /* allocate header in a separate new pbuf */ - q = pbuf_alloc(PBUF_IP, UDP_HLEN, PBUF_RAM); - /* new header pbuf could not be allocated? */ - if (q == NULL) { - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: could not allocate header\n")); - return ERR_MEM; - } - if (p->tot_len != 0) { - /* chain header q in front of given pbuf p (only if p contains data) */ - pbuf_chain(q, p); - } - /* first pbuf q points to header pbuf */ - LWIP_DEBUGF(UDP_DEBUG, - ("udp_send: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p)); - } else { - /* adding space for header within p succeeded */ - /* first pbuf q equals given pbuf */ - q = p; - LWIP_DEBUGF(UDP_DEBUG, ("udp_send: added header in given pbuf %p\n", (void *)p)); - } - LWIP_ASSERT("check that first pbuf can hold struct udp_hdr", - (q->len >= sizeof(struct udp_hdr))); - /* q now represents the packet to be sent */ - udphdr = (struct udp_hdr *)q->payload; - udphdr->src = lwip_htons(pcb->local_port); - udphdr->dest = lwip_htons(dst_port); - /* in UDP, 0 checksum means 'no checksum' */ - udphdr->chksum = 0x0000; - - /* Multicast Loop? */ -#if LWIP_MULTICAST_TX_OPTIONS - if (((pcb->flags & UDP_FLAGS_MULTICAST_LOOP) != 0) && ip_addr_ismulticast(dst_ip)) { - q->flags |= PBUF_FLAG_MCASTLOOP; - } -#endif /* LWIP_MULTICAST_TX_OPTIONS */ - - LWIP_DEBUGF(UDP_DEBUG, ("udp_send: sending datagram of length %"U16_F"\n", q->tot_len)); - -#if LWIP_UDPLITE - /* UDP Lite protocol? */ - if (pcb->flags & UDP_FLAGS_UDPLITE) { - u16_t chklen, chklen_hdr; - LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE packet length %"U16_F"\n", q->tot_len)); - /* set UDP message length in UDP header */ - chklen_hdr = chklen = pcb->chksum_len_tx; - if ((chklen < sizeof(struct udp_hdr)) || (chklen > q->tot_len)) { - if (chklen != 0) { - LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE pcb->chksum_len is illegal: %"U16_F"\n", chklen)); - } - /* For UDP-Lite, checksum length of 0 means checksum - over the complete packet. (See RFC 3828 chap. 3.1) - At least the UDP-Lite header must be covered by the - checksum, therefore, if chksum_len has an illegal - value, we generate the checksum over the complete - packet to be safe. */ - chklen_hdr = 0; - chklen = q->tot_len; - } - udphdr->len = lwip_htons(chklen_hdr); - /* calculate checksum */ -#if CHECKSUM_GEN_UDP - IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_UDP) { -#if LWIP_CHECKSUM_ON_COPY - if (have_chksum) { - chklen = UDP_HLEN; - } -#endif /* LWIP_CHECKSUM_ON_COPY */ - udphdr->chksum = ip_chksum_pseudo_partial(q, IP_PROTO_UDPLITE, - q->tot_len, chklen, src_ip, dst_ip); -#if LWIP_CHECKSUM_ON_COPY - if (have_chksum) { - u32_t acc; - acc = udphdr->chksum + (u16_t)~(chksum); - udphdr->chksum = FOLD_U32T(acc); - } -#endif /* LWIP_CHECKSUM_ON_COPY */ - - /* chksum zero must become 0xffff, as zero means 'no checksum' */ - if (udphdr->chksum == 0x0000) { - udphdr->chksum = 0xffff; - } - } -#endif /* CHECKSUM_GEN_UDP */ - - ip_proto = IP_PROTO_UDPLITE; - } else -#endif /* LWIP_UDPLITE */ - { /* UDP */ - LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %"U16_F"\n", q->tot_len)); - udphdr->len = lwip_htons(q->tot_len); - /* calculate checksum */ -#if CHECKSUM_GEN_UDP - IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_UDP) { - /* Checksum is mandatory over IPv6. */ - if (IP_IS_V6(dst_ip) || (pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) { - u16_t udpchksum; -#if LWIP_CHECKSUM_ON_COPY - if (have_chksum) { - u32_t acc; - udpchksum = ip_chksum_pseudo_partial(q, IP_PROTO_UDP, - q->tot_len, UDP_HLEN, src_ip, dst_ip); - acc = udpchksum + (u16_t)~(chksum); - udpchksum = FOLD_U32T(acc); - } else -#endif /* LWIP_CHECKSUM_ON_COPY */ - { - udpchksum = ip_chksum_pseudo(q, IP_PROTO_UDP, q->tot_len, - src_ip, dst_ip); - } - - /* chksum zero must become 0xffff, as zero means 'no checksum' */ - if (udpchksum == 0x0000) { - udpchksum = 0xffff; - } - udphdr->chksum = udpchksum; - } - } -#endif /* CHECKSUM_GEN_UDP */ - ip_proto = IP_PROTO_UDP; - } - - /* Determine TTL to use */ -#if LWIP_MULTICAST_TX_OPTIONS - ttl = (ip_addr_ismulticast(dst_ip) ? udp_get_multicast_ttl(pcb) : pcb->ttl); -#else /* LWIP_MULTICAST_TX_OPTIONS */ - ttl = pcb->ttl; -#endif /* LWIP_MULTICAST_TX_OPTIONS */ - - LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04"X16_F"\n", udphdr->chksum)); - LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,0x%02"X16_F",)\n", (u16_t)ip_proto)); - /* output to IP */ - NETIF_SET_HINTS(netif, &(pcb->netif_hints)); - err = ip_output_if_src(q, src_ip, dst_ip, ttl, pcb->tos, ip_proto, netif); - NETIF_RESET_HINTS(netif); - - /* @todo: must this be increased even if error occurred? */ - MIB2_STATS_INC(mib2.udpoutdatagrams); - - /* did we chain a separate header pbuf earlier? */ - if (q != p) { - /* free the header pbuf */ - pbuf_free(q); - q = NULL; - /* p is still referenced by the caller, and will live on */ - } - - UDP_STATS_INC(udp.xmit); - return err; -} - -/** - * @ingroup udp_raw - * Bind an UDP PCB. - * - * @param pcb UDP PCB to be bound with a local address ipaddr and port. - * @param ipaddr local IP address to bind with. Use IP_ANY_TYPE to - * bind to all local interfaces. - * @param port local UDP port to bind with. Use 0 to automatically bind - * to a random port between UDP_LOCAL_PORT_RANGE_START and - * UDP_LOCAL_PORT_RANGE_END. - * - * ipaddr & port are expected to be in the same byte order as in the pcb. - * - * @return lwIP error code. - * - ERR_OK. Successful. No error occurred. - * - ERR_USE. The specified ipaddr and port are already bound to by - * another UDP PCB. - * - * @see udp_disconnect() - */ -err_t -udp_bind(struct udp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port) -{ - struct udp_pcb *ipcb; - u8_t rebind; -#if LWIP_IPV6 && LWIP_IPV6_SCOPES - ip_addr_t zoned_ipaddr; -#endif /* LWIP_IPV6 && LWIP_IPV6_SCOPES */ - - LWIP_ASSERT_CORE_LOCKED(); - -#if LWIP_IPV4 - /* Don't propagate NULL pointer (IPv4 ANY) to subsequent functions */ - if (ipaddr == NULL) { - ipaddr = IP4_ADDR_ANY; - } -#else /* LWIP_IPV4 */ - LWIP_ERROR("udp_bind: invalid ipaddr", ipaddr != NULL, return ERR_ARG); -#endif /* LWIP_IPV4 */ - - LWIP_ERROR("udp_bind: invalid pcb", pcb != NULL, return ERR_ARG); - - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_bind(ipaddr = ")); - ip_addr_debug_print(UDP_DEBUG | LWIP_DBG_TRACE, ipaddr); - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, (", port = %"U16_F")\n", port)); - - rebind = 0; - /* Check for double bind and rebind of the same pcb */ - for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) { - /* is this UDP PCB already on active list? */ - if (pcb == ipcb) { - rebind = 1; - break; - } - } - -#if LWIP_IPV6 && LWIP_IPV6_SCOPES - /* If the given IP address should have a zone but doesn't, assign one now. - * This is legacy support: scope-aware callers should always provide properly - * zoned source addresses. Do the zone selection before the address-in-use - * check below; as such we have to make a temporary copy of the address. */ - if (IP_IS_V6(ipaddr) && ip6_addr_lacks_zone(ip_2_ip6(ipaddr), IP6_UNKNOWN)) { - ip_addr_copy(zoned_ipaddr, *ipaddr); - ip6_addr_select_zone(ip_2_ip6(&zoned_ipaddr), ip_2_ip6(&zoned_ipaddr)); - ipaddr = &zoned_ipaddr; - } -#endif /* LWIP_IPV6 && LWIP_IPV6_SCOPES */ - - /* no port specified? */ - if (port == 0) { - port = udp_new_port(); - if (port == 0) { - /* no more ports available in local range */ - LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: out of free UDP ports\n")); - return ERR_USE; - } - } else { - for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) { - if (pcb != ipcb) { - /* By default, we don't allow to bind to a port that any other udp - PCB is already bound to, unless *all* PCBs with that port have tha - REUSEADDR flag set. */ -#if SO_REUSE - if (!ip_get_option(pcb, SOF_REUSEADDR) || - !ip_get_option(ipcb, SOF_REUSEADDR)) -#endif /* SO_REUSE */ - { - /* port matches that of PCB in list and REUSEADDR not set -> reject */ - if ((ipcb->local_port == port) && - /* IP address matches or any IP used? */ - (ip_addr_cmp(&ipcb->local_ip, ipaddr) || ip_addr_isany(ipaddr) || - ip_addr_isany(&ipcb->local_ip))) { - /* other PCB already binds to this local IP and port */ - LWIP_DEBUGF(UDP_DEBUG, - ("udp_bind: local port %"U16_F" already bound by another pcb\n", port)); - return ERR_USE; - } - } - } - } - } - - ip_addr_set_ipaddr(&pcb->local_ip, ipaddr); - - pcb->local_port = port; - mib2_udp_bind(pcb); - /* pcb not active yet? */ - if (rebind == 0) { - /* place the PCB on the active list if not already there */ - pcb->next = udp_pcbs; - udp_pcbs = pcb; - } - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("udp_bind: bound to ")); - ip_addr_debug_print_val(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, pcb->local_ip); - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, (", port %"U16_F")\n", pcb->local_port)); - return ERR_OK; -} - -/** - * @ingroup udp_raw - * Bind an UDP PCB to a specific netif. - * After calling this function, all packets received via this PCB - * are guaranteed to have come in via the specified netif, and all - * outgoing packets will go out via the specified netif. - * - * @param pcb UDP PCB to be bound. - * @param netif netif to bind udp pcb to. Can be NULL. - * - * @see udp_disconnect() - */ -void -udp_bind_netif(struct udp_pcb *pcb, const struct netif *netif) -{ - LWIP_ASSERT_CORE_LOCKED(); - - if (netif != NULL) { - pcb->netif_idx = netif_get_index(netif); - } else { - pcb->netif_idx = NETIF_NO_INDEX; - } -} - -/** - * @ingroup udp_raw - * Sets the remote end of the pcb. This function does not generate any - * network traffic, but only sets the remote address of the pcb. - * - * @param pcb UDP PCB to be connected with remote address ipaddr and port. - * @param ipaddr remote IP address to connect with. - * @param port remote UDP port to connect with. - * - * @return lwIP error code - * - * ipaddr & port are expected to be in the same byte order as in the pcb. - * - * The udp pcb is bound to a random local port if not already bound. - * - * @see udp_disconnect() - */ -err_t -udp_connect(struct udp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port) -{ - struct udp_pcb *ipcb; - - LWIP_ASSERT_CORE_LOCKED(); - - LWIP_ERROR("udp_connect: invalid pcb", pcb != NULL, return ERR_ARG); - LWIP_ERROR("udp_connect: invalid ipaddr", ipaddr != NULL, return ERR_ARG); - - if (pcb->local_port == 0) { - err_t err = udp_bind(pcb, &pcb->local_ip, pcb->local_port); - if (err != ERR_OK) { - return err; - } - } - - ip_addr_set_ipaddr(&pcb->remote_ip, ipaddr); -#if LWIP_IPV6 && LWIP_IPV6_SCOPES - /* If the given IP address should have a zone but doesn't, assign one now, - * using the bound address to make a more informed decision when possible. */ - if (IP_IS_V6(&pcb->remote_ip) && - ip6_addr_lacks_zone(ip_2_ip6(&pcb->remote_ip), IP6_UNKNOWN)) { - ip6_addr_select_zone(ip_2_ip6(&pcb->remote_ip), ip_2_ip6(&pcb->local_ip)); - } -#endif /* LWIP_IPV6 && LWIP_IPV6_SCOPES */ - - pcb->remote_port = port; - pcb->flags |= UDP_FLAGS_CONNECTED; - - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("udp_connect: connected to ")); - ip_addr_debug_print_val(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, - pcb->remote_ip); - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, (", port %"U16_F")\n", pcb->remote_port)); - - /* Insert UDP PCB into the list of active UDP PCBs. */ - for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) { - if (pcb == ipcb) { - /* already on the list, just return */ - return ERR_OK; - } - } - /* PCB not yet on the list, add PCB now */ - pcb->next = udp_pcbs; - udp_pcbs = pcb; - return ERR_OK; -} - -/** - * @ingroup udp_raw - * Remove the remote end of the pcb. This function does not generate - * any network traffic, but only removes the remote address of the pcb. - * - * @param pcb the udp pcb to disconnect. - */ -void -udp_disconnect(struct udp_pcb *pcb) -{ - LWIP_ASSERT_CORE_LOCKED(); - - LWIP_ERROR("udp_disconnect: invalid pcb", pcb != NULL, return); - - /* reset remote address association */ -#if LWIP_IPV4 && LWIP_IPV6 - if (IP_IS_ANY_TYPE_VAL(pcb->local_ip)) { - ip_addr_copy(pcb->remote_ip, *IP_ANY_TYPE); - } else { -#endif - ip_addr_set_any(IP_IS_V6_VAL(pcb->remote_ip), &pcb->remote_ip); -#if LWIP_IPV4 && LWIP_IPV6 - } -#endif - pcb->remote_port = 0; - pcb->netif_idx = NETIF_NO_INDEX; - /* mark PCB as unconnected */ - udp_clear_flags(pcb, UDP_FLAGS_CONNECTED); -} - -/** - * @ingroup udp_raw - * Set a receive callback for a UDP PCB. - * This callback will be called when receiving a datagram for the pcb. - * - * @param pcb the pcb for which to set the recv callback - * @param recv function pointer of the callback function - * @param recv_arg additional argument to pass to the callback function - */ -void -udp_recv(struct udp_pcb *pcb, udp_recv_fn recv, void *recv_arg) -{ - LWIP_ASSERT_CORE_LOCKED(); - - LWIP_ERROR("udp_recv: invalid pcb", pcb != NULL, return); - - /* remember recv() callback and user data */ - pcb->recv = recv; - pcb->recv_arg = recv_arg; -} - -/** - * @ingroup udp_raw - * Removes and deallocates the pcb. - * - * @param pcb UDP PCB to be removed. The PCB is removed from the list of - * UDP PCB's and the data structure is freed from memory. - * - * @see udp_new() - */ -void -udp_remove(struct udp_pcb *pcb) -{ - struct udp_pcb *pcb2; - - LWIP_ASSERT_CORE_LOCKED(); - - LWIP_ERROR("udp_remove: invalid pcb", pcb != NULL, return); - - mib2_udp_unbind(pcb); - /* pcb to be removed is first in list? */ - if (udp_pcbs == pcb) { - /* make list start at 2nd pcb */ - udp_pcbs = udp_pcbs->next; - /* pcb not 1st in list */ - } else { - for (pcb2 = udp_pcbs; pcb2 != NULL; pcb2 = pcb2->next) { - /* find pcb in udp_pcbs list */ - if (pcb2->next != NULL && pcb2->next == pcb) { - /* remove pcb from list */ - pcb2->next = pcb->next; - break; - } - } - } - memp_free(MEMP_UDP_PCB, pcb); -} - -/** - * @ingroup udp_raw - * Creates a new UDP pcb which can be used for UDP communication. The - * pcb is not active until it has either been bound to a local address - * or connected to a remote address. - * - * @return The UDP PCB which was created. NULL if the PCB data structure - * could not be allocated. - * - * @see udp_remove() - */ -struct udp_pcb * -udp_new(void) -{ - struct udp_pcb *pcb; - - LWIP_ASSERT_CORE_LOCKED(); - - pcb = (struct udp_pcb *)memp_malloc(MEMP_UDP_PCB); - /* could allocate UDP PCB? */ - if (pcb != NULL) { - /* UDP Lite: by initializing to all zeroes, chksum_len is set to 0 - * which means checksum is generated over the whole datagram per default - * (recommended as default by RFC 3828). */ - /* initialize PCB to all zeroes */ - memset(pcb, 0, sizeof(struct udp_pcb)); - pcb->ttl = UDP_TTL; -#if LWIP_MULTICAST_TX_OPTIONS - udp_set_multicast_ttl(pcb, UDP_TTL); -#endif /* LWIP_MULTICAST_TX_OPTIONS */ - } - return pcb; -} - -/** - * @ingroup udp_raw - * Create a UDP PCB for specific IP type. - * The pcb is not active until it has either been bound to a local address - * or connected to a remote address. - * - * @param type IP address type, see @ref lwip_ip_addr_type definitions. - * If you want to listen to IPv4 and IPv6 (dual-stack) packets, - * supply @ref IPADDR_TYPE_ANY as argument and bind to @ref IP_ANY_TYPE. - * @return The UDP PCB which was created. NULL if the PCB data structure - * could not be allocated. - * - * @see udp_remove() - */ -struct udp_pcb * -udp_new_ip_type(u8_t type) -{ - struct udp_pcb *pcb; - - LWIP_ASSERT_CORE_LOCKED(); - - pcb = udp_new(); -#if LWIP_IPV4 && LWIP_IPV6 - if (pcb != NULL) { - IP_SET_TYPE_VAL(pcb->local_ip, type); - IP_SET_TYPE_VAL(pcb->remote_ip, type); - } -#else - LWIP_UNUSED_ARG(type); -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - return pcb; -} - -/** This function is called from netif.c when address is changed - * - * @param old_addr IP address of the netif before change - * @param new_addr IP address of the netif after change - */ -void udp_netif_ip_addr_changed(const ip_addr_t *old_addr, const ip_addr_t *new_addr) -{ - struct udp_pcb *upcb; - - if (!ip_addr_isany(old_addr) && !ip_addr_isany(new_addr)) { - for (upcb = udp_pcbs; upcb != NULL; upcb = upcb->next) { - /* PCB bound to current local interface address? */ - if (ip_addr_cmp(&upcb->local_ip, old_addr)) { - /* The PCB is bound to the old ipaddr and - * is set to bound to the new one instead */ - ip_addr_copy(upcb->local_ip, *new_addr); - } - } - } -} - -#if UDP_DEBUG -/** - * Print UDP header information for debug purposes. - * - * @param udphdr pointer to the udp header in memory. - */ -void -udp_debug_print(struct udp_hdr *udphdr) -{ - LWIP_DEBUGF(UDP_DEBUG, ("UDP header:\n")); - LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(UDP_DEBUG, ("| %5"U16_F" | %5"U16_F" | (src port, dest port)\n", - lwip_ntohs(udphdr->src), lwip_ntohs(udphdr->dest))); - LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(UDP_DEBUG, ("| %5"U16_F" | 0x%04"X16_F" | (len, chksum)\n", - lwip_ntohs(udphdr->len), lwip_ntohs(udphdr->chksum))); - LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n")); -} -#endif /* UDP_DEBUG */ - -#endif /* LWIP_UDP */ diff --git a/third-party/lwip-2.1.2/include/compat/posix/arpa/inet.h b/third-party/lwip-2.1.2/include/compat/posix/arpa/inet.h deleted file mode 100644 index 0ed9baf3..00000000 --- a/third-party/lwip-2.1.2/include/compat/posix/arpa/inet.h +++ /dev/null @@ -1,33 +0,0 @@ -/** - * @file - * This file is a posix wrapper for lwip/sockets.h. - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#include "lwip/sockets.h" diff --git a/third-party/lwip-2.1.2/include/compat/posix/net/if.h b/third-party/lwip-2.1.2/include/compat/posix/net/if.h deleted file mode 100644 index 6b8e63a5..00000000 --- a/third-party/lwip-2.1.2/include/compat/posix/net/if.h +++ /dev/null @@ -1,36 +0,0 @@ -/** - * @file - * This file is a posix wrapper for lwip/if_api.h. - */ - -/* - * Copyright (c) 2017 Joel Cunningham, Garmin International, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#include "lwip/if_api.h" diff --git a/third-party/lwip-2.1.2/include/compat/posix/netdb.h b/third-party/lwip-2.1.2/include/compat/posix/netdb.h deleted file mode 100644 index 12d4c7f5..00000000 --- a/third-party/lwip-2.1.2/include/compat/posix/netdb.h +++ /dev/null @@ -1,33 +0,0 @@ -/** - * @file - * This file is a posix wrapper for lwip/netdb.h. - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#include "lwip/netdb.h" diff --git a/third-party/lwip-2.1.2/include/compat/posix/sys/socket.h b/third-party/lwip-2.1.2/include/compat/posix/sys/socket.h deleted file mode 100644 index 0ed9baf3..00000000 --- a/third-party/lwip-2.1.2/include/compat/posix/sys/socket.h +++ /dev/null @@ -1,33 +0,0 @@ -/** - * @file - * This file is a posix wrapper for lwip/sockets.h. - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#include "lwip/sockets.h" diff --git a/third-party/lwip-2.1.2/include/compat/stdc/errno.h b/third-party/lwip-2.1.2/include/compat/stdc/errno.h deleted file mode 100644 index 98a9aec9..00000000 --- a/third-party/lwip-2.1.2/include/compat/stdc/errno.h +++ /dev/null @@ -1,33 +0,0 @@ -/** - * @file - * This file is a posix/stdc wrapper for lwip/errno.h. - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#include "lwip/errno.h" diff --git a/third-party/lwip-2.1.2/include/lwip/altcp.h b/third-party/lwip-2.1.2/include/lwip/altcp.h deleted file mode 100644 index 97abc54d..00000000 --- a/third-party/lwip-2.1.2/include/lwip/altcp.h +++ /dev/null @@ -1,201 +0,0 @@ -/** - * @file - * Application layered TCP connection API (to be used from TCPIP thread)\n - * - * This file contains the generic API. - * For more details see @ref altcp_api. - */ - -/* - * Copyright (c) 2017 Simon Goldschmidt - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Simon Goldschmidt - * - */ -#ifndef LWIP_HDR_ALTCP_H -#define LWIP_HDR_ALTCP_H - -#include "lwip/opt.h" - -#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/tcpbase.h" -#include "lwip/err.h" -#include "lwip/pbuf.h" -#include "lwip/ip_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct altcp_pcb; -struct altcp_functions; - -typedef err_t (*altcp_accept_fn)(void *arg, struct altcp_pcb *new_conn, err_t err); -typedef err_t (*altcp_connected_fn)(void *arg, struct altcp_pcb *conn, err_t err); -typedef err_t (*altcp_recv_fn)(void *arg, struct altcp_pcb *conn, struct pbuf *p, err_t err); -typedef err_t (*altcp_sent_fn)(void *arg, struct altcp_pcb *conn, u16_t len); -typedef err_t (*altcp_poll_fn)(void *arg, struct altcp_pcb *conn); -typedef void (*altcp_err_fn)(void *arg, err_t err); - -typedef struct altcp_pcb* (*altcp_new_fn)(void *arg, u8_t ip_type); - -struct altcp_pcb { - const struct altcp_functions *fns; - struct altcp_pcb *inner_conn; - void *arg; - void *state; - /* application callbacks */ - altcp_accept_fn accept; - altcp_connected_fn connected; - altcp_recv_fn recv; - altcp_sent_fn sent; - altcp_poll_fn poll; - altcp_err_fn err; - u8_t pollinterval; -}; - -/** @ingroup altcp */ -typedef struct altcp_allocator_s { - /** Allocator function */ - altcp_new_fn alloc; - /** Argument to allocator function */ - void *arg; -} altcp_allocator_t; - -struct altcp_pcb *altcp_new(altcp_allocator_t *allocator); -struct altcp_pcb *altcp_new_ip6(altcp_allocator_t *allocator); -struct altcp_pcb *altcp_new_ip_type(altcp_allocator_t *allocator, u8_t ip_type); - -void altcp_arg(struct altcp_pcb *conn, void *arg); -void altcp_accept(struct altcp_pcb *conn, altcp_accept_fn accept); -void altcp_recv(struct altcp_pcb *conn, altcp_recv_fn recv); -void altcp_sent(struct altcp_pcb *conn, altcp_sent_fn sent); -void altcp_poll(struct altcp_pcb *conn, altcp_poll_fn poll, u8_t interval); -void altcp_err(struct altcp_pcb *conn, altcp_err_fn err); - -void altcp_recved(struct altcp_pcb *conn, u16_t len); -err_t altcp_bind(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port); -err_t altcp_connect(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port, altcp_connected_fn connected); - -/* return conn for source code compatibility to tcp callback API only */ -struct altcp_pcb *altcp_listen_with_backlog_and_err(struct altcp_pcb *conn, u8_t backlog, err_t *err); -#define altcp_listen_with_backlog(conn, backlog) altcp_listen_with_backlog_and_err(conn, backlog, NULL) -/** @ingroup altcp */ -#define altcp_listen(conn) altcp_listen_with_backlog_and_err(conn, TCP_DEFAULT_LISTEN_BACKLOG, NULL) - -void altcp_abort(struct altcp_pcb *conn); -err_t altcp_close(struct altcp_pcb *conn); -err_t altcp_shutdown(struct altcp_pcb *conn, int shut_rx, int shut_tx); - -err_t altcp_write(struct altcp_pcb *conn, const void *dataptr, u16_t len, u8_t apiflags); -err_t altcp_output(struct altcp_pcb *conn); - -u16_t altcp_mss(struct altcp_pcb *conn); -u16_t altcp_sndbuf(struct altcp_pcb *conn); -u16_t altcp_sndqueuelen(struct altcp_pcb *conn); -void altcp_nagle_disable(struct altcp_pcb *conn); -void altcp_nagle_enable(struct altcp_pcb *conn); -int altcp_nagle_disabled(struct altcp_pcb *conn); - -void altcp_setprio(struct altcp_pcb *conn, u8_t prio); - -err_t altcp_get_tcp_addrinfo(struct altcp_pcb *conn, int local, ip_addr_t *addr, u16_t *port); -ip_addr_t *altcp_get_ip(struct altcp_pcb *conn, int local); -u16_t altcp_get_port(struct altcp_pcb *conn, int local); - -#ifdef LWIP_DEBUG -enum tcp_state altcp_dbg_get_tcp_state(struct altcp_pcb *conn); -#endif - -#ifdef __cplusplus -} -#endif - -#else /* LWIP_ALTCP */ - -/* ALTCP disabled, define everything to link against tcp callback API (e.g. to get a small non-ssl httpd) */ - -#include "lwip/tcp.h" - -#define altcp_accept_fn tcp_accept_fn -#define altcp_connected_fn tcp_connected_fn -#define altcp_recv_fn tcp_recv_fn -#define altcp_sent_fn tcp_sent_fn -#define altcp_poll_fn tcp_poll_fn -#define altcp_err_fn tcp_err_fn - -#define altcp_pcb tcp_pcb -#define altcp_tcp_new_ip_type tcp_new_ip_type -#define altcp_tcp_new tcp_new -#define altcp_tcp_new_ip6 tcp_new_ip6 - -#define altcp_new(allocator) tcp_new() -#define altcp_new_ip6(allocator) tcp_new_ip6() -#define altcp_new_ip_type(allocator, ip_type) tcp_new_ip_type(ip_type) - -#define altcp_arg tcp_arg -#define altcp_accept tcp_accept -#define altcp_recv tcp_recv -#define altcp_sent tcp_sent -#define altcp_poll tcp_poll -#define altcp_err tcp_err - -#define altcp_recved tcp_recved -#define altcp_bind tcp_bind -#define altcp_connect tcp_connect - -#define altcp_listen_with_backlog_and_err tcp_listen_with_backlog_and_err -#define altcp_listen_with_backlog tcp_listen_with_backlog -#define altcp_listen tcp_listen - -#define altcp_abort tcp_abort -#define altcp_close tcp_close -#define altcp_shutdown tcp_shutdown - -#define altcp_write tcp_write -#define altcp_output tcp_output - -#define altcp_mss tcp_mss -#define altcp_sndbuf tcp_sndbuf -#define altcp_sndqueuelen tcp_sndqueuelen -#define altcp_nagle_disable tcp_nagle_disable -#define altcp_nagle_enable tcp_nagle_enable -#define altcp_nagle_disabled tcp_nagle_disabled -#define altcp_setprio tcp_setprio - -#define altcp_get_tcp_addrinfo tcp_get_tcp_addrinfo -#define altcp_get_ip(pcb, local) ((local) ? (&(pcb)->local_ip) : (&(pcb)->remote_ip)) - -#ifdef LWIP_DEBUG -#define altcp_dbg_get_tcp_state tcp_dbg_get_tcp_state -#endif - -#endif /* LWIP_ALTCP */ - -#endif /* LWIP_HDR_ALTCP_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/altcp_tcp.h b/third-party/lwip-2.1.2/include/lwip/altcp_tcp.h deleted file mode 100644 index dbde5846..00000000 --- a/third-party/lwip-2.1.2/include/lwip/altcp_tcp.h +++ /dev/null @@ -1,72 +0,0 @@ -/** - * @file - * Application layered TCP connection API (to be used from TCPIP thread)\n - * This interface mimics the tcp callback API to the application while preventing - * direct linking (much like virtual functions). - * This way, an application can make use of other application layer protocols - * on top of TCP without knowing the details (e.g. TLS, proxy connection). - * - * This file contains the base implementation calling into tcp. - */ - -/* - * Copyright (c) 2017 Simon Goldschmidt - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Simon Goldschmidt - * - */ -#ifndef LWIP_HDR_ALTCP_TCP_H -#define LWIP_HDR_ALTCP_TCP_H - -#include "lwip/opt.h" - -#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/altcp.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct altcp_pcb *altcp_tcp_new_ip_type(u8_t ip_type); - -#define altcp_tcp_new() altcp_tcp_new_ip_type(IPADDR_TYPE_V4) -#define altcp_tcp_new_ip6() altcp_tcp_new_ip_type(IPADDR_TYPE_V6) - -struct altcp_pcb *altcp_tcp_alloc(void *arg, u8_t ip_type); - -struct tcp_pcb; -struct altcp_pcb *altcp_tcp_wrap(struct tcp_pcb *tpcb); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_ALTCP */ - -#endif /* LWIP_HDR_ALTCP_TCP_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/altcp_tls.h b/third-party/lwip-2.1.2/include/lwip/altcp_tls.h deleted file mode 100644 index 7b17c608..00000000 --- a/third-party/lwip-2.1.2/include/lwip/altcp_tls.h +++ /dev/null @@ -1,117 +0,0 @@ -/** - * @file - * Application layered TCP/TLS connection API (to be used from TCPIP thread) - * - * @defgroup altcp_tls TLS layer - * @ingroup altcp - * This file contains function prototypes for a TLS layer. - * A port to ARM mbedtls is provided in the apps/ tree - * (LWIP_ALTCP_TLS_MBEDTLS option). - */ - -/* - * Copyright (c) 2017 Simon Goldschmidt - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Simon Goldschmidt - * - */ -#ifndef LWIP_HDR_ALTCP_TLS_H -#define LWIP_HDR_ALTCP_TLS_H - -#include "lwip/opt.h" - -#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */ - -#if LWIP_ALTCP_TLS - -#include "lwip/altcp.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** @ingroup altcp_tls - * ALTCP_TLS configuration handle, content depends on port (e.g. mbedtls) - */ -struct altcp_tls_config; - -/** @ingroup altcp_tls - * Create an ALTCP_TLS server configuration handle - */ -struct altcp_tls_config *altcp_tls_create_config_server_privkey_cert(const u8_t *privkey, size_t privkey_len, - const u8_t *privkey_pass, size_t privkey_pass_len, - const u8_t *cert, size_t cert_len); - -/** @ingroup altcp_tls - * Create an ALTCP_TLS client configuration handle - */ -struct altcp_tls_config *altcp_tls_create_config_client(const u8_t *cert, size_t cert_len); - -/** @ingroup altcp_tls - * Create an ALTCP_TLS client configuration handle with two-way server/client authentication - */ -struct altcp_tls_config *altcp_tls_create_config_client_2wayauth(const u8_t *ca, size_t ca_len, const u8_t *privkey, size_t privkey_len, - const u8_t *privkey_pass, size_t privkey_pass_len, - const u8_t *cert, size_t cert_len); - -/** @ingroup altcp_tls - * Free an ALTCP_TLS configuration handle - */ -void altcp_tls_free_config(struct altcp_tls_config *conf); - -/** @ingroup altcp_tls - * Create new ALTCP_TLS layer wrapping an existing pcb as inner connection (e.g. TLS over TCP) - */ -struct altcp_pcb *altcp_tls_wrap(struct altcp_tls_config *config, struct altcp_pcb *inner_pcb); - -/** @ingroup altcp_tls - * Create new ALTCP_TLS pcb and its inner tcp pcb - */ -struct altcp_pcb *altcp_tls_new(struct altcp_tls_config *config, u8_t ip_type); - -/** @ingroup altcp_tls - * Create new ALTCP_TLS layer pcb and its inner tcp pcb. - * Same as @ref altcp_tls_new but this allocator function fits to - * @ref altcp_allocator_t / @ref altcp_new.\n - 'arg' must contain a struct altcp_tls_config *. - */ -struct altcp_pcb *altcp_tls_alloc(void *arg, u8_t ip_type); - -/** @ingroup altcp_tls - * Return pointer to internal TLS context so application can tweak it. - * Real type depends on port (e.g. mbedtls) - */ -void *altcp_tls_context(struct altcp_pcb *conn); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_ALTCP_TLS */ -#endif /* LWIP_ALTCP */ -#endif /* LWIP_HDR_ALTCP_TLS_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/api.h b/third-party/lwip-2.1.2/include/lwip/api.h deleted file mode 100644 index c2afaf26..00000000 --- a/third-party/lwip-2.1.2/include/lwip/api.h +++ /dev/null @@ -1,431 +0,0 @@ -/** - * @file - * netconn API (to be used from non-TCPIP threads) - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_API_H -#define LWIP_HDR_API_H - -#include "lwip/opt.h" - -#if LWIP_NETCONN || LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ -/* Note: Netconn API is always available when sockets are enabled - - * sockets are implemented on top of them */ - -#include "lwip/arch.h" -#include "lwip/netbuf.h" -#include "lwip/sys.h" -#include "lwip/ip_addr.h" -#include "lwip/err.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Throughout this file, IP addresses and port numbers are expected to be in - * the same byte order as in the corresponding pcb. - */ - -/* Flags for netconn_write (u8_t) */ -#define NETCONN_NOFLAG 0x00 -#define NETCONN_NOCOPY 0x00 /* Only for source code compatibility */ -#define NETCONN_COPY 0x01 -#define NETCONN_MORE 0x02 -#define NETCONN_DONTBLOCK 0x04 -#define NETCONN_NOAUTORCVD 0x08 /* prevent netconn_recv_data_tcp() from updating the tcp window - must be done manually via netconn_tcp_recvd() */ -#define NETCONN_NOFIN 0x10 /* upper layer already received data, leave FIN in queue until called again */ - -/* Flags for struct netconn.flags (u8_t) */ -/** This netconn had an error, don't block on recvmbox/acceptmbox any more */ -#define NETCONN_FLAG_MBOXCLOSED 0x01 -/** Should this netconn avoid blocking? */ -#define NETCONN_FLAG_NON_BLOCKING 0x02 -/** Was the last connect action a non-blocking one? */ -#define NETCONN_FLAG_IN_NONBLOCKING_CONNECT 0x04 -#if LWIP_NETCONN_FULLDUPLEX - /** The mbox of this netconn is being deallocated, don't use it anymore */ -#define NETCONN_FLAG_MBOXINVALID 0x08 -#endif /* LWIP_NETCONN_FULLDUPLEX */ -/** If a nonblocking write has been rejected before, poll_tcp needs to - check if the netconn is writable again */ -#define NETCONN_FLAG_CHECK_WRITESPACE 0x10 -#if LWIP_IPV6 -/** If this flag is set then only IPv6 communication is allowed on the - netconn. As per RFC#3493 this features defaults to OFF allowing - dual-stack usage by default. */ -#define NETCONN_FLAG_IPV6_V6ONLY 0x20 -#endif /* LWIP_IPV6 */ -#if LWIP_NETBUF_RECVINFO -/** Received packet info will be recorded for this netconn */ -#define NETCONN_FLAG_PKTINFO 0x40 -#endif /* LWIP_NETBUF_RECVINFO */ -/** A FIN has been received but not passed to the application yet */ -#define NETCONN_FIN_RX_PENDING 0x80 - -/* Helpers to process several netconn_types by the same code */ -#define NETCONNTYPE_GROUP(t) ((t)&0xF0) -#define NETCONNTYPE_DATAGRAM(t) ((t)&0xE0) -#if LWIP_IPV6 -#define NETCONN_TYPE_IPV6 0x08 -#define NETCONNTYPE_ISIPV6(t) (((t)&NETCONN_TYPE_IPV6) != 0) -#define NETCONNTYPE_ISUDPLITE(t) (((t)&0xF3) == NETCONN_UDPLITE) -#define NETCONNTYPE_ISUDPNOCHKSUM(t) (((t)&0xF3) == NETCONN_UDPNOCHKSUM) -#else /* LWIP_IPV6 */ -#define NETCONNTYPE_ISIPV6(t) (0) -#define NETCONNTYPE_ISUDPLITE(t) ((t) == NETCONN_UDPLITE) -#define NETCONNTYPE_ISUDPNOCHKSUM(t) ((t) == NETCONN_UDPNOCHKSUM) -#endif /* LWIP_IPV6 */ - -/** @ingroup netconn_common - * Protocol family and type of the netconn - */ -enum netconn_type { - NETCONN_INVALID = 0, - /** TCP IPv4 */ - NETCONN_TCP = 0x10, -#if LWIP_IPV6 - /** TCP IPv6 */ - NETCONN_TCP_IPV6 = NETCONN_TCP | NETCONN_TYPE_IPV6 /* 0x18 */, -#endif /* LWIP_IPV6 */ - /** UDP IPv4 */ - NETCONN_UDP = 0x20, - /** UDP IPv4 lite */ - NETCONN_UDPLITE = 0x21, - /** UDP IPv4 no checksum */ - NETCONN_UDPNOCHKSUM = 0x22, - -#if LWIP_IPV6 - /** UDP IPv6 (dual-stack by default, unless you call @ref netconn_set_ipv6only) */ - NETCONN_UDP_IPV6 = NETCONN_UDP | NETCONN_TYPE_IPV6 /* 0x28 */, - /** UDP IPv6 lite (dual-stack by default, unless you call @ref netconn_set_ipv6only) */ - NETCONN_UDPLITE_IPV6 = NETCONN_UDPLITE | NETCONN_TYPE_IPV6 /* 0x29 */, - /** UDP IPv6 no checksum (dual-stack by default, unless you call @ref netconn_set_ipv6only) */ - NETCONN_UDPNOCHKSUM_IPV6 = NETCONN_UDPNOCHKSUM | NETCONN_TYPE_IPV6 /* 0x2a */, -#endif /* LWIP_IPV6 */ - - /** Raw connection IPv4 */ - NETCONN_RAW = 0x40 -#if LWIP_IPV6 - /** Raw connection IPv6 (dual-stack by default, unless you call @ref netconn_set_ipv6only) */ - , NETCONN_RAW_IPV6 = NETCONN_RAW | NETCONN_TYPE_IPV6 /* 0x48 */ -#endif /* LWIP_IPV6 */ -}; - -/** Current state of the netconn. Non-TCP netconns are always - * in state NETCONN_NONE! */ -enum netconn_state { - NETCONN_NONE, - NETCONN_WRITE, - NETCONN_LISTEN, - NETCONN_CONNECT, - NETCONN_CLOSE -}; - -/** Used to inform the callback function about changes - * - * Event explanation: - * - * In the netconn implementation, there are three ways to block a client: - * - * - accept mbox (sys_arch_mbox_fetch(&conn->acceptmbox, &accept_ptr, 0); in netconn_accept()) - * - receive mbox (sys_arch_mbox_fetch(&conn->recvmbox, &buf, 0); in netconn_recv_data()) - * - send queue is full (sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 0); in lwip_netconn_do_write()) - * - * The events have to be seen as events signaling the state of these mboxes/semaphores. For non-blocking - * connections, you need to know in advance whether a call to a netconn function call would block or not, - * and these events tell you about that. - * - * RCVPLUS events say: Safe to perform a potentially blocking call call once more. - * They are counted in sockets - three RCVPLUS events for accept mbox means you are safe - * to call netconn_accept 3 times without being blocked. - * Same thing for receive mbox. - * - * RCVMINUS events say: Your call to to a possibly blocking function is "acknowledged". - * Socket implementation decrements the counter. - * - * For TX, there is no need to count, its merely a flag. SENDPLUS means you may send something. - * SENDPLUS occurs when enough data was delivered to peer so netconn_send() can be called again. - * A SENDMINUS event occurs when the next call to a netconn_send() would be blocking. - */ -enum netconn_evt { - NETCONN_EVT_RCVPLUS, - NETCONN_EVT_RCVMINUS, - NETCONN_EVT_SENDPLUS, - NETCONN_EVT_SENDMINUS, - NETCONN_EVT_ERROR -}; - -#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) -/** Used for netconn_join_leave_group() */ -enum netconn_igmp { - NETCONN_JOIN, - NETCONN_LEAVE -}; -#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ - -#if LWIP_DNS -/* Used for netconn_gethostbyname_addrtype(), these should match the DNS_ADDRTYPE defines in dns.h */ -#define NETCONN_DNS_DEFAULT NETCONN_DNS_IPV4_IPV6 -#define NETCONN_DNS_IPV4 0 -#define NETCONN_DNS_IPV6 1 -#define NETCONN_DNS_IPV4_IPV6 2 /* try to resolve IPv4 first, try IPv6 if IPv4 fails only */ -#define NETCONN_DNS_IPV6_IPV4 3 /* try to resolve IPv6 first, try IPv4 if IPv6 fails only */ -#endif /* LWIP_DNS */ - -/* forward-declare some structs to avoid to include their headers */ -struct ip_pcb; -struct tcp_pcb; -struct udp_pcb; -struct raw_pcb; -struct netconn; -struct api_msg; - -/** A callback prototype to inform about events for a netconn */ -typedef void (* netconn_callback)(struct netconn *, enum netconn_evt, u16_t len); - -/** A netconn descriptor */ -struct netconn { - /** type of the netconn (TCP, UDP or RAW) */ - enum netconn_type type; - /** current state of the netconn */ - enum netconn_state state; - /** the lwIP internal protocol control block */ - union { - struct ip_pcb *ip; - struct tcp_pcb *tcp; - struct udp_pcb *udp; - struct raw_pcb *raw; - } pcb; - /** the last asynchronous unreported error this netconn had */ - err_t pending_err; -#if !LWIP_NETCONN_SEM_PER_THREAD - /** sem that is used to synchronously execute functions in the core context */ - sys_sem_t op_completed; -#endif - /** mbox where received packets are stored until they are fetched - by the netconn application thread (can grow quite big) */ - sys_mbox_t recvmbox; -#if LWIP_TCP - /** mbox where new connections are stored until processed - by the application thread */ - sys_mbox_t acceptmbox; -#endif /* LWIP_TCP */ -#if LWIP_NETCONN_FULLDUPLEX - /** number of threads waiting on an mbox. This is required to unblock - all threads when closing while threads are waiting. */ - int mbox_threads_waiting; -#endif - /** only used for socket layer */ -#if LWIP_SOCKET - int socket; -#endif /* LWIP_SOCKET */ -#if LWIP_SO_SNDTIMEO - /** timeout to wait for sending data (which means enqueueing data for sending - in internal buffers) in milliseconds */ - s32_t send_timeout; -#endif /* LWIP_SO_RCVTIMEO */ -#if LWIP_SO_RCVTIMEO - /** timeout in milliseconds to wait for new data to be received - (or connections to arrive for listening netconns) */ - u32_t recv_timeout; -#endif /* LWIP_SO_RCVTIMEO */ -#if LWIP_SO_RCVBUF - /** maximum amount of bytes queued in recvmbox - not used for TCP: adjust TCP_WND instead! */ - int recv_bufsize; - /** number of bytes currently in recvmbox to be received, - tested against recv_bufsize to limit bytes on recvmbox - for UDP and RAW, used for FIONREAD */ - int recv_avail; -#endif /* LWIP_SO_RCVBUF */ -#if LWIP_SO_LINGER - /** values <0 mean linger is disabled, values > 0 are seconds to linger */ - s16_t linger; -#endif /* LWIP_SO_LINGER */ - /** flags holding more netconn-internal state, see NETCONN_FLAG_* defines */ - u8_t flags; -#if LWIP_TCP - /** TCP: when data passed to netconn_write doesn't fit into the send buffer, - this temporarily stores the message. - Also used during connect and close. */ - struct api_msg *current_msg; -#endif /* LWIP_TCP */ - /** A callback function that is informed about events for this netconn */ - netconn_callback callback; -}; - -/** This vector type is passed to @ref netconn_write_vectors_partly to send - * multiple buffers at once. - * ATTENTION: This type has to directly map struct iovec since one is casted - * into the other! - */ -struct netvector { - /** pointer to the application buffer that contains the data to send */ - const void *ptr; - /** size of the application data to send */ - size_t len; -}; - -/** Register an Network connection event */ -#define API_EVENT(c,e,l) if (c->callback) { \ - (*c->callback)(c, e, l); \ - } - -/* Network connection functions: */ - -/** @ingroup netconn_common - * Create new netconn connection - * @param t @ref netconn_type */ -#define netconn_new(t) netconn_new_with_proto_and_callback(t, 0, NULL) -#define netconn_new_with_callback(t, c) netconn_new_with_proto_and_callback(t, 0, c) -struct netconn *netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, - netconn_callback callback); -err_t netconn_prepare_delete(struct netconn *conn); -err_t netconn_delete(struct netconn *conn); -/** Get the type of a netconn (as enum netconn_type). */ -#define netconn_type(conn) (conn->type) - -err_t netconn_getaddr(struct netconn *conn, ip_addr_t *addr, - u16_t *port, u8_t local); -/** @ingroup netconn_common */ -#define netconn_peer(c,i,p) netconn_getaddr(c,i,p,0) -/** @ingroup netconn_common */ -#define netconn_addr(c,i,p) netconn_getaddr(c,i,p,1) - -err_t netconn_bind(struct netconn *conn, const ip_addr_t *addr, u16_t port); -err_t netconn_bind_if(struct netconn *conn, u8_t if_idx); -err_t netconn_connect(struct netconn *conn, const ip_addr_t *addr, u16_t port); -err_t netconn_disconnect (struct netconn *conn); -err_t netconn_listen_with_backlog(struct netconn *conn, u8_t backlog); -/** @ingroup netconn_tcp */ -#define netconn_listen(conn) netconn_listen_with_backlog(conn, TCP_DEFAULT_LISTEN_BACKLOG) -err_t netconn_accept(struct netconn *conn, struct netconn **new_conn); -err_t netconn_recv(struct netconn *conn, struct netbuf **new_buf); -err_t netconn_recv_udp_raw_netbuf(struct netconn *conn, struct netbuf **new_buf); -err_t netconn_recv_udp_raw_netbuf_flags(struct netconn *conn, struct netbuf **new_buf, u8_t apiflags); -err_t netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf); -err_t netconn_recv_tcp_pbuf_flags(struct netconn *conn, struct pbuf **new_buf, u8_t apiflags); -err_t netconn_tcp_recvd(struct netconn *conn, size_t len); -err_t netconn_sendto(struct netconn *conn, struct netbuf *buf, - const ip_addr_t *addr, u16_t port); -err_t netconn_send(struct netconn *conn, struct netbuf *buf); -err_t netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size, - u8_t apiflags, size_t *bytes_written); -err_t netconn_write_vectors_partly(struct netconn *conn, struct netvector *vectors, u16_t vectorcnt, - u8_t apiflags, size_t *bytes_written); -/** @ingroup netconn_tcp */ -#define netconn_write(conn, dataptr, size, apiflags) \ - netconn_write_partly(conn, dataptr, size, apiflags, NULL) -err_t netconn_close(struct netconn *conn); -err_t netconn_shutdown(struct netconn *conn, u8_t shut_rx, u8_t shut_tx); - -#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) -err_t netconn_join_leave_group(struct netconn *conn, const ip_addr_t *multiaddr, - const ip_addr_t *netif_addr, enum netconn_igmp join_or_leave); -err_t netconn_join_leave_group_netif(struct netconn *conn, const ip_addr_t *multiaddr, - u8_t if_idx, enum netconn_igmp join_or_leave); -#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ -#if LWIP_DNS -#if LWIP_IPV4 && LWIP_IPV6 -err_t netconn_gethostbyname_addrtype(const char *name, ip_addr_t *addr, u8_t dns_addrtype); -#define netconn_gethostbyname(name, addr) netconn_gethostbyname_addrtype(name, addr, NETCONN_DNS_DEFAULT) -#else /* LWIP_IPV4 && LWIP_IPV6 */ -err_t netconn_gethostbyname(const char *name, ip_addr_t *addr); -#define netconn_gethostbyname_addrtype(name, addr, dns_addrtype) netconn_gethostbyname(name, addr) -#endif /* LWIP_IPV4 && LWIP_IPV6 */ -#endif /* LWIP_DNS */ - -err_t netconn_err(struct netconn *conn); -#define netconn_recv_bufsize(conn) ((conn)->recv_bufsize) - -#define netconn_set_flags(conn, set_flags) do { (conn)->flags = (u8_t)((conn)->flags | (set_flags)); } while(0) -#define netconn_clear_flags(conn, clr_flags) do { (conn)->flags = (u8_t)((conn)->flags & (u8_t)(~(clr_flags) & 0xff)); } while(0) -#define netconn_is_flag_set(conn, flag) (((conn)->flags & (flag)) != 0) - -/** Set the blocking status of netconn calls (@todo: write/send is missing) */ -#define netconn_set_nonblocking(conn, val) do { if(val) { \ - netconn_set_flags(conn, NETCONN_FLAG_NON_BLOCKING); \ -} else { \ - netconn_clear_flags(conn, NETCONN_FLAG_NON_BLOCKING); }} while(0) -/** Get the blocking status of netconn calls (@todo: write/send is missing) */ -#define netconn_is_nonblocking(conn) (((conn)->flags & NETCONN_FLAG_NON_BLOCKING) != 0) - -#if LWIP_IPV6 -/** @ingroup netconn_common - * TCP: Set the IPv6 ONLY status of netconn calls (see NETCONN_FLAG_IPV6_V6ONLY) - */ -#define netconn_set_ipv6only(conn, val) do { if(val) { \ - netconn_set_flags(conn, NETCONN_FLAG_IPV6_V6ONLY); \ -} else { \ - netconn_clear_flags(conn, NETCONN_FLAG_IPV6_V6ONLY); }} while(0) -/** @ingroup netconn_common - * TCP: Get the IPv6 ONLY status of netconn calls (see NETCONN_FLAG_IPV6_V6ONLY) - */ -#define netconn_get_ipv6only(conn) (((conn)->flags & NETCONN_FLAG_IPV6_V6ONLY) != 0) -#endif /* LWIP_IPV6 */ - -#if LWIP_SO_SNDTIMEO -/** Set the send timeout in milliseconds */ -#define netconn_set_sendtimeout(conn, timeout) ((conn)->send_timeout = (timeout)) -/** Get the send timeout in milliseconds */ -#define netconn_get_sendtimeout(conn) ((conn)->send_timeout) -#endif /* LWIP_SO_SNDTIMEO */ -#if LWIP_SO_RCVTIMEO -/** Set the receive timeout in milliseconds */ -#define netconn_set_recvtimeout(conn, timeout) ((conn)->recv_timeout = (timeout)) -/** Get the receive timeout in milliseconds */ -#define netconn_get_recvtimeout(conn) ((conn)->recv_timeout) -#endif /* LWIP_SO_RCVTIMEO */ -#if LWIP_SO_RCVBUF -/** Set the receive buffer in bytes */ -#define netconn_set_recvbufsize(conn, recvbufsize) ((conn)->recv_bufsize = (recvbufsize)) -/** Get the receive buffer in bytes */ -#define netconn_get_recvbufsize(conn) ((conn)->recv_bufsize) -#endif /* LWIP_SO_RCVBUF*/ - -#if LWIP_NETCONN_SEM_PER_THREAD -void netconn_thread_init(void); -void netconn_thread_cleanup(void); -#else /* LWIP_NETCONN_SEM_PER_THREAD */ -#define netconn_thread_init() -#define netconn_thread_cleanup() -#endif /* LWIP_NETCONN_SEM_PER_THREAD */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_NETCONN || LWIP_SOCKET */ - -#endif /* LWIP_HDR_API_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/arch.h b/third-party/lwip-2.1.2/include/lwip/arch.h deleted file mode 100644 index 55bd8444..00000000 --- a/third-party/lwip-2.1.2/include/lwip/arch.h +++ /dev/null @@ -1,395 +0,0 @@ -/** - * @file - * Support for different processor and compiler architectures - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_ARCH_H -#define LWIP_HDR_ARCH_H - -#ifndef LITTLE_ENDIAN -#define LITTLE_ENDIAN 1234 -#endif - -#ifndef BIG_ENDIAN -#define BIG_ENDIAN 4321 -#endif - -#include "arch/cc.h" - -/** - * @defgroup compiler_abstraction Compiler/platform abstraction - * @ingroup sys_layer - * All defines related to this section must not be placed in lwipopts.h, - * but in arch/cc.h! - * If the compiler does not provide memset() this file must include a - * definition of it, or include a file which defines it. - * These options cannot be \#defined in lwipopts.h since they are not options - * of lwIP itself, but options of the lwIP port to your system. - * @{ - */ - -/** Define the byte order of the system. - * Needed for conversion of network data to host byte order. - * Allowed values: LITTLE_ENDIAN and BIG_ENDIAN - */ -#ifndef BYTE_ORDER -#define BYTE_ORDER LITTLE_ENDIAN -#endif - -/** Define random number generator function of your system */ -#ifdef __DOXYGEN__ -#define LWIP_RAND() ((u32_t)rand()) -#endif - -/** Platform specific diagnostic output.\n - * Note the default implementation pulls in printf, which may - * in turn pull in a lot of standard libary code. In resource-constrained - * systems, this should be defined to something less resource-consuming. - */ -#ifndef LWIP_PLATFORM_DIAG -#define LWIP_PLATFORM_DIAG(x) do {printf x;} while(0) -#include -#include -#endif - -/** Platform specific assertion handling.\n - * Note the default implementation pulls in printf, fflush and abort, which may - * in turn pull in a lot of standard libary code. In resource-constrained - * systems, this should be defined to something less resource-consuming. - */ -#ifndef LWIP_PLATFORM_ASSERT -#define LWIP_PLATFORM_ASSERT(x) do {printf("Assertion \"%s\" failed at line %d in %s\n", \ - x, __LINE__, __FILE__); fflush(NULL); abort();} while(0) -#include -#include -#endif - -/** Define this to 1 in arch/cc.h of your port if you do not want to - * include stddef.h header to get size_t. You need to typedef size_t - * by yourself in this case. - */ -#ifndef LWIP_NO_STDDEF_H -#define LWIP_NO_STDDEF_H 0 -#endif - -#if !LWIP_NO_STDDEF_H -#include /* for size_t */ -#endif - -/** Define this to 1 in arch/cc.h of your port if your compiler does not provide - * the stdint.h header. You need to typedef the generic types listed in - * lwip/arch.h yourself in this case (u8_t, u16_t...). - */ -#ifndef LWIP_NO_STDINT_H -#define LWIP_NO_STDINT_H 0 -#endif - -/* Define generic types used in lwIP */ -#if !LWIP_NO_STDINT_H -#include -/* stdint.h is C99 which should also provide support for 64-bit integers */ -#if !defined(LWIP_HAVE_INT64) && defined(UINT64_MAX) -#define LWIP_HAVE_INT64 1 -#endif -typedef uint8_t u8_t; -typedef int8_t s8_t; -typedef uint16_t u16_t; -typedef int16_t s16_t; -typedef uint32_t u32_t; -typedef int32_t s32_t; -#if LWIP_HAVE_INT64 -typedef uint64_t u64_t; -typedef int64_t s64_t; -#endif -typedef uintptr_t mem_ptr_t; -#endif - -/** Define this to 1 in arch/cc.h of your port if your compiler does not provide - * the inttypes.h header. You need to define the format strings listed in - * lwip/arch.h yourself in this case (X8_F, U16_F...). - */ -#ifndef LWIP_NO_INTTYPES_H -#define LWIP_NO_INTTYPES_H 0 -#endif - -/* Define (sn)printf formatters for these lwIP types */ -#if !LWIP_NO_INTTYPES_H -#include -#ifndef X8_F -#define X8_F "02" PRIx8 -#endif -#ifndef U16_F -#define U16_F PRIu16 -#endif -#ifndef S16_F -#define S16_F PRId16 -#endif -#ifndef X16_F -#define X16_F PRIx16 -#endif -#ifndef U32_F -#define U32_F PRIu32 -#endif -#ifndef S32_F -#define S32_F PRId32 -#endif -#ifndef X32_F -#define X32_F PRIx32 -#endif -#ifndef SZT_F -#define SZT_F PRIuPTR -#endif -#endif - -/** Define this to 1 in arch/cc.h of your port if your compiler does not provide - * the limits.h header. You need to define the type limits yourself in this case - * (e.g. INT_MAX, SSIZE_MAX). - */ -#ifndef LWIP_NO_LIMITS_H -#define LWIP_NO_LIMITS_H 0 -#endif - -/* Include limits.h? */ -#if !LWIP_NO_LIMITS_H -#include -#endif - -/* Do we need to define ssize_t? This is a compatibility hack: - * Unfortunately, this type seems to be unavailable on some systems (even if - * sys/types or unistd.h are available). - * Being like that, we define it to 'int' if SSIZE_MAX is not defined. - */ -#ifdef SSIZE_MAX -/* If SSIZE_MAX is defined, unistd.h should provide the type as well */ -#ifndef LWIP_NO_UNISTD_H -#define LWIP_NO_UNISTD_H 0 -#endif -#if !LWIP_NO_UNISTD_H -#include -#endif -#else /* SSIZE_MAX */ -#ifndef __aarch64__ -typedef int ssize_t; /* aarch64 already define this type */ -#endif -#define SSIZE_MAX INT_MAX -#endif /* SSIZE_MAX */ - -/* some maximum values needed in lwip code */ -#define LWIP_UINT32_MAX 0xffffffff - -/** Define this to 1 in arch/cc.h of your port if your compiler does not provide - * the ctype.h header. If ctype.h is available, a few character functions - * are mapped to the appropriate functions (lwip_islower, lwip_isdigit...), if - * not, a private implementation is provided. - */ -#ifndef LWIP_NO_CTYPE_H -#define LWIP_NO_CTYPE_H 0 -#endif - -#if LWIP_NO_CTYPE_H -#define lwip_in_range(c, lo, up) ((u8_t)(c) >= (lo) && (u8_t)(c) <= (up)) -#define lwip_isdigit(c) lwip_in_range((c), '0', '9') -#define lwip_isxdigit(c) (lwip_isdigit(c) || lwip_in_range((c), 'a', 'f') || lwip_in_range((c), 'A', 'F')) -#define lwip_islower(c) lwip_in_range((c), 'a', 'z') -#define lwip_isspace(c) ((c) == ' ' || (c) == '\f' || (c) == '\n' || (c) == '\r' || (c) == '\t' || (c) == '\v') -#define lwip_isupper(c) lwip_in_range((c), 'A', 'Z') -#define lwip_tolower(c) (lwip_isupper(c) ? (c) - 'A' + 'a' : c) -#define lwip_toupper(c) (lwip_islower(c) ? (c) - 'a' + 'A' : c) -#else -#include -#define lwip_isdigit(c) isdigit((unsigned char)(c)) -#define lwip_isxdigit(c) isxdigit((unsigned char)(c)) -#define lwip_islower(c) islower((unsigned char)(c)) -#define lwip_isspace(c) isspace((unsigned char)(c)) -#define lwip_isupper(c) isupper((unsigned char)(c)) -#define lwip_tolower(c) tolower((unsigned char)(c)) -#define lwip_toupper(c) toupper((unsigned char)(c)) -#endif - -/** C++ const_cast(val) equivalent to remove constness from a value (GCC -Wcast-qual) */ -#ifndef LWIP_CONST_CAST -#define LWIP_CONST_CAST(target_type, val) ((target_type)((ptrdiff_t)val)) -#endif - -/** Get rid of alignment cast warnings (GCC -Wcast-align) */ -#ifndef LWIP_ALIGNMENT_CAST -#define LWIP_ALIGNMENT_CAST(target_type, val) LWIP_CONST_CAST(target_type, val) -#endif - -/** Get rid of warnings related to pointer-to-numeric and vice-versa casts, - * e.g. "conversion from 'u8_t' to 'void *' of greater size" - */ -#ifndef LWIP_PTR_NUMERIC_CAST -#define LWIP_PTR_NUMERIC_CAST(target_type, val) LWIP_CONST_CAST(target_type, val) -#endif - -/** Avoid warnings/errors related to implicitly casting away packed attributes by doing a explicit cast */ -#ifndef LWIP_PACKED_CAST -#define LWIP_PACKED_CAST(target_type, val) LWIP_CONST_CAST(target_type, val) -#endif - -/** Allocates a memory buffer of specified size that is of sufficient size to align - * its start address using LWIP_MEM_ALIGN. - * You can declare your own version here e.g. to enforce alignment without adding - * trailing padding bytes (see LWIP_MEM_ALIGN_BUFFER) or your own section placement - * requirements.\n - * e.g. if you use gcc and need 32 bit alignment:\n - * \#define LWIP_DECLARE_MEMORY_ALIGNED(variable_name, size) u8_t variable_name[size] \_\_attribute\_\_((aligned(4)))\n - * or more portable:\n - * \#define LWIP_DECLARE_MEMORY_ALIGNED(variable_name, size) u32_t variable_name[(size + sizeof(u32_t) - 1) / sizeof(u32_t)] - */ -#ifndef LWIP_DECLARE_MEMORY_ALIGNED -#define LWIP_DECLARE_MEMORY_ALIGNED(variable_name, size) u8_t variable_name[LWIP_MEM_ALIGN_BUFFER(size)] -#endif - -/** Calculate memory size for an aligned buffer - returns the next highest - * multiple of MEM_ALIGNMENT (e.g. LWIP_MEM_ALIGN_SIZE(3) and - * LWIP_MEM_ALIGN_SIZE(4) will both yield 4 for MEM_ALIGNMENT == 4). - */ -#ifndef LWIP_MEM_ALIGN_SIZE -#define LWIP_MEM_ALIGN_SIZE(size) (((size) + MEM_ALIGNMENT - 1U) & ~(MEM_ALIGNMENT-1U)) -#endif - -/** Calculate safe memory size for an aligned buffer when using an unaligned - * type as storage. This includes a safety-margin on (MEM_ALIGNMENT - 1) at the - * start (e.g. if buffer is u8_t[] and actual data will be u32_t*) - */ -#ifndef LWIP_MEM_ALIGN_BUFFER -#define LWIP_MEM_ALIGN_BUFFER(size) (((size) + MEM_ALIGNMENT - 1U)) -#endif - -/** Align a memory pointer to the alignment defined by MEM_ALIGNMENT - * so that ADDR % MEM_ALIGNMENT == 0 - */ -#ifndef LWIP_MEM_ALIGN -#define LWIP_MEM_ALIGN(addr) ((void *)(((mem_ptr_t)(addr) + MEM_ALIGNMENT - 1) & ~(mem_ptr_t)(MEM_ALIGNMENT-1))) -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** Packed structs support. - * Placed BEFORE declaration of a packed struct.\n - * For examples of packed struct declarations, see include/lwip/prot/ subfolder.\n - * A port to GCC/clang is included in lwIP, if you use these compilers there is nothing to do here. - */ -#ifndef PACK_STRUCT_BEGIN -#define PACK_STRUCT_BEGIN -#endif /* PACK_STRUCT_BEGIN */ - -/** Packed structs support. - * Placed AFTER declaration of a packed struct.\n - * For examples of packed struct declarations, see include/lwip/prot/ subfolder.\n - * A port to GCC/clang is included in lwIP, if you use these compilers there is nothing to do here. - */ -#ifndef PACK_STRUCT_END -#define PACK_STRUCT_END -#endif /* PACK_STRUCT_END */ - -/** Packed structs support. - * Placed between end of declaration of a packed struct and trailing semicolon.\n - * For examples of packed struct declarations, see include/lwip/prot/ subfolder.\n - * A port to GCC/clang is included in lwIP, if you use these compilers there is nothing to do here. - */ -#ifndef PACK_STRUCT_STRUCT -#if defined(__GNUC__) || defined(__clang__) -#define PACK_STRUCT_STRUCT __attribute__((packed)) -#else -#define PACK_STRUCT_STRUCT -#endif -#endif /* PACK_STRUCT_STRUCT */ - -/** Packed structs support. - * Wraps u32_t and u16_t members.\n - * For examples of packed struct declarations, see include/lwip/prot/ subfolder.\n - * A port to GCC/clang is included in lwIP, if you use these compilers there is nothing to do here. - */ -#ifndef PACK_STRUCT_FIELD -#define PACK_STRUCT_FIELD(x) x -#endif /* PACK_STRUCT_FIELD */ - -/** Packed structs support. - * Wraps u8_t members, where some compilers warn that packing is not necessary.\n - * For examples of packed struct declarations, see include/lwip/prot/ subfolder.\n - * A port to GCC/clang is included in lwIP, if you use these compilers there is nothing to do here. - */ -#ifndef PACK_STRUCT_FLD_8 -#define PACK_STRUCT_FLD_8(x) PACK_STRUCT_FIELD(x) -#endif /* PACK_STRUCT_FLD_8 */ - -/** Packed structs support. - * Wraps members that are packed structs themselves, where some compilers warn that packing is not necessary.\n - * For examples of packed struct declarations, see include/lwip/prot/ subfolder.\n - * A port to GCC/clang is included in lwIP, if you use these compilers there is nothing to do here. - */ -#ifndef PACK_STRUCT_FLD_S -#define PACK_STRUCT_FLD_S(x) PACK_STRUCT_FIELD(x) -#endif /* PACK_STRUCT_FLD_S */ - -/** PACK_STRUCT_USE_INCLUDES==1: Packed structs support using \#include files before and after struct to be packed.\n - * The file included BEFORE the struct is "arch/bpstruct.h".\n - * The file included AFTER the struct is "arch/epstruct.h".\n - * This can be used to implement struct packing on MS Visual C compilers, see - * the Win32 port in the lwIP contrib repository for reference. - * For examples of packed struct declarations, see include/lwip/prot/ subfolder.\n - * A port to GCC/clang is included in lwIP, if you use these compilers there is nothing to do here. - */ -#ifdef __DOXYGEN__ -#define PACK_STRUCT_USE_INCLUDES -#endif - -/** Eliminates compiler warning about unused arguments (GCC -Wextra -Wunused). */ -#ifndef LWIP_UNUSED_ARG -#define LWIP_UNUSED_ARG(x) (void)x -#endif /* LWIP_UNUSED_ARG */ - -/** LWIP_PROVIDE_ERRNO==1: Let lwIP provide ERRNO values and the 'errno' variable. - * If this is disabled, cc.h must either define 'errno', include , - * define LWIP_ERRNO_STDINCLUDE to get included or - * define LWIP_ERRNO_INCLUDE to or equivalent. - */ -#if defined __DOXYGEN__ -#define LWIP_PROVIDE_ERRNO -#endif - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_ARCH_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/autoip.h b/third-party/lwip-2.1.2/include/lwip/autoip.h deleted file mode 100644 index 1d85bccf..00000000 --- a/third-party/lwip-2.1.2/include/lwip/autoip.h +++ /dev/null @@ -1,99 +0,0 @@ -/** - * @file - * - * AutoIP Automatic LinkLocal IP Configuration - */ - -/* - * - * Copyright (c) 2007 Dominik Spies - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Dominik Spies - * - * This is a AutoIP implementation for the lwIP TCP/IP stack. It aims to conform - * with RFC 3927. - * - */ - -#ifndef LWIP_HDR_AUTOIP_H -#define LWIP_HDR_AUTOIP_H - -#include "lwip/opt.h" - -#if LWIP_IPV4 && LWIP_AUTOIP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/netif.h" -/* #include "lwip/udp.h" */ -#include "lwip/etharp.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** AutoIP Timing */ -#define AUTOIP_TMR_INTERVAL 100 -#define AUTOIP_TICKS_PER_SECOND (1000 / AUTOIP_TMR_INTERVAL) - -/** AutoIP state information per netif */ -struct autoip -{ - /** the currently selected, probed, announced or used LL IP-Address */ - ip4_addr_t llipaddr; - /** current AutoIP state machine state */ - u8_t state; - /** sent number of probes or announces, dependent on state */ - u8_t sent_num; - /** ticks to wait, tick is AUTOIP_TMR_INTERVAL long */ - u16_t ttw; - /** ticks until a conflict can be solved by defending */ - u8_t lastconflict; - /** total number of probed/used Link Local IP-Addresses */ - u8_t tried_llipaddr; -}; - - -void autoip_set_struct(struct netif *netif, struct autoip *autoip); -/** Remove a struct autoip previously set to the netif using autoip_set_struct() */ -#define autoip_remove_struct(netif) do { (netif)->autoip = NULL; } while (0) -err_t autoip_start(struct netif *netif); -err_t autoip_stop(struct netif *netif); -void autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr); -void autoip_tmr(void); -void autoip_network_changed(struct netif *netif); -u8_t autoip_supplied_address(const struct netif *netif); - -/* for lwIP internal use by ip4.c */ -u8_t autoip_accept_packet(struct netif *netif, const ip4_addr_t *addr); - -#define netif_autoip_data(netif) ((struct autoip*)netif_get_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_AUTOIP)) - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV4 && LWIP_AUTOIP */ - -#endif /* LWIP_HDR_AUTOIP_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/debug.h b/third-party/lwip-2.1.2/include/lwip/debug.h deleted file mode 100644 index baa6a409..00000000 --- a/third-party/lwip-2.1.2/include/lwip/debug.h +++ /dev/null @@ -1,161 +0,0 @@ -/** - * @file - * Debug messages infrastructure - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_DEBUG_H -#define LWIP_HDR_DEBUG_H - -#include "lwip/arch.h" -#include "lwip/opt.h" - -/** - * @defgroup debugging_levels LWIP_DBG_MIN_LEVEL and LWIP_DBG_TYPES_ON values - * @ingroup lwip_opts_debugmsg - * @{ - */ - -/** @name Debug level (LWIP_DBG_MIN_LEVEL) - * @{ - */ -/** Debug level: ALL messages*/ -#define LWIP_DBG_LEVEL_ALL 0x00 -/** Debug level: Warnings. bad checksums, dropped packets, ... */ -#define LWIP_DBG_LEVEL_WARNING 0x01 -/** Debug level: Serious. memory allocation failures, ... */ -#define LWIP_DBG_LEVEL_SERIOUS 0x02 -/** Debug level: Severe */ -#define LWIP_DBG_LEVEL_SEVERE 0x03 -/** - * @} - */ - -#define LWIP_DBG_MASK_LEVEL 0x03 -/* compatibility define only */ -#define LWIP_DBG_LEVEL_OFF LWIP_DBG_LEVEL_ALL - -/** @name Enable/disable debug messages completely (LWIP_DBG_TYPES_ON) - * @{ - */ -/** flag for LWIP_DEBUGF to enable that debug message */ -#define LWIP_DBG_ON 0x80U -/** flag for LWIP_DEBUGF to disable that debug message */ -#define LWIP_DBG_OFF 0x00U -/** - * @} - */ - -/** @name Debug message types (LWIP_DBG_TYPES_ON) - * @{ - */ -/** flag for LWIP_DEBUGF indicating a tracing message (to follow program flow) */ -#define LWIP_DBG_TRACE 0x40U -/** flag for LWIP_DEBUGF indicating a state debug message (to follow module states) */ -#define LWIP_DBG_STATE 0x20U -/** flag for LWIP_DEBUGF indicating newly added code, not thoroughly tested yet */ -#define LWIP_DBG_FRESH 0x10U -/** flag for LWIP_DEBUGF to halt after printing this debug message */ -#define LWIP_DBG_HALT 0x08U -/** - * @} - */ - -/** - * @} - */ - -/** - * @defgroup lwip_assertions Assertion handling - * @ingroup lwip_opts_debug - * @{ - */ -/** - * LWIP_NOASSERT: Disable LWIP_ASSERT checks: - * To disable assertions define LWIP_NOASSERT in arch/cc.h. - */ -#ifdef __DOXYGEN__ -#define LWIP_NOASSERT -#undef LWIP_NOASSERT -#endif -/** - * @} - */ - -#ifndef LWIP_NOASSERT -#define LWIP_ASSERT(message, assertion) do { if (!(assertion)) { \ - LWIP_PLATFORM_ASSERT(message); }} while(0) -#else /* LWIP_NOASSERT */ -#define LWIP_ASSERT(message, assertion) -#endif /* LWIP_NOASSERT */ - -#ifndef LWIP_ERROR -#ifndef LWIP_NOASSERT -#define LWIP_PLATFORM_ERROR(message) LWIP_PLATFORM_ASSERT(message) -#elif defined LWIP_DEBUG -#define LWIP_PLATFORM_ERROR(message) LWIP_PLATFORM_DIAG((message)) -#else -#define LWIP_PLATFORM_ERROR(message) -#endif - -/* if "expression" isn't true, then print "message" and execute "handler" expression */ -#define LWIP_ERROR(message, expression, handler) do { if (!(expression)) { \ - LWIP_PLATFORM_ERROR(message); handler;}} while(0) -#endif /* LWIP_ERROR */ - -/** Enable debug message printing, but only if debug message type is enabled - * AND is of correct type AND is at least LWIP_DBG_LEVEL. - */ -#ifdef __DOXYGEN__ -#define LWIP_DEBUG -#undef LWIP_DEBUG -#endif - -#ifdef LWIP_DEBUG -#define LWIP_DEBUGF(debug, message) do { \ - if ( \ - ((debug) & LWIP_DBG_ON) && \ - ((debug) & LWIP_DBG_TYPES_ON) && \ - ((s16_t)((debug) & LWIP_DBG_MASK_LEVEL) >= LWIP_DBG_MIN_LEVEL)) { \ - LWIP_PLATFORM_DIAG(message); \ - if ((debug) & LWIP_DBG_HALT) { \ - while(1); \ - } \ - } \ - } while(0) - -#else /* LWIP_DEBUG */ -#define LWIP_DEBUGF(debug, message) -#endif /* LWIP_DEBUG */ - -#endif /* LWIP_HDR_DEBUG_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/def.h b/third-party/lwip-2.1.2/include/lwip/def.h deleted file mode 100644 index dfb266d1..00000000 --- a/third-party/lwip-2.1.2/include/lwip/def.h +++ /dev/null @@ -1,152 +0,0 @@ -/** - * @file - * various utility macros - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -/** - * @defgroup perf Performance measurement - * @ingroup sys_layer - * All defines related to this section must not be placed in lwipopts.h, - * but in arch/perf.h! - * Measurement calls made throughout lwip, these can be defined to nothing. - * - PERF_START: start measuring something. - * - PERF_STOP(x): stop measuring something, and record the result. - */ - -#ifndef LWIP_HDR_DEF_H -#define LWIP_HDR_DEF_H - -/* arch.h might define NULL already */ -#include "lwip/arch.h" -#include "lwip/opt.h" -#if LWIP_PERF -#include "arch/perf.h" -#else /* LWIP_PERF */ -#define PERF_START /* null definition */ -#define PERF_STOP(x) /* null definition */ -#endif /* LWIP_PERF */ - -#ifdef __cplusplus -extern "C" { -#endif - -#define LWIP_MAX(x , y) (((x) > (y)) ? (x) : (y)) -#define LWIP_MIN(x , y) (((x) < (y)) ? (x) : (y)) - -/* Get the number of entries in an array ('x' must NOT be a pointer!) */ -#define LWIP_ARRAYSIZE(x) (sizeof(x)/sizeof((x)[0])) - -/** Create u32_t value from bytes */ -#define LWIP_MAKEU32(a,b,c,d) (((u32_t)((a) & 0xff) << 24) | \ - ((u32_t)((b) & 0xff) << 16) | \ - ((u32_t)((c) & 0xff) << 8) | \ - (u32_t)((d) & 0xff)) - -#ifndef NULL -#ifdef __cplusplus -#define NULL 0 -#else -#define NULL ((void *)0) -#endif -#endif - -#if BYTE_ORDER == BIG_ENDIAN -#define lwip_htons(x) ((u16_t)(x)) -#define lwip_ntohs(x) ((u16_t)(x)) -#define lwip_htonl(x) ((u32_t)(x)) -#define lwip_ntohl(x) ((u32_t)(x)) -#define PP_HTONS(x) ((u16_t)(x)) -#define PP_NTOHS(x) ((u16_t)(x)) -#define PP_HTONL(x) ((u32_t)(x)) -#define PP_NTOHL(x) ((u32_t)(x)) -#else /* BYTE_ORDER != BIG_ENDIAN */ -#ifndef lwip_htons -u16_t lwip_htons(u16_t x); -#endif -#define lwip_ntohs(x) lwip_htons(x) - -#ifndef lwip_htonl -u32_t lwip_htonl(u32_t x); -#endif -#define lwip_ntohl(x) lwip_htonl(x) - -/* These macros should be calculated by the preprocessor and are used - with compile-time constants only (so that there is no little-endian - overhead at runtime). */ -#define PP_HTONS(x) ((u16_t)((((x) & (u16_t)0x00ffU) << 8) | (((x) & (u16_t)0xff00U) >> 8))) -#define PP_NTOHS(x) PP_HTONS(x) -#define PP_HTONL(x) ((((x) & (u32_t)0x000000ffUL) << 24) | \ - (((x) & (u32_t)0x0000ff00UL) << 8) | \ - (((x) & (u32_t)0x00ff0000UL) >> 8) | \ - (((x) & (u32_t)0xff000000UL) >> 24)) -#define PP_NTOHL(x) PP_HTONL(x) -#endif /* BYTE_ORDER == BIG_ENDIAN */ - -/* Provide usual function names as macros for users, but this can be turned off */ -#ifndef LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS -#define htons(x) lwip_htons(x) -#define ntohs(x) lwip_ntohs(x) -#define htonl(x) lwip_htonl(x) -#define ntohl(x) lwip_ntohl(x) -#endif - -/* Functions that are not available as standard implementations. - * In cc.h, you can #define these to implementations available on - * your platform to save some code bytes if you use these functions - * in your application, too. - */ - -#ifndef lwip_itoa -/* This can be #defined to itoa() or snprintf(result, bufsize, "%d", number) depending on your platform */ -void lwip_itoa(char* result, size_t bufsize, int number); -#endif -#ifndef lwip_strnicmp -/* This can be #defined to strnicmp() or strncasecmp() depending on your platform */ -int lwip_strnicmp(const char* str1, const char* str2, size_t len); -#endif -#ifndef lwip_stricmp -/* This can be #defined to stricmp() or strcasecmp() depending on your platform */ -int lwip_stricmp(const char* str1, const char* str2); -#endif -#ifndef lwip_strnstr -/* This can be #defined to strnstr() depending on your platform */ -char* lwip_strnstr(const char* buffer, const char* token, size_t n); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_DEF_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/dhcp.h b/third-party/lwip-2.1.2/include/lwip/dhcp.h deleted file mode 100644 index c78aa0ba..00000000 --- a/third-party/lwip-2.1.2/include/lwip/dhcp.h +++ /dev/null @@ -1,139 +0,0 @@ -/** - * @file - * DHCP client API - */ - -/* - * Copyright (c) 2001-2004 Leon Woestenberg - * Copyright (c) 2001-2004 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Leon Woestenberg - * - */ -#ifndef LWIP_HDR_DHCP_H -#define LWIP_HDR_DHCP_H - -#include "lwip/opt.h" - -#if LWIP_DHCP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/netif.h" -#include "lwip/udp.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** period (in seconds) of the application calling dhcp_coarse_tmr() */ -#define DHCP_COARSE_TIMER_SECS 60 -/** period (in milliseconds) of the application calling dhcp_coarse_tmr() */ -#define DHCP_COARSE_TIMER_MSECS (DHCP_COARSE_TIMER_SECS * 1000UL) -/** period (in milliseconds) of the application calling dhcp_fine_tmr() */ -#define DHCP_FINE_TIMER_MSECS 500 - -#define DHCP_BOOT_FILE_LEN 128U - -/* AutoIP cooperation flags (struct dhcp.autoip_coop_state) */ -typedef enum { - DHCP_AUTOIP_COOP_STATE_OFF = 0, - DHCP_AUTOIP_COOP_STATE_ON = 1 -} dhcp_autoip_coop_state_enum_t; - -struct dhcp -{ - /** transaction identifier of last sent request */ - u32_t xid; - /** track PCB allocation state */ - u8_t pcb_allocated; - /** current DHCP state machine state */ - u8_t state; - /** retries of current request */ - u8_t tries; -#if LWIP_DHCP_AUTOIP_COOP - u8_t autoip_coop_state; -#endif - u8_t subnet_mask_given; - - u16_t request_timeout; /* #ticks with period DHCP_FINE_TIMER_SECS for request timeout */ - u16_t t1_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for renewal time */ - u16_t t2_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for rebind time */ - u16_t t1_renew_time; /* #ticks with period DHCP_COARSE_TIMER_SECS until next renew try */ - u16_t t2_rebind_time; /* #ticks with period DHCP_COARSE_TIMER_SECS until next rebind try */ - u16_t lease_used; /* #ticks with period DHCP_COARSE_TIMER_SECS since last received DHCP ack */ - u16_t t0_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for lease time */ - ip_addr_t server_ip_addr; /* dhcp server address that offered this lease (ip_addr_t because passed to UDP) */ - ip4_addr_t offered_ip_addr; - ip4_addr_t offered_sn_mask; - ip4_addr_t offered_gw_addr; - - u32_t offered_t0_lease; /* lease period (in seconds) */ - u32_t offered_t1_renew; /* recommended renew time (usually 50% of lease period) */ - u32_t offered_t2_rebind; /* recommended rebind time (usually 87.5 of lease period) */ -#if LWIP_DHCP_BOOTP_FILE - ip4_addr_t offered_si_addr; - char boot_file_name[DHCP_BOOT_FILE_LEN]; -#endif /* LWIP_DHCP_BOOTPFILE */ -}; - - -void dhcp_set_struct(struct netif *netif, struct dhcp *dhcp); -/** Remove a struct dhcp previously set to the netif using dhcp_set_struct() */ -#define dhcp_remove_struct(netif) netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP, NULL) -void dhcp_cleanup(struct netif *netif); -err_t dhcp_start(struct netif *netif); -err_t dhcp_renew(struct netif *netif); -err_t dhcp_release(struct netif *netif); -void dhcp_stop(struct netif *netif); -void dhcp_release_and_stop(struct netif *netif); -void dhcp_inform(struct netif *netif); -void dhcp_network_changed(struct netif *netif); -#if DHCP_DOES_ARP_CHECK -void dhcp_arp_reply(struct netif *netif, const ip4_addr_t *addr); -#endif -u8_t dhcp_supplied_address(const struct netif *netif); -/* to be called every minute */ -void dhcp_coarse_tmr(void); -/* to be called every half second */ -void dhcp_fine_tmr(void); - -#if LWIP_DHCP_GET_NTP_SRV -/** This function must exist, in other to add offered NTP servers to - * the NTP (or SNTP) engine. - * See LWIP_DHCP_MAX_NTP_SERVERS */ -extern void dhcp_set_ntp_servers(u8_t num_ntp_servers, const ip4_addr_t* ntp_server_addrs); -#endif /* LWIP_DHCP_GET_NTP_SRV */ - -#define netif_dhcp_data(netif) ((struct dhcp*)netif_get_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP)) - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_DHCP */ - -#endif /*LWIP_HDR_DHCP_H*/ diff --git a/third-party/lwip-2.1.2/include/lwip/dhcp6.h b/third-party/lwip-2.1.2/include/lwip/dhcp6.h deleted file mode 100644 index 5cc4a015..00000000 --- a/third-party/lwip-2.1.2/include/lwip/dhcp6.h +++ /dev/null @@ -1,104 +0,0 @@ -/** - * @file - * - * DHCPv6 client: IPv6 address autoconfiguration as per - * RFC 3315 (stateful DHCPv6) and - * RFC 3736 (stateless DHCPv6). - */ - -/* - * Copyright (c) 2018 Simon Goldschmidt - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Simon Goldschmidt - */ - -#ifndef LWIP_HDR_IP6_DHCP6_H -#define LWIP_HDR_IP6_DHCP6_H - -#include "lwip/opt.h" - -#if LWIP_IPV6_DHCP6 /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/err.h" -#include "lwip/netif.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** period (in milliseconds) of the application calling dhcp6_tmr() */ -#define DHCP6_TIMER_MSECS 500 - -struct dhcp6 -{ - /** transaction identifier of last sent request */ - u32_t xid; - /** track PCB allocation state */ - u8_t pcb_allocated; - /** current DHCPv6 state machine state */ - u8_t state; - /** retries of current request */ - u8_t tries; - /** if request config is triggered while another action is active, this keeps track of it */ - u8_t request_config_pending; - /** #ticks with period DHCP6_TIMER_MSECS for request timeout */ - u16_t request_timeout; -#if LWIP_IPV6_DHCP6_STATEFUL - /* @todo: add more members here to keep track of stateful DHCPv6 data, like lease times */ -#endif /* LWIP_IPV6_DHCP6_STATEFUL */ -}; - -void dhcp6_set_struct(struct netif *netif, struct dhcp6 *dhcp6); -/** Remove a struct dhcp6 previously set to the netif using dhcp6_set_struct() */ -#define dhcp6_remove_struct(netif) netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP6, NULL) -void dhcp6_cleanup(struct netif *netif); - -err_t dhcp6_enable_stateful(struct netif *netif); -err_t dhcp6_enable_stateless(struct netif *netif); -void dhcp6_disable(struct netif *netif); - -void dhcp6_tmr(void); - -void dhcp6_nd6_ra_trigger(struct netif *netif, u8_t managed_addr_config, u8_t other_config); - -#if LWIP_DHCP6_GET_NTP_SRV -/** This function must exist, in other to add offered NTP servers to - * the NTP (or SNTP) engine. - * See LWIP_DHCP6_MAX_NTP_SERVERS */ -extern void dhcp6_set_ntp_servers(u8_t num_ntp_servers, const ip_addr_t* ntp_server_addrs); -#endif /* LWIP_DHCP6_GET_NTP_SRV */ - -#define netif_dhcp6_data(netif) ((struct dhcp6*)netif_get_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP6)) - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV6_DHCP6 */ - -#endif /* LWIP_HDR_IP6_DHCP6_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/dns.h b/third-party/lwip-2.1.2/include/lwip/dns.h deleted file mode 100644 index 09134154..00000000 --- a/third-party/lwip-2.1.2/include/lwip/dns.h +++ /dev/null @@ -1,131 +0,0 @@ -/** - * @file - * DNS API - */ - -/** - * lwip DNS resolver header file. - - * Author: Jim Pettinato - * April 2007 - - * ported from uIP resolv.c Copyright (c) 2002-2003, Adam Dunkels. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef LWIP_HDR_DNS_H -#define LWIP_HDR_DNS_H - -#include "lwip/opt.h" - -#if LWIP_DNS - -#include "lwip/ip_addr.h" -#include "lwip/err.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** DNS timer period */ -#define DNS_TMR_INTERVAL 1000 - -/* DNS resolve types: */ -#define LWIP_DNS_ADDRTYPE_IPV4 0 -#define LWIP_DNS_ADDRTYPE_IPV6 1 -#define LWIP_DNS_ADDRTYPE_IPV4_IPV6 2 /* try to resolve IPv4 first, try IPv6 if IPv4 fails only */ -#define LWIP_DNS_ADDRTYPE_IPV6_IPV4 3 /* try to resolve IPv6 first, try IPv4 if IPv6 fails only */ -#if LWIP_IPV4 && LWIP_IPV6 -#ifndef LWIP_DNS_ADDRTYPE_DEFAULT -#define LWIP_DNS_ADDRTYPE_DEFAULT LWIP_DNS_ADDRTYPE_IPV4_IPV6 -#endif -#elif LWIP_IPV4 -#define LWIP_DNS_ADDRTYPE_DEFAULT LWIP_DNS_ADDRTYPE_IPV4 -#else -#define LWIP_DNS_ADDRTYPE_DEFAULT LWIP_DNS_ADDRTYPE_IPV6 -#endif - -#if DNS_LOCAL_HOSTLIST -/** struct used for local host-list */ -struct local_hostlist_entry { - /** static hostname */ - const char *name; - /** static host address in network byteorder */ - ip_addr_t addr; - struct local_hostlist_entry *next; -}; -#define DNS_LOCAL_HOSTLIST_ELEM(name, addr_init) {name, addr_init, NULL} -#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC -#ifndef DNS_LOCAL_HOSTLIST_MAX_NAMELEN -#define DNS_LOCAL_HOSTLIST_MAX_NAMELEN DNS_MAX_NAME_LENGTH -#endif -#define LOCALHOSTLIST_ELEM_SIZE ((sizeof(struct local_hostlist_entry) + DNS_LOCAL_HOSTLIST_MAX_NAMELEN + 1)) -#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ -#endif /* DNS_LOCAL_HOSTLIST */ - -#if LWIP_IPV4 -extern const ip_addr_t dns_mquery_v4group; -#endif /* LWIP_IPV4 */ -#if LWIP_IPV6 -extern const ip_addr_t dns_mquery_v6group; -#endif /* LWIP_IPV6 */ - -/** Callback which is invoked when a hostname is found. - * A function of this type must be implemented by the application using the DNS resolver. - * @param name pointer to the name that was looked up. - * @param ipaddr pointer to an ip_addr_t containing the IP address of the hostname, - * or NULL if the name could not be found (or on any other error). - * @param callback_arg a user-specified callback argument passed to dns_gethostbyname -*/ -typedef void (*dns_found_callback)(const char *name, const ip_addr_t *ipaddr, void *callback_arg); - -void dns_init(void); -void dns_tmr(void); -void dns_setserver(u8_t numdns, const ip_addr_t *dnsserver); -const ip_addr_t* dns_getserver(u8_t numdns); -err_t dns_gethostbyname(const char *hostname, ip_addr_t *addr, - dns_found_callback found, void *callback_arg); -err_t dns_gethostbyname_addrtype(const char *hostname, ip_addr_t *addr, - dns_found_callback found, void *callback_arg, - u8_t dns_addrtype); - - -#if DNS_LOCAL_HOSTLIST -size_t dns_local_iterate(dns_found_callback iterator_fn, void *iterator_arg); -err_t dns_local_lookup(const char *hostname, ip_addr_t *addr, u8_t dns_addrtype); -#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC -int dns_local_removehost(const char *hostname, const ip_addr_t *addr); -err_t dns_local_addhost(const char *hostname, const ip_addr_t *addr); -#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ -#endif /* DNS_LOCAL_HOSTLIST */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_DNS */ - -#endif /* LWIP_HDR_DNS_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/err.h b/third-party/lwip-2.1.2/include/lwip/err.h deleted file mode 100644 index 887d9b3f..00000000 --- a/third-party/lwip-2.1.2/include/lwip/err.h +++ /dev/null @@ -1,117 +0,0 @@ -/** - * @file - * lwIP Error codes - */ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_ERR_H -#define LWIP_HDR_ERR_H - -#include "lwip/opt.h" -#include "lwip/arch.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup infrastructure_errors Error codes - * @ingroup infrastructure - * @{ - */ - -/** Definitions for error constants. */ -typedef enum { -/** No error, everything OK. */ - ERR_OK = 0, -/** Out of memory error. */ - ERR_MEM = -1, -/** Buffer error. */ - ERR_BUF = -2, -/** Timeout. */ - ERR_TIMEOUT = -3, -/** Routing problem. */ - ERR_RTE = -4, -/** Operation in progress */ - ERR_INPROGRESS = -5, -/** Illegal value. */ - ERR_VAL = -6, -/** Operation would block. */ - ERR_WOULDBLOCK = -7, -/** Address in use. */ - ERR_USE = -8, -/** Already connecting. */ - ERR_ALREADY = -9, -/** Conn already established.*/ - ERR_ISCONN = -10, -/** Not connected. */ - ERR_CONN = -11, -/** Low-level netif error */ - ERR_IF = -12, - -/** Connection aborted. */ - ERR_ABRT = -13, -/** Connection reset. */ - ERR_RST = -14, -/** Connection closed. */ - ERR_CLSD = -15, -/** Illegal argument. */ - ERR_ARG = -16 -} err_enum_t; - -/** Define LWIP_ERR_T in cc.h if you want to use - * a different type for your platform (must be signed). */ -#ifdef LWIP_ERR_T -typedef LWIP_ERR_T err_t; -#else /* LWIP_ERR_T */ -typedef s8_t err_t; -#endif /* LWIP_ERR_T*/ - -/** - * @} - */ - -#ifdef LWIP_DEBUG -extern const char *lwip_strerr(err_t err); -#else -#define lwip_strerr(x) "" -#endif /* LWIP_DEBUG */ - -#if !NO_SYS -int err_to_errno(err_t err); -#endif /* !NO_SYS */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_ERR_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/errno.h b/third-party/lwip-2.1.2/include/lwip/errno.h deleted file mode 100644 index 48d6b539..00000000 --- a/third-party/lwip-2.1.2/include/lwip/errno.h +++ /dev/null @@ -1,198 +0,0 @@ -/** - * @file - * Posix Errno defines - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_ERRNO_H -#define LWIP_HDR_ERRNO_H - -#include "lwip/opt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef LWIP_PROVIDE_ERRNO - -#define EPERM 1 /* Operation not permitted */ -#define ENOENT 2 /* No such file or directory */ -#define ESRCH 3 /* No such process */ -#define EINTR 4 /* Interrupted system call */ -#define EIO 5 /* I/O error */ -#define ENXIO 6 /* No such device or address */ -#define E2BIG 7 /* Arg list too long */ -#define ENOEXEC 8 /* Exec format error */ -#define EBADF 9 /* Bad file number */ -#define ECHILD 10 /* No child processes */ -#define EAGAIN 11 /* Try again */ -#define ENOMEM 12 /* Out of memory */ -#define EACCES 13 /* Permission denied */ -#define EFAULT 14 /* Bad address */ -#define ENOTBLK 15 /* Block device required */ -#define EBUSY 16 /* Device or resource busy */ -#define EEXIST 17 /* File exists */ -#define EXDEV 18 /* Cross-device link */ -#define ENODEV 19 /* No such device */ -#define ENOTDIR 20 /* Not a directory */ -#define EISDIR 21 /* Is a directory */ -#define EINVAL 22 /* Invalid argument */ -#define ENFILE 23 /* File table overflow */ -#define EMFILE 24 /* Too many open files */ -#define ENOTTY 25 /* Not a typewriter */ -#define ETXTBSY 26 /* Text file busy */ -#define EFBIG 27 /* File too large */ -#define ENOSPC 28 /* No space left on device */ -#define ESPIPE 29 /* Illegal seek */ -#define EROFS 30 /* Read-only file system */ -#define EMLINK 31 /* Too many links */ -#define EPIPE 32 /* Broken pipe */ -#define EDOM 33 /* Math argument out of domain of func */ -#define ERANGE 34 /* Math result not representable */ -#define EDEADLK 35 /* Resource deadlock would occur */ -#define ENAMETOOLONG 36 /* File name too long */ -#define ENOLCK 37 /* No record locks available */ -#define ENOSYS 38 /* Function not implemented */ -#define ENOTEMPTY 39 /* Directory not empty */ -#define ELOOP 40 /* Too many symbolic links encountered */ -#define EWOULDBLOCK EAGAIN /* Operation would block */ -#define ENOMSG 42 /* No message of desired type */ -#define EIDRM 43 /* Identifier removed */ -#define ECHRNG 44 /* Channel number out of range */ -#define EL2NSYNC 45 /* Level 2 not synchronized */ -#define EL3HLT 46 /* Level 3 halted */ -#define EL3RST 47 /* Level 3 reset */ -#define ELNRNG 48 /* Link number out of range */ -#define EUNATCH 49 /* Protocol driver not attached */ -#define ENOCSI 50 /* No CSI structure available */ -#define EL2HLT 51 /* Level 2 halted */ -#define EBADE 52 /* Invalid exchange */ -#define EBADR 53 /* Invalid request descriptor */ -#define EXFULL 54 /* Exchange full */ -#define ENOANO 55 /* No anode */ -#define EBADRQC 56 /* Invalid request code */ -#define EBADSLT 57 /* Invalid slot */ - -#define EDEADLOCK EDEADLK - -#define EBFONT 59 /* Bad font file format */ -#define ENOSTR 60 /* Device not a stream */ -#define ENODATA 61 /* No data available */ -#define ETIME 62 /* Timer expired */ -#define ENOSR 63 /* Out of streams resources */ -#define ENONET 64 /* Machine is not on the network */ -#define ENOPKG 65 /* Package not installed */ -#define EREMOTE 66 /* Object is remote */ -#define ENOLINK 67 /* Link has been severed */ -#define EADV 68 /* Advertise error */ -#define ESRMNT 69 /* Srmount error */ -#define ECOMM 70 /* Communication error on send */ -#define EPROTO 71 /* Protocol error */ -#define EMULTIHOP 72 /* Multihop attempted */ -#define EDOTDOT 73 /* RFS specific error */ -#define EBADMSG 74 /* Not a data message */ -#define EOVERFLOW 75 /* Value too large for defined data type */ -#define ENOTUNIQ 76 /* Name not unique on network */ -#define EBADFD 77 /* File descriptor in bad state */ -#define EREMCHG 78 /* Remote address changed */ -#define ELIBACC 79 /* Can not access a needed shared library */ -#define ELIBBAD 80 /* Accessing a corrupted shared library */ -#define ELIBSCN 81 /* .lib section in a.out corrupted */ -#define ELIBMAX 82 /* Attempting to link in too many shared libraries */ -#define ELIBEXEC 83 /* Cannot exec a shared library directly */ -#define EILSEQ 84 /* Illegal byte sequence */ -#define ERESTART 85 /* Interrupted system call should be restarted */ -#define ESTRPIPE 86 /* Streams pipe error */ -#define EUSERS 87 /* Too many users */ -#define ENOTSOCK 88 /* Socket operation on non-socket */ -#define EDESTADDRREQ 89 /* Destination address required */ -#define EMSGSIZE 90 /* Message too long */ -#define EPROTOTYPE 91 /* Protocol wrong type for socket */ -#define ENOPROTOOPT 92 /* Protocol not available */ -#define EPROTONOSUPPORT 93 /* Protocol not supported */ -#define ESOCKTNOSUPPORT 94 /* Socket type not supported */ -#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ -#define EPFNOSUPPORT 96 /* Protocol family not supported */ -#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ -#define EADDRINUSE 98 /* Address already in use */ -#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ -#define ENETDOWN 100 /* Network is down */ -#define ENETUNREACH 101 /* Network is unreachable */ -#define ENETRESET 102 /* Network dropped connection because of reset */ -#define ECONNABORTED 103 /* Software caused connection abort */ -#define ECONNRESET 104 /* Connection reset by peer */ -#define ENOBUFS 105 /* No buffer space available */ -#define EISCONN 106 /* Transport endpoint is already connected */ -#define ENOTCONN 107 /* Transport endpoint is not connected */ -#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ -#define ETOOMANYREFS 109 /* Too many references: cannot splice */ -#define ETIMEDOUT 110 /* Connection timed out */ -#define ECONNREFUSED 111 /* Connection refused */ -#define EHOSTDOWN 112 /* Host is down */ -#define EHOSTUNREACH 113 /* No route to host */ -#define EALREADY 114 /* Operation already in progress */ -#define EINPROGRESS 115 /* Operation now in progress */ -#define ESTALE 116 /* Stale NFS file handle */ -#define EUCLEAN 117 /* Structure needs cleaning */ -#define ENOTNAM 118 /* Not a XENIX named type file */ -#define ENAVAIL 119 /* No XENIX semaphores available */ -#define EISNAM 120 /* Is a named type file */ -#define EREMOTEIO 121 /* Remote I/O error */ -#define EDQUOT 122 /* Quota exceeded */ - -#define ENOMEDIUM 123 /* No medium found */ -#define EMEDIUMTYPE 124 /* Wrong medium type */ - -#ifndef errno -extern int errno; -#endif - -#else /* LWIP_PROVIDE_ERRNO */ - -/* Define LWIP_ERRNO_STDINCLUDE if you want to include here */ -#ifdef LWIP_ERRNO_STDINCLUDE -#include -#else /* LWIP_ERRNO_STDINCLUDE */ -/* Define LWIP_ERRNO_INCLUDE to an equivalent of to include the error defines here */ -#ifdef LWIP_ERRNO_INCLUDE -#include LWIP_ERRNO_INCLUDE -#endif /* LWIP_ERRNO_INCLUDE */ -#endif /* LWIP_ERRNO_STDINCLUDE */ - -#endif /* LWIP_PROVIDE_ERRNO */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_ERRNO_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/etharp.h b/third-party/lwip-2.1.2/include/lwip/etharp.h deleted file mode 100644 index 2036b246..00000000 --- a/third-party/lwip-2.1.2/include/lwip/etharp.h +++ /dev/null @@ -1,105 +0,0 @@ -/** - * @file - * Ethernet output function - handles OUTGOING ethernet level traffic, implements - * ARP resolving. - * To be used in most low-level netif implementations - */ - -/* - * Copyright (c) 2001-2003 Swedish Institute of Computer Science. - * Copyright (c) 2003-2004 Leon Woestenberg - * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#ifndef LWIP_HDR_NETIF_ETHARP_H -#define LWIP_HDR_NETIF_ETHARP_H - -#include "lwip/opt.h" - -#if LWIP_ARP || LWIP_ETHERNET /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/pbuf.h" -#include "lwip/ip4_addr.h" -#include "lwip/netif.h" -#include "lwip/ip4.h" -#include "lwip/prot/ethernet.h" - -#if LWIP_IPV4 && LWIP_ARP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/prot/etharp.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** 1 seconds period */ -#define ARP_TMR_INTERVAL 1000 - -#if ARP_QUEUEING -/** struct for queueing outgoing packets for unknown address - * defined here to be accessed by memp.h - */ -struct etharp_q_entry { - struct etharp_q_entry *next; - struct pbuf *p; -}; -#endif /* ARP_QUEUEING */ - -#define etharp_init() /* Compatibility define, no init needed. */ -void etharp_tmr(void); -ssize_t etharp_find_addr(struct netif *netif, const ip4_addr_t *ipaddr, - struct eth_addr **eth_ret, const ip4_addr_t **ip_ret); -int etharp_get_entry(size_t i, ip4_addr_t **ipaddr, struct netif **netif, struct eth_addr **eth_ret); -err_t etharp_output(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr); -err_t etharp_query(struct netif *netif, const ip4_addr_t *ipaddr, struct pbuf *q); -err_t etharp_request(struct netif *netif, const ip4_addr_t *ipaddr); -/** For Ethernet network interfaces, we might want to send "gratuitous ARP"; - * this is an ARP packet sent by a node in order to spontaneously cause other - * nodes to update an entry in their ARP cache. - * From RFC 3220 "IP Mobility Support for IPv4" section 4.6. */ -#define etharp_gratuitous(netif) etharp_request((netif), netif_ip4_addr(netif)) -void etharp_cleanup_netif(struct netif *netif); - -#if ETHARP_SUPPORT_STATIC_ENTRIES -err_t etharp_add_static_entry(const ip4_addr_t *ipaddr, struct eth_addr *ethaddr); -err_t etharp_remove_static_entry(const ip4_addr_t *ipaddr); -#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ - -void etharp_input(struct pbuf *p, struct netif *netif); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV4 && LWIP_ARP */ -#endif /* LWIP_ARP || LWIP_ETHERNET */ - -#endif /* LWIP_HDR_NETIF_ETHARP_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/ethip6.h b/third-party/lwip-2.1.2/include/lwip/ethip6.h deleted file mode 100644 index 5e88dffd..00000000 --- a/third-party/lwip-2.1.2/include/lwip/ethip6.h +++ /dev/null @@ -1,68 +0,0 @@ -/** - * @file - * - * Ethernet output for IPv6. Uses ND tables for link-layer addressing. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -#ifndef LWIP_HDR_ETHIP6_H -#define LWIP_HDR_ETHIP6_H - -#include "lwip/opt.h" - -#if LWIP_IPV6 && LWIP_ETHERNET /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/pbuf.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#include "lwip/netif.h" - - -#ifdef __cplusplus -extern "C" { -#endif - - -err_t ethip6_output(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV6 && LWIP_ETHERNET */ - -#endif /* LWIP_HDR_ETHIP6_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/icmp.h b/third-party/lwip-2.1.2/include/lwip/icmp.h deleted file mode 100644 index f5a31fd4..00000000 --- a/third-party/lwip-2.1.2/include/lwip/icmp.h +++ /dev/null @@ -1,110 +0,0 @@ -/** - * @file - * ICMP API - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_ICMP_H -#define LWIP_HDR_ICMP_H - -#include "lwip/opt.h" -#include "lwip/pbuf.h" -#include "lwip/ip_addr.h" -#include "lwip/netif.h" -#include "lwip/prot/icmp.h" - -#if LWIP_IPV6 && LWIP_ICMP6 -#include "lwip/icmp6.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** ICMP destination unreachable codes */ -enum icmp_dur_type { - /** net unreachable */ - ICMP_DUR_NET = 0, - /** host unreachable */ - ICMP_DUR_HOST = 1, - /** protocol unreachable */ - ICMP_DUR_PROTO = 2, - /** port unreachable */ - ICMP_DUR_PORT = 3, - /** fragmentation needed and DF set */ - ICMP_DUR_FRAG = 4, - /** source route failed */ - ICMP_DUR_SR = 5 -}; - -/** ICMP time exceeded codes */ -enum icmp_te_type { - /** time to live exceeded in transit */ - ICMP_TE_TTL = 0, - /** fragment reassembly time exceeded */ - ICMP_TE_FRAG = 1 -}; - -#if LWIP_IPV4 && LWIP_ICMP /* don't build if not configured for use in lwipopts.h */ - -void icmp_input(struct pbuf *p, struct netif *inp); -void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t); -void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t); - -#endif /* LWIP_IPV4 && LWIP_ICMP */ - -#if LWIP_IPV4 && LWIP_IPV6 -#if LWIP_ICMP && LWIP_ICMP6 -#define icmp_port_unreach(isipv6, pbuf) ((isipv6) ? \ - icmp6_dest_unreach(pbuf, ICMP6_DUR_PORT) : \ - icmp_dest_unreach(pbuf, ICMP_DUR_PORT)) -#elif LWIP_ICMP -#define icmp_port_unreach(isipv6, pbuf) do{ if(!(isipv6)) { icmp_dest_unreach(pbuf, ICMP_DUR_PORT);}}while(0) -#elif LWIP_ICMP6 -#define icmp_port_unreach(isipv6, pbuf) do{ if(isipv6) { icmp6_dest_unreach(pbuf, ICMP6_DUR_PORT);}}while(0) -#else -#define icmp_port_unreach(isipv6, pbuf) -#endif -#elif LWIP_IPV6 && LWIP_ICMP6 -#define icmp_port_unreach(isipv6, pbuf) icmp6_dest_unreach(pbuf, ICMP6_DUR_PORT) -#elif LWIP_IPV4 && LWIP_ICMP -#define icmp_port_unreach(isipv6, pbuf) icmp_dest_unreach(pbuf, ICMP_DUR_PORT) -#else /* (LWIP_IPV6 && LWIP_ICMP6) || (LWIP_IPV4 && LWIP_ICMP) */ -#define icmp_port_unreach(isipv6, pbuf) -#endif /* (LWIP_IPV6 && LWIP_ICMP6) || (LWIP_IPV4 && LWIP_ICMP) LWIP_IPV4*/ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_ICMP_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/icmp6.h b/third-party/lwip-2.1.2/include/lwip/icmp6.h deleted file mode 100644 index 0ccb7899..00000000 --- a/third-party/lwip-2.1.2/include/lwip/icmp6.h +++ /dev/null @@ -1,72 +0,0 @@ -/** - * @file - * - * IPv6 version of ICMP, as per RFC 4443. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ -#ifndef LWIP_HDR_ICMP6_H -#define LWIP_HDR_ICMP6_H - -#include "lwip/opt.h" -#include "lwip/pbuf.h" -#include "lwip/ip6_addr.h" -#include "lwip/netif.h" -#include "lwip/prot/icmp6.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if LWIP_ICMP6 && LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - -void icmp6_input(struct pbuf *p, struct netif *inp); -void icmp6_dest_unreach(struct pbuf *p, enum icmp6_dur_code c); -void icmp6_packet_too_big(struct pbuf *p, u32_t mtu); -void icmp6_time_exceeded(struct pbuf *p, enum icmp6_te_code c); -void icmp6_time_exceeded_with_addrs(struct pbuf *p, enum icmp6_te_code c, - const ip6_addr_t *src_addr, const ip6_addr_t *dest_addr); -void icmp6_param_problem(struct pbuf *p, enum icmp6_pp_code c, const void *pointer); - -#endif /* LWIP_ICMP6 && LWIP_IPV6 */ - - -#ifdef __cplusplus -} -#endif - - -#endif /* LWIP_HDR_ICMP6_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/if_api.h b/third-party/lwip-2.1.2/include/lwip/if_api.h deleted file mode 100644 index 39017abd..00000000 --- a/third-party/lwip-2.1.2/include/lwip/if_api.h +++ /dev/null @@ -1,68 +0,0 @@ -/** - * @file - * Interface Identification APIs from: - * RFC 3493: Basic Socket Interface Extensions for IPv6 - * Section 4: Interface Identification - */ - -/* - * Copyright (c) 2017 Joel Cunningham, Garmin International, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Joel Cunningham - * - */ -#ifndef LWIP_HDR_IF_H -#define LWIP_HDR_IF_H - -#include "lwip/opt.h" - -#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/netif.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define IF_NAMESIZE NETIF_NAMESIZE - -char * lwip_if_indextoname(unsigned int ifindex, char *ifname); -unsigned int lwip_if_nametoindex(const char *ifname); - -#if LWIP_COMPAT_SOCKETS -#define if_indextoname(ifindex, ifname) lwip_if_indextoname(ifindex,ifname) -#define if_nametoindex(ifname) lwip_if_nametoindex(ifname) -#endif /* LWIP_COMPAT_SOCKETS */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_SOCKET */ - -#endif /* LWIP_HDR_IF_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/igmp.h b/third-party/lwip-2.1.2/include/lwip/igmp.h deleted file mode 100644 index ffd80e68..00000000 --- a/third-party/lwip-2.1.2/include/lwip/igmp.h +++ /dev/null @@ -1,115 +0,0 @@ -/** - * @file - * IGMP API - */ - -/* - * Copyright (c) 2002 CITEL Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of CITEL Technologies Ltd nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY CITEL TECHNOLOGIES AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL CITEL TECHNOLOGIES OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is a contribution to the lwIP TCP/IP stack. - * The Swedish Institute of Computer Science and Adam Dunkels - * are specifically granted permission to redistribute this - * source code. -*/ - -#ifndef LWIP_HDR_IGMP_H -#define LWIP_HDR_IGMP_H - -#include "lwip/opt.h" -#include "lwip/ip_addr.h" -#include "lwip/netif.h" -#include "lwip/pbuf.h" - -#if LWIP_IPV4 && LWIP_IGMP /* don't build if not configured for use in lwipopts.h */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* IGMP timer */ -#define IGMP_TMR_INTERVAL 100 /* Milliseconds */ -#define IGMP_V1_DELAYING_MEMBER_TMR (1000/IGMP_TMR_INTERVAL) -#define IGMP_JOIN_DELAYING_MEMBER_TMR (500 /IGMP_TMR_INTERVAL) - -/* Compatibility defines (don't use for new code) */ -#define IGMP_DEL_MAC_FILTER NETIF_DEL_MAC_FILTER -#define IGMP_ADD_MAC_FILTER NETIF_ADD_MAC_FILTER - -/** - * igmp group structure - there is - * a list of groups for each interface - * these should really be linked from the interface, but - * if we keep them separate we will not affect the lwip original code - * too much - * - * There will be a group for the all systems group address but this - * will not run the state machine as it is used to kick off reports - * from all the other groups - */ -struct igmp_group { - /** next link */ - struct igmp_group *next; - /** multicast address */ - ip4_addr_t group_address; - /** signifies we were the last person to report */ - u8_t last_reporter_flag; - /** current state of the group */ - u8_t group_state; - /** timer for reporting, negative is OFF */ - u16_t timer; - /** counter of simultaneous uses */ - u8_t use; -}; - -/* Prototypes */ -void igmp_init(void); -err_t igmp_start(struct netif *netif); -err_t igmp_stop(struct netif *netif); -void igmp_report_groups(struct netif *netif); -struct igmp_group *igmp_lookfor_group(struct netif *ifp, const ip4_addr_t *addr); -void igmp_input(struct pbuf *p, struct netif *inp, const ip4_addr_t *dest); -err_t igmp_joingroup(const ip4_addr_t *ifaddr, const ip4_addr_t *groupaddr); -err_t igmp_joingroup_netif(struct netif *netif, const ip4_addr_t *groupaddr); -err_t igmp_leavegroup(const ip4_addr_t *ifaddr, const ip4_addr_t *groupaddr); -err_t igmp_leavegroup_netif(struct netif *netif, const ip4_addr_t *groupaddr); -void igmp_tmr(void); - -/** @ingroup igmp - * Get list head of IGMP groups for netif. - * Note: The allsystems group IP is contained in the list as first entry. - * @see @ref netif_set_igmp_mac_filter() - */ -#define netif_igmp_data(netif) ((struct igmp_group *)netif_get_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_IGMP)) - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV4 && LWIP_IGMP */ - -#endif /* LWIP_HDR_IGMP_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/inet.h b/third-party/lwip-2.1.2/include/lwip/inet.h deleted file mode 100644 index 2982a0f4..00000000 --- a/third-party/lwip-2.1.2/include/lwip/inet.h +++ /dev/null @@ -1,169 +0,0 @@ -/** - * @file - * This file (together with sockets.h) aims to provide structs and functions from - * - arpa/inet.h - * - netinet/in.h - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_INET_H -#define LWIP_HDR_INET_H - -#include "lwip/opt.h" -#include "lwip/def.h" -#include "lwip/ip_addr.h" -#include "lwip/ip6_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* If your port already typedef's in_addr_t, define IN_ADDR_T_DEFINED - to prevent this code from redefining it. */ -#if !defined(in_addr_t) && !defined(IN_ADDR_T_DEFINED) -typedef u32_t in_addr_t; -#endif - -struct in_addr { - in_addr_t s_addr; -}; - -struct in6_addr { - union { - u32_t u32_addr[4]; - u8_t u8_addr[16]; - } un; -#define s6_addr un.u8_addr -}; - -/** 255.255.255.255 */ -#define INADDR_NONE IPADDR_NONE -/** 127.0.0.1 */ -#define INADDR_LOOPBACK IPADDR_LOOPBACK -/** 0.0.0.0 */ -#define INADDR_ANY IPADDR_ANY -/** 255.255.255.255 */ -#define INADDR_BROADCAST IPADDR_BROADCAST - -/** This macro can be used to initialize a variable of type struct in6_addr - to the IPv6 wildcard address. */ -#define IN6ADDR_ANY_INIT {{{0,0,0,0}}} -/** This macro can be used to initialize a variable of type struct in6_addr - to the IPv6 loopback address. */ -#define IN6ADDR_LOOPBACK_INIT {{{0,0,0,PP_HTONL(1)}}} -/** This variable is initialized by the system to contain the wildcard IPv6 address. */ -extern const struct in6_addr in6addr_any; - -/* Definitions of the bits in an (IPv4) Internet address integer. - - On subnets, host and network parts are found according to - the subnet mask, not these masks. */ -#define IN_CLASSA(a) IP_CLASSA(a) -#define IN_CLASSA_NET IP_CLASSA_NET -#define IN_CLASSA_NSHIFT IP_CLASSA_NSHIFT -#define IN_CLASSA_HOST IP_CLASSA_HOST -#define IN_CLASSA_MAX IP_CLASSA_MAX - -#define IN_CLASSB(b) IP_CLASSB(b) -#define IN_CLASSB_NET IP_CLASSB_NET -#define IN_CLASSB_NSHIFT IP_CLASSB_NSHIFT -#define IN_CLASSB_HOST IP_CLASSB_HOST -#define IN_CLASSB_MAX IP_CLASSB_MAX - -#define IN_CLASSC(c) IP_CLASSC(c) -#define IN_CLASSC_NET IP_CLASSC_NET -#define IN_CLASSC_NSHIFT IP_CLASSC_NSHIFT -#define IN_CLASSC_HOST IP_CLASSC_HOST -#define IN_CLASSC_MAX IP_CLASSC_MAX - -#define IN_CLASSD(d) IP_CLASSD(d) -#define IN_CLASSD_NET IP_CLASSD_NET /* These ones aren't really */ -#define IN_CLASSD_NSHIFT IP_CLASSD_NSHIFT /* net and host fields, but */ -#define IN_CLASSD_HOST IP_CLASSD_HOST /* routing needn't know. */ -#define IN_CLASSD_MAX IP_CLASSD_MAX - -#define IN_MULTICAST(a) IP_MULTICAST(a) - -#define IN_EXPERIMENTAL(a) IP_EXPERIMENTAL(a) -#define IN_BADCLASS(a) IP_BADCLASS(a) - -#define IN_LOOPBACKNET IP_LOOPBACKNET - - -#ifndef INET_ADDRSTRLEN -#define INET_ADDRSTRLEN IP4ADDR_STRLEN_MAX -#endif -#if LWIP_IPV6 -#ifndef INET6_ADDRSTRLEN -#define INET6_ADDRSTRLEN IP6ADDR_STRLEN_MAX -#endif -#endif - -#if LWIP_IPV4 - -#define inet_addr_from_ip4addr(target_inaddr, source_ipaddr) ((target_inaddr)->s_addr = ip4_addr_get_u32(source_ipaddr)) -#define inet_addr_to_ip4addr(target_ipaddr, source_inaddr) (ip4_addr_set_u32(target_ipaddr, (source_inaddr)->s_addr)) - -/* directly map this to the lwip internal functions */ -#define inet_addr(cp) ipaddr_addr(cp) -#define inet_aton(cp, addr) ip4addr_aton(cp, (ip4_addr_t*)addr) -#define inet_ntoa(addr) ip4addr_ntoa((const ip4_addr_t*)&(addr)) -#define inet_ntoa_r(addr, buf, buflen) ip4addr_ntoa_r((const ip4_addr_t*)&(addr), buf, buflen) - -#endif /* LWIP_IPV4 */ - -#if LWIP_IPV6 -#define inet6_addr_from_ip6addr(target_in6addr, source_ip6addr) {(target_in6addr)->un.u32_addr[0] = (source_ip6addr)->addr[0]; \ - (target_in6addr)->un.u32_addr[1] = (source_ip6addr)->addr[1]; \ - (target_in6addr)->un.u32_addr[2] = (source_ip6addr)->addr[2]; \ - (target_in6addr)->un.u32_addr[3] = (source_ip6addr)->addr[3];} -#define inet6_addr_to_ip6addr(target_ip6addr, source_in6addr) {(target_ip6addr)->addr[0] = (source_in6addr)->un.u32_addr[0]; \ - (target_ip6addr)->addr[1] = (source_in6addr)->un.u32_addr[1]; \ - (target_ip6addr)->addr[2] = (source_in6addr)->un.u32_addr[2]; \ - (target_ip6addr)->addr[3] = (source_in6addr)->un.u32_addr[3]; \ - ip6_addr_clear_zone(target_ip6addr);} - -/* directly map this to the lwip internal functions */ -#define inet6_aton(cp, addr) ip6addr_aton(cp, (ip6_addr_t*)addr) -#define inet6_ntoa(addr) ip6addr_ntoa((const ip6_addr_t*)&(addr)) -#define inet6_ntoa_r(addr, buf, buflen) ip6addr_ntoa_r((const ip6_addr_t*)&(addr), buf, buflen) - -#endif /* LWIP_IPV6 */ - - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_INET_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/inet_chksum.h b/third-party/lwip-2.1.2/include/lwip/inet_chksum.h deleted file mode 100644 index 76893ef5..00000000 --- a/third-party/lwip-2.1.2/include/lwip/inet_chksum.h +++ /dev/null @@ -1,105 +0,0 @@ -/** - * @file - * IP checksum calculation functions - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_INET_CHKSUM_H -#define LWIP_HDR_INET_CHKSUM_H - -#include "lwip/opt.h" - -#include "lwip/pbuf.h" -#include "lwip/ip_addr.h" - -/** Swap the bytes in an u16_t: much like lwip_htons() for little-endian */ -#ifndef SWAP_BYTES_IN_WORD -#define SWAP_BYTES_IN_WORD(w) (((w) & 0xff) << 8) | (((w) & 0xff00) >> 8) -#endif /* SWAP_BYTES_IN_WORD */ - -/** Split an u32_t in two u16_ts and add them up */ -#ifndef FOLD_U32T -#define FOLD_U32T(u) ((u32_t)(((u) >> 16) + ((u) & 0x0000ffffUL))) -#endif - -#if LWIP_CHECKSUM_ON_COPY -/** Function-like macro: same as MEMCPY but returns the checksum of copied data - as u16_t */ -# ifndef LWIP_CHKSUM_COPY -# define LWIP_CHKSUM_COPY(dst, src, len) lwip_chksum_copy(dst, src, len) -# ifndef LWIP_CHKSUM_COPY_ALGORITHM -# define LWIP_CHKSUM_COPY_ALGORITHM 1 -# endif /* LWIP_CHKSUM_COPY_ALGORITHM */ -# else /* LWIP_CHKSUM_COPY */ -# define LWIP_CHKSUM_COPY_ALGORITHM 0 -# endif /* LWIP_CHKSUM_COPY */ -#else /* LWIP_CHECKSUM_ON_COPY */ -# define LWIP_CHKSUM_COPY_ALGORITHM 0 -#endif /* LWIP_CHECKSUM_ON_COPY */ - -#ifdef __cplusplus -extern "C" { -#endif - -u16_t inet_chksum(const void *dataptr, u16_t len); -u16_t inet_chksum_pbuf(struct pbuf *p); -#if LWIP_CHKSUM_COPY_ALGORITHM -u16_t lwip_chksum_copy(void *dst, const void *src, u16_t len); -#endif /* LWIP_CHKSUM_COPY_ALGORITHM */ - -#if LWIP_IPV4 -u16_t inet_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len, - const ip4_addr_t *src, const ip4_addr_t *dest); -u16_t inet_chksum_pseudo_partial(struct pbuf *p, u8_t proto, - u16_t proto_len, u16_t chksum_len, const ip4_addr_t *src, const ip4_addr_t *dest); -#endif /* LWIP_IPV4 */ - -#if LWIP_IPV6 -u16_t ip6_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len, - const ip6_addr_t *src, const ip6_addr_t *dest); -u16_t ip6_chksum_pseudo_partial(struct pbuf *p, u8_t proto, u16_t proto_len, - u16_t chksum_len, const ip6_addr_t *src, const ip6_addr_t *dest); -#endif /* LWIP_IPV6 */ - - -u16_t ip_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len, - const ip_addr_t *src, const ip_addr_t *dest); -u16_t ip_chksum_pseudo_partial(struct pbuf *p, u8_t proto, u16_t proto_len, - u16_t chksum_len, const ip_addr_t *src, const ip_addr_t *dest); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_INET_H */ - diff --git a/third-party/lwip-2.1.2/include/lwip/init.h b/third-party/lwip-2.1.2/include/lwip/init.h deleted file mode 100644 index a149be18..00000000 --- a/third-party/lwip-2.1.2/include/lwip/init.h +++ /dev/null @@ -1,100 +0,0 @@ -/** - * @file - * lwIP initialization API - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_INIT_H -#define LWIP_HDR_INIT_H - -#include "lwip/opt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup lwip_version Version - * @ingroup lwip - * @{ - */ - -/** X.x.x: Major version of the stack */ -#define LWIP_VERSION_MAJOR 2 -/** x.X.x: Minor version of the stack */ -#define LWIP_VERSION_MINOR 1 -/** x.x.X: Revision of the stack */ -#define LWIP_VERSION_REVISION 2 -/** For release candidates, this is set to 1..254 - * For official releases, this is set to 255 (LWIP_RC_RELEASE) - * For development versions (Git), this is set to 0 (LWIP_RC_DEVELOPMENT) */ -#define LWIP_VERSION_RC LWIP_RC_RELEASE - -/** LWIP_VERSION_RC is set to LWIP_RC_RELEASE for official releases */ -#define LWIP_RC_RELEASE 255 -/** LWIP_VERSION_RC is set to LWIP_RC_DEVELOPMENT for Git versions */ -#define LWIP_RC_DEVELOPMENT 0 - -#define LWIP_VERSION_IS_RELEASE (LWIP_VERSION_RC == LWIP_RC_RELEASE) -#define LWIP_VERSION_IS_DEVELOPMENT (LWIP_VERSION_RC == LWIP_RC_DEVELOPMENT) -#define LWIP_VERSION_IS_RC ((LWIP_VERSION_RC != LWIP_RC_RELEASE) && (LWIP_VERSION_RC != LWIP_RC_DEVELOPMENT)) - -/* Some helper defines to get a version string */ -#define LWIP_VERSTR2(x) #x -#define LWIP_VERSTR(x) LWIP_VERSTR2(x) -#if LWIP_VERSION_IS_RELEASE -#define LWIP_VERSION_STRING_SUFFIX "" -#elif LWIP_VERSION_IS_DEVELOPMENT -#define LWIP_VERSION_STRING_SUFFIX "d" -#else -#define LWIP_VERSION_STRING_SUFFIX "rc" LWIP_VERSTR(LWIP_VERSION_RC) -#endif - -/** Provides the version of the stack */ -#define LWIP_VERSION ((LWIP_VERSION_MAJOR) << 24 | (LWIP_VERSION_MINOR) << 16 | \ - (LWIP_VERSION_REVISION) << 8 | (LWIP_VERSION_RC)) -/** Provides the version of the stack as string */ -#define LWIP_VERSION_STRING LWIP_VERSTR(LWIP_VERSION_MAJOR) "." LWIP_VERSTR(LWIP_VERSION_MINOR) "." LWIP_VERSTR(LWIP_VERSION_REVISION) LWIP_VERSION_STRING_SUFFIX - -/** - * @} - */ - -/* Modules initialization */ -void lwip_init(void); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_INIT_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/init.h.cmake.in b/third-party/lwip-2.1.2/include/lwip/init.h.cmake.in deleted file mode 100644 index 9b609b74..00000000 --- a/third-party/lwip-2.1.2/include/lwip/init.h.cmake.in +++ /dev/null @@ -1,100 +0,0 @@ -/** - * @file - * lwIP initialization API - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_INIT_H -#define LWIP_HDR_INIT_H - -#include "lwip/opt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup lwip_version Version - * @ingroup lwip - * @{ - */ - -/** X.x.x: Major version of the stack */ -#define LWIP_VERSION_MAJOR ${LWIP_VERSION_MAJOR} -/** x.X.x: Minor version of the stack */ -#define LWIP_VERSION_MINOR ${LWIP_VERSION_MINOR} -/** x.x.X: Revision of the stack */ -#define LWIP_VERSION_REVISION ${LWIP_VERSION_REVISION} -/** For release candidates, this is set to 1..254 - * For official releases, this is set to 255 (LWIP_RC_RELEASE) - * For development versions (Git), this is set to 0 (LWIP_RC_DEVELOPMENT) */ -#define LWIP_VERSION_RC ${LWIP_VERSION_RC} - -/** LWIP_VERSION_RC is set to LWIP_RC_RELEASE for official releases */ -#define LWIP_RC_RELEASE 255 -/** LWIP_VERSION_RC is set to LWIP_RC_DEVELOPMENT for Git versions */ -#define LWIP_RC_DEVELOPMENT 0 - -#define LWIP_VERSION_IS_RELEASE (LWIP_VERSION_RC == LWIP_RC_RELEASE) -#define LWIP_VERSION_IS_DEVELOPMENT (LWIP_VERSION_RC == LWIP_RC_DEVELOPMENT) -#define LWIP_VERSION_IS_RC ((LWIP_VERSION_RC != LWIP_RC_RELEASE) && (LWIP_VERSION_RC != LWIP_RC_DEVELOPMENT)) - -/* Some helper defines to get a version string */ -#define LWIP_VERSTR2(x) #x -#define LWIP_VERSTR(x) LWIP_VERSTR2(x) -#if LWIP_VERSION_IS_RELEASE -#define LWIP_VERSION_STRING_SUFFIX "" -#elif LWIP_VERSION_IS_DEVELOPMENT -#define LWIP_VERSION_STRING_SUFFIX "d" -#else -#define LWIP_VERSION_STRING_SUFFIX "rc" LWIP_VERSTR(LWIP_VERSION_RC) -#endif - -/** Provides the version of the stack */ -#define LWIP_VERSION ((LWIP_VERSION_MAJOR) << 24 | (LWIP_VERSION_MINOR) << 16 | \ - (LWIP_VERSION_REVISION) << 8 | (LWIP_VERSION_RC)) -/** Provides the version of the stack as string */ -#define LWIP_VERSION_STRING LWIP_VERSTR(LWIP_VERSION_MAJOR) "." LWIP_VERSTR(LWIP_VERSION_MINOR) "." LWIP_VERSTR(LWIP_VERSION_REVISION) LWIP_VERSION_STRING_SUFFIX - -/** - * @} - */ - -/* Modules initialization */ -void lwip_init(void); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_INIT_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/ip.h b/third-party/lwip-2.1.2/include/lwip/ip.h deleted file mode 100644 index 653c3b2f..00000000 --- a/third-party/lwip-2.1.2/include/lwip/ip.h +++ /dev/null @@ -1,330 +0,0 @@ -/** - * @file - * IP API - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_IP_H -#define LWIP_HDR_IP_H - -#include "lwip/opt.h" - -#include "lwip/def.h" -#include "lwip/pbuf.h" -#include "lwip/ip_addr.h" -#include "lwip/err.h" -#include "lwip/netif.h" -#include "lwip/ip4.h" -#include "lwip/ip6.h" -#include "lwip/prot/ip.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* This is passed as the destination address to ip_output_if (not - to ip_output), meaning that an IP header already is constructed - in the pbuf. This is used when TCP retransmits. */ -#define LWIP_IP_HDRINCL NULL - -/** pbufs passed to IP must have a ref-count of 1 as their payload pointer - gets altered as the packet is passed down the stack */ -#ifndef LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX -#define LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p) LWIP_ASSERT("p->ref == 1", (p)->ref == 1) -#endif - -#if LWIP_NETIF_USE_HINTS -#define IP_PCB_NETIFHINT ;struct netif_hint netif_hints -#else /* LWIP_NETIF_USE_HINTS */ -#define IP_PCB_NETIFHINT -#endif /* LWIP_NETIF_USE_HINTS */ - -/** This is the common part of all PCB types. It needs to be at the - beginning of a PCB type definition. It is located here so that - changes to this common part are made in one location instead of - having to change all PCB structs. */ -#define IP_PCB \ - /* ip addresses in network byte order */ \ - ip_addr_t local_ip; \ - ip_addr_t remote_ip; \ - /* Bound netif index */ \ - u8_t netif_idx; \ - /* Socket options */ \ - u8_t so_options; \ - /* Type Of Service */ \ - u8_t tos; \ - /* Time To Live */ \ - u8_t ttl \ - /* link layer address resolution hint */ \ - IP_PCB_NETIFHINT - -struct ip_pcb { - /* Common members of all PCB types */ - IP_PCB; -}; - -/* - * Option flags per-socket. These are the same like SO_XXX in sockets.h - */ -#define SOF_REUSEADDR 0x04U /* allow local address reuse */ -#define SOF_KEEPALIVE 0x08U /* keep connections alive */ -#define SOF_BROADCAST 0x20U /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */ - -/* These flags are inherited (e.g. from a listen-pcb to a connection-pcb): */ -#define SOF_INHERITED (SOF_REUSEADDR|SOF_KEEPALIVE) - -/** Global variables of this module, kept in a struct for efficient access using base+index. */ -struct ip_globals -{ - /** The interface that accepted the packet for the current callback invocation. */ - struct netif *current_netif; - /** The interface that received the packet for the current callback invocation. */ - struct netif *current_input_netif; -#if LWIP_IPV4 - /** Header of the input packet currently being processed. */ - const struct ip_hdr *current_ip4_header; -#endif /* LWIP_IPV4 */ -#if LWIP_IPV6 - /** Header of the input IPv6 packet currently being processed. */ - struct ip6_hdr *current_ip6_header; -#endif /* LWIP_IPV6 */ - /** Total header length of current_ip4/6_header (i.e. after this, the UDP/TCP header starts) */ - u16_t current_ip_header_tot_len; - /** Source IP address of current_header */ - ip_addr_t current_iphdr_src; - /** Destination IP address of current_header */ - ip_addr_t current_iphdr_dest; -}; -extern struct ip_globals ip_data; - - -/** Get the interface that accepted the current packet. - * This may or may not be the receiving netif, depending on your netif/network setup. - * This function must only be called from a receive callback (udp_recv, - * raw_recv, tcp_accept). It will return NULL otherwise. */ -#define ip_current_netif() (ip_data.current_netif) -/** Get the interface that received the current packet. - * This function must only be called from a receive callback (udp_recv, - * raw_recv, tcp_accept). It will return NULL otherwise. */ -#define ip_current_input_netif() (ip_data.current_input_netif) -/** Total header length of ip(6)_current_header() (i.e. after this, the UDP/TCP header starts) */ -#define ip_current_header_tot_len() (ip_data.current_ip_header_tot_len) -/** Source IP address of current_header */ -#define ip_current_src_addr() (&ip_data.current_iphdr_src) -/** Destination IP address of current_header */ -#define ip_current_dest_addr() (&ip_data.current_iphdr_dest) - -#if LWIP_IPV4 && LWIP_IPV6 -/** Get the IPv4 header of the current packet. - * This function must only be called from a receive callback (udp_recv, - * raw_recv, tcp_accept). It will return NULL otherwise. */ -#define ip4_current_header() ip_data.current_ip4_header -/** Get the IPv6 header of the current packet. - * This function must only be called from a receive callback (udp_recv, - * raw_recv, tcp_accept). It will return NULL otherwise. */ -#define ip6_current_header() ((const struct ip6_hdr*)(ip_data.current_ip6_header)) -/** Returns TRUE if the current IP input packet is IPv6, FALSE if it is IPv4 */ -#define ip_current_is_v6() (ip6_current_header() != NULL) -/** Source IPv6 address of current_header */ -#define ip6_current_src_addr() (ip_2_ip6(&ip_data.current_iphdr_src)) -/** Destination IPv6 address of current_header */ -#define ip6_current_dest_addr() (ip_2_ip6(&ip_data.current_iphdr_dest)) -/** Get the transport layer protocol */ -#define ip_current_header_proto() (ip_current_is_v6() ? \ - IP6H_NEXTH(ip6_current_header()) :\ - IPH_PROTO(ip4_current_header())) -/** Get the transport layer header */ -#define ip_next_header_ptr() ((const void*)((ip_current_is_v6() ? \ - (const u8_t*)ip6_current_header() : (const u8_t*)ip4_current_header()) + ip_current_header_tot_len())) - -/** Source IP4 address of current_header */ -#define ip4_current_src_addr() (ip_2_ip4(&ip_data.current_iphdr_src)) -/** Destination IP4 address of current_header */ -#define ip4_current_dest_addr() (ip_2_ip4(&ip_data.current_iphdr_dest)) - -#elif LWIP_IPV4 /* LWIP_IPV4 && LWIP_IPV6 */ - -/** Get the IPv4 header of the current packet. - * This function must only be called from a receive callback (udp_recv, - * raw_recv, tcp_accept). It will return NULL otherwise. */ -#define ip4_current_header() ip_data.current_ip4_header -/** Always returns FALSE when only supporting IPv4 only */ -#define ip_current_is_v6() 0 -/** Get the transport layer protocol */ -#define ip_current_header_proto() IPH_PROTO(ip4_current_header()) -/** Get the transport layer header */ -#define ip_next_header_ptr() ((const void*)((const u8_t*)ip4_current_header() + ip_current_header_tot_len())) -/** Source IP4 address of current_header */ -#define ip4_current_src_addr() (&ip_data.current_iphdr_src) -/** Destination IP4 address of current_header */ -#define ip4_current_dest_addr() (&ip_data.current_iphdr_dest) - -#elif LWIP_IPV6 /* LWIP_IPV4 && LWIP_IPV6 */ - -/** Get the IPv6 header of the current packet. - * This function must only be called from a receive callback (udp_recv, - * raw_recv, tcp_accept). It will return NULL otherwise. */ -#define ip6_current_header() ((const struct ip6_hdr*)(ip_data.current_ip6_header)) -/** Always returns TRUE when only supporting IPv6 only */ -#define ip_current_is_v6() 1 -/** Get the transport layer protocol */ -#define ip_current_header_proto() IP6H_NEXTH(ip6_current_header()) -/** Get the transport layer header */ -#define ip_next_header_ptr() ((const void*)(((const u8_t*)ip6_current_header()) + ip_current_header_tot_len())) -/** Source IP6 address of current_header */ -#define ip6_current_src_addr() (&ip_data.current_iphdr_src) -/** Destination IP6 address of current_header */ -#define ip6_current_dest_addr() (&ip_data.current_iphdr_dest) - -#endif /* LWIP_IPV6 */ - -/** Union source address of current_header */ -#define ip_current_src_addr() (&ip_data.current_iphdr_src) -/** Union destination address of current_header */ -#define ip_current_dest_addr() (&ip_data.current_iphdr_dest) - -/** Gets an IP pcb option (SOF_* flags) */ -#define ip_get_option(pcb, opt) ((pcb)->so_options & (opt)) -/** Sets an IP pcb option (SOF_* flags) */ -#define ip_set_option(pcb, opt) ((pcb)->so_options = (u8_t)((pcb)->so_options | (opt))) -/** Resets an IP pcb option (SOF_* flags) */ -#define ip_reset_option(pcb, opt) ((pcb)->so_options = (u8_t)((pcb)->so_options & ~(opt))) - -#if LWIP_IPV4 && LWIP_IPV6 -/** - * @ingroup ip - * Output IP packet, netif is selected by source address - */ -#define ip_output(p, src, dest, ttl, tos, proto) \ - (IP_IS_V6(dest) ? \ - ip6_output(p, ip_2_ip6(src), ip_2_ip6(dest), ttl, tos, proto) : \ - ip4_output(p, ip_2_ip4(src), ip_2_ip4(dest), ttl, tos, proto)) -/** - * @ingroup ip - * Output IP packet to specified interface - */ -#define ip_output_if(p, src, dest, ttl, tos, proto, netif) \ - (IP_IS_V6(dest) ? \ - ip6_output_if(p, ip_2_ip6(src), ip_2_ip6(dest), ttl, tos, proto, netif) : \ - ip4_output_if(p, ip_2_ip4(src), ip_2_ip4(dest), ttl, tos, proto, netif)) -/** - * @ingroup ip - * Output IP packet to interface specifying source address - */ -#define ip_output_if_src(p, src, dest, ttl, tos, proto, netif) \ - (IP_IS_V6(dest) ? \ - ip6_output_if_src(p, ip_2_ip6(src), ip_2_ip6(dest), ttl, tos, proto, netif) : \ - ip4_output_if_src(p, ip_2_ip4(src), ip_2_ip4(dest), ttl, tos, proto, netif)) -/** Output IP packet that already includes an IP header. */ -#define ip_output_if_hdrincl(p, src, dest, netif) \ - (IP_IS_V6(dest) ? \ - ip6_output_if(p, ip_2_ip6(src), LWIP_IP_HDRINCL, 0, 0, 0, netif) : \ - ip4_output_if(p, ip_2_ip4(src), LWIP_IP_HDRINCL, 0, 0, 0, netif)) -/** Output IP packet with netif_hint */ -#define ip_output_hinted(p, src, dest, ttl, tos, proto, netif_hint) \ - (IP_IS_V6(dest) ? \ - ip6_output_hinted(p, ip_2_ip6(src), ip_2_ip6(dest), ttl, tos, proto, netif_hint) : \ - ip4_output_hinted(p, ip_2_ip4(src), ip_2_ip4(dest), ttl, tos, proto, netif_hint)) -/** - * @ingroup ip - * Get netif for address combination. See \ref ip6_route and \ref ip4_route - */ -#define ip_route(src, dest) \ - (IP_IS_V6(dest) ? \ - ip6_route(ip_2_ip6(src), ip_2_ip6(dest)) : \ - ip4_route_src(ip_2_ip4(src), ip_2_ip4(dest))) -/** - * @ingroup ip - * Get netif for IP. - */ -#define ip_netif_get_local_ip(netif, dest) (IP_IS_V6(dest) ? \ - ip6_netif_get_local_ip(netif, ip_2_ip6(dest)) : \ - ip4_netif_get_local_ip(netif)) -#define ip_debug_print(is_ipv6, p) ((is_ipv6) ? ip6_debug_print(p) : ip4_debug_print(p)) - -err_t ip_input(struct pbuf *p, struct netif *inp); - -#elif LWIP_IPV4 /* LWIP_IPV4 && LWIP_IPV6 */ - -#define ip_output(p, src, dest, ttl, tos, proto) \ - ip4_output(p, src, dest, ttl, tos, proto) -#define ip_output_if(p, src, dest, ttl, tos, proto, netif) \ - ip4_output_if(p, src, dest, ttl, tos, proto, netif) -#define ip_output_if_src(p, src, dest, ttl, tos, proto, netif) \ - ip4_output_if_src(p, src, dest, ttl, tos, proto, netif) -#define ip_output_hinted(p, src, dest, ttl, tos, proto, netif_hint) \ - ip4_output_hinted(p, src, dest, ttl, tos, proto, netif_hint) -#define ip_output_if_hdrincl(p, src, dest, netif) \ - ip4_output_if(p, src, LWIP_IP_HDRINCL, 0, 0, 0, netif) -#define ip_route(src, dest) \ - ip4_route_src(src, dest) -#define ip_netif_get_local_ip(netif, dest) \ - ip4_netif_get_local_ip(netif) -#define ip_debug_print(is_ipv6, p) ip4_debug_print(p) - -#define ip_input ip4_input - -#elif LWIP_IPV6 /* LWIP_IPV4 && LWIP_IPV6 */ - -#define ip_output(p, src, dest, ttl, tos, proto) \ - ip6_output(p, src, dest, ttl, tos, proto) -#define ip_output_if(p, src, dest, ttl, tos, proto, netif) \ - ip6_output_if(p, src, dest, ttl, tos, proto, netif) -#define ip_output_if_src(p, src, dest, ttl, tos, proto, netif) \ - ip6_output_if_src(p, src, dest, ttl, tos, proto, netif) -#define ip_output_hinted(p, src, dest, ttl, tos, proto, netif_hint) \ - ip6_output_hinted(p, src, dest, ttl, tos, proto, netif_hint) -#define ip_output_if_hdrincl(p, src, dest, netif) \ - ip6_output_if(p, src, LWIP_IP_HDRINCL, 0, 0, 0, netif) -#define ip_route(src, dest) \ - ip6_route(src, dest) -#define ip_netif_get_local_ip(netif, dest) \ - ip6_netif_get_local_ip(netif, dest) -#define ip_debug_print(is_ipv6, p) ip6_debug_print(p) - -#define ip_input ip6_input - -#endif /* LWIP_IPV6 */ - -#define ip_route_get_local_ip(src, dest, netif, ipaddr) do { \ - (netif) = ip_route(src, dest); \ - (ipaddr) = ip_netif_get_local_ip(netif, dest); \ -}while(0) - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_IP_H */ - - diff --git a/third-party/lwip-2.1.2/include/lwip/ip4.h b/third-party/lwip-2.1.2/include/lwip/ip4.h deleted file mode 100644 index fd35a336..00000000 --- a/third-party/lwip-2.1.2/include/lwip/ip4.h +++ /dev/null @@ -1,111 +0,0 @@ -/** - * @file - * IPv4 API - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_IP4_H -#define LWIP_HDR_IP4_H - -#include "lwip/opt.h" - -#if LWIP_IPV4 - -#include "lwip/def.h" -#include "lwip/pbuf.h" -#include "lwip/ip4_addr.h" -#include "lwip/err.h" -#include "lwip/netif.h" -#include "lwip/prot/ip4.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef LWIP_HOOK_IP4_ROUTE_SRC -#define LWIP_IPV4_SRC_ROUTING 1 -#else -#define LWIP_IPV4_SRC_ROUTING 0 -#endif - -/** Currently, the function ip_output_if_opt() is only used with IGMP */ -#define IP_OPTIONS_SEND (LWIP_IPV4 && LWIP_IGMP) - -#define ip_init() /* Compatibility define, no init needed. */ -struct netif *ip4_route(const ip4_addr_t *dest); -#if LWIP_IPV4_SRC_ROUTING -struct netif *ip4_route_src(const ip4_addr_t *src, const ip4_addr_t *dest); -#else /* LWIP_IPV4_SRC_ROUTING */ -#define ip4_route_src(src, dest) ip4_route(dest) -#endif /* LWIP_IPV4_SRC_ROUTING */ -err_t ip4_input(struct pbuf *p, struct netif *inp); -err_t ip4_output(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto); -err_t ip4_output_if(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, struct netif *netif); -err_t ip4_output_if_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, struct netif *netif); -#if LWIP_NETIF_USE_HINTS -err_t ip4_output_hinted(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, struct netif_hint *netif_hint); -#endif /* LWIP_NETIF_USE_HINTS */ -#if IP_OPTIONS_SEND -err_t ip4_output_if_opt(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options, - u16_t optlen); -err_t ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options, - u16_t optlen); -#endif /* IP_OPTIONS_SEND */ - -#if LWIP_MULTICAST_TX_OPTIONS -void ip4_set_default_multicast_netif(struct netif* default_multicast_netif); -#endif /* LWIP_MULTICAST_TX_OPTIONS */ - -#define ip4_netif_get_local_ip(netif) (((netif) != NULL) ? netif_ip_addr4(netif) : NULL) - -#if IP_DEBUG -void ip4_debug_print(struct pbuf *p); -#else -#define ip4_debug_print(p) -#endif /* IP_DEBUG */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV4 */ - -#endif /* LWIP_HDR_IP_H */ - - diff --git a/third-party/lwip-2.1.2/include/lwip/ip4_addr.h b/third-party/lwip-2.1.2/include/lwip/ip4_addr.h deleted file mode 100644 index f244c4f5..00000000 --- a/third-party/lwip-2.1.2/include/lwip/ip4_addr.h +++ /dev/null @@ -1,216 +0,0 @@ -/** - * @file - * IPv4 address API - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_IP4_ADDR_H -#define LWIP_HDR_IP4_ADDR_H - -#include "lwip/opt.h" -#include "lwip/def.h" - -#if LWIP_IPV4 - -#ifdef __cplusplus -extern "C" { -#endif - -/** This is the aligned version of ip4_addr_t, - used as local variable, on the stack, etc. */ -struct ip4_addr { - u32_t addr; -}; - -/** ip4_addr_t uses a struct for convenience only, so that the same defines can - * operate both on ip4_addr_t as well as on ip4_addr_p_t. */ -typedef struct ip4_addr ip4_addr_t; - -/* Forward declaration to not include netif.h */ -struct netif; - -/** 255.255.255.255 */ -#define IPADDR_NONE ((u32_t)0xffffffffUL) -/** 127.0.0.1 */ -#define IPADDR_LOOPBACK ((u32_t)0x7f000001UL) -/** 0.0.0.0 */ -#define IPADDR_ANY ((u32_t)0x00000000UL) -/** 255.255.255.255 */ -#define IPADDR_BROADCAST ((u32_t)0xffffffffUL) - -/* Definitions of the bits in an Internet address integer. - - On subnets, host and network parts are found according to - the subnet mask, not these masks. */ -#define IP_CLASSA(a) ((((u32_t)(a)) & 0x80000000UL) == 0) -#define IP_CLASSA_NET 0xff000000 -#define IP_CLASSA_NSHIFT 24 -#define IP_CLASSA_HOST (0xffffffff & ~IP_CLASSA_NET) -#define IP_CLASSA_MAX 128 - -#define IP_CLASSB(a) ((((u32_t)(a)) & 0xc0000000UL) == 0x80000000UL) -#define IP_CLASSB_NET 0xffff0000 -#define IP_CLASSB_NSHIFT 16 -#define IP_CLASSB_HOST (0xffffffff & ~IP_CLASSB_NET) -#define IP_CLASSB_MAX 65536 - -#define IP_CLASSC(a) ((((u32_t)(a)) & 0xe0000000UL) == 0xc0000000UL) -#define IP_CLASSC_NET 0xffffff00 -#define IP_CLASSC_NSHIFT 8 -#define IP_CLASSC_HOST (0xffffffff & ~IP_CLASSC_NET) - -#define IP_CLASSD(a) (((u32_t)(a) & 0xf0000000UL) == 0xe0000000UL) -#define IP_CLASSD_NET 0xf0000000 /* These ones aren't really */ -#define IP_CLASSD_NSHIFT 28 /* net and host fields, but */ -#define IP_CLASSD_HOST 0x0fffffff /* routing needn't know. */ -#define IP_MULTICAST(a) IP_CLASSD(a) - -#define IP_EXPERIMENTAL(a) (((u32_t)(a) & 0xf0000000UL) == 0xf0000000UL) -#define IP_BADCLASS(a) (((u32_t)(a) & 0xf0000000UL) == 0xf0000000UL) - -#define IP_LOOPBACKNET 127 /* official! */ - -/** Set an IP address given by the four byte-parts */ -#define IP4_ADDR(ipaddr, a,b,c,d) (ipaddr)->addr = PP_HTONL(LWIP_MAKEU32(a,b,c,d)) - -/** Copy IP address - faster than ip4_addr_set: no NULL check */ -#define ip4_addr_copy(dest, src) ((dest).addr = (src).addr) -/** Safely copy one IP address to another (src may be NULL) */ -#define ip4_addr_set(dest, src) ((dest)->addr = \ - ((src) == NULL ? 0 : \ - (src)->addr)) -/** Set complete address to zero */ -#define ip4_addr_set_zero(ipaddr) ((ipaddr)->addr = 0) -/** Set address to IPADDR_ANY (no need for lwip_htonl()) */ -#define ip4_addr_set_any(ipaddr) ((ipaddr)->addr = IPADDR_ANY) -/** Set address to loopback address */ -#define ip4_addr_set_loopback(ipaddr) ((ipaddr)->addr = PP_HTONL(IPADDR_LOOPBACK)) -/** Check if an address is in the loopback region */ -#define ip4_addr_isloopback(ipaddr) (((ipaddr)->addr & PP_HTONL(IP_CLASSA_NET)) == PP_HTONL(((u32_t)IP_LOOPBACKNET) << 24)) -/** Safely copy one IP address to another and change byte order - * from host- to network-order. */ -#define ip4_addr_set_hton(dest, src) ((dest)->addr = \ - ((src) == NULL ? 0:\ - lwip_htonl((src)->addr))) -/** IPv4 only: set the IP address given as an u32_t */ -#define ip4_addr_set_u32(dest_ipaddr, src_u32) ((dest_ipaddr)->addr = (src_u32)) -/** IPv4 only: get the IP address as an u32_t */ -#define ip4_addr_get_u32(src_ipaddr) ((src_ipaddr)->addr) - -/** Get the network address by combining host address with netmask */ -#define ip4_addr_get_network(target, host, netmask) do { ((target)->addr = ((host)->addr) & ((netmask)->addr)); } while(0) - -/** - * Determine if two address are on the same network. - * - * @arg addr1 IP address 1 - * @arg addr2 IP address 2 - * @arg mask network identifier mask - * @return !0 if the network identifiers of both address match - */ -#define ip4_addr_netcmp(addr1, addr2, mask) (((addr1)->addr & \ - (mask)->addr) == \ - ((addr2)->addr & \ - (mask)->addr)) -#define ip4_addr_cmp(addr1, addr2) ((addr1)->addr == (addr2)->addr) - -#define ip4_addr_isany_val(addr1) ((addr1).addr == IPADDR_ANY) -#define ip4_addr_isany(addr1) ((addr1) == NULL || ip4_addr_isany_val(*(addr1))) - -#define ip4_addr_isbroadcast(addr1, netif) ip4_addr_isbroadcast_u32((addr1)->addr, netif) -u8_t ip4_addr_isbroadcast_u32(u32_t addr, const struct netif *netif); - -#define ip_addr_netmask_valid(netmask) ip4_addr_netmask_valid((netmask)->addr) -u8_t ip4_addr_netmask_valid(u32_t netmask); - -#define ip4_addr_ismulticast(addr1) (((addr1)->addr & PP_HTONL(0xf0000000UL)) == PP_HTONL(0xe0000000UL)) - -#define ip4_addr_islinklocal(addr1) (((addr1)->addr & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xa9fe0000UL)) - -#define ip4_addr_debug_print_parts(debug, a, b, c, d) \ - LWIP_DEBUGF(debug, ("%" U16_F ".%" U16_F ".%" U16_F ".%" U16_F, a, b, c, d)) -#define ip4_addr_debug_print(debug, ipaddr) \ - ip4_addr_debug_print_parts(debug, \ - (u16_t)((ipaddr) != NULL ? ip4_addr1_16(ipaddr) : 0), \ - (u16_t)((ipaddr) != NULL ? ip4_addr2_16(ipaddr) : 0), \ - (u16_t)((ipaddr) != NULL ? ip4_addr3_16(ipaddr) : 0), \ - (u16_t)((ipaddr) != NULL ? ip4_addr4_16(ipaddr) : 0)) -#define ip4_addr_debug_print_val(debug, ipaddr) \ - ip4_addr_debug_print_parts(debug, \ - ip4_addr1_16_val(ipaddr), \ - ip4_addr2_16_val(ipaddr), \ - ip4_addr3_16_val(ipaddr), \ - ip4_addr4_16_val(ipaddr)) - -/* Get one byte from the 4-byte address */ -#define ip4_addr_get_byte(ipaddr, idx) (((const u8_t*)(&(ipaddr)->addr))[idx]) -#define ip4_addr1(ipaddr) ip4_addr_get_byte(ipaddr, 0) -#define ip4_addr2(ipaddr) ip4_addr_get_byte(ipaddr, 1) -#define ip4_addr3(ipaddr) ip4_addr_get_byte(ipaddr, 2) -#define ip4_addr4(ipaddr) ip4_addr_get_byte(ipaddr, 3) -/* Get one byte from the 4-byte address, but argument is 'ip4_addr_t', - * not a pointer */ -#define ip4_addr_get_byte_val(ipaddr, idx) ((u8_t)(((ipaddr).addr >> (idx * 8)) & 0xff)) -#define ip4_addr1_val(ipaddr) ip4_addr_get_byte_val(ipaddr, 0) -#define ip4_addr2_val(ipaddr) ip4_addr_get_byte_val(ipaddr, 1) -#define ip4_addr3_val(ipaddr) ip4_addr_get_byte_val(ipaddr, 2) -#define ip4_addr4_val(ipaddr) ip4_addr_get_byte_val(ipaddr, 3) -/* These are cast to u16_t, with the intent that they are often arguments - * to printf using the U16_F format from cc.h. */ -#define ip4_addr1_16(ipaddr) ((u16_t)ip4_addr1(ipaddr)) -#define ip4_addr2_16(ipaddr) ((u16_t)ip4_addr2(ipaddr)) -#define ip4_addr3_16(ipaddr) ((u16_t)ip4_addr3(ipaddr)) -#define ip4_addr4_16(ipaddr) ((u16_t)ip4_addr4(ipaddr)) -#define ip4_addr1_16_val(ipaddr) ((u16_t)ip4_addr1_val(ipaddr)) -#define ip4_addr2_16_val(ipaddr) ((u16_t)ip4_addr2_val(ipaddr)) -#define ip4_addr3_16_val(ipaddr) ((u16_t)ip4_addr3_val(ipaddr)) -#define ip4_addr4_16_val(ipaddr) ((u16_t)ip4_addr4_val(ipaddr)) - -#define IP4ADDR_STRLEN_MAX 16 - -/** For backwards compatibility */ -#define ip_ntoa(ipaddr) ipaddr_ntoa(ipaddr) - -u32_t ipaddr_addr(const char *cp); -int ip4addr_aton(const char *cp, ip4_addr_t *addr); -/** returns ptr to static buffer; not reentrant! */ -char *ip4addr_ntoa(const ip4_addr_t *addr); -char *ip4addr_ntoa_r(const ip4_addr_t *addr, char *buf, int buflen); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV4 */ - -#endif /* LWIP_HDR_IP_ADDR_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/ip4_frag.h b/third-party/lwip-2.1.2/include/lwip/ip4_frag.h deleted file mode 100644 index ed5bf14a..00000000 --- a/third-party/lwip-2.1.2/include/lwip/ip4_frag.h +++ /dev/null @@ -1,100 +0,0 @@ -/** - * @file - * IP fragmentation/reassembly - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Jani Monoses - * - */ - -#ifndef LWIP_HDR_IP4_FRAG_H -#define LWIP_HDR_IP4_FRAG_H - -#include "lwip/opt.h" -#include "lwip/err.h" -#include "lwip/pbuf.h" -#include "lwip/netif.h" -#include "lwip/ip_addr.h" -#include "lwip/ip.h" - -#if LWIP_IPV4 - -#ifdef __cplusplus -extern "C" { -#endif - -#if IP_REASSEMBLY -/* The IP reassembly timer interval in milliseconds. */ -#define IP_TMR_INTERVAL 1000 - -/** IP reassembly helper struct. - * This is exported because memp needs to know the size. - */ -struct ip_reassdata { - struct ip_reassdata *next; - struct pbuf *p; - struct ip_hdr iphdr; - u16_t datagram_len; - u8_t flags; - u8_t timer; -}; - -void ip_reass_init(void); -void ip_reass_tmr(void); -struct pbuf * ip4_reass(struct pbuf *p); -#endif /* IP_REASSEMBLY */ - -#if IP_FRAG -#if !LWIP_NETIF_TX_SINGLE_PBUF -#ifndef LWIP_PBUF_CUSTOM_REF_DEFINED -#define LWIP_PBUF_CUSTOM_REF_DEFINED -/** A custom pbuf that holds a reference to another pbuf, which is freed - * when this custom pbuf is freed. This is used to create a custom PBUF_REF - * that points into the original pbuf. */ -struct pbuf_custom_ref { - /** 'base class' */ - struct pbuf_custom pc; - /** pointer to the original pbuf that is referenced */ - struct pbuf *original; -}; -#endif /* LWIP_PBUF_CUSTOM_REF_DEFINED */ -#endif /* !LWIP_NETIF_TX_SINGLE_PBUF */ - -err_t ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest); -#endif /* IP_FRAG */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV4 */ - -#endif /* LWIP_HDR_IP4_FRAG_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/ip6.h b/third-party/lwip-2.1.2/include/lwip/ip6.h deleted file mode 100644 index f894e063..00000000 --- a/third-party/lwip-2.1.2/include/lwip/ip6.h +++ /dev/null @@ -1,93 +0,0 @@ -/** - * @file - * - * IPv6 layer. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ -#ifndef LWIP_HDR_IP6_H -#define LWIP_HDR_IP6_H - -#include "lwip/opt.h" - -#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/ip6_addr.h" -#include "lwip/prot/ip6.h" -#include "lwip/def.h" -#include "lwip/pbuf.h" -#include "lwip/netif.h" - -#include "lwip/err.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct netif *ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest); -const ip_addr_t *ip6_select_source_address(struct netif *netif, const ip6_addr_t * dest); -err_t ip6_input(struct pbuf *p, struct netif *inp); -err_t ip6_output(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest, - u8_t hl, u8_t tc, u8_t nexth); -err_t ip6_output_if(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest, - u8_t hl, u8_t tc, u8_t nexth, struct netif *netif); -err_t ip6_output_if_src(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest, - u8_t hl, u8_t tc, u8_t nexth, struct netif *netif); -#if LWIP_NETIF_USE_HINTS -err_t ip6_output_hinted(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest, - u8_t hl, u8_t tc, u8_t nexth, struct netif_hint *netif_hint); -#endif /* LWIP_NETIF_USE_HINTS */ -#if LWIP_IPV6_MLD -err_t ip6_options_add_hbh_ra(struct pbuf * p, u8_t nexth, u8_t value); -#endif /* LWIP_IPV6_MLD */ - -#define ip6_netif_get_local_ip(netif, dest) (((netif) != NULL) ? \ - ip6_select_source_address(netif, dest) : NULL) - -#if IP6_DEBUG -void ip6_debug_print(struct pbuf *p); -#else -#define ip6_debug_print(p) -#endif /* IP6_DEBUG */ - - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV6 */ - -#endif /* LWIP_HDR_IP6_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/ip6_addr.h b/third-party/lwip-2.1.2/include/lwip/ip6_addr.h deleted file mode 100644 index 29c2a34d..00000000 --- a/third-party/lwip-2.1.2/include/lwip/ip6_addr.h +++ /dev/null @@ -1,352 +0,0 @@ -/** - * @file - * - * IPv6 addresses. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * Structs and macros for handling IPv6 addresses. - * - * Please coordinate changes and requests with Ivan Delamer - * - */ -#ifndef LWIP_HDR_IP6_ADDR_H -#define LWIP_HDR_IP6_ADDR_H - -#include "lwip/opt.h" -#include "def.h" - -#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/ip6_zone.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -/** This is the aligned version of ip6_addr_t, - used as local variable, on the stack, etc. */ -struct ip6_addr { - u32_t addr[4]; -#if LWIP_IPV6_SCOPES - u8_t zone; -#endif /* LWIP_IPV6_SCOPES */ -}; - -/** IPv6 address */ -typedef struct ip6_addr ip6_addr_t; - -/** Set an IPv6 partial address given by byte-parts */ -#define IP6_ADDR_PART(ip6addr, index, a,b,c,d) \ - (ip6addr)->addr[index] = PP_HTONL(LWIP_MAKEU32(a,b,c,d)) - -/** Set a full IPv6 address by passing the 4 u32_t indices in network byte order - (use PP_HTONL() for constants) */ -#define IP6_ADDR(ip6addr, idx0, idx1, idx2, idx3) do { \ - (ip6addr)->addr[0] = idx0; \ - (ip6addr)->addr[1] = idx1; \ - (ip6addr)->addr[2] = idx2; \ - (ip6addr)->addr[3] = idx3; \ - ip6_addr_clear_zone(ip6addr); } while(0) - -/** Access address in 16-bit block */ -#define IP6_ADDR_BLOCK1(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[0]) >> 16) & 0xffff)) -/** Access address in 16-bit block */ -#define IP6_ADDR_BLOCK2(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[0])) & 0xffff)) -/** Access address in 16-bit block */ -#define IP6_ADDR_BLOCK3(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[1]) >> 16) & 0xffff)) -/** Access address in 16-bit block */ -#define IP6_ADDR_BLOCK4(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[1])) & 0xffff)) -/** Access address in 16-bit block */ -#define IP6_ADDR_BLOCK5(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[2]) >> 16) & 0xffff)) -/** Access address in 16-bit block */ -#define IP6_ADDR_BLOCK6(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[2])) & 0xffff)) -/** Access address in 16-bit block */ -#define IP6_ADDR_BLOCK7(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[3]) >> 16) & 0xffff)) -/** Access address in 16-bit block */ -#define IP6_ADDR_BLOCK8(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[3])) & 0xffff)) - -/** Copy IPv6 address - faster than ip6_addr_set: no NULL check */ -#define ip6_addr_copy(dest, src) do{(dest).addr[0] = (src).addr[0]; \ - (dest).addr[1] = (src).addr[1]; \ - (dest).addr[2] = (src).addr[2]; \ - (dest).addr[3] = (src).addr[3]; \ - ip6_addr_copy_zone((dest), (src)); }while(0) -/** Safely copy one IPv6 address to another (src may be NULL) */ -#define ip6_addr_set(dest, src) do{(dest)->addr[0] = (src) == NULL ? 0 : (src)->addr[0]; \ - (dest)->addr[1] = (src) == NULL ? 0 : (src)->addr[1]; \ - (dest)->addr[2] = (src) == NULL ? 0 : (src)->addr[2]; \ - (dest)->addr[3] = (src) == NULL ? 0 : (src)->addr[3]; \ - ip6_addr_set_zone((dest), (src) == NULL ? IP6_NO_ZONE : ip6_addr_zone(src)); }while(0) - -/** Copy packed IPv6 address to unpacked IPv6 address; zone is not set */ -#define ip6_addr_copy_from_packed(dest, src) do{(dest).addr[0] = (src).addr[0]; \ - (dest).addr[1] = (src).addr[1]; \ - (dest).addr[2] = (src).addr[2]; \ - (dest).addr[3] = (src).addr[3]; \ - ip6_addr_clear_zone(&dest); }while(0) - -/** Copy unpacked IPv6 address to packed IPv6 address; zone is lost */ -#define ip6_addr_copy_to_packed(dest, src) do{(dest).addr[0] = (src).addr[0]; \ - (dest).addr[1] = (src).addr[1]; \ - (dest).addr[2] = (src).addr[2]; \ - (dest).addr[3] = (src).addr[3]; }while(0) - -/** Set complete address to zero */ -#define ip6_addr_set_zero(ip6addr) do{(ip6addr)->addr[0] = 0; \ - (ip6addr)->addr[1] = 0; \ - (ip6addr)->addr[2] = 0; \ - (ip6addr)->addr[3] = 0; \ - ip6_addr_clear_zone(ip6addr);}while(0) - -/** Set address to ipv6 'any' (no need for lwip_htonl()) */ -#define ip6_addr_set_any(ip6addr) ip6_addr_set_zero(ip6addr) -/** Set address to ipv6 loopback address */ -#define ip6_addr_set_loopback(ip6addr) do{(ip6addr)->addr[0] = 0; \ - (ip6addr)->addr[1] = 0; \ - (ip6addr)->addr[2] = 0; \ - (ip6addr)->addr[3] = PP_HTONL(0x00000001UL); \ - ip6_addr_clear_zone(ip6addr);}while(0) -/** Safely copy one IPv6 address to another and change byte order - * from host- to network-order. */ -#define ip6_addr_set_hton(dest, src) do{(dest)->addr[0] = (src) == NULL ? 0 : lwip_htonl((src)->addr[0]); \ - (dest)->addr[1] = (src) == NULL ? 0 : lwip_htonl((src)->addr[1]); \ - (dest)->addr[2] = (src) == NULL ? 0 : lwip_htonl((src)->addr[2]); \ - (dest)->addr[3] = (src) == NULL ? 0 : lwip_htonl((src)->addr[3]); \ - ip6_addr_set_zone((dest), (src) == NULL ? IP6_NO_ZONE : ip6_addr_zone(src));}while(0) - - -/** Compare IPv6 networks, ignoring zone information. To be used sparingly! */ -#define ip6_addr_netcmp_zoneless(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \ - ((addr1)->addr[1] == (addr2)->addr[1])) - -/** - * Determine if two IPv6 address are on the same network. - * - * @param addr1 IPv6 address 1 - * @param addr2 IPv6 address 2 - * @return 1 if the network identifiers of both address match, 0 if not - */ -#define ip6_addr_netcmp(addr1, addr2) (ip6_addr_netcmp_zoneless((addr1), (addr2)) && \ - ip6_addr_cmp_zone((addr1), (addr2))) - -/* Exact-host comparison *after* ip6_addr_netcmp() succeeded, for efficiency. */ -#define ip6_addr_nethostcmp(addr1, addr2) (((addr1)->addr[2] == (addr2)->addr[2]) && \ - ((addr1)->addr[3] == (addr2)->addr[3])) - -/** Compare IPv6 addresses, ignoring zone information. To be used sparingly! */ -#define ip6_addr_cmp_zoneless(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \ - ((addr1)->addr[1] == (addr2)->addr[1]) && \ - ((addr1)->addr[2] == (addr2)->addr[2]) && \ - ((addr1)->addr[3] == (addr2)->addr[3])) -/** - * Determine if two IPv6 addresses are the same. In particular, the address - * part of both must be the same, and the zone must be compatible. - * - * @param addr1 IPv6 address 1 - * @param addr2 IPv6 address 2 - * @return 1 if the addresses are considered equal, 0 if not - */ -#define ip6_addr_cmp(addr1, addr2) (ip6_addr_cmp_zoneless((addr1), (addr2)) && \ - ip6_addr_cmp_zone((addr1), (addr2))) - -/** Compare IPv6 address to packed address and zone */ -#define ip6_addr_cmp_packed(ip6addr, paddr, zone_idx) (((ip6addr)->addr[0] == (paddr)->addr[0]) && \ - ((ip6addr)->addr[1] == (paddr)->addr[1]) && \ - ((ip6addr)->addr[2] == (paddr)->addr[2]) && \ - ((ip6addr)->addr[3] == (paddr)->addr[3]) && \ - ip6_addr_equals_zone((ip6addr), (zone_idx))) - -#define ip6_get_subnet_id(ip6addr) (lwip_htonl((ip6addr)->addr[2]) & 0x0000ffffUL) - -#define ip6_addr_isany_val(ip6addr) (((ip6addr).addr[0] == 0) && \ - ((ip6addr).addr[1] == 0) && \ - ((ip6addr).addr[2] == 0) && \ - ((ip6addr).addr[3] == 0)) -#define ip6_addr_isany(ip6addr) (((ip6addr) == NULL) || ip6_addr_isany_val(*(ip6addr))) - -#define ip6_addr_isloopback(ip6addr) (((ip6addr)->addr[0] == 0UL) && \ - ((ip6addr)->addr[1] == 0UL) && \ - ((ip6addr)->addr[2] == 0UL) && \ - ((ip6addr)->addr[3] == PP_HTONL(0x00000001UL))) - -#define ip6_addr_isglobal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xe0000000UL)) == PP_HTONL(0x20000000UL)) - -#define ip6_addr_islinklocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffc00000UL)) == PP_HTONL(0xfe800000UL)) - -#define ip6_addr_issitelocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffc00000UL)) == PP_HTONL(0xfec00000UL)) - -#define ip6_addr_isuniquelocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xfe000000UL)) == PP_HTONL(0xfc000000UL)) - -#define ip6_addr_isipv4mappedipv6(ip6addr) (((ip6addr)->addr[0] == 0) && ((ip6addr)->addr[1] == 0) && (((ip6addr)->addr[2]) == PP_HTONL(0x0000FFFFUL))) - -#define ip6_addr_ismulticast(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff000000UL)) == PP_HTONL(0xff000000UL)) -#define ip6_addr_multicast_transient_flag(ip6addr) ((ip6addr)->addr[0] & PP_HTONL(0x00100000UL)) -#define ip6_addr_multicast_prefix_flag(ip6addr) ((ip6addr)->addr[0] & PP_HTONL(0x00200000UL)) -#define ip6_addr_multicast_rendezvous_flag(ip6addr) ((ip6addr)->addr[0] & PP_HTONL(0x00400000UL)) -#define ip6_addr_multicast_scope(ip6addr) ((lwip_htonl((ip6addr)->addr[0]) >> 16) & 0xf) -#define IP6_MULTICAST_SCOPE_RESERVED 0x0 -#define IP6_MULTICAST_SCOPE_RESERVED0 0x0 -#define IP6_MULTICAST_SCOPE_INTERFACE_LOCAL 0x1 -#define IP6_MULTICAST_SCOPE_LINK_LOCAL 0x2 -#define IP6_MULTICAST_SCOPE_RESERVED3 0x3 -#define IP6_MULTICAST_SCOPE_ADMIN_LOCAL 0x4 -#define IP6_MULTICAST_SCOPE_SITE_LOCAL 0x5 -#define IP6_MULTICAST_SCOPE_ORGANIZATION_LOCAL 0x8 -#define IP6_MULTICAST_SCOPE_GLOBAL 0xe -#define IP6_MULTICAST_SCOPE_RESERVEDF 0xf -#define ip6_addr_ismulticast_iflocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff8f0000UL)) == PP_HTONL(0xff010000UL)) -#define ip6_addr_ismulticast_linklocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff8f0000UL)) == PP_HTONL(0xff020000UL)) -#define ip6_addr_ismulticast_adminlocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff8f0000UL)) == PP_HTONL(0xff040000UL)) -#define ip6_addr_ismulticast_sitelocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff8f0000UL)) == PP_HTONL(0xff050000UL)) -#define ip6_addr_ismulticast_orglocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff8f0000UL)) == PP_HTONL(0xff080000UL)) -#define ip6_addr_ismulticast_global(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff8f0000UL)) == PP_HTONL(0xff0e0000UL)) - -/* Scoping note: while interface-local and link-local multicast addresses do - * have a scope (i.e., they are meaningful only in the context of a particular - * interface), the following functions are not assigning or comparing zone - * indices. The reason for this is backward compatibility. Any call site that - * produces a non-global multicast address must assign a multicast address as - * appropriate itself. */ - -#define ip6_addr_isallnodes_iflocal(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xff010000UL)) && \ - ((ip6addr)->addr[1] == 0UL) && \ - ((ip6addr)->addr[2] == 0UL) && \ - ((ip6addr)->addr[3] == PP_HTONL(0x00000001UL))) - -#define ip6_addr_isallnodes_linklocal(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \ - ((ip6addr)->addr[1] == 0UL) && \ - ((ip6addr)->addr[2] == 0UL) && \ - ((ip6addr)->addr[3] == PP_HTONL(0x00000001UL))) -#define ip6_addr_set_allnodes_linklocal(ip6addr) do{(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \ - (ip6addr)->addr[1] = 0; \ - (ip6addr)->addr[2] = 0; \ - (ip6addr)->addr[3] = PP_HTONL(0x00000001UL); \ - ip6_addr_clear_zone(ip6addr); }while(0) - -#define ip6_addr_isallrouters_linklocal(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \ - ((ip6addr)->addr[1] == 0UL) && \ - ((ip6addr)->addr[2] == 0UL) && \ - ((ip6addr)->addr[3] == PP_HTONL(0x00000002UL))) -#define ip6_addr_set_allrouters_linklocal(ip6addr) do{(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \ - (ip6addr)->addr[1] = 0; \ - (ip6addr)->addr[2] = 0; \ - (ip6addr)->addr[3] = PP_HTONL(0x00000002UL); \ - ip6_addr_clear_zone(ip6addr); }while(0) - -#define ip6_addr_issolicitednode(ip6addr) ( ((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \ - ((ip6addr)->addr[2] == PP_HTONL(0x00000001UL)) && \ - (((ip6addr)->addr[3] & PP_HTONL(0xff000000UL)) == PP_HTONL(0xff000000UL)) ) - -#define ip6_addr_set_solicitednode(ip6addr, if_id) do{(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \ - (ip6addr)->addr[1] = 0; \ - (ip6addr)->addr[2] = PP_HTONL(0x00000001UL); \ - (ip6addr)->addr[3] = (PP_HTONL(0xff000000UL) | (if_id)); \ - ip6_addr_clear_zone(ip6addr); }while(0) - -#define ip6_addr_cmp_solicitednode(ip6addr, sn_addr) (((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \ - ((ip6addr)->addr[1] == 0) && \ - ((ip6addr)->addr[2] == PP_HTONL(0x00000001UL)) && \ - ((ip6addr)->addr[3] == (PP_HTONL(0xff000000UL) | (sn_addr)->addr[3]))) - -/* IPv6 address states. */ -#define IP6_ADDR_INVALID 0x00 -#define IP6_ADDR_TENTATIVE 0x08 -#define IP6_ADDR_TENTATIVE_1 0x09 /* 1 probe sent */ -#define IP6_ADDR_TENTATIVE_2 0x0a /* 2 probes sent */ -#define IP6_ADDR_TENTATIVE_3 0x0b /* 3 probes sent */ -#define IP6_ADDR_TENTATIVE_4 0x0c /* 4 probes sent */ -#define IP6_ADDR_TENTATIVE_5 0x0d /* 5 probes sent */ -#define IP6_ADDR_TENTATIVE_6 0x0e /* 6 probes sent */ -#define IP6_ADDR_TENTATIVE_7 0x0f /* 7 probes sent */ -#define IP6_ADDR_VALID 0x10 /* This bit marks an address as valid (preferred or deprecated) */ -#define IP6_ADDR_PREFERRED 0x30 -#define IP6_ADDR_DEPRECATED 0x10 /* Same as VALID (valid but not preferred) */ -#define IP6_ADDR_DUPLICATED 0x40 /* Failed DAD test, not valid */ - -#define IP6_ADDR_TENTATIVE_COUNT_MASK 0x07 /* 1-7 probes sent */ - -#define ip6_addr_isinvalid(addr_state) (addr_state == IP6_ADDR_INVALID) -#define ip6_addr_istentative(addr_state) (addr_state & IP6_ADDR_TENTATIVE) -#define ip6_addr_isvalid(addr_state) (addr_state & IP6_ADDR_VALID) /* Include valid, preferred, and deprecated. */ -#define ip6_addr_ispreferred(addr_state) (addr_state == IP6_ADDR_PREFERRED) -#define ip6_addr_isdeprecated(addr_state) (addr_state == IP6_ADDR_DEPRECATED) -#define ip6_addr_isduplicated(addr_state) (addr_state == IP6_ADDR_DUPLICATED) - -#if LWIP_IPV6_ADDRESS_LIFETIMES -#define IP6_ADDR_LIFE_STATIC (0) -#define IP6_ADDR_LIFE_INFINITE (0xffffffffUL) -#define ip6_addr_life_isstatic(addr_life) ((addr_life) == IP6_ADDR_LIFE_STATIC) -#define ip6_addr_life_isinfinite(addr_life) ((addr_life) == IP6_ADDR_LIFE_INFINITE) -#endif /* LWIP_IPV6_ADDRESS_LIFETIMES */ - -#define ip6_addr_debug_print_parts(debug, a, b, c, d, e, f, g, h) \ - LWIP_DEBUGF(debug, ("%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F, \ - a, b, c, d, e, f, g, h)) -#define ip6_addr_debug_print(debug, ipaddr) \ - ip6_addr_debug_print_parts(debug, \ - (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK1(ipaddr) : 0), \ - (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK2(ipaddr) : 0), \ - (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK3(ipaddr) : 0), \ - (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK4(ipaddr) : 0), \ - (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK5(ipaddr) : 0), \ - (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK6(ipaddr) : 0), \ - (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK7(ipaddr) : 0), \ - (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK8(ipaddr) : 0)) -#define ip6_addr_debug_print_val(debug, ipaddr) \ - ip6_addr_debug_print_parts(debug, \ - IP6_ADDR_BLOCK1(&(ipaddr)), \ - IP6_ADDR_BLOCK2(&(ipaddr)), \ - IP6_ADDR_BLOCK3(&(ipaddr)), \ - IP6_ADDR_BLOCK4(&(ipaddr)), \ - IP6_ADDR_BLOCK5(&(ipaddr)), \ - IP6_ADDR_BLOCK6(&(ipaddr)), \ - IP6_ADDR_BLOCK7(&(ipaddr)), \ - IP6_ADDR_BLOCK8(&(ipaddr))) - -#define IP6ADDR_STRLEN_MAX 46 - -int ip6addr_aton(const char *cp, ip6_addr_t *addr); -/** returns ptr to static buffer; not reentrant! */ -char *ip6addr_ntoa(const ip6_addr_t *addr); -char *ip6addr_ntoa_r(const ip6_addr_t *addr, char *buf, int buflen); - - - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV6 */ - -#endif /* LWIP_HDR_IP6_ADDR_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/ip6_frag.h b/third-party/lwip-2.1.2/include/lwip/ip6_frag.h deleted file mode 100644 index 87e0e86a..00000000 --- a/third-party/lwip-2.1.2/include/lwip/ip6_frag.h +++ /dev/null @@ -1,144 +0,0 @@ -/** - * @file - * - * IPv6 fragmentation and reassembly. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ -#ifndef LWIP_HDR_IP6_FRAG_H -#define LWIP_HDR_IP6_FRAG_H - -#include "lwip/opt.h" -#include "lwip/pbuf.h" -#include "lwip/ip6_addr.h" -#include "lwip/ip6.h" -#include "lwip/netif.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -#if LWIP_IPV6 && LWIP_IPV6_REASS /* don't build if not configured for use in lwipopts.h */ - -/** The IPv6 reassembly timer interval in milliseconds. */ -#define IP6_REASS_TMR_INTERVAL 1000 - -/** IP6_FRAG_COPYHEADER==1: for platforms where sizeof(void*) > 4, "struct - * ip6_reass_helper" is too large to be stored in the IPv6 fragment header, and - * will bleed into the header before it, which may be the IPv6 header or an - * extension header. This means that for each first fragment packet, we need to - * 1) make a copy of some IPv6 header fields (src+dest) that we need later on, - * just in case we do overwrite part of the IPv6 header, and 2) make a copy of - * the header data that we overwrote, so that we can restore it before either - * completing reassembly or sending an ICMPv6 reply. The last part is true even - * if this setting is disabled, but if it is enabled, we need to save a bit - * more data (up to the size of a pointer) because we overwrite more. */ -#ifndef IPV6_FRAG_COPYHEADER -#define IPV6_FRAG_COPYHEADER 0 -#endif - -/* With IPV6_FRAG_COPYHEADER==1, a helper structure may (or, depending on the - * presence of extensions, may not) overwrite part of the IP header. Therefore, - * we copy the fields that we need from the IP header for as long as the helper - * structure may still be in place. This is easier than temporarily restoring - * those fields in the IP header each time we need to perform checks on them. */ -#if IPV6_FRAG_COPYHEADER -#define IPV6_FRAG_SRC(ipr) ((ipr)->src) -#define IPV6_FRAG_DEST(ipr) ((ipr)->dest) -#else /* IPV6_FRAG_COPYHEADER */ -#define IPV6_FRAG_SRC(ipr) ((ipr)->iphdr->src) -#define IPV6_FRAG_DEST(ipr) ((ipr)->iphdr->dest) -#endif /* IPV6_FRAG_COPYHEADER */ - -/** IPv6 reassembly helper struct. - * This is exported because memp needs to know the size. - */ -struct ip6_reassdata { - struct ip6_reassdata *next; - struct pbuf *p; - struct ip6_hdr *iphdr; /* pointer to the first (original) IPv6 header */ -#if IPV6_FRAG_COPYHEADER - ip6_addr_p_t src; /* copy of the source address in the IP header */ - ip6_addr_p_t dest; /* copy of the destination address in the IP header */ - /* This buffer (for the part of the original header that we overwrite) will - * be slightly oversized, but we cannot compute the exact size from here. */ - u8_t orig_hdr[sizeof(struct ip6_frag_hdr) + sizeof(void*)]; -#else /* IPV6_FRAG_COPYHEADER */ - /* In this case we still need the buffer, for sending ICMPv6 replies. */ - u8_t orig_hdr[sizeof(struct ip6_frag_hdr)]; -#endif /* IPV6_FRAG_COPYHEADER */ - u32_t identification; - u16_t datagram_len; - u8_t nexth; - u8_t timer; -#if LWIP_IPV6_SCOPES - u8_t src_zone; /* zone of original packet's source address */ - u8_t dest_zone; /* zone of original packet's destination address */ -#endif /* LWIP_IPV6_SCOPES */ -}; - -#define ip6_reass_init() /* Compatibility define */ -void ip6_reass_tmr(void); -struct pbuf *ip6_reass(struct pbuf *p); - -#endif /* LWIP_IPV6 && LWIP_IPV6_REASS */ - -#if LWIP_IPV6 && LWIP_IPV6_FRAG /* don't build if not configured for use in lwipopts.h */ - -#ifndef LWIP_PBUF_CUSTOM_REF_DEFINED -#define LWIP_PBUF_CUSTOM_REF_DEFINED -/** A custom pbuf that holds a reference to another pbuf, which is freed - * when this custom pbuf is freed. This is used to create a custom PBUF_REF - * that points into the original pbuf. */ -struct pbuf_custom_ref { - /** 'base class' */ - struct pbuf_custom pc; - /** pointer to the original pbuf that is referenced */ - struct pbuf *original; -}; -#endif /* LWIP_PBUF_CUSTOM_REF_DEFINED */ - -err_t ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest); - -#endif /* LWIP_IPV6 && LWIP_IPV6_FRAG */ - - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_IP6_FRAG_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/ip6_zone.h b/third-party/lwip-2.1.2/include/lwip/ip6_zone.h deleted file mode 100644 index 525790e6..00000000 --- a/third-party/lwip-2.1.2/include/lwip/ip6_zone.h +++ /dev/null @@ -1,304 +0,0 @@ -/** - * @file - * - * IPv6 address scopes, zones, and scoping policy. - * - * This header provides the means to implement support for IPv6 address scopes, - * as per RFC 4007. An address scope can be either global or more constrained. - * In lwIP, we say that an address "has a scope" or "is scoped" when its scope - * is constrained, in which case the address is meaningful only in a specific - * "zone." For unicast addresses, only link-local addresses have a scope; in - * that case, the scope is the link. For multicast addresses, there are various - * scopes defined by RFC 4007 and others. For any constrained scope, a system - * must establish a (potentially one-to-many) mapping between zones and local - * interfaces. For example, a link-local address is valid on only one link (its - * zone). That link may be attached to one or more local interfaces. The - * decisions on which scopes are constrained and the mapping between zones and - * interfaces is together what we refer to as the "scoping policy" - more on - * this in a bit. - * - * In lwIP, each IPv6 address has an associated zone index. This zone index may - * be set to "no zone" (IP6_NO_ZONE, 0) or an actual zone. We say that an - * address "has a zone" or "is zoned" when its zone index is *not* set to "no - * zone." In lwIP, in principle, each address should be "properly zoned," which - * means that if the address has a zone if and only if has a scope. As such, it - * is a rule that an unscoped (e.g., global) address must never have a zone. - * Even though one could argue that there is always one zone even for global - * scopes, this rule exists for implementation simplicity. Violation of the - * rule will trigger assertions or otherwise result in undesired behavior. - * - * Backward compatibility prevents us from requiring that applications always - * provide properly zoned addresses. We do enforce the rule that the in the - * lwIP link layer (everything below netif->output_ip6() and in particular ND6) - * *all* addresses are properly zoned. Thus, on the output paths down the - * stack, various places deal with the case of addresses that lack a zone. - * Some of them are best-effort for efficiency (e.g. the PCB bind and connect - * API calls' attempts to add missing zones); ultimately the IPv6 output - * handler (@ref ip6_output_if_src) will set a zone if necessary. - * - * Aside from dealing with scoped addresses lacking a zone, a proper IPv6 - * implementation must also ensure that a packet with a scoped source and/or - * destination address does not leave its zone. This is currently implemented - * in the input and forward functions. However, for output, these checks are - * deliberately omitted in order to keep the implementation lightweight. The - * routing algorithm in @ref ip6_route will take decisions such that it will - * not cause zone violations unless the application sets bad addresses, though. - * - * In terms of scoping policy, lwIP implements the default policy from RFC 4007 - * using macros in this file. This policy considers link-local unicast - * addresses and (only) interface-local and link-local multicast addresses as - * having a scope. For all these addresses, the zone is equal to the interface. - * As shown below in this file, it is possible to implement a custom policy. - */ - -/* - * Copyright (c) 2017 The MINIX 3 Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: David van Moolenbroek - * - */ -#ifndef LWIP_HDR_IP6_ZONE_H -#define LWIP_HDR_IP6_ZONE_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup ip6_zones IPv6 Zones - * @ingroup ip6 - * @{ - */ - -#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - -/** Identifier for "no zone". */ -#define IP6_NO_ZONE 0 - -#if LWIP_IPV6_SCOPES - -/** Zone initializer for static IPv6 address initialization, including comma. */ -#define IPADDR6_ZONE_INIT , IP6_NO_ZONE - -/** Return the zone index of the given IPv6 address; possibly "no zone". */ -#define ip6_addr_zone(ip6addr) ((ip6addr)->zone) - -/** Does the given IPv6 address have a zone set? (0/1) */ -#define ip6_addr_has_zone(ip6addr) (ip6_addr_zone(ip6addr) != IP6_NO_ZONE) - -/** Set the zone field of an IPv6 address to a particular value. */ -#define ip6_addr_set_zone(ip6addr, zone_idx) ((ip6addr)->zone = (zone_idx)) - -/** Clear the zone field of an IPv6 address, setting it to "no zone". */ -#define ip6_addr_clear_zone(ip6addr) ((ip6addr)->zone = IP6_NO_ZONE) - -/** Copy the zone field from the second IPv6 address to the first one. */ -#define ip6_addr_copy_zone(ip6addr1, ip6addr2) ((ip6addr1).zone = (ip6addr2).zone) - -/** Is the zone field of the given IPv6 address equal to the given zone index? (0/1) */ -#define ip6_addr_equals_zone(ip6addr, zone_idx) ((ip6addr)->zone == (zone_idx)) - -/** Are the zone fields of the given IPv6 addresses equal? (0/1) - * This macro must only be used on IPv6 addresses of the same scope. */ -#define ip6_addr_cmp_zone(ip6addr1, ip6addr2) ((ip6addr1)->zone == (ip6addr2)->zone) - -/** Symbolic constants for the 'type' parameters in some of the macros. - * These exist for efficiency only, allowing the macros to avoid certain tests - * when the address is known not to be of a certain type. Dead code elimination - * will do the rest. IP6_MULTICAST is supported but currently not optimized. - * @see ip6_addr_has_scope, ip6_addr_assign_zone, ip6_addr_lacks_zone. - */ -enum lwip_ipv6_scope_type -{ - /** Unknown */ - IP6_UNKNOWN = 0, - /** Unicast */ - IP6_UNICAST = 1, - /** Multicast */ - IP6_MULTICAST = 2 -}; - -/** IPV6_CUSTOM_SCOPES: together, the following three macro definitions, - * @ref ip6_addr_has_scope, @ref ip6_addr_assign_zone, and - * @ref ip6_addr_test_zone, completely define the lwIP scoping policy. - * The definitions below implement the default policy from RFC 4007 Sec. 6. - * Should an implementation desire to implement a different policy, it can - * define IPV6_CUSTOM_SCOPES to 1 and supply its own definitions for the three - * macros instead. - */ -#ifndef IPV6_CUSTOM_SCOPES -#define IPV6_CUSTOM_SCOPES 0 -#endif /* !IPV6_CUSTOM_SCOPES */ - -#if !IPV6_CUSTOM_SCOPES - -/** - * Determine whether an IPv6 address has a constrained scope, and as such is - * meaningful only if accompanied by a zone index to identify the scope's zone. - * The given address type may be used to eliminate at compile time certain - * checks that will evaluate to false at run time anyway. - * - * This default implementation follows the default model of RFC 4007, where - * only interface-local and link-local scopes are defined. - * - * Even though the unicast loopback address does have an implied link-local - * scope, in this implementation it does not have an explicitly assigned zone - * index. As such it should not be tested for in this macro. - * - * @param ip6addr the IPv6 address (const); only its address part is examined. - * @param type address type; see @ref lwip_ipv6_scope_type. - * @return 1 if the address has a constrained scope, 0 if it does not. - */ -#define ip6_addr_has_scope(ip6addr, type) \ - (ip6_addr_islinklocal(ip6addr) || (((type) != IP6_UNICAST) && \ - (ip6_addr_ismulticast_iflocal(ip6addr) || \ - ip6_addr_ismulticast_linklocal(ip6addr)))) - -/** - * Assign a zone index to an IPv6 address, based on a network interface. If the - * given address has a scope, the assigned zone index is that scope's zone of - * the given netif; otherwise, the assigned zone index is "no zone". - * - * This default implementation follows the default model of RFC 4007, where - * only interface-local and link-local scopes are defined, and the zone index - * of both of those scopes always equals the index of the network interface. - * As such, this default implementation need not distinguish between different - * constrained scopes when assigning the zone. - * - * @param ip6addr the IPv6 address; its address part is examined, and its zone - * index is assigned. - * @param type address type; see @ref lwip_ipv6_scope_type. - * @param netif the network interface (const). - */ -#define ip6_addr_assign_zone(ip6addr, type, netif) \ - (ip6_addr_set_zone((ip6addr), \ - ip6_addr_has_scope((ip6addr), (type)) ? netif_get_index(netif) : 0)) - -/** - * Test whether an IPv6 address is "zone-compatible" with a network interface. - * That is, test whether the network interface is part of the zone associated - * with the address. For efficiency, this macro is only ever called if the - * given address is either scoped or zoned, and thus, it need not test this. - * If an address is scoped but not zoned, or zoned and not scoped, it is - * considered not zone-compatible with any netif. - * - * This default implementation follows the default model of RFC 4007, where - * only interface-local and link-local scopes are defined, and the zone index - * of both of those scopes always equals the index of the network interface. - * As such, there is always only one matching netif for a specific zone index, - * but all call sites of this macro currently support multiple matching netifs - * as well (at no additional expense in the common case). - * - * @param ip6addr the IPv6 address (const). - * @param netif the network interface (const). - * @return 1 if the address is scope-compatible with the netif, 0 if not. - */ -#define ip6_addr_test_zone(ip6addr, netif) \ - (ip6_addr_equals_zone((ip6addr), netif_get_index(netif))) - -#endif /* !IPV6_CUSTOM_SCOPES */ - -/** Does the given IPv6 address have a scope, and as such should also have a - * zone to be meaningful, but does not actually have a zone? (0/1) */ -#define ip6_addr_lacks_zone(ip6addr, type) \ - (!ip6_addr_has_zone(ip6addr) && ip6_addr_has_scope((ip6addr), (type))) - -/** - * Try to select a zone for a scoped address that does not yet have a zone. - * Called from PCB bind and connect routines, for two reasons: 1) to save on - * this (relatively expensive) selection for every individual packet route - * operation and 2) to allow the application to obtain the selected zone from - * the PCB as is customary for e.g. getsockname/getpeername BSD socket calls. - * - * Ideally, callers would always supply a properly zoned address, in which case - * this function would not be needed. It exists both for compatibility with the - * BSD socket API (which accepts zoneless destination addresses) and for - * backward compatibility with pre-scoping lwIP code. - * - * It may be impossible to select a zone, e.g. if there are no netifs. In that - * case, the address's zone field will be left as is. - * - * @param dest the IPv6 address for which to select and set a zone. - * @param src source IPv6 address (const); may be equal to dest. - */ -#define ip6_addr_select_zone(dest, src) do { struct netif *selected_netif; \ - selected_netif = ip6_route((src), (dest)); \ - if (selected_netif != NULL) { \ - ip6_addr_assign_zone((dest), IP6_UNKNOWN, selected_netif); \ - } } while (0) - -/** - * @} - */ - -#else /* LWIP_IPV6_SCOPES */ - -#define IPADDR6_ZONE_INIT -#define ip6_addr_zone(ip6addr) (IP6_NO_ZONE) -#define ip6_addr_has_zone(ip6addr) (0) -#define ip6_addr_set_zone(ip6addr, zone_idx) -#define ip6_addr_clear_zone(ip6addr) -#define ip6_addr_copy_zone(ip6addr1, ip6addr2) -#define ip6_addr_equals_zone(ip6addr, zone_idx) (1) -#define ip6_addr_cmp_zone(ip6addr1, ip6addr2) (1) -#define IPV6_CUSTOM_SCOPES 0 -#define ip6_addr_has_scope(ip6addr, type) (0) -#define ip6_addr_assign_zone(ip6addr, type, netif) -#define ip6_addr_test_zone(ip6addr, netif) (1) -#define ip6_addr_lacks_zone(ip6addr, type) (0) -#define ip6_addr_select_zone(ip6addr, src) - -#endif /* LWIP_IPV6_SCOPES */ - -#if LWIP_IPV6_SCOPES && LWIP_IPV6_SCOPES_DEBUG - -/** Verify that the given IPv6 address is properly zoned. */ -#define IP6_ADDR_ZONECHECK(ip6addr) LWIP_ASSERT("IPv6 zone check failed", \ - ip6_addr_has_scope(ip6addr, IP6_UNKNOWN) == ip6_addr_has_zone(ip6addr)) - -/** Verify that the given IPv6 address is properly zoned for the given netif. */ -#define IP6_ADDR_ZONECHECK_NETIF(ip6addr, netif) LWIP_ASSERT("IPv6 netif zone check failed", \ - ip6_addr_has_scope(ip6addr, IP6_UNKNOWN) ? \ - (ip6_addr_has_zone(ip6addr) && \ - (((netif) == NULL) || ip6_addr_test_zone((ip6addr), (netif)))) : \ - !ip6_addr_has_zone(ip6addr)) - -#else /* LWIP_IPV6_SCOPES && LWIP_IPV6_SCOPES_DEBUG */ - -#define IP6_ADDR_ZONECHECK(ip6addr) -#define IP6_ADDR_ZONECHECK_NETIF(ip6addr, netif) - -#endif /* LWIP_IPV6_SCOPES && LWIP_IPV6_SCOPES_DEBUG */ - -#endif /* LWIP_IPV6 */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_IP6_ZONE_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/ip_addr.h b/third-party/lwip-2.1.2/include/lwip/ip_addr.h deleted file mode 100644 index 2f977709..00000000 --- a/third-party/lwip-2.1.2/include/lwip/ip_addr.h +++ /dev/null @@ -1,438 +0,0 @@ -/** - * @file - * IP address API (common IPv4 and IPv6) - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_IP_ADDR_H -#define LWIP_HDR_IP_ADDR_H - -#include "lwip/opt.h" -#include "lwip/def.h" - -#include "lwip/ip4_addr.h" -#include "lwip/ip6_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** @ingroup ipaddr - * IP address types for use in ip_addr_t.type member. - * @see tcp_new_ip_type(), udp_new_ip_type(), raw_new_ip_type(). - */ -enum lwip_ip_addr_type { - /** IPv4 */ - IPADDR_TYPE_V4 = 0U, - /** IPv6 */ - IPADDR_TYPE_V6 = 6U, - /** IPv4+IPv6 ("dual-stack") */ - IPADDR_TYPE_ANY = 46U -}; - -#if LWIP_IPV4 && LWIP_IPV6 -/** - * @ingroup ipaddr - * A union struct for both IP version's addresses. - * ATTENTION: watch out for its size when adding IPv6 address scope! - */ -typedef struct ip_addr { - union { - ip6_addr_t ip6; - ip4_addr_t ip4; - } u_addr; - /** @ref lwip_ip_addr_type */ - u8_t type; -} ip_addr_t; - -extern const ip_addr_t ip_addr_any_type; - -/** @ingroup ip4addr */ -#define IPADDR4_INIT(u32val) { { { { u32val, 0ul, 0ul, 0ul } IPADDR6_ZONE_INIT } }, IPADDR_TYPE_V4 } -/** @ingroup ip4addr */ -#define IPADDR4_INIT_BYTES(a,b,c,d) IPADDR4_INIT(PP_HTONL(LWIP_MAKEU32(a,b,c,d))) - -/** @ingroup ip6addr */ -#define IPADDR6_INIT(a, b, c, d) { { { { a, b, c, d } IPADDR6_ZONE_INIT } }, IPADDR_TYPE_V6 } -/** @ingroup ip6addr */ -#define IPADDR6_INIT_HOST(a, b, c, d) { { { { PP_HTONL(a), PP_HTONL(b), PP_HTONL(c), PP_HTONL(d) } IPADDR6_ZONE_INIT } }, IPADDR_TYPE_V6 } - -/** @ingroup ipaddr */ -#define IP_IS_ANY_TYPE_VAL(ipaddr) (IP_GET_TYPE(&ipaddr) == IPADDR_TYPE_ANY) -/** @ingroup ipaddr */ -#define IPADDR_ANY_TYPE_INIT { { { { 0ul, 0ul, 0ul, 0ul } IPADDR6_ZONE_INIT } }, IPADDR_TYPE_ANY } - -/** @ingroup ip4addr */ -#define IP_IS_V4_VAL(ipaddr) (IP_GET_TYPE(&ipaddr) == IPADDR_TYPE_V4) -/** @ingroup ip6addr */ -#define IP_IS_V6_VAL(ipaddr) (IP_GET_TYPE(&ipaddr) == IPADDR_TYPE_V6) -/** @ingroup ip4addr */ -#define IP_IS_V4(ipaddr) (((ipaddr) == NULL) || IP_IS_V4_VAL(*(ipaddr))) -/** @ingroup ip6addr */ -#define IP_IS_V6(ipaddr) (((ipaddr) != NULL) && IP_IS_V6_VAL(*(ipaddr))) - -#define IP_SET_TYPE_VAL(ipaddr, iptype) do { (ipaddr).type = (iptype); }while(0) -#define IP_SET_TYPE(ipaddr, iptype) do { if((ipaddr) != NULL) { IP_SET_TYPE_VAL(*(ipaddr), iptype); }}while(0) -#define IP_GET_TYPE(ipaddr) ((ipaddr)->type) - -#define IP_ADDR_RAW_SIZE(ipaddr) (IP_GET_TYPE(&ipaddr) == IPADDR_TYPE_V4 ? sizeof(ip4_addr_t) : sizeof(ip6_addr_t)) - -#define IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ipaddr) (IP_GET_TYPE(&pcb->local_ip) == IP_GET_TYPE(ipaddr)) -#define IP_ADDR_PCB_VERSION_MATCH(pcb, ipaddr) (IP_IS_ANY_TYPE_VAL(pcb->local_ip) || IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ipaddr)) - -/** @ingroup ip6addr - * Convert generic ip address to specific protocol version - */ -#define ip_2_ip6(ipaddr) (&((ipaddr)->u_addr.ip6)) -/** @ingroup ip4addr - * Convert generic ip address to specific protocol version - */ -#define ip_2_ip4(ipaddr) (&((ipaddr)->u_addr.ip4)) - -/** @ingroup ip4addr */ -#define IP_ADDR4(ipaddr,a,b,c,d) do { IP4_ADDR(ip_2_ip4(ipaddr),a,b,c,d); \ - IP_SET_TYPE_VAL(*(ipaddr), IPADDR_TYPE_V4); } while(0) -/** @ingroup ip6addr */ -#define IP_ADDR6(ipaddr,i0,i1,i2,i3) do { IP6_ADDR(ip_2_ip6(ipaddr),i0,i1,i2,i3); \ - IP_SET_TYPE_VAL(*(ipaddr), IPADDR_TYPE_V6); } while(0) -/** @ingroup ip6addr */ -#define IP_ADDR6_HOST(ipaddr,i0,i1,i2,i3) IP_ADDR6(ipaddr,PP_HTONL(i0),PP_HTONL(i1),PP_HTONL(i2),PP_HTONL(i3)) - -#define ip_clear_no4(ipaddr) do { ip_2_ip6(ipaddr)->addr[1] = \ - ip_2_ip6(ipaddr)->addr[2] = \ - ip_2_ip6(ipaddr)->addr[3] = 0; \ - ip6_addr_clear_zone(ip_2_ip6(ipaddr)); }while(0) - -/** @ingroup ipaddr */ -#define ip_addr_copy(dest, src) do{ IP_SET_TYPE_VAL(dest, IP_GET_TYPE(&src)); if(IP_IS_V6_VAL(src)){ \ - ip6_addr_copy(*ip_2_ip6(&(dest)), *ip_2_ip6(&(src))); }else{ \ - ip4_addr_copy(*ip_2_ip4(&(dest)), *ip_2_ip4(&(src))); ip_clear_no4(&dest); }}while(0) -/** @ingroup ip6addr */ -#define ip_addr_copy_from_ip6(dest, src) do{ \ - ip6_addr_copy(*ip_2_ip6(&(dest)), src); IP_SET_TYPE_VAL(dest, IPADDR_TYPE_V6); }while(0) -/** @ingroup ip6addr */ -#define ip_addr_copy_from_ip6_packed(dest, src) do{ \ - ip6_addr_copy_from_packed(*ip_2_ip6(&(dest)), src); IP_SET_TYPE_VAL(dest, IPADDR_TYPE_V6); }while(0) -/** @ingroup ip4addr */ -#define ip_addr_copy_from_ip4(dest, src) do{ \ - ip4_addr_copy(*ip_2_ip4(&(dest)), src); IP_SET_TYPE_VAL(dest, IPADDR_TYPE_V4); ip_clear_no4(&dest); }while(0) -/** @ingroup ip4addr */ -#define ip_addr_set_ip4_u32(ipaddr, val) do{if(ipaddr){ip4_addr_set_u32(ip_2_ip4(ipaddr), val); \ - IP_SET_TYPE(ipaddr, IPADDR_TYPE_V4); ip_clear_no4(ipaddr); }}while(0) -/** @ingroup ip4addr */ -#define ip_addr_set_ip4_u32_val(ipaddr, val) do{ ip4_addr_set_u32(ip_2_ip4(&(ipaddr)), val); \ - IP_SET_TYPE_VAL(ipaddr, IPADDR_TYPE_V4); ip_clear_no4(&ipaddr); }while(0) -/** @ingroup ip4addr */ -#define ip_addr_get_ip4_u32(ipaddr) (((ipaddr) && IP_IS_V4(ipaddr)) ? \ - ip4_addr_get_u32(ip_2_ip4(ipaddr)) : 0) -/** @ingroup ipaddr */ -#define ip_addr_set(dest, src) do{ IP_SET_TYPE(dest, IP_GET_TYPE(src)); if(IP_IS_V6(src)){ \ - ip6_addr_set(ip_2_ip6(dest), ip_2_ip6(src)); }else{ \ - ip4_addr_set(ip_2_ip4(dest), ip_2_ip4(src)); ip_clear_no4(dest); }}while(0) -/** @ingroup ipaddr */ -#define ip_addr_set_ipaddr(dest, src) ip_addr_set(dest, src) -/** @ingroup ipaddr */ -#define ip_addr_set_zero(ipaddr) do{ \ - ip6_addr_set_zero(ip_2_ip6(ipaddr)); IP_SET_TYPE(ipaddr, 0); }while(0) -/** @ingroup ip5addr */ -#define ip_addr_set_zero_ip4(ipaddr) do{ \ - ip6_addr_set_zero(ip_2_ip6(ipaddr)); IP_SET_TYPE(ipaddr, IPADDR_TYPE_V4); }while(0) -/** @ingroup ip6addr */ -#define ip_addr_set_zero_ip6(ipaddr) do{ \ - ip6_addr_set_zero(ip_2_ip6(ipaddr)); IP_SET_TYPE(ipaddr, IPADDR_TYPE_V6); }while(0) -/** @ingroup ipaddr */ -#define ip_addr_set_any(is_ipv6, ipaddr) do{if(is_ipv6){ \ - ip6_addr_set_any(ip_2_ip6(ipaddr)); IP_SET_TYPE(ipaddr, IPADDR_TYPE_V6); }else{ \ - ip4_addr_set_any(ip_2_ip4(ipaddr)); IP_SET_TYPE(ipaddr, IPADDR_TYPE_V4); ip_clear_no4(ipaddr); }}while(0) -/** @ingroup ipaddr */ -#define ip_addr_set_any_val(is_ipv6, ipaddr) do{if(is_ipv6){ \ - ip6_addr_set_any(ip_2_ip6(&(ipaddr))); IP_SET_TYPE_VAL(ipaddr, IPADDR_TYPE_V6); }else{ \ - ip4_addr_set_any(ip_2_ip4(&(ipaddr))); IP_SET_TYPE_VAL(ipaddr, IPADDR_TYPE_V4); ip_clear_no4(&ipaddr); }}while(0) -/** @ingroup ipaddr */ -#define ip_addr_set_loopback(is_ipv6, ipaddr) do{if(is_ipv6){ \ - ip6_addr_set_loopback(ip_2_ip6(ipaddr)); IP_SET_TYPE(ipaddr, IPADDR_TYPE_V6); }else{ \ - ip4_addr_set_loopback(ip_2_ip4(ipaddr)); IP_SET_TYPE(ipaddr, IPADDR_TYPE_V4); ip_clear_no4(ipaddr); }}while(0) -/** @ingroup ipaddr */ -#define ip_addr_set_loopback_val(is_ipv6, ipaddr) do{if(is_ipv6){ \ - ip6_addr_set_loopback(ip_2_ip6(&(ipaddr))); IP_SET_TYPE_VAL(ipaddr, IPADDR_TYPE_V6); }else{ \ - ip4_addr_set_loopback(ip_2_ip4(&(ipaddr))); IP_SET_TYPE_VAL(ipaddr, IPADDR_TYPE_V4); ip_clear_no4(&ipaddr); }}while(0) -/** @ingroup ipaddr */ -#define ip_addr_set_hton(dest, src) do{if(IP_IS_V6(src)){ \ - ip6_addr_set_hton(ip_2_ip6(dest), ip_2_ip6(src)); IP_SET_TYPE(dest, IPADDR_TYPE_V6); }else{ \ - ip4_addr_set_hton(ip_2_ip4(dest), ip_2_ip4(src)); IP_SET_TYPE(dest, IPADDR_TYPE_V4); ip_clear_no4(ipaddr); }}while(0) -/** @ingroup ipaddr */ -#define ip_addr_get_network(target, host, netmask) do{if(IP_IS_V6(host)){ \ - ip4_addr_set_zero(ip_2_ip4(target)); IP_SET_TYPE(target, IPADDR_TYPE_V6); } else { \ - ip4_addr_get_network(ip_2_ip4(target), ip_2_ip4(host), ip_2_ip4(netmask)); IP_SET_TYPE(target, IPADDR_TYPE_V4); }}while(0) -/** @ingroup ipaddr */ -#define ip_addr_netcmp(addr1, addr2, mask) ((IP_IS_V6(addr1) && IP_IS_V6(addr2)) ? \ - 0 : \ - ip4_addr_netcmp(ip_2_ip4(addr1), ip_2_ip4(addr2), mask)) -/** @ingroup ipaddr */ -#define ip_addr_cmp(addr1, addr2) ((IP_GET_TYPE(addr1) != IP_GET_TYPE(addr2)) ? 0 : (IP_IS_V6_VAL(*(addr1)) ? \ - ip6_addr_cmp(ip_2_ip6(addr1), ip_2_ip6(addr2)) : \ - ip4_addr_cmp(ip_2_ip4(addr1), ip_2_ip4(addr2)))) -/** @ingroup ipaddr */ -#define ip_addr_cmp_zoneless(addr1, addr2) ((IP_GET_TYPE(addr1) != IP_GET_TYPE(addr2)) ? 0 : (IP_IS_V6_VAL(*(addr1)) ? \ - ip6_addr_cmp_zoneless(ip_2_ip6(addr1), ip_2_ip6(addr2)) : \ - ip4_addr_cmp(ip_2_ip4(addr1), ip_2_ip4(addr2)))) -/** @ingroup ipaddr */ -#define ip_addr_isany(ipaddr) (((ipaddr) == NULL) ? 1 : ((IP_IS_V6(ipaddr)) ? \ - ip6_addr_isany(ip_2_ip6(ipaddr)) : \ - ip4_addr_isany(ip_2_ip4(ipaddr)))) -/** @ingroup ipaddr */ -#define ip_addr_isany_val(ipaddr) ((IP_IS_V6_VAL(ipaddr)) ? \ - ip6_addr_isany_val(*ip_2_ip6(&(ipaddr))) : \ - ip4_addr_isany_val(*ip_2_ip4(&(ipaddr)))) -/** @ingroup ipaddr */ -#define ip_addr_isbroadcast(ipaddr, netif) ((IP_IS_V6(ipaddr)) ? \ - 0 : \ - ip4_addr_isbroadcast(ip_2_ip4(ipaddr), netif)) -/** @ingroup ipaddr */ -#define ip_addr_ismulticast(ipaddr) ((IP_IS_V6(ipaddr)) ? \ - ip6_addr_ismulticast(ip_2_ip6(ipaddr)) : \ - ip4_addr_ismulticast(ip_2_ip4(ipaddr))) -/** @ingroup ipaddr */ -#define ip_addr_isloopback(ipaddr) ((IP_IS_V6(ipaddr)) ? \ - ip6_addr_isloopback(ip_2_ip6(ipaddr)) : \ - ip4_addr_isloopback(ip_2_ip4(ipaddr))) -/** @ingroup ipaddr */ -#define ip_addr_islinklocal(ipaddr) ((IP_IS_V6(ipaddr)) ? \ - ip6_addr_islinklocal(ip_2_ip6(ipaddr)) : \ - ip4_addr_islinklocal(ip_2_ip4(ipaddr))) -#define ip_addr_debug_print(debug, ipaddr) do { if(IP_IS_V6(ipaddr)) { \ - ip6_addr_debug_print(debug, ip_2_ip6(ipaddr)); } else { \ - ip4_addr_debug_print(debug, ip_2_ip4(ipaddr)); }}while(0) -#define ip_addr_debug_print_val(debug, ipaddr) do { if(IP_IS_V6_VAL(ipaddr)) { \ - ip6_addr_debug_print_val(debug, *ip_2_ip6(&(ipaddr))); } else { \ - ip4_addr_debug_print_val(debug, *ip_2_ip4(&(ipaddr))); }}while(0) -char *ipaddr_ntoa(const ip_addr_t *addr); -char *ipaddr_ntoa_r(const ip_addr_t *addr, char *buf, int buflen); -int ipaddr_aton(const char *cp, ip_addr_t *addr); - -/** @ingroup ipaddr */ -#define IPADDR_STRLEN_MAX IP6ADDR_STRLEN_MAX - -/** @ingroup ipaddr */ -#define ip4_2_ipv4_mapped_ipv6(ip6addr, ip4addr) do { \ - (ip6addr)->addr[3] = (ip4addr)->addr; \ - (ip6addr)->addr[2] = PP_HTONL(0x0000FFFFUL); \ - (ip6addr)->addr[1] = 0; \ - (ip6addr)->addr[0] = 0; \ - ip6_addr_clear_zone(ip6addr); } while(0); - -/** @ingroup ipaddr */ -#define unmap_ipv4_mapped_ipv6(ip4addr, ip6addr) \ - (ip4addr)->addr = (ip6addr)->addr[3]; - -#define IP46_ADDR_ANY(type) (((type) == IPADDR_TYPE_V6)? IP6_ADDR_ANY : IP4_ADDR_ANY) - -#else /* LWIP_IPV4 && LWIP_IPV6 */ - -#define IP_ADDR_PCB_VERSION_MATCH(addr, pcb) 1 -#define IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ipaddr) 1 - -#define ip_addr_set_any_val(is_ipv6, ipaddr) ip_addr_set_any(is_ipv6, &(ipaddr)) -#define ip_addr_set_loopback_val(is_ipv6, ipaddr) ip_addr_set_loopback(is_ipv6, &(ipaddr)) - -#if LWIP_IPV4 - -typedef ip4_addr_t ip_addr_t; -#define IPADDR4_INIT(u32val) { u32val } -#define IPADDR4_INIT_BYTES(a,b,c,d) IPADDR4_INIT(PP_HTONL(LWIP_MAKEU32(a,b,c,d))) -#define IP_IS_V4_VAL(ipaddr) 1 -#define IP_IS_V6_VAL(ipaddr) 0 -#define IP_IS_V4(ipaddr) 1 -#define IP_IS_V6(ipaddr) 0 -#define IP_IS_ANY_TYPE_VAL(ipaddr) 0 -#define IP_SET_TYPE_VAL(ipaddr, iptype) -#define IP_SET_TYPE(ipaddr, iptype) -#define IP_GET_TYPE(ipaddr) IPADDR_TYPE_V4 -#define IP_ADDR_RAW_SIZE(ipaddr) sizeof(ip4_addr_t) -#define ip_2_ip4(ipaddr) (ipaddr) -#define IP_ADDR4(ipaddr,a,b,c,d) IP4_ADDR(ipaddr,a,b,c,d) - -#define ip_addr_copy(dest, src) ip4_addr_copy(dest, src) -#define ip_addr_copy_from_ip4(dest, src) ip4_addr_copy(dest, src) -#define ip_addr_set_ip4_u32(ipaddr, val) ip4_addr_set_u32(ip_2_ip4(ipaddr), val) -#define ip_addr_set_ip4_u32_val(ipaddr, val) ip_addr_set_ip4_u32(&(ipaddr), val) -#define ip_addr_get_ip4_u32(ipaddr) ip4_addr_get_u32(ip_2_ip4(ipaddr)) -#define ip_addr_set(dest, src) ip4_addr_set(dest, src) -#define ip_addr_set_ipaddr(dest, src) ip4_addr_set(dest, src) -#define ip_addr_set_zero(ipaddr) ip4_addr_set_zero(ipaddr) -#define ip_addr_set_zero_ip4(ipaddr) ip4_addr_set_zero(ipaddr) -#define ip_addr_set_any(is_ipv6, ipaddr) ip4_addr_set_any(ipaddr) -#define ip_addr_set_loopback(is_ipv6, ipaddr) ip4_addr_set_loopback(ipaddr) -#define ip_addr_set_hton(dest, src) ip4_addr_set_hton(dest, src) -#define ip_addr_get_network(target, host, mask) ip4_addr_get_network(target, host, mask) -#define ip_addr_netcmp(addr1, addr2, mask) ip4_addr_netcmp(addr1, addr2, mask) -#define ip_addr_cmp(addr1, addr2) ip4_addr_cmp(addr1, addr2) -#define ip_addr_isany(ipaddr) ip4_addr_isany(ipaddr) -#define ip_addr_isany_val(ipaddr) ip4_addr_isany_val(ipaddr) -#define ip_addr_isloopback(ipaddr) ip4_addr_isloopback(ipaddr) -#define ip_addr_islinklocal(ipaddr) ip4_addr_islinklocal(ipaddr) -#define ip_addr_isbroadcast(addr, netif) ip4_addr_isbroadcast(addr, netif) -#define ip_addr_ismulticast(ipaddr) ip4_addr_ismulticast(ipaddr) -#define ip_addr_debug_print(debug, ipaddr) ip4_addr_debug_print(debug, ipaddr) -#define ip_addr_debug_print_val(debug, ipaddr) ip4_addr_debug_print_val(debug, ipaddr) -#define ipaddr_ntoa(ipaddr) ip4addr_ntoa(ipaddr) -#define ipaddr_ntoa_r(ipaddr, buf, buflen) ip4addr_ntoa_r(ipaddr, buf, buflen) -#define ipaddr_aton(cp, addr) ip4addr_aton(cp, addr) - -#define IPADDR_STRLEN_MAX IP4ADDR_STRLEN_MAX - -#define IP46_ADDR_ANY(type) (IP4_ADDR_ANY) - -#else /* LWIP_IPV4 */ - -typedef ip6_addr_t ip_addr_t; -#define IPADDR6_INIT(a, b, c, d) { { a, b, c, d } IPADDR6_ZONE_INIT } -#define IPADDR6_INIT_HOST(a, b, c, d) { { PP_HTONL(a), PP_HTONL(b), PP_HTONL(c), PP_HTONL(d) } IPADDR6_ZONE_INIT } -#define IP_IS_V4_VAL(ipaddr) 0 -#define IP_IS_V6_VAL(ipaddr) 1 -#define IP_IS_V4(ipaddr) 0 -#define IP_IS_V6(ipaddr) 1 -#define IP_IS_ANY_TYPE_VAL(ipaddr) 0 -#define IP_SET_TYPE_VAL(ipaddr, iptype) -#define IP_SET_TYPE(ipaddr, iptype) -#define IP_GET_TYPE(ipaddr) IPADDR_TYPE_V6 -#define IP_ADDR_RAW_SIZE(ipaddr) sizeof(ip6_addr_t) -#define ip_2_ip6(ipaddr) (ipaddr) -#define IP_ADDR6(ipaddr,i0,i1,i2,i3) IP6_ADDR(ipaddr,i0,i1,i2,i3) -#define IP_ADDR6_HOST(ipaddr,i0,i1,i2,i3) IP_ADDR6(ipaddr,PP_HTONL(i0),PP_HTONL(i1),PP_HTONL(i2),PP_HTONL(i3)) - -#define ip_addr_copy(dest, src) ip6_addr_copy(dest, src) -#define ip_addr_copy_from_ip6(dest, src) ip6_addr_copy(dest, src) -#define ip_addr_copy_from_ip6_packed(dest, src) ip6_addr_copy_from_packed(dest, src) -#define ip_addr_set(dest, src) ip6_addr_set(dest, src) -#define ip_addr_set_ipaddr(dest, src) ip6_addr_set(dest, src) -#define ip_addr_set_zero(ipaddr) ip6_addr_set_zero(ipaddr) -#define ip_addr_set_zero_ip6(ipaddr) ip6_addr_set_zero(ipaddr) -#define ip_addr_set_any(is_ipv6, ipaddr) ip6_addr_set_any(ipaddr) -#define ip_addr_set_loopback(is_ipv6, ipaddr) ip6_addr_set_loopback(ipaddr) -#define ip_addr_set_hton(dest, src) ip6_addr_set_hton(dest, src) -#define ip_addr_get_network(target, host, mask) ip6_addr_set_zero(target) -#define ip_addr_netcmp(addr1, addr2, mask) 0 -#define ip_addr_cmp(addr1, addr2) ip6_addr_cmp(addr1, addr2) -#define ip_addr_cmp_zoneless(addr1, addr2) ip6_addr_cmp_zoneless(addr1, addr2) -#define ip_addr_isany(ipaddr) ip6_addr_isany(ipaddr) -#define ip_addr_isany_val(ipaddr) ip6_addr_isany_val(ipaddr) -#define ip_addr_isloopback(ipaddr) ip6_addr_isloopback(ipaddr) -#define ip_addr_islinklocal(ipaddr) ip6_addr_islinklocal(ipaddr) -#define ip_addr_isbroadcast(addr, netif) 0 -#define ip_addr_ismulticast(ipaddr) ip6_addr_ismulticast(ipaddr) -#define ip_addr_debug_print(debug, ipaddr) ip6_addr_debug_print(debug, ipaddr) -#define ip_addr_debug_print_val(debug, ipaddr) ip6_addr_debug_print_val(debug, ipaddr) -#define ipaddr_ntoa(ipaddr) ip6addr_ntoa(ipaddr) -#define ipaddr_ntoa_r(ipaddr, buf, buflen) ip6addr_ntoa_r(ipaddr, buf, buflen) -#define ipaddr_aton(cp, addr) ip6addr_aton(cp, addr) - -#define IPADDR_STRLEN_MAX IP6ADDR_STRLEN_MAX - -#define IP46_ADDR_ANY(type) (IP6_ADDR_ANY) - -#endif /* LWIP_IPV4 */ -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - -#if LWIP_IPV4 - -extern const ip_addr_t ip_addr_any; -extern const ip_addr_t ip_addr_broadcast; - -/** - * @ingroup ip4addr - * Can be used as a fixed/const ip_addr_t - * for the IP wildcard. - * Defined to @ref IP4_ADDR_ANY when IPv4 is enabled. - * Defined to @ref IP6_ADDR_ANY in IPv6 only systems. - * Use this if you can handle IPv4 _AND_ IPv6 addresses. - * Use @ref IP4_ADDR_ANY or @ref IP6_ADDR_ANY when the IP - * type matters. - */ -#define IP_ADDR_ANY IP4_ADDR_ANY -/** - * @ingroup ip4addr - * Can be used as a fixed/const ip_addr_t - * for the IPv4 wildcard and the broadcast address - */ -#define IP4_ADDR_ANY (&ip_addr_any) -/** - * @ingroup ip4addr - * Can be used as a fixed/const ip4_addr_t - * for the wildcard and the broadcast address - */ -#define IP4_ADDR_ANY4 (ip_2_ip4(&ip_addr_any)) - -/** @ingroup ip4addr */ -#define IP_ADDR_BROADCAST (&ip_addr_broadcast) -/** @ingroup ip4addr */ -#define IP4_ADDR_BROADCAST (ip_2_ip4(&ip_addr_broadcast)) - -#endif /* LWIP_IPV4*/ - -#if LWIP_IPV6 - -extern const ip_addr_t ip6_addr_any; - -/** - * @ingroup ip6addr - * IP6_ADDR_ANY can be used as a fixed ip_addr_t - * for the IPv6 wildcard address - */ -#define IP6_ADDR_ANY (&ip6_addr_any) -/** - * @ingroup ip6addr - * IP6_ADDR_ANY6 can be used as a fixed ip6_addr_t - * for the IPv6 wildcard address - */ -#define IP6_ADDR_ANY6 (ip_2_ip6(&ip6_addr_any)) - -#if !LWIP_IPV4 -/** IPv6-only configurations */ -#define IP_ADDR_ANY IP6_ADDR_ANY -#endif /* !LWIP_IPV4 */ - -#endif - -#if LWIP_IPV4 && LWIP_IPV6 -/** @ingroup ipaddr */ -#define IP_ANY_TYPE (&ip_addr_any_type) -#else -#define IP_ANY_TYPE IP_ADDR_ANY -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_IP_ADDR_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/mem.h b/third-party/lwip-2.1.2/include/lwip/mem.h deleted file mode 100644 index ff208d25..00000000 --- a/third-party/lwip-2.1.2/include/lwip/mem.h +++ /dev/null @@ -1,82 +0,0 @@ -/** - * @file - * Heap API - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_MEM_H -#define LWIP_HDR_MEM_H - -#include "lwip/opt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if MEM_LIBC_MALLOC - -#include "lwip/arch.h" - -typedef size_t mem_size_t; -#define MEM_SIZE_F SZT_F - -#elif MEM_USE_POOLS - -typedef u16_t mem_size_t; -#define MEM_SIZE_F U16_F - -#else - -/* MEM_SIZE would have to be aligned, but using 64000 here instead of - * 65535 leaves some room for alignment... - */ -#if MEM_SIZE > 64000L -typedef u32_t mem_size_t; -#define MEM_SIZE_F U32_F -#else -typedef u16_t mem_size_t; -#define MEM_SIZE_F U16_F -#endif /* MEM_SIZE > 64000 */ -#endif - -void mem_init(void); -void *mem_trim(void *mem, mem_size_t size); -void *mem_malloc(mem_size_t size); -void *mem_calloc(mem_size_t count, mem_size_t size); -void mem_free(void *mem); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_MEM_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/memp.h b/third-party/lwip-2.1.2/include/lwip/memp.h deleted file mode 100644 index 1630b26c..00000000 --- a/third-party/lwip-2.1.2/include/lwip/memp.h +++ /dev/null @@ -1,155 +0,0 @@ -/** - * @file - * Memory pool API - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#ifndef LWIP_HDR_MEMP_H -#define LWIP_HDR_MEMP_H - -#include "lwip/opt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* run once with empty definition to handle all custom includes in lwippools.h */ -#define LWIP_MEMPOOL(name,num,size,desc) -#include "lwip/priv/memp_std.h" - -/** Create the list of all memory pools managed by memp. MEMP_MAX represents a NULL pool at the end */ -typedef enum { -#define LWIP_MEMPOOL(name,num,size,desc) MEMP_##name, -#include "lwip/priv/memp_std.h" - MEMP_MAX -} memp_t; - -#include "lwip/priv/memp_priv.h" -#include "lwip/stats.h" - -extern const struct memp_desc* const memp_pools[MEMP_MAX]; - -/** - * @ingroup mempool - * Declare prototype for private memory pool if it is used in multiple files - */ -#define LWIP_MEMPOOL_PROTOTYPE(name) extern const struct memp_desc memp_ ## name - -#if MEMP_MEM_MALLOC - -#define LWIP_MEMPOOL_DECLARE(name,num,size,desc) \ - LWIP_MEMPOOL_DECLARE_STATS_INSTANCE(memp_stats_ ## name) \ - const struct memp_desc memp_ ## name = { \ - DECLARE_LWIP_MEMPOOL_DESC(desc) \ - LWIP_MEMPOOL_DECLARE_STATS_REFERENCE(memp_stats_ ## name) \ - LWIP_MEM_ALIGN_SIZE(size) \ - }; - -#else /* MEMP_MEM_MALLOC */ - -/** - * @ingroup mempool - * Declare a private memory pool - * Private mempools example: - * .h: only when pool is used in multiple .c files: LWIP_MEMPOOL_PROTOTYPE(my_private_pool); - * .c: - * - in global variables section: LWIP_MEMPOOL_DECLARE(my_private_pool, 10, sizeof(foo), "Some description") - * - call ONCE before using pool (e.g. in some init() function): LWIP_MEMPOOL_INIT(my_private_pool); - * - allocate: void* my_new_mem = LWIP_MEMPOOL_ALLOC(my_private_pool); - * - free: LWIP_MEMPOOL_FREE(my_private_pool, my_new_mem); - * - * To relocate a pool, declare it as extern in cc.h. Example for GCC: - * extern u8_t \_\_attribute\_\_((section(".onchip_mem"))) memp_memory_my_private_pool_base[]; - */ -#define LWIP_MEMPOOL_DECLARE(name,num,size,desc) \ - LWIP_DECLARE_MEMORY_ALIGNED(memp_memory_ ## name ## _base, ((num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size)))); \ - \ - LWIP_MEMPOOL_DECLARE_STATS_INSTANCE(memp_stats_ ## name) \ - \ - static struct memp *memp_tab_ ## name; \ - \ - const struct memp_desc memp_ ## name = { \ - DECLARE_LWIP_MEMPOOL_DESC(desc) \ - LWIP_MEMPOOL_DECLARE_STATS_REFERENCE(memp_stats_ ## name) \ - LWIP_MEM_ALIGN_SIZE(size), \ - (num), \ - memp_memory_ ## name ## _base, \ - &memp_tab_ ## name \ - }; - -#endif /* MEMP_MEM_MALLOC */ - -/** - * @ingroup mempool - * Initialize a private memory pool - */ -#define LWIP_MEMPOOL_INIT(name) memp_init_pool(&memp_ ## name) -/** - * @ingroup mempool - * Allocate from a private memory pool - */ -#define LWIP_MEMPOOL_ALLOC(name) memp_malloc_pool(&memp_ ## name) -/** - * @ingroup mempool - * Free element from a private memory pool - */ -#define LWIP_MEMPOOL_FREE(name, x) memp_free_pool(&memp_ ## name, (x)) - -#if MEM_USE_POOLS -/** This structure is used to save the pool one element came from. - * This has to be defined here as it is required for pool size calculation. */ -struct memp_malloc_helper -{ - memp_t poolnr; -#if MEMP_OVERFLOW_CHECK || (LWIP_STATS && MEM_STATS) - u16_t size; -#endif /* MEMP_OVERFLOW_CHECK || (LWIP_STATS && MEM_STATS) */ -}; -#endif /* MEM_USE_POOLS */ - -void memp_init(void); - -#if MEMP_OVERFLOW_CHECK -void *memp_malloc_fn(memp_t type, const char* file, const int line); -#define memp_malloc(t) memp_malloc_fn((t), __FILE__, __LINE__) -#else -void *memp_malloc(memp_t type); -#endif -void memp_free(memp_t type, void *mem); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_MEMP_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/mld6.h b/third-party/lwip-2.1.2/include/lwip/mld6.h deleted file mode 100644 index 7fa0797f..00000000 --- a/third-party/lwip-2.1.2/include/lwip/mld6.h +++ /dev/null @@ -1,99 +0,0 @@ -/** - * @file - * - * Multicast listener discovery for IPv6. Aims to be compliant with RFC 2710. - * No support for MLDv2. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -#ifndef LWIP_HDR_MLD6_H -#define LWIP_HDR_MLD6_H - -#include "lwip/opt.h" - -#if LWIP_IPV6_MLD && LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/pbuf.h" -#include "lwip/netif.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** MLD group */ -struct mld_group { - /** next link */ - struct mld_group *next; - /** multicast address */ - ip6_addr_t group_address; - /** signifies we were the last person to report */ - u8_t last_reporter_flag; - /** current state of the group */ - u8_t group_state; - /** timer for reporting */ - u16_t timer; - /** counter of simultaneous uses */ - u8_t use; -}; - -#define MLD6_TMR_INTERVAL 100 /* Milliseconds */ - -err_t mld6_stop(struct netif *netif); -void mld6_report_groups(struct netif *netif); -void mld6_tmr(void); -struct mld_group *mld6_lookfor_group(struct netif *ifp, const ip6_addr_t *addr); -void mld6_input(struct pbuf *p, struct netif *inp); -err_t mld6_joingroup(const ip6_addr_t *srcaddr, const ip6_addr_t *groupaddr); -err_t mld6_joingroup_netif(struct netif *netif, const ip6_addr_t *groupaddr); -err_t mld6_leavegroup(const ip6_addr_t *srcaddr, const ip6_addr_t *groupaddr); -err_t mld6_leavegroup_netif(struct netif *netif, const ip6_addr_t *groupaddr); - -/** @ingroup mld6 - * Get list head of MLD6 groups for netif. - * Note: The allnodes group IP is NOT in the list, since it must always - * be received for correct IPv6 operation. - * @see @ref netif_set_mld_mac_filter() - */ -#define netif_mld6_data(netif) ((struct mld_group *)netif_get_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_MLD6)) - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV6_MLD && LWIP_IPV6 */ - -#endif /* LWIP_HDR_MLD6_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/nd6.h b/third-party/lwip-2.1.2/include/lwip/nd6.h deleted file mode 100644 index c30e624f..00000000 --- a/third-party/lwip-2.1.2/include/lwip/nd6.h +++ /dev/null @@ -1,90 +0,0 @@ -/** - * @file - * - * Neighbor discovery and stateless address autoconfiguration for IPv6. - * Aims to be compliant with RFC 4861 (Neighbor discovery) and RFC 4862 - * (Address autoconfiguration). - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -#ifndef LWIP_HDR_ND6_H -#define LWIP_HDR_ND6_H - -#include "lwip/opt.h" - -#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/ip6_addr.h" -#include "lwip/err.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** 1 second period */ -#define ND6_TMR_INTERVAL 1000 - -/** Router solicitations are sent in 4 second intervals (see RFC 4861, ch. 6.3.7) */ -#ifndef ND6_RTR_SOLICITATION_INTERVAL -#define ND6_RTR_SOLICITATION_INTERVAL 4000 -#endif - -struct pbuf; -struct netif; - -void nd6_tmr(void); -void nd6_input(struct pbuf *p, struct netif *inp); -void nd6_clear_destination_cache(void); -struct netif *nd6_find_route(const ip6_addr_t *ip6addr); -err_t nd6_get_next_hop_addr_or_queue(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr, const u8_t **hwaddrp); -u16_t nd6_get_destination_mtu(const ip6_addr_t *ip6addr, struct netif *netif); -#if LWIP_ND6_TCP_REACHABILITY_HINTS -void nd6_reachability_hint(const ip6_addr_t *ip6addr); -#endif /* LWIP_ND6_TCP_REACHABILITY_HINTS */ -void nd6_cleanup_netif(struct netif *netif); -#if LWIP_IPV6_MLD -void nd6_adjust_mld_membership(struct netif *netif, s8_t addr_idx, u8_t new_state); -#endif /* LWIP_IPV6_MLD */ -void nd6_restart_netif(struct netif *netif); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV6 */ - -#endif /* LWIP_HDR_ND6_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/netbuf.h b/third-party/lwip-2.1.2/include/lwip/netbuf.h deleted file mode 100644 index 42a911bc..00000000 --- a/third-party/lwip-2.1.2/include/lwip/netbuf.h +++ /dev/null @@ -1,116 +0,0 @@ -/** - * @file - * netbuf API (for netconn API) - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_NETBUF_H -#define LWIP_HDR_NETBUF_H - -#include "lwip/opt.h" - -#if LWIP_NETCONN || LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ -/* Note: Netconn API is always available when sockets are enabled - - * sockets are implemented on top of them */ - -#include "lwip/pbuf.h" -#include "lwip/ip_addr.h" -#include "lwip/ip6_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** This netbuf has dest-addr/port set */ -#define NETBUF_FLAG_DESTADDR 0x01 -/** This netbuf includes a checksum */ -#define NETBUF_FLAG_CHKSUM 0x02 - -/** "Network buffer" - contains data and addressing info */ -struct netbuf { - struct pbuf *p, *ptr; - ip_addr_t addr; - u16_t port; -#if LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY - u8_t flags; - u16_t toport_chksum; -#if LWIP_NETBUF_RECVINFO - ip_addr_t toaddr; -#endif /* LWIP_NETBUF_RECVINFO */ -#endif /* LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY */ -}; - -/* Network buffer functions: */ -struct netbuf * netbuf_new (void); -void netbuf_delete (struct netbuf *buf); -void * netbuf_alloc (struct netbuf *buf, u16_t size); -void netbuf_free (struct netbuf *buf); -err_t netbuf_ref (struct netbuf *buf, - const void *dataptr, u16_t size); -void netbuf_chain (struct netbuf *head, struct netbuf *tail); - -err_t netbuf_data (struct netbuf *buf, - void **dataptr, u16_t *len); -s8_t netbuf_next (struct netbuf *buf); -void netbuf_first (struct netbuf *buf); - - -#define netbuf_copy_partial(buf, dataptr, len, offset) \ - pbuf_copy_partial((buf)->p, (dataptr), (len), (offset)) -#define netbuf_copy(buf,dataptr,len) netbuf_copy_partial(buf, dataptr, len, 0) -#define netbuf_take(buf, dataptr, len) pbuf_take((buf)->p, dataptr, len) -#define netbuf_len(buf) ((buf)->p->tot_len) -#define netbuf_fromaddr(buf) (&((buf)->addr)) -#define netbuf_set_fromaddr(buf, fromaddr) ip_addr_set(&((buf)->addr), fromaddr) -#define netbuf_fromport(buf) ((buf)->port) -#if LWIP_NETBUF_RECVINFO -#define netbuf_destaddr(buf) (&((buf)->toaddr)) -#define netbuf_set_destaddr(buf, destaddr) ip_addr_set(&((buf)->toaddr), destaddr) -#if LWIP_CHECKSUM_ON_COPY -#define netbuf_destport(buf) (((buf)->flags & NETBUF_FLAG_DESTADDR) ? (buf)->toport_chksum : 0) -#else /* LWIP_CHECKSUM_ON_COPY */ -#define netbuf_destport(buf) ((buf)->toport_chksum) -#endif /* LWIP_CHECKSUM_ON_COPY */ -#endif /* LWIP_NETBUF_RECVINFO */ -#if LWIP_CHECKSUM_ON_COPY -#define netbuf_set_chksum(buf, chksum) do { (buf)->flags = NETBUF_FLAG_CHKSUM; \ - (buf)->toport_chksum = chksum; } while(0) -#endif /* LWIP_CHECKSUM_ON_COPY */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_NETCONN || LWIP_SOCKET */ - -#endif /* LWIP_HDR_NETBUF_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/netdb.h b/third-party/lwip-2.1.2/include/lwip/netdb.h deleted file mode 100644 index d3d15dfa..00000000 --- a/third-party/lwip-2.1.2/include/lwip/netdb.h +++ /dev/null @@ -1,150 +0,0 @@ -/** - * @file - * NETDB API (sockets) - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Simon Goldschmidt - * - */ -#ifndef LWIP_HDR_NETDB_H -#define LWIP_HDR_NETDB_H - -#include "lwip/opt.h" - -#if LWIP_DNS && LWIP_SOCKET - -#include "lwip/arch.h" -#include "lwip/inet.h" -#include "lwip/sockets.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* some rarely used options */ -#ifndef LWIP_DNS_API_DECLARE_H_ERRNO -#define LWIP_DNS_API_DECLARE_H_ERRNO 1 -#endif - -#ifndef LWIP_DNS_API_DEFINE_ERRORS -#define LWIP_DNS_API_DEFINE_ERRORS 1 -#endif - -#ifndef LWIP_DNS_API_DEFINE_FLAGS -#define LWIP_DNS_API_DEFINE_FLAGS 1 -#endif - -#ifndef LWIP_DNS_API_DECLARE_STRUCTS -#define LWIP_DNS_API_DECLARE_STRUCTS 1 -#endif - -#if LWIP_DNS_API_DEFINE_ERRORS -/** Errors used by the DNS API functions, h_errno can be one of them */ -#define EAI_NONAME 200 -#define EAI_SERVICE 201 -#define EAI_FAIL 202 -#define EAI_MEMORY 203 -#define EAI_FAMILY 204 - -#define HOST_NOT_FOUND 210 -#define NO_DATA 211 -#define NO_RECOVERY 212 -#define TRY_AGAIN 213 -#endif /* LWIP_DNS_API_DEFINE_ERRORS */ - -#if LWIP_DNS_API_DEFINE_FLAGS -/* input flags for struct addrinfo */ -#define AI_PASSIVE 0x01 -#define AI_CANONNAME 0x02 -#define AI_NUMERICHOST 0x04 -#define AI_NUMERICSERV 0x08 -#define AI_V4MAPPED 0x10 -#define AI_ALL 0x20 -#define AI_ADDRCONFIG 0x40 -#endif /* LWIP_DNS_API_DEFINE_FLAGS */ - -#if LWIP_DNS_API_DECLARE_STRUCTS -struct hostent { - char *h_name; /* Official name of the host. */ - char **h_aliases; /* A pointer to an array of pointers to alternative host names, - terminated by a null pointer. */ - int h_addrtype; /* Address type. */ - int h_length; /* The length, in bytes, of the address. */ - char **h_addr_list; /* A pointer to an array of pointers to network addresses (in - network byte order) for the host, terminated by a null pointer. */ -#define h_addr h_addr_list[0] /* for backward compatibility */ -}; - -struct addrinfo { - int ai_flags; /* Input flags. */ - int ai_family; /* Address family of socket. */ - int ai_socktype; /* Socket type. */ - int ai_protocol; /* Protocol of socket. */ - socklen_t ai_addrlen; /* Length of socket address. */ - struct sockaddr *ai_addr; /* Socket address of socket. */ - char *ai_canonname; /* Canonical name of service location. */ - struct addrinfo *ai_next; /* Pointer to next in list. */ -}; -#endif /* LWIP_DNS_API_DECLARE_STRUCTS */ - -#define NETDB_ELEM_SIZE (sizeof(struct addrinfo) + sizeof(struct sockaddr_storage) + DNS_MAX_NAME_LENGTH + 1) - -#if LWIP_DNS_API_DECLARE_H_ERRNO -/* application accessible error code set by the DNS API functions */ -extern int h_errno; -#endif /* LWIP_DNS_API_DECLARE_H_ERRNO*/ - -struct hostent *lwip_gethostbyname(const char *name); -int lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf, - size_t buflen, struct hostent **result, int *h_errnop); -void lwip_freeaddrinfo(struct addrinfo *ai); -int lwip_getaddrinfo(const char *nodename, - const char *servname, - const struct addrinfo *hints, - struct addrinfo **res); - -#if LWIP_COMPAT_SOCKETS -/** @ingroup netdbapi */ -#define gethostbyname(name) lwip_gethostbyname(name) -/** @ingroup netdbapi */ -#define gethostbyname_r(name, ret, buf, buflen, result, h_errnop) \ - lwip_gethostbyname_r(name, ret, buf, buflen, result, h_errnop) -/** @ingroup netdbapi */ -#define freeaddrinfo(addrinfo) lwip_freeaddrinfo(addrinfo) -/** @ingroup netdbapi */ -#define getaddrinfo(nodname, servname, hints, res) \ - lwip_getaddrinfo(nodname, servname, hints, res) -#endif /* LWIP_COMPAT_SOCKETS */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_DNS && LWIP_SOCKET */ - -#endif /* LWIP_HDR_NETDB_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/netif.h b/third-party/lwip-2.1.2/include/lwip/netif.h deleted file mode 100644 index 911196ab..00000000 --- a/third-party/lwip-2.1.2/include/lwip/netif.h +++ /dev/null @@ -1,669 +0,0 @@ -/** - * @file - * netif API (to be used from TCPIP thread) - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_NETIF_H -#define LWIP_HDR_NETIF_H - -#include "lwip/opt.h" - -#define ENABLE_LOOPBACK (LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF) - -#include "lwip/err.h" - -#include "lwip/ip_addr.h" - -#include "lwip/def.h" -#include "lwip/pbuf.h" -#include "lwip/stats.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Throughout this file, IP addresses are expected to be in - * the same byte order as in IP_PCB. */ - -/** Must be the maximum of all used hardware address lengths - across all types of interfaces in use. - This does not have to be changed, normally. */ -#ifndef NETIF_MAX_HWADDR_LEN -#define NETIF_MAX_HWADDR_LEN 6U -#endif - -/** The size of a fully constructed netif name which the - * netif can be identified by in APIs. Composed of - * 2 chars, 3 (max) digits, and 1 \0 - */ -#define NETIF_NAMESIZE 6 - -/** - * @defgroup netif_flags Flags - * @ingroup netif - * @{ - */ - -/** Whether the network interface is 'up'. This is - * a software flag used to control whether this network - * interface is enabled and processes traffic. - * It must be set by the startup code before this netif can be used - * (also for dhcp/autoip). - */ -#define NETIF_FLAG_UP 0x01U -/** If set, the netif has broadcast capability. - * Set by the netif driver in its init function. */ -#define NETIF_FLAG_BROADCAST 0x02U -/** If set, the interface has an active link - * (set by the network interface driver). - * Either set by the netif driver in its init function (if the link - * is up at that time) or at a later point once the link comes up - * (if link detection is supported by the hardware). */ -#define NETIF_FLAG_LINK_UP 0x04U -/** If set, the netif is an ethernet device using ARP. - * Set by the netif driver in its init function. - * Used to check input packet types and use of DHCP. */ -#define NETIF_FLAG_ETHARP 0x08U -/** If set, the netif is an ethernet device. It might not use - * ARP or TCP/IP if it is used for PPPoE only. - */ -#define NETIF_FLAG_ETHERNET 0x10U -/** If set, the netif has IGMP capability. - * Set by the netif driver in its init function. */ -#define NETIF_FLAG_IGMP 0x20U -/** If set, the netif has MLD6 capability. - * Set by the netif driver in its init function. */ -#define NETIF_FLAG_MLD6 0x40U - -/** - * @} - */ - -enum lwip_internal_netif_client_data_index -{ -#if LWIP_IPV4 -#if LWIP_DHCP - LWIP_NETIF_CLIENT_DATA_INDEX_DHCP, -#endif -#if LWIP_AUTOIP - LWIP_NETIF_CLIENT_DATA_INDEX_AUTOIP, -#endif -#if LWIP_IGMP - LWIP_NETIF_CLIENT_DATA_INDEX_IGMP, -#endif -#endif /* LWIP_IPV4 */ -#if LWIP_IPV6 -#if LWIP_IPV6_DHCP6 - LWIP_NETIF_CLIENT_DATA_INDEX_DHCP6, -#endif -#if LWIP_IPV6_MLD - LWIP_NETIF_CLIENT_DATA_INDEX_MLD6, -#endif -#endif /* LWIP_IPV6 */ - LWIP_NETIF_CLIENT_DATA_INDEX_MAX -}; - -#if LWIP_CHECKSUM_CTRL_PER_NETIF -#define NETIF_CHECKSUM_GEN_IP 0x0001 -#define NETIF_CHECKSUM_GEN_UDP 0x0002 -#define NETIF_CHECKSUM_GEN_TCP 0x0004 -#define NETIF_CHECKSUM_GEN_ICMP 0x0008 -#define NETIF_CHECKSUM_GEN_ICMP6 0x0010 -#define NETIF_CHECKSUM_CHECK_IP 0x0100 -#define NETIF_CHECKSUM_CHECK_UDP 0x0200 -#define NETIF_CHECKSUM_CHECK_TCP 0x0400 -#define NETIF_CHECKSUM_CHECK_ICMP 0x0800 -#define NETIF_CHECKSUM_CHECK_ICMP6 0x1000 -#define NETIF_CHECKSUM_ENABLE_ALL 0xFFFF -#define NETIF_CHECKSUM_DISABLE_ALL 0x0000 -#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */ - -struct netif; - -/** MAC Filter Actions, these are passed to a netif's igmp_mac_filter or - * mld_mac_filter callback function. */ -enum netif_mac_filter_action { - /** Delete a filter entry */ - NETIF_DEL_MAC_FILTER = 0, - /** Add a filter entry */ - NETIF_ADD_MAC_FILTER = 1 -}; - -/** Function prototype for netif init functions. Set up flags and output/linkoutput - * callback functions in this function. - * - * @param netif The netif to initialize - */ -typedef err_t (*netif_init_fn)(struct netif *netif); -/** Function prototype for netif->input functions. This function is saved as 'input' - * callback function in the netif struct. Call it when a packet has been received. - * - * @param p The received packet, copied into a pbuf - * @param inp The netif which received the packet - * @return ERR_OK if the packet was handled - * != ERR_OK is the packet was NOT handled, in this case, the caller has - * to free the pbuf - */ -typedef err_t (*netif_input_fn)(struct pbuf *p, struct netif *inp); - -#if LWIP_IPV4 -/** Function prototype for netif->output functions. Called by lwIP when a packet - * shall be sent. For ethernet netif, set this to 'etharp_output' and set - * 'linkoutput'. - * - * @param netif The netif which shall send a packet - * @param p The packet to send (p->payload points to IP header) - * @param ipaddr The IP address to which the packet shall be sent - */ -typedef err_t (*netif_output_fn)(struct netif *netif, struct pbuf *p, - const ip4_addr_t *ipaddr); -#endif /* LWIP_IPV4*/ - -#if LWIP_IPV6 -/** Function prototype for netif->output_ip6 functions. Called by lwIP when a packet - * shall be sent. For ethernet netif, set this to 'ethip6_output' and set - * 'linkoutput'. - * - * @param netif The netif which shall send a packet - * @param p The packet to send (p->payload points to IP header) - * @param ipaddr The IPv6 address to which the packet shall be sent - */ -typedef err_t (*netif_output_ip6_fn)(struct netif *netif, struct pbuf *p, - const ip6_addr_t *ipaddr); -#endif /* LWIP_IPV6 */ - -/** Function prototype for netif->linkoutput functions. Only used for ethernet - * netifs. This function is called by ARP when a packet shall be sent. - * - * @param netif The netif which shall send a packet - * @param p The packet to send (raw ethernet packet) - */ -typedef err_t (*netif_linkoutput_fn)(struct netif *netif, struct pbuf *p); -/** Function prototype for netif status- or link-callback functions. */ -typedef void (*netif_status_callback_fn)(struct netif *netif); -#if LWIP_IPV4 && LWIP_IGMP -/** Function prototype for netif igmp_mac_filter functions */ -typedef err_t (*netif_igmp_mac_filter_fn)(struct netif *netif, - const ip4_addr_t *group, enum netif_mac_filter_action action); -#endif /* LWIP_IPV4 && LWIP_IGMP */ -#if LWIP_IPV6 && LWIP_IPV6_MLD -/** Function prototype for netif mld_mac_filter functions */ -typedef err_t (*netif_mld_mac_filter_fn)(struct netif *netif, - const ip6_addr_t *group, enum netif_mac_filter_action action); -#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ - -#if LWIP_DHCP || LWIP_AUTOIP || LWIP_IGMP || LWIP_IPV6_MLD || LWIP_IPV6_DHCP6 || (LWIP_NUM_NETIF_CLIENT_DATA > 0) -#if LWIP_NUM_NETIF_CLIENT_DATA > 0 -u8_t netif_alloc_client_data_id(void); -#endif -/** @ingroup netif_cd - * Set client data. Obtain ID from netif_alloc_client_data_id(). - */ -#define netif_set_client_data(netif, id, data) netif_get_client_data(netif, id) = (data) -/** @ingroup netif_cd - * Get client data. Obtain ID from netif_alloc_client_data_id(). - */ -#define netif_get_client_data(netif, id) (netif)->client_data[(id)] -#endif - -#if (LWIP_IPV4 && LWIP_ARP && (ARP_TABLE_SIZE > 0x7f)) || (LWIP_IPV6 && (LWIP_ND6_NUM_DESTINATIONS > 0x7f)) -typedef u16_t netif_addr_idx_t; -#define NETIF_ADDR_IDX_MAX 0x7FFF -#else -typedef u8_t netif_addr_idx_t; -#define NETIF_ADDR_IDX_MAX 0x7F -#endif - -#if LWIP_NETIF_HWADDRHINT -#define LWIP_NETIF_USE_HINTS 1 -struct netif_hint { - netif_addr_idx_t addr_hint; -}; -#else /* LWIP_NETIF_HWADDRHINT */ -#define LWIP_NETIF_USE_HINTS 0 -#endif /* LWIP_NETIF_HWADDRHINT */ - -/** Generic data structure used for all lwIP network interfaces. - * The following fields should be filled in by the initialization - * function for the device driver: hwaddr_len, hwaddr[], mtu, flags */ -struct netif { -#if !LWIP_SINGLE_NETIF - /** pointer to next in linked list */ - struct netif *next; -#endif - -#if LWIP_IPV4 - /** IP address configuration in network byte order */ - ip_addr_t ip_addr; - ip_addr_t netmask; - ip_addr_t gw; -#endif /* LWIP_IPV4 */ -#if LWIP_IPV6 - /** Array of IPv6 addresses for this netif. */ - ip_addr_t ip6_addr[LWIP_IPV6_NUM_ADDRESSES]; - /** The state of each IPv6 address (Tentative, Preferred, etc). - * @see ip6_addr.h */ - u8_t ip6_addr_state[LWIP_IPV6_NUM_ADDRESSES]; -#if LWIP_IPV6_ADDRESS_LIFETIMES - /** Remaining valid and preferred lifetime of each IPv6 address, in seconds. - * For valid lifetimes, the special value of IP6_ADDR_LIFE_STATIC (0) - * indicates the address is static and has no lifetimes. */ - u32_t ip6_addr_valid_life[LWIP_IPV6_NUM_ADDRESSES]; - u32_t ip6_addr_pref_life[LWIP_IPV6_NUM_ADDRESSES]; -#endif /* LWIP_IPV6_ADDRESS_LIFETIMES */ -#endif /* LWIP_IPV6 */ - /** This function is called by the network device driver - * to pass a packet up the TCP/IP stack. */ - netif_input_fn input; -#if LWIP_IPV4 - /** This function is called by the IP module when it wants - * to send a packet on the interface. This function typically - * first resolves the hardware address, then sends the packet. - * For ethernet physical layer, this is usually etharp_output() */ - netif_output_fn output; -#endif /* LWIP_IPV4 */ - /** This function is called by ethernet_output() when it wants - * to send a packet on the interface. This function outputs - * the pbuf as-is on the link medium. */ - netif_linkoutput_fn linkoutput; -#if LWIP_IPV6 - /** This function is called by the IPv6 module when it wants - * to send a packet on the interface. This function typically - * first resolves the hardware address, then sends the packet. - * For ethernet physical layer, this is usually ethip6_output() */ - netif_output_ip6_fn output_ip6; -#endif /* LWIP_IPV6 */ -#if LWIP_NETIF_STATUS_CALLBACK - /** This function is called when the netif state is set to up or down - */ - netif_status_callback_fn status_callback; -#endif /* LWIP_NETIF_STATUS_CALLBACK */ -#if LWIP_NETIF_LINK_CALLBACK - /** This function is called when the netif link is set to up or down - */ - netif_status_callback_fn link_callback; -#endif /* LWIP_NETIF_LINK_CALLBACK */ -#if LWIP_NETIF_REMOVE_CALLBACK - /** This function is called when the netif has been removed */ - netif_status_callback_fn remove_callback; -#endif /* LWIP_NETIF_REMOVE_CALLBACK */ - /** This field can be set by the device driver and could point - * to state information for the device. */ - void *state; -#ifdef netif_get_client_data - void* client_data[LWIP_NETIF_CLIENT_DATA_INDEX_MAX + LWIP_NUM_NETIF_CLIENT_DATA]; -#endif -#if LWIP_NETIF_HOSTNAME - /* the hostname for this netif, NULL is a valid value */ - const char* hostname; -#endif /* LWIP_NETIF_HOSTNAME */ -#if LWIP_CHECKSUM_CTRL_PER_NETIF - u16_t chksum_flags; -#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF*/ - /** maximum transfer unit (in bytes) */ - u16_t mtu; -#if LWIP_IPV6 && LWIP_ND6_ALLOW_RA_UPDATES - /** maximum transfer unit (in bytes), updated by RA */ - u16_t mtu6; -#endif /* LWIP_IPV6 && LWIP_ND6_ALLOW_RA_UPDATES */ - /** link level hardware address of this interface */ - u8_t hwaddr[NETIF_MAX_HWADDR_LEN]; - /** number of bytes used in hwaddr */ - u8_t hwaddr_len; - /** flags (@see @ref netif_flags) */ - u8_t flags; - /** descriptive abbreviation */ - char name[2]; - /** number of this interface. Used for @ref if_api and @ref netifapi_netif, - * as well as for IPv6 zones */ - u8_t num; -#if LWIP_IPV6_AUTOCONFIG - /** is this netif enabled for IPv6 autoconfiguration */ - u8_t ip6_autoconfig_enabled; -#endif /* LWIP_IPV6_AUTOCONFIG */ -#if LWIP_IPV6_SEND_ROUTER_SOLICIT - /** Number of Router Solicitation messages that remain to be sent. */ - u8_t rs_count; -#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ -#if MIB2_STATS - /** link type (from "snmp_ifType" enum from snmp_mib2.h) */ - u8_t link_type; - /** (estimate) link speed */ - u32_t link_speed; - /** timestamp at last change made (up/down) */ - u32_t ts; - /** counters */ - struct stats_mib2_netif_ctrs mib2_counters; -#endif /* MIB2_STATS */ -#if LWIP_IPV4 && LWIP_IGMP - /** This function could be called to add or delete an entry in the multicast - filter table of the ethernet MAC.*/ - netif_igmp_mac_filter_fn igmp_mac_filter; -#endif /* LWIP_IPV4 && LWIP_IGMP */ -#if LWIP_IPV6 && LWIP_IPV6_MLD - /** This function could be called to add or delete an entry in the IPv6 multicast - filter table of the ethernet MAC. */ - netif_mld_mac_filter_fn mld_mac_filter; -#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ -#if LWIP_NETIF_USE_HINTS - struct netif_hint *hints; -#endif /* LWIP_NETIF_USE_HINTS */ -#if ENABLE_LOOPBACK - /* List of packets to be queued for ourselves. */ - struct pbuf *loop_first; - struct pbuf *loop_last; -#if LWIP_LOOPBACK_MAX_PBUFS - u16_t loop_cnt_current; -#endif /* LWIP_LOOPBACK_MAX_PBUFS */ -#endif /* ENABLE_LOOPBACK */ -}; - -#if LWIP_CHECKSUM_CTRL_PER_NETIF -#define NETIF_SET_CHECKSUM_CTRL(netif, chksumflags) do { \ - (netif)->chksum_flags = chksumflags; } while(0) -#define IF__NETIF_CHECKSUM_ENABLED(netif, chksumflag) if (((netif) == NULL) || (((netif)->chksum_flags & (chksumflag)) != 0)) -#else /* LWIP_CHECKSUM_CTRL_PER_NETIF */ -#define NETIF_SET_CHECKSUM_CTRL(netif, chksumflags) -#define IF__NETIF_CHECKSUM_ENABLED(netif, chksumflag) -#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */ - -#if LWIP_SINGLE_NETIF -#define NETIF_FOREACH(netif) if (((netif) = netif_default) != NULL) -#else /* LWIP_SINGLE_NETIF */ -/** The list of network interfaces. */ -extern struct netif *netif_list; -#define NETIF_FOREACH(netif) for ((netif) = netif_list; (netif) != NULL; (netif) = (netif)->next) -#endif /* LWIP_SINGLE_NETIF */ -/** The default network interface. */ -extern struct netif *netif_default; - -void netif_init(void); - -struct netif *netif_add_noaddr(struct netif *netif, void *state, netif_init_fn init, netif_input_fn input); - -#if LWIP_IPV4 -struct netif *netif_add(struct netif *netif, - const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw, - void *state, netif_init_fn init, netif_input_fn input); -void netif_set_addr(struct netif *netif, const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, - const ip4_addr_t *gw); -#else /* LWIP_IPV4 */ -struct netif *netif_add(struct netif *netif, void *state, netif_init_fn init, netif_input_fn input); -#endif /* LWIP_IPV4 */ -void netif_remove(struct netif * netif); - -/* Returns a network interface given its name. The name is of the form - "et0", where the first two letters are the "name" field in the - netif structure, and the digit is in the num field in the same - structure. */ -struct netif *netif_find(const char *name); - -void netif_set_default(struct netif *netif); - -#if LWIP_IPV4 -void netif_set_ipaddr(struct netif *netif, const ip4_addr_t *ipaddr); -void netif_set_netmask(struct netif *netif, const ip4_addr_t *netmask); -void netif_set_gw(struct netif *netif, const ip4_addr_t *gw); -/** @ingroup netif_ip4 */ -#define netif_ip4_addr(netif) ((const ip4_addr_t*)ip_2_ip4(&((netif)->ip_addr))) -/** @ingroup netif_ip4 */ -#define netif_ip4_netmask(netif) ((const ip4_addr_t*)ip_2_ip4(&((netif)->netmask))) -/** @ingroup netif_ip4 */ -#define netif_ip4_gw(netif) ((const ip4_addr_t*)ip_2_ip4(&((netif)->gw))) -/** @ingroup netif_ip4 */ -#define netif_ip_addr4(netif) ((const ip_addr_t*)&((netif)->ip_addr)) -/** @ingroup netif_ip4 */ -#define netif_ip_netmask4(netif) ((const ip_addr_t*)&((netif)->netmask)) -/** @ingroup netif_ip4 */ -#define netif_ip_gw4(netif) ((const ip_addr_t*)&((netif)->gw)) -#endif /* LWIP_IPV4 */ - -#define netif_set_flags(netif, set_flags) do { (netif)->flags = (u8_t)((netif)->flags | (set_flags)); } while(0) -#define netif_clear_flags(netif, clr_flags) do { (netif)->flags = (u8_t)((netif)->flags & (u8_t)(~(clr_flags) & 0xff)); } while(0) -#define netif_is_flag_set(nefif, flag) (((netif)->flags & (flag)) != 0) - -void netif_set_up(struct netif *netif); -void netif_set_down(struct netif *netif); -/** @ingroup netif - * Ask if an interface is up - */ -#define netif_is_up(netif) (((netif)->flags & NETIF_FLAG_UP) ? (u8_t)1 : (u8_t)0) - -#if LWIP_NETIF_STATUS_CALLBACK -void netif_set_status_callback(struct netif *netif, netif_status_callback_fn status_callback); -#endif /* LWIP_NETIF_STATUS_CALLBACK */ -#if LWIP_NETIF_REMOVE_CALLBACK -void netif_set_remove_callback(struct netif *netif, netif_status_callback_fn remove_callback); -#endif /* LWIP_NETIF_REMOVE_CALLBACK */ - -void netif_set_link_up(struct netif *netif); -void netif_set_link_down(struct netif *netif); -/** Ask if a link is up */ -#define netif_is_link_up(netif) (((netif)->flags & NETIF_FLAG_LINK_UP) ? (u8_t)1 : (u8_t)0) - -#if LWIP_NETIF_LINK_CALLBACK -void netif_set_link_callback(struct netif *netif, netif_status_callback_fn link_callback); -#endif /* LWIP_NETIF_LINK_CALLBACK */ - -#if LWIP_NETIF_HOSTNAME -/** @ingroup netif */ -#define netif_set_hostname(netif, name) do { if((netif) != NULL) { (netif)->hostname = name; }}while(0) -/** @ingroup netif */ -#define netif_get_hostname(netif) (((netif) != NULL) ? ((netif)->hostname) : NULL) -#endif /* LWIP_NETIF_HOSTNAME */ - -#if LWIP_IGMP -/** @ingroup netif */ -#define netif_set_igmp_mac_filter(netif, function) do { if((netif) != NULL) { (netif)->igmp_mac_filter = function; }}while(0) -#define netif_get_igmp_mac_filter(netif) (((netif) != NULL) ? ((netif)->igmp_mac_filter) : NULL) -#endif /* LWIP_IGMP */ - -#if LWIP_IPV6 && LWIP_IPV6_MLD -/** @ingroup netif */ -#define netif_set_mld_mac_filter(netif, function) do { if((netif) != NULL) { (netif)->mld_mac_filter = function; }}while(0) -#define netif_get_mld_mac_filter(netif) (((netif) != NULL) ? ((netif)->mld_mac_filter) : NULL) -#define netif_mld_mac_filter(netif, addr, action) do { if((netif) && (netif)->mld_mac_filter) { (netif)->mld_mac_filter((netif), (addr), (action)); }}while(0) -#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ - -#if ENABLE_LOOPBACK -err_t netif_loop_output(struct netif *netif, struct pbuf *p); -void netif_poll(struct netif *netif); -#if !LWIP_NETIF_LOOPBACK_MULTITHREADING -void netif_poll_all(void); -#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */ -#endif /* ENABLE_LOOPBACK */ - -err_t netif_input(struct pbuf *p, struct netif *inp); - -#if LWIP_IPV6 -/** @ingroup netif_ip6 */ -#define netif_ip_addr6(netif, i) ((const ip_addr_t*)(&((netif)->ip6_addr[i]))) -/** @ingroup netif_ip6 */ -#define netif_ip6_addr(netif, i) ((const ip6_addr_t*)ip_2_ip6(&((netif)->ip6_addr[i]))) -void netif_ip6_addr_set(struct netif *netif, s8_t addr_idx, const ip6_addr_t *addr6); -void netif_ip6_addr_set_parts(struct netif *netif, s8_t addr_idx, u32_t i0, u32_t i1, u32_t i2, u32_t i3); -#define netif_ip6_addr_state(netif, i) ((netif)->ip6_addr_state[i]) -void netif_ip6_addr_set_state(struct netif* netif, s8_t addr_idx, u8_t state); -s8_t netif_get_ip6_addr_match(struct netif *netif, const ip6_addr_t *ip6addr); -void netif_create_ip6_linklocal_address(struct netif *netif, u8_t from_mac_48bit); -err_t netif_add_ip6_address(struct netif *netif, const ip6_addr_t *ip6addr, s8_t *chosen_idx); -#define netif_set_ip6_autoconfig_enabled(netif, action) do { if(netif) { (netif)->ip6_autoconfig_enabled = (action); }}while(0) -#if LWIP_IPV6_ADDRESS_LIFETIMES -#define netif_ip6_addr_valid_life(netif, i) \ - (((netif) != NULL) ? ((netif)->ip6_addr_valid_life[i]) : IP6_ADDR_LIFE_STATIC) -#define netif_ip6_addr_set_valid_life(netif, i, secs) \ - do { if (netif != NULL) { (netif)->ip6_addr_valid_life[i] = (secs); }} while (0) -#define netif_ip6_addr_pref_life(netif, i) \ - (((netif) != NULL) ? ((netif)->ip6_addr_pref_life[i]) : IP6_ADDR_LIFE_STATIC) -#define netif_ip6_addr_set_pref_life(netif, i, secs) \ - do { if (netif != NULL) { (netif)->ip6_addr_pref_life[i] = (secs); }} while (0) -#define netif_ip6_addr_isstatic(netif, i) \ - (netif_ip6_addr_valid_life((netif), (i)) == IP6_ADDR_LIFE_STATIC) -#else /* !LWIP_IPV6_ADDRESS_LIFETIMES */ -#define netif_ip6_addr_isstatic(netif, i) (1) /* all addresses are static */ -#endif /* !LWIP_IPV6_ADDRESS_LIFETIMES */ -#if LWIP_ND6_ALLOW_RA_UPDATES -#define netif_mtu6(netif) ((netif)->mtu6) -#else /* LWIP_ND6_ALLOW_RA_UPDATES */ -#define netif_mtu6(netif) ((netif)->mtu) -#endif /* LWIP_ND6_ALLOW_RA_UPDATES */ -#endif /* LWIP_IPV6 */ - -#if LWIP_NETIF_USE_HINTS -#define NETIF_SET_HINTS(netif, netifhint) (netif)->hints = (netifhint) -#define NETIF_RESET_HINTS(netif) (netif)->hints = NULL -#else /* LWIP_NETIF_USE_HINTS */ -#define NETIF_SET_HINTS(netif, netifhint) -#define NETIF_RESET_HINTS(netif) -#endif /* LWIP_NETIF_USE_HINTS */ - -u8_t netif_name_to_index(const char *name); -char * netif_index_to_name(u8_t idx, char *name); -struct netif* netif_get_by_index(u8_t idx); - -/* Interface indexes always start at 1 per RFC 3493, section 4, num starts at 0 (internal index is 0..254)*/ -#define netif_get_index(netif) ((u8_t)((netif)->num + 1)) -#define NETIF_NO_INDEX (0) - -/** - * @ingroup netif - * Extended netif status callback (NSC) reasons flags. - * May be extended in the future! - */ -typedef u16_t netif_nsc_reason_t; - -/* used for initialization only */ -#define LWIP_NSC_NONE 0x0000 -/** netif was added. arg: NULL. Called AFTER netif was added. */ -#define LWIP_NSC_NETIF_ADDED 0x0001 -/** netif was removed. arg: NULL. Called BEFORE netif is removed. */ -#define LWIP_NSC_NETIF_REMOVED 0x0002 -/** link changed */ -#define LWIP_NSC_LINK_CHANGED 0x0004 -/** netif administrative status changed.\n - * up is called AFTER netif is set up.\n - * down is called BEFORE the netif is actually set down. */ -#define LWIP_NSC_STATUS_CHANGED 0x0008 -/** IPv4 address has changed */ -#define LWIP_NSC_IPV4_ADDRESS_CHANGED 0x0010 -/** IPv4 gateway has changed */ -#define LWIP_NSC_IPV4_GATEWAY_CHANGED 0x0020 -/** IPv4 netmask has changed */ -#define LWIP_NSC_IPV4_NETMASK_CHANGED 0x0040 -/** called AFTER IPv4 address/gateway/netmask changes have been applied */ -#define LWIP_NSC_IPV4_SETTINGS_CHANGED 0x0080 -/** IPv6 address was added */ -#define LWIP_NSC_IPV6_SET 0x0100 -/** IPv6 address state has changed */ -#define LWIP_NSC_IPV6_ADDR_STATE_CHANGED 0x0200 - -/** @ingroup netif - * Argument supplied to netif_ext_callback_fn. - */ -typedef union -{ - /** Args to LWIP_NSC_LINK_CHANGED callback */ - struct link_changed_s - { - /** 1: up; 0: down */ - u8_t state; - } link_changed; - /** Args to LWIP_NSC_STATUS_CHANGED callback */ - struct status_changed_s - { - /** 1: up; 0: down */ - u8_t state; - } status_changed; - /** Args to LWIP_NSC_IPV4_ADDRESS_CHANGED|LWIP_NSC_IPV4_GATEWAY_CHANGED|LWIP_NSC_IPV4_NETMASK_CHANGED|LWIP_NSC_IPV4_SETTINGS_CHANGED callback */ - struct ipv4_changed_s - { - /** Old IPv4 address */ - const ip_addr_t* old_address; - const ip_addr_t* old_netmask; - const ip_addr_t* old_gw; - } ipv4_changed; - /** Args to LWIP_NSC_IPV6_SET callback */ - struct ipv6_set_s - { - /** Index of changed IPv6 address */ - s8_t addr_index; - /** Old IPv6 address */ - const ip_addr_t* old_address; - } ipv6_set; - /** Args to LWIP_NSC_IPV6_ADDR_STATE_CHANGED callback */ - struct ipv6_addr_state_changed_s - { - /** Index of affected IPv6 address */ - s8_t addr_index; - /** Old IPv6 address state */ - u8_t old_state; - /** Affected IPv6 address */ - const ip_addr_t* address; - } ipv6_addr_state_changed; -} netif_ext_callback_args_t; - -/** - * @ingroup netif - * Function used for extended netif status callbacks - * Note: When parsing reason argument, keep in mind that more reasons may be added in the future! - * @param netif netif that is affected by change - * @param reason change reason - * @param args depends on reason, see reason description - */ -typedef void (*netif_ext_callback_fn)(struct netif* netif, netif_nsc_reason_t reason, const netif_ext_callback_args_t* args); - -#if LWIP_NETIF_EXT_STATUS_CALLBACK -struct netif_ext_callback; -typedef struct netif_ext_callback -{ - netif_ext_callback_fn callback_fn; - struct netif_ext_callback* next; -} netif_ext_callback_t; - -#define NETIF_DECLARE_EXT_CALLBACK(name) static netif_ext_callback_t name; -void netif_add_ext_callback(netif_ext_callback_t* callback, netif_ext_callback_fn fn); -void netif_remove_ext_callback(netif_ext_callback_t* callback); -void netif_invoke_ext_callback(struct netif* netif, netif_nsc_reason_t reason, const netif_ext_callback_args_t* args); -#else -#define NETIF_DECLARE_EXT_CALLBACK(name) -#define netif_add_ext_callback(callback, fn) -#define netif_remove_ext_callback(callback) -#define netif_invoke_ext_callback(netif, reason, args) -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_NETIF_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/netifapi.h b/third-party/lwip-2.1.2/include/lwip/netifapi.h deleted file mode 100644 index e0631791..00000000 --- a/third-party/lwip-2.1.2/include/lwip/netifapi.h +++ /dev/null @@ -1,161 +0,0 @@ -/** - * @file - * netif API (to be used from non-TCPIP threads) - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ -#ifndef LWIP_HDR_NETIFAPI_H -#define LWIP_HDR_NETIFAPI_H - -#include "lwip/opt.h" - -#if LWIP_NETIF_API /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/sys.h" -#include "lwip/netif.h" -#include "lwip/dhcp.h" -#include "lwip/autoip.h" -#include "lwip/priv/tcpip_priv.h" -#include "lwip/priv/api_msg.h" -#include "lwip/prot/ethernet.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* API for application */ -#if LWIP_ARP && LWIP_IPV4 -/* Used for netfiapi_arp_* APIs */ -enum netifapi_arp_entry { - NETIFAPI_ARP_PERM /* Permanent entry */ - /* Other entry types can be added here */ -}; - -/** @ingroup netifapi_arp */ -err_t netifapi_arp_add(const ip4_addr_t *ipaddr, struct eth_addr *ethaddr, enum netifapi_arp_entry type); -/** @ingroup netifapi_arp */ -err_t netifapi_arp_remove(const ip4_addr_t *ipaddr, enum netifapi_arp_entry type); -#endif /* LWIP_ARP && LWIP_IPV4 */ - -err_t netifapi_netif_add(struct netif *netif, -#if LWIP_IPV4 - const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw, -#endif /* LWIP_IPV4 */ - void *state, netif_init_fn init, netif_input_fn input); - -#if LWIP_IPV4 -err_t netifapi_netif_set_addr(struct netif *netif, const ip4_addr_t *ipaddr, - const ip4_addr_t *netmask, const ip4_addr_t *gw); -#endif /* LWIP_IPV4*/ - -err_t netifapi_netif_common(struct netif *netif, netifapi_void_fn voidfunc, - netifapi_errt_fn errtfunc); - -/** @ingroup netifapi_netif */ -err_t netifapi_netif_name_to_index(const char *name, u8_t *index); -/** @ingroup netifapi_netif */ -err_t netifapi_netif_index_to_name(u8_t index, char *name); - -/** @ingroup netifapi_netif - * @see netif_remove() - */ -#define netifapi_netif_remove(n) netifapi_netif_common(n, netif_remove, NULL) -/** @ingroup netifapi_netif - * @see netif_set_up() - */ -#define netifapi_netif_set_up(n) netifapi_netif_common(n, netif_set_up, NULL) -/** @ingroup netifapi_netif - * @see netif_set_down() - */ -#define netifapi_netif_set_down(n) netifapi_netif_common(n, netif_set_down, NULL) -/** @ingroup netifapi_netif - * @see netif_set_default() - */ -#define netifapi_netif_set_default(n) netifapi_netif_common(n, netif_set_default, NULL) -/** @ingroup netifapi_netif - * @see netif_set_link_up() - */ -#define netifapi_netif_set_link_up(n) netifapi_netif_common(n, netif_set_link_up, NULL) -/** @ingroup netifapi_netif - * @see netif_set_link_down() - */ -#define netifapi_netif_set_link_down(n) netifapi_netif_common(n, netif_set_link_down, NULL) - -/** - * @defgroup netifapi_dhcp4 DHCPv4 - * @ingroup netifapi - * To be called from non-TCPIP threads - */ -/** @ingroup netifapi_dhcp4 - * @see dhcp_start() - */ -#define netifapi_dhcp_start(n) netifapi_netif_common(n, NULL, dhcp_start) -/** - * @ingroup netifapi_dhcp4 - * @deprecated Use netifapi_dhcp_release_and_stop() instead. - */ -#define netifapi_dhcp_stop(n) netifapi_netif_common(n, dhcp_stop, NULL) -/** @ingroup netifapi_dhcp4 - * @see dhcp_inform() - */ -#define netifapi_dhcp_inform(n) netifapi_netif_common(n, dhcp_inform, NULL) -/** @ingroup netifapi_dhcp4 - * @see dhcp_renew() - */ -#define netifapi_dhcp_renew(n) netifapi_netif_common(n, NULL, dhcp_renew) -/** - * @ingroup netifapi_dhcp4 - * @deprecated Use netifapi_dhcp_release_and_stop() instead. - */ -#define netifapi_dhcp_release(n) netifapi_netif_common(n, NULL, dhcp_release) -/** @ingroup netifapi_dhcp4 - * @see dhcp_release_and_stop() - */ -#define netifapi_dhcp_release_and_stop(n) netifapi_netif_common(n, dhcp_release_and_stop, NULL) - -/** - * @defgroup netifapi_autoip AUTOIP - * @ingroup netifapi - * To be called from non-TCPIP threads - */ -/** @ingroup netifapi_autoip - * @see autoip_start() - */ -#define netifapi_autoip_start(n) netifapi_netif_common(n, NULL, autoip_start) -/** @ingroup netifapi_autoip - * @see autoip_stop() - */ -#define netifapi_autoip_stop(n) netifapi_netif_common(n, NULL, autoip_stop) - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_NETIF_API */ - -#endif /* LWIP_HDR_NETIFAPI_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/opt.h b/third-party/lwip-2.1.2/include/lwip/opt.h deleted file mode 100644 index d34cb899..00000000 --- a/third-party/lwip-2.1.2/include/lwip/opt.h +++ /dev/null @@ -1,3519 +0,0 @@ -/** - * @file - * - * lwIP Options Configuration - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -/* - * NOTE: || defined __DOXYGEN__ is a workaround for doxygen bug - - * without this, doxygen does not see the actual #define - */ - -#if !defined LWIP_HDR_OPT_H -#define LWIP_HDR_OPT_H - -/* - * Include user defined options first. Anything not defined in these files - * will be set to standard values. Override anything you don't like! - */ -#include "lwipopts.h" -#include "lwip/debug.h" - -/** - * @defgroup lwip_opts Options (lwipopts.h) - * @ingroup lwip - * - * @defgroup lwip_opts_debug Debugging - * @ingroup lwip_opts - * - * @defgroup lwip_opts_infrastructure Infrastructure - * @ingroup lwip_opts - * - * @defgroup lwip_opts_callback Callback-style APIs - * @ingroup lwip_opts - * - * @defgroup lwip_opts_threadsafe_apis Thread-safe APIs - * @ingroup lwip_opts - */ - - /* - ------------------------------------ - -------------- NO SYS -------------- - ------------------------------------ -*/ -/** - * @defgroup lwip_opts_nosys NO_SYS - * @ingroup lwip_opts_infrastructure - * @{ - */ -/** - * NO_SYS==1: Use lwIP without OS-awareness (no thread, semaphores, mutexes or - * mboxes). This means threaded APIs cannot be used (socket, netconn, - * i.e. everything in the 'api' folder), only the callback-style raw API is - * available (and you have to watch out for yourself that you don't access - * lwIP functions/structures from more than one context at a time!) - */ -#if !defined NO_SYS || defined __DOXYGEN__ -#define NO_SYS 0 -#endif -/** - * @} - */ - -/** - * @defgroup lwip_opts_timers Timers - * @ingroup lwip_opts_infrastructure - * @{ - */ -/** - * LWIP_TIMERS==0: Drop support for sys_timeout and lwip-internal cyclic timers. - * (the array of lwip-internal cyclic timers is still provided) - * (check NO_SYS_NO_TIMERS for compatibility to old versions) - */ -#if !defined LWIP_TIMERS || defined __DOXYGEN__ -#ifdef NO_SYS_NO_TIMERS -#define LWIP_TIMERS (!NO_SYS || (NO_SYS && !NO_SYS_NO_TIMERS)) -#else -#define LWIP_TIMERS 1 -#endif -#endif - -/** - * LWIP_TIMERS_CUSTOM==1: Provide your own timer implementation. - * Function prototypes in timeouts.h and the array of lwip-internal cyclic timers - * are still included, but the implementation is not. The following functions - * will be required: sys_timeouts_init(), sys_timeout(), sys_untimeout(), - * sys_timeouts_mbox_fetch() - */ -#if !defined LWIP_TIMERS_CUSTOM || defined __DOXYGEN__ -#define LWIP_TIMERS_CUSTOM 0 -#endif -/** - * @} - */ - -/** - * @defgroup lwip_opts_memcpy memcpy - * @ingroup lwip_opts_infrastructure - * @{ - */ -/** - * MEMCPY: override this if you have a faster implementation at hand than the - * one included in your C library - */ -#if !defined MEMCPY || defined __DOXYGEN__ -#define MEMCPY(dst,src,len) memcpy(dst,src,len) -#endif - -/** - * SMEMCPY: override this with care! Some compilers (e.g. gcc) can inline a - * call to memcpy() if the length is known at compile time and is small. - */ -#if !defined SMEMCPY || defined __DOXYGEN__ -#define SMEMCPY(dst,src,len) memcpy(dst,src,len) -#endif - -/** - * MEMMOVE: override this if you have a faster implementation at hand than the - * one included in your C library. lwIP currently uses MEMMOVE only when IPv6 - * fragmentation support is enabled. - */ -#if !defined MEMMOVE || defined __DOXYGEN__ -#define MEMMOVE(dst,src,len) memmove(dst,src,len) -#endif -/** - * @} - */ - -/* - ------------------------------------ - ----------- Core locking ----------- - ------------------------------------ -*/ -/** - * @defgroup lwip_opts_lock Core locking and MPU - * @ingroup lwip_opts_infrastructure - * @{ - */ -/** - * LWIP_MPU_COMPATIBLE: enables special memory management mechanism - * which makes lwip able to work on MPU (Memory Protection Unit) system - * by not passing stack-pointers to other threads - * (this decreases performance as memory is allocated from pools instead - * of keeping it on the stack) - */ -#if !defined LWIP_MPU_COMPATIBLE || defined __DOXYGEN__ -#define LWIP_MPU_COMPATIBLE 0 -#endif - -/** - * LWIP_TCPIP_CORE_LOCKING - * Creates a global mutex that is held during TCPIP thread operations. - * Can be locked by client code to perform lwIP operations without changing - * into TCPIP thread using callbacks. See LOCK_TCPIP_CORE() and - * UNLOCK_TCPIP_CORE(). - * Your system should provide mutexes supporting priority inversion to use this. - */ -#if !defined LWIP_TCPIP_CORE_LOCKING || defined __DOXYGEN__ -#define LWIP_TCPIP_CORE_LOCKING 0 -#endif - -/** - * LWIP_TCPIP_CORE_LOCKING_INPUT: when LWIP_TCPIP_CORE_LOCKING is enabled, - * this lets tcpip_input() grab the mutex for input packets as well, - * instead of allocating a message and passing it to tcpip_thread. - * - * ATTENTION: this does not work when tcpip_input() is called from - * interrupt context! - */ -#if !defined LWIP_TCPIP_CORE_LOCKING_INPUT || defined __DOXYGEN__ -#define LWIP_TCPIP_CORE_LOCKING_INPUT 0 -#endif - -/** - * SYS_LIGHTWEIGHT_PROT==1: enable inter-task protection (and task-vs-interrupt - * protection) for certain critical regions during buffer allocation, deallocation - * and memory allocation and deallocation. - * ATTENTION: This is required when using lwIP from more than one context! If - * you disable this, you must be sure what you are doing! - */ -#if !defined SYS_LIGHTWEIGHT_PROT || defined __DOXYGEN__ -#define SYS_LIGHTWEIGHT_PROT 1 -#endif - -/** - * Macro/function to check whether lwIP's threading/locking - * requirements are satisfied during current function call. - * This macro usually calls a function that is implemented in the OS-dependent - * sys layer and performs the following checks: - * - Not in ISR (this should be checked for NO_SYS==1, too!) - * - If @ref LWIP_TCPIP_CORE_LOCKING = 1: TCPIP core lock is held - * - If @ref LWIP_TCPIP_CORE_LOCKING = 0: function is called from TCPIP thread - * @see @ref multithreading - */ -#if !defined LWIP_ASSERT_CORE_LOCKED || defined __DOXYGEN__ -#define LWIP_ASSERT_CORE_LOCKED() -#endif - -/** - * Called as first thing in the lwIP TCPIP thread. Can be used in conjunction - * with @ref LWIP_ASSERT_CORE_LOCKED to check core locking. - * @see @ref multithreading - */ -#if !defined LWIP_MARK_TCPIP_THREAD || defined __DOXYGEN__ -#define LWIP_MARK_TCPIP_THREAD() -#endif -/** - * @} - */ - -/* - ------------------------------------ - ---------- Memory options ---------- - ------------------------------------ -*/ -/** - * @defgroup lwip_opts_mem Heap and memory pools - * @ingroup lwip_opts_infrastructure - * @{ - */ -/** - * MEM_LIBC_MALLOC==1: Use malloc/free/realloc provided by your C-library - * instead of the lwip internal allocator. Can save code size if you - * already use it. - */ -#if !defined MEM_LIBC_MALLOC || defined __DOXYGEN__ -#define MEM_LIBC_MALLOC 0 -#endif - -/** - * MEMP_MEM_MALLOC==1: Use mem_malloc/mem_free instead of the lwip pool allocator. - * Especially useful with MEM_LIBC_MALLOC but handle with care regarding execution - * speed (heap alloc can be much slower than pool alloc) and usage from interrupts - * (especially if your netif driver allocates PBUF_POOL pbufs for received frames - * from interrupt)! - * ATTENTION: Currently, this uses the heap for ALL pools (also for private pools, - * not only for internal pools defined in memp_std.h)! - */ -#if !defined MEMP_MEM_MALLOC || defined __DOXYGEN__ -#define MEMP_MEM_MALLOC 0 -#endif - -/** - * MEMP_MEM_INIT==1: Force use of memset to initialize pool memory. - * Useful if pool are moved in uninitialized section of memory. This will ensure - * default values in pcbs struct are well initialized in all conditions. - */ -#if !defined MEMP_MEM_INIT || defined __DOXYGEN__ -#define MEMP_MEM_INIT 0 -#endif - -/** - * MEM_ALIGNMENT: should be set to the alignment of the CPU - * 4 byte alignment -> \#define MEM_ALIGNMENT 4 - * 2 byte alignment -> \#define MEM_ALIGNMENT 2 - */ -#if !defined MEM_ALIGNMENT || defined __DOXYGEN__ -#define MEM_ALIGNMENT 1 -#endif - -/** - * MEM_SIZE: the size of the heap memory. If the application will send - * a lot of data that needs to be copied, this should be set high. - */ -#if !defined MEM_SIZE || defined __DOXYGEN__ -#define MEM_SIZE 1600 -#endif - -/** - * MEMP_OVERFLOW_CHECK: memp overflow protection reserves a configurable - * amount of bytes before and after each memp element in every pool and fills - * it with a prominent default value. - * MEMP_OVERFLOW_CHECK == 0 no checking - * MEMP_OVERFLOW_CHECK == 1 checks each element when it is freed - * MEMP_OVERFLOW_CHECK >= 2 checks each element in every pool every time - * memp_malloc() or memp_free() is called (useful but slow!) - */ -#if !defined MEMP_OVERFLOW_CHECK || defined __DOXYGEN__ -#define MEMP_OVERFLOW_CHECK 0 -#endif - -/** - * MEMP_SANITY_CHECK==1: run a sanity check after each memp_free() to make - * sure that there are no cycles in the linked lists. - */ -#if !defined MEMP_SANITY_CHECK || defined __DOXYGEN__ -#define MEMP_SANITY_CHECK 0 -#endif - -/** - * MEM_OVERFLOW_CHECK: mem overflow protection reserves a configurable - * amount of bytes before and after each heap allocation chunk and fills - * it with a prominent default value. - * MEM_OVERFLOW_CHECK == 0 no checking - * MEM_OVERFLOW_CHECK == 1 checks each element when it is freed - * MEM_OVERFLOW_CHECK >= 2 checks all heap elements every time - * mem_malloc() or mem_free() is called (useful but slow!) - */ -#if !defined MEM_OVERFLOW_CHECK || defined __DOXYGEN__ -#define MEM_OVERFLOW_CHECK 0 -#endif - -/** - * MEM_SANITY_CHECK==1: run a sanity check after each mem_free() to make - * sure that the linked list of heap elements is not corrupted. - */ -#if !defined MEM_SANITY_CHECK || defined __DOXYGEN__ -#define MEM_SANITY_CHECK 0 -#endif - -/** - * MEM_USE_POOLS==1: Use an alternative to malloc() by allocating from a set - * of memory pools of various sizes. When mem_malloc is called, an element of - * the smallest pool that can provide the length needed is returned. - * To use this, MEMP_USE_CUSTOM_POOLS also has to be enabled. - */ -#if !defined MEM_USE_POOLS || defined __DOXYGEN__ -#define MEM_USE_POOLS 0 -#endif - -/** - * MEM_USE_POOLS_TRY_BIGGER_POOL==1: if one malloc-pool is empty, try the next - * bigger pool - WARNING: THIS MIGHT WASTE MEMORY but it can make a system more - * reliable. */ -#if !defined MEM_USE_POOLS_TRY_BIGGER_POOL || defined __DOXYGEN__ -#define MEM_USE_POOLS_TRY_BIGGER_POOL 0 -#endif - -/** - * MEMP_USE_CUSTOM_POOLS==1: whether to include a user file lwippools.h - * that defines additional pools beyond the "standard" ones required - * by lwIP. If you set this to 1, you must have lwippools.h in your - * include path somewhere. - */ -#if !defined MEMP_USE_CUSTOM_POOLS || defined __DOXYGEN__ -#define MEMP_USE_CUSTOM_POOLS 0 -#endif - -/** - * Set this to 1 if you want to free PBUF_RAM pbufs (or call mem_free()) from - * interrupt context (or another context that doesn't allow waiting for a - * semaphore). - * If set to 1, mem_malloc will be protected by a semaphore and SYS_ARCH_PROTECT, - * while mem_free will only use SYS_ARCH_PROTECT. mem_malloc SYS_ARCH_UNPROTECTs - * with each loop so that mem_free can run. - * - * ATTENTION: As you can see from the above description, this leads to dis-/ - * enabling interrupts often, which can be slow! Also, on low memory, mem_malloc - * can need longer. - * - * If you don't want that, at least for NO_SYS=0, you can still use the following - * functions to enqueue a deallocation call which then runs in the tcpip_thread - * context: - * - pbuf_free_callback(p); - * - mem_free_callback(m); - */ -#if !defined LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT || defined __DOXYGEN__ -#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 0 -#endif -/** - * @} - */ - -/* - ------------------------------------------------ - ---------- Internal Memory Pool Sizes ---------- - ------------------------------------------------ -*/ -/** - * @defgroup lwip_opts_memp Internal memory pools - * @ingroup lwip_opts_infrastructure - * @{ - */ -/** - * MEMP_NUM_PBUF: the number of memp struct pbufs (used for PBUF_ROM and PBUF_REF). - * If the application sends a lot of data out of ROM (or other static memory), - * this should be set high. - */ -#if !defined MEMP_NUM_PBUF || defined __DOXYGEN__ -#define MEMP_NUM_PBUF 16 -#endif - -/** - * MEMP_NUM_RAW_PCB: Number of raw connection PCBs - * (requires the LWIP_RAW option) - */ -#if !defined MEMP_NUM_RAW_PCB || defined __DOXYGEN__ -#define MEMP_NUM_RAW_PCB 4 -#endif - -/** - * MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One - * per active UDP "connection". - * (requires the LWIP_UDP option) - */ -#if !defined MEMP_NUM_UDP_PCB || defined __DOXYGEN__ -#define MEMP_NUM_UDP_PCB 4 -#endif - -/** - * MEMP_NUM_TCP_PCB: the number of simultaneously active TCP connections. - * (requires the LWIP_TCP option) - */ -#if !defined MEMP_NUM_TCP_PCB || defined __DOXYGEN__ -#define MEMP_NUM_TCP_PCB 5 -#endif - -/** - * MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP connections. - * (requires the LWIP_TCP option) - */ -#if !defined MEMP_NUM_TCP_PCB_LISTEN || defined __DOXYGEN__ -#define MEMP_NUM_TCP_PCB_LISTEN 8 -#endif - -/** - * MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP segments. - * (requires the LWIP_TCP option) - */ -#if !defined MEMP_NUM_TCP_SEG || defined __DOXYGEN__ -#define MEMP_NUM_TCP_SEG 16 -#endif - -/** - * MEMP_NUM_ALTCP_PCB: the number of simultaneously active altcp layer pcbs. - * (requires the LWIP_ALTCP option) - * Connections with multiple layers require more than one altcp_pcb (e.g. TLS - * over TCP requires 2 altcp_pcbs, one for TLS and one for TCP). - */ -#if !defined MEMP_NUM_ALTCP_PCB || defined __DOXYGEN__ -#define MEMP_NUM_ALTCP_PCB MEMP_NUM_TCP_PCB -#endif - -/** - * MEMP_NUM_REASSDATA: the number of IP packets simultaneously queued for - * reassembly (whole packets, not fragments!) - */ -#if !defined MEMP_NUM_REASSDATA || defined __DOXYGEN__ -#define MEMP_NUM_REASSDATA 5 -#endif - -/** - * MEMP_NUM_FRAG_PBUF: the number of IP fragments simultaneously sent - * (fragments, not whole packets!). - * This is only used with LWIP_NETIF_TX_SINGLE_PBUF==0 and only has to be > 1 - * with DMA-enabled MACs where the packet is not yet sent when netif->output - * returns. - */ -#if !defined MEMP_NUM_FRAG_PBUF || defined __DOXYGEN__ -#define MEMP_NUM_FRAG_PBUF 15 -#endif - -/** - * MEMP_NUM_ARP_QUEUE: the number of simultaneously queued outgoing - * packets (pbufs) that are waiting for an ARP request (to resolve - * their destination address) to finish. - * (requires the ARP_QUEUEING option) - */ -#if !defined MEMP_NUM_ARP_QUEUE || defined __DOXYGEN__ -#define MEMP_NUM_ARP_QUEUE 30 -#endif - -/** - * MEMP_NUM_IGMP_GROUP: The number of multicast groups whose network interfaces - * can be members at the same time (one per netif - allsystems group -, plus one - * per netif membership). - * (requires the LWIP_IGMP option) - */ -#if !defined MEMP_NUM_IGMP_GROUP || defined __DOXYGEN__ -#define MEMP_NUM_IGMP_GROUP 8 -#endif - -/** - * The number of sys timeouts used by the core stack (not apps) - * The default number of timeouts is calculated here for all enabled modules. - */ -#define LWIP_NUM_SYS_TIMEOUT_INTERNAL (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + PPP_NUM_TIMEOUTS + (LWIP_IPV6 * (1 + LWIP_IPV6_REASS + LWIP_IPV6_MLD))) - -/** - * MEMP_NUM_SYS_TIMEOUT: the number of simultaneously active timeouts. - * The default number of timeouts is calculated here for all enabled modules. - * The formula expects settings to be either '0' or '1'. - */ -#if !defined MEMP_NUM_SYS_TIMEOUT || defined __DOXYGEN__ -#define MEMP_NUM_SYS_TIMEOUT LWIP_NUM_SYS_TIMEOUT_INTERNAL -#endif - -/** - * MEMP_NUM_NETBUF: the number of struct netbufs. - * (only needed if you use the sequential API, like api_lib.c) - */ -#if !defined MEMP_NUM_NETBUF || defined __DOXYGEN__ -#define MEMP_NUM_NETBUF 2 -#endif - -/** - * MEMP_NUM_NETCONN: the number of struct netconns. - * (only needed if you use the sequential API, like api_lib.c) - */ -#if !defined MEMP_NUM_NETCONN || defined __DOXYGEN__ -#define MEMP_NUM_NETCONN 4 -#endif - -/** - * MEMP_NUM_SELECT_CB: the number of struct lwip_select_cb. - * (Only needed if you have LWIP_MPU_COMPATIBLE==1 and use the socket API. - * In that case, you need one per thread calling lwip_select.) - */ -#if !defined MEMP_NUM_SELECT_CB || defined __DOXYGEN__ -#define MEMP_NUM_SELECT_CB 4 -#endif - -/** - * MEMP_NUM_TCPIP_MSG_API: the number of struct tcpip_msg, which are used - * for callback/timeout API communication. - * (only needed if you use tcpip.c) - */ -#if !defined MEMP_NUM_TCPIP_MSG_API || defined __DOXYGEN__ -#define MEMP_NUM_TCPIP_MSG_API 8 -#endif - -/** - * MEMP_NUM_TCPIP_MSG_INPKT: the number of struct tcpip_msg, which are used - * for incoming packets. - * (only needed if you use tcpip.c) - */ -#if !defined MEMP_NUM_TCPIP_MSG_INPKT || defined __DOXYGEN__ -#define MEMP_NUM_TCPIP_MSG_INPKT 8 -#endif - -/** - * MEMP_NUM_NETDB: the number of concurrently running lwip_addrinfo() calls - * (before freeing the corresponding memory using lwip_freeaddrinfo()). - */ -#if !defined MEMP_NUM_NETDB || defined __DOXYGEN__ -#define MEMP_NUM_NETDB 1 -#endif - -/** - * MEMP_NUM_LOCALHOSTLIST: the number of host entries in the local host list - * if DNS_LOCAL_HOSTLIST_IS_DYNAMIC==1. - */ -#if !defined MEMP_NUM_LOCALHOSTLIST || defined __DOXYGEN__ -#define MEMP_NUM_LOCALHOSTLIST 1 -#endif - -/** - * PBUF_POOL_SIZE: the number of buffers in the pbuf pool. - */ -#if !defined PBUF_POOL_SIZE || defined __DOXYGEN__ -#define PBUF_POOL_SIZE 16 -#endif - -/** MEMP_NUM_API_MSG: the number of concurrently active calls to various - * socket, netconn, and tcpip functions - */ -#if !defined MEMP_NUM_API_MSG || defined __DOXYGEN__ -#define MEMP_NUM_API_MSG MEMP_NUM_TCPIP_MSG_API -#endif - -/** MEMP_NUM_DNS_API_MSG: the number of concurrently active calls to netconn_gethostbyname - */ -#if !defined MEMP_NUM_DNS_API_MSG || defined __DOXYGEN__ -#define MEMP_NUM_DNS_API_MSG MEMP_NUM_TCPIP_MSG_API -#endif - -/** MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA: the number of concurrently active calls - * to getsockopt/setsockopt - */ -#if !defined MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA || defined __DOXYGEN__ -#define MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA MEMP_NUM_TCPIP_MSG_API -#endif - -/** MEMP_NUM_NETIFAPI_MSG: the number of concurrently active calls to the - * netifapi functions - */ -#if !defined MEMP_NUM_NETIFAPI_MSG || defined __DOXYGEN__ -#define MEMP_NUM_NETIFAPI_MSG MEMP_NUM_TCPIP_MSG_API -#endif -/** - * @} - */ - -/* - --------------------------------- - ---------- ARP options ---------- - --------------------------------- -*/ -/** - * @defgroup lwip_opts_arp ARP - * @ingroup lwip_opts_ipv4 - * @{ - */ -/** - * LWIP_ARP==1: Enable ARP functionality. - */ -#if !defined LWIP_ARP || defined __DOXYGEN__ -#define LWIP_ARP 1 -#endif - -/** - * ARP_TABLE_SIZE: Number of active MAC-IP address pairs cached. - */ -#if !defined ARP_TABLE_SIZE || defined __DOXYGEN__ -#define ARP_TABLE_SIZE 10 -#endif - -/** the time an ARP entry stays valid after its last update, - * for ARP_TMR_INTERVAL = 1000, this is - * (60 * 5) seconds = 5 minutes. - */ -#if !defined ARP_MAXAGE || defined __DOXYGEN__ -#define ARP_MAXAGE 300 -#endif - -/** - * ARP_QUEUEING==1: Multiple outgoing packets are queued during hardware address - * resolution. By default, only the most recent packet is queued per IP address. - * This is sufficient for most protocols and mainly reduces TCP connection - * startup time. Set this to 1 if you know your application sends more than one - * packet in a row to an IP address that is not in the ARP cache. - */ -#if !defined ARP_QUEUEING || defined __DOXYGEN__ -#define ARP_QUEUEING 0 -#endif - -/** The maximum number of packets which may be queued for each - * unresolved address by other network layers. Defaults to 3, 0 means disabled. - * Old packets are dropped, new packets are queued. - */ -#if !defined ARP_QUEUE_LEN || defined __DOXYGEN__ -#define ARP_QUEUE_LEN 3 -#endif - -/** - * ETHARP_SUPPORT_VLAN==1: support receiving and sending ethernet packets with - * VLAN header. See the description of LWIP_HOOK_VLAN_CHECK and - * LWIP_HOOK_VLAN_SET hooks to check/set VLAN headers. - * Additionally, you can define ETHARP_VLAN_CHECK to an u16_t VLAN ID to check. - * If ETHARP_VLAN_CHECK is defined, only VLAN-traffic for this VLAN is accepted. - * If ETHARP_VLAN_CHECK is not defined, all traffic is accepted. - * Alternatively, define a function/define ETHARP_VLAN_CHECK_FN(eth_hdr, vlan) - * that returns 1 to accept a packet or 0 to drop a packet. - */ -#if !defined ETHARP_SUPPORT_VLAN || defined __DOXYGEN__ -#define ETHARP_SUPPORT_VLAN 0 -#endif - -/** LWIP_ETHERNET==1: enable ethernet support even though ARP might be disabled - */ -#if !defined LWIP_ETHERNET || defined __DOXYGEN__ -#define LWIP_ETHERNET LWIP_ARP -#endif - -/** ETH_PAD_SIZE: number of bytes added before the ethernet header to ensure - * alignment of payload after that header. Since the header is 14 bytes long, - * without this padding e.g. addresses in the IP header will not be aligned - * on a 32-bit boundary, so setting this to 2 can speed up 32-bit-platforms. - */ -#if !defined ETH_PAD_SIZE || defined __DOXYGEN__ -#define ETH_PAD_SIZE 0 -#endif - -/** ETHARP_SUPPORT_STATIC_ENTRIES==1: enable code to support static ARP table - * entries (using etharp_add_static_entry/etharp_remove_static_entry). - */ -#if !defined ETHARP_SUPPORT_STATIC_ENTRIES || defined __DOXYGEN__ -#define ETHARP_SUPPORT_STATIC_ENTRIES 0 -#endif - -/** ETHARP_TABLE_MATCH_NETIF==1: Match netif for ARP table entries. - * If disabled, duplicate IP address on multiple netifs are not supported - * (but this should only occur for AutoIP). - */ -#if !defined ETHARP_TABLE_MATCH_NETIF || defined __DOXYGEN__ -#define ETHARP_TABLE_MATCH_NETIF !LWIP_SINGLE_NETIF -#endif -/** - * @} - */ - -/* - -------------------------------- - ---------- IP options ---------- - -------------------------------- -*/ -/** - * @defgroup lwip_opts_ipv4 IPv4 - * @ingroup lwip_opts - * @{ - */ -/** - * LWIP_IPV4==1: Enable IPv4 - */ -#if !defined LWIP_IPV4 || defined __DOXYGEN__ -#define LWIP_IPV4 1 -#endif - -/** - * IP_FORWARD==1: Enables the ability to forward IP packets across network - * interfaces. If you are going to run lwIP on a device with only one network - * interface, define this to 0. - */ -#if !defined IP_FORWARD || defined __DOXYGEN__ -#define IP_FORWARD 0 -#endif - -/** - * IP_REASSEMBLY==1: Reassemble incoming fragmented IP packets. Note that - * this option does not affect outgoing packet sizes, which can be controlled - * via IP_FRAG. - */ -#if !defined IP_REASSEMBLY || defined __DOXYGEN__ -#define IP_REASSEMBLY 1 -#endif - -/** - * IP_FRAG==1: Fragment outgoing IP packets if their size exceeds MTU. Note - * that this option does not affect incoming packet sizes, which can be - * controlled via IP_REASSEMBLY. - */ -#if !defined IP_FRAG || defined __DOXYGEN__ -#define IP_FRAG 1 -#endif - -#if !LWIP_IPV4 -/* disable IPv4 extensions when IPv4 is disabled */ -#undef IP_FORWARD -#define IP_FORWARD 0 -#undef IP_REASSEMBLY -#define IP_REASSEMBLY 0 -#undef IP_FRAG -#define IP_FRAG 0 -#endif /* !LWIP_IPV4 */ - -/** - * IP_OPTIONS_ALLOWED: Defines the behavior for IP options. - * IP_OPTIONS_ALLOWED==0: All packets with IP options are dropped. - * IP_OPTIONS_ALLOWED==1: IP options are allowed (but not parsed). - */ -#if !defined IP_OPTIONS_ALLOWED || defined __DOXYGEN__ -#define IP_OPTIONS_ALLOWED 1 -#endif - -/** - * IP_REASS_MAXAGE: Maximum time (in multiples of IP_TMR_INTERVAL - so seconds, normally) - * a fragmented IP packet waits for all fragments to arrive. If not all fragments arrived - * in this time, the whole packet is discarded. - */ -#if !defined IP_REASS_MAXAGE || defined __DOXYGEN__ -#define IP_REASS_MAXAGE 15 -#endif - -/** - * IP_REASS_MAX_PBUFS: Total maximum amount of pbufs waiting to be reassembled. - * Since the received pbufs are enqueued, be sure to configure - * PBUF_POOL_SIZE > IP_REASS_MAX_PBUFS so that the stack is still able to receive - * packets even if the maximum amount of fragments is enqueued for reassembly! - * When IPv4 *and* IPv6 are enabled, this even changes to - * (PBUF_POOL_SIZE > 2 * IP_REASS_MAX_PBUFS)! - */ -#if !defined IP_REASS_MAX_PBUFS || defined __DOXYGEN__ -#define IP_REASS_MAX_PBUFS 10 -#endif - -/** - * IP_DEFAULT_TTL: Default value for Time-To-Live used by transport layers. - */ -#if !defined IP_DEFAULT_TTL || defined __DOXYGEN__ -#define IP_DEFAULT_TTL 255 -#endif - -/** - * IP_SOF_BROADCAST=1: Use the SOF_BROADCAST field to enable broadcast - * filter per pcb on udp and raw send operations. To enable broadcast filter - * on recv operations, you also have to set IP_SOF_BROADCAST_RECV=1. - */ -#if !defined IP_SOF_BROADCAST || defined __DOXYGEN__ -#define IP_SOF_BROADCAST 0 -#endif - -/** - * IP_SOF_BROADCAST_RECV (requires IP_SOF_BROADCAST=1) enable the broadcast - * filter on recv operations. - */ -#if !defined IP_SOF_BROADCAST_RECV || defined __DOXYGEN__ -#define IP_SOF_BROADCAST_RECV 0 -#endif - -/** - * IP_FORWARD_ALLOW_TX_ON_RX_NETIF==1: allow ip_forward() to send packets back - * out on the netif where it was received. This should only be used for - * wireless networks. - * ATTENTION: When this is 1, make sure your netif driver correctly marks incoming - * link-layer-broadcast/multicast packets as such using the corresponding pbuf flags! - */ -#if !defined IP_FORWARD_ALLOW_TX_ON_RX_NETIF || defined __DOXYGEN__ -#define IP_FORWARD_ALLOW_TX_ON_RX_NETIF 0 -#endif -/** - * @} - */ - -/* - ---------------------------------- - ---------- ICMP options ---------- - ---------------------------------- -*/ -/** - * @defgroup lwip_opts_icmp ICMP - * @ingroup lwip_opts_ipv4 - * @{ - */ -/** - * LWIP_ICMP==1: Enable ICMP module inside the IP stack. - * Be careful, disable that make your product non-compliant to RFC1122 - */ -#if !defined LWIP_ICMP || defined __DOXYGEN__ -#define LWIP_ICMP 1 -#endif - -/** - * ICMP_TTL: Default value for Time-To-Live used by ICMP packets. - */ -#if !defined ICMP_TTL || defined __DOXYGEN__ -#define ICMP_TTL IP_DEFAULT_TTL -#endif - -/** - * LWIP_BROADCAST_PING==1: respond to broadcast pings (default is unicast only) - */ -#if !defined LWIP_BROADCAST_PING || defined __DOXYGEN__ -#define LWIP_BROADCAST_PING 0 -#endif - -/** - * LWIP_MULTICAST_PING==1: respond to multicast pings (default is unicast only) - */ -#if !defined LWIP_MULTICAST_PING || defined __DOXYGEN__ -#define LWIP_MULTICAST_PING 0 -#endif -/** - * @} - */ - -/* - --------------------------------- - ---------- RAW options ---------- - --------------------------------- -*/ -/** - * @defgroup lwip_opts_raw RAW - * @ingroup lwip_opts_callback - * @{ - */ -/** - * LWIP_RAW==1: Enable application layer to hook into the IP layer itself. - */ -#if !defined LWIP_RAW || defined __DOXYGEN__ -#define LWIP_RAW 0 -#endif - -/** - * LWIP_RAW==1: Enable application layer to hook into the IP layer itself. - */ -#if !defined RAW_TTL || defined __DOXYGEN__ -#define RAW_TTL IP_DEFAULT_TTL -#endif -/** - * @} - */ - -/* - ---------------------------------- - ---------- DHCP options ---------- - ---------------------------------- -*/ -/** - * @defgroup lwip_opts_dhcp DHCP - * @ingroup lwip_opts_ipv4 - * @{ - */ -/** - * LWIP_DHCP==1: Enable DHCP module. - */ -#if !defined LWIP_DHCP || defined __DOXYGEN__ -#define LWIP_DHCP 0 -#endif -#if !LWIP_IPV4 -/* disable DHCP when IPv4 is disabled */ -#undef LWIP_DHCP -#define LWIP_DHCP 0 -#endif /* !LWIP_IPV4 */ - -/** - * DHCP_DOES_ARP_CHECK==1: Do an ARP check on the offered address. - */ -#if !defined DHCP_DOES_ARP_CHECK || defined __DOXYGEN__ -#define DHCP_DOES_ARP_CHECK (LWIP_DHCP && LWIP_ARP) -#endif - -/** - * LWIP_DHCP_BOOTP_FILE==1: Store offered_si_addr and boot_file_name. - */ -#if !defined LWIP_DHCP_BOOTP_FILE || defined __DOXYGEN__ -#define LWIP_DHCP_BOOTP_FILE 0 -#endif - -/** - * LWIP_DHCP_GETS_NTP==1: Request NTP servers with discover/select. For each - * response packet, an callback is called, which has to be provided by the port: - * void dhcp_set_ntp_servers(u8_t num_ntp_servers, ip_addr_t* ntp_server_addrs); -*/ -#if !defined LWIP_DHCP_GET_NTP_SRV || defined __DOXYGEN__ -#define LWIP_DHCP_GET_NTP_SRV 0 -#endif - -/** - * The maximum of NTP servers requested - */ -#if !defined LWIP_DHCP_MAX_NTP_SERVERS || defined __DOXYGEN__ -#define LWIP_DHCP_MAX_NTP_SERVERS 1 -#endif - -/** - * LWIP_DHCP_MAX_DNS_SERVERS > 0: Request DNS servers with discover/select. - * DNS servers received in the response are passed to DNS via @ref dns_setserver() - * (up to the maximum limit defined here). - */ -#if !defined LWIP_DHCP_MAX_DNS_SERVERS || defined __DOXYGEN__ -#define LWIP_DHCP_MAX_DNS_SERVERS DNS_MAX_SERVERS -#endif -/** - * @} - */ - -/* - ------------------------------------ - ---------- AUTOIP options ---------- - ------------------------------------ -*/ -/** - * @defgroup lwip_opts_autoip AUTOIP - * @ingroup lwip_opts_ipv4 - * @{ - */ -/** - * LWIP_AUTOIP==1: Enable AUTOIP module. - */ -#if !defined LWIP_AUTOIP || defined __DOXYGEN__ -#define LWIP_AUTOIP 0 -#endif -#if !LWIP_IPV4 -/* disable AUTOIP when IPv4 is disabled */ -#undef LWIP_AUTOIP -#define LWIP_AUTOIP 0 -#endif /* !LWIP_IPV4 */ - -/** - * LWIP_DHCP_AUTOIP_COOP==1: Allow DHCP and AUTOIP to be both enabled on - * the same interface at the same time. - */ -#if !defined LWIP_DHCP_AUTOIP_COOP || defined __DOXYGEN__ -#define LWIP_DHCP_AUTOIP_COOP 0 -#endif - -/** - * LWIP_DHCP_AUTOIP_COOP_TRIES: Set to the number of DHCP DISCOVER probes - * that should be sent before falling back on AUTOIP (the DHCP client keeps - * running in this case). This can be set as low as 1 to get an AutoIP address - * very quickly, but you should be prepared to handle a changing IP address - * when DHCP overrides AutoIP. - */ -#if !defined LWIP_DHCP_AUTOIP_COOP_TRIES || defined __DOXYGEN__ -#define LWIP_DHCP_AUTOIP_COOP_TRIES 9 -#endif -/** - * @} - */ - -/* - ---------------------------------- - ----- SNMP MIB2 support ----- - ---------------------------------- -*/ -/** - * @defgroup lwip_opts_mib2 SNMP MIB2 callbacks - * @ingroup lwip_opts_infrastructure - * @{ - */ -/** - * LWIP_MIB2_CALLBACKS==1: Turn on SNMP MIB2 callbacks. - * Turn this on to get callbacks needed to implement MIB2. - * Usually MIB2_STATS should be enabled, too. - */ -#if !defined LWIP_MIB2_CALLBACKS || defined __DOXYGEN__ -#define LWIP_MIB2_CALLBACKS 0 -#endif -/** - * @} - */ - -/* - ---------------------------------- - -------- Multicast options ------- - ---------------------------------- -*/ -/** - * @defgroup lwip_opts_multicast Multicast - * @ingroup lwip_opts_infrastructure - * @{ - */ -/** - * LWIP_MULTICAST_TX_OPTIONS==1: Enable multicast TX support like the socket options - * IP_MULTICAST_TTL/IP_MULTICAST_IF/IP_MULTICAST_LOOP, as well as (currently only) - * core support for the corresponding IPv6 options. - */ -#if !defined LWIP_MULTICAST_TX_OPTIONS || defined __DOXYGEN__ -#define LWIP_MULTICAST_TX_OPTIONS ((LWIP_IGMP || LWIP_IPV6_MLD) && (LWIP_UDP || LWIP_RAW)) -#endif -/** - * @} - */ - -/* - ---------------------------------- - ---------- IGMP options ---------- - ---------------------------------- -*/ -/** - * @defgroup lwip_opts_igmp IGMP - * @ingroup lwip_opts_ipv4 - * @{ - */ -/** - * LWIP_IGMP==1: Turn on IGMP module. - */ -#if !defined LWIP_IGMP || defined __DOXYGEN__ -#define LWIP_IGMP 0 -#endif -#if !LWIP_IPV4 -#undef LWIP_IGMP -#define LWIP_IGMP 0 -#endif -/** - * @} - */ - -/* - ---------------------------------- - ---------- DNS options ----------- - ---------------------------------- -*/ -/** - * @defgroup lwip_opts_dns DNS - * @ingroup lwip_opts_callback - * @{ - */ -/** - * LWIP_DNS==1: Turn on DNS module. UDP must be available for DNS - * transport. - */ -#if !defined LWIP_DNS || defined __DOXYGEN__ -#define LWIP_DNS 0 -#endif - -/** DNS maximum number of entries to maintain locally. */ -#if !defined DNS_TABLE_SIZE || defined __DOXYGEN__ -#define DNS_TABLE_SIZE 4 -#endif - -/** DNS maximum host name length supported in the name table. */ -#if !defined DNS_MAX_NAME_LENGTH || defined __DOXYGEN__ -#define DNS_MAX_NAME_LENGTH 256 -#endif - -/** The maximum of DNS servers - * The first server can be initialized automatically by defining - * DNS_SERVER_ADDRESS(ipaddr), where 'ipaddr' is an 'ip_addr_t*' - */ -#if !defined DNS_MAX_SERVERS || defined __DOXYGEN__ -#define DNS_MAX_SERVERS 2 -#endif - -/** DNS maximum number of retries when asking for a name, before "timeout". */ -#if !defined DNS_MAX_RETRIES || defined __DOXYGEN__ -#define DNS_MAX_RETRIES 4 -#endif - -/** DNS do a name checking between the query and the response. */ -#if !defined DNS_DOES_NAME_CHECK || defined __DOXYGEN__ -#define DNS_DOES_NAME_CHECK 1 -#endif - -/** LWIP_DNS_SECURE: controls the security level of the DNS implementation - * Use all DNS security features by default. - * This is overridable but should only be needed by very small targets - * or when using against non standard DNS servers. */ -#if !defined LWIP_DNS_SECURE || defined __DOXYGEN__ -#define LWIP_DNS_SECURE (LWIP_DNS_SECURE_RAND_XID | LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING | LWIP_DNS_SECURE_RAND_SRC_PORT) -#endif - -/* A list of DNS security features follows */ -#define LWIP_DNS_SECURE_RAND_XID 1 -#define LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING 2 -#define LWIP_DNS_SECURE_RAND_SRC_PORT 4 - -/** DNS_LOCAL_HOSTLIST: Implements a local host-to-address list. If enabled, you have to define an initializer: - * \#define DNS_LOCAL_HOSTLIST_INIT {DNS_LOCAL_HOSTLIST_ELEM("host_ip4", IPADDR4_INIT_BYTES(1,2,3,4)), \ - * DNS_LOCAL_HOSTLIST_ELEM("host_ip6", IPADDR6_INIT_HOST(123, 234, 345, 456)} - * - * Instead, you can also use an external function: - * \#define DNS_LOOKUP_LOCAL_EXTERN(x) extern err_t my_lookup_function(const char *name, ip_addr_t *addr, u8_t dns_addrtype) - * that looks up the IP address and returns ERR_OK if found (LWIP_DNS_ADDRTYPE_xxx is passed in dns_addrtype). - */ -#if !defined DNS_LOCAL_HOSTLIST || defined __DOXYGEN__ -#define DNS_LOCAL_HOSTLIST 0 -#endif /* DNS_LOCAL_HOSTLIST */ - -/** If this is turned on, the local host-list can be dynamically changed - * at runtime. */ -#if !defined DNS_LOCAL_HOSTLIST_IS_DYNAMIC || defined __DOXYGEN__ -#define DNS_LOCAL_HOSTLIST_IS_DYNAMIC 0 -#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ - -/** Set this to 1 to enable querying ".local" names via mDNS - * using a One-Shot Multicast DNS Query */ -#if !defined LWIP_DNS_SUPPORT_MDNS_QUERIES || defined __DOXYGEN__ -#define LWIP_DNS_SUPPORT_MDNS_QUERIES 0 -#endif -/** - * @} - */ - -/* - --------------------------------- - ---------- UDP options ---------- - --------------------------------- -*/ -/** - * @defgroup lwip_opts_udp UDP - * @ingroup lwip_opts_callback - * @{ - */ -/** - * LWIP_UDP==1: Turn on UDP. - */ -#if !defined LWIP_UDP || defined __DOXYGEN__ -#define LWIP_UDP 1 -#endif - -/** - * LWIP_UDPLITE==1: Turn on UDP-Lite. (Requires LWIP_UDP) - */ -#if !defined LWIP_UDPLITE || defined __DOXYGEN__ -#define LWIP_UDPLITE 0 -#endif - -/** - * UDP_TTL: Default Time-To-Live value. - */ -#if !defined UDP_TTL || defined __DOXYGEN__ -#define UDP_TTL IP_DEFAULT_TTL -#endif - -/** - * LWIP_NETBUF_RECVINFO==1: append destination addr and port to every netbuf. - */ -#if !defined LWIP_NETBUF_RECVINFO || defined __DOXYGEN__ -#define LWIP_NETBUF_RECVINFO 0 -#endif -/** - * @} - */ - -/* - --------------------------------- - ---------- TCP options ---------- - --------------------------------- -*/ -/** - * @defgroup lwip_opts_tcp TCP - * @ingroup lwip_opts_callback - * @{ - */ -/** - * LWIP_TCP==1: Turn on TCP. - */ -#if !defined LWIP_TCP || defined __DOXYGEN__ -#define LWIP_TCP 1 -#endif - -/** - * TCP_TTL: Default Time-To-Live value. - */ -#if !defined TCP_TTL || defined __DOXYGEN__ -#define TCP_TTL IP_DEFAULT_TTL -#endif - -/** - * TCP_WND: The size of a TCP window. This must be at least - * (2 * TCP_MSS) for things to work well. - * ATTENTION: when using TCP_RCV_SCALE, TCP_WND is the total size - * with scaling applied. Maximum window value in the TCP header - * will be TCP_WND >> TCP_RCV_SCALE - */ -#if !defined TCP_WND || defined __DOXYGEN__ -#define TCP_WND (4 * TCP_MSS) -#endif - -/** - * TCP_MAXRTX: Maximum number of retransmissions of data segments. - */ -#if !defined TCP_MAXRTX || defined __DOXYGEN__ -#define TCP_MAXRTX 12 -#endif - -/** - * TCP_SYNMAXRTX: Maximum number of retransmissions of SYN segments. - */ -#if !defined TCP_SYNMAXRTX || defined __DOXYGEN__ -#define TCP_SYNMAXRTX 6 -#endif - -/** - * TCP_QUEUE_OOSEQ==1: TCP will queue segments that arrive out of order. - * Define to 0 if your device is low on memory. - */ -#if !defined TCP_QUEUE_OOSEQ || defined __DOXYGEN__ -#define TCP_QUEUE_OOSEQ LWIP_TCP -#endif - -/** - * LWIP_TCP_SACK_OUT==1: TCP will support sending selective acknowledgements (SACKs). - */ -#if !defined LWIP_TCP_SACK_OUT || defined __DOXYGEN__ -#define LWIP_TCP_SACK_OUT 0 -#endif - -/** - * LWIP_TCP_MAX_SACK_NUM: The maximum number of SACK values to include in TCP segments. - * Must be at least 1, but is only used if LWIP_TCP_SACK_OUT is enabled. - * NOTE: Even though we never send more than 3 or 4 SACK ranges in a single segment - * (depending on other options), setting this option to values greater than 4 is not pointless. - * This is basically the max number of SACK ranges we want to keep track of. - * As new data is delivered, some of the SACK ranges may be removed or merged. - * In that case some of those older SACK ranges may be used again. - * The amount of memory used to store SACK ranges is LWIP_TCP_MAX_SACK_NUM * 8 bytes for each TCP PCB. - */ -#if !defined LWIP_TCP_MAX_SACK_NUM || defined __DOXYGEN__ -#define LWIP_TCP_MAX_SACK_NUM 4 -#endif - -/** - * TCP_MSS: TCP Maximum segment size. (default is 536, a conservative default, - * you might want to increase this.) - * For the receive side, this MSS is advertised to the remote side - * when opening a connection. For the transmit size, this MSS sets - * an upper limit on the MSS advertised by the remote host. - */ -#if !defined TCP_MSS || defined __DOXYGEN__ -#define TCP_MSS 536 -#endif - -/** - * TCP_CALCULATE_EFF_SEND_MSS: "The maximum size of a segment that TCP really - * sends, the 'effective send MSS,' MUST be the smaller of the send MSS (which - * reflects the available reassembly buffer size at the remote host) and the - * largest size permitted by the IP layer" (RFC 1122) - * Setting this to 1 enables code that checks TCP_MSS against the MTU of the - * netif used for a connection and limits the MSS if it would be too big otherwise. - */ -#if !defined TCP_CALCULATE_EFF_SEND_MSS || defined __DOXYGEN__ -#define TCP_CALCULATE_EFF_SEND_MSS 1 -#endif - - -/** - * TCP_SND_BUF: TCP sender buffer space (bytes). - * To achieve good performance, this should be at least 2 * TCP_MSS. - */ -#if !defined TCP_SND_BUF || defined __DOXYGEN__ -#define TCP_SND_BUF (2 * TCP_MSS) -#endif - -/** - * TCP_SND_QUEUELEN: TCP sender buffer space (pbufs). This must be at least - * as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. - */ -#if !defined TCP_SND_QUEUELEN || defined __DOXYGEN__ -#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS)) -#endif - -/** - * TCP_SNDLOWAT: TCP writable space (bytes). This must be less than - * TCP_SND_BUF. It is the amount of space which must be available in the - * TCP snd_buf for select to return writable (combined with TCP_SNDQUEUELOWAT). - */ -#if !defined TCP_SNDLOWAT || defined __DOXYGEN__ -#define TCP_SNDLOWAT LWIP_MIN(LWIP_MAX(((TCP_SND_BUF)/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF) - 1) -#endif - -/** - * TCP_SNDQUEUELOWAT: TCP writable bufs (pbuf count). This must be less - * than TCP_SND_QUEUELEN. If the number of pbufs queued on a pcb drops below - * this number, select returns writable (combined with TCP_SNDLOWAT). - */ -#if !defined TCP_SNDQUEUELOWAT || defined __DOXYGEN__ -#define TCP_SNDQUEUELOWAT LWIP_MAX(((TCP_SND_QUEUELEN)/2), 5) -#endif - -/** - * TCP_OOSEQ_MAX_BYTES: The default maximum number of bytes queued on ooseq per - * pcb if TCP_OOSEQ_BYTES_LIMIT is not defined. Default is 0 (no limit). - * Only valid for TCP_QUEUE_OOSEQ==1. - */ -#if !defined TCP_OOSEQ_MAX_BYTES || defined __DOXYGEN__ -#define TCP_OOSEQ_MAX_BYTES 0 -#endif - -/** - * TCP_OOSEQ_BYTES_LIMIT(pcb): Return the maximum number of bytes to be queued - * on ooseq per pcb, given the pcb. Only valid for TCP_QUEUE_OOSEQ==1 && - * TCP_OOSEQ_MAX_BYTES==1. - * Use this to override TCP_OOSEQ_MAX_BYTES to a dynamic value per pcb. - */ -#if !defined TCP_OOSEQ_BYTES_LIMIT -#if TCP_OOSEQ_MAX_BYTES -#define TCP_OOSEQ_BYTES_LIMIT(pcb) TCP_OOSEQ_MAX_BYTES -#elif defined __DOXYGEN__ -#define TCP_OOSEQ_BYTES_LIMIT(pcb) -#endif -#endif - -/** - * TCP_OOSEQ_MAX_PBUFS: The default maximum number of pbufs queued on ooseq per - * pcb if TCP_OOSEQ_BYTES_LIMIT is not defined. Default is 0 (no limit). - * Only valid for TCP_QUEUE_OOSEQ==1. - */ -#if !defined TCP_OOSEQ_MAX_PBUFS || defined __DOXYGEN__ -#define TCP_OOSEQ_MAX_PBUFS 0 -#endif - -/** - * TCP_OOSEQ_PBUFS_LIMIT(pcb): Return the maximum number of pbufs to be queued - * on ooseq per pcb, given the pcb. Only valid for TCP_QUEUE_OOSEQ==1 && - * TCP_OOSEQ_MAX_PBUFS==1. - * Use this to override TCP_OOSEQ_MAX_PBUFS to a dynamic value per pcb. - */ -#if !defined TCP_OOSEQ_PBUFS_LIMIT -#if TCP_OOSEQ_MAX_PBUFS -#define TCP_OOSEQ_PBUFS_LIMIT(pcb) TCP_OOSEQ_MAX_PBUFS -#elif defined __DOXYGEN__ -#define TCP_OOSEQ_PBUFS_LIMIT(pcb) -#endif -#endif - -/** - * TCP_LISTEN_BACKLOG: Enable the backlog option for tcp listen pcb. - */ -#if !defined TCP_LISTEN_BACKLOG || defined __DOXYGEN__ -#define TCP_LISTEN_BACKLOG 0 -#endif - -/** - * The maximum allowed backlog for TCP listen netconns. - * This backlog is used unless another is explicitly specified. - * 0xff is the maximum (u8_t). - */ -#if !defined TCP_DEFAULT_LISTEN_BACKLOG || defined __DOXYGEN__ -#define TCP_DEFAULT_LISTEN_BACKLOG 0xff -#endif - -/** - * TCP_OVERSIZE: The maximum number of bytes that tcp_write may - * allocate ahead of time in an attempt to create shorter pbuf chains - * for transmission. The meaningful range is 0 to TCP_MSS. Some - * suggested values are: - * - * 0: Disable oversized allocation. Each tcp_write() allocates a new - pbuf (old behaviour). - * 1: Allocate size-aligned pbufs with minimal excess. Use this if your - * scatter-gather DMA requires aligned fragments. - * 128: Limit the pbuf/memory overhead to 20%. - * TCP_MSS: Try to create unfragmented TCP packets. - * TCP_MSS/4: Try to create 4 fragments or less per TCP packet. - */ -#if !defined TCP_OVERSIZE || defined __DOXYGEN__ -#define TCP_OVERSIZE TCP_MSS -#endif - -/** - * LWIP_TCP_TIMESTAMPS==1: support the TCP timestamp option. - * The timestamp option is currently only used to help remote hosts, it is not - * really used locally. Therefore, it is only enabled when a TS option is - * received in the initial SYN packet from a remote host. - */ -#if !defined LWIP_TCP_TIMESTAMPS || defined __DOXYGEN__ -#define LWIP_TCP_TIMESTAMPS 0 -#endif - -/** - * TCP_WND_UPDATE_THRESHOLD: difference in window to trigger an - * explicit window update - */ -#if !defined TCP_WND_UPDATE_THRESHOLD || defined __DOXYGEN__ -#define TCP_WND_UPDATE_THRESHOLD LWIP_MIN((TCP_WND / 4), (TCP_MSS * 4)) -#endif - -/** - * LWIP_EVENT_API and LWIP_CALLBACK_API: Only one of these should be set to 1. - * LWIP_EVENT_API==1: The user defines lwip_tcp_event() to receive all - * events (accept, sent, etc) that happen in the system. - * LWIP_CALLBACK_API==1: The PCB callback function is called directly - * for the event. This is the default. - */ -#if !defined(LWIP_EVENT_API) && !defined(LWIP_CALLBACK_API) || defined __DOXYGEN__ -#define LWIP_EVENT_API 0 -#define LWIP_CALLBACK_API 1 -#else -#ifndef LWIP_EVENT_API -#define LWIP_EVENT_API 0 -#endif -#ifndef LWIP_CALLBACK_API -#define LWIP_CALLBACK_API 0 -#endif -#endif - -/** - * LWIP_WND_SCALE and TCP_RCV_SCALE: - * Set LWIP_WND_SCALE to 1 to enable window scaling. - * Set TCP_RCV_SCALE to the desired scaling factor (shift count in the - * range of [0..14]). - * When LWIP_WND_SCALE is enabled but TCP_RCV_SCALE is 0, we can use a large - * send window while having a small receive window only. - */ -#if !defined LWIP_WND_SCALE || defined __DOXYGEN__ -#define LWIP_WND_SCALE 0 -#define TCP_RCV_SCALE 0 -#endif - -/** - * LWIP_TCP_PCB_NUM_EXT_ARGS: - * When this is > 0, every tcp pcb (including listen pcb) includes a number of - * additional argument entries in an array (see tcp_ext_arg_alloc_id) - */ -#if !defined LWIP_TCP_PCB_NUM_EXT_ARGS || defined __DOXYGEN__ -#define LWIP_TCP_PCB_NUM_EXT_ARGS 0 -#endif - -/** LWIP_ALTCP==1: enable the altcp API. - * altcp is an abstraction layer that prevents applications linking against the - * tcp.h functions but provides the same functionality. It is used to e.g. add - * SSL/TLS or proxy-connect support to an application written for the tcp callback - * API without that application knowing the protocol details. - * - * With LWIP_ALTCP==0, applications written against the altcp API can still be - * compiled but are directly linked against the tcp.h callback API and then - * cannot use layered protocols. - * - * See @ref altcp_api - */ -#if !defined LWIP_ALTCP || defined __DOXYGEN__ -#define LWIP_ALTCP 0 -#endif - -/** LWIP_ALTCP_TLS==1: enable TLS support for altcp API. - * This needs a port of the functions in altcp_tls.h to a TLS library. - * A port to ARM mbedtls is provided with lwIP, see apps/altcp_tls/ directory - * and LWIP_ALTCP_TLS_MBEDTLS option. - */ -#if !defined LWIP_ALTCP_TLS || defined __DOXYGEN__ -#define LWIP_ALTCP_TLS 0 -#endif - -/** - * @} - */ - -/* - ---------------------------------- - ---------- Pbuf options ---------- - ---------------------------------- -*/ -/** - * @defgroup lwip_opts_pbuf PBUF - * @ingroup lwip_opts - * @{ - */ -/** - * PBUF_LINK_HLEN: the number of bytes that should be allocated for a - * link level header. The default is 14, the standard value for - * Ethernet. - */ -#if !defined PBUF_LINK_HLEN || defined __DOXYGEN__ -#if defined LWIP_HOOK_VLAN_SET && !defined __DOXYGEN__ -#define PBUF_LINK_HLEN (18 + ETH_PAD_SIZE) -#else /* LWIP_HOOK_VLAN_SET */ -#define PBUF_LINK_HLEN (14 + ETH_PAD_SIZE) -#endif /* LWIP_HOOK_VLAN_SET */ -#endif - -/** - * PBUF_LINK_ENCAPSULATION_HLEN: the number of bytes that should be allocated - * for an additional encapsulation header before ethernet headers (e.g. 802.11) - */ -#if !defined PBUF_LINK_ENCAPSULATION_HLEN || defined __DOXYGEN__ -#define PBUF_LINK_ENCAPSULATION_HLEN 0 -#endif - -/** - * PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. The default is - * designed to accommodate single full size TCP frame in one pbuf, including - * TCP_MSS, IP header, and link header. - */ -#if !defined PBUF_POOL_BUFSIZE || defined __DOXYGEN__ -#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN) -#endif - -/** - * LWIP_PBUF_REF_T: Refcount type in pbuf. - * Default width of u8_t can be increased if 255 refs are not enough for you. - */ -#if !defined LWIP_PBUF_REF_T || defined __DOXYGEN__ -#define LWIP_PBUF_REF_T u8_t -#endif -/** - * @} - */ - -/* - ------------------------------------------------ - ---------- Network Interfaces options ---------- - ------------------------------------------------ -*/ -/** - * @defgroup lwip_opts_netif NETIF - * @ingroup lwip_opts - * @{ - */ -/** - * LWIP_SINGLE_NETIF==1: use a single netif only. This is the common case for - * small real-life targets. Some code like routing etc. can be left out. - */ -#if !defined LWIP_SINGLE_NETIF || defined __DOXYGEN__ -#define LWIP_SINGLE_NETIF 0 -#endif - -/** - * LWIP_NETIF_HOSTNAME==1: use DHCP_OPTION_HOSTNAME with netif's hostname - * field. - */ -#if !defined LWIP_NETIF_HOSTNAME || defined __DOXYGEN__ -#define LWIP_NETIF_HOSTNAME 0 -#endif - -/** - * LWIP_NETIF_API==1: Support netif api (in netifapi.c) - */ -#if !defined LWIP_NETIF_API || defined __DOXYGEN__ -#define LWIP_NETIF_API 0 -#endif - -/** - * LWIP_NETIF_STATUS_CALLBACK==1: Support a callback function whenever an interface - * changes its up/down status (i.e., due to DHCP IP acquisition) - */ -#if !defined LWIP_NETIF_STATUS_CALLBACK || defined __DOXYGEN__ -#define LWIP_NETIF_STATUS_CALLBACK 0 -#endif - -/** - * LWIP_NETIF_EXT_STATUS_CALLBACK==1: Support an extended callback function - * for several netif related event that supports multiple subscribers. - * @see netif_ext_status_callback - */ -#if !defined LWIP_NETIF_EXT_STATUS_CALLBACK || defined __DOXYGEN__ -#define LWIP_NETIF_EXT_STATUS_CALLBACK 0 -#endif - -/** - * LWIP_NETIF_LINK_CALLBACK==1: Support a callback function from an interface - * whenever the link changes (i.e., link down) - */ -#if !defined LWIP_NETIF_LINK_CALLBACK || defined __DOXYGEN__ -#define LWIP_NETIF_LINK_CALLBACK 0 -#endif - -/** - * LWIP_NETIF_REMOVE_CALLBACK==1: Support a callback function that is called - * when a netif has been removed - */ -#if !defined LWIP_NETIF_REMOVE_CALLBACK || defined __DOXYGEN__ -#define LWIP_NETIF_REMOVE_CALLBACK 0 -#endif - -/** - * LWIP_NETIF_HWADDRHINT==1: Cache link-layer-address hints (e.g. table - * indices) in struct netif. TCP and UDP can make use of this to prevent - * scanning the ARP table for every sent packet. While this is faster for big - * ARP tables or many concurrent connections, it might be counterproductive - * if you have a tiny ARP table or if there never are concurrent connections. - */ -#if !defined LWIP_NETIF_HWADDRHINT || defined __DOXYGEN__ -#define LWIP_NETIF_HWADDRHINT 0 -#endif - -/** - * LWIP_NETIF_TX_SINGLE_PBUF: if this is set to 1, lwIP *tries* to put all data - * to be sent into one single pbuf. This is for compatibility with DMA-enabled - * MACs that do not support scatter-gather. - * Beware that this might involve CPU-memcpy before transmitting that would not - * be needed without this flag! Use this only if you need to! - * - * ATTENTION: a driver should *NOT* rely on getting single pbufs but check TX - * pbufs for being in one piece. If not, @ref pbuf_clone can be used to get - * a single pbuf: - * if (p->next != NULL) { - * struct pbuf *q = pbuf_clone(PBUF_RAW, PBUF_RAM, p); - * if (q == NULL) { - * return ERR_MEM; - * } - * p = q; ATTENTION: do NOT free the old 'p' as the ref belongs to the caller! - * } - */ -#if !defined LWIP_NETIF_TX_SINGLE_PBUF || defined __DOXYGEN__ -#define LWIP_NETIF_TX_SINGLE_PBUF 0 -#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ - -/** - * LWIP_NUM_NETIF_CLIENT_DATA: Number of clients that may store - * data in client_data member array of struct netif (max. 256). - */ -#if !defined LWIP_NUM_NETIF_CLIENT_DATA || defined __DOXYGEN__ -#define LWIP_NUM_NETIF_CLIENT_DATA 0 -#endif -/** - * @} - */ - -/* - ------------------------------------ - ---------- LOOPIF options ---------- - ------------------------------------ -*/ -/** - * @defgroup lwip_opts_loop Loopback interface - * @ingroup lwip_opts_netif - * @{ - */ -/** - * LWIP_HAVE_LOOPIF==1: Support loop interface (127.0.0.1). - * This is only needed when no real netifs are available. If at least one other - * netif is available, loopback traffic uses this netif. - */ -#if !defined LWIP_HAVE_LOOPIF || defined __DOXYGEN__ -#define LWIP_HAVE_LOOPIF (LWIP_NETIF_LOOPBACK && !LWIP_SINGLE_NETIF) -#endif - -/** - * LWIP_LOOPIF_MULTICAST==1: Support multicast/IGMP on loop interface (127.0.0.1). - */ -#if !defined LWIP_LOOPIF_MULTICAST || defined __DOXYGEN__ -#define LWIP_LOOPIF_MULTICAST 0 -#endif - -/** - * LWIP_NETIF_LOOPBACK==1: Support sending packets with a destination IP - * address equal to the netif IP address, looping them back up the stack. - */ -#if !defined LWIP_NETIF_LOOPBACK || defined __DOXYGEN__ -#define LWIP_NETIF_LOOPBACK 0 -#endif - -/** - * LWIP_LOOPBACK_MAX_PBUFS: Maximum number of pbufs on queue for loopback - * sending for each netif (0 = disabled) - */ -#if !defined LWIP_LOOPBACK_MAX_PBUFS || defined __DOXYGEN__ -#define LWIP_LOOPBACK_MAX_PBUFS 0 -#endif - -/** - * LWIP_NETIF_LOOPBACK_MULTITHREADING: Indicates whether threading is enabled in - * the system, as netifs must change how they behave depending on this setting - * for the LWIP_NETIF_LOOPBACK option to work. - * Setting this is needed to avoid reentering non-reentrant functions like - * tcp_input(). - * LWIP_NETIF_LOOPBACK_MULTITHREADING==1: Indicates that the user is using a - * multithreaded environment like tcpip.c. In this case, netif->input() - * is called directly. - * LWIP_NETIF_LOOPBACK_MULTITHREADING==0: Indicates a polling (or NO_SYS) setup. - * The packets are put on a list and netif_poll() must be called in - * the main application loop. - */ -#if !defined LWIP_NETIF_LOOPBACK_MULTITHREADING || defined __DOXYGEN__ -#define LWIP_NETIF_LOOPBACK_MULTITHREADING (!NO_SYS) -#endif -/** - * @} - */ - -/* - ------------------------------------ - ---------- Thread options ---------- - ------------------------------------ -*/ -/** - * @defgroup lwip_opts_thread Threading - * @ingroup lwip_opts_infrastructure - * @{ - */ -/** - * TCPIP_THREAD_NAME: The name assigned to the main tcpip thread. - */ -#if !defined TCPIP_THREAD_NAME || defined __DOXYGEN__ -#define TCPIP_THREAD_NAME "tcpip_thread" -#endif - -/** - * TCPIP_THREAD_STACKSIZE: The stack size used by the main tcpip thread. - * The stack size value itself is platform-dependent, but is passed to - * sys_thread_new() when the thread is created. - */ -#if !defined TCPIP_THREAD_STACKSIZE || defined __DOXYGEN__ -#define TCPIP_THREAD_STACKSIZE 4096 -#endif - -/** - * TCPIP_THREAD_PRIO: The priority assigned to the main tcpip thread. - * The priority value itself is platform-dependent, but is passed to - * sys_thread_new() when the thread is created. - */ -#if !defined TCPIP_THREAD_PRIO || defined __DOXYGEN__ -#define TCPIP_THREAD_PRIO 5 -#endif - -/** - * TCPIP_MBOX_SIZE: The mailbox size for the tcpip thread messages - * The queue size value itself is platform-dependent, but is passed to - * sys_mbox_new() when tcpip_init is called. - */ -#if !defined TCPIP_MBOX_SIZE || defined __DOXYGEN__ -#define TCPIP_MBOX_SIZE 12 -#endif - -/** - * Define this to something that triggers a watchdog. This is called from - * tcpip_thread after processing a message. - */ -#if !defined LWIP_TCPIP_THREAD_ALIVE || defined __DOXYGEN__ -#define LWIP_TCPIP_THREAD_ALIVE() -#endif - -/** - * SLIPIF_THREAD_NAME: The name assigned to the slipif_loop thread. - */ -#if !defined SLIPIF_THREAD_NAME || defined __DOXYGEN__ -#define SLIPIF_THREAD_NAME "slipif_loop" -#endif - -/** - * SLIP_THREAD_STACKSIZE: The stack size used by the slipif_loop thread. - * The stack size value itself is platform-dependent, but is passed to - * sys_thread_new() when the thread is created. - */ -#if !defined SLIPIF_THREAD_STACKSIZE || defined __DOXYGEN__ -#define SLIPIF_THREAD_STACKSIZE 0 -#endif - -/** - * SLIPIF_THREAD_PRIO: The priority assigned to the slipif_loop thread. - * The priority value itself is platform-dependent, but is passed to - * sys_thread_new() when the thread is created. - */ -#if !defined SLIPIF_THREAD_PRIO || defined __DOXYGEN__ -#define SLIPIF_THREAD_PRIO 1 -#endif - -/** - * DEFAULT_THREAD_NAME: The name assigned to any other lwIP thread. - */ -#if !defined DEFAULT_THREAD_NAME || defined __DOXYGEN__ -#define DEFAULT_THREAD_NAME "lwIP" -#endif - -/** - * DEFAULT_THREAD_STACKSIZE: The stack size used by any other lwIP thread. - * The stack size value itself is platform-dependent, but is passed to - * sys_thread_new() when the thread is created. - */ -#if !defined DEFAULT_THREAD_STACKSIZE || defined __DOXYGEN__ -#define DEFAULT_THREAD_STACKSIZE 512 -#endif - -/** - * DEFAULT_THREAD_PRIO: The priority assigned to any other lwIP thread. - * The priority value itself is platform-dependent, but is passed to - * sys_thread_new() when the thread is created. - */ -#if !defined DEFAULT_THREAD_PRIO || defined __DOXYGEN__ -#define DEFAULT_THREAD_PRIO 5 -#endif - -/** - * DEFAULT_RAW_RECVMBOX_SIZE: The mailbox size for the incoming packets on a - * NETCONN_RAW. The queue size value itself is platform-dependent, but is passed - * to sys_mbox_new() when the recvmbox is created. - */ -#if !defined DEFAULT_RAW_RECVMBOX_SIZE || defined __DOXYGEN__ -#define DEFAULT_RAW_RECVMBOX_SIZE 0 -#endif - -/** - * DEFAULT_UDP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a - * NETCONN_UDP. The queue size value itself is platform-dependent, but is passed - * to sys_mbox_new() when the recvmbox is created. - */ -#if !defined DEFAULT_UDP_RECVMBOX_SIZE || defined __DOXYGEN__ -#define DEFAULT_UDP_RECVMBOX_SIZE 12 -#endif - -/** - * DEFAULT_TCP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a - * NETCONN_TCP. The queue size value itself is platform-dependent, but is passed - * to sys_mbox_new() when the recvmbox is created. - */ -#if !defined DEFAULT_TCP_RECVMBOX_SIZE || defined __DOXYGEN__ -#define DEFAULT_TCP_RECVMBOX_SIZE 12 -#endif - -/** - * DEFAULT_ACCEPTMBOX_SIZE: The mailbox size for the incoming connections. - * The queue size value itself is platform-dependent, but is passed to - * sys_mbox_new() when the acceptmbox is created. - */ -#if !defined DEFAULT_ACCEPTMBOX_SIZE || defined __DOXYGEN__ -#define DEFAULT_ACCEPTMBOX_SIZE 12 -#endif -/** - * @} - */ - -/* - ---------------------------------------------- - ---------- Sequential layer options ---------- - ---------------------------------------------- -*/ -/** - * @defgroup lwip_opts_netconn Netconn - * @ingroup lwip_opts_threadsafe_apis - * @{ - */ -/** - * LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c) - */ -#if !defined LWIP_NETCONN || defined __DOXYGEN__ -#define LWIP_NETCONN 1 -#endif - -/** LWIP_TCPIP_TIMEOUT==1: Enable tcpip_timeout/tcpip_untimeout to create - * timers running in tcpip_thread from another thread. - */ -#if !defined LWIP_TCPIP_TIMEOUT || defined __DOXYGEN__ -#define LWIP_TCPIP_TIMEOUT 0 -#endif - -/** LWIP_NETCONN_SEM_PER_THREAD==1: Use one (thread-local) semaphore per - * thread calling socket/netconn functions instead of allocating one - * semaphore per netconn (and per select etc.) - * ATTENTION: a thread-local semaphore for API calls is needed: - * - LWIP_NETCONN_THREAD_SEM_GET() returning a sys_sem_t* - * - LWIP_NETCONN_THREAD_SEM_ALLOC() creating the semaphore - * - LWIP_NETCONN_THREAD_SEM_FREE() freeing the semaphore - * The latter 2 can be invoked up by calling netconn_thread_init()/netconn_thread_cleanup(). - * Ports may call these for threads created with sys_thread_new(). - */ -#if !defined LWIP_NETCONN_SEM_PER_THREAD || defined __DOXYGEN__ -#define LWIP_NETCONN_SEM_PER_THREAD 0 -#endif - -/** LWIP_NETCONN_FULLDUPLEX==1: Enable code that allows reading from one thread, - * writing from a 2nd thread and closing from a 3rd thread at the same time. - * ATTENTION: This is currently really alpha! Some requirements: - * - LWIP_NETCONN_SEM_PER_THREAD==1 is required to use one socket/netconn from - * multiple threads at once - * - sys_mbox_free() has to unblock receive tasks waiting on recvmbox/acceptmbox - * and prevent a task pending on this during/after deletion - */ -#if !defined LWIP_NETCONN_FULLDUPLEX || defined __DOXYGEN__ -#define LWIP_NETCONN_FULLDUPLEX 0 -#endif -/** - * @} - */ - -/* - ------------------------------------ - ---------- Socket options ---------- - ------------------------------------ -*/ -/** - * @defgroup lwip_opts_socket Sockets - * @ingroup lwip_opts_threadsafe_apis - * @{ - */ -/** - * LWIP_SOCKET==1: Enable Socket API (require to use sockets.c) - */ -#if !defined LWIP_SOCKET || defined __DOXYGEN__ -#define LWIP_SOCKET 1 -#endif - -/** - * LWIP_COMPAT_SOCKETS==1: Enable BSD-style sockets functions names through defines. - * LWIP_COMPAT_SOCKETS==2: Same as ==1 but correctly named functions are created. - * While this helps code completion, it might conflict with existing libraries. - * (only used if you use sockets.c) - */ -#if !defined LWIP_COMPAT_SOCKETS || defined __DOXYGEN__ -#define LWIP_COMPAT_SOCKETS 1 -#endif - -/** - * LWIP_POSIX_SOCKETS_IO_NAMES==1: Enable POSIX-style sockets functions names. - * Disable this option if you use a POSIX operating system that uses the same - * names (read, write & close). (only used if you use sockets.c) - */ -#if !defined LWIP_POSIX_SOCKETS_IO_NAMES || defined __DOXYGEN__ -#define LWIP_POSIX_SOCKETS_IO_NAMES 1 -#endif - -/** - * LWIP_SOCKET_OFFSET==n: Increases the file descriptor number created by LwIP with n. - * This can be useful when there are multiple APIs which create file descriptors. - * When they all start with a different offset and you won't make them overlap you can - * re implement read/write/close/ioctl/fnctl to send the requested action to the right - * library (sharing select will need more work though). - */ -#if !defined LWIP_SOCKET_OFFSET || defined __DOXYGEN__ -#define LWIP_SOCKET_OFFSET 0 -#endif - -/** - * LWIP_TCP_KEEPALIVE==1: Enable TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT - * options processing. Note that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set - * in seconds. (does not require sockets.c, and will affect tcp.c) - */ -#if !defined LWIP_TCP_KEEPALIVE || defined __DOXYGEN__ -#define LWIP_TCP_KEEPALIVE 0 -#endif - -/** - * LWIP_SO_SNDTIMEO==1: Enable send timeout for sockets/netconns and - * SO_SNDTIMEO processing. - */ -#if !defined LWIP_SO_SNDTIMEO || defined __DOXYGEN__ -#define LWIP_SO_SNDTIMEO 0 -#endif - -/** - * LWIP_SO_RCVTIMEO==1: Enable receive timeout for sockets/netconns and - * SO_RCVTIMEO processing. - */ -#if !defined LWIP_SO_RCVTIMEO || defined __DOXYGEN__ -#define LWIP_SO_RCVTIMEO 0 -#endif - -/** - * LWIP_SO_SNDRCVTIMEO_NONSTANDARD==1: SO_RCVTIMEO/SO_SNDTIMEO take an int - * (milliseconds, much like winsock does) instead of a struct timeval (default). - */ -#if !defined LWIP_SO_SNDRCVTIMEO_NONSTANDARD || defined __DOXYGEN__ -#define LWIP_SO_SNDRCVTIMEO_NONSTANDARD 0 -#endif - -/** - * LWIP_SO_RCVBUF==1: Enable SO_RCVBUF processing. - */ -#if !defined LWIP_SO_RCVBUF || defined __DOXYGEN__ -#define LWIP_SO_RCVBUF 0 -#endif - -/** - * LWIP_SO_LINGER==1: Enable SO_LINGER processing. - */ -#if !defined LWIP_SO_LINGER || defined __DOXYGEN__ -#define LWIP_SO_LINGER 0 -#endif - -/** - * If LWIP_SO_RCVBUF is used, this is the default value for recv_bufsize. - */ -#if !defined RECV_BUFSIZE_DEFAULT || defined __DOXYGEN__ -#define RECV_BUFSIZE_DEFAULT INT_MAX -#endif - -/** - * By default, TCP socket/netconn close waits 20 seconds max to send the FIN - */ -#if !defined LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT || defined __DOXYGEN__ -#define LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT 20000 -#endif - -/** - * SO_REUSE==1: Enable SO_REUSEADDR option. - */ -#if !defined SO_REUSE || defined __DOXYGEN__ -#define SO_REUSE 0 -#endif - -/** - * SO_REUSE_RXTOALL==1: Pass a copy of incoming broadcast/multicast packets - * to all local matches if SO_REUSEADDR is turned on. - * WARNING: Adds a memcpy for every packet if passing to more than one pcb! - */ -#if !defined SO_REUSE_RXTOALL || defined __DOXYGEN__ -#define SO_REUSE_RXTOALL 0 -#endif - -/** - * LWIP_FIONREAD_LINUXMODE==0 (default): ioctl/FIONREAD returns the amount of - * pending data in the network buffer. This is the way windows does it. It's - * the default for lwIP since it is smaller. - * LWIP_FIONREAD_LINUXMODE==1: ioctl/FIONREAD returns the size of the next - * pending datagram in bytes. This is the way linux does it. This code is only - * here for compatibility. - */ -#if !defined LWIP_FIONREAD_LINUXMODE || defined __DOXYGEN__ -#define LWIP_FIONREAD_LINUXMODE 0 -#endif - -/** - * LWIP_SOCKET_SELECT==1 (default): enable select() for sockets (uses a netconn - * callback to keep track of events). - * This saves RAM (counters per socket) and code (netconn event callback), which - * should improve performance a bit). - */ -#if !defined LWIP_SOCKET_SELECT || defined __DOXYGEN__ -#define LWIP_SOCKET_SELECT 1 -#endif - -/** - * LWIP_SOCKET_POLL==1 (default): enable poll() for sockets (including - * struct pollfd, nfds_t, and constants) - */ -#if !defined LWIP_SOCKET_POLL || defined __DOXYGEN__ -#define LWIP_SOCKET_POLL 1 -#endif -/** - * @} - */ - -/* - ---------------------------------------- - ---------- Statistics options ---------- - ---------------------------------------- -*/ -/** - * @defgroup lwip_opts_stats Statistics - * @ingroup lwip_opts_debug - * @{ - */ -/** - * LWIP_STATS==1: Enable statistics collection in lwip_stats. - */ -#if !defined LWIP_STATS || defined __DOXYGEN__ -#define LWIP_STATS 1 -#endif - -#if LWIP_STATS - -/** - * LWIP_STATS_DISPLAY==1: Compile in the statistics output functions. - */ -#if !defined LWIP_STATS_DISPLAY || defined __DOXYGEN__ -#define LWIP_STATS_DISPLAY 0 -#endif - -/** - * LINK_STATS==1: Enable link stats. - */ -#if !defined LINK_STATS || defined __DOXYGEN__ -#define LINK_STATS 1 -#endif - -/** - * ETHARP_STATS==1: Enable etharp stats. - */ -#if !defined ETHARP_STATS || defined __DOXYGEN__ -#define ETHARP_STATS (LWIP_ARP) -#endif - -/** - * IP_STATS==1: Enable IP stats. - */ -#if !defined IP_STATS || defined __DOXYGEN__ -#define IP_STATS 1 -#endif - -/** - * IPFRAG_STATS==1: Enable IP fragmentation stats. Default is - * on if using either frag or reass. - */ -#if !defined IPFRAG_STATS || defined __DOXYGEN__ -#define IPFRAG_STATS (IP_REASSEMBLY || IP_FRAG) -#endif - -/** - * ICMP_STATS==1: Enable ICMP stats. - */ -#if !defined ICMP_STATS || defined __DOXYGEN__ -#define ICMP_STATS 1 -#endif - -/** - * IGMP_STATS==1: Enable IGMP stats. - */ -#if !defined IGMP_STATS || defined __DOXYGEN__ -#define IGMP_STATS (LWIP_IGMP) -#endif - -/** - * UDP_STATS==1: Enable UDP stats. Default is on if - * UDP enabled, otherwise off. - */ -#if !defined UDP_STATS || defined __DOXYGEN__ -#define UDP_STATS (LWIP_UDP) -#endif - -/** - * TCP_STATS==1: Enable TCP stats. Default is on if TCP - * enabled, otherwise off. - */ -#if !defined TCP_STATS || defined __DOXYGEN__ -#define TCP_STATS (LWIP_TCP) -#endif - -/** - * MEM_STATS==1: Enable mem.c stats. - */ -#if !defined MEM_STATS || defined __DOXYGEN__ -#define MEM_STATS ((MEM_LIBC_MALLOC == 0) && (MEM_USE_POOLS == 0)) -#endif - -/** - * MEMP_STATS==1: Enable memp.c pool stats. - */ -#if !defined MEMP_STATS || defined __DOXYGEN__ -#define MEMP_STATS (MEMP_MEM_MALLOC == 0) -#endif - -/** - * SYS_STATS==1: Enable system stats (sem and mbox counts, etc). - */ -#if !defined SYS_STATS || defined __DOXYGEN__ -#define SYS_STATS (NO_SYS == 0) -#endif - -/** - * IP6_STATS==1: Enable IPv6 stats. - */ -#if !defined IP6_STATS || defined __DOXYGEN__ -#define IP6_STATS (LWIP_IPV6) -#endif - -/** - * ICMP6_STATS==1: Enable ICMP for IPv6 stats. - */ -#if !defined ICMP6_STATS || defined __DOXYGEN__ -#define ICMP6_STATS (LWIP_IPV6 && LWIP_ICMP6) -#endif - -/** - * IP6_FRAG_STATS==1: Enable IPv6 fragmentation stats. - */ -#if !defined IP6_FRAG_STATS || defined __DOXYGEN__ -#define IP6_FRAG_STATS (LWIP_IPV6 && (LWIP_IPV6_FRAG || LWIP_IPV6_REASS)) -#endif - -/** - * MLD6_STATS==1: Enable MLD for IPv6 stats. - */ -#if !defined MLD6_STATS || defined __DOXYGEN__ -#define MLD6_STATS (LWIP_IPV6 && LWIP_IPV6_MLD) -#endif - -/** - * ND6_STATS==1: Enable Neighbor discovery for IPv6 stats. - */ -#if !defined ND6_STATS || defined __DOXYGEN__ -#define ND6_STATS (LWIP_IPV6) -#endif - -/** - * MIB2_STATS==1: Stats for SNMP MIB2. - */ -#if !defined MIB2_STATS || defined __DOXYGEN__ -#define MIB2_STATS 0 -#endif - -#else - -#define LINK_STATS 0 -#define ETHARP_STATS 0 -#define IP_STATS 0 -#define IPFRAG_STATS 0 -#define ICMP_STATS 0 -#define IGMP_STATS 0 -#define UDP_STATS 0 -#define TCP_STATS 0 -#define MEM_STATS 0 -#define MEMP_STATS 0 -#define SYS_STATS 0 -#define LWIP_STATS_DISPLAY 0 -#define IP6_STATS 0 -#define ICMP6_STATS 0 -#define IP6_FRAG_STATS 0 -#define MLD6_STATS 0 -#define ND6_STATS 0 -#define MIB2_STATS 0 - -#endif /* LWIP_STATS */ -/** - * @} - */ - -/* - -------------------------------------- - ---------- Checksum options ---------- - -------------------------------------- -*/ -/** - * @defgroup lwip_opts_checksum Checksum - * @ingroup lwip_opts_infrastructure - * @{ - */ -/** - * LWIP_CHECKSUM_CTRL_PER_NETIF==1: Checksum generation/check can be enabled/disabled - * per netif. - * ATTENTION: if enabled, the CHECKSUM_GEN_* and CHECKSUM_CHECK_* defines must be enabled! - */ -#if !defined LWIP_CHECKSUM_CTRL_PER_NETIF || defined __DOXYGEN__ -#define LWIP_CHECKSUM_CTRL_PER_NETIF 0 -#endif - -/** - * CHECKSUM_GEN_IP==1: Generate checksums in software for outgoing IP packets. - */ -#if !defined CHECKSUM_GEN_IP || defined __DOXYGEN__ -#define CHECKSUM_GEN_IP 1 -#endif - -/** - * CHECKSUM_GEN_UDP==1: Generate checksums in software for outgoing UDP packets. - */ -#if !defined CHECKSUM_GEN_UDP || defined __DOXYGEN__ -#define CHECKSUM_GEN_UDP 1 -#endif - -/** - * CHECKSUM_GEN_TCP==1: Generate checksums in software for outgoing TCP packets. - */ -#if !defined CHECKSUM_GEN_TCP || defined __DOXYGEN__ -#define CHECKSUM_GEN_TCP 1 -#endif - -/** - * CHECKSUM_GEN_ICMP==1: Generate checksums in software for outgoing ICMP packets. - */ -#if !defined CHECKSUM_GEN_ICMP || defined __DOXYGEN__ -#define CHECKSUM_GEN_ICMP 1 -#endif - -/** - * CHECKSUM_GEN_ICMP6==1: Generate checksums in software for outgoing ICMP6 packets. - */ -#if !defined CHECKSUM_GEN_ICMP6 || defined __DOXYGEN__ -#define CHECKSUM_GEN_ICMP6 1 -#endif - -/** - * CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets. - */ -#if !defined CHECKSUM_CHECK_IP || defined __DOXYGEN__ -#define CHECKSUM_CHECK_IP 1 -#endif - -/** - * CHECKSUM_CHECK_UDP==1: Check checksums in software for incoming UDP packets. - */ -#if !defined CHECKSUM_CHECK_UDP || defined __DOXYGEN__ -#define CHECKSUM_CHECK_UDP 1 -#endif - -/** - * CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets. - */ -#if !defined CHECKSUM_CHECK_TCP || defined __DOXYGEN__ -#define CHECKSUM_CHECK_TCP 1 -#endif - -/** - * CHECKSUM_CHECK_ICMP==1: Check checksums in software for incoming ICMP packets. - */ -#if !defined CHECKSUM_CHECK_ICMP || defined __DOXYGEN__ -#define CHECKSUM_CHECK_ICMP 1 -#endif - -/** - * CHECKSUM_CHECK_ICMP6==1: Check checksums in software for incoming ICMPv6 packets - */ -#if !defined CHECKSUM_CHECK_ICMP6 || defined __DOXYGEN__ -#define CHECKSUM_CHECK_ICMP6 1 -#endif - -/** - * LWIP_CHECKSUM_ON_COPY==1: Calculate checksum when copying data from - * application buffers to pbufs. - */ -#if !defined LWIP_CHECKSUM_ON_COPY || defined __DOXYGEN__ -#define LWIP_CHECKSUM_ON_COPY 0 -#endif -/** - * @} - */ - -/* - --------------------------------------- - ---------- IPv6 options --------------- - --------------------------------------- -*/ -/** - * @defgroup lwip_opts_ipv6 IPv6 - * @ingroup lwip_opts - * @{ - */ -/** - * LWIP_IPV6==1: Enable IPv6 - */ -#if !defined LWIP_IPV6 || defined __DOXYGEN__ -#define LWIP_IPV6 0 -#endif - -/** - * IPV6_REASS_MAXAGE: Maximum time (in multiples of IP6_REASS_TMR_INTERVAL - so seconds, normally) - * a fragmented IP packet waits for all fragments to arrive. If not all fragments arrived - * in this time, the whole packet is discarded. - */ -#if !defined IPV6_REASS_MAXAGE || defined __DOXYGEN__ -#define IPV6_REASS_MAXAGE 60 -#endif - -/** - * LWIP_IPV6_SCOPES==1: Enable support for IPv6 address scopes, ensuring that - * e.g. link-local addresses are really treated as link-local. Disable this - * setting only for single-interface configurations. - * All addresses that have a scope according to the default policy (link-local - * unicast addresses, interface-local and link-local multicast addresses) should - * now have a zone set on them before being passed to the core API, although - * lwIP will currently attempt to select a zone on the caller's behalf when - * necessary. Applications that directly assign IPv6 addresses to interfaces - * (which is NOT recommended) must now ensure that link-local addresses carry - * the netif's zone. See the new ip6_zone.h header file for more information and - * relevant macros. For now it is still possible to turn off scopes support - * through the new LWIP_IPV6_SCOPES option. When upgrading an implementation that - * uses the core API directly, it is highly recommended to enable - * LWIP_IPV6_SCOPES_DEBUG at least for a while, to ensure e.g. proper address - * initialization. - */ -#if !defined LWIP_IPV6_SCOPES || defined __DOXYGEN__ -#define LWIP_IPV6_SCOPES (LWIP_IPV6 && !LWIP_SINGLE_NETIF) -#endif - -/** - * LWIP_IPV6_SCOPES_DEBUG==1: Perform run-time checks to verify that addresses - * are properly zoned (see ip6_zone.h on what that means) where it matters. - * Enabling this setting is highly recommended when upgrading from an existing - * installation that is not yet scope-aware; otherwise it may be too expensive. - */ -#if !defined LWIP_IPV6_SCOPES_DEBUG || defined __DOXYGEN__ -#define LWIP_IPV6_SCOPES_DEBUG 0 -#endif - -/** - * LWIP_IPV6_NUM_ADDRESSES: Number of IPv6 addresses per netif. - */ -#if !defined LWIP_IPV6_NUM_ADDRESSES || defined __DOXYGEN__ -#define LWIP_IPV6_NUM_ADDRESSES 3 -#endif - -/** - * LWIP_IPV6_FORWARD==1: Forward IPv6 packets across netifs - */ -#if !defined LWIP_IPV6_FORWARD || defined __DOXYGEN__ -#define LWIP_IPV6_FORWARD 0 -#endif - -/** - * LWIP_IPV6_FRAG==1: Fragment outgoing IPv6 packets that are too big. - */ -#if !defined LWIP_IPV6_FRAG || defined __DOXYGEN__ -#define LWIP_IPV6_FRAG 1 -#endif - -/** - * LWIP_IPV6_REASS==1: reassemble incoming IPv6 packets that fragmented - */ -#if !defined LWIP_IPV6_REASS || defined __DOXYGEN__ -#define LWIP_IPV6_REASS LWIP_IPV6 -#endif - -/** - * LWIP_IPV6_SEND_ROUTER_SOLICIT==1: Send router solicitation messages during - * network startup. - */ -#if !defined LWIP_IPV6_SEND_ROUTER_SOLICIT || defined __DOXYGEN__ -#define LWIP_IPV6_SEND_ROUTER_SOLICIT 1 -#endif - -/** - * LWIP_IPV6_AUTOCONFIG==1: Enable stateless address autoconfiguration as per RFC 4862. - */ -#if !defined LWIP_IPV6_AUTOCONFIG || defined __DOXYGEN__ -#define LWIP_IPV6_AUTOCONFIG LWIP_IPV6 -#endif - -/** - * LWIP_IPV6_ADDRESS_LIFETIMES==1: Keep valid and preferred lifetimes for each - * IPv6 address. Required for LWIP_IPV6_AUTOCONFIG. May still be enabled - * otherwise, in which case the application may assign address lifetimes with - * the appropriate macros. Addresses with no lifetime are assumed to be static. - * If this option is disabled, all addresses are assumed to be static. - */ -#if !defined LWIP_IPV6_ADDRESS_LIFETIMES || defined __DOXYGEN__ -#define LWIP_IPV6_ADDRESS_LIFETIMES LWIP_IPV6_AUTOCONFIG -#endif - -/** - * LWIP_IPV6_DUP_DETECT_ATTEMPTS=[0..7]: Number of duplicate address detection attempts. - */ -#if !defined LWIP_IPV6_DUP_DETECT_ATTEMPTS || defined __DOXYGEN__ -#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 1 -#endif -/** - * @} - */ - -/** - * @defgroup lwip_opts_icmp6 ICMP6 - * @ingroup lwip_opts_ipv6 - * @{ - */ -/** - * LWIP_ICMP6==1: Enable ICMPv6 (mandatory per RFC) - */ -#if !defined LWIP_ICMP6 || defined __DOXYGEN__ -#define LWIP_ICMP6 LWIP_IPV6 -#endif - -/** - * LWIP_ICMP6_DATASIZE: bytes from original packet to send back in - * ICMPv6 error messages. - */ -#if !defined LWIP_ICMP6_DATASIZE || defined __DOXYGEN__ -#define LWIP_ICMP6_DATASIZE 8 -#endif - -/** - * LWIP_ICMP6_HL: default hop limit for ICMPv6 messages - */ -#if !defined LWIP_ICMP6_HL || defined __DOXYGEN__ -#define LWIP_ICMP6_HL 255 -#endif -/** - * @} - */ - -/** - * @defgroup lwip_opts_mld6 Multicast listener discovery - * @ingroup lwip_opts_ipv6 - * @{ - */ -/** - * LWIP_IPV6_MLD==1: Enable multicast listener discovery protocol. - * If LWIP_IPV6 is enabled but this setting is disabled, the MAC layer must - * indiscriminately pass all inbound IPv6 multicast traffic to lwIP. - */ -#if !defined LWIP_IPV6_MLD || defined __DOXYGEN__ -#define LWIP_IPV6_MLD LWIP_IPV6 -#endif - -/** - * MEMP_NUM_MLD6_GROUP: Max number of IPv6 multicast groups that can be joined. - * There must be enough groups so that each netif can join the solicited-node - * multicast group for each of its local addresses, plus one for MDNS if - * applicable, plus any number of groups to be joined on UDP sockets. - */ -#if !defined MEMP_NUM_MLD6_GROUP || defined __DOXYGEN__ -#define MEMP_NUM_MLD6_GROUP 4 -#endif -/** - * @} - */ - -/** - * @defgroup lwip_opts_nd6 Neighbor discovery - * @ingroup lwip_opts_ipv6 - * @{ - */ -/** - * LWIP_ND6_QUEUEING==1: queue outgoing IPv6 packets while MAC address - * is being resolved. - */ -#if !defined LWIP_ND6_QUEUEING || defined __DOXYGEN__ -#define LWIP_ND6_QUEUEING LWIP_IPV6 -#endif - -/** - * MEMP_NUM_ND6_QUEUE: Max number of IPv6 packets to queue during MAC resolution. - */ -#if !defined MEMP_NUM_ND6_QUEUE || defined __DOXYGEN__ -#define MEMP_NUM_ND6_QUEUE 20 -#endif - -/** - * LWIP_ND6_NUM_NEIGHBORS: Number of entries in IPv6 neighbor cache - */ -#if !defined LWIP_ND6_NUM_NEIGHBORS || defined __DOXYGEN__ -#define LWIP_ND6_NUM_NEIGHBORS 10 -#endif - -/** - * LWIP_ND6_NUM_DESTINATIONS: number of entries in IPv6 destination cache - */ -#if !defined LWIP_ND6_NUM_DESTINATIONS || defined __DOXYGEN__ -#define LWIP_ND6_NUM_DESTINATIONS 10 -#endif - -/** - * LWIP_ND6_NUM_PREFIXES: number of entries in IPv6 on-link prefixes cache - */ -#if !defined LWIP_ND6_NUM_PREFIXES || defined __DOXYGEN__ -#define LWIP_ND6_NUM_PREFIXES 5 -#endif - -/** - * LWIP_ND6_NUM_ROUTERS: number of entries in IPv6 default router cache - */ -#if !defined LWIP_ND6_NUM_ROUTERS || defined __DOXYGEN__ -#define LWIP_ND6_NUM_ROUTERS 3 -#endif - -/** - * LWIP_ND6_MAX_MULTICAST_SOLICIT: max number of multicast solicit messages to send - * (neighbor solicit and router solicit) - */ -#if !defined LWIP_ND6_MAX_MULTICAST_SOLICIT || defined __DOXYGEN__ -#define LWIP_ND6_MAX_MULTICAST_SOLICIT 3 -#endif - -/** - * LWIP_ND6_MAX_UNICAST_SOLICIT: max number of unicast neighbor solicitation messages - * to send during neighbor reachability detection. - */ -#if !defined LWIP_ND6_MAX_UNICAST_SOLICIT || defined __DOXYGEN__ -#define LWIP_ND6_MAX_UNICAST_SOLICIT 3 -#endif - -/** - * Unused: See ND RFC (time in milliseconds). - */ -#if !defined LWIP_ND6_MAX_ANYCAST_DELAY_TIME || defined __DOXYGEN__ -#define LWIP_ND6_MAX_ANYCAST_DELAY_TIME 1000 -#endif - -/** - * Unused: See ND RFC - */ -#if !defined LWIP_ND6_MAX_NEIGHBOR_ADVERTISEMENT || defined __DOXYGEN__ -#define LWIP_ND6_MAX_NEIGHBOR_ADVERTISEMENT 3 -#endif - -/** - * LWIP_ND6_REACHABLE_TIME: default neighbor reachable time (in milliseconds). - * May be updated by router advertisement messages. - */ -#if !defined LWIP_ND6_REACHABLE_TIME || defined __DOXYGEN__ -#define LWIP_ND6_REACHABLE_TIME 30000 -#endif - -/** - * LWIP_ND6_RETRANS_TIMER: default retransmission timer for solicitation messages - */ -#if !defined LWIP_ND6_RETRANS_TIMER || defined __DOXYGEN__ -#define LWIP_ND6_RETRANS_TIMER 1000 -#endif - -/** - * LWIP_ND6_DELAY_FIRST_PROBE_TIME: Delay before first unicast neighbor solicitation - * message is sent, during neighbor reachability detection. - */ -#if !defined LWIP_ND6_DELAY_FIRST_PROBE_TIME || defined __DOXYGEN__ -#define LWIP_ND6_DELAY_FIRST_PROBE_TIME 5000 -#endif - -/** - * LWIP_ND6_ALLOW_RA_UPDATES==1: Allow Router Advertisement messages to update - * Reachable time and retransmission timers, and netif MTU. - */ -#if !defined LWIP_ND6_ALLOW_RA_UPDATES || defined __DOXYGEN__ -#define LWIP_ND6_ALLOW_RA_UPDATES 1 -#endif - -/** - * LWIP_ND6_TCP_REACHABILITY_HINTS==1: Allow TCP to provide Neighbor Discovery - * with reachability hints for connected destinations. This helps avoid sending - * unicast neighbor solicitation messages. - */ -#if !defined LWIP_ND6_TCP_REACHABILITY_HINTS || defined __DOXYGEN__ -#define LWIP_ND6_TCP_REACHABILITY_HINTS 1 -#endif - -/** - * LWIP_ND6_RDNSS_MAX_DNS_SERVERS > 0: Use IPv6 Router Advertisement Recursive - * DNS Server Option (as per RFC 6106) to copy a defined maximum number of DNS - * servers to the DNS module. - */ -#if !defined LWIP_ND6_RDNSS_MAX_DNS_SERVERS || defined __DOXYGEN__ -#define LWIP_ND6_RDNSS_MAX_DNS_SERVERS 0 -#endif -/** - * @} - */ - -/** - * @defgroup lwip_opts_dhcpv6 DHCPv6 - * @ingroup lwip_opts_ipv6 - * @{ - */ -/** - * LWIP_IPV6_DHCP6==1: enable DHCPv6 stateful/stateless address autoconfiguration. - */ -#if !defined LWIP_IPV6_DHCP6 || defined __DOXYGEN__ -#define LWIP_IPV6_DHCP6 0 -#endif - -/** - * LWIP_IPV6_DHCP6_STATEFUL==1: enable DHCPv6 stateful address autoconfiguration. - * (not supported, yet!) - */ -#if !defined LWIP_IPV6_DHCP6_STATEFUL || defined __DOXYGEN__ -#define LWIP_IPV6_DHCP6_STATEFUL 0 -#endif - -/** - * LWIP_IPV6_DHCP6_STATELESS==1: enable DHCPv6 stateless address autoconfiguration. - */ -#if !defined LWIP_IPV6_DHCP6_STATELESS || defined __DOXYGEN__ -#define LWIP_IPV6_DHCP6_STATELESS LWIP_IPV6_DHCP6 -#endif - -/** - * LWIP_DHCP6_GETS_NTP==1: Request NTP servers via DHCPv6. For each - * response packet, a callback is called, which has to be provided by the port: - * void dhcp6_set_ntp_servers(u8_t num_ntp_servers, ip_addr_t* ntp_server_addrs); -*/ -#if !defined LWIP_DHCP6_GET_NTP_SRV || defined __DOXYGEN__ -#define LWIP_DHCP6_GET_NTP_SRV 0 -#endif - -/** - * The maximum of NTP servers requested - */ -#if !defined LWIP_DHCP6_MAX_NTP_SERVERS || defined __DOXYGEN__ -#define LWIP_DHCP6_MAX_NTP_SERVERS 1 -#endif - -/** - * LWIP_DHCP6_MAX_DNS_SERVERS > 0: Request DNS servers via DHCPv6. - * DNS servers received in the response are passed to DNS via @ref dns_setserver() - * (up to the maximum limit defined here). - */ -#if !defined LWIP_DHCP6_MAX_DNS_SERVERS || defined __DOXYGEN__ -#define LWIP_DHCP6_MAX_DNS_SERVERS DNS_MAX_SERVERS -#endif -/** - * @} - */ - -/* - --------------------------------------- - ---------- Hook options --------------- - --------------------------------------- -*/ - -/** - * @defgroup lwip_opts_hooks Hooks - * @ingroup lwip_opts_infrastructure - * Hooks are undefined by default, define them to a function if you need them. - * @{ - */ - -/** - * LWIP_HOOK_FILENAME: Custom filename to \#include in files that provide hooks. - * Declare your hook function prototypes in there, you may also \#include all headers - * providing data types that are need in this file. - */ -#ifdef __DOXYGEN__ -#define LWIP_HOOK_FILENAME "path/to/my/lwip_hooks.h" -#endif - -/** - * LWIP_HOOK_TCP_ISN: - * Hook for generation of the Initial Sequence Number (ISN) for a new TCP - * connection. The default lwIP ISN generation algorithm is very basic and may - * allow for TCP spoofing attacks. This hook provides the means to implement - * the standardized ISN generation algorithm from RFC 6528 (see contrib/adons/tcp_isn), - * or any other desired algorithm as a replacement. - * Called from tcp_connect() and tcp_listen_input() when an ISN is needed for - * a new TCP connection, if TCP support (@ref LWIP_TCP) is enabled.\n - * Signature:\code{.c} - * u32_t my_hook_tcp_isn(const ip_addr_t* local_ip, u16_t local_port, const ip_addr_t* remote_ip, u16_t remote_port); - * \endcode - * - it may be necessary to use "struct ip_addr" (ip4_addr, ip6_addr) instead of "ip_addr_t" in function declarations\n - * Arguments: - * - local_ip: pointer to the local IP address of the connection - * - local_port: local port number of the connection (host-byte order) - * - remote_ip: pointer to the remote IP address of the connection - * - remote_port: remote port number of the connection (host-byte order)\n - * Return value: - * - the 32-bit Initial Sequence Number to use for the new TCP connection. - */ -#ifdef __DOXYGEN__ -#define LWIP_HOOK_TCP_ISN(local_ip, local_port, remote_ip, remote_port) -#endif - -/** - * LWIP_HOOK_TCP_INPACKET_PCB: - * Hook for intercepting incoming packets before they are passed to a pcb. This - * allows updating some state or even dropping a packet. - * Signature:\code{.c} - * err_t my_hook_tcp_inpkt(struct tcp_pcb *pcb, struct tcp_hdr *hdr, u16_t optlen, u16_t opt1len, u8_t *opt2, struct pbuf *p); - * \endcode - * Arguments: - * - pcb: tcp_pcb selected for input of this packet (ATTENTION: this may be - * struct tcp_pcb_listen if pcb->state == LISTEN) - * - hdr: pointer to tcp header (ATTENTION: tcp options may not be in one piece!) - * - optlen: tcp option length - * - opt1len: tcp option length 1st part - * - opt2: if this is != NULL, tcp options are split among 2 pbufs. In that case, - * options start at right after the tcp header ('(u8_t*)(hdr + 1)') for - * the first 'opt1len' bytes and the rest starts at 'opt2'. opt2len can - * be simply calculated: 'opt2len = optlen - opt1len;' - * - p: input packet, p->payload points to application data (that's why tcp hdr - * and options are passed in seperately) - * Return value: - * - ERR_OK: continue input of this packet as normal - * - != ERR_OK: drop this packet for input (don't continue input processing) - * - * ATTENTION: don't call any tcp api functions that might change tcp state (pcb - * state or any pcb lists) from this callback! - */ -#ifdef __DOXYGEN__ -#define LWIP_HOOK_TCP_INPACKET_PCB(pcb, hdr, optlen, opt1len, opt2, p) -#endif - -/** - * LWIP_HOOK_TCP_OUT_TCPOPT_LENGTH: - * Hook for increasing the size of the options allocated with a tcp header. - * Together with LWIP_HOOK_TCP_OUT_ADD_TCPOPTS, this can be used to add custom - * options to outgoing tcp segments. - * Signature:\code{.c} - * u8_t my_hook_tcp_out_tcpopt_length(const struct tcp_pcb *pcb, u8_t internal_option_length); - * \endcode - * Arguments: - * - pcb: tcp_pcb that transmits (ATTENTION: this may be NULL or - * struct tcp_pcb_listen if pcb->state == LISTEN) - * - internal_option_length: tcp option length used by the stack internally - * Return value: - * - a number of bytes to allocate for tcp options (internal_option_length <= ret <= 40) - * - * ATTENTION: don't call any tcp api functions that might change tcp state (pcb - * state or any pcb lists) from this callback! - */ -#ifdef __DOXYGEN__ -#define LWIP_HOOK_TCP_OUT_TCPOPT_LENGTH(pcb, internal_len) -#endif - -/** - * LWIP_HOOK_TCP_OUT_ADD_TCPOPTS: - * Hook for adding custom options to outgoing tcp segments. - * Space for these custom options has to be reserved via LWIP_HOOK_TCP_OUT_TCPOPT_LENGTH. - * Signature:\code{.c} - * u32_t *my_hook_tcp_out_add_tcpopts(struct pbuf *p, struct tcp_hdr *hdr, const struct tcp_pcb *pcb, u32_t *opts); - * \endcode - * Arguments: - * - p: output packet, p->payload pointing to tcp header, data follows - * - hdr: tcp header - * - pcb: tcp_pcb that transmits (ATTENTION: this may be NULL or - * struct tcp_pcb_listen if pcb->state == LISTEN) - * - opts: pointer where to add the custom options (there may already be options - * between the header and these) - * Return value: - * - pointer pointing directly after the inserted options - * - * ATTENTION: don't call any tcp api functions that might change tcp state (pcb - * state or any pcb lists) from this callback! - */ -#ifdef __DOXYGEN__ -#define LWIP_HOOK_TCP_OUT_ADD_TCPOPTS(p, hdr, pcb, opts) -#endif - -/** - * LWIP_HOOK_IP4_INPUT(pbuf, input_netif): - * Called from ip_input() (IPv4) - * Signature:\code{.c} - * int my_hook(struct pbuf *pbuf, struct netif *input_netif); - * \endcode - * Arguments: - * - pbuf: received struct pbuf passed to ip_input() - * - input_netif: struct netif on which the packet has been received - * Return values: - * - 0: Hook has not consumed the packet, packet is processed as normal - * - != 0: Hook has consumed the packet. - * If the hook consumed the packet, 'pbuf' is in the responsibility of the hook - * (i.e. free it when done). - */ -#ifdef __DOXYGEN__ -#define LWIP_HOOK_IP4_INPUT(pbuf, input_netif) -#endif - -/** - * LWIP_HOOK_IP4_ROUTE(dest): - * Called from ip_route() (IPv4) - * Signature:\code{.c} - * struct netif *my_hook(const ip4_addr_t *dest); - * \endcode - * Arguments: - * - dest: destination IPv4 address - * Returns values: - * - the destination netif - * - NULL if no destination netif is found. In that case, ip_route() continues as normal. - */ -#ifdef __DOXYGEN__ -#define LWIP_HOOK_IP4_ROUTE() -#endif - -/** - * LWIP_HOOK_IP4_ROUTE_SRC(src, dest): - * Source-based routing for IPv4 - called from ip_route() (IPv4) - * Signature:\code{.c} - * struct netif *my_hook(const ip4_addr_t *src, const ip4_addr_t *dest); - * \endcode - * Arguments: - * - src: local/source IPv4 address - * - dest: destination IPv4 address - * Returns values: - * - the destination netif - * - NULL if no destination netif is found. In that case, ip_route() continues as normal. - */ -#ifdef __DOXYGEN__ -#define LWIP_HOOK_IP4_ROUTE_SRC(src, dest) -#endif - -/** - * LWIP_HOOK_IP4_CANFORWARD(src, dest): - * Check if an IPv4 can be forwarded - called from: - * ip4_input() -> ip4_forward() -> ip4_canforward() (IPv4) - * - source address is available via ip4_current_src_addr() - * - calling an output function in this context (e.g. multicast router) is allowed - * Signature:\code{.c} - * int my_hook(struct pbuf *p, u32_t dest_addr_hostorder); - * \endcode - * Arguments: - * - p: packet to forward - * - dest: destination IPv4 address - * Returns values: - * - 1: forward - * - 0: don't forward - * - -1: no decision. In that case, ip4_canforward() continues as normal. - */ -#ifdef __DOXYGEN__ -#define LWIP_HOOK_IP4_CANFORWARD(src, dest) -#endif - -/** - * LWIP_HOOK_ETHARP_GET_GW(netif, dest): - * Called from etharp_output() (IPv4) - * Signature:\code{.c} - * const ip4_addr_t *my_hook(struct netif *netif, const ip4_addr_t *dest); - * \endcode - * Arguments: - * - netif: the netif used for sending - * - dest: the destination IPv4 address - * Return values: - * - the IPv4 address of the gateway to handle the specified destination IPv4 address - * - NULL, in which case the netif's default gateway is used - * - * The returned address MUST be directly reachable on the specified netif! - * This function is meant to implement advanced IPv4 routing together with - * LWIP_HOOK_IP4_ROUTE(). The actual routing/gateway table implementation is - * not part of lwIP but can e.g. be hidden in the netif's state argument. -*/ -#ifdef __DOXYGEN__ -#define LWIP_HOOK_ETHARP_GET_GW(netif, dest) -#endif - -/** - * LWIP_HOOK_IP6_INPUT(pbuf, input_netif): - * Called from ip6_input() (IPv6) - * Signature:\code{.c} - * int my_hook(struct pbuf *pbuf, struct netif *input_netif); - * \endcode - * Arguments: - * - pbuf: received struct pbuf passed to ip6_input() - * - input_netif: struct netif on which the packet has been received - * Return values: - * - 0: Hook has not consumed the packet, packet is processed as normal - * - != 0: Hook has consumed the packet. - * If the hook consumed the packet, 'pbuf' is in the responsibility of the hook - * (i.e. free it when done). - */ -#ifdef __DOXYGEN__ -#define LWIP_HOOK_IP6_INPUT(pbuf, input_netif) -#endif - -/** - * LWIP_HOOK_IP6_ROUTE(src, dest): - * Called from ip_route() (IPv6) - * Signature:\code{.c} - * struct netif *my_hook(const ip6_addr_t *dest, const ip6_addr_t *src); - * \endcode - * Arguments: - * - src: source IPv6 address - * - dest: destination IPv6 address - * Return values: - * - the destination netif - * - NULL if no destination netif is found. In that case, ip6_route() continues as normal. - */ -#ifdef __DOXYGEN__ -#define LWIP_HOOK_IP6_ROUTE(src, dest) -#endif - -/** - * LWIP_HOOK_ND6_GET_GW(netif, dest): - * Called from nd6_get_next_hop_entry() (IPv6) - * Signature:\code{.c} - * const ip6_addr_t *my_hook(struct netif *netif, const ip6_addr_t *dest); - * \endcode - * Arguments: - * - netif: the netif used for sending - * - dest: the destination IPv6 address - * Return values: - * - the IPv6 address of the next hop to handle the specified destination IPv6 address - * - NULL, in which case a NDP-discovered router is used instead - * - * The returned address MUST be directly reachable on the specified netif! - * This function is meant to implement advanced IPv6 routing together with - * LWIP_HOOK_IP6_ROUTE(). The actual routing/gateway table implementation is - * not part of lwIP but can e.g. be hidden in the netif's state argument. -*/ -#ifdef __DOXYGEN__ -#define LWIP_HOOK_ND6_GET_GW(netif, dest) -#endif - -/** - * LWIP_HOOK_VLAN_CHECK(netif, eth_hdr, vlan_hdr): - * Called from ethernet_input() if VLAN support is enabled - * Signature:\code{.c} - * int my_hook(struct netif *netif, struct eth_hdr *eth_hdr, struct eth_vlan_hdr *vlan_hdr); - * \endcode - * Arguments: - * - netif: struct netif on which the packet has been received - * - eth_hdr: struct eth_hdr of the packet - * - vlan_hdr: struct eth_vlan_hdr of the packet - * Return values: - * - 0: Packet must be dropped. - * - != 0: Packet must be accepted. - */ -#ifdef __DOXYGEN__ -#define LWIP_HOOK_VLAN_CHECK(netif, eth_hdr, vlan_hdr) -#endif - -/** - * LWIP_HOOK_VLAN_SET: - * Hook can be used to set prio_vid field of vlan_hdr. If you need to store data - * on per-netif basis to implement this callback, see @ref netif_cd. - * Called from ethernet_output() if VLAN support (@ref ETHARP_SUPPORT_VLAN) is enabled.\n - * Signature:\code{.c} - * s32_t my_hook_vlan_set(struct netif* netif, struct pbuf* pbuf, const struct eth_addr* src, const struct eth_addr* dst, u16_t eth_type);\n - * \endcode - * Arguments: - * - netif: struct netif that the packet will be sent through - * - p: struct pbuf packet to be sent - * - src: source eth address - * - dst: destination eth address - * - eth_type: ethernet type to packet to be sent\n - * - * - * Return values: - * - <0: Packet shall not contain VLAN header. - * - 0 <= return value <= 0xFFFF: Packet shall contain VLAN header. Return value is prio_vid in host byte order. - */ -#ifdef __DOXYGEN__ -#define LWIP_HOOK_VLAN_SET(netif, p, src, dst, eth_type) -#endif - -/** - * LWIP_HOOK_MEMP_AVAILABLE(memp_t_type): - * Called from memp_free() when a memp pool was empty and an item is now available - * Signature:\code{.c} - * void my_hook(memp_t type); - * \endcode - */ -#ifdef __DOXYGEN__ -#define LWIP_HOOK_MEMP_AVAILABLE(memp_t_type) -#endif - -/** - * LWIP_HOOK_UNKNOWN_ETH_PROTOCOL(pbuf, netif): - * Called from ethernet_input() when an unknown eth type is encountered. - * Signature:\code{.c} - * err_t my_hook(struct pbuf* pbuf, struct netif* netif); - * \endcode - * Arguments: - * - p: rx packet with unknown eth type - * - netif: netif on which the packet has been received - * Return values: - * - ERR_OK if packet is accepted (hook function now owns the pbuf) - * - any error code otherwise (pbuf is freed) - * - * Payload points to ethernet header! - */ -#ifdef __DOXYGEN__ -#define LWIP_HOOK_UNKNOWN_ETH_PROTOCOL(pbuf, netif) -#endif - -/** - * LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, state, msg, msg_type, options_len_ptr): - * Called from various dhcp functions when sending a DHCP message. - * This hook is called just before the DHCP message trailer is added, so the - * options are at the end of a DHCP message. - * Signature:\code{.c} - * void my_hook(struct netif *netif, struct dhcp *dhcp, u8_t state, struct dhcp_msg *msg, - * u8_t msg_type, u16_t *options_len_ptr); - * \endcode - * Arguments: - * - netif: struct netif that the packet will be sent through - * - dhcp: struct dhcp on that netif - * - state: current dhcp state (dhcp_state_enum_t as an u8_t) - * - msg: struct dhcp_msg that will be sent - * - msg_type: dhcp message type to be sent (u8_t) - * - options_len_ptr: pointer to the current length of options in the dhcp_msg "msg" - * (must be increased when options are added!) - * - * Options need to appended like this: - * LWIP_ASSERT("dhcp option overflow", *options_len_ptr + option_len + 2 <= DHCP_OPTIONS_LEN); - * msg->options[(*options_len_ptr)++] = <option_number>; - * msg->options[(*options_len_ptr)++] = <option_len>; - * msg->options[(*options_len_ptr)++] = <option_bytes>; - * [...] - */ -#ifdef __DOXYGEN__ -#define LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, state, msg, msg_type, options_len_ptr) -#endif - -/** - * LWIP_HOOK_DHCP_PARSE_OPTION(netif, dhcp, state, msg, msg_type, option, len, pbuf, option_value_offset): - * Called from dhcp_parse_reply when receiving a DHCP message. - * This hook is called for every option in the received message that is not handled internally. - * Signature:\code{.c} - * void my_hook(struct netif *netif, struct dhcp *dhcp, u8_t state, struct dhcp_msg *msg, - * u8_t msg_type, u8_t option, u8_t option_len, struct pbuf *pbuf, u16_t option_value_offset); - * \endcode - * Arguments: - * - netif: struct netif that the packet will be sent through - * - dhcp: struct dhcp on that netif - * - state: current dhcp state (dhcp_state_enum_t as an u8_t) - * - msg: struct dhcp_msg that was received - * - msg_type: dhcp message type received (u8_t, ATTENTION: only valid after - * the message type option has been parsed!) - * - option: option value (u8_t) - * - len: option data length (u8_t) - * - pbuf: pbuf where option data is contained - * - option_value_offset: offset in pbuf where option data begins - * - * A nice way to get the option contents is pbuf_get_contiguous(): - * u8_t buf[32]; - * u8_t *ptr = (u8_t*)pbuf_get_contiguous(p, buf, sizeof(buf), LWIP_MIN(option_len, sizeof(buf)), offset); - */ -#ifdef __DOXYGEN__ -#define LWIP_HOOK_DHCP_PARSE_OPTION(netif, dhcp, state, msg, msg_type, option, len, pbuf, offset) -#endif - -/** - * LWIP_HOOK_DHCP6_APPEND_OPTIONS(netif, dhcp6, state, msg, msg_type, options_len_ptr, max_len): - * Called from various dhcp6 functions when sending a DHCP6 message. - * This hook is called just before the DHCP6 message is sent, so the - * options are at the end of a DHCP6 message. - * Signature:\code{.c} - * void my_hook(struct netif *netif, struct dhcp6 *dhcp, u8_t state, struct dhcp6_msg *msg, - * u8_t msg_type, u16_t *options_len_ptr); - * \endcode - * Arguments: - * - netif: struct netif that the packet will be sent through - * - dhcp6: struct dhcp6 on that netif - * - state: current dhcp6 state (dhcp6_state_enum_t as an u8_t) - * - msg: struct dhcp6_msg that will be sent - * - msg_type: dhcp6 message type to be sent (u8_t) - * - options_len_ptr: pointer to the current length of options in the dhcp6_msg "msg" - * (must be increased when options are added!) - * - * Options need to appended like this: - * u8_t *options = (u8_t *)(msg + 1); - * LWIP_ASSERT("dhcp option overflow", sizeof(struct dhcp6_msg) + *options_len_ptr + newoptlen <= max_len); - * options[(*options_len_ptr)++] = <option_data>; - * [...] - */ -#ifdef __DOXYGEN__ -#define LWIP_HOOK_DHCP6_APPEND_OPTIONS(netif, dhcp6, state, msg, msg_type, options_len_ptr, max_len) -#endif - -/** - * LWIP_HOOK_SOCKETS_SETSOCKOPT(s, sock, level, optname, optval, optlen, err) - * Called from socket API to implement setsockopt() for options not provided by lwIP. - * Core lock is held when this hook is called. - * Signature:\code{.c} - * int my_hook(int s, struct lwip_sock *sock, int level, int optname, const void *optval, socklen_t optlen, int *err) - * \endcode - * Arguments: - * - s: socket file descriptor - * - sock: internal socket descriptor (see lwip/priv/sockets_priv.h) - * - level: protocol level at which the option resides - * - optname: option to set - * - optval: value to set - * - optlen: size of optval - * - err: output error - * Return values: - * - 0: Hook has not consumed the option, code continues as normal (to internal options) - * - != 0: Hook has consumed the option, 'err' is returned - */ -#ifdef __DOXYGEN__ -#define LWIP_HOOK_SOCKETS_SETSOCKOPT(s, sock, level, optname, optval, optlen, err) -#endif - -/** - * LWIP_HOOK_SOCKETS_GETSOCKOPT(s, sock, level, optname, optval, optlen, err) - * Called from socket API to implement getsockopt() for options not provided by lwIP. - * Core lock is held when this hook is called. - * Signature:\code{.c} - * int my_hook(int s, struct lwip_sock *sock, int level, int optname, void *optval, socklen_t *optlen, int *err) - * \endcode - * Arguments: - * - s: socket file descriptor - * - sock: internal socket descriptor (see lwip/priv/sockets_priv.h) - * - level: protocol level at which the option resides - * - optname: option to get - * - optval: value to get - * - optlen: size of optval - * - err: output error - * Return values: - * - 0: Hook has not consumed the option, code continues as normal (to internal options) - * - != 0: Hook has consumed the option, 'err' is returned - */ -#ifdef __DOXYGEN__ -#define LWIP_HOOK_SOCKETS_GETSOCKOPT(s, sock, level, optname, optval, optlen, err) -#endif - -/** - * LWIP_HOOK_NETCONN_EXTERNAL_RESOLVE(name, addr, addrtype, err) - * Called from netconn APIs (not usable with callback apps) allowing an - * external DNS resolver (which uses sequential API) to handle the query. - * Signature:\code{.c} - * int my_hook(const char *name, ip_addr_t *addr, u8_t addrtype, err_t *err) - * \endcode - * Arguments: - * - name: hostname to resolve - * - addr: output host address - * - addrtype: type of address to query - * - err: output error - * Return values: - * - 0: Hook has not consumed hostname query, query continues into DNS module - * - != 0: Hook has consumed the query - * - * err must also be checked to determine if the hook consumed the query, but - * the query failed - */ -#ifdef __DOXYGEN__ -#define LWIP_HOOK_NETCONN_EXTERNAL_RESOLVE(name, addr, addrtype, err) -#endif -/** - * @} - */ - -/* - --------------------------------------- - ---------- Debugging options ---------- - --------------------------------------- -*/ -/** - * @defgroup lwip_opts_debugmsg Debug messages - * @ingroup lwip_opts_debug - * @{ - */ -/** - * LWIP_DBG_MIN_LEVEL: After masking, the value of the debug is - * compared against this value. If it is smaller, then debugging - * messages are written. - * @see debugging_levels - */ -#if !defined LWIP_DBG_MIN_LEVEL || defined __DOXYGEN__ -#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL -#endif - -/** - * LWIP_DBG_TYPES_ON: A mask that can be used to globally enable/disable - * debug messages of certain types. - * @see debugging_levels - */ -#if !defined LWIP_DBG_TYPES_ON || defined __DOXYGEN__ -#define LWIP_DBG_TYPES_ON LWIP_DBG_ON -#endif - -/** - * ETHARP_DEBUG: Enable debugging in etharp.c. - */ -#if !defined ETHARP_DEBUG || defined __DOXYGEN__ -#define ETHARP_DEBUG LWIP_DBG_OFF -#endif - -/** - * NETIF_DEBUG: Enable debugging in netif.c. - */ -#if !defined NETIF_DEBUG || defined __DOXYGEN__ -#define NETIF_DEBUG LWIP_DBG_OFF -#endif - -/** - * PBUF_DEBUG: Enable debugging in pbuf.c. - */ -#if !defined PBUF_DEBUG || defined __DOXYGEN__ -#define PBUF_DEBUG LWIP_DBG_OFF -#endif - -/** - * API_LIB_DEBUG: Enable debugging in api_lib.c. - */ -#if !defined API_LIB_DEBUG || defined __DOXYGEN__ -#define API_LIB_DEBUG LWIP_DBG_OFF -#endif - -/** - * API_MSG_DEBUG: Enable debugging in api_msg.c. - */ -#if !defined API_MSG_DEBUG || defined __DOXYGEN__ -#define API_MSG_DEBUG LWIP_DBG_OFF -#endif - -/** - * SOCKETS_DEBUG: Enable debugging in sockets.c. - */ -#if !defined SOCKETS_DEBUG || defined __DOXYGEN__ -#define SOCKETS_DEBUG LWIP_DBG_OFF -#endif - -/** - * ICMP_DEBUG: Enable debugging in icmp.c. - */ -#if !defined ICMP_DEBUG || defined __DOXYGEN__ -#define ICMP_DEBUG LWIP_DBG_OFF -#endif - -/** - * IGMP_DEBUG: Enable debugging in igmp.c. - */ -#if !defined IGMP_DEBUG || defined __DOXYGEN__ -#define IGMP_DEBUG LWIP_DBG_OFF -#endif - -/** - * INET_DEBUG: Enable debugging in inet.c. - */ -#if !defined INET_DEBUG || defined __DOXYGEN__ -#define INET_DEBUG LWIP_DBG_OFF -#endif - -/** - * IP_DEBUG: Enable debugging for IP. - */ -#if !defined IP_DEBUG || defined __DOXYGEN__ -#define IP_DEBUG LWIP_DBG_OFF -#endif - -/** - * IP_REASS_DEBUG: Enable debugging in ip_frag.c for both frag & reass. - */ -#if !defined IP_REASS_DEBUG || defined __DOXYGEN__ -#define IP_REASS_DEBUG LWIP_DBG_OFF -#endif - -/** - * RAW_DEBUG: Enable debugging in raw.c. - */ -#if !defined RAW_DEBUG || defined __DOXYGEN__ -#define RAW_DEBUG LWIP_DBG_OFF -#endif - -/** - * MEM_DEBUG: Enable debugging in mem.c. - */ -#if !defined MEM_DEBUG || defined __DOXYGEN__ -#define MEM_DEBUG LWIP_DBG_OFF -#endif - -/** - * MEMP_DEBUG: Enable debugging in memp.c. - */ -#if !defined MEMP_DEBUG || defined __DOXYGEN__ -#define MEMP_DEBUG LWIP_DBG_OFF -#endif - -/** - * SYS_DEBUG: Enable debugging in sys.c. - */ -#if !defined SYS_DEBUG || defined __DOXYGEN__ -#define SYS_DEBUG LWIP_DBG_OFF -#endif - -/** - * TIMERS_DEBUG: Enable debugging in timers.c. - */ -#if !defined TIMERS_DEBUG || defined __DOXYGEN__ -#define TIMERS_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_DEBUG: Enable debugging for TCP. - */ -#if !defined TCP_DEBUG || defined __DOXYGEN__ -#define TCP_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_INPUT_DEBUG: Enable debugging in tcp_in.c for incoming debug. - */ -#if !defined TCP_INPUT_DEBUG || defined __DOXYGEN__ -#define TCP_INPUT_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_FR_DEBUG: Enable debugging in tcp_in.c for fast retransmit. - */ -#if !defined TCP_FR_DEBUG || defined __DOXYGEN__ -#define TCP_FR_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_RTO_DEBUG: Enable debugging in TCP for retransmit - * timeout. - */ -#if !defined TCP_RTO_DEBUG || defined __DOXYGEN__ -#define TCP_RTO_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_CWND_DEBUG: Enable debugging for TCP congestion window. - */ -#if !defined TCP_CWND_DEBUG || defined __DOXYGEN__ -#define TCP_CWND_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_WND_DEBUG: Enable debugging in tcp_in.c for window updating. - */ -#if !defined TCP_WND_DEBUG || defined __DOXYGEN__ -#define TCP_WND_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_OUTPUT_DEBUG: Enable debugging in tcp_out.c output functions. - */ -#if !defined TCP_OUTPUT_DEBUG || defined __DOXYGEN__ -#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_RST_DEBUG: Enable debugging for TCP with the RST message. - */ -#if !defined TCP_RST_DEBUG || defined __DOXYGEN__ -#define TCP_RST_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_QLEN_DEBUG: Enable debugging for TCP queue lengths. - */ -#if !defined TCP_QLEN_DEBUG || defined __DOXYGEN__ -#define TCP_QLEN_DEBUG LWIP_DBG_OFF -#endif - -/** - * UDP_DEBUG: Enable debugging in UDP. - */ -#if !defined UDP_DEBUG || defined __DOXYGEN__ -#define UDP_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCPIP_DEBUG: Enable debugging in tcpip.c. - */ -#if !defined TCPIP_DEBUG || defined __DOXYGEN__ -#define TCPIP_DEBUG LWIP_DBG_OFF -#endif - -/** - * SLIP_DEBUG: Enable debugging in slipif.c. - */ -#if !defined SLIP_DEBUG || defined __DOXYGEN__ -#define SLIP_DEBUG LWIP_DBG_OFF -#endif - -/** - * DHCP_DEBUG: Enable debugging in dhcp.c. - */ -#if !defined DHCP_DEBUG || defined __DOXYGEN__ -#define DHCP_DEBUG LWIP_DBG_OFF -#endif - -/** - * AUTOIP_DEBUG: Enable debugging in autoip.c. - */ -#if !defined AUTOIP_DEBUG || defined __DOXYGEN__ -#define AUTOIP_DEBUG LWIP_DBG_OFF -#endif - -/** - * DNS_DEBUG: Enable debugging for DNS. - */ -#if !defined DNS_DEBUG || defined __DOXYGEN__ -#define DNS_DEBUG LWIP_DBG_OFF -#endif - -/** - * IP6_DEBUG: Enable debugging for IPv6. - */ -#if !defined IP6_DEBUG || defined __DOXYGEN__ -#define IP6_DEBUG LWIP_DBG_OFF -#endif - -/** - * DHCP6_DEBUG: Enable debugging in dhcp6.c. - */ -#if !defined DHCP6_DEBUG || defined __DOXYGEN__ -#define DHCP6_DEBUG LWIP_DBG_OFF -#endif -/** - * @} - */ - -/** - * LWIP_TESTMODE: Changes to make unit test possible - */ -#if !defined LWIP_TESTMODE -#define LWIP_TESTMODE 0 -#endif - -/* - -------------------------------------------------- - ---------- Performance tracking options ---------- - -------------------------------------------------- -*/ -/** - * @defgroup lwip_opts_perf Performance - * @ingroup lwip_opts_debug - * @{ - */ -/** - * LWIP_PERF: Enable performance testing for lwIP - * (if enabled, arch/perf.h is included) - */ -#if !defined LWIP_PERF || defined __DOXYGEN__ -#define LWIP_PERF 0 -#endif -/** - * @} - */ - -#endif /* LWIP_HDR_OPT_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/pbuf.h b/third-party/lwip-2.1.2/include/lwip/pbuf.h deleted file mode 100644 index 4858e5b1..00000000 --- a/third-party/lwip-2.1.2/include/lwip/pbuf.h +++ /dev/null @@ -1,322 +0,0 @@ -/** - * @file - * pbuf API - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#ifndef LWIP_HDR_PBUF_H -#define LWIP_HDR_PBUF_H - -#include "lwip/opt.h" -#include "lwip/err.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** LWIP_SUPPORT_CUSTOM_PBUF==1: Custom pbufs behave much like their pbuf type - * but they are allocated by external code (initialised by calling - * pbuf_alloced_custom()) and when pbuf_free gives up their last reference, they - * are freed by calling pbuf_custom->custom_free_function(). - * Currently, the pbuf_custom code is only needed for one specific configuration - * of IP_FRAG, unless required by external driver/application code. */ -#ifndef LWIP_SUPPORT_CUSTOM_PBUF -#define LWIP_SUPPORT_CUSTOM_PBUF ((IP_FRAG && !LWIP_NETIF_TX_SINGLE_PBUF) || (LWIP_IPV6 && LWIP_IPV6_FRAG)) -#endif - -/** @ingroup pbuf - * PBUF_NEEDS_COPY(p): return a boolean value indicating whether the given - * pbuf needs to be copied in order to be kept around beyond the current call - * stack without risking being corrupted. The default setting provides safety: - * it will make a copy iof any pbuf chain that does not consist entirely of - * PBUF_ROM type pbufs. For setups with zero-copy support, it may be redefined - * to evaluate to true in all cases, for example. However, doing so also has an - * effect on the application side: any buffers that are *not* copied must also - * *not* be reused by the application after passing them to lwIP. For example, - * when setting PBUF_NEEDS_COPY to (0), after using udp_send() with a PBUF_RAM - * pbuf, the application must free the pbuf immediately, rather than reusing it - * for other purposes. For more background information on this, see tasks #6735 - * and #7896, and bugs #11400 and #49914. */ -#ifndef PBUF_NEEDS_COPY -#define PBUF_NEEDS_COPY(p) ((p)->type_internal & PBUF_TYPE_FLAG_DATA_VOLATILE) -#endif /* PBUF_NEEDS_COPY */ - -/* @todo: We need a mechanism to prevent wasting memory in every pbuf - (TCP vs. UDP, IPv4 vs. IPv6: UDP/IPv4 packets may waste up to 28 bytes) */ - -#define PBUF_TRANSPORT_HLEN 20 -#if LWIP_IPV6 -#define PBUF_IP_HLEN 40 -#else -#define PBUF_IP_HLEN 20 -#endif - -/** - * @ingroup pbuf - * Enumeration of pbuf layers - */ -typedef enum { - /** Includes spare room for transport layer header, e.g. UDP header. - * Use this if you intend to pass the pbuf to functions like udp_send(). - */ - PBUF_TRANSPORT = PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN, - /** Includes spare room for IP header. - * Use this if you intend to pass the pbuf to functions like raw_send(). - */ - PBUF_IP = PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN, - /** Includes spare room for link layer header (ethernet header). - * Use this if you intend to pass the pbuf to functions like ethernet_output(). - * @see PBUF_LINK_HLEN - */ - PBUF_LINK = PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN, - /** Includes spare room for additional encapsulation header before ethernet - * headers (e.g. 802.11). - * Use this if you intend to pass the pbuf to functions like netif->linkoutput(). - * @see PBUF_LINK_ENCAPSULATION_HLEN - */ - PBUF_RAW_TX = PBUF_LINK_ENCAPSULATION_HLEN, - /** Use this for input packets in a netif driver when calling netif->input() - * in the most common case - ethernet-layer netif driver. */ - PBUF_RAW = 0 -} pbuf_layer; - - -/* Base flags for pbuf_type definitions: */ - -/** Indicates that the payload directly follows the struct pbuf. - * This makes @ref pbuf_header work in both directions. */ -#define PBUF_TYPE_FLAG_STRUCT_DATA_CONTIGUOUS 0x80 -/** Indicates the data stored in this pbuf can change. If this pbuf needs - * to be queued, it must be copied/duplicated. */ -#define PBUF_TYPE_FLAG_DATA_VOLATILE 0x40 -/** 4 bits are reserved for 16 allocation sources (e.g. heap, pool1, pool2, etc) - * Internally, we use: 0=heap, 1=MEMP_PBUF, 2=MEMP_PBUF_POOL -> 13 types free*/ -#define PBUF_TYPE_ALLOC_SRC_MASK 0x0F -/** Indicates this pbuf is used for RX (if not set, indicates use for TX). - * This information can be used to keep some spare RX buffers e.g. for - * receiving TCP ACKs to unblock a connection) */ -#define PBUF_ALLOC_FLAG_RX 0x0100 -/** Indicates the application needs the pbuf payload to be in one piece */ -#define PBUF_ALLOC_FLAG_DATA_CONTIGUOUS 0x0200 - -#define PBUF_TYPE_ALLOC_SRC_MASK_STD_HEAP 0x00 -#define PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF 0x01 -#define PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF_POOL 0x02 -/** First pbuf allocation type for applications */ -#define PBUF_TYPE_ALLOC_SRC_MASK_APP_MIN 0x03 -/** Last pbuf allocation type for applications */ -#define PBUF_TYPE_ALLOC_SRC_MASK_APP_MAX PBUF_TYPE_ALLOC_SRC_MASK - -/** - * @ingroup pbuf - * Enumeration of pbuf types ,pbuf的类型 - */ -typedef enum { - /** pbuf data is stored in RAM, used for TX mostly, struct pbuf and its payload - are allocated in one piece of contiguous memory (so the first payload byte - can be calculated from struct pbuf). - pbuf_alloc() allocates PBUF_RAM pbufs as unchained pbufs (although that might - change in future versions). - This should be used for all OUTGOING packets (TX).*/ - PBUF_RAM = (PBUF_ALLOC_FLAG_DATA_CONTIGUOUS | PBUF_TYPE_FLAG_STRUCT_DATA_CONTIGUOUS | PBUF_TYPE_ALLOC_SRC_MASK_STD_HEAP), - /** pbuf data is stored in ROM, i.e. struct pbuf and its payload are located in - totally different memory areas. Since it points to ROM, payload does not - have to be copied when queued for transmission. */ - PBUF_ROM = PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF, - /** pbuf comes from the pbuf pool. Much like PBUF_ROM but payload might change - so it has to be duplicated when queued before transmitting, depending on - who has a 'ref' to it. */ - PBUF_REF = (PBUF_TYPE_FLAG_DATA_VOLATILE | PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF), - /** pbuf payload refers to RAM. This one comes from a pool and should be used - for RX. Payload can be chained (scatter-gather RX) but like PBUF_RAM, struct - pbuf and its payload are allocated in one piece of contiguous memory (so - the first payload byte can be calculated from struct pbuf). - Don't use this for TX, if the pool becomes empty e.g. because of TCP queuing, - you are unable to receive TCP acks! */ - PBUF_POOL = (PBUF_ALLOC_FLAG_RX | PBUF_TYPE_FLAG_STRUCT_DATA_CONTIGUOUS | PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF_POOL) -} pbuf_type; - - -/** indicates this packet's data should be immediately passed to the application */ -#define PBUF_FLAG_PUSH 0x01U -/** indicates this is a custom pbuf: pbuf_free calls pbuf_custom->custom_free_function() - when the last reference is released (plus custom PBUF_RAM cannot be trimmed) */ -#define PBUF_FLAG_IS_CUSTOM 0x02U -/** indicates this pbuf is UDP multicast to be looped back */ -#define PBUF_FLAG_MCASTLOOP 0x04U -/** indicates this pbuf was received as link-level broadcast */ -#define PBUF_FLAG_LLBCAST 0x08U -/** indicates this pbuf was received as link-level multicast */ -#define PBUF_FLAG_LLMCAST 0x10U -/** indicates this pbuf includes a TCP FIN flag */ -#define PBUF_FLAG_TCP_FIN 0x20U - -/** Main packet buffer struct */ -struct pbuf { - /** next pbuf in singly linked pbuf chain */ - struct pbuf *next; //指向下一个数据包 - - /** pointer to the actual data in the buffer */ - void *payload; //指向数据区域的指针,指向该pbuf管理的数据区域起始地址,可以是ROM或者RAM中的某个地址 - - /** - * total length of this buffer and all next buffers in chain - * belonging to the same packet. - * - * For non-queue packet chains this is the invariant: - * p->tot_len == p->len + (p->next? p->next->tot_len: 0) - */ - u16_t tot_len;//记录当前pbuf及其后续pbuf所有数据的长度 - - /** length of this buffer */ - u16_t len;//当前pbuf中有效的数据长度 - - /** a bit field indicating pbuf type and allocation sources - (see PBUF_TYPE_FLAG_*, PBUF_ALLOC_FLAG_* and PBUF_TYPE_ALLOC_SRC_MASK) - */ - u8_t type_internal;//pbuf的类型 - - /** misc flags */ - u8_t flags; - - /** - * the reference count always equals the number of pointers - * that refer to this pbuf. This can be pointers from an application, - * the stack itself, or pbuf->next pointers from a chain. - */ - LWIP_PBUF_REF_T ref; - - /** For incoming packets, this contains the input netif's index */ - u8_t if_idx;//该pbuf被引用的次数, 引用表示有其他指针指向当前pbuf -}; - - -/** Helper struct for const-correctness only. - * The only meaning of this one is to provide a const payload pointer - * for PBUF_ROM type. - */ -struct pbuf_rom { - /** next pbuf in singly linked pbuf chain */ - struct pbuf *next; - - /** pointer to the actual data in the buffer */ - const void *payload; -}; - -#if LWIP_SUPPORT_CUSTOM_PBUF -/** Prototype for a function to free a custom pbuf */ -typedef void (*pbuf_free_custom_fn)(struct pbuf *p); - -/** A custom pbuf: like a pbuf, but following a function pointer to free it. */ -struct pbuf_custom { - /** The actual pbuf */ - struct pbuf pbuf; - /** This function is called when pbuf_free deallocates this pbuf(_custom) */ - pbuf_free_custom_fn custom_free_function; -}; -#endif /* LWIP_SUPPORT_CUSTOM_PBUF */ - -/** Define this to 0 to prevent freeing ooseq pbufs when the PBUF_POOL is empty */ -#ifndef PBUF_POOL_FREE_OOSEQ -#define PBUF_POOL_FREE_OOSEQ 1 -#endif /* PBUF_POOL_FREE_OOSEQ */ -#if LWIP_TCP && TCP_QUEUE_OOSEQ && NO_SYS && PBUF_POOL_FREE_OOSEQ -extern volatile u8_t pbuf_free_ooseq_pending; -void pbuf_free_ooseq(void); -/** When not using sys_check_timeouts(), call PBUF_CHECK_FREE_OOSEQ() - at regular intervals from main level to check if ooseq pbufs need to be - freed! */ -#define PBUF_CHECK_FREE_OOSEQ() do { if(pbuf_free_ooseq_pending) { \ - /* pbuf_alloc() reported PBUF_POOL to be empty -> try to free some \ - ooseq queued pbufs now */ \ - pbuf_free_ooseq(); }}while(0) -#else /* LWIP_TCP && TCP_QUEUE_OOSEQ && NO_SYS && PBUF_POOL_FREE_OOSEQ */ - /* Otherwise declare an empty PBUF_CHECK_FREE_OOSEQ */ - #define PBUF_CHECK_FREE_OOSEQ() -#endif /* LWIP_TCP && TCP_QUEUE_OOSEQ && NO_SYS && PBUF_POOL_FREE_OOSEQ*/ - -/* Initializes the pbuf module. This call is empty for now, but may not be in future. */ -#define pbuf_init() - -struct pbuf *pbuf_alloc(pbuf_layer l, u16_t length, pbuf_type type); -struct pbuf *pbuf_alloc_reference(void *payload, u16_t length, pbuf_type type); -#if LWIP_SUPPORT_CUSTOM_PBUF -struct pbuf *pbuf_alloced_custom(pbuf_layer l, u16_t length, pbuf_type type, - struct pbuf_custom *p, void *payload_mem, - u16_t payload_mem_len); -#endif /* LWIP_SUPPORT_CUSTOM_PBUF */ -void pbuf_realloc(struct pbuf *p, u16_t size); -#define pbuf_get_allocsrc(p) ((p)->type_internal & PBUF_TYPE_ALLOC_SRC_MASK) -#define pbuf_match_allocsrc(p, type) (pbuf_get_allocsrc(p) == ((type) & PBUF_TYPE_ALLOC_SRC_MASK)) -#define pbuf_match_type(p, type) pbuf_match_allocsrc(p, type) -u8_t pbuf_header(struct pbuf *p, s16_t header_size); -u8_t pbuf_header_force(struct pbuf *p, s16_t header_size); -u8_t pbuf_add_header(struct pbuf *p, size_t header_size_increment); -u8_t pbuf_add_header_force(struct pbuf *p, size_t header_size_increment); -u8_t pbuf_remove_header(struct pbuf *p, size_t header_size); -struct pbuf *pbuf_free_header(struct pbuf *q, u16_t size); -void pbuf_ref(struct pbuf *p); -u8_t pbuf_free(struct pbuf *p); -u16_t pbuf_clen(const struct pbuf *p); -void pbuf_cat(struct pbuf *head, struct pbuf *tail); -void pbuf_chain(struct pbuf *head, struct pbuf *tail); -struct pbuf *pbuf_dechain(struct pbuf *p); -err_t pbuf_copy(struct pbuf *p_to, const struct pbuf *p_from); -u16_t pbuf_copy_partial(const struct pbuf *p, void *dataptr, u16_t len, u16_t offset); -void *pbuf_get_contiguous(const struct pbuf *p, void *buffer, size_t bufsize, u16_t len, u16_t offset); -err_t pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len); -err_t pbuf_take_at(struct pbuf *buf, const void *dataptr, u16_t len, u16_t offset); -struct pbuf *pbuf_skip(struct pbuf* in, u16_t in_offset, u16_t* out_offset); -struct pbuf *pbuf_coalesce(struct pbuf *p, pbuf_layer layer); -struct pbuf *pbuf_clone(pbuf_layer l, pbuf_type type, struct pbuf *p); -#if LWIP_CHECKSUM_ON_COPY -err_t pbuf_fill_chksum(struct pbuf *p, u16_t start_offset, const void *dataptr, - u16_t len, u16_t *chksum); -#endif /* LWIP_CHECKSUM_ON_COPY */ -#if LWIP_TCP && TCP_QUEUE_OOSEQ && LWIP_WND_SCALE -void pbuf_split_64k(struct pbuf *p, struct pbuf **rest); -#endif /* LWIP_TCP && TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ - -u8_t pbuf_get_at(const struct pbuf* p, u16_t offset); -int pbuf_try_get_at(const struct pbuf* p, u16_t offset); -void pbuf_put_at(struct pbuf* p, u16_t offset, u8_t data); -u16_t pbuf_memcmp(const struct pbuf* p, u16_t offset, const void* s2, u16_t n); -u16_t pbuf_memfind(const struct pbuf* p, const void* mem, u16_t mem_len, u16_t start_offset); -u16_t pbuf_strstr(const struct pbuf* p, const char* substr); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_PBUF_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/priv/altcp_priv.h b/third-party/lwip-2.1.2/include/lwip/priv/altcp_priv.h deleted file mode 100644 index 2d3b2fdb..00000000 --- a/third-party/lwip-2.1.2/include/lwip/priv/altcp_priv.h +++ /dev/null @@ -1,146 +0,0 @@ -/** - * @file - * Application layered TCP connection API (to be used from TCPIP thread)\n - * This interface mimics the tcp callback API to the application while preventing - * direct linking (much like virtual functions). - * This way, an application can make use of other application layer protocols - * on top of TCP without knowing the details (e.g. TLS, proxy connection). - */ - -/* - * Copyright (c) 2017 Simon Goldschmidt - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Simon Goldschmidt - * - */ -#ifndef LWIP_HDR_ALTCP_PRIV_H -#define LWIP_HDR_ALTCP_PRIV_H - -#include "lwip/opt.h" - -#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/altcp.h" -#include "lwip/ip_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct altcp_pcb *altcp_alloc(void); -void altcp_free(struct altcp_pcb *conn); - -/* Function prototypes for application layers */ -typedef void (*altcp_set_poll_fn)(struct altcp_pcb *conn, u8_t interval); -typedef void (*altcp_recved_fn)(struct altcp_pcb *conn, u16_t len); -typedef err_t (*altcp_bind_fn)(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port); -typedef err_t (*altcp_connect_fn)(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port, altcp_connected_fn connected); - -typedef struct altcp_pcb *(*altcp_listen_fn)(struct altcp_pcb *conn, u8_t backlog, err_t *err); - -typedef void (*altcp_abort_fn)(struct altcp_pcb *conn); -typedef err_t (*altcp_close_fn)(struct altcp_pcb *conn); -typedef err_t (*altcp_shutdown_fn)(struct altcp_pcb *conn, int shut_rx, int shut_tx); - -typedef err_t (*altcp_write_fn)(struct altcp_pcb *conn, const void *dataptr, u16_t len, u8_t apiflags); -typedef err_t (*altcp_output_fn)(struct altcp_pcb *conn); - -typedef u16_t (*altcp_mss_fn)(struct altcp_pcb *conn); -typedef u16_t (*altcp_sndbuf_fn)(struct altcp_pcb *conn); -typedef u16_t (*altcp_sndqueuelen_fn)(struct altcp_pcb *conn); -typedef void (*altcp_nagle_disable_fn)(struct altcp_pcb *conn); -typedef void (*altcp_nagle_enable_fn)(struct altcp_pcb *conn); -typedef int (*altcp_nagle_disabled_fn)(struct altcp_pcb *conn); - -typedef void (*altcp_setprio_fn)(struct altcp_pcb *conn, u8_t prio); - -typedef void (*altcp_dealloc_fn)(struct altcp_pcb *conn); - -typedef err_t (*altcp_get_tcp_addrinfo_fn)(struct altcp_pcb *conn, int local, ip_addr_t *addr, u16_t *port); -typedef ip_addr_t *(*altcp_get_ip_fn)(struct altcp_pcb *conn, int local); -typedef u16_t (*altcp_get_port_fn)(struct altcp_pcb *conn, int local); - -#ifdef LWIP_DEBUG -typedef enum tcp_state (*altcp_dbg_get_tcp_state_fn)(struct altcp_pcb *conn); -#endif - -struct altcp_functions { - altcp_set_poll_fn set_poll; - altcp_recved_fn recved; - altcp_bind_fn bind; - altcp_connect_fn connect; - altcp_listen_fn listen; - altcp_abort_fn abort; - altcp_close_fn close; - altcp_shutdown_fn shutdown; - altcp_write_fn write; - altcp_output_fn output; - altcp_mss_fn mss; - altcp_sndbuf_fn sndbuf; - altcp_sndqueuelen_fn sndqueuelen; - altcp_nagle_disable_fn nagle_disable; - altcp_nagle_enable_fn nagle_enable; - altcp_nagle_disabled_fn nagle_disabled; - altcp_setprio_fn setprio; - altcp_dealloc_fn dealloc; - altcp_get_tcp_addrinfo_fn addrinfo; - altcp_get_ip_fn getip; - altcp_get_port_fn getport; -#ifdef LWIP_DEBUG - altcp_dbg_get_tcp_state_fn dbg_get_tcp_state; -#endif -}; - -void altcp_default_set_poll(struct altcp_pcb *conn, u8_t interval); -void altcp_default_recved(struct altcp_pcb *conn, u16_t len); -err_t altcp_default_bind(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port); -err_t altcp_default_shutdown(struct altcp_pcb *conn, int shut_rx, int shut_tx); -err_t altcp_default_write(struct altcp_pcb *conn, const void *dataptr, u16_t len, u8_t apiflags); -err_t altcp_default_output(struct altcp_pcb *conn); -u16_t altcp_default_mss(struct altcp_pcb *conn); -u16_t altcp_default_sndbuf(struct altcp_pcb *conn); -u16_t altcp_default_sndqueuelen(struct altcp_pcb *conn); -void altcp_default_nagle_disable(struct altcp_pcb *conn); -void altcp_default_nagle_enable(struct altcp_pcb *conn); -int altcp_default_nagle_disabled(struct altcp_pcb *conn); -void altcp_default_setprio(struct altcp_pcb *conn, u8_t prio); -void altcp_default_dealloc(struct altcp_pcb *conn); -err_t altcp_default_get_tcp_addrinfo(struct altcp_pcb *conn, int local, ip_addr_t *addr, u16_t *port); -ip_addr_t *altcp_default_get_ip(struct altcp_pcb *conn, int local); -u16_t altcp_default_get_port(struct altcp_pcb *conn, int local); -#ifdef LWIP_DEBUG -enum tcp_state altcp_default_dbg_get_tcp_state(struct altcp_pcb *conn); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_ALTCP */ - -#endif /* LWIP_HDR_ALTCP_PRIV_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/priv/api_msg.h b/third-party/lwip-2.1.2/include/lwip/priv/api_msg.h deleted file mode 100644 index 9e8ffc9e..00000000 --- a/third-party/lwip-2.1.2/include/lwip/priv/api_msg.h +++ /dev/null @@ -1,272 +0,0 @@ -/** - * @file - * netconn API lwIP internal implementations (do not use in application code) - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_API_MSG_H -#define LWIP_HDR_API_MSG_H - -#include "lwip/opt.h" - -#include "lwip/arch.h" -#include "lwip/ip_addr.h" -#include "lwip/err.h" -#include "lwip/sys.h" -#include "lwip/igmp.h" -#include "lwip/api.h" -#include "lwip/priv/tcpip_priv.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if LWIP_NETCONN || LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ -/* Note: Netconn API is always available when sockets are enabled - - * sockets are implemented on top of them */ - -#if LWIP_MPU_COMPATIBLE -#if LWIP_NETCONN_SEM_PER_THREAD -#define API_MSG_M_DEF_SEM(m) *m -#else -#define API_MSG_M_DEF_SEM(m) API_MSG_M_DEF(m) -#endif -#else /* LWIP_MPU_COMPATIBLE */ -#define API_MSG_M_DEF_SEM(m) API_MSG_M_DEF(m) -#endif /* LWIP_MPU_COMPATIBLE */ - -/* For the netconn API, these values are use as a bitmask! */ -#define NETCONN_SHUT_RD 1 -#define NETCONN_SHUT_WR 2 -#define NETCONN_SHUT_RDWR (NETCONN_SHUT_RD | NETCONN_SHUT_WR) - -/* IP addresses and port numbers are expected to be in - * the same byte order as in the corresponding pcb. - */ -/** This struct includes everything that is necessary to execute a function - for a netconn in another thread context (mainly used to process netconns - in the tcpip_thread context to be thread safe). */ -struct api_msg { - /** The netconn which to process - always needed: it includes the semaphore - which is used to block the application thread until the function finished. */ - struct netconn *conn; - /** The return value of the function executed in tcpip_thread. */ - err_t err; - /** Depending on the executed function, one of these union members is used */ - union { - /** used for lwip_netconn_do_send */ - struct netbuf *b; - /** used for lwip_netconn_do_newconn */ - struct { - u8_t proto; - } n; - /** used for lwip_netconn_do_bind and lwip_netconn_do_connect */ - struct { - API_MSG_M_DEF_C(ip_addr_t, ipaddr); - u16_t port; - u8_t if_idx; - } bc; - /** used for lwip_netconn_do_getaddr */ - struct { - ip_addr_t API_MSG_M_DEF(ipaddr); - u16_t API_MSG_M_DEF(port); - u8_t local; - } ad; - /** used for lwip_netconn_do_write */ - struct { - /** current vector to write */ - const struct netvector *vector; - /** number of unwritten vectors */ - u16_t vector_cnt; - /** offset into current vector */ - size_t vector_off; - /** total length across vectors */ - size_t len; - /** offset into total length/output of bytes written when err == ERR_OK */ - size_t offset; - u8_t apiflags; -#if LWIP_SO_SNDTIMEO - u32_t time_started; -#endif /* LWIP_SO_SNDTIMEO */ - } w; - /** used for lwip_netconn_do_recv */ - struct { - size_t len; - } r; -#if LWIP_TCP - /** used for lwip_netconn_do_close (/shutdown) */ - struct { - u8_t shut; -#if LWIP_SO_SNDTIMEO || LWIP_SO_LINGER - u32_t time_started; -#else /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */ - u8_t polls_left; -#endif /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */ - } sd; -#endif /* LWIP_TCP */ -#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) - /** used for lwip_netconn_do_join_leave_group */ - struct { - API_MSG_M_DEF_C(ip_addr_t, multiaddr); - API_MSG_M_DEF_C(ip_addr_t, netif_addr); - u8_t if_idx; - enum netconn_igmp join_or_leave; - } jl; -#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ -#if TCP_LISTEN_BACKLOG - struct { - u8_t backlog; - } lb; -#endif /* TCP_LISTEN_BACKLOG */ - } msg; -#if LWIP_NETCONN_SEM_PER_THREAD - sys_sem_t* op_completed_sem; -#endif /* LWIP_NETCONN_SEM_PER_THREAD */ -}; - -#if LWIP_NETCONN_SEM_PER_THREAD -#define LWIP_API_MSG_SEM(msg) ((msg)->op_completed_sem) -#else /* LWIP_NETCONN_SEM_PER_THREAD */ -#define LWIP_API_MSG_SEM(msg) (&(msg)->conn->op_completed) -#endif /* LWIP_NETCONN_SEM_PER_THREAD */ - - -#if LWIP_DNS -/** As lwip_netconn_do_gethostbyname requires more arguments but doesn't require a netconn, - it has its own struct (to avoid struct api_msg getting bigger than necessary). - lwip_netconn_do_gethostbyname must be called using tcpip_callback instead of tcpip_apimsg - (see netconn_gethostbyname). */ -struct dns_api_msg { - /** Hostname to query or dotted IP address string */ -#if LWIP_MPU_COMPATIBLE - char name[DNS_MAX_NAME_LENGTH]; -#else /* LWIP_MPU_COMPATIBLE */ - const char *name; -#endif /* LWIP_MPU_COMPATIBLE */ - /** The resolved address is stored here */ - ip_addr_t API_MSG_M_DEF(addr); -#if LWIP_IPV4 && LWIP_IPV6 - /** Type of resolve call */ - u8_t dns_addrtype; -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - /** This semaphore is posted when the name is resolved, the application thread - should wait on it. */ - sys_sem_t API_MSG_M_DEF_SEM(sem); - /** Errors are given back here */ - err_t API_MSG_M_DEF(err); -}; -#endif /* LWIP_DNS */ - -#if LWIP_NETCONN_FULLDUPLEX -int lwip_netconn_is_deallocated_msg(void *msg); -#endif -int lwip_netconn_is_err_msg(void *msg, err_t *err); -void lwip_netconn_do_newconn (void *m); -void lwip_netconn_do_delconn (void *m); -void lwip_netconn_do_bind (void *m); -void lwip_netconn_do_bind_if (void *m); -void lwip_netconn_do_connect (void *m); -void lwip_netconn_do_disconnect (void *m); -void lwip_netconn_do_listen (void *m); -void lwip_netconn_do_send (void *m); -void lwip_netconn_do_recv (void *m); -#if TCP_LISTEN_BACKLOG -void lwip_netconn_do_accepted (void *m); -#endif /* TCP_LISTEN_BACKLOG */ -void lwip_netconn_do_write (void *m); -void lwip_netconn_do_getaddr (void *m); -void lwip_netconn_do_close (void *m); -void lwip_netconn_do_shutdown (void *m); -#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) -void lwip_netconn_do_join_leave_group(void *m); -void lwip_netconn_do_join_leave_group_netif(void *m); -#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ - -#if LWIP_DNS -void lwip_netconn_do_gethostbyname(void *arg); -#endif /* LWIP_DNS */ - -struct netconn* netconn_alloc(enum netconn_type t, netconn_callback callback); -void netconn_free(struct netconn *conn); - -#endif /* LWIP_NETCONN || LWIP_SOCKET */ - -#if LWIP_NETIF_API /* don't build if not configured for use in lwipopts.h */ - -/* netifapi related lwIP internal definitions */ - -#if LWIP_MPU_COMPATIBLE -#define NETIFAPI_IPADDR_DEF(type, m) type m -#else /* LWIP_MPU_COMPATIBLE */ -#define NETIFAPI_IPADDR_DEF(type, m) const type * m -#endif /* LWIP_MPU_COMPATIBLE */ - -typedef void (*netifapi_void_fn)(struct netif *netif); -typedef err_t (*netifapi_errt_fn)(struct netif *netif); - -struct netifapi_msg { - struct tcpip_api_call_data call; - struct netif *netif; - union { - struct { -#if LWIP_IPV4 - NETIFAPI_IPADDR_DEF(ip4_addr_t, ipaddr); - NETIFAPI_IPADDR_DEF(ip4_addr_t, netmask); - NETIFAPI_IPADDR_DEF(ip4_addr_t, gw); -#endif /* LWIP_IPV4 */ - void *state; - netif_init_fn init; - netif_input_fn input; - } add; - struct { - netifapi_void_fn voidfunc; - netifapi_errt_fn errtfunc; - } common; - struct { -#if LWIP_MPU_COMPATIBLE - char name[NETIF_NAMESIZE]; -#else /* LWIP_MPU_COMPATIBLE */ - char *name; -#endif /* LWIP_MPU_COMPATIBLE */ - u8_t index; - } ifs; - } msg; -}; - -#endif /* LWIP_NETIF_API */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_API_MSG_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/priv/mem_priv.h b/third-party/lwip-2.1.2/include/lwip/priv/mem_priv.h deleted file mode 100644 index 8630d754..00000000 --- a/third-party/lwip-2.1.2/include/lwip/priv/mem_priv.h +++ /dev/null @@ -1,84 +0,0 @@ -/** - * @file - * lwIP internal memory implementations (do not use in application code) - */ - -/* - * Copyright (c) 2018 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Simon Goldschmidt - * - */ - -#ifndef LWIP_HDR_MEM_PRIV_H -#define LWIP_HDR_MEM_PRIV_H - -#include "lwip/opt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#include "lwip/mem.h" - -#if MEM_OVERFLOW_CHECK || MEMP_OVERFLOW_CHECK -/* if MEM_OVERFLOW_CHECK or MEMP_OVERFLOW_CHECK is turned on, we reserve some - * bytes at the beginning and at the end of each element, initialize them as - * 0xcd and check them later. - * If MEM(P)_OVERFLOW_CHECK is >= 2, on every call to mem(p)_malloc or mem(p)_free, - * every single element in each pool/heap is checked! - * This is VERY SLOW but also very helpful. - * MEM_SANITY_REGION_BEFORE and MEM_SANITY_REGION_AFTER can be overridden in - * lwipopts.h to change the amount reserved for checking. */ -#ifndef MEM_SANITY_REGION_BEFORE -#define MEM_SANITY_REGION_BEFORE 16 -#endif /* MEM_SANITY_REGION_BEFORE*/ -#if MEM_SANITY_REGION_BEFORE > 0 -#define MEM_SANITY_REGION_BEFORE_ALIGNED LWIP_MEM_ALIGN_SIZE(MEM_SANITY_REGION_BEFORE) -#else -#define MEM_SANITY_REGION_BEFORE_ALIGNED 0 -#endif /* MEM_SANITY_REGION_BEFORE*/ -#ifndef MEM_SANITY_REGION_AFTER -#define MEM_SANITY_REGION_AFTER 16 -#endif /* MEM_SANITY_REGION_AFTER*/ -#if MEM_SANITY_REGION_AFTER > 0 -#define MEM_SANITY_REGION_AFTER_ALIGNED LWIP_MEM_ALIGN_SIZE(MEM_SANITY_REGION_AFTER) -#else -#define MEM_SANITY_REGION_AFTER_ALIGNED 0 -#endif /* MEM_SANITY_REGION_AFTER*/ - -void mem_overflow_init_raw(void *p, size_t size); -void mem_overflow_check_raw(void *p, size_t size, const char *descr1, const char *descr2); - -#endif /* MEM_OVERFLOW_CHECK || MEMP_OVERFLOW_CHECK */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_MEMP_PRIV_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/priv/memp_priv.h b/third-party/lwip-2.1.2/include/lwip/priv/memp_priv.h deleted file mode 100644 index 1f14cb16..00000000 --- a/third-party/lwip-2.1.2/include/lwip/priv/memp_priv.h +++ /dev/null @@ -1,161 +0,0 @@ -/** - * @file - * memory pools lwIP internal implementations (do not use in application code) - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#ifndef LWIP_HDR_MEMP_PRIV_H -#define LWIP_HDR_MEMP_PRIV_H - -#include "lwip/opt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#include "lwip/mem.h" -#include "lwip/priv/mem_priv.h" - -#if MEMP_OVERFLOW_CHECK - - -/* MEMP_SIZE: save space for struct memp and for sanity check */ -#define MEMP_SIZE (LWIP_MEM_ALIGN_SIZE(sizeof(struct memp)) + MEM_SANITY_REGION_BEFORE_ALIGNED) -#define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x) + MEM_SANITY_REGION_AFTER_ALIGNED) - -#else /* MEMP_OVERFLOW_CHECK */ - -/* No sanity checks - * We don't need to preserve the struct memp while not allocated, so we - * can save a little space and set MEMP_SIZE to 0. - */ -#define MEMP_SIZE 0 -#define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x)) - -#endif /* MEMP_OVERFLOW_CHECK */ - -#if !MEMP_MEM_MALLOC || MEMP_OVERFLOW_CHECK -struct memp { - struct memp *next; -#if MEMP_OVERFLOW_CHECK - const char *file; - int line; -#endif /* MEMP_OVERFLOW_CHECK */ -}; -#endif /* !MEMP_MEM_MALLOC || MEMP_OVERFLOW_CHECK */ - -#if MEM_USE_POOLS && MEMP_USE_CUSTOM_POOLS -/* Use a helper type to get the start and end of the user "memory pools" for mem_malloc */ -typedef enum { - /* Get the first (via: - MEMP_POOL_HELPER_START = ((u8_t) 1*MEMP_POOL_A + 0*MEMP_POOL_B + 0*MEMP_POOL_C + 0)*/ - MEMP_POOL_HELPER_FIRST = ((u8_t) -#define LWIP_MEMPOOL(name,num,size,desc) -#define LWIP_MALLOC_MEMPOOL_START 1 -#define LWIP_MALLOC_MEMPOOL(num, size) * MEMP_POOL_##size + 0 -#define LWIP_MALLOC_MEMPOOL_END -#include "lwip/priv/memp_std.h" - ) , - /* Get the last (via: - MEMP_POOL_HELPER_END = ((u8_t) 0 + MEMP_POOL_A*0 + MEMP_POOL_B*0 + MEMP_POOL_C*1) */ - MEMP_POOL_HELPER_LAST = ((u8_t) -#define LWIP_MEMPOOL(name,num,size,desc) -#define LWIP_MALLOC_MEMPOOL_START -#define LWIP_MALLOC_MEMPOOL(num, size) 0 + MEMP_POOL_##size * -#define LWIP_MALLOC_MEMPOOL_END 1 -#include "lwip/priv/memp_std.h" - ) -} memp_pool_helper_t; - -/* The actual start and stop values are here (cast them over) - We use this helper type and these defines so we can avoid using const memp_t values */ -#define MEMP_POOL_FIRST ((memp_t) MEMP_POOL_HELPER_FIRST) -#define MEMP_POOL_LAST ((memp_t) MEMP_POOL_HELPER_LAST) -#endif /* MEM_USE_POOLS && MEMP_USE_CUSTOM_POOLS */ - -/** Memory pool descriptor */ -struct memp_desc { -#if defined(LWIP_DEBUG) || MEMP_OVERFLOW_CHECK || LWIP_STATS_DISPLAY - /** Textual description */ - const char *desc; -#endif /* LWIP_DEBUG || MEMP_OVERFLOW_CHECK || LWIP_STATS_DISPLAY */ -#if MEMP_STATS - /** Statistics */ - struct stats_mem *stats; -#endif - - /** Element size */ - u16_t size; - -#if !MEMP_MEM_MALLOC - /** Number of elements */ - u16_t num; - - /** Base address */ - u8_t *base; - - /** First free element of each pool. Elements form a linked list. */ - struct memp **tab; -#endif /* MEMP_MEM_MALLOC */ -}; - -#if defined(LWIP_DEBUG) || MEMP_OVERFLOW_CHECK || LWIP_STATS_DISPLAY -#define DECLARE_LWIP_MEMPOOL_DESC(desc) (desc), -#else -#define DECLARE_LWIP_MEMPOOL_DESC(desc) -#endif - -#if MEMP_STATS -#define LWIP_MEMPOOL_DECLARE_STATS_INSTANCE(name) static struct stats_mem name; -#define LWIP_MEMPOOL_DECLARE_STATS_REFERENCE(name) &name, -#else -#define LWIP_MEMPOOL_DECLARE_STATS_INSTANCE(name) -#define LWIP_MEMPOOL_DECLARE_STATS_REFERENCE(name) -#endif - -void memp_init_pool(const struct memp_desc *desc); - -#if MEMP_OVERFLOW_CHECK -void *memp_malloc_pool_fn(const struct memp_desc* desc, const char* file, const int line); -#define memp_malloc_pool(d) memp_malloc_pool_fn((d), __FILE__, __LINE__) -#else -void *memp_malloc_pool(const struct memp_desc *desc); -#endif -void memp_free_pool(const struct memp_desc* desc, void *mem); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_MEMP_PRIV_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/priv/memp_std.h b/third-party/lwip-2.1.2/include/lwip/priv/memp_std.h deleted file mode 100644 index 669ad4d7..00000000 --- a/third-party/lwip-2.1.2/include/lwip/priv/memp_std.h +++ /dev/null @@ -1,153 +0,0 @@ -/** - * @file - * lwIP internal memory pools (do not use in application code) - * This file is deliberately included multiple times: once with empty - * definition of LWIP_MEMPOOL() to handle all includes and multiple times - * to build up various lists of mem pools. - */ - -/* - * SETUP: Make sure we define everything we will need. - * - * We have create three types of pools: - * 1) MEMPOOL - standard pools - * 2) MALLOC_MEMPOOL - to be used by mem_malloc in mem.c - * 3) PBUF_MEMPOOL - a mempool of pbuf's, so include space for the pbuf struct - * - * If the include'r doesn't require any special treatment of each of the types - * above, then will declare #2 & #3 to be just standard mempools. - */ -#ifndef LWIP_MALLOC_MEMPOOL -/* This treats "malloc pools" just like any other pool. - The pools are a little bigger to provide 'size' as the amount of user data. */ -#define LWIP_MALLOC_MEMPOOL(num, size) LWIP_MEMPOOL(POOL_##size, num, (size + LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper))), "MALLOC_"#size) -#define LWIP_MALLOC_MEMPOOL_START -#define LWIP_MALLOC_MEMPOOL_END -#endif /* LWIP_MALLOC_MEMPOOL */ - -#ifndef LWIP_PBUF_MEMPOOL -/* This treats "pbuf pools" just like any other pool. - * Allocates buffers for a pbuf struct AND a payload size */ -#define LWIP_PBUF_MEMPOOL(name, num, payload, desc) LWIP_MEMPOOL(name, num, (LWIP_MEM_ALIGN_SIZE(sizeof(struct pbuf)) + LWIP_MEM_ALIGN_SIZE(payload)), desc) -#endif /* LWIP_PBUF_MEMPOOL */ - - -/* - * A list of internal pools used by LWIP. - * - * LWIP_MEMPOOL(pool_name, number_elements, element_size, pool_description) - * creates a pool name MEMP_pool_name. description is used in stats.c - */ -#if LWIP_RAW -LWIP_MEMPOOL(RAW_PCB, MEMP_NUM_RAW_PCB, sizeof(struct raw_pcb), "RAW_PCB") -#endif /* LWIP_RAW */ - -#if LWIP_UDP -LWIP_MEMPOOL(UDP_PCB, MEMP_NUM_UDP_PCB, sizeof(struct udp_pcb), "UDP_PCB") -#endif /* LWIP_UDP */ - -#if LWIP_TCP -LWIP_MEMPOOL(TCP_PCB, MEMP_NUM_TCP_PCB, sizeof(struct tcp_pcb), "TCP_PCB") -LWIP_MEMPOOL(TCP_PCB_LISTEN, MEMP_NUM_TCP_PCB_LISTEN, sizeof(struct tcp_pcb_listen), "TCP_PCB_LISTEN") -LWIP_MEMPOOL(TCP_SEG, MEMP_NUM_TCP_SEG, sizeof(struct tcp_seg), "TCP_SEG") -#endif /* LWIP_TCP */ - -#if LWIP_ALTCP && LWIP_TCP -LWIP_MEMPOOL(ALTCP_PCB, MEMP_NUM_ALTCP_PCB, sizeof(struct altcp_pcb), "ALTCP_PCB") -#endif /* LWIP_ALTCP && LWIP_TCP */ - -#if LWIP_IPV4 && IP_REASSEMBLY -LWIP_MEMPOOL(REASSDATA, MEMP_NUM_REASSDATA, sizeof(struct ip_reassdata), "REASSDATA") -#endif /* LWIP_IPV4 && IP_REASSEMBLY */ -#if (IP_FRAG && !LWIP_NETIF_TX_SINGLE_PBUF) || (LWIP_IPV6 && LWIP_IPV6_FRAG) -LWIP_MEMPOOL(FRAG_PBUF, MEMP_NUM_FRAG_PBUF, sizeof(struct pbuf_custom_ref),"FRAG_PBUF") -#endif /* IP_FRAG && !LWIP_NETIF_TX_SINGLE_PBUF || (LWIP_IPV6 && LWIP_IPV6_FRAG) */ - -#if LWIP_NETCONN || LWIP_SOCKET -LWIP_MEMPOOL(NETBUF, MEMP_NUM_NETBUF, sizeof(struct netbuf), "NETBUF") -LWIP_MEMPOOL(NETCONN, MEMP_NUM_NETCONN, sizeof(struct netconn), "NETCONN") -#endif /* LWIP_NETCONN || LWIP_SOCKET */ - -#if NO_SYS==0 -LWIP_MEMPOOL(TCPIP_MSG_API, MEMP_NUM_TCPIP_MSG_API, sizeof(struct tcpip_msg), "TCPIP_MSG_API") -#if LWIP_MPU_COMPATIBLE -LWIP_MEMPOOL(API_MSG, MEMP_NUM_API_MSG, sizeof(struct api_msg), "API_MSG") -#if LWIP_DNS -LWIP_MEMPOOL(DNS_API_MSG, MEMP_NUM_DNS_API_MSG, sizeof(struct dns_api_msg), "DNS_API_MSG") -#endif -#if LWIP_SOCKET && !LWIP_TCPIP_CORE_LOCKING -LWIP_MEMPOOL(SOCKET_SETGETSOCKOPT_DATA, MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA, sizeof(struct lwip_setgetsockopt_data), "SOCKET_SETGETSOCKOPT_DATA") -#endif -#if LWIP_SOCKET && (LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL) -LWIP_MEMPOOL(SELECT_CB, MEMP_NUM_SELECT_CB, sizeof(struct lwip_select_cb), "SELECT_CB") -#endif /* LWIP_SOCKET && (LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL) */ -#if LWIP_NETIF_API -LWIP_MEMPOOL(NETIFAPI_MSG, MEMP_NUM_NETIFAPI_MSG, sizeof(struct netifapi_msg), "NETIFAPI_MSG") -#endif -#endif /* LWIP_MPU_COMPATIBLE */ -#if !LWIP_TCPIP_CORE_LOCKING_INPUT -LWIP_MEMPOOL(TCPIP_MSG_INPKT,MEMP_NUM_TCPIP_MSG_INPKT, sizeof(struct tcpip_msg), "TCPIP_MSG_INPKT") -#endif /* !LWIP_TCPIP_CORE_LOCKING_INPUT */ -#endif /* NO_SYS==0 */ - -#if LWIP_IPV4 && LWIP_ARP && ARP_QUEUEING -LWIP_MEMPOOL(ARP_QUEUE, MEMP_NUM_ARP_QUEUE, sizeof(struct etharp_q_entry), "ARP_QUEUE") -#endif /* LWIP_IPV4 && LWIP_ARP && ARP_QUEUEING */ - -#if LWIP_IGMP -LWIP_MEMPOOL(IGMP_GROUP, MEMP_NUM_IGMP_GROUP, sizeof(struct igmp_group), "IGMP_GROUP") -#endif /* LWIP_IGMP */ - -#if LWIP_TIMERS && !LWIP_TIMERS_CUSTOM -LWIP_MEMPOOL(SYS_TIMEOUT, MEMP_NUM_SYS_TIMEOUT, sizeof(struct sys_timeo), "SYS_TIMEOUT") -#endif /* LWIP_TIMERS && !LWIP_TIMERS_CUSTOM */ - -#if LWIP_DNS && LWIP_SOCKET -LWIP_MEMPOOL(NETDB, MEMP_NUM_NETDB, NETDB_ELEM_SIZE, "NETDB") -#endif /* LWIP_DNS && LWIP_SOCKET */ -#if LWIP_DNS && DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC -LWIP_MEMPOOL(LOCALHOSTLIST, MEMP_NUM_LOCALHOSTLIST, LOCALHOSTLIST_ELEM_SIZE, "LOCALHOSTLIST") -#endif /* LWIP_DNS && DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ - -#if LWIP_IPV6 && LWIP_ND6_QUEUEING -LWIP_MEMPOOL(ND6_QUEUE, MEMP_NUM_ND6_QUEUE, sizeof(struct nd6_q_entry), "ND6_QUEUE") -#endif /* LWIP_IPV6 && LWIP_ND6_QUEUEING */ - -#if LWIP_IPV6 && LWIP_IPV6_REASS -LWIP_MEMPOOL(IP6_REASSDATA, MEMP_NUM_REASSDATA, sizeof(struct ip6_reassdata), "IP6_REASSDATA") -#endif /* LWIP_IPV6 && LWIP_IPV6_REASS */ - -#if LWIP_IPV6 && LWIP_IPV6_MLD -LWIP_MEMPOOL(MLD6_GROUP, MEMP_NUM_MLD6_GROUP, sizeof(struct mld_group), "MLD6_GROUP") -#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ - - -/* - * A list of pools of pbuf's used by LWIP. - * - * LWIP_PBUF_MEMPOOL(pool_name, number_elements, pbuf_payload_size, pool_description) - * creates a pool name MEMP_pool_name. description is used in stats.c - * This allocates enough space for the pbuf struct and a payload. - * (Example: pbuf_payload_size=0 allocates only size for the struct) - */ -LWIP_MEMPOOL(PBUF, MEMP_NUM_PBUF, sizeof(struct pbuf), "PBUF_REF/ROM") -LWIP_PBUF_MEMPOOL(PBUF_POOL, PBUF_POOL_SIZE, PBUF_POOL_BUFSIZE, "PBUF_POOL") - - -/* - * Allow for user-defined pools; this must be explicitly set in lwipopts.h - * since the default is to NOT look for lwippools.h - */ -#if MEMP_USE_CUSTOM_POOLS -#include "lwippools.h" -#endif /* MEMP_USE_CUSTOM_POOLS */ - -/* - * REQUIRED CLEANUP: Clear up so we don't get "multiply defined" error later - * (#undef is ignored for something that is not defined) - */ -#undef LWIP_MEMPOOL -#undef LWIP_MALLOC_MEMPOOL -#undef LWIP_MALLOC_MEMPOOL_START -#undef LWIP_MALLOC_MEMPOOL_END -#undef LWIP_PBUF_MEMPOOL diff --git a/third-party/lwip-2.1.2/include/lwip/priv/nd6_priv.h b/third-party/lwip-2.1.2/include/lwip/priv/nd6_priv.h deleted file mode 100644 index cc3007d9..00000000 --- a/third-party/lwip-2.1.2/include/lwip/priv/nd6_priv.h +++ /dev/null @@ -1,142 +0,0 @@ -/** - * @file - * - * Neighbor discovery and stateless address autoconfiguration for IPv6. - * Aims to be compliant with RFC 4861 (Neighbor discovery) and RFC 4862 - * (Address autoconfiguration). - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -#ifndef LWIP_HDR_ND6_PRIV_H -#define LWIP_HDR_ND6_PRIV_H - -#include "lwip/opt.h" - -#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/pbuf.h" -#include "lwip/ip6_addr.h" -#include "lwip/netif.h" - - -#ifdef __cplusplus -extern "C" { -#endif - -#if LWIP_ND6_QUEUEING -/** struct for queueing outgoing packets for unknown address - * defined here to be accessed by memp.h - */ -struct nd6_q_entry { - struct nd6_q_entry *next; - struct pbuf *p; -}; -#endif /* LWIP_ND6_QUEUEING */ - -/** Struct for tables. */ -struct nd6_neighbor_cache_entry { - ip6_addr_t next_hop_address; - struct netif *netif; - u8_t lladdr[NETIF_MAX_HWADDR_LEN]; - /*u32_t pmtu;*/ -#if LWIP_ND6_QUEUEING - /** Pointer to queue of pending outgoing packets on this entry. */ - struct nd6_q_entry *q; -#else /* LWIP_ND6_QUEUEING */ - /** Pointer to a single pending outgoing packet on this entry. */ - struct pbuf *q; -#endif /* LWIP_ND6_QUEUEING */ - u8_t state; - u8_t isrouter; - union { - u32_t reachable_time; /* in seconds */ - u32_t delay_time; /* ticks (ND6_TMR_INTERVAL) */ - u32_t probes_sent; - u32_t stale_time; /* ticks (ND6_TMR_INTERVAL) */ - } counter; -}; - -struct nd6_destination_cache_entry { - ip6_addr_t destination_addr; - ip6_addr_t next_hop_addr; - u16_t pmtu; - u32_t age; -}; - -struct nd6_prefix_list_entry { - ip6_addr_t prefix; - struct netif *netif; - u32_t invalidation_timer; /* in seconds */ -}; - -struct nd6_router_list_entry { - struct nd6_neighbor_cache_entry *neighbor_entry; - u32_t invalidation_timer; /* in seconds */ - u8_t flags; -}; - -enum nd6_neighbor_cache_entry_state { - ND6_NO_ENTRY = 0, - ND6_INCOMPLETE, - ND6_REACHABLE, - ND6_STALE, - ND6_DELAY, - ND6_PROBE -}; - -#define ND6_HOPLIM 255 /* maximum hop limit, required in all ND packets */ - -#define ND6_2HRS 7200 /* two hours, expressed in number of seconds */ - -/* Router tables. */ -/* @todo make these static? and entries accessible through API? */ -extern struct nd6_neighbor_cache_entry neighbor_cache[]; -extern struct nd6_destination_cache_entry destination_cache[]; -extern struct nd6_prefix_list_entry prefix_list[]; -extern struct nd6_router_list_entry default_router_list[]; - -/* Default values, can be updated by a RA message. */ -extern u32_t reachable_time; -extern u32_t retrans_timer; - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV6 */ - -#endif /* LWIP_HDR_ND6_PRIV_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/priv/raw_priv.h b/third-party/lwip-2.1.2/include/lwip/priv/raw_priv.h deleted file mode 100644 index d4561d4f..00000000 --- a/third-party/lwip-2.1.2/include/lwip/priv/raw_priv.h +++ /dev/null @@ -1,69 +0,0 @@ -/** - * @file - * raw API internal implementations (do not use in application code) - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_RAW_PRIV_H -#define LWIP_HDR_RAW_PRIV_H - -#include "lwip/opt.h" - -#if LWIP_RAW /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/raw.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** return codes for raw_input */ -typedef enum raw_input_state -{ - RAW_INPUT_NONE = 0, /* pbuf did not match any pcbs */ - RAW_INPUT_EATEN, /* pbuf handed off and delivered to pcb */ - RAW_INPUT_DELIVERED /* pbuf only delivered to pcb (pbuf can still be referenced) */ -} raw_input_state_t; - -/* The following functions are the lower layer interface to RAW. */ -raw_input_state_t raw_input(struct pbuf *p, struct netif *inp); - -void raw_netif_ip_addr_changed(const ip_addr_t* old_addr, const ip_addr_t* new_addr); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_RAW */ - -#endif /* LWIP_HDR_RAW_PRIV_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/priv/sockets_priv.h b/third-party/lwip-2.1.2/include/lwip/priv/sockets_priv.h deleted file mode 100644 index d8f9904d..00000000 --- a/third-party/lwip-2.1.2/include/lwip/priv/sockets_priv.h +++ /dev/null @@ -1,175 +0,0 @@ -/** - * @file - * Sockets API internal implementations (do not use in application code) - */ - -/* - * Copyright (c) 2017 Joel Cunningham, Garmin International, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Joel Cunningham - * - */ -#ifndef LWIP_HDR_SOCKETS_PRIV_H -#define LWIP_HDR_SOCKETS_PRIV_H - -#include "lwip/opt.h" - -#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/err.h" -#include "lwip/sockets.h" -#include "lwip/sys.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define NUM_SOCKETS MEMP_NUM_NETCONN - -/** This is overridable for the rare case where more than 255 threads - * select on the same socket... - */ -#ifndef SELWAIT_T -#define SELWAIT_T u8_t -#endif - -union lwip_sock_lastdata { - struct netbuf *netbuf; - struct pbuf *pbuf; -}; - -/** Contains all internal pointers and states used for a socket */ -struct lwip_sock { - /** sockets currently are built on netconns, each socket has one netconn */ - struct netconn *conn; - /** data that was left from the previous read */ - union lwip_sock_lastdata lastdata; -#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL - /** number of times data was received, set by event_callback(), - tested by the receive and select functions */ - s16_t rcvevent; - /** number of times data was ACKed (free send buffer), set by event_callback(), - tested by select */ - u16_t sendevent; - /** error happened for this socket, set by event_callback(), tested by select */ - u16_t errevent; - /** counter of how many threads are waiting for this socket using select */ - SELWAIT_T select_waiting; -#endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */ -#if LWIP_NETCONN_FULLDUPLEX - /* counter of how many threads are using a struct lwip_sock (not the 'int') */ - u8_t fd_used; - /* status of pending close/delete actions */ - u8_t fd_free_pending; -#define LWIP_SOCK_FD_FREE_TCP 1 -#define LWIP_SOCK_FD_FREE_FREE 2 -#endif -}; - -#ifndef set_errno -#define set_errno(err) do { if (err) { errno = (err); } } while(0) -#endif - -#if !LWIP_TCPIP_CORE_LOCKING -/** Maximum optlen used by setsockopt/getsockopt */ -#define LWIP_SETGETSOCKOPT_MAXOPTLEN LWIP_MAX(16, sizeof(struct ifreq)) - -/** This struct is used to pass data to the set/getsockopt_internal - * functions running in tcpip_thread context (only a void* is allowed) */ -struct lwip_setgetsockopt_data { - /** socket index for which to change options */ - int s; - /** level of the option to process */ - int level; - /** name of the option to process */ - int optname; - /** set: value to set the option to - * get: value of the option is stored here */ -#if LWIP_MPU_COMPATIBLE - u8_t optval[LWIP_SETGETSOCKOPT_MAXOPTLEN]; -#else - union { - void *p; - const void *pc; - } optval; -#endif - /** size of *optval */ - socklen_t optlen; - /** if an error occurs, it is temporarily stored here */ - int err; - /** semaphore to wake up the calling task */ - void* completed_sem; -}; -#endif /* !LWIP_TCPIP_CORE_LOCKING */ - -#ifdef __cplusplus -} -#endif - -struct lwip_sock* lwip_socket_dbg_get_socket(int fd); - -#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL - -#if LWIP_NETCONN_SEM_PER_THREAD -#define SELECT_SEM_T sys_sem_t* -#define SELECT_SEM_PTR(sem) (sem) -#else /* LWIP_NETCONN_SEM_PER_THREAD */ -#define SELECT_SEM_T sys_sem_t -#define SELECT_SEM_PTR(sem) (&(sem)) -#endif /* LWIP_NETCONN_SEM_PER_THREAD */ - -/** Description for a task waiting in select */ -struct lwip_select_cb { - /** Pointer to the next waiting task */ - struct lwip_select_cb *next; - /** Pointer to the previous waiting task */ - struct lwip_select_cb *prev; -#if LWIP_SOCKET_SELECT - /** readset passed to select */ - fd_set *readset; - /** writeset passed to select */ - fd_set *writeset; - /** unimplemented: exceptset passed to select */ - fd_set *exceptset; -#endif /* LWIP_SOCKET_SELECT */ -#if LWIP_SOCKET_POLL - /** fds passed to poll; NULL if select */ - struct pollfd *poll_fds; - /** nfds passed to poll; 0 if select */ - nfds_t poll_nfds; -#endif /* LWIP_SOCKET_POLL */ - /** don't signal the same semaphore twice: set to 1 when signalled */ - int sem_signalled; - /** semaphore to wake up a task waiting for select */ - SELECT_SEM_T sem; -}; -#endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */ - -#endif /* LWIP_SOCKET */ - -#endif /* LWIP_HDR_SOCKETS_PRIV_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/priv/tcp_priv.h b/third-party/lwip-2.1.2/include/lwip/priv/tcp_priv.h deleted file mode 100644 index 72f9126d..00000000 --- a/third-party/lwip-2.1.2/include/lwip/priv/tcp_priv.h +++ /dev/null @@ -1,523 +0,0 @@ -/** - * @file - * TCP internal implementations (do not use in application code) - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_TCP_PRIV_H -#define LWIP_HDR_TCP_PRIV_H - -#include "lwip/opt.h" - -#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/tcp.h" -#include "lwip/mem.h" -#include "lwip/pbuf.h" -#include "lwip/ip.h" -#include "lwip/icmp.h" -#include "lwip/err.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#include "lwip/prot/tcp.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Functions for interfacing with TCP: */ - -/* Lower layer interface to TCP: */ -void tcp_init (void); /* Initialize this module. */ -void tcp_tmr (void); /* Must be called every - TCP_TMR_INTERVAL - ms. (Typically 250 ms). */ -/* It is also possible to call these two functions at the right - intervals (instead of calling tcp_tmr()). */ -void tcp_slowtmr (void); -void tcp_fasttmr (void); - -/* Call this from a netif driver (watch out for threading issues!) that has - returned a memory error on transmit and now has free buffers to send more. - This iterates all active pcbs that had an error and tries to call - tcp_output, so use this with care as it might slow down the system. */ -void tcp_txnow (void); - -/* Only used by IP to pass a TCP segment to TCP: */ -void tcp_input (struct pbuf *p, struct netif *inp); -/* Used within the TCP code only: */ -struct tcp_pcb * tcp_alloc (u8_t prio); -void tcp_free (struct tcp_pcb *pcb); -void tcp_abandon (struct tcp_pcb *pcb, int reset); -err_t tcp_send_empty_ack(struct tcp_pcb *pcb); -err_t tcp_rexmit (struct tcp_pcb *pcb); -err_t tcp_rexmit_rto_prepare(struct tcp_pcb *pcb); -void tcp_rexmit_rto_commit(struct tcp_pcb *pcb); -void tcp_rexmit_rto (struct tcp_pcb *pcb); -void tcp_rexmit_fast (struct tcp_pcb *pcb); -u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb); -err_t tcp_process_refused_data(struct tcp_pcb *pcb); - -/** - * This is the Nagle algorithm: try to combine user data to send as few TCP - * segments as possible. Only send if - * - no previously transmitted data on the connection remains unacknowledged or - * - the TF_NODELAY flag is set (nagle algorithm turned off for this pcb) or - * - the only unsent segment is at least pcb->mss bytes long (or there is more - * than one unsent segment - with lwIP, this can happen although unsent->len < mss) - * - or if we are in fast-retransmit (TF_INFR) - */ -#define tcp_do_output_nagle(tpcb) ((((tpcb)->unacked == NULL) || \ - ((tpcb)->flags & (TF_NODELAY | TF_INFR)) || \ - (((tpcb)->unsent != NULL) && (((tpcb)->unsent->next != NULL) || \ - ((tpcb)->unsent->len >= (tpcb)->mss))) || \ - ((tcp_sndbuf(tpcb) == 0) || (tcp_sndqueuelen(tpcb) >= TCP_SND_QUEUELEN)) \ - ) ? 1 : 0) -#define tcp_output_nagle(tpcb) (tcp_do_output_nagle(tpcb) ? tcp_output(tpcb) : ERR_OK) - - -#define TCP_SEQ_LT(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) < 0) -#define TCP_SEQ_LEQ(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) <= 0) -#define TCP_SEQ_GT(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) > 0) -#define TCP_SEQ_GEQ(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) >= 0) -/* is b<=a<=c? */ -#if 0 /* see bug #10548 */ -#define TCP_SEQ_BETWEEN(a,b,c) ((c)-(b) >= (a)-(b)) -#endif -#define TCP_SEQ_BETWEEN(a,b,c) (TCP_SEQ_GEQ(a,b) && TCP_SEQ_LEQ(a,c)) - -#ifndef TCP_TMR_INTERVAL -#define TCP_TMR_INTERVAL 250 /* The TCP timer interval in milliseconds. */ -#endif /* TCP_TMR_INTERVAL */ - -#ifndef TCP_FAST_INTERVAL -#define TCP_FAST_INTERVAL TCP_TMR_INTERVAL /* the fine grained timeout in milliseconds */ -#endif /* TCP_FAST_INTERVAL */ - -#ifndef TCP_SLOW_INTERVAL -#define TCP_SLOW_INTERVAL (2*TCP_TMR_INTERVAL) /* the coarse grained timeout in milliseconds */ -#endif /* TCP_SLOW_INTERVAL */ - -#define TCP_FIN_WAIT_TIMEOUT 20000 /* milliseconds */ -#define TCP_SYN_RCVD_TIMEOUT 20000 /* milliseconds */ - -#define TCP_OOSEQ_TIMEOUT 6U /* x RTO */ - -#ifndef TCP_MSL -#define TCP_MSL 60000UL /* The maximum segment lifetime in milliseconds */ -#endif - -/* Keepalive values, compliant with RFC 1122. Don't change this unless you know what you're doing */ -#ifndef TCP_KEEPIDLE_DEFAULT -#define TCP_KEEPIDLE_DEFAULT 7200000UL /* Default KEEPALIVE timer in milliseconds */ -#endif - -#ifndef TCP_KEEPINTVL_DEFAULT -#define TCP_KEEPINTVL_DEFAULT 75000UL /* Default Time between KEEPALIVE probes in milliseconds */ -#endif - -#ifndef TCP_KEEPCNT_DEFAULT -#define TCP_KEEPCNT_DEFAULT 9U /* Default Counter for KEEPALIVE probes */ -#endif - -#define TCP_MAXIDLE TCP_KEEPCNT_DEFAULT * TCP_KEEPINTVL_DEFAULT /* Maximum KEEPALIVE probe time */ - -#define TCP_TCPLEN(seg) ((seg)->len + (((TCPH_FLAGS((seg)->tcphdr) & (TCP_FIN | TCP_SYN)) != 0) ? 1U : 0U)) - -/** Flags used on input processing, not on pcb->flags -*/ -#define TF_RESET (u8_t)0x08U /* Connection was reset. */ -#define TF_CLOSED (u8_t)0x10U /* Connection was successfully closed. */ -#define TF_GOT_FIN (u8_t)0x20U /* Connection was closed by the remote end. */ - - -#if LWIP_EVENT_API - -#define TCP_EVENT_ACCEPT(lpcb,pcb,arg,err,ret) ret = lwip_tcp_event(arg, (pcb),\ - LWIP_EVENT_ACCEPT, NULL, 0, err) -#define TCP_EVENT_SENT(pcb,space,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ - LWIP_EVENT_SENT, NULL, space, ERR_OK) -#define TCP_EVENT_RECV(pcb,p,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ - LWIP_EVENT_RECV, (p), 0, (err)) -#define TCP_EVENT_CLOSED(pcb,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ - LWIP_EVENT_RECV, NULL, 0, ERR_OK) -#define TCP_EVENT_CONNECTED(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ - LWIP_EVENT_CONNECTED, NULL, 0, (err)) -#define TCP_EVENT_POLL(pcb,ret) do { if ((pcb)->state != SYN_RCVD) { \ - ret = lwip_tcp_event((pcb)->callback_arg, (pcb), LWIP_EVENT_POLL, NULL, 0, ERR_OK); \ - } else { \ - ret = ERR_ARG; } } while(0) -/* For event API, last state SYN_RCVD must be excluded here: the application - has not seen this pcb, yet! */ -#define TCP_EVENT_ERR(last_state,errf,arg,err) do { if (last_state != SYN_RCVD) { \ - lwip_tcp_event((arg), NULL, LWIP_EVENT_ERR, NULL, 0, (err)); } } while(0) - -#else /* LWIP_EVENT_API */ - -#define TCP_EVENT_ACCEPT(lpcb,pcb,arg,err,ret) \ - do { \ - if((lpcb)->accept != NULL) \ - (ret) = (lpcb)->accept((arg),(pcb),(err)); \ - else (ret) = ERR_ARG; \ - } while (0) - -#define TCP_EVENT_SENT(pcb,space,ret) \ - do { \ - if((pcb)->sent != NULL) \ - (ret) = (pcb)->sent((pcb)->callback_arg,(pcb),(space)); \ - else (ret) = ERR_OK; \ - } while (0) - -#define TCP_EVENT_RECV(pcb,p,err,ret) \ - do { \ - if((pcb)->recv != NULL) { \ - (ret) = (pcb)->recv((pcb)->callback_arg,(pcb),(p),(err));\ - } else { \ - (ret) = tcp_recv_null(NULL, (pcb), (p), (err)); \ - } \ - } while (0) - -#define TCP_EVENT_CLOSED(pcb,ret) \ - do { \ - if(((pcb)->recv != NULL)) { \ - (ret) = (pcb)->recv((pcb)->callback_arg,(pcb),NULL,ERR_OK);\ - } else { \ - (ret) = ERR_OK; \ - } \ - } while (0) - -#define TCP_EVENT_CONNECTED(pcb,err,ret) \ - do { \ - if((pcb)->connected != NULL) \ - (ret) = (pcb)->connected((pcb)->callback_arg,(pcb),(err)); \ - else (ret) = ERR_OK; \ - } while (0) - -#define TCP_EVENT_POLL(pcb,ret) \ - do { \ - if((pcb)->poll != NULL) \ - (ret) = (pcb)->poll((pcb)->callback_arg,(pcb)); \ - else (ret) = ERR_OK; \ - } while (0) - -#define TCP_EVENT_ERR(last_state,errf,arg,err) \ - do { \ - LWIP_UNUSED_ARG(last_state); \ - if((errf) != NULL) \ - (errf)((arg),(err)); \ - } while (0) - -#endif /* LWIP_EVENT_API */ - -/** Enabled extra-check for TCP_OVERSIZE if LWIP_DEBUG is enabled */ -#if TCP_OVERSIZE && defined(LWIP_DEBUG) -#define TCP_OVERSIZE_DBGCHECK 1 -#else -#define TCP_OVERSIZE_DBGCHECK 0 -#endif - -/** Don't generate checksum on copy if CHECKSUM_GEN_TCP is disabled */ -#define TCP_CHECKSUM_ON_COPY (LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_TCP) - -/* This structure represents a TCP segment on the unsent, unacked and ooseq queues */ -struct tcp_seg { - struct tcp_seg *next; /* used when putting segments on a queue */ - struct pbuf *p; /* buffer containing data + TCP header */ - u16_t len; /* the TCP length of this segment */ -#if TCP_OVERSIZE_DBGCHECK - u16_t oversize_left; /* Extra bytes available at the end of the last - pbuf in unsent (used for asserting vs. - tcp_pcb.unsent_oversize only) */ -#endif /* TCP_OVERSIZE_DBGCHECK */ -#if TCP_CHECKSUM_ON_COPY - u16_t chksum; - u8_t chksum_swapped; -#endif /* TCP_CHECKSUM_ON_COPY */ - u8_t flags; -#define TF_SEG_OPTS_MSS (u8_t)0x01U /* Include MSS option (only used in SYN segments) */ -#define TF_SEG_OPTS_TS (u8_t)0x02U /* Include timestamp option. */ -#define TF_SEG_DATA_CHECKSUMMED (u8_t)0x04U /* ALL data (not the header) is - checksummed into 'chksum' */ -#define TF_SEG_OPTS_WND_SCALE (u8_t)0x08U /* Include WND SCALE option (only used in SYN segments) */ -#define TF_SEG_OPTS_SACK_PERM (u8_t)0x10U /* Include SACK Permitted option (only used in SYN segments) */ - struct tcp_hdr *tcphdr; /* the TCP header */ -}; - -#define LWIP_TCP_OPT_EOL 0 -#define LWIP_TCP_OPT_NOP 1 -#define LWIP_TCP_OPT_MSS 2 -#define LWIP_TCP_OPT_WS 3 -#define LWIP_TCP_OPT_SACK_PERM 4 -#define LWIP_TCP_OPT_TS 8 - -#define LWIP_TCP_OPT_LEN_MSS 4 -#if LWIP_TCP_TIMESTAMPS -#define LWIP_TCP_OPT_LEN_TS 10 -#define LWIP_TCP_OPT_LEN_TS_OUT 12 /* aligned for output (includes NOP padding) */ -#else -#define LWIP_TCP_OPT_LEN_TS_OUT 0 -#endif -#if LWIP_WND_SCALE -#define LWIP_TCP_OPT_LEN_WS 3 -#define LWIP_TCP_OPT_LEN_WS_OUT 4 /* aligned for output (includes NOP padding) */ -#else -#define LWIP_TCP_OPT_LEN_WS_OUT 0 -#endif - -#if LWIP_TCP_SACK_OUT -#define LWIP_TCP_OPT_LEN_SACK_PERM 2 -#define LWIP_TCP_OPT_LEN_SACK_PERM_OUT 4 /* aligned for output (includes NOP padding) */ -#else -#define LWIP_TCP_OPT_LEN_SACK_PERM_OUT 0 -#endif - -#define LWIP_TCP_OPT_LENGTH(flags) \ - ((flags) & TF_SEG_OPTS_MSS ? LWIP_TCP_OPT_LEN_MSS : 0) + \ - ((flags) & TF_SEG_OPTS_TS ? LWIP_TCP_OPT_LEN_TS_OUT : 0) + \ - ((flags) & TF_SEG_OPTS_WND_SCALE ? LWIP_TCP_OPT_LEN_WS_OUT : 0) + \ - ((flags) & TF_SEG_OPTS_SACK_PERM ? LWIP_TCP_OPT_LEN_SACK_PERM_OUT : 0) - -/** This returns a TCP header option for MSS in an u32_t */ -#define TCP_BUILD_MSS_OPTION(mss) lwip_htonl(0x02040000 | ((mss) & 0xFFFF)) - -#if LWIP_WND_SCALE -#define TCPWNDSIZE_F U32_F -#define TCPWND_MAX 0xFFFFFFFFU -#define TCPWND_CHECK16(x) LWIP_ASSERT("window size > 0xFFFF", (x) <= 0xFFFF) -#define TCPWND_MIN16(x) ((u16_t)LWIP_MIN((x), 0xFFFF)) -#else /* LWIP_WND_SCALE */ -#define TCPWNDSIZE_F U16_F -#define TCPWND_MAX 0xFFFFU -#define TCPWND_CHECK16(x) -#define TCPWND_MIN16(x) x -#endif /* LWIP_WND_SCALE */ - -/* Global variables: */ -extern struct tcp_pcb *tcp_input_pcb; -extern u32_t tcp_ticks; -extern u8_t tcp_active_pcbs_changed; - -/* The TCP PCB lists. */ -union tcp_listen_pcbs_t { /* List of all TCP PCBs in LISTEN state. */ - struct tcp_pcb_listen *listen_pcbs; - struct tcp_pcb *pcbs; -}; -extern struct tcp_pcb *tcp_bound_pcbs; -extern union tcp_listen_pcbs_t tcp_listen_pcbs; -extern struct tcp_pcb *tcp_active_pcbs; /* List of all TCP PCBs that are in a - state in which they accept or send - data. */ -extern struct tcp_pcb *tcp_tw_pcbs; /* List of all TCP PCBs in TIME-WAIT. */ - -#define NUM_TCP_PCB_LISTS_NO_TIME_WAIT 3 -#define NUM_TCP_PCB_LISTS 4 -extern struct tcp_pcb ** const tcp_pcb_lists[NUM_TCP_PCB_LISTS]; - -/* Axioms about the above lists: - 1) Every TCP PCB that is not CLOSED is in one of the lists. - 2) A PCB is only in one of the lists. - 3) All PCBs in the tcp_listen_pcbs list is in LISTEN state. - 4) All PCBs in the tcp_tw_pcbs list is in TIME-WAIT state. -*/ -/* Define two macros, TCP_REG and TCP_RMV that registers a TCP PCB - with a PCB list or removes a PCB from a list, respectively. */ -#ifndef TCP_DEBUG_PCB_LISTS -#define TCP_DEBUG_PCB_LISTS 0 -#endif -#if TCP_DEBUG_PCB_LISTS -#define TCP_REG(pcbs, npcb) do {\ - struct tcp_pcb *tcp_tmp_pcb; \ - LWIP_DEBUGF(TCP_DEBUG, ("TCP_REG %p local port %"U16_F"\n", (void *)(npcb), (npcb)->local_port)); \ - for (tcp_tmp_pcb = *(pcbs); \ - tcp_tmp_pcb != NULL; \ - tcp_tmp_pcb = tcp_tmp_pcb->next) { \ - LWIP_ASSERT("TCP_REG: already registered\n", tcp_tmp_pcb != (npcb)); \ - } \ - LWIP_ASSERT("TCP_REG: pcb->state != CLOSED", ((pcbs) == &tcp_bound_pcbs) || ((npcb)->state != CLOSED)); \ - (npcb)->next = *(pcbs); \ - LWIP_ASSERT("TCP_REG: npcb->next != npcb", (npcb)->next != (npcb)); \ - *(pcbs) = (npcb); \ - LWIP_ASSERT("TCP_REG: tcp_pcbs sane", tcp_pcbs_sane()); \ - tcp_timer_needed(); \ - } while(0) -#define TCP_RMV(pcbs, npcb) do { \ - struct tcp_pcb *tcp_tmp_pcb; \ - LWIP_ASSERT("TCP_RMV: pcbs != NULL", *(pcbs) != NULL); \ - LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removing %p from %p\n", (void *)(npcb), (void *)(*(pcbs)))); \ - if(*(pcbs) == (npcb)) { \ - *(pcbs) = (*pcbs)->next; \ - } else for (tcp_tmp_pcb = *(pcbs); tcp_tmp_pcb != NULL; tcp_tmp_pcb = tcp_tmp_pcb->next) { \ - if(tcp_tmp_pcb->next == (npcb)) { \ - tcp_tmp_pcb->next = (npcb)->next; \ - break; \ - } \ - } \ - (npcb)->next = NULL; \ - LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \ - LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removed %p from %p\n", (void *)(npcb), (void *)(*(pcbs)))); \ - } while(0) - -#else /* LWIP_DEBUG */ - -#define TCP_REG(pcbs, npcb) \ - do { \ - (npcb)->next = *pcbs; \ - *(pcbs) = (npcb); \ - tcp_timer_needed(); \ - } while (0) - -#define TCP_RMV(pcbs, npcb) \ - do { \ - if(*(pcbs) == (npcb)) { \ - (*(pcbs)) = (*pcbs)->next; \ - } \ - else { \ - struct tcp_pcb *tcp_tmp_pcb; \ - for (tcp_tmp_pcb = *pcbs; \ - tcp_tmp_pcb != NULL; \ - tcp_tmp_pcb = tcp_tmp_pcb->next) { \ - if(tcp_tmp_pcb->next == (npcb)) { \ - tcp_tmp_pcb->next = (npcb)->next; \ - break; \ - } \ - } \ - } \ - (npcb)->next = NULL; \ - } while(0) - -#endif /* LWIP_DEBUG */ - -#define TCP_REG_ACTIVE(npcb) \ - do { \ - TCP_REG(&tcp_active_pcbs, npcb); \ - tcp_active_pcbs_changed = 1; \ - } while (0) - -#define TCP_RMV_ACTIVE(npcb) \ - do { \ - TCP_RMV(&tcp_active_pcbs, npcb); \ - tcp_active_pcbs_changed = 1; \ - } while (0) - -#define TCP_PCB_REMOVE_ACTIVE(pcb) \ - do { \ - tcp_pcb_remove(&tcp_active_pcbs, pcb); \ - tcp_active_pcbs_changed = 1; \ - } while (0) - - -/* Internal functions: */ -struct tcp_pcb *tcp_pcb_copy(struct tcp_pcb *pcb); -void tcp_pcb_purge(struct tcp_pcb *pcb); -void tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb); - -void tcp_segs_free(struct tcp_seg *seg); -void tcp_seg_free(struct tcp_seg *seg); -struct tcp_seg *tcp_seg_copy(struct tcp_seg *seg); - -#define tcp_ack(pcb) \ - do { \ - if((pcb)->flags & TF_ACK_DELAY) { \ - tcp_clear_flags(pcb, TF_ACK_DELAY); \ - tcp_ack_now(pcb); \ - } \ - else { \ - tcp_set_flags(pcb, TF_ACK_DELAY); \ - } \ - } while (0) - -#define tcp_ack_now(pcb) \ - tcp_set_flags(pcb, TF_ACK_NOW) - -err_t tcp_send_fin(struct tcp_pcb *pcb); -err_t tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags); - -void tcp_rexmit_seg(struct tcp_pcb *pcb, struct tcp_seg *seg); - -void tcp_rst(const struct tcp_pcb* pcb, u32_t seqno, u32_t ackno, - const ip_addr_t *local_ip, const ip_addr_t *remote_ip, - u16_t local_port, u16_t remote_port); - -u32_t tcp_next_iss(struct tcp_pcb *pcb); - -err_t tcp_keepalive(struct tcp_pcb *pcb); -err_t tcp_split_unsent_seg(struct tcp_pcb *pcb, u16_t split); -err_t tcp_zero_window_probe(struct tcp_pcb *pcb); -void tcp_trigger_input_pcb_close(void); - -#if TCP_CALCULATE_EFF_SEND_MSS -u16_t tcp_eff_send_mss_netif(u16_t sendmss, struct netif *outif, - const ip_addr_t *dest); -#define tcp_eff_send_mss(sendmss, src, dest) \ - tcp_eff_send_mss_netif(sendmss, ip_route(src, dest), dest) -#endif /* TCP_CALCULATE_EFF_SEND_MSS */ - -#if LWIP_CALLBACK_API -err_t tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err); -#endif /* LWIP_CALLBACK_API */ - -#if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG -void tcp_debug_print(struct tcp_hdr *tcphdr); -void tcp_debug_print_flags(u8_t flags); -void tcp_debug_print_state(enum tcp_state s); -void tcp_debug_print_pcbs(void); -s16_t tcp_pcbs_sane(void); -#else -# define tcp_debug_print(tcphdr) -# define tcp_debug_print_flags(flags) -# define tcp_debug_print_state(s) -# define tcp_debug_print_pcbs() -# define tcp_pcbs_sane() 1 -#endif /* TCP_DEBUG */ - -/** External function (implemented in timers.c), called when TCP detects - * that a timer is needed (i.e. active- or time-wait-pcb found). */ -void tcp_timer_needed(void); - -void tcp_netif_ip_addr_changed(const ip_addr_t* old_addr, const ip_addr_t* new_addr); - -#if TCP_QUEUE_OOSEQ -void tcp_free_ooseq(struct tcp_pcb *pcb); -#endif - -#if LWIP_TCP_PCB_NUM_EXT_ARGS -err_t tcp_ext_arg_invoke_callbacks_passive_open(struct tcp_pcb_listen *lpcb, struct tcp_pcb *cpcb); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_TCP */ - -#endif /* LWIP_HDR_TCP_PRIV_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/priv/tcpip_priv.h b/third-party/lwip-2.1.2/include/lwip/priv/tcpip_priv.h deleted file mode 100644 index 74be634b..00000000 --- a/third-party/lwip-2.1.2/include/lwip/priv/tcpip_priv.h +++ /dev/null @@ -1,170 +0,0 @@ -/** - * @file - * TCPIP API internal implementations (do not use in application code) - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_TCPIP_PRIV_H -#define LWIP_HDR_TCPIP_PRIV_H - -#include "lwip/opt.h" - -#if !NO_SYS /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/tcpip.h" -#include "lwip/sys.h" -#include "lwip/timeouts.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct pbuf; -struct netif; - -#if LWIP_MPU_COMPATIBLE -#define API_VAR_REF(name) (*(name)) -#define API_VAR_DECLARE(type, name) type * name -#define API_VAR_ALLOC_EXT(type, pool, name, errorblock) do { \ - name = (type *)memp_malloc(pool); \ - if (name == NULL) { \ - errorblock; \ - } \ - } while(0) -#define API_VAR_ALLOC(type, pool, name, errorval) API_VAR_ALLOC_EXT(type, pool, name, return errorval) -#define API_VAR_ALLOC_POOL(type, pool, name, errorval) do { \ - name = (type *)LWIP_MEMPOOL_ALLOC(pool); \ - if (name == NULL) { \ - return errorval; \ - } \ - } while(0) -#define API_VAR_FREE(pool, name) memp_free(pool, name) -#define API_VAR_FREE_POOL(pool, name) LWIP_MEMPOOL_FREE(pool, name) -#define API_EXPR_REF(expr) (&(expr)) -#if LWIP_NETCONN_SEM_PER_THREAD -#define API_EXPR_REF_SEM(expr) (expr) -#else -#define API_EXPR_REF_SEM(expr) API_EXPR_REF(expr) -#endif -#define API_EXPR_DEREF(expr) expr -#define API_MSG_M_DEF(m) m -#define API_MSG_M_DEF_C(t, m) t m -#else /* LWIP_MPU_COMPATIBLE */ -#define API_VAR_REF(name) name -#define API_VAR_DECLARE(type, name) type name -#define API_VAR_ALLOC_EXT(type, pool, name, errorblock) -#define API_VAR_ALLOC(type, pool, name, errorval) -#define API_VAR_ALLOC_POOL(type, pool, name, errorval) -#define API_VAR_FREE(pool, name) -#define API_VAR_FREE_POOL(pool, name) -#define API_EXPR_REF(expr) expr -#define API_EXPR_REF_SEM(expr) API_EXPR_REF(expr) -#define API_EXPR_DEREF(expr) (*(expr)) -#define API_MSG_M_DEF(m) *m -#define API_MSG_M_DEF_C(t, m) const t * m -#endif /* LWIP_MPU_COMPATIBLE */ - -err_t tcpip_send_msg_wait_sem(tcpip_callback_fn fn, void *apimsg, sys_sem_t* sem); - -struct tcpip_api_call_data -{ -#if !LWIP_TCPIP_CORE_LOCKING - err_t err; -#if !LWIP_NETCONN_SEM_PER_THREAD - sys_sem_t sem; -#endif /* LWIP_NETCONN_SEM_PER_THREAD */ -#else /* !LWIP_TCPIP_CORE_LOCKING */ - u8_t dummy; /* avoid empty struct :-( */ -#endif /* !LWIP_TCPIP_CORE_LOCKING */ -}; -typedef err_t (*tcpip_api_call_fn)(struct tcpip_api_call_data* call); -err_t tcpip_api_call(tcpip_api_call_fn fn, struct tcpip_api_call_data *call); - -enum tcpip_msg_type { -#if !LWIP_TCPIP_CORE_LOCKING - TCPIP_MSG_API, - TCPIP_MSG_API_CALL, -#endif /* !LWIP_TCPIP_CORE_LOCKING */ -#if !LWIP_TCPIP_CORE_LOCKING_INPUT - TCPIP_MSG_INPKT, -#endif /* !LWIP_TCPIP_CORE_LOCKING_INPUT */ -#if LWIP_TCPIP_TIMEOUT && LWIP_TIMERS - TCPIP_MSG_TIMEOUT, - TCPIP_MSG_UNTIMEOUT, -#endif /* LWIP_TCPIP_TIMEOUT && LWIP_TIMERS */ - TCPIP_MSG_CALLBACK, - TCPIP_MSG_CALLBACK_STATIC -}; - -struct tcpip_msg { - enum tcpip_msg_type type; - union { -#if !LWIP_TCPIP_CORE_LOCKING - struct { - tcpip_callback_fn function; - void* msg; - } api_msg; - struct { - tcpip_api_call_fn function; - struct tcpip_api_call_data *arg; - sys_sem_t *sem; - } api_call; -#endif /* LWIP_TCPIP_CORE_LOCKING */ -#if !LWIP_TCPIP_CORE_LOCKING_INPUT - struct { - struct pbuf *p; - struct netif *netif; - netif_input_fn input_fn; - } inp; -#endif /* !LWIP_TCPIP_CORE_LOCKING_INPUT */ - struct { - tcpip_callback_fn function; - void *ctx; - } cb; -#if LWIP_TCPIP_TIMEOUT && LWIP_TIMERS - struct { - u32_t msecs; - sys_timeout_handler h; - void *arg; - } tmo; -#endif /* LWIP_TCPIP_TIMEOUT && LWIP_TIMERS */ - } msg; -}; - -#ifdef __cplusplus -} -#endif - -#endif /* !NO_SYS */ - -#endif /* LWIP_HDR_TCPIP_PRIV_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/prot/autoip.h b/third-party/lwip-2.1.2/include/lwip/prot/autoip.h deleted file mode 100644 index fd3af8a9..00000000 --- a/third-party/lwip-2.1.2/include/lwip/prot/autoip.h +++ /dev/null @@ -1,78 +0,0 @@ -/** - * @file - * AutoIP protocol definitions - */ - -/* - * - * Copyright (c) 2007 Dominik Spies - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Dominik Spies - * - * This is a AutoIP implementation for the lwIP TCP/IP stack. It aims to conform - * with RFC 3927. - * - */ - -#ifndef LWIP_HDR_PROT_AUTOIP_H -#define LWIP_HDR_PROT_AUTOIP_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* 169.254.0.0 */ -#define AUTOIP_NET 0xA9FE0000 -/* 169.254.1.0 */ -#define AUTOIP_RANGE_START (AUTOIP_NET | 0x0100) -/* 169.254.254.255 */ -#define AUTOIP_RANGE_END (AUTOIP_NET | 0xFEFF) - -/* RFC 3927 Constants */ -#define PROBE_WAIT 1 /* second (initial random delay) */ -#define PROBE_MIN 1 /* second (minimum delay till repeated probe) */ -#define PROBE_MAX 2 /* seconds (maximum delay till repeated probe) */ -#define PROBE_NUM 3 /* (number of probe packets) */ -#define ANNOUNCE_NUM 2 /* (number of announcement packets) */ -#define ANNOUNCE_INTERVAL 2 /* seconds (time between announcement packets) */ -#define ANNOUNCE_WAIT 2 /* seconds (delay before announcing) */ -#define MAX_CONFLICTS 10 /* (max conflicts before rate limiting) */ -#define RATE_LIMIT_INTERVAL 60 /* seconds (delay between successive attempts) */ -#define DEFEND_INTERVAL 10 /* seconds (min. wait between defensive ARPs) */ - -/* AutoIP client states */ -typedef enum { - AUTOIP_STATE_OFF = 0, - AUTOIP_STATE_PROBING = 1, - AUTOIP_STATE_ANNOUNCING = 2, - AUTOIP_STATE_BOUND = 3 -} autoip_state_enum_t; - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_PROT_AUTOIP_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/prot/dhcp.h b/third-party/lwip-2.1.2/include/lwip/prot/dhcp.h deleted file mode 100644 index ab18dca3..00000000 --- a/third-party/lwip-2.1.2/include/lwip/prot/dhcp.h +++ /dev/null @@ -1,178 +0,0 @@ -/** - * @file - * DHCP protocol definitions - */ - -/* - * Copyright (c) 2001-2004 Leon Woestenberg - * Copyright (c) 2001-2004 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Leon Woestenberg - * - */ -#ifndef LWIP_HDR_PROT_DHCP_H -#define LWIP_HDR_PROT_DHCP_H - -#include "lwip/opt.h" -#include "lwip/arch.h" -#include "lwip/prot/ip4.h" - -#ifdef __cplusplus -extern "C" { -#endif - - /* DHCP message item offsets and length */ -#define DHCP_CHADDR_LEN 16U -#define DHCP_SNAME_OFS 44U -#define DHCP_SNAME_LEN 64U -#define DHCP_FILE_OFS 108U -#define DHCP_FILE_LEN 128U -#define DHCP_MSG_LEN 236U -#define DHCP_OPTIONS_OFS (DHCP_MSG_LEN + 4U) /* 4 byte: cookie */ - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -/** minimum set of fields of any DHCP message */ -struct dhcp_msg -{ - PACK_STRUCT_FLD_8(u8_t op); - PACK_STRUCT_FLD_8(u8_t htype); - PACK_STRUCT_FLD_8(u8_t hlen); - PACK_STRUCT_FLD_8(u8_t hops); - PACK_STRUCT_FIELD(u32_t xid); - PACK_STRUCT_FIELD(u16_t secs); - PACK_STRUCT_FIELD(u16_t flags); - PACK_STRUCT_FLD_S(ip4_addr_p_t ciaddr); - PACK_STRUCT_FLD_S(ip4_addr_p_t yiaddr); - PACK_STRUCT_FLD_S(ip4_addr_p_t siaddr); - PACK_STRUCT_FLD_S(ip4_addr_p_t giaddr); - PACK_STRUCT_FLD_8(u8_t chaddr[DHCP_CHADDR_LEN]); - PACK_STRUCT_FLD_8(u8_t sname[DHCP_SNAME_LEN]); - PACK_STRUCT_FLD_8(u8_t file[DHCP_FILE_LEN]); - PACK_STRUCT_FIELD(u32_t cookie); -#define DHCP_MIN_OPTIONS_LEN 68U -/** make sure user does not configure this too small */ -#if ((defined(DHCP_OPTIONS_LEN)) && (DHCP_OPTIONS_LEN < DHCP_MIN_OPTIONS_LEN)) -# undef DHCP_OPTIONS_LEN -#endif -/** allow this to be configured in lwipopts.h, but not too small */ -#if (!defined(DHCP_OPTIONS_LEN)) -/** set this to be sufficient for your options in outgoing DHCP msgs */ -# define DHCP_OPTIONS_LEN DHCP_MIN_OPTIONS_LEN -#endif - PACK_STRUCT_FLD_8(u8_t options[DHCP_OPTIONS_LEN]); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - - -/* DHCP client states */ -typedef enum { - DHCP_STATE_OFF = 0, - DHCP_STATE_REQUESTING = 1, - DHCP_STATE_INIT = 2, - DHCP_STATE_REBOOTING = 3, - DHCP_STATE_REBINDING = 4, - DHCP_STATE_RENEWING = 5, - DHCP_STATE_SELECTING = 6, - DHCP_STATE_INFORMING = 7, - DHCP_STATE_CHECKING = 8, - DHCP_STATE_PERMANENT = 9, /* not yet implemented */ - DHCP_STATE_BOUND = 10, - DHCP_STATE_RELEASING = 11, /* not yet implemented */ - DHCP_STATE_BACKING_OFF = 12 -} dhcp_state_enum_t; - -/* DHCP op codes */ -#define DHCP_BOOTREQUEST 1 -#define DHCP_BOOTREPLY 2 - -/* DHCP message types */ -#define DHCP_DISCOVER 1 -#define DHCP_OFFER 2 -#define DHCP_REQUEST 3 -#define DHCP_DECLINE 4 -#define DHCP_ACK 5 -#define DHCP_NAK 6 -#define DHCP_RELEASE 7 -#define DHCP_INFORM 8 - -#define DHCP_MAGIC_COOKIE 0x63825363UL - -/* This is a list of options for BOOTP and DHCP, see RFC 2132 for descriptions */ - -/* BootP options */ -#define DHCP_OPTION_PAD 0 -#define DHCP_OPTION_SUBNET_MASK 1 /* RFC 2132 3.3 */ -#define DHCP_OPTION_ROUTER 3 -#define DHCP_OPTION_DNS_SERVER 6 -#define DHCP_OPTION_HOSTNAME 12 -#define DHCP_OPTION_IP_TTL 23 -#define DHCP_OPTION_MTU 26 -#define DHCP_OPTION_BROADCAST 28 -#define DHCP_OPTION_TCP_TTL 37 -#define DHCP_OPTION_NTP 42 -#define DHCP_OPTION_END 255 - -/* DHCP options */ -#define DHCP_OPTION_REQUESTED_IP 50 /* RFC 2132 9.1, requested IP address */ -#define DHCP_OPTION_LEASE_TIME 51 /* RFC 2132 9.2, time in seconds, in 4 bytes */ -#define DHCP_OPTION_OVERLOAD 52 /* RFC2132 9.3, use file and/or sname field for options */ - -#define DHCP_OPTION_MESSAGE_TYPE 53 /* RFC 2132 9.6, important for DHCP */ -#define DHCP_OPTION_MESSAGE_TYPE_LEN 1 - -#define DHCP_OPTION_SERVER_ID 54 /* RFC 2132 9.7, server IP address */ -#define DHCP_OPTION_PARAMETER_REQUEST_LIST 55 /* RFC 2132 9.8, requested option types */ - -#define DHCP_OPTION_MAX_MSG_SIZE 57 /* RFC 2132 9.10, message size accepted >= 576 */ -#define DHCP_OPTION_MAX_MSG_SIZE_LEN 2 - -#define DHCP_OPTION_T1 58 /* T1 renewal time */ -#define DHCP_OPTION_T2 59 /* T2 rebinding time */ -#define DHCP_OPTION_US 60 -#define DHCP_OPTION_CLIENT_ID 61 -#define DHCP_OPTION_TFTP_SERVERNAME 66 -#define DHCP_OPTION_BOOTFILE 67 - -/* possible combinations of overloading the file and sname fields with options */ -#define DHCP_OVERLOAD_NONE 0 -#define DHCP_OVERLOAD_FILE 1 -#define DHCP_OVERLOAD_SNAME 2 -#define DHCP_OVERLOAD_SNAME_FILE 3 - - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_PROT_DHCP_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/prot/dhcp6.h b/third-party/lwip-2.1.2/include/lwip/prot/dhcp6.h deleted file mode 100644 index 0754c91b..00000000 --- a/third-party/lwip-2.1.2/include/lwip/prot/dhcp6.h +++ /dev/null @@ -1,138 +0,0 @@ -/** - * @file - * DHCPv6 protocol definitions - */ - -/* - * Copyright (c) 2017 Simon Goldschmidt - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Simon Goldschmidt - * - */ -#ifndef LWIP_HDR_PROT_DHCP6_H -#define LWIP_HDR_PROT_DHCP6_H - -#include "lwip/opt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define DHCP6_CLIENT_PORT 546 -#define DHCP6_SERVER_PORT 547 - - - /* DHCPv6 message item offsets and length */ -#define DHCP6_TRANSACTION_ID_LEN 3 - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -/** minimum set of fields of any DHCPv6 message */ -struct dhcp6_msg -{ - PACK_STRUCT_FLD_8(u8_t msgtype); - PACK_STRUCT_FLD_8(u8_t transaction_id[DHCP6_TRANSACTION_ID_LEN]); - /* options follow */ -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - - -/* DHCP6 client states */ -typedef enum { - DHCP6_STATE_OFF = 0, - DHCP6_STATE_STATELESS_IDLE = 1, - DHCP6_STATE_REQUESTING_CONFIG = 2 -} dhcp6_state_enum_t; - -/* DHCPv6 message types */ -#define DHCP6_SOLICIT 1 -#define DHCP6_ADVERTISE 2 -#define DHCP6_REQUEST 3 -#define DHCP6_CONFIRM 4 -#define DHCP6_RENEW 5 -#define DHCP6_REBIND 6 -#define DHCP6_REPLY 7 -#define DHCP6_RELEASE 8 -#define DHCP6_DECLINE 9 -#define DHCP6_RECONFIGURE 10 -#define DHCP6_INFOREQUEST 11 -#define DHCP6_RELAYFORW 12 -#define DHCP6_RELAYREPL 13 -/* More message types see https://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml */ - -/** DHCPv6 status codes */ -#define DHCP6_STATUS_SUCCESS 0 /* Success. */ -#define DHCP6_STATUS_UNSPECFAIL 1 /* Failure, reason unspecified; this status code is sent by either a client or a server to indicate a failure not explicitly specified in this document. */ -#define DHCP6_STATUS_NOADDRSAVAIL 2 /* Server has no addresses available to assign to the IA(s). */ -#define DHCP6_STATUS_NOBINDING 3 /* Client record (binding) unavailable. */ -#define DHCP6_STATUS_NOTONLINK 4 /* The prefix for the address is not appropriate for the link to which the client is attached. */ -#define DHCP6_STATUS_USEMULTICAST 5 /* Sent by a server to a client to force the client to send messages to the server using the All_DHCP_Relay_Agents_and_Servers address. */ -/* More status codes see https://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml */ - -/** DHCPv6 DUID types */ -#define DHCP6_DUID_LLT 1 /* LLT: Link-layer Address Plus Time */ -#define DHCP6_DUID_EN 2 /* EN: Enterprise number */ -#define DHCP6_DUID_LL 3 /* LL: Link-layer Address */ -#define DHCP6_DUID_UUID 4 /* UUID (RFC 6355) */ - -/* DHCPv6 options */ -#define DHCP6_OPTION_CLIENTID 1 -#define DHCP6_OPTION_SERVERID 2 -#define DHCP6_OPTION_IA_NA 3 -#define DHCP6_OPTION_IA_TA 4 -#define DHCP6_OPTION_IAADDR 5 -#define DHCP6_OPTION_ORO 6 -#define DHCP6_OPTION_PREFERENCE 7 -#define DHCP6_OPTION_ELAPSED_TIME 8 -#define DHCP6_OPTION_RELAY_MSG 9 -#define DHCP6_OPTION_AUTH 11 -#define DHCP6_OPTION_UNICAST 12 -#define DHCP6_OPTION_STATUS_CODE 13 -#define DHCP6_OPTION_RAPID_COMMIT 14 -#define DHCP6_OPTION_USER_CLASS 15 -#define DHCP6_OPTION_VENDOR_CLASS 16 -#define DHCP6_OPTION_VENDOR_OPTS 17 -#define DHCP6_OPTION_INTERFACE_ID 18 -#define DHCP6_OPTION_RECONF_MSG 19 -#define DHCP6_OPTION_RECONF_ACCEPT 20 -/* More options see https://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml */ -#define DHCP6_OPTION_DNS_SERVERS 23 /* RFC 3646 */ -#define DHCP6_OPTION_DOMAIN_LIST 24 /* RFC 3646 */ -#define DHCP6_OPTION_SNTP_SERVERS 31 /* RFC 4075 */ - - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_PROT_DHCP6_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/prot/dns.h b/third-party/lwip-2.1.2/include/lwip/prot/dns.h deleted file mode 100644 index 94782d6e..00000000 --- a/third-party/lwip-2.1.2/include/lwip/prot/dns.h +++ /dev/null @@ -1,140 +0,0 @@ -/** - * @file - * DNS - host name to IP address resolver. - */ - -/* - * Port to lwIP from uIP - * by Jim Pettinato April 2007 - * - * security fixes and more by Simon Goldschmidt - * - * uIP version Copyright (c) 2002-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef LWIP_HDR_PROT_DNS_H -#define LWIP_HDR_PROT_DNS_H - -#include "lwip/arch.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** DNS server port address */ -#ifndef DNS_SERVER_PORT -#define DNS_SERVER_PORT 53 -#endif - -/* DNS field TYPE used for "Resource Records" */ -#define DNS_RRTYPE_A 1 /* a host address */ -#define DNS_RRTYPE_NS 2 /* an authoritative name server */ -#define DNS_RRTYPE_MD 3 /* a mail destination (Obsolete - use MX) */ -#define DNS_RRTYPE_MF 4 /* a mail forwarder (Obsolete - use MX) */ -#define DNS_RRTYPE_CNAME 5 /* the canonical name for an alias */ -#define DNS_RRTYPE_SOA 6 /* marks the start of a zone of authority */ -#define DNS_RRTYPE_MB 7 /* a mailbox domain name (EXPERIMENTAL) */ -#define DNS_RRTYPE_MG 8 /* a mail group member (EXPERIMENTAL) */ -#define DNS_RRTYPE_MR 9 /* a mail rename domain name (EXPERIMENTAL) */ -#define DNS_RRTYPE_NULL 10 /* a null RR (EXPERIMENTAL) */ -#define DNS_RRTYPE_WKS 11 /* a well known service description */ -#define DNS_RRTYPE_PTR 12 /* a domain name pointer */ -#define DNS_RRTYPE_HINFO 13 /* host information */ -#define DNS_RRTYPE_MINFO 14 /* mailbox or mail list information */ -#define DNS_RRTYPE_MX 15 /* mail exchange */ -#define DNS_RRTYPE_TXT 16 /* text strings */ -#define DNS_RRTYPE_AAAA 28 /* IPv6 address */ -#define DNS_RRTYPE_SRV 33 /* service location */ -#define DNS_RRTYPE_ANY 255 /* any type */ - -/* DNS field CLASS used for "Resource Records" */ -#define DNS_RRCLASS_IN 1 /* the Internet */ -#define DNS_RRCLASS_CS 2 /* the CSNET class (Obsolete - used only for examples in some obsolete RFCs) */ -#define DNS_RRCLASS_CH 3 /* the CHAOS class */ -#define DNS_RRCLASS_HS 4 /* Hesiod [Dyer 87] */ -#define DNS_RRCLASS_ANY 255 /* any class */ -#define DNS_RRCLASS_FLUSH 0x800 /* Flush bit */ - -/* DNS protocol flags */ -#define DNS_FLAG1_RESPONSE 0x80 -#define DNS_FLAG1_OPCODE_STATUS 0x10 -#define DNS_FLAG1_OPCODE_INVERSE 0x08 -#define DNS_FLAG1_OPCODE_STANDARD 0x00 -#define DNS_FLAG1_AUTHORATIVE 0x04 -#define DNS_FLAG1_TRUNC 0x02 -#define DNS_FLAG1_RD 0x01 -#define DNS_FLAG2_RA 0x80 -#define DNS_FLAG2_ERR_MASK 0x0f -#define DNS_FLAG2_ERR_NONE 0x00 -#define DNS_FLAG2_ERR_NAME 0x03 - -#define DNS_HDR_GET_OPCODE(hdr) ((((hdr)->flags1) >> 3) & 0xF) - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -/** DNS message header */ -struct dns_hdr { - PACK_STRUCT_FIELD(u16_t id); - PACK_STRUCT_FLD_8(u8_t flags1); - PACK_STRUCT_FLD_8(u8_t flags2); - PACK_STRUCT_FIELD(u16_t numquestions); - PACK_STRUCT_FIELD(u16_t numanswers); - PACK_STRUCT_FIELD(u16_t numauthrr); - PACK_STRUCT_FIELD(u16_t numextrarr); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif -#define SIZEOF_DNS_HDR 12 - - -/* Multicast DNS definitions */ - -/** UDP port for multicast DNS queries */ -#ifndef DNS_MQUERY_PORT -#define DNS_MQUERY_PORT 5353 -#endif - -/* IPv4 group for multicast DNS queries: 224.0.0.251 */ -#ifndef DNS_MQUERY_IPV4_GROUP_INIT -#define DNS_MQUERY_IPV4_GROUP_INIT IPADDR4_INIT_BYTES(224,0,0,251) -#endif - -/* IPv6 group for multicast DNS queries: FF02::FB */ -#ifndef DNS_MQUERY_IPV6_GROUP_INIT -#define DNS_MQUERY_IPV6_GROUP_INIT IPADDR6_INIT_HOST(0xFF020000,0,0,0xFB) -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_PROT_DNS_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/prot/etharp.h b/third-party/lwip-2.1.2/include/lwip/prot/etharp.h deleted file mode 100644 index 811c2284..00000000 --- a/third-party/lwip-2.1.2/include/lwip/prot/etharp.h +++ /dev/null @@ -1,114 +0,0 @@ -/** - * @file - * ARP protocol definitions - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_PROT_ETHARP_H -#define LWIP_HDR_PROT_ETHARP_H - -#include "lwip/arch.h" -#include "lwip/prot/ethernet.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef ETHARP_HWADDR_LEN -#define ETHARP_HWADDR_LEN ETH_HWADDR_LEN -#endif - -/** - * struct ip4_addr_wordaligned is used in the definition of the ARP packet format in - * order to support compilers that don't have structure packing. - */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ip4_addr_wordaligned { - PACK_STRUCT_FIELD(u16_t addrw[2]); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** MEMCPY-like copying of IP addresses where addresses are known to be - * 16-bit-aligned if the port is correctly configured (so a port could define - * this to copying 2 u16_t's) - no NULL-pointer-checking needed. */ -#ifndef IPADDR_WORDALIGNED_COPY_TO_IP4_ADDR_T -#define IPADDR_WORDALIGNED_COPY_TO_IP4_ADDR_T(dest, src) SMEMCPY(dest, src, sizeof(ip4_addr_t)) -#endif - - /** MEMCPY-like copying of IP addresses where addresses are known to be - * 16-bit-aligned if the port is correctly configured (so a port could define - * this to copying 2 u16_t's) - no NULL-pointer-checking needed. */ -#ifndef IPADDR_WORDALIGNED_COPY_FROM_IP4_ADDR_T -#define IPADDR_WORDALIGNED_COPY_FROM_IP4_ADDR_T(dest, src) SMEMCPY(dest, src, sizeof(ip4_addr_t)) -#endif - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -/** the ARP message, see RFC 826 ("Packet format") */ -struct etharp_hdr { - PACK_STRUCT_FIELD(u16_t hwtype); - PACK_STRUCT_FIELD(u16_t proto); - PACK_STRUCT_FLD_8(u8_t hwlen); - PACK_STRUCT_FLD_8(u8_t protolen); - PACK_STRUCT_FIELD(u16_t opcode); - PACK_STRUCT_FLD_S(struct eth_addr shwaddr); - PACK_STRUCT_FLD_S(struct ip4_addr_wordaligned sipaddr); - PACK_STRUCT_FLD_S(struct eth_addr dhwaddr); - PACK_STRUCT_FLD_S(struct ip4_addr_wordaligned dipaddr); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#define SIZEOF_ETHARP_HDR 28 - -/* ARP message types (opcodes) */ -enum etharp_opcode { - ARP_REQUEST = 1, - ARP_REPLY = 2 -}; - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_PROT_ETHARP_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/prot/ethernet.h b/third-party/lwip-2.1.2/include/lwip/prot/ethernet.h deleted file mode 100644 index 309e5746..00000000 --- a/third-party/lwip-2.1.2/include/lwip/prot/ethernet.h +++ /dev/null @@ -1,125 +0,0 @@ -/** - * @file - * Ethernet protocol definitions - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_PROT_ETHERNET_H -#define LWIP_HDR_PROT_ETHERNET_H - -#include "lwip/arch.h" -#include "lwip/prot/ieee.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef ETH_HWADDR_LEN -#ifdef ETHARP_HWADDR_LEN -#define ETH_HWADDR_LEN ETHARP_HWADDR_LEN /* compatibility mode */ -#else -#define ETH_HWADDR_LEN 6 -#endif -#endif - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -/** An Ethernet MAC address */ -struct eth_addr { - PACK_STRUCT_FLD_8(u8_t addr[ETH_HWADDR_LEN]); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** Initialize a struct eth_addr with its 6 bytes (takes care of correct braces) */ -#define ETH_ADDR(b0, b1, b2, b3, b4, b5) {{b0, b1, b2, b3, b4, b5}} - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -/** Ethernet header */ -struct eth_hdr { -#if ETH_PAD_SIZE - PACK_STRUCT_FLD_8(u8_t padding[ETH_PAD_SIZE]); -#endif - PACK_STRUCT_FLD_S(struct eth_addr dest); - PACK_STRUCT_FLD_S(struct eth_addr src); - PACK_STRUCT_FIELD(u16_t type); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#define SIZEOF_ETH_HDR (14 + ETH_PAD_SIZE) - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -/** VLAN header inserted between ethernet header and payload - * if 'type' in ethernet header is ETHTYPE_VLAN. - * See IEEE802.Q */ -struct eth_vlan_hdr { - PACK_STRUCT_FIELD(u16_t prio_vid); - PACK_STRUCT_FIELD(u16_t tpid); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#define SIZEOF_VLAN_HDR 4 -#define VLAN_ID(vlan_hdr) (lwip_htons((vlan_hdr)->prio_vid) & 0xFFF) - -/** The 24-bit IANA IPv4-multicast OUI is 01-00-5e: */ -#define LL_IP4_MULTICAST_ADDR_0 0x01 -#define LL_IP4_MULTICAST_ADDR_1 0x00 -#define LL_IP4_MULTICAST_ADDR_2 0x5e - -/** IPv6 multicast uses this prefix */ -#define LL_IP6_MULTICAST_ADDR_0 0x33 -#define LL_IP6_MULTICAST_ADDR_1 0x33 - -#define eth_addr_cmp(addr1, addr2) (memcmp((addr1)->addr, (addr2)->addr, ETH_HWADDR_LEN) == 0) - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_PROT_ETHERNET_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/prot/iana.h b/third-party/lwip-2.1.2/include/lwip/prot/iana.h deleted file mode 100644 index 32890ccc..00000000 --- a/third-party/lwip-2.1.2/include/lwip/prot/iana.h +++ /dev/null @@ -1,97 +0,0 @@ -/** - * @file - * IANA assigned numbers (RFC 1700 and successors) - * - * @defgroup iana IANA assigned numbers - * @ingroup infrastructure - */ - -/* - * Copyright (c) 2017 Dirk Ziegelmeier. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Dirk Ziegelmeier - * - */ - -#ifndef LWIP_HDR_PROT_IANA_H -#define LWIP_HDR_PROT_IANA_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @ingroup iana - * Hardware types - */ -enum lwip_iana_hwtype { - /** Ethernet */ - LWIP_IANA_HWTYPE_ETHERNET = 1 -}; - -/** - * @ingroup iana - * Port numbers - * https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.txt - */ -enum lwip_iana_port_number { - /** SMTP */ - LWIP_IANA_PORT_SMTP = 25, - /** DHCP server */ - LWIP_IANA_PORT_DHCP_SERVER = 67, - /** DHCP client */ - LWIP_IANA_PORT_DHCP_CLIENT = 68, - /** TFTP */ - LWIP_IANA_PORT_TFTP = 69, - /** HTTP */ - LWIP_IANA_PORT_HTTP = 80, - /** SNTP */ - LWIP_IANA_PORT_SNTP = 123, - /** NETBIOS */ - LWIP_IANA_PORT_NETBIOS = 137, - /** SNMP */ - LWIP_IANA_PORT_SNMP = 161, - /** SNMP traps */ - LWIP_IANA_PORT_SNMP_TRAP = 162, - /** HTTPS */ - LWIP_IANA_PORT_HTTPS = 443, - /** SMTPS */ - LWIP_IANA_PORT_SMTPS = 465, - /** MQTT */ - LWIP_IANA_PORT_MQTT = 1883, - /** MDNS */ - LWIP_IANA_PORT_MDNS = 5353, - /** Secure MQTT */ - LWIP_IANA_PORT_SECURE_MQTT = 8883 -}; - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_PROT_IANA_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/prot/icmp.h b/third-party/lwip-2.1.2/include/lwip/prot/icmp.h deleted file mode 100644 index 7d19385c..00000000 --- a/third-party/lwip-2.1.2/include/lwip/prot/icmp.h +++ /dev/null @@ -1,91 +0,0 @@ -/** - * @file - * ICMP protocol definitions - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_PROT_ICMP_H -#define LWIP_HDR_PROT_ICMP_H - -#include "lwip/arch.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define ICMP_ER 0 /* echo reply */ -#define ICMP_DUR 3 /* destination unreachable */ -#define ICMP_SQ 4 /* source quench */ -#define ICMP_RD 5 /* redirect */ -#define ICMP_ECHO 8 /* echo */ -#define ICMP_TE 11 /* time exceeded */ -#define ICMP_PP 12 /* parameter problem */ -#define ICMP_TS 13 /* timestamp */ -#define ICMP_TSR 14 /* timestamp reply */ -#define ICMP_IRQ 15 /* information request */ -#define ICMP_IR 16 /* information reply */ -#define ICMP_AM 17 /* address mask request */ -#define ICMP_AMR 18 /* address mask reply */ - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -/** This is the standard ICMP header only that the u32_t data - * is split to two u16_t like ICMP echo needs it. - * This header is also used for other ICMP types that do not - * use the data part. - */ -PACK_STRUCT_BEGIN -struct icmp_echo_hdr { - PACK_STRUCT_FLD_8(u8_t type); - PACK_STRUCT_FLD_8(u8_t code); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FIELD(u16_t id); - PACK_STRUCT_FIELD(u16_t seqno); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/* Compatibility defines, old versions used to combine type and code to an u16_t */ -#define ICMPH_TYPE(hdr) ((hdr)->type) -#define ICMPH_CODE(hdr) ((hdr)->code) -#define ICMPH_TYPE_SET(hdr, t) ((hdr)->type = (t)) -#define ICMPH_CODE_SET(hdr, c) ((hdr)->code = (c)) - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_PROT_ICMP_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/prot/icmp6.h b/third-party/lwip-2.1.2/include/lwip/prot/icmp6.h deleted file mode 100644 index 34611204..00000000 --- a/third-party/lwip-2.1.2/include/lwip/prot/icmp6.h +++ /dev/null @@ -1,170 +0,0 @@ -/** - * @file - * ICMP6 protocol definitions - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_PROT_ICMP6_H -#define LWIP_HDR_PROT_ICMP6_H - -#include "lwip/arch.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** ICMP type */ -enum icmp6_type { - /** Destination unreachable */ - ICMP6_TYPE_DUR = 1, - /** Packet too big */ - ICMP6_TYPE_PTB = 2, - /** Time exceeded */ - ICMP6_TYPE_TE = 3, - /** Parameter problem */ - ICMP6_TYPE_PP = 4, - /** Private experimentation */ - ICMP6_TYPE_PE1 = 100, - /** Private experimentation */ - ICMP6_TYPE_PE2 = 101, - /** Reserved for expansion of error messages */ - ICMP6_TYPE_RSV_ERR = 127, - - /** Echo request */ - ICMP6_TYPE_EREQ = 128, - /** Echo reply */ - ICMP6_TYPE_EREP = 129, - /** Multicast listener query */ - ICMP6_TYPE_MLQ = 130, - /** Multicast listener report */ - ICMP6_TYPE_MLR = 131, - /** Multicast listener done */ - ICMP6_TYPE_MLD = 132, - /** Router solicitation */ - ICMP6_TYPE_RS = 133, - /** Router advertisement */ - ICMP6_TYPE_RA = 134, - /** Neighbor solicitation */ - ICMP6_TYPE_NS = 135, - /** Neighbor advertisement */ - ICMP6_TYPE_NA = 136, - /** Redirect */ - ICMP6_TYPE_RD = 137, - /** Multicast router advertisement */ - ICMP6_TYPE_MRA = 151, - /** Multicast router solicitation */ - ICMP6_TYPE_MRS = 152, - /** Multicast router termination */ - ICMP6_TYPE_MRT = 153, - /** Private experimentation */ - ICMP6_TYPE_PE3 = 200, - /** Private experimentation */ - ICMP6_TYPE_PE4 = 201, - /** Reserved for expansion of informational messages */ - ICMP6_TYPE_RSV_INF = 255 -}; - -/** ICMP destination unreachable codes */ -enum icmp6_dur_code { - /** No route to destination */ - ICMP6_DUR_NO_ROUTE = 0, - /** Communication with destination administratively prohibited */ - ICMP6_DUR_PROHIBITED = 1, - /** Beyond scope of source address */ - ICMP6_DUR_SCOPE = 2, - /** Address unreachable */ - ICMP6_DUR_ADDRESS = 3, - /** Port unreachable */ - ICMP6_DUR_PORT = 4, - /** Source address failed ingress/egress policy */ - ICMP6_DUR_POLICY = 5, - /** Reject route to destination */ - ICMP6_DUR_REJECT_ROUTE = 6 -}; - -/** ICMP time exceeded codes */ -enum icmp6_te_code { - /** Hop limit exceeded in transit */ - ICMP6_TE_HL = 0, - /** Fragment reassembly time exceeded */ - ICMP6_TE_FRAG = 1 -}; - -/** ICMP parameter code */ -enum icmp6_pp_code { - /** Erroneous header field encountered */ - ICMP6_PP_FIELD = 0, - /** Unrecognized next header type encountered */ - ICMP6_PP_HEADER = 1, - /** Unrecognized IPv6 option encountered */ - ICMP6_PP_OPTION = 2 -}; - -/** This is the standard ICMP6 header. */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct icmp6_hdr { - PACK_STRUCT_FLD_8(u8_t type); - PACK_STRUCT_FLD_8(u8_t code); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FIELD(u32_t data); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** This is the ICMP6 header adapted for echo req/resp. */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct icmp6_echo_hdr { - PACK_STRUCT_FLD_8(u8_t type); - PACK_STRUCT_FLD_8(u8_t code); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FIELD(u16_t id); - PACK_STRUCT_FIELD(u16_t seqno); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_PROT_ICMP6_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/prot/ieee.h b/third-party/lwip-2.1.2/include/lwip/prot/ieee.h deleted file mode 100644 index abbb9e31..00000000 --- a/third-party/lwip-2.1.2/include/lwip/prot/ieee.h +++ /dev/null @@ -1,91 +0,0 @@ -/** - * @file - * IEEE assigned numbers - * - * @defgroup ieee IEEE assigned numbers - * @ingroup infrastructure - */ - -/* - * Copyright (c) 2017 Dirk Ziegelmeier. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Dirk Ziegelmeier - * - */ - -#ifndef LWIP_HDR_PROT_IEEE_H -#define LWIP_HDR_PROT_IEEE_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @ingroup ieee - * A list of often ethtypes (although lwIP does not use all of them). - */ -enum lwip_ieee_eth_type { - /** Internet protocol v4 */ - ETHTYPE_IP = 0x0800U, - /** Address resolution protocol */ - ETHTYPE_ARP = 0x0806U, - /** Wake on lan */ - ETHTYPE_WOL = 0x0842U, - /** RARP */ - ETHTYPE_RARP = 0x8035U, - /** Virtual local area network */ - ETHTYPE_VLAN = 0x8100U, - /** Internet protocol v6 */ - ETHTYPE_IPV6 = 0x86DDU, - /** PPP Over Ethernet Discovery Stage */ - ETHTYPE_PPPOEDISC = 0x8863U, - /** PPP Over Ethernet Session Stage */ - ETHTYPE_PPPOE = 0x8864U, - /** Jumbo Frames */ - ETHTYPE_JUMBO = 0x8870U, - /** Process field network */ - ETHTYPE_PROFINET = 0x8892U, - /** Ethernet for control automation technology */ - ETHTYPE_ETHERCAT = 0x88A4U, - /** Link layer discovery protocol */ - ETHTYPE_LLDP = 0x88CCU, - /** Serial real-time communication system */ - ETHTYPE_SERCOS = 0x88CDU, - /** Media redundancy protocol */ - ETHTYPE_MRP = 0x88E3U, - /** Precision time protocol */ - ETHTYPE_PTP = 0x88F7U, - /** Q-in-Q, 802.1ad */ - ETHTYPE_QINQ = 0x9100U -}; - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_PROT_IEEE_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/prot/igmp.h b/third-party/lwip-2.1.2/include/lwip/prot/igmp.h deleted file mode 100644 index 46b81a9d..00000000 --- a/third-party/lwip-2.1.2/include/lwip/prot/igmp.h +++ /dev/null @@ -1,90 +0,0 @@ -/** - * @file - * IGMP protocol definitions - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_PROT_IGMP_H -#define LWIP_HDR_PROT_IGMP_H - -#include "lwip/arch.h" -#include "lwip/prot/ip4.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * IGMP constants - */ -#define IGMP_TTL 1 -#define IGMP_MINLEN 8 -#define ROUTER_ALERT 0x9404U -#define ROUTER_ALERTLEN 4 - -/* - * IGMP message types, including version number. - */ -#define IGMP_MEMB_QUERY 0x11 /* Membership query */ -#define IGMP_V1_MEMB_REPORT 0x12 /* Ver. 1 membership report */ -#define IGMP_V2_MEMB_REPORT 0x16 /* Ver. 2 membership report */ -#define IGMP_LEAVE_GROUP 0x17 /* Leave-group message */ - -/* Group membership states */ -#define IGMP_GROUP_NON_MEMBER 0 -#define IGMP_GROUP_DELAYING_MEMBER 1 -#define IGMP_GROUP_IDLE_MEMBER 2 - -/** - * IGMP packet format. - */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct igmp_msg { - PACK_STRUCT_FLD_8(u8_t igmp_msgtype); - PACK_STRUCT_FLD_8(u8_t igmp_maxresp); - PACK_STRUCT_FIELD(u16_t igmp_checksum); - PACK_STRUCT_FLD_S(ip4_addr_p_t igmp_group_address); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_PROT_IGMP_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/prot/ip.h b/third-party/lwip-2.1.2/include/lwip/prot/ip.h deleted file mode 100644 index 223158f5..00000000 --- a/third-party/lwip-2.1.2/include/lwip/prot/ip.h +++ /dev/null @@ -1,59 +0,0 @@ -/** - * @file - * IP protocol definitions - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_PROT_IP_H -#define LWIP_HDR_PROT_IP_H - -#include "lwip/arch.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define IP_PROTO_ICMP 1 -#define IP_PROTO_IGMP 2 -#define IP_PROTO_UDP 17 -#define IP_PROTO_UDPLITE 136 -#define IP_PROTO_TCP 6 - -/** This operates on a void* by loading the first byte */ -#define IP_HDR_GET_VERSION(ptr) ((*(u8_t*)(ptr)) >> 4) - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_PROT_IP_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/prot/ip4.h b/third-party/lwip-2.1.2/include/lwip/prot/ip4.h deleted file mode 100644 index 93474611..00000000 --- a/third-party/lwip-2.1.2/include/lwip/prot/ip4.h +++ /dev/null @@ -1,131 +0,0 @@ -/** - * @file - * IPv4 protocol definitions - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_PROT_IP4_H -#define LWIP_HDR_PROT_IP4_H - -#include "lwip/arch.h" -#include "lwip/ip4_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** This is the packed version of ip4_addr_t, - used in network headers that are itself packed */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ip4_addr_packed { - PACK_STRUCT_FIELD(u32_t addr); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -typedef struct ip4_addr_packed ip4_addr_p_t; - -/* Size of the IPv4 header. Same as 'sizeof(struct ip_hdr)'. */ -#define IP_HLEN 20 -/* Maximum size of the IPv4 header with options. */ -#define IP_HLEN_MAX 60 - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -/* The IPv4 header */ -struct ip_hdr { - /* version / header length */ - PACK_STRUCT_FLD_8(u8_t _v_hl); - /* type of service */ - PACK_STRUCT_FLD_8(u8_t _tos); - /* total length */ - PACK_STRUCT_FIELD(u16_t _len); - /* identification */ - PACK_STRUCT_FIELD(u16_t _id); - /* fragment offset field */ - PACK_STRUCT_FIELD(u16_t _offset); -#define IP_RF 0x8000U /* reserved fragment flag */ -#define IP_DF 0x4000U /* don't fragment flag */ -#define IP_MF 0x2000U /* more fragments flag */ -#define IP_OFFMASK 0x1fffU /* mask for fragmenting bits */ - /* time to live */ - PACK_STRUCT_FLD_8(u8_t _ttl); - /* protocol*/ - PACK_STRUCT_FLD_8(u8_t _proto); - /* checksum */ - PACK_STRUCT_FIELD(u16_t _chksum); - /* source and destination IP addresses */ - PACK_STRUCT_FLD_S(ip4_addr_p_t src); - PACK_STRUCT_FLD_S(ip4_addr_p_t dest); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/* Macros to get struct ip_hdr fields: */ -#define IPH_V(hdr) ((hdr)->_v_hl >> 4) -#define IPH_HL(hdr) ((hdr)->_v_hl & 0x0f) -#define IPH_HL_BYTES(hdr) ((u8_t)(IPH_HL(hdr) * 4)) -#define IPH_TOS(hdr) ((hdr)->_tos) -#define IPH_LEN(hdr) ((hdr)->_len) -#define IPH_ID(hdr) ((hdr)->_id) -#define IPH_OFFSET(hdr) ((hdr)->_offset) -#define IPH_OFFSET_BYTES(hdr) ((u16_t)((lwip_ntohs(IPH_OFFSET(hdr)) & IP_OFFMASK) * 8U)) -#define IPH_TTL(hdr) ((hdr)->_ttl) -#define IPH_PROTO(hdr) ((hdr)->_proto) -#define IPH_CHKSUM(hdr) ((hdr)->_chksum) - -/* Macros to set struct ip_hdr fields: */ -#define IPH_VHL_SET(hdr, v, hl) (hdr)->_v_hl = (u8_t)((((v) << 4) | (hl))) -#define IPH_TOS_SET(hdr, tos) (hdr)->_tos = (tos) -#define IPH_LEN_SET(hdr, len) (hdr)->_len = (len) -#define IPH_ID_SET(hdr, id) (hdr)->_id = (id) -#define IPH_OFFSET_SET(hdr, off) (hdr)->_offset = (off) -#define IPH_TTL_SET(hdr, ttl) (hdr)->_ttl = (u8_t)(ttl) -#define IPH_PROTO_SET(hdr, proto) (hdr)->_proto = (u8_t)(proto) -#define IPH_CHKSUM_SET(hdr, chksum) (hdr)->_chksum = (chksum) - - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_PROT_IP4_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/prot/ip6.h b/third-party/lwip-2.1.2/include/lwip/prot/ip6.h deleted file mode 100644 index 0f6de455..00000000 --- a/third-party/lwip-2.1.2/include/lwip/prot/ip6.h +++ /dev/null @@ -1,233 +0,0 @@ -/** - * @file - * IPv6 protocol definitions - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_PROT_IP6_H -#define LWIP_HDR_PROT_IP6_H - -#include "lwip/arch.h" -#include "lwip/ip6_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** This is the packed version of ip6_addr_t, - used in network headers that are itself packed */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ip6_addr_packed { - PACK_STRUCT_FIELD(u32_t addr[4]); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif -typedef struct ip6_addr_packed ip6_addr_p_t; - -#define IP6_HLEN 40 - -#define IP6_NEXTH_HOPBYHOP 0 -#define IP6_NEXTH_TCP 6 -#define IP6_NEXTH_UDP 17 -#define IP6_NEXTH_ENCAPS 41 -#define IP6_NEXTH_ROUTING 43 -#define IP6_NEXTH_FRAGMENT 44 -#define IP6_NEXTH_ICMP6 58 -#define IP6_NEXTH_NONE 59 -#define IP6_NEXTH_DESTOPTS 60 -#define IP6_NEXTH_UDPLITE 136 - -/** The IPv6 header. */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ip6_hdr { - /** version / traffic class / flow label */ - PACK_STRUCT_FIELD(u32_t _v_tc_fl); - /** payload length */ - PACK_STRUCT_FIELD(u16_t _plen); - /** next header */ - PACK_STRUCT_FLD_8(u8_t _nexth); - /** hop limit */ - PACK_STRUCT_FLD_8(u8_t _hoplim); - /** source and destination IP addresses */ - PACK_STRUCT_FLD_S(ip6_addr_p_t src); - PACK_STRUCT_FLD_S(ip6_addr_p_t dest); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif -#define IP6H_V(hdr) ((lwip_ntohl((hdr)->_v_tc_fl) >> 28) & 0x0f) -#define IP6H_TC(hdr) ((lwip_ntohl((hdr)->_v_tc_fl) >> 20) & 0xff) -#define IP6H_FL(hdr) (lwip_ntohl((hdr)->_v_tc_fl) & 0x000fffff) -#define IP6H_PLEN(hdr) (lwip_ntohs((hdr)->_plen)) -#define IP6H_NEXTH(hdr) ((hdr)->_nexth) -#define IP6H_NEXTH_P(hdr) ((u8_t *)(hdr) + 6) -#define IP6H_HOPLIM(hdr) ((hdr)->_hoplim) -#define IP6H_VTCFL_SET(hdr, v, tc, fl) (hdr)->_v_tc_fl = (lwip_htonl((((u32_t)(v)) << 28) | (((u32_t)(tc)) << 20) | (fl))) -#define IP6H_PLEN_SET(hdr, plen) (hdr)->_plen = lwip_htons(plen) -#define IP6H_NEXTH_SET(hdr, nexth) (hdr)->_nexth = (nexth) -#define IP6H_HOPLIM_SET(hdr, hl) (hdr)->_hoplim = (u8_t)(hl) - -/* ipv6 extended options header */ -#define IP6_PAD1_OPTION 0 -#define IP6_PADN_OPTION 1 -#define IP6_ROUTER_ALERT_OPTION 5 -#define IP6_JUMBO_OPTION 194 -#define IP6_HOME_ADDRESS_OPTION 201 -#define IP6_ROUTER_ALERT_DLEN 2 -#define IP6_ROUTER_ALERT_VALUE_MLD 0 - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ip6_opt_hdr { - /* router alert option type */ - PACK_STRUCT_FLD_8(u8_t _opt_type); - /* router alert option data len */ - PACK_STRUCT_FLD_8(u8_t _opt_dlen); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif -#define IP6_OPT_HLEN 2 -#define IP6_OPT_TYPE_ACTION(hdr) ((((hdr)->_opt_type) >> 6) & 0x3) -#define IP6_OPT_TYPE_CHANGE(hdr) ((((hdr)->_opt_type) >> 5) & 0x1) -#define IP6_OPT_TYPE(hdr) ((hdr)->_opt_type) -#define IP6_OPT_DLEN(hdr) ((hdr)->_opt_dlen) - -/* Hop-by-Hop header. */ -#define IP6_HBH_HLEN 2 - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ip6_hbh_hdr { - /* next header */ - PACK_STRUCT_FLD_8(u8_t _nexth); - /* header length in 8-octet units */ - PACK_STRUCT_FLD_8(u8_t _hlen); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif -#define IP6_HBH_NEXTH(hdr) ((hdr)->_nexth) - -/* Destination header. */ -#define IP6_DEST_HLEN 2 - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ip6_dest_hdr { - /* next header */ - PACK_STRUCT_FLD_8(u8_t _nexth); - /* header length in 8-octet units */ - PACK_STRUCT_FLD_8(u8_t _hlen); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif -#define IP6_DEST_NEXTH(hdr) ((hdr)->_nexth) - -/* Routing header */ -#define IP6_ROUT_TYPE2 2 -#define IP6_ROUT_RPL 3 - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ip6_rout_hdr { - /* next header */ - PACK_STRUCT_FLD_8(u8_t _nexth); - /* reserved */ - PACK_STRUCT_FLD_8(u8_t _hlen); - /* fragment offset */ - PACK_STRUCT_FIELD(u8_t _routing_type); - /* fragmented packet identification */ - PACK_STRUCT_FIELD(u8_t _segments_left); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif -#define IP6_ROUT_NEXTH(hdr) ((hdr)->_nexth) -#define IP6_ROUT_TYPE(hdr) ((hdr)->_routing_type) -#define IP6_ROUT_SEG_LEFT(hdr) ((hdr)->_segments_left) - -/* Fragment header. */ -#define IP6_FRAG_HLEN 8 -#define IP6_FRAG_OFFSET_MASK 0xfff8 -#define IP6_FRAG_MORE_FLAG 0x0001 - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ip6_frag_hdr { - /* next header */ - PACK_STRUCT_FLD_8(u8_t _nexth); - /* reserved */ - PACK_STRUCT_FLD_8(u8_t reserved); - /* fragment offset */ - PACK_STRUCT_FIELD(u16_t _fragment_offset); - /* fragmented packet identification */ - PACK_STRUCT_FIELD(u32_t _identification); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif -#define IP6_FRAG_NEXTH(hdr) ((hdr)->_nexth) -#define IP6_FRAG_MBIT(hdr) (lwip_ntohs((hdr)->_fragment_offset) & 0x1) -#define IP6_FRAG_ID(hdr) (lwip_ntohl((hdr)->_identification)) - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_PROT_IP6_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/prot/mld6.h b/third-party/lwip-2.1.2/include/lwip/prot/mld6.h deleted file mode 100644 index 71f1dcbd..00000000 --- a/third-party/lwip-2.1.2/include/lwip/prot/mld6.h +++ /dev/null @@ -1,71 +0,0 @@ -/** - * @file - * MLD6 protocol definitions - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_PROT_MLD6_H -#define LWIP_HDR_PROT_MLD6_H - -#include "lwip/arch.h" -#include "lwip/prot/ip6.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define MLD6_HBH_HLEN 8 -/** Multicast listener report/query/done message header. */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct mld_header { - PACK_STRUCT_FLD_8(u8_t type); - PACK_STRUCT_FLD_8(u8_t code); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FIELD(u16_t max_resp_delay); - PACK_STRUCT_FIELD(u16_t reserved); - PACK_STRUCT_FLD_S(ip6_addr_p_t multicast_address); - /* Options follow. */ -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_PROT_MLD6_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/prot/nd6.h b/third-party/lwip-2.1.2/include/lwip/prot/nd6.h deleted file mode 100644 index c270d07c..00000000 --- a/third-party/lwip-2.1.2/include/lwip/prot/nd6.h +++ /dev/null @@ -1,274 +0,0 @@ -/** - * @file - * ND6 protocol definitions - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_PROT_ND6_H -#define LWIP_HDR_PROT_ND6_H - -#include "lwip/arch.h" -#include "lwip/ip6_addr.h" -#include "lwip/prot/ip6.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** Neighbor solicitation message header. */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ns_header { - PACK_STRUCT_FLD_8(u8_t type); - PACK_STRUCT_FLD_8(u8_t code); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FIELD(u32_t reserved); - PACK_STRUCT_FLD_S(ip6_addr_p_t target_address); - /* Options follow. */ -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** Neighbor advertisement message header. */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct na_header { - PACK_STRUCT_FLD_8(u8_t type); - PACK_STRUCT_FLD_8(u8_t code); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FLD_8(u8_t flags); - PACK_STRUCT_FLD_8(u8_t reserved[3]); - PACK_STRUCT_FLD_S(ip6_addr_p_t target_address); - /* Options follow. */ -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif -#define ND6_FLAG_ROUTER (0x80) -#define ND6_FLAG_SOLICITED (0x40) -#define ND6_FLAG_OVERRIDE (0x20) - -/** Router solicitation message header. */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct rs_header { - PACK_STRUCT_FLD_8(u8_t type); - PACK_STRUCT_FLD_8(u8_t code); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FIELD(u32_t reserved); - /* Options follow. */ -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** Router advertisement message header. */ -#define ND6_RA_FLAG_MANAGED_ADDR_CONFIG (0x80) -#define ND6_RA_FLAG_OTHER_CONFIG (0x40) -#define ND6_RA_FLAG_HOME_AGENT (0x20) -#define ND6_RA_PREFERENCE_MASK (0x18) -#define ND6_RA_PREFERENCE_HIGH (0x08) -#define ND6_RA_PREFERENCE_MEDIUM (0x00) -#define ND6_RA_PREFERENCE_LOW (0x18) -#define ND6_RA_PREFERENCE_DISABLED (0x10) -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ra_header { - PACK_STRUCT_FLD_8(u8_t type); - PACK_STRUCT_FLD_8(u8_t code); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FLD_8(u8_t current_hop_limit); - PACK_STRUCT_FLD_8(u8_t flags); - PACK_STRUCT_FIELD(u16_t router_lifetime); - PACK_STRUCT_FIELD(u32_t reachable_time); - PACK_STRUCT_FIELD(u32_t retrans_timer); - /* Options follow. */ -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** Redirect message header. */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct redirect_header { - PACK_STRUCT_FLD_8(u8_t type); - PACK_STRUCT_FLD_8(u8_t code); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FIELD(u32_t reserved); - PACK_STRUCT_FLD_S(ip6_addr_p_t target_address); - PACK_STRUCT_FLD_S(ip6_addr_p_t destination_address); - /* Options follow. */ -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** Link-layer address option. */ -#define ND6_OPTION_TYPE_SOURCE_LLADDR (0x01) -#define ND6_OPTION_TYPE_TARGET_LLADDR (0x02) -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct lladdr_option { - PACK_STRUCT_FLD_8(u8_t type); - PACK_STRUCT_FLD_8(u8_t length); - PACK_STRUCT_FLD_8(u8_t addr[NETIF_MAX_HWADDR_LEN]); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** Prefix information option. */ -#define ND6_OPTION_TYPE_PREFIX_INFO (0x03) -#define ND6_PREFIX_FLAG_ON_LINK (0x80) -#define ND6_PREFIX_FLAG_AUTONOMOUS (0x40) -#define ND6_PREFIX_FLAG_ROUTER_ADDRESS (0x20) -#define ND6_PREFIX_FLAG_SITE_PREFIX (0x10) -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct prefix_option { - PACK_STRUCT_FLD_8(u8_t type); - PACK_STRUCT_FLD_8(u8_t length); - PACK_STRUCT_FLD_8(u8_t prefix_length); - PACK_STRUCT_FLD_8(u8_t flags); - PACK_STRUCT_FIELD(u32_t valid_lifetime); - PACK_STRUCT_FIELD(u32_t preferred_lifetime); - PACK_STRUCT_FLD_8(u8_t reserved2[3]); - PACK_STRUCT_FLD_8(u8_t site_prefix_length); - PACK_STRUCT_FLD_S(ip6_addr_p_t prefix); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** Redirected header option. */ -#define ND6_OPTION_TYPE_REDIR_HDR (0x04) -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct redirected_header_option { - PACK_STRUCT_FLD_8(u8_t type); - PACK_STRUCT_FLD_8(u8_t length); - PACK_STRUCT_FLD_8(u8_t reserved[6]); - /* Portion of redirected packet follows. */ - /* PACK_STRUCT_FLD_8(u8_t redirected[8]); */ -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** MTU option. */ -#define ND6_OPTION_TYPE_MTU (0x05) -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct mtu_option { - PACK_STRUCT_FLD_8(u8_t type); - PACK_STRUCT_FLD_8(u8_t length); - PACK_STRUCT_FIELD(u16_t reserved); - PACK_STRUCT_FIELD(u32_t mtu); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** Route information option. */ -#define ND6_OPTION_TYPE_ROUTE_INFO (24) -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct route_option { - PACK_STRUCT_FLD_8(u8_t type); - PACK_STRUCT_FLD_8(u8_t length); - PACK_STRUCT_FLD_8(u8_t prefix_length); - PACK_STRUCT_FLD_8(u8_t preference); - PACK_STRUCT_FIELD(u32_t route_lifetime); - PACK_STRUCT_FLD_S(ip6_addr_p_t prefix); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** Recursive DNS Server Option. */ -#define ND6_OPTION_TYPE_RDNSS (25) -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct rdnss_option { - PACK_STRUCT_FLD_8(u8_t type); - PACK_STRUCT_FLD_8(u8_t length); - PACK_STRUCT_FIELD(u16_t reserved); - PACK_STRUCT_FIELD(u32_t lifetime); - PACK_STRUCT_FLD_S(ip6_addr_p_t rdnss_address[1]); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#define SIZEOF_RDNSS_OPTION_BASE 8 /* size without addresses */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_PROT_ND6_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/prot/tcp.h b/third-party/lwip-2.1.2/include/lwip/prot/tcp.h deleted file mode 100644 index c1d7de1f..00000000 --- a/third-party/lwip-2.1.2/include/lwip/prot/tcp.h +++ /dev/null @@ -1,100 +0,0 @@ -/** - * @file - * TCP protocol definitions - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_PROT_TCP_H -#define LWIP_HDR_PROT_TCP_H - -#include "lwip/arch.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Length of the TCP header, excluding options. */ -#define TCP_HLEN 20 - -/* Fields are (of course) in network byte order. - * Some fields are converted to host byte order in tcp_input(). - */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct tcp_hdr { - PACK_STRUCT_FIELD(u16_t src); - PACK_STRUCT_FIELD(u16_t dest); - PACK_STRUCT_FIELD(u32_t seqno); - PACK_STRUCT_FIELD(u32_t ackno); - PACK_STRUCT_FIELD(u16_t _hdrlen_rsvd_flags); - PACK_STRUCT_FIELD(u16_t wnd); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FIELD(u16_t urgp); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/* TCP header flags bits */ -#define TCP_FIN 0x01U -#define TCP_SYN 0x02U -#define TCP_RST 0x04U -#define TCP_PSH 0x08U -#define TCP_ACK 0x10U -#define TCP_URG 0x20U -#define TCP_ECE 0x40U -#define TCP_CWR 0x80U -/* Valid TCP header flags */ -#define TCP_FLAGS 0x3fU - -#define TCP_MAX_OPTION_BYTES 40 - -#define TCPH_HDRLEN(phdr) ((u16_t)(lwip_ntohs((phdr)->_hdrlen_rsvd_flags) >> 12)) -#define TCPH_HDRLEN_BYTES(phdr) ((u8_t)(TCPH_HDRLEN(phdr) << 2)) -#define TCPH_FLAGS(phdr) ((u8_t)((lwip_ntohs((phdr)->_hdrlen_rsvd_flags) & TCP_FLAGS))) - -#define TCPH_HDRLEN_SET(phdr, len) (phdr)->_hdrlen_rsvd_flags = lwip_htons(((len) << 12) | TCPH_FLAGS(phdr)) -#define TCPH_FLAGS_SET(phdr, flags) (phdr)->_hdrlen_rsvd_flags = (((phdr)->_hdrlen_rsvd_flags & PP_HTONS(~TCP_FLAGS)) | lwip_htons(flags)) -#define TCPH_HDRLEN_FLAGS_SET(phdr, len, flags) (phdr)->_hdrlen_rsvd_flags = (u16_t)(lwip_htons((u16_t)((len) << 12) | (flags))) - -#define TCPH_SET_FLAG(phdr, flags ) (phdr)->_hdrlen_rsvd_flags = ((phdr)->_hdrlen_rsvd_flags | lwip_htons(flags)) -#define TCPH_UNSET_FLAG(phdr, flags) (phdr)->_hdrlen_rsvd_flags = ((phdr)->_hdrlen_rsvd_flags & ~lwip_htons(flags)) - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_PROT_TCP_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/prot/udp.h b/third-party/lwip-2.1.2/include/lwip/prot/udp.h deleted file mode 100644 index 664f19a3..00000000 --- a/third-party/lwip-2.1.2/include/lwip/prot/udp.h +++ /dev/null @@ -1,68 +0,0 @@ -/** - * @file - * UDP protocol definitions - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_PROT_UDP_H -#define LWIP_HDR_PROT_UDP_H - -#include "lwip/arch.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define UDP_HLEN 8 - -/* Fields are (of course) in network byte order. */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct udp_hdr { - PACK_STRUCT_FIELD(u16_t src); - PACK_STRUCT_FIELD(u16_t dest); /* src/dest UDP ports */ - PACK_STRUCT_FIELD(u16_t len); - PACK_STRUCT_FIELD(u16_t chksum); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_PROT_UDP_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/raw.h b/third-party/lwip-2.1.2/include/lwip/raw.h deleted file mode 100644 index b129bd3b..00000000 --- a/third-party/lwip-2.1.2/include/lwip/raw.h +++ /dev/null @@ -1,143 +0,0 @@ -/** - * @file - * raw API (to be used from TCPIP thread)\n - * See also @ref raw_raw - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_RAW_H -#define LWIP_HDR_RAW_H - -#include "lwip/opt.h" - -#if LWIP_RAW /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/pbuf.h" -#include "lwip/def.h" -#include "lwip/ip.h" -#include "lwip/ip_addr.h" -#include "lwip/ip6_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define RAW_FLAGS_CONNECTED 0x01U -#define RAW_FLAGS_HDRINCL 0x02U -#define RAW_FLAGS_MULTICAST_LOOP 0x04U - -struct raw_pcb; - -/** Function prototype for raw pcb receive callback functions. - * @param arg user supplied argument (raw_pcb.recv_arg) - * @param pcb the raw_pcb which received data - * @param p the packet buffer that was received - * @param addr the remote IP address from which the packet was received - * @return 1 if the packet was 'eaten' (aka. deleted), - * 0 if the packet lives on - * If returning 1, the callback is responsible for freeing the pbuf - * if it's not used any more. - */ -typedef u8_t (*raw_recv_fn)(void *arg, struct raw_pcb *pcb, struct pbuf *p, - const ip_addr_t *addr); - -/** the RAW protocol control block */ -struct raw_pcb { - /* Common members of all PCB types */ - IP_PCB; - - struct raw_pcb *next; - - u8_t protocol; - u8_t flags; - -#if LWIP_MULTICAST_TX_OPTIONS - /** outgoing network interface for multicast packets, by interface index (if nonzero) */ - u8_t mcast_ifindex; - /** TTL for outgoing multicast packets */ - u8_t mcast_ttl; -#endif /* LWIP_MULTICAST_TX_OPTIONS */ - - /** receive callback function */ - raw_recv_fn recv; - /* user-supplied argument for the recv callback */ - void *recv_arg; -#if LWIP_IPV6 - /* fields for handling checksum computations as per RFC3542. */ - u16_t chksum_offset; - u8_t chksum_reqd; -#endif -}; - -/* The following functions is the application layer interface to the - RAW code. */ -struct raw_pcb * raw_new (u8_t proto); -struct raw_pcb * raw_new_ip_type(u8_t type, u8_t proto); -void raw_remove (struct raw_pcb *pcb); -err_t raw_bind (struct raw_pcb *pcb, const ip_addr_t *ipaddr); -void raw_bind_netif (struct raw_pcb *pcb, const struct netif *netif); -err_t raw_connect (struct raw_pcb *pcb, const ip_addr_t *ipaddr); -void raw_disconnect (struct raw_pcb *pcb); - -err_t raw_sendto (struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *ipaddr); -err_t raw_sendto_if_src(struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip, struct netif *netif, const ip_addr_t *src_ip); -err_t raw_send (struct raw_pcb *pcb, struct pbuf *p); - -void raw_recv (struct raw_pcb *pcb, raw_recv_fn recv, void *recv_arg); - -#define raw_flags(pcb) ((pcb)->flags) -#define raw_setflags(pcb,f) ((pcb)->flags = (f)) - -#define raw_set_flags(pcb, set_flags) do { (pcb)->flags = (u8_t)((pcb)->flags | (set_flags)); } while(0) -#define raw_clear_flags(pcb, clr_flags) do { (pcb)->flags = (u8_t)((pcb)->flags & (u8_t)(~(clr_flags) & 0xff)); } while(0) -#define raw_is_flag_set(pcb, flag) (((pcb)->flags & (flag)) != 0) - -#define raw_init() /* Compatibility define, no init needed. */ - -/* for compatibility with older implementation */ -#define raw_new_ip6(proto) raw_new_ip_type(IPADDR_TYPE_V6, proto) - -#if LWIP_MULTICAST_TX_OPTIONS -#define raw_set_multicast_netif_index(pcb, idx) ((pcb)->mcast_ifindex = (idx)) -#define raw_get_multicast_netif_index(pcb) ((pcb)->mcast_ifindex) -#define raw_set_multicast_ttl(pcb, value) ((pcb)->mcast_ttl = (value)) -#define raw_get_multicast_ttl(pcb) ((pcb)->mcast_ttl) -#endif /* LWIP_MULTICAST_TX_OPTIONS */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_RAW */ - -#endif /* LWIP_HDR_RAW_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/sio.h b/third-party/lwip-2.1.2/include/lwip/sio.h deleted file mode 100644 index 7643e195..00000000 --- a/third-party/lwip-2.1.2/include/lwip/sio.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - */ - -/* - * This is the interface to the platform specific serial IO module - * It needs to be implemented by those platforms which need SLIP or PPP - */ - -#ifndef SIO_H -#define SIO_H - -#include "lwip/arch.h" -#include "lwip/opt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* If you want to define sio_fd_t elsewhere or differently, - define this in your cc.h file. */ -#ifndef __sio_fd_t_defined -typedef void * sio_fd_t; -#endif - -/* The following functions can be defined to something else in your cc.h file - or be implemented in your custom sio.c file. */ - -#ifndef sio_open -/** - * Opens a serial device for communication. - * - * @param devnum device number - * @return handle to serial device if successful, NULL otherwise - */ -sio_fd_t sio_open(u8_t devnum); -#endif - -#ifndef sio_send -/** - * Sends a single character to the serial device. - * - * @param c character to send - * @param fd serial device handle - * - * @note This function will block until the character can be sent. - */ -void sio_send(u8_t c, sio_fd_t fd); -#endif - -#ifndef sio_recv -/** - * Receives a single character from the serial device. - * - * @param fd serial device handle - * - * @note This function will block until a character is received. - */ -u8_t sio_recv(sio_fd_t fd); -#endif - -#ifndef sio_read -/** - * Reads from the serial device. - * - * @param fd serial device handle - * @param data pointer to data buffer for receiving - * @param len maximum length (in bytes) of data to receive - * @return number of bytes actually received - may be 0 if aborted by sio_read_abort - * - * @note This function will block until data can be received. The blocking - * can be cancelled by calling sio_read_abort(). - */ -u32_t sio_read(sio_fd_t fd, u8_t *data, u32_t len); -#endif - -#ifndef sio_tryread -/** - * Tries to read from the serial device. Same as sio_read but returns - * immediately if no data is available and never blocks. - * - * @param fd serial device handle - * @param data pointer to data buffer for receiving - * @param len maximum length (in bytes) of data to receive - * @return number of bytes actually received - */ -u32_t sio_tryread(sio_fd_t fd, u8_t *data, u32_t len); -#endif - -#ifndef sio_write -/** - * Writes to the serial device. - * - * @param fd serial device handle - * @param data pointer to data to send - * @param len length (in bytes) of data to send - * @return number of bytes actually sent - * - * @note This function will block until all data can be sent. - */ -u32_t sio_write(sio_fd_t fd, u8_t *data, u32_t len); -#endif - -#ifndef sio_read_abort -/** - * Aborts a blocking sio_read() call. - * - * @param fd serial device handle - */ -void sio_read_abort(sio_fd_t fd); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* SIO_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/snmp.h b/third-party/lwip-2.1.2/include/lwip/snmp.h deleted file mode 100644 index 8704d0b4..00000000 --- a/third-party/lwip-2.1.2/include/lwip/snmp.h +++ /dev/null @@ -1,213 +0,0 @@ -/** - * @file - * SNMP support API for implementing netifs and statitics for MIB2 - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Dirk Ziegelmeier - * - */ -#ifndef LWIP_HDR_SNMP_H -#define LWIP_HDR_SNMP_H - -#include "lwip/opt.h" -#include "lwip/ip_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct udp_pcb; -struct netif; - -/** - * @defgroup netif_mib2 MIB2 statistics - * @ingroup netif - */ - -/* MIB2 statistics functions */ -#if MIB2_STATS /* don't build if not configured for use in lwipopts.h */ -/** - * @ingroup netif_mib2 - * @see RFC1213, "MIB-II, 6. Definitions" - */ -enum snmp_ifType { - snmp_ifType_other=1, /* none of the following */ - snmp_ifType_regular1822, - snmp_ifType_hdh1822, - snmp_ifType_ddn_x25, - snmp_ifType_rfc877_x25, - snmp_ifType_ethernet_csmacd, - snmp_ifType_iso88023_csmacd, - snmp_ifType_iso88024_tokenBus, - snmp_ifType_iso88025_tokenRing, - snmp_ifType_iso88026_man, - snmp_ifType_starLan, - snmp_ifType_proteon_10Mbit, - snmp_ifType_proteon_80Mbit, - snmp_ifType_hyperchannel, - snmp_ifType_fddi, - snmp_ifType_lapb, - snmp_ifType_sdlc, - snmp_ifType_ds1, /* T-1 */ - snmp_ifType_e1, /* european equiv. of T-1 */ - snmp_ifType_basicISDN, - snmp_ifType_primaryISDN, /* proprietary serial */ - snmp_ifType_propPointToPointSerial, - snmp_ifType_ppp, - snmp_ifType_softwareLoopback, - snmp_ifType_eon, /* CLNP over IP [11] */ - snmp_ifType_ethernet_3Mbit, - snmp_ifType_nsip, /* XNS over IP */ - snmp_ifType_slip, /* generic SLIP */ - snmp_ifType_ultra, /* ULTRA technologies */ - snmp_ifType_ds3, /* T-3 */ - snmp_ifType_sip, /* SMDS */ - snmp_ifType_frame_relay -}; - -/** This macro has a precision of ~49 days because sys_now returns u32_t. \#define your own if you want ~490 days. */ -#ifndef MIB2_COPY_SYSUPTIME_TO -#define MIB2_COPY_SYSUPTIME_TO(ptrToVal) (*(ptrToVal) = (sys_now() / 10)) -#endif - -/** - * @ingroup netif_mib2 - * Increment stats member for SNMP MIB2 stats (struct stats_mib2_netif_ctrs) - */ -#define MIB2_STATS_NETIF_INC(n, x) do { ++(n)->mib2_counters.x; } while(0) -/** - * @ingroup netif_mib2 - * Add value to stats member for SNMP MIB2 stats (struct stats_mib2_netif_ctrs) - */ -#define MIB2_STATS_NETIF_ADD(n, x, val) do { (n)->mib2_counters.x += (val); } while(0) - -/** - * @ingroup netif_mib2 - * Init MIB2 statistic counters in netif - * @param netif Netif to init - * @param type one of enum @ref snmp_ifType - * @param speed your link speed here (units: bits per second) - */ -#define MIB2_INIT_NETIF(netif, type, speed) do { \ - (netif)->link_type = (type); \ - (netif)->link_speed = (speed);\ - (netif)->ts = 0; \ - (netif)->mib2_counters.ifinoctets = 0; \ - (netif)->mib2_counters.ifinucastpkts = 0; \ - (netif)->mib2_counters.ifinnucastpkts = 0; \ - (netif)->mib2_counters.ifindiscards = 0; \ - (netif)->mib2_counters.ifinerrors = 0; \ - (netif)->mib2_counters.ifinunknownprotos = 0; \ - (netif)->mib2_counters.ifoutoctets = 0; \ - (netif)->mib2_counters.ifoutucastpkts = 0; \ - (netif)->mib2_counters.ifoutnucastpkts = 0; \ - (netif)->mib2_counters.ifoutdiscards = 0; \ - (netif)->mib2_counters.ifouterrors = 0; } while(0) -#else /* MIB2_STATS */ -#ifndef MIB2_COPY_SYSUPTIME_TO -#define MIB2_COPY_SYSUPTIME_TO(ptrToVal) -#endif -#define MIB2_INIT_NETIF(netif, type, speed) -#define MIB2_STATS_NETIF_INC(n, x) -#define MIB2_STATS_NETIF_ADD(n, x, val) -#endif /* MIB2_STATS */ - -/* LWIP MIB2 callbacks */ -#if LWIP_MIB2_CALLBACKS /* don't build if not configured for use in lwipopts.h */ -/* network interface */ -void mib2_netif_added(struct netif *ni); -void mib2_netif_removed(struct netif *ni); - -#if LWIP_IPV4 && LWIP_ARP -/* ARP (for atTable and ipNetToMediaTable) */ -void mib2_add_arp_entry(struct netif *ni, ip4_addr_t *ip); -void mib2_remove_arp_entry(struct netif *ni, ip4_addr_t *ip); -#else /* LWIP_IPV4 && LWIP_ARP */ -#define mib2_add_arp_entry(ni,ip) -#define mib2_remove_arp_entry(ni,ip) -#endif /* LWIP_IPV4 && LWIP_ARP */ - -/* IP */ -#if LWIP_IPV4 -void mib2_add_ip4(struct netif *ni); -void mib2_remove_ip4(struct netif *ni); -void mib2_add_route_ip4(u8_t dflt, struct netif *ni); -void mib2_remove_route_ip4(u8_t dflt, struct netif *ni); -#endif /* LWIP_IPV4 */ - -/* UDP */ -#if LWIP_UDP -void mib2_udp_bind(struct udp_pcb *pcb); -void mib2_udp_unbind(struct udp_pcb *pcb); -#endif /* LWIP_UDP */ - -#else /* LWIP_MIB2_CALLBACKS */ -/* LWIP_MIB2_CALLBACKS support not available */ -/* define everything to be empty */ - -/* network interface */ -#define mib2_netif_added(ni) -#define mib2_netif_removed(ni) - -/* ARP */ -#define mib2_add_arp_entry(ni,ip) -#define mib2_remove_arp_entry(ni,ip) - -/* IP */ -#define mib2_add_ip4(ni) -#define mib2_remove_ip4(ni) -#define mib2_add_route_ip4(dflt, ni) -#define mib2_remove_route_ip4(dflt, ni) - -/* UDP */ -#define mib2_udp_bind(pcb) -#define mib2_udp_unbind(pcb) -#endif /* LWIP_MIB2_CALLBACKS */ - -/* for source-code compatibility reasons only, can be removed (not used internally) */ -#define NETIF_INIT_SNMP MIB2_INIT_NETIF -#define snmp_add_ifinoctets(ni,value) MIB2_STATS_NETIF_ADD(ni, ifinoctets, value) -#define snmp_inc_ifinucastpkts(ni) MIB2_STATS_NETIF_INC(ni, ifinucastpkts) -#define snmp_inc_ifinnucastpkts(ni) MIB2_STATS_NETIF_INC(ni, ifinnucastpkts) -#define snmp_inc_ifindiscards(ni) MIB2_STATS_NETIF_INC(ni, ifindiscards) -#define snmp_inc_ifinerrors(ni) MIB2_STATS_NETIF_INC(ni, ifinerrors) -#define snmp_inc_ifinunknownprotos(ni) MIB2_STATS_NETIF_INC(ni, ifinunknownprotos) -#define snmp_add_ifoutoctets(ni,value) MIB2_STATS_NETIF_ADD(ni, ifoutoctets, value) -#define snmp_inc_ifoutucastpkts(ni) MIB2_STATS_NETIF_INC(ni, ifoutucastpkts) -#define snmp_inc_ifoutnucastpkts(ni) MIB2_STATS_NETIF_INC(ni, ifoutnucastpkts) -#define snmp_inc_ifoutdiscards(ni) MIB2_STATS_NETIF_INC(ni, ifoutdiscards) -#define snmp_inc_ifouterrors(ni) MIB2_STATS_NETIF_INC(ni, ifouterrors) - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_SNMP_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/sockets.h b/third-party/lwip-2.1.2/include/lwip/sockets.h deleted file mode 100644 index d70d36c4..00000000 --- a/third-party/lwip-2.1.2/include/lwip/sockets.h +++ /dev/null @@ -1,688 +0,0 @@ -/** - * @file - * Socket API (to be used from non-TCPIP threads) - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - - -#ifndef LWIP_HDR_SOCKETS_H -#define LWIP_HDR_SOCKETS_H - -#include "lwip/opt.h" - -#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/ip_addr.h" -#include "lwip/netif.h" -#include "lwip/err.h" -#include "lwip/inet.h" -#include "lwip/errno.h" - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* If your port already typedef's sa_family_t, define SA_FAMILY_T_DEFINED - to prevent this code from redefining it. */ -#if !defined(sa_family_t) && !defined(SA_FAMILY_T_DEFINED) -typedef u8_t sa_family_t; -#endif -/* If your port already typedef's in_port_t, define IN_PORT_T_DEFINED - to prevent this code from redefining it. */ -#if !defined(in_port_t) && !defined(IN_PORT_T_DEFINED) -typedef u16_t in_port_t; -#endif - -#if LWIP_IPV4 -/* members are in network byte order */ -struct sockaddr_in { - u8_t sin_len; - sa_family_t sin_family; - in_port_t sin_port; - struct in_addr sin_addr; -#define SIN_ZERO_LEN 8 - char sin_zero[SIN_ZERO_LEN]; -}; -#endif /* LWIP_IPV4 */ - -#if LWIP_IPV6 -struct sockaddr_in6 { - u8_t sin6_len; /* length of this structure */ - sa_family_t sin6_family; /* AF_INET6 */ - in_port_t sin6_port; /* Transport layer port # */ - u32_t sin6_flowinfo; /* IPv6 flow information */ - struct in6_addr sin6_addr; /* IPv6 address */ - u32_t sin6_scope_id; /* Set of interfaces for scope */ -}; -#endif /* LWIP_IPV6 */ - -struct sockaddr { - u8_t sa_len; - sa_family_t sa_family; - char sa_data[14]; -}; - -struct sockaddr_storage { - u8_t s2_len; - sa_family_t ss_family; - char s2_data1[2]; - u32_t s2_data2[3]; -#if LWIP_IPV6 - u32_t s2_data3[3]; -#endif /* LWIP_IPV6 */ -}; - -/* If your port already typedef's socklen_t, define SOCKLEN_T_DEFINED - to prevent this code from redefining it. */ -#if !defined(socklen_t) && !defined(SOCKLEN_T_DEFINED) -typedef u32_t socklen_t; -#endif - -#if !defined IOV_MAX -#define IOV_MAX 0xFFFF -#elif IOV_MAX > 0xFFFF -#error "IOV_MAX larger than supported by LwIP" -#endif /* IOV_MAX */ - -#if !defined(iovec) -struct iovec { - void *iov_base; - size_t iov_len; -}; -#endif - -struct msghdr { - void *msg_name; - socklen_t msg_namelen; - struct iovec *msg_iov; - int msg_iovlen; - void *msg_control; - socklen_t msg_controllen; - int msg_flags; -}; - -/* struct msghdr->msg_flags bit field values */ -#define MSG_TRUNC 0x04 -#define MSG_CTRUNC 0x08 - -/* RFC 3542, Section 20: Ancillary Data */ -struct cmsghdr { - socklen_t cmsg_len; /* number of bytes, including header */ - int cmsg_level; /* originating protocol */ - int cmsg_type; /* protocol-specific type */ -}; -/* Data section follows header and possible padding, typically referred to as - unsigned char cmsg_data[]; */ - -/* cmsg header/data alignment. NOTE: we align to native word size (double word -size on 16-bit arch) so structures are not placed at an unaligned address. -16-bit arch needs double word to ensure 32-bit alignment because socklen_t -could be 32 bits. If we ever have cmsg data with a 64-bit variable, alignment -will need to increase long long */ -#define ALIGN_H(size) (((size) + sizeof(long) - 1U) & ~(sizeof(long)-1U)) -#define ALIGN_D(size) ALIGN_H(size) - -#define CMSG_FIRSTHDR(mhdr) \ - ((mhdr)->msg_controllen >= sizeof(struct cmsghdr) ? \ - (struct cmsghdr *)(mhdr)->msg_control : \ - (struct cmsghdr *)NULL) - -#define CMSG_NXTHDR(mhdr, cmsg) \ - (((cmsg) == NULL) ? CMSG_FIRSTHDR(mhdr) : \ - (((u8_t *)(cmsg) + ALIGN_H((cmsg)->cmsg_len) \ - + ALIGN_D(sizeof(struct cmsghdr)) > \ - (u8_t *)((mhdr)->msg_control) + (mhdr)->msg_controllen) ? \ - (struct cmsghdr *)NULL : \ - (struct cmsghdr *)((void*)((u8_t *)(cmsg) + \ - ALIGN_H((cmsg)->cmsg_len))))) - -#define CMSG_DATA(cmsg) ((void*)((u8_t *)(cmsg) + \ - ALIGN_D(sizeof(struct cmsghdr)))) - -#define CMSG_SPACE(length) (ALIGN_D(sizeof(struct cmsghdr)) + \ - ALIGN_H(length)) - -#define CMSG_LEN(length) (ALIGN_D(sizeof(struct cmsghdr)) + \ - length) - -/* Set socket options argument */ -#define IFNAMSIZ NETIF_NAMESIZE -struct ifreq { - char ifr_name[IFNAMSIZ]; /* Interface name */ -}; - -/* Socket protocol types (TCP/UDP/RAW) */ -#define SOCK_STREAM 1 -#define SOCK_DGRAM 2 -#define SOCK_RAW 3 - -/* - * Option flags per-socket. These must match the SOF_ flags in ip.h (checked in init.c) - */ -#define SO_REUSEADDR 0x0004 /* Allow local address reuse */ -#define SO_KEEPALIVE 0x0008 /* keep connections alive */ -#define SO_BROADCAST 0x0020 /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */ - - -/* - * Additional options, not kept in so_options. - */ -#define SO_DEBUG 0x0001 /* Unimplemented: turn on debugging info recording */ -#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */ -#define SO_DONTROUTE 0x0010 /* Unimplemented: just use interface addresses */ -#define SO_USELOOPBACK 0x0040 /* Unimplemented: bypass hardware when possible */ -#define SO_LINGER 0x0080 /* linger on close if data present */ -#define SO_DONTLINGER ((int)(~SO_LINGER)) -#define SO_OOBINLINE 0x0100 /* Unimplemented: leave received OOB data in line */ -#define SO_REUSEPORT 0x0200 /* Unimplemented: allow local address & port reuse */ -#define SO_SNDBUF 0x1001 /* Unimplemented: send buffer size */ -#define SO_RCVBUF 0x1002 /* receive buffer size */ -#define SO_SNDLOWAT 0x1003 /* Unimplemented: send low-water mark */ -#define SO_RCVLOWAT 0x1004 /* Unimplemented: receive low-water mark */ -#define SO_SNDTIMEO 0x1005 /* send timeout */ -#define SO_RCVTIMEO 0x1006 /* receive timeout */ -#define SO_ERROR 0x1007 /* get error status and clear */ -#define SO_TYPE 0x1008 /* get socket type */ -#define SO_CONTIMEO 0x1009 /* Unimplemented: connect timeout */ -#define SO_NO_CHECK 0x100a /* don't create UDP checksum */ -#define SO_BINDTODEVICE 0x100b /* bind to device */ - -/* - * Structure used for manipulating linger option. - */ -struct linger { - int l_onoff; /* option on/off */ - int l_linger; /* linger time in seconds */ -}; - -/* - * Level number for (get/set)sockopt() to apply to socket itself. - */ -#define SOL_SOCKET 0xfff /* options for socket level */ - - -#define AF_UNSPEC 0 -#define AF_INET 2 -#if LWIP_IPV6 -#define AF_INET6 10 -#else /* LWIP_IPV6 */ -#define AF_INET6 AF_UNSPEC -#endif /* LWIP_IPV6 */ -#define PF_INET AF_INET -#define PF_INET6 AF_INET6 -#define PF_UNSPEC AF_UNSPEC - -#define IPPROTO_IP 0 -#define IPPROTO_ICMP 1 -#define IPPROTO_TCP 6 -#define IPPROTO_UDP 17 -#if LWIP_IPV6 -#define IPPROTO_IPV6 41 -#define IPPROTO_ICMPV6 58 -#endif /* LWIP_IPV6 */ -#define IPPROTO_UDPLITE 136 -#define IPPROTO_RAW 255 - -/* Flags we can use with send and recv. */ -#define MSG_PEEK 0x01 /* Peeks at an incoming message */ -#define MSG_WAITALL 0x02 /* Unimplemented: Requests that the function block until the full amount of data requested can be returned */ -#define MSG_OOB 0x04 /* Unimplemented: Requests out-of-band data. The significance and semantics of out-of-band data are protocol-specific */ -#define MSG_DONTWAIT 0x08 /* Nonblocking i/o for this operation only */ -#define MSG_MORE 0x10 /* Sender will send more */ -#define MSG_NOSIGNAL 0x20 /* Uninmplemented: Requests not to send the SIGPIPE signal if an attempt to send is made on a stream-oriented socket that is no longer connected. */ - - -/* - * Options for level IPPROTO_IP - */ -#define IP_TOS 1 -#define IP_TTL 2 -#define IP_PKTINFO 8 - -#if LWIP_TCP -/* - * Options for level IPPROTO_TCP - */ -#define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */ -#define TCP_KEEPALIVE 0x02 /* send KEEPALIVE probes when idle for pcb->keep_idle milliseconds */ -#define TCP_KEEPIDLE 0x03 /* set pcb->keep_idle - Same as TCP_KEEPALIVE, but use seconds for get/setsockopt */ -#define TCP_KEEPINTVL 0x04 /* set pcb->keep_intvl - Use seconds for get/setsockopt */ -#define TCP_KEEPCNT 0x05 /* set pcb->keep_cnt - Use number of probes sent for get/setsockopt */ -#endif /* LWIP_TCP */ - -#if LWIP_IPV6 -/* - * Options for level IPPROTO_IPV6 - */ -#define IPV6_CHECKSUM 7 /* RFC3542: calculate and insert the ICMPv6 checksum for raw sockets. */ -#define IPV6_V6ONLY 27 /* RFC3493: boolean control to restrict AF_INET6 sockets to IPv6 communications only. */ -#endif /* LWIP_IPV6 */ - -#if LWIP_UDP && LWIP_UDPLITE -/* - * Options for level IPPROTO_UDPLITE - */ -#define UDPLITE_SEND_CSCOV 0x01 /* sender checksum coverage */ -#define UDPLITE_RECV_CSCOV 0x02 /* minimal receiver checksum coverage */ -#endif /* LWIP_UDP && LWIP_UDPLITE*/ - - -#if LWIP_MULTICAST_TX_OPTIONS -/* - * Options and types for UDP multicast traffic handling - */ -#define IP_MULTICAST_TTL 5 -#define IP_MULTICAST_IF 6 -#define IP_MULTICAST_LOOP 7 -#endif /* LWIP_MULTICAST_TX_OPTIONS */ - -#if LWIP_IGMP -/* - * Options and types related to multicast membership - */ -#define IP_ADD_MEMBERSHIP 3 -#define IP_DROP_MEMBERSHIP 4 - -typedef struct ip_mreq { - struct in_addr imr_multiaddr; /* IP multicast address of group */ - struct in_addr imr_interface; /* local IP address of interface */ -} ip_mreq; -#endif /* LWIP_IGMP */ - -#if LWIP_IPV4 -struct in_pktinfo { - unsigned int ipi_ifindex; /* Interface index */ - struct in_addr ipi_addr; /* Destination (from header) address */ -}; -#endif /* LWIP_IPV4 */ - -#if LWIP_IPV6_MLD -/* - * Options and types related to IPv6 multicast membership - */ -#define IPV6_JOIN_GROUP 12 -#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP -#define IPV6_LEAVE_GROUP 13 -#define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP - -typedef struct ipv6_mreq { - struct in6_addr ipv6mr_multiaddr; /* IPv6 multicast addr */ - unsigned int ipv6mr_interface; /* interface index, or 0 */ -} ipv6_mreq; -#endif /* LWIP_IPV6_MLD */ - -/* - * The Type of Service provides an indication of the abstract - * parameters of the quality of service desired. These parameters are - * to be used to guide the selection of the actual service parameters - * when transmitting a datagram through a particular network. Several - * networks offer service precedence, which somehow treats high - * precedence traffic as more important than other traffic (generally - * by accepting only traffic above a certain precedence at time of high - * load). The major choice is a three way tradeoff between low-delay, - * high-reliability, and high-throughput. - * The use of the Delay, Throughput, and Reliability indications may - * increase the cost (in some sense) of the service. In many networks - * better performance for one of these parameters is coupled with worse - * performance on another. Except for very unusual cases at most two - * of these three indications should be set. - */ -#define IPTOS_TOS_MASK 0x1E -#define IPTOS_TOS(tos) ((tos) & IPTOS_TOS_MASK) -#define IPTOS_LOWDELAY 0x10 -#define IPTOS_THROUGHPUT 0x08 -#define IPTOS_RELIABILITY 0x04 -#define IPTOS_LOWCOST 0x02 -#define IPTOS_MINCOST IPTOS_LOWCOST - -/* - * The Network Control precedence designation is intended to be used - * within a network only. The actual use and control of that - * designation is up to each network. The Internetwork Control - * designation is intended for use by gateway control originators only. - * If the actual use of these precedence designations is of concern to - * a particular network, it is the responsibility of that network to - * control the access to, and use of, those precedence designations. - */ -#define IPTOS_PREC_MASK 0xe0 -#define IPTOS_PREC(tos) ((tos) & IPTOS_PREC_MASK) -#define IPTOS_PREC_NETCONTROL 0xe0 -#define IPTOS_PREC_INTERNETCONTROL 0xc0 -#define IPTOS_PREC_CRITIC_ECP 0xa0 -#define IPTOS_PREC_FLASHOVERRIDE 0x80 -#define IPTOS_PREC_FLASH 0x60 -#define IPTOS_PREC_IMMEDIATE 0x40 -#define IPTOS_PREC_PRIORITY 0x20 -#define IPTOS_PREC_ROUTINE 0x00 - - -/* - * Commands for ioctlsocket(), taken from the BSD file fcntl.h. - * lwip_ioctl only supports FIONREAD and FIONBIO, for now - * - * Ioctl's have the command encoded in the lower word, - * and the size of any in or out parameters in the upper - * word. The high 2 bits of the upper word are used - * to encode the in/out status of the parameter; for now - * we restrict parameters to at most 128 bytes. - */ -#if !defined(FIONREAD) || !defined(FIONBIO) -#define IOCPARM_MASK 0x7fU /* parameters must be < 128 bytes */ -#define IOC_VOID 0x20000000UL /* no parameters */ -#define IOC_OUT 0x40000000UL /* copy out parameters */ -#define IOC_IN 0x80000000UL /* copy in parameters */ -#define IOC_INOUT (IOC_IN|IOC_OUT) - /* 0x20000000 distinguishes new & - old ioctl's */ -#define _IO(x,y) ((long)(IOC_VOID|((x)<<8)|(y))) - -#define _IOR(x,y,t) ((long)(IOC_OUT|((sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))) - -#define _IOW(x,y,t) ((long)(IOC_IN|((sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))) -#endif /* !defined(FIONREAD) || !defined(FIONBIO) */ - -#ifndef FIONREAD -#define FIONREAD _IOR('f', 127, unsigned long) /* get # bytes to read */ -#endif -#ifndef FIONBIO -#define FIONBIO _IOW('f', 126, unsigned long) /* set/clear non-blocking i/o */ -#endif - -/* Socket I/O Controls: unimplemented */ -#ifndef SIOCSHIWAT -#define SIOCSHIWAT _IOW('s', 0, unsigned long) /* set high watermark */ -#define SIOCGHIWAT _IOR('s', 1, unsigned long) /* get high watermark */ -#define SIOCSLOWAT _IOW('s', 2, unsigned long) /* set low watermark */ -#define SIOCGLOWAT _IOR('s', 3, unsigned long) /* get low watermark */ -#define SIOCATMARK _IOR('s', 7, unsigned long) /* at oob mark? */ -#endif - -/* commands for fnctl */ -#ifndef F_GETFL -#define F_GETFL 3 -#endif -#ifndef F_SETFL -#define F_SETFL 4 -#endif - -/* File status flags and file access modes for fnctl, - these are bits in an int. */ -#ifndef O_NONBLOCK -#define O_NONBLOCK 1 /* nonblocking I/O */ -#endif -#ifndef O_NDELAY -#define O_NDELAY O_NONBLOCK /* same as O_NONBLOCK, for compatibility */ -#endif -#ifndef O_RDONLY -#define O_RDONLY 2 -#endif -#ifndef O_WRONLY -#define O_WRONLY 4 -#endif -#ifndef O_RDWR -#define O_RDWR (O_RDONLY|O_WRONLY) -#endif - -#ifndef SHUT_RD - #define SHUT_RD 0 - #define SHUT_WR 1 - #define SHUT_RDWR 2 -#endif - -/* FD_SET used for lwip_select */ -#ifndef FD_SET -#undef FD_SETSIZE -/* Make FD_SETSIZE match NUM_SOCKETS in socket.c */ -#define FD_SETSIZE MEMP_NUM_NETCONN -#define LWIP_SELECT_MAXNFDS (FD_SETSIZE + LWIP_SOCKET_OFFSET) -#define FDSETSAFESET(n, code) do { \ - if (((n) - LWIP_SOCKET_OFFSET < MEMP_NUM_NETCONN) && (((int)(n) - LWIP_SOCKET_OFFSET) >= 0)) { \ - code; }} while(0) -#define FDSETSAFEGET(n, code) (((n) - LWIP_SOCKET_OFFSET < MEMP_NUM_NETCONN) && (((int)(n) - LWIP_SOCKET_OFFSET) >= 0) ?\ - (code) : 0) -#define FD_SET(n, p) FDSETSAFESET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] = (u8_t)((p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] | (1 << (((n)-LWIP_SOCKET_OFFSET) & 7)))) -#define FD_CLR(n, p) FDSETSAFESET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] = (u8_t)((p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] & ~(1 << (((n)-LWIP_SOCKET_OFFSET) & 7)))) -#define FD_ISSET(n,p) FDSETSAFEGET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] & (1 << (((n)-LWIP_SOCKET_OFFSET) & 7))) -#define FD_ZERO(p) memset((void*)(p), 0, sizeof(*(p))) - -typedef struct fd_set -{ - unsigned char fd_bits [(FD_SETSIZE+7)/8]; -} fd_set; - -#elif FD_SETSIZE < (LWIP_SOCKET_OFFSET + MEMP_NUM_NETCONN) -#error "external FD_SETSIZE too small for number of sockets" -#else -#define LWIP_SELECT_MAXNFDS FD_SETSIZE -#endif /* FD_SET */ - -/* poll-related defines and types */ -/* @todo: find a better way to guard the definition of these defines and types if already defined */ -#if !defined(POLLIN) && !defined(POLLOUT) -#define POLLIN 0x1 -#define POLLOUT 0x2 -#define POLLERR 0x4 -#define POLLNVAL 0x8 -/* Below values are unimplemented */ -#define POLLRDNORM 0x10 -#define POLLRDBAND 0x20 -#define POLLPRI 0x40 -#define POLLWRNORM 0x80 -#define POLLWRBAND 0x100 -#define POLLHUP 0x200 -typedef unsigned int nfds_t; -struct pollfd -{ - int fd; - short events; - short revents; -}; -#endif - -/** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided - * by your system, set this to 0 and include in cc.h */ -#ifndef LWIP_TIMEVAL_PRIVATE -#define LWIP_TIMEVAL_PRIVATE 1 -#endif - -#if LWIP_TIMEVAL_PRIVATE -struct timeval { - long tv_sec; /* seconds */ - long tv_usec; /* and microseconds */ -}; -#endif /* LWIP_TIMEVAL_PRIVATE */ - -#define lwip_socket_init() /* Compatibility define, no init needed. */ -void lwip_socket_thread_init(void); /* LWIP_NETCONN_SEM_PER_THREAD==1: initialize thread-local semaphore */ -void lwip_socket_thread_cleanup(void); /* LWIP_NETCONN_SEM_PER_THREAD==1: destroy thread-local semaphore */ - -#if LWIP_COMPAT_SOCKETS == 2 -/* This helps code parsers/code completion by not having the COMPAT functions as defines */ -#define lwip_accept accept -#define lwip_bind bind -#define lwip_shutdown shutdown -#define lwip_getpeername getpeername -#define lwip_getsockname getsockname -#define lwip_setsockopt setsockopt -#define lwip_getsockopt getsockopt -#define lwip_close closesocket -#define lwip_connect connect -#define lwip_listen listen -#define lwip_recv recv -#define lwip_recvmsg recvmsg -#define lwip_recvfrom recvfrom -#define lwip_send send -#define lwip_sendmsg sendmsg -#define lwip_sendto sendto -#define lwip_socket socket -#if LWIP_SOCKET_SELECT -#define lwip_select select -#endif -#if LWIP_SOCKET_POLL -#define lwip_poll poll -#endif -#define lwip_ioctl ioctlsocket -#define lwip_inet_ntop inet_ntop -#define lwip_inet_pton inet_pton - -#if LWIP_POSIX_SOCKETS_IO_NAMES -#define lwip_read read -#define lwip_readv readv -#define lwip_write write -#define lwip_writev writev -#undef lwip_close -#define lwip_close close -#define closesocket(s) close(s) -int fcntl(int s, int cmd, ...); -#undef lwip_ioctl -#define lwip_ioctl ioctl -#define ioctlsocket ioctl -#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */ -#endif /* LWIP_COMPAT_SOCKETS == 2 */ - -int lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen); -int lwip_bind(int s, const struct sockaddr *name, socklen_t namelen); -int lwip_shutdown(int s, int how); -int lwip_getpeername (int s, struct sockaddr *name, socklen_t *namelen); -int lwip_getsockname (int s, struct sockaddr *name, socklen_t *namelen); -int lwip_getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen); -int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen); - int lwip_close(int s); -int lwip_connect(int s, const struct sockaddr *name, socklen_t namelen); -int lwip_listen(int s, int backlog); -ssize_t lwip_recv(int s, void *mem, size_t len, int flags); -ssize_t lwip_read(int s, void *mem, size_t len); -ssize_t lwip_readv(int s, const struct iovec *iov, int iovcnt); -ssize_t lwip_recvfrom(int s, void *mem, size_t len, int flags, - struct sockaddr *from, socklen_t *fromlen); -ssize_t lwip_recvmsg(int s, struct msghdr *message, int flags); -ssize_t lwip_send(int s, const void *dataptr, size_t size, int flags); -ssize_t lwip_sendmsg(int s, const struct msghdr *message, int flags); -ssize_t lwip_sendto(int s, const void *dataptr, size_t size, int flags, - const struct sockaddr *to, socklen_t tolen); -int lwip_socket(int domain, int type, int protocol); -ssize_t lwip_write(int s, const void *dataptr, size_t size); -ssize_t lwip_writev(int s, const struct iovec *iov, int iovcnt); -#if LWIP_SOCKET_SELECT -int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, - struct timeval *timeout); -#endif -#if LWIP_SOCKET_POLL -int lwip_poll(struct pollfd *fds, nfds_t nfds, int timeout); -#endif -int lwip_ioctl(int s, long cmd, void *argp); -int lwip_fcntl(int s, int cmd, int val); -const char *lwip_inet_ntop(int af, const void *src, char *dst, socklen_t size); -int lwip_inet_pton(int af, const char *src, void *dst); - -#if LWIP_COMPAT_SOCKETS -#if LWIP_COMPAT_SOCKETS != 2 -/** @ingroup socket */ -#define accept(s,addr,addrlen) lwip_accept(s,addr,addrlen) -/** @ingroup socket */ -#define bind(s,name,namelen) lwip_bind(s,name,namelen) -/** @ingroup socket */ -#define shutdown(s,how) lwip_shutdown(s,how) -/** @ingroup socket */ -#define getpeername(s,name,namelen) lwip_getpeername(s,name,namelen) -/** @ingroup socket */ -#define getsockname(s,name,namelen) lwip_getsockname(s,name,namelen) -/** @ingroup socket */ -#define setsockopt(s,level,optname,opval,optlen) lwip_setsockopt(s,level,optname,opval,optlen) -/** @ingroup socket */ -#define getsockopt(s,level,optname,opval,optlen) lwip_getsockopt(s,level,optname,opval,optlen) -/** @ingroup socket */ -#define closesocket(s) lwip_close(s) -/** @ingroup socket */ -#define connect(s,name,namelen) lwip_connect(s,name,namelen) -/** @ingroup socket */ -#define listen(s,backlog) lwip_listen(s,backlog) -/** @ingroup socket */ -#define recv(s,mem,len,flags) lwip_recv(s,mem,len,flags) -/** @ingroup socket */ -#define recvmsg(s,message,flags) lwip_recvmsg(s,message,flags) -/** @ingroup socket */ -#define recvfrom(s,mem,len,flags,from,fromlen) lwip_recvfrom(s,mem,len,flags,from,fromlen) -/** @ingroup socket */ -#define send(s,dataptr,size,flags) lwip_send(s,dataptr,size,flags) -/** @ingroup socket */ -#define sendmsg(s,message,flags) lwip_sendmsg(s,message,flags) -/** @ingroup socket */ -#define sendto(s,dataptr,size,flags,to,tolen) lwip_sendto(s,dataptr,size,flags,to,tolen) -/** @ingroup socket */ -#define socket(domain,type,protocol) lwip_socket(domain,type,protocol) -#if LWIP_SOCKET_SELECT -/** @ingroup socket */ -#define select(maxfdp1,readset,writeset,exceptset,timeout) lwip_select(maxfdp1,readset,writeset,exceptset,timeout) -#endif -#if LWIP_SOCKET_POLL -/** @ingroup socket */ -#define poll(fds,nfds,timeout) lwip_poll(fds,nfds,timeout) -#endif -/** @ingroup socket */ -#define ioctlsocket(s,cmd,argp) lwip_ioctl(s,cmd,argp) -/** @ingroup socket */ -#define inet_ntop(af,src,dst,size) lwip_inet_ntop(af,src,dst,size) -/** @ingroup socket */ -#define inet_pton(af,src,dst) lwip_inet_pton(af,src,dst) - -#if LWIP_POSIX_SOCKETS_IO_NAMES -/** @ingroup socket */ -#define read(s,mem,len) lwip_read(s,mem,len) -/** @ingroup socket */ -#define readv(s,iov,iovcnt) lwip_readv(s,iov,iovcnt) -/** @ingroup socket */ -#define write(s,dataptr,len) lwip_write(s,dataptr,len) -/** @ingroup socket */ -#define writev(s,iov,iovcnt) lwip_writev(s,iov,iovcnt) -/** @ingroup socket */ -#define close(s) lwip_close(s) -/** @ingroup socket */ -#define fcntl(s,cmd,val) lwip_fcntl(s,cmd,val) -/** @ingroup socket */ -#define ioctl(s,cmd,argp) lwip_ioctl(s,cmd,argp) -#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */ -#endif /* LWIP_COMPAT_SOCKETS != 2 */ - -#endif /* LWIP_COMPAT_SOCKETS */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_SOCKET */ - -#endif /* LWIP_HDR_SOCKETS_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/stats.h b/third-party/lwip-2.1.2/include/lwip/stats.h deleted file mode 100644 index b570dbac..00000000 --- a/third-party/lwip-2.1.2/include/lwip/stats.h +++ /dev/null @@ -1,491 +0,0 @@ -/** - * @file - * Statistics API (to be used from TCPIP thread) - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_STATS_H -#define LWIP_HDR_STATS_H - -#include "lwip/opt.h" - -#include "lwip/mem.h" -#include "lwip/memp.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if LWIP_STATS - -#ifndef LWIP_STATS_LARGE -#define LWIP_STATS_LARGE 0 -#endif - -#if LWIP_STATS_LARGE -#define STAT_COUNTER u32_t -#define STAT_COUNTER_F U32_F -#else -#define STAT_COUNTER u16_t -#define STAT_COUNTER_F U16_F -#endif - -/** Protocol related stats */ -struct stats_proto { - STAT_COUNTER xmit; /* Transmitted packets. */ - STAT_COUNTER recv; /* Received packets. */ - STAT_COUNTER fw; /* Forwarded packets. */ - STAT_COUNTER drop; /* Dropped packets. */ - STAT_COUNTER chkerr; /* Checksum error. */ - STAT_COUNTER lenerr; /* Invalid length error. */ - STAT_COUNTER memerr; /* Out of memory error. */ - STAT_COUNTER rterr; /* Routing error. */ - STAT_COUNTER proterr; /* Protocol error. */ - STAT_COUNTER opterr; /* Error in options. */ - STAT_COUNTER err; /* Misc error. */ - STAT_COUNTER cachehit; -}; - -/** IGMP stats */ -struct stats_igmp { - STAT_COUNTER xmit; /* Transmitted packets. */ - STAT_COUNTER recv; /* Received packets. */ - STAT_COUNTER drop; /* Dropped packets. */ - STAT_COUNTER chkerr; /* Checksum error. */ - STAT_COUNTER lenerr; /* Invalid length error. */ - STAT_COUNTER memerr; /* Out of memory error. */ - STAT_COUNTER proterr; /* Protocol error. */ - STAT_COUNTER rx_v1; /* Received v1 frames. */ - STAT_COUNTER rx_group; /* Received group-specific queries. */ - STAT_COUNTER rx_general; /* Received general queries. */ - STAT_COUNTER rx_report; /* Received reports. */ - STAT_COUNTER tx_join; /* Sent joins. */ - STAT_COUNTER tx_leave; /* Sent leaves. */ - STAT_COUNTER tx_report; /* Sent reports. */ -}; - -/** Memory stats */ -struct stats_mem { -#if defined(LWIP_DEBUG) || LWIP_STATS_DISPLAY - const char *name; -#endif /* defined(LWIP_DEBUG) || LWIP_STATS_DISPLAY */ - STAT_COUNTER err; - mem_size_t avail; - mem_size_t used; - mem_size_t max; - STAT_COUNTER illegal; -}; - -/** System element stats */ -struct stats_syselem { - STAT_COUNTER used; - STAT_COUNTER max; - STAT_COUNTER err; -}; - -/** System stats */ -struct stats_sys { - struct stats_syselem sem; - struct stats_syselem mutex; - struct stats_syselem mbox; -}; - -/** SNMP MIB2 stats */ -struct stats_mib2 { - /* IP */ - u32_t ipinhdrerrors; - u32_t ipinaddrerrors; - u32_t ipinunknownprotos; - u32_t ipindiscards; - u32_t ipindelivers; - u32_t ipoutrequests; - u32_t ipoutdiscards; - u32_t ipoutnoroutes; - u32_t ipreasmoks; - u32_t ipreasmfails; - u32_t ipfragoks; - u32_t ipfragfails; - u32_t ipfragcreates; - u32_t ipreasmreqds; - u32_t ipforwdatagrams; - u32_t ipinreceives; - - /* TCP */ - u32_t tcpactiveopens; - u32_t tcppassiveopens; - u32_t tcpattemptfails; - u32_t tcpestabresets; - u32_t tcpoutsegs; - u32_t tcpretranssegs; - u32_t tcpinsegs; - u32_t tcpinerrs; - u32_t tcpoutrsts; - - /* UDP */ - u32_t udpindatagrams; - u32_t udpnoports; - u32_t udpinerrors; - u32_t udpoutdatagrams; - - /* ICMP */ - u32_t icmpinmsgs; - u32_t icmpinerrors; - u32_t icmpindestunreachs; - u32_t icmpintimeexcds; - u32_t icmpinparmprobs; - u32_t icmpinsrcquenchs; - u32_t icmpinredirects; - u32_t icmpinechos; - u32_t icmpinechoreps; - u32_t icmpintimestamps; - u32_t icmpintimestampreps; - u32_t icmpinaddrmasks; - u32_t icmpinaddrmaskreps; - u32_t icmpoutmsgs; - u32_t icmpouterrors; - u32_t icmpoutdestunreachs; - u32_t icmpouttimeexcds; - u32_t icmpoutechos; /* can be incremented by user application ('ping') */ - u32_t icmpoutechoreps; -}; - -/** - * @ingroup netif_mib2 - * SNMP MIB2 interface stats - */ -struct stats_mib2_netif_ctrs { - /** The total number of octets received on the interface, including framing characters */ - u32_t ifinoctets; - /** The number of packets, delivered by this sub-layer to a higher (sub-)layer, which were - * not addressed to a multicast or broadcast address at this sub-layer */ - u32_t ifinucastpkts; - /** The number of packets, delivered by this sub-layer to a higher (sub-)layer, which were - * addressed to a multicast or broadcast address at this sub-layer */ - u32_t ifinnucastpkts; - /** The number of inbound packets which were chosen to be discarded even though no errors had - * been detected to prevent their being deliverable to a higher-layer protocol. One possible - * reason for discarding such a packet could be to free up buffer space */ - u32_t ifindiscards; - /** For packet-oriented interfaces, the number of inbound packets that contained errors - * preventing them from being deliverable to a higher-layer protocol. For character- - * oriented or fixed-length interfaces, the number of inbound transmission units that - * contained errors preventing them from being deliverable to a higher-layer protocol. */ - u32_t ifinerrors; - /** For packet-oriented interfaces, the number of packets received via the interface which - * were discarded because of an unknown or unsupported protocol. For character-oriented - * or fixed-length interfaces that support protocol multiplexing the number of transmission - * units received via the interface which were discarded because of an unknown or unsupported - * protocol. For any interface that does not support protocol multiplexing, this counter will - * always be 0 */ - u32_t ifinunknownprotos; - /** The total number of octets transmitted out of the interface, including framing characters. */ - u32_t ifoutoctets; - /** The total number of packets that higher-level protocols requested be transmitted, and - * which were not addressed to a multicast or broadcast address at this sub-layer, including - * those that were discarded or not sent. */ - u32_t ifoutucastpkts; - /** The total number of packets that higher-level protocols requested be transmitted, and which - * were addressed to a multicast or broadcast address at this sub-layer, including - * those that were discarded or not sent. */ - u32_t ifoutnucastpkts; - /** The number of outbound packets which were chosen to be discarded even though no errors had - * been detected to prevent their being transmitted. One possible reason for discarding - * such a packet could be to free up buffer space. */ - u32_t ifoutdiscards; - /** For packet-oriented interfaces, the number of outbound packets that could not be transmitted - * because of errors. For character-oriented or fixed-length interfaces, the number of outbound - * transmission units that could not be transmitted because of errors. */ - u32_t ifouterrors; -}; - -/** lwIP stats container */ -struct stats_ { -#if LINK_STATS - /** Link level */ - struct stats_proto link; -#endif -#if ETHARP_STATS - /** ARP */ - struct stats_proto etharp; -#endif -#if IPFRAG_STATS - /** Fragmentation */ - struct stats_proto ip_frag; -#endif -#if IP_STATS - /** IP */ - struct stats_proto ip; -#endif -#if ICMP_STATS - /** ICMP */ - struct stats_proto icmp; -#endif -#if IGMP_STATS - /** IGMP */ - struct stats_igmp igmp; -#endif -#if UDP_STATS - /** UDP */ - struct stats_proto udp; -#endif -#if TCP_STATS - /** TCP */ - struct stats_proto tcp; -#endif -#if MEM_STATS - /** Heap */ - struct stats_mem mem; -#endif -#if MEMP_STATS - /** Internal memory pools */ - struct stats_mem *memp[MEMP_MAX]; -#endif -#if SYS_STATS - /** System */ - struct stats_sys sys; -#endif -#if IP6_STATS - /** IPv6 */ - struct stats_proto ip6; -#endif -#if ICMP6_STATS - /** ICMP6 */ - struct stats_proto icmp6; -#endif -#if IP6_FRAG_STATS - /** IPv6 fragmentation */ - struct stats_proto ip6_frag; -#endif -#if MLD6_STATS - /** Multicast listener discovery */ - struct stats_igmp mld6; -#endif -#if ND6_STATS - /** Neighbor discovery */ - struct stats_proto nd6; -#endif -#if MIB2_STATS - /** SNMP MIB2 */ - struct stats_mib2 mib2; -#endif -}; - -/** Global variable containing lwIP internal statistics. Add this to your debugger's watchlist. */ -extern struct stats_ lwip_stats; - -/** Init statistics */ -void stats_init(void); - -#define STATS_INC(x) ++lwip_stats.x -#define STATS_DEC(x) --lwip_stats.x -#define STATS_INC_USED(x, y, type) do { lwip_stats.x.used = (type)(lwip_stats.x.used + y); \ - if (lwip_stats.x.max < lwip_stats.x.used) { \ - lwip_stats.x.max = lwip_stats.x.used; \ - } \ - } while(0) -#define STATS_GET(x) lwip_stats.x -#else /* LWIP_STATS */ -#define stats_init() -#define STATS_INC(x) -#define STATS_DEC(x) -#define STATS_INC_USED(x, y, type) -#endif /* LWIP_STATS */ - -#if TCP_STATS -#define TCP_STATS_INC(x) STATS_INC(x) -#define TCP_STATS_DISPLAY() stats_display_proto(&lwip_stats.tcp, "TCP") -#else -#define TCP_STATS_INC(x) -#define TCP_STATS_DISPLAY() -#endif - -#if UDP_STATS -#define UDP_STATS_INC(x) STATS_INC(x) -#define UDP_STATS_DISPLAY() stats_display_proto(&lwip_stats.udp, "UDP") -#else -#define UDP_STATS_INC(x) -#define UDP_STATS_DISPLAY() -#endif - -#if ICMP_STATS -#define ICMP_STATS_INC(x) STATS_INC(x) -#define ICMP_STATS_DISPLAY() stats_display_proto(&lwip_stats.icmp, "ICMP") -#else -#define ICMP_STATS_INC(x) -#define ICMP_STATS_DISPLAY() -#endif - -#if IGMP_STATS -#define IGMP_STATS_INC(x) STATS_INC(x) -#define IGMP_STATS_DISPLAY() stats_display_igmp(&lwip_stats.igmp, "IGMP") -#else -#define IGMP_STATS_INC(x) -#define IGMP_STATS_DISPLAY() -#endif - -#if IP_STATS -#define IP_STATS_INC(x) STATS_INC(x) -#define IP_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip, "IP") -#else -#define IP_STATS_INC(x) -#define IP_STATS_DISPLAY() -#endif - -#if IPFRAG_STATS -#define IPFRAG_STATS_INC(x) STATS_INC(x) -#define IPFRAG_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip_frag, "IP_FRAG") -#else -#define IPFRAG_STATS_INC(x) -#define IPFRAG_STATS_DISPLAY() -#endif - -#if ETHARP_STATS -#define ETHARP_STATS_INC(x) STATS_INC(x) -#define ETHARP_STATS_DISPLAY() stats_display_proto(&lwip_stats.etharp, "ETHARP") -#else -#define ETHARP_STATS_INC(x) -#define ETHARP_STATS_DISPLAY() -#endif - -#if LINK_STATS -#define LINK_STATS_INC(x) STATS_INC(x) -#define LINK_STATS_DISPLAY() stats_display_proto(&lwip_stats.link, "LINK") -#else -#define LINK_STATS_INC(x) -#define LINK_STATS_DISPLAY() -#endif - -#if MEM_STATS -#define MEM_STATS_AVAIL(x, y) lwip_stats.mem.x = y -#define MEM_STATS_INC(x) STATS_INC(mem.x) -#define MEM_STATS_INC_USED(x, y) STATS_INC_USED(mem, y, mem_size_t) -#define MEM_STATS_DEC_USED(x, y) lwip_stats.mem.x = (mem_size_t)((lwip_stats.mem.x) - (y)) -#define MEM_STATS_DISPLAY() stats_display_mem(&lwip_stats.mem, "HEAP") -#else -#define MEM_STATS_AVAIL(x, y) -#define MEM_STATS_INC(x) -#define MEM_STATS_INC_USED(x, y) -#define MEM_STATS_DEC_USED(x, y) -#define MEM_STATS_DISPLAY() -#endif - - #if MEMP_STATS -#define MEMP_STATS_DEC(x, i) STATS_DEC(memp[i]->x) -#define MEMP_STATS_DISPLAY(i) stats_display_memp(lwip_stats.memp[i], i) -#define MEMP_STATS_GET(x, i) STATS_GET(memp[i]->x) - #else -#define MEMP_STATS_DEC(x, i) -#define MEMP_STATS_DISPLAY(i) -#define MEMP_STATS_GET(x, i) 0 -#endif - -#if SYS_STATS -#define SYS_STATS_INC(x) STATS_INC(sys.x) -#define SYS_STATS_DEC(x) STATS_DEC(sys.x) -#define SYS_STATS_INC_USED(x) STATS_INC_USED(sys.x, 1, STAT_COUNTER) -#define SYS_STATS_DISPLAY() stats_display_sys(&lwip_stats.sys) -#else -#define SYS_STATS_INC(x) -#define SYS_STATS_DEC(x) -#define SYS_STATS_INC_USED(x) -#define SYS_STATS_DISPLAY() -#endif - -#if IP6_STATS -#define IP6_STATS_INC(x) STATS_INC(x) -#define IP6_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip6, "IPv6") -#else -#define IP6_STATS_INC(x) -#define IP6_STATS_DISPLAY() -#endif - -#if ICMP6_STATS -#define ICMP6_STATS_INC(x) STATS_INC(x) -#define ICMP6_STATS_DISPLAY() stats_display_proto(&lwip_stats.icmp6, "ICMPv6") -#else -#define ICMP6_STATS_INC(x) -#define ICMP6_STATS_DISPLAY() -#endif - -#if IP6_FRAG_STATS -#define IP6_FRAG_STATS_INC(x) STATS_INC(x) -#define IP6_FRAG_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip6_frag, "IPv6 FRAG") -#else -#define IP6_FRAG_STATS_INC(x) -#define IP6_FRAG_STATS_DISPLAY() -#endif - -#if MLD6_STATS -#define MLD6_STATS_INC(x) STATS_INC(x) -#define MLD6_STATS_DISPLAY() stats_display_igmp(&lwip_stats.mld6, "MLDv1") -#else -#define MLD6_STATS_INC(x) -#define MLD6_STATS_DISPLAY() -#endif - -#if ND6_STATS -#define ND6_STATS_INC(x) STATS_INC(x) -#define ND6_STATS_DISPLAY() stats_display_proto(&lwip_stats.nd6, "ND") -#else -#define ND6_STATS_INC(x) -#define ND6_STATS_DISPLAY() -#endif - -#if MIB2_STATS -#define MIB2_STATS_INC(x) STATS_INC(x) -#else -#define MIB2_STATS_INC(x) -#endif - -/* Display of statistics */ -#if LWIP_STATS_DISPLAY -void stats_display(void); -void stats_display_proto(struct stats_proto *proto, const char *name); -void stats_display_igmp(struct stats_igmp *igmp, const char *name); -void stats_display_mem(struct stats_mem *mem, const char *name); -void stats_display_memp(struct stats_mem *mem, int index); -void stats_display_sys(struct stats_sys *sys); -#else /* LWIP_STATS_DISPLAY */ -#define stats_display() -#define stats_display_proto(proto, name) -#define stats_display_igmp(igmp, name) -#define stats_display_mem(mem, name) -#define stats_display_memp(mem, index) -#define stats_display_sys(sys) -#endif /* LWIP_STATS_DISPLAY */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_STATS_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/sys.h b/third-party/lwip-2.1.2/include/lwip/sys.h deleted file mode 100644 index 168e465b..00000000 --- a/third-party/lwip-2.1.2/include/lwip/sys.h +++ /dev/null @@ -1,560 +0,0 @@ -/** - * @file - * OS abstraction layer - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - */ - -#ifndef LWIP_HDR_SYS_H -#define LWIP_HDR_SYS_H - -#include "lwip/opt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if NO_SYS - -/* For a totally minimal and standalone system, we provide null - definitions of the sys_ functions. */ -typedef u8_t sys_sem_t; -typedef u8_t sys_mutex_t; -typedef u8_t sys_mbox_t; - -#define sys_sem_new(s, c) ERR_OK -#define sys_sem_signal(s) -#define sys_sem_wait(s) -#define sys_arch_sem_wait(s,t) -#define sys_sem_free(s) -#define sys_sem_valid(s) 0 -#define sys_sem_valid_val(s) 0 -#define sys_sem_set_invalid(s) -#define sys_sem_set_invalid_val(s) -#define sys_mutex_new(mu) ERR_OK -#define sys_mutex_lock(mu) -#define sys_mutex_unlock(mu) -#define sys_mutex_free(mu) -#define sys_mutex_valid(mu) 0 -#define sys_mutex_set_invalid(mu) -#define sys_mbox_new(m, s) ERR_OK -#define sys_mbox_fetch(m,d) -#define sys_mbox_tryfetch(m,d) -#define sys_mbox_post(m,d) -#define sys_mbox_trypost(m,d) -#define sys_mbox_free(m) -#define sys_mbox_valid(m) -#define sys_mbox_valid_val(m) -#define sys_mbox_set_invalid(m) -#define sys_mbox_set_invalid_val(m) - -#define sys_thread_new(n,t,a,s,p) - -#define sys_msleep(t) - -#else /* NO_SYS */ - -/** Return code for timeouts from sys_arch_mbox_fetch and sys_arch_sem_wait */ -#define SYS_ARCH_TIMEOUT 0xffffffffUL - -/** sys_mbox_tryfetch() returns SYS_MBOX_EMPTY if appropriate. - * For now we use the same magic value, but we allow this to change in future. - */ -#define SYS_MBOX_EMPTY SYS_ARCH_TIMEOUT - -#include "lwip/err.h" -#include "arch/sys_arch.h" - -/** Function prototype for thread functions */ -typedef void (*lwip_thread_fn)(void *arg); - -/* Function prototypes for functions to be implemented by platform ports - (in sys_arch.c) */ - -/* Mutex functions: */ - -/** Define LWIP_COMPAT_MUTEX if the port has no mutexes and binary semaphores - should be used instead */ -#ifndef LWIP_COMPAT_MUTEX -#define LWIP_COMPAT_MUTEX 0 -#endif - -#if LWIP_COMPAT_MUTEX -/* for old ports that don't have mutexes: define them to binary semaphores */ -#define sys_mutex_t sys_sem_t -#define sys_mutex_new(mutex) sys_sem_new(mutex, 1) -#define sys_mutex_lock(mutex) sys_sem_wait(mutex) -#define sys_mutex_unlock(mutex) sys_sem_signal(mutex) -#define sys_mutex_free(mutex) sys_sem_free(mutex) -#define sys_mutex_valid(mutex) sys_sem_valid(mutex) -#define sys_mutex_set_invalid(mutex) sys_sem_set_invalid(mutex) - -#else /* LWIP_COMPAT_MUTEX */ - -/** - * @ingroup sys_mutex - * Create a new mutex. - * Note that mutexes are expected to not be taken recursively by the lwIP code, - * so both implementation types (recursive or non-recursive) should work. - * The mutex is allocated to the memory that 'mutex' - * points to (which can be both a pointer or the actual OS structure). - * If the mutex has been created, ERR_OK should be returned. Returning any - * other error will provide a hint what went wrong, but except for assertions, - * no real error handling is implemented. - * - * @param mutex pointer to the mutex to create - * @return ERR_OK if successful, another err_t otherwise - */ -err_t sys_mutex_new(sys_mutex_t *mutex); -/** - * @ingroup sys_mutex - * Blocks the thread until the mutex can be grabbed. - * @param mutex the mutex to lock - */ -void sys_mutex_lock(sys_mutex_t *mutex); -/** - * @ingroup sys_mutex - * Releases the mutex previously locked through 'sys_mutex_lock()'. - * @param mutex the mutex to unlock - */ -void sys_mutex_unlock(sys_mutex_t *mutex); -/** - * @ingroup sys_mutex - * Deallocates a mutex. - * @param mutex the mutex to delete - */ -void sys_mutex_free(sys_mutex_t *mutex); -#ifndef sys_mutex_valid -/** - * @ingroup sys_mutex - * Returns 1 if the mutes is valid, 0 if it is not valid. - * When using pointers, a simple way is to check the pointer for != NULL. - * When directly using OS structures, implementing this may be more complex. - * This may also be a define, in which case the function is not prototyped. - */ -int sys_mutex_valid(sys_mutex_t *mutex); -#endif -#ifndef sys_mutex_set_invalid -/** - * @ingroup sys_mutex - * Invalidate a mutex so that sys_mutex_valid() returns 0. - * ATTENTION: This does NOT mean that the mutex shall be deallocated: - * sys_mutex_free() is always called before calling this function! - * This may also be a define, in which case the function is not prototyped. - */ -void sys_mutex_set_invalid(sys_mutex_t *mutex); -#endif -#endif /* LWIP_COMPAT_MUTEX */ - -/* Semaphore functions: */ - -/** - * @ingroup sys_sem - * Create a new semaphore - * Creates a new semaphore. The semaphore is allocated to the memory that 'sem' - * points to (which can be both a pointer or the actual OS structure). - * The "count" argument specifies the initial state of the semaphore (which is - * either 0 or 1). - * If the semaphore has been created, ERR_OK should be returned. Returning any - * other error will provide a hint what went wrong, but except for assertions, - * no real error handling is implemented. - * - * @param sem pointer to the semaphore to create - * @param count initial count of the semaphore - * @return ERR_OK if successful, another err_t otherwise - */ -err_t sys_sem_new(sys_sem_t *sem, u8_t count); -/** - * @ingroup sys_sem - * Signals a semaphore - * @param sem the semaphore to signal - */ -void sys_sem_signal(sys_sem_t *sem); -/** - * @ingroup sys_sem - * Blocks the thread while waiting for the semaphore to be signaled. If the - * "timeout" argument is non-zero, the thread should only be blocked for the - * specified time (measured in milliseconds). If the "timeout" argument is zero, - * the thread should be blocked until the semaphore is signalled. - * - * The return value is SYS_ARCH_TIMEOUT if the semaphore wasn't signaled within - * the specified time or any other value if it was signaled (with or without - * waiting). - * Notice that lwIP implements a function with a similar name, - * sys_sem_wait(), that uses the sys_arch_sem_wait() function. - * - * @param sem the semaphore to wait for - * @param timeout timeout in milliseconds to wait (0 = wait forever) - * @return SYS_ARCH_TIMEOUT on timeout, any other value on success - */ -u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout); -/** - * @ingroup sys_sem - * Deallocates a semaphore. - * @param sem semaphore to delete - */ -void sys_sem_free(sys_sem_t *sem); -/** Wait for a semaphore - forever/no timeout */ -#define sys_sem_wait(sem) sys_arch_sem_wait(sem, 0) -#ifndef sys_sem_valid -/** - * @ingroup sys_sem - * Returns 1 if the semaphore is valid, 0 if it is not valid. - * When using pointers, a simple way is to check the pointer for != NULL. - * When directly using OS structures, implementing this may be more complex. - * This may also be a define, in which case the function is not prototyped. - */ -int sys_sem_valid(sys_sem_t *sem); -#endif -#ifndef sys_sem_set_invalid -/** - * @ingroup sys_sem - * Invalidate a semaphore so that sys_sem_valid() returns 0. - * ATTENTION: This does NOT mean that the semaphore shall be deallocated: - * sys_sem_free() is always called before calling this function! - * This may also be a define, in which case the function is not prototyped. - */ -void sys_sem_set_invalid(sys_sem_t *sem); -#endif -#ifndef sys_sem_valid_val -/** - * Same as sys_sem_valid() but taking a value, not a pointer - */ -#define sys_sem_valid_val(sem) sys_sem_valid(&(sem)) -#endif -#ifndef sys_sem_set_invalid_val -/** - * Same as sys_sem_set_invalid() but taking a value, not a pointer - */ -#define sys_sem_set_invalid_val(sem) sys_sem_set_invalid(&(sem)) -#endif - -#ifndef sys_msleep -/** - * @ingroup sys_misc - * Sleep for specified number of ms - */ -void sys_msleep(u32_t ms); /* only has a (close to) 1 ms resolution. */ -#endif - -/* Mailbox functions. */ - -/** - * @ingroup sys_mbox - * Creates an empty mailbox for maximum "size" elements. Elements stored - * in mailboxes are pointers. You have to define macros "_MBOX_SIZE" - * in your lwipopts.h, or ignore this parameter in your implementation - * and use a default size. - * If the mailbox has been created, ERR_OK should be returned. Returning any - * other error will provide a hint what went wrong, but except for assertions, - * no real error handling is implemented. - * - * @param mbox pointer to the mbox to create - * @param size (minimum) number of messages in this mbox - * @return ERR_OK if successful, another err_t otherwise - */ -err_t sys_mbox_new(sys_mbox_t *mbox, int size); -/** - * @ingroup sys_mbox - * Post a message to an mbox - may not fail - * -> blocks if full, only to be used from tasks NOT from ISR! - * - * @param mbox mbox to posts the message - * @param msg message to post (ATTENTION: can be NULL) - */ -void sys_mbox_post(sys_mbox_t *mbox, void *msg); -/** - * @ingroup sys_mbox - * Try to post a message to an mbox - may fail if full. - * Can be used from ISR (if the sys arch layer allows this). - * Returns ERR_MEM if it is full, else, ERR_OK if the "msg" is posted. - * - * @param mbox mbox to posts the message - * @param msg message to post (ATTENTION: can be NULL) - */ -err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg); -/** - * @ingroup sys_mbox - * Try to post a message to an mbox - may fail if full. - * To be be used from ISR. - * Returns ERR_MEM if it is full, else, ERR_OK if the "msg" is posted. - * - * @param mbox mbox to posts the message - * @param msg message to post (ATTENTION: can be NULL) - */ -err_t sys_mbox_trypost_fromisr(sys_mbox_t *mbox, void *msg); -/** - * @ingroup sys_mbox - * Blocks the thread until a message arrives in the mailbox, but does - * not block the thread longer than "timeout" milliseconds (similar to - * the sys_arch_sem_wait() function). If "timeout" is 0, the thread should - * be blocked until a message arrives. The "msg" argument is a result - * parameter that is set by the function (i.e., by doing "*msg = - * ptr"). The "msg" parameter maybe NULL to indicate that the message - * should be dropped. - * The return values are the same as for the sys_arch_sem_wait() function: - * SYS_ARCH_TIMEOUT if there was a timeout, any other value if a messages - * is received. - * - * Note that a function with a similar name, sys_mbox_fetch(), is - * implemented by lwIP. - * - * @param mbox mbox to get a message from - * @param msg pointer where the message is stored - * @param timeout maximum time (in milliseconds) to wait for a message (0 = wait forever) - * @return SYS_ARCH_TIMEOUT on timeout, any other value if a message has been received - */ -u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout); -/* Allow port to override with a macro, e.g. special timeout for sys_arch_mbox_fetch() */ -#ifndef sys_arch_mbox_tryfetch -/** - * @ingroup sys_mbox - * This is similar to sys_arch_mbox_fetch, however if a message is not - * present in the mailbox, it immediately returns with the code - * SYS_MBOX_EMPTY. On success 0 is returned. - * To allow for efficient implementations, this can be defined as a - * function-like macro in sys_arch.h instead of a normal function. For - * example, a naive implementation could be: - * \#define sys_arch_mbox_tryfetch(mbox,msg) sys_arch_mbox_fetch(mbox,msg,1) - * although this would introduce unnecessary delays. - * - * @param mbox mbox to get a message from - * @param msg pointer where the message is stored - * @return 0 (milliseconds) if a message has been received - * or SYS_MBOX_EMPTY if the mailbox is empty - */ -u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg); -#endif -/** - * For now, we map straight to sys_arch implementation. - */ -#define sys_mbox_tryfetch(mbox, msg) sys_arch_mbox_tryfetch(mbox, msg) -/** - * @ingroup sys_mbox - * Deallocates a mailbox. If there are messages still present in the - * mailbox when the mailbox is deallocated, it is an indication of a - * programming error in lwIP and the developer should be notified. - * - * @param mbox mbox to delete - */ -void sys_mbox_free(sys_mbox_t *mbox); -#define sys_mbox_fetch(mbox, msg) sys_arch_mbox_fetch(mbox, msg, 0) -#ifndef sys_mbox_valid -/** - * @ingroup sys_mbox - * Returns 1 if the mailbox is valid, 0 if it is not valid. - * When using pointers, a simple way is to check the pointer for != NULL. - * When directly using OS structures, implementing this may be more complex. - * This may also be a define, in which case the function is not prototyped. - */ -int sys_mbox_valid(sys_mbox_t *mbox); -#endif -#ifndef sys_mbox_set_invalid -/** - * @ingroup sys_mbox - * Invalidate a mailbox so that sys_mbox_valid() returns 0. - * ATTENTION: This does NOT mean that the mailbox shall be deallocated: - * sys_mbox_free() is always called before calling this function! - * This may also be a define, in which case the function is not prototyped. - */ -void sys_mbox_set_invalid(sys_mbox_t *mbox); -#endif -#ifndef sys_mbox_valid_val -/** - * Same as sys_mbox_valid() but taking a value, not a pointer - */ -#define sys_mbox_valid_val(mbox) sys_mbox_valid(&(mbox)) -#endif -#ifndef sys_mbox_set_invalid_val -/** - * Same as sys_mbox_set_invalid() but taking a value, not a pointer - */ -#define sys_mbox_set_invalid_val(mbox) sys_mbox_set_invalid(&(mbox)) -#endif - - -/** - * @ingroup sys_misc - * The only thread function: - * Starts a new thread named "name" with priority "prio" that will begin its - * execution in the function "thread()". The "arg" argument will be passed as an - * argument to the thread() function. The stack size to used for this thread is - * the "stacksize" parameter. The id of the new thread is returned. Both the id - * and the priority are system dependent. - * ATTENTION: although this function returns a value, it MUST NOT FAIL (ports have to assert this!) - * - * @param name human-readable name for the thread (used for debugging purposes) - * @param thread thread-function - * @param arg parameter passed to 'thread' - * @param stacksize stack size in bytes for the new thread (may be ignored by ports) - * @param prio priority of the new thread (may be ignored by ports) */ -sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio); - -#endif /* NO_SYS */ - -/** - * @ingroup sys_misc - * sys_init() must be called before anything else. - * Initialize the sys_arch layer. - */ -void sys_init(void); - -#ifndef sys_jiffies -/** - * Ticks/jiffies since power up. - */ -u32_t sys_jiffies(void); -#endif - -/** - * @ingroup sys_time - * Returns the current time in milliseconds, - * may be the same as sys_jiffies or at least based on it. - * Don't care for wraparound, this is only used for time diffs. - * Not implementing this function means you cannot use some modules (e.g. TCP - * timestamps, internal timeouts for NO_SYS==1). - */ -u32_t sys_now(void); - -/* Critical Region Protection */ -/* These functions must be implemented in the sys_arch.c file. - In some implementations they can provide a more light-weight protection - mechanism than using semaphores. Otherwise semaphores can be used for - implementation */ -#ifndef SYS_ARCH_PROTECT -/** SYS_LIGHTWEIGHT_PROT - * define SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection - * for certain critical regions during buffer allocation, deallocation and memory - * allocation and deallocation. - */ -#if SYS_LIGHTWEIGHT_PROT - -/** - * @ingroup sys_prot - * SYS_ARCH_DECL_PROTECT - * declare a protection variable. This macro will default to defining a variable of - * type sys_prot_t. If a particular port needs a different implementation, then - * this macro may be defined in sys_arch.h. - */ -#define SYS_ARCH_DECL_PROTECT(lev) sys_prot_t lev -/** - * @ingroup sys_prot - * SYS_ARCH_PROTECT - * Perform a "fast" protect. This could be implemented by - * disabling interrupts for an embedded system or by using a semaphore or - * mutex. The implementation should allow calling SYS_ARCH_PROTECT when - * already protected. The old protection level is returned in the variable - * "lev". This macro will default to calling the sys_arch_protect() function - * which should be implemented in sys_arch.c. If a particular port needs a - * different implementation, then this macro may be defined in sys_arch.h - */ -#define SYS_ARCH_PROTECT(lev) lev = sys_arch_protect() -/** - * @ingroup sys_prot - * SYS_ARCH_UNPROTECT - * Perform a "fast" set of the protection level to "lev". This could be - * implemented by setting the interrupt level to "lev" within the MACRO or by - * using a semaphore or mutex. This macro will default to calling the - * sys_arch_unprotect() function which should be implemented in - * sys_arch.c. If a particular port needs a different implementation, then - * this macro may be defined in sys_arch.h - */ -#define SYS_ARCH_UNPROTECT(lev) sys_arch_unprotect(lev) -sys_prot_t sys_arch_protect(void); -void sys_arch_unprotect(sys_prot_t pval); - -#else - -#define SYS_ARCH_DECL_PROTECT(lev) -#define SYS_ARCH_PROTECT(lev) -#define SYS_ARCH_UNPROTECT(lev) - -#endif /* SYS_LIGHTWEIGHT_PROT */ - -#endif /* SYS_ARCH_PROTECT */ - -/* - * Macros to set/get and increase/decrease variables in a thread-safe way. - * Use these for accessing variable that are used from more than one thread. - */ - -#ifndef SYS_ARCH_INC -#define SYS_ARCH_INC(var, val) do { \ - SYS_ARCH_DECL_PROTECT(old_level); \ - SYS_ARCH_PROTECT(old_level); \ - var += val; \ - SYS_ARCH_UNPROTECT(old_level); \ - } while(0) -#endif /* SYS_ARCH_INC */ - -#ifndef SYS_ARCH_DEC -#define SYS_ARCH_DEC(var, val) do { \ - SYS_ARCH_DECL_PROTECT(old_level); \ - SYS_ARCH_PROTECT(old_level); \ - var -= val; \ - SYS_ARCH_UNPROTECT(old_level); \ - } while(0) -#endif /* SYS_ARCH_DEC */ - -#ifndef SYS_ARCH_GET -#define SYS_ARCH_GET(var, ret) do { \ - SYS_ARCH_DECL_PROTECT(old_level); \ - SYS_ARCH_PROTECT(old_level); \ - ret = var; \ - SYS_ARCH_UNPROTECT(old_level); \ - } while(0) -#endif /* SYS_ARCH_GET */ - -#ifndef SYS_ARCH_SET -#define SYS_ARCH_SET(var, val) do { \ - SYS_ARCH_DECL_PROTECT(old_level); \ - SYS_ARCH_PROTECT(old_level); \ - var = val; \ - SYS_ARCH_UNPROTECT(old_level); \ - } while(0) -#endif /* SYS_ARCH_SET */ - -#ifndef SYS_ARCH_LOCKED -#define SYS_ARCH_LOCKED(code) do { \ - SYS_ARCH_DECL_PROTECT(old_level); \ - SYS_ARCH_PROTECT(old_level); \ - code; \ - SYS_ARCH_UNPROTECT(old_level); \ - } while(0) -#endif /* SYS_ARCH_LOCKED */ - - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_SYS_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/tcp.h b/third-party/lwip-2.1.2/include/lwip/tcp.h deleted file mode 100644 index daf75994..00000000 --- a/third-party/lwip-2.1.2/include/lwip/tcp.h +++ /dev/null @@ -1,500 +0,0 @@ -/** - * @file - * TCP API (to be used from TCPIP thread)\n - * See also @ref tcp_raw - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_TCP_H -#define LWIP_HDR_TCP_H - -#include "lwip/opt.h" - -#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/tcpbase.h" -#include "lwip/mem.h" -#include "lwip/pbuf.h" -#include "lwip/ip.h" -#include "lwip/icmp.h" -#include "lwip/err.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct tcp_pcb; -struct tcp_pcb_listen; - -/** Function prototype for tcp accept callback functions. Called when a new - * connection can be accepted on a listening pcb. - * - * @param arg Additional argument to pass to the callback function (@see tcp_arg()) - * @param newpcb The new connection pcb - * @param err An error code if there has been an error accepting. - * Only return ERR_ABRT if you have called tcp_abort from within the - * callback function! - */ -typedef err_t (*tcp_accept_fn)(void *arg, struct tcp_pcb *newpcb, err_t err); - -/** Function prototype for tcp receive callback functions. Called when data has - * been received. - * - * @param arg Additional argument to pass to the callback function (@see tcp_arg()) - * @param tpcb The connection pcb which received data - * @param p The received data (or NULL when the connection has been closed!) - * @param err An error code if there has been an error receiving - * Only return ERR_ABRT if you have called tcp_abort from within the - * callback function! - */ -typedef err_t (*tcp_recv_fn)(void *arg, struct tcp_pcb *tpcb, - struct pbuf *p, err_t err); - -/** Function prototype for tcp sent callback functions. Called when sent data has - * been acknowledged by the remote side. Use it to free corresponding resources. - * This also means that the pcb has now space available to send new data. - * - * @param arg Additional argument to pass to the callback function (@see tcp_arg()) - * @param tpcb The connection pcb for which data has been acknowledged - * @param len The amount of bytes acknowledged - * @return ERR_OK: try to send some data by calling tcp_output - * Only return ERR_ABRT if you have called tcp_abort from within the - * callback function! - */ -typedef err_t (*tcp_sent_fn)(void *arg, struct tcp_pcb *tpcb, - u16_t len); - -/** Function prototype for tcp poll callback functions. Called periodically as - * specified by @see tcp_poll. - * - * @param arg Additional argument to pass to the callback function (@see tcp_arg()) - * @param tpcb tcp pcb - * @return ERR_OK: try to send some data by calling tcp_output - * Only return ERR_ABRT if you have called tcp_abort from within the - * callback function! - */ -typedef err_t (*tcp_poll_fn)(void *arg, struct tcp_pcb *tpcb); - -/** Function prototype for tcp error callback functions. Called when the pcb - * receives a RST or is unexpectedly closed for any other reason. - * - * @note The corresponding pcb is already freed when this callback is called! - * - * @param arg Additional argument to pass to the callback function (@see tcp_arg()) - * @param err Error code to indicate why the pcb has been closed - * ERR_ABRT: aborted through tcp_abort or by a TCP timer - * ERR_RST: the connection was reset by the remote host - */ -typedef void (*tcp_err_fn)(void *arg, err_t err); - -/** Function prototype for tcp connected callback functions. Called when a pcb - * is connected to the remote side after initiating a connection attempt by - * calling tcp_connect(). - * - * @param arg Additional argument to pass to the callback function (@see tcp_arg()) - * @param tpcb The connection pcb which is connected - * @param err An unused error code, always ERR_OK currently ;-) @todo! - * Only return ERR_ABRT if you have called tcp_abort from within the - * callback function! - * - * @note When a connection attempt fails, the error callback is currently called! - */ -typedef err_t (*tcp_connected_fn)(void *arg, struct tcp_pcb *tpcb, err_t err); - -#if LWIP_WND_SCALE -#define RCV_WND_SCALE(pcb, wnd) (((wnd) >> (pcb)->rcv_scale)) -#define SND_WND_SCALE(pcb, wnd) (((wnd) << (pcb)->snd_scale)) -#define TCPWND16(x) ((u16_t)LWIP_MIN((x), 0xFFFF)) -#define TCP_WND_MAX(pcb) ((tcpwnd_size_t)(((pcb)->flags & TF_WND_SCALE) ? TCP_WND : TCPWND16(TCP_WND))) -#else -#define RCV_WND_SCALE(pcb, wnd) (wnd) -#define SND_WND_SCALE(pcb, wnd) (wnd) -#define TCPWND16(x) (x) -#define TCP_WND_MAX(pcb) TCP_WND -#endif -/* Increments a tcpwnd_size_t and holds at max value rather than rollover */ -#define TCP_WND_INC(wnd, inc) do { \ - if ((tcpwnd_size_t)(wnd + inc) >= wnd) { \ - wnd = (tcpwnd_size_t)(wnd + inc); \ - } else { \ - wnd = (tcpwnd_size_t)-1; \ - } \ - } while(0) - -#if LWIP_TCP_SACK_OUT -/** SACK ranges to include in ACK packets. - * SACK entry is invalid if left==right. */ -struct tcp_sack_range { - /** Left edge of the SACK: the first acknowledged sequence number. */ - u32_t left; - /** Right edge of the SACK: the last acknowledged sequence number +1 (so first NOT acknowledged). */ - u32_t right; -}; -#endif /* LWIP_TCP_SACK_OUT */ - -/** Function prototype for deallocation of arguments. Called *just before* the - * pcb is freed, so don't expect to be able to do anything with this pcb! - * - * @param id ext arg id (allocated via @ref tcp_ext_arg_alloc_id) - * @param data pointer to the data (set via @ref tcp_ext_arg_set before) - */ -typedef void (*tcp_extarg_callback_pcb_destroyed_fn)(u8_t id, void *data); - -/** Function prototype to transition arguments from a listening pcb to an accepted pcb - * - * @param id ext arg id (allocated via @ref tcp_ext_arg_alloc_id) - * @param lpcb the listening pcb accepting a connection - * @param cpcb the newly allocated connection pcb - * @return ERR_OK if OK, any error if connection should be dropped - */ -typedef err_t (*tcp_extarg_callback_passive_open_fn)(u8_t id, struct tcp_pcb_listen *lpcb, struct tcp_pcb *cpcb); - -/** A table of callback functions that is invoked for ext arguments */ -struct tcp_ext_arg_callbacks { - /** @ref tcp_extarg_callback_pcb_destroyed_fn */ - tcp_extarg_callback_pcb_destroyed_fn destroy; - /** @ref tcp_extarg_callback_passive_open_fn */ - tcp_extarg_callback_passive_open_fn passive_open; -}; - -#define LWIP_TCP_PCB_NUM_EXT_ARG_ID_INVALID 0xFF - -#if LWIP_TCP_PCB_NUM_EXT_ARGS -/* This is the structure for ext args in tcp pcbs (used as array) */ -struct tcp_pcb_ext_args { - const struct tcp_ext_arg_callbacks *callbacks; - void *data; -}; -/* This is a helper define to prevent zero size arrays if disabled */ -#define TCP_PCB_EXTARGS struct tcp_pcb_ext_args ext_args[LWIP_TCP_PCB_NUM_EXT_ARGS]; -#else -#define TCP_PCB_EXTARGS -#endif - -typedef u16_t tcpflags_t; -#define TCP_ALLFLAGS 0xffffU - -/** - * members common to struct tcp_pcb and struct tcp_listen_pcb - */ -#define TCP_PCB_COMMON(type) \ - type *next; /* for the linked list */ \ - void *callback_arg; \ - TCP_PCB_EXTARGS \ - enum tcp_state state; /* TCP state */ \ - u8_t prio; \ - /* ports are in host byte order */ \ - u16_t local_port - - -/** the TCP protocol control block for listening pcbs */ -struct tcp_pcb_listen { -/** Common members of all PCB types */ - IP_PCB; -/** Protocol specific PCB members */ - TCP_PCB_COMMON(struct tcp_pcb_listen); - -#if LWIP_CALLBACK_API - /* Function to call when a listener has been connected. */ - tcp_accept_fn accept; -#endif /* LWIP_CALLBACK_API */ - -#if TCP_LISTEN_BACKLOG - u8_t backlog; - u8_t accepts_pending; -#endif /* TCP_LISTEN_BACKLOG */ -}; - - -/** the TCP protocol control block */ -struct tcp_pcb { -/** common PCB members */ - IP_PCB; -/** protocol specific PCB members */ - TCP_PCB_COMMON(struct tcp_pcb); - - /* ports are in host byte order */ - u16_t remote_port; - - tcpflags_t flags; -#define TF_ACK_DELAY 0x01U /* Delayed ACK. */ -#define TF_ACK_NOW 0x02U /* Immediate ACK. */ -#define TF_INFR 0x04U /* In fast recovery. */ -#define TF_CLOSEPEND 0x08U /* If this is set, tcp_close failed to enqueue the FIN (retried in tcp_tmr) */ -#define TF_RXCLOSED 0x10U /* rx closed by tcp_shutdown */ -#define TF_FIN 0x20U /* Connection was closed locally (FIN segment enqueued). */ -#define TF_NODELAY 0x40U /* Disable Nagle algorithm */ -#define TF_NAGLEMEMERR 0x80U /* nagle enabled, memerr, try to output to prevent delayed ACK to happen */ -#if LWIP_WND_SCALE -#define TF_WND_SCALE 0x0100U /* Window Scale option enabled */ -#endif -#if TCP_LISTEN_BACKLOG -#define TF_BACKLOGPEND 0x0200U /* If this is set, a connection pcb has increased the backlog on its listener */ -#endif -#if LWIP_TCP_TIMESTAMPS -#define TF_TIMESTAMP 0x0400U /* Timestamp option enabled */ -#endif -#define TF_RTO 0x0800U /* RTO timer has fired, in-flight data moved to unsent and being retransmitted */ -#if LWIP_TCP_SACK_OUT -#define TF_SACK 0x1000U /* Selective ACKs enabled */ -#endif - - /* the rest of the fields are in host byte order - as we have to do some math with them */ - - /* Timers */ - u8_t polltmr, pollinterval; - u8_t last_timer; - u32_t tmr; - - /* receiver variables */ - u32_t rcv_nxt; /* next seqno expected */ - tcpwnd_size_t rcv_wnd; /* receiver window available */ - tcpwnd_size_t rcv_ann_wnd; /* receiver window to announce */ - u32_t rcv_ann_right_edge; /* announced right edge of window */ - -#if LWIP_TCP_SACK_OUT - /* SACK ranges to include in ACK packets (entry is invalid if left==right) */ - struct tcp_sack_range rcv_sacks[LWIP_TCP_MAX_SACK_NUM]; -#define LWIP_TCP_SACK_VALID(pcb, idx) ((pcb)->rcv_sacks[idx].left != (pcb)->rcv_sacks[idx].right) -#endif /* LWIP_TCP_SACK_OUT */ - - /* Retransmission timer. */ - s16_t rtime; - - u16_t mss; /* maximum segment size */ - - /* RTT (round trip time) estimation variables */ - u32_t rttest; /* RTT estimate in 500ms ticks */ - u32_t rtseq; /* sequence number being timed */ - s16_t sa, sv; /* @see "Congestion Avoidance and Control" by Van Jacobson and Karels */ - - s16_t rto; /* retransmission time-out (in ticks of TCP_SLOW_INTERVAL) */ - u8_t nrtx; /* number of retransmissions */ - - /* fast retransmit/recovery */ - u8_t dupacks; - u32_t lastack; /* Highest acknowledged seqno. */ - - /* congestion avoidance/control variables */ - tcpwnd_size_t cwnd; - tcpwnd_size_t ssthresh; - - /* first byte following last rto byte */ - u32_t rto_end; - - /* sender variables */ - u32_t snd_nxt; /* next new seqno to be sent */ - u32_t snd_wl1, snd_wl2; /* Sequence and acknowledgement numbers of last - window update. */ - u32_t snd_lbb; /* Sequence number of next byte to be buffered. */ - tcpwnd_size_t snd_wnd; /* sender window */ - tcpwnd_size_t snd_wnd_max; /* the maximum sender window announced by the remote host */ - - tcpwnd_size_t snd_buf; /* Available buffer space for sending (in bytes). */ -#define TCP_SNDQUEUELEN_OVERFLOW (0xffffU-3) - u16_t snd_queuelen; /* Number of pbufs currently in the send buffer. */ - -#if TCP_OVERSIZE - /* Extra bytes available at the end of the last pbuf in unsent. */ - u16_t unsent_oversize; -#endif /* TCP_OVERSIZE */ - - tcpwnd_size_t bytes_acked; - - /* These are ordered by sequence number: */ - struct tcp_seg *unsent; /* Unsent (queued) segments. */ - struct tcp_seg *unacked; /* Sent but unacknowledged segments. */ -#if TCP_QUEUE_OOSEQ - struct tcp_seg *ooseq; /* Received out of sequence segments. */ -#endif /* TCP_QUEUE_OOSEQ */ - - struct pbuf *refused_data; /* Data previously received but not yet taken by upper layer */ - -#if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG - struct tcp_pcb_listen* listener; -#endif /* LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG */ - -#if LWIP_CALLBACK_API - /* Function to be called when more send buffer space is available. */ - tcp_sent_fn sent; - /* Function to be called when (in-sequence) data has arrived. */ - tcp_recv_fn recv; - /* Function to be called when a connection has been set up. */ - tcp_connected_fn connected; - /* Function which is called periodically. */ - tcp_poll_fn poll; - /* Function to be called whenever a fatal error occurs. */ - tcp_err_fn errf; -#endif /* LWIP_CALLBACK_API */ - -#if LWIP_TCP_TIMESTAMPS - u32_t ts_lastacksent; - u32_t ts_recent; -#endif /* LWIP_TCP_TIMESTAMPS */ - - /* idle time before KEEPALIVE is sent */ - u32_t keep_idle; -#if LWIP_TCP_KEEPALIVE - u32_t keep_intvl; - u32_t keep_cnt; -#endif /* LWIP_TCP_KEEPALIVE */ - - /* Persist timer counter */ - u8_t persist_cnt; - /* Persist timer back-off */ - u8_t persist_backoff; - /* Number of persist probes */ - u8_t persist_probe; - - /* KEEPALIVE counter */ - u8_t keep_cnt_sent; - -#if LWIP_WND_SCALE - u8_t snd_scale; - u8_t rcv_scale; -#endif -}; - -#if LWIP_EVENT_API - -enum lwip_event { - LWIP_EVENT_ACCEPT, - LWIP_EVENT_SENT, - LWIP_EVENT_RECV, - LWIP_EVENT_CONNECTED, - LWIP_EVENT_POLL, - LWIP_EVENT_ERR -}; - -err_t lwip_tcp_event(void *arg, struct tcp_pcb *pcb, - enum lwip_event, - struct pbuf *p, - u16_t size, - err_t err); - -#endif /* LWIP_EVENT_API */ - -/* Application program's interface: */ -struct tcp_pcb * tcp_new (void); -struct tcp_pcb * tcp_new_ip_type (u8_t type); - -void tcp_arg (struct tcp_pcb *pcb, void *arg); -#if LWIP_CALLBACK_API -void tcp_recv (struct tcp_pcb *pcb, tcp_recv_fn recv); -void tcp_sent (struct tcp_pcb *pcb, tcp_sent_fn sent); -void tcp_err (struct tcp_pcb *pcb, tcp_err_fn err); -void tcp_accept (struct tcp_pcb *pcb, tcp_accept_fn accept); -#endif /* LWIP_CALLBACK_API */ -void tcp_poll (struct tcp_pcb *pcb, tcp_poll_fn poll, u8_t interval); - -#define tcp_set_flags(pcb, set_flags) do { (pcb)->flags = (tcpflags_t)((pcb)->flags | (set_flags)); } while(0) -#define tcp_clear_flags(pcb, clr_flags) do { (pcb)->flags = (tcpflags_t)((pcb)->flags & (tcpflags_t)(~(clr_flags) & TCP_ALLFLAGS)); } while(0) -#define tcp_is_flag_set(pcb, flag) (((pcb)->flags & (flag)) != 0) - -#if LWIP_TCP_TIMESTAMPS -#define tcp_mss(pcb) (((pcb)->flags & TF_TIMESTAMP) ? ((pcb)->mss - 12) : (pcb)->mss) -#else /* LWIP_TCP_TIMESTAMPS */ -/** @ingroup tcp_raw */ -#define tcp_mss(pcb) ((pcb)->mss) -#endif /* LWIP_TCP_TIMESTAMPS */ -/** @ingroup tcp_raw */ -#define tcp_sndbuf(pcb) (TCPWND16((pcb)->snd_buf)) -/** @ingroup tcp_raw */ -#define tcp_sndqueuelen(pcb) ((pcb)->snd_queuelen) -/** @ingroup tcp_raw */ -#define tcp_nagle_disable(pcb) tcp_set_flags(pcb, TF_NODELAY) -/** @ingroup tcp_raw */ -#define tcp_nagle_enable(pcb) tcp_clear_flags(pcb, TF_NODELAY) -/** @ingroup tcp_raw */ -#define tcp_nagle_disabled(pcb) tcp_is_flag_set(pcb, TF_NODELAY) - -#if TCP_LISTEN_BACKLOG -#define tcp_backlog_set(pcb, new_backlog) do { \ - LWIP_ASSERT("pcb->state == LISTEN (called for wrong pcb?)", (pcb)->state == LISTEN); \ - ((struct tcp_pcb_listen *)(pcb))->backlog = ((new_backlog) ? (new_backlog) : 1); } while(0) -void tcp_backlog_delayed(struct tcp_pcb* pcb); -void tcp_backlog_accepted(struct tcp_pcb* pcb); -#else /* TCP_LISTEN_BACKLOG */ -#define tcp_backlog_set(pcb, new_backlog) -#define tcp_backlog_delayed(pcb) -#define tcp_backlog_accepted(pcb) -#endif /* TCP_LISTEN_BACKLOG */ -#define tcp_accepted(pcb) do { LWIP_UNUSED_ARG(pcb); } while(0) /* compatibility define, not needed any more */ - -void tcp_recved (struct tcp_pcb *pcb, u16_t len); -err_t tcp_bind (struct tcp_pcb *pcb, const ip_addr_t *ipaddr, - u16_t port); -void tcp_bind_netif(struct tcp_pcb *pcb, const struct netif *netif); -err_t tcp_connect (struct tcp_pcb *pcb, const ip_addr_t *ipaddr, - u16_t port, tcp_connected_fn connected); - -struct tcp_pcb * tcp_listen_with_backlog_and_err(struct tcp_pcb *pcb, u8_t backlog, err_t *err); -struct tcp_pcb * tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog); -/** @ingroup tcp_raw */ -#define tcp_listen(pcb) tcp_listen_with_backlog(pcb, TCP_DEFAULT_LISTEN_BACKLOG) - -void tcp_abort (struct tcp_pcb *pcb); -err_t tcp_close (struct tcp_pcb *pcb); -err_t tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx); - -err_t tcp_write (struct tcp_pcb *pcb, const void *dataptr, u16_t len, - u8_t apiflags); - -void tcp_setprio (struct tcp_pcb *pcb, u8_t prio); - -err_t tcp_output (struct tcp_pcb *pcb); - -err_t tcp_tcp_get_tcp_addrinfo(struct tcp_pcb *pcb, int local, ip_addr_t *addr, u16_t *port); - -#define tcp_dbg_get_tcp_state(pcb) ((pcb)->state) - -/* for compatibility with older implementation */ -#define tcp_new_ip6() tcp_new_ip_type(IPADDR_TYPE_V6) - -#if LWIP_TCP_PCB_NUM_EXT_ARGS -u8_t tcp_ext_arg_alloc_id(void); -void tcp_ext_arg_set_callbacks(struct tcp_pcb *pcb, uint8_t id, const struct tcp_ext_arg_callbacks * const callbacks); -void tcp_ext_arg_set(struct tcp_pcb *pcb, uint8_t id, void *arg); -void *tcp_ext_arg_get(const struct tcp_pcb *pcb, uint8_t id); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_TCP */ - -#endif /* LWIP_HDR_TCP_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/tcpbase.h b/third-party/lwip-2.1.2/include/lwip/tcpbase.h deleted file mode 100644 index 00230746..00000000 --- a/third-party/lwip-2.1.2/include/lwip/tcpbase.h +++ /dev/null @@ -1,88 +0,0 @@ -/** - * @file - * Base TCP API definitions shared by TCP and ALTCP\n - * See also @ref tcp_raw - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_TCPBASE_H -#define LWIP_HDR_TCPBASE_H - -#include "lwip/opt.h" - -#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ - -#ifdef __cplusplus -extern "C" { -#endif - - -#if LWIP_WND_SCALE -typedef u32_t tcpwnd_size_t; -#else -typedef u16_t tcpwnd_size_t; -#endif - -enum tcp_state { - CLOSED = 0, - LISTEN = 1, - SYN_SENT = 2, - SYN_RCVD = 3, - ESTABLISHED = 4, - FIN_WAIT_1 = 5, - FIN_WAIT_2 = 6, - CLOSE_WAIT = 7, - CLOSING = 8, - LAST_ACK = 9, - TIME_WAIT = 10 -}; -/* ATTENTION: this depends on state number ordering! */ -#define TCP_STATE_IS_CLOSING(state) ((state) >= FIN_WAIT_1) - -/* Flags for "apiflags" parameter in tcp_write */ -#define TCP_WRITE_FLAG_COPY 0x01 -#define TCP_WRITE_FLAG_MORE 0x02 - -#define TCP_PRIO_MIN 1 -#define TCP_PRIO_NORMAL 64 -#define TCP_PRIO_MAX 127 - -const char* tcp_debug_state_str(enum tcp_state s); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_TCP */ - -#endif /* LWIP_HDR_TCPBASE_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/tcpip.h b/third-party/lwip-2.1.2/include/lwip/tcpip.h deleted file mode 100644 index 0b8880a9..00000000 --- a/third-party/lwip-2.1.2/include/lwip/tcpip.h +++ /dev/null @@ -1,113 +0,0 @@ -/** - * @file - * Functions to sync with TCPIP thread - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_TCPIP_H -#define LWIP_HDR_TCPIP_H - -#include "lwip/opt.h" - -#if !NO_SYS /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/err.h" -#include "lwip/timeouts.h" -#include "lwip/netif.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if LWIP_TCPIP_CORE_LOCKING -/** The global semaphore to lock the stack. */ -extern sys_mutex_t lock_tcpip_core; -#if !defined LOCK_TCPIP_CORE || defined __DOXYGEN__ -/** Lock lwIP core mutex (needs @ref LWIP_TCPIP_CORE_LOCKING 1) */ -#define LOCK_TCPIP_CORE() sys_mutex_lock(&lock_tcpip_core) -/** Unlock lwIP core mutex (needs @ref LWIP_TCPIP_CORE_LOCKING 1) */ -#define UNLOCK_TCPIP_CORE() sys_mutex_unlock(&lock_tcpip_core) -#endif /* LOCK_TCPIP_CORE */ -#else /* LWIP_TCPIP_CORE_LOCKING */ -#define LOCK_TCPIP_CORE() -#define UNLOCK_TCPIP_CORE() -#endif /* LWIP_TCPIP_CORE_LOCKING */ - -struct pbuf; -struct netif; - -/** Function prototype for the init_done function passed to tcpip_init */ -typedef void (*tcpip_init_done_fn)(void *arg); -/** Function prototype for functions passed to tcpip_callback() */ -typedef void (*tcpip_callback_fn)(void *ctx); - -/* Forward declarations */ -struct tcpip_callback_msg; - -void tcpip_init(tcpip_init_done_fn tcpip_init_done, void *arg); - -err_t tcpip_inpkt(struct pbuf *p, struct netif *inp, netif_input_fn input_fn); -err_t tcpip_input(struct pbuf *p, struct netif *inp); - -err_t tcpip_try_callback(tcpip_callback_fn function, void *ctx); -err_t tcpip_callback(tcpip_callback_fn function, void *ctx); -/** @ingroup lwip_os - * @deprecated use tcpip_try_callback() or tcpip_callback() instead - */ -#define tcpip_callback_with_block(function, ctx, block) ((block != 0)? tcpip_callback(function, ctx) : tcpip_try_callback(function, ctx)) - -struct tcpip_callback_msg* tcpip_callbackmsg_new(tcpip_callback_fn function, void *ctx); -void tcpip_callbackmsg_delete(struct tcpip_callback_msg* msg); -err_t tcpip_callbackmsg_trycallback(struct tcpip_callback_msg* msg); -err_t tcpip_callbackmsg_trycallback_fromisr(struct tcpip_callback_msg* msg); - -/* free pbufs or heap memory from another context without blocking */ -err_t pbuf_free_callback(struct pbuf *p); -err_t mem_free_callback(void *m); - -#if LWIP_TCPIP_TIMEOUT && LWIP_TIMERS -err_t tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg); -err_t tcpip_untimeout(sys_timeout_handler h, void *arg); -#endif /* LWIP_TCPIP_TIMEOUT && LWIP_TIMERS */ - -#ifdef TCPIP_THREAD_TEST -int tcpip_thread_poll_one(void); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* !NO_SYS */ - -#endif /* LWIP_HDR_TCPIP_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/timeouts.h b/third-party/lwip-2.1.2/include/lwip/timeouts.h deleted file mode 100644 index b601f9eb..00000000 --- a/third-party/lwip-2.1.2/include/lwip/timeouts.h +++ /dev/null @@ -1,128 +0,0 @@ -/** - * @file - * Timer implementations - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * Simon Goldschmidt - * - */ -#ifndef LWIP_HDR_TIMEOUTS_H -#define LWIP_HDR_TIMEOUTS_H - -#include "lwip/opt.h" -#include "lwip/err.h" -#if !NO_SYS -#include "lwip/sys.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef LWIP_DEBUG_TIMERNAMES -#ifdef LWIP_DEBUG -#define LWIP_DEBUG_TIMERNAMES SYS_DEBUG -#else /* LWIP_DEBUG */ -#define LWIP_DEBUG_TIMERNAMES 0 -#endif /* LWIP_DEBUG*/ -#endif - -/** Returned by sys_timeouts_sleeptime() to indicate there is no timer, so we - * can sleep forever. - */ -#define SYS_TIMEOUTS_SLEEPTIME_INFINITE 0xFFFFFFFF - -/** Function prototype for a stack-internal timer function that has to be - * called at a defined interval */ -typedef void (* lwip_cyclic_timer_handler)(void); - -/** This struct contains information about a stack-internal timer function - that has to be called at a defined interval */ -struct lwip_cyclic_timer { - u32_t interval_ms; - lwip_cyclic_timer_handler handler; -#if LWIP_DEBUG_TIMERNAMES - const char* handler_name; -#endif /* LWIP_DEBUG_TIMERNAMES */ -}; - -/** This array contains all stack-internal cyclic timers. To get the number of - * timers, use lwip_num_cyclic_timers */ -extern const struct lwip_cyclic_timer lwip_cyclic_timers[]; -/** Array size of lwip_cyclic_timers[] */ -extern const int lwip_num_cyclic_timers; - -#if LWIP_TIMERS - -/** Function prototype for a timeout callback function. Register such a function - * using sys_timeout(). - * - * @param arg Additional argument to pass to the function - set up by sys_timeout() - */ -typedef void (* sys_timeout_handler)(void *arg); - -struct sys_timeo { - struct sys_timeo *next; - u32_t time; - sys_timeout_handler h; - void *arg; -#if LWIP_DEBUG_TIMERNAMES - const char* handler_name; -#endif /* LWIP_DEBUG_TIMERNAMES */ -}; - -void sys_timeouts_init(void); - -#if LWIP_DEBUG_TIMERNAMES -void sys_timeout_debug(u32_t msecs, sys_timeout_handler handler, void *arg, const char* handler_name); -#define sys_timeout(msecs, handler, arg) sys_timeout_debug(msecs, handler, arg, #handler) -#else /* LWIP_DEBUG_TIMERNAMES */ -void sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg); -#endif /* LWIP_DEBUG_TIMERNAMES */ - -void sys_untimeout(sys_timeout_handler handler, void *arg); -void sys_restart_timeouts(void); -void sys_check_timeouts(void); -u32_t sys_timeouts_sleeptime(void); - -#if LWIP_TESTMODE -struct sys_timeo** sys_timeouts_get_next_timeout(void); -void lwip_cyclic_timer(void *arg); -#endif - -#endif /* LWIP_TIMERS */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_TIMEOUTS_H */ diff --git a/third-party/lwip-2.1.2/include/lwip/udp.h b/third-party/lwip-2.1.2/include/lwip/udp.h deleted file mode 100644 index b1c78e58..00000000 --- a/third-party/lwip-2.1.2/include/lwip/udp.h +++ /dev/null @@ -1,195 +0,0 @@ -/** - * @file - * UDP API (to be used from TCPIP thread)\n - * See also @ref udp_raw - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_UDP_H -#define LWIP_HDR_UDP_H - -#include "lwip/opt.h" - -#if LWIP_UDP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/pbuf.h" -#include "lwip/netif.h" -#include "lwip/ip_addr.h" -#include "lwip/ip.h" -#include "lwip/ip6_addr.h" -#include "lwip/prot/udp.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define UDP_FLAGS_NOCHKSUM 0x01U -#define UDP_FLAGS_UDPLITE 0x02U -#define UDP_FLAGS_CONNECTED 0x04U -#define UDP_FLAGS_MULTICAST_LOOP 0x08U - -struct udp_pcb; - -/** Function prototype for udp pcb receive callback functions - * addr and port are in same byte order as in the pcb - * The callback is responsible for freeing the pbuf - * if it's not used any more. - * - * ATTENTION: Be aware that 'addr' might point into the pbuf 'p' so freeing this pbuf - * can make 'addr' invalid, too. - * - * @param arg user supplied argument (udp_pcb.recv_arg) - * @param pcb the udp_pcb which received data - * @param p the packet buffer that was received - * @param addr the remote IP address from which the packet was received - * @param port the remote port from which the packet was received - */ -typedef void (*udp_recv_fn)(void *arg, struct udp_pcb *pcb, struct pbuf *p, - const ip_addr_t *addr, u16_t port); - -/** the UDP protocol control block */ -struct udp_pcb { -/** Common members of all PCB types */ - IP_PCB; - -/* Protocol specific PCB members */ - - struct udp_pcb *next; - - u8_t flags; - /** ports are in host byte order */ - u16_t local_port, remote_port; - -#if LWIP_MULTICAST_TX_OPTIONS -#if LWIP_IPV4 - /** outgoing network interface for multicast packets, by IPv4 address (if not 'any') */ - ip4_addr_t mcast_ip4; -#endif /* LWIP_IPV4 */ - /** outgoing network interface for multicast packets, by interface index (if nonzero) */ - u8_t mcast_ifindex; - /** TTL for outgoing multicast packets */ - u8_t mcast_ttl; -#endif /* LWIP_MULTICAST_TX_OPTIONS */ - -#if LWIP_UDPLITE - /** used for UDP_LITE only */ - u16_t chksum_len_rx, chksum_len_tx; -#endif /* LWIP_UDPLITE */ - - /** receive callback function */ - udp_recv_fn recv; - /** user-supplied argument for the recv callback */ - void *recv_arg; -}; -/* udp_pcbs export for external reference (e.g. SNMP agent) */ -extern struct udp_pcb *udp_pcbs; - -/* The following functions is the application layer interface to the - UDP code. */ -struct udp_pcb * udp_new (void); -struct udp_pcb * udp_new_ip_type(u8_t type); -void udp_remove (struct udp_pcb *pcb); -err_t udp_bind (struct udp_pcb *pcb, const ip_addr_t *ipaddr, - u16_t port); -void udp_bind_netif (struct udp_pcb *pcb, const struct netif* netif); -err_t udp_connect (struct udp_pcb *pcb, const ip_addr_t *ipaddr, - u16_t port); -void udp_disconnect (struct udp_pcb *pcb); -void udp_recv (struct udp_pcb *pcb, udp_recv_fn recv, - void *recv_arg); -err_t udp_sendto_if (struct udp_pcb *pcb, struct pbuf *p, - const ip_addr_t *dst_ip, u16_t dst_port, - struct netif *netif); -err_t udp_sendto_if_src(struct udp_pcb *pcb, struct pbuf *p, - const ip_addr_t *dst_ip, u16_t dst_port, - struct netif *netif, const ip_addr_t *src_ip); -err_t udp_sendto (struct udp_pcb *pcb, struct pbuf *p, - const ip_addr_t *dst_ip, u16_t dst_port); -err_t udp_send (struct udp_pcb *pcb, struct pbuf *p); - -#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP -err_t udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, - const ip_addr_t *dst_ip, u16_t dst_port, - struct netif *netif, u8_t have_chksum, - u16_t chksum); -err_t udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, - const ip_addr_t *dst_ip, u16_t dst_port, - u8_t have_chksum, u16_t chksum); -err_t udp_send_chksum(struct udp_pcb *pcb, struct pbuf *p, - u8_t have_chksum, u16_t chksum); -err_t udp_sendto_if_src_chksum(struct udp_pcb *pcb, struct pbuf *p, - const ip_addr_t *dst_ip, u16_t dst_port, struct netif *netif, - u8_t have_chksum, u16_t chksum, const ip_addr_t *src_ip); -#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ - -#define udp_flags(pcb) ((pcb)->flags) -#define udp_setflags(pcb, f) ((pcb)->flags = (f)) - -#define udp_set_flags(pcb, set_flags) do { (pcb)->flags = (u8_t)((pcb)->flags | (set_flags)); } while(0) -#define udp_clear_flags(pcb, clr_flags) do { (pcb)->flags = (u8_t)((pcb)->flags & (u8_t)(~(clr_flags) & 0xff)); } while(0) -#define udp_is_flag_set(pcb, flag) (((pcb)->flags & (flag)) != 0) - -/* The following functions are the lower layer interface to UDP. */ -void udp_input (struct pbuf *p, struct netif *inp); - -void udp_init (void); - -/* for compatibility with older implementation */ -#define udp_new_ip6() udp_new_ip_type(IPADDR_TYPE_V6) - -#if LWIP_MULTICAST_TX_OPTIONS -#if LWIP_IPV4 -#define udp_set_multicast_netif_addr(pcb, ip4addr) ip4_addr_copy((pcb)->mcast_ip4, *(ip4addr)) -#define udp_get_multicast_netif_addr(pcb) (&(pcb)->mcast_ip4) -#endif /* LWIP_IPV4 */ -#define udp_set_multicast_netif_index(pcb, idx) ((pcb)->mcast_ifindex = (idx)) -#define udp_get_multicast_netif_index(pcb) ((pcb)->mcast_ifindex) -#define udp_set_multicast_ttl(pcb, value) ((pcb)->mcast_ttl = (value)) -#define udp_get_multicast_ttl(pcb) ((pcb)->mcast_ttl) -#endif /* LWIP_MULTICAST_TX_OPTIONS */ - -#if UDP_DEBUG -void udp_debug_print(struct udp_hdr *udphdr); -#else -#define udp_debug_print(udphdr) -#endif - -void udp_netif_ip_addr_changed(const ip_addr_t* old_addr, const ip_addr_t* new_addr); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_UDP */ - -#endif /* LWIP_HDR_UDP_H */ diff --git a/third-party/lwip-2.1.2/include/netif/bridgeif.h b/third-party/lwip-2.1.2/include/netif/bridgeif.h deleted file mode 100644 index f4f8cf14..00000000 --- a/third-party/lwip-2.1.2/include/netif/bridgeif.h +++ /dev/null @@ -1,127 +0,0 @@ -/** - * @file - * lwIP netif implementing an IEEE 802.1D MAC Bridge - */ - -/* - * Copyright (c) 2017 Simon Goldschmidt. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Simon Goldschmidt - * - */ -#ifndef LWIP_HDR_NETIF_BRIDGEIF_H -#define LWIP_HDR_NETIF_BRIDGEIF_H - -#include "netif/bridgeif_opts.h" - -#include "lwip/err.h" -#include "lwip/prot/ethernet.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct netif; - -#if (BRIDGEIF_MAX_PORTS < 0) || (BRIDGEIF_MAX_PORTS >= 64) -#error BRIDGEIF_MAX_PORTS must be [1..63] -#elif BRIDGEIF_MAX_PORTS < 8 -typedef u8_t bridgeif_portmask_t; -#elif BRIDGEIF_MAX_PORTS < 16 -typedef u16_t bridgeif_portmask_t; -#elif BRIDGEIF_MAX_PORTS < 32 -typedef u32_t bridgeif_portmask_t; -#elif BRIDGEIF_MAX_PORTS < 64 -typedef u64_t bridgeif_portmask_t; -#endif - -#define BR_FLOOD ((bridgeif_portmask_t)-1) - -/** @ingroup bridgeif - * Initialisation data for @ref bridgeif_init. - * An instance of this type must be passed as parameter 'state' to @ref netif_add - * when the bridge is added. - */ -typedef struct bridgeif_initdata_s { - /** MAC address of the bridge (cannot use the netif's addresses) */ - struct eth_addr ethaddr; - /** Maximum number of ports in the bridge (ports are stored in an array, this - influences memory allocated for netif->state of the bridge netif). */ - u8_t max_ports; - /** Maximum number of dynamic/learning entries in the bridge's forwarding database. - In the default implementation, this controls memory consumption only. */ - u16_t max_fdb_dynamic_entries; - /** Maximum number of static forwarding entries. Influences memory consumption! */ - u16_t max_fdb_static_entries; -} bridgeif_initdata_t; - -/** @ingroup bridgeif - * Use this for constant initialization of a bridgeif_initdat_t - * (ethaddr must be passed as ETH_ADDR()) - */ -#define BRIDGEIF_INITDATA1(max_ports, max_fdb_dynamic_entries, max_fdb_static_entries, ethaddr) {ethaddr, max_ports, max_fdb_dynamic_entries, max_fdb_static_entries} -/** @ingroup bridgeif - * Use this for constant initialization of a bridgeif_initdat_t - * (each byte of ethaddr must be passed) - */ -#define BRIDGEIF_INITDATA2(max_ports, max_fdb_dynamic_entries, max_fdb_static_entries, e0, e1, e2, e3, e4, e5) {{e0, e1, e2, e3, e4, e5}, max_ports, max_fdb_dynamic_entries, max_fdb_static_entries} - -err_t bridgeif_init(struct netif *netif); -err_t bridgeif_add_port(struct netif *bridgeif, struct netif *portif); -err_t bridgeif_fdb_add(struct netif *bridgeif, const struct eth_addr *addr, bridgeif_portmask_t ports); -err_t bridgeif_fdb_remove(struct netif *bridgeif, const struct eth_addr *addr); - -/* FDB interface, can be replaced by own implementation */ -void bridgeif_fdb_update_src(void *fdb_ptr, struct eth_addr *src_addr, u8_t port_idx); -bridgeif_portmask_t bridgeif_fdb_get_dst_ports(void *fdb_ptr, struct eth_addr *dst_addr); -void* bridgeif_fdb_init(u16_t max_fdb_entries); - -#if BRIDGEIF_PORT_NETIFS_OUTPUT_DIRECT -#ifndef BRIDGEIF_DECL_PROTECT -/* define bridgeif protection to sys_arch_protect... */ -#include "lwip/sys.h" -#define BRIDGEIF_DECL_PROTECT(lev) SYS_ARCH_DECL_PROTECT(lev) -#define BRIDGEIF_READ_PROTECT(lev) SYS_ARCH_PROTECT(lev) -#define BRIDGEIF_READ_UNPROTECT(lev) SYS_ARCH_UNPROTECT(lev) -#define BRIDGEIF_WRITE_PROTECT(lev) -#define BRIDGEIF_WRITE_UNPROTECT(lev) -#endif -#else /* BRIDGEIF_PORT_NETIFS_OUTPUT_DIRECT */ -#include "lwip/tcpip.h" -#define BRIDGEIF_DECL_PROTECT(lev) -#define BRIDGEIF_READ_PROTECT(lev) -#define BRIDGEIF_READ_UNPROTECT(lev) -#define BRIDGEIF_WRITE_PROTECT(lev) -#define BRIDGEIF_WRITE_UNPROTECT(lev) -#endif /* BRIDGEIF_PORT_NETIFS_OUTPUT_DIRECT */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_NETIF_BRIDGEIF_H */ diff --git a/third-party/lwip-2.1.2/include/netif/bridgeif_opts.h b/third-party/lwip-2.1.2/include/netif/bridgeif_opts.h deleted file mode 100644 index b85c3017..00000000 --- a/third-party/lwip-2.1.2/include/netif/bridgeif_opts.h +++ /dev/null @@ -1,90 +0,0 @@ -/** - * @file - * lwIP netif implementing an IEEE 802.1D MAC Bridge - */ - -/* - * Copyright (c) 2017 Simon Goldschmidt. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Simon Goldschmidt - * - */ - -#ifndef LWIP_HDR_NETIF_BRIDGEIF_OPTS_H -#define LWIP_HDR_NETIF_BRIDGEIF_OPTS_H - -#include "lwip/opt.h" - -/** - * @defgroup bridgeif_opts Options - * @ingroup bridgeif - * @{ - */ - -/** BRIDGEIF_PORT_NETIFS_OUTPUT_DIRECT==1: set port netif's 'input' function - * to call directly into bridgeif code and on top of that, directly call into - * the selected forwarding port's 'linkoutput' function. - * This means that the bridgeif input/output path is protected from concurrent access - * but as well, *all* bridge port netif's drivers must correctly handle concurrent access! - * == 0: get into tcpip_thread for every input packet (no multithreading) - * ATTENTION: as ==0 relies on tcpip.h, the default depends on NO_SYS setting - */ -#ifndef BRIDGEIF_PORT_NETIFS_OUTPUT_DIRECT -#define BRIDGEIF_PORT_NETIFS_OUTPUT_DIRECT NO_SYS -#endif - -/** BRIDGEIF_MAX_PORTS: this is used to create a typedef used for forwarding - * bit-fields: the number of bits required is this + 1 (for the internal/cpu port) - * (63 is the maximum, resulting in an u64_t for the bit mask) - * ATTENTION: this controls the maximum number of the implementation only! - * The max. number of ports per bridge must still be passed via netif_add parameter! - */ -#ifndef BRIDGEIF_MAX_PORTS -#define BRIDGEIF_MAX_PORTS 7 -#endif - -/** BRIDGEIF_DEBUG: Enable generic debugging in bridgeif.c. */ -#ifndef BRIDGEIF_DEBUG -#define BRIDGEIF_DEBUG LWIP_DBG_OFF -#endif - -/** BRIDGEIF_DEBUG: Enable FDB debugging in bridgeif.c. */ -#ifndef BRIDGEIF_FDB_DEBUG -#define BRIDGEIF_FDB_DEBUG LWIP_DBG_OFF -#endif - -/** BRIDGEIF_DEBUG: Enable forwarding debugging in bridgeif.c. */ -#ifndef BRIDGEIF_FW_DEBUG -#define BRIDGEIF_FW_DEBUG LWIP_DBG_OFF -#endif - -/** - * @} - */ - -#endif /* LWIP_HDR_NETIF_BRIDGEIF_OPTS_H */ diff --git a/third-party/lwip-2.1.2/include/netif/etharp.h b/third-party/lwip-2.1.2/include/netif/etharp.h deleted file mode 100644 index b536fd28..00000000 --- a/third-party/lwip-2.1.2/include/netif/etharp.h +++ /dev/null @@ -1,3 +0,0 @@ -/* ARP has been moved to core/ipv4, provide this #include for compatibility only */ -#include "lwip/etharp.h" -#include "netif/ethernet.h" diff --git a/third-party/lwip-2.1.2/include/netif/ethernet.h b/third-party/lwip-2.1.2/include/netif/ethernet.h deleted file mode 100644 index 49649cbf..00000000 --- a/third-party/lwip-2.1.2/include/netif/ethernet.h +++ /dev/null @@ -1,77 +0,0 @@ -/** - * @file - * Ethernet input function - handles INCOMING ethernet level traffic - * To be used in most low-level netif implementations - */ - -/* - * Copyright (c) 2001-2003 Swedish Institute of Computer Science. - * Copyright (c) 2003-2004 Leon Woestenberg - * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#ifndef LWIP_HDR_NETIF_ETHERNET_H -#define LWIP_HDR_NETIF_ETHERNET_H - -#include "lwip/opt.h" - -#include "lwip/pbuf.h" -#include "lwip/netif.h" -#include "lwip/prot/ethernet.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if LWIP_ARP || LWIP_ETHERNET - -/** Define this to 1 and define LWIP_ARP_FILTER_NETIF_FN(pbuf, netif, type) - * to a filter function that returns the correct netif when using multiple - * netifs on one hardware interface where the netif's low-level receive - * routine cannot decide for the correct netif (e.g. when mapping multiple - * IP addresses to one hardware interface). - */ -#ifndef LWIP_ARP_FILTER_NETIF -#define LWIP_ARP_FILTER_NETIF 0 -#endif - -err_t ethernet_input(struct pbuf *p, struct netif *netif); -err_t ethernet_output(struct netif* netif, struct pbuf* p, const struct eth_addr* src, const struct eth_addr* dst, u16_t eth_type); - -extern const struct eth_addr ethbroadcast, ethzero; - -#endif /* LWIP_ARP || LWIP_ETHERNET */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_NETIF_ETHERNET_H */ diff --git a/third-party/lwip-2.1.2/include/netif/ieee802154.h b/third-party/lwip-2.1.2/include/netif/ieee802154.h deleted file mode 100644 index 54e019fd..00000000 --- a/third-party/lwip-2.1.2/include/netif/ieee802154.h +++ /dev/null @@ -1,112 +0,0 @@ -/** - * @file - * Definitions for IEEE 802.15.4 MAC frames - */ - -/* - * Copyright (c) 2018 Simon Goldschmidt. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Simon Goldschmidt - * - */ -#ifndef LWIP_HDR_NETIF_IEEE802154_H -#define LWIP_HDR_NETIF_IEEE802154_H - -#include "lwip/opt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -/** General MAC frame format - * This shows the full featured header, mainly for documentation. - * Some fields are omitted or shortened to achieve frame compression. - */ -struct ieee_802154_hdr { - /** See IEEE_802154_FC_* defines */ - PACK_STRUCT_FIELD(u16_t frame_control); - /** Sequence number is omitted if IEEE_802154_FC_SEQNO_SUPPR is set in frame_control */ - PACK_STRUCT_FLD_8(u8_t sequence_number); - /** Destination PAN ID is omitted if Destination Addressing Mode is 0 */ - PACK_STRUCT_FIELD(u16_t destination_pan_id); - /** Destination Address is omitted if Destination Addressing Mode is 0 */ - PACK_STRUCT_FLD_8(u8_t destination_address[8]); - /** Source PAN ID is omitted if Source Addressing Mode is 0 - or if IEEE_802154_FC_PANID_COMPR is set in frame control*/ - PACK_STRUCT_FIELD(u16_t source_pan_id); - /** Source Address is omitted if Source Addressing Mode is 0 */ - PACK_STRUCT_FLD_8(u8_t source_address[8]); - /* The rest is variable */ -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/* Addressing modes (2 bits) */ -#define IEEE_802154_ADDR_MODE_NO_ADDR 0x00 /* PAN ID and address fields are not present */ -#define IEEE_802154_ADDR_MODE_RESERVED 0x01 /* Reserved */ -#define IEEE_802154_ADDR_MODE_SHORT 0x02 /* Address field contains a short address (16 bit) */ -#define IEEE_802154_ADDR_MODE_EXT 0x03 /* Address field contains an extended address (64 bit) */ - -/* IEEE 802.15.4 Frame Control definitions (2 bytes; see IEEE 802.15.4-2015 ch. 7.2.1) */ -#define IEEE_802154_FC_FT_MASK 0x0007 /* bits 0..2: Frame Type */ -#define IEEE_802154_FC_FT_BEACON 0x00 -#define IEEE_802154_FC_FT_DATA 0x01 -#define IEEE_802154_FC_FT_ACK 0x02 -#define IEEE_802154_FC_FT_MAC_CMD 0x03 -#define IEEE_802154_FC_FT_RESERVED 0x04 -#define IEEE_802154_FC_FT_MULTIPURPOSE 0x05 -#define IEEE_802154_FC_FT_FRAG 0x06 -#define IEEE_802154_FC_FT_EXT 0x07 -#define IEEE_802154_FC_SEC_EN 0x0008 /* bit 3: Security Enabled */ -#define IEEE_802154_FC_FRAME_PEND 0x0010 /* bit 4: Frame Pending */ -#define IEEE_802154_FC_ACK_REQ 0x0020 /* bit 5: AR (ACK required) */ -#define IEEE_802154_FC_PANID_COMPR 0x0040 /* bit 6: PAN ID Compression (src and dst are equal, src PAN ID omitted) */ -#define IEEE_802154_FC_RESERVED 0x0080 -#define IEEE_802154_FC_SEQNO_SUPPR 0x0100 /* bit 8: Sequence Number Suppression */ -#define IEEE_802154_FC_IE_PRESENT 0x0200 /* bit 9: IE Present */ -#define IEEE_802154_FC_DST_ADDR_MODE_MASK 0x0c00 /* bits 10..11: Destination Addressing Mode */ -#define IEEE_802154_FC_DST_ADDR_MODE_NO_ADDR (IEEE_802154_ADDR_MODE_NO_ADDR << 10) -#define IEEE_802154_FC_DST_ADDR_MODE_SHORT (IEEE_802154_ADDR_MODE_SHORT << 10) -#define IEEE_802154_FC_DST_ADDR_MODE_EXT (IEEE_802154_ADDR_MODE_EXT << 10) -#define IEEE_802154_FC_FRAME_VERSION_MASK 0x3000 /* bits 12..13: Frame Version */ -#define IEEE_802154_FC_FRAME_VERSION_GET(x) (((x) & IEEE_802154_FC_FRAME_VERSION_MASK) >> 12) -#define IEEE_802154_FC_SRC_ADDR_MODE_MASK 0xc000 /* bits 14..15: Source Addressing Mode */ -#define IEEE_802154_FC_SRC_ADDR_MODE_SHORT (IEEE_802154_ADDR_MODE_SHORT << 14) -#define IEEE_802154_FC_SRC_ADDR_MODE_EXT (IEEE_802154_ADDR_MODE_EXT << 14) - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_NETIF_IEEE802154_H */ diff --git a/third-party/lwip-2.1.2/include/netif/lowpan6.h b/third-party/lwip-2.1.2/include/netif/lowpan6.h deleted file mode 100644 index ecff24ba..00000000 --- a/third-party/lwip-2.1.2/include/netif/lowpan6.h +++ /dev/null @@ -1,89 +0,0 @@ -/** - * @file - * - * 6LowPAN output for IPv6. Uses ND tables for link-layer addressing. Fragments packets to 6LowPAN units. - */ - -/* - * Copyright (c) 2015 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -#ifndef LWIP_HDR_LOWPAN6_H -#define LWIP_HDR_LOWPAN6_H - -#include "netif/lowpan6_opts.h" - -#if LWIP_IPV6 - -#include "netif/lowpan6_common.h" -#include "lwip/pbuf.h" -#include "lwip/ip.h" -#include "lwip/ip_addr.h" -#include "lwip/netif.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** 1 second period for reassembly */ -#define LOWPAN6_TMR_INTERVAL 1000 - -void lowpan6_tmr(void); - -err_t lowpan6_set_context(u8_t idx, const ip6_addr_t * context); -err_t lowpan6_set_short_addr(u8_t addr_high, u8_t addr_low); - -#if LWIP_IPV4 -err_t lowpan4_output(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr); -#endif /* LWIP_IPV4 */ -err_t lowpan6_output(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr); -err_t lowpan6_input(struct pbuf * p, struct netif *netif); -err_t lowpan6_if_init(struct netif *netif); - -/* pan_id in network byte order. */ -err_t lowpan6_set_pan_id(u16_t pan_id); - -u16_t lowpan6_calc_crc(const void *buf, u16_t len); - -#if !NO_SYS -err_t tcpip_6lowpan_input(struct pbuf *p, struct netif *inp); -#endif /* !NO_SYS */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV6 */ - -#endif /* LWIP_HDR_LOWPAN6_H */ diff --git a/third-party/lwip-2.1.2/include/netif/lowpan6_ble.h b/third-party/lwip-2.1.2/include/netif/lowpan6_ble.h deleted file mode 100644 index 01896a7f..00000000 --- a/third-party/lwip-2.1.2/include/netif/lowpan6_ble.h +++ /dev/null @@ -1,78 +0,0 @@ -/** - * @file - * 6LowPAN over BLE for IPv6 (RFC7668). - */ - -/* - * Copyright (c) 2017 Benjamin Aigner - * Copyright (c) 2015 Inico Technologies Ltd. , Author: Ivan Delamer - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Benjamin Aigner - * - * Based on the original 6lowpan implementation of lwIP ( @see 6lowpan.c) - */ - -#ifndef LWIP_HDR_LOWPAN6_BLE_H -#define LWIP_HDR_LOWPAN6_BLE_H - -#include "netif/lowpan6_opts.h" - -#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - -#include "netif/lowpan6_common.h" -#include "lwip/pbuf.h" -#include "lwip/ip.h" -#include "lwip/ip_addr.h" -#include "lwip/netif.h" - -#ifdef __cplusplus -extern "C" { -#endif - -err_t rfc7668_output(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr); -err_t rfc7668_input(struct pbuf * p, struct netif *netif); -err_t rfc7668_set_local_addr_eui64(struct netif *netif, const u8_t *local_addr, size_t local_addr_len); -err_t rfc7668_set_local_addr_mac48(struct netif *netif, const u8_t *local_addr, size_t local_addr_len, int is_public_addr); -err_t rfc7668_set_peer_addr_eui64(struct netif *netif, const u8_t *peer_addr, size_t peer_addr_len); -err_t rfc7668_set_peer_addr_mac48(struct netif *netif, const u8_t *peer_addr, size_t peer_addr_len, int is_public_addr); -err_t rfc7668_set_context(u8_t index, const ip6_addr_t * context); -err_t rfc7668_if_init(struct netif *netif); - -#if !NO_SYS -err_t tcpip_rfc7668_input(struct pbuf *p, struct netif *inp); -#endif - -void ble_addr_to_eui64(uint8_t *dst, const uint8_t *src, int public_addr); -void eui64_to_ble_addr(uint8_t *dst, const uint8_t *src); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV6 */ - -#endif /* LWIP_HDR_LOWPAN6_BLE_H */ diff --git a/third-party/lwip-2.1.2/include/netif/lowpan6_common.h b/third-party/lwip-2.1.2/include/netif/lowpan6_common.h deleted file mode 100644 index 0dc13ab5..00000000 --- a/third-party/lwip-2.1.2/include/netif/lowpan6_common.h +++ /dev/null @@ -1,82 +0,0 @@ -/** - * @file - * - * Common 6LowPAN routines for IPv6. Uses ND tables for link-layer addressing. Fragments packets to 6LowPAN units. - */ - -/* - * Copyright (c) 2015 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -#ifndef LWIP_HDR_LOWPAN6_COMMON_H -#define LWIP_HDR_LOWPAN6_COMMON_H - -#include "netif/lowpan6_opts.h" - -#if LWIP_IPV6 /* don't build if IPv6 is disabled in lwipopts.h */ - -#include "lwip/pbuf.h" -#include "lwip/ip.h" -#include "lwip/ip6_addr.h" -#include "lwip/netif.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** Helper define for a link layer address, which can be encoded as 0, 2 or 8 bytes */ -struct lowpan6_link_addr { - /* encoded length of the address */ - u8_t addr_len; - /* address bytes */ - u8_t addr[8]; -}; - -s8_t lowpan6_get_address_mode(const ip6_addr_t *ip6addr, const struct lowpan6_link_addr *mac_addr); - -#if LWIP_6LOWPAN_IPHC -err_t lowpan6_compress_headers(struct netif *netif, u8_t *inbuf, size_t inbuf_size, u8_t *outbuf, size_t outbuf_size, - u8_t *lowpan6_header_len_out, u8_t *hidden_header_len_out, ip6_addr_t *lowpan6_contexts, - const struct lowpan6_link_addr *src, const struct lowpan6_link_addr *dst); -struct pbuf *lowpan6_decompress(struct pbuf *p, u16_t datagram_size, ip6_addr_t *lowpan6_contexts, - struct lowpan6_link_addr *src, struct lowpan6_link_addr *dest); -#endif /* LWIP_6LOWPAN_IPHC */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV6 */ - -#endif /* LWIP_HDR_LOWPAN6_COMMON_H */ diff --git a/third-party/lwip-2.1.2/include/netif/lowpan6_opts.h b/third-party/lwip-2.1.2/include/netif/lowpan6_opts.h deleted file mode 100644 index 17d46cdc..00000000 --- a/third-party/lwip-2.1.2/include/netif/lowpan6_opts.h +++ /dev/null @@ -1,122 +0,0 @@ -/** - * @file - * 6LowPAN options list - */ - -/* - * Copyright (c) 2015 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -#ifndef LWIP_HDR_LOWPAN6_OPTS_H -#define LWIP_HDR_LOWPAN6_OPTS_H - -#include "lwip/opt.h" - -/** LWIP_6LOWPAN_NUM_CONTEXTS: define the number of compression - * contexts per netif type - */ -#ifndef LWIP_6LOWPAN_NUM_CONTEXTS -#define LWIP_6LOWPAN_NUM_CONTEXTS 10 -#endif - -/** LWIP_6LOWPAN_INFER_SHORT_ADDRESS: set this to 0 to disable creating - * short addresses for matching addresses (debug only) - */ -#ifndef LWIP_6LOWPAN_INFER_SHORT_ADDRESS -#define LWIP_6LOWPAN_INFER_SHORT_ADDRESS 1 -#endif - -/** LWIP_6LOWPAN_IPHC: set this to 0 to disable IP header compression as per - * RFC 6282 (which is mandatory for BLE) - */ -#ifndef LWIP_6LOWPAN_IPHC -#define LWIP_6LOWPAN_IPHC 1 -#endif - -/** Set this to 1 if your IEEE 802.15.4 interface can calculate and check the - * CRC in hardware. This means TX packets get 2 zero bytes added on transmission - * which are to be filled with the CRC. - */ -#ifndef LWIP_6LOWPAN_802154_HW_CRC -#define LWIP_6LOWPAN_802154_HW_CRC 0 -#endif - -/** If LWIP_6LOWPAN_802154_HW_CRC==0, this can override the default slow - * implementation of the CRC used for 6LoWPAN over IEEE 802.15.4 (which uses - * a shift register). - */ -#ifndef LWIP_6LOWPAN_CALC_CRC -#define LWIP_6LOWPAN_CALC_CRC(buf, len) lowpan6_calc_crc(buf, len) -#endif - -/** Debug level for 6LoWPAN in general */ -#ifndef LWIP_LOWPAN6_DEBUG -#define LWIP_LOWPAN6_DEBUG LWIP_DBG_OFF -#endif - -/** Debug level for 6LoWPAN over IEEE 802.15.4 */ -#ifndef LWIP_LOWPAN6_802154_DEBUG -#define LWIP_LOWPAN6_802154_DEBUG LWIP_DBG_OFF -#endif - -/** LWIP_LOWPAN6_IP_COMPRESSED_DEBUG: enable compressed IP frame - * output debugging - */ -#ifndef LWIP_LOWPAN6_IP_COMPRESSED_DEBUG -#define LWIP_LOWPAN6_IP_COMPRESSED_DEBUG LWIP_DBG_OFF -#endif - -/** LWIP_LOWPAN6_DECOMPRESSION_DEBUG: enable decompression debug output - */ -#ifndef LWIP_LOWPAN6_DECOMPRESSION_DEBUG -#define LWIP_LOWPAN6_DECOMPRESSION_DEBUG LWIP_DBG_OFF -#endif - -/** LWIP_RFC7668_IP_UNCOMPRESSED_DEBUG: enable decompressed IP frame - * output debugging */ -#ifndef LWIP_RFC7668_IP_UNCOMPRESSED_DEBUG -#define LWIP_RFC7668_IP_UNCOMPRESSED_DEBUG LWIP_DBG_OFF -#endif - -/** LWIP_RFC7668_LINUX_WORKAROUND_PUBLIC_ADDRESS: - * Currently, the linux kernel driver for 6lowpan sets/clears a bit in - * the address, depending on the BD address (either public or not). - * Might not be RFC7668 conform, so you may select to do that (=1) or - * not (=0) */ -#ifndef LWIP_RFC7668_LINUX_WORKAROUND_PUBLIC_ADDRESS -#define LWIP_RFC7668_LINUX_WORKAROUND_PUBLIC_ADDRESS 1 -#endif - - -#endif /* LWIP_HDR_LOWPAN6_OPTS_H */ diff --git a/third-party/lwip-2.1.2/include/netif/ppp/ccp.h b/third-party/lwip-2.1.2/include/netif/ppp/ccp.h deleted file mode 100644 index b2285228..00000000 --- a/third-party/lwip-2.1.2/include/netif/ppp/ccp.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - * ccp.h - Definitions for PPP Compression Control Protocol. - * - * Copyright (c) 1994-2002 Paul Mackerras. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 3. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * $Id: ccp.h,v 1.12 2004/11/04 10:02:26 paulus Exp $ - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && CCP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef CCP_H -#define CCP_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * CCP codes. - */ - -#define CCP_CONFREQ 1 -#define CCP_CONFACK 2 -#define CCP_TERMREQ 5 -#define CCP_TERMACK 6 -#define CCP_RESETREQ 14 -#define CCP_RESETACK 15 - -/* - * Max # bytes for a CCP option - */ - -#define CCP_MAX_OPTION_LENGTH 32 - -/* - * Parts of a CCP packet. - */ - -#define CCP_CODE(dp) ((dp)[0]) -#define CCP_ID(dp) ((dp)[1]) -#define CCP_LENGTH(dp) (((dp)[2] << 8) + (dp)[3]) -#define CCP_HDRLEN 4 - -#define CCP_OPT_CODE(dp) ((dp)[0]) -#define CCP_OPT_LENGTH(dp) ((dp)[1]) -#define CCP_OPT_MINLEN 2 - -#if BSDCOMPRESS_SUPPORT -/* - * Definitions for BSD-Compress. - */ - -#define CI_BSD_COMPRESS 21 /* config. option for BSD-Compress */ -#define CILEN_BSD_COMPRESS 3 /* length of config. option */ - -/* Macros for handling the 3rd byte of the BSD-Compress config option. */ -#define BSD_NBITS(x) ((x) & 0x1F) /* number of bits requested */ -#define BSD_VERSION(x) ((x) >> 5) /* version of option format */ -#define BSD_CURRENT_VERSION 1 /* current version number */ -#define BSD_MAKE_OPT(v, n) (((v) << 5) | (n)) - -#define BSD_MIN_BITS 9 /* smallest code size supported */ -#define BSD_MAX_BITS 15 /* largest code size supported */ -#endif /* BSDCOMPRESS_SUPPORT */ - -#if DEFLATE_SUPPORT -/* - * Definitions for Deflate. - */ - -#define CI_DEFLATE 26 /* config option for Deflate */ -#define CI_DEFLATE_DRAFT 24 /* value used in original draft RFC */ -#define CILEN_DEFLATE 4 /* length of its config option */ - -#define DEFLATE_MIN_SIZE 9 -#define DEFLATE_MAX_SIZE 15 -#define DEFLATE_METHOD_VAL 8 -#define DEFLATE_SIZE(x) (((x) >> 4) + 8) -#define DEFLATE_METHOD(x) ((x) & 0x0F) -#define DEFLATE_MAKE_OPT(w) ((((w) - 8) << 4) + DEFLATE_METHOD_VAL) -#define DEFLATE_CHK_SEQUENCE 0 -#endif /* DEFLATE_SUPPORT */ - -#if MPPE_SUPPORT -/* - * Definitions for MPPE. - */ - -#define CI_MPPE 18 /* config option for MPPE */ -#define CILEN_MPPE 6 /* length of config option */ -#endif /* MPPE_SUPPORT */ - -#if PREDICTOR_SUPPORT -/* - * Definitions for other, as yet unsupported, compression methods. - */ - -#define CI_PREDICTOR_1 1 /* config option for Predictor-1 */ -#define CILEN_PREDICTOR_1 2 /* length of its config option */ -#define CI_PREDICTOR_2 2 /* config option for Predictor-2 */ -#define CILEN_PREDICTOR_2 2 /* length of its config option */ -#endif /* PREDICTOR_SUPPORT */ - -typedef struct ccp_options { -#if DEFLATE_SUPPORT - unsigned int deflate :1; /* do Deflate? */ - unsigned int deflate_correct :1; /* use correct code for deflate? */ - unsigned int deflate_draft :1; /* use draft RFC code for deflate? */ -#endif /* DEFLATE_SUPPORT */ -#if BSDCOMPRESS_SUPPORT - unsigned int bsd_compress :1; /* do BSD Compress? */ -#endif /* BSDCOMPRESS_SUPPORT */ -#if PREDICTOR_SUPPORT - unsigned int predictor_1 :1; /* do Predictor-1? */ - unsigned int predictor_2 :1; /* do Predictor-2? */ -#endif /* PREDICTOR_SUPPORT */ - -#if MPPE_SUPPORT - u8_t mppe; /* MPPE bitfield */ -#endif /* MPPE_SUPPORT */ -#if BSDCOMPRESS_SUPPORT - u_short bsd_bits; /* # bits/code for BSD Compress */ -#endif /* BSDCOMPRESS_SUPPORT */ -#if DEFLATE_SUPPORT - u_short deflate_size; /* lg(window size) for Deflate */ -#endif /* DEFLATE_SUPPORT */ - u8_t method; /* code for chosen compression method */ -} ccp_options; - -extern const struct protent ccp_protent; - -void ccp_resetrequest(ppp_pcb *pcb); /* Issue a reset-request. */ - -#ifdef __cplusplus -} -#endif - -#endif /* CCP_H */ -#endif /* PPP_SUPPORT && CCP_SUPPORT */ diff --git a/third-party/lwip-2.1.2/include/netif/ppp/chap-md5.h b/third-party/lwip-2.1.2/include/netif/ppp/chap-md5.h deleted file mode 100644 index eb0269fe..00000000 --- a/third-party/lwip-2.1.2/include/netif/ppp/chap-md5.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * chap-md5.h - New CHAP/MD5 implementation. - * - * Copyright (c) 2003 Paul Mackerras. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 3. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && CHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -extern const struct chap_digest_type md5_digest; - -#endif /* PPP_SUPPORT && CHAP_SUPPORT */ diff --git a/third-party/lwip-2.1.2/include/netif/ppp/chap-new.h b/third-party/lwip-2.1.2/include/netif/ppp/chap-new.h deleted file mode 100644 index 2d8cd9ca..00000000 --- a/third-party/lwip-2.1.2/include/netif/ppp/chap-new.h +++ /dev/null @@ -1,200 +0,0 @@ -/* - * chap-new.c - New CHAP implementation. - * - * Copyright (c) 2003 Paul Mackerras. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 3. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && CHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef CHAP_H -#define CHAP_H - -#include "ppp.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * CHAP packets begin with a standard header with code, id, len (2 bytes). - */ -#define CHAP_HDRLEN 4 - -/* - * Values for the code field. - */ -#define CHAP_CHALLENGE 1 -#define CHAP_RESPONSE 2 -#define CHAP_SUCCESS 3 -#define CHAP_FAILURE 4 - -/* - * CHAP digest codes. - */ -#define CHAP_MD5 5 -#if MSCHAP_SUPPORT -#define CHAP_MICROSOFT 0x80 -#define CHAP_MICROSOFT_V2 0x81 -#endif /* MSCHAP_SUPPORT */ - -/* - * Semi-arbitrary limits on challenge and response fields. - */ -#define MAX_CHALLENGE_LEN 64 -#define MAX_RESPONSE_LEN 64 - -/* - * These limits apply to challenge and response packets we send. - * The +4 is the +1 that we actually need rounded up. - */ -#define CHAL_MAX_PKTLEN (PPP_HDRLEN + CHAP_HDRLEN + 4 + MAX_CHALLENGE_LEN + MAXNAMELEN) -#define RESP_MAX_PKTLEN (PPP_HDRLEN + CHAP_HDRLEN + 4 + MAX_RESPONSE_LEN + MAXNAMELEN) - -/* bitmask of supported algorithms */ -#if MSCHAP_SUPPORT -#define MDTYPE_MICROSOFT_V2 0x1 -#define MDTYPE_MICROSOFT 0x2 -#endif /* MSCHAP_SUPPORT */ -#define MDTYPE_MD5 0x4 -#define MDTYPE_NONE 0 - -#if MSCHAP_SUPPORT -/* Return the digest alg. ID for the most preferred digest type. */ -#define CHAP_DIGEST(mdtype) \ - ((mdtype) & MDTYPE_MD5)? CHAP_MD5: \ - ((mdtype) & MDTYPE_MICROSOFT_V2)? CHAP_MICROSOFT_V2: \ - ((mdtype) & MDTYPE_MICROSOFT)? CHAP_MICROSOFT: \ - 0 -#else /* !MSCHAP_SUPPORT */ -#define CHAP_DIGEST(mdtype) \ - ((mdtype) & MDTYPE_MD5)? CHAP_MD5: \ - 0 -#endif /* MSCHAP_SUPPORT */ - -/* Return the bit flag (lsb set) for our most preferred digest type. */ -#define CHAP_MDTYPE(mdtype) ((mdtype) ^ ((mdtype) - 1)) & (mdtype) - -/* Return the bit flag for a given digest algorithm ID. */ -#if MSCHAP_SUPPORT -#define CHAP_MDTYPE_D(digest) \ - ((digest) == CHAP_MICROSOFT_V2)? MDTYPE_MICROSOFT_V2: \ - ((digest) == CHAP_MICROSOFT)? MDTYPE_MICROSOFT: \ - ((digest) == CHAP_MD5)? MDTYPE_MD5: \ - 0 -#else /* !MSCHAP_SUPPORT */ -#define CHAP_MDTYPE_D(digest) \ - ((digest) == CHAP_MD5)? MDTYPE_MD5: \ - 0 -#endif /* MSCHAP_SUPPORT */ - -/* Can we do the requested digest? */ -#if MSCHAP_SUPPORT -#define CHAP_CANDIGEST(mdtype, digest) \ - ((digest) == CHAP_MICROSOFT_V2)? (mdtype) & MDTYPE_MICROSOFT_V2: \ - ((digest) == CHAP_MICROSOFT)? (mdtype) & MDTYPE_MICROSOFT: \ - ((digest) == CHAP_MD5)? (mdtype) & MDTYPE_MD5: \ - 0 -#else /* !MSCHAP_SUPPORT */ -#define CHAP_CANDIGEST(mdtype, digest) \ - ((digest) == CHAP_MD5)? (mdtype) & MDTYPE_MD5: \ - 0 -#endif /* MSCHAP_SUPPORT */ - -/* - * The code for each digest type has to supply one of these. - */ -struct chap_digest_type { - int code; - -#if PPP_SERVER - /* - * Note: challenge and response arguments below are formatted as - * a length byte followed by the actual challenge/response data. - */ - void (*generate_challenge)(ppp_pcb *pcb, unsigned char *challenge); - int (*verify_response)(ppp_pcb *pcb, int id, const char *name, - const unsigned char *secret, int secret_len, - const unsigned char *challenge, const unsigned char *response, - char *message, int message_space); -#endif /* PPP_SERVER */ - void (*make_response)(ppp_pcb *pcb, unsigned char *response, int id, const char *our_name, - const unsigned char *challenge, const char *secret, int secret_len, - unsigned char *priv); - int (*check_success)(ppp_pcb *pcb, unsigned char *pkt, int len, unsigned char *priv); - void (*handle_failure)(ppp_pcb *pcb, unsigned char *pkt, int len); -}; - -/* - * Each interface is described by chap structure. - */ -#if CHAP_SUPPORT -typedef struct chap_client_state { - u8_t flags; - const char *name; - const struct chap_digest_type *digest; - unsigned char priv[64]; /* private area for digest's use */ -} chap_client_state; - -#if PPP_SERVER -typedef struct chap_server_state { - u8_t flags; - u8_t id; - const char *name; - const struct chap_digest_type *digest; - int challenge_xmits; - int challenge_pktlen; - unsigned char challenge[CHAL_MAX_PKTLEN]; -} chap_server_state; -#endif /* PPP_SERVER */ -#endif /* CHAP_SUPPORT */ - -#if 0 /* UNUSED */ -/* Hook for a plugin to validate CHAP challenge */ -extern int (*chap_verify_hook)(char *name, char *ourname, int id, - const struct chap_digest_type *digest, - unsigned char *challenge, unsigned char *response, - char *message, int message_space); -#endif /* UNUSED */ - -#if PPP_SERVER -/* Called by authentication code to start authenticating the peer. */ -extern void chap_auth_peer(ppp_pcb *pcb, const char *our_name, int digest_code); -#endif /* PPP_SERVER */ - -/* Called by auth. code to start authenticating us to the peer. */ -extern void chap_auth_with_peer(ppp_pcb *pcb, const char *our_name, int digest_code); - -/* Represents the CHAP protocol to the main pppd code */ -extern const struct protent chap_protent; - -#ifdef __cplusplus -} -#endif - -#endif /* CHAP_H */ -#endif /* PPP_SUPPORT && CHAP_SUPPORT */ diff --git a/third-party/lwip-2.1.2/include/netif/ppp/chap_ms.h b/third-party/lwip-2.1.2/include/netif/ppp/chap_ms.h deleted file mode 100644 index 07952911..00000000 --- a/third-party/lwip-2.1.2/include/netif/ppp/chap_ms.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * chap_ms.h - Challenge Handshake Authentication Protocol definitions. - * - * Copyright (c) 1995 Eric Rosenquist. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * $Id: chap_ms.h,v 1.13 2004/11/15 22:13:26 paulus Exp $ - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && MSCHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef CHAPMS_INCLUDE -#define CHAPMS_INCLUDE - -extern const struct chap_digest_type chapms_digest; -extern const struct chap_digest_type chapms2_digest; - -#endif /* CHAPMS_INCLUDE */ - -#endif /* PPP_SUPPORT && MSCHAP_SUPPORT */ diff --git a/third-party/lwip-2.1.2/include/netif/ppp/eap.h b/third-party/lwip-2.1.2/include/netif/ppp/eap.h deleted file mode 100644 index 3ee9aaf8..00000000 --- a/third-party/lwip-2.1.2/include/netif/ppp/eap.h +++ /dev/null @@ -1,169 +0,0 @@ -/* - * eap.h - Extensible Authentication Protocol for PPP (RFC 2284) - * - * Copyright (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - * - * Non-exclusive rights to redistribute, modify, translate, and use - * this software in source and binary forms, in whole or in part, is - * hereby granted, provided that the above copyright notice is - * duplicated in any source form, and that neither the name of the - * copyright holder nor the author is used to endorse or promote - * products derived from this software. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Original version by James Carlson - * - * $Id: eap.h,v 1.2 2003/06/11 23:56:26 paulus Exp $ - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && EAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef PPP_EAP_H -#define PPP_EAP_H - -#include "ppp.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Packet header = Code, id, length. - */ -#define EAP_HEADERLEN 4 - - -/* EAP message codes. */ -#define EAP_REQUEST 1 -#define EAP_RESPONSE 2 -#define EAP_SUCCESS 3 -#define EAP_FAILURE 4 - -/* EAP types */ -#define EAPT_IDENTITY 1 -#define EAPT_NOTIFICATION 2 -#define EAPT_NAK 3 /* (response only) */ -#define EAPT_MD5CHAP 4 -#define EAPT_OTP 5 /* One-Time Password; RFC 1938 */ -#define EAPT_TOKEN 6 /* Generic Token Card */ -/* 7 and 8 are unassigned. */ -#define EAPT_RSA 9 /* RSA Public Key Authentication */ -#define EAPT_DSS 10 /* DSS Unilateral */ -#define EAPT_KEA 11 /* KEA */ -#define EAPT_KEA_VALIDATE 12 /* KEA-VALIDATE */ -#define EAPT_TLS 13 /* EAP-TLS */ -#define EAPT_DEFENDER 14 /* Defender Token (AXENT) */ -#define EAPT_W2K 15 /* Windows 2000 EAP */ -#define EAPT_ARCOT 16 /* Arcot Systems */ -#define EAPT_CISCOWIRELESS 17 /* Cisco Wireless */ -#define EAPT_NOKIACARD 18 /* Nokia IP smart card */ -#define EAPT_SRP 19 /* Secure Remote Password */ -/* 20 is deprecated */ - -/* EAP SRP-SHA1 Subtypes */ -#define EAPSRP_CHALLENGE 1 /* Request 1 - Challenge */ -#define EAPSRP_CKEY 1 /* Response 1 - Client Key */ -#define EAPSRP_SKEY 2 /* Request 2 - Server Key */ -#define EAPSRP_CVALIDATOR 2 /* Response 2 - Client Validator */ -#define EAPSRP_SVALIDATOR 3 /* Request 3 - Server Validator */ -#define EAPSRP_ACK 3 /* Response 3 - final ack */ -#define EAPSRP_LWRECHALLENGE 4 /* Req/resp 4 - Lightweight rechal */ - -#define SRPVAL_EBIT 0x00000001 /* Use shared key for ECP */ - -#define SRP_PSEUDO_ID "pseudo_" -#define SRP_PSEUDO_LEN 7 - -#define MD5_SIGNATURE_SIZE 16 -#define EAP_MIN_CHALLENGE_LENGTH 17 -#define EAP_MAX_CHALLENGE_LENGTH 24 -#define EAP_MIN_MAX_POWER_OF_TWO_CHALLENGE_LENGTH 3 /* 2^3-1 = 7, 17+7 = 24 */ - -#define EAP_STATES \ - "Initial", "Pending", "Closed", "Listen", "Identify", \ - "SRP1", "SRP2", "SRP3", "MD5Chall", "Open", "SRP4", "BadAuth" - -#define eap_client_active(pcb) ((pcb)->eap.es_client.ea_state == eapListen) -#if PPP_SERVER -#define eap_server_active(pcb) \ - ((pcb)->eap.es_server.ea_state >= eapIdentify && \ - (pcb)->eap.es_server.ea_state <= eapMD5Chall) -#endif /* PPP_SERVER */ - -/* - * Complete EAP state for one PPP session. - */ -enum eap_state_code { - eapInitial = 0, /* No EAP authentication yet requested */ - eapPending, /* Waiting for LCP (no timer) */ - eapClosed, /* Authentication not in use */ - eapListen, /* Client ready (and timer running) */ - eapIdentify, /* EAP Identify sent */ - eapSRP1, /* Sent EAP SRP-SHA1 Subtype 1 */ - eapSRP2, /* Sent EAP SRP-SHA1 Subtype 2 */ - eapSRP3, /* Sent EAP SRP-SHA1 Subtype 3 */ - eapMD5Chall, /* Sent MD5-Challenge */ - eapOpen, /* Completed authentication */ - eapSRP4, /* Sent EAP SRP-SHA1 Subtype 4 */ - eapBadAuth /* Failed authentication */ -}; - -struct eap_auth { - const char *ea_name; /* Our name */ - char ea_peer[MAXNAMELEN +1]; /* Peer's name */ - void *ea_session; /* Authentication library linkage */ - u_char *ea_skey; /* Shared encryption key */ - u_short ea_namelen; /* Length of our name */ - u_short ea_peerlen; /* Length of peer's name */ - enum eap_state_code ea_state; - u_char ea_id; /* Current id */ - u_char ea_requests; /* Number of Requests sent/received */ - u_char ea_responses; /* Number of Responses */ - u_char ea_type; /* One of EAPT_* */ - u32_t ea_keyflags; /* SRP shared key usage flags */ -}; - -#ifndef EAP_MAX_CHALLENGE_LENGTH -#define EAP_MAX_CHALLENGE_LENGTH 24 -#endif -typedef struct eap_state { - struct eap_auth es_client; /* Client (authenticatee) data */ -#if PPP_SERVER - struct eap_auth es_server; /* Server (authenticator) data */ -#endif /* PPP_SERVER */ - int es_savedtime; /* Saved timeout */ - int es_rechallenge; /* EAP rechallenge interval */ - int es_lwrechallenge; /* SRP lightweight rechallenge inter */ - u8_t es_usepseudo; /* Use SRP Pseudonym if offered one */ - int es_usedpseudo; /* Set if we already sent PN */ - int es_challen; /* Length of challenge string */ - u_char es_challenge[EAP_MAX_CHALLENGE_LENGTH]; -} eap_state; - -/* - * Timeouts. - */ -#if 0 /* moved to ppp_opts.h */ -#define EAP_DEFTIMEOUT 3 /* Timeout (seconds) for rexmit */ -#define EAP_DEFTRANSMITS 10 /* max # times to transmit */ -#define EAP_DEFREQTIME 20 /* Time to wait for peer request */ -#define EAP_DEFALLOWREQ 20 /* max # times to accept requests */ -#endif /* moved to ppp_opts.h */ - -void eap_authwithpeer(ppp_pcb *pcb, const char *localname); -void eap_authpeer(ppp_pcb *pcb, const char *localname); - -extern const struct protent eap_protent; - -#ifdef __cplusplus -} -#endif - -#endif /* PPP_EAP_H */ - -#endif /* PPP_SUPPORT && EAP_SUPPORT */ diff --git a/third-party/lwip-2.1.2/include/netif/ppp/ecp.h b/third-party/lwip-2.1.2/include/netif/ppp/ecp.h deleted file mode 100644 index d8808c3a..00000000 --- a/third-party/lwip-2.1.2/include/netif/ppp/ecp.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * ecp.h - Definitions for PPP Encryption Control Protocol. - * - * Copyright (c) 2002 Google, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * $Id: ecp.h,v 1.2 2003/01/10 07:12:36 fcusack Exp $ - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && ECP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef ECP_H -#define ECP_H - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct ecp_options { - bool required; /* Is ECP required? */ - unsigned enctype; /* Encryption type */ -} ecp_options; - -extern fsm ecp_fsm[]; -extern ecp_options ecp_wantoptions[]; -extern ecp_options ecp_gotoptions[]; -extern ecp_options ecp_allowoptions[]; -extern ecp_options ecp_hisoptions[]; - -extern const struct protent ecp_protent; - -#ifdef __cplusplus -} -#endif - -#endif /* ECP_H */ -#endif /* PPP_SUPPORT && ECP_SUPPORT */ diff --git a/third-party/lwip-2.1.2/include/netif/ppp/eui64.h b/third-party/lwip-2.1.2/include/netif/ppp/eui64.h deleted file mode 100644 index 5adeb482..00000000 --- a/third-party/lwip-2.1.2/include/netif/ppp/eui64.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * eui64.h - EUI64 routines for IPv6CP. - * - * Copyright (c) 1999 Tommi Komulainen. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Tommi Komulainen - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * $Id: eui64.h,v 1.6 2002/12/04 23:03:32 paulus Exp $ -*/ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && PPP_IPV6_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef EUI64_H -#define EUI64_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * @todo: - * - * Maybe this should be done by processing struct in6_addr directly... - */ -typedef union -{ - u8_t e8[8]; - u16_t e16[4]; - u32_t e32[2]; -} eui64_t; - -#define eui64_iszero(e) (((e).e32[0] | (e).e32[1]) == 0) -#define eui64_equals(e, o) (((e).e32[0] == (o).e32[0]) && \ - ((e).e32[1] == (o).e32[1])) -#define eui64_zero(e) (e).e32[0] = (e).e32[1] = 0; - -#define eui64_copy(s, d) memcpy(&(d), &(s), sizeof(eui64_t)) - -#define eui64_magic(e) do { \ - (e).e32[0] = magic(); \ - (e).e32[1] = magic(); \ - (e).e8[0] &= ~2; \ - } while (0) -#define eui64_magic_nz(x) do { \ - eui64_magic(x); \ - } while (eui64_iszero(x)) -#define eui64_magic_ne(x, y) do { \ - eui64_magic(x); \ - } while (eui64_equals(x, y)) - -#define eui64_get(ll, cp) do { \ - eui64_copy((*cp), (ll)); \ - (cp) += sizeof(eui64_t); \ - } while (0) - -#define eui64_put(ll, cp) do { \ - eui64_copy((ll), (*cp)); \ - (cp) += sizeof(eui64_t); \ - } while (0) - -#define eui64_set32(e, l) do { \ - (e).e32[0] = 0; \ - (e).e32[1] = lwip_htonl(l); \ - } while (0) -#define eui64_setlo32(e, l) eui64_set32(e, l) - -char *eui64_ntoa(eui64_t); /* Returns ascii representation of id */ - -#ifdef __cplusplus -} -#endif - -#endif /* EUI64_H */ -#endif /* PPP_SUPPORT && PPP_IPV6_SUPPORT */ diff --git a/third-party/lwip-2.1.2/include/netif/ppp/fsm.h b/third-party/lwip-2.1.2/include/netif/ppp/fsm.h deleted file mode 100644 index 8dec700e..00000000 --- a/third-party/lwip-2.1.2/include/netif/ppp/fsm.h +++ /dev/null @@ -1,182 +0,0 @@ -/* - * fsm.h - {Link, IP} Control Protocol Finite State Machine definitions. - * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * $Id: fsm.h,v 1.10 2004/11/13 02:28:15 paulus Exp $ - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef FSM_H -#define FSM_H - -#include "ppp.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Packet header = Code, id, length. - */ -#define HEADERLEN 4 - - -/* - * CP (LCP, IPCP, etc.) codes. - */ -#define CONFREQ 1 /* Configuration Request */ -#define CONFACK 2 /* Configuration Ack */ -#define CONFNAK 3 /* Configuration Nak */ -#define CONFREJ 4 /* Configuration Reject */ -#define TERMREQ 5 /* Termination Request */ -#define TERMACK 6 /* Termination Ack */ -#define CODEREJ 7 /* Code Reject */ - - -/* - * Each FSM is described by an fsm structure and fsm callbacks. - */ -typedef struct fsm { - ppp_pcb *pcb; /* PPP Interface */ - const struct fsm_callbacks *callbacks; /* Callback routines */ - const char *term_reason; /* Reason for closing protocol */ - u8_t seen_ack; /* Have received valid Ack/Nak/Rej to Req */ - /* -- This is our only flag, we might use u_int :1 if we have more flags */ - u16_t protocol; /* Data Link Layer Protocol field value */ - u8_t state; /* State */ - u8_t flags; /* Contains option bits */ - u8_t id; /* Current id */ - u8_t reqid; /* Current request id */ - u8_t retransmits; /* Number of retransmissions left */ - u8_t nakloops; /* Number of nak loops since last ack */ - u8_t rnakloops; /* Number of naks received */ - u8_t maxnakloops; /* Maximum number of nak loops tolerated - (necessary because IPCP require a custom large max nak loops value) */ - u8_t term_reason_len; /* Length of term_reason */ -} fsm; - - -typedef struct fsm_callbacks { - void (*resetci) /* Reset our Configuration Information */ - (fsm *); - int (*cilen) /* Length of our Configuration Information */ - (fsm *); - void (*addci) /* Add our Configuration Information */ - (fsm *, u_char *, int *); - int (*ackci) /* ACK our Configuration Information */ - (fsm *, u_char *, int); - int (*nakci) /* NAK our Configuration Information */ - (fsm *, u_char *, int, int); - int (*rejci) /* Reject our Configuration Information */ - (fsm *, u_char *, int); - int (*reqci) /* Request peer's Configuration Information */ - (fsm *, u_char *, int *, int); - void (*up) /* Called when fsm reaches PPP_FSM_OPENED state */ - (fsm *); - void (*down) /* Called when fsm leaves PPP_FSM_OPENED state */ - (fsm *); - void (*starting) /* Called when we want the lower layer */ - (fsm *); - void (*finished) /* Called when we don't want the lower layer */ - (fsm *); - void (*protreject) /* Called when Protocol-Reject received */ - (int); - void (*retransmit) /* Retransmission is necessary */ - (fsm *); - int (*extcode) /* Called when unknown code received */ - (fsm *, int, int, u_char *, int); - const char *proto_name; /* String name for protocol (for messages) */ -} fsm_callbacks; - - -/* - * Link states. - */ -#define PPP_FSM_INITIAL 0 /* Down, hasn't been opened */ -#define PPP_FSM_STARTING 1 /* Down, been opened */ -#define PPP_FSM_CLOSED 2 /* Up, hasn't been opened */ -#define PPP_FSM_STOPPED 3 /* Open, waiting for down event */ -#define PPP_FSM_CLOSING 4 /* Terminating the connection, not open */ -#define PPP_FSM_STOPPING 5 /* Terminating, but open */ -#define PPP_FSM_REQSENT 6 /* We've sent a Config Request */ -#define PPP_FSM_ACKRCVD 7 /* We've received a Config Ack */ -#define PPP_FSM_ACKSENT 8 /* We've sent a Config Ack */ -#define PPP_FSM_OPENED 9 /* Connection available */ - - -/* - * Flags - indicate options controlling FSM operation - */ -#define OPT_PASSIVE 1 /* Don't die if we don't get a response */ -#define OPT_RESTART 2 /* Treat 2nd OPEN as DOWN, UP */ -#define OPT_SILENT 4 /* Wait for peer to speak first */ - - -/* - * Timeouts. - */ -#if 0 /* moved to ppp_opts.h */ -#define DEFTIMEOUT 3 /* Timeout time in seconds */ -#define DEFMAXTERMREQS 2 /* Maximum Terminate-Request transmissions */ -#define DEFMAXCONFREQS 10 /* Maximum Configure-Request transmissions */ -#define DEFMAXNAKLOOPS 5 /* Maximum number of nak loops */ -#endif /* moved to ppp_opts.h */ - - -/* - * Prototypes - */ -void fsm_init(fsm *f); -void fsm_lowerup(fsm *f); -void fsm_lowerdown(fsm *f); -void fsm_open(fsm *f); -void fsm_close(fsm *f, const char *reason); -void fsm_input(fsm *f, u_char *inpacket, int l); -void fsm_protreject(fsm *f); -void fsm_sdata(fsm *f, u_char code, u_char id, const u_char *data, int datalen); - -#ifdef __cplusplus -} -#endif - -#endif /* FSM_H */ -#endif /* PPP_SUPPORT */ diff --git a/third-party/lwip-2.1.2/include/netif/ppp/ipcp.h b/third-party/lwip-2.1.2/include/netif/ppp/ipcp.h deleted file mode 100644 index 32fdd1c6..00000000 --- a/third-party/lwip-2.1.2/include/netif/ppp/ipcp.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * ipcp.h - IP Control Protocol definitions. - * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * $Id: ipcp.h,v 1.14 2002/12/04 23:03:32 paulus Exp $ - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && PPP_IPV4_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef IPCP_H -#define IPCP_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Options. - */ -#define CI_ADDRS 1 /* IP Addresses */ -#if VJ_SUPPORT -#define CI_COMPRESSTYPE 2 /* Compression Type */ -#endif /* VJ_SUPPORT */ -#define CI_ADDR 3 - -#if LWIP_DNS -#define CI_MS_DNS1 129 /* Primary DNS value */ -#define CI_MS_DNS2 131 /* Secondary DNS value */ -#endif /* LWIP_DNS */ -#if 0 /* UNUSED - WINS */ -#define CI_MS_WINS1 130 /* Primary WINS value */ -#define CI_MS_WINS2 132 /* Secondary WINS value */ -#endif /* UNUSED - WINS */ - -#if VJ_SUPPORT -#define MAX_STATES 16 /* from slcompress.h */ - -#define IPCP_VJMODE_OLD 1 /* "old" mode (option # = 0x0037) */ -#define IPCP_VJMODE_RFC1172 2 /* "old-rfc"mode (option # = 0x002d) */ -#define IPCP_VJMODE_RFC1332 3 /* "new-rfc"mode (option # = 0x002d, */ - /* maxslot and slot number compression) */ - -#define IPCP_VJ_COMP 0x002d /* current value for VJ compression option*/ -#define IPCP_VJ_COMP_OLD 0x0037 /* "old" (i.e, broken) value for VJ */ - /* compression option*/ -#endif /* VJ_SUPPORT */ - -typedef struct ipcp_options { - unsigned int neg_addr :1; /* Negotiate IP Address? */ - unsigned int old_addrs :1; /* Use old (IP-Addresses) option? */ - unsigned int req_addr :1; /* Ask peer to send IP address? */ -#if 0 /* UNUSED */ - unsigned int default_route :1; /* Assign default route through interface? */ - unsigned int replace_default_route :1; /* Replace default route through interface? */ -#endif /* UNUSED */ -#if 0 /* UNUSED - PROXY ARP */ - unsigned int proxy_arp :1; /* Make proxy ARP entry for peer? */ -#endif /* UNUSED - PROXY ARP */ -#if VJ_SUPPORT - unsigned int neg_vj :1; /* Van Jacobson Compression? */ - unsigned int old_vj :1; /* use old (short) form of VJ option? */ - unsigned int cflag :1; -#endif /* VJ_SUPPORT */ - unsigned int accept_local :1; /* accept peer's value for ouraddr */ - unsigned int accept_remote :1; /* accept peer's value for hisaddr */ -#if LWIP_DNS - unsigned int req_dns1 :1; /* Ask peer to send primary DNS address? */ - unsigned int req_dns2 :1; /* Ask peer to send secondary DNS address? */ -#endif /* LWIP_DNS */ - - u32_t ouraddr, hisaddr; /* Addresses in NETWORK BYTE ORDER */ -#if LWIP_DNS - u32_t dnsaddr[2]; /* Primary and secondary MS DNS entries */ -#endif /* LWIP_DNS */ -#if 0 /* UNUSED - WINS */ - u32_t winsaddr[2]; /* Primary and secondary MS WINS entries */ -#endif /* UNUSED - WINS */ - -#if VJ_SUPPORT - u16_t vj_protocol; /* protocol value to use in VJ option */ - u8_t maxslotindex; /* values for RFC1332 VJ compression neg. */ -#endif /* VJ_SUPPORT */ -} ipcp_options; - -#if 0 /* UNUSED, already defined by lwIP */ -char *ip_ntoa (u32_t); -#endif /* UNUSED, already defined by lwIP */ - -extern const struct protent ipcp_protent; - -#ifdef __cplusplus -} -#endif - -#endif /* IPCP_H */ -#endif /* PPP_SUPPORT && PPP_IPV4_SUPPORT */ diff --git a/third-party/lwip-2.1.2/include/netif/ppp/ipv6cp.h b/third-party/lwip-2.1.2/include/netif/ppp/ipv6cp.h deleted file mode 100644 index 90999738..00000000 --- a/third-party/lwip-2.1.2/include/netif/ppp/ipv6cp.h +++ /dev/null @@ -1,191 +0,0 @@ -/* - * ipv6cp.h - PPP IPV6 Control Protocol. - * - * Copyright (c) 1999 Tommi Komulainen. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Tommi Komulainen - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -/* Original version, based on RFC2023 : - - Copyright (c) 1995, 1996, 1997 Francis.Dupont@inria.fr, INRIA Rocquencourt, - Alain.Durand@imag.fr, IMAG, - Jean-Luc.Richier@imag.fr, IMAG-LSR. - - Copyright (c) 1998, 1999 Francis.Dupont@inria.fr, GIE DYADE, - Alain.Durand@imag.fr, IMAG, - Jean-Luc.Richier@imag.fr, IMAG-LSR. - - Ce travail a été fait au sein du GIE DYADE (Groupement d'Intérêt - Économique ayant pour membres BULL S.A. et l'INRIA). - - Ce logiciel informatique est disponible aux conditions - usuelles dans la recherche, c'est-à-dire qu'il peut - être utilisé, copié, modifié, distribué à l'unique - condition que ce texte soit conservé afin que - l'origine de ce logiciel soit reconnue. - - Le nom de l'Institut National de Recherche en Informatique - et en Automatique (INRIA), de l'IMAG, ou d'une personne morale - ou physique ayant participé à l'élaboration de ce logiciel ne peut - être utilisé sans son accord préalable explicite. - - Ce logiciel est fourni tel quel sans aucune garantie, - support ou responsabilité d'aucune sorte. - Ce logiciel est dérivé de sources d'origine - "University of California at Berkeley" et - "Digital Equipment Corporation" couvertes par des copyrights. - - L'Institut d'Informatique et de Mathématiques Appliquées de Grenoble (IMAG) - est une fédération d'unités mixtes de recherche du CNRS, de l'Institut National - Polytechnique de Grenoble et de l'Université Joseph Fourier regroupant - sept laboratoires dont le laboratoire Logiciels, Systèmes, Réseaux (LSR). - - This work has been done in the context of GIE DYADE (joint R & D venture - between BULL S.A. and INRIA). - - This software is available with usual "research" terms - with the aim of retain credits of the software. - Permission to use, copy, modify and distribute this software for any - purpose and without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies, - and the name of INRIA, IMAG, or any contributor not be used in advertising - or publicity pertaining to this material without the prior explicit - permission. The software is provided "as is" without any - warranties, support or liabilities of any kind. - This software is derived from source code from - "University of California at Berkeley" and - "Digital Equipment Corporation" protected by copyrights. - - Grenoble's Institute of Computer Science and Applied Mathematics (IMAG) - is a federation of seven research units funded by the CNRS, National - Polytechnic Institute of Grenoble and University Joseph Fourier. - The research unit in Software, Systems, Networks (LSR) is member of IMAG. -*/ - -/* - * Derived from : - * - * - * ipcp.h - IP Control Protocol definitions. - * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * $Id: ipv6cp.h,v 1.7 2002/12/04 23:03:32 paulus Exp $ - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && PPP_IPV6_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef IPV6CP_H -#define IPV6CP_H - -#include "eui64.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Options. - */ -#define CI_IFACEID 1 /* Interface Identifier */ -#ifdef IPV6CP_COMP -#define CI_COMPRESSTYPE 2 /* Compression Type */ -#endif /* IPV6CP_COMP */ - -/* No compression types yet defined. - *#define IPV6CP_COMP 0x004f - */ -typedef struct ipv6cp_options { - unsigned int neg_ifaceid :1; /* Negotiate interface identifier? */ - unsigned int req_ifaceid :1; /* Ask peer to send interface identifier? */ - unsigned int accept_local :1; /* accept peer's value for iface id? */ - unsigned int opt_local :1; /* ourtoken set by option */ - unsigned int opt_remote :1; /* histoken set by option */ - unsigned int use_ip :1; /* use IP as interface identifier */ -#if 0 - unsigned int use_persistent :1; /* use uniquely persistent value for address */ -#endif -#ifdef IPV6CP_COMP - unsigned int neg_vj :1; /* Van Jacobson Compression? */ -#endif /* IPV6CP_COMP */ - -#ifdef IPV6CP_COMP - u_short vj_protocol; /* protocol value to use in VJ option */ -#endif /* IPV6CP_COMP */ - eui64_t ourid, hisid; /* Interface identifiers */ -} ipv6cp_options; - -extern const struct protent ipv6cp_protent; - -#ifdef __cplusplus -} -#endif - -#endif /* IPV6CP_H */ -#endif /* PPP_SUPPORT && PPP_IPV6_SUPPORT */ diff --git a/third-party/lwip-2.1.2/include/netif/ppp/lcp.h b/third-party/lwip-2.1.2/include/netif/ppp/lcp.h deleted file mode 100644 index 18ad1cb2..00000000 --- a/third-party/lwip-2.1.2/include/netif/ppp/lcp.h +++ /dev/null @@ -1,179 +0,0 @@ -/* - * lcp.h - Link Control Protocol definitions. - * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * $Id: lcp.h,v 1.20 2004/11/14 22:53:42 carlsonj Exp $ - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef LCP_H -#define LCP_H - -#include "ppp.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Options. - */ -#define CI_VENDOR 0 /* Vendor Specific */ -#define CI_MRU 1 /* Maximum Receive Unit */ -#define CI_ASYNCMAP 2 /* Async Control Character Map */ -#define CI_AUTHTYPE 3 /* Authentication Type */ -#define CI_QUALITY 4 /* Quality Protocol */ -#define CI_MAGICNUMBER 5 /* Magic Number */ -#define CI_PCOMPRESSION 7 /* Protocol Field Compression */ -#define CI_ACCOMPRESSION 8 /* Address/Control Field Compression */ -#define CI_FCSALTERN 9 /* FCS-Alternatives */ -#define CI_SDP 10 /* Self-Describing-Pad */ -#define CI_NUMBERED 11 /* Numbered-Mode */ -#define CI_CALLBACK 13 /* callback */ -#define CI_MRRU 17 /* max reconstructed receive unit; multilink */ -#define CI_SSNHF 18 /* short sequence numbers for multilink */ -#define CI_EPDISC 19 /* endpoint discriminator */ -#define CI_MPPLUS 22 /* Multi-Link-Plus-Procedure */ -#define CI_LDISC 23 /* Link-Discriminator */ -#define CI_LCPAUTH 24 /* LCP Authentication */ -#define CI_COBS 25 /* Consistent Overhead Byte Stuffing */ -#define CI_PREFELIS 26 /* Prefix Elision */ -#define CI_MPHDRFMT 27 /* MP Header Format */ -#define CI_I18N 28 /* Internationalization */ -#define CI_SDL 29 /* Simple Data Link */ - -/* - * LCP-specific packet types (code numbers). - */ -#define PROTREJ 8 /* Protocol Reject */ -#define ECHOREQ 9 /* Echo Request */ -#define ECHOREP 10 /* Echo Reply */ -#define DISCREQ 11 /* Discard Request */ -#define IDENTIF 12 /* Identification */ -#define TIMEREM 13 /* Time Remaining */ - -/* Value used as data for CI_CALLBACK option */ -#define CBCP_OPT 6 /* Use callback control protocol */ - -#if 0 /* moved to ppp_opts.h */ -#define DEFMRU 1500 /* Try for this */ -#define MINMRU 128 /* No MRUs below this */ -#define MAXMRU 16384 /* Normally limit MRU to this */ -#endif /* moved to ppp_opts.h */ - -/* An endpoint discriminator, used with multilink. */ -#define MAX_ENDP_LEN 20 /* maximum length of discriminator value */ -struct epdisc { - unsigned char class_; /* -- The word "class" is reserved in C++. */ - unsigned char length; - unsigned char value[MAX_ENDP_LEN]; -}; - -/* - * The state of options is described by an lcp_options structure. - */ -typedef struct lcp_options { - unsigned int passive :1; /* Don't die if we don't get a response */ - unsigned int silent :1; /* Wait for the other end to start first */ -#if 0 /* UNUSED */ - unsigned int restart :1; /* Restart vs. exit after close */ -#endif /* UNUSED */ - unsigned int neg_mru :1; /* Negotiate the MRU? */ - unsigned int neg_asyncmap :1; /* Negotiate the async map? */ -#if PAP_SUPPORT - unsigned int neg_upap :1; /* Ask for UPAP authentication? */ -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - unsigned int neg_chap :1; /* Ask for CHAP authentication? */ -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT - unsigned int neg_eap :1; /* Ask for EAP authentication? */ -#endif /* EAP_SUPPORT */ - unsigned int neg_magicnumber :1; /* Ask for magic number? */ - unsigned int neg_pcompression :1; /* HDLC Protocol Field Compression? */ - unsigned int neg_accompression :1; /* HDLC Address/Control Field Compression? */ -#if LQR_SUPPORT - unsigned int neg_lqr :1; /* Negotiate use of Link Quality Reports */ -#endif /* LQR_SUPPORT */ - unsigned int neg_cbcp :1; /* Negotiate use of CBCP */ -#ifdef HAVE_MULTILINK - unsigned int neg_mrru :1; /* negotiate multilink MRRU */ -#endif /* HAVE_MULTILINK */ - unsigned int neg_ssnhf :1; /* negotiate short sequence numbers */ - unsigned int neg_endpoint :1; /* negotiate endpoint discriminator */ - - u16_t mru; /* Value of MRU */ -#ifdef HAVE_MULTILINK - u16_t mrru; /* Value of MRRU, and multilink enable */ -#endif /* MULTILINK */ -#if CHAP_SUPPORT - u8_t chap_mdtype; /* which MD types (hashing algorithm) */ -#endif /* CHAP_SUPPORT */ - u32_t asyncmap; /* Value of async map */ - u32_t magicnumber; - u8_t numloops; /* Number of loops during magic number neg. */ -#if LQR_SUPPORT - u32_t lqr_period; /* Reporting period for LQR 1/100ths second */ -#endif /* LQR_SUPPORT */ - struct epdisc endpoint; /* endpoint discriminator */ -} lcp_options; - -void lcp_open(ppp_pcb *pcb); -void lcp_close(ppp_pcb *pcb, const char *reason); -void lcp_lowerup(ppp_pcb *pcb); -void lcp_lowerdown(ppp_pcb *pcb); -void lcp_sprotrej(ppp_pcb *pcb, u_char *p, int len); /* send protocol reject */ - -extern const struct protent lcp_protent; - -#if 0 /* moved to ppp_opts.h */ -/* Default number of times we receive our magic number from the peer - before deciding the link is looped-back. */ -#define DEFLOOPBACKFAIL 10 -#endif /* moved to ppp_opts.h */ - -#ifdef __cplusplus -} -#endif - -#endif /* LCP_H */ -#endif /* PPP_SUPPORT */ diff --git a/third-party/lwip-2.1.2/include/netif/ppp/magic.h b/third-party/lwip-2.1.2/include/netif/ppp/magic.h deleted file mode 100644 index a165e18f..00000000 --- a/third-party/lwip-2.1.2/include/netif/ppp/magic.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * magic.h - PPP Magic Number definitions. - * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * $Id: magic.h,v 1.5 2003/06/11 23:56:26 paulus Exp $ - */ -/***************************************************************************** -* randm.h - Random number generator header file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* Copyright (c) 1998 Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher -* Ported to lwIP. -* 98-05-29 Guy Lancaster , Global Election Systems Inc. -* Extracted from avos. -*****************************************************************************/ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef MAGIC_H -#define MAGIC_H - -#ifdef __cplusplus -extern "C" { -#endif - -/*********************** -*** PUBLIC FUNCTIONS *** -***********************/ - -/* - * Initialize the random number generator. - */ -void magic_init(void); - -/* - * Randomize our random seed value. To be called for truely random events - * such as user operations and network traffic. - */ -void magic_randomize(void); - -/* - * Return a new random number. - */ -u32_t magic(void); /* Returns the next magic number */ - -/* - * Fill buffer with random bytes - * - * Use the random pool to generate random data. This degrades to pseudo - * random when used faster than randomness is supplied using magic_churnrand(). - * Thus it's important to make sure that the results of this are not - * published directly because one could predict the next result to at - * least some degree. Also, it's important to get a good seed before - * the first use. - */ -void magic_random_bytes(unsigned char *buf, u32_t buf_len); - -/* - * Return a new random number between 0 and (2^pow)-1 included. - */ -u32_t magic_pow(u8_t pow); - -#ifdef __cplusplus -} -#endif - -#endif /* MAGIC_H */ - -#endif /* PPP_SUPPORT */ diff --git a/third-party/lwip-2.1.2/include/netif/ppp/mppe.h b/third-party/lwip-2.1.2/include/netif/ppp/mppe.h deleted file mode 100644 index 5de11284..00000000 --- a/third-party/lwip-2.1.2/include/netif/ppp/mppe.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * mppe.h - Definitions for MPPE - * - * Copyright (c) 2008 Paul Mackerras. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && MPPE_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef MPPE_H -#define MPPE_H - -#include "netif/ppp/pppcrypt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define MPPE_PAD 4 /* MPPE growth per frame */ -#define MPPE_MAX_KEY_LEN 16 /* largest key length (128-bit) */ - -/* option bits for ccp_options.mppe */ -#define MPPE_OPT_40 0x01 /* 40 bit */ -#define MPPE_OPT_128 0x02 /* 128 bit */ -#define MPPE_OPT_STATEFUL 0x04 /* stateful mode */ -/* unsupported opts */ -#define MPPE_OPT_56 0x08 /* 56 bit */ -#define MPPE_OPT_MPPC 0x10 /* MPPC compression */ -#define MPPE_OPT_D 0x20 /* Unknown */ -#define MPPE_OPT_UNSUPPORTED (MPPE_OPT_56|MPPE_OPT_MPPC|MPPE_OPT_D) -#define MPPE_OPT_UNKNOWN 0x40 /* Bits !defined in RFC 3078 were set */ - -/* - * This is not nice ... the alternative is a bitfield struct though. - * And unfortunately, we cannot share the same bits for the option - * names above since C and H are the same bit. We could do a u_int32 - * but then we have to do a lwip_htonl() all the time and/or we still need - * to know which octet is which. - */ -#define MPPE_C_BIT 0x01 /* MPPC */ -#define MPPE_D_BIT 0x10 /* Obsolete, usage unknown */ -#define MPPE_L_BIT 0x20 /* 40-bit */ -#define MPPE_S_BIT 0x40 /* 128-bit */ -#define MPPE_M_BIT 0x80 /* 56-bit, not supported */ -#define MPPE_H_BIT 0x01 /* Stateless (in a different byte) */ - -/* Does not include H bit; used for least significant octet only. */ -#define MPPE_ALL_BITS (MPPE_D_BIT|MPPE_L_BIT|MPPE_S_BIT|MPPE_M_BIT|MPPE_H_BIT) - -/* Build a CI from mppe opts (see RFC 3078) */ -#define MPPE_OPTS_TO_CI(opts, ci) \ - do { \ - u_char *ptr = ci; /* u_char[4] */ \ - \ - /* H bit */ \ - if (opts & MPPE_OPT_STATEFUL) \ - *ptr++ = 0x0; \ - else \ - *ptr++ = MPPE_H_BIT; \ - *ptr++ = 0; \ - *ptr++ = 0; \ - \ - /* S,L bits */ \ - *ptr = 0; \ - if (opts & MPPE_OPT_128) \ - *ptr |= MPPE_S_BIT; \ - if (opts & MPPE_OPT_40) \ - *ptr |= MPPE_L_BIT; \ - /* M,D,C bits not supported */ \ - } while (/* CONSTCOND */ 0) - -/* The reverse of the above */ -#define MPPE_CI_TO_OPTS(ci, opts) \ - do { \ - const u_char *ptr = ci; /* u_char[4] */ \ - \ - opts = 0; \ - \ - /* H bit */ \ - if (!(ptr[0] & MPPE_H_BIT)) \ - opts |= MPPE_OPT_STATEFUL; \ - \ - /* S,L bits */ \ - if (ptr[3] & MPPE_S_BIT) \ - opts |= MPPE_OPT_128; \ - if (ptr[3] & MPPE_L_BIT) \ - opts |= MPPE_OPT_40; \ - \ - /* M,D,C bits */ \ - if (ptr[3] & MPPE_M_BIT) \ - opts |= MPPE_OPT_56; \ - if (ptr[3] & MPPE_D_BIT) \ - opts |= MPPE_OPT_D; \ - if (ptr[3] & MPPE_C_BIT) \ - opts |= MPPE_OPT_MPPC; \ - \ - /* Other bits */ \ - if (ptr[0] & ~MPPE_H_BIT) \ - opts |= MPPE_OPT_UNKNOWN; \ - if (ptr[1] || ptr[2]) \ - opts |= MPPE_OPT_UNKNOWN; \ - if (ptr[3] & ~MPPE_ALL_BITS) \ - opts |= MPPE_OPT_UNKNOWN; \ - } while (/* CONSTCOND */ 0) - -/* Shared MPPE padding between MSCHAP and MPPE */ -#define SHA1_PAD_SIZE 40 - -static const u8_t mppe_sha1_pad1[SHA1_PAD_SIZE] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; -static const u8_t mppe_sha1_pad2[SHA1_PAD_SIZE] = { - 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, - 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, - 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, - 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2 -}; - -/* - * State for an MPPE (de)compressor. - */ -typedef struct ppp_mppe_state { - lwip_arc4_context arc4; - u8_t master_key[MPPE_MAX_KEY_LEN]; - u8_t session_key[MPPE_MAX_KEY_LEN]; - u8_t keylen; /* key length in bytes */ - /* NB: 128-bit == 16, 40-bit == 8! - * If we want to support 56-bit, the unit has to change to bits - */ - u8_t bits; /* MPPE control bits */ - u16_t ccount; /* 12-bit coherency count (seqno) */ - u16_t sanity_errors; /* take down LCP if too many */ - unsigned int stateful :1; /* stateful mode flag */ - unsigned int discard :1; /* stateful mode packet loss flag */ -} ppp_mppe_state; - -void mppe_set_key(ppp_pcb *pcb, ppp_mppe_state *state, u8_t *key); -void mppe_init(ppp_pcb *pcb, ppp_mppe_state *state, u8_t options); -void mppe_comp_reset(ppp_pcb *pcb, ppp_mppe_state *state); -err_t mppe_compress(ppp_pcb *pcb, ppp_mppe_state *state, struct pbuf **pb, u16_t protocol); -void mppe_decomp_reset(ppp_pcb *pcb, ppp_mppe_state *state); -err_t mppe_decompress(ppp_pcb *pcb, ppp_mppe_state *state, struct pbuf **pb); - -#ifdef __cplusplus -} -#endif - -#endif /* MPPE_H */ -#endif /* PPP_SUPPORT && MPPE_SUPPORT */ diff --git a/third-party/lwip-2.1.2/include/netif/ppp/polarssl/arc4.h b/third-party/lwip-2.1.2/include/netif/ppp/polarssl/arc4.h deleted file mode 100644 index 4af724cd..00000000 --- a/third-party/lwip-2.1.2/include/netif/ppp/polarssl/arc4.h +++ /dev/null @@ -1,81 +0,0 @@ -/** - * \file arc4.h - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the names of PolarSSL or XySSL nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "netif/ppp/ppp_opts.h" -#if LWIP_INCLUDED_POLARSSL_ARC4 - -#ifndef LWIP_INCLUDED_POLARSSL_ARC4_H -#define LWIP_INCLUDED_POLARSSL_ARC4_H - -/** - * \brief ARC4 context structure - */ -typedef struct -{ - int x; /*!< permutation index */ - int y; /*!< permutation index */ - unsigned char m[256]; /*!< permutation table */ -} -arc4_context; - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief ARC4 key schedule - * - * \param ctx ARC4 context to be initialized - * \param key the secret key - * \param keylen length of the key - */ -void arc4_setup( arc4_context *ctx, unsigned char *key, int keylen ); - -/** - * \brief ARC4 cipher function - * - * \param ctx ARC4 context - * \param buf buffer to be processed - * \param buflen amount of data in buf - */ -void arc4_crypt( arc4_context *ctx, unsigned char *buf, int buflen ); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_INCLUDED_POLARSSL_ARC4_H */ - -#endif /* LWIP_INCLUDED_POLARSSL_ARC4 */ diff --git a/third-party/lwip-2.1.2/include/netif/ppp/polarssl/des.h b/third-party/lwip-2.1.2/include/netif/ppp/polarssl/des.h deleted file mode 100644 index e893890e..00000000 --- a/third-party/lwip-2.1.2/include/netif/ppp/polarssl/des.h +++ /dev/null @@ -1,92 +0,0 @@ -/** - * \file des.h - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the names of PolarSSL or XySSL nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "netif/ppp/ppp_opts.h" -#if LWIP_INCLUDED_POLARSSL_DES - -#ifndef LWIP_INCLUDED_POLARSSL_DES_H -#define LWIP_INCLUDED_POLARSSL_DES_H - -#define DES_ENCRYPT 1 -#define DES_DECRYPT 0 - -/** - * \brief DES context structure - */ -typedef struct -{ - int mode; /*!< encrypt/decrypt */ - unsigned long sk[32]; /*!< DES subkeys */ -} -des_context; - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief DES key schedule (56-bit, encryption) - * - * \param ctx DES context to be initialized - * \param key 8-byte secret key - */ -void des_setkey_enc( des_context *ctx, unsigned char key[8] ); - -/** - * \brief DES key schedule (56-bit, decryption) - * - * \param ctx DES context to be initialized - * \param key 8-byte secret key - */ -void des_setkey_dec( des_context *ctx, unsigned char key[8] ); - -/** - * \brief DES-ECB block encryption/decryption - * - * \param ctx DES context - * \param input 64-bit input block - * \param output 64-bit output block - */ -void des_crypt_ecb( des_context *ctx, - const unsigned char input[8], - unsigned char output[8] ); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_INCLUDED_POLARSSL_DES_H */ - -#endif /* LWIP_INCLUDED_POLARSSL_DES */ diff --git a/third-party/lwip-2.1.2/include/netif/ppp/polarssl/md4.h b/third-party/lwip-2.1.2/include/netif/ppp/polarssl/md4.h deleted file mode 100644 index 57044568..00000000 --- a/third-party/lwip-2.1.2/include/netif/ppp/polarssl/md4.h +++ /dev/null @@ -1,97 +0,0 @@ -/** - * \file md4.h - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the names of PolarSSL or XySSL nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "netif/ppp/ppp_opts.h" -#if LWIP_INCLUDED_POLARSSL_MD4 - -#ifndef LWIP_INCLUDED_POLARSSL_MD4_H -#define LWIP_INCLUDED_POLARSSL_MD4_H - -/** - * \brief MD4 context structure - */ -typedef struct -{ - unsigned long total[2]; /*!< number of bytes processed */ - unsigned long state[4]; /*!< intermediate digest state */ - unsigned char buffer[64]; /*!< data block being processed */ -} -md4_context; - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief MD4 context setup - * - * \param ctx context to be initialized - */ -void md4_starts( md4_context *ctx ); - -/** - * \brief MD4 process buffer - * - * \param ctx MD4 context - * \param input buffer holding the data - * \param ilen length of the input data - */ -void md4_update( md4_context *ctx, const unsigned char *input, int ilen ); - -/** - * \brief MD4 final digest - * - * \param ctx MD4 context - * \param output MD4 checksum result - */ -void md4_finish( md4_context *ctx, unsigned char output[16] ); - -/** - * \brief Output = MD4( input buffer ) - * - * \param input buffer holding the data - * \param ilen length of the input data - * \param output MD4 checksum result - */ -void md4( unsigned char *input, int ilen, unsigned char output[16] ); - - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_INCLUDED_POLARSSL_MD4_H */ - -#endif /* LWIP_INCLUDED_POLARSSL_MD4 */ diff --git a/third-party/lwip-2.1.2/include/netif/ppp/polarssl/md5.h b/third-party/lwip-2.1.2/include/netif/ppp/polarssl/md5.h deleted file mode 100644 index 12440118..00000000 --- a/third-party/lwip-2.1.2/include/netif/ppp/polarssl/md5.h +++ /dev/null @@ -1,96 +0,0 @@ -/** - * \file md5.h - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the names of PolarSSL or XySSL nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "netif/ppp/ppp_opts.h" -#if LWIP_INCLUDED_POLARSSL_MD5 - -#ifndef LWIP_INCLUDED_POLARSSL_MD5_H -#define LWIP_INCLUDED_POLARSSL_MD5_H - -/** - * \brief MD5 context structure - */ -typedef struct -{ - unsigned long total[2]; /*!< number of bytes processed */ - unsigned long state[4]; /*!< intermediate digest state */ - unsigned char buffer[64]; /*!< data block being processed */ -} -md5_context; - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief MD5 context setup - * - * \param ctx context to be initialized - */ -void md5_starts( md5_context *ctx ); - -/** - * \brief MD5 process buffer - * - * \param ctx MD5 context - * \param input buffer holding the data - * \param ilen length of the input data - */ -void md5_update( md5_context *ctx, const unsigned char *input, int ilen ); - -/** - * \brief MD5 final digest - * - * \param ctx MD5 context - * \param output MD5 checksum result - */ -void md5_finish( md5_context *ctx, unsigned char output[16] ); - -/** - * \brief Output = MD5( input buffer ) - * - * \param input buffer holding the data - * \param ilen length of the input data - * \param output MD5 checksum result - */ -void md5( unsigned char *input, int ilen, unsigned char output[16] ); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_INCLUDED_POLARSSL_MD5_H */ - -#endif /* LWIP_INCLUDED_POLARSSL_MD5 */ diff --git a/third-party/lwip-2.1.2/include/netif/ppp/polarssl/sha1.h b/third-party/lwip-2.1.2/include/netif/ppp/polarssl/sha1.h deleted file mode 100644 index a4c53e07..00000000 --- a/third-party/lwip-2.1.2/include/netif/ppp/polarssl/sha1.h +++ /dev/null @@ -1,96 +0,0 @@ -/** - * \file sha1.h - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the names of PolarSSL or XySSL nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "netif/ppp/ppp_opts.h" -#if LWIP_INCLUDED_POLARSSL_SHA1 - -#ifndef LWIP_INCLUDED_POLARSSL_SHA1_H -#define LWIP_INCLUDED_POLARSSL_SHA1_H - -/** - * \brief SHA-1 context structure - */ -typedef struct -{ - unsigned long total[2]; /*!< number of bytes processed */ - unsigned long state[5]; /*!< intermediate digest state */ - unsigned char buffer[64]; /*!< data block being processed */ -} -sha1_context; - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief SHA-1 context setup - * - * \param ctx context to be initialized - */ -void sha1_starts( sha1_context *ctx ); - -/** - * \brief SHA-1 process buffer - * - * \param ctx SHA-1 context - * \param input buffer holding the data - * \param ilen length of the input data - */ -void sha1_update( sha1_context *ctx, const unsigned char *input, int ilen ); - -/** - * \brief SHA-1 final digest - * - * \param ctx SHA-1 context - * \param output SHA-1 checksum result - */ -void sha1_finish( sha1_context *ctx, unsigned char output[20] ); - -/** - * \brief Output = SHA-1( input buffer ) - * - * \param input buffer holding the data - * \param ilen length of the input data - * \param output SHA-1 checksum result - */ -void sha1( unsigned char *input, int ilen, unsigned char output[20] ); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_INCLUDED_POLARSSL_SHA1_H */ - -#endif /* LWIP_INCLUDED_POLARSSL_SHA1 */ diff --git a/third-party/lwip-2.1.2/include/netif/ppp/ppp.h b/third-party/lwip-2.1.2/include/netif/ppp/ppp.h deleted file mode 100644 index 3d73c365..00000000 --- a/third-party/lwip-2.1.2/include/netif/ppp/ppp.h +++ /dev/null @@ -1,698 +0,0 @@ -/***************************************************************************** -* ppp.h - Network Point to Point Protocol header file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1997 Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher -* Ported to lwIP. -* 97-11-05 Guy Lancaster , Global Election Systems Inc. -* Original derived from BSD codes. -*****************************************************************************/ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef PPP_H -#define PPP_H - -#include "lwip/def.h" -#include "lwip/stats.h" -#include "lwip/mem.h" -#include "lwip/netif.h" -#include "lwip/sys.h" -#include "lwip/timeouts.h" -#if PPP_IPV6_SUPPORT -#include "lwip/ip6_addr.h" -#endif /* PPP_IPV6_SUPPORT */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Disable non-working or rarely used PPP feature, so rarely that we don't want to bloat ppp_opts.h with them */ -#ifndef PPP_OPTIONS -#define PPP_OPTIONS 0 -#endif - -#ifndef PPP_NOTIFY -#define PPP_NOTIFY 0 -#endif - -#ifndef PPP_REMOTENAME -#define PPP_REMOTENAME 0 -#endif - -#ifndef PPP_IDLETIMELIMIT -#define PPP_IDLETIMELIMIT 0 -#endif - -#ifndef PPP_LCP_ADAPTIVE -#define PPP_LCP_ADAPTIVE 0 -#endif - -#ifndef PPP_MAXCONNECT -#define PPP_MAXCONNECT 0 -#endif - -#ifndef PPP_ALLOWED_ADDRS -#define PPP_ALLOWED_ADDRS 0 -#endif - -#ifndef PPP_PROTOCOLNAME -#define PPP_PROTOCOLNAME 0 -#endif - -#ifndef PPP_STATS_SUPPORT -#define PPP_STATS_SUPPORT 0 -#endif - -#ifndef DEFLATE_SUPPORT -#define DEFLATE_SUPPORT 0 -#endif - -#ifndef BSDCOMPRESS_SUPPORT -#define BSDCOMPRESS_SUPPORT 0 -#endif - -#ifndef PREDICTOR_SUPPORT -#define PREDICTOR_SUPPORT 0 -#endif - -/************************* -*** PUBLIC DEFINITIONS *** -*************************/ - -/* - * The basic PPP frame. - */ -#define PPP_HDRLEN 4 /* octets for standard ppp header */ -#define PPP_FCSLEN 2 /* octets for FCS */ - -/* - * Values for phase. - */ -#define PPP_PHASE_DEAD 0 -#define PPP_PHASE_MASTER 1 -#define PPP_PHASE_HOLDOFF 2 -#define PPP_PHASE_INITIALIZE 3 -#define PPP_PHASE_SERIALCONN 4 -#define PPP_PHASE_DORMANT 5 -#define PPP_PHASE_ESTABLISH 6 -#define PPP_PHASE_AUTHENTICATE 7 -#define PPP_PHASE_CALLBACK 8 -#define PPP_PHASE_NETWORK 9 -#define PPP_PHASE_RUNNING 10 -#define PPP_PHASE_TERMINATE 11 -#define PPP_PHASE_DISCONNECT 12 - -/* Error codes. */ -#define PPPERR_NONE 0 /* No error. */ -#define PPPERR_PARAM 1 /* Invalid parameter. */ -#define PPPERR_OPEN 2 /* Unable to open PPP session. */ -#define PPPERR_DEVICE 3 /* Invalid I/O device for PPP. */ -#define PPPERR_ALLOC 4 /* Unable to allocate resources. */ -#define PPPERR_USER 5 /* User interrupt. */ -#define PPPERR_CONNECT 6 /* Connection lost. */ -#define PPPERR_AUTHFAIL 7 /* Failed authentication challenge. */ -#define PPPERR_PROTOCOL 8 /* Failed to meet protocol. */ -#define PPPERR_PEERDEAD 9 /* Connection timeout */ -#define PPPERR_IDLETIMEOUT 10 /* Idle Timeout */ -#define PPPERR_CONNECTTIME 11 /* Max connect time reached */ -#define PPPERR_LOOPBACK 12 /* Loopback detected */ - -/* Whether auth support is enabled at all */ -#define PPP_AUTH_SUPPORT (PAP_SUPPORT || CHAP_SUPPORT || EAP_SUPPORT) - -/************************ -*** PUBLIC DATA TYPES *** -************************/ - -/* - * Other headers require ppp_pcb definition for prototypes, but ppp_pcb - * require some structure definition from other headers as well, we are - * fixing the dependency loop here by declaring the ppp_pcb type then - * by including headers containing necessary struct definition for ppp_pcb - */ -typedef struct ppp_pcb_s ppp_pcb; - -/* Type definitions for BSD code. */ -#ifndef __u_char_defined -typedef unsigned long u_long; -typedef unsigned int u_int; -typedef unsigned short u_short; -typedef unsigned char u_char; -#endif - -#include "fsm.h" -#include "lcp.h" -#if CCP_SUPPORT -#include "ccp.h" -#endif /* CCP_SUPPORT */ -#if MPPE_SUPPORT -#include "mppe.h" -#endif /* MPPE_SUPPORT */ -#if PPP_IPV4_SUPPORT -#include "ipcp.h" -#endif /* PPP_IPV4_SUPPORT */ -#if PPP_IPV6_SUPPORT -#include "ipv6cp.h" -#endif /* PPP_IPV6_SUPPORT */ -#if PAP_SUPPORT -#include "upap.h" -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT -#include "chap-new.h" -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT -#include "eap.h" -#endif /* EAP_SUPPORT */ -#if VJ_SUPPORT -#include "vj.h" -#endif /* VJ_SUPPORT */ - -/* Link status callback function prototype */ -typedef void (*ppp_link_status_cb_fn)(ppp_pcb *pcb, int err_code, void *ctx); - -/* - * PPP configuration. - */ -typedef struct ppp_settings_s { - -#if PPP_SERVER && PPP_AUTH_SUPPORT - unsigned int auth_required :1; /* Peer is required to authenticate */ - unsigned int null_login :1; /* Username of "" and a password of "" are acceptable */ -#endif /* PPP_SERVER && PPP_AUTH_SUPPORT */ -#if PPP_REMOTENAME - unsigned int explicit_remote :1; /* remote_name specified with remotename opt */ -#endif /* PPP_REMOTENAME */ -#if PAP_SUPPORT - unsigned int refuse_pap :1; /* Don't proceed auth. with PAP */ -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - unsigned int refuse_chap :1; /* Don't proceed auth. with CHAP */ -#endif /* CHAP_SUPPORT */ -#if MSCHAP_SUPPORT - unsigned int refuse_mschap :1; /* Don't proceed auth. with MS-CHAP */ - unsigned int refuse_mschap_v2 :1; /* Don't proceed auth. with MS-CHAPv2 */ -#endif /* MSCHAP_SUPPORT */ -#if EAP_SUPPORT - unsigned int refuse_eap :1; /* Don't proceed auth. with EAP */ -#endif /* EAP_SUPPORT */ -#if LWIP_DNS - unsigned int usepeerdns :1; /* Ask peer for DNS adds */ -#endif /* LWIP_DNS */ - unsigned int persist :1; /* Persist mode, always try to open the connection */ -#if PRINTPKT_SUPPORT - unsigned int hide_password :1; /* Hide password in dumped packets */ -#endif /* PRINTPKT_SUPPORT */ - unsigned int noremoteip :1; /* Let him have no IP address */ - unsigned int lax_recv :1; /* accept control chars in asyncmap */ - unsigned int noendpoint :1; /* don't send/accept endpoint discriminator */ -#if PPP_LCP_ADAPTIVE - unsigned int lcp_echo_adaptive :1; /* request echo only if the link was idle */ -#endif /* PPP_LCP_ADAPTIVE */ -#if MPPE_SUPPORT - unsigned int require_mppe :1; /* Require MPPE (Microsoft Point to Point Encryption) */ - unsigned int refuse_mppe_40 :1; /* Allow MPPE 40-bit mode? */ - unsigned int refuse_mppe_128 :1; /* Allow MPPE 128-bit mode? */ - unsigned int refuse_mppe_stateful :1; /* Allow MPPE stateful mode? */ -#endif /* MPPE_SUPPORT */ - - u16_t listen_time; /* time to listen first (ms), waiting for peer to send LCP packet */ - -#if PPP_IDLETIMELIMIT - u16_t idle_time_limit; /* Disconnect if idle for this many seconds */ -#endif /* PPP_IDLETIMELIMIT */ -#if PPP_MAXCONNECT - u32_t maxconnect; /* Maximum connect time (seconds) */ -#endif /* PPP_MAXCONNECT */ - -#if PPP_AUTH_SUPPORT - /* auth data */ - const char *user; /* Username for PAP */ - const char *passwd; /* Password for PAP, secret for CHAP */ -#if PPP_REMOTENAME - char remote_name[MAXNAMELEN + 1]; /* Peer's name for authentication */ -#endif /* PPP_REMOTENAME */ - -#if PAP_SUPPORT - u8_t pap_timeout_time; /* Timeout (seconds) for auth-req retrans. */ - u8_t pap_max_transmits; /* Number of auth-reqs sent */ -#if PPP_SERVER - u8_t pap_req_timeout; /* Time to wait for auth-req from peer */ -#endif /* PPP_SERVER */ -#endif /* PAP_SUPPPORT */ - -#if CHAP_SUPPORT - u8_t chap_timeout_time; /* Timeout (seconds) for retransmitting req */ - u8_t chap_max_transmits; /* max # times to send challenge */ -#if PPP_SERVER - u8_t chap_rechallenge_time; /* Time to wait for auth-req from peer */ -#endif /* PPP_SERVER */ -#endif /* CHAP_SUPPPORT */ - -#if EAP_SUPPORT - u8_t eap_req_time; /* Time to wait (for retransmit/fail) */ - u8_t eap_allow_req; /* Max Requests allowed */ -#if PPP_SERVER - u8_t eap_timeout_time; /* Time to wait (for retransmit/fail) */ - u8_t eap_max_transmits; /* Max Requests allowed */ -#endif /* PPP_SERVER */ -#endif /* EAP_SUPPORT */ - -#endif /* PPP_AUTH_SUPPORT */ - - u8_t fsm_timeout_time; /* Timeout time in seconds */ - u8_t fsm_max_conf_req_transmits; /* Maximum Configure-Request transmissions */ - u8_t fsm_max_term_transmits; /* Maximum Terminate-Request transmissions */ - u8_t fsm_max_nak_loops; /* Maximum number of nak loops tolerated */ - - u8_t lcp_loopbackfail; /* Number of times we receive our magic number from the peer - before deciding the link is looped-back. */ - u8_t lcp_echo_interval; /* Interval between LCP echo-requests */ - u8_t lcp_echo_fails; /* Tolerance to unanswered echo-requests */ - -} ppp_settings; - -#if PPP_SERVER -struct ppp_addrs { -#if PPP_IPV4_SUPPORT - ip4_addr_t our_ipaddr, his_ipaddr, netmask; -#if LWIP_DNS - ip4_addr_t dns1, dns2; -#endif /* LWIP_DNS */ -#endif /* PPP_IPV4_SUPPORT */ -#if PPP_IPV6_SUPPORT - ip6_addr_t our6_ipaddr, his6_ipaddr; -#endif /* PPP_IPV6_SUPPORT */ -}; -#endif /* PPP_SERVER */ - -/* - * PPP interface control block. - */ -struct ppp_pcb_s { - ppp_settings settings; - const struct link_callbacks *link_cb; - void *link_ctx_cb; - void (*link_status_cb)(ppp_pcb *pcb, int err_code, void *ctx); /* Status change callback */ -#if PPP_NOTIFY_PHASE - void (*notify_phase_cb)(ppp_pcb *pcb, u8_t phase, void *ctx); /* Notify phase callback */ -#endif /* PPP_NOTIFY_PHASE */ - void *ctx_cb; /* Callbacks optional pointer */ - struct netif *netif; /* PPP interface */ - u8_t phase; /* where the link is at */ - u8_t err_code; /* Code indicating why interface is down. */ - - /* flags */ -#if PPP_IPV4_SUPPORT - unsigned int ask_for_local :1; /* request our address from peer */ - unsigned int ipcp_is_open :1; /* haven't called np_finished() */ - unsigned int ipcp_is_up :1; /* have called ipcp_up() */ - unsigned int if4_up :1; /* True when the IPv4 interface is up. */ -#if 0 /* UNUSED - PROXY ARP */ - unsigned int proxy_arp_set :1; /* Have created proxy arp entry */ -#endif /* UNUSED - PROXY ARP */ -#endif /* PPP_IPV4_SUPPORT */ -#if PPP_IPV6_SUPPORT - unsigned int ipv6cp_is_up :1; /* have called ip6cp_up() */ - unsigned int if6_up :1; /* True when the IPv6 interface is up. */ -#endif /* PPP_IPV6_SUPPORT */ - unsigned int lcp_echo_timer_running :1; /* set if a timer is running */ -#if VJ_SUPPORT - unsigned int vj_enabled :1; /* Flag indicating VJ compression enabled. */ -#endif /* VJ_SUPPORT */ -#if CCP_SUPPORT - unsigned int ccp_all_rejected :1; /* we rejected all peer's options */ -#endif /* CCP_SUPPORT */ -#if MPPE_SUPPORT - unsigned int mppe_keys_set :1; /* Have the MPPE keys been set? */ -#endif /* MPPE_SUPPORT */ - -#if PPP_AUTH_SUPPORT - /* auth data */ -#if PPP_SERVER && defined(HAVE_MULTILINK) - char peer_authname[MAXNAMELEN + 1]; /* The name by which the peer authenticated itself to us. */ -#endif /* PPP_SERVER && defined(HAVE_MULTILINK) */ - u16_t auth_pending; /* Records which authentication operations haven't completed yet. */ - u16_t auth_done; /* Records which authentication operations have been completed. */ - -#if PAP_SUPPORT - upap_state upap; /* PAP data */ -#endif /* PAP_SUPPORT */ - -#if CHAP_SUPPORT - chap_client_state chap_client; /* CHAP client data */ -#if PPP_SERVER - chap_server_state chap_server; /* CHAP server data */ -#endif /* PPP_SERVER */ -#endif /* CHAP_SUPPORT */ - -#if EAP_SUPPORT - eap_state eap; /* EAP data */ -#endif /* EAP_SUPPORT */ -#endif /* PPP_AUTH_SUPPORT */ - - fsm lcp_fsm; /* LCP fsm structure */ - lcp_options lcp_wantoptions; /* Options that we want to request */ - lcp_options lcp_gotoptions; /* Options that peer ack'd */ - lcp_options lcp_allowoptions; /* Options we allow peer to request */ - lcp_options lcp_hisoptions; /* Options that we ack'd */ - u16_t peer_mru; /* currently negotiated peer MRU */ - u8_t lcp_echos_pending; /* Number of outstanding echo msgs */ - u8_t lcp_echo_number; /* ID number of next echo frame */ - - u8_t num_np_open; /* Number of network protocols which we have opened. */ - u8_t num_np_up; /* Number of network protocols which have come up. */ - -#if VJ_SUPPORT - struct vjcompress vj_comp; /* Van Jacobson compression header. */ -#endif /* VJ_SUPPORT */ - -#if CCP_SUPPORT - fsm ccp_fsm; /* CCP fsm structure */ - ccp_options ccp_wantoptions; /* what to request the peer to use */ - ccp_options ccp_gotoptions; /* what the peer agreed to do */ - ccp_options ccp_allowoptions; /* what we'll agree to do */ - ccp_options ccp_hisoptions; /* what we agreed to do */ - u8_t ccp_localstate; /* Local state (mainly for handling reset-reqs and reset-acks). */ - u8_t ccp_receive_method; /* Method chosen on receive path */ - u8_t ccp_transmit_method; /* Method chosen on transmit path */ -#if MPPE_SUPPORT - ppp_mppe_state mppe_comp; /* MPPE "compressor" structure */ - ppp_mppe_state mppe_decomp; /* MPPE "decompressor" structure */ -#endif /* MPPE_SUPPORT */ -#endif /* CCP_SUPPORT */ - -#if PPP_IPV4_SUPPORT - fsm ipcp_fsm; /* IPCP fsm structure */ - ipcp_options ipcp_wantoptions; /* Options that we want to request */ - ipcp_options ipcp_gotoptions; /* Options that peer ack'd */ - ipcp_options ipcp_allowoptions; /* Options we allow peer to request */ - ipcp_options ipcp_hisoptions; /* Options that we ack'd */ -#endif /* PPP_IPV4_SUPPORT */ - -#if PPP_IPV6_SUPPORT - fsm ipv6cp_fsm; /* IPV6CP fsm structure */ - ipv6cp_options ipv6cp_wantoptions; /* Options that we want to request */ - ipv6cp_options ipv6cp_gotoptions; /* Options that peer ack'd */ - ipv6cp_options ipv6cp_allowoptions; /* Options we allow peer to request */ - ipv6cp_options ipv6cp_hisoptions; /* Options that we ack'd */ -#endif /* PPP_IPV6_SUPPORT */ -}; - -/************************ - *** PUBLIC FUNCTIONS *** - ************************/ - -/* - * WARNING: For multi-threads environment, all ppp_set_* functions most - * only be called while the PPP is in the dead phase (i.e. disconnected). - */ - -#if PPP_AUTH_SUPPORT -/* - * Set PPP authentication. - * - * Warning: Using PPPAUTHTYPE_ANY might have security consequences. - * RFC 1994 says: - * - * In practice, within or associated with each PPP server, there is a - * database which associates "user" names with authentication - * information ("secrets"). It is not anticipated that a particular - * named user would be authenticated by multiple methods. This would - * make the user vulnerable to attacks which negotiate the least secure - * method from among a set (such as PAP rather than CHAP). If the same - * secret was used, PAP would reveal the secret to be used later with - * CHAP. - * - * Instead, for each user name there should be an indication of exactly - * one method used to authenticate that user name. If a user needs to - * make use of different authentication methods under different - * circumstances, then distinct user names SHOULD be employed, each of - * which identifies exactly one authentication method. - * - * Default is none auth type, unset (NULL) user and passwd. - */ -#define PPPAUTHTYPE_NONE 0x00 -#define PPPAUTHTYPE_PAP 0x01 -#define PPPAUTHTYPE_CHAP 0x02 -#define PPPAUTHTYPE_MSCHAP 0x04 -#define PPPAUTHTYPE_MSCHAP_V2 0x08 -#define PPPAUTHTYPE_EAP 0x10 -#define PPPAUTHTYPE_ANY 0xff -void ppp_set_auth(ppp_pcb *pcb, u8_t authtype, const char *user, const char *passwd); - -/* - * If set, peer is required to authenticate. This is mostly necessary for PPP server support. - * - * Default is false. - */ -#define ppp_set_auth_required(ppp, boolval) (ppp->settings.auth_required = boolval) -#endif /* PPP_AUTH_SUPPORT */ - -#if PPP_IPV4_SUPPORT -/* - * Set PPP interface "our" and "his" IPv4 addresses. This is mostly necessary for PPP server - * support but it can also be used on a PPP link where each side choose its own IP address. - * - * Default is unset (0.0.0.0). - */ -#define ppp_set_ipcp_ouraddr(ppp, addr) do { ppp->ipcp_wantoptions.ouraddr = ip4_addr_get_u32(addr); \ - ppp->ask_for_local = ppp->ipcp_wantoptions.ouraddr != 0; } while(0) -#define ppp_set_ipcp_hisaddr(ppp, addr) (ppp->ipcp_wantoptions.hisaddr = ip4_addr_get_u32(addr)) -#if LWIP_DNS -/* - * Set DNS server addresses that are sent if the peer asks for them. This is mostly necessary - * for PPP server support. - * - * Default is unset (0.0.0.0). - */ -#define ppp_set_ipcp_dnsaddr(ppp, index, addr) (ppp->ipcp_allowoptions.dnsaddr[index] = ip4_addr_get_u32(addr)) - -/* - * If set, we ask the peer for up to 2 DNS server addresses. Received DNS server addresses are - * registered using the dns_setserver() function. - * - * Default is false. - */ -#define ppp_set_usepeerdns(ppp, boolval) (ppp->settings.usepeerdns = boolval) -#endif /* LWIP_DNS */ -#endif /* PPP_IPV4_SUPPORT */ - -#if MPPE_SUPPORT -/* Disable MPPE (Microsoft Point to Point Encryption). This parameter is exclusive. */ -#define PPP_MPPE_DISABLE 0x00 -/* Require the use of MPPE (Microsoft Point to Point Encryption). */ -#define PPP_MPPE_ENABLE 0x01 -/* Allow MPPE to use stateful mode. Stateless mode is still attempted first. */ -#define PPP_MPPE_ALLOW_STATEFUL 0x02 -/* Refuse the use of MPPE with 40-bit encryption. Conflict with PPP_MPPE_REFUSE_128. */ -#define PPP_MPPE_REFUSE_40 0x04 -/* Refuse the use of MPPE with 128-bit encryption. Conflict with PPP_MPPE_REFUSE_40. */ -#define PPP_MPPE_REFUSE_128 0x08 -/* - * Set MPPE configuration - * - * Default is disabled. - */ -void ppp_set_mppe(ppp_pcb *pcb, u8_t flags); -#endif /* MPPE_SUPPORT */ - -/* - * Wait for up to intval milliseconds for a valid PPP packet from the peer. - * At the end of this time, or when a valid PPP packet is received from the - * peer, we commence negotiation by sending our first LCP packet. - * - * Default is 0. - */ -#define ppp_set_listen_time(ppp, intval) (ppp->settings.listen_time = intval) - -/* - * If set, we will attempt to initiate a connection but if no reply is received from - * the peer, we will then just wait passively for a valid LCP packet from the peer. - * - * Default is false. - */ -#define ppp_set_passive(ppp, boolval) (ppp->lcp_wantoptions.passive = boolval) - -/* - * If set, we will not transmit LCP packets to initiate a connection until a valid - * LCP packet is received from the peer. This is what we usually call the server mode. - * - * Default is false. - */ -#define ppp_set_silent(ppp, boolval) (ppp->lcp_wantoptions.silent = boolval) - -/* - * If set, enable protocol field compression negotiation in both the receive and - * the transmit direction. - * - * Default is true. - */ -#define ppp_set_neg_pcomp(ppp, boolval) (ppp->lcp_wantoptions.neg_pcompression = \ - ppp->lcp_allowoptions.neg_pcompression = boolval) - -/* - * If set, enable Address/Control compression in both the receive and the transmit - * direction. - * - * Default is true. - */ -#define ppp_set_neg_accomp(ppp, boolval) (ppp->lcp_wantoptions.neg_accompression = \ - ppp->lcp_allowoptions.neg_accompression = boolval) - -/* - * If set, enable asyncmap negotiation. Otherwise forcing all control characters to - * be escaped for both the transmit and the receive direction. - * - * Default is true. - */ -#define ppp_set_neg_asyncmap(ppp, boolval) (ppp->lcp_wantoptions.neg_asyncmap = \ - ppp->lcp_allowoptions.neg_asyncmap = boolval) - -/* - * This option sets the Async-Control-Character-Map (ACCM) for this end of the link. - * The ACCM is a set of 32 bits, one for each of the ASCII control characters with - * values from 0 to 31, where a 1 bit indicates that the corresponding control - * character should not be used in PPP packets sent to this system. The map is - * an unsigned 32 bits integer where the least significant bit (00000001) represents - * character 0 and the most significant bit (80000000) represents character 31. - * We will then ask the peer to send these characters as a 2-byte escape sequence. - * - * Default is 0. - */ -#define ppp_set_asyncmap(ppp, intval) (ppp->lcp_wantoptions.asyncmap = intval) - -/* - * Set a PPP interface as the default network interface - * (used to output all packets for which no specific route is found). - */ -#define ppp_set_default(ppp) netif_set_default(ppp->netif) - -#if PPP_NOTIFY_PHASE -/* - * Set a PPP notify phase callback. - * - * This can be used for example to set a LED pattern depending on the - * current phase of the PPP session. - */ -typedef void (*ppp_notify_phase_cb_fn)(ppp_pcb *pcb, u8_t phase, void *ctx); -void ppp_set_notify_phase_callback(ppp_pcb *pcb, ppp_notify_phase_cb_fn notify_phase_cb); -#endif /* PPP_NOTIFY_PHASE */ - -/* - * Initiate a PPP connection. - * - * This can only be called if PPP is in the dead phase. - * - * Holdoff is the time to wait (in seconds) before initiating - * the connection. - * - * If this port connects to a modem, the modem connection must be - * established before calling this. - */ -err_t ppp_connect(ppp_pcb *pcb, u16_t holdoff); - -#if PPP_SERVER -/* - * Listen for an incoming PPP connection. - * - * This can only be called if PPP is in the dead phase. - * - * If this port connects to a modem, the modem connection must be - * established before calling this. - */ -err_t ppp_listen(ppp_pcb *pcb); -#endif /* PPP_SERVER */ - -/* - * Initiate the end of a PPP connection. - * Any outstanding packets in the queues are dropped. - * - * Setting nocarrier to 1 close the PPP connection without initiating the - * shutdown procedure. Always using nocarrier = 0 is still recommended, - * this is going to take a little longer time if your link is down, but - * is a safer choice for the PPP state machine. - * - * Return 0 on success, an error code on failure. - */ -err_t ppp_close(ppp_pcb *pcb, u8_t nocarrier); - -/* - * Release the control block. - * - * This can only be called if PPP is in the dead phase. - * - * You must use ppp_close() before if you wish to terminate - * an established PPP session. - * - * Return 0 on success, an error code on failure. - */ -err_t ppp_free(ppp_pcb *pcb); - -/* - * PPP IOCTL commands. - * - * Get the up status - 0 for down, non-zero for up. The argument must - * point to an int. - */ -#define PPPCTLG_UPSTATUS 0 - -/* - * Get the PPP error code. The argument must point to an int. - * Returns a PPPERR_* value. - */ -#define PPPCTLG_ERRCODE 1 - -/* - * Get the fd associated with a PPP over serial - */ -#define PPPCTLG_FD 2 - -/* - * Get and set parameters for the given connection. - * Return 0 on success, an error code on failure. - */ -err_t ppp_ioctl(ppp_pcb *pcb, u8_t cmd, void *arg); - -/* Get the PPP netif interface */ -#define ppp_netif(ppp) (ppp->netif) - -/* Set an lwIP-style status-callback for the selected PPP device */ -#define ppp_set_netif_statuscallback(ppp, status_cb) \ - netif_set_status_callback(ppp->netif, status_cb); - -/* Set an lwIP-style link-callback for the selected PPP device */ -#define ppp_set_netif_linkcallback(ppp, link_cb) \ - netif_set_link_callback(ppp->netif, link_cb); - -#ifdef __cplusplus -} -#endif - -#endif /* PPP_H */ - -#endif /* PPP_SUPPORT */ diff --git a/third-party/lwip-2.1.2/include/netif/ppp/ppp_impl.h b/third-party/lwip-2.1.2/include/netif/ppp/ppp_impl.h deleted file mode 100644 index 40843d5a..00000000 --- a/third-party/lwip-2.1.2/include/netif/ppp/ppp_impl.h +++ /dev/null @@ -1,722 +0,0 @@ -/***************************************************************************** -* ppp.h - Network Point to Point Protocol header file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1997 Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher -* Ported to lwIP. -* 97-11-05 Guy Lancaster , Global Election Systems Inc. -* Original derived from BSD codes. -*****************************************************************************/ -#ifndef LWIP_HDR_PPP_IMPL_H -#define LWIP_HDR_PPP_IMPL_H - -#include "netif/ppp/ppp_opts.h" - -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifdef PPP_INCLUDE_SETTINGS_HEADER -#include "ppp_settings.h" -#endif - -#include /* formats */ -#include -#include -#include /* strtol() */ - -#include "lwip/netif.h" -#include "lwip/def.h" -#include "lwip/timeouts.h" - -#include "ppp.h" -#include "pppdebug.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Memory used for control packets. - * - * PPP_CTRL_PBUF_MAX_SIZE is the amount of memory we allocate when we - * cannot figure out how much we are going to use before filling the buffer. - */ -#if PPP_USE_PBUF_RAM -#define PPP_CTRL_PBUF_TYPE PBUF_RAM -#define PPP_CTRL_PBUF_MAX_SIZE 512 -#else /* PPP_USE_PBUF_RAM */ -#define PPP_CTRL_PBUF_TYPE PBUF_POOL -#define PPP_CTRL_PBUF_MAX_SIZE PBUF_POOL_BUFSIZE -#endif /* PPP_USE_PBUF_RAM */ - -/* - * The basic PPP frame. - */ -#define PPP_ADDRESS(p) (((u_char *)(p))[0]) -#define PPP_CONTROL(p) (((u_char *)(p))[1]) -#define PPP_PROTOCOL(p) ((((u_char *)(p))[2] << 8) + ((u_char *)(p))[3]) - -/* - * Significant octet values. - */ -#define PPP_ALLSTATIONS 0xff /* All-Stations broadcast address */ -#define PPP_UI 0x03 /* Unnumbered Information */ -#define PPP_FLAG 0x7e /* Flag Sequence */ -#define PPP_ESCAPE 0x7d /* Asynchronous Control Escape */ -#define PPP_TRANS 0x20 /* Asynchronous transparency modifier */ - -/* - * Protocol field values. - */ -#define PPP_IP 0x21 /* Internet Protocol */ -#if 0 /* UNUSED */ -#define PPP_AT 0x29 /* AppleTalk Protocol */ -#define PPP_IPX 0x2b /* IPX protocol */ -#endif /* UNUSED */ -#if VJ_SUPPORT -#define PPP_VJC_COMP 0x2d /* VJ compressed TCP */ -#define PPP_VJC_UNCOMP 0x2f /* VJ uncompressed TCP */ -#endif /* VJ_SUPPORT */ -#if PPP_IPV6_SUPPORT -#define PPP_IPV6 0x57 /* Internet Protocol Version 6 */ -#endif /* PPP_IPV6_SUPPORT */ -#if CCP_SUPPORT -#define PPP_COMP 0xfd /* compressed packet */ -#endif /* CCP_SUPPORT */ -#define PPP_IPCP 0x8021 /* IP Control Protocol */ -#if 0 /* UNUSED */ -#define PPP_ATCP 0x8029 /* AppleTalk Control Protocol */ -#define PPP_IPXCP 0x802b /* IPX Control Protocol */ -#endif /* UNUSED */ -#if PPP_IPV6_SUPPORT -#define PPP_IPV6CP 0x8057 /* IPv6 Control Protocol */ -#endif /* PPP_IPV6_SUPPORT */ -#if CCP_SUPPORT -#define PPP_CCP 0x80fd /* Compression Control Protocol */ -#endif /* CCP_SUPPORT */ -#if ECP_SUPPORT -#define PPP_ECP 0x8053 /* Encryption Control Protocol */ -#endif /* ECP_SUPPORT */ -#define PPP_LCP 0xc021 /* Link Control Protocol */ -#if PAP_SUPPORT -#define PPP_PAP 0xc023 /* Password Authentication Protocol */ -#endif /* PAP_SUPPORT */ -#if LQR_SUPPORT -#define PPP_LQR 0xc025 /* Link Quality Report protocol */ -#endif /* LQR_SUPPORT */ -#if CHAP_SUPPORT -#define PPP_CHAP 0xc223 /* Cryptographic Handshake Auth. Protocol */ -#endif /* CHAP_SUPPORT */ -#if CBCP_SUPPORT -#define PPP_CBCP 0xc029 /* Callback Control Protocol */ -#endif /* CBCP_SUPPORT */ -#if EAP_SUPPORT -#define PPP_EAP 0xc227 /* Extensible Authentication Protocol */ -#endif /* EAP_SUPPORT */ - -/* - * The following struct gives the addresses of procedures to call - * for a particular lower link level protocol. - */ -struct link_callbacks { - /* Start a connection (e.g. Initiate discovery phase) */ - void (*connect) (ppp_pcb *pcb, void *ctx); -#if PPP_SERVER - /* Listen for an incoming connection (Passive mode) */ - void (*listen) (ppp_pcb *pcb, void *ctx); -#endif /* PPP_SERVER */ - /* End a connection (i.e. initiate disconnect phase) */ - void (*disconnect) (ppp_pcb *pcb, void *ctx); - /* Free lower protocol control block */ - err_t (*free) (ppp_pcb *pcb, void *ctx); - /* Write a pbuf to a ppp link, only used from PPP functions to send PPP packets. */ - err_t (*write)(ppp_pcb *pcb, void *ctx, struct pbuf *p); - /* Send a packet from lwIP core (IPv4 or IPv6) */ - err_t (*netif_output)(ppp_pcb *pcb, void *ctx, struct pbuf *p, u_short protocol); - /* configure the transmit-side characteristics of the PPP interface */ - void (*send_config)(ppp_pcb *pcb, void *ctx, u32_t accm, int pcomp, int accomp); - /* confire the receive-side characteristics of the PPP interface */ - void (*recv_config)(ppp_pcb *pcb, void *ctx, u32_t accm, int pcomp, int accomp); -}; - -/* - * What to do with network protocol (NP) packets. - */ -enum NPmode { - NPMODE_PASS, /* pass the packet through */ - NPMODE_DROP, /* silently drop the packet */ - NPMODE_ERROR, /* return an error */ - NPMODE_QUEUE /* save it up for later. */ -}; - -/* - * Statistics. - */ -#if PPP_STATS_SUPPORT -struct pppstat { - unsigned int ppp_ibytes; /* bytes received */ - unsigned int ppp_ipackets; /* packets received */ - unsigned int ppp_ierrors; /* receive errors */ - unsigned int ppp_obytes; /* bytes sent */ - unsigned int ppp_opackets; /* packets sent */ - unsigned int ppp_oerrors; /* transmit errors */ -}; - -#if VJ_SUPPORT -struct vjstat { - unsigned int vjs_packets; /* outbound packets */ - unsigned int vjs_compressed; /* outbound compressed packets */ - unsigned int vjs_searches; /* searches for connection state */ - unsigned int vjs_misses; /* times couldn't find conn. state */ - unsigned int vjs_uncompressedin; /* inbound uncompressed packets */ - unsigned int vjs_compressedin; /* inbound compressed packets */ - unsigned int vjs_errorin; /* inbound unknown type packets */ - unsigned int vjs_tossed; /* inbound packets tossed because of error */ -}; -#endif /* VJ_SUPPORT */ - -struct ppp_stats { - struct pppstat p; /* basic PPP statistics */ -#if VJ_SUPPORT - struct vjstat vj; /* VJ header compression statistics */ -#endif /* VJ_SUPPORT */ -}; - -#if CCP_SUPPORT -struct compstat { - unsigned int unc_bytes; /* total uncompressed bytes */ - unsigned int unc_packets; /* total uncompressed packets */ - unsigned int comp_bytes; /* compressed bytes */ - unsigned int comp_packets; /* compressed packets */ - unsigned int inc_bytes; /* incompressible bytes */ - unsigned int inc_packets; /* incompressible packets */ - unsigned int ratio; /* recent compression ratio << 8 */ -}; - -struct ppp_comp_stats { - struct compstat c; /* packet compression statistics */ - struct compstat d; /* packet decompression statistics */ -}; -#endif /* CCP_SUPPORT */ - -#endif /* PPP_STATS_SUPPORT */ - -#if PPP_IDLETIMELIMIT -/* - * The following structure records the time in seconds since - * the last NP packet was sent or received. - */ -struct ppp_idle { - time_t xmit_idle; /* time since last NP packet sent */ - time_t recv_idle; /* time since last NP packet received */ -}; -#endif /* PPP_IDLETIMELIMIT */ - -/* values for epdisc.class */ -#define EPD_NULL 0 /* null discriminator, no data */ -#define EPD_LOCAL 1 -#define EPD_IP 2 -#define EPD_MAC 3 -#define EPD_MAGIC 4 -#define EPD_PHONENUM 5 - -/* - * Global variables. - */ -#ifdef HAVE_MULTILINK -extern u8_t multilink; /* enable multilink operation */ -extern u8_t doing_multilink; -extern u8_t multilink_master; -extern u8_t bundle_eof; -extern u8_t bundle_terminating; -#endif - -#ifdef MAXOCTETS -extern unsigned int maxoctets; /* Maximum octetes per session (in bytes) */ -extern int maxoctets_dir; /* Direction : - 0 - in+out (default) - 1 - in - 2 - out - 3 - max(in,out) */ -extern int maxoctets_timeout; /* Timeout for check of octets limit */ -#define PPP_OCTETS_DIRECTION_SUM 0 -#define PPP_OCTETS_DIRECTION_IN 1 -#define PPP_OCTETS_DIRECTION_OUT 2 -#define PPP_OCTETS_DIRECTION_MAXOVERAL 3 -/* same as previos, but little different on RADIUS side */ -#define PPP_OCTETS_DIRECTION_MAXSESSION 4 -#endif - -/* Data input may be used by CCP and ECP, remove this entry - * from struct protent to save some flash - */ -#define PPP_DATAINPUT 0 - -/* - * The following struct gives the addresses of procedures to call - * for a particular protocol. - */ -struct protent { - u_short protocol; /* PPP protocol number */ - /* Initialization procedure */ - void (*init) (ppp_pcb *pcb); - /* Process a received packet */ - void (*input) (ppp_pcb *pcb, u_char *pkt, int len); - /* Process a received protocol-reject */ - void (*protrej) (ppp_pcb *pcb); - /* Lower layer has come up */ - void (*lowerup) (ppp_pcb *pcb); - /* Lower layer has gone down */ - void (*lowerdown) (ppp_pcb *pcb); - /* Open the protocol */ - void (*open) (ppp_pcb *pcb); - /* Close the protocol */ - void (*close) (ppp_pcb *pcb, const char *reason); -#if PRINTPKT_SUPPORT - /* Print a packet in readable form */ - int (*printpkt) (const u_char *pkt, int len, - void (*printer) (void *, const char *, ...), - void *arg); -#endif /* PRINTPKT_SUPPORT */ -#if PPP_DATAINPUT - /* Process a received data packet */ - void (*datainput) (ppp_pcb *pcb, u_char *pkt, int len); -#endif /* PPP_DATAINPUT */ -#if PRINTPKT_SUPPORT - const char *name; /* Text name of protocol */ - const char *data_name; /* Text name of corresponding data protocol */ -#endif /* PRINTPKT_SUPPORT */ -#if PPP_OPTIONS - option_t *options; /* List of command-line options */ - /* Check requested options, assign defaults */ - void (*check_options) (void); -#endif /* PPP_OPTIONS */ -#if DEMAND_SUPPORT - /* Configure interface for demand-dial */ - int (*demand_conf) (int unit); - /* Say whether to bring up link for this pkt */ - int (*active_pkt) (u_char *pkt, int len); -#endif /* DEMAND_SUPPORT */ -}; - -/* Table of pointers to supported protocols */ -extern const struct protent* const protocols[]; - - -/* Values for auth_pending, auth_done */ -#if PAP_SUPPORT -#define PAP_WITHPEER 0x1 -#define PAP_PEER 0x2 -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT -#define CHAP_WITHPEER 0x4 -#define CHAP_PEER 0x8 -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT -#define EAP_WITHPEER 0x10 -#define EAP_PEER 0x20 -#endif /* EAP_SUPPORT */ - -/* Values for auth_done only */ -#if CHAP_SUPPORT -#define CHAP_MD5_WITHPEER 0x40 -#define CHAP_MD5_PEER 0x80 -#if MSCHAP_SUPPORT -#define CHAP_MS_SHIFT 8 /* LSB position for MS auths */ -#define CHAP_MS_WITHPEER 0x100 -#define CHAP_MS_PEER 0x200 -#define CHAP_MS2_WITHPEER 0x400 -#define CHAP_MS2_PEER 0x800 -#endif /* MSCHAP_SUPPORT */ -#endif /* CHAP_SUPPORT */ - -/* Supported CHAP protocols */ -#if CHAP_SUPPORT - -#if MSCHAP_SUPPORT -#define CHAP_MDTYPE_SUPPORTED (MDTYPE_MICROSOFT_V2 | MDTYPE_MICROSOFT | MDTYPE_MD5) -#else /* MSCHAP_SUPPORT */ -#define CHAP_MDTYPE_SUPPORTED (MDTYPE_MD5) -#endif /* MSCHAP_SUPPORT */ - -#else /* CHAP_SUPPORT */ -#define CHAP_MDTYPE_SUPPORTED (MDTYPE_NONE) -#endif /* CHAP_SUPPORT */ - -#if PPP_STATS_SUPPORT -/* - * PPP statistics structure - */ -struct pppd_stats { - unsigned int bytes_in; - unsigned int bytes_out; - unsigned int pkts_in; - unsigned int pkts_out; -}; -#endif /* PPP_STATS_SUPPORT */ - - -/* - * PPP private functions - */ - - -/* - * Functions called from lwIP core. - */ - -/* initialize the PPP subsystem */ -int ppp_init(void); - -/* - * Functions called from PPP link protocols. - */ - -/* Create a new PPP control block */ -ppp_pcb *ppp_new(struct netif *pppif, const struct link_callbacks *callbacks, void *link_ctx_cb, - ppp_link_status_cb_fn link_status_cb, void *ctx_cb); - -/* Initiate LCP open request */ -void ppp_start(ppp_pcb *pcb); - -/* Called when link failed to setup */ -void ppp_link_failed(ppp_pcb *pcb); - -/* Called when link is normally down (i.e. it was asked to end) */ -void ppp_link_end(ppp_pcb *pcb); - -/* function called to process input packet */ -void ppp_input(ppp_pcb *pcb, struct pbuf *pb); - - -/* - * Functions called by PPP protocols. - */ - -/* function called by all PPP subsystems to send packets */ -err_t ppp_write(ppp_pcb *pcb, struct pbuf *p); - -/* functions called by auth.c link_terminated() */ -void ppp_link_terminated(ppp_pcb *pcb); - -void new_phase(ppp_pcb *pcb, int p); - -int ppp_send_config(ppp_pcb *pcb, int mtu, u32_t accm, int pcomp, int accomp); -int ppp_recv_config(ppp_pcb *pcb, int mru, u32_t accm, int pcomp, int accomp); - -#if PPP_IPV4_SUPPORT -int sifaddr(ppp_pcb *pcb, u32_t our_adr, u32_t his_adr, u32_t netmask); -int cifaddr(ppp_pcb *pcb, u32_t our_adr, u32_t his_adr); -#if 0 /* UNUSED - PROXY ARP */ -int sifproxyarp(ppp_pcb *pcb, u32_t his_adr); -int cifproxyarp(ppp_pcb *pcb, u32_t his_adr); -#endif /* UNUSED - PROXY ARP */ -#if LWIP_DNS -int sdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2); -int cdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2); -#endif /* LWIP_DNS */ -#if VJ_SUPPORT -int sifvjcomp(ppp_pcb *pcb, int vjcomp, int cidcomp, int maxcid); -#endif /* VJ_SUPPORT */ -int sifup(ppp_pcb *pcb); -int sifdown (ppp_pcb *pcb); -u32_t get_mask(u32_t addr); -#endif /* PPP_IPV4_SUPPORT */ - -#if PPP_IPV6_SUPPORT -int sif6addr(ppp_pcb *pcb, eui64_t our_eui64, eui64_t his_eui64); -int cif6addr(ppp_pcb *pcb, eui64_t our_eui64, eui64_t his_eui64); -int sif6up(ppp_pcb *pcb); -int sif6down (ppp_pcb *pcb); -#endif /* PPP_IPV6_SUPPORT */ - -#if DEMAND_SUPPORT -int sifnpmode(ppp_pcb *pcb, int proto, enum NPmode mode); -#endif /* DEMAND_SUPPORt */ - -void netif_set_mtu(ppp_pcb *pcb, int mtu); -int netif_get_mtu(ppp_pcb *pcb); - -#if CCP_SUPPORT -#if 0 /* unused */ -int ccp_test(ppp_pcb *pcb, u_char *opt_ptr, int opt_len, int for_transmit); -#endif /* unused */ -void ccp_set(ppp_pcb *pcb, u8_t isopen, u8_t isup, u8_t receive_method, u8_t transmit_method); -void ccp_reset_comp(ppp_pcb *pcb); -void ccp_reset_decomp(ppp_pcb *pcb); -#if 0 /* unused */ -int ccp_fatal_error(ppp_pcb *pcb); -#endif /* unused */ -#endif /* CCP_SUPPORT */ - -#if PPP_IDLETIMELIMIT -int get_idle_time(ppp_pcb *pcb, struct ppp_idle *ip); -#endif /* PPP_IDLETIMELIMIT */ - -#if DEMAND_SUPPORT -int get_loop_output(void); -#endif /* DEMAND_SUPPORT */ - -/* Optional protocol names list, to make our messages a little more informative. */ -#if PPP_PROTOCOLNAME -const char * protocol_name(int proto); -#endif /* PPP_PROTOCOLNAME */ - -/* Optional stats support, to get some statistics on the PPP interface */ -#if PPP_STATS_SUPPORT -void print_link_stats(void); /* Print stats, if available */ -void reset_link_stats(int u); /* Reset (init) stats when link goes up */ -void update_link_stats(int u); /* Get stats at link termination */ -#endif /* PPP_STATS_SUPPORT */ - - - -/* - * Inline versions of get/put char/short/long. - * Pointer is advanced; we assume that both arguments - * are lvalues and will already be in registers. - * cp MUST be u_char *. - */ -#define GETCHAR(c, cp) { \ - (c) = *(cp)++; \ -} -#define PUTCHAR(c, cp) { \ - *(cp)++ = (u_char) (c); \ -} -#define GETSHORT(s, cp) { \ - (s) = *(cp)++ << 8; \ - (s) |= *(cp)++; \ -} -#define PUTSHORT(s, cp) { \ - *(cp)++ = (u_char) ((s) >> 8); \ - *(cp)++ = (u_char) (s); \ -} -#define GETLONG(l, cp) { \ - (l) = *(cp)++ << 8; \ - (l) |= *(cp)++; (l) <<= 8; \ - (l) |= *(cp)++; (l) <<= 8; \ - (l) |= *(cp)++; \ -} -#define PUTLONG(l, cp) { \ - *(cp)++ = (u_char) ((l) >> 24); \ - *(cp)++ = (u_char) ((l) >> 16); \ - *(cp)++ = (u_char) ((l) >> 8); \ - *(cp)++ = (u_char) (l); \ -} - -#define INCPTR(n, cp) ((cp) += (n)) -#define DECPTR(n, cp) ((cp) -= (n)) - -/* - * System dependent definitions for user-level 4.3BSD UNIX implementation. - */ -#define TIMEOUT(f, a, t) do { sys_untimeout((f), (a)); sys_timeout((t)*1000, (f), (a)); } while(0) -#define TIMEOUTMS(f, a, t) do { sys_untimeout((f), (a)); sys_timeout((t), (f), (a)); } while(0) -#define UNTIMEOUT(f, a) sys_untimeout((f), (a)) - -#define BZERO(s, n) memset(s, 0, n) -#define BCMP(s1, s2, l) memcmp(s1, s2, l) - -#define PRINTMSG(m, l) { ppp_info("Remote message: %0.*v", l, m); } - -/* - * MAKEHEADER - Add Header fields to a packet. - */ -#define MAKEHEADER(p, t) { \ - PUTCHAR(PPP_ALLSTATIONS, p); \ - PUTCHAR(PPP_UI, p); \ - PUTSHORT(t, p); } - -/* Procedures exported from auth.c */ -void link_required(ppp_pcb *pcb); /* we are starting to use the link */ -void link_terminated(ppp_pcb *pcb); /* we are finished with the link */ -void link_down(ppp_pcb *pcb); /* the LCP layer has left the Opened state */ -void upper_layers_down(ppp_pcb *pcb); /* take all NCPs down */ -void link_established(ppp_pcb *pcb); /* the link is up; authenticate now */ -void start_networks(ppp_pcb *pcb); /* start all the network control protos */ -void continue_networks(ppp_pcb *pcb); /* start network [ip, etc] control protos */ -#if PPP_AUTH_SUPPORT -#if PPP_SERVER -int auth_check_passwd(ppp_pcb *pcb, char *auser, int userlen, char *apasswd, int passwdlen, const char **msg, int *msglen); - /* check the user name and passwd against configuration */ -void auth_peer_fail(ppp_pcb *pcb, int protocol); - /* peer failed to authenticate itself */ -void auth_peer_success(ppp_pcb *pcb, int protocol, int prot_flavor, const char *name, int namelen); - /* peer successfully authenticated itself */ -#endif /* PPP_SERVER */ -void auth_withpeer_fail(ppp_pcb *pcb, int protocol); - /* we failed to authenticate ourselves */ -void auth_withpeer_success(ppp_pcb *pcb, int protocol, int prot_flavor); - /* we successfully authenticated ourselves */ -#endif /* PPP_AUTH_SUPPORT */ -void np_up(ppp_pcb *pcb, int proto); /* a network protocol has come up */ -void np_down(ppp_pcb *pcb, int proto); /* a network protocol has gone down */ -void np_finished(ppp_pcb *pcb, int proto); /* a network protocol no longer needs link */ -#if PPP_AUTH_SUPPORT -int get_secret(ppp_pcb *pcb, const char *client, const char *server, char *secret, int *secret_len, int am_server); - /* get "secret" for chap */ -#endif /* PPP_AUTH_SUPPORT */ - -/* Procedures exported from ipcp.c */ -/* int parse_dotted_ip (char *, u32_t *); */ - -/* Procedures exported from demand.c */ -#if DEMAND_SUPPORT -void demand_conf (void); /* config interface(s) for demand-dial */ -void demand_block (void); /* set all NPs to queue up packets */ -void demand_unblock (void); /* set all NPs to pass packets */ -void demand_discard (void); /* set all NPs to discard packets */ -void demand_rexmit (int, u32_t); /* retransmit saved frames for an NP*/ -int loop_chars (unsigned char *, int); /* process chars from loopback */ -int loop_frame (unsigned char *, int); /* should we bring link up? */ -#endif /* DEMAND_SUPPORT */ - -/* Procedures exported from multilink.c */ -#ifdef HAVE_MULTILINK -void mp_check_options (void); /* Check multilink-related options */ -int mp_join_bundle (void); /* join our link to an appropriate bundle */ -void mp_exit_bundle (void); /* have disconnected our link from bundle */ -void mp_bundle_terminated (void); -char *epdisc_to_str (struct epdisc *); /* string from endpoint discrim. */ -int str_to_epdisc (struct epdisc *, char *); /* endpt disc. from str */ -#else -#define mp_bundle_terminated() /* nothing */ -#define mp_exit_bundle() /* nothing */ -#define doing_multilink 0 -#define multilink_master 0 -#endif - -/* Procedures exported from utils.c. */ -void ppp_print_string(const u_char *p, int len, void (*printer) (void *, const char *, ...), void *arg); /* Format a string for output */ -int ppp_slprintf(char *buf, int buflen, const char *fmt, ...); /* sprintf++ */ -int ppp_vslprintf(char *buf, int buflen, const char *fmt, va_list args); /* vsprintf++ */ -size_t ppp_strlcpy(char *dest, const char *src, size_t len); /* safe strcpy */ -size_t ppp_strlcat(char *dest, const char *src, size_t len); /* safe strncpy */ -void ppp_dbglog(const char *fmt, ...); /* log a debug message */ -void ppp_info(const char *fmt, ...); /* log an informational message */ -void ppp_notice(const char *fmt, ...); /* log a notice-level message */ -void ppp_warn(const char *fmt, ...); /* log a warning message */ -void ppp_error(const char *fmt, ...); /* log an error message */ -void ppp_fatal(const char *fmt, ...); /* log an error message and die(1) */ -#if PRINTPKT_SUPPORT -void ppp_dump_packet(ppp_pcb *pcb, const char *tag, unsigned char *p, int len); - /* dump packet to debug log if interesting */ -#endif /* PRINTPKT_SUPPORT */ - -/* - * Number of necessary timers analysis. - * - * PPP use at least one timer per each of its protocol, but not all protocols are - * active at the same time, thus the number of necessary timeouts is actually - * lower than enabled protocols. Here is the actual necessary timeouts based - * on code analysis. - * - * Note that many features analysed here are not working at all and are only - * there for a comprehensive analysis of necessary timers in order to prevent - * having to redo that each time we add a feature. - * - * Timer list - * - * | holdoff timeout - * | low level protocol timeout (PPPoE or PPPoL2P) - * | LCP delayed UP - * | LCP retransmit (FSM) - * | LCP Echo timer - * .| PAP or CHAP or EAP authentication - * . | ECP retransmit (FSM) - * . | CCP retransmit (FSM) when MPPE is enabled - * . | CCP retransmit (FSM) when MPPE is NOT enabled - * . | IPCP retransmit (FSM) - * . .| IP6CP retransmit (FSM) - * . . | Idle time limit - * . . | Max connect time - * . . | Max octets - * . . | CCP RACK timeout - * . . . - * PPP_PHASE_DEAD - * PPP_PHASE_HOLDOFF - * | . . . - * PPP_PHASE_INITIALIZE - * | . . . - * PPP_PHASE_ESTABLISH - * | . . . - * |. . . - * | . . - * PPP_PHASE_AUTHENTICATE - * | . . - * || . . - * PPP_PHASE_NETWORK - * | || . . - * | ||| . - * PPP_PHASE_RUNNING - * | .||||| - * | . |||| - * PPP_PHASE_TERMINATE - * | . |||| - * PPP_PHASE_NETWORK - * |. . - * PPP_PHASE_ESTABLISH - * PPP_PHASE_DISCONNECT - * PPP_PHASE_DEAD - * - * Alright, PPP basic retransmission and LCP Echo consume one timer. - * 1 - * - * If authentication is enabled one timer is necessary during authentication. - * 1 + PPP_AUTH_SUPPORT - * - * If ECP is enabled one timer is necessary before IPCP and/or IP6CP, one more - * is necessary if CCP is enabled (only with MPPE support but we don't care much - * up to this detail level). - * 1 + ECP_SUPPORT + CCP_SUPPORT - * - * If CCP is enabled it might consume a timer during IPCP or IP6CP, thus - * we might use IPCP, IP6CP and CCP timers simultaneously. - * 1 + PPP_IPV4_SUPPORT + PPP_IPV6_SUPPORT + CCP_SUPPORT - * - * When entering running phase, IPCP or IP6CP is still running. If idle time limit - * is enabled one more timer is necessary. Same for max connect time and max - * octets features. Furthermore CCP RACK might be used past this point. - * 1 + PPP_IPV4_SUPPORT + PPP_IPV6_SUPPORT -1 + PPP_IDLETIMELIMIT + PPP_MAXCONNECT + MAXOCTETS + CCP_SUPPORT - * - * IPv4 or IPv6 must be enabled, therefore we don't need to take care the authentication - * and the CCP + ECP case, thus reducing overall complexity. - * 1 + LWIP_MAX(PPP_IPV4_SUPPORT + PPP_IPV6_SUPPORT + CCP_SUPPORT, PPP_IPV4_SUPPORT + PPP_IPV6_SUPPORT -1 + PPP_IDLETIMELIMIT + PPP_MAXCONNECT + MAXOCTETS + CCP_SUPPORT) - * - * We don't support PPP_IDLETIMELIMIT + PPP_MAXCONNECT + MAXOCTETS features - * and adding those defines to ppp_opts.h just for having the value always - * defined to 0 isn't worth it. - * 1 + LWIP_MAX(PPP_IPV4_SUPPORT + PPP_IPV6_SUPPORT + CCP_SUPPORT, PPP_IPV4_SUPPORT + PPP_IPV6_SUPPORT -1 + CCP_SUPPORT) - * - * Thus, the following is enough for now. - * 1 + PPP_IPV4_SUPPORT + PPP_IPV6_SUPPORT + CCP_SUPPORT - */ - -#ifdef __cplusplus -} -#endif - -#endif /* PPP_SUPPORT */ -#endif /* LWIP_HDR_PPP_IMPL_H */ diff --git a/third-party/lwip-2.1.2/include/netif/ppp/ppp_opts.h b/third-party/lwip-2.1.2/include/netif/ppp/ppp_opts.h deleted file mode 100644 index 6702bec6..00000000 --- a/third-party/lwip-2.1.2/include/netif/ppp/ppp_opts.h +++ /dev/null @@ -1,610 +0,0 @@ -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#ifndef LWIP_PPP_OPTS_H -#define LWIP_PPP_OPTS_H - -#include "lwip/opt.h" - -/** - * PPP_SUPPORT==1: Enable PPP. - */ -#ifndef PPP_SUPPORT -#define PPP_SUPPORT 0 -#endif - -/** - * PPPOE_SUPPORT==1: Enable PPP Over Ethernet - */ -#ifndef PPPOE_SUPPORT -#define PPPOE_SUPPORT 0 -#endif - -/** - * PPPOL2TP_SUPPORT==1: Enable PPP Over L2TP - */ -#ifndef PPPOL2TP_SUPPORT -#define PPPOL2TP_SUPPORT 0 -#endif - -/** - * PPPOL2TP_AUTH_SUPPORT==1: Enable PPP Over L2TP Auth (enable MD5 support) - */ -#ifndef PPPOL2TP_AUTH_SUPPORT -#define PPPOL2TP_AUTH_SUPPORT PPPOL2TP_SUPPORT -#endif - -/** - * PPPOS_SUPPORT==1: Enable PPP Over Serial - */ -#ifndef PPPOS_SUPPORT -#define PPPOS_SUPPORT PPP_SUPPORT -#endif - -/** - * LWIP_PPP_API==1: Enable PPP API (in pppapi.c) - */ -#ifndef LWIP_PPP_API -#define LWIP_PPP_API (PPP_SUPPORT && (NO_SYS == 0)) -#endif - -#if PPP_SUPPORT - -/** - * MEMP_NUM_PPP_PCB: the number of simultaneously active PPP - * connections (requires the PPP_SUPPORT option) - */ -#ifndef MEMP_NUM_PPP_PCB -#define MEMP_NUM_PPP_PCB 1 -#endif - -/** - * PPP_NUM_TIMEOUTS_PER_PCB: the number of sys_timeouts running in parallel per - * ppp_pcb. See the detailed explanation at the end of ppp_impl.h about simultaneous - * timers analysis. - */ -#ifndef PPP_NUM_TIMEOUTS_PER_PCB -#define PPP_NUM_TIMEOUTS_PER_PCB (1 + PPP_IPV4_SUPPORT + PPP_IPV6_SUPPORT + CCP_SUPPORT) -#endif - -/* The number of sys_timeouts required for the PPP module */ -#define PPP_NUM_TIMEOUTS (PPP_SUPPORT * PPP_NUM_TIMEOUTS_PER_PCB * MEMP_NUM_PPP_PCB) - -/** - * MEMP_NUM_PPPOS_INTERFACES: the number of concurrently active PPPoS - * interfaces (only used with PPPOS_SUPPORT==1) - */ -#ifndef MEMP_NUM_PPPOS_INTERFACES -#define MEMP_NUM_PPPOS_INTERFACES MEMP_NUM_PPP_PCB -#endif - -/** - * MEMP_NUM_PPPOE_INTERFACES: the number of concurrently active PPPoE - * interfaces (only used with PPPOE_SUPPORT==1) - */ -#ifndef MEMP_NUM_PPPOE_INTERFACES -#define MEMP_NUM_PPPOE_INTERFACES 1 -#endif - -/** - * MEMP_NUM_PPPOL2TP_INTERFACES: the number of concurrently active PPPoL2TP - * interfaces (only used with PPPOL2TP_SUPPORT==1) - */ -#ifndef MEMP_NUM_PPPOL2TP_INTERFACES -#define MEMP_NUM_PPPOL2TP_INTERFACES 1 -#endif - -/** - * MEMP_NUM_PPP_API_MSG: Number of concurrent PPP API messages (in pppapi.c) - */ -#ifndef MEMP_NUM_PPP_API_MSG -#define MEMP_NUM_PPP_API_MSG 5 -#endif - -/** - * PPP_DEBUG: Enable debugging for PPP. - */ -#ifndef PPP_DEBUG -#define PPP_DEBUG LWIP_DBG_OFF -#endif - -/** - * PPP_INPROC_IRQ_SAFE==1 call pppos_input() using tcpip_callback(). - * - * Please read the "PPPoS input path" chapter in the PPP documentation about this option. - */ -#ifndef PPP_INPROC_IRQ_SAFE -#define PPP_INPROC_IRQ_SAFE 0 -#endif - -/** - * PRINTPKT_SUPPORT==1: Enable PPP print packet support - * - * Mandatory for debugging, it displays exchanged packet content in debug trace. - */ -#ifndef PRINTPKT_SUPPORT -#define PRINTPKT_SUPPORT 0 -#endif - -/** - * PPP_IPV4_SUPPORT==1: Enable PPP IPv4 support - */ -#ifndef PPP_IPV4_SUPPORT -#define PPP_IPV4_SUPPORT (LWIP_IPV4) -#endif - -/** - * PPP_IPV6_SUPPORT==1: Enable PPP IPv6 support - */ -#ifndef PPP_IPV6_SUPPORT -#define PPP_IPV6_SUPPORT (LWIP_IPV6) -#endif - -/** - * PPP_NOTIFY_PHASE==1: Support PPP notify phase support - * - * PPP notify phase support allows you to set a callback which is - * called on change of the internal PPP state machine. - * - * This can be used for example to set a LED pattern depending on the - * current phase of the PPP session. - */ -#ifndef PPP_NOTIFY_PHASE -#define PPP_NOTIFY_PHASE 0 -#endif - -/** - * pbuf_type PPP is using for LCP, PAP, CHAP, EAP, CCP, IPCP and IP6CP packets. - * - * Memory allocated must be single buffered for PPP to works, it requires pbuf - * that are not going to be chained when allocated. This requires setting - * PBUF_POOL_BUFSIZE to at least 512 bytes, which is quite huge for small systems. - * - * Setting PPP_USE_PBUF_RAM to 1 makes PPP use memory from heap where continuous - * buffers are required, allowing you to use a smaller PBUF_POOL_BUFSIZE. - */ -#ifndef PPP_USE_PBUF_RAM -#define PPP_USE_PBUF_RAM 0 -#endif - -/** - * PPP_FCS_TABLE: Keep a 256*2 byte table to speed up FCS calculation for PPPoS - */ -#ifndef PPP_FCS_TABLE -#define PPP_FCS_TABLE 1 -#endif - -/** - * PAP_SUPPORT==1: Support PAP. - */ -#ifndef PAP_SUPPORT -#define PAP_SUPPORT 0 -#endif - -/** - * CHAP_SUPPORT==1: Support CHAP. - */ -#ifndef CHAP_SUPPORT -#define CHAP_SUPPORT 0 -#endif - -/** - * MSCHAP_SUPPORT==1: Support MSCHAP. - */ -#ifndef MSCHAP_SUPPORT -#define MSCHAP_SUPPORT 0 -#endif -#if MSCHAP_SUPPORT -/* MSCHAP requires CHAP support */ -#undef CHAP_SUPPORT -#define CHAP_SUPPORT 1 -#endif /* MSCHAP_SUPPORT */ - -/** - * EAP_SUPPORT==1: Support EAP. - */ -#ifndef EAP_SUPPORT -#define EAP_SUPPORT 0 -#endif - -/** - * CCP_SUPPORT==1: Support CCP. - */ -#ifndef CCP_SUPPORT -#define CCP_SUPPORT 0 -#endif - -/** - * MPPE_SUPPORT==1: Support MPPE. - */ -#ifndef MPPE_SUPPORT -#define MPPE_SUPPORT 0 -#endif -#if MPPE_SUPPORT -/* MPPE requires CCP support */ -#undef CCP_SUPPORT -#define CCP_SUPPORT 1 -/* MPPE requires MSCHAP support */ -#undef MSCHAP_SUPPORT -#define MSCHAP_SUPPORT 1 -/* MSCHAP requires CHAP support */ -#undef CHAP_SUPPORT -#define CHAP_SUPPORT 1 -#endif /* MPPE_SUPPORT */ - -/** - * CBCP_SUPPORT==1: Support CBCP. CURRENTLY NOT SUPPORTED! DO NOT SET! - */ -#ifndef CBCP_SUPPORT -#define CBCP_SUPPORT 0 -#endif - -/** - * ECP_SUPPORT==1: Support ECP. CURRENTLY NOT SUPPORTED! DO NOT SET! - */ -#ifndef ECP_SUPPORT -#define ECP_SUPPORT 0 -#endif - -/** - * DEMAND_SUPPORT==1: Support dial on demand. CURRENTLY NOT SUPPORTED! DO NOT SET! - */ -#ifndef DEMAND_SUPPORT -#define DEMAND_SUPPORT 0 -#endif - -/** - * LQR_SUPPORT==1: Support Link Quality Report. Do nothing except exchanging some LCP packets. - */ -#ifndef LQR_SUPPORT -#define LQR_SUPPORT 0 -#endif - -/** - * PPP_SERVER==1: Enable PPP server support (waiting for incoming PPP session). - * - * Currently only supported for PPPoS. - */ -#ifndef PPP_SERVER -#define PPP_SERVER 0 -#endif - -#if PPP_SERVER -/* - * PPP_OUR_NAME: Our name for authentication purposes - */ -#ifndef PPP_OUR_NAME -#define PPP_OUR_NAME "lwIP" -#endif -#endif /* PPP_SERVER */ - -/** - * VJ_SUPPORT==1: Support VJ header compression. - */ -#ifndef VJ_SUPPORT -#define VJ_SUPPORT 1 -#endif -/* VJ compression is only supported for TCP over IPv4 over PPPoS. */ -#if !PPPOS_SUPPORT || !PPP_IPV4_SUPPORT || !LWIP_TCP -#undef VJ_SUPPORT -#define VJ_SUPPORT 0 -#endif /* !PPPOS_SUPPORT */ - -/** - * PPP_MD5_RANDM==1: Use MD5 for better randomness. - * Enabled by default if CHAP, EAP, or L2TP AUTH support is enabled. - */ -#ifndef PPP_MD5_RANDM -#define PPP_MD5_RANDM (CHAP_SUPPORT || EAP_SUPPORT || PPPOL2TP_AUTH_SUPPORT) -#endif - -/** - * PolarSSL embedded library - * - * - * lwIP contains some files fetched from the latest BSD release of - * the PolarSSL project (PolarSSL 0.10.1-bsd) for ciphers and encryption - * methods we need for lwIP PPP support. - * - * The PolarSSL files were cleaned to contain only the necessary struct - * fields and functions needed for lwIP. - * - * The PolarSSL API was not changed at all, so if you are already using - * PolarSSL you can choose to skip the compilation of the included PolarSSL - * library into lwIP. - * - * If you are not using the embedded copy you must include external - * libraries into your arch/cc.h port file. - * - * Beware of the stack requirements which can be a lot larger if you are not - * using our cleaned PolarSSL library. - */ - -/** - * LWIP_USE_EXTERNAL_POLARSSL: Use external PolarSSL library - */ -#ifndef LWIP_USE_EXTERNAL_POLARSSL -#define LWIP_USE_EXTERNAL_POLARSSL 0 -#endif - -/** - * LWIP_USE_EXTERNAL_MBEDTLS: Use external mbed TLS library - */ -#ifndef LWIP_USE_EXTERNAL_MBEDTLS -#define LWIP_USE_EXTERNAL_MBEDTLS 0 -#endif - -/* - * PPP Timeouts - */ - -/** - * FSM_DEFTIMEOUT: Timeout time in seconds - */ -#ifndef FSM_DEFTIMEOUT -#define FSM_DEFTIMEOUT 6 -#endif - -/** - * FSM_DEFMAXTERMREQS: Maximum Terminate-Request transmissions - */ -#ifndef FSM_DEFMAXTERMREQS -#define FSM_DEFMAXTERMREQS 2 -#endif - -/** - * FSM_DEFMAXCONFREQS: Maximum Configure-Request transmissions - */ -#ifndef FSM_DEFMAXCONFREQS -#define FSM_DEFMAXCONFREQS 10 -#endif - -/** - * FSM_DEFMAXNAKLOOPS: Maximum number of nak loops - */ -#ifndef FSM_DEFMAXNAKLOOPS -#define FSM_DEFMAXNAKLOOPS 5 -#endif - -/** - * UPAP_DEFTIMEOUT: Timeout (seconds) for retransmitting req - */ -#ifndef UPAP_DEFTIMEOUT -#define UPAP_DEFTIMEOUT 6 -#endif - -/** - * UPAP_DEFTRANSMITS: Maximum number of auth-reqs to send - */ -#ifndef UPAP_DEFTRANSMITS -#define UPAP_DEFTRANSMITS 10 -#endif - -#if PPP_SERVER -/** - * UPAP_DEFREQTIME: Time to wait for auth-req from peer - */ -#ifndef UPAP_DEFREQTIME -#define UPAP_DEFREQTIME 30 -#endif -#endif /* PPP_SERVER */ - -/** - * CHAP_DEFTIMEOUT: Timeout (seconds) for retransmitting req - */ -#ifndef CHAP_DEFTIMEOUT -#define CHAP_DEFTIMEOUT 6 -#endif - -/** - * CHAP_DEFTRANSMITS: max # times to send challenge - */ -#ifndef CHAP_DEFTRANSMITS -#define CHAP_DEFTRANSMITS 10 -#endif - -#if PPP_SERVER -/** - * CHAP_DEFRECHALLENGETIME: If this option is > 0, rechallenge the peer every n seconds - */ -#ifndef CHAP_DEFRECHALLENGETIME -#define CHAP_DEFRECHALLENGETIME 0 -#endif -#endif /* PPP_SERVER */ - -/** - * EAP_DEFREQTIME: Time to wait for peer request - */ -#ifndef EAP_DEFREQTIME -#define EAP_DEFREQTIME 6 -#endif - -/** - * EAP_DEFALLOWREQ: max # times to accept requests - */ -#ifndef EAP_DEFALLOWREQ -#define EAP_DEFALLOWREQ 10 -#endif - -#if PPP_SERVER -/** - * EAP_DEFTIMEOUT: Timeout (seconds) for rexmit - */ -#ifndef EAP_DEFTIMEOUT -#define EAP_DEFTIMEOUT 6 -#endif - -/** - * EAP_DEFTRANSMITS: max # times to transmit - */ -#ifndef EAP_DEFTRANSMITS -#define EAP_DEFTRANSMITS 10 -#endif -#endif /* PPP_SERVER */ - -/** - * LCP_DEFLOOPBACKFAIL: Default number of times we receive our magic number from the peer - * before deciding the link is looped-back. - */ -#ifndef LCP_DEFLOOPBACKFAIL -#define LCP_DEFLOOPBACKFAIL 10 -#endif - -/** - * LCP_ECHOINTERVAL: Interval in seconds between keepalive echo requests, 0 to disable. - */ -#ifndef LCP_ECHOINTERVAL -#define LCP_ECHOINTERVAL 0 -#endif - -/** - * LCP_MAXECHOFAILS: Number of unanswered echo requests before failure. - */ -#ifndef LCP_MAXECHOFAILS -#define LCP_MAXECHOFAILS 3 -#endif - -/** - * PPP_MAXIDLEFLAG: Max Xmit idle time (in ms) before resend flag char. - */ -#ifndef PPP_MAXIDLEFLAG -#define PPP_MAXIDLEFLAG 100 -#endif - -/** - * PPP Packet sizes - */ - -/** - * PPP_MRU: Default MRU - */ -#ifndef PPP_MRU -#define PPP_MRU 1500 -#endif - -/** - * PPP_DEFMRU: Default MRU to try - */ -#ifndef PPP_DEFMRU -#define PPP_DEFMRU 1500 -#endif - -/** - * PPP_MAXMRU: Normally limit MRU to this (pppd default = 16384) - */ -#ifndef PPP_MAXMRU -#define PPP_MAXMRU 1500 -#endif - -/** - * PPP_MINMRU: No MRUs below this - */ -#ifndef PPP_MINMRU -#define PPP_MINMRU 128 -#endif - -/** - * PPPOL2TP_DEFMRU: Default MTU and MRU for L2TP - * Default = 1500 - PPPoE(6) - PPP Protocol(2) - IPv4 header(20) - UDP Header(8) - * - L2TP Header(6) - HDLC Header(2) - PPP Protocol(2) - MPPE Header(2) - PPP Protocol(2) - */ -#if PPPOL2TP_SUPPORT -#ifndef PPPOL2TP_DEFMRU -#define PPPOL2TP_DEFMRU 1450 -#endif -#endif /* PPPOL2TP_SUPPORT */ - -/** - * MAXNAMELEN: max length of hostname or name for auth - */ -#ifndef MAXNAMELEN -#define MAXNAMELEN 256 -#endif - -/** - * MAXSECRETLEN: max length of password or secret - */ -#ifndef MAXSECRETLEN -#define MAXSECRETLEN 256 -#endif - -/* ------------------------------------------------------------------------- */ - -/* - * Build triggers for embedded PolarSSL - */ -#if !LWIP_USE_EXTERNAL_POLARSSL && !LWIP_USE_EXTERNAL_MBEDTLS - -/* CHAP, EAP, L2TP AUTH and MD5 Random require MD5 support */ -#if CHAP_SUPPORT || EAP_SUPPORT || PPPOL2TP_AUTH_SUPPORT || PPP_MD5_RANDM -#define LWIP_INCLUDED_POLARSSL_MD5 1 -#endif /* CHAP_SUPPORT || EAP_SUPPORT || PPPOL2TP_AUTH_SUPPORT || PPP_MD5_RANDM */ - -#if MSCHAP_SUPPORT - -/* MSCHAP require MD4 support */ -#define LWIP_INCLUDED_POLARSSL_MD4 1 -/* MSCHAP require SHA1 support */ -#define LWIP_INCLUDED_POLARSSL_SHA1 1 -/* MSCHAP require DES support */ -#define LWIP_INCLUDED_POLARSSL_DES 1 - -/* MS-CHAP support is required for MPPE */ -#if MPPE_SUPPORT -/* MPPE require ARC4 support */ -#define LWIP_INCLUDED_POLARSSL_ARC4 1 -#endif /* MPPE_SUPPORT */ - -#endif /* MSCHAP_SUPPORT */ - -#endif /* !LWIP_USE_EXTERNAL_POLARSSL && !LWIP_USE_EXTERNAL_MBEDTLS */ - -/* Default value if unset */ -#ifndef LWIP_INCLUDED_POLARSSL_MD4 -#define LWIP_INCLUDED_POLARSSL_MD4 0 -#endif /* LWIP_INCLUDED_POLARSSL_MD4 */ -#ifndef LWIP_INCLUDED_POLARSSL_MD5 -#define LWIP_INCLUDED_POLARSSL_MD5 0 -#endif /* LWIP_INCLUDED_POLARSSL_MD5 */ -#ifndef LWIP_INCLUDED_POLARSSL_SHA1 -#define LWIP_INCLUDED_POLARSSL_SHA1 0 -#endif /* LWIP_INCLUDED_POLARSSL_SHA1 */ -#ifndef LWIP_INCLUDED_POLARSSL_DES -#define LWIP_INCLUDED_POLARSSL_DES 0 -#endif /* LWIP_INCLUDED_POLARSSL_DES */ -#ifndef LWIP_INCLUDED_POLARSSL_ARC4 -#define LWIP_INCLUDED_POLARSSL_ARC4 0 -#endif /* LWIP_INCLUDED_POLARSSL_ARC4 */ - -#endif /* PPP_SUPPORT */ - -/* Default value if unset */ -#ifndef PPP_NUM_TIMEOUTS -#define PPP_NUM_TIMEOUTS 0 -#endif /* PPP_NUM_TIMEOUTS */ - -#endif /* LWIP_PPP_OPTS_H */ diff --git a/third-party/lwip-2.1.2/include/netif/ppp/pppapi.h b/third-party/lwip-2.1.2/include/netif/ppp/pppapi.h deleted file mode 100644 index 913d93f7..00000000 --- a/third-party/lwip-2.1.2/include/netif/ppp/pppapi.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#ifndef LWIP_PPPAPI_H -#define LWIP_PPPAPI_H - -#include "netif/ppp/ppp_opts.h" - -#if LWIP_PPP_API /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/sys.h" -#include "lwip/netif.h" -#include "lwip/priv/tcpip_priv.h" -#include "netif/ppp/ppp.h" -#if PPPOS_SUPPORT -#include "netif/ppp/pppos.h" -#endif /* PPPOS_SUPPORT */ - -#ifdef __cplusplus -extern "C" { -#endif - -struct pppapi_msg_msg { - ppp_pcb *ppp; - union { -#if PPP_NOTIFY_PHASE - struct { - ppp_notify_phase_cb_fn notify_phase_cb; - } setnotifyphasecb; -#endif /* PPP_NOTIFY_PHASE */ -#if PPPOS_SUPPORT - struct { - struct netif *pppif; - pppos_output_cb_fn output_cb; - ppp_link_status_cb_fn link_status_cb; - void *ctx_cb; - } serialcreate; -#endif /* PPPOS_SUPPORT */ -#if PPPOE_SUPPORT - struct { - struct netif *pppif; - struct netif *ethif; - const char *service_name; - const char *concentrator_name; - ppp_link_status_cb_fn link_status_cb; - void *ctx_cb; - } ethernetcreate; -#endif /* PPPOE_SUPPORT */ -#if PPPOL2TP_SUPPORT - struct { - struct netif *pppif; - struct netif *netif; - API_MSG_M_DEF_C(ip_addr_t, ipaddr); - u16_t port; -#if PPPOL2TP_AUTH_SUPPORT - const u8_t *secret; - u8_t secret_len; -#endif /* PPPOL2TP_AUTH_SUPPORT */ - ppp_link_status_cb_fn link_status_cb; - void *ctx_cb; - } l2tpcreate; -#endif /* PPPOL2TP_SUPPORT */ - struct { - u16_t holdoff; - } connect; - struct { - u8_t nocarrier; - } close; - struct { - u8_t cmd; - void *arg; - } ioctl; - } msg; -}; - -struct pppapi_msg { - struct tcpip_api_call_data call; - struct pppapi_msg_msg msg; -}; - -/* API for application */ -err_t pppapi_set_default(ppp_pcb *pcb); -#if PPP_NOTIFY_PHASE -err_t pppapi_set_notify_phase_callback(ppp_pcb *pcb, ppp_notify_phase_cb_fn notify_phase_cb); -#endif /* PPP_NOTIFY_PHASE */ -#if PPPOS_SUPPORT -ppp_pcb *pppapi_pppos_create(struct netif *pppif, pppos_output_cb_fn output_cb, ppp_link_status_cb_fn link_status_cb, void *ctx_cb); -#endif /* PPPOS_SUPPORT */ -#if PPPOE_SUPPORT -ppp_pcb *pppapi_pppoe_create(struct netif *pppif, struct netif *ethif, const char *service_name, - const char *concentrator_name, ppp_link_status_cb_fn link_status_cb, - void *ctx_cb); -#endif /* PPPOE_SUPPORT */ -#if PPPOL2TP_SUPPORT -ppp_pcb *pppapi_pppol2tp_create(struct netif *pppif, struct netif *netif, ip_addr_t *ipaddr, u16_t port, - const u8_t *secret, u8_t secret_len, - ppp_link_status_cb_fn link_status_cb, void *ctx_cb); -#endif /* PPPOL2TP_SUPPORT */ -err_t pppapi_connect(ppp_pcb *pcb, u16_t holdoff); -#if PPP_SERVER -err_t pppapi_listen(ppp_pcb *pcb); -#endif /* PPP_SERVER */ -err_t pppapi_close(ppp_pcb *pcb, u8_t nocarrier); -err_t pppapi_free(ppp_pcb *pcb); -err_t pppapi_ioctl(ppp_pcb *pcb, u8_t cmd, void *arg); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_PPP_API */ - -#endif /* LWIP_PPPAPI_H */ diff --git a/third-party/lwip-2.1.2/include/netif/ppp/pppcrypt.h b/third-party/lwip-2.1.2/include/netif/ppp/pppcrypt.h deleted file mode 100644 index c0230bbc..00000000 --- a/third-party/lwip-2.1.2/include/netif/ppp/pppcrypt.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * pppcrypt.c - PPP/DES linkage for MS-CHAP and EAP SRP-SHA1 - * - * Extracted from chap_ms.c by James Carlson. - * - * Copyright (c) 1995 Eric Rosenquist. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -/* This header file is included in all PPP modules needing hashes and/or ciphers */ - -#ifndef PPPCRYPT_H -#define PPPCRYPT_H - -/* - * If included PolarSSL copy is not used, user is expected to include - * external libraries in arch/cc.h (which is included by lwip/arch.h). - */ -#include "lwip/arch.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Map hashes and ciphers functions to PolarSSL - */ -#if !LWIP_USE_EXTERNAL_MBEDTLS - -#include "netif/ppp/polarssl/md4.h" -#define lwip_md4_context md4_context -#define lwip_md4_init(context) -#define lwip_md4_starts md4_starts -#define lwip_md4_update md4_update -#define lwip_md4_finish md4_finish -#define lwip_md4_free(context) - -#include "netif/ppp/polarssl/md5.h" -#define lwip_md5_context md5_context -#define lwip_md5_init(context) -#define lwip_md5_starts md5_starts -#define lwip_md5_update md5_update -#define lwip_md5_finish md5_finish -#define lwip_md5_free(context) - -#include "netif/ppp/polarssl/sha1.h" -#define lwip_sha1_context sha1_context -#define lwip_sha1_init(context) -#define lwip_sha1_starts sha1_starts -#define lwip_sha1_update sha1_update -#define lwip_sha1_finish sha1_finish -#define lwip_sha1_free(context) - -#include "netif/ppp/polarssl/des.h" -#define lwip_des_context des_context -#define lwip_des_init(context) -#define lwip_des_setkey_enc des_setkey_enc -#define lwip_des_crypt_ecb des_crypt_ecb -#define lwip_des_free(context) - -#include "netif/ppp/polarssl/arc4.h" -#define lwip_arc4_context arc4_context -#define lwip_arc4_init(context) -#define lwip_arc4_setup arc4_setup -#define lwip_arc4_crypt arc4_crypt -#define lwip_arc4_free(context) - -#endif /* !LWIP_USE_EXTERNAL_MBEDTLS */ - -/* - * Map hashes and ciphers functions to mbed TLS - */ -#if LWIP_USE_EXTERNAL_MBEDTLS - -#define lwip_md4_context mbedtls_md4_context -#define lwip_md4_init mbedtls_md4_init -#define lwip_md4_starts mbedtls_md4_starts -#define lwip_md4_update mbedtls_md4_update -#define lwip_md4_finish mbedtls_md4_finish -#define lwip_md4_free mbedtls_md4_free - -#define lwip_md5_context mbedtls_md5_context -#define lwip_md5_init mbedtls_md5_init -#define lwip_md5_starts mbedtls_md5_starts -#define lwip_md5_update mbedtls_md5_update -#define lwip_md5_finish mbedtls_md5_finish -#define lwip_md5_free mbedtls_md5_free - -#define lwip_sha1_context mbedtls_sha1_context -#define lwip_sha1_init mbedtls_sha1_init -#define lwip_sha1_starts mbedtls_sha1_starts -#define lwip_sha1_update mbedtls_sha1_update -#define lwip_sha1_finish mbedtls_sha1_finish -#define lwip_sha1_free mbedtls_sha1_free - -#define lwip_des_context mbedtls_des_context -#define lwip_des_init mbedtls_des_init -#define lwip_des_setkey_enc mbedtls_des_setkey_enc -#define lwip_des_crypt_ecb mbedtls_des_crypt_ecb -#define lwip_des_free mbedtls_des_free - -#define lwip_arc4_context mbedtls_arc4_context -#define lwip_arc4_init mbedtls_arc4_init -#define lwip_arc4_setup mbedtls_arc4_setup -#define lwip_arc4_crypt(context, buffer, length) mbedtls_arc4_crypt(context, length, buffer, buffer) -#define lwip_arc4_free mbedtls_arc4_free - -#endif /* LWIP_USE_EXTERNAL_MBEDTLS */ - -void pppcrypt_56_to_64_bit_key(u_char *key, u_char *des_key); - -#ifdef __cplusplus -} -#endif - -#endif /* PPPCRYPT_H */ - -#endif /* PPP_SUPPORT */ diff --git a/third-party/lwip-2.1.2/include/netif/ppp/pppdebug.h b/third-party/lwip-2.1.2/include/netif/ppp/pppdebug.h deleted file mode 100644 index 36ee4f9b..00000000 --- a/third-party/lwip-2.1.2/include/netif/ppp/pppdebug.h +++ /dev/null @@ -1,88 +0,0 @@ -/***************************************************************************** -* pppdebug.h - System debugging utilities. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1998 Global Election Systems Inc. -* portions Copyright (c) 2001 by Cognizant Pty Ltd. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY (please don't use tabs!) -* -* 03-01-01 Marc Boucher -* Ported to lwIP. -* 98-07-29 Guy Lancaster , Global Election Systems Inc. -* Original. -* -***************************************************************************** -*/ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef PPPDEBUG_H -#define PPPDEBUG_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Trace levels. */ -#define LOG_CRITICAL (PPP_DEBUG | LWIP_DBG_LEVEL_SEVERE) -#define LOG_ERR (PPP_DEBUG | LWIP_DBG_LEVEL_SEVERE) -#define LOG_NOTICE (PPP_DEBUG | LWIP_DBG_LEVEL_WARNING) -#define LOG_WARNING (PPP_DEBUG | LWIP_DBG_LEVEL_WARNING) -#define LOG_INFO (PPP_DEBUG) -#define LOG_DETAIL (PPP_DEBUG) -#define LOG_DEBUG (PPP_DEBUG) - -#if PPP_DEBUG - -#define MAINDEBUG(a) LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a) -#define SYSDEBUG(a) LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a) -#define FSMDEBUG(a) LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a) -#define LCPDEBUG(a) LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a) -#define IPCPDEBUG(a) LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a) -#define IPV6CPDEBUG(a) LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a) -#define UPAPDEBUG(a) LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a) -#define CHAPDEBUG(a) LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a) -#define PPPDEBUG(a, b) LWIP_DEBUGF(a, b) - -#else /* PPP_DEBUG */ - -#define MAINDEBUG(a) -#define SYSDEBUG(a) -#define FSMDEBUG(a) -#define LCPDEBUG(a) -#define IPCPDEBUG(a) -#define IPV6CPDEBUG(a) -#define UPAPDEBUG(a) -#define CHAPDEBUG(a) -#define PPPDEBUG(a, b) - -#endif /* PPP_DEBUG */ - -#ifdef __cplusplus -} -#endif - -#endif /* PPPDEBUG_H */ - -#endif /* PPP_SUPPORT */ diff --git a/third-party/lwip-2.1.2/include/netif/ppp/pppoe.h b/third-party/lwip-2.1.2/include/netif/ppp/pppoe.h deleted file mode 100644 index 08ab7ab5..00000000 --- a/third-party/lwip-2.1.2/include/netif/ppp/pppoe.h +++ /dev/null @@ -1,187 +0,0 @@ -/***************************************************************************** -* pppoe.h - PPP Over Ethernet implementation for lwIP. -* -* Copyright (c) 2006 by Marc Boucher, Services Informatiques (MBSI) inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 06-01-01 Marc Boucher -* Ported to lwIP. -*****************************************************************************/ - - - -/* based on NetBSD: if_pppoe.c,v 1.64 2006/01/31 23:50:15 martin Exp */ - -/*- - * Copyright (c) 2002 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Martin Husemann . - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && PPPOE_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef PPP_OE_H -#define PPP_OE_H - -#include "ppp.h" -#include "lwip/etharp.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct pppoehdr { - PACK_STRUCT_FLD_8(u8_t vertype); - PACK_STRUCT_FLD_8(u8_t code); - PACK_STRUCT_FIELD(u16_t session); - PACK_STRUCT_FIELD(u16_t plen); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct pppoetag { - PACK_STRUCT_FIELD(u16_t tag); - PACK_STRUCT_FIELD(u16_t len); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - - -#define PPPOE_STATE_INITIAL 0 -#define PPPOE_STATE_PADI_SENT 1 -#define PPPOE_STATE_PADR_SENT 2 -#define PPPOE_STATE_SESSION 3 -/* passive */ -#define PPPOE_STATE_PADO_SENT 1 - -#define PPPOE_HEADERLEN sizeof(struct pppoehdr) -#define PPPOE_VERTYPE 0x11 /* VER=1, TYPE = 1 */ - -#define PPPOE_TAG_EOL 0x0000 /* end of list */ -#define PPPOE_TAG_SNAME 0x0101 /* service name */ -#define PPPOE_TAG_ACNAME 0x0102 /* access concentrator name */ -#define PPPOE_TAG_HUNIQUE 0x0103 /* host unique */ -#define PPPOE_TAG_ACCOOKIE 0x0104 /* AC cookie */ -#define PPPOE_TAG_VENDOR 0x0105 /* vendor specific */ -#define PPPOE_TAG_RELAYSID 0x0110 /* relay session id */ -#define PPPOE_TAG_SNAME_ERR 0x0201 /* service name error */ -#define PPPOE_TAG_ACSYS_ERR 0x0202 /* AC system error */ -#define PPPOE_TAG_GENERIC_ERR 0x0203 /* gerneric error */ - -#define PPPOE_CODE_PADI 0x09 /* Active Discovery Initiation */ -#define PPPOE_CODE_PADO 0x07 /* Active Discovery Offer */ -#define PPPOE_CODE_PADR 0x19 /* Active Discovery Request */ -#define PPPOE_CODE_PADS 0x65 /* Active Discovery Session confirmation */ -#define PPPOE_CODE_PADT 0xA7 /* Active Discovery Terminate */ - -#ifndef PPPOE_MAX_AC_COOKIE_LEN -#define PPPOE_MAX_AC_COOKIE_LEN 64 -#endif - -struct pppoe_softc { - struct pppoe_softc *next; - struct netif *sc_ethif; /* ethernet interface we are using */ - ppp_pcb *pcb; /* PPP PCB */ - - struct eth_addr sc_dest; /* hardware address of concentrator */ - u16_t sc_session; /* PPPoE session id */ - u8_t sc_state; /* discovery phase or session connected */ - -#ifdef PPPOE_TODO - u8_t *sc_service_name; /* if != NULL: requested name of service */ - u8_t *sc_concentrator_name; /* if != NULL: requested concentrator id */ -#endif /* PPPOE_TODO */ - u8_t sc_ac_cookie[PPPOE_MAX_AC_COOKIE_LEN]; /* content of AC cookie we must echo back */ - u8_t sc_ac_cookie_len; /* length of cookie data */ -#ifdef PPPOE_SERVER - u8_t *sc_hunique; /* content of host unique we must echo back */ - u8_t sc_hunique_len; /* length of host unique */ -#endif - u8_t sc_padi_retried; /* number of PADI retries already done */ - u8_t sc_padr_retried; /* number of PADR retries already done */ -}; - - -#define pppoe_init() /* compatibility define, no initialization needed */ - -ppp_pcb *pppoe_create(struct netif *pppif, - struct netif *ethif, - const char *service_name, const char *concentrator_name, - ppp_link_status_cb_fn link_status_cb, void *ctx_cb); - -/* - * Functions called from lwIP - * DO NOT CALL FROM lwIP USER APPLICATION. - */ -void pppoe_disc_input(struct netif *netif, struct pbuf *p); -void pppoe_data_input(struct netif *netif, struct pbuf *p); - -#ifdef __cplusplus -} -#endif - -#endif /* PPP_OE_H */ - -#endif /* PPP_SUPPORT && PPPOE_SUPPORT */ diff --git a/third-party/lwip-2.1.2/include/netif/ppp/pppol2tp.h b/third-party/lwip-2.1.2/include/netif/ppp/pppol2tp.h deleted file mode 100644 index 1221ca15..00000000 --- a/third-party/lwip-2.1.2/include/netif/ppp/pppol2tp.h +++ /dev/null @@ -1,209 +0,0 @@ -/** - * @file - * Network Point to Point Protocol over Layer 2 Tunneling Protocol header file. - * - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && PPPOL2TP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef PPPOL2TP_H -#define PPPOL2TP_H - -#include "ppp.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Timeout */ -#define PPPOL2TP_CONTROL_TIMEOUT (5*1000) /* base for quick timeout calculation */ -#define PPPOL2TP_SLOW_RETRY (60*1000) /* persistent retry interval */ - -#define PPPOL2TP_MAXSCCRQ 4 /* retry SCCRQ four times (quickly) */ -#define PPPOL2TP_MAXICRQ 4 /* retry IRCQ four times */ -#define PPPOL2TP_MAXICCN 4 /* retry ICCN four times */ - -/* L2TP header flags */ -#define PPPOL2TP_HEADERFLAG_CONTROL 0x8000 -#define PPPOL2TP_HEADERFLAG_LENGTH 0x4000 -#define PPPOL2TP_HEADERFLAG_SEQUENCE 0x0800 -#define PPPOL2TP_HEADERFLAG_OFFSET 0x0200 -#define PPPOL2TP_HEADERFLAG_PRIORITY 0x0100 -#define PPPOL2TP_HEADERFLAG_VERSION 0x0002 - -/* Mandatory bits for control: Control, Length, Sequence, Version 2 */ -#define PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY (PPPOL2TP_HEADERFLAG_CONTROL|PPPOL2TP_HEADERFLAG_LENGTH|PPPOL2TP_HEADERFLAG_SEQUENCE|PPPOL2TP_HEADERFLAG_VERSION) -/* Forbidden bits for control: Offset, Priority */ -#define PPPOL2TP_HEADERFLAG_CONTROL_FORBIDDEN (PPPOL2TP_HEADERFLAG_OFFSET|PPPOL2TP_HEADERFLAG_PRIORITY) - -/* Mandatory bits for data: Version 2 */ -#define PPPOL2TP_HEADERFLAG_DATA_MANDATORY (PPPOL2TP_HEADERFLAG_VERSION) - -/* AVP (Attribute Value Pair) header */ -#define PPPOL2TP_AVPHEADERFLAG_MANDATORY 0x8000 -#define PPPOL2TP_AVPHEADERFLAG_HIDDEN 0x4000 -#define PPPOL2TP_AVPHEADERFLAG_LENGTHMASK 0x03ff - -/* -- AVP - Message type */ -#define PPPOL2TP_AVPTYPE_MESSAGE 0 /* Message type */ - -/* Control Connection Management */ -#define PPPOL2TP_MESSAGETYPE_SCCRQ 1 /* Start Control Connection Request */ -#define PPPOL2TP_MESSAGETYPE_SCCRP 2 /* Start Control Connection Reply */ -#define PPPOL2TP_MESSAGETYPE_SCCCN 3 /* Start Control Connection Connected */ -#define PPPOL2TP_MESSAGETYPE_STOPCCN 4 /* Stop Control Connection Notification */ -#define PPPOL2TP_MESSAGETYPE_HELLO 6 /* Hello */ -/* Call Management */ -#define PPPOL2TP_MESSAGETYPE_OCRQ 7 /* Outgoing Call Request */ -#define PPPOL2TP_MESSAGETYPE_OCRP 8 /* Outgoing Call Reply */ -#define PPPOL2TP_MESSAGETYPE_OCCN 9 /* Outgoing Call Connected */ -#define PPPOL2TP_MESSAGETYPE_ICRQ 10 /* Incoming Call Request */ -#define PPPOL2TP_MESSAGETYPE_ICRP 11 /* Incoming Call Reply */ -#define PPPOL2TP_MESSAGETYPE_ICCN 12 /* Incoming Call Connected */ -#define PPPOL2TP_MESSAGETYPE_CDN 14 /* Call Disconnect Notify */ -/* Error reporting */ -#define PPPOL2TP_MESSAGETYPE_WEN 15 /* WAN Error Notify */ -/* PPP Session Control */ -#define PPPOL2TP_MESSAGETYPE_SLI 16 /* Set Link Info */ - -/* -- AVP - Result code */ -#define PPPOL2TP_AVPTYPE_RESULTCODE 1 /* Result code */ -#define PPPOL2TP_RESULTCODE 1 /* General request to clear control connection */ - -/* -- AVP - Protocol version (!= L2TP Header version) */ -#define PPPOL2TP_AVPTYPE_VERSION 2 -#define PPPOL2TP_VERSION 0x0100 /* L2TP Protocol version 1, revision 0 */ - -/* -- AVP - Framing capabilities */ -#define PPPOL2TP_AVPTYPE_FRAMINGCAPABILITIES 3 /* Bearer capabilities */ -#define PPPOL2TP_FRAMINGCAPABILITIES 0x00000003 /* Async + Sync framing */ - -/* -- AVP - Bearer capabilities */ -#define PPPOL2TP_AVPTYPE_BEARERCAPABILITIES 4 /* Bearer capabilities */ -#define PPPOL2TP_BEARERCAPABILITIES 0x00000003 /* Analog + Digital Access */ - -/* -- AVP - Tie breaker */ -#define PPPOL2TP_AVPTYPE_TIEBREAKER 5 - -/* -- AVP - Host name */ -#define PPPOL2TP_AVPTYPE_HOSTNAME 7 /* Host name */ -#define PPPOL2TP_HOSTNAME "lwIP" /* FIXME: make it configurable */ - -/* -- AVP - Vendor name */ -#define PPPOL2TP_AVPTYPE_VENDORNAME 8 /* Vendor name */ -#define PPPOL2TP_VENDORNAME "lwIP" /* FIXME: make it configurable */ - -/* -- AVP - Assign tunnel ID */ -#define PPPOL2TP_AVPTYPE_TUNNELID 9 /* Assign Tunnel ID */ - -/* -- AVP - Receive window size */ -#define PPPOL2TP_AVPTYPE_RECEIVEWINDOWSIZE 10 /* Receive window size */ -#define PPPOL2TP_RECEIVEWINDOWSIZE 8 /* FIXME: make it configurable */ - -/* -- AVP - Challenge */ -#define PPPOL2TP_AVPTYPE_CHALLENGE 11 /* Challenge */ - -/* -- AVP - Cause code */ -#define PPPOL2TP_AVPTYPE_CAUSECODE 12 /* Cause code*/ - -/* -- AVP - Challenge response */ -#define PPPOL2TP_AVPTYPE_CHALLENGERESPONSE 13 /* Challenge response */ -#define PPPOL2TP_AVPTYPE_CHALLENGERESPONSE_SIZE 16 - -/* -- AVP - Assign session ID */ -#define PPPOL2TP_AVPTYPE_SESSIONID 14 /* Assign Session ID */ - -/* -- AVP - Call serial number */ -#define PPPOL2TP_AVPTYPE_CALLSERIALNUMBER 15 /* Call Serial Number */ - -/* -- AVP - Framing type */ -#define PPPOL2TP_AVPTYPE_FRAMINGTYPE 19 /* Framing Type */ -#define PPPOL2TP_FRAMINGTYPE 0x00000001 /* Sync framing */ - -/* -- AVP - TX Connect Speed */ -#define PPPOL2TP_AVPTYPE_TXCONNECTSPEED 24 /* TX Connect Speed */ -#define PPPOL2TP_TXCONNECTSPEED 100000000 /* Connect speed: 100 Mbits/s */ - -/* L2TP Session state */ -#define PPPOL2TP_STATE_INITIAL 0 -#define PPPOL2TP_STATE_SCCRQ_SENT 1 -#define PPPOL2TP_STATE_ICRQ_SENT 2 -#define PPPOL2TP_STATE_ICCN_SENT 3 -#define PPPOL2TP_STATE_DATA 4 - -#define PPPOL2TP_OUTPUT_DATA_HEADER_LEN 6 /* Our data header len */ - -/* - * PPPoL2TP interface control block. - */ -typedef struct pppol2tp_pcb_s pppol2tp_pcb; -struct pppol2tp_pcb_s { - ppp_pcb *ppp; /* PPP PCB */ - u8_t phase; /* L2TP phase */ - struct udp_pcb *udp; /* UDP L2TP Socket */ - struct netif *netif; /* Output interface, used as a default route */ - ip_addr_t remote_ip; /* LNS IP Address */ - u16_t remote_port; /* LNS port */ -#if PPPOL2TP_AUTH_SUPPORT - const u8_t *secret; /* Secret string */ - u8_t secret_len; /* Secret string length */ - u8_t secret_rv[16]; /* Random vector */ - u8_t challenge_hash[16]; /* Challenge response */ - u8_t send_challenge; /* Boolean whether the next sent packet should contains a challenge response */ -#endif /* PPPOL2TP_AUTH_SUPPORT */ - - u16_t tunnel_port; /* Tunnel port */ - u16_t our_ns; /* NS to peer */ - u16_t peer_nr; /* NR from peer */ - u16_t peer_ns; /* Expected NS from peer */ - u16_t source_tunnel_id; /* Tunnel ID assigned by peer */ - u16_t remote_tunnel_id; /* Tunnel ID assigned to peer */ - u16_t source_session_id; /* Session ID assigned by peer */ - u16_t remote_session_id; /* Session ID assigned to peer */ - - u8_t sccrq_retried; /* number of SCCRQ retries already done */ - u8_t icrq_retried; /* number of ICRQ retries already done */ - u8_t iccn_retried; /* number of ICCN retries already done */ -}; - - -/* Create a new L2TP session. */ -ppp_pcb *pppol2tp_create(struct netif *pppif, - struct netif *netif, const ip_addr_t *ipaddr, u16_t port, - const u8_t *secret, u8_t secret_len, - ppp_link_status_cb_fn link_status_cb, void *ctx_cb); - -#ifdef __cplusplus -} -#endif - -#endif /* PPPOL2TP_H */ -#endif /* PPP_SUPPORT && PPPOL2TP_SUPPORT */ diff --git a/third-party/lwip-2.1.2/include/netif/ppp/pppos.h b/third-party/lwip-2.1.2/include/netif/ppp/pppos.h deleted file mode 100644 index 380a965c..00000000 --- a/third-party/lwip-2.1.2/include/netif/ppp/pppos.h +++ /dev/null @@ -1,126 +0,0 @@ -/** - * @file - * Network Point to Point Protocol over Serial header file. - * - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && PPPOS_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef PPPOS_H -#define PPPOS_H - -#include "lwip/sys.h" - -#include "ppp.h" -#include "vj.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* PPP packet parser states. Current state indicates operation yet to be - * completed. */ -enum { - PDIDLE = 0, /* Idle state - waiting. */ - PDSTART, /* Process start flag. */ - PDADDRESS, /* Process address field. */ - PDCONTROL, /* Process control field. */ - PDPROTOCOL1, /* Process protocol field 1. */ - PDPROTOCOL2, /* Process protocol field 2. */ - PDDATA /* Process data byte. */ -}; - -/* PPPoS serial output callback function prototype */ -typedef u32_t (*pppos_output_cb_fn)(ppp_pcb *pcb, u8_t *data, u32_t len, void *ctx); - -/* - * Extended asyncmap - allows any character to be escaped. - */ -typedef u8_t ext_accm[32]; - -/* - * PPPoS interface control block. - */ -typedef struct pppos_pcb_s pppos_pcb; -struct pppos_pcb_s { - /* -- below are data that will NOT be cleared between two sessions */ - ppp_pcb *ppp; /* PPP PCB */ - pppos_output_cb_fn output_cb; /* PPP serial output callback */ - - /* -- below are data that will be cleared between two sessions - * - * last_xmit must be the first member of cleared members, because it is - * used to know which part must not be cleared. - */ - u32_t last_xmit; /* Time of last transmission. */ - ext_accm out_accm; /* Async-Ctl-Char-Map for output. */ - - /* flags */ - unsigned int open :1; /* Set if PPPoS is open */ - unsigned int pcomp :1; /* Does peer accept protocol compression? */ - unsigned int accomp :1; /* Does peer accept addr/ctl compression? */ - - /* PPPoS rx */ - ext_accm in_accm; /* Async-Ctl-Char-Map for input. */ - struct pbuf *in_head, *in_tail; /* The input packet. */ - u16_t in_protocol; /* The input protocol code. */ - u16_t in_fcs; /* Input Frame Check Sequence value. */ - u8_t in_state; /* The input process state. */ - u8_t in_escaped; /* Escape next character. */ -}; - -/* Create a new PPPoS session. */ -ppp_pcb *pppos_create(struct netif *pppif, pppos_output_cb_fn output_cb, - ppp_link_status_cb_fn link_status_cb, void *ctx_cb); - -#if !NO_SYS && !PPP_INPROC_IRQ_SAFE -/* Pass received raw characters to PPPoS to be decoded through lwIP TCPIP thread. */ -err_t pppos_input_tcpip(ppp_pcb *ppp, u8_t *s, int l); -#endif /* !NO_SYS && !PPP_INPROC_IRQ_SAFE */ - -/* PPP over Serial: this is the input function to be called for received data. */ -void pppos_input(ppp_pcb *ppp, u8_t* data, int len); - - -/* - * Functions called from lwIP - * DO NOT CALL FROM lwIP USER APPLICATION. - */ -#if !NO_SYS && !PPP_INPROC_IRQ_SAFE -err_t pppos_input_sys(struct pbuf *p, struct netif *inp); -#endif /* !NO_SYS && !PPP_INPROC_IRQ_SAFE */ - -#ifdef __cplusplus -} -#endif - -#endif /* PPPOS_H */ -#endif /* PPP_SUPPORT && PPPOL2TP_SUPPORT */ diff --git a/third-party/lwip-2.1.2/include/netif/ppp/upap.h b/third-party/lwip-2.1.2/include/netif/ppp/upap.h deleted file mode 100644 index 540d9814..00000000 --- a/third-party/lwip-2.1.2/include/netif/ppp/upap.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * upap.h - User/Password Authentication Protocol definitions. - * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * $Id: upap.h,v 1.8 2002/12/04 23:03:33 paulus Exp $ - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && PAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef UPAP_H -#define UPAP_H - -#include "ppp.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Packet header = Code, id, length. - */ -#define UPAP_HEADERLEN 4 - - -/* - * UPAP codes. - */ -#define UPAP_AUTHREQ 1 /* Authenticate-Request */ -#define UPAP_AUTHACK 2 /* Authenticate-Ack */ -#define UPAP_AUTHNAK 3 /* Authenticate-Nak */ - - -/* - * Client states. - */ -#define UPAPCS_INITIAL 0 /* Connection down */ -#define UPAPCS_CLOSED 1 /* Connection up, haven't requested auth */ -#define UPAPCS_PENDING 2 /* Connection down, have requested auth */ -#define UPAPCS_AUTHREQ 3 /* We've sent an Authenticate-Request */ -#define UPAPCS_OPEN 4 /* We've received an Ack */ -#define UPAPCS_BADAUTH 5 /* We've received a Nak */ - -/* - * Server states. - */ -#define UPAPSS_INITIAL 0 /* Connection down */ -#define UPAPSS_CLOSED 1 /* Connection up, haven't requested auth */ -#define UPAPSS_PENDING 2 /* Connection down, have requested auth */ -#define UPAPSS_LISTEN 3 /* Listening for an Authenticate */ -#define UPAPSS_OPEN 4 /* We've sent an Ack */ -#define UPAPSS_BADAUTH 5 /* We've sent a Nak */ - - -/* - * Timeouts. - */ -#if 0 /* moved to ppp_opts.h */ -#define UPAP_DEFTIMEOUT 3 /* Timeout (seconds) for retransmitting req */ -#define UPAP_DEFREQTIME 30 /* Time to wait for auth-req from peer */ -#endif /* moved to ppp_opts.h */ - -/* - * Each interface is described by upap structure. - */ -#if PAP_SUPPORT -typedef struct upap_state { - const char *us_user; /* User */ - u8_t us_userlen; /* User length */ - const char *us_passwd; /* Password */ - u8_t us_passwdlen; /* Password length */ - u8_t us_clientstate; /* Client state */ -#if PPP_SERVER - u8_t us_serverstate; /* Server state */ -#endif /* PPP_SERVER */ - u8_t us_id; /* Current id */ - u8_t us_transmits; /* Number of auth-reqs sent */ -} upap_state; -#endif /* PAP_SUPPORT */ - - -void upap_authwithpeer(ppp_pcb *pcb, const char *user, const char *password); -#if PPP_SERVER -void upap_authpeer(ppp_pcb *pcb); -#endif /* PPP_SERVER */ - -extern const struct protent pap_protent; - -#ifdef __cplusplus -} -#endif - -#endif /* UPAP_H */ -#endif /* PPP_SUPPORT && PAP_SUPPORT */ diff --git a/third-party/lwip-2.1.2/include/netif/ppp/vj.h b/third-party/lwip-2.1.2/include/netif/ppp/vj.h deleted file mode 100644 index 77d9976c..00000000 --- a/third-party/lwip-2.1.2/include/netif/ppp/vj.h +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Definitions for tcp compression routines. - * - * $Id: vj.h,v 1.7 2010/02/22 17:52:09 goldsimon Exp $ - * - * Copyright (c) 1989 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: - * - Initial distribution. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && VJ_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef VJ_H -#define VJ_H - -#include "lwip/ip.h" -#include "lwip/priv/tcp_priv.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define MAX_SLOTS 16 /* must be > 2 and < 256 */ -#define MAX_HDR 128 - -/* - * Compressed packet format: - * - * The first octet contains the packet type (top 3 bits), TCP - * 'push' bit, and flags that indicate which of the 4 TCP sequence - * numbers have changed (bottom 5 bits). The next octet is a - * conversation number that associates a saved IP/TCP header with - * the compressed packet. The next two octets are the TCP checksum - * from the original datagram. The next 0 to 15 octets are - * sequence number changes, one change per bit set in the header - * (there may be no changes and there are two special cases where - * the receiver implicitly knows what changed -- see below). - * - * There are 5 numbers which can change (they are always inserted - * in the following order): TCP urgent pointer, window, - * acknowlegement, sequence number and IP ID. (The urgent pointer - * is different from the others in that its value is sent, not the - * change in value.) Since typical use of SLIP links is biased - * toward small packets (see comments on MTU/MSS below), changes - * use a variable length coding with one octet for numbers in the - * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the - * range 256 - 65535 or 0. (If the change in sequence number or - * ack is more than 65535, an uncompressed packet is sent.) - */ - -/* - * Packet types (must not conflict with IP protocol version) - * - * The top nibble of the first octet is the packet type. There are - * three possible types: IP (not proto TCP or tcp with one of the - * control flags set); uncompressed TCP (a normal IP/TCP packet but - * with the 8-bit protocol field replaced by an 8-bit connection id -- - * this type of packet syncs the sender & receiver); and compressed - * TCP (described above). - * - * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and - * is logically part of the 4-bit "changes" field that follows. Top - * three bits are actual packet type. For backward compatibility - * and in the interest of conserving bits, numbers are chosen so the - * IP protocol version number (4) which normally appears in this nibble - * means "IP packet". - */ - -/* packet types */ -#define TYPE_IP 0x40 -#define TYPE_UNCOMPRESSED_TCP 0x70 -#define TYPE_COMPRESSED_TCP 0x80 -#define TYPE_ERROR 0x00 - -/* Bits in first octet of compressed packet */ -#define NEW_C 0x40 /* flag bits for what changed in a packet */ -#define NEW_I 0x20 -#define NEW_S 0x08 -#define NEW_A 0x04 -#define NEW_W 0x02 -#define NEW_U 0x01 - -/* reserved, special-case values of above */ -#define SPECIAL_I (NEW_S|NEW_W|NEW_U) /* echoed interactive traffic */ -#define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */ -#define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U) - -#define TCP_PUSH_BIT 0x10 - - -/* - * "state" data for each active tcp conversation on the wire. This is - * basically a copy of the entire IP/TCP header from the last packet - * we saw from the conversation together with a small identifier - * the transmit & receive ends of the line use to locate saved header. - */ -struct cstate { - struct cstate *cs_next; /* next most recently used state (xmit only) */ - u16_t cs_hlen; /* size of hdr (receive only) */ - u8_t cs_id; /* connection # associated with this state */ - u8_t cs_filler; - union { - char csu_hdr[MAX_HDR]; - struct ip_hdr csu_ip; /* ip/tcp hdr from most recent packet */ - } vjcs_u; -}; -#define cs_ip vjcs_u.csu_ip -#define cs_hdr vjcs_u.csu_hdr - - -struct vjstat { - u32_t vjs_packets; /* outbound packets */ - u32_t vjs_compressed; /* outbound compressed packets */ - u32_t vjs_searches; /* searches for connection state */ - u32_t vjs_misses; /* times couldn't find conn. state */ - u32_t vjs_uncompressedin; /* inbound uncompressed packets */ - u32_t vjs_compressedin; /* inbound compressed packets */ - u32_t vjs_errorin; /* inbound unknown type packets */ - u32_t vjs_tossed; /* inbound packets tossed because of error */ -}; - -/* - * all the state data for one serial line (we need one of these per line). - */ -struct vjcompress { - struct cstate *last_cs; /* most recently used tstate */ - u8_t last_recv; /* last rcvd conn. id */ - u8_t last_xmit; /* last sent conn. id */ - u16_t flags; - u8_t maxSlotIndex; - u8_t compressSlot; /* Flag indicating OK to compress slot ID. */ -#if LINK_STATS - struct vjstat stats; -#endif - struct cstate tstate[MAX_SLOTS]; /* xmit connection states */ - struct cstate rstate[MAX_SLOTS]; /* receive connection states */ -}; - -/* flag values */ -#define VJF_TOSS 1U /* tossing rcvd frames because of input err */ - -extern void vj_compress_init (struct vjcompress *comp); -extern u8_t vj_compress_tcp (struct vjcompress *comp, struct pbuf **pb); -extern void vj_uncompress_err (struct vjcompress *comp); -extern int vj_uncompress_uncomp(struct pbuf *nb, struct vjcompress *comp); -extern int vj_uncompress_tcp (struct pbuf **nb, struct vjcompress *comp); - -#ifdef __cplusplus -} -#endif - -#endif /* VJ_H */ - -#endif /* PPP_SUPPORT && VJ_SUPPORT */ diff --git a/third-party/lwip-2.1.2/include/netif/slipif.h b/third-party/lwip-2.1.2/include/netif/slipif.h deleted file mode 100644 index 65ba31f8..00000000 --- a/third-party/lwip-2.1.2/include/netif/slipif.h +++ /dev/null @@ -1,87 +0,0 @@ -/** - * @file - * - * SLIP netif API - */ - -/* - * Copyright (c) 2001, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_NETIF_SLIPIF_H -#define LWIP_HDR_NETIF_SLIPIF_H - -#include "lwip/opt.h" -#include "lwip/netif.h" - -/** Set this to 1 to start a thread that blocks reading on the serial line - * (using sio_read()). - */ -#ifndef SLIP_USE_RX_THREAD -#define SLIP_USE_RX_THREAD !NO_SYS -#endif - -/** Set this to 1 to enable functions to pass in RX bytes from ISR context. - * If enabled, slipif_received_byte[s]() process incoming bytes and put assembled - * packets on a queue, which is fed into lwIP from slipif_poll(). - * If disabled, slipif_poll() polls the serial line (using sio_tryread()). - */ -#ifndef SLIP_RX_FROM_ISR -#define SLIP_RX_FROM_ISR 0 -#endif - -/** Set this to 1 (default for SLIP_RX_FROM_ISR) to queue incoming packets - * received by slipif_received_byte[s]() as long as PBUF_POOL pbufs are available. - * If disabled, packets will be dropped if more than one packet is received. - */ -#ifndef SLIP_RX_QUEUE -#define SLIP_RX_QUEUE SLIP_RX_FROM_ISR -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -err_t slipif_init(struct netif * netif); -void slipif_poll(struct netif *netif); -#if SLIP_RX_FROM_ISR -void slipif_process_rxqueue(struct netif *netif); -void slipif_received_byte(struct netif *netif, u8_t data); -void slipif_received_bytes(struct netif *netif, u8_t *data, u8_t len); -#endif /* SLIP_RX_FROM_ISR */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_NETIF_SLIPIF_H */ - diff --git a/third-party/lwip-2.1.2/include/netif/zepif.h b/third-party/lwip-2.1.2/include/netif/zepif.h deleted file mode 100644 index 2a801b4c..00000000 --- a/third-party/lwip-2.1.2/include/netif/zepif.h +++ /dev/null @@ -1,81 +0,0 @@ -/** - * @file - * - * A netif implementing the ZigBee Eencapsulation Protocol (ZEP). - * This is used to tunnel 6LowPAN over UDP. - */ - -/* - * Copyright (c) 2018 Simon Goldschmidt - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Simon Goldschmidt - * - */ - -#ifndef LWIP_HDR_ZEPIF_H -#define LWIP_HDR_ZEPIF_H - -#include "lwip/opt.h" -#include "netif/lowpan6.h" - -#if LWIP_IPV6 && LWIP_UDP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/netif.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define ZEPIF_DEFAULT_UDP_PORT 17754 - -/** Pass this struct as 'state' to netif_add to control the behaviour - * of this netif. If NULL is passed, default behaviour is chosen */ -struct zepif_init { - /** The UDP port used to ZEP frames from (0 = default) */ - u16_t zep_src_udp_port; - /** The UDP port used to ZEP frames to (0 = default) */ - u16_t zep_dst_udp_port; - /** The IP address to sed ZEP frames from (NULL = ANY) */ - const ip_addr_t *zep_src_ip_addr; - /** The IP address to sed ZEP frames to (NULL = BROADCAST) */ - const ip_addr_t *zep_dst_ip_addr; - /** If != NULL, the udp pcb is bound to this netif */ - const struct netif *zep_netif; - /** MAC address of the 6LowPAN device */ - u8_t addr[6]; -}; - -err_t zepif_init(struct netif *netif); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV6 && LWIP_UDP */ - -#endif /* LWIP_HDR_ZEPIF_H */ diff --git a/third-party/lwip-2.1.2/lwip_freertos.mk b/third-party/lwip-2.1.2/lwip_freertos.mk new file mode 100644 index 00000000..0a4e6eec --- /dev/null +++ b/third-party/lwip-2.1.2/lwip_freertos.mk @@ -0,0 +1,25 @@ +LWIP_FREERTOS_CUR_DIR := $(FREERTOS_SDK_ROOT)/third-party + +ifdef CONFIG_USE_LWIP + +include $(STANDALONE_DIR)/third-party/lwip-2.1.2/lwip.mk + +ifdef CONFIG_LWIP_FGMAC # src code of ports + INC_DIR += $(LWIP_FREERTOS_CUR_DIR)/lwip-2.1.2/ports/fgmac \ + $(LWIP_FREERTOS_CUR_DIR)/lwip-2.1.2/ports + + SRC_DIR += $(LWIP_FREERTOS_CUR_DIR)/lwip-2.1.2/ports/fgmac \ + $(LWIP_FREERTOS_CUR_DIR)/lwip-2.1.2/ports +endif #CONFIG_LWIP_FGMAC + +ifdef CONFIG_LWIP_FXMAC + INC_DIR += $(LWIP_FREERTOS_CUR_DIR)/lwip-2.1.2/ports/fxmac \ + $(LWIP_FREERTOS_CUR_DIR)/lwip-2.1.2/ports + SRC_DIR += $(LWIP_FREERTOS_CUR_DIR)/lwip-2.1.2/ports/fxmac \ + $(LWIP_FREERTOS_CUR_DIR)/lwip-2.1.2/ports +endif + +INC_DIR += $(LWIP_FREERTOS_CUR_DIR)/lwip-2.1.2/ports/arch +SRC_DIR += $(LWIP_FREERTOS_CUR_DIR)/lwip-2.1.2/ports/arch + +endif diff --git a/third-party/lwip-2.1.2/netif/FILES b/third-party/lwip-2.1.2/netif/FILES deleted file mode 100644 index 1ffd6f2d..00000000 --- a/third-party/lwip-2.1.2/netif/FILES +++ /dev/null @@ -1,23 +0,0 @@ -This directory contains generic network interface device drivers that -do not contain any hardware or architecture specific code. The files -are: - -ethernet.c - Shared code for Ethernet based interfaces. - -lowpan6.c - A 6LoWPAN implementation as a netif. - -lowpan6_ble.c - A 6LoWPAN over Bluetooth Low Energy (BLE) implementation as netif, - according to RFC-7668. - -slipif.c - A generic implementation of the SLIP (Serial Line IP) - protocol. It requires a sio (serial I/O) module to work. - -ppp/ Point-to-Point Protocol stack - The lwIP PPP support is based from pppd (http://ppp.samba.org) with - huge changes to match code size and memory requirements for embedded - devices. Please read /doc/ppp.txt and ppp/PPPD_FOLLOWUP for a detailed - explanation. diff --git a/third-party/lwip-2.1.2/netif/bridgeif.c b/third-party/lwip-2.1.2/netif/bridgeif.c deleted file mode 100644 index 8a97bce3..00000000 --- a/third-party/lwip-2.1.2/netif/bridgeif.c +++ /dev/null @@ -1,563 +0,0 @@ -/** - * @file - * lwIP netif implementing an IEEE 802.1D MAC Bridge - */ - -/* - * Copyright (c) 2017 Simon Goldschmidt. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Simon Goldschmidt - * - */ - -/** - * @defgroup bridgeif IEEE 802.1D bridge - * @ingroup netifs - * This file implements an IEEE 802.1D bridge by using a multilayer netif approach - * (one hardware-independent netif for the bridge that uses hardware netifs for its ports). - * On transmit, the bridge selects the outgoing port(s). - * On receive, the port netif calls into the bridge (via its netif->input function) and - * the bridge selects the port(s) (and/or its netif->input function) to pass the received pbuf to. - * - * Usage: - * - add the port netifs just like you would when using them as dedicated netif without a bridge - * - only NETIF_FLAG_ETHARP/NETIF_FLAG_ETHERNET netifs are supported as bridge ports - * - add the bridge port netifs without IPv4 addresses (i.e. pass 'NULL, NULL, NULL') - * - don't add IPv6 addresses to the port netifs! - * - set up the bridge configuration in a global variable of type 'bridgeif_initdata_t' that contains - * - the MAC address of the bridge - * - some configuration options controlling the memory consumption (maximum number of ports - * and FDB entries) - * - e.g. for a bridge MAC address 00-01-02-03-04-05, 2 bridge ports, 1024 FDB entries + 16 static MAC entries: - * bridgeif_initdata_t mybridge_initdata = BRIDGEIF_INITDATA1(2, 1024, 16, ETH_ADDR(0, 1, 2, 3, 4, 5)); - * - add the bridge netif (with IPv4 config): - * struct netif bridge_netif; - * netif_add(&bridge_netif, &my_ip, &my_netmask, &my_gw, &mybridge_initdata, bridgeif_init, tcpip_input); - * NOTE: the passed 'input' function depends on BRIDGEIF_PORT_NETIFS_OUTPUT_DIRECT setting, - * which controls where the forwarding is done (netif low level input context vs. tcpip_thread) - * - set up all ports netifs and the bridge netif - * - * - When adding a port netif, NETIF_FLAG_ETHARP flag will be removed from a port - * to prevent ETHARP working on that port netif (we only want one IP per bridge not per port). - * - When adding a port netif, its input function is changed to call into the bridge. - * - * - * @todo: - * - compact static FDB entries (instead of walking the whole array) - * - add FDB query/read access - * - add FDB change callback (when learning or dropping auto-learned entries) - * - prefill FDB with MAC classes that should never be forwarded - * - multicast snooping? (and only forward group addresses to interested ports) - * - support removing ports - * - check SNMP integration - * - VLAN handling / trunk ports - * - priority handling? (although that largely depends on TX queue limitations and lwIP doesn't provide tx-done handling) - */ - -#include "netif/bridgeif.h" -#include "lwip/netif.h" -#include "lwip/sys.h" -#include "lwip/etharp.h" -#include "lwip/ethip6.h" -#include "lwip/snmp.h" -#include "lwip/timeouts.h" -#include - -#if LWIP_NUM_NETIF_CLIENT_DATA - -/* Define those to better describe your network interface. */ -#define IFNAME0 'b' -#define IFNAME1 'r' - -struct bridgeif_private_s; -typedef struct bridgeif_port_private_s { - struct bridgeif_private_s *bridge; - struct netif *port_netif; - u8_t port_num; -} bridgeif_port_t; - -typedef struct bridgeif_fdb_static_entry_s { - u8_t used; - bridgeif_portmask_t dst_ports; - struct eth_addr addr; -} bridgeif_fdb_static_entry_t; - -typedef struct bridgeif_private_s { - struct netif *netif; - struct eth_addr ethaddr; - u8_t max_ports; - u8_t num_ports; - bridgeif_port_t *ports; - u16_t max_fdbs_entries; - bridgeif_fdb_static_entry_t *fdbs; - u16_t max_fdbd_entries; - void *fdbd; -} bridgeif_private_t; - -/* netif data index to get the bridge on input */ -u8_t bridgeif_netif_client_id = 0xff; - -/** - * @ingroup bridgeif - * Add a static entry to the forwarding database. - * A static entry marks where frames to a specific eth address (unicast or group address) are - * forwarded. - * bits [0..(BRIDGEIF_MAX_PORTS-1)]: hw ports - * bit [BRIDGEIF_MAX_PORTS]: cpu port - * 0: drop - */ -err_t -bridgeif_fdb_add(struct netif *bridgeif, const struct eth_addr *addr, bridgeif_portmask_t ports) -{ - int i; - bridgeif_private_t *br; - BRIDGEIF_DECL_PROTECT(lev); - LWIP_ASSERT("invalid netif", bridgeif != NULL); - br = (bridgeif_private_t *)bridgeif->state; - LWIP_ASSERT("invalid state", br != NULL); - - BRIDGEIF_READ_PROTECT(lev); - for (i = 0; i < br->max_fdbs_entries; i++) { - if (!br->fdbs[i].used) { - BRIDGEIF_WRITE_PROTECT(lev); - if (!br->fdbs[i].used) { - br->fdbs[i].used = 1; - br->fdbs[i].dst_ports = ports; - memcpy(&br->fdbs[i].addr, addr, sizeof(struct eth_addr)); - BRIDGEIF_WRITE_UNPROTECT(lev); - BRIDGEIF_READ_UNPROTECT(lev); - return ERR_OK; - } - BRIDGEIF_WRITE_UNPROTECT(lev); - } - } - BRIDGEIF_READ_UNPROTECT(lev); - return ERR_MEM; -} - -/** - * @ingroup bridgeif - * Remove a static entry from the forwarding database - */ -err_t -bridgeif_fdb_remove(struct netif *bridgeif, const struct eth_addr *addr) -{ - int i; - bridgeif_private_t *br; - BRIDGEIF_DECL_PROTECT(lev); - LWIP_ASSERT("invalid netif", bridgeif != NULL); - br = (bridgeif_private_t *)bridgeif->state; - LWIP_ASSERT("invalid state", br != NULL); - - BRIDGEIF_READ_PROTECT(lev); - for (i = 0; i < br->max_fdbs_entries; i++) { - if (br->fdbs[i].used && !memcmp(&br->fdbs[i].addr, addr, sizeof(struct eth_addr))) { - BRIDGEIF_WRITE_PROTECT(lev); - if (br->fdbs[i].used && !memcmp(&br->fdbs[i].addr, addr, sizeof(struct eth_addr))) { - memset(&br->fdbs[i], 0, sizeof(bridgeif_fdb_static_entry_t)); - BRIDGEIF_WRITE_UNPROTECT(lev); - BRIDGEIF_READ_UNPROTECT(lev); - return ERR_OK; - } - BRIDGEIF_WRITE_UNPROTECT(lev); - } - } - BRIDGEIF_READ_UNPROTECT(lev); - return ERR_VAL; -} - -/** Get the forwarding port(s) (as bit mask) for the specified destination mac address */ -static bridgeif_portmask_t -bridgeif_find_dst_ports(bridgeif_private_t *br, struct eth_addr *dst_addr) -{ - int i; - BRIDGEIF_DECL_PROTECT(lev); - BRIDGEIF_READ_PROTECT(lev); - /* first check for static entries */ - for (i = 0; i < br->max_fdbs_entries; i++) { - if (br->fdbs[i].used) { - if (!memcmp(&br->fdbs[i].addr, dst_addr, sizeof(struct eth_addr))) { - bridgeif_portmask_t ret = br->fdbs[i].dst_ports; - BRIDGEIF_READ_UNPROTECT(lev); - return ret; - } - } - } - if (dst_addr->addr[0] & 1) { - /* no match found: flood remaining group address */ - BRIDGEIF_READ_UNPROTECT(lev); - return BR_FLOOD; - } - BRIDGEIF_READ_UNPROTECT(lev); - /* no match found: check dynamic fdb for port or fall back to flooding */ - return bridgeif_fdb_get_dst_ports(br->fdbd, dst_addr); -} - -/** Helper function to see if a destination mac belongs to the bridge - * (bridge netif or one of the port netifs), in which case the frame - * is sent to the cpu only. - */ -static int -bridgeif_is_local_mac(bridgeif_private_t *br, struct eth_addr *addr) -{ - int i; - BRIDGEIF_DECL_PROTECT(lev); - if (!memcmp(br->netif->hwaddr, addr, sizeof(struct eth_addr))) { - return 1; - } - BRIDGEIF_READ_PROTECT(lev); - for (i = 0; i < br->num_ports; i++) { - struct netif *portif = br->ports[i].port_netif; - if (portif != NULL) { - if (!memcmp(portif->hwaddr, addr, sizeof(struct eth_addr))) { - BRIDGEIF_READ_UNPROTECT(lev); - return 1; - } - } - } - BRIDGEIF_READ_UNPROTECT(lev); - return 0; -} - -/* Output helper function */ -static err_t -bridgeif_send_to_port(bridgeif_private_t *br, struct pbuf *p, u8_t dstport_idx) -{ - if (dstport_idx < BRIDGEIF_MAX_PORTS) { - /* possibly an external port */ - if (dstport_idx < br->max_ports) { - struct netif *portif = br->ports[dstport_idx].port_netif; - if ((portif != NULL) && (portif->linkoutput != NULL)) { - /* prevent sending out to rx port */ - if (netif_get_index(portif) != p->if_idx) { - if (netif_is_link_up(portif)) { - LWIP_DEBUGF(BRIDGEIF_FW_DEBUG, ("br -> flood(%p:%d) -> %d\n", (void *)p, p->if_idx, netif_get_index(portif))); - return portif->linkoutput(portif, p); - } - } - } - } - } else { - LWIP_ASSERT("invalid port index", dstport_idx == BRIDGEIF_MAX_PORTS); - } - return ERR_OK; -} - -/** Helper function to pass a pbuf to all ports marked in 'dstports' - */ -static err_t -bridgeif_send_to_ports(bridgeif_private_t *br, struct pbuf *p, bridgeif_portmask_t dstports) -{ - err_t err, ret_err = ERR_OK; - u8_t i; - bridgeif_portmask_t mask = 1; - BRIDGEIF_DECL_PROTECT(lev); - BRIDGEIF_READ_PROTECT(lev); - for (i = 0; i < BRIDGEIF_MAX_PORTS; i++, mask = (bridgeif_portmask_t)(mask << 1)) { - if (dstports & mask) { - err = bridgeif_send_to_port(br, p, i); - if (err != ERR_OK) { - ret_err = err; - } - } - } - BRIDGEIF_READ_UNPROTECT(lev); - return ret_err; -} - -/** Output function of the application port of the bridge (the one with an ip address). - * The forwarding port(s) where this pbuf is sent on is/are automatically selected - * from the FDB. - */ -static err_t -bridgeif_output(struct netif *netif, struct pbuf *p) -{ - err_t err; - bridgeif_private_t *br = (bridgeif_private_t *)netif->state; - struct eth_addr *dst = (struct eth_addr *)(p->payload); - - bridgeif_portmask_t dstports = bridgeif_find_dst_ports(br, dst); - err = bridgeif_send_to_ports(br, p, dstports); - - MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len); - if (((u8_t *)p->payload)[0] & 1) { - /* broadcast or multicast packet*/ - MIB2_STATS_NETIF_INC(netif, ifoutnucastpkts); - } else { - /* unicast packet */ - MIB2_STATS_NETIF_INC(netif, ifoutucastpkts); - } - /* increase ifoutdiscards or ifouterrors on error */ - - LINK_STATS_INC(link.xmit); - - return err; -} - -/** The actual bridge input function. Port netif's input is changed to call - * here. This function decides where the frame is forwarded. - */ -static err_t -bridgeif_input(struct pbuf *p, struct netif *netif) -{ - u8_t rx_idx; - bridgeif_portmask_t dstports; - struct eth_addr *src, *dst; - bridgeif_private_t *br; - bridgeif_port_t *port; - if (p == NULL || netif == NULL) { - return ERR_VAL; - } - port = (bridgeif_port_t *)netif_get_client_data(netif, bridgeif_netif_client_id); - LWIP_ASSERT("port data not set", port != NULL); - if (port == NULL || port->bridge == NULL) { - return ERR_VAL; - } - br = (bridgeif_private_t *)port->bridge; - rx_idx = netif_get_index(netif); - /* store receive index in pbuf */ - p->if_idx = rx_idx; - - dst = (struct eth_addr *)p->payload; - src = (struct eth_addr *)(((u8_t *)p->payload) + sizeof(struct eth_addr)); - - if ((src->addr[0] & 1) == 0) { - /* update src for all non-group addresses */ - bridgeif_fdb_update_src(br->fdbd, src, port->port_num); - } - - if (dst->addr[0] & 1) { - /* group address -> flood + cpu? */ - dstports = bridgeif_find_dst_ports(br, dst); - bridgeif_send_to_ports(br, p, dstports); - if (dstports & (1 << BRIDGEIF_MAX_PORTS)) { - /* we pass the reference to ->input or have to free it */ - LWIP_DEBUGF(BRIDGEIF_FW_DEBUG, ("br -> input(%p)\n", (void *)p)); - if (br->netif->input(p, br->netif) != ERR_OK) { - pbuf_free(p); - } - } else { - /* all references done */ - pbuf_free(p); - } - /* always return ERR_OK here to prevent the caller freeing the pbuf */ - return ERR_OK; - } else { - /* is this for one of the local ports? */ - if (bridgeif_is_local_mac(br, dst)) { - /* yes, send to cpu port only */ - LWIP_DEBUGF(BRIDGEIF_FW_DEBUG, ("br -> input(%p)\n", (void *)p)); - return br->netif->input(p, br->netif); - } - - /* get dst port */ - dstports = bridgeif_find_dst_ports(br, dst); - bridgeif_send_to_ports(br, p, dstports); - /* no need to send to cpu, flooding is for external ports only */ - /* by this, we consumed the pbuf */ - pbuf_free(p); - /* always return ERR_OK here to prevent the caller freeing the pbuf */ - return ERR_OK; - } -} - -#if !BRIDGEIF_PORT_NETIFS_OUTPUT_DIRECT -/** Input function for port netifs used to synchronize into tcpip_thread. - */ -static err_t -bridgeif_tcpip_input(struct pbuf *p, struct netif *netif) -{ - return tcpip_inpkt(p, netif, bridgeif_input); -} -#endif /* BRIDGEIF_PORT_NETIFS_OUTPUT_DIRECT */ - -/** - * @ingroup bridgeif - * Initialization function passed to netif_add(). - * - * ATTENTION: A pointer to a @ref bridgeif_initdata_t must be passed as 'state' - * to @ref netif_add when adding the bridge. I supplies MAC address - * and controls memory allocation (number of ports, FDB size). - * - * @param netif the lwip network interface structure for this ethernetif - * @return ERR_OK if the loopif is initialized - * ERR_MEM if private data couldn't be allocated - * any other err_t on error - */ -err_t -bridgeif_init(struct netif *netif) -{ - bridgeif_initdata_t *init_data; - bridgeif_private_t *br; - size_t alloc_len_sizet; - mem_size_t alloc_len; - - LWIP_ASSERT("netif != NULL", (netif != NULL)); - LWIP_ASSERT("bridgeif needs an input callback", (netif->input != NULL)); -#if !BRIDGEIF_PORT_NETIFS_OUTPUT_DIRECT - if (netif->input == tcpip_input) { - LWIP_DEBUGF(BRIDGEIF_DEBUG | LWIP_DBG_ON, ("bridgeif does not need tcpip_input, use netif_input/ethernet_input instead")); - } -#endif - - if (bridgeif_netif_client_id == 0xFF) { - bridgeif_netif_client_id = netif_alloc_client_data_id(); - } - - init_data = (bridgeif_initdata_t *)netif->state; - LWIP_ASSERT("init_data != NULL", (init_data != NULL)); - LWIP_ASSERT("init_data->max_ports <= BRIDGEIF_MAX_PORTS", - init_data->max_ports <= BRIDGEIF_MAX_PORTS); - - alloc_len_sizet = sizeof(bridgeif_private_t) + (init_data->max_ports * sizeof(bridgeif_port_t) + (init_data->max_fdb_static_entries * sizeof(bridgeif_fdb_static_entry_t))); - alloc_len = (mem_size_t)alloc_len_sizet; - LWIP_ASSERT("alloc_len == alloc_len_sizet", alloc_len == alloc_len_sizet); - LWIP_DEBUGF(BRIDGEIF_DEBUG, ("bridgeif_init: allocating %d bytes for private data\n", (int)alloc_len)); - br = (bridgeif_private_t *)mem_calloc(1, alloc_len); - if (br == NULL) { - LWIP_DEBUGF(NETIF_DEBUG, ("bridgeif_init: out of memory\n")); - return ERR_MEM; - } - memcpy(&br->ethaddr, &init_data->ethaddr, sizeof(br->ethaddr)); - br->netif = netif; - - br->max_ports = init_data->max_ports; - br->ports = (bridgeif_port_t *)(br + 1); - - br->max_fdbs_entries = init_data->max_fdb_static_entries; - br->fdbs = (bridgeif_fdb_static_entry_t *)(((u8_t *)(br + 1)) + (init_data->max_ports * sizeof(bridgeif_port_t))); - - br->max_fdbd_entries = init_data->max_fdb_dynamic_entries; - br->fdbd = bridgeif_fdb_init(init_data->max_fdb_dynamic_entries); - if (br->fdbd == NULL) { - LWIP_DEBUGF(NETIF_DEBUG, ("bridgeif_init: out of memory in fdb_init\n")); - mem_free(br); - return ERR_MEM; - } - -#if LWIP_NETIF_HOSTNAME - /* Initialize interface hostname */ - netif->hostname = "lwip"; -#endif /* LWIP_NETIF_HOSTNAME */ - - /* - * Initialize the snmp variables and counters inside the struct netif. - * The last argument should be replaced with your link speed, in units - * of bits per second. - */ - MIB2_INIT_NETIF(netif, snmp_ifType_ethernet_csmacd, 0); - - netif->state = br; - netif->name[0] = IFNAME0; - netif->name[1] = IFNAME1; - /* We directly use etharp_output() here to save a function call. - * You can instead declare your own function an call etharp_output() - * from it if you have to do some checks before sending (e.g. if link - * is available...) */ -#if LWIP_IPV4 - netif->output = etharp_output; -#endif /* LWIP_IPV4 */ -#if LWIP_IPV6 - netif->output_ip6 = ethip6_output; -#endif /* LWIP_IPV6 */ - netif->linkoutput = bridgeif_output; - - /* set MAC hardware address length */ - netif->hwaddr_len = ETH_HWADDR_LEN; - - /* set MAC hardware address */ - memcpy(netif->hwaddr, &br->ethaddr, ETH_HWADDR_LEN); - - /* maximum transfer unit */ - netif->mtu = 1500; - - /* device capabilities */ - /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */ - netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP | NETIF_FLAG_MLD6 | NETIF_FLAG_LINK_UP; - -#if LWIP_IPV6 && LWIP_IPV6_MLD - /* - * For hardware/netifs that implement MAC filtering. - * All-nodes link-local is handled by default, so we must let the hardware know - * to allow multicast packets in. - * Should set mld_mac_filter previously. */ - if (netif->mld_mac_filter != NULL) { - ip6_addr_t ip6_allnodes_ll; - ip6_addr_set_allnodes_linklocal(&ip6_allnodes_ll); - netif->mld_mac_filter(netif, &ip6_allnodes_ll, NETIF_ADD_MAC_FILTER); - } -#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ - - return ERR_OK; -} - -/** - * @ingroup bridgeif - * Add a port to the bridge - */ -err_t -bridgeif_add_port(struct netif *bridgeif, struct netif *portif) -{ - bridgeif_private_t *br; - bridgeif_port_t *port; - - LWIP_ASSERT("bridgeif != NULL", bridgeif != NULL); - LWIP_ASSERT("bridgeif->state != NULL", bridgeif->state != NULL); - LWIP_ASSERT("portif != NULL", portif != NULL); - - if (!(portif->flags & NETIF_FLAG_ETHARP) || !(portif->flags & NETIF_FLAG_ETHERNET)) { - /* can only add ETHERNET/ETHARP interfaces */ - return ERR_VAL; - } - - br = (bridgeif_private_t *)bridgeif->state; - - if (br->num_ports >= br->max_ports) { - return ERR_VAL; - } - port = &br->ports[br->num_ports]; - port->port_netif = portif; - port->port_num = br->num_ports; - port->bridge = br; - br->num_ports++; - - /* let the port call us on input */ -#if BRIDGEIF_PORT_NETIFS_OUTPUT_DIRECT - portif->input = bridgeif_input; -#else - portif->input = bridgeif_tcpip_input; -#endif - /* store pointer to bridge in netif */ - netif_set_client_data(portif, bridgeif_netif_client_id, port); - /* remove ETHARP flag to prevent sending report events on netif-up */ - netif_clear_flags(portif, NETIF_FLAG_ETHARP); - - return ERR_OK; -} - -#endif /* LWIP_NUM_NETIF_CLIENT_DATA */ diff --git a/third-party/lwip-2.1.2/netif/bridgeif_fdb.c b/third-party/lwip-2.1.2/netif/bridgeif_fdb.c deleted file mode 100644 index 6739fc24..00000000 --- a/third-party/lwip-2.1.2/netif/bridgeif_fdb.c +++ /dev/null @@ -1,212 +0,0 @@ -/** - * @file - * lwIP netif implementing an FDB for IEEE 802.1D MAC Bridge - */ - -/* - * Copyright (c) 2017 Simon Goldschmidt. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Simon Goldschmidt - * - */ - -/** - * @defgroup bridgeif_fdb FDB example code - * @ingroup bridgeif - * This file implements an example for an FDB (Forwarding DataBase) - */ - -#include "netif/bridgeif.h" -#include "lwip/sys.h" -#include "lwip/mem.h" -#include "lwip/timeouts.h" -#include - -#define BRIDGEIF_AGE_TIMER_MS 1000 - -#define BR_FDB_TIMEOUT_SEC (60*5) /* 5 minutes FDB timeout */ - -typedef struct bridgeif_dfdb_entry_s { - u8_t used; - u8_t port; - u32_t ts; - struct eth_addr addr; -} bridgeif_dfdb_entry_t; - -typedef struct bridgeif_dfdb_s { - u16_t max_fdb_entries; - bridgeif_dfdb_entry_t *fdb; -} bridgeif_dfdb_t; - -/** - * @ingroup bridgeif_fdb - * A real simple and slow implementation of an auto-learning forwarding database that - * remembers known src mac addresses to know which port to send frames destined for that - * mac address. - * - * ATTENTION: This is meant as an example only, in real-world use, you should - * provide a better implementation :-) - */ -void -bridgeif_fdb_update_src(void *fdb_ptr, struct eth_addr *src_addr, u8_t port_idx) -{ - int i; - bridgeif_dfdb_t *fdb = (bridgeif_dfdb_t *)fdb_ptr; - BRIDGEIF_DECL_PROTECT(lev); - BRIDGEIF_READ_PROTECT(lev); - for (i = 0; i < fdb->max_fdb_entries; i++) { - bridgeif_dfdb_entry_t *e = &fdb->fdb[i]; - if (e->used && e->ts) { - if (!memcmp(&e->addr, src_addr, sizeof(struct eth_addr))) { - LWIP_DEBUGF(BRIDGEIF_FDB_DEBUG, ("br: update src %02x:%02x:%02x:%02x:%02x:%02x (from %d) @ idx %d\n", - src_addr->addr[0], src_addr->addr[1], src_addr->addr[2], src_addr->addr[3], src_addr->addr[4], src_addr->addr[5], - port_idx, i)); - BRIDGEIF_WRITE_PROTECT(lev); - e->ts = BR_FDB_TIMEOUT_SEC; - e->port = port_idx; - BRIDGEIF_WRITE_UNPROTECT(lev); - BRIDGEIF_READ_UNPROTECT(lev); - return; - } - } - } - /* not found, allocate new entry from free */ - for (i = 0; i < fdb->max_fdb_entries; i++) { - bridgeif_dfdb_entry_t *e = &fdb->fdb[i]; - if (!e->used || !e->ts) { - BRIDGEIF_WRITE_PROTECT(lev); - /* check again when protected */ - if (!e->used || !e->ts) { - LWIP_DEBUGF(BRIDGEIF_FDB_DEBUG, ("br: create src %02x:%02x:%02x:%02x:%02x:%02x (from %d) @ idx %d\n", - src_addr->addr[0], src_addr->addr[1], src_addr->addr[2], src_addr->addr[3], src_addr->addr[4], src_addr->addr[5], - port_idx, i)); - memcpy(&e->addr, src_addr, sizeof(struct eth_addr)); - e->ts = BR_FDB_TIMEOUT_SEC; - e->port = port_idx; - e->used = 1; - BRIDGEIF_WRITE_UNPROTECT(lev); - BRIDGEIF_READ_UNPROTECT(lev); - return; - } - BRIDGEIF_WRITE_UNPROTECT(lev); - } - } - BRIDGEIF_READ_UNPROTECT(lev); - /* not found, no free entry -> flood */ -} - -/** - * @ingroup bridgeif_fdb - * Walk our list of auto-learnt fdb entries and return a port to forward or BR_FLOOD if unknown - */ -bridgeif_portmask_t -bridgeif_fdb_get_dst_ports(void *fdb_ptr, struct eth_addr *dst_addr) -{ - int i; - bridgeif_dfdb_t *fdb = (bridgeif_dfdb_t *)fdb_ptr; - BRIDGEIF_DECL_PROTECT(lev); - BRIDGEIF_READ_PROTECT(lev); - for (i = 0; i < fdb->max_fdb_entries; i++) { - bridgeif_dfdb_entry_t *e = &fdb->fdb[i]; - if (e->used && e->ts) { - if (!memcmp(&e->addr, dst_addr, sizeof(struct eth_addr))) { - bridgeif_portmask_t ret = (bridgeif_portmask_t)(1 << e->port); - BRIDGEIF_READ_UNPROTECT(lev); - return ret; - } - } - } - BRIDGEIF_READ_UNPROTECT(lev); - return BR_FLOOD; -} - -/** - * @ingroup bridgeif_fdb - * Aging implementation of our simple fdb - */ -static void -bridgeif_fdb_age_one_second(void *fdb_ptr) -{ - int i; - bridgeif_dfdb_t *fdb; - BRIDGEIF_DECL_PROTECT(lev); - - fdb = (bridgeif_dfdb_t *)fdb_ptr; - BRIDGEIF_READ_PROTECT(lev); - - for (i = 0; i < fdb->max_fdb_entries; i++) { - bridgeif_dfdb_entry_t *e = &fdb->fdb[i]; - if (e->used && e->ts) { - BRIDGEIF_WRITE_PROTECT(lev); - /* check again when protected */ - if (e->used && e->ts) { - if (--e->ts == 0) { - e->used = 0; - } - } - BRIDGEIF_WRITE_UNPROTECT(lev); - } - } - BRIDGEIF_READ_UNPROTECT(lev); -} - -/** Timer callback for fdb aging, called once per second */ -static void -bridgeif_age_tmr(void *arg) -{ - bridgeif_dfdb_t *fdb = (bridgeif_dfdb_t *)arg; - - LWIP_ASSERT("invalid arg", arg != NULL); - - bridgeif_fdb_age_one_second(fdb); - sys_timeout(BRIDGEIF_AGE_TIMER_MS, bridgeif_age_tmr, arg); -} - -/** - * @ingroup bridgeif_fdb - * Init our simple fdb list - */ -void * -bridgeif_fdb_init(u16_t max_fdb_entries) -{ - bridgeif_dfdb_t *fdb; - size_t alloc_len_sizet = sizeof(bridgeif_dfdb_t) + (max_fdb_entries * sizeof(bridgeif_dfdb_entry_t)); - mem_size_t alloc_len = (mem_size_t)alloc_len_sizet; - LWIP_ASSERT("alloc_len == alloc_len_sizet", alloc_len == alloc_len_sizet); - LWIP_DEBUGF(BRIDGEIF_DEBUG, ("bridgeif_fdb_init: allocating %d bytes for private FDB data\n", (int)alloc_len)); - fdb = (bridgeif_dfdb_t *)mem_calloc(1, alloc_len); - if (fdb == NULL) { - return NULL; - } - fdb->max_fdb_entries = max_fdb_entries; - fdb->fdb = (bridgeif_dfdb_entry_t *)(fdb + 1); - - sys_timeout(BRIDGEIF_AGE_TIMER_MS, bridgeif_age_tmr, fdb); - - return fdb; -} diff --git a/third-party/lwip-2.1.2/netif/ethernet.c b/third-party/lwip-2.1.2/netif/ethernet.c deleted file mode 100644 index dd171e28..00000000 --- a/third-party/lwip-2.1.2/netif/ethernet.c +++ /dev/null @@ -1,321 +0,0 @@ -/** - * @file - * Ethernet common functions - * - * @defgroup ethernet Ethernet - * @ingroup callbackstyle_api - */ - -/* - * Copyright (c) 2001-2003 Swedish Institute of Computer Science. - * Copyright (c) 2003-2004 Leon Woestenberg - * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#include "lwip/opt.h" - -#if LWIP_ARP || LWIP_ETHERNET - -#include "netif/ethernet.h" -#include "lwip/def.h" -#include "lwip/stats.h" -#include "lwip/etharp.h" -#include "lwip/ip.h" -#include "lwip/snmp.h" - -#include - -#include "netif/ppp/ppp_opts.h" -#if PPPOE_SUPPORT -#include "netif/ppp/pppoe.h" -#endif /* PPPOE_SUPPORT */ - -#ifdef LWIP_HOOK_FILENAME -#include LWIP_HOOK_FILENAME -#endif - -const struct eth_addr ethbroadcast = {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}; -const struct eth_addr ethzero = {{0, 0, 0, 0, 0, 0}}; - -/** - * @ingroup lwip_nosys - * Process received ethernet frames. Using this function instead of directly - * calling ip_input and passing ARP frames through etharp in ethernetif_input, - * the ARP cache is protected from concurrent access.\n - * Don't call directly, pass to netif_add() and call netif->input(). - * - * @param p the received packet, p->payload pointing to the ethernet header - * @param netif the network interface on which the packet was received - * - * @see LWIP_HOOK_UNKNOWN_ETH_PROTOCOL - * @see ETHARP_SUPPORT_VLAN - * @see LWIP_HOOK_VLAN_CHECK - */ -err_t -ethernet_input(struct pbuf *p, struct netif *netif) -{ - struct eth_hdr *ethhdr; - u16_t type; -#if LWIP_ARP || ETHARP_SUPPORT_VLAN || LWIP_IPV6 - u16_t next_hdr_offset = SIZEOF_ETH_HDR; -#endif /* LWIP_ARP || ETHARP_SUPPORT_VLAN */ - - LWIP_ASSERT_CORE_LOCKED(); - - if (p->len <= SIZEOF_ETH_HDR) { - /* a packet with only an ethernet header (or less) is not valid for us */ - ETHARP_STATS_INC(etharp.proterr); - ETHARP_STATS_INC(etharp.drop); - MIB2_STATS_NETIF_INC(netif, ifinerrors); - goto free_and_return; - } - - if (p->if_idx == NETIF_NO_INDEX) { - p->if_idx = netif_get_index(netif); - } - - /* points to packet payload, which starts with an Ethernet header */ - ethhdr = (struct eth_hdr *)p->payload; - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, - ("ethernet_input: dest:%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F", src:%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F", type:%"X16_F"\n", - (unsigned char)ethhdr->dest.addr[0], (unsigned char)ethhdr->dest.addr[1], (unsigned char)ethhdr->dest.addr[2], - (unsigned char)ethhdr->dest.addr[3], (unsigned char)ethhdr->dest.addr[4], (unsigned char)ethhdr->dest.addr[5], - (unsigned char)ethhdr->src.addr[0], (unsigned char)ethhdr->src.addr[1], (unsigned char)ethhdr->src.addr[2], - (unsigned char)ethhdr->src.addr[3], (unsigned char)ethhdr->src.addr[4], (unsigned char)ethhdr->src.addr[5], - lwip_htons(ethhdr->type))); - - type = ethhdr->type; -#if ETHARP_SUPPORT_VLAN - if (type == PP_HTONS(ETHTYPE_VLAN)) { - struct eth_vlan_hdr *vlan = (struct eth_vlan_hdr *)(((char *)ethhdr) + SIZEOF_ETH_HDR); - next_hdr_offset = SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR; - if (p->len <= SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR) { - /* a packet with only an ethernet/vlan header (or less) is not valid for us */ - ETHARP_STATS_INC(etharp.proterr); - ETHARP_STATS_INC(etharp.drop); - MIB2_STATS_NETIF_INC(netif, ifinerrors); - goto free_and_return; - } -#if defined(LWIP_HOOK_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK_FN) /* if not, allow all VLANs */ -#ifdef LWIP_HOOK_VLAN_CHECK - if (!LWIP_HOOK_VLAN_CHECK(netif, ethhdr, vlan)) { -#elif defined(ETHARP_VLAN_CHECK_FN) - if (!ETHARP_VLAN_CHECK_FN(ethhdr, vlan)) { -#elif defined(ETHARP_VLAN_CHECK) - if (VLAN_ID(vlan) != ETHARP_VLAN_CHECK) { -#endif - /* silently ignore this packet: not for our VLAN */ - pbuf_free(p); - return ERR_OK; - } -#endif /* defined(LWIP_HOOK_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK_FN) */ - type = vlan->tpid; - } -#endif /* ETHARP_SUPPORT_VLAN */ - -#if LWIP_ARP_FILTER_NETIF - netif = LWIP_ARP_FILTER_NETIF_FN(p, netif, lwip_htons(type)); -#endif /* LWIP_ARP_FILTER_NETIF*/ - - if (ethhdr->dest.addr[0] & 1) { - /* this might be a multicast or broadcast packet */ - if (ethhdr->dest.addr[0] == LL_IP4_MULTICAST_ADDR_0) { -#if LWIP_IPV4 - if ((ethhdr->dest.addr[1] == LL_IP4_MULTICAST_ADDR_1) && - (ethhdr->dest.addr[2] == LL_IP4_MULTICAST_ADDR_2)) { - /* mark the pbuf as link-layer multicast */ - p->flags |= PBUF_FLAG_LLMCAST; - } -#endif /* LWIP_IPV4 */ - } -#if LWIP_IPV6 - else if ((ethhdr->dest.addr[0] == LL_IP6_MULTICAST_ADDR_0) && - (ethhdr->dest.addr[1] == LL_IP6_MULTICAST_ADDR_1)) { - /* mark the pbuf as link-layer multicast */ - p->flags |= PBUF_FLAG_LLMCAST; - } -#endif /* LWIP_IPV6 */ - else if (eth_addr_cmp(ðhdr->dest, ðbroadcast)) { - /* mark the pbuf as link-layer broadcast */ - p->flags |= PBUF_FLAG_LLBCAST; - } - } - - switch (type) { -#if LWIP_IPV4 && LWIP_ARP - /* IP packet? */ - case PP_HTONS(ETHTYPE_IP): - if (!(netif->flags & NETIF_FLAG_ETHARP)) { - goto free_and_return; - } - /* skip Ethernet header (min. size checked above) */ - if (pbuf_remove_header(p, next_hdr_offset)) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, - ("ethernet_input: IPv4 packet dropped, too short (%"U16_F"/%"U16_F")\n", - p->tot_len, next_hdr_offset)); - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("Can't move over header in packet")); - goto free_and_return; - } else { - /* pass to IP layer */ - ip4_input(p, netif); - } - break; - - case PP_HTONS(ETHTYPE_ARP): - if (!(netif->flags & NETIF_FLAG_ETHARP)) { - goto free_and_return; - } - /* skip Ethernet header (min. size checked above) */ - if (pbuf_remove_header(p, next_hdr_offset)) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, - ("ethernet_input: ARP response packet dropped, too short (%"U16_F"/%"U16_F")\n", - p->tot_len, next_hdr_offset)); - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("Can't move over header in packet")); - ETHARP_STATS_INC(etharp.lenerr); - ETHARP_STATS_INC(etharp.drop); - goto free_and_return; - } else { - /* pass p to ARP module */ - etharp_input(p, netif); - } - break; -#endif /* LWIP_IPV4 && LWIP_ARP */ -#if PPPOE_SUPPORT - case PP_HTONS(ETHTYPE_PPPOEDISC): /* PPP Over Ethernet Discovery Stage */ - pppoe_disc_input(netif, p); - break; - - case PP_HTONS(ETHTYPE_PPPOE): /* PPP Over Ethernet Session Stage */ - pppoe_data_input(netif, p); - break; -#endif /* PPPOE_SUPPORT */ - -#if LWIP_IPV6 - case PP_HTONS(ETHTYPE_IPV6): /* IPv6 */ - /* skip Ethernet header */ - if ((p->len < next_hdr_offset) || pbuf_remove_header(p, next_hdr_offset)) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, - ("ethernet_input: IPv6 packet dropped, too short (%"U16_F"/%"U16_F")\n", - p->tot_len, next_hdr_offset)); - goto free_and_return; - } else { - /* pass to IPv6 layer */ - ip6_input(p, netif); - } - break; -#endif /* LWIP_IPV6 */ - - default: -#ifdef LWIP_HOOK_UNKNOWN_ETH_PROTOCOL - if (LWIP_HOOK_UNKNOWN_ETH_PROTOCOL(p, netif) == ERR_OK) { - break; - } -#endif - ETHARP_STATS_INC(etharp.proterr); - ETHARP_STATS_INC(etharp.drop); - MIB2_STATS_NETIF_INC(netif, ifinunknownprotos); - goto free_and_return; - } - - /* This means the pbuf is freed or consumed, - so the caller doesn't have to free it again */ - return ERR_OK; - -free_and_return: - pbuf_free(p); - return ERR_OK; -} - -/** - * @ingroup ethernet - * Send an ethernet packet on the network using netif->linkoutput(). - * The ethernet header is filled in before sending. - * - * @see LWIP_HOOK_VLAN_SET - * - * @param netif the lwIP network interface on which to send the packet - * @param p the packet to send. pbuf layer must be @ref PBUF_LINK. - * @param src the source MAC address to be copied into the ethernet header - * @param dst the destination MAC address to be copied into the ethernet header - * @param eth_type ethernet type (@ref lwip_ieee_eth_type) - * @return ERR_OK if the packet was sent, any other err_t on failure - */ -err_t -ethernet_output(struct netif * netif, struct pbuf * p, - const struct eth_addr * src, const struct eth_addr * dst, - u16_t eth_type) { - struct eth_hdr *ethhdr; - u16_t eth_type_be = lwip_htons(eth_type); - -#if ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) - s32_t vlan_prio_vid = LWIP_HOOK_VLAN_SET(netif, p, src, dst, eth_type); - if (vlan_prio_vid >= 0) { - struct eth_vlan_hdr *vlanhdr; - - LWIP_ASSERT("prio_vid must be <= 0xFFFF", vlan_prio_vid <= 0xFFFF); - - if (pbuf_add_header(p, SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR) != 0) { - goto pbuf_header_failed; - } - vlanhdr = (struct eth_vlan_hdr *)(((u8_t *)p->payload) + SIZEOF_ETH_HDR); - vlanhdr->tpid = eth_type_be; - vlanhdr->prio_vid = lwip_htons((u16_t)vlan_prio_vid); - - eth_type_be = PP_HTONS(ETHTYPE_VLAN); - } else -#endif /* ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) */ - { - if (pbuf_add_header(p, SIZEOF_ETH_HDR) != 0) { - goto pbuf_header_failed; - } - } - - LWIP_ASSERT_CORE_LOCKED(); - - ethhdr = (struct eth_hdr *)p->payload; - ethhdr->type = eth_type_be; - SMEMCPY(ðhdr->dest, dst, ETH_HWADDR_LEN); - SMEMCPY(ðhdr->src, src, ETH_HWADDR_LEN); - - LWIP_ASSERT("netif->hwaddr_len must be 6 for ethernet_output!", - (netif->hwaddr_len == ETH_HWADDR_LEN)); - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, - ("ethernet_output: sending packet %p\n", (void *)p)); - - /* send the packet */ - return netif->linkoutput(netif, p); - -pbuf_header_failed: - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, - ("ethernet_output: could not allocate room for header.\n")); - LINK_STATS_INC(link.lenerr); - return ERR_BUF; -} - -#endif /* LWIP_ARP || LWIP_ETHERNET */ diff --git a/third-party/lwip-2.1.2/netif/lowpan6.c b/third-party/lwip-2.1.2/netif/lowpan6.c deleted file mode 100644 index 7f0d2767..00000000 --- a/third-party/lwip-2.1.2/netif/lowpan6.c +++ /dev/null @@ -1,920 +0,0 @@ -/** - * @file - * - * 6LowPAN output for IPv6. Uses ND tables for link-layer addressing. Fragments packets to 6LowPAN units. - * - * This implementation aims to conform to IEEE 802.15.4(-2015), RFC 4944 and RFC 6282. - * @todo: RFC 6775. - */ - -/* - * Copyright (c) 2015 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -/** - * @defgroup sixlowpan 6LoWPAN (RFC4944) - * @ingroup netifs - * 6LowPAN netif implementation - */ - -#include "netif/lowpan6.h" - -#if LWIP_IPV6 - -#include "lwip/ip.h" -#include "lwip/pbuf.h" -#include "lwip/ip_addr.h" -#include "lwip/netif.h" -#include "lwip/nd6.h" -#include "lwip/mem.h" -#include "lwip/udp.h" -#include "lwip/tcpip.h" -#include "lwip/snmp.h" -#include "netif/ieee802154.h" - -#include - -#if LWIP_6LOWPAN_802154_HW_CRC -#define LWIP_6LOWPAN_DO_CALC_CRC(buf, len) 0 -#else -#define LWIP_6LOWPAN_DO_CALC_CRC(buf, len) LWIP_6LOWPAN_CALC_CRC(buf, len) -#endif - -/** This is a helper struct for reassembly of fragments - * (IEEE 802.15.4 limits to 127 bytes) - */ -struct lowpan6_reass_helper { - struct lowpan6_reass_helper *next_packet; - struct pbuf *reass; - struct pbuf *frags; - u8_t timer; - struct lowpan6_link_addr sender_addr; - u16_t datagram_size; - u16_t datagram_tag; -}; - -/** This struct keeps track of per-netif state */ -struct lowpan6_ieee802154_data { - /** fragment reassembly list */ - struct lowpan6_reass_helper *reass_list; -#if LWIP_6LOWPAN_NUM_CONTEXTS > 0 - /** address context for compression */ - ip6_addr_t lowpan6_context[LWIP_6LOWPAN_NUM_CONTEXTS]; -#endif - /** Datagram Tag for fragmentation */ - u16_t tx_datagram_tag; - /** local PAN ID for IEEE 802.15.4 header */ - u16_t ieee_802154_pan_id; - /** Sequence Number for IEEE 802.15.4 transmission */ - u8_t tx_frame_seq_num; -}; - -/* Maximum frame size is 127 bytes minus CRC size */ -#define LOWPAN6_MAX_PAYLOAD (127 - 2) - -/** Currently, this state is global, since there's only one 6LoWPAN netif */ -static struct lowpan6_ieee802154_data lowpan6_data; - -#if LWIP_6LOWPAN_NUM_CONTEXTS > 0 -#define LWIP_6LOWPAN_CONTEXTS(netif) lowpan6_data.lowpan6_context -#else -#define LWIP_6LOWPAN_CONTEXTS(netif) NULL -#endif - -static const struct lowpan6_link_addr ieee_802154_broadcast = {2, {0xff, 0xff}}; - -#if LWIP_6LOWPAN_INFER_SHORT_ADDRESS -static struct lowpan6_link_addr short_mac_addr = {2, {0, 0}}; -#endif /* LWIP_6LOWPAN_INFER_SHORT_ADDRESS */ - -/* IEEE 802.15.4 specific functions: */ - -/** Write the IEEE 802.15.4 header that encapsulates the 6LoWPAN frame. - * Src and dst PAN IDs are filled with the ID set by @ref lowpan6_set_pan_id. - * - * Since the length is variable: - * @returns the header length - */ -static u8_t -lowpan6_write_iee802154_header(struct ieee_802154_hdr *hdr, const struct lowpan6_link_addr *src, - const struct lowpan6_link_addr *dst) -{ - u8_t ieee_header_len; - u8_t *buffer; - u8_t i; - u16_t fc; - - fc = IEEE_802154_FC_FT_DATA; /* send data packet (2003 frame version) */ - fc |= IEEE_802154_FC_PANID_COMPR; /* set PAN ID compression, for now src and dst PANs are equal */ - if (dst != &ieee_802154_broadcast) { - fc |= IEEE_802154_FC_ACK_REQ; /* data packet, no broadcast: ack required. */ - } - if (dst->addr_len == 2) { - fc |= IEEE_802154_FC_DST_ADDR_MODE_SHORT; - } else { - LWIP_ASSERT("invalid dst address length", dst->addr_len == 8); - fc |= IEEE_802154_FC_DST_ADDR_MODE_EXT; - } - if (src->addr_len == 2) { - fc |= IEEE_802154_FC_SRC_ADDR_MODE_SHORT; - } else { - LWIP_ASSERT("invalid src address length", src->addr_len == 8); - fc |= IEEE_802154_FC_SRC_ADDR_MODE_EXT; - } - hdr->frame_control = fc; - hdr->sequence_number = lowpan6_data.tx_frame_seq_num++; - hdr->destination_pan_id = lowpan6_data.ieee_802154_pan_id; /* pan id */ - - buffer = (u8_t *)hdr; - ieee_header_len = 5; - i = dst->addr_len; - /* reverse memcpy of dst addr */ - while (i-- > 0) { - buffer[ieee_header_len++] = dst->addr[i]; - } - /* Source PAN ID skipped due to PAN ID Compression */ - i = src->addr_len; - /* reverse memcpy of src addr */ - while (i-- > 0) { - buffer[ieee_header_len++] = src->addr[i]; - } - return ieee_header_len; -} - -/** Parse the IEEE 802.15.4 header from a pbuf. - * If successful, the header is hidden from the pbuf. - * - * PAN IDs and seuqence number are not checked - * - * @param p input pbuf, p->payload pointing at the IEEE 802.15.4 header - * @param src pointer to source address filled from the header - * @param dest pointer to destination address filled from the header - * @returns ERR_OK if successful - */ -static err_t -lowpan6_parse_iee802154_header(struct pbuf *p, struct lowpan6_link_addr *src, - struct lowpan6_link_addr *dest) -{ - u8_t *puc; - s8_t i; - u16_t frame_control, addr_mode; - u16_t datagram_offset; - - /* Parse IEEE 802.15.4 header */ - puc = (u8_t *)p->payload; - frame_control = puc[0] | (puc[1] << 8); - datagram_offset = 2; - if (frame_control & IEEE_802154_FC_SEQNO_SUPPR) { - if (IEEE_802154_FC_FRAME_VERSION_GET(frame_control) <= 1) { - /* sequence number suppressed, this is not valid for versions 0/1 */ - return ERR_VAL; - } - } else { - datagram_offset++; - } - datagram_offset += 2; /* Skip destination PAN ID */ - addr_mode = frame_control & IEEE_802154_FC_DST_ADDR_MODE_MASK; - if (addr_mode == IEEE_802154_FC_DST_ADDR_MODE_EXT) { - /* extended address (64 bit) */ - dest->addr_len = 8; - /* reverse memcpy: */ - for (i = 0; i < 8; i++) { - dest->addr[i] = puc[datagram_offset + 7 - i]; - } - datagram_offset += 8; - } else if (addr_mode == IEEE_802154_FC_DST_ADDR_MODE_SHORT) { - /* short address (16 bit) */ - dest->addr_len = 2; - /* reverse memcpy: */ - dest->addr[0] = puc[datagram_offset + 1]; - dest->addr[1] = puc[datagram_offset]; - datagram_offset += 2; - } else { - /* unsupported address mode (do we need "no address"?) */ - return ERR_VAL; - } - - if (!(frame_control & IEEE_802154_FC_PANID_COMPR)) { - /* No PAN ID compression, skip source PAN ID */ - datagram_offset += 2; - } - - addr_mode = frame_control & IEEE_802154_FC_SRC_ADDR_MODE_MASK; - if (addr_mode == IEEE_802154_FC_SRC_ADDR_MODE_EXT) { - /* extended address (64 bit) */ - src->addr_len = 8; - /* reverse memcpy: */ - for (i = 0; i < 8; i++) { - src->addr[i] = puc[datagram_offset + 7 - i]; - } - datagram_offset += 8; - } else if (addr_mode == IEEE_802154_FC_DST_ADDR_MODE_SHORT) { - /* short address (16 bit) */ - src->addr_len = 2; - src->addr[0] = puc[datagram_offset + 1]; - src->addr[1] = puc[datagram_offset]; - datagram_offset += 2; - } else { - /* unsupported address mode (do we need "no address"?) */ - return ERR_VAL; - } - - /* hide IEEE802.15.4 header. */ - if (pbuf_remove_header(p, datagram_offset)) { - return ERR_VAL; - } - return ERR_OK; -} - -/** Calculate the 16-bit CRC as required by IEEE 802.15.4 */ -u16_t -lowpan6_calc_crc(const void* buf, u16_t len) -{ -#define CCITT_POLY_16 0x8408U - u16_t i; - u8_t b; - u16_t crc = 0; - const u8_t* p = (const u8_t*)buf; - - for (i = 0; i < len; i++) { - u8_t data = *p; - for (b = 0U; b < 8U; b++) { - if (((data ^ crc) & 1) != 0) { - crc = (u16_t)((crc >> 1) ^ CCITT_POLY_16); - } else { - crc = (u16_t)(crc >> 1); - } - data = (u8_t)(data >> 1); - } - p++; - } - return crc; -} - -/* Fragmentation specific functions: */ - -static void -free_reass_datagram(struct lowpan6_reass_helper *lrh) -{ - if (lrh->reass) { - pbuf_free(lrh->reass); - } - if (lrh->frags) { - pbuf_free(lrh->frags); - } - mem_free(lrh); -} - -/** - * Removes a datagram from the reassembly queue. - **/ -static void -dequeue_datagram(struct lowpan6_reass_helper *lrh, struct lowpan6_reass_helper *prev) -{ - if (lowpan6_data.reass_list == lrh) { - lowpan6_data.reass_list = lowpan6_data.reass_list->next_packet; - } else { - /* it wasn't the first, so it must have a valid 'prev' */ - LWIP_ASSERT("sanity check linked list", prev != NULL); - prev->next_packet = lrh->next_packet; - } -} - -/** - * Periodic timer for 6LowPAN functions: - * - * - Remove incomplete/old packets - */ -void -lowpan6_tmr(void) -{ - struct lowpan6_reass_helper *lrh, *lrh_next, *lrh_prev = NULL; - - lrh = lowpan6_data.reass_list; - while (lrh != NULL) { - lrh_next = lrh->next_packet; - if ((--lrh->timer) == 0) { - dequeue_datagram(lrh, lrh_prev); - free_reass_datagram(lrh); - } else { - lrh_prev = lrh; - } - lrh = lrh_next; - } -} - -/* - * Encapsulates data into IEEE 802.15.4 frames. - * Fragments an IPv6 datagram into 6LowPAN units, which fit into IEEE 802.15.4 frames. - * If configured, will compress IPv6 and or UDP headers. - * */ -static err_t -lowpan6_frag(struct netif *netif, struct pbuf *p, const struct lowpan6_link_addr *src, const struct lowpan6_link_addr *dst) -{ - struct pbuf *p_frag; - u16_t frag_len, remaining_len, max_data_len; - u8_t *buffer; - u8_t ieee_header_len; - u8_t lowpan6_header_len; - u8_t hidden_header_len; - u16_t crc; - u16_t datagram_offset; - err_t err = ERR_IF; - - LWIP_ASSERT("lowpan6_frag: netif->linkoutput not set", netif->linkoutput != NULL); - - /* We'll use a dedicated pbuf for building 6LowPAN fragments. */ - p_frag = pbuf_alloc(PBUF_RAW, 127, PBUF_RAM); - if (p_frag == NULL) { - MIB2_STATS_NETIF_INC(netif, ifoutdiscards); - return ERR_MEM; - } - LWIP_ASSERT("this needs a pbuf in one piece", p_frag->len == p_frag->tot_len); - - /* Write IEEE 802.15.4 header. */ - buffer = (u8_t *)p_frag->payload; - ieee_header_len = lowpan6_write_iee802154_header((struct ieee_802154_hdr *)buffer, src, dst); - LWIP_ASSERT("ieee_header_len < p_frag->len", ieee_header_len < p_frag->len); - -#if LWIP_6LOWPAN_IPHC - /* Perform 6LowPAN IPv6 header compression according to RFC 6282 */ - /* do the header compression (this does NOT copy any non-compressed data) */ - err = lowpan6_compress_headers(netif, (u8_t *)p->payload, p->len, - &buffer[ieee_header_len], p_frag->len - ieee_header_len, &lowpan6_header_len, - &hidden_header_len, LWIP_6LOWPAN_CONTEXTS(netif), src, dst); - if (err != ERR_OK) { - MIB2_STATS_NETIF_INC(netif, ifoutdiscards); - pbuf_free(p_frag); - return err; - } - pbuf_remove_header(p, hidden_header_len); - -#else /* LWIP_6LOWPAN_IPHC */ - /* Send uncompressed IPv6 header with appropriate dispatch byte. */ - lowpan6_header_len = 1; - buffer[ieee_header_len] = 0x41; /* IPv6 dispatch */ -#endif /* LWIP_6LOWPAN_IPHC */ - - /* Calculate remaining packet length */ - remaining_len = p->tot_len; - - if (remaining_len > 0x7FF) { - MIB2_STATS_NETIF_INC(netif, ifoutdiscards); - /* datagram_size must fit into 11 bit */ - pbuf_free(p_frag); - return ERR_VAL; - } - - /* Fragment, or 1 packet? */ - max_data_len = LOWPAN6_MAX_PAYLOAD - ieee_header_len - lowpan6_header_len; - if (remaining_len > max_data_len) { - u16_t data_len; - /* We must move the 6LowPAN header to make room for the FRAG header. */ - memmove(&buffer[ieee_header_len + 4], &buffer[ieee_header_len], lowpan6_header_len); - - /* Now we need to fragment the packet. FRAG1 header first */ - buffer[ieee_header_len] = 0xc0 | (((p->tot_len + hidden_header_len) >> 8) & 0x7); - buffer[ieee_header_len + 1] = (p->tot_len + hidden_header_len) & 0xff; - - lowpan6_data.tx_datagram_tag++; - buffer[ieee_header_len + 2] = (lowpan6_data.tx_datagram_tag >> 8) & 0xff; - buffer[ieee_header_len + 3] = lowpan6_data.tx_datagram_tag & 0xff; - - /* Fragment follows. */ - data_len = (max_data_len - 4) & 0xf8; - frag_len = data_len + lowpan6_header_len; - - pbuf_copy_partial(p, buffer + ieee_header_len + lowpan6_header_len + 4, frag_len - lowpan6_header_len, 0); - remaining_len -= frag_len - lowpan6_header_len; - /* datagram offset holds the offset before compression */ - datagram_offset = frag_len - lowpan6_header_len + hidden_header_len; - LWIP_ASSERT("datagram offset must be a multiple of 8", (datagram_offset & 7) == 0); - - /* Calculate frame length */ - p_frag->len = p_frag->tot_len = ieee_header_len + 4 + frag_len + 2; /* add 2 bytes for crc*/ - - /* 2 bytes CRC */ - crc = LWIP_6LOWPAN_DO_CALC_CRC(p_frag->payload, p_frag->len - 2); - pbuf_take_at(p_frag, &crc, 2, p_frag->len - 2); - - /* send the packet */ - MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p_frag->tot_len); - LWIP_DEBUGF(LWIP_LOWPAN6_DEBUG | LWIP_DBG_TRACE, ("lowpan6_send: sending packet %p\n", (void *)p)); - err = netif->linkoutput(netif, p_frag); - - while ((remaining_len > 0) && (err == ERR_OK)) { - struct ieee_802154_hdr *hdr = (struct ieee_802154_hdr *)buffer; - /* new frame, new seq num for ACK */ - hdr->sequence_number = lowpan6_data.tx_frame_seq_num++; - - buffer[ieee_header_len] |= 0x20; /* Change FRAG1 to FRAGN */ - - LWIP_ASSERT("datagram offset must be a multiple of 8", (datagram_offset & 7) == 0); - buffer[ieee_header_len + 4] = (u8_t)(datagram_offset >> 3); /* datagram offset in FRAGN header (datagram_offset is max. 11 bit) */ - - frag_len = (127 - ieee_header_len - 5 - 2) & 0xf8; - if (frag_len > remaining_len) { - frag_len = remaining_len; - } - - pbuf_copy_partial(p, buffer + ieee_header_len + 5, frag_len, p->tot_len - remaining_len); - remaining_len -= frag_len; - datagram_offset += frag_len; - - /* Calculate frame length */ - p_frag->len = p_frag->tot_len = frag_len + 5 + ieee_header_len + 2; - - /* 2 bytes CRC */ - crc = LWIP_6LOWPAN_DO_CALC_CRC(p_frag->payload, p_frag->len - 2); - pbuf_take_at(p_frag, &crc, 2, p_frag->len - 2); - - /* send the packet */ - MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p_frag->tot_len); - LWIP_DEBUGF(LWIP_LOWPAN6_DEBUG | LWIP_DBG_TRACE, ("lowpan6_send: sending packet %p\n", (void *)p)); - err = netif->linkoutput(netif, p_frag); - } - } else { - /* It fits in one frame. */ - frag_len = remaining_len; - - /* Copy IPv6 packet */ - pbuf_copy_partial(p, buffer + ieee_header_len + lowpan6_header_len, frag_len, 0); - remaining_len = 0; - - /* Calculate frame length */ - p_frag->len = p_frag->tot_len = frag_len + lowpan6_header_len + ieee_header_len + 2; - LWIP_ASSERT("", p_frag->len <= 127); - - /* 2 bytes CRC */ - crc = LWIP_6LOWPAN_DO_CALC_CRC(p_frag->payload, p_frag->len - 2); - pbuf_take_at(p_frag, &crc, 2, p_frag->len - 2); - - /* send the packet */ - MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p_frag->tot_len); - LWIP_DEBUGF(LWIP_LOWPAN6_DEBUG | LWIP_DBG_TRACE, ("lowpan6_send: sending packet %p\n", (void *)p)); - err = netif->linkoutput(netif, p_frag); - } - - pbuf_free(p_frag); - - return err; -} - -/** - * @ingroup sixlowpan - * Set context - */ -err_t -lowpan6_set_context(u8_t idx, const ip6_addr_t *context) -{ -#if LWIP_6LOWPAN_NUM_CONTEXTS > 0 - if (idx >= LWIP_6LOWPAN_NUM_CONTEXTS) { - return ERR_ARG; - } - - IP6_ADDR_ZONECHECK(context); - - ip6_addr_set(&lowpan6_data.lowpan6_context[idx], context); - - return ERR_OK; -#else - LWIP_UNUSED_ARG(idx); - LWIP_UNUSED_ARG(context); - return ERR_ARG; -#endif -} - -#if LWIP_6LOWPAN_INFER_SHORT_ADDRESS -/** - * @ingroup sixlowpan - * Set short address - */ -err_t -lowpan6_set_short_addr(u8_t addr_high, u8_t addr_low) -{ - short_mac_addr.addr[0] = addr_high; - short_mac_addr.addr[1] = addr_low; - - return ERR_OK; -} -#endif /* LWIP_6LOWPAN_INFER_SHORT_ADDRESS */ - -/* Create IEEE 802.15.4 address from netif address */ -static err_t -lowpan6_hwaddr_to_addr(struct netif *netif, struct lowpan6_link_addr *addr) -{ - addr->addr_len = 8; - if (netif->hwaddr_len == 8) { - LWIP_ERROR("NETIF_MAX_HWADDR_LEN >= 8 required", sizeof(netif->hwaddr) >= 8, return ERR_VAL;); - SMEMCPY(addr->addr, netif->hwaddr, 8); - } else if (netif->hwaddr_len == 6) { - /* Copy from MAC-48 */ - SMEMCPY(addr->addr, netif->hwaddr, 3); - addr->addr[3] = addr->addr[4] = 0xff; - SMEMCPY(&addr->addr[5], &netif->hwaddr[3], 3); - } else { - /* Invalid address length, don't know how to convert this */ - return ERR_VAL; - } - return ERR_OK; -} - -/** - * @ingroup sixlowpan - * Resolve and fill-in IEEE 802.15.4 address header for outgoing IPv6 packet. - * - * Perform Header Compression and fragment if necessary. - * - * @param netif The lwIP network interface which the IP packet will be sent on. - * @param q The pbuf(s) containing the IP packet to be sent. - * @param ip6addr The IP address of the packet destination. - * - * @return err_t - */ -err_t -lowpan6_output(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr) -{ - err_t result; - const u8_t *hwaddr; - struct lowpan6_link_addr src, dest; -#if LWIP_6LOWPAN_INFER_SHORT_ADDRESS - ip6_addr_t ip6_src; - struct ip6_hdr *ip6_hdr; -#endif /* LWIP_6LOWPAN_INFER_SHORT_ADDRESS */ - -#if LWIP_6LOWPAN_INFER_SHORT_ADDRESS - /* Check if we can compress source address (use aligned copy) */ - ip6_hdr = (struct ip6_hdr *)q->payload; - ip6_addr_copy_from_packed(ip6_src, ip6_hdr->src); - ip6_addr_assign_zone(&ip6_src, IP6_UNICAST, netif); - if (lowpan6_get_address_mode(&ip6_src, &short_mac_addr) == 3) { - src.addr_len = 2; - src.addr[0] = short_mac_addr.addr[0]; - src.addr[1] = short_mac_addr.addr[1]; - } else -#endif /* LWIP_6LOWPAN_INFER_SHORT_ADDRESS */ - { - result = lowpan6_hwaddr_to_addr(netif, &src); - if (result != ERR_OK) { - MIB2_STATS_NETIF_INC(netif, ifoutdiscards); - return result; - } - } - - /* multicast destination IP address? */ - if (ip6_addr_ismulticast(ip6addr)) { - MIB2_STATS_NETIF_INC(netif, ifoutnucastpkts); - /* We need to send to the broadcast address.*/ - return lowpan6_frag(netif, q, &src, &ieee_802154_broadcast); - } - - /* We have a unicast destination IP address */ - /* @todo anycast? */ - -#if LWIP_6LOWPAN_INFER_SHORT_ADDRESS - if (src.addr_len == 2) { - /* If source address was compressable to short_mac_addr, and dest has same subnet and - * is also compressable to 2-bytes, assume we can infer dest as a short address too. */ - dest.addr_len = 2; - dest.addr[0] = ((u8_t *)q->payload)[38]; - dest.addr[1] = ((u8_t *)q->payload)[39]; - if ((src.addr_len == 2) && (ip6_addr_netcmp_zoneless(&ip6_hdr->src, &ip6_hdr->dest)) && - (lowpan6_get_address_mode(ip6addr, &dest) == 3)) { - MIB2_STATS_NETIF_INC(netif, ifoutucastpkts); - return lowpan6_frag(netif, q, &src, &dest); - } - } -#endif /* LWIP_6LOWPAN_INFER_SHORT_ADDRESS */ - - /* Ask ND6 what to do with the packet. */ - result = nd6_get_next_hop_addr_or_queue(netif, q, ip6addr, &hwaddr); - if (result != ERR_OK) { - MIB2_STATS_NETIF_INC(netif, ifoutdiscards); - return result; - } - - /* If no hardware address is returned, nd6 has queued the packet for later. */ - if (hwaddr == NULL) { - return ERR_OK; - } - - /* Send out the packet using the returned hardware address. */ - dest.addr_len = netif->hwaddr_len; - /* XXX: Inferring the length of the source address from the destination address - * is not correct for IEEE 802.15.4, but currently we don't get this information - * from the neighbor cache */ - SMEMCPY(dest.addr, hwaddr, netif->hwaddr_len); - MIB2_STATS_NETIF_INC(netif, ifoutucastpkts); - return lowpan6_frag(netif, q, &src, &dest); -} -/** - * @ingroup sixlowpan - * NETIF input function: don't free the input pbuf when returning != ERR_OK! - */ -err_t -lowpan6_input(struct pbuf *p, struct netif *netif) -{ - u8_t *puc, b; - s8_t i; - struct lowpan6_link_addr src, dest; - u16_t datagram_size = 0; - u16_t datagram_offset, datagram_tag; - struct lowpan6_reass_helper *lrh, *lrh_next, *lrh_prev = NULL; - - if (p == NULL) { - return ERR_OK; - } - - MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len); - - if (p->len != p->tot_len) { - /* for now, this needs a pbuf in one piece */ - goto lowpan6_input_discard; - } - - if (lowpan6_parse_iee802154_header(p, &src, &dest) != ERR_OK) { - goto lowpan6_input_discard; - } - - /* Check dispatch. */ - puc = (u8_t *)p->payload; - - b = *puc; - if ((b & 0xf8) == 0xc0) { - /* FRAG1 dispatch. add this packet to reassembly list. */ - datagram_size = ((u16_t)(puc[0] & 0x07) << 8) | (u16_t)puc[1]; - datagram_tag = ((u16_t)puc[2] << 8) | (u16_t)puc[3]; - - /* check for duplicate */ - lrh = lowpan6_data.reass_list; - while (lrh != NULL) { - uint8_t discard = 0; - lrh_next = lrh->next_packet; - if ((lrh->sender_addr.addr_len == src.addr_len) && - (memcmp(lrh->sender_addr.addr, src.addr, src.addr_len) == 0)) { - /* address match with packet in reassembly. */ - if ((datagram_tag == lrh->datagram_tag) && (datagram_size == lrh->datagram_size)) { - /* duplicate fragment. */ - goto lowpan6_input_discard; - } else { - /* We are receiving the start of a new datagram. Discard old one (incomplete). */ - discard = 1; - } - } - if (discard) { - dequeue_datagram(lrh, lrh_prev); - free_reass_datagram(lrh); - } else { - lrh_prev = lrh; - } - /* Check next datagram in queue. */ - lrh = lrh_next; - } - - pbuf_remove_header(p, 4); /* hide frag1 dispatch */ - - lrh = (struct lowpan6_reass_helper *) mem_malloc(sizeof(struct lowpan6_reass_helper)); - if (lrh == NULL) { - goto lowpan6_input_discard; - } - - lrh->sender_addr.addr_len = src.addr_len; - for (i = 0; i < src.addr_len; i++) { - lrh->sender_addr.addr[i] = src.addr[i]; - } - lrh->datagram_size = datagram_size; - lrh->datagram_tag = datagram_tag; - lrh->frags = NULL; - if (*(u8_t *)p->payload == 0x41) { - /* This is a complete IPv6 packet, just skip dispatch byte. */ - pbuf_remove_header(p, 1); /* hide dispatch byte. */ - lrh->reass = p; - } else if ((*(u8_t *)p->payload & 0xe0 ) == 0x60) { - lrh->reass = lowpan6_decompress(p, datagram_size, LWIP_6LOWPAN_CONTEXTS(netif), &src, &dest); - if (lrh->reass == NULL) { - /* decompression failed */ - mem_free(lrh); - goto lowpan6_input_discard; - } - } - /* TODO: handle the case where we already have FRAGN received */ - lrh->next_packet = lowpan6_data.reass_list; - lrh->timer = 2; - lowpan6_data.reass_list = lrh; - - return ERR_OK; - } else if ((b & 0xf8) == 0xe0) { - /* FRAGN dispatch, find packet being reassembled. */ - datagram_size = ((u16_t)(puc[0] & 0x07) << 8) | (u16_t)puc[1]; - datagram_tag = ((u16_t)puc[2] << 8) | (u16_t)puc[3]; - datagram_offset = (u16_t)puc[4] << 3; - pbuf_remove_header(p, 4); /* hide frag1 dispatch but keep datagram offset for reassembly */ - - for (lrh = lowpan6_data.reass_list; lrh != NULL; lrh_prev = lrh, lrh = lrh->next_packet) { - if ((lrh->sender_addr.addr_len == src.addr_len) && - (memcmp(lrh->sender_addr.addr, src.addr, src.addr_len) == 0) && - (datagram_tag == lrh->datagram_tag) && - (datagram_size == lrh->datagram_size)) { - break; - } - } - if (lrh == NULL) { - /* rogue fragment */ - goto lowpan6_input_discard; - } - /* Insert new pbuf into list of fragments. Each fragment is a pbuf, - this only works for unchained pbufs. */ - LWIP_ASSERT("p->next == NULL", p->next == NULL); - if (lrh->reass != NULL) { - /* FRAG1 already received, check this offset against first len */ - if (datagram_offset < lrh->reass->len) { - /* fragment overlap, discard old fragments */ - dequeue_datagram(lrh, lrh_prev); - free_reass_datagram(lrh); - goto lowpan6_input_discard; - } - } - if (lrh->frags == NULL) { - /* first FRAGN */ - lrh->frags = p; - } else { - /* find the correct place to insert */ - struct pbuf *q, *last; - u16_t new_frag_len = p->len - 1; /* p->len includes datagram_offset byte */ - for (q = lrh->frags, last = NULL; q != NULL; last = q, q = q->next) { - u16_t q_datagram_offset = ((u8_t *)q->payload)[0] << 3; - u16_t q_frag_len = q->len - 1; - if (datagram_offset < q_datagram_offset) { - if (datagram_offset + new_frag_len > q_datagram_offset) { - /* overlap, discard old fragments */ - dequeue_datagram(lrh, lrh_prev); - free_reass_datagram(lrh); - goto lowpan6_input_discard; - } - /* insert here */ - break; - } else if (datagram_offset == q_datagram_offset) { - if (q_frag_len != new_frag_len) { - /* fragment mismatch, discard old fragments */ - dequeue_datagram(lrh, lrh_prev); - free_reass_datagram(lrh); - goto lowpan6_input_discard; - } - /* duplicate, ignore */ - pbuf_free(p); - return ERR_OK; - } - } - /* insert fragment */ - if (last == NULL) { - lrh->frags = p; - } else { - last->next = p; - p->next = q; - } - } - /* check if all fragments were received */ - if (lrh->reass) { - u16_t offset = lrh->reass->len; - struct pbuf *q; - for (q = lrh->frags; q != NULL; q = q->next) { - u16_t q_datagram_offset = ((u8_t *)q->payload)[0] << 3; - if (q_datagram_offset != offset) { - /* not complete, wait for more fragments */ - return ERR_OK; - } - offset += q->len - 1; - } - if (offset == datagram_size) { - /* all fragments received, combine pbufs */ - u16_t datagram_left = datagram_size - lrh->reass->len; - for (q = lrh->frags; q != NULL; q = q->next) { - /* hide datagram_offset byte now */ - pbuf_remove_header(q, 1); - q->tot_len = datagram_left; - datagram_left -= q->len; - } - LWIP_ASSERT("datagram_left == 0", datagram_left == 0); - q = lrh->reass; - q->tot_len = datagram_size; - q->next = lrh->frags; - lrh->frags = NULL; - lrh->reass = NULL; - dequeue_datagram(lrh, lrh_prev); - mem_free(lrh); - - /* @todo: distinguish unicast/multicast */ - MIB2_STATS_NETIF_INC(netif, ifinucastpkts); - return ip6_input(q, netif); - } - } - /* pbuf enqueued, waiting for more fragments */ - return ERR_OK; - } else { - if (b == 0x41) { - /* This is a complete IPv6 packet, just skip dispatch byte. */ - pbuf_remove_header(p, 1); /* hide dispatch byte. */ - } else if ((b & 0xe0 ) == 0x60) { - /* IPv6 headers are compressed using IPHC. */ - p = lowpan6_decompress(p, datagram_size, LWIP_6LOWPAN_CONTEXTS(netif), &src, &dest); - if (p == NULL) { - MIB2_STATS_NETIF_INC(netif, ifindiscards); - return ERR_OK; - } - } else { - goto lowpan6_input_discard; - } - - /* @todo: distinguish unicast/multicast */ - MIB2_STATS_NETIF_INC(netif, ifinucastpkts); - - return ip6_input(p, netif); - } -lowpan6_input_discard: - MIB2_STATS_NETIF_INC(netif, ifindiscards); - pbuf_free(p); - /* always return ERR_OK here to prevent the caller freeing the pbuf */ - return ERR_OK; -} - -/** - * @ingroup sixlowpan - */ -err_t -lowpan6_if_init(struct netif *netif) -{ - netif->name[0] = 'L'; - netif->name[1] = '6'; - netif->output_ip6 = lowpan6_output; - - MIB2_INIT_NETIF(netif, snmp_ifType_other, 0); - - /* maximum transfer unit */ - netif->mtu = 1280; - - /* broadcast capability */ - netif->flags = NETIF_FLAG_BROADCAST /* | NETIF_FLAG_LOWPAN6 */; - - return ERR_OK; -} - -/** - * @ingroup sixlowpan - * Set PAN ID - */ -err_t -lowpan6_set_pan_id(u16_t pan_id) -{ - lowpan6_data.ieee_802154_pan_id = pan_id; - - return ERR_OK; -} - -#if !NO_SYS -/** - * @ingroup sixlowpan - * Pass a received packet to tcpip_thread for input processing - * - * @param p the received packet, p->payload pointing to the - * IEEE 802.15.4 header. - * @param inp the network interface on which the packet was received - */ -err_t -tcpip_6lowpan_input(struct pbuf *p, struct netif *inp) -{ - return tcpip_inpkt(p, inp, lowpan6_input); -} -#endif /* !NO_SYS */ - -#endif /* LWIP_IPV6 */ diff --git a/third-party/lwip-2.1.2/netif/lowpan6_ble.c b/third-party/lwip-2.1.2/netif/lowpan6_ble.c deleted file mode 100644 index d89816d3..00000000 --- a/third-party/lwip-2.1.2/netif/lowpan6_ble.c +++ /dev/null @@ -1,447 +0,0 @@ -/** - * @file - * 6LowPAN over BLE output for IPv6 (RFC7668). -*/ - -/* - * Copyright (c) 2017 Benjamin Aigner - * Copyright (c) 2015 Inico Technologies Ltd. , Author: Ivan Delamer - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Benjamin Aigner - * - * Based on the original 6lowpan implementation of lwIP ( @see 6lowpan.c) - */ - - -/** - * @defgroup rfc7668if 6LoWPAN over BLE (RFC7668) - * @ingroup netifs - * This file implements a RFC7668 implementation for 6LoWPAN over - * Bluetooth Low Energy. The specification is very similar to 6LoWPAN, - * so most of the code is re-used. - * Compared to 6LoWPAN, much functionality is already implemented in - * lower BLE layers (fragmenting, session management,...). - * - * Usage: - * - add this netif - * - don't add IPv4 addresses (no IPv4 support in RFC7668), pass 'NULL','NULL','NULL' - * - use the BLE to EUI64 conversation util to create an IPv6 link-local address from the BLE MAC (@ref ble_addr_to_eui64) - * - input function: @ref rfc7668_input - * - set the link output function, which transmits output data to an established L2CAP channel - * - If data arrives (HCI event "L2CAP_DATA_PACKET"): - * - allocate a @ref PBUF_RAW buffer - * - let the pbuf struct point to the incoming data or copy it to the buffer - * - call netif->input - * - * @todo: - * - further testing - * - support compression contexts - * - support multiple addresses - * - support multicast - * - support neighbor discovery - */ - - -#include "netif/lowpan6_ble.h" - -#if LWIP_IPV6 - -#include "lwip/ip.h" -#include "lwip/pbuf.h" -#include "lwip/ip_addr.h" -#include "lwip/netif.h" -#include "lwip/nd6.h" -#include "lwip/mem.h" -#include "lwip/udp.h" -#include "lwip/tcpip.h" -#include "lwip/snmp.h" - -#include - -#if LWIP_6LOWPAN_NUM_CONTEXTS > 0 -/** context memory, containing IPv6 addresses */ -static ip6_addr_t rfc7668_context[LWIP_6LOWPAN_NUM_CONTEXTS]; -#else -#define rfc7668_context NULL -#endif - -static struct lowpan6_link_addr rfc7668_local_addr; -static struct lowpan6_link_addr rfc7668_peer_addr; - -/** - * @ingroup rfc7668if - * convert BT address to EUI64 addr - * - * This method converts a Bluetooth MAC address to an EUI64 address, - * which is used within IPv6 communication - * - * @param dst IPv6 destination space - * @param src BLE MAC address source - * @param public_addr If the LWIP_RFC7668_LINUX_WORKAROUND_PUBLIC_ADDRESS - * option is set, bit 0x02 will be set if param=0 (no public addr); cleared otherwise - * - * @see LWIP_RFC7668_LINUX_WORKAROUND_PUBLIC_ADDRESS - */ -void -ble_addr_to_eui64(uint8_t *dst, const uint8_t *src, int public_addr) -{ - /* according to RFC7668 ch 3.2.2. */ - memcpy(dst, src, 3); - dst[3] = 0xFF; - dst[4] = 0xFE; - memcpy(&dst[5], &src[3], 3); -#if LWIP_RFC7668_LINUX_WORKAROUND_PUBLIC_ADDRESS - if(public_addr) { - dst[0] &= ~0x02; - } else { - dst[0] |= 0x02; - } -#else - LWIP_UNUSED_ARG(public_addr); -#endif -} - -/** - * @ingroup rfc7668if - * convert EUI64 address to Bluetooth MAC addr - * - * This method converts an EUI64 address to a Bluetooth MAC address, - * - * @param dst BLE MAC address destination - * @param src IPv6 source - * - */ -void -eui64_to_ble_addr(uint8_t *dst, const uint8_t *src) -{ - /* according to RFC7668 ch 3.2.2. */ - memcpy(dst,src,3); - memcpy(&dst[3],&src[5],3); -} - -/** Set an address used for stateful compression. - * This expects an address of 6 or 8 bytes. - */ -static err_t -rfc7668_set_addr(struct lowpan6_link_addr *addr, const u8_t *in_addr, size_t in_addr_len, int is_mac_48, int is_public_addr) -{ - if ((in_addr == NULL) || (addr == NULL)) { - return ERR_VAL; - } - if (is_mac_48) { - if (in_addr_len != 6) { - return ERR_VAL; - } - addr->addr_len = 8; - ble_addr_to_eui64(addr->addr, in_addr, is_public_addr); - } else { - if (in_addr_len != 8) { - return ERR_VAL; - } - addr->addr_len = 8; - memcpy(addr->addr, in_addr, 8); - } - return ERR_OK; -} - - -/** Set the local address used for stateful compression. - * This expects an address of 8 bytes. - */ -err_t -rfc7668_set_local_addr_eui64(struct netif *netif, const u8_t *local_addr, size_t local_addr_len) -{ - /* netif not used for now, the address is stored globally... */ - LWIP_UNUSED_ARG(netif); - return rfc7668_set_addr(&rfc7668_local_addr, local_addr, local_addr_len, 0, 0); -} - -/** Set the local address used for stateful compression. - * This expects an address of 6 bytes. - */ -err_t -rfc7668_set_local_addr_mac48(struct netif *netif, const u8_t *local_addr, size_t local_addr_len, int is_public_addr) -{ - /* netif not used for now, the address is stored globally... */ - LWIP_UNUSED_ARG(netif); - return rfc7668_set_addr(&rfc7668_local_addr, local_addr, local_addr_len, 1, is_public_addr); -} - -/** Set the peer address used for stateful compression. - * This expects an address of 8 bytes. - */ -err_t -rfc7668_set_peer_addr_eui64(struct netif *netif, const u8_t *peer_addr, size_t peer_addr_len) -{ - /* netif not used for now, the address is stored globally... */ - LWIP_UNUSED_ARG(netif); - return rfc7668_set_addr(&rfc7668_peer_addr, peer_addr, peer_addr_len, 0, 0); -} - -/** Set the peer address used for stateful compression. - * This expects an address of 6 bytes. - */ -err_t -rfc7668_set_peer_addr_mac48(struct netif *netif, const u8_t *peer_addr, size_t peer_addr_len, int is_public_addr) -{ - /* netif not used for now, the address is stored globally... */ - LWIP_UNUSED_ARG(netif); - return rfc7668_set_addr(&rfc7668_peer_addr, peer_addr, peer_addr_len, 1, is_public_addr); -} - -/** Encapsulate IPv6 frames for BLE transmission - * - * This method implements the IPv6 header compression: - * *) According to RFC6282 - * *) See Figure 2, contains base format of bit positions - * *) Fragmentation not necessary (done at L2CAP layer of BLE) - * @note Currently the pbuf allocation uses 256 bytes. If longer packets are used (possible due to MTU=1480Bytes), increase it here! - * - * @param p Pbuf struct, containing the payload data - * @param netif Output network interface. Should be of RFC7668 type - * - * @return Same as netif->output. - */ -static err_t -rfc7668_compress(struct netif *netif, struct pbuf *p) -{ - struct pbuf *p_frag; - u16_t remaining_len; - u8_t *buffer; - u8_t lowpan6_header_len; - u8_t hidden_header_len; - err_t err; - - LWIP_ASSERT("lowpan6_frag: netif->linkoutput not set", netif->linkoutput != NULL); - -#if LWIP_6LOWPAN_IPHC - - /* We'll use a dedicated pbuf for building BLE fragments. - * We'll over-allocate it by the bytes saved for header compression. - */ - p_frag = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM); - if (p_frag == NULL) { - MIB2_STATS_NETIF_INC(netif, ifoutdiscards); - return ERR_MEM; - } - LWIP_ASSERT("this needs a pbuf in one piece", p_frag->len == p_frag->tot_len); - - /* Write IP6 header (with IPHC). */ - buffer = (u8_t*)p_frag->payload; - - err = lowpan6_compress_headers(netif, (u8_t *)p->payload, p->len, buffer, p_frag->len, - &lowpan6_header_len, &hidden_header_len, rfc7668_context, &rfc7668_local_addr, &rfc7668_peer_addr); - if (err != ERR_OK) { - MIB2_STATS_NETIF_INC(netif, ifoutdiscards); - pbuf_free(p_frag); - return err; - } - pbuf_remove_header(p, hidden_header_len); - - /* Calculate remaining packet length */ - remaining_len = p->tot_len; - - /* Copy IPv6 packet */ - pbuf_copy_partial(p, buffer + lowpan6_header_len, remaining_len, 0); - - /* Calculate frame length */ - p_frag->len = p_frag->tot_len = remaining_len + lowpan6_header_len; - - /* send the packet */ - MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p_frag->tot_len); - LWIP_DEBUGF(LWIP_LOWPAN6_DEBUG|LWIP_DBG_TRACE, ("rfc7668_output: sending packet %p\n", (void *)p)); - err = netif->linkoutput(netif, p_frag); - - pbuf_free(p_frag); - - return err; -#else /* LWIP_6LOWPAN_IPHC */ - /* 6LoWPAN over BLE requires IPHC! */ - return ERR_IF; -#endif/* LWIP_6LOWPAN_IPHC */ -} - -/** - * @ingroup rfc7668if - * Set context id IPv6 address - * - * Store one IPv6 address to a given context id. - * - * @param idx Context id - * @param context IPv6 addr for this context - * - * @return ERR_OK (if everything is fine), ERR_ARG (if the context id is out of range), ERR_VAL (if contexts disabled) - */ -err_t -rfc7668_set_context(u8_t idx, const ip6_addr_t *context) -{ -#if LWIP_6LOWPAN_NUM_CONTEXTS > 0 - /* check if the ID is possible */ - if (idx >= LWIP_6LOWPAN_NUM_CONTEXTS) { - return ERR_ARG; - } - /* copy IPv6 address to context storage */ - ip6_addr_set(&rfc7668_context[idx], context); - return ERR_OK; -#else - LWIP_UNUSED_ARG(idx); - LWIP_UNUSED_ARG(context); - return ERR_VAL; -#endif -} - -/** - * @ingroup rfc7668if - * Compress outgoing IPv6 packet and pass it on to netif->linkoutput - * - * @param netif The lwIP network interface which the IP packet will be sent on. - * @param q The pbuf(s) containing the IP packet to be sent. - * @param ip6addr The IP address of the packet destination. - * - * @return See rfc7668_compress - */ -err_t -rfc7668_output(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr) -{ - /* dst ip6addr is not used here, we only have one peer */ - LWIP_UNUSED_ARG(ip6addr); - - return rfc7668_compress(netif, q); -} - -/** - * @ingroup rfc7668if - * Process a received raw payload from an L2CAP channel - * - * @param p the received packet, p->payload pointing to the - * IPv6 header (maybe compressed) - * @param netif the network interface on which the packet was received - * - * @return ERR_OK if everything was fine - */ -err_t -rfc7668_input(struct pbuf * p, struct netif *netif) -{ - u8_t * puc; - - MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len); - - /* Load first header byte */ - puc = (u8_t*)p->payload; - - /* no IP header compression */ - if (*puc == 0x41) { - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("Completed packet, removing dispatch: 0x%2x \n", *puc)); - /* This is a complete IPv6 packet, just skip header byte. */ - pbuf_remove_header(p, 1); - /* IPHC header compression */ - } else if ((*puc & 0xe0 )== 0x60) { - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("Completed packet, decompress dispatch: 0x%2x \n", *puc)); - /* IPv6 headers are compressed using IPHC. */ - p = lowpan6_decompress(p, 0, rfc7668_context, &rfc7668_peer_addr, &rfc7668_local_addr); - /* if no pbuf is returned, handle as discarded packet */ - if (p == NULL) { - MIB2_STATS_NETIF_INC(netif, ifindiscards); - return ERR_OK; - } - /* invalid header byte, discard */ - } else { - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("Completed packet, discarding: 0x%2x \n", *puc)); - MIB2_STATS_NETIF_INC(netif, ifindiscards); - pbuf_free(p); - return ERR_OK; - } - /* @todo: distinguish unicast/multicast */ - MIB2_STATS_NETIF_INC(netif, ifinucastpkts); - -#if LWIP_RFC7668_IP_UNCOMPRESSED_DEBUG - { - u16_t i; - LWIP_DEBUGF(LWIP_RFC7668_IP_UNCOMPRESSED_DEBUG, ("IPv6 payload:\n")); - for (i = 0; i < p->len; i++) { - if ((i%4)==0) { - LWIP_DEBUGF(LWIP_RFC7668_IP_UNCOMPRESSED_DEBUG, ("\n")); - } - LWIP_DEBUGF(LWIP_RFC7668_IP_UNCOMPRESSED_DEBUG, ("%2X ", *((uint8_t *)p->payload+i))); - } - LWIP_DEBUGF(LWIP_RFC7668_IP_UNCOMPRESSED_DEBUG, ("\np->len: %d\n", p->len)); - } -#endif - /* pass data to ip6_input */ - return ip6_input(p, netif); -} - -/** - * @ingroup rfc7668if - * Initialize the netif - * - * No flags are used (broadcast not possible, not ethernet, ...) - * The shortname for this netif is "BT" - * - * @param netif the network interface to be initialized as RFC7668 netif - * - * @return ERR_OK if everything went fine - */ -err_t -rfc7668_if_init(struct netif *netif) -{ - netif->name[0] = 'b'; - netif->name[1] = 't'; - /* local function as IPv6 output */ - netif->output_ip6 = rfc7668_output; - - MIB2_INIT_NETIF(netif, snmp_ifType_other, 0); - - /* maximum transfer unit, set according to RFC7668 ch2.4 */ - netif->mtu = 1280; - - /* no flags set (no broadcast, ethernet,...)*/ - netif->flags = 0; - - /* everything fine */ - return ERR_OK; -} - -#if !NO_SYS -/** - * Pass a received packet to tcpip_thread for input processing - * - * @param p the received packet, p->payload pointing to the - * IEEE 802.15.4 header. - * @param inp the network interface on which the packet was received - * - * @return see @ref tcpip_inpkt, same return values - */ -err_t -tcpip_rfc7668_input(struct pbuf *p, struct netif *inp) -{ - /* send data to upper layer, return the result */ - return tcpip_inpkt(p, inp, rfc7668_input); -} -#endif /* !NO_SYS */ - -#endif /* LWIP_IPV6 */ diff --git a/third-party/lwip-2.1.2/netif/lowpan6_common.c b/third-party/lwip-2.1.2/netif/lowpan6_common.c deleted file mode 100644 index baea206a..00000000 --- a/third-party/lwip-2.1.2/netif/lowpan6_common.c +++ /dev/null @@ -1,841 +0,0 @@ -/** - * @file - * - * Common 6LowPAN routines for IPv6. Uses ND tables for link-layer addressing. Fragments packets to 6LowPAN units. - * - * This implementation aims to conform to IEEE 802.15.4(-2015), RFC 4944 and RFC 6282. - * @todo: RFC 6775. - */ - -/* - * Copyright (c) 2015 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -/** - * @defgroup sixlowpan 6LoWPAN (RFC4944) - * @ingroup netifs - * 6LowPAN netif implementation - */ - -#include "netif/lowpan6_common.h" - -#if LWIP_IPV6 - -#include "lwip/ip.h" -#include "lwip/pbuf.h" -#include "lwip/ip_addr.h" -#include "lwip/netif.h" -#include "lwip/udp.h" - -#include - -/* Determine compression mode for unicast address. */ -s8_t -lowpan6_get_address_mode(const ip6_addr_t *ip6addr, const struct lowpan6_link_addr *mac_addr) -{ - if (mac_addr->addr_len == 2) { - if ((ip6addr->addr[2] == (u32_t)PP_HTONL(0x000000ff)) && - ((ip6addr->addr[3] & PP_HTONL(0xffff0000)) == PP_NTOHL(0xfe000000))) { - if ((ip6addr->addr[3] & PP_HTONL(0x0000ffff)) == lwip_ntohl((mac_addr->addr[0] << 8) | mac_addr->addr[1])) { - return 3; - } - } - } else if (mac_addr->addr_len == 8) { - if ((ip6addr->addr[2] == lwip_ntohl(((mac_addr->addr[0] ^ 2) << 24) | (mac_addr->addr[1] << 16) | mac_addr->addr[2] << 8 | mac_addr->addr[3])) && - (ip6addr->addr[3] == lwip_ntohl((mac_addr->addr[4] << 24) | (mac_addr->addr[5] << 16) | mac_addr->addr[6] << 8 | mac_addr->addr[7]))) { - return 3; - } - } - - if ((ip6addr->addr[2] == PP_HTONL(0x000000ffUL)) && - ((ip6addr->addr[3] & PP_HTONL(0xffff0000)) == PP_NTOHL(0xfe000000UL))) { - return 2; - } - - return 1; -} - -#if LWIP_6LOWPAN_IPHC - -/* Determine compression mode for multicast address. */ -static s8_t -lowpan6_get_address_mode_mc(const ip6_addr_t *ip6addr) -{ - if ((ip6addr->addr[0] == PP_HTONL(0xff020000)) && - (ip6addr->addr[1] == 0) && - (ip6addr->addr[2] == 0) && - ((ip6addr->addr[3] & PP_HTONL(0xffffff00)) == 0)) { - return 3; - } else if (((ip6addr->addr[0] & PP_HTONL(0xff00ffff)) == PP_HTONL(0xff000000)) && - (ip6addr->addr[1] == 0)) { - if ((ip6addr->addr[2] == 0) && - ((ip6addr->addr[3] & PP_HTONL(0xff000000)) == 0)) { - return 2; - } else if ((ip6addr->addr[2] & PP_HTONL(0xffffff00)) == 0) { - return 1; - } - } - - return 0; -} - -#if LWIP_6LOWPAN_NUM_CONTEXTS > 0 -static s8_t -lowpan6_context_lookup(const ip6_addr_t *lowpan6_contexts, const ip6_addr_t *ip6addr) -{ - s8_t i; - - for (i = 0; i < LWIP_6LOWPAN_NUM_CONTEXTS; i++) { - if (ip6_addr_netcmp(&lowpan6_contexts[i], ip6addr)) { - return i; - } - } - return -1; -} -#endif /* LWIP_6LOWPAN_NUM_CONTEXTS > 0 */ - -/* - * Compress IPv6 and/or UDP headers. - * */ -err_t -lowpan6_compress_headers(struct netif *netif, u8_t *inbuf, size_t inbuf_size, u8_t *outbuf, size_t outbuf_size, - u8_t *lowpan6_header_len_out, u8_t *hidden_header_len_out, ip6_addr_t *lowpan6_contexts, - const struct lowpan6_link_addr *src, const struct lowpan6_link_addr *dst) -{ - u8_t *buffer, *inptr; - u8_t lowpan6_header_len; - u8_t hidden_header_len = 0; - s8_t i; - struct ip6_hdr *ip6hdr; - ip_addr_t ip6src, ip6dst; - - LWIP_ASSERT("netif != NULL", netif != NULL); - LWIP_ASSERT("inbuf != NULL", inbuf != NULL); - LWIP_ASSERT("outbuf != NULL", outbuf != NULL); - LWIP_ASSERT("lowpan6_header_len_out != NULL", lowpan6_header_len_out != NULL); - LWIP_ASSERT("hidden_header_len_out != NULL", hidden_header_len_out != NULL); - - /* Perform 6LowPAN IPv6 header compression according to RFC 6282 */ - buffer = outbuf; - inptr = inbuf; - - if (inbuf_size < IP6_HLEN) { - /* input buffer too short */ - return ERR_VAL; - } - if (outbuf_size < IP6_HLEN) { - /* output buffer too short for worst case */ - return ERR_MEM; - } - - /* Point to ip6 header and align copies of src/dest addresses. */ - ip6hdr = (struct ip6_hdr *)inptr; - ip_addr_copy_from_ip6_packed(ip6dst, ip6hdr->dest); - ip6_addr_assign_zone(ip_2_ip6(&ip6dst), IP6_UNKNOWN, netif); - ip_addr_copy_from_ip6_packed(ip6src, ip6hdr->src); - ip6_addr_assign_zone(ip_2_ip6(&ip6src), IP6_UNKNOWN, netif); - - /* Basic length of 6LowPAN header, set dispatch and clear fields. */ - lowpan6_header_len = 2; - buffer[0] = 0x60; - buffer[1] = 0; - - /* Determine whether there will be a Context Identifier Extension byte or not. - * If so, set it already. */ -#if LWIP_6LOWPAN_NUM_CONTEXTS > 0 - buffer[2] = 0; - - i = lowpan6_context_lookup(lowpan6_contexts, ip_2_ip6(&ip6src)); - if (i >= 0) { - /* Stateful source address compression. */ - buffer[1] |= 0x40; - buffer[2] |= (i & 0x0f) << 4; - } - - i = lowpan6_context_lookup(lowpan6_contexts, ip_2_ip6(&ip6dst)); - if (i >= 0) { - /* Stateful destination address compression. */ - buffer[1] |= 0x04; - buffer[2] |= i & 0x0f; - } - - if (buffer[2] != 0x00) { - /* Context identifier extension byte is appended. */ - buffer[1] |= 0x80; - lowpan6_header_len++; - } -#else /* LWIP_6LOWPAN_NUM_CONTEXTS > 0 */ - LWIP_UNUSED_ARG(lowpan6_contexts); -#endif /* LWIP_6LOWPAN_NUM_CONTEXTS > 0 */ - - /* Determine TF field: Traffic Class, Flow Label */ - if (IP6H_FL(ip6hdr) == 0) { - /* Flow label is elided. */ - buffer[0] |= 0x10; - if (IP6H_TC(ip6hdr) == 0) { - /* Traffic class (ECN+DSCP) elided too. */ - buffer[0] |= 0x08; - } else { - /* Traffic class (ECN+DSCP) appended. */ - buffer[lowpan6_header_len++] = IP6H_TC(ip6hdr); - } - } else { - if (((IP6H_TC(ip6hdr) & 0x3f) == 0)) { - /* DSCP portion of Traffic Class is elided, ECN and FL are appended (3 bytes) */ - buffer[0] |= 0x08; - - buffer[lowpan6_header_len] = IP6H_TC(ip6hdr) & 0xc0; - buffer[lowpan6_header_len++] |= (IP6H_FL(ip6hdr) >> 16) & 0x0f; - buffer[lowpan6_header_len++] = (IP6H_FL(ip6hdr) >> 8) & 0xff; - buffer[lowpan6_header_len++] = IP6H_FL(ip6hdr) & 0xff; - } else { - /* Traffic class and flow label are appended (4 bytes) */ - buffer[lowpan6_header_len++] = IP6H_TC(ip6hdr); - buffer[lowpan6_header_len++] = (IP6H_FL(ip6hdr) >> 16) & 0x0f; - buffer[lowpan6_header_len++] = (IP6H_FL(ip6hdr) >> 8) & 0xff; - buffer[lowpan6_header_len++] = IP6H_FL(ip6hdr) & 0xff; - } - } - - /* Compress NH? - * Only if UDP for now. @todo support other NH compression. */ - if (IP6H_NEXTH(ip6hdr) == IP6_NEXTH_UDP) { - buffer[0] |= 0x04; - } else { - /* append nexth. */ - buffer[lowpan6_header_len++] = IP6H_NEXTH(ip6hdr); - } - - /* Compress hop limit? */ - if (IP6H_HOPLIM(ip6hdr) == 255) { - buffer[0] |= 0x03; - } else if (IP6H_HOPLIM(ip6hdr) == 64) { - buffer[0] |= 0x02; - } else if (IP6H_HOPLIM(ip6hdr) == 1) { - buffer[0] |= 0x01; - } else { - /* append hop limit */ - buffer[lowpan6_header_len++] = IP6H_HOPLIM(ip6hdr); - } - - /* Compress source address */ - if (((buffer[1] & 0x40) != 0) || - (ip6_addr_islinklocal(ip_2_ip6(&ip6src)))) { - /* Context-based or link-local source address compression. */ - i = lowpan6_get_address_mode(ip_2_ip6(&ip6src), src); - buffer[1] |= (i & 0x03) << 4; - if (i == 1) { - MEMCPY(buffer + lowpan6_header_len, inptr + 16, 8); - lowpan6_header_len += 8; - } else if (i == 2) { - MEMCPY(buffer + lowpan6_header_len, inptr + 22, 2); - lowpan6_header_len += 2; - } - } else if (ip6_addr_isany(ip_2_ip6(&ip6src))) { - /* Special case: mark SAC and leave SAM=0 */ - buffer[1] |= 0x40; - } else { - /* Append full address. */ - MEMCPY(buffer + lowpan6_header_len, inptr + 8, 16); - lowpan6_header_len += 16; - } - - /* Compress destination address */ - if (ip6_addr_ismulticast(ip_2_ip6(&ip6dst))) { - /* @todo support stateful multicast address compression */ - - buffer[1] |= 0x08; - - i = lowpan6_get_address_mode_mc(ip_2_ip6(&ip6dst)); - buffer[1] |= i & 0x03; - if (i == 0) { - MEMCPY(buffer + lowpan6_header_len, inptr + 24, 16); - lowpan6_header_len += 16; - } else if (i == 1) { - buffer[lowpan6_header_len++] = inptr[25]; - MEMCPY(buffer + lowpan6_header_len, inptr + 35, 5); - lowpan6_header_len += 5; - } else if (i == 2) { - buffer[lowpan6_header_len++] = inptr[25]; - MEMCPY(buffer + lowpan6_header_len, inptr + 37, 3); - lowpan6_header_len += 3; - } else if (i == 3) { - buffer[lowpan6_header_len++] = (inptr)[39]; - } - } else if (((buffer[1] & 0x04) != 0) || - (ip6_addr_islinklocal(ip_2_ip6(&ip6dst)))) { - /* Context-based or link-local destination address compression. */ - i = lowpan6_get_address_mode(ip_2_ip6(&ip6dst), dst); - buffer[1] |= i & 0x03; - if (i == 1) { - MEMCPY(buffer + lowpan6_header_len, inptr + 32, 8); - lowpan6_header_len += 8; - } else if (i == 2) { - MEMCPY(buffer + lowpan6_header_len, inptr + 38, 2); - lowpan6_header_len += 2; - } - } else { - /* Append full address. */ - MEMCPY(buffer + lowpan6_header_len, inptr + 24, 16); - lowpan6_header_len += 16; - } - - /* Move to payload. */ - inptr += IP6_HLEN; - hidden_header_len += IP6_HLEN; - -#if LWIP_UDP - /* Compress UDP header? */ - if (IP6H_NEXTH(ip6hdr) == IP6_NEXTH_UDP) { - /* @todo support optional checksum compression */ - - if (inbuf_size < IP6_HLEN + UDP_HLEN) { - /* input buffer too short */ - return ERR_VAL; - } - if (outbuf_size < (size_t)(hidden_header_len + 7)) { - /* output buffer too short for worst case */ - return ERR_MEM; - } - - buffer[lowpan6_header_len] = 0xf0; - - /* determine port compression mode. */ - if ((inptr[0] == 0xf0) && ((inptr[1] & 0xf0) == 0xb0) && - (inptr[2] == 0xf0) && ((inptr[3] & 0xf0) == 0xb0)) { - /* Compress source and dest ports. */ - buffer[lowpan6_header_len++] |= 0x03; - buffer[lowpan6_header_len++] = ((inptr[1] & 0x0f) << 4) | (inptr[3] & 0x0f); - } else if (inptr[0] == 0xf0) { - /* Compress source port. */ - buffer[lowpan6_header_len++] |= 0x02; - buffer[lowpan6_header_len++] = inptr[1]; - buffer[lowpan6_header_len++] = inptr[2]; - buffer[lowpan6_header_len++] = inptr[3]; - } else if (inptr[2] == 0xf0) { - /* Compress dest port. */ - buffer[lowpan6_header_len++] |= 0x01; - buffer[lowpan6_header_len++] = inptr[0]; - buffer[lowpan6_header_len++] = inptr[1]; - buffer[lowpan6_header_len++] = inptr[3]; - } else { - /* append full ports. */ - lowpan6_header_len++; - buffer[lowpan6_header_len++] = inptr[0]; - buffer[lowpan6_header_len++] = inptr[1]; - buffer[lowpan6_header_len++] = inptr[2]; - buffer[lowpan6_header_len++] = inptr[3]; - } - - /* elide length and copy checksum */ - buffer[lowpan6_header_len++] = inptr[6]; - buffer[lowpan6_header_len++] = inptr[7]; - - hidden_header_len += UDP_HLEN; - } -#endif /* LWIP_UDP */ - - *lowpan6_header_len_out = lowpan6_header_len; - *hidden_header_len_out = hidden_header_len; - - return ERR_OK; -} - -/** Decompress IPv6 and UDP headers compressed according to RFC 6282 - * - * @param lowpan6_buffer compressed headers, first byte is the dispatch byte - * @param lowpan6_bufsize size of lowpan6_buffer (may include data after headers) - * @param decomp_buffer buffer where the decompressed headers are stored - * @param decomp_bufsize size of decomp_buffer - * @param hdr_size_comp returns the size of the compressed headers (skip to get to data) - * @param hdr_size_decomp returns the size of the decompressed headers (IPv6 + UDP) - * @param datagram_size datagram size from fragments or 0 if unfragmented - * @param compressed_size compressed datagram size (for unfragmented rx) - * @param lowpan6_contexts context addresses - * @param src source address of the outer layer, used for address compression - * @param dest destination address of the outer layer, used for address compression - * @return ERR_OK if decompression succeeded, an error otherwise - */ -static err_t -lowpan6_decompress_hdr(u8_t *lowpan6_buffer, size_t lowpan6_bufsize, - u8_t *decomp_buffer, size_t decomp_bufsize, - u16_t *hdr_size_comp, u16_t *hdr_size_decomp, - u16_t datagram_size, u16_t compressed_size, - ip6_addr_t *lowpan6_contexts, - struct lowpan6_link_addr *src, struct lowpan6_link_addr *dest) -{ - u16_t lowpan6_offset; - struct ip6_hdr *ip6hdr; - s8_t i; - u32_t header_temp; - u16_t ip6_offset = IP6_HLEN; - - LWIP_ASSERT("lowpan6_buffer != NULL", lowpan6_buffer != NULL); - LWIP_ASSERT("decomp_buffer != NULL", decomp_buffer != NULL); - LWIP_ASSERT("src != NULL", src != NULL); - LWIP_ASSERT("dest != NULL", dest != NULL); - LWIP_ASSERT("hdr_size_comp != NULL", hdr_size_comp != NULL); - LWIP_ASSERT("dehdr_size_decompst != NULL", hdr_size_decomp != NULL); - - ip6hdr = (struct ip6_hdr *)decomp_buffer; - if (decomp_bufsize < IP6_HLEN) { - return ERR_MEM; - } - - /* output the full compressed packet, if set in @see lowpan6_opts.h */ -#if LWIP_LOWPAN6_IP_COMPRESSED_DEBUG - { - u16_t j; - LWIP_DEBUGF(LWIP_LOWPAN6_IP_COMPRESSED_DEBUG, ("lowpan6_decompress_hdr: IP6 payload (compressed): \n")); - for (j = 0; j < lowpan6_bufsize; j++) { - if ((j % 4) == 0) { - LWIP_DEBUGF(LWIP_LOWPAN6_IP_COMPRESSED_DEBUG, ("\n")); - } - LWIP_DEBUGF(LWIP_LOWPAN6_IP_COMPRESSED_DEBUG, ("%2X ", lowpan6_buffer[j])); - } - LWIP_DEBUGF(LWIP_LOWPAN6_IP_COMPRESSED_DEBUG, ("\np->len: %d", lowpan6_bufsize)); - } -#endif - - /* offset for inline IP headers (RFC 6282 ch3)*/ - lowpan6_offset = 2; - /* if CID is set (context identifier), the context byte - * follows immediately after the header, so other IPHC fields are @+3 */ - if (lowpan6_buffer[1] & 0x80) { - lowpan6_offset++; - } - - /* Set IPv6 version, traffic class and flow label. (RFC6282, ch 3.1.1.)*/ - if ((lowpan6_buffer[0] & 0x18) == 0x00) { - header_temp = ((lowpan6_buffer[lowpan6_offset+1] & 0x0f) << 16) | \ - (lowpan6_buffer[lowpan6_offset + 2] << 8) | lowpan6_buffer[lowpan6_offset+3]; - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("TF: 00, ECN: 0x%2x, Flowlabel+DSCP: 0x%8X\n", \ - lowpan6_buffer[lowpan6_offset],header_temp)); - IP6H_VTCFL_SET(ip6hdr, 6, lowpan6_buffer[lowpan6_offset], header_temp); - /* increase offset, processed 4 bytes here: - * TF=00: ECN + DSCP + 4-bit Pad + Flow Label (4 bytes)*/ - lowpan6_offset += 4; - } else if ((lowpan6_buffer[0] & 0x18) == 0x08) { - header_temp = ((lowpan6_buffer[lowpan6_offset] & 0x0f) << 16) | (lowpan6_buffer[lowpan6_offset + 1] << 8) | lowpan6_buffer[lowpan6_offset+2]; - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("TF: 01, ECN: 0x%2x, Flowlabel: 0x%2X, DSCP ignored\n", \ - lowpan6_buffer[lowpan6_offset] & 0xc0,header_temp)); - IP6H_VTCFL_SET(ip6hdr, 6, lowpan6_buffer[lowpan6_offset] & 0xc0, header_temp); - /* increase offset, processed 3 bytes here: - * TF=01: ECN + 2-bit Pad + Flow Label (3 bytes), DSCP is elided.*/ - lowpan6_offset += 3; - } else if ((lowpan6_buffer[0] & 0x18) == 0x10) { - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("TF: 10, DCSP+ECN: 0x%2x, Flowlabel ignored\n", lowpan6_buffer[lowpan6_offset])); - IP6H_VTCFL_SET(ip6hdr, 6, lowpan6_buffer[lowpan6_offset],0); - /* increase offset, processed 1 byte here: - * ECN + DSCP (1 byte), Flow Label is elided.*/ - lowpan6_offset += 1; - } else if ((lowpan6_buffer[0] & 0x18) == 0x18) { - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("TF: 11, DCSP/ECN & Flowlabel ignored\n")); - /* don't increase offset, no bytes processed here */ - IP6H_VTCFL_SET(ip6hdr, 6, 0, 0); - } - - /* Set Next Header (NH) */ - if ((lowpan6_buffer[0] & 0x04) == 0x00) { - /* 0: full next header byte carried inline (increase offset)*/ - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("NH: 0x%2X\n", lowpan6_buffer[lowpan6_offset+1])); - IP6H_NEXTH_SET(ip6hdr, lowpan6_buffer[lowpan6_offset++]); - } else { - /* 1: NH compression, LOWPAN_NHC (RFC6282, ch 4.1) */ - /* We should fill this later with NHC decoding */ - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("NH: skipped, later done with NHC\n")); - IP6H_NEXTH_SET(ip6hdr, 0); - } - - /* Set Hop Limit, either carried inline or 3 different hops (1,64,255) */ - if ((lowpan6_buffer[0] & 0x03) == 0x00) { - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("Hops: full value: %d\n", lowpan6_buffer[lowpan6_offset+1])); - IP6H_HOPLIM_SET(ip6hdr, lowpan6_buffer[lowpan6_offset++]); - } else if ((lowpan6_buffer[0] & 0x03) == 0x01) { - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("Hops: compressed: 1\n")); - IP6H_HOPLIM_SET(ip6hdr, 1); - } else if ((lowpan6_buffer[0] & 0x03) == 0x02) { - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("Hops: compressed: 64\n")); - IP6H_HOPLIM_SET(ip6hdr, 64); - } else if ((lowpan6_buffer[0] & 0x03) == 0x03) { - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("Hops: compressed: 255\n")); - IP6H_HOPLIM_SET(ip6hdr, 255); - } - - /* Source address decoding. */ - if ((lowpan6_buffer[1] & 0x40) == 0x00) { - /* Source address compression (SAC) = 0 -> stateless compression */ - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAC == 0, no context byte\n")); - /* Stateless compression */ - if ((lowpan6_buffer[1] & 0x30) == 0x00) { - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAM == 00, no src compression, fetching 128bits inline\n")); - /* copy full address, increase offset by 16 Bytes */ - MEMCPY(&ip6hdr->src.addr[0], lowpan6_buffer + lowpan6_offset, 16); - lowpan6_offset += 16; - } else if ((lowpan6_buffer[1] & 0x30) == 0x10) { - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAM == 01, src compression, 64bits inline\n")); - /* set 64 bits to link local */ - ip6hdr->src.addr[0] = PP_HTONL(0xfe800000UL); - ip6hdr->src.addr[1] = 0; - /* copy 8 Bytes, increase offset */ - MEMCPY(&ip6hdr->src.addr[2], lowpan6_buffer + lowpan6_offset, 8); - lowpan6_offset += 8; - } else if ((lowpan6_buffer[1] & 0x30) == 0x20) { - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAM == 10, src compression, 16bits inline\n")); - /* set 96 bits to link local */ - ip6hdr->src.addr[0] = PP_HTONL(0xfe800000UL); - ip6hdr->src.addr[1] = 0; - ip6hdr->src.addr[2] = PP_HTONL(0x000000ffUL); - /* extract remaining 16bits from inline bytes, increase offset */ - ip6hdr->src.addr[3] = lwip_htonl(0xfe000000UL | (lowpan6_buffer[lowpan6_offset] << 8) | - lowpan6_buffer[lowpan6_offset + 1]); - lowpan6_offset += 2; - } else if ((lowpan6_buffer[1] & 0x30) == 0x30) { - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAM == 11, src compression, 0bits inline, using other headers\n")); - /* no information avalaible, using other layers, see RFC6282 ch 3.2.2 */ - ip6hdr->src.addr[0] = PP_HTONL(0xfe800000UL); - ip6hdr->src.addr[1] = 0; - if (src->addr_len == 2) { - ip6hdr->src.addr[2] = PP_HTONL(0x000000ffUL); - ip6hdr->src.addr[3] = lwip_htonl(0xfe000000UL | (src->addr[0] << 8) | src->addr[1]); - } else if (src->addr_len == 8) { - ip6hdr->src.addr[2] = lwip_htonl(((src->addr[0] ^ 2) << 24) | (src->addr[1] << 16) | - (src->addr[2] << 8) | src->addr[3]); - ip6hdr->src.addr[3] = lwip_htonl((src->addr[4] << 24) | (src->addr[5] << 16) | - (src->addr[6] << 8) | src->addr[7]); - } else { - /* invalid source address length */ - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("Invalid source address length\n")); - return ERR_VAL; - } - } - } else { - /* Source address compression (SAC) = 1 -> stateful/context-based compression */ - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAC == 1, additional context byte\n")); - if ((lowpan6_buffer[1] & 0x30) == 0x00) { - /* SAM=00, address=> :: (ANY) */ - ip6hdr->src.addr[0] = 0; - ip6hdr->src.addr[1] = 0; - ip6hdr->src.addr[2] = 0; - ip6hdr->src.addr[3] = 0; - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAM == 00, context compression, ANY (::)\n")); - } else { - /* Set prefix from context info */ - if (lowpan6_buffer[1] & 0x80) { - i = (lowpan6_buffer[2] >> 4) & 0x0f; - } else { - i = 0; - } - if (i >= LWIP_6LOWPAN_NUM_CONTEXTS) { - /* Error */ - return ERR_VAL; - } -#if LWIP_6LOWPAN_NUM_CONTEXTS > 0 - ip6hdr->src.addr[0] = lowpan6_contexts[i].addr[0]; - ip6hdr->src.addr[1] = lowpan6_contexts[i].addr[1]; - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAM == xx, context compression found @%d: %8X, %8X\n", (int)i, ip6hdr->src.addr[0], ip6hdr->src.addr[1])); -#else - LWIP_UNUSED_ARG(lowpan6_contexts); -#endif - } - - /* determine further address bits */ - if ((lowpan6_buffer[1] & 0x30) == 0x10) { - /* SAM=01, load additional 64bits */ - MEMCPY(&ip6hdr->src.addr[2], lowpan6_buffer + lowpan6_offset, 8); - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAM == 01, context compression, 64bits inline\n")); - lowpan6_offset += 8; - } else if ((lowpan6_buffer[1] & 0x30) == 0x20) { - /* SAM=01, load additional 16bits */ - ip6hdr->src.addr[2] = PP_HTONL(0x000000ffUL); - ip6hdr->src.addr[3] = lwip_htonl(0xfe000000UL | (lowpan6_buffer[lowpan6_offset] << 8) | lowpan6_buffer[lowpan6_offset + 1]); - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAM == 10, context compression, 16bits inline\n")); - lowpan6_offset += 2; - } else if ((lowpan6_buffer[1] & 0x30) == 0x30) { - /* SAM=11, address is fully elided, load from other layers */ - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAM == 11, context compression, 0bits inline, using other headers\n")); - if (src->addr_len == 2) { - ip6hdr->src.addr[2] = PP_HTONL(0x000000ffUL); - ip6hdr->src.addr[3] = lwip_htonl(0xfe000000UL | (src->addr[0] << 8) | src->addr[1]); - } else if (src->addr_len == 8) { - ip6hdr->src.addr[2] = lwip_htonl(((src->addr[0] ^ 2) << 24) | (src->addr[1] << 16) | (src->addr[2] << 8) | src->addr[3]); - ip6hdr->src.addr[3] = lwip_htonl((src->addr[4] << 24) | (src->addr[5] << 16) | (src->addr[6] << 8) | src->addr[7]); - } else { - /* invalid source address length */ - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("Invalid source address length\n")); - return ERR_VAL; - } - } - } - - /* Destination address decoding. */ - if (lowpan6_buffer[1] & 0x08) { - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("M=1: multicast\n")); - /* Multicast destination */ - if (lowpan6_buffer[1] & 0x04) { - LWIP_DEBUGF(LWIP_DBG_ON,("DAC == 1, context multicast: unsupported!!!\n")); - /* @todo support stateful multicast addressing */ - return ERR_VAL; - } - - if ((lowpan6_buffer[1] & 0x03) == 0x00) { - /* DAM = 00, copy full address (128bits) */ - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("DAM == 00, no dst compression, fetching 128bits inline\n")); - MEMCPY(&ip6hdr->dest.addr[0], lowpan6_buffer + lowpan6_offset, 16); - lowpan6_offset += 16; - } else if ((lowpan6_buffer[1] & 0x03) == 0x01) { - /* DAM = 01, copy 4 bytes (32bits) */ - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("DAM == 01, dst address form (48bits): ffXX::00XX:XXXX:XXXX\n")); - ip6hdr->dest.addr[0] = lwip_htonl(0xff000000UL | (lowpan6_buffer[lowpan6_offset++] << 16)); - ip6hdr->dest.addr[1] = 0; - ip6hdr->dest.addr[2] = lwip_htonl(lowpan6_buffer[lowpan6_offset++]); - ip6hdr->dest.addr[3] = lwip_htonl((lowpan6_buffer[lowpan6_offset] << 24) | (lowpan6_buffer[lowpan6_offset + 1] << 16) | (lowpan6_buffer[lowpan6_offset + 2] << 8) | lowpan6_buffer[lowpan6_offset + 3]); - lowpan6_offset += 4; - } else if ((lowpan6_buffer[1] & 0x03) == 0x02) { - /* DAM = 10, copy 3 bytes (24bits) */ - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("DAM == 10, dst address form (32bits): ffXX::00XX:XXXX\n")); - ip6hdr->dest.addr[0] = lwip_htonl(0xff000000UL | (lowpan6_buffer[lowpan6_offset++] << 16)); - ip6hdr->dest.addr[1] = 0; - ip6hdr->dest.addr[2] = 0; - ip6hdr->dest.addr[3] = lwip_htonl((lowpan6_buffer[lowpan6_offset] << 16) | (lowpan6_buffer[lowpan6_offset + 1] << 8) | lowpan6_buffer[lowpan6_offset + 2]); - lowpan6_offset += 3; - } else if ((lowpan6_buffer[1] & 0x03) == 0x03) { - /* DAM = 11, copy 1 byte (8bits) */ - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("DAM == 11, dst address form (8bits): ff02::00XX\n")); - ip6hdr->dest.addr[0] = PP_HTONL(0xff020000UL); - ip6hdr->dest.addr[1] = 0; - ip6hdr->dest.addr[2] = 0; - ip6hdr->dest.addr[3] = lwip_htonl(lowpan6_buffer[lowpan6_offset++]); - } - - } else { - /* no Multicast (M=0) */ - if (lowpan6_buffer[1] & 0x04) { - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("DAC == 1, stateful compression\n")); - /* Stateful destination compression */ - /* Set prefix from context info */ - if (lowpan6_buffer[1] & 0x80) { - i = lowpan6_buffer[2] & 0x0f; - } else { - i = 0; - } - if (i >= LWIP_6LOWPAN_NUM_CONTEXTS) { - /* Error */ - return ERR_VAL; - } -#if LWIP_6LOWPAN_NUM_CONTEXTS > 0 - ip6hdr->dest.addr[0] = lowpan6_contexts[i].addr[0]; - ip6hdr->dest.addr[1] = lowpan6_contexts[i].addr[1]; -#endif - } else { - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("DAC == 0, stateless compression, setting link local prefix\n")); - /* Link local address compression */ - ip6hdr->dest.addr[0] = PP_HTONL(0xfe800000UL); - ip6hdr->dest.addr[1] = 0; - } - - /* M=0, DAC=0, determining destination address length via DAM=xx */ - if ((lowpan6_buffer[1] & 0x03) == 0x00) { - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("DAM == 00, no dst compression, fetching 128bits inline")); - /* DAM=00, copy full address */ - MEMCPY(&ip6hdr->dest.addr[0], lowpan6_buffer + lowpan6_offset, 16); - lowpan6_offset += 16; - } else if ((lowpan6_buffer[1] & 0x03) == 0x01) { - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("DAM == 01, dst compression, 64bits inline\n")); - /* DAM=01, copy 64 inline bits, increase offset */ - MEMCPY(&ip6hdr->dest.addr[2], lowpan6_buffer + lowpan6_offset, 8); - lowpan6_offset += 8; - } else if ((lowpan6_buffer[1] & 0x03) == 0x02) { - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("DAM == 01, dst compression, 16bits inline\n")); - /* DAM=10, copy 16 inline bits, increase offset */ - ip6hdr->dest.addr[2] = PP_HTONL(0x000000ffUL); - ip6hdr->dest.addr[3] = lwip_htonl(0xfe000000UL | (lowpan6_buffer[lowpan6_offset] << 8) | lowpan6_buffer[lowpan6_offset + 1]); - lowpan6_offset += 2; - } else if ((lowpan6_buffer[1] & 0x03) == 0x03) { - /* DAM=11, no bits available, use other headers (not done here) */ - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG,("DAM == 01, dst compression, 0bits inline, using other headers\n")); - if (dest->addr_len == 2) { - ip6hdr->dest.addr[2] = PP_HTONL(0x000000ffUL); - ip6hdr->dest.addr[3] = lwip_htonl(0xfe000000UL | (dest->addr[0] << 8) | dest->addr[1]); - } else if (dest->addr_len == 8) { - ip6hdr->dest.addr[2] = lwip_htonl(((dest->addr[0] ^ 2) << 24) | (dest->addr[1] << 16) | dest->addr[2] << 8 | dest->addr[3]); - ip6hdr->dest.addr[3] = lwip_htonl((dest->addr[4] << 24) | (dest->addr[5] << 16) | dest->addr[6] << 8 | dest->addr[7]); - } else { - /* invalid destination address length */ - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("Invalid destination address length\n")); - return ERR_VAL; - } - } - } - - - /* Next Header Compression (NHC) decoding? */ - if (lowpan6_buffer[0] & 0x04) { - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("NHC decoding\n")); -#if LWIP_UDP - if ((lowpan6_buffer[lowpan6_offset] & 0xf8) == 0xf0) { - /* NHC: UDP */ - struct udp_hdr *udphdr; - LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("NHC: UDP\n")); - - /* UDP compression */ - IP6H_NEXTH_SET(ip6hdr, IP6_NEXTH_UDP); - udphdr = (struct udp_hdr *)((u8_t *)decomp_buffer + ip6_offset); - if (decomp_bufsize < IP6_HLEN + UDP_HLEN) { - return ERR_MEM; - } - - /* Checksum decompression */ - if (lowpan6_buffer[lowpan6_offset] & 0x04) { - /* @todo support checksum decompress */ - LWIP_DEBUGF(LWIP_DBG_ON, ("NHC: UDP chechsum decompression UNSUPPORTED\n")); - return ERR_VAL; - } - - /* Decompress ports, according to RFC4944 */ - i = lowpan6_buffer[lowpan6_offset++] & 0x03; - if (i == 0) { - udphdr->src = lwip_htons(lowpan6_buffer[lowpan6_offset] << 8 | lowpan6_buffer[lowpan6_offset + 1]); - udphdr->dest = lwip_htons(lowpan6_buffer[lowpan6_offset + 2] << 8 | lowpan6_buffer[lowpan6_offset + 3]); - lowpan6_offset += 4; - } else if (i == 0x01) { - udphdr->src = lwip_htons(lowpan6_buffer[lowpan6_offset] << 8 | lowpan6_buffer[lowpan6_offset + 1]); - udphdr->dest = lwip_htons(0xf000 | lowpan6_buffer[lowpan6_offset + 2]); - lowpan6_offset += 3; - } else if (i == 0x02) { - udphdr->src = lwip_htons(0xf000 | lowpan6_buffer[lowpan6_offset]); - udphdr->dest = lwip_htons(lowpan6_buffer[lowpan6_offset + 1] << 8 | lowpan6_buffer[lowpan6_offset + 2]); - lowpan6_offset += 3; - } else if (i == 0x03) { - udphdr->src = lwip_htons(0xf0b0 | ((lowpan6_buffer[lowpan6_offset] >> 4) & 0x0f)); - udphdr->dest = lwip_htons(0xf0b0 | (lowpan6_buffer[lowpan6_offset] & 0x0f)); - lowpan6_offset += 1; - } - - udphdr->chksum = lwip_htons(lowpan6_buffer[lowpan6_offset] << 8 | lowpan6_buffer[lowpan6_offset + 1]); - lowpan6_offset += 2; - ip6_offset += UDP_HLEN; - if (datagram_size == 0) { - datagram_size = compressed_size - lowpan6_offset + ip6_offset; - } - udphdr->len = lwip_htons(datagram_size - IP6_HLEN); - - } else -#endif /* LWIP_UDP */ - { - LWIP_DEBUGF(LWIP_DBG_ON,("NHC: unsupported protocol!\n")); - /* @todo support NHC other than UDP */ - return ERR_VAL; - } - } - if (datagram_size == 0) { - datagram_size = compressed_size - lowpan6_offset + ip6_offset; - } - /* Infer IPv6 payload length for header */ - IP6H_PLEN_SET(ip6hdr, datagram_size - IP6_HLEN); - - if (lowpan6_offset > lowpan6_bufsize) { - /* input buffer overflow */ - return ERR_VAL; - } - *hdr_size_comp = lowpan6_offset; - *hdr_size_decomp = ip6_offset; - - return ERR_OK; -} - -struct pbuf * -lowpan6_decompress(struct pbuf *p, u16_t datagram_size, ip6_addr_t *lowpan6_contexts, - struct lowpan6_link_addr *src, struct lowpan6_link_addr *dest) -{ - struct pbuf *q; - u16_t lowpan6_offset, ip6_offset; - err_t err; - -#if LWIP_UDP -#define UDP_HLEN_ALLOC UDP_HLEN -#else -#define UDP_HLEN_ALLOC 0 -#endif - - /* Allocate a buffer for decompression. This buffer will be too big and will be - trimmed once the final size is known. */ - q = pbuf_alloc(PBUF_IP, p->len + IP6_HLEN + UDP_HLEN_ALLOC, PBUF_POOL); - if (q == NULL) { - pbuf_free(p); - return NULL; - } - if (q->len < IP6_HLEN + UDP_HLEN_ALLOC) { - /* The headers need to fit into the first pbuf */ - pbuf_free(p); - pbuf_free(q); - return NULL; - } - - /* Decompress the IPv6 (and possibly UDP) header(s) into the new pbuf */ - err = lowpan6_decompress_hdr((u8_t *)p->payload, p->len, (u8_t *)q->payload, q->len, - &lowpan6_offset, &ip6_offset, datagram_size, p->tot_len, lowpan6_contexts, src, dest); - if (err != ERR_OK) { - pbuf_free(p); - pbuf_free(q); - return NULL; - } - - /* Now we copy leftover contents from p to q, so we have all L2 and L3 headers - (and L4?) in a single pbuf: */ - - /* Hide the compressed headers in p */ - pbuf_remove_header(p, lowpan6_offset); - /* Temporarily hide the headers in q... */ - pbuf_remove_header(q, ip6_offset); - /* ... copy the rest of p into q... */ - pbuf_copy(q, p); - /* ... and reveal the headers again... */ - pbuf_add_header_force(q, ip6_offset); - /* ... trim the pbuf to its correct size... */ - pbuf_realloc(q, ip6_offset + p->len); - /* ... and cat possibly remaining (data-only) pbufs */ - if (p->next != NULL) { - pbuf_cat(q, p->next); - } - /* the original (first) pbuf can now be freed */ - p->next = NULL; - pbuf_free(p); - - /* all done */ - return q; -} - -#endif /* LWIP_6LOWPAN_IPHC */ -#endif /* LWIP_IPV6 */ diff --git a/third-party/lwip-2.1.2/netif/ppp/PPPD_FOLLOWUP b/third-party/lwip-2.1.2/netif/ppp/PPPD_FOLLOWUP deleted file mode 100644 index c231982a..00000000 --- a/third-party/lwip-2.1.2/netif/ppp/PPPD_FOLLOWUP +++ /dev/null @@ -1,473 +0,0 @@ -The lwIP PPP support is based from pppd 2.4.5 (http://ppp.samba.org) with -huge changes to match code size and memory requirements for embedded devices. - -Anyway, pppd has a mature codebase for years and the average commit count -is getting low on their Git repository, meaning that we can follow what -is happening on their side and merge what is relevant for lwIP. - -So, here is the pppd follow up, so that we don't get away too far from pppd. - - -== Patch fetched from from pppd Debian packages == - -This has nothing to do with pppd, but we merged some good patch from -Debian and this is a good place to be. - -- LCP adaptive echo, so that we don't send LCP echo request if we - are receiving data from peer, can be enabled by setting PPP_LCP_ADAPTIVE - to true. - -- IPCP no/replace default route option, were added in the early stage of - the ppp port, but it wasn't really helpful and was disabled when adding - the new API ppp_set_default() call, which gives the lwIP user control over - which one is the default interface, it was actually a requirement if you - are doing PPP over PPP (i.e. PPPoL2TP, VPN link, over PPPoE, ADSL link). - -- using rp-pppoe pppd exits with EXIT_OK after receiving a timeout waiting - for PADO due to no modem attached, bug reported to pppd bug tracker, fixed - in Debian but not in the latest (at the time when the port were started) - pppd release. - - -== Commits on pppd == - -2010-03-06 - Document +ipv6 and ipv6cp-accept-local - e7537958aee79b3f653c601e903cb31d78fb7dcc - -Don't care. - - -2010-03-06 - Install pppol2tp plugins with sane permissions - 406215672cfadc03017341fe03802d1c7294b903 - -Don't care. - - -2010-03-07 - pppd: Terminate correctly if lcp_lowerup delayed calling - fsm_lowerup - 3eb9e810cfa515543655659b72dde30c54fea0a5 - -Merged 2012-05-17. - - -2010-03-07 - rp_pppoe: Copy acName and pppd_pppoe_service after option parsing - cab58617fd9d328029fffabc788020264b4fa91f - -Don't care, is a patch for pppd/plugins/rp-pppoe/plugin.c which is not part -of the port. - - -2010-08-23 - set and reset options to control environment variables - for scripts. - 2b6310fd24dba8e0fca8999916a162f0a1842a84 - -We can't fork processes in embedded, therefore all the pppd process run -feature is disabled in the port, so we don't care about the new -"environment variables" pppd feature. - - -2010-08-23 - Nit: use _exit when exec fails and restrict values to 0-255 - per POSIX. - 2b4ea140432eeba5a007c0d4e6236bd0e0c12ba4 - -Again, we are not running as a heavy process, so all exit() or _exit() calls -were removed. - - -2010-08-23 - Fix quote handling in configuration files to be more like shell - quoting. - 3089132cdf5b58dbdfc2daf08ec5c08eb47f8aca - -We are not parsing config file, all the filesystem I/O stuff were disabled -in our port. - - -2010-08-24 - rp-pppoe: allow MTU to be increased up to 1500 - fd1dcdf758418f040da3ed801ab001b5e46854e7 - -Only concern changes on RP-PPPoE plugin, which we don't use. - - -2010-09-11 - chat: Allow TIMEOUT value to come from environment variable - ae80bf833e48a6202f44a935a68083ae52ad3824 - -See 2b6310fd24dba8e0fca8999916a162f0a1842a84. - - -2011-03-05 - pppdump: Fix printfs with insufficient arguments - 7b8db569642c83ba3283745034f2e2c95e459423 - -pppdump is a ppp tool outside pppd source tree. - - -2012-05-06 - pppd: Don't unconditionally disable VJ compression under Linux - d8a66adf98a0e525cf38031b42098d539da6eeb6 - -Patch for sys-linux.c, which we don't use. - - -2012-05-20 - Remove old version of Linux if_pppol2tp.h - c41092dd4c49267f232f6cba3d31c6c68bfdf68d - -Not in the port. - - -2012-05-20 - pppd: Make MSCHAP-v2 cope better with packet loss - 08ef47ca532294eb428238c831616748940e24a2 - -This is an interesting patch. However it consumes much more memory for -MSCHAP and I am not sure if the benefit worth it. The PPP client can -always start the authentication again if it failed for whatever reason. - - -2012-05-20 - scripts: Make poff ignore extra arguments to pppd - 18f515f32c9f5723a9c2c912601e04335106534b - -Again, we are not running scripts. - - -2012-05-20 - rp-pppoe plugin: Print leading zeros in MAC address - f5dda0cfc220c4b52e26144096d729e27b30f0f7 - -Again, we are not using the RP-PPPoE plugin. - - -2012-05-20 - pppd: Notify IPv6 up/down as we do for IPv4 - 845cda8fa18939cf56e60b073f63a7efa65336fc - -This is just a patch that adds plugins hooks for IPv6, the plugin interface -was disabled because we don't have .so plugins in embedded. - - -2012-05-20 - pppd: Enable IPV6 by default and fix some warnings - 0b6118239615e98959f7e0b4e746bdd197533248 - -Change on Makefile for IPv6, warnings were already cleared during port. - - -2012-05-20 - contrib: Fix pppgetpass.gtk compilation - 80a8e2ce257ca12cce723519a0f20ea1d663b14a - -Change on Makefile, don't care. - - -2012-05-20 - pppd: Don't crash if crypt() returns NULL - 04c4348108d847e034dd91066cc6843f60d71731 - -We are using the PolarSSL DES implementation that does not return NULL. - - -2012-05-20 - pppd: Eliminate some warnings - c44ae5e6a7338c96eb463881fe709b2dfaffe568 - -Again, we are handling compilation warnings on our own. - - -2012-05-20 - rp-pppoe plugin: Import some fixes from rp-pppoe-3.10 - 1817d83e51a411044e730ba89ebdb0480e1c8cd4 - -Once more, we are not using the RP-PPPoE plugin. - - -2013-01-23 - pppd: Clarify circumstances where DNS1/DNS2 environment variables are set - cf2f5c9538b9400ade23446a194729b0a4113b3a - -Documentation only. - - -2013-02-03 - ppp: ignore unrecognised radiusclient configuration directives - 7f736dde0da3c19855997d9e67370e351e15e923 - -Radius plugin, not in the port. - - -2013-02-03 - pppd: Take out unused %r conversion completely - 356d8d558d844412119aa18c8e5a113bc6459c7b - -Merged 2014-04-15. - - -2013-02-03 - pppd: Arrange to use logwtmp from libutil on Linux - 9617a7eb137f4fee62799a677a9ecf8d834db3f5 - -Patch for sys-linux.c, which we don't use. - - -2013-02-03 - pppdump: Eliminate some compiler warnings - 3e3acf1ba2b3046c072a42c19164788a9e419bd1 - -pppdump is a ppp tool outside pppd source tree. - - -2013-02-03 - chat: Correct spelling errors in the man page - 8dea1b969d266ccbf6f3a8c5474eb6dcd8838e3b - -Documentation only. - - -2013-02-03 - pppd: Fix spelling errors in man page - 9e05a25d76b3f83096c661678010320df673df6b - -Documentation only. - - -2013-02-03 - plugins/passprompt: Fix potential out-of-bounds array reference - 8edb889b753056a691a3e4b217a110a35f9fdedb - -Plugin patch, we do not have plugins. - - -2013-02-03 - chat: Fix *roff errors in the man page - a7c3489eeaf44e83ce592143c7c8a5b5c29f4c48 - -Documentation only. - - -2013-03-02 - pppd: Fix man page description of case when remote IP address isn't known - 224841f4799f4f1e2e71bc490c54448d66740f4f - -Documentation only. - - -2013-03-02 - pppd: Add master_detach option - 398ed2585640d198c53e736ee5bbd67f7ce8168e - -Option for multilink support, we do not support multilink and this option -is about detaching from the terminal, which is out of the embedded scope. - - -2013-03-11 - pppd: Default exit status to EXIT_CONNECT_FAILED during connection phase - 225361d64ae737afdc8cb57579a2f33525461bc9 - -Commented out in our port, and already fixed by a previously applied Debian patch. - - -2013-03-11 - pppstats: Fix undefined macro in man page - d16a3985eade5280b8e171f5dd0670a91cba0d39 - -Documentation only. - - -2013-05-11 - plugins/radius: Handle bindaddr keyword in radiusclient.conf - d883b2dbafeed3ebd9d7a56ab1469373bd001a3b - -Radius plugin, not in the port. - - -2013-06-09 - pppoatm: Remove explicit loading of pppoatm kernel module - 52cd43a84bea524033b918b603698104f221bbb7 - -PPPoATM plugin, not in the port. - - -2013-06-09 - pppd: Fix segfault in update_db_entry() - 37476164f15a45015310b9d4b197c2d7db1f7f8f - -We do not use the samba db. - - -2013-06-09 - chat: Fix some text that was intended to be literal - cd9683676618adcee8add2c3cfa3382341b5a1f6 - -Documentation only. - - -2013-06-09 - README.pppoe: Minor semantic fix - b5b8898af6fd3d44e873cfc66810ace5f1f47e17 - -Documentation only. - - -2013-06-10 - radius: Handle additional attributes - 2f581cd986a56f2ec4a95abad4f8297a1b10d7e2 - -Radius plugin, not in the port. - - -2013-06-10 - chat, pppd: Use \e instead of \\ in man pages - 8d6942415d22f6ca4377340ca26e345c3f5fa5db - -Documentation only. - - -2014-01-02 - pppd: Don't crash if NULL pointer passed to vslprintf for %q or %v - 906814431bddeb2061825fa1ebad1a967b6d87a9 - -Merged 2014-04-15. - - -2014-01-02 - pppd: Accept IPCP ConfAck packets containing MS-WINS options - a243f217f1c6ac1aa7793806bc88590d077f490a - -Merged 2014-04-15. - - -2014-01-02 - config: Update Solaris compiler options and enable CHAPMS and IPV6 - 99c46caaed01b7edba87962aa52b77fad61bfd7b - -Solaris port, don't care. - - -2014-01-02 - Update README and patchlevel for 2.4.6 release - 4043750fca36e7e0eb90d702e048ad1da4929418 - -Just release stuff. - - -2014-02-18 - pppd: Add option "stop-bits" to set number of serial port stop bits. - ad993a20ee485f0d0e2ac4105221641b200da6e2 - -Low level serial port, not in the port. - - -2014-03-09 - pppd: Separate IPv6 handling for sifup/sifdown - b04d2dc6df5c6b5650fea44250d58757ee3dac4a - -Reimplemented. - - -2014-03-09 - pppol2tp: Connect up/down events to notifiers and add IPv6 ones - fafbe50251efc7d6b4a8be652d085316e112b34f - -Not in the port. - - -2014-03-09 - pppd: Add declarations to eliminate compile warnings - 50967962addebe15c7a7e63116ff46a0441dc464 - -We are handling compilation warnings on our own - - -2014-03-09 - pppd: Eliminate some unnecessary ifdefs - de8da14d845ee6db9236ccfddabf1d8ebf045ddb - -We mostly did that previously. Anyway, merged 2014-12-24. - - -2014-08-01 - radius: Fix realms-config-file option - 880a81be7c8e0fe8567227bc17a1bff3ea035943 - -Radius plugin, not in the port. - - -2014-08-01 - pppd: Eliminate potential integer overflow in option parsing - 7658e8257183f062dc01f87969c140707c7e52cb - -pppd config file parser, not in the port. - - -2014-08-01 - pppd: Eliminate memory leak with multiple instances of a string option - b94b7fbbaa0589aa6ec5fdc733aeb9ff294d2656 - -pppd config file parser, not in the port. - - -2014-08-01 - pppd: Fix a stack variable overflow in MSCHAP-v2 - 36733a891fb56594fcee580f667b33a64b990981 - -This fixes a bug introduced in 08ef47ca ("pppd: Make MSCHAP-v2 cope better with packet loss"). - -We didn't merge 08ef47ca ;-) - - -2014-08-01 - winbind plugin: Add -DMPPE=1 to eliminate compiler warnings - 2b05e22c62095e97dd0a97e4b5588402c2185071 - -Linux plugin, not in the port. - - -2014-08-09 - Update README and patchlevel for 2.4.7 release - 6e8eaa7a78b31cdab2edf140a9c8afdb02ffaca5 - -Just release stuff. - - -2014-08-10 - abort on errors in subdir builds - 5e90783d11a59268e05f4cfb29ce2343b13e8ab2 - -Linux Makefile, not in the port. - - -2014-06-03 - pppd: add support for defaultroute-metric option - 35e5a569c988b1ff865b02a24d9a727a00db4da9 - -Only necessary for Linux, lwIP does not support route metrics. - - -2014-12-13 - scripts: Avoid killing wrong pppd - 67811a647d399db5d188a242827760615a0f86b5 - -pppd helper script, not in the port. - - -2014-12-20 - pppd: Fix sign-extension when displaying bytes in octal - 5e8c3cb256a7e86e3572a82a75d51c6850efdbdc - -Merged 2016-07-02. - - -2015-03-01 - Suppress false error message on PPPoE disconnect - 219aac3b53d0827549377f1bfe22853ee52d4405 - -PPPoE plugin, not in the port. - - -2015-03-01 - Send PADT on PPPoE disconnect - cd2c14f998c57bbe6a01dc5854f2763c0d7f31fb - -PPPoE plugin, not in the port. And our PPPoE implementation already does -that: pppoe_disconnect() calls pppoe_send_padt(). - - -2015-08-14 - pppd: ipxcp: Prevent buffer overrun on remote router name - fe149de624f96629a7f46732055d8f718c74b856 - -We never ported IPX support. lwIP does not support IPX. - - -2015-03-25 - pppd: Fix ccp_options.mppe type - 234edab99a6bb250cc9ecd384cca27b0c8b475ce - -We found that while working on MPPE support in lwIP, that's our patch ;-) - - -2015-03-24 - pppd: Fix ccp_cilen calculated size if both deflate_correct and deflate_draft are enabled - 094cb8ae4c61db225e67fedadb4964f846dd0c27 - -We found that while working on MPPE support in lwIP, that's our patch ;-) - - -2015-08-14 - Merge branch 'master' of https://github.com/ncopa/ppp - 3a5c9a8fbc8970375cd881151d44e4b6fe249c6a - -Merge commit, we don't care. - - -2015-08-14 - Merge branch 'master' of git://github.com/vapier/ppp - 912e4fc6665aca188dced7ea7fdc663ce5a2dd24 - -Merge commit, we don't care. - - -2015-08-14 - Merge branch 'bug_fix' of git://github.com/radaiming/ppp - dfd33d7f526ecd7b39dd1bba8101260d02af5ebb - -Merge commit, we don't care. - - -2015-08-14 - Merge branch 'master' of git://github.com/pprindeville/ppp - aa4a985f6114d08cf4e47634fb6325da71016473 - -Merge commit, we don't care. - - -2015-08-14 - Merge branch 'no-error-on-already-closed' of git://github.com/farnz/ppp - 6edf252483b30dbcdcc5059f01831455365d5b6e - -Merge commit, we don't care. - - -2015-08-14 - Merge branch 'send-padt-on-disconnect' of git://github.com/farnz/ppp - 84684243d651f55f6df69d2a6707b52fbbe62bb9 - -Merge commit, we don't care. diff --git a/third-party/lwip-2.1.2/netif/ppp/auth.c b/third-party/lwip-2.1.2/netif/ppp/auth.c deleted file mode 100644 index c8673ad0..00000000 --- a/third-party/lwip-2.1.2/netif/ppp/auth.c +++ /dev/null @@ -1,2510 +0,0 @@ -/* - * auth.c - PPP authentication and phase control. - * - * Copyright (c) 1993-2002 Paul Mackerras. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 3. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Derived from main.c, which is: - * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#if 0 /* UNUSED */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if defined(_PATH_LASTLOG) && defined(__linux__) -#include -#endif - -#include -#include -#include - -#ifdef HAS_SHADOW -#include -#ifndef PW_PPP -#define PW_PPP PW_LOGIN -#endif -#endif - -#include -#endif /* UNUSED */ - -#include "netif/ppp/ppp_impl.h" - -#include "netif/ppp/fsm.h" -#include "netif/ppp/lcp.h" -#if CCP_SUPPORT -#include "netif/ppp/ccp.h" -#endif /* CCP_SUPPORT */ -#if ECP_SUPPORT -#include "netif/ppp/ecp.h" -#endif /* ECP_SUPPORT */ -#include "netif/ppp/ipcp.h" -#if PAP_SUPPORT -#include "netif/ppp/upap.h" -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT -#include "netif/ppp/chap-new.h" -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT -#include "netif/ppp/eap.h" -#endif /* EAP_SUPPORT */ -#if CBCP_SUPPORT -#include "netif/ppp/cbcp.h" -#endif - -#if 0 /* UNUSED */ -#include "session.h" -#endif /* UNUSED */ - -#if 0 /* UNUSED */ -/* Bits in scan_authfile return value */ -#define NONWILD_SERVER 1 -#define NONWILD_CLIENT 2 - -#define ISWILD(word) (word[0] == '*' && word[1] == 0) -#endif /* UNUSED */ - -#if 0 /* UNUSED */ -/* List of addresses which the peer may use. */ -static struct permitted_ip *addresses[NUM_PPP]; - -/* Wordlist giving addresses which the peer may use - without authenticating itself. */ -static struct wordlist *noauth_addrs; - -/* Remote telephone number, if available */ -char remote_number[MAXNAMELEN]; - -/* Wordlist giving remote telephone numbers which may connect. */ -static struct wordlist *permitted_numbers; - -/* Extra options to apply, from the secrets file entry for the peer. */ -static struct wordlist *extra_options; -#endif /* UNUSED */ - -#if 0 /* UNUSED */ -/* Set if we require authentication only because we have a default route. */ -static bool default_auth; - -/* Hook to enable a plugin to control the idle time limit */ -int (*idle_time_hook) (struct ppp_idle *) = NULL; - -/* Hook for a plugin to say whether we can possibly authenticate any peer */ -int (*pap_check_hook) (void) = NULL; - -/* Hook for a plugin to check the PAP user and password */ -int (*pap_auth_hook) (char *user, char *passwd, char **msgp, - struct wordlist **paddrs, - struct wordlist **popts) = NULL; - -/* Hook for a plugin to know about the PAP user logout */ -void (*pap_logout_hook) (void) = NULL; - -/* Hook for a plugin to get the PAP password for authenticating us */ -int (*pap_passwd_hook) (char *user, char *passwd) = NULL; - -/* Hook for a plugin to say if we can possibly authenticate a peer using CHAP */ -int (*chap_check_hook) (void) = NULL; - -/* Hook for a plugin to get the CHAP password for authenticating us */ -int (*chap_passwd_hook) (char *user, char *passwd) = NULL; - -/* Hook for a plugin to say whether it is OK if the peer - refuses to authenticate. */ -int (*null_auth_hook) (struct wordlist **paddrs, - struct wordlist **popts) = NULL; - -int (*allowed_address_hook) (u32_t addr) = NULL; -#endif /* UNUSED */ - -#ifdef HAVE_MULTILINK -/* Hook for plugin to hear when an interface joins a multilink bundle */ -void (*multilink_join_hook) (void) = NULL; -#endif - -#if PPP_NOTIFY -/* A notifier for when the peer has authenticated itself, - and we are proceeding to the network phase. */ -struct notifier *auth_up_notifier = NULL; - -/* A notifier for when the link goes down. */ -struct notifier *link_down_notifier = NULL; -#endif /* PPP_NOTIFY */ - -/* - * Option variables. - */ -#if 0 /* MOVED TO ppp_settings */ -bool uselogin = 0; /* Use /etc/passwd for checking PAP */ -bool session_mgmt = 0; /* Do session management (login records) */ -bool cryptpap = 0; /* Passwords in pap-secrets are encrypted */ -bool refuse_pap = 0; /* Don't wanna auth. ourselves with PAP */ -bool refuse_chap = 0; /* Don't wanna auth. ourselves with CHAP */ -bool refuse_eap = 0; /* Don't wanna auth. ourselves with EAP */ -#if MSCHAP_SUPPORT -bool refuse_mschap = 0; /* Don't wanna auth. ourselves with MS-CHAP */ -bool refuse_mschap_v2 = 0; /* Don't wanna auth. ourselves with MS-CHAPv2 */ -#else /* MSCHAP_SUPPORT */ -bool refuse_mschap = 1; /* Don't wanna auth. ourselves with MS-CHAP */ -bool refuse_mschap_v2 = 1; /* Don't wanna auth. ourselves with MS-CHAPv2 */ -#endif /* MSCHAP_SUPPORT */ -bool usehostname = 0; /* Use hostname for our_name */ -bool auth_required = 0; /* Always require authentication from peer */ -bool allow_any_ip = 0; /* Allow peer to use any IP address */ -bool explicit_remote = 0; /* User specified explicit remote name */ -bool explicit_user = 0; /* Set if "user" option supplied */ -bool explicit_passwd = 0; /* Set if "password" option supplied */ -char remote_name[MAXNAMELEN]; /* Peer's name for authentication */ -static char *uafname; /* name of most recent +ua file */ - -extern char *crypt (const char *, const char *); -#endif /* UNUSED */ -/* Prototypes for procedures local to this file. */ - -static void network_phase(ppp_pcb *pcb); -#if PPP_IDLETIMELIMIT -static void check_idle(void *arg); -#endif /* PPP_IDLETIMELIMIT */ -#if PPP_MAXCONNECT -static void connect_time_expired(void *arg); -#endif /* PPP_MAXCONNECT */ -#if 0 /* UNUSED */ -static int null_login (int); -/* static int get_pap_passwd (char *); */ -static int have_pap_secret (int *); -static int have_chap_secret (char *, char *, int, int *); -static int have_srp_secret (char *client, char *server, int need_ip, - int *lacks_ipp); -static int ip_addr_check (u32_t, struct permitted_ip *); -static int scan_authfile (FILE *, char *, char *, char *, - struct wordlist **, struct wordlist **, - char *, int); -static void free_wordlist (struct wordlist *); -static void set_allowed_addrs (int, struct wordlist *, struct wordlist *); -static int some_ip_ok (struct wordlist *); -static int setupapfile (char **); -static int privgroup (char **); -static int set_noauth_addr (char **); -static int set_permitted_number (char **); -static void check_access (FILE *, char *); -static int wordlist_count (struct wordlist *); -#endif /* UNUSED */ - -#ifdef MAXOCTETS -static void check_maxoctets (void *); -#endif - -#if PPP_OPTIONS -/* - * Authentication-related options. - */ -option_t auth_options[] = { - { "auth", o_bool, &auth_required, - "Require authentication from peer", OPT_PRIO | 1 }, - { "noauth", o_bool, &auth_required, - "Don't require peer to authenticate", OPT_PRIOSUB | OPT_PRIV, - &allow_any_ip }, - { "require-pap", o_bool, &lcp_wantoptions[0].neg_upap, - "Require PAP authentication from peer", - OPT_PRIOSUB | 1, &auth_required }, - { "+pap", o_bool, &lcp_wantoptions[0].neg_upap, - "Require PAP authentication from peer", - OPT_ALIAS | OPT_PRIOSUB | 1, &auth_required }, - { "require-chap", o_bool, &auth_required, - "Require CHAP authentication from peer", - OPT_PRIOSUB | OPT_A2OR | MDTYPE_MD5, - &lcp_wantoptions[0].chap_mdtype }, - { "+chap", o_bool, &auth_required, - "Require CHAP authentication from peer", - OPT_ALIAS | OPT_PRIOSUB | OPT_A2OR | MDTYPE_MD5, - &lcp_wantoptions[0].chap_mdtype }, -#if MSCHAP_SUPPORT - { "require-mschap", o_bool, &auth_required, - "Require MS-CHAP authentication from peer", - OPT_PRIOSUB | OPT_A2OR | MDTYPE_MICROSOFT, - &lcp_wantoptions[0].chap_mdtype }, - { "+mschap", o_bool, &auth_required, - "Require MS-CHAP authentication from peer", - OPT_ALIAS | OPT_PRIOSUB | OPT_A2OR | MDTYPE_MICROSOFT, - &lcp_wantoptions[0].chap_mdtype }, - { "require-mschap-v2", o_bool, &auth_required, - "Require MS-CHAPv2 authentication from peer", - OPT_PRIOSUB | OPT_A2OR | MDTYPE_MICROSOFT_V2, - &lcp_wantoptions[0].chap_mdtype }, - { "+mschap-v2", o_bool, &auth_required, - "Require MS-CHAPv2 authentication from peer", - OPT_ALIAS | OPT_PRIOSUB | OPT_A2OR | MDTYPE_MICROSOFT_V2, - &lcp_wantoptions[0].chap_mdtype }, -#endif /* MSCHAP_SUPPORT */ -#if 0 - { "refuse-pap", o_bool, &refuse_pap, - "Don't agree to auth to peer with PAP", 1 }, - { "-pap", o_bool, &refuse_pap, - "Don't allow PAP authentication with peer", OPT_ALIAS | 1 }, - { "refuse-chap", o_bool, &refuse_chap, - "Don't agree to auth to peer with CHAP", - OPT_A2CLRB | MDTYPE_MD5, - &lcp_allowoptions[0].chap_mdtype }, - { "-chap", o_bool, &refuse_chap, - "Don't allow CHAP authentication with peer", - OPT_ALIAS | OPT_A2CLRB | MDTYPE_MD5, - &lcp_allowoptions[0].chap_mdtype }, -#endif -#if MSCHAP_SUPPORT -#if 0 - { "refuse-mschap", o_bool, &refuse_mschap, - "Don't agree to auth to peer with MS-CHAP", - OPT_A2CLRB | MDTYPE_MICROSOFT, - &lcp_allowoptions[0].chap_mdtype }, - { "-mschap", o_bool, &refuse_mschap, - "Don't allow MS-CHAP authentication with peer", - OPT_ALIAS | OPT_A2CLRB | MDTYPE_MICROSOFT, - &lcp_allowoptions[0].chap_mdtype }, - { "refuse-mschap-v2", o_bool, &refuse_mschap_v2, - "Don't agree to auth to peer with MS-CHAPv2", - OPT_A2CLRB | MDTYPE_MICROSOFT_V2, - &lcp_allowoptions[0].chap_mdtype }, - { "-mschap-v2", o_bool, &refuse_mschap_v2, - "Don't allow MS-CHAPv2 authentication with peer", - OPT_ALIAS | OPT_A2CLRB | MDTYPE_MICROSOFT_V2, - &lcp_allowoptions[0].chap_mdtype }, -#endif -#endif /* MSCHAP_SUPPORT*/ -#if EAP_SUPPORT - { "require-eap", o_bool, &lcp_wantoptions[0].neg_eap, - "Require EAP authentication from peer", OPT_PRIOSUB | 1, - &auth_required }, -#if 0 - { "refuse-eap", o_bool, &refuse_eap, - "Don't agree to authenticate to peer with EAP", 1 }, -#endif -#endif /* EAP_SUPPORT */ - { "name", o_string, our_name, - "Set local name for authentication", - OPT_PRIO | OPT_PRIV | OPT_STATIC, NULL, MAXNAMELEN }, - - { "+ua", o_special, (void *)setupapfile, - "Get PAP user and password from file", - OPT_PRIO | OPT_A2STRVAL, &uafname }, - -#if 0 - { "user", o_string, user, - "Set name for auth with peer", OPT_PRIO | OPT_STATIC, - &explicit_user, MAXNAMELEN }, - - { "password", o_string, passwd, - "Password for authenticating us to the peer", - OPT_PRIO | OPT_STATIC | OPT_HIDE, - &explicit_passwd, MAXSECRETLEN }, -#endif - - { "usehostname", o_bool, &usehostname, - "Must use hostname for authentication", 1 }, - - { "remotename", o_string, remote_name, - "Set remote name for authentication", OPT_PRIO | OPT_STATIC, - &explicit_remote, MAXNAMELEN }, - - { "login", o_bool, &uselogin, - "Use system password database for PAP", OPT_A2COPY | 1 , - &session_mgmt }, - { "enable-session", o_bool, &session_mgmt, - "Enable session accounting for remote peers", OPT_PRIV | 1 }, - - { "papcrypt", o_bool, &cryptpap, - "PAP passwords are encrypted", 1 }, - - { "privgroup", o_special, (void *)privgroup, - "Allow group members to use privileged options", OPT_PRIV | OPT_A2LIST }, - - { "allow-ip", o_special, (void *)set_noauth_addr, - "Set IP address(es) which can be used without authentication", - OPT_PRIV | OPT_A2LIST }, - - { "remotenumber", o_string, remote_number, - "Set remote telephone number for authentication", OPT_PRIO | OPT_STATIC, - NULL, MAXNAMELEN }, - - { "allow-number", o_special, (void *)set_permitted_number, - "Set telephone number(s) which are allowed to connect", - OPT_PRIV | OPT_A2LIST }, - - { NULL } -}; -#endif /* PPP_OPTIONS */ - -#if 0 /* UNUSED */ -/* - * setupapfile - specifies UPAP info for authenticating with peer. - */ -static int -setupapfile(argv) - char **argv; -{ - FILE *ufile; - int l; - uid_t euid; - char u[MAXNAMELEN], p[MAXSECRETLEN]; - char *fname; - - lcp_allowoptions[0].neg_upap = 1; - - /* open user info file */ - fname = strdup(*argv); - if (fname == NULL) - novm("+ua file name"); - euid = geteuid(); - if (seteuid(getuid()) == -1) { - option_error("unable to reset uid before opening %s: %m", fname); - return 0; - } - ufile = fopen(fname, "r"); - if (seteuid(euid) == -1) - fatal("unable to regain privileges: %m"); - if (ufile == NULL) { - option_error("unable to open user login data file %s", fname); - return 0; - } - check_access(ufile, fname); - uafname = fname; - - /* get username */ - if (fgets(u, MAXNAMELEN - 1, ufile) == NULL - || fgets(p, MAXSECRETLEN - 1, ufile) == NULL) { - fclose(ufile); - option_error("unable to read user login data file %s", fname); - return 0; - } - fclose(ufile); - - /* get rid of newlines */ - l = strlen(u); - if (l > 0 && u[l-1] == '\n') - u[l-1] = 0; - l = strlen(p); - if (l > 0 && p[l-1] == '\n') - p[l-1] = 0; - - if (override_value("user", option_priority, fname)) { - strlcpy(ppp_settings.user, u, sizeof(ppp_settings.user)); - explicit_user = 1; - } - if (override_value("passwd", option_priority, fname)) { - strlcpy(ppp_settings.passwd, p, sizeof(ppp_settings.passwd)); - explicit_passwd = 1; - } - - return (1); -} - -/* - * privgroup - allow members of the group to have privileged access. - */ -static int -privgroup(argv) - char **argv; -{ - struct group *g; - int i; - - g = getgrnam(*argv); - if (g == 0) { - option_error("group %s is unknown", *argv); - return 0; - } - for (i = 0; i < ngroups; ++i) { - if (groups[i] == g->gr_gid) { - privileged = 1; - break; - } - } - return 1; -} - - -/* - * set_noauth_addr - set address(es) that can be used without authentication. - * Equivalent to specifying an entry like `"" * "" addr' in pap-secrets. - */ -static int -set_noauth_addr(argv) - char **argv; -{ - char *addr = *argv; - int l = strlen(addr) + 1; - struct wordlist *wp; - - wp = (struct wordlist *) malloc(sizeof(struct wordlist) + l); - if (wp == NULL) - novm("allow-ip argument"); - wp->word = (char *) (wp + 1); - wp->next = noauth_addrs; - MEMCPY(wp->word, addr, l); - noauth_addrs = wp; - return 1; -} - - -/* - * set_permitted_number - set remote telephone number(s) that may connect. - */ -static int -set_permitted_number(argv) - char **argv; -{ - char *number = *argv; - int l = strlen(number) + 1; - struct wordlist *wp; - - wp = (struct wordlist *) malloc(sizeof(struct wordlist) + l); - if (wp == NULL) - novm("allow-number argument"); - wp->word = (char *) (wp + 1); - wp->next = permitted_numbers; - MEMCPY(wp->word, number, l); - permitted_numbers = wp; - return 1; -} -#endif - -/* - * An Open on LCP has requested a change from Dead to Establish phase. - */ -void link_required(ppp_pcb *pcb) { - LWIP_UNUSED_ARG(pcb); -} - -#if 0 -/* - * Bring the link up to the point of being able to do ppp. - */ -void start_link(unit) - int unit; -{ - ppp_pcb *pcb = &ppp_pcb_list[unit]; - char *msg; - - status = EXIT_NEGOTIATION_FAILED; - new_phase(pcb, PPP_PHASE_SERIALCONN); - - hungup = 0; - devfd = the_channel->connect(); - msg = "Connect script failed"; - if (devfd < 0) - goto fail; - - /* set up the serial device as a ppp interface */ - /* - * N.B. we used to do tdb_writelock/tdb_writeunlock around this - * (from establish_ppp to set_ifunit). However, we won't be - * doing the set_ifunit in multilink mode, which is the only time - * we need the atomicity that the tdb_writelock/tdb_writeunlock - * gives us. Thus we don't need the tdb_writelock/tdb_writeunlock. - */ - fd_ppp = the_channel->establish_ppp(devfd); - msg = "ppp establishment failed"; - if (fd_ppp < 0) { - status = EXIT_FATAL_ERROR; - goto disconnect; - } - - if (!demand && ifunit >= 0) - set_ifunit(1); - - /* - * Start opening the connection and wait for - * incoming events (reply, timeout, etc.). - */ - if (ifunit >= 0) - ppp_notice("Connect: %s <--> %s", ifname, ppp_devnam); - else - ppp_notice("Starting negotiation on %s", ppp_devnam); - add_fd(fd_ppp); - - new_phase(pcb, PPP_PHASE_ESTABLISH); - - lcp_lowerup(pcb); - return; - - disconnect: - new_phase(pcb, PPP_PHASE_DISCONNECT); - if (the_channel->disconnect) - the_channel->disconnect(); - - fail: - new_phase(pcb, PPP_PHASE_DEAD); - if (the_channel->cleanup) - (*the_channel->cleanup)(); -} -#endif - -/* - * LCP has terminated the link; go to the Dead phase and take the - * physical layer down. - */ -void link_terminated(ppp_pcb *pcb) { - if (pcb->phase == PPP_PHASE_DEAD -#ifdef HAVE_MULTILINK - || pcb->phase == PPP_PHASE_MASTER -#endif /* HAVE_MULTILINK */ - ) - return; - new_phase(pcb, PPP_PHASE_DISCONNECT); - -#if 0 /* UNUSED */ - if (pap_logout_hook) { - pap_logout_hook(); - } - session_end(devnam); -#endif /* UNUSED */ - - if (!doing_multilink) { - ppp_notice("Connection terminated."); -#if PPP_STATS_SUPPORT - print_link_stats(); -#endif /* PPP_STATS_SUPPORT */ - } else - ppp_notice("Link terminated."); - - lcp_lowerdown(pcb); - - ppp_link_terminated(pcb); -#if 0 - /* - * Delete pid files before disestablishing ppp. Otherwise it - * can happen that another pppd gets the same unit and then - * we delete its pid file. - */ - if (!doing_multilink && !demand) - remove_pidfiles(); - - /* - * If we may want to bring the link up again, transfer - * the ppp unit back to the loopback. Set the - * real serial device back to its normal mode of operation. - */ - if (fd_ppp >= 0) { - remove_fd(fd_ppp); - clean_check(); - the_channel->disestablish_ppp(devfd); - if (doing_multilink) - mp_exit_bundle(); - fd_ppp = -1; - } - if (!hungup) - lcp_lowerdown(pcb); - if (!doing_multilink && !demand) - script_unsetenv("IFNAME"); - - /* - * Run disconnector script, if requested. - * XXX we may not be able to do this if the line has hung up! - */ - if (devfd >= 0 && the_channel->disconnect) { - the_channel->disconnect(); - devfd = -1; - } - if (the_channel->cleanup) - (*the_channel->cleanup)(); - - if (doing_multilink && multilink_master) { - if (!bundle_terminating) - new_phase(pcb, PPP_PHASE_MASTER); - else - mp_bundle_terminated(); - } else - new_phase(pcb, PPP_PHASE_DEAD); -#endif -} - -/* - * LCP has gone down; it will either die or try to re-establish. - */ -void link_down(ppp_pcb *pcb) { -#if PPP_NOTIFY - notify(link_down_notifier, 0); -#endif /* PPP_NOTIFY */ - - if (!doing_multilink) { - upper_layers_down(pcb); - if (pcb->phase != PPP_PHASE_DEAD -#ifdef HAVE_MULTILINK - && pcb->phase != PPP_PHASE_MASTER -#endif /* HAVE_MULTILINK */ - ) - new_phase(pcb, PPP_PHASE_ESTABLISH); - } - /* XXX if doing_multilink, should do something to stop - network-layer traffic on the link */ -} - -void upper_layers_down(ppp_pcb *pcb) { - int i; - const struct protent *protp; - - for (i = 0; (protp = protocols[i]) != NULL; ++i) { - if (protp->protocol != PPP_LCP && protp->lowerdown != NULL) - (*protp->lowerdown)(pcb); - if (protp->protocol < 0xC000 && protp->close != NULL) - (*protp->close)(pcb, "LCP down"); - } - pcb->num_np_open = 0; - pcb->num_np_up = 0; -} - -/* - * The link is established. - * Proceed to the Dead, Authenticate or Network phase as appropriate. - */ -void link_established(ppp_pcb *pcb) { -#if PPP_AUTH_SUPPORT - int auth; -#if PPP_SERVER -#if PAP_SUPPORT - lcp_options *wo = &pcb->lcp_wantoptions; -#endif /* PAP_SUPPORT */ - lcp_options *go = &pcb->lcp_gotoptions; -#endif /* PPP_SERVER */ - lcp_options *ho = &pcb->lcp_hisoptions; -#endif /* PPP_AUTH_SUPPORT */ - int i; - const struct protent *protp; - - /* - * Tell higher-level protocols that LCP is up. - */ - if (!doing_multilink) { - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (protp->protocol != PPP_LCP - && protp->lowerup != NULL) - (*protp->lowerup)(pcb); - } - -#if PPP_AUTH_SUPPORT -#if PPP_SERVER -#if PPP_ALLOWED_ADDRS - if (!auth_required && noauth_addrs != NULL) - set_allowed_addrs(unit, NULL, NULL); -#endif /* PPP_ALLOWED_ADDRS */ - - if (pcb->settings.auth_required && !(0 -#if PAP_SUPPORT - || go->neg_upap -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - || go->neg_chap -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT - || go->neg_eap -#endif /* EAP_SUPPORT */ - )) { - -#if PPP_ALLOWED_ADDRS - /* - * We wanted the peer to authenticate itself, and it refused: - * if we have some address(es) it can use without auth, fine, - * otherwise treat it as though it authenticated with PAP using - * a username of "" and a password of "". If that's not OK, - * boot it out. - */ - if (noauth_addrs != NULL) { - set_allowed_addrs(unit, NULL, NULL); - } else -#endif /* PPP_ALLOWED_ADDRS */ - if (!pcb->settings.null_login -#if PAP_SUPPORT - || !wo->neg_upap -#endif /* PAP_SUPPORT */ - ) { - ppp_warn("peer refused to authenticate: terminating link"); -#if 0 /* UNUSED */ - status = EXIT_PEER_AUTH_FAILED; -#endif /* UNUSED */ - pcb->err_code = PPPERR_AUTHFAIL; - lcp_close(pcb, "peer refused to authenticate"); - return; - } - } -#endif /* PPP_SERVER */ - - new_phase(pcb, PPP_PHASE_AUTHENTICATE); - auth = 0; -#if PPP_SERVER -#if EAP_SUPPORT - if (go->neg_eap) { - eap_authpeer(pcb, PPP_OUR_NAME); - auth |= EAP_PEER; - } else -#endif /* EAP_SUPPORT */ -#if CHAP_SUPPORT - if (go->neg_chap) { - chap_auth_peer(pcb, PPP_OUR_NAME, CHAP_DIGEST(go->chap_mdtype)); - auth |= CHAP_PEER; - } else -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT - if (go->neg_upap) { - upap_authpeer(pcb); - auth |= PAP_PEER; - } else -#endif /* PAP_SUPPORT */ - {} -#endif /* PPP_SERVER */ - -#if EAP_SUPPORT - if (ho->neg_eap) { - eap_authwithpeer(pcb, pcb->settings.user); - auth |= EAP_WITHPEER; - } else -#endif /* EAP_SUPPORT */ -#if CHAP_SUPPORT - if (ho->neg_chap) { - chap_auth_with_peer(pcb, pcb->settings.user, CHAP_DIGEST(ho->chap_mdtype)); - auth |= CHAP_WITHPEER; - } else -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT - if (ho->neg_upap) { - upap_authwithpeer(pcb, pcb->settings.user, pcb->settings.passwd); - auth |= PAP_WITHPEER; - } else -#endif /* PAP_SUPPORT */ - {} - - pcb->auth_pending = auth; - pcb->auth_done = 0; - - if (!auth) -#endif /* PPP_AUTH_SUPPORT */ - network_phase(pcb); -} - -/* - * Proceed to the network phase. - */ -static void network_phase(ppp_pcb *pcb) { -#if CBCP_SUPPORT - ppp_pcb *pcb = &ppp_pcb_list[unit]; -#endif -#if 0 /* UNUSED */ - lcp_options *go = &lcp_gotoptions[unit]; -#endif /* UNUSED */ - -#if 0 /* UNUSED */ - /* Log calling number. */ - if (*remote_number) - ppp_notice("peer from calling number %q authorized", remote_number); -#endif /* UNUSED */ - -#if PPP_NOTIFY - /* - * If the peer had to authenticate, notify it now. - */ - if (0 -#if CHAP_SUPPORT - || go->neg_chap -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT - || go->neg_upap -#endif /* PAP_SUPPORT */ -#if EAP_SUPPORT - || go->neg_eap -#endif /* EAP_SUPPORT */ - ) { - notify(auth_up_notifier, 0); - } -#endif /* PPP_NOTIFY */ - -#if CBCP_SUPPORT - /* - * If we negotiated callback, do it now. - */ - if (go->neg_cbcp) { - new_phase(pcb, PPP_PHASE_CALLBACK); - (*cbcp_protent.open)(pcb); - return; - } -#endif - -#if PPP_OPTIONS - /* - * Process extra options from the secrets file - */ - if (extra_options) { - options_from_list(extra_options, 1); - free_wordlist(extra_options); - extra_options = 0; - } -#endif /* PPP_OPTIONS */ - start_networks(pcb); -} - -void start_networks(ppp_pcb *pcb) { -#if CCP_SUPPORT || ECP_SUPPORT - int i; - const struct protent *protp; -#endif /* CCP_SUPPORT || ECP_SUPPORT */ - - new_phase(pcb, PPP_PHASE_NETWORK); - -#ifdef HAVE_MULTILINK - if (multilink) { - if (mp_join_bundle()) { - if (multilink_join_hook) - (*multilink_join_hook)(); - if (updetach && !nodetach) - detach(); - return; - } - } -#endif /* HAVE_MULTILINK */ - -#ifdef PPP_FILTER - if (!demand) - set_filters(&pass_filter, &active_filter); -#endif -#if CCP_SUPPORT || ECP_SUPPORT - /* Start CCP and ECP */ - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if ( - (0 -#if ECP_SUPPORT - || protp->protocol == PPP_ECP -#endif /* ECP_SUPPORT */ -#if CCP_SUPPORT - || protp->protocol == PPP_CCP -#endif /* CCP_SUPPORT */ - ) - && protp->open != NULL) - (*protp->open)(pcb); -#endif /* CCP_SUPPORT || ECP_SUPPORT */ - - /* - * Bring up other network protocols iff encryption is not required. - */ - if (1 -#if ECP_SUPPORT - && !ecp_gotoptions[unit].required -#endif /* ECP_SUPPORT */ -#if MPPE_SUPPORT - && !pcb->ccp_gotoptions.mppe -#endif /* MPPE_SUPPORT */ - ) - continue_networks(pcb); -} - -void continue_networks(ppp_pcb *pcb) { - int i; - const struct protent *protp; - - /* - * Start the "real" network protocols. - */ - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (protp->protocol < 0xC000 -#if CCP_SUPPORT - && protp->protocol != PPP_CCP -#endif /* CCP_SUPPORT */ -#if ECP_SUPPORT - && protp->protocol != PPP_ECP -#endif /* ECP_SUPPORT */ - && protp->open != NULL) { - (*protp->open)(pcb); - ++pcb->num_np_open; - } - - if (pcb->num_np_open == 0) - /* nothing to do */ - lcp_close(pcb, "No network protocols running"); -} - -#if PPP_AUTH_SUPPORT -#if PPP_SERVER -/* - * auth_check_passwd - Check the user name and passwd against configuration. - * - * returns: - * 0: Authentication failed. - * 1: Authentication succeeded. - * In either case, msg points to an appropriate message and msglen to the message len. - */ -int auth_check_passwd(ppp_pcb *pcb, char *auser, int userlen, char *apasswd, int passwdlen, const char **msg, int *msglen) { - int secretuserlen; - int secretpasswdlen; - - if (pcb->settings.user && pcb->settings.passwd) { - secretuserlen = (int)strlen(pcb->settings.user); - secretpasswdlen = (int)strlen(pcb->settings.passwd); - if (secretuserlen == userlen - && secretpasswdlen == passwdlen - && !memcmp(auser, pcb->settings.user, userlen) - && !memcmp(apasswd, pcb->settings.passwd, passwdlen) ) { - *msg = "Login ok"; - *msglen = sizeof("Login ok")-1; - return 1; - } - } - - *msg = "Login incorrect"; - *msglen = sizeof("Login incorrect")-1; - return 0; -} - -/* - * The peer has failed to authenticate himself using `protocol'. - */ -void auth_peer_fail(ppp_pcb *pcb, int protocol) { - LWIP_UNUSED_ARG(protocol); - /* - * Authentication failure: take the link down - */ -#if 0 /* UNUSED */ - status = EXIT_PEER_AUTH_FAILED; -#endif /* UNUSED */ - pcb->err_code = PPPERR_AUTHFAIL; - lcp_close(pcb, "Authentication failed"); -} - -/* - * The peer has been successfully authenticated using `protocol'. - */ -void auth_peer_success(ppp_pcb *pcb, int protocol, int prot_flavor, const char *name, int namelen) { - int bit; -#ifndef HAVE_MULTILINK - LWIP_UNUSED_ARG(name); - LWIP_UNUSED_ARG(namelen); -#endif /* HAVE_MULTILINK */ - - switch (protocol) { -#if CHAP_SUPPORT - case PPP_CHAP: - bit = CHAP_PEER; - switch (prot_flavor) { - case CHAP_MD5: - bit |= CHAP_MD5_PEER; - break; -#if MSCHAP_SUPPORT - case CHAP_MICROSOFT: - bit |= CHAP_MS_PEER; - break; - case CHAP_MICROSOFT_V2: - bit |= CHAP_MS2_PEER; - break; -#endif /* MSCHAP_SUPPORT */ - default: - break; - } - break; -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT - case PPP_PAP: - bit = PAP_PEER; - break; -#endif /* PAP_SUPPORT */ -#if EAP_SUPPORT - case PPP_EAP: - bit = EAP_PEER; - break; -#endif /* EAP_SUPPORT */ - default: - ppp_warn("auth_peer_success: unknown protocol %x", protocol); - return; - } - -#ifdef HAVE_MULTILINK - /* - * Save the authenticated name of the peer for later. - */ - if (namelen > (int)sizeof(pcb->peer_authname) - 1) - namelen = (int)sizeof(pcb->peer_authname) - 1; - MEMCPY(pcb->peer_authname, name, namelen); - pcb->peer_authname[namelen] = 0; -#endif /* HAVE_MULTILINK */ -#if 0 /* UNUSED */ - script_setenv("PEERNAME", , 0); -#endif /* UNUSED */ - - /* Save the authentication method for later. */ - pcb->auth_done |= bit; - - /* - * If there is no more authentication still to be done, - * proceed to the network (or callback) phase. - */ - if ((pcb->auth_pending &= ~bit) == 0) - network_phase(pcb); -} -#endif /* PPP_SERVER */ - -/* - * We have failed to authenticate ourselves to the peer using `protocol'. - */ -void auth_withpeer_fail(ppp_pcb *pcb, int protocol) { - LWIP_UNUSED_ARG(protocol); - /* - * We've failed to authenticate ourselves to our peer. - * - * Some servers keep sending CHAP challenges, but there - * is no point in persisting without any way to get updated - * authentication secrets. - * - * He'll probably take the link down, and there's not much - * we can do except wait for that. - */ - pcb->err_code = PPPERR_AUTHFAIL; - lcp_close(pcb, "Failed to authenticate ourselves to peer"); -} - -/* - * We have successfully authenticated ourselves with the peer using `protocol'. - */ -void auth_withpeer_success(ppp_pcb *pcb, int protocol, int prot_flavor) { - int bit; - const char *prot = ""; - - switch (protocol) { -#if CHAP_SUPPORT - case PPP_CHAP: - bit = CHAP_WITHPEER; - prot = "CHAP"; - switch (prot_flavor) { - case CHAP_MD5: - bit |= CHAP_MD5_WITHPEER; - break; -#if MSCHAP_SUPPORT - case CHAP_MICROSOFT: - bit |= CHAP_MS_WITHPEER; - break; - case CHAP_MICROSOFT_V2: - bit |= CHAP_MS2_WITHPEER; - break; -#endif /* MSCHAP_SUPPORT */ - default: - break; - } - break; -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT - case PPP_PAP: - bit = PAP_WITHPEER; - prot = "PAP"; - break; -#endif /* PAP_SUPPORT */ -#if EAP_SUPPORT - case PPP_EAP: - bit = EAP_WITHPEER; - prot = "EAP"; - break; -#endif /* EAP_SUPPORT */ - default: - ppp_warn("auth_withpeer_success: unknown protocol %x", protocol); - bit = 0; - /* no break */ - } - - ppp_notice("%s authentication succeeded", prot); - - /* Save the authentication method for later. */ - pcb->auth_done |= bit; - - /* - * If there is no more authentication still being done, - * proceed to the network (or callback) phase. - */ - if ((pcb->auth_pending &= ~bit) == 0) - network_phase(pcb); -} -#endif /* PPP_AUTH_SUPPORT */ - - -/* - * np_up - a network protocol has come up. - */ -void np_up(ppp_pcb *pcb, int proto) { -#if PPP_IDLETIMELIMIT - int tlim; -#endif /* PPP_IDLETIMELIMIT */ - LWIP_UNUSED_ARG(proto); - - if (pcb->num_np_up == 0) { - /* - * At this point we consider that the link has come up successfully. - */ - new_phase(pcb, PPP_PHASE_RUNNING); - -#if PPP_IDLETIMELIMIT -#if 0 /* UNUSED */ - if (idle_time_hook != 0) - tlim = (*idle_time_hook)(NULL); - else -#endif /* UNUSED */ - tlim = pcb->settings.idle_time_limit; - if (tlim > 0) - TIMEOUT(check_idle, (void*)pcb, tlim); -#endif /* PPP_IDLETIMELIMIT */ - -#if PPP_MAXCONNECT - /* - * Set a timeout to close the connection once the maximum - * connect time has expired. - */ - if (pcb->settings.maxconnect > 0) - TIMEOUT(connect_time_expired, (void*)pcb, pcb->settings.maxconnect); -#endif /* PPP_MAXCONNECT */ - -#ifdef MAXOCTETS - if (maxoctets > 0) - TIMEOUT(check_maxoctets, NULL, maxoctets_timeout); -#endif - -#if 0 /* Unused */ - /* - * Detach now, if the updetach option was given. - */ - if (updetach && !nodetach) - detach(); -#endif /* Unused */ - } - ++pcb->num_np_up; -} - -/* - * np_down - a network protocol has gone down. - */ -void np_down(ppp_pcb *pcb, int proto) { - LWIP_UNUSED_ARG(proto); - if (--pcb->num_np_up == 0) { -#if PPP_IDLETIMELIMIT - UNTIMEOUT(check_idle, (void*)pcb); -#endif /* PPP_IDLETIMELIMIT */ -#if PPP_MAXCONNECT - UNTIMEOUT(connect_time_expired, NULL); -#endif /* PPP_MAXCONNECT */ -#ifdef MAXOCTETS - UNTIMEOUT(check_maxoctets, NULL); -#endif - new_phase(pcb, PPP_PHASE_NETWORK); - } -} - -/* - * np_finished - a network protocol has finished using the link. - */ -void np_finished(ppp_pcb *pcb, int proto) { - LWIP_UNUSED_ARG(proto); - if (--pcb->num_np_open <= 0) { - /* no further use for the link: shut up shop. */ - lcp_close(pcb, "No network protocols running"); - } -} - -#ifdef MAXOCTETS -static void -check_maxoctets(arg) - void *arg; -{ -#if PPP_STATS_SUPPORT - unsigned int used; - - update_link_stats(ifunit); - link_stats_valid=0; - - switch(maxoctets_dir) { - case PPP_OCTETS_DIRECTION_IN: - used = link_stats.bytes_in; - break; - case PPP_OCTETS_DIRECTION_OUT: - used = link_stats.bytes_out; - break; - case PPP_OCTETS_DIRECTION_MAXOVERAL: - case PPP_OCTETS_DIRECTION_MAXSESSION: - used = (link_stats.bytes_in > link_stats.bytes_out) ? link_stats.bytes_in : link_stats.bytes_out; - break; - default: - used = link_stats.bytes_in+link_stats.bytes_out; - break; - } - if (used > maxoctets) { - ppp_notice("Traffic limit reached. Limit: %u Used: %u", maxoctets, used); - status = EXIT_TRAFFIC_LIMIT; - lcp_close(pcb, "Traffic limit"); -#if 0 /* UNUSED */ - need_holdoff = 0; -#endif /* UNUSED */ - } else { - TIMEOUT(check_maxoctets, NULL, maxoctets_timeout); - } -#endif /* PPP_STATS_SUPPORT */ -} -#endif /* MAXOCTETS */ - -#if PPP_IDLETIMELIMIT -/* - * check_idle - check whether the link has been idle for long - * enough that we can shut it down. - */ -static void check_idle(void *arg) { - ppp_pcb *pcb = (ppp_pcb*)arg; - struct ppp_idle idle; - time_t itime; - int tlim; - - if (!get_idle_time(pcb, &idle)) - return; -#if 0 /* UNUSED */ - if (idle_time_hook != 0) { - tlim = idle_time_hook(&idle); - } else { -#endif /* UNUSED */ - itime = LWIP_MIN(idle.xmit_idle, idle.recv_idle); - tlim = pcb->settings.idle_time_limit - itime; -#if 0 /* UNUSED */ - } -#endif /* UNUSED */ - if (tlim <= 0) { - /* link is idle: shut it down. */ - ppp_notice("Terminating connection due to lack of activity."); - pcb->err_code = PPPERR_IDLETIMEOUT; - lcp_close(pcb, "Link inactive"); -#if 0 /* UNUSED */ - need_holdoff = 0; -#endif /* UNUSED */ - } else { - TIMEOUT(check_idle, (void*)pcb, tlim); - } -} -#endif /* PPP_IDLETIMELIMIT */ - -#if PPP_MAXCONNECT -/* - * connect_time_expired - log a message and close the connection. - */ -static void connect_time_expired(void *arg) { - ppp_pcb *pcb = (ppp_pcb*)arg; - ppp_info("Connect time expired"); - pcb->err_code = PPPERR_CONNECTTIME; - lcp_close(pcb, "Connect time expired"); /* Close connection */ -} -#endif /* PPP_MAXCONNECT */ - -#if PPP_OPTIONS -/* - * auth_check_options - called to check authentication options. - */ -void -auth_check_options() -{ - lcp_options *wo = &lcp_wantoptions[0]; - int can_auth; - int lacks_ip; - - /* Default our_name to hostname, and user to our_name */ - if (our_name[0] == 0 || usehostname) - strlcpy(our_name, hostname, sizeof(our_name)); - /* If a blank username was explicitly given as an option, trust - the user and don't use our_name */ - if (ppp_settings.user[0] == 0 && !explicit_user) - strlcpy(ppp_settings.user, our_name, sizeof(ppp_settings.user)); - - /* - * If we have a default route, require the peer to authenticate - * unless the noauth option was given or the real user is root. - */ - if (!auth_required && !allow_any_ip && have_route_to(0) && !privileged) { - auth_required = 1; - default_auth = 1; - } - -#if CHAP_SUPPORT - /* If we selected any CHAP flavors, we should probably negotiate it. :-) */ - if (wo->chap_mdtype) - wo->neg_chap = 1; -#endif /* CHAP_SUPPORT */ - - /* If authentication is required, ask peer for CHAP, PAP, or EAP. */ - if (auth_required) { - allow_any_ip = 0; - if (1 -#if CHAP_SUPPORT - && !wo->neg_chap -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT - && !wo->neg_upap -#endif /* PAP_SUPPORT */ -#if EAP_SUPPORT - && !wo->neg_eap -#endif /* EAP_SUPPORT */ - ) { -#if CHAP_SUPPORT - wo->neg_chap = CHAP_MDTYPE_SUPPORTED != MDTYPE_NONE; - wo->chap_mdtype = CHAP_MDTYPE_SUPPORTED; -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT - wo->neg_upap = 1; -#endif /* PAP_SUPPORT */ -#if EAP_SUPPORT - wo->neg_eap = 1; -#endif /* EAP_SUPPORT */ - } - } else { -#if CHAP_SUPPORT - wo->neg_chap = 0; - wo->chap_mdtype = MDTYPE_NONE; -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT - wo->neg_upap = 0; -#endif /* PAP_SUPPORT */ -#if EAP_SUPPORT - wo->neg_eap = 0; -#endif /* EAP_SUPPORT */ - } - - /* - * Check whether we have appropriate secrets to use - * to authenticate the peer. Note that EAP can authenticate by way - * of a CHAP-like exchanges as well as SRP. - */ - lacks_ip = 0; -#if PAP_SUPPORT - can_auth = wo->neg_upap && (uselogin || have_pap_secret(&lacks_ip)); -#else - can_auth = 0; -#endif /* PAP_SUPPORT */ - if (!can_auth && (0 -#if CHAP_SUPPORT - || wo->neg_chap -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT - || wo->neg_eap -#endif /* EAP_SUPPORT */ - )) { -#if CHAP_SUPPORT - can_auth = have_chap_secret((explicit_remote? remote_name: NULL), - our_name, 1, &lacks_ip); -#else - can_auth = 0; -#endif - } - if (!can_auth -#if EAP_SUPPORT - && wo->neg_eap -#endif /* EAP_SUPPORT */ - ) { - can_auth = have_srp_secret((explicit_remote? remote_name: NULL), - our_name, 1, &lacks_ip); - } - - if (auth_required && !can_auth && noauth_addrs == NULL) { - if (default_auth) { - option_error( -"By default the remote system is required to authenticate itself"); - option_error( -"(because this system has a default route to the internet)"); - } else if (explicit_remote) - option_error( -"The remote system (%s) is required to authenticate itself", - remote_name); - else - option_error( -"The remote system is required to authenticate itself"); - option_error( -"but I couldn't find any suitable secret (password) for it to use to do so."); - if (lacks_ip) - option_error( -"(None of the available passwords would let it use an IP address.)"); - - exit(1); - } - - /* - * Early check for remote number authorization. - */ - if (!auth_number()) { - ppp_warn("calling number %q is not authorized", remote_number); - exit(EXIT_CNID_AUTH_FAILED); - } -} -#endif /* PPP_OPTIONS */ - -#if 0 /* UNUSED */ -/* - * auth_reset - called when LCP is starting negotiations to recheck - * authentication options, i.e. whether we have appropriate secrets - * to use for authenticating ourselves and/or the peer. - */ -void -auth_reset(unit) - int unit; -{ - lcp_options *go = &lcp_gotoptions[unit]; - lcp_options *ao = &lcp_allowoptions[unit]; - int hadchap; - - hadchap = -1; - ao->neg_upap = !refuse_pap && (passwd[0] != 0 || get_pap_passwd(NULL)); - ao->neg_chap = (!refuse_chap || !refuse_mschap || !refuse_mschap_v2) - && (passwd[0] != 0 || - (hadchap = have_chap_secret(user, (explicit_remote? remote_name: - NULL), 0, NULL))); - ao->neg_eap = !refuse_eap && ( - passwd[0] != 0 || - (hadchap == 1 || (hadchap == -1 && have_chap_secret(user, - (explicit_remote? remote_name: NULL), 0, NULL))) || - have_srp_secret(user, (explicit_remote? remote_name: NULL), 0, NULL)); - - hadchap = -1; - if (go->neg_upap && !uselogin && !have_pap_secret(NULL)) - go->neg_upap = 0; - if (go->neg_chap) { - if (!(hadchap = have_chap_secret((explicit_remote? remote_name: NULL), - our_name, 1, NULL))) - go->neg_chap = 0; - } - if (go->neg_eap && - (hadchap == 0 || (hadchap == -1 && - !have_chap_secret((explicit_remote? remote_name: NULL), our_name, - 1, NULL))) && - !have_srp_secret((explicit_remote? remote_name: NULL), our_name, 1, - NULL)) - go->neg_eap = 0; -} - -/* - * check_passwd - Check the user name and passwd against the PAP secrets - * file. If requested, also check against the system password database, - * and login the user if OK. - * - * returns: - * UPAP_AUTHNAK: Authentication failed. - * UPAP_AUTHACK: Authentication succeeded. - * In either case, msg points to an appropriate message. - */ -int -check_passwd(unit, auser, userlen, apasswd, passwdlen, msg) - int unit; - char *auser; - int userlen; - char *apasswd; - int passwdlen; - char **msg; -{ - return UPAP_AUTHNAK; - int ret; - char *filename; - FILE *f; - struct wordlist *addrs = NULL, *opts = NULL; - char passwd[256], user[256]; - char secret[MAXWORDLEN]; - static int attempts = 0; - - /* - * Make copies of apasswd and auser, then null-terminate them. - * If there are unprintable characters in the password, make - * them visible. - */ - slprintf(ppp_settings.passwd, sizeof(ppp_settings.passwd), "%.*v", passwdlen, apasswd); - slprintf(ppp_settings.user, sizeof(ppp_settings.user), "%.*v", userlen, auser); - *msg = ""; - - /* - * Check if a plugin wants to handle this. - */ - if (pap_auth_hook) { - ret = (*pap_auth_hook)(ppp_settings.user, ppp_settings.passwd, msg, &addrs, &opts); - if (ret >= 0) { - /* note: set_allowed_addrs() saves opts (but not addrs): - don't free it! */ - if (ret) - set_allowed_addrs(unit, addrs, opts); - else if (opts != 0) - free_wordlist(opts); - if (addrs != 0) - free_wordlist(addrs); - BZERO(ppp_settings.passwd, sizeof(ppp_settings.passwd)); - return ret? UPAP_AUTHACK: UPAP_AUTHNAK; - } - } - - /* - * Open the file of pap secrets and scan for a suitable secret - * for authenticating this user. - */ - filename = _PATH_UPAPFILE; - addrs = opts = NULL; - ret = UPAP_AUTHNAK; - f = fopen(filename, "r"); - if (f == NULL) { - ppp_error("Can't open PAP password file %s: %m", filename); - - } else { - check_access(f, filename); - if (scan_authfile(f, ppp_settings.user, our_name, secret, &addrs, &opts, filename, 0) < 0) { - ppp_warn("no PAP secret found for %s", user); - } else { - /* - * If the secret is "@login", it means to check - * the password against the login database. - */ - int login_secret = strcmp(secret, "@login") == 0; - ret = UPAP_AUTHACK; - if (uselogin || login_secret) { - /* login option or secret is @login */ - if (session_full(ppp_settings.user, ppp_settings.passwd, devnam, msg) == 0) { - ret = UPAP_AUTHNAK; - } - } else if (session_mgmt) { - if (session_check(ppp_settings.user, NULL, devnam, NULL) == 0) { - ppp_warn("Peer %q failed PAP Session verification", user); - ret = UPAP_AUTHNAK; - } - } - if (secret[0] != 0 && !login_secret) { - /* password given in pap-secrets - must match */ - if ((cryptpap || strcmp(ppp_settings.passwd, secret) != 0) - && strcmp(crypt(ppp_settings.passwd, secret), secret) != 0) - ret = UPAP_AUTHNAK; - } - } - fclose(f); - } - - if (ret == UPAP_AUTHNAK) { - if (**msg == 0) - *msg = "Login incorrect"; - /* - * XXX can we ever get here more than once?? - * Frustrate passwd stealer programs. - * Allow 10 tries, but start backing off after 3 (stolen from login). - * On 10'th, drop the connection. - */ - if (attempts++ >= 10) { - ppp_warn("%d LOGIN FAILURES ON %s, %s", attempts, devnam, user); - lcp_close(pcb, "login failed"); - } - if (attempts > 3) - sleep((u_int) (attempts - 3) * 5); - if (opts != NULL) - free_wordlist(opts); - - } else { - attempts = 0; /* Reset count */ - if (**msg == 0) - *msg = "Login ok"; - set_allowed_addrs(unit, addrs, opts); - } - - if (addrs != NULL) - free_wordlist(addrs); - BZERO(ppp_settings.passwd, sizeof(ppp_settings.passwd)); - BZERO(secret, sizeof(secret)); - - return ret; -} - -/* - * null_login - Check if a username of "" and a password of "" are - * acceptable, and iff so, set the list of acceptable IP addresses - * and return 1. - */ -static int -null_login(unit) - int unit; -{ - char *filename; - FILE *f; - int i, ret; - struct wordlist *addrs, *opts; - char secret[MAXWORDLEN]; - - /* - * Check if a plugin wants to handle this. - */ - ret = -1; - if (null_auth_hook) - ret = (*null_auth_hook)(&addrs, &opts); - - /* - * Open the file of pap secrets and scan for a suitable secret. - */ - if (ret <= 0) { - filename = _PATH_UPAPFILE; - addrs = NULL; - f = fopen(filename, "r"); - if (f == NULL) - return 0; - check_access(f, filename); - - i = scan_authfile(f, "", our_name, secret, &addrs, &opts, filename, 0); - ret = i >= 0 && secret[0] == 0; - BZERO(secret, sizeof(secret)); - fclose(f); - } - - if (ret) - set_allowed_addrs(unit, addrs, opts); - else if (opts != 0) - free_wordlist(opts); - if (addrs != 0) - free_wordlist(addrs); - - return ret; -} - -/* - * get_pap_passwd - get a password for authenticating ourselves with - * our peer using PAP. Returns 1 on success, 0 if no suitable password - * could be found. - * Assumes passwd points to MAXSECRETLEN bytes of space (if non-null). - */ -static int -get_pap_passwd(passwd) - char *passwd; -{ - char *filename; - FILE *f; - int ret; - char secret[MAXWORDLEN]; - - /* - * Check whether a plugin wants to supply this. - */ - if (pap_passwd_hook) { - ret = (*pap_passwd_hook)(ppp_settings,user, ppp_settings.passwd); - if (ret >= 0) - return ret; - } - - filename = _PATH_UPAPFILE; - f = fopen(filename, "r"); - if (f == NULL) - return 0; - check_access(f, filename); - ret = scan_authfile(f, user, - (remote_name[0]? remote_name: NULL), - secret, NULL, NULL, filename, 0); - fclose(f); - if (ret < 0) - return 0; - if (passwd != NULL) - strlcpy(passwd, secret, MAXSECRETLEN); - BZERO(secret, sizeof(secret)); - return 1; -} - -/* - * have_pap_secret - check whether we have a PAP file with any - * secrets that we could possibly use for authenticating the peer. - */ -static int -have_pap_secret(lacks_ipp) - int *lacks_ipp; -{ - FILE *f; - int ret; - char *filename; - struct wordlist *addrs; - - /* let the plugin decide, if there is one */ - if (pap_check_hook) { - ret = (*pap_check_hook)(); - if (ret >= 0) - return ret; - } - - filename = _PATH_UPAPFILE; - f = fopen(filename, "r"); - if (f == NULL) - return 0; - - ret = scan_authfile(f, (explicit_remote? remote_name: NULL), our_name, - NULL, &addrs, NULL, filename, 0); - fclose(f); - if (ret >= 0 && !some_ip_ok(addrs)) { - if (lacks_ipp != 0) - *lacks_ipp = 1; - ret = -1; - } - if (addrs != 0) - free_wordlist(addrs); - - return ret >= 0; -} - -/* - * have_chap_secret - check whether we have a CHAP file with a - * secret that we could possibly use for authenticating `client' - * on `server'. Either can be the null string, meaning we don't - * know the identity yet. - */ -static int -have_chap_secret(client, server, need_ip, lacks_ipp) - char *client; - char *server; - int need_ip; - int *lacks_ipp; -{ - FILE *f; - int ret; - char *filename; - struct wordlist *addrs; - - if (chap_check_hook) { - ret = (*chap_check_hook)(); - if (ret >= 0) { - return ret; - } - } - - filename = _PATH_CHAPFILE; - f = fopen(filename, "r"); - if (f == NULL) - return 0; - - if (client != NULL && client[0] == 0) - client = NULL; - else if (server != NULL && server[0] == 0) - server = NULL; - - ret = scan_authfile(f, client, server, NULL, &addrs, NULL, filename, 0); - fclose(f); - if (ret >= 0 && need_ip && !some_ip_ok(addrs)) { - if (lacks_ipp != 0) - *lacks_ipp = 1; - ret = -1; - } - if (addrs != 0) - free_wordlist(addrs); - - return ret >= 0; -} - -/* - * have_srp_secret - check whether we have a SRP file with a - * secret that we could possibly use for authenticating `client' - * on `server'. Either can be the null string, meaning we don't - * know the identity yet. - */ -static int -have_srp_secret(client, server, need_ip, lacks_ipp) - char *client; - char *server; - int need_ip; - int *lacks_ipp; -{ - FILE *f; - int ret; - char *filename; - struct wordlist *addrs; - - filename = _PATH_SRPFILE; - f = fopen(filename, "r"); - if (f == NULL) - return 0; - - if (client != NULL && client[0] == 0) - client = NULL; - else if (server != NULL && server[0] == 0) - server = NULL; - - ret = scan_authfile(f, client, server, NULL, &addrs, NULL, filename, 0); - fclose(f); - if (ret >= 0 && need_ip && !some_ip_ok(addrs)) { - if (lacks_ipp != 0) - *lacks_ipp = 1; - ret = -1; - } - if (addrs != 0) - free_wordlist(addrs); - - return ret >= 0; -} -#endif /* UNUSED */ - -#if PPP_AUTH_SUPPORT -/* - * get_secret - open the CHAP secret file and return the secret - * for authenticating the given client on the given server. - * (We could be either client or server). - */ -int get_secret(ppp_pcb *pcb, const char *client, const char *server, char *secret, int *secret_len, int am_server) { - int len; - LWIP_UNUSED_ARG(server); - LWIP_UNUSED_ARG(am_server); - - if (!client || !client[0] || !pcb->settings.user || !pcb->settings.passwd || strcmp(client, pcb->settings.user)) { - return 0; - } - - len = (int)strlen(pcb->settings.passwd); - if (len > MAXSECRETLEN) { - ppp_error("Secret for %s on %s is too long", client, server); - len = MAXSECRETLEN; - } - - MEMCPY(secret, pcb->settings.passwd, len); - *secret_len = len; - return 1; - -#if 0 /* UNUSED */ - FILE *f; - int ret, len; - char *filename; - struct wordlist *addrs, *opts; - char secbuf[MAXWORDLEN]; - struct wordlist *addrs; - addrs = NULL; - - if (!am_server && ppp_settings.passwd[0] != 0) { - strlcpy(secbuf, ppp_settings.passwd, sizeof(secbuf)); - } else if (!am_server && chap_passwd_hook) { - if ( (*chap_passwd_hook)(client, secbuf) < 0) { - ppp_error("Unable to obtain CHAP password for %s on %s from plugin", - client, server); - return 0; - } - } else { - filename = _PATH_CHAPFILE; - addrs = NULL; - secbuf[0] = 0; - - f = fopen(filename, "r"); - if (f == NULL) { - ppp_error("Can't open chap secret file %s: %m", filename); - return 0; - } - check_access(f, filename); - - ret = scan_authfile(f, client, server, secbuf, &addrs, &opts, filename, 0); - fclose(f); - if (ret < 0) - return 0; - - if (am_server) - set_allowed_addrs(unit, addrs, opts); - else if (opts != 0) - free_wordlist(opts); - if (addrs != 0) - free_wordlist(addrs); - } - - len = strlen(secbuf); - if (len > MAXSECRETLEN) { - ppp_error("Secret for %s on %s is too long", client, server); - len = MAXSECRETLEN; - } - MEMCPY(secret, secbuf, len); - BZERO(secbuf, sizeof(secbuf)); - *secret_len = len; - - return 1; -#endif /* UNUSED */ -} -#endif /* PPP_AUTH_SUPPORT */ - - -#if 0 /* UNUSED */ -/* - * get_srp_secret - open the SRP secret file and return the secret - * for authenticating the given client on the given server. - * (We could be either client or server). - */ -int -get_srp_secret(unit, client, server, secret, am_server) - int unit; - char *client; - char *server; - char *secret; - int am_server; -{ - FILE *fp; - int ret; - char *filename; - struct wordlist *addrs, *opts; - - if (!am_server && ppp_settings.passwd[0] != '\0') { - strlcpy(secret, ppp_settings.passwd, MAXWORDLEN); - } else { - filename = _PATH_SRPFILE; - addrs = NULL; - - fp = fopen(filename, "r"); - if (fp == NULL) { - ppp_error("Can't open srp secret file %s: %m", filename); - return 0; - } - check_access(fp, filename); - - secret[0] = '\0'; - ret = scan_authfile(fp, client, server, secret, &addrs, &opts, - filename, am_server); - fclose(fp); - if (ret < 0) - return 0; - - if (am_server) - set_allowed_addrs(unit, addrs, opts); - else if (opts != NULL) - free_wordlist(opts); - if (addrs != NULL) - free_wordlist(addrs); - } - - return 1; -} - -/* - * set_allowed_addrs() - set the list of allowed addresses. - * Also looks for `--' indicating options to apply for this peer - * and leaves the following words in extra_options. - */ -static void -set_allowed_addrs(unit, addrs, opts) - int unit; - struct wordlist *addrs; - struct wordlist *opts; -{ - int n; - struct wordlist *ap, **plink; - struct permitted_ip *ip; - char *ptr_word, *ptr_mask; - struct hostent *hp; - struct netent *np; - u32_t a, mask, ah, offset; - struct ipcp_options *wo = &ipcp_wantoptions[unit]; - u32_t suggested_ip = 0; - - if (addresses[unit] != NULL) - free(addresses[unit]); - addresses[unit] = NULL; - if (extra_options != NULL) - free_wordlist(extra_options); - extra_options = opts; - - /* - * Count the number of IP addresses given. - */ - n = wordlist_count(addrs) + wordlist_count(noauth_addrs); - if (n == 0) - return; - ip = (struct permitted_ip *) malloc((n + 1) * sizeof(struct permitted_ip)); - if (ip == 0) - return; - - /* temporarily append the noauth_addrs list to addrs */ - for (plink = &addrs; *plink != NULL; plink = &(*plink)->next) - ; - *plink = noauth_addrs; - - n = 0; - for (ap = addrs; ap != NULL; ap = ap->next) { - /* "-" means no addresses authorized, "*" means any address allowed */ - ptr_word = ap->word; - if (strcmp(ptr_word, "-") == 0) - break; - if (strcmp(ptr_word, "*") == 0) { - ip[n].permit = 1; - ip[n].base = ip[n].mask = 0; - ++n; - break; - } - - ip[n].permit = 1; - if (*ptr_word == '!') { - ip[n].permit = 0; - ++ptr_word; - } - - mask = ~ (u32_t) 0; - offset = 0; - ptr_mask = strchr (ptr_word, '/'); - if (ptr_mask != NULL) { - int bit_count; - char *endp; - - bit_count = (int) strtol (ptr_mask+1, &endp, 10); - if (bit_count <= 0 || bit_count > 32) { - ppp_warn("invalid address length %v in auth. address list", - ptr_mask+1); - continue; - } - bit_count = 32 - bit_count; /* # bits in host part */ - if (*endp == '+') { - offset = ifunit + 1; - ++endp; - } - if (*endp != 0) { - ppp_warn("invalid address length syntax: %v", ptr_mask+1); - continue; - } - *ptr_mask = '\0'; - mask <<= bit_count; - } - - hp = gethostbyname(ptr_word); - if (hp != NULL && hp->h_addrtype == AF_INET) { - a = *(u32_t *)hp->h_addr; - } else { - np = getnetbyname (ptr_word); - if (np != NULL && np->n_addrtype == AF_INET) { - a = lwip_htonl ((u32_t)np->n_net); - if (ptr_mask == NULL) { - /* calculate appropriate mask for net */ - ah = lwip_ntohl(a); - if (IN_CLASSA(ah)) - mask = IN_CLASSA_NET; - else if (IN_CLASSB(ah)) - mask = IN_CLASSB_NET; - else if (IN_CLASSC(ah)) - mask = IN_CLASSC_NET; - } - } else { - a = inet_addr (ptr_word); - } - } - - if (ptr_mask != NULL) - *ptr_mask = '/'; - - if (a == (u32_t)-1L) { - ppp_warn("unknown host %s in auth. address list", ap->word); - continue; - } - if (offset != 0) { - if (offset >= ~mask) { - ppp_warn("interface unit %d too large for subnet %v", - ifunit, ptr_word); - continue; - } - a = lwip_htonl((lwip_ntohl(a) & mask) + offset); - mask = ~(u32_t)0; - } - ip[n].mask = lwip_htonl(mask); - ip[n].base = a & ip[n].mask; - ++n; - if (~mask == 0 && suggested_ip == 0) - suggested_ip = a; - } - *plink = NULL; - - ip[n].permit = 0; /* make the last entry forbid all addresses */ - ip[n].base = 0; /* to terminate the list */ - ip[n].mask = 0; - - addresses[unit] = ip; - - /* - * If the address given for the peer isn't authorized, or if - * the user hasn't given one, AND there is an authorized address - * which is a single host, then use that if we find one. - */ - if (suggested_ip != 0 - && (wo->hisaddr == 0 || !auth_ip_addr(unit, wo->hisaddr))) { - wo->hisaddr = suggested_ip; - /* - * Do we insist on this address? No, if there are other - * addresses authorized than the suggested one. - */ - if (n > 1) - wo->accept_remote = 1; - } -} - -/* - * auth_ip_addr - check whether the peer is authorized to use - * a given IP address. Returns 1 if authorized, 0 otherwise. - */ -int -auth_ip_addr(unit, addr) - int unit; - u32_t addr; -{ - int ok; - - /* don't allow loopback or multicast address */ - if (bad_ip_adrs(addr)) - return 0; - - if (allowed_address_hook) { - ok = allowed_address_hook(addr); - if (ok >= 0) return ok; - } - - if (addresses[unit] != NULL) { - ok = ip_addr_check(addr, addresses[unit]); - if (ok >= 0) - return ok; - } - - if (auth_required) - return 0; /* no addresses authorized */ - return allow_any_ip || privileged || !have_route_to(addr); -} - -static int -ip_addr_check(addr, addrs) - u32_t addr; - struct permitted_ip *addrs; -{ - for (; ; ++addrs) - if ((addr & addrs->mask) == addrs->base) - return addrs->permit; -} - -/* - * bad_ip_adrs - return 1 if the IP address is one we don't want - * to use, such as an address in the loopback net or a multicast address. - * addr is in network byte order. - */ -int -bad_ip_adrs(addr) - u32_t addr; -{ - addr = lwip_ntohl(addr); - return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET - || IN_MULTICAST(addr) || IN_BADCLASS(addr); -} - -/* - * some_ip_ok - check a wordlist to see if it authorizes any - * IP address(es). - */ -static int -some_ip_ok(addrs) - struct wordlist *addrs; -{ - for (; addrs != 0; addrs = addrs->next) { - if (addrs->word[0] == '-') - break; - if (addrs->word[0] != '!') - return 1; /* some IP address is allowed */ - } - return 0; -} - -/* - * auth_number - check whether the remote number is allowed to connect. - * Returns 1 if authorized, 0 otherwise. - */ -int -auth_number() -{ - struct wordlist *wp = permitted_numbers; - int l; - - /* Allow all if no authorization list. */ - if (!wp) - return 1; - - /* Allow if we have a match in the authorization list. */ - while (wp) { - /* trailing '*' wildcard */ - l = strlen(wp->word); - if ((wp->word)[l - 1] == '*') - l--; - if (!strncasecmp(wp->word, remote_number, l)) - return 1; - wp = wp->next; - } - - return 0; -} - -/* - * check_access - complain if a secret file has too-liberal permissions. - */ -static void -check_access(f, filename) - FILE *f; - char *filename; -{ - struct stat sbuf; - - if (fstat(fileno(f), &sbuf) < 0) { - ppp_warn("cannot stat secret file %s: %m", filename); - } else if ((sbuf.st_mode & (S_IRWXG | S_IRWXO)) != 0) { - ppp_warn("Warning - secret file %s has world and/or group access", - filename); - } -} - -/* - * scan_authfile - Scan an authorization file for a secret suitable - * for authenticating `client' on `server'. The return value is -1 - * if no secret is found, otherwise >= 0. The return value has - * NONWILD_CLIENT set if the secret didn't have "*" for the client, and - * NONWILD_SERVER set if the secret didn't have "*" for the server. - * Any following words on the line up to a "--" (i.e. address authorization - * info) are placed in a wordlist and returned in *addrs. Any - * following words (extra options) are placed in a wordlist and - * returned in *opts. - * We assume secret is NULL or points to MAXWORDLEN bytes of space. - * Flags are non-zero if we need two colons in the secret in order to - * match. - */ -static int -scan_authfile(f, client, server, secret, addrs, opts, filename, flags) - FILE *f; - char *client; - char *server; - char *secret; - struct wordlist **addrs; - struct wordlist **opts; - char *filename; - int flags; -{ - int newline, xxx; - int got_flag, best_flag; - FILE *sf; - struct wordlist *ap, *addr_list, *alist, **app; - char word[MAXWORDLEN]; - char atfile[MAXWORDLEN]; - char lsecret[MAXWORDLEN]; - char *cp; - - if (addrs != NULL) - *addrs = NULL; - if (opts != NULL) - *opts = NULL; - addr_list = NULL; - if (!getword(f, word, &newline, filename)) - return -1; /* file is empty??? */ - newline = 1; - best_flag = -1; - for (;;) { - /* - * Skip until we find a word at the start of a line. - */ - while (!newline && getword(f, word, &newline, filename)) - ; - if (!newline) - break; /* got to end of file */ - - /* - * Got a client - check if it's a match or a wildcard. - */ - got_flag = 0; - if (client != NULL && strcmp(word, client) != 0 && !ISWILD(word)) { - newline = 0; - continue; - } - if (!ISWILD(word)) - got_flag = NONWILD_CLIENT; - - /* - * Now get a server and check if it matches. - */ - if (!getword(f, word, &newline, filename)) - break; - if (newline) - continue; - if (!ISWILD(word)) { - if (server != NULL && strcmp(word, server) != 0) - continue; - got_flag |= NONWILD_SERVER; - } - - /* - * Got some sort of a match - see if it's better than what - * we have already. - */ - if (got_flag <= best_flag) - continue; - - /* - * Get the secret. - */ - if (!getword(f, word, &newline, filename)) - break; - if (newline) - continue; - - /* - * SRP-SHA1 authenticator should never be reading secrets from - * a file. (Authenticatee may, though.) - */ - if (flags && ((cp = strchr(word, ':')) == NULL || - strchr(cp + 1, ':') == NULL)) - continue; - - if (secret != NULL) { - /* - * Special syntax: @/pathname means read secret from file. - */ - if (word[0] == '@' && word[1] == '/') { - strlcpy(atfile, word+1, sizeof(atfile)); - if ((sf = fopen(atfile, "r")) == NULL) { - ppp_warn("can't open indirect secret file %s", atfile); - continue; - } - check_access(sf, atfile); - if (!getword(sf, word, &xxx, atfile)) { - ppp_warn("no secret in indirect secret file %s", atfile); - fclose(sf); - continue; - } - fclose(sf); - } - strlcpy(lsecret, word, sizeof(lsecret)); - } - - /* - * Now read address authorization info and make a wordlist. - */ - app = &alist; - for (;;) { - if (!getword(f, word, &newline, filename) || newline) - break; - ap = (struct wordlist *) - malloc(sizeof(struct wordlist) + strlen(word) + 1); - if (ap == NULL) - novm("authorized addresses"); - ap->word = (char *) (ap + 1); - strcpy(ap->word, word); - *app = ap; - app = &ap->next; - } - *app = NULL; - - /* - * This is the best so far; remember it. - */ - best_flag = got_flag; - if (addr_list) - free_wordlist(addr_list); - addr_list = alist; - if (secret != NULL) - strlcpy(secret, lsecret, MAXWORDLEN); - - if (!newline) - break; - } - - /* scan for a -- word indicating the start of options */ - for (app = &addr_list; (ap = *app) != NULL; app = &ap->next) - if (strcmp(ap->word, "--") == 0) - break; - /* ap = start of options */ - if (ap != NULL) { - ap = ap->next; /* first option */ - free(*app); /* free the "--" word */ - *app = NULL; /* terminate addr list */ - } - if (opts != NULL) - *opts = ap; - else if (ap != NULL) - free_wordlist(ap); - if (addrs != NULL) - *addrs = addr_list; - else if (addr_list != NULL) - free_wordlist(addr_list); - - return best_flag; -} - -/* - * wordlist_count - return the number of items in a wordlist - */ -static int -wordlist_count(wp) - struct wordlist *wp; -{ - int n; - - for (n = 0; wp != NULL; wp = wp->next) - ++n; - return n; -} - -/* - * free_wordlist - release memory allocated for a wordlist. - */ -static void -free_wordlist(wp) - struct wordlist *wp; -{ - struct wordlist *next; - - while (wp != NULL) { - next = wp->next; - free(wp); - wp = next; - } -} -#endif /* UNUSED */ - -#endif /* PPP_SUPPORT */ diff --git a/third-party/lwip-2.1.2/netif/ppp/ccp.c b/third-party/lwip-2.1.2/netif/ppp/ccp.c deleted file mode 100644 index f8519ebe..00000000 --- a/third-party/lwip-2.1.2/netif/ppp/ccp.c +++ /dev/null @@ -1,1740 +0,0 @@ -/* - * ccp.c - PPP Compression Control Protocol. - * - * Copyright (c) 1994-2002 Paul Mackerras. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 3. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && CCP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include -#include - -#include "netif/ppp/ppp_impl.h" - -#include "netif/ppp/fsm.h" -#include "netif/ppp/ccp.h" - -#if MPPE_SUPPORT -#include "netif/ppp/lcp.h" /* lcp_close(), lcp_fsm */ -#include "netif/ppp/mppe.h" /* mppe_init() */ -#endif /* MPPE_SUPPORT */ - -/* - * Unfortunately there is a bug in zlib which means that using a - * size of 8 (window size = 256) for Deflate compression will cause - * buffer overruns and kernel crashes in the deflate module. - * Until this is fixed we only accept sizes in the range 9 .. 15. - * Thanks to James Carlson for pointing this out. - */ -#define DEFLATE_MIN_WORKS 9 - -/* - * Command-line options. - */ -#if PPP_OPTIONS -static int setbsdcomp (char **); -static int setdeflate (char **); -static char bsd_value[8]; -static char deflate_value[8]; - -/* - * Option variables. - */ -#if MPPE_SUPPORT -bool refuse_mppe_stateful = 1; /* Allow stateful mode? */ -#endif /* MPPE_SUPPORT */ - -static option_t ccp_option_list[] = { - { "noccp", o_bool, &ccp_protent.enabled_flag, - "Disable CCP negotiation" }, - { "-ccp", o_bool, &ccp_protent.enabled_flag, - "Disable CCP negotiation", OPT_ALIAS }, - - { "bsdcomp", o_special, (void *)setbsdcomp, - "Request BSD-Compress packet compression", - OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, bsd_value }, - { "nobsdcomp", o_bool, &ccp_wantoptions[0].bsd_compress, - "don't allow BSD-Compress", OPT_PRIOSUB | OPT_A2CLR, - &ccp_allowoptions[0].bsd_compress }, - { "-bsdcomp", o_bool, &ccp_wantoptions[0].bsd_compress, - "don't allow BSD-Compress", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, - &ccp_allowoptions[0].bsd_compress }, - - { "deflate", o_special, (void *)setdeflate, - "request Deflate compression", - OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, deflate_value }, - { "nodeflate", o_bool, &ccp_wantoptions[0].deflate, - "don't allow Deflate compression", OPT_PRIOSUB | OPT_A2CLR, - &ccp_allowoptions[0].deflate }, - { "-deflate", o_bool, &ccp_wantoptions[0].deflate, - "don't allow Deflate compression", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, - &ccp_allowoptions[0].deflate }, - - { "nodeflatedraft", o_bool, &ccp_wantoptions[0].deflate_draft, - "don't use draft deflate #", OPT_A2COPY, - &ccp_allowoptions[0].deflate_draft }, - - { "predictor1", o_bool, &ccp_wantoptions[0].predictor_1, - "request Predictor-1", OPT_PRIO | 1 }, - { "nopredictor1", o_bool, &ccp_wantoptions[0].predictor_1, - "don't allow Predictor-1", OPT_PRIOSUB | OPT_A2CLR, - &ccp_allowoptions[0].predictor_1 }, - { "-predictor1", o_bool, &ccp_wantoptions[0].predictor_1, - "don't allow Predictor-1", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, - &ccp_allowoptions[0].predictor_1 }, - -#if MPPE_SUPPORT - /* MPPE options are symmetrical ... we only set wantoptions here */ - { "require-mppe", o_bool, &ccp_wantoptions[0].mppe, - "require MPPE encryption", - OPT_PRIO | MPPE_OPT_40 | MPPE_OPT_128 }, - { "+mppe", o_bool, &ccp_wantoptions[0].mppe, - "require MPPE encryption", - OPT_ALIAS | OPT_PRIO | MPPE_OPT_40 | MPPE_OPT_128 }, - { "nomppe", o_bool, &ccp_wantoptions[0].mppe, - "don't allow MPPE encryption", OPT_PRIO }, - { "-mppe", o_bool, &ccp_wantoptions[0].mppe, - "don't allow MPPE encryption", OPT_ALIAS | OPT_PRIO }, - - /* We use ccp_allowoptions[0].mppe as a junk var ... it is reset later */ - { "require-mppe-40", o_bool, &ccp_allowoptions[0].mppe, - "require MPPE 40-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_40, - &ccp_wantoptions[0].mppe }, - { "+mppe-40", o_bool, &ccp_allowoptions[0].mppe, - "require MPPE 40-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_40, - &ccp_wantoptions[0].mppe }, - { "nomppe-40", o_bool, &ccp_allowoptions[0].mppe, - "don't allow MPPE 40-bit encryption", - OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_40, &ccp_wantoptions[0].mppe }, - { "-mppe-40", o_bool, &ccp_allowoptions[0].mppe, - "don't allow MPPE 40-bit encryption", - OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_40, - &ccp_wantoptions[0].mppe }, - - { "require-mppe-128", o_bool, &ccp_allowoptions[0].mppe, - "require MPPE 128-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_128, - &ccp_wantoptions[0].mppe }, - { "+mppe-128", o_bool, &ccp_allowoptions[0].mppe, - "require MPPE 128-bit encryption", - OPT_ALIAS | OPT_PRIO | OPT_A2OR | MPPE_OPT_128, - &ccp_wantoptions[0].mppe }, - { "nomppe-128", o_bool, &ccp_allowoptions[0].mppe, - "don't allow MPPE 128-bit encryption", - OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_128, &ccp_wantoptions[0].mppe }, - { "-mppe-128", o_bool, &ccp_allowoptions[0].mppe, - "don't allow MPPE 128-bit encryption", - OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_128, - &ccp_wantoptions[0].mppe }, - - /* strange one; we always request stateless, but will we allow stateful? */ - { "mppe-stateful", o_bool, &refuse_mppe_stateful, - "allow MPPE stateful mode", OPT_PRIO }, - { "nomppe-stateful", o_bool, &refuse_mppe_stateful, - "disallow MPPE stateful mode", OPT_PRIO | 1 }, -#endif /* MPPE_SUPPORT */ - - { NULL } -}; -#endif /* PPP_OPTIONS */ - -/* - * Protocol entry points from main code. - */ -static void ccp_init(ppp_pcb *pcb); -static void ccp_open(ppp_pcb *pcb); -static void ccp_close(ppp_pcb *pcb, const char *reason); -static void ccp_lowerup(ppp_pcb *pcb); -static void ccp_lowerdown(ppp_pcb *pcb); -static void ccp_input(ppp_pcb *pcb, u_char *pkt, int len); -static void ccp_protrej(ppp_pcb *pcb); -#if PRINTPKT_SUPPORT -static int ccp_printpkt(const u_char *p, int plen, void (*printer) (void *, const char *, ...), void *arg); -#endif /* PRINTPKT_SUPPORT */ -#if PPP_DATAINPUT -static void ccp_datainput(ppp_pcb *pcb, u_char *pkt, int len); -#endif /* PPP_DATAINPUT */ - -const struct protent ccp_protent = { - PPP_CCP, - ccp_init, - ccp_input, - ccp_protrej, - ccp_lowerup, - ccp_lowerdown, - ccp_open, - ccp_close, -#if PRINTPKT_SUPPORT - ccp_printpkt, -#endif /* PRINTPKT_SUPPORT */ -#if PPP_DATAINPUT - ccp_datainput, -#endif /* PPP_DATAINPUT */ -#if PRINTPKT_SUPPORT - "CCP", - "Compressed", -#endif /* PRINTPKT_SUPPORT */ -#if PPP_OPTIONS - ccp_option_list, - NULL, -#endif /* PPP_OPTIONS */ -#if DEMAND_SUPPORT - NULL, - NULL -#endif /* DEMAND_SUPPORT */ -}; - -/* - * Callbacks for fsm code. - */ -static void ccp_resetci (fsm *); -static int ccp_cilen (fsm *); -static void ccp_addci (fsm *, u_char *, int *); -static int ccp_ackci (fsm *, u_char *, int); -static int ccp_nakci (fsm *, u_char *, int, int); -static int ccp_rejci (fsm *, u_char *, int); -static int ccp_reqci (fsm *, u_char *, int *, int); -static void ccp_up (fsm *); -static void ccp_down (fsm *); -static int ccp_extcode (fsm *, int, int, u_char *, int); -static void ccp_rack_timeout (void *); -static const char *method_name (ccp_options *, ccp_options *); - -static const fsm_callbacks ccp_callbacks = { - ccp_resetci, - ccp_cilen, - ccp_addci, - ccp_ackci, - ccp_nakci, - ccp_rejci, - ccp_reqci, - ccp_up, - ccp_down, - NULL, - NULL, - NULL, - NULL, - ccp_extcode, - "CCP" -}; - -/* - * Do we want / did we get any compression? - */ -static int ccp_anycompress(ccp_options *opt) { - return (0 -#if DEFLATE_SUPPORT - || (opt)->deflate -#endif /* DEFLATE_SUPPORT */ -#if BSDCOMPRESS_SUPPORT - || (opt)->bsd_compress -#endif /* BSDCOMPRESS_SUPPORT */ -#if PREDICTOR_SUPPORT - || (opt)->predictor_1 || (opt)->predictor_2 -#endif /* PREDICTOR_SUPPORT */ -#if MPPE_SUPPORT - || (opt)->mppe -#endif /* MPPE_SUPPORT */ - ); -} - -/* - * Local state (mainly for handling reset-reqs and reset-acks). - */ -#define RACK_PENDING 1 /* waiting for reset-ack */ -#define RREQ_REPEAT 2 /* send another reset-req if no reset-ack */ - -#define RACKTIMEOUT 1 /* second */ - -#if PPP_OPTIONS -/* - * Option parsing - */ -static int -setbsdcomp(argv) - char **argv; -{ - int rbits, abits; - char *str, *endp; - - str = *argv; - abits = rbits = strtol(str, &endp, 0); - if (endp != str && *endp == ',') { - str = endp + 1; - abits = strtol(str, &endp, 0); - } - if (*endp != 0 || endp == str) { - option_error("invalid parameter '%s' for bsdcomp option", *argv); - return 0; - } - if ((rbits != 0 && (rbits < BSD_MIN_BITS || rbits > BSD_MAX_BITS)) - || (abits != 0 && (abits < BSD_MIN_BITS || abits > BSD_MAX_BITS))) { - option_error("bsdcomp option values must be 0 or %d .. %d", - BSD_MIN_BITS, BSD_MAX_BITS); - return 0; - } - if (rbits > 0) { - ccp_wantoptions[0].bsd_compress = 1; - ccp_wantoptions[0].bsd_bits = rbits; - } else - ccp_wantoptions[0].bsd_compress = 0; - if (abits > 0) { - ccp_allowoptions[0].bsd_compress = 1; - ccp_allowoptions[0].bsd_bits = abits; - } else - ccp_allowoptions[0].bsd_compress = 0; - ppp_slprintf(bsd_value, sizeof(bsd_value), - rbits == abits? "%d": "%d,%d", rbits, abits); - - return 1; -} - -static int -setdeflate(argv) - char **argv; -{ - int rbits, abits; - char *str, *endp; - - str = *argv; - abits = rbits = strtol(str, &endp, 0); - if (endp != str && *endp == ',') { - str = endp + 1; - abits = strtol(str, &endp, 0); - } - if (*endp != 0 || endp == str) { - option_error("invalid parameter '%s' for deflate option", *argv); - return 0; - } - if ((rbits != 0 && (rbits < DEFLATE_MIN_SIZE || rbits > DEFLATE_MAX_SIZE)) - || (abits != 0 && (abits < DEFLATE_MIN_SIZE - || abits > DEFLATE_MAX_SIZE))) { - option_error("deflate option values must be 0 or %d .. %d", - DEFLATE_MIN_SIZE, DEFLATE_MAX_SIZE); - return 0; - } - if (rbits == DEFLATE_MIN_SIZE || abits == DEFLATE_MIN_SIZE) { - if (rbits == DEFLATE_MIN_SIZE) - rbits = DEFLATE_MIN_WORKS; - if (abits == DEFLATE_MIN_SIZE) - abits = DEFLATE_MIN_WORKS; - warn("deflate option value of %d changed to %d to avoid zlib bug", - DEFLATE_MIN_SIZE, DEFLATE_MIN_WORKS); - } - if (rbits > 0) { - ccp_wantoptions[0].deflate = 1; - ccp_wantoptions[0].deflate_size = rbits; - } else - ccp_wantoptions[0].deflate = 0; - if (abits > 0) { - ccp_allowoptions[0].deflate = 1; - ccp_allowoptions[0].deflate_size = abits; - } else - ccp_allowoptions[0].deflate = 0; - ppp_slprintf(deflate_value, sizeof(deflate_value), - rbits == abits? "%d": "%d,%d", rbits, abits); - - return 1; -} -#endif /* PPP_OPTIONS */ - -/* - * ccp_init - initialize CCP. - */ -static void ccp_init(ppp_pcb *pcb) { - fsm *f = &pcb->ccp_fsm; - - f->pcb = pcb; - f->protocol = PPP_CCP; - f->callbacks = &ccp_callbacks; - fsm_init(f); - -#if 0 /* Not necessary, everything is cleared in ppp_new() */ - memset(wo, 0, sizeof(*wo)); - memset(go, 0, sizeof(*go)); - memset(ao, 0, sizeof(*ao)); - memset(ho, 0, sizeof(*ho)); -#endif /* 0 */ - -#if DEFLATE_SUPPORT - wo->deflate = 1; - wo->deflate_size = DEFLATE_MAX_SIZE; - wo->deflate_correct = 1; - wo->deflate_draft = 1; - ao->deflate = 1; - ao->deflate_size = DEFLATE_MAX_SIZE; - ao->deflate_correct = 1; - ao->deflate_draft = 1; -#endif /* DEFLATE_SUPPORT */ - -#if BSDCOMPRESS_SUPPORT - wo->bsd_compress = 1; - wo->bsd_bits = BSD_MAX_BITS; - ao->bsd_compress = 1; - ao->bsd_bits = BSD_MAX_BITS; -#endif /* BSDCOMPRESS_SUPPORT */ - -#if PREDICTOR_SUPPORT - ao->predictor_1 = 1; -#endif /* PREDICTOR_SUPPORT */ -} - -/* - * ccp_open - CCP is allowed to come up. - */ -static void ccp_open(ppp_pcb *pcb) { - fsm *f = &pcb->ccp_fsm; - ccp_options *go = &pcb->ccp_gotoptions; - - if (f->state != PPP_FSM_OPENED) - ccp_set(pcb, 1, 0, 0, 0); - - /* - * Find out which compressors the kernel supports before - * deciding whether to open in silent mode. - */ - ccp_resetci(f); - if (!ccp_anycompress(go)) - f->flags |= OPT_SILENT; - - fsm_open(f); -} - -/* - * ccp_close - Terminate CCP. - */ -static void ccp_close(ppp_pcb *pcb, const char *reason) { - fsm *f = &pcb->ccp_fsm; - ccp_set(pcb, 0, 0, 0, 0); - fsm_close(f, reason); -} - -/* - * ccp_lowerup - we may now transmit CCP packets. - */ -static void ccp_lowerup(ppp_pcb *pcb) { - fsm *f = &pcb->ccp_fsm; - fsm_lowerup(f); -} - -/* - * ccp_lowerdown - we may not transmit CCP packets. - */ -static void ccp_lowerdown(ppp_pcb *pcb) { - fsm *f = &pcb->ccp_fsm; - fsm_lowerdown(f); -} - -/* - * ccp_input - process a received CCP packet. - */ -static void ccp_input(ppp_pcb *pcb, u_char *p, int len) { - fsm *f = &pcb->ccp_fsm; - ccp_options *go = &pcb->ccp_gotoptions; - int oldstate; - - /* - * Check for a terminate-request so we can print a message. - */ - oldstate = f->state; - fsm_input(f, p, len); - if (oldstate == PPP_FSM_OPENED && p[0] == TERMREQ && f->state != PPP_FSM_OPENED) { - ppp_notice("Compression disabled by peer."); -#if MPPE_SUPPORT - if (go->mppe) { - ppp_error("MPPE disabled, closing LCP"); - lcp_close(pcb, "MPPE disabled by peer"); - } -#endif /* MPPE_SUPPORT */ - } - - /* - * If we get a terminate-ack and we're not asking for compression, - * close CCP. - */ - if (oldstate == PPP_FSM_REQSENT && p[0] == TERMACK - && !ccp_anycompress(go)) - ccp_close(pcb, "No compression negotiated"); -} - -/* - * Handle a CCP-specific code. - */ -static int ccp_extcode(fsm *f, int code, int id, u_char *p, int len) { - ppp_pcb *pcb = f->pcb; - LWIP_UNUSED_ARG(p); - LWIP_UNUSED_ARG(len); - - switch (code) { - case CCP_RESETREQ: - if (f->state != PPP_FSM_OPENED) - break; - ccp_reset_comp(pcb); - /* send a reset-ack, which the transmitter will see and - reset its compression state. */ - fsm_sdata(f, CCP_RESETACK, id, NULL, 0); - break; - - case CCP_RESETACK: - if ((pcb->ccp_localstate & RACK_PENDING) && id == f->reqid) { - pcb->ccp_localstate &= ~(RACK_PENDING | RREQ_REPEAT); - UNTIMEOUT(ccp_rack_timeout, f); - ccp_reset_decomp(pcb); - } - break; - - default: - return 0; - } - - return 1; -} - -/* - * ccp_protrej - peer doesn't talk CCP. - */ -static void ccp_protrej(ppp_pcb *pcb) { - fsm *f = &pcb->ccp_fsm; -#if MPPE_SUPPORT - ccp_options *go = &pcb->ccp_gotoptions; -#endif /* MPPE_SUPPORT */ - - ccp_set(pcb, 0, 0, 0, 0); - fsm_lowerdown(f); - -#if MPPE_SUPPORT - if (go->mppe) { - ppp_error("MPPE required but peer negotiation failed"); - lcp_close(pcb, "MPPE required but peer negotiation failed"); - } -#endif /* MPPE_SUPPORT */ - -} - -/* - * ccp_resetci - initialize at start of negotiation. - */ -static void ccp_resetci(fsm *f) { - ppp_pcb *pcb = f->pcb; - ccp_options *go = &pcb->ccp_gotoptions; - ccp_options *wo = &pcb->ccp_wantoptions; -#if MPPE_SUPPORT - ccp_options *ao = &pcb->ccp_allowoptions; -#endif /* MPPE_SUPPORT */ -#if DEFLATE_SUPPORT || BSDCOMPRESS_SUPPORT || PREDICTOR_SUPPORT - u_char opt_buf[CCP_MAX_OPTION_LENGTH]; -#endif /* DEFLATE_SUPPORT || BSDCOMPRESS_SUPPORT || PREDICTOR_SUPPORT */ -#if DEFLATE_SUPPORT || BSDCOMPRESS_SUPPORT - int res; -#endif /* DEFLATE_SUPPORT || BSDCOMPRESS_SUPPORT */ - -#if MPPE_SUPPORT - if (pcb->settings.require_mppe) { - wo->mppe = ao->mppe = - (pcb->settings.refuse_mppe_40 ? 0 : MPPE_OPT_40) - | (pcb->settings.refuse_mppe_128 ? 0 : MPPE_OPT_128); - } -#endif /* MPPE_SUPPORT */ - - *go = *wo; - pcb->ccp_all_rejected = 0; - -#if MPPE_SUPPORT - if (go->mppe) { - int auth_mschap_bits = pcb->auth_done; - int numbits; - - /* - * Start with a basic sanity check: mschap[v2] auth must be in - * exactly one direction. RFC 3079 says that the keys are - * 'derived from the credentials of the peer that initiated the call', - * however the PPP protocol doesn't have such a concept, and pppd - * cannot get this info externally. Instead we do the best we can. - * NB: If MPPE is required, all other compression opts are invalid. - * So, we return right away if we can't do it. - */ - - /* Leave only the mschap auth bits set */ - auth_mschap_bits &= (CHAP_MS_WITHPEER | CHAP_MS_PEER | - CHAP_MS2_WITHPEER | CHAP_MS2_PEER); - /* Count the mschap auths */ - auth_mschap_bits >>= CHAP_MS_SHIFT; - numbits = 0; - do { - numbits += auth_mschap_bits & 1; - auth_mschap_bits >>= 1; - } while (auth_mschap_bits); - if (numbits > 1) { - ppp_error("MPPE required, but auth done in both directions."); - lcp_close(pcb, "MPPE required but not available"); - return; - } - if (!numbits) { - ppp_error("MPPE required, but MS-CHAP[v2] auth not performed."); - lcp_close(pcb, "MPPE required but not available"); - return; - } - - /* A plugin (eg radius) may not have obtained key material. */ - if (!pcb->mppe_keys_set) { - ppp_error("MPPE required, but keys are not available. " - "Possible plugin problem?"); - lcp_close(pcb, "MPPE required but not available"); - return; - } - - /* LM auth not supported for MPPE */ - if (pcb->auth_done & (CHAP_MS_WITHPEER | CHAP_MS_PEER)) { - /* This might be noise */ - if (go->mppe & MPPE_OPT_40) { - ppp_notice("Disabling 40-bit MPPE; MS-CHAP LM not supported"); - go->mppe &= ~MPPE_OPT_40; - wo->mppe &= ~MPPE_OPT_40; - } - } - - /* Last check: can we actually negotiate something? */ - if (!(go->mppe & (MPPE_OPT_40 | MPPE_OPT_128))) { - /* Could be misconfig, could be 40-bit disabled above. */ - ppp_error("MPPE required, but both 40-bit and 128-bit disabled."); - lcp_close(pcb, "MPPE required but not available"); - return; - } - - /* sync options */ - ao->mppe = go->mppe; - /* MPPE is not compatible with other compression types */ -#if BSDCOMPRESS_SUPPORT - ao->bsd_compress = go->bsd_compress = 0; -#endif /* BSDCOMPRESS_SUPPORT */ -#if PREDICTOR_SUPPORT - ao->predictor_1 = go->predictor_1 = 0; - ao->predictor_2 = go->predictor_2 = 0; -#endif /* PREDICTOR_SUPPORT */ -#if DEFLATE_SUPPORT - ao->deflate = go->deflate = 0; -#endif /* DEFLATE_SUPPORT */ - } -#endif /* MPPE_SUPPORT */ - - /* - * Check whether the kernel knows about the various - * compression methods we might request. - */ -#if BSDCOMPRESS_SUPPORT - /* FIXME: we don't need to test if BSD compress is available - * if BSDCOMPRESS_SUPPORT is set, it is. - */ - if (go->bsd_compress) { - opt_buf[0] = CI_BSD_COMPRESS; - opt_buf[1] = CILEN_BSD_COMPRESS; - for (;;) { - if (go->bsd_bits < BSD_MIN_BITS) { - go->bsd_compress = 0; - break; - } - opt_buf[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits); - res = ccp_test(pcb, opt_buf, CILEN_BSD_COMPRESS, 0); - if (res > 0) { - break; - } else if (res < 0) { - go->bsd_compress = 0; - break; - } - go->bsd_bits--; - } - } -#endif /* BSDCOMPRESS_SUPPORT */ -#if DEFLATE_SUPPORT - /* FIXME: we don't need to test if deflate is available - * if DEFLATE_SUPPORT is set, it is. - */ - if (go->deflate) { - if (go->deflate_correct) { - opt_buf[0] = CI_DEFLATE; - opt_buf[1] = CILEN_DEFLATE; - opt_buf[3] = DEFLATE_CHK_SEQUENCE; - for (;;) { - if (go->deflate_size < DEFLATE_MIN_WORKS) { - go->deflate_correct = 0; - break; - } - opt_buf[2] = DEFLATE_MAKE_OPT(go->deflate_size); - res = ccp_test(pcb, opt_buf, CILEN_DEFLATE, 0); - if (res > 0) { - break; - } else if (res < 0) { - go->deflate_correct = 0; - break; - } - go->deflate_size--; - } - } - if (go->deflate_draft) { - opt_buf[0] = CI_DEFLATE_DRAFT; - opt_buf[1] = CILEN_DEFLATE; - opt_buf[3] = DEFLATE_CHK_SEQUENCE; - for (;;) { - if (go->deflate_size < DEFLATE_MIN_WORKS) { - go->deflate_draft = 0; - break; - } - opt_buf[2] = DEFLATE_MAKE_OPT(go->deflate_size); - res = ccp_test(pcb, opt_buf, CILEN_DEFLATE, 0); - if (res > 0) { - break; - } else if (res < 0) { - go->deflate_draft = 0; - break; - } - go->deflate_size--; - } - } - if (!go->deflate_correct && !go->deflate_draft) - go->deflate = 0; - } -#endif /* DEFLATE_SUPPORT */ -#if PREDICTOR_SUPPORT - /* FIXME: we don't need to test if predictor is available, - * if PREDICTOR_SUPPORT is set, it is. - */ - if (go->predictor_1) { - opt_buf[0] = CI_PREDICTOR_1; - opt_buf[1] = CILEN_PREDICTOR_1; - if (ccp_test(pcb, opt_buf, CILEN_PREDICTOR_1, 0) <= 0) - go->predictor_1 = 0; - } - if (go->predictor_2) { - opt_buf[0] = CI_PREDICTOR_2; - opt_buf[1] = CILEN_PREDICTOR_2; - if (ccp_test(pcb, opt_buf, CILEN_PREDICTOR_2, 0) <= 0) - go->predictor_2 = 0; - } -#endif /* PREDICTOR_SUPPORT */ -} - -/* - * ccp_cilen - Return total length of our configuration info. - */ -static int ccp_cilen(fsm *f) { - ppp_pcb *pcb = f->pcb; - ccp_options *go = &pcb->ccp_gotoptions; - - return 0 -#if BSDCOMPRESS_SUPPORT - + (go->bsd_compress? CILEN_BSD_COMPRESS: 0) -#endif /* BSDCOMPRESS_SUPPORT */ -#if DEFLATE_SUPPORT - + (go->deflate && go->deflate_correct? CILEN_DEFLATE: 0) - + (go->deflate && go->deflate_draft? CILEN_DEFLATE: 0) -#endif /* DEFLATE_SUPPORT */ -#if PREDICTOR_SUPPORT - + (go->predictor_1? CILEN_PREDICTOR_1: 0) - + (go->predictor_2? CILEN_PREDICTOR_2: 0) -#endif /* PREDICTOR_SUPPORT */ -#if MPPE_SUPPORT - + (go->mppe? CILEN_MPPE: 0) -#endif /* MPPE_SUPPORT */ - ; -} - -/* - * ccp_addci - put our requests in a packet. - */ -static void ccp_addci(fsm *f, u_char *p, int *lenp) { - ppp_pcb *pcb = f->pcb; - ccp_options *go = &pcb->ccp_gotoptions; - u_char *p0 = p; - - /* - * Add the compression types that we can receive, in decreasing - * preference order. - */ -#if MPPE_SUPPORT - if (go->mppe) { - p[0] = CI_MPPE; - p[1] = CILEN_MPPE; - MPPE_OPTS_TO_CI(go->mppe, &p[2]); - mppe_init(pcb, &pcb->mppe_decomp, go->mppe); - p += CILEN_MPPE; - } -#endif /* MPPE_SUPPORT */ -#if DEFLATE_SUPPORT - if (go->deflate) { - if (go->deflate_correct) { - p[0] = CI_DEFLATE; - p[1] = CILEN_DEFLATE; - p[2] = DEFLATE_MAKE_OPT(go->deflate_size); - p[3] = DEFLATE_CHK_SEQUENCE; - p += CILEN_DEFLATE; - } - if (go->deflate_draft) { - p[0] = CI_DEFLATE_DRAFT; - p[1] = CILEN_DEFLATE; - p[2] = p[2 - CILEN_DEFLATE]; - p[3] = DEFLATE_CHK_SEQUENCE; - p += CILEN_DEFLATE; - } - } -#endif /* DEFLATE_SUPPORT */ -#if BSDCOMPRESS_SUPPORT - if (go->bsd_compress) { - p[0] = CI_BSD_COMPRESS; - p[1] = CILEN_BSD_COMPRESS; - p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits); - p += CILEN_BSD_COMPRESS; - } -#endif /* BSDCOMPRESS_SUPPORT */ -#if PREDICTOR_SUPPORT - /* XXX Should Predictor 2 be preferable to Predictor 1? */ - if (go->predictor_1) { - p[0] = CI_PREDICTOR_1; - p[1] = CILEN_PREDICTOR_1; - p += CILEN_PREDICTOR_1; - } - if (go->predictor_2) { - p[0] = CI_PREDICTOR_2; - p[1] = CILEN_PREDICTOR_2; - p += CILEN_PREDICTOR_2; - } -#endif /* PREDICTOR_SUPPORT */ - - go->method = (p > p0)? p0[0]: 0; - - *lenp = p - p0; -} - -/* - * ccp_ackci - process a received configure-ack, and return - * 1 iff the packet was OK. - */ -static int ccp_ackci(fsm *f, u_char *p, int len) { - ppp_pcb *pcb = f->pcb; - ccp_options *go = &pcb->ccp_gotoptions; -#if BSDCOMPRESS_SUPPORT || PREDICTOR_SUPPORT - u_char *p0 = p; -#endif /* BSDCOMPRESS_SUPPORT || PREDICTOR_SUPPORT */ - -#if MPPE_SUPPORT - if (go->mppe) { - u_char opt_buf[CILEN_MPPE]; - - opt_buf[0] = CI_MPPE; - opt_buf[1] = CILEN_MPPE; - MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]); - if (len < CILEN_MPPE || memcmp(opt_buf, p, CILEN_MPPE)) - return 0; - p += CILEN_MPPE; - len -= CILEN_MPPE; - /* XXX Cope with first/fast ack */ - if (len == 0) - return 1; - } -#endif /* MPPE_SUPPORT */ -#if DEFLATE_SUPPORT - if (go->deflate) { - if (len < CILEN_DEFLATE - || p[0] != (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT) - || p[1] != CILEN_DEFLATE - || p[2] != DEFLATE_MAKE_OPT(go->deflate_size) - || p[3] != DEFLATE_CHK_SEQUENCE) - return 0; - p += CILEN_DEFLATE; - len -= CILEN_DEFLATE; - /* XXX Cope with first/fast ack */ - if (len == 0) - return 1; - if (go->deflate_correct && go->deflate_draft) { - if (len < CILEN_DEFLATE - || p[0] != CI_DEFLATE_DRAFT - || p[1] != CILEN_DEFLATE - || p[2] != DEFLATE_MAKE_OPT(go->deflate_size) - || p[3] != DEFLATE_CHK_SEQUENCE) - return 0; - p += CILEN_DEFLATE; - len -= CILEN_DEFLATE; - } - } -#endif /* DEFLATE_SUPPORT */ -#if BSDCOMPRESS_SUPPORT - if (go->bsd_compress) { - if (len < CILEN_BSD_COMPRESS - || p[0] != CI_BSD_COMPRESS || p[1] != CILEN_BSD_COMPRESS - || p[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits)) - return 0; - p += CILEN_BSD_COMPRESS; - len -= CILEN_BSD_COMPRESS; - /* XXX Cope with first/fast ack */ - if (p == p0 && len == 0) - return 1; - } -#endif /* BSDCOMPRESS_SUPPORT */ -#if PREDICTOR_SUPPORT - if (go->predictor_1) { - if (len < CILEN_PREDICTOR_1 - || p[0] != CI_PREDICTOR_1 || p[1] != CILEN_PREDICTOR_1) - return 0; - p += CILEN_PREDICTOR_1; - len -= CILEN_PREDICTOR_1; - /* XXX Cope with first/fast ack */ - if (p == p0 && len == 0) - return 1; - } - if (go->predictor_2) { - if (len < CILEN_PREDICTOR_2 - || p[0] != CI_PREDICTOR_2 || p[1] != CILEN_PREDICTOR_2) - return 0; - p += CILEN_PREDICTOR_2; - len -= CILEN_PREDICTOR_2; - /* XXX Cope with first/fast ack */ - if (p == p0 && len == 0) - return 1; - } -#endif /* PREDICTOR_SUPPORT */ - - if (len != 0) - return 0; - return 1; -} - -/* - * ccp_nakci - process received configure-nak. - * Returns 1 iff the nak was OK. - */ -static int ccp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { - ppp_pcb *pcb = f->pcb; - ccp_options *go = &pcb->ccp_gotoptions; - ccp_options no; /* options we've seen already */ - ccp_options try_; /* options to ask for next time */ - LWIP_UNUSED_ARG(treat_as_reject); -#if !MPPE_SUPPORT && !DEFLATE_SUPPORT && !BSDCOMPRESS_SUPPORT - LWIP_UNUSED_ARG(p); - LWIP_UNUSED_ARG(len); -#endif /* !MPPE_SUPPORT && !DEFLATE_SUPPORT && !BSDCOMPRESS_SUPPORT */ - - memset(&no, 0, sizeof(no)); - try_ = *go; - -#if MPPE_SUPPORT - if (go->mppe && len >= CILEN_MPPE - && p[0] == CI_MPPE && p[1] == CILEN_MPPE) { - no.mppe = 1; - /* - * Peer wants us to use a different strength or other setting. - * Fail if we aren't willing to use his suggestion. - */ - MPPE_CI_TO_OPTS(&p[2], try_.mppe); - if ((try_.mppe & MPPE_OPT_STATEFUL) && pcb->settings.refuse_mppe_stateful) { - ppp_error("Refusing MPPE stateful mode offered by peer"); - try_.mppe = 0; - } else if (((go->mppe | MPPE_OPT_STATEFUL) & try_.mppe) != try_.mppe) { - /* Peer must have set options we didn't request (suggest) */ - try_.mppe = 0; - } - - if (!try_.mppe) { - ppp_error("MPPE required but peer negotiation failed"); - lcp_close(pcb, "MPPE required but peer negotiation failed"); - } - } -#endif /* MPPE_SUPPORT */ -#if DEFLATE_SUPPORT - if (go->deflate && len >= CILEN_DEFLATE - && p[0] == (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT) - && p[1] == CILEN_DEFLATE) { - no.deflate = 1; - /* - * Peer wants us to use a different code size or something. - * Stop asking for Deflate if we don't understand his suggestion. - */ - if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL - || DEFLATE_SIZE(p[2]) < DEFLATE_MIN_WORKS - || p[3] != DEFLATE_CHK_SEQUENCE) - try_.deflate = 0; - else if (DEFLATE_SIZE(p[2]) < go->deflate_size) - try_.deflate_size = DEFLATE_SIZE(p[2]); - p += CILEN_DEFLATE; - len -= CILEN_DEFLATE; - if (go->deflate_correct && go->deflate_draft - && len >= CILEN_DEFLATE && p[0] == CI_DEFLATE_DRAFT - && p[1] == CILEN_DEFLATE) { - p += CILEN_DEFLATE; - len -= CILEN_DEFLATE; - } - } -#endif /* DEFLATE_SUPPORT */ -#if BSDCOMPRESS_SUPPORT - if (go->bsd_compress && len >= CILEN_BSD_COMPRESS - && p[0] == CI_BSD_COMPRESS && p[1] == CILEN_BSD_COMPRESS) { - no.bsd_compress = 1; - /* - * Peer wants us to use a different number of bits - * or a different version. - */ - if (BSD_VERSION(p[2]) != BSD_CURRENT_VERSION) - try_.bsd_compress = 0; - else if (BSD_NBITS(p[2]) < go->bsd_bits) - try_.bsd_bits = BSD_NBITS(p[2]); - p += CILEN_BSD_COMPRESS; - len -= CILEN_BSD_COMPRESS; - } -#endif /* BSDCOMPRESS_SUPPORT */ - - /* - * Predictor-1 and 2 have no options, so they can't be Naked. - * - * There may be remaining options but we ignore them. - */ - - if (f->state != PPP_FSM_OPENED) - *go = try_; - return 1; -} - -/* - * ccp_rejci - reject some of our suggested compression methods. - */ -static int ccp_rejci(fsm *f, u_char *p, int len) { - ppp_pcb *pcb = f->pcb; - ccp_options *go = &pcb->ccp_gotoptions; - ccp_options try_; /* options to request next time */ - - try_ = *go; - - /* - * Cope with empty configure-rejects by ceasing to send - * configure-requests. - */ - if (len == 0 && pcb->ccp_all_rejected) - return -1; - -#if MPPE_SUPPORT - if (go->mppe && len >= CILEN_MPPE - && p[0] == CI_MPPE && p[1] == CILEN_MPPE) { - ppp_error("MPPE required but peer refused"); - lcp_close(pcb, "MPPE required but peer refused"); - p += CILEN_MPPE; - len -= CILEN_MPPE; - } -#endif /* MPPE_SUPPORT */ -#if DEFLATE_SUPPORT - if (go->deflate_correct && len >= CILEN_DEFLATE - && p[0] == CI_DEFLATE && p[1] == CILEN_DEFLATE) { - if (p[2] != DEFLATE_MAKE_OPT(go->deflate_size) - || p[3] != DEFLATE_CHK_SEQUENCE) - return 0; /* Rej is bad */ - try_.deflate_correct = 0; - p += CILEN_DEFLATE; - len -= CILEN_DEFLATE; - } - if (go->deflate_draft && len >= CILEN_DEFLATE - && p[0] == CI_DEFLATE_DRAFT && p[1] == CILEN_DEFLATE) { - if (p[2] != DEFLATE_MAKE_OPT(go->deflate_size) - || p[3] != DEFLATE_CHK_SEQUENCE) - return 0; /* Rej is bad */ - try_.deflate_draft = 0; - p += CILEN_DEFLATE; - len -= CILEN_DEFLATE; - } - if (!try_.deflate_correct && !try_.deflate_draft) - try_.deflate = 0; -#endif /* DEFLATE_SUPPORT */ -#if BSDCOMPRESS_SUPPORT - if (go->bsd_compress && len >= CILEN_BSD_COMPRESS - && p[0] == CI_BSD_COMPRESS && p[1] == CILEN_BSD_COMPRESS) { - if (p[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits)) - return 0; - try_.bsd_compress = 0; - p += CILEN_BSD_COMPRESS; - len -= CILEN_BSD_COMPRESS; - } -#endif /* BSDCOMPRESS_SUPPORT */ -#if PREDICTOR_SUPPORT - if (go->predictor_1 && len >= CILEN_PREDICTOR_1 - && p[0] == CI_PREDICTOR_1 && p[1] == CILEN_PREDICTOR_1) { - try_.predictor_1 = 0; - p += CILEN_PREDICTOR_1; - len -= CILEN_PREDICTOR_1; - } - if (go->predictor_2 && len >= CILEN_PREDICTOR_2 - && p[0] == CI_PREDICTOR_2 && p[1] == CILEN_PREDICTOR_2) { - try_.predictor_2 = 0; - p += CILEN_PREDICTOR_2; - len -= CILEN_PREDICTOR_2; - } -#endif /* PREDICTOR_SUPPORT */ - - if (len != 0) - return 0; - - if (f->state != PPP_FSM_OPENED) - *go = try_; - - return 1; -} - -/* - * ccp_reqci - processed a received configure-request. - * Returns CONFACK, CONFNAK or CONFREJ and the packet modified - * appropriately. - */ -static int ccp_reqci(fsm *f, u_char *p, int *lenp, int dont_nak) { - ppp_pcb *pcb = f->pcb; - ccp_options *ho = &pcb->ccp_hisoptions; - ccp_options *ao = &pcb->ccp_allowoptions; - int ret, newret; -#if DEFLATE_SUPPORT || BSDCOMPRESS_SUPPORT - int res; - int nb; -#endif /* DEFLATE_SUPPORT || BSDCOMPRESS_SUPPORT */ - u_char *p0, *retp; - int len, clen, type; -#if MPPE_SUPPORT - u8_t rej_for_ci_mppe = 1; /* Are we rejecting based on a bad/missing */ - /* CI_MPPE, or due to other options? */ -#endif /* MPPE_SUPPORT */ - - ret = CONFACK; - retp = p0 = p; - len = *lenp; - - memset(ho, 0, sizeof(ccp_options)); - ho->method = (len > 0)? p[0]: 0; - - while (len > 0) { - newret = CONFACK; - if (len < 2 || p[1] < 2 || p[1] > len) { - /* length is bad */ - clen = len; - newret = CONFREJ; - - } else { - type = p[0]; - clen = p[1]; - - switch (type) { -#if MPPE_SUPPORT - case CI_MPPE: - if (!ao->mppe || clen != CILEN_MPPE) { - newret = CONFREJ; - break; - } - MPPE_CI_TO_OPTS(&p[2], ho->mppe); - - /* Nak if anything unsupported or unknown are set. */ - if (ho->mppe & MPPE_OPT_UNSUPPORTED) { - newret = CONFNAK; - ho->mppe &= ~MPPE_OPT_UNSUPPORTED; - } - if (ho->mppe & MPPE_OPT_UNKNOWN) { - newret = CONFNAK; - ho->mppe &= ~MPPE_OPT_UNKNOWN; - } - - /* Check state opt */ - if (ho->mppe & MPPE_OPT_STATEFUL) { - /* - * We can Nak and request stateless, but it's a - * lot easier to just assume the peer will request - * it if he can do it; stateful mode is bad over - * the Internet -- which is where we expect MPPE. - */ - if (pcb->settings.refuse_mppe_stateful) { - ppp_error("Refusing MPPE stateful mode offered by peer"); - newret = CONFREJ; - break; - } - } - - /* Find out which of {S,L} are set. */ - if ((ho->mppe & MPPE_OPT_128) - && (ho->mppe & MPPE_OPT_40)) { - /* Both are set, negotiate the strongest. */ - newret = CONFNAK; - if (ao->mppe & MPPE_OPT_128) - ho->mppe &= ~MPPE_OPT_40; - else if (ao->mppe & MPPE_OPT_40) - ho->mppe &= ~MPPE_OPT_128; - else { - newret = CONFREJ; - break; - } - } else if (ho->mppe & MPPE_OPT_128) { - if (!(ao->mppe & MPPE_OPT_128)) { - newret = CONFREJ; - break; - } - } else if (ho->mppe & MPPE_OPT_40) { - if (!(ao->mppe & MPPE_OPT_40)) { - newret = CONFREJ; - break; - } - } else { - /* Neither are set. */ - /* We cannot accept this. */ - newret = CONFNAK; - /* Give the peer our idea of what can be used, - so it can choose and confirm */ - ho->mppe = ao->mppe; - } - - /* rebuild the opts */ - MPPE_OPTS_TO_CI(ho->mppe, &p[2]); - if (newret == CONFACK) { - int mtu; - - mppe_init(pcb, &pcb->mppe_comp, ho->mppe); - /* - * We need to decrease the interface MTU by MPPE_PAD - * because MPPE frames **grow**. The kernel [must] - * allocate MPPE_PAD extra bytes in xmit buffers. - */ - mtu = netif_get_mtu(pcb); - if (mtu) - netif_set_mtu(pcb, mtu - MPPE_PAD); - else - newret = CONFREJ; - } - - /* - * We have accepted MPPE or are willing to negotiate - * MPPE parameters. A CONFREJ is due to subsequent - * (non-MPPE) processing. - */ - rej_for_ci_mppe = 0; - break; -#endif /* MPPE_SUPPORT */ -#if DEFLATE_SUPPORT - case CI_DEFLATE: - case CI_DEFLATE_DRAFT: - if (!ao->deflate || clen != CILEN_DEFLATE - || (!ao->deflate_correct && type == CI_DEFLATE) - || (!ao->deflate_draft && type == CI_DEFLATE_DRAFT)) { - newret = CONFREJ; - break; - } - - ho->deflate = 1; - ho->deflate_size = nb = DEFLATE_SIZE(p[2]); - if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL - || p[3] != DEFLATE_CHK_SEQUENCE - || nb > ao->deflate_size || nb < DEFLATE_MIN_WORKS) { - newret = CONFNAK; - if (!dont_nak) { - p[2] = DEFLATE_MAKE_OPT(ao->deflate_size); - p[3] = DEFLATE_CHK_SEQUENCE; - /* fall through to test this #bits below */ - } else - break; - } - - /* - * Check whether we can do Deflate with the window - * size they want. If the window is too big, reduce - * it until the kernel can cope and nak with that. - * We only check this for the first option. - */ - if (p == p0) { - for (;;) { - res = ccp_test(pcb, p, CILEN_DEFLATE, 1); - if (res > 0) - break; /* it's OK now */ - if (res < 0 || nb == DEFLATE_MIN_WORKS || dont_nak) { - newret = CONFREJ; - p[2] = DEFLATE_MAKE_OPT(ho->deflate_size); - break; - } - newret = CONFNAK; - --nb; - p[2] = DEFLATE_MAKE_OPT(nb); - } - } - break; -#endif /* DEFLATE_SUPPORT */ -#if BSDCOMPRESS_SUPPORT - case CI_BSD_COMPRESS: - if (!ao->bsd_compress || clen != CILEN_BSD_COMPRESS) { - newret = CONFREJ; - break; - } - - ho->bsd_compress = 1; - ho->bsd_bits = nb = BSD_NBITS(p[2]); - if (BSD_VERSION(p[2]) != BSD_CURRENT_VERSION - || nb > ao->bsd_bits || nb < BSD_MIN_BITS) { - newret = CONFNAK; - if (!dont_nak) { - p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, ao->bsd_bits); - /* fall through to test this #bits below */ - } else - break; - } - - /* - * Check whether we can do BSD-Compress with the code - * size they want. If the code size is too big, reduce - * it until the kernel can cope and nak with that. - * We only check this for the first option. - */ - if (p == p0) { - for (;;) { - res = ccp_test(pcb, p, CILEN_BSD_COMPRESS, 1); - if (res > 0) - break; - if (res < 0 || nb == BSD_MIN_BITS || dont_nak) { - newret = CONFREJ; - p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, - ho->bsd_bits); - break; - } - newret = CONFNAK; - --nb; - p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, nb); - } - } - break; -#endif /* BSDCOMPRESS_SUPPORT */ -#if PREDICTOR_SUPPORT - case CI_PREDICTOR_1: - if (!ao->predictor_1 || clen != CILEN_PREDICTOR_1) { - newret = CONFREJ; - break; - } - - ho->predictor_1 = 1; - if (p == p0 - && ccp_test(pcb, p, CILEN_PREDICTOR_1, 1) <= 0) { - newret = CONFREJ; - } - break; - - case CI_PREDICTOR_2: - if (!ao->predictor_2 || clen != CILEN_PREDICTOR_2) { - newret = CONFREJ; - break; - } - - ho->predictor_2 = 1; - if (p == p0 - && ccp_test(pcb, p, CILEN_PREDICTOR_2, 1) <= 0) { - newret = CONFREJ; - } - break; -#endif /* PREDICTOR_SUPPORT */ - - default: - newret = CONFREJ; - } - } - - if (newret == CONFNAK && dont_nak) - newret = CONFREJ; - if (!(newret == CONFACK || (newret == CONFNAK && ret == CONFREJ))) { - /* we're returning this option */ - if (newret == CONFREJ && ret == CONFNAK) - retp = p0; - ret = newret; - if (p != retp) - MEMCPY(retp, p, clen); - retp += clen; - } - - p += clen; - len -= clen; - } - - if (ret != CONFACK) { - if (ret == CONFREJ && *lenp == retp - p0) - pcb->ccp_all_rejected = 1; - else - *lenp = retp - p0; - } -#if MPPE_SUPPORT - if (ret == CONFREJ && ao->mppe && rej_for_ci_mppe) { - ppp_error("MPPE required but peer negotiation failed"); - lcp_close(pcb, "MPPE required but peer negotiation failed"); - } -#endif /* MPPE_SUPPORT */ - return ret; -} - -/* - * Make a string name for a compression method (or 2). - */ -static const char *method_name(ccp_options *opt, ccp_options *opt2) { - static char result[64]; -#if !DEFLATE_SUPPORT && !BSDCOMPRESS_SUPPORT - LWIP_UNUSED_ARG(opt2); -#endif /* !DEFLATE_SUPPORT && !BSDCOMPRESS_SUPPORT */ - - if (!ccp_anycompress(opt)) - return "(none)"; - switch (opt->method) { -#if MPPE_SUPPORT - case CI_MPPE: - { - char *p = result; - char *q = result + sizeof(result); /* 1 past result */ - - ppp_slprintf(p, q - p, "MPPE "); - p += 5; - if (opt->mppe & MPPE_OPT_128) { - ppp_slprintf(p, q - p, "128-bit "); - p += 8; - } - if (opt->mppe & MPPE_OPT_40) { - ppp_slprintf(p, q - p, "40-bit "); - p += 7; - } - if (opt->mppe & MPPE_OPT_STATEFUL) - ppp_slprintf(p, q - p, "stateful"); - else - ppp_slprintf(p, q - p, "stateless"); - - break; - } -#endif /* MPPE_SUPPORT */ -#if DEFLATE_SUPPORT - case CI_DEFLATE: - case CI_DEFLATE_DRAFT: - if (opt2 != NULL && opt2->deflate_size != opt->deflate_size) - ppp_slprintf(result, sizeof(result), "Deflate%s (%d/%d)", - (opt->method == CI_DEFLATE_DRAFT? "(old#)": ""), - opt->deflate_size, opt2->deflate_size); - else - ppp_slprintf(result, sizeof(result), "Deflate%s (%d)", - (opt->method == CI_DEFLATE_DRAFT? "(old#)": ""), - opt->deflate_size); - break; -#endif /* DEFLATE_SUPPORT */ -#if BSDCOMPRESS_SUPPORT - case CI_BSD_COMPRESS: - if (opt2 != NULL && opt2->bsd_bits != opt->bsd_bits) - ppp_slprintf(result, sizeof(result), "BSD-Compress (%d/%d)", - opt->bsd_bits, opt2->bsd_bits); - else - ppp_slprintf(result, sizeof(result), "BSD-Compress (%d)", - opt->bsd_bits); - break; -#endif /* BSDCOMPRESS_SUPPORT */ -#if PREDICTOR_SUPPORT - case CI_PREDICTOR_1: - return "Predictor 1"; - case CI_PREDICTOR_2: - return "Predictor 2"; -#endif /* PREDICTOR_SUPPORT */ - default: - ppp_slprintf(result, sizeof(result), "Method %d", opt->method); - } - return result; -} - -/* - * CCP has come up - inform the kernel driver and log a message. - */ -static void ccp_up(fsm *f) { - ppp_pcb *pcb = f->pcb; - ccp_options *go = &pcb->ccp_gotoptions; - ccp_options *ho = &pcb->ccp_hisoptions; - char method1[64]; - - ccp_set(pcb, 1, 1, go->method, ho->method); - if (ccp_anycompress(go)) { - if (ccp_anycompress(ho)) { - if (go->method == ho->method) { - ppp_notice("%s compression enabled", method_name(go, ho)); - } else { - ppp_strlcpy(method1, method_name(go, NULL), sizeof(method1)); - ppp_notice("%s / %s compression enabled", - method1, method_name(ho, NULL)); - } - } else - ppp_notice("%s receive compression enabled", method_name(go, NULL)); - } else if (ccp_anycompress(ho)) - ppp_notice("%s transmit compression enabled", method_name(ho, NULL)); -#if MPPE_SUPPORT - if (go->mppe) { - continue_networks(pcb); /* Bring up IP et al */ - } -#endif /* MPPE_SUPPORT */ -} - -/* - * CCP has gone down - inform the kernel driver. - */ -static void ccp_down(fsm *f) { - ppp_pcb *pcb = f->pcb; -#if MPPE_SUPPORT - ccp_options *go = &pcb->ccp_gotoptions; -#endif /* MPPE_SUPPORT */ - - if (pcb->ccp_localstate & RACK_PENDING) - UNTIMEOUT(ccp_rack_timeout, f); - pcb->ccp_localstate = 0; - ccp_set(pcb, 1, 0, 0, 0); -#if MPPE_SUPPORT - if (go->mppe) { - go->mppe = 0; - if (pcb->lcp_fsm.state == PPP_FSM_OPENED) { - /* If LCP is not already going down, make sure it does. */ - ppp_error("MPPE disabled"); - lcp_close(pcb, "MPPE disabled"); - } - } -#endif /* MPPE_SUPPORT */ -} - -#if PRINTPKT_SUPPORT -/* - * Print the contents of a CCP packet. - */ -static const char* const ccp_codenames[] = { - "ConfReq", "ConfAck", "ConfNak", "ConfRej", - "TermReq", "TermAck", "CodeRej", - NULL, NULL, NULL, NULL, NULL, NULL, - "ResetReq", "ResetAck", -}; - -static int ccp_printpkt(const u_char *p, int plen, void (*printer) (void *, const char *, ...), void *arg) { - const u_char *p0, *optend; - int code, id, len; - int optlen; - - p0 = p; - if (plen < HEADERLEN) - return 0; - code = p[0]; - id = p[1]; - len = (p[2] << 8) + p[3]; - if (len < HEADERLEN || len > plen) - return 0; - - if (code >= 1 && code <= (int)LWIP_ARRAYSIZE(ccp_codenames) && ccp_codenames[code-1] != NULL) - printer(arg, " %s", ccp_codenames[code-1]); - else - printer(arg, " code=0x%x", code); - printer(arg, " id=0x%x", id); - len -= HEADERLEN; - p += HEADERLEN; - - switch (code) { - case CONFREQ: - case CONFACK: - case CONFNAK: - case CONFREJ: - /* print list of possible compression methods */ - while (len >= 2) { - code = p[0]; - optlen = p[1]; - if (optlen < 2 || optlen > len) - break; - printer(arg, " <"); - len -= optlen; - optend = p + optlen; - switch (code) { -#if MPPE_SUPPORT - case CI_MPPE: - if (optlen >= CILEN_MPPE) { - u_char mppe_opts; - - MPPE_CI_TO_OPTS(&p[2], mppe_opts); - printer(arg, "mppe %s %s %s %s %s %s%s", - (p[2] & MPPE_H_BIT)? "+H": "-H", - (p[5] & MPPE_M_BIT)? "+M": "-M", - (p[5] & MPPE_S_BIT)? "+S": "-S", - (p[5] & MPPE_L_BIT)? "+L": "-L", - (p[5] & MPPE_D_BIT)? "+D": "-D", - (p[5] & MPPE_C_BIT)? "+C": "-C", - (mppe_opts & MPPE_OPT_UNKNOWN)? " +U": ""); - if (mppe_opts & MPPE_OPT_UNKNOWN) - printer(arg, " (%.2x %.2x %.2x %.2x)", - p[2], p[3], p[4], p[5]); - p += CILEN_MPPE; - } - break; -#endif /* MPPE_SUPPORT */ -#if DEFLATE_SUPPORT - case CI_DEFLATE: - case CI_DEFLATE_DRAFT: - if (optlen >= CILEN_DEFLATE) { - printer(arg, "deflate%s %d", - (code == CI_DEFLATE_DRAFT? "(old#)": ""), - DEFLATE_SIZE(p[2])); - if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL) - printer(arg, " method %d", DEFLATE_METHOD(p[2])); - if (p[3] != DEFLATE_CHK_SEQUENCE) - printer(arg, " check %d", p[3]); - p += CILEN_DEFLATE; - } - break; -#endif /* DEFLATE_SUPPORT */ -#if BSDCOMPRESS_SUPPORT - case CI_BSD_COMPRESS: - if (optlen >= CILEN_BSD_COMPRESS) { - printer(arg, "bsd v%d %d", BSD_VERSION(p[2]), - BSD_NBITS(p[2])); - p += CILEN_BSD_COMPRESS; - } - break; -#endif /* BSDCOMPRESS_SUPPORT */ -#if PREDICTOR_SUPPORT - case CI_PREDICTOR_1: - if (optlen >= CILEN_PREDICTOR_1) { - printer(arg, "predictor 1"); - p += CILEN_PREDICTOR_1; - } - break; - case CI_PREDICTOR_2: - if (optlen >= CILEN_PREDICTOR_2) { - printer(arg, "predictor 2"); - p += CILEN_PREDICTOR_2; - } - break; -#endif /* PREDICTOR_SUPPORT */ - default: - break; - } - while (p < optend) - printer(arg, " %.2x", *p++); - printer(arg, ">"); - } - break; - - case TERMACK: - case TERMREQ: - if (len > 0 && *p >= ' ' && *p < 0x7f) { - ppp_print_string(p, len, printer, arg); - p += len; - len = 0; - } - break; - default: - break; - } - - /* dump out the rest of the packet in hex */ - while (--len >= 0) - printer(arg, " %.2x", *p++); - - return p - p0; -} -#endif /* PRINTPKT_SUPPORT */ - -#if PPP_DATAINPUT -/* - * We have received a packet that the decompressor failed to - * decompress. Here we would expect to issue a reset-request, but - * Motorola has a patent on resetting the compressor as a result of - * detecting an error in the decompressed data after decompression. - * (See US patent 5,130,993; international patent publication number - * WO 91/10289; Australian patent 73296/91.) - * - * So we ask the kernel whether the error was detected after - * decompression; if it was, we take CCP down, thus disabling - * compression :-(, otherwise we issue the reset-request. - */ -static void ccp_datainput(ppp_pcb *pcb, u_char *pkt, int len) { - fsm *f; -#if MPPE_SUPPORT - ccp_options *go = &pcb->ccp_gotoptions; -#endif /* MPPE_SUPPORT */ - LWIP_UNUSED_ARG(pkt); - LWIP_UNUSED_ARG(len); - - f = &pcb->ccp_fsm; - if (f->state == PPP_FSM_OPENED) { - if (ccp_fatal_error(pcb)) { - /* - * Disable compression by taking CCP down. - */ - ppp_error("Lost compression sync: disabling compression"); - ccp_close(pcb, "Lost compression sync"); -#if MPPE_SUPPORT - /* - * If we were doing MPPE, we must also take the link down. - */ - if (go->mppe) { - ppp_error("Too many MPPE errors, closing LCP"); - lcp_close(pcb, "Too many MPPE errors"); - } -#endif /* MPPE_SUPPORT */ - } else { - /* - * Send a reset-request to reset the peer's compressor. - * We don't do that if we are still waiting for an - * acknowledgement to a previous reset-request. - */ - if (!(pcb->ccp_localstate & RACK_PENDING)) { - fsm_sdata(f, CCP_RESETREQ, f->reqid = ++f->id, NULL, 0); - TIMEOUT(ccp_rack_timeout, f, RACKTIMEOUT); - pcb->ccp_localstate |= RACK_PENDING; - } else - pcb->ccp_localstate |= RREQ_REPEAT; - } - } -} -#endif /* PPP_DATAINPUT */ - -/* - * We have received a packet that the decompressor failed to - * decompress. Issue a reset-request. - */ -void ccp_resetrequest(ppp_pcb *pcb) { - fsm *f = &pcb->ccp_fsm; - - if (f->state != PPP_FSM_OPENED) - return; - - /* - * Send a reset-request to reset the peer's compressor. - * We don't do that if we are still waiting for an - * acknowledgement to a previous reset-request. - */ - if (!(pcb->ccp_localstate & RACK_PENDING)) { - fsm_sdata(f, CCP_RESETREQ, f->reqid = ++f->id, NULL, 0); - TIMEOUT(ccp_rack_timeout, f, RACKTIMEOUT); - pcb->ccp_localstate |= RACK_PENDING; - } else - pcb->ccp_localstate |= RREQ_REPEAT; -} - -/* - * Timeout waiting for reset-ack. - */ -static void ccp_rack_timeout(void *arg) { - fsm *f = (fsm*)arg; - ppp_pcb *pcb = f->pcb; - - if (f->state == PPP_FSM_OPENED && (pcb->ccp_localstate & RREQ_REPEAT)) { - fsm_sdata(f, CCP_RESETREQ, f->reqid, NULL, 0); - TIMEOUT(ccp_rack_timeout, f, RACKTIMEOUT); - pcb->ccp_localstate &= ~RREQ_REPEAT; - } else - pcb->ccp_localstate &= ~RACK_PENDING; -} - -#endif /* PPP_SUPPORT && CCP_SUPPORT */ diff --git a/third-party/lwip-2.1.2/netif/ppp/chap-md5.c b/third-party/lwip-2.1.2/netif/ppp/chap-md5.c deleted file mode 100644 index 88f069f0..00000000 --- a/third-party/lwip-2.1.2/netif/ppp/chap-md5.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * chap-md5.c - New CHAP/MD5 implementation. - * - * Copyright (c) 2003 Paul Mackerras. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 3. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && CHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#if 0 /* UNUSED */ -#include -#include -#endif /* UNUSED */ - -#include "netif/ppp/ppp_impl.h" - -#include "netif/ppp/chap-new.h" -#include "netif/ppp/chap-md5.h" -#include "netif/ppp/magic.h" -#include "netif/ppp/pppcrypt.h" - -#define MD5_HASH_SIZE 16 -#define MD5_MIN_CHALLENGE 17 -#define MD5_MAX_CHALLENGE 24 -#define MD5_MIN_MAX_POWER_OF_TWO_CHALLENGE 3 /* 2^3-1 = 7, 17+7 = 24 */ - -#if PPP_SERVER -static void chap_md5_generate_challenge(ppp_pcb *pcb, unsigned char *cp) { - int clen; - LWIP_UNUSED_ARG(pcb); - - clen = MD5_MIN_CHALLENGE + magic_pow(MD5_MIN_MAX_POWER_OF_TWO_CHALLENGE); - *cp++ = clen; - magic_random_bytes(cp, clen); -} - -static int chap_md5_verify_response(ppp_pcb *pcb, int id, const char *name, - const unsigned char *secret, int secret_len, - const unsigned char *challenge, const unsigned char *response, - char *message, int message_space) { - lwip_md5_context ctx; - unsigned char idbyte = id; - unsigned char hash[MD5_HASH_SIZE]; - int challenge_len, response_len; - LWIP_UNUSED_ARG(name); - LWIP_UNUSED_ARG(pcb); - - challenge_len = *challenge++; - response_len = *response++; - if (response_len == MD5_HASH_SIZE) { - /* Generate hash of ID, secret, challenge */ - lwip_md5_init(&ctx); - lwip_md5_starts(&ctx); - lwip_md5_update(&ctx, &idbyte, 1); - lwip_md5_update(&ctx, secret, secret_len); - lwip_md5_update(&ctx, challenge, challenge_len); - lwip_md5_finish(&ctx, hash); - lwip_md5_free(&ctx); - - /* Test if our hash matches the peer's response */ - if (memcmp(hash, response, MD5_HASH_SIZE) == 0) { - ppp_slprintf(message, message_space, "Access granted"); - return 1; - } - } - ppp_slprintf(message, message_space, "Access denied"); - return 0; -} -#endif /* PPP_SERVER */ - -static void chap_md5_make_response(ppp_pcb *pcb, unsigned char *response, int id, const char *our_name, - const unsigned char *challenge, const char *secret, int secret_len, - unsigned char *private_) { - lwip_md5_context ctx; - unsigned char idbyte = id; - int challenge_len = *challenge++; - LWIP_UNUSED_ARG(our_name); - LWIP_UNUSED_ARG(private_); - LWIP_UNUSED_ARG(pcb); - - lwip_md5_init(&ctx); - lwip_md5_starts(&ctx); - lwip_md5_update(&ctx, &idbyte, 1); - lwip_md5_update(&ctx, (const u_char *)secret, secret_len); - lwip_md5_update(&ctx, challenge, challenge_len); - lwip_md5_finish(&ctx, &response[1]); - lwip_md5_free(&ctx); - response[0] = MD5_HASH_SIZE; -} - -const struct chap_digest_type md5_digest = { - CHAP_MD5, /* code */ -#if PPP_SERVER - chap_md5_generate_challenge, - chap_md5_verify_response, -#endif /* PPP_SERVER */ - chap_md5_make_response, - NULL, /* check_success */ - NULL, /* handle_failure */ -}; - -#endif /* PPP_SUPPORT && CHAP_SUPPORT */ diff --git a/third-party/lwip-2.1.2/netif/ppp/chap-new.c b/third-party/lwip-2.1.2/netif/ppp/chap-new.c deleted file mode 100644 index 485122d2..00000000 --- a/third-party/lwip-2.1.2/netif/ppp/chap-new.c +++ /dev/null @@ -1,677 +0,0 @@ -/* - * chap-new.c - New CHAP implementation. - * - * Copyright (c) 2003 Paul Mackerras. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 3. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && CHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#if 0 /* UNUSED */ -#include -#include -#endif /* UNUSED */ - -#include "netif/ppp/ppp_impl.h" - -#if 0 /* UNUSED */ -#include "session.h" -#endif /* UNUSED */ - -#include "netif/ppp/chap-new.h" -#include "netif/ppp/chap-md5.h" -#if MSCHAP_SUPPORT -#include "netif/ppp/chap_ms.h" -#endif -#include "netif/ppp/magic.h" - -#if 0 /* UNUSED */ -/* Hook for a plugin to validate CHAP challenge */ -int (*chap_verify_hook)(const char *name, const char *ourname, int id, - const struct chap_digest_type *digest, - const unsigned char *challenge, const unsigned char *response, - char *message, int message_space) = NULL; -#endif /* UNUSED */ - -#if PPP_OPTIONS -/* - * Command-line options. - */ -static option_t chap_option_list[] = { - { "chap-restart", o_int, &chap_timeout_time, - "Set timeout for CHAP", OPT_PRIO }, - { "chap-max-challenge", o_int, &pcb->settings.chap_max_transmits, - "Set max #xmits for challenge", OPT_PRIO }, - { "chap-interval", o_int, &pcb->settings.chap_rechallenge_time, - "Set interval for rechallenge", OPT_PRIO }, - { NULL } -}; -#endif /* PPP_OPTIONS */ - - -/* Values for flags in chap_client_state and chap_server_state */ -#define LOWERUP 1 -#define AUTH_STARTED 2 -#define AUTH_DONE 4 -#define AUTH_FAILED 8 -#define TIMEOUT_PENDING 0x10 -#define CHALLENGE_VALID 0x20 - -/* - * Prototypes. - */ -static void chap_init(ppp_pcb *pcb); -static void chap_lowerup(ppp_pcb *pcb); -static void chap_lowerdown(ppp_pcb *pcb); -#if PPP_SERVER -static void chap_timeout(void *arg); -static void chap_generate_challenge(ppp_pcb *pcb); -static void chap_handle_response(ppp_pcb *pcb, int code, - unsigned char *pkt, int len); -static int chap_verify_response(ppp_pcb *pcb, const char *name, const char *ourname, int id, - const struct chap_digest_type *digest, - const unsigned char *challenge, const unsigned char *response, - char *message, int message_space); -#endif /* PPP_SERVER */ -static void chap_respond(ppp_pcb *pcb, int id, - unsigned char *pkt, int len); -static void chap_handle_status(ppp_pcb *pcb, int code, int id, - unsigned char *pkt, int len); -static void chap_protrej(ppp_pcb *pcb); -static void chap_input(ppp_pcb *pcb, unsigned char *pkt, int pktlen); -#if PRINTPKT_SUPPORT -static int chap_print_pkt(const unsigned char *p, int plen, - void (*printer) (void *, const char *, ...), void *arg); -#endif /* PRINTPKT_SUPPORT */ - -/* List of digest types that we know about */ -static const struct chap_digest_type* const chap_digests[] = { - &md5_digest, -#if MSCHAP_SUPPORT - &chapms_digest, - &chapms2_digest, -#endif /* MSCHAP_SUPPORT */ - NULL -}; - -/* - * chap_init - reset to initial state. - */ -static void chap_init(ppp_pcb *pcb) { - LWIP_UNUSED_ARG(pcb); - -#if 0 /* Not necessary, everything is cleared in ppp_new() */ - memset(&pcb->chap_client, 0, sizeof(chap_client_state)); -#if PPP_SERVER - memset(&pcb->chap_server, 0, sizeof(chap_server_state)); -#endif /* PPP_SERVER */ -#endif /* 0 */ -} - -/* - * chap_lowerup - we can start doing stuff now. - */ -static void chap_lowerup(ppp_pcb *pcb) { - - pcb->chap_client.flags |= LOWERUP; -#if PPP_SERVER - pcb->chap_server.flags |= LOWERUP; - if (pcb->chap_server.flags & AUTH_STARTED) - chap_timeout(pcb); -#endif /* PPP_SERVER */ -} - -static void chap_lowerdown(ppp_pcb *pcb) { - - pcb->chap_client.flags = 0; -#if PPP_SERVER - if (pcb->chap_server.flags & TIMEOUT_PENDING) - UNTIMEOUT(chap_timeout, pcb); - pcb->chap_server.flags = 0; -#endif /* PPP_SERVER */ -} - -#if PPP_SERVER -/* - * chap_auth_peer - Start authenticating the peer. - * If the lower layer is already up, we start sending challenges, - * otherwise we wait for the lower layer to come up. - */ -void chap_auth_peer(ppp_pcb *pcb, const char *our_name, int digest_code) { - const struct chap_digest_type *dp; - int i; - - if (pcb->chap_server.flags & AUTH_STARTED) { - ppp_error("CHAP: peer authentication already started!"); - return; - } - for (i = 0; (dp = chap_digests[i]) != NULL; ++i) - if (dp->code == digest_code) - break; - if (dp == NULL) - ppp_fatal("CHAP digest 0x%x requested but not available", - digest_code); - - pcb->chap_server.digest = dp; - pcb->chap_server.name = our_name; - /* Start with a random ID value */ - pcb->chap_server.id = magic(); - pcb->chap_server.flags |= AUTH_STARTED; - if (pcb->chap_server.flags & LOWERUP) - chap_timeout(pcb); -} -#endif /* PPP_SERVER */ - -/* - * chap_auth_with_peer - Prepare to authenticate ourselves to the peer. - * There isn't much to do until we receive a challenge. - */ -void chap_auth_with_peer(ppp_pcb *pcb, const char *our_name, int digest_code) { - const struct chap_digest_type *dp; - int i; - - if(NULL == our_name) - return; - - if (pcb->chap_client.flags & AUTH_STARTED) { - ppp_error("CHAP: authentication with peer already started!"); - return; - } - for (i = 0; (dp = chap_digests[i]) != NULL; ++i) - if (dp->code == digest_code) - break; - - if (dp == NULL) - ppp_fatal("CHAP digest 0x%x requested but not available", - digest_code); - - pcb->chap_client.digest = dp; - pcb->chap_client.name = our_name; - pcb->chap_client.flags |= AUTH_STARTED; -} - -#if PPP_SERVER -/* - * chap_timeout - It's time to send another challenge to the peer. - * This could be either a retransmission of a previous challenge, - * or a new challenge to start re-authentication. - */ -static void chap_timeout(void *arg) { - ppp_pcb *pcb = (ppp_pcb*)arg; - struct pbuf *p; - - pcb->chap_server.flags &= ~TIMEOUT_PENDING; - if ((pcb->chap_server.flags & CHALLENGE_VALID) == 0) { - pcb->chap_server.challenge_xmits = 0; - chap_generate_challenge(pcb); - pcb->chap_server.flags |= CHALLENGE_VALID; - } else if (pcb->chap_server.challenge_xmits >= pcb->settings.chap_max_transmits) { - pcb->chap_server.flags &= ~CHALLENGE_VALID; - pcb->chap_server.flags |= AUTH_DONE | AUTH_FAILED; - auth_peer_fail(pcb, PPP_CHAP); - return; - } - - p = pbuf_alloc(PBUF_RAW, (u16_t)(pcb->chap_server.challenge_pktlen), PPP_CTRL_PBUF_TYPE); - if(NULL == p) - return; - if(p->tot_len != p->len) { - pbuf_free(p); - return; - } - MEMCPY(p->payload, pcb->chap_server.challenge, pcb->chap_server.challenge_pktlen); - ppp_write(pcb, p); - ++pcb->chap_server.challenge_xmits; - pcb->chap_server.flags |= TIMEOUT_PENDING; - TIMEOUT(chap_timeout, arg, pcb->settings.chap_timeout_time); -} - -/* - * chap_generate_challenge - generate a challenge string and format - * the challenge packet in pcb->chap_server.challenge_pkt. - */ -static void chap_generate_challenge(ppp_pcb *pcb) { - int clen = 1, nlen, len; - unsigned char *p; - - p = pcb->chap_server.challenge; - MAKEHEADER(p, PPP_CHAP); - p += CHAP_HDRLEN; - pcb->chap_server.digest->generate_challenge(pcb, p); - clen = *p; - nlen = strlen(pcb->chap_server.name); - memcpy(p + 1 + clen, pcb->chap_server.name, nlen); - - len = CHAP_HDRLEN + 1 + clen + nlen; - pcb->chap_server.challenge_pktlen = PPP_HDRLEN + len; - - p = pcb->chap_server.challenge + PPP_HDRLEN; - p[0] = CHAP_CHALLENGE; - p[1] = ++pcb->chap_server.id; - p[2] = len >> 8; - p[3] = len; -} - -/* - * chap_handle_response - check the response to our challenge. - */ -static void chap_handle_response(ppp_pcb *pcb, int id, - unsigned char *pkt, int len) { - int response_len, ok, mlen; - const unsigned char *response; - unsigned char *outp; - struct pbuf *p; - const char *name = NULL; /* initialized to shut gcc up */ -#if 0 /* UNUSED */ - int (*verifier)(const char *, const char *, int, const struct chap_digest_type *, - const unsigned char *, const unsigned char *, char *, int); -#endif /* UNUSED */ - char rname[MAXNAMELEN+1]; - char message[256]; - - if ((pcb->chap_server.flags & LOWERUP) == 0) - return; - if (id != pcb->chap_server.challenge[PPP_HDRLEN+1] || len < 2) - return; - if (pcb->chap_server.flags & CHALLENGE_VALID) { - response = pkt; - GETCHAR(response_len, pkt); - len -= response_len + 1; /* length of name */ - name = (char *)pkt + response_len; - if (len < 0) - return; - - if (pcb->chap_server.flags & TIMEOUT_PENDING) { - pcb->chap_server.flags &= ~TIMEOUT_PENDING; - UNTIMEOUT(chap_timeout, pcb); - } -#if PPP_REMOTENAME - if (pcb->settings.explicit_remote) { - name = pcb->remote_name; - } else -#endif /* PPP_REMOTENAME */ - { - /* Null terminate and clean remote name. */ - ppp_slprintf(rname, sizeof(rname), "%.*v", len, name); - name = rname; - } - -#if 0 /* UNUSED */ - if (chap_verify_hook) - verifier = chap_verify_hook; - else - verifier = chap_verify_response; - ok = (*verifier)(name, pcb->chap_server.name, id, pcb->chap_server.digest, - pcb->chap_server.challenge + PPP_HDRLEN + CHAP_HDRLEN, - response, pcb->chap_server.message, sizeof(pcb->chap_server.message)); -#endif /* UNUSED */ - ok = chap_verify_response(pcb, name, pcb->chap_server.name, id, pcb->chap_server.digest, - pcb->chap_server.challenge + PPP_HDRLEN + CHAP_HDRLEN, - response, message, sizeof(message)); -#if 0 /* UNUSED */ - if (!ok || !auth_number()) { -#endif /* UNUSED */ - if (!ok) { - pcb->chap_server.flags |= AUTH_FAILED; - ppp_warn("Peer %q failed CHAP authentication", name); - } - } else if ((pcb->chap_server.flags & AUTH_DONE) == 0) - return; - - /* send the response */ - mlen = strlen(message); - len = CHAP_HDRLEN + mlen; - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN +len), PPP_CTRL_PBUF_TYPE); - if(NULL == p) - return; - if(p->tot_len != p->len) { - pbuf_free(p); - return; - } - - outp = (unsigned char *)p->payload; - MAKEHEADER(outp, PPP_CHAP); - - outp[0] = (pcb->chap_server.flags & AUTH_FAILED)? CHAP_FAILURE: CHAP_SUCCESS; - outp[1] = id; - outp[2] = len >> 8; - outp[3] = len; - if (mlen > 0) - memcpy(outp + CHAP_HDRLEN, message, mlen); - ppp_write(pcb, p); - - if (pcb->chap_server.flags & CHALLENGE_VALID) { - pcb->chap_server.flags &= ~CHALLENGE_VALID; - if (!(pcb->chap_server.flags & AUTH_DONE) && !(pcb->chap_server.flags & AUTH_FAILED)) { - -#if 0 /* UNUSED */ - /* - * Auth is OK, so now we need to check session restrictions - * to ensure everything is OK, but only if we used a - * plugin, and only if we're configured to check. This - * allows us to do PAM checks on PPP servers that - * authenticate against ActiveDirectory, and use AD for - * account info (like when using Winbind integrated with - * PAM). - */ - if (session_mgmt && - session_check(name, NULL, devnam, NULL) == 0) { - pcb->chap_server.flags |= AUTH_FAILED; - ppp_warn("Peer %q failed CHAP Session verification", name); - } -#endif /* UNUSED */ - - } - if (pcb->chap_server.flags & AUTH_FAILED) { - auth_peer_fail(pcb, PPP_CHAP); - } else { - if ((pcb->chap_server.flags & AUTH_DONE) == 0) - auth_peer_success(pcb, PPP_CHAP, - pcb->chap_server.digest->code, - name, strlen(name)); - if (pcb->settings.chap_rechallenge_time) { - pcb->chap_server.flags |= TIMEOUT_PENDING; - TIMEOUT(chap_timeout, pcb, - pcb->settings.chap_rechallenge_time); - } - } - pcb->chap_server.flags |= AUTH_DONE; - } -} - -/* - * chap_verify_response - check whether the peer's response matches - * what we think it should be. Returns 1 if it does (authentication - * succeeded), or 0 if it doesn't. - */ -static int chap_verify_response(ppp_pcb *pcb, const char *name, const char *ourname, int id, - const struct chap_digest_type *digest, - const unsigned char *challenge, const unsigned char *response, - char *message, int message_space) { - int ok; - unsigned char secret[MAXSECRETLEN]; - int secret_len; - - /* Get the secret that the peer is supposed to know */ - if (!get_secret(pcb, name, ourname, (char *)secret, &secret_len, 1)) { - ppp_error("No CHAP secret found for authenticating %q", name); - return 0; - } - ok = digest->verify_response(pcb, id, name, secret, secret_len, challenge, - response, message, message_space); - memset(secret, 0, sizeof(secret)); - - return ok; -} -#endif /* PPP_SERVER */ - -/* - * chap_respond - Generate and send a response to a challenge. - */ -static void chap_respond(ppp_pcb *pcb, int id, - unsigned char *pkt, int len) { - int clen, nlen; - int secret_len; - struct pbuf *p; - u_char *outp; - char rname[MAXNAMELEN+1]; - char secret[MAXSECRETLEN+1]; - - p = pbuf_alloc(PBUF_RAW, (u16_t)(RESP_MAX_PKTLEN), PPP_CTRL_PBUF_TYPE); - if(NULL == p) - return; - if(p->tot_len != p->len) { - pbuf_free(p); - return; - } - - if ((pcb->chap_client.flags & (LOWERUP | AUTH_STARTED)) != (LOWERUP | AUTH_STARTED)) - return; /* not ready */ - if (len < 2 || len < pkt[0] + 1) - return; /* too short */ - clen = pkt[0]; - nlen = len - (clen + 1); - - /* Null terminate and clean remote name. */ - ppp_slprintf(rname, sizeof(rname), "%.*v", nlen, pkt + clen + 1); - -#if PPP_REMOTENAME - /* Microsoft doesn't send their name back in the PPP packet */ - if (pcb->settings.explicit_remote || (pcb->settings.remote_name[0] != 0 && rname[0] == 0)) - strlcpy(rname, pcb->settings.remote_name, sizeof(rname)); -#endif /* PPP_REMOTENAME */ - - /* get secret for authenticating ourselves with the specified host */ - if (!get_secret(pcb, pcb->chap_client.name, rname, secret, &secret_len, 0)) { - secret_len = 0; /* assume null secret if can't find one */ - ppp_warn("No CHAP secret found for authenticating us to %q", rname); - } - - outp = (u_char*)p->payload; - MAKEHEADER(outp, PPP_CHAP); - outp += CHAP_HDRLEN; - - pcb->chap_client.digest->make_response(pcb, outp, id, pcb->chap_client.name, pkt, - secret, secret_len, pcb->chap_client.priv); - memset(secret, 0, secret_len); - - clen = *outp; - nlen = strlen(pcb->chap_client.name); - memcpy(outp + clen + 1, pcb->chap_client.name, nlen); - - outp = (u_char*)p->payload + PPP_HDRLEN; - len = CHAP_HDRLEN + clen + 1 + nlen; - outp[0] = CHAP_RESPONSE; - outp[1] = id; - outp[2] = len >> 8; - outp[3] = len; - - pbuf_realloc(p, PPP_HDRLEN + len); - ppp_write(pcb, p); -} - -static void chap_handle_status(ppp_pcb *pcb, int code, int id, - unsigned char *pkt, int len) { - const char *msg = NULL; - LWIP_UNUSED_ARG(id); - - if ((pcb->chap_client.flags & (AUTH_DONE|AUTH_STARTED|LOWERUP)) - != (AUTH_STARTED|LOWERUP)) - return; - pcb->chap_client.flags |= AUTH_DONE; - - if (code == CHAP_SUCCESS) { - /* used for MS-CHAP v2 mutual auth, yuck */ - if (pcb->chap_client.digest->check_success != NULL) { - if (!(*pcb->chap_client.digest->check_success)(pcb, pkt, len, pcb->chap_client.priv)) - code = CHAP_FAILURE; - } else - msg = "CHAP authentication succeeded"; - } else { - if (pcb->chap_client.digest->handle_failure != NULL) - (*pcb->chap_client.digest->handle_failure)(pcb, pkt, len); - else - msg = "CHAP authentication failed"; - } - if (msg) { - if (len > 0) - ppp_info("%s: %.*v", msg, len, pkt); - else - ppp_info("%s", msg); - } - if (code == CHAP_SUCCESS) - auth_withpeer_success(pcb, PPP_CHAP, pcb->chap_client.digest->code); - else { - pcb->chap_client.flags |= AUTH_FAILED; - ppp_error("CHAP authentication failed"); - auth_withpeer_fail(pcb, PPP_CHAP); - } -} - -static void chap_input(ppp_pcb *pcb, unsigned char *pkt, int pktlen) { - unsigned char code, id; - int len; - - if (pktlen < CHAP_HDRLEN) - return; - GETCHAR(code, pkt); - GETCHAR(id, pkt); - GETSHORT(len, pkt); - if (len < CHAP_HDRLEN || len > pktlen) - return; - len -= CHAP_HDRLEN; - - switch (code) { - case CHAP_CHALLENGE: - chap_respond(pcb, id, pkt, len); - break; -#if PPP_SERVER - case CHAP_RESPONSE: - chap_handle_response(pcb, id, pkt, len); - break; -#endif /* PPP_SERVER */ - case CHAP_FAILURE: - case CHAP_SUCCESS: - chap_handle_status(pcb, code, id, pkt, len); - break; - default: - break; - } -} - -static void chap_protrej(ppp_pcb *pcb) { - -#if PPP_SERVER - if (pcb->chap_server.flags & TIMEOUT_PENDING) { - pcb->chap_server.flags &= ~TIMEOUT_PENDING; - UNTIMEOUT(chap_timeout, pcb); - } - if (pcb->chap_server.flags & AUTH_STARTED) { - pcb->chap_server.flags = 0; - auth_peer_fail(pcb, PPP_CHAP); - } -#endif /* PPP_SERVER */ - if ((pcb->chap_client.flags & (AUTH_STARTED|AUTH_DONE)) == AUTH_STARTED) { - pcb->chap_client.flags &= ~AUTH_STARTED; - ppp_error("CHAP authentication failed due to protocol-reject"); - auth_withpeer_fail(pcb, PPP_CHAP); - } -} - -#if PRINTPKT_SUPPORT -/* - * chap_print_pkt - print the contents of a CHAP packet. - */ -static const char* const chap_code_names[] = { - "Challenge", "Response", "Success", "Failure" -}; - -static int chap_print_pkt(const unsigned char *p, int plen, - void (*printer) (void *, const char *, ...), void *arg) { - int code, id, len; - int clen, nlen; - unsigned char x; - - if (plen < CHAP_HDRLEN) - return 0; - GETCHAR(code, p); - GETCHAR(id, p); - GETSHORT(len, p); - if (len < CHAP_HDRLEN || len > plen) - return 0; - - if (code >= 1 && code <= (int)LWIP_ARRAYSIZE(chap_code_names)) - printer(arg, " %s", chap_code_names[code-1]); - else - printer(arg, " code=0x%x", code); - printer(arg, " id=0x%x", id); - len -= CHAP_HDRLEN; - switch (code) { - case CHAP_CHALLENGE: - case CHAP_RESPONSE: - if (len < 1) - break; - clen = p[0]; - if (len < clen + 1) - break; - ++p; - nlen = len - clen - 1; - printer(arg, " <"); - for (; clen > 0; --clen) { - GETCHAR(x, p); - printer(arg, "%.2x", x); - } - printer(arg, ">, name = "); - ppp_print_string(p, nlen, printer, arg); - break; - case CHAP_FAILURE: - case CHAP_SUCCESS: - printer(arg, " "); - ppp_print_string(p, len, printer, arg); - break; - default: - for (clen = len; clen > 0; --clen) { - GETCHAR(x, p); - printer(arg, " %.2x", x); - } - /* no break */ - } - - return len + CHAP_HDRLEN; -} -#endif /* PRINTPKT_SUPPORT */ - -const struct protent chap_protent = { - PPP_CHAP, - chap_init, - chap_input, - chap_protrej, - chap_lowerup, - chap_lowerdown, - NULL, /* open */ - NULL, /* close */ -#if PRINTPKT_SUPPORT - chap_print_pkt, -#endif /* PRINTPKT_SUPPORT */ -#if PPP_DATAINPUT - NULL, /* datainput */ -#endif /* PPP_DATAINPUT */ -#if PRINTPKT_SUPPORT - "CHAP", /* name */ - NULL, /* data_name */ -#endif /* PRINTPKT_SUPPORT */ -#if PPP_OPTIONS - chap_option_list, - NULL, /* check_options */ -#endif /* PPP_OPTIONS */ -#if DEMAND_SUPPORT - NULL, - NULL -#endif /* DEMAND_SUPPORT */ -}; - -#endif /* PPP_SUPPORT && CHAP_SUPPORT */ diff --git a/third-party/lwip-2.1.2/netif/ppp/chap_ms.c b/third-party/lwip-2.1.2/netif/ppp/chap_ms.c deleted file mode 100644 index 5a989c9b..00000000 --- a/third-party/lwip-2.1.2/netif/ppp/chap_ms.c +++ /dev/null @@ -1,962 +0,0 @@ -/* - * chap_ms.c - Microsoft MS-CHAP compatible implementation. - * - * Copyright (c) 1995 Eric Rosenquist. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * Modifications by Lauri Pesonen / lpesonen@clinet.fi, april 1997 - * - * Implemented LANManager type password response to MS-CHAP challenges. - * Now pppd provides both NT style and LANMan style blocks, and the - * prefered is set by option "ms-lanman". Default is to use NT. - * The hash text (StdText) was taken from Win95 RASAPI32.DLL. - * - * You should also use DOMAIN\\USERNAME as described in README.MSCHAP80 - */ - -/* - * Modifications by Frank Cusack, frank@google.com, March 2002. - * - * Implemented MS-CHAPv2 functionality, heavily based on sample - * implementation in RFC 2759. Implemented MPPE functionality, - * heavily based on sample implementation in RFC 3079. - * - * Copyright (c) 2002 Google, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && MSCHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#if 0 /* UNUSED */ -#include -#include -#include -#include -#include -#include -#include -#endif /* UNUSED */ - -#include "netif/ppp/ppp_impl.h" - -#include "netif/ppp/chap-new.h" -#include "netif/ppp/chap_ms.h" -#include "netif/ppp/pppcrypt.h" -#include "netif/ppp/magic.h" -#if MPPE_SUPPORT -#include "netif/ppp/mppe.h" /* For mppe_sha1_pad*, mppe_set_key() */ -#endif /* MPPE_SUPPORT */ - -#define SHA1_SIGNATURE_SIZE 20 -#define MD4_SIGNATURE_SIZE 16 /* 16 bytes in a MD4 message digest */ -#define MAX_NT_PASSWORD 256 /* Max (Unicode) chars in an NT pass */ - -#define MS_CHAP_RESPONSE_LEN 49 /* Response length for MS-CHAP */ -#define MS_CHAP2_RESPONSE_LEN 49 /* Response length for MS-CHAPv2 */ -#define MS_AUTH_RESPONSE_LENGTH 40 /* MS-CHAPv2 authenticator response, */ - /* as ASCII */ - -/* Error codes for MS-CHAP failure messages. */ -#define MS_CHAP_ERROR_RESTRICTED_LOGON_HOURS 646 -#define MS_CHAP_ERROR_ACCT_DISABLED 647 -#define MS_CHAP_ERROR_PASSWD_EXPIRED 648 -#define MS_CHAP_ERROR_NO_DIALIN_PERMISSION 649 -#define MS_CHAP_ERROR_AUTHENTICATION_FAILURE 691 -#define MS_CHAP_ERROR_CHANGING_PASSWORD 709 - -/* - * Offsets within the response field for MS-CHAP - */ -#define MS_CHAP_LANMANRESP 0 -#define MS_CHAP_LANMANRESP_LEN 24 -#define MS_CHAP_NTRESP 24 -#define MS_CHAP_NTRESP_LEN 24 -#define MS_CHAP_USENT 48 - -/* - * Offsets within the response field for MS-CHAP2 - */ -#define MS_CHAP2_PEER_CHALLENGE 0 -#define MS_CHAP2_PEER_CHAL_LEN 16 -#define MS_CHAP2_RESERVED_LEN 8 -#define MS_CHAP2_NTRESP 24 -#define MS_CHAP2_NTRESP_LEN 24 -#define MS_CHAP2_FLAGS 48 - -#if MPPE_SUPPORT -#if 0 /* UNUSED */ -/* These values are the RADIUS attribute values--see RFC 2548. */ -#define MPPE_ENC_POL_ENC_ALLOWED 1 -#define MPPE_ENC_POL_ENC_REQUIRED 2 -#define MPPE_ENC_TYPES_RC4_40 2 -#define MPPE_ENC_TYPES_RC4_128 4 - -/* used by plugins (using above values) */ -extern void set_mppe_enc_types(int, int); -#endif /* UNUSED */ -#endif /* MPPE_SUPPORT */ - -/* Are we the authenticator or authenticatee? For MS-CHAPv2 key derivation. */ -#define MS_CHAP2_AUTHENTICATEE 0 -#define MS_CHAP2_AUTHENTICATOR 1 - -static void ascii2unicode (const char[], int, u_char[]); -static void NTPasswordHash (u_char *, int, u_char[MD4_SIGNATURE_SIZE]); -static void ChallengeResponse (const u_char *, const u_char *, u_char[24]); -static void ChallengeHash (const u_char[16], const u_char *, const char *, u_char[8]); -static void ChapMS_NT (const u_char *, const char *, int, u_char[24]); -static void ChapMS2_NT (const u_char *, const u_char[16], const char *, const char *, int, - u_char[24]); -static void GenerateAuthenticatorResponsePlain - (const char*, int, u_char[24], const u_char[16], const u_char *, - const char *, u_char[41]); -#ifdef MSLANMAN -static void ChapMS_LANMan (u_char *, char *, int, u_char *); -#endif - -static void GenerateAuthenticatorResponse(const u_char PasswordHashHash[MD4_SIGNATURE_SIZE], - u_char NTResponse[24], const u_char PeerChallenge[16], - const u_char *rchallenge, const char *username, - u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1]); - -#if MPPE_SUPPORT -static void Set_Start_Key (ppp_pcb *pcb, const u_char *, const char *, int); -static void SetMasterKeys (ppp_pcb *pcb, const char *, int, u_char[24], int); -#endif /* MPPE_SUPPORT */ - -static void ChapMS (ppp_pcb *pcb, const u_char *, const char *, int, u_char *); -static void ChapMS2 (ppp_pcb *pcb, const u_char *, const u_char *, const char *, const char *, int, - u_char *, u_char[MS_AUTH_RESPONSE_LENGTH+1], int); - -#ifdef MSLANMAN -bool ms_lanman = 0; /* Use LanMan password instead of NT */ - /* Has meaning only with MS-CHAP challenges */ -#endif - -#if MPPE_SUPPORT -#ifdef DEBUGMPPEKEY -/* For MPPE debug */ -/* Use "[]|}{?/><,`!2&&(" (sans quotes) for RFC 3079 MS-CHAPv2 test value */ -static char *mschap_challenge = NULL; -/* Use "!@\#$%^&*()_+:3|~" (sans quotes, backslash is to escape #) for ... */ -static char *mschap2_peer_challenge = NULL; -#endif - -#include "netif/ppp/fsm.h" /* Need to poke MPPE options */ -#include "netif/ppp/ccp.h" -#endif /* MPPE_SUPPORT */ - -#if PPP_OPTIONS -/* - * Command-line options. - */ -static option_t chapms_option_list[] = { -#ifdef MSLANMAN - { "ms-lanman", o_bool, &ms_lanman, - "Use LanMan passwd when using MS-CHAP", 1 }, -#endif -#ifdef DEBUGMPPEKEY - { "mschap-challenge", o_string, &mschap_challenge, - "specify CHAP challenge" }, - { "mschap2-peer-challenge", o_string, &mschap2_peer_challenge, - "specify CHAP peer challenge" }, -#endif - { NULL } -}; -#endif /* PPP_OPTIONS */ - -#if PPP_SERVER -/* - * chapms_generate_challenge - generate a challenge for MS-CHAP. - * For MS-CHAP the challenge length is fixed at 8 bytes. - * The length goes in challenge[0] and the actual challenge starts - * at challenge[1]. - */ -static void chapms_generate_challenge(ppp_pcb *pcb, unsigned char *challenge) { - LWIP_UNUSED_ARG(pcb); - - *challenge++ = 8; -#ifdef DEBUGMPPEKEY - if (mschap_challenge && strlen(mschap_challenge) == 8) - memcpy(challenge, mschap_challenge, 8); - else -#endif - magic_random_bytes(challenge, 8); -} - -static void chapms2_generate_challenge(ppp_pcb *pcb, unsigned char *challenge) { - LWIP_UNUSED_ARG(pcb); - - *challenge++ = 16; -#ifdef DEBUGMPPEKEY - if (mschap_challenge && strlen(mschap_challenge) == 16) - memcpy(challenge, mschap_challenge, 16); - else -#endif - magic_random_bytes(challenge, 16); -} - -static int chapms_verify_response(ppp_pcb *pcb, int id, const char *name, - const unsigned char *secret, int secret_len, - const unsigned char *challenge, const unsigned char *response, - char *message, int message_space) { - unsigned char md[MS_CHAP_RESPONSE_LEN]; - int diff; - int challenge_len, response_len; - LWIP_UNUSED_ARG(id); - LWIP_UNUSED_ARG(name); - - challenge_len = *challenge++; /* skip length, is 8 */ - response_len = *response++; - if (response_len != MS_CHAP_RESPONSE_LEN) - goto bad; - -#ifndef MSLANMAN - if (!response[MS_CHAP_USENT]) { - /* Should really propagate this into the error packet. */ - ppp_notice("Peer request for LANMAN auth not supported"); - goto bad; - } -#endif - - /* Generate the expected response. */ - ChapMS(pcb, (const u_char *)challenge, (const char *)secret, secret_len, md); - -#ifdef MSLANMAN - /* Determine which part of response to verify against */ - if (!response[MS_CHAP_USENT]) - diff = memcmp(&response[MS_CHAP_LANMANRESP], - &md[MS_CHAP_LANMANRESP], MS_CHAP_LANMANRESP_LEN); - else -#endif - diff = memcmp(&response[MS_CHAP_NTRESP], &md[MS_CHAP_NTRESP], - MS_CHAP_NTRESP_LEN); - - if (diff == 0) { - ppp_slprintf(message, message_space, "Access granted"); - return 1; - } - - bad: - /* See comments below for MS-CHAP V2 */ - ppp_slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0", - challenge_len, challenge); - return 0; -} - -static int chapms2_verify_response(ppp_pcb *pcb, int id, const char *name, - const unsigned char *secret, int secret_len, - const unsigned char *challenge, const unsigned char *response, - char *message, int message_space) { - unsigned char md[MS_CHAP2_RESPONSE_LEN]; - char saresponse[MS_AUTH_RESPONSE_LENGTH+1]; - int challenge_len, response_len; - LWIP_UNUSED_ARG(id); - - challenge_len = *challenge++; /* skip length, is 16 */ - response_len = *response++; - if (response_len != MS_CHAP2_RESPONSE_LEN) - goto bad; /* not even the right length */ - - /* Generate the expected response and our mutual auth. */ - ChapMS2(pcb, (const u_char*)challenge, (const u_char*)&response[MS_CHAP2_PEER_CHALLENGE], name, - (const char *)secret, secret_len, md, - (unsigned char *)saresponse, MS_CHAP2_AUTHENTICATOR); - - /* compare MDs and send the appropriate status */ - /* - * Per RFC 2759, success message must be formatted as - * "S= M=" - * where - * is the Authenticator Response (mutual auth) - * is a text message - * - * However, some versions of Windows (win98 tested) do not know - * about the M= part (required per RFC 2759) and flag - * it as an error (reported incorrectly as an encryption error - * to the user). Since the RFC requires it, and it can be - * useful information, we supply it if the peer is a conforming - * system. Luckily (?), win98 sets the Flags field to 0x04 - * (contrary to RFC requirements) so we can use that to - * distinguish between conforming and non-conforming systems. - * - * Special thanks to Alex Swiridov for - * help debugging this. - */ - if (memcmp(&md[MS_CHAP2_NTRESP], &response[MS_CHAP2_NTRESP], - MS_CHAP2_NTRESP_LEN) == 0) { - if (response[MS_CHAP2_FLAGS]) - ppp_slprintf(message, message_space, "S=%s", saresponse); - else - ppp_slprintf(message, message_space, "S=%s M=%s", - saresponse, "Access granted"); - return 1; - } - - bad: - /* - * Failure message must be formatted as - * "E=e R=r C=c V=v M=m" - * where - * e = error code (we use 691, ERROR_AUTHENTICATION_FAILURE) - * r = retry (we use 1, ok to retry) - * c = challenge to use for next response, we reuse previous - * v = Change Password version supported, we use 0 - * m = text message - * - * The M=m part is only for MS-CHAPv2. Neither win2k nor - * win98 (others untested) display the message to the user anyway. - * They also both ignore the E=e code. - * - * Note that it's safe to reuse the same challenge as we don't - * actually accept another response based on the error message - * (and no clients try to resend a response anyway). - * - * Basically, this whole bit is useless code, even the small - * implementation here is only because of overspecification. - */ - ppp_slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0 M=%s", - challenge_len, challenge, "Access denied"); - return 0; -} -#endif /* PPP_SERVER */ - -static void chapms_make_response(ppp_pcb *pcb, unsigned char *response, int id, const char *our_name, - const unsigned char *challenge, const char *secret, int secret_len, - unsigned char *private_) { - LWIP_UNUSED_ARG(id); - LWIP_UNUSED_ARG(our_name); - LWIP_UNUSED_ARG(private_); - challenge++; /* skip length, should be 8 */ - *response++ = MS_CHAP_RESPONSE_LEN; - ChapMS(pcb, challenge, secret, secret_len, response); -} - -static void chapms2_make_response(ppp_pcb *pcb, unsigned char *response, int id, const char *our_name, - const unsigned char *challenge, const char *secret, int secret_len, - unsigned char *private_) { - LWIP_UNUSED_ARG(id); - challenge++; /* skip length, should be 16 */ - *response++ = MS_CHAP2_RESPONSE_LEN; - ChapMS2(pcb, challenge, -#ifdef DEBUGMPPEKEY - mschap2_peer_challenge, -#else - NULL, -#endif - our_name, secret, secret_len, response, private_, - MS_CHAP2_AUTHENTICATEE); -} - -static int chapms2_check_success(ppp_pcb *pcb, unsigned char *msg, int len, unsigned char *private_) { - LWIP_UNUSED_ARG(pcb); - - if ((len < MS_AUTH_RESPONSE_LENGTH + 2) || - strncmp((char *)msg, "S=", 2) != 0) { - /* Packet does not start with "S=" */ - ppp_error("MS-CHAPv2 Success packet is badly formed."); - return 0; - } - msg += 2; - len -= 2; - if (len < MS_AUTH_RESPONSE_LENGTH - || memcmp(msg, private_, MS_AUTH_RESPONSE_LENGTH)) { - /* Authenticator Response did not match expected. */ - ppp_error("MS-CHAPv2 mutual authentication failed."); - return 0; - } - /* Authenticator Response matches. */ - msg += MS_AUTH_RESPONSE_LENGTH; /* Eat it */ - len -= MS_AUTH_RESPONSE_LENGTH; - if ((len >= 3) && !strncmp((char *)msg, " M=", 3)) { - msg += 3; /* Eat the delimiter */ - } else if (len) { - /* Packet has extra text which does not begin " M=" */ - ppp_error("MS-CHAPv2 Success packet is badly formed."); - return 0; - } - return 1; -} - -static void chapms_handle_failure(ppp_pcb *pcb, unsigned char *inp, int len) { - int err; - const char *p; - char msg[64]; - LWIP_UNUSED_ARG(pcb); - - /* We want a null-terminated string for strxxx(). */ - len = LWIP_MIN(len, 63); - MEMCPY(msg, inp, len); - msg[len] = 0; - p = msg; - - /* - * Deal with MS-CHAP formatted failure messages; just print the - * M= part (if any). For MS-CHAP we're not really supposed - * to use M=, but it shouldn't hurt. See - * chapms[2]_verify_response. - */ - if (!strncmp(p, "E=", 2)) - err = strtol(p+2, NULL, 10); /* Remember the error code. */ - else - goto print_msg; /* Message is badly formatted. */ - - if (len && ((p = strstr(p, " M=")) != NULL)) { - /* M= field found. */ - p += 3; - } else { - /* No M=; use the error code. */ - switch (err) { - case MS_CHAP_ERROR_RESTRICTED_LOGON_HOURS: - p = "E=646 Restricted logon hours"; - break; - - case MS_CHAP_ERROR_ACCT_DISABLED: - p = "E=647 Account disabled"; - break; - - case MS_CHAP_ERROR_PASSWD_EXPIRED: - p = "E=648 Password expired"; - break; - - case MS_CHAP_ERROR_NO_DIALIN_PERMISSION: - p = "E=649 No dialin permission"; - break; - - case MS_CHAP_ERROR_AUTHENTICATION_FAILURE: - p = "E=691 Authentication failure"; - break; - - case MS_CHAP_ERROR_CHANGING_PASSWORD: - /* Should never see this, we don't support Change Password. */ - p = "E=709 Error changing password"; - break; - - default: - ppp_error("Unknown MS-CHAP authentication failure: %.*v", - len, inp); - return; - } - } -print_msg: - if (p != NULL) - ppp_error("MS-CHAP authentication failed: %v", p); -} - -static void ChallengeResponse(const u_char *challenge, - const u_char PasswordHash[MD4_SIGNATURE_SIZE], - u_char response[24]) { - u_char ZPasswordHash[21]; - lwip_des_context des; - u_char des_key[8]; - - BZERO(ZPasswordHash, sizeof(ZPasswordHash)); - MEMCPY(ZPasswordHash, PasswordHash, MD4_SIGNATURE_SIZE); - -#if 0 - dbglog("ChallengeResponse - ZPasswordHash %.*B", - sizeof(ZPasswordHash), ZPasswordHash); -#endif - - pppcrypt_56_to_64_bit_key(ZPasswordHash + 0, des_key); - lwip_des_init(&des); - lwip_des_setkey_enc(&des, des_key); - lwip_des_crypt_ecb(&des, challenge, response +0); - lwip_des_free(&des); - - pppcrypt_56_to_64_bit_key(ZPasswordHash + 7, des_key); - lwip_des_init(&des); - lwip_des_setkey_enc(&des, des_key); - lwip_des_crypt_ecb(&des, challenge, response +8); - lwip_des_free(&des); - - pppcrypt_56_to_64_bit_key(ZPasswordHash + 14, des_key); - lwip_des_init(&des); - lwip_des_setkey_enc(&des, des_key); - lwip_des_crypt_ecb(&des, challenge, response +16); - lwip_des_free(&des); - -#if 0 - dbglog("ChallengeResponse - response %.24B", response); -#endif -} - -static void ChallengeHash(const u_char PeerChallenge[16], const u_char *rchallenge, - const char *username, u_char Challenge[8]) { - lwip_sha1_context sha1Context; - u_char sha1Hash[SHA1_SIGNATURE_SIZE]; - const char *user; - - /* remove domain from "domain\username" */ - if ((user = strrchr(username, '\\')) != NULL) - ++user; - else - user = username; - - lwip_sha1_init(&sha1Context); - lwip_sha1_starts(&sha1Context); - lwip_sha1_update(&sha1Context, PeerChallenge, 16); - lwip_sha1_update(&sha1Context, rchallenge, 16); - lwip_sha1_update(&sha1Context, (const unsigned char*)user, strlen(user)); - lwip_sha1_finish(&sha1Context, sha1Hash); - lwip_sha1_free(&sha1Context); - - MEMCPY(Challenge, sha1Hash, 8); -} - -/* - * Convert the ASCII version of the password to Unicode. - * This implicitly supports 8-bit ISO8859/1 characters. - * This gives us the little-endian representation, which - * is assumed by all M$ CHAP RFCs. (Unicode byte ordering - * is machine-dependent.) - */ -static void ascii2unicode(const char ascii[], int ascii_len, u_char unicode[]) { - int i; - - BZERO(unicode, ascii_len * 2); - for (i = 0; i < ascii_len; i++) - unicode[i * 2] = (u_char) ascii[i]; -} - -static void NTPasswordHash(u_char *secret, int secret_len, u_char hash[MD4_SIGNATURE_SIZE]) { - lwip_md4_context md4Context; - - lwip_md4_init(&md4Context); - lwip_md4_starts(&md4Context); - lwip_md4_update(&md4Context, secret, secret_len); - lwip_md4_finish(&md4Context, hash); - lwip_md4_free(&md4Context); -} - -static void ChapMS_NT(const u_char *rchallenge, const char *secret, int secret_len, - u_char NTResponse[24]) { - u_char unicodePassword[MAX_NT_PASSWORD * 2]; - u_char PasswordHash[MD4_SIGNATURE_SIZE]; - - /* Hash the Unicode version of the secret (== password). */ - ascii2unicode(secret, secret_len, unicodePassword); - NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); - - ChallengeResponse(rchallenge, PasswordHash, NTResponse); -} - -static void ChapMS2_NT(const u_char *rchallenge, const u_char PeerChallenge[16], const char *username, - const char *secret, int secret_len, u_char NTResponse[24]) { - u_char unicodePassword[MAX_NT_PASSWORD * 2]; - u_char PasswordHash[MD4_SIGNATURE_SIZE]; - u_char Challenge[8]; - - ChallengeHash(PeerChallenge, rchallenge, username, Challenge); - - /* Hash the Unicode version of the secret (== password). */ - ascii2unicode(secret, secret_len, unicodePassword); - NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); - - ChallengeResponse(Challenge, PasswordHash, NTResponse); -} - -#ifdef MSLANMAN -static u_char *StdText = (u_char *)"KGS!@#$%"; /* key from rasapi32.dll */ - -static void ChapMS_LANMan(u_char *rchallenge, char *secret, int secret_len, - unsigned char *response) { - int i; - u_char UcasePassword[MAX_NT_PASSWORD]; /* max is actually 14 */ - u_char PasswordHash[MD4_SIGNATURE_SIZE]; - lwip_des_context des; - u_char des_key[8]; - - /* LANMan password is case insensitive */ - BZERO(UcasePassword, sizeof(UcasePassword)); - for (i = 0; i < secret_len; i++) - UcasePassword[i] = (u_char)toupper(secret[i]); - - pppcrypt_56_to_64_bit_key(UcasePassword +0, des_key); - lwip_des_init(&des); - lwip_des_setkey_enc(&des, des_key); - lwip_des_crypt_ecb(&des, StdText, PasswordHash +0); - lwip_des_free(&des); - - pppcrypt_56_to_64_bit_key(UcasePassword +7, des_key); - lwip_des_init(&des); - lwip_des_setkey_enc(&des, des_key); - lwip_des_crypt_ecb(&des, StdText, PasswordHash +8); - lwip_des_free(&des); - - ChallengeResponse(rchallenge, PasswordHash, &response[MS_CHAP_LANMANRESP]); -} -#endif - - -static void GenerateAuthenticatorResponse(const u_char PasswordHashHash[MD4_SIGNATURE_SIZE], - u_char NTResponse[24], const u_char PeerChallenge[16], - const u_char *rchallenge, const char *username, - u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1]) { - /* - * "Magic" constants used in response generation, from RFC 2759. - */ - static const u_char Magic1[39] = /* "Magic server to client signing constant" */ - { 0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65, - 0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67, - 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74 }; - static const u_char Magic2[41] = /* "Pad to make it do more than one iteration" */ - { 0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B, - 0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F, - 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E, - 0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F, - 0x6E }; - - int i; - lwip_sha1_context sha1Context; - u_char Digest[SHA1_SIGNATURE_SIZE]; - u_char Challenge[8]; - - lwip_sha1_init(&sha1Context); - lwip_sha1_starts(&sha1Context); - lwip_sha1_update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); - lwip_sha1_update(&sha1Context, NTResponse, 24); - lwip_sha1_update(&sha1Context, Magic1, sizeof(Magic1)); - lwip_sha1_finish(&sha1Context, Digest); - lwip_sha1_free(&sha1Context); - - ChallengeHash(PeerChallenge, rchallenge, username, Challenge); - - lwip_sha1_init(&sha1Context); - lwip_sha1_starts(&sha1Context); - lwip_sha1_update(&sha1Context, Digest, sizeof(Digest)); - lwip_sha1_update(&sha1Context, Challenge, sizeof(Challenge)); - lwip_sha1_update(&sha1Context, Magic2, sizeof(Magic2)); - lwip_sha1_finish(&sha1Context, Digest); - lwip_sha1_free(&sha1Context); - - /* Convert to ASCII hex string. */ - for (i = 0; i < LWIP_MAX((MS_AUTH_RESPONSE_LENGTH / 2), (int)sizeof(Digest)); i++) - sprintf((char *)&authResponse[i * 2], "%02X", Digest[i]); -} - - -static void GenerateAuthenticatorResponsePlain( - const char *secret, int secret_len, - u_char NTResponse[24], const u_char PeerChallenge[16], - const u_char *rchallenge, const char *username, - u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1]) { - u_char unicodePassword[MAX_NT_PASSWORD * 2]; - u_char PasswordHash[MD4_SIGNATURE_SIZE]; - u_char PasswordHashHash[MD4_SIGNATURE_SIZE]; - - /* Hash (x2) the Unicode version of the secret (== password). */ - ascii2unicode(secret, secret_len, unicodePassword); - NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); - NTPasswordHash(PasswordHash, sizeof(PasswordHash), - PasswordHashHash); - - GenerateAuthenticatorResponse(PasswordHashHash, NTResponse, PeerChallenge, - rchallenge, username, authResponse); -} - - -#if MPPE_SUPPORT -/* - * Set mppe_xxxx_key from MS-CHAP credentials. (see RFC 3079) - */ -static void Set_Start_Key(ppp_pcb *pcb, const u_char *rchallenge, const char *secret, int secret_len) { - u_char unicodePassword[MAX_NT_PASSWORD * 2]; - u_char PasswordHash[MD4_SIGNATURE_SIZE]; - u_char PasswordHashHash[MD4_SIGNATURE_SIZE]; - lwip_sha1_context sha1Context; - u_char Digest[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */ - - /* Hash (x2) the Unicode version of the secret (== password). */ - ascii2unicode(secret, secret_len, unicodePassword); - NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); - NTPasswordHash(PasswordHash, sizeof(PasswordHash), PasswordHashHash); - - lwip_sha1_init(&sha1Context); - lwip_sha1_starts(&sha1Context); - lwip_sha1_update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); - lwip_sha1_update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); - lwip_sha1_update(&sha1Context, rchallenge, 8); - lwip_sha1_finish(&sha1Context, Digest); - lwip_sha1_free(&sha1Context); - - /* Same key in both directions. */ - mppe_set_key(pcb, &pcb->mppe_comp, Digest); - mppe_set_key(pcb, &pcb->mppe_decomp, Digest); - - pcb->mppe_keys_set = 1; -} - -/* - * Set mppe_xxxx_key from MS-CHAPv2 credentials. (see RFC 3079) - */ -static void SetMasterKeys(ppp_pcb *pcb, const char *secret, int secret_len, u_char NTResponse[24], int IsServer) { - u_char unicodePassword[MAX_NT_PASSWORD * 2]; - u_char PasswordHash[MD4_SIGNATURE_SIZE]; - u_char PasswordHashHash[MD4_SIGNATURE_SIZE]; - lwip_sha1_context sha1Context; - u_char MasterKey[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */ - u_char Digest[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */ - const u_char *s; - - /* "This is the MPPE Master Key" */ - static const u_char Magic1[27] = - { 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x4d, 0x50, 0x50, 0x45, 0x20, 0x4d, - 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x4b, 0x65, 0x79 }; - /* "On the client side, this is the send key; " - "on the server side, it is the receive key." */ - static const u_char Magic2[84] = - { 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, - 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79, - 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x69, 0x64, 0x65, - 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20, - 0x6b, 0x65, 0x79, 0x2e }; - /* "On the client side, this is the receive key; " - "on the server side, it is the send key." */ - static const u_char Magic3[84] = - { 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, - 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20, - 0x6b, 0x65, 0x79, 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, - 0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, - 0x6b, 0x65, 0x79, 0x2e }; - - /* Hash (x2) the Unicode version of the secret (== password). */ - ascii2unicode(secret, secret_len, unicodePassword); - NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); - NTPasswordHash(PasswordHash, sizeof(PasswordHash), PasswordHashHash); - - lwip_sha1_init(&sha1Context); - lwip_sha1_starts(&sha1Context); - lwip_sha1_update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); - lwip_sha1_update(&sha1Context, NTResponse, 24); - lwip_sha1_update(&sha1Context, Magic1, sizeof(Magic1)); - lwip_sha1_finish(&sha1Context, MasterKey); - lwip_sha1_free(&sha1Context); - - /* - * generate send key - */ - if (IsServer) - s = Magic3; - else - s = Magic2; - lwip_sha1_init(&sha1Context); - lwip_sha1_starts(&sha1Context); - lwip_sha1_update(&sha1Context, MasterKey, 16); - lwip_sha1_update(&sha1Context, mppe_sha1_pad1, SHA1_PAD_SIZE); - lwip_sha1_update(&sha1Context, s, 84); - lwip_sha1_update(&sha1Context, mppe_sha1_pad2, SHA1_PAD_SIZE); - lwip_sha1_finish(&sha1Context, Digest); - lwip_sha1_free(&sha1Context); - - mppe_set_key(pcb, &pcb->mppe_comp, Digest); - - /* - * generate recv key - */ - if (IsServer) - s = Magic2; - else - s = Magic3; - lwip_sha1_init(&sha1Context); - lwip_sha1_starts(&sha1Context); - lwip_sha1_update(&sha1Context, MasterKey, 16); - lwip_sha1_update(&sha1Context, mppe_sha1_pad1, SHA1_PAD_SIZE); - lwip_sha1_update(&sha1Context, s, 84); - lwip_sha1_update(&sha1Context, mppe_sha1_pad2, SHA1_PAD_SIZE); - lwip_sha1_finish(&sha1Context, Digest); - lwip_sha1_free(&sha1Context); - - mppe_set_key(pcb, &pcb->mppe_decomp, Digest); - - pcb->mppe_keys_set = 1; -} - -#endif /* MPPE_SUPPORT */ - - -static void ChapMS(ppp_pcb *pcb, const u_char *rchallenge, const char *secret, int secret_len, - unsigned char *response) { -#if !MPPE_SUPPORT - LWIP_UNUSED_ARG(pcb); -#endif /* !MPPE_SUPPORT */ - BZERO(response, MS_CHAP_RESPONSE_LEN); - - ChapMS_NT(rchallenge, secret, secret_len, &response[MS_CHAP_NTRESP]); - -#ifdef MSLANMAN - ChapMS_LANMan(rchallenge, secret, secret_len, - &response[MS_CHAP_LANMANRESP]); - - /* preferred method is set by option */ - response[MS_CHAP_USENT] = !ms_lanman; -#else - response[MS_CHAP_USENT] = 1; -#endif - -#if MPPE_SUPPORT - Set_Start_Key(pcb, rchallenge, secret, secret_len); -#endif /* MPPE_SUPPORT */ -} - - -/* - * If PeerChallenge is NULL, one is generated and the PeerChallenge - * field of response is filled in. Call this way when generating a response. - * If PeerChallenge is supplied, it is copied into the PeerChallenge field. - * Call this way when verifying a response (or debugging). - * Do not call with PeerChallenge = response. - * - * The PeerChallenge field of response is then used for calculation of the - * Authenticator Response. - */ -static void ChapMS2(ppp_pcb *pcb, const u_char *rchallenge, const u_char *PeerChallenge, - const char *user, const char *secret, int secret_len, unsigned char *response, - u_char authResponse[], int authenticator) { - /* ARGSUSED */ - LWIP_UNUSED_ARG(authenticator); -#if !MPPE_SUPPORT - LWIP_UNUSED_ARG(pcb); -#endif /* !MPPE_SUPPORT */ - - BZERO(response, MS_CHAP2_RESPONSE_LEN); - - /* Generate the Peer-Challenge if requested, or copy it if supplied. */ - if (!PeerChallenge) - magic_random_bytes(&response[MS_CHAP2_PEER_CHALLENGE], MS_CHAP2_PEER_CHAL_LEN); - else - MEMCPY(&response[MS_CHAP2_PEER_CHALLENGE], PeerChallenge, - MS_CHAP2_PEER_CHAL_LEN); - - /* Generate the NT-Response */ - ChapMS2_NT(rchallenge, &response[MS_CHAP2_PEER_CHALLENGE], user, - secret, secret_len, &response[MS_CHAP2_NTRESP]); - - /* Generate the Authenticator Response. */ - GenerateAuthenticatorResponsePlain(secret, secret_len, - &response[MS_CHAP2_NTRESP], - &response[MS_CHAP2_PEER_CHALLENGE], - rchallenge, user, authResponse); - -#if MPPE_SUPPORT - SetMasterKeys(pcb, secret, secret_len, - &response[MS_CHAP2_NTRESP], authenticator); -#endif /* MPPE_SUPPORT */ -} - -#if 0 /* UNUSED */ -#if MPPE_SUPPORT -/* - * Set MPPE options from plugins. - */ -void set_mppe_enc_types(int policy, int types) { - /* Early exit for unknown policies. */ - if (policy != MPPE_ENC_POL_ENC_ALLOWED || - policy != MPPE_ENC_POL_ENC_REQUIRED) - return; - - /* Don't modify MPPE if it's optional and wasn't already configured. */ - if (policy == MPPE_ENC_POL_ENC_ALLOWED && !ccp_wantoptions[0].mppe) - return; - - /* - * Disable undesirable encryption types. Note that we don't ENABLE - * any encryption types, to avoid overriding manual configuration. - */ - switch(types) { - case MPPE_ENC_TYPES_RC4_40: - ccp_wantoptions[0].mppe &= ~MPPE_OPT_128; /* disable 128-bit */ - break; - case MPPE_ENC_TYPES_RC4_128: - ccp_wantoptions[0].mppe &= ~MPPE_OPT_40; /* disable 40-bit */ - break; - default: - break; - } -} -#endif /* MPPE_SUPPORT */ -#endif /* UNUSED */ - -const struct chap_digest_type chapms_digest = { - CHAP_MICROSOFT, /* code */ -#if PPP_SERVER - chapms_generate_challenge, - chapms_verify_response, -#endif /* PPP_SERVER */ - chapms_make_response, - NULL, /* check_success */ - chapms_handle_failure, -}; - -const struct chap_digest_type chapms2_digest = { - CHAP_MICROSOFT_V2, /* code */ -#if PPP_SERVER - chapms2_generate_challenge, - chapms2_verify_response, -#endif /* PPP_SERVER */ - chapms2_make_response, - chapms2_check_success, - chapms_handle_failure, -}; - -#endif /* PPP_SUPPORT && MSCHAP_SUPPORT */ diff --git a/third-party/lwip-2.1.2/netif/ppp/demand.c b/third-party/lwip-2.1.2/netif/ppp/demand.c deleted file mode 100644 index 26c6c30d..00000000 --- a/third-party/lwip-2.1.2/netif/ppp/demand.c +++ /dev/null @@ -1,465 +0,0 @@ -/* - * demand.c - Support routines for demand-dialling. - * - * Copyright (c) 1996-2002 Paul Mackerras. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 3. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && DEMAND_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef PPP_FILTER -#include -#endif - -#include "netif/ppp/ppp_impl.h" - -#include "netif/ppp/fsm.h" -#include "netif/ppp/ipcp.h" -#include "netif/ppp/lcp.h" - -char *frame; -int framelen; -int framemax; -int escape_flag; -int flush_flag; -int fcs; - -struct packet { - int length; - struct packet *next; - unsigned char data[1]; -}; - -struct packet *pend_q; -struct packet *pend_qtail; - -static int active_packet (unsigned char *, int); - -/* - * demand_conf - configure the interface for doing dial-on-demand. - */ -void -demand_conf() -{ - int i; - const struct protent *protp; - -/* framemax = lcp_allowoptions[0].mru; - if (framemax < PPP_MRU) */ - framemax = PPP_MRU; - framemax += PPP_HDRLEN + PPP_FCSLEN; - frame = malloc(framemax); - if (frame == NULL) - novm("demand frame"); - framelen = 0; - pend_q = NULL; - escape_flag = 0; - flush_flag = 0; - fcs = PPP_INITFCS; - - netif_set_mtu(pcb, LWIP_MIN(lcp_allowoptions[0].mru, PPP_MRU)); - if (ppp_send_config(pcb, PPP_MRU, (u32_t) 0, 0, 0) < 0 - || ppp_recv_config(pcb, PPP_MRU, (u32_t) 0, 0, 0) < 0) - fatal("Couldn't set up demand-dialled PPP interface: %m"); - -#ifdef PPP_FILTER - set_filters(&pass_filter, &active_filter); -#endif - - /* - * Call the demand_conf procedure for each protocol that's got one. - */ - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (protp->demand_conf != NULL) - ((*protp->demand_conf)(pcb)); -/* FIXME: find a way to die() here */ -#if 0 - if (!((*protp->demand_conf)(pcb))) - die(1); -#endif -} - - -/* - * demand_block - set each network protocol to block further packets. - */ -void -demand_block() -{ - int i; - const struct protent *protp; - - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (protp->demand_conf != NULL) - sifnpmode(pcb, protp->protocol & ~0x8000, NPMODE_QUEUE); - get_loop_output(); -} - -/* - * demand_discard - set each network protocol to discard packets - * with an error. - */ -void -demand_discard() -{ - struct packet *pkt, *nextpkt; - int i; - const struct protent *protp; - - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (protp->demand_conf != NULL) - sifnpmode(pcb, protp->protocol & ~0x8000, NPMODE_ERROR); - get_loop_output(); - - /* discard all saved packets */ - for (pkt = pend_q; pkt != NULL; pkt = nextpkt) { - nextpkt = pkt->next; - free(pkt); - } - pend_q = NULL; - framelen = 0; - flush_flag = 0; - escape_flag = 0; - fcs = PPP_INITFCS; -} - -/* - * demand_unblock - set each enabled network protocol to pass packets. - */ -void -demand_unblock() -{ - int i; - const struct protent *protp; - - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (protp->demand_conf != NULL) - sifnpmode(pcb, protp->protocol & ~0x8000, NPMODE_PASS); -} - -/* - * FCS lookup table as calculated by genfcstab. - */ -static u_short fcstab[256] = { - 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, - 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, - 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, - 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, - 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, - 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, - 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, - 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, - 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, - 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, - 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, - 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, - 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, - 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, - 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, - 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, - 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, - 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, - 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, - 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, - 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, - 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, - 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, - 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, - 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, - 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, - 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, - 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, - 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, - 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, - 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, - 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 -}; - -/* - * loop_chars - process characters received from the loopback. - * Calls loop_frame when a complete frame has been accumulated. - * Return value is 1 if we need to bring up the link, 0 otherwise. - */ -int -loop_chars(p, n) - unsigned char *p; - int n; -{ - int c, rv; - - rv = 0; - -/* check for synchronous connection... */ - - if ( (p[0] == 0xFF) && (p[1] == 0x03) ) { - rv = loop_frame(p,n); - return rv; - } - - for (; n > 0; --n) { - c = *p++; - if (c == PPP_FLAG) { - if (!escape_flag && !flush_flag - && framelen > 2 && fcs == PPP_GOODFCS) { - framelen -= 2; - if (loop_frame((unsigned char *)frame, framelen)) - rv = 1; - } - framelen = 0; - flush_flag = 0; - escape_flag = 0; - fcs = PPP_INITFCS; - continue; - } - if (flush_flag) - continue; - if (escape_flag) { - c ^= PPP_TRANS; - escape_flag = 0; - } else if (c == PPP_ESCAPE) { - escape_flag = 1; - continue; - } - if (framelen >= framemax) { - flush_flag = 1; - continue; - } - frame[framelen++] = c; - fcs = PPP_FCS(fcs, c); - } - return rv; -} - -/* - * loop_frame - given a frame obtained from the loopback, - * decide whether to bring up the link or not, and, if we want - * to transmit this frame later, put it on the pending queue. - * Return value is 1 if we need to bring up the link, 0 otherwise. - * We assume that the kernel driver has already applied the - * pass_filter, so we won't get packets it rejected. - * We apply the active_filter to see if we want this packet to - * bring up the link. - */ -int -loop_frame(frame, len) - unsigned char *frame; - int len; -{ - struct packet *pkt; - - /* dbglog("from loop: %P", frame, len); */ - if (len < PPP_HDRLEN) - return 0; - if ((PPP_PROTOCOL(frame) & 0x8000) != 0) - return 0; /* shouldn't get any of these anyway */ - if (!active_packet(frame, len)) - return 0; - - pkt = (struct packet *) malloc(sizeof(struct packet) + len); - if (pkt != NULL) { - pkt->length = len; - pkt->next = NULL; - memcpy(pkt->data, frame, len); - if (pend_q == NULL) - pend_q = pkt; - else - pend_qtail->next = pkt; - pend_qtail = pkt; - } - return 1; -} - -/* - * demand_rexmit - Resend all those frames which we got via the - * loopback, now that the real serial link is up. - */ -void -demand_rexmit(proto, newip) - int proto; - u32_t newip; -{ - struct packet *pkt, *prev, *nextpkt; - unsigned short checksum; - unsigned short pkt_checksum = 0; - unsigned iphdr; - struct timeval tv; - char cv = 0; - char ipstr[16]; - - prev = NULL; - pkt = pend_q; - pend_q = NULL; - tv.tv_sec = 1; - tv.tv_usec = 0; - select(0,NULL,NULL,NULL,&tv); /* Sleep for 1 Seconds */ - for (; pkt != NULL; pkt = nextpkt) { - nextpkt = pkt->next; - if (PPP_PROTOCOL(pkt->data) == proto) { - if ( (proto == PPP_IP) && newip ) { - /* Get old checksum */ - - iphdr = (pkt->data[4] & 15) << 2; - checksum = *((unsigned short *) (pkt->data+14)); - if (checksum == 0xFFFF) { - checksum = 0; - } - - - if (pkt->data[13] == 17) { - pkt_checksum = *((unsigned short *) (pkt->data+10+iphdr)); - if (pkt_checksum) { - cv = 1; - if (pkt_checksum == 0xFFFF) { - pkt_checksum = 0; - } - } - else { - cv = 0; - } - } - - if (pkt->data[13] == 6) { - pkt_checksum = *((unsigned short *) (pkt->data+20+iphdr)); - cv = 1; - if (pkt_checksum == 0xFFFF) { - pkt_checksum = 0; - } - } - - /* Delete old Source-IP-Address */ - checksum -= *((unsigned short *) (pkt->data+16)) ^ 0xFFFF; - checksum -= *((unsigned short *) (pkt->data+18)) ^ 0xFFFF; - - pkt_checksum -= *((unsigned short *) (pkt->data+16)) ^ 0xFFFF; - pkt_checksum -= *((unsigned short *) (pkt->data+18)) ^ 0xFFFF; - - /* Change Source-IP-Address */ - * ((u32_t *) (pkt->data + 16)) = newip; - - /* Add new Source-IP-Address */ - checksum += *((unsigned short *) (pkt->data+16)) ^ 0xFFFF; - checksum += *((unsigned short *) (pkt->data+18)) ^ 0xFFFF; - - pkt_checksum += *((unsigned short *) (pkt->data+16)) ^ 0xFFFF; - pkt_checksum += *((unsigned short *) (pkt->data+18)) ^ 0xFFFF; - - /* Write new checksum */ - if (!checksum) { - checksum = 0xFFFF; - } - *((unsigned short *) (pkt->data+14)) = checksum; - if (pkt->data[13] == 6) { - *((unsigned short *) (pkt->data+20+iphdr)) = pkt_checksum; - } - if (cv && (pkt->data[13] == 17) ) { - *((unsigned short *) (pkt->data+10+iphdr)) = pkt_checksum; - } - - /* Log Packet */ - strcpy(ipstr,inet_ntoa(*( (struct in_addr *) (pkt->data+16)))); - if (pkt->data[13] == 1) { - syslog(LOG_INFO,"Open ICMP %s -> %s\n", - ipstr, - inet_ntoa(*( (struct in_addr *) (pkt->data+20)))); - } else { - syslog(LOG_INFO,"Open %s %s:%d -> %s:%d\n", - pkt->data[13] == 6 ? "TCP" : "UDP", - ipstr, - ntohs(*( (short *) (pkt->data+iphdr+4))), - inet_ntoa(*( (struct in_addr *) (pkt->data+20))), - ntohs(*( (short *) (pkt->data+iphdr+6)))); - } - } - output(pcb, pkt->data, pkt->length); - free(pkt); - } else { - if (prev == NULL) - pend_q = pkt; - else - prev->next = pkt; - prev = pkt; - } - } - pend_qtail = prev; - if (prev != NULL) - prev->next = NULL; -} - -/* - * Scan a packet to decide whether it is an "active" packet, - * that is, whether it is worth bringing up the link for. - */ -static int -active_packet(p, len) - unsigned char *p; - int len; -{ - int proto, i; - const struct protent *protp; - - if (len < PPP_HDRLEN) - return 0; - proto = PPP_PROTOCOL(p); -#ifdef PPP_FILTER - p[0] = 1; /* outbound packet indicator */ - if ((pass_filter.bf_len != 0 - && bpf_filter(pass_filter.bf_insns, p, len, len) == 0) - || (active_filter.bf_len != 0 - && bpf_filter(active_filter.bf_insns, p, len, len) == 0)) { - p[0] = 0xff; - return 0; - } - p[0] = 0xff; -#endif - for (i = 0; (protp = protocols[i]) != NULL; ++i) { - if (protp->protocol < 0xC000 && (protp->protocol & ~0x8000) == proto) { - if (protp->active_pkt == NULL) - return 1; - return (*protp->active_pkt)(p, len); - } - } - return 0; /* not a supported protocol !!?? */ -} - -#endif /* PPP_SUPPORT && DEMAND_SUPPORT */ diff --git a/third-party/lwip-2.1.2/netif/ppp/eap.c b/third-party/lwip-2.1.2/netif/ppp/eap.c deleted file mode 100644 index 8fb56368..00000000 --- a/third-party/lwip-2.1.2/netif/ppp/eap.c +++ /dev/null @@ -1,2423 +0,0 @@ -/* - * eap.c - Extensible Authentication Protocol for PPP (RFC 2284) - * - * Copyright (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - * - * Non-exclusive rights to redistribute, modify, translate, and use - * this software in source and binary forms, in whole or in part, is - * hereby granted, provided that the above copyright notice is - * duplicated in any source form, and that neither the name of the - * copyright holder nor the author is used to endorse or promote - * products derived from this software. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Original version by James Carlson - * - * This implementation of EAP supports MD5-Challenge and SRP-SHA1 - * authentication styles. Note that support of MD5-Challenge is a - * requirement of RFC 2284, and that it's essentially just a - * reimplementation of regular RFC 1994 CHAP using EAP messages. - * - * As an authenticator ("server"), there are multiple phases for each - * style. In the first phase of each style, the unauthenticated peer - * name is queried using the EAP Identity request type. If the - * "remotename" option is used, then this phase is skipped, because - * the peer's name is presumed to be known. - * - * For MD5-Challenge, there are two phases, and the second phase - * consists of sending the challenge itself and handling the - * associated response. - * - * For SRP-SHA1, there are four phases. The second sends 's', 'N', - * and 'g'. The reply contains 'A'. The third sends 'B', and the - * reply contains 'M1'. The forth sends the 'M2' value. - * - * As an authenticatee ("client"), there's just a single phase -- - * responding to the queries generated by the peer. EAP is an - * authenticator-driven protocol. - * - * Based on draft-ietf-pppext-eap-srp-03.txt. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && EAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include "netif/ppp/ppp_impl.h" -#include "netif/ppp/eap.h" -#include "netif/ppp/magic.h" -#include "netif/ppp/pppcrypt.h" - -#ifdef USE_SRP -#include -#include -#include -#endif /* USE_SRP */ - -#ifndef SHA_DIGESTSIZE -#define SHA_DIGESTSIZE 20 -#endif - -#ifdef USE_SRP -static char *pn_secret = NULL; /* Pseudonym generating secret */ -#endif - -#if PPP_OPTIONS -/* - * Command-line options. - */ -static option_t eap_option_list[] = { - { "eap-restart", o_int, &eap_states[0].es_server.ea_timeout, - "Set retransmit timeout for EAP Requests (server)" }, - { "eap-max-sreq", o_int, &eap_states[0].es_server.ea_maxrequests, - "Set max number of EAP Requests sent (server)" }, - { "eap-timeout", o_int, &eap_states[0].es_client.ea_timeout, - "Set time limit for peer EAP authentication" }, - { "eap-max-rreq", o_int, &eap_states[0].es_client.ea_maxrequests, - "Set max number of EAP Requests allows (client)" }, - { "eap-interval", o_int, &eap_states[0].es_rechallenge, - "Set interval for EAP rechallenge" }, -#ifdef USE_SRP - { "srp-interval", o_int, &eap_states[0].es_lwrechallenge, - "Set interval for SRP lightweight rechallenge" }, - { "srp-pn-secret", o_string, &pn_secret, - "Long term pseudonym generation secret" }, - { "srp-use-pseudonym", o_bool, &eap_states[0].es_usepseudo, - "Use pseudonym if offered one by server", 1 }, -#endif - { NULL } -}; -#endif /* PPP_OPTIONS */ - -/* - * Protocol entry points. - */ -static void eap_init(ppp_pcb *pcb); -static void eap_input(ppp_pcb *pcb, u_char *inp, int inlen); -static void eap_protrej(ppp_pcb *pcb); -static void eap_lowerup(ppp_pcb *pcb); -static void eap_lowerdown(ppp_pcb *pcb); -#if PRINTPKT_SUPPORT -static int eap_printpkt(const u_char *inp, int inlen, - void (*)(void *arg, const char *fmt, ...), void *arg); -#endif /* PRINTPKT_SUPPORT */ - -const struct protent eap_protent = { - PPP_EAP, /* protocol number */ - eap_init, /* initialization procedure */ - eap_input, /* process a received packet */ - eap_protrej, /* process a received protocol-reject */ - eap_lowerup, /* lower layer has gone up */ - eap_lowerdown, /* lower layer has gone down */ - NULL, /* open the protocol */ - NULL, /* close the protocol */ -#if PRINTPKT_SUPPORT - eap_printpkt, /* print a packet in readable form */ -#endif /* PRINTPKT_SUPPORT */ -#if PPP_DATAINPUT - NULL, /* process a received data packet */ -#endif /* PPP_DATAINPUT */ -#if PRINTPKT_SUPPORT - "EAP", /* text name of protocol */ - NULL, /* text name of corresponding data protocol */ -#endif /* PRINTPKT_SUPPORT */ -#if PPP_OPTIONS - eap_option_list, /* list of command-line options */ - NULL, /* check requested options; assign defaults */ -#endif /* PPP_OPTIONS */ -#if DEMAND_SUPPORT - NULL, /* configure interface for demand-dial */ - NULL /* say whether to bring up link for this pkt */ -#endif /* DEMAND_SUPPORT */ -}; - -#ifdef USE_SRP -/* - * A well-known 2048 bit modulus. - */ -static const u_char wkmodulus[] = { - 0xAC, 0x6B, 0xDB, 0x41, 0x32, 0x4A, 0x9A, 0x9B, - 0xF1, 0x66, 0xDE, 0x5E, 0x13, 0x89, 0x58, 0x2F, - 0xAF, 0x72, 0xB6, 0x65, 0x19, 0x87, 0xEE, 0x07, - 0xFC, 0x31, 0x92, 0x94, 0x3D, 0xB5, 0x60, 0x50, - 0xA3, 0x73, 0x29, 0xCB, 0xB4, 0xA0, 0x99, 0xED, - 0x81, 0x93, 0xE0, 0x75, 0x77, 0x67, 0xA1, 0x3D, - 0xD5, 0x23, 0x12, 0xAB, 0x4B, 0x03, 0x31, 0x0D, - 0xCD, 0x7F, 0x48, 0xA9, 0xDA, 0x04, 0xFD, 0x50, - 0xE8, 0x08, 0x39, 0x69, 0xED, 0xB7, 0x67, 0xB0, - 0xCF, 0x60, 0x95, 0x17, 0x9A, 0x16, 0x3A, 0xB3, - 0x66, 0x1A, 0x05, 0xFB, 0xD5, 0xFA, 0xAA, 0xE8, - 0x29, 0x18, 0xA9, 0x96, 0x2F, 0x0B, 0x93, 0xB8, - 0x55, 0xF9, 0x79, 0x93, 0xEC, 0x97, 0x5E, 0xEA, - 0xA8, 0x0D, 0x74, 0x0A, 0xDB, 0xF4, 0xFF, 0x74, - 0x73, 0x59, 0xD0, 0x41, 0xD5, 0xC3, 0x3E, 0xA7, - 0x1D, 0x28, 0x1E, 0x44, 0x6B, 0x14, 0x77, 0x3B, - 0xCA, 0x97, 0xB4, 0x3A, 0x23, 0xFB, 0x80, 0x16, - 0x76, 0xBD, 0x20, 0x7A, 0x43, 0x6C, 0x64, 0x81, - 0xF1, 0xD2, 0xB9, 0x07, 0x87, 0x17, 0x46, 0x1A, - 0x5B, 0x9D, 0x32, 0xE6, 0x88, 0xF8, 0x77, 0x48, - 0x54, 0x45, 0x23, 0xB5, 0x24, 0xB0, 0xD5, 0x7D, - 0x5E, 0xA7, 0x7A, 0x27, 0x75, 0xD2, 0xEC, 0xFA, - 0x03, 0x2C, 0xFB, 0xDB, 0xF5, 0x2F, 0xB3, 0x78, - 0x61, 0x60, 0x27, 0x90, 0x04, 0xE5, 0x7A, 0xE6, - 0xAF, 0x87, 0x4E, 0x73, 0x03, 0xCE, 0x53, 0x29, - 0x9C, 0xCC, 0x04, 0x1C, 0x7B, 0xC3, 0x08, 0xD8, - 0x2A, 0x56, 0x98, 0xF3, 0xA8, 0xD0, 0xC3, 0x82, - 0x71, 0xAE, 0x35, 0xF8, 0xE9, 0xDB, 0xFB, 0xB6, - 0x94, 0xB5, 0xC8, 0x03, 0xD8, 0x9F, 0x7A, 0xE4, - 0x35, 0xDE, 0x23, 0x6D, 0x52, 0x5F, 0x54, 0x75, - 0x9B, 0x65, 0xE3, 0x72, 0xFC, 0xD6, 0x8E, 0xF2, - 0x0F, 0xA7, 0x11, 0x1F, 0x9E, 0x4A, 0xFF, 0x73 -}; -#endif - -#if PPP_SERVER -/* Local forward declarations. */ -static void eap_server_timeout(void *arg); -#endif /* PPP_SERVER */ - -/* - * Convert EAP state code to printable string for debug. - */ -static const char * eap_state_name(enum eap_state_code esc) -{ - static const char *state_names[] = { EAP_STATES }; - - return (state_names[(int)esc]); -} - -/* - * eap_init - Initialize state for an EAP user. This is currently - * called once by main() during start-up. - */ -static void eap_init(ppp_pcb *pcb) { - - BZERO(&pcb->eap, sizeof(eap_state)); -#if PPP_SERVER - pcb->eap.es_server.ea_id = magic(); -#endif /* PPP_SERVER */ -} - -/* - * eap_client_timeout - Give up waiting for the peer to send any - * Request messages. - */ -static void eap_client_timeout(void *arg) { - ppp_pcb *pcb = (ppp_pcb*)arg; - - if (!eap_client_active(pcb)) - return; - - ppp_error("EAP: timeout waiting for Request from peer"); - auth_withpeer_fail(pcb, PPP_EAP); - pcb->eap.es_client.ea_state = eapBadAuth; -} - -/* - * eap_authwithpeer - Authenticate to our peer (behave as client). - * - * Start client state and wait for requests. This is called only - * after eap_lowerup. - */ -void eap_authwithpeer(ppp_pcb *pcb, const char *localname) { - - if(NULL == localname) - return; - - /* Save the peer name we're given */ - pcb->eap.es_client.ea_name = localname; - pcb->eap.es_client.ea_namelen = strlen(localname); - - pcb->eap.es_client.ea_state = eapListen; - - /* - * Start a timer so that if the other end just goes - * silent, we don't sit here waiting forever. - */ - if (pcb->settings.eap_req_time > 0) - TIMEOUT(eap_client_timeout, pcb, - pcb->settings.eap_req_time); -} - -#if PPP_SERVER -/* - * Format a standard EAP Failure message and send it to the peer. - * (Server operation) - */ -static void eap_send_failure(ppp_pcb *pcb) { - struct pbuf *p; - u_char *outp; - - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + EAP_HEADERLEN), PPP_CTRL_PBUF_TYPE); - if(NULL == p) - return; - if(p->tot_len != p->len) { - pbuf_free(p); - return; - } - - outp = (u_char*)p->payload; - - MAKEHEADER(outp, PPP_EAP); - - PUTCHAR(EAP_FAILURE, outp); - pcb->eap.es_server.ea_id++; - PUTCHAR(pcb->eap.es_server.ea_id, outp); - PUTSHORT(EAP_HEADERLEN, outp); - - ppp_write(pcb, p); - - pcb->eap.es_server.ea_state = eapBadAuth; - auth_peer_fail(pcb, PPP_EAP); -} - -/* - * Format a standard EAP Success message and send it to the peer. - * (Server operation) - */ -static void eap_send_success(ppp_pcb *pcb) { - struct pbuf *p; - u_char *outp; - - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + EAP_HEADERLEN), PPP_CTRL_PBUF_TYPE); - if(NULL == p) - return; - if(p->tot_len != p->len) { - pbuf_free(p); - return; - } - - outp = (u_char*)p->payload; - - MAKEHEADER(outp, PPP_EAP); - - PUTCHAR(EAP_SUCCESS, outp); - pcb->eap.es_server.ea_id++; - PUTCHAR(pcb->eap.es_server.ea_id, outp); - PUTSHORT(EAP_HEADERLEN, outp); - - ppp_write(pcb, p); - - auth_peer_success(pcb, PPP_EAP, 0, - pcb->eap.es_server.ea_peer, pcb->eap.es_server.ea_peerlen); -} -#endif /* PPP_SERVER */ - -#ifdef USE_SRP -/* - * Set DES key according to pseudonym-generating secret and current - * date. - */ -static bool -pncrypt_setkey(int timeoffs) -{ - struct tm *tp; - char tbuf[9]; - SHA1_CTX ctxt; - u_char dig[SHA_DIGESTSIZE]; - time_t reftime; - - if (pn_secret == NULL) - return (0); - reftime = time(NULL) + timeoffs; - tp = localtime(&reftime); - SHA1Init(&ctxt); - SHA1Update(&ctxt, pn_secret, strlen(pn_secret)); - strftime(tbuf, sizeof (tbuf), "%Y%m%d", tp); - SHA1Update(&ctxt, tbuf, strlen(tbuf)); - SHA1Final(dig, &ctxt); - /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ - return (DesSetkey(dig)); -} - -static char base64[] = -"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -struct b64state { - u32_t bs_bits; - int bs_offs; -}; - -static int -b64enc(bs, inp, inlen, outp) -struct b64state *bs; -u_char *inp; -int inlen; -u_char *outp; -{ - int outlen = 0; - - while (inlen > 0) { - bs->bs_bits = (bs->bs_bits << 8) | *inp++; - inlen--; - bs->bs_offs += 8; - if (bs->bs_offs >= 24) { - *outp++ = base64[(bs->bs_bits >> 18) & 0x3F]; - *outp++ = base64[(bs->bs_bits >> 12) & 0x3F]; - *outp++ = base64[(bs->bs_bits >> 6) & 0x3F]; - *outp++ = base64[bs->bs_bits & 0x3F]; - outlen += 4; - bs->bs_offs = 0; - bs->bs_bits = 0; - } - } - return (outlen); -} - -static int -b64flush(bs, outp) -struct b64state *bs; -u_char *outp; -{ - int outlen = 0; - - if (bs->bs_offs == 8) { - *outp++ = base64[(bs->bs_bits >> 2) & 0x3F]; - *outp++ = base64[(bs->bs_bits << 4) & 0x3F]; - outlen = 2; - } else if (bs->bs_offs == 16) { - *outp++ = base64[(bs->bs_bits >> 10) & 0x3F]; - *outp++ = base64[(bs->bs_bits >> 4) & 0x3F]; - *outp++ = base64[(bs->bs_bits << 2) & 0x3F]; - outlen = 3; - } - bs->bs_offs = 0; - bs->bs_bits = 0; - return (outlen); -} - -static int -b64dec(bs, inp, inlen, outp) -struct b64state *bs; -u_char *inp; -int inlen; -u_char *outp; -{ - int outlen = 0; - char *cp; - - while (inlen > 0) { - if ((cp = strchr(base64, *inp++)) == NULL) - break; - bs->bs_bits = (bs->bs_bits << 6) | (cp - base64); - inlen--; - bs->bs_offs += 6; - if (bs->bs_offs >= 8) { - *outp++ = bs->bs_bits >> (bs->bs_offs - 8); - outlen++; - bs->bs_offs -= 8; - } - } - return (outlen); -} -#endif /* USE_SRP */ - -#if PPP_SERVER -/* - * Assume that current waiting server state is complete and figure - * next state to use based on available authentication data. 'status' - * indicates if there was an error in handling the last query. It is - * 0 for success and non-zero for failure. - */ -static void eap_figure_next_state(ppp_pcb *pcb, int status) { -#ifdef USE_SRP - unsigned char secbuf[MAXSECRETLEN], clear[8], *sp, *dp; - struct t_pw tpw; - struct t_confent *tce, mytce; - char *cp, *cp2; - struct t_server *ts; - int id, i, plen, toffs; - u_char vals[2]; - struct b64state bs; -#endif /* USE_SRP */ - - pcb->settings.eap_timeout_time = pcb->eap.es_savedtime; - switch (pcb->eap.es_server.ea_state) { - case eapBadAuth: - return; - - case eapIdentify: -#ifdef USE_SRP - /* Discard any previous session. */ - ts = (struct t_server *)pcb->eap.es_server.ea_session; - if (ts != NULL) { - t_serverclose(ts); - pcb->eap.es_server.ea_session = NULL; - pcb->eap.es_server.ea_skey = NULL; - } -#endif /* USE_SRP */ - if (status != 0) { - pcb->eap.es_server.ea_state = eapBadAuth; - break; - } -#ifdef USE_SRP - /* If we've got a pseudonym, try to decode to real name. */ - if (pcb->eap.es_server.ea_peerlen > SRP_PSEUDO_LEN && - strncmp(pcb->eap.es_server.ea_peer, SRP_PSEUDO_ID, - SRP_PSEUDO_LEN) == 0 && - (pcb->eap.es_server.ea_peerlen - SRP_PSEUDO_LEN) * 3 / 4 < - sizeof (secbuf)) { - BZERO(&bs, sizeof (bs)); - plen = b64dec(&bs, - pcb->eap.es_server.ea_peer + SRP_PSEUDO_LEN, - pcb->eap.es_server.ea_peerlen - SRP_PSEUDO_LEN, - secbuf); - toffs = 0; - for (i = 0; i < 5; i++) { - pncrypt_setkey(toffs); - toffs -= 86400; - /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ - if (!DesDecrypt(secbuf, clear)) { - ppp_dbglog("no DES here; cannot decode " - "pseudonym"); - return; - } - id = *(unsigned char *)clear; - if (id + 1 <= plen && id + 9 > plen) - break; - } - if (plen % 8 == 0 && i < 5) { - /* - * Note that this is always shorter than the - * original stored string, so there's no need - * to realloc. - */ - if ((i = plen = *(unsigned char *)clear) > 7) - i = 7; - pcb->eap.es_server.ea_peerlen = plen; - dp = (unsigned char *)pcb->eap.es_server.ea_peer; - MEMCPY(dp, clear + 1, i); - plen -= i; - dp += i; - sp = secbuf + 8; - while (plen > 0) { - /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ - (void) DesDecrypt(sp, dp); - sp += 8; - dp += 8; - plen -= 8; - } - pcb->eap.es_server.ea_peer[ - pcb->eap.es_server.ea_peerlen] = '\0'; - ppp_dbglog("decoded pseudonym to \"%.*q\"", - pcb->eap.es_server.ea_peerlen, - pcb->eap.es_server.ea_peer); - } else { - ppp_dbglog("failed to decode real name"); - /* Stay in eapIdentfy state; requery */ - break; - } - } - /* Look up user in secrets database. */ - if (get_srp_secret(pcb->eap.es_unit, pcb->eap.es_server.ea_peer, - pcb->eap.es_server.ea_name, (char *)secbuf, 1) != 0) { - /* Set up default in case SRP entry is bad */ - pcb->eap.es_server.ea_state = eapMD5Chall; - /* Get t_confent based on index in srp-secrets */ - id = strtol((char *)secbuf, &cp, 10); - if (*cp++ != ':' || id < 0) - break; - if (id == 0) { - mytce.index = 0; - mytce.modulus.data = (u_char *)wkmodulus; - mytce.modulus.len = sizeof (wkmodulus); - mytce.generator.data = (u_char *)"\002"; - mytce.generator.len = 1; - tce = &mytce; - } else if ((tce = gettcid(id)) != NULL) { - /* - * Client will have to verify this modulus/ - * generator combination, and that will take - * a while. Lengthen the timeout here. - */ - if (pcb->settings.eap_timeout_time > 0 && - pcb->settings.eap_timeout_time < 30) - pcb->settings.eap_timeout_time = 30; - } else { - break; - } - if ((cp2 = strchr(cp, ':')) == NULL) - break; - *cp2++ = '\0'; - tpw.pebuf.name = pcb->eap.es_server.ea_peer; - tpw.pebuf.password.len = t_fromb64((char *)tpw.pwbuf, - cp); - tpw.pebuf.password.data = tpw.pwbuf; - tpw.pebuf.salt.len = t_fromb64((char *)tpw.saltbuf, - cp2); - tpw.pebuf.salt.data = tpw.saltbuf; - if ((ts = t_serveropenraw(&tpw.pebuf, tce)) == NULL) - break; - pcb->eap.es_server.ea_session = (void *)ts; - pcb->eap.es_server.ea_state = eapSRP1; - vals[0] = pcb->eap.es_server.ea_id + 1; - vals[1] = EAPT_SRP; - t_serveraddexdata(ts, vals, 2); - /* Generate B; must call before t_servergetkey() */ - t_servergenexp(ts); - break; - } -#endif /* USE_SRP */ - pcb->eap.es_server.ea_state = eapMD5Chall; - break; - - case eapSRP1: -#ifdef USE_SRP - ts = (struct t_server *)pcb->eap.es_server.ea_session; - if (ts != NULL && status != 0) { - t_serverclose(ts); - pcb->eap.es_server.ea_session = NULL; - pcb->eap.es_server.ea_skey = NULL; - } -#endif /* USE_SRP */ - if (status == 1) { - pcb->eap.es_server.ea_state = eapMD5Chall; - } else if (status != 0 || pcb->eap.es_server.ea_session == NULL) { - pcb->eap.es_server.ea_state = eapBadAuth; - } else { - pcb->eap.es_server.ea_state = eapSRP2; - } - break; - - case eapSRP2: -#ifdef USE_SRP - ts = (struct t_server *)pcb->eap.es_server.ea_session; - if (ts != NULL && status != 0) { - t_serverclose(ts); - pcb->eap.es_server.ea_session = NULL; - pcb->eap.es_server.ea_skey = NULL; - } -#endif /* USE_SRP */ - if (status != 0 || pcb->eap.es_server.ea_session == NULL) { - pcb->eap.es_server.ea_state = eapBadAuth; - } else { - pcb->eap.es_server.ea_state = eapSRP3; - } - break; - - case eapSRP3: - case eapSRP4: -#ifdef USE_SRP - ts = (struct t_server *)pcb->eap.es_server.ea_session; - if (ts != NULL && status != 0) { - t_serverclose(ts); - pcb->eap.es_server.ea_session = NULL; - pcb->eap.es_server.ea_skey = NULL; - } -#endif /* USE_SRP */ - if (status != 0 || pcb->eap.es_server.ea_session == NULL) { - pcb->eap.es_server.ea_state = eapBadAuth; - } else { - pcb->eap.es_server.ea_state = eapOpen; - } - break; - - case eapMD5Chall: - if (status != 0) { - pcb->eap.es_server.ea_state = eapBadAuth; - } else { - pcb->eap.es_server.ea_state = eapOpen; - } - break; - - default: - pcb->eap.es_server.ea_state = eapBadAuth; - break; - } - if (pcb->eap.es_server.ea_state == eapBadAuth) - eap_send_failure(pcb); -} - -/* - * Format an EAP Request message and send it to the peer. Message - * type depends on current state. (Server operation) - */ -static void eap_send_request(ppp_pcb *pcb) { - struct pbuf *p; - u_char *outp; - u_char *lenloc; - int outlen; - int len; - const char *str; -#ifdef USE_SRP - struct t_server *ts; - u_char clear[8], cipher[8], dig[SHA_DIGESTSIZE], *optr, *cp; - int i, j; - struct b64state b64; - SHA1_CTX ctxt; -#endif /* USE_SRP */ - - /* Handle both initial auth and restart */ - if (pcb->eap.es_server.ea_state < eapIdentify && - pcb->eap.es_server.ea_state != eapInitial) { - pcb->eap.es_server.ea_state = eapIdentify; -#if PPP_REMOTENAME - if (pcb->settings.explicit_remote && pcb->remote_name) { - /* - * If we already know the peer's - * unauthenticated name, then there's no - * reason to ask. Go to next state instead. - */ - int len = (int)strlen(pcb->remote_name); - if (len > MAXNAMELEN) { - len = MAXNAMELEN; - } - MEMCPY(pcb->eap.es_server.ea_peer, pcb->remote_name, len); - pcb->eap.es_server.ea_peer[len] = '\0'; - pcb->eap.es_server.ea_peerlen = len; - eap_figure_next_state(pcb, 0); - } -#endif /* PPP_REMOTENAME */ - } - - if (pcb->settings.eap_max_transmits > 0 && - pcb->eap.es_server.ea_requests >= pcb->settings.eap_max_transmits) { - if (pcb->eap.es_server.ea_responses > 0) - ppp_error("EAP: too many Requests sent"); - else - ppp_error("EAP: no response to Requests"); - eap_send_failure(pcb); - return; - } - - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_CTRL_PBUF_MAX_SIZE), PPP_CTRL_PBUF_TYPE); - if(NULL == p) - return; - if(p->tot_len != p->len) { - pbuf_free(p); - return; - } - - outp = (u_char*)p->payload; - - MAKEHEADER(outp, PPP_EAP); - - PUTCHAR(EAP_REQUEST, outp); - PUTCHAR(pcb->eap.es_server.ea_id, outp); - lenloc = outp; - INCPTR(2, outp); - - switch (pcb->eap.es_server.ea_state) { - case eapIdentify: - PUTCHAR(EAPT_IDENTITY, outp); - str = "Name"; - len = strlen(str); - MEMCPY(outp, str, len); - INCPTR(len, outp); - break; - - case eapMD5Chall: - PUTCHAR(EAPT_MD5CHAP, outp); - /* - * pick a random challenge length between - * EAP_MIN_CHALLENGE_LENGTH and EAP_MAX_CHALLENGE_LENGTH - */ - pcb->eap.es_challen = EAP_MIN_CHALLENGE_LENGTH + - magic_pow(EAP_MIN_MAX_POWER_OF_TWO_CHALLENGE_LENGTH); - PUTCHAR(pcb->eap.es_challen, outp); - magic_random_bytes(pcb->eap.es_challenge, pcb->eap.es_challen); - MEMCPY(outp, pcb->eap.es_challenge, pcb->eap.es_challen); - INCPTR(pcb->eap.es_challen, outp); - MEMCPY(outp, pcb->eap.es_server.ea_name, pcb->eap.es_server.ea_namelen); - INCPTR(pcb->eap.es_server.ea_namelen, outp); - break; - -#ifdef USE_SRP - case eapSRP1: - PUTCHAR(EAPT_SRP, outp); - PUTCHAR(EAPSRP_CHALLENGE, outp); - - PUTCHAR(pcb->eap.es_server.ea_namelen, outp); - MEMCPY(outp, pcb->eap.es_server.ea_name, pcb->eap.es_server.ea_namelen); - INCPTR(pcb->eap.es_server.ea_namelen, outp); - - ts = (struct t_server *)pcb->eap.es_server.ea_session; - assert(ts != NULL); - PUTCHAR(ts->s.len, outp); - MEMCPY(outp, ts->s.data, ts->s.len); - INCPTR(ts->s.len, outp); - - if (ts->g.len == 1 && ts->g.data[0] == 2) { - PUTCHAR(0, outp); - } else { - PUTCHAR(ts->g.len, outp); - MEMCPY(outp, ts->g.data, ts->g.len); - INCPTR(ts->g.len, outp); - } - - if (ts->n.len != sizeof (wkmodulus) || - BCMP(ts->n.data, wkmodulus, sizeof (wkmodulus)) != 0) { - MEMCPY(outp, ts->n.data, ts->n.len); - INCPTR(ts->n.len, outp); - } - break; - - case eapSRP2: - PUTCHAR(EAPT_SRP, outp); - PUTCHAR(EAPSRP_SKEY, outp); - - ts = (struct t_server *)pcb->eap.es_server.ea_session; - assert(ts != NULL); - MEMCPY(outp, ts->B.data, ts->B.len); - INCPTR(ts->B.len, outp); - break; - - case eapSRP3: - PUTCHAR(EAPT_SRP, outp); - PUTCHAR(EAPSRP_SVALIDATOR, outp); - PUTLONG(SRPVAL_EBIT, outp); - ts = (struct t_server *)pcb->eap.es_server.ea_session; - assert(ts != NULL); - MEMCPY(outp, t_serverresponse(ts), SHA_DIGESTSIZE); - INCPTR(SHA_DIGESTSIZE, outp); - - if (pncrypt_setkey(0)) { - /* Generate pseudonym */ - optr = outp; - cp = (unsigned char *)pcb->eap.es_server.ea_peer; - if ((j = i = pcb->eap.es_server.ea_peerlen) > 7) - j = 7; - clear[0] = i; - MEMCPY(clear + 1, cp, j); - i -= j; - cp += j; - /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ - if (!DesEncrypt(clear, cipher)) { - ppp_dbglog("no DES here; not generating pseudonym"); - break; - } - BZERO(&b64, sizeof (b64)); - outp++; /* space for pseudonym length */ - outp += b64enc(&b64, cipher, 8, outp); - while (i >= 8) { - /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ - (void) DesEncrypt(cp, cipher); - outp += b64enc(&b64, cipher, 8, outp); - cp += 8; - i -= 8; - } - if (i > 0) { - MEMCPY(clear, cp, i); - cp += i; - magic_random_bytes(cp, 8-i); - /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ - (void) DesEncrypt(clear, cipher); - outp += b64enc(&b64, cipher, 8, outp); - } - outp += b64flush(&b64, outp); - - /* Set length and pad out to next 20 octet boundary */ - i = outp - optr - 1; - *optr = i; - i %= SHA_DIGESTSIZE; - if (i != 0) { - magic_random_bytes(outp, SHA_DIGESTSIZE-i); - INCPTR(SHA_DIGESTSIZE-i, outp); - } - - /* Obscure the pseudonym with SHA1 hash */ - SHA1Init(&ctxt); - SHA1Update(&ctxt, &pcb->eap.es_server.ea_id, 1); - SHA1Update(&ctxt, pcb->eap.es_server.ea_skey, - SESSION_KEY_LEN); - SHA1Update(&ctxt, pcb->eap.es_server.ea_peer, - pcb->eap.es_server.ea_peerlen); - while (optr < outp) { - SHA1Final(dig, &ctxt); - cp = dig; - while (cp < dig + SHA_DIGESTSIZE) - *optr++ ^= *cp++; - SHA1Init(&ctxt); - SHA1Update(&ctxt, &pcb->eap.es_server.ea_id, 1); - SHA1Update(&ctxt, pcb->eap.es_server.ea_skey, - SESSION_KEY_LEN); - SHA1Update(&ctxt, optr - SHA_DIGESTSIZE, - SHA_DIGESTSIZE); - } - } - break; - - case eapSRP4: - PUTCHAR(EAPT_SRP, outp); - PUTCHAR(EAPSRP_LWRECHALLENGE, outp); - pcb->eap.es_challen = EAP_MIN_CHALLENGE_LENGTH + - magic_pow(EAP_MIN_MAX_POWER_OF_TWO_CHALLENGE_LENGTH); - magic_random_bytes(pcb->eap.es_challenge, pcb->eap.es_challen); - MEMCPY(outp, pcb->eap.es_challenge, pcb->eap.es_challen); - INCPTR(pcb->eap.es_challen, outp); - break; -#endif /* USE_SRP */ - - default: - return; - } - - outlen = (outp - (unsigned char*)p->payload) - PPP_HDRLEN; - PUTSHORT(outlen, lenloc); - - pbuf_realloc(p, outlen + PPP_HDRLEN); - ppp_write(pcb, p); - - pcb->eap.es_server.ea_requests++; - - if (pcb->settings.eap_timeout_time > 0) - TIMEOUT(eap_server_timeout, pcb, pcb->settings.eap_timeout_time); -} - -/* - * eap_authpeer - Authenticate our peer (behave as server). - * - * Start server state and send first request. This is called only - * after eap_lowerup. - */ -void eap_authpeer(ppp_pcb *pcb, const char *localname) { - - /* Save the name we're given. */ - pcb->eap.es_server.ea_name = localname; - pcb->eap.es_server.ea_namelen = strlen(localname); - - pcb->eap.es_savedtime = pcb->settings.eap_timeout_time; - - /* Lower layer up yet? */ - if (pcb->eap.es_server.ea_state == eapInitial || - pcb->eap.es_server.ea_state == eapPending) { - pcb->eap.es_server.ea_state = eapPending; - return; - } - - pcb->eap.es_server.ea_state = eapPending; - - /* ID number not updated here intentionally; hashed into M1 */ - eap_send_request(pcb); -} - -/* - * eap_server_timeout - Retransmission timer for sending Requests - * expired. - */ -static void eap_server_timeout(void *arg) { - ppp_pcb *pcb = (ppp_pcb*)arg; - - if (!eap_server_active(pcb)) - return; - - /* EAP ID number must not change on timeout. */ - eap_send_request(pcb); -} - -/* - * When it's time to send rechallenge the peer, this timeout is - * called. Once the rechallenge is successful, the response handler - * will restart the timer. If it fails, then the link is dropped. - */ -static void eap_rechallenge(void *arg) { - ppp_pcb *pcb = (ppp_pcb*)arg; - - if (pcb->eap.es_server.ea_state != eapOpen && - pcb->eap.es_server.ea_state != eapSRP4) - return; - - pcb->eap.es_server.ea_requests = 0; - pcb->eap.es_server.ea_state = eapIdentify; - eap_figure_next_state(pcb, 0); - pcb->eap.es_server.ea_id++; - eap_send_request(pcb); -} - -static void srp_lwrechallenge(void *arg) { - ppp_pcb *pcb = (ppp_pcb*)arg; - - if (pcb->eap.es_server.ea_state != eapOpen || - pcb->eap.es_server.ea_type != EAPT_SRP) - return; - - pcb->eap.es_server.ea_requests = 0; - pcb->eap.es_server.ea_state = eapSRP4; - pcb->eap.es_server.ea_id++; - eap_send_request(pcb); -} -#endif /* PPP_SERVER */ - -/* - * eap_lowerup - The lower layer is now up. - * - * This is called before either eap_authpeer or eap_authwithpeer. See - * link_established() in auth.c. All that's necessary here is to - * return to closed state so that those two routines will do the right - * thing. - */ -static void eap_lowerup(ppp_pcb *pcb) { - pcb->eap.es_client.ea_state = eapClosed; -#if PPP_SERVER - pcb->eap.es_server.ea_state = eapClosed; -#endif /* PPP_SERVER */ -} - -/* - * eap_lowerdown - The lower layer is now down. - * - * Cancel all timeouts and return to initial state. - */ -static void eap_lowerdown(ppp_pcb *pcb) { - - if (eap_client_active(pcb) && pcb->settings.eap_req_time > 0) { - UNTIMEOUT(eap_client_timeout, pcb); - } -#if PPP_SERVER - if (eap_server_active(pcb)) { - if (pcb->settings.eap_timeout_time > 0) { - UNTIMEOUT(eap_server_timeout, pcb); - } - } else { - if ((pcb->eap.es_server.ea_state == eapOpen || - pcb->eap.es_server.ea_state == eapSRP4) && - pcb->eap.es_rechallenge > 0) { - UNTIMEOUT(eap_rechallenge, (void *)pcb); - } - if (pcb->eap.es_server.ea_state == eapOpen && - pcb->eap.es_lwrechallenge > 0) { - UNTIMEOUT(srp_lwrechallenge, (void *)pcb); - } - } - - pcb->eap.es_client.ea_state = pcb->eap.es_server.ea_state = eapInitial; - pcb->eap.es_client.ea_requests = pcb->eap.es_server.ea_requests = 0; -#endif /* PPP_SERVER */ -} - -/* - * eap_protrej - Peer doesn't speak this protocol. - * - * This shouldn't happen. If it does, it represents authentication - * failure. - */ -static void eap_protrej(ppp_pcb *pcb) { - - if (eap_client_active(pcb)) { - ppp_error("EAP authentication failed due to Protocol-Reject"); - auth_withpeer_fail(pcb, PPP_EAP); - } -#if PPP_SERVER - if (eap_server_active(pcb)) { - ppp_error("EAP authentication of peer failed on Protocol-Reject"); - auth_peer_fail(pcb, PPP_EAP); - } -#endif /* PPP_SERVER */ - eap_lowerdown(pcb); -} - -/* - * Format and send a regular EAP Response message. - */ -static void eap_send_response(ppp_pcb *pcb, u_char id, u_char typenum, const u_char *str, int lenstr) { - struct pbuf *p; - u_char *outp; - int msglen; - - msglen = EAP_HEADERLEN + sizeof (u_char) + lenstr; - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PPP_CTRL_PBUF_TYPE); - if(NULL == p) - return; - if(p->tot_len != p->len) { - pbuf_free(p); - return; - } - - outp = (u_char*)p->payload; - - MAKEHEADER(outp, PPP_EAP); - - PUTCHAR(EAP_RESPONSE, outp); - PUTCHAR(id, outp); - pcb->eap.es_client.ea_id = id; - PUTSHORT(msglen, outp); - PUTCHAR(typenum, outp); - if (lenstr > 0) { - MEMCPY(outp, str, lenstr); - } - - ppp_write(pcb, p); -} - -/* - * Format and send an MD5-Challenge EAP Response message. - */ -static void eap_chap_response(ppp_pcb *pcb, u_char id, u_char *hash, const char *name, int namelen) { - struct pbuf *p; - u_char *outp; - int msglen; - - msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + MD5_SIGNATURE_SIZE + - namelen; - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PPP_CTRL_PBUF_TYPE); - if(NULL == p) - return; - if(p->tot_len != p->len) { - pbuf_free(p); - return; - } - - outp = (u_char*)p->payload; - - MAKEHEADER(outp, PPP_EAP); - - PUTCHAR(EAP_RESPONSE, outp); - PUTCHAR(id, outp); - pcb->eap.es_client.ea_id = id; - PUTSHORT(msglen, outp); - PUTCHAR(EAPT_MD5CHAP, outp); - PUTCHAR(MD5_SIGNATURE_SIZE, outp); - MEMCPY(outp, hash, MD5_SIGNATURE_SIZE); - INCPTR(MD5_SIGNATURE_SIZE, outp); - if (namelen > 0) { - MEMCPY(outp, name, namelen); - } - - ppp_write(pcb, p); -} - -#ifdef USE_SRP -/* - * Format and send a SRP EAP Response message. - */ -static void -eap_srp_response(esp, id, subtypenum, str, lenstr) -eap_state *esp; -u_char id; -u_char subtypenum; -u_char *str; -int lenstr; -{ - ppp_pcb *pcb = &ppp_pcb_list[pcb->eap.es_unit]; - struct pbuf *p; - u_char *outp; - int msglen; - - msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + lenstr; - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PPP_CTRL_PBUF_TYPE); - if(NULL == p) - return; - if(p->tot_len != p->len) { - pbuf_free(p); - return; - } - - outp = p->payload; - - MAKEHEADER(outp, PPP_EAP); - - PUTCHAR(EAP_RESPONSE, outp); - PUTCHAR(id, outp); - pcb->eap.es_client.ea_id = id; - PUTSHORT(msglen, outp); - PUTCHAR(EAPT_SRP, outp); - PUTCHAR(subtypenum, outp); - if (lenstr > 0) { - MEMCPY(outp, str, lenstr); - } - - ppp_write(pcb, p); -} - -/* - * Format and send a SRP EAP Client Validator Response message. - */ -static void -eap_srpval_response(esp, id, flags, str) -eap_state *esp; -u_char id; -u32_t flags; -u_char *str; -{ - ppp_pcb *pcb = &ppp_pcb_list[pcb->eap.es_unit]; - struct pbuf *p; - u_char *outp; - int msglen; - - msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + sizeof (u32_t) + - SHA_DIGESTSIZE; - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PPP_CTRL_PBUF_TYPE); - if(NULL == p) - return; - if(p->tot_len != p->len) { - pbuf_free(p); - return; - } - - outp = p->payload; - - MAKEHEADER(outp, PPP_EAP); - - PUTCHAR(EAP_RESPONSE, outp); - PUTCHAR(id, outp); - pcb->eap.es_client.ea_id = id; - PUTSHORT(msglen, outp); - PUTCHAR(EAPT_SRP, outp); - PUTCHAR(EAPSRP_CVALIDATOR, outp); - PUTLONG(flags, outp); - MEMCPY(outp, str, SHA_DIGESTSIZE); - - ppp_write(pcb, p); -} -#endif /* USE_SRP */ - -static void eap_send_nak(ppp_pcb *pcb, u_char id, u_char type) { - struct pbuf *p; - u_char *outp; - int msglen; - - msglen = EAP_HEADERLEN + 2 * sizeof (u_char); - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PPP_CTRL_PBUF_TYPE); - if(NULL == p) - return; - if(p->tot_len != p->len) { - pbuf_free(p); - return; - } - - outp = (u_char*)p->payload; - - MAKEHEADER(outp, PPP_EAP); - - PUTCHAR(EAP_RESPONSE, outp); - PUTCHAR(id, outp); - pcb->eap.es_client.ea_id = id; - PUTSHORT(msglen, outp); - PUTCHAR(EAPT_NAK, outp); - PUTCHAR(type, outp); - - ppp_write(pcb, p); -} - -#ifdef USE_SRP -static char * -name_of_pn_file() -{ - char *user, *path, *file; - struct passwd *pw; - size_t pl; - static bool pnlogged = 0; - - pw = getpwuid(getuid()); - if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0) { - errno = EINVAL; - return (NULL); - } - file = _PATH_PSEUDONYM; - pl = strlen(user) + strlen(file) + 2; - path = malloc(pl); - if (path == NULL) - return (NULL); - (void) slprintf(path, pl, "%s/%s", user, file); - if (!pnlogged) { - ppp_dbglog("pseudonym file: %s", path); - pnlogged = 1; - } - return (path); -} - -static int -open_pn_file(modebits) -mode_t modebits; -{ - char *path; - int fd, err; - - if ((path = name_of_pn_file()) == NULL) - return (-1); - fd = open(path, modebits, S_IRUSR | S_IWUSR); - err = errno; - free(path); - errno = err; - return (fd); -} - -static void -remove_pn_file() -{ - char *path; - - if ((path = name_of_pn_file()) != NULL) { - (void) unlink(path); - (void) free(path); - } -} - -static void -write_pseudonym(esp, inp, len, id) -eap_state *esp; -u_char *inp; -int len, id; -{ - u_char val; - u_char *datp, *digp; - SHA1_CTX ctxt; - u_char dig[SHA_DIGESTSIZE]; - int dsize, fd, olen = len; - - /* - * Do the decoding by working backwards. This eliminates the need - * to save the decoded output in a separate buffer. - */ - val = id; - while (len > 0) { - if ((dsize = len % SHA_DIGESTSIZE) == 0) - dsize = SHA_DIGESTSIZE; - len -= dsize; - datp = inp + len; - SHA1Init(&ctxt); - SHA1Update(&ctxt, &val, 1); - SHA1Update(&ctxt, pcb->eap.es_client.ea_skey, SESSION_KEY_LEN); - if (len > 0) { - SHA1Update(&ctxt, datp, SHA_DIGESTSIZE); - } else { - SHA1Update(&ctxt, pcb->eap.es_client.ea_name, - pcb->eap.es_client.ea_namelen); - } - SHA1Final(dig, &ctxt); - for (digp = dig; digp < dig + SHA_DIGESTSIZE; digp++) - *datp++ ^= *digp; - } - - /* Now check that the result is sane */ - if (olen <= 0 || *inp + 1 > olen) { - ppp_dbglog("EAP: decoded pseudonym is unusable <%.*B>", olen, inp); - return; - } - - /* Save it away */ - fd = open_pn_file(O_WRONLY | O_CREAT | O_TRUNC); - if (fd < 0) { - ppp_dbglog("EAP: error saving pseudonym: %m"); - return; - } - len = write(fd, inp + 1, *inp); - if (close(fd) != -1 && len == *inp) { - ppp_dbglog("EAP: saved pseudonym"); - pcb->eap.es_usedpseudo = 0; - } else { - ppp_dbglog("EAP: failed to save pseudonym"); - remove_pn_file(); - } -} -#endif /* USE_SRP */ - -/* - * eap_request - Receive EAP Request message (client mode). - */ -static void eap_request(ppp_pcb *pcb, u_char *inp, int id, int len) { - u_char typenum; - u_char vallen; - int secret_len; - char secret[MAXSECRETLEN]; - char rhostname[MAXNAMELEN]; - lwip_md5_context mdContext; - u_char hash[MD5_SIGNATURE_SIZE]; -#ifdef USE_SRP - struct t_client *tc; - struct t_num sval, gval, Nval, *Ap, Bval; - u_char vals[2]; - SHA1_CTX ctxt; - u_char dig[SHA_DIGESTSIZE]; - int fd; -#endif /* USE_SRP */ - - /* - * Note: we update es_client.ea_id *only if* a Response - * message is being generated. Otherwise, we leave it the - * same for duplicate detection purposes. - */ - - pcb->eap.es_client.ea_requests++; - if (pcb->settings.eap_allow_req != 0 && - pcb->eap.es_client.ea_requests > pcb->settings.eap_allow_req) { - ppp_info("EAP: received too many Request messages"); - if (pcb->settings.eap_req_time > 0) { - UNTIMEOUT(eap_client_timeout, pcb); - } - auth_withpeer_fail(pcb, PPP_EAP); - return; - } - - if (len <= 0) { - ppp_error("EAP: empty Request message discarded"); - return; - } - - GETCHAR(typenum, inp); - len--; - - switch (typenum) { - case EAPT_IDENTITY: - if (len > 0) - ppp_info("EAP: Identity prompt \"%.*q\"", len, inp); -#ifdef USE_SRP - if (pcb->eap.es_usepseudo && - (pcb->eap.es_usedpseudo == 0 || - (pcb->eap.es_usedpseudo == 1 && - id == pcb->eap.es_client.ea_id))) { - pcb->eap.es_usedpseudo = 1; - /* Try to get a pseudonym */ - if ((fd = open_pn_file(O_RDONLY)) >= 0) { - strcpy(rhostname, SRP_PSEUDO_ID); - len = read(fd, rhostname + SRP_PSEUDO_LEN, - sizeof (rhostname) - SRP_PSEUDO_LEN); - /* XXX NAI unsupported */ - if (len > 0) { - eap_send_response(pcb, id, typenum, - rhostname, len + SRP_PSEUDO_LEN); - } - (void) close(fd); - if (len > 0) - break; - } - } - /* Stop using pseudonym now. */ - if (pcb->eap.es_usepseudo && pcb->eap.es_usedpseudo != 2) { - remove_pn_file(); - pcb->eap.es_usedpseudo = 2; - } -#endif /* USE_SRP */ - eap_send_response(pcb, id, typenum, (const u_char*)pcb->eap.es_client.ea_name, - pcb->eap.es_client.ea_namelen); - break; - - case EAPT_NOTIFICATION: - if (len > 0) - ppp_info("EAP: Notification \"%.*q\"", len, inp); - eap_send_response(pcb, id, typenum, NULL, 0); - break; - - case EAPT_NAK: - /* - * Avoid the temptation to send Response Nak in reply - * to Request Nak here. It can only lead to trouble. - */ - ppp_warn("EAP: unexpected Nak in Request; ignored"); - /* Return because we're waiting for something real. */ - return; - - case EAPT_MD5CHAP: - if (len < 1) { - ppp_error("EAP: received MD5-Challenge with no data"); - /* Bogus request; wait for something real. */ - return; - } - GETCHAR(vallen, inp); - len--; - if (vallen < 8 || vallen > len) { - ppp_error("EAP: MD5-Challenge with bad length %d (8..%d)", - vallen, len); - /* Try something better. */ - eap_send_nak(pcb, id, EAPT_SRP); - break; - } - - /* Not so likely to happen. */ - if (vallen >= len + sizeof (rhostname)) { - ppp_dbglog("EAP: trimming really long peer name down"); - MEMCPY(rhostname, inp + vallen, sizeof (rhostname) - 1); - rhostname[sizeof (rhostname) - 1] = '\0'; - } else { - MEMCPY(rhostname, inp + vallen, len - vallen); - rhostname[len - vallen] = '\0'; - } - -#if PPP_REMOTENAME - /* In case the remote doesn't give us his name. */ - if (pcb->settings.explicit_remote || - (pcb->settings.remote_name[0] != '\0' && vallen == len)) - strlcpy(rhostname, pcb->settings.remote_name, sizeof (rhostname)); -#endif /* PPP_REMOTENAME */ - - /* - * Get the secret for authenticating ourselves with - * the specified host. - */ - if (!get_secret(pcb, pcb->eap.es_client.ea_name, - rhostname, secret, &secret_len, 0)) { - ppp_dbglog("EAP: no MD5 secret for auth to %q", rhostname); - eap_send_nak(pcb, id, EAPT_SRP); - break; - } - lwip_md5_init(&mdContext); - lwip_md5_starts(&mdContext); - typenum = id; - lwip_md5_update(&mdContext, &typenum, 1); - lwip_md5_update(&mdContext, (u_char *)secret, secret_len); - BZERO(secret, sizeof (secret)); - lwip_md5_update(&mdContext, inp, vallen); - lwip_md5_finish(&mdContext, hash); - lwip_md5_free(&mdContext); - eap_chap_response(pcb, id, hash, pcb->eap.es_client.ea_name, - pcb->eap.es_client.ea_namelen); - break; - -#ifdef USE_SRP - case EAPT_SRP: - if (len < 1) { - ppp_error("EAP: received empty SRP Request"); - /* Bogus request; wait for something real. */ - return; - } - - /* Get subtype */ - GETCHAR(vallen, inp); - len--; - switch (vallen) { - case EAPSRP_CHALLENGE: - tc = NULL; - if (pcb->eap.es_client.ea_session != NULL) { - tc = (struct t_client *)pcb->eap.es_client. - ea_session; - /* - * If this is a new challenge, then start - * over with a new client session context. - * Otherwise, just resend last response. - */ - if (id != pcb->eap.es_client.ea_id) { - t_clientclose(tc); - pcb->eap.es_client.ea_session = NULL; - tc = NULL; - } - } - /* No session key just yet */ - pcb->eap.es_client.ea_skey = NULL; - if (tc == NULL) { - int rhostnamelen; - - GETCHAR(vallen, inp); - len--; - if (vallen >= len) { - ppp_error("EAP: badly-formed SRP Challenge" - " (name)"); - /* Ignore badly-formed messages */ - return; - } - MEMCPY(rhostname, inp, vallen); - rhostname[vallen] = '\0'; - INCPTR(vallen, inp); - len -= vallen; - - /* - * In case the remote doesn't give us his name, - * use configured name. - */ - if (explicit_remote || - (remote_name[0] != '\0' && vallen == 0)) { - strlcpy(rhostname, remote_name, - sizeof (rhostname)); - } - - rhostnamelen = (int)strlen(rhostname); - if (rhostnamelen > MAXNAMELEN) { - rhostnamelen = MAXNAMELEN; - } - MEMCPY(pcb->eap.es_client.ea_peer, rhostname, rhostnamelen); - pcb->eap.es_client.ea_peer[rhostnamelen] = '\0'; - pcb->eap.es_client.ea_peerlen = rhostnamelen; - - GETCHAR(vallen, inp); - len--; - if (vallen >= len) { - ppp_error("EAP: badly-formed SRP Challenge" - " (s)"); - /* Ignore badly-formed messages */ - return; - } - sval.data = inp; - sval.len = vallen; - INCPTR(vallen, inp); - len -= vallen; - - GETCHAR(vallen, inp); - len--; - if (vallen > len) { - ppp_error("EAP: badly-formed SRP Challenge" - " (g)"); - /* Ignore badly-formed messages */ - return; - } - /* If no generator present, then use value 2 */ - if (vallen == 0) { - gval.data = (u_char *)"\002"; - gval.len = 1; - } else { - gval.data = inp; - gval.len = vallen; - } - INCPTR(vallen, inp); - len -= vallen; - - /* - * If no modulus present, then use well-known - * value. - */ - if (len == 0) { - Nval.data = (u_char *)wkmodulus; - Nval.len = sizeof (wkmodulus); - } else { - Nval.data = inp; - Nval.len = len; - } - tc = t_clientopen(pcb->eap.es_client.ea_name, - &Nval, &gval, &sval); - if (tc == NULL) { - eap_send_nak(pcb, id, EAPT_MD5CHAP); - break; - } - pcb->eap.es_client.ea_session = (void *)tc; - - /* Add Challenge ID & type to verifier */ - vals[0] = id; - vals[1] = EAPT_SRP; - t_clientaddexdata(tc, vals, 2); - } - Ap = t_clientgenexp(tc); - eap_srp_response(esp, id, EAPSRP_CKEY, Ap->data, - Ap->len); - break; - - case EAPSRP_SKEY: - tc = (struct t_client *)pcb->eap.es_client.ea_session; - if (tc == NULL) { - ppp_warn("EAP: peer sent Subtype 2 without 1"); - eap_send_nak(pcb, id, EAPT_MD5CHAP); - break; - } - if (pcb->eap.es_client.ea_skey != NULL) { - /* - * ID number should not change here. Warn - * if it does (but otherwise ignore). - */ - if (id != pcb->eap.es_client.ea_id) { - ppp_warn("EAP: ID changed from %d to %d " - "in SRP Subtype 2 rexmit", - pcb->eap.es_client.ea_id, id); - } - } else { - if (get_srp_secret(pcb->eap.es_unit, - pcb->eap.es_client.ea_name, - pcb->eap.es_client.ea_peer, secret, 0) == 0) { - /* - * Can't work with this peer because - * the secret is missing. Just give - * up. - */ - eap_send_nak(pcb, id, EAPT_MD5CHAP); - break; - } - Bval.data = inp; - Bval.len = len; - t_clientpasswd(tc, secret); - BZERO(secret, sizeof (secret)); - pcb->eap.es_client.ea_skey = - t_clientgetkey(tc, &Bval); - if (pcb->eap.es_client.ea_skey == NULL) { - /* Server is rogue; stop now */ - ppp_error("EAP: SRP server is rogue"); - goto client_failure; - } - } - eap_srpval_response(esp, id, SRPVAL_EBIT, - t_clientresponse(tc)); - break; - - case EAPSRP_SVALIDATOR: - tc = (struct t_client *)pcb->eap.es_client.ea_session; - if (tc == NULL || pcb->eap.es_client.ea_skey == NULL) { - ppp_warn("EAP: peer sent Subtype 3 without 1/2"); - eap_send_nak(pcb, id, EAPT_MD5CHAP); - break; - } - /* - * If we're already open, then this ought to be a - * duplicate. Otherwise, check that the server is - * who we think it is. - */ - if (pcb->eap.es_client.ea_state == eapOpen) { - if (id != pcb->eap.es_client.ea_id) { - ppp_warn("EAP: ID changed from %d to %d " - "in SRP Subtype 3 rexmit", - pcb->eap.es_client.ea_id, id); - } - } else { - len -= sizeof (u32_t) + SHA_DIGESTSIZE; - if (len < 0 || t_clientverify(tc, inp + - sizeof (u32_t)) != 0) { - ppp_error("EAP: SRP server verification " - "failed"); - goto client_failure; - } - GETLONG(pcb->eap.es_client.ea_keyflags, inp); - /* Save pseudonym if user wants it. */ - if (len > 0 && pcb->eap.es_usepseudo) { - INCPTR(SHA_DIGESTSIZE, inp); - write_pseudonym(esp, inp, len, id); - } - } - /* - * We've verified our peer. We're now mostly done, - * except for waiting on the regular EAP Success - * message. - */ - eap_srp_response(esp, id, EAPSRP_ACK, NULL, 0); - break; - - case EAPSRP_LWRECHALLENGE: - if (len < 4) { - ppp_warn("EAP: malformed Lightweight rechallenge"); - return; - } - SHA1Init(&ctxt); - vals[0] = id; - SHA1Update(&ctxt, vals, 1); - SHA1Update(&ctxt, pcb->eap.es_client.ea_skey, - SESSION_KEY_LEN); - SHA1Update(&ctxt, inp, len); - SHA1Update(&ctxt, pcb->eap.es_client.ea_name, - pcb->eap.es_client.ea_namelen); - SHA1Final(dig, &ctxt); - eap_srp_response(esp, id, EAPSRP_LWRECHALLENGE, dig, - SHA_DIGESTSIZE); - break; - - default: - ppp_error("EAP: unknown SRP Subtype %d", vallen); - eap_send_nak(pcb, id, EAPT_MD5CHAP); - break; - } - break; -#endif /* USE_SRP */ - - default: - ppp_info("EAP: unknown authentication type %d; Naking", typenum); - eap_send_nak(pcb, id, EAPT_SRP); - break; - } - - if (pcb->settings.eap_req_time > 0) { - UNTIMEOUT(eap_client_timeout, pcb); - TIMEOUT(eap_client_timeout, pcb, - pcb->settings.eap_req_time); - } - return; - -#ifdef USE_SRP -client_failure: - pcb->eap.es_client.ea_state = eapBadAuth; - if (pcb->settings.eap_req_time > 0) { - UNTIMEOUT(eap_client_timeout, (void *)esp); - } - pcb->eap.es_client.ea_session = NULL; - t_clientclose(tc); - auth_withpeer_fail(pcb, PPP_EAP); -#endif /* USE_SRP */ -} - -#if PPP_SERVER -/* - * eap_response - Receive EAP Response message (server mode). - */ -static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { - u_char typenum; - u_char vallen; - int secret_len; - char secret[MAXSECRETLEN]; - char rhostname[MAXNAMELEN]; - lwip_md5_context mdContext; - u_char hash[MD5_SIGNATURE_SIZE]; -#ifdef USE_SRP - struct t_server *ts; - struct t_num A; - SHA1_CTX ctxt; - u_char dig[SHA_DIGESTSIZE]; -#endif /* USE_SRP */ - - if (pcb->eap.es_server.ea_id != id) { - ppp_dbglog("EAP: discarding Response %d; expected ID %d", id, - pcb->eap.es_server.ea_id); - return; - } - - pcb->eap.es_server.ea_responses++; - - if (len <= 0) { - ppp_error("EAP: empty Response message discarded"); - return; - } - - GETCHAR(typenum, inp); - len--; - - switch (typenum) { - case EAPT_IDENTITY: - if (pcb->eap.es_server.ea_state != eapIdentify) { - ppp_dbglog("EAP discarding unwanted Identify \"%.q\"", len, - inp); - break; - } - ppp_info("EAP: unauthenticated peer name \"%.*q\"", len, inp); - if (len > MAXNAMELEN) { - len = MAXNAMELEN; - } - MEMCPY(pcb->eap.es_server.ea_peer, inp, len); - pcb->eap.es_server.ea_peer[len] = '\0'; - pcb->eap.es_server.ea_peerlen = len; - eap_figure_next_state(pcb, 0); - break; - - case EAPT_NOTIFICATION: - ppp_dbglog("EAP unexpected Notification; response discarded"); - break; - - case EAPT_NAK: - if (len < 1) { - ppp_info("EAP: Nak Response with no suggested protocol"); - eap_figure_next_state(pcb, 1); - break; - } - - GETCHAR(vallen, inp); - len--; - - if ( -#if PPP_REMOTENAME - !pcb->explicit_remote && -#endif /* PPP_REMOTENAME */ - pcb->eap.es_server.ea_state == eapIdentify){ - /* Peer cannot Nak Identify Request */ - eap_figure_next_state(pcb, 1); - break; - } - - switch (vallen) { - case EAPT_SRP: - /* Run through SRP validator selection again. */ - pcb->eap.es_server.ea_state = eapIdentify; - eap_figure_next_state(pcb, 0); - break; - - case EAPT_MD5CHAP: - pcb->eap.es_server.ea_state = eapMD5Chall; - break; - - default: - ppp_dbglog("EAP: peer requesting unknown Type %d", vallen); - switch (pcb->eap.es_server.ea_state) { - case eapSRP1: - case eapSRP2: - case eapSRP3: - pcb->eap.es_server.ea_state = eapMD5Chall; - break; - case eapMD5Chall: - case eapSRP4: - pcb->eap.es_server.ea_state = eapIdentify; - eap_figure_next_state(pcb, 0); - break; - default: - break; - } - break; - } - break; - - case EAPT_MD5CHAP: - if (pcb->eap.es_server.ea_state != eapMD5Chall) { - ppp_error("EAP: unexpected MD5-Response"); - eap_figure_next_state(pcb, 1); - break; - } - if (len < 1) { - ppp_error("EAP: received MD5-Response with no data"); - eap_figure_next_state(pcb, 1); - break; - } - GETCHAR(vallen, inp); - len--; - if (vallen != 16 || vallen > len) { - ppp_error("EAP: MD5-Response with bad length %d", vallen); - eap_figure_next_state(pcb, 1); - break; - } - - /* Not so likely to happen. */ - if (vallen >= len + sizeof (rhostname)) { - ppp_dbglog("EAP: trimming really long peer name down"); - MEMCPY(rhostname, inp + vallen, sizeof (rhostname) - 1); - rhostname[sizeof (rhostname) - 1] = '\0'; - } else { - MEMCPY(rhostname, inp + vallen, len - vallen); - rhostname[len - vallen] = '\0'; - } - -#if PPP_REMOTENAME - /* In case the remote doesn't give us his name. */ - if (explicit_remote || - (remote_name[0] != '\0' && vallen == len)) - strlcpy(rhostname, remote_name, sizeof (rhostname)); -#endif /* PPP_REMOTENAME */ - - /* - * Get the secret for authenticating the specified - * host. - */ - if (!get_secret(pcb, rhostname, - pcb->eap.es_server.ea_name, secret, &secret_len, 1)) { - ppp_dbglog("EAP: no MD5 secret for auth of %q", rhostname); - eap_send_failure(pcb); - break; - } - lwip_md5_init(&mdContext); - lwip_md5_starts(&mdContext); - lwip_md5_update(&mdContext, &pcb->eap.es_server.ea_id, 1); - lwip_md5_update(&mdContext, (u_char *)secret, secret_len); - BZERO(secret, sizeof (secret)); - lwip_md5_update(&mdContext, pcb->eap.es_challenge, pcb->eap.es_challen); - lwip_md5_finish(&mdContext, hash); - lwip_md5_free(&mdContext); - if (BCMP(hash, inp, MD5_SIGNATURE_SIZE) != 0) { - eap_send_failure(pcb); - break; - } - pcb->eap.es_server.ea_type = EAPT_MD5CHAP; - eap_send_success(pcb); - eap_figure_next_state(pcb, 0); - if (pcb->eap.es_rechallenge != 0) - TIMEOUT(eap_rechallenge, pcb, pcb->eap.es_rechallenge); - break; - -#ifdef USE_SRP - case EAPT_SRP: - if (len < 1) { - ppp_error("EAP: empty SRP Response"); - eap_figure_next_state(pcb, 1); - break; - } - GETCHAR(typenum, inp); - len--; - switch (typenum) { - case EAPSRP_CKEY: - if (pcb->eap.es_server.ea_state != eapSRP1) { - ppp_error("EAP: unexpected SRP Subtype 1 Response"); - eap_figure_next_state(pcb, 1); - break; - } - A.data = inp; - A.len = len; - ts = (struct t_server *)pcb->eap.es_server.ea_session; - assert(ts != NULL); - pcb->eap.es_server.ea_skey = t_servergetkey(ts, &A); - if (pcb->eap.es_server.ea_skey == NULL) { - /* Client's A value is bogus; terminate now */ - ppp_error("EAP: bogus A value from client"); - eap_send_failure(pcb); - } else { - eap_figure_next_state(pcb, 0); - } - break; - - case EAPSRP_CVALIDATOR: - if (pcb->eap.es_server.ea_state != eapSRP2) { - ppp_error("EAP: unexpected SRP Subtype 2 Response"); - eap_figure_next_state(pcb, 1); - break; - } - if (len < sizeof (u32_t) + SHA_DIGESTSIZE) { - ppp_error("EAP: M1 length %d < %d", len, - sizeof (u32_t) + SHA_DIGESTSIZE); - eap_figure_next_state(pcb, 1); - break; - } - GETLONG(pcb->eap.es_server.ea_keyflags, inp); - ts = (struct t_server *)pcb->eap.es_server.ea_session; - assert(ts != NULL); - if (t_serververify(ts, inp)) { - ppp_info("EAP: unable to validate client identity"); - eap_send_failure(pcb); - break; - } - eap_figure_next_state(pcb, 0); - break; - - case EAPSRP_ACK: - if (pcb->eap.es_server.ea_state != eapSRP3) { - ppp_error("EAP: unexpected SRP Subtype 3 Response"); - eap_send_failure(esp); - break; - } - pcb->eap.es_server.ea_type = EAPT_SRP; - eap_send_success(pcb, esp); - eap_figure_next_state(pcb, 0); - if (pcb->eap.es_rechallenge != 0) - TIMEOUT(eap_rechallenge, pcb, - pcb->eap.es_rechallenge); - if (pcb->eap.es_lwrechallenge != 0) - TIMEOUT(srp_lwrechallenge, pcb, - pcb->eap.es_lwrechallenge); - break; - - case EAPSRP_LWRECHALLENGE: - if (pcb->eap.es_server.ea_state != eapSRP4) { - ppp_info("EAP: unexpected SRP Subtype 4 Response"); - return; - } - if (len != SHA_DIGESTSIZE) { - ppp_error("EAP: bad Lightweight rechallenge " - "response"); - return; - } - SHA1Init(&ctxt); - vallen = id; - SHA1Update(&ctxt, &vallen, 1); - SHA1Update(&ctxt, pcb->eap.es_server.ea_skey, - SESSION_KEY_LEN); - SHA1Update(&ctxt, pcb->eap.es_challenge, pcb->eap.es_challen); - SHA1Update(&ctxt, pcb->eap.es_server.ea_peer, - pcb->eap.es_server.ea_peerlen); - SHA1Final(dig, &ctxt); - if (BCMP(dig, inp, SHA_DIGESTSIZE) != 0) { - ppp_error("EAP: failed Lightweight rechallenge"); - eap_send_failure(pcb); - break; - } - pcb->eap.es_server.ea_state = eapOpen; - if (pcb->eap.es_lwrechallenge != 0) - TIMEOUT(srp_lwrechallenge, esp, - pcb->eap.es_lwrechallenge); - break; - } - break; -#endif /* USE_SRP */ - - default: - /* This can't happen. */ - ppp_error("EAP: unknown Response type %d; ignored", typenum); - return; - } - - if (pcb->settings.eap_timeout_time > 0) { - UNTIMEOUT(eap_server_timeout, pcb); - } - - if (pcb->eap.es_server.ea_state != eapBadAuth && - pcb->eap.es_server.ea_state != eapOpen) { - pcb->eap.es_server.ea_id++; - eap_send_request(pcb); - } -} -#endif /* PPP_SERVER */ - -/* - * eap_success - Receive EAP Success message (client mode). - */ -static void eap_success(ppp_pcb *pcb, u_char *inp, int id, int len) { - LWIP_UNUSED_ARG(id); - - if (pcb->eap.es_client.ea_state != eapOpen && !eap_client_active(pcb)) { - ppp_dbglog("EAP unexpected success message in state %s (%d)", - eap_state_name(pcb->eap.es_client.ea_state), - pcb->eap.es_client.ea_state); - return; - } - - if (pcb->settings.eap_req_time > 0) { - UNTIMEOUT(eap_client_timeout, pcb); - } - - if (len > 0) { - /* This is odd. The spec doesn't allow for this. */ - PRINTMSG(inp, len); - } - - pcb->eap.es_client.ea_state = eapOpen; - auth_withpeer_success(pcb, PPP_EAP, 0); -} - -/* - * eap_failure - Receive EAP Failure message (client mode). - */ -static void eap_failure(ppp_pcb *pcb, u_char *inp, int id, int len) { - LWIP_UNUSED_ARG(id); - - if (!eap_client_active(pcb)) { - ppp_dbglog("EAP unexpected failure message in state %s (%d)", - eap_state_name(pcb->eap.es_client.ea_state), - pcb->eap.es_client.ea_state); - } - - if (pcb->settings.eap_req_time > 0) { - UNTIMEOUT(eap_client_timeout, pcb); - } - - if (len > 0) { - /* This is odd. The spec doesn't allow for this. */ - PRINTMSG(inp, len); - } - - pcb->eap.es_client.ea_state = eapBadAuth; - - ppp_error("EAP: peer reports authentication failure"); - auth_withpeer_fail(pcb, PPP_EAP); -} - -/* - * eap_input - Handle received EAP message. - */ -static void eap_input(ppp_pcb *pcb, u_char *inp, int inlen) { - u_char code, id; - int len; - - /* - * Parse header (code, id and length). If packet too short, - * drop it. - */ - if (inlen < EAP_HEADERLEN) { - ppp_error("EAP: packet too short: %d < %d", inlen, EAP_HEADERLEN); - return; - } - GETCHAR(code, inp); - GETCHAR(id, inp); - GETSHORT(len, inp); - if (len < EAP_HEADERLEN || len > inlen) { - ppp_error("EAP: packet has illegal length field %d (%d..%d)", len, - EAP_HEADERLEN, inlen); - return; - } - len -= EAP_HEADERLEN; - - /* Dispatch based on message code */ - switch (code) { - case EAP_REQUEST: - eap_request(pcb, inp, id, len); - break; - -#if PPP_SERVER - case EAP_RESPONSE: - eap_response(pcb, inp, id, len); - break; -#endif /* PPP_SERVER */ - - case EAP_SUCCESS: - eap_success(pcb, inp, id, len); - break; - - case EAP_FAILURE: - eap_failure(pcb, inp, id, len); - break; - - default: /* XXX Need code reject */ - /* Note: it's not legal to send EAP Nak here. */ - ppp_warn("EAP: unknown code %d received", code); - break; - } -} - -#if PRINTPKT_SUPPORT -/* - * eap_printpkt - print the contents of an EAP packet. - */ -static const char* const eap_codenames[] = { - "Request", "Response", "Success", "Failure" -}; - -static const char* const eap_typenames[] = { - "Identity", "Notification", "Nak", "MD5-Challenge", - "OTP", "Generic-Token", NULL, NULL, - "RSA", "DSS", "KEA", "KEA-Validate", - "TLS", "Defender", "Windows 2000", "Arcot", - "Cisco", "Nokia", "SRP" -}; - -static int eap_printpkt(const u_char *inp, int inlen, void (*printer) (void *, const char *, ...), void *arg) { - int code, id, len, rtype, vallen; - const u_char *pstart; - u32_t uval; - - if (inlen < EAP_HEADERLEN) - return (0); - pstart = inp; - GETCHAR(code, inp); - GETCHAR(id, inp); - GETSHORT(len, inp); - if (len < EAP_HEADERLEN || len > inlen) - return (0); - - if (code >= 1 && code <= (int)LWIP_ARRAYSIZE(eap_codenames)) - printer(arg, " %s", eap_codenames[code-1]); - else - printer(arg, " code=0x%x", code); - printer(arg, " id=0x%x", id); - len -= EAP_HEADERLEN; - switch (code) { - case EAP_REQUEST: - if (len < 1) { - printer(arg, " "); - break; - } - GETCHAR(rtype, inp); - len--; - if (rtype >= 1 && rtype <= (int)LWIP_ARRAYSIZE(eap_typenames)) - printer(arg, " %s", eap_typenames[rtype-1]); - else - printer(arg, " type=0x%x", rtype); - switch (rtype) { - case EAPT_IDENTITY: - case EAPT_NOTIFICATION: - if (len > 0) { - printer(arg, " "); - INCPTR(len, inp); - len = 0; - } else { - printer(arg, " "); - } - break; - - case EAPT_MD5CHAP: - if (len <= 0) - break; - GETCHAR(vallen, inp); - len--; - if (vallen > len) - goto truncated; - printer(arg, " ", vallen, inp); - INCPTR(vallen, inp); - len -= vallen; - if (len > 0) { - printer(arg, " "); - INCPTR(len, inp); - len = 0; - } else { - printer(arg, " "); - } - break; - - case EAPT_SRP: - if (len < 3) - goto truncated; - GETCHAR(vallen, inp); - len--; - printer(arg, "-%d", vallen); - switch (vallen) { - case EAPSRP_CHALLENGE: - GETCHAR(vallen, inp); - len--; - if (vallen >= len) - goto truncated; - if (vallen > 0) { - printer(arg, " "); - } else { - printer(arg, " "); - } - INCPTR(vallen, inp); - len -= vallen; - GETCHAR(vallen, inp); - len--; - if (vallen >= len) - goto truncated; - printer(arg, " ", vallen, inp); - INCPTR(vallen, inp); - len -= vallen; - GETCHAR(vallen, inp); - len--; - if (vallen > len) - goto truncated; - if (vallen == 0) { - printer(arg, " "); - } else { - printer(arg, " ", vallen, inp); - } - INCPTR(vallen, inp); - len -= vallen; - if (len == 0) { - printer(arg, " "); - } else { - printer(arg, " ", len, inp); - INCPTR(len, inp); - len = 0; - } - break; - - case EAPSRP_SKEY: - printer(arg, " ", len, inp); - INCPTR(len, inp); - len = 0; - break; - - case EAPSRP_SVALIDATOR: - if (len < (int)sizeof (u32_t)) - break; - GETLONG(uval, inp); - len -= sizeof (u32_t); - if (uval & SRPVAL_EBIT) { - printer(arg, " E"); - uval &= ~SRPVAL_EBIT; - } - if (uval != 0) { - printer(arg, " f<%X>", uval); - } - if ((vallen = len) > SHA_DIGESTSIZE) - vallen = SHA_DIGESTSIZE; - printer(arg, " ", len, inp, - len < SHA_DIGESTSIZE ? "?" : ""); - INCPTR(vallen, inp); - len -= vallen; - if (len > 0) { - printer(arg, " ", len, inp); - INCPTR(len, inp); - len = 0; - } - break; - - case EAPSRP_LWRECHALLENGE: - printer(arg, " ", len, inp); - INCPTR(len, inp); - len = 0; - break; - default: - break; - } - break; - default: - break; - } - break; - - case EAP_RESPONSE: - if (len < 1) - break; - GETCHAR(rtype, inp); - len--; - if (rtype >= 1 && rtype <= (int)LWIP_ARRAYSIZE(eap_typenames)) - printer(arg, " %s", eap_typenames[rtype-1]); - else - printer(arg, " type=0x%x", rtype); - switch (rtype) { - case EAPT_IDENTITY: - if (len > 0) { - printer(arg, " "); - INCPTR(len, inp); - len = 0; - } - break; - - case EAPT_NAK: - if (len <= 0) { - printer(arg, " "); - break; - } - GETCHAR(rtype, inp); - len--; - printer(arg, " = 1 && rtype < (int)LWIP_ARRAYSIZE(eap_typenames)) - printer(arg, " (%s)", eap_typenames[rtype-1]); - printer(arg, ">"); - break; - - case EAPT_MD5CHAP: - if (len <= 0) { - printer(arg, " "); - break; - } - GETCHAR(vallen, inp); - len--; - if (vallen > len) - goto truncated; - printer(arg, " ", vallen, inp); - INCPTR(vallen, inp); - len -= vallen; - if (len > 0) { - printer(arg, " "); - INCPTR(len, inp); - len = 0; - } else { - printer(arg, " "); - } - break; - - case EAPT_SRP: - if (len < 1) - goto truncated; - GETCHAR(vallen, inp); - len--; - printer(arg, "-%d", vallen); - switch (vallen) { - case EAPSRP_CKEY: - printer(arg, " ", len, inp); - INCPTR(len, inp); - len = 0; - break; - - case EAPSRP_CVALIDATOR: - if (len < (int)sizeof (u32_t)) - break; - GETLONG(uval, inp); - len -= sizeof (u32_t); - if (uval & SRPVAL_EBIT) { - printer(arg, " E"); - uval &= ~SRPVAL_EBIT; - } - if (uval != 0) { - printer(arg, " f<%X>", uval); - } - printer(arg, " ", len, inp, - len == SHA_DIGESTSIZE ? "" : "?"); - INCPTR(len, inp); - len = 0; - break; - - case EAPSRP_ACK: - break; - - case EAPSRP_LWRECHALLENGE: - printer(arg, " ", len, inp, - len == SHA_DIGESTSIZE ? "" : "?"); - if ((vallen = len) > SHA_DIGESTSIZE) - vallen = SHA_DIGESTSIZE; - INCPTR(vallen, inp); - len -= vallen; - break; - default: - break; - } - break; - default: - break; - } - break; - - case EAP_SUCCESS: /* No payload expected for these! */ - case EAP_FAILURE: - default: - break; - - truncated: - printer(arg, " "); - break; - } - - if (len > 8) - printer(arg, "%8B...", inp); - else if (len > 0) - printer(arg, "%.*B", len, inp); - INCPTR(len, inp); - - return (inp - pstart); -} -#endif /* PRINTPKT_SUPPORT */ - -#endif /* PPP_SUPPORT && EAP_SUPPORT */ diff --git a/third-party/lwip-2.1.2/netif/ppp/ecp.c b/third-party/lwip-2.1.2/netif/ppp/ecp.c deleted file mode 100644 index 4d84f609..00000000 --- a/third-party/lwip-2.1.2/netif/ppp/ecp.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * ecp.c - PPP Encryption Control Protocol. - * - * Copyright (c) 2002 Google, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Derived from ccp.c, which is: - * - * Copyright (c) 1994-2002 Paul Mackerras. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 3. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && ECP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include - -#include "netif/ppp/ppp_impl.h" - -#include "netif/ppp/fsm.h" -#include "netif/ppp/ecp.h" - -#if PPP_OPTIONS -static option_t ecp_option_list[] = { - { "noecp", o_bool, &ecp_protent.enabled_flag, - "Disable ECP negotiation" }, - { "-ecp", o_bool, &ecp_protent.enabled_flag, - "Disable ECP negotiation", OPT_ALIAS }, - - { NULL } -}; -#endif /* PPP_OPTIONS */ - -/* - * Protocol entry points from main code. - */ -static void ecp_init (int unit); -/* -static void ecp_open (int unit); -static void ecp_close (int unit, char *); -static void ecp_lowerup (int unit); -static void ecp_lowerdown (int); -static void ecp_input (int unit, u_char *pkt, int len); -static void ecp_protrej (int unit); -*/ -#if PRINTPKT_SUPPORT -static int ecp_printpkt (const u_char *pkt, int len, - void (*printer) (void *, char *, ...), - void *arg); -#endif /* PRINTPKT_SUPPORT */ -/* -static void ecp_datainput (int unit, u_char *pkt, int len); -*/ - -const struct protent ecp_protent = { - PPP_ECP, - ecp_init, - NULL, /* ecp_input, */ - NULL, /* ecp_protrej, */ - NULL, /* ecp_lowerup, */ - NULL, /* ecp_lowerdown, */ - NULL, /* ecp_open, */ - NULL, /* ecp_close, */ -#if PRINTPKT_SUPPORT - ecp_printpkt, -#endif /* PRINTPKT_SUPPORT */ -#if PPP_DATAINPUT - NULL, /* ecp_datainput, */ -#endif /* PPP_DATAINPUT */ -#if PRINTPKT_SUPPORT - "ECP", - "Encrypted", -#endif /* PRINTPKT_SUPPORT */ -#if PPP_OPTIONS - ecp_option_list, - NULL, -#endif /* PPP_OPTIONS */ -#if DEMAND_SUPPORT - NULL, - NULL -#endif /* DEMAND_SUPPORT */ -}; - -fsm ecp_fsm[NUM_PPP]; -ecp_options ecp_wantoptions[NUM_PPP]; /* what to request the peer to use */ -ecp_options ecp_gotoptions[NUM_PPP]; /* what the peer agreed to do */ -ecp_options ecp_allowoptions[NUM_PPP]; /* what we'll agree to do */ -ecp_options ecp_hisoptions[NUM_PPP]; /* what we agreed to do */ - -static const fsm_callbacks ecp_callbacks = { - NULL, /* ecp_resetci, */ - NULL, /* ecp_cilen, */ - NULL, /* ecp_addci, */ - NULL, /* ecp_ackci, */ - NULL, /* ecp_nakci, */ - NULL, /* ecp_rejci, */ - NULL, /* ecp_reqci, */ - NULL, /* ecp_up, */ - NULL, /* ecp_down, */ - NULL, - NULL, - NULL, - NULL, - NULL, /* ecp_extcode, */ - "ECP" -}; - -/* - * ecp_init - initialize ECP. - */ -static void -ecp_init(unit) - int unit; -{ - fsm *f = &ecp_fsm[unit]; - - f->unit = unit; - f->protocol = PPP_ECP; - f->callbacks = &ecp_callbacks; - fsm_init(f); - -#if 0 /* Not necessary, everything is cleared in ppp_new() */ - memset(&ecp_wantoptions[unit], 0, sizeof(ecp_options)); - memset(&ecp_gotoptions[unit], 0, sizeof(ecp_options)); - memset(&ecp_allowoptions[unit], 0, sizeof(ecp_options)); - memset(&ecp_hisoptions[unit], 0, sizeof(ecp_options)); -#endif /* 0 */ - -} - - -#if PRINTPKT_SUPPORT -static int -ecp_printpkt(p, plen, printer, arg) - const u_char *p; - int plen; - void (*printer) (void *, char *, ...); - void *arg; -{ - return 0; -} -#endif /* PRINTPKT_SUPPORT */ - -#endif /* PPP_SUPPORT && ECP_SUPPORT */ diff --git a/third-party/lwip-2.1.2/netif/ppp/eui64.c b/third-party/lwip-2.1.2/netif/ppp/eui64.c deleted file mode 100644 index 01493bc1..00000000 --- a/third-party/lwip-2.1.2/netif/ppp/eui64.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * eui64.c - EUI64 routines for IPv6CP. - * - * Copyright (c) 1999 Tommi Komulainen. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Tommi Komulainen - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * $Id: eui64.c,v 1.6 2002/12/04 23:03:32 paulus Exp $ - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && PPP_IPV6_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include "netif/ppp/ppp_impl.h" -#include "netif/ppp/eui64.h" - -/* - * eui64_ntoa - Make an ascii representation of an interface identifier - */ -char *eui64_ntoa(eui64_t e) { - static char buf[20]; - - sprintf(buf, "%02x%02x:%02x%02x:%02x%02x:%02x%02x", - e.e8[0], e.e8[1], e.e8[2], e.e8[3], - e.e8[4], e.e8[5], e.e8[6], e.e8[7]); - return buf; -} - -#endif /* PPP_SUPPORT && PPP_IPV6_SUPPORT */ diff --git a/third-party/lwip-2.1.2/netif/ppp/fsm.c b/third-party/lwip-2.1.2/netif/ppp/fsm.c deleted file mode 100644 index b1f08aff..00000000 --- a/third-party/lwip-2.1.2/netif/ppp/fsm.c +++ /dev/null @@ -1,799 +0,0 @@ -/* - * fsm.c - {Link, IP} Control Protocol Finite State Machine. - * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -/* - * @todo: - * Randomize fsm id on link/init. - * Deal with variable outgoing MTU. - */ - -#if 0 /* UNUSED */ -#include -#include -#include -#endif /* UNUSED */ - -#include "netif/ppp/ppp_impl.h" - -#include "netif/ppp/fsm.h" - -static void fsm_timeout (void *); -static void fsm_rconfreq(fsm *f, u_char id, u_char *inp, int len); -static void fsm_rconfack(fsm *f, int id, u_char *inp, int len); -static void fsm_rconfnakrej(fsm *f, int code, int id, u_char *inp, int len); -static void fsm_rtermreq(fsm *f, int id, u_char *p, int len); -static void fsm_rtermack(fsm *f); -static void fsm_rcoderej(fsm *f, u_char *inp, int len); -static void fsm_sconfreq(fsm *f, int retransmit); - -#define PROTO_NAME(f) ((f)->callbacks->proto_name) - -/* - * fsm_init - Initialize fsm. - * - * Initialize fsm state. - */ -void fsm_init(fsm *f) { - ppp_pcb *pcb = f->pcb; - f->state = PPP_FSM_INITIAL; - f->flags = 0; - f->id = 0; /* XXX Start with random id? */ - f->maxnakloops = pcb->settings.fsm_max_nak_loops; - f->term_reason_len = 0; -} - - -/* - * fsm_lowerup - The lower layer is up. - */ -void fsm_lowerup(fsm *f) { - switch( f->state ){ - case PPP_FSM_INITIAL: - f->state = PPP_FSM_CLOSED; - break; - - case PPP_FSM_STARTING: - if( f->flags & OPT_SILENT ) - f->state = PPP_FSM_STOPPED; - else { - /* Send an initial configure-request */ - fsm_sconfreq(f, 0); - f->state = PPP_FSM_REQSENT; - } - break; - - default: - FSMDEBUG(("%s: Up event in state %d!", PROTO_NAME(f), f->state)); - /* no break */ - } -} - - -/* - * fsm_lowerdown - The lower layer is down. - * - * Cancel all timeouts and inform upper layers. - */ -void fsm_lowerdown(fsm *f) { - switch( f->state ){ - case PPP_FSM_CLOSED: - f->state = PPP_FSM_INITIAL; - break; - - case PPP_FSM_STOPPED: - f->state = PPP_FSM_STARTING; - if( f->callbacks->starting ) - (*f->callbacks->starting)(f); - break; - - case PPP_FSM_CLOSING: - f->state = PPP_FSM_INITIAL; - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - break; - - case PPP_FSM_STOPPING: - case PPP_FSM_REQSENT: - case PPP_FSM_ACKRCVD: - case PPP_FSM_ACKSENT: - f->state = PPP_FSM_STARTING; - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - break; - - case PPP_FSM_OPENED: - if( f->callbacks->down ) - (*f->callbacks->down)(f); - f->state = PPP_FSM_STARTING; - break; - - default: - FSMDEBUG(("%s: Down event in state %d!", PROTO_NAME(f), f->state)); - /* no break */ - } -} - - -/* - * fsm_open - Link is allowed to come up. - */ -void fsm_open(fsm *f) { - switch( f->state ){ - case PPP_FSM_INITIAL: - f->state = PPP_FSM_STARTING; - if( f->callbacks->starting ) - (*f->callbacks->starting)(f); - break; - - case PPP_FSM_CLOSED: - if( f->flags & OPT_SILENT ) - f->state = PPP_FSM_STOPPED; - else { - /* Send an initial configure-request */ - fsm_sconfreq(f, 0); - f->state = PPP_FSM_REQSENT; - } - break; - - case PPP_FSM_CLOSING: - f->state = PPP_FSM_STOPPING; - /* fall through */ - /* no break */ - case PPP_FSM_STOPPED: - case PPP_FSM_OPENED: - if( f->flags & OPT_RESTART ){ - fsm_lowerdown(f); - fsm_lowerup(f); - } - break; - default: - break; - } -} - -/* - * terminate_layer - Start process of shutting down the FSM - * - * Cancel any timeout running, notify upper layers we're done, and - * send a terminate-request message as configured. - */ -static void terminate_layer(fsm *f, int nextstate) { - ppp_pcb *pcb = f->pcb; - - if( f->state != PPP_FSM_OPENED ) - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - else if( f->callbacks->down ) - (*f->callbacks->down)(f); /* Inform upper layers we're down */ - - /* Init restart counter and send Terminate-Request */ - f->retransmits = pcb->settings.fsm_max_term_transmits; - fsm_sdata(f, TERMREQ, f->reqid = ++f->id, - (const u_char *) f->term_reason, f->term_reason_len); - - if (f->retransmits == 0) { - /* - * User asked for no terminate requests at all; just close it. - * We've already fired off one Terminate-Request just to be nice - * to the peer, but we're not going to wait for a reply. - */ - f->state = nextstate == PPP_FSM_CLOSING ? PPP_FSM_CLOSED : PPP_FSM_STOPPED; - if( f->callbacks->finished ) - (*f->callbacks->finished)(f); - return; - } - - TIMEOUT(fsm_timeout, f, pcb->settings.fsm_timeout_time); - --f->retransmits; - - f->state = nextstate; -} - -/* - * fsm_close - Start closing connection. - * - * Cancel timeouts and either initiate close or possibly go directly to - * the PPP_FSM_CLOSED state. - */ -void fsm_close(fsm *f, const char *reason) { - f->term_reason = reason; - f->term_reason_len = (reason == NULL? 0: (u8_t)LWIP_MIN(strlen(reason), 0xFF) ); - switch( f->state ){ - case PPP_FSM_STARTING: - f->state = PPP_FSM_INITIAL; - break; - case PPP_FSM_STOPPED: - f->state = PPP_FSM_CLOSED; - break; - case PPP_FSM_STOPPING: - f->state = PPP_FSM_CLOSING; - break; - - case PPP_FSM_REQSENT: - case PPP_FSM_ACKRCVD: - case PPP_FSM_ACKSENT: - case PPP_FSM_OPENED: - terminate_layer(f, PPP_FSM_CLOSING); - break; - default: - break; - } -} - - -/* - * fsm_timeout - Timeout expired. - */ -static void fsm_timeout(void *arg) { - fsm *f = (fsm *) arg; - ppp_pcb *pcb = f->pcb; - - switch (f->state) { - case PPP_FSM_CLOSING: - case PPP_FSM_STOPPING: - if( f->retransmits <= 0 ){ - /* - * We've waited for an ack long enough. Peer probably heard us. - */ - f->state = (f->state == PPP_FSM_CLOSING)? PPP_FSM_CLOSED: PPP_FSM_STOPPED; - if( f->callbacks->finished ) - (*f->callbacks->finished)(f); - } else { - /* Send Terminate-Request */ - fsm_sdata(f, TERMREQ, f->reqid = ++f->id, - (const u_char *) f->term_reason, f->term_reason_len); - TIMEOUT(fsm_timeout, f, pcb->settings.fsm_timeout_time); - --f->retransmits; - } - break; - - case PPP_FSM_REQSENT: - case PPP_FSM_ACKRCVD: - case PPP_FSM_ACKSENT: - if (f->retransmits <= 0) { - ppp_warn("%s: timeout sending Config-Requests", PROTO_NAME(f)); - f->state = PPP_FSM_STOPPED; - if( (f->flags & OPT_PASSIVE) == 0 && f->callbacks->finished ) - (*f->callbacks->finished)(f); - - } else { - /* Retransmit the configure-request */ - if (f->callbacks->retransmit) - (*f->callbacks->retransmit)(f); - fsm_sconfreq(f, 1); /* Re-send Configure-Request */ - if( f->state == PPP_FSM_ACKRCVD ) - f->state = PPP_FSM_REQSENT; - } - break; - - default: - FSMDEBUG(("%s: Timeout event in state %d!", PROTO_NAME(f), f->state)); - /* no break */ - } -} - - -/* - * fsm_input - Input packet. - */ -void fsm_input(fsm *f, u_char *inpacket, int l) { - u_char *inp; - u_char code, id; - int len; - - /* - * Parse header (code, id and length). - * If packet too short, drop it. - */ - inp = inpacket; - if (l < HEADERLEN) { - FSMDEBUG(("fsm_input(%x): Rcvd short header.", f->protocol)); - return; - } - GETCHAR(code, inp); - GETCHAR(id, inp); - GETSHORT(len, inp); - if (len < HEADERLEN) { - FSMDEBUG(("fsm_input(%x): Rcvd illegal length.", f->protocol)); - return; - } - if (len > l) { - FSMDEBUG(("fsm_input(%x): Rcvd short packet.", f->protocol)); - return; - } - len -= HEADERLEN; /* subtract header length */ - - if( f->state == PPP_FSM_INITIAL || f->state == PPP_FSM_STARTING ){ - FSMDEBUG(("fsm_input(%x): Rcvd packet in state %d.", - f->protocol, f->state)); - return; - } - - /* - * Action depends on code. - */ - switch (code) { - case CONFREQ: - fsm_rconfreq(f, id, inp, len); - break; - - case CONFACK: - fsm_rconfack(f, id, inp, len); - break; - - case CONFNAK: - case CONFREJ: - fsm_rconfnakrej(f, code, id, inp, len); - break; - - case TERMREQ: - fsm_rtermreq(f, id, inp, len); - break; - - case TERMACK: - fsm_rtermack(f); - break; - - case CODEREJ: - fsm_rcoderej(f, inp, len); - break; - - default: - if( !f->callbacks->extcode - || !(*f->callbacks->extcode)(f, code, id, inp, len) ) - fsm_sdata(f, CODEREJ, ++f->id, inpacket, len + HEADERLEN); - break; - } -} - - -/* - * fsm_rconfreq - Receive Configure-Request. - */ -static void fsm_rconfreq(fsm *f, u_char id, u_char *inp, int len) { - int code, reject_if_disagree; - - switch( f->state ){ - case PPP_FSM_CLOSED: - /* Go away, we're closed */ - fsm_sdata(f, TERMACK, id, NULL, 0); - return; - case PPP_FSM_CLOSING: - case PPP_FSM_STOPPING: - return; - - case PPP_FSM_OPENED: - /* Go down and restart negotiation */ - if( f->callbacks->down ) - (*f->callbacks->down)(f); /* Inform upper layers */ - fsm_sconfreq(f, 0); /* Send initial Configure-Request */ - f->state = PPP_FSM_REQSENT; - break; - - case PPP_FSM_STOPPED: - /* Negotiation started by our peer */ - fsm_sconfreq(f, 0); /* Send initial Configure-Request */ - f->state = PPP_FSM_REQSENT; - break; - default: - break; - } - - /* - * Pass the requested configuration options - * to protocol-specific code for checking. - */ - if (f->callbacks->reqci){ /* Check CI */ - reject_if_disagree = (f->nakloops >= f->maxnakloops); - code = (*f->callbacks->reqci)(f, inp, &len, reject_if_disagree); - } else if (len) - code = CONFREJ; /* Reject all CI */ - else - code = CONFACK; - - /* send the Ack, Nak or Rej to the peer */ - fsm_sdata(f, code, id, inp, len); - - if (code == CONFACK) { - if (f->state == PPP_FSM_ACKRCVD) { - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - f->state = PPP_FSM_OPENED; - if (f->callbacks->up) - (*f->callbacks->up)(f); /* Inform upper layers */ - } else - f->state = PPP_FSM_ACKSENT; - f->nakloops = 0; - - } else { - /* we sent CONFACK or CONFREJ */ - if (f->state != PPP_FSM_ACKRCVD) - f->state = PPP_FSM_REQSENT; - if( code == CONFNAK ) - ++f->nakloops; - } -} - - -/* - * fsm_rconfack - Receive Configure-Ack. - */ -static void fsm_rconfack(fsm *f, int id, u_char *inp, int len) { - ppp_pcb *pcb = f->pcb; - - if (id != f->reqid || f->seen_ack) /* Expected id? */ - return; /* Nope, toss... */ - if( !(f->callbacks->ackci? (*f->callbacks->ackci)(f, inp, len): - (len == 0)) ){ - /* Ack is bad - ignore it */ - ppp_error("Received bad configure-ack: %P", inp, len); - return; - } - f->seen_ack = 1; - f->rnakloops = 0; - - switch (f->state) { - case PPP_FSM_CLOSED: - case PPP_FSM_STOPPED: - fsm_sdata(f, TERMACK, id, NULL, 0); - break; - - case PPP_FSM_REQSENT: - f->state = PPP_FSM_ACKRCVD; - f->retransmits = pcb->settings.fsm_max_conf_req_transmits; - break; - - case PPP_FSM_ACKRCVD: - /* Huh? an extra valid Ack? oh well... */ - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - fsm_sconfreq(f, 0); - f->state = PPP_FSM_REQSENT; - break; - - case PPP_FSM_ACKSENT: - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - f->state = PPP_FSM_OPENED; - f->retransmits = pcb->settings.fsm_max_conf_req_transmits; - if (f->callbacks->up) - (*f->callbacks->up)(f); /* Inform upper layers */ - break; - - case PPP_FSM_OPENED: - /* Go down and restart negotiation */ - if (f->callbacks->down) - (*f->callbacks->down)(f); /* Inform upper layers */ - fsm_sconfreq(f, 0); /* Send initial Configure-Request */ - f->state = PPP_FSM_REQSENT; - break; - default: - break; - } -} - - -/* - * fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject. - */ -static void fsm_rconfnakrej(fsm *f, int code, int id, u_char *inp, int len) { - int ret; - int treat_as_reject; - - if (id != f->reqid || f->seen_ack) /* Expected id? */ - return; /* Nope, toss... */ - - if (code == CONFNAK) { - ++f->rnakloops; - treat_as_reject = (f->rnakloops >= f->maxnakloops); - if (f->callbacks->nakci == NULL - || !(ret = f->callbacks->nakci(f, inp, len, treat_as_reject))) { - ppp_error("Received bad configure-nak: %P", inp, len); - return; - } - } else { - f->rnakloops = 0; - if (f->callbacks->rejci == NULL - || !(ret = f->callbacks->rejci(f, inp, len))) { - ppp_error("Received bad configure-rej: %P", inp, len); - return; - } - } - - f->seen_ack = 1; - - switch (f->state) { - case PPP_FSM_CLOSED: - case PPP_FSM_STOPPED: - fsm_sdata(f, TERMACK, id, NULL, 0); - break; - - case PPP_FSM_REQSENT: - case PPP_FSM_ACKSENT: - /* They didn't agree to what we wanted - try another request */ - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - if (ret < 0) - f->state = PPP_FSM_STOPPED; /* kludge for stopping CCP */ - else - fsm_sconfreq(f, 0); /* Send Configure-Request */ - break; - - case PPP_FSM_ACKRCVD: - /* Got a Nak/reject when we had already had an Ack?? oh well... */ - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - fsm_sconfreq(f, 0); - f->state = PPP_FSM_REQSENT; - break; - - case PPP_FSM_OPENED: - /* Go down and restart negotiation */ - if (f->callbacks->down) - (*f->callbacks->down)(f); /* Inform upper layers */ - fsm_sconfreq(f, 0); /* Send initial Configure-Request */ - f->state = PPP_FSM_REQSENT; - break; - default: - break; - } -} - - -/* - * fsm_rtermreq - Receive Terminate-Req. - */ -static void fsm_rtermreq(fsm *f, int id, u_char *p, int len) { - ppp_pcb *pcb = f->pcb; - - switch (f->state) { - case PPP_FSM_ACKRCVD: - case PPP_FSM_ACKSENT: - f->state = PPP_FSM_REQSENT; /* Start over but keep trying */ - break; - - case PPP_FSM_OPENED: - if (len > 0) { - ppp_info("%s terminated by peer (%0.*v)", PROTO_NAME(f), len, p); - } else - ppp_info("%s terminated by peer", PROTO_NAME(f)); - f->retransmits = 0; - f->state = PPP_FSM_STOPPING; - if (f->callbacks->down) - (*f->callbacks->down)(f); /* Inform upper layers */ - TIMEOUT(fsm_timeout, f, pcb->settings.fsm_timeout_time); - break; - default: - break; - } - - fsm_sdata(f, TERMACK, id, NULL, 0); -} - - -/* - * fsm_rtermack - Receive Terminate-Ack. - */ -static void fsm_rtermack(fsm *f) { - switch (f->state) { - case PPP_FSM_CLOSING: - UNTIMEOUT(fsm_timeout, f); - f->state = PPP_FSM_CLOSED; - if( f->callbacks->finished ) - (*f->callbacks->finished)(f); - break; - case PPP_FSM_STOPPING: - UNTIMEOUT(fsm_timeout, f); - f->state = PPP_FSM_STOPPED; - if( f->callbacks->finished ) - (*f->callbacks->finished)(f); - break; - - case PPP_FSM_ACKRCVD: - f->state = PPP_FSM_REQSENT; - break; - - case PPP_FSM_OPENED: - if (f->callbacks->down) - (*f->callbacks->down)(f); /* Inform upper layers */ - fsm_sconfreq(f, 0); - f->state = PPP_FSM_REQSENT; - break; - default: - break; - } -} - - -/* - * fsm_rcoderej - Receive an Code-Reject. - */ -static void fsm_rcoderej(fsm *f, u_char *inp, int len) { - u_char code, id; - - if (len < HEADERLEN) { - FSMDEBUG(("fsm_rcoderej: Rcvd short Code-Reject packet!")); - return; - } - GETCHAR(code, inp); - GETCHAR(id, inp); - ppp_warn("%s: Rcvd Code-Reject for code %d, id %d", PROTO_NAME(f), code, id); - - if( f->state == PPP_FSM_ACKRCVD ) - f->state = PPP_FSM_REQSENT; -} - - -/* - * fsm_protreject - Peer doesn't speak this protocol. - * - * Treat this as a catastrophic error (RXJ-). - */ -void fsm_protreject(fsm *f) { - switch( f->state ){ - case PPP_FSM_CLOSING: - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - /* fall through */ - /* no break */ - case PPP_FSM_CLOSED: - f->state = PPP_FSM_CLOSED; - if( f->callbacks->finished ) - (*f->callbacks->finished)(f); - break; - - case PPP_FSM_STOPPING: - case PPP_FSM_REQSENT: - case PPP_FSM_ACKRCVD: - case PPP_FSM_ACKSENT: - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - /* fall through */ - /* no break */ - case PPP_FSM_STOPPED: - f->state = PPP_FSM_STOPPED; - if( f->callbacks->finished ) - (*f->callbacks->finished)(f); - break; - - case PPP_FSM_OPENED: - terminate_layer(f, PPP_FSM_STOPPING); - break; - - default: - FSMDEBUG(("%s: Protocol-reject event in state %d!", - PROTO_NAME(f), f->state)); - /* no break */ - } -} - - -/* - * fsm_sconfreq - Send a Configure-Request. - */ -static void fsm_sconfreq(fsm *f, int retransmit) { - ppp_pcb *pcb = f->pcb; - struct pbuf *p; - u_char *outp; - int cilen; - - if( f->state != PPP_FSM_REQSENT && f->state != PPP_FSM_ACKRCVD && f->state != PPP_FSM_ACKSENT ){ - /* Not currently negotiating - reset options */ - if( f->callbacks->resetci ) - (*f->callbacks->resetci)(f); - f->nakloops = 0; - f->rnakloops = 0; - } - - if( !retransmit ){ - /* New request - reset retransmission counter, use new ID */ - f->retransmits = pcb->settings.fsm_max_conf_req_transmits; - f->reqid = ++f->id; - } - - f->seen_ack = 0; - - /* - * Make up the request packet - */ - if( f->callbacks->cilen && f->callbacks->addci ){ - cilen = (*f->callbacks->cilen)(f); - if( cilen > pcb->peer_mru - HEADERLEN ) - cilen = pcb->peer_mru - HEADERLEN; - } else - cilen = 0; - - p = pbuf_alloc(PBUF_RAW, (u16_t)(cilen + HEADERLEN + PPP_HDRLEN), PPP_CTRL_PBUF_TYPE); - if(NULL == p) - return; - if(p->tot_len != p->len) { - pbuf_free(p); - return; - } - - /* send the request to our peer */ - outp = (u_char*)p->payload; - MAKEHEADER(outp, f->protocol); - PUTCHAR(CONFREQ, outp); - PUTCHAR(f->reqid, outp); - PUTSHORT(cilen + HEADERLEN, outp); - if (cilen != 0) { - (*f->callbacks->addci)(f, outp, &cilen); - LWIP_ASSERT("cilen == p->len - HEADERLEN - PPP_HDRLEN", cilen == p->len - HEADERLEN - PPP_HDRLEN); - } - - ppp_write(pcb, p); - - /* start the retransmit timer */ - --f->retransmits; - TIMEOUT(fsm_timeout, f, pcb->settings.fsm_timeout_time); -} - - -/* - * fsm_sdata - Send some data. - * - * Used for all packets sent to our peer by this module. - */ -void fsm_sdata(fsm *f, u_char code, u_char id, const u_char *data, int datalen) { - ppp_pcb *pcb = f->pcb; - struct pbuf *p; - u_char *outp; - int outlen; - - /* Adjust length to be smaller than MTU */ - if (datalen > pcb->peer_mru - HEADERLEN) - datalen = pcb->peer_mru - HEADERLEN; - outlen = datalen + HEADERLEN; - - p = pbuf_alloc(PBUF_RAW, (u16_t)(outlen + PPP_HDRLEN), PPP_CTRL_PBUF_TYPE); - if(NULL == p) - return; - if(p->tot_len != p->len) { - pbuf_free(p); - return; - } - - outp = (u_char*)p->payload; - if (datalen) /* && data != outp + PPP_HDRLEN + HEADERLEN) -- was only for fsm_sconfreq() */ - MEMCPY(outp + PPP_HDRLEN + HEADERLEN, data, datalen); - MAKEHEADER(outp, f->protocol); - PUTCHAR(code, outp); - PUTCHAR(id, outp); - PUTSHORT(outlen, outp); - ppp_write(pcb, p); -} - -#endif /* PPP_SUPPORT */ diff --git a/third-party/lwip-2.1.2/netif/ppp/ipcp.c b/third-party/lwip-2.1.2/netif/ppp/ipcp.c deleted file mode 100644 index b7c766eb..00000000 --- a/third-party/lwip-2.1.2/netif/ppp/ipcp.c +++ /dev/null @@ -1,2418 +0,0 @@ -/* - * ipcp.c - PPP IP Control Protocol. - * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && PPP_IPV4_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -/* - * @todo: - */ - -#if 0 /* UNUSED */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#endif /* UNUSED */ - -#include "netif/ppp/ppp_impl.h" - -#include "netif/ppp/fsm.h" -#include "netif/ppp/ipcp.h" - -#if 0 /* UNUSED */ -/* global vars */ -u32_t netmask = 0; /* IP netmask to set on interface */ -#endif /* UNUSED */ - -#if 0 /* UNUSED */ -bool disable_defaultip = 0; /* Don't use hostname for default IP adrs */ -#endif /* UNUSED */ - -#if 0 /* moved to ppp_settings */ -bool noremoteip = 0; /* Let him have no IP address */ -#endif /* moved to ppp_setting */ - -#if 0 /* UNUSED */ -/* Hook for a plugin to know when IP protocol has come up */ -void (*ip_up_hook) (void) = NULL; - -/* Hook for a plugin to know when IP protocol has come down */ -void (*ip_down_hook) (void) = NULL; - -/* Hook for a plugin to choose the remote IP address */ -void (*ip_choose_hook) (u32_t *) = NULL; -#endif /* UNUSED */ - -#if PPP_NOTIFY -/* Notifiers for when IPCP goes up and down */ -struct notifier *ip_up_notifier = NULL; -struct notifier *ip_down_notifier = NULL; -#endif /* PPP_NOTIFY */ - -/* local vars */ -#if 0 /* moved to ppp_pcb */ -static int default_route_set[NUM_PPP]; /* Have set up a default route */ -static int proxy_arp_set[NUM_PPP]; /* Have created proxy arp entry */ -static int ipcp_is_up; /* have called np_up() */ -static int ipcp_is_open; /* haven't called np_finished() */ -static bool ask_for_local; /* request our address from peer */ -#endif /* moved to ppp_pcb */ -#if 0 /* UNUSED */ -static char vj_value[8]; /* string form of vj option value */ -static char netmask_str[20]; /* string form of netmask value */ -#endif /* UNUSED */ - -/* - * Callbacks for fsm code. (CI = Configuration Information) - */ -static void ipcp_resetci(fsm *f); /* Reset our CI */ -static int ipcp_cilen(fsm *f); /* Return length of our CI */ -static void ipcp_addci(fsm *f, u_char *ucp, int *lenp); /* Add our CI */ -static int ipcp_ackci(fsm *f, u_char *p, int len); /* Peer ack'd our CI */ -static int ipcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject);/* Peer nak'd our CI */ -static int ipcp_rejci(fsm *f, u_char *p, int len); /* Peer rej'd our CI */ -static int ipcp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree); /* Rcv CI */ -static void ipcp_up(fsm *f); /* We're UP */ -static void ipcp_down(fsm *f); /* We're DOWN */ -static void ipcp_finished(fsm *f); /* Don't need lower layer */ - -static const fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */ - ipcp_resetci, /* Reset our Configuration Information */ - ipcp_cilen, /* Length of our Configuration Information */ - ipcp_addci, /* Add our Configuration Information */ - ipcp_ackci, /* ACK our Configuration Information */ - ipcp_nakci, /* NAK our Configuration Information */ - ipcp_rejci, /* Reject our Configuration Information */ - ipcp_reqci, /* Request peer's Configuration Information */ - ipcp_up, /* Called when fsm reaches OPENED state */ - ipcp_down, /* Called when fsm leaves OPENED state */ - NULL, /* Called when we want the lower layer up */ - ipcp_finished, /* Called when we want the lower layer down */ - NULL, /* Called when Protocol-Reject received */ - NULL, /* Retransmission is necessary */ - NULL, /* Called to handle protocol-specific codes */ - "IPCP" /* String name of protocol */ -}; - -/* - * Command-line options. - */ -#if PPP_OPTIONS -static int setvjslots (char **); -static int setdnsaddr (char **); -static int setwinsaddr (char **); -static int setnetmask (char **); -int setipaddr (char *, char **, int); - -static void printipaddr (option_t *, void (*)(void *, char *,...),void *); - -static option_t ipcp_option_list[] = { - { "noip", o_bool, &ipcp_protent.enabled_flag, - "Disable IP and IPCP" }, - { "-ip", o_bool, &ipcp_protent.enabled_flag, - "Disable IP and IPCP", OPT_ALIAS }, - - { "novj", o_bool, &ipcp_wantoptions[0].neg_vj, - "Disable VJ compression", OPT_A2CLR, &ipcp_allowoptions[0].neg_vj }, - { "-vj", o_bool, &ipcp_wantoptions[0].neg_vj, - "Disable VJ compression", OPT_ALIAS | OPT_A2CLR, - &ipcp_allowoptions[0].neg_vj }, - - { "novjccomp", o_bool, &ipcp_wantoptions[0].cflag, - "Disable VJ connection-ID compression", OPT_A2CLR, - &ipcp_allowoptions[0].cflag }, - { "-vjccomp", o_bool, &ipcp_wantoptions[0].cflag, - "Disable VJ connection-ID compression", OPT_ALIAS | OPT_A2CLR, - &ipcp_allowoptions[0].cflag }, - - { "vj-max-slots", o_special, (void *)setvjslots, - "Set maximum VJ header slots", - OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, vj_value }, - - { "ipcp-accept-local", o_bool, &ipcp_wantoptions[0].accept_local, - "Accept peer's address for us", 1 }, - { "ipcp-accept-remote", o_bool, &ipcp_wantoptions[0].accept_remote, - "Accept peer's address for it", 1 }, - - { "ipparam", o_string, &ipparam, - "Set ip script parameter", OPT_PRIO }, - - { "noipdefault", o_bool, &disable_defaultip, - "Don't use name for default IP adrs", 1 }, - - { "ms-dns", 1, (void *)setdnsaddr, - "DNS address for the peer's use" }, - { "ms-wins", 1, (void *)setwinsaddr, - "Nameserver for SMB over TCP/IP for peer" }, - - { "ipcp-restart", o_int, &ipcp_fsm[0].timeouttime, - "Set timeout for IPCP", OPT_PRIO }, - { "ipcp-max-terminate", o_int, &ipcp_fsm[0].maxtermtransmits, - "Set max #xmits for term-reqs", OPT_PRIO }, - { "ipcp-max-configure", o_int, &ipcp_fsm[0].maxconfreqtransmits, - "Set max #xmits for conf-reqs", OPT_PRIO }, - { "ipcp-max-failure", o_int, &ipcp_fsm[0].maxnakloops, - "Set max #conf-naks for IPCP", OPT_PRIO }, - - { "defaultroute", o_bool, &ipcp_wantoptions[0].default_route, - "Add default route", OPT_ENABLE|1, &ipcp_allowoptions[0].default_route }, - { "nodefaultroute", o_bool, &ipcp_allowoptions[0].default_route, - "disable defaultroute option", OPT_A2CLR, - &ipcp_wantoptions[0].default_route }, - { "-defaultroute", o_bool, &ipcp_allowoptions[0].default_route, - "disable defaultroute option", OPT_ALIAS | OPT_A2CLR, - &ipcp_wantoptions[0].default_route }, - - { "replacedefaultroute", o_bool, - &ipcp_wantoptions[0].replace_default_route, - "Replace default route", 1 - }, - { "noreplacedefaultroute", o_bool, - &ipcp_allowoptions[0].replace_default_route, - "Never replace default route", OPT_A2COPY, - &ipcp_wantoptions[0].replace_default_route }, - { "proxyarp", o_bool, &ipcp_wantoptions[0].proxy_arp, - "Add proxy ARP entry", OPT_ENABLE|1, &ipcp_allowoptions[0].proxy_arp }, - { "noproxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp, - "disable proxyarp option", OPT_A2CLR, - &ipcp_wantoptions[0].proxy_arp }, - { "-proxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp, - "disable proxyarp option", OPT_ALIAS | OPT_A2CLR, - &ipcp_wantoptions[0].proxy_arp }, - - { "usepeerdns", o_bool, &usepeerdns, - "Ask peer for DNS address(es)", 1 }, - - { "netmask", o_special, (void *)setnetmask, - "set netmask", OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, netmask_str }, - - { "ipcp-no-addresses", o_bool, &ipcp_wantoptions[0].old_addrs, - "Disable old-style IP-Addresses usage", OPT_A2CLR, - &ipcp_allowoptions[0].old_addrs }, - { "ipcp-no-address", o_bool, &ipcp_wantoptions[0].neg_addr, - "Disable IP-Address usage", OPT_A2CLR, - &ipcp_allowoptions[0].neg_addr }, - - { "noremoteip", o_bool, &noremoteip, - "Allow peer to have no IP address", 1 }, - - { "nosendip", o_bool, &ipcp_wantoptions[0].neg_addr, - "Don't send our IP address to peer", OPT_A2CLR, - &ipcp_wantoptions[0].old_addrs}, - - { "IP addresses", o_wild, (void *) &setipaddr, - "set local and remote IP addresses", - OPT_NOARG | OPT_A2PRINTER, (void *) &printipaddr }, - - { NULL } -}; -#endif /* PPP_OPTIONS */ - -/* - * Protocol entry points from main code. - */ -static void ipcp_init(ppp_pcb *pcb); -static void ipcp_open(ppp_pcb *pcb); -static void ipcp_close(ppp_pcb *pcb, const char *reason); -static void ipcp_lowerup(ppp_pcb *pcb); -static void ipcp_lowerdown(ppp_pcb *pcb); -static void ipcp_input(ppp_pcb *pcb, u_char *p, int len); -static void ipcp_protrej(ppp_pcb *pcb); -#if PRINTPKT_SUPPORT -static int ipcp_printpkt(const u_char *p, int plen, - void (*printer) (void *, const char *, ...), void *arg); -#endif /* PRINTPKT_SUPPORT */ -#if PPP_OPTIONS -static void ip_check_options (void); -#endif /* PPP_OPTIONS */ -#if DEMAND_SUPPORT -static int ip_demand_conf (int); -static int ip_active_pkt (u_char *, int); -#endif /* DEMAND_SUPPORT */ -#if 0 /* UNUSED */ -static void create_resolv (u32_t, u32_t); -#endif /* UNUSED */ - -const struct protent ipcp_protent = { - PPP_IPCP, - ipcp_init, - ipcp_input, - ipcp_protrej, - ipcp_lowerup, - ipcp_lowerdown, - ipcp_open, - ipcp_close, -#if PRINTPKT_SUPPORT - ipcp_printpkt, -#endif /* PRINTPKT_SUPPORT */ -#if PPP_DATAINPUT - NULL, -#endif /* PPP_DATAINPUT */ -#if PRINTPKT_SUPPORT - "IPCP", - "IP", -#endif /* PRINTPKT_SUPPORT */ -#if PPP_OPTIONS - ipcp_option_list, - ip_check_options, -#endif /* PPP_OPTIONS */ -#if DEMAND_SUPPORT - ip_demand_conf, - ip_active_pkt -#endif /* DEMAND_SUPPORT */ -}; - -static void ipcp_clear_addrs(ppp_pcb *pcb, u32_t ouraddr, u32_t hisaddr, u8_t replacedefaultroute); - -/* - * Lengths of configuration options. - */ -#define CILEN_VOID 2 -#define CILEN_COMPRESS 4 /* min length for compression protocol opt. */ -#define CILEN_VJ 6 /* length for RFC1332 Van-Jacobson opt. */ -#define CILEN_ADDR 6 /* new-style single address option */ -#define CILEN_ADDRS 10 /* old-style dual address option */ - - -#define CODENAME(x) ((x) == CONFACK ? "ACK" : \ - (x) == CONFNAK ? "NAK" : "REJ") - -#if 0 /* UNUSED, already defined by lwIP */ -/* - * Make a string representation of a network IP address. - */ -char * -ip_ntoa(ipaddr) -u32_t ipaddr; -{ - static char b[64]; - - slprintf(b, sizeof(b), "%I", ipaddr); - return b; -} -#endif /* UNUSED, already defined by lwIP */ - -/* - * Option parsing. - */ -#if PPP_OPTIONS -/* - * setvjslots - set maximum number of connection slots for VJ compression - */ -static int -setvjslots(argv) - char **argv; -{ - int value; - - if (!int_option(*argv, &value)) - return 0; - - if (value < 2 || value > 16) { - option_error("vj-max-slots value must be between 2 and 16"); - return 0; - } - ipcp_wantoptions [0].maxslotindex = - ipcp_allowoptions[0].maxslotindex = value - 1; - slprintf(vj_value, sizeof(vj_value), "%d", value); - return 1; -} - -/* - * setdnsaddr - set the dns address(es) - */ -static int -setdnsaddr(argv) - char **argv; -{ - u32_t dns; - struct hostent *hp; - - dns = inet_addr(*argv); - if (dns == (u32_t) -1) { - if ((hp = gethostbyname(*argv)) == NULL) { - option_error("invalid address parameter '%s' for ms-dns option", - *argv); - return 0; - } - dns = *(u32_t *)hp->h_addr; - } - - /* We take the last 2 values given, the 2nd-last as the primary - and the last as the secondary. If only one is given it - becomes both primary and secondary. */ - if (ipcp_allowoptions[0].dnsaddr[1] == 0) - ipcp_allowoptions[0].dnsaddr[0] = dns; - else - ipcp_allowoptions[0].dnsaddr[0] = ipcp_allowoptions[0].dnsaddr[1]; - - /* always set the secondary address value. */ - ipcp_allowoptions[0].dnsaddr[1] = dns; - - return (1); -} - -/* - * setwinsaddr - set the wins address(es) - * This is primrarly used with the Samba package under UNIX or for pointing - * the caller to the existing WINS server on a Windows NT platform. - */ -static int -setwinsaddr(argv) - char **argv; -{ - u32_t wins; - struct hostent *hp; - - wins = inet_addr(*argv); - if (wins == (u32_t) -1) { - if ((hp = gethostbyname(*argv)) == NULL) { - option_error("invalid address parameter '%s' for ms-wins option", - *argv); - return 0; - } - wins = *(u32_t *)hp->h_addr; - } - - /* We take the last 2 values given, the 2nd-last as the primary - and the last as the secondary. If only one is given it - becomes both primary and secondary. */ - if (ipcp_allowoptions[0].winsaddr[1] == 0) - ipcp_allowoptions[0].winsaddr[0] = wins; - else - ipcp_allowoptions[0].winsaddr[0] = ipcp_allowoptions[0].winsaddr[1]; - - /* always set the secondary address value. */ - ipcp_allowoptions[0].winsaddr[1] = wins; - - return (1); -} - -/* - * setipaddr - Set the IP address - * If doit is 0, the call is to check whether this option is - * potentially an IP address specification. - * Not static so that plugins can call it to set the addresses - */ -int -setipaddr(arg, argv, doit) - char *arg; - char **argv; - int doit; -{ - struct hostent *hp; - char *colon; - u32_t local, remote; - ipcp_options *wo = &ipcp_wantoptions[0]; - static int prio_local = 0, prio_remote = 0; - - /* - * IP address pair separated by ":". - */ - if ((colon = strchr(arg, ':')) == NULL) - return 0; - if (!doit) - return 1; - - /* - * If colon first character, then no local addr. - */ - if (colon != arg && option_priority >= prio_local) { - *colon = '\0'; - if ((local = inet_addr(arg)) == (u32_t) -1) { - if ((hp = gethostbyname(arg)) == NULL) { - option_error("unknown host: %s", arg); - return 0; - } - local = *(u32_t *)hp->h_addr; - } - if (bad_ip_adrs(local)) { - option_error("bad local IP address %s", ip_ntoa(local)); - return 0; - } - if (local != 0) - wo->ouraddr = local; - *colon = ':'; - prio_local = option_priority; - } - - /* - * If colon last character, then no remote addr. - */ - if (*++colon != '\0' && option_priority >= prio_remote) { - if ((remote = inet_addr(colon)) == (u32_t) -1) { - if ((hp = gethostbyname(colon)) == NULL) { - option_error("unknown host: %s", colon); - return 0; - } - remote = *(u32_t *)hp->h_addr; - if (remote_name[0] == 0) - strlcpy(remote_name, colon, sizeof(remote_name)); - } - if (bad_ip_adrs(remote)) { - option_error("bad remote IP address %s", ip_ntoa(remote)); - return 0; - } - if (remote != 0) - wo->hisaddr = remote; - prio_remote = option_priority; - } - - return 1; -} - -static void -printipaddr(opt, printer, arg) - option_t *opt; - void (*printer) (void *, char *, ...); - void *arg; -{ - ipcp_options *wo = &ipcp_wantoptions[0]; - - if (wo->ouraddr != 0) - printer(arg, "%I", wo->ouraddr); - printer(arg, ":"); - if (wo->hisaddr != 0) - printer(arg, "%I", wo->hisaddr); -} - -/* - * setnetmask - set the netmask to be used on the interface. - */ -static int -setnetmask(argv) - char **argv; -{ - u32_t mask; - int n; - char *p; - - /* - * Unfortunately, if we use inet_addr, we can't tell whether - * a result of all 1s is an error or a valid 255.255.255.255. - */ - p = *argv; - n = parse_dotted_ip(p, &mask); - - mask = lwip_htonl(mask); - - if (n == 0 || p[n] != 0 || (netmask & ~mask) != 0) { - option_error("invalid netmask value '%s'", *argv); - return 0; - } - - netmask = mask; - slprintf(netmask_str, sizeof(netmask_str), "%I", mask); - - return (1); -} - -int -parse_dotted_ip(p, vp) - char *p; - u32_t *vp; -{ - int n; - u32_t v, b; - char *endp, *p0 = p; - - v = 0; - for (n = 3;; --n) { - b = strtoul(p, &endp, 0); - if (endp == p) - return 0; - if (b > 255) { - if (n < 3) - return 0; - /* accept e.g. 0xffffff00 */ - *vp = b; - return endp - p0; - } - v |= b << (n * 8); - p = endp; - if (n == 0) - break; - if (*p != '.') - return 0; - ++p; - } - *vp = v; - return p - p0; -} -#endif /* PPP_OPTIONS */ - -/* - * ipcp_init - Initialize IPCP. - */ -static void ipcp_init(ppp_pcb *pcb) { - fsm *f = &pcb->ipcp_fsm; - - ipcp_options *wo = &pcb->ipcp_wantoptions; - ipcp_options *ao = &pcb->ipcp_allowoptions; - - f->pcb = pcb; - f->protocol = PPP_IPCP; - f->callbacks = &ipcp_callbacks; - fsm_init(f); - - /* - * Some 3G modems use repeated IPCP NAKs as a way of stalling - * until they can contact a server on the network, so we increase - * the default number of NAKs we accept before we start treating - * them as rejects. - */ - f->maxnakloops = 100; - -#if 0 /* Not necessary, everything is cleared in ppp_new() */ - memset(wo, 0, sizeof(*wo)); - memset(ao, 0, sizeof(*ao)); -#endif /* 0 */ - - wo->neg_addr = wo->old_addrs = 1; -#if VJ_SUPPORT - wo->neg_vj = 1; - wo->vj_protocol = IPCP_VJ_COMP; - wo->maxslotindex = MAX_STATES - 1; /* really max index */ - wo->cflag = 1; -#endif /* VJ_SUPPORT */ - -#if 0 /* UNUSED */ - /* wanting default route by default */ - wo->default_route = 1; -#endif /* UNUSED */ - - ao->neg_addr = ao->old_addrs = 1; -#if VJ_SUPPORT - /* max slots and slot-id compression are currently hardwired in */ - /* ppp_if.c to 16 and 1, this needs to be changed (among other */ - /* things) gmc */ - - ao->neg_vj = 1; - ao->maxslotindex = MAX_STATES - 1; - ao->cflag = 1; -#endif /* #if VJ_SUPPORT */ - -#if 0 /* UNUSED */ - /* - * XXX These control whether the user may use the proxyarp - * and defaultroute options. - */ - ao->proxy_arp = 1; - ao->default_route = 1; -#endif /* UNUSED */ -} - - -/* - * ipcp_open - IPCP is allowed to come up. - */ -static void ipcp_open(ppp_pcb *pcb) { - fsm *f = &pcb->ipcp_fsm; - fsm_open(f); - pcb->ipcp_is_open = 1; -} - - -/* - * ipcp_close - Take IPCP down. - */ -static void ipcp_close(ppp_pcb *pcb, const char *reason) { - fsm *f = &pcb->ipcp_fsm; - fsm_close(f, reason); -} - - -/* - * ipcp_lowerup - The lower layer is up. - */ -static void ipcp_lowerup(ppp_pcb *pcb) { - fsm *f = &pcb->ipcp_fsm; - fsm_lowerup(f); -} - - -/* - * ipcp_lowerdown - The lower layer is down. - */ -static void ipcp_lowerdown(ppp_pcb *pcb) { - fsm *f = &pcb->ipcp_fsm; - fsm_lowerdown(f); -} - - -/* - * ipcp_input - Input IPCP packet. - */ -static void ipcp_input(ppp_pcb *pcb, u_char *p, int len) { - fsm *f = &pcb->ipcp_fsm; - fsm_input(f, p, len); -} - - -/* - * ipcp_protrej - A Protocol-Reject was received for IPCP. - * - * Pretend the lower layer went down, so we shut up. - */ -static void ipcp_protrej(ppp_pcb *pcb) { - fsm *f = &pcb->ipcp_fsm; - fsm_lowerdown(f); -} - - -/* - * ipcp_resetci - Reset our CI. - * Called by fsm_sconfreq, Send Configure Request. - */ -static void ipcp_resetci(fsm *f) { - ppp_pcb *pcb = f->pcb; - ipcp_options *wo = &pcb->ipcp_wantoptions; - ipcp_options *go = &pcb->ipcp_gotoptions; - ipcp_options *ao = &pcb->ipcp_allowoptions; - - wo->req_addr = (wo->neg_addr || wo->old_addrs) && - (ao->neg_addr || ao->old_addrs); - if (wo->ouraddr == 0) - wo->accept_local = 1; - if (wo->hisaddr == 0) - wo->accept_remote = 1; -#if LWIP_DNS - wo->req_dns1 = wo->req_dns2 = pcb->settings.usepeerdns; /* Request DNS addresses from the peer */ -#endif /* LWIP_DNS */ - *go = *wo; - if (!pcb->ask_for_local) - go->ouraddr = 0; -#if 0 /* UNUSED */ - if (ip_choose_hook) { - ip_choose_hook(&wo->hisaddr); - if (wo->hisaddr) { - wo->accept_remote = 0; - } - } -#endif /* UNUSED */ - BZERO(&pcb->ipcp_hisoptions, sizeof(ipcp_options)); -} - - -/* - * ipcp_cilen - Return length of our CI. - * Called by fsm_sconfreq, Send Configure Request. - */ -static int ipcp_cilen(fsm *f) { - ppp_pcb *pcb = f->pcb; - ipcp_options *go = &pcb->ipcp_gotoptions; -#if VJ_SUPPORT - ipcp_options *wo = &pcb->ipcp_wantoptions; -#endif /* VJ_SUPPORT */ - ipcp_options *ho = &pcb->ipcp_hisoptions; - -#define LENCIADDRS(neg) (neg ? CILEN_ADDRS : 0) -#if VJ_SUPPORT -#define LENCIVJ(neg, old) (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0) -#endif /* VJ_SUPPORT */ -#define LENCIADDR(neg) (neg ? CILEN_ADDR : 0) -#if LWIP_DNS -#define LENCIDNS(neg) LENCIADDR(neg) -#endif /* LWIP_DNS */ -#if 0 /* UNUSED - WINS */ -#define LENCIWINS(neg) LENCIADDR(neg) -#endif /* UNUSED - WINS */ - - /* - * First see if we want to change our options to the old - * forms because we have received old forms from the peer. - */ - if (go->neg_addr && go->old_addrs && !ho->neg_addr && ho->old_addrs) - go->neg_addr = 0; - -#if VJ_SUPPORT - if (wo->neg_vj && !go->neg_vj && !go->old_vj) { - /* try an older style of VJ negotiation */ - /* use the old style only if the peer did */ - if (ho->neg_vj && ho->old_vj) { - go->neg_vj = 1; - go->old_vj = 1; - go->vj_protocol = ho->vj_protocol; - } - } -#endif /* VJ_SUPPORT */ - - return (LENCIADDRS(!go->neg_addr && go->old_addrs) + -#if VJ_SUPPORT - LENCIVJ(go->neg_vj, go->old_vj) + -#endif /* VJ_SUPPORT */ - LENCIADDR(go->neg_addr) + -#if LWIP_DNS - LENCIDNS(go->req_dns1) + - LENCIDNS(go->req_dns2) + -#endif /* LWIP_DNS */ -#if 0 /* UNUSED - WINS */ - LENCIWINS(go->winsaddr[0]) + - LENCIWINS(go->winsaddr[1]) + -#endif /* UNUSED - WINS */ - 0); -} - - -/* - * ipcp_addci - Add our desired CIs to a packet. - * Called by fsm_sconfreq, Send Configure Request. - */ -static void ipcp_addci(fsm *f, u_char *ucp, int *lenp) { - ppp_pcb *pcb = f->pcb; - ipcp_options *go = &pcb->ipcp_gotoptions; - int len = *lenp; - -#define ADDCIADDRS(opt, neg, val1, val2) \ - if (neg) { \ - if (len >= CILEN_ADDRS) { \ - u32_t l; \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_ADDRS, ucp); \ - l = lwip_ntohl(val1); \ - PUTLONG(l, ucp); \ - l = lwip_ntohl(val2); \ - PUTLONG(l, ucp); \ - len -= CILEN_ADDRS; \ - } else \ - go->old_addrs = 0; \ - } - -#if VJ_SUPPORT -#define ADDCIVJ(opt, neg, val, old, maxslotindex, cflag) \ - if (neg) { \ - int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \ - if (len >= vjlen) { \ - PUTCHAR(opt, ucp); \ - PUTCHAR(vjlen, ucp); \ - PUTSHORT(val, ucp); \ - if (!old) { \ - PUTCHAR(maxslotindex, ucp); \ - PUTCHAR(cflag, ucp); \ - } \ - len -= vjlen; \ - } else \ - neg = 0; \ - } -#endif /* VJ_SUPPORT */ - -#define ADDCIADDR(opt, neg, val) \ - if (neg) { \ - if (len >= CILEN_ADDR) { \ - u32_t l; \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_ADDR, ucp); \ - l = lwip_ntohl(val); \ - PUTLONG(l, ucp); \ - len -= CILEN_ADDR; \ - } else \ - neg = 0; \ - } - -#if LWIP_DNS -#define ADDCIDNS(opt, neg, addr) \ - if (neg) { \ - if (len >= CILEN_ADDR) { \ - u32_t l; \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_ADDR, ucp); \ - l = lwip_ntohl(addr); \ - PUTLONG(l, ucp); \ - len -= CILEN_ADDR; \ - } else \ - neg = 0; \ - } -#endif /* LWIP_DNS */ - -#if 0 /* UNUSED - WINS */ -#define ADDCIWINS(opt, addr) \ - if (addr) { \ - if (len >= CILEN_ADDR) { \ - u32_t l; \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_ADDR, ucp); \ - l = lwip_ntohl(addr); \ - PUTLONG(l, ucp); \ - len -= CILEN_ADDR; \ - } else \ - addr = 0; \ - } -#endif /* UNUSED - WINS */ - - ADDCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, go->ouraddr, - go->hisaddr); - -#if VJ_SUPPORT - ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj, - go->maxslotindex, go->cflag); -#endif /* VJ_SUPPORT */ - - ADDCIADDR(CI_ADDR, go->neg_addr, go->ouraddr); - -#if LWIP_DNS - ADDCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]); - - ADDCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]); -#endif /* LWIP_DNS */ - -#if 0 /* UNUSED - WINS */ - ADDCIWINS(CI_MS_WINS1, go->winsaddr[0]); - - ADDCIWINS(CI_MS_WINS2, go->winsaddr[1]); -#endif /* UNUSED - WINS */ - - *lenp -= len; -} - - -/* - * ipcp_ackci - Ack our CIs. - * Called by fsm_rconfack, Receive Configure ACK. - * - * Returns: - * 0 - Ack was bad. - * 1 - Ack was good. - */ -static int ipcp_ackci(fsm *f, u_char *p, int len) { - ppp_pcb *pcb = f->pcb; - ipcp_options *go = &pcb->ipcp_gotoptions; - u_short cilen, citype; - u32_t cilong; -#if VJ_SUPPORT - u_short cishort; - u_char cimaxslotindex, cicflag; -#endif /* VJ_SUPPORT */ - - /* - * CIs must be in exactly the same order that we sent... - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ - -#define ACKCIADDRS(opt, neg, val1, val2) \ - if (neg) { \ - u32_t l; \ - if ((len -= CILEN_ADDRS) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_ADDRS || \ - citype != opt) \ - goto bad; \ - GETLONG(l, p); \ - cilong = lwip_htonl(l); \ - if (val1 != cilong) \ - goto bad; \ - GETLONG(l, p); \ - cilong = lwip_htonl(l); \ - if (val2 != cilong) \ - goto bad; \ - } - -#if VJ_SUPPORT -#define ACKCIVJ(opt, neg, val, old, maxslotindex, cflag) \ - if (neg) { \ - int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \ - if ((len -= vjlen) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != vjlen || \ - citype != opt) \ - goto bad; \ - GETSHORT(cishort, p); \ - if (cishort != val) \ - goto bad; \ - if (!old) { \ - GETCHAR(cimaxslotindex, p); \ - if (cimaxslotindex != maxslotindex) \ - goto bad; \ - GETCHAR(cicflag, p); \ - if (cicflag != cflag) \ - goto bad; \ - } \ - } -#endif /* VJ_SUPPORT */ - -#define ACKCIADDR(opt, neg, val) \ - if (neg) { \ - u32_t l; \ - if ((len -= CILEN_ADDR) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_ADDR || \ - citype != opt) \ - goto bad; \ - GETLONG(l, p); \ - cilong = lwip_htonl(l); \ - if (val != cilong) \ - goto bad; \ - } - -#if LWIP_DNS -#define ACKCIDNS(opt, neg, addr) \ - if (neg) { \ - u32_t l; \ - if ((len -= CILEN_ADDR) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_ADDR || citype != opt) \ - goto bad; \ - GETLONG(l, p); \ - cilong = lwip_htonl(l); \ - if (addr != cilong) \ - goto bad; \ - } -#endif /* LWIP_DNS */ - -#if 0 /* UNUSED - WINS */ -#define ACKCIWINS(opt, addr) \ - if (addr) { \ - u32_t l; \ - if ((len -= CILEN_ADDR) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_ADDR || citype != opt) \ - goto bad; \ - GETLONG(l, p); \ - cilong = lwip_htonl(l); \ - if (addr != cilong) \ - goto bad; \ - } -#endif /* UNUSED - WINS */ - - ACKCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, go->ouraddr, - go->hisaddr); - -#if VJ_SUPPORT - ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj, - go->maxslotindex, go->cflag); -#endif /* VJ_SUPPORT */ - - ACKCIADDR(CI_ADDR, go->neg_addr, go->ouraddr); - -#if LWIP_DNS - ACKCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]); - - ACKCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]); -#endif /* LWIP_DNS */ - -#if 0 /* UNUSED - WINS */ - ACKCIWINS(CI_MS_WINS1, go->winsaddr[0]); - - ACKCIWINS(CI_MS_WINS2, go->winsaddr[1]); -#endif /* UNUSED - WINS */ - - /* - * If there are any remaining CIs, then this packet is bad. - */ - if (len != 0) - goto bad; - return (1); - -bad: - IPCPDEBUG(("ipcp_ackci: received bad Ack!")); - return (0); -} - -/* - * ipcp_nakci - Peer has sent a NAK for some of our CIs. - * This should not modify any state if the Nak is bad - * or if IPCP is in the OPENED state. - * Calback from fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject. - * - * Returns: - * 0 - Nak was bad. - * 1 - Nak was good. - */ -static int ipcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { - ppp_pcb *pcb = f->pcb; - ipcp_options *go = &pcb->ipcp_gotoptions; - u_char citype, cilen, *next; -#if VJ_SUPPORT - u_char cimaxslotindex, cicflag; - u_short cishort; -#endif /* VJ_SUPPORT */ - u32_t ciaddr1, ciaddr2, l; -#if LWIP_DNS - u32_t cidnsaddr; -#endif /* LWIP_DNS */ - ipcp_options no; /* options we've seen Naks for */ - ipcp_options try_; /* options to request next time */ - - BZERO(&no, sizeof(no)); - try_ = *go; - - /* - * Any Nak'd CIs must be in exactly the same order that we sent. - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ -#define NAKCIADDRS(opt, neg, code) \ - if ((neg) && \ - (cilen = p[1]) == CILEN_ADDRS && \ - len >= cilen && \ - p[0] == opt) { \ - len -= cilen; \ - INCPTR(2, p); \ - GETLONG(l, p); \ - ciaddr1 = lwip_htonl(l); \ - GETLONG(l, p); \ - ciaddr2 = lwip_htonl(l); \ - no.old_addrs = 1; \ - code \ - } - -#if VJ_SUPPORT -#define NAKCIVJ(opt, neg, code) \ - if (go->neg && \ - ((cilen = p[1]) == CILEN_COMPRESS || cilen == CILEN_VJ) && \ - len >= cilen && \ - p[0] == opt) { \ - len -= cilen; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - no.neg = 1; \ - code \ - } -#endif /* VJ_SUPPORT */ - -#define NAKCIADDR(opt, neg, code) \ - if (go->neg && \ - (cilen = p[1]) == CILEN_ADDR && \ - len >= cilen && \ - p[0] == opt) { \ - len -= cilen; \ - INCPTR(2, p); \ - GETLONG(l, p); \ - ciaddr1 = lwip_htonl(l); \ - no.neg = 1; \ - code \ - } - -#if LWIP_DNS -#define NAKCIDNS(opt, neg, code) \ - if (go->neg && \ - ((cilen = p[1]) == CILEN_ADDR) && \ - len >= cilen && \ - p[0] == opt) { \ - len -= cilen; \ - INCPTR(2, p); \ - GETLONG(l, p); \ - cidnsaddr = lwip_htonl(l); \ - no.neg = 1; \ - code \ - } -#endif /* LWIP_DNS */ - - /* - * Accept the peer's idea of {our,his} address, if different - * from our idea, only if the accept_{local,remote} flag is set. - */ - NAKCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, - if (treat_as_reject) { - try_.old_addrs = 0; - } else { - if (go->accept_local && ciaddr1) { - /* take his idea of our address */ - try_.ouraddr = ciaddr1; - } - if (go->accept_remote && ciaddr2) { - /* take his idea of his address */ - try_.hisaddr = ciaddr2; - } - } - ); - -#if VJ_SUPPORT - /* - * Accept the peer's value of maxslotindex provided that it - * is less than what we asked for. Turn off slot-ID compression - * if the peer wants. Send old-style compress-type option if - * the peer wants. - */ - NAKCIVJ(CI_COMPRESSTYPE, neg_vj, - if (treat_as_reject) { - try_.neg_vj = 0; - } else if (cilen == CILEN_VJ) { - GETCHAR(cimaxslotindex, p); - GETCHAR(cicflag, p); - if (cishort == IPCP_VJ_COMP) { - try_.old_vj = 0; - if (cimaxslotindex < go->maxslotindex) - try_.maxslotindex = cimaxslotindex; - if (!cicflag) - try_.cflag = 0; - } else { - try_.neg_vj = 0; - } - } else { - if (cishort == IPCP_VJ_COMP || cishort == IPCP_VJ_COMP_OLD) { - try_.old_vj = 1; - try_.vj_protocol = cishort; - } else { - try_.neg_vj = 0; - } - } - ); -#endif /* VJ_SUPPORT */ - - NAKCIADDR(CI_ADDR, neg_addr, - if (treat_as_reject) { - try_.neg_addr = 0; - try_.old_addrs = 0; - } else if (go->accept_local && ciaddr1) { - /* take his idea of our address */ - try_.ouraddr = ciaddr1; - } - ); - -#if LWIP_DNS - NAKCIDNS(CI_MS_DNS1, req_dns1, - if (treat_as_reject) { - try_.req_dns1 = 0; - } else { - try_.dnsaddr[0] = cidnsaddr; - } - ); - - NAKCIDNS(CI_MS_DNS2, req_dns2, - if (treat_as_reject) { - try_.req_dns2 = 0; - } else { - try_.dnsaddr[1] = cidnsaddr; - } - ); -#endif /* #if LWIP_DNS */ - - /* - * There may be remaining CIs, if the peer is requesting negotiation - * on an option that we didn't include in our request packet. - * If they want to negotiate about IP addresses, we comply. - * If they want us to ask for compression, we refuse. - * If they want us to ask for ms-dns, we do that, since some - * peers get huffy if we don't. - */ - while (len >= CILEN_VOID) { - GETCHAR(citype, p); - GETCHAR(cilen, p); - if ( cilen < CILEN_VOID || (len -= cilen) < 0 ) - goto bad; - next = p + cilen - 2; - - switch (citype) { -#if VJ_SUPPORT - case CI_COMPRESSTYPE: - if (go->neg_vj || no.neg_vj || - (cilen != CILEN_VJ && cilen != CILEN_COMPRESS)) - goto bad; - no.neg_vj = 1; - break; -#endif /* VJ_SUPPORT */ - case CI_ADDRS: - if ((!go->neg_addr && go->old_addrs) || no.old_addrs - || cilen != CILEN_ADDRS) - goto bad; - try_.neg_addr = 0; - GETLONG(l, p); - ciaddr1 = lwip_htonl(l); - if (ciaddr1 && go->accept_local) - try_.ouraddr = ciaddr1; - GETLONG(l, p); - ciaddr2 = lwip_htonl(l); - if (ciaddr2 && go->accept_remote) - try_.hisaddr = ciaddr2; - no.old_addrs = 1; - break; - case CI_ADDR: - if (go->neg_addr || no.neg_addr || cilen != CILEN_ADDR) - goto bad; - try_.old_addrs = 0; - GETLONG(l, p); - ciaddr1 = lwip_htonl(l); - if (ciaddr1 && go->accept_local) - try_.ouraddr = ciaddr1; - if (try_.ouraddr != 0) - try_.neg_addr = 1; - no.neg_addr = 1; - break; -#if LWIP_DNS - case CI_MS_DNS1: - if (go->req_dns1 || no.req_dns1 || cilen != CILEN_ADDR) - goto bad; - GETLONG(l, p); - try_.dnsaddr[0] = lwip_htonl(l); - try_.req_dns1 = 1; - no.req_dns1 = 1; - break; - case CI_MS_DNS2: - if (go->req_dns2 || no.req_dns2 || cilen != CILEN_ADDR) - goto bad; - GETLONG(l, p); - try_.dnsaddr[1] = lwip_htonl(l); - try_.req_dns2 = 1; - no.req_dns2 = 1; - break; -#endif /* LWIP_DNS */ -#if 0 /* UNUSED - WINS */ - case CI_MS_WINS1: - case CI_MS_WINS2: - if (cilen != CILEN_ADDR) - goto bad; - GETLONG(l, p); - ciaddr1 = lwip_htonl(l); - if (ciaddr1) - try_.winsaddr[citype == CI_MS_WINS2] = ciaddr1; - break; -#endif /* UNUSED - WINS */ - default: - break; - } - p = next; - } - - /* - * OK, the Nak is good. Now we can update state. - * If there are any remaining options, we ignore them. - */ - if (f->state != PPP_FSM_OPENED) - *go = try_; - - return 1; - -bad: - IPCPDEBUG(("ipcp_nakci: received bad Nak!")); - return 0; -} - - -/* - * ipcp_rejci - Reject some of our CIs. - * Callback from fsm_rconfnakrej. - */ -static int ipcp_rejci(fsm *f, u_char *p, int len) { - ppp_pcb *pcb = f->pcb; - ipcp_options *go = &pcb->ipcp_gotoptions; - u_char cilen; -#if VJ_SUPPORT - u_char cimaxslotindex, ciflag; - u_short cishort; -#endif /* VJ_SUPPORT */ - u32_t cilong; - ipcp_options try_; /* options to request next time */ - - try_ = *go; - /* - * Any Rejected CIs must be in exactly the same order that we sent. - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ -#define REJCIADDRS(opt, neg, val1, val2) \ - if ((neg) && \ - (cilen = p[1]) == CILEN_ADDRS && \ - len >= cilen && \ - p[0] == opt) { \ - u32_t l; \ - len -= cilen; \ - INCPTR(2, p); \ - GETLONG(l, p); \ - cilong = lwip_htonl(l); \ - /* Check rejected value. */ \ - if (cilong != val1) \ - goto bad; \ - GETLONG(l, p); \ - cilong = lwip_htonl(l); \ - /* Check rejected value. */ \ - if (cilong != val2) \ - goto bad; \ - try_.old_addrs = 0; \ - } - -#if VJ_SUPPORT -#define REJCIVJ(opt, neg, val, old, maxslot, cflag) \ - if (go->neg && \ - p[1] == (old? CILEN_COMPRESS : CILEN_VJ) && \ - len >= p[1] && \ - p[0] == opt) { \ - len -= p[1]; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - /* Check rejected value. */ \ - if (cishort != val) \ - goto bad; \ - if (!old) { \ - GETCHAR(cimaxslotindex, p); \ - if (cimaxslotindex != maxslot) \ - goto bad; \ - GETCHAR(ciflag, p); \ - if (ciflag != cflag) \ - goto bad; \ - } \ - try_.neg = 0; \ - } -#endif /* VJ_SUPPORT */ - -#define REJCIADDR(opt, neg, val) \ - if (go->neg && \ - (cilen = p[1]) == CILEN_ADDR && \ - len >= cilen && \ - p[0] == opt) { \ - u32_t l; \ - len -= cilen; \ - INCPTR(2, p); \ - GETLONG(l, p); \ - cilong = lwip_htonl(l); \ - /* Check rejected value. */ \ - if (cilong != val) \ - goto bad; \ - try_.neg = 0; \ - } - -#if LWIP_DNS -#define REJCIDNS(opt, neg, dnsaddr) \ - if (go->neg && \ - ((cilen = p[1]) == CILEN_ADDR) && \ - len >= cilen && \ - p[0] == opt) { \ - u32_t l; \ - len -= cilen; \ - INCPTR(2, p); \ - GETLONG(l, p); \ - cilong = lwip_htonl(l); \ - /* Check rejected value. */ \ - if (cilong != dnsaddr) \ - goto bad; \ - try_.neg = 0; \ - } -#endif /* LWIP_DNS */ - -#if 0 /* UNUSED - WINS */ -#define REJCIWINS(opt, addr) \ - if (addr && \ - ((cilen = p[1]) == CILEN_ADDR) && \ - len >= cilen && \ - p[0] == opt) { \ - u32_t l; \ - len -= cilen; \ - INCPTR(2, p); \ - GETLONG(l, p); \ - cilong = lwip_htonl(l); \ - /* Check rejected value. */ \ - if (cilong != addr) \ - goto bad; \ - try_.winsaddr[opt == CI_MS_WINS2] = 0; \ - } -#endif /* UNUSED - WINS */ - - REJCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, - go->ouraddr, go->hisaddr); - -#if VJ_SUPPORT - REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol, go->old_vj, - go->maxslotindex, go->cflag); -#endif /* VJ_SUPPORT */ - - REJCIADDR(CI_ADDR, neg_addr, go->ouraddr); - -#if LWIP_DNS - REJCIDNS(CI_MS_DNS1, req_dns1, go->dnsaddr[0]); - - REJCIDNS(CI_MS_DNS2, req_dns2, go->dnsaddr[1]); -#endif /* LWIP_DNS */ - -#if 0 /* UNUSED - WINS */ - REJCIWINS(CI_MS_WINS1, go->winsaddr[0]); - - REJCIWINS(CI_MS_WINS2, go->winsaddr[1]); -#endif /* UNUSED - WINS */ - - /* - * If there are any remaining CIs, then this packet is bad. - */ - if (len != 0) - goto bad; - /* - * Now we can update state. - */ - if (f->state != PPP_FSM_OPENED) - *go = try_; - return 1; - -bad: - IPCPDEBUG(("ipcp_rejci: received bad Reject!")); - return 0; -} - - -/* - * ipcp_reqci - Check the peer's requested CIs and send appropriate response. - * Callback from fsm_rconfreq, Receive Configure Request - * - * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified - * appropriately. If reject_if_disagree is non-zero, doesn't return - * CONFNAK; returns CONFREJ if it can't return CONFACK. - * - * inp = Requested CIs - * len = Length of requested CIs - */ -static int ipcp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree) { - ppp_pcb *pcb = f->pcb; - ipcp_options *wo = &pcb->ipcp_wantoptions; - ipcp_options *ho = &pcb->ipcp_hisoptions; - ipcp_options *ao = &pcb->ipcp_allowoptions; - u_char *cip, *next; /* Pointer to current and next CIs */ - u_short cilen, citype; /* Parsed len, type */ -#if VJ_SUPPORT - u_short cishort; /* Parsed short value */ -#endif /* VJ_SUPPORT */ - u32_t tl, ciaddr1, ciaddr2;/* Parsed address values */ - int rc = CONFACK; /* Final packet return code */ - int orc; /* Individual option return code */ - u_char *p; /* Pointer to next char to parse */ - u_char *ucp = inp; /* Pointer to current output char */ - int l = *len; /* Length left */ -#if VJ_SUPPORT - u_char maxslotindex, cflag; -#endif /* VJ_SUPPORT */ -#if LWIP_DNS - int d; -#endif /* LWIP_DNS */ - - /* - * Reset all his options. - */ - BZERO(ho, sizeof(*ho)); - - /* - * Process all his options. - */ - next = inp; - while (l) { - orc = CONFACK; /* Assume success */ - cip = p = next; /* Remember begining of CI */ - if (l < 2 || /* Not enough data for CI header or */ - p[1] < 2 || /* CI length too small or */ - p[1] > l) { /* CI length too big? */ - IPCPDEBUG(("ipcp_reqci: bad CI length!")); - orc = CONFREJ; /* Reject bad CI */ - cilen = l; /* Reject till end of packet */ - l = 0; /* Don't loop again */ - goto endswitch; - } - GETCHAR(citype, p); /* Parse CI type */ - GETCHAR(cilen, p); /* Parse CI length */ - l -= cilen; /* Adjust remaining length */ - next += cilen; /* Step to next CI */ - - switch (citype) { /* Check CI type */ - case CI_ADDRS: - if (!ao->old_addrs || ho->neg_addr || - cilen != CILEN_ADDRS) { /* Check CI length */ - orc = CONFREJ; /* Reject CI */ - break; - } - - /* - * If he has no address, or if we both have his address but - * disagree about it, then NAK it with our idea. - * In particular, if we don't know his address, but he does, - * then accept it. - */ - GETLONG(tl, p); /* Parse source address (his) */ - ciaddr1 = lwip_htonl(tl); - if (ciaddr1 != wo->hisaddr - && (ciaddr1 == 0 || !wo->accept_remote)) { - orc = CONFNAK; - if (!reject_if_disagree) { - DECPTR(sizeof(u32_t), p); - tl = lwip_ntohl(wo->hisaddr); - PUTLONG(tl, p); - } - } else if (ciaddr1 == 0 && wo->hisaddr == 0) { - /* - * If neither we nor he knows his address, reject the option. - */ - orc = CONFREJ; - wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */ - break; - } - - /* - * If he doesn't know our address, or if we both have our address - * but disagree about it, then NAK it with our idea. - */ - GETLONG(tl, p); /* Parse desination address (ours) */ - ciaddr2 = lwip_htonl(tl); - if (ciaddr2 != wo->ouraddr) { - if (ciaddr2 == 0 || !wo->accept_local) { - orc = CONFNAK; - if (!reject_if_disagree) { - DECPTR(sizeof(u32_t), p); - tl = lwip_ntohl(wo->ouraddr); - PUTLONG(tl, p); - } - } else { - wo->ouraddr = ciaddr2; /* accept peer's idea */ - } - } - - ho->old_addrs = 1; - ho->hisaddr = ciaddr1; - ho->ouraddr = ciaddr2; - break; - - case CI_ADDR: - if (!ao->neg_addr || ho->old_addrs || - cilen != CILEN_ADDR) { /* Check CI length */ - orc = CONFREJ; /* Reject CI */ - break; - } - - /* - * If he has no address, or if we both have his address but - * disagree about it, then NAK it with our idea. - * In particular, if we don't know his address, but he does, - * then accept it. - */ - GETLONG(tl, p); /* Parse source address (his) */ - ciaddr1 = lwip_htonl(tl); - if (ciaddr1 != wo->hisaddr - && (ciaddr1 == 0 || !wo->accept_remote)) { - orc = CONFNAK; - if (!reject_if_disagree) { - DECPTR(sizeof(u32_t), p); - tl = lwip_ntohl(wo->hisaddr); - PUTLONG(tl, p); - } - } else if (ciaddr1 == 0 && wo->hisaddr == 0) { - /* - * Don't ACK an address of 0.0.0.0 - reject it instead. - */ - orc = CONFREJ; - wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */ - break; - } - - ho->neg_addr = 1; - ho->hisaddr = ciaddr1; - break; - -#if LWIP_DNS - case CI_MS_DNS1: - case CI_MS_DNS2: - /* Microsoft primary or secondary DNS request */ - d = citype == CI_MS_DNS2; - - /* If we do not have a DNS address then we cannot send it */ - if (ao->dnsaddr[d] == 0 || - cilen != CILEN_ADDR) { /* Check CI length */ - orc = CONFREJ; /* Reject CI */ - break; - } - GETLONG(tl, p); - if (lwip_htonl(tl) != ao->dnsaddr[d]) { - DECPTR(sizeof(u32_t), p); - tl = lwip_ntohl(ao->dnsaddr[d]); - PUTLONG(tl, p); - orc = CONFNAK; - } - break; -#endif /* LWIP_DNS */ - -#if 0 /* UNUSED - WINS */ - case CI_MS_WINS1: - case CI_MS_WINS2: - /* Microsoft primary or secondary WINS request */ - d = citype == CI_MS_WINS2; - - /* If we do not have a DNS address then we cannot send it */ - if (ao->winsaddr[d] == 0 || - cilen != CILEN_ADDR) { /* Check CI length */ - orc = CONFREJ; /* Reject CI */ - break; - } - GETLONG(tl, p); - if (lwip_htonl(tl) != ao->winsaddr[d]) { - DECPTR(sizeof(u32_t), p); - tl = lwip_ntohl(ao->winsaddr[d]); - PUTLONG(tl, p); - orc = CONFNAK; - } - break; -#endif /* UNUSED - WINS */ - -#if VJ_SUPPORT - case CI_COMPRESSTYPE: - if (!ao->neg_vj || - (cilen != CILEN_VJ && cilen != CILEN_COMPRESS)) { - orc = CONFREJ; - break; - } - GETSHORT(cishort, p); - - if (!(cishort == IPCP_VJ_COMP || - (cishort == IPCP_VJ_COMP_OLD && cilen == CILEN_COMPRESS))) { - orc = CONFREJ; - break; - } - - ho->neg_vj = 1; - ho->vj_protocol = cishort; - if (cilen == CILEN_VJ) { - GETCHAR(maxslotindex, p); - if (maxslotindex > ao->maxslotindex) { - orc = CONFNAK; - if (!reject_if_disagree){ - DECPTR(1, p); - PUTCHAR(ao->maxslotindex, p); - } - } - GETCHAR(cflag, p); - if (cflag && !ao->cflag) { - orc = CONFNAK; - if (!reject_if_disagree){ - DECPTR(1, p); - PUTCHAR(wo->cflag, p); - } - } - ho->maxslotindex = maxslotindex; - ho->cflag = cflag; - } else { - ho->old_vj = 1; - ho->maxslotindex = MAX_STATES - 1; - ho->cflag = 1; - } - break; -#endif /* VJ_SUPPORT */ - - default: - orc = CONFREJ; - break; - } -endswitch: - if (orc == CONFACK && /* Good CI */ - rc != CONFACK) /* but prior CI wasnt? */ - continue; /* Don't send this one */ - - if (orc == CONFNAK) { /* Nak this CI? */ - if (reject_if_disagree) /* Getting fed up with sending NAKs? */ - orc = CONFREJ; /* Get tough if so */ - else { - if (rc == CONFREJ) /* Rejecting prior CI? */ - continue; /* Don't send this one */ - if (rc == CONFACK) { /* Ack'd all prior CIs? */ - rc = CONFNAK; /* Not anymore... */ - ucp = inp; /* Backup */ - } - } - } - - if (orc == CONFREJ && /* Reject this CI */ - rc != CONFREJ) { /* but no prior ones? */ - rc = CONFREJ; - ucp = inp; /* Backup */ - } - - /* Need to move CI? */ - if (ucp != cip) - MEMCPY(ucp, cip, cilen); /* Move it */ - - /* Update output pointer */ - INCPTR(cilen, ucp); - } - - /* - * If we aren't rejecting this packet, and we want to negotiate - * their address, and they didn't send their address, then we - * send a NAK with a CI_ADDR option appended. We assume the - * input buffer is long enough that we can append the extra - * option safely. - */ - if (rc != CONFREJ && !ho->neg_addr && !ho->old_addrs && - wo->req_addr && !reject_if_disagree && !pcb->settings.noremoteip) { - if (rc == CONFACK) { - rc = CONFNAK; - ucp = inp; /* reset pointer */ - wo->req_addr = 0; /* don't ask again */ - } - PUTCHAR(CI_ADDR, ucp); - PUTCHAR(CILEN_ADDR, ucp); - tl = lwip_ntohl(wo->hisaddr); - PUTLONG(tl, ucp); - } - - *len = ucp - inp; /* Compute output length */ - IPCPDEBUG(("ipcp: returning Configure-%s", CODENAME(rc))); - return (rc); /* Return final code */ -} - - -#if 0 /* UNUSED */ -/* - * ip_check_options - check that any IP-related options are OK, - * and assign appropriate defaults. - */ -static void -ip_check_options() -{ - struct hostent *hp; - u32_t local; - ipcp_options *wo = &ipcp_wantoptions[0]; - - /* - * Default our local IP address based on our hostname. - * If local IP address already given, don't bother. - */ - if (wo->ouraddr == 0 && !disable_defaultip) { - /* - * Look up our hostname (possibly with domain name appended) - * and take the first IP address as our local IP address. - * If there isn't an IP address for our hostname, too bad. - */ - wo->accept_local = 1; /* don't insist on this default value */ - if ((hp = gethostbyname(hostname)) != NULL) { - local = *(u32_t *)hp->h_addr; - if (local != 0 && !bad_ip_adrs(local)) - wo->ouraddr = local; - } - } - ask_for_local = wo->ouraddr != 0 || !disable_defaultip; -} -#endif /* UNUSED */ - -#if DEMAND_SUPPORT -/* - * ip_demand_conf - configure the interface as though - * IPCP were up, for use with dial-on-demand. - */ -static int -ip_demand_conf(u) - int u; -{ - ppp_pcb *pcb = &ppp_pcb_list[u]; - ipcp_options *wo = &ipcp_wantoptions[u]; - - if (wo->hisaddr == 0 && !pcb->settings.noremoteip) { - /* make up an arbitrary address for the peer */ - wo->hisaddr = lwip_htonl(0x0a707070 + ifunit); - wo->accept_remote = 1; - } - if (wo->ouraddr == 0) { - /* make up an arbitrary address for us */ - wo->ouraddr = lwip_htonl(0x0a404040 + ifunit); - wo->accept_local = 1; - ask_for_local = 0; /* don't tell the peer this address */ - } - if (!sifaddr(pcb, wo->ouraddr, wo->hisaddr, get_mask(wo->ouraddr))) - return 0; - if (!sifup(pcb)) - return 0; - if (!sifnpmode(pcb, PPP_IP, NPMODE_QUEUE)) - return 0; -#if 0 /* UNUSED */ - if (wo->default_route) - if (sifdefaultroute(pcb, wo->ouraddr, wo->hisaddr, - wo->replace_default_route)) - default_route_set[u] = 1; -#endif /* UNUSED */ -#if 0 /* UNUSED - PROXY ARP */ - if (wo->proxy_arp) - if (sifproxyarp(pcb, wo->hisaddr)) - proxy_arp_set[u] = 1; -#endif /* UNUSED - PROXY ARP */ - - ppp_notice("local IP address %I", wo->ouraddr); - if (wo->hisaddr) - ppp_notice("remote IP address %I", wo->hisaddr); - - return 1; -} -#endif /* DEMAND_SUPPORT */ - -/* - * ipcp_up - IPCP has come UP. - * - * Configure the IP network interface appropriately and bring it up. - */ -static void ipcp_up(fsm *f) { - ppp_pcb *pcb = f->pcb; - u32_t mask; - ipcp_options *ho = &pcb->ipcp_hisoptions; - ipcp_options *go = &pcb->ipcp_gotoptions; - ipcp_options *wo = &pcb->ipcp_wantoptions; - - IPCPDEBUG(("ipcp: up")); - - /* - * We must have a non-zero IP address for both ends of the link. - */ - if (!ho->neg_addr && !ho->old_addrs) - ho->hisaddr = wo->hisaddr; - - if (!(go->neg_addr || go->old_addrs) && (wo->neg_addr || wo->old_addrs) - && wo->ouraddr != 0) { - ppp_error("Peer refused to agree to our IP address"); - ipcp_close(f->pcb, "Refused our IP address"); - return; - } - if (go->ouraddr == 0) { - ppp_error("Could not determine local IP address"); - ipcp_close(f->pcb, "Could not determine local IP address"); - return; - } - if (ho->hisaddr == 0 && !pcb->settings.noremoteip) { - ho->hisaddr = lwip_htonl(0x0a404040); - ppp_warn("Could not determine remote IP address: defaulting to %I", - ho->hisaddr); - } -#if 0 /* UNUSED */ - script_setenv("IPLOCAL", ip_ntoa(go->ouraddr), 0); - if (ho->hisaddr != 0) - script_setenv("IPREMOTE", ip_ntoa(ho->hisaddr), 1); -#endif /* UNUSED */ - -#if LWIP_DNS - if (!go->req_dns1) - go->dnsaddr[0] = 0; - if (!go->req_dns2) - go->dnsaddr[1] = 0; -#if 0 /* UNUSED */ - if (go->dnsaddr[0]) - script_setenv("DNS1", ip_ntoa(go->dnsaddr[0]), 0); - if (go->dnsaddr[1]) - script_setenv("DNS2", ip_ntoa(go->dnsaddr[1]), 0); -#endif /* UNUSED */ - if (pcb->settings.usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) { - sdns(pcb, go->dnsaddr[0], go->dnsaddr[1]); -#if 0 /* UNUSED */ - script_setenv("USEPEERDNS", "1", 0); - create_resolv(go->dnsaddr[0], go->dnsaddr[1]); -#endif /* UNUSED */ - } -#endif /* LWIP_DNS */ - - /* - * Check that the peer is allowed to use the IP address it wants. - */ - if (ho->hisaddr != 0) { - u32_t addr = lwip_ntohl(ho->hisaddr); - if ((addr >> IP_CLASSA_NSHIFT) == IP_LOOPBACKNET - || IP_MULTICAST(addr) || IP_BADCLASS(addr) - /* - * For now, consider that PPP in server mode with peer required - * to authenticate must provide the peer IP address, reject any - * IP address wanted by peer different than the one we wanted. - */ -#if PPP_SERVER && PPP_AUTH_SUPPORT - || (pcb->settings.auth_required && wo->hisaddr != ho->hisaddr) -#endif /* PPP_SERVER && PPP_AUTH_SUPPORT */ - ) { - ppp_error("Peer is not authorized to use remote address %I", ho->hisaddr); - ipcp_close(pcb, "Unauthorized remote IP address"); - return; - } - } -#if 0 /* Unused */ - /* Upstream checking code */ - if (ho->hisaddr != 0 && !auth_ip_addr(f->unit, ho->hisaddr)) { - ppp_error("Peer is not authorized to use remote address %I", ho->hisaddr); - ipcp_close(f->unit, "Unauthorized remote IP address"); - return; - } -#endif /* Unused */ - -#if VJ_SUPPORT - /* set tcp compression */ - sifvjcomp(pcb, ho->neg_vj, ho->cflag, ho->maxslotindex); -#endif /* VJ_SUPPORT */ - -#if DEMAND_SUPPORT - /* - * If we are doing dial-on-demand, the interface is already - * configured, so we put out any saved-up packets, then set the - * interface to pass IP packets. - */ - if (demand) { - if (go->ouraddr != wo->ouraddr || ho->hisaddr != wo->hisaddr) { - ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr, - wo->replace_default_route); - if (go->ouraddr != wo->ouraddr) { - ppp_warn("Local IP address changed to %I", go->ouraddr); - script_setenv("OLDIPLOCAL", ip_ntoa(wo->ouraddr), 0); - wo->ouraddr = go->ouraddr; - } else - script_unsetenv("OLDIPLOCAL"); - if (ho->hisaddr != wo->hisaddr && wo->hisaddr != 0) { - ppp_warn("Remote IP address changed to %I", ho->hisaddr); - script_setenv("OLDIPREMOTE", ip_ntoa(wo->hisaddr), 0); - wo->hisaddr = ho->hisaddr; - } else - script_unsetenv("OLDIPREMOTE"); - - /* Set the interface to the new addresses */ - mask = get_mask(go->ouraddr); - if (!sifaddr(pcb, go->ouraddr, ho->hisaddr, mask)) { -#if PPP_DEBUG - ppp_warn("Interface configuration failed"); -#endif /* PPP_DEBUG */ - ipcp_close(f->unit, "Interface configuration failed"); - return; - } - - /* assign a default route through the interface if required */ - if (ipcp_wantoptions[f->unit].default_route) - if (sifdefaultroute(pcb, go->ouraddr, ho->hisaddr, - wo->replace_default_route)) - default_route_set[f->unit] = 1; - -#if 0 /* UNUSED - PROXY ARP */ - /* Make a proxy ARP entry if requested. */ - if (ho->hisaddr != 0 && ipcp_wantoptions[f->unit].proxy_arp) - if (sifproxyarp(pcb, ho->hisaddr)) - proxy_arp_set[f->unit] = 1; -#endif /* UNUSED - PROXY ARP */ - - } - demand_rexmit(PPP_IP,go->ouraddr); - sifnpmode(pcb, PPP_IP, NPMODE_PASS); - - } else -#endif /* DEMAND_SUPPORT */ - { - /* - * Set IP addresses and (if specified) netmask. - */ - mask = get_mask(go->ouraddr); - -#if !(defined(SVR4) && (defined(SNI) || defined(__USLC__))) - if (!sifaddr(pcb, go->ouraddr, ho->hisaddr, mask)) { -#if PPP_DEBUG - ppp_warn("Interface configuration failed"); -#endif /* PPP_DEBUG */ - ipcp_close(f->pcb, "Interface configuration failed"); - return; - } -#endif - - /* bring the interface up for IP */ - if (!sifup(pcb)) { -#if PPP_DEBUG - ppp_warn("Interface failed to come up"); -#endif /* PPP_DEBUG */ - ipcp_close(f->pcb, "Interface configuration failed"); - return; - } - -#if (defined(SVR4) && (defined(SNI) || defined(__USLC__))) - if (!sifaddr(pcb, go->ouraddr, ho->hisaddr, mask)) { -#if PPP_DEBUG - ppp_warn("Interface configuration failed"); -#endif /* PPP_DEBUG */ - ipcp_close(f->unit, "Interface configuration failed"); - return; - } -#endif -#if DEMAND_SUPPORT - sifnpmode(pcb, PPP_IP, NPMODE_PASS); -#endif /* DEMAND_SUPPORT */ - -#if 0 /* UNUSED */ - /* assign a default route through the interface if required */ - if (wo->default_route) - if (sifdefaultroute(pcb, go->ouraddr, ho->hisaddr, - wo->replace_default_route)) - pcb->default_route_set = 1; -#endif /* UNUSED */ - -#if 0 /* UNUSED - PROXY ARP */ - /* Make a proxy ARP entry if requested. */ - if (ho->hisaddr != 0 && wo->proxy_arp) - if (sifproxyarp(pcb, ho->hisaddr)) - pcb->proxy_arp_set = 1; -#endif /* UNUSED - PROXY ARP */ - - wo->ouraddr = go->ouraddr; - - ppp_notice("local IP address %I", go->ouraddr); - if (ho->hisaddr != 0) - ppp_notice("remote IP address %I", ho->hisaddr); -#if LWIP_DNS - if (go->dnsaddr[0]) - ppp_notice("primary DNS address %I", go->dnsaddr[0]); - if (go->dnsaddr[1]) - ppp_notice("secondary DNS address %I", go->dnsaddr[1]); -#endif /* LWIP_DNS */ - } - -#if PPP_STATS_SUPPORT - reset_link_stats(f->unit); -#endif /* PPP_STATS_SUPPORT */ - - np_up(pcb, PPP_IP); - pcb->ipcp_is_up = 1; - -#if PPP_NOTIFY - notify(ip_up_notifier, 0); -#endif /* PPP_NOTIFY */ -#if 0 /* UNUSED */ - if (ip_up_hook) - ip_up_hook(); -#endif /* UNUSED */ -} - - -/* - * ipcp_down - IPCP has gone DOWN. - * - * Take the IP network interface down, clear its addresses - * and delete routes through it. - */ -static void ipcp_down(fsm *f) { - ppp_pcb *pcb = f->pcb; - ipcp_options *ho = &pcb->ipcp_hisoptions; - ipcp_options *go = &pcb->ipcp_gotoptions; - - IPCPDEBUG(("ipcp: down")); -#if PPP_STATS_SUPPORT - /* XXX a bit IPv4-centric here, we only need to get the stats - * before the interface is marked down. */ - /* XXX more correct: we must get the stats before running the notifiers, - * at least for the radius plugin */ - update_link_stats(f->unit); -#endif /* PPP_STATS_SUPPORT */ -#if PPP_NOTIFY - notify(ip_down_notifier, 0); -#endif /* PPP_NOTIFY */ -#if 0 /* UNUSED */ - if (ip_down_hook) - ip_down_hook(); -#endif /* UNUSED */ - if (pcb->ipcp_is_up) { - pcb->ipcp_is_up = 0; - np_down(pcb, PPP_IP); - } -#if VJ_SUPPORT - sifvjcomp(pcb, 0, 0, 0); -#endif /* VJ_SUPPORT */ - -#if PPP_STATS_SUPPORT - print_link_stats(); /* _after_ running the notifiers and ip_down_hook(), - * because print_link_stats() sets link_stats_valid - * to 0 (zero) */ -#endif /* PPP_STATS_SUPPORT */ - -#if DEMAND_SUPPORT - /* - * If we are doing dial-on-demand, set the interface - * to queue up outgoing packets (for now). - */ - if (demand) { - sifnpmode(pcb, PPP_IP, NPMODE_QUEUE); - } else -#endif /* DEMAND_SUPPORT */ - { -#if DEMAND_SUPPORT - sifnpmode(pcb, PPP_IP, NPMODE_DROP); -#endif /* DEMAND_SUPPORT */ - sifdown(pcb); - ipcp_clear_addrs(pcb, go->ouraddr, - ho->hisaddr, 0); -#if LWIP_DNS - cdns(pcb, go->dnsaddr[0], go->dnsaddr[1]); -#endif /* LWIP_DNS */ - } -} - - -/* - * ipcp_clear_addrs() - clear the interface addresses, routes, - * proxy arp entries, etc. - */ -static void ipcp_clear_addrs(ppp_pcb *pcb, u32_t ouraddr, u32_t hisaddr, u8_t replacedefaultroute) { - LWIP_UNUSED_ARG(replacedefaultroute); - -#if 0 /* UNUSED - PROXY ARP */ - if (pcb->proxy_arp_set) { - cifproxyarp(pcb, hisaddr); - pcb->proxy_arp_set = 0; - } -#endif /* UNUSED - PROXY ARP */ -#if 0 /* UNUSED */ - /* If replacedefaultroute, sifdefaultroute will be called soon - * with replacedefaultroute set and that will overwrite the current - * default route. This is the case only when doing demand, otherwise - * during demand, this cifdefaultroute would restore the old default - * route which is not what we want in this case. In the non-demand - * case, we'll delete the default route and restore the old if there - * is one saved by an sifdefaultroute with replacedefaultroute. - */ - if (!replacedefaultroute && pcb->default_route_set) { - cifdefaultroute(pcb, ouraddr, hisaddr); - pcb->default_route_set = 0; - } -#endif /* UNUSED */ - cifaddr(pcb, ouraddr, hisaddr); -} - - -/* - * ipcp_finished - possibly shut down the lower layers. - */ -static void ipcp_finished(fsm *f) { - ppp_pcb *pcb = f->pcb; - if (pcb->ipcp_is_open) { - pcb->ipcp_is_open = 0; - np_finished(pcb, PPP_IP); - } -} - - -#if 0 /* UNUSED */ -/* - * create_resolv - create the replacement resolv.conf file - */ -static void -create_resolv(peerdns1, peerdns2) - u32_t peerdns1, peerdns2; -{ - -} -#endif /* UNUSED */ - -#if PRINTPKT_SUPPORT -/* - * ipcp_printpkt - print the contents of an IPCP packet. - */ -static const char* const ipcp_codenames[] = { - "ConfReq", "ConfAck", "ConfNak", "ConfRej", - "TermReq", "TermAck", "CodeRej" -}; - -static int ipcp_printpkt(const u_char *p, int plen, - void (*printer) (void *, const char *, ...), void *arg) { - int code, id, len, olen; - const u_char *pstart, *optend; -#if VJ_SUPPORT - u_short cishort; -#endif /* VJ_SUPPORT */ - u32_t cilong; - - if (plen < HEADERLEN) - return 0; - pstart = p; - GETCHAR(code, p); - GETCHAR(id, p); - GETSHORT(len, p); - if (len < HEADERLEN || len > plen) - return 0; - - if (code >= 1 && code <= (int)LWIP_ARRAYSIZE(ipcp_codenames)) - printer(arg, " %s", ipcp_codenames[code-1]); - else - printer(arg, " code=0x%x", code); - printer(arg, " id=0x%x", id); - len -= HEADERLEN; - switch (code) { - case CONFREQ: - case CONFACK: - case CONFNAK: - case CONFREJ: - /* print option list */ - while (len >= 2) { - GETCHAR(code, p); - GETCHAR(olen, p); - p -= 2; - if (olen < 2 || olen > len) { - break; - } - printer(arg, " <"); - len -= olen; - optend = p + olen; - switch (code) { - case CI_ADDRS: - if (olen == CILEN_ADDRS) { - p += 2; - GETLONG(cilong, p); - printer(arg, "addrs %I", lwip_htonl(cilong)); - GETLONG(cilong, p); - printer(arg, " %I", lwip_htonl(cilong)); - } - break; -#if VJ_SUPPORT - case CI_COMPRESSTYPE: - if (olen >= CILEN_COMPRESS) { - p += 2; - GETSHORT(cishort, p); - printer(arg, "compress "); - switch (cishort) { - case IPCP_VJ_COMP: - printer(arg, "VJ"); - break; - case IPCP_VJ_COMP_OLD: - printer(arg, "old-VJ"); - break; - default: - printer(arg, "0x%x", cishort); - } - } - break; -#endif /* VJ_SUPPORT */ - case CI_ADDR: - if (olen == CILEN_ADDR) { - p += 2; - GETLONG(cilong, p); - printer(arg, "addr %I", lwip_htonl(cilong)); - } - break; -#if LWIP_DNS - case CI_MS_DNS1: - case CI_MS_DNS2: - p += 2; - GETLONG(cilong, p); - printer(arg, "ms-dns%d %I", (code == CI_MS_DNS1? 1: 2), - htonl(cilong)); - break; -#endif /* LWIP_DNS */ -#if 0 /* UNUSED - WINS */ - case CI_MS_WINS1: - case CI_MS_WINS2: - p += 2; - GETLONG(cilong, p); - printer(arg, "ms-wins %I", lwip_htonl(cilong)); - break; -#endif /* UNUSED - WINS */ - default: - break; - } - while (p < optend) { - GETCHAR(code, p); - printer(arg, " %.2x", code); - } - printer(arg, ">"); - } - break; - - case TERMACK: - case TERMREQ: - if (len > 0 && *p >= ' ' && *p < 0x7f) { - printer(arg, " "); - ppp_print_string(p, len, printer, arg); - p += len; - len = 0; - } - break; - default: - break; - } - - /* print the rest of the bytes in the packet */ - for (; len > 0; --len) { - GETCHAR(code, p); - printer(arg, " %.2x", code); - } - - return p - pstart; -} -#endif /* PRINTPKT_SUPPORT */ - -#if DEMAND_SUPPORT -/* - * ip_active_pkt - see if this IP packet is worth bringing the link up for. - * We don't bring the link up for IP fragments or for TCP FIN packets - * with no data. - */ -#define IP_HDRLEN 20 /* bytes */ -#define IP_OFFMASK 0x1fff -#ifndef IPPROTO_TCP -#define IPPROTO_TCP 6 -#endif -#define TCP_HDRLEN 20 -#define TH_FIN 0x01 - -/* - * We use these macros because the IP header may be at an odd address, - * and some compilers might use word loads to get th_off or ip_hl. - */ - -#define net_short(x) (((x)[0] << 8) + (x)[1]) -#define get_iphl(x) (((unsigned char *)(x))[0] & 0xF) -#define get_ipoff(x) net_short((unsigned char *)(x) + 6) -#define get_ipproto(x) (((unsigned char *)(x))[9]) -#define get_tcpoff(x) (((unsigned char *)(x))[12] >> 4) -#define get_tcpflags(x) (((unsigned char *)(x))[13]) - -static int -ip_active_pkt(pkt, len) - u_char *pkt; - int len; -{ - u_char *tcp; - int hlen; - - len -= PPP_HDRLEN; - pkt += PPP_HDRLEN; - if (len < IP_HDRLEN) - return 0; - if ((get_ipoff(pkt) & IP_OFFMASK) != 0) - return 0; - if (get_ipproto(pkt) != IPPROTO_TCP) - return 1; - hlen = get_iphl(pkt) * 4; - if (len < hlen + TCP_HDRLEN) - return 0; - tcp = pkt + hlen; - if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == hlen + get_tcpoff(tcp) * 4) - return 0; - return 1; -} -#endif /* DEMAND_SUPPORT */ - -#endif /* PPP_SUPPORT && PPP_IPV4_SUPPORT */ diff --git a/third-party/lwip-2.1.2/netif/ppp/ipv6cp.c b/third-party/lwip-2.1.2/netif/ppp/ipv6cp.c deleted file mode 100644 index 11c18df7..00000000 --- a/third-party/lwip-2.1.2/netif/ppp/ipv6cp.c +++ /dev/null @@ -1,1533 +0,0 @@ -/* - * ipv6cp.c - PPP IPV6 Control Protocol. - * - * Copyright (c) 1999 Tommi Komulainen. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Tommi Komulainen - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -/* Original version, based on RFC2023 : - - Copyright (c) 1995, 1996, 1997 Francis.Dupont@inria.fr, INRIA Rocquencourt, - Alain.Durand@imag.fr, IMAG, - Jean-Luc.Richier@imag.fr, IMAG-LSR. - - Copyright (c) 1998, 1999 Francis.Dupont@inria.fr, GIE DYADE, - Alain.Durand@imag.fr, IMAG, - Jean-Luc.Richier@imag.fr, IMAG-LSR. - - Ce travail a été fait au sein du GIE DYADE (Groupement d'Intérêt - Économique ayant pour membres BULL S.A. et l'INRIA). - - Ce logiciel informatique est disponible aux conditions - usuelles dans la recherche, c'est-à-dire qu'il peut - être utilisé, copié, modifié, distribué à l'unique - condition que ce texte soit conservé afin que - l'origine de ce logiciel soit reconnue. - - Le nom de l'Institut National de Recherche en Informatique - et en Automatique (INRIA), de l'IMAG, ou d'une personne morale - ou physique ayant participé à l'élaboration de ce logiciel ne peut - être utilisé sans son accord préalable explicite. - - Ce logiciel est fourni tel quel sans aucune garantie, - support ou responsabilité d'aucune sorte. - Ce logiciel est dérivé de sources d'origine - "University of California at Berkeley" et - "Digital Equipment Corporation" couvertes par des copyrights. - - L'Institut d'Informatique et de Mathématiques Appliquées de Grenoble (IMAG) - est une fédération d'unités mixtes de recherche du CNRS, de l'Institut National - Polytechnique de Grenoble et de l'Université Joseph Fourier regroupant - sept laboratoires dont le laboratoire Logiciels, Systèmes, Réseaux (LSR). - - This work has been done in the context of GIE DYADE (joint R & D venture - between BULL S.A. and INRIA). - - This software is available with usual "research" terms - with the aim of retain credits of the software. - Permission to use, copy, modify and distribute this software for any - purpose and without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies, - and the name of INRIA, IMAG, or any contributor not be used in advertising - or publicity pertaining to this material without the prior explicit - permission. The software is provided "as is" without any - warranties, support or liabilities of any kind. - This software is derived from source code from - "University of California at Berkeley" and - "Digital Equipment Corporation" protected by copyrights. - - Grenoble's Institute of Computer Science and Applied Mathematics (IMAG) - is a federation of seven research units funded by the CNRS, National - Polytechnic Institute of Grenoble and University Joseph Fourier. - The research unit in Software, Systems, Networks (LSR) is member of IMAG. -*/ - -/* - * Derived from : - * - * - * ipcp.c - PPP IP Control Protocol. - * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * $Id: ipv6cp.c,v 1.21 2005/08/25 23:59:34 paulus Exp $ - */ - -/* - * @todo: - * - * Proxy Neighbour Discovery. - * - * Better defines for selecting the ordering of - * interface up / set address. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && PPP_IPV6_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#if 0 /* UNUSED */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#endif /* UNUSED */ - -#include "netif/ppp/ppp_impl.h" -#include "netif/ppp/fsm.h" -#include "netif/ppp/ipcp.h" -#include "netif/ppp/ipv6cp.h" -#include "netif/ppp/magic.h" - -/* global vars */ -#if 0 /* UNUSED */ -int no_ifaceid_neg = 0; -#endif /* UNUSED */ - -/* - * Callbacks for fsm code. (CI = Configuration Information) - */ -static void ipv6cp_resetci(fsm *f); /* Reset our CI */ -static int ipv6cp_cilen(fsm *f); /* Return length of our CI */ -static void ipv6cp_addci(fsm *f, u_char *ucp, int *lenp); /* Add our CI */ -static int ipv6cp_ackci(fsm *f, u_char *p, int len); /* Peer ack'd our CI */ -static int ipv6cp_nakci(fsm *f, u_char *p, int len, int treat_as_reject); /* Peer nak'd our CI */ -static int ipv6cp_rejci(fsm *f, u_char *p, int len); /* Peer rej'd our CI */ -static int ipv6cp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree); /* Rcv CI */ -static void ipv6cp_up(fsm *f); /* We're UP */ -static void ipv6cp_down(fsm *f); /* We're DOWN */ -static void ipv6cp_finished(fsm *f); /* Don't need lower layer */ - -static const fsm_callbacks ipv6cp_callbacks = { /* IPV6CP callback routines */ - ipv6cp_resetci, /* Reset our Configuration Information */ - ipv6cp_cilen, /* Length of our Configuration Information */ - ipv6cp_addci, /* Add our Configuration Information */ - ipv6cp_ackci, /* ACK our Configuration Information */ - ipv6cp_nakci, /* NAK our Configuration Information */ - ipv6cp_rejci, /* Reject our Configuration Information */ - ipv6cp_reqci, /* Request peer's Configuration Information */ - ipv6cp_up, /* Called when fsm reaches OPENED state */ - ipv6cp_down, /* Called when fsm leaves OPENED state */ - NULL, /* Called when we want the lower layer up */ - ipv6cp_finished, /* Called when we want the lower layer down */ - NULL, /* Called when Protocol-Reject received */ - NULL, /* Retransmission is necessary */ - NULL, /* Called to handle protocol-specific codes */ - "IPV6CP" /* String name of protocol */ -}; - -#if PPP_OPTIONS -/* - * Command-line options. - */ -static int setifaceid(char **arg)); -static void printifaceid(option_t *, - void (*)(void *, char *, ...), void *)); - -static option_t ipv6cp_option_list[] = { - { "ipv6", o_special, (void *)setifaceid, - "Set interface identifiers for IPV6", - OPT_A2PRINTER, (void *)printifaceid }, - - { "+ipv6", o_bool, &ipv6cp_protent.enabled_flag, - "Enable IPv6 and IPv6CP", OPT_PRIO | 1 }, - { "noipv6", o_bool, &ipv6cp_protent.enabled_flag, - "Disable IPv6 and IPv6CP", OPT_PRIOSUB }, - { "-ipv6", o_bool, &ipv6cp_protent.enabled_flag, - "Disable IPv6 and IPv6CP", OPT_PRIOSUB | OPT_ALIAS }, - - { "ipv6cp-accept-local", o_bool, &ipv6cp_allowoptions[0].accept_local, - "Accept peer's interface identifier for us", 1 }, - - { "ipv6cp-use-ipaddr", o_bool, &ipv6cp_allowoptions[0].use_ip, - "Use (default) IPv4 address as interface identifier", 1 }, - - { "ipv6cp-use-persistent", o_bool, &ipv6cp_wantoptions[0].use_persistent, - "Use uniquely-available persistent value for link local address", 1 }, - - { "ipv6cp-restart", o_int, &ipv6cp_fsm[0].timeouttime, - "Set timeout for IPv6CP", OPT_PRIO }, - { "ipv6cp-max-terminate", o_int, &ipv6cp_fsm[0].maxtermtransmits, - "Set max #xmits for term-reqs", OPT_PRIO }, - { "ipv6cp-max-configure", o_int, &ipv6cp_fsm[0].maxconfreqtransmits, - "Set max #xmits for conf-reqs", OPT_PRIO }, - { "ipv6cp-max-failure", o_int, &ipv6cp_fsm[0].maxnakloops, - "Set max #conf-naks for IPv6CP", OPT_PRIO }, - - { NULL } -}; -#endif /* PPP_OPTIONS */ - -/* - * Protocol entry points from main code. - */ -static void ipv6cp_init(ppp_pcb *pcb); -static void ipv6cp_open(ppp_pcb *pcb); -static void ipv6cp_close(ppp_pcb *pcb, const char *reason); -static void ipv6cp_lowerup(ppp_pcb *pcb); -static void ipv6cp_lowerdown(ppp_pcb *pcb); -static void ipv6cp_input(ppp_pcb *pcb, u_char *p, int len); -static void ipv6cp_protrej(ppp_pcb *pcb); -#if PPP_OPTIONS -static void ipv6_check_options(void); -#endif /* PPP_OPTIONS */ -#if DEMAND_SUPPORT -static int ipv6_demand_conf(int u); -#endif /* DEMAND_SUPPORT */ -#if PRINTPKT_SUPPORT -static int ipv6cp_printpkt(const u_char *p, int plen, - void (*printer)(void *, const char *, ...), void *arg); -#endif /* PRINTPKT_SUPPORT */ -#if DEMAND_SUPPORT -static int ipv6_active_pkt(u_char *pkt, int len); -#endif /* DEMAND_SUPPORT */ - -const struct protent ipv6cp_protent = { - PPP_IPV6CP, - ipv6cp_init, - ipv6cp_input, - ipv6cp_protrej, - ipv6cp_lowerup, - ipv6cp_lowerdown, - ipv6cp_open, - ipv6cp_close, -#if PRINTPKT_SUPPORT - ipv6cp_printpkt, -#endif /* PRINTPKT_SUPPORT */ -#if PPP_DATAINPUT - NULL, -#endif /* PPP_DATAINPUT */ -#if PRINTPKT_SUPPORT - "IPV6CP", - "IPV6", -#endif /* PRINTPKT_SUPPORT */ -#if PPP_OPTIONS - ipv6cp_option_list, - ipv6_check_options, -#endif /* PPP_OPTIONS */ -#if DEMAND_SUPPORT - ipv6_demand_conf, - ipv6_active_pkt -#endif /* DEMAND_SUPPORT */ -}; - -static void ipv6cp_clear_addrs(ppp_pcb *pcb, eui64_t ourid, eui64_t hisid); -#if 0 /* UNUSED */ -static void ipv6cp_script(char *)); -static void ipv6cp_script_done(void *)); -#endif /* UNUSED */ - -/* - * Lengths of configuration options. - */ -#define CILEN_VOID 2 -#define CILEN_COMPRESS 4 /* length for RFC2023 compress opt. */ -#define CILEN_IFACEID 10 /* RFC2472, interface identifier */ - -#define CODENAME(x) ((x) == CONFACK ? "ACK" : \ - (x) == CONFNAK ? "NAK" : "REJ") - -#if 0 /* UNUSED */ -/* - * This state variable is used to ensure that we don't - * run an ipcp-up/down script while one is already running. - */ -static enum script_state { - s_down, - s_up, -} ipv6cp_script_state; -static pid_t ipv6cp_script_pid; -#endif /* UNUSED */ - -static char *llv6_ntoa(eui64_t ifaceid); - -#if PPP_OPTIONS -/* - * setifaceid - set the interface identifiers manually - */ -static int -setifaceid(argv) - char **argv; -{ - char *comma, *arg, c; - ipv6cp_options *wo = &ipv6cp_wantoptions[0]; - struct in6_addr addr; - static int prio_local, prio_remote; - -#define VALIDID(a) ( (((a).s6_addr32[0] == 0) && ((a).s6_addr32[1] == 0)) && \ - (((a).s6_addr32[2] != 0) || ((a).s6_addr32[3] != 0)) ) - - arg = *argv; - if ((comma = strchr(arg, ',')) == NULL) - comma = arg + strlen(arg); - - /* - * If comma first character, then no local identifier - */ - if (comma != arg) { - c = *comma; - *comma = '\0'; - - if (inet_pton(AF_INET6, arg, &addr) == 0 || !VALIDID(addr)) { - option_error("Illegal interface identifier (local): %s", arg); - return 0; - } - - if (option_priority >= prio_local) { - eui64_copy(addr.s6_addr32[2], wo->ourid); - wo->opt_local = 1; - prio_local = option_priority; - } - *comma = c; - } - - /* - * If comma last character, the no remote identifier - */ - if (*comma != 0 && *++comma != '\0') { - if (inet_pton(AF_INET6, comma, &addr) == 0 || !VALIDID(addr)) { - option_error("Illegal interface identifier (remote): %s", comma); - return 0; - } - if (option_priority >= prio_remote) { - eui64_copy(addr.s6_addr32[2], wo->hisid); - wo->opt_remote = 1; - prio_remote = option_priority; - } - } - - if (override_value("+ipv6", option_priority, option_source)) - ipv6cp_protent.enabled_flag = 1; - return 1; -} - -static void -printifaceid(opt, printer, arg) - option_t *opt; - void (*printer)(void *, char *, ...)); - void *arg; -{ - ipv6cp_options *wo = &ipv6cp_wantoptions[0]; - - if (wo->opt_local) - printer(arg, "%s", llv6_ntoa(wo->ourid)); - printer(arg, ","); - if (wo->opt_remote) - printer(arg, "%s", llv6_ntoa(wo->hisid)); -} -#endif /* PPP_OPTIONS */ - -/* - * Make a string representation of a network address. - */ -static char * -llv6_ntoa(eui64_t ifaceid) -{ - static char b[26]; - - sprintf(b, "fe80::%02x%02x:%02x%02x:%02x%02x:%02x%02x", - ifaceid.e8[0], ifaceid.e8[1], ifaceid.e8[2], ifaceid.e8[3], - ifaceid.e8[4], ifaceid.e8[5], ifaceid.e8[6], ifaceid.e8[7]); - - return b; -} - - -/* - * ipv6cp_init - Initialize IPV6CP. - */ -static void ipv6cp_init(ppp_pcb *pcb) { - fsm *f = &pcb->ipv6cp_fsm; - ipv6cp_options *wo = &pcb->ipv6cp_wantoptions; - ipv6cp_options *ao = &pcb->ipv6cp_allowoptions; - - f->pcb = pcb; - f->protocol = PPP_IPV6CP; - f->callbacks = &ipv6cp_callbacks; - fsm_init(f); - -#if 0 /* Not necessary, everything is cleared in ppp_new() */ - memset(wo, 0, sizeof(*wo)); - memset(ao, 0, sizeof(*ao)); -#endif /* 0 */ - - wo->accept_local = 1; - wo->neg_ifaceid = 1; - ao->neg_ifaceid = 1; - -#ifdef IPV6CP_COMP - wo->neg_vj = 1; - ao->neg_vj = 1; - wo->vj_protocol = IPV6CP_COMP; -#endif - -} - - -/* - * ipv6cp_open - IPV6CP is allowed to come up. - */ -static void ipv6cp_open(ppp_pcb *pcb) { - fsm_open(&pcb->ipv6cp_fsm); -} - - -/* - * ipv6cp_close - Take IPV6CP down. - */ -static void ipv6cp_close(ppp_pcb *pcb, const char *reason) { - fsm_close(&pcb->ipv6cp_fsm, reason); -} - - -/* - * ipv6cp_lowerup - The lower layer is up. - */ -static void ipv6cp_lowerup(ppp_pcb *pcb) { - fsm_lowerup(&pcb->ipv6cp_fsm); -} - - -/* - * ipv6cp_lowerdown - The lower layer is down. - */ -static void ipv6cp_lowerdown(ppp_pcb *pcb) { - fsm_lowerdown(&pcb->ipv6cp_fsm); -} - - -/* - * ipv6cp_input - Input IPV6CP packet. - */ -static void ipv6cp_input(ppp_pcb *pcb, u_char *p, int len) { - fsm_input(&pcb->ipv6cp_fsm, p, len); -} - - -/* - * ipv6cp_protrej - A Protocol-Reject was received for IPV6CP. - * - * Pretend the lower layer went down, so we shut up. - */ -static void ipv6cp_protrej(ppp_pcb *pcb) { - fsm_lowerdown(&pcb->ipv6cp_fsm); -} - - -/* - * ipv6cp_resetci - Reset our CI. - */ -static void ipv6cp_resetci(fsm *f) { - ppp_pcb *pcb = f->pcb; - ipv6cp_options *wo = &pcb->ipv6cp_wantoptions; - ipv6cp_options *go = &pcb->ipv6cp_gotoptions; - ipv6cp_options *ao = &pcb->ipv6cp_allowoptions; - - wo->req_ifaceid = wo->neg_ifaceid && ao->neg_ifaceid; - - if (!wo->opt_local) { - eui64_magic_nz(wo->ourid); - } - - *go = *wo; - eui64_zero(go->hisid); /* last proposed interface identifier */ -} - - -/* - * ipv6cp_cilen - Return length of our CI. - */ -static int ipv6cp_cilen(fsm *f) { - ppp_pcb *pcb = f->pcb; - ipv6cp_options *go = &pcb->ipv6cp_gotoptions; - -#ifdef IPV6CP_COMP -#define LENCIVJ(neg) (neg ? CILEN_COMPRESS : 0) -#endif /* IPV6CP_COMP */ -#define LENCIIFACEID(neg) (neg ? CILEN_IFACEID : 0) - - return (LENCIIFACEID(go->neg_ifaceid) + -#ifdef IPV6CP_COMP - LENCIVJ(go->neg_vj) + -#endif /* IPV6CP_COMP */ - 0); -} - - -/* - * ipv6cp_addci - Add our desired CIs to a packet. - */ -static void ipv6cp_addci(fsm *f, u_char *ucp, int *lenp) { - ppp_pcb *pcb = f->pcb; - ipv6cp_options *go = &pcb->ipv6cp_gotoptions; - int len = *lenp; - -#ifdef IPV6CP_COMP -#define ADDCIVJ(opt, neg, val) \ - if (neg) { \ - int vjlen = CILEN_COMPRESS; \ - if (len >= vjlen) { \ - PUTCHAR(opt, ucp); \ - PUTCHAR(vjlen, ucp); \ - PUTSHORT(val, ucp); \ - len -= vjlen; \ - } else \ - neg = 0; \ - } -#endif /* IPV6CP_COMP */ - -#define ADDCIIFACEID(opt, neg, val1) \ - if (neg) { \ - int idlen = CILEN_IFACEID; \ - if (len >= idlen) { \ - PUTCHAR(opt, ucp); \ - PUTCHAR(idlen, ucp); \ - eui64_put(val1, ucp); \ - len -= idlen; \ - } else \ - neg = 0; \ - } - - ADDCIIFACEID(CI_IFACEID, go->neg_ifaceid, go->ourid); - -#ifdef IPV6CP_COMP - ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol); -#endif /* IPV6CP_COMP */ - - *lenp -= len; -} - - -/* - * ipv6cp_ackci - Ack our CIs. - * - * Returns: - * 0 - Ack was bad. - * 1 - Ack was good. - */ -static int ipv6cp_ackci(fsm *f, u_char *p, int len) { - ppp_pcb *pcb = f->pcb; - ipv6cp_options *go = &pcb->ipv6cp_gotoptions; - u_short cilen, citype; -#ifdef IPV6CP_COMP - u_short cishort; -#endif /* IPV6CP_COMP */ - eui64_t ifaceid; - - /* - * CIs must be in exactly the same order that we sent... - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ - -#ifdef IPV6CP_COMP -#define ACKCIVJ(opt, neg, val) \ - if (neg) { \ - int vjlen = CILEN_COMPRESS; \ - if ((len -= vjlen) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != vjlen || \ - citype != opt) \ - goto bad; \ - GETSHORT(cishort, p); \ - if (cishort != val) \ - goto bad; \ - } -#endif /* IPV6CP_COMP */ - -#define ACKCIIFACEID(opt, neg, val1) \ - if (neg) { \ - int idlen = CILEN_IFACEID; \ - if ((len -= idlen) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != idlen || \ - citype != opt) \ - goto bad; \ - eui64_get(ifaceid, p); \ - if (! eui64_equals(val1, ifaceid)) \ - goto bad; \ - } - - ACKCIIFACEID(CI_IFACEID, go->neg_ifaceid, go->ourid); - -#ifdef IPV6CP_COMP - ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol); -#endif /* IPV6CP_COMP */ - - /* - * If there are any remaining CIs, then this packet is bad. - */ - if (len != 0) - goto bad; - return (1); - -bad: - IPV6CPDEBUG(("ipv6cp_ackci: received bad Ack!")); - return (0); -} - -/* - * ipv6cp_nakci - Peer has sent a NAK for some of our CIs. - * This should not modify any state if the Nak is bad - * or if IPV6CP is in the OPENED state. - * - * Returns: - * 0 - Nak was bad. - * 1 - Nak was good. - */ -static int ipv6cp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { - ppp_pcb *pcb = f->pcb; - ipv6cp_options *go = &pcb->ipv6cp_gotoptions; - u_char citype, cilen, *next; -#ifdef IPV6CP_COMP - u_short cishort; -#endif /* IPV6CP_COMP */ - eui64_t ifaceid; - ipv6cp_options no; /* options we've seen Naks for */ - ipv6cp_options try_; /* options to request next time */ - - BZERO(&no, sizeof(no)); - try_ = *go; - - /* - * Any Nak'd CIs must be in exactly the same order that we sent. - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ -#define NAKCIIFACEID(opt, neg, code) \ - if (go->neg && \ - len >= (cilen = CILEN_IFACEID) && \ - p[1] == cilen && \ - p[0] == opt) { \ - len -= cilen; \ - INCPTR(2, p); \ - eui64_get(ifaceid, p); \ - no.neg = 1; \ - code \ - } - -#ifdef IPV6CP_COMP -#define NAKCIVJ(opt, neg, code) \ - if (go->neg && \ - ((cilen = p[1]) == CILEN_COMPRESS) && \ - len >= cilen && \ - p[0] == opt) { \ - len -= cilen; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - no.neg = 1; \ - code \ - } -#endif /* IPV6CP_COMP */ - - /* - * Accept the peer's idea of {our,his} interface identifier, if different - * from our idea, only if the accept_{local,remote} flag is set. - */ - NAKCIIFACEID(CI_IFACEID, neg_ifaceid, - if (treat_as_reject) { - try_.neg_ifaceid = 0; - } else if (go->accept_local) { - while (eui64_iszero(ifaceid) || - eui64_equals(ifaceid, go->hisid)) /* bad luck */ - eui64_magic(ifaceid); - try_.ourid = ifaceid; - IPV6CPDEBUG(("local LL address %s", llv6_ntoa(ifaceid))); - } - ); - -#ifdef IPV6CP_COMP - NAKCIVJ(CI_COMPRESSTYPE, neg_vj, - { - if (cishort == IPV6CP_COMP && !treat_as_reject) { - try_.vj_protocol = cishort; - } else { - try_.neg_vj = 0; - } - } - ); -#endif /* IPV6CP_COMP */ - - /* - * There may be remaining CIs, if the peer is requesting negotiation - * on an option that we didn't include in our request packet. - * If they want to negotiate about interface identifier, we comply. - * If they want us to ask for compression, we refuse. - */ - while (len >= CILEN_VOID) { - GETCHAR(citype, p); - GETCHAR(cilen, p); - if ( cilen < CILEN_VOID || (len -= cilen) < 0 ) - goto bad; - next = p + cilen - 2; - - switch (citype) { -#ifdef IPV6CP_COMP - case CI_COMPRESSTYPE: - if (go->neg_vj || no.neg_vj || - (cilen != CILEN_COMPRESS)) - goto bad; - no.neg_vj = 1; - break; -#endif /* IPV6CP_COMP */ - case CI_IFACEID: - if (go->neg_ifaceid || no.neg_ifaceid || cilen != CILEN_IFACEID) - goto bad; - try_.neg_ifaceid = 1; - eui64_get(ifaceid, p); - if (go->accept_local) { - while (eui64_iszero(ifaceid) || - eui64_equals(ifaceid, go->hisid)) /* bad luck */ - eui64_magic(ifaceid); - try_.ourid = ifaceid; - } - no.neg_ifaceid = 1; - break; - default: - break; - } - p = next; - } - - /* If there is still anything left, this packet is bad. */ - if (len != 0) - goto bad; - - /* - * OK, the Nak is good. Now we can update state. - */ - if (f->state != PPP_FSM_OPENED) - *go = try_; - - return 1; - -bad: - IPV6CPDEBUG(("ipv6cp_nakci: received bad Nak!")); - return 0; -} - - -/* - * ipv6cp_rejci - Reject some of our CIs. - */ -static int ipv6cp_rejci(fsm *f, u_char *p, int len) { - ppp_pcb *pcb = f->pcb; - ipv6cp_options *go = &pcb->ipv6cp_gotoptions; - u_char cilen; -#ifdef IPV6CP_COMP - u_short cishort; -#endif /* IPV6CP_COMP */ - eui64_t ifaceid; - ipv6cp_options try_; /* options to request next time */ - - try_ = *go; - /* - * Any Rejected CIs must be in exactly the same order that we sent. - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ -#define REJCIIFACEID(opt, neg, val1) \ - if (go->neg && \ - len >= (cilen = CILEN_IFACEID) && \ - p[1] == cilen && \ - p[0] == opt) { \ - len -= cilen; \ - INCPTR(2, p); \ - eui64_get(ifaceid, p); \ - /* Check rejected value. */ \ - if (! eui64_equals(ifaceid, val1)) \ - goto bad; \ - try_.neg = 0; \ - } - -#ifdef IPV6CP_COMP -#define REJCIVJ(opt, neg, val) \ - if (go->neg && \ - p[1] == CILEN_COMPRESS && \ - len >= p[1] && \ - p[0] == opt) { \ - len -= p[1]; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - /* Check rejected value. */ \ - if (cishort != val) \ - goto bad; \ - try_.neg = 0; \ - } -#endif /* IPV6CP_COMP */ - - REJCIIFACEID(CI_IFACEID, neg_ifaceid, go->ourid); - -#ifdef IPV6CP_COMP - REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol); -#endif /* IPV6CP_COMP */ - - /* - * If there are any remaining CIs, then this packet is bad. - */ - if (len != 0) - goto bad; - /* - * Now we can update state. - */ - if (f->state != PPP_FSM_OPENED) - *go = try_; - return 1; - -bad: - IPV6CPDEBUG(("ipv6cp_rejci: received bad Reject!")); - return 0; -} - - -/* - * ipv6cp_reqci - Check the peer's requested CIs and send appropriate response. - * - * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified - * appropriately. If reject_if_disagree is non-zero, doesn't return - * CONFNAK; returns CONFREJ if it can't return CONFACK. - * - * inp = Requested CIs - * len = Length of requested CIs - * - */ -static int ipv6cp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree) { - ppp_pcb *pcb = f->pcb; - ipv6cp_options *wo = &pcb->ipv6cp_wantoptions; - ipv6cp_options *ho = &pcb->ipv6cp_hisoptions; - ipv6cp_options *ao = &pcb->ipv6cp_allowoptions; - ipv6cp_options *go = &pcb->ipv6cp_gotoptions; - u_char *cip, *next; /* Pointer to current and next CIs */ - u_short cilen, citype; /* Parsed len, type */ -#ifdef IPV6CP_COMP - u_short cishort; /* Parsed short value */ -#endif /* IPV6CP_COMP */ - eui64_t ifaceid; /* Parsed interface identifier */ - int rc = CONFACK; /* Final packet return code */ - int orc; /* Individual option return code */ - u_char *p; /* Pointer to next char to parse */ - u_char *ucp = inp; /* Pointer to current output char */ - int l = *len; /* Length left */ - - /* - * Reset all his options. - */ - BZERO(ho, sizeof(*ho)); - - /* - * Process all his options. - */ - next = inp; - while (l) { - orc = CONFACK; /* Assume success */ - cip = p = next; /* Remember begining of CI */ - if (l < 2 || /* Not enough data for CI header or */ - p[1] < 2 || /* CI length too small or */ - p[1] > l) { /* CI length too big? */ - IPV6CPDEBUG(("ipv6cp_reqci: bad CI length!")); - orc = CONFREJ; /* Reject bad CI */ - cilen = l; /* Reject till end of packet */ - l = 0; /* Don't loop again */ - goto endswitch; - } - GETCHAR(citype, p); /* Parse CI type */ - GETCHAR(cilen, p); /* Parse CI length */ - l -= cilen; /* Adjust remaining length */ - next += cilen; /* Step to next CI */ - - switch (citype) { /* Check CI type */ - case CI_IFACEID: - IPV6CPDEBUG(("ipv6cp: received interface identifier ")); - - if (!ao->neg_ifaceid || - cilen != CILEN_IFACEID) { /* Check CI length */ - orc = CONFREJ; /* Reject CI */ - break; - } - - /* - * If he has no interface identifier, or if we both have same - * identifier then NAK it with new idea. - * In particular, if we don't know his identifier, but he does, - * then accept it. - */ - eui64_get(ifaceid, p); - IPV6CPDEBUG(("(%s)", llv6_ntoa(ifaceid))); - if (eui64_iszero(ifaceid) && eui64_iszero(go->ourid)) { - orc = CONFREJ; /* Reject CI */ - break; - } - if (!eui64_iszero(wo->hisid) && - !eui64_equals(ifaceid, wo->hisid) && - eui64_iszero(go->hisid)) { - - orc = CONFNAK; - ifaceid = wo->hisid; - go->hisid = ifaceid; - DECPTR(sizeof(ifaceid), p); - eui64_put(ifaceid, p); - } else - if (eui64_iszero(ifaceid) || eui64_equals(ifaceid, go->ourid)) { - orc = CONFNAK; - if (eui64_iszero(go->hisid)) /* first time, try option */ - ifaceid = wo->hisid; - while (eui64_iszero(ifaceid) || - eui64_equals(ifaceid, go->ourid)) /* bad luck */ - eui64_magic(ifaceid); - go->hisid = ifaceid; - DECPTR(sizeof(ifaceid), p); - eui64_put(ifaceid, p); - } - - ho->neg_ifaceid = 1; - ho->hisid = ifaceid; - break; - -#ifdef IPV6CP_COMP - case CI_COMPRESSTYPE: - IPV6CPDEBUG(("ipv6cp: received COMPRESSTYPE ")); - if (!ao->neg_vj || - (cilen != CILEN_COMPRESS)) { - orc = CONFREJ; - break; - } - GETSHORT(cishort, p); - IPV6CPDEBUG(("(%d)", cishort)); - - if (!(cishort == IPV6CP_COMP)) { - orc = CONFREJ; - break; - } - - ho->neg_vj = 1; - ho->vj_protocol = cishort; - break; -#endif /* IPV6CP_COMP */ - - default: - orc = CONFREJ; - break; - } - -endswitch: - IPV6CPDEBUG((" (%s)\n", CODENAME(orc))); - - if (orc == CONFACK && /* Good CI */ - rc != CONFACK) /* but prior CI wasnt? */ - continue; /* Don't send this one */ - - if (orc == CONFNAK) { /* Nak this CI? */ - if (reject_if_disagree) /* Getting fed up with sending NAKs? */ - orc = CONFREJ; /* Get tough if so */ - else { - if (rc == CONFREJ) /* Rejecting prior CI? */ - continue; /* Don't send this one */ - if (rc == CONFACK) { /* Ack'd all prior CIs? */ - rc = CONFNAK; /* Not anymore... */ - ucp = inp; /* Backup */ - } - } - } - - if (orc == CONFREJ && /* Reject this CI */ - rc != CONFREJ) { /* but no prior ones? */ - rc = CONFREJ; - ucp = inp; /* Backup */ - } - - /* Need to move CI? */ - if (ucp != cip) - MEMCPY(ucp, cip, cilen); /* Move it */ - - /* Update output pointer */ - INCPTR(cilen, ucp); - } - - /* - * If we aren't rejecting this packet, and we want to negotiate - * their identifier and they didn't send their identifier, then we - * send a NAK with a CI_IFACEID option appended. We assume the - * input buffer is long enough that we can append the extra - * option safely. - */ - if (rc != CONFREJ && !ho->neg_ifaceid && - wo->req_ifaceid && !reject_if_disagree) { - if (rc == CONFACK) { - rc = CONFNAK; - ucp = inp; /* reset pointer */ - wo->req_ifaceid = 0; /* don't ask again */ - } - PUTCHAR(CI_IFACEID, ucp); - PUTCHAR(CILEN_IFACEID, ucp); - eui64_put(wo->hisid, ucp); - } - - *len = ucp - inp; /* Compute output length */ - IPV6CPDEBUG(("ipv6cp: returning Configure-%s", CODENAME(rc))); - return (rc); /* Return final code */ -} - -#if PPP_OPTIONS -/* - * ipv6_check_options - check that any IP-related options are OK, - * and assign appropriate defaults. - */ -static void ipv6_check_options() { - ipv6cp_options *wo = &ipv6cp_wantoptions[0]; - - if (!ipv6cp_protent.enabled_flag) - return; - - /* - * Persistent link-local id is only used when user has not explicitly - * configure/hard-code the id - */ - if ((wo->use_persistent) && (!wo->opt_local) && (!wo->opt_remote)) { - - /* - * On systems where there are no Ethernet interfaces used, there - * may be other ways to obtain a persistent id. Right now, it - * will fall back to using magic [see eui64_magic] below when - * an EUI-48 from MAC address can't be obtained. Other possibilities - * include obtaining EEPROM serial numbers, or some other unique - * yet persistent number. On Sparc platforms, this is possible, - * but too bad there's no standards yet for x86 machines. - */ - if (ether_to_eui64(&wo->ourid)) { - wo->opt_local = 1; - } - } - - if (!wo->opt_local) { /* init interface identifier */ - if (wo->use_ip && eui64_iszero(wo->ourid)) { - eui64_setlo32(wo->ourid, lwip_ntohl(ipcp_wantoptions[0].ouraddr)); - if (!eui64_iszero(wo->ourid)) - wo->opt_local = 1; - } - - while (eui64_iszero(wo->ourid)) - eui64_magic(wo->ourid); - } - - if (!wo->opt_remote) { - if (wo->use_ip && eui64_iszero(wo->hisid)) { - eui64_setlo32(wo->hisid, lwip_ntohl(ipcp_wantoptions[0].hisaddr)); - if (!eui64_iszero(wo->hisid)) - wo->opt_remote = 1; - } - } - - if (demand && (eui64_iszero(wo->ourid) || eui64_iszero(wo->hisid))) { - option_error("local/remote LL address required for demand-dialling\n"); - exit(1); - } -} -#endif /* PPP_OPTIONS */ - -#if DEMAND_SUPPORT -/* - * ipv6_demand_conf - configure the interface as though - * IPV6CP were up, for use with dial-on-demand. - */ -static int ipv6_demand_conf(int u) { - ipv6cp_options *wo = &ipv6cp_wantoptions[u]; - - if (!sif6up(u)) - return 0; - - if (!sif6addr(u, wo->ourid, wo->hisid)) - return 0; - - if (!sifnpmode(u, PPP_IPV6, NPMODE_QUEUE)) - return 0; - - ppp_notice("ipv6_demand_conf"); - ppp_notice("local LL address %s", llv6_ntoa(wo->ourid)); - ppp_notice("remote LL address %s", llv6_ntoa(wo->hisid)); - - return 1; -} -#endif /* DEMAND_SUPPORT */ - - -/* - * ipv6cp_up - IPV6CP has come UP. - * - * Configure the IPv6 network interface appropriately and bring it up. - */ -static void ipv6cp_up(fsm *f) { - ppp_pcb *pcb = f->pcb; - ipv6cp_options *wo = &pcb->ipv6cp_wantoptions; - ipv6cp_options *ho = &pcb->ipv6cp_hisoptions; - ipv6cp_options *go = &pcb->ipv6cp_gotoptions; - - IPV6CPDEBUG(("ipv6cp: up")); - - /* - * We must have a non-zero LL address for both ends of the link. - */ - if (!ho->neg_ifaceid) - ho->hisid = wo->hisid; - -#if 0 /* UNUSED */ - if(!no_ifaceid_neg) { -#endif /* UNUSED */ - if (eui64_iszero(ho->hisid)) { - ppp_error("Could not determine remote LL address"); - ipv6cp_close(f->pcb, "Could not determine remote LL address"); - return; - } - if (eui64_iszero(go->ourid)) { - ppp_error("Could not determine local LL address"); - ipv6cp_close(f->pcb, "Could not determine local LL address"); - return; - } - if (eui64_equals(go->ourid, ho->hisid)) { - ppp_error("local and remote LL addresses are equal"); - ipv6cp_close(f->pcb, "local and remote LL addresses are equal"); - return; - } -#if 0 /* UNUSED */ - } -#endif /* UNUSED */ -#if 0 /* UNUSED */ - script_setenv("LLLOCAL", llv6_ntoa(go->ourid), 0); - script_setenv("LLREMOTE", llv6_ntoa(ho->hisid), 0); -#endif /* UNUSED */ - -#ifdef IPV6CP_COMP - /* set tcp compression */ - sif6comp(f->unit, ho->neg_vj); -#endif - -#if DEMAND_SUPPORT - /* - * If we are doing dial-on-demand, the interface is already - * configured, so we put out any saved-up packets, then set the - * interface to pass IPv6 packets. - */ - if (demand) { - if (! eui64_equals(go->ourid, wo->ourid) || - ! eui64_equals(ho->hisid, wo->hisid)) { - if (! eui64_equals(go->ourid, wo->ourid)) - warn("Local LL address changed to %s", - llv6_ntoa(go->ourid)); - if (! eui64_equals(ho->hisid, wo->hisid)) - warn("Remote LL address changed to %s", - llv6_ntoa(ho->hisid)); - ipv6cp_clear_addrs(f->pcb, go->ourid, ho->hisid); - - /* Set the interface to the new addresses */ - if (!sif6addr(f->pcb, go->ourid, ho->hisid)) { - if (debug) - warn("sif6addr failed"); - ipv6cp_close(f->unit, "Interface configuration failed"); - return; - } - - } - demand_rexmit(PPP_IPV6); - sifnpmode(f->unit, PPP_IPV6, NPMODE_PASS); - - } else -#endif /* DEMAND_SUPPORT */ - { - /* - * Set LL addresses - */ - if (!sif6addr(f->pcb, go->ourid, ho->hisid)) { - PPPDEBUG(LOG_DEBUG, ("sif6addr failed")); - ipv6cp_close(f->pcb, "Interface configuration failed"); - return; - } - - /* bring the interface up for IPv6 */ - if (!sif6up(f->pcb)) { - PPPDEBUG(LOG_DEBUG, ("sif6up failed (IPV6)")); - ipv6cp_close(f->pcb, "Interface configuration failed"); - return; - } -#if DEMAND_SUPPORT - sifnpmode(f->pcb, PPP_IPV6, NPMODE_PASS); -#endif /* DEMAND_SUPPORT */ - - ppp_notice("local LL address %s", llv6_ntoa(go->ourid)); - ppp_notice("remote LL address %s", llv6_ntoa(ho->hisid)); - } - - np_up(f->pcb, PPP_IPV6); - pcb->ipv6cp_is_up = 1; - -#if 0 /* UNUSED */ - /* - * Execute the ipv6-up script, like this: - * /etc/ppp/ipv6-up interface tty speed local-LL remote-LL - */ - if (ipv6cp_script_state == s_down && ipv6cp_script_pid == 0) { - ipv6cp_script_state = s_up; - ipv6cp_script(_PATH_IPV6UP); - } -#endif /* UNUSED */ -} - - -/* - * ipv6cp_down - IPV6CP has gone DOWN. - * - * Take the IPv6 network interface down, clear its addresses - * and delete routes through it. - */ -static void ipv6cp_down(fsm *f) { - ppp_pcb *pcb = f->pcb; - ipv6cp_options *go = &pcb->ipv6cp_gotoptions; - ipv6cp_options *ho = &pcb->ipv6cp_hisoptions; - - IPV6CPDEBUG(("ipv6cp: down")); -#if PPP_STATS_SUPPORT - update_link_stats(f->unit); -#endif /* PPP_STATS_SUPPORT */ - if (pcb->ipv6cp_is_up) { - pcb->ipv6cp_is_up = 0; - np_down(f->pcb, PPP_IPV6); - } -#ifdef IPV6CP_COMP - sif6comp(f->unit, 0); -#endif - -#if DEMAND_SUPPORT - /* - * If we are doing dial-on-demand, set the interface - * to queue up outgoing packets (for now). - */ - if (demand) { - sifnpmode(f->pcb, PPP_IPV6, NPMODE_QUEUE); - } else -#endif /* DEMAND_SUPPORT */ - { -#if DEMAND_SUPPORT - sifnpmode(f->pcb, PPP_IPV6, NPMODE_DROP); -#endif /* DEMAND_SUPPORT */ - ipv6cp_clear_addrs(f->pcb, - go->ourid, - ho->hisid); - sif6down(f->pcb); - } - -#if 0 /* UNUSED */ - /* Execute the ipv6-down script */ - if (ipv6cp_script_state == s_up && ipv6cp_script_pid == 0) { - ipv6cp_script_state = s_down; - ipv6cp_script(_PATH_IPV6DOWN); - } -#endif /* UNUSED */ -} - - -/* - * ipv6cp_clear_addrs() - clear the interface addresses, routes, - * proxy neighbour discovery entries, etc. - */ -static void ipv6cp_clear_addrs(ppp_pcb *pcb, eui64_t ourid, eui64_t hisid) { - cif6addr(pcb, ourid, hisid); -} - - -/* - * ipv6cp_finished - possibly shut down the lower layers. - */ -static void ipv6cp_finished(fsm *f) { - np_finished(f->pcb, PPP_IPV6); -} - - -#if 0 /* UNUSED */ -/* - * ipv6cp_script_done - called when the ipv6-up or ipv6-down script - * has finished. - */ -static void -ipv6cp_script_done(arg) - void *arg; -{ - ipv6cp_script_pid = 0; - switch (ipv6cp_script_state) { - case s_up: - if (ipv6cp_fsm[0].state != PPP_FSM_OPENED) { - ipv6cp_script_state = s_down; - ipv6cp_script(_PATH_IPV6DOWN); - } - break; - case s_down: - if (ipv6cp_fsm[0].state == PPP_FSM_OPENED) { - ipv6cp_script_state = s_up; - ipv6cp_script(_PATH_IPV6UP); - } - break; - } -} - - -/* - * ipv6cp_script - Execute a script with arguments - * interface-name tty-name speed local-LL remote-LL. - */ -static void -ipv6cp_script(script) - char *script; -{ - char strspeed[32], strlocal[32], strremote[32]; - char *argv[8]; - - sprintf(strspeed, "%d", baud_rate); - strcpy(strlocal, llv6_ntoa(ipv6cp_gotoptions[0].ourid)); - strcpy(strremote, llv6_ntoa(ipv6cp_hisoptions[0].hisid)); - - argv[0] = script; - argv[1] = ifname; - argv[2] = devnam; - argv[3] = strspeed; - argv[4] = strlocal; - argv[5] = strremote; - argv[6] = ipparam; - argv[7] = NULL; - - ipv6cp_script_pid = run_program(script, argv, 0, ipv6cp_script_done, - NULL, 0); -} -#endif /* UNUSED */ - -#if PRINTPKT_SUPPORT -/* - * ipv6cp_printpkt - print the contents of an IPV6CP packet. - */ -static const char* const ipv6cp_codenames[] = { - "ConfReq", "ConfAck", "ConfNak", "ConfRej", - "TermReq", "TermAck", "CodeRej" -}; - -static int ipv6cp_printpkt(const u_char *p, int plen, - void (*printer)(void *, const char *, ...), void *arg) { - int code, id, len, olen; - const u_char *pstart, *optend; -#ifdef IPV6CP_COMP - u_short cishort; -#endif /* IPV6CP_COMP */ - eui64_t ifaceid; - - if (plen < HEADERLEN) - return 0; - pstart = p; - GETCHAR(code, p); - GETCHAR(id, p); - GETSHORT(len, p); - if (len < HEADERLEN || len > plen) - return 0; - - if (code >= 1 && code <= (int)LWIP_ARRAYSIZE(ipv6cp_codenames)) - printer(arg, " %s", ipv6cp_codenames[code-1]); - else - printer(arg, " code=0x%x", code); - printer(arg, " id=0x%x", id); - len -= HEADERLEN; - switch (code) { - case CONFREQ: - case CONFACK: - case CONFNAK: - case CONFREJ: - /* print option list */ - while (len >= 2) { - GETCHAR(code, p); - GETCHAR(olen, p); - p -= 2; - if (olen < 2 || olen > len) { - break; - } - printer(arg, " <"); - len -= olen; - optend = p + olen; - switch (code) { -#ifdef IPV6CP_COMP - case CI_COMPRESSTYPE: - if (olen >= CILEN_COMPRESS) { - p += 2; - GETSHORT(cishort, p); - printer(arg, "compress "); - printer(arg, "0x%x", cishort); - } - break; -#endif /* IPV6CP_COMP */ - case CI_IFACEID: - if (olen == CILEN_IFACEID) { - p += 2; - eui64_get(ifaceid, p); - printer(arg, "addr %s", llv6_ntoa(ifaceid)); - } - break; - default: - break; - } - while (p < optend) { - GETCHAR(code, p); - printer(arg, " %.2x", code); - } - printer(arg, ">"); - } - break; - - case TERMACK: - case TERMREQ: - if (len > 0 && *p >= ' ' && *p < 0x7f) { - printer(arg, " "); - ppp_print_string(p, len, printer, arg); - p += len; - len = 0; - } - break; - default: - break; - } - - /* print the rest of the bytes in the packet */ - for (; len > 0; --len) { - GETCHAR(code, p); - printer(arg, " %.2x", code); - } - - return p - pstart; -} -#endif /* PRINTPKT_SUPPORT */ - -#if DEMAND_SUPPORT -/* - * ipv6_active_pkt - see if this IP packet is worth bringing the link up for. - * We don't bring the link up for IP fragments or for TCP FIN packets - * with no data. - */ -#define IP6_HDRLEN 40 /* bytes */ -#define IP6_NHDR_FRAG 44 /* fragment IPv6 header */ -#define TCP_HDRLEN 20 -#define TH_FIN 0x01 - -/* - * We use these macros because the IP header may be at an odd address, - * and some compilers might use word loads to get th_off or ip_hl. - */ - -#define get_ip6nh(x) (((unsigned char *)(x))[6]) -#define get_tcpoff(x) (((unsigned char *)(x))[12] >> 4) -#define get_tcpflags(x) (((unsigned char *)(x))[13]) - -static int ipv6_active_pkt(u_char *pkt, int len) { - u_char *tcp; - - len -= PPP_HDRLEN; - pkt += PPP_HDRLEN; - if (len < IP6_HDRLEN) - return 0; - if (get_ip6nh(pkt) == IP6_NHDR_FRAG) - return 0; - if (get_ip6nh(pkt) != IPPROTO_TCP) - return 1; - if (len < IP6_HDRLEN + TCP_HDRLEN) - return 0; - tcp = pkt + IP6_HDRLEN; - if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == IP6_HDRLEN + get_tcpoff(tcp) * 4) - return 0; - return 1; -} -#endif /* DEMAND_SUPPORT */ - -#endif /* PPP_SUPPORT && PPP_IPV6_SUPPORT */ diff --git a/third-party/lwip-2.1.2/netif/ppp/lcp.c b/third-party/lwip-2.1.2/netif/ppp/lcp.c deleted file mode 100644 index 90ed183b..00000000 --- a/third-party/lwip-2.1.2/netif/ppp/lcp.c +++ /dev/null @@ -1,2790 +0,0 @@ -/* - * lcp.c - PPP Link Control Protocol. - * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -/* - * @todo: - */ - -#if 0 /* UNUSED */ -#include -#include -#include -#endif /* UNUSED */ - -#include "netif/ppp/ppp_impl.h" - -#include "netif/ppp/fsm.h" -#include "netif/ppp/lcp.h" -#if CHAP_SUPPORT -#include "netif/ppp/chap-new.h" -#endif /* CHAP_SUPPORT */ -#include "netif/ppp/magic.h" - -/* - * When the link comes up we want to be able to wait for a short while, - * or until seeing some input from the peer, before starting to send - * configure-requests. We do this by delaying the fsm_lowerup call. - */ -/* steal a bit in fsm flags word */ -#define DELAYED_UP 0x80 - -static void lcp_delayed_up(void *arg); - -/* - * LCP-related command-line options. - */ -#if 0 /* UNUSED */ -int lcp_echo_interval = 0; /* Interval between LCP echo-requests */ -int lcp_echo_fails = 0; /* Tolerance to unanswered echo-requests */ -#endif /* UNUSED */ - -#if 0 /* UNUSED */ -/* options */ -static u_int lcp_echo_interval = LCP_ECHOINTERVAL; /* Interval between LCP echo-requests */ -static u_int lcp_echo_fails = LCP_MAXECHOFAILS; /* Tolerance to unanswered echo-requests */ -#endif /* UNUSED */ - -#if 0 /* UNUSED */ -#if PPP_LCP_ADAPTIVE -bool lcp_echo_adaptive = 0; /* request echo only if the link was idle */ -#endif -bool lax_recv = 0; /* accept control chars in asyncmap */ -bool noendpoint = 0; /* don't send/accept endpoint discriminator */ -#endif /* UNUSED */ - -#if PPP_OPTIONS -static int noopt (char **); -#endif /* PPP_OPTIONS */ - -#ifdef HAVE_MULTILINK -static int setendpoint (char **); -static void printendpoint (option_t *, void (*)(void *, char *, ...), - void *); -#endif /* HAVE_MULTILINK */ - -#if PPP_OPTIONS -static option_t lcp_option_list[] = { - /* LCP options */ - { "-all", o_special_noarg, (void *)noopt, - "Don't request/allow any LCP options" }, - - { "noaccomp", o_bool, &lcp_wantoptions[0].neg_accompression, - "Disable address/control compression", - OPT_A2CLR, &lcp_allowoptions[0].neg_accompression }, - { "-ac", o_bool, &lcp_wantoptions[0].neg_accompression, - "Disable address/control compression", - OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_accompression }, - - { "asyncmap", o_uint32, &lcp_wantoptions[0].asyncmap, - "Set asyncmap (for received packets)", - OPT_OR, &lcp_wantoptions[0].neg_asyncmap }, - { "-as", o_uint32, &lcp_wantoptions[0].asyncmap, - "Set asyncmap (for received packets)", - OPT_ALIAS | OPT_OR, &lcp_wantoptions[0].neg_asyncmap }, - { "default-asyncmap", o_uint32, &lcp_wantoptions[0].asyncmap, - "Disable asyncmap negotiation", - OPT_OR | OPT_NOARG | OPT_VAL(~0U) | OPT_A2CLR, - &lcp_allowoptions[0].neg_asyncmap }, - { "-am", o_uint32, &lcp_wantoptions[0].asyncmap, - "Disable asyncmap negotiation", - OPT_ALIAS | OPT_OR | OPT_NOARG | OPT_VAL(~0U) | OPT_A2CLR, - &lcp_allowoptions[0].neg_asyncmap }, - - { "nomagic", o_bool, &lcp_wantoptions[0].neg_magicnumber, - "Disable magic number negotiation (looped-back line detection)", - OPT_A2CLR, &lcp_allowoptions[0].neg_magicnumber }, - { "-mn", o_bool, &lcp_wantoptions[0].neg_magicnumber, - "Disable magic number negotiation (looped-back line detection)", - OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_magicnumber }, - - { "mru", o_int, &lcp_wantoptions[0].mru, - "Set MRU (maximum received packet size) for negotiation", - OPT_PRIO, &lcp_wantoptions[0].neg_mru }, - { "default-mru", o_bool, &lcp_wantoptions[0].neg_mru, - "Disable MRU negotiation (use default 1500)", - OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_mru }, - { "-mru", o_bool, &lcp_wantoptions[0].neg_mru, - "Disable MRU negotiation (use default 1500)", - OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_mru }, - - { "mtu", o_int, &lcp_allowoptions[0].mru, - "Set our MTU", OPT_LIMITS, NULL, MAXMRU, MINMRU }, - - { "nopcomp", o_bool, &lcp_wantoptions[0].neg_pcompression, - "Disable protocol field compression", - OPT_A2CLR, &lcp_allowoptions[0].neg_pcompression }, - { "-pc", o_bool, &lcp_wantoptions[0].neg_pcompression, - "Disable protocol field compression", - OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_pcompression }, - - { "passive", o_bool, &lcp_wantoptions[0].passive, - "Set passive mode", 1 }, - { "-p", o_bool, &lcp_wantoptions[0].passive, - "Set passive mode", OPT_ALIAS | 1 }, - - { "silent", o_bool, &lcp_wantoptions[0].silent, - "Set silent mode", 1 }, - - { "lcp-echo-failure", o_int, &lcp_echo_fails, - "Set number of consecutive echo failures to indicate link failure", - OPT_PRIO }, - { "lcp-echo-interval", o_int, &lcp_echo_interval, - "Set time in seconds between LCP echo requests", OPT_PRIO }, -#if PPP_LCP_ADAPTIVE - { "lcp-echo-adaptive", o_bool, &lcp_echo_adaptive, - "Suppress LCP echo requests if traffic was received", 1 }, -#endif - { "lcp-restart", o_int, &lcp_fsm[0].timeouttime, - "Set time in seconds between LCP retransmissions", OPT_PRIO }, - { "lcp-max-terminate", o_int, &lcp_fsm[0].maxtermtransmits, - "Set maximum number of LCP terminate-request transmissions", OPT_PRIO }, - { "lcp-max-configure", o_int, &lcp_fsm[0].maxconfreqtransmits, - "Set maximum number of LCP configure-request transmissions", OPT_PRIO }, - { "lcp-max-failure", o_int, &lcp_fsm[0].maxnakloops, - "Set limit on number of LCP configure-naks", OPT_PRIO }, - - { "receive-all", o_bool, &lax_recv, - "Accept all received control characters", 1 }, - -#ifdef HAVE_MULTILINK - { "mrru", o_int, &lcp_wantoptions[0].mrru, - "Maximum received packet size for multilink bundle", - OPT_PRIO, &lcp_wantoptions[0].neg_mrru }, - - { "mpshortseq", o_bool, &lcp_wantoptions[0].neg_ssnhf, - "Use short sequence numbers in multilink headers", - OPT_PRIO | 1, &lcp_allowoptions[0].neg_ssnhf }, - { "nompshortseq", o_bool, &lcp_wantoptions[0].neg_ssnhf, - "Don't use short sequence numbers in multilink headers", - OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_ssnhf }, - - { "endpoint", o_special, (void *) setendpoint, - "Endpoint discriminator for multilink", - OPT_PRIO | OPT_A2PRINTER, (void *) printendpoint }, -#endif /* HAVE_MULTILINK */ - - { "noendpoint", o_bool, &noendpoint, - "Don't send or accept multilink endpoint discriminator", 1 }, - - {NULL} -}; -#endif /* PPP_OPTIONS */ - -/* - * Callbacks for fsm code. (CI = Configuration Information) - */ -static void lcp_resetci(fsm *f); /* Reset our CI */ -static int lcp_cilen(fsm *f); /* Return length of our CI */ -static void lcp_addci(fsm *f, u_char *ucp, int *lenp); /* Add our CI to pkt */ -static int lcp_ackci(fsm *f, u_char *p, int len); /* Peer ack'd our CI */ -static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject); /* Peer nak'd our CI */ -static int lcp_rejci(fsm *f, u_char *p, int len); /* Peer rej'd our CI */ -static int lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree); /* Rcv peer CI */ -static void lcp_up(fsm *f); /* We're UP */ -static void lcp_down(fsm *f); /* We're DOWN */ -static void lcp_starting (fsm *); /* We need lower layer up */ -static void lcp_finished (fsm *); /* We need lower layer down */ -static int lcp_extcode(fsm *f, int code, int id, u_char *inp, int len); -static void lcp_rprotrej(fsm *f, u_char *inp, int len); - -/* - * routines to send LCP echos to peer - */ - -static void lcp_echo_lowerup(ppp_pcb *pcb); -static void lcp_echo_lowerdown(ppp_pcb *pcb); -static void LcpEchoTimeout(void *arg); -static void lcp_received_echo_reply(fsm *f, int id, u_char *inp, int len); -static void LcpSendEchoRequest(fsm *f); -static void LcpLinkFailure(fsm *f); -static void LcpEchoCheck(fsm *f); - -static const fsm_callbacks lcp_callbacks = { /* LCP callback routines */ - lcp_resetci, /* Reset our Configuration Information */ - lcp_cilen, /* Length of our Configuration Information */ - lcp_addci, /* Add our Configuration Information */ - lcp_ackci, /* ACK our Configuration Information */ - lcp_nakci, /* NAK our Configuration Information */ - lcp_rejci, /* Reject our Configuration Information */ - lcp_reqci, /* Request peer's Configuration Information */ - lcp_up, /* Called when fsm reaches OPENED state */ - lcp_down, /* Called when fsm leaves OPENED state */ - lcp_starting, /* Called when we want the lower layer up */ - lcp_finished, /* Called when we want the lower layer down */ - NULL, /* Called when Protocol-Reject received */ - NULL, /* Retransmission is necessary */ - lcp_extcode, /* Called to handle LCP-specific codes */ - "LCP" /* String name of protocol */ -}; - -/* - * Protocol entry points. - * Some of these are called directly. - */ - -static void lcp_init(ppp_pcb *pcb); -static void lcp_input(ppp_pcb *pcb, u_char *p, int len); -static void lcp_protrej(ppp_pcb *pcb); -#if PRINTPKT_SUPPORT -static int lcp_printpkt(const u_char *p, int plen, - void (*printer) (void *, const char *, ...), void *arg); -#endif /* PRINTPKT_SUPPORT */ - -const struct protent lcp_protent = { - PPP_LCP, - lcp_init, - lcp_input, - lcp_protrej, - lcp_lowerup, - lcp_lowerdown, - lcp_open, - lcp_close, -#if PRINTPKT_SUPPORT - lcp_printpkt, -#endif /* PRINTPKT_SUPPORT */ -#if PPP_DATAINPUT - NULL, -#endif /* PPP_DATAINPUT */ -#if PRINTPKT_SUPPORT - "LCP", - NULL, -#endif /* PRINTPKT_SUPPORT */ -#if PPP_OPTIONS - lcp_option_list, - NULL, -#endif /* PPP_OPTIONS */ -#if DEMAND_SUPPORT - NULL, - NULL -#endif /* DEMAND_SUPPORT */ -}; - -/* - * Length of each type of configuration option (in octets) - */ -#define CILEN_VOID 2 -#define CILEN_CHAR 3 -#define CILEN_SHORT 4 /* CILEN_VOID + 2 */ -#if CHAP_SUPPORT -#define CILEN_CHAP 5 /* CILEN_VOID + 2 + 1 */ -#endif /* CHAP_SUPPORT */ -#define CILEN_LONG 6 /* CILEN_VOID + 4 */ -#if LQR_SUPPORT -#define CILEN_LQR 8 /* CILEN_VOID + 2 + 4 */ -#endif /* LQR_SUPPORT */ -#define CILEN_CBCP 3 - -#define CODENAME(x) ((x) == CONFACK ? "ACK" : \ - (x) == CONFNAK ? "NAK" : "REJ") - -#if PPP_OPTIONS -/* - * noopt - Disable all options (why?). - */ -static int -noopt(argv) - char **argv; -{ - BZERO((char *) &lcp_wantoptions[0], sizeof (struct lcp_options)); - BZERO((char *) &lcp_allowoptions[0], sizeof (struct lcp_options)); - - return (1); -} -#endif /* PPP_OPTIONS */ - -#ifdef HAVE_MULTILINK -static int -setendpoint(argv) - char **argv; -{ - if (str_to_epdisc(&lcp_wantoptions[0].endpoint, *argv)) { - lcp_wantoptions[0].neg_endpoint = 1; - return 1; - } - option_error("Can't parse '%s' as an endpoint discriminator", *argv); - return 0; -} - -static void -printendpoint(opt, printer, arg) - option_t *opt; - void (*printer) (void *, char *, ...); - void *arg; -{ - printer(arg, "%s", epdisc_to_str(&lcp_wantoptions[0].endpoint)); -} -#endif /* HAVE_MULTILINK */ - -/* - * lcp_init - Initialize LCP. - */ -static void lcp_init(ppp_pcb *pcb) { - fsm *f = &pcb->lcp_fsm; - lcp_options *wo = &pcb->lcp_wantoptions; - lcp_options *ao = &pcb->lcp_allowoptions; - - f->pcb = pcb; - f->protocol = PPP_LCP; - f->callbacks = &lcp_callbacks; - - fsm_init(f); - - BZERO(wo, sizeof(*wo)); - wo->neg_mru = 1; - wo->mru = PPP_DEFMRU; - wo->neg_asyncmap = 1; - wo->neg_magicnumber = 1; - wo->neg_pcompression = 1; - wo->neg_accompression = 1; - - BZERO(ao, sizeof(*ao)); - ao->neg_mru = 1; - ao->mru = PPP_MAXMRU; - ao->neg_asyncmap = 1; -#if CHAP_SUPPORT - ao->neg_chap = 1; - ao->chap_mdtype = CHAP_MDTYPE_SUPPORTED; -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT - ao->neg_upap = 1; -#endif /* PAP_SUPPORT */ -#if EAP_SUPPORT - ao->neg_eap = 1; -#endif /* EAP_SUPPORT */ - ao->neg_magicnumber = 1; - ao->neg_pcompression = 1; - ao->neg_accompression = 1; - ao->neg_endpoint = 1; -} - - -/* - * lcp_open - LCP is allowed to come up. - */ -void lcp_open(ppp_pcb *pcb) { - fsm *f = &pcb->lcp_fsm; - lcp_options *wo = &pcb->lcp_wantoptions; - - f->flags &= ~(OPT_PASSIVE | OPT_SILENT); - if (wo->passive) - f->flags |= OPT_PASSIVE; - if (wo->silent) - f->flags |= OPT_SILENT; - fsm_open(f); -} - - -/* - * lcp_close - Take LCP down. - */ -void lcp_close(ppp_pcb *pcb, const char *reason) { - fsm *f = &pcb->lcp_fsm; - int oldstate; - - if (pcb->phase != PPP_PHASE_DEAD -#ifdef HAVE_MULTILINK - && pcb->phase != PPP_PHASE_MASTER -#endif /* HAVE_MULTILINK */ - ) - new_phase(pcb, PPP_PHASE_TERMINATE); - - if (f->flags & DELAYED_UP) { - UNTIMEOUT(lcp_delayed_up, f); - f->state = PPP_FSM_STOPPED; - } - oldstate = f->state; - - fsm_close(f, reason); - if (oldstate == PPP_FSM_STOPPED && (f->flags & (OPT_PASSIVE|OPT_SILENT|DELAYED_UP))) { - /* - * This action is not strictly according to the FSM in RFC1548, - * but it does mean that the program terminates if you do a - * lcp_close() when a connection hasn't been established - * because we are in passive/silent mode or because we have - * delayed the fsm_lowerup() call and it hasn't happened yet. - */ - f->flags &= ~DELAYED_UP; - lcp_finished(f); - } -} - - -/* - * lcp_lowerup - The lower layer is up. - */ -void lcp_lowerup(ppp_pcb *pcb) { - lcp_options *wo = &pcb->lcp_wantoptions; - fsm *f = &pcb->lcp_fsm; - /* - * Don't use A/C or protocol compression on transmission, - * but accept A/C and protocol compressed packets - * if we are going to ask for A/C and protocol compression. - */ - if (ppp_send_config(pcb, PPP_MRU, 0xffffffff, 0, 0) < 0 - || ppp_recv_config(pcb, PPP_MRU, (pcb->settings.lax_recv? 0: 0xffffffff), - wo->neg_pcompression, wo->neg_accompression) < 0) - return; - pcb->peer_mru = PPP_MRU; - - if (pcb->settings.listen_time != 0) { - f->flags |= DELAYED_UP; - TIMEOUTMS(lcp_delayed_up, f, pcb->settings.listen_time); - } else - fsm_lowerup(f); -} - - -/* - * lcp_lowerdown - The lower layer is down. - */ -void lcp_lowerdown(ppp_pcb *pcb) { - fsm *f = &pcb->lcp_fsm; - - if (f->flags & DELAYED_UP) { - f->flags &= ~DELAYED_UP; - UNTIMEOUT(lcp_delayed_up, f); - } else - fsm_lowerdown(f); -} - - -/* - * lcp_delayed_up - Bring the lower layer up now. - */ -static void lcp_delayed_up(void *arg) { - fsm *f = (fsm*)arg; - - if (f->flags & DELAYED_UP) { - f->flags &= ~DELAYED_UP; - fsm_lowerup(f); - } -} - - -/* - * lcp_input - Input LCP packet. - */ -static void lcp_input(ppp_pcb *pcb, u_char *p, int len) { - fsm *f = &pcb->lcp_fsm; - - if (f->flags & DELAYED_UP) { - f->flags &= ~DELAYED_UP; - UNTIMEOUT(lcp_delayed_up, f); - fsm_lowerup(f); - } - fsm_input(f, p, len); -} - -/* - * lcp_extcode - Handle a LCP-specific code. - */ -static int lcp_extcode(fsm *f, int code, int id, u_char *inp, int len) { - ppp_pcb *pcb = f->pcb; - lcp_options *go = &pcb->lcp_gotoptions; - u_char *magp; - - switch( code ){ - case PROTREJ: - lcp_rprotrej(f, inp, len); - break; - - case ECHOREQ: - if (f->state != PPP_FSM_OPENED) - break; - magp = inp; - PUTLONG(go->magicnumber, magp); - fsm_sdata(f, ECHOREP, id, inp, len); - break; - - case ECHOREP: - lcp_received_echo_reply(f, id, inp, len); - break; - - case DISCREQ: - case IDENTIF: - case TIMEREM: - break; - - default: - return 0; - } - return 1; -} - - -/* - * lcp_rprotrej - Receive an Protocol-Reject. - * - * Figure out which protocol is rejected and inform it. - */ -static void lcp_rprotrej(fsm *f, u_char *inp, int len) { - int i; - const struct protent *protp; - u_short prot; -#if PPP_PROTOCOLNAME - const char *pname; -#endif /* PPP_PROTOCOLNAME */ - - if (len < 2) { - LCPDEBUG(("lcp_rprotrej: Rcvd short Protocol-Reject packet!")); - return; - } - - GETSHORT(prot, inp); - - /* - * Protocol-Reject packets received in any state other than the LCP - * OPENED state SHOULD be silently discarded. - */ - if( f->state != PPP_FSM_OPENED ){ - LCPDEBUG(("Protocol-Reject discarded: LCP in state %d", f->state)); - return; - } - -#if PPP_PROTOCOLNAME - pname = protocol_name(prot); -#endif /* PPP_PROTOCOLNAME */ - - /* - * Upcall the proper Protocol-Reject routine. - */ - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (protp->protocol == prot) { -#if PPP_PROTOCOLNAME - if (pname != NULL) - ppp_dbglog("Protocol-Reject for '%s' (0x%x) received", pname, - prot); - else -#endif /* PPP_PROTOCOLNAME */ - ppp_dbglog("Protocol-Reject for 0x%x received", prot); - (*protp->protrej)(f->pcb); - return; - } - -#if PPP_PROTOCOLNAME - if (pname != NULL) - ppp_warn("Protocol-Reject for unsupported protocol '%s' (0x%x)", pname, - prot); - else -#endif /* #if PPP_PROTOCOLNAME */ - ppp_warn("Protocol-Reject for unsupported protocol 0x%x", prot); -} - - -/* - * lcp_protrej - A Protocol-Reject was received. - */ -/*ARGSUSED*/ -static void lcp_protrej(ppp_pcb *pcb) { - /* - * Can't reject LCP! - */ - ppp_error("Received Protocol-Reject for LCP!"); - fsm_protreject(&pcb->lcp_fsm); -} - - -/* - * lcp_sprotrej - Send a Protocol-Reject for some protocol. - */ -void lcp_sprotrej(ppp_pcb *pcb, u_char *p, int len) { - fsm *f = &pcb->lcp_fsm; - /* - * Send back the protocol and the information field of the - * rejected packet. We only get here if LCP is in the OPENED state. - */ -#if 0 - p += 2; - len -= 2; -#endif - - fsm_sdata(f, PROTREJ, ++f->id, - p, len); -} - - -/* - * lcp_resetci - Reset our CI. - */ -static void lcp_resetci(fsm *f) { - ppp_pcb *pcb = f->pcb; - lcp_options *wo = &pcb->lcp_wantoptions; - lcp_options *go = &pcb->lcp_gotoptions; - lcp_options *ao = &pcb->lcp_allowoptions; - -#if PPP_AUTH_SUPPORT - - /* note: default value is true for allow options */ - if (pcb->settings.user && pcb->settings.passwd) { -#if PAP_SUPPORT - if (pcb->settings.refuse_pap) { - ao->neg_upap = 0; - } -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - if (pcb->settings.refuse_chap) { - ao->chap_mdtype &= ~MDTYPE_MD5; - } -#if MSCHAP_SUPPORT - if (pcb->settings.refuse_mschap) { - ao->chap_mdtype &= ~MDTYPE_MICROSOFT; - } - if (pcb->settings.refuse_mschap_v2) { - ao->chap_mdtype &= ~MDTYPE_MICROSOFT_V2; - } -#endif /* MSCHAP_SUPPORT */ - ao->neg_chap = (ao->chap_mdtype != MDTYPE_NONE); -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT - if (pcb->settings.refuse_eap) { - ao->neg_eap = 0; - } -#endif /* EAP_SUPPORT */ - -#if PPP_SERVER - /* note: default value is false for wanted options */ - if (pcb->settings.auth_required) { -#if PAP_SUPPORT - if (!pcb->settings.refuse_pap) { - wo->neg_upap = 1; - } -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - if (!pcb->settings.refuse_chap) { - wo->chap_mdtype |= MDTYPE_MD5; - } -#if MSCHAP_SUPPORT - if (!pcb->settings.refuse_mschap) { - wo->chap_mdtype |= MDTYPE_MICROSOFT; - } - if (!pcb->settings.refuse_mschap_v2) { - wo->chap_mdtype |= MDTYPE_MICROSOFT_V2; - } -#endif /* MSCHAP_SUPPORT */ - wo->neg_chap = (wo->chap_mdtype != MDTYPE_NONE); -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT - if (!pcb->settings.refuse_eap) { - wo->neg_eap = 1; - } -#endif /* EAP_SUPPORT */ - } -#endif /* PPP_SERVER */ - - } else { -#if PAP_SUPPORT - ao->neg_upap = 0; -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - ao->neg_chap = 0; - ao->chap_mdtype = MDTYPE_NONE; -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT - ao->neg_eap = 0; -#endif /* EAP_SUPPORT */ - } - - PPPDEBUG(LOG_DEBUG, ("ppp: auth protocols:")); -#if PAP_SUPPORT - PPPDEBUG(LOG_DEBUG, (" PAP=%d", ao->neg_upap)); -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - PPPDEBUG(LOG_DEBUG, (" CHAP=%d CHAP_MD5=%d", ao->neg_chap, !!(ao->chap_mdtype&MDTYPE_MD5))); -#if MSCHAP_SUPPORT - PPPDEBUG(LOG_DEBUG, (" CHAP_MS=%d CHAP_MS2=%d", !!(ao->chap_mdtype&MDTYPE_MICROSOFT), !!(ao->chap_mdtype&MDTYPE_MICROSOFT_V2))); -#endif /* MSCHAP_SUPPORT */ -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT - PPPDEBUG(LOG_DEBUG, (" EAP=%d", ao->neg_eap)); -#endif /* EAP_SUPPORT */ - PPPDEBUG(LOG_DEBUG, ("\n")); - -#endif /* PPP_AUTH_SUPPORT */ - - wo->magicnumber = magic(); - wo->numloops = 0; - *go = *wo; -#ifdef HAVE_MULTILINK - if (!multilink) { - go->neg_mrru = 0; -#endif /* HAVE_MULTILINK */ - go->neg_ssnhf = 0; - go->neg_endpoint = 0; -#ifdef HAVE_MULTILINK - } -#endif /* HAVE_MULTILINK */ - if (pcb->settings.noendpoint) - ao->neg_endpoint = 0; - pcb->peer_mru = PPP_MRU; -#if 0 /* UNUSED */ - auth_reset(pcb); -#endif /* UNUSED */ -} - - -/* - * lcp_cilen - Return length of our CI. - */ -static int lcp_cilen(fsm *f) { - ppp_pcb *pcb = f->pcb; - lcp_options *go = &pcb->lcp_gotoptions; - -#define LENCIVOID(neg) ((neg) ? CILEN_VOID : 0) -#if CHAP_SUPPORT -#define LENCICHAP(neg) ((neg) ? CILEN_CHAP : 0) -#endif /* CHAP_SUPPORT */ -#define LENCISHORT(neg) ((neg) ? CILEN_SHORT : 0) -#define LENCILONG(neg) ((neg) ? CILEN_LONG : 0) -#if LQR_SUPPORT -#define LENCILQR(neg) ((neg) ? CILEN_LQR: 0) -#endif /* LQR_SUPPORT */ -#define LENCICBCP(neg) ((neg) ? CILEN_CBCP: 0) - /* - * NB: we only ask for one of CHAP, UPAP, or EAP, even if we will - * accept more than one. We prefer EAP first, then CHAP, then - * PAP. - */ - return (LENCISHORT(go->neg_mru && go->mru != PPP_DEFMRU) + - LENCILONG(go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) + -#if EAP_SUPPORT - LENCISHORT(go->neg_eap) + -#endif /* EAP_SUPPORT */ -#if CHAP_SUPPORT /* cannot be improved, embedding a directive within macro arguments is not portable */ -#if EAP_SUPPORT - LENCICHAP(!go->neg_eap && go->neg_chap) + -#endif /* EAP_SUPPORT */ -#if !EAP_SUPPORT - LENCICHAP(go->neg_chap) + -#endif /* !EAP_SUPPORT */ -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT /* cannot be improved, embedding a directive within macro arguments is not portable */ -#if EAP_SUPPORT && CHAP_SUPPORT - LENCISHORT(!go->neg_eap && !go->neg_chap && go->neg_upap) + -#endif /* EAP_SUPPORT && CHAP_SUPPORT */ -#if EAP_SUPPORT && !CHAP_SUPPORT - LENCISHORT(!go->neg_eap && go->neg_upap) + -#endif /* EAP_SUPPORT && !CHAP_SUPPORT */ -#if !EAP_SUPPORT && CHAP_SUPPORT - LENCISHORT(!go->neg_chap && go->neg_upap) + -#endif /* !EAP_SUPPORT && CHAP_SUPPORT */ -#if !EAP_SUPPORT && !CHAP_SUPPORT - LENCISHORT(go->neg_upap) + -#endif /* !EAP_SUPPORT && !CHAP_SUPPORT */ -#endif /* PAP_SUPPORT */ -#if LQR_SUPPORT - LENCILQR(go->neg_lqr) + -#endif /* LQR_SUPPORT */ - LENCICBCP(go->neg_cbcp) + - LENCILONG(go->neg_magicnumber) + - LENCIVOID(go->neg_pcompression) + - LENCIVOID(go->neg_accompression) + -#ifdef HAVE_MULTILINK - LENCISHORT(go->neg_mrru) + -#endif /* HAVE_MULTILINK */ - LENCIVOID(go->neg_ssnhf) + - (go->neg_endpoint? CILEN_CHAR + go->endpoint.length: 0)); -} - - -/* - * lcp_addci - Add our desired CIs to a packet. - */ -static void lcp_addci(fsm *f, u_char *ucp, int *lenp) { - ppp_pcb *pcb = f->pcb; - lcp_options *go = &pcb->lcp_gotoptions; - u_char *start_ucp = ucp; - -#define ADDCIVOID(opt, neg) \ - if (neg) { \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_VOID, ucp); \ - } -#define ADDCISHORT(opt, neg, val) \ - if (neg) { \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_SHORT, ucp); \ - PUTSHORT(val, ucp); \ - } -#if CHAP_SUPPORT -#define ADDCICHAP(opt, neg, val) \ - if (neg) { \ - PUTCHAR((opt), ucp); \ - PUTCHAR(CILEN_CHAP, ucp); \ - PUTSHORT(PPP_CHAP, ucp); \ - PUTCHAR((CHAP_DIGEST(val)), ucp); \ - } -#endif /* CHAP_SUPPORT */ -#define ADDCILONG(opt, neg, val) \ - if (neg) { \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_LONG, ucp); \ - PUTLONG(val, ucp); \ - } -#if LQR_SUPPORT -#define ADDCILQR(opt, neg, val) \ - if (neg) { \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_LQR, ucp); \ - PUTSHORT(PPP_LQR, ucp); \ - PUTLONG(val, ucp); \ - } -#endif /* LQR_SUPPORT */ -#define ADDCICHAR(opt, neg, val) \ - if (neg) { \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_CHAR, ucp); \ - PUTCHAR(val, ucp); \ - } -#define ADDCIENDP(opt, neg, class, val, len) \ - if (neg) { \ - int i; \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_CHAR + len, ucp); \ - PUTCHAR(class, ucp); \ - for (i = 0; i < len; ++i) \ - PUTCHAR(val[i], ucp); \ - } - - ADDCISHORT(CI_MRU, go->neg_mru && go->mru != PPP_DEFMRU, go->mru); - ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF, - go->asyncmap); -#if EAP_SUPPORT - ADDCISHORT(CI_AUTHTYPE, go->neg_eap, PPP_EAP); -#endif /* EAP_SUPPORT */ -#if CHAP_SUPPORT /* cannot be improved, embedding a directive within macro arguments is not portable */ -#if EAP_SUPPORT - ADDCICHAP(CI_AUTHTYPE, !go->neg_eap && go->neg_chap, go->chap_mdtype); -#endif /* EAP_SUPPORT */ -#if !EAP_SUPPORT - ADDCICHAP(CI_AUTHTYPE, go->neg_chap, go->chap_mdtype); -#endif /* !EAP_SUPPORT */ -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT /* cannot be improved, embedding a directive within macro arguments is not portable */ -#if EAP_SUPPORT && CHAP_SUPPORT - ADDCISHORT(CI_AUTHTYPE, !go->neg_eap && !go->neg_chap && go->neg_upap, PPP_PAP); -#endif /* EAP_SUPPORT && CHAP_SUPPORT */ -#if EAP_SUPPORT && !CHAP_SUPPORT - ADDCISHORT(CI_AUTHTYPE, !go->neg_eap && go->neg_upap, PPP_PAP); -#endif /* EAP_SUPPORT && !CHAP_SUPPORT */ -#if !EAP_SUPPORT && CHAP_SUPPORT - ADDCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP); -#endif /* !EAP_SUPPORT && CHAP_SUPPORT */ -#if !EAP_SUPPORT && !CHAP_SUPPORT - ADDCISHORT(CI_AUTHTYPE, go->neg_upap, PPP_PAP); -#endif /* !EAP_SUPPORT && !CHAP_SUPPORT */ -#endif /* PAP_SUPPORT */ -#if LQR_SUPPORT - ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period); -#endif /* LQR_SUPPORT */ - ADDCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT); - ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber); - ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression); - ADDCIVOID(CI_ACCOMPRESSION, go->neg_accompression); -#ifdef HAVE_MULTILINK - ADDCISHORT(CI_MRRU, go->neg_mrru, go->mrru); -#endif - ADDCIVOID(CI_SSNHF, go->neg_ssnhf); - ADDCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class_, - go->endpoint.value, go->endpoint.length); - - if (ucp - start_ucp != *lenp) { - /* this should never happen, because peer_mtu should be 1500 */ - ppp_error("Bug in lcp_addci: wrong length"); - } -} - - -/* - * lcp_ackci - Ack our CIs. - * This should not modify any state if the Ack is bad. - * - * Returns: - * 0 - Ack was bad. - * 1 - Ack was good. - */ -static int lcp_ackci(fsm *f, u_char *p, int len) { - ppp_pcb *pcb = f->pcb; - lcp_options *go = &pcb->lcp_gotoptions; - u_char cilen, citype, cichar; - u_short cishort; - u32_t cilong; - - /* - * CIs must be in exactly the same order that we sent. - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ -#define ACKCIVOID(opt, neg) \ - if (neg) { \ - if ((len -= CILEN_VOID) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_VOID || \ - citype != opt) \ - goto bad; \ - } -#define ACKCISHORT(opt, neg, val) \ - if (neg) { \ - if ((len -= CILEN_SHORT) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_SHORT || \ - citype != opt) \ - goto bad; \ - GETSHORT(cishort, p); \ - if (cishort != val) \ - goto bad; \ - } -#define ACKCICHAR(opt, neg, val) \ - if (neg) { \ - if ((len -= CILEN_CHAR) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_CHAR || \ - citype != opt) \ - goto bad; \ - GETCHAR(cichar, p); \ - if (cichar != val) \ - goto bad; \ - } -#if CHAP_SUPPORT -#define ACKCICHAP(opt, neg, val) \ - if (neg) { \ - if ((len -= CILEN_CHAP) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_CHAP || \ - citype != (opt)) \ - goto bad; \ - GETSHORT(cishort, p); \ - if (cishort != PPP_CHAP) \ - goto bad; \ - GETCHAR(cichar, p); \ - if (cichar != (CHAP_DIGEST(val))) \ - goto bad; \ - } -#endif /* CHAP_SUPPORT */ -#define ACKCILONG(opt, neg, val) \ - if (neg) { \ - if ((len -= CILEN_LONG) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_LONG || \ - citype != opt) \ - goto bad; \ - GETLONG(cilong, p); \ - if (cilong != val) \ - goto bad; \ - } -#if LQR_SUPPORT -#define ACKCILQR(opt, neg, val) \ - if (neg) { \ - if ((len -= CILEN_LQR) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_LQR || \ - citype != opt) \ - goto bad; \ - GETSHORT(cishort, p); \ - if (cishort != PPP_LQR) \ - goto bad; \ - GETLONG(cilong, p); \ - if (cilong != val) \ - goto bad; \ - } -#endif /* LQR_SUPPORT */ -#define ACKCIENDP(opt, neg, class, val, vlen) \ - if (neg) { \ - int i; \ - if ((len -= CILEN_CHAR + vlen) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_CHAR + vlen || \ - citype != opt) \ - goto bad; \ - GETCHAR(cichar, p); \ - if (cichar != class) \ - goto bad; \ - for (i = 0; i < vlen; ++i) { \ - GETCHAR(cichar, p); \ - if (cichar != val[i]) \ - goto bad; \ - } \ - } - - ACKCISHORT(CI_MRU, go->neg_mru && go->mru != PPP_DEFMRU, go->mru); - ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF, - go->asyncmap); -#if EAP_SUPPORT - ACKCISHORT(CI_AUTHTYPE, go->neg_eap, PPP_EAP); -#endif /* EAP_SUPPORT */ -#if CHAP_SUPPORT /* cannot be improved, embedding a directive within macro arguments is not portable */ -#if EAP_SUPPORT - ACKCICHAP(CI_AUTHTYPE, !go->neg_eap && go->neg_chap, go->chap_mdtype); -#endif /* EAP_SUPPORT */ -#if !EAP_SUPPORT - ACKCICHAP(CI_AUTHTYPE, go->neg_chap, go->chap_mdtype); -#endif /* !EAP_SUPPORT */ -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT /* cannot be improved, embedding a directive within macro arguments is not portable */ -#if EAP_SUPPORT && CHAP_SUPPORT - ACKCISHORT(CI_AUTHTYPE, !go->neg_eap && !go->neg_chap && go->neg_upap, PPP_PAP); -#endif /* EAP_SUPPORT && CHAP_SUPPORT */ -#if EAP_SUPPORT && !CHAP_SUPPORT - ACKCISHORT(CI_AUTHTYPE, !go->neg_eap && go->neg_upap, PPP_PAP); -#endif /* EAP_SUPPORT && !CHAP_SUPPORT */ -#if !EAP_SUPPORT && CHAP_SUPPORT - ACKCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP); -#endif /* !EAP_SUPPORT && CHAP_SUPPORT */ -#if !EAP_SUPPORT && !CHAP_SUPPORT - ACKCISHORT(CI_AUTHTYPE, go->neg_upap, PPP_PAP); -#endif /* !EAP_SUPPORT && !CHAP_SUPPORT */ -#endif /* PAP_SUPPORT */ -#if LQR_SUPPORT - ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period); -#endif /* LQR_SUPPORT */ - ACKCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT); - ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber); - ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression); - ACKCIVOID(CI_ACCOMPRESSION, go->neg_accompression); -#ifdef HAVE_MULTILINK - ACKCISHORT(CI_MRRU, go->neg_mrru, go->mrru); -#endif /* HAVE_MULTILINK */ - ACKCIVOID(CI_SSNHF, go->neg_ssnhf); - ACKCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class_, - go->endpoint.value, go->endpoint.length); - - /* - * If there are any remaining CIs, then this packet is bad. - */ - if (len != 0) - goto bad; - return (1); -bad: - LCPDEBUG(("lcp_acki: received bad Ack!")); - return (0); -} - - -/* - * lcp_nakci - Peer has sent a NAK for some of our CIs. - * This should not modify any state if the Nak is bad - * or if LCP is in the OPENED state. - * - * Returns: - * 0 - Nak was bad. - * 1 - Nak was good. - */ -static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { - ppp_pcb *pcb = f->pcb; - lcp_options *go = &pcb->lcp_gotoptions; - lcp_options *wo = &pcb->lcp_wantoptions; - u_char citype, cichar, *next; - u_short cishort; - u32_t cilong; - lcp_options no; /* options we've seen Naks for */ - lcp_options try_; /* options to request next time */ - int looped_back = 0; - int cilen; - - BZERO(&no, sizeof(no)); - try_ = *go; - - /* - * Any Nak'd CIs must be in exactly the same order that we sent. - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ -#define NAKCIVOID(opt, neg) \ - if (go->neg && \ - len >= CILEN_VOID && \ - p[1] == CILEN_VOID && \ - p[0] == opt) { \ - len -= CILEN_VOID; \ - INCPTR(CILEN_VOID, p); \ - no.neg = 1; \ - try_.neg = 0; \ - } -#if CHAP_SUPPORT -#define NAKCICHAP(opt, neg, code) \ - if (go->neg && \ - len >= CILEN_CHAP && \ - p[1] == CILEN_CHAP && \ - p[0] == opt) { \ - len -= CILEN_CHAP; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - GETCHAR(cichar, p); \ - no.neg = 1; \ - code \ - } -#endif /* CHAP_SUPPORT */ -#define NAKCICHAR(opt, neg, code) \ - if (go->neg && \ - len >= CILEN_CHAR && \ - p[1] == CILEN_CHAR && \ - p[0] == opt) { \ - len -= CILEN_CHAR; \ - INCPTR(2, p); \ - GETCHAR(cichar, p); \ - no.neg = 1; \ - code \ - } -#define NAKCISHORT(opt, neg, code) \ - if (go->neg && \ - len >= CILEN_SHORT && \ - p[1] == CILEN_SHORT && \ - p[0] == opt) { \ - len -= CILEN_SHORT; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - no.neg = 1; \ - code \ - } -#define NAKCILONG(opt, neg, code) \ - if (go->neg && \ - len >= CILEN_LONG && \ - p[1] == CILEN_LONG && \ - p[0] == opt) { \ - len -= CILEN_LONG; \ - INCPTR(2, p); \ - GETLONG(cilong, p); \ - no.neg = 1; \ - code \ - } -#if LQR_SUPPORT -#define NAKCILQR(opt, neg, code) \ - if (go->neg && \ - len >= CILEN_LQR && \ - p[1] == CILEN_LQR && \ - p[0] == opt) { \ - len -= CILEN_LQR; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - GETLONG(cilong, p); \ - no.neg = 1; \ - code \ - } -#endif /* LQR_SUPPORT */ -#define NAKCIENDP(opt, neg) \ - if (go->neg && \ - len >= CILEN_CHAR && \ - p[0] == opt && \ - p[1] >= CILEN_CHAR && \ - p[1] <= len) { \ - len -= p[1]; \ - INCPTR(p[1], p); \ - no.neg = 1; \ - try_.neg = 0; \ - } - - /* - * NOTE! There must be no assignments to individual fields of *go in - * the code below. Any such assignment is a BUG! - */ - /* - * We don't care if they want to send us smaller packets than - * we want. Therefore, accept any MRU less than what we asked for, - * but then ignore the new value when setting the MRU in the kernel. - * If they send us a bigger MRU than what we asked, accept it, up to - * the limit of the default MRU we'd get if we didn't negotiate. - */ - if (go->neg_mru && go->mru != PPP_DEFMRU) { - NAKCISHORT(CI_MRU, neg_mru, - if (cishort <= wo->mru || cishort <= PPP_DEFMRU) - try_.mru = cishort; - ); - } - - /* - * Add any characters they want to our (receive-side) asyncmap. - */ - if (go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) { - NAKCILONG(CI_ASYNCMAP, neg_asyncmap, - try_.asyncmap = go->asyncmap | cilong; - ); - } - - /* - * If they've nak'd our authentication-protocol, check whether - * they are proposing a different protocol, or a different - * hash algorithm for CHAP. - */ - if ((0 -#if CHAP_SUPPORT - || go->neg_chap -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT - || go->neg_upap -#endif /* PAP_SUPPORT */ -#if EAP_SUPPORT - || go->neg_eap -#endif /* EAP_SUPPORT */ - ) - && len >= CILEN_SHORT - && p[0] == CI_AUTHTYPE && p[1] >= CILEN_SHORT && p[1] <= len) { - cilen = p[1]; - len -= cilen; -#if CHAP_SUPPORT - no.neg_chap = go->neg_chap; -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT - no.neg_upap = go->neg_upap; -#endif /* PAP_SUPPORT */ -#if EAP_SUPPORT - no.neg_eap = go->neg_eap; -#endif /* EAP_SUPPORT */ - INCPTR(2, p); - GETSHORT(cishort, p); - -#if PAP_SUPPORT - if (cishort == PPP_PAP && cilen == CILEN_SHORT) { -#if EAP_SUPPORT - /* If we were asking for EAP, then we need to stop that. */ - if (go->neg_eap) - try_.neg_eap = 0; - else -#endif /* EAP_SUPPORT */ - -#if CHAP_SUPPORT - /* If we were asking for CHAP, then we need to stop that. */ - if (go->neg_chap) - try_.neg_chap = 0; - else -#endif /* CHAP_SUPPORT */ - - /* - * If we weren't asking for CHAP or EAP, then we were asking for - * PAP, in which case this Nak is bad. - */ - goto bad; - } else -#endif /* PAP_SUPPORT */ - -#if CHAP_SUPPORT - if (cishort == PPP_CHAP && cilen == CILEN_CHAP) { - GETCHAR(cichar, p); -#if EAP_SUPPORT - /* Stop asking for EAP, if we were. */ - if (go->neg_eap) { - try_.neg_eap = 0; - /* Try to set up to use their suggestion, if possible */ - if (CHAP_CANDIGEST(go->chap_mdtype, cichar)) - try_.chap_mdtype = CHAP_MDTYPE_D(cichar); - } else -#endif /* EAP_SUPPORT */ - if (go->neg_chap) { - /* - * We were asking for our preferred algorithm, they must - * want something different. - */ - if (cichar != CHAP_DIGEST(go->chap_mdtype)) { - if (CHAP_CANDIGEST(go->chap_mdtype, cichar)) { - /* Use their suggestion if we support it ... */ - try_.chap_mdtype = CHAP_MDTYPE_D(cichar); - } else { - /* ... otherwise, try our next-preferred algorithm. */ - try_.chap_mdtype &= ~(CHAP_MDTYPE(try_.chap_mdtype)); - if (try_.chap_mdtype == MDTYPE_NONE) /* out of algos */ - try_.neg_chap = 0; - } - } else { - /* - * Whoops, they Nak'd our algorithm of choice - * but then suggested it back to us. - */ - goto bad; - } - } else { - /* - * Stop asking for PAP if we were asking for it. - */ -#if PAP_SUPPORT - try_.neg_upap = 0; -#endif /* PAP_SUPPORT */ - } - - } else -#endif /* CHAP_SUPPORT */ - { - -#if EAP_SUPPORT - /* - * If we were asking for EAP, and they're Conf-Naking EAP, - * well, that's just strange. Nobody should do that. - */ - if (cishort == PPP_EAP && cilen == CILEN_SHORT && go->neg_eap) - ppp_dbglog("Unexpected Conf-Nak for EAP"); - - /* - * We don't recognize what they're suggesting. - * Stop asking for what we were asking for. - */ - if (go->neg_eap) - try_.neg_eap = 0; - else -#endif /* EAP_SUPPORT */ - -#if CHAP_SUPPORT - if (go->neg_chap) - try_.neg_chap = 0; - else -#endif /* CHAP_SUPPORT */ - -#if PAP_SUPPORT - if(1) - try_.neg_upap = 0; - else -#endif /* PAP_SUPPORT */ - {} - - p += cilen - CILEN_SHORT; - } - } - -#if LQR_SUPPORT - /* - * If they can't cope with our link quality protocol, we'll have - * to stop asking for LQR. We haven't got any other protocol. - * If they Nak the reporting period, take their value XXX ? - */ - NAKCILQR(CI_QUALITY, neg_lqr, - if (cishort != PPP_LQR) - try_.neg_lqr = 0; - else - try_.lqr_period = cilong; - ); -#endif /* LQR_SUPPORT */ - - /* - * Only implementing CBCP...not the rest of the callback options - */ - NAKCICHAR(CI_CALLBACK, neg_cbcp, - try_.neg_cbcp = 0; - (void)cichar; /* if CHAP support is not compiled, cichar is set but not used, which makes some compilers complaining */ - ); - - /* - * Check for a looped-back line. - */ - NAKCILONG(CI_MAGICNUMBER, neg_magicnumber, - try_.magicnumber = magic(); - looped_back = 1; - ); - - /* - * Peer shouldn't send Nak for protocol compression or - * address/control compression requests; they should send - * a Reject instead. If they send a Nak, treat it as a Reject. - */ - NAKCIVOID(CI_PCOMPRESSION, neg_pcompression); - NAKCIVOID(CI_ACCOMPRESSION, neg_accompression); - -#ifdef HAVE_MULTILINK - /* - * Nak for MRRU option - accept their value if it is smaller - * than the one we want. - */ - if (go->neg_mrru) { - NAKCISHORT(CI_MRRU, neg_mrru, - if (treat_as_reject) - try_.neg_mrru = 0; - else if (cishort <= wo->mrru) - try_.mrru = cishort; - ); - } -#else /* HAVE_MULTILINK */ - LWIP_UNUSED_ARG(treat_as_reject); -#endif /* HAVE_MULTILINK */ - - /* - * Nak for short sequence numbers shouldn't be sent, treat it - * like a reject. - */ - NAKCIVOID(CI_SSNHF, neg_ssnhf); - - /* - * Nak of the endpoint discriminator option is not permitted, - * treat it like a reject. - */ - NAKCIENDP(CI_EPDISC, neg_endpoint); - - /* - * There may be remaining CIs, if the peer is requesting negotiation - * on an option that we didn't include in our request packet. - * If we see an option that we requested, or one we've already seen - * in this packet, then this packet is bad. - * If we wanted to respond by starting to negotiate on the requested - * option(s), we could, but we don't, because except for the - * authentication type and quality protocol, if we are not negotiating - * an option, it is because we were told not to. - * For the authentication type, the Nak from the peer means - * `let me authenticate myself with you' which is a bit pointless. - * For the quality protocol, the Nak means `ask me to send you quality - * reports', but if we didn't ask for them, we don't want them. - * An option we don't recognize represents the peer asking to - * negotiate some option we don't support, so ignore it. - */ - while (len >= CILEN_VOID) { - GETCHAR(citype, p); - GETCHAR(cilen, p); - if (cilen < CILEN_VOID || (len -= cilen) < 0) - goto bad; - next = p + cilen - 2; - - switch (citype) { - case CI_MRU: - if ((go->neg_mru && go->mru != PPP_DEFMRU) - || no.neg_mru || cilen != CILEN_SHORT) - goto bad; - GETSHORT(cishort, p); - if (cishort < PPP_DEFMRU) { - try_.neg_mru = 1; - try_.mru = cishort; - } - break; - case CI_ASYNCMAP: - if ((go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) - || no.neg_asyncmap || cilen != CILEN_LONG) - goto bad; - break; - case CI_AUTHTYPE: - if (0 -#if CHAP_SUPPORT - || go->neg_chap || no.neg_chap -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT - || go->neg_upap || no.neg_upap -#endif /* PAP_SUPPORT */ -#if EAP_SUPPORT - || go->neg_eap || no.neg_eap -#endif /* EAP_SUPPORT */ - ) - goto bad; - break; - case CI_MAGICNUMBER: - if (go->neg_magicnumber || no.neg_magicnumber || - cilen != CILEN_LONG) - goto bad; - break; - case CI_PCOMPRESSION: - if (go->neg_pcompression || no.neg_pcompression - || cilen != CILEN_VOID) - goto bad; - break; - case CI_ACCOMPRESSION: - if (go->neg_accompression || no.neg_accompression - || cilen != CILEN_VOID) - goto bad; - break; -#if LQR_SUPPORT - case CI_QUALITY: - if (go->neg_lqr || no.neg_lqr || cilen != CILEN_LQR) - goto bad; - break; -#endif /* LQR_SUPPORT */ -#ifdef HAVE_MULTILINK - case CI_MRRU: - if (go->neg_mrru || no.neg_mrru || cilen != CILEN_SHORT) - goto bad; - break; -#endif /* HAVE_MULTILINK */ - case CI_SSNHF: - if (go->neg_ssnhf || no.neg_ssnhf || cilen != CILEN_VOID) - goto bad; - try_.neg_ssnhf = 1; - break; - case CI_EPDISC: - if (go->neg_endpoint || no.neg_endpoint || cilen < CILEN_CHAR) - goto bad; - break; - default: - break; - } - p = next; - } - - /* - * OK, the Nak is good. Now we can update state. - * If there are any options left we ignore them. - */ - if (f->state != PPP_FSM_OPENED) { - if (looped_back) { - if (++try_.numloops >= pcb->settings.lcp_loopbackfail) { - ppp_notice("Serial line is looped back."); - pcb->err_code = PPPERR_LOOPBACK; - lcp_close(f->pcb, "Loopback detected"); - } - } else - try_.numloops = 0; - *go = try_; - } - - return 1; - -bad: - LCPDEBUG(("lcp_nakci: received bad Nak!")); - return 0; -} - - -/* - * lcp_rejci - Peer has Rejected some of our CIs. - * This should not modify any state if the Reject is bad - * or if LCP is in the OPENED state. - * - * Returns: - * 0 - Reject was bad. - * 1 - Reject was good. - */ -static int lcp_rejci(fsm *f, u_char *p, int len) { - ppp_pcb *pcb = f->pcb; - lcp_options *go = &pcb->lcp_gotoptions; - u_char cichar; - u_short cishort; - u32_t cilong; - lcp_options try_; /* options to request next time */ - - try_ = *go; - - /* - * Any Rejected CIs must be in exactly the same order that we sent. - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ -#define REJCIVOID(opt, neg) \ - if (go->neg && \ - len >= CILEN_VOID && \ - p[1] == CILEN_VOID && \ - p[0] == opt) { \ - len -= CILEN_VOID; \ - INCPTR(CILEN_VOID, p); \ - try_.neg = 0; \ - } -#define REJCISHORT(opt, neg, val) \ - if (go->neg && \ - len >= CILEN_SHORT && \ - p[1] == CILEN_SHORT && \ - p[0] == opt) { \ - len -= CILEN_SHORT; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - /* Check rejected value. */ \ - if (cishort != val) \ - goto bad; \ - try_.neg = 0; \ - } - -#if CHAP_SUPPORT && EAP_SUPPORT && PAP_SUPPORT -#define REJCICHAP(opt, neg, val) \ - if (go->neg && \ - len >= CILEN_CHAP && \ - p[1] == CILEN_CHAP && \ - p[0] == opt) { \ - len -= CILEN_CHAP; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - GETCHAR(cichar, p); \ - /* Check rejected value. */ \ - if ((cishort != PPP_CHAP) || (cichar != (CHAP_DIGEST(val)))) \ - goto bad; \ - try_.neg = 0; \ - try_.neg_eap = try_.neg_upap = 0; \ - } -#endif /* CHAP_SUPPORT && EAP_SUPPORT && PAP_SUPPORT */ - -#if CHAP_SUPPORT && !EAP_SUPPORT && PAP_SUPPORT -#define REJCICHAP(opt, neg, val) \ - if (go->neg && \ - len >= CILEN_CHAP && \ - p[1] == CILEN_CHAP && \ - p[0] == opt) { \ - len -= CILEN_CHAP; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - GETCHAR(cichar, p); \ - /* Check rejected value. */ \ - if ((cishort != PPP_CHAP) || (cichar != (CHAP_DIGEST(val)))) \ - goto bad; \ - try_.neg = 0; \ - try_.neg_upap = 0; \ - } -#endif /* CHAP_SUPPORT && !EAP_SUPPORT && PAP_SUPPORT */ - -#if CHAP_SUPPORT && EAP_SUPPORT && !PAP_SUPPORT -#define REJCICHAP(opt, neg, val) \ - if (go->neg && \ - len >= CILEN_CHAP && \ - p[1] == CILEN_CHAP && \ - p[0] == opt) { \ - len -= CILEN_CHAP; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - GETCHAR(cichar, p); \ - /* Check rejected value. */ \ - if ((cishort != PPP_CHAP) || (cichar != (CHAP_DIGEST(val)))) \ - goto bad; \ - try_.neg = 0; \ - try_.neg_eap = 0; \ - } -#endif /* CHAP_SUPPORT && EAP_SUPPORT && !PAP_SUPPORT */ - -#if CHAP_SUPPORT && !EAP_SUPPORT && !PAP_SUPPORT -#define REJCICHAP(opt, neg, val) \ - if (go->neg && \ - len >= CILEN_CHAP && \ - p[1] == CILEN_CHAP && \ - p[0] == opt) { \ - len -= CILEN_CHAP; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - GETCHAR(cichar, p); \ - /* Check rejected value. */ \ - if ((cishort != PPP_CHAP) || (cichar != (CHAP_DIGEST(val)))) \ - goto bad; \ - try_.neg = 0; \ - } -#endif /* CHAP_SUPPORT && !EAP_SUPPORT && !PAP_SUPPORT */ - -#define REJCILONG(opt, neg, val) \ - if (go->neg && \ - len >= CILEN_LONG && \ - p[1] == CILEN_LONG && \ - p[0] == opt) { \ - len -= CILEN_LONG; \ - INCPTR(2, p); \ - GETLONG(cilong, p); \ - /* Check rejected value. */ \ - if (cilong != val) \ - goto bad; \ - try_.neg = 0; \ - } -#if LQR_SUPPORT -#define REJCILQR(opt, neg, val) \ - if (go->neg && \ - len >= CILEN_LQR && \ - p[1] == CILEN_LQR && \ - p[0] == opt) { \ - len -= CILEN_LQR; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - GETLONG(cilong, p); \ - /* Check rejected value. */ \ - if (cishort != PPP_LQR || cilong != val) \ - goto bad; \ - try_.neg = 0; \ - } -#endif /* LQR_SUPPORT */ -#define REJCICBCP(opt, neg, val) \ - if (go->neg && \ - len >= CILEN_CBCP && \ - p[1] == CILEN_CBCP && \ - p[0] == opt) { \ - len -= CILEN_CBCP; \ - INCPTR(2, p); \ - GETCHAR(cichar, p); \ - /* Check rejected value. */ \ - if (cichar != val) \ - goto bad; \ - try_.neg = 0; \ - } -#define REJCIENDP(opt, neg, class, val, vlen) \ - if (go->neg && \ - len >= CILEN_CHAR + vlen && \ - p[0] == opt && \ - p[1] == CILEN_CHAR + vlen) { \ - int i; \ - len -= CILEN_CHAR + vlen; \ - INCPTR(2, p); \ - GETCHAR(cichar, p); \ - if (cichar != class) \ - goto bad; \ - for (i = 0; i < vlen; ++i) { \ - GETCHAR(cichar, p); \ - if (cichar != val[i]) \ - goto bad; \ - } \ - try_.neg = 0; \ - } - - REJCISHORT(CI_MRU, neg_mru, go->mru); - REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap); -#if EAP_SUPPORT - REJCISHORT(CI_AUTHTYPE, neg_eap, PPP_EAP); - if (!go->neg_eap) { -#endif /* EAP_SUPPORT */ -#if CHAP_SUPPORT - REJCICHAP(CI_AUTHTYPE, neg_chap, go->chap_mdtype); - if (!go->neg_chap) { -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT - REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP); -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - } -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT - } -#endif /* EAP_SUPPORT */ -#if LQR_SUPPORT - REJCILQR(CI_QUALITY, neg_lqr, go->lqr_period); -#endif /* LQR_SUPPORT */ - REJCICBCP(CI_CALLBACK, neg_cbcp, CBCP_OPT); - REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber); - REJCIVOID(CI_PCOMPRESSION, neg_pcompression); - REJCIVOID(CI_ACCOMPRESSION, neg_accompression); -#ifdef HAVE_MULTILINK - REJCISHORT(CI_MRRU, neg_mrru, go->mrru); -#endif /* HAVE_MULTILINK */ - REJCIVOID(CI_SSNHF, neg_ssnhf); - REJCIENDP(CI_EPDISC, neg_endpoint, go->endpoint.class_, - go->endpoint.value, go->endpoint.length); - - /* - * If there are any remaining CIs, then this packet is bad. - */ - if (len != 0) - goto bad; - /* - * Now we can update state. - */ - if (f->state != PPP_FSM_OPENED) - *go = try_; - return 1; - -bad: - LCPDEBUG(("lcp_rejci: received bad Reject!")); - return 0; -} - - -/* - * lcp_reqci - Check the peer's requested CIs and send appropriate response. - * - * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified - * appropriately. If reject_if_disagree is non-zero, doesn't return - * CONFNAK; returns CONFREJ if it can't return CONFACK. - * - * inp = Requested CIs - * lenp = Length of requested CIs - */ -static int lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree) { - ppp_pcb *pcb = f->pcb; - lcp_options *go = &pcb->lcp_gotoptions; - lcp_options *ho = &pcb->lcp_hisoptions; - lcp_options *ao = &pcb->lcp_allowoptions; - u_char *cip, *next; /* Pointer to current and next CIs */ - int cilen, citype, cichar; /* Parsed len, type, char value */ - u_short cishort; /* Parsed short value */ - u32_t cilong; /* Parse long value */ - int rc = CONFACK; /* Final packet return code */ - int orc; /* Individual option return code */ - u_char *p; /* Pointer to next char to parse */ - u_char *rejp; /* Pointer to next char in reject frame */ - struct pbuf *nakp; /* Nak buffer */ - u_char *nakoutp; /* Pointer to next char in Nak frame */ - int l = *lenp; /* Length left */ - - /* - * Reset all his options. - */ - BZERO(ho, sizeof(*ho)); - - /* - * Process all his options. - */ - next = inp; - nakp = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_CTRL_PBUF_MAX_SIZE), PPP_CTRL_PBUF_TYPE); - if(NULL == nakp) - return 0; - if(nakp->tot_len != nakp->len) { - pbuf_free(nakp); - return 0; - } - - nakoutp = (u_char*)nakp->payload; - rejp = inp; - while (l) { - orc = CONFACK; /* Assume success */ - cip = p = next; /* Remember begining of CI */ - if (l < 2 || /* Not enough data for CI header or */ - p[1] < 2 || /* CI length too small or */ - p[1] > l) { /* CI length too big? */ - LCPDEBUG(("lcp_reqci: bad CI length!")); - orc = CONFREJ; /* Reject bad CI */ - cilen = l; /* Reject till end of packet */ - l = 0; /* Don't loop again */ - citype = 0; - goto endswitch; - } - GETCHAR(citype, p); /* Parse CI type */ - GETCHAR(cilen, p); /* Parse CI length */ - l -= cilen; /* Adjust remaining length */ - next += cilen; /* Step to next CI */ - - switch (citype) { /* Check CI type */ - case CI_MRU: - if (!ao->neg_mru || /* Allow option? */ - cilen != CILEN_SHORT) { /* Check CI length */ - orc = CONFREJ; /* Reject CI */ - break; - } - GETSHORT(cishort, p); /* Parse MRU */ - - /* - * He must be able to receive at least our minimum. - * No need to check a maximum. If he sends a large number, - * we'll just ignore it. - */ - if (cishort < PPP_MINMRU) { - orc = CONFNAK; /* Nak CI */ - PUTCHAR(CI_MRU, nakoutp); - PUTCHAR(CILEN_SHORT, nakoutp); - PUTSHORT(PPP_MINMRU, nakoutp); /* Give him a hint */ - break; - } - ho->neg_mru = 1; /* Remember he sent MRU */ - ho->mru = cishort; /* And remember value */ - break; - - case CI_ASYNCMAP: - if (!ao->neg_asyncmap || - cilen != CILEN_LONG) { - orc = CONFREJ; - break; - } - GETLONG(cilong, p); - - /* - * Asyncmap must have set at least the bits - * which are set in lcp_allowoptions[unit].asyncmap. - */ - if ((ao->asyncmap & ~cilong) != 0) { - orc = CONFNAK; - PUTCHAR(CI_ASYNCMAP, nakoutp); - PUTCHAR(CILEN_LONG, nakoutp); - PUTLONG(ao->asyncmap | cilong, nakoutp); - break; - } - ho->neg_asyncmap = 1; - ho->asyncmap = cilong; - break; - - case CI_AUTHTYPE: - if (cilen < CILEN_SHORT || - !(0 -#if PAP_SUPPORT - || ao->neg_upap -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - || ao->neg_chap -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT - || ao->neg_eap -#endif /* EAP_SUPPORT */ - )) { - /* - * Reject the option if we're not willing to authenticate. - */ - ppp_dbglog("No auth is possible"); - orc = CONFREJ; - break; - } - GETSHORT(cishort, p); - - /* - * Authtype must be PAP, CHAP, or EAP. - * - * Note: if more than one of ao->neg_upap, ao->neg_chap, and - * ao->neg_eap are set, and the peer sends a Configure-Request - * with two or more authenticate-protocol requests, then we will - * reject the second request. - * Whether we end up doing CHAP, UPAP, or EAP depends then on - * the ordering of the CIs in the peer's Configure-Request. - */ - -#if PAP_SUPPORT - if (cishort == PPP_PAP) { - /* we've already accepted CHAP or EAP */ - if (0 -#if CHAP_SUPPORT - || ho->neg_chap -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT - || ho->neg_eap -#endif /* EAP_SUPPORT */ - || cilen != CILEN_SHORT) { - LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE PAP, rejecting...")); - orc = CONFREJ; - break; - } - if (!ao->neg_upap) { /* we don't want to do PAP */ - orc = CONFNAK; /* NAK it and suggest CHAP or EAP */ - PUTCHAR(CI_AUTHTYPE, nakoutp); -#if EAP_SUPPORT - if (ao->neg_eap) { - PUTCHAR(CILEN_SHORT, nakoutp); - PUTSHORT(PPP_EAP, nakoutp); - } else { -#endif /* EAP_SUPPORT */ -#if CHAP_SUPPORT - PUTCHAR(CILEN_CHAP, nakoutp); - PUTSHORT(PPP_CHAP, nakoutp); - PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakoutp); -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT - } -#endif /* EAP_SUPPORT */ - break; - } - ho->neg_upap = 1; - break; - } -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - if (cishort == PPP_CHAP) { - /* we've already accepted PAP or EAP */ - if ( -#if PAP_SUPPORT - ho->neg_upap || -#endif /* PAP_SUPPORT */ -#if EAP_SUPPORT - ho->neg_eap || -#endif /* EAP_SUPPORT */ - cilen != CILEN_CHAP) { - LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE CHAP, rejecting...")); - orc = CONFREJ; - break; - } - if (!ao->neg_chap) { /* we don't want to do CHAP */ - orc = CONFNAK; /* NAK it and suggest EAP or PAP */ - PUTCHAR(CI_AUTHTYPE, nakoutp); - PUTCHAR(CILEN_SHORT, nakoutp); -#if EAP_SUPPORT - if (ao->neg_eap) { - PUTSHORT(PPP_EAP, nakoutp); - } else -#endif /* EAP_SUPPORT */ -#if PAP_SUPPORT - if(1) { - PUTSHORT(PPP_PAP, nakoutp); - } - else -#endif /* PAP_SUPPORT */ - {} - break; - } - GETCHAR(cichar, p); /* get digest type */ - if (!(CHAP_CANDIGEST(ao->chap_mdtype, cichar))) { - /* - * We can't/won't do the requested type, - * suggest something else. - */ - orc = CONFNAK; - PUTCHAR(CI_AUTHTYPE, nakoutp); - PUTCHAR(CILEN_CHAP, nakoutp); - PUTSHORT(PPP_CHAP, nakoutp); - PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakoutp); - break; - } - ho->chap_mdtype = CHAP_MDTYPE_D(cichar); /* save md type */ - ho->neg_chap = 1; - break; - } -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT - if (cishort == PPP_EAP) { - /* we've already accepted CHAP or PAP */ - if ( -#if CHAP_SUPPORT - ho->neg_chap || -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT - ho->neg_upap || -#endif /* PAP_SUPPORT */ - cilen != CILEN_SHORT) { - LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE EAP, rejecting...")); - orc = CONFREJ; - break; - } - if (!ao->neg_eap) { /* we don't want to do EAP */ - orc = CONFNAK; /* NAK it and suggest CHAP or PAP */ - PUTCHAR(CI_AUTHTYPE, nakoutp); -#if CHAP_SUPPORT - if (ao->neg_chap) { - PUTCHAR(CILEN_CHAP, nakoutp); - PUTSHORT(PPP_CHAP, nakoutp); - PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakoutp); - } else -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT - if(1) { - PUTCHAR(CILEN_SHORT, nakoutp); - PUTSHORT(PPP_PAP, nakoutp); - } else -#endif /* PAP_SUPPORT */ - {} - break; - } - ho->neg_eap = 1; - break; - } -#endif /* EAP_SUPPORT */ - - /* - * We don't recognize the protocol they're asking for. - * Nak it with something we're willing to do. - * (At this point we know ao->neg_upap || ao->neg_chap || - * ao->neg_eap.) - */ - orc = CONFNAK; - PUTCHAR(CI_AUTHTYPE, nakoutp); - -#if EAP_SUPPORT - if (ao->neg_eap) { - PUTCHAR(CILEN_SHORT, nakoutp); - PUTSHORT(PPP_EAP, nakoutp); - } else -#endif /* EAP_SUPPORT */ -#if CHAP_SUPPORT - if (ao->neg_chap) { - PUTCHAR(CILEN_CHAP, nakoutp); - PUTSHORT(PPP_CHAP, nakoutp); - PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakoutp); - } else -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT - if(1) { - PUTCHAR(CILEN_SHORT, nakoutp); - PUTSHORT(PPP_PAP, nakoutp); - } else -#endif /* PAP_SUPPORT */ - {} - break; - -#if LQR_SUPPORT - case CI_QUALITY: - if (!ao->neg_lqr || - cilen != CILEN_LQR) { - orc = CONFREJ; - break; - } - - GETSHORT(cishort, p); - GETLONG(cilong, p); - - /* - * Check the protocol and the reporting period. - * XXX When should we Nak this, and what with? - */ - if (cishort != PPP_LQR) { - orc = CONFNAK; - PUTCHAR(CI_QUALITY, nakoutp); - PUTCHAR(CILEN_LQR, nakoutp); - PUTSHORT(PPP_LQR, nakoutp); - PUTLONG(ao->lqr_period, nakoutp); - break; - } - break; -#endif /* LQR_SUPPORT */ - - case CI_MAGICNUMBER: - if (!(ao->neg_magicnumber || go->neg_magicnumber) || - cilen != CILEN_LONG) { - orc = CONFREJ; - break; - } - GETLONG(cilong, p); - - /* - * He must have a different magic number. - */ - if (go->neg_magicnumber && - cilong == go->magicnumber) { - cilong = magic(); /* Don't put magic() inside macro! */ - orc = CONFNAK; - PUTCHAR(CI_MAGICNUMBER, nakoutp); - PUTCHAR(CILEN_LONG, nakoutp); - PUTLONG(cilong, nakoutp); - break; - } - ho->neg_magicnumber = 1; - ho->magicnumber = cilong; - break; - - - case CI_PCOMPRESSION: - if (!ao->neg_pcompression || - cilen != CILEN_VOID) { - orc = CONFREJ; - break; - } - ho->neg_pcompression = 1; - break; - - case CI_ACCOMPRESSION: - if (!ao->neg_accompression || - cilen != CILEN_VOID) { - orc = CONFREJ; - break; - } - ho->neg_accompression = 1; - break; - -#ifdef HAVE_MULTILINK - case CI_MRRU: - if (!ao->neg_mrru - || !multilink - || cilen != CILEN_SHORT) { - orc = CONFREJ; - break; - } - - GETSHORT(cishort, p); - /* possibly should insist on a minimum/maximum MRRU here */ - ho->neg_mrru = 1; - ho->mrru = cishort; - break; -#endif /* HAVE_MULTILINK */ - - case CI_SSNHF: - if (!ao->neg_ssnhf -#ifdef HAVE_MULTILINK - || !multilink -#endif /* HAVE_MULTILINK */ - || cilen != CILEN_VOID) { - orc = CONFREJ; - break; - } - ho->neg_ssnhf = 1; - break; - - case CI_EPDISC: - if (!ao->neg_endpoint || - cilen < CILEN_CHAR || - cilen > CILEN_CHAR + MAX_ENDP_LEN) { - orc = CONFREJ; - break; - } - GETCHAR(cichar, p); - cilen -= CILEN_CHAR; - ho->neg_endpoint = 1; - ho->endpoint.class_ = cichar; - ho->endpoint.length = cilen; - MEMCPY(ho->endpoint.value, p, cilen); - INCPTR(cilen, p); - break; - - default: - LCPDEBUG(("lcp_reqci: rcvd unknown option %d", citype)); - orc = CONFREJ; - break; - } - -endswitch: - if (orc == CONFACK && /* Good CI */ - rc != CONFACK) /* but prior CI wasnt? */ - continue; /* Don't send this one */ - - if (orc == CONFNAK) { /* Nak this CI? */ - if (reject_if_disagree /* Getting fed up with sending NAKs? */ - && citype != CI_MAGICNUMBER) { - orc = CONFREJ; /* Get tough if so */ - } else { - if (rc == CONFREJ) /* Rejecting prior CI? */ - continue; /* Don't send this one */ - rc = CONFNAK; - } - } - if (orc == CONFREJ) { /* Reject this CI */ - rc = CONFREJ; - if (cip != rejp) /* Need to move rejected CI? */ - MEMCPY(rejp, cip, cilen); /* Move it */ - INCPTR(cilen, rejp); /* Update output pointer */ - } - } - - /* - * If we wanted to send additional NAKs (for unsent CIs), the - * code would go here. The extra NAKs would go at *nakoutp. - * At present there are no cases where we want to ask the - * peer to negotiate an option. - */ - - switch (rc) { - case CONFACK: - *lenp = next - inp; - break; - case CONFNAK: - /* - * Copy the Nak'd options from the nak buffer to the caller's buffer. - */ - *lenp = nakoutp - (u_char*)nakp->payload; - MEMCPY(inp, nakp->payload, *lenp); - break; - case CONFREJ: - *lenp = rejp - inp; - break; - default: - break; - } - - pbuf_free(nakp); - LCPDEBUG(("lcp_reqci: returning CONF%s.", CODENAME(rc))); - return (rc); /* Return final code */ -} - - -/* - * lcp_up - LCP has come UP. - */ -static void lcp_up(fsm *f) { - ppp_pcb *pcb = f->pcb; - lcp_options *wo = &pcb->lcp_wantoptions; - lcp_options *ho = &pcb->lcp_hisoptions; - lcp_options *go = &pcb->lcp_gotoptions; - lcp_options *ao = &pcb->lcp_allowoptions; - int mtu, mru; - - if (!go->neg_magicnumber) - go->magicnumber = 0; - if (!ho->neg_magicnumber) - ho->magicnumber = 0; - - /* - * Set our MTU to the smaller of the MTU we wanted and - * the MRU our peer wanted. If we negotiated an MRU, - * set our MRU to the larger of value we wanted and - * the value we got in the negotiation. - * Note on the MTU: the link MTU can be the MRU the peer wanted, - * the interface MTU is set to the lowest of that, the - * MTU we want to use, and our link MRU. - */ - mtu = ho->neg_mru? ho->mru: PPP_MRU; - mru = go->neg_mru? LWIP_MAX(wo->mru, go->mru): PPP_MRU; -#ifdef HAVE_MULTILINK - if (!(multilink && go->neg_mrru && ho->neg_mrru)) -#endif /* HAVE_MULTILINK */ - netif_set_mtu(pcb, LWIP_MIN(LWIP_MIN(mtu, mru), ao->mru)); - ppp_send_config(pcb, mtu, - (ho->neg_asyncmap? ho->asyncmap: 0xffffffff), - ho->neg_pcompression, ho->neg_accompression); - ppp_recv_config(pcb, mru, - (pcb->settings.lax_recv? 0: go->neg_asyncmap? go->asyncmap: 0xffffffff), - go->neg_pcompression, go->neg_accompression); - - if (ho->neg_mru) - pcb->peer_mru = ho->mru; - - lcp_echo_lowerup(f->pcb); /* Enable echo messages */ - - link_established(pcb); -} - - -/* - * lcp_down - LCP has gone DOWN. - * - * Alert other protocols. - */ -static void lcp_down(fsm *f) { - ppp_pcb *pcb = f->pcb; - lcp_options *go = &pcb->lcp_gotoptions; - - lcp_echo_lowerdown(f->pcb); - - link_down(pcb); - - ppp_send_config(pcb, PPP_MRU, 0xffffffff, 0, 0); - ppp_recv_config(pcb, PPP_MRU, - (go->neg_asyncmap? go->asyncmap: 0xffffffff), - go->neg_pcompression, go->neg_accompression); - pcb->peer_mru = PPP_MRU; -} - - -/* - * lcp_starting - LCP needs the lower layer up. - */ -static void lcp_starting(fsm *f) { - ppp_pcb *pcb = f->pcb; - link_required(pcb); -} - - -/* - * lcp_finished - LCP has finished with the lower layer. - */ -static void lcp_finished(fsm *f) { - ppp_pcb *pcb = f->pcb; - link_terminated(pcb); -} - - -#if PRINTPKT_SUPPORT -/* - * lcp_printpkt - print the contents of an LCP packet. - */ -static const char* const lcp_codenames[] = { - "ConfReq", "ConfAck", "ConfNak", "ConfRej", - "TermReq", "TermAck", "CodeRej", "ProtRej", - "EchoReq", "EchoRep", "DiscReq", "Ident", - "TimeRem" -}; - -static int lcp_printpkt(const u_char *p, int plen, - void (*printer) (void *, const char *, ...), void *arg) { - int code, id, len, olen, i; - const u_char *pstart, *optend; - u_short cishort; - u32_t cilong; - - if (plen < HEADERLEN) - return 0; - pstart = p; - GETCHAR(code, p); - GETCHAR(id, p); - GETSHORT(len, p); - if (len < HEADERLEN || len > plen) - return 0; - - if (code >= 1 && code <= (int)LWIP_ARRAYSIZE(lcp_codenames)) - printer(arg, " %s", lcp_codenames[code-1]); - else - printer(arg, " code=0x%x", code); - printer(arg, " id=0x%x", id); - len -= HEADERLEN; - switch (code) { - case CONFREQ: - case CONFACK: - case CONFNAK: - case CONFREJ: - /* print option list */ - while (len >= 2) { - GETCHAR(code, p); - GETCHAR(olen, p); - p -= 2; - if (olen < 2 || olen > len) { - break; - } - printer(arg, " <"); - len -= olen; - optend = p + olen; - switch (code) { - case CI_MRU: - if (olen == CILEN_SHORT) { - p += 2; - GETSHORT(cishort, p); - printer(arg, "mru %d", cishort); - } - break; - case CI_ASYNCMAP: - if (olen == CILEN_LONG) { - p += 2; - GETLONG(cilong, p); - printer(arg, "asyncmap 0x%x", cilong); - } - break; - case CI_AUTHTYPE: - if (olen >= CILEN_SHORT) { - p += 2; - printer(arg, "auth "); - GETSHORT(cishort, p); - switch (cishort) { -#if PAP_SUPPORT - case PPP_PAP: - printer(arg, "pap"); - break; -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - case PPP_CHAP: - printer(arg, "chap"); - if (p < optend) { - switch (*p) { - case CHAP_MD5: - printer(arg, " MD5"); - ++p; - break; -#if MSCHAP_SUPPORT - case CHAP_MICROSOFT: - printer(arg, " MS"); - ++p; - break; - - case CHAP_MICROSOFT_V2: - printer(arg, " MS-v2"); - ++p; - break; -#endif /* MSCHAP_SUPPORT */ - default: - break; - } - } - break; -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT - case PPP_EAP: - printer(arg, "eap"); - break; -#endif /* EAP_SUPPORT */ - default: - printer(arg, "0x%x", cishort); - } - } - break; -#if LQR_SUPPORT - case CI_QUALITY: - if (olen >= CILEN_SHORT) { - p += 2; - printer(arg, "quality "); - GETSHORT(cishort, p); - switch (cishort) { - case PPP_LQR: - printer(arg, "lqr"); - break; - default: - printer(arg, "0x%x", cishort); - } - } - break; -#endif /* LQR_SUPPORT */ - case CI_CALLBACK: - if (olen >= CILEN_CHAR) { - p += 2; - printer(arg, "callback "); - GETCHAR(cishort, p); - switch (cishort) { - case CBCP_OPT: - printer(arg, "CBCP"); - break; - default: - printer(arg, "0x%x", cishort); - } - } - break; - case CI_MAGICNUMBER: - if (olen == CILEN_LONG) { - p += 2; - GETLONG(cilong, p); - printer(arg, "magic 0x%x", cilong); - } - break; - case CI_PCOMPRESSION: - if (olen == CILEN_VOID) { - p += 2; - printer(arg, "pcomp"); - } - break; - case CI_ACCOMPRESSION: - if (olen == CILEN_VOID) { - p += 2; - printer(arg, "accomp"); - } - break; - case CI_MRRU: - if (olen == CILEN_SHORT) { - p += 2; - GETSHORT(cishort, p); - printer(arg, "mrru %d", cishort); - } - break; - case CI_SSNHF: - if (olen == CILEN_VOID) { - p += 2; - printer(arg, "ssnhf"); - } - break; - case CI_EPDISC: -#ifdef HAVE_MULTILINK - if (olen >= CILEN_CHAR) { - struct epdisc epd; - p += 2; - GETCHAR(epd.class, p); - epd.length = olen - CILEN_CHAR; - if (epd.length > MAX_ENDP_LEN) - epd.length = MAX_ENDP_LEN; - if (epd.length > 0) { - MEMCPY(epd.value, p, epd.length); - p += epd.length; - } - printer(arg, "endpoint [%s]", epdisc_to_str(&epd)); - } -#else - printer(arg, "endpoint"); -#endif - break; - default: - break; - } - while (p < optend) { - GETCHAR(code, p); - printer(arg, " %.2x", code); - } - printer(arg, ">"); - } - break; - - case TERMACK: - case TERMREQ: - if (len > 0 && *p >= ' ' && *p < 0x7f) { - printer(arg, " "); - ppp_print_string(p, len, printer, arg); - p += len; - len = 0; - } - break; - - case ECHOREQ: - case ECHOREP: - case DISCREQ: - if (len >= 4) { - GETLONG(cilong, p); - printer(arg, " magic=0x%x", cilong); - len -= 4; - } - break; - - case IDENTIF: - case TIMEREM: - if (len >= 4) { - GETLONG(cilong, p); - printer(arg, " magic=0x%x", cilong); - len -= 4; - } - if (code == TIMEREM) { - if (len < 4) - break; - GETLONG(cilong, p); - printer(arg, " seconds=%u", cilong); - len -= 4; - } - if (len > 0) { - printer(arg, " "); - ppp_print_string(p, len, printer, arg); - p += len; - len = 0; - } - break; - default: - break; - } - - /* print the rest of the bytes in the packet */ - for (i = 0; i < len && i < 32; ++i) { - GETCHAR(code, p); - printer(arg, " %.2x", code); - } - if (i < len) { - printer(arg, " ..."); - p += len - i; - } - - return p - pstart; -} -#endif /* PRINTPKT_SUPPORT */ - -/* - * Time to shut down the link because there is nothing out there. - */ - -static void LcpLinkFailure(fsm *f) { - ppp_pcb *pcb = f->pcb; - if (f->state == PPP_FSM_OPENED) { - ppp_info("No response to %d echo-requests", pcb->lcp_echos_pending); - ppp_notice("Serial link appears to be disconnected."); - pcb->err_code = PPPERR_PEERDEAD; - lcp_close(pcb, "Peer not responding"); - } -} - -/* - * Timer expired for the LCP echo requests from this process. - */ - -static void LcpEchoCheck(fsm *f) { - ppp_pcb *pcb = f->pcb; - - LcpSendEchoRequest (f); - if (f->state != PPP_FSM_OPENED) - return; - - /* - * Start the timer for the next interval. - */ - if (pcb->lcp_echo_timer_running) - ppp_warn("assertion lcp_echo_timer_running==0 failed"); - TIMEOUT (LcpEchoTimeout, f, pcb->settings.lcp_echo_interval); - pcb->lcp_echo_timer_running = 1; -} - -/* - * LcpEchoTimeout - Timer expired on the LCP echo - */ - -static void LcpEchoTimeout(void *arg) { - fsm *f = (fsm*)arg; - ppp_pcb *pcb = f->pcb; - if (pcb->lcp_echo_timer_running != 0) { - pcb->lcp_echo_timer_running = 0; - LcpEchoCheck ((fsm *) arg); - } -} - -/* - * LcpEchoReply - LCP has received a reply to the echo - */ - -static void lcp_received_echo_reply(fsm *f, int id, u_char *inp, int len) { - ppp_pcb *pcb = f->pcb; - lcp_options *go = &pcb->lcp_gotoptions; - u32_t magic_val; - LWIP_UNUSED_ARG(id); - - /* Check the magic number - don't count replies from ourselves. */ - if (len < 4) { - ppp_dbglog("lcp: received short Echo-Reply, length %d", len); - return; - } - GETLONG(magic_val, inp); - if (go->neg_magicnumber - && magic_val == go->magicnumber) { - ppp_warn("appear to have received our own echo-reply!"); - return; - } - - /* Reset the number of outstanding echo frames */ - pcb->lcp_echos_pending = 0; -} - -/* - * LcpSendEchoRequest - Send an echo request frame to the peer - */ - -static void LcpSendEchoRequest(fsm *f) { - ppp_pcb *pcb = f->pcb; - lcp_options *go = &pcb->lcp_gotoptions; - u32_t lcp_magic; - u_char pkt[4], *pktp; - - /* - * Detect the failure of the peer at this point. - */ - if (pcb->settings.lcp_echo_fails != 0) { - if (pcb->lcp_echos_pending >= pcb->settings.lcp_echo_fails) { - LcpLinkFailure(f); - pcb->lcp_echos_pending = 0; - } - } - -#if PPP_LCP_ADAPTIVE - /* - * If adaptive echos have been enabled, only send the echo request if - * no traffic was received since the last one. - */ - if (pcb->settings.lcp_echo_adaptive) { - static unsigned int last_pkts_in = 0; - -#if PPP_STATS_SUPPORT - update_link_stats(f->unit); - link_stats_valid = 0; -#endif /* PPP_STATS_SUPPORT */ - - if (link_stats.pkts_in != last_pkts_in) { - last_pkts_in = link_stats.pkts_in; - return; - } - } -#endif - - /* - * Make and send the echo request frame. - */ - if (f->state == PPP_FSM_OPENED) { - lcp_magic = go->magicnumber; - pktp = pkt; - PUTLONG(lcp_magic, pktp); - fsm_sdata(f, ECHOREQ, pcb->lcp_echo_number++, pkt, pktp - pkt); - ++pcb->lcp_echos_pending; - } -} - -/* - * lcp_echo_lowerup - Start the timer for the LCP frame - */ - -static void lcp_echo_lowerup(ppp_pcb *pcb) { - fsm *f = &pcb->lcp_fsm; - - /* Clear the parameters for generating echo frames */ - pcb->lcp_echos_pending = 0; - pcb->lcp_echo_number = 0; - pcb->lcp_echo_timer_running = 0; - - /* If a timeout interval is specified then start the timer */ - if (pcb->settings.lcp_echo_interval != 0) - LcpEchoCheck (f); -} - -/* - * lcp_echo_lowerdown - Stop the timer for the LCP frame - */ - -static void lcp_echo_lowerdown(ppp_pcb *pcb) { - fsm *f = &pcb->lcp_fsm; - - if (pcb->lcp_echo_timer_running != 0) { - UNTIMEOUT (LcpEchoTimeout, f); - pcb->lcp_echo_timer_running = 0; - } -} - -#endif /* PPP_SUPPORT */ diff --git a/third-party/lwip-2.1.2/netif/ppp/magic.c b/third-party/lwip-2.1.2/netif/ppp/magic.c deleted file mode 100644 index d0d87c5e..00000000 --- a/third-party/lwip-2.1.2/netif/ppp/magic.c +++ /dev/null @@ -1,294 +0,0 @@ -/* - * magic.c - PPP Magic Number routines. - * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/***************************************************************************** -* randm.c - Random number generator program file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* Copyright (c) 1998 by Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher -* Ported to lwIP. -* 98-06-03 Guy Lancaster , Global Election Systems Inc. -* Extracted from avos. -*****************************************************************************/ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include "netif/ppp/ppp_impl.h" -#include "netif/ppp/magic.h" - -#if PPP_MD5_RANDM /* Using MD5 for better randomness if enabled */ - -#include "netif/ppp/pppcrypt.h" - -#define MD5_HASH_SIZE 16 -static char magic_randpool[MD5_HASH_SIZE]; /* Pool of randomness. */ -static long magic_randcount; /* Pseudo-random incrementer */ -static u32_t magic_randomseed; /* Seed used for random number generation. */ - -/* - * Churn the randomness pool on a random event. Call this early and often - * on random and semi-random system events to build randomness in time for - * usage. For randomly timed events, pass a null pointer and a zero length - * and this will use the system timer and other sources to add randomness. - * If new random data is available, pass a pointer to that and it will be - * included. - * - * Ref: Applied Cryptography 2nd Ed. by Bruce Schneier p. 427 - */ -static void magic_churnrand(char *rand_data, u32_t rand_len) { - lwip_md5_context md5_ctx; - - /* LWIP_DEBUGF(LOG_INFO, ("magic_churnrand: %u@%P\n", rand_len, rand_data)); */ - lwip_md5_init(&md5_ctx); - lwip_md5_starts(&md5_ctx); - lwip_md5_update(&md5_ctx, (u_char *)magic_randpool, sizeof(magic_randpool)); - if (rand_data) { - lwip_md5_update(&md5_ctx, (u_char *)rand_data, rand_len); - } else { - struct { - /* INCLUDE fields for any system sources of randomness */ - u32_t jiffies; -#ifdef LWIP_RAND - u32_t rand; -#endif /* LWIP_RAND */ - } sys_data; - magic_randomseed += sys_jiffies(); - sys_data.jiffies = magic_randomseed; -#ifdef LWIP_RAND - sys_data.rand = LWIP_RAND(); -#endif /* LWIP_RAND */ - /* Load sys_data fields here. */ - lwip_md5_update(&md5_ctx, (u_char *)&sys_data, sizeof(sys_data)); - } - lwip_md5_finish(&md5_ctx, (u_char *)magic_randpool); - lwip_md5_free(&md5_ctx); -/* LWIP_DEBUGF(LOG_INFO, ("magic_churnrand: -> 0\n")); */ -} - -/* - * Initialize the random number generator. - */ -void magic_init(void) { - magic_churnrand(NULL, 0); -} - -/* - * Randomize our random seed value. - */ -void magic_randomize(void) { - magic_churnrand(NULL, 0); -} - -/* - * magic_random_bytes - Fill a buffer with random bytes. - * - * Use the random pool to generate random data. This degrades to pseudo - * random when used faster than randomness is supplied using magic_churnrand(). - * Note: It's important that there be sufficient randomness in magic_randpool - * before this is called for otherwise the range of the result may be - * narrow enough to make a search feasible. - * - * Ref: Applied Cryptography 2nd Ed. by Bruce Schneier p. 427 - * - * XXX Why does he not just call magic_churnrand() for each block? Probably - * so that you don't ever publish the seed which could possibly help - * predict future values. - * XXX Why don't we preserve md5 between blocks and just update it with - * magic_randcount each time? Probably there is a weakness but I wish that - * it was documented. - */ -void magic_random_bytes(unsigned char *buf, u32_t buf_len) { - lwip_md5_context md5_ctx; - u_char tmp[MD5_HASH_SIZE]; - u32_t n; - - while (buf_len > 0) { - lwip_md5_init(&md5_ctx); - lwip_md5_starts(&md5_ctx); - lwip_md5_update(&md5_ctx, (u_char *)magic_randpool, sizeof(magic_randpool)); - lwip_md5_update(&md5_ctx, (u_char *)&magic_randcount, sizeof(magic_randcount)); - lwip_md5_finish(&md5_ctx, tmp); - lwip_md5_free(&md5_ctx); - magic_randcount++; - n = LWIP_MIN(buf_len, MD5_HASH_SIZE); - MEMCPY(buf, tmp, n); - buf += n; - buf_len -= n; - } -} - -/* - * Return a new random number. - */ -u32_t magic(void) { - u32_t new_rand; - - magic_random_bytes((unsigned char *)&new_rand, sizeof(new_rand)); - - return new_rand; -} - -#else /* PPP_MD5_RANDM */ - -/*****************************/ -/*** LOCAL DATA STRUCTURES ***/ -/*****************************/ -#ifndef LWIP_RAND -static int magic_randomized; /* Set when truely randomized. */ -#endif /* LWIP_RAND */ -static u32_t magic_randomseed; /* Seed used for random number generation. */ - - -/***********************************/ -/*** PUBLIC FUNCTION DEFINITIONS ***/ -/***********************************/ - -/* - * Initialize the random number generator. - * - * Here we attempt to compute a random number seed but even if - * it isn't random, we'll randomize it later. - * - * The current method uses the fields from the real time clock, - * the idle process counter, the millisecond counter, and the - * hardware timer tick counter. When this is invoked - * in startup(), then the idle counter and timer values may - * repeat after each boot and the real time clock may not be - * operational. Thus we call it again on the first random - * event. - */ -void magic_init(void) { - magic_randomseed += sys_jiffies(); -#ifndef LWIP_RAND - /* Initialize the Borland random number generator. */ - srand((unsigned)magic_randomseed); -#endif /* LWIP_RAND */ -} - -/* - * magic_init - Initialize the magic number generator. - * - * Randomize our random seed value. Here we use the fact that - * this function is called at *truely random* times by the polling - * and network functions. Here we only get 16 bits of new random - * value but we use the previous value to randomize the other 16 - * bits. - */ -void magic_randomize(void) { -#ifndef LWIP_RAND - if (!magic_randomized) { - magic_randomized = !0; - magic_init(); - /* The initialization function also updates the seed. */ - } else { -#endif /* LWIP_RAND */ - magic_randomseed += sys_jiffies(); -#ifndef LWIP_RAND - } -#endif /* LWIP_RAND */ -} - -/* - * Return a new random number. - * - * Here we use the Borland rand() function to supply a pseudo random - * number which we make truely random by combining it with our own - * seed which is randomized by truely random events. - * Thus the numbers will be truely random unless there have been no - * operator or network events in which case it will be pseudo random - * seeded by the real time clock. - */ -u32_t magic(void) { -#ifdef LWIP_RAND - return LWIP_RAND() + magic_randomseed; -#else /* LWIP_RAND */ - return ((u32_t)rand() << 16) + (u32_t)rand() + magic_randomseed; -#endif /* LWIP_RAND */ -} - -/* - * magic_random_bytes - Fill a buffer with random bytes. - */ -void magic_random_bytes(unsigned char *buf, u32_t buf_len) { - u32_t new_rand, n; - - while (buf_len > 0) { - new_rand = magic(); - n = LWIP_MIN(buf_len, sizeof(new_rand)); - MEMCPY(buf, &new_rand, n); - buf += n; - buf_len -= n; - } -} -#endif /* PPP_MD5_RANDM */ - -/* - * Return a new random number between 0 and (2^pow)-1 included. - */ -u32_t magic_pow(u8_t pow) { - return magic() & ~(~0UL<. - * Copyright (c) 2002,2003,2004 Google, Inc. - * All rights reserved. - * - * License: - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. - * - * Changelog: - * 08/12/05 - Matt Domsch - * Only need extra skb padding on transmit, not receive. - * 06/18/04 - Matt Domsch , Oleg Makarenko - * Use Linux kernel 2.6 arc4 and sha1 routines rather than - * providing our own. - * 2/15/04 - TS: added #include and testing for Kernel - * version before using - * MOD_DEC_USAGE_COUNT/MOD_INC_USAGE_COUNT which are - * deprecated in 2.6 - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && MPPE_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include - -#include "lwip/err.h" - -#include "netif/ppp/ppp_impl.h" -#include "netif/ppp/ccp.h" -#include "netif/ppp/mppe.h" -#include "netif/ppp/pppdebug.h" -#include "netif/ppp/pppcrypt.h" - -#define SHA1_SIGNATURE_SIZE 20 - -/* ppp_mppe_state.bits definitions */ -#define MPPE_BIT_A 0x80 /* Encryption table were (re)inititalized */ -#define MPPE_BIT_B 0x40 /* MPPC only (not implemented) */ -#define MPPE_BIT_C 0x20 /* MPPC only (not implemented) */ -#define MPPE_BIT_D 0x10 /* This is an encrypted frame */ - -#define MPPE_BIT_FLUSHED MPPE_BIT_A -#define MPPE_BIT_ENCRYPTED MPPE_BIT_D - -#define MPPE_BITS(p) ((p)[0] & 0xf0) -#define MPPE_CCOUNT(p) ((((p)[0] & 0x0f) << 8) + (p)[1]) -#define MPPE_CCOUNT_SPACE 0x1000 /* The size of the ccount space */ - -#define MPPE_OVHD 2 /* MPPE overhead/packet */ -#define SANITY_MAX 1600 /* Max bogon factor we will tolerate */ - -/* - * Perform the MPPE rekey algorithm, from RFC 3078, sec. 7.3. - * Well, not what's written there, but rather what they meant. - */ -static void mppe_rekey(ppp_mppe_state * state, int initial_key) -{ - lwip_sha1_context sha1_ctx; - u8_t sha1_digest[SHA1_SIGNATURE_SIZE]; - - /* - * Key Derivation, from RFC 3078, RFC 3079. - * Equivalent to Get_Key() for MS-CHAP as described in RFC 3079. - */ - lwip_sha1_init(&sha1_ctx); - lwip_sha1_starts(&sha1_ctx); - lwip_sha1_update(&sha1_ctx, state->master_key, state->keylen); - lwip_sha1_update(&sha1_ctx, mppe_sha1_pad1, SHA1_PAD_SIZE); - lwip_sha1_update(&sha1_ctx, state->session_key, state->keylen); - lwip_sha1_update(&sha1_ctx, mppe_sha1_pad2, SHA1_PAD_SIZE); - lwip_sha1_finish(&sha1_ctx, sha1_digest); - lwip_sha1_free(&sha1_ctx); - MEMCPY(state->session_key, sha1_digest, state->keylen); - - if (!initial_key) { - lwip_arc4_init(&state->arc4); - lwip_arc4_setup(&state->arc4, sha1_digest, state->keylen); - lwip_arc4_crypt(&state->arc4, state->session_key, state->keylen); - lwip_arc4_free(&state->arc4); - } - if (state->keylen == 8) { - /* See RFC 3078 */ - state->session_key[0] = 0xd1; - state->session_key[1] = 0x26; - state->session_key[2] = 0x9e; - } - lwip_arc4_init(&state->arc4); - lwip_arc4_setup(&state->arc4, state->session_key, state->keylen); -} - -/* - * Set key, used by MSCHAP before mppe_init() is actually called by CCP so we - * don't have to keep multiple copies of keys. - */ -void mppe_set_key(ppp_pcb *pcb, ppp_mppe_state *state, u8_t *key) { - LWIP_UNUSED_ARG(pcb); - MEMCPY(state->master_key, key, MPPE_MAX_KEY_LEN); -} - -/* - * Initialize (de)compressor state. - */ -void -mppe_init(ppp_pcb *pcb, ppp_mppe_state *state, u8_t options) -{ -#if PPP_DEBUG - const u8_t *debugstr = (const u8_t*)"mppe_comp_init"; - if (&pcb->mppe_decomp == state) { - debugstr = (const u8_t*)"mppe_decomp_init"; - } -#endif /* PPP_DEBUG */ - - /* Save keys. */ - MEMCPY(state->session_key, state->master_key, sizeof(state->master_key)); - - if (options & MPPE_OPT_128) - state->keylen = 16; - else if (options & MPPE_OPT_40) - state->keylen = 8; - else { - PPPDEBUG(LOG_DEBUG, ("%s[%d]: unknown key length\n", debugstr, - pcb->netif->num)); - lcp_close(pcb, "MPPE required but peer negotiation failed"); - return; - } - if (options & MPPE_OPT_STATEFUL) - state->stateful = 1; - - /* Generate the initial session key. */ - mppe_rekey(state, 1); - -#if PPP_DEBUG - { - int i; - char mkey[sizeof(state->master_key) * 2 + 1]; - char skey[sizeof(state->session_key) * 2 + 1]; - - PPPDEBUG(LOG_DEBUG, ("%s[%d]: initialized with %d-bit %s mode\n", - debugstr, pcb->netif->num, (state->keylen == 16) ? 128 : 40, - (state->stateful) ? "stateful" : "stateless")); - - for (i = 0; i < (int)sizeof(state->master_key); i++) - sprintf(mkey + i * 2, "%02x", state->master_key[i]); - for (i = 0; i < (int)sizeof(state->session_key); i++) - sprintf(skey + i * 2, "%02x", state->session_key[i]); - PPPDEBUG(LOG_DEBUG, - ("%s[%d]: keys: master: %s initial session: %s\n", - debugstr, pcb->netif->num, mkey, skey)); - } -#endif /* PPP_DEBUG */ - - /* - * Initialize the coherency count. The initial value is not specified - * in RFC 3078, but we can make a reasonable assumption that it will - * start at 0. Setting it to the max here makes the comp/decomp code - * do the right thing (determined through experiment). - */ - state->ccount = MPPE_CCOUNT_SPACE - 1; - - /* - * Note that even though we have initialized the key table, we don't - * set the FLUSHED bit. This is contrary to RFC 3078, sec. 3.1. - */ - state->bits = MPPE_BIT_ENCRYPTED; -} - -/* - * We received a CCP Reset-Request (actually, we are sending a Reset-Ack), - * tell the compressor to rekey. Note that we MUST NOT rekey for - * every CCP Reset-Request; we only rekey on the next xmit packet. - * We might get multiple CCP Reset-Requests if our CCP Reset-Ack is lost. - * So, rekeying for every CCP Reset-Request is broken as the peer will not - * know how many times we've rekeyed. (If we rekey and THEN get another - * CCP Reset-Request, we must rekey again.) - */ -void mppe_comp_reset(ppp_pcb *pcb, ppp_mppe_state *state) -{ - LWIP_UNUSED_ARG(pcb); - state->bits |= MPPE_BIT_FLUSHED; -} - -/* - * Compress (encrypt) a packet. - * It's strange to call this a compressor, since the output is always - * MPPE_OVHD + 2 bytes larger than the input. - */ -err_t -mppe_compress(ppp_pcb *pcb, ppp_mppe_state *state, struct pbuf **pb, u16_t protocol) -{ - struct pbuf *n, *np; - u8_t *pl; - err_t err; - - LWIP_UNUSED_ARG(pcb); - - /* TCP stack requires that we don't change the packet payload, therefore we copy - * the whole packet before encryption. - */ - np = pbuf_alloc(PBUF_RAW, MPPE_OVHD + sizeof(protocol) + (*pb)->tot_len, PBUF_RAM); - if (!np) { - return ERR_MEM; - } - - /* Hide MPPE header + protocol */ - pbuf_remove_header(np, MPPE_OVHD + sizeof(protocol)); - - if ((err = pbuf_copy(np, *pb)) != ERR_OK) { - pbuf_free(np); - return err; - } - - /* Reveal MPPE header + protocol */ - pbuf_add_header(np, MPPE_OVHD + sizeof(protocol)); - - *pb = np; - pl = (u8_t*)np->payload; - - state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE; - PPPDEBUG(LOG_DEBUG, ("mppe_compress[%d]: ccount %d\n", pcb->netif->num, state->ccount)); - /* FIXME: use PUT* macros */ - pl[0] = state->ccount>>8; - pl[1] = state->ccount; - - if (!state->stateful || /* stateless mode */ - ((state->ccount & 0xff) == 0xff) || /* "flag" packet */ - (state->bits & MPPE_BIT_FLUSHED)) { /* CCP Reset-Request */ - /* We must rekey */ - if (state->stateful) { - PPPDEBUG(LOG_DEBUG, ("mppe_compress[%d]: rekeying\n", pcb->netif->num)); - } - mppe_rekey(state, 0); - state->bits |= MPPE_BIT_FLUSHED; - } - pl[0] |= state->bits; - state->bits &= ~MPPE_BIT_FLUSHED; /* reset for next xmit */ - pl += MPPE_OVHD; - - /* Add protocol */ - /* FIXME: add PFC support */ - pl[0] = protocol >> 8; - pl[1] = protocol; - - /* Hide MPPE header */ - pbuf_remove_header(np, MPPE_OVHD); - - /* Encrypt packet */ - for (n = np; n != NULL; n = n->next) { - lwip_arc4_crypt(&state->arc4, (u8_t*)n->payload, n->len); - if (n->tot_len == n->len) { - break; - } - } - - /* Reveal MPPE header */ - pbuf_add_header(np, MPPE_OVHD); - - return ERR_OK; -} - -/* - * We received a CCP Reset-Ack. Just ignore it. - */ -void mppe_decomp_reset(ppp_pcb *pcb, ppp_mppe_state *state) -{ - LWIP_UNUSED_ARG(pcb); - LWIP_UNUSED_ARG(state); - return; -} - -/* - * Decompress (decrypt) an MPPE packet. - */ -err_t -mppe_decompress(ppp_pcb *pcb, ppp_mppe_state *state, struct pbuf **pb) -{ - struct pbuf *n0 = *pb, *n; - u8_t *pl; - u16_t ccount; - u8_t flushed; - - /* MPPE Header */ - if (n0->len < MPPE_OVHD) { - PPPDEBUG(LOG_DEBUG, - ("mppe_decompress[%d]: short pkt (%d)\n", - pcb->netif->num, n0->len)); - state->sanity_errors += 100; - goto sanity_error; - } - - pl = (u8_t*)n0->payload; - flushed = MPPE_BITS(pl) & MPPE_BIT_FLUSHED; - ccount = MPPE_CCOUNT(pl); - PPPDEBUG(LOG_DEBUG, ("mppe_decompress[%d]: ccount %d\n", - pcb->netif->num, ccount)); - - /* sanity checks -- terminate with extreme prejudice */ - if (!(MPPE_BITS(pl) & MPPE_BIT_ENCRYPTED)) { - PPPDEBUG(LOG_DEBUG, - ("mppe_decompress[%d]: ENCRYPTED bit not set!\n", - pcb->netif->num)); - state->sanity_errors += 100; - goto sanity_error; - } - if (!state->stateful && !flushed) { - PPPDEBUG(LOG_DEBUG, ("mppe_decompress[%d]: FLUSHED bit not set in " - "stateless mode!\n", pcb->netif->num)); - state->sanity_errors += 100; - goto sanity_error; - } - if (state->stateful && ((ccount & 0xff) == 0xff) && !flushed) { - PPPDEBUG(LOG_DEBUG, ("mppe_decompress[%d]: FLUSHED bit not set on " - "flag packet!\n", pcb->netif->num)); - state->sanity_errors += 100; - goto sanity_error; - } - - /* - * Check the coherency count. - */ - - if (!state->stateful) { - /* Discard late packet */ - if ((ccount - state->ccount) % MPPE_CCOUNT_SPACE > MPPE_CCOUNT_SPACE / 2) { - state->sanity_errors++; - goto sanity_error; - } - - /* RFC 3078, sec 8.1. Rekey for every packet. */ - while (state->ccount != ccount) { - mppe_rekey(state, 0); - state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE; - } - } else { - /* RFC 3078, sec 8.2. */ - if (!state->discard) { - /* normal state */ - state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE; - if (ccount != state->ccount) { - /* - * (ccount > state->ccount) - * Packet loss detected, enter the discard state. - * Signal the peer to rekey (by sending a CCP Reset-Request). - */ - state->discard = 1; - ccp_resetrequest(pcb); - return ERR_BUF; - } - } else { - /* discard state */ - if (!flushed) { - /* ccp.c will be silent (no additional CCP Reset-Requests). */ - return ERR_BUF; - } else { - /* Rekey for every missed "flag" packet. */ - while ((ccount & ~0xff) != - (state->ccount & ~0xff)) { - mppe_rekey(state, 0); - state->ccount = - (state->ccount + - 256) % MPPE_CCOUNT_SPACE; - } - - /* reset */ - state->discard = 0; - state->ccount = ccount; - /* - * Another problem with RFC 3078 here. It implies that the - * peer need not send a Reset-Ack packet. But RFC 1962 - * requires it. Hopefully, M$ does send a Reset-Ack; even - * though it isn't required for MPPE synchronization, it is - * required to reset CCP state. - */ - } - } - if (flushed) - mppe_rekey(state, 0); - } - - /* Hide MPPE header */ - pbuf_remove_header(n0, MPPE_OVHD); - - /* Decrypt the packet. */ - for (n = n0; n != NULL; n = n->next) { - lwip_arc4_crypt(&state->arc4, (u8_t*)n->payload, n->len); - if (n->tot_len == n->len) { - break; - } - } - - /* good packet credit */ - state->sanity_errors >>= 1; - - return ERR_OK; - -sanity_error: - if (state->sanity_errors >= SANITY_MAX) { - /* - * Take LCP down if the peer is sending too many bogons. - * We don't want to do this for a single or just a few - * instances since it could just be due to packet corruption. - */ - lcp_close(pcb, "Too many MPPE errors"); - } - return ERR_BUF; -} - -#endif /* PPP_SUPPORT && MPPE_SUPPORT */ diff --git a/third-party/lwip-2.1.2/netif/ppp/multilink.c b/third-party/lwip-2.1.2/netif/ppp/multilink.c deleted file mode 100644 index 62014e8c..00000000 --- a/third-party/lwip-2.1.2/netif/ppp/multilink.c +++ /dev/null @@ -1,609 +0,0 @@ -/* - * multilink.c - support routines for multilink. - * - * Copyright (c) 2000-2002 Paul Mackerras. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 3. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && defined(HAVE_MULTILINK) /* don't build if not configured for use in lwipopts.h */ - -/* Multilink support - * - * Multilink uses Samba TDB (Trivial Database Library), which - * we cannot port, because it needs a filesystem. - * - * We have to choose between doing a memory-shared TDB-clone, - * or dropping multilink support at all. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "netif/ppp/ppp_impl.h" - -#include "netif/ppp/fsm.h" -#include "netif/ppp/lcp.h" -#include "netif/ppp/tdb.h" - -bool endpoint_specified; /* user gave explicit endpoint discriminator */ -char *bundle_id; /* identifier for our bundle */ -char *blinks_id; /* key for the list of links */ -bool doing_multilink; /* multilink was enabled and agreed to */ -bool multilink_master; /* we own the multilink bundle */ - -extern TDB_CONTEXT *pppdb; -extern char db_key[]; - -static void make_bundle_links (int append); -static void remove_bundle_link (void); -static void iterate_bundle_links (void (*func) (char *)); - -static int get_default_epdisc (struct epdisc *); -static int parse_num (char *str, const char *key, int *valp); -static int owns_unit (TDB_DATA pid, int unit); - -#define set_ip_epdisc(ep, addr) do { \ - ep->length = 4; \ - ep->value[0] = addr >> 24; \ - ep->value[1] = addr >> 16; \ - ep->value[2] = addr >> 8; \ - ep->value[3] = addr; \ -} while (0) - -#define LOCAL_IP_ADDR(addr) \ - (((addr) & 0xff000000) == 0x0a000000 /* 10.x.x.x */ \ - || ((addr) & 0xfff00000) == 0xac100000 /* 172.16.x.x */ \ - || ((addr) & 0xffff0000) == 0xc0a80000) /* 192.168.x.x */ - -#define process_exists(n) (kill((n), 0) == 0 || errno != ESRCH) - -void -mp_check_options() -{ - lcp_options *wo = &lcp_wantoptions[0]; - lcp_options *ao = &lcp_allowoptions[0]; - - doing_multilink = 0; - if (!multilink) - return; - /* if we're doing multilink, we have to negotiate MRRU */ - if (!wo->neg_mrru) { - /* mrru not specified, default to mru */ - wo->mrru = wo->mru; - wo->neg_mrru = 1; - } - ao->mrru = ao->mru; - ao->neg_mrru = 1; - - if (!wo->neg_endpoint && !noendpoint) { - /* get a default endpoint value */ - wo->neg_endpoint = get_default_epdisc(&wo->endpoint); - } -} - -/* - * Make a new bundle or join us to an existing bundle - * if we are doing multilink. - */ -int -mp_join_bundle() -{ - lcp_options *go = &lcp_gotoptions[0]; - lcp_options *ho = &lcp_hisoptions[0]; - lcp_options *ao = &lcp_allowoptions[0]; - int unit, pppd_pid; - int l, mtu; - char *p; - TDB_DATA key, pid, rec; - - if (doing_multilink) { - /* have previously joined a bundle */ - if (!go->neg_mrru || !ho->neg_mrru) { - notice("oops, didn't get multilink on renegotiation"); - lcp_close(pcb, "multilink required"); - return 0; - } - /* XXX should check the peer_authname and ho->endpoint - are the same as previously */ - return 0; - } - - if (!go->neg_mrru || !ho->neg_mrru) { - /* not doing multilink */ - if (go->neg_mrru) - notice("oops, multilink negotiated only for receive"); - mtu = ho->neg_mru? ho->mru: PPP_MRU; - if (mtu > ao->mru) - mtu = ao->mru; - if (demand) { - /* already have a bundle */ - cfg_bundle(0, 0, 0, 0); - netif_set_mtu(pcb, mtu); - return 0; - } - make_new_bundle(0, 0, 0, 0); - set_ifunit(1); - netif_set_mtu(pcb, mtu); - return 0; - } - - doing_multilink = 1; - - /* - * Find the appropriate bundle or join a new one. - * First we make up a name for the bundle. - * The length estimate is worst-case assuming every - * character has to be quoted. - */ - l = 4 * strlen(peer_authname) + 10; - if (ho->neg_endpoint) - l += 3 * ho->endpoint.length + 8; - if (bundle_name) - l += 3 * strlen(bundle_name) + 2; - bundle_id = malloc(l); - if (bundle_id == 0) - novm("bundle identifier"); - - p = bundle_id; - p += slprintf(p, l-1, "BUNDLE=\"%q\"", peer_authname); - if (ho->neg_endpoint || bundle_name) - *p++ = '/'; - if (ho->neg_endpoint) - p += slprintf(p, bundle_id+l-p, "%s", - epdisc_to_str(&ho->endpoint)); - if (bundle_name) - p += slprintf(p, bundle_id+l-p, "/%v", bundle_name); - - /* Make the key for the list of links belonging to the bundle */ - l = p - bundle_id; - blinks_id = malloc(l + 7); - if (blinks_id == NULL) - novm("bundle links key"); - slprintf(blinks_id, l + 7, "BUNDLE_LINKS=%s", bundle_id + 7); - - /* - * For demand mode, we only need to configure the bundle - * and attach the link. - */ - mtu = LWIP_MIN(ho->mrru, ao->mru); - if (demand) { - cfg_bundle(go->mrru, ho->mrru, go->neg_ssnhf, ho->neg_ssnhf); - netif_set_mtu(pcb, mtu); - script_setenv("BUNDLE", bundle_id + 7, 1); - return 0; - } - - /* - * Check if the bundle ID is already in the database. - */ - unit = -1; - lock_db(); - key.dptr = bundle_id; - key.dsize = p - bundle_id; - pid = tdb_fetch(pppdb, key); - if (pid.dptr != NULL) { - /* bundle ID exists, see if the pppd record exists */ - rec = tdb_fetch(pppdb, pid); - if (rec.dptr != NULL && rec.dsize > 0) { - /* make sure the string is null-terminated */ - rec.dptr[rec.dsize-1] = 0; - /* parse the interface number */ - parse_num(rec.dptr, "IFNAME=ppp", &unit); - /* check the pid value */ - if (!parse_num(rec.dptr, "PPPD_PID=", &pppd_pid) - || !process_exists(pppd_pid) - || !owns_unit(pid, unit)) - unit = -1; - free(rec.dptr); - } - free(pid.dptr); - } - - if (unit >= 0) { - /* attach to existing unit */ - if (bundle_attach(unit)) { - set_ifunit(0); - script_setenv("BUNDLE", bundle_id + 7, 0); - make_bundle_links(1); - unlock_db(); - info("Link attached to %s", ifname); - return 1; - } - /* attach failed because bundle doesn't exist */ - } - - /* we have to make a new bundle */ - make_new_bundle(go->mrru, ho->mrru, go->neg_ssnhf, ho->neg_ssnhf); - set_ifunit(1); - netif_set_mtu(pcb, mtu); - script_setenv("BUNDLE", bundle_id + 7, 1); - make_bundle_links(pcb); - unlock_db(); - info("New bundle %s created", ifname); - multilink_master = 1; - return 0; -} - -void mp_exit_bundle() -{ - lock_db(); - remove_bundle_link(); - unlock_db(); -} - -static void sendhup(char *str) -{ - int pid; - - if (parse_num(str, "PPPD_PID=", &pid) && pid != getpid()) { - if (debug) - dbglog("sending SIGHUP to process %d", pid); - kill(pid, SIGHUP); - } -} - -void mp_bundle_terminated() -{ - TDB_DATA key; - - bundle_terminating = 1; - upper_layers_down(pcb); - notice("Connection terminated."); -#if PPP_STATS_SUPPORT - print_link_stats(); -#endif /* PPP_STATS_SUPPORT */ - if (!demand) { - remove_pidfiles(); - script_unsetenv("IFNAME"); - } - - lock_db(); - destroy_bundle(); - iterate_bundle_links(sendhup); - key.dptr = blinks_id; - key.dsize = strlen(blinks_id); - tdb_delete(pppdb, key); - unlock_db(); - - new_phase(PPP_PHASE_DEAD); - - doing_multilink = 0; - multilink_master = 0; -} - -static void make_bundle_links(int append) -{ - TDB_DATA key, rec; - char *p; - char entry[32]; - int l; - - key.dptr = blinks_id; - key.dsize = strlen(blinks_id); - slprintf(entry, sizeof(entry), "%s;", db_key); - p = entry; - if (append) { - rec = tdb_fetch(pppdb, key); - if (rec.dptr != NULL && rec.dsize > 0) { - rec.dptr[rec.dsize-1] = 0; - if (strstr(rec.dptr, db_key) != NULL) { - /* already in there? strange */ - warn("link entry already exists in tdb"); - return; - } - l = rec.dsize + strlen(entry); - p = malloc(l); - if (p == NULL) - novm("bundle link list"); - slprintf(p, l, "%s%s", rec.dptr, entry); - } else { - warn("bundle link list not found"); - } - if (rec.dptr != NULL) - free(rec.dptr); - } - rec.dptr = p; - rec.dsize = strlen(p) + 1; - if (tdb_store(pppdb, key, rec, TDB_REPLACE)) - error("couldn't %s bundle link list", - append? "update": "create"); - if (p != entry) - free(p); -} - -static void remove_bundle_link() -{ - TDB_DATA key, rec; - char entry[32]; - char *p, *q; - int l; - - key.dptr = blinks_id; - key.dsize = strlen(blinks_id); - slprintf(entry, sizeof(entry), "%s;", db_key); - - rec = tdb_fetch(pppdb, key); - if (rec.dptr == NULL || rec.dsize <= 0) { - if (rec.dptr != NULL) - free(rec.dptr); - return; - } - rec.dptr[rec.dsize-1] = 0; - p = strstr(rec.dptr, entry); - if (p != NULL) { - q = p + strlen(entry); - l = strlen(q) + 1; - memmove(p, q, l); - rec.dsize = p - rec.dptr + l; - if (tdb_store(pppdb, key, rec, TDB_REPLACE)) - error("couldn't update bundle link list (removal)"); - } - free(rec.dptr); -} - -static void iterate_bundle_links(void (*func)(char *)) -{ - TDB_DATA key, rec, pp; - char *p, *q; - - key.dptr = blinks_id; - key.dsize = strlen(blinks_id); - rec = tdb_fetch(pppdb, key); - if (rec.dptr == NULL || rec.dsize <= 0) { - error("bundle link list not found (iterating list)"); - if (rec.dptr != NULL) - free(rec.dptr); - return; - } - p = rec.dptr; - p[rec.dsize-1] = 0; - while ((q = strchr(p, ';')) != NULL) { - *q = 0; - key.dptr = p; - key.dsize = q - p; - pp = tdb_fetch(pppdb, key); - if (pp.dptr != NULL && pp.dsize > 0) { - pp.dptr[pp.dsize-1] = 0; - func(pp.dptr); - } - if (pp.dptr != NULL) - free(pp.dptr); - p = q + 1; - } - free(rec.dptr); -} - -static int -parse_num(str, key, valp) - char *str; - const char *key; - int *valp; -{ - char *p, *endp; - int i; - - p = strstr(str, key); - if (p != 0) { - p += strlen(key); - i = strtol(p, &endp, 10); - if (endp != p && (*endp == 0 || *endp == ';')) { - *valp = i; - return 1; - } - } - return 0; -} - -/* - * Check whether the pppd identified by `key' still owns ppp unit `unit'. - */ -static int -owns_unit(key, unit) - TDB_DATA key; - int unit; -{ - char ifkey[32]; - TDB_DATA kd, vd; - int ret = 0; - - slprintf(ifkey, sizeof(ifkey), "IFNAME=ppp%d", unit); - kd.dptr = ifkey; - kd.dsize = strlen(ifkey); - vd = tdb_fetch(pppdb, kd); - if (vd.dptr != NULL) { - ret = vd.dsize == key.dsize - && memcmp(vd.dptr, key.dptr, vd.dsize) == 0; - free(vd.dptr); - } - return ret; -} - -static int -get_default_epdisc(ep) - struct epdisc *ep; -{ - char *p; - struct hostent *hp; - u32_t addr; - - /* First try for an ethernet MAC address */ - p = get_first_ethernet(); - if (p != 0 && get_if_hwaddr(ep->value, p) >= 0) { - ep->class = EPD_MAC; - ep->length = 6; - return 1; - } - - /* see if our hostname corresponds to a reasonable IP address */ - hp = gethostbyname(hostname); - if (hp != NULL) { - addr = *(u32_t *)hp->h_addr; - if (!bad_ip_adrs(addr)) { - addr = lwip_ntohl(addr); - if (!LOCAL_IP_ADDR(addr)) { - ep->class = EPD_IP; - set_ip_epdisc(ep, addr); - return 1; - } - } - } - - return 0; -} - -/* - * epdisc_to_str - make a printable string from an endpoint discriminator. - */ - -static char *endp_class_names[] = { - "null", "local", "IP", "MAC", "magic", "phone" -}; - -char * -epdisc_to_str(ep) - struct epdisc *ep; -{ - static char str[MAX_ENDP_LEN*3+8]; - u_char *p = ep->value; - int i, mask = 0; - char *q, c, c2; - - if (ep->class == EPD_NULL && ep->length == 0) - return "null"; - if (ep->class == EPD_IP && ep->length == 4) { - u32_t addr; - - GETLONG(addr, p); - slprintf(str, sizeof(str), "IP:%I", lwip_htonl(addr)); - return str; - } - - c = ':'; - c2 = '.'; - if (ep->class == EPD_MAC && ep->length == 6) - c2 = ':'; - else if (ep->class == EPD_MAGIC && (ep->length % 4) == 0) - mask = 3; - q = str; - if (ep->class <= EPD_PHONENUM) - q += slprintf(q, sizeof(str)-1, "%s", - endp_class_names[ep->class]); - else - q += slprintf(q, sizeof(str)-1, "%d", ep->class); - c = ':'; - for (i = 0; i < ep->length && i < MAX_ENDP_LEN; ++i) { - if ((i & mask) == 0) { - *q++ = c; - c = c2; - } - q += slprintf(q, str + sizeof(str) - q, "%.2x", ep->value[i]); - } - return str; -} - -static int hexc_val(int c) -{ - if (c >= 'a') - return c - 'a' + 10; - if (c >= 'A') - return c - 'A' + 10; - return c - '0'; -} - -int -str_to_epdisc(ep, str) - struct epdisc *ep; - char *str; -{ - int i, l; - char *p, *endp; - - for (i = EPD_NULL; i <= EPD_PHONENUM; ++i) { - int sl = strlen(endp_class_names[i]); - if (strncasecmp(str, endp_class_names[i], sl) == 0) { - str += sl; - break; - } - } - if (i > EPD_PHONENUM) { - /* not a class name, try a decimal class number */ - i = strtol(str, &endp, 10); - if (endp == str) - return 0; /* can't parse class number */ - str = endp; - } - ep->class = i; - if (*str == 0) { - ep->length = 0; - return 1; - } - if (*str != ':' && *str != '.') - return 0; - ++str; - - if (i == EPD_IP) { - u32_t addr; - i = parse_dotted_ip(str, &addr); - if (i == 0 || str[i] != 0) - return 0; - set_ip_epdisc(ep, addr); - return 1; - } - if (i == EPD_MAC && get_if_hwaddr(ep->value, str) >= 0) { - ep->length = 6; - return 1; - } - - p = str; - for (l = 0; l < MAX_ENDP_LEN; ++l) { - if (*str == 0) - break; - if (p <= str) - for (p = str; isxdigit(*p); ++p) - ; - i = p - str; - if (i == 0) - return 0; - ep->value[l] = hexc_val(*str++); - if ((i & 1) == 0) - ep->value[l] = (ep->value[l] << 4) + hexc_val(*str++); - if (*str == ':' || *str == '.') - ++str; - } - if (*str != 0 || (ep->class == EPD_MAC && l != 6)) - return 0; - ep->length = l; - return 1; -} - -#endif /* PPP_SUPPORT && HAVE_MULTILINK */ diff --git a/third-party/lwip-2.1.2/netif/ppp/polarssl/README b/third-party/lwip-2.1.2/netif/ppp/polarssl/README deleted file mode 100644 index 3fdf159e..00000000 --- a/third-party/lwip-2.1.2/netif/ppp/polarssl/README +++ /dev/null @@ -1,22 +0,0 @@ -About PolarSSL files into lwIP PPP support ------------------------------------------- - -This folder contains some files fetched from the latest BSD release of -the PolarSSL project (PolarSSL 0.10.1-bsd) for ciphers and encryption -methods we need for lwIP PPP support. - -The PolarSSL files were cleaned to contain only the necessary struct -fields and functions needed for lwIP. - -The PolarSSL API was not changed at all, so if you are already using -PolarSSL you can choose to skip the compilation of the included PolarSSL -library into lwIP. - -If you are not using the embedded copy you must include external -libraries into your arch/cc.h port file. - -Beware of the stack requirements which can be a lot larger if you are not -using our cleaned PolarSSL library. - - -PolarSSL project website: http://polarssl.org/ diff --git a/third-party/lwip-2.1.2/netif/ppp/polarssl/arc4.c b/third-party/lwip-2.1.2/netif/ppp/polarssl/arc4.c deleted file mode 100644 index 6e17ec42..00000000 --- a/third-party/lwip-2.1.2/netif/ppp/polarssl/arc4.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * An implementation of the ARCFOUR algorithm - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the names of PolarSSL or XySSL nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * The ARCFOUR algorithm was publicly disclosed on 94/09. - * - * http://groups.google.com/group/sci.crypt/msg/10a300c9d21afca0 - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_ARC4 - -#include "netif/ppp/polarssl/arc4.h" -/* - * ARC4 key schedule - */ -void arc4_setup( arc4_context *ctx, unsigned char *key, int keylen ) -{ - int i, j, k, a; - unsigned char *m; - - ctx->x = 0; - ctx->y = 0; - m = ctx->m; - - for( i = 0; i < 256; i++ ) - m[i] = (unsigned char) i; - - j = k = 0; - - for( i = 0; i < 256; i++, k++ ) - { - if( k >= keylen ) k = 0; - - a = m[i]; - j = ( j + a + key[k] ) & 0xFF; - m[i] = m[j]; - m[j] = (unsigned char) a; - } -} - -/* - * ARC4 cipher function - */ -void arc4_crypt( arc4_context *ctx, unsigned char *buf, int buflen ) -{ - int i, x, y, a, b; - unsigned char *m; - - x = ctx->x; - y = ctx->y; - m = ctx->m; - - for( i = 0; i < buflen; i++ ) - { - x = ( x + 1 ) & 0xFF; a = m[x]; - y = ( y + a ) & 0xFF; b = m[y]; - - m[x] = (unsigned char) b; - m[y] = (unsigned char) a; - - buf[i] = (unsigned char) - ( buf[i] ^ m[(unsigned char)( a + b )] ); - } - - ctx->x = x; - ctx->y = y; -} - -#endif /* PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_DES */ diff --git a/third-party/lwip-2.1.2/netif/ppp/polarssl/des.c b/third-party/lwip-2.1.2/netif/ppp/polarssl/des.c deleted file mode 100644 index 9a89d007..00000000 --- a/third-party/lwip-2.1.2/netif/ppp/polarssl/des.c +++ /dev/null @@ -1,422 +0,0 @@ -/* - * FIPS-46-3 compliant Triple-DES implementation - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the names of PolarSSL or XySSL nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * DES, on which TDES is based, was originally designed by Horst Feistel - * at IBM in 1974, and was adopted as a standard by NIST (formerly NBS). - * - * http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_DES - -#include "netif/ppp/polarssl/des.h" - -/* - * 32-bit integer manipulation macros (big endian) - */ -#ifndef GET_ULONG_BE -#define GET_ULONG_BE(n,b,i) \ -{ \ - (n) = ( (unsigned long) (b)[(i) ] << 24 ) \ - | ( (unsigned long) (b)[(i) + 1] << 16 ) \ - | ( (unsigned long) (b)[(i) + 2] << 8 ) \ - | ( (unsigned long) (b)[(i) + 3] ); \ -} -#endif - -#ifndef PUT_ULONG_BE -#define PUT_ULONG_BE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) ); \ -} -#endif - -/* - * Expanded DES S-boxes - */ -static const unsigned long SB1[64] = -{ - 0x01010400, 0x00000000, 0x00010000, 0x01010404, - 0x01010004, 0x00010404, 0x00000004, 0x00010000, - 0x00000400, 0x01010400, 0x01010404, 0x00000400, - 0x01000404, 0x01010004, 0x01000000, 0x00000004, - 0x00000404, 0x01000400, 0x01000400, 0x00010400, - 0x00010400, 0x01010000, 0x01010000, 0x01000404, - 0x00010004, 0x01000004, 0x01000004, 0x00010004, - 0x00000000, 0x00000404, 0x00010404, 0x01000000, - 0x00010000, 0x01010404, 0x00000004, 0x01010000, - 0x01010400, 0x01000000, 0x01000000, 0x00000400, - 0x01010004, 0x00010000, 0x00010400, 0x01000004, - 0x00000400, 0x00000004, 0x01000404, 0x00010404, - 0x01010404, 0x00010004, 0x01010000, 0x01000404, - 0x01000004, 0x00000404, 0x00010404, 0x01010400, - 0x00000404, 0x01000400, 0x01000400, 0x00000000, - 0x00010004, 0x00010400, 0x00000000, 0x01010004 -}; - -static const unsigned long SB2[64] = -{ - 0x80108020, 0x80008000, 0x00008000, 0x00108020, - 0x00100000, 0x00000020, 0x80100020, 0x80008020, - 0x80000020, 0x80108020, 0x80108000, 0x80000000, - 0x80008000, 0x00100000, 0x00000020, 0x80100020, - 0x00108000, 0x00100020, 0x80008020, 0x00000000, - 0x80000000, 0x00008000, 0x00108020, 0x80100000, - 0x00100020, 0x80000020, 0x00000000, 0x00108000, - 0x00008020, 0x80108000, 0x80100000, 0x00008020, - 0x00000000, 0x00108020, 0x80100020, 0x00100000, - 0x80008020, 0x80100000, 0x80108000, 0x00008000, - 0x80100000, 0x80008000, 0x00000020, 0x80108020, - 0x00108020, 0x00000020, 0x00008000, 0x80000000, - 0x00008020, 0x80108000, 0x00100000, 0x80000020, - 0x00100020, 0x80008020, 0x80000020, 0x00100020, - 0x00108000, 0x00000000, 0x80008000, 0x00008020, - 0x80000000, 0x80100020, 0x80108020, 0x00108000 -}; - -static const unsigned long SB3[64] = -{ - 0x00000208, 0x08020200, 0x00000000, 0x08020008, - 0x08000200, 0x00000000, 0x00020208, 0x08000200, - 0x00020008, 0x08000008, 0x08000008, 0x00020000, - 0x08020208, 0x00020008, 0x08020000, 0x00000208, - 0x08000000, 0x00000008, 0x08020200, 0x00000200, - 0x00020200, 0x08020000, 0x08020008, 0x00020208, - 0x08000208, 0x00020200, 0x00020000, 0x08000208, - 0x00000008, 0x08020208, 0x00000200, 0x08000000, - 0x08020200, 0x08000000, 0x00020008, 0x00000208, - 0x00020000, 0x08020200, 0x08000200, 0x00000000, - 0x00000200, 0x00020008, 0x08020208, 0x08000200, - 0x08000008, 0x00000200, 0x00000000, 0x08020008, - 0x08000208, 0x00020000, 0x08000000, 0x08020208, - 0x00000008, 0x00020208, 0x00020200, 0x08000008, - 0x08020000, 0x08000208, 0x00000208, 0x08020000, - 0x00020208, 0x00000008, 0x08020008, 0x00020200 -}; - -static const unsigned long SB4[64] = -{ - 0x00802001, 0x00002081, 0x00002081, 0x00000080, - 0x00802080, 0x00800081, 0x00800001, 0x00002001, - 0x00000000, 0x00802000, 0x00802000, 0x00802081, - 0x00000081, 0x00000000, 0x00800080, 0x00800001, - 0x00000001, 0x00002000, 0x00800000, 0x00802001, - 0x00000080, 0x00800000, 0x00002001, 0x00002080, - 0x00800081, 0x00000001, 0x00002080, 0x00800080, - 0x00002000, 0x00802080, 0x00802081, 0x00000081, - 0x00800080, 0x00800001, 0x00802000, 0x00802081, - 0x00000081, 0x00000000, 0x00000000, 0x00802000, - 0x00002080, 0x00800080, 0x00800081, 0x00000001, - 0x00802001, 0x00002081, 0x00002081, 0x00000080, - 0x00802081, 0x00000081, 0x00000001, 0x00002000, - 0x00800001, 0x00002001, 0x00802080, 0x00800081, - 0x00002001, 0x00002080, 0x00800000, 0x00802001, - 0x00000080, 0x00800000, 0x00002000, 0x00802080 -}; - -static const unsigned long SB5[64] = -{ - 0x00000100, 0x02080100, 0x02080000, 0x42000100, - 0x00080000, 0x00000100, 0x40000000, 0x02080000, - 0x40080100, 0x00080000, 0x02000100, 0x40080100, - 0x42000100, 0x42080000, 0x00080100, 0x40000000, - 0x02000000, 0x40080000, 0x40080000, 0x00000000, - 0x40000100, 0x42080100, 0x42080100, 0x02000100, - 0x42080000, 0x40000100, 0x00000000, 0x42000000, - 0x02080100, 0x02000000, 0x42000000, 0x00080100, - 0x00080000, 0x42000100, 0x00000100, 0x02000000, - 0x40000000, 0x02080000, 0x42000100, 0x40080100, - 0x02000100, 0x40000000, 0x42080000, 0x02080100, - 0x40080100, 0x00000100, 0x02000000, 0x42080000, - 0x42080100, 0x00080100, 0x42000000, 0x42080100, - 0x02080000, 0x00000000, 0x40080000, 0x42000000, - 0x00080100, 0x02000100, 0x40000100, 0x00080000, - 0x00000000, 0x40080000, 0x02080100, 0x40000100 -}; - -static const unsigned long SB6[64] = -{ - 0x20000010, 0x20400000, 0x00004000, 0x20404010, - 0x20400000, 0x00000010, 0x20404010, 0x00400000, - 0x20004000, 0x00404010, 0x00400000, 0x20000010, - 0x00400010, 0x20004000, 0x20000000, 0x00004010, - 0x00000000, 0x00400010, 0x20004010, 0x00004000, - 0x00404000, 0x20004010, 0x00000010, 0x20400010, - 0x20400010, 0x00000000, 0x00404010, 0x20404000, - 0x00004010, 0x00404000, 0x20404000, 0x20000000, - 0x20004000, 0x00000010, 0x20400010, 0x00404000, - 0x20404010, 0x00400000, 0x00004010, 0x20000010, - 0x00400000, 0x20004000, 0x20000000, 0x00004010, - 0x20000010, 0x20404010, 0x00404000, 0x20400000, - 0x00404010, 0x20404000, 0x00000000, 0x20400010, - 0x00000010, 0x00004000, 0x20400000, 0x00404010, - 0x00004000, 0x00400010, 0x20004010, 0x00000000, - 0x20404000, 0x20000000, 0x00400010, 0x20004010 -}; - -static const unsigned long SB7[64] = -{ - 0x00200000, 0x04200002, 0x04000802, 0x00000000, - 0x00000800, 0x04000802, 0x00200802, 0x04200800, - 0x04200802, 0x00200000, 0x00000000, 0x04000002, - 0x00000002, 0x04000000, 0x04200002, 0x00000802, - 0x04000800, 0x00200802, 0x00200002, 0x04000800, - 0x04000002, 0x04200000, 0x04200800, 0x00200002, - 0x04200000, 0x00000800, 0x00000802, 0x04200802, - 0x00200800, 0x00000002, 0x04000000, 0x00200800, - 0x04000000, 0x00200800, 0x00200000, 0x04000802, - 0x04000802, 0x04200002, 0x04200002, 0x00000002, - 0x00200002, 0x04000000, 0x04000800, 0x00200000, - 0x04200800, 0x00000802, 0x00200802, 0x04200800, - 0x00000802, 0x04000002, 0x04200802, 0x04200000, - 0x00200800, 0x00000000, 0x00000002, 0x04200802, - 0x00000000, 0x00200802, 0x04200000, 0x00000800, - 0x04000002, 0x04000800, 0x00000800, 0x00200002 -}; - -static const unsigned long SB8[64] = -{ - 0x10001040, 0x00001000, 0x00040000, 0x10041040, - 0x10000000, 0x10001040, 0x00000040, 0x10000000, - 0x00040040, 0x10040000, 0x10041040, 0x00041000, - 0x10041000, 0x00041040, 0x00001000, 0x00000040, - 0x10040000, 0x10000040, 0x10001000, 0x00001040, - 0x00041000, 0x00040040, 0x10040040, 0x10041000, - 0x00001040, 0x00000000, 0x00000000, 0x10040040, - 0x10000040, 0x10001000, 0x00041040, 0x00040000, - 0x00041040, 0x00040000, 0x10041000, 0x00001000, - 0x00000040, 0x10040040, 0x00001000, 0x00041040, - 0x10001000, 0x00000040, 0x10000040, 0x10040000, - 0x10040040, 0x10000000, 0x00040000, 0x10001040, - 0x00000000, 0x10041040, 0x00040040, 0x10000040, - 0x10040000, 0x10001000, 0x10001040, 0x00000000, - 0x10041040, 0x00041000, 0x00041000, 0x00001040, - 0x00001040, 0x00040040, 0x10000000, 0x10041000 -}; - -/* - * PC1: left and right halves bit-swap - */ -static const unsigned long LHs[16] = -{ - 0x00000000, 0x00000001, 0x00000100, 0x00000101, - 0x00010000, 0x00010001, 0x00010100, 0x00010101, - 0x01000000, 0x01000001, 0x01000100, 0x01000101, - 0x01010000, 0x01010001, 0x01010100, 0x01010101 -}; - -static const unsigned long RHs[16] = -{ - 0x00000000, 0x01000000, 0x00010000, 0x01010000, - 0x00000100, 0x01000100, 0x00010100, 0x01010100, - 0x00000001, 0x01000001, 0x00010001, 0x01010001, - 0x00000101, 0x01000101, 0x00010101, 0x01010101, -}; - -/* - * Initial Permutation macro - */ -#define DES_IP(X,Y) \ -{ \ - T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \ - T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \ - T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \ - T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \ - Y = ((Y << 1) | (Y >> 31)) & 0xFFFFFFFF; \ - T = (X ^ Y) & 0xAAAAAAAA; Y ^= T; X ^= T; \ - X = ((X << 1) | (X >> 31)) & 0xFFFFFFFF; \ -} - -/* - * Final Permutation macro - */ -#define DES_FP(X,Y) \ -{ \ - X = ((X << 31) | (X >> 1)) & 0xFFFFFFFF; \ - T = (X ^ Y) & 0xAAAAAAAA; X ^= T; Y ^= T; \ - Y = ((Y << 31) | (Y >> 1)) & 0xFFFFFFFF; \ - T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \ - T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \ - T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \ - T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \ -} - -/* - * DES round macro - */ -#define DES_ROUND(X,Y) \ -{ \ - T = *SK++ ^ X; \ - Y ^= SB8[ (T ) & 0x3F ] ^ \ - SB6[ (T >> 8) & 0x3F ] ^ \ - SB4[ (T >> 16) & 0x3F ] ^ \ - SB2[ (T >> 24) & 0x3F ]; \ - \ - T = *SK++ ^ ((X << 28) | (X >> 4)); \ - Y ^= SB7[ (T ) & 0x3F ] ^ \ - SB5[ (T >> 8) & 0x3F ] ^ \ - SB3[ (T >> 16) & 0x3F ] ^ \ - SB1[ (T >> 24) & 0x3F ]; \ -} - -#define SWAP(a,b) { unsigned long t = a; a = b; b = t; t = 0; } - -static void des_setkey( unsigned long SK[32], unsigned char key[8] ) -{ - int i; - unsigned long X, Y, T; - - GET_ULONG_BE( X, key, 0 ); - GET_ULONG_BE( Y, key, 4 ); - - /* - * Permuted Choice 1 - */ - T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4); - T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T ); - - X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2) - | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] ) - | (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6) - | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4); - - Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2) - | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] ) - | (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6) - | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4); - - X &= 0x0FFFFFFF; - Y &= 0x0FFFFFFF; - - /* - * calculate subkeys - */ - for( i = 0; i < 16; i++ ) - { - if( i < 2 || i == 8 || i == 15 ) - { - X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF; - Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF; - } - else - { - X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF; - Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF; - } - - *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000) - | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000) - | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000) - | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000) - | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000) - | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000) - | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400) - | ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100) - | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010) - | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004) - | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001); - - *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000) - | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000) - | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000) - | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000) - | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000) - | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000) - | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000) - | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400) - | ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100) - | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011) - | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002); - } -} - -/* - * DES key schedule (56-bit, encryption) - */ -void des_setkey_enc( des_context *ctx, unsigned char key[8] ) -{ - des_setkey( ctx->sk, key ); -} - -/* - * DES key schedule (56-bit, decryption) - */ -void des_setkey_dec( des_context *ctx, unsigned char key[8] ) -{ - int i; - - des_setkey( ctx->sk, key ); - - for( i = 0; i < 16; i += 2 ) - { - SWAP( ctx->sk[i ], ctx->sk[30 - i] ); - SWAP( ctx->sk[i + 1], ctx->sk[31 - i] ); - } -} - -/* - * DES-ECB block encryption/decryption - */ -void des_crypt_ecb( des_context *ctx, - const unsigned char input[8], - unsigned char output[8] ) -{ - int i; - unsigned long X, Y, T, *SK; - - SK = ctx->sk; - - GET_ULONG_BE( X, input, 0 ); - GET_ULONG_BE( Y, input, 4 ); - - DES_IP( X, Y ); - - for( i = 0; i < 8; i++ ) - { - DES_ROUND( Y, X ); - DES_ROUND( X, Y ); - } - - DES_FP( Y, X ); - - PUT_ULONG_BE( Y, output, 0 ); - PUT_ULONG_BE( X, output, 4 ); -} - -#endif /* PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_DES */ diff --git a/third-party/lwip-2.1.2/netif/ppp/polarssl/md4.c b/third-party/lwip-2.1.2/netif/ppp/polarssl/md4.c deleted file mode 100644 index b1701a07..00000000 --- a/third-party/lwip-2.1.2/netif/ppp/polarssl/md4.c +++ /dev/null @@ -1,281 +0,0 @@ -/* - * RFC 1186/1320 compliant MD4 implementation - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the names of PolarSSL or XySSL nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * The MD4 algorithm was designed by Ron Rivest in 1990. - * - * http://www.ietf.org/rfc/rfc1186.txt - * http://www.ietf.org/rfc/rfc1320.txt - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_MD4 - -#include "netif/ppp/polarssl/md4.h" - -#include - -/* - * 32-bit integer manipulation macros (little endian) - */ -#ifndef GET_ULONG_LE -#define GET_ULONG_LE(n,b,i) \ -{ \ - (n) = ( (unsigned long) (b)[(i) ] ) \ - | ( (unsigned long) (b)[(i) + 1] << 8 ) \ - | ( (unsigned long) (b)[(i) + 2] << 16 ) \ - | ( (unsigned long) (b)[(i) + 3] << 24 ); \ -} -#endif - -#ifndef PUT_ULONG_LE -#define PUT_ULONG_LE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( (n) ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ -} -#endif - -/* - * MD4 context setup - */ -void md4_starts( md4_context *ctx ) -{ - ctx->total[0] = 0; - ctx->total[1] = 0; - - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; -} - -static void md4_process( md4_context *ctx, const unsigned char data[64] ) -{ - unsigned long X[16], A, B, C, D; - - GET_ULONG_LE( X[ 0], data, 0 ); - GET_ULONG_LE( X[ 1], data, 4 ); - GET_ULONG_LE( X[ 2], data, 8 ); - GET_ULONG_LE( X[ 3], data, 12 ); - GET_ULONG_LE( X[ 4], data, 16 ); - GET_ULONG_LE( X[ 5], data, 20 ); - GET_ULONG_LE( X[ 6], data, 24 ); - GET_ULONG_LE( X[ 7], data, 28 ); - GET_ULONG_LE( X[ 8], data, 32 ); - GET_ULONG_LE( X[ 9], data, 36 ); - GET_ULONG_LE( X[10], data, 40 ); - GET_ULONG_LE( X[11], data, 44 ); - GET_ULONG_LE( X[12], data, 48 ); - GET_ULONG_LE( X[13], data, 52 ); - GET_ULONG_LE( X[14], data, 56 ); - GET_ULONG_LE( X[15], data, 60 ); - -#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) - - A = ctx->state[0]; - B = ctx->state[1]; - C = ctx->state[2]; - D = ctx->state[3]; - -#define F(x, y, z) ((x & y) | ((~x) & z)) -#define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); } - - P( A, B, C, D, X[ 0], 3 ); - P( D, A, B, C, X[ 1], 7 ); - P( C, D, A, B, X[ 2], 11 ); - P( B, C, D, A, X[ 3], 19 ); - P( A, B, C, D, X[ 4], 3 ); - P( D, A, B, C, X[ 5], 7 ); - P( C, D, A, B, X[ 6], 11 ); - P( B, C, D, A, X[ 7], 19 ); - P( A, B, C, D, X[ 8], 3 ); - P( D, A, B, C, X[ 9], 7 ); - P( C, D, A, B, X[10], 11 ); - P( B, C, D, A, X[11], 19 ); - P( A, B, C, D, X[12], 3 ); - P( D, A, B, C, X[13], 7 ); - P( C, D, A, B, X[14], 11 ); - P( B, C, D, A, X[15], 19 ); - -#undef P -#undef F - -#define F(x,y,z) ((x & y) | (x & z) | (y & z)) -#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); } - - P( A, B, C, D, X[ 0], 3 ); - P( D, A, B, C, X[ 4], 5 ); - P( C, D, A, B, X[ 8], 9 ); - P( B, C, D, A, X[12], 13 ); - P( A, B, C, D, X[ 1], 3 ); - P( D, A, B, C, X[ 5], 5 ); - P( C, D, A, B, X[ 9], 9 ); - P( B, C, D, A, X[13], 13 ); - P( A, B, C, D, X[ 2], 3 ); - P( D, A, B, C, X[ 6], 5 ); - P( C, D, A, B, X[10], 9 ); - P( B, C, D, A, X[14], 13 ); - P( A, B, C, D, X[ 3], 3 ); - P( D, A, B, C, X[ 7], 5 ); - P( C, D, A, B, X[11], 9 ); - P( B, C, D, A, X[15], 13 ); - -#undef P -#undef F - -#define F(x,y,z) (x ^ y ^ z) -#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); } - - P( A, B, C, D, X[ 0], 3 ); - P( D, A, B, C, X[ 8], 9 ); - P( C, D, A, B, X[ 4], 11 ); - P( B, C, D, A, X[12], 15 ); - P( A, B, C, D, X[ 2], 3 ); - P( D, A, B, C, X[10], 9 ); - P( C, D, A, B, X[ 6], 11 ); - P( B, C, D, A, X[14], 15 ); - P( A, B, C, D, X[ 1], 3 ); - P( D, A, B, C, X[ 9], 9 ); - P( C, D, A, B, X[ 5], 11 ); - P( B, C, D, A, X[13], 15 ); - P( A, B, C, D, X[ 3], 3 ); - P( D, A, B, C, X[11], 9 ); - P( C, D, A, B, X[ 7], 11 ); - P( B, C, D, A, X[15], 15 ); - -#undef F -#undef P - - ctx->state[0] += A; - ctx->state[1] += B; - ctx->state[2] += C; - ctx->state[3] += D; -} - -/* - * MD4 process buffer - */ -void md4_update( md4_context *ctx, const unsigned char *input, int ilen ) -{ - int fill; - unsigned long left; - - if( ilen <= 0 ) - return; - - left = ctx->total[0] & 0x3F; - fill = 64 - left; - - ctx->total[0] += ilen; - ctx->total[0] &= 0xFFFFFFFF; - - if( ctx->total[0] < (unsigned long) ilen ) - ctx->total[1]++; - - if( left && ilen >= fill ) - { - MEMCPY( (void *) (ctx->buffer + left), - input, fill ); - md4_process( ctx, ctx->buffer ); - input += fill; - ilen -= fill; - left = 0; - } - - while( ilen >= 64 ) - { - md4_process( ctx, input ); - input += 64; - ilen -= 64; - } - - if( ilen > 0 ) - { - MEMCPY( (void *) (ctx->buffer + left), - input, ilen ); - } -} - -static const unsigned char md4_padding[64] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* - * MD4 final digest - */ -void md4_finish( md4_context *ctx, unsigned char output[16] ) -{ - unsigned long last, padn; - unsigned long high, low; - unsigned char msglen[8]; - - high = ( ctx->total[0] >> 29 ) - | ( ctx->total[1] << 3 ); - low = ( ctx->total[0] << 3 ); - - PUT_ULONG_LE( low, msglen, 0 ); - PUT_ULONG_LE( high, msglen, 4 ); - - last = ctx->total[0] & 0x3F; - padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); - - md4_update( ctx, md4_padding, padn ); - md4_update( ctx, msglen, 8 ); - - PUT_ULONG_LE( ctx->state[0], output, 0 ); - PUT_ULONG_LE( ctx->state[1], output, 4 ); - PUT_ULONG_LE( ctx->state[2], output, 8 ); - PUT_ULONG_LE( ctx->state[3], output, 12 ); -} - -/* - * output = MD4( input buffer ) - */ -void md4( unsigned char *input, int ilen, unsigned char output[16] ) -{ - md4_context ctx; - - md4_starts( &ctx ); - md4_update( &ctx, input, ilen ); - md4_finish( &ctx, output ); -} - -#endif /* PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_MD4 */ diff --git a/third-party/lwip-2.1.2/netif/ppp/polarssl/md5.c b/third-party/lwip-2.1.2/netif/ppp/polarssl/md5.c deleted file mode 100644 index 1ec4d81a..00000000 --- a/third-party/lwip-2.1.2/netif/ppp/polarssl/md5.c +++ /dev/null @@ -1,300 +0,0 @@ -/* - * RFC 1321 compliant MD5 implementation - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the names of PolarSSL or XySSL nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * The MD5 algorithm was designed by Ron Rivest in 1991. - * - * http://www.ietf.org/rfc/rfc1321.txt - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_MD5 - -#include "netif/ppp/polarssl/md5.h" - -#include - -/* - * 32-bit integer manipulation macros (little endian) - */ -#ifndef GET_ULONG_LE -#define GET_ULONG_LE(n,b,i) \ -{ \ - (n) = ( (unsigned long) (b)[(i) ] ) \ - | ( (unsigned long) (b)[(i) + 1] << 8 ) \ - | ( (unsigned long) (b)[(i) + 2] << 16 ) \ - | ( (unsigned long) (b)[(i) + 3] << 24 ); \ -} -#endif - -#ifndef PUT_ULONG_LE -#define PUT_ULONG_LE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( (n) ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ -} -#endif - -/* - * MD5 context setup - */ -void md5_starts( md5_context *ctx ) -{ - ctx->total[0] = 0; - ctx->total[1] = 0; - - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; -} - -static void md5_process( md5_context *ctx, const unsigned char data[64] ) -{ - unsigned long X[16], A, B, C, D; - - GET_ULONG_LE( X[ 0], data, 0 ); - GET_ULONG_LE( X[ 1], data, 4 ); - GET_ULONG_LE( X[ 2], data, 8 ); - GET_ULONG_LE( X[ 3], data, 12 ); - GET_ULONG_LE( X[ 4], data, 16 ); - GET_ULONG_LE( X[ 5], data, 20 ); - GET_ULONG_LE( X[ 6], data, 24 ); - GET_ULONG_LE( X[ 7], data, 28 ); - GET_ULONG_LE( X[ 8], data, 32 ); - GET_ULONG_LE( X[ 9], data, 36 ); - GET_ULONG_LE( X[10], data, 40 ); - GET_ULONG_LE( X[11], data, 44 ); - GET_ULONG_LE( X[12], data, 48 ); - GET_ULONG_LE( X[13], data, 52 ); - GET_ULONG_LE( X[14], data, 56 ); - GET_ULONG_LE( X[15], data, 60 ); - -#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) - -#define P(a,b,c,d,k,s,t) \ -{ \ - a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \ -} - - A = ctx->state[0]; - B = ctx->state[1]; - C = ctx->state[2]; - D = ctx->state[3]; - -#define F(x,y,z) (z ^ (x & (y ^ z))) - - P( A, B, C, D, 0, 7, 0xD76AA478 ); - P( D, A, B, C, 1, 12, 0xE8C7B756 ); - P( C, D, A, B, 2, 17, 0x242070DB ); - P( B, C, D, A, 3, 22, 0xC1BDCEEE ); - P( A, B, C, D, 4, 7, 0xF57C0FAF ); - P( D, A, B, C, 5, 12, 0x4787C62A ); - P( C, D, A, B, 6, 17, 0xA8304613 ); - P( B, C, D, A, 7, 22, 0xFD469501 ); - P( A, B, C, D, 8, 7, 0x698098D8 ); - P( D, A, B, C, 9, 12, 0x8B44F7AF ); - P( C, D, A, B, 10, 17, 0xFFFF5BB1 ); - P( B, C, D, A, 11, 22, 0x895CD7BE ); - P( A, B, C, D, 12, 7, 0x6B901122 ); - P( D, A, B, C, 13, 12, 0xFD987193 ); - P( C, D, A, B, 14, 17, 0xA679438E ); - P( B, C, D, A, 15, 22, 0x49B40821 ); - -#undef F - -#define F(x,y,z) (y ^ (z & (x ^ y))) - - P( A, B, C, D, 1, 5, 0xF61E2562 ); - P( D, A, B, C, 6, 9, 0xC040B340 ); - P( C, D, A, B, 11, 14, 0x265E5A51 ); - P( B, C, D, A, 0, 20, 0xE9B6C7AA ); - P( A, B, C, D, 5, 5, 0xD62F105D ); - P( D, A, B, C, 10, 9, 0x02441453 ); - P( C, D, A, B, 15, 14, 0xD8A1E681 ); - P( B, C, D, A, 4, 20, 0xE7D3FBC8 ); - P( A, B, C, D, 9, 5, 0x21E1CDE6 ); - P( D, A, B, C, 14, 9, 0xC33707D6 ); - P( C, D, A, B, 3, 14, 0xF4D50D87 ); - P( B, C, D, A, 8, 20, 0x455A14ED ); - P( A, B, C, D, 13, 5, 0xA9E3E905 ); - P( D, A, B, C, 2, 9, 0xFCEFA3F8 ); - P( C, D, A, B, 7, 14, 0x676F02D9 ); - P( B, C, D, A, 12, 20, 0x8D2A4C8A ); - -#undef F - -#define F(x,y,z) (x ^ y ^ z) - - P( A, B, C, D, 5, 4, 0xFFFA3942 ); - P( D, A, B, C, 8, 11, 0x8771F681 ); - P( C, D, A, B, 11, 16, 0x6D9D6122 ); - P( B, C, D, A, 14, 23, 0xFDE5380C ); - P( A, B, C, D, 1, 4, 0xA4BEEA44 ); - P( D, A, B, C, 4, 11, 0x4BDECFA9 ); - P( C, D, A, B, 7, 16, 0xF6BB4B60 ); - P( B, C, D, A, 10, 23, 0xBEBFBC70 ); - P( A, B, C, D, 13, 4, 0x289B7EC6 ); - P( D, A, B, C, 0, 11, 0xEAA127FA ); - P( C, D, A, B, 3, 16, 0xD4EF3085 ); - P( B, C, D, A, 6, 23, 0x04881D05 ); - P( A, B, C, D, 9, 4, 0xD9D4D039 ); - P( D, A, B, C, 12, 11, 0xE6DB99E5 ); - P( C, D, A, B, 15, 16, 0x1FA27CF8 ); - P( B, C, D, A, 2, 23, 0xC4AC5665 ); - -#undef F - -#define F(x,y,z) (y ^ (x | ~z)) - - P( A, B, C, D, 0, 6, 0xF4292244 ); - P( D, A, B, C, 7, 10, 0x432AFF97 ); - P( C, D, A, B, 14, 15, 0xAB9423A7 ); - P( B, C, D, A, 5, 21, 0xFC93A039 ); - P( A, B, C, D, 12, 6, 0x655B59C3 ); - P( D, A, B, C, 3, 10, 0x8F0CCC92 ); - P( C, D, A, B, 10, 15, 0xFFEFF47D ); - P( B, C, D, A, 1, 21, 0x85845DD1 ); - P( A, B, C, D, 8, 6, 0x6FA87E4F ); - P( D, A, B, C, 15, 10, 0xFE2CE6E0 ); - P( C, D, A, B, 6, 15, 0xA3014314 ); - P( B, C, D, A, 13, 21, 0x4E0811A1 ); - P( A, B, C, D, 4, 6, 0xF7537E82 ); - P( D, A, B, C, 11, 10, 0xBD3AF235 ); - P( C, D, A, B, 2, 15, 0x2AD7D2BB ); - P( B, C, D, A, 9, 21, 0xEB86D391 ); - -#undef F - - ctx->state[0] += A; - ctx->state[1] += B; - ctx->state[2] += C; - ctx->state[3] += D; -} - -/* - * MD5 process buffer - */ -void md5_update( md5_context *ctx, const unsigned char *input, int ilen ) -{ - int fill; - unsigned long left; - - if( ilen <= 0 ) - return; - - left = ctx->total[0] & 0x3F; - fill = 64 - left; - - ctx->total[0] += ilen; - ctx->total[0] &= 0xFFFFFFFF; - - if( ctx->total[0] < (unsigned long) ilen ) - ctx->total[1]++; - - if( left && ilen >= fill ) - { - MEMCPY( (void *) (ctx->buffer + left), - input, fill ); - md5_process( ctx, ctx->buffer ); - input += fill; - ilen -= fill; - left = 0; - } - - while( ilen >= 64 ) - { - md5_process( ctx, input ); - input += 64; - ilen -= 64; - } - - if( ilen > 0 ) - { - MEMCPY( (void *) (ctx->buffer + left), - input, ilen ); - } -} - -static const unsigned char md5_padding[64] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* - * MD5 final digest - */ -void md5_finish( md5_context *ctx, unsigned char output[16] ) -{ - unsigned long last, padn; - unsigned long high, low; - unsigned char msglen[8]; - - high = ( ctx->total[0] >> 29 ) - | ( ctx->total[1] << 3 ); - low = ( ctx->total[0] << 3 ); - - PUT_ULONG_LE( low, msglen, 0 ); - PUT_ULONG_LE( high, msglen, 4 ); - - last = ctx->total[0] & 0x3F; - padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); - - md5_update( ctx, md5_padding, padn ); - md5_update( ctx, msglen, 8 ); - - PUT_ULONG_LE( ctx->state[0], output, 0 ); - PUT_ULONG_LE( ctx->state[1], output, 4 ); - PUT_ULONG_LE( ctx->state[2], output, 8 ); - PUT_ULONG_LE( ctx->state[3], output, 12 ); -} - -/* - * output = MD5( input buffer ) - */ -void md5( unsigned char *input, int ilen, unsigned char output[16] ) -{ - md5_context ctx; - - md5_starts( &ctx ); - md5_update( &ctx, input, ilen ); - md5_finish( &ctx, output ); -} - -#endif /* PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_MD5 */ diff --git a/third-party/lwip-2.1.2/netif/ppp/polarssl/sha1.c b/third-party/lwip-2.1.2/netif/ppp/polarssl/sha1.c deleted file mode 100644 index c2192eac..00000000 --- a/third-party/lwip-2.1.2/netif/ppp/polarssl/sha1.c +++ /dev/null @@ -1,335 +0,0 @@ -/* - * FIPS-180-1 compliant SHA-1 implementation - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the names of PolarSSL or XySSL nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * The SHA-1 standard was published by NIST in 1993. - * - * http://www.itl.nist.gov/fipspubs/fip180-1.htm - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_SHA1 - -#include "netif/ppp/polarssl/sha1.h" - -#include - -/* - * 32-bit integer manipulation macros (big endian) - */ -#ifndef GET_ULONG_BE -#define GET_ULONG_BE(n,b,i) \ -{ \ - (n) = ( (unsigned long) (b)[(i) ] << 24 ) \ - | ( (unsigned long) (b)[(i) + 1] << 16 ) \ - | ( (unsigned long) (b)[(i) + 2] << 8 ) \ - | ( (unsigned long) (b)[(i) + 3] ); \ -} -#endif - -#ifndef PUT_ULONG_BE -#define PUT_ULONG_BE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) ); \ -} -#endif - -/* - * SHA-1 context setup - */ -void sha1_starts( sha1_context *ctx ) -{ - ctx->total[0] = 0; - ctx->total[1] = 0; - - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; - ctx->state[4] = 0xC3D2E1F0; -} - -static void sha1_process( sha1_context *ctx, const unsigned char data[64] ) -{ - unsigned long temp, W[16], A, B, C, D, E; - - GET_ULONG_BE( W[ 0], data, 0 ); - GET_ULONG_BE( W[ 1], data, 4 ); - GET_ULONG_BE( W[ 2], data, 8 ); - GET_ULONG_BE( W[ 3], data, 12 ); - GET_ULONG_BE( W[ 4], data, 16 ); - GET_ULONG_BE( W[ 5], data, 20 ); - GET_ULONG_BE( W[ 6], data, 24 ); - GET_ULONG_BE( W[ 7], data, 28 ); - GET_ULONG_BE( W[ 8], data, 32 ); - GET_ULONG_BE( W[ 9], data, 36 ); - GET_ULONG_BE( W[10], data, 40 ); - GET_ULONG_BE( W[11], data, 44 ); - GET_ULONG_BE( W[12], data, 48 ); - GET_ULONG_BE( W[13], data, 52 ); - GET_ULONG_BE( W[14], data, 56 ); - GET_ULONG_BE( W[15], data, 60 ); - -#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) - -#define R(t) \ -( \ - temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \ - W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \ - ( W[t & 0x0F] = S(temp,1) ) \ -) - -#define P(a,b,c,d,e,x) \ -{ \ - e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \ -} - - A = ctx->state[0]; - B = ctx->state[1]; - C = ctx->state[2]; - D = ctx->state[3]; - E = ctx->state[4]; - -#define F(x,y,z) (z ^ (x & (y ^ z))) -#define K 0x5A827999 - - P( A, B, C, D, E, W[0] ); - P( E, A, B, C, D, W[1] ); - P( D, E, A, B, C, W[2] ); - P( C, D, E, A, B, W[3] ); - P( B, C, D, E, A, W[4] ); - P( A, B, C, D, E, W[5] ); - P( E, A, B, C, D, W[6] ); - P( D, E, A, B, C, W[7] ); - P( C, D, E, A, B, W[8] ); - P( B, C, D, E, A, W[9] ); - P( A, B, C, D, E, W[10] ); - P( E, A, B, C, D, W[11] ); - P( D, E, A, B, C, W[12] ); - P( C, D, E, A, B, W[13] ); - P( B, C, D, E, A, W[14] ); - P( A, B, C, D, E, W[15] ); - P( E, A, B, C, D, R(16) ); - P( D, E, A, B, C, R(17) ); - P( C, D, E, A, B, R(18) ); - P( B, C, D, E, A, R(19) ); - -#undef K -#undef F - -#define F(x,y,z) (x ^ y ^ z) -#define K 0x6ED9EBA1 - - P( A, B, C, D, E, R(20) ); - P( E, A, B, C, D, R(21) ); - P( D, E, A, B, C, R(22) ); - P( C, D, E, A, B, R(23) ); - P( B, C, D, E, A, R(24) ); - P( A, B, C, D, E, R(25) ); - P( E, A, B, C, D, R(26) ); - P( D, E, A, B, C, R(27) ); - P( C, D, E, A, B, R(28) ); - P( B, C, D, E, A, R(29) ); - P( A, B, C, D, E, R(30) ); - P( E, A, B, C, D, R(31) ); - P( D, E, A, B, C, R(32) ); - P( C, D, E, A, B, R(33) ); - P( B, C, D, E, A, R(34) ); - P( A, B, C, D, E, R(35) ); - P( E, A, B, C, D, R(36) ); - P( D, E, A, B, C, R(37) ); - P( C, D, E, A, B, R(38) ); - P( B, C, D, E, A, R(39) ); - -#undef K -#undef F - -#define F(x,y,z) ((x & y) | (z & (x | y))) -#define K 0x8F1BBCDC - - P( A, B, C, D, E, R(40) ); - P( E, A, B, C, D, R(41) ); - P( D, E, A, B, C, R(42) ); - P( C, D, E, A, B, R(43) ); - P( B, C, D, E, A, R(44) ); - P( A, B, C, D, E, R(45) ); - P( E, A, B, C, D, R(46) ); - P( D, E, A, B, C, R(47) ); - P( C, D, E, A, B, R(48) ); - P( B, C, D, E, A, R(49) ); - P( A, B, C, D, E, R(50) ); - P( E, A, B, C, D, R(51) ); - P( D, E, A, B, C, R(52) ); - P( C, D, E, A, B, R(53) ); - P( B, C, D, E, A, R(54) ); - P( A, B, C, D, E, R(55) ); - P( E, A, B, C, D, R(56) ); - P( D, E, A, B, C, R(57) ); - P( C, D, E, A, B, R(58) ); - P( B, C, D, E, A, R(59) ); - -#undef K -#undef F - -#define F(x,y,z) (x ^ y ^ z) -#define K 0xCA62C1D6 - - P( A, B, C, D, E, R(60) ); - P( E, A, B, C, D, R(61) ); - P( D, E, A, B, C, R(62) ); - P( C, D, E, A, B, R(63) ); - P( B, C, D, E, A, R(64) ); - P( A, B, C, D, E, R(65) ); - P( E, A, B, C, D, R(66) ); - P( D, E, A, B, C, R(67) ); - P( C, D, E, A, B, R(68) ); - P( B, C, D, E, A, R(69) ); - P( A, B, C, D, E, R(70) ); - P( E, A, B, C, D, R(71) ); - P( D, E, A, B, C, R(72) ); - P( C, D, E, A, B, R(73) ); - P( B, C, D, E, A, R(74) ); - P( A, B, C, D, E, R(75) ); - P( E, A, B, C, D, R(76) ); - P( D, E, A, B, C, R(77) ); - P( C, D, E, A, B, R(78) ); - P( B, C, D, E, A, R(79) ); - -#undef K -#undef F - - ctx->state[0] += A; - ctx->state[1] += B; - ctx->state[2] += C; - ctx->state[3] += D; - ctx->state[4] += E; -} - -/* - * SHA-1 process buffer - */ -void sha1_update( sha1_context *ctx, const unsigned char *input, int ilen ) -{ - int fill; - unsigned long left; - - if( ilen <= 0 ) - return; - - left = ctx->total[0] & 0x3F; - fill = 64 - left; - - ctx->total[0] += ilen; - ctx->total[0] &= 0xFFFFFFFF; - - if( ctx->total[0] < (unsigned long) ilen ) - ctx->total[1]++; - - if( left && ilen >= fill ) - { - MEMCPY( (void *) (ctx->buffer + left), - input, fill ); - sha1_process( ctx, ctx->buffer ); - input += fill; - ilen -= fill; - left = 0; - } - - while( ilen >= 64 ) - { - sha1_process( ctx, input ); - input += 64; - ilen -= 64; - } - - if( ilen > 0 ) - { - MEMCPY( (void *) (ctx->buffer + left), - input, ilen ); - } -} - -static const unsigned char sha1_padding[64] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* - * SHA-1 final digest - */ -void sha1_finish( sha1_context *ctx, unsigned char output[20] ) -{ - unsigned long last, padn; - unsigned long high, low; - unsigned char msglen[8]; - - high = ( ctx->total[0] >> 29 ) - | ( ctx->total[1] << 3 ); - low = ( ctx->total[0] << 3 ); - - PUT_ULONG_BE( high, msglen, 0 ); - PUT_ULONG_BE( low, msglen, 4 ); - - last = ctx->total[0] & 0x3F; - padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); - - sha1_update( ctx, sha1_padding, padn ); - sha1_update( ctx, msglen, 8 ); - - PUT_ULONG_BE( ctx->state[0], output, 0 ); - PUT_ULONG_BE( ctx->state[1], output, 4 ); - PUT_ULONG_BE( ctx->state[2], output, 8 ); - PUT_ULONG_BE( ctx->state[3], output, 12 ); - PUT_ULONG_BE( ctx->state[4], output, 16 ); -} - -/* - * output = SHA-1( input buffer ) - */ -void sha1( unsigned char *input, int ilen, unsigned char output[20] ) -{ - sha1_context ctx; - - sha1_starts( &ctx ); - sha1_update( &ctx, input, ilen ); - sha1_finish( &ctx, output ); -} - -#endif /* PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_SHA1 */ diff --git a/third-party/lwip-2.1.2/netif/ppp/ppp.c b/third-party/lwip-2.1.2/netif/ppp/ppp.c deleted file mode 100644 index a9c18e30..00000000 --- a/third-party/lwip-2.1.2/netif/ppp/ppp.c +++ /dev/null @@ -1,1628 +0,0 @@ -/***************************************************************************** -* ppp.c - Network Point to Point Protocol program file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1997 by Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher -* Ported to lwIP. -* 97-11-05 Guy Lancaster , Global Election Systems Inc. -* Original. -*****************************************************************************/ - -/* - * ppp_defs.h - PPP definitions. - * - * if_pppvar.h - private structures and declarations for PPP. - * - * Copyright (c) 1994 The Australian National University. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO - * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, - * OR MODIFICATIONS. - */ - -/* - * if_ppp.h - Point-to-Point Protocol definitions. - * - * Copyright (c) 1989 Carnegie Mellon University. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by Carnegie Mellon University. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -/** - * @defgroup ppp PPP - * @ingroup netifs - * @verbinclude "ppp.txt" - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/pbuf.h" -#include "lwip/stats.h" -#include "lwip/sys.h" -#include "lwip/tcpip.h" -#include "lwip/api.h" -#include "lwip/snmp.h" -#include "lwip/ip4.h" /* for ip4_input() */ -#if PPP_IPV6_SUPPORT -#include "lwip/ip6.h" /* for ip6_input() */ -#endif /* PPP_IPV6_SUPPORT */ -#include "lwip/dns.h" - -#include "netif/ppp/ppp_impl.h" -#include "netif/ppp/pppos.h" - -#include "netif/ppp/fsm.h" -#include "netif/ppp/lcp.h" -#include "netif/ppp/magic.h" - -#if PAP_SUPPORT -#include "netif/ppp/upap.h" -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT -#include "netif/ppp/chap-new.h" -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT -#include "netif/ppp/eap.h" -#endif /* EAP_SUPPORT */ -#if CCP_SUPPORT -#include "netif/ppp/ccp.h" -#endif /* CCP_SUPPORT */ -#if MPPE_SUPPORT -#include "netif/ppp/mppe.h" -#endif /* MPPE_SUPPORT */ -#if ECP_SUPPORT -#include "netif/ppp/ecp.h" -#endif /* EAP_SUPPORT */ -#if VJ_SUPPORT -#include "netif/ppp/vj.h" -#endif /* VJ_SUPPORT */ -#if PPP_IPV4_SUPPORT -#include "netif/ppp/ipcp.h" -#endif /* PPP_IPV4_SUPPORT */ -#if PPP_IPV6_SUPPORT -#include "netif/ppp/ipv6cp.h" -#endif /* PPP_IPV6_SUPPORT */ - -/*************************/ -/*** LOCAL DEFINITIONS ***/ -/*************************/ - -/* Memory pools */ -#if PPPOS_SUPPORT -LWIP_MEMPOOL_PROTOTYPE(PPPOS_PCB); -#endif -#if PPPOE_SUPPORT -LWIP_MEMPOOL_PROTOTYPE(PPPOE_IF); -#endif -#if PPPOL2TP_SUPPORT -LWIP_MEMPOOL_PROTOTYPE(PPPOL2TP_PCB); -#endif -#if LWIP_PPP_API && LWIP_MPU_COMPATIBLE -LWIP_MEMPOOL_PROTOTYPE(PPPAPI_MSG); -#endif -LWIP_MEMPOOL_DECLARE(PPP_PCB, MEMP_NUM_PPP_PCB, sizeof(ppp_pcb), "PPP_PCB") - -/* FIXME: add stats per PPP session */ -#if PPP_STATS_SUPPORT -static struct timeval start_time; /* Time when link was started. */ -static struct pppd_stats old_link_stats; -struct pppd_stats link_stats; -unsigned link_connect_time; -int link_stats_valid; -#endif /* PPP_STATS_SUPPORT */ - -/* - * PPP Data Link Layer "protocol" table. - * One entry per supported protocol. - * The last entry must be NULL. - */ -const struct protent* const protocols[] = { - &lcp_protent, -#if PAP_SUPPORT - &pap_protent, -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - &chap_protent, -#endif /* CHAP_SUPPORT */ -#if CBCP_SUPPORT - &cbcp_protent, -#endif /* CBCP_SUPPORT */ -#if PPP_IPV4_SUPPORT - &ipcp_protent, -#endif /* PPP_IPV4_SUPPORT */ -#if PPP_IPV6_SUPPORT - &ipv6cp_protent, -#endif /* PPP_IPV6_SUPPORT */ -#if CCP_SUPPORT - &ccp_protent, -#endif /* CCP_SUPPORT */ -#if ECP_SUPPORT - &ecp_protent, -#endif /* ECP_SUPPORT */ -#ifdef AT_CHANGE - &atcp_protent, -#endif /* AT_CHANGE */ -#if EAP_SUPPORT - &eap_protent, -#endif /* EAP_SUPPORT */ - NULL -}; - -/* Prototypes for procedures local to this file. */ -static void ppp_do_connect(void *arg); -static err_t ppp_netif_init_cb(struct netif *netif); -#if PPP_IPV4_SUPPORT -static err_t ppp_netif_output_ip4(struct netif *netif, struct pbuf *pb, const ip4_addr_t *ipaddr); -#endif /* PPP_IPV4_SUPPORT */ -#if PPP_IPV6_SUPPORT -static err_t ppp_netif_output_ip6(struct netif *netif, struct pbuf *pb, const ip6_addr_t *ipaddr); -#endif /* PPP_IPV6_SUPPORT */ -static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u16_t protocol); - -/***********************************/ -/*** PUBLIC FUNCTION DEFINITIONS ***/ -/***********************************/ -#if PPP_AUTH_SUPPORT -void ppp_set_auth(ppp_pcb *pcb, u8_t authtype, const char *user, const char *passwd) { - LWIP_ASSERT_CORE_LOCKED(); -#if PAP_SUPPORT - pcb->settings.refuse_pap = !(authtype & PPPAUTHTYPE_PAP); -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - pcb->settings.refuse_chap = !(authtype & PPPAUTHTYPE_CHAP); -#if MSCHAP_SUPPORT - pcb->settings.refuse_mschap = !(authtype & PPPAUTHTYPE_MSCHAP); - pcb->settings.refuse_mschap_v2 = !(authtype & PPPAUTHTYPE_MSCHAP_V2); -#endif /* MSCHAP_SUPPORT */ -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT - pcb->settings.refuse_eap = !(authtype & PPPAUTHTYPE_EAP); -#endif /* EAP_SUPPORT */ - pcb->settings.user = user; - pcb->settings.passwd = passwd; -} -#endif /* PPP_AUTH_SUPPORT */ - -#if MPPE_SUPPORT -/* Set MPPE configuration */ -void ppp_set_mppe(ppp_pcb *pcb, u8_t flags) { - if (flags == PPP_MPPE_DISABLE) { - pcb->settings.require_mppe = 0; - return; - } - - pcb->settings.require_mppe = 1; - pcb->settings.refuse_mppe_stateful = !(flags & PPP_MPPE_ALLOW_STATEFUL); - pcb->settings.refuse_mppe_40 = !!(flags & PPP_MPPE_REFUSE_40); - pcb->settings.refuse_mppe_128 = !!(flags & PPP_MPPE_REFUSE_128); -} -#endif /* MPPE_SUPPORT */ - -#if PPP_NOTIFY_PHASE -void ppp_set_notify_phase_callback(ppp_pcb *pcb, ppp_notify_phase_cb_fn notify_phase_cb) { - pcb->notify_phase_cb = notify_phase_cb; - notify_phase_cb(pcb, pcb->phase, pcb->ctx_cb); -} -#endif /* PPP_NOTIFY_PHASE */ - -/* - * Initiate a PPP connection. - * - * This can only be called if PPP is in the dead phase. - * - * Holdoff is the time to wait (in seconds) before initiating - * the connection. - * - * If this port connects to a modem, the modem connection must be - * established before calling this. - */ -err_t ppp_connect(ppp_pcb *pcb, u16_t holdoff) { - LWIP_ASSERT_CORE_LOCKED(); - if (pcb->phase != PPP_PHASE_DEAD) { - return ERR_ALREADY; - } - - PPPDEBUG(LOG_DEBUG, ("ppp_connect[%d]: holdoff=%d\n", pcb->netif->num, holdoff)); - - magic_randomize(); - - if (holdoff == 0) { - ppp_do_connect(pcb); - return ERR_OK; - } - - new_phase(pcb, PPP_PHASE_HOLDOFF); - sys_timeout((u32_t)(holdoff*1000), ppp_do_connect, pcb); - return ERR_OK; -} - -#if PPP_SERVER -/* - * Listen for an incoming PPP connection. - * - * This can only be called if PPP is in the dead phase. - * - * If this port connects to a modem, the modem connection must be - * established before calling this. - */ -err_t ppp_listen(ppp_pcb *pcb) { - LWIP_ASSERT_CORE_LOCKED(); - if (pcb->phase != PPP_PHASE_DEAD) { - return ERR_ALREADY; - } - - PPPDEBUG(LOG_DEBUG, ("ppp_listen[%d]\n", pcb->netif->num)); - - magic_randomize(); - - if (pcb->link_cb->listen) { - new_phase(pcb, PPP_PHASE_INITIALIZE); - pcb->link_cb->listen(pcb, pcb->link_ctx_cb); - return ERR_OK; - } - return ERR_IF; -} -#endif /* PPP_SERVER */ - -/* - * Initiate the end of a PPP connection. - * Any outstanding packets in the queues are dropped. - * - * Setting nocarrier to 1 close the PPP connection without initiating the - * shutdown procedure. Always using nocarrier = 0 is still recommended, - * this is going to take a little longer time if your link is down, but - * is a safer choice for the PPP state machine. - * - * Return 0 on success, an error code on failure. - */ -err_t -ppp_close(ppp_pcb *pcb, u8_t nocarrier) -{ - LWIP_ASSERT_CORE_LOCKED(); - - pcb->err_code = PPPERR_USER; - - /* holdoff phase, cancel the reconnection */ - if (pcb->phase == PPP_PHASE_HOLDOFF) { - sys_untimeout(ppp_do_connect, pcb); - new_phase(pcb, PPP_PHASE_DEAD); - } - - /* dead phase, nothing to do, call the status callback to be consistent */ - if (pcb->phase == PPP_PHASE_DEAD) { - pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb); - return ERR_OK; - } - - /* Already terminating, nothing to do */ - if (pcb->phase >= PPP_PHASE_TERMINATE) { - return ERR_INPROGRESS; - } - - /* LCP not open, close link protocol */ - if (pcb->phase < PPP_PHASE_ESTABLISH) { - new_phase(pcb, PPP_PHASE_DISCONNECT); - ppp_link_terminated(pcb); - return ERR_OK; - } - - /* - * Only accept carrier lost signal on the stable running phase in order - * to prevent changing the PPP phase FSM in transition phases. - * - * Always using nocarrier = 0 is still recommended, this is going to - * take a little longer time, but is a safer choice from FSM point of view. - */ - if (nocarrier && pcb->phase == PPP_PHASE_RUNNING) { - PPPDEBUG(LOG_DEBUG, ("ppp_close[%d]: carrier lost -> lcp_lowerdown\n", pcb->netif->num)); - lcp_lowerdown(pcb); - /* forced link termination, this will force link protocol to disconnect. */ - link_terminated(pcb); - return ERR_OK; - } - - /* Disconnect */ - PPPDEBUG(LOG_DEBUG, ("ppp_close[%d]: kill_link -> lcp_close\n", pcb->netif->num)); - /* LCP soft close request. */ - lcp_close(pcb, "User request"); - return ERR_OK; -} - -/* - * Release the control block. - * - * This can only be called if PPP is in the dead phase. - * - * You must use ppp_close() before if you wish to terminate - * an established PPP session. - * - * Return 0 on success, an error code on failure. - */ -err_t ppp_free(ppp_pcb *pcb) { - err_t err; - LWIP_ASSERT_CORE_LOCKED(); - if (pcb->phase != PPP_PHASE_DEAD) { - return ERR_CONN; - } - - PPPDEBUG(LOG_DEBUG, ("ppp_free[%d]\n", pcb->netif->num)); - - netif_remove(pcb->netif); - - err = pcb->link_cb->free(pcb, pcb->link_ctx_cb); - - LWIP_MEMPOOL_FREE(PPP_PCB, pcb); - return err; -} - -/* Get and set parameters for the given connection. - * Return 0 on success, an error code on failure. */ -err_t -ppp_ioctl(ppp_pcb *pcb, u8_t cmd, void *arg) -{ - LWIP_ASSERT_CORE_LOCKED(); - if (pcb == NULL) { - return ERR_VAL; - } - - switch(cmd) { - case PPPCTLG_UPSTATUS: /* Get the PPP up status. */ - if (!arg) { - goto fail; - } - *(int *)arg = (int)(0 -#if PPP_IPV4_SUPPORT - || pcb->if4_up -#endif /* PPP_IPV4_SUPPORT */ -#if PPP_IPV6_SUPPORT - || pcb->if6_up -#endif /* PPP_IPV6_SUPPORT */ - ); - return ERR_OK; - - case PPPCTLG_ERRCODE: /* Get the PPP error code. */ - if (!arg) { - goto fail; - } - *(int *)arg = (int)(pcb->err_code); - return ERR_OK; - - default: - goto fail; - } - -fail: - return ERR_VAL; -} - - -/**********************************/ -/*** LOCAL FUNCTION DEFINITIONS ***/ -/**********************************/ - -static void ppp_do_connect(void *arg) { - ppp_pcb *pcb = (ppp_pcb*)arg; - - LWIP_ASSERT("pcb->phase == PPP_PHASE_DEAD || pcb->phase == PPP_PHASE_HOLDOFF", pcb->phase == PPP_PHASE_DEAD || pcb->phase == PPP_PHASE_HOLDOFF); - - new_phase(pcb, PPP_PHASE_INITIALIZE); - pcb->link_cb->connect(pcb, pcb->link_ctx_cb); -} - -/* - * ppp_netif_init_cb - netif init callback - */ -static err_t ppp_netif_init_cb(struct netif *netif) { - netif->name[0] = 'p'; - netif->name[1] = 'p'; -#if PPP_IPV4_SUPPORT - netif->output = ppp_netif_output_ip4; -#endif /* PPP_IPV4_SUPPORT */ -#if PPP_IPV6_SUPPORT - netif->output_ip6 = ppp_netif_output_ip6; -#endif /* PPP_IPV6_SUPPORT */ - netif->flags = NETIF_FLAG_UP; -#if LWIP_NETIF_HOSTNAME - /* @todo: Initialize interface hostname */ - /* netif_set_hostname(netif, "lwip"); */ -#endif /* LWIP_NETIF_HOSTNAME */ - return ERR_OK; -} - -#if PPP_IPV4_SUPPORT -/* - * Send an IPv4 packet on the given connection. - */ -static err_t ppp_netif_output_ip4(struct netif *netif, struct pbuf *pb, const ip4_addr_t *ipaddr) { - LWIP_UNUSED_ARG(ipaddr); - return ppp_netif_output(netif, pb, PPP_IP); -} -#endif /* PPP_IPV4_SUPPORT */ - -#if PPP_IPV6_SUPPORT -/* - * Send an IPv6 packet on the given connection. - */ -static err_t ppp_netif_output_ip6(struct netif *netif, struct pbuf *pb, const ip6_addr_t *ipaddr) { - LWIP_UNUSED_ARG(ipaddr); - return ppp_netif_output(netif, pb, PPP_IPV6); -} -#endif /* PPP_IPV6_SUPPORT */ - -static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u16_t protocol) { - ppp_pcb *pcb = (ppp_pcb*)netif->state; - err_t err; - struct pbuf *fpb = NULL; - - /* Check that the link is up. */ - if (0 -#if PPP_IPV4_SUPPORT - || (protocol == PPP_IP && !pcb->if4_up) -#endif /* PPP_IPV4_SUPPORT */ -#if PPP_IPV6_SUPPORT - || (protocol == PPP_IPV6 && !pcb->if6_up) -#endif /* PPP_IPV6_SUPPORT */ - ) { - PPPDEBUG(LOG_ERR, ("ppp_netif_output[%d]: link not up\n", pcb->netif->num)); - goto err_rte_drop; - } - -#if MPPE_SUPPORT - /* If MPPE is required, refuse any IP packet until we are able to crypt them. */ - if (pcb->settings.require_mppe && pcb->ccp_transmit_method != CI_MPPE) { - PPPDEBUG(LOG_ERR, ("ppp_netif_output[%d]: MPPE required, not up\n", pcb->netif->num)); - goto err_rte_drop; - } -#endif /* MPPE_SUPPORT */ - -#if VJ_SUPPORT - /* - * Attempt Van Jacobson header compression if VJ is configured and - * this is an IP packet. - */ - if (protocol == PPP_IP && pcb->vj_enabled) { - switch (vj_compress_tcp(&pcb->vj_comp, &pb)) { - case TYPE_IP: - /* No change... - protocol = PPP_IP; */ - break; - case TYPE_COMPRESSED_TCP: - /* vj_compress_tcp() returns a new allocated pbuf, indicate we should free - * our duplicated pbuf later */ - fpb = pb; - protocol = PPP_VJC_COMP; - break; - case TYPE_UNCOMPRESSED_TCP: - /* vj_compress_tcp() returns a new allocated pbuf, indicate we should free - * our duplicated pbuf later */ - fpb = pb; - protocol = PPP_VJC_UNCOMP; - break; - default: - PPPDEBUG(LOG_WARNING, ("ppp_netif_output[%d]: bad IP packet\n", pcb->netif->num)); - LINK_STATS_INC(link.proterr); - LINK_STATS_INC(link.drop); - MIB2_STATS_NETIF_INC(pcb->netif, ifoutdiscards); - return ERR_VAL; - } - } -#endif /* VJ_SUPPORT */ - -#if CCP_SUPPORT - switch (pcb->ccp_transmit_method) { - case 0: - break; /* Don't compress */ -#if MPPE_SUPPORT - case CI_MPPE: - if ((err = mppe_compress(pcb, &pcb->mppe_comp, &pb, protocol)) != ERR_OK) { - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.drop); - MIB2_STATS_NETIF_INC(netif, ifoutdiscards); - goto err; - } - /* if VJ compressor returned a new allocated pbuf, free it */ - if (fpb) { - pbuf_free(fpb); - } - /* mppe_compress() returns a new allocated pbuf, indicate we should free - * our duplicated pbuf later */ - fpb = pb; - protocol = PPP_COMP; - break; -#endif /* MPPE_SUPPORT */ - default: - PPPDEBUG(LOG_ERR, ("ppp_netif_output[%d]: bad CCP transmit method\n", pcb->netif->num)); - goto err_rte_drop; /* Cannot really happen, we only negotiate what we are able to do */ - } -#endif /* CCP_SUPPORT */ - - err = pcb->link_cb->netif_output(pcb, pcb->link_ctx_cb, pb, protocol); - goto err; - -err_rte_drop: - err = ERR_RTE; - LINK_STATS_INC(link.rterr); - LINK_STATS_INC(link.drop); - MIB2_STATS_NETIF_INC(netif, ifoutdiscards); -err: - if (fpb) { - pbuf_free(fpb); - } - return err; -} - -/************************************/ -/*** PRIVATE FUNCTION DEFINITIONS ***/ -/************************************/ - -/* Initialize the PPP subsystem. */ -int ppp_init(void) -{ -#if PPPOS_SUPPORT - LWIP_MEMPOOL_INIT(PPPOS_PCB); -#endif -#if PPPOE_SUPPORT - LWIP_MEMPOOL_INIT(PPPOE_IF); -#endif -#if PPPOL2TP_SUPPORT - LWIP_MEMPOOL_INIT(PPPOL2TP_PCB); -#endif -#if LWIP_PPP_API && LWIP_MPU_COMPATIBLE - LWIP_MEMPOOL_INIT(PPPAPI_MSG); -#endif - - LWIP_MEMPOOL_INIT(PPP_PCB); - - /* - * Initialize magic number generator now so that protocols may - * use magic numbers in initialization. - */ - magic_init(); - - return 0; -} - -/* - * Create a new PPP control block. - * - * This initializes the PPP control block but does not - * attempt to negotiate the LCP session. - * - * Return a new PPP connection control block pointer - * on success or a null pointer on failure. - */ -ppp_pcb *ppp_new(struct netif *pppif, const struct link_callbacks *callbacks, void *link_ctx_cb, ppp_link_status_cb_fn link_status_cb, void *ctx_cb) { - ppp_pcb *pcb; - const struct protent *protp; - int i; - - /* PPP is single-threaded: without a callback, - * there is no way to know when the link is up. */ - if (link_status_cb == NULL) { - return NULL; - } - - pcb = (ppp_pcb*)LWIP_MEMPOOL_ALLOC(PPP_PCB); - if (pcb == NULL) { - return NULL; - } - - memset(pcb, 0, sizeof(ppp_pcb)); - - /* default configuration */ -#if PAP_SUPPORT - pcb->settings.pap_timeout_time = UPAP_DEFTIMEOUT; - pcb->settings.pap_max_transmits = UPAP_DEFTRANSMITS; -#if PPP_SERVER - pcb->settings.pap_req_timeout = UPAP_DEFREQTIME; -#endif /* PPP_SERVER */ -#endif /* PAP_SUPPORT */ - -#if CHAP_SUPPORT - pcb->settings.chap_timeout_time = CHAP_DEFTIMEOUT; - pcb->settings.chap_max_transmits = CHAP_DEFTRANSMITS; -#if PPP_SERVER - pcb->settings.chap_rechallenge_time = CHAP_DEFRECHALLENGETIME; -#endif /* PPP_SERVER */ -#endif /* CHAP_SUPPPORT */ - -#if EAP_SUPPORT - pcb->settings.eap_req_time = EAP_DEFREQTIME; - pcb->settings.eap_allow_req = EAP_DEFALLOWREQ; -#if PPP_SERVER - pcb->settings.eap_timeout_time = EAP_DEFTIMEOUT; - pcb->settings.eap_max_transmits = EAP_DEFTRANSMITS; -#endif /* PPP_SERVER */ -#endif /* EAP_SUPPORT */ - - pcb->settings.lcp_loopbackfail = LCP_DEFLOOPBACKFAIL; - pcb->settings.lcp_echo_interval = LCP_ECHOINTERVAL; - pcb->settings.lcp_echo_fails = LCP_MAXECHOFAILS; - - pcb->settings.fsm_timeout_time = FSM_DEFTIMEOUT; - pcb->settings.fsm_max_conf_req_transmits = FSM_DEFMAXCONFREQS; - pcb->settings.fsm_max_term_transmits = FSM_DEFMAXTERMREQS; - pcb->settings.fsm_max_nak_loops = FSM_DEFMAXNAKLOOPS; - - pcb->netif = pppif; - MIB2_INIT_NETIF(pppif, snmp_ifType_ppp, 0); - if (!netif_add(pcb->netif, -#if LWIP_IPV4 - IP4_ADDR_ANY4, IP4_ADDR_BROADCAST, IP4_ADDR_ANY4, -#endif /* LWIP_IPV4 */ - (void *)pcb, ppp_netif_init_cb, NULL)) { - LWIP_MEMPOOL_FREE(PPP_PCB, pcb); - PPPDEBUG(LOG_ERR, ("ppp_new: netif_add failed\n")); - return NULL; - } - - pcb->link_cb = callbacks; - pcb->link_ctx_cb = link_ctx_cb; - pcb->link_status_cb = link_status_cb; - pcb->ctx_cb = ctx_cb; - - /* - * Initialize each protocol. - */ - for (i = 0; (protp = protocols[i]) != NULL; ++i) { - (*protp->init)(pcb); - } - - new_phase(pcb, PPP_PHASE_DEAD); - return pcb; -} - -/** Initiate LCP open request */ -void ppp_start(ppp_pcb *pcb) { - PPPDEBUG(LOG_DEBUG, ("ppp_start[%d]\n", pcb->netif->num)); - - /* Clean data not taken care by anything else, mostly shared data. */ -#if PPP_STATS_SUPPORT - link_stats_valid = 0; -#endif /* PPP_STATS_SUPPORT */ -#if MPPE_SUPPORT - pcb->mppe_keys_set = 0; - memset(&pcb->mppe_comp, 0, sizeof(pcb->mppe_comp)); - memset(&pcb->mppe_decomp, 0, sizeof(pcb->mppe_decomp)); -#endif /* MPPE_SUPPORT */ -#if VJ_SUPPORT - vj_compress_init(&pcb->vj_comp); -#endif /* VJ_SUPPORT */ - - /* Start protocol */ - new_phase(pcb, PPP_PHASE_ESTABLISH); - lcp_open(pcb); - lcp_lowerup(pcb); - PPPDEBUG(LOG_DEBUG, ("ppp_start[%d]: finished\n", pcb->netif->num)); -} - -/** Called when link failed to setup */ -void ppp_link_failed(ppp_pcb *pcb) { - PPPDEBUG(LOG_DEBUG, ("ppp_link_failed[%d]\n", pcb->netif->num)); - new_phase(pcb, PPP_PHASE_DEAD); - pcb->err_code = PPPERR_OPEN; - pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb); -} - -/** Called when link is normally down (i.e. it was asked to end) */ -void ppp_link_end(ppp_pcb *pcb) { - PPPDEBUG(LOG_DEBUG, ("ppp_link_end[%d]\n", pcb->netif->num)); - new_phase(pcb, PPP_PHASE_DEAD); - if (pcb->err_code == PPPERR_NONE) { - pcb->err_code = PPPERR_CONNECT; - } - pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb); -} - -/* - * Pass the processed input packet to the appropriate handler. - * This function and all handlers run in the context of the tcpip_thread - */ -void ppp_input(ppp_pcb *pcb, struct pbuf *pb) { - u16_t protocol; -#if PPP_DEBUG && PPP_PROTOCOLNAME - const char *pname; -#endif /* PPP_DEBUG && PPP_PROTOCOLNAME */ - - magic_randomize(); - - if (pb->len < 2) { - PPPDEBUG(LOG_ERR, ("ppp_input[%d]: packet too short\n", pcb->netif->num)); - goto drop; - } - protocol = (((u8_t *)pb->payload)[0] << 8) | ((u8_t*)pb->payload)[1]; - -#if PRINTPKT_SUPPORT - ppp_dump_packet(pcb, "rcvd", (unsigned char *)pb->payload, pb->len); -#endif /* PRINTPKT_SUPPORT */ - - pbuf_remove_header(pb, sizeof(protocol)); - - LINK_STATS_INC(link.recv); - MIB2_STATS_NETIF_INC(pcb->netif, ifinucastpkts); - MIB2_STATS_NETIF_ADD(pcb->netif, ifinoctets, pb->tot_len); - - /* - * Toss all non-LCP packets unless LCP is OPEN. - */ - if (protocol != PPP_LCP && pcb->lcp_fsm.state != PPP_FSM_OPENED) { - ppp_dbglog("Discarded non-LCP packet when LCP not open"); - goto drop; - } - - /* - * Until we get past the authentication phase, toss all packets - * except LCP, LQR and authentication packets. - */ - if (pcb->phase <= PPP_PHASE_AUTHENTICATE - && !(protocol == PPP_LCP -#if LQR_SUPPORT - || protocol == PPP_LQR -#endif /* LQR_SUPPORT */ -#if PAP_SUPPORT - || protocol == PPP_PAP -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - || protocol == PPP_CHAP -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT - || protocol == PPP_EAP -#endif /* EAP_SUPPORT */ - )) { - ppp_dbglog("discarding proto 0x%x in phase %d", protocol, pcb->phase); - goto drop; - } - -#if CCP_SUPPORT -#if MPPE_SUPPORT - /* - * MPPE is required and unencrypted data has arrived (this - * should never happen!). We should probably drop the link if - * the protocol is in the range of what should be encrypted. - * At the least, we drop this packet. - */ - if (pcb->settings.require_mppe && protocol != PPP_COMP && protocol < 0x8000) { - PPPDEBUG(LOG_ERR, ("ppp_input[%d]: MPPE required, received unencrypted data!\n", pcb->netif->num)); - goto drop; - } -#endif /* MPPE_SUPPORT */ - - if (protocol == PPP_COMP) { - u8_t *pl; - - switch (pcb->ccp_receive_method) { -#if MPPE_SUPPORT - case CI_MPPE: - if (mppe_decompress(pcb, &pcb->mppe_decomp, &pb) != ERR_OK) { - goto drop; - } - break; -#endif /* MPPE_SUPPORT */ - default: - PPPDEBUG(LOG_ERR, ("ppp_input[%d]: bad CCP receive method\n", pcb->netif->num)); - goto drop; /* Cannot really happen, we only negotiate what we are able to do */ - } - - /* Assume no PFC */ - if (pb->len < 2) { - goto drop; - } - - /* Extract and hide protocol (do PFC decompression if necessary) */ - pl = (u8_t*)pb->payload; - if (pl[0] & 0x01) { - protocol = pl[0]; - pbuf_remove_header(pb, 1); - } else { - protocol = (pl[0] << 8) | pl[1]; - pbuf_remove_header(pb, 2); - } - } -#endif /* CCP_SUPPORT */ - - switch(protocol) { - -#if PPP_IPV4_SUPPORT - case PPP_IP: /* Internet Protocol */ - PPPDEBUG(LOG_INFO, ("ppp_input[%d]: ip in pbuf len=%d\n", pcb->netif->num, pb->tot_len)); - ip4_input(pb, pcb->netif); - return; -#endif /* PPP_IPV4_SUPPORT */ - -#if PPP_IPV6_SUPPORT - case PPP_IPV6: /* Internet Protocol Version 6 */ - PPPDEBUG(LOG_INFO, ("ppp_input[%d]: ip6 in pbuf len=%d\n", pcb->netif->num, pb->tot_len)); - ip6_input(pb, pcb->netif); - return; -#endif /* PPP_IPV6_SUPPORT */ - -#if VJ_SUPPORT - case PPP_VJC_COMP: /* VJ compressed TCP */ - /* - * Clip off the VJ header and prepend the rebuilt TCP/IP header and - * pass the result to IP. - */ - PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_comp in pbuf len=%d\n", pcb->netif->num, pb->tot_len)); - if (pcb->vj_enabled && vj_uncompress_tcp(&pb, &pcb->vj_comp) >= 0) { - ip4_input(pb, pcb->netif); - return; - } - /* Something's wrong so drop it. */ - PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping VJ compressed\n", pcb->netif->num)); - break; - - case PPP_VJC_UNCOMP: /* VJ uncompressed TCP */ - /* - * Process the TCP/IP header for VJ header compression and then pass - * the packet to IP. - */ - PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_un in pbuf len=%d\n", pcb->netif->num, pb->tot_len)); - if (pcb->vj_enabled && vj_uncompress_uncomp(pb, &pcb->vj_comp) >= 0) { - ip4_input(pb, pcb->netif); - return; - } - /* Something's wrong so drop it. */ - PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping VJ uncompressed\n", pcb->netif->num)); - break; -#endif /* VJ_SUPPORT */ - - default: { - int i; - const struct protent *protp; - - /* - * Upcall the proper protocol input routine. - */ - for (i = 0; (protp = protocols[i]) != NULL; ++i) { - if (protp->protocol == protocol) { - pb = pbuf_coalesce(pb, PBUF_RAW); - (*protp->input)(pcb, (u8_t*)pb->payload, pb->len); - goto out; - } -#if 0 /* UNUSED - * - * This is actually a (hacked?) way for the Linux kernel to pass a data - * packet to pppd. pppd in normal condition only do signaling - * (LCP, PAP, CHAP, IPCP, ...) and does not handle any data packet at all. - * - * We don't even need this interface, which is only there because of PPP - * interface limitation between Linux kernel and pppd. For MPPE, which uses - * CCP to negotiate although it is not really a (de)compressor, we added - * ccp_resetrequest() in CCP and MPPE input data flow is calling either - * ccp_resetrequest() or lcp_close() if the issue is, respectively, non-fatal - * or fatal, this is what ccp_datainput() really do. - */ - if (protocol == (protp->protocol & ~0x8000) - && protp->datainput != NULL) { - (*protp->datainput)(pcb, pb->payload, pb->len); - goto out; - } -#endif /* UNUSED */ - } - -#if PPP_DEBUG -#if PPP_PROTOCOLNAME - pname = protocol_name(protocol); - if (pname != NULL) { - ppp_warn("Unsupported protocol '%s' (0x%x) received", pname, protocol); - } else -#endif /* PPP_PROTOCOLNAME */ - ppp_warn("Unsupported protocol 0x%x received", protocol); -#endif /* PPP_DEBUG */ - if (pbuf_add_header(pb, sizeof(protocol))) { - PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping (pbuf_add_header failed)\n", pcb->netif->num)); - goto drop; - } - lcp_sprotrej(pcb, (u8_t*)pb->payload, pb->len); - } - break; - } - -drop: - LINK_STATS_INC(link.drop); - MIB2_STATS_NETIF_INC(pcb->netif, ifindiscards); - -out: - pbuf_free(pb); -} - -/* - * Write a pbuf to a ppp link, only used from PPP functions - * to send PPP packets. - * - * IPv4 and IPv6 packets from lwIP are sent, respectively, - * with ppp_netif_output_ip4() and ppp_netif_output_ip6() - * functions (which are callbacks of the netif PPP interface). - */ -err_t ppp_write(ppp_pcb *pcb, struct pbuf *p) { -#if PRINTPKT_SUPPORT - ppp_dump_packet(pcb, "sent", (unsigned char *)p->payload+2, p->len-2); -#endif /* PRINTPKT_SUPPORT */ - return pcb->link_cb->write(pcb, pcb->link_ctx_cb, p); -} - -void ppp_link_terminated(ppp_pcb *pcb) { - PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated[%d]\n", pcb->netif->num)); - pcb->link_cb->disconnect(pcb, pcb->link_ctx_cb); - PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated[%d]: finished.\n", pcb->netif->num)); -} - - -/************************************************************************ - * Functions called by various PPP subsystems to configure - * the PPP interface or change the PPP phase. - */ - -/* - * new_phase - signal the start of a new phase of pppd's operation. - */ -void new_phase(ppp_pcb *pcb, int p) { - pcb->phase = p; - PPPDEBUG(LOG_DEBUG, ("ppp phase changed[%d]: phase=%d\n", pcb->netif->num, pcb->phase)); -#if PPP_NOTIFY_PHASE - if (pcb->notify_phase_cb != NULL) { - pcb->notify_phase_cb(pcb, p, pcb->ctx_cb); - } -#endif /* PPP_NOTIFY_PHASE */ -} - -/* - * ppp_send_config - configure the transmit-side characteristics of - * the ppp interface. - */ -int ppp_send_config(ppp_pcb *pcb, int mtu, u32_t accm, int pcomp, int accomp) { - LWIP_UNUSED_ARG(mtu); - /* pcb->mtu = mtu; -- set correctly with netif_set_mtu */ - - if (pcb->link_cb->send_config) { - pcb->link_cb->send_config(pcb, pcb->link_ctx_cb, accm, pcomp, accomp); - } - - PPPDEBUG(LOG_INFO, ("ppp_send_config[%d]\n", pcb->netif->num) ); - return 0; -} - -/* - * ppp_recv_config - configure the receive-side characteristics of - * the ppp interface. - */ -int ppp_recv_config(ppp_pcb *pcb, int mru, u32_t accm, int pcomp, int accomp) { - LWIP_UNUSED_ARG(mru); - - if (pcb->link_cb->recv_config) { - pcb->link_cb->recv_config(pcb, pcb->link_ctx_cb, accm, pcomp, accomp); - } - - PPPDEBUG(LOG_INFO, ("ppp_recv_config[%d]\n", pcb->netif->num)); - return 0; -} - -#if PPP_IPV4_SUPPORT -/* - * sifaddr - Config the interface IP addresses and netmask. - */ -int sifaddr(ppp_pcb *pcb, u32_t our_adr, u32_t his_adr, u32_t netmask) { - ip4_addr_t ip, nm, gw; - - ip4_addr_set_u32(&ip, our_adr); - ip4_addr_set_u32(&nm, netmask); - ip4_addr_set_u32(&gw, his_adr); - netif_set_addr(pcb->netif, &ip, &nm, &gw); - return 1; -} - -/******************************************************************** - * - * cifaddr - Clear the interface IP addresses, and delete routes - * through the interface if possible. - */ -int cifaddr(ppp_pcb *pcb, u32_t our_adr, u32_t his_adr) { - LWIP_UNUSED_ARG(our_adr); - LWIP_UNUSED_ARG(his_adr); - - netif_set_addr(pcb->netif, IP4_ADDR_ANY4, IP4_ADDR_BROADCAST, IP4_ADDR_ANY4); - return 1; -} - -#if 0 /* UNUSED - PROXY ARP */ -/******************************************************************** - * - * sifproxyarp - Make a proxy ARP entry for the peer. - */ - -int sifproxyarp(ppp_pcb *pcb, u32_t his_adr) { - LWIP_UNUSED_ARG(pcb); - LWIP_UNUSED_ARG(his_adr); - return 0; -} - -/******************************************************************** - * - * cifproxyarp - Delete the proxy ARP entry for the peer. - */ - -int cifproxyarp(ppp_pcb *pcb, u32_t his_adr) { - LWIP_UNUSED_ARG(pcb); - LWIP_UNUSED_ARG(his_adr); - return 0; -} -#endif /* UNUSED - PROXY ARP */ - -#if LWIP_DNS -/* - * sdns - Config the DNS servers - */ -int sdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2) { - ip_addr_t ns; - LWIP_UNUSED_ARG(pcb); - - ip_addr_set_ip4_u32_val(ns, ns1); - dns_setserver(0, &ns); - ip_addr_set_ip4_u32_val(ns, ns2); - dns_setserver(1, &ns); - return 1; -} - -/******************************************************************** - * - * cdns - Clear the DNS servers - */ -int cdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2) { - const ip_addr_t *nsa; - ip_addr_t nsb; - LWIP_UNUSED_ARG(pcb); - - nsa = dns_getserver(0); - ip_addr_set_ip4_u32_val(nsb, ns1); - if (ip_addr_cmp(nsa, &nsb)) { - dns_setserver(0, IP_ADDR_ANY); - } - nsa = dns_getserver(1); - ip_addr_set_ip4_u32_val(nsb, ns2); - if (ip_addr_cmp(nsa, &nsb)) { - dns_setserver(1, IP_ADDR_ANY); - } - return 1; -} -#endif /* LWIP_DNS */ - -#if VJ_SUPPORT -/******************************************************************** - * - * sifvjcomp - config tcp header compression - */ -int sifvjcomp(ppp_pcb *pcb, int vjcomp, int cidcomp, int maxcid) { - pcb->vj_enabled = vjcomp; - pcb->vj_comp.compressSlot = cidcomp; - pcb->vj_comp.maxSlotIndex = maxcid; - PPPDEBUG(LOG_INFO, ("sifvjcomp[%d]: VJ compress enable=%d slot=%d max slot=%d\n", - pcb->netif->num, vjcomp, cidcomp, maxcid)); - return 0; -} -#endif /* VJ_SUPPORT */ - -/* - * sifup - Config the interface up and enable IP packets to pass. - */ -int sifup(ppp_pcb *pcb) { - pcb->if4_up = 1; - pcb->err_code = PPPERR_NONE; - netif_set_link_up(pcb->netif); - - PPPDEBUG(LOG_DEBUG, ("sifup[%d]: err_code=%d\n", pcb->netif->num, pcb->err_code)); - pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb); - return 1; -} - -/******************************************************************** - * - * sifdown - Disable the indicated protocol and config the interface - * down if there are no remaining protocols. - */ -int sifdown(ppp_pcb *pcb) { - - pcb->if4_up = 0; - - if (1 -#if PPP_IPV6_SUPPORT - /* set the interface down if IPv6 is down as well */ - && !pcb->if6_up -#endif /* PPP_IPV6_SUPPORT */ - ) { - /* make sure the netif link callback is called */ - netif_set_link_down(pcb->netif); - } - PPPDEBUG(LOG_DEBUG, ("sifdown[%d]: err_code=%d\n", pcb->netif->num, pcb->err_code)); - return 1; -} - -/******************************************************************** - * - * Return user specified netmask, modified by any mask we might determine - * for address `addr' (in network byte order). - * Here we scan through the system's list of interfaces, looking for - * any non-point-to-point interfaces which might appear to be on the same - * network as `addr'. If we find any, we OR in their netmask to the - * user-specified netmask. - */ -u32_t get_mask(u32_t addr) { -#if 0 - u32_t mask, nmask; - - addr = lwip_htonl(addr); - if (IP_CLASSA(addr)) { /* determine network mask for address class */ - nmask = IP_CLASSA_NET; - } else if (IP_CLASSB(addr)) { - nmask = IP_CLASSB_NET; - } else { - nmask = IP_CLASSC_NET; - } - - /* class D nets are disallowed by bad_ip_adrs */ - mask = PP_HTONL(0xffffff00UL) | lwip_htonl(nmask); - - /* XXX - * Scan through the system's network interfaces. - * Get each netmask and OR them into our mask. - */ - /* return mask; */ - return mask; -#endif /* 0 */ - LWIP_UNUSED_ARG(addr); - return IPADDR_BROADCAST; -} -#endif /* PPP_IPV4_SUPPORT */ - -#if PPP_IPV6_SUPPORT -#define IN6_LLADDR_FROM_EUI64(ip6, eui64) do { \ - ip6.addr[0] = PP_HTONL(0xfe800000); \ - ip6.addr[1] = 0; \ - eui64_copy(eui64, ip6.addr[2]); \ - } while (0) - -/******************************************************************** - * - * sif6addr - Config the interface with an IPv6 link-local address - */ -int sif6addr(ppp_pcb *pcb, eui64_t our_eui64, eui64_t his_eui64) { - ip6_addr_t ip6; - LWIP_UNUSED_ARG(his_eui64); - - IN6_LLADDR_FROM_EUI64(ip6, our_eui64); - netif_ip6_addr_set(pcb->netif, 0, &ip6); - netif_ip6_addr_set_state(pcb->netif, 0, IP6_ADDR_PREFERRED); - /* FIXME: should we add an IPv6 static neighbor using his_eui64 ? */ - return 1; -} - -/******************************************************************** - * - * cif6addr - Remove IPv6 address from interface - */ -int cif6addr(ppp_pcb *pcb, eui64_t our_eui64, eui64_t his_eui64) { - LWIP_UNUSED_ARG(our_eui64); - LWIP_UNUSED_ARG(his_eui64); - - netif_ip6_addr_set_state(pcb->netif, 0, IP6_ADDR_INVALID); - netif_ip6_addr_set(pcb->netif, 0, IP6_ADDR_ANY6); - return 1; -} - -/* - * sif6up - Config the interface up and enable IPv6 packets to pass. - */ -int sif6up(ppp_pcb *pcb) { - - pcb->if6_up = 1; - pcb->err_code = PPPERR_NONE; - netif_set_link_up(pcb->netif); - - PPPDEBUG(LOG_DEBUG, ("sif6up[%d]: err_code=%d\n", pcb->netif->num, pcb->err_code)); - pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb); - return 1; -} - -/******************************************************************** - * - * sif6down - Disable the indicated protocol and config the interface - * down if there are no remaining protocols. - */ -int sif6down(ppp_pcb *pcb) { - - pcb->if6_up = 0; - - if (1 -#if PPP_IPV4_SUPPORT - /* set the interface down if IPv4 is down as well */ - && !pcb->if4_up -#endif /* PPP_IPV4_SUPPORT */ - ) { - /* make sure the netif link callback is called */ - netif_set_link_down(pcb->netif); - } - PPPDEBUG(LOG_DEBUG, ("sif6down[%d]: err_code=%d\n", pcb->netif->num, pcb->err_code)); - return 1; -} -#endif /* PPP_IPV6_SUPPORT */ - -#if DEMAND_SUPPORT -/* - * sifnpmode - Set the mode for handling packets for a given NP. - */ -int sifnpmode(ppp_pcb *pcb, int proto, enum NPmode mode) { - LWIP_UNUSED_ARG(pcb); - LWIP_UNUSED_ARG(proto); - LWIP_UNUSED_ARG(mode); - return 0; -} -#endif /* DEMAND_SUPPORT */ - -/* - * netif_set_mtu - set the MTU on the PPP network interface. - */ -void netif_set_mtu(ppp_pcb *pcb, int mtu) { - - pcb->netif->mtu = mtu; - PPPDEBUG(LOG_INFO, ("netif_set_mtu[%d]: mtu=%d\n", pcb->netif->num, mtu)); -} - -/* - * netif_get_mtu - get PPP interface MTU - */ -int netif_get_mtu(ppp_pcb *pcb) { - - return pcb->netif->mtu; -} - -#if CCP_SUPPORT -#if 0 /* unused */ -/* - * ccp_test - whether a given compression method is acceptable for use. - */ -int -ccp_test(ppp_pcb *pcb, u_char *opt_ptr, int opt_len, int for_transmit) -{ - LWIP_UNUSED_ARG(pcb); - LWIP_UNUSED_ARG(opt_ptr); - LWIP_UNUSED_ARG(opt_len); - LWIP_UNUSED_ARG(for_transmit); - return -1; -} -#endif /* unused */ - -/* - * ccp_set - inform about the current state of CCP. - */ -void -ccp_set(ppp_pcb *pcb, u8_t isopen, u8_t isup, u8_t receive_method, u8_t transmit_method) -{ - LWIP_UNUSED_ARG(isopen); - LWIP_UNUSED_ARG(isup); - pcb->ccp_receive_method = receive_method; - pcb->ccp_transmit_method = transmit_method; - PPPDEBUG(LOG_DEBUG, ("ccp_set[%d]: is_open=%d, is_up=%d, receive_method=%u, transmit_method=%u\n", - pcb->netif->num, isopen, isup, receive_method, transmit_method)); -} - -void -ccp_reset_comp(ppp_pcb *pcb) -{ - switch (pcb->ccp_transmit_method) { -#if MPPE_SUPPORT - case CI_MPPE: - mppe_comp_reset(pcb, &pcb->mppe_comp); - break; -#endif /* MPPE_SUPPORT */ - default: - break; - } -} - -void -ccp_reset_decomp(ppp_pcb *pcb) -{ - switch (pcb->ccp_receive_method) { -#if MPPE_SUPPORT - case CI_MPPE: - mppe_decomp_reset(pcb, &pcb->mppe_decomp); - break; -#endif /* MPPE_SUPPORT */ - default: - break; - } -} - -#if 0 /* unused */ -/* - * ccp_fatal_error - returns 1 if decompression was disabled as a - * result of an error detected after decompression of a packet, - * 0 otherwise. This is necessary because of patent nonsense. - */ -int -ccp_fatal_error(ppp_pcb *pcb) -{ - LWIP_UNUSED_ARG(pcb); - return 1; -} -#endif /* unused */ -#endif /* CCP_SUPPORT */ - -#if PPP_IDLETIMELIMIT -/******************************************************************** - * - * get_idle_time - return how long the link has been idle. - */ -int get_idle_time(ppp_pcb *pcb, struct ppp_idle *ip) { - /* FIXME: add idle time support and make it optional */ - LWIP_UNUSED_ARG(pcb); - LWIP_UNUSED_ARG(ip); - return 1; -} -#endif /* PPP_IDLETIMELIMIT */ - -#if DEMAND_SUPPORT -/******************************************************************** - * - * get_loop_output - get outgoing packets from the ppp device, - * and detect when we want to bring the real link up. - * Return value is 1 if we need to bring up the link, 0 otherwise. - */ -int get_loop_output(void) { - return 0; -} -#endif /* DEMAND_SUPPORT */ - -#if PPP_PROTOCOLNAME -/* List of protocol names, to make our messages a little more informative. */ -struct protocol_list { - u_short proto; - const char *name; -} const protocol_list[] = { - { 0x21, "IP" }, - { 0x23, "OSI Network Layer" }, - { 0x25, "Xerox NS IDP" }, - { 0x27, "DECnet Phase IV" }, - { 0x29, "Appletalk" }, - { 0x2b, "Novell IPX" }, - { 0x2d, "VJ compressed TCP/IP" }, - { 0x2f, "VJ uncompressed TCP/IP" }, - { 0x31, "Bridging PDU" }, - { 0x33, "Stream Protocol ST-II" }, - { 0x35, "Banyan Vines" }, - { 0x39, "AppleTalk EDDP" }, - { 0x3b, "AppleTalk SmartBuffered" }, - { 0x3d, "Multi-Link" }, - { 0x3f, "NETBIOS Framing" }, - { 0x41, "Cisco Systems" }, - { 0x43, "Ascom Timeplex" }, - { 0x45, "Fujitsu Link Backup and Load Balancing (LBLB)" }, - { 0x47, "DCA Remote Lan" }, - { 0x49, "Serial Data Transport Protocol (PPP-SDTP)" }, - { 0x4b, "SNA over 802.2" }, - { 0x4d, "SNA" }, - { 0x4f, "IP6 Header Compression" }, - { 0x51, "KNX Bridging Data" }, - { 0x53, "Encryption" }, - { 0x55, "Individual Link Encryption" }, - { 0x57, "IPv6" }, - { 0x59, "PPP Muxing" }, - { 0x5b, "Vendor-Specific Network Protocol" }, - { 0x61, "RTP IPHC Full Header" }, - { 0x63, "RTP IPHC Compressed TCP" }, - { 0x65, "RTP IPHC Compressed non-TCP" }, - { 0x67, "RTP IPHC Compressed UDP 8" }, - { 0x69, "RTP IPHC Compressed RTP 8" }, - { 0x6f, "Stampede Bridging" }, - { 0x73, "MP+" }, - { 0xc1, "NTCITS IPI" }, - { 0xfb, "single-link compression" }, - { 0xfd, "Compressed Datagram" }, - { 0x0201, "802.1d Hello Packets" }, - { 0x0203, "IBM Source Routing BPDU" }, - { 0x0205, "DEC LANBridge100 Spanning Tree" }, - { 0x0207, "Cisco Discovery Protocol" }, - { 0x0209, "Netcs Twin Routing" }, - { 0x020b, "STP - Scheduled Transfer Protocol" }, - { 0x020d, "EDP - Extreme Discovery Protocol" }, - { 0x0211, "Optical Supervisory Channel Protocol" }, - { 0x0213, "Optical Supervisory Channel Protocol" }, - { 0x0231, "Luxcom" }, - { 0x0233, "Sigma Network Systems" }, - { 0x0235, "Apple Client Server Protocol" }, - { 0x0281, "MPLS Unicast" }, - { 0x0283, "MPLS Multicast" }, - { 0x0285, "IEEE p1284.4 standard - data packets" }, - { 0x0287, "ETSI TETRA Network Protocol Type 1" }, - { 0x0289, "Multichannel Flow Treatment Protocol" }, - { 0x2063, "RTP IPHC Compressed TCP No Delta" }, - { 0x2065, "RTP IPHC Context State" }, - { 0x2067, "RTP IPHC Compressed UDP 16" }, - { 0x2069, "RTP IPHC Compressed RTP 16" }, - { 0x4001, "Cray Communications Control Protocol" }, - { 0x4003, "CDPD Mobile Network Registration Protocol" }, - { 0x4005, "Expand accelerator protocol" }, - { 0x4007, "ODSICP NCP" }, - { 0x4009, "DOCSIS DLL" }, - { 0x400B, "Cetacean Network Detection Protocol" }, - { 0x4021, "Stacker LZS" }, - { 0x4023, "RefTek Protocol" }, - { 0x4025, "Fibre Channel" }, - { 0x4027, "EMIT Protocols" }, - { 0x405b, "Vendor-Specific Protocol (VSP)" }, - { 0x8021, "Internet Protocol Control Protocol" }, - { 0x8023, "OSI Network Layer Control Protocol" }, - { 0x8025, "Xerox NS IDP Control Protocol" }, - { 0x8027, "DECnet Phase IV Control Protocol" }, - { 0x8029, "Appletalk Control Protocol" }, - { 0x802b, "Novell IPX Control Protocol" }, - { 0x8031, "Bridging NCP" }, - { 0x8033, "Stream Protocol Control Protocol" }, - { 0x8035, "Banyan Vines Control Protocol" }, - { 0x803d, "Multi-Link Control Protocol" }, - { 0x803f, "NETBIOS Framing Control Protocol" }, - { 0x8041, "Cisco Systems Control Protocol" }, - { 0x8043, "Ascom Timeplex" }, - { 0x8045, "Fujitsu LBLB Control Protocol" }, - { 0x8047, "DCA Remote Lan Network Control Protocol (RLNCP)" }, - { 0x8049, "Serial Data Control Protocol (PPP-SDCP)" }, - { 0x804b, "SNA over 802.2 Control Protocol" }, - { 0x804d, "SNA Control Protocol" }, - { 0x804f, "IP6 Header Compression Control Protocol" }, - { 0x8051, "KNX Bridging Control Protocol" }, - { 0x8053, "Encryption Control Protocol" }, - { 0x8055, "Individual Link Encryption Control Protocol" }, - { 0x8057, "IPv6 Control Protocol" }, - { 0x8059, "PPP Muxing Control Protocol" }, - { 0x805b, "Vendor-Specific Network Control Protocol (VSNCP)" }, - { 0x806f, "Stampede Bridging Control Protocol" }, - { 0x8073, "MP+ Control Protocol" }, - { 0x80c1, "NTCITS IPI Control Protocol" }, - { 0x80fb, "Single Link Compression Control Protocol" }, - { 0x80fd, "Compression Control Protocol" }, - { 0x8207, "Cisco Discovery Protocol Control" }, - { 0x8209, "Netcs Twin Routing" }, - { 0x820b, "STP - Control Protocol" }, - { 0x820d, "EDPCP - Extreme Discovery Protocol Ctrl Prtcl" }, - { 0x8235, "Apple Client Server Protocol Control" }, - { 0x8281, "MPLSCP" }, - { 0x8285, "IEEE p1284.4 standard - Protocol Control" }, - { 0x8287, "ETSI TETRA TNP1 Control Protocol" }, - { 0x8289, "Multichannel Flow Treatment Protocol" }, - { 0xc021, "Link Control Protocol" }, - { 0xc023, "Password Authentication Protocol" }, - { 0xc025, "Link Quality Report" }, - { 0xc027, "Shiva Password Authentication Protocol" }, - { 0xc029, "CallBack Control Protocol (CBCP)" }, - { 0xc02b, "BACP Bandwidth Allocation Control Protocol" }, - { 0xc02d, "BAP" }, - { 0xc05b, "Vendor-Specific Authentication Protocol (VSAP)" }, - { 0xc081, "Container Control Protocol" }, - { 0xc223, "Challenge Handshake Authentication Protocol" }, - { 0xc225, "RSA Authentication Protocol" }, - { 0xc227, "Extensible Authentication Protocol" }, - { 0xc229, "Mitsubishi Security Info Exch Ptcl (SIEP)" }, - { 0xc26f, "Stampede Bridging Authorization Protocol" }, - { 0xc281, "Proprietary Authentication Protocol" }, - { 0xc283, "Proprietary Authentication Protocol" }, - { 0xc481, "Proprietary Node ID Authentication Protocol" }, - { 0, NULL }, -}; - -/* - * protocol_name - find a name for a PPP protocol. - */ -const char * protocol_name(int proto) { - const struct protocol_list *lp; - - for (lp = protocol_list; lp->proto != 0; ++lp) { - if (proto == lp->proto) { - return lp->name; - } - } - return NULL; -} -#endif /* PPP_PROTOCOLNAME */ - -#if PPP_STATS_SUPPORT - -/* ---- Note on PPP Stats support ---- - * - * The one willing link stats support should add the get_ppp_stats() - * to fetch statistics from lwIP. - */ - -/* - * reset_link_stats - "reset" stats when link goes up. - */ -void reset_link_stats(int u) { - if (!get_ppp_stats(u, &old_link_stats)) { - return; - } - gettimeofday(&start_time, NULL); -} - -/* - * update_link_stats - get stats at link termination. - */ -void update_link_stats(int u) { - struct timeval now; - char numbuf[32]; - - if (!get_ppp_stats(u, &link_stats) || gettimeofday(&now, NULL) < 0) { - return; - } - link_connect_time = now.tv_sec - start_time.tv_sec; - link_stats_valid = 1; - - link_stats.bytes_in -= old_link_stats.bytes_in; - link_stats.bytes_out -= old_link_stats.bytes_out; - link_stats.pkts_in -= old_link_stats.pkts_in; - link_stats.pkts_out -= old_link_stats.pkts_out; -} - -void print_link_stats() { - /* - * Print connect time and statistics. - */ - if (link_stats_valid) { - int t = (link_connect_time + 5) / 6; /* 1/10ths of minutes */ - info("Connect time %d.%d minutes.", t/10, t%10); - info("Sent %u bytes, received %u bytes.", link_stats.bytes_out, link_stats.bytes_in); - link_stats_valid = 0; - } -} -#endif /* PPP_STATS_SUPPORT */ - -#endif /* PPP_SUPPORT */ diff --git a/third-party/lwip-2.1.2/netif/ppp/pppapi.c b/third-party/lwip-2.1.2/netif/ppp/pppapi.c deleted file mode 100644 index 947f7ba8..00000000 --- a/third-party/lwip-2.1.2/netif/ppp/pppapi.c +++ /dev/null @@ -1,427 +0,0 @@ -/** - * @file - * Point To Point Protocol Sequential API module - * - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#include "netif/ppp/ppp_opts.h" - -#if LWIP_PPP_API /* don't build if not configured for use in lwipopts.h */ - -#include "netif/ppp/pppapi.h" -#include "lwip/priv/tcpip_priv.h" -#include "netif/ppp/pppoe.h" -#include "netif/ppp/pppol2tp.h" -#include "netif/ppp/pppos.h" - -#if LWIP_MPU_COMPATIBLE -LWIP_MEMPOOL_DECLARE(PPPAPI_MSG, MEMP_NUM_PPP_API_MSG, sizeof(struct pppapi_msg), "PPPAPI_MSG") -#endif - -#define PPPAPI_VAR_REF(name) API_VAR_REF(name) -#define PPPAPI_VAR_DECLARE(name) API_VAR_DECLARE(struct pppapi_msg, name) -#define PPPAPI_VAR_ALLOC(name) API_VAR_ALLOC_POOL(struct pppapi_msg, PPPAPI_MSG, name, ERR_MEM) -#define PPPAPI_VAR_ALLOC_RETURN_NULL(name) API_VAR_ALLOC_POOL(struct pppapi_msg, PPPAPI_MSG, name, NULL) -#define PPPAPI_VAR_FREE(name) API_VAR_FREE_POOL(PPPAPI_MSG, name) - -/** - * Call ppp_set_default() inside the tcpip_thread context. - */ -static err_t -pppapi_do_ppp_set_default(struct tcpip_api_call_data *m) -{ - /* cast through void* to silence alignment warnings. - * We know it works because the structs have been instantiated as struct pppapi_msg */ - struct pppapi_msg *msg = (struct pppapi_msg *)(void*)m; - - ppp_set_default(msg->msg.ppp); - return ERR_OK; -} - -/** - * Call ppp_set_default() in a thread-safe way by running that function inside the - * tcpip_thread context. - */ -err_t -pppapi_set_default(ppp_pcb *pcb) -{ - err_t err; - PPPAPI_VAR_DECLARE(msg); - PPPAPI_VAR_ALLOC(msg); - - PPPAPI_VAR_REF(msg).msg.ppp = pcb; - err = tcpip_api_call(pppapi_do_ppp_set_default, &PPPAPI_VAR_REF(msg).call); - PPPAPI_VAR_FREE(msg); - return err; -} - - -#if PPP_NOTIFY_PHASE -/** - * Call ppp_set_notify_phase_callback() inside the tcpip_thread context. - */ -static err_t -pppapi_do_ppp_set_notify_phase_callback(struct tcpip_api_call_data *m) -{ - /* cast through void* to silence alignment warnings. - * We know it works because the structs have been instantiated as struct pppapi_msg */ - struct pppapi_msg *msg = (struct pppapi_msg *)(void*)m; - - ppp_set_notify_phase_callback(msg->msg.ppp, msg->msg.msg.setnotifyphasecb.notify_phase_cb); - return ERR_OK; -} - -/** - * Call ppp_set_notify_phase_callback() in a thread-safe way by running that function inside the - * tcpip_thread context. - */ -err_t -pppapi_set_notify_phase_callback(ppp_pcb *pcb, ppp_notify_phase_cb_fn notify_phase_cb) -{ - err_t err; - PPPAPI_VAR_DECLARE(msg); - PPPAPI_VAR_ALLOC(msg); - - PPPAPI_VAR_REF(msg).msg.ppp = pcb; - PPPAPI_VAR_REF(msg).msg.msg.setnotifyphasecb.notify_phase_cb = notify_phase_cb; - err = tcpip_api_call(pppapi_do_ppp_set_notify_phase_callback, &PPPAPI_VAR_REF(msg).call); - PPPAPI_VAR_FREE(msg); - return err; -} -#endif /* PPP_NOTIFY_PHASE */ - - -#if PPPOS_SUPPORT -/** - * Call pppos_create() inside the tcpip_thread context. - */ -static err_t -pppapi_do_pppos_create(struct tcpip_api_call_data *m) -{ - /* cast through void* to silence alignment warnings. - * We know it works because the structs have been instantiated as struct pppapi_msg */ - struct pppapi_msg *msg = (struct pppapi_msg *)(void*)m; - - msg->msg.ppp = pppos_create(msg->msg.msg.serialcreate.pppif, msg->msg.msg.serialcreate.output_cb, - msg->msg.msg.serialcreate.link_status_cb, msg->msg.msg.serialcreate.ctx_cb); - return ERR_OK; -} - -/** - * Call pppos_create() in a thread-safe way by running that function inside the - * tcpip_thread context. - */ -ppp_pcb* -pppapi_pppos_create(struct netif *pppif, pppos_output_cb_fn output_cb, - ppp_link_status_cb_fn link_status_cb, void *ctx_cb) -{ - ppp_pcb* result; - PPPAPI_VAR_DECLARE(msg); - PPPAPI_VAR_ALLOC_RETURN_NULL(msg); - - PPPAPI_VAR_REF(msg).msg.ppp = NULL; - PPPAPI_VAR_REF(msg).msg.msg.serialcreate.pppif = pppif; - PPPAPI_VAR_REF(msg).msg.msg.serialcreate.output_cb = output_cb; - PPPAPI_VAR_REF(msg).msg.msg.serialcreate.link_status_cb = link_status_cb; - PPPAPI_VAR_REF(msg).msg.msg.serialcreate.ctx_cb = ctx_cb; - tcpip_api_call(pppapi_do_pppos_create, &PPPAPI_VAR_REF(msg).call); - result = PPPAPI_VAR_REF(msg).msg.ppp; - PPPAPI_VAR_FREE(msg); - return result; -} -#endif /* PPPOS_SUPPORT */ - - -#if PPPOE_SUPPORT -/** - * Call pppoe_create() inside the tcpip_thread context. - */ -static err_t -pppapi_do_pppoe_create(struct tcpip_api_call_data *m) -{ - /* cast through void* to silence alignment warnings. - * We know it works because the structs have been instantiated as struct pppapi_msg */ - struct pppapi_msg *msg = (struct pppapi_msg *)(void*)m; - - msg->msg.ppp = pppoe_create(msg->msg.msg.ethernetcreate.pppif, msg->msg.msg.ethernetcreate.ethif, - msg->msg.msg.ethernetcreate.service_name, msg->msg.msg.ethernetcreate.concentrator_name, - msg->msg.msg.ethernetcreate.link_status_cb, msg->msg.msg.ethernetcreate.ctx_cb); - return ERR_OK; -} - -/** - * Call pppoe_create() in a thread-safe way by running that function inside the - * tcpip_thread context. - */ -ppp_pcb* -pppapi_pppoe_create(struct netif *pppif, struct netif *ethif, const char *service_name, - const char *concentrator_name, ppp_link_status_cb_fn link_status_cb, - void *ctx_cb) -{ - ppp_pcb* result; - PPPAPI_VAR_DECLARE(msg); - PPPAPI_VAR_ALLOC_RETURN_NULL(msg); - - PPPAPI_VAR_REF(msg).msg.ppp = NULL; - PPPAPI_VAR_REF(msg).msg.msg.ethernetcreate.pppif = pppif; - PPPAPI_VAR_REF(msg).msg.msg.ethernetcreate.ethif = ethif; - PPPAPI_VAR_REF(msg).msg.msg.ethernetcreate.service_name = service_name; - PPPAPI_VAR_REF(msg).msg.msg.ethernetcreate.concentrator_name = concentrator_name; - PPPAPI_VAR_REF(msg).msg.msg.ethernetcreate.link_status_cb = link_status_cb; - PPPAPI_VAR_REF(msg).msg.msg.ethernetcreate.ctx_cb = ctx_cb; - tcpip_api_call(pppapi_do_pppoe_create, &PPPAPI_VAR_REF(msg).call); - result = PPPAPI_VAR_REF(msg).msg.ppp; - PPPAPI_VAR_FREE(msg); - return result; -} -#endif /* PPPOE_SUPPORT */ - - -#if PPPOL2TP_SUPPORT -/** - * Call pppol2tp_create() inside the tcpip_thread context. - */ -static err_t -pppapi_do_pppol2tp_create(struct tcpip_api_call_data *m) -{ - /* cast through void* to silence alignment warnings. - * We know it works because the structs have been instantiated as struct pppapi_msg */ - struct pppapi_msg *msg = (struct pppapi_msg *)(void*)m; - - msg->msg.ppp = pppol2tp_create(msg->msg.msg.l2tpcreate.pppif, - msg->msg.msg.l2tpcreate.netif, API_EXPR_REF(msg->msg.msg.l2tpcreate.ipaddr), msg->msg.msg.l2tpcreate.port, -#if PPPOL2TP_AUTH_SUPPORT - msg->msg.msg.l2tpcreate.secret, - msg->msg.msg.l2tpcreate.secret_len, -#else /* PPPOL2TP_AUTH_SUPPORT */ - NULL, - 0, -#endif /* PPPOL2TP_AUTH_SUPPORT */ - msg->msg.msg.l2tpcreate.link_status_cb, msg->msg.msg.l2tpcreate.ctx_cb); - return ERR_OK; -} - -/** - * Call pppol2tp_create() in a thread-safe way by running that function inside the - * tcpip_thread context. - */ -ppp_pcb* -pppapi_pppol2tp_create(struct netif *pppif, struct netif *netif, ip_addr_t *ipaddr, u16_t port, - const u8_t *secret, u8_t secret_len, - ppp_link_status_cb_fn link_status_cb, void *ctx_cb) -{ - ppp_pcb* result; - PPPAPI_VAR_DECLARE(msg); - PPPAPI_VAR_ALLOC_RETURN_NULL(msg); -#if !PPPOL2TP_AUTH_SUPPORT - LWIP_UNUSED_ARG(secret); - LWIP_UNUSED_ARG(secret_len); -#endif /* !PPPOL2TP_AUTH_SUPPORT */ - - PPPAPI_VAR_REF(msg).msg.ppp = NULL; - PPPAPI_VAR_REF(msg).msg.msg.l2tpcreate.pppif = pppif; - PPPAPI_VAR_REF(msg).msg.msg.l2tpcreate.netif = netif; - PPPAPI_VAR_REF(msg).msg.msg.l2tpcreate.ipaddr = PPPAPI_VAR_REF(ipaddr); - PPPAPI_VAR_REF(msg).msg.msg.l2tpcreate.port = port; -#if PPPOL2TP_AUTH_SUPPORT - PPPAPI_VAR_REF(msg).msg.msg.l2tpcreate.secret = secret; - PPPAPI_VAR_REF(msg).msg.msg.l2tpcreate.secret_len = secret_len; -#endif /* PPPOL2TP_AUTH_SUPPORT */ - PPPAPI_VAR_REF(msg).msg.msg.l2tpcreate.link_status_cb = link_status_cb; - PPPAPI_VAR_REF(msg).msg.msg.l2tpcreate.ctx_cb = ctx_cb; - tcpip_api_call(pppapi_do_pppol2tp_create, &PPPAPI_VAR_REF(msg).call); - result = PPPAPI_VAR_REF(msg).msg.ppp; - PPPAPI_VAR_FREE(msg); - return result; -} -#endif /* PPPOL2TP_SUPPORT */ - - -/** - * Call ppp_connect() inside the tcpip_thread context. - */ -static err_t -pppapi_do_ppp_connect(struct tcpip_api_call_data *m) -{ - /* cast through void* to silence alignment warnings. - * We know it works because the structs have been instantiated as struct pppapi_msg */ - struct pppapi_msg *msg = (struct pppapi_msg *)(void*)m; - - return ppp_connect(msg->msg.ppp, msg->msg.msg.connect.holdoff); -} - -/** - * Call ppp_connect() in a thread-safe way by running that function inside the - * tcpip_thread context. - */ -err_t -pppapi_connect(ppp_pcb *pcb, u16_t holdoff) -{ - err_t err; - PPPAPI_VAR_DECLARE(msg); - PPPAPI_VAR_ALLOC(msg); - - PPPAPI_VAR_REF(msg).msg.ppp = pcb; - PPPAPI_VAR_REF(msg).msg.msg.connect.holdoff = holdoff; - err = tcpip_api_call(pppapi_do_ppp_connect, &PPPAPI_VAR_REF(msg).call); - PPPAPI_VAR_FREE(msg); - return err; -} - - -#if PPP_SERVER -/** - * Call ppp_listen() inside the tcpip_thread context. - */ -static err_t -pppapi_do_ppp_listen(struct tcpip_api_call_data *m) -{ - /* cast through void* to silence alignment warnings. - * We know it works because the structs have been instantiated as struct pppapi_msg */ - struct pppapi_msg *msg = (struct pppapi_msg *)(void*)m; - - return ppp_listen(msg->msg.ppp); -} - -/** - * Call ppp_listen() in a thread-safe way by running that function inside the - * tcpip_thread context. - */ -err_t -pppapi_listen(ppp_pcb *pcb) -{ - err_t err; - PPPAPI_VAR_DECLARE(msg); - PPPAPI_VAR_ALLOC(msg); - - PPPAPI_VAR_REF(msg).msg.ppp = pcb; - err = tcpip_api_call(pppapi_do_ppp_listen, &PPPAPI_VAR_REF(msg).call); - PPPAPI_VAR_FREE(msg); - return err; -} -#endif /* PPP_SERVER */ - - -/** - * Call ppp_close() inside the tcpip_thread context. - */ -static err_t -pppapi_do_ppp_close(struct tcpip_api_call_data *m) -{ - /* cast through void* to silence alignment warnings. - * We know it works because the structs have been instantiated as struct pppapi_msg */ - struct pppapi_msg *msg = (struct pppapi_msg *)(void*)m; - - return ppp_close(msg->msg.ppp, msg->msg.msg.close.nocarrier); -} - -/** - * Call ppp_close() in a thread-safe way by running that function inside the - * tcpip_thread context. - */ -err_t -pppapi_close(ppp_pcb *pcb, u8_t nocarrier) -{ - err_t err; - PPPAPI_VAR_DECLARE(msg); - PPPAPI_VAR_ALLOC(msg); - - PPPAPI_VAR_REF(msg).msg.ppp = pcb; - PPPAPI_VAR_REF(msg).msg.msg.close.nocarrier = nocarrier; - err = tcpip_api_call(pppapi_do_ppp_close, &PPPAPI_VAR_REF(msg).call); - PPPAPI_VAR_FREE(msg); - return err; -} - - -/** - * Call ppp_free() inside the tcpip_thread context. - */ -static err_t -pppapi_do_ppp_free(struct tcpip_api_call_data *m) -{ - /* cast through void* to silence alignment warnings. - * We know it works because the structs have been instantiated as struct pppapi_msg */ - struct pppapi_msg *msg = (struct pppapi_msg *)(void*)m; - - return ppp_free(msg->msg.ppp); -} - -/** - * Call ppp_free() in a thread-safe way by running that function inside the - * tcpip_thread context. - */ -err_t -pppapi_free(ppp_pcb *pcb) -{ - err_t err; - PPPAPI_VAR_DECLARE(msg); - PPPAPI_VAR_ALLOC(msg); - - PPPAPI_VAR_REF(msg).msg.ppp = pcb; - err = tcpip_api_call(pppapi_do_ppp_free, &PPPAPI_VAR_REF(msg).call); - PPPAPI_VAR_FREE(msg); - return err; -} - - -/** - * Call ppp_ioctl() inside the tcpip_thread context. - */ -static err_t -pppapi_do_ppp_ioctl(struct tcpip_api_call_data *m) -{ - /* cast through void* to silence alignment warnings. - * We know it works because the structs have been instantiated as struct pppapi_msg */ - struct pppapi_msg *msg = (struct pppapi_msg *)(void*)m; - - return ppp_ioctl(msg->msg.ppp, msg->msg.msg.ioctl.cmd, msg->msg.msg.ioctl.arg); -} - -/** - * Call ppp_ioctl() in a thread-safe way by running that function inside the - * tcpip_thread context. - */ -err_t -pppapi_ioctl(ppp_pcb *pcb, u8_t cmd, void *arg) -{ - err_t err; - PPPAPI_VAR_DECLARE(msg); - PPPAPI_VAR_ALLOC(msg); - - PPPAPI_VAR_REF(msg).msg.ppp = pcb; - PPPAPI_VAR_REF(msg).msg.msg.ioctl.cmd = cmd; - PPPAPI_VAR_REF(msg).msg.msg.ioctl.arg = arg; - err = tcpip_api_call(pppapi_do_ppp_ioctl, &PPPAPI_VAR_REF(msg).call); - PPPAPI_VAR_FREE(msg); - return err; -} - -#endif /* LWIP_PPP_API */ diff --git a/third-party/lwip-2.1.2/netif/ppp/pppcrypt.c b/third-party/lwip-2.1.2/netif/ppp/pppcrypt.c deleted file mode 100644 index 82d78c13..00000000 --- a/third-party/lwip-2.1.2/netif/ppp/pppcrypt.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * pppcrypt.c - PPP/DES linkage for MS-CHAP and EAP SRP-SHA1 - * - * Extracted from chap_ms.c by James Carlson. - * - * Copyright (c) 1995 Eric Rosenquist. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && MSCHAP_SUPPORT /* don't build if not necessary */ - -#include "netif/ppp/ppp_impl.h" - -#include "netif/ppp/pppcrypt.h" - - -static u_char pppcrypt_get_7bits(u_char *input, int startBit) { - unsigned int word; - - word = (unsigned)input[startBit / 8] << 8; - word |= (unsigned)input[startBit / 8 + 1]; - - word >>= 15 - (startBit % 8 + 7); - - return word & 0xFE; -} - -/* IN 56 bit DES key missing parity bits - * OUT 64 bit DES key with parity bits added - */ -void pppcrypt_56_to_64_bit_key(u_char *key, u_char * des_key) { - des_key[0] = pppcrypt_get_7bits(key, 0); - des_key[1] = pppcrypt_get_7bits(key, 7); - des_key[2] = pppcrypt_get_7bits(key, 14); - des_key[3] = pppcrypt_get_7bits(key, 21); - des_key[4] = pppcrypt_get_7bits(key, 28); - des_key[5] = pppcrypt_get_7bits(key, 35); - des_key[6] = pppcrypt_get_7bits(key, 42); - des_key[7] = pppcrypt_get_7bits(key, 49); -} - -#endif /* PPP_SUPPORT && MSCHAP_SUPPORT */ diff --git a/third-party/lwip-2.1.2/netif/ppp/pppoe.c b/third-party/lwip-2.1.2/netif/ppp/pppoe.c deleted file mode 100644 index 8ed2d638..00000000 --- a/third-party/lwip-2.1.2/netif/ppp/pppoe.c +++ /dev/null @@ -1,1201 +0,0 @@ -/***************************************************************************** -* pppoe.c - PPP Over Ethernet implementation for lwIP. -* -* Copyright (c) 2006 by Marc Boucher, Services Informatiques (MBSI) inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 06-01-01 Marc Boucher -* Ported to lwIP. -*****************************************************************************/ - - - -/* based on NetBSD: if_pppoe.c,v 1.64 2006/01/31 23:50:15 martin Exp */ - -/*- - * Copyright (c) 2002 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Martin Husemann . - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && PPPOE_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#if 0 /* UNUSED */ -#include -#include -#endif /* UNUSED */ - -#include "lwip/timeouts.h" -#include "lwip/memp.h" -#include "lwip/stats.h" -#include "lwip/snmp.h" - -#include "netif/ethernet.h" -#include "netif/ppp/ppp_impl.h" -#include "netif/ppp/lcp.h" -#include "netif/ppp/ipcp.h" -#include "netif/ppp/pppoe.h" - -/* Memory pool */ -LWIP_MEMPOOL_DECLARE(PPPOE_IF, MEMP_NUM_PPPOE_INTERFACES, sizeof(struct pppoe_softc), "PPPOE_IF") - -/* Add a 16 bit unsigned value to a buffer pointed to by PTR */ -#define PPPOE_ADD_16(PTR, VAL) \ - *(PTR)++ = (u8_t)((VAL) / 256); \ - *(PTR)++ = (u8_t)((VAL) % 256) - -/* Add a complete PPPoE header to the buffer pointed to by PTR */ -#define PPPOE_ADD_HEADER(PTR, CODE, SESS, LEN) \ - *(PTR)++ = PPPOE_VERTYPE; \ - *(PTR)++ = (CODE); \ - PPPOE_ADD_16(PTR, SESS); \ - PPPOE_ADD_16(PTR, LEN) - -#define PPPOE_DISC_TIMEOUT (5*1000) /* base for quick timeout calculation */ -#define PPPOE_SLOW_RETRY (60*1000) /* persistent retry interval */ -#define PPPOE_DISC_MAXPADI 4 /* retry PADI four times (quickly) */ -#define PPPOE_DISC_MAXPADR 2 /* retry PADR twice */ - -#ifdef PPPOE_SERVER -#error "PPPOE_SERVER is not yet supported under lwIP!" -/* from if_spppsubr.c */ -#define IFF_PASSIVE IFF_LINK0 /* wait passively for connection */ -#endif - -#define PPPOE_ERRORSTRING_LEN 64 - - -/* callbacks called from PPP core */ -static err_t pppoe_write(ppp_pcb *ppp, void *ctx, struct pbuf *p); -static err_t pppoe_netif_output(ppp_pcb *ppp, void *ctx, struct pbuf *p, u_short protocol); -static void pppoe_connect(ppp_pcb *ppp, void *ctx); -static void pppoe_disconnect(ppp_pcb *ppp, void *ctx); -static err_t pppoe_destroy(ppp_pcb *ppp, void *ctx); - -/* management routines */ -static void pppoe_abort_connect(struct pppoe_softc *); -#if 0 /* UNUSED */ -static void pppoe_clear_softc(struct pppoe_softc *, const char *); -#endif /* UNUSED */ - -/* internal timeout handling */ -static void pppoe_timeout(void *); - -/* sending actual protocol controll packets */ -static err_t pppoe_send_padi(struct pppoe_softc *); -static err_t pppoe_send_padr(struct pppoe_softc *); -#ifdef PPPOE_SERVER -static err_t pppoe_send_pado(struct pppoe_softc *); -static err_t pppoe_send_pads(struct pppoe_softc *); -#endif -static err_t pppoe_send_padt(struct netif *, u_int, const u8_t *); - -/* internal helper functions */ -static err_t pppoe_xmit(struct pppoe_softc *sc, struct pbuf *pb); -static struct pppoe_softc* pppoe_find_softc_by_session(u_int session, struct netif *rcvif); -static struct pppoe_softc* pppoe_find_softc_by_hunique(u8_t *token, size_t len, struct netif *rcvif); - -/** linked list of created pppoe interfaces */ -static struct pppoe_softc *pppoe_softc_list; - -/* Callbacks structure for PPP core */ -static const struct link_callbacks pppoe_callbacks = { - pppoe_connect, -#if PPP_SERVER - NULL, -#endif /* PPP_SERVER */ - pppoe_disconnect, - pppoe_destroy, - pppoe_write, - pppoe_netif_output, - NULL, - NULL -}; - -/* - * Create a new PPP Over Ethernet (PPPoE) connection. - * - * Return 0 on success, an error code on failure. - */ -ppp_pcb *pppoe_create(struct netif *pppif, - struct netif *ethif, - const char *service_name, const char *concentrator_name, - ppp_link_status_cb_fn link_status_cb, void *ctx_cb) -{ - ppp_pcb *ppp; - struct pppoe_softc *sc; - LWIP_UNUSED_ARG(service_name); - LWIP_UNUSED_ARG(concentrator_name); - LWIP_ASSERT_CORE_LOCKED(); - - sc = (struct pppoe_softc *)LWIP_MEMPOOL_ALLOC(PPPOE_IF); - if (sc == NULL) { - return NULL; - } - - ppp = ppp_new(pppif, &pppoe_callbacks, sc, link_status_cb, ctx_cb); - if (ppp == NULL) { - LWIP_MEMPOOL_FREE(PPPOE_IF, sc); - return NULL; - } - - memset(sc, 0, sizeof(struct pppoe_softc)); - sc->pcb = ppp; - sc->sc_ethif = ethif; - /* put the new interface at the head of the list */ - sc->next = pppoe_softc_list; - pppoe_softc_list = sc; - return ppp; -} - -/* Called by PPP core */ -static err_t pppoe_write(ppp_pcb *ppp, void *ctx, struct pbuf *p) { - struct pppoe_softc *sc = (struct pppoe_softc *)ctx; - struct pbuf *ph; /* Ethernet + PPPoE header */ - err_t ret; -#if MIB2_STATS - u16_t tot_len; -#else /* MIB2_STATS */ - LWIP_UNUSED_ARG(ppp); -#endif /* MIB2_STATS */ - - /* skip address & flags */ - pbuf_remove_header(p, 2); - - ph = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HEADERLEN), PBUF_RAM); - if(!ph) { - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.proterr); - MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards); - pbuf_free(p); - return ERR_MEM; - } - - pbuf_remove_header(ph, PPPOE_HEADERLEN); /* hide PPPoE header */ - pbuf_cat(ph, p); -#if MIB2_STATS - tot_len = ph->tot_len; -#endif /* MIB2_STATS */ - - ret = pppoe_xmit(sc, ph); - if (ret != ERR_OK) { - LINK_STATS_INC(link.err); - MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards); - return ret; - } - - MIB2_STATS_NETIF_ADD(ppp->netif, ifoutoctets, (u16_t)tot_len); - MIB2_STATS_NETIF_INC(ppp->netif, ifoutucastpkts); - LINK_STATS_INC(link.xmit); - return ERR_OK; -} - -/* Called by PPP core */ -static err_t pppoe_netif_output(ppp_pcb *ppp, void *ctx, struct pbuf *p, u_short protocol) { - struct pppoe_softc *sc = (struct pppoe_softc *)ctx; - struct pbuf *pb; - u8_t *pl; - err_t err; -#if MIB2_STATS - u16_t tot_len; -#else /* MIB2_STATS */ - LWIP_UNUSED_ARG(ppp); -#endif /* MIB2_STATS */ - - /* @todo: try to use pbuf_header() here! */ - pb = pbuf_alloc(PBUF_LINK, PPPOE_HEADERLEN + sizeof(protocol), PBUF_RAM); - if(!pb) { - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.proterr); - MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards); - return ERR_MEM; - } - - pbuf_remove_header(pb, PPPOE_HEADERLEN); - - pl = (u8_t*)pb->payload; - PUTSHORT(protocol, pl); - - pbuf_chain(pb, p); -#if MIB2_STATS - tot_len = pb->tot_len; -#endif /* MIB2_STATS */ - - if( (err = pppoe_xmit(sc, pb)) != ERR_OK) { - LINK_STATS_INC(link.err); - MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards); - return err; - } - - MIB2_STATS_NETIF_ADD(ppp->netif, ifoutoctets, tot_len); - MIB2_STATS_NETIF_INC(ppp->netif, ifoutucastpkts); - LINK_STATS_INC(link.xmit); - return ERR_OK; -} - -static err_t -pppoe_destroy(ppp_pcb *ppp, void *ctx) -{ - struct pppoe_softc *sc = (struct pppoe_softc *)ctx; - struct pppoe_softc **copp, *freep; - LWIP_UNUSED_ARG(ppp); - - sys_untimeout(pppoe_timeout, sc); - - /* remove interface from list */ - for (copp = &pppoe_softc_list; (freep = *copp); copp = &freep->next) { - if (freep == sc) { - *copp = freep->next; - break; - } - } - -#ifdef PPPOE_TODO - if (sc->sc_concentrator_name) { - mem_free(sc->sc_concentrator_name); - } - if (sc->sc_service_name) { - mem_free(sc->sc_service_name); - } -#endif /* PPPOE_TODO */ - LWIP_MEMPOOL_FREE(PPPOE_IF, sc); - - return ERR_OK; -} - -/* - * Find the interface handling the specified session. - * Note: O(number of sessions open), this is a client-side only, mean - * and lean implementation, so number of open sessions typically should - * be 1. - */ -static struct pppoe_softc* pppoe_find_softc_by_session(u_int session, struct netif *rcvif) { - struct pppoe_softc *sc; - - for (sc = pppoe_softc_list; sc != NULL; sc = sc->next) { - if (sc->sc_state == PPPOE_STATE_SESSION - && sc->sc_session == session - && sc->sc_ethif == rcvif) { - return sc; - } - } - return NULL; -} - -/* Check host unique token passed and return appropriate softc pointer, - * or NULL if token is bogus. */ -static struct pppoe_softc* pppoe_find_softc_by_hunique(u8_t *token, size_t len, struct netif *rcvif) { - struct pppoe_softc *sc, *t; - - if (len != sizeof sc) { - return NULL; - } - MEMCPY(&t, token, len); - - for (sc = pppoe_softc_list; sc != NULL; sc = sc->next) { - if (sc == t) { - break; - } - } - - if (sc == NULL) { - PPPDEBUG(LOG_DEBUG, ("pppoe: alien host unique tag, no session found\n")); - return NULL; - } - - /* should be safe to access *sc now */ - if (sc->sc_state < PPPOE_STATE_PADI_SENT || sc->sc_state >= PPPOE_STATE_SESSION) { - PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": host unique tag found, but it belongs to a connection in state %d\n", - sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, sc->sc_state)); - return NULL; - } - if (sc->sc_ethif != rcvif) { - PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": wrong interface, not accepting host unique\n", - sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); - return NULL; - } - return sc; -} - -/* analyze and handle a single received packet while not in session state */ -void -pppoe_disc_input(struct netif *netif, struct pbuf *pb) -{ - u16_t tag, len, off; - u16_t session, plen; - struct pppoe_softc *sc; -#if PPP_DEBUG - const char *err_msg = NULL; -#endif /* PPP_DEBUG */ - u8_t *ac_cookie; - u16_t ac_cookie_len; -#ifdef PPPOE_SERVER - u8_t *hunique; - size_t hunique_len; -#endif - struct pppoehdr *ph; - struct pppoetag pt; - int err; - struct eth_hdr *ethhdr; - - /* don't do anything if there is not a single PPPoE instance */ - if (pppoe_softc_list == NULL) { - pbuf_free(pb); - return; - } - - pb = pbuf_coalesce(pb, PBUF_RAW); - - ethhdr = (struct eth_hdr *)pb->payload; - - ac_cookie = NULL; - ac_cookie_len = 0; -#ifdef PPPOE_SERVER - hunique = NULL; - hunique_len = 0; -#endif - session = 0; - off = sizeof(struct eth_hdr) + sizeof(struct pppoehdr); - if (pb->len < off) { - PPPDEBUG(LOG_DEBUG, ("pppoe: packet too short: %d\n", pb->len)); - goto done; - } - - ph = (struct pppoehdr *) (ethhdr + 1); - if (ph->vertype != PPPOE_VERTYPE) { - PPPDEBUG(LOG_DEBUG, ("pppoe: unknown version/type packet: 0x%x\n", ph->vertype)); - goto done; - } - session = lwip_ntohs(ph->session); - plen = lwip_ntohs(ph->plen); - - if (plen > (pb->len - off)) { - PPPDEBUG(LOG_DEBUG, ("pppoe: packet content does not fit: data available = %d, packet size = %u\n", - pb->len - off, plen)); - goto done; - } - if(pb->tot_len == pb->len) { - u16_t framelen = off + plen; - if (framelen < pb->len) { - /* ignore trailing garbage */ - pb->tot_len = pb->len = framelen; - } - } - tag = 0; - len = 0; - sc = NULL; - while (off + sizeof(pt) <= pb->len) { - MEMCPY(&pt, (u8_t*)pb->payload + off, sizeof(pt)); - tag = lwip_ntohs(pt.tag); - len = lwip_ntohs(pt.len); - if (off + sizeof(pt) + len > pb->len) { - PPPDEBUG(LOG_DEBUG, ("pppoe: tag 0x%x len 0x%x is too long\n", tag, len)); - goto done; - } - switch (tag) { - case PPPOE_TAG_EOL: - goto breakbreak; - case PPPOE_TAG_SNAME: - break; /* ignored */ - case PPPOE_TAG_ACNAME: - break; /* ignored */ - case PPPOE_TAG_HUNIQUE: - if (sc != NULL) { - break; - } -#ifdef PPPOE_SERVER - hunique = (u8_t*)pb->payload + off + sizeof(pt); - hunique_len = len; -#endif - sc = pppoe_find_softc_by_hunique((u8_t*)pb->payload + off + sizeof(pt), len, netif); - break; - case PPPOE_TAG_ACCOOKIE: - if (ac_cookie == NULL) { - if (len > PPPOE_MAX_AC_COOKIE_LEN) { - PPPDEBUG(LOG_DEBUG, ("pppoe: AC cookie is too long: len = %d, max = %d\n", len, PPPOE_MAX_AC_COOKIE_LEN)); - goto done; - } - ac_cookie = (u8_t*)pb->payload + off + sizeof(pt); - ac_cookie_len = len; - } - break; -#if PPP_DEBUG - case PPPOE_TAG_SNAME_ERR: - err_msg = "SERVICE NAME ERROR"; - break; - case PPPOE_TAG_ACSYS_ERR: - err_msg = "AC SYSTEM ERROR"; - break; - case PPPOE_TAG_GENERIC_ERR: - err_msg = "GENERIC ERROR"; - break; -#endif /* PPP_DEBUG */ - default: - break; - } -#if PPP_DEBUG - if (err_msg != NULL) { - char error_tmp[PPPOE_ERRORSTRING_LEN]; - u16_t error_len = LWIP_MIN(len, sizeof(error_tmp)-1); - strncpy(error_tmp, (char*)pb->payload + off + sizeof(pt), error_len); - error_tmp[error_len] = '\0'; - if (sc) { - PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": %s: %s\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err_msg, error_tmp)); - } else { - PPPDEBUG(LOG_DEBUG, ("pppoe: %s: %s\n", err_msg, error_tmp)); - } - } -#endif /* PPP_DEBUG */ - off += sizeof(pt) + len; - } - -breakbreak:; - switch (ph->code) { - case PPPOE_CODE_PADI: -#ifdef PPPOE_SERVER - /* - * got service name, concentrator name, and/or host unique. - * ignore if we have no interfaces with IFF_PASSIVE|IFF_UP. - */ - if (LIST_EMPTY(&pppoe_softc_list)) { - goto done; - } - LIST_FOREACH(sc, &pppoe_softc_list, sc_list) { - if (!(sc->sc_sppp.pp_if.if_flags & IFF_UP)) { - continue; - } - if (!(sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE)) { - continue; - } - if (sc->sc_state == PPPOE_STATE_INITIAL) { - break; - } - } - if (sc == NULL) { - /* PPPDEBUG(LOG_DEBUG, ("pppoe: free passive interface is not found\n")); */ - goto done; - } - if (hunique) { - if (sc->sc_hunique) { - mem_free(sc->sc_hunique); - } - sc->sc_hunique = mem_malloc(hunique_len); - if (sc->sc_hunique == NULL) { - goto done; - } - sc->sc_hunique_len = hunique_len; - MEMCPY(sc->sc_hunique, hunique, hunique_len); - } - MEMCPY(&sc->sc_dest, eh->ether_shost, sizeof sc->sc_dest); - sc->sc_state = PPPOE_STATE_PADO_SENT; - pppoe_send_pado(sc); - break; -#endif /* PPPOE_SERVER */ - case PPPOE_CODE_PADR: -#ifdef PPPOE_SERVER - /* - * get sc from ac_cookie if IFF_PASSIVE - */ - if (ac_cookie == NULL) { - /* be quiet if there is not a single pppoe instance */ - PPPDEBUG(LOG_DEBUG, ("pppoe: received PADR but not includes ac_cookie\n")); - goto done; - } - sc = pppoe_find_softc_by_hunique(ac_cookie, ac_cookie_len, netif); - if (sc == NULL) { - /* be quiet if there is not a single pppoe instance */ - if (!LIST_EMPTY(&pppoe_softc_list)) { - PPPDEBUG(LOG_DEBUG, ("pppoe: received PADR but could not find request for it\n")); - } - goto done; - } - if (sc->sc_state != PPPOE_STATE_PADO_SENT) { - PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": received unexpected PADR\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); - goto done; - } - if (hunique) { - if (sc->sc_hunique) { - mem_free(sc->sc_hunique); - } - sc->sc_hunique = mem_malloc(hunique_len); - if (sc->sc_hunique == NULL) { - goto done; - } - sc->sc_hunique_len = hunique_len; - MEMCPY(sc->sc_hunique, hunique, hunique_len); - } - pppoe_send_pads(sc); - sc->sc_state = PPPOE_STATE_SESSION; - ppp_start(sc->pcb); /* notify upper layers */ - break; -#else - /* ignore, we are no access concentrator */ - goto done; -#endif /* PPPOE_SERVER */ - case PPPOE_CODE_PADO: - if (sc == NULL) { - /* be quiet if there is not a single pppoe instance */ - if (pppoe_softc_list != NULL) { - PPPDEBUG(LOG_DEBUG, ("pppoe: received PADO but could not find request for it\n")); - } - goto done; - } - if (sc->sc_state != PPPOE_STATE_PADI_SENT) { - PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": received unexpected PADO\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); - goto done; - } - if (ac_cookie) { - sc->sc_ac_cookie_len = ac_cookie_len; - MEMCPY(sc->sc_ac_cookie, ac_cookie, ac_cookie_len); - } - MEMCPY(&sc->sc_dest, ethhdr->src.addr, sizeof(sc->sc_dest.addr)); - sys_untimeout(pppoe_timeout, sc); - sc->sc_padr_retried = 0; - sc->sc_state = PPPOE_STATE_PADR_SENT; - if ((err = pppoe_send_padr(sc)) != 0) { - PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADR, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); - LWIP_UNUSED_ARG(err); /* if PPPDEBUG is disabled */ - } - sys_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc); - break; - case PPPOE_CODE_PADS: - if (sc == NULL) { - goto done; - } - sc->sc_session = session; - sys_untimeout(pppoe_timeout, sc); - PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": session 0x%x connected\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, session)); - sc->sc_state = PPPOE_STATE_SESSION; - ppp_start(sc->pcb); /* notify upper layers */ - break; - case PPPOE_CODE_PADT: - /* Don't disconnect here, we let the LCP Echo/Reply find the fact - * that PPP session is down. Asking the PPP stack to end the session - * require strict checking about the PPP phase to prevent endless - * disconnection loops. - */ -#if 0 /* UNUSED */ - if (sc == NULL) { /* PADT frames are rarely sent with a hunique tag, this is actually almost always true */ - goto done; - } - pppoe_clear_softc(sc, "received PADT"); -#endif /* UNUSED */ - break; - default: - if(sc) { - PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": unknown code (0x%"X16_F") session = 0x%"X16_F"\n", - sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, - (u16_t)ph->code, session)); - } else { - PPPDEBUG(LOG_DEBUG, ("pppoe: unknown code (0x%"X16_F") session = 0x%"X16_F"\n", (u16_t)ph->code, session)); - } - break; - } - -done: - pbuf_free(pb); - return; -} - -void -pppoe_data_input(struct netif *netif, struct pbuf *pb) -{ - u16_t session, plen; - struct pppoe_softc *sc; - struct pppoehdr *ph; -#ifdef PPPOE_TERM_UNKNOWN_SESSIONS - u8_t shost[ETHER_ADDR_LEN]; -#endif - -#ifdef PPPOE_TERM_UNKNOWN_SESSIONS - MEMCPY(shost, ((struct eth_hdr *)pb->payload)->src.addr, sizeof(shost)); -#endif - if (pbuf_remove_header(pb, sizeof(struct eth_hdr)) != 0) { - /* bail out */ - PPPDEBUG(LOG_ERR, ("pppoe_data_input: pbuf_remove_header failed\n")); - LINK_STATS_INC(link.lenerr); - goto drop; - } - - if (pb->len < sizeof(*ph)) { - PPPDEBUG(LOG_DEBUG, ("pppoe_data_input: could not get PPPoE header\n")); - goto drop; - } - ph = (struct pppoehdr *)pb->payload; - - if (ph->vertype != PPPOE_VERTYPE) { - PPPDEBUG(LOG_DEBUG, ("pppoe (data): unknown version/type packet: 0x%x\n", ph->vertype)); - goto drop; - } - if (ph->code != 0) { - goto drop; - } - - session = lwip_ntohs(ph->session); - sc = pppoe_find_softc_by_session(session, netif); - if (sc == NULL) { -#ifdef PPPOE_TERM_UNKNOWN_SESSIONS - PPPDEBUG(LOG_DEBUG, ("pppoe: input for unknown session 0x%x, sending PADT\n", session)); - pppoe_send_padt(netif, session, shost); -#endif - goto drop; - } - - plen = lwip_ntohs(ph->plen); - - if (pbuf_remove_header(pb, PPPOE_HEADERLEN) != 0) { - /* bail out */ - PPPDEBUG(LOG_ERR, ("pppoe_data_input: pbuf_remove_header PPPOE_HEADERLEN failed\n")); - LINK_STATS_INC(link.lenerr); - goto drop; - } - - PPPDEBUG(LOG_DEBUG, ("pppoe_data_input: %c%c%"U16_F": pkthdr.len=%d, pppoe.len=%d\n", - sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, - pb->len, plen)); - - if (pb->tot_len < plen) { - goto drop; - } - - /* Dispatch the packet thereby consuming it. */ - ppp_input(sc->pcb, pb); - return; - -drop: - pbuf_free(pb); -} - -static err_t -pppoe_output(struct pppoe_softc *sc, struct pbuf *pb) -{ - struct eth_hdr *ethhdr; - u16_t etype; - err_t res; - - /* make room for Ethernet header - should not fail */ - if (pbuf_add_header(pb, sizeof(struct eth_hdr)) != 0) { - /* bail out */ - PPPDEBUG(LOG_ERR, ("pppoe: %c%c%"U16_F": pppoe_output: could not allocate room for Ethernet header\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); - LINK_STATS_INC(link.lenerr); - pbuf_free(pb); - return ERR_BUF; - } - ethhdr = (struct eth_hdr *)pb->payload; - etype = sc->sc_state == PPPOE_STATE_SESSION ? ETHTYPE_PPPOE : ETHTYPE_PPPOEDISC; - ethhdr->type = lwip_htons(etype); - MEMCPY(ðhdr->dest.addr, &sc->sc_dest.addr, sizeof(ethhdr->dest.addr)); - MEMCPY(ðhdr->src.addr, &sc->sc_ethif->hwaddr, sizeof(ethhdr->src.addr)); - - PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F" (%x) state=%d, session=0x%x output -> %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F", len=%d\n", - sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, etype, - sc->sc_state, sc->sc_session, - sc->sc_dest.addr[0], sc->sc_dest.addr[1], sc->sc_dest.addr[2], sc->sc_dest.addr[3], sc->sc_dest.addr[4], sc->sc_dest.addr[5], - pb->tot_len)); - - res = sc->sc_ethif->linkoutput(sc->sc_ethif, pb); - - pbuf_free(pb); - - return res; -} - -static err_t -pppoe_send_padi(struct pppoe_softc *sc) -{ - struct pbuf *pb; - u8_t *p; - int len; -#ifdef PPPOE_TODO - int l1 = 0, l2 = 0; /* XXX: gcc */ -#endif /* PPPOE_TODO */ - - /* calculate length of frame (excluding ethernet header + pppoe header) */ - len = 2 + 2 + 2 + 2 + sizeof sc; /* service name tag is required, host unique is send too */ -#ifdef PPPOE_TODO - if (sc->sc_service_name != NULL) { - l1 = (int)strlen(sc->sc_service_name); - len += l1; - } - if (sc->sc_concentrator_name != NULL) { - l2 = (int)strlen(sc->sc_concentrator_name); - len += 2 + 2 + l2; - } -#endif /* PPPOE_TODO */ - LWIP_ASSERT("sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff", - sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff); - - /* allocate a buffer */ - pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HEADERLEN + len), PBUF_RAM); - if (!pb) { - return ERR_MEM; - } - LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); - - p = (u8_t*)pb->payload; - /* fill in pkt */ - PPPOE_ADD_HEADER(p, PPPOE_CODE_PADI, 0, (u16_t)len); - PPPOE_ADD_16(p, PPPOE_TAG_SNAME); -#ifdef PPPOE_TODO - if (sc->sc_service_name != NULL) { - PPPOE_ADD_16(p, l1); - MEMCPY(p, sc->sc_service_name, l1); - p += l1; - } else -#endif /* PPPOE_TODO */ - { - PPPOE_ADD_16(p, 0); - } -#ifdef PPPOE_TODO - if (sc->sc_concentrator_name != NULL) { - PPPOE_ADD_16(p, PPPOE_TAG_ACNAME); - PPPOE_ADD_16(p, l2); - MEMCPY(p, sc->sc_concentrator_name, l2); - p += l2; - } -#endif /* PPPOE_TODO */ - PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); - PPPOE_ADD_16(p, sizeof(sc)); - MEMCPY(p, &sc, sizeof sc); - - /* send pkt */ - return pppoe_output(sc, pb); -} - -static void -pppoe_timeout(void *arg) -{ - u32_t retry_wait; - int err; - struct pppoe_softc *sc = (struct pppoe_softc*)arg; - - PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": timeout\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); - - switch (sc->sc_state) { - case PPPOE_STATE_PADI_SENT: - /* - * We have two basic ways of retrying: - * - Quick retry mode: try a few times in short sequence - * - Slow retry mode: we already had a connection successfully - * established and will try infinitely (without user - * intervention) - * We only enter slow retry mode if IFF_LINK1 (aka autodial) - * is not set. - */ - if (sc->sc_padi_retried < 0xff) { - sc->sc_padi_retried++; - } - if (!sc->pcb->settings.persist && sc->sc_padi_retried >= PPPOE_DISC_MAXPADI) { -#if 0 - if ((sc->sc_sppp.pp_if.if_flags & IFF_LINK1) == 0) { - /* slow retry mode */ - retry_wait = PPPOE_SLOW_RETRY; - } else -#endif - { - pppoe_abort_connect(sc); - return; - } - } - /* initialize for quick retry mode */ - retry_wait = LWIP_MIN(PPPOE_DISC_TIMEOUT * sc->sc_padi_retried, PPPOE_SLOW_RETRY); - if ((err = pppoe_send_padi(sc)) != 0) { - sc->sc_padi_retried--; - PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to transmit PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); - LWIP_UNUSED_ARG(err); /* if PPPDEBUG is disabled */ - } - sys_timeout(retry_wait, pppoe_timeout, sc); - break; - - case PPPOE_STATE_PADR_SENT: - sc->sc_padr_retried++; - if (sc->sc_padr_retried >= PPPOE_DISC_MAXPADR) { - MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); - sc->sc_state = PPPOE_STATE_PADI_SENT; - sc->sc_padr_retried = 0; - if ((err = pppoe_send_padi(sc)) != 0) { - PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); - LWIP_UNUSED_ARG(err); /* if PPPDEBUG is disabled */ - } - sys_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried), pppoe_timeout, sc); - return; - } - if ((err = pppoe_send_padr(sc)) != 0) { - sc->sc_padr_retried--; - PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADR, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); - LWIP_UNUSED_ARG(err); /* if PPPDEBUG is disabled */ - } - sys_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc); - break; - default: - return; /* all done, work in peace */ - } -} - -/* Start a connection (i.e. initiate discovery phase) */ -static void -pppoe_connect(ppp_pcb *ppp, void *ctx) -{ - err_t err; - struct pppoe_softc *sc = (struct pppoe_softc *)ctx; - lcp_options *lcp_wo; - lcp_options *lcp_ao; -#if PPP_IPV4_SUPPORT && VJ_SUPPORT - ipcp_options *ipcp_wo; - ipcp_options *ipcp_ao; -#endif /* PPP_IPV4_SUPPORT && VJ_SUPPORT */ - - sc->sc_session = 0; - sc->sc_ac_cookie_len = 0; - sc->sc_padi_retried = 0; - sc->sc_padr_retried = 0; - /* changed to real address later */ - MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); -#ifdef PPPOE_SERVER - /* wait PADI if IFF_PASSIVE */ - if ((sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE)) { - return 0; - } -#endif - - lcp_wo = &ppp->lcp_wantoptions; - lcp_wo->mru = sc->sc_ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ - lcp_wo->neg_asyncmap = 0; - lcp_wo->neg_pcompression = 0; - lcp_wo->neg_accompression = 0; - lcp_wo->passive = 0; - lcp_wo->silent = 0; - - lcp_ao = &ppp->lcp_allowoptions; - lcp_ao->mru = sc->sc_ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ - lcp_ao->neg_asyncmap = 0; - lcp_ao->neg_pcompression = 0; - lcp_ao->neg_accompression = 0; - -#if PPP_IPV4_SUPPORT && VJ_SUPPORT - ipcp_wo = &ppp->ipcp_wantoptions; - ipcp_wo->neg_vj = 0; - ipcp_wo->old_vj = 0; - - ipcp_ao = &ppp->ipcp_allowoptions; - ipcp_ao->neg_vj = 0; - ipcp_ao->old_vj = 0; -#endif /* PPP_IPV4_SUPPORT && VJ_SUPPORT */ - - /* save state, in case we fail to send PADI */ - sc->sc_state = PPPOE_STATE_PADI_SENT; - if ((err = pppoe_send_padi(sc)) != 0) { - PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); - } - sys_timeout(PPPOE_DISC_TIMEOUT, pppoe_timeout, sc); -} - -/* disconnect */ -static void -pppoe_disconnect(ppp_pcb *ppp, void *ctx) -{ - struct pppoe_softc *sc = (struct pppoe_softc *)ctx; - - PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": disconnecting\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); - if (sc->sc_state == PPPOE_STATE_SESSION) { - pppoe_send_padt(sc->sc_ethif, sc->sc_session, (const u8_t *)&sc->sc_dest); - } - - /* stop any timer, disconnect can be called while initiating is in progress */ - sys_untimeout(pppoe_timeout, sc); - sc->sc_state = PPPOE_STATE_INITIAL; -#ifdef PPPOE_SERVER - if (sc->sc_hunique) { - mem_free(sc->sc_hunique); - sc->sc_hunique = NULL; /* probably not necessary, if state is initial we shouldn't have to access hunique anyway */ - } - sc->sc_hunique_len = 0; /* probably not necessary, if state is initial we shouldn't have to access hunique anyway */ -#endif - ppp_link_end(ppp); /* notify upper layers */ - return; -} - -/* Connection attempt aborted */ -static void -pppoe_abort_connect(struct pppoe_softc *sc) -{ - PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": could not establish connection\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); - sc->sc_state = PPPOE_STATE_INITIAL; - ppp_link_failed(sc->pcb); /* notify upper layers */ -} - -/* Send a PADR packet */ -static err_t -pppoe_send_padr(struct pppoe_softc *sc) -{ - struct pbuf *pb; - u8_t *p; - size_t len; -#ifdef PPPOE_TODO - size_t l1 = 0; /* XXX: gcc */ -#endif /* PPPOE_TODO */ - - len = 2 + 2 + 2 + 2 + sizeof(sc); /* service name, host unique */ -#ifdef PPPOE_TODO - if (sc->sc_service_name != NULL) { /* service name tag maybe empty */ - l1 = strlen(sc->sc_service_name); - len += l1; - } -#endif /* PPPOE_TODO */ - if (sc->sc_ac_cookie_len > 0) { - len += 2 + 2 + sc->sc_ac_cookie_len; /* AC cookie */ - } - LWIP_ASSERT("sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff", - sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff); - pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HEADERLEN + len), PBUF_RAM); - if (!pb) { - return ERR_MEM; - } - LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); - p = (u8_t*)pb->payload; - PPPOE_ADD_HEADER(p, PPPOE_CODE_PADR, 0, len); - PPPOE_ADD_16(p, PPPOE_TAG_SNAME); -#ifdef PPPOE_TODO - if (sc->sc_service_name != NULL) { - PPPOE_ADD_16(p, l1); - MEMCPY(p, sc->sc_service_name, l1); - p += l1; - } else -#endif /* PPPOE_TODO */ - { - PPPOE_ADD_16(p, 0); - } - if (sc->sc_ac_cookie_len > 0) { - PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE); - PPPOE_ADD_16(p, sc->sc_ac_cookie_len); - MEMCPY(p, sc->sc_ac_cookie, sc->sc_ac_cookie_len); - p += sc->sc_ac_cookie_len; - } - PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); - PPPOE_ADD_16(p, sizeof(sc)); - MEMCPY(p, &sc, sizeof sc); - - return pppoe_output(sc, pb); -} - -/* send a PADT packet */ -static err_t -pppoe_send_padt(struct netif *outgoing_if, u_int session, const u8_t *dest) -{ - struct pbuf *pb; - struct eth_hdr *ethhdr; - err_t res; - u8_t *p; - - pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HEADERLEN), PBUF_RAM); - if (!pb) { - return ERR_MEM; - } - LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); - - if (pbuf_add_header(pb, sizeof(struct eth_hdr))) { - PPPDEBUG(LOG_ERR, ("pppoe: pppoe_send_padt: could not allocate room for PPPoE header\n")); - LINK_STATS_INC(link.lenerr); - pbuf_free(pb); - return ERR_BUF; - } - ethhdr = (struct eth_hdr *)pb->payload; - ethhdr->type = PP_HTONS(ETHTYPE_PPPOEDISC); - MEMCPY(ðhdr->dest.addr, dest, sizeof(ethhdr->dest.addr)); - MEMCPY(ðhdr->src.addr, &outgoing_if->hwaddr, sizeof(ethhdr->src.addr)); - - p = (u8_t*)(ethhdr + 1); - PPPOE_ADD_HEADER(p, PPPOE_CODE_PADT, session, 0); - - res = outgoing_if->linkoutput(outgoing_if, pb); - - pbuf_free(pb); - - return res; -} - -#ifdef PPPOE_SERVER -static err_t -pppoe_send_pado(struct pppoe_softc *sc) -{ - struct pbuf *pb; - u8_t *p; - size_t len; - - /* calc length */ - len = 0; - /* include ac_cookie */ - len += 2 + 2 + sizeof(sc); - /* include hunique */ - len += 2 + 2 + sc->sc_hunique_len; - pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HEADERLEN + len), PBUF_RAM); - if (!pb) { - return ERR_MEM; - } - LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); - p = (u8_t*)pb->payload; - PPPOE_ADD_HEADER(p, PPPOE_CODE_PADO, 0, len); - PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE); - PPPOE_ADD_16(p, sizeof(sc)); - MEMCPY(p, &sc, sizeof(sc)); - p += sizeof(sc); - PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); - PPPOE_ADD_16(p, sc->sc_hunique_len); - MEMCPY(p, sc->sc_hunique, sc->sc_hunique_len); - return pppoe_output(sc, pb); -} - -static err_t -pppoe_send_pads(struct pppoe_softc *sc) -{ - struct pbuf *pb; - u8_t *p; - size_t len, l1 = 0; /* XXX: gcc */ - - sc->sc_session = mono_time.tv_sec % 0xff + 1; - /* calc length */ - len = 0; - /* include hunique */ - len += 2 + 2 + 2 + 2 + sc->sc_hunique_len; /* service name, host unique*/ - if (sc->sc_service_name != NULL) { /* service name tag maybe empty */ - l1 = strlen(sc->sc_service_name); - len += l1; - } - pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HEADERLEN + len), PBUF_RAM); - if (!pb) { - return ERR_MEM; - } - LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); - p = (u8_t*)pb->payload; - PPPOE_ADD_HEADER(p, PPPOE_CODE_PADS, sc->sc_session, len); - PPPOE_ADD_16(p, PPPOE_TAG_SNAME); - if (sc->sc_service_name != NULL) { - PPPOE_ADD_16(p, l1); - MEMCPY(p, sc->sc_service_name, l1); - p += l1; - } else { - PPPOE_ADD_16(p, 0); - } - PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); - PPPOE_ADD_16(p, sc->sc_hunique_len); - MEMCPY(p, sc->sc_hunique, sc->sc_hunique_len); - return pppoe_output(sc, pb); -} -#endif - -static err_t -pppoe_xmit(struct pppoe_softc *sc, struct pbuf *pb) -{ - u8_t *p; - size_t len; - - len = pb->tot_len; - - /* make room for PPPoE header - should not fail */ - if (pbuf_add_header(pb, PPPOE_HEADERLEN) != 0) { - /* bail out */ - PPPDEBUG(LOG_ERR, ("pppoe: %c%c%"U16_F": pppoe_xmit: could not allocate room for PPPoE header\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); - LINK_STATS_INC(link.lenerr); - pbuf_free(pb); - return ERR_BUF; - } - - p = (u8_t*)pb->payload; - PPPOE_ADD_HEADER(p, 0, sc->sc_session, len); - - return pppoe_output(sc, pb); -} - -#if 0 /*def PFIL_HOOKS*/ -static int -pppoe_ifattach_hook(void *arg, struct pbuf **mp, struct netif *ifp, int dir) -{ - struct pppoe_softc *sc; - int s; - - if (mp != (struct pbuf **)PFIL_IFNET_DETACH) { - return 0; - } - - LIST_FOREACH(sc, &pppoe_softc_list, sc_list) { - if (sc->sc_ethif != ifp) { - continue; - } - if (sc->sc_sppp.pp_if.if_flags & IFF_UP) { - sc->sc_sppp.pp_if.if_flags &= ~(IFF_UP|IFF_RUNNING); - PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": ethernet interface detached, going down\n", - sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); - } - sc->sc_ethif = NULL; - pppoe_clear_softc(sc, "ethernet interface detached"); - } - - return 0; -} -#endif - -#if 0 /* UNUSED */ -static void -pppoe_clear_softc(struct pppoe_softc *sc, const char *message) -{ - LWIP_UNUSED_ARG(message); - - /* stop timer */ - sys_untimeout(pppoe_timeout, sc); - PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": session 0x%x terminated, %s\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, sc->sc_session, message)); - sc->sc_state = PPPOE_STATE_INITIAL; - ppp_link_end(sc->pcb); /* notify upper layers - /!\ dangerous /!\ - see pppoe_disc_input() */ -} -#endif /* UNUSED */ -#endif /* PPP_SUPPORT && PPPOE_SUPPORT */ diff --git a/third-party/lwip-2.1.2/netif/ppp/pppol2tp.c b/third-party/lwip-2.1.2/netif/ppp/pppol2tp.c deleted file mode 100644 index 4c4557fc..00000000 --- a/third-party/lwip-2.1.2/netif/ppp/pppol2tp.c +++ /dev/null @@ -1,1159 +0,0 @@ -/** - * @file - * Network Point to Point Protocol over Layer 2 Tunneling Protocol program file. - * - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -/* - * L2TP Support status: - * - * Supported: - * - L2TPv2 (PPP over L2TP, a.k.a. UDP tunnels) - * - LAC - * - * Not supported: - * - LNS (require PPP server support) - * - L2TPv3 ethernet pseudowires - * - L2TPv3 VLAN pseudowire - * - L2TPv3 PPP pseudowires - * - L2TPv3 IP encapsulation - * - L2TPv3 IP pseudowire - * - L2TP tunnel switching - http://tools.ietf.org/html/draft-ietf-l2tpext-tunnel-switching-08 - * - Multiple tunnels per UDP socket, as well as multiple sessions per tunnel - * - Hidden AVPs - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && PPPOL2TP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/err.h" -#include "lwip/memp.h" -#include "lwip/netif.h" -#include "lwip/udp.h" -#include "lwip/snmp.h" - -#include "netif/ppp/ppp_impl.h" -#include "netif/ppp/lcp.h" -#include "netif/ppp/ipcp.h" -#include "netif/ppp/pppol2tp.h" -#include "netif/ppp/pppcrypt.h" -#include "netif/ppp/magic.h" - -/* Memory pool */ -LWIP_MEMPOOL_DECLARE(PPPOL2TP_PCB, MEMP_NUM_PPPOL2TP_INTERFACES, sizeof(pppol2tp_pcb), "PPPOL2TP_PCB") - -/* callbacks called from PPP core */ -static err_t pppol2tp_write(ppp_pcb *ppp, void *ctx, struct pbuf *p); -static err_t pppol2tp_netif_output(ppp_pcb *ppp, void *ctx, struct pbuf *p, u_short protocol); -static err_t pppol2tp_destroy(ppp_pcb *ppp, void *ctx); /* Destroy a L2TP control block */ -static void pppol2tp_connect(ppp_pcb *ppp, void *ctx); /* Be a LAC, connect to a LNS. */ -static void pppol2tp_disconnect(ppp_pcb *ppp, void *ctx); /* Disconnect */ - - /* Prototypes for procedures local to this file. */ -static void pppol2tp_input(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port); -static void pppol2tp_dispatch_control_packet(pppol2tp_pcb *l2tp, u16_t port, struct pbuf *p, u16_t ns, u16_t nr); -static void pppol2tp_timeout(void *arg); -static void pppol2tp_abort_connect(pppol2tp_pcb *l2tp); -static err_t pppol2tp_send_sccrq(pppol2tp_pcb *l2tp); -static err_t pppol2tp_send_scccn(pppol2tp_pcb *l2tp, u16_t ns); -static err_t pppol2tp_send_icrq(pppol2tp_pcb *l2tp, u16_t ns); -static err_t pppol2tp_send_iccn(pppol2tp_pcb *l2tp, u16_t ns); -static err_t pppol2tp_send_zlb(pppol2tp_pcb *l2tp, u16_t ns, u16_t nr); -static err_t pppol2tp_send_stopccn(pppol2tp_pcb *l2tp, u16_t ns); -static err_t pppol2tp_xmit(pppol2tp_pcb *l2tp, struct pbuf *pb); -static err_t pppol2tp_udp_send(pppol2tp_pcb *l2tp, struct pbuf *pb); - -/* Callbacks structure for PPP core */ -static const struct link_callbacks pppol2tp_callbacks = { - pppol2tp_connect, -#if PPP_SERVER - NULL, -#endif /* PPP_SERVER */ - pppol2tp_disconnect, - pppol2tp_destroy, - pppol2tp_write, - pppol2tp_netif_output, - NULL, - NULL -}; - - -/* Create a new L2TP session. */ -ppp_pcb *pppol2tp_create(struct netif *pppif, - struct netif *netif, const ip_addr_t *ipaddr, u16_t port, - const u8_t *secret, u8_t secret_len, - ppp_link_status_cb_fn link_status_cb, void *ctx_cb) { - ppp_pcb *ppp; - pppol2tp_pcb *l2tp; - struct udp_pcb *udp; -#if !PPPOL2TP_AUTH_SUPPORT - LWIP_UNUSED_ARG(secret); - LWIP_UNUSED_ARG(secret_len); -#endif /* !PPPOL2TP_AUTH_SUPPORT */ - - if (ipaddr == NULL) { - goto ipaddr_check_failed; - } - - l2tp = (pppol2tp_pcb *)LWIP_MEMPOOL_ALLOC(PPPOL2TP_PCB); - if (l2tp == NULL) { - goto memp_malloc_l2tp_failed; - } - - udp = udp_new_ip_type(IP_GET_TYPE(ipaddr)); - if (udp == NULL) { - goto udp_new_failed; - } - udp_recv(udp, pppol2tp_input, l2tp); - - ppp = ppp_new(pppif, &pppol2tp_callbacks, l2tp, link_status_cb, ctx_cb); - if (ppp == NULL) { - goto ppp_new_failed; - } - - memset(l2tp, 0, sizeof(pppol2tp_pcb)); - l2tp->phase = PPPOL2TP_STATE_INITIAL; - l2tp->ppp = ppp; - l2tp->udp = udp; - l2tp->netif = netif; - ip_addr_copy(l2tp->remote_ip, *ipaddr); - l2tp->remote_port = port; -#if PPPOL2TP_AUTH_SUPPORT - l2tp->secret = secret; - l2tp->secret_len = secret_len; -#endif /* PPPOL2TP_AUTH_SUPPORT */ - - return ppp; - -ppp_new_failed: - udp_remove(udp); -udp_new_failed: - LWIP_MEMPOOL_FREE(PPPOL2TP_PCB, l2tp); -memp_malloc_l2tp_failed: -ipaddr_check_failed: - return NULL; -} - -/* Called by PPP core */ -static err_t pppol2tp_write(ppp_pcb *ppp, void *ctx, struct pbuf *p) { - pppol2tp_pcb *l2tp = (pppol2tp_pcb *)ctx; - struct pbuf *ph; /* UDP + L2TP header */ - err_t ret; -#if MIB2_STATS - u16_t tot_len; -#else /* MIB2_STATS */ - LWIP_UNUSED_ARG(ppp); -#endif /* MIB2_STATS */ - - ph = pbuf_alloc(PBUF_TRANSPORT, (u16_t)(PPPOL2TP_OUTPUT_DATA_HEADER_LEN), PBUF_RAM); - if(!ph) { - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.proterr); - MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards); - pbuf_free(p); - return ERR_MEM; - } - - pbuf_remove_header(ph, PPPOL2TP_OUTPUT_DATA_HEADER_LEN); /* hide L2TP header */ - pbuf_cat(ph, p); -#if MIB2_STATS - tot_len = ph->tot_len; -#endif /* MIB2_STATS */ - - ret = pppol2tp_xmit(l2tp, ph); - if (ret != ERR_OK) { - LINK_STATS_INC(link.err); - MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards); - return ret; - } - - MIB2_STATS_NETIF_ADD(ppp->netif, ifoutoctets, (u16_t)tot_len); - MIB2_STATS_NETIF_INC(ppp->netif, ifoutucastpkts); - LINK_STATS_INC(link.xmit); - return ERR_OK; -} - -/* Called by PPP core */ -static err_t pppol2tp_netif_output(ppp_pcb *ppp, void *ctx, struct pbuf *p, u_short protocol) { - pppol2tp_pcb *l2tp = (pppol2tp_pcb *)ctx; - struct pbuf *pb; - u8_t *pl; - err_t err; -#if MIB2_STATS - u16_t tot_len; -#else /* MIB2_STATS */ - LWIP_UNUSED_ARG(ppp); -#endif /* MIB2_STATS */ - - /* @todo: try to use pbuf_header() here! */ - pb = pbuf_alloc(PBUF_TRANSPORT, PPPOL2TP_OUTPUT_DATA_HEADER_LEN + sizeof(protocol), PBUF_RAM); - if(!pb) { - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.proterr); - MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards); - return ERR_MEM; - } - - pbuf_remove_header(pb, PPPOL2TP_OUTPUT_DATA_HEADER_LEN); - - pl = (u8_t*)pb->payload; - PUTSHORT(protocol, pl); - - pbuf_chain(pb, p); -#if MIB2_STATS - tot_len = pb->tot_len; -#endif /* MIB2_STATS */ - - if( (err = pppol2tp_xmit(l2tp, pb)) != ERR_OK) { - LINK_STATS_INC(link.err); - MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards); - return err; - } - - MIB2_STATS_NETIF_ADD(ppp->netif, ifoutoctets, tot_len); - MIB2_STATS_NETIF_INC(ppp->netif, ifoutucastpkts); - LINK_STATS_INC(link.xmit); - return ERR_OK; -} - -/* Destroy a L2TP control block */ -static err_t pppol2tp_destroy(ppp_pcb *ppp, void *ctx) { - pppol2tp_pcb *l2tp = (pppol2tp_pcb *)ctx; - LWIP_UNUSED_ARG(ppp); - - sys_untimeout(pppol2tp_timeout, l2tp); - udp_remove(l2tp->udp); - LWIP_MEMPOOL_FREE(PPPOL2TP_PCB, l2tp); - return ERR_OK; -} - -/* Be a LAC, connect to a LNS. */ -static void pppol2tp_connect(ppp_pcb *ppp, void *ctx) { - err_t err; - pppol2tp_pcb *l2tp = (pppol2tp_pcb *)ctx; - lcp_options *lcp_wo; - lcp_options *lcp_ao; -#if PPP_IPV4_SUPPORT && VJ_SUPPORT - ipcp_options *ipcp_wo; - ipcp_options *ipcp_ao; -#endif /* PPP_IPV4_SUPPORT && VJ_SUPPORT */ - - l2tp->tunnel_port = l2tp->remote_port; - l2tp->our_ns = 0; - l2tp->peer_nr = 0; - l2tp->peer_ns = 0; - l2tp->source_tunnel_id = 0; - l2tp->remote_tunnel_id = 0; - l2tp->source_session_id = 0; - l2tp->remote_session_id = 0; - /* l2tp->*_retried are cleared when used */ - - lcp_wo = &ppp->lcp_wantoptions; - lcp_wo->mru = PPPOL2TP_DEFMRU; - lcp_wo->neg_asyncmap = 0; - lcp_wo->neg_pcompression = 0; - lcp_wo->neg_accompression = 0; - lcp_wo->passive = 0; - lcp_wo->silent = 0; - - lcp_ao = &ppp->lcp_allowoptions; - lcp_ao->mru = PPPOL2TP_DEFMRU; - lcp_ao->neg_asyncmap = 0; - lcp_ao->neg_pcompression = 0; - lcp_ao->neg_accompression = 0; - -#if PPP_IPV4_SUPPORT && VJ_SUPPORT - ipcp_wo = &ppp->ipcp_wantoptions; - ipcp_wo->neg_vj = 0; - ipcp_wo->old_vj = 0; - - ipcp_ao = &ppp->ipcp_allowoptions; - ipcp_ao->neg_vj = 0; - ipcp_ao->old_vj = 0; -#endif /* PPP_IPV4_SUPPORT && VJ_SUPPORT */ - - /* Listen to a random source port, we need to do that instead of using udp_connect() - * because the L2TP LNS might answer with its own random source port (!= 1701) - */ -#if LWIP_IPV6 - if (IP_IS_V6_VAL(l2tp->udp->local_ip)) { - udp_bind(l2tp->udp, IP6_ADDR_ANY, 0); - } else -#endif /* LWIP_IPV6 */ - udp_bind(l2tp->udp, IP_ADDR_ANY, 0); - -#if PPPOL2TP_AUTH_SUPPORT - /* Generate random vector */ - if (l2tp->secret != NULL) { - magic_random_bytes(l2tp->secret_rv, sizeof(l2tp->secret_rv)); - } -#endif /* PPPOL2TP_AUTH_SUPPORT */ - - do { - l2tp->remote_tunnel_id = magic(); - } while(l2tp->remote_tunnel_id == 0); - /* save state, in case we fail to send SCCRQ */ - l2tp->sccrq_retried = 0; - l2tp->phase = PPPOL2TP_STATE_SCCRQ_SENT; - if ((err = pppol2tp_send_sccrq(l2tp)) != 0) { - PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send SCCRQ, error=%d\n", err)); - } - sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp); -} - -/* Disconnect */ -static void pppol2tp_disconnect(ppp_pcb *ppp, void *ctx) { - pppol2tp_pcb *l2tp = (pppol2tp_pcb *)ctx; - - l2tp->our_ns++; - pppol2tp_send_stopccn(l2tp, l2tp->our_ns); - - /* stop any timer, disconnect can be called while initiating is in progress */ - sys_untimeout(pppol2tp_timeout, l2tp); - l2tp->phase = PPPOL2TP_STATE_INITIAL; - ppp_link_end(ppp); /* notify upper layers */ -} - -/* UDP Callback for incoming IPv4 L2TP frames */ -static void pppol2tp_input(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) { - pppol2tp_pcb *l2tp = (pppol2tp_pcb*)arg; - u16_t hflags, hlen, len=0, tunnel_id=0, session_id=0, ns=0, nr=0, offset=0; - u8_t *inp; - LWIP_UNUSED_ARG(pcb); - - /* we can't unbound a UDP pcb, thus we can still receive UDP frames after the link is closed */ - if (l2tp->phase < PPPOL2TP_STATE_SCCRQ_SENT) { - goto free_and_return; - } - - if (!ip_addr_cmp(&l2tp->remote_ip, addr)) { - goto free_and_return; - } - - /* discard packet if port mismatch, but only if we received a SCCRP */ - if (l2tp->phase > PPPOL2TP_STATE_SCCRQ_SENT && l2tp->tunnel_port != port) { - goto free_and_return; - } - - /* printf("-----------\nL2TP INPUT, %d\n", p->len); */ - - /* L2TP header */ - if (p->len < sizeof(hflags) + sizeof(tunnel_id) + sizeof(session_id) ) { - goto packet_too_short; - } - - inp = (u8_t*)p->payload; - GETSHORT(hflags, inp); - - if (hflags & PPPOL2TP_HEADERFLAG_CONTROL) { - /* check mandatory flags for a control packet */ - if ( (hflags & PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY) != PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY ) { - PPPDEBUG(LOG_DEBUG, ("pppol2tp: mandatory header flags for control packet not set\n")); - goto free_and_return; - } - /* check forbidden flags for a control packet */ - if (hflags & PPPOL2TP_HEADERFLAG_CONTROL_FORBIDDEN) { - PPPDEBUG(LOG_DEBUG, ("pppol2tp: forbidden header flags for control packet found\n")); - goto free_and_return; - } - } else { - /* check mandatory flags for a data packet */ - if ( (hflags & PPPOL2TP_HEADERFLAG_DATA_MANDATORY) != PPPOL2TP_HEADERFLAG_DATA_MANDATORY) { - PPPDEBUG(LOG_DEBUG, ("pppol2tp: mandatory header flags for data packet not set\n")); - goto free_and_return; - } - } - - /* Expected header size */ - hlen = sizeof(hflags) + sizeof(tunnel_id) + sizeof(session_id); - if (hflags & PPPOL2TP_HEADERFLAG_LENGTH) { - hlen += sizeof(len); - } - if (hflags & PPPOL2TP_HEADERFLAG_SEQUENCE) { - hlen += sizeof(ns) + sizeof(nr); - } - if (hflags & PPPOL2TP_HEADERFLAG_OFFSET) { - hlen += sizeof(offset); - } - if (p->len < hlen) { - goto packet_too_short; - } - - if (hflags & PPPOL2TP_HEADERFLAG_LENGTH) { - GETSHORT(len, inp); - if (p->len < len || len < hlen) { - goto packet_too_short; - } - } - GETSHORT(tunnel_id, inp); - GETSHORT(session_id, inp); - if (hflags & PPPOL2TP_HEADERFLAG_SEQUENCE) { - GETSHORT(ns, inp); - GETSHORT(nr, inp); - } - if (hflags & PPPOL2TP_HEADERFLAG_OFFSET) { - GETSHORT(offset, inp) - if (offset > 4096) { /* don't be fooled with large offset which might overflow hlen */ - PPPDEBUG(LOG_DEBUG, ("pppol2tp: strange packet received, offset=%d\n", offset)); - goto free_and_return; - } - hlen += offset; - if (p->len < hlen) { - goto packet_too_short; - } - INCPTR(offset, inp); - } - - /* printf("HLEN = %d\n", hlen); */ - - /* skip L2TP header */ - if (pbuf_remove_header(p, hlen) != 0) { - goto free_and_return; - } - - /* printf("LEN=%d, TUNNEL_ID=%d, SESSION_ID=%d, NS=%d, NR=%d, OFFSET=%d\n", len, tunnel_id, session_id, ns, nr, offset); */ - PPPDEBUG(LOG_DEBUG, ("pppol2tp: input packet, len=%"U16_F", tunnel=%"U16_F", session=%"U16_F", ns=%"U16_F", nr=%"U16_F"\n", - len, tunnel_id, session_id, ns, nr)); - - /* Control packet */ - if (hflags & PPPOL2TP_HEADERFLAG_CONTROL) { - pppol2tp_dispatch_control_packet(l2tp, port, p, ns, nr); - goto free_and_return; - } - - /* Data packet */ - if(l2tp->phase != PPPOL2TP_STATE_DATA) { - goto free_and_return; - } - if(tunnel_id != l2tp->remote_tunnel_id) { - PPPDEBUG(LOG_DEBUG, ("pppol2tp: tunnel ID mismatch, assigned=%d, received=%d\n", l2tp->remote_tunnel_id, tunnel_id)); - goto free_and_return; - } - if(session_id != l2tp->remote_session_id) { - PPPDEBUG(LOG_DEBUG, ("pppol2tp: session ID mismatch, assigned=%d, received=%d\n", l2tp->remote_session_id, session_id)); - goto free_and_return; - } - /* - * skip address & flags if necessary - * - * RFC 2661 does not specify whether the PPP frame in the L2TP payload should - * have a HDLC header or not. We handle both cases for compatibility. - */ - if (p->len >= 2) { - GETSHORT(hflags, inp); - if (hflags == 0xff03) { - pbuf_remove_header(p, 2); - } - } - /* Dispatch the packet thereby consuming it. */ - ppp_input(l2tp->ppp, p); - return; - -packet_too_short: - PPPDEBUG(LOG_DEBUG, ("pppol2tp: packet too short: %d\n", p->len)); -free_and_return: - pbuf_free(p); -} - -/* L2TP Control packet entry point */ -static void pppol2tp_dispatch_control_packet(pppol2tp_pcb *l2tp, u16_t port, struct pbuf *p, u16_t ns, u16_t nr) { - u8_t *inp; - u16_t avplen, avpflags, vendorid, attributetype, messagetype=0; - err_t err; -#if PPPOL2TP_AUTH_SUPPORT - lwip_md5_context md5_ctx; - u8_t md5_hash[16]; - u8_t challenge_id = 0; -#endif /* PPPOL2TP_AUTH_SUPPORT */ - - /* printf("L2TP CTRL INPUT, ns=%d, nr=%d, len=%d\n", ns, nr, p->len); */ - - /* Drop unexpected packet */ - if (ns != l2tp->peer_ns) { - PPPDEBUG(LOG_DEBUG, ("pppol2tp: drop unexpected packet: received NS=%d, expected NS=%d\n", ns, l2tp->peer_ns)); - /* - * In order to ensure that all messages are acknowledged properly - * (particularly in the case of a lost ZLB ACK message), receipt - * of duplicate messages MUST be acknowledged. - * - * In this very special case we Ack a packet we previously received. - * Therefore our NS is the NR we just received. And our NR is the - * NS we just received plus one. - */ - if ((s16_t)(ns - l2tp->peer_ns) < 0) { - pppol2tp_send_zlb(l2tp, nr, ns+1); - } - return; - } - - l2tp->peer_nr = nr; - - /* Handle the special case of the ICCN acknowledge */ - if (l2tp->phase == PPPOL2TP_STATE_ICCN_SENT && (s16_t)(l2tp->peer_nr - l2tp->our_ns) > 0) { - l2tp->phase = PPPOL2TP_STATE_DATA; - sys_untimeout(pppol2tp_timeout, l2tp); - ppp_start(l2tp->ppp); /* notify upper layers */ - } - - /* ZLB packets */ - if (p->tot_len == 0) { - return; - } - /* A ZLB packet does not consume a NS slot thus we don't record the NS value for ZLB packets */ - l2tp->peer_ns = ns+1; - - p = pbuf_coalesce(p, PBUF_RAW); - inp = (u8_t*)p->payload; - /* Decode AVPs */ - while (p->len > 0) { - if (p->len < sizeof(avpflags) + sizeof(vendorid) + sizeof(attributetype) ) { - goto packet_too_short; - } - GETSHORT(avpflags, inp); - avplen = avpflags & PPPOL2TP_AVPHEADERFLAG_LENGTHMASK; - /* printf("AVPLEN = %d\n", avplen); */ - if (p->len < avplen || avplen < sizeof(avpflags) + sizeof(vendorid) + sizeof(attributetype)) { - goto packet_too_short; - } - GETSHORT(vendorid, inp); - GETSHORT(attributetype, inp); - avplen -= sizeof(avpflags) + sizeof(vendorid) + sizeof(attributetype); - - /* Message type must be the first AVP */ - if (messagetype == 0) { - if (attributetype != 0 || vendorid != 0 || avplen != sizeof(messagetype) ) { - PPPDEBUG(LOG_DEBUG, ("pppol2tp: message type must be the first AVP\n")); - return; - } - GETSHORT(messagetype, inp); - /* printf("Message type = %d\n", messagetype); */ - switch(messagetype) { - /* Start Control Connection Reply */ - case PPPOL2TP_MESSAGETYPE_SCCRP: - /* Only accept SCCRP packet if we sent a SCCRQ */ - if (l2tp->phase != PPPOL2TP_STATE_SCCRQ_SENT) { - goto send_zlb; - } - break; - /* Incoming Call Reply */ - case PPPOL2TP_MESSAGETYPE_ICRP: - /* Only accept ICRP packet if we sent a IRCQ */ - if (l2tp->phase != PPPOL2TP_STATE_ICRQ_SENT) { - goto send_zlb; - } - break; - /* Stop Control Connection Notification */ - case PPPOL2TP_MESSAGETYPE_STOPCCN: - pppol2tp_send_zlb(l2tp, l2tp->our_ns+1, l2tp->peer_ns); /* Ack the StopCCN before we switch to down state */ - if (l2tp->phase < PPPOL2TP_STATE_DATA) { - pppol2tp_abort_connect(l2tp); - } else if (l2tp->phase == PPPOL2TP_STATE_DATA) { - /* Don't disconnect here, we let the LCP Echo/Reply find the fact - * that PPP session is down. Asking the PPP stack to end the session - * require strict checking about the PPP phase to prevent endless - * disconnection loops. - */ - } - return; - default: - break; - } - goto nextavp; - } - - /* Skip proprietary L2TP extensions */ - if (vendorid != 0) { - goto skipavp; - } - - switch (messagetype) { - /* Start Control Connection Reply */ - case PPPOL2TP_MESSAGETYPE_SCCRP: - switch (attributetype) { - case PPPOL2TP_AVPTYPE_TUNNELID: - if (avplen != sizeof(l2tp->source_tunnel_id) ) { - PPPDEBUG(LOG_DEBUG, ("pppol2tp: AVP Assign tunnel ID length check failed\n")); - return; - } - GETSHORT(l2tp->source_tunnel_id, inp); - PPPDEBUG(LOG_DEBUG, ("pppol2tp: Assigned tunnel ID %"U16_F"\n", l2tp->source_tunnel_id)); - goto nextavp; -#if PPPOL2TP_AUTH_SUPPORT - case PPPOL2TP_AVPTYPE_CHALLENGE: - if (avplen == 0) { - PPPDEBUG(LOG_DEBUG, ("pppol2tp: Challenge length check failed\n")); - return; - } - if (l2tp->secret == NULL) { - PPPDEBUG(LOG_DEBUG, ("pppol2tp: Received challenge from peer and no secret key available\n")); - pppol2tp_abort_connect(l2tp); - return; - } - /* Generate hash of ID, secret, challenge */ - lwip_md5_init(&md5_ctx); - lwip_md5_starts(&md5_ctx); - challenge_id = PPPOL2TP_MESSAGETYPE_SCCCN; - lwip_md5_update(&md5_ctx, &challenge_id, 1); - lwip_md5_update(&md5_ctx, l2tp->secret, l2tp->secret_len); - lwip_md5_update(&md5_ctx, inp, avplen); - lwip_md5_finish(&md5_ctx, l2tp->challenge_hash); - lwip_md5_free(&md5_ctx); - l2tp->send_challenge = 1; - goto skipavp; - case PPPOL2TP_AVPTYPE_CHALLENGERESPONSE: - if (avplen != PPPOL2TP_AVPTYPE_CHALLENGERESPONSE_SIZE) { - PPPDEBUG(LOG_DEBUG, ("pppol2tp: AVP Challenge Response length check failed\n")); - return; - } - /* Generate hash of ID, secret, challenge */ - lwip_md5_init(&md5_ctx); - lwip_md5_starts(&md5_ctx); - challenge_id = PPPOL2TP_MESSAGETYPE_SCCRP; - lwip_md5_update(&md5_ctx, &challenge_id, 1); - lwip_md5_update(&md5_ctx, l2tp->secret, l2tp->secret_len); - lwip_md5_update(&md5_ctx, l2tp->secret_rv, sizeof(l2tp->secret_rv)); - lwip_md5_finish(&md5_ctx, md5_hash); - lwip_md5_free(&md5_ctx); - if ( memcmp(inp, md5_hash, sizeof(md5_hash)) ) { - PPPDEBUG(LOG_DEBUG, ("pppol2tp: Received challenge response from peer and secret key do not match\n")); - pppol2tp_abort_connect(l2tp); - return; - } - goto skipavp; -#endif /* PPPOL2TP_AUTH_SUPPORT */ - default: - break; - } - break; - /* Incoming Call Reply */ - case PPPOL2TP_MESSAGETYPE_ICRP: - switch (attributetype) { - case PPPOL2TP_AVPTYPE_SESSIONID: - if (avplen != sizeof(l2tp->source_session_id) ) { - PPPDEBUG(LOG_DEBUG, ("pppol2tp: AVP Assign session ID length check failed\n")); - return; - } - GETSHORT(l2tp->source_session_id, inp); - PPPDEBUG(LOG_DEBUG, ("pppol2tp: Assigned session ID %"U16_F"\n", l2tp->source_session_id)); - goto nextavp; - default: - break; - } - break; - default: - break; - } - -skipavp: - INCPTR(avplen, inp); -nextavp: - /* printf("AVP Found, vendor=%d, attribute=%d, len=%d\n", vendorid, attributetype, avplen); */ - /* next AVP */ - if (pbuf_remove_header(p, avplen + sizeof(avpflags) + sizeof(vendorid) + sizeof(attributetype)) != 0) { - return; - } - } - - switch(messagetype) { - /* Start Control Connection Reply */ - case PPPOL2TP_MESSAGETYPE_SCCRP: - do { - l2tp->remote_session_id = magic(); - } while(l2tp->remote_session_id == 0); - l2tp->tunnel_port = port; /* LNS server might have chosen its own local port */ - l2tp->icrq_retried = 0; - l2tp->phase = PPPOL2TP_STATE_ICRQ_SENT; - l2tp->our_ns++; - if ((err = pppol2tp_send_scccn(l2tp, l2tp->our_ns)) != 0) { - PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send SCCCN, error=%d\n", err)); - LWIP_UNUSED_ARG(err); /* if PPPDEBUG is disabled */ - } - l2tp->our_ns++; - if ((err = pppol2tp_send_icrq(l2tp, l2tp->our_ns)) != 0) { - PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send ICRQ, error=%d\n", err)); - LWIP_UNUSED_ARG(err); /* if PPPDEBUG is disabled */ - } - sys_untimeout(pppol2tp_timeout, l2tp); - sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp); - break; - /* Incoming Call Reply */ - case PPPOL2TP_MESSAGETYPE_ICRP: - l2tp->iccn_retried = 0; - l2tp->phase = PPPOL2TP_STATE_ICCN_SENT; - l2tp->our_ns++; - if ((err = pppol2tp_send_iccn(l2tp, l2tp->our_ns)) != 0) { - PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send ICCN, error=%d\n", err)); - LWIP_UNUSED_ARG(err); /* if PPPDEBUG is disabled */ - } - sys_untimeout(pppol2tp_timeout, l2tp); - sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp); - break; - /* Unhandled packet, send ZLB ACK */ - default: - goto send_zlb; - } - return; - -send_zlb: - pppol2tp_send_zlb(l2tp, l2tp->our_ns+1, l2tp->peer_ns); - return; -packet_too_short: - PPPDEBUG(LOG_DEBUG, ("pppol2tp: packet too short: %d\n", p->len)); -} - -/* L2TP Timeout handler */ -static void pppol2tp_timeout(void *arg) { - pppol2tp_pcb *l2tp = (pppol2tp_pcb*)arg; - err_t err; - u32_t retry_wait; - - PPPDEBUG(LOG_DEBUG, ("pppol2tp: timeout\n")); - - switch (l2tp->phase) { - case PPPOL2TP_STATE_SCCRQ_SENT: - /* backoff wait */ - if (l2tp->sccrq_retried < 0xff) { - l2tp->sccrq_retried++; - } - if (!l2tp->ppp->settings.persist && l2tp->sccrq_retried >= PPPOL2TP_MAXSCCRQ) { - pppol2tp_abort_connect(l2tp); - return; - } - retry_wait = LWIP_MIN(PPPOL2TP_CONTROL_TIMEOUT * l2tp->sccrq_retried, PPPOL2TP_SLOW_RETRY); - PPPDEBUG(LOG_DEBUG, ("pppol2tp: sccrq_retried=%d\n", l2tp->sccrq_retried)); - if ((err = pppol2tp_send_sccrq(l2tp)) != 0) { - l2tp->sccrq_retried--; - PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send SCCRQ, error=%d\n", err)); - LWIP_UNUSED_ARG(err); /* if PPPDEBUG is disabled */ - } - sys_timeout(retry_wait, pppol2tp_timeout, l2tp); - break; - - case PPPOL2TP_STATE_ICRQ_SENT: - l2tp->icrq_retried++; - if (l2tp->icrq_retried >= PPPOL2TP_MAXICRQ) { - pppol2tp_abort_connect(l2tp); - return; - } - PPPDEBUG(LOG_DEBUG, ("pppol2tp: icrq_retried=%d\n", l2tp->icrq_retried)); - if ((s16_t)(l2tp->peer_nr - l2tp->our_ns) < 0) { /* the SCCCN was not acknowledged */ - if ((err = pppol2tp_send_scccn(l2tp, l2tp->our_ns -1)) != 0) { - l2tp->icrq_retried--; - PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send SCCCN, error=%d\n", err)); - LWIP_UNUSED_ARG(err); /* if PPPDEBUG is disabled */ - sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp); - break; - } - } - if ((err = pppol2tp_send_icrq(l2tp, l2tp->our_ns)) != 0) { - l2tp->icrq_retried--; - PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send ICRQ, error=%d\n", err)); - LWIP_UNUSED_ARG(err); /* if PPPDEBUG is disabled */ - } - sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp); - break; - - case PPPOL2TP_STATE_ICCN_SENT: - l2tp->iccn_retried++; - if (l2tp->iccn_retried >= PPPOL2TP_MAXICCN) { - pppol2tp_abort_connect(l2tp); - return; - } - PPPDEBUG(LOG_DEBUG, ("pppol2tp: iccn_retried=%d\n", l2tp->iccn_retried)); - if ((err = pppol2tp_send_iccn(l2tp, l2tp->our_ns)) != 0) { - l2tp->iccn_retried--; - PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send ICCN, error=%d\n", err)); - LWIP_UNUSED_ARG(err); /* if PPPDEBUG is disabled */ - } - sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp); - break; - - default: - return; /* all done, work in peace */ - } -} - -/* Connection attempt aborted */ -static void pppol2tp_abort_connect(pppol2tp_pcb *l2tp) { - PPPDEBUG(LOG_DEBUG, ("pppol2tp: could not establish connection\n")); - l2tp->phase = PPPOL2TP_STATE_INITIAL; - ppp_link_failed(l2tp->ppp); /* notify upper layers */ -} - -/* Initiate a new tunnel */ -static err_t pppol2tp_send_sccrq(pppol2tp_pcb *l2tp) { - struct pbuf *pb; - u8_t *p; - u16_t len; - - /* calculate UDP packet length */ - len = 12 +8 +8 +10 +10 +6+sizeof(PPPOL2TP_HOSTNAME)-1 +6+sizeof(PPPOL2TP_VENDORNAME)-1 +8 +8; -#if PPPOL2TP_AUTH_SUPPORT - if (l2tp->secret != NULL) { - len += 6 + sizeof(l2tp->secret_rv); - } -#endif /* PPPOL2TP_AUTH_SUPPORT */ - - /* allocate a buffer */ - pb = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); - if (pb == NULL) { - return ERR_MEM; - } - LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); - - p = (u8_t*)pb->payload; - /* fill in pkt */ - /* L2TP control header */ - PUTSHORT(PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY, p); - PUTSHORT(len, p); /* Length */ - PUTSHORT(0, p); /* Tunnel Id */ - PUTSHORT(0, p); /* Session Id */ - PUTSHORT(0, p); /* NS Sequence number - to peer */ - PUTSHORT(0, p); /* NR Sequence number - expected for peer */ - - /* AVP - Message type */ - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_MESSAGE, p); /* Attribute type: Message Type */ - PUTSHORT(PPPOL2TP_MESSAGETYPE_SCCRQ, p); /* Attribute value: Message type: SCCRQ */ - - /* AVP - L2TP Version */ - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_VERSION, p); /* Attribute type: Version */ - PUTSHORT(PPPOL2TP_VERSION, p); /* Attribute value: L2TP Version */ - - /* AVP - Framing capabilities */ - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 10, p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_FRAMINGCAPABILITIES, p); /* Attribute type: Framing capabilities */ - PUTLONG(PPPOL2TP_FRAMINGCAPABILITIES, p); /* Attribute value: Framing capabilities */ - - /* AVP - Bearer capabilities */ - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 10, p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_BEARERCAPABILITIES, p); /* Attribute type: Bearer capabilities */ - PUTLONG(PPPOL2TP_BEARERCAPABILITIES, p); /* Attribute value: Bearer capabilities */ - - /* AVP - Host name */ - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 6+sizeof(PPPOL2TP_HOSTNAME)-1, p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_HOSTNAME, p); /* Attribute type: Hostname */ - MEMCPY(p, PPPOL2TP_HOSTNAME, sizeof(PPPOL2TP_HOSTNAME)-1); /* Attribute value: Hostname */ - INCPTR(sizeof(PPPOL2TP_HOSTNAME)-1, p); - - /* AVP - Vendor name */ - PUTSHORT(6+sizeof(PPPOL2TP_VENDORNAME)-1, p); /* len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_VENDORNAME, p); /* Attribute type: Vendor name */ - MEMCPY(p, PPPOL2TP_VENDORNAME, sizeof(PPPOL2TP_VENDORNAME)-1); /* Attribute value: Vendor name */ - INCPTR(sizeof(PPPOL2TP_VENDORNAME)-1, p); - - /* AVP - Assign tunnel ID */ - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_TUNNELID, p); /* Attribute type: Tunnel ID */ - PUTSHORT(l2tp->remote_tunnel_id, p); /* Attribute value: Tunnel ID */ - - /* AVP - Receive window size */ - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_RECEIVEWINDOWSIZE, p); /* Attribute type: Receive window size */ - PUTSHORT(PPPOL2TP_RECEIVEWINDOWSIZE, p); /* Attribute value: Receive window size */ - -#if PPPOL2TP_AUTH_SUPPORT - /* AVP - Challenge */ - if (l2tp->secret != NULL) { - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 6 + sizeof(l2tp->secret_rv), p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_CHALLENGE, p); /* Attribute type: Challenge */ - MEMCPY(p, l2tp->secret_rv, sizeof(l2tp->secret_rv)); /* Attribute value: Random vector */ - INCPTR(sizeof(l2tp->secret_rv), p); - } -#endif /* PPPOL2TP_AUTH_SUPPORT */ - - return pppol2tp_udp_send(l2tp, pb); -} - -/* Complete tunnel establishment */ -static err_t pppol2tp_send_scccn(pppol2tp_pcb *l2tp, u16_t ns) { - struct pbuf *pb; - u8_t *p; - u16_t len; - - /* calculate UDP packet length */ - len = 12 +8; -#if PPPOL2TP_AUTH_SUPPORT - if (l2tp->send_challenge) { - len += 6 + sizeof(l2tp->challenge_hash); - } -#endif /* PPPOL2TP_AUTH_SUPPORT */ - - /* allocate a buffer */ - pb = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); - if (pb == NULL) { - return ERR_MEM; - } - LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); - - p = (u8_t*)pb->payload; - /* fill in pkt */ - /* L2TP control header */ - PUTSHORT(PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY, p); - PUTSHORT(len, p); /* Length */ - PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */ - PUTSHORT(0, p); /* Session Id */ - PUTSHORT(ns, p); /* NS Sequence number - to peer */ - PUTSHORT(l2tp->peer_ns, p); /* NR Sequence number - expected for peer */ - - /* AVP - Message type */ - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_MESSAGE, p); /* Attribute type: Message Type */ - PUTSHORT(PPPOL2TP_MESSAGETYPE_SCCCN, p); /* Attribute value: Message type: SCCCN */ - -#if PPPOL2TP_AUTH_SUPPORT - /* AVP - Challenge response */ - if (l2tp->send_challenge) { - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 6 + sizeof(l2tp->challenge_hash), p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_CHALLENGERESPONSE, p); /* Attribute type: Challenge response */ - MEMCPY(p, l2tp->challenge_hash, sizeof(l2tp->challenge_hash)); /* Attribute value: Computed challenge */ - INCPTR(sizeof(l2tp->challenge_hash), p); - } -#endif /* PPPOL2TP_AUTH_SUPPORT */ - - return pppol2tp_udp_send(l2tp, pb); -} - -/* Initiate a new session */ -static err_t pppol2tp_send_icrq(pppol2tp_pcb *l2tp, u16_t ns) { - struct pbuf *pb; - u8_t *p; - u16_t len; - u32_t serialnumber; - - /* calculate UDP packet length */ - len = 12 +8 +8 +10; - - /* allocate a buffer */ - pb = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); - if (pb == NULL) { - return ERR_MEM; - } - LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); - - p = (u8_t*)pb->payload; - /* fill in pkt */ - /* L2TP control header */ - PUTSHORT(PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY, p); - PUTSHORT(len, p); /* Length */ - PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */ - PUTSHORT(0, p); /* Session Id */ - PUTSHORT(ns, p); /* NS Sequence number - to peer */ - PUTSHORT(l2tp->peer_ns, p); /* NR Sequence number - expected for peer */ - - /* AVP - Message type */ - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_MESSAGE, p); /* Attribute type: Message Type */ - PUTSHORT(PPPOL2TP_MESSAGETYPE_ICRQ, p); /* Attribute value: Message type: ICRQ */ - - /* AVP - Assign session ID */ - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_SESSIONID, p); /* Attribute type: Session ID */ - PUTSHORT(l2tp->remote_session_id, p); /* Attribute value: Session ID */ - - /* AVP - Call Serial Number */ - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 10, p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_CALLSERIALNUMBER, p); /* Attribute type: Serial number */ - serialnumber = magic(); - PUTLONG(serialnumber, p); /* Attribute value: Serial number */ - - return pppol2tp_udp_send(l2tp, pb); -} - -/* Complete tunnel establishment */ -static err_t pppol2tp_send_iccn(pppol2tp_pcb *l2tp, u16_t ns) { - struct pbuf *pb; - u8_t *p; - u16_t len; - - /* calculate UDP packet length */ - len = 12 +8 +10 +10; - - /* allocate a buffer */ - pb = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); - if (pb == NULL) { - return ERR_MEM; - } - LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); - - p = (u8_t*)pb->payload; - /* fill in pkt */ - /* L2TP control header */ - PUTSHORT(PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY, p); - PUTSHORT(len, p); /* Length */ - PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */ - PUTSHORT(l2tp->source_session_id, p); /* Session Id */ - PUTSHORT(ns, p); /* NS Sequence number - to peer */ - PUTSHORT(l2tp->peer_ns, p); /* NR Sequence number - expected for peer */ - - /* AVP - Message type */ - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_MESSAGE, p); /* Attribute type: Message Type */ - PUTSHORT(PPPOL2TP_MESSAGETYPE_ICCN, p); /* Attribute value: Message type: ICCN */ - - /* AVP - Framing type */ - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 10, p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_FRAMINGTYPE, p); /* Attribute type: Framing type */ - PUTLONG(PPPOL2TP_FRAMINGTYPE, p); /* Attribute value: Framing type */ - - /* AVP - TX Connect speed */ - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 10, p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_TXCONNECTSPEED, p); /* Attribute type: TX Connect speed */ - PUTLONG(PPPOL2TP_TXCONNECTSPEED, p); /* Attribute value: TX Connect speed */ - - return pppol2tp_udp_send(l2tp, pb); -} - -/* Send a ZLB ACK packet */ -static err_t pppol2tp_send_zlb(pppol2tp_pcb *l2tp, u16_t ns, u16_t nr) { - struct pbuf *pb; - u8_t *p; - u16_t len; - - /* calculate UDP packet length */ - len = 12; - - /* allocate a buffer */ - pb = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); - if (pb == NULL) { - return ERR_MEM; - } - LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); - - p = (u8_t*)pb->payload; - /* fill in pkt */ - /* L2TP control header */ - PUTSHORT(PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY, p); - PUTSHORT(len, p); /* Length */ - PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */ - PUTSHORT(0, p); /* Session Id */ - PUTSHORT(ns, p); /* NS Sequence number - to peer */ - PUTSHORT(nr, p); /* NR Sequence number - expected for peer */ - - return pppol2tp_udp_send(l2tp, pb); -} - -/* Send a StopCCN packet */ -static err_t pppol2tp_send_stopccn(pppol2tp_pcb *l2tp, u16_t ns) { - struct pbuf *pb; - u8_t *p; - u16_t len; - - /* calculate UDP packet length */ - len = 12 +8 +8 +8; - - /* allocate a buffer */ - pb = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); - if (pb == NULL) { - return ERR_MEM; - } - LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); - - p = (u8_t*)pb->payload; - /* fill in pkt */ - /* L2TP control header */ - PUTSHORT(PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY, p); - PUTSHORT(len, p); /* Length */ - PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */ - PUTSHORT(0, p); /* Session Id */ - PUTSHORT(ns, p); /* NS Sequence number - to peer */ - PUTSHORT(l2tp->peer_ns, p); /* NR Sequence number - expected for peer */ - - /* AVP - Message type */ - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_MESSAGE, p); /* Attribute type: Message Type */ - PUTSHORT(PPPOL2TP_MESSAGETYPE_STOPCCN, p); /* Attribute value: Message type: StopCCN */ - - /* AVP - Assign tunnel ID */ - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_TUNNELID, p); /* Attribute type: Tunnel ID */ - PUTSHORT(l2tp->remote_tunnel_id, p); /* Attribute value: Tunnel ID */ - - /* AVP - Result code */ - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_RESULTCODE, p); /* Attribute type: Result code */ - PUTSHORT(PPPOL2TP_RESULTCODE, p); /* Attribute value: Result code */ - - return pppol2tp_udp_send(l2tp, pb); -} - -static err_t pppol2tp_xmit(pppol2tp_pcb *l2tp, struct pbuf *pb) { - u8_t *p; - - /* make room for L2TP header - should not fail */ - if (pbuf_add_header(pb, PPPOL2TP_OUTPUT_DATA_HEADER_LEN) != 0) { - /* bail out */ - PPPDEBUG(LOG_ERR, ("pppol2tp: pppol2tp_pcb: could not allocate room for L2TP header\n")); - LINK_STATS_INC(link.lenerr); - pbuf_free(pb); - return ERR_BUF; - } - - p = (u8_t*)pb->payload; - PUTSHORT(PPPOL2TP_HEADERFLAG_DATA_MANDATORY, p); - PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */ - PUTSHORT(l2tp->source_session_id, p); /* Session Id */ - - return pppol2tp_udp_send(l2tp, pb); -} - -static err_t pppol2tp_udp_send(pppol2tp_pcb *l2tp, struct pbuf *pb) { - err_t err; - if (l2tp->netif) { - err = udp_sendto_if(l2tp->udp, pb, &l2tp->remote_ip, l2tp->tunnel_port, l2tp->netif); - } else { - err = udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->tunnel_port); - } - pbuf_free(pb); - return err; -} - -#endif /* PPP_SUPPORT && PPPOL2TP_SUPPORT */ diff --git a/third-party/lwip-2.1.2/netif/ppp/pppos.c b/third-party/lwip-2.1.2/netif/ppp/pppos.c deleted file mode 100644 index dff02554..00000000 --- a/third-party/lwip-2.1.2/netif/ppp/pppos.c +++ /dev/null @@ -1,895 +0,0 @@ -/** - * @file - * Network Point to Point Protocol over Serial file. - * - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && PPPOS_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include - -#include "lwip/arch.h" -#include "lwip/err.h" -#include "lwip/pbuf.h" -#include "lwip/sys.h" -#include "lwip/memp.h" -#include "lwip/netif.h" -#include "lwip/snmp.h" -#include "lwip/priv/tcpip_priv.h" -#include "lwip/api.h" -#include "lwip/ip4.h" /* for ip4_input() */ - -#include "netif/ppp/ppp_impl.h" -#include "netif/ppp/pppos.h" -#include "netif/ppp/vj.h" - -/* Memory pool */ -LWIP_MEMPOOL_DECLARE(PPPOS_PCB, MEMP_NUM_PPPOS_INTERFACES, sizeof(pppos_pcb), "PPPOS_PCB") - -/* callbacks called from PPP core */ -static err_t pppos_write(ppp_pcb *ppp, void *ctx, struct pbuf *p); -static err_t pppos_netif_output(ppp_pcb *ppp, void *ctx, struct pbuf *pb, u16_t protocol); -static void pppos_connect(ppp_pcb *ppp, void *ctx); -#if PPP_SERVER -static void pppos_listen(ppp_pcb *ppp, void *ctx); -#endif /* PPP_SERVER */ -static void pppos_disconnect(ppp_pcb *ppp, void *ctx); -static err_t pppos_destroy(ppp_pcb *ppp, void *ctx); -static void pppos_send_config(ppp_pcb *ppp, void *ctx, u32_t accm, int pcomp, int accomp); -static void pppos_recv_config(ppp_pcb *ppp, void *ctx, u32_t accm, int pcomp, int accomp); - -/* Prototypes for procedures local to this file. */ -#if PPP_INPROC_IRQ_SAFE -static void pppos_input_callback(void *arg); -#endif /* PPP_INPROC_IRQ_SAFE */ -static void pppos_input_free_current_packet(pppos_pcb *pppos); -static void pppos_input_drop(pppos_pcb *pppos); -static err_t pppos_output_append(pppos_pcb *pppos, err_t err, struct pbuf *nb, u8_t c, u8_t accm, u16_t *fcs); -static err_t pppos_output_last(pppos_pcb *pppos, err_t err, struct pbuf *nb, u16_t *fcs); - -/* Callbacks structure for PPP core */ -static const struct link_callbacks pppos_callbacks = { - pppos_connect, -#if PPP_SERVER - pppos_listen, -#endif /* PPP_SERVER */ - pppos_disconnect, - pppos_destroy, - pppos_write, - pppos_netif_output, - pppos_send_config, - pppos_recv_config -}; - -/* PPP's Asynchronous-Control-Character-Map. The mask array is used - * to select the specific bit for a character. */ -#define ESCAPE_P(accm, c) ((accm)[(c) >> 3] & 1 << (c & 0x07)) - -#if PPP_FCS_TABLE -/* - * FCS lookup table as calculated by genfcstab. - */ -static const u16_t fcstab[256] = { - 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, - 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, - 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, - 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, - 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, - 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, - 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, - 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, - 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, - 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, - 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, - 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, - 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, - 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, - 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, - 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, - 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, - 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, - 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, - 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, - 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, - 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, - 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, - 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, - 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, - 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, - 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, - 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, - 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, - 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, - 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, - 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 -}; -#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff]) -#else /* PPP_FCS_TABLE */ -/* The HDLC polynomial: X**0 + X**5 + X**12 + X**16 (0x8408) */ -#define PPP_FCS_POLYNOMIAL 0x8408 -static u16_t -ppp_get_fcs(u8_t byte) -{ - unsigned int octet; - int bit; - octet = byte; - for (bit = 8; bit-- > 0; ) { - octet = (octet & 0x01) ? ((octet >> 1) ^ PPP_FCS_POLYNOMIAL) : (octet >> 1); - } - return octet & 0xffff; -} -#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ ppp_get_fcs(((fcs) ^ (c)) & 0xff)) -#endif /* PPP_FCS_TABLE */ - -/* - * Values for FCS calculations. - */ -#define PPP_INITFCS 0xffff /* Initial FCS value */ -#define PPP_GOODFCS 0xf0b8 /* Good final FCS value */ - -#if PPP_INPROC_IRQ_SAFE -#define PPPOS_DECL_PROTECT(lev) SYS_ARCH_DECL_PROTECT(lev) -#define PPPOS_PROTECT(lev) SYS_ARCH_PROTECT(lev) -#define PPPOS_UNPROTECT(lev) SYS_ARCH_UNPROTECT(lev) -#else -#define PPPOS_DECL_PROTECT(lev) -#define PPPOS_PROTECT(lev) -#define PPPOS_UNPROTECT(lev) -#endif /* PPP_INPROC_IRQ_SAFE */ - - -/* - * Create a new PPP connection using the given serial I/O device. - * - * Return 0 on success, an error code on failure. - */ -ppp_pcb *pppos_create(struct netif *pppif, pppos_output_cb_fn output_cb, - ppp_link_status_cb_fn link_status_cb, void *ctx_cb) -{ - pppos_pcb *pppos; - ppp_pcb *ppp; - LWIP_ASSERT_CORE_LOCKED(); - - pppos = (pppos_pcb *)LWIP_MEMPOOL_ALLOC(PPPOS_PCB); - if (pppos == NULL) { - return NULL; - } - - ppp = ppp_new(pppif, &pppos_callbacks, pppos, link_status_cb, ctx_cb); - if (ppp == NULL) { - LWIP_MEMPOOL_FREE(PPPOS_PCB, pppos); - return NULL; - } - - memset(pppos, 0, sizeof(pppos_pcb)); - pppos->ppp = ppp; - pppos->output_cb = output_cb; - return ppp; -} - -/* Called by PPP core */ -static err_t -pppos_write(ppp_pcb *ppp, void *ctx, struct pbuf *p) -{ - pppos_pcb *pppos = (pppos_pcb *)ctx; - u8_t *s; - struct pbuf *nb; - u16_t n; - u16_t fcs_out; - err_t err; - LWIP_UNUSED_ARG(ppp); - - /* Grab an output buffer. Using PBUF_POOL here for tx is ok since the pbuf - gets freed by 'pppos_output_last' before this function returns and thus - cannot starve rx. */ - nb = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); - if (nb == NULL) { - PPPDEBUG(LOG_WARNING, ("pppos_write[%d]: alloc fail\n", ppp->netif->num)); - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.drop); - MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards); - pbuf_free(p); - return ERR_MEM; - } - - /* Set nb->tot_len to actual payload length */ - nb->tot_len = p->len; - - /* If the link has been idle, we'll send a fresh flag character to - * flush any noise. */ - err = ERR_OK; - if ((sys_now() - pppos->last_xmit) >= PPP_MAXIDLEFLAG) { - err = pppos_output_append(pppos, err, nb, PPP_FLAG, 0, NULL); - } - - /* Load output buffer. */ - fcs_out = PPP_INITFCS; - s = (u8_t*)p->payload; - n = p->len; - while (n-- > 0) { - err = pppos_output_append(pppos, err, nb, *s++, 1, &fcs_out); - } - - err = pppos_output_last(pppos, err, nb, &fcs_out); - if (err == ERR_OK) { - PPPDEBUG(LOG_INFO, ("pppos_write[%d]: len=%d\n", ppp->netif->num, p->len)); - } else { - PPPDEBUG(LOG_WARNING, ("pppos_write[%d]: output failed len=%d\n", ppp->netif->num, p->len)); - } - pbuf_free(p); - return err; -} - -/* Called by PPP core */ -static err_t -pppos_netif_output(ppp_pcb *ppp, void *ctx, struct pbuf *pb, u16_t protocol) -{ - pppos_pcb *pppos = (pppos_pcb *)ctx; - struct pbuf *nb, *p; - u16_t fcs_out; - err_t err; - LWIP_UNUSED_ARG(ppp); - - /* Grab an output buffer. Using PBUF_POOL here for tx is ok since the pbuf - gets freed by 'pppos_output_last' before this function returns and thus - cannot starve rx. */ - nb = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); - if (nb == NULL) { - PPPDEBUG(LOG_WARNING, ("pppos_netif_output[%d]: alloc fail\n", ppp->netif->num)); - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.drop); - MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards); - return ERR_MEM; - } - - /* Set nb->tot_len to actual payload length */ - nb->tot_len = pb->tot_len; - - /* If the link has been idle, we'll send a fresh flag character to - * flush any noise. */ - err = ERR_OK; - if ((sys_now() - pppos->last_xmit) >= PPP_MAXIDLEFLAG) { - err = pppos_output_append(pppos, err, nb, PPP_FLAG, 0, NULL); - } - - fcs_out = PPP_INITFCS; - if (!pppos->accomp) { - err = pppos_output_append(pppos, err, nb, PPP_ALLSTATIONS, 1, &fcs_out); - err = pppos_output_append(pppos, err, nb, PPP_UI, 1, &fcs_out); - } - if (!pppos->pcomp || protocol > 0xFF) { - err = pppos_output_append(pppos, err, nb, (protocol >> 8) & 0xFF, 1, &fcs_out); - } - err = pppos_output_append(pppos, err, nb, protocol & 0xFF, 1, &fcs_out); - - /* Load packet. */ - for(p = pb; p; p = p->next) { - u16_t n = p->len; - u8_t *s = (u8_t*)p->payload; - - while (n-- > 0) { - err = pppos_output_append(pppos, err, nb, *s++, 1, &fcs_out); - } - } - - err = pppos_output_last(pppos, err, nb, &fcs_out); - if (err == ERR_OK) { - PPPDEBUG(LOG_INFO, ("pppos_netif_output[%d]: proto=0x%"X16_F", len = %d\n", ppp->netif->num, protocol, pb->tot_len)); - } else { - PPPDEBUG(LOG_WARNING, ("pppos_netif_output[%d]: output failed proto=0x%"X16_F", len = %d\n", ppp->netif->num, protocol, pb->tot_len)); - } - return err; -} - -static void -pppos_connect(ppp_pcb *ppp, void *ctx) -{ - pppos_pcb *pppos = (pppos_pcb *)ctx; - PPPOS_DECL_PROTECT(lev); - -#if PPP_INPROC_IRQ_SAFE - /* input pbuf left over from last session? */ - pppos_input_free_current_packet(pppos); -#endif /* PPP_INPROC_IRQ_SAFE */ - - /* reset PPPoS control block to its initial state */ - memset(&pppos->last_xmit, 0, sizeof(pppos_pcb) - offsetof(pppos_pcb, last_xmit)); - - /* - * Default the in and out accm so that escape and flag characters - * are always escaped. - */ - pppos->in_accm[15] = 0x60; /* no need to protect since RX is not running */ - pppos->out_accm[15] = 0x60; - PPPOS_PROTECT(lev); - pppos->open = 1; - PPPOS_UNPROTECT(lev); - - /* - * Start the connection and handle incoming events (packet or timeout). - */ - PPPDEBUG(LOG_INFO, ("pppos_connect: unit %d: connecting\n", ppp->netif->num)); - ppp_start(ppp); /* notify upper layers */ -} - -#if PPP_SERVER -static void -pppos_listen(ppp_pcb *ppp, void *ctx) -{ - pppos_pcb *pppos = (pppos_pcb *)ctx; - PPPOS_DECL_PROTECT(lev); - -#if PPP_INPROC_IRQ_SAFE - /* input pbuf left over from last session? */ - pppos_input_free_current_packet(pppos); -#endif /* PPP_INPROC_IRQ_SAFE */ - - /* reset PPPoS control block to its initial state */ - memset(&pppos->last_xmit, 0, sizeof(pppos_pcb) - offsetof(pppos_pcb, last_xmit)); - - /* - * Default the in and out accm so that escape and flag characters - * are always escaped. - */ - pppos->in_accm[15] = 0x60; /* no need to protect since RX is not running */ - pppos->out_accm[15] = 0x60; - PPPOS_PROTECT(lev); - pppos->open = 1; - PPPOS_UNPROTECT(lev); - - /* - * Wait for something to happen. - */ - PPPDEBUG(LOG_INFO, ("pppos_listen: unit %d: listening\n", ppp->netif->num)); - ppp_start(ppp); /* notify upper layers */ -} -#endif /* PPP_SERVER */ - -static void -pppos_disconnect(ppp_pcb *ppp, void *ctx) -{ - pppos_pcb *pppos = (pppos_pcb *)ctx; - PPPOS_DECL_PROTECT(lev); - - PPPOS_PROTECT(lev); - pppos->open = 0; - PPPOS_UNPROTECT(lev); - - /* If PPP_INPROC_IRQ_SAFE is used we cannot call - * pppos_input_free_current_packet() here because - * rx IRQ might still call pppos_input(). - */ -#if !PPP_INPROC_IRQ_SAFE - /* input pbuf left ? */ - pppos_input_free_current_packet(pppos); -#endif /* !PPP_INPROC_IRQ_SAFE */ - - ppp_link_end(ppp); /* notify upper layers */ -} - -static err_t -pppos_destroy(ppp_pcb *ppp, void *ctx) -{ - pppos_pcb *pppos = (pppos_pcb *)ctx; - LWIP_UNUSED_ARG(ppp); - -#if PPP_INPROC_IRQ_SAFE - /* input pbuf left ? */ - pppos_input_free_current_packet(pppos); -#endif /* PPP_INPROC_IRQ_SAFE */ - - LWIP_MEMPOOL_FREE(PPPOS_PCB, pppos); - return ERR_OK; -} - -#if !NO_SYS && !PPP_INPROC_IRQ_SAFE -/** Pass received raw characters to PPPoS to be decoded through lwIP TCPIP thread. - * - * This is one of the only functions that may be called outside of the TCPIP thread! - * - * @param ppp PPP descriptor index, returned by pppos_create() - * @param s received data - * @param l length of received data - */ -err_t -pppos_input_tcpip(ppp_pcb *ppp, u8_t *s, int l) -{ - struct pbuf *p; - err_t err; - - p = pbuf_alloc(PBUF_RAW, l, PBUF_POOL); - if (!p) { - return ERR_MEM; - } - pbuf_take(p, s, l); - - err = tcpip_inpkt(p, ppp_netif(ppp), pppos_input_sys); - if (err != ERR_OK) { - pbuf_free(p); - } - return err; -} - -/* called from TCPIP thread */ -err_t pppos_input_sys(struct pbuf *p, struct netif *inp) { - ppp_pcb *ppp = (ppp_pcb*)inp->state; - struct pbuf *n; - LWIP_ASSERT_CORE_LOCKED(); - - for (n = p; n; n = n->next) { - pppos_input(ppp, (u8_t*)n->payload, n->len); - } - pbuf_free(p); - return ERR_OK; -} -#endif /* !NO_SYS && !PPP_INPROC_IRQ_SAFE */ - -/** PPPoS input helper struct, must be packed since it is stored - * to pbuf->payload, which might be unaligned. */ -#if PPP_INPROC_IRQ_SAFE -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct pppos_input_header { - PACK_STRUCT_FIELD(ppp_pcb *ppp); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif -#endif /* PPP_INPROC_IRQ_SAFE */ - -/** Pass received raw characters to PPPoS to be decoded. - * - * @param ppp PPP descriptor index, returned by pppos_create() - * @param s received data - * @param l length of received data - */ -void -pppos_input(ppp_pcb *ppp, u8_t *s, int l) -{ - pppos_pcb *pppos = (pppos_pcb *)ppp->link_ctx_cb; - struct pbuf *next_pbuf; - u8_t cur_char; - u8_t escaped; - PPPOS_DECL_PROTECT(lev); -#if !PPP_INPROC_IRQ_SAFE - LWIP_ASSERT_CORE_LOCKED(); -#endif - - PPPDEBUG(LOG_DEBUG, ("pppos_input[%d]: got %d bytes\n", ppp->netif->num, l)); - while (l-- > 0) { - cur_char = *s++; - - PPPOS_PROTECT(lev); - /* ppp_input can disconnect the interface, we need to abort to prevent a memory - * leak if there are remaining bytes because pppos_connect and pppos_listen - * functions expect input buffer to be free. Furthermore there are no real - * reason to continue reading bytes if we are disconnected. - */ - if (!pppos->open) { - PPPOS_UNPROTECT(lev); - return; - } - escaped = ESCAPE_P(pppos->in_accm, cur_char); - PPPOS_UNPROTECT(lev); - /* Handle special characters. */ - if (escaped) { - /* Check for escape sequences. */ - /* XXX Note that this does not handle an escaped 0x5d character which - * would appear as an escape character. Since this is an ASCII ']' - * and there is no reason that I know of to escape it, I won't complicate - * the code to handle this case. GLL */ - if (cur_char == PPP_ESCAPE) { - pppos->in_escaped = 1; - /* Check for the flag character. */ - } else if (cur_char == PPP_FLAG) { - /* If this is just an extra flag character, ignore it. */ - if (pppos->in_state <= PDADDRESS) { - /* ignore it */; - /* If we haven't received the packet header, drop what has come in. */ - } else if (pppos->in_state < PDDATA) { - PPPDEBUG(LOG_WARNING, - ("pppos_input[%d]: Dropping incomplete packet %d\n", - ppp->netif->num, pppos->in_state)); - LINK_STATS_INC(link.lenerr); - pppos_input_drop(pppos); - /* If the fcs is invalid, drop the packet. */ - } else if (pppos->in_fcs != PPP_GOODFCS) { - PPPDEBUG(LOG_INFO, - ("pppos_input[%d]: Dropping bad fcs 0x%"X16_F" proto=0x%"X16_F"\n", - ppp->netif->num, pppos->in_fcs, pppos->in_protocol)); - /* Note: If you get lots of these, check for UART frame errors or try different baud rate */ - LINK_STATS_INC(link.chkerr); - pppos_input_drop(pppos); - /* Otherwise it's a good packet so pass it on. */ - } else { - struct pbuf *inp; - /* Trim off the checksum. */ - if(pppos->in_tail->len > 2) { - pppos->in_tail->len -= 2; - - pppos->in_tail->tot_len = pppos->in_tail->len; - if (pppos->in_tail != pppos->in_head) { - pbuf_cat(pppos->in_head, pppos->in_tail); - } - } else { - pppos->in_tail->tot_len = pppos->in_tail->len; - if (pppos->in_tail != pppos->in_head) { - pbuf_cat(pppos->in_head, pppos->in_tail); - } - - pbuf_realloc(pppos->in_head, pppos->in_head->tot_len - 2); - } - - /* Dispatch the packet thereby consuming it. */ - inp = pppos->in_head; - /* Packet consumed, release our references. */ - pppos->in_head = NULL; - pppos->in_tail = NULL; -#if IP_FORWARD || LWIP_IPV6_FORWARD - /* hide the room for Ethernet forwarding header */ - pbuf_remove_header(inp, PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN); -#endif /* IP_FORWARD || LWIP_IPV6_FORWARD */ -#if PPP_INPROC_IRQ_SAFE - if(tcpip_try_callback(pppos_input_callback, inp) != ERR_OK) { - PPPDEBUG(LOG_ERR, ("pppos_input[%d]: tcpip_callback() failed, dropping packet\n", ppp->netif->num)); - pbuf_free(inp); - LINK_STATS_INC(link.drop); - MIB2_STATS_NETIF_INC(ppp->netif, ifindiscards); - } -#else /* PPP_INPROC_IRQ_SAFE */ - ppp_input(ppp, inp); -#endif /* PPP_INPROC_IRQ_SAFE */ - } - - /* Prepare for a new packet. */ - pppos->in_fcs = PPP_INITFCS; - pppos->in_state = PDADDRESS; - pppos->in_escaped = 0; - /* Other characters are usually control characters that may have - * been inserted by the physical layer so here we just drop them. */ - } else { - PPPDEBUG(LOG_WARNING, - ("pppos_input[%d]: Dropping ACCM char <%d>\n", ppp->netif->num, cur_char)); - } - /* Process other characters. */ - } else { - /* Unencode escaped characters. */ - if (pppos->in_escaped) { - pppos->in_escaped = 0; - cur_char ^= PPP_TRANS; - } - - /* Process character relative to current state. */ - switch(pppos->in_state) { - case PDIDLE: /* Idle state - waiting. */ - /* Drop the character if it's not 0xff - * we would have processed a flag character above. */ - if (cur_char != PPP_ALLSTATIONS) { - break; - } - /* no break */ - /* Fall through */ - - case PDSTART: /* Process start flag. */ - /* Prepare for a new packet. */ - pppos->in_fcs = PPP_INITFCS; - /* no break */ - /* Fall through */ - - case PDADDRESS: /* Process address field. */ - if (cur_char == PPP_ALLSTATIONS) { - pppos->in_state = PDCONTROL; - break; - } - /* no break */ - - /* Else assume compressed address and control fields so - * fall through to get the protocol... */ - /* Fall through */ - case PDCONTROL: /* Process control field. */ - /* If we don't get a valid control code, restart. */ - if (cur_char == PPP_UI) { - pppos->in_state = PDPROTOCOL1; - break; - } - /* no break */ - -#if 0 - else { - PPPDEBUG(LOG_WARNING, - ("pppos_input[%d]: Invalid control <%d>\n", ppp->netif->num, cur_char)); - pppos->in_state = PDSTART; - } -#endif - /* Fall through */ - - case PDPROTOCOL1: /* Process protocol field 1. */ - /* If the lower bit is set, this is the end of the protocol - * field. */ - if (cur_char & 1) { - pppos->in_protocol = cur_char; - pppos->in_state = PDDATA; - } else { - pppos->in_protocol = (u16_t)cur_char << 8; - pppos->in_state = PDPROTOCOL2; - } - break; - case PDPROTOCOL2: /* Process protocol field 2. */ - pppos->in_protocol |= cur_char; - pppos->in_state = PDDATA; - break; - case PDDATA: /* Process data byte. */ - /* Make space to receive processed data. */ - if (pppos->in_tail == NULL || pppos->in_tail->len == PBUF_POOL_BUFSIZE) { - u16_t pbuf_alloc_len; - if (pppos->in_tail != NULL) { - pppos->in_tail->tot_len = pppos->in_tail->len; - if (pppos->in_tail != pppos->in_head) { - pbuf_cat(pppos->in_head, pppos->in_tail); - /* give up the in_tail reference now */ - pppos->in_tail = NULL; - } - } - /* If we haven't started a packet, we need a packet header. */ - pbuf_alloc_len = 0; -#if IP_FORWARD || LWIP_IPV6_FORWARD - /* If IP forwarding is enabled we are reserving PBUF_LINK_ENCAPSULATION_HLEN - * + PBUF_LINK_HLEN bytes so the packet is being allocated with enough header - * space to be forwarded (to Ethernet for example). - */ - if (pppos->in_head == NULL) { - pbuf_alloc_len = PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN; - } -#endif /* IP_FORWARD || LWIP_IPV6_FORWARD */ - next_pbuf = pbuf_alloc(PBUF_RAW, pbuf_alloc_len, PBUF_POOL); - if (next_pbuf == NULL) { - /* No free buffers. Drop the input packet and let the - * higher layers deal with it. Continue processing - * the received pbuf chain in case a new packet starts. */ - PPPDEBUG(LOG_ERR, ("pppos_input[%d]: NO FREE PBUFS!\n", ppp->netif->num)); - LINK_STATS_INC(link.memerr); - pppos_input_drop(pppos); - pppos->in_state = PDSTART; /* Wait for flag sequence. */ - break; - } - if (pppos->in_head == NULL) { - u8_t *payload = ((u8_t*)next_pbuf->payload) + pbuf_alloc_len; -#if PPP_INPROC_IRQ_SAFE - ((struct pppos_input_header*)payload)->ppp = ppp; - payload += sizeof(struct pppos_input_header); - next_pbuf->len += sizeof(struct pppos_input_header); -#endif /* PPP_INPROC_IRQ_SAFE */ - next_pbuf->len += sizeof(pppos->in_protocol); - *(payload++) = pppos->in_protocol >> 8; - *(payload) = pppos->in_protocol & 0xFF; - pppos->in_head = next_pbuf; - } - pppos->in_tail = next_pbuf; - } - /* Load character into buffer. */ - ((u8_t*)pppos->in_tail->payload)[pppos->in_tail->len++] = cur_char; - break; - default: - break; - } - - /* update the frame check sequence number. */ - pppos->in_fcs = PPP_FCS(pppos->in_fcs, cur_char); - } - } /* while (l-- > 0), all bytes processed */ -} - -#if PPP_INPROC_IRQ_SAFE -/* PPPoS input callback using one input pointer - */ -static void pppos_input_callback(void *arg) { - struct pbuf *pb = (struct pbuf*)arg; - ppp_pcb *ppp; - - ppp = ((struct pppos_input_header*)pb->payload)->ppp; - if(pbuf_remove_header(pb, sizeof(struct pppos_input_header))) { - LWIP_ASSERT("pbuf_remove_header failed\n", 0); - goto drop; - } - - /* Dispatch the packet thereby consuming it. */ - ppp_input(ppp, pb); - return; - -drop: - LINK_STATS_INC(link.drop); - MIB2_STATS_NETIF_INC(ppp->netif, ifindiscards); - pbuf_free(pb); -} -#endif /* PPP_INPROC_IRQ_SAFE */ - -static void -pppos_send_config(ppp_pcb *ppp, void *ctx, u32_t accm, int pcomp, int accomp) -{ - int i; - pppos_pcb *pppos = (pppos_pcb *)ctx; - LWIP_UNUSED_ARG(ppp); - - pppos->pcomp = pcomp; - pppos->accomp = accomp; - - /* Load the ACCM bits for the 32 control codes. */ - for (i = 0; i < 32/8; i++) { - pppos->out_accm[i] = (u8_t)((accm >> (8 * i)) & 0xFF); - } - - PPPDEBUG(LOG_INFO, ("pppos_send_config[%d]: out_accm=%X %X %X %X\n", - pppos->ppp->netif->num, - pppos->out_accm[0], pppos->out_accm[1], pppos->out_accm[2], pppos->out_accm[3])); -} - -static void -pppos_recv_config(ppp_pcb *ppp, void *ctx, u32_t accm, int pcomp, int accomp) -{ - int i; - pppos_pcb *pppos = (pppos_pcb *)ctx; - PPPOS_DECL_PROTECT(lev); - LWIP_UNUSED_ARG(ppp); - LWIP_UNUSED_ARG(pcomp); - LWIP_UNUSED_ARG(accomp); - - /* Load the ACCM bits for the 32 control codes. */ - PPPOS_PROTECT(lev); - for (i = 0; i < 32 / 8; i++) { - pppos->in_accm[i] = (u8_t)(accm >> (i * 8)); - } - PPPOS_UNPROTECT(lev); - - PPPDEBUG(LOG_INFO, ("pppos_recv_config[%d]: in_accm=%X %X %X %X\n", - pppos->ppp->netif->num, - pppos->in_accm[0], pppos->in_accm[1], pppos->in_accm[2], pppos->in_accm[3])); -} - -/* - * Drop the input packet. - */ -static void -pppos_input_free_current_packet(pppos_pcb *pppos) -{ - if (pppos->in_head != NULL) { - if (pppos->in_tail && (pppos->in_tail != pppos->in_head)) { - pbuf_free(pppos->in_tail); - } - pbuf_free(pppos->in_head); - pppos->in_head = NULL; - } - pppos->in_tail = NULL; -} - -/* - * Drop the input packet and increase error counters. - */ -static void -pppos_input_drop(pppos_pcb *pppos) -{ - if (pppos->in_head != NULL) { -#if 0 - PPPDEBUG(LOG_INFO, ("pppos_input_drop: %d:%.*H\n", pppos->in_head->len, min(60, pppos->in_head->len * 2), pppos->in_head->payload)); -#endif - PPPDEBUG(LOG_INFO, ("pppos_input_drop: pbuf len=%d, addr %p\n", pppos->in_head->len, (void*)pppos->in_head)); - } - pppos_input_free_current_packet(pppos); -#if VJ_SUPPORT - vj_uncompress_err(&pppos->ppp->vj_comp); -#endif /* VJ_SUPPORT */ - - LINK_STATS_INC(link.drop); - MIB2_STATS_NETIF_INC(pppos->ppp->netif, ifindiscards); -} - -/* - * pppos_output_append - append given character to end of given pbuf. - * If out_accm is not 0 and the character needs to be escaped, do so. - * If pbuf is full, send the pbuf and reuse it. - * Return the current pbuf. - */ -static err_t -pppos_output_append(pppos_pcb *pppos, err_t err, struct pbuf *nb, u8_t c, u8_t accm, u16_t *fcs) -{ - if (err != ERR_OK) { - return err; - } - - /* Make sure there is room for the character and an escape code. - * Sure we don't quite fill the buffer if the character doesn't - * get escaped but is one character worth complicating this? */ - if ((PBUF_POOL_BUFSIZE - nb->len) < 2) { - u32_t l = pppos->output_cb(pppos->ppp, (u8_t*)nb->payload, nb->len, pppos->ppp->ctx_cb); - if (l != nb->len) { - return ERR_IF; - } - nb->len = 0; - } - - /* Update FCS before checking for special characters. */ - if (fcs) { - *fcs = PPP_FCS(*fcs, c); - } - - /* Copy to output buffer escaping special characters. */ - if (accm && ESCAPE_P(pppos->out_accm, c)) { - *((u8_t*)nb->payload + nb->len++) = PPP_ESCAPE; - *((u8_t*)nb->payload + nb->len++) = c ^ PPP_TRANS; - } else { - *((u8_t*)nb->payload + nb->len++) = c; - } - - return ERR_OK; -} - -static err_t -pppos_output_last(pppos_pcb *pppos, err_t err, struct pbuf *nb, u16_t *fcs) -{ - ppp_pcb *ppp = pppos->ppp; - - /* Add FCS and trailing flag. */ - err = pppos_output_append(pppos, err, nb, ~(*fcs) & 0xFF, 1, NULL); - err = pppos_output_append(pppos, err, nb, (~(*fcs) >> 8) & 0xFF, 1, NULL); - err = pppos_output_append(pppos, err, nb, PPP_FLAG, 0, NULL); - - if (err != ERR_OK) { - goto failed; - } - - /* Send remaining buffer if not empty */ - if (nb->len > 0) { - u32_t l = pppos->output_cb(ppp, (u8_t*)nb->payload, nb->len, ppp->ctx_cb); - if (l != nb->len) { - err = ERR_IF; - goto failed; - } - } - - pppos->last_xmit = sys_now(); - MIB2_STATS_NETIF_ADD(ppp->netif, ifoutoctets, nb->tot_len); - MIB2_STATS_NETIF_INC(ppp->netif, ifoutucastpkts); - LINK_STATS_INC(link.xmit); - pbuf_free(nb); - return ERR_OK; - -failed: - pppos->last_xmit = 0; /* prepend PPP_FLAG to next packet */ - LINK_STATS_INC(link.err); - LINK_STATS_INC(link.drop); - MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards); - pbuf_free(nb); - return err; -} - -#endif /* PPP_SUPPORT && PPPOS_SUPPORT */ diff --git a/third-party/lwip-2.1.2/netif/ppp/upap.c b/third-party/lwip-2.1.2/netif/ppp/upap.c deleted file mode 100644 index 3b2399dc..00000000 --- a/third-party/lwip-2.1.2/netif/ppp/upap.c +++ /dev/null @@ -1,677 +0,0 @@ -/* - * upap.c - User/Password Authentication Protocol. - * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && PAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -/* - * @todo: - */ - -#if 0 /* UNUSED */ -#include -#include -#endif /* UNUSED */ - -#include "netif/ppp/ppp_impl.h" - -#include "netif/ppp/upap.h" - -#if PPP_OPTIONS -/* - * Command-line options. - */ -static option_t pap_option_list[] = { - { "hide-password", o_bool, &hide_password, - "Don't output passwords to log", OPT_PRIO | 1 }, - { "show-password", o_bool, &hide_password, - "Show password string in debug log messages", OPT_PRIOSUB | 0 }, - - { "pap-restart", o_int, &upap[0].us_timeouttime, - "Set retransmit timeout for PAP", OPT_PRIO }, - { "pap-max-authreq", o_int, &upap[0].us_maxtransmits, - "Set max number of transmissions for auth-reqs", OPT_PRIO }, - { "pap-timeout", o_int, &upap[0].us_reqtimeout, - "Set time limit for peer PAP authentication", OPT_PRIO }, - - { NULL } -}; -#endif /* PPP_OPTIONS */ - -/* - * Protocol entry points. - */ -static void upap_init(ppp_pcb *pcb); -static void upap_lowerup(ppp_pcb *pcb); -static void upap_lowerdown(ppp_pcb *pcb); -static void upap_input(ppp_pcb *pcb, u_char *inpacket, int l); -static void upap_protrej(ppp_pcb *pcb); -#if PRINTPKT_SUPPORT -static int upap_printpkt(const u_char *p, int plen, void (*printer) (void *, const char *, ...), void *arg); -#endif /* PRINTPKT_SUPPORT */ - -const struct protent pap_protent = { - PPP_PAP, - upap_init, - upap_input, - upap_protrej, - upap_lowerup, - upap_lowerdown, - NULL, - NULL, -#if PRINTPKT_SUPPORT - upap_printpkt, -#endif /* PRINTPKT_SUPPORT */ -#if PPP_DATAINPUT - NULL, -#endif /* PPP_DATAINPUT */ -#if PRINTPKT_SUPPORT - "PAP", - NULL, -#endif /* PRINTPKT_SUPPORT */ -#if PPP_OPTIONS - pap_option_list, - NULL, -#endif /* PPP_OPTIONS */ -#if DEMAND_SUPPORT - NULL, - NULL -#endif /* DEMAND_SUPPORT */ -}; - -static void upap_timeout(void *arg); -#if PPP_SERVER -static void upap_reqtimeout(void *arg); -static void upap_rauthreq(ppp_pcb *pcb, u_char *inp, int id, int len); -#endif /* PPP_SERVER */ -static void upap_rauthack(ppp_pcb *pcb, u_char *inp, int id, int len); -static void upap_rauthnak(ppp_pcb *pcb, u_char *inp, int id, int len); -static void upap_sauthreq(ppp_pcb *pcb); -#if PPP_SERVER -static void upap_sresp(ppp_pcb *pcb, u_char code, u_char id, const char *msg, int msglen); -#endif /* PPP_SERVER */ - - -/* - * upap_init - Initialize a UPAP unit. - */ -static void upap_init(ppp_pcb *pcb) { - pcb->upap.us_user = NULL; - pcb->upap.us_userlen = 0; - pcb->upap.us_passwd = NULL; - pcb->upap.us_passwdlen = 0; - pcb->upap.us_clientstate = UPAPCS_INITIAL; -#if PPP_SERVER - pcb->upap.us_serverstate = UPAPSS_INITIAL; -#endif /* PPP_SERVER */ - pcb->upap.us_id = 0; -} - - -/* - * upap_authwithpeer - Authenticate us with our peer (start client). - * - * Set new state and send authenticate's. - */ -void upap_authwithpeer(ppp_pcb *pcb, const char *user, const char *password) { - - if(!user || !password) - return; - - /* Save the username and password we're given */ - pcb->upap.us_user = user; - pcb->upap.us_userlen = (u8_t)LWIP_MIN(strlen(user), 0xff); - pcb->upap.us_passwd = password; - pcb->upap.us_passwdlen = (u8_t)LWIP_MIN(strlen(password), 0xff); - pcb->upap.us_transmits = 0; - - /* Lower layer up yet? */ - if (pcb->upap.us_clientstate == UPAPCS_INITIAL || - pcb->upap.us_clientstate == UPAPCS_PENDING) { - pcb->upap.us_clientstate = UPAPCS_PENDING; - return; - } - - upap_sauthreq(pcb); /* Start protocol */ -} - -#if PPP_SERVER -/* - * upap_authpeer - Authenticate our peer (start server). - * - * Set new state. - */ -void upap_authpeer(ppp_pcb *pcb) { - - /* Lower layer up yet? */ - if (pcb->upap.us_serverstate == UPAPSS_INITIAL || - pcb->upap.us_serverstate == UPAPSS_PENDING) { - pcb->upap.us_serverstate = UPAPSS_PENDING; - return; - } - - pcb->upap.us_serverstate = UPAPSS_LISTEN; - if (pcb->settings.pap_req_timeout > 0) - TIMEOUT(upap_reqtimeout, pcb, pcb->settings.pap_req_timeout); -} -#endif /* PPP_SERVER */ - -/* - * upap_timeout - Retransmission timer for sending auth-reqs expired. - */ -static void upap_timeout(void *arg) { - ppp_pcb *pcb = (ppp_pcb*)arg; - - if (pcb->upap.us_clientstate != UPAPCS_AUTHREQ) - return; - - if (pcb->upap.us_transmits >= pcb->settings.pap_max_transmits) { - /* give up in disgust */ - ppp_error("No response to PAP authenticate-requests"); - pcb->upap.us_clientstate = UPAPCS_BADAUTH; - auth_withpeer_fail(pcb, PPP_PAP); - return; - } - - upap_sauthreq(pcb); /* Send Authenticate-Request */ -} - - -#if PPP_SERVER -/* - * upap_reqtimeout - Give up waiting for the peer to send an auth-req. - */ -static void upap_reqtimeout(void *arg) { - ppp_pcb *pcb = (ppp_pcb*)arg; - - if (pcb->upap.us_serverstate != UPAPSS_LISTEN) - return; /* huh?? */ - - auth_peer_fail(pcb, PPP_PAP); - pcb->upap.us_serverstate = UPAPSS_BADAUTH; -} -#endif /* PPP_SERVER */ - - -/* - * upap_lowerup - The lower layer is up. - * - * Start authenticating if pending. - */ -static void upap_lowerup(ppp_pcb *pcb) { - - if (pcb->upap.us_clientstate == UPAPCS_INITIAL) - pcb->upap.us_clientstate = UPAPCS_CLOSED; - else if (pcb->upap.us_clientstate == UPAPCS_PENDING) { - upap_sauthreq(pcb); /* send an auth-request */ - } - -#if PPP_SERVER - if (pcb->upap.us_serverstate == UPAPSS_INITIAL) - pcb->upap.us_serverstate = UPAPSS_CLOSED; - else if (pcb->upap.us_serverstate == UPAPSS_PENDING) { - pcb->upap.us_serverstate = UPAPSS_LISTEN; - if (pcb->settings.pap_req_timeout > 0) - TIMEOUT(upap_reqtimeout, pcb, pcb->settings.pap_req_timeout); - } -#endif /* PPP_SERVER */ -} - - -/* - * upap_lowerdown - The lower layer is down. - * - * Cancel all timeouts. - */ -static void upap_lowerdown(ppp_pcb *pcb) { - - if (pcb->upap.us_clientstate == UPAPCS_AUTHREQ) /* Timeout pending? */ - UNTIMEOUT(upap_timeout, pcb); /* Cancel timeout */ -#if PPP_SERVER - if (pcb->upap.us_serverstate == UPAPSS_LISTEN && pcb->settings.pap_req_timeout > 0) - UNTIMEOUT(upap_reqtimeout, pcb); -#endif /* PPP_SERVER */ - - pcb->upap.us_clientstate = UPAPCS_INITIAL; -#if PPP_SERVER - pcb->upap.us_serverstate = UPAPSS_INITIAL; -#endif /* PPP_SERVER */ -} - - -/* - * upap_protrej - Peer doesn't speak this protocol. - * - * This shouldn't happen. In any case, pretend lower layer went down. - */ -static void upap_protrej(ppp_pcb *pcb) { - - if (pcb->upap.us_clientstate == UPAPCS_AUTHREQ) { - ppp_error("PAP authentication failed due to protocol-reject"); - auth_withpeer_fail(pcb, PPP_PAP); - } -#if PPP_SERVER - if (pcb->upap.us_serverstate == UPAPSS_LISTEN) { - ppp_error("PAP authentication of peer failed (protocol-reject)"); - auth_peer_fail(pcb, PPP_PAP); - } -#endif /* PPP_SERVER */ - upap_lowerdown(pcb); -} - - -/* - * upap_input - Input UPAP packet. - */ -static void upap_input(ppp_pcb *pcb, u_char *inpacket, int l) { - u_char *inp; - u_char code, id; - int len; - - /* - * Parse header (code, id and length). - * If packet too short, drop it. - */ - inp = inpacket; - if (l < UPAP_HEADERLEN) { - UPAPDEBUG(("pap_input: rcvd short header.")); - return; - } - GETCHAR(code, inp); - GETCHAR(id, inp); - GETSHORT(len, inp); - if (len < UPAP_HEADERLEN) { - UPAPDEBUG(("pap_input: rcvd illegal length.")); - return; - } - if (len > l) { - UPAPDEBUG(("pap_input: rcvd short packet.")); - return; - } - len -= UPAP_HEADERLEN; - - /* - * Action depends on code. - */ - switch (code) { - case UPAP_AUTHREQ: -#if PPP_SERVER - upap_rauthreq(pcb, inp, id, len); -#endif /* PPP_SERVER */ - break; - - case UPAP_AUTHACK: - upap_rauthack(pcb, inp, id, len); - break; - - case UPAP_AUTHNAK: - upap_rauthnak(pcb, inp, id, len); - break; - - default: /* XXX Need code reject */ - break; - } -} - -#if PPP_SERVER -/* - * upap_rauth - Receive Authenticate. - */ -static void upap_rauthreq(ppp_pcb *pcb, u_char *inp, int id, int len) { - u_char ruserlen, rpasswdlen; - char *ruser; - char *rpasswd; - char rhostname[256]; - int retcode; - const char *msg; - int msglen; - - if (pcb->upap.us_serverstate < UPAPSS_LISTEN) - return; - - /* - * If we receive a duplicate authenticate-request, we are - * supposed to return the same status as for the first request. - */ - if (pcb->upap.us_serverstate == UPAPSS_OPEN) { - upap_sresp(pcb, UPAP_AUTHACK, id, "", 0); /* return auth-ack */ - return; - } - if (pcb->upap.us_serverstate == UPAPSS_BADAUTH) { - upap_sresp(pcb, UPAP_AUTHNAK, id, "", 0); /* return auth-nak */ - return; - } - - /* - * Parse user/passwd. - */ - if (len < 1) { - UPAPDEBUG(("pap_rauth: rcvd short packet.")); - return; - } - GETCHAR(ruserlen, inp); - len -= sizeof (u_char) + ruserlen + sizeof (u_char); - if (len < 0) { - UPAPDEBUG(("pap_rauth: rcvd short packet.")); - return; - } - ruser = (char *) inp; - INCPTR(ruserlen, inp); - GETCHAR(rpasswdlen, inp); - if (len < rpasswdlen) { - UPAPDEBUG(("pap_rauth: rcvd short packet.")); - return; - } - - rpasswd = (char *) inp; - - /* - * Check the username and password given. - */ - retcode = UPAP_AUTHNAK; - if (auth_check_passwd(pcb, ruser, ruserlen, rpasswd, rpasswdlen, &msg, &msglen)) { - retcode = UPAP_AUTHACK; - } - BZERO(rpasswd, rpasswdlen); - -#if 0 /* UNUSED */ - /* - * Check remote number authorization. A plugin may have filled in - * the remote number or added an allowed number, and rather than - * return an authenticate failure, is leaving it for us to verify. - */ - if (retcode == UPAP_AUTHACK) { - if (!auth_number()) { - /* We do not want to leak info about the pap result. */ - retcode = UPAP_AUTHNAK; /* XXX exit value will be "wrong" */ - warn("calling number %q is not authorized", remote_number); - } - } - - msglen = strlen(msg); - if (msglen > 255) - msglen = 255; -#endif /* UNUSED */ - - upap_sresp(pcb, retcode, id, msg, msglen); - - /* Null terminate and clean remote name. */ - ppp_slprintf(rhostname, sizeof(rhostname), "%.*v", ruserlen, ruser); - - if (retcode == UPAP_AUTHACK) { - pcb->upap.us_serverstate = UPAPSS_OPEN; - ppp_notice("PAP peer authentication succeeded for %q", rhostname); - auth_peer_success(pcb, PPP_PAP, 0, ruser, ruserlen); - } else { - pcb->upap.us_serverstate = UPAPSS_BADAUTH; - ppp_warn("PAP peer authentication failed for %q", rhostname); - auth_peer_fail(pcb, PPP_PAP); - } - - if (pcb->settings.pap_req_timeout > 0) - UNTIMEOUT(upap_reqtimeout, pcb); -} -#endif /* PPP_SERVER */ - -/* - * upap_rauthack - Receive Authenticate-Ack. - */ -static void upap_rauthack(ppp_pcb *pcb, u_char *inp, int id, int len) { - u_char msglen; - char *msg; - LWIP_UNUSED_ARG(id); - - if (pcb->upap.us_clientstate != UPAPCS_AUTHREQ) /* XXX */ - return; - - /* - * Parse message. - */ - if (len < 1) { - UPAPDEBUG(("pap_rauthack: ignoring missing msg-length.")); - } else { - GETCHAR(msglen, inp); - if (msglen > 0) { - len -= sizeof (u_char); - if (len < msglen) { - UPAPDEBUG(("pap_rauthack: rcvd short packet.")); - return; - } - msg = (char *) inp; - PRINTMSG(msg, msglen); - } - } - - pcb->upap.us_clientstate = UPAPCS_OPEN; - - auth_withpeer_success(pcb, PPP_PAP, 0); -} - - -/* - * upap_rauthnak - Receive Authenticate-Nak. - */ -static void upap_rauthnak(ppp_pcb *pcb, u_char *inp, int id, int len) { - u_char msglen; - char *msg; - LWIP_UNUSED_ARG(id); - - if (pcb->upap.us_clientstate != UPAPCS_AUTHREQ) /* XXX */ - return; - - /* - * Parse message. - */ - if (len < 1) { - UPAPDEBUG(("pap_rauthnak: ignoring missing msg-length.")); - } else { - GETCHAR(msglen, inp); - if (msglen > 0) { - len -= sizeof (u_char); - if (len < msglen) { - UPAPDEBUG(("pap_rauthnak: rcvd short packet.")); - return; - } - msg = (char *) inp; - PRINTMSG(msg, msglen); - } - } - - pcb->upap.us_clientstate = UPAPCS_BADAUTH; - - ppp_error("PAP authentication failed"); - auth_withpeer_fail(pcb, PPP_PAP); -} - - -/* - * upap_sauthreq - Send an Authenticate-Request. - */ -static void upap_sauthreq(ppp_pcb *pcb) { - struct pbuf *p; - u_char *outp; - int outlen; - - outlen = UPAP_HEADERLEN + 2 * sizeof (u_char) + - pcb->upap.us_userlen + pcb->upap.us_passwdlen; - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN +outlen), PPP_CTRL_PBUF_TYPE); - if(NULL == p) - return; - if(p->tot_len != p->len) { - pbuf_free(p); - return; - } - - outp = (u_char*)p->payload; - MAKEHEADER(outp, PPP_PAP); - - PUTCHAR(UPAP_AUTHREQ, outp); - PUTCHAR(++pcb->upap.us_id, outp); - PUTSHORT(outlen, outp); - PUTCHAR(pcb->upap.us_userlen, outp); - MEMCPY(outp, pcb->upap.us_user, pcb->upap.us_userlen); - INCPTR(pcb->upap.us_userlen, outp); - PUTCHAR(pcb->upap.us_passwdlen, outp); - MEMCPY(outp, pcb->upap.us_passwd, pcb->upap.us_passwdlen); - - ppp_write(pcb, p); - - TIMEOUT(upap_timeout, pcb, pcb->settings.pap_timeout_time); - ++pcb->upap.us_transmits; - pcb->upap.us_clientstate = UPAPCS_AUTHREQ; -} - -#if PPP_SERVER -/* - * upap_sresp - Send a response (ack or nak). - */ -static void upap_sresp(ppp_pcb *pcb, u_char code, u_char id, const char *msg, int msglen) { - struct pbuf *p; - u_char *outp; - int outlen; - - outlen = UPAP_HEADERLEN + sizeof (u_char) + msglen; - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN +outlen), PPP_CTRL_PBUF_TYPE); - if(NULL == p) - return; - if(p->tot_len != p->len) { - pbuf_free(p); - return; - } - - outp = (u_char*)p->payload; - MAKEHEADER(outp, PPP_PAP); - - PUTCHAR(code, outp); - PUTCHAR(id, outp); - PUTSHORT(outlen, outp); - PUTCHAR(msglen, outp); - MEMCPY(outp, msg, msglen); - - ppp_write(pcb, p); -} -#endif /* PPP_SERVER */ - -#if PRINTPKT_SUPPORT -/* - * upap_printpkt - print the contents of a PAP packet. - */ -static const char* const upap_codenames[] = { - "AuthReq", "AuthAck", "AuthNak" -}; - -static int upap_printpkt(const u_char *p, int plen, void (*printer) (void *, const char *, ...), void *arg) { - int code, id, len; - int mlen, ulen, wlen; - const u_char *user, *pwd, *msg; - const u_char *pstart; - - if (plen < UPAP_HEADERLEN) - return 0; - pstart = p; - GETCHAR(code, p); - GETCHAR(id, p); - GETSHORT(len, p); - if (len < UPAP_HEADERLEN || len > plen) - return 0; - - if (code >= 1 && code <= (int)LWIP_ARRAYSIZE(upap_codenames)) - printer(arg, " %s", upap_codenames[code-1]); - else - printer(arg, " code=0x%x", code); - printer(arg, " id=0x%x", id); - len -= UPAP_HEADERLEN; - switch (code) { - case UPAP_AUTHREQ: - if (len < 1) - break; - ulen = p[0]; - if (len < ulen + 2) - break; - wlen = p[ulen + 1]; - if (len < ulen + wlen + 2) - break; - user = (const u_char *) (p + 1); - pwd = (const u_char *) (p + ulen + 2); - p += ulen + wlen + 2; - len -= ulen + wlen + 2; - printer(arg, " user="); - ppp_print_string(user, ulen, printer, arg); - printer(arg, " password="); -/* FIXME: require ppp_pcb struct as printpkt() argument */ -#if 0 - if (!pcb->settings.hide_password) -#endif - ppp_print_string(pwd, wlen, printer, arg); -#if 0 - else - printer(arg, ""); -#endif - break; - case UPAP_AUTHACK: - case UPAP_AUTHNAK: - if (len < 1) - break; - mlen = p[0]; - if (len < mlen + 1) - break; - msg = (const u_char *) (p + 1); - p += mlen + 1; - len -= mlen + 1; - printer(arg, " "); - ppp_print_string(msg, mlen, printer, arg); - break; - default: - break; - } - - /* print the rest of the bytes in the packet */ - for (; len > 0; --len) { - GETCHAR(code, p); - printer(arg, " %.2x", code); - } - - return p - pstart; -} -#endif /* PRINTPKT_SUPPORT */ - -#endif /* PPP_SUPPORT && PAP_SUPPORT */ diff --git a/third-party/lwip-2.1.2/netif/ppp/utils.c b/third-party/lwip-2.1.2/netif/ppp/utils.c deleted file mode 100644 index f1366dae..00000000 --- a/third-party/lwip-2.1.2/netif/ppp/utils.c +++ /dev/null @@ -1,957 +0,0 @@ -/* - * utils.c - various utility functions used in pppd. - * - * Copyright (c) 1999-2002 Paul Mackerras. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 3. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#if 0 /* UNUSED */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef SVR4 -#include -#endif -#endif /* UNUSED */ - -#include "netif/ppp/ppp_impl.h" - -#include "netif/ppp/fsm.h" -#include "netif/ppp/lcp.h" - -#if defined(SUNOS4) -extern char *strerror(); -#endif - -static void ppp_logit(int level, const char *fmt, va_list args); -static void ppp_log_write(int level, char *buf); -#if PRINTPKT_SUPPORT -static void ppp_vslp_printer(void *arg, const char *fmt, ...); -static void ppp_format_packet(const u_char *p, int len, - void (*printer) (void *, const char *, ...), void *arg); - -struct buffer_info { - char *ptr; - int len; -}; -#endif /* PRINTPKT_SUPPORT */ - -/* - * ppp_strlcpy - like strcpy/strncpy, doesn't overflow destination buffer, - * always leaves destination null-terminated (for len > 0). - */ -size_t ppp_strlcpy(char *dest, const char *src, size_t len) { - size_t ret = strlen(src); - - if (len != 0) { - if (ret < len) - strcpy(dest, src); - else { - strncpy(dest, src, len - 1); - dest[len-1] = 0; - } - } - return ret; -} - -/* - * ppp_strlcat - like strcat/strncat, doesn't overflow destination buffer, - * always leaves destination null-terminated (for len > 0). - */ -size_t ppp_strlcat(char *dest, const char *src, size_t len) { - size_t dlen = strlen(dest); - - return dlen + ppp_strlcpy(dest + dlen, src, (len > dlen? len - dlen: 0)); -} - - -/* - * ppp_slprintf - format a message into a buffer. Like sprintf except we - * also specify the length of the output buffer, and we handle - * %m (error message), %v (visible string), - * %q (quoted string), %t (current time) and %I (IP address) formats. - * Doesn't do floating-point formats. - * Returns the number of chars put into buf. - */ -int ppp_slprintf(char *buf, int buflen, const char *fmt, ...) { - va_list args; - int n; - - va_start(args, fmt); - n = ppp_vslprintf(buf, buflen, fmt, args); - va_end(args); - return n; -} - -/* - * ppp_vslprintf - like ppp_slprintf, takes a va_list instead of a list of args. - */ -#define OUTCHAR(c) (buflen > 0? (--buflen, *buf++ = (c)): 0) - -int ppp_vslprintf(char *buf, int buflen, const char *fmt, va_list args) { - int c, i, n; - int width, prec, fillch; - int base, len, neg, quoted; - unsigned long val = 0; - const char *f; - char *str, *buf0; - const unsigned char *p; - char num[32]; -#if 0 /* need port */ - time_t t; -#endif /* need port */ - u32_t ip; - static char hexchars[] = "0123456789abcdef"; -#if PRINTPKT_SUPPORT - struct buffer_info bufinfo; -#endif /* PRINTPKT_SUPPORT */ - - buf0 = buf; - --buflen; - while (buflen > 0) { - for (f = fmt; *f != '%' && *f != 0; ++f) - ; - if (f > fmt) { - len = f - fmt; - if (len > buflen) - len = buflen; - memcpy(buf, fmt, len); - buf += len; - buflen -= len; - fmt = f; - } - if (*fmt == 0) - break; - c = *++fmt; - width = 0; - prec = -1; - fillch = ' '; - if (c == '0') { - fillch = '0'; - c = *++fmt; - } - if (c == '*') { - width = va_arg(args, int); - c = *++fmt; - } else { - while (lwip_isdigit(c)) { - width = width * 10 + c - '0'; - c = *++fmt; - } - } - if (c == '.') { - c = *++fmt; - if (c == '*') { - prec = va_arg(args, int); - c = *++fmt; - } else { - prec = 0; - while (lwip_isdigit(c)) { - prec = prec * 10 + c - '0'; - c = *++fmt; - } - } - } - str = 0; - base = 0; - neg = 0; - ++fmt; - switch (c) { - case 'l': - c = *fmt++; - switch (c) { - case 'd': - val = va_arg(args, long); - if ((long)val < 0) { - neg = 1; - val = (unsigned long)-(long)val; - } - base = 10; - break; - case 'u': - val = va_arg(args, unsigned long); - base = 10; - break; - default: - OUTCHAR('%'); - OUTCHAR('l'); - --fmt; /* so %lz outputs %lz etc. */ - continue; - } - break; - case 'd': - i = va_arg(args, int); - if (i < 0) { - neg = 1; - val = -i; - } else - val = i; - base = 10; - break; - case 'u': - val = va_arg(args, unsigned int); - base = 10; - break; - case 'o': - val = va_arg(args, unsigned int); - base = 8; - break; - case 'x': - case 'X': - val = va_arg(args, unsigned int); - base = 16; - break; -#if 0 /* unused (and wrong on LLP64 systems) */ - case 'p': - val = (unsigned long) va_arg(args, void *); - base = 16; - neg = 2; - break; -#endif /* unused (and wrong on LLP64 systems) */ - case 's': - str = va_arg(args, char *); - break; - case 'c': - num[0] = va_arg(args, int); - num[1] = 0; - str = num; - break; -#if 0 /* do we always have strerror() in embedded ? */ - case 'm': - str = strerror(errno); - break; -#endif /* do we always have strerror() in embedded ? */ - case 'I': - ip = va_arg(args, u32_t); - ip = lwip_ntohl(ip); - ppp_slprintf(num, sizeof(num), "%d.%d.%d.%d", (ip >> 24) & 0xff, - (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff); - str = num; - break; -#if 0 /* need port */ - case 't': - time(&t); - str = ctime(&t); - str += 4; /* chop off the day name */ - str[15] = 0; /* chop off year and newline */ - break; -#endif /* need port */ - case 'v': /* "visible" string */ - case 'q': /* quoted string */ - quoted = c == 'q'; - p = va_arg(args, unsigned char *); - if (p == NULL) - p = (const unsigned char *)""; - if (fillch == '0' && prec >= 0) { - n = prec; - } else { - n = strlen((const char *)p); - if (prec >= 0 && n > prec) - n = prec; - } - while (n > 0 && buflen > 0) { - c = *p++; - --n; - if (!quoted && c >= 0x80) { - OUTCHAR('M'); - OUTCHAR('-'); - c -= 0x80; - } - if (quoted && (c == '"' || c == '\\')) - OUTCHAR('\\'); - if (c < 0x20 || (0x7f <= c && c < 0xa0)) { - if (quoted) { - OUTCHAR('\\'); - switch (c) { - case '\t': OUTCHAR('t'); break; - case '\n': OUTCHAR('n'); break; - case '\b': OUTCHAR('b'); break; - case '\f': OUTCHAR('f'); break; - default: - OUTCHAR('x'); - OUTCHAR(hexchars[c >> 4]); - OUTCHAR(hexchars[c & 0xf]); - } - } else { - if (c == '\t') - OUTCHAR(c); - else { - OUTCHAR('^'); - OUTCHAR(c ^ 0x40); - } - } - } else - OUTCHAR(c); - } - continue; -#if PRINTPKT_SUPPORT - case 'P': /* print PPP packet */ - bufinfo.ptr = buf; - bufinfo.len = buflen + 1; - p = va_arg(args, unsigned char *); - n = va_arg(args, int); - ppp_format_packet(p, n, ppp_vslp_printer, &bufinfo); - buf = bufinfo.ptr; - buflen = bufinfo.len - 1; - continue; -#endif /* PRINTPKT_SUPPORT */ - case 'B': - p = va_arg(args, unsigned char *); - for (n = prec; n > 0; --n) { - c = *p++; - if (fillch == ' ') - OUTCHAR(' '); - OUTCHAR(hexchars[(c >> 4) & 0xf]); - OUTCHAR(hexchars[c & 0xf]); - } - continue; - default: - *buf++ = '%'; - if (c != '%') - --fmt; /* so %z outputs %z etc. */ - --buflen; - continue; - } - if (base != 0) { - str = num + sizeof(num); - *--str = 0; - while (str > num + neg) { - *--str = hexchars[val % base]; - val = val / base; - if (--prec <= 0 && val == 0) - break; - } - switch (neg) { - case 1: - *--str = '-'; - break; - case 2: - *--str = 'x'; - *--str = '0'; - break; - default: - break; - } - len = num + sizeof(num) - 1 - str; - } else { - len = strlen(str); - if (prec >= 0 && len > prec) - len = prec; - } - if (width > 0) { - if (width > buflen) - width = buflen; - if ((n = width - len) > 0) { - buflen -= n; - for (; n > 0; --n) - *buf++ = fillch; - } - } - if (len > buflen) - len = buflen; - memcpy(buf, str, len); - buf += len; - buflen -= len; - } - *buf = 0; - return buf - buf0; -} - -#if PRINTPKT_SUPPORT -/* - * vslp_printer - used in processing a %P format - */ -static void ppp_vslp_printer(void *arg, const char *fmt, ...) { - int n; - va_list pvar; - struct buffer_info *bi; - - va_start(pvar, fmt); - bi = (struct buffer_info *) arg; - n = ppp_vslprintf(bi->ptr, bi->len, fmt, pvar); - va_end(pvar); - - bi->ptr += n; - bi->len -= n; -} -#endif /* PRINTPKT_SUPPORT */ - -#if 0 /* UNUSED */ -/* - * log_packet - format a packet and log it. - */ - -void -log_packet(p, len, prefix, level) - u_char *p; - int len; - char *prefix; - int level; -{ - init_pr_log(prefix, level); - ppp_format_packet(p, len, pr_log, &level); - end_pr_log(); -} -#endif /* UNUSED */ - -#if PRINTPKT_SUPPORT -/* - * ppp_format_packet - make a readable representation of a packet, - * calling `printer(arg, format, ...)' to output it. - */ -static void ppp_format_packet(const u_char *p, int len, - void (*printer) (void *, const char *, ...), void *arg) { - int i, n; - u_short proto; - const struct protent *protp; - - if (len >= 2) { - GETSHORT(proto, p); - len -= 2; - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (proto == protp->protocol) - break; - if (protp != NULL) { - printer(arg, "[%s", protp->name); - n = (*protp->printpkt)(p, len, printer, arg); - printer(arg, "]"); - p += n; - len -= n; - } else { - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (proto == (protp->protocol & ~0x8000)) - break; - if (protp != 0 && protp->data_name != 0) { - printer(arg, "[%s data]", protp->data_name); - if (len > 8) - printer(arg, "%.8B ...", p); - else - printer(arg, "%.*B", len, p); - len = 0; - } else - printer(arg, "[proto=0x%x]", proto); - } - } - - if (len > 32) - printer(arg, "%.32B ...", p); - else - printer(arg, "%.*B", len, p); -} -#endif /* PRINTPKT_SUPPORT */ - -#if 0 /* UNUSED */ -/* - * init_pr_log, end_pr_log - initialize and finish use of pr_log. - */ - -static char line[256]; /* line to be logged accumulated here */ -static char *linep; /* current pointer within line */ -static int llevel; /* level for logging */ - -void -init_pr_log(prefix, level) - const char *prefix; - int level; -{ - linep = line; - if (prefix != NULL) { - ppp_strlcpy(line, prefix, sizeof(line)); - linep = line + strlen(line); - } - llevel = level; -} - -void -end_pr_log() -{ - if (linep != line) { - *linep = 0; - ppp_log_write(llevel, line); - } -} - -/* - * pr_log - printer routine for outputting to log - */ -void -pr_log (void *arg, const char *fmt, ...) -{ - int l, n; - va_list pvar; - char *p, *eol; - char buf[256]; - - va_start(pvar, fmt); - n = ppp_vslprintf(buf, sizeof(buf), fmt, pvar); - va_end(pvar); - - p = buf; - eol = strchr(buf, '\n'); - if (linep != line) { - l = (eol == NULL)? n: eol - buf; - if (linep + l < line + sizeof(line)) { - if (l > 0) { - memcpy(linep, buf, l); - linep += l; - } - if (eol == NULL) - return; - p = eol + 1; - eol = strchr(p, '\n'); - } - *linep = 0; - ppp_log_write(llevel, line); - linep = line; - } - - while (eol != NULL) { - *eol = 0; - ppp_log_write(llevel, p); - p = eol + 1; - eol = strchr(p, '\n'); - } - - /* assumes sizeof(buf) <= sizeof(line) */ - l = buf + n - p; - if (l > 0) { - memcpy(line, p, n); - linep = line + l; - } -} -#endif /* UNUSED */ - -/* - * ppp_print_string - print a readable representation of a string using - * printer. - */ -void ppp_print_string(const u_char *p, int len, void (*printer) (void *, const char *, ...), void *arg) { - int c; - - printer(arg, "\""); - for (; len > 0; --len) { - c = *p++; - if (' ' <= c && c <= '~') { - if (c == '\\' || c == '"') - printer(arg, "\\"); - printer(arg, "%c", c); - } else { - switch (c) { - case '\n': - printer(arg, "\\n"); - break; - case '\r': - printer(arg, "\\r"); - break; - case '\t': - printer(arg, "\\t"); - break; - default: - printer(arg, "\\%.3o", (u8_t)c); - /* no break */ - } - } - } - printer(arg, "\""); -} - -/* - * ppp_logit - does the hard work for fatal et al. - */ -static void ppp_logit(int level, const char *fmt, va_list args) { - char buf[1024]; - - ppp_vslprintf(buf, sizeof(buf), fmt, args); - ppp_log_write(level, buf); -} - -static void ppp_log_write(int level, char *buf) { - LWIP_UNUSED_ARG(level); /* necessary if PPPDEBUG is defined to an empty function */ - LWIP_UNUSED_ARG(buf); - PPPDEBUG(level, ("%s\n", buf) ); -#if 0 - if (log_to_fd >= 0 && (level != LOG_DEBUG || debug)) { - int n = strlen(buf); - - if (n > 0 && buf[n-1] == '\n') - --n; - if (write(log_to_fd, buf, n) != n - || write(log_to_fd, "\n", 1) != 1) - log_to_fd = -1; - } -#endif -} - -/* - * ppp_fatal - log an error message and die horribly. - */ -void ppp_fatal(const char *fmt, ...) { - va_list pvar; - - va_start(pvar, fmt); - ppp_logit(LOG_ERR, fmt, pvar); - va_end(pvar); - - LWIP_ASSERT("ppp_fatal", 0); /* as promised */ -} - -/* - * ppp_error - log an error message. - */ -void ppp_error(const char *fmt, ...) { - va_list pvar; - - va_start(pvar, fmt); - ppp_logit(LOG_ERR, fmt, pvar); - va_end(pvar); -#if 0 /* UNUSED */ - ++error_count; -#endif /* UNUSED */ -} - -/* - * ppp_warn - log a warning message. - */ -void ppp_warn(const char *fmt, ...) { - va_list pvar; - - va_start(pvar, fmt); - ppp_logit(LOG_WARNING, fmt, pvar); - va_end(pvar); -} - -/* - * ppp_notice - log a notice-level message. - */ -void ppp_notice(const char *fmt, ...) { - va_list pvar; - - va_start(pvar, fmt); - ppp_logit(LOG_NOTICE, fmt, pvar); - va_end(pvar); -} - -/* - * ppp_info - log an informational message. - */ -void ppp_info(const char *fmt, ...) { - va_list pvar; - - va_start(pvar, fmt); - ppp_logit(LOG_INFO, fmt, pvar); - va_end(pvar); -} - -/* - * ppp_dbglog - log a debug message. - */ -void ppp_dbglog(const char *fmt, ...) { - va_list pvar; - - va_start(pvar, fmt); - ppp_logit(LOG_DEBUG, fmt, pvar); - va_end(pvar); -} - -#if PRINTPKT_SUPPORT -/* - * ppp_dump_packet - print out a packet in readable form if it is interesting. - * Assumes len >= PPP_HDRLEN. - */ -void ppp_dump_packet(ppp_pcb *pcb, const char *tag, unsigned char *p, int len) { - int proto; - - /* - * don't print data packets, i.e. IPv4, IPv6, VJ, and compressed packets. - */ - proto = (p[0] << 8) + p[1]; - if (proto < 0xC000 && (proto & ~0x8000) == proto) - return; - - /* - * don't print valid LCP echo request/reply packets if the link is up. - */ - if (proto == PPP_LCP && pcb->phase == PPP_PHASE_RUNNING && len >= 2 + HEADERLEN) { - unsigned char *lcp = p + 2; - int l = (lcp[2] << 8) + lcp[3]; - - if ((lcp[0] == ECHOREQ || lcp[0] == ECHOREP) - && l >= HEADERLEN && l <= len - 2) - return; - } - - ppp_dbglog("%s %P", tag, p, len); -} -#endif /* PRINTPKT_SUPPORT */ - -#if 0 /* Unused */ - -/* - * complete_read - read a full `count' bytes from fd, - * unless end-of-file or an error other than EINTR is encountered. - */ -ssize_t -complete_read(int fd, void *buf, size_t count) -{ - size_t done; - ssize_t nb; - char *ptr = buf; - - for (done = 0; done < count; ) { - nb = read(fd, ptr, count - done); - if (nb < 0) { - if (errno == EINTR) - continue; - return -1; - } - if (nb == 0) - break; - done += nb; - ptr += nb; - } - return done; -} - -/* Procedures for locking the serial device using a lock file. */ -#ifndef LOCK_DIR -#ifdef __linux__ -#define LOCK_DIR "/var/lock" -#else -#ifdef SVR4 -#define LOCK_DIR "/var/spool/locks" -#else -#define LOCK_DIR "/var/spool/lock" -#endif -#endif -#endif /* LOCK_DIR */ - -static char lock_file[MAXPATHLEN]; - -/* - * lock - create a lock file for the named device - */ -int -lock(dev) - char *dev; -{ -#ifdef LOCKLIB - int result; - - result = mklock (dev, (void *) 0); - if (result == 0) { - ppp_strlcpy(lock_file, dev, sizeof(lock_file)); - return 0; - } - - if (result > 0) - ppp_notice("Device %s is locked by pid %d", dev, result); - else - ppp_error("Can't create lock file %s", lock_file); - return -1; - -#else /* LOCKLIB */ - - char lock_buffer[12]; - int fd, pid, n; - -#ifdef SVR4 - struct stat sbuf; - - if (stat(dev, &sbuf) < 0) { - ppp_error("Can't get device number for %s: %m", dev); - return -1; - } - if ((sbuf.st_mode & S_IFMT) != S_IFCHR) { - ppp_error("Can't lock %s: not a character device", dev); - return -1; - } - ppp_slprintf(lock_file, sizeof(lock_file), "%s/LK.%03d.%03d.%03d", - LOCK_DIR, major(sbuf.st_dev), - major(sbuf.st_rdev), minor(sbuf.st_rdev)); -#else - char *p; - char lockdev[MAXPATHLEN]; - - if ((p = strstr(dev, "dev/")) != NULL) { - dev = p + 4; - strncpy(lockdev, dev, MAXPATHLEN-1); - lockdev[MAXPATHLEN-1] = 0; - while ((p = strrchr(lockdev, '/')) != NULL) { - *p = '_'; - } - dev = lockdev; - } else - if ((p = strrchr(dev, '/')) != NULL) - dev = p + 1; - - ppp_slprintf(lock_file, sizeof(lock_file), "%s/LCK..%s", LOCK_DIR, dev); -#endif - - while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) { - if (errno != EEXIST) { - ppp_error("Can't create lock file %s: %m", lock_file); - break; - } - - /* Read the lock file to find out who has the device locked. */ - fd = open(lock_file, O_RDONLY, 0); - if (fd < 0) { - if (errno == ENOENT) /* This is just a timing problem. */ - continue; - ppp_error("Can't open existing lock file %s: %m", lock_file); - break; - } -#ifndef LOCK_BINARY - n = read(fd, lock_buffer, 11); -#else - n = read(fd, &pid, sizeof(pid)); -#endif /* LOCK_BINARY */ - close(fd); - fd = -1; - if (n <= 0) { - ppp_error("Can't read pid from lock file %s", lock_file); - break; - } - - /* See if the process still exists. */ -#ifndef LOCK_BINARY - lock_buffer[n] = 0; - pid = atoi(lock_buffer); -#endif /* LOCK_BINARY */ - if (pid == getpid()) - return 1; /* somebody else locked it for us */ - if (pid == 0 - || (kill(pid, 0) == -1 && errno == ESRCH)) { - if (unlink (lock_file) == 0) { - ppp_notice("Removed stale lock on %s (pid %d)", dev, pid); - continue; - } - ppp_warn("Couldn't remove stale lock on %s", dev); - } else - ppp_notice("Device %s is locked by pid %d", dev, pid); - break; - } - - if (fd < 0) { - lock_file[0] = 0; - return -1; - } - - pid = getpid(); -#ifndef LOCK_BINARY - ppp_slprintf(lock_buffer, sizeof(lock_buffer), "%10d\n", pid); - write (fd, lock_buffer, 11); -#else - write(fd, &pid, sizeof (pid)); -#endif - close(fd); - return 0; - -#endif -} - -/* - * relock - called to update our lockfile when we are about to detach, - * thus changing our pid (we fork, the child carries on, and the parent dies). - * Note that this is called by the parent, with pid equal to the pid - * of the child. This avoids a potential race which would exist if - * we had the child rewrite the lockfile (the parent might die first, - * and another process could think the lock was stale if it checked - * between when the parent died and the child rewrote the lockfile). - */ -int -relock(pid) - int pid; -{ -#ifdef LOCKLIB - /* XXX is there a way to do this? */ - return -1; -#else /* LOCKLIB */ - - int fd; - char lock_buffer[12]; - - if (lock_file[0] == 0) - return -1; - fd = open(lock_file, O_WRONLY, 0); - if (fd < 0) { - ppp_error("Couldn't reopen lock file %s: %m", lock_file); - lock_file[0] = 0; - return -1; - } - -#ifndef LOCK_BINARY - ppp_slprintf(lock_buffer, sizeof(lock_buffer), "%10d\n", pid); - write (fd, lock_buffer, 11); -#else - write(fd, &pid, sizeof(pid)); -#endif /* LOCK_BINARY */ - close(fd); - return 0; - -#endif /* LOCKLIB */ -} - -/* - * unlock - remove our lockfile - */ -void -unlock() -{ - if (lock_file[0]) { -#ifdef LOCKLIB - (void) rmlock(lock_file, (void *) 0); -#else - unlink(lock_file); -#endif - lock_file[0] = 0; - } -} - -#endif /* Unused */ - -#endif /* PPP_SUPPORT */ diff --git a/third-party/lwip-2.1.2/netif/ppp/vj.c b/third-party/lwip-2.1.2/netif/ppp/vj.c deleted file mode 100644 index 3fecba69..00000000 --- a/third-party/lwip-2.1.2/netif/ppp/vj.c +++ /dev/null @@ -1,685 +0,0 @@ -/* - * Routines to compress and uncompess tcp packets (for transmission - * over low speed serial lines. - * - * Copyright (c) 1989 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: - * Initial distribution. - * - * Modified June 1993 by Paul Mackerras, paulus@cs.anu.edu.au, - * so that the entire packet being decompressed doesn't have - * to be in contiguous memory (just the compressed header). - * - * Modified March 1998 by Guy Lancaster, glanca@gesn.com, - * for a 16 bit processor. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && VJ_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include "netif/ppp/ppp_impl.h" -#include "netif/ppp/pppdebug.h" - -#include "netif/ppp/vj.h" - -#include - -#if LINK_STATS -#define INCR(counter) ++comp->stats.counter -#else -#define INCR(counter) -#endif - -void -vj_compress_init(struct vjcompress *comp) -{ - u8_t i; - struct cstate *tstate = comp->tstate; - -#if MAX_SLOTS == 0 - memset((char *)comp, 0, sizeof(*comp)); -#endif - comp->maxSlotIndex = MAX_SLOTS - 1; - comp->compressSlot = 0; /* Disable slot ID compression by default. */ - for (i = MAX_SLOTS - 1; i > 0; --i) { - tstate[i].cs_id = i; - tstate[i].cs_next = &tstate[i - 1]; - } - tstate[0].cs_next = &tstate[MAX_SLOTS - 1]; - tstate[0].cs_id = 0; - comp->last_cs = &tstate[0]; - comp->last_recv = 255; - comp->last_xmit = 255; - comp->flags = VJF_TOSS; -} - - -/* ENCODE encodes a number that is known to be non-zero. ENCODEZ - * checks for zero (since zero has to be encoded in the long, 3 byte - * form). - */ -#define ENCODE(n) { \ - if ((u16_t)(n) >= 256) { \ - *cp++ = 0; \ - cp[1] = (u8_t)(n); \ - cp[0] = (u8_t)((n) >> 8); \ - cp += 2; \ - } else { \ - *cp++ = (u8_t)(n); \ - } \ -} -#define ENCODEZ(n) { \ - if ((u16_t)(n) >= 256 || (u16_t)(n) == 0) { \ - *cp++ = 0; \ - cp[1] = (u8_t)(n); \ - cp[0] = (u8_t)((n) >> 8); \ - cp += 2; \ - } else { \ - *cp++ = (u8_t)(n); \ - } \ -} - -#define DECODEL(f) { \ - if (*cp == 0) {\ - u32_t tmp_ = lwip_ntohl(f) + ((cp[1] << 8) | cp[2]); \ - (f) = lwip_htonl(tmp_); \ - cp += 3; \ - } else { \ - u32_t tmp_ = lwip_ntohl(f) + (u32_t)*cp++; \ - (f) = lwip_htonl(tmp_); \ - } \ -} - -#define DECODES(f) { \ - if (*cp == 0) {\ - u16_t tmp_ = lwip_ntohs(f) + (((u16_t)cp[1] << 8) | cp[2]); \ - (f) = lwip_htons(tmp_); \ - cp += 3; \ - } else { \ - u16_t tmp_ = lwip_ntohs(f) + (u16_t)*cp++; \ - (f) = lwip_htons(tmp_); \ - } \ -} - -#define DECODEU(f) { \ - if (*cp == 0) {\ - (f) = lwip_htons(((u16_t)cp[1] << 8) | cp[2]); \ - cp += 3; \ - } else { \ - (f) = lwip_htons((u16_t)*cp++); \ - } \ -} - -/* Helper structures for unaligned *u32_t and *u16_t accesses */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct vj_u32_t { - PACK_STRUCT_FIELD(u32_t v); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct vj_u16_t { - PACK_STRUCT_FIELD(u16_t v); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/* - * vj_compress_tcp - Attempt to do Van Jacobson header compression on a - * packet. This assumes that nb and comp are not null and that the first - * buffer of the chain contains a valid IP header. - * Return the VJ type code indicating whether or not the packet was - * compressed. - */ -u8_t -vj_compress_tcp(struct vjcompress *comp, struct pbuf **pb) -{ - struct pbuf *np = *pb; - struct ip_hdr *ip = (struct ip_hdr *)np->payload; - struct cstate *cs = comp->last_cs->cs_next; - u16_t ilen = IPH_HL(ip); - u16_t hlen; - struct tcp_hdr *oth; - struct tcp_hdr *th; - u16_t deltaS, deltaA = 0; - u32_t deltaL; - u32_t changes = 0; - u8_t new_seq[16]; - u8_t *cp = new_seq; - - /* - * Check that the packet is IP proto TCP. - */ - if (IPH_PROTO(ip) != IP_PROTO_TCP) { - return (TYPE_IP); - } - - /* - * Bail if this is an IP fragment or if the TCP packet isn't - * `compressible' (i.e., ACK isn't set or some other control bit is - * set). - */ - if ((IPH_OFFSET(ip) & PP_HTONS(0x3fff)) || np->tot_len < 40) { - return (TYPE_IP); - } - th = (struct tcp_hdr *)&((struct vj_u32_t*)ip)[ilen]; - if ((TCPH_FLAGS(th) & (TCP_SYN|TCP_FIN|TCP_RST|TCP_ACK)) != TCP_ACK) { - return (TYPE_IP); - } - - /* Check that the TCP/IP headers are contained in the first buffer. */ - hlen = ilen + TCPH_HDRLEN(th); - hlen <<= 2; - if (np->len < hlen) { - PPPDEBUG(LOG_INFO, ("vj_compress_tcp: header len %d spans buffers\n", hlen)); - return (TYPE_IP); - } - - /* TCP stack requires that we don't change the packet payload, therefore we copy - * the whole packet before compression. */ - np = pbuf_clone(PBUF_RAW, PBUF_RAM, *pb); - if (!np) { - return (TYPE_IP); - } - - *pb = np; - ip = (struct ip_hdr *)np->payload; - - /* - * Packet is compressible -- we're going to send either a - * COMPRESSED_TCP or UNCOMPRESSED_TCP packet. Either way we need - * to locate (or create) the connection state. Special case the - * most recently used connection since it's most likely to be used - * again & we don't have to do any reordering if it's used. - */ - INCR(vjs_packets); - if (!ip4_addr_cmp(&ip->src, &cs->cs_ip.src) - || !ip4_addr_cmp(&ip->dest, &cs->cs_ip.dest) - || (*(struct vj_u32_t*)th).v != (((struct vj_u32_t*)&cs->cs_ip)[IPH_HL(&cs->cs_ip)]).v) { - /* - * Wasn't the first -- search for it. - * - * States are kept in a circularly linked list with - * last_cs pointing to the end of the list. The - * list is kept in lru order by moving a state to the - * head of the list whenever it is referenced. Since - * the list is short and, empirically, the connection - * we want is almost always near the front, we locate - * states via linear search. If we don't find a state - * for the datagram, the oldest state is (re-)used. - */ - struct cstate *lcs; - struct cstate *lastcs = comp->last_cs; - - do { - lcs = cs; cs = cs->cs_next; - INCR(vjs_searches); - if (ip4_addr_cmp(&ip->src, &cs->cs_ip.src) - && ip4_addr_cmp(&ip->dest, &cs->cs_ip.dest) - && (*(struct vj_u32_t*)th).v == (((struct vj_u32_t*)&cs->cs_ip)[IPH_HL(&cs->cs_ip)]).v) { - goto found; - } - } while (cs != lastcs); - - /* - * Didn't find it -- re-use oldest cstate. Send an - * uncompressed packet that tells the other side what - * connection number we're using for this conversation. - * Note that since the state list is circular, the oldest - * state points to the newest and we only need to set - * last_cs to update the lru linkage. - */ - INCR(vjs_misses); - comp->last_cs = lcs; - goto uncompressed; - - found: - /* - * Found it -- move to the front on the connection list. - */ - if (cs == lastcs) { - comp->last_cs = lcs; - } else { - lcs->cs_next = cs->cs_next; - cs->cs_next = lastcs->cs_next; - lastcs->cs_next = cs; - } - } - - oth = (struct tcp_hdr *)&((struct vj_u32_t*)&cs->cs_ip)[ilen]; - deltaS = ilen; - - /* - * Make sure that only what we expect to change changed. The first - * line of the `if' checks the IP protocol version, header length & - * type of service. The 2nd line checks the "Don't fragment" bit. - * The 3rd line checks the time-to-live and protocol (the protocol - * check is unnecessary but costless). The 4th line checks the TCP - * header length. The 5th line checks IP options, if any. The 6th - * line checks TCP options, if any. If any of these things are - * different between the previous & current datagram, we send the - * current datagram `uncompressed'. - */ - if ((((struct vj_u16_t*)ip)[0]).v != (((struct vj_u16_t*)&cs->cs_ip)[0]).v - || (((struct vj_u16_t*)ip)[3]).v != (((struct vj_u16_t*)&cs->cs_ip)[3]).v - || (((struct vj_u16_t*)ip)[4]).v != (((struct vj_u16_t*)&cs->cs_ip)[4]).v - || TCPH_HDRLEN(th) != TCPH_HDRLEN(oth) - || (deltaS > 5 && BCMP(ip + 1, &cs->cs_ip + 1, (deltaS - 5) << 2)) - || (TCPH_HDRLEN(th) > 5 && BCMP(th + 1, oth + 1, (TCPH_HDRLEN(th) - 5) << 2))) { - goto uncompressed; - } - - /* - * Figure out which of the changing fields changed. The - * receiver expects changes in the order: urgent, window, - * ack, seq (the order minimizes the number of temporaries - * needed in this section of code). - */ - if (TCPH_FLAGS(th) & TCP_URG) { - deltaS = lwip_ntohs(th->urgp); - ENCODEZ(deltaS); - changes |= NEW_U; - } else if (th->urgp != oth->urgp) { - /* argh! URG not set but urp changed -- a sensible - * implementation should never do this but RFC793 - * doesn't prohibit the change so we have to deal - * with it. */ - goto uncompressed; - } - - if ((deltaS = (u16_t)(lwip_ntohs(th->wnd) - lwip_ntohs(oth->wnd))) != 0) { - ENCODE(deltaS); - changes |= NEW_W; - } - - if ((deltaL = lwip_ntohl(th->ackno) - lwip_ntohl(oth->ackno)) != 0) { - if (deltaL > 0xffff) { - goto uncompressed; - } - deltaA = (u16_t)deltaL; - ENCODE(deltaA); - changes |= NEW_A; - } - - if ((deltaL = lwip_ntohl(th->seqno) - lwip_ntohl(oth->seqno)) != 0) { - if (deltaL > 0xffff) { - goto uncompressed; - } - deltaS = (u16_t)deltaL; - ENCODE(deltaS); - changes |= NEW_S; - } - - switch(changes) { - case 0: - /* - * Nothing changed. If this packet contains data and the - * last one didn't, this is probably a data packet following - * an ack (normal on an interactive connection) and we send - * it compressed. Otherwise it's probably a retransmit, - * retransmitted ack or window probe. Send it uncompressed - * in case the other side missed the compressed version. - */ - if (IPH_LEN(ip) != IPH_LEN(&cs->cs_ip) && - lwip_ntohs(IPH_LEN(&cs->cs_ip)) == hlen) { - break; - } - /* no break */ - /* fall through */ - - case SPECIAL_I: - case SPECIAL_D: - /* - * actual changes match one of our special case encodings -- - * send packet uncompressed. - */ - goto uncompressed; - - case NEW_S|NEW_A: - if (deltaS == deltaA && deltaS == lwip_ntohs(IPH_LEN(&cs->cs_ip)) - hlen) { - /* special case for echoed terminal traffic */ - changes = SPECIAL_I; - cp = new_seq; - } - break; - - case NEW_S: - if (deltaS == lwip_ntohs(IPH_LEN(&cs->cs_ip)) - hlen) { - /* special case for data xfer */ - changes = SPECIAL_D; - cp = new_seq; - } - break; - default: - break; - } - - deltaS = (u16_t)(lwip_ntohs(IPH_ID(ip)) - lwip_ntohs(IPH_ID(&cs->cs_ip))); - if (deltaS != 1) { - ENCODEZ(deltaS); - changes |= NEW_I; - } - if (TCPH_FLAGS(th) & TCP_PSH) { - changes |= TCP_PUSH_BIT; - } - /* - * Grab the cksum before we overwrite it below. Then update our - * state with this packet's header. - */ - deltaA = lwip_ntohs(th->chksum); - MEMCPY(&cs->cs_ip, ip, hlen); - - /* - * We want to use the original packet as our compressed packet. - * (cp - new_seq) is the number of bytes we need for compressed - * sequence numbers. In addition we need one byte for the change - * mask, one for the connection id and two for the tcp checksum. - * So, (cp - new_seq) + 4 bytes of header are needed. hlen is how - * many bytes of the original packet to toss so subtract the two to - * get the new packet size. - */ - deltaS = (u16_t)(cp - new_seq); - if (!comp->compressSlot || comp->last_xmit != cs->cs_id) { - comp->last_xmit = cs->cs_id; - hlen -= deltaS + 4; - if (pbuf_remove_header(np, hlen)){ - /* Can we cope with this failing? Just assert for now */ - LWIP_ASSERT("pbuf_remove_header failed\n", 0); - } - cp = (u8_t*)np->payload; - *cp++ = (u8_t)(changes | NEW_C); - *cp++ = cs->cs_id; - } else { - hlen -= deltaS + 3; - if (pbuf_remove_header(np, hlen)) { - /* Can we cope with this failing? Just assert for now */ - LWIP_ASSERT("pbuf_remove_header failed\n", 0); - } - cp = (u8_t*)np->payload; - *cp++ = (u8_t)changes; - } - *cp++ = (u8_t)(deltaA >> 8); - *cp++ = (u8_t)deltaA; - MEMCPY(cp, new_seq, deltaS); - INCR(vjs_compressed); - return (TYPE_COMPRESSED_TCP); - - /* - * Update connection state cs & send uncompressed packet (that is, - * a regular ip/tcp packet but with the 'conversation id' we hope - * to use on future compressed packets in the protocol field). - */ -uncompressed: - MEMCPY(&cs->cs_ip, ip, hlen); - IPH_PROTO_SET(ip, cs->cs_id); - comp->last_xmit = cs->cs_id; - return (TYPE_UNCOMPRESSED_TCP); -} - -/* - * Called when we may have missed a packet. - */ -void -vj_uncompress_err(struct vjcompress *comp) -{ - comp->flags |= VJF_TOSS; - INCR(vjs_errorin); -} - -/* - * "Uncompress" a packet of type TYPE_UNCOMPRESSED_TCP. - * Return 0 on success, -1 on failure. - */ -int -vj_uncompress_uncomp(struct pbuf *nb, struct vjcompress *comp) -{ - u32_t hlen; - struct cstate *cs; - struct ip_hdr *ip; - - ip = (struct ip_hdr *)nb->payload; - hlen = IPH_HL(ip) << 2; - if (IPH_PROTO(ip) >= MAX_SLOTS - || hlen + sizeof(struct tcp_hdr) > nb->len - || (hlen += TCPH_HDRLEN_BYTES((struct tcp_hdr *)&((char *)ip)[hlen])) - > nb->len - || hlen > MAX_HDR) { - PPPDEBUG(LOG_INFO, ("vj_uncompress_uncomp: bad cid=%d, hlen=%d buflen=%d\n", - IPH_PROTO(ip), hlen, nb->len)); - vj_uncompress_err(comp); - return -1; - } - cs = &comp->rstate[comp->last_recv = IPH_PROTO(ip)]; - comp->flags &=~ VJF_TOSS; - IPH_PROTO_SET(ip, IP_PROTO_TCP); - /* copy from/to bigger buffers checked above instead of cs->cs_ip and ip - just to help static code analysis to see this is correct ;-) */ - MEMCPY(&cs->cs_hdr, nb->payload, hlen); - cs->cs_hlen = (u16_t)hlen; - INCR(vjs_uncompressedin); - return 0; -} - -/* - * Uncompress a packet of type TYPE_COMPRESSED_TCP. - * The packet is composed of a buffer chain and the first buffer - * must contain an accurate chain length. - * The first buffer must include the entire compressed TCP/IP header. - * This procedure replaces the compressed header with the uncompressed - * header and returns the length of the VJ header. - */ -int -vj_uncompress_tcp(struct pbuf **nb, struct vjcompress *comp) -{ - u8_t *cp; - struct tcp_hdr *th; - struct cstate *cs; - struct vj_u16_t *bp; - struct pbuf *n0 = *nb; - u32_t tmp; - u32_t vjlen, hlen, changes; - - INCR(vjs_compressedin); - cp = (u8_t*)n0->payload; - changes = *cp++; - if (changes & NEW_C) { - /* - * Make sure the state index is in range, then grab the state. - * If we have a good state index, clear the 'discard' flag. - */ - if (*cp >= MAX_SLOTS) { - PPPDEBUG(LOG_INFO, ("vj_uncompress_tcp: bad cid=%d\n", *cp)); - goto bad; - } - - comp->flags &=~ VJF_TOSS; - comp->last_recv = *cp++; - } else { - /* - * this packet has an implicit state index. If we've - * had a line error since the last time we got an - * explicit state index, we have to toss the packet. - */ - if (comp->flags & VJF_TOSS) { - PPPDEBUG(LOG_INFO, ("vj_uncompress_tcp: tossing\n")); - INCR(vjs_tossed); - return (-1); - } - } - cs = &comp->rstate[comp->last_recv]; - hlen = IPH_HL(&cs->cs_ip) << 2; - th = (struct tcp_hdr *)&((u8_t*)&cs->cs_ip)[hlen]; - th->chksum = lwip_htons((*cp << 8) | cp[1]); - cp += 2; - if (changes & TCP_PUSH_BIT) { - TCPH_SET_FLAG(th, TCP_PSH); - } else { - TCPH_UNSET_FLAG(th, TCP_PSH); - } - - switch (changes & SPECIALS_MASK) { - case SPECIAL_I: - { - u32_t i = lwip_ntohs(IPH_LEN(&cs->cs_ip)) - cs->cs_hlen; - /* some compilers can't nest inline assembler.. */ - tmp = lwip_ntohl(th->ackno) + i; - th->ackno = lwip_htonl(tmp); - tmp = lwip_ntohl(th->seqno) + i; - th->seqno = lwip_htonl(tmp); - } - break; - - case SPECIAL_D: - /* some compilers can't nest inline assembler.. */ - tmp = lwip_ntohl(th->seqno) + lwip_ntohs(IPH_LEN(&cs->cs_ip)) - cs->cs_hlen; - th->seqno = lwip_htonl(tmp); - break; - - default: - if (changes & NEW_U) { - TCPH_SET_FLAG(th, TCP_URG); - DECODEU(th->urgp); - } else { - TCPH_UNSET_FLAG(th, TCP_URG); - } - if (changes & NEW_W) { - DECODES(th->wnd); - } - if (changes & NEW_A) { - DECODEL(th->ackno); - } - if (changes & NEW_S) { - DECODEL(th->seqno); - } - break; - } - if (changes & NEW_I) { - DECODES(cs->cs_ip._id); - } else { - IPH_ID_SET(&cs->cs_ip, lwip_ntohs(IPH_ID(&cs->cs_ip)) + 1); - IPH_ID_SET(&cs->cs_ip, lwip_htons(IPH_ID(&cs->cs_ip))); - } - - /* - * At this point, cp points to the first byte of data in the - * packet. Fill in the IP total length and update the IP - * header checksum. - */ - vjlen = (u16_t)(cp - (u8_t*)n0->payload); - if (n0->len < vjlen) { - /* - * We must have dropped some characters (crc should detect - * this but the old slip framing won't) - */ - PPPDEBUG(LOG_INFO, ("vj_uncompress_tcp: head buffer %d too short %d\n", - n0->len, vjlen)); - goto bad; - } - -#if BYTE_ORDER == LITTLE_ENDIAN - tmp = n0->tot_len - vjlen + cs->cs_hlen; - IPH_LEN_SET(&cs->cs_ip, lwip_htons((u16_t)tmp)); -#else - IPH_LEN_SET(&cs->cs_ip, lwip_htons(n0->tot_len - vjlen + cs->cs_hlen)); -#endif - - /* recompute the ip header checksum */ - bp = (struct vj_u16_t*) &cs->cs_ip; - IPH_CHKSUM_SET(&cs->cs_ip, 0); - for (tmp = 0; hlen > 0; hlen -= 2) { - tmp += (*bp++).v; - } - tmp = (tmp & 0xffff) + (tmp >> 16); - tmp = (tmp & 0xffff) + (tmp >> 16); - IPH_CHKSUM_SET(&cs->cs_ip, (u16_t)(~tmp)); - - /* Remove the compressed header and prepend the uncompressed header. */ - if (pbuf_remove_header(n0, vjlen)) { - /* Can we cope with this failing? Just assert for now */ - LWIP_ASSERT("pbuf_remove_header failed\n", 0); - goto bad; - } - - if(LWIP_MEM_ALIGN(n0->payload) != n0->payload) { - struct pbuf *np; - -#if IP_FORWARD - /* If IP forwarding is enabled we are using a PBUF_LINK packet type so - * the packet is being allocated with enough header space to be - * forwarded (to Ethernet for example). - */ - np = pbuf_alloc(PBUF_LINK, n0->len + cs->cs_hlen, PBUF_POOL); -#else /* IP_FORWARD */ - np = pbuf_alloc(PBUF_RAW, n0->len + cs->cs_hlen, PBUF_POOL); -#endif /* IP_FORWARD */ - if(!np) { - PPPDEBUG(LOG_WARNING, ("vj_uncompress_tcp: realign failed\n")); - goto bad; - } - - if (pbuf_remove_header(np, cs->cs_hlen)) { - /* Can we cope with this failing? Just assert for now */ - LWIP_ASSERT("pbuf_remove_header failed\n", 0); - goto bad; - } - - pbuf_take(np, n0->payload, n0->len); - - if(n0->next) { - pbuf_chain(np, n0->next); - pbuf_dechain(n0); - } - pbuf_free(n0); - n0 = np; - } - - if (pbuf_add_header(n0, cs->cs_hlen)) { - struct pbuf *np; - - LWIP_ASSERT("vj_uncompress_tcp: cs->cs_hlen <= PBUF_POOL_BUFSIZE", cs->cs_hlen <= PBUF_POOL_BUFSIZE); - np = pbuf_alloc(PBUF_RAW, cs->cs_hlen, PBUF_POOL); - if(!np) { - PPPDEBUG(LOG_WARNING, ("vj_uncompress_tcp: prepend failed\n")); - goto bad; - } - pbuf_cat(np, n0); - n0 = np; - } - LWIP_ASSERT("n0->len >= cs->cs_hlen", n0->len >= cs->cs_hlen); - MEMCPY(n0->payload, &cs->cs_ip, cs->cs_hlen); - - *nb = n0; - - return vjlen; - -bad: - vj_uncompress_err(comp); - return (-1); -} - -#endif /* PPP_SUPPORT && VJ_SUPPORT */ diff --git a/third-party/lwip-2.1.2/netif/slipif.c_o b/third-party/lwip-2.1.2/netif/slipif.c_o deleted file mode 100644 index 9b175dc3..00000000 --- a/third-party/lwip-2.1.2/netif/slipif.c_o +++ /dev/null @@ -1,558 +0,0 @@ -/** - * @file - * SLIP Interface - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is built upon the file: src/arch/rtxc/netif/sioslip.c - * - * Author: Magnus Ivarsson - * Simon Goldschmidt - */ - - -/** - * @defgroup slipif SLIP - * @ingroup netifs - * - * This is an arch independent SLIP netif. The specific serial hooks must be - * provided by another file. They are sio_open, sio_read/sio_tryread and sio_send - * - * Usage: This netif can be used in three ways:\n - * 1) For NO_SYS==0, an RX thread can be used which blocks on sio_read() - * until data is received.\n - * 2) In your main loop, call slipif_poll() to check for new RX bytes, - * completed packets are fed into netif->input().\n - * 3) Call slipif_received_byte[s]() from your serial RX ISR and - * slipif_process_rxqueue() from your main loop. ISR level decodes - * packets and puts completed packets on a queue which is fed into - * the stack from the main loop (needs SYS_LIGHTWEIGHT_PROT for - * pbuf_alloc to work on ISR level!). - * - */ - -#include "netif/slipif.h" -#include "lwip/opt.h" - -#include "lwip/def.h" -#include "lwip/pbuf.h" -#include "lwip/stats.h" -#include "lwip/snmp.h" -#include "lwip/sys.h" -#include "lwip/sio.h" - -#define SLIP_END 0xC0 /* 0300: start and end of every packet */ -#define SLIP_ESC 0xDB /* 0333: escape start (one byte escaped data follows) */ -#define SLIP_ESC_END 0xDC /* 0334: following escape: original byte is 0xC0 (END) */ -#define SLIP_ESC_ESC 0xDD /* 0335: following escape: original byte is 0xDB (ESC) */ - -/** Maximum packet size that is received by this netif */ -#ifndef SLIP_MAX_SIZE -#define SLIP_MAX_SIZE 1500 -#endif - -/** Define this to the interface speed for SNMP - * (sio_fd is the sio_fd_t returned by sio_open). - * The default value of zero means 'unknown'. - */ -#ifndef SLIP_SIO_SPEED -#define SLIP_SIO_SPEED(sio_fd) 0 -#endif - -enum slipif_recv_state { - SLIP_RECV_NORMAL, - SLIP_RECV_ESCAPE -}; - -struct slipif_priv { - sio_fd_t sd; - /* q is the whole pbuf chain for a packet, p is the current pbuf in the chain */ - struct pbuf *p, *q; - u8_t state; - u16_t i, recved; -#if SLIP_RX_FROM_ISR - struct pbuf *rxpackets; -#endif -}; - -/** - * Send a pbuf doing the necessary SLIP encapsulation - * - * Uses the serial layer's sio_send() - * - * @param netif the lwip network interface structure for this slipif - * @param p the pbuf chain packet to send - * @return always returns ERR_OK since the serial layer does not provide return values - */ -static err_t -slipif_output(struct netif *netif, struct pbuf *p) -{ - struct slipif_priv *priv; - struct pbuf *q; - u16_t i; - u8_t c; - - LWIP_ASSERT("netif != NULL", (netif != NULL)); - LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); - LWIP_ASSERT("p != NULL", (p != NULL)); - - LWIP_DEBUGF(SLIP_DEBUG, ("slipif_output: sending %"U16_F" bytes\n", p->tot_len)); - priv = (struct slipif_priv *)netif->state; - - /* Send pbuf out on the serial I/O device. */ - /* Start with packet delimiter. */ - sio_send(SLIP_END, priv->sd); - - for (q = p; q != NULL; q = q->next) { - for (i = 0; i < q->len; i++) { - c = ((u8_t *)q->payload)[i]; - switch (c) { - case SLIP_END: - /* need to escape this byte (0xC0 -> 0xDB, 0xDC) */ - sio_send(SLIP_ESC, priv->sd); - sio_send(SLIP_ESC_END, priv->sd); - break; - case SLIP_ESC: - /* need to escape this byte (0xDB -> 0xDB, 0xDD) */ - sio_send(SLIP_ESC, priv->sd); - sio_send(SLIP_ESC_ESC, priv->sd); - break; - default: - /* normal byte - no need for escaping */ - sio_send(c, priv->sd); - break; - } - } - } - /* End with packet delimiter. */ - sio_send(SLIP_END, priv->sd); - return ERR_OK; -} - -#if LWIP_IPV4 -/** - * Send a pbuf doing the necessary SLIP encapsulation - * - * Uses the serial layer's sio_send() - * - * @param netif the lwip network interface structure for this slipif - * @param p the pbuf chain packet to send - * @param ipaddr the ip address to send the packet to (not used for slipif) - * @return always returns ERR_OK since the serial layer does not provide return values - */ -static err_t -slipif_output_v4(struct netif *netif, struct pbuf *p, const ip4_addr_t *ipaddr) -{ - LWIP_UNUSED_ARG(ipaddr); - return slipif_output(netif, p); -} -#endif /* LWIP_IPV4 */ - -#if LWIP_IPV6 -/** - * Send a pbuf doing the necessary SLIP encapsulation - * - * Uses the serial layer's sio_send() - * - * @param netif the lwip network interface structure for this slipif - * @param p the pbuf chain packet to send - * @param ipaddr the ip address to send the packet to (not used for slipif) - * @return always returns ERR_OK since the serial layer does not provide return values - */ -static err_t -slipif_output_v6(struct netif *netif, struct pbuf *p, const ip6_addr_t *ipaddr) -{ - LWIP_UNUSED_ARG(ipaddr); - return slipif_output(netif, p); -} -#endif /* LWIP_IPV6 */ - -/** - * Handle the incoming SLIP stream character by character - * - * @param netif the lwip network interface structure for this slipif - * @param c received character (multiple calls to this function will - * return a complete packet, NULL is returned before - used for polling) - * @return The IP packet when SLIP_END is received - */ -static struct pbuf * -slipif_rxbyte(struct netif *netif, u8_t c) -{ - struct slipif_priv *priv; - struct pbuf *t; - - LWIP_ASSERT("netif != NULL", (netif != NULL)); - LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); - - priv = (struct slipif_priv *)netif->state; - - switch (priv->state) { - case SLIP_RECV_NORMAL: - switch (c) { - case SLIP_END: - if (priv->recved > 0) { - /* Received whole packet. */ - /* Trim the pbuf to the size of the received packet. */ - pbuf_realloc(priv->q, priv->recved); - - LINK_STATS_INC(link.recv); - - LWIP_DEBUGF(SLIP_DEBUG, ("slipif: Got packet (%"U16_F" bytes)\n", priv->recved)); - t = priv->q; - priv->p = priv->q = NULL; - priv->i = priv->recved = 0; - return t; - } - return NULL; - case SLIP_ESC: - priv->state = SLIP_RECV_ESCAPE; - return NULL; - default: - break; - } /* end switch (c) */ - break; - case SLIP_RECV_ESCAPE: - /* un-escape END or ESC bytes, leave other bytes - (although that would be a protocol error) */ - switch (c) { - case SLIP_ESC_END: - c = SLIP_END; - break; - case SLIP_ESC_ESC: - c = SLIP_ESC; - break; - default: - break; - } - priv->state = SLIP_RECV_NORMAL; - break; - default: - break; - } /* end switch (priv->state) */ - - /* byte received, packet not yet completely received */ - if (priv->p == NULL) { - /* allocate a new pbuf */ - LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: alloc\n")); - priv->p = pbuf_alloc(PBUF_LINK, (PBUF_POOL_BUFSIZE - PBUF_LINK_HLEN - PBUF_LINK_ENCAPSULATION_HLEN), PBUF_POOL); - - if (priv->p == NULL) { - LINK_STATS_INC(link.drop); - LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: no new pbuf! (DROP)\n")); - /* don't process any further since we got no pbuf to receive to */ - return NULL; - } - - if (priv->q != NULL) { - /* 'chain' the pbuf to the existing chain */ - pbuf_cat(priv->q, priv->p); - } else { - /* p is the first pbuf in the chain */ - priv->q = priv->p; - } - } - - /* this automatically drops bytes if > SLIP_MAX_SIZE */ - if ((priv->p != NULL) && (priv->recved <= SLIP_MAX_SIZE)) { - ((u8_t *)priv->p->payload)[priv->i] = c; - priv->recved++; - priv->i++; - if (priv->i >= priv->p->len) { - /* on to the next pbuf */ - priv->i = 0; - if (priv->p->next != NULL && priv->p->next->len > 0) { - /* p is a chain, on to the next in the chain */ - priv->p = priv->p->next; - } else { - /* p is a single pbuf, set it to NULL so next time a new - * pbuf is allocated */ - priv->p = NULL; - } - } - } - return NULL; -} - -/** Like slipif_rxbyte, but passes completed packets to netif->input - * - * @param netif The lwip network interface structure for this slipif - * @param c received character - */ -static void -slipif_rxbyte_input(struct netif *netif, u8_t c) -{ - struct pbuf *p; - p = slipif_rxbyte(netif, c); - if (p != NULL) { - if (netif->input(p, netif) != ERR_OK) { - pbuf_free(p); - } - } -} - -#if SLIP_USE_RX_THREAD -/** - * The SLIP input thread. - * - * Feed the IP layer with incoming packets - * - * @param nf the lwip network interface structure for this slipif - */ -static void -slipif_loop_thread(void *nf) -{ - u8_t c; - struct netif *netif = (struct netif *)nf; - struct slipif_priv *priv = (struct slipif_priv *)netif->state; - - while (1) { - if (sio_read(priv->sd, &c, 1) > 0) { - slipif_rxbyte_input(netif, c); - } - } -} -#endif /* SLIP_USE_RX_THREAD */ - -/** - * @ingroup slipif - * SLIP netif initialization - * - * Call the arch specific sio_open and remember - * the opened device in the state field of the netif. - * - * @param netif the lwip network interface structure for this slipif - * @return ERR_OK if serial line could be opened, - * ERR_MEM if no memory could be allocated, - * ERR_IF is serial line couldn't be opened - * - * @note If netif->state is interpreted as an u8_t serial port number. - * - */ -err_t -slipif_init(struct netif *netif) -{ - struct slipif_priv *priv; - u8_t sio_num; - - LWIP_ASSERT("slipif needs an input callback", netif->input != NULL); - - /* netif->state contains serial port number */ - sio_num = LWIP_PTR_NUMERIC_CAST(u8_t, netif->state); - - LWIP_DEBUGF(SLIP_DEBUG, ("slipif_init: netif->num=%"U16_F"\n", (u16_t)sio_num)); - - /* Allocate private data */ - priv = (struct slipif_priv *)mem_malloc(sizeof(struct slipif_priv)); - if (!priv) { - return ERR_MEM; - } - - netif->name[0] = 's'; - netif->name[1] = 'l'; -#if LWIP_IPV4 - netif->output = slipif_output_v4; -#endif /* LWIP_IPV4 */ -#if LWIP_IPV6 - netif->output_ip6 = slipif_output_v6; -#endif /* LWIP_IPV6 */ - netif->mtu = SLIP_MAX_SIZE; - - /* Try to open the serial port. */ - priv->sd = sio_open(sio_num); - if (!priv->sd) { - /* Opening the serial port failed. */ - mem_free(priv); - return ERR_IF; - } - - /* Initialize private data */ - priv->p = NULL; - priv->q = NULL; - priv->state = SLIP_RECV_NORMAL; - priv->i = 0; - priv->recved = 0; -#if SLIP_RX_FROM_ISR - priv->rxpackets = NULL; -#endif - - netif->state = priv; - - /* initialize the snmp variables and counters inside the struct netif */ - MIB2_INIT_NETIF(netif, snmp_ifType_slip, SLIP_SIO_SPEED(priv->sd)); - -#if SLIP_USE_RX_THREAD - /* Create a thread to poll the serial line. */ - sys_thread_new(SLIPIF_THREAD_NAME, slipif_loop_thread, netif, - SLIPIF_THREAD_STACKSIZE, SLIPIF_THREAD_PRIO); -#endif /* SLIP_USE_RX_THREAD */ - return ERR_OK; -} - -/** - * @ingroup slipif - * Polls the serial device and feeds the IP layer with incoming packets. - * - * @param netif The lwip network interface structure for this slipif - */ -void -slipif_poll(struct netif *netif) -{ - u8_t c; - struct slipif_priv *priv; - - LWIP_ASSERT("netif != NULL", (netif != NULL)); - LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); - - priv = (struct slipif_priv *)netif->state; - - while (sio_tryread(priv->sd, &c, 1) > 0) { - slipif_rxbyte_input(netif, c); - } -} - -#if SLIP_RX_FROM_ISR -/** - * @ingroup slipif - * Feeds the IP layer with incoming packets that were receive - * - * @param netif The lwip network interface structure for this slipif - */ -void -slipif_process_rxqueue(struct netif *netif) -{ - struct slipif_priv *priv; - SYS_ARCH_DECL_PROTECT(old_level); - - LWIP_ASSERT("netif != NULL", (netif != NULL)); - LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); - - priv = (struct slipif_priv *)netif->state; - - SYS_ARCH_PROTECT(old_level); - while (priv->rxpackets != NULL) { - struct pbuf *p = priv->rxpackets; -#if SLIP_RX_QUEUE - /* dequeue packet */ - struct pbuf *q = p; - while ((q->len != q->tot_len) && (q->next != NULL)) { - q = q->next; - } - priv->rxpackets = q->next; - q->next = NULL; -#else /* SLIP_RX_QUEUE */ - priv->rxpackets = NULL; -#endif /* SLIP_RX_QUEUE */ - SYS_ARCH_UNPROTECT(old_level); - if (netif->input(p, netif) != ERR_OK) { - pbuf_free(p); - } - SYS_ARCH_PROTECT(old_level); - } - SYS_ARCH_UNPROTECT(old_level); -} - -/** Like slipif_rxbyte, but queues completed packets. - * - * @param netif The lwip network interface structure for this slipif - * @param data Received serial byte - */ -static void -slipif_rxbyte_enqueue(struct netif *netif, u8_t data) -{ - struct pbuf *p; - struct slipif_priv *priv = (struct slipif_priv *)netif->state; - SYS_ARCH_DECL_PROTECT(old_level); - - p = slipif_rxbyte(netif, data); - if (p != NULL) { - SYS_ARCH_PROTECT(old_level); - if (priv->rxpackets != NULL) { -#if SLIP_RX_QUEUE - /* queue multiple pbufs */ - struct pbuf *q = p; - while (q->next != NULL) { - q = q->next; - } - q->next = p; - } else { -#else /* SLIP_RX_QUEUE */ - pbuf_free(priv->rxpackets); - } - { -#endif /* SLIP_RX_QUEUE */ - priv->rxpackets = p; - } - SYS_ARCH_UNPROTECT(old_level); - } -} - -/** - * @ingroup slipif - * Process a received byte, completed packets are put on a queue that is - * fed into IP through slipif_process_rxqueue(). - * - * This function can be called from ISR if SYS_LIGHTWEIGHT_PROT is enabled. - * - * @param netif The lwip network interface structure for this slipif - * @param data received character - */ -void -slipif_received_byte(struct netif *netif, u8_t data) -{ - LWIP_ASSERT("netif != NULL", (netif != NULL)); - LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); - slipif_rxbyte_enqueue(netif, data); -} - -/** - * @ingroup slipif - * Process multiple received byte, completed packets are put on a queue that is - * fed into IP through slipif_process_rxqueue(). - * - * This function can be called from ISR if SYS_LIGHTWEIGHT_PROT is enabled. - * - * @param netif The lwip network interface structure for this slipif - * @param data received character - * @param len Number of received characters - */ -void -slipif_received_bytes(struct netif *netif, u8_t *data, u8_t len) -{ - u8_t i; - u8_t *rxdata = data; - LWIP_ASSERT("netif != NULL", (netif != NULL)); - LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); - - for (i = 0; i < len; i++, rxdata++) { - slipif_rxbyte_enqueue(netif, *rxdata); - } -} -#endif /* SLIP_RX_FROM_ISR */ diff --git a/third-party/lwip-2.1.2/netif/zepif.c b/third-party/lwip-2.1.2/netif/zepif.c deleted file mode 100644 index b4033030..00000000 --- a/third-party/lwip-2.1.2/netif/zepif.c +++ /dev/null @@ -1,300 +0,0 @@ -/** - * @file - * - * @defgroup zepif ZEP - ZigBee Encapsulation Protocol - * @ingroup netifs - * A netif implementing the ZigBee Encapsulation Protocol (ZEP). - * This is used to tunnel 6LowPAN over UDP. - * - * Usage (there must be a default netif before!): - * @code{.c} - * netif_add(&zep_netif, NULL, NULL, NULL, NULL, zepif_init, tcpip_6lowpan_input); - * netif_create_ip6_linklocal_address(&zep_netif, 1); - * netif_set_up(&zep_netif); - * netif_set_link_up(&zep_netif); - * @endcode - */ - -/* - * Copyright (c) 2018 Simon Goldschmidt - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Simon Goldschmidt - * - */ - -#include "netif/zepif.h" - -#if LWIP_IPV6 && LWIP_UDP - -#include "netif/lowpan6.h" -#include "lwip/udp.h" -#include "lwip/timeouts.h" -#include - -/** Define this to 1 to loop back TX packets for testing */ -#ifndef ZEPIF_LOOPBACK -#define ZEPIF_LOOPBACK 0 -#endif - -#define ZEP_MAX_DATA_LEN 127 - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct zep_hdr { - PACK_STRUCT_FLD_8(u8_t prot_id[2]); - PACK_STRUCT_FLD_8(u8_t prot_version); - PACK_STRUCT_FLD_8(u8_t type); - PACK_STRUCT_FLD_8(u8_t channel_id); - PACK_STRUCT_FIELD(u16_t device_id); - PACK_STRUCT_FLD_8(u8_t crc_mode); - PACK_STRUCT_FLD_8(u8_t unknown_1); - PACK_STRUCT_FIELD(u32_t timestamp[2]); - PACK_STRUCT_FIELD(u32_t seq_num); - PACK_STRUCT_FLD_8(u8_t unknown_2[10]); - PACK_STRUCT_FLD_8(u8_t len); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -struct zepif_state { - struct zepif_init init; - struct udp_pcb *pcb; - u32_t seqno; -}; - -static u8_t zep_lowpan_timer_running; - -/* Helper function that calls the 6LoWPAN timer and reschedules itself */ -static void -zep_lowpan_timer(void *arg) -{ - lowpan6_tmr(); - if (zep_lowpan_timer_running) { - sys_timeout(LOWPAN6_TMR_INTERVAL, zep_lowpan_timer, arg); - } -} - -/* Pass received pbufs into 6LowPAN netif */ -static void -zepif_udp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, - const ip_addr_t *addr, u16_t port) -{ - err_t err; - struct netif *netif_lowpan6 = (struct netif *)arg; - struct zep_hdr *zep; - - LWIP_ASSERT("arg != NULL", arg != NULL); - LWIP_ASSERT("pcb != NULL", pcb != NULL); - LWIP_UNUSED_ARG(pcb); /* for LWIP_NOASSERT */ - LWIP_UNUSED_ARG(addr); - LWIP_UNUSED_ARG(port); - if (p == NULL) { - return; - } - - /* Parse and hide the ZEP header */ - if (p->len < sizeof(struct zep_hdr)) { - /* need the zep_hdr in one piece */ - goto err_return; - } - zep = (struct zep_hdr *)p->payload; - if (zep->prot_id[0] != 'E') { - goto err_return; - } - if (zep->prot_id[1] != 'X') { - goto err_return; - } - if (zep->prot_version != 2) { - /* we only support this version for now */ - goto err_return; - } - if (zep->type != 1) { - goto err_return; - } - if (zep->crc_mode != 1) { - goto err_return; - } - if (zep->len != p->tot_len - sizeof(struct zep_hdr)) { - goto err_return; - } - /* everything seems to be OK, hide the ZEP header */ - if (pbuf_remove_header(p, sizeof(struct zep_hdr))) { - goto err_return; - } - /* TODO Check CRC? */ - /* remove CRC trailer */ - pbuf_realloc(p, p->tot_len - 2); - - /* Call into 6LoWPAN code. */ - err = netif_lowpan6->input(p, netif_lowpan6); - if (err == ERR_OK) { - return; - } -err_return: - pbuf_free(p); -} - -/* Send 6LoWPAN TX packets as UDP broadcast */ -static err_t -zepif_linkoutput(struct netif *netif, struct pbuf *p) -{ - err_t err; - struct pbuf *q; - struct zep_hdr *zep; - struct zepif_state *state; - - LWIP_ASSERT("invalid netif", netif != NULL); - LWIP_ASSERT("invalid pbuf", p != NULL); - - if (p->tot_len > ZEP_MAX_DATA_LEN) { - return ERR_VAL; - } - LWIP_ASSERT("TODO: support chained pbufs", p->next == NULL); - - state = (struct zepif_state *)netif->state; - LWIP_ASSERT("state->pcb != NULL", state->pcb != NULL); - - q = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct zep_hdr) + p->tot_len, PBUF_RAM); - if (q == NULL) { - return ERR_MEM; - } - zep = (struct zep_hdr *)q->payload; - memset(zep, 0, sizeof(struct zep_hdr)); - zep->prot_id[0] = 'E'; - zep->prot_id[1] = 'X'; - zep->prot_version = 2; - zep->type = 1; /* Data */ - zep->channel_id = 0; /* whatever */ - zep->device_id = lwip_htons(1); /* whatever */ - zep->crc_mode = 1; - zep->unknown_1 = 0xff; - zep->seq_num = lwip_htonl(state->seqno); - state->seqno++; - zep->len = (u8_t)p->tot_len; - - err = pbuf_take_at(q, p->payload, p->tot_len, sizeof(struct zep_hdr)); - if (err == ERR_OK) { -#if ZEPIF_LOOPBACK - zepif_udp_recv(netif, state->pcb, pbuf_clone(PBUF_RAW, PBUF_RAM, q), NULL, 0); -#endif - err = udp_sendto(state->pcb, q, state->init.zep_dst_ip_addr, state->init.zep_dst_udp_port); - } - pbuf_free(q); - - return err; -} - -/** - * @ingroup zepif - * Set up a raw 6LowPAN netif and surround it with input- and output - * functions for ZEP - */ -err_t -zepif_init(struct netif *netif) -{ - err_t err; - struct zepif_init *init_state = (struct zepif_init *)netif->state; - struct zepif_state *state = (struct zepif_state *)mem_malloc(sizeof(struct zepif_state)); - - LWIP_ASSERT("zepif needs an input callback", netif->input != NULL); - - if (state == NULL) { - return ERR_MEM; - } - memset(state, 0, sizeof(struct zepif_state)); - if (init_state != NULL) { - memcpy(&state->init, init_state, sizeof(struct zepif_init)); - } - if (state->init.zep_src_udp_port == 0) { - state->init.zep_src_udp_port = ZEPIF_DEFAULT_UDP_PORT; - } - if (state->init.zep_dst_udp_port == 0) { - state->init.zep_dst_udp_port = ZEPIF_DEFAULT_UDP_PORT; - } -#if LWIP_IPV4 - if (state->init.zep_dst_ip_addr == NULL) { - /* With IPv4 enabled, default to broadcasting packets if no address is set */ - state->init.zep_dst_ip_addr = IP_ADDR_BROADCAST; - } -#endif /* LWIP_IPV4 */ - - netif->state = NULL; - - state->pcb = udp_new_ip_type(IPADDR_TYPE_ANY); - if (state->pcb == NULL) { - err = ERR_MEM; - goto err_ret; - } - err = udp_bind(state->pcb, state->init.zep_src_ip_addr, state->init.zep_src_udp_port); - if (err != ERR_OK) { - goto err_ret; - } - if (state->init.zep_netif != NULL) { - udp_bind_netif(state->pcb, state->init.zep_netif); - } - LWIP_ASSERT("udp_bind(lowpan6_broadcast_pcb) failed", err == ERR_OK); - ip_set_option(state->pcb, SOF_BROADCAST); - udp_recv(state->pcb, zepif_udp_recv, netif); - - err = lowpan6_if_init(netif); - LWIP_ASSERT("lowpan6_if_init set a state", netif->state == NULL); - if (err == ERR_OK) { - netif->state = state; - netif->hwaddr_len = 6; - if (init_state != NULL) { - memcpy(netif->hwaddr, init_state->addr, 6); - } else { - u8_t i; - for (i = 0; i < 6; i++) { - netif->hwaddr[i] = i; - } - netif->hwaddr[0] &= 0xfc; - } - netif->linkoutput = zepif_linkoutput; - - if (!zep_lowpan_timer_running) { - sys_timeout(LOWPAN6_TMR_INTERVAL, zep_lowpan_timer, NULL); - zep_lowpan_timer_running = 1; - } - - return ERR_OK; - } - -err_ret: - if (state->pcb != NULL) { - udp_remove(state->pcb); - } - mem_free(state); - return err; -} - -#endif /* LWIP_IPV6 && LWIP_UDP */ diff --git a/third-party/lwip-2.1.2/ports/Kconfig b/third-party/lwip-2.1.2/ports/Kconfig deleted file mode 100644 index 6ca6acac..00000000 --- a/third-party/lwip-2.1.2/ports/Kconfig +++ /dev/null @@ -1,22 +0,0 @@ -menu "LWIP Port Configuration" - - choice LWIP_GMAC_CTRL_TYPE - prompt "Gmac Drivers" - default LWIP_FGMAC - help - Select Gmac Driver for Lwip - - config LWIP_FGMAC - bool "FGMAC" - - config LWIP_FXMAC - select FREERTOS_USE_XMAC - bool "FXMAC" - - endchoice # LWIP_GMAC_CTRL_TYPE - - # add thread configuration - - - -endmenu \ No newline at end of file diff --git a/third-party/lwip-2.1.2/ports/fxmac/arch/cc.h b/third-party/lwip-2.1.2/ports/arch/cc.h similarity index 76% rename from third-party/lwip-2.1.2/ports/fxmac/arch/cc.h rename to third-party/lwip-2.1.2/ports/arch/cc.h index 5003882c..f071361f 100644 --- a/third-party/lwip-2.1.2/ports/fxmac/arch/cc.h +++ b/third-party/lwip-2.1.2/ports/arch/cc.h @@ -1,27 +1,30 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: cc.h - * Date: 2022-04-02 16:43:32 - * LastEditTime: 2022-04-19 21:27:57 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Date: 2022-11-07 11:49:13 + * LastEditTime: 2022-11-07 11:49:14 + * Description: This file is for the lwIP TCP/IP stack. + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 liuzhihong 2022/11/26 first release */ -#ifndef LWIP_ARCH_CC_H -#define LWIP_ARCH_CC_H + +#ifndef CC_H +#define CC_H + #if defined __ANDROID__ #define LWIP_UNIX_ANDROID @@ -37,17 +40,22 @@ #define LWIP_UNIX_HURD #endif -#define LWIP_NO_STDINT_H 1 //not include "stdint.h" +#define LWIP_NO_STDINT_H 1 /*not include "stdint.h"*/ /* define basic types */ #include +#ifdef __cplusplus +extern "C" +{ +#endif + typedef uint8_t u8_t; // unsigned 8-bit typedef signed char s8_t; // signed 8-bit typedef uint16_t u16_t; // unsigned 16-bit typedef short s16_t; // signed 16-bit typedef uint32_t u32_t; // unsigned 32-bit -typedef long s32_t; // signed 32-bit +typedef signed int s32_t; // signed 32-bit typedef uint64_t u64_t; // unsigned 64-bit #if defined(__aarch64__) typedef u64_t mem_ptr_t; @@ -78,7 +86,7 @@ typedef u32_t mem_ptr_t; #define LWIP_ERRNO_INCLUDE #if defined(LWIP_UNIX_LINUX) || defined(LWIP_UNIX_HURD) -#define LWIP_ERRNO_STDINCLUDE 1 + #define LWIP_ERRNO_STDINCLUDE 1 #endif #define LWIP_RAND() ((u32_t)rand()) @@ -108,4 +116,9 @@ typedef struct sio_status_s sio_status_t; typedef unsigned int sys_prot_t; + +#ifdef __cplusplus +} +#endif + #endif /* LWIP_ARCH_CC_H */ diff --git a/third-party/lwip-2.1.2/ports/fxmac/arch/sys_arch.c b/third-party/lwip-2.1.2/ports/arch/sys_arch.c similarity index 42% rename from third-party/lwip-2.1.2/ports/fxmac/arch/sys_arch.c rename to third-party/lwip-2.1.2/ports/arch/sys_arch.c index e05ef809..4ef6014a 100644 --- a/third-party/lwip-2.1.2/ports/fxmac/arch/sys_arch.c +++ b/third-party/lwip-2.1.2/ports/arch/sys_arch.c @@ -1,25 +1,27 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: sys_arch.c - * Date: 2022-07-18 13:27:02 - * LastEditTime: 2022-07-18 13:27:02 - * Description: This file is for - * + * Date: 2022-11-07 11:49:01 + * LastEditTime: 2022-11-07 11:49:01 + * Description: This file is for the lwIP TCP/IP stack. + * * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 liuzhihong 2022/5/26 first release */ + /* lwIP includes. */ #include "lwip/debug.h" #include "lwip/def.h" @@ -27,32 +29,45 @@ #include "lwip/mem.h" #include "lwip/stats.h" +#ifdef __aarch64__ + #include "faarch64.h" +#else + #include "fcp15.h" +#endif + +#include "fdebug.h" + +#define SYSTEM_ARCH_DEBUG_TAG "SYSTEM_ARCH" +#define SYSTEM_ARCH_PRINT_E(format, ...) FT_DEBUG_PRINT_E(SYSTEM_ARCH_DEBUG_TAG, format, ##__VA_ARGS__) +#define SYSTEM_ARCH_PRINT_I(format, ...) FT_DEBUG_PRINT_I(SYSTEM_ARCH_DEBUG_TAG, format, ##__VA_ARGS__) +#define SYSTEM_ARCH_PRINT_D(format, ...) FT_DEBUG_PRINT_D(SYSTEM_ARCH_DEBUG_TAG, format, ##__VA_ARGS__) +#define SYSTEM_ARCH_PRINT_W(format, ...) FT_DEBUG_PRINT_W(SYSTEM_ARCH_DEBUG_TAG, format, ##__VA_ARGS__) + #if !NO_SYS #include "FreeRTOS.h" #include "task.h" #if defined(LWIP_PROVIDE_ERRNO) -int errno; + int errno; #endif -extern int isr_calling_flg ; +extern int vApplicationInIrq(void); /*-----------------------------------------------------------------------------------*/ // Creates an empty mailbox. err_t sys_mbox_new(sys_mbox_t *mbox, int size) { - UBaseType_t archMessageLength = size; + UBaseType_t archMessageLength = size; - if (size > archMAX_MESG_QUEUE_LENGTH) - archMessageLength = archMAX_MESG_QUEUE_LENGTH; + *mbox = xQueueCreate(archMessageLength, sizeof(void *)); - *mbox = xQueueCreate(archMessageLength, sizeof(void *)); - - if (*mbox == NULL) - return ERR_MEM; + if (*mbox == NULL) + { + return ERR_MEM; + } - return ERR_OK; + return ERR_OK; } /*-----------------------------------------------------------------------------------*/ @@ -63,22 +78,22 @@ err_t sys_mbox_new(sys_mbox_t *mbox, int size) */ void sys_mbox_free(sys_mbox_t *mbox) { - UBaseType_t uxReturn; + UBaseType_t uxReturn; - uxReturn = uxQueueMessagesWaiting(*mbox); - if (uxReturn) - { - /* Line for breakpoint. Should never break here! */ - portNOP(); + uxReturn = uxQueueMessagesWaiting(*mbox); + if (uxReturn) + { + /* Line for breakpoint. Should never break here! */ + portNOP(); #if SYS_STATS - lwip_stats.sys.mbox.err++; + lwip_stats.sys.mbox.err++; #endif /* SYS_STATS */ - LWIP_ASSERT("sys_mbox_free err uxQueueMessagesWaiting.\r\n ", uxReturn == pdTRUE); - } + LWIP_ASSERT("sys_mbox_free err uxQueueMessagesWaiting.\r\n ", uxReturn == pdTRUE); + } - vQueueDelete(*mbox); + vQueueDelete(*mbox); #if SYS_STATS - --lwip_stats.sys.mbox.used; + --lwip_stats.sys.mbox.used; #endif /* SYS_STATS */ } @@ -86,87 +101,94 @@ void sys_mbox_free(sys_mbox_t *mbox) // Posts the "msg" to the mailbox. void sys_mbox_post(sys_mbox_t *mbox, void *data) { - portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; - if (*mbox == NULL) - return; - - if(isr_calling_flg != 0) - { - xQueueSendToBackFromISR( *mbox, &data, &xHigherPriorityTaskWoken ); - if (xHigherPriorityTaskWoken == pdTRUE) { - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); - } - } - else - { - xQueueSendToBack(*mbox, &data, portMAX_DELAY); - } + portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; + if (*mbox == NULL) + { + return; + } + + if (vApplicationInIrq() != 0) + { + xQueueSendToBackFromISR(*mbox, &data, &xHigherPriorityTaskWoken); + if (xHigherPriorityTaskWoken == pdTRUE) + { + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + } + } + else + { + xQueueSendToBack(*mbox, &data, portMAX_DELAY); + } } /*-----------------------------------------------------------------------------------*/ // Try to post the "msg" to the mailbox. err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) { - err_t result; - portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; - - if (*mbox == NULL) - return ERR_MEM; - - if(isr_calling_flg != 0) - { - result = xQueueSendFromISR( *mbox, &msg, &xHigherPriorityTaskWoken ); - if(xHigherPriorityTaskWoken == pdTRUE) - { - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); - } - } - else - { - result = xQueueSend( *mbox, &msg, ( portTickType ) 0 ); - } - - if( result == pdPASS ) - { - result = ERR_OK; - } - else - { - printf("Queue is full\r\n"); - /* The queue was already full. */ - result = ERR_MEM; - #if SYS_STATS - lwip_stats.sys.mbox.err++; - #endif /* SYS_STATS */ - } - - return result; + err_t result; + portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; + + if (*mbox == NULL) + { + return ERR_MEM; + } + + if (vApplicationInIrq() != 0) + { + result = xQueueSendFromISR(*mbox, &msg, &xHigherPriorityTaskWoken); + if (xHigherPriorityTaskWoken == pdTRUE) + { + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + } + } + else + { + result = xQueueSend(*mbox, &msg, (portTickType) 0); + } + + if (result == pdPASS) + { + result = ERR_OK; + } + else + { + SYSTEM_ARCH_PRINT_W("Queue is full.\r\n"); + /* The queue was already full. */ + result = ERR_MEM; +#if SYS_STATS + lwip_stats.sys.mbox.err++; +#endif /* SYS_STATS */ + } + + return result; } /*-----------------------------------------------------------------------------------*/ // Try to post the "msg" to the mailbox. err_t sys_mbox_trypost_fromisr(sys_mbox_t *mbox, void *msg) { - err_t result; - BaseType_t xHigherPriorityTaskWoken; - - if (*mbox == NULL) - return ERR_MEM; - - if (xQueueSendFromISR(*mbox, &msg, &xHigherPriorityTaskWoken) == pdTRUE) - { - result = ERR_OK; - } - else - { - // could not post, queue must be full - result = ERR_MEM; - } - - // Actual macro used here is port specific. - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); - - return result; + err_t result; + BaseType_t xHigherPriorityTaskWoken; + + if (*mbox == NULL) + { + return ERR_MEM; + } + + if (xQueueSendFromISR(*mbox, &msg, &xHigherPriorityTaskWoken) == pdTRUE) + { + result = ERR_OK; + } + else + { + // could not post, queue must be full + result = ERR_MEM; + } + + // Actual macro used here is port specific. + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + + return result; } /*-----------------------------------------------------------------------------------*/ @@ -187,105 +209,93 @@ err_t sys_mbox_trypost_fromisr(sys_mbox_t *mbox, void *msg) */ u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) { - void *dummyptr; - - BaseType_t err; - - portTickType xStartTime, xEndTime, xElapsed; - unsigned long ulReturn; - portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; - - xStartTime = xTaskGetTickCount(); - - if (*mbox == NULL) - { - return SYS_ARCH_TIMEOUT; - } - - if (msg == NULL) - { - msg = &dummyptr; - } - - if (timeout != 0) - { - - if(isr_calling_flg != 0) - { - if( pdTRUE == xQueueReceiveFromISR( *mbox, &( *msg ), &xHigherPriorityTaskWoken ) ) - { - xEndTime = xTaskGetTickCount(); - xElapsed = ( xEndTime - xStartTime ) * portTICK_RATE_MS; - ulReturn = xElapsed; - if (xHigherPriorityTaskWoken == pdTRUE) - { - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); - } - } - else - { - *msg = NULL; - ulReturn = SYS_ARCH_TIMEOUT; - } - } - else - { - if( pdTRUE == xQueueReceive( *mbox, &( *msg ), timeout / portTICK_RATE_MS ) ) - { - xEndTime = xTaskGetTickCount(); - xElapsed = ( xEndTime - xStartTime ) * portTICK_RATE_MS; + void *dummyptr; - ulReturn = xElapsed; - } - else - { - /* Timed out. */ - *msg = NULL; - ulReturn = SYS_ARCH_TIMEOUT; - } - } + BaseType_t err; + + portTickType xStartTime, xEndTime, xElapsed; + unsigned long ulReturn; + portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; - } - else // block forever for a message. - { + xStartTime = xTaskGetTickCount(); - if(isr_calling_flg != 0) + if (*mbox == NULL) { - xQueueReceiveFromISR(*mbox, &(*msg), &xHigherPriorityTaskWoken); - if(xHigherPriorityTaskWoken == pdTRUE) - { - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); - } + return SYS_ARCH_TIMEOUT; } - else - { - xQueueReceive(*mbox, &(*msg), portMAX_DELAY); - } - xEndTime = xTaskGetTickCount(); - xElapsed = ( xEndTime - xStartTime ) * portTICK_RATE_MS; - - if( xElapsed == 0UL ) - { - xElapsed = 1UL; - } + if (msg == NULL) + { + msg = &dummyptr; + } - ulReturn = xElapsed; + if (timeout != 0) + { - - // err = xQueueReceive(*mbox, &(*msg), portMAX_DELAY); + if (vApplicationInIrq() != 0) + { + if (pdTRUE == xQueueReceiveFromISR(*mbox, &(*msg), &xHigherPriorityTaskWoken)) + { + xEndTime = xTaskGetTickCount(); + xElapsed = (xEndTime - xStartTime) * portTICK_RATE_MS; + ulReturn = xElapsed; + if (xHigherPriorityTaskWoken == pdTRUE) + { + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + } + } + else + { + *msg = NULL; + ulReturn = SYS_ARCH_TIMEOUT; + } + } + else + { + if (pdTRUE == xQueueReceive(*mbox, &(*msg), timeout / portTICK_RATE_MS)) + { + xEndTime = xTaskGetTickCount(); + xElapsed = (xEndTime - xStartTime) * portTICK_RATE_MS; + + ulReturn = xElapsed; + } + else + { + /* Timed out. */ + *msg = NULL; + ulReturn = SYS_ARCH_TIMEOUT; + } + } - // if (pdTRUE != err) - // { - // LWIP_ASSERT("sys_arch_mbox_fetch xQueueReceive returned with error!", err == pdTRUE); - // } + } + else // block forever for a message. + { - // EndTime = xTaskGetTickCount(); - // Elapsed = (EndTime - StartTime) * portTICK_RATE_MS; + if (vApplicationInIrq() != 0) + { + xQueueReceiveFromISR(*mbox, &(*msg), &xHigherPriorityTaskWoken); + if (xHigherPriorityTaskWoken == pdTRUE) + { + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + } + } + else + { + xQueueReceive(*mbox, &(*msg), portMAX_DELAY); + } + + xEndTime = xTaskGetTickCount(); + xElapsed = (xEndTime - xStartTime) * portTICK_RATE_MS; + + if (xElapsed == 0UL) + { + xElapsed = 1UL; + } + + ulReturn = xElapsed; - // return (Elapsed); // return time blocked TODO test - } - return ulReturn; + } + return ulReturn; } /*-----------------------------------------------------------------------------------*/ @@ -295,65 +305,61 @@ u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) */ u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) { - void *dummyptr; - long lResult; - unsigned long ulReturn; - portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; - if (*mbox == NULL) - { - return SYS_ARCH_TIMEOUT; - } - - if (msg == NULL) - { - msg = &dummyptr; - } - - if(isr_calling_flg != 0) - { - lResult = xQueueReceiveFromISR( *mbox, &( *msg ), &xHigherPriorityTaskWoken ); - if (xHigherPriorityTaskWoken == pdTRUE) - { - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); - } - } - else - { - lResult = xQueueReceive( *mbox, &( *msg ), 0UL ); - } - - if( lResult == pdPASS ) - { - ulReturn = ERR_OK; - } - else - { - ulReturn = SYS_MBOX_EMPTY; - } - - return ulReturn; - -// if (pdTRUE == xQueueReceive(*mbox, &(*msg), 0)) -// { -// return ERR_OK; -// } -// else -// { -// return SYS_MBOX_EMPTY; -// } + void *dummyptr; + long lResult; + unsigned long ulReturn; + portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; + if (*mbox == NULL) + { + return SYS_ARCH_TIMEOUT; + } + + if (msg == NULL) + { + msg = &dummyptr; + } + + if (vApplicationInIrq() != 0) + { + lResult = xQueueReceiveFromISR(*mbox, &(*msg), &xHigherPriorityTaskWoken); + if (xHigherPriorityTaskWoken == pdTRUE) + { + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + } + } + else + { + lResult = xQueueReceive(*mbox, &(*msg), 0UL); + } + + if (lResult == pdPASS) + { + ulReturn = ERR_OK; + } + else + { + ulReturn = SYS_MBOX_EMPTY; + } + + return ulReturn; + } /*----------------------------------------------------------------------------------*/ int sys_mbox_valid(sys_mbox_t *mbox) { - if (*mbox == SYS_MBOX_NULL) - return 0; - else - return 1; + if (*mbox == SYS_MBOX_NULL) + { + return 0; + } + else + { + return 1; + } } /*-----------------------------------------------------------------------------------*/ void sys_mbox_set_invalid(sys_mbox_t *mbox) { - *mbox = SYS_MBOX_NULL; + *mbox = SYS_MBOX_NULL; } /*-----------------------------------------------------------------------------------*/ @@ -361,30 +367,30 @@ void sys_mbox_set_invalid(sys_mbox_t *mbox) // the initial state of the semaphore. err_t sys_sem_new(sys_sem_t *sem, u8_t count) { - vSemaphoreCreateBinary(*sem); + vSemaphoreCreateBinary(*sem); - if (*sem == NULL) - { + if (*sem == NULL) + { #if SYS_STATS - ++lwip_stats.sys.sem.err; + ++lwip_stats.sys.sem.err; #endif /* SYS_STATS */ - return ERR_MEM; - } + return ERR_MEM; + } - if (count == 0) // Means it can't be taken - { - xSemaphoreTake(*sem, 1); - } + if (count == 0) // Means it can't be taken + { + xSemaphoreTake(*sem, 1); + } #if SYS_STATS - ++lwip_stats.sys.sem.used; - if (lwip_stats.sys.sem.max < lwip_stats.sys.sem.used) - { - lwip_stats.sys.sem.max = lwip_stats.sys.sem.used; - } + ++lwip_stats.sys.sem.used; + if (lwip_stats.sys.sem.max < lwip_stats.sys.sem.used) + { + lwip_stats.sys.sem.max = lwip_stats.sys.sem.used; + } #endif /* SYS_STATS */ - return ERR_OK; + return ERR_OK; } /*-----------------------------------------------------------------------------------*/ @@ -406,151 +412,126 @@ err_t sys_sem_new(sys_sem_t *sem, u8_t count) u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) { - portTickType xStartTime, xEndTime, xElapsed; - portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; - BaseType_t err; - unsigned long ulReturn; - - xStartTime = xTaskGetTickCount(); - - if (*sem == NULL) - return SYS_ARCH_TIMEOUT; - - if (timeout != 0) - { - - if(isr_calling_flg != 0) - { - if( xSemaphoreTakeFromISR( *sem, &xHigherPriorityTaskWoken ) == pdTRUE ) - { - xEndTime = xTaskGetTickCount(); - xElapsed = (xEndTime - xStartTime) * portTICK_RATE_MS; - ulReturn = xElapsed; - if (xHigherPriorityTaskWoken == pdTRUE) - { - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); - } - } - else - { - ulReturn = SYS_ARCH_TIMEOUT; - } - } - else - { - if (xSemaphoreTake(*sem, timeout / portTICK_RATE_MS) == pdTRUE) - { - xEndTime = xTaskGetTickCount(); - xElapsed = (xEndTime - xStartTime) * portTICK_RATE_MS; - - return (xElapsed); // return time blocked TODO test - } - else - { - return SYS_ARCH_TIMEOUT; - } - } - - // if (xSemaphoreTake(*sem, timeout / portTICK_RATE_MS) == pdTRUE) - // { - // EndTime = xTaskGetTickCount(); - // Elapsed = (EndTime - StartTime) * portTICK_RATE_MS; - - // return (Elapsed); // return time blocked TODO test - // } - // else - // { - // return SYS_ARCH_TIMEOUT; - // } - } - else // must block without a timeout - { - - if(isr_calling_flg != 0) - { - xSemaphoreTakeFromISR( *sem, &xHigherPriorityTaskWoken ); - if (xHigherPriorityTaskWoken == pdTRUE) - { - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); - } - } - else - { - xSemaphoreTake(*sem, portMAX_DELAY); - } - - xEndTime = xTaskGetTickCount(); - xElapsed = ( xEndTime - xStartTime ) * portTICK_RATE_MS; - - if( xElapsed == 0UL ) - { - xElapsed = 1UL; - } - - ulReturn = xElapsed; - - // err = xSemaphoreTake(*sem, portMAX_DELAY); - - // if (pdTRUE != err) - // { - // LWIP_ASSERT("sys_arch_mbox_fetch xQueueReceive returned with error!", err == pdTRUE); - // } - - // EndTime = xTaskGetTickCount(); - // Elapsed = (EndTime - StartTime) * portTICK_RATE_MS; - - // return (Elapsed); // return time blocked - } - return ulReturn ; + portTickType xStartTime, xEndTime, xElapsed; + portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; + BaseType_t err; + unsigned long ulReturn; + + xStartTime = xTaskGetTickCount(); + + if (*sem == NULL) + { + return SYS_ARCH_TIMEOUT; + } + + if (timeout != 0) + { + + if (vApplicationInIrq() != 0) + { + if (xSemaphoreTakeFromISR(*sem, &xHigherPriorityTaskWoken) == pdTRUE) + { + xEndTime = xTaskGetTickCount(); + xElapsed = (xEndTime - xStartTime) * portTICK_RATE_MS; + ulReturn = xElapsed; + if (xHigherPriorityTaskWoken == pdTRUE) + { + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + } + } + else + { + ulReturn = SYS_ARCH_TIMEOUT; + } + } + else + { + if (xSemaphoreTake(*sem, timeout / portTICK_RATE_MS) == pdTRUE) + { + xEndTime = xTaskGetTickCount(); + xElapsed = (xEndTime - xStartTime) * portTICK_RATE_MS; + + return (xElapsed); // return time blocked TODO test + } + else + { + return SYS_ARCH_TIMEOUT; + } + } + + } + else // must block without a timeout + { + + if (vApplicationInIrq() != 0) + { + xSemaphoreTakeFromISR(*sem, &xHigherPriorityTaskWoken); + if (xHigherPriorityTaskWoken == pdTRUE) + { + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + } + } + else + { + xSemaphoreTake(*sem, portMAX_DELAY); + } + + xEndTime = xTaskGetTickCount(); + xElapsed = (xEndTime - xStartTime) * portTICK_RATE_MS; + + if (xElapsed == 0UL) + { + xElapsed = 1UL; + } + + ulReturn = xElapsed; + + } + return ulReturn ; } /*-----------------------------------------------------------------------------------*/ // Signals a semaphore void sys_sem_signal(sys_sem_t *sem) { -portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; - if (*sem == NULL) - return; - - if(isr_calling_flg != 0) - { - xSemaphoreGiveFromISR( *sem, &xHigherPriorityTaskWoken ); - if (xHigherPriorityTaskWoken == pdTRUE) - { - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); - } - } - else - { - xSemaphoreGive(*sem); - } - -} - + portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; + if (*sem == NULL) + { + return; + } -// void sys_sem_signal_fromisr(sys_sem_t *sem) -// { -// printf("sys_sem_signal_fromisr is here \r\n") ; -// portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; -// if (*sem == NULL) -// return; + if (vApplicationInIrq() != 0) + { + xSemaphoreGiveFromISR(*sem, &xHigherPriorityTaskWoken); + if (xHigherPriorityTaskWoken == pdTRUE) + { + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + } + } + else + { + xSemaphoreGive(*sem); + } -// xSemaphoreGiveFromISR(*sem,&xHigherPriorityTaskWoken); -// } +} /*-----------------------------------------------------------------------------------*/ // Deallocates a semaphore void sys_sem_free(sys_sem_t *sem) { - vSemaphoreDelete(*sem); + vSemaphoreDelete(*sem); } /*-----------------------------------------------------------------------------------*/ int sys_sem_valid(sys_sem_t *sem) { - if (*sem == SYS_SEM_NULL) - return 0; - else - return 1; + if (*sem == SYS_SEM_NULL) + { + return 0; + } + else + { + return 1; + } } /*-----------------------------------------------------------------------------------*/ @@ -560,14 +541,14 @@ int sys_sem_valid(sys_sem_t *sem) */ void sys_sem_set_invalid(sys_sem_t *sem) { - *sem = SYS_SEM_NULL; + *sem = SYS_SEM_NULL; } /*-----------------------------------------------------------------------------------*/ /* sys_init() must be called before anything else. */ void sys_init(void) { - /* nothing on FreeRTOS porting */ + /* nothing on FreeRTOS porting */ } /*-----------------------------------------------------------------------------------*/ /* Mutexes*/ @@ -586,26 +567,26 @@ void sys_init(void) err_t sys_mutex_new(sys_mutex_t *mutex) { - *mutex = xSemaphoreCreateMutex(); + *mutex = xSemaphoreCreateMutex(); - // vSemaphoreCreateBinary(*mutex); + // vSemaphoreCreateBinary(*mutex); - if (*mutex == NULL) - { + if (*mutex == NULL) + { #if SYS_STATS - ++lwip_stats.sys.mutex.err; + ++lwip_stats.sys.mutex.err; #endif /* SYS_STATS */ - return ERR_MEM; - } + return ERR_MEM; + } #if SYS_STATS - ++lwip_stats.sys.mutex.used; - if (lwip_stats.sys.mutex.max < lwip_stats.sys.mutex.used) - { - lwip_stats.sys.mutex.max = lwip_stats.sys.mutex.used; - } + ++lwip_stats.sys.mutex.used; + if (lwip_stats.sys.mutex.max < lwip_stats.sys.mutex.used) + { + lwip_stats.sys.mutex.max = lwip_stats.sys.mutex.used; + } #endif /* SYS_STATS */ - return ERR_OK; + return ERR_OK; } /*-----------------------------------------------------------------------------------*/ @@ -613,50 +594,56 @@ err_t sys_mutex_new(sys_mutex_t *mutex) void sys_mutex_free(sys_mutex_t *mutex) { #if SYS_STATS - --lwip_stats.sys.mutex.used; + --lwip_stats.sys.mutex.used; #endif /* SYS_STATS */ - vSemaphoreDelete(*mutex); + vSemaphoreDelete(*mutex); } /*-----------------------------------------------------------------------------------*/ /* Lock a mutex*/ void sys_mutex_lock(sys_mutex_t *mutex) { - portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; - if (*mutex == NULL) - return; - if(isr_calling_flg != 0) - { - xSemaphoreTakeFromISR( *mutex, &xHigherPriorityTaskWoken ); - if (xHigherPriorityTaskWoken == pdTRUE) - { - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); - } - } - else - { - sys_arch_sem_wait(mutex, 0); - } + portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; + if (*mutex == NULL) + { + return; + } + if (vApplicationInIrq() != 0) + { + xSemaphoreTakeFromISR(*mutex, &xHigherPriorityTaskWoken); + if (xHigherPriorityTaskWoken == pdTRUE) + { + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + } + } + else + { + sys_arch_sem_wait(mutex, 0); + } } /*-----------------------------------------------------------------------------------*/ /* Unlock a mutex*/ void sys_mutex_unlock(sys_mutex_t *mutex) { - portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; - if (*mutex == NULL) - return; - - if(isr_calling_flg != 0) - { - xSemaphoreGiveFromISR( *mutex, &xHigherPriorityTaskWoken ); - if (xHigherPriorityTaskWoken == pdTRUE) - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); - } - else - { - xSemaphoreGive(*mutex); - } + portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; + if (*mutex == NULL) + { + return; + } + + if (vApplicationInIrq() != 0) + { + xSemaphoreGiveFromISR(*mutex, &xHigherPriorityTaskWoken); + if (xHigherPriorityTaskWoken == pdTRUE) + { + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + } + } + else + { + xSemaphoreGive(*mutex); + } } #endif /*LWIP_COMPAT_MUTEX*/ @@ -671,20 +658,25 @@ void sys_mutex_unlock(sys_mutex_t *mutex) */ sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio) { - sys_thread_t createdTaskHandle = NULL; + sys_thread_t createdTaskHandle = NULL; + + int result; - int result; + result = xTaskCreate(thread, name, stacksize, arg, prio, &createdTaskHandle); - result = xTaskCreate(thread, name, stacksize, arg, prio, &createdTaskHandle); + if (result == pdPASS) + { + return createdTaskHandle; + } + else + { + return NULL; + } +} - if (result == pdPASS) - { - return createdTaskHandle; - } - else - { - return NULL; - } +void sys_thread_delete(sys_thread_t handle) +{ + vTaskDelete(handle); } /* @@ -705,16 +697,16 @@ sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, */ sys_prot_t sys_arch_protect(void) { - if(isr_calling_flg != 0) - { - - } - else - { - vPortEnterCritical(); - } - - return 1; + sys_prot_t cur; + + if (vApplicationInIrq() != 0) + { + return 0; + } + + cur = MFCPSR(); + MTCPSR(cur | 0xC0); + return cur; } /* @@ -726,25 +718,27 @@ sys_prot_t sys_arch_protect(void) Note: This function is based on FreeRTOS API, because no equivalent CMSIS-RTOS API is available */ -void sys_arch_unprotect(sys_prot_t pval) +void sys_arch_unprotect(sys_prot_t lev) { - (void)pval; - if(isr_calling_flg != 0) - { - - } - else - { - vPortExitCritical(); - } + if (vApplicationInIrq() != 0) + { + return ; + } + + MTCPSR(lev); } void sys_arch_assert(const char *file, int line) { - printf("sys_arch_assert: %d in %s, pcTaskGetTaskName:%s.r\n", line, file, pcTaskGetTaskName(NULL)); - while (1) - ; + SYSTEM_ARCH_PRINT_W("sys_arch_assert: %d in %s, pcTaskGetTaskName:%s.r\n", line, file, pcTaskGetTaskName(NULL)); + while (1) + ; +} + +void sys_arch_delay(const unsigned int msec) +{ + vTaskDelay(msec / portTICK_RATE_MS); } #endif /* !NO_SYS */ diff --git a/third-party/lwip-2.1.2/ports/fxmac/arch/sys_arch.h b/third-party/lwip-2.1.2/ports/arch/sys_arch.h similarity index 56% rename from third-party/lwip-2.1.2/ports/fxmac/arch/sys_arch.h rename to third-party/lwip-2.1.2/ports/arch/sys_arch.h index 112d256b..e2895989 100644 --- a/third-party/lwip-2.1.2/ports/fxmac/arch/sys_arch.h +++ b/third-party/lwip-2.1.2/ports/arch/sys_arch.h @@ -1,36 +1,40 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: sys_arch.h * Date: 2022-07-18 13:25:02 * LastEditTime: 2022-07-18 13:25:02 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- + * Description: This file is for the lwIP TCP/IP stack. + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 liuzhihong 2022/5/26 first release */ -#ifndef __SYS_ARCH_H__ -#define __SYS_ARCH_H__ +#ifndef SYS_ARCH_H +#define SYS_ARCH_H +#include "sdkconfig.h" +#include "lwipopts.h" #if !NO_SYS - -#include "FreeRTOS.h" -#include "task.h" -#include "queue.h" -#include "semphr.h" + #include "FreeRTOS.h" + #include "task.h" + #include "queue.h" + #include "semphr.h" + #include "cc.h" +#endif #ifdef __cplusplus extern "C" @@ -40,7 +44,7 @@ extern "C" #define SYS_MBOX_NULL (xQueueHandle)0 #define SYS_SEM_NULL (xSemaphoreHandle)0 #define SYS_DEFAULT_THREAD_STACK_DEPTH configMINIMAL_STACK_SIZE - +#if !NO_SYS typedef xSemaphoreHandle sys_sem_t; typedef xSemaphoreHandle sys_mutex_t; typedef xQueueHandle sys_mbox_t; @@ -55,12 +59,15 @@ typedef struct _sys_arch_state_t } sys_arch_state_t; /* Message queue constants. */ -#define archMAX_MESG_QUEUE_LENGTH (12) +void sys_thread_delete(sys_thread_t handle); +void sys_arch_delay(const unsigned int msec); +#endif + +sys_prot_t sys_arch_protect(void); +void sys_arch_unprotect(sys_prot_t pval); #ifdef __cplusplus } #endif -#endif - #endif /* __SYS_ARCH_H__ */ diff --git a/third-party/lwip-2.1.2/ports/fgmac/arch/cc.h b/third-party/lwip-2.1.2/ports/fgmac/arch/cc.h deleted file mode 100644 index 89f4042f..00000000 --- a/third-party/lwip-2.1.2/ports/fgmac/arch/cc.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2001-2003 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_ARCH_CC_H -#define LWIP_ARCH_CC_H - -/* see https://sourceforge.net/p/predef/wiki/OperatingSystems/ */ -#if defined __ANDROID__ -#define LWIP_UNIX_ANDROID -#elif defined __linux__ -#define LWIP_UNIX_LINUX -#elif defined __APPLE__ -#define LWIP_UNIX_MACH -#elif defined __OpenBSD__ -#define LWIP_UNIX_OPENBSD -#elif defined __CYGWIN__ -#define LWIP_UNIX_CYGWIN -#elif defined __GNU__ -#define LWIP_UNIX_HURD -#endif - -#define LWIP_NO_STDINT_H 1 //not include "stdint.h" - -/* define basic types */ -#include - -typedef uint8_t u8_t; // unsigned 8-bit -typedef signed char s8_t; // signed 8-bit -typedef uint16_t u16_t; // unsigned 16-bit -typedef short s16_t; // signed 16-bit -typedef uint32_t u32_t; // unsigned 32-bit -typedef long s32_t; // signed 32-bit -typedef uint64_t u64_t; // unsigned 64-bit -#if defined(__aarch64__) -typedef u64_t mem_ptr_t; -#else -typedef u32_t mem_ptr_t; -#endif - -/* define printf format */ -#define U16_F "hu" -#define S16_F "d" -#define X16_F "hx" -#define U32_F "u" -#define S32_F "d" -#define X32_F "x" -#if defined(__aarch64__) -#define SZT_F "luz" -#else -#define SZT_F "uz" -#endif - -#ifndef BYTE_ORDER -#define BYTE_ORDER LITTLE_ENDIAN -#endif - -#define LWIP_TIMEVAL_PRIVATE 0 -#include - -#define LWIP_ERRNO_INCLUDE - -#if defined(LWIP_UNIX_LINUX) || defined(LWIP_UNIX_HURD) -#define LWIP_ERRNO_STDINCLUDE 1 -#endif - -#define LWIP_RAND() ((u32_t)rand()) - -/* different handling for unit test, normally not needed */ -#ifdef LWIP_NOASSERT_ON_ERROR -#define LWIP_ERROR(message, expression, handler) do { if (!(expression)) { \ - handler;}} while(0) -#endif - -#if defined(LWIP_UNIX_ANDROID) && defined(FD_SET) -typedef __kernel_fd_set fd_set; -#endif - -#if defined(LWIP_UNIX_MACH) -/* sys/types.h and signal.h bring in Darwin byte order macros. pull the - header here and disable LwIP's version so that apps still can get - the macros via LwIP headers and use system headers */ -#include -#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS -#endif - -struct sio_status_s; -typedef struct sio_status_s sio_status_t; -#define sio_fd_t sio_status_t* -#define __sio_fd_t_defined - -typedef unsigned int sys_prot_t; - -#endif /* LWIP_ARCH_CC_H */ diff --git a/third-party/lwip-2.1.2/ports/fgmac/arch/sys_arch.h b/third-party/lwip-2.1.2/ports/fgmac/arch/sys_arch.h deleted file mode 100644 index 14234a34..00000000 --- a/third-party/lwip-2.1.2/ports/fgmac/arch/sys_arch.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2001-2003 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef __SYS_ARCH_H__ -#define __SYS_ARCH_H__ - - -#if !NO_SYS - -#include "FreeRTOS.h" -#include "task.h" -#include "queue.h" -#include "semphr.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -#define SYS_MBOX_NULL (xQueueHandle)0 -#define SYS_SEM_NULL (xSemaphoreHandle)0 -#define SYS_DEFAULT_THREAD_STACK_DEPTH configMINIMAL_STACK_SIZE - -typedef xSemaphoreHandle sys_sem_t; -typedef xSemaphoreHandle sys_mutex_t; -typedef xQueueHandle sys_mbox_t; -typedef xTaskHandle sys_thread_t; - -typedef struct _sys_arch_state_t -{ - // Task creation data. - char cTaskName[configMAX_TASK_NAME_LEN]; - unsigned short nStackDepth; - unsigned short nTaskCount; -} sys_arch_state_t; - -/* Message queue constants. */ -#define archMAX_MESG_QUEUE_LENGTH (12) - -#ifdef __cplusplus -} -#endif - -#endif - -#endif /* __SYS_ARCH_H__ */ diff --git a/third-party/lwip-2.1.2/ports/fgmac/ethernetif.c b/third-party/lwip-2.1.2/ports/fgmac/ethernetif.c index 9bcc11ff..6f54f08c 100644 --- a/third-party/lwip-2.1.2/ports/fgmac/ethernetif.c +++ b/third-party/lwip-2.1.2/ports/fgmac/ethernetif.c @@ -1,69 +1,61 @@ /* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels + * FilePath: ethernetif.c + * Date: 2022-12-09 16:42:31 + * LastEditTime: 2022-12-14 10:05:50 + * Description: This file is the function file of the gmac adaptation to lwip stack. * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 wangxiaodong 2022/6/20 first release + * 2.0 liuzhihong 2022/1/12 restructure */ + #include -#include "../include/lwip/opt.h" -#include "../include/lwip/mem.h" -#include "../include/lwip/memp.h" -#include "../include/lwip/timeouts.h" +#include "lwip/opt.h" +#include "lwip/mem.h" +#include "lwip/timeouts.h" #include "../include/netif/ethernet.h" #include "../include/lwip/etharp.h" #include "../include/lwip/debug.h" -#include "ethernetif.h" #include "sdkconfig.h" #include "fparameters.h" - +#include "lwip_port.h" #if LWIP_IPV6 -#include "lwip/ethip6.h" + #include "lwip/ethip6.h" #endif -#include "ft_os_gmac.h" +#include "fgmac_os.h" #include "fgmac.h" #include "fgmac_hw.h" #include "fgmac_phy.h" - +#include "fdebug.h" #include "fassert.h" #include "finterrupt.h" +#include "fgeneric_timer.h" #ifndef SDK_CONFIG_H__ - #error "Please include sdkconfig.h first" + #error "Please include sdkconfig.h first" #endif #ifndef CONFIG_USE_SYS_TICK - #error "Please enable system tick by CONFIG_USE_SYS_TICK first" + #error "Please enable system tick by CONFIG_USE_SYS_TICK first" #endif -#include "fgeneric_timer.h" -#include "fgmac.h" -#include "fdebug.h" + + /* The time to block waiting for input. */ #define TIME_WAITING_FOR_INPUT (portMAX_DELAY) @@ -75,470 +67,259 @@ #define ETHNETIF_DEBUG_W(format, ...) FT_DEBUG_PRINT_W(ETHNETIF_DEBUG_TAG, format, ##__VA_ARGS__) /** - * Helper struct to hold private data used to operate your ethernet interface. - * Keeping the ethernet address of the MAC in this struct is not necessary - * as it is already kept in the struct netif. - * But this is only an example, anyway... + * This function should do the actual transmission of the packet. The packet is + * contained in the pbuf that is passed to the function. This pbuf + * might be chained. + * + * @param netif the lwip network interface structure for this ethernetif + * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type) + * @return ERR_OK if the packet could be sent + * an err_t value if the packet couldn't be sent + * + * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to + * strange results. You might consider waiting for space in the DMA queue + * to become available since the stack doesn't retry to send a packet + * dropped because of memory failure (except for the TCP timers). */ -static netif_config netif_config_instance[GMAC_INSTANCE_NUM]; - -void ethernet_link_thread(void *argument) +static err_t low_level_output(struct netif *netif, struct pbuf *p) { - EventBits_t ev; - FtOsGmac *os_gmac_ptr = (FtOsGmac *)argument; - struct netif *netif = &os_gmac_ptr->netif_object; - u32 last_status = 0; - u32 flag; - - for (;;) - { - ev = xEventGroupWaitBits(os_gmac_ptr->s_status_event, - FT_NETIF_LINKUP | FT_NETIF_DOWN, - pdTRUE, pdFALSE, portMAX_DELAY); - - if (ev & FT_NETIF_DOWN) - { - netif_set_link_down(netif); - netif_set_down(netif); - last_status = FT_NETIF_DOWN; - } + FError ret ; + FGmacOs *instance_p = NULL; + FASSERT(netif != NULL); + FASSERT(netif->state != NULL); + struct LwipPort *gmac_netif_p = (struct LwipPort *)(netif->state); + FASSERT(gmac_netif_p != NULL); - else if (ev & FT_NETIF_LINKUP) - { - flag = (last_status == FT_NETIF_LINKUP) ? 0 : 1; - last_status = FT_NETIF_LINKUP; - ETHNETIF_DEBUG_I("FT_NETIF_LINKUP Linkup \r\n"); - } - else - { - ETHNETIF_DEBUG_I("EventGroup is error \r\n"); - FASSERT(0); - } + instance_p = (FGmacOs *)(gmac_netif_p->state) ; + + portENTER_CRITICAL(); +#if ETH_PAD_SIZE + pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ +#endif + + ret = FGmacOsTx(instance_p, p); - if (flag) +#if ETH_PAD_SIZE + pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ +#endif + portEXIT_CRITICAL(); + + if (ret != FT_SUCCESS) { - flag = 0; - netif_set_link_down(netif); - netif_set_down(netif); - ETHNETIF_DEBUG_I(" Start Linkup \r\n"); - FtOsGmacStop(os_gmac_ptr); - FtOsGmacStart(os_gmac_ptr); - ETHNETIF_DEBUG_I(" HardWare is ok \r\n"); - if (last_status == FT_NETIF_LINKUP) - { - vTaskDelay(500); - netif_set_up(netif); - netif_set_link_up(netif); - } + return ERR_MEM; } - } -} -void GmacReceiveCallBack(void *args) -{ - FtOsGmac *os_gmac_ptr; - os_gmac_ptr = (FtOsGmac *)args; - xSemaphoreGiveFromISR(os_gmac_ptr->s_semaphore, 0); + return ERR_OK; } -void GmacStatusCheckCallBack(void *args, u32 mac_phy_status) + +static struct pbuf *low_level_input(struct netif *netif) { - struct netif *netifPtr; - FtOsGmac *Os_GmacPtr; - BaseType_t xHigherPriorityTaskWoken = pdFALSE; - BaseType_t xResult = pdFALSE; - - netifPtr = (struct netif *)args; - Os_GmacPtr = container_of(netifPtr, FtOsGmac, netif_object); - - if (mac_phy_status & 0x8) - { - ETHNETIF_DEBUG_I("netif_set_link_up \r\n"); - xResult = xEventGroupSetBitsFromISR(Os_GmacPtr->s_status_event, FT_NETIF_LINKUP, &xHigherPriorityTaskWoken); - } - else - { - ETHNETIF_DEBUG_I("netif_set_link_down \r\n"); - xResult = xEventGroupSetBitsFromISR(Os_GmacPtr->s_status_event, FT_NETIF_DOWN, &xHigherPriorityTaskWoken); - } - - if (xResult != pdFAIL) - { - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); - } + FGmacOs *instance_p = NULL; + FASSERT(netif != NULL); + FASSERT(netif->state != NULL); + struct LwipPort *gmac_netif_p = (struct LwipPort *)(netif->state); + FASSERT(gmac_netif_p != NULL); + instance_p = (FGmacOs *)(gmac_netif_p->state) ; + + return FGmacOsRx(instance_p); } -/** - * In this function, the hardware should be initialized. - * Called from ethernetif_init(). - * - * @param netif the already initialized lwip network interface structure - * for this ethernetif - */ -static err_t low_level_init(struct netif *netif) +static void ethernetif_input(struct netif *netif) { - LWIP_ASSERT("netif != NULL", (netif != NULL)); - FGmacMacAddr mac_addr; - FGmac *gmac_ctrl; - FtOsGmac *os_gmac_ptr; - u16 reg_value = 0; - os_gmac_ptr = container_of(netif, FtOsGmac, netif_object); - gmac_ctrl = &os_gmac_ptr->gmac; - - ethernetif *ethernetif_p = (ethernetif *)(netif->state); - - netif_config *netif_config_p = container_of(ethernetif_p, netif_config, netifctrl); - - /* Create a binary semaphore used for informing ethernetif of frame reception */ - FASSERT((os_gmac_ptr->s_semaphore = xSemaphoreCreateBinary()) != NULL); - /* Create a event group used for ethernetif of status change */ - FASSERT((os_gmac_ptr->s_status_event = xEventGroupCreate()) != NULL); - - /* Init Gmac */ - FError ret = FtOsGmacInit(os_gmac_ptr, netif_config_p); - if(ret != FGMAC_SUCCESS) - { - if(ret == FGMAC_ERR_PHY_AUTO_FAILED) - { - ETHNETIF_DEBUG_E("FtOsGmacInit is failed, phy auto negotiation is not success."); - } - else + struct eth_hdr *ethhdr; + struct pbuf *p; + SYS_ARCH_DECL_PROTECT(lev); + +#if !NO_SYS + while (1) +#endif { - ETHNETIF_DEBUG_E("FtOsGmacInit is failed"); - return ERR_CONN; - } - } + /* move received packet into a new pbuf */ + SYS_ARCH_PROTECT(lev); + p = low_level_input(netif); + SYS_ARCH_UNPROTECT(lev); - /* Set Receive Callback */ - FGmacRegisterEvtHandler(gmac_ctrl, FGMAC_RX_COMPLETE_EVT, GmacReceiveCallBack); + /* no packet could be read, silently ignore this */ + if (p == NULL) + { + return; + } -#if LWIP_ARP || LWIP_ETHERNET + /* points to packet payload, which starts with an Ethernet header */ + ethhdr = p->payload; - /* set MAC hardware address length */ - netif->hwaddr_len = ETH_HWADDR_LEN; - - for(u8 i = 0; i<(sizeof(mac_addr)/sizeof(mac_addr[0])); i++) - { - mac_addr[i] = netif->hwaddr[i]; - } +#if LINK_STATS + lwip_stats.link.recv++; +#endif /* LINK_STATS */ + switch (htons(ethhdr->type)) + { + /* IP or ARP packet? */ + case ETHTYPE_IP: + case ETHTYPE_ARP: +#if LWIP_IPV6 + /*IPv6 Packet?*/ + case ETHTYPE_IPV6: +#endif +#if PPPOE_SUPPORT + /* PPPoE packet? */ + case ETHTYPE_PPPOEDISC: + case ETHTYPE_PPPOE: +#endif /* PPPOE_SUPPORT */ + + /* full packet send to tcpip_thread to process */ + if (netif->input(p, netif) != ERR_OK) + { + LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\r\n")); + pbuf_free(p); + p = NULL; + } + break; + + default: + pbuf_free(p); + p = NULL; + break; + } + } - /* set MAC hardware address */ - FGmacSetMacAddr(gmac_ctrl->config.base_addr, mac_addr); + return; +} - /* clear rgmii interrupt due to phy reset */ - reg_value = FGMAC_READ_REG32(gmac_ctrl->config.base_addr, FGMAC_MAC_PHY_STATUS); - /* maximum transfer unit */ - netif->mtu = GMAC_MTU; +static void ethernetif_start(struct netif *netif) +{ + struct LwipPort *gmac_netif_p = (struct LwipPort *)(netif->state); + if (gmac_netif_p == NULL) + { + ETHNETIF_DEBUG_E("%s,gmac_netif_p is NULL\n", __FUNCTION__); + return; + } + FGmacOs *instance_p = (FGmacOs *)(gmac_netif_p->state); + FGmacOsStart(instance_p); +} -/* Accept broadcast address and ARP traffic */ -/* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */ -#if LWIP_ARP - netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; -#else - netif->flags |= NETIF_FLAG_BROADCAST; -#endif /* LWIP_ARP */ - /* Create the task that handles the ETH_MAC */ - if (xTaskCreate((TaskFunction_t)ethernetif_input, - os_gmac_ptr->config.mac_input_thread.thread_name, - os_gmac_ptr->config.mac_input_thread.stack_depth, - os_gmac_ptr, os_gmac_ptr->config.mac_input_thread.priority, - &os_gmac_ptr->config.mac_input_thread.thread_handle) != pdPASS) +static enum lwip_port_link_status ethernetif_link_detect(struct netif *netif) +{ + struct LwipPort *gmac_netif_p = (struct LwipPort *)(netif->state); + FGmacOs *instance_p; + if (gmac_netif_p == NULL) + { + return ETH_LINK_UNDEFINED; + } + instance_p = (FGmacOs *)gmac_netif_p->state; + if (instance_p->instance.is_ready != FT_COMPONENT_IS_READY) { - ETHNETIF_DEBUG_I("xTaskCreate is Error %s\r\n", os_gmac_ptr->config.mac_input_thread.thread_name); - FASSERT(0); - } + return ETH_LINK_UNDEFINED; + } - /* Enable MAC and DMA transmission and reception */ - FtOsGmacStart(os_gmac_ptr); + return FGmacPhyStatus(gmac_netif_p); +} - /* Read Register Configuration */ - FGmacReadPhyReg(gmac_ctrl, gmac_ctrl->phy_addr, PHY_INTERRUPT_ENABLE_OFFSET, ®_value); - reg_value |= (PHY_INTERRUPT_ENABLE_LINK_FAIL); +static void ethernetif_deinit(struct netif *netif) +{ + struct LwipPort *gmac_netif_p = (struct LwipPort *)(netif->state); + if (gmac_netif_p == NULL) + { + ETHNETIF_DEBUG_E("%s,gmac_netif_p is NULL\n", __FUNCTION__); + return; + } - /* Enable Interrupt on change of link status */ - FGmacWritePhyReg(gmac_ctrl, gmac_ctrl->phy_addr, PHY_INTERRUPT_ENABLE_OFFSET, reg_value); + FGmacOs *instance_p = (FGmacOs *)(gmac_netif_p->state); -#endif /* LWIP_ARP || LWIP_ETHERNET */ + FGmacStopTrans(&instance_p->instance); - return ERR_OK; } /** - * This function should do the actual transmission of the packet. The packet is - * contained in the pbuf that is passed to the function. This pbuf - * might be chained. - * - * @param netif the lwip network interface structure for this ethernetif - * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type) - * @return ERR_OK if the packet could be sent - * an err_t value if the packet couldn't be sent + * In this function, the hardware should be initialized. + * Called from ethernetif_init(). * - * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to - * strange results. You might consider waiting for space in the DMA queue - * to become available since the stack doesn't retry to send a packet - * dropped because of memory failure (except for the TCP timers). - * - * 发送数据的过程,用户在应用层想要通过一个网卡发送数据,那么就要将数据传入LwIP内核中, - * 经过内核进行传输层封装、IP层封装等。简单来说,就是上层将要发送的数据层层封装, - * 存储在pbuf数据包中,可能数据很大,需要多个pbuf才能存放得下, - * 这时pbuf就以链表的形式存在,当发送数据的时候,就要将属于一个数据包的数据全部发送出去。 - * 此处需要注意的是,属于同一个数据包的所有数据都必须放在同一个以太网帧中发送。 + * @param netif the already initialized lwip network interface structure + * for this ethernetif */ - -static err_t low_level_output(struct netif *netif, struct pbuf *p) +static err_t low_level_init(struct netif *netif) { - err_t errval = ERR_OK; - struct pbuf *q; - u8 *buffer = NULL; - volatile FGmacDmaDesc *dma_tx_desc; - u32 frame_length = 0; - u32 buffer_offset = 0; - u32 bytes_left_to_copy = 0; - u32 pay_load_offset = 0; - - FGmac *gmac; - FtOsGmac *os_gmac; - os_gmac = (FtOsGmac *)container_of(netif, FtOsGmac, netif_object); - gmac = &os_gmac->gmac; - dma_tx_desc = &gmac->tx_desc[gmac->tx_ring.desc_buf_idx]; - buffer = (u8 *)(intptr)(dma_tx_desc->buf_addr); - - if (buffer == NULL) - { - ETHNETIF_DEBUG_I(" error buffer is 0 \r\n"); - return ERR_VAL; - } + uintptr mac_address = (uintptr)(netif->state); + struct LwipPort *gmac_netif_p; + FGmacOs *instance_p; + FGmac *gmac_p = NULL; + FError ret; + u32 dmacrreg; + FtOsGmacPhyControl os_config; + s32_t status = FT_SUCCESS; + FASSERT(netif != NULL); + FASSERT(netif->state != NULL); + UserConfig *config_p; + + gmac_netif_p = mem_malloc(sizeof * gmac_netif_p); + if (gmac_netif_p == NULL) + { + LWIP_DEBUGF(NETIF_DEBUG, ("gmac_netif_p init: out of memory\r\n")); + return ERR_MEM; + } -#if ETH_PAD_SIZE - pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ -#endif + /* obtain config of this emac */ + ETHNETIF_DEBUG_I("netif->state is %p \r\n ", netif->state); - for (q = p; q != NULL; q = q->next) - { - /* Is this buffer available? If not, goto error */ - if ((dma_tx_desc->status & FGMAC_DMA_TDES0_OWN) != 0) - { - errval = ERR_USE; - ETHNETIF_DEBUG_I("error errval = ERR_USE; \r\n"); - goto error; - } - - /* Get bytes in current lwIP buffer */ - bytes_left_to_copy = q->len; - pay_load_offset = 0; - - /* Check if the length of data to copy is bigger than Tx buffer size*/ - while ((bytes_left_to_copy + buffer_offset) > GMAC_MAX_PACKET_SIZE) - { - /* Copy data to Tx buffer*/ - memcpy((u8 *)((u8 *)buffer + buffer_offset), (u8 *)((u8 *)q->payload + pay_load_offset), (GMAC_MAX_PACKET_SIZE - buffer_offset)); - FGMAC_DMA_INC_DESC(gmac->tx_ring.desc_buf_idx, gmac->tx_ring.desc_max_num); - /* Point to next descriptor */ - dma_tx_desc = &gmac->tx_desc[gmac->tx_ring.desc_buf_idx]; - - /* Check if the Bufferis available */ - if ((dma_tx_desc->status & FGMAC_DMA_TDES0_OWN) != (u32)0) - { - errval = ERR_USE; - ETHNETIF_DEBUG_I("Check if the Bufferis available \r\n"); - goto error; - } - - buffer = (u8 *)(intptr)(dma_tx_desc->buf_addr); - bytes_left_to_copy = bytes_left_to_copy - (GMAC_MAX_PACKET_SIZE - buffer_offset); - pay_load_offset = pay_load_offset + (GMAC_MAX_PACKET_SIZE - buffer_offset); - frame_length = frame_length + (GMAC_MAX_PACKET_SIZE - buffer_offset); - buffer_offset = 0; - - if (buffer == NULL) - { - ETHNETIF_DEBUG_I(" error Buffer is 0 \r\n"); - return ERR_VAL; - } - } - - /* Copy the remaining bytes */ - memcpy((u8 *)((u8 *)buffer + buffer_offset), (u8 *)((u8 *)q->payload + pay_load_offset), bytes_left_to_copy); - buffer_offset = buffer_offset + bytes_left_to_copy; - frame_length = frame_length + bytes_left_to_copy; - } - - FGMAC_DMA_INC_DESC(gmac->tx_ring.desc_buf_idx, gmac->tx_ring.desc_max_num); + config_p = (UserConfig *)netif->state; + os_config.instance_id = config_p->mac_instance; -#if ETH_PAD_SIZE - pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ -#endif + os_config.autonegotiation = config_p->autonegotiation; /* 1 is autonegotiation ,0 is manually set */ + os_config.phy_speed = config_p->phy_speed; /* FGMAC_PHY_SPEED_XXX */ + os_config.phy_duplex = config_p->phy_duplex; /* FGMAC_PHY_XXX_DUPLEX */ - FError ret = FGmacSendFrame(gmac, frame_length); + instance_p = FGmacOsGetInstancePointer(&os_config); + if (instance_p == NULL) + { + ETHNETIF_DEBUG_E("FGmacOsGetInstancePointer is error\r\n"); + return ERR_ARG; + } - if (ret != FGMAC_SUCCESS) - { - errval = ERR_USE; - ETHNETIF_DEBUG_I("error errval = ERR_USE; FGmacSendFrame\r\n"); - goto error; - } - -error: - FGmacResmuDmaUnderflow(gmac->config.base_addr); + for (int i = 0; i < 6; i++) + { + instance_p->hwaddr[i] = netif->hwaddr[i]; + } - return errval; -} + ret = FGmacOsInit(instance_p); + if (ret != FT_SUCCESS) + { + ETHNETIF_DEBUG_E("FGmacOsInit is error\r\n"); + return ERR_ARG; + } -/** - * Should allocate a pbuf and transfer the bytes of the incoming - * packet from the interface into the pbuf. - * - * @param netif the lwip network interface structure for this ethernetif - * @return a pbuf filled with the received packet (including MAC header) - * NULL on memory error - * - * 该函数用于从网卡中接收一个数据包,并将数据包封装在pbuf中递交给上层 - */ -static struct pbuf *low_level_input(struct netif *netif) -{ - struct pbuf *p = NULL; - struct pbuf *q = NULL; - u16 length = 0; - u8 *buffer; - volatile FGmacDmaDesc *dma_rx_desc; - u32 buffer_offset = 0; - u32 pay_load_offset = 0; - u32 bytes_left_to_copy = 0; - - u32 desc_buffer_index; /* For Current Desc buffer buf position */ - FtOsGmac *os_gmac; - FGmac *gmac; - - os_gmac = (FtOsGmac *)container_of(netif, FtOsGmac, netif_object); - gmac = &os_gmac->gmac; - - /* get received frame */ - if (FGmacRecvFrame(gmac) != FT_SUCCESS) - { - return NULL; - } - - desc_buffer_index = gmac->rx_ring.desc_buf_idx; - length = (gmac->rx_desc[desc_buffer_index].status & FGMAC_DMA_RDES0_FRAME_LEN_MASK) >> FGMAC_DMA_RDES0_FRAME_LEN_SHIFT; - buffer = (u8 *)(intptr)(gmac->rx_desc[desc_buffer_index].buf_addr); + gmac_netif_p->state = (void *)instance_p; + netif->state = (void *)gmac_netif_p; /* update state */ + instance_p->stack_pointer = gmac_netif_p; -#if ETH_PAD_SIZE - length += ETH_PAD_SIZE; /* allow room for Ethernet padding */ -#endif + /* maximum transfer unit */ + netif->mtu = GMAC_MTU; - if (length > 0) - { - /* We allocate a pbuf chain of pbufs from the Lwip buffer pool */ - p = pbuf_alloc(PBUF_RAW, length, PBUF_POOL); - } + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | + NETIF_FLAG_LINK_UP; -#ifdef RAW_DATA_PRINT - dump_hex(Buffer, (u32)length); -#endif - if (p != NULL) - { -#if ETH_PAD_SIZE - pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ +#if LWIP_IPV6 && LWIP_IPV6_MLD + netif->flags |= NETIF_FLAG_MLD6; #endif - dma_rx_desc = &gmac->rx_desc[desc_buffer_index]; - buffer_offset = 0; - for (q = p; q != NULL; q = q->next) - { - bytes_left_to_copy = q->len; - pay_load_offset = 0; - /* Check if the length of bytes to copy in current pbuf is bigger than Rx buffer size*/ - while ((bytes_left_to_copy + buffer_offset) > GMAC_MAX_PACKET_SIZE) - { - /* Copy data to pbuf */ - memcpy((u8 *)((u8 *)q->payload + pay_load_offset), (u8 *)((u8 *)buffer + buffer_offset), (GMAC_MAX_PACKET_SIZE - buffer_offset)); - - /* Point to next descriptor */ - FGMAC_DMA_INC_DESC(desc_buffer_index, gmac->rx_ring.desc_max_num); - if (desc_buffer_index == gmac->rx_ring.desc_idx) - { - break; - } - - dma_rx_desc = &gmac->rx_desc[desc_buffer_index]; - buffer = (u8 *)(intptr)(dma_rx_desc->buf_addr); - - bytes_left_to_copy = bytes_left_to_copy - (GMAC_MAX_PACKET_SIZE - buffer_offset); - pay_load_offset = pay_load_offset + (GMAC_MAX_PACKET_SIZE - buffer_offset); - buffer_offset = 0; - } - /* Copy remaining data in pbuf */ - memcpy((u8 *)((u8 *)q->payload + pay_load_offset), (u8 *)((u8 *)buffer + buffer_offset), bytes_left_to_copy); - buffer_offset = buffer_offset + bytes_left_to_copy; - } -#if ETH_PAD_SIZE - pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ +#if LWIP_IGMP + netif->flags |= NETIF_FLAG_IGMP; #endif - }else - { - printf("error mallco is %d \r\n",length); - } - - /* Release descriptors to DMA */ - /* Point to first descriptor */ - dma_rx_desc = &gmac->rx_desc[desc_buffer_index]; - /* Set Own bit in Rx descriptors: gives the buffers back to DMA */ - for (desc_buffer_index = gmac->rx_ring.desc_buf_idx; desc_buffer_index != gmac->rx_ring.desc_idx; FGMAC_DMA_INC_DESC(desc_buffer_index, gmac->rx_ring.desc_max_num)) - { - dma_rx_desc->status |= FGMAC_DMA_RDES0_OWN; - dma_rx_desc = &gmac->rx_desc[desc_buffer_index]; - } - - /* Sync index */ - gmac->rx_ring.desc_buf_idx = gmac->rx_ring.desc_idx; - - FGmacResumeDmaRecv(gmac->config.base_addr); - - return p; -} + gmac_netif_p->ops.eth_detect = ethernetif_link_detect ; + gmac_netif_p->ops.eth_input = ethernetif_input; + gmac_netif_p->ops.eth_deinit = ethernetif_deinit; + gmac_netif_p->ops.eth_start = ethernetif_start; + ETHNETIF_DEBUG_I("ready to leave netif \r\n"); + return ERR_OK; +} -/** - * This function should be called when a packet is ready to be read - * from the interface. It uses the function low_level_input() that - * should handle the actual reception of bytes from the network - * interface. Then the type of the received packet is determined and - * the appropriate input function is called. - * - * @param netif the lwip network interface structure for this ethernetif - */ -void ethernetif_input(void const *argument) -{ - struct pbuf *p = 0; - FtOsGmac *os_gmac_ptr = (FtOsGmac *)argument; - struct netif *netif = &os_gmac_ptr->netif_object; - for (;;) - { - if (xSemaphoreTake(os_gmac_ptr->s_semaphore, TIME_WAITING_FOR_INPUT) == pdTRUE) - { - do - { - LOCK_TCPIP_CORE(); - p = low_level_input(netif); - if (p != NULL) - { - if (netif->input(p, netif) != ERR_OK) - { - pbuf_free(p); - } - } - UNLOCK_TCPIP_CORE(); - } while (p != NULL); - } - } -} #if !LWIP_ARP /** @@ -548,153 +329,44 @@ void ethernetif_input(void const *argument) * @return ERR_OK if ... */ static err_t low_level_output_arp_off(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr) -{ - err_t errval; - errval = ERR_OK; - - return errval; +{ + err_t errval; + errval = ERR_OK; + + return errval; } -#endif /* LWIP_ARP */ +#endif /* LWIP_ARP */ + + -/** - * Should be called at the beginning of the program to set up the - * network interface. It calls the function low_level_init() to do the - * actual setup of the hardware. - * - * This function should be passed as a parameter to netif_add(). - * - * @param netif the lwip network interface structure for this ethernetif - * @return ERR_OK if the loopif is initialized - * ERR_MEM if private data couldn't be allocated - * any other err_t on error - * 接收网卡的数据,接收完毕后将数据封装在pbuf中通过网卡netif的input接口递交给上层 - */ err_t ethernetif_init(struct netif *netif) { - LWIP_ASSERT("netif != NULL", (netif != NULL)); - err_t ret = ERR_OK; - u32 gmac_id = (u32)(uintptr)netif->state; - - memset(&netif_config_instance[gmac_id], 0, sizeof(netif_config_instance[gmac_id])); - printf("&netif_config_instance[gmac_id] = %#x\n", &netif_config_instance[gmac_id]); - LWIP_DEBUGF(NETIF_DEBUG, ("*******start init eth\n")); + LWIP_DEBUGF(NETIF_DEBUG, ("*******start init eth\n")); #if LWIP_NETIF_HOSTNAME - /* Initialize interface hostname */ - netif->hostname = "lwip"; + /* Initialize interface hostname */ + netif->hostname = "lwip"; #endif /* LWIP_NETIF_HOSTNAME */ - netif->state = &netif_config_instance[gmac_id].netifctrl; // 通过state将ethernetif结构传递到上层 - - /* We directly use etharp_output() here to save a function call. - * You can instead declare your own function an call etharp_output() - * from it if you have to do some checks before sending (e.g. if link - * is available...) */ - #if LWIP_IPV4 #if LWIP_ARP || LWIP_ETHERNET #if LWIP_ARP - netif->output = etharp_output; + netif->output = etharp_output; #else - /* The user should write ist own code in low_level_output_arp_off function */ - netif->output = low_level_output_arp_off; + /* The user should write ist own code in low_level_output_arp_off function */ + netif->output = low_level_output_arp_off; #endif /* LWIP_ARP */ #endif /* LWIP_ARP || LWIP_ETHERNET */ #endif /* LWIP_IPV4 */ + netif->linkoutput = low_level_output; #if LWIP_IPV6 - netif->output_ip6 = ethip6_output; -#endif /* LWIP_IPV6 */ - - netif->linkoutput = low_level_output; - - /* initialize the hardware */ - ret = low_level_init(netif); - - return ret; -} - -/** -* @brief Returns the current time in milliseconds -* when LWIP_TIMERS == 1 and NO_SYS == 1 -* @param None -* @retval Time -*/ -u32_t sys_jiffies(void) -{ - return GenericGetTick(); -} - -/** - * Sends a single character to the serial device. - * - * @param c character to send - * @param fd serial device handle - * - * @note This function will block until the character can be sent. - */ -void sio_send(u8_t c, sio_fd_t fd) -{ - (void)c; - (void)fd; -} - -/** - * Opens a serial device for communication. - * - * @param devnum device number - * @return handle to serial device if successful, NULL otherwise - */ -sio_fd_t sio_open(u8_t devnum) -{ - sio_fd_t sd; - (void)devnum; - - sd = 0; - - return sd; -} - -/** - * Reads from the serial device. - * - * @param fd serial device handle - * @param data pointer to data buffer for receiving - * @param len maximum length (in bytes) of data to receive - * @return number of bytes actually received - may be 0 if aborted by sio_read_abort - * - * @note This function will block until data can be received. The blocking - * can be cancelled by calling sio_read_abort(). - */ -u32_t sio_read(sio_fd_t fd, u8_t *data, u32_t len) -{ - u32_t recved_bytes; - (void)len; - (void)data; - (void)fd; + netif->output_ip6 = ethip6_output; +#endif - recved_bytes = 0; + low_level_init(netif); - return recved_bytes; + return ERR_OK; } -/** - * Tries to read from the serial device. Same as sio_read but returns - * immediately if no data is available and never blocks. - * - * @param fd serial device handle - * @param data pointer to data buffer for receiving - * @param len maximum length (in bytes) of data to receive - * @return number of bytes actually received - */ -u32_t sio_tryread(sio_fd_t fd, u8_t *data, u32_t len) -{ - u32_t recved_bytes; - (void)len; - (void)data; - (void)fd; - - recved_bytes = 0; // dummy code - return recved_bytes; -} \ No newline at end of file diff --git a/third-party/lwip-2.1.2/ports/fgmac/ethernetif.h b/third-party/lwip-2.1.2/ports/fgmac/ethernetif.h deleted file mode 100644 index c6843bf5..00000000 --- a/third-party/lwip-2.1.2/ports/fgmac/ethernetif.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright : (C) 2022 Phytium Information Technology, Inc. - * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * - * FilePath: ethernetif.h - * Date: 2022-02-24 13:42:19 - * LastEditTime: 2022-03-21 17:04:37 - * Description:  This file is for - * - * Modify History: - * Ver   Who        Date         Changes - * ----- ------     --------    -------------------------------------- - */ - -#ifndef __ETHERNETIF_H__ -#define __ETHERNETIF_H__ - -#include "lwip/err.h" -#include "lwip/netif.h" -#include "fgmac.h" -#include "fparameters.h" -#include "sdkconfig.h" - -#define GMAC_RX_DESCNUM CONFIG_GMAC_RX_DESCNUM -#define GMAC_TX_DESCNUM CONFIG_GMAC_TX_DESCNUM - -typedef struct { - struct eth_addr *ethaddr; - FGmac *ethctrl; -}ethernetif; - -typedef struct -{ - FGmac gctrl; - ethernetif netifctrl; - /* align buf and descriptor by 128 */ - u8 tx_buf[GMAC_TX_DESCNUM * GMAC_MAX_PACKET_SIZE] __aligned(GMAC_DMA_MIN_ALIGN); - u8 rx_buf[GMAC_RX_DESCNUM * GMAC_MAX_PACKET_SIZE] __aligned(GMAC_DMA_MIN_ALIGN); - u8 tx_desc[GMAC_TX_DESCNUM * sizeof(FGmacDmaDesc)] __aligned(GMAC_DMA_MIN_ALIGN); - u8 rx_desc[GMAC_RX_DESCNUM * sizeof(FGmacDmaDesc) + 128] __aligned(GMAC_DMA_MIN_ALIGN); -}netif_config; - -err_t ethernetif_init(struct netif *netif); -void ethernetif_input(void const *argument); - -#endif \ No newline at end of file diff --git a/third-party/lwip-2.1.2/ports/fgmac/ft_os_gmac.c b/third-party/lwip-2.1.2/ports/fgmac/ft_os_gmac.c deleted file mode 100644 index 887554b4..00000000 --- a/third-party/lwip-2.1.2/ports/fgmac/ft_os_gmac.c +++ /dev/null @@ -1,445 +0,0 @@ -/* - * Copyright : (C) 2022 Phytium Information Technology, Inc. - * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * - * FilePath: ft_os_gmac.c - * Date: 2022-02-24 13:42:19 - * LastEditTime: 2022-03-25 09:16:57 - * Description:  This file is for - * - * Modify History: - * Ver   Who        Date         Changes - * ----- ------     --------    -------------------------------------- - */ - - -#include -#include -#include -#include -#include -#include "ft_os_gmac.h" -#include "fgmac.h" -#include "fassert.h" -#include "fio.h" -#include "fassert.h" -#include "finterrupt.h" -#include "list.h" -#include "fcpu_info.h" -#include "fdebug.h" - -#define OS_MAC_DEBUG_TAG "OS_MAC" - -#define OS_MAC_DEBUG_D(format, ...) FT_DEBUG_PRINT_D(OS_MAC_DEBUG_TAG, format, ##__VA_ARGS__) -#define OS_MAC_DEBUG_I(format, ...) FT_DEBUG_PRINT_I(OS_MAC_DEBUG_TAG, format, ##__VA_ARGS__) -#define OS_MAC_DEBUG_E(format, ...) FT_DEBUG_PRINT_E(OS_MAC_DEBUG_TAG, format, ##__VA_ARGS__) -#define OS_MAC_DEBUG_W(format, ...) FT_DEBUG_PRINT_W(OS_MAC_DEBUG_TAG, format, ##__VA_ARGS__) - -#define FT_OS_GMACOBJECT_READLY 0x58 - -static boolean rx_data_flag = FALSE; -static FGmacConfig gmac_config; - -static void EthLinkPhyStatusChecker(void *param) -{ - FASSERT(param != NULL); - FGmac *instance_p = (FGmac *)param; - uintptr base_addr = instance_p->config.base_addr; - - u32 status = FGMAC_READ_REG32(base_addr, FGMAC_MAC_PHY_STATUS); - - if (FGMAC_RGSMIIIS_LNKSTS_UP == (FGMAC_RGSMIIIS_LNKSTS & status)) - { - FGmacPhyCfgInitialize(instance_p); - OS_MAC_DEBUG_I("link is up"); - } - else - { - OS_MAC_DEBUG_I("link is down"); - } - - return; -} - -static void EthLinkDmaErrChecker(void *param) -{ - FASSERT(param != NULL); - FGmac *instance_p = (FGmac *)param; - uintptr base_addr = instance_p->config.base_addr; - - u32 reg_val = FGMAC_READ_REG32(base_addr, FGMAC_DMA_INTR_OFFSET); - u32 status = FGMAC_READ_REG32(base_addr, FGMAC_DMA_STATUS_OFFSET); - - if ((FGMAC_DMA_STATUS_TPS & status) && (FGMAC_DMA_INTR_ENA_TSE & reg_val)) - { - OS_MAC_DEBUG_E("Transmit process stopped"); - } - - if ((FGMAC_DMA_STATUS_TU & status) && (FGMAC_DMA_INTR_ENA_TUE & reg_val)) - { - OS_MAC_DEBUG_E("Transmit Buffer Unavailable"); - } - - if ((FGMAC_DMA_STATUS_TJT & status) && (FGMAC_DMA_INTR_ENA_THE & reg_val)) - { - OS_MAC_DEBUG_E("Transmit Jabber Timeout"); - } - - if ((FGMAC_DMA_STATUS_OVF & status) && (FGMAC_DMA_INTR_ENA_OVE & reg_val)) - { - OS_MAC_DEBUG_E("Receive Overflow"); - } - - if ((FGMAC_DMA_STATUS_UNF & status) && (FGMAC_DMA_INTR_ENA_UNE & reg_val)) - { - OS_MAC_DEBUG_E("Transmit Underflow"); - } - - if ((FGMAC_DMA_STATUS_RU & status) && (FGMAC_DMA_INTR_ENA_RUE & reg_val)) - { - OS_MAC_DEBUG_E("Receive Buffer Unavailable"); - } - - if ((FGMAC_DMA_STATUS_RPS & status) && (FGMAC_DMA_INTR_ENA_RSE & reg_val)) - { - OS_MAC_DEBUG_E("Receive Process Stopped"); - } - - if ((FGMAC_DMA_STATUS_RWT & status) && (FGMAC_DMA_INTR_ENA_RWE & reg_val)) - { - OS_MAC_DEBUG_E("Receive Watchdog Timeout"); - } - - if ((FGMAC_DMA_STATUS_ETI & status) && (FGMAC_DMA_INTR_ENA_ETE & reg_val)) - { - OS_MAC_DEBUG_E("Early Transmit Interrupt"); - } - - if ((FGMAC_DMA_STATUS_FBI & status) && (FGMAC_DMA_INTR_ENA_FBE & reg_val)) - { - OS_MAC_DEBUG_E("Fatal Bus Error"); - } - - return; -} - -void EthLinkStatusChecker(void *param) -{ - FASSERT(param); - FGmac *instance_p = (FGmac *)param; - uintptr base_addr = instance_p->config.base_addr; - u32 status = FGMAC_READ_REG32(base_addr, FGMAC_MAC_PHY_STATUS); - u32 speed_status, duplex_status; - u32 speed, duplex; - - /* Check the link status */ - if (FGMAC_RGSMIIIS_LNKSTS_UP == (FGMAC_RGSMIIIS_LNKSTS & status)) - { - speed_status = FGMAC_RGSMIIIS_SPEED & status; - duplex_status = FGMAC_RGSMIIIS_LNKMODE & status; - - if (FGMAC_RGSMIIIS_SPEED_125MHZ == speed_status) - speed = FGMAC_PHY_SPEED_1000; - else if (FGMAC_RGSMIIIS_SPEED_25MHZ == speed_status) - speed = FGMAC_PHY_SPEED_100; - else - speed = FGMAC_PHY_SPEED_10; - - if (FGMAC_RGSMIIIS_LNKMODE_HALF == duplex_status) - duplex = FGMAC_PHY_MODE_HALFDUPLEX; - else - duplex = FGMAC_PHY_MODE_FULLDUPLEX; - - OS_MAC_DEBUG_I("link is up --- %d/%s", - speed, (FGMAC_PHY_MODE_FULLDUPLEX == duplex) ? "full" : "half"); - } - else - { - OS_MAC_DEBUG_I("link is down ---"); - } -} - -static void EthLinkRecvDoneCallback(void *param) -{ - FASSERT(param); - FGmac *instance_p = (FGmac *)param; - - if (TRUE == rx_data_flag) - { - OS_MAC_DEBUG_W("last rx data has not been handled !!!"); - } - - rx_data_flag = TRUE; - OS_MAC_DEBUG_I("recv data"); - return; -} - -static void EthLinkTransDoneCallback(void *param) -{ - FASSERT(param); - FGmac *instance_p = (FGmac *)param; - - FGmacResumeDmaSend(instance_p->config.base_addr); - OS_MAC_DEBUG_I("resume trans"); - return; -} - -int FtOsGmacSetupInterrupt(FGmac *instance_p) -{ - LWIP_ASSERT("instance_p != NULL", (instance_p != NULL)); - FGmacConfig *config_p = &instance_p->config; - uintptr base_addr = config_p->base_addr; - u32 irq_num = config_p->irq_num; - u32 cpu_id; - - u32 irq_priority = (config_p->irq_prority); - - if(irq_priority < (configMAX_API_CALL_INTERRUPT_PRIORITY)) - { - OS_MAC_DEBUG_E("gmac irq priority is not applicable, you need set value below configMAX_API_CALL_INTERRUPT_PRIORITY!!!"); - FASSERT(0); - } - - /* gic initialize */ - GetCpuId(&cpu_id); - InterruptSetTargetCpus(irq_num, cpu_id); - - /* disable all gmac & dma intr */ - FGmacSetInterruptMask(instance_p, FGMAC_CTRL_INTR, FGMAC_ISR_MASK_ALL_BITS); - FGmacSetInterruptMask(instance_p, FGMAC_DMA_INTR, FGMAC_DMA_INTR_ENA_ALL_MASK); - - InterruptSetPriority(irq_num, irq_priority); - InterruptInstall(irq_num, FGmacInterruptHandler, instance_p, "GMAC-IRQ"); - - /* register intr callback */ - FGmacRegisterEvtHandler(instance_p, FGMAC_PHY_STATUS_EVT, EthLinkPhyStatusChecker); - FGmacRegisterEvtHandler(instance_p, FGMAC_DMA_ERR_EVT, EthLinkDmaErrChecker); - FGmacRegisterEvtHandler(instance_p, FGMAC_LINK_STATUS_EVT, EthLinkStatusChecker); - FGmacRegisterEvtHandler(instance_p, FGMAC_TX_COMPLETE_EVT, EthLinkTransDoneCallback); - - /* umask intr */ - InterruptUmask(irq_num); - - /* enable some interrupts */ - FGmacSetInterruptUmask(instance_p, FGMAC_CTRL_INTR, FGMAC_ISR_MASK_RSIM); - FGmacSetInterruptUmask(instance_p, FGMAC_DMA_INTR, - FGMAC_DMA_INTR_ENA_NIE | FGMAC_DMA_INTR_ENA_RIE | FGMAC_DMA_INTR_ENA_AIE); - - OS_MAC_DEBUG_I("gmac setup done"); - return 0; -} - - -/** - * @name: Ft_Os_GmacMem_Create - * @msg: Initialize the Gmac TX/Rx Describe Memory 。 - * @param {*} - * @return {*} - */ - -static void FtOsGmacMemCreate(FtOsGmac *os_gmac, netif_config *netif_config_p) -{ - FASSERT(os_gmac != NULL); - - os_gmac->rx_buffer = netif_config_p->rx_buf; - if (os_gmac->rx_buffer == NULL) - { - OS_MAC_DEBUG_E("Rxbuffer Malloc is error "); - FASSERT(0); - } - - os_gmac->tx_buffer = netif_config_p->tx_buf; - if (os_gmac->tx_buffer == NULL) - { - OS_MAC_DEBUG_E("Txbuffer Malloc is error "); - FASSERT(0); - } - - os_gmac->gmac.tx_desc = (FGmacDmaDesc *)netif_config_p->tx_desc; - if (os_gmac->gmac.tx_desc == NULL) - { - OS_MAC_DEBUG_E("tx_desc Malloc is error "); - FASSERT(0); - } - - os_gmac->gmac.rx_desc = (FGmacDmaDesc *)netif_config_p->rx_desc; - if (os_gmac->gmac.rx_desc == NULL) - { - OS_MAC_DEBUG_E("rx_desc Malloc is error "); - FASSERT(0); - } - -#define ROUND_UP(x, align) (((long)(x) + ((long)align - 1)) & \ - ~((long)align - 1)) - - os_gmac->gmac.rx_desc = (FGmacDmaDesc *)ROUND_UP(os_gmac->gmac.rx_desc, 128); -} - -static void FtOsGmacMemFree(FtOsGmac *os_gmac) -{ - FASSERT(os_gmac != NULL); - if (os_gmac->rx_buffer) - { - vPortFree(os_gmac->rx_buffer); - } - - if (os_gmac->tx_buffer) - { - vPortFree(os_gmac->tx_buffer); - } - - if (os_gmac->gmac.rx_desc) - { - vPortFree((void *)(os_gmac->gmac.rx_desc)); - } - - if (os_gmac->gmac.tx_desc) - { - vPortFree((void *)(os_gmac->gmac.tx_desc)); - } -} - -/** - * @name: Ft_Os_Gmac Object_Init - * @msg: - * @param {FtOsGmac} *Os_Gmac - * @param {FtOsGmacConfig} *config - * @return {*} - */ -void FtOsGmacObjectInit(FtOsGmac *os_gmac, FtOsGmacConfig *config) -{ - FASSERT(os_gmac != NULL); - FASSERT(os_gmac->is_ready != FT_OS_GMACOBJECT_READLY); - memset(os_gmac, 0, sizeof(FtOsGmac)); - os_gmac->config = *config; - os_gmac->is_ready = FT_OS_GMACOBJECT_READLY; -} - -/** - * @name: Ft_Os_Gmac_Init - * @msg: - * @param {Ft_Os_Gmac} *Os_Gmac - * @param {u32} InstanceId - * @return {*} - */ - -FError FtOsGmacInit(FtOsGmac *os_gmac, netif_config *netif_config_p) -{ - FASSERT(os_gmac != NULL); - FASSERT(os_gmac->is_ready == FT_OS_GMACOBJECT_READLY); - const FGmacConfig *def_config_p = NULL; - FGmac *gmac; - FError ret = FGMAC_SUCCESS; - gmac = &os_gmac->gmac; - - FtOsGmacMemFree(os_gmac); - - memset(gmac, 0U, sizeof(FGmac)); - def_config_p = FGmacLookupConfig(os_gmac->config.gmac_instance); - if(NULL == def_config_p) - { - OS_MAC_DEBUG_E("gmac lookup cfg failed "); - return FGMAC_ERR_FAILED; - } - - gmac_config = *def_config_p; - gmac_config.speed = FGMAC_PHY_SPEED_1000; - gmac_config.mdc_clk_hz = FGMAC_PHY_MII_ADDR_CR_250_300MHZ; - gmac_config.en_auto_negtiation = TRUE; - gmac_config.duplex_mode = FGMAC_PHY_MODE_FULLDUPLEX; - -#ifdef CONFIG_GMAC_IRQ_PRIORITY - gmac_config.irq_prority = CONFIG_GMAC_IRQ_PRIORITY; -#else - gmac_config.irq_prority = IRQ_PRIORITY_VALUE_12; -#endif - - /* initialize gmac */ - ret = FGmacCfgInitialize(gmac, &gmac_config); - if(FGMAC_SUCCESS != ret) - { - OS_MAC_DEBUG_E("gmac cfg init failed "); - os_gmac->is_ready = 0; - return FGMAC_ERR_FAILED; - } - - FtOsGmacMemCreate(os_gmac, netif_config_p); - - /* initialize phy */ - ret = FGmacPhyCfgInitialize(gmac); - if(FGMAC_SUCCESS != ret) - { - OS_MAC_DEBUG_E("gmac phy cfg init failed "); - return FGMAC_ERR_PHY_AUTO_FAILED; - } - - return ret; -} - -/** - * @name: Ft_Os_Gmac_Start - * @msg: - * @param {Ft_Os_Gmac} *Os_Gmac - * @return {*} - */ - -void FtOsGmacStart(FtOsGmac *os_gmac) -{ - FASSERT(os_gmac != NULL); - FASSERT((os_gmac->is_ready == FT_OS_GMACOBJECT_READLY)); - - FGmac *gmac; - gmac = &os_gmac->gmac; - u32 ret = FT_SUCCESS; - - /* Initialize Rx Description list : ring Mode */ - ret = FGmacSetupRxDescRing(gmac, (FGmacDmaDesc *)(gmac->rx_desc), os_gmac->rx_buffer, GMAC_MAX_PACKET_SIZE, GMAC_RX_DESCNUM); - if (FT_SUCCESS != ret) - { - OS_MAC_DEBUG_E("gmac setup rx return err code %d\r\n", ret); - FASSERT(FT_SUCCESS == ret); - } - - /* Initialize Tx Description list : ring Mode */ - ret = FGmacSetupTxDescRing(gmac, (FGmacDmaDesc *)(gmac->tx_desc), os_gmac->tx_buffer, GMAC_MAX_PACKET_SIZE, GMAC_TX_DESCNUM); - if (FT_SUCCESS != ret) - { - OS_MAC_DEBUG_E("gmac setup tx return err code %d\r\n", ret); - FASSERT(FT_SUCCESS == ret); - } - - /* enable gmac */ - FGmacStartTrans(gmac); - - /* Gmac interrupt init */ - FtOsGmacSetupInterrupt(gmac); - - return; -} - -void FtOsGmacStop(FtOsGmac *os_gmac) -{ - FGmac *gmac; - - FASSERT(os_gmac != NULL); - FASSERT((os_gmac->is_ready == FT_OS_GMACOBJECT_READLY)); - gmac = &os_gmac->gmac; - - /* disable all gmac & dma intr */ - FGmacSetInterruptMask(gmac, FGMAC_CTRL_INTR, FGMAC_ISR_MASK_ALL_BITS); - FGmacSetInterruptMask(gmac, FGMAC_DMA_INTR, FGMAC_DMA_INTR_ENA_ALL_MASK); - - /* umask intr */ - InterruptMask(gmac->config.irq_num); - - FGmacStopTrans(gmac); -} diff --git a/third-party/lwip-2.1.2/ports/fgmac/lwip_port.c b/third-party/lwip-2.1.2/ports/fgmac/lwip_port.c deleted file mode 100644 index 3217749a..00000000 --- a/third-party/lwip-2.1.2/ports/fgmac/lwip_port.c +++ /dev/null @@ -1,369 +0,0 @@ -/* - * Copyright : (C) 2022 Phytium Information Technology, Inc. - * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * - * FilePath: lwip_port.c - * Date: 2022-06-09 16:03:57 - * LastEditTime: 2022-06-09 16:03:57 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- - */ - -#include - -#include "sdkconfig.h" -#ifndef SDK_CONFIG_H__ - #warning "Please include sdkconfig.h" -#endif - -#include "lwipopts.h" - -#ifdef CONFIG_LWIP_FXMAC -#include "fxmac.h" -#include "ethernetif.h" -#include "eth_ieee_reg.h" -#endif - -#ifdef CONFIG_LWIP_FGMAC -#include "ethernetif.h" -#include "fgmac.h" -#include "fgmac_phy.h" -#include "fgmac_hw.h" -#endif - -#include "lwip/mem.h" -#include "lwip/stats.h" -#include "lwip/sys.h" -#include "lwip/ip.h" -#include "lwip/tcp.h" -#include "lwip/udp.h" -#include "lwip/priv/tcp_priv.h" -#include "lwip/ip_addr.h" -#include "lwip/init.h" - -#include "netif/etharp.h" -#include "lwip_port.h" -#include "fparameters.h" -#include "ftypes.h" -#include "fdebug.h" -#include "fgeneric_timer.h" - -#if !NO_SYS -#include "lwip/tcpip.h" -#endif - -#ifdef OS_IS_FREERTOS -#define THREAD_STACKSIZE 256 -#define LINK_DETECT_THREAD_INTERVAL 1000 /* one second */ - -void link_detect_thread(void *p); -#endif - -#define LWIP_PORT_DEBUG_TAG "LWIP-PORT" -#define LWIP_PORT_ERROR(format, ...) FT_DEBUG_PRINT_E(LWIP_PORT_DEBUG_TAG, format, ##__VA_ARGS__) -#define LWIP_PORT_INFO(format, ...) FT_DEBUG_PRINT_I(LWIP_PORT_DEBUG_TAG, format, ##__VA_ARGS__) -#define LWIP_PORT_DEBUG(format, ...) FT_DEBUG_PRINT_D(LWIP_PORT_DEBUG_TAG, format, ##__VA_ARGS__) -#define LWIP_PORT_WARN(format, ...) FT_DEBUG_PRINT_W(LWIP_PORT_DEBUG_TAG, format, ##__VA_ARGS__) - -/* Define those to better describe your network interface. */ -#define IFNAME0 'f' -#define IFNAME1 't' - -enum ethernet_link_status eth_link_status = ETH_LINK_UNDEFINED; -u32 phyaddrforemac; - -volatile u32 timer_irq_cnt = 0; - -/* - * lwip_port_add: this is a wrapper around lwIP's netif_add function. - * The objective is to provide portability between the different Xilinx MAC's - * This function can be used to add both xps_ethernetlite and xps_ll_temac - * based interfaces - */ -struct netif *lwip_port_add(struct netif *netif, - ip_addr_t *ipaddr, ip_addr_t *netmask, ip_addr_t *gw, - unsigned char *mac_ethernet_address, - unsigned int mac_id) -{ - u8 i; - -#ifdef OS_IS_FREERTOS - /* Start thread to detect link periodically for Hot Plug autodetect */ - sys_thread_new("link_detect_thread", link_detect_thread, netif, - THREAD_STACKSIZE, tskIDLE_PRIORITY); -#endif - - /* set mac address */ - netif->hwaddr_len = NETIF_MAX_HWADDR_LEN; - for (i = 0; i < NETIF_MAX_HWADDR_LEN; i++) - netif->hwaddr[i] = mac_ethernet_address[i]; - - netif->name[0] = IFNAME0; - netif->name[1] = IFNAME1; - - /* initialize based on MAC type */ - return netif_add(netif, -#if LWIP_IPV4 - (const ip4_addr_t *)ipaddr, netmask, gw, -#endif - (void*)(uintptr)mac_id, - - ethernetif_init, - -#if NO_SYS - ethernet_input -#else - tcpip_input -#endif - ); - -} - -#if !NO_SYS -/* - * The input thread calls lwIP to process any received packets. - * This thread waits until a packet is received (sem_rx_data_available), - * and then calls lwip_port_input which processes 1 packet at a time. - */ -void lwip_port_input_thread(struct netif *netif) -{ - struct xmac_netif *emac = (struct xmac_netif *)netif->state; - while (1) { - /* sleep until there are packets to process - * This semaphore is set by the packet receive interrupt - * routine. - */ - sys_sem_wait(&emac->sem_rx_data_available); - - /* move all received packets to lwIP */ - lwip_port_input(netif); - } -} -#endif - -void lwip_port_input(struct netif *netif) -{ - ethernetif_input(netif); -} - -#if defined(CONFIG_LWIP_FXMAC) -static u32 phy_link_detect(FXmac *instance_p, u32 phy_addr) -{ - u16 status; - - /* Read Phy Status register twice to get the confirmation of the current - * link status. - */ - - FXmacPhyRead(instance_p, phy_addr, PHY_STATUS_REG_OFFSET, &status); - FXmacPhyRead(instance_p, phy_addr, PHY_STATUS_REG_OFFSET, &status); - - if (status & PHY_STAT_LINK_STATUS) - return 1; - return 0; -} - -static u32 phy_autoneg_status(FXmac *instance_p, u32 phy_addr) -{ - u16 status; - - /* Read Phy Status register twice to get the confirmation of the current - * link status. - */ - FXmacPhyRead(instance_p, phy_addr, PHY_STATUS_REG_OFFSET, &status); - FXmacPhyRead(instance_p, phy_addr, PHY_STATUS_REG_OFFSET, &status); - - if (status & PHY_STATUS_AUTONEGOTIATE_COMPLETE) - return 1; - return 0; -} - - - -void lwip_port_link_detect(struct netif *netif) -{ - u32 link_speed, phy_link_status; - struct xmac_netif *xmac_netif_p = (struct xmac_netif *)(netif->state); - ethernetif *ethernetif_p = (ethernetif *)(xmac_netif_p->state); - FXmac *instance_p = ðernetif_p->xmac_ctrl; - - if ((instance_p->is_ready != (u32)FT_COMPONENT_IS_READY) || - (eth_link_status == ETH_LINK_UNDEFINED)) - return; - - phy_link_status = phy_link_detect(instance_p, phyaddrforemac); - - if ((eth_link_status == ETH_LINK_UP) && (!phy_link_status)) - eth_link_status = ETH_LINK_DOWN; - - switch (eth_link_status) { - case ETH_LINK_UNDEFINED: - case ETH_LINK_UP: - return; - case ETH_LINK_DOWN: - netif_set_link_down(netif); - eth_link_status = ETH_LINK_NEGOTIATING; - LWIP_PORT_DEBUG("Ethernet Link down"); - break; - case ETH_LINK_NEGOTIATING: - if (phy_link_status && phy_autoneg_status(instance_p, phyaddrforemac)) - { - /* Initiate Phy setup to get link speed */ - netif_set_link_up(netif); - eth_link_status = ETH_LINK_UP; - LWIP_PORT_DEBUG("Ethernet Link up"); - } - break; - } -} - -#else - -static u32 phy_link_detect(FGmac *instance_p, u32 phy_addr) -{ - u16 status; - - /* Read Phy Status register twice to get the confirmation of the current - * link status. - */ - FGmacReadPhyReg(instance_p, instance_p->phy_addr, FGMAC_PHY_MII_STATUS_REG, &status); - FGmacReadPhyReg(instance_p, instance_p->phy_addr, FGMAC_PHY_MII_STATUS_REG, &status); - - if (status & FGMAC_PHY_MII_SR_LSTATUS) - return 1; - return 0; -} - -static u32 phy_autoneg_status(FGmac *instance_p, u32 phy_addr) -{ - u16 status; - - /* Read Phy Status register twice to get the confirmation of the current - * link status. - */ - FGmacReadPhyReg(instance_p, instance_p->phy_addr, FGMAC_PHY_MII_STATUS_REG, &status); - FGmacReadPhyReg(instance_p, instance_p->phy_addr, FGMAC_PHY_MII_STATUS_REG, &status); - - if (status & FGMAC_PHY_MII_SR_AUTO_NEGOT_COMPLETE) - return 1; - return 0; -} - -void lwip_port_link_detect(struct netif *netif) -{ - u32 link_speed, phy_link_status; - enum ethernet_link_status link_status; - - ethernetif *mac_netif = (ethernetif *)(netif->state); - FGmac *instance_p = mac_netif->ethctrl; - - if (instance_p->is_ready != FT_COMPONENT_IS_READY) - { - LWIP_PORT_ERROR("instance_p is not ready\n"); - return; - } - - /* read gmac phy link status */ - phy_link_status = phy_link_detect(instance_p, instance_p->phy_addr); - link_status = phy_link_status ? ETH_LINK_UP : ETH_LINK_DOWN; - - /* if the link status is changed */ - if(eth_link_status != link_status) - eth_link_status = link_status; - else - return; - - switch (eth_link_status) - { - case ETH_LINK_UP: - if (phy_link_status && phy_autoneg_status(instance_p, instance_p->phy_addr)) - { - netif_set_link_up(netif); - eth_link_status = ETH_LINK_UP; - LWIP_PORT_DEBUG("Ethernet Link up\r\n"); - } - break; - case ETH_LINK_DOWN: - netif_set_link_down(netif); - LWIP_PORT_DEBUG("Ethernet Link down\r\n"); - break; - default: - break; - } - - return; -} - - -void lwip_port_start(struct netif *netif) -{ - u32 link_speed, phy_link_status; - enum ethernet_link_status link_status; - - ethernetif *mac_netif = (ethernetif *)(netif->state); - FGmac *instance_p = mac_netif->ethctrl; - - if (instance_p->is_ready != FT_COMPONENT_IS_READY) - { - LWIP_PORT_ERROR("instance_p is not ready\n"); - return; - } - FGmacStartTrans(instance_p); -} - -void lwip_port_stop(struct netif *netif) -{ - u32 link_speed, phy_link_status; - enum ethernet_link_status link_status; - - ethernetif *mac_netif = (ethernetif *)(netif->state); - FGmac *instance_p = mac_netif->ethctrl; - - if (instance_p->is_ready != FT_COMPONENT_IS_READY) - { - LWIP_PORT_ERROR("instance_p is not ready\n"); - return; - } - - FGmacStopTrans(instance_p); -} - -#endif - -/** -* @brief Returns the current time in milliseconds -* when LWIP_TIMERS == 1 and NO_SYS == 1 -* @param None -* @retval Time -*/ -u32_t sys_now(void) -{ - return GenericGetTick(); -} - -#ifdef OS_IS_FREERTOS -void link_detect_thread(void *p) -{ - struct netif *netif = (struct netif *) p; - - while (1) { - /* Call lwip_port_link_detect() every second to detect Ethernet link - * change. - */ - lwip_port_link_detect(netif); - vTaskDelay(LINK_DETECT_THREAD_INTERVAL / portTICK_RATE_MS); - } -} -#endif diff --git a/third-party/lwip-2.1.2/ports/fgmac/lwip_port.h b/third-party/lwip-2.1.2/ports/fgmac/lwip_port.h deleted file mode 100644 index 16d45f8a..00000000 --- a/third-party/lwip-2.1.2/ports/fgmac/lwip_port.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright : (C) 2022 Phytium Information Technology, Inc. - * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * - * FilePath: lwip_port.h - * Date: 2022-04-06 14:46:52 - * LastEditTime: 2022-04-06 14:46:53 - * Description:  This file is for - * - * Modify History: - * Ver   Who        Date         Changes - * ----- ------     --------    -------------------------------------- - */ - -#ifndef __LWIP_PORT_H_ -#define __LWIP_PORT_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "lwipopts.h" - -#if !NO_SYS -#ifdef OS_IS_XILKERNEL -#include "xmk.h" -#endif -#include "lwip/sys.h" -#endif - -#include "lwip/netif.h" -#include "lwip/ip.h" - -struct xmac_netif { - void *state; -#if !NO_SYS - sys_sem_t sem_rx_data_available; -#endif -#if defined(OS_IS_FREERTOS) && defined(__arm__) && !defined(ARMR5) - TimerHandle_t xTimer; -#endif -}; - -enum ethernet_link_status { - ETH_LINK_UNDEFINED = 0, - ETH_LINK_UP, - ETH_LINK_DOWN, - ETH_LINK_NEGOTIATING -}; - -void lwip_port_link_detect(struct netif *netif); -void lwip_port_input(struct netif *netif); -void lwip_port_input_thread(struct netif *netif); -struct netif *lwip_port_add(struct netif *netif, - ip_addr_t *ipaddr, ip_addr_t *netmask, ip_addr_t *gw, - unsigned char *mac_ethernet_address, - unsigned int mac_id); - -void lwip_port_start(struct netif *netif); -void lwip_port_stop(struct netif *netif); - -#if defined(__arm__) || defined(__aarch64__) -void lwip_port_resetrx_on_no_rxdata(struct netif *netif); -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/third-party/lwip-2.1.2/ports/fgmac/lwipopts.h b/third-party/lwip-2.1.2/ports/fgmac/lwipopts.h deleted file mode 100644 index bf08f1a4..00000000 --- a/third-party/lwip-2.1.2/ports/fgmac/lwipopts.h +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright (c) 2001-2003 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_LWIPOPTS_H -#define LWIP_LWIPOPTS_H - -#include "sdkconfig.h" -#ifndef SDK_CONFIG_H__ - #warning "Please include sdkconfig.h" -#endif - -#include "arch/sys_arch.h" - - -#ifdef CONFIG_LWIP_IPV4_TEST -#define LWIP_IPV4 1 -#define LWIP_IPV6 0 -#define LWIP_IPV6_MLD 0 -/* ---------- DHCP options ---------- */ -/* Define LWIP_DHCP to 1 if you want DHCP configuration of - interfaces. */ -#define LWIP_DHCP 0 -#endif - -#ifdef CONFIG_LWIP_IPV4_DHCP_TEST -#define LWIP_IPV4 1 -#define LWIP_IPV6 0 -#define LWIP_IPV6_MLD 0 -/* ---------- DHCP options ---------- */ -/* Define LWIP_DHCP to 1 if you want DHCP configuration of - interfaces. */ -#define LWIP_DHCP 1 -#endif - -#ifdef CONFIG_LWIP_IPV6_TEST -#define LWIP_IPV4 0 -#define LWIP_IPV6 1 -#define LWIP_IPV6_MLD 0 -/* ---------- DHCP options ---------- */ -/* Define LWIP_DHCP to 1 if you want DHCP configuration of - interfaces. */ -#define LWIP_DHCP 0 -#endif - -#define NO_SYS 0 /* 无操作系统模拟层, 只提供RAW CALL */ -#define LWIP_SOCKET (NO_SYS==0) -#define LWIP_NETCONN (NO_SYS==0) -#define LWIP_NETIF_API (NO_SYS==0) - -#define LWIP_IGMP LWIP_IPV4 -#define LWIP_ICMP LWIP_IPV4 - - -#define TCP_LISTEN_BACKLOG 1 - -#define LWIP_SO_RCVTIMEO 1 -#define LWIP_SO_RCVBUF 1 - -#define LWIP_TCPIP_CORE_LOCKING 1 - -#define LWIP_NETIF_LINK_CALLBACK 0 //支持来自接口的回调函数 -#define LWIP_NETIF_STATUS_CALLBACK 1 -#define LWIP_NETIF_EXT_STATUS_CALLBACK 1 - -#ifndef LWIP_DEBUG -#define LWIP_DEBUG //打印调试信息 -#endif - -#ifdef LWIP_DEBUG -#define PPP_DEBUG LWIP_DBG_OFF -#define MEM_DEBUG LWIP_DBG_OFF -#define MEMP_DEBUG LWIP_DBG_OFF -#define PBUF_DEBUG LWIP_DBG_OFF -#define API_LIB_DEBUG LWIP_DBG_OFF -#define API_MSG_DEBUG LWIP_DBG_OFF -#define TCPIP_DEBUG LWIP_DBG_OFF -#define SOCKETS_DEBUG LWIP_DBG_OFF -#define DNS_DEBUG LWIP_DBG_OFF -#define AUTOIP_DEBUG LWIP_DBG_OFF -#define IP_DEBUG LWIP_DBG_OFF -#define IP_REASS_DEBUG LWIP_DBG_OFF -#define ICMP_DEBUG LWIP_DBG_OFF -#define IGMP_DEBUG LWIP_DBG_OFF -#define UDP_DEBUG LWIP_DBG_OFF -#define TCP_DEBUG LWIP_DBG_OFF -#define TCP_INPUT_DEBUG LWIP_DBG_OFF -#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF -#define TCP_RTO_DEBUG LWIP_DBG_OFF -#define TCP_CWND_DEBUG LWIP_DBG_OFF -#define TCP_WND_DEBUG LWIP_DBG_OFF -#define TCP_FR_DEBUG LWIP_DBG_OFF -#define TCP_QLEN_DEBUG LWIP_DBG_OFF -#define TCP_RST_DEBUG LWIP_DBG_OFF -#endif - -#define NETIF_DEBUG LWIP_DBG_ON -#define DHCP_DEBUG LWIP_DBG_ON - -/* ---------- Memory options ---------- */ -/* MEM_ALIGNMENT: should be set to the alignment of the CPU for which - lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2 - byte alignment -> define MEM_ALIGNMENT to 2. */ -/* MSVC port: intel processors don't need 4-byte alignment, - but are faster that way! */ -#define MEM_ALIGNMENT 4U //设置为编译LwIP的CPU的对齐方式 - -/* MEM_SIZE: the size of the heap memory. If the application will send -a lot of data that needs to be copied, this should be set high. */ -#define MEM_SIZE ( 1024 * 1024) // 最大可以分配的内存 - -/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application - sends a lot of data out of ROM (or other static memory), this - should be set high. */ -#define MEMP_NUM_PBUF 50 //内存池中pbuf的数量 -/* MEMP_NUM_RAW_PCB: the number of UDP protocol control blocks. One - per active RAW "connection". */ -#define MEMP_NUM_RAW_PCB 10 -/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One - per active UDP "connection". */ -#define MEMP_NUM_UDP_PCB 6 //UDP控制块的数量 -/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP - connections. */ -#define MEMP_NUM_TCP_PCB 10 //TCP控制块的数量 -/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP - connections. */ -#define MEMP_NUM_TCP_PCB_LISTEN 8 //侦听TCP连接的数量 -/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP - segments. */ -#define MEMP_NUM_TCP_SEG 12 //同时排队的TCP块的数量 -/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active - timeouts. */ -#define MEMP_NUM_SYS_TIMEOUT (LWIP_NUM_SYS_TIMEOUT_INTERNAL + 8) //同时活动的超时数 - -/* The following four are used only with the sequential API and can be - set to 0 if the application only will use the raw API. */ -/* MEMP_NUM_NETBUF: the number of struct netbufs. */ -#define MEMP_NUM_NETBUF 2 -/* MEMP_NUM_NETCONN: the number of struct netconns. */ -#define MEMP_NUM_NETCONN 10 -/* MEMP_NUM_TCPIP_MSG_*: the number of struct tcpip_msg, which is used - for sequential API communication and incoming packets. Used in - src/api/tcpip.c. */ -#define MEMP_NUM_TCPIP_MSG_API 16 -#define MEMP_NUM_TCPIP_MSG_INPKT 16 - -/* ---------- Pbuf options ---------- */ -/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */ -#define PBUF_POOL_SIZE (2 * 1024) /* pbuf tests need ~200KByte */ - -/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */ -#define PBUF_POOL_BUFSIZE (2 * 1024) //pbuf池中每个pbuf的大小 - -/** SYS_LIGHTWEIGHT_PROT - * define SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection - * for certain critical regions during buffer allocation, deallocation and memory - * allocation and deallocation. - */ -#define SYS_LIGHTWEIGHT_PROT (NO_SYS==0) //0, 不提供缓冲区分配释放的保护 - -/* ---------- TCP options ---------- */ -#define LWIP_TCP 1 -#define TCP_TTL 255 - -#define LWIP_ALTCP (LWIP_TCP) - -/* Controls if TCP should queue segments that arrive out of - order. Define to 0 if your device is low on memory. */ -#define TCP_QUEUE_OOSEQ 1 - -/* TCP Maximum segment size. */ -#define TCP_MSS 1024 //TCP最大报文段大小 - -/* TCP sender buffer space (bytes). */ -#define TCP_SND_BUF 2048 //TCP发送方缓冲区空间(字节) - -/* TCP sender buffer space (pbufs). This must be at least = 2 * - TCP_SND_BUF/TCP_MSS for things to work. */ -#define TCP_SND_QUEUELEN (4 * TCP_SND_BUF/TCP_MSS) - -/* TCP writable space (bytes). This must be less than or equal - to TCP_SND_BUF. It is the amount of space which must be - available in the tcp snd_buf for select to return writable */ -#define TCP_SNDLOWAT (TCP_SND_BUF/2) - -/* TCP receive window. */ -#define TCP_WND (20 * 1024) //TCP接收窗口 - -/* Maximum number of retransmissions of data segments. */ -#define TCP_MAXRTX 12 - -/* Maximum number of retransmissions of SYN segments. */ -#define TCP_SYNMAXRTX 4 - -/* IP reassembly and segmentation.These are orthogonal even - * if they both deal with IP fragments */ -#define IP_REASSEMBLY 1 -#define IP_REASS_MAX_PBUFS (10 * ((1500 + PBUF_POOL_BUFSIZE - 1) / PBUF_POOL_BUFSIZE)) -#define MEMP_NUM_REASSDATA IP_REASS_MAX_PBUFS -#define IP_FRAG 1 -#define IPV6_FRAG_COPYHEADER 1 - -/* 1 if you want to do an ARP check on the offered address - (recommended). */ -#define DHCP_DOES_ARP_CHECK (LWIP_DHCP) - -/* ---------- AUTOIP options ------- */ -#define LWIP_AUTOIP (LWIP_DHCP) -#define LWIP_DHCP_AUTOIP_COOP (LWIP_DHCP && LWIP_AUTOIP) - -/* ---------- UDP options ---------- */ -#define LWIP_UDP 1 -#define LWIP_UDPLITE LWIP_UDP - -#define LWIP_SNMP LWIP_UDP -#define MIB2_STATS LWIP_SNMP - -#define LWIP_DNS LWIP_UDP -#define LWIP_MDNS_RESPONDER LWIP_UDP - -#define LWIP_NUM_NETIF_CLIENT_DATA (LWIP_MDNS_RESPONDER) - -/* ---------- RAW options ---------- */ -#define LWIP_RAW 1 - -#define LWIP_PROVIDE_ERRNO 1 //使用errno - -/** ETH_PAD_SIZE: number of bytes added before the ethernet header to ensure - * alignment of payload after that header. Since the header is 14 bytes long, - * without this padding e.g. addresses in the IP header will not be aligned - * on a 32-bit boundary, so setting this to 2 can speed up 32-bit-platforms. - */ -#define ETH_PAD_SIZE 0 - - -/* The following defines must be done even in OPTTEST mode: */ -#if !defined(NO_SYS) || !NO_SYS /* default is 0 */ -void sys_check_core_locking(void); -#define LWIP_ASSERT_CORE_LOCKED() //sys_check_core_locking() -void sys_mark_tcpip_thread(void); -#define LWIP_MARK_TCPIP_THREAD() //sys_mark_tcpip_thread() - -#if !defined(LWIP_TCPIP_CORE_LOCKING) || LWIP_TCPIP_CORE_LOCKING /* default is 1 */ -/** The global semaphore to lock the stack. */ -extern sys_mutex_t lock_tcpip_core; -#define LOCK_TCPIP_CORE() sys_mutex_lock(&lock_tcpip_core)//sys_lock_tcpip_core() -#define UNLOCK_TCPIP_CORE() sys_mutex_unlock(&lock_tcpip_core)//sys_unlock_tcpip_core() -#endif -#endif - -#endif /* LWIP_LWIPOPTS_H */ diff --git a/third-party/lwip-2.1.2/ports/fgmac/sys_arch.c b/third-party/lwip-2.1.2/ports/fgmac/sys_arch.c deleted file mode 100644 index ddac7b62..00000000 --- a/third-party/lwip-2.1.2/ports/fgmac/sys_arch.c +++ /dev/null @@ -1,499 +0,0 @@ -/* lwIP includes. */ -#include "lwip/debug.h" -#include "lwip/def.h" -#include "lwip/sys.h" -#include "lwip/mem.h" -#include "lwip/stats.h" - -#if !NO_SYS - -#include "FreeRTOS.h" -#include "task.h" - -#if defined(LWIP_PROVIDE_ERRNO) -int errno; -#endif - -/*-----------------------------------------------------------------------------------*/ -// Creates an empty mailbox. -err_t sys_mbox_new(sys_mbox_t *mbox, int size) -{ - UBaseType_t archMessageLength = size; - - if (size > archMAX_MESG_QUEUE_LENGTH) - archMessageLength = archMAX_MESG_QUEUE_LENGTH; - - *mbox = xQueueCreate(archMessageLength, sizeof(void *)); - - if (*mbox == NULL) - return ERR_MEM; - - return ERR_OK; -} - -/*-----------------------------------------------------------------------------------*/ -/* - Deallocates a mailbox. If there are messages still present in the - mailbox when the mailbox is deallocated, it is an indication of a - programming error in lwIP and the developer should be notified. -*/ -void sys_mbox_free(sys_mbox_t *mbox) -{ - UBaseType_t uxReturn; - - uxReturn = uxQueueMessagesWaiting(*mbox); - if (uxReturn) - { - /* Line for breakpoint. Should never break here! */ - portNOP(); -#if SYS_STATS - lwip_stats.sys.mbox.err++; -#endif /* SYS_STATS */ - LWIP_ASSERT("sys_mbox_free err uxQueueMessagesWaiting.\r\n ", uxReturn == pdTRUE); - } - - vQueueDelete(*mbox); -#if SYS_STATS - --lwip_stats.sys.mbox.used; -#endif /* SYS_STATS */ -} - -/*-----------------------------------------------------------------------------------*/ -// Posts the "msg" to the mailbox. -void sys_mbox_post(sys_mbox_t *mbox, void *data) -{ - if (*mbox == NULL) - return; - - xQueueSendToBack(*mbox, &data, portMAX_DELAY); -} - -/*-----------------------------------------------------------------------------------*/ -// Try to post the "msg" to the mailbox. -err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) -{ - err_t result; - - if (*mbox == NULL) - return ERR_MEM; - - if (xQueueSend(*mbox, &msg, 0) == pdTRUE) - { - result = ERR_OK; - } - else - { -#if SYS_STATS - lwip_stats.sys.mbox.err++; -#endif /* SYS_STATS */ - // could not post, queue must be full - result = ERR_MEM; - } - - return result; -} - -/*-----------------------------------------------------------------------------------*/ -// Try to post the "msg" to the mailbox. -err_t sys_mbox_trypost_fromisr(sys_mbox_t *mbox, void *msg) -{ - err_t result; - BaseType_t xHigherPriorityTaskWoken; - - if (*mbox == NULL) - return ERR_MEM; - - if (xQueueSendFromISR(*mbox, &msg, &xHigherPriorityTaskWoken) == pdTRUE) - { - result = ERR_OK; - } - else - { - // could not post, queue must be full - result = ERR_MEM; - } - - // Actual macro used here is port specific. - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); - - return result; -} - -/*-----------------------------------------------------------------------------------*/ -/* - Blocks the thread until a message arrives in the mailbox, but does - not block the thread longer than "timeout" milliseconds (similar to - the sys_arch_sem_wait() function). The "msg" argument is a result - parameter that is set by the function (i.e., by doing "*msg = - ptr"). The "msg" parameter maybe NULL to indicate that the message - should be dropped. - - The return values are the same as for the sys_arch_sem_wait() function: - Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a - timeout. - - Note that a function with a similar name, sys_mbox_fetch(), is - implemented by lwIP. -*/ -u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) -{ - void *dummyptr; - - BaseType_t err; - - portTickType StartTime, EndTime, Elapsed; - - StartTime = xTaskGetTickCount(); - - if (*mbox == NULL) - return SYS_ARCH_TIMEOUT; - - if (msg == NULL) - { - msg = &dummyptr; - } - - if (timeout != 0) - { - if (pdTRUE == xQueueReceive(*mbox, &(*msg), timeout / portTICK_RATE_MS)) - { - EndTime = xTaskGetTickCount(); - Elapsed = (EndTime - StartTime) * portTICK_RATE_MS; - - return (Elapsed); - } - else // timed out blocking for message - { - *msg = NULL; - - return SYS_ARCH_TIMEOUT; - } - } - else // block forever for a message. - { - err = xQueueReceive(*mbox, &(*msg), portMAX_DELAY); - - if (pdTRUE != err) - { - LWIP_ASSERT("sys_arch_mbox_fetch xQueueReceive returned with error!", err == pdTRUE); - } - - EndTime = xTaskGetTickCount(); - Elapsed = (EndTime - StartTime) * portTICK_RATE_MS; - - return (Elapsed); // return time blocked TODO test - } -} - -/*-----------------------------------------------------------------------------------*/ -/* - Similar to sys_arch_mbox_fetch, but if message is not ready immediately, we'll - return with SYS_MBOX_EMPTY. On success, 0 is returned. -*/ -u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) -{ - void *dummyptr; - - if (*mbox == NULL) - return SYS_ARCH_TIMEOUT; - - if (msg == NULL) - { - msg = &dummyptr; - } - - if (pdTRUE == xQueueReceive(*mbox, &(*msg), 0)) - { - return ERR_OK; - } - else - { - return SYS_MBOX_EMPTY; - } -} -/*----------------------------------------------------------------------------------*/ -int sys_mbox_valid(sys_mbox_t *mbox) -{ - if (*mbox == SYS_MBOX_NULL) - return 0; - else - return 1; -} -/*-----------------------------------------------------------------------------------*/ -void sys_mbox_set_invalid(sys_mbox_t *mbox) -{ - *mbox = SYS_MBOX_NULL; -} - -/*-----------------------------------------------------------------------------------*/ -// Creates a new semaphore. The "count" argument specifies -// the initial state of the semaphore. -err_t sys_sem_new(sys_sem_t *sem, u8_t count) -{ - vSemaphoreCreateBinary(*sem); - - if (*sem == NULL) - { -#if SYS_STATS - ++lwip_stats.sys.sem.err; -#endif /* SYS_STATS */ - return ERR_MEM; - } - - if (count == 0) // Means it can't be taken - { - xSemaphoreTake(*sem, 1); - } - -#if SYS_STATS - ++lwip_stats.sys.sem.used; - if (lwip_stats.sys.sem.max < lwip_stats.sys.sem.used) - { - lwip_stats.sys.sem.max = lwip_stats.sys.sem.used; - } -#endif /* SYS_STATS */ - - return ERR_OK; -} - -/*-----------------------------------------------------------------------------------*/ -/* - Blocks the thread while waiting for the semaphore to be - signaled. If the "timeout" argument is non-zero, the thread should - only be blocked for the specified time (measured in - milliseconds). - - If the timeout argument is non-zero, the return value is the number of - milliseconds spent waiting for the semaphore to be signaled. If the - semaphore wasn't signaled within the specified time, the return value is - SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore - (i.e., it was already signaled), the function may return zero. - - Notice that lwIP implements a function with a similar name, - sys_sem_wait(), that uses the sys_arch_sem_wait() function. -*/ - -u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) -{ - portTickType StartTime, EndTime, Elapsed; - - BaseType_t err; - - StartTime = xTaskGetTickCount(); - - if (*sem == NULL) - return SYS_ARCH_TIMEOUT; - - if (timeout != 0) - { - if (xSemaphoreTake(*sem, timeout / portTICK_RATE_MS) == pdTRUE) - { - EndTime = xTaskGetTickCount(); - Elapsed = (EndTime - StartTime) * portTICK_RATE_MS; - - return (Elapsed); // return time blocked TODO test - } - else - { - return SYS_ARCH_TIMEOUT; - } - } - else // must block without a timeout - { - - err = xSemaphoreTake(*sem, portMAX_DELAY); - - if (pdTRUE != err) - { - LWIP_ASSERT("sys_arch_mbox_fetch xQueueReceive returned with error!", err == pdTRUE); - } - - EndTime = xTaskGetTickCount(); - Elapsed = (EndTime - StartTime) * portTICK_RATE_MS; - - return (Elapsed); // return time blocked - } -} - -/*-----------------------------------------------------------------------------------*/ -// Signals a semaphore -void sys_sem_signal(sys_sem_t *sem) -{ - - if (*sem == NULL) - return; - - xSemaphoreGive(*sem); -} - -/*-----------------------------------------------------------------------------------*/ -// Deallocates a semaphore -void sys_sem_free(sys_sem_t *sem) -{ - vSemaphoreDelete(*sem); -} -/*-----------------------------------------------------------------------------------*/ -int sys_sem_valid(sys_sem_t *sem) -{ - if (*sem == SYS_SEM_NULL) - return 0; - else - return 1; -} - -/*-----------------------------------------------------------------------------------*/ -/** - * @ingroup sys_sem - * Set a semaphore invalid so that sys_sem_valid returns 0 - */ -void sys_sem_set_invalid(sys_sem_t *sem) -{ - *sem = SYS_SEM_NULL; -} -/*-----------------------------------------------------------------------------------*/ - -/* sys_init() must be called before anything else. */ -void sys_init(void) -{ - /* nothing on FreeRTOS porting */ -} -/*-----------------------------------------------------------------------------------*/ -/* Mutexes*/ -/*-----------------------------------------------------------------------------------*/ -/*-----------------------------------------------------------------------------------*/ -#if LWIP_COMPAT_MUTEX == 0 - -/** - * @ingroup sys_mutex - * Create a new mutex. - * Note that mutexes are expected to not be taken recursively by the lwIP code, - * so both implementation types (recursive or non-recursive) should work. - * @param mutex pointer to the mutex to create - * @return ERR_OK if successful, another err_t otherwise - */ -err_t sys_mutex_new(sys_mutex_t *mutex) -{ - - *mutex = xSemaphoreCreateMutex(); - - if (*mutex == NULL) - { -#if SYS_STATS - ++lwip_stats.sys.mutex.err; -#endif /* SYS_STATS */ - return ERR_MEM; - } - -#if SYS_STATS - ++lwip_stats.sys.mutex.used; - if (lwip_stats.sys.mutex.max < lwip_stats.sys.mutex.used) - { - lwip_stats.sys.mutex.max = lwip_stats.sys.mutex.used; - } -#endif /* SYS_STATS */ - return ERR_OK; -} - -/*-----------------------------------------------------------------------------------*/ -/* Deallocate a mutex*/ -void sys_mutex_free(sys_mutex_t *mutex) -{ -#if SYS_STATS - --lwip_stats.sys.mutex.used; -#endif /* SYS_STATS */ - - vSemaphoreDelete(*mutex); -} -/*-----------------------------------------------------------------------------------*/ -/* Lock a mutex*/ -void sys_mutex_lock(sys_mutex_t *mutex) -{ - if (*mutex == NULL) - return; - - sys_arch_sem_wait(mutex, 0); -} - -/*-----------------------------------------------------------------------------------*/ -/* Unlock a mutex*/ -void sys_mutex_unlock(sys_mutex_t *mutex) -{ - if (*mutex == NULL) - return; - - xSemaphoreGive(*mutex); -} -#endif /*LWIP_COMPAT_MUTEX*/ -/*-----------------------------------------------------------------------------------*/ -// TODO -/*-----------------------------------------------------------------------------------*/ -/* - Starts a new thread with priority "prio" that will begin its execution in the - function "thread()". The "arg" argument will be passed as an argument to the - thread() function. The id of the new thread is returned. Both the id and - the priority are system dependent. -*/ -sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio) -{ - sys_thread_t createdTaskHandle = NULL; - - int result; - - result = xTaskCreate(thread, name, stacksize, arg, prio, &createdTaskHandle); - - if (result == pdPASS) - { - return createdTaskHandle; - } - else - { - return NULL; - } -} - -/* - This optional function does a "fast" critical region protection and returns - the previous protection level. This function is only called during very short - critical regions. An embedded system which supports ISR-based drivers might - want to implement this function by disabling interrupts. Task-based systems - might want to implement this by using a mutex or disabling tasking. This - function should support recursive calls from the same task or interrupt. In - other words, sys_arch_protect() could be called while already protected. In - that case the return value indicates that it is already protected. - - sys_arch_protect() is only required if your port is supporting an operating - system. - - Note: This function is based on FreeRTOS API, because no equivalent CMSIS-RTOS - API is available -*/ -sys_prot_t sys_arch_protect(void) -{ - vPortEnterCritical(); - return 1; -} - -/* - This optional function does a "fast" set of critical region protection to the - value specified by pval. See the documentation for sys_arch_protect() for - more information. This function is only required if your port is supporting - an operating system. - - Note: This function is based on FreeRTOS API, because no equivalent CMSIS-RTOS - API is available -*/ -void sys_arch_unprotect(sys_prot_t pval) -{ - (void)pval; - vPortExitCritical(); -} - -void sys_arch_assert(const char *file, int line) -{ - - printf("sys_arch_assert: %d in %s, pcTaskGetTaskName:%s.r\n", line, file, pcTaskGetTaskName(NULL)); - while (1) - ; -} - -#endif /* !NO_SYS */ diff --git a/third-party/lwip-2.1.2/ports/fxmac/ethernetif.c b/third-party/lwip-2.1.2/ports/fxmac/ethernetif.c index 6e5d1f6c..cd9ab893 100644 --- a/third-party/lwip-2.1.2/ports/fxmac/ethernetif.c +++ b/third-party/lwip-2.1.2/ports/fxmac/ethernetif.c @@ -1,24 +1,26 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: ethernetif.c * Date: 2022-07-21 19:18:46 * LastEditTime: 2022-07-21 19:18:46 - * Description: This file is for - * - * Modify History: + * Description: This file is the function file of the xmac adaptation to lwip stack. + * + * Modify History: * Ver Who Date Changes * ----- ------ -------- -------------------------------------- + * 1.0 wangxiaodong 2022/6/20 first release + * 2.0 liuzhihong 2022/1/12 restructure */ @@ -34,9 +36,8 @@ #include "lwip/stats.h" #include "lwip/igmp.h" #include "netif/etharp.h" -#include "ethernetif.h" #include "lwip_port.h" -#include "ft_os_xmac.h" +#include "fxmac_os.h" #include "fdebug.h" @@ -48,12 +49,52 @@ #if LWIP_IPV6 -#include "lwip/ethip6.h" + #include "lwip/ethip6.h" #endif -/* Define those to better describe your network interface. */ -#define IFNAME0 'f' -#define IFNAME1 't' +static void ethernetif_input(struct netif *netif); + +enum lwip_port_link_status ethernetif_link_detect(struct netif *netif) +{ + struct LwipPort *xmac_netif_p = (struct LwipPort *)(netif->state); + FXmacOs *instance_p; + if (xmac_netif_p == NULL) + { + return ETH_LINK_UNDEFINED; + } + instance_p = (FXmacOs *)xmac_netif_p->state; + if (instance_p->instance.is_ready != FT_COMPONENT_IS_READY) + { + return ETH_LINK_UNDEFINED; + } + + return FXmacPhyReconnect(xmac_netif_p); +} + +static void ethernetif_start(struct netif *netif) +{ + struct LwipPort *xmac_netif_p = (struct LwipPort *)(netif->state); + if (xmac_netif_p == NULL) + { + FXMAC_LWIP_NET_PRINT_E("%s,xmac_netif_p is NULL\n", __FUNCTION__); + return; + } + FXmacOs *instance_p = (FXmacOs *)(xmac_netif_p->state); + FXmacOsStart(instance_p); +} + +static void ethernetif_deinit(struct netif *netif) +{ + struct LwipPort *xmac_netif_p = (struct LwipPort *)(netif->state); + if (xmac_netif_p == NULL) + { + FXMAC_LWIP_NET_PRINT_E("%s,xmac_netif_p is NULL\n", __FUNCTION__); + return; + } + + FXmacOs *instance_p = (FXmacOs *)(xmac_netif_p->state); + FXmacOsStop(instance_p); +} /* * low_level_output(): @@ -78,7 +119,7 @@ static err_t low_level_output(struct netif *netif, struct pbuf *p) #if ETH_PAD_SIZE pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ #endif - + ret = FXmacOsTx(instance_p, p); #if ETH_PAD_SIZE @@ -88,7 +129,7 @@ static err_t low_level_output(struct netif *netif, struct pbuf *p) if (ret != FT_SUCCESS) { - return ERR_MEM; + return ERR_MEM; } return ERR_OK; @@ -126,7 +167,7 @@ static struct pbuf *low_level_input(struct netif *netif) * */ -void ethernetif_input(struct netif *netif) +static void ethernetif_input(struct netif *netif) { struct eth_hdr *ethhdr; struct pbuf *p; @@ -152,38 +193,38 @@ void ethernetif_input(struct netif *netif) #if LINK_STATS lwip_stats.link.recv++; - #endif /* LINK_STATS */ +#endif /* LINK_STATS */ switch (htons(ethhdr->type)) { - /* IP or ARP packet? */ - case ETHTYPE_IP: - case ETHTYPE_ARP: - #if LWIP_IPV6 - /*IPv6 Packet?*/ - case ETHTYPE_IPV6: - #endif - #if PPPOE_SUPPORT + /* IP or ARP packet? */ + case ETHTYPE_IP: + case ETHTYPE_ARP: +#if LWIP_IPV6 + /*IPv6 Packet?*/ + case ETHTYPE_IPV6: +#endif +#if PPPOE_SUPPORT /* PPPoE packet? */ - case ETHTYPE_PPPOEDISC: - case ETHTYPE_PPPOE: - #endif /* PPPOE_SUPPORT */ - - /* full packet send to tcpip_thread to process */ - if (netif->input(p, netif) != ERR_OK) - { - LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\r\n")); + case ETHTYPE_PPPOEDISC: + case ETHTYPE_PPPOE: +#endif /* PPPOE_SUPPORT */ + + /* full packet send to tcpip_thread to process */ + if (netif->input(p, netif) != ERR_OK) + { + LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\r\n")); + pbuf_free(p); + p = NULL; + } + break; + + default: pbuf_free(p); p = NULL; - } - break; - - default: - pbuf_free(p); - p = NULL; - break; + break; } } - + return; } @@ -199,9 +240,9 @@ static err_t low_level_init(struct netif *netif) s32_t status = FT_SUCCESS; FASSERT(netif != NULL); FASSERT(netif->state != NULL); - user_config *config_p; + UserConfig *config_p; - xmac_netif_p = mem_malloc(sizeof *xmac_netif_p); + xmac_netif_p = mem_malloc(sizeof * xmac_netif_p); if (xmac_netif_p == NULL) { LWIP_DEBUGF(NETIF_DEBUG, ("xmac_netif_p init: out of memory\r\n")); @@ -212,9 +253,9 @@ static err_t low_level_init(struct netif *netif) sys_sem_new(&xmac_netif_p->sem_rx_data_available, 0); #endif /* obtain config of this emac */ - FXMAC_LWIP_NET_PRINT_I("netif->state is %p \r\n ",netif->state); + FXMAC_LWIP_NET_PRINT_I("netif->state is %p \r\n ", netif->state); - config_p = (user_config *)netif->state; + config_p = (UserConfig *)netif->state; os_config.instance_id = config_p->mac_instance; switch (config_p->mii_interface) @@ -235,7 +276,7 @@ static err_t low_level_init(struct netif *netif) os_config.phy_duplex = config_p->phy_duplex; /* FXMAC_PHY_XXX_DUPLEX */ instance_p = FXmacOsGetInstancePointer(&os_config); - if(instance_p == NULL) + if (instance_p == NULL) { FXMAC_LWIP_NET_PRINT_E("FXmacOsGetInstancePointer is error\r\n"); return ERR_ARG; @@ -264,7 +305,7 @@ static err_t low_level_init(struct netif *netif) /* maximum transfer unit */ - if(instance_p->config & FXMAC_OS_CONFIG_JUMBO) + if (instance_p->config & FXMAC_OS_CONFIG_JUMBO) { netif->mtu = FXMAC_MTU_JUMBO - FXMAC_HDR_SIZE; } @@ -276,17 +317,20 @@ static err_t low_level_init(struct netif *netif) netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; +#if LWIP_IPV6 && LWIP_IPV6_MLD + netif->flags |= NETIF_FLAG_MLD6; +#endif - #if LWIP_IPV6 && LWIP_IPV6_MLD - netif->flags |= NETIF_FLAG_MLD6; - #endif - - #if LWIP_IGMP - netif->flags |= NETIF_FLAG_IGMP; - #endif +#if LWIP_IGMP + netif->flags |= NETIF_FLAG_IGMP; +#endif + xmac_netif_p->ops.eth_detect = ethernetif_link_detect ; + xmac_netif_p->ops.eth_input = ethernetif_input; + xmac_netif_p->ops.eth_deinit = ethernetif_deinit; + xmac_netif_p->ops.eth_start = ethernetif_start; - FXMAC_LWIP_NET_PRINT_I("ready to leave netif \r\n"); + FXMAC_LWIP_NET_PRINT_I("Ready to leave netif \r\n"); return ERR_OK; } @@ -299,15 +343,15 @@ static err_t low_level_init(struct netif *netif) * @return ERR_OK if ... */ static err_t low_level_output_arp_off(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr) -{ - err_t errval; - errval = ERR_OK; - - - return errval; - +{ + err_t errval; + errval = ERR_OK; + + + return errval; + } -#endif /* LWIP_ARP */ +#endif /* LWIP_ARP */ /* * ethernetif_init(): @@ -320,23 +364,20 @@ static err_t low_level_output_arp_off(struct netif *netif, struct pbuf *q, const err_t ethernetif_init(struct netif *netif) { - LWIP_DEBUGF(NETIF_DEBUG, ("*******start init eth\n")); - - netif->name[0] = IFNAME0; - netif->name[1] = IFNAME1; + LWIP_DEBUGF(NETIF_DEBUG, ("*******Start init eth\n")); #if LWIP_NETIF_HOSTNAME - /* Initialize interface hostname */ - netif->hostname = "lwip"; + /* Initialize interface hostname */ + netif->hostname = "lwip"; #endif /* LWIP_NETIF_HOSTNAME */ #if LWIP_IPV4 #if LWIP_ARP || LWIP_ETHERNET #if LWIP_ARP - netif->output = etharp_output; + netif->output = etharp_output; #else - /* The user should write ist own code in low_level_output_arp_off function */ - netif->output = low_level_output_arp_off; + /* The user should write ist own code in low_level_output_arp_off function */ + netif->output = low_level_output_arp_off; #endif /* LWIP_ARP */ #endif /* LWIP_ARP || LWIP_ETHERNET */ #endif /* LWIP_IPV4 */ @@ -350,3 +391,4 @@ err_t ethernetif_init(struct netif *netif) return ERR_OK; } + diff --git a/third-party/lwip-2.1.2/ports/fxmac/ethernetif.h b/third-party/lwip-2.1.2/ports/fxmac/ethernetif.h deleted file mode 100644 index 2b5d0e72..00000000 --- a/third-party/lwip-2.1.2/ports/fxmac/ethernetif.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright : (C) 2022 Phytium Information Technology, Inc. - * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * - * FilePath: ethernetif.h - * Date: 2022-04-02 16:43:32 - * LastEditTime: 2022-04-19 21:27:57 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- - */ - -#ifndef __ETHERNETIF_H__ -#define __ETHERNETIF_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "lwip/netif.h" -#include "netif/etharp.h" -#include "lwip/sys.h" -#include "lwip_port.h" -#include "fprintk.h" -#include "fxmac.h" -#include "arch/cc.h" - -#define MAX_FRAME_SIZE_JUMBO (FXMAC_MTU_JUMBO + FXMAC_HDR_SIZE + FXMAC_TRL_SIZE) - -err_t ethernetif_init(struct netif *netif); -void ethernetif_input(struct netif *netif); - - - -#ifdef __cplusplus -} -#endif - -#endif /* __ETHERNETIF_H__ */ diff --git a/third-party/lwip-2.1.2/ports/fxmac/lwip_port.c b/third-party/lwip-2.1.2/ports/fxmac/lwip_port.c deleted file mode 100644 index 1bbeb399..00000000 --- a/third-party/lwip-2.1.2/ports/fxmac/lwip_port.c +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright : (C) 2022 Phytium Information Technology, Inc. - * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * - * FilePath: lwip_port.c - * Date: 2022-04-06 14:46:52 - * LastEditTime: 2022-04-06 14:46:53 - * Description:  This file is for - * - * Modify History: - * Ver   Who        Date         Changes - * ----- ------     --------    -------------------------------------- - */ - -#include - -#include "sdkconfig.h" -#ifndef SDK_CONFIG_H__ - #warning "Please include sdkconfig.h" -#endif - -#include "lwipopts.h" - -#ifdef CONFIG_LWIP_FXMAC -#include "ft_os_xmac.h" -#include "ethernetif.h" -#include "eth_ieee_reg.h" -#endif - -#ifdef CONFIG_LWIP_FGMAC -#include "ethernetif.h" -#include "fgmac.h" -#include "fgmac_phy.h" -#include "fgmac_hw.h" -#endif - -#include "lwip/mem.h" -#include "lwip/stats.h" -#include "lwip/sys.h" -#include "lwip/ip.h" -#include "lwip/tcp.h" -#include "lwip/udp.h" -#include "lwip/priv/tcp_priv.h" -#include "lwip/ip_addr.h" -#include "lwip/init.h" - -#include "netif/etharp.h" -#include "lwip_port.h" -#include "fparameters.h" -#include "fprintk.h" -#include "fdebug.h" - -#if !NO_SYS -#include "lwip/tcpip.h" -#endif - -#define LWIP_PORT_DEBUG_TAG "LWIP-PORT" -#define LWIP_PORT_ERROR(format, ...) FT_DEBUG_PRINT_E(LWIP_PORT_DEBUG_TAG, format, ##__VA_ARGS__) -#define LWIP_PORT_INFO(format, ...) FT_DEBUG_PRINT_I(LWIP_PORT_DEBUG_TAG, format, ##__VA_ARGS__) -#define LWIP_PORT_DEBUG(format, ...) FT_DEBUG_PRINT_D(LWIP_PORT_DEBUG_TAG, format, ##__VA_ARGS__) -#define LWIP_PORT_WARN(format, ...) FT_DEBUG_PRINT_W(LWIP_PORT_DEBUG_TAG, format, ##__VA_ARGS__) - - -#if !NO_SYS -#define THREAD_STACKSIZE 256 -#define LINK_DETECT_THREAD_INTERVAL 1000 /* one second */ - -void link_detect_thread(void *p); -#endif - -/* Define those to better describe your network interface. */ -#define IFNAME0 'f' -#define IFNAME1 't' - -enum ethernet_link_status eth_link_status = ETH_LINK_UNDEFINED; -u32 phyaddrforemac; - -volatile u32 timer_irq_cnt = 0; - -/* - * lwip_port_add: this is a wrapper around lwIP's netif_add function. - * The objective is to provide portability between the different MAC's - * This function can be used to add both xps_ethernetlite and xps_ll_temac - * based interfaces - */ -struct netif *lwip_port_add(struct netif *netif, - ip_addr_t *ipaddr, ip_addr_t *netmask, ip_addr_t *gw, - unsigned char *mac_ethernet_address, - user_config *user_config) -{ - int i; - struct netif * netif_p ; - if(user_config->magic_code != LWIP_PORT_CONFIG_MAGIC_CODE) - { - printf("user_config is illegitmacy \r\n"); - return NULL; - } -#if !NO_SYS - /* Start thread to detect link periodically for Hot Plug autodetect */ - sys_thread_new("link_detect_thread", link_detect_thread, netif, - THREAD_STACKSIZE, tskIDLE_PRIORITY); -#endif - - /* set mac address */ - netif->hwaddr_len = 6; - for (i = 0; i < 6; i++) - netif->hwaddr[i] = mac_ethernet_address[i]; - - netif->name[0] = IFNAME0; - netif->name[1] = IFNAME1; - /* initialize based on MAC type */ - netif_p = netif_add(netif, -#if LWIP_IPV4 && LWIP_IPV6 - &ipaddr->u_addr.ip4, &netmask->u_addr.ip4, &gw->u_addr.ip4, -#elif LWIP_IPV4 - ipaddr, netmask, gw, -#endif - (void*)(uintptr)user_config, - ethernetif_init, -#if NO_SYS - ethernet_input -#else - tcpip_input -#endif - ); - - - return netif_p ; -} - -#if !NO_SYS -/* - * The input thread calls lwIP to process any received packets. - * This thread waits until a packet is received (sem_rx_data_available), - * and then calls lwip_port_input which processes 1 packet at a time. - */ -void lwip_port_input_thread(struct netif *netif) -{ - struct LwipPort *emac = (struct LwipPort *)netif->state; - - while (1) { - /* sleep until there are packets to process - * This semaphore is set by the packet receive interrupt - * routine. - */ - sys_arch_sem_wait(&emac->sem_rx_data_available,0); - /* move all received packets to lwIP */ - lwip_port_input(netif); - } -} -#endif - -void lwip_port_input(struct netif *netif) -{ - ethernetif_input(netif); -} - -extern enum ethernet_link_status FXmacPhyReconnect(struct LwipPort *xmac_netif_p); - -void lwip_port_link_detect(struct netif *netif) -{ - enum ethernet_link_status status; - struct LwipPort *xmac_netif_p = (struct LwipPort *)(netif->state); - FXmacOs *instance_p; - if(xmac_netif_p == NULL) - { - return; - } - instance_p = (FXmacOs *)xmac_netif_p->state; - if (instance_p->instance.is_ready != FT_COMPONENT_IS_READY) - { - return; - } - - status = FXmacPhyReconnect(xmac_netif_p); - - switch(status) - { - case ETH_LINK_UP: - if(netif_is_link_up(netif) == 0) - { - LWIP_PORT_INFO("link up"); - netif_set_link_up(netif) ; - } - break; - case ETH_LINK_DOWN: - default: - if(netif_is_link_up(netif) == 1) - { - LWIP_PORT_INFO("link down"); - netif_set_link_down(netif) ; - } - break; - } -} - - -#if !NO_SYS - -void link_detect_thread(void *p) -{ - struct netif *netif = (struct netif *) p; - - while (1) { - /* Call eth_link_detect() every second to detect Ethernet link - * change. - */ - lwip_port_link_detect(netif); - vTaskDelay(LINK_DETECT_THREAD_INTERVAL / portTICK_RATE_MS); - } -} - -#endif - - -void lwip_port_start(struct netif *netif) -{ - u32 link_speed, phy_link_status; - enum ethernet_link_status link_status; - - struct ethernetif *mac_netif = (struct ethernetif *)(netif->state); - -} - -void lwip_port_stop(struct netif *netif) -{ - u32 link_speed, phy_link_status; - enum ethernet_link_status link_status; - - struct ethernetif *mac_netif = (struct ethernetif *)(netif->state); -} - - -/* gCpuRuntime value from freertos_configs.c */ -extern volatile unsigned int gCpuRuntime; - -u32_t sys_now(void) -{ - return gCpuRuntime; -} diff --git a/third-party/lwip-2.1.2/ports/fxmac/lwip_port.h b/third-party/lwip-2.1.2/ports/fxmac/lwip_port.h deleted file mode 100644 index e1cd3792..00000000 --- a/third-party/lwip-2.1.2/ports/fxmac/lwip_port.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright : (C) 2022 Phytium Information Technology, Inc. - * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * - * FilePath: lwip_port.h - * Date: 2022-07-21 11:05:57 - * LastEditTime: 2022-07-21 11:05:57 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- - */ - - -#ifndef __LWIP_PORT_H_ -#define __LWIP_PORT_H_ - -#ifdef __cplusplus -extern "C" { -#endif -#include "ftypes.h" -#include "lwipopts.h" - -#include "lwip/netif.h" -#include "lwip/ip.h" - - -/* Mii interface */ -#define LWIP_PORT_INTERFACE_RGMII 0 -#define LWIP_PORT_INTERFACE_SGMII 1 - -/* Phy speed */ -#define LWIP_PORT_SPEED_10M 10 -#define LWIP_PORT_SPEED_100M 100 -#define LWIP_PORT_SPEED_1000M 1000 - -/* Duplex */ -#define LWIP_PORT_HALF_DUPLEX 0 -#define LWIP_PORT_FULL_DUPLEX 1 - -#define LWIP_PORT_CONFIG_MAGIC_CODE 0x616b6200 - -typedef struct -{ - u32 magic_code; /* LWIP_PORT_CONFIG_MAGIC_CODE */ - u32 mac_instance; - u32 mii_interface; /* LWIP_PORT_INTERFACE_XXX */ - u32 autonegotiation; /* 1 is autonegotiation ,0 is manually set */ - u32 phy_speed; /* LWIP_PORT_SPEED_XXX */ - u32 phy_duplex; /* LWIP_PORT_XXX_DUPLEX */ -} user_config; - -#define LWIP_PORT_CONFIG_DEFAULT_INIT(config) \ - do \ - { \ - config.magic_code = LWIP_PORT_CONFIG_MAGIC_CODE; \ - config.mac_instance = 3; \ - config.mii_interface = LWIP_PORT_INTERFACE_RGMII; \ - config.autonegotiation = 1; \ - config.phy_speed = LWIP_PORT_SPEED_1000M; \ - config.phy_duplex = LWIP_PORT_FULL_DUPLEX; \ -}while(0) - -struct LwipPort { - void *state; - -#if !NO_SYS - sys_sem_t sem_rx_data_available; -#endif -}; - -enum ethernet_link_status { - ETH_LINK_UNDEFINED = 0, - ETH_LINK_UP, - ETH_LINK_DOWN, - ETH_LINK_NEGOTIATING -}; - -void lwip_port_link_detect(struct netif *netif); -void lwip_port_input(struct netif *netif); -void lwip_port_input_thread(struct netif *netif); -struct netif *lwip_port_add(struct netif *netif, - ip_addr_t *ipaddr, ip_addr_t *netmask, ip_addr_t *gw, - unsigned char *mac_ethernet_address, - user_config *user_config); - -void lwip_port_start(struct netif *netif); -void lwip_port_stop(struct netif *netif); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/third-party/lwip-2.1.2/ports/lwipopts.h b/third-party/lwip-2.1.2/ports/lwipopts.h deleted file mode 100644 index b380e532..00000000 --- a/third-party/lwip-2.1.2/ports/lwipopts.h +++ /dev/null @@ -1,1236 +0,0 @@ -/* - * Copyright : (C) 2022 Phytium Information Technology, Inc. - * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * - * FilePath: lwipopts.h - * Date: 2022-09-16 13:54:28 - * LastEditTime: 2022-09-16 13:54:28 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- - */ - -#ifndef LWIP_HDR_LWIPOPTS_H -#define LWIP_HDR_LWIPOPTS_H - -#include "sdkconfig.h" -#ifndef SDK_CONFIG_H__ - #warning "Please include sdkconfig.h" -#endif - -#include "arch/sys_arch.h" - - -#ifdef __cplusplus -extern "C" { -#endif - - - -/* System */ -#define NO_SYS 0 -#define LWIP_COMPAT_MUTEX_ALLOWED 1 -#define LWIP_COMPAT_MUTEX 1 /* Define LWIP_COMPAT_MUTEX if the port has no mutexes and binary semaphore should be used instead */ -#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 1 -#define LWIP_PROVIDE_ERRNO 1 /* 使用errno */ - - -/* Memory config */ - -#define MEM_LIBC_MALLOC 0 - -/* mem heap */ - -#if defined(CONFIG_LWIP_USE_MEM_HEAP) - -#define MEMP_MEM_MALLOC 1 -/* MEM_SIZE: the size of the heap memory. If the application will send -a lot of data that needs to be copied, this should be set high. */ -#define MEM_SIZE (CONFIG_MEM_SIZE * 1024 * 1024) /* mem heap size */ - -#else - -#endif - -/** - * MEM_ALIGNMENT: should be set to the alignment of the CPU - * 4 byte alignment -> #define MEM_ALIGNMENT 4 - * 2 byte alignment -> #define MEM_ALIGNMENT 2 - */ -#define MEM_ALIGNMENT CONFIG_MEM_ALIGNMENT - - -/* Internal Memory Pool Sizes */ - -/* mem pool */ - -#ifdef CONFIG_LWIP_USE_MEM_POOL - -/** - * MEM_USE_POOLS==1: Use an alternative to malloc() by allocating from a set - * of memory pools of various sizes. When mem_malloc is called, an element of - * the smallest pool that can provide the length needed is returned. - * To use this, MEMP_USE_CUSTOM_POOLS also has to be enabled. - */ -#define MEM_USE_POOLS 1 - -#define MEMP_USE_CUSTOM_POOLS 1 - -/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application - sends a lot of data out of ROM (or other static memory), this - should be set high. */ -#define MEMP_NUM_PBUF CONFIG_MEMP_NUM_PBUF - -#else -#endif - - -/* ---------- Pbuf options ---------- */ -/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */ -#define PBUF_POOL_SIZE (CONFIG_PBUF_POOL_SIZE * 1024) /* pbuf tests need ~200KByte */ -/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */ -#define PBUF_POOL_BUFSIZE (CONFIG_PBUF_POOL_BUFSIZE * 1024) /* this parameter need over xmac rx_buf_size*/ - - -/** - * MEMP_NUM_NETCONN: the number of struct netconns. - * (only needed if you use the sequential API, like api_lib.c) - */ -#define MEMP_NUM_NETCONN CONFIG_LWIP_MAX_SOCKETS - -/** - * MEMP_NUM_RAW_PCB: Number of raw connection PCBs - * (requires the LWIP_RAW option) - */ -#define MEMP_NUM_RAW_PCB CONFIG_LWIP_MAX_RAW_PCBS - -/** - * MEMP_NUM_TCP_PCB: the number of simultaneously active TCP connections. - * (requires the LWIP_TCP option) - */ -#define MEMP_NUM_TCP_PCB CONFIG_LWIP_MAX_ACTIVE_TCP - -/** - * MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP connections. - * (requires the LWIP_TCP option) - */ -#define MEMP_NUM_TCP_PCB_LISTEN CONFIG_LWIP_MAX_LISTENING_TCP - -/** - * MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One - * per active UDP "connection". - * (requires the LWIP_UDP option) - */ -#define MEMP_NUM_UDP_PCB CONFIG_LWIP_MAX_UDP_PCBS - - -/* ARP options */ - -/** - * ARP_QUEUEING==1: Multiple outgoing packets are queued during hardware address - * resolution. By default, only the most recent packet is queued per IP address. - * This is sufficient for most protocols and mainly reduces TCP connection - * startup time. Set this to 1 if you know your application sends more than one - * packet in a row to an IP address that is not in the ARP cache. - */ -#define ARP_QUEUEING 1 - - -/* IP options */ -/** - * LWIP_IPV4==1: Enable IPv4 - */ -#define LWIP_IPV4 1 - -/** - * IP_REASSEMBLY==1: Reassemble incoming fragmented IP4 packets. Note that - * this option does not affect outgoing packet sizes, which can be controlled - * via IP_FRAG. - */ -#ifdef CONFIG_LWIP_IP4_REASSEMBLY -#define IP_REASSEMBLY 1 -#else -#define IP_REASSEMBLY 0 -#endif - -/** - * IP_FRAG==1: Fragment outgoing IP4 packets if their size exceeds MTU. Note - * that this option does not affect incoming packet sizes, which can be - * controlled via IP_REASSEMBLY. - */ -#ifdef CONFIG_LWIP_IP4_FRAG -#define IP_FRAG 1 -#else -#define IP_FRAG 0 -#endif - -/** - * IP_FORWARD==1: Enables the ability to forward IP packets across network - * interfaces. If you are going to run lwIP on a device with only one network - * interface, define this to 0. - */ -#ifdef CONFIG_LWIP_IP_FORWARD -#define IP_FORWARD 1 -#else -#define IP_FORWARD 0 -#endif - -/** - * IP_NAPT==1: Enables IPv4 Network Address and Port Translation. - * Note that both CONFIG_LWIP_IP_FORWARD and CONFIG_LWIP_L2_TO_L3_COPY options - * need to be enabled in system configuration - */ -#ifdef CONFIG_LWIP_IPV4_NAPT -#define IP_NAPT 1 -#else -#define IP_NAPT 0 -#endif - -/** - * IP_REASS_MAXAGE: Maximum time (in multiples of IP_TMR_INTERVAL - so seconds, normally) - * a fragmented IP packet waits for all fragments to arrive. If not all fragments arrived - * in this time, the whole packet is discarded. - */ -#define IP_REASS_MAXAGE 3 - -/** - * IP_REASS_MAX_PBUFS: Total maximum amount of pbufs waiting to be reassembled. - * Since the received pbufs are enqueued, be sure to configure - * PBUF_POOL_SIZE > IP_REASS_MAX_PBUFS so that the stack is still able to receive - * packets even if the maximum amount of fragments is enqueued for reassembly! - */ -#define IP_REASS_MAX_PBUFS CONFIG_IP_REASS_MAX_PBUFS - -/* ICMP options */ - -/** - * LWIP_ICMP==1: Enable ICMP module inside the IP stack. - * Be careful, disable that make your product non-compliant to RFC1122 - */ -#ifdef CONFIG_LWIP_ICMP -#define LWIP_ICMP 1 -#else -#define LWIP_ICMP 0 -#endif - -/** - * LWIP_BROADCAST_PING==1: respond to broadcast pings (default is unicast only) - */ -#ifdef CONFIG_LWIP_BROADCAST_PING -#define LWIP_BROADCAST_PING 1 -#else -#define LWIP_BROADCAST_PING 0 -#endif - -/** - * LWIP_MULTICAST_PING==1: respond to multicast pings (default is unicast only) - */ -#ifdef CONFIG_LWIP_MULTICAST_PING -#define LWIP_MULTICAST_PING 1 -#else -#define LWIP_MULTICAST_PING 0 -#endif - - -/* RAW options */ -/** - * LWIP_RAW==1: Enable application layer to hook into the IP layer itself. - */ -#define LWIP_RAW 1 - -/* DHCP options */ -/** - * LWIP_DHCP==1: Enable DHCP module. - */ -#if defined(CONFIG_LWIP_DHCP_ENABLE) -#define LWIP_DHCP 1 -#else -#define LWIP_DHCP 0 -#endif - -/** - * DHCP_DOES_ARP_CHECK==1: Do an ARP check on the offered address. - */ -#ifdef CONFIG_LWIP_DHCP_DOES_ARP_CHECK -#define DHCP_DOES_ARP_CHECK 1 -#else -#define DHCP_DOES_ARP_CHECK 0 -#endif - -/** - * LWIP_DHCP_GETS_NTP==1: Request NTP servers with discover/select. For each - * response packet, an callback is called, which has to be provided by the port: - * void dhcp_set_ntp_servers(u8_t num_ntp_servers, ip_addr_t* ntp_server_addrs); -*/ -#ifdef CONFIG_LWIP_DHCP_GET_NTP_SRV -#define LWIP_DHCP_GET_NTP_SRV 1 -#else -#define LWIP_DHCP_GET_NTP_SRV 0 -#endif - -/** - * LWIP_DHCP_DISABLE_CLIENT_ID==1: Do not add option 61 (client-id) to DHCP packets - * - */ -#ifdef CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID -#define ESP_DHCP_DISABLE_CLIENT_ID 1 -#else -#define ESP_DHCP_DISABLE_CLIENT_ID 0 -#endif - -/** - * CONFIG_LWIP_DHCP_RESTORE_LAST_IP==1: Last valid IP address obtained from DHCP server - * is restored after reset/power-up. - */ -#ifdef CONFIG_LWIP_DHCP_RESTORE_LAST_IP -/* - * Make the post-init hook check if we could restore the previously bound address - * - if yes reset the state to bound and mark result as ERR_OK (which skips discovery state) - * - if no, return false to continue normally to the discovery state - */ -#define LWIP_HOOK_DHCP_POST_INIT(netif, result) \ - (dhcp_ip_addr_restore(netif) ? ( dhcp_set_state(dhcp, DHCP_STATE_BOUND), \ - dhcp_network_changed(netif), \ - (result) = ERR_OK , \ - true ) : \ - false) -#else -#define LWIP_HOOK_DHCP_PRE_DISCOVERY(netif, result) (false) -#endif /* CONFIG_LWIP_DHCP_RESTORE_LAST_IP */ - -/** - * The maximum of NTP servers requested - */ -#define LWIP_DHCP_MAX_NTP_SERVERS CONFIG_LWIP_DHCP_MAX_NTP_SERVERS - -/** - * CONFIG_LWIP_DHCP_OPTIONS_LEN: The total length of outgoing DHCP option msg. If you have many options - * and options value is too long, you can configure the length according to your requirements - */ -#define DHCP_OPTIONS_LEN CONFIG_LWIP_DHCP_OPTIONS_LEN - -/** - * LWIP_DHCP_DISABLE_VENDOR_CLASS_ID==1: Do not add option 60 (Vendor Class Identifier) to DHCP packets - */ -#define ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID - - -/* Since for embedded devices it's not that hard to miss a discover packet, so lower - * the discover retry backoff time from (2,4,8,16,32,60,60)s to (500m,1,2,4,8,15,15)s. - */ -#define DHCP_REQUEST_TIMEOUT_SEQUENCE(tries) (( (tries) < 6 ? 1 << (tries) : 60) * 250) - -static inline uint32_t timeout_from_offered(uint32_t lease, uint32_t min) -{ - uint32_t timeout = lease; - if (timeout == 0) { - timeout = min; - } - return timeout; -} - -#define DHCP_CALC_TIMEOUT_FROM_OFFERED_T0_LEASE(dhcp) \ - timeout_from_offered((dhcp)->offered_t0_lease, 120) -#define DHCP_CALC_TIMEOUT_FROM_OFFERED_T1_RENEW(dhcp) \ - timeout_from_offered((dhcp)->offered_t1_renew, (dhcp)->t0_timeout>>1 /* 50% */ ) -#define DHCP_CALC_TIMEOUT_FROM_OFFERED_T2_REBIND(dhcp) \ - timeout_from_offered((dhcp)->offered_t2_rebind, ((dhcp)->t0_timeout/8)*7 /* 87.5% */ ) - -// #define LWIP_HOOK_DHCP_PARSE_OPTION(netif, dhcp, state, msg, msg_type, option, len, pbuf, offset) \ -// do { LWIP_UNUSED_ARG(msg); \ -// dhcp_parse_extra_opts(dhcp, state, option, len, pbuf, offset); \ -// } while(0) - -// #define LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, state, msg, msg_type, options_len_ptr) \ -// dhcp_append_extra_opts(netif, state, msg, options_len_ptr); - -/* AUTOIP options */ - -/** - * LWIP_AUTOIP==1: Enable AUTOIP module. - */ -#ifdef CONFIG_LWIP_AUTOIP -#define LWIP_AUTOIP 1 - -/** -* LWIP_DHCP_AUTOIP_COOP==1: Allow DHCP and AUTOIP to be both enabled on -* the same interface at the same time. -*/ -#define LWIP_DHCP_AUTOIP_COOP 1 - -/** -* LWIP_DHCP_AUTOIP_COOP_TRIES: Set to the number of DHCP DISCOVER probes -* that should be sent before falling back on AUTOIP. This can be set -* as low as 1 to get an AutoIP address very quickly, but you should -* be prepared to handle a changing IP address when DHCP overrides -* AutoIP. -*/ -#define LWIP_DHCP_AUTOIP_COOP_TRIES CONFIG_LWIP_AUTOIP_TRIES - -/** - * LWIP_AUTOIP_MAX_CONFLICTS: Defines max conflicts before rate limiting - */ -#define LWIP_AUTOIP_MAX_CONFLICTS CONFIG_LWIP_AUTOIP_MAX_CONFLICTS - -/** - * LWIP_AUTOIP_RATE_LIMIT_INTERVAL: Delay in seconds between successive attempts - */ -#define LWIP_AUTOIP_RATE_LIMIT_INTERVAL CONFIG_LWIP_AUTOIP_RATE_LIMIT_INTERVAL - -#endif /* CONFIG_LWIP_AUTOIP */ - -/* IGMP options */ -/** - * LWIP_IGMP==1: Turn on IGMP module. - */ -#define LWIP_IGMP 1 - -/* DNS options */ -/** - * LWIP_DNS==1: Turn on DNS module. UDP must be available for DNS - * transport. - */ -#define LWIP_DNS 1 - -/** The maximum of DNS servers - */ -#define DNS_MAX_SERVERS 3 - -/** - * - * The last server can be initialized automatically by defining - * FALLBACK_DNS_SERVER_ADDRESS(ipaddr), where 'ipaddr' is an 'ip_addr_t*' - */ -#define DNS_FALLBACK_SERVER_INDEX (DNS_MAX_SERVERS - 1) - -/** - * LWIP_DNS_SUPPORT_MDNS_QUERIES==1: Enable mDNS queries in hostname resolution. - * This option is set via menuconfig. - */ -#ifdef CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES -#define LWIP_DNS_SUPPORT_MDNS_QUERIES 1 -#else -#define LWIP_DNS_SUPPORT_MDNS_QUERIES 0 -#endif - -/* UDP options */ - -/** - * LWIP_UDP==1: Turn on UDP. - */ -#define LWIP_UDP 1 - -/** - * LWIP_NETBUF_RECVINFO==1: Enable IP_PKTINFO option. - * This option is set via menuconfig. - */ -#ifdef CONFIG_LWIP_NETBUF_RECVINFO -#define LWIP_NETBUF_RECVINFO 1 -#else -#define LWIP_NETBUF_RECVINFO 0 -#endif - - -/* TCP options */ - -/** - * LWIP_TCP==1: Turn on TCP. - */ -#define LWIP_TCP 1 - -/** - * TCP_WND: The size of a TCP window. This must be at least - * (2 * TCP_MSS) for things to work well. - * ATTENTION: when using TCP_RCV_SCALE, TCP_WND is the total size - * with scaling applied. Maximum window value in the TCP header - * will be TCP_WND >> TCP_RCV_SCALE - */ -#define TCP_WND CONFIG_LWIP_TCP_WND_DEFAULT - -/** - * TCP_MAXRTX: Maximum number of retransmissions of data segments. - */ -#define TCP_MAXRTX CONFIG_LWIP_TCP_MAXRTX - -/** - * TCP_SYNMAXRTX: Maximum number of retransmissions of SYN segments. - */ -#define TCP_SYNMAXRTX CONFIG_LWIP_TCP_SYNMAXRTX - -/** - * TCP_QUEUE_OOSEQ==1: TCP will queue segments that arrive out of order. - * Define to 0 if your device is low on memory. - */ -#ifdef CONFIG_LWIP_TCP_QUEUE_OOSEQ -#define TCP_QUEUE_OOSEQ 1 -#else -#define TCP_QUEUE_OOSEQ 0 -#endif - -/** - * LWIP_TCP_SACK_OUT==1: TCP will support sending selective acknowledgements (SACKs). - */ -#ifdef CONFIG_LWIP_TCP_SACK_OUT -#define LWIP_TCP_SACK_OUT 1 -#else -#define LWIP_TCP_SACK_OUT 0 -#endif - -/** - * TCP_MSS: TCP Maximum segment size. (default is 536, a conservative default, - * you might want to increase this.) - * For the receive side, this MSS is advertised to the remote side - * when opening a connection. For the transmit size, this MSS sets - * an upper limit on the MSS advertised by the remote host. - */ -#define TCP_MSS CONFIG_LWIP_TCP_MSS - -/** - * TCP_SND_BUF: TCP sender buffer space (bytes). - * To achieve good performance, this should be at least 2 * TCP_MSS. - */ -#define TCP_SND_BUF CONFIG_LWIP_TCP_SND_BUF_DEFAULT - - -/** - * TCP_LISTEN_BACKLOG: Enable the backlog option for tcp listen pcb. - */ -#define TCP_LISTEN_BACKLOG 1 - -/** - * TCP_OVERSIZE: The maximum number of bytes that tcp_write may - * allocate ahead of time - */ -#ifdef CONFIG_LWIP_TCP_OVERSIZE_MSS -#define TCP_OVERSIZE TCP_MSS -#endif -#ifdef CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS -#define TCP_OVERSIZE (TCP_MSS/4) -#endif -#ifdef CONFIG_LWIP_TCP_OVERSIZE_DISABLE -#define TCP_OVERSIZE 0 -#endif -#ifndef TCP_OVERSIZE -#error "One of CONFIG_TCP_OVERSIZE_xxx options should be set by sdkconfig" -#endif - -/** - * LWIP_EVENT_API and LWIP_CALLBACK_API: Only one of these should be set to 1. - * LWIP_EVENT_API==1: The user defines lwip_tcp_event() to receive all - * events (accept, sent, etc) that happen in the system. - * LWIP_CALLBACK_API==1: The PCB callback function is called directly - * for the event. This is the default. - */ -#define LWIP_EVENT_API 0 -#define LWIP_CALLBACK_API 1 - -/** - * TCP_TMR_INTERVAL: TCP timer interval - */ -#define TCP_TMR_INTERVAL CONFIG_LWIP_TCP_TMR_INTERVAL - -/** - * TCP_MSL: The maximum segment lifetime in milliseconds - */ -#define TCP_MSL CONFIG_LWIP_TCP_MSL - -/** - * LWIP_WND_SCALE and TCP_RCV_SCALE: - * Set LWIP_WND_SCALE to 1 to enable window scaling. - * Set TCP_RCV_SCALE to the desired scaling factor (shift count in the - * range of [0..14]). - * When LWIP_WND_SCALE is enabled but TCP_RCV_SCALE is 0, we can use a large - * send window while having a small receive window only. - */ -#ifdef CONFIG_LWIP_WND_SCALE -#define LWIP_WND_SCALE 1 -#define TCP_RCV_SCALE CONFIG_LWIP_TCP_RCV_SCALE -#else -#define LWIP_WND_SCALE 0 -#define TCP_RCV_SCALE 0 -#endif /* CONFIG_LWIP_WND_SCALE */ - -/** - * LWIP_TCP_RTO_TIME: TCP rto time. - * Default is 3 second. - */ -#define LWIP_TCP_RTO_TIME CONFIG_LWIP_TCP_RTO_TIME - - -/* Network Interfaces options */ - -/** - * LWIP_NETIF_HOSTNAME==1: use DHCP_OPTION_HOSTNAME with netif's hostname - * field. - */ -#define LWIP_NETIF_HOSTNAME 1 - -/** - * LWIP_NETIF_API==1: Support netif api (in netifapi.c) - */ -#ifdef CONFIG_LWIP_NETIF_API -#define LWIP_NETIF_API 1 -#else -#define LWIP_NETIF_API 0 -#endif - - -/** - * LWIP_NETIF_STATUS_CALLBACK==1: Support a callback function whenever an interface - * changes its up/down status (i.e., due to DHCP IP acquisition) - */ -#ifdef CONFIG_LWIP_NETIF_STATUS_CALLBACK -#define LWIP_NETIF_STATUS_CALLBACK 1 -#else -#define LWIP_NETIF_STATUS_CALLBACK 0 -#endif - - -/** - * LWIP_NETIF_EXT_STATUS_CALLBACK==1: Support an extended callback function - * for several netif related event that supports multiple subscribers. - * - */ -#define LWIP_NETIF_EXT_STATUS_CALLBACK 1 - -/** - * LWIP_NETIF_TX_SINGLE_PBUF: if this is set to 1, lwIP *tries* to put all data - * to be sent into one single pbuf. This is for compatibility with DMA-enabled - * MACs that do not support scatter-gather. - * Beware that this might involve CPU-memcpy before transmitting that would not - * be needed without this flag! Use this only if you need to! - * - * ATTENTION: a driver should *NOT* rely on getting single pbufs but check TX - * pbufs for being in one piece. If not, @ref pbuf_clone can be used to get - * a single pbuf: - * if (p->next != NULL) { - * struct pbuf *q = pbuf_clone(PBUF_RAW, PBUF_RAM, p); - * if (q == NULL) { - * return ERR_MEM; - * } - * p = q; ATTENTION: do NOT free the old 'p' as the ref belongs to the caller! - * } - */ -#define LWIP_NETIF_TX_SINGLE_PBUF 1 - -/* - ------------------------------------ - ---------- LOOPIF options ---------- - ------------------------------------ -*/ - -/* loopif options */ -/** - * LWIP_HAVE_LOOPIF==1: Support loop interface (127.0.0.1). - * This is only needed when no real netifs are available. If at least one other -*/ -#ifdef CONFIG_LWIP_NETIF_LOOPBACK -#define LWIP_HAVE_LOOPIF 1 - -/** - * LWIP_NETIF_LOOPBACK==1: Support sending packets with a destination IP - * address equal to the netif IP address, looping them back up the stack. - */ -#define LWIP_NETIF_LOOPBACK 1 - -/** - * LWIP_LOOPBACK_MAX_PBUFS: Maximum number of pbufs on queue for loopback - * sending for each netif (0 = disabled) - */ -#define LWIP_LOOPBACK_MAX_PBUFS CONFIG_LWIP_LOOPBACK_MAX_PBUFS -#else -#define LWIP_HAVE_LOOPIF 0 -#endif - -/* SLIPIF options */ - -#ifdef CONFIG_LWIP_SLIP_SUPPORT -/** - * Enable SLIP receive from ISR functions and disable Rx thread - * - * This is the only supported mode of lwIP SLIP interface, so that - * - incoming packets are queued into pbufs - * - no thread is created from lwIP - * meaning it is the application responsibility to read data - * from IO driver and feed them to the slip interface - */ -#define SLIP_RX_FROM_ISR 1 -#define SLIP_USE_RX_THREAD 0 - -/** - * SLIP_DEBUG: Enable debugging for SLIP. - */ -#ifdef CONFIG_LWIP_SLIP_DEBUG_ON -#define SLIP_DEBUG LWIP_DBG_ON -#else -#define SLIP_DEBUG LWIP_DBG_OFF -#endif -#endif /* CONFIG_LWIP_SLIP_SUPPORT */ - -/* Platform specific locking */ - -/** - * LWIP_TCPIP_CORE_LOCKING - * Creates a global mutex that is held during TCPIP thread operations. - * Can be locked by client code to perform lwIP operations without changing - * into TCPIP thread using callbacks. See LOCK_TCPIP_CORE() and - * UNLOCK_TCPIP_CORE(). - * Your system should provide mutexes supporting priority inversion to use this. - */ -#ifdef CONFIG_LWIP_TCPIP_CORE_LOCKING -#define LWIP_TCPIP_CORE_LOCKING 1 -#else -#define LWIP_TCPIP_CORE_LOCKING 0 -#endif - -/** - * SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain - * critical regions during buffer allocation, deallocation and memory - * allocation and deallocation. - */ -#define SYS_LIGHTWEIGHT_PROT 1 - -/** - * MEMCPY: override this if you have a faster implementation at hand than the - * one included in your C library - */ -#define MEMCPY(dst,src,len) memcpy(dst,src,len) - -/** - * SMEMCPY: override this with care! Some compilers (e.g. gcc) can inline a - * call to memcpy() if the length is known at compile time and is small. - */ -#define SMEMCPY(dst,src,len) memcpy(dst,src,len) - - -/* Sequential layer options */ - -/** - * LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c) - */ -#define LWIP_NETCONN 1 - -/** LWIP_NETCONN_SEM_PER_THREAD==1: Use one (thread-local) semaphore per - * thread calling socket/netconn functions instead of allocating one - * semaphore per netconn (and per select etc.) - * ATTENTION: a thread-local semaphore for API calls is needed: - * - LWIP_NETCONN_THREAD_SEM_GET() returning a sys_sem_t* - * - LWIP_NETCONN_THREAD_SEM_ALLOC() creating the semaphore - * - LWIP_NETCONN_THREAD_SEM_FREE() freeing the semaphore - * The latter 2 can be invoked up by calling netconn_thread_init()/netconn_thread_cleanup(). - * Ports may call these for threads created with sys_thread_new(). - */ -#if LWIP_TCPIP_CORE_LOCKING -#define LWIP_NETCONN_SEM_PER_THREAD 0 -#else -#define LWIP_NETCONN_SEM_PER_THREAD 1 -#endif - -/** LWIP_NETCONN_FULLDUPLEX==1: Enable code that allows reading from one thread, - * writing from a 2nd thread and closing from a 3rd thread at the same time. - * ATTENTION: This is currently really alpha! Some requirements: - * - LWIP_NETCONN_SEM_PER_THREAD==1 is required to use one socket/netconn from - * multiple threads at once - * - sys_mbox_free() has to unblock receive tasks waiting on recvmbox/acceptmbox - * and prevent a task pending on this during/after deletion - */ -#define LWIP_NETCONN_FULLDUPLEX 1 - - -/* Socket options */ - -/** - * LWIP_SOCKET==1: Enable Socket API (require to use sockets.c) - */ -#define LWIP_SOCKET 1 - -/** - * LWIP_COMPAT_SOCKETS==1: Enable BSD-style sockets functions names through defines. - * LWIP_COMPAT_SOCKETS==2: Same as ==1 but correctly named functions are created. - * While this helps code completion, it might conflict with existing libraries. - * (only used if you use sockets.c) - */ -#define LWIP_COMPAT_SOCKETS 1 - -/** - * LWIP_POSIX_SOCKETS_IO_NAMES==1: Enable POSIX-style sockets functions names. - * Disable this option if you use a POSIX operating system that uses the same - * names (read, write & close). (only used if you use sockets.c) - * - * POSIX I/O functions are mapped to LWIP via the VFS layer - * (see port/vfs_lwip.c) - */ -/** - */ -#define LWIP_POSIX_SOCKETS_IO_NAMES 1 - -/** - * LWIP_SOCKET_OFFSET==n: Increases the file descriptor number created by LwIP with n. - * - * FD_SETSIZE from sys/types.h is the maximum number of supported file - * descriptors and CONFIG_LWIP_MAX_SOCKETS defines the number of sockets; - * LWIP_SOCKET_OFFSET is configured to use the largest numbers of file - * descriptors for sockets. File descriptors from 0 to LWIP_SOCKET_OFFSET-1 - * are non-socket descriptors and from LWIP_SOCKET_OFFSET to FD_SETSIZE are - * socket descriptors. - */ -#define LWIP_SOCKET_OFFSET (FD_SETSIZE - CONFIG_LWIP_MAX_SOCKETS) - -/** - * LWIP_SO_SNDTIMEO==1: Enable send timeout for sockets/netconns and - * SO_SNDTIMEO processing. - */ -#define LWIP_SO_SNDTIMEO 1 - -/** - * LWIP_SO_RCVTIMEO==1: Enable receive timeout for sockets/netconns and - * SO_RCVTIMEO processing. - */ -#define LWIP_SO_RCVTIMEO 1 - -/** - * LWIP_TCP_KEEPALIVE==1: Enable TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT - * options processing. Note that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set - * in seconds. (does not require sockets.c, and will affect tcp.c) - */ -#define LWIP_TCP_KEEPALIVE 1 - -/** - * LWIP_SO_LINGER==1: Enable SO_LINGER processing. - * This option is set via menuconfig. - */ -#ifdef CONFIG_LWIP_SO_LINGER -#define LWIP_SO_LINGER 1 -#else -#define LWIP_SO_LINGER 0 -#endif - -/** - * LWIP_SO_RCVBUF==1: Enable SO_RCVBUF processing. - * This option is set via menuconfig. - */ -#ifdef CONFIG_LWIP_SO_RCVBUF -#define LWIP_SO_RCVBUF 1 -#else -#define LWIP_SO_RCVBUF 0 -#endif - -/** - * SO_REUSE==1: Enable SO_REUSEADDR option. - * This option is set via menuconfig. - */ -#ifdef CONFIG_LWIP_SO_REUSE -#define SO_REUSE 1 -#else -#define SO_REUSE 0 -#endif - -/** - * SO_REUSE_RXTOALL==1: Pass a copy of incoming broadcast/multicast packets - * to all local matches if SO_REUSEADDR is turned on. - * WARNING: Adds a memcpy for every packet if passing to more than one pcb! - */ -#ifdef CONFIG_LWIP_SO_REUSE_RXTOALL -#define SO_REUSE_RXTOALL 1 -#else -#define SO_REUSE_RXTOALL 0 -#endif - -/** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided - * by your system, set this to 0 and include in cc.h */ -#define LWIP_TIMEVAL_PRIVATE 0 - -/* Statistics options */ - -/** - * LWIP_STATS==1: Enable statistics collection in lwip_stats. - */ -#ifdef CONFIG_LWIP_STATS -#define LWIP_STATS 1 -#define ESP_STATS_MEM 1 - -/** - * LWIP_STATS_DISPLAY==1: Compile in the statistics output functions. - */ -#define LWIP_STATS_DISPLAY 1 -#else -#define LWIP_STATS 0 -#define ESP_STATS_MEM 0 -#endif /* CONFIG_LWIP_STATS */ - - -/* PPP options */ - -/** - * PPP_SUPPORT==1: Enable PPP. - */ -#ifdef CONFIG_LWIP_PPP_SUPPORT -#define PPP_SUPPORT 1 - -/** - * PPP_IPV6_SUPPORT == 1: Enable IPV6 support for local link - * between modem and lwIP stack. - * Some modems do not support IPV6 addressing in local link and - * the only option available is to disable IPV6 address negotiation. - */ -#define PPP_IPV6_SUPPORT CONFIG_LWIP_PPP_ENABLE_IPV6 - -/** - * PPP_NOTIFY_PHASE==1: Support PPP notify phase. - */ -#define PPP_NOTIFY_PHASE CONFIG_LWIP_PPP_NOTIFY_PHASE_SUPPORT - -/** - * PAP_SUPPORT==1: Support PAP. - */ -#define PAP_SUPPORT CONFIG_LWIP_PPP_PAP_SUPPORT - -/** - * CHAP_SUPPORT==1: Support CHAP. - */ -#define CHAP_SUPPORT CONFIG_LWIP_PPP_CHAP_SUPPORT - -/** - * MSCHAP_SUPPORT==1: Support MSCHAP. - */ -#define MSCHAP_SUPPORT CONFIG_LWIP_PPP_MSCHAP_SUPPORT - -/** - * CCP_SUPPORT==1: Support CCP. - */ -#define MPPE_SUPPORT CONFIG_LWIP_PPP_MPPE_SUPPORT - -/** - * PPP_MAXIDLEFLAG: Max Xmit idle time (in ms) before resend flag char. - * TODO: If PPP_MAXIDLEFLAG > 0 and next package is send during PPP_MAXIDLEFLAG time, - * then 0x7E is not added at the begining of PPP package but 0x7E termination - * is always at the end. This behaviour brokes PPP dial with GSM (PPPoS). - * The PPP package should always start and end with 0x7E. - */ - -#define PPP_MAXIDLEFLAG 0 - -#ifdef CONFIG_LWIP_ENABLE_LCP_ECHO -/** - * LCP_ECHOINTERVAL: Interval in seconds between keepalive LCP echo requests, 0 to disable. - */ -#define LCP_ECHOINTERVAL CONFIG_LWIP_LCP_ECHOINTERVAL - -/** - * LCP_MAXECHOFAILS: Number of consecutive unanswered echo requests before failure is indicated. - */ -#define LCP_MAXECHOFAILS CONFIG_LWIP_LCP_MAXECHOFAILS -#endif /* CONFIG_LWIP_ENABLE_LCP_ECHO */ - -/** - * PPP_DEBUG: Enable debugging for PPP. - */ -#ifdef CONFIG_LWIP_PPP_DEBUG_ON -#define PPP_DEBUG LWIP_DBG_ON -#define PRINTPKT_SUPPORT 1 -#define PPP_PROTOCOLNAME 1 -#else -#define PPP_DEBUG LWIP_DBG_OFF -#endif /* CONFIG_LWIP_PPP_DEBUG_ON */ -#else -#define PPP_SUPPORT 0 -#endif /* CONFIG_LWIP_PPP_SUPPORT */ - - -/* checksum options */ - -/** - * CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets. - */ -#ifdef CONFIG_LWIP_CHECKSUM_CHECK_IP -#define CHECKSUM_CHECK_IP 1 -#else -#define CHECKSUM_CHECK_IP 0 -#endif - -/** - * CHECKSUM_CHECK_UDP==1: Check checksums in software for incoming UDP packets. - */ -#ifdef CONFIG_LWIP_CHECKSUM_CHECK_UDP -#define CHECKSUM_CHECK_UDP 1 -#else -#define CHECKSUM_CHECK_UDP 0 -#endif - -/** - * CHECKSUM_CHECK_ICMP==1: Check checksums in software for incoming ICMP packets. - */ -#ifdef CONFIG_LWIP_CHECKSUM_CHECK_ICMP -#define CHECKSUM_CHECK_ICMP 1 -#else -#define CHECKSUM_CHECK_ICMP 0 -#endif - -/* IPv6 options */ - -/** - * LWIP_IPV6==1: Enable IPv6 - */ -#if defined(CONFIG_LWIP_IPV6) && !defined(CONFIG_USE_IPV4_ONLY) -#define LWIP_IPV6 1 -#else -#define LWIP_IPV6 0 -#endif - -/** - * LWIP_IPV6_NUM_ADDRESSES: Number of IPv6 addresses per netif. - */ -#define LWIP_IPV6_NUM_ADDRESSES CONFIG_LWIP_IPV6_NUM_ADDRESSES - -/** - * LWIP_IPV6_FORWARD==1: Forward IPv6 packets across netifs - */ -#ifdef CONFIG_LWIP_IPV6_FORWARD -#define LWIP_IPV6_FORWARD 1 -#else -#define LWIP_IPV6_FORWARD 0 -#endif - -/** - * LWIP_IPV6_FRAG==1: Fragment outgoing IP6 packets if their size exceeds MTU. Note - * that this option does not affect incoming packet sizes, which can be - * controlled via IP6_REASSEMBLY. - */ -#ifdef CONFIG_LWIP_IP6_FRAG -#define LWIP_IPV6_FRAG 1 -#else -#define LWIP_IPV6_FRAG 0 -#endif - -/** - * LWIP_IPV6_REASS==1: reassemble incoming IP6 packets that fragmented. Note that - * this option does not affect outgoing packet sizes, which can be controlled - * via LWIP_IP6_FRAG. - */ -#ifdef CONFIG_LWIP_IP6_REASSEMBLY -#define LWIP_IPV6_REASS 1 -#define IPV6_FRAG_COPYHEADER 1 -#else -#define LWIP_IPV6_REASS 0 -#endif - - -/** - * LWIP_IPV6_AUTOCONFIG==1: Enable stateless address autoconfiguration as per RFC 4862. - */ -#ifdef CONFIG_LWIP_IPV6_AUTOCONFIG -#define ESP_IPV6_AUTOCONFIG 1 -#else -#define ESP_IPV6_AUTOCONFIG 0 -#endif - -/** - * LWIP_ND6_RDNSS_MAX_DNS_SERVERS > 0: Use IPv6 Router Advertisement Recursive - * DNS Server Option (as per RFC 6106) to copy a defined maximum number of DNS - * servers to the DNS module. - */ -#define LWIP_ND6_RDNSS_MAX_DNS_SERVERS CONFIG_LWIP_IPV6_RDNSS_MAX_DNS_SERVERS - -/** - * LWIP_IPV6_DHCP6==1: enable DHCPv6 stateful/stateless address autoconfiguration. - */ -#ifdef CONFIG_LWIP_IPV6_DHCP6 -#define LWIP_IPV6_DHCP6 1 -#else -#define LWIP_IPV6_DHCP6 0 -#endif - -/** - * MEMP_NUM_ND6_QUEUE: Max number of IPv6 packets to queue during MAC resolution. - */ -#define MEMP_NUM_ND6_QUEUE CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE - -/** - * LWIP_ND6_NUM_NEIGHBORS: Number of entries in IPv6 neighbor cache - */ -#define LWIP_ND6_NUM_NEIGHBORS CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS - -/* Hook options */ - - -// #define LWIP_HOOK_FILENAME "lwip_default_hooks.h" -// #define LWIP_HOOK_IP4_ROUTE_SRC ip4_route_src_hook -#include "sockets_ext.h" -#define LWIP_HOOK_SOCKETS_GETSOCKOPT(s, sock, level, optname, optval, optlen, err) \ - lwip_getsockopt_impl_ext(sock, level, optname, optval, optlen, err)?(done_socket(sock), 1): 0 - -#define LWIP_HOOK_SOCKETS_SETSOCKOPT(s, sock, level, optname, optval, optlen, err) \ - lwip_setsockopt_impl_ext(sock, level, optname, optval, optlen, err)?(done_socket(sock), 1): 0 - - - -/* debug option */ -/** - * LWIP_DEBUG: Enable lwip debugging in other modules. - */ -#ifdef CONFIG_LWIP_DEBUG -#define LWIP_DEBUG LWIP_DBG_ON -#else -#undef LWIP_DEBUG -#endif - -/** - * ETHARP_DEBUG: Enable debugging in etharp.c. - */ -#ifdef CONFIG_LWIP_ETHARP_DEBUG -#define ETHARP_DEBUG LWIP_DBG_ON -#else -#define ETHARP_DEBUG LWIP_DBG_OFF -#endif - -/** - * NETIF_DEBUG: Enable debugging in netif.c. - */ -#ifdef CONFIG_LWIP_NETIF_DEBUG -#define NETIF_DEBUG LWIP_DBG_ON -#else -#define NETIF_DEBUG LWIP_DBG_OFF -#endif - -/** - * PBUF_DEBUG: Enable debugging in pbuf.c. - */ -#ifdef CONFIG_LWIP_PBUF_DEBUG -#define PBUF_DEBUG LWIP_DBG_ON -#else -#define PBUF_DEBUG LWIP_DBG_OFF -#endif - -/** - * API_LIB_DEBUG: Enable debugging in api_lib.c. - */ -#ifdef CONFIG_LWIP_API_LIB_DEBUG -#define API_LIB_DEBUG LWIP_DBG_ON -#else -#define API_LIB_DEBUG LWIP_DBG_OFF -#endif - -/** - * SOCKETS_DEBUG: Enable debugging in sockets.c. - */ -#ifdef CONFIG_LWIP_SOCKETS_DEBUG -#define SOCKETS_DEBUG LWIP_DBG_ON -#else -#define SOCKETS_DEBUG LWIP_DBG_OFF -#endif - -/** - * ICMP_DEBUG: Enable debugging in icmp.c. - */ -#ifdef CONFIG_LWIP_ICMP_DEBUG -#define ICMP_DEBUG LWIP_DBG_ON -#else -#define ICMP_DEBUG LWIP_DBG_OFF -#endif - -#ifdef CONFIG_LWIP_ICMP6_DEBUG -#define ICMP6_DEBUG LWIP_DBG_ON -#else -#define ICMP6_DEBUG LWIP_DBG_OFF -#endif - -/** - * DHCP_DEBUG: Enable debugging in dhcp.c. - */ -#ifdef CONFIG_LWIP_DHCP_DEBUG -#define DHCP_DEBUG LWIP_DBG_ON -#else -#define DHCP_DEBUG LWIP_DBG_OFF -#endif - - -/** - * IP_DEBUG: Enable debugging for IP. - */ -#ifdef CONFIG_LWIP_IP_DEBUG -#define IP_DEBUG LWIP_DBG_ON -#define IP_REASS_DEBUG LWIP_DBG_ON -#else -#define IP_DEBUG LWIP_DBG_OFF - -#endif - -/** - * IP6_DEBUG: Enable debugging for IP6. - */ -#ifdef CONFIG_LWIP_IP6_DEBUG -#define IP6_DEBUG LWIP_DBG_ON -#else -#define IP6_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_DEBUG: Enable debugging for TCP. - */ -#ifdef CONFIG_LWIP_TCP_DEBUG -#define TCP_DEBUG LWIP_DBG_ON -#else -#define TCP_DEBUG LWIP_DBG_OFF -#endif - -/** - * SNTP_DEBUG: Enable debugging for SNTP. - */ -#ifdef CONFIG_LWIP_SNTP_DEBUG -#define SNTP_DEBUG LWIP_DBG_ON -#else -#define SNTP_DEBUG LWIP_DBG_OFF -#endif - -/** - * DNS_DEBUG: Enable debugging for DNS. - */ -#ifdef CONFIG_LWIP_DNS_DEBUG -#define DNS_DEBUG LWIP_DBG_ON -#else -#define DNS_DEBUG LWIP_DBG_OFF -#endif - -/** - * MEMP_DEBUG: Enable debugging in memp.c. - */ -#define MEMP_DEBUG LWIP_DBG_OFF - -/** - * TCP_INPUT_DEBUG: Enable debugging in tcp_in.c for incoming debug. - */ -#define TCP_INPUT_DEBUG LWIP_DBG_OFF - -/** - * TCP_OUTPUT_DEBUG: Enable debugging in tcp_out.c output functions. - */ -#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF - -/** - * TCPIP_DEBUG: Enable debugging in tcpip.c. - */ -#define TCPIP_DEBUG LWIP_DBG_OFF - -/** - * TCP_OOSEQ_DEBUG: Enable debugging in tcpin.c for OOSEQ. - */ -#define TCP_OOSEQ_DEBUG LWIP_DBG_OFF - - - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_LWIPOPTS_H */ diff --git a/third-party/lwip-2.1.2/ports/lwippools.h b/third-party/lwip-2.1.2/ports/lwippools.h deleted file mode 100644 index 80d293e2..00000000 --- a/third-party/lwip-2.1.2/ports/lwippools.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright : (C) 2022 Phytium Information Technology, Inc. - * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * - * FilePath: lwippools.h - * Date: 2022-09-22 16:39:55 - * LastEditTime: 2022-09-22 16:39:56 - * Description: This file is for - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- - */ - - -#ifndef LWIP_POOLS_H -#define LWIP_POOLS_H - -#endif // ! - diff --git a/third-party/lwip-2.1.2/ports/sockets_ext.c b/third-party/lwip-2.1.2/ports/sockets_ext.c deleted file mode 100644 index 2a940c09..00000000 --- a/third-party/lwip-2.1.2/ports/sockets_ext.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "lwip/sockets.h" -#include "lwip/priv/sockets_priv.h" -#include "lwip/api.h" -#include "lwip/sys.h" -#include "lwip/tcp.h" -#include "lwip/raw.h" -#include "lwip/udp.h" -#include "sockets_ext.h" - -#define LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, opttype) do { \ - if (((optlen) < sizeof(opttype)) || ((sock)->conn == NULL) || ((sock)->conn->pcb.tcp == NULL)) { *err=EINVAL; goto exit; } }while(0) - -#define LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, opttype, netconntype) do { \ - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, opttype); \ - if (NETCONNTYPE_GROUP(netconn_type((sock)->conn)) != netconntype) { *err=ENOPROTOOPT; goto exit; } } while(0) - - -bool lwip_setsockopt_impl_ext(struct lwip_sock* sock, int level, int optname, const void *optval, socklen_t optlen, int *err) -{ -#if LWIP_IPV6 - if (level != IPPROTO_IPV6) -#endif /* LWIP_IPV6 */ - { - return false; - } - -#if LWIP_IPV6 - switch (optname) { - default: - return false; - case IPV6_MULTICAST_IF: /* NB: like IP_MULTICAST_IF, this takes an IP not an index */ - { - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, u8_t, NETCONN_UDP); - udp_set_multicast_netif_index(sock->conn->pcb.udp, (u8_t)(*(const u8_t*)optval)); - } - break; - case IPV6_MULTICAST_HOPS: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, u8_t, NETCONN_UDP); - udp_set_multicast_ttl(sock->conn->pcb.udp, (u8_t)(*(const u8_t*)optval)); - break; - case IPV6_MULTICAST_LOOP: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, u8_t, NETCONN_UDP); - if (*(const u8_t*)optval) { - udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) | UDP_FLAGS_MULTICAST_LOOP); - } else { - udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) & ~UDP_FLAGS_MULTICAST_LOOP); - } - break; - } -exit: - return true; -#endif /* LWIP_IPV6 */ -} - -bool lwip_getsockopt_impl_ext(struct lwip_sock* sock, int level, int optname, void *optval, uint32_t *optlen, int *err) -{ -#if LWIP_IPV6 - if (level != IPPROTO_IPV6) -#endif /* LWIP_IPV6 */ - { - return false; - } - -#if LWIP_IPV6 - switch (optname) { - default: - return false; - case IPV6_MULTICAST_IF: /* NB: like IP_MULTICAST_IF, this returns an IP not an index */ - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, u8_t); - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) { - *err = ENOPROTOOPT; - goto exit; - } - *(u8_t*)optval = udp_get_multicast_netif_index(sock->conn->pcb.udp); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt_ext(IPPROTO_IPV6, IPV6_MULTICAST_IF) = 0x%"X32_F"\n", - *(u32_t *)optval)); - break; - case IPV6_MULTICAST_HOPS: - printf("IPV6_MULTICAST_HOPS\n"); - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, u8_t); - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) { - *err = ENOPROTOOPT; - goto exit; - } - *(u8_t*)optval = udp_get_multicast_ttl(sock->conn->pcb.udp); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt_ext(IPPROTO_IPV6, IP_MULTICAST_LOOP) = %d\n", - *(int *)optval)); - break; - case IPV6_MULTICAST_LOOP: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, u8_t); - if ((udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_MULTICAST_LOOP) != 0) { - *(u8_t*)optval = 1; - } else { - *(u8_t*)optval = 0; - } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt_ext(IPPROTO_IPV6, IP_MULTICAST_LOOP) = %d\n", - *(int *)optval)); - break; - } -exit: - return true; -#endif /* LWIP_IPV6 */ -} diff --git a/third-party/lwip-2.1.2/ports/sockets_ext.h b/third-party/lwip-2.1.2/ports/sockets_ext.h deleted file mode 100644 index 48ffcf61..00000000 --- a/third-party/lwip-2.1.2/ports/sockets_ext.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ -#pragma once -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define IPV6_MULTICAST_IF 0x300 -#define IPV6_MULTICAST_HOPS 0x301 -#define IPV6_MULTICAST_LOOP 0x302 - -struct lwip_sock; - -bool lwip_setsockopt_impl_ext(struct lwip_sock* sock, int level, int optname, const void *optval, uint32_t optlen, int *err); -bool lwip_getsockopt_impl_ext(struct lwip_sock* sock, int level, int optname, void *optval, uint32_t *optlen, int *err); -#ifdef __cplusplus -} -#endif diff --git a/third-party/openamp/ports/helper.c b/third-party/openamp/ports/helper.c index ff813c17..458dd48a 100644 --- a/third-party/openamp/ports/helper.c +++ b/third-party/openamp/ports/helper.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: helper.c * Date: 2022-02-24 13:56:43 * LastEditTime: 2022-03-21 17:04:43 - * Description:  This file is for - * - * Modify History: + * Description:  This file is for helper + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/04/21 first release */ @@ -26,52 +27,56 @@ #include "platform_info.h" #include #include "fcache.h" -#include +#include static void system_metal_logger(enum metal_log_level level, - const char *format, ...) + const char *format, ...) { - char msg[1024]; - va_list args; - static const char * const level_strs[] = { - "metal: emergency: ", - "metal: alert: ", - "metal: critical: ", - "metal: error: ", - "metal: warning: ", - "metal: notice: ", - "metal: info: ", - "metal: debug: ", - }; + char msg[1024]; + va_list args; + static const char *const level_strs[] = + { + "metal: emergency: ", + "metal: alert: ", + "metal: critical: ", + "metal: error: ", + "metal: warning: ", + "metal: notice: ", + "metal: info: ", + "metal: debug: ", + }; - va_start(args, format); - vsnprintf(msg, sizeof(msg), format, args); - va_end(args); + va_start(args, format); + vsnprintf(msg, sizeof(msg), format, args); + va_end(args); - if (level <= METAL_LOG_EMERGENCY || level > METAL_LOG_DEBUG) - level = METAL_LOG_EMERGENCY; + if (level <= METAL_LOG_EMERGENCY || level > METAL_LOG_DEBUG) + { + level = METAL_LOG_EMERGENCY; + } - printf("%s%s", level_strs[level], msg); + printf("%s%s", level_strs[level], msg); } /* Main hw machinery initialization entry point, called from main()*/ /* return 0 on success */ int init_system(void) { - int ret; - struct metal_init_params metal_param = { - .log_handler = system_metal_logger, - .log_level = METAL_LOG_INFO, - }; + int ret; + struct metal_init_params metal_param = + { + .log_handler = system_metal_logger, + .log_level = METAL_LOG_INFO, + }; - /* Low level abstraction layer for openamp initialization */ - ret = metal_init(&metal_param); - return ret; + /* Low level abstraction layer for openamp initialization */ + ret = metal_init(&metal_param); + return ret; } void cleanup_system(void) { - metal_finish(); - FCacheDCacheInvalidate() ; - FCacheICacheInvalidate() ; + metal_finish(); + FCacheDCacheInvalidate() ; + FCacheICacheInvalidate() ; } diff --git a/third-party/openamp/ports/phytium_os_rproc.c b/third-party/openamp/ports/phytium_os_rproc.c index de2f0136..3b7e57f1 100644 --- a/third-party/openamp/ports/phytium_os_rproc.c +++ b/third-party/openamp/ports/phytium_os_rproc.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: phytium_os_rproc.c * Date: 2022-02-25 09:59:08 * LastEditTime: 2022-02-25 09:59:08 - * Description:  This file is for - * - * Modify History: + * Description:  This file is for defining phytium platform specific remoteproc implementation. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/04/21 first release */ /***************************** Include Files *********************************/ @@ -57,15 +58,15 @@ #ifdef CONFIG_MEM_NORMAL -#define DEFAULT_MEM_ATTRIBUTE (MT_NORMAL|MT_P_RW_U_RW) + #define DEFAULT_MEM_ATTRIBUTE (MT_NORMAL|MT_P_RW_U_RW) #endif #ifdef CONFIG_MEM_WRITE_THROUGH -#define DEFAULT_MEM_ATTRIBUTE (MT_NORMAL_WT|MT_P_RW_U_RW) + #define DEFAULT_MEM_ATTRIBUTE (MT_NORMAL_WT|MT_P_RW_U_RW) #endif #ifdef CONFIG_MEM_NO_CACHE -#define DEFAULT_MEM_ATTRIBUTE (MT_NORMAL_NC|MT_P_RW_U_RW) + #define DEFAULT_MEM_ATTRIBUTE (MT_NORMAL_NC|MT_P_RW_U_RW) #endif #ifdef CONFIG_USE_OPENAMP_IPI @@ -73,16 +74,17 @@ static void PhytiumIrqhandler(s32 vector, void *param) { struct remoteproc *rproc = param; - struct remoteproc_priv *prproc; - u32 cpu_id; + struct remoteproc_priv *prproc; + u32 cpu_id; (void)vector; - if(!rproc) { - PHYTIUM_RPROC_MAIN_DEBUG_E("rproc is empty \r\n") ; + if (!rproc) + { + PHYTIUM_RPROC_MAIN_DEBUG_E("rproc is empty \r\n") ; return ; } - - prproc = rproc->priv; + + prproc = rproc->priv; atomic_flag_clear(&prproc->ipi_nokick); } @@ -90,150 +92,172 @@ static void PhytiumIrqhandler(s32 vector, void *param) static struct remoteproc * PhytiumProcInit(struct remoteproc *rproc, struct remoteproc_ops *ops, - void *arg) + void *arg) { struct remoteproc_priv *prproc = arg; - struct metal_device *kick_dev; - unsigned int irq_vect; - int ret; + struct metal_device *kick_dev; + unsigned int irq_vect; + int ret; if (!rproc || !prproc || !ops) - return NULL; - ret = metal_device_open(prproc->kick_dev_bus_name, - prproc->kick_dev_name, - &kick_dev); - if (ret) { - PHYTIUM_RPROC_MAIN_DEBUG_E("failed to open polling device: %d.\r\n", ret); - return NULL; - } + { + return NULL; + } + ret = metal_device_open(prproc->kick_dev_bus_name, + prproc->kick_dev_name, + &kick_dev); + if (ret) + { + PHYTIUM_RPROC_MAIN_DEBUG_E("Failed to open polling device: %d.\r\n", ret); + return NULL; + } rproc->priv = prproc; - prproc->kick_dev = kick_dev; - prproc->kick_io = metal_device_io_region(kick_dev, 0); + prproc->kick_dev = kick_dev; + prproc->kick_io = metal_device_io_region(kick_dev, 0); if (!prproc->kick_io) + { goto err1; + } #ifdef CONFIG_USE_OPENAMP_IPI - u32 cpu_id; - atomic_store(&prproc->ipi_nokick, 1); - GetCpuId(&cpu_id); - /* Register interrupt handler and enable interrupt */ - irq_vect = (uintptr_t)kick_dev->irq_info; - PHYTIUM_RPROC_MAIN_DEBUG_I("irq_vect is %d \r\n",irq_vect) ; - PHYTIUM_RPROC_MAIN_DEBUG_I("current %d \r\n",cpu_id) ; - - InterruptSetPriority(irq_vect,16) ; - InterruptInstall(irq_vect,PhytiumIrqhandler,rproc,"phytium_rproc") ; - + u32 cpu_id; + atomic_store(&prproc->ipi_nokick, 1); + GetCpuId(&cpu_id); + /* Register interrupt handler and enable interrupt */ + irq_vect = (uintptr_t)kick_dev->irq_info; + PHYTIUM_RPROC_MAIN_DEBUG_I("irq_vect is %d \r\n", irq_vect) ; + PHYTIUM_RPROC_MAIN_DEBUG_I("current %d \r\n", cpu_id) ; + + InterruptSetPriority(irq_vect, 16) ; + InterruptInstall(irq_vect, PhytiumIrqhandler, rproc, "phytium_rproc") ; + InterruptUmask(irq_vect) ; #else - (void)irq_vect; - metal_io_write32(prproc->kick_io, 0, !POLL_STOP); + (void)irq_vect; + metal_io_write32(prproc->kick_io, 0, !POLL_STOP); #endif /* !CONFIG_USE_OPENAMP_IPI */ - rproc->ops = ops; + rproc->ops = ops; - return rproc; + return rproc; err1: - metal_device_close(kick_dev); - return NULL; + metal_device_close(kick_dev); + return NULL; } static void PhytiumProcRemove(struct remoteproc *rproc) { struct remoteproc_priv *prproc; - struct metal_device *dev; + struct metal_device *dev; if (!rproc) - { - return; - } - - prproc = rproc->priv; + { + return; + } + + prproc = rproc->priv; #ifdef CONFIG_USE_OPENAMP_IPI - dev = prproc->kick_dev; - if (dev) { - PHYTIUM_RPROC_MAIN_DEBUG_E("Start to remove \r\n") ; - InterruptMask((uintptr_t)dev->irq_info); - } + dev = prproc->kick_dev; + if (dev) + { + PHYTIUM_RPROC_MAIN_DEBUG_E("Start to remove \r\n") ; + InterruptMask((uintptr_t)dev->irq_info); + } #else /* RPMSG_NO_IPI */ - (void)dev; + (void)dev; #endif /* !RPMSG_NO_IPI */ - metal_device_close(prproc->kick_dev); + metal_device_close(prproc->kick_dev); } static void * PhytiumProcMmap(struct remoteproc *rproc, metal_phys_addr_t *pa, - metal_phys_addr_t *da, size_t size, - unsigned int attribute, struct metal_io_region **io) + metal_phys_addr_t *da, size_t size, + unsigned int attribute, struct metal_io_region **io) { struct remoteproc_mem *mem; - metal_phys_addr_t lpa, lda; - struct metal_io_region *tmpio; + metal_phys_addr_t lpa, lda; + struct metal_io_region *tmpio; lpa = *pa; - lda = *da; - - if (lpa == METAL_BAD_PHYS && lda == METAL_BAD_PHYS) - return NULL; - if (lpa == METAL_BAD_PHYS) - lpa = lda; - if (lda == METAL_BAD_PHYS) - lda = lpa; - - if (!attribute) - attribute = DEFAULT_MEM_ATTRIBUTE; - - mem = metal_allocate_memory(sizeof(*mem)); - if (!mem) - return NULL; - tmpio = metal_allocate_memory(sizeof(*tmpio)); - if (!tmpio) { - metal_free_memory(mem); - return NULL; - } - remoteproc_init_mem(mem, NULL, lpa, lda, size, tmpio); - /* va is the same as pa in this platform */ - metal_io_init(tmpio, (void *)lpa, &mem->pa, size, - -1, attribute, NULL); - remoteproc_add_mem(rproc, mem); - *pa = lpa; - *da = lda; - if (io) - *io = tmpio; - return metal_io_phys_to_virt(tmpio, mem->pa); + lda = *da; + + if (lpa == METAL_BAD_PHYS && lda == METAL_BAD_PHYS) + { + return NULL; + } + if (lpa == METAL_BAD_PHYS) + { + lpa = lda; + } + if (lda == METAL_BAD_PHYS) + { + lda = lpa; + } + + if (!attribute) + { + attribute = DEFAULT_MEM_ATTRIBUTE; + } + + mem = metal_allocate_memory(sizeof(*mem)); + if (!mem) + { + return NULL; + } + tmpio = metal_allocate_memory(sizeof(*tmpio)); + if (!tmpio) + { + metal_free_memory(mem); + return NULL; + } + remoteproc_init_mem(mem, NULL, lpa, lda, size, tmpio); + /* va is the same as pa in this platform */ + metal_io_init(tmpio, (void *)lpa, &mem->pa, size, + -1, attribute, NULL); + remoteproc_add_mem(rproc, mem); + *pa = lpa; + *da = lda; + if (io) + { + *io = tmpio; + } + return metal_io_phys_to_virt(tmpio, mem->pa); } static int PhytiumProcNotify(struct remoteproc *rproc, uint32_t id) { - struct remoteproc_priv *prproc; + struct remoteproc_priv *prproc; - (void)id; - if (!rproc) - return -1; + (void)id; + if (!rproc) + { + return -1; + } - prproc = rproc->priv; + prproc = rproc->priv; #ifndef CONFIG_USE_OPENAMP_IPI - metal_io_write32(prproc->kick_io, 0, POLL_STOP); + metal_io_write32(prproc->kick_io, 0, POLL_STOP); #else - u32 cpu_id; - GetCpuId(&cpu_id); - InterruptCoreInterSend((uintptr)(prproc->kick_dev->irq_info), prproc->ipi_chn_mask); + u32 cpu_id; + GetCpuId(&cpu_id); + InterruptCoreInterSend((uintptr)(prproc->kick_dev->irq_info), prproc->ipi_chn_mask); #endif /* RPMSG_NO_IPI */ - return 0; + return 0; } -struct remoteproc_ops phytium_proc_ops = { - .init = PhytiumProcInit, - .remove = PhytiumProcRemove, - .mmap = PhytiumProcMmap, - .notify = PhytiumProcNotify, - .start = NULL, - .stop = NULL, - .shutdown = NULL, +struct remoteproc_ops phytium_proc_ops = +{ + .init = PhytiumProcInit, + .remove = PhytiumProcRemove, + .mmap = PhytiumProcMmap, + .notify = PhytiumProcNotify, + .start = NULL, + .stop = NULL, + .shutdown = NULL, }; diff --git a/third-party/openamp/ports/platform_info.c b/third-party/openamp/ports/platform_info.c index 0ef7fb79..c81051ee 100644 --- a/third-party/openamp/ports/platform_info.c +++ b/third-party/openamp/ports/platform_info.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: platform_info.c * Date: 2022-02-23 11:24:12 * LastEditTime: 2022-02-23 11:43:44 - * Description:  This file is for - * - * Modify History: + * Description:  This file is for defining platform specific data and implements APIs to set platform specific information for OpenAMP. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/04/21 first release */ /***************************** Include Files *********************************/ @@ -54,19 +55,19 @@ #ifdef CONFIG_USE_OPENAMP_IPI -#define _rproc_wait() asm volatile("wfi") + #define _rproc_wait() asm volatile("wfi") #endif /* !RPMSG_NO_IPI */ #ifdef CONFIG_MEM_NORMAL -#define MEM_ATTR_ACESS (MT_NORMAL|MT_P_RW_U_RW) + #define MEM_ATTR_ACESS (MT_NORMAL|MT_P_RW_U_RW) #endif #ifdef CONFIG_MEM_WRITE_THROUGH -#define MEM_ATTR_ACESS (MT_NORMAL_WT|MT_P_RW_U_RW) + #define MEM_ATTR_ACESS (MT_NORMAL_WT|MT_P_RW_U_RW) #endif #ifdef CONFIG_MEM_NO_CACHE -#define MEM_ATTR_ACESS (MT_NORMAL_NC|MT_P_RW_U_RW) + #define MEM_ATTR_ACESS (MT_NORMAL_NC|MT_P_RW_U_RW) #endif @@ -75,38 +76,40 @@ /* Polling information used by remoteproc operations. */ static metal_phys_addr_t poll_phys_addr = POLL_BASE_ADDR; -struct metal_device kick_device = { - .name = "poll_dev", - .bus = NULL, - .num_regions = 1, - .regions = { - { - .virt = (void *)POLL_BASE_ADDR, - .physmap = &poll_phys_addr, - .size = 0x1000, - .page_shift = -1UL, - .page_mask = -1UL, - .mem_flags = MEM_ATTR_ACESS, - .ops = {NULL}, - } - }, - .node = {NULL}, +struct metal_device kick_device = +{ + .name = "poll_dev", + .bus = NULL, + .num_regions = 1, + .regions = { + { + .virt = (void *)POLL_BASE_ADDR, + .physmap = &poll_phys_addr, + .size = 0x1000, + .page_shift = -1UL, + .page_mask = -1UL, + .mem_flags = MEM_ATTR_ACESS, + .ops = {NULL}, + } + }, + .node = {NULL}, #ifdef CONFIG_USE_OPENAMP_IPI - .irq_num = 1, - .irq_info = (void *)CONFIG_IPI_IRQ_NUM, + .irq_num = 1, + .irq_info = (void *)CONFIG_IPI_IRQ_NUM, #endif /* !RPMSG_NO_IPI */ }; -static struct remoteproc_priv rproc_priv = { - .kick_dev_name = KICK_DEV_NAME, - .kick_dev_bus_name = KICK_BUS_NAME, +static struct remoteproc_priv rproc_priv = +{ + .kick_dev_name = KICK_DEV_NAME, + .kick_dev_bus_name = KICK_BUS_NAME, #ifdef CONFIG_USE_OPENAMP_IPI - .ipi_chn_mask = CONFIG_IPI_CHN_BITMASK,//IPI_CHN_BITMASK, + .ipi_chn_mask = CONFIG_IPI_CHN_BITMASK,//IPI_CHN_BITMASK, #endif /* !RPMSG_NO_IPI */ }; #ifdef CONFIG_USE_MASTER_VRING_DEFINE -static metal_phys_addr_t linux_share_buffer; + static metal_phys_addr_t linux_share_buffer; #endif static struct remoteproc rproc_inst; @@ -122,48 +125,53 @@ extern struct remote_resource_table resources; static struct remoteproc *platform_create_proc(int proc_index, int rsc_index) { - void *rsc_table; - int rsc_size; - int ret; - u32 cpu_id; - metal_phys_addr_t pa; - - (void)proc_index; - - rsc_table = (void *)&resources; //get_resource_table(rsc_index, &rsc_size); - rsc_size = sizeof(resources); - /* resource_table_dump(); */ - /* Register IPI device */ - if (metal_register_generic_device(&kick_device)) - return NULL; - /* Initialize remoteproc instance */ - if (!remoteproc_init(&rproc_inst, &phytium_proc_ops, &rproc_priv)) - return NULL; - - /* Mmap shared memories Or shall we constraint that they will be set as carved out in the resource table?. mmap resource table */ - pa = (metal_phys_addr_t)rsc_table; - (void *)remoteproc_mmap(&rproc_inst, &pa, NULL, rsc_size, MEM_ATTR_ACESS, &rproc_inst.rsc_io); - /* mmap shared memory */ - pa = SHARED_MEM_PA; - (void *)remoteproc_mmap(&rproc_inst, &pa, NULL, SHARED_MEM_SIZE, MEM_ATTR_ACESS, NULL); - - /* linux kernel malloc addr */ + void *rsc_table; + int rsc_size; + int ret; + u32 cpu_id; + metal_phys_addr_t pa; + + (void)proc_index; + + rsc_table = (void *)&resources; //get_resource_table(rsc_index, &rsc_size); + rsc_size = sizeof(resources); + /* resource_table_dump(); */ + /* Register IPI device */ + if (metal_register_generic_device(&kick_device)) + { + return NULL; + } + /* Initialize remoteproc instance */ + if (!remoteproc_init(&rproc_inst, &phytium_proc_ops, &rproc_priv)) + { + return NULL; + } + + /* Mmap shared memories Or shall we constraint that they will be set as carved out in the resource table?. mmap resource table */ + pa = (metal_phys_addr_t)rsc_table; + (void *)remoteproc_mmap(&rproc_inst, &pa, NULL, rsc_size, MEM_ATTR_ACESS, &rproc_inst.rsc_io); + /* mmap shared memory */ + pa = SHARED_MEM_PA; + (void *)remoteproc_mmap(&rproc_inst, &pa, NULL, SHARED_MEM_SIZE, MEM_ATTR_ACESS, NULL); + + /* linux kernel malloc addr */ #ifdef CONFIG_USE_MASTER_VRING_DEFINE - pa = resources.rpmsg_vdev.vring[0].da; /* 默认kernel vring[0].da 的首地址是整个sharebuffer 的起始位置 */ - (void *)remoteproc_mmap(&rproc_inst, &pa, NULL, SHARED_MEM_SIZE * 2, MEM_ATTR_ACESS, NULL); - linux_share_buffer = pa; + pa = resources.rpmsg_vdev.vring[0].da; /* 默认kernel vring[0].da 的首地址是整个sharebuffer 的起始位置 */ + (void *)remoteproc_mmap(&rproc_inst, &pa, NULL, SHARED_MEM_SIZE * 2, MEM_ATTR_ACESS, NULL); + linux_share_buffer = pa; #endif - /* parse resource table to remoteproc */ - ret = remoteproc_set_rsc_table(&rproc_inst, rsc_table, rsc_size); - if (ret) { - FT_PLAT_INFO_MAIN_DEBUG_E("Failed to intialize remoteproc %d \r\n",ret); - remoteproc_remove(&rproc_inst); - return NULL; - } - - FT_PLAT_INFO_MAIN_DEBUG_I("Initialize remoteproc successfully.\r\n"); - - return &rproc_inst; + /* parse resource table to remoteproc */ + ret = remoteproc_set_rsc_table(&rproc_inst, rsc_table, rsc_size); + if (ret) + { + FT_PLAT_INFO_MAIN_DEBUG_E("Failed to intialize remoteproc %d \r\n", ret); + remoteproc_remove(&rproc_inst); + return NULL; + } + + FT_PLAT_INFO_MAIN_DEBUG_I("Initialize remoteproc successfully.\r\n"); + + return &rproc_inst; } extern int init_system(void); @@ -171,147 +179,170 @@ extern void cleanup_system(void); int platform_init(int argc, char *argv[], void **platform) { - unsigned long proc_id = 0; - unsigned long rsc_id = 0; - struct remoteproc *rproc; - - if (!platform) { - FT_PLAT_INFO_MAIN_DEBUG_E("Failed to initialize platform, NULL pointer to store platform data.\r\n"); - return -EINVAL; - } - - /* Initialize HW system components */ - init_system(); - - if (argc >= 2) - proc_id = strtoul(argv[1], NULL, 0); - - if (argc >= 3) - rsc_id = strtoul(argv[2], NULL, 0); - rproc = platform_create_proc(proc_id, rsc_id); - if (!rproc) { - FT_PLAT_INFO_MAIN_DEBUG_E("Failed to create remoteproc device.\r\n"); - return -EINVAL; - } - - *platform = rproc; - - return 0; + unsigned long proc_id = 0; + unsigned long rsc_id = 0; + struct remoteproc *rproc; + + if (!platform) + { + FT_PLAT_INFO_MAIN_DEBUG_E("Failed to initialize platform, NULL pointer to store platform data.\r\n"); + return -EINVAL; + } + + /* Initialize HW system components */ + init_system(); + + if (argc >= 2) + { + proc_id = strtoul(argv[1], NULL, 0); + } + + if (argc >= 3) + { + rsc_id = strtoul(argv[2], NULL, 0); + } + rproc = platform_create_proc(proc_id, rsc_id); + if (!rproc) + { + FT_PLAT_INFO_MAIN_DEBUG_E("Failed to create remoteproc device.\r\n"); + return -EINVAL; + } + + *platform = rproc; + + return 0; } struct rpmsg_device *platform_create_rpmsg_vdev(void *platform, unsigned int vdev_index, unsigned int role, void (*rst_cb)(struct virtio_device *vdev), rpmsg_ns_bind_cb ns_bind_cb) { - struct remoteproc *rproc = platform; - struct rpmsg_virtio_device *rpmsg_vdev; - struct virtio_device *vdev; - void *shbuf; - struct metal_io_region *shbuf_io; - int ret; - - rpmsg_vdev = metal_allocate_memory(sizeof(*rpmsg_vdev)); - if (!rpmsg_vdev) - return NULL; + struct remoteproc *rproc = platform; + struct rpmsg_virtio_device *rpmsg_vdev; + struct virtio_device *vdev; + void *shbuf; + struct metal_io_region *shbuf_io; + int ret; + + rpmsg_vdev = metal_allocate_memory(sizeof(*rpmsg_vdev)); + if (!rpmsg_vdev) + { + return NULL; + } #ifdef CONFIG_USE_MASTER_VRING_DEFINE - shbuf_io = remoteproc_get_io_with_pa(rproc, linux_share_buffer); - if (!shbuf_io) - goto err1; - FT_PLAT_INFO_MAIN_DEBUG_I("linux_share_buffer is %p \r\n",linux_share_buffer); - shbuf = metal_io_phys_to_virt(shbuf_io, linux_share_buffer + SHARED_BUF_OFFSET); + shbuf_io = remoteproc_get_io_with_pa(rproc, linux_share_buffer); + if (!shbuf_io) + { + goto err1; + } + FT_PLAT_INFO_MAIN_DEBUG_I("linux_share_buffer is %p \r\n", linux_share_buffer); + shbuf = metal_io_phys_to_virt(shbuf_io, linux_share_buffer + SHARED_BUF_OFFSET); #else - shbuf_io = remoteproc_get_io_with_pa(rproc, SHARED_MEM_PA); - FT_PLAT_INFO_MAIN_DEBUG_I("shbuf_io is %p \r\n",shbuf_io); - if (!shbuf_io) - goto err1; - - shbuf = metal_io_phys_to_virt(shbuf_io, SHARED_MEM_PA + SHARED_BUF_OFFSET); + shbuf_io = remoteproc_get_io_with_pa(rproc, SHARED_MEM_PA); + FT_PLAT_INFO_MAIN_DEBUG_I("shbuf_io is %p \r\n", shbuf_io); + if (!shbuf_io) + { + goto err1; + } + + shbuf = metal_io_phys_to_virt(shbuf_io, SHARED_MEM_PA + SHARED_BUF_OFFSET); #endif - FT_PLAT_INFO_MAIN_DEBUG_I("creating remoteproc virtio\r\n"); - /* TODO: can we have a wrapper for the following two functions? */ - vdev = remoteproc_create_virtio(rproc, vdev_index, role, rst_cb); - if (!vdev) { - FT_PLAT_INFO_MAIN_DEBUG_E("failed remoteproc_create_virtio\r\n"); - goto err1; - } + FT_PLAT_INFO_MAIN_DEBUG_I("Creating remoteproc virtio\r\n"); + /* TODO: can we have a wrapper for the following two functions? */ + vdev = remoteproc_create_virtio(rproc, vdev_index, role, rst_cb); + if (!vdev) + { + FT_PLAT_INFO_MAIN_DEBUG_E("Failed remoteproc_create_virtio\r\n"); + goto err1; + } - FT_PLAT_INFO_MAIN_DEBUG_I("initializing rpmsg shared buffer pool\r\n"); - /* Only RPMsg virtio master needs to initialize the shared buffers pool */ - rpmsg_virtio_init_shm_pool(&shpool, shbuf, (SHARED_MEM_SIZE - SHARED_BUF_OFFSET)); + FT_PLAT_INFO_MAIN_DEBUG_I("Initializing rpmsg shared buffer pool\r\n"); + /* Only RPMsg virtio master needs to initialize the shared buffers pool */ + rpmsg_virtio_init_shm_pool(&shpool, shbuf, (SHARED_MEM_SIZE - SHARED_BUF_OFFSET)); - FT_PLAT_INFO_MAIN_DEBUG_I("initializing rpmsg vdev\r\n"); - /* RPMsg virtio slave can set shared buffers pool argument to NULL */ - ret = rpmsg_init_vdev(rpmsg_vdev, vdev, ns_bind_cb, shbuf_io, &shpool); - if (ret) { - FT_PLAT_INFO_MAIN_DEBUG_E("failed rpmsg_init_vdev\r\n"); - goto err2; - } + FT_PLAT_INFO_MAIN_DEBUG_I("Initializing rpmsg vdev\r\n"); + /* RPMsg virtio slave can set shared buffers pool argument to NULL */ + ret = rpmsg_init_vdev(rpmsg_vdev, vdev, ns_bind_cb, shbuf_io, &shpool); + if (ret) + { + FT_PLAT_INFO_MAIN_DEBUG_E("Failed rpmsg_init_vdev\r\n"); + goto err2; + } - FT_PLAT_INFO_MAIN_DEBUG_I("initializing rpmsg vdev\r\n"); - return rpmsg_virtio_get_rpmsg_device(rpmsg_vdev); + FT_PLAT_INFO_MAIN_DEBUG_I("Initializing rpmsg vdev\r\n"); + return rpmsg_virtio_get_rpmsg_device(rpmsg_vdev); err2: - remoteproc_remove_virtio(rproc, vdev); + remoteproc_remove_virtio(rproc, vdev); err1: - metal_free_memory(rpmsg_vdev); - return NULL; + metal_free_memory(rpmsg_vdev); + return NULL; } int platform_poll(void *priv) { - struct remoteproc *rproc = priv; - struct remoteproc_priv *prproc; - unsigned int flags; - int ret; + struct remoteproc *rproc = priv; + struct remoteproc_priv *prproc; + unsigned int flags; + int ret; - prproc = rproc->priv; - while(1) { + prproc = rproc->priv; + while (1) + { #ifndef CONFIG_USE_OPENAMP_IPI - if (metal_io_read32(prproc->kick_io, 0) & 0x2) { //RPROC_M2S_SHIFT - ret = remoteproc_get_notification(rproc, - RSC_NOTIFY_ID_ANY); - if (ret) - return ret; - break; - } - (void)flags; + if (metal_io_read32(prproc->kick_io, 0) & 0x2) //RPROC_M2S_SHIFT + { + ret = remoteproc_get_notification(rproc, + RSC_NOTIFY_ID_ANY); + if (ret) + { + return ret; + } + break; + } + (void)flags; #else /* !RPMSG_NO_IPI */ - flags = metal_irq_save_disable(); - if (!(atomic_flag_test_and_set(&prproc->ipi_nokick))) { - metal_irq_restore_enable(flags); - ret = remoteproc_get_notification(rproc, - RSC_NOTIFY_ID_ANY); - if (ret) - return ret; - break; - } - _rproc_wait(); - metal_irq_restore_enable(flags); + flags = metal_irq_save_disable(); + if (!(atomic_flag_test_and_set(&prproc->ipi_nokick))) + { + metal_irq_restore_enable(flags); + ret = remoteproc_get_notification(rproc, + RSC_NOTIFY_ID_ANY); + if (ret) + { + return ret; + } + break; + } + _rproc_wait(); + metal_irq_restore_enable(flags); #endif /* RPMSG_NO_IPI */ - } - return 0; + } + return 0; } void platform_release_rpmsg_vdev(struct rpmsg_device *rpdev, void *platform) { - struct rpmsg_virtio_device *rpvdev; - struct remoteproc *rproc; + struct rpmsg_virtio_device *rpvdev; + struct remoteproc *rproc; - rpvdev = metal_container_of(rpdev, struct rpmsg_virtio_device, rdev); - rproc = platform; + rpvdev = metal_container_of(rpdev, struct rpmsg_virtio_device, rdev); + rproc = platform; - rpmsg_deinit_vdev(rpvdev); - remoteproc_remove_virtio(rproc, rpvdev->vdev); + rpmsg_deinit_vdev(rpvdev); + remoteproc_remove_virtio(rproc, rpvdev->vdev); } void platform_cleanup(void *platform) { - struct remoteproc *rproc = platform; + struct remoteproc *rproc = platform; - if (rproc) - remoteproc_remove(rproc); - cleanup_system(); + if (rproc) + { + remoteproc_remove(rproc); + } + cleanup_system(); } diff --git a/third-party/openamp/ports/platform_info.h b/third-party/openamp/ports/platform_info.h index 010a027b..9651eb9d 100644 --- a/third-party/openamp/ports/platform_info.h +++ b/third-party/openamp/ports/platform_info.h @@ -1,22 +1,22 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: platform_info.h * Date: 2022-02-23 11:24:12 * LastEditTime: 2022-02-23 11:43:53 - * Description:  This file is for - * - * Modify History: + * Description:  This file is for + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- */ @@ -42,21 +42,21 @@ extern "C" { #endif -/***************** Macros (Inline Functions) Definitions *********************/ + /***************** Macros (Inline Functions) Definitions *********************/ -/* Cortex R5 memory attributes */ -#define DEVICE_SHARED 0x00000001U /* device, shareable */ -#define DEVICE_NONSHARED 0x00000010U /* device, non shareable */ -#define NORM_NSHARED_NCACHE 0x00000008U /* Non cacheable non shareable */ -#define NORM_SHARED_NCACHE 0x0000000CU /* Non cacheable shareable */ -#define PRIV_RW_USER_RW (0x00000003U<<8U) /* Full Access */ + /* Cortex R5 memory attributes */ +#define DEVICE_SHARED 0x00000001U /* device, shareable */ +#define DEVICE_NONSHARED 0x00000010U /* device, non shareable */ +#define NORM_NSHARED_NCACHE 0x00000008U /* Non cacheable non shareable */ +#define NORM_SHARED_NCACHE 0x0000000CU /* Non cacheable shareable */ +#define PRIV_RW_USER_RW (0x00000003U<<8U) /* Full Access */ -#define SHARED_MEM_PA CONFIG_VRING_TX_ADDR +#define SHARED_MEM_PA CONFIG_VRING_TX_ADDR #define POLL_BASE_ADDR CONFIG_POLL_BASE_ADDR -#define SHARED_MEM_SIZE 0x100000UL /* 必须要和kernel 进行约定 */ -#define SHARED_BUF_OFFSET 0x8000UL +#define SHARED_MEM_SIZE 0x100000UL /* 必须要和kernel 进行约定 */ +#define SHARED_BUF_OFFSET 0x8000UL #ifdef CONFIG_USE_OPENAMP_IPI @@ -68,77 +68,78 @@ extern "C" { #define POLL_STOP 0x1U #endif -/**************************** Type Definitions *******************************/ + /**************************** Type Definitions *******************************/ -struct remoteproc_priv { - const char *kick_dev_name; - const char *kick_dev_bus_name; - struct metal_device *kick_dev; - struct metal_io_region *kick_io; + struct remoteproc_priv + { + const char *kick_dev_name; + const char *kick_dev_bus_name; + struct metal_device *kick_dev; + struct metal_io_region *kick_io; #ifdef CONFIG_USE_OPENAMP_IPI - unsigned int ipi_chn_mask; /**< IPI channel mask */ - atomic_int ipi_nokick; + unsigned int ipi_chn_mask; /**< IPI channel mask */ + atomic_int ipi_nokick; #endif /* !RPMSG_NO_IPI */ -}; - -/************************** Function Prototypes ******************************/ - -/** - * platform_init - initialize the platform - * - * It will initialize the platform. - * - * @argc: number of arguments - * @argv: array of the input arguements - * @platform: pointer to store the platform data pointer - * - * return 0 for success or negative value for failure - */ -int platform_init(int argc, char *argv[], void **platform); - -/** - * platform_create_rpmsg_vdev - create rpmsg vdev - * - * It will create rpmsg virtio device, and returns the rpmsg virtio - * device pointer. - * - * @platform: pointer to the private data - * @vdev_index: index of the virtio device, there can more than one vdev - * on the platform. - * @role: virtio master or virtio slave of the vdev - * @rst_cb: virtio device reset callback - * @ns_bind_cb: rpmsg name service bind callback - * - * return pointer to the rpmsg virtio device - */ -struct rpmsg_device * -platform_create_rpmsg_vdev(void *platform, unsigned int vdev_index, - unsigned int role, - void (*rst_cb)(struct virtio_device *vdev), - rpmsg_ns_bind_cb ns_bind_cb); - -/** - * platform_poll - platform poll function - * - * @platform: pointer to the platform - * - * return negative value for errors, otherwise 0. - */ -int platform_poll(void *platform); - -/** - * platform_release_rpmsg_vdev - release rpmsg virtio device - * - * @rpdev: pointer to the rpmsg device - */ -void platform_release_rpmsg_vdev(struct rpmsg_device *rpdev, void *platform); - -/** - * platform_cleanup - clean up the platform resource - * - * @platform: pointer to the platform - */ -void platform_cleanup(void *platform); + }; + + /************************** Function Prototypes ******************************/ + + /** + * platform_init - initialize the platform + * + * It will initialize the platform. + * + * @argc: number of arguments + * @argv: array of the input arguements + * @platform: pointer to store the platform data pointer + * + * return 0 for success or negative value for failure + */ + int platform_init(int argc, char *argv[], void **platform); + + /** + * platform_create_rpmsg_vdev - create rpmsg vdev + * + * It will create rpmsg virtio device, and returns the rpmsg virtio + * device pointer. + * + * @platform: pointer to the private data + * @vdev_index: index of the virtio device, there can more than one vdev + * on the platform. + * @role: virtio master or virtio slave of the vdev + * @rst_cb: virtio device reset callback + * @ns_bind_cb: rpmsg name service bind callback + * + * return pointer to the rpmsg virtio device + */ + struct rpmsg_device * + platform_create_rpmsg_vdev(void *platform, unsigned int vdev_index, + unsigned int role, + void (*rst_cb)(struct virtio_device *vdev), + rpmsg_ns_bind_cb ns_bind_cb); + + /** + * platform_poll - platform poll function + * + * @platform: pointer to the platform + * + * return negative value for errors, otherwise 0. + */ + int platform_poll(void *platform); + + /** + * platform_release_rpmsg_vdev - release rpmsg virtio device + * + * @rpdev: pointer to the rpmsg device + */ + void platform_release_rpmsg_vdev(struct rpmsg_device *rpdev, void *platform); + + /** + * platform_cleanup - clean up the platform resource + * + * @platform: pointer to the platform + */ + void platform_cleanup(void *platform); #if defined __cplusplus diff --git a/third-party/openamp/ports/rsc_table.c b/third-party/openamp/ports/rsc_table.c index c2535406..7f342b93 100644 --- a/third-party/openamp/ports/rsc_table.c +++ b/third-party/openamp/ports/rsc_table.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: rsc_table.c * Date: 2022-02-23 11:24:12 * LastEditTime: 2022-02-23 11:43:59 - * Description:  This file is for - * - * Modify History: + * Description:  This file populates resource table for BM remote + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/04/21 first release */ @@ -28,6 +29,13 @@ #include "rsc_table.h" #include #include "sdkconfig.h" +#include "fdebug.h" + +#define RSC_TABLE_DEBUG_TAG "RSC_TABLE" +#define RSC_TABLE_DEBUG(format, ...) FT_DEBUG_PRINT_D(RSC_TABLE_DEBUG_TAG, format, ##__VA_ARGS__) +#define RSC_TABLE_INFO(format, ...) FT_DEBUG_PRINT_I(RSC_TABLE_DEBUG_TAG, format, ##__VA_ARGS__) +#define RSC_TABLE_WARN(format, ...) FT_DEBUG_PRINT_W(RSC_TABLE_DEBUG_TAG, format, ##__VA_ARGS__) +#define RSC_TABLE_ERROR(format, ...) FT_DEBUG_PRINT_E(RSC_TABLE_DEBUG_TAG, format, ##__VA_ARGS__) /***************** Macros (Inline Functions) Definitions *********************/ @@ -45,9 +53,9 @@ #define NUM_VRINGS 0x02 #define VRING_ALIGN 0x1000 -#define RING_TX CONFIG_VRING_TX_ADDR -#define RING_RX CONFIG_VRING_RX_ADDR -#define VRING_SIZE CONFIG_VRING_SIZE +#define RING_TX CONFIG_VRING_TX_ADDR +#define RING_RX CONFIG_VRING_RX_ADDR +#define VRING_SIZE CONFIG_VRING_SIZE #define NUM_TABLE_ENTRIES 1 @@ -57,36 +65,37 @@ /************************** Variable Definitions *****************************/ -struct remote_resource_table __resource resources = { - /* Version */ - 1, - - /* NUmber of table entries */ - NUM_TABLE_ENTRIES, - /* reserved fields */ - {0, 0,}, - - /* Offsets of rsc entries */ - { - offsetof(struct remote_resource_table, rpmsg_vdev), - }, - - /* Virtio device entry */ - { - RSC_VDEV, VIRTIO_ID_RPMSG_, 0, RPMSG_IPU_C0_FEATURES, 0, 0, 0, - NUM_VRINGS, {0, 0}, - }, - - /* Vring rsc entry - part of vdev rsc entry */ - {RING_TX, VRING_ALIGN, VRING_SIZE, 1, 0}, - {RING_RX, VRING_ALIGN, VRING_SIZE, 2, 0}, +struct remote_resource_table __resource resources = +{ + /* Version */ + 1, + + /* NUmber of table entries */ + NUM_TABLE_ENTRIES, + /* reserved fields */ + {0, 0,}, + + /* Offsets of rsc entries */ + { + offsetof(struct remote_resource_table, rpmsg_vdev), + }, + + /* Virtio device entry */ + { + RSC_VDEV, VIRTIO_ID_RPMSG_, 0, RPMSG_IPU_C0_FEATURES, 0, 0, 0, + NUM_VRINGS, {0, 0}, + }, + + /* Vring rsc entry - part of vdev rsc entry */ + {RING_TX, VRING_ALIGN, VRING_SIZE, 1, 0}, + {RING_RX, VRING_ALIGN, VRING_SIZE, 2, 0}, }; -void *get_resource_table (int rsc_id, int *len) +void *get_resource_table(int rsc_id, int *len) { - (void) rsc_id; - *len = sizeof(resources); - return &resources; + (void) rsc_id; + *len = sizeof(resources); + return &resources; } @@ -96,25 +105,25 @@ void *get_resource_table (int rsc_id, int *len) void resource_table_dump(void) { - printf("version is %d \r\n",resources.version); - printf("num is %d \r\n",resources.num); - printf("offset is %d \r\n",resources.offset[0]); - printf("rpmsg_vdev.type is %d \r\n",resources.rpmsg_vdev.type); - printf("rpmsg_vdev.id is %d \r\n",resources.rpmsg_vdev.id); - printf("rpmsg_vdev.notifyid is %d \r\n",resources.rpmsg_vdev.notifyid); - printf("rpmsg_vdev.dfeatures is %d \r\n",resources.rpmsg_vdev.dfeatures); - printf("rpmsg_vdev.gfeatures is %d \r\n",resources.rpmsg_vdev.gfeatures); - printf("rpmsg_vdev.config_len is %d \r\n",resources.rpmsg_vdev.config_len); - printf("rpmsg_vdev.status is %d \r\n",resources.rpmsg_vdev.status); - printf("rpmsg_vdev.num_of_vrings is %d \r\n",resources.rpmsg_vdev.num_of_vrings); - printf("rpmsg_vdev.vring[0].da is %x \r\n",resources.rpmsg_vdev.vring[0].da); - printf("rpmsg_vdev.vring[0].align is %d \r\n",resources.rpmsg_vdev.vring[0].align); - printf("rpmsg_vdev.vring[0].num is %d \r\n",resources.rpmsg_vdev.vring[0].num); - printf("rpmsg_vdev.vring[0].notifyid is %d \r\n",resources.rpmsg_vdev.vring[0].notifyid); - printf("rpmsg_vdev.vring[0].reserved is %d \r\n",resources.rpmsg_vdev.vring[0].reserved); - printf("rpmsg_vdev.vring[1].da is %x \r\n",resources.rpmsg_vdev.vring[1].da); - printf("rpmsg_vdev.vring[1].align is %d \r\n",resources.rpmsg_vdev.vring[1].align); - printf("rpmsg_vdev.vring[1].num is %d \r\n",resources.rpmsg_vdev.vring[1].num); - printf("rpmsg_vdev.vring[1].notifyid is %d \r\n",resources.rpmsg_vdev.vring[1].notifyid); - printf("rpmsg_vdev.vring[1].reserved is %d \r\n",resources.rpmsg_vdev.vring[1].reserved); + RSC_TABLE_DEBUG("version is %d .\r\n", resources.version); + RSC_TABLE_DEBUG("num is %d .\r\n", resources.num); + RSC_TABLE_DEBUG("offset is %d .\r\n", resources.offset[0]); + RSC_TABLE_DEBUG("rpmsg_vdev.type is %d .\r\n", resources.rpmsg_vdev.type); + RSC_TABLE_DEBUG("rpmsg_vdev.id is %d .\r\n", resources.rpmsg_vdev.id); + RSC_TABLE_DEBUG("rpmsg_vdev.notifyid is %d .\r\n", resources.rpmsg_vdev.notifyid); + RSC_TABLE_DEBUG("rpmsg_vdev.dfeatures is %d .\r\n", resources.rpmsg_vdev.dfeatures); + RSC_TABLE_DEBUG("rpmsg_vdev.gfeatures is %d .\r\n", resources.rpmsg_vdev.gfeatures); + RSC_TABLE_DEBUG("rpmsg_vdev.config_len is %d .\r\n", resources.rpmsg_vdev.config_len); + RSC_TABLE_DEBUG("rpmsg_vdev.status is %d .\r\n", resources.rpmsg_vdev.status); + RSC_TABLE_DEBUG("rpmsg_vdev.num_of_vrings is %d .\r\n", resources.rpmsg_vdev.num_of_vrings); + RSC_TABLE_DEBUG("rpmsg_vdev.vring[0].da is %x .\r\n", resources.rpmsg_vdev.vring[0].da); + RSC_TABLE_DEBUG("rpmsg_vdev.vring[0].align is %d .\r\n", resources.rpmsg_vdev.vring[0].align); + RSC_TABLE_DEBUG("rpmsg_vdev.vring[0].num is %d .\r\n", resources.rpmsg_vdev.vring[0].num); + RSC_TABLE_DEBUG("rpmsg_vdev.vring[0].notifyid is %d .\r\n", resources.rpmsg_vdev.vring[0].notifyid); + RSC_TABLE_DEBUG("rpmsg_vdev.vring[0].reserved is %d .\r\n", resources.rpmsg_vdev.vring[0].reserved); + RSC_TABLE_DEBUG("rpmsg_vdev.vring[1].da is %x .\r\n", resources.rpmsg_vdev.vring[1].da); + RSC_TABLE_DEBUG("rpmsg_vdev.vring[1].align is %d .\r\n", resources.rpmsg_vdev.vring[1].align); + RSC_TABLE_DEBUG("rpmsg_vdev.vring[1].num is %d .\r\n", resources.rpmsg_vdev.vring[1].num); + RSC_TABLE_DEBUG("rpmsg_vdev.vring[1].notifyid is %d .\r\n", resources.rpmsg_vdev.vring[1].notifyid); + RSC_TABLE_DEBUG("rpmsg_vdev.vring[1].reserved is %d .\r\n", resources.rpmsg_vdev.vring[1].reserved); } diff --git a/third-party/openamp/ports/rsc_table.h b/third-party/openamp/ports/rsc_table.h index 473a04bc..ed1a4994 100644 --- a/third-party/openamp/ports/rsc_table.h +++ b/third-party/openamp/ports/rsc_table.h @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: rsc_table.h * Date: 2022-02-23 11:24:12 * LastEditTime: 2022-02-23 11:44:06 - * Description:  This file is for - * - * Modify History: + * Description:  This file populates resource table for BM remote + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 huanghe 2022/03/25 first release */ @@ -34,32 +35,33 @@ extern "C" { #endif -/************************** Constant Definitions *****************************/ + /************************** Constant Definitions *****************************/ -/************************** Variable Definitions *****************************/ + /************************** Variable Definitions *****************************/ -/************************** Function Prototypes ******************************/ + /************************** Function Prototypes ******************************/ -/***************** Macros (Inline Functions) Definitions *********************/ + /***************** Macros (Inline Functions) Definitions *********************/ #define NO_RESOURCE_ENTRIES 8 -/**************************** Type Definitions *******************************/ - -/* Resource table for the given remote */ -struct remote_resource_table { - unsigned int version; - unsigned int num; - unsigned int reserved[2]; - unsigned int offset[NO_RESOURCE_ENTRIES]; - /* rpmsg vdev entry */ - struct fw_rsc_vdev rpmsg_vdev; - struct fw_rsc_vdev_vring rpmsg_vring0; - struct fw_rsc_vdev_vring rpmsg_vring1; -}__attribute__((packed, aligned(0x100))); - -void *get_resource_table (int rsc_id, int *len); + /**************************** Type Definitions *******************************/ + + /* Resource table for the given remote */ + struct remote_resource_table + { + unsigned int version; + unsigned int num; + unsigned int reserved[2]; + unsigned int offset[NO_RESOURCE_ENTRIES]; + /* rpmsg vdev entry */ + struct fw_rsc_vdev rpmsg_vdev; + struct fw_rsc_vdev_vring rpmsg_vring0; + struct fw_rsc_vdev_vring rpmsg_vring1; + } __attribute__((packed, aligned(0x100))); + + void *get_resource_table(int rsc_id, int *len); #if defined __cplusplus } diff --git a/third-party/sdmmc-1.0/Kconfig b/third-party/sdmmc-1.0/Kconfig index 682390a2..43cca455 100644 --- a/third-party/sdmmc-1.0/Kconfig +++ b/third-party/sdmmc-1.0/Kconfig @@ -1,12 +1 @@ -menu "SDMMC Configuration" - choice SDMMC_PORT_TYPE - prompt "MMC/SD Type" - help - Select MMC/SD Driver - - config SDMMC_PORT_FSDIO - bool "FSDIO" - select USE_SDMMC - select ENABLE_FSDIO - endchoice #SDMMC_PORT_TYPE -endmenu \ No newline at end of file +source "$STANDALONE_DIR/third-party/sdmmc/Kconfig" \ No newline at end of file diff --git a/third-party/sdmmc-1.0/inc/sdmmc_cmd.h b/third-party/sdmmc-1.0/inc/sdmmc_cmd.h deleted file mode 100644 index b5f7e32c..00000000 --- a/third-party/sdmmc-1.0/inc/sdmmc_cmd.h +++ /dev/null @@ -1,312 +0,0 @@ -// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef _SDMMC_CMD_H_ -#define _SDMMC_CMD_H_ - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include -#include "sdmmc_types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Probe and initialize SD/MMC card using given host - * - * @note Only SD cards (SDSC and SDHC/SDXC) are supported now. - * Support for MMC/eMMC cards will be added later. - * - * @param host pointer to structure defining host controller - * @param out_card pointer to structure which will receive information - * about the card when the function completes - * @return - * - SDMMC_OK on success - * - One of the error codes from SDMMC host controller - */ -sdmmc_err_t sdmmc_card_init(const sdmmc_host_t* host, - sdmmc_card_t* out_card); - -/** - * Probe and initialize eMMC using given host - * - * @note Only eMMC are supported for this function. - * - * @param host pointer to structure defining host controller - * @param out_card pointer to structure which will receive information - * about the card when the function completes - * @return - * - SDMMC_OK on success - * - One of the error codes from SDMMC host controller - */ -sdmmc_err_t sdmmc_init_emmc(const sdmmc_host_t *config, sdmmc_card_t *card); - -/** - * Probe and initialize TF cards (SDHC/SDXC) using given host - * - * @note Only TF are supported for this function. - * - * @param host pointer to structure defining host controller - * @param out_card pointer to structure which will receive information - * about the card when the function completes - * @return - * - SDMMC_OK on success - * - One of the error codes from SDMMC host controller - */ -sdmmc_err_t sdmmc_init_tf_card(const sdmmc_host_t *config, sdmmc_card_t *card); - -/** - * @brief Print information about the card to a stream - * @param stream stream obtained using fopen or fdopen - * @param card card information structure initialized using sdmmc_card_init - */ -void sdmmc_card_print_info(FILE* stream, const sdmmc_card_t* card); - -/** - * Write given number of sectors to SD/MMC card - * - * @param card pointer to card information structure previously initialized - * using sdmmc_card_init - * @param src pointer to data buffer to read data from; data size must be - * equal to sector_count * card->csd.sector_size - * @param start_sector sector where to start writing - * @param sector_count number of sectors to write - * @return - * - SDMMC_OK on success - * - One of the error codes from SDMMC host controller - */ -sdmmc_err_t sdmmc_write_sectors(sdmmc_card_t* card, const void* src, - size_t start_sector, size_t sector_count); - -/** - * Write given number of sectors to SD/MMC card - * - * @param card pointer to card information structure previously initialized - * using sdmmc_card_init - * @param dst pointer to data buffer to write into; buffer size must be - * at least sector_count * card->csd.sector_size - * @param start_sector sector where to start reading - * @param sector_count number of sectors to read - * @return - * - SDMMC_OK on success - * - One of the error codes from SDMMC host controller - */ -sdmmc_err_t sdmmc_read_sectors(sdmmc_card_t* card, void* dst, - size_t start_sector, size_t sector_count); - -/** - * Read one byte from an SDIO card using IO_RW_DIRECT (CMD52) - * - * @param card pointer to card information structure previously initialized - * using sdmmc_card_init - * @param function IO function number - * @param reg byte address within IO function - * @param[out] out_byte output, receives the value read from the card - * @return - * - SDMMC_OK on success - * - One of the error codes from SDMMC host controller - */ -sdmmc_err_t sdmmc_io_read_byte(sdmmc_card_t* card, uint32_t function, - uint32_t reg, uint8_t *out_byte); - -/** - * Write one byte to an SDIO card using IO_RW_DIRECT (CMD52) - * - * @param card pointer to card information structure previously initialized - * using sdmmc_card_init - * @param function IO function number - * @param reg byte address within IO function - * @param in_byte value to be written - * @param[out] out_byte if not NULL, receives new byte value read - * from the card (read-after-write). - * @return - * - SDMMC_OK on success - * - One of the error codes from SDMMC host controller - */ -sdmmc_err_t sdmmc_io_write_byte(sdmmc_card_t* card, uint32_t function, - uint32_t reg, uint8_t in_byte, uint8_t* out_byte); - -/** - * Read multiple bytes from an SDIO card using IO_RW_EXTENDED (CMD53) - * - * This function performs read operation using CMD53 in byte mode. - * For block mode, see sdmmc_io_read_blocks. - * - * @param card pointer to card information structure previously initialized - * using sdmmc_card_init - * @param function IO function number - * @param addr byte address within IO function where reading starts - * @param dst buffer which receives the data read from card - * @param size number of bytes to read - * @return - * - SDMMC_OK on success - * - SDMMC_ERR_INVALID_SIZE if size exceeds 512 bytes - * - One of the error codes from SDMMC host controller - */ -sdmmc_err_t sdmmc_io_read_bytes(sdmmc_card_t* card, uint32_t function, - uint32_t addr, void* dst, size_t size); - -/** - * Write multiple bytes to an SDIO card using IO_RW_EXTENDED (CMD53) - * - * This function performs write operation using CMD53 in byte mode. - * For block mode, see sdmmc_io_write_blocks. - * - * @param card pointer to card information structure previously initialized - * using sdmmc_card_init - * @param function IO function number - * @param addr byte address within IO function where writing starts - * @param src data to be written - * @param size number of bytes to write - * @return - * - SDMMC_OK on success - * - SDMMC_ERR_INVALID_SIZE if size exceeds 512 bytes - * - One of the error codes from SDMMC host controller - */ -sdmmc_err_t sdmmc_io_write_bytes(sdmmc_card_t* card, uint32_t function, - uint32_t addr, const void* src, size_t size); - -/** - * Read blocks of data from an SDIO card using IO_RW_EXTENDED (CMD53) - * - * This function performs read operation using CMD53 in block mode. - * For byte mode, see sdmmc_io_read_bytes. - * - * @param card pointer to card information structure previously initialized - * using sdmmc_card_init - * @param function IO function number - * @param addr byte address within IO function where writing starts - * @param dst buffer which receives the data read from card - * @param size number of bytes to read, must be divisible by the card block - * size. - * @return - * - SDMMC_OK on success - * - SDMMC_ERR_INVALID_SIZE if size is not divisible by 512 bytes - * - One of the error codes from SDMMC host controller - */ -sdmmc_err_t sdmmc_io_read_blocks(sdmmc_card_t* card, uint32_t function, - uint32_t addr, void* dst, size_t size); - -/** - * Write blocks of data to an SDIO card using IO_RW_EXTENDED (CMD53) - * - * This function performs write operation using CMD53 in block mode. - * For byte mode, see sdmmc_io_write_bytes. - * - * @param card pointer to card information structure previously initialized - * using sdmmc_card_init - * @param function IO function number - * @param addr byte address within IO function where writing starts - * @param src data to be written - * @param size number of bytes to read, must be divisible by the card block - * size. - * @return - * - SDMMC_OK on success - * - SDMMC_ERR_INVALID_SIZE if size is not divisible by 512 bytes - * - One of the error codes from SDMMC host controller - */ -sdmmc_err_t sdmmc_io_write_blocks(sdmmc_card_t* card, uint32_t function, - uint32_t addr, const void* src, size_t size); - -/** - * Enable SDIO interrupt in the SDMMC host - * - * @param card pointer to card information structure previously initialized - * using sdmmc_card_init - * @return - * - SDMMC_OK on success - * - SDMMC_ERR_NOT_SUPPORTED if the host controller does not support - * IO interrupts - */ -sdmmc_err_t sdmmc_io_enable_int(sdmmc_card_t* card); - -/** - * Block until an SDIO interrupt is received - * - * Slave uses D1 line to signal interrupt condition to the host. - * This function can be used to wait for the interrupt. - * - * @param card pointer to card information structure previously initialized - * using sdmmc_card_init - * @param timeout_ticks time to wait for the interrupt, in RTOS ticks - * @return - * - SDMMC_OK if the interrupt is received - * - SDMMC_ERR_NOT_SUPPORTED if the host controller does not support - * IO interrupts - * - SDMMC_ERR_TIMEOUT if the interrupt does not happen in timeout_ticks - */ -sdmmc_err_t sdmmc_io_wait_int(sdmmc_card_t* card, TickType_t timeout_ticks); - -/** - * Get the data of CIS region of a SDIO card. - * - * You may provide a buffer not sufficient to store all the CIS data. In this - * case, this functions store as much data into your buffer as possible. Also, - * this function will try to get and return the size required for you. - * - * @param card pointer to card information structure previously initialized - * using sdmmc_card_init - * @param out_buffer Output buffer of the CIS data - * @param buffer_size Size of the buffer. - * @param inout_cis_size Mandatory, pointer to a size, input and output. - * - input: Limitation of maximum searching range, should be 0 or larger than - * buffer_size. The function searches for CIS_CODE_END until this range. Set to - * 0 to search infinitely. - * - output: The size required to store all the CIS data, if CIS_CODE_END is found. - * - * @return - * - SDMMC_OK: on success - * - SDMMC_ERR_INVALID_RESPONSE: if the card does not (correctly) support CIS. - * - SDMMC_ERR_INVALID_SIZE: CIS_CODE_END found, but buffer_size is less than - * required size, which is stored in the inout_cis_size then. - * - SDMMC_ERR_NOT_FOUND: if the CIS_CODE_END not found. Increase input value of - * inout_cis_size or set it to 0, if you still want to search for the end; - * output value of inout_cis_size is invalid in this case. - * - and other error code return from sdmmc_io_read_bytes - */ -sdmmc_err_t sdmmc_io_get_cis_data(sdmmc_card_t* card, uint8_t* out_buffer, size_t buffer_size, size_t* inout_cis_size); - -/** - * Parse and print the CIS information of a SDIO card. - * - * @note Not all the CIS codes and all kinds of tuples are supported. If you - * see some unresolved code, you can add the parsing of these code in - * sdmmc_io.c and contribute to the IDF through the Github repository. - * - * using sdmmc_card_init - * @param buffer Buffer to parse - * @param buffer_size Size of the buffer. - * @param fp File pointer to print to, set to NULL to print to stdout. - * - * @return - * - SDMMC_OK: on success - * - SDMMC_ERR_NOT_SUPPORTED: if the value from the card is not supported to be parsed. - * - SDMMC_ERR_INVALID_SIZE: if the CIS size fields are not correct. - */ -sdmmc_err_t sdmmc_io_print_cis_info(uint8_t* buffer, size_t buffer_size, FILE* fp); - -sdmmc_err_t sdmmc_send_cmd_switch(sdmmc_card_t *card); - -sdmmc_err_t sdmmc_send_stop_transmission(sdmmc_card_t *card); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/third-party/sdmmc-1.0/inc/sdmmc_common.h b/third-party/sdmmc-1.0/inc/sdmmc_common.h deleted file mode 100644 index 537d83d0..00000000 --- a/third-party/sdmmc-1.0/inc/sdmmc_common.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (c) 2006 Uwe Stuehler - * Adaptations to ESP-IDF Copyright (c) 2016-2018 Espressif Systems (Shanghai) PTE LTD - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _SDMMC_COMMON_H_ -#define _SDMMC_COMMON_H_ - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include -#include - -#include "sdmmc_defs.h" -#include "sdmmc_types.h" -#include "sdmmc_cmd.h" -#include "sdmmc_port.h" - -/** - * @brief Flags to indicate the capabilities of the various memory systems - */ -#define MALLOC_CAP_EXEC (1<<0) ///< Memory must be able to run executable code -#define MALLOC_CAP_32BIT (1<<1) ///< Memory must allow for aligned 32-bit data accesses -#define MALLOC_CAP_8BIT (1<<2) ///< Memory must allow for 8/16/...-bit data accesses -#define MALLOC_CAP_DMA (1<<3) ///< Memory must be able to accessed by DMA -#define MALLOC_CAP_PID2 (1<<4) ///< Memory must be mapped to PID2 memory space (PIDs are not currently used) -#define MALLOC_CAP_PID3 (1<<5) ///< Memory must be mapped to PID3 memory space (PIDs are not currently used) -#define MALLOC_CAP_PID4 (1<<6) ///< Memory must be mapped to PID4 memory space (PIDs are not currently used) -#define MALLOC_CAP_PID5 (1<<7) ///< Memory must be mapped to PID5 memory space (PIDs are not currently used) -#define MALLOC_CAP_PID6 (1<<8) ///< Memory must be mapped to PID6 memory space (PIDs are not currently used) -#define MALLOC_CAP_PID7 (1<<9) ///< Memory must be mapped to PID7 memory space (PIDs are not currently used) -#define MALLOC_CAP_SPIRAM (1<<10) ///< Memory must be in SPI RAM -#define MALLOC_CAP_INTERNAL (1<<11) ///< Memory must be internal; specifically it should not disappear when flash/spiram cache is switched off -#define MALLOC_CAP_DEFAULT (1<<12) ///< Memory can be returned in a non-capability-specific memory allocation (e.g. malloc(), calloc()) call -#define MALLOC_CAP_IRAM_8BIT (1<<13) ///< Memory must be in IRAM and allow unaligned access -#define MALLOC_CAP_RETENTION (1<<14) - -#define MALLOC_CAP_INVALID (1<<31) ///< Memory can't be used / list end marker - - -#define SDMMC_GO_IDLE_DELAY_MS 20 -#define SDMMC_IO_SEND_OP_COND_DELAY_MS 10 - -/* These delay values are mostly useful for cases when CD pin is not used, and - * the card is removed. In this case, SDMMC peripheral may not always return - * CMD_DONE / DATA_DONE interrupts after signaling the error. These timeouts work - * as a safety net in such cases. - */ -#define SDMMC_DEFAULT_CMD_TIMEOUT_MS 1000 // Max timeout of ordinary commands -#define SDMMC_WRITE_CMD_TIMEOUT_MS 5000 // Max timeout of write commands - -/* Maximum retry/error count for SEND_OP_COND (CMD1). - * These are somewhat arbitrary, values originate from OpenBSD driver. - */ -#define SDMMC_SEND_OP_COND_MAX_RETRIES 100 -#define SDMMC_SEND_OP_COND_MAX_ERRORS 3 - -/* Functions to send individual commands */ -sdmmc_err_t sdmmc_send_cmd(sdmmc_card_t* card, sdmmc_command_t* cmd); -sdmmc_err_t sdmmc_send_app_cmd(sdmmc_card_t* card, sdmmc_command_t* cmd); -sdmmc_err_t sdmmc_send_cmd_go_idle_state(sdmmc_card_t* card); -sdmmc_err_t sdmmc_send_cmd_send_if_cond(sdmmc_card_t* card, uint32_t ocr); -sdmmc_err_t sdmmc_send_cmd_send_op_cond(sdmmc_card_t* card, uint32_t ocr, uint32_t *ocrp); -sdmmc_err_t sdmmc_send_cmd_read_ocr(sdmmc_card_t *card, uint32_t *ocrp); -sdmmc_err_t sdmmc_send_cmd_send_cid(sdmmc_card_t *card, sdmmc_cid_t *out_cid); -sdmmc_err_t sdmmc_send_cmd_all_send_cid(sdmmc_card_t* card, sdmmc_response_t* out_raw_cid); -sdmmc_err_t sdmmc_send_cmd_set_relative_addr(sdmmc_card_t* card, uint16_t* out_rca); -sdmmc_err_t sdmmc_send_cmd_set_blocklen(sdmmc_card_t* card, sdmmc_csd_t* csd); -sdmmc_err_t sdmmc_send_cmd_switch_func(sdmmc_card_t* card, - uint32_t mode, uint32_t group, uint32_t function, - sdmmc_switch_func_rsp_t* resp); -sdmmc_err_t sdmmc_send_cmd_send_csd(sdmmc_card_t* card, sdmmc_csd_t* out_csd); -sdmmc_err_t sdmmc_send_cmd_select_card(sdmmc_card_t* card, uint32_t rca); -sdmmc_err_t sdmmc_send_cmd_send_scr(sdmmc_card_t* card, sdmmc_scr_t *out_scr); -sdmmc_err_t sdmmc_send_cmd_set_bus_width(sdmmc_card_t* card, int width); -sdmmc_err_t sdmmc_send_cmd_send_status(sdmmc_card_t* card, uint32_t* out_status); -sdmmc_err_t sdmmc_send_cmd_crc_on_off(sdmmc_card_t* card, bool crc_enable); -sdmmc_err_t sdmmc_init_switch_hs(sdmmc_card_t *card); -sdmmc_err_t sdmmc_set_blockcount(sdmmc_card_t *card, size_t block_count); - -/* Higher level functions */ -sdmmc_err_t sdmmc_enable_hs_mode(sdmmc_card_t* card); -sdmmc_err_t sdmmc_enable_hs_mode_and_check(sdmmc_card_t* card); -sdmmc_err_t sdmmc_write_sectors_dma(sdmmc_card_t* card, const void* src, - size_t start_block, size_t block_count); -sdmmc_err_t sdmmc_read_sectors_dma(sdmmc_card_t* card, void* dst, - size_t start_block, size_t block_count); - -/* SD specific */ -sdmmc_err_t sdmmc_check_scr(sdmmc_card_t* card); -sdmmc_err_t sdmmc_decode_cid(sdmmc_response_t resp, sdmmc_cid_t* out_cid); -sdmmc_err_t sdmmc_decode_csd(sdmmc_response_t response, sdmmc_csd_t* out_csd); -sdmmc_err_t sdmmc_decode_scr(uint32_t *raw_scr, sdmmc_scr_t* out_scr); - -/* SDIO specific */ -sdmmc_err_t sdmmc_io_reset(sdmmc_card_t* card); -sdmmc_err_t sdmmc_io_enable_hs_mode(sdmmc_card_t* card); -sdmmc_err_t sdmmc_io_send_op_cond(sdmmc_card_t* card, uint32_t ocr, uint32_t *ocrp); -sdmmc_err_t sdmmc_io_rw_direct(sdmmc_card_t* card, int function, - uint32_t reg, uint32_t arg, uint8_t *byte); -sdmmc_err_t sdmmc_io_rw_extended(sdmmc_card_t* card, int function, - uint32_t reg, int arg, void *data, size_t size); - - -/* MMC specific */ -sdmmc_err_t sdmmc_mmc_send_ext_csd_data(sdmmc_card_t* card, void *out_data, size_t datalen); -sdmmc_err_t sdmmc_mmc_switch(sdmmc_card_t* card, uint8_t set, uint8_t index, uint8_t value); -sdmmc_err_t sdmmc_mmc_decode_cid(int mmc_ver, sdmmc_response_t resp, sdmmc_cid_t* out_cid); -sdmmc_err_t sdmmc_mmc_decode_csd(sdmmc_response_t response, sdmmc_csd_t* out_csd); -sdmmc_err_t sdmmc_mmc_enable_hs_mode(sdmmc_card_t* card); - -/* Parts of card initialization flow */ -sdmmc_err_t sdmmc_init_sd_if_cond(sdmmc_card_t* card); -sdmmc_err_t sdmmc_init_select_card(sdmmc_card_t* card); -sdmmc_err_t sdmmc_init_csd(sdmmc_card_t* card); -sdmmc_err_t sdmmc_init_cid(sdmmc_card_t* card); -sdmmc_err_t sdmmc_init_rca(sdmmc_card_t* card); -sdmmc_err_t sdmmc_init_mmc_decode_cid(sdmmc_card_t* card); -sdmmc_err_t sdmmc_init_ocr(sdmmc_card_t* card); -sdmmc_err_t sdmmc_init_spi_crc(sdmmc_card_t* card); -sdmmc_err_t sdmmc_init_io(sdmmc_card_t* card); -sdmmc_err_t sdmmc_init_sd_blocklen(sdmmc_card_t* card); -sdmmc_err_t sdmmc_init_sd_scr(sdmmc_card_t* card); -sdmmc_err_t sdmmc_init_sd_wait_data_ready(sdmmc_card_t* card); -sdmmc_err_t sdmmc_init_mmc_read_ext_csd(sdmmc_card_t* card); -sdmmc_err_t sdmmc_init_mmc_read_cid(sdmmc_card_t* card); -sdmmc_err_t sdmmc_init_host_bus_width(sdmmc_card_t* card); -sdmmc_err_t sdmmc_init_sd_bus_width(sdmmc_card_t* card); -sdmmc_err_t sdmmc_init_io_bus_width(sdmmc_card_t* card); -sdmmc_err_t sdmmc_init_mmc_bus_width(sdmmc_card_t* card); -sdmmc_err_t sdmmc_init_card_hs_mode(sdmmc_card_t* card); -sdmmc_err_t sdmmc_init_host_frequency(sdmmc_card_t* card); -sdmmc_err_t sdmmc_init_mmc_check_csd(sdmmc_card_t* card); - -/* Various helper functions */ -static inline bool host_is_spi(const sdmmc_card_t* card) -{ - return (card->host.flags & SDMMC_HOST_FLAG_SPI) != 0; -} - -static inline bool host_support_sdio(const sdmmc_card_t* card) -{ - return (card->host.flags & SDMMC_HOST_FLAG_SDIO) != 0; -} - -static inline uint32_t get_host_ocr(float voltage) -{ - // TODO: report exact voltage to the card - // For now tell that the host has 2.8-3.6V voltage range - (void) voltage; - return SD_OCR_VOL_MASK; -} - -void sdmmc_flip_byte_order(uint32_t* response, size_t size); - -sdmmc_err_t sdmmc_fix_host_flags(sdmmc_card_t *card); - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/third-party/sdmmc-1.0/inc/sdmmc_defs.h b/third-party/sdmmc-1.0/inc/sdmmc_defs.h deleted file mode 100644 index 603d5209..00000000 --- a/third-party/sdmmc-1.0/inc/sdmmc_defs.h +++ /dev/null @@ -1,492 +0,0 @@ -/* - * Copyright (c) 2006 Uwe Stuehler - * Adaptations to ESP-IDF Copyright (c) 2016 Espressif Systems (Shanghai) PTE LTD - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _SDMMC_DEFS_H_ -#define _SDMMC_DEFS_H_ - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include -#include - -/* MMC commands */ /* response type */ -#define MMC_GO_IDLE_STATE 0 /* R0 */ -#define MMC_SEND_OP_COND 1 /* R3 */ -#define MMC_ALL_SEND_CID 2 /* R2 */ -#define MMC_SET_RELATIVE_ADDR 3 /* R1 */ -#define MMC_SWITCH 6 /* R1B */ -#define MMC_SELECT_CARD 7 /* R1 */ -#define MMC_SEND_EXT_CSD 8 /* R1 */ -#define MMC_SEND_CSD 9 /* R2 */ -#define MMC_SEND_CID 10 /* R1 */ -#define MMC_READ_DAT_UNTIL_STOP 11 /* R1 */ -#define MMC_STOP_TRANSMISSION 12 /* R1B */ -#define MMC_SEND_STATUS 13 /* R1 */ -#define MMC_SET_BLOCKLEN 16 /* R1 */ -#define MMC_READ_BLOCK_SINGLE 17 /* R1 */ -#define MMC_READ_BLOCK_MULTIPLE 18 /* R1 */ -#define MMC_WRITE_DAT_UNTIL_STOP 20 /* R1 */ -#define MMC_SET_BLOCK_COUNT 23 /* R1 */ -#define MMC_WRITE_BLOCK_SINGLE 24 /* R1 */ -#define MMC_WRITE_BLOCK_MULTIPLE 25 /* R1 */ -#define MMC_APP_CMD 55 /* R1 */ - -/* SD commands */ /* response type */ -#define SD_SEND_RELATIVE_ADDR 3 /* R6 */ -#define SD_SEND_SWITCH_FUNC 6 /* R1 */ -#define SD_SEND_IF_COND 8 /* R7 */ -#define SD_READ_OCR 58 /* R3 */ -#define SD_CRC_ON_OFF 59 /* R1 */ - -/* SD application commands */ /* response type */ -#define SD_APP_SET_BUS_WIDTH 6 /* R1 */ -#define SD_APP_SD_STATUS 13 /* R2 */ -#define SD_APP_OP_COND 41 /* R3 */ -#define SD_APP_SEND_SCR 51 /* R1 */ - -/* SD IO commands */ -#define SD_IO_SEND_OP_COND 5 /* R4 */ -#define SD_IO_RW_DIRECT 52 /* R5 */ -#define SD_IO_RW_EXTENDED 53 /* R5 */ - -/* OCR bits */ -#define MMC_OCR_MEM_READY (1 << 31) /* memory power-up status bit */ -#define MMC_OCR_ACCESS_MODE_MASK 0x60000000 /* bits 30:29 */ -#define MMC_OCR_SECTOR_MODE (1 << 30) -#define MMC_OCR_BYTE_MODE (1 << 29) -#define MMC_OCR_3_5V_3_6V (1 << 23) -#define MMC_OCR_3_4V_3_5V (1 << 22) -#define MMC_OCR_3_3V_3_4V (1 << 21) -#define MMC_OCR_3_2V_3_3V (1 << 20) -#define MMC_OCR_3_1V_3_2V (1 << 19) -#define MMC_OCR_3_0V_3_1V (1 << 18) -#define MMC_OCR_2_9V_3_0V (1 << 17) -#define MMC_OCR_2_8V_2_9V (1 << 16) -#define MMC_OCR_2_7V_2_8V (1 << 15) -#define MMC_OCR_2_6V_2_7V (1 << 14) -#define MMC_OCR_2_5V_2_6V (1 << 13) -#define MMC_OCR_2_4V_2_5V (1 << 12) -#define MMC_OCR_2_3V_2_4V (1 << 11) -#define MMC_OCR_2_2V_2_3V (1 << 10) -#define MMC_OCR_2_1V_2_2V (1 << 9) -#define MMC_OCR_2_0V_2_1V (1 << 8) -#define MMC_OCR_1_65V_1_95V (1 << 7) - -#define SD_OCR_SDHC_CAP (1 << 30) -#define SD_OCR_VOL_MASK 0xFF8000 /* bits 23:15 */ - -/* SD mode R1 response type bits */ -#define MMC_R1_READY_FOR_DATA (1 << 8) /* ready for next transfer */ -#define MMC_R1_APP_CMD (1 << 5) /* app. commands supported */ -#define MMC_R1_SWITCH_ERROR (1 << 7) /* switch command did not succeed */ - -/* SPI mode R1 response type bits */ -#define SD_SPI_R1_IDLE_STATE (1 << 0) -#define SD_SPI_R1_ERASE_RST (1 << 1) -#define SD_SPI_R1_ILLEGAL_CMD (1 << 2) -#define SD_SPI_R1_CMD_CRC_ERR (1 << 3) -#define SD_SPI_R1_ERASE_SEQ_ERR (1 << 4) -#define SD_SPI_R1_ADDR_ERR (1 << 5) -#define SD_SPI_R1_PARAM_ERR (1 << 6) -#define SD_SPI_R1_NO_RESPONSE (1 << 7) - -#define SDIO_R1_FUNC_NUM_ERR (1 << 4) - -/* 48-bit response decoding (32 bits w/o CRC) */ -#define MMC_R1(resp) ((resp)[0]) -#define MMC_R3(resp) ((resp)[0]) -#define MMC_R4(resp) ((resp)[0]) -#define MMC_R5(resp) ((resp)[0]) -#define SD_R6(resp) ((resp)[0]) -#define MMC_R1_CURRENT_STATE(resp) (((resp)[0] >> 9) & 0xf) - -/* SPI mode response decoding */ -#define SD_SPI_R1(resp) ((resp)[0] & 0xff) -#define SD_SPI_R2(resp) ((resp)[0] & 0xffff) -#define SD_SPI_R3(resp) ((resp)[0]) -#define SD_SPI_R7(resp) ((resp)[0]) - -/* SPI mode data response decoding */ -#define SD_SPI_DATA_RSP_VALID(resp_byte) (((resp_byte)&0x11) == 0x1) -#define SD_SPI_DATA_RSP(resp_byte) (((resp_byte) >> 1) & 0x7) -#define SD_SPI_DATA_ACCEPTED 0x2 -#define SD_SPI_DATA_CRC_ERROR 0x5 -#define SD_SPI_DATA_WR_ERROR 0x6 - -/* RCA argument and response */ -#define MMC_ARG_RCA(rca) ((rca) << 16) -#define SD_R6_RCA(resp) (SD_R6((resp)) >> 16) - -/* bus width argument */ -#define SD_ARG_BUS_WIDTH_1 0 -#define SD_ARG_BUS_WIDTH_4 2 - -/* EXT_CSD fields */ -#define EXT_CSD_BUS_WIDTH 183 /* WO */ -#define EXT_CSD_HS_TIMING 185 /* R/W */ -#define EXT_CSD_REV 192 /* RO */ -#define EXT_CSD_STRUCTURE 194 /* RO */ -#define EXT_CSD_CARD_TYPE 196 /* RO */ -#define EXT_CSD_SEC_COUNT 212 /* RO */ -#define EXT_CSD_PWR_CL_26_360 203 /* RO */ -#define EXT_CSD_PWR_CL_52_360 202 /* RO */ -#define EXT_CSD_PWR_CL_26_195 201 /* RO */ -#define EXT_CSD_PWR_CL_52_195 200 /* RO */ -#define EXT_CSD_POWER_CLASS 187 /* R/W */ -#define EXT_CSD_CMD_SET 191 /* R/W */ -#define EXT_CSD_S_CMD_SET 504 /* RO */ - -/* EXT_CSD field definitions */ -#define EXT_CSD_CMD_SET_NORMAL (1U << 0) -#define EXT_CSD_CMD_SET_SECURE (1U << 1) -#define EXT_CSD_CMD_SET_CPSECURE (1U << 2) - -/* EXT_CSD_HS_TIMING */ -#define EXT_CSD_HS_TIMING_BC 0 -#define EXT_CSD_HS_TIMING_HS 1 -#define EXT_CSD_HS_TIMING_HS200 2 -#define EXT_CSD_HS_TIMING_HS400 3 - -/* EXT_CSD_BUS_WIDTH */ -#define EXT_CSD_BUS_WIDTH_1 0 -#define EXT_CSD_BUS_WIDTH_4 1 -#define EXT_CSD_BUS_WIDTH_8 2 -#define EXT_CSD_BUS_WIDTH_4_DDR 5 -#define EXT_CSD_BUS_WIDTH_8_DDR 6 - -/* EXT_CSD_CARD_TYPE */ -/* The only currently valid values for this field are 0x01, 0x03, 0x07, - * 0x0B and 0x0F. */ -#define EXT_CSD_CARD_TYPE_F_26M (1 << 0) /* SDR at "rated voltages */ -#define EXT_CSD_CARD_TYPE_F_52M (1 << 1) /* SDR at "rated voltages */ -#define EXT_CSD_CARD_TYPE_F_52M_1_8V (1 << 2) /* DDR, 1.8V or 3.3V I/O */ -#define EXT_CSD_CARD_TYPE_F_52M_1_2V (1 << 3) /* DDR, 1.2V I/O */ -#define EXT_CSD_CARD_TYPE_26M 0x01 -#define EXT_CSD_CARD_TYPE_52M 0x03 -#define EXT_CSD_CARD_TYPE_52M_V18 0x07 -#define EXT_CSD_CARD_TYPE_52M_V12 0x0b -#define EXT_CSD_CARD_TYPE_52M_V12_18 0x0f - -/* EXT_CSD MMC */ -#define EXT_CSD_MMC_SIZE 512 - -/* MMC_SWITCH access mode */ -#define MMC_SWITCH_MODE_CMD_SET 0x00 /* Change the command set */ -#define MMC_SWITCH_MODE_SET_BITS 0x01 /* Set bits in value */ -#define MMC_SWITCH_MODE_CLEAR_BITS 0x02 /* Clear bits in value */ -#define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target to value */ - -/* MMC R2 response (CSD) */ -#define MMC_CSD_CSDVER(resp) MMC_RSP_BITS((resp), 126, 2) -#define MMC_CSD_CSDVER_1_0 1 -#define MMC_CSD_CSDVER_2_0 2 -#define MMC_CSD_CSDVER_EXT_CSD 3 -#define MMC_CSD_MMCVER(resp) MMC_RSP_BITS((resp), 122, 4) -#define MMC_CSD_MMCVER_1_0 0 /* MMC 1.0 - 1.2 */ -#define MMC_CSD_MMCVER_1_4 1 /* MMC 1.4 */ -#define MMC_CSD_MMCVER_2_0 2 /* MMC 2.0 - 2.2 */ -#define MMC_CSD_MMCVER_3_1 3 /* MMC 3.1 - 3.3 */ -#define MMC_CSD_MMCVER_4_0 4 /* MMC 4 */ -#define MMC_CSD_READ_BL_LEN(resp) MMC_RSP_BITS((resp), 80, 4) -#define MMC_CSD_C_SIZE(resp) MMC_RSP_BITS((resp), 62, 12) -#define MMC_CSD_CAPACITY(resp) ((MMC_CSD_C_SIZE((resp)) + 1) << (MMC_CSD_C_SIZE_MULT((resp)) + 2)) -#define MMC_CSD_C_SIZE_MULT(resp) MMC_RSP_BITS((resp), 47, 3) - -/* MMC v1 R2 response (CID) */ -#define MMC_CID_MID_V1(resp) MMC_RSP_BITS((resp), 104, 24) -#define MMC_CID_PNM_V1_CPY(resp, pnm) \ - do \ - { \ - (pnm)[0] = MMC_RSP_BITS((resp), 96, 8); \ - (pnm)[1] = MMC_RSP_BITS((resp), 88, 8); \ - (pnm)[2] = MMC_RSP_BITS((resp), 80, 8); \ - (pnm)[3] = MMC_RSP_BITS((resp), 72, 8); \ - (pnm)[4] = MMC_RSP_BITS((resp), 64, 8); \ - (pnm)[5] = MMC_RSP_BITS((resp), 56, 8); \ - (pnm)[6] = MMC_RSP_BITS((resp), 48, 8); \ - (pnm)[7] = '\0'; \ - } while (0) -#define MMC_CID_REV_V1(resp) MMC_RSP_BITS((resp), 40, 8) -#define MMC_CID_PSN_V1(resp) MMC_RSP_BITS((resp), 16, 24) -#define MMC_CID_MDT_V1(resp) MMC_RSP_BITS((resp), 8, 8) - -/* MMC v2 R2 response (CID) */ -#define MMC_CID_MID_V2(resp) MMC_RSP_BITS((resp), 120, 8) -#define MMC_CID_OID_V2(resp) MMC_RSP_BITS((resp), 104, 16) -#define MMC_CID_PNM_V2_CPY(resp, pnm) \ - do \ - { \ - (pnm)[0] = MMC_RSP_BITS((resp), 96, 8); \ - (pnm)[1] = MMC_RSP_BITS((resp), 88, 8); \ - (pnm)[2] = MMC_RSP_BITS((resp), 80, 8); \ - (pnm)[3] = MMC_RSP_BITS((resp), 72, 8); \ - (pnm)[4] = MMC_RSP_BITS((resp), 64, 8); \ - (pnm)[5] = MMC_RSP_BITS((resp), 56, 8); \ - (pnm)[6] = '\0'; \ - } while (0) -#define MMC_CID_PSN_V2(resp) MMC_RSP_BITS((resp), 16, 32) - -/* SD R2 response (CSD) */ -#define SD_CSD_CSDVER(resp) MMC_RSP_BITS((resp), 126, 2) -#define SD_CSD_CSDVER_1_0 0 -#define SD_CSD_CSDVER_2_0 1 -#define SD_CSD_TAAC(resp) MMC_RSP_BITS((resp), 112, 8) -#define SD_CSD_TAAC_1_5_MSEC 0x26 -#define SD_CSD_NSAC(resp) MMC_RSP_BITS((resp), 104, 8) -#define SD_CSD_SPEED(resp) MMC_RSP_BITS((resp), 96, 8) -#define SD_CSD_SPEED_25_MHZ 0x32 -#define SD_CSD_SPEED_50_MHZ 0x5a -#define SD_CSD_CCC(resp) MMC_RSP_BITS((resp), 84, 12) -#define SD_CSD_CCC_BASIC (1 << 0) /* basic */ -#define SD_CSD_CCC_BR (1 << 2) /* block read */ -#define SD_CSD_CCC_BW (1 << 4) /* block write */ -#define SD_CSD_CCC_ERASE (1 << 5) /* erase */ -#define SD_CSD_CCC_WP (1 << 6) /* write protection */ -#define SD_CSD_CCC_LC (1 << 7) /* lock card */ -#define SD_CSD_CCC_AS (1 << 8) /*application specific*/ -#define SD_CSD_CCC_IOM (1 << 9) /* I/O mode */ -#define SD_CSD_CCC_SWITCH (1 << 10) /* switch */ -#define SD_CSD_READ_BL_LEN(resp) MMC_RSP_BITS((resp), 80, 4) -#define SD_CSD_READ_BL_PARTIAL(resp) MMC_RSP_BITS((resp), 79, 1) -#define SD_CSD_WRITE_BLK_MISALIGN(resp) MMC_RSP_BITS((resp), 78, 1) -#define SD_CSD_READ_BLK_MISALIGN(resp) MMC_RSP_BITS((resp), 77, 1) -#define SD_CSD_DSR_IMP(resp) MMC_RSP_BITS((resp), 76, 1) -#define SD_CSD_C_SIZE(resp) MMC_RSP_BITS((resp), 62, 12) -#define SD_CSD_CAPACITY(resp) ((SD_CSD_C_SIZE((resp)) + 1) << (SD_CSD_C_SIZE_MULT((resp)) + 2)) -#define SD_CSD_V2_C_SIZE(resp) MMC_RSP_BITS((resp), 48, 22) -#define SD_CSD_V2_CAPACITY(resp) ((SD_CSD_V2_C_SIZE((resp)) + 1) << 10) -#define SD_CSD_V2_BL_LEN 0x9 /* 512 */ -#define SD_CSD_VDD_R_CURR_MIN(resp) MMC_RSP_BITS((resp), 59, 3) -#define SD_CSD_VDD_R_CURR_MAX(resp) MMC_RSP_BITS((resp), 56, 3) -#define SD_CSD_VDD_W_CURR_MIN(resp) MMC_RSP_BITS((resp), 53, 3) -#define SD_CSD_VDD_W_CURR_MAX(resp) MMC_RSP_BITS((resp), 50, 3) -#define SD_CSD_VDD_RW_CURR_100mA 0x7 -#define SD_CSD_VDD_RW_CURR_80mA 0x6 -#define SD_CSD_C_SIZE_MULT(resp) MMC_RSP_BITS((resp), 47, 3) -#define SD_CSD_ERASE_BLK_EN(resp) MMC_RSP_BITS((resp), 46, 1) -#define SD_CSD_SECTOR_SIZE(resp) MMC_RSP_BITS((resp), 39, 7) /* +1 */ -#define SD_CSD_WP_GRP_SIZE(resp) MMC_RSP_BITS((resp), 32, 7) /* +1 */ -#define SD_CSD_WP_GRP_ENABLE(resp) MMC_RSP_BITS((resp), 31, 1) -#define SD_CSD_R2W_FACTOR(resp) MMC_RSP_BITS((resp), 26, 3) -#define SD_CSD_WRITE_BL_LEN(resp) MMC_RSP_BITS((resp), 22, 4) -#define SD_CSD_RW_BL_LEN_2G 0xa -#define SD_CSD_RW_BL_LEN_1G 0x9 -#define SD_CSD_WRITE_BL_PARTIAL(resp) MMC_RSP_BITS((resp), 21, 1) -#define SD_CSD_FILE_FORMAT_GRP(resp) MMC_RSP_BITS((resp), 15, 1) -#define SD_CSD_COPY(resp) MMC_RSP_BITS((resp), 14, 1) -#define SD_CSD_PERM_WRITE_PROTECT(resp) MMC_RSP_BITS((resp), 13, 1) -#define SD_CSD_TMP_WRITE_PROTECT(resp) MMC_RSP_BITS((resp), 12, 1) -#define SD_CSD_FILE_FORMAT(resp) MMC_RSP_BITS((resp), 10, 2) - -/* SD R2 response (CID) */ -#define SD_CID_MID(resp) MMC_RSP_BITS((resp), 120, 8) -#define SD_CID_OID(resp) MMC_RSP_BITS((resp), 104, 16) -#define SD_CID_PNM_CPY(resp, pnm) \ - do \ - { \ - (pnm)[0] = MMC_RSP_BITS((resp), 96, 8); \ - (pnm)[1] = MMC_RSP_BITS((resp), 88, 8); \ - (pnm)[2] = MMC_RSP_BITS((resp), 80, 8); \ - (pnm)[3] = MMC_RSP_BITS((resp), 72, 8); \ - (pnm)[4] = MMC_RSP_BITS((resp), 64, 8); \ - (pnm)[5] = '\0'; \ - } while (0) -#define SD_CID_REV(resp) MMC_RSP_BITS((resp), 56, 8) -#define SD_CID_PSN(resp) MMC_RSP_BITS((resp), 24, 32) -#define SD_CID_MDT(resp) MMC_RSP_BITS((resp), 8, 12) - -/* SCR (SD Configuration Register) */ -#define SCR_STRUCTURE(scr) MMC_RSP_BITS((scr), 60, 4) -#define SCR_STRUCTURE_VER_1_0 0 /* Version 1.0 */ -#define SCR_SD_SPEC(scr) MMC_RSP_BITS((scr), 56, 4) -#define SCR_SD_SPEC_VER_1_0 0 /* Version 1.0 and 1.01 */ -#define SCR_SD_SPEC_VER_1_10 1 /* Version 1.10 */ -#define SCR_SD_SPEC_VER_2 2 /* Version 2.00 or Version 3.0x */ -#define SCR_DATA_STAT_AFTER_ERASE(scr) MMC_RSP_BITS((scr), 55, 1) -#define SCR_SD_SECURITY(scr) MMC_RSP_BITS((scr), 52, 3) -#define SCR_SD_SECURITY_NONE 0 /* no security */ -#define SCR_SD_SECURITY_1_0 1 /* security protocol 1.0 */ -#define SCR_SD_SECURITY_1_0_2 2 /* security protocol 1.0 */ -#define SCR_SD_BUS_WIDTHS(scr) MMC_RSP_BITS((scr), 48, 4) -#define SCR_SD_BUS_WIDTHS_1BIT (1 << 0) /* 1bit (DAT0) */ -#define SCR_SD_BUS_WIDTHS_4BIT (1 << 2) /* 4bit (DAT0-3) */ -#define SCR_SD_SPEC3(scr) MMC_RSP_BITS((scr), 47, 1) -#define SCR_EX_SECURITY(scr) MMC_RSP_BITS((scr), 43, 4) -#define SCR_SD_SPEC4(scr) MMC_RSP_BITS((scr), 42, 1) -#define SCR_RESERVED(scr) MMC_RSP_BITS((scr), 34, 8) -#define SCR_CMD_SUPPORT_CMD23(scr) MMC_RSP_BITS((scr), 33, 1) -#define SCR_CMD_SUPPORT_CMD20(scr) MMC_RSP_BITS((scr), 32, 1) -#define SCR_RESERVED2(scr) MMC_RSP_BITS((scr), 0, 32) - -/* Max supply current in SWITCH_FUNC response (in mA) */ -#define SD_SFUNC_I_MAX(status) (MMC_RSP_BITS((uint32_t *)(status), 496, 16)) - -/* Supported flags in SWITCH_FUNC response */ -#define SD_SFUNC_SUPPORTED(status, group) \ - (MMC_RSP_BITS((uint32_t *)(status), 400 + (group - 1) * 16, 16)) - -/* Selected function in SWITCH_FUNC response */ -#define SD_SFUNC_SELECTED(status, group) \ - (MMC_RSP_BITS((uint32_t *)(status), 376 + (group - 1) * 4, 4)) - -/* Busy flags in SWITCH_FUNC response */ -#define SD_SFUNC_BUSY(status, group) \ - (MMC_RSP_BITS((uint32_t *)(status), 272 + (group - 1) * 16, 16)) - -/* Version of SWITCH_FUNC response */ -#define SD_SFUNC_VER(status) (MMC_RSP_BITS((uint32_t *)(status), 368, 8)) - -#define SD_SFUNC_GROUP_MAX 6 -#define SD_SFUNC_FUNC_MAX 15 - -#define SD_ACCESS_MODE 1 /* Function group 1, Access Mode */ - -#define SD_ACCESS_MODE_SDR12 0 /* 25 MHz clock */ -#define SD_ACCESS_MODE_SDR25 1 /* 50 MHz clock */ -#define SD_ACCESS_MODE_SDR50 2 /* UHS-I, 100 MHz clock */ -#define SD_ACCESS_MODE_SDR104 3 /* UHS-I, 208 MHz clock */ -#define SD_ACCESS_MODE_DDR50 4 /* UHS-I, 50 MHz clock, DDR */ - -/** - * @brief Extract up to 32 sequential bits from an array of 32-bit words - * - * Bits within the word are numbered in the increasing order from LSB to MSB. - * - * As an example, consider 2 32-bit words: - * - * 0x01234567 0x89abcdef - * - * On a little-endian system, the bytes are stored in memory as follows: - * - * 67 45 23 01 ef cd ab 89 - * - * MMC_RSP_BITS will extact bits as follows: - * - * start=0 len=4 -> result=0x00000007 - * start=0 len=12 -> result=0x00000567 - * start=28 len=8 -> result=0x000000f0 - * start=59 len=5 -> result=0x00000011 - * - * @param src array of words to extract bits from - * @param start index of the first bit to extract - * @param len number of bits to extract, 1 to 32 - * @return 32-bit word where requested bits start from LSB - */ -static inline uint32_t MMC_RSP_BITS(uint32_t *src, int start, int len) -{ - uint32_t mask = (len % 32 == 0) ? UINT_MAX : UINT_MAX >> (32 - (len % 32)); - size_t word = start / 32; - size_t shift = start % 32; - uint32_t right = src[word] >> shift; - uint32_t left = (len + shift <= 32) ? 0 : src[word + 1] << ((32 - shift) % 32); - return (left | right) & mask; -} - -/* SD R4 response (IO OCR) */ -#define SD_IO_OCR_MEM_READY (1 << 31) -#define SD_IO_OCR_NUM_FUNCTIONS(ocr) (((ocr) >> 28) & 0x7) -#define SD_IO_OCR_MEM_PRESENT (1 << 27) -#define SD_IO_OCR_MASK 0x00fffff0 - -/* CMD52 arguments */ -#define SD_ARG_CMD52_READ (0 << 31) -#define SD_ARG_CMD52_WRITE (1 << 31) -#define SD_ARG_CMD52_FUNC_SHIFT 28 -#define SD_ARG_CMD52_FUNC_MASK 0x7 -#define SD_ARG_CMD52_EXCHANGE (1 << 27) -#define SD_ARG_CMD52_REG_SHIFT 9 -#define SD_ARG_CMD52_REG_MASK 0x1ffff -#define SD_ARG_CMD52_DATA_SHIFT 0 -#define SD_ARG_CMD52_DATA_MASK 0xff -#define SD_R5_DATA(resp) ((resp)[0] & 0xff) - -/* CMD53 arguments */ -#define SD_ARG_CMD53_READ (0 << 31) -#define SD_ARG_CMD53_WRITE (1 << 31) -#define SD_ARG_CMD53_FUNC_SHIFT 28 -#define SD_ARG_CMD53_FUNC_MASK 0x7 -#define SD_ARG_CMD53_BLOCK_MODE (1 << 27) -#define SD_ARG_CMD53_INCREMENT (1 << 26) -#define SD_ARG_CMD53_REG_SHIFT 9 -#define SD_ARG_CMD53_REG_MASK 0x1ffff -#define SD_ARG_CMD53_LENGTH_SHIFT 0 -#define SD_ARG_CMD53_LENGTH_MASK 0x1ff -#define SD_ARG_CMD53_LENGTH_MAX 512 - -/* Card Common Control Registers (CCCR) */ -#define SD_IO_CCCR_START 0x00000 -#define SD_IO_CCCR_SIZE 0x100 -#define SD_IO_CCCR_FN_ENABLE 0x02 -#define SD_IO_CCCR_FN_READY 0x03 -#define SD_IO_CCCR_INT_ENABLE 0x04 -#define SD_IO_CCCR_INT_PENDING 0x05 -#define SD_IO_CCCR_CTL 0x06 -#define CCCR_CTL_RES (1 << 3) -#define SD_IO_CCCR_BUS_WIDTH 0x07 -#define CCCR_BUS_WIDTH_1 (0 << 0) -#define CCCR_BUS_WIDTH_4 (2 << 0) -#define CCCR_BUS_WIDTH_8 (3 << 0) -#define CCCR_BUS_WIDTH_ECSI (1 << 5) -#define SD_IO_CCCR_CARD_CAP 0x08 -#define CCCR_CARD_CAP_LSC BIT(6) -#define CCCR_CARD_CAP_4BLS BIT(7) -#define SD_IO_CCCR_CISPTR 0x09 -#define SD_IO_CCCR_BLKSIZEL 0x10 -#define SD_IO_CCCR_BLKSIZEH 0x11 -#define SD_IO_CCCR_HIGHSPEED 0x13 -#define CCCR_HIGHSPEED_SUPPORT BIT(0) -#define CCCR_HIGHSPEED_ENABLE BIT(1) - -/* Function Basic Registers (FBR) */ -#define SD_IO_FBR_START 0x00100 -#define SD_IO_FBR_SIZE 0x00700 - -/* Card Information Structure (CIS) */ -#define SD_IO_CIS_START 0x01000 -#define SD_IO_CIS_SIZE 0x17000 - -/* CIS tuple codes (based on PC Card 16) */ -#define CISTPL_CODE_NULL 0x00 -#define CISTPL_CODE_DEVICE 0x01 -#define CISTPL_CODE_CHKSUM 0x10 -#define CISTPL_CODE_VERS1 0x15 -#define CISTPL_CODE_ALTSTR 0x16 -#define CISTPL_CODE_CONFIG 0x1A -#define CISTPL_CODE_CFTABLE_ENTRY 0x1B -#define CISTPL_CODE_MANFID 0x20 -#define CISTPL_CODE_FUNCID 0x21 -#define TPLFID_FUNCTION_SDIO 0x0c -#define CISTPL_CODE_FUNCE 0x22 -#define CISTPL_CODE_VENDER_BEGIN 0x80 -#define CISTPL_CODE_VENDER_END 0x8F -#define CISTPL_CODE_SDIO_STD 0x91 -#define CISTPL_CODE_SDIO_EXT 0x92 -#define CISTPL_CODE_END 0xFF - -/* Timing */ -#define SDMMC_TIMING_LEGACY 0 -#define SDMMC_TIMING_HIGHSPEED 1 -#define SDMMC_TIMING_MMC_DDR52 2 - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/third-party/sdmmc-1.0/inc/sdmmc_types.h b/third-party/sdmmc-1.0/inc/sdmmc_types.h deleted file mode 100644 index c199d6e1..00000000 --- a/third-party/sdmmc-1.0/inc/sdmmc_types.h +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (c) 2006 Uwe Stuehler - * Adaptations to ESP-IDF Copyright (c) 2016 Espressif Systems (Shanghai) PTE LTD - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _SDMMC_TYPES_H_ -#define _SDMMC_TYPES_H_ - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include -#include - -#include "sdmmc_port.h" - -/* Definitions for error constants. */ -#define SDMMC_OK 0 /* sdmmc_err_t value indicating success (no error) */ -#define SDMMC_FAIL -1 /* Generic sdmmc_err_t code indicating failure */ - -#define SDMMC_ERR_NO_MEM 0x101 /* Out of memory */ -#define SDMMC_ERR_INVALID_ARG 0x102 /* Invalid argument */ -#define SDMMC_ERR_INVALID_STATE 0x103 /* Invalid state */ -#define SDMMC_ERR_INVALID_SIZE 0x104 /* Invalid size */ -#define SDMMC_ERR_NOT_FOUND 0x105 /* Requested resource not found */ -#define SDMMC_ERR_NOT_SUPPORTED 0x106 /* Operation or feature not supported */ -#define SDMMC_ERR_TIMEOUT 0x107 /* Operation timed out */ -#define SDMMC_ERR_INVALID_RESPONSE 0x108 /* Received response was invalid */ -#define SDMMC_ERR_INVALID_CRC 0x109 /* CRC or checksum was invalid */ -#define SDMMC_ERR_INVALID_VERSION 0x10A /* Version was invalid */ -#define SDMMC_ERR_INVALID_MAC 0x10B /* MAC address was invalid */ -#define SDMMC_ERR_SEND_CMD_FAILED 0x10C /* Send command failed */ -#define SDMMC_ERR_NOT_READY 0x10D /* Host not ready */ - -/** - * Decoded values from SD card Card Specific Data register - */ -typedef struct { - int csd_ver; /* CSD structure format */ - int mmc_ver; /* MMC version (for CID format) */ - int capacity; /* total number of sectors */ - int sector_size; /* sector size in bytes */ - int read_block_len; /* block length for reads */ - int card_command_class; /* Card Command Class for SD */ - int tr_speed; /* Max transfer speed */ -} sdmmc_csd_t; - -/** - * Decoded values from SD card Card IDentification register - */ -typedef struct { - int mfg_id; /* manufacturer identification number */ - int oem_id; /* OEM/product identification number */ - char name[8]; /* product name (MMC v1 has the longest) */ - int revision; /* product revision */ - int serial; /* product serial number */ - int date; /* manufacturing date */ -} sdmmc_cid_t; - -/** - * Decoded values from SD Configuration Register - */ -typedef struct { - int sd_spec; /* SD Physical layer specification version, reported by card */ - int bus_width; /* bus widths supported by card: BIT(0) — 1-bit bus, BIT(2) — 4-bit bus */ -} sdmmc_scr_t; - -/** - * Decoded values of Extended Card Specific Data - */ -typedef struct { - uint8_t power_class; /* Power class used by the card */ -} sdmmc_ext_csd_t; - -/** - * SD/MMC command response buffer - */ -typedef uint32_t sdmmc_response_t[4]; - -/** - * SD SWITCH_FUNC response buffer - */ -typedef struct { - uint32_t data[512 / 8 / sizeof(uint32_t)]; /* response data */ -} sdmmc_switch_func_rsp_t; - -/** - * SD/MMC command information - */ -typedef struct { - uint32_t opcode; /* SD or MMC command index */ - uint32_t arg; /* SD/MMC command argument */ - sdmmc_response_t response; /* response buffer */ - void* data; /* buffer to send or read into */ - size_t datalen; /* length of data buffer */ - size_t blklen; /* block length */ - int flags; /* see below */ -/** @cond */ -#define SCF_ITSDONE 0x0001 /* command is complete */ -#define SCF_CMD(flags) ((flags) & 0x00f0) -#define SCF_CMD_AC 0x0000 -#define SCF_CMD_ADTC 0x0010 -#define SCF_CMD_BC 0x0020 -#define SCF_CMD_BCR 0x0030 -#define SCF_CMD_READ 0x0040 /* read command (data expected) */ -#define SCF_RSP_BSY 0x0100 -#define SCF_RSP_136 0x0200 -#define SCF_RSP_CRC 0x0400 -#define SCF_RSP_IDX 0x0800 -#define SCF_RSP_PRESENT 0x1000 -/* response types */ -#define SCF_RSP_R0 0 /* none */ -#define SCF_RSP_R1 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX) -#define SCF_RSP_R1B (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX|SCF_RSP_BSY) -#define SCF_RSP_R2 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_136) -#define SCF_RSP_R3 (SCF_RSP_PRESENT) -#define SCF_RSP_R4 (SCF_RSP_PRESENT) -#define SCF_RSP_R5 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX) -#define SCF_RSP_R5B (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX|SCF_RSP_BSY) -#define SCF_RSP_R6 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX) -#define SCF_RSP_R7 (SCF_RSP_PRESENT|SCF_RSP_CRC|SCF_RSP_IDX) -/* special flags */ -#define SCF_WAIT_BUSY 0x2000 /* Wait for completion of card busy signal before returning */ -/** @endcond */ - sdmmc_err_t error; /* error returned from transfer */ - int timeout_ms; /* response timeout, in milliseconds */ -} sdmmc_command_t; - -/** - * SD/MMC Host description - * - * This structure defines properties of SD/MMC host and functions - * of SD/MMC host which can be used by upper layers. - */ -typedef struct { - uint32_t flags; /* flags defining host properties */ -#define SDMMC_HOST_FLAG_1BIT BIT(0) /* host supports 1-line SD and MMC protocol */ -#define SDMMC_HOST_FLAG_4BIT BIT(1) /* host supports 4-line SD and MMC protocol */ -#define SDMMC_HOST_FLAG_8BIT BIT(2) /* host supports 8-line MMC protocol */ -#define SDMMC_HOST_FLAG_SPI BIT(3) /* host supports SPI protocol */ -#define SDMMC_HOST_FLAG_DDR BIT(4) /* host supports DDR mode for SD/MMC */ -#define SDMMC_HOST_FLAG_DEINIT_ARG BIT(5) /* host `deinit` function called with the slot argument */ -#define SDMMC_HOST_FLAG_SDIO BIT(6) /* host supports SDIO */ - int slot; /* slot number, to be passed to host functions */ - int max_freq_khz; /* max frequency supported by the host */ -#define SDMMC_FREQ_DEFAULT 20000 /* SD/MMC Default speed (limited by clock divider) */ -#define SDMMC_FREQ_HIGHSPEED 40000 /* SD High speed (limited by clock divider) */ -#define SDMMC_FREQ_PROBING 400 /* SD/MMC probing speed */ -#define SDMMC_FREQ_52M 52000 /* MMC 52MHz speed */ -#define SDMMC_FREQ_25M 25000 -#define SDMMC_FREQ_26M 26000 /* MMC 26MHz speed */ -#define SDMMC_FREQ_50M 50000 /* SD/MMC 50MHz high speed */ - float io_voltage; /* I/O voltage used by the controller (voltage switching is not supported) */ - sdmmc_err_t (*init)(int slot); /* Host function to initialize the driver */ - sdmmc_err_t (*set_bus_width)(int slot, size_t width); /* host function to set bus width */ - size_t (*get_bus_width)(int slot); /* host function to get bus width */ - sdmmc_err_t (*set_bus_ddr_mode)(int slot, bool ddr_enable); /* host function to set DDR mode */ - sdmmc_err_t (*set_card_clk)(int slot, uint32_t freq_khz); /* host function to set card clock frequency */ - sdmmc_err_t (*do_transaction)(int slot, sdmmc_command_t* cmdinfo); /* host function to do a transaction */ - union { - sdmmc_err_t (*deinit)(void); /* host function to deinitialize the driver */ - sdmmc_err_t (*deinit_p)(int slot); /* host function to deinitialize the driver, called with the `slot` */ - }; - sdmmc_err_t (*io_int_enable)(int slot); /* Host function to enable SDIO interrupt line */ - sdmmc_err_t (*io_int_wait)(int slot, TickType_t timeout_ticks); /* Host function to wait for SDIO interrupt line to be active */ - int command_timeout_ms; /* timeout, in milliseconds, of a single command. Set to 0 to use the default value. */ -} sdmmc_host_t; - -/** - * SD/MMC card information structure - */ -typedef struct { - sdmmc_host_t host; /* Host with which the card is associated */ - uint32_t ocr; /* OCR (Operation Conditions Register) value */ - union { - sdmmc_cid_t cid; /* decoded CID (Card IDentification) register value */ - sdmmc_response_t raw_cid; /* raw CID of MMC card to be decoded - after the CSD is fetched in the data transfer mode*/ - }; - sdmmc_csd_t csd; /* decoded CSD (Card-Specific Data) register value */ - sdmmc_scr_t scr; /* decoded SCR (SD card Configuration Register) value */ - sdmmc_ext_csd_t ext_csd; /* decoded EXT_CSD (Extended Card Specific Data) register value */ - uint16_t rca; /* RCA (Relative Card Address) */ - uint16_t max_freq_khz; /* Maximum frequency, in kHz, supported by the card */ - uint32_t is_mem : 1; /* Bit indicates if the card is a memory card */ - uint32_t is_sdio : 1; /* Bit indicates if the card is an IO card */ - uint32_t is_mmc : 1; /* Bit indicates if the card is MMC */ - uint32_t num_io_functions : 3; /* If is_sdio is 1, contains the number of IO functions on the card */ - uint32_t log_bus_width : 2; /* log2(bus width supported by card) */ - uint32_t is_ddr : 1; /* Card supports DDR mode */ - uint32_t reserved : 23; /* Reserved for future expansion */ -} sdmmc_card_t; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/third-party/sdmmc-1.0/osal/sdmmc_system.c b/third-party/sdmmc-1.0/osal/sdmmc_system.c new file mode 100644 index 00000000..f07e8799 --- /dev/null +++ b/third-party/sdmmc-1.0/osal/sdmmc_system.c @@ -0,0 +1,95 @@ + +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: sdmmc_system.c + * Date: 2022-02-10 14:53:44 + * LastEditTime: 2022-02-25 11:47:44 + * Description:  This files is for sdmmc baremetal port + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2022/11/15 first release + */ +#include + +#include +#include "fmemory_pool.h" + +#include "sdmmc_system.h" + +#define SDMMC_MEM_BUF_SIZE SZ_1M +#define SDMMC_ALIGNMENT 64U +#define SDMMC_256_ALIGNMENT 256U + +static u8 sdmmc_buf[SDMMC_MEM_BUF_SIZE] = {0}; +static FMemp sdmmc_mem_pool; + +void sdmmc_sys_init(void) +{ + memset(&sdmmc_mem_pool, 0, sizeof(sdmmc_mem_pool)); + + FError result = FMempInit(&sdmmc_mem_pool, sdmmc_buf, sdmmc_buf + SDMMC_MEM_BUF_SIZE); /* init memory pool */ + SDMMC_ASSERT(result == FMEMP_SUCCESS); +} + +void sdmmc_sys_deinit(void) +{ + FASSERT(FT_COMPONENT_IS_READY == sdmmc_mem_pool.is_ready); + FMempDeinit(&sdmmc_mem_pool); +} + +void sdmmc_sys_delay_ms(uint32_t msecs) +{ + vTaskDelay(pdMS_TO_TICKS(msecs)); +} + +void *sdmmc_sys_heap_caps_malloc(size_t size, uint32_t caps) +{ + void *ptr = NULL; + FASSERT(FT_COMPONENT_IS_READY == sdmmc_mem_pool.is_ready); + + if (caps & MALLOC_8_ALIGN) + { + ptr = FMempMallocAlign(&sdmmc_mem_pool, size, 8); /* allocate alligned memory for DMA access */ + } + else if (caps & MALLOC_32_ALIGN) + { + ptr = FMempMallocAlign(&sdmmc_mem_pool, size, 32); + } + else if (caps & MALLOC_64_ALIGN) + { + ptr = FMempMallocAlign(&sdmmc_mem_pool, size, 64); + } + else if (caps & MALLOC_256_ALIGN) + { + ptr = FMempMallocAlign(&sdmmc_mem_pool, size, 256); + } + else if (caps & MALLOC_512_ALIGN) + { + ptr = FMempMallocAlign(&sdmmc_mem_pool, size, 512); + } + else + { + ptr = FMempCalloc(&sdmmc_mem_pool, 1, size); + } + + return ptr; +} + +void sdmmc_sys_free(void *ptr) +{ + FASSERT(FT_COMPONENT_IS_READY == sdmmc_mem_pool.is_ready); + FMempFree(&sdmmc_mem_pool, ptr); +} \ No newline at end of file diff --git a/third-party/sdmmc-1.0/port/fsdio/sdmmc_port.h b/third-party/sdmmc-1.0/osal/sdmmc_system.h similarity index 53% rename from third-party/sdmmc-1.0/port/fsdio/sdmmc_port.h rename to third-party/sdmmc-1.0/osal/sdmmc_system.h index a49b057b..8ab15c91 100644 --- a/third-party/sdmmc-1.0/port/fsdio/sdmmc_port.h +++ b/third-party/sdmmc-1.0/osal/sdmmc_system.h @@ -11,47 +11,65 @@ * See the Phytium Public License for more details. * * - * FilePath: sdmmc_port.h - * Date: 2022-07-25 09:58:09 - * LastEditTime: 2022-07-25 09:58:09 - * Description:  This files is for + * FilePath: sdmmc_system.h + * Date: 2022-02-10 14:53:44 + * LastEditTime: 2022-02-25 11:46:22 + * Description:  This files is for sdmmc baremetal port * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2022/11/15 first release */ -#ifndef THIRD_PARTY_SDMMC_PORT_H -#define THIRD_PARTY_SDMMC_PORT_H + +#ifndef SDMMC_SYSTEM_H +#define SDMMC_SYSTEM_H #ifdef __cplusplus extern "C" { #endif -/***************************** Include Files *********************************/ -#include - #include "ftypes.h" -#include "fsleep.h" -#include "fkernel.h" #include "fassert.h" #include "fdebug.h" +#include "fprintf.h" -/************************** Constant Definitions *****************************/ -#define true TRUE -#define false FALSE +/* Definitions for portable marco. */ +#ifdef BIT +#undef BIT +#endif +#define BIT(x) (1U << (x)) -/**************************** Type Definitions *******************************/ -typedef s32 sdmmc_err_t; -typedef boolean bool; +#ifndef MAX +#undef MAX +#endif +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) -/************************** Variable Definitions *****************************/ +#ifndef MIN +#undef MIN +#endif +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -/***************** Macros (Inline Functions) Definitions *********************/ -#define SDMMC_DELAY(m) fsleep_microsec(m) #define SDMMC_ASSERT(a) FASSERT(a) #define WORD_ALIGNED_ATTR __attribute__((aligned(4))) -#define SDMMC_PTR_DMA_CAP(a) sdmmc_port_is_aligned_memory(a) +#define SDMMC_PTR_DMA_CAP(a) !((unsigned long)a % 512) +#define true TRUE +#define false FALSE +#define MALLOC_8_ALIGN (1U << 0) +#define MALLOC_32_ALIGN (1U << 1) +#define MALLOC_64_ALIGN (1U << 2) +#define MALLOC_256_ALIGN (1U << 3) +#define MALLOC_512_ALIGN (1U << 4) +#define MALLOC_CAP_DMA MALLOC_512_ALIGN +#define MALLOC_CAP_DESC MALLOC_256_ALIGN + +#define SDMMC_PRINTF printf + +/* Definitions for portable types. */ +typedef int sdmmc_err_t; +typedef int bool; +typedef unsigned long tick_type_t; #define SDMMC_LOGE( tag, format, ... ) LOG_EARLY_IMPL(tag, format, FT_LOG_ERROR, E, ##__VA_ARGS__) #define SDMMC_LOGW( tag, format, ... ) LOG_EARLY_IMPL(tag, format, FT_LOG_WARN, W, ##__VA_ARGS__) @@ -61,23 +79,11 @@ typedef boolean bool; #define SDMMC_LOG_BUFFER_HEXDUMP( tag, buffer, buff_len, level ) FtDumpHexWord((u32 *)(buffer), (u32)(buff_len)) -/************************** Function Prototypes ******************************/ - -/*****************************************************************************/ -/* init sdmmc before use */ -sdmmc_err_t sdmmc_port_init(void); - -/* deinit sdmmc */ -sdmmc_err_t sdmmc_port_deinit(void); - -/* allocate aligned memory from local memory pool */ -void *sdmmc_port_align_malloc(size_t want_size, boolean dma_capable); - -/* free memory to local memory pool */ -void sdmmc_port_align_free(void *pv); - -/* check if address of buffer is aligned */ -boolean sdmmc_port_is_aligned_memory(const void *buf_p); +void sdmmc_sys_init(void); +void sdmmc_sys_deinit(void); +void sdmmc_sys_delay_ms(uint32_t msecs); +void *sdmmc_sys_heap_caps_malloc(size_t size, uint32_t caps); +void sdmmc_sys_free(void *ptr); #ifdef __cplusplus } diff --git a/third-party/sdmmc-1.0/port/fsdio/fsdio_port.c b/third-party/sdmmc-1.0/port/fsdio/fsdio_port.c new file mode 100644 index 00000000..857f4f12 --- /dev/null +++ b/third-party/sdmmc-1.0/port/fsdio/fsdio_port.c @@ -0,0 +1,735 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fsdio_port.c + * Date: 2022-02-10 14:53:44 + * LastEditTime: 2022-02-25 11:46:22 + * Description:  This files is for sdio port + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2022/12/7 init commit + */ +#include + +#include +#include +#include + +#include "fparameters.h" +#include "fassert.h" +#include "fcache.h" +#include "finterrupt.h" +#include "fdebug.h" +#include "fcpu_info.h" + +#include "fsdio.h" +#include "fsdio_hw.h" + +#include "fsdio_port.h" + +/************************** Constant Definitions *****************************/ +#define SDIO_MAX_BLK_TRANS 128U + +#define FFREERTOS_SDIO_OK FT_SUCCESS +#define FFREERTOS_SDIO_SEMA_ERR FT_CODE_ERR(ErrModPort, ErrBspMmc, 1) +#define FFREERTOS_SDIO_HOST_ERR FT_CODE_ERR(ErrModPort, ErrBspMmc, 2) +#define FFREERTOS_SDIO_EVT_ERR FT_CODE_ERR(ErrModPort, ErrBspMmc, 3) +#define FFREERTOS_SDIO_READ_ERR FT_CODE_ERR(ErrModPort, ErrBspMmc, 4) +#define FFREERTOS_SDIO_WRITE_ERR FT_CODE_ERR(ErrModPort, ErrBspMmc, 5) + +#define FFREERTOS_SDIO_IRQ_PRIORITY IRQ_PRIORITY_VALUE_12 +/**************************** Type Definitions *******************************/ +typedef struct +{ + FSdio ctrl; + sdmmc_host_instance_t *instance; + SemaphoreHandle_t locker; + EventGroupHandle_t evt; +#define FFREERTOS_SDIO_CMD_TRANS_DONE (0x1 << 0) /* evt bit when command / data finished */ +#define FFREERTOS_SDIO_DAT_TRANS_DONE (0x1 << 1) +#define FFREERTOS_SDIO_ERROR_OCCURRED (0x1 << 2) /* evt bit when ctrl in error occurred */ +#define FFREERTOS_SDIO_PLUG_INOUT (0x1 << 3) /* evt bit when card plug-in/out occurred */ + FSdioCmdData cmd_pkg; + FSdioData dat_pkg; + volatile FSdioIDmaDesc *rw_desc; +} sdmmc_host_slot_info; + +/************************** Variable Definitions *****************************/ +static sdmmc_host_slot_info host_slot_info[FSDIO_NUM]; + +/***************** Macros (Inline Functions) Definitions *********************/ +#define FSDIO_DEBUG_TAG "FSDIO-HOST" +#define FSDIO_ERROR(format, ...) FT_DEBUG_PRINT_E(FSDIO_DEBUG_TAG, format, ##__VA_ARGS__) +#define FSDIO_WARN(format, ...) FT_DEBUG_PRINT_W(FSDIO_DEBUG_TAG, format, ##__VA_ARGS__) +#define FSDIO_INFO(format, ...) FT_DEBUG_PRINT_I(FSDIO_DEBUG_TAG, format, ##__VA_ARGS__) +#define FSDIO_DEBUG(format, ...) FT_DEBUG_PRINT_D(FSDIO_DEBUG_TAG, format, ##__VA_ARGS__) + +/************************** Function Prototypes ******************************/ +static inline sdmmc_host_slot_info *fsdio_get_slot_info(int slot) +{ + return &host_slot_info[slot]; +} + +static inline sdmmc_host_instance_t *fsdio_get_instance(int slot) +{ + return host_slot_info[slot].instance; +} + +static inline FSdio *fsdio_get_ctrl(int slot) +{ + return &host_slot_info[slot].ctrl; +} + +sdmmc_err_t sdmmc_cmd_set_block_count(sdmmc_card_t *card, u32 block_count); +sdmmc_err_t sdmmc_send_stop_transmission(sdmmc_card_t *card); +/*****************************************************************************/ +static void fsdio_host_relax(void) +{ + sdmmc_sys_delay_ms(1); +} + +static void fsdio_setup_interrupt(int slot) +{ + FSdio *ctrl = fsdio_get_ctrl(slot); + + uintptr base_addr = ctrl->config.base_addr; + u32 cpu_id = 0; + + GetCpuId(&cpu_id); + FSDIO_INFO("cpu_id is cpu_id %d.", cpu_id); + InterruptSetTargetCpus(ctrl->config.irq_num, cpu_id); + InterruptSetPriority(ctrl->config.irq_num, FFREERTOS_SDIO_IRQ_PRIORITY); + + /* register intr callback */ + InterruptInstall(ctrl->config.irq_num, + FSdioInterruptHandler, + ctrl, + NULL); + + /* enable sdio irq */ + InterruptUmask(ctrl->config.irq_num); + + FSDIO_INFO("SDIO interrupt setup done !!!"); + return; +} + + +/* sdmmc host set bus width */ +static sdmmc_err_t fsdio_host_set_bus_width(int slot, size_t width) +{ + FASSERT((slot >= 0) && (slot < FSDIO_NUM)); + FSdio *ctrl_p = fsdio_get_ctrl(slot); + uintptr base_addr = ctrl_p->config.base_addr; + FSDIO_INFO("Set bus width as %d", width); + FSdioSetBusWidth(base_addr, width); + return SDMMC_OK; +} + +/* sdmmc host get bus width */ +static size_t fsdio_host_get_bus_width(int slot) +{ + FASSERT((slot >= 0) && (slot < FSDIO_NUM)); + return 4U; /* host support 4 bus width */ +} + +/* sdmmc host set ddr mode */ +static sdmmc_err_t fsdio_host_set_ddr_mode(int slot, bool ddr_enabled) +{ + FASSERT((slot >= 0) && (slot < FSDIO_NUM)); + FSDIO_ERROR("sdio_host_set_bus_ddr_mode not supported !!!"); + return SDMMC_OK; +} + +/* sdmmc host change card clock freq */ +static sdmmc_err_t fsdio_host_set_clk_freq(int slot, u32 freq_khz) +{ + FASSERT((slot >= 0) && (slot < FSDIO_NUM)); + FSdio *ctrl_p = fsdio_get_ctrl(slot); + sdmmc_host_slot_info *impl = fsdio_get_slot_info(slot); + FError err = FSdioSetClkFreq(ctrl_p, freq_khz * 1000); + + if (FSDIO_SUCCESS == err) + { + FSDIO_INFO("Set clk rate as %dKHz.\n", freq_khz); + return SDMMC_OK; + } + else + { + return SDMMC_FAIL; + } +} + +static sdmmc_err_t fsdio_host_io_int_enable(int slot) +{ + FASSERT((slot >= 0) && (slot < FSDIO_NUM)); + FSDIO_ERROR("sdio_host_io_int_enable not supported !!!"); + return SDMMC_OK; +} + +static sdmmc_err_t fsdio_host_io_int_wait(int slot, tick_type_t timeout_ticks) +{ + FASSERT((slot >= 0) && (slot < FSDIO_NUM)); + FSDIO_ERROR("sdio_host_io_int_wait not supported !!!"); + return SDMMC_OK; +} + +static sdmmc_err_t fsdio_host_get_real_freq(int slot, int *real_freq_khz) +{ + sdmmc_host_slot_info *impl = fsdio_get_slot_info(slot); + *real_freq_khz = FSdioGetClkFreq(&(impl->ctrl)) / 1000; + return SDMMC_OK; +} + +static void fsdio_convert_cmdinfo(sdmmc_command_t *cmdinfo, FSdioCmdData *const cmd_data) +{ + if (MMC_GO_IDLE_STATE == cmdinfo->opcode) + { + cmd_data->flag |= FSDIO_CMD_FLAG_NEED_INIT; + } + + if (SCF_RSP_CRC & cmdinfo->flags) + { + cmd_data->flag |= FSDIO_CMD_FLAG_NEED_RESP_CRC; + } + + if (SCF_RSP_PRESENT & cmdinfo->flags) + { + cmd_data->flag |= FSDIO_CMD_FLAG_EXP_RESP; + + if (SCF_RSP_136 & cmdinfo->flags) + { + cmd_data->flag |= FSDIO_CMD_FLAG_EXP_LONG_RESP; + } + } + + if (cmdinfo->data) + { + FASSERT_MSG(cmd_data->data_p, "Data buffer shall be assigned."); + cmd_data->flag |= FSDIO_CMD_FLAG_EXP_DATA; + + if (SCF_CMD_READ & cmdinfo->flags) + { + cmd_data->flag |= FSDIO_CMD_FLAG_READ_DATA; + } + else + { + cmd_data->flag |= FSDIO_CMD_FLAG_WRITE_DATA; + } + + cmd_data->data_p->buf = cmdinfo->data; + cmd_data->data_p->blksz = cmdinfo->blklen; + cmd_data->data_p->datalen = cmdinfo->datalen; + FSDIO_INFO("buf@%p, blksz: %d, datalen: %d", + cmd_data->data_p->buf, + cmd_data->data_p->blksz, + cmd_data->data_p->datalen); + } + + cmd_data->cmdidx = cmdinfo->opcode; + cmd_data->cmdarg = cmdinfo->arg; + + /* FSdioDumpCmdInfo(cmd_data); */ + return; +} + +static sdmmc_err_t fsdio_host_pre_command(int slot, sdmmc_command_t *cmdinfo) +{ + sdmmc_host_instance_t *instance_p = fsdio_get_instance(slot); + sdmmc_host_slot_info *impl = fsdio_get_slot_info(slot); + + if (!(instance_p->config.flags & SDMMC_HOST_IO_SUPPORT)) /* filter function card only command */ + { + FSDIO_INFO("opcode = %d", cmdinfo->opcode); + if (SD_IO_SEND_OP_COND == cmdinfo->opcode) + { + FSDIO_INFO("Reject SD_IO_SEND_OP_COND for memory card."); + return SDMMC_FAIL; + } + + if (SD_IO_RW_DIRECT == cmdinfo->opcode) + { + FSDIO_INFO("Reject SD_IO_RW_DIRECT for memory card."); + return SDMMC_ERR_TIMEOUT; + } + } + + if (!(instance_p->config.flags & SDMMC_HOST_REMOVABLE_CARD)) /* filter SD memory card only command */ + { + FSDIO_INFO("opcode = %d", cmdinfo->opcode); + if ((SD_SEND_IF_COND == cmdinfo->opcode) && (NULL == cmdinfo->data)) + { + /* MMC_SEND_EXT_CSD = 8 need to send so check cmdinfo->data to distinguish + SD_SEND_IF_COND from MMC_SEND_EXT_CSD */ + FSDIO_INFO("Reject SD_SEND_IF_COND for eMMC."); + return SDMMC_ERR_NOT_SUPPORTED; + } + + if (MMC_APP_CMD == cmdinfo->opcode) + { + FSDIO_INFO("Reject MMC_APP_CMD for eMMC."); + return SDMMC_ERR_TIMEOUT; + } + } + + if ((MMC_READ_BLOCK_MULTIPLE == cmdinfo->opcode) || + (MMC_WRITE_BLOCK_MULTIPLE == cmdinfo->opcode) && (cmdinfo->data)) + { + u32 block_count = cmdinfo->datalen / cmdinfo->blklen; + if (block_count > 1U) + { + return sdmmc_cmd_set_block_count(&instance_p->card, block_count); + } + } + + return SDMMC_OK; +} + +static sdmmc_err_t fsdio_host_post_command(int slot, sdmmc_command_t *cmdinfo) +{ + sdmmc_host_instance_t *instance_p = fsdio_get_instance(slot); + sdmmc_host_slot_info *impl = fsdio_get_slot_info(slot); + + if ((cmdinfo->error) && (cmdinfo->data)) + { + (void)sdmmc_send_stop_transmission(&(instance_p->card)); + } + + return SDMMC_OK; +} + +static void fsdio_card_detected(FSdio *const ctrl, void *args, u32 status, u32 dmac_status) +{ + FASSERT(ctrl); + int slot = ctrl->config.instance_id; + sdmmc_host_slot_info *slot_info = fsdio_get_slot_info(slot); + BaseType_t xhigher_priority_task_woken = pdFALSE; + BaseType_t x_result = pdFALSE; + + FSDIO_DEBUG("card-%d detected ...", slot); + FASSERT(slot_info->evt); + x_result = xEventGroupSetBitsFromISR(slot_info->evt, FFREERTOS_SDIO_PLUG_INOUT, + &xhigher_priority_task_woken); + +} + +/* send signal sdio error from interrupt */ +static void fsdio_handle_error(FSdio *const ctrl, void *args, u32 status, u32 dmac_status) +{ + FASSERT(ctrl); + FSDIO_ERROR("SDIO error occur ..."); + int slot = ctrl->config.instance_id; + sdmmc_host_slot_info *slot_info = fsdio_get_slot_info(slot); + BaseType_t xhigher_priority_task_woken = pdFALSE; + BaseType_t x_result = pdFALSE; + + FSDIO_ERROR(" cmd: %d.", slot_info->cmd_pkg.cmdidx); + FSDIO_ERROR(" status: 0x%x, dmac status: 0x%x.", status, dmac_status); + if (status & FSDIO_INT_RE_BIT) + { + FSDIO_ERROR(" Response err."); + } + + if (dmac_status & FSDIO_DMAC_STATUS_DU) + { + FSDIO_ERROR(" Fescriptor un-readable."); + } + + FASSERT(slot_info->evt); + x_result = xEventGroupSetBitsFromISR(slot_info->evt, FFREERTOS_SDIO_ERROR_OCCURRED, + &xhigher_priority_task_woken); +} + +/* send signal sdio command done from interrupt */ +static void fsdio_ack_cmd_done(FSdio *const ctrl, void *args, u32 status, u32 dmac_status) +{ + FASSERT(ctrl); + int slot = ctrl->config.instance_id; + sdmmc_host_slot_info *slot_info = fsdio_get_slot_info(slot); + BaseType_t xhigher_priority_task_woken = pdFALSE; + BaseType_t x_result = pdFALSE; + + FSDIO_DEBUG("Ack cmd and data trans done."); + FASSERT(slot_info->evt); + x_result = xEventGroupSetBitsFromISR(slot_info->evt, FFREERTOS_SDIO_CMD_TRANS_DONE, + &xhigher_priority_task_woken); + + return; +} + +/* send signal sdio data over from interrupt */ +static void fsdio_ack_data_done(FSdio *const ctrl, void *args, u32 status, u32 dmac_status) +{ + FASSERT(ctrl); + int slot = ctrl->config.instance_id; + sdmmc_host_slot_info *slot_info = fsdio_get_slot_info(slot); + BaseType_t xhigher_priority_task_woken = pdFALSE; + BaseType_t x_result = pdFALSE; + + FSDIO_DEBUG("Ack cmd and data trans done."); + FASSERT(slot_info->evt); + x_result = xEventGroupSetBitsFromISR(slot_info->evt, FFREERTOS_SDIO_DAT_TRANS_DONE, + &xhigher_priority_task_woken); + + return; +} + +/* wait sdio command done / data over / error occurred from task */ +static FError fsdio_wait_cmd_data_done(int slot, int timeout_ms) +{ + sdmmc_err_t ret = SDMMC_OK; + sdmmc_host_instance_t *instance = fsdio_get_instance(slot); + sdmmc_host_t *host = &instance->host; + FSdio *ctrl = fsdio_get_ctrl(slot); + sdmmc_host_slot_info *slot_info = fsdio_get_slot_info(slot); + FSdioCmdData *cmd_data = &(slot_info->cmd_pkg); + FSdioData *trans_data = &(slot_info->dat_pkg); + + const TickType_t wait_delay = pdMS_TO_TICKS(timeout_ms); /* wait for 5000 ms */ + EventBits_t ev; + FError err = FFREERTOS_SDIO_OK; + u32 evt_bits = FFREERTOS_SDIO_CMD_TRANS_DONE; /* command done */ + u32 err_bits = FFREERTOS_SDIO_ERROR_OCCURRED; /* error occurred */ + + if (cmd_data->data_p) + { + evt_bits |= FFREERTOS_SDIO_DAT_TRANS_DONE; /* need to wait data over */ + } + + /* block task to wait finish signal */ + FASSERT_MSG(slot_info->evt, "evt not exists"); + ev = xEventGroupWaitBits(slot_info->evt, evt_bits, + pdTRUE, pdTRUE, wait_delay); /* wait for cmd/data done */ + if (ev & evt_bits == evt_bits) + { + FSDIO_DEBUG("Trans done."); + err = FSdioGetCmdResponse(ctrl, cmd_data); /* check for response data */ + } + else if (ev & err_bits) + { + /* restart controller in interrupt is not a good idea */ + FSdioDumpRegister(ctrl->config.base_addr); + FSDIO_WARN("Restart controller from error state !!!"); + (void)FSdioRestart(ctrl); /* update clock otherwise next command will also fail */ + err = FFREERTOS_SDIO_EVT_ERR; + } + else + { + FSDIO_ERROR("Trans timeout, ev: 0x%x != 0x%x.", ev, evt_bits); + err = FFREERTOS_SDIO_EVT_ERR; + } + + return err; +} + +static sdmmc_err_t fsdio_host_do_transaction(int slot, sdmmc_command_t *cmdinfo) +{ + FASSERT(cmdinfo); + FError err; + sdmmc_err_t ret = SDMMC_OK; + sdmmc_host_instance_t *instance = fsdio_get_instance(slot); + sdmmc_host_t *host = &instance->host; + FSdio *ctrl = fsdio_get_ctrl(slot); + + sdmmc_host_slot_info *slot_info = fsdio_get_slot_info(slot); + FSdioCmdData *cmd_data = &(slot_info->cmd_pkg); + FSdioData *trans_data = &(slot_info->dat_pkg); + + ret = fsdio_host_pre_command(slot, cmdinfo); + if (SDMMC_OK != ret) + { + /* if not supported (bypass), return ok, if other error (reject), return fail */ + return ret; + } + + memset(cmd_data, 0, sizeof(*cmd_data)); + if (cmdinfo->data) + { + memset(trans_data, 0, sizeof(*trans_data)); + cmd_data->data_p = trans_data; + } + else + { + cmd_data->data_p = NULL; /* no need to wait for data */ + } + + fsdio_convert_cmdinfo(cmdinfo, cmd_data); + + if (SDMMC_HOST_WORK_MODE_DMA & instance->config.flags) /* DMA mode */ + { + err = FSdioDMATransfer(ctrl, cmd_data); + if (FSDIO_SUCCESS != err) + { + ret = SDMMC_FAIL; + goto err_exit; + } + } + else /* non-DMA, PIO mode */ + { + err = FSdioPIOTransfer(ctrl, cmd_data); + if (FSDIO_SUCCESS != err) + { + ret = SDMMC_FAIL; + goto err_exit; + } + } + + /* wait command / data over signal */ + err = fsdio_wait_cmd_data_done(slot, host->command_timeout_ms); + if (FSDIO_SUCCESS != err) + { + ret = SDMMC_FAIL; + cmdinfo->error = SDMMC_FAIL; + } + else + { + if (SCF_RSP_PRESENT & cmdinfo->flags) + { + memcpy(cmdinfo->response, cmd_data->response, sizeof(u32) * 4); + } + } + + ret = fsdio_host_post_command(slot, cmdinfo); + if (SDMMC_OK != ret) + { + goto err_exit; + } + +err_exit: + return ret; +} + +static sdmmc_err_t fsdio_ctrl_init(int slot_id) +{ + sdmmc_err_t ret = SDMMC_OK; + FSdio *ctrl_p = fsdio_get_ctrl(slot_id); + sdmmc_host_instance_t *instance = fsdio_get_instance(slot_id); + FSdioConfig ctrl_config; + const FSdioConfig *def_ctrl_config; + + memset(&ctrl_config, 0, sizeof(ctrl_config)); + + SDMMC_ASSERT((def_ctrl_config = FSdioLookupConfig(slot_id)) != NULL); + ctrl_config = *def_ctrl_config; + + if (!(instance->config.flags & SDMMC_HOST_WORK_MODE_IRQ)) + { + FSDIO_ERROR("IRQ mode is required !!!"); + return SDMMC_FAIL; + } + + if (instance->config.flags & SDMMC_HOST_WORK_MODE_DMA) + { + ctrl_config.trans_mode = FSDIO_IDMA_TRANS_MODE; + } + else + { + ctrl_config.trans_mode = FSDIO_PIO_TRANS_MODE; + } + + if (instance->config.flags & SDMMC_HOST_REMOVABLE_CARD) + { + ctrl_config.non_removable = FALSE; + } + else + { + ctrl_config.non_removable = TRUE; + } + + if ((instance->config.flags & SDMMC_HOST_WORK_MODE_IRQ) && + !(instance->config.flags & SDMMC_HOST_WORK_MODE_DMA)) + { + FSDIO_ERROR("PIO can only work in poll mode !!!"); + ret = SDMMC_FAIL; + goto err_exit; + } + + ctrl_config.filp_resp_byte_order = FALSE; /* sdmmc will handle byte order filp */ + if (FSDIO_SUCCESS != FSdioCfgInitialize(ctrl_p, &ctrl_config)) + { + FSDIO_ERROR("SDIO ctrl init failed."); + ret = SDMMC_FAIL; + goto err_exit; + } + + FSdioRegisterRelaxHandler(ctrl_p, fsdio_host_relax); + + fsdio_setup_interrupt(slot_id); + FSdioRegisterEvtHandler(ctrl_p, FSDIO_EVT_CARD_DETECTED, fsdio_card_detected, NULL); + FSdioRegisterEvtHandler(ctrl_p, FSDIO_EVT_ERR_OCCURE, fsdio_handle_error, NULL); + FSdioRegisterEvtHandler(ctrl_p, FSDIO_EVT_CMD_DONE, fsdio_ack_cmd_done, NULL); + FSdioRegisterEvtHandler(ctrl_p, FSDIO_EVT_DATA_DONE, fsdio_ack_data_done, NULL); + + host_slot_info[slot_id].rw_desc = sdmmc_sys_heap_caps_malloc(SDIO_MAX_BLK_TRANS * sizeof(FSdioIDmaDesc), MALLOC_256_ALIGN); + if (NULL == host_slot_info[slot_id].rw_desc) + { + ret = SDMMC_FAIL; + goto err_exit; + } + + if ((instance->config.flags & SDMMC_HOST_WORK_MODE_DMA) && + (FSDIO_SUCCESS != FSdioSetIDMAList(ctrl_p, host_slot_info[slot_id].rw_desc, SDIO_MAX_BLK_TRANS))) + { + FSDIO_ERROR("SDIO ctrl setup DMA failed."); + ret = SDMMC_FAIL; + goto err_exit; + } + +err_exit: + return ret; +} + +static sdmmc_err_t fsdio_card_init(int slot_id) +{ + sdmmc_err_t ret = SDMMC_OK; + sdmmc_host_instance_t *instance = fsdio_get_instance(slot_id); + sdmmc_host_t *host_p = &instance->host; + sdmmc_card_t *card_p = &instance->card; + + ret = fsdio_host_set_clk_freq(slot_id, SDMMC_FREQ_PROBING); + if (SDMMC_OK != ret) + { + FSDIO_ERROR("SDIO ctrl setup 400kHz clock failed."); + return ret; + } + + ret = fsdio_host_set_bus_width(slot_id, 1U); + if (SDMMC_OK != ret) + { + FSDIO_ERROR("SDIO ctrl set 1 bus width failed."); + return ret; + } + + ret = sdmmc_card_init(host_p, card_p); + if (SDMMC_OK == ret) + { + sdmmc_card_print_info(card_p); + } + + return ret; +} + +sdmmc_err_t fsdio_host_init(sdmmc_host_instance_t *const instance, const sdmmc_host_config_t *config) +{ + SDMMC_ASSERT(instance && config); + SDMMC_ASSERT(config->slot < FSDIO_NUM); + int slot_id = config->slot; + sdmmc_host_t *host_p = &instance->host; + sdmmc_card_t *card_p = &instance->card; + FSdio *ctrl_p = fsdio_get_ctrl(slot_id); + sdmmc_host_slot_info *slot_info = fsdio_get_slot_info(slot_id); + sdmmc_err_t ret = SDMMC_OK; + + memset(host_p, 0, sizeof(*host_p)); + memset(card_p, 0, sizeof(*card_p)); + + instance->private = &host_slot_info[slot_id]; + host_slot_info[slot_id].instance = instance; + + instance->config = *config; + FSDIO_INFO("instance->config.flags = 0x%x", instance->config.flags); + + /* config sdmmc host */ + host_p->flags |= (SDMMC_HOST_FLAG_4BIT | SDMMC_HOST_FLAG_1BIT); /* support 1-bit and 4-bit dat line */ + host_p->flags &= ~SDMMC_HOST_FLAG_DDR; /* no DDR mode, support SDR only */ + host_p->flags &= ~SDMMC_HOST_FLAG_SPI; /* no SPI mode */ + host_p->slot = slot_id; + host_p->max_freq_khz = SDMMC_FREQ_50M; + host_p->io_voltage = 3.3f; /* SD 2.0, no UHS-I support, so support 3.3v only */ + + host_p->command_timeout_ms = 5000; /* 5000ms */ + + /* register sdio host ops */ + host_p->set_bus_width = fsdio_host_set_bus_width; + host_p->get_bus_width = fsdio_host_get_bus_width; + host_p->set_bus_ddr_mode = fsdio_host_set_ddr_mode; + host_p->set_card_clk = fsdio_host_set_clk_freq; + host_p->get_real_freq = fsdio_host_get_real_freq; + host_p->do_transaction = fsdio_host_do_transaction; + host_p->io_int_enable = fsdio_host_io_int_enable; + host_p->io_int_wait = fsdio_host_io_int_wait; + + taskENTER_CRITICAL(); /* no scheduler during init */ + + FASSERT_MSG(NULL == slot_info->locker, "Locker exists !!!"); + FASSERT_MSG((slot_info->locker = xSemaphoreCreateMutex()) != NULL, "create mutex failed !!!"); + + FASSERT_MSG(NULL == slot_info->evt, "Event group exists !!!"); + FASSERT_MSG((slot_info->evt = xEventGroupCreate()) != NULL, "create event group failed !!!"); + + FASSERT(sdmmc_host_lock(host_p) == SDMMC_OK); + + ret = fsdio_ctrl_init(slot_id); + if (SDMMC_OK != ret) + { + goto err_exit; + } + + taskEXIT_CRITICAL(); /* allow schedule after init */ + + /* send command and init card */ + ret = fsdio_card_init(slot_id); + if (SDMMC_OK != ret) + { + FSdioDumpRegister(ctrl_p->config.base_addr); + goto err_exit; + } + + instance->is_ready = FT_COMPONENT_IS_READY; + +err_exit: + sdmmc_host_unlock(host_p); + return ret; +} + +sdmmc_err_t fsdio_host_deinit(sdmmc_host_instance_t *const instance) +{ + sdmmc_err_t ret = SDMMC_OK; + int slot = instance->config.slot; + sdmmc_host_t *host_p = &instance->host; + sdmmc_host_slot_info *slot_info = fsdio_get_slot_info(slot); + + /* no scheduler during deinit */ + taskENTER_CRITICAL(); + + FASSERT_MSG(NULL != slot_info->locker, "Locker not exists !!!"); + vSemaphoreDelete(slot_info->locker); + slot_info->locker = NULL; + + FASSERT_MSG(NULL != slot_info->evt, "Event group not exists !!!"); + vEventGroupDelete(slot_info->evt); + slot_info->evt = NULL; + + taskEXIT_CRITICAL(); /* allow schedule after deinit */ + + return ret; +} + +sdmmc_err_t fsdio_host_lock(sdmmc_host_t *host) +{ + FASSERT(host); + int slot_id = host->slot; + sdmmc_host_slot_info *slot_info = fsdio_get_slot_info(slot_id); + + return (pdTRUE == xSemaphoreTake(slot_info->locker, portMAX_DELAY)) ? SDMMC_OK : SDMMC_FAIL; +} + +void fsdio_host_unlock(sdmmc_host_t *host) +{ + FASSERT(host); + int slot_id = host->slot; + sdmmc_host_slot_info *slot_info = fsdio_get_slot_info(slot_id); + + xSemaphoreGive(slot_info->locker); +} \ No newline at end of file diff --git a/third-party/lwip-2.1.2/README.md b/third-party/sdmmc-1.0/port/fsdio/fsdio_port.h similarity index 42% rename from third-party/lwip-2.1.2/README.md rename to third-party/sdmmc-1.0/port/fsdio/fsdio_port.h index fda0b3af..1a95c490 100644 --- a/third-party/lwip-2.1.2/README.md +++ b/third-party/sdmmc-1.0/port/fsdio/fsdio_port.h @@ -1,49 +1,48 @@ - + * 1.0 zhugengyu 2022/12/7 init commit + */ -# 移植方法 +#ifndef FSDIO_PORT_H +#define FSDIO_PORT_H -## 获取源码 +#include "sdmmc_host.h" -[contrib-2.1.0](http://download.savannah.nongnu.org/releases/lwip/contrib-2.1.0.zip) -[lwip-2.1.2](http://download.savannah.nongnu.org/releases/lwip/lwip-2.1.2.zip) +#ifdef __cplusplus +extern "C" +{ +#endif -## 放置源码 +sdmmc_err_t fsdio_host_init(sdmmc_host_instance_t *const instance, const sdmmc_host_config_t *config); -- 源码路径 -``` -src --> LwIP -``` +sdmmc_err_t fsdio_host_deinit(sdmmc_host_instance_t *const instance); -- 源码分组 +sdmmc_err_t fsdio_host_lock(sdmmc_host_t *const host); -- api -- core -- netif -- arch +void fsdio_host_unlock(sdmmc_host_t *const host); -## 移植头文件 +#ifdef __cplusplus +} +#endif -- lwipopts.h,替代默认的opt.h -- cc.h -- pref.h \ No newline at end of file +#endif \ No newline at end of file diff --git a/third-party/sdmmc-1.0/port/sdmmc_host_os.h b/third-party/sdmmc-1.0/port/sdmmc_host_os.h new file mode 100644 index 00000000..bb1635b4 --- /dev/null +++ b/third-party/sdmmc-1.0/port/sdmmc_host_os.h @@ -0,0 +1,186 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: fsdio_port.h + * Date: 2022-02-10 14:53:44 + * LastEditTime: 2022-02-25 11:46:22 + * Description:  This files is for sdmmc function definition + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2022/12/7 init commit + */ +#ifndef SDMMC_HOST_OS_H +#define SDMMC_HOST_OS_H + +#pragma once + +#include "sdmmc_host.h" +#include "sdmmc_cmd.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define SDMMC_LOCKED_CALL_NON_RET_NON_ARG(func, card) \ + do { \ + SDMMC_ASSERT(card); \ + if (SDMMC_OK == sdmmc_host_lock((sdmmc_host_t *)&(card->host))) {\ + func(card);\ + } \ + sdmmc_host_unlock((sdmmc_host_t *)&(card->host));\ + } while(0); + +#define SDMMC_LOCKED_CALL_NON_ARG(func, card) \ + do { \ + SDMMC_ASSERT(card); \ + sdmmc_err_t err = SDMMC_OK; \ + if (SDMMC_OK == sdmmc_host_lock(&(card->host))) {\ + err = func(card);\ + } \ + sdmmc_host_unlock(&(card->host));\ + return err; \ + } while(0); + +#define SDMMC_LOCKED_CALL_NON_RET(func, card, ...) \ + do { \ + SDMMC_ASSERT(card); \ + if (SDMMC_OK == sdmmc_host_lock(&(card->host))) {\ + func(card, ##__VA_ARGS__);\ + } \ + sdmmc_host_unlock(&(card->host));\ + } while(0); + +#define SDMMC_LOCKED_CALL(func, card, ...) \ + do { \ + SDMMC_ASSERT(card); \ + sdmmc_err_t err = SDMMC_OK; \ + if (SDMMC_OK == sdmmc_host_lock(&(card->host))) {\ + err = func(card, ##__VA_ARGS__);\ + } \ + sdmmc_host_unlock(&(card->host));\ + return err; \ + } while(0); + +/* thread-safe API warpper */ +static inline void sdmmc_os_card_print_info(const sdmmc_card_t *card) +{ + SDMMC_LOCKED_CALL_NON_RET_NON_ARG(sdmmc_card_print_info, card); +} + +static inline sdmmc_err_t sdmmc_os_get_status(sdmmc_card_t *card) +{ + SDMMC_LOCKED_CALL_NON_ARG(sdmmc_get_status, card); +} + +sdmmc_err_t sdmmc_os_write_sectors(sdmmc_card_t *card, const void *src, + size_t start_sector, size_t sector_count) +{ + SDMMC_LOCKED_CALL(sdmmc_write_sectors, card, src, start_sector, sector_count); +} + +sdmmc_err_t sdmmc_os_read_sectors(sdmmc_card_t *card, void *dst, + size_t start_sector, size_t sector_count) +{ + SDMMC_LOCKED_CALL(sdmmc_read_sectors, card, dst, start_sector, sector_count); +} + +sdmmc_err_t sdmmc_os_erase_sectors(sdmmc_card_t *card, size_t start_sector, + size_t sector_count, sdmmc_erase_arg_t arg) +{ + SDMMC_LOCKED_CALL(sdmmc_erase_sectors, card, start_sector, sector_count, arg); +} + +sdmmc_err_t sdmmc_os_can_discard(sdmmc_card_t *card) +{ + SDMMC_LOCKED_CALL_NON_ARG(sdmmc_can_discard, card); +} + +sdmmc_err_t sdmmc_os_can_trim(sdmmc_card_t *card) +{ + SDMMC_LOCKED_CALL_NON_ARG(sdmmc_can_trim, card); +} + +sdmmc_err_t sdmmc_os_mmc_can_sanitize(sdmmc_card_t *card) +{ + SDMMC_LOCKED_CALL_NON_ARG(sdmmc_mmc_can_sanitize, card); +} + +sdmmc_err_t sdmmc_os_mmc_sanitize(sdmmc_card_t *card, uint32_t timeout_ms) +{ + SDMMC_LOCKED_CALL(sdmmc_mmc_sanitize, card, timeout_ms); +} + +sdmmc_err_t sdmmc_os_full_erase(sdmmc_card_t *card) +{ + SDMMC_LOCKED_CALL_NON_ARG(sdmmc_full_erase, card); +} + +sdmmc_err_t sdmmc_os_io_read_byte(sdmmc_card_t *card, uint32_t function, + uint32_t reg, uint8_t *out_byte) +{ + SDMMC_LOCKED_CALL(sdmmc_io_read_byte, card, function, reg, out_byte); +} + +sdmmc_err_t sdmmc_os_io_write_byte(sdmmc_card_t *card, uint32_t function, + uint32_t reg, uint8_t in_byte, uint8_t *out_byte) +{ + SDMMC_LOCKED_CALL(sdmmc_io_write_byte, card, function, reg, in_byte, out_byte); +} + +sdmmc_err_t sdmmc_os_io_read_bytes(sdmmc_card_t *card, uint32_t function, + uint32_t addr, void *dst, size_t size) +{ + SDMMC_LOCKED_CALL(sdmmc_io_read_bytes, card, function, addr, dst, size); +} + +sdmmc_err_t sdmmc_os_io_write_bytes(sdmmc_card_t *card, uint32_t function, + uint32_t addr, const void *src, size_t size) +{ + SDMMC_LOCKED_CALL(sdmmc_io_write_bytes, card, function, addr, src, size); +} + +sdmmc_err_t sdmmc_os_io_read_blocks(sdmmc_card_t *card, uint32_t function, + uint32_t addr, void *dst, size_t size) +{ + SDMMC_LOCKED_CALL(sdmmc_io_read_blocks, card, function, addr, dst, size); +} + +sdmmc_err_t sdmmc_os_io_write_blocks(sdmmc_card_t *card, uint32_t function, + uint32_t addr, const void *src, size_t size) +{ + SDMMC_LOCKED_CALL(sdmmc_io_write_blocks, card, function, addr, src, size); +} + +sdmmc_err_t sdmmc_os_io_enable_int(sdmmc_card_t *card) +{ + SDMMC_LOCKED_CALL_NON_ARG(sdmmc_io_enable_int, card); +} + +sdmmc_err_t sdmmc_os_io_wait_int(sdmmc_card_t *card, tick_type_t timeout_ticks) +{ + SDMMC_LOCKED_CALL(sdmmc_io_wait_int, card, timeout_ticks); +} + +sdmmc_err_t sdmmc_os_io_get_cis_data(sdmmc_card_t *card, uint8_t *out_buffer, size_t buffer_size, size_t *inout_cis_size) +{ + SDMMC_LOCKED_CALL(sdmmc_io_get_cis_data, card, out_buffer, buffer_size, inout_cis_size); +} + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/third-party/sdmmc-1.0/sdmmc.mk b/third-party/sdmmc-1.0/sdmmc.mk new file mode 100644 index 00000000..2388f5e4 --- /dev/null +++ b/third-party/sdmmc-1.0/sdmmc.mk @@ -0,0 +1,20 @@ +SDMMC_OS_DIR := $(FREERTOS_SDK_ROOT)/third-party/sdmmc-1.0 +SDMMC_BM_DIR := $(STANDALONE_DIR)/third-party/sdmmc + +include $(SDMMC_BM_DIR)/sdmmc.mk + +ifdef CONFIG_USE_FREERTOS + +INC_DIR += $(SDMMC_OS_DIR)/osal\ + $(SDMMC_OS_DIR)/port +SRC_DIR += $(SDMMC_OS_DIR)/osal\ + $(SDMMC_OS_DIR)/port + + ifdef CONFIG_SDMMC_USE_FSDIO + + INC_DIR += $(SDMMC_OS_DIR)/port/fsdio + SRC_DIR += $(SDMMC_OS_DIR)/port/fsdio + + endif #CONFIG_SDMMC_USE_FSDIO + +endif \ No newline at end of file diff --git a/third-party/sdmmc-1.0/src/sdmmc_cmd.c b/third-party/sdmmc-1.0/src/sdmmc_cmd.c deleted file mode 100644 index b2246c30..00000000 --- a/third-party/sdmmc-1.0/src/sdmmc_cmd.c +++ /dev/null @@ -1,676 +0,0 @@ -/* - * Copyright (c) 2006 Uwe Stuehler - * Adaptations to ESP-IDF Copyright (c) 2016-2018 Espressif Systems (Shanghai) PTE LTD - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "sdmmc_common.h" - -static const char *TAG = "sdmmc_cmd"; - -sdmmc_err_t sdmmc_send_cmd(sdmmc_card_t *card, sdmmc_command_t *cmd) -{ - if (card->host.command_timeout_ms != 0) - { - cmd->timeout_ms = card->host.command_timeout_ms; - } - else if (cmd->timeout_ms == 0) - { - cmd->timeout_ms = SDMMC_DEFAULT_CMD_TIMEOUT_MS; - } - - int slot = card->host.slot; - SDMMC_LOGV(TAG, "sending cmd slot=%d op=%d arg=%x flags=%x data=%p blklen=%d datalen=%d timeout=%d", - slot, cmd->opcode, cmd->arg, cmd->flags, cmd->data, cmd->blklen, cmd->datalen, cmd->timeout_ms); - sdmmc_err_t err = (*card->host.do_transaction)(slot, cmd); - if (err != 0) - { - SDMMC_LOGD(TAG, "cmd=%d, sdmmc_req_run returned 0x%x", cmd->opcode, err); - return err; - } - int state = MMC_R1_CURRENT_STATE(cmd->response); - SDMMC_LOGV(TAG, "cmd response %08x %08x %08x %08x err=0x%x state=%d", - cmd->response[0], - cmd->response[1], - cmd->response[2], - cmd->response[3], - cmd->error, - state); - return cmd->error; -} - -sdmmc_err_t sdmmc_send_app_cmd(sdmmc_card_t *card, sdmmc_command_t *cmd) -{ - sdmmc_command_t app_cmd = { - .opcode = MMC_APP_CMD, - .flags = SCF_CMD_AC | SCF_RSP_R1, - .arg = MMC_ARG_RCA(card->rca), - }; - SDMMC_LOGI(TAG, "cmd to be send %d", cmd->opcode); - sdmmc_err_t err = sdmmc_send_cmd(card, &app_cmd); - if (err != SDMMC_OK) - { - return err; - } - // Check APP_CMD status bit (only in SD mode) - if (!host_is_spi(card) && !(MMC_R1(app_cmd.response) & MMC_R1_APP_CMD)) - { - SDMMC_LOGW(TAG, "card doesn't support APP_CMD"); - return SDMMC_ERR_NOT_SUPPORTED; - } - return sdmmc_send_cmd(card, cmd); -} - -sdmmc_err_t sdmmc_send_cmd_go_idle_state(sdmmc_card_t *card) -{ - sdmmc_command_t cmd = { - .opcode = MMC_GO_IDLE_STATE, - .flags = SCF_CMD_BC | SCF_RSP_R0, - }; - sdmmc_err_t err = sdmmc_send_cmd(card, &cmd); - if (host_is_spi(card)) - { - /* To enter SPI mode, CMD0 needs to be sent twice (see figure 4-1 in - * SD Simplified spec v4.10). Some cards enter SD mode on first CMD0, - * so don't expect the above command to succeed. - * SCF_RSP_R1 flag below tells the lower layer to expect correct R1 - * response (in SPI mode). - */ - (void)err; - SDMMC_DELAY(SDMMC_GO_IDLE_DELAY_MS); - - cmd.flags |= SCF_RSP_R1; - err = sdmmc_send_cmd(card, &cmd); - } - if (err == SDMMC_OK) - { - SDMMC_DELAY(SDMMC_GO_IDLE_DELAY_MS); - } - return err; -} - -sdmmc_err_t sdmmc_send_cmd_send_if_cond(sdmmc_card_t *card, uint32_t ocr) -{ - const uint8_t pattern = 0xaa; /* any pattern will do here */ - sdmmc_command_t cmd = { - .opcode = SD_SEND_IF_COND, - .arg = (((ocr & SD_OCR_VOL_MASK) != 0) << 8) | pattern, - .flags = SCF_CMD_BCR | SCF_RSP_R7, - }; - sdmmc_err_t err = sdmmc_send_cmd(card, &cmd); - if (err != SDMMC_OK) - { - return err; - } - uint8_t response = cmd.response[0] & 0xff; - if (response != pattern) - { - SDMMC_LOGE(TAG, "%s: received=0x%x expected=0x%x", __func__, response, pattern); - return SDMMC_ERR_INVALID_RESPONSE; - } - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_send_cmd_send_op_cond(sdmmc_card_t *card, uint32_t ocr, uint32_t *ocrp) -{ - sdmmc_err_t err; - - sdmmc_command_t cmd = { - .arg = ocr, - .flags = SCF_CMD_BCR | SCF_RSP_R3, - .opcode = SD_APP_OP_COND}; - int nretries = SDMMC_SEND_OP_COND_MAX_RETRIES; - int err_cnt = SDMMC_SEND_OP_COND_MAX_ERRORS; - for (; nretries != 0; --nretries) - { - bzero(&cmd, sizeof cmd); - cmd.arg = ocr; - cmd.flags = SCF_CMD_BCR | SCF_RSP_R3; - if (!card->is_mmc) - { /* SD mode */ - SDMMC_LOGD(TAG, "SD mode"); - cmd.opcode = SD_APP_OP_COND; - err = sdmmc_send_app_cmd(card, &cmd); - } - else - { /* MMC mode */ - SDMMC_LOGD(TAG, "MMC mode"); - cmd.arg &= ~MMC_OCR_ACCESS_MODE_MASK; - cmd.arg |= MMC_OCR_SECTOR_MODE; - cmd.opcode = MMC_SEND_OP_COND; - err = sdmmc_send_cmd(card, &cmd); - } - - if (err != SDMMC_OK) - { - if (--err_cnt == 0) - { - SDMMC_LOGD(TAG, "%s: sdmmc_send_app_cmd err=0x%x", __func__, err); - return err; - } - else - { - SDMMC_LOGV(TAG, "%s: ignoring err=0x%x", __func__, err); - continue; - } - } - // In SD protocol, card sets MEM_READY bit in OCR when it is ready. - // In SPI protocol, card clears IDLE_STATE bit in R1 response. - if (!host_is_spi(card)) - { - if ((MMC_R3(cmd.response) & MMC_OCR_MEM_READY) || - ocr == 0) - { - break; - } - } - else - { - if ((SD_SPI_R1(cmd.response) & SD_SPI_R1_IDLE_STATE) == 0) - { - break; - } - } - SDMMC_DELAY(1000); - } - if (nretries == 0) - { - return SDMMC_ERR_TIMEOUT; - } - if (ocrp) - { - *ocrp = MMC_R3(cmd.response); - } - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_send_cmd_read_ocr(sdmmc_card_t *card, uint32_t *ocrp) -{ - SDMMC_ASSERT(ocrp); - sdmmc_command_t cmd = { - .opcode = SD_READ_OCR, - .flags = SCF_CMD_BCR | SCF_RSP_R2}; - sdmmc_err_t err = sdmmc_send_cmd(card, &cmd); - if (err != SDMMC_OK) - { - return err; - } - *ocrp = SD_SPI_R3(cmd.response); - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_send_cmd_all_send_cid(sdmmc_card_t *card, sdmmc_response_t *out_raw_cid) -{ - SDMMC_ASSERT(out_raw_cid); - sdmmc_command_t cmd = { - .opcode = MMC_ALL_SEND_CID, - .flags = SCF_CMD_BCR | SCF_RSP_R2}; - sdmmc_err_t err = sdmmc_send_cmd(card, &cmd); - if (err != SDMMC_OK) - { - return err; - } - memcpy(out_raw_cid, &cmd.response, sizeof(sdmmc_response_t)); - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_send_cmd_send_cid(sdmmc_card_t *card, sdmmc_cid_t *out_cid) -{ - SDMMC_ASSERT(out_cid); - SDMMC_ASSERT(host_is_spi(card) && "SEND_CID should only be used in SPI mode"); - SDMMC_ASSERT(!card->is_mmc && "MMC cards are not supported in SPI mode"); - sdmmc_response_t buf; - sdmmc_command_t cmd = { - .opcode = MMC_SEND_CID, - .flags = SCF_CMD_READ | SCF_CMD_ADTC, - .arg = 0, - .data = &buf[0], - .datalen = sizeof(buf)}; - sdmmc_err_t err = sdmmc_send_cmd(card, &cmd); - if (err != SDMMC_OK) - { - return err; - } - sdmmc_flip_byte_order(buf, sizeof(buf)); - return sdmmc_decode_cid(buf, out_cid); -} - -sdmmc_err_t sdmmc_send_cmd_set_relative_addr(sdmmc_card_t *card, uint16_t *out_rca) -{ - SDMMC_ASSERT(out_rca); - sdmmc_command_t cmd = { - .opcode = SD_SEND_RELATIVE_ADDR, - .flags = SCF_CMD_BCR | SCF_RSP_R6}; - - /* MMC cards expect us to set the RCA. - * Set RCA to 1 since we don't support multiple cards on the same bus, for now. - */ - uint16_t mmc_rca = 1; - if (card->is_mmc) - { - cmd.arg = MMC_ARG_RCA(mmc_rca); - } - - sdmmc_err_t err = sdmmc_send_cmd(card, &cmd); - if (err != SDMMC_OK) - { - return err; - } - *out_rca = (card->is_mmc) ? mmc_rca : SD_R6_RCA(cmd.response); - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_send_cmd_set_blocklen(sdmmc_card_t *card, sdmmc_csd_t *csd) -{ - sdmmc_command_t cmd = { - .opcode = MMC_SET_BLOCKLEN, - .arg = csd->sector_size, - .flags = SCF_CMD_AC | SCF_RSP_R1}; - SDMMC_LOGD(TAG, "set block len: sector size: 0x%x", csd->sector_size); - return sdmmc_send_cmd(card, &cmd); -} - -sdmmc_err_t sdmmc_send_cmd_send_csd(sdmmc_card_t *card, sdmmc_csd_t *out_csd) -{ - /* The trick with SEND_CSD is that in SPI mode, it acts as a data read - * command, while in SD mode it is an AC command with R2 response. - */ - sdmmc_response_t spi_buf; - const bool is_spi = host_is_spi(card); - sdmmc_command_t cmd = { - .opcode = MMC_SEND_CSD, - .arg = is_spi ? 0 : MMC_ARG_RCA(card->rca), - .flags = is_spi ? (SCF_CMD_READ | SCF_CMD_ADTC | SCF_RSP_R1) : (SCF_CMD_AC | SCF_RSP_R2), - .data = is_spi ? &spi_buf[0] : 0, - .datalen = is_spi ? sizeof(spi_buf) : 0, - }; - sdmmc_err_t err = sdmmc_send_cmd(card, &cmd); - if (err != SDMMC_OK) - { - return err; - } - uint32_t *ptr = cmd.response; - if (is_spi) - { - sdmmc_flip_byte_order(spi_buf, sizeof(spi_buf)); - ptr = spi_buf; - } - - if (card->is_mmc) - { - err = sdmmc_mmc_decode_csd(cmd.response, out_csd); - } - else - { - err = sdmmc_decode_csd(ptr, out_csd); - } - return err; -} - -sdmmc_err_t sdmmc_send_cmd_select_card(sdmmc_card_t *card, uint32_t rca) -{ - /* Don't expect to see a response when de-selecting a card */ - uint32_t response = (rca == 0) ? 0 : SCF_RSP_R1; - sdmmc_command_t cmd = { - .opcode = MMC_SELECT_CARD, - .arg = MMC_ARG_RCA(rca), - .flags = SCF_CMD_AC | response}; - return sdmmc_send_cmd(card, &cmd); -} - -sdmmc_err_t sdmmc_send_cmd_send_scr(sdmmc_card_t *card, sdmmc_scr_t *out_scr) -{ - size_t datalen = 8; - uint32_t *buf = (uint32_t *)sdmmc_port_align_malloc(datalen, TRUE); - if (buf == NULL) - { - return SDMMC_ERR_NO_MEM; - } - SDMMC_LOGI(TAG, "send scr buf: %p, datalen: %d", buf, datalen); - sdmmc_command_t cmd = { - .data = buf, - .datalen = datalen, - .blklen = datalen, - .flags = SCF_CMD_ADTC | SCF_CMD_READ | SCF_RSP_R1, - .opcode = SD_APP_SEND_SCR}; - sdmmc_err_t err = sdmmc_send_app_cmd(card, &cmd); - if (err == SDMMC_OK) - { - err = sdmmc_decode_scr(buf, out_scr); - } - sdmmc_port_align_free(buf); - return err; -} - -sdmmc_err_t sdmmc_send_cmd_set_bus_width(sdmmc_card_t *card, int width) -{ - sdmmc_command_t cmd = { - .opcode = SD_APP_SET_BUS_WIDTH, - .flags = SCF_RSP_R1 | SCF_CMD_AC, - .arg = (width == 4) ? SD_ARG_BUS_WIDTH_4 : SD_ARG_BUS_WIDTH_1, - }; - - return sdmmc_send_app_cmd(card, &cmd); -} - -sdmmc_err_t sdmmc_send_cmd_crc_on_off(sdmmc_card_t *card, bool crc_enable) -{ - SDMMC_ASSERT(host_is_spi(card) && "CRC_ON_OFF can only be used in SPI mode"); - sdmmc_command_t cmd = { - .opcode = SD_CRC_ON_OFF, - .arg = crc_enable ? 1 : 0, - .flags = SCF_CMD_AC | SCF_RSP_R1}; - return sdmmc_send_cmd(card, &cmd); -} - -sdmmc_err_t sdmmc_send_cmd_send_status(sdmmc_card_t *card, uint32_t *out_status) -{ - sdmmc_command_t cmd = { - .opcode = MMC_SEND_STATUS, - .arg = MMC_ARG_RCA(card->rca), - .flags = SCF_CMD_AC | SCF_RSP_R1}; - sdmmc_err_t err = sdmmc_send_cmd(card, &cmd); - if (err != SDMMC_OK) - { - return err; - } - if (out_status) - { - *out_status = MMC_R1(cmd.response); - } - return SDMMC_OK; -} - -/* set number of blocks in next transcation */ -sdmmc_err_t sdmmc_set_blockcount(sdmmc_card_t *card, size_t block_count) -{ - sdmmc_command_t cmd = { - .opcode = MMC_SET_BLOCK_COUNT, - .arg = block_count & 0xffff, - .flags = SCF_CMD_AC | SCF_RSP_R1}; - return sdmmc_send_cmd(card, &cmd); -} - -sdmmc_err_t sdmmc_write_sectors(sdmmc_card_t *card, const void *src, - size_t start_block, size_t block_count) -{ - sdmmc_err_t err = SDMMC_OK; - size_t block_size = card->csd.sector_size; - if (SDMMC_PTR_DMA_CAP(src) && (intptr_t)src % 4 == 0) - { - err = sdmmc_write_sectors_dma(card, src, start_block, block_count); - } - else - { - // SDMMC peripheral needs DMA-capable buffers. Split the write into - // separate single block writes, if needed, and allocate a temporary - // DMA-capable buffer. - void *tmp_buf = sdmmc_port_align_malloc(block_size, TRUE); - if (tmp_buf == NULL) - { - return SDMMC_ERR_NO_MEM; - } - const uint8_t *cur_src = (const uint8_t *)src; - for (size_t i = 0; i < block_count; ++i) - { - memcpy(tmp_buf, cur_src, block_size); - cur_src += block_size; - err = sdmmc_write_sectors_dma(card, tmp_buf, start_block + i, 1); - if (err != SDMMC_OK) - { - SDMMC_LOGD(TAG, "%s: error 0x%x writing block %d+%d", - __func__, err, start_block, i); - break; - } - } - sdmmc_port_align_free(tmp_buf); - } - return err; -} - -sdmmc_err_t sdmmc_write_sectors_dma(sdmmc_card_t *card, const void *src, - size_t start_block, size_t block_count) -{ - if (start_block + block_count > (size_t)card->csd.capacity) - { - - SDMMC_LOGI(TAG, "start: %d, cnt: %d, capacity: %d", start_block, block_count, (size_t)card->csd.capacity); - return SDMMC_ERR_INVALID_SIZE; - } - size_t block_size = card->csd.sector_size; - sdmmc_err_t err = SDMMC_OK; - sdmmc_command_t cmd = { - .flags = SCF_CMD_ADTC | SCF_RSP_R1, - .blklen = block_size, - .data = (void *)src, - .datalen = block_count * block_size, - .timeout_ms = SDMMC_WRITE_CMD_TIMEOUT_MS}; - if (block_count == 1) - { - cmd.opcode = MMC_WRITE_BLOCK_SINGLE; - } - else - { - cmd.opcode = MMC_WRITE_BLOCK_MULTIPLE; - } - if (card->ocr & SD_OCR_SDHC_CAP) - { - cmd.arg = start_block; - } - else - { - cmd.arg = start_block * block_size; - } - - /* for multi-block transcation, send CMD-23 to announce block num, this is optional */ - if (block_count > 1) - { - err = sdmmc_set_blockcount(card, block_count); - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: sdmmc_set_blockcount returned 0x%x", __func__, err); - return err; - } - } - - err = sdmmc_send_cmd(card, &cmd); - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: sdmmc_send_cmd returned 0x%x", __func__, err); - return err; - } - - /* stop transmission for multi-block write, CMD12 is no supported for mmc card */ - if ((FALSE == card->is_mmc) && (block_count > 1)) - { - err = sdmmc_send_stop_transmission(card); - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: send_stop_transmission returned 0x%x", __func__, err); - return err; - } - } - - uint32_t status = 0; - size_t count = 0; - while (!host_is_spi(card) && !(status & MMC_R1_READY_FOR_DATA)) - { - // TODO: add some timeout here - err = sdmmc_send_cmd_send_status(card, &status); - if (err != SDMMC_OK) - { - return err; - } - if (++count % 10 == 0) - { - SDMMC_LOGV(TAG, "waiting for card to become ready (%d)", count); - } - } - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_read_sectors(sdmmc_card_t *card, void *dst, - size_t start_block, size_t block_count) -{ - sdmmc_err_t err = SDMMC_OK; - size_t block_size = card->csd.sector_size; - if (SDMMC_PTR_DMA_CAP(dst) && (intptr_t)dst % 4 == 0) - { - err = sdmmc_read_sectors_dma(card, dst, start_block, block_count); - } - else - { - // SDMMC peripheral needs DMA-capable buffers. Split the read into - // separate single block reads, if needed, and allocate a temporary - // DMA-capable buffer. - void *tmp_buf = sdmmc_port_align_malloc(block_size, TRUE); - if (tmp_buf == NULL) - { - return SDMMC_ERR_NO_MEM; - } - uint8_t *cur_dst = (uint8_t *)dst; - for (size_t i = 0; i < block_count; ++i) - { - err = sdmmc_read_sectors_dma(card, tmp_buf, start_block + i, 1); - if (err != SDMMC_OK) - { - SDMMC_LOGD(TAG, "%s: error 0x%x writing block %d+%d", - __func__, err, start_block, i); - break; - } - memcpy(cur_dst, tmp_buf, block_size); - cur_dst += block_size; - } - sdmmc_port_align_free(tmp_buf); - } - - return err; -} - -sdmmc_err_t sdmmc_read_sectors_dma(sdmmc_card_t *card, void *dst, - size_t start_block, size_t block_count) -{ - if (start_block + block_count > (size_t)card->csd.capacity) - { - - SDMMC_LOGI(TAG, "start: %d, cnt: %d, capacity: %d", start_block, block_count, (size_t)card->csd.capacity); - return SDMMC_ERR_INVALID_SIZE; - } - size_t block_size = card->csd.sector_size; - sdmmc_err_t err = SDMMC_OK; - sdmmc_command_t cmd = { - .flags = SCF_CMD_ADTC | SCF_CMD_READ | SCF_RSP_R1, - .blklen = block_size, - .data = (void *)dst, - .datalen = block_count * block_size}; - if (block_count == 1) - { - cmd.opcode = MMC_READ_BLOCK_SINGLE; - } - else - { - cmd.opcode = MMC_READ_BLOCK_MULTIPLE; - } - if (card->ocr & SD_OCR_SDHC_CAP) - { - cmd.arg = start_block; - } - else - { - cmd.arg = start_block * block_size; - } - - - /* for multi-block transcation, send CMD-23 to announce block num, this is optional */ - if (block_count > 1) - { - err = sdmmc_set_blockcount(card, block_count); - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: sdmmc_set_blockcount returned 0x%x", __func__, err); - return err; - } - } - - err = sdmmc_send_cmd(card, &cmd); - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: sdmmc_send_cmd returned 0x%x", __func__, err); - return err; - } - - /* stop transmission for multi-block read, CMD12 is no supported for mmc card */ - if ((FALSE == card->is_mmc) && (block_count > 1)) - { - err = sdmmc_send_stop_transmission(card); - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: send_stop_transmission returned 0x%x", __func__, err); - return err; - } - } - - uint32_t status = 0; - size_t count = 0; - while (!host_is_spi(card) && !(status & MMC_R1_READY_FOR_DATA)) - { - // TODO: add some timeout here - err = sdmmc_send_cmd_send_status(card, &status); - if (err != SDMMC_OK) - { - return err; - } - if (++count % 10 == 0) - { - SDMMC_LOGV(TAG, "waiting for card to become ready (%d)", count); - } - } - - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_send_cmd_switch(sdmmc_card_t *card) -{ - size_t datalen = 64; - sdmmc_err_t err; - - uint32_t *buf = (uint32_t *)sdmmc_port_align_malloc(datalen, FALSE); - if (NULL == buf) - { - return SDMMC_ERR_NO_MEM; - } - - memset(buf, 0, datalen); - sdmmc_command_t cmd = { - .opcode = MMC_SWITCH, - .arg = 0x2, - .flags = SCF_CMD_ADTC | SCF_RSP_R1 - }; - - err = sdmmc_send_app_cmd(card, &cmd); - sdmmc_port_align_free(buf); - return err; -} - -sdmmc_err_t sdmmc_send_stop_transmission(sdmmc_card_t *card) -{ - sdmmc_err_t err; - sdmmc_command_t cmd = { - .opcode = MMC_STOP_TRANSMISSION, - .arg = 0x0, - .flags = SCF_RSP_R1B - }; - err = sdmmc_send_app_cmd(card, &cmd); - return err; -} diff --git a/third-party/sdmmc-1.0/src/sdmmc_common.c b/third-party/sdmmc-1.0/src/sdmmc_common.c deleted file mode 100644 index 3ae686e3..00000000 --- a/third-party/sdmmc-1.0/src/sdmmc_common.c +++ /dev/null @@ -1,400 +0,0 @@ -/* - * Copyright (c) 2006 Uwe Stuehler - * Adaptations to ESP-IDF Copyright (c) 2016-2018 Espressif Systems (Shanghai) PTE LTD - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "sdmmc_common.h" - -static const char *TAG = "sdmmc_common"; - -sdmmc_err_t sdmmc_init_ocr(sdmmc_card_t *card) -{ - sdmmc_err_t err; - /* In SPI mode, READ_OCR (CMD58) command is used to figure out which voltage - * ranges the card can support. This step is skipped since 1.8V isn't - * supported on the ESP32. - */ - - uint32_t host_ocr = get_host_ocr(card->host.io_voltage); - if ((card->ocr & SD_OCR_SDHC_CAP) != 0) - { - host_ocr |= SD_OCR_SDHC_CAP; - } - /* Send SEND_OP_COND (ACMD41) command to the card until it becomes ready. */ - err = sdmmc_send_cmd_send_op_cond(card, host_ocr, &card->ocr); - - /* If time-out, re-try send_op_cond as MMC */ - if (err == SDMMC_ERR_TIMEOUT && !host_is_spi(card)) - { - SDMMC_LOGD(TAG, "send_op_cond timeout, trying MMC"); - card->is_mmc = 1; - err = sdmmc_send_cmd_send_op_cond(card, host_ocr, &card->ocr); - } - - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: send_op_cond (1) returned 0x%x", __func__, err); - return err; - } - if (host_is_spi(card)) - { - err = sdmmc_send_cmd_read_ocr(card, &card->ocr); - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: read_ocr returned 0x%x", __func__, err); - return err; - } - } - SDMMC_LOGD(TAG, "host_ocr=0x%x card_ocr=0x%x", host_ocr, card->ocr); - - /* Clear all voltage bits in host's OCR which the card doesn't support. - * Don't touch CCS bit because in SPI mode cards don't report CCS in ACMD41 - * response. - */ - host_ocr &= (card->ocr | (~SD_OCR_VOL_MASK)); - SDMMC_LOGD(TAG, "sdmmc_card_init: host_ocr=%08x, card_ocr=%08x", host_ocr, card->ocr); - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_init_cid(sdmmc_card_t *card) -{ - sdmmc_err_t err; - sdmmc_response_t raw_cid; - if (!host_is_spi(card)) - { - err = sdmmc_send_cmd_all_send_cid(card, &raw_cid); - - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: all_send_cid returned 0x%x", __func__, err); - return err; - } - if (!card->is_mmc) - { - err = sdmmc_decode_cid(raw_cid, &card->cid); - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: decoding CID failed (0x%x)", __func__, err); - return err; - } - } - else - { - /* For MMC, need to know CSD to decode CID. But CSD can only be read - * in data transfer mode, and it is not possible to read CID in data - * transfer mode. We temporiliy store the raw cid and do the - * decoding after the RCA is set and the card is in data transfer - * mode. - */ - memcpy(card->raw_cid, raw_cid, sizeof(sdmmc_response_t)); - } - } - else - { - err = sdmmc_send_cmd_send_cid(card, &card->cid); - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: send_cid returned 0x%x", __func__, err); - return err; - } - } - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_init_rca(sdmmc_card_t *card) -{ - sdmmc_err_t err; - err = sdmmc_send_cmd_set_relative_addr(card, &card->rca); - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: set_relative_addr returned 0x%x", __func__, err); - return err; - } - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_init_mmc_decode_cid(sdmmc_card_t *card) -{ - sdmmc_err_t err; - sdmmc_response_t raw_cid; - memcpy(raw_cid, card->raw_cid, sizeof(raw_cid)); - err = sdmmc_mmc_decode_cid(card->csd.mmc_ver, raw_cid, &card->cid); - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: decoding CID failed (0x%x)", __func__, err); - return err; - } - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_init_csd(sdmmc_card_t *card) -{ - SDMMC_ASSERT(card->is_mem == 1); - /* Get and decode the contents of CSD register. Determine card capacity. */ - sdmmc_err_t err = sdmmc_send_cmd_send_csd(card, &card->csd); - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: send_csd returned 0x%x", __func__, err); - return err; - } - const size_t max_sdsc_capacity = UINT32_MAX / card->csd.sector_size + 1; - if (!(card->ocr & SD_OCR_SDHC_CAP) && - ((size_t)card->csd.capacity > max_sdsc_capacity)) - { - SDMMC_LOGW(TAG, "%s: SDSC card reports capacity=%u. Limiting to %u.", - __func__, card->csd.capacity, max_sdsc_capacity); - card->csd.capacity = max_sdsc_capacity; - } - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_init_select_card(sdmmc_card_t *card) -{ - SDMMC_ASSERT(!host_is_spi(card)); - sdmmc_err_t err = sdmmc_send_cmd_select_card(card, card->rca); - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: select_card returned 0x%x", __func__, err); - return err; - } - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_init_card_hs_mode(sdmmc_card_t *card) -{ - sdmmc_err_t err = SDMMC_ERR_NOT_SUPPORTED; - if (card->is_mem && !card->is_mmc) - { - err = sdmmc_enable_hs_mode_and_check(card); - } - else if (card->is_sdio) - { - err = sdmmc_io_enable_hs_mode(card); - } - else if (card->is_mmc) - { - err = sdmmc_mmc_enable_hs_mode(card); - } - if (err == SDMMC_ERR_NOT_SUPPORTED) - { - SDMMC_LOGD(TAG, "%s: host supports HS mode, but card doesn't", __func__); - card->max_freq_khz = SDMMC_FREQ_DEFAULT; - } - else if (err != SDMMC_OK) - { - return err; - } - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_init_host_bus_width(sdmmc_card_t *card) -{ - int bus_width = 1; - - - if ((card->host.flags & SDMMC_HOST_FLAG_4BIT) && - (card->log_bus_width == 2)) - { - bus_width = 4; - } - else if ((card->host.flags & SDMMC_HOST_FLAG_8BIT) && - (card->log_bus_width == 3)) - { - bus_width = 8; - } - SDMMC_LOGD(TAG, "%s: using %d-bit bus", __func__, bus_width); - if (bus_width > 1) - { - sdmmc_err_t err = (*card->host.set_bus_width)(card->host.slot, bus_width); - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "host.set_bus_width failed (0x%x)", err); - return err; - } - } - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_init_host_frequency(sdmmc_card_t *card) -{ - /* if max freq of card exceed host, host configuration must change, otherwise card init will failed */ - if (card->max_freq_khz > card->host.max_freq_khz) - { - SDMMC_LOGE(TAG, "max freq of card %dkHz shall <= max freq of host %dkHz", - card->max_freq_khz, card->host.max_freq_khz); - return SDMMC_FAIL; - } - - SDMMC_ASSERT(card->max_freq_khz <= card->host.max_freq_khz); - - /* Find highest frequency in the following list, - * which is below card->max_freq_khz. - */ - const uint32_t freq_values[] = { - SDMMC_FREQ_52M, - SDMMC_FREQ_HIGHSPEED, - SDMMC_FREQ_26M, - SDMMC_FREQ_25M, /* add option 25MHz, which is common */ - SDMMC_FREQ_DEFAULT - /* NOTE: in sdspi mode, 20MHz may not work. in that case, add 10MHz here. */ - }; - const int n_freq_values = sizeof(freq_values) / sizeof(freq_values[0]); - - /* select a freq from freq_values that is close to max freq of card */ - uint32_t selected_freq = SDMMC_FREQ_PROBING; - for (int i = 0; i < n_freq_values; ++i) - { - uint32_t freq = freq_values[i]; - if (card->max_freq_khz >= freq) - { - selected_freq = freq; - break; - } - } - - SDMMC_LOGD(TAG, "%s: using %d kHz bus frequency", __func__, selected_freq); - if (selected_freq > SDMMC_FREQ_PROBING) - { - sdmmc_err_t err = (*card->host.set_card_clk)(card->host.slot, selected_freq); - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "failed to switch bus frequency (0x%x)", err); - return err; - } - } - - if (card->is_ddr) - { - if (card->host.set_bus_ddr_mode == NULL) - { - SDMMC_LOGE(TAG, "host doesn't support DDR mode or voltage switching"); - return SDMMC_ERR_NOT_SUPPORTED; - } - sdmmc_err_t err = (*card->host.set_bus_ddr_mode)(card->host.slot, true); - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "failed to switch bus to DDR mode (0x%x)", err); - return err; - } - } - return SDMMC_OK; -} - -void sdmmc_flip_byte_order(uint32_t *response, size_t size) -{ - SDMMC_ASSERT(size % (2 * sizeof(uint32_t)) == 0); - const size_t n_words = size / sizeof(uint32_t); - for (size_t i = 0; i < n_words / 2; ++i) - { - uint32_t left = __builtin_bswap32(response[i]); - uint32_t right = __builtin_bswap32(response[n_words - i - 1]); - response[i] = right; - response[n_words - i - 1] = left; - } -} - -void sdmmc_card_print_info(FILE *stream, const sdmmc_card_t *card) -{ - bool print_scr = card->is_mmc ? false : true; /* emmc card do not have scr to read */ - bool print_csd = true; - - const char *type; - fprintf(stream, "Probe Card Success !!!\n"); - fprintf(stream, "======================\n"); - fprintf(stream, "Name: %s\n", card->cid.name); - if (card->is_sdio) - { - type = "SDIO"; - print_scr = true; - print_csd = true; - } - else if (card->is_mmc) - { - type = "MMC"; - print_csd = true; - } - else - { - type = (card->ocr & SD_OCR_SDHC_CAP) ? "SDHC/SDXC" : "SDSC"; - } - - fprintf(stream, "Manufactory ID: 0x%x\n", card->cid.mfg_id); - fprintf(stream, "OEM ID: 0x%x\n", card->cid.oem_id); - fprintf(stream, "Serial NO.: 0x%x\n", card->cid.serial); - fprintf(stream, "Revision: 0x%x\n", card->cid.revision); - fprintf(stream, "Type: %s\n", type); - - if (card->max_freq_khz < 1000) - { - fprintf(stream, "Speed: %d kHz\n", card->max_freq_khz); - } - else - { - fprintf(stream, "Speed: %d MHz%s\n", card->max_freq_khz / 1000, - card->is_ddr ? ", DDR" : ""); - } - fprintf(stream, "Size: %lluMB\n", ((uint64_t)card->csd.capacity) * card->csd.sector_size / (1024 * 1024)); - - if (print_csd) - { - fprintf(stream, "CSD: ver=%d, class=%d, max speed=%d, sector_size=%d, capacity=%d, read_bl_len=%d, \n", - card->csd.csd_ver, - card->csd.card_command_class, - card->csd.tr_speed, - card->csd.sector_size, - card->csd.capacity, - card->csd.read_block_len); - } - - if (print_scr) - { - fprintf(stream, "SCR: sd_spec=%d, bus_width=%d\n", - card->scr.sd_spec, - card->scr.bus_width); - } - - fprintf(stream, "======================\n"); -} - -sdmmc_err_t sdmmc_fix_host_flags(sdmmc_card_t *card) -{ - const uint32_t width_1bit = SDMMC_HOST_FLAG_1BIT; - const uint32_t width_4bit = SDMMC_HOST_FLAG_4BIT; - const uint32_t width_8bit = SDMMC_HOST_FLAG_8BIT; - const uint32_t width_mask = width_1bit | width_4bit | width_8bit; - - int slot_bit_width = card->host.get_bus_width(card->host.slot); - if (slot_bit_width == 1 && - (card->host.flags & (width_4bit | width_8bit))) - { - card->host.flags &= ~width_mask; - card->host.flags |= width_1bit; - } - else if (slot_bit_width == 4 && (card->host.flags & width_8bit)) - { - if ((card->host.flags & width_4bit) == 0) - { - SDMMC_LOGW(TAG, "slot width set to 4, but host flags don't have 4 line mode enabled; using 1 line mode"); - card->host.flags &= ~width_mask; - card->host.flags |= width_1bit; - } - else - { - card->host.flags &= ~width_mask; - card->host.flags |= width_4bit; - } - } - return SDMMC_OK; -} diff --git a/third-party/sdmmc-1.0/src/sdmmc_init.c b/third-party/sdmmc-1.0/src/sdmmc_init.c deleted file mode 100644 index b3af6850..00000000 --- a/third-party/sdmmc-1.0/src/sdmmc_init.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright (c) 2006 Uwe Stuehler - * Adaptations to ESP-IDF Copyright (c) 2016-2018 Espressif Systems (Shanghai) PTE LTD - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "sdmmc_common.h" - -static const char *TAG = "sdmmc_init"; - -#define SDMMC_INIT_STEP(condition, function) \ - do \ - { \ - if ((condition)) \ - { \ - sdmmc_err_t err = (function)(card); \ - if (err != SDMMC_OK) \ - { \ - SDMMC_LOGD(TAG, "%s: %s returned 0x%x", __func__, #function, err); \ - return err; \ - } \ - } \ - } while (0); - -sdmmc_err_t sdmmc_card_init(const sdmmc_host_t *config, sdmmc_card_t *card) -{ - memset(card, 0, sizeof(*card)); - memcpy(&card->host, config, sizeof(*config)); - const bool is_spi = host_is_spi(card); - const bool always = true; - const bool io_supported = host_support_sdio(card); //true; - - /* Check if host flags are compatible with slot configuration. */ - SDMMC_INIT_STEP(!is_spi, sdmmc_fix_host_flags); - - /* Reset SDIO (CMD52, RES) before re-initializing IO (CMD5). */ - SDMMC_INIT_STEP(io_supported, sdmmc_io_reset); - - /* GO_IDLE_STATE (CMD0) command resets the card */ - SDMMC_INIT_STEP(always, sdmmc_send_cmd_go_idle_state); - - /* SEND_IF_COND (CMD8) command is used to identify SDHC/SDXC cards. */ - SDMMC_INIT_STEP(always, sdmmc_init_sd_if_cond); - - /* IO_SEND_OP_COND(CMD5), Determine if the card is an IO card. */ - SDMMC_INIT_STEP(io_supported, sdmmc_init_io); - - /* if support io, send CMD5 to check if it is memory card inserted, otherwise, - assert card as memory */ - const bool is_mem = io_supported ? card->is_mem : true; - /* if not support io, assert sdio not support */ - const bool is_sdio = io_supported ? !is_mem : false; - - if (!io_supported) - card->is_mem = 1; /* assert card as memory card when io not support */ - - /* Enable CRC16 checks for data transfers in SPI mode */ - SDMMC_INIT_STEP(is_spi, sdmmc_init_spi_crc); - - /* Use SEND_OP_COND(CMD41) to set up card OCR */ - SDMMC_INIT_STEP(is_mem, sdmmc_init_ocr); - - const bool is_mmc = is_mem && card->is_mmc; - const bool is_sdmem = is_mem && !is_mmc; - - SDMMC_LOGD(TAG, "%s: card type is %s", __func__, - is_sdio ? "SDIO" : is_mmc ? "MMC" - : "SD"); - - /* Read the contents of CID register*/ - SDMMC_INIT_STEP(is_mem, sdmmc_init_cid); - - /* Assign RCA (CMD3) */ - SDMMC_INIT_STEP(!is_spi, sdmmc_init_rca); - - /* Read and decode the contents of CSD register */ - SDMMC_INIT_STEP(is_mem, sdmmc_init_csd); - - /* Decode the contents of mmc CID register */ - SDMMC_INIT_STEP(is_mmc && !is_spi, sdmmc_init_mmc_decode_cid); - - /* Switch the card from stand-by mode to data transfer mode (not needed if - * SPI interface is used). This is needed to issue SET_BLOCKLEN and - * SEND_SCR commands. (CMD7) - */ - SDMMC_INIT_STEP(!is_spi, sdmmc_init_select_card); - - /* SD memory cards: - * Set block len for SDSC cards to 512 bytes (same as SDHC) - * Read SCR - * Wait to enter data transfer state - */ - SDMMC_INIT_STEP(is_sdmem, sdmmc_init_sd_blocklen); - - /* essential!!! switch from 1bit to 4bit */ - SDMMC_INIT_STEP(is_sdmem, sdmmc_init_switch_hs); - - SDMMC_INIT_STEP(is_sdmem, sdmmc_init_sd_scr); - SDMMC_INIT_STEP(is_sdmem, sdmmc_init_sd_wait_data_ready); - - /* MMC cards: read CXD */ - SDMMC_INIT_STEP(is_mmc, sdmmc_init_mmc_read_ext_csd); - - /* Try to switch card to HS mode if the card supports it. - * Set card->max_freq_khz value accordingly. - */ - SDMMC_INIT_STEP(always, sdmmc_init_card_hs_mode); - - /* Set bus width. One call for every kind of card, then one for the host */ - if (!is_spi) { - SDMMC_INIT_STEP(is_sdmem, sdmmc_init_sd_bus_width); - SDMMC_INIT_STEP(is_sdio, sdmmc_init_io_bus_width); - SDMMC_INIT_STEP(is_mmc, sdmmc_init_mmc_bus_width); - SDMMC_INIT_STEP(always, sdmmc_init_host_bus_width); - } - - /* Switch to the host to use card->max_freq_khz frequency. */ - SDMMC_INIT_STEP(always, sdmmc_init_host_frequency); - - /* Sanity check after switching the bus mode and frequency */ - //SDMMC_INIT_STEP(is_sdmem, sdmmc_check_scr); - /* TODO: this is CMD line only, add data checks for eMMC */ - SDMMC_INIT_STEP(is_mmc, sdmmc_init_mmc_check_csd); - /* TODO: add similar checks for SDIO */ - - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_init_tf_card(const sdmmc_host_t *config, sdmmc_card_t *card) -{ - const bool always = true; - memset(card, 0, sizeof(*card)); /* reset card data */ - card->is_mem = TRUE; /* assert card as memory card when io not support */ - card->is_mmc = FALSE; /* assert card is not un-removeable emmc card */ - card->is_sdio = FALSE; - memcpy(&card->host, config, sizeof(*config)); /* copy card configs */ - - SDMMC_LOGD(TAG, "card type is SD"); - - /* Check if host flags are compatible with slot configuration. */ - SDMMC_INIT_STEP(always, sdmmc_fix_host_flags); - - /* GO_IDLE_STATE (CMD0) command resets the card */ - SDMMC_INIT_STEP(always, sdmmc_send_cmd_go_idle_state); - - /* SEND_IF_COND (CMD8) command is used to identify SDHC/SDXC cards. */ - SDMMC_INIT_STEP(always, sdmmc_init_sd_if_cond); - - /* Use SEND_OP_COND (CMD41) to set up card OCR */ - SDMMC_INIT_STEP(always, sdmmc_init_ocr); - - /* Read the contents of CID register (CMD2)*/ - SDMMC_INIT_STEP(always, sdmmc_init_cid); - - /* Assign RCA (CMD3) */ - SDMMC_INIT_STEP(always, sdmmc_init_rca); - - /* Read and decode the contents of CSD register (CMD9) */ - SDMMC_INIT_STEP(always, sdmmc_init_csd); - - /* Switch the card from stand-by mode to data transfer mode (not needed if - * SPI interface is used). This is needed to issue SET_BLOCKLEN and - * SEND_SCR commands. (CMD7) - */ - SDMMC_INIT_STEP(always, sdmmc_init_select_card); - - /* Get bus width of card (CMD51) */ - SDMMC_INIT_STEP(always, sdmmc_init_sd_scr); - - /* Check current status of card (CMD13) */ - SDMMC_INIT_STEP(always, sdmmc_init_sd_wait_data_ready); - - /* Set bus width (CMD6) */ - SDMMC_INIT_STEP(always, sdmmc_init_sd_bus_width); - - /* Call driver function to change bus width */ - SDMMC_INIT_STEP(always, sdmmc_init_host_bus_width); - - /* SD memory cards: - * Set block len for SDSC cards to 512 bytes (same as SDHC) - * Read SCR - * Wait to enter data transfer state (CMD16) - */ - SDMMC_INIT_STEP(always, sdmmc_init_sd_blocklen); - - /* Try to switch card to HS mode if the card supports it. - * Set card->max_freq_khz value accordingly. - */ - SDMMC_INIT_STEP(always, sdmmc_init_card_hs_mode); - - /* Call driver function use card->max_freq_khz frequency. */ - SDMMC_INIT_STEP(always, sdmmc_init_host_frequency); - - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_init_emmc(const sdmmc_host_t *config, sdmmc_card_t *card) -{ - const bool always = true; - memset(card, 0, sizeof(*card)); /* reset card data */ - card->is_mem = TRUE; /* assert card as memory card when io not support */ - card->is_mmc = TRUE; /* assert card is not un-removeable emmc card */ - card->is_sdio = FALSE; - memcpy(&card->host, config, sizeof(*config)); /* copy card configs */ - - SDMMC_LOGD(TAG, "card type is eMMC"); - - /* Check if host flags are compatible with slot configuration. */ - SDMMC_INIT_STEP(always, sdmmc_fix_host_flags); - - /* GO_IDLE_STATE (CMD0) command resets the card */ - SDMMC_INIT_STEP(always, sdmmc_send_cmd_go_idle_state); - - /* Use MMC_SEND_OP_COND (CMD1) to set up card OCR */ - SDMMC_INIT_STEP(always, sdmmc_init_ocr); - - /* Read the contents of CID register (CMD2) */ - SDMMC_INIT_STEP(always, sdmmc_init_cid); - - /* Assign RCA (CMD3) */ - SDMMC_INIT_STEP(always, sdmmc_init_rca); - - /* Read and decode the contents of CSD register (CMD9) */ - SDMMC_INIT_STEP(always, sdmmc_init_csd); - - /* Decode the contents of mmc CID register */ - SDMMC_INIT_STEP(always, sdmmc_init_mmc_decode_cid); - - /* Switch the card from stand-by mode to data transfer mode (not needed if - * SPI interface is used). This is needed to issue SET_BLOCKLEN and - * SEND_SCR commands. (CMD7) - */ - SDMMC_INIT_STEP(always, sdmmc_init_select_card); - - /* MMC cards: read CXD (CMD8) */ - SDMMC_INIT_STEP(always, sdmmc_init_mmc_read_ext_csd); - - /* Switch bus width and call driver function to change bus width (CMD6) */ - SDMMC_INIT_STEP(always, sdmmc_init_mmc_bus_width); - SDMMC_INIT_STEP(always, sdmmc_init_host_bus_width); - - /* Check current status of card (CMD13) */ - SDMMC_INIT_STEP(always, sdmmc_init_sd_wait_data_ready); - - /* Try to switch card to HS mode if the card supports it. - * Set card->max_freq_khz value accordingly. - */ - SDMMC_INIT_STEP(always, sdmmc_init_card_hs_mode); - - return SDMMC_OK; -} \ No newline at end of file diff --git a/third-party/sdmmc-1.0/src/sdmmc_io.c b/third-party/sdmmc-1.0/src/sdmmc_io.c deleted file mode 100644 index eb5fa6a7..00000000 --- a/third-party/sdmmc-1.0/src/sdmmc_io.c +++ /dev/null @@ -1,725 +0,0 @@ -/* - * Copyright (c) 2006 Uwe Stuehler - * Adaptations to ESP-IDF Copyright (c) 2016-2018 Espressif Systems (Shanghai) PTE LTD - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "sdmmc_common.h" - -#define CIS_TUPLE(NAME) \ - (cis_tuple_t) { .code = CISTPL_CODE_##NAME, .name = #NAME, .func = &cis_tuple_func_default, } -#define CIS_TUPLE_WITH_FUNC(NAME, FUNC) \ - (cis_tuple_t) { .code = CISTPL_CODE_##NAME, .name = #NAME, .func = &(FUNC), } - -#define CIS_CHECK_SIZE(SIZE, MINIMAL) \ - do \ - { \ - int store_size = (SIZE); \ - if ((store_size) < (MINIMAL)) \ - return SDMMC_ERR_INVALID_SIZE; \ - } while (0) -#define CIS_CHECK_UNSUPPORTED(COND) \ - do \ - { \ - if (!(COND)) \ - return SDMMC_ERR_NOT_SUPPORTED; \ - } while (0) -#define CIS_GET_MINIMAL_SIZE 32 - -typedef sdmmc_err_t (*cis_tuple_info_func_t)(const void *tuple_info, uint8_t *data, FILE *fp); - -typedef struct -{ - int code; - const char *name; - cis_tuple_info_func_t func; -} cis_tuple_t; - -static const char *TAG = "sdmmc_io"; - -static sdmmc_err_t cis_tuple_func_default(const void *p, uint8_t *data, FILE *fp); -static sdmmc_err_t cis_tuple_func_manfid(const void *p, uint8_t *data, FILE *fp); -static sdmmc_err_t cis_tuple_func_cftable_entry(const void *p, uint8_t *data, FILE *fp); -static sdmmc_err_t cis_tuple_func_end(const void *p, uint8_t *data, FILE *fp); - -static const cis_tuple_t cis_table[] = { - CIS_TUPLE(NULL), - CIS_TUPLE(DEVICE), - CIS_TUPLE(CHKSUM), - CIS_TUPLE(VERS1), - CIS_TUPLE(ALTSTR), - CIS_TUPLE(CONFIG), - CIS_TUPLE_WITH_FUNC(CFTABLE_ENTRY, cis_tuple_func_cftable_entry), - CIS_TUPLE_WITH_FUNC(MANFID, cis_tuple_func_manfid), - CIS_TUPLE(FUNCID), - CIS_TUPLE(FUNCE), - CIS_TUPLE(VENDER_BEGIN), - CIS_TUPLE(VENDER_END), - CIS_TUPLE(SDIO_STD), - CIS_TUPLE(SDIO_EXT), - CIS_TUPLE_WITH_FUNC(END, cis_tuple_func_end), -}; - -sdmmc_err_t sdmmc_io_reset(sdmmc_card_t *card) -{ - uint8_t sdio_reset = CCCR_CTL_RES; - sdmmc_err_t err = sdmmc_io_rw_direct(card, 0, SD_IO_CCCR_CTL, SD_ARG_CMD52_WRITE, &sdio_reset); - if (err == SDMMC_ERR_TIMEOUT || (host_is_spi(card) && err == SDMMC_ERR_NOT_SUPPORTED)) - { - /* Non-IO cards are allowed to time out (in SD mode) or - * return "invalid command" error (in SPI mode). - */ - } - else if (err == SDMMC_ERR_NOT_FOUND) - { - SDMMC_LOGD(TAG, "%s: card not present", __func__); - return err; - } - else if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: unexpected return: 0x%x", __func__, err); - return err; - } - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_init_io(sdmmc_card_t *card) -{ - /* IO_SEND_OP_COND(CMD5), Determine if the card is an IO card. - * Non-IO cards will not respond to this command. - */ - sdmmc_err_t err = sdmmc_io_send_op_cond(card, 0, &card->ocr); - if (err != SDMMC_OK) - { - SDMMC_LOGD(TAG, "%s: io_send_op_cond (1) returned 0x%x; not IO card", __func__, err); - card->is_sdio = 0; - card->is_mem = 1; - } - else - { - card->is_sdio = 1; - - if (card->ocr & SD_IO_OCR_MEM_PRESENT) - { - SDMMC_LOGD(TAG, "%s: IO-only card", __func__); - card->is_mem = 0; - } - card->num_io_functions = SD_IO_OCR_NUM_FUNCTIONS(card->ocr); - SDMMC_LOGD(TAG, "%s: number of IO functions: %d", __func__, card->num_io_functions); - if (card->num_io_functions == 0) - { - card->is_sdio = 0; - } - uint32_t host_ocr = get_host_ocr(card->host.io_voltage); - host_ocr &= card->ocr; - err = sdmmc_io_send_op_cond(card, host_ocr, &card->ocr); - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: sdmmc_io_send_op_cond (1) returned 0x%x", __func__, err); - return err; - } - err = sdmmc_io_enable_int(card); - if (err != SDMMC_OK) - { - SDMMC_LOGD(TAG, "%s: sdmmc_enable_int failed (0x%x)", __func__, err); - } - } - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_init_io_bus_width(sdmmc_card_t *card) -{ - sdmmc_err_t err; - card->log_bus_width = 0; - if (card->host.flags & SDMMC_HOST_FLAG_4BIT) - { - uint8_t card_cap = 0; - err = sdmmc_io_rw_direct(card, 0, SD_IO_CCCR_CARD_CAP, - SD_ARG_CMD52_READ, &card_cap); - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: sdmmc_io_rw_direct (read SD_IO_CCCR_CARD_CAP) returned 0x%0x", __func__, err); - return err; - } - SDMMC_LOGD(TAG, "IO card capabilities byte: %02x", card_cap); - if (!(card_cap & CCCR_CARD_CAP_LSC) || - (card_cap & CCCR_CARD_CAP_4BLS)) - { - // This card supports 4-bit bus mode - uint8_t bus_width = CCCR_BUS_WIDTH_4; - err = sdmmc_io_rw_direct(card, 0, SD_IO_CCCR_BUS_WIDTH, - SD_ARG_CMD52_WRITE, &bus_width); - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: sdmmc_io_rw_direct (write SD_IO_CCCR_BUS_WIDTH) returned 0x%0x", __func__, err); - return err; - } - card->log_bus_width = 2; - } - } - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_io_enable_hs_mode(sdmmc_card_t *card) -{ - /* If the host is configured to use low frequency, don't attempt to switch */ - if (card->host.max_freq_khz < SDMMC_FREQ_DEFAULT) - { - card->max_freq_khz = card->host.max_freq_khz; - return SDMMC_OK; - } - else if (card->host.max_freq_khz < SDMMC_FREQ_HIGHSPEED) - { - card->max_freq_khz = SDMMC_FREQ_DEFAULT; - return SDMMC_OK; - } - - /* For IO cards, do write + read operation on "High Speed" register, - * setting EHS bit. If both EHS and SHS read back as set, then HS mode - * has been enabled. - */ - uint8_t val = CCCR_HIGHSPEED_ENABLE; - sdmmc_err_t err = sdmmc_io_rw_direct(card, 0, SD_IO_CCCR_HIGHSPEED, - SD_ARG_CMD52_WRITE | SD_ARG_CMD52_EXCHANGE, &val); - if (err != SDMMC_OK) - { - SDMMC_LOGD(TAG, "%s: sdmmc_io_rw_direct returned 0x%x", __func__, err); - return err; - } - - SDMMC_LOGD(TAG, "%s: CCCR_HIGHSPEED=0x%02x", __func__, val); - const uint8_t hs_mask = CCCR_HIGHSPEED_ENABLE | CCCR_HIGHSPEED_SUPPORT; - if ((val & hs_mask) != hs_mask) - { - return SDMMC_ERR_NOT_SUPPORTED; - } - card->max_freq_khz = SDMMC_FREQ_HIGHSPEED; - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_io_send_op_cond(sdmmc_card_t *card, uint32_t ocr, uint32_t *ocrp) -{ - sdmmc_err_t err = SDMMC_OK; - sdmmc_command_t cmd = { - .flags = SCF_CMD_BCR | SCF_RSP_R4, - .arg = ocr, - .opcode = SD_IO_SEND_OP_COND}; - for (size_t i = 0; i < 100; i++) - { - err = sdmmc_send_cmd(card, &cmd); - if (err != SDMMC_OK) - { - break; - } - if ((MMC_R4(cmd.response) & SD_IO_OCR_MEM_READY) || - ocr == 0) - { - break; - } - err = SDMMC_ERR_TIMEOUT; - SDMMC_DELAY(SDMMC_IO_SEND_OP_COND_DELAY_MS); - } - if (err == SDMMC_OK && ocrp != NULL) - *ocrp = MMC_R4(cmd.response); - - return err; -} - -sdmmc_err_t sdmmc_io_rw_direct(sdmmc_card_t *card, int func, - uint32_t reg, uint32_t arg, uint8_t *byte) -{ - sdmmc_err_t err; - sdmmc_command_t cmd = { - .flags = SCF_CMD_AC | SCF_RSP_R5, - .arg = 0, - .opcode = SD_IO_RW_DIRECT}; - - arg |= (func & SD_ARG_CMD52_FUNC_MASK) << SD_ARG_CMD52_FUNC_SHIFT; - arg |= (reg & SD_ARG_CMD52_REG_MASK) << SD_ARG_CMD52_REG_SHIFT; - arg |= (*byte & SD_ARG_CMD52_DATA_MASK) << SD_ARG_CMD52_DATA_SHIFT; - cmd.arg = arg; - - err = sdmmc_send_cmd(card, &cmd); - if (err != SDMMC_OK) - { - SDMMC_LOGV(TAG, "%s: sdmmc_send_cmd returned 0x%x", __func__, err); - return err; - } - - *byte = SD_R5_DATA(cmd.response); - - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_io_read_byte(sdmmc_card_t *card, uint32_t function, - uint32_t addr, uint8_t *out_byte) -{ - sdmmc_err_t ret = sdmmc_io_rw_direct(card, function, addr, SD_ARG_CMD52_READ, out_byte); - if (ret != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: sdmmc_io_rw_direct (read 0x%x) returned 0x%x", __func__, addr, ret); - } - return ret; -} - -sdmmc_err_t sdmmc_io_write_byte(sdmmc_card_t *card, uint32_t function, - uint32_t addr, uint8_t in_byte, uint8_t *out_byte) -{ - uint8_t tmp_byte = in_byte; - sdmmc_err_t ret = sdmmc_io_rw_direct(card, function, addr, - SD_ARG_CMD52_WRITE | SD_ARG_CMD52_EXCHANGE, &tmp_byte); - if (ret != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: sdmmc_io_rw_direct (write 0x%x) returned 0x%x", __func__, addr, ret); - return ret; - } - if (out_byte != NULL) - { - *out_byte = tmp_byte; - } - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_io_rw_extended(sdmmc_card_t *card, int func, - uint32_t reg, int arg, void *datap, size_t datalen) -{ - sdmmc_err_t err; - const size_t max_byte_transfer_size = 512; - sdmmc_command_t cmd = { - .flags = SCF_CMD_AC | SCF_RSP_R5, - .arg = 0, - .opcode = SD_IO_RW_EXTENDED, - .data = datap, - .datalen = datalen, - .blklen = max_byte_transfer_size /* TODO: read max block size from CIS */ - }; - - uint32_t count; /* number of bytes or blocks, depending on transfer mode */ - if (arg & SD_ARG_CMD53_BLOCK_MODE) - { - if (cmd.datalen % cmd.blklen != 0) - { - return SDMMC_ERR_INVALID_SIZE; - } - count = cmd.datalen / cmd.blklen; - } - else - { - if (datalen > max_byte_transfer_size) - { - /* TODO: split into multiple operations? */ - return SDMMC_ERR_INVALID_SIZE; - } - if (datalen == max_byte_transfer_size) - { - count = 0; // See 5.3.1 SDIO simplifed spec - } - else - { - count = datalen; - } - cmd.blklen = datalen; - } - - arg |= (func & SD_ARG_CMD53_FUNC_MASK) << SD_ARG_CMD53_FUNC_SHIFT; - arg |= (reg & SD_ARG_CMD53_REG_MASK) << SD_ARG_CMD53_REG_SHIFT; - arg |= (count & SD_ARG_CMD53_LENGTH_MASK) << SD_ARG_CMD53_LENGTH_SHIFT; - cmd.arg = arg; - - if ((arg & SD_ARG_CMD53_WRITE) == 0) - { - cmd.flags |= SCF_CMD_READ; - } - - err = sdmmc_send_cmd(card, &cmd); - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: sdmmc_send_cmd returned 0x%x", __func__, err); - return err; - } - - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_io_read_bytes(sdmmc_card_t *card, uint32_t function, - uint32_t addr, void *dst, size_t size) -{ - /* host quirk: SDIO transfer with length not divisible by 4 bytes - * has to be split into two transfers: one with aligned length, - * the other one for the remaining 1-3 bytes. - */ - uint8_t *pc_dst = dst; - while (size > 0) - { - size_t size_aligned = size & (~3); - size_t will_transfer = size_aligned > 0 ? size_aligned : size; - - sdmmc_err_t err = sdmmc_io_rw_extended(card, function, addr, - SD_ARG_CMD53_READ | SD_ARG_CMD53_INCREMENT, - pc_dst, will_transfer); - if (err != SDMMC_OK) - { - return err; - } - pc_dst += will_transfer; - size -= will_transfer; - addr += will_transfer; - } - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_io_write_bytes(sdmmc_card_t *card, uint32_t function, - uint32_t addr, const void *src, size_t size) -{ - /* same host quirk as in sdmmc_io_read_bytes */ - const uint8_t *pc_src = (const uint8_t *)src; - - while (size > 0) - { - size_t size_aligned = size & (~3); - size_t will_transfer = size_aligned > 0 ? size_aligned : size; - - sdmmc_err_t err = sdmmc_io_rw_extended(card, function, addr, - SD_ARG_CMD53_WRITE | SD_ARG_CMD53_INCREMENT, - (void *)pc_src, will_transfer); - if (err != SDMMC_OK) - { - return err; - } - pc_src += will_transfer; - size -= will_transfer; - addr += will_transfer; - } - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_io_read_blocks(sdmmc_card_t *card, uint32_t function, - uint32_t addr, void *dst, size_t size) -{ - if (size % 4 != 0) - { - return SDMMC_ERR_INVALID_SIZE; - } - return sdmmc_io_rw_extended(card, function, addr, - SD_ARG_CMD53_READ | SD_ARG_CMD53_INCREMENT | SD_ARG_CMD53_BLOCK_MODE, - dst, size); -} - -sdmmc_err_t sdmmc_io_write_blocks(sdmmc_card_t *card, uint32_t function, - uint32_t addr, const void *src, size_t size) -{ - if (size % 4 != 0) - { - return SDMMC_ERR_INVALID_SIZE; - } - return sdmmc_io_rw_extended(card, function, addr, - SD_ARG_CMD53_WRITE | SD_ARG_CMD53_INCREMENT | SD_ARG_CMD53_BLOCK_MODE, - (void *)src, size); -} - -sdmmc_err_t sdmmc_io_enable_int(sdmmc_card_t *card) -{ - if (card->host.io_int_enable == NULL) - { - return SDMMC_ERR_NOT_SUPPORTED; - } - return (*card->host.io_int_enable)(card->host.slot); -} - -sdmmc_err_t sdmmc_io_wait_int(sdmmc_card_t *card, TickType_t timeout_ticks) -{ - if (card->host.io_int_wait == NULL) - { - return SDMMC_ERR_NOT_SUPPORTED; - } - return (*card->host.io_int_wait)(card->host.slot, timeout_ticks); -} - -/* - * Print the CIS information of a CIS card, currently only ESP slave supported. - */ - -static sdmmc_err_t cis_tuple_func_default(const void *p, uint8_t *data, FILE *fp) -{ - const cis_tuple_t *tuple = (const cis_tuple_t *)p; - uint8_t code = *(data++); - int size = *(data++); - if (tuple) - { - fprintf(fp, "TUPLE: %s, size: %d: ", tuple->name, size); - } - else - { - fprintf(fp, "TUPLE: unknown(%02X), size: %d: ", code, size); - } - for (int i = 0; i < size; i++) - fprintf(fp, "%02X ", *(data++)); - fprintf(fp, "\n"); - return SDMMC_OK; -} - -static sdmmc_err_t cis_tuple_func_manfid(const void *p, uint8_t *data, FILE *fp) -{ - const cis_tuple_t *tuple = (const cis_tuple_t *)p; - data++; - int size = *(data++); - fprintf(fp, "TUPLE: %s, size: %d\n", tuple->name, size); - CIS_CHECK_SIZE(size, 4); - fprintf(fp, " MANF: %04X, CARD: %04X\n", *(uint16_t *)(data), *(uint16_t *)(data + 2)); - return SDMMC_OK; -} - -static sdmmc_err_t cis_tuple_func_end(const void *p, uint8_t *data, FILE *fp) -{ - const cis_tuple_t *tuple = (const cis_tuple_t *)p; - data++; - fprintf(fp, "TUPLE: %s\n", tuple->name); - return SDMMC_OK; -} - -static sdmmc_err_t cis_tuple_func_cftable_entry(const void *p, uint8_t *data, FILE *fp) -{ - const cis_tuple_t *tuple = (const cis_tuple_t *)p; - data++; - int size = *(data++); - fprintf(fp, "TUPLE: %s, size: %d\n", tuple->name, size); - CIS_CHECK_SIZE(size, 2); - - CIS_CHECK_SIZE(size--, 1); - bool interface = data[0] & BIT(7); - bool def = data[0] & BIT(6); - int conf_ent_num = data[0] & 0x3F; - fprintf(fp, " INDX: %02X, Intface: %d, Default: %d, Conf-Entry-Num: %d\n", *(data++), interface, def, conf_ent_num); - - if (interface) - { - CIS_CHECK_SIZE(size--, 1); - fprintf(fp, " IF: %02X\n", *(data++)); - } - - CIS_CHECK_SIZE(size--, 1); - bool misc = data[0] & BIT(7); - int mem_space = (data[0] >> 5) & (0x3); - bool irq = data[0] & BIT(4); - bool io_sp = data[0] & BIT(3); - bool timing = data[0] & BIT(2); - int power = data[0] & 3; - fprintf(fp, " FS: %02X, misc: %d, mem_space: %d, irq: %d, io_space: %d, timing: %d, power: %d\n", *(data++), misc, mem_space, irq, io_sp, timing, power); - - CIS_CHECK_UNSUPPORTED(power == 0); //power descriptor is not handled yet - CIS_CHECK_UNSUPPORTED(!timing); //timing descriptor is not handled yet - CIS_CHECK_UNSUPPORTED(!io_sp); //io space descriptor is not handled yet - - if (irq) - { - CIS_CHECK_SIZE(size--, 1); - bool mask = data[0] & BIT(4); - fprintf(fp, " IR: %02X, mask: %d, ", *(data++), mask); - if (mask) - { - CIS_CHECK_SIZE(size, 2); - size -= 2; - fprintf(fp, " IRQ: %02X %02X\n", data[0], data[1]); - data += 2; - } - } - - if (mem_space) - { - CIS_CHECK_SIZE(size, 2); - size -= 2; - CIS_CHECK_UNSUPPORTED(mem_space == 1); //other cases not handled yet - int len = *(uint16_t *)data; - fprintf(fp, " LEN: %04X\n", len); - data += 2; - } - - CIS_CHECK_UNSUPPORTED(misc == 0); //misc descriptor is not handled yet - return SDMMC_OK; -} - -static const cis_tuple_t *get_tuple(uint8_t code) -{ - for (size_t i = 0; i < sizeof(cis_table) / sizeof(cis_tuple_t); i++) - { - if (code == cis_table[i].code) - return &cis_table[i]; - } - return NULL; -} - -sdmmc_err_t sdmmc_io_print_cis_info(uint8_t *buffer, size_t buffer_size, FILE *fp) -{ - SDMMC_LOG_BUFFER_HEXDUMP("CIS", buffer, buffer_size, ESP_LOG_DEBUG); - if (!fp) - fp = stdout; - - uint8_t *cis = buffer; - do - { - const cis_tuple_t *tuple = get_tuple(cis[0]); - int size = cis[1]; - sdmmc_err_t ret = SDMMC_OK; - if (tuple) - { - ret = tuple->func(tuple, cis, fp); - } - else - { - ret = cis_tuple_func_default(NULL, cis, fp); - } - if (ret != SDMMC_OK) - return ret; - cis += 2 + size; - if (tuple && tuple->code == CISTPL_CODE_END) - break; - } while (cis < buffer + buffer_size); - return SDMMC_OK; -} - -/** - * Check tuples in the buffer. - * - * @param buf Buffer to check - * @param buffer_size Size of the buffer - * @param inout_cis_offset - * - input: the last cis_offset, relative to the beginning of the buf. -1 if - * this buffer begin with the tuple length, otherwise should be no smaller than - * zero. - * - output: when the end tuple found, output offset of the CISTPL_CODE_END - * byte + 1 (relative to the beginning of the buffer; when not found, output - * the address of next tuple code. - * - * @return true if found, false if haven't. - */ -static bool check_tuples_in_buffer(uint8_t *buf, int buffer_size, int *inout_cis_offset) -{ - int cis_offset = *inout_cis_offset; - if (cis_offset == -1) - { - //the CIS code is checked in the last buffer, skip to next tuple - cis_offset += buf[0] + 2; - } - SDMMC_ASSERT(cis_offset >= 0); - while (1) - { - if (cis_offset < buffer_size) - { - //A CIS code in the buffer, check it - if (buf[cis_offset] == CISTPL_CODE_END) - { - *inout_cis_offset = cis_offset + 1; - return true; - } - } - if (cis_offset + 1 < buffer_size) - { - cis_offset += buf[cis_offset + 1] + 2; - } - else - { - break; - } - } - *inout_cis_offset = cis_offset; - return false; -} - -sdmmc_err_t sdmmc_io_get_cis_data(sdmmc_card_t *card, uint8_t *out_buffer, size_t buffer_size, size_t *inout_cis_size) -{ - sdmmc_err_t ret = SDMMC_OK; - WORD_ALIGNED_ATTR uint8_t buf[CIS_GET_MINIMAL_SIZE]; - - /* Pointer to size is a mandatory parameter */ - SDMMC_ASSERT(inout_cis_size); - - /* - * CIS region exist in 0x1000~0x17FFF of FUNC 0, get the start address of it - * from CCCR register. - */ - uint32_t addr; - ret = sdmmc_io_read_bytes(card, 0, 9, &addr, 3); - if (ret != SDMMC_OK) - return ret; - //the sdmmc_io driver reads 4 bytes, the most significant byte is not the address. - addr &= 0xffffff; - if (addr < 0x1000 || addr > 0x17FFF) - { - return SDMMC_ERR_INVALID_RESPONSE; - } - - /* - * To avoid reading too long, take the input value as limitation if - * existing. - */ - size_t max_reading = UINT32_MAX; - if (*inout_cis_size != 0) - { - max_reading = *inout_cis_size; - } - - /* - * Parse the length while reading. If find the end tuple, or reaches the - * limitation, read no more and return both the data and the size already - * read. - */ - int buffer_offset = 0; - int cur_cis_offset = 0; - bool end_tuple_found = false; - do - { - ret = sdmmc_io_read_bytes(card, 0, addr + buffer_offset, &buf, CIS_GET_MINIMAL_SIZE); - if (ret != SDMMC_OK) - return ret; - - //calculate relative to the beginning of the buffer - int offset = cur_cis_offset - buffer_offset; - bool finish = check_tuples_in_buffer(buf, CIS_GET_MINIMAL_SIZE, &offset); - - int remain_size = buffer_size - buffer_offset; - int copy_len; - if (finish) - { - copy_len = min(offset, remain_size); - end_tuple_found = true; - } - else - { - copy_len = min(CIS_GET_MINIMAL_SIZE, remain_size); - } - if (copy_len > 0) - { - memcpy(out_buffer + buffer_offset, buf, copy_len); - } - cur_cis_offset = buffer_offset + offset; - buffer_offset += CIS_GET_MINIMAL_SIZE; - } while (!end_tuple_found && (size_t)buffer_offset < max_reading); - - if (end_tuple_found) - { - *inout_cis_size = cur_cis_offset; - if ((size_t)cur_cis_offset > buffer_size) - { - return SDMMC_ERR_INVALID_SIZE; - } - else - { - return SDMMC_OK; - } - } - else - { - return SDMMC_ERR_NOT_FOUND; - } -} diff --git a/third-party/sdmmc-1.0/src/sdmmc_mmc.c b/third-party/sdmmc-1.0/src/sdmmc_mmc.c deleted file mode 100644 index 4c6dffed..00000000 --- a/third-party/sdmmc-1.0/src/sdmmc_mmc.c +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Copyright (c) 2006 Uwe Stuehler - * Adaptations to ESP-IDF Copyright (c) 2016-2018 Espressif Systems (Shanghai) PTE LTD - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include "sdmmc_common.h" - -static const char *TAG = "sdmmc_mmc"; - -sdmmc_err_t sdmmc_init_mmc_read_ext_csd(sdmmc_card_t *card) -{ - int card_type; - sdmmc_err_t err = SDMMC_OK; - - uint8_t *ext_csd = sdmmc_port_align_malloc(EXT_CSD_MMC_SIZE, TRUE); - if (!ext_csd) - { - SDMMC_LOGE(TAG, "%s: could not allocate ext_csd", __func__); - return SDMMC_ERR_NO_MEM; - } - - uint32_t sectors = 0; - - SDMMC_LOGD(TAG, "MMC version: %d", card->csd.mmc_ver); - if (card->csd.mmc_ver < MMC_CSD_MMCVER_4_0) - { - err = SDMMC_ERR_NOT_SUPPORTED; - goto out; - } - - /* read EXT_CSD */ - err = sdmmc_mmc_send_ext_csd_data(card, ext_csd, EXT_CSD_MMC_SIZE); - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: send_ext_csd_data error 0x%x", __func__, err); - goto out; - } - card_type = ext_csd[EXT_CSD_CARD_TYPE]; - - card->is_ddr = 0; - if (card_type & EXT_CSD_CARD_TYPE_F_52M_1_8V) - { - card->max_freq_khz = SDMMC_FREQ_52M; - if ((card->host.flags & SDMMC_HOST_FLAG_DDR) && - card->host.max_freq_khz >= SDMMC_FREQ_26M && - card->host.get_bus_width(card->host.slot) == 4) - { - SDMMC_LOGD(TAG, "card and host support DDR mode"); - card->is_ddr = 1; - } - } - else if (card_type & EXT_CSD_CARD_TYPE_F_52M) - { - card->max_freq_khz = SDMMC_FREQ_52M; - } - else if (card_type & EXT_CSD_CARD_TYPE_F_26M) - { - card->max_freq_khz = SDMMC_FREQ_26M; - } - else - { - SDMMC_LOGW(TAG, "%s: unknown CARD_TYPE 0x%x", __func__, card_type); - } - /* For MMC cards, use speed value from EXT_CSD */ - card->csd.tr_speed = card->max_freq_khz * 1000; - SDMMC_LOGD(TAG, "MMC card type %d, max_freq_khz=%d, is_ddr=%d", card_type, card->max_freq_khz, card->is_ddr); - card->max_freq_khz = min((int)card->max_freq_khz, card->host.max_freq_khz); - - if (card->host.flags & SDMMC_HOST_FLAG_8BIT) - { - card->ext_csd.power_class = ext_csd[(card->max_freq_khz > SDMMC_FREQ_26M) ? EXT_CSD_PWR_CL_52_360 : EXT_CSD_PWR_CL_26_360] >> 4; - card->log_bus_width = 3; - } - else if (card->host.flags & SDMMC_HOST_FLAG_4BIT) - { - card->ext_csd.power_class = ext_csd[(card->max_freq_khz > SDMMC_FREQ_26M) ? EXT_CSD_PWR_CL_52_360 : EXT_CSD_PWR_CL_26_360] & 0x0f; - card->log_bus_width = 2; - } - else - { - card->ext_csd.power_class = 0; //card must be able to do full rate at powerclass 0 in 1-bit mode - card->log_bus_width = 0; - } - - sectors = (ext_csd[EXT_CSD_SEC_COUNT + 0] << 0) | (ext_csd[EXT_CSD_SEC_COUNT + 1] << 8) | (ext_csd[EXT_CSD_SEC_COUNT + 2] << 16) | (ext_csd[EXT_CSD_SEC_COUNT + 3] << 24); - - if (sectors > (2u * 1024 * 1024 * 1024) / 512) - { - card->csd.capacity = sectors; - } - -out: - sdmmc_port_align_free(ext_csd); - return err; -} - -sdmmc_err_t sdmmc_init_mmc_bus_width(sdmmc_card_t *card) -{ - sdmmc_err_t err; - if (card->ext_csd.power_class != 0) - { - err = sdmmc_mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_POWER_CLASS, card->ext_csd.power_class); - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: can't change power class (%d bit), 0x%x", __func__, card->ext_csd.power_class, err); - return err; - } - } - - if (card->log_bus_width > 0) - { - int csd_bus_width_value = EXT_CSD_BUS_WIDTH_1; - int bus_width = 1; - if (card->log_bus_width == 2) - { - if (card->is_ddr) - { - csd_bus_width_value = EXT_CSD_BUS_WIDTH_4_DDR; - } - else - { - csd_bus_width_value = EXT_CSD_BUS_WIDTH_4; - } - bus_width = 4; - } - else if (card->log_bus_width == 3) - { - if (card->is_ddr) - { - csd_bus_width_value = EXT_CSD_BUS_WIDTH_8_DDR; - } - else - { - csd_bus_width_value = EXT_CSD_BUS_WIDTH_8; - } - bus_width = 8; - } - err = sdmmc_mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_BUS_WIDTH, csd_bus_width_value); - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: can't change bus width (%d bit), 0x%x", - __func__, bus_width, err); - return err; - } - } - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_mmc_enable_hs_mode(sdmmc_card_t *card) -{ - sdmmc_err_t err; - if (card->max_freq_khz > SDMMC_FREQ_26M) - { - /* switch to high speed timing */ - err = sdmmc_mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_HS_TIMING, EXT_CSD_HS_TIMING_HS); - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: mmc_switch EXT_CSD_HS_TIMING_HS error 0x%x", - __func__, err); - return err; - } - } - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_mmc_decode_cid(int mmc_ver, sdmmc_response_t resp, sdmmc_cid_t *out_cid) -{ - if (mmc_ver == MMC_CSD_MMCVER_1_0 || - mmc_ver == MMC_CSD_MMCVER_1_4) - { - out_cid->mfg_id = MMC_CID_MID_V1(resp); - out_cid->oem_id = 0; - MMC_CID_PNM_V1_CPY(resp, out_cid->name); - out_cid->revision = MMC_CID_REV_V1(resp); - out_cid->serial = MMC_CID_PSN_V1(resp); - out_cid->date = MMC_CID_MDT_V1(resp); - } - else if (mmc_ver == MMC_CSD_MMCVER_2_0 || - mmc_ver == MMC_CSD_MMCVER_3_1 || - mmc_ver == MMC_CSD_MMCVER_4_0) - { - out_cid->mfg_id = MMC_CID_MID_V2(resp); - out_cid->oem_id = MMC_CID_OID_V2(resp); - MMC_CID_PNM_V1_CPY(resp, out_cid->name); - out_cid->revision = 0; - out_cid->serial = MMC_CID_PSN_V1(resp); - out_cid->date = 0; - } - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_mmc_decode_csd(sdmmc_response_t response, sdmmc_csd_t *out_csd) -{ - out_csd->csd_ver = MMC_CSD_CSDVER(response); - if (out_csd->csd_ver == MMC_CSD_CSDVER_1_0 || - out_csd->csd_ver == MMC_CSD_CSDVER_2_0 || - out_csd->csd_ver == MMC_CSD_CSDVER_EXT_CSD) - { - out_csd->mmc_ver = MMC_CSD_MMCVER(response); - out_csd->capacity = MMC_CSD_CAPACITY(response); - out_csd->read_block_len = MMC_CSD_READ_BL_LEN(response); - } - else - { - SDMMC_LOGE(TAG, "unknown MMC CSD structure version 0x%x\n", out_csd->csd_ver); - return 1; - } - int read_bl_size = 1 << out_csd->read_block_len; - out_csd->sector_size = min(read_bl_size, 512); - if (out_csd->sector_size < read_bl_size) - { - out_csd->capacity *= read_bl_size / out_csd->sector_size; - } - /* tr_speed will be determined when reading CXD */ - out_csd->tr_speed = 0; - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_mmc_send_ext_csd_data(sdmmc_card_t *card, void *out_data, size_t datalen) -{ - SDMMC_ASSERT(SDMMC_PTR_DMA_CAP(out_data)); - sdmmc_command_t cmd = { - .data = out_data, - .datalen = datalen, - .blklen = datalen, - .opcode = MMC_SEND_EXT_CSD, - .arg = 0, - .flags = SCF_CMD_ADTC | SCF_RSP_R1 | SCF_CMD_READ}; - return sdmmc_send_cmd(card, &cmd); -} - -sdmmc_err_t sdmmc_mmc_switch(sdmmc_card_t *card, uint8_t set, uint8_t index, uint8_t value) -{ - sdmmc_command_t cmd = { - .opcode = MMC_SWITCH, - .arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | (index << 16) | (value << 8) | set, - .flags = SCF_RSP_R1B | SCF_CMD_AC | SCF_WAIT_BUSY, - }; - sdmmc_err_t err = sdmmc_send_cmd(card, &cmd); - if (err == SDMMC_OK) - { - //check response bit to see that switch was accepted - if (MMC_R1(cmd.response) & MMC_R1_SWITCH_ERROR) - err = SDMMC_ERR_INVALID_RESPONSE; - } - - return err; -} - -sdmmc_err_t sdmmc_init_mmc_check_csd(sdmmc_card_t *card) -{ - sdmmc_err_t err; - SDMMC_ASSERT(card->is_mem == 1); - SDMMC_ASSERT(card->rca != 0); - //The card will not respond to send_csd command in the transfer state. - //Deselect it first. - err = sdmmc_send_cmd_select_card(card, 0); - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: select_card returned 0x%x", __func__, err); - return err; - } - - sdmmc_csd_t csd; - /* Get the contents of CSD register to verify the communication over CMD line - is OK. */ - err = sdmmc_send_cmd_send_csd(card, &csd); - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: send_csd returned 0x%x", __func__, err); - return err; - } - - //Select the card again - err = sdmmc_send_cmd_select_card(card, card->rca); - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: select_card returned 0x%x", __func__, err); - return err; - } - return SDMMC_OK; -} diff --git a/third-party/sdmmc-1.0/src/sdmmc_sd.c b/third-party/sdmmc-1.0/src/sdmmc_sd.c deleted file mode 100644 index 247f036c..00000000 --- a/third-party/sdmmc-1.0/src/sdmmc_sd.c +++ /dev/null @@ -1,408 +0,0 @@ -/* - * Copyright (c) 2006 Uwe Stuehler - * Adaptations to ESP-IDF Copyright (c) 2016-2018 Espressif Systems (Shanghai) PTE LTD - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "sdmmc_common.h" - -static const char *TAG = "sdmmc_sd"; - -sdmmc_err_t sdmmc_init_sd_if_cond(sdmmc_card_t *card) -{ - /* SEND_IF_COND (CMD8) command is used to identify SDHC/SDXC cards. - * SD v1 and non-SD cards will not respond to this command. - */ - uint32_t host_ocr = get_host_ocr(card->host.io_voltage); - sdmmc_err_t err = sdmmc_send_cmd_send_if_cond(card, host_ocr); - if (err == SDMMC_OK) - { - SDMMC_LOGD(TAG, "SDHC/SDXC card"); - host_ocr |= SD_OCR_SDHC_CAP; - } - else if (err == SDMMC_ERR_TIMEOUT) - { - SDMMC_LOGD(TAG, "CMD8 timeout; not an SD v2.00 card"); - } - else if (host_is_spi(card) && err == SDMMC_ERR_NOT_SUPPORTED) - { - SDMMC_LOGD(TAG, "CMD8 rejected; not an SD v2.00 card"); - } - else - { - SDMMC_LOGE(TAG, "%s: send_if_cond (1) returned 0x%x", __func__, err); - return err; - } - card->ocr = host_ocr; - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_init_sd_blocklen(sdmmc_card_t *card) -{ - /* SDSC cards support configurable data block lengths. - * We don't use this feature and set the block length to 512 bytes, - * same as the block length for SDHC cards. - */ - if ((card->ocr & SD_OCR_SDHC_CAP) == 0) - { - sdmmc_err_t err = sdmmc_send_cmd_set_blocklen(card, &card->csd); - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: set_blocklen returned 0x%x", __func__, err); - return err; - } - } - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_init_sd_scr(sdmmc_card_t *card) -{ - sdmmc_err_t err; - /* Get the contents of SCR register: bus width and the version of SD spec - * supported by the card. - * In SD mode, this is the first command which uses D0 line. Errors at - * this step usually indicate connection issue or lack of pull-up resistor. - */ - err = sdmmc_send_cmd_send_scr(card, &card->scr); - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: send_scr (1) returned 0x%x", __func__, err); - return err; - } - - if ((card->scr.bus_width & SCR_SD_BUS_WIDTHS_4BIT) && (card->host.flags & SDMMC_HOST_FLAG_4BIT)) - { - card->log_bus_width = 2; - } - else - { - card->log_bus_width = 0; - } - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_init_sd_bus_width(sdmmc_card_t *card) -{ - int width = 1; - if (card->log_bus_width == 2) - { - width = 4; - } - else if (card->log_bus_width == 3) - { - width = 8; - } - sdmmc_err_t err = sdmmc_send_cmd_set_bus_width(card, width); - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "set_bus_width %d failed (0x%x)", width, err); - return err; - } - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_init_sd_wait_data_ready(sdmmc_card_t *card) -{ - /* Wait for the card to be ready for data transfers */ - uint32_t status = 0; - uint32_t count = 0; - while (!host_is_spi(card) && !(status & MMC_R1_READY_FOR_DATA)) - { - // TODO: add some timeout here - sdmmc_err_t err = sdmmc_send_cmd_send_status(card, &status); - if (err != SDMMC_OK) - { - return err; - } - if (++count % 16 == 0) - { - SDMMC_LOGV(TAG, "waiting for card to become ready (%d)", count); - } - } - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_send_cmd_switch_func(sdmmc_card_t *card, - uint32_t mode, uint32_t group, uint32_t function, - sdmmc_switch_func_rsp_t *resp) -{ - if (card->scr.sd_spec < SCR_SD_SPEC_VER_1_10 || - ((card->csd.card_command_class & SD_CSD_CCC_SWITCH) == 0)) - { - return SDMMC_ERR_NOT_SUPPORTED; - } - - if (group == 0 || - group > SD_SFUNC_GROUP_MAX || - function > SD_SFUNC_FUNC_MAX) - { - return SDMMC_ERR_INVALID_ARG; - } - - if (mode > 1) - { - return SDMMC_ERR_INVALID_ARG; - } - - uint32_t group_shift = (group - 1) << 2; - /* all functions which should not be affected are set to 0xf (no change) */ - uint32_t other_func_mask = (0x00ffffff & ~(0xf << group_shift)); - uint32_t func_val = (function << group_shift) | other_func_mask; - - sdmmc_command_t cmd = { - .opcode = MMC_SWITCH, - .flags = SCF_CMD_ADTC | SCF_CMD_READ | SCF_RSP_R1, - .blklen = sizeof(sdmmc_switch_func_rsp_t), - .data = resp->data, - .datalen = sizeof(sdmmc_switch_func_rsp_t), - .arg = (!!mode << 31) | func_val}; - - sdmmc_err_t err = sdmmc_send_cmd(card, &cmd); - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: sdmmc_send_cmd returned 0x%x", __func__, err); - return err; - } - sdmmc_flip_byte_order(resp->data, sizeof(sdmmc_switch_func_rsp_t)); - uint32_t resp_ver = SD_SFUNC_VER(resp->data); - if (resp_ver == 0) - { - /* busy response is never sent */ - } - else if (resp_ver == 1) - { - if (SD_SFUNC_BUSY(resp->data, group) & (1 << function)) - { - SDMMC_LOGD(TAG, "%s: response indicates function %d:%d is busy", - __func__, group, function); - return SDMMC_ERR_INVALID_STATE; - } - } - else - { - SDMMC_LOGE(TAG, "%s: got an invalid version of SWITCH_FUNC response: 0x%02x", - __func__, resp_ver); - return SDMMC_ERR_INVALID_RESPONSE; - } - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_enable_hs_mode(sdmmc_card_t *card) -{ - /* This will determine if the card supports SWITCH_FUNC command, - * and high speed mode. If the cards supports both, this will enable - * high speed mode at the card side. - */ - if (card->scr.sd_spec < SCR_SD_SPEC_VER_1_10 || - ((card->csd.card_command_class & SD_CSD_CCC_SWITCH) == 0)) - { - return SDMMC_ERR_NOT_SUPPORTED; - } - sdmmc_switch_func_rsp_t *response = (sdmmc_switch_func_rsp_t *) - sdmmc_port_align_malloc(sizeof(*response), TRUE); - if (response == NULL) - { - return SDMMC_ERR_NO_MEM; - } - - sdmmc_err_t err = sdmmc_send_cmd_switch_func(card, 0, SD_ACCESS_MODE, 0, response); - if (err != SDMMC_OK) - { - SDMMC_LOGD(TAG, "%s: sdmmc_send_cmd_switch_func (1) returned 0x%x", __func__, err); - goto out; - } - uint32_t supported_mask = SD_SFUNC_SUPPORTED(response->data, 1); - if ((supported_mask & BIT(SD_ACCESS_MODE_SDR25)) == 0) - { - err = SDMMC_ERR_NOT_SUPPORTED; - goto out; - } - err = sdmmc_send_cmd_switch_func(card, 1, SD_ACCESS_MODE, SD_ACCESS_MODE_SDR25, response); - if (err != SDMMC_OK) - { - SDMMC_LOGD(TAG, "%s: sdmmc_send_cmd_switch_func (2) returned 0x%x", __func__, err); - goto out; - } - -out: - sdmmc_port_align_free(response); - return err; -} - -sdmmc_err_t sdmmc_enable_hs_mode_and_check(sdmmc_card_t *card) -{ - /* All cards should support at least default speed */ - card->max_freq_khz = SDMMC_FREQ_DEFAULT; - if (card->host.max_freq_khz <= card->max_freq_khz) - { - /* Host is configured to use low frequency, don't attempt to switch */ - card->max_freq_khz = card->host.max_freq_khz; - return SDMMC_OK; - } - - /* Try to enabled HS mode */ - sdmmc_err_t err = sdmmc_enable_hs_mode(card); - if (err != SDMMC_OK) - { - return err; - } - /* HS mode has been enabled on the card. - * Read CSD again, it should now indicate that the card supports - * 50MHz clock. - * Since SEND_CSD is allowed only in standby mode, and the card is currently in data transfer - * mode, deselect the card first, then get the CSD, then select the card again. This step is - * not required in SPI mode, since CMD7 (select_card) is not supported. - */ - const bool is_spi = host_is_spi(card); - if (!is_spi) - { - err = sdmmc_send_cmd_select_card(card, 0); - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: select_card (1) returned 0x%x", __func__, err); - return err; - } - } - err = sdmmc_send_cmd_send_csd(card, &card->csd); - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: send_csd returned 0x%x", __func__, err); - return err; - } - if (!is_spi) - { - err = sdmmc_send_cmd_select_card(card, card->rca); - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: select_card (2) returned 0x%x", __func__, err); - return err; - } - } - - if (card->csd.tr_speed != 50000000) - { - SDMMC_LOGW(TAG, "unexpected: after enabling HS mode, tr_speed=%d", card->csd.tr_speed); - return SDMMC_ERR_NOT_SUPPORTED; - } - - card->max_freq_khz = SDMMC_FREQ_HIGHSPEED; - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_check_scr(sdmmc_card_t *card) -{ - /* If frequency switch has been performed, read SCR register one more time - * and compare the result with the previous one. Use this simple check as - * an indicator of potential signal integrity issues. - */ - sdmmc_scr_t scr_tmp; - sdmmc_err_t err = sdmmc_send_cmd_send_scr(card, &scr_tmp); - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: send_scr returned 0x%x", __func__, err); - return err; - } - if (memcmp(&card->scr, &scr_tmp, sizeof(scr_tmp)) != 0) - { - SDMMC_LOGE(TAG, "got corrupted data after increasing clock frequency"); - return SDMMC_ERR_INVALID_RESPONSE; - } - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_init_spi_crc(sdmmc_card_t *card) -{ - /* In SD mode, CRC checks of data transfers are mandatory and performed - * by the hardware. In SPI mode, CRC16 of data transfers is optional and - * needs to be enabled. - */ - SDMMC_ASSERT(host_is_spi(card)); - sdmmc_err_t err = sdmmc_send_cmd_crc_on_off(card, true); - if (err != SDMMC_OK) - { - SDMMC_LOGE(TAG, "%s: sdmmc_send_cmd_crc_on_off returned 0x%x", __func__, err); - return err; - } - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_decode_cid(sdmmc_response_t resp, sdmmc_cid_t *out_cid) -{ - out_cid->mfg_id = SD_CID_MID(resp); - out_cid->oem_id = SD_CID_OID(resp); - SD_CID_PNM_CPY(resp, out_cid->name); - out_cid->revision = SD_CID_REV(resp); - out_cid->serial = SD_CID_PSN(resp); - out_cid->date = SD_CID_MDT(resp); - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_decode_csd(sdmmc_response_t response, sdmmc_csd_t *out_csd) -{ - out_csd->csd_ver = SD_CSD_CSDVER(response); - switch (out_csd->csd_ver) - { - case SD_CSD_CSDVER_2_0: - out_csd->capacity = SD_CSD_V2_CAPACITY(response); - out_csd->read_block_len = SD_CSD_V2_BL_LEN; - break; - case SD_CSD_CSDVER_1_0: - out_csd->capacity = SD_CSD_CAPACITY(response); - out_csd->read_block_len = SD_CSD_READ_BL_LEN(response); - break; - default: - SDMMC_LOGE(TAG, "unknown SD CSD structure version 0x%x", out_csd->csd_ver); - return SDMMC_ERR_NOT_SUPPORTED; - } - out_csd->card_command_class = SD_CSD_CCC(response); - int read_bl_size = 1 << out_csd->read_block_len; - out_csd->sector_size = min(read_bl_size, 512); - if (out_csd->sector_size < read_bl_size) - { - out_csd->capacity *= read_bl_size / out_csd->sector_size; - } - int speed = SD_CSD_SPEED(response); - if (speed == SD_CSD_SPEED_50_MHZ) - { - out_csd->tr_speed = 50000000; - } - else - { - out_csd->tr_speed = 25000000; - } - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_decode_scr(uint32_t *raw_scr, sdmmc_scr_t *out_scr) -{ - sdmmc_response_t resp = {0}; - resp[1] = __builtin_bswap32(raw_scr[0]); - resp[0] = __builtin_bswap32(raw_scr[1]); - int ver = SCR_STRUCTURE(resp); - if (ver != 0) - { - SDMMC_LOGE(TAG, "decode scr failed at %s raw_scr: 0x%x ver: 0x%x", - __func__, *raw_scr, ver); - return SDMMC_ERR_NOT_SUPPORTED; - } - out_scr->sd_spec = SCR_SD_SPEC(resp); - out_scr->bus_width = SCR_SD_BUS_WIDTHS(resp); - SDMMC_LOGD(TAG, "sd spec: 0x%x, bus width: %d", out_scr->sd_spec, out_scr->bus_width); - return SDMMC_OK; -} - -sdmmc_err_t sdmmc_init_switch_hs(sdmmc_card_t *card) -{ - return sdmmc_send_cmd_switch(card); -} \ No newline at end of file diff --git a/third-party/sfud-1.1.0/ports/fqspi/fqspi_sfud_core.c b/third-party/sfud-1.1.0/ports/fqspi/fqspi_sfud_core.c index 2c2fd2f2..d291e7e9 100644 --- a/third-party/sfud-1.1.0/ports/fqspi/fqspi_sfud_core.c +++ b/third-party/sfud-1.1.0/ports/fqspi/fqspi_sfud_core.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: fqspi_sfud_core.c * Date: 2022-02-10 14:53:44 * LastEditTime: 2022-02-25 11:47:57 - * Description:  This files is for - * - * Modify History: + * Description:  This files is for providing sfud func based on qspi. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/8/9 first commit */ #include "fparameters.h" @@ -34,7 +35,7 @@ extern void sfud_log_debug(const char *file, const long line, const char *format, ...); extern void sfud_log_info(const char *format, ...); -typedef struct +typedef struct { u32 id; FFreeRTOSQspi *os_qspi_p; @@ -44,13 +45,13 @@ typedef struct static FQspiSfudOs sfud_instance = { - .id = FQSPI_INSTANCE_0, + .id = FQSPI0_ID, .os_qspi_p = NULL, .cs = FQSPI_CS_0, .is_inited = FALSE }; -static FQspiSfudOs fqspi_sfud_os[FQSPI_INSTANCE_NUM] = {0} ; +static FQspiSfudOs fqspi_sfud_os[FQSPI_NUM] = {0} ; #ifdef SFUD_USING_QSPI @@ -58,7 +59,8 @@ static FQspiSfudOs fqspi_sfud_os[FQSPI_INSTANCE_NUM] = {0} ; * read flash data by QSPI */ static sfud_err FQspiFastRead(const sfud_spi *spi, uint32_t addr, sfud_qspi_read_cmd_format *qspi_read_cmd_format, - uint8_t *read_buf, size_t read_size) { + uint8_t *read_buf, size_t read_size) +{ sfud_err result = SFUD_SUCCESS; FQspiSfudOs *qspi_sfud_os_p = (FQspiSfudOs *)spi->user_data; @@ -67,17 +69,17 @@ static sfud_err FQspiFastRead(const sfud_spi *spi, uint32_t addr, sfud_qspi_read memset(&message, 0, sizeof(message)); /* set default read instruction */ - #ifdef CONFIG_SFUD_QSPI_READ_MODE_READ - qspi_read_cmd_format->instruction = SFUD_CMD_READ_DATA; - #endif +#ifdef CONFIG_SFUD_QSPI_READ_MODE_READ + qspi_read_cmd_format->instruction = SFUD_CMD_READ_DATA; +#endif - #ifdef CONFIG_SFUD_QSPI_READ_MODE_DUAL_READ +#ifdef CONFIG_SFUD_QSPI_READ_MODE_DUAL_READ qspi_read_cmd_format->instruction = SFUD_CMD_DUAL_IO_READ_DATA; - #endif +#endif - #ifdef CONFIG_SFUD_QSPI_READ_MODE_QUAD_READ +#ifdef CONFIG_SFUD_QSPI_READ_MODE_QUAD_READ qspi_read_cmd_format->instruction = SFUD_CMD_QUAD_IO_READ_DATA; - #endif +#endif /* add your qspi read flash data code */ message.read_buf = read_buf; @@ -86,14 +88,14 @@ static sfud_err FQspiFastRead(const sfud_spi *spi, uint32_t addr, sfud_qspi_read message.cmd = qspi_read_cmd_format->instruction; message.cs = qspi_sfud_os_p->cs; result = FFreeRTOSQspiTransfer(qspi_sfud_os_p->os_qspi_p, &message); - + return result; } #endif /* SFUD_USING_QSPI */ -static sfud_err FQspiFlashTransfer(const sfud_spi *spi, const u8 *write_buf, - size_t write_size, u8 *read_buf, size_t read_size) +static sfud_err FQspiFlashTransfer(const sfud_spi *spi, const u8 *write_buf, + size_t write_size, u8 *read_buf, size_t read_size) { SFUD_ASSERT(spi); sfud_err ret = SFUD_SUCCESS; @@ -101,7 +103,7 @@ static sfud_err FQspiFlashTransfer(const sfud_spi *spi, const u8 *write_buf, u32 addr = 0; u8 i = 0; size_t len = 0; - + FQspiSfudOs *qspi_sfud_os_p = (FQspiSfudOs *)spi->user_data; FQspiCtrl *qspi_p = &qspi_sfud_os_p->os_qspi_p->qspi_ctrl; @@ -112,48 +114,48 @@ static sfud_err FQspiFlashTransfer(const sfud_spi *spi, const u8 *write_buf, if (write_size && read_size) { command = write_buf[0]; - switch(command) + switch (command) { case SFUD_CMD_JEDEC_ID: message.cs = qspi_sfud_os_p->cs; - message.cmd = command; + message.cmd = command; message.read_buf = read_buf; message.length = read_size; ret = FFreeRTOSQspiTransfer(qspi_sfud_os_p->os_qspi_p, &message); if (SFUD_SUCCESS != ret) { - printf("failed cmd = %#x, test result 0x%x\r\n", command, ret); + printf("failed cmd = %#x, test result 0x%x.\r\n", command, ret); return ret; } break; case SFUD_CMD_READ_SFDP_REGISTER: - if(write_size >= 4) + if (write_size >= 4) { addr = ((write_buf[1] << 16) | (write_buf[2] << 8) | (write_buf[3])); } message.cs = qspi_sfud_os_p->cs; - message.cmd = command; + message.cmd = command; message.addr = addr; message.read_buf = read_buf; message.length = read_size; ret = FFreeRTOSQspiTransfer(qspi_sfud_os_p->os_qspi_p, &message); if (SFUD_SUCCESS != ret) { - printf("failed cmd = %#x, test result 0x%x\r\n", command, ret); + printf("failed cmd = %#x, test result 0x%x.\r\n", command, ret); return ret; } break; case SFUD_CMD_READ_STATUS_REGISTER: message.cs = qspi_sfud_os_p->cs; - message.cmd = command; + message.cmd = command; message.read_buf = read_buf; message.length = 1; ret = FFreeRTOSQspiTransfer(qspi_sfud_os_p->os_qspi_p, &message); if (SFUD_SUCCESS != ret) { - printf("failed cmd = %#x, test result 0x%x\r\n", command, ret); + printf("failed cmd = %#x, test result 0x%x.\r\n", command, ret); return ret; } break; @@ -161,10 +163,10 @@ static sfud_err FQspiFlashTransfer(const sfud_spi *spi, const u8 *write_buf, break; } } - else if(write_size) + else if (write_size) { command = write_buf[0]; - switch(command) + switch (command) { case SFUD_CMD_ENABLE_RESET: case SFUD_CMD_RESET: @@ -172,40 +174,40 @@ static sfud_err FQspiFlashTransfer(const sfud_spi *spi, const u8 *write_buf, case SFUD_CMD_WRITE_DISABLE: case SFUD_CMD_WRITE_STATUS_REGISTER: message.cs = qspi_sfud_os_p->cs; - message.cmd = command; + message.cmd = command; ret = FFreeRTOSQspiTransfer(qspi_sfud_os_p->os_qspi_p, &message); if (SFUD_SUCCESS != ret) { - printf("failed cmd = %#x, test result 0x%x\r\n", command, ret); + printf("failed cmd = %#x, test result 0x%x.\r\n", command, ret); return ret; } break; - + /* some erase commands are used in SFUD_FLASH_CHIP_TABLE, users need add if not identify */ case SFUD_CMD_ERASE_CHIP: case SFUD_CMD_ERASE_SECTOR: SFUD_ASSERT(write_size >= len); for (i = 1; i < len; i++) { - addr = ((addr << 8)|(write_buf[i])); + addr = ((addr << 8) | (write_buf[i])); } message.cs = qspi_sfud_os_p->cs; - message.cmd = command; + message.cmd = command; message.addr = addr; ret = FFreeRTOSQspiTransfer(qspi_sfud_os_p->os_qspi_p, &message); if (SFUD_SUCCESS != ret) { - printf("failed cmd = %#x, test result 0x%x\r\n", command, ret); + printf("failed cmd = %#x, test result 0x%x.\r\n", command, ret); return ret; } - break; + break; case SFUD_CMD_PAGE_PROGRAM: /* write Flash data */ SFUD_ASSERT(write_size > len); for (i = 1; i < len; i++) { - addr = ((addr << 8)|(write_buf[i])); + addr = ((addr << 8) | (write_buf[i])); } message.write_buf = &write_buf[len]; @@ -216,7 +218,7 @@ static sfud_err FQspiFlashTransfer(const sfud_spi *spi, const u8 *write_buf, ret = FFreeRTOSQspiTransfer(qspi_sfud_os_p->os_qspi_p, &message); if (SFUD_SUCCESS != ret) { - printf("failed cmd = %#x, test result 0x%x\r\n", command, ret); + printf("failed cmd = %#x, test result 0x%x.\r\n", command, ret); return ret; } break; @@ -235,36 +237,37 @@ static sfud_err FQspiFlashTransfer(const sfud_spi *spi, const u8 *write_buf, /** * SPI write data then read data */ -static sfud_err FQspiWriteRead(const sfud_spi *spi, const uint8_t *write_buf, - size_t write_size, uint8_t *read_buf, - size_t read_size) { +static sfud_err FQspiWriteRead(const sfud_spi *spi, const uint8_t *write_buf, + size_t write_size, uint8_t *read_buf, + size_t read_size) +{ sfud_err result = SFUD_SUCCESS; uint8_t send_data, read_data; - - if (write_size) + + if (write_size) { SFUD_ASSERT(write_buf); } - if (read_size) + if (read_size) { SFUD_ASSERT(read_buf); } - FQspiFlashTransfer(spi, write_buf, write_size, read_buf, read_size); + FQspiFlashTransfer(spi, write_buf, write_size, read_buf, read_size); return result; } sfud_err FQspiProbe(sfud_flash *flash) { - sfud_spi *spi_p = &flash->spi; + sfud_spi *spi_p = &flash->spi; sfud_err result = SFUD_SUCCESS; FQspiSfudOs *user_data = &sfud_instance; - if(!memcmp(FQSPI0_SFUD_NAME,spi_p->name,strlen(FQSPI0_SFUD_NAME))) + if (!memcmp(FQSPI0_SFUD_NAME, spi_p->name, strlen(FQSPI0_SFUD_NAME))) { if (FALSE == user_data->is_inited) { @@ -277,10 +280,10 @@ sfud_err FQspiProbe(sfud_flash *flash) /* adout 60 seconds timeout */ flash->retry.times = 60 * 10000; - #ifdef SFUD_USING_QSPI +#ifdef SFUD_USING_QSPI flash->spi.qspi_read = FQspiFastRead; - #endif - user_data->is_inited = TRUE; +#endif + user_data->is_inited = TRUE; } } else diff --git a/third-party/sfud-1.1.0/ports/fqspi/fqspi_sfud_core.h b/third-party/sfud-1.1.0/ports/fqspi/fqspi_sfud_core.h index b10f86a2..43beb540 100644 --- a/third-party/sfud-1.1.0/ports/fqspi/fqspi_sfud_core.h +++ b/third-party/sfud-1.1.0/ports/fqspi/fqspi_sfud_core.h @@ -1,29 +1,30 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: fqspi_sfud_core.h * Date: 2022-02-10 14:53:44 * LastEditTime: 2022-02-25 11:46:38 - * Description:  This files is for - * - * Modify History: + * Description:  This files is for providing sfud api based on qspi + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/8/9 first commit */ -#ifndef FQSPI_SFUD_H -#define FQSPI_SFUD_H +#ifndef FQSPI_SFUD_CORE_H +#define FQSPI_SFUD_CORE_H #include "sfud.h" #include @@ -31,8 +32,17 @@ #include #include "sfud_def.h" +#ifdef __cplusplus +extern "C" +{ +#endif + #define FQSPI0_SFUD_NAME "FQSPI0" -sfud_err FQspiProbe(sfud_flash *flash) ; +sfud_err FQspiProbe(sfud_flash *flash) ; + +#ifdef __cplusplus +} +#endif #endif // ! diff --git a/third-party/sfud-1.1.0/ports/fspim/fspim_sfud_core.c b/third-party/sfud-1.1.0/ports/fspim/fspim_sfud_core.c index 49edbc7e..111fa142 100644 --- a/third-party/sfud-1.1.0/ports/fspim/fspim_sfud_core.c +++ b/third-party/sfud-1.1.0/ports/fspim/fspim_sfud_core.c @@ -1,22 +1,22 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: fspim_sfud_core.c * Date: 2022-08-19 10:09:23 * LastEditTime: 2022-08-19 10:09:23 - * Description:  This files is for - * - * Modify History: + * Description:  This files is for + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- */ @@ -46,14 +46,14 @@ static FSpimSfudOs sfud_instance = { .spi_id = FSPI2_ID, .spi = NULL, - .spi_cfg = + .spi_cfg = { /* you may need to assign spi mode according to flash spec. */ .spi_mode = FFREERTOS_SPIM_MODE_0, .en_dma = FALSE, .inner_loopback = FALSE }, - .spi_msg = + .spi_msg = { .rx_buf = NULL, .rx_len = 0U, @@ -73,11 +73,11 @@ static sfud_err FSpimReadWrite(const sfud_spi *spi, const uint8_t *write_buf, si SFUD_DEBUG("spi_write_read@%p beg+++++++++++++++++++++++++++++++++++++++++++++++++++", spi); if (NULL != write_buf) { - SFUD_DEBUG("++++ Write %d Bytes @%p: 0x%x, 0x%x, 0x%x", - write_size, write_buf, - ((write_size > 0)) ? write_buf[0] : 0xff, - ((write_size > 1)) ? write_buf[1] : 0xff, - ((write_size > 2)) ? write_buf[2] : 0xff); + SFUD_DEBUG("++++ Write %d Bytes @%p: 0x%x, 0x%x, 0x%x", + write_size, write_buf, + ((write_size > 0)) ? write_buf[0] : 0xff, + ((write_size > 1)) ? write_buf[1] : 0xff, + ((write_size > 2)) ? write_buf[2] : 0xff); } /** @@ -88,7 +88,7 @@ static sfud_err FSpimReadWrite(const sfud_spi *spi, const uint8_t *write_buf, si user_data->spi_msg.tx_buf = write_buf; user_data->spi_msg.tx_len = write_size; err = FFreeRTOSSpimTransfer(user_data->spi, &user_data->spi_msg); - if (FT_SUCCESS != err) + if (FT_SUCCESS != err) { result = write_size > 0 ? SFUD_ERR_WRITE : SFUD_ERR_READ; SFUD_ERROR("sfud transfer failed !!!"); @@ -96,15 +96,15 @@ static sfud_err FSpimReadWrite(const sfud_spi *spi, const uint8_t *write_buf, si if (NULL != read_buf) { - SFUD_DEBUG("++++ Read %d Bytes @%p: 0x%x, 0x%x, 0x%x", - read_size, read_buf, - ((read_size > 0)) ? read_buf[0] : 0xff, - ((read_size > 1)) ? read_buf[1] : 0xff, - ((read_size > 2)) ? read_buf[2] : 0xff); + SFUD_DEBUG("++++ Read %d Bytes @%p: 0x%x, 0x%x, 0x%x", + read_size, read_buf, + ((read_size > 0)) ? read_buf[0] : 0xff, + ((read_size > 1)) ? read_buf[1] : 0xff, + ((read_size > 2)) ? read_buf[2] : 0xff); } SFUD_DEBUG("spi_write_read@%p end+++++++++++++++++++++++++++++++++++++++++++++++++++", spi); - return result; + return result; } sfud_err FSpimProbe(sfud_flash *flash) @@ -114,7 +114,7 @@ sfud_err FSpimProbe(sfud_flash *flash) if (!memcmp(FSPIM2_SFUD_NAME, spi_p->name, strlen(FSPIM2_SFUD_NAME))) { - /* sfud_spi_port_init will be called for each flash candidate, + /* sfud_spi_port_init will be called for each flash candidate, and we just do controller init for the first time */ if (FALSE == user_data->is_inited) { @@ -125,7 +125,7 @@ sfud_err FSpimProbe(sfud_flash *flash) return SFUD_ERR_NOT_FOUND; } - user_data->is_inited = TRUE; + user_data->is_inited = TRUE; } flash->spi.user_data = user_data; flash->spi.wr = FSpimReadWrite; diff --git a/third-party/sfud-1.1.0/ports/fspim/fspim_sfud_core.h b/third-party/sfud-1.1.0/ports/fspim/fspim_sfud_core.h index f8748cb1..a7a7fe92 100644 --- a/third-party/sfud-1.1.0/ports/fspim/fspim_sfud_core.h +++ b/third-party/sfud-1.1.0/ports/fspim/fspim_sfud_core.h @@ -1,31 +1,41 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: fspim_sfud_core.h * Date: 2022-08-19 10:09:31 * LastEditTime: 2022-08-19 10:09:31 - * Description:  This files is for - * - * Modify History: + * Description:  This files is for + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 zhugengyu 2022/8/26 first release */ -#ifndef FSPIM_SFUD_H -#define FSPIM_SFUD_H +#ifndef FSPIM_SFUD_CORE_H +#define FSPIM_SFUD_CORE_H #include "sfud.h" #include "sfud_def.h" +#ifdef __cplusplus +extern "C" +{ +#endif + sfud_err FSpimProbe(sfud_flash *flash); +#ifdef __cplusplus +} +#endif + #endif // ! \ No newline at end of file diff --git a/third-party/sfud-1.1.0/ports/sfud_port.c b/third-party/sfud-1.1.0/ports/sfud_port.c index 28190506..252f85a8 100644 --- a/third-party/sfud-1.1.0/ports/sfud_port.c +++ b/third-party/sfud-1.1.0/ports/sfud_port.c @@ -40,11 +40,11 @@ #include "semphr.h" #ifdef CONFIG_SFUD_CTRL_FSPIM -#include "fspim_sfud_core.h" + #include "fspim_sfud_core.h" #endif #ifdef CONFIG_SFUD_CTRL_FQSPI -#include "fqspi_sfud_core.h" -#endif + #include "fqspi_sfud_core.h" +#endif static char log_buf[256]; @@ -54,18 +54,18 @@ static xSemaphoreHandle xSemaphore; void sfud_log_debug(const char *file, const long line, const char *format, ...); void sfud_log_info(const char *format, ...); -static void spi_lock(const sfud_spi *spi) +static void spi_lock(const sfud_spi *spi) { xSemaphoreTake(xSemaphore, portMAX_DELAY); } -static void spi_unlock(const sfud_spi *spi) +static void spi_unlock(const sfud_spi *spi) { xSemaphoreGive(xSemaphore); } /* about 100 microsecond delay */ -static void retry_delay_100us(void) +static void retry_delay_100us(void) { fsleep_microsec(100); } @@ -76,7 +76,7 @@ static void retry_delay_100us(void) * @return {*} * @param {sfud_flash} *flash */ -sfud_err sfud_spi_port_init(sfud_flash *flash) +sfud_err sfud_spi_port_init(sfud_flash *flash) { sfud_err result = SFUD_SUCCESS; @@ -141,7 +141,7 @@ ret: * @param format output format * @param ... args */ -void sfud_log_debug(const char *file, const long line, const char *format, ...) +void sfud_log_debug(const char *file, const long line, const char *format, ...) { va_list args; @@ -160,7 +160,7 @@ void sfud_log_debug(const char *file, const long line, const char *format, ...) * @param format output format * @param ... args */ -void sfud_log_info(const char *format, ...) +void sfud_log_info(const char *format, ...) { va_list args; diff --git a/third-party/spiffs-0.3.7/config.md b/third-party/spiffs-0.3.7/config.md index 221ece58..50d96b4d 100644 --- a/third-party/spiffs-0.3.7/config.md +++ b/third-party/spiffs-0.3.7/config.md @@ -24,8 +24,8 @@ SPIFFS技术手册: #include #include -#include "ft_types.h" -#include "ft_debug.h" +#include "ftypes.h" +#include "fdebug.h" #ifdef _SPIFFS_TEST #include "testrunner.h" diff --git a/third-party/spiffs-0.3.7/inc/spiffs.h b/third-party/spiffs-0.3.7/inc/spiffs.h index 9ba98ba6..d0bd758c 100644 --- a/third-party/spiffs-0.3.7/inc/spiffs.h +++ b/third-party/spiffs-0.3.7/inc/spiffs.h @@ -18,7 +18,8 @@ * * Modify History: * Ver   Who        Date         Changes - * ----- ------     --------    -------------------------------------- + * ----- ------      --------    -------------------------------------- + * 1.0 wangxiaodong 2022/8/9 first release */ /* * spiffs.h diff --git a/third-party/spiffs-0.3.7/ports/fqspi/fqspi_spiffs_port.c b/third-party/spiffs-0.3.7/ports/fqspi/fqspi_spiffs_port.c index 1e780efa..4bddf056 100644 --- a/third-party/spiffs-0.3.7/ports/fqspi/fqspi_spiffs_port.c +++ b/third-party/spiffs-0.3.7/ports/fqspi/fqspi_spiffs_port.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: fqspi_spiffs_port.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:24:47 - * Description:  This files is for - * - * Modify History: + * Description:  This files is for providing spiffs func based on qspi. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/8/9 first release */ /***************************** Include Files *********************************/ @@ -31,8 +32,8 @@ #include "fqspi_spiffs_port.h" /************************** Constant Definitions *****************************/ -#define FSPIFFS_FLASH_START_ADDR (7 * SZ_1M) -#define FSPIFFS_FLASH_SIZE SZ_1M +#define FSPIFFS_FLASH_START_ADDR (7 * SZ_1M) +#define FSPIFFS_FLASH_SIZE SZ_1M /**************************** Type Definitions *******************************/ /************************** Variable Definitions *****************************/ @@ -52,23 +53,23 @@ static s32_t FSpiffsRead(struct spiffs_t *fs, u32_t addr, u32_t size, u8_t *buf) { FASSERT_MSG(fs, "NULL fs instance"); FASSERT_MSG(buf, "NULL buffer"); - if ((FALSE == is_sfud_ready) || (NULL == flash_instance)) - { - FQSPI_ERROR("sfud not ready"); - return FSPIFFS_QSPI_PORT_SFUD_NOT_READY; - } - - sfud_err result = sfud_read(flash_instance, - (u32)addr, - (fsize_t)size, - (u8 *)buf); - if (SFUD_SUCCESS != result) + if ((FALSE == is_sfud_ready) || (NULL == flash_instance)) { - FQSPI_ERROR("read failed: %d", result); + FQSPI_ERROR("SFUD not ready."); + return FSPIFFS_QSPI_PORT_SFUD_NOT_READY; + } + + sfud_err result = sfud_read(flash_instance, + (u32)addr, + (fsize_t)size, + (u8 *)buf); + if (SFUD_SUCCESS != result) + { + FQSPI_ERROR("Read failed: %d", result); return FSPIFFS_QSPI_PORT_SFUD_IO_ERROR; } - FQSPI_DEBUG("sfud read success"); + FQSPI_DEBUG("SFUD read success."); return FSPIFFS_QSPI_PORT_OK; } @@ -76,45 +77,45 @@ static s32_t FSpiffsWrite(struct spiffs_t *fs, u32_t addr, u32_t size, u8_t *buf { FASSERT_MSG(fs, "NULL fs instance"); FASSERT_MSG(buf, "NULL buffer"); - if ((FALSE == is_sfud_ready) || (NULL == flash_instance)) - { - FQSPI_ERROR("sfud not ready"); - return FSPIFFS_QSPI_PORT_SFUD_NOT_READY; - } - - sfud_err result = sfud_write(flash_instance, - (u32)addr, - (fsize_t)size, - (const u8 *)buf); - if (SFUD_SUCCESS != result) + if ((FALSE == is_sfud_ready) || (NULL == flash_instance)) { - FQSPI_ERROR("write failed: %d", result); + FQSPI_ERROR("SFUD not ready."); + return FSPIFFS_QSPI_PORT_SFUD_NOT_READY; + } + + sfud_err result = sfud_write(flash_instance, + (u32)addr, + (fsize_t)size, + (const u8 *)buf); + if (SFUD_SUCCESS != result) + { + FQSPI_ERROR("Write failed: %d.", result); return FSPIFFS_QSPI_PORT_SFUD_IO_ERROR; } - FQSPI_DEBUG("sfud write success"); + FQSPI_DEBUG("SFUD write success."); return FSPIFFS_QSPI_PORT_OK; } static s32_t FSpiffsErase(struct spiffs_t *fs, u32_t addr, u32_t size) { - FASSERT_MSG(fs, "NULL fs instance"); - if ((FALSE == is_sfud_ready) || (NULL == flash_instance)) - { - FQSPI_ERROR("sfud not ready"); - return FSPIFFS_QSPI_PORT_SFUD_NOT_READY; - } - - sfud_err result = sfud_erase(flash_instance, - (u32)addr, - (fsize_t)(size)); - if (SFUD_SUCCESS != result) + FASSERT_MSG(fs, "NULL fs instance"); + if ((FALSE == is_sfud_ready) || (NULL == flash_instance)) { - FQSPI_ERROR("erase failed: %d", result); + FQSPI_ERROR("SFUD not ready."); + return FSPIFFS_QSPI_PORT_SFUD_NOT_READY; + } + + sfud_err result = sfud_erase(flash_instance, + (u32)addr, + (fsize_t)(size)); + if (SFUD_SUCCESS != result) + { + FQSPI_ERROR("Erase failed: %d.", result); return FSPIFFS_QSPI_PORT_SFUD_IO_ERROR; } - FQSPI_DEBUG("sfud erase success"); + FQSPI_DEBUG("SFUD erase success"); return FSPIFFS_QSPI_PORT_OK; } @@ -123,79 +124,79 @@ int FSpiffsQspiInitialize(FSpiffs *const instance) FASSERT(instance); if (FT_COMPONENT_IS_READY == instance->fs_ready) { - FQSPI_ERROR("little-fs already inited and mounted"); + FQSPI_ERROR("little-fs already inited and mounted."); + return FSPIFFS_QSPI_PORT_ALREADY_INITED; + } + + if ((TRUE == is_sfud_ready) || (NULL != flash_instance)) + { + FQSPI_ERROR("SFUD already inited."); return FSPIFFS_QSPI_PORT_ALREADY_INITED; } - - if ((TRUE == is_sfud_ready) || (NULL != flash_instance)) - { - FQSPI_ERROR("sfud already inited"); - return FSPIFFS_QSPI_PORT_ALREADY_INITED; - } - - int sfud_ret = sfud_init(); - if (SFUD_SUCCESS != sfud_ret) - { - FQSPI_ERROR("sfud init failed: %d", sfud_ret); - return FSPIFFS_QSPI_PORT_SFUD_INIT_FAILED; - } - - flash_instance = sfud_get_device(flash_id); - if (NULL == flash_instance) - { - FQSPI_ERROR("get sfud flash failed"); - return FSPIFFS_QSPI_PORT_SFUD_INIT_FAILED; - } - - if ((flash_instance->chip.capacity < (instance->fs_addr + instance->fs_size)) || - (FSPIFFS_LOG_BLOCK_SIZE % flash_instance->chip.erase_gran)) - { - FQSPI_ERROR("flash not support !!! capacity %d < space %d, erase_gran %d %% %d != 0", - flash_instance->chip.capacity, - (instance->fs_addr + instance->fs_size), - FSPIFFS_LOG_BLOCK_SIZE, - flash_instance->chip.erase_gran); - return FSPIFFS_QSPI_PORT_SFUD_INIT_FAILED; - } - - if (flash_instance->chip.capacity < SZ_1M) + + int sfud_ret = sfud_init(); + if (SFUD_SUCCESS != sfud_ret) { - printf("%d KB %s is current selected device.\r\n", - flash_instance->chip.capacity / SZ_1K, - flash_instance->name); + FQSPI_ERROR("SFUD init failed: %d.", sfud_ret); + return FSPIFFS_QSPI_PORT_SFUD_INIT_FAILED; + } + + flash_instance = sfud_get_device(flash_id); + if (NULL == flash_instance) + { + FQSPI_ERROR("Get SFUD flash failed"); + return FSPIFFS_QSPI_PORT_SFUD_INIT_FAILED; + } + + if ((flash_instance->chip.capacity < (instance->fs_addr + instance->fs_size)) || + (FSPIFFS_LOG_BLOCK_SIZE % flash_instance->chip.erase_gran)) + { + FQSPI_ERROR("Flash not support !!! capacity %d < space %d, erase_gran %d %% %d != 0", + flash_instance->chip.capacity, + (instance->fs_addr + instance->fs_size), + FSPIFFS_LOG_BLOCK_SIZE, + flash_instance->chip.erase_gran); + return FSPIFFS_QSPI_PORT_SFUD_INIT_FAILED; + } + + if (flash_instance->chip.capacity < SZ_1M) + { + FQSPI_DEBUG("%d KB %s is current selected device.\r\n", + flash_instance->chip.capacity / SZ_1K, + flash_instance->name); } else { - printf("%d MB %s is current selected device.\r\n", - flash_instance->chip.capacity / SZ_1M, - flash_instance->name); + FQSPI_DEBUG("%d MB %s is current selected device.\r\n", + flash_instance->chip.capacity / SZ_1M, + flash_instance->name); } - is_sfud_ready = TRUE; - /* instance->fs_ready will be set after mount filesystem */; - return FSPIFFS_QSPI_PORT_OK; + is_sfud_ready = TRUE; + /* instance->fs_ready will be set after mount filesystem */; + return FSPIFFS_QSPI_PORT_OK; } void FSpiffsQspiDeInitialize(FSpiffs *const instance) { - memset(instance, 0, sizeof(FSpiffs)); - is_sfud_ready = FALSE; - return; + memset(instance, 0, sizeof(FSpiffs)); + is_sfud_ready = FALSE; + return; } const spiffs_config *FSpiffsQspiGetDefaultConfig(void) { - static const spiffs_config cfg = - { - .phys_addr = FSPIFFS_FLASH_START_ADDR, /* start spiffs at start of spi flash */ - .phys_size = FSPIFFS_FLASH_SIZE, /* flash_capcity in use */ - .phys_erase_block = FSPIFFS_LOG_BLOCK_SIZE, /* according to datasheet */ - .log_block_size = FSPIFFS_LOG_BLOCK_SIZE, /* let us not complicate things */ - .log_page_size = FSPIFFS_LOG_PAGE_SIZE, /* as we said */ - .hal_read_f = FSpiffsRead, - .hal_write_f = FSpiffsWrite, - .hal_erase_f = FSpiffsErase - }; - - return (const spiffs_config *)&cfg; + static const spiffs_config cfg = + { + .phys_addr = FSPIFFS_FLASH_START_ADDR, /* start spiffs at start of spi flash */ + .phys_size = FSPIFFS_FLASH_SIZE, /* flash_capcity in use */ + .phys_erase_block = FSPIFFS_LOG_BLOCK_SIZE, /* according to datasheet */ + .log_block_size = FSPIFFS_LOG_BLOCK_SIZE, /* let us not complicate things */ + .log_page_size = FSPIFFS_LOG_PAGE_SIZE, /* as we said */ + .hal_read_f = FSpiffsRead, + .hal_write_f = FSpiffsWrite, + .hal_erase_f = FSpiffsErase + }; + + return (const spiffs_config *)&cfg; } \ No newline at end of file diff --git a/third-party/spiffs-0.3.7/ports/fqspi/fqspi_spiffs_port.h b/third-party/spiffs-0.3.7/ports/fqspi/fqspi_spiffs_port.h index 983c3107..6674378c 100644 --- a/third-party/spiffs-0.3.7/ports/fqspi/fqspi_spiffs_port.h +++ b/third-party/spiffs-0.3.7/ports/fqspi/fqspi_spiffs_port.h @@ -1,37 +1,39 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: fqspi_spiffs_port.h * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:24:52 - * Description:  This files is for - * - * Modify History: + * Description:  This files is for providing spiffs api based on qspi. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/8/9 first release */ #ifndef FQSPI_SPIFFS_PORT_H #define FQSPI_SPIFFS_PORT_H -#ifdef __cplusplus -extern "C" -{ -#endif /***************************** Include Files *********************************/ #include "ftypes.h" #include "spiffs_port.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /************************** Constant Definitions *****************************/ enum { diff --git a/third-party/spiffs-0.3.7/ports/fspim/fspim_spiffs_port.c b/third-party/spiffs-0.3.7/ports/fspim/fspim_spiffs_port.c index aaaa8b9f..2891fe91 100644 --- a/third-party/spiffs-0.3.7/ports/fspim/fspim_spiffs_port.c +++ b/third-party/spiffs-0.3.7/ports/fspim/fspim_spiffs_port.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: fspim_spiffs_port.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:24:47 - * Description:  This files is for - * - * Modify History: + * Description:  This files is for providing spiffs func based on spi. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 liqiaozhong 2022/4/15 first commit, support Spiffs */ /***************************** Include Files *********************************/ @@ -32,8 +33,8 @@ #include "fspim_spiffs_port.h" /************************** Constant Definitions *****************************/ -#define FSPIFFS_FLASH_START_ADDR 0x0 -#define FSPIFFS_FLASH_SIZE SZ_1M +#define FSPIFFS_FLASH_START_ADDR 0x0 +#define FSPIFFS_FLASH_SIZE SZ_1M /**************************** Type Definitions *******************************/ /************************** Variable Definitions *****************************/ @@ -53,19 +54,19 @@ static s32_t FSpiffsRead(struct spiffs_t *fs, u32_t addr, u32_t size, u8_t *buf) { FASSERT_MSG(fs, "NULL fs instance"); FASSERT_MSG(buf, "NULL buffer"); - if ((FALSE == is_sfud_ready) || (NULL == flash_instance)) - { - FSPIM_ERROR("sfud not ready"); - return FSPIFFS_SPIM_PORT_SFUD_NOT_READY; - } - - sfud_err result = sfud_read(flash_instance, - (u32)addr, - (fsize_t)size, - (u8 *)buf); - if (SFUD_SUCCESS != result) + if ((FALSE == is_sfud_ready) || (NULL == flash_instance)) { - FSPIM_ERROR("read failed: %d", result); + FSPIM_ERROR("sfud not ready"); + return FSPIFFS_SPIM_PORT_SFUD_NOT_READY; + } + + sfud_err result = sfud_read(flash_instance, + (u32)addr, + (fsize_t)size, + (u8 *)buf); + if (SFUD_SUCCESS != result) + { + FSPIM_ERROR("Read failed: %d", result); return FSPIFFS_SPIM_PORT_SFUD_IO_ERROR; } @@ -77,19 +78,19 @@ static s32_t FSpiffsWrite(struct spiffs_t *fs, u32_t addr, u32_t size, u8_t *buf { FASSERT_MSG(fs, "NULL fs instance"); FASSERT_MSG(buf, "NULL buffer"); - if ((FALSE == is_sfud_ready) || (NULL == flash_instance)) - { - FSPIM_ERROR("sfud not ready"); - return FSPIFFS_SPIM_PORT_SFUD_NOT_READY; - } - - sfud_err result = sfud_write(flash_instance, - (u32)addr, - (fsize_t)size, - (const u8 *)buf); - if (SFUD_SUCCESS != result) + if ((FALSE == is_sfud_ready) || (NULL == flash_instance)) { - FSPIM_ERROR("write failed: %d", result); + FSPIM_ERROR("sfud not ready"); + return FSPIFFS_SPIM_PORT_SFUD_NOT_READY; + } + + sfud_err result = sfud_write(flash_instance, + (u32)addr, + (fsize_t)size, + (const u8 *)buf); + if (SFUD_SUCCESS != result) + { + FSPIM_ERROR("Write failed: %d", result); return FSPIFFS_SPIM_PORT_SFUD_IO_ERROR; } @@ -99,19 +100,19 @@ static s32_t FSpiffsWrite(struct spiffs_t *fs, u32_t addr, u32_t size, u8_t *buf static s32_t FSpiffsErase(struct spiffs_t *fs, u32_t addr, u32_t size) { - FASSERT_MSG(fs, "NULL fs instance"); - if ((FALSE == is_sfud_ready) || (NULL == flash_instance)) - { - FSPIM_ERROR("sfud not ready"); - return FSPIFFS_SPIM_PORT_SFUD_NOT_READY; - } - - sfud_err result = sfud_erase(flash_instance, - (u32)addr, - (fsize_t)(size)); - if (SFUD_SUCCESS != result) + FASSERT_MSG(fs, "NULL fs instance"); + if ((FALSE == is_sfud_ready) || (NULL == flash_instance)) { - FSPIM_ERROR("erase failed: %d", result); + FSPIM_ERROR("sfud not ready"); + return FSPIFFS_SPIM_PORT_SFUD_NOT_READY; + } + + sfud_err result = sfud_erase(flash_instance, + (u32)addr, + (fsize_t)(size)); + if (SFUD_SUCCESS != result) + { + FSPIM_ERROR("Erase failed: %d", result); return FSPIFFS_SPIM_PORT_SFUD_IO_ERROR; } @@ -127,76 +128,76 @@ int FSpiffsSpimInitialize(FSpiffs *const instance) FSPIM_ERROR("little-fs already inited and mounted"); return FSPIFFS_SPIM_PORT_ALREADY_INITED; } - - if ((TRUE == is_sfud_ready) || (NULL != flash_instance)) - { + + if ((TRUE == is_sfud_ready) || (NULL != flash_instance)) + { FSPIM_ERROR("sfud already inited"); - return FSPIFFS_SPIM_PORT_ALREADY_INITED; - } - - int sfud_ret = sfud_init(); - if (SFUD_SUCCESS != sfud_ret) - { - FSPIM_ERROR("sfud init failed: %d", sfud_ret); - return FSPIFFS_SPIM_PORT_SFUD_INIT_FAILED; - } - - flash_instance = sfud_get_device(flash_id); - if (NULL == flash_instance) - { - FSPIM_ERROR("get sfud flash failed"); - return FSPIFFS_SPIM_PORT_SFUD_INIT_FAILED; - } - - if ((flash_instance->chip.capacity < (instance->fs_addr + instance->fs_size)) || - (FSPIFFS_LOG_BLOCK_SIZE % flash_instance->chip.erase_gran)) - { - FSPIM_ERROR("flash not support !!! capacity %d < space %d, erase_gran %d %% %d != 0", - flash_instance->chip.capacity, - (instance->fs_addr + instance->fs_size), - FSPIFFS_LOG_BLOCK_SIZE, - flash_instance->chip.erase_gran); - return FSPIFFS_SPIM_PORT_SFUD_INIT_FAILED; - } - - if (flash_instance->chip.capacity < SZ_1M) + return FSPIFFS_SPIM_PORT_ALREADY_INITED; + } + + int sfud_ret = sfud_init(); + if (SFUD_SUCCESS != sfud_ret) { - printf("%d KB %s is current selected device.\r\n", - flash_instance->chip.capacity / SZ_1K, - flash_instance->name); + FSPIM_ERROR("sfud init failed: %d", sfud_ret); + return FSPIFFS_SPIM_PORT_SFUD_INIT_FAILED; + } + + flash_instance = sfud_get_device(flash_id); + if (NULL == flash_instance) + { + FSPIM_ERROR("Get sfud flash failed"); + return FSPIFFS_SPIM_PORT_SFUD_INIT_FAILED; + } + + if ((flash_instance->chip.capacity < (instance->fs_addr + instance->fs_size)) || + (FSPIFFS_LOG_BLOCK_SIZE % flash_instance->chip.erase_gran)) + { + FSPIM_ERROR("Flash not support !!! capacity %d < space %d, erase_gran %d %% %d != 0", + flash_instance->chip.capacity, + (instance->fs_addr + instance->fs_size), + FSPIFFS_LOG_BLOCK_SIZE, + flash_instance->chip.erase_gran); + return FSPIFFS_SPIM_PORT_SFUD_INIT_FAILED; + } + + if (flash_instance->chip.capacity < SZ_1M) + { + printf("%d KB %s is current selected device.\r\n", + flash_instance->chip.capacity / SZ_1K, + flash_instance->name); } else { - printf("%d MB %s is current selected device.\r\n", - flash_instance->chip.capacity / SZ_1M, - flash_instance->name); + printf("%d MB %s is current selected device.\r\n", + flash_instance->chip.capacity / SZ_1M, + flash_instance->name); } - is_sfud_ready = TRUE; - /* instance->fs_ready will be set after mount filesystem */; - return FSPIFFS_SPIM_PORT_OK; + is_sfud_ready = TRUE; + /* instance->fs_ready will be set after mount filesystem */; + return FSPIFFS_SPIM_PORT_OK; } void FSpiffsSpimDeInitialize(FSpiffs *const instance) { - memset(instance, 0, sizeof(FSpiffs)); - is_sfud_ready = FALSE; - return; + memset(instance, 0, sizeof(FSpiffs)); + is_sfud_ready = FALSE; + return; } const spiffs_config *FSpiffsSpimGetDefaultConfig(void) { - static const spiffs_config cfg = - { - .phys_addr = FSPIFFS_FLASH_START_ADDR, /* start spiffs at start of spi flash */ - .phys_size = FSPIFFS_FLASH_SIZE, /* flash_capcity in use */ - .phys_erase_block = FSPIFFS_LOG_BLOCK_SIZE, /* according to datasheet */ - .log_block_size = FSPIFFS_LOG_BLOCK_SIZE, /* let us not complicate things */ - .log_page_size = FSPIFFS_LOG_PAGE_SIZE, /* as we said */ - .hal_read_f = FSpiffsRead, - .hal_write_f = FSpiffsWrite, - .hal_erase_f = FSpiffsErase - }; - - return (const spiffs_config *)&cfg; + static const spiffs_config cfg = + { + .phys_addr = FSPIFFS_FLASH_START_ADDR, /* start spiffs at start of spi flash */ + .phys_size = FSPIFFS_FLASH_SIZE, /* flash_capcity in use */ + .phys_erase_block = FSPIFFS_LOG_BLOCK_SIZE, /* according to datasheet */ + .log_block_size = FSPIFFS_LOG_BLOCK_SIZE, /* let us not complicate things */ + .log_page_size = FSPIFFS_LOG_PAGE_SIZE, /* as we said */ + .hal_read_f = FSpiffsRead, + .hal_write_f = FSpiffsWrite, + .hal_erase_f = FSpiffsErase + }; + + return (const spiffs_config *)&cfg; } \ No newline at end of file diff --git a/third-party/spiffs-0.3.7/ports/fspim/fspim_spiffs_port.h b/third-party/spiffs-0.3.7/ports/fspim/fspim_spiffs_port.h index 57fd335e..6ebc4452 100644 --- a/third-party/spiffs-0.3.7/ports/fspim/fspim_spiffs_port.h +++ b/third-party/spiffs-0.3.7/ports/fspim/fspim_spiffs_port.h @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: fspim_spiffs_port.h * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:24:52 - * Description:  This files is for - * - * Modify History: + * Description:  This files is for providing spiffs api based on spi. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 liqiaozhong 2022/4/15 first commit, support Spiffs */ #ifndef FSPIM_SPIFFS_PORT_H diff --git a/third-party/spiffs-0.3.7/ports/spiffs_config.h b/third-party/spiffs-0.3.7/ports/spiffs_config.h index 055b3a8d..f8f1e189 100644 --- a/third-party/spiffs-0.3.7/ports/spiffs_config.h +++ b/third-party/spiffs-0.3.7/ports/spiffs_config.h @@ -5,8 +5,8 @@ * Author: petera */ -#ifndef SPIFFS_CONFIG_H_ -#define SPIFFS_CONFIG_H_ +#ifndef SPIFFS_CONFIG_H +#define SPIFFS_CONFIG_H // ----------- 8< ------------ // Following includes are for the linux test build of spiffs @@ -20,8 +20,13 @@ #include "ftypes.h" #include "fdebug.h" +#ifdef __cplusplus +extern "C" +{ +#endif + #ifdef _SPIFFS_TEST -#include "testrunner.h" + #include "testrunner.h" #endif // ----------- >8 ------------ @@ -30,23 +35,23 @@ // port debug printfs // Set generic spiffs debug output call. #ifndef SPIFFS_DBG -#define SPIFFS_DBG(_f, ...) FT_DEBUG_PRINT_D("SPIFFS", _f, ##__VA_ARGS__) + #define SPIFFS_DBG(_f, ...) FT_DEBUG_PRINT_D("SPIFFS", _f, ##__VA_ARGS__) #endif // Set spiffs debug output call for garbage collecting. #ifndef SPIFFS_GC_DBG -#define SPIFFS_GC_DBG(_f, ...) FT_DEBUG_PRINT_D("SPIFFS-GC", _f, ##__VA_ARGS__) + #define SPIFFS_GC_DBG(_f, ...) FT_DEBUG_PRINT_D("SPIFFS-GC", _f, ##__VA_ARGS__) #endif // Set spiffs debug output call for caching. #ifndef SPIFFS_CACHE_DBG -#define SPIFFS_CACHE_DBG(_f, ...) FT_DEBUG_PRINT_D("SPIFFS-CACHE", _f, ##__VA_ARGS__) + #define SPIFFS_CACHE_DBG(_f, ...) FT_DEBUG_PRINT_D("SPIFFS-CACHE", _f, ##__VA_ARGS__) #endif // Set spiffs debug output call for system consistency checks. #ifndef SPIFFS_CHECK_DBG -#define SPIFFS_CHECK_DBG(_f, ...) FT_DEBUG_PRINT_D("SPIFFS-CHECK", _f, ##__VA_ARGS__) + #define SPIFFS_CHECK_DBG(_f, ...) FT_DEBUG_PRINT_D("SPIFFS-CHECK", _f, ##__VA_ARGS__) #endif // Set spiffs debug output call for all api invocations. #ifndef SPIFFS_API_DBG -#define SPIFFS_API_DBG(_f, ...) FT_DEBUG_PRINT_D("SPIFFS-API", _f, ##__VA_ARGS__) + #define SPIFFS_API_DBG(_f, ...) FT_DEBUG_PRINT_D("SPIFFS-API", _f, ##__VA_ARGS__) #endif @@ -54,35 +59,35 @@ // Defines spiffs debug print formatters // some general signed number #ifndef _SPIPRIi -#define _SPIPRIi "%d" + #define _SPIPRIi "%d" #endif // address #ifndef _SPIPRIad -#define _SPIPRIad "%08x" + #define _SPIPRIad "%08x" #endif // block #ifndef _SPIPRIbl -#define _SPIPRIbl "%04x" + #define _SPIPRIbl "%04x" #endif // page #ifndef _SPIPRIpg -#define _SPIPRIpg "%04x" + #define _SPIPRIpg "%04x" #endif // span index #ifndef _SPIPRIsp -#define _SPIPRIsp "%04x" + #define _SPIPRIsp "%04x" #endif // file descriptor #ifndef _SPIPRIfd -#define _SPIPRIfd "%d" + #define _SPIPRIfd "%d" #endif // file object id #ifndef _SPIPRIid -#define _SPIPRIid "%04x" + #define _SPIPRIid "%04x" #endif // file flags #ifndef _SPIPRIfl -#define _SPIPRIfl "%02x" + #define _SPIPRIfl "%02x" #endif @@ -90,40 +95,40 @@ // for filedescriptor and cache buffers. Once decided for a configuration, // this can be disabled to reduce flash. #ifndef SPIFFS_BUFFER_HELP -#define SPIFFS_BUFFER_HELP 0 + #define SPIFFS_BUFFER_HELP 0 #endif // Enables/disable memory read caching of nucleus file system operations. // If enabled, memory area must be provided for cache in SPIFFS_mount. #ifndef SPIFFS_CACHE -#define SPIFFS_CACHE 1 /* 在RAM中为SPIFFS提供缓存区 */ + #define SPIFFS_CACHE 1 /* 在RAM中为SPIFFS提供缓存区 */ #endif #if SPIFFS_CACHE -// Enables memory write caching for file descriptors in hydrogen -#ifndef SPIFFS_CACHE_WR -#define SPIFFS_CACHE_WR 1 /* 使能文件描述符写缓存 */ -#endif + // Enables memory write caching for file descriptors in hydrogen + #ifndef SPIFFS_CACHE_WR + #define SPIFFS_CACHE_WR 1 /* 使能文件描述符写缓存 */ + #endif -// Enable/disable statistics on caching. Debug/test purpose only. -#ifndef SPIFFS_CACHE_STATS -#define SPIFFS_CACHE_STATS 0 -#endif + // Enable/disable statistics on caching. Debug/test purpose only. + #ifndef SPIFFS_CACHE_STATS + #define SPIFFS_CACHE_STATS 0 + #endif #endif // Always check header of each accessed page to ensure consistent state. // If enabled it will increase number of reads, will increase flash. #ifndef SPIFFS_PAGE_CHECK -#define SPIFFS_PAGE_CHECK 1 /* 检查每页是否可以访问 */ + #define SPIFFS_PAGE_CHECK 1 /* 检查每页是否可以访问 */ #endif // Define maximum number of gc runs to perform to reach desired free pages. #ifndef SPIFFS_GC_MAX_RUNS -#define SPIFFS_GC_MAX_RUNS 5 + #define SPIFFS_GC_MAX_RUNS 5 #endif // Enable/disable statistics on gc. Debug/test purpose only. #ifndef SPIFFS_GC_STATS -#define SPIFFS_GC_STATS 0 + #define SPIFFS_GC_STATS 0 #endif // Garbage collecting examines all pages in a block which and sums up @@ -136,23 +141,23 @@ // Garbage collecting heuristics - weight used for deleted pages. #ifndef SPIFFS_GC_HEUR_W_DELET -#define SPIFFS_GC_HEUR_W_DELET (5) + #define SPIFFS_GC_HEUR_W_DELET (5) #endif // Garbage collecting heuristics - weight used for used pages. #ifndef SPIFFS_GC_HEUR_W_USED -#define SPIFFS_GC_HEUR_W_USED (-1) + #define SPIFFS_GC_HEUR_W_USED (-1) #endif // Garbage collecting heuristics - weight used for time between // last erased and erase of this block. #ifndef SPIFFS_GC_HEUR_W_ERASE_AGE -#define SPIFFS_GC_HEUR_W_ERASE_AGE (50) + #define SPIFFS_GC_HEUR_W_ERASE_AGE (50) #endif // Object name maximum length. Note that this length include the // zero-termination character, meaning maximum string of characters // can at most be SPIFFS_OBJ_NAME_LEN - 1. #ifndef SPIFFS_OBJ_NAME_LEN -#define SPIFFS_OBJ_NAME_LEN (32) /* 文件名最大长度为32字节 */ + #define SPIFFS_OBJ_NAME_LEN (32) /* 文件名最大长度为32字节 */ #endif // Maximum length of the metadata associated with an object. @@ -166,14 +171,14 @@ // logical_page_size - (SPIFFS_OBJ_NAME_LEN + sizeof(spiffs_page_header) + // spiffs_object_ix_header fields + at least some LUT entries) #ifndef SPIFFS_OBJ_META_LEN -#define SPIFFS_OBJ_META_LEN (0) + #define SPIFFS_OBJ_META_LEN (0) #endif // Size of buffer allocated on stack used when copying data. // Lower value generates more read/writes. No meaning having it bigger // than logical page size. #ifndef SPIFFS_COPY_BUFFER_STACK -#define SPIFFS_COPY_BUFFER_STACK (64) + #define SPIFFS_COPY_BUFFER_STACK (64) #endif // Enable this to have an identifiable spiffs filesystem. This will look for @@ -181,18 +186,18 @@ // not on mount point. If not, SPIFFS_format must be called prior to mounting // again. #ifndef SPIFFS_USE_MAGIC -#define SPIFFS_USE_MAGIC (1) /* SPIFF会利用Magic num去检查Flash中的文件系统是否ok */ + #define SPIFFS_USE_MAGIC (1) /* SPIFF会利用Magic num去检查Flash中的文件系统是否ok */ #endif #if SPIFFS_USE_MAGIC -// Only valid when SPIFFS_USE_MAGIC is enabled. If SPIFFS_USE_MAGIC_LENGTH is -// enabled, the magic will also be dependent on the length of the filesystem. -// For example, a filesystem configured and formatted for 4 megabytes will not -// be accepted for mounting with a configuration defining the filesystem as 2 -// megabytes. -#ifndef SPIFFS_USE_MAGIC_LENGTH -#define SPIFFS_USE_MAGIC_LENGTH (1) -#endif + // Only valid when SPIFFS_USE_MAGIC is enabled. If SPIFFS_USE_MAGIC_LENGTH is + // enabled, the magic will also be dependent on the length of the filesystem. + // For example, a filesystem configured and formatted for 4 megabytes will not + // be accepted for mounting with a configuration defining the filesystem as 2 + // megabytes. + #ifndef SPIFFS_USE_MAGIC_LENGTH + #define SPIFFS_USE_MAGIC_LENGTH (1) + #endif #endif extern void FSpiffsSemLock(void); @@ -203,49 +208,49 @@ extern void FSpiffsSemUnlock(void); // define this to enter a mutex if you're running on a multithreaded system #ifndef SPIFFS_LOCK -#define SPIFFS_LOCK(fs) FSpiffsSemLock() + #define SPIFFS_LOCK(fs) FSpiffsSemLock() #endif // define this to exit a mutex if you're running on a multithreaded system #ifndef SPIFFS_UNLOCK -#define SPIFFS_UNLOCK(fs) FSpiffsSemUnlock() + #define SPIFFS_UNLOCK(fs) FSpiffsSemUnlock() #endif // Enable if only one spiffs instance with constant configuration will exist // on the target. This will reduce calculations, flash and memory accesses. // Parts of configuration must be defined below instead of at time of mount. #ifndef SPIFFS_SINGLETON -#define SPIFFS_SINGLETON 0 /* 只使用单个SPIFFS实例 */ + #define SPIFFS_SINGLETON 0 /* 只使用单个SPIFFS实例 */ #endif #if SPIFFS_SINGLETON -// Instead of giving parameters in config struct, singleton build must -// give parameters in defines below. -#ifndef SPIFFS_CFG_PHYS_SZ -#define SPIFFS_CFG_PHYS_SZ(ignore) (1024*1024*2) /* flash 容量 2MB */ -#endif -#ifndef SPIFFS_CFG_PHYS_ERASE_SZ -#define SPIFFS_CFG_PHYS_ERASE_SZ(ignore) (65536) /* flash 擦除单位 */ -#endif -#ifndef SPIFFS_CFG_PHYS_ADDR -#define SPIFFS_CFG_PHYS_ADDR(ignore) (0) /* flash 起始物理地址 */ -#endif -#ifndef SPIFFS_CFG_LOG_PAGE_SZ -#define SPIFFS_CFG_LOG_PAGE_SZ(ignore) (256) /* 页大小,写数据的单位,为256的整数倍 */ -#endif -#ifndef SPIFFS_CFG_LOG_BLOCK_SZ -#define SPIFFS_CFG_LOG_BLOCK_SZ(ignore) (65536) /* 块大小,一般与 flash 擦除单位保持一致 */ -#endif + // Instead of giving parameters in config struct, singleton build must + // give parameters in defines below. + #ifndef SPIFFS_CFG_PHYS_SZ + #define SPIFFS_CFG_PHYS_SZ(ignore) (1024*1024*2) /* flash 容量 2MB */ + #endif + #ifndef SPIFFS_CFG_PHYS_ERASE_SZ + #define SPIFFS_CFG_PHYS_ERASE_SZ(ignore) (65536) /* flash 擦除单位 */ + #endif + #ifndef SPIFFS_CFG_PHYS_ADDR + #define SPIFFS_CFG_PHYS_ADDR(ignore) (0) /* flash 起始物理地址 */ + #endif + #ifndef SPIFFS_CFG_LOG_PAGE_SZ + #define SPIFFS_CFG_LOG_PAGE_SZ(ignore) (256) /* 页大小,写数据的单位,为256的整数倍 */ + #endif + #ifndef SPIFFS_CFG_LOG_BLOCK_SZ + #define SPIFFS_CFG_LOG_BLOCK_SZ(ignore) (65536) /* 块大小,一般与 flash 擦除单位保持一致 */ + #endif #endif // Enable this if your target needs aligned data for index tables #ifndef SPIFFS_ALIGNED_OBJECT_INDEX_TABLES -#define SPIFFS_ALIGNED_OBJECT_INDEX_TABLES 1 /* 文件索引使用对齐内存 */ + #define SPIFFS_ALIGNED_OBJECT_INDEX_TABLES 1 /* 文件索引使用对齐内存 */ #endif // Enable this if you want the HAL callbacks to be called with the spiffs struct #ifndef SPIFFS_HAL_CALLBACK_EXTRA -#define SPIFFS_HAL_CALLBACK_EXTRA 1 + #define SPIFFS_HAL_CALLBACK_EXTRA 1 #endif // Enable this if you want to add an integer offset to all file handles @@ -255,7 +260,7 @@ extern void FSpiffsSemUnlock(void); // NB: This adds config field fh_ix_offset in the configuration struct when // mounting, which must be defined. #ifndef SPIFFS_FILEHDL_OFFSET -#define SPIFFS_FILEHDL_OFFSET 0 + #define SPIFFS_FILEHDL_OFFSET 0 #endif // Enable this to compile a read only version of spiffs. @@ -269,7 +274,7 @@ extern void FSpiffsSemUnlock(void); // returned. // Might be useful for e.g. bootloaders and such. #ifndef SPIFFS_READ_ONLY -#define SPIFFS_READ_ONLY 0 + #define SPIFFS_READ_ONLY 0 #endif // Enable this to add a temporal file cache using the fd buffer. @@ -291,7 +296,7 @@ extern void FSpiffsSemUnlock(void); // directly. If all available descriptors become opened, all cache memory is // lost. #ifndef SPIFFS_TEMPORAL_FD_CACHE -#define SPIFFS_TEMPORAL_FD_CACHE 1 /* 启用此选项可优化文件的打开。spiffs 获得的文件描述符越多,缓存就越有效。请注意,这会向每个文件描述符添加额外的 6 个字节 */ + #define SPIFFS_TEMPORAL_FD_CACHE 1 /* 启用此选项可优化文件的打开。spiffs 获得的文件描述符越多,缓存就越有效。请注意,这会向每个文件描述符添加额外的 6 个字节 */ #endif // Temporal file cache hit score. Each time a file is opened, all cached files @@ -300,7 +305,7 @@ extern void FSpiffsSemUnlock(void); // value for the specific access patterns of the application. However, it must // be between 1 (no gain for hitting a cached entry often) and 255. #ifndef SPIFFS_TEMPORAL_CACHE_HIT_SCORE -#define SPIFFS_TEMPORAL_CACHE_HIT_SCORE 4 + #define SPIFFS_TEMPORAL_CACHE_HIT_SCORE 4 #endif // Enable to be able to map object indices to memory. @@ -316,35 +321,35 @@ extern void FSpiffsSemUnlock(void); // file is modified in some way. The index buffer is tied to the file // descriptor. #ifndef SPIFFS_IX_MAP -#define SPIFFS_IX_MAP 1 + #define SPIFFS_IX_MAP 1 #endif // Set SPIFFS_TEST_VISUALISATION to non-zero to enable SPIFFS_vis function // in the api. This function will visualize all filesystem using given printf // function. #ifndef SPIFFS_TEST_VISUALISATION -#define SPIFFS_TEST_VISUALISATION 1 + #define SPIFFS_TEST_VISUALISATION 1 #endif #if SPIFFS_TEST_VISUALISATION -#ifndef spiffs_printf -#define spiffs_printf(...) printf(__VA_ARGS__) -#endif -// spiffs_printf argument for a free page -#ifndef SPIFFS_TEST_VIS_FREE_STR -#define SPIFFS_TEST_VIS_FREE_STR "_" -#endif -// spiffs_printf argument for a deleted page -#ifndef SPIFFS_TEST_VIS_DELE_STR -#define SPIFFS_TEST_VIS_DELE_STR "/" -#endif -// spiffs_printf argument for an index page for given object id -#ifndef SPIFFS_TEST_VIS_INDX_STR -#define SPIFFS_TEST_VIS_INDX_STR(id) "i" -#endif -// spiffs_printf argument for a data page for given object id -#ifndef SPIFFS_TEST_VIS_DATA_STR -#define SPIFFS_TEST_VIS_DATA_STR(id) "d" -#endif + #ifndef spiffs_printf + #define spiffs_printf(...) printf(__VA_ARGS__) + #endif + // spiffs_printf argument for a free page + #ifndef SPIFFS_TEST_VIS_FREE_STR + #define SPIFFS_TEST_VIS_FREE_STR "_" + #endif + // spiffs_printf argument for a deleted page + #ifndef SPIFFS_TEST_VIS_DELE_STR + #define SPIFFS_TEST_VIS_DELE_STR "/" + #endif + // spiffs_printf argument for an index page for given object id + #ifndef SPIFFS_TEST_VIS_INDX_STR + #define SPIFFS_TEST_VIS_INDX_STR(id) "i" + #endif + // spiffs_printf argument for a data page for given object id + #ifndef SPIFFS_TEST_VIS_DATA_STR + #define SPIFFS_TEST_VIS_DATA_STR(id) "d" + #endif #endif /* typedefs for porting */ @@ -375,4 +380,8 @@ typedef u16_t spiffs_obj_id; // i.e. (spiffs_file_system_size / log_page_size) - 1 typedef u16_t spiffs_span_ix; +#ifdef __cplusplus +} +#endif + #endif /* SPIFFS_CONFIG_H_ */ diff --git a/third-party/spiffs-0.3.7/ports/spiffs_port.c b/third-party/spiffs-0.3.7/ports/spiffs_port.c index 190ca0a9..9f6b8e9a 100644 --- a/third-party/spiffs-0.3.7/ports/spiffs_port.c +++ b/third-party/spiffs-0.3.7/ports/spiffs_port.c @@ -1,24 +1,25 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: spiffs_port.c * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:24:47 - * Description:  This files is for - * - * Modify History: + * Description:  This files is for providing func that divide sfud api into qspi and spi. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/8/9 first release */ /***************************** Include Files *********************************/ @@ -32,10 +33,10 @@ #include "spiffs_port.h" #ifdef CONFIG_SPIFFS_ON_FSPIM_SFUD -#include "fspim_spiffs_port.h" + #include "fspim_spiffs_port.h" #endif #ifdef CONFIG_SPIFFS_ON_FQSPI_SFUD -#include "fqspi_spiffs_port.h" + #include "fqspi_spiffs_port.h" #endif @@ -67,7 +68,7 @@ void FSpiffsSemCreate(void) void FSpiffsSemDelete(void) { - vSemaphoreDelete(xSpiffsSemaphore); + vSemaphoreDelete(xSpiffsSemaphore); } int FSpiffsInitialize(FSpiffs *const instance, FSpiffsPortType type) diff --git a/third-party/spiffs-0.3.7/ports/spiffs_port.h b/third-party/spiffs-0.3.7/ports/spiffs_port.h index ea7e1983..0a5465a4 100644 --- a/third-party/spiffs-0.3.7/ports/spiffs_port.h +++ b/third-party/spiffs-0.3.7/ports/spiffs_port.h @@ -1,38 +1,41 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: spiffs_port.h * Date: 2022-02-10 14:53:42 * LastEditTime: 2022-02-18 08:24:52 - * Description:  This files is for - * - * Modify History: + * Description:  This files is for giving tolal spiffs init api. + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- + * 1.0 wangxiaodong 2022/8/9 first release */ -#ifndef SPIFFS_PORT_H -#define SPIFFS_PORT_H +#ifndef SPIFFS_PORT_H +#define SPIFFS_PORT_H -#ifdef __cplusplus -extern "C" -{ -#endif /***************************** Include Files *********************************/ #include "ftypes.h" #include "spiffs.h" /************************** Constant Definitions *****************************/ + +#ifdef __cplusplus +extern "C" +{ +#endif + typedef enum { FSPIFFS_PORT_TO_FSPIM = 0, @@ -46,7 +49,7 @@ enum /**************************** Type Definitions *******************************/ typedef struct spiffs_t spiffs; -typedef struct +typedef struct { spiffs fs; u32 fs_ready; diff --git a/third-party/third-party.mk b/third-party/third-party.mk index fcf058cc..7b25d263 100644 --- a/third-party/third-party.mk +++ b/third-party/third-party.mk @@ -9,6 +9,8 @@ SRC_DIR += $(THIRD_PARTY_CUR_DIR)/freertos/portable/MemMang SRC_DIR += $(THIRD_PARTY_CUR_DIR)/freertos/portable SRC_DIR += $(THIRD_PARTY_CUR_DIR)/freertos +INC_DIR += $(THIRD_PARTY_CUR_DIR)/freertos/portable/GCC/ft_platform + ifdef CONFIG_TARGET_ARMV8_AARCH64 SRC_DIR += $(THIRD_PARTY_CUR_DIR)/freertos/portable/GCC/ft_platform/aarch64 INC_DIR += $(THIRD_PARTY_CUR_DIR)/freertos/portable/GCC/ft_platform/aarch64 @@ -21,44 +23,44 @@ endif #CONFIG_TARGET_ARMV8_AARCH32 ifdef CONFIG_USE_LWIP -# src code of lwip -SRC_DIR += $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/api \ - $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/core \ - $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/core/ipv4 \ - $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/core/ipv6 \ - $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/netif \ - $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/port - -INC_DIR += $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/include \ - $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/include/compat \ - $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/include/lwip \ - $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/include/lwip/apps \ - $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/include/lwip/priv \ - $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/include/lwip/port \ - $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/include/netif \ - $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/port - -# src code of ports -ifdef CONFIG_LWIP_FGMAC -INC_DIR += $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/ports/fgmac \ - $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/ports/fgmac/arch - -SRC_DIR += $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/ports/fgmac \ - $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/ports/fgmac/arch -endif -ifdef CONFIG_LWIP_FXMAC -INC_DIR += $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/ports/fxmac \ - $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/ports/fxmac/arch \ - $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/apps/ping \ - $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/ports +include $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/lwip_freertos.mk -SRC_DIR += $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/ports/fxmac \ - $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/ports/fxmac/arch \ - $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/apps/ping \ - $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/ports - -endif +# src code of lwip +# SRC_DIR += $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/api \ +# $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/core \ +# $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/core/ipv4 \ +# $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/core/ipv6 \ +# $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/netif \ +# $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/ports \ +# $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/ports/arch \ +# $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/apps/if + +# INC_DIR += $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/include \ +# $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/include/compat \ +# $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/include/lwip \ +# $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/include/lwip/apps \ +# $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/include/lwip/priv \ +# $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/include/lwip/port \ +# $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/include/netif \ +# $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/ports \ +# $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/ports/arch + +# EXCL_SRC += $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/netif/slipif.c \ +# $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/ports/arch/sys_arch_raw.c + +# # src code of ports +# ifdef CONFIG_LWIP_FGMAC +# INC_DIR += $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/ports/rtos/fgmac + +# SRC_DIR += $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/ports/rtos/fgmac +# endif + +# ifdef CONFIG_LWIP_FXMAC +# INC_DIR += $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/ports/rtos/fxmac +# SRC_DIR += $(THIRD_PARTY_CUR_DIR)/lwip-2.1.2/ports/rtos/fxmac + +# endif endif #CONFIG_USE_LWIP @@ -113,38 +115,11 @@ ifdef CONFIG_USE_BACKTRACE SRC_DIR += $(THIRD_PARTY_CUR_DIR)/backtrace endif #CONFIG_USE_BACKTRACE +ifdef CONFIG_USE_FATFS_0_1_4 -ifdef CONFIG_USE_FATFS - - INC_DIR += $(THIRD_PARTY_CUR_DIR)/fatfs-0.1.3 - SRC_DIR += $(THIRD_PARTY_CUR_DIR)/fatfs-0.1.3 - - ifdef CONFIG_SELECT_FATFS_RAM_DISK - INC_DIR += $(THIRD_PARTY_CUR_DIR)/fatfs-0.1.3/port/ramdisk - SRC_DIR += $(THIRD_PARTY_CUR_DIR)/fatfs-0.1.3/port/ramdisk - endif - - ifdef CONFIG_SELECT_FATFS_FSDMMC - INC_DIR += $(THIRD_PARTY_CUR_DIR)/fatfs-0.1.3/port/fsdmmc - SRC_DIR += $(THIRD_PARTY_CUR_DIR)/fatfs-0.1.3/port/fsdmmc - endif - - ifdef CONFIG_SELECT_FATFS_FSATA_PCIE - INC_DIR += $(THIRD_PARTY_CUR_DIR)/fatfs-0.1.3/port/fsata_pcie - SRC_DIR += $(THIRD_PARTY_CUR_DIR)/fatfs-0.1.3/port/fsata_pcie - endif - - ifdef CONFIG_SELECT_FATFS_FSATA_CONTROLLER - INC_DIR += $(THIRD_PARTY_CUR_DIR)/fatfs-0.1.3/port/fsata_controller - SRC_DIR += $(THIRD_PARTY_CUR_DIR)/fatfs-0.1.3/port/fsata_controller - endif - - ifdef CONFIG_SELECT_FATFS_USB - INC_DIR += $(THIRD_PARTY_CUR_DIR)/fatfs-0.1.3/port/fusb_pcie - SRC_DIR += $(THIRD_PARTY_CUR_DIR)/fatfs-0.1.3/port/fusb_pcie - endif -endif #CONFIG_USE_FATFS +include $(THIRD_PARTY_CUR_DIR)/fatfs-0.1.4/fatfs.mk +endif #CONFIG_USE_FATFS_0_1_4 ifdef CONFIG_USE_SFUD @@ -219,18 +194,8 @@ ifdef CONFIG_USE_SDMMC_CMD $(shell export PATH=$(THIRD_PARTY_CUR_DIR)/sdmmc-1.0:$PATH) - INC_DIR += $(THIRD_PARTY_CUR_DIR)/sdmmc-1.0 \ - $(THIRD_PARTY_CUR_DIR)/sdmmc-1.0/inc \ - $(THIRD_PARTY_CUR_DIR)/sdmmc-1.0/src - SRC_DIR += $(THIRD_PARTY_CUR_DIR)/sdmmc-1.0 \ - $(THIRD_PARTY_CUR_DIR)/sdmmc-1.0/src - - ifdef CONFIG_SDMMC_PORT_FSDIO - INC_DIR += $(THIRD_PARTY_CUR_DIR)/sdmmc-1.0/port \ - $(THIRD_PARTY_CUR_DIR)/sdmmc-1.0/port/fsdio - SRC_DIR += $(THIRD_PARTY_CUR_DIR)/sdmmc-1.0/port \ - $(THIRD_PARTY_CUR_DIR)/sdmmc-1.0/port/fsdio - endif #CONFIG_SDMMC_PORT_FSDIO +include $(THIRD_PARTY_CUR_DIR)/sdmmc-1.0/sdmmc.mk + endif #CONFIG_USE_SDMMC_CMD ifdef CONFIG_USE_CHERRY_USB @@ -238,3 +203,4 @@ ifdef CONFIG_USE_CHERRY_USB include $(THIRD_PARTY_CUR_DIR)/cherryusb-0.6.0/makefile endif #CONFIG_USE_CHERRY_USB + diff --git a/third-party/tlsf-3.1.0/port/fmemory_pool.c b/third-party/tlsf-3.1.0/port/fmemory_pool.c index 15b74b03..dd6f2b18 100644 --- a/third-party/tlsf-3.1.0/port/fmemory_pool.c +++ b/third-party/tlsf-3.1.0/port/fmemory_pool.c @@ -1,22 +1,22 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: fmemory_pool.c * Date: 2021-11-25 15:19:14 * LastEditTime: 2022-02-17 18:01:43 * Description:  This files is for memory pool API implmentation - * - * Modify History: + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- * 1.0 zhugengyu 2021/12/2 init @@ -42,10 +42,10 @@ static inline boolean FMempTakeSema(SemaphoreHandle_t locker) { - FASSERT_MSG((NULL != locker), "locker not exists"); + FASSERT_MSG((NULL != locker), "Locker not exists."); if (pdFALSE == xSemaphoreTake(locker, portMAX_DELAY)) { - FMEMP_ERROR("failed to give locker !!!"); + FMEMP_ERROR("Failed to give locker !!!"); return FALSE; } @@ -54,10 +54,10 @@ static inline boolean FMempTakeSema(SemaphoreHandle_t locker) static inline void FMempGiveSema(SemaphoreHandle_t locker) { - FASSERT_MSG((NULL != locker), "locker not exists"); + FASSERT_MSG((NULL != locker), "Locker not exists."); if (pdFALSE == xSemaphoreGive(locker)) { - FMEMP_ERROR("failed to give locker !!!"); + FMEMP_ERROR("Failed to give locker !!!"); } return; @@ -100,18 +100,18 @@ static void FMempDumpTagList(FMemp *memp) FMempTag *cur_tag = memp->tags_list; FMempTag *nxt_tag; - FMEMP_INFO("memory block status: "); + FMEMP_INFO("Memory block status: "); while (NULL != cur_tag) { nxt_tag = cur_tag->next; if (FMEMP_TAG_ALLOCATED == cur_tag->status) { - FMEMP_INFO(" [%d]: @0x%lx, sz: %ld, st: %s, msg: %s", - cur_tag->id, - cur_tag->mem_addr, - cur_tag->mem_size, - status_info[cur_tag->status], - cur_tag->msg); + FMEMP_INFO(" [%d]: @0x%lx, sz: %ld, st: %s, msg: %s", + cur_tag->id, + cur_tag->mem_addr, + cur_tag->mem_size, + status_info[cur_tag->status], + cur_tag->msg); } cur_tag = nxt_tag; } @@ -151,14 +151,14 @@ static boolean FMempTagIfExists(FMemp *memp, uintptr mem_addr, FMempTagStatus ne FMEMP_ERROR("Free twice !!!"); } - FMEMP_DEBUG("change @0x%lx from %s to %s", cur_tag->mem_addr, - status_info[cur_tag->status], - status_info[new_status]); - FMEMP_DEBUG(" size from %ld to %ld", cur_tag->mem_size, - new_size); + FMEMP_DEBUG("Change @0x%lx from %s to %s.", cur_tag->mem_addr, + status_info[cur_tag->status], + status_info[new_status]); + FMEMP_DEBUG(" size from %ld to %ld.", cur_tag->mem_size, + new_size); cur_tag->status = new_status; cur_tag->mem_size = new_size; - + if (NULL != new_msg) { const fsize_t msg_len = min((fsize_t)(FMEMP_TAG_MSG_LEN - 1), strlen(new_msg)); @@ -252,7 +252,7 @@ void *FMempMallocTag(FMemp *memp, fsize_t size, const char *file, unsigned long void *ptr = FMempMalloc(memp, size); snprintf(msg_buf, FMEMP_TAG_MSG_LEN, "%s_%d: %s", file, line, msg); FMempDoTag(memp, ptr, FMEMP_TAG_ALLOCATED, size, msg_buf); - return ptr; + return ptr; } /** @@ -273,7 +273,7 @@ void *FMempMallocAlignTag(FMemp *memp, fsize_t size, fsize_t align, const char * void *ptr = FMempMallocAlign(memp, size, align); snprintf(msg_buf, FMEMP_TAG_MSG_LEN, "%s_%d: %s", file, line, msg); FMempDoTag(memp, ptr, FMEMP_TAG_ALLOCATED, size, msg_buf); - return ptr; + return ptr; } /** @@ -294,7 +294,7 @@ void *FMempCallocTag(FMemp *memp, fsize_t count, fsize_t size, const char *file, void *ptr = FMempCalloc(memp, count, size); snprintf(msg_buf, FMEMP_TAG_MSG_LEN, "%s_%d: %s", file, line, msg); FMempDoTag(memp, ptr, FMEMP_TAG_ALLOCATED, size, msg_buf); - return ptr; + return ptr; } /** @@ -316,7 +316,7 @@ void *FMempReallocTag(FMemp *memp, void *ptr, fsize_t size, const char *file, un ptr = FMempRealloc(memp, ptr, size); snprintf(msg_buf, FMEMP_TAG_MSG_LEN, "%s_%d: %s", file, line, msg); FMempDoTag(memp, ptr, FMEMP_TAG_ALLOCATED, size, msg_buf); - return ptr; + return ptr; } /** @@ -357,7 +357,7 @@ FError FMempInit(FMemp *memp, void *begin_addr, void *end_addr) if ((FT_COMPONENT_IS_READY == memp->is_ready) || (NULL != memp->tlsf_ptr)) { - FMEMP_ERROR("memory tlsf_ptr already inited, you may lose access to original memory tlsf_ptr"); + FMEMP_ERROR("Memory tlsf_ptr already inited, you may lose access to original memory tlsf_ptr."); return FMEMP_ERR_ALREADY_INIT; } @@ -367,7 +367,7 @@ FError FMempInit(FMemp *memp, void *begin_addr, void *end_addr) } else { - FMEMP_ERROR("invalid input buf beg: %p, end: %p", begin_addr, end_addr); + FMEMP_ERROR("Invalid input buf beg: %p, end: %p.", begin_addr, end_addr); return FMEMP_ERR_INVALID_BUF; } @@ -375,12 +375,12 @@ FError FMempInit(FMemp *memp, void *begin_addr, void *end_addr) FASSERT(NULL != (memp->locker = xSemaphoreCreateMutex())); /* no scheduler when init */ - taskENTER_CRITICAL(); + taskENTER_CRITICAL(); memp->tlsf_ptr = (tlsf_t)tlsf_create_with_pool(begin_addr, size); if (NULL == memp->tlsf_ptr) { - FMEMP_ERROR("allocate TLSF buf failed"); + FMEMP_ERROR("Allocate TLSF buf failed."); ret = FMEMP_ERR_INIT_TLFS; goto err_ret; } @@ -388,7 +388,7 @@ FError FMempInit(FMemp *memp, void *begin_addr, void *end_addr) memp->pools_list = FMempMalloc(memp, sizeof(FMempPoolList *)); if (NULL == memp->pools_list) { - FMEMP_ERROR("allocate TLSF block failed"); + FMEMP_ERROR("Allocate TLSF block failed."); ret = FMEMP_ERR_BAD_MALLOC; goto err_ret; } @@ -427,17 +427,17 @@ void FMempDeinit(FMemp *memp) { FASSERT(memp != NULL); - FMempPoolList * pool_node = (FMempPoolList *)memp->pools_list; + FMempPoolList *pool_node = (FMempPoolList *)memp->pools_list; pool_t tlsf_ptr = pool_node->pool_addr; if ((FT_COMPONENT_IS_READY != memp->is_ready) && (NULL == memp->tlsf_ptr)) { - FMEMP_WARN("memory tlsf_ptr not inited"); + FMEMP_WARN("Memory tlsf_ptr not inited."); return; } /* no scheduler when init */ - taskENTER_CRITICAL(); + taskENTER_CRITICAL(); #ifdef FMEMP_TAG_DEBUG FMempRemoveTagList(memp); @@ -478,7 +478,9 @@ void *FMempMalloc(FMemp *memp, fsize_t nbytes) nbytes = (nbytes > 20) ? nbytes : 20; if (!FMempTakeSema(memp->locker)) + { return ptr; + } if (memp->tlsf_ptr) { @@ -505,7 +507,9 @@ void *FMempMallocAlign(FMemp *memp, fsize_t size, fsize_t align) size = (size > 20) ? size : 20; if (!FMempTakeSema(memp->locker)) + { return ptr; + } if (memp->tlsf_ptr) { @@ -533,10 +537,12 @@ void *FMempCalloc(FMemp *memp, fsize_t count, fsize_t size) total_size = count * size; if (!FMempTakeSema(memp->locker)) + { return ptr; + } ptr = FMempMalloc(memp, total_size); - + FMempGiveSema(memp->locker); if (ptr != NULL) { @@ -560,7 +566,9 @@ void *FMempCalloc(FMemp *memp, fsize_t count, fsize_t size) void *FMempRealloc(FMemp *memp, void *ptr, fsize_t nbytes) { if (!FMempTakeSema(memp->locker)) + { return ptr; + } if (memp->tlsf_ptr) { @@ -582,7 +590,9 @@ void *FMempRealloc(FMemp *memp, void *ptr, fsize_t nbytes) void FMempFree(FMemp *memp, void *ptr) { if (!FMempTakeSema(memp->locker)) + { return; + } if (memp->tlsf_ptr) { @@ -621,7 +631,9 @@ void FMemProbe(FMemp *memp, u32 *total, u32 *used, u32 *max_used) total_mem = 0; if (!FMempTakeSema(memp->locker)) + { return; + } tlsf_walk_pool(tlsf_get_pool(memp->tlsf_ptr), FMemInfo, 0); @@ -644,7 +656,7 @@ void FMemListAll(FMemp *memp) u8 i = 0; u8 len = 0; - FMempPoolList * pool_node; + FMempPoolList *pool_node; FSListNode *node; node = &memp->pools_list->list; @@ -652,7 +664,9 @@ void FMemListAll(FMemp *memp) total_mem = 0; if (!FMempTakeSema(memp->locker)) + { return; + } len = FSListLen(node) + 1; for (i = 0; i < len; i++) @@ -664,10 +678,10 @@ void FMemListAll(FMemp *memp) FMempGiveSema(memp->locker); - FMEMP_INFO("total memory: %d", total_mem); - FMEMP_INFO("used memory : %d", used_mem); - FMEMP_INFO("check tlsf: %d", tlsf_check(memp->tlsf_ptr)); - FMEMP_INFO("check tlsf pool: %d", tlsf_check_pool(memp->tlsf_ptr)); + FMEMP_INFO("Total memory: %d", total_mem); + FMEMP_INFO("Used memory : %d", used_mem); + FMEMP_INFO("Check tlsf: %d", tlsf_check(memp->tlsf_ptr)); + FMEMP_INFO("Check tlsf pool: %d", tlsf_check_pool(memp->tlsf_ptr)); #ifdef FMEMP_TAG_DEBUG FMempDumpTagList(memp); diff --git a/third-party/tlsf-3.1.0/port/fmemory_pool.h b/third-party/tlsf-3.1.0/port/fmemory_pool.h index 8c79f216..6ee4d7ca 100644 --- a/third-party/tlsf-3.1.0/port/fmemory_pool.h +++ b/third-party/tlsf-3.1.0/port/fmemory_pool.h @@ -1,35 +1,30 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: fmemory_pool.h * Date: 2021-11-25 15:18:57 * LastEditTime: 2022-02-17 18:02:16 * Description:  This files is for memory pool API definition - * - * Modify History: + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- * 1.0 zhugengyu 2021/12/2 init * 1.1 zhugengyu 2022/2/28 support memory tag for trace */ -#ifndef _FT_MEMORY_POOL_H_ -#define _FT_MEMORY_POOL_H_ - -#ifdef __cplusplus -extern "C" -{ -#endif +#ifndef FMEMORY_POOL_H +#define FMEMORY_POOL_H #include #include "FreeRTOS.h" @@ -41,7 +36,12 @@ extern "C" #include "tlsf.h" #include "fslink_list.h" -#define FMEMP_SUCCESS FT_SUCCESS +#ifdef __cplusplus +extern "C" +{ +#endif + +#define FMEMP_SUCCESS FT_SUCCESS #define FMEMP_ERR_INVALID_BUF FT_MAKE_ERRCODE(ErrorModGeneral, ErrCommMemp, 0) #define FMEMP_ERR_INIT_TLFS FT_MAKE_ERRCODE(ErrorModGeneral, ErrCommMemp, 1) #define FMEMP_ERR_BAD_MALLOC FT_MAKE_ERRCODE(ErrorModGeneral, ErrCommMemp, 2) diff --git a/third-party/tlsf-3.1.0/port/fslink_list.h b/third-party/tlsf-3.1.0/port/fslink_list.h index c9769b79..4a08dde9 100644 --- a/third-party/tlsf-3.1.0/port/fslink_list.h +++ b/third-party/tlsf-3.1.0/port/fslink_list.h @@ -1,38 +1,38 @@ /* - * Copyright : (C) 2022 Phytium Information Technology, Inc. + * Copyright : (C) 2022 Phytium Information Technology, Inc. * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * + * See the Phytium Public License for more details. + * + * * FilePath: fslink_list.h * Date: 2021-12-02 13:18:02 * LastEditTime: 2022-02-17 18:02:59 * Description:  This files is for singal link list definition - * - * Modify History: + * + * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- * 1.0 zhugengyu 2021/12/2 init */ -#ifndef _FT_SLINK_LIST_H_ -#define _FT_SLINK_LIST_H_ +#ifndef FSLINK_LIST_H +#define FSLINK_LIST_H + +#include "ftypes.h" +#include "fkernel.h" #ifdef __cplusplus extern "C" { #endif -#include "ftypes.h" -#include "fkernel.h" - /** * Single List structure */ @@ -65,7 +65,10 @@ static void FSListAppend(FSListNode *l, FSListNode *n) FSListNode *node; node = l; - while (node->next) node = node->next; + while (node->next) + { + node = node->next; + } /* append the node to the tail */ node->next = n; @@ -123,7 +126,10 @@ static FSListNode *FSListFirst(FSListNode *l) */ static FSListNode *FSListTail(FSListNode *l) { - while (l->next) l = l->next; + while (l->next) + { + l = l->next; + } return l; } @@ -161,10 +167,16 @@ static FSListNode *FSListRemove(FSListNode *l, FSListNode *n) { /* remove slist head */ FSListNode *node = l; - while (node->next && node->next != n) node = node->next; + while (node->next && node->next != n) + { + node = node->next; + } /* remove node */ - if (node->next != (FSListNode *)0) node->next = node->next->next; + if (node->next != (FSListNode *)0) + { + node->next = node->next->next; + } return l; } -- Gitee

    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�!_+?G>?;Ac7OPPf$&q!6HB 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%0D#tt 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

  • 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