1+ /**
2+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+ * SPDX-License-Identifier: Apache-2.0.
4+ */
5+ #include "mqtt_request_response.h"
6+
7+ #include "mqtt5_client.h"
8+ #include "mqtt_client_connection.h"
9+
10+ #include "aws/mqtt/request-response/request_response_client.h"
11+
12+ static const char * s_capsule_name_mqtt_request_response_client = "aws_mqtt_request_response_client" ;
13+
14+ static const char * AWS_PYOBJECT_KEY_REQUEST_RESPONSE_CLIENT_OPTIONS = "RequestResponseClientOptions" ;
15+ static const char * AWS_PYOBJECT_KEY_MAX_REQUEST_RESPONSE_SUBSCRIPTIONS = "max_request_response_subscriptions" ;
16+ static const char * AWS_PYOBJECT_KEY_MAX_STREAMING_SUBSCRIPTIONS = "max_streaming_subscriptions" ;
17+ static const char * AWS_PYOBJECT_KEY_OPERATION_TIMEOUT_IN_SECONDS = "operation_timeout_in_seconds" ;
18+
19+ struct mqtt_request_response_client_binding {
20+ struct aws_mqtt_request_response_client * native ;
21+ };
22+
23+ static void s_mqtt_request_response_python_client_destructor (PyObject * client_capsule ) {
24+ struct mqtt_request_response_client_binding * client_binding =
25+ PyCapsule_GetPointer (client_capsule , s_capsule_name_mqtt_request_response_client );
26+ assert (client_binding );
27+
28+ client_binding -> native = aws_mqtt_request_response_client_release (client_binding -> native );
29+
30+ aws_mem_release (aws_py_get_allocator (), client_binding );
31+ }
32+
33+ /*
34+ * Returns success as true/false. If not successful, a python error will be set, so the caller does not need to check
35+ */
36+ static bool s_init_mqtt_request_response_client_options (
37+ struct aws_mqtt_request_response_client_options * client_options ,
38+ PyObject * client_options_py ) {
39+ AWS_ZERO_STRUCT (* client_options );
40+
41+ uint32_t max_request_response_subscriptions = PyObject_GetAttrAsUint32 (
42+ client_options_py ,
43+ AWS_PYOBJECT_KEY_REQUEST_RESPONSE_CLIENT_OPTIONS ,
44+ AWS_PYOBJECT_KEY_MAX_REQUEST_RESPONSE_SUBSCRIPTIONS );
45+ if (PyErr_Occurred ()) {
46+ PyErr_Format (PyErr_Occurred (), "Cannot convert max_request_response_subscriptions to a C uint32" );
47+ return false;
48+ }
49+
50+ uint32_t max_streaming_subscriptions = PyObject_GetAttrAsUint32 (
51+ client_options_py ,
52+ AWS_PYOBJECT_KEY_REQUEST_RESPONSE_CLIENT_OPTIONS ,
53+ AWS_PYOBJECT_KEY_MAX_STREAMING_SUBSCRIPTIONS );
54+ if (PyErr_Occurred ()) {
55+ PyErr_Format (PyErr_Occurred (), "Cannot convert max_streaming_subscriptions to a C uint32" );
56+ return false;
57+ }
58+
59+ uint32_t timeout_in_seconds = PyObject_GetAttrAsUint32 (
60+ client_options_py ,
61+ AWS_PYOBJECT_KEY_REQUEST_RESPONSE_CLIENT_OPTIONS ,
62+ AWS_PYOBJECT_KEY_OPERATION_TIMEOUT_IN_SECONDS );
63+ if (PyErr_Occurred ()) {
64+ PyErr_Format (PyErr_Occurred (), "Cannot convert operation_timeout_in_seconds to a C uint32_t" );
65+ return false;
66+ }
67+
68+ client_options -> max_request_response_subscriptions = (size_t )max_request_response_subscriptions ;
69+ client_options -> max_streaming_subscriptions = (size_t )max_streaming_subscriptions ;
70+ client_options -> operation_timeout_seconds = (uint32_t )timeout_in_seconds ;
71+
72+ return true;
73+ }
74+
75+ PyObject * aws_py_mqtt_request_response_client_new_from_5 (PyObject * self , PyObject * args ) {
76+ (void )self ;
77+
78+ PyObject * mqtt5_client_py = NULL ;
79+ PyObject * client_options_py = NULL ;
80+
81+ if (!PyArg_ParseTuple (
82+ args ,
83+ "OO" ,
84+ /* O */ & mqtt5_client_py ,
85+ /* O */ & client_options_py )) {
86+ return NULL ;
87+ }
88+
89+ struct aws_mqtt5_client * protocol_client = aws_py_get_mqtt5_client (mqtt5_client_py );
90+ if (protocol_client == NULL ) {
91+ return NULL ;
92+ }
93+
94+ struct aws_mqtt_request_response_client_options client_options ;
95+ if (!s_init_mqtt_request_response_client_options (& client_options , client_options_py )) {
96+ return NULL ;
97+ }
98+
99+ struct aws_allocator * allocator = aws_py_get_allocator ();
100+
101+ struct aws_mqtt_request_response_client * rr_client =
102+ aws_mqtt_request_response_client_new_from_mqtt5_client (allocator , protocol_client , & client_options );
103+ if (rr_client == NULL ) {
104+ PyErr_SetAwsLastError ();
105+ return NULL ;
106+ }
107+
108+ struct mqtt_request_response_client_binding * client_binding =
109+ aws_mem_calloc (allocator , 1 , sizeof (struct mqtt_request_response_client_binding ));
110+ // Python object that wraps a c struct and a function to call when its reference goes to zero
111+ PyObject * capsule = PyCapsule_New (
112+ client_binding , s_capsule_name_mqtt_request_response_client , s_mqtt_request_response_python_client_destructor );
113+ if (!capsule ) {
114+ aws_mem_release (allocator , client_binding );
115+ aws_mqtt_request_response_client_release (rr_client );
116+ return NULL ;
117+ }
118+
119+ client_binding -> native = rr_client ;
120+
121+ return capsule ;
122+ }
123+
124+ PyObject * aws_py_mqtt_request_response_client_new_from_311 (PyObject * self , PyObject * args ) {
125+ (void )self ;
126+
127+ PyObject * mqtt_connection_py = NULL ;
128+ PyObject * client_options_py = NULL ;
129+
130+ if (!PyArg_ParseTuple (
131+ args ,
132+ "OO" ,
133+ /* O */ & mqtt_connection_py ,
134+ /* O */ & client_options_py )) {
135+ return NULL ;
136+ }
137+
138+ struct aws_mqtt_client_connection * protocol_client = aws_py_get_mqtt_client_connection (mqtt_connection_py );
139+ if (protocol_client == NULL ) {
140+ return NULL ;
141+ }
142+
143+ struct aws_mqtt_request_response_client_options client_options ;
144+ if (!s_init_mqtt_request_response_client_options (& client_options , client_options_py )) {
145+ return NULL ;
146+ }
147+
148+ struct aws_allocator * allocator = aws_py_get_allocator ();
149+
150+ struct aws_mqtt_request_response_client * rr_client =
151+ aws_mqtt_request_response_client_new_from_mqtt311_client (allocator , protocol_client , & client_options );
152+ if (rr_client == NULL ) {
153+ PyErr_SetAwsLastError ();
154+ return NULL ;
155+ }
156+
157+ struct mqtt_request_response_client_binding * client_binding =
158+ aws_mem_calloc (allocator , 1 , sizeof (struct mqtt_request_response_client_binding ));
159+ // Python object that wraps a c struct and a function to call when its reference goes to zero
160+ PyObject * capsule = PyCapsule_New (
161+ client_binding , s_capsule_name_mqtt_request_response_client , s_mqtt_request_response_python_client_destructor );
162+ if (!capsule ) {
163+ aws_mem_release (allocator , client_binding );
164+ aws_mqtt_request_response_client_release (rr_client );
165+ return NULL ;
166+ }
167+
168+ client_binding -> native = rr_client ;
169+
170+ return capsule ;
171+ }
172+
173+ struct aws_mqtt_request_response_client * aws_py_get_mqtt_request_response_client (
174+ PyObject * mqtt_request_response_client ) {
175+ AWS_PY_RETURN_NATIVE_FROM_BINDING (
176+ mqtt_request_response_client ,
177+ s_capsule_name_mqtt_request_response_client ,
178+ "Client" ,
179+ mqtt_request_response_client_binding );
180+ }
0 commit comments