Skip to content

Commit bc6f065

Browse files
committed
working on compilation errors
1 parent 7812695 commit bc6f065

File tree

38 files changed

+102
-110
lines changed

38 files changed

+102
-110
lines changed

extmod/extmod.mk

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# This makefile fragment adds the source code files for the core extmod modules
22
# and provides rules to build 3rd-party components for extmod modules.
33

4+
# CIRCUITPY-CHANGE: many extmod modules removed
5+
# CIRCUITPY-CHANGE: modzlib.c still used
46
SRC_EXTMOD_C += \
57
extmod/modasyncio.c \
68
extmod/modbinascii.c \
@@ -12,7 +14,6 @@ SRC_EXTMOD_C += \
1214
extmod/modrandom.c \
1315
extmod/modre.c \
1416
extmod/modselect.c \
15-
extmod/moductypes.c \
1617
extmod/modzlib.c \
1718
extmod/vfs.c \
1819
extmod/vfs_blockdev.c \

extmod/modjson.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ static mp_obj_t mod_json_loads(mp_obj_t obj) {
442442
vstr_t vstr = {bufinfo.len, bufinfo.len, (char *)bufinfo.buf, true};
443443
mp_obj_stringio_t sio = {{&mp_type_stringio}, &vstr, 0, MP_OBJ_NULL};
444444
// CIRCUITPY-CHANGE
445-
return mod_json_load(MP_OBJ_FROM_PTR(&sio), false);
445+
return _mod_json_load(MP_OBJ_FROM_PTR(&sio), false);
446446
}
447447
static MP_DEFINE_CONST_FUN_OBJ_1(mod_json_loads_obj, mod_json_loads);
448448

extmod/vfs_fat.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,8 @@ static const mp_obj_property_t fat_vfs_label_obj = {
526526
#endif
527527

528528
static const mp_rom_map_elem_t fat_vfs_locals_dict_table[] = {
529-
#if _FS_REENTRANT
529+
// CIRCUITPY-CHANGE: correct name
530+
#if FF_FS_REENTRANT
530531
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&fat_vfs_del_obj) },
531532
#endif
532533
{ MP_ROM_QSTR(MP_QSTR_mkfs), MP_ROM_PTR(&fat_vfs_mkfs_obj) },

extmod/vfs_fat_file.c

-5
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,6 @@ const byte fresult_to_errno_table[20] = {
6262
[FR_INVALID_PARAMETER] = MP_EINVAL,
6363
};
6464

65-
typedef struct _pyb_file_obj_t {
66-
mp_obj_base_t base;
67-
FIL fp;
68-
} pyb_file_obj_t;
69-
7065
static void file_obj_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
7166
(void)kind;
7267
// CIRCUITPY-CHANGE

lib/mbedtls

lib/mbedtls_config/mbedtls_config.h

+40-26
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* The MIT License (MIT)
55
*
6-
* Copyright (c) 2018-2022 Damien P. George
6+
* Copyright (c) 2018-2019 Damien P. George
77
*
88
* Permission is hereby granted, free of charge, to any person obtaining a copy
99
* of this software and associated documentation files (the "Software"), to deal
@@ -23,17 +23,18 @@
2323
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2424
* THE SOFTWARE.
2525
*/
26-
#ifndef MICROPY_INCLUDED_MBEDTLS_CONFIG_COMMON_H
27-
#define MICROPY_INCLUDED_MBEDTLS_CONFIG_COMMON_H
26+
#ifndef MICROPY_INCLUDED_MBEDTLS_CONFIG_H
27+
#define MICROPY_INCLUDED_MBEDTLS_CONFIG_H
2828

2929
// If you want to debug MBEDTLS uncomment the following and
30-
// pass "3" to mbedtls_debug_set_threshold in socket_new.
30+
// Pass 3 to mbedtls_debug_set_threshold in socket_new
3131
// #define MBEDTLS_DEBUG_C
3232

33-
// Set mbedtls configuration.
34-
#define MBEDTLS_HAVE_TIME
35-
#define MBEDTLS_HAVE_TIME_DATE
33+
// Set mbedtls configuration
34+
#define MBEDTLS_PLATFORM_MEMORY
35+
#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
3636
#define MBEDTLS_DEPRECATED_REMOVED
37+
#define MBEDTLS_ENTROPY_HARDWARE_ALT
3738
#define MBEDTLS_AES_ROM_TABLES
3839
#define MBEDTLS_CIPHER_MODE_CBC
3940
#define MBEDTLS_ECP_DP_SECP192R1_ENABLED
@@ -44,26 +45,39 @@
4445
#define MBEDTLS_ECP_DP_SECP192K1_ENABLED
4546
#define MBEDTLS_ECP_DP_SECP224K1_ENABLED
4647
#define MBEDTLS_ECP_DP_SECP256K1_ENABLED
47-
#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
48+
#define MBEDTLS_ECP_DP_BP256R1_ENABLED
49+
#define MBEDTLS_ECP_DP_BP384R1_ENABLED
50+
#define MBEDTLS_ECP_DP_BP512R1_ENABLED
51+
#define MBEDTLS_ECP_DP_CURVE25519_ENABLED
52+
#define MBEDTLS_ECP_NIST_OPTIM
53+
#define MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
54+
#define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
55+
#define MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
4856
#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
49-
#define MBEDTLS_CAN_ECDH
50-
#define MBEDTLS_PK_CAN_ECDSA_SIGN
57+
#define MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
58+
#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
59+
#define MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
60+
#define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
61+
#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
62+
#define MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED
63+
#define MBEDTLS_NO_PLATFORM_ENTROPY
5164
#define MBEDTLS_PKCS1_V15
5265
#define MBEDTLS_SHA256_SMALLER
5366
#define MBEDTLS_SSL_PROTO_TLS1
5467
#define MBEDTLS_SSL_PROTO_TLS1_1
5568
#define MBEDTLS_SSL_PROTO_TLS1_2
5669
#define MBEDTLS_SSL_SERVER_NAME_INDICATION
5770

58-
// Use a smaller output buffer to reduce size of SSL context.
71+
// Use a smaller output buffer to reduce size of SSL context
5972
#define MBEDTLS_SSL_MAX_CONTENT_LEN (16384)
6073
#define MBEDTLS_SSL_IN_CONTENT_LEN (MBEDTLS_SSL_MAX_CONTENT_LEN)
6174
#define MBEDTLS_SSL_OUT_CONTENT_LEN (4096)
6275

63-
// Enable mbedtls modules.
76+
// Enable mbedtls modules
6477
#define MBEDTLS_AES_C
6578
#define MBEDTLS_ASN1_PARSE_C
6679
#define MBEDTLS_ASN1_WRITE_C
80+
#define MBEDTLS_BASE64_C
6781
#define MBEDTLS_BIGNUM_C
6882
#define MBEDTLS_CIPHER_C
6983
#define MBEDTLS_CTR_DRBG_C
@@ -72,35 +86,30 @@
7286
#define MBEDTLS_ECP_C
7387
#define MBEDTLS_ENTROPY_C
7488
#define MBEDTLS_ERROR_C
89+
#define MBEDTLS_GCM_C
7590
#define MBEDTLS_MD_C
7691
#define MBEDTLS_MD5_C
7792
#define MBEDTLS_OID_C
7893
#define MBEDTLS_PKCS5_C
94+
#define MBEDTLS_PEM_PARSE_C
7995
#define MBEDTLS_PK_C
8096
#define MBEDTLS_PK_PARSE_C
8197
#define MBEDTLS_PLATFORM_C
8298
#define MBEDTLS_RSA_C
8399
#define MBEDTLS_SHA1_C
84-
#define MBEDTLS_SHA224_C
85100
#define MBEDTLS_SHA256_C
86-
#define MBEDTLS_SHA384_C
87101
#define MBEDTLS_SHA512_C
88102
#define MBEDTLS_SSL_CLI_C
89103
#define MBEDTLS_SSL_SRV_C
90104
#define MBEDTLS_SSL_TLS_C
105+
#define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE
91106
#define MBEDTLS_X509_CRT_PARSE_C
92107
#define MBEDTLS_X509_USE_C
108+
#define MBEDTLS_HAVE_TIME
109+
#define MBEDTLS_DHM_C // needed by DHE_PSK
110+
#undef MBEDTLS_HAVE_TIME_DATE
93111

94-
// A port may enable this option to select additional bare-metal configuration.
95-
#if MICROPY_MBEDTLS_CONFIG_BARE_METAL
96-
97-
// Bare-metal mbedtls configuration.
98-
#define MBEDTLS_PLATFORM_MEMORY
99-
#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
100-
#define MBEDTLS_ENTROPY_HARDWARE_ALT
101-
#define MBEDTLS_NO_PLATFORM_ENTROPY
102-
103-
// Bare-metal memory allocation hooks.
112+
// Memory allocation hooks
104113
#include <stdlib.h>
105114
#include <stdio.h>
106115
void *m_tracked_calloc(size_t nmemb, size_t size);
@@ -109,6 +118,11 @@ void m_tracked_free(void *ptr);
109118
#define MBEDTLS_PLATFORM_STD_FREE m_tracked_free
110119
#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf
111120

112-
#endif
121+
// Time hook
122+
#include <time.h>
123+
time_t rp2_rtctime_seconds(time_t *timer);
124+
#define MBEDTLS_PLATFORM_TIME_MACRO rp2_rtctime_seconds
125+
126+
#include "mbedtls/check_config.h"
113127

114-
#endif // MICROPY_INCLUDED_MBEDTLS_CONFIG_COMMON_H
128+
#endif /* MICROPY_INCLUDED_MBEDTLS_CONFIG_H */

lib/mbedtls_config/mbedtls_config_hashlib.h

-8
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@
4545
#define MBEDTLS_SHA512_C
4646
#undef MBEDTLS_HAVE_TIME_DATE
4747

48-
<<<<<<<< HEAD:lib/mbedtls_config/mbedtls_config_hashlib.h
4948
// Memory allocation hooks
5049
#include <stdlib.h>
5150
#include <stdio.h>
@@ -54,13 +53,6 @@ void m_tracked_free(void *ptr);
5453
#define MBEDTLS_PLATFORM_STD_CALLOC m_tracked_calloc
5554
#define MBEDTLS_PLATFORM_STD_FREE m_tracked_free
5655
#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf
57-
========
58-
// Time hook
59-
#include <time.h>
60-
time_t rp2_rtctime_seconds(time_t *timer);
61-
#define MBEDTLS_PLATFORM_TIME_MACRO rp2_rtctime_seconds
62-
#define MBEDTLS_PLATFORM_MS_TIME_ALT mbedtls_ms_time
63-
>>>>>>>> v1.23.0:lib/mbedtls_config/mbedtls_config_port.h
6456

6557
#include "mbedtls/check_config.h"
6658

lib/mbedtls_config/mbedtls_port.c

+7-12
Original file line numberDiff line numberDiff line change
@@ -25,22 +25,23 @@
2525
*/
2626
#include <py/mpconfig.h>
2727

28-
// CIRCUITPY-CHANGE: CIRCUITPY_SSL_MBEDTLS instead of MICROPY_SSL_MBEDTLS
2928
#if CIRCUITPY_SSL_MBEDTLS
3029

31-
#include "mbedtls_config_port.h"
30+
#include "mbedtls_config.h"
31+
#include "mbedtls/entropy_poll.h"
32+
33+
#include "hardware/rtc.h"
34+
#include "shared/timeutils/timeutils.h"
35+
#include "shared-bindings/os/__init__.h"
3236

3337
#include "hardware/rtc.h"
3438
#include "shared/timeutils/timeutils.h"
35-
#include "mbedtls/platform_time.h"
3639

3740
extern uint8_t rosc_random_u8(size_t cycles);
3841

3942
int mbedtls_hardware_poll(void *data, unsigned char *output, size_t len, size_t *olen) {
4043
*olen = len;
41-
for (size_t i = 0; i < len; i++) {
42-
output[i] = rosc_random_u8(8);
43-
}
44+
common_hal_os_urandom(data, len);
4445
return 0;
4546
}
4647

@@ -50,10 +51,4 @@ time_t rp2_rtctime_seconds(time_t *timer) {
5051
return timeutils_seconds_since_epoch(t.year, t.month, t.day, t.hour, t.min, t.sec);
5152
}
5253

53-
mbedtls_ms_time_t mbedtls_ms_time(void) {
54-
time_t *tv = NULL;
55-
mbedtls_ms_time_t current_ms;
56-
current_ms = rp2_rtctime_seconds(tv) * 1000;
57-
return current_ms;
58-
}
5954
#endif

ports/espressif/bindings/espcamera/Camera.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,7 @@ static mp_obj_t espcamera_camera_make_new(const mp_obj_type_t *type, size_t n_ar
120120
mp_int_t jpeg_quality = mp_arg_validate_int_range(args[ARG_jpeg_quality].u_int, 2, 55, MP_QSTR_jpeg_quality);
121121
mp_int_t framebuffer_count = mp_arg_validate_int_range(args[ARG_framebuffer_count].u_int, 1, 2, MP_QSTR_framebuffer_count);
122122

123-
espcamera_camera_obj_t *self = m_new_obj_with_finaliser(espcamera_camera_obj_t);
124-
self->base.type = &espcamera_camera_type;
123+
espcamera_camera_obj_t *self = mp_obj_malloc_with_finaliser(espcamera_camera_obj_t, &espcamera_camera_type);
125124
common_hal_espcamera_camera_construct(
126125
self,
127126
data_pins,

ports/espressif/common-hal/socketpool/Socket.c

+4-3
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,7 @@ socketpool_socket_obj_t *common_hal_socketpool_socket(socketpool_socketpool_obj_
260260
mp_raise_NotImplementedError(MP_ERROR_TEXT("Unsupported socket type"));
261261
}
262262

263-
socketpool_socket_obj_t *sock = m_new_obj_with_finaliser(socketpool_socket_obj_t);
264-
sock->base.type = &socketpool_socket_type;
263+
socketpool_socket_obj_t *sock = mp_obj_malloc_with_finaliser(socketpool_socket_obj_t, &socketpool_socket_type);
265264

266265
if (!_socketpool_socket(self, family, type, proto, sock)) {
267266
mp_raise_RuntimeError(MP_ERROR_TEXT("Out of sockets"));
@@ -326,7 +325,9 @@ int socketpool_socket_accept(socketpool_socket_obj_t *self, mp_obj_t *peer_out,
326325
}
327326

328327
socketpool_socket_obj_t *common_hal_socketpool_socket_accept(socketpool_socket_obj_t *self, mp_obj_t *peer_out) {
329-
socketpool_socket_obj_t *sock = m_new_obj_with_finaliser(socketpool_socket_obj_t);
328+
// Set the socket type only after the socketpool_socket_accept succeeds, so that the
329+
// finaliser is not called on a bad socket.
330+
socketpool_socket_obj_t *sock = mp_obj_malloc_with_finaliser(socketpool_socket_obj_t, NULL);
330331
int newsoc = socketpool_socket_accept(self, peer_out, NULL);
331332

332333
if (newsoc > 0) {

ports/raspberrypi/common-hal/socketpool/Socket.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -746,8 +746,7 @@ socketpool_socket_obj_t *common_hal_socketpool_socket(socketpool_socketpool_obj_
746746
mp_raise_NotImplementedError(MP_ERROR_TEXT("Only IPv4 sockets supported"));
747747
}
748748

749-
socketpool_socket_obj_t *socket = m_new_obj_with_finaliser(socketpool_socket_obj_t);
750-
socket->base.type = &socketpool_socket_type;
749+
socketpool_socket_obj_t *socket = mp_obj_malloc_with_finaliser(socketpool_socket_obj_t, &socketpool_socket_type);
751750

752751
if (!socketpool_socket(self, family, type, proto, socket)) {
753752
mp_raise_RuntimeError(MP_ERROR_TEXT("Out of sockets"));
@@ -849,7 +848,8 @@ socketpool_socket_obj_t *common_hal_socketpool_socket_accept(socketpool_socket_o
849848
mp_obj_t *peer_out) {
850849
// Create new socket object, do it here because we must not raise an out-of-memory
851850
// exception when the LWIP concurrency lock is held
852-
socketpool_socket_obj_t *accepted = m_new_obj_with_finaliser(socketpool_socket_obj_t);
851+
// Don't set the type field: socketpool_socket_reset() will do that when checking for already reset.
852+
socketpool_socket_obj_t *accepted = mp_obj_malloc_with_finaliser(socketpool_socket_obj_t, NULL);
853853
socketpool_socket_reset(accepted);
854854

855855
int ret = socketpool_socket_accept(socket, peer_out, accepted);

py/binary.c

+3
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,8 @@ static inline uint16_t mp_encode_half_float(float x) {
189189

190190
#elif MICROPY_PY_BUILTINS_FLOAT
191191

192+
// CIRCUITPY-CHANGE: avoid warnings about unused functions
193+
#if defined(MICROPY_PY_FLOAT_USE_NATIVE_FLT16) && MICROPY_PY_FLOAT_USE_NATIVE_FLT16
192194
static float mp_decode_half_float(uint16_t hf) {
193195
union {
194196
uint32_t i;
@@ -259,6 +261,7 @@ static uint16_t mp_encode_half_float(float x) {
259261
uint16_t bits = ((fpu.i >> 16) & 0x8000) | (e << 10) | m;
260262
return bits;
261263
}
264+
#endif // defined(MICROPY_PY_FLOAT_USE_NATIVE_FLT16) && MICROPY_PY_FLOAT_USE_NATIVE_FLT16
262265

263266
#endif
264267

py/circuitpy_mpconfig.h

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ extern void common_hal_mcu_enable_interrupts(void);
4343
// MicroPython-only options not used by CircuitPython, but present in various files
4444
// inherited from MicroPython, especially in extmod/
4545
#define MICROPY_ENABLE_DYNRUNTIME (0)
46+
#define MICROPY_HW_ENABLE_USB_RUNTIME_DEVICE (0)
4647
#define MICROPY_PY_BLUETOOTH (0)
4748
#define MICROPY_PY_LWIP_SLIP (0)
4849
#define MICROPY_PY_OS_DUPTERM (0)

py/emitglue.c

+8-3
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ void mp_emit_glue_assign_bytecode(mp_raw_code_t *rc, const byte *code,
7272

7373
rc->kind = MP_CODE_BYTECODE;
7474
rc->is_generator = (scope_flags & MP_SCOPE_FLAG_GENERATOR) != 0;
75+
rc->is_async = (scope_flags & MP_SCOPE_FLAG_ASYNC) != 0;
7576
rc->fun_data = code;
7677
rc->children = children;
7778

@@ -134,6 +135,7 @@ void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, cons
134135

135136
rc->kind = kind;
136137
rc->is_generator = (scope_flags & MP_SCOPE_FLAG_GENERATOR) != 0;
138+
rc->is_async = (scope_flags & MP_SCOPE_FLAG_ASYNC) != 0;
137139
rc->fun_data = fun_data;
138140

139141
#if MICROPY_PERSISTENT_CODE_SAVE
@@ -207,9 +209,12 @@ mp_obj_t mp_make_function_from_proto_fun(mp_proto_fun_t proto_fun, const mp_modu
207209
fun = mp_obj_new_fun_native(def_args, rc->fun_data, context, rc->children);
208210
// Check for a generator function, and if so change the type of the object
209211
// CIRCUITPY-CHANGE: distinguish generators and async
210-
if ((rc->scope_flags & MP_SCOPE_FLAG_ASYNC) != 0) {
212+
#if MICROPY_PY_ASYNC_AWAIT
213+
if ((rc->is_async) != 0) {
211214
((mp_obj_base_t *)MP_OBJ_TO_PTR(fun))->type = &mp_type_native_coro_wrap;
212-
} else if ((rc->is_generator) != 0) {
215+
} else
216+
#endif
217+
if ((rc->is_generator) != 0) {
213218
((mp_obj_base_t *)MP_OBJ_TO_PTR(fun))->type = &mp_type_native_gen_wrap;
214219
}
215220
break;
@@ -231,7 +236,7 @@ mp_obj_t mp_make_function_from_proto_fun(mp_proto_fun_t proto_fun, const mp_modu
231236
// A generator is MP_SCOPE_FLAG_ASYNC | MP_SCOPE_FLAG_GENERATOR,
232237
// so check for ASYNC first.
233238
#if MICROPY_PY_ASYNC_AWAIT
234-
if ((rc->scope_flags & MP_SCOPE_FLAG_ASYNC) != 0) {
239+
if ((rc->is_async) != 0) {
235240
((mp_obj_base_t *)MP_OBJ_TO_PTR(fun))->type = &mp_type_coro_wrap;
236241
} else
237242
#endif

py/emitglue.h

+2
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ typedef struct _mp_raw_code_t {
7575
uint8_t proto_fun_indicator[2];
7676
uint8_t kind; // of type mp_raw_code_kind_t; only 3 bits used
7777
bool is_generator;
78+
bool is_async;
7879
const void *fun_data;
7980
struct _mp_raw_code_t **children;
8081
#if MICROPY_PERSISTENT_CODE_SAVE
@@ -105,6 +106,7 @@ typedef struct _mp_raw_code_truncated_t {
105106
uint8_t proto_fun_indicator[2];
106107
uint8_t kind;
107108
bool is_generator;
109+
bool is_async;
108110
const void *fun_data;
109111
struct _mp_raw_code_t **children;
110112
#if MICROPY_PERSISTENT_CODE_SAVE

py/mkrules.mk

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ ifeq ($(MICROPY_PREVIEW_VERSION_2),1)
1111
CFLAGS += -DMICROPY_PREVIEW_VERSION_2=1
1212
endif
1313

14-
HELP_BUILD_ERROR ?= "See \033[1;31mAdafruit \"Building CircuitPython\" Learn Guide; Adafruit Discord #circuitpython-dev\033[0m"
14+
HELP_BUILD_ERROR ?= "See \033[1;31mAdafruit \"Building CircuitPython\" Learn Guide; Adafruit Discord \#circuitpython-dev\033[0m"
1515
HELP_MPY_LIB_SUBMODULE ?= "\033[1;31mError: micropython-lib submodule is not initialized.\033[0m Run 'make submodules'"
1616

1717
# Extra deps that need to happen before object compilation.

0 commit comments

Comments
 (0)