Example #1
0
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;
}
Example #2
0
void frame_received (VortexChannel    * channel,
		     VortexConnection * connection,
		     VortexFrame      * frame,
		     axlPointer           user_data)
{
	int iterator = 10;
	printf ("A frame received on channl: %d\n",     vortex_channel_get_number (channel));
	printf ("Data received: '%s'\n",                (char*) vortex_frame_get_payload (frame));

	/* reply the peer client with the same content 10 times */
	while (iterator >= 0) {
		printf ("Sending the reply..\n");
		if (! vortex_channel_send_ans_rpyv (channel,
						    vortex_frame_get_msgno (frame),
						    "Received Ok(%d): %s",
						    iterator,
						    vortex_frame_get_payload (frame))) {
			fprintf (stderr, "There was an error while sending the reply message");
		}
		printf ("Reply: %d sent..\n", iterator);
		iterator--;
	}
	
	/* send the last reply. */
	if (!vortex_channel_finalize_ans_rpy (channel, vortex_frame_get_msgno (frame))) {
		fprintf (stderr, "There was an error while sending the NUL reply message");
	}
				
	printf ("VORTEX_LISTENER: end task (pid: %d)\n", getpid ());


	return;
}
Example #3
0
axl_bool vortex_sequencer_remove_message_sent (VortexCtx * ctx, VortexChannel * channel)
{
	VortexSequencerData * data;
	axl_bool              is_empty;

	/* get pending message */
	data  = vortex_channel_remove_pending_message (channel);
	if (data == NULL)
		return axl_true; /* is_empty=axl_true : notify caller
				    that this channel has nothing to
				    send anymore */

	/* get if the queue is empty */
	is_empty = (vortex_channel_next_pending_message (channel) == NULL);

	/* log here */
	vortex_log (VORTEX_LEVEL_DEBUG, "Last message on channel=%d (%p) was sent completly, pending messages: %d (%d)",
		    vortex_channel_get_number (channel), channel, vortex_channel_pending_messages (channel), is_empty);

	/* release a reference */
	/* vortex_channel_unref (channel); */

	/* release feeder */
	vortex_payload_feeder_unref (data->feeder);

	/* release data */
	axl_free (data->message);
	axl_free (data);

	return is_empty;
}
Example #4
0
/** 
 * @internal
 *
 * @brief Internal function that allows the vortex reader to
 * re-sequence messages that are hold due to channel being stalled
 * 
 * @param channel The channel to notify
 */
void     vortex_sequencer_signal_update        (VortexChannel       * channel,
						VortexConnection    * connection)
{
	/* get current context */
	VortexCtx            * ctx = vortex_channel_get_ctx (channel);
	VortexSequencerState * state;

	vortex_log (VORTEX_LEVEL_DEBUG, "about to check for pending queue messages=%d not sequenced for channel=%d (%p)",
		    vortex_channel_pending_messages (channel), vortex_channel_get_number (channel), channel);

	/* check if we have data to be resequenced */
	if (vortex_channel_next_pending_message (channel)) {

		/* get reference to the state */
		state = ctx->sequencer_state;

		/* move to ready */
		vortex_mutex_lock (&state->mutex);
		if (! axl_hash_get (state->ready, channel)) {
			/* update channel reference */
			if (! vortex_channel_ref2 (channel, "sequencer")) {
				vortex_log (VORTEX_LEVEL_CRITICAL, "unable to acquire channel %p reference, failed to to signal sequencer for SEQ frame update",
					    channel);
				vortex_mutex_unlock (&state->mutex);
				return;
			} /* end if */

			/* insert hash */
			axl_hash_insert_full (state->ready, channel, (axlDestroyFunc) __vortex_sequencer_channel_unref, INT_TO_PTR (1), NULL);
		} /* end if */
		/* signal */
		vortex_cond_signal (&state->cond);
		vortex_mutex_unlock (&state->mutex);

	}else {
		vortex_log (VORTEX_LEVEL_DEBUG, "there is no messages pending to be sequenced, over the channel=%d",
		       vortex_channel_get_number (channel));
	} /* end if */

	return;
}
void frame_received (VortexChannel    * channel,
		     VortexConnection * connection,
		     VortexFrame      * frame,
		     axlPointer           user_data)
{
	printf ("VORTEX_LISTENER: STARTED (pid: %d)\n", getpid ());
	printf ("A frame received on channl: %d\n",     vortex_channel_get_number (channel));
	printf ("Data received: '%s'\n",                (char*) vortex_frame_get_payload (frame));

	/* reply */
	vortex_channel_send_rpy (channel,
				 "I have received you message, thanks..",
				 37,
				 vortex_frame_get_msgno (frame));
	printf ("VORTEX_LISTENER: CLOSE CHANNEL (pid: %d)\n", getpid ());

	/* close the channel */
	vortex_channel_close (channel, NULL);
	
	printf ("VORTEX_LISTENER: FINSHED (pid: %d)\n",       getpid ());
	return;
}
void frame_received (VortexChannel    * channel,
                     VortexConnection * connection,
                     VortexFrame      * frame,
                     axlPointer           user_data)
{
    VortexAsyncQueue * queue;
    int                iterator = 0;


    printf ("A frame received on channl: %d\n",     vortex_channel_get_number (channel));
    printf ("Data received: '%s'\n",                (char*) vortex_frame_get_payload (frame));

    if (vortex_frame_get_type (frame) == VORTEX_FRAME_TYPE_MSG) {
        /* send back a series of replies */
        queue = vortex_async_queue_new ();

        while (iterator < 100) {
            /* wait during 50ms */
            vortex_async_queue_timedpop (queue, 50000);

            /* send a reply */
            vortex_channel_send_ans_rpy (channel, "This is a reply to the message", 30, vortex_frame_get_msgno (frame));

            /* next message */
            iterator++;
        }

        /* send NUL */
        vortex_channel_finalize_ans_rpy (channel, vortex_frame_get_msgno (frame));

    }

    printf ("VORTEX_LISTENER: end task (pid: %d)\n", getpid ());


    return;
}
Example #7
0
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;
}
Example #8
0
/** 
 * @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;
}
Example #9
0
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;
}
Example #10
0
/**
 * @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;
}