axl_bool vortex_sequencer_direct_send (VortexConnection * connection, VortexChannel * channel, VortexWriterData * packet) { /* reply number */ axl_bool result = axl_true; #if defined(ENABLE_VORTEX_LOG) VortexCtx * ctx = vortex_connection_get_ctx (connection); #endif #if defined(ENABLE_VORTEX_LOG) /* send the frame */ if (vortex_log2_is_enabled (ctx)) vortex_log2 (VORTEX_LEVEL_DEBUG, "Sending message, size (%d) over channel=%d (%p), connection id=%d, errno=%d, Content: \n%s", packet->the_size, vortex_channel_get_number (channel), channel, vortex_connection_get_id (connection), errno, packet->the_frame); else vortex_log (VORTEX_LEVEL_DEBUG, "Sending message, size (%d) over channel=%d (%p), connection id=%d, errno=%d", packet->the_size, vortex_channel_get_number (channel), channel, vortex_connection_get_id (connection), errno); #endif if (! vortex_frame_send_raw (connection, packet->the_frame, packet->the_size)) { /* drop a log */ vortex_log (VORTEX_LEVEL_CRITICAL, "unable to send frame over connection id=%d: errno=(%d): %s", vortex_connection_get_id (connection), errno, vortex_errno_get_error (errno)); /* set as non connected and flag the result */ result = axl_false; } /* signal the message have been sent */ if ((packet->type == VORTEX_FRAME_TYPE_RPY || packet->type == VORTEX_FRAME_TYPE_NUL) && packet->is_complete && ! packet->fixed_more) { /* update reply sent */ vortex_channel_update_status (channel, 0, packet->msg_no, UPDATE_RPY_NO_WRITTEN); /* unblock waiting thread for replies sent */ vortex_channel_signal_reply_sent_on_close_blocked (channel); /* signal reply sent */ vortex_channel_signal_rpy_sent (channel, packet->msg_no); } /* nothing more */ return result; }
/** * @brief The ppath_selected function is used by turbulence to signal * modules that a connection was finally configured under the provided * profile path. This is important because a profile path defines how * the connection will be limited and configured to accept profiles, * configuring process permission and so on. * * It is also useful because at the time a profile path is selected, * serverName name is available, allowing the module to take especial * actions. * * @param ctx The \ref TurbulenceCtx where the profile path was selected. * * @param ppath_selected Reference to the object representing the profile path selected. See \ref turbulence_ppath. * * @param conn The VortexConnection object that was configured with the provided profile path. * * @return axl_true to accept or not the connection. Keep in mind * returning axl_false may also terminate current child process * (according to \ref turbulence_clean_start "clean start" configuration). */ static axl_bool test_ppath_selected (TurbulenceCtx * ctx, TurbulencePPathDef * ppath_selected, VortexConnection * conn) { msg ("Turbulence configured ppath %s to connection id %d", turbulence_ppath_get_name (ppath_selected), vortex_connection_get_id (conn)); return axl_true; }
axl_bool vortex_sequencer_queue_data (VortexCtx * ctx, VortexSequencerData * data) { axl_bool is_stalled; v_return_val_if_fail (data, axl_false); /* check state before handling this message with the sequencer */ if (ctx->vortex_exit || ctx->sequencer_state == NULL || ctx->sequencer_state->exit) { vortex_payload_feeder_unref (data->feeder); axl_free (data->message); axl_free (data); return axl_false; } /* update channel reference (this reference is associated to the data) */ /* if (! vortex_channel_ref (data->channel)) { vortex_log (VORTEX_LEVEL_WARNING, "trying to queue a message to be sent over a channel not opened (vortex_channel_ref failed)"); vortex_payload_feeder_unref (data->feeder); axl_free (data->message); axl_free (data); return axl_false; } */ vortex_log2 (VORTEX_LEVEL_DEBUG, "new message to be sent: msgno %d, channel %d, conn-id=%d, is-stalled: %d (size: %d):\n%s", data->msg_no, data->channel_num, vortex_connection_get_id (vortex_channel_get_connection (data->channel)), vortex_channel_is_stalled (data->channel), data->message_size, data->message ? data->message : "**** empty message ****"); /* get current is stalled status */ is_stalled = vortex_channel_is_stalled (data->channel); /* add the channel to the sequencer structure */ if (! vortex_sequencer_add_channel (ctx, data)) return axl_false; /* signal sequencer (but only if the channel is not stalled) */ if (! is_stalled) vortex_sequencer_signal (ctx); return axl_true; }
/* mod_test_11 ppath-selected handler */ static axl_bool mod_test_11_ppath_selected (TurbulenceCtx * _ctx, TurbulencePPathDef * ppath_selected, VortexConnection * conn) { /* mutex lock */ vortex_mutex_lock (&mutex); /* unlock mutex */ vortex_mutex_unlock (&mutex); msg ("Test 11: received profile path selected %s, connection id %d", turbulence_ppath_get_name (ppath_selected), vortex_connection_get_id (conn)); /* register a profile at this point */ vortex_profiles_register (TBC_VORTEX_CTX (ctx), "urn:aspl.es:beep:profiles:reg-test:profile-11", NULL, NULL, NULL, NULL, mod_test_11_frame_received, NULL); /* notification ok */ return true; } /* end mod_test_11_ppath_selected */
void test_20_frame_received (VortexChannel * channel, VortexConnection * conn, VortexFrame * frame, axlPointer user_data) { const char * profile_path; TurbulencePPathDef * ppath; char * conn_id; if (axl_cmp ((const char *) vortex_frame_get_payload (frame), "get-profile-path-name")) { /* get profile path */ ppath = turbulence_ppath_selected (conn); if (ppath == NULL) { vortex_channel_send_rpy (channel, "no profile path selected!!!", 27, vortex_frame_get_msgno (frame)); return; } /* end if */ /* get profile path name */ profile_path = turbulence_ppath_get_name (ppath); if (profile_path == NULL) { vortex_channel_send_rpy (channel, "no profile path name defined", 28, vortex_frame_get_msgno (frame)); return; } printf ("Test 20: CHILD: returning profile path name: %s\n", profile_path); /* set profile path name */ vortex_channel_send_rpy (channel, profile_path, strlen (profile_path), vortex_frame_get_msgno (frame)); return; } /* send conn-id in case no other command was received */ conn_id = axl_strdup_printf ("%d", vortex_connection_get_id (conn)); vortex_channel_send_rpy (channel, conn_id, strlen (conn_id), vortex_frame_get_msgno (frame)); axl_free (conn_id); return; }
axl_bool __mod_sasl_mysql_prepare_query_and_auth (TurbulenceCtx * ctx, const char * _query, VortexConnection * conn, axlNode * auth_db_node_conf, const char * auth_id, const char * authorization_id, const char * formated_password, const char * password, const char * serverName, const char * sasl_method, axl_bool just_run_query, axl_bool skip_login_error_reporting, axlError ** err) { MYSQL_RES * result; MYSQL_ROW row; axl_bool _result; char * query; /* duplicate query */ query = axl_strdup (_query); if (query == NULL) return axl_false; /* allocation failure */ /* replace query with recognized tokens */ axl_replace (query, "%u", auth_id); axl_replace (query, "%n", serverName); axl_replace (query, "%i", authorization_id); axl_replace (query, "%m", sasl_method); axl_replace (query, "%p", vortex_connection_get_host (conn)); if (! just_run_query) { msg ("Trying to auth [%s] with query string [%s], conn-id=%d from %s:%s ", auth_id, query, vortex_connection_get_id (conn), vortex_connection_get_host (conn), vortex_connection_get_port (conn)); } /* end if */ /* run query */ result = mod_sasl_mysql_do_query (ctx, auth_db_node_conf, query, axl_false, err); axl_free (query); /* check if we have to only run this query */ if (just_run_query) { mysql_free_result (result); return axl_true; } /* end if */ /* check result */ if (result == NULL) { error ("Unable to authenticate user, query string failed with %s", axl_error_get (*err)); axl_error_free (*err); return axl_false; } /* end if */ /* return content from the first [0][0] array position */ row = mysql_fetch_row (result); if (row == NULL) { if (! skip_login_error_reporting) { /* log login failure */ error ("login failure: %s, failed from: %s", auth_id, vortex_connection_get_host_ip (conn)); } /* end if */ mysql_free_result (result); return axl_false; } /* end if */ /* check result */ _result = axl_cmp (row[0], formated_password); if (! _result) { /* if it fails, check password format */ /* support here passwords schemes using */ /* http://wiki.dovecot.org/Authentication/PasswordSchemes */ _result = common_sasl_check_crypt_password (password, row[0]); } /* end if */ mysql_free_result (result); return _result; }
void vortex_sequencer_process_channels (VortexCtx * ctx, VortexSequencerState * state, axl_bool process_channel_0) { axl_bool paused; axl_bool complete; axl_bool is_empty; axl_bool is_stalled; VortexChannel * channel = NULL; VortexConnection * conn = NULL; /* now iterate all ready channels */ axl_hash_cursor_first (state->ready_cursor); while (axl_hash_cursor_has_item (state->ready_cursor)) { /* get the channel and manage it, unlocking * during the process */ channel = axl_hash_cursor_get_key (state->ready_cursor); /* check for remove flag */ if (PTR_TO_INT (vortex_channel_get_data (channel, "vo:seq:del"))) { axl_hash_cursor_remove (state->ready_cursor); continue; } /* check if channel is stalled */ if (vortex_channel_is_stalled (channel)) { vortex_log (VORTEX_LEVEL_DEBUG, "channel=%d (%p) is stalled, removing from ready set", vortex_channel_get_number (channel), channel); axl_hash_cursor_remove (state->ready_cursor); continue; } /* end if */ /* check what kind of channel is this to know if we * have to process it */ if (process_channel_0 && vortex_channel_get_number (channel) != 0) { axl_hash_cursor_next (state->ready_cursor); continue; } if (!process_channel_0 && vortex_channel_get_number (channel) == 0) { axl_hash_cursor_next (state->ready_cursor); continue; } /* get connection reference */ conn = vortex_channel_get_connection (channel); /* acquire connection */ if (! vortex_connection_ref (conn, "vortex-sequencer")) { vortex_log (VORTEX_LEVEL_CRITICAL, "Unable to acquire reference to the connection (%p) inside vortex sequencer to do sending round, dropping channel (%p)", conn, channel); axl_hash_cursor_remove (state->ready_cursor); continue; } /* end if */ vortex_log (VORTEX_LEVEL_DEBUG, "handling next send channel=%d (%p), conn-id=%d (%p)", vortex_channel_get_number (channel), channel, vortex_connection_get_id (conn), conn); /* unlock and call */ vortex_mutex_unlock (&state->mutex); /* call to do send operation */ paused = axl_false; complete = axl_false; is_empty = axl_false; __vortex_sequencer_do_send_round (ctx, channel, conn, &paused, &complete); vortex_log (VORTEX_LEVEL_DEBUG, "it seems the message was sent completely over conn-id=%d, channel=%d (%p)", vortex_connection_get_id (conn), vortex_channel_get_number (channel), channel); /* release connection (unlock mutex to allow * connection close process to reenter into * sequencer module) */ vortex_connection_unref (conn, "vortex-sequencer"); vortex_mutex_lock (&state->mutex); /* remove message sent */ is_stalled = vortex_channel_is_stalled (channel); if (complete) { /* remove message sent */ is_empty = vortex_sequencer_remove_message_sent (ctx, channel); } /* end if */ /* check for remove flag */ if (PTR_TO_INT (vortex_channel_get_data (channel, "vo:seq:del"))) { axl_hash_cursor_remove (state->ready_cursor); continue; } /* check channel after send operation */ if (is_empty) { vortex_log (VORTEX_LEVEL_DEBUG, "Channel %p is empty (no more pending messages), removing from sequencer", channel); /* no more send operations, remove channel from our registry but check * first it wasn't removed during the unlock */ axl_hash_cursor_remove (state->ready_cursor); continue; } /* now check stalled channel */ if (is_stalled || paused) { vortex_log (VORTEX_LEVEL_DEBUG, "Channel %p is stalled or paused, removing from sequencer", channel); /* no more send operations, remove channel from our registry but check * first it wasn't removed during the unlock */ axl_hash_cursor_remove (state->ready_cursor); continue; } /* end if */ /* next item */ axl_hash_cursor_next (state->ready_cursor); } /* end while */ return; }
/** * @internal Function that does a send round for a channel. The * function assumes the channel is not stalled (but can end stalled * after the function finished). * */ void __vortex_sequencer_do_send_round (VortexCtx * ctx, VortexChannel * channel, VortexConnection * conn, axl_bool * paused, axl_bool * complete) { VortexSequencerData * data; #if defined(ENABLE_VORTEX_LOG) int message_size; int max_seq_no = 0; #endif int size_to_copy; VortexWriterData packet; /* get data from channel */ data = vortex_channel_next_pending_message (channel); if (data == NULL) { /* no pending message on this channel */ vortex_log (VORTEX_LEVEL_DEBUG, "no data were found to sequence on this channel, remove channel"); return; } vortex_log (VORTEX_LEVEL_DEBUG, "a new message to be sequenced: (conn-id=%d, channel=%d, size=%d)..", vortex_connection_get_id (conn), data->channel_num, data->message_size); /* if feeder is defined, get pending message size */ if (data->feeder) data->message_size = vortex_payload_feeder_get_pending_size (data->feeder); /* refresh all sending data */ data->first_seq_no = vortex_channel_get_next_seq_no (channel); #if defined(ENABLE_VORTEX_LOG) message_size = data->message_size; max_seq_no = vortex_channel_get_max_seq_no_remote_accepted (channel); #endif vortex_log (VORTEX_LEVEL_DEBUG, "sequence operation (%p): type=%d, msgno=%d, next seq no=%u message size=%d max seq no=%u step=%u", data, data->type, data->msg_no, data->first_seq_no, message_size, max_seq_no, data->step); /* build the packet to send */ size_to_copy = vortex_sequencer_build_packet_to_send (ctx, channel, conn, data, &packet); *complete = packet.is_complete; /* check if the transfer is cancelled or paused */ if (size_to_copy < 0) { *paused = axl_true; return; } /* STEP 1: now queue the rest of the message if it wasn't * completly sequence. We do this before sending the frame to * avoid a possible race condition between sending the message * sequenced, be processed at the remote side, the remote side * generate a SEQ frame, send it, and our vortex reader * process it, finding that there is not pending, not yet * completely sequenced message. * * Incredible, but true! */ if (! packet.is_complete) { /* well, it seems we didn't be able to send the hole * message, so there are some remaining bytes. Just * keep track about how many bytes we have sent. We * will used this information once the message is * enabled to be sent again on the next SEQ * received. */ data->step = data->step + size_to_copy; /* make next seq no value to point to the next byte to send */ data->first_seq_no = (data->first_seq_no + size_to_copy) % (MAX_SEQ_NO); /* make message size to be decreased the amount of bytes sent. */ data->message_size = data->message_size - size_to_copy; vortex_log (VORTEX_LEVEL_DEBUG, "updating message sequencing status: next seq no=%u max seq no accepted=%u message size=%d step=%u", data->first_seq_no, max_seq_no, data->message_size, data->step); vortex_log (VORTEX_LEVEL_DEBUG, "the message sequenced is not going to be sent completely (%d != %d)", size_to_copy, message_size); } /* end if */ /* because we have sent the message, update remote seqno buffer used */ vortex_channel_update_status (channel, size_to_copy, 0, UPDATE_SEQ_NO); /* STEP 2: now, send the package built, queueing it at the * channel queue. At this point, we have prepared the rest to * be sequenced message. */ /* now, perform a send operation for the frame built */ vortex_log (VORTEX_LEVEL_DEBUG, "frame built, send the frame directly (over channel=%d, conn-id=%d)", vortex_channel_get_number (channel), vortex_connection_get_id (conn)); if (! vortex_sequencer_direct_send (conn, channel, &packet)) { vortex_log (VORTEX_LEVEL_WARNING, "unable to send data at this moment"); return; } /* that's all vortex sequencer process can do */ return; }
int vortex_sequencer_build_packet_to_send (VortexCtx * ctx, VortexChannel * channel, VortexConnection * conn, VortexSequencerData * data, VortexWriterData * packet) { int size_to_copy = 0; unsigned int max_seq_no_accepted = vortex_channel_get_max_seq_no_remote_accepted (channel); char * payload = NULL; /* clear packet */ memset (packet, 0, sizeof (VortexWriterData)); /* flag as not complete until something different is set */ packet->is_complete = axl_false; /* check particular case where an empty message is to be sent * and the message is NUL */ if (data->message_size == 0 && data->type == VORTEX_FRAME_TYPE_NUL) goto build_frame; /* calculate how many bytes to copy from the payload * according to max_seq_no */ size_to_copy = vortex_channel_get_next_frame_size (channel, data->first_seq_no, data->message_size, max_seq_no_accepted); /* check that the next_frame_size do not report wrong values */ if (size_to_copy > data->message_size || size_to_copy <= 0) { __vortex_connection_shutdown_and_record_error ( conn, VortexProtocolError, "vortex_channel_get_next_frame_size is reporting wrong values (size to copy: %d > message size: %d), this will cause protocol failures...shutdown connection id=%d (channel stalled: %d)", size_to_copy, data->message_size, vortex_connection_get_id (conn), vortex_channel_is_stalled (channel)); return 0; } /* check here if we have a feeder defined */ if (data->feeder) { if (data->feeder->status == 0) { /* check and increase buffer */ CHECK_AND_INCREASE_BUFFER (size_to_copy, ctx->sequencer_feeder_buffer, ctx->sequencer_feeder_buffer_size); /* get content available at this moment to be sent */ size_to_copy = vortex_payload_feeder_get_content (data->feeder, size_to_copy, ctx->sequencer_feeder_buffer); } else { vortex_log (VORTEX_LEVEL_DEBUG, "feeder cancelled, close transfer status is: %d", data->feeder->close_transfer); if (! data->feeder->close_transfer) { /* also record current msgno to continue in the future */ data->feeder->msg_no = data->msg_no; /* remove queued request if found same pointer */ if (data == vortex_channel_next_pending_message (channel)) { /* remove the queued request but ensure we are the only thread touching this */ vortex_sequencer_remove_message_sent (ctx, channel); } /* signal caller to stop delivering this content */ return -1; } /* end if */ /* flag this feeder is about being cancelled/paused */ size_to_copy = -1; } /* end if */ } /* end if */ vortex_log (VORTEX_LEVEL_DEBUG, "the channel=%d (on conn-id=%d) is not stalled, continue with sequencing, about to send (size_to_copy:%d) bytes as payload (buffer:%d)...", vortex_channel_get_number (channel), vortex_connection_get_id (vortex_channel_get_connection (channel)), size_to_copy, ctx->sequencer_send_buffer_size); vortex_log (VORTEX_LEVEL_DEBUG, "channel remote max seq no accepted: %u (proposed: %u)...", vortex_channel_get_max_seq_no_remote_accepted (channel), max_seq_no_accepted); /* create the new package to be managed by the vortex writer */ packet->msg_no = data->msg_no; if (size_to_copy > 0) { /* check if we have to realloc buffer */ CHECK_AND_INCREASE_BUFFER (size_to_copy, ctx->sequencer_send_buffer, ctx->sequencer_send_buffer_size); } /* we have the payload on buffer */ build_frame: /* set datatype for this package */ packet->type = data->type; /* report what we are going to sequence */ vortex_log (VORTEX_LEVEL_DEBUG, "sequencing next message: type=%d, channel num=%d, msgno=%d, more=%d, next seq=%u size=%d ansno=%d", data->type, data->channel_num, data->msg_no, !(data->message_size == size_to_copy), data->first_seq_no, size_to_copy, data->ansno); vortex_log (VORTEX_LEVEL_DEBUG, " message=%p, step=%u, message-size=%u", data->message, data->step, data->message_size); /* point to payload */ if (data->feeder) { payload = (size_to_copy > 0) ? ctx->sequencer_feeder_buffer : NULL; } else payload = (data->message != NULL) ? (data->message + data->step) : NULL; /* check if the packet is complete (either last frame or all * the payload fits into a single frame */ if (data->feeder) { /* prepare is complete flag */ packet->is_complete = (data->feeder->status != 0 && data->feeder->close_transfer) ? axl_true : vortex_payload_feeder_is_finished (data->feeder); /* normalize size_to_copy to avoid the caller to skipp ending this empty frame */ if (size_to_copy < 0) size_to_copy = 0; } else packet->is_complete = (size_to_copy == data->message_size); /* build frame */ packet->the_frame = vortex_frame_build_up_from_params_s_buffer ( data->type, /* frame type to be created */ data->channel_num, /* channel number the frame applies to */ data->msg_no, /* the message number */ /* frame payload size to be created */ !packet->is_complete || data->fixed_more, /* have more frames */ data->first_seq_no, /* sequence number for the frame to be created */ /* size for the payload starting from previous sequence number */ size_to_copy, /* an optional ansno value, only used for ANS frames */ data->ansno, /* no mime configuration, already handled from vortex channel module */ NULL, /* no mime configuration for transfer encoding, * already handler by vortex channel module */ NULL, /* the frame payload itself */ payload, /* calculated frame size */ &(packet->the_size), /* buffer and its size */ ctx->sequencer_send_buffer, ctx->sequencer_send_buffer_size); /* update fixed more flag on packet */ packet->fixed_more = data->fixed_more; /* return size used from the entire message */ return size_to_copy; }
/** * implements vortex.tls.start_tls */ int lua_vortex_tls_start_tls (lua_State * L) { VortexConnection ** conn; VortexConnection * conn2; VortexStatus status = VortexError; char * status_msg = NULL; const char * serverName = NULL; LuaVortexRefs * references = NULL; /* check parameters */ if (! lua_vortex_check_params (L, "o|zfd")) return 0; /* get context */ conn = lua_touserdata (L, 1); /* get serverName value */ if (lua_gettop (L) > 1) serverName = lua_tostring (L, 2); /* acquire a reference to the connection during the process */ if (! vortex_connection_ref (*conn, "start tls")) { lua_vortex_error (L, "Failed to acquire reference to the connection during handshake.."); return 0; } /* end if */ lua_vortex_log (LUA_VORTEX_DEBUG, "Starting TLS process over conn-id=%d, with ref count=%d", vortex_connection_get_id (*conn), vortex_connection_ref_count (*conn)); /* check for async notification */ if (lua_gettop (L) > 2) { lua_vortex_log (LUA_VORTEX_DEBUG, "Detected async tls activation.."); /* create reference */ references = lua_vortex_acquire_references (CONN_CTX (*conn), L, 3, 4, 0); /* call to start TLS async */ vortex_tls_start_negotiation (*conn, lua_tostring (L, 2), lua_vortex_tls_bridge_async_notify, references); return 0; } /* end if */ /* unlock during operation */ LUA_VORTEX_UNLOCK (L, axl_false); /* call to authenticate in a blocking manner */ conn2 = vortex_tls_start_negotiation_sync (*conn, serverName, &status, &status_msg); lua_vortex_log (LUA_VORTEX_DEBUG, "Finished TLS process with status=%d, message=%s (old ref count: %d)", status, status_msg, vortex_connection_ref_count (*conn)); /* unlock during operation */ LUA_VORTEX_LOCK (L, axl_false); if (status != 2) { /* reduce reference because tls process didn't finished */ vortex_connection_unref (*conn, "start tls"); } else { /* ok tls was ok, flag old connection as transient to * only unref */ lua_vortex_log (LUA_VORTEX_DEBUG, "Flagging connection id=%d as transient due to TLS ok status", vortex_connection_get_id (*conn)); lua_vortex_metatable_set_bool (L, 1, "transient", axl_true); } /* end if */ /* build connection result */ lua_vortex_connection_new_ref (L, conn2, axl_false); vortex_connection_unref (conn2, "start tls"); /* push status */ lua_pushnumber (L, status); lua_pushstring (L, status_msg); return 3; }
/** * @brief a frame received Callback */ void listenerFrameReceivedCallback (VortexChannel* channel, VortexConnection* connection, VortexFrame* frame, axlPointer user_data) { VORTEXListenerFrameReceivedCallbackData* callbackData = (VORTEXListenerFrameReceivedCallbackData*) user_data; TML_INT32 iRet = TML_SUCCESS; ///////////////////////////////////////////////////////////////////////////// // Fetching all necessary attributes from Vortex: /////////////////////////// // Die Connection ID: callbackData->pLog->log (TML_LOG_VORTEX_CMD, "TMLCoreListener", "listenerFrameReceivedCallback", "Vortex CMD", "vortex_connection_get_id"); int iConnectionID = vortex_connection_get_id(connection); /////////////////////////// // Die Host IP: callbackData->pLog->log (TML_LOG_VORTEX_CMD, "TMLCoreListener", "listenerFrameReceivedCallback", "Vortex CMD", "vortex_connection_get_host_ip"); const char* sHostIP = vortex_connection_get_host_ip(connection); /////////////////////////// // Der Port: callbackData->pLog->log (TML_LOG_VORTEX_CMD, "TMLCoreListener", "listenerFrameReceivedCallback", "Vortex CMD", "vortex_connection_get_local_port"); const char* sPort = vortex_connection_get_port(connection); /////////////////////////// // Die Channel ID: callbackData->pLog->log (TML_LOG_VORTEX_CMD, "TMLCoreListener", "listenerFrameReceivedCallback", "Vortex CMD", "vortex_channel_get_number"); int iChannelID = vortex_channel_get_number (channel); if (-1 == iChannelID) iRet = TML_ERR_LISTENER_COMMUNICATION; /////////////////////////// // Die Message ID: callbackData->pLog->log (TML_LOG_VORTEX_CMD, "TMLCoreListener", "listenerFrameReceivedCallback", "Vortex CMD", "vortex_frame_get_msgno"); int iMsgID = vortex_frame_get_msgno (frame); if (-1 == iMsgID) iRet = TML_ERR_LISTENER_COMMUNICATION; /////////////////////////// // Das Profil, mit dem der Sender conneted ist: callbackData->pLog->log (TML_LOG_VORTEX_CMD, "TMLCoreListener", "listenerFrameReceivedCallback", "Vortex CMD", "vortex_channel_get_profile"); const char* sProfile = vortex_channel_get_profile (channel); if (NULL == sProfile) iRet = TML_ERR_LISTENER_COMMUNICATION; /////////////////////////// // Das Payload: callbackData->pLog->log (TML_LOG_VORTEX_CMD, "TMLCoreListener", "listenerFrameReceivedCallback", "Vortex CMD", "vortex_frame_get_payload"); char* cPayload = (char*)vortex_frame_get_payload (frame); if (NULL == cPayload) iRet = TML_ERR_LISTENER_COMMUNICATION; /////////////////////////// // Die Payloadsize: callbackData->pLog->log (TML_LOG_VORTEX_CMD, "TMLCoreListener", "listenerFrameReceivedCallback", "Vortex CMD", "vortex_frame_get_payload_size"); int iPayloadSize = vortex_frame_get_payload_size (frame); if (-1 == iPayloadSize) iRet = TML_ERR_LISTENER_COMMUNICATION; ///////////////////////////////////////////////////////////////////////////// // Set all necessary Vortex attributes into the TML_COMMAND_HANDLE Obj: if (TML_SUCCESS == iRet){ // A new TML_COMMAND_HANDLE object out of the payload: TML_COMMAND_HANDLE cmdHandle; iRet = tml_Cmd_Create(&cmdHandle); if (TML_SUCCESS == iRet){ SIDEX_HANDLE sHandle; /////////////////////////////////////////////// // Acquire critical section use: tml_Cmd_Acquire_Sidex_Handle(cmdHandle, &sHandle); iRet = sidex_Set_Content(sHandle, cPayload); /////////////////////////////////////////////// // Now I can release the critical section use: tml_Cmd_Release_Sidex_Handle(cmdHandle); } if (TML_SUCCESS == iRet){ // Vortex- session ID into the TML_COMMAND_HANDLE object: tml_Cmd_Attr_Set_Session_ID(cmdHandle, iConnectionID); // Don't mind of return value // Vortex- channel ID into the TML_COMMAND_HANDLE object: tml_Cmd_Attr_Set_Channel_ID(cmdHandle, iChannelID); // Don't mind of return value callbackData->pLog->log (TML_LOG_VORTEX_CMD, "TMLCoreListener", "listenerFrameReceivedCallback", "Vortex CMD", "vortex_channel_ref"); vortex_channel_ref(channel); // I will be shure to have a valid channel until the reply is send // Vortex- channel into the TML_COMMAND_HANDLE object: tml_Cmd_Attr_Set_Channel(cmdHandle, channel); // Don't mind of return value // Vortex- message ID into the TML_COMMAND_HANDLE object: tml_Cmd_Attr_Set_Message_ID(cmdHandle, iMsgID); // Don't mind of return value // Vortex- profile into the TML_COMMAND_HANDLE object: tml_Cmd_Attr_Set_Profile(cmdHandle, sProfile); // The core handle: tml_Cmd_Attr_Set_Core_Reference(cmdHandle, callbackData->tmlcorehandle); // Don't mind of return value TML_CONNECTION_HANDLE connectionHandle = TML_HANDLE_TYPE_NULL; ////////////////////////////////////////////////////////////////// // Add the connection to the list: if (NULL != sHostIP && NULL != sPort && NULL != connection){ ((tmlCoreWrapper*)callbackData->tmlcorehandle)->tmlCoreWrapper_Connect(sHostIP, sPort, false, &connectionHandle, connection); ((tmlObjWrapper*)cmdHandle)->tmlObjWrapper_Set_Connection(connectionHandle); } // Now call the callback method: globalCallback(callbackData->callback, (void*) cmdHandle); } } else{ callbackData->pLog->log ("TMLCoreListener", "listenerFrameReceivedCallback", "ERROR", "Problem on getting some attributes."); } return; }