| /** |
| * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. |
| * SPDX-License-Identifier: Apache-2.0. |
| */ |
| |
| #include <jni.h> |
| |
| #include <crt.h> |
| #include <java_class_ids.h> |
| #include <mqtt5_packets.h> |
| #include <mqtt5_utils.h> |
| |
| /* on 32-bit platforms, casting pointers to longs throws a warning we don't need */ |
| #if UINTPTR_MAX == 0xffffffff |
| # if defined(_MSC_VER) |
| # pragma warning(push) |
| # pragma warning(disable : 4305) /* 'type cast': truncation from 'jlong' to 'jni_tls_ctx_options *' */ |
| # else |
| # pragma GCC diagnostic push |
| # pragma GCC diagnostic ignored "-Wpointer-to-int-cast" |
| # pragma GCC diagnostic ignored "-Wint-to-pointer-cast" |
| # endif |
| #endif |
| |
| int s_set_jni_uint32_t_field_in_packet( |
| JNIEnv *env, |
| const uint32_t *native_integer, |
| jobject packet, |
| jfieldID field_id, |
| char *field_name, |
| bool optional) { |
| |
| if (native_integer != NULL) { |
| jobject jni_long = (*env)->NewObject( |
| env, boxed_long_properties.long_class, boxed_long_properties.constructor, (jlong)*native_integer); |
| if (aws_jni_check_and_clear_exception(env)) { |
| AWS_LOGF_ERROR(AWS_LS_MQTT5_CLIENT, "Could not create uint32 field %s", field_name); |
| return AWS_OP_ERR; |
| } |
| (*env)->SetObjectField(env, packet, field_id, jni_long); |
| if (aws_jni_check_and_clear_exception(env)) { |
| AWS_LOGF_ERROR(AWS_LS_MQTT5_CLIENT, "Could not set uint32 field %s", field_name); |
| return AWS_OP_ERR; |
| } |
| if (!optional) { |
| return AWS_OP_SUCCESS; |
| } |
| } |
| if (optional) { |
| return AWS_OP_SUCCESS; |
| } else { |
| return AWS_OP_ERR; |
| } |
| } |
| |
| int s_set_jni_uint16_t_field_in_packet( |
| JNIEnv *env, |
| const uint16_t *native_integer, |
| jobject packet, |
| jfieldID field_id, |
| char *field_name, |
| bool optional) { |
| if (native_integer != NULL) { |
| jobject jni_int = (*env)->NewObject( |
| env, |
| boxed_integer_properties.integer_class, |
| boxed_integer_properties.integer_constructor_id, |
| (jint)*native_integer); |
| if (aws_jni_check_and_clear_exception(env)) { |
| AWS_LOGF_ERROR(AWS_LS_MQTT5_CLIENT, "Could not create uint16 field %s", field_name); |
| return AWS_OP_ERR; |
| } |
| (*env)->SetObjectField(env, packet, field_id, jni_int); |
| if (aws_jni_check_and_clear_exception(env)) { |
| AWS_LOGF_ERROR(AWS_LS_MQTT5_CLIENT, "Could not set uint16 field %s", field_name); |
| return AWS_OP_ERR; |
| } |
| if (!optional) { |
| return AWS_OP_SUCCESS; |
| } |
| } |
| if (optional) { |
| return AWS_OP_SUCCESS; |
| } else { |
| return AWS_OP_ERR; |
| } |
| } |
| |
| int s_set_jni_bool_field_in_packet( |
| JNIEnv *env, |
| const bool *native_boolean, |
| jobject packet, |
| jfieldID field_id, |
| char *field_name, |
| bool optional) { |
| if (native_boolean != NULL) { |
| jobject jni_boolean = (*env)->NewObject( |
| env, |
| boxed_boolean_properties.boolean_class, |
| boxed_boolean_properties.boolean_constructor_id, |
| (jboolean)*native_boolean); |
| if (aws_jni_check_and_clear_exception(env)) { |
| AWS_LOGF_ERROR(AWS_LS_MQTT5_CLIENT, "Could not create boolean field %s", field_name); |
| return AWS_OP_ERR; |
| } |
| |
| (*env)->SetObjectField(env, packet, field_id, jni_boolean); |
| if (aws_jni_check_and_clear_exception(env)) { |
| AWS_LOGF_ERROR(AWS_LS_MQTT5_CLIENT, "Could not set boolean field %s", field_name); |
| return AWS_OP_ERR; |
| } |
| |
| if (!optional) { |
| return AWS_OP_SUCCESS; |
| } |
| } |
| if (optional) { |
| return AWS_OP_SUCCESS; |
| } else { |
| return AWS_OP_ERR; |
| } |
| } |
| |
| int s_set_jni_string_field_in_packet( |
| JNIEnv *env, |
| const struct aws_byte_cursor *native_cursor, |
| jobject packet, |
| jfieldID field_id, |
| char *field_name, |
| bool optional) { |
| if (native_cursor != NULL) { |
| jstring jni_string = aws_jni_string_from_cursor(env, native_cursor); |
| (*env)->SetObjectField(env, packet, field_id, jni_string); |
| if (aws_jni_check_and_clear_exception(env)) { |
| AWS_LOGF_ERROR(AWS_LS_MQTT5_CLIENT, "Could not set string field %s", field_name); |
| return AWS_OP_ERR; |
| } |
| if (!optional) { |
| return AWS_OP_SUCCESS; |
| } |
| } |
| if (optional) { |
| return AWS_OP_SUCCESS; |
| } else { |
| return AWS_OP_ERR; |
| } |
| } |
| |
| int s_set_jni_byte_array_field_in_packet( |
| JNIEnv *env, |
| const struct aws_byte_cursor *native_cursor, |
| jobject packet, |
| jfieldID field_id, |
| char *field_name, |
| bool optional) { |
| if (native_cursor != NULL) { |
| jbyteArray jni_byte = aws_jni_byte_array_from_cursor(env, native_cursor); |
| (*env)->SetObjectField(env, packet, field_id, jni_byte); |
| if (aws_jni_check_and_clear_exception(env)) { |
| AWS_LOGF_ERROR(AWS_LS_MQTT5_CLIENT, "Could not set string field %s", field_name); |
| return AWS_OP_ERR; |
| } |
| if (!optional) { |
| return AWS_OP_SUCCESS; |
| } |
| } |
| if (optional) { |
| return AWS_OP_SUCCESS; |
| } else { |
| return AWS_OP_ERR; |
| } |
| } |
| |
| int s_set_user_properties_field( |
| JNIEnv *env, |
| const size_t user_property_count, |
| const struct aws_mqtt5_user_property *packet_properties, |
| jobject packet, |
| jfieldID user_property_field_id) { |
| /* No properties - nothing to do */ |
| if (packet_properties == NULL) { |
| return AWS_OP_SUCCESS; |
| } |
| |
| if (user_property_count > 0) { |
| jobject jni_user_properties_list = (*env)->NewObject( |
| env, boxed_array_list_properties.list_class, boxed_array_list_properties.list_constructor_id); |
| if (aws_jni_check_and_clear_exception(env)) { |
| AWS_LOGF_ERROR(AWS_LS_MQTT5_CLIENT, "Could not make new user properties list"); |
| return AWS_OP_ERR; |
| } |
| |
| (*env)->SetObjectField(env, packet, user_property_field_id, jni_user_properties_list); |
| if (aws_jni_check_and_clear_exception(env)) { |
| AWS_LOGF_ERROR(AWS_LS_MQTT5_CLIENT, "Could not set new user properties list"); |
| return AWS_OP_ERR; |
| } |
| |
| for (size_t i = 0; i < user_property_count; ++i) { |
| const struct aws_mqtt5_user_property *property = &packet_properties[i]; |
| jstring jni_new_property_name = aws_jni_string_from_cursor(env, &property->name); |
| jstring jni_new_property_value = aws_jni_string_from_cursor(env, &property->value); |
| |
| jobject jni_new_property = (*env)->NewObject( |
| env, |
| mqtt5_user_property_properties.user_property_class, |
| mqtt5_user_property_properties.property_constructor_id, |
| jni_new_property_name, |
| jni_new_property_value); |
| if (aws_jni_check_and_clear_exception(env)) { |
| AWS_LOGF_ERROR(AWS_LS_MQTT5_CLIENT, "Could not make new user property"); |
| return AWS_OP_ERR; |
| } |
| |
| jboolean jni_add_result = (*env)->CallBooleanMethod( |
| env, jni_user_properties_list, boxed_list_properties.list_add_id, jni_new_property); |
| if (aws_jni_check_and_clear_exception(env)) { |
| AWS_LOGF_ERROR(AWS_LS_MQTT5_CLIENT, "Could not add new user property"); |
| return AWS_OP_ERR; |
| } |
| |
| if ((bool)jni_add_result == false) { |
| return AWS_OP_ERR; |
| } |
| } |
| } |
| return AWS_OP_SUCCESS; |
| } |
| |
| int s_set_int_enum_in_packet( |
| JNIEnv *env, |
| const int *int_enum, |
| jobject packet, |
| jmethodID set_enum_field_id, |
| bool optional) { |
| |
| if (int_enum) { |
| if (*int_enum < 0) { |
| return AWS_OP_ERR; |
| } |
| (*env)->CallVoidMethod(env, packet, set_enum_field_id, (jint)*int_enum); |
| if (aws_jni_check_and_clear_exception(env)) { |
| return AWS_OP_ERR; |
| } |
| |
| if (!optional) { |
| return AWS_OP_SUCCESS; |
| } |
| } |
| |
| if (optional) { |
| return AWS_OP_SUCCESS; |
| } else { |
| return AWS_OP_ERR; |
| } |
| } |
| |
| jobject s_aws_mqtt5_client_create_jni_connack_packet_from_native( |
| JNIEnv *env, |
| const struct aws_mqtt5_packet_connack_view *native_connack_data) { |
| |
| jobject connack_data = (*env)->NewObject( |
| env, |
| mqtt5_connack_packet_properties.connack_packet_class, |
| mqtt5_connack_packet_properties.connack_constructor_id); |
| |
| (*env)->SetBooleanField( |
| env, |
| connack_data, |
| mqtt5_connack_packet_properties.connack_session_present_field_id, |
| (jboolean)native_connack_data->session_present); |
| |
| int reason_code_int = (int)native_connack_data->reason_code; |
| if (reason_code_int < 0) { |
| AWS_LOGF_ERROR(AWS_LS_MQTT5_CLIENT, "Error when creating ConnAckPacket from native: Reason code is negative!"); |
| return NULL; |
| } |
| (*env)->CallVoidMethod( |
| env, connack_data, mqtt5_connack_packet_properties.connack_native_add_reason_code_id, (jint)reason_code_int); |
| |
| /* Set all of the optional data in Java classes */ |
| if (s_set_jni_uint32_t_field_in_packet( |
| env, |
| native_connack_data->session_expiry_interval, |
| connack_data, |
| mqtt5_connack_packet_properties.connack_session_expiry_interval_field_id, |
| "session expiry interval", |
| true) != AWS_OP_SUCCESS) { |
| return NULL; |
| } |
| if (s_set_jni_uint16_t_field_in_packet( |
| env, |
| native_connack_data->receive_maximum, |
| connack_data, |
| mqtt5_connack_packet_properties.connack_receive_maximum_field_id, |
| "receive maximum", |
| true) != AWS_OP_SUCCESS) { |
| return NULL; |
| }; |
| |
| if (native_connack_data->maximum_qos) { |
| int *maximum_qos_int = (int *)native_connack_data->maximum_qos; |
| if (s_set_int_enum_in_packet( |
| env, |
| maximum_qos_int, |
| connack_data, |
| mqtt5_connack_packet_properties.connack_native_add_maximum_qos_id, |
| true) != AWS_OP_SUCCESS) { |
| AWS_LOGF_ERROR( |
| AWS_LS_MQTT5_CLIENT, "Error when creating ConnAckPacket from native: Could not set maximum QOS"); |
| return NULL; |
| } |
| } |
| |
| if (s_set_jni_bool_field_in_packet( |
| env, |
| native_connack_data->retain_available, |
| connack_data, |
| mqtt5_connack_packet_properties.connack_retain_available_field_id, |
| "retain available", |
| true) != AWS_OP_SUCCESS) { |
| return NULL; |
| } |
| if (s_set_jni_uint32_t_field_in_packet( |
| env, |
| native_connack_data->maximum_packet_size, |
| connack_data, |
| mqtt5_connack_packet_properties.connack_maximum_packet_size_field_id, |
| "maximum packet size", |
| true) != AWS_OP_SUCCESS) { |
| return NULL; |
| } |
| if (s_set_jni_string_field_in_packet( |
| env, |
| native_connack_data->assigned_client_identifier, |
| connack_data, |
| mqtt5_connack_packet_properties.connack_assigned_client_identifier_field_id, |
| "assigned client identifier", |
| true) != AWS_OP_SUCCESS) { |
| return NULL; |
| } |
| if (s_set_jni_uint16_t_field_in_packet( |
| env, |
| native_connack_data->topic_alias_maximum, |
| connack_data, |
| mqtt5_connack_packet_properties.connack_topic_alias_maximum_field_id, |
| "topic alias maximum", |
| true) != AWS_OP_SUCCESS) { |
| return NULL; |
| }; |
| if (s_set_jni_string_field_in_packet( |
| env, |
| native_connack_data->reason_string, |
| connack_data, |
| mqtt5_connack_packet_properties.connack_reason_string_field_id, |
| "reason string", |
| true) != AWS_OP_SUCCESS) { |
| return NULL; |
| } |
| if (s_set_jni_bool_field_in_packet( |
| env, |
| native_connack_data->wildcard_subscriptions_available, |
| connack_data, |
| mqtt5_connack_packet_properties.connack_wildcard_subscriptions_available_field_id, |
| "wildcard subscriptions available", |
| true) != AWS_OP_SUCCESS) { |
| return NULL; |
| }; |
| if (s_set_jni_bool_field_in_packet( |
| env, |
| native_connack_data->subscription_identifiers_available, |
| connack_data, |
| mqtt5_connack_packet_properties.connack_subscription_identifiers_available_field_id, |
| "subscription identifiers available", |
| true) != AWS_OP_SUCCESS) { |
| return NULL; |
| }; |
| if (s_set_jni_bool_field_in_packet( |
| env, |
| native_connack_data->shared_subscriptions_available, |
| connack_data, |
| mqtt5_connack_packet_properties.connack_shared_subscriptions_available_field_id, |
| "shared subscriptions available", |
| true) != AWS_OP_SUCCESS) { |
| return NULL; |
| }; |
| if (s_set_jni_uint16_t_field_in_packet( |
| env, |
| native_connack_data->server_keep_alive, |
| connack_data, |
| mqtt5_connack_packet_properties.connack_server_keep_alive_field_id, |
| "server keep alive", |
| true) != AWS_OP_SUCCESS) { |
| return NULL; |
| }; |
| if (s_set_jni_string_field_in_packet( |
| env, |
| native_connack_data->response_information, |
| connack_data, |
| mqtt5_connack_packet_properties.connack_response_information_field_id, |
| "response information", |
| true) != AWS_OP_SUCCESS) { |
| return NULL; |
| } |
| if (s_set_jni_string_field_in_packet( |
| env, |
| native_connack_data->server_reference, |
| connack_data, |
| mqtt5_connack_packet_properties.connack_server_reference_field_id, |
| "server reference", |
| true) != AWS_OP_SUCCESS) { |
| return NULL; |
| } |
| |
| if (s_set_user_properties_field( |
| env, |
| native_connack_data->user_property_count, |
| native_connack_data->user_properties, |
| connack_data, |
| mqtt5_connack_packet_properties.connack_user_properties_field_id) != AWS_OP_SUCCESS) { |
| AWS_LOGF_ERROR( |
| AWS_LS_MQTT5_CLIENT, "Error when creating ConnAckPacket from native: could not add user property!"); |
| return NULL; |
| } |
| |
| return connack_data; |
| } |
| |
| jobject s_aws_mqtt5_client_create_jni_disconnect_packet_from_native( |
| JNIEnv *env, |
| const struct aws_mqtt5_packet_disconnect_view *native_disconnect_data) { |
| |
| jobject disconnect_packet_data = (*env)->NewObject( |
| env, |
| mqtt5_disconnect_packet_properties.disconnect_packet_class, |
| mqtt5_disconnect_packet_properties.disconnect_constructor_id); |
| |
| int reason_code_int = (int)native_disconnect_data->reason_code; |
| if (s_set_int_enum_in_packet( |
| env, |
| &reason_code_int, |
| disconnect_packet_data, |
| mqtt5_disconnect_packet_properties.disconnect_native_add_disconnect_reason_code_id, |
| false) != AWS_OP_SUCCESS) { |
| AWS_LOGF_ERROR( |
| AWS_LS_MQTT5_CLIENT, "Error when creating DisconnectPacket from native: Could not set reason code"); |
| return NULL; |
| } |
| |
| if (s_set_jni_uint32_t_field_in_packet( |
| env, |
| native_disconnect_data->session_expiry_interval_seconds, |
| disconnect_packet_data, |
| mqtt5_disconnect_packet_properties.disconnect_session_expiry_interval_seconds_field_id, |
| "session expiry interval seconds", |
| true) != AWS_OP_SUCCESS) { |
| return NULL; |
| } |
| if (s_set_jni_string_field_in_packet( |
| env, |
| native_disconnect_data->reason_string, |
| disconnect_packet_data, |
| mqtt5_disconnect_packet_properties.disconnect_reason_string_field_id, |
| "reason string", |
| true) != AWS_OP_SUCCESS) { |
| return NULL; |
| } |
| if (s_set_jni_string_field_in_packet( |
| env, |
| native_disconnect_data->server_reference, |
| disconnect_packet_data, |
| mqtt5_disconnect_packet_properties.disconnect_session_server_reference_field_id, |
| "server reference", |
| true) != AWS_OP_SUCCESS) { |
| return NULL; |
| } |
| |
| if (s_set_user_properties_field( |
| env, |
| native_disconnect_data->user_property_count, |
| native_disconnect_data->user_properties, |
| disconnect_packet_data, |
| mqtt5_disconnect_packet_properties.disconnect_user_properties_field_id) != AWS_OP_SUCCESS) { |
| AWS_LOGF_ERROR( |
| AWS_LS_MQTT5_CLIENT, "Error when creating DisconnectPacket from native: could not add user property!"); |
| return NULL; |
| } |
| |
| return disconnect_packet_data; |
| } |
| |
| jobject s_aws_mqtt5_client_create_jni_negotiated_settings_from_native( |
| JNIEnv *env, |
| const struct aws_mqtt5_negotiated_settings *native_negotiated_settings_data) { |
| |
| jobject negotiated_settings_data = (*env)->NewObject( |
| env, |
| mqtt5_negotiated_settings_properties.negotiated_settings_class, |
| mqtt5_negotiated_settings_properties.negotiated_settings_constructor_id); |
| |
| (*env)->CallVoidMethod( |
| env, |
| negotiated_settings_data, |
| mqtt5_negotiated_settings_properties.negotiated_settings_native_set_qos_id, |
| (jint)native_negotiated_settings_data->maximum_qos); |
| aws_jni_check_and_clear_exception(env); /* To hide JNI warning */ |
| |
| (*env)->SetLongField( |
| env, |
| negotiated_settings_data, |
| mqtt5_negotiated_settings_properties.negotiated_settings_session_expiry_interval_field_id, |
| (jlong)native_negotiated_settings_data->session_expiry_interval); |
| (*env)->SetIntField( |
| env, |
| negotiated_settings_data, |
| mqtt5_negotiated_settings_properties.negotiated_settings_receive_maximum_from_server_field_id, |
| (jint)native_negotiated_settings_data->receive_maximum_from_server); |
| (*env)->SetLongField( |
| env, |
| negotiated_settings_data, |
| mqtt5_negotiated_settings_properties.negotiated_settings_maximum_packet_size_to_server_field_id, |
| (jlong)native_negotiated_settings_data->maximum_packet_size_to_server); |
| (*env)->SetIntField( |
| env, |
| negotiated_settings_data, |
| mqtt5_negotiated_settings_properties.negotiated_settings_topic_alias_maximum_to_server_field_id, |
| (jint)native_negotiated_settings_data->topic_alias_maximum_to_server); |
| (*env)->SetIntField( |
| env, |
| negotiated_settings_data, |
| mqtt5_negotiated_settings_properties.negotiated_settings_topic_alias_maximum_to_client_field_id, |
| (jint)native_negotiated_settings_data->topic_alias_maximum_to_client); |
| (*env)->SetIntField( |
| env, |
| negotiated_settings_data, |
| mqtt5_negotiated_settings_properties.negotiated_settings_server_keep_alive_field_id, |
| (jint)native_negotiated_settings_data->server_keep_alive); |
| (*env)->SetBooleanField( |
| env, |
| negotiated_settings_data, |
| mqtt5_negotiated_settings_properties.negotiated_settings_retain_available_field_id, |
| (jboolean)native_negotiated_settings_data->retain_available); |
| (*env)->SetBooleanField( |
| env, |
| negotiated_settings_data, |
| mqtt5_negotiated_settings_properties.negotiated_settings_wildcard_subscriptions_available_field_id, |
| (jboolean)native_negotiated_settings_data->wildcard_subscriptions_available); |
| (*env)->SetBooleanField( |
| env, |
| negotiated_settings_data, |
| mqtt5_negotiated_settings_properties.negotiated_settings_subscription_identifiers_available_field_id, |
| (jboolean)native_negotiated_settings_data->subscription_identifiers_available); |
| (*env)->SetBooleanField( |
| env, |
| negotiated_settings_data, |
| mqtt5_negotiated_settings_properties.negotiated_settings_shared_subscriptions_available_field_id, |
| (jboolean)native_negotiated_settings_data->shared_subscriptions_available); |
| (*env)->SetBooleanField( |
| env, |
| negotiated_settings_data, |
| mqtt5_negotiated_settings_properties.negotiated_settings_rejoined_session_field_id, |
| (jboolean)native_negotiated_settings_data->rejoined_session); |
| |
| struct aws_byte_cursor client_id_storage_cursor = |
| aws_byte_cursor_from_buf(&native_negotiated_settings_data->client_id_storage); |
| jstring jni_assigned_client_id = aws_jni_string_from_cursor(env, &client_id_storage_cursor); |
| (*env)->SetObjectField( |
| env, |
| negotiated_settings_data, |
| mqtt5_negotiated_settings_properties.negotiated_settings_assigned_client_id_field_id, |
| jni_assigned_client_id); |
| |
| return negotiated_settings_data; |
| } |
| |
| jobject s_aws_mqtt5_client_create_jni_publish_packet_from_native( |
| JNIEnv *env, |
| const struct aws_mqtt5_packet_publish_view *publish) { |
| jobject publish_packet_data = (*env)->NewObject( |
| env, |
| mqtt5_publish_packet_properties.publish_packet_class, |
| mqtt5_publish_packet_properties.publish_constructor_id); |
| |
| jbyteArray jni_payload = aws_jni_byte_array_from_cursor(env, &publish->payload); |
| (*env)->SetObjectField( |
| env, publish_packet_data, mqtt5_publish_packet_properties.publish_payload_field_id, jni_payload); |
| |
| int publish_qos_int = (int)publish->qos; |
| if (s_set_int_enum_in_packet( |
| env, |
| &publish_qos_int, |
| publish_packet_data, |
| mqtt5_publish_packet_properties.publish_native_set_qos_id, |
| false) != AWS_OP_SUCCESS) { |
| AWS_LOGF_ERROR(AWS_LS_MQTT5_CLIENT, "Error when creating PublishPacket from native: Could not set QOS"); |
| return NULL; |
| } |
| |
| if (s_set_jni_bool_field_in_packet( |
| env, |
| &publish->retain, |
| publish_packet_data, |
| mqtt5_publish_packet_properties.publish_retain_field_id, |
| "retain", |
| false) != AWS_OP_SUCCESS) { |
| AWS_LOGF_ERROR(AWS_LS_MQTT5_CLIENT, "Error when creating PublishPacket from native: Could not set retain"); |
| return NULL; |
| } |
| |
| jstring jni_topic = aws_jni_string_from_cursor(env, &publish->topic); |
| (*env)->SetObjectField(env, publish_packet_data, mqtt5_publish_packet_properties.publish_topic_field_id, jni_topic); |
| |
| if (publish->payload_format) { |
| if (s_set_int_enum_in_packet( |
| env, |
| (int *)publish->payload_format, |
| publish_packet_data, |
| mqtt5_publish_packet_properties.publish_native_set_payload_format_indicator_id, |
| true) != AWS_OP_SUCCESS) { |
| AWS_LOGF_ERROR( |
| AWS_LS_MQTT5_CLIENT, "Error when creating PublishPacket from native: Could not set payload format"); |
| return NULL; |
| } |
| } |
| |
| if (s_set_jni_uint32_t_field_in_packet( |
| env, |
| publish->message_expiry_interval_seconds, |
| publish_packet_data, |
| mqtt5_publish_packet_properties.publish_message_expiry_interval_seconds_field_id, |
| "message expiry interval seconds", |
| true) != AWS_OP_SUCCESS) { |
| return NULL; |
| } |
| |
| if (s_set_jni_uint16_t_field_in_packet( |
| env, |
| publish->topic_alias, |
| publish_packet_data, |
| mqtt5_publish_packet_properties.publish_topic_alias_field_id, |
| "topic alias", |
| true) != AWS_OP_SUCCESS) { |
| return NULL; |
| } |
| |
| if (s_set_jni_string_field_in_packet( |
| env, |
| publish->response_topic, |
| publish_packet_data, |
| mqtt5_publish_packet_properties.publish_response_topic_field_id, |
| "response topic", |
| true) != AWS_OP_SUCCESS) { |
| return NULL; |
| } |
| |
| if (s_set_jni_byte_array_field_in_packet( |
| env, |
| publish->correlation_data, |
| publish_packet_data, |
| mqtt5_publish_packet_properties.publish_correlation_data_field_id, |
| "correlation data", |
| true) != AWS_OP_SUCCESS) { |
| return NULL; |
| } |
| |
| if (s_set_jni_string_field_in_packet( |
| env, |
| publish->content_type, |
| publish_packet_data, |
| mqtt5_publish_packet_properties.publish_content_type_field_id, |
| "content type", |
| true) != AWS_OP_SUCCESS) { |
| return NULL; |
| } |
| |
| if (publish->subscription_identifier_count && publish->subscription_identifiers) { |
| jobject jni_subscription_identifiers = (*env)->NewObject( |
| env, boxed_array_list_properties.list_class, boxed_array_list_properties.list_constructor_id); |
| (*env)->SetObjectField( |
| env, |
| publish_packet_data, |
| mqtt5_publish_packet_properties.publish_subscription_identifiers_field_id, |
| jni_subscription_identifiers); |
| |
| for (size_t i = 0; i < publish->subscription_identifier_count; ++i) { |
| const uint32_t *identifier = &publish->subscription_identifiers[i]; |
| jobject jni_identifier_obj = (*env)->NewObject( |
| env, boxed_long_properties.long_class, boxed_long_properties.constructor, (jlong)*identifier); |
| jboolean jni_add_result = (*env)->CallBooleanMethod( |
| env, jni_subscription_identifiers, boxed_list_properties.list_add_id, jni_identifier_obj); |
| if (aws_jni_check_and_clear_exception(env)) { |
| AWS_LOGF_ERROR( |
| AWS_LS_MQTT5_CLIENT, |
| "When creating PublishPacket from native could not add subscription identifier!"); |
| return NULL; |
| } |
| if ((bool)jni_add_result == false) { |
| AWS_LOGF_ERROR( |
| AWS_LS_MQTT5_CLIENT, |
| "When creating PublishPacket from native could not add subscription identifier!"); |
| return NULL; |
| } |
| } |
| } |
| |
| if (s_set_user_properties_field( |
| env, |
| publish->user_property_count, |
| publish->user_properties, |
| publish_packet_data, |
| mqtt5_publish_packet_properties.publish_user_properties_field_id) == AWS_OP_ERR) { |
| AWS_LOGF_ERROR(AWS_LS_MQTT5_CLIENT, "When creating PublishPacket from native could not add user properties!"); |
| return NULL; |
| } |
| |
| return publish_packet_data; |
| } |
| |
| jobject s_aws_mqtt5_client_create_jni_puback_packet_from_native( |
| JNIEnv *env, |
| struct aws_mqtt5_packet_puback_view *puback_packet) { |
| /* Make the PubAck packet */ |
| jobject puback_packet_data = (*env)->NewObject( |
| env, mqtt5_puback_packet_properties.puback_packet_class, mqtt5_puback_packet_properties.puback_constructor_id); |
| |
| int reason_code_int = (int)puback_packet->reason_code; |
| if (s_set_int_enum_in_packet( |
| env, |
| &reason_code_int, |
| puback_packet_data, |
| mqtt5_puback_packet_properties.puback_native_add_reason_code_id, |
| false) != AWS_OP_SUCCESS) { |
| AWS_LOGF_ERROR(AWS_LS_MQTT5_CLIENT, "Error when creating PubAck result from native: Could not set reason code"); |
| return NULL; |
| } |
| if (s_set_jni_string_field_in_packet( |
| env, |
| puback_packet->reason_string, |
| puback_packet_data, |
| mqtt5_puback_packet_properties.puback_reason_string_field_id, |
| "reason string", |
| true) != AWS_OP_SUCCESS) { |
| return NULL; |
| } |
| if (s_set_user_properties_field( |
| env, |
| puback_packet->user_property_count, |
| puback_packet->user_properties, |
| puback_packet_data, |
| mqtt5_puback_packet_properties.puback_user_properties_field_id) == AWS_OP_ERR) { |
| AWS_LOGF_ERROR(AWS_LS_MQTT5_CLIENT, "When creating PubAckPacket from native could not add user property!"); |
| return NULL; |
| } |
| return puback_packet_data; |
| } |