Example #1
0
/****************************************************************************
  Name          : eda_dec_chan_open_cbk_msg
 
  Description   : This routine decodes a channel open callback message
 
  Arguments     : NCS_UBAID *msg,
                  EDSV_MSG *msg
                  
  Return Values : uint32_t
 
  Notes         : None.
******************************************************************************/
static uint32_t eda_dec_chan_open_cbk_msg(NCS_UBAID *uba, EDSV_MSG *msg)
{
	uint8_t *p8;
	int32_t total_bytes = 0;
	EDSV_EDA_CHAN_OPEN_CBK_PARAM *param = &msg->info.cbk_info.param.chan_open_cbk;
	uint8_t local_data[256];

	if (uba == NULL) {
		TRACE_4("uba is NULL");
		return 0;
	}

	/* chan_name_len */
	p8 = ncs_dec_flatten_space(uba, local_data, 2);
	param->chan_name.length = ncs_decode_16bit(&p8);
	ncs_dec_skip_space(uba, 2);
	total_bytes += 2;

	/* chan_name */
	ncs_decode_n_octets_from_uba(uba, param->chan_name.value, (uint32_t)param->chan_name.length);
	total_bytes += (uint32_t)param->chan_name.length;

	/* chan_id, chan_open_id, chan_open_flags, eda_chan_hdl, error */
	p8 = ncs_dec_flatten_space(uba, local_data, 17);
	param->chan_id = ncs_decode_32bit(&p8);
	param->chan_open_id = ncs_decode_32bit(&p8);
	param->chan_open_flags = ncs_decode_8bit(&p8);
	param->eda_chan_hdl = ncs_decode_32bit(&p8);
	param->error = ncs_decode_32bit(&p8);
	ncs_dec_skip_space(uba, 17);
	total_bytes += 17;

	return total_bytes;
}
Example #2
0
static uint32_t eda_dec_clm_status_cbk_msg(NCS_UBAID *uba, EDSV_MSG *msg)
{
	uint8_t *p8;
	int32_t total_bytes = 0;
	EDSV_EDA_CLM_STATUS_CBK_PARAM *param = &msg->info.cbk_info.param.clm_status_cbk;
	uint8_t local_data[256];

	if (uba == NULL) {
		TRACE_4("uba is NULL");
		return 0;
	}

	/* ClmNodeStatus */
	p8 = ncs_dec_flatten_space(uba, local_data, 2);
	param->node_status = ncs_decode_16bit(&p8);
	ncs_dec_skip_space(uba, 2);
	total_bytes += 2;
	return total_bytes;
}
Example #3
0
/*****************************************************************************
 * Function Name: dts_log_msg_decode
 * Purpose:       decodes a NCSDTS_FLTR from a ubaid
 ****************************************************************************/
uns32 dts_log_msg_decode(NCSFL_NORMAL *logmsg, NCS_UBAID *uba)
{
	uns8 *data = NULL;
	uns8 data_buff[DTS_MAX_SIZE_DATA];

	if (uba == NULL)
		return m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dts_log_msg_decode: User buffer is NULL");

	if (logmsg == NULL)
		return m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dts_log_msg_decode: Message to be decoded is NULL");

	data = ncs_dec_flatten_space(uba, data_buff, DTS_LOG_MSG_HDR_SIZE);
	if (data == NULL)
		return m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dts_log_msg_decode: ncs_dec_flatten_space returns NULL");

	logmsg->hdr.time.seconds = ncs_decode_32bit(&data);
	logmsg->hdr.time.millisecs = ncs_decode_32bit(&data);

	logmsg->hdr.vr_id = ncs_decode_16bit(&data);
	logmsg->hdr.ss_id = ncs_decode_32bit(&data);
	logmsg->hdr.inst_id = ncs_decode_32bit(&data);
	logmsg->hdr.severity = ncs_decode_8bit(&data);
	logmsg->hdr.category = ncs_decode_32bit(&data);

	logmsg->hdr.fmat_id = ncs_decode_8bit(&data);

	ncs_dec_skip_space(uba, DTS_LOG_MSG_HDR_SIZE);

	/* Check for any mem failure in dts_log_str_decode */
	if (dts_log_str_decode(uba, &logmsg->hdr.fmat_type) == NCSCC_RC_FAILURE)
		return m_DTS_DBG_SINK(NCSCC_RC_FAILURE,
				      "dts_log_msg_decode: dts_log_str_decode returned memory alloc failure");

	memcpy(&logmsg->uba, uba, sizeof(NCS_UBAID));

	return NCSCC_RC_SUCCESS;
}
Example #4
0
/****************************************************************************
 * Function Name: dts_mds_dec
 * Purpose:        decode a DTS message coming in
 ****************************************************************************/
uns32 dts_mds_dec(MDS_CLIENT_HDL yr_svc_hdl, NCSCONTEXT *msg,
		  SS_SVC_ID to_svc, NCS_UBAID *uba, MDS_CLIENT_MSG_FORMAT_VER msg_fmat_ver)
{
	uns8 *data = NULL;
	DTSV_MSG *mm;
	uns8 data_buff[DTSV_DTA_DTS_HDR_SIZE];
	uns32 lenn = 0;

	if ((msg_fmat_ver < DTS_MDS_MIN_MSG_FMAT_VER_SUPPORT) || (msg_fmat_ver > DTS_MDS_MAX_MSG_FMAT_VER_SUPPORT))
		return m_DTS_DBG_SINK(NCSCC_RC_FAILURE,
				      "dts_mds_dec: Message format version is not within acceptable range");

	if (uba == NULL)
		return m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dts_mds_dec: DTS decode: user buffer is NULL");

	if (msg == NULL)
		return m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dts_mds_dec: DTS decode: Message is NULL");

	mm = m_MMGR_ALLOC_DTSV_MSG;

	if (mm == NULL) {
		return m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dts_mds_dec: DTS decode: Failed to allocate DTSV message");
	}

	memset(mm, '\0', sizeof(DTSV_MSG));

	*msg = mm;

	data = ncs_dec_flatten_space(uba, data_buff, DTSV_DTA_DTS_HDR_SIZE);
	if (data == NULL) {
		m_MMGR_FREE_DTSV_MSG(mm);
		return m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dts_mds_dec: DTS decode: ncs_dec_flatten_space returns NULL");
	}

	mm->vrid = ncs_decode_16bit(&data);

	mm->msg_type = ncs_decode_8bit(&data);

	ncs_dec_skip_space(uba, DTSV_DTA_DTS_HDR_SIZE);

	switch (mm->msg_type) {
	case DTA_REGISTER_SVC:
		{
			data = ncs_dec_flatten_space(uba, data_buff, sizeof(SS_SVC_ID));
			if (data == NULL) {
				m_MMGR_FREE_DTSV_MSG(mm);
				return m_DTS_DBG_SINK(NCSCC_RC_FAILURE,
						      "dts_mds_dec: DTS decode: ncs_dec_flatten_space returns NULL");
			}
			mm->data.data.reg.svc_id = ncs_decode_32bit(&data);
			ncs_dec_skip_space(uba, sizeof(SS_SVC_ID));

			/* Decode the version no. */
			data = ncs_dec_flatten_space(uba, data_buff, sizeof(uns16));
			if (data == NULL) {
				m_MMGR_FREE_DTSV_MSG(mm);
				return m_DTS_DBG_SINK(NCSCC_RC_FAILURE,
						      "dts_mds_dec: DTS decode: ncs_dec_flatten_space returns NULL");
			}
			mm->data.data.reg.version = ncs_decode_16bit(&data);
			ncs_dec_skip_space(uba, sizeof(uns16));

			/* Decode the service name */
			data = ncs_dec_flatten_space(uba, data_buff, sizeof(uns32));
			if (data == NULL) {
				m_MMGR_FREE_DTSV_MSG(mm);
				return m_DTS_DBG_SINK(NCSCC_RC_FAILURE,
						      "dts_mds_dec: DTS decode: ncs_dec_flatten_space returns NULL");
			}
			lenn = ncs_decode_32bit(&data);
			ncs_dec_skip_space(uba, sizeof(uns32));
			if (lenn == 0) {
				/* No need to decode any further. no service name specified */
			} else if (lenn < DTSV_SVC_NAME_MAX) {	/* Check valid len of svc_name */
				ncs_decode_n_octets_from_uba(uba, (uns8 *)mm->data.data.reg.svc_name, lenn);
			} else {	/* Discard this message */

				m_MMGR_FREE_DTSV_MSG(mm);
				return m_DTS_DBG_SINK(NCSCC_RC_FAILURE,
						      "dts_mds_dec: Length of service name decoded in register message exceeds limits");
			}
			break;
		}
	case DTA_UNREGISTER_SVC:
		{
			data = ncs_dec_flatten_space(uba, data_buff, sizeof(SS_SVC_ID));
			if (data == NULL) {
				m_MMGR_FREE_DTSV_MSG(mm);
				return m_DTS_DBG_SINK(NCSCC_RC_FAILURE,
						      "dts_mds_dec: DTS decode: ncs_dec_flatten_space returns NULL");
			}
			mm->data.data.unreg.svc_id = ncs_decode_32bit(&data);
			ncs_dec_skip_space(uba, sizeof(SS_SVC_ID));

			/* Decode the version no. */
			data = ncs_dec_flatten_space(uba, data_buff, sizeof(uns16));
			if (data == NULL) {
				m_MMGR_FREE_DTSV_MSG(mm);
				return m_DTS_DBG_SINK(NCSCC_RC_FAILURE,
						      "dts_mds_dec: DTS decode: ncs_dec_flatten_space returns NULL");
			}
			mm->data.data.unreg.version = ncs_decode_16bit(&data);
			ncs_dec_skip_space(uba, sizeof(uns16));

			/* Decode the service name */
			data = ncs_dec_flatten_space(uba, data_buff, sizeof(uns32));
			if (data == NULL) {
				m_MMGR_FREE_DTSV_MSG(mm);
				return m_DTS_DBG_SINK(NCSCC_RC_FAILURE,
						      "dts_mds_dec: DTS decode: ncs_dec_flatten_space returns NULL");
			}
			lenn = ncs_decode_32bit(&data);
			ncs_dec_skip_space(uba, sizeof(uns32));
			if (lenn == 0) {
				/* No need to decode any further. no service name specified */
			}
			if (lenn < DTSV_SVC_NAME_MAX) {	/* Check valid len of svc_name */
				ncs_decode_n_octets_from_uba(uba, (uns8 *)mm->data.data.unreg.svc_name, lenn);
			} else {	/* Discard this message */

				m_MMGR_FREE_DTSV_MSG(mm);
				return m_DTS_DBG_SINK(NCSCC_RC_FAILURE,
						      "dts_mds_dec: Length of service name decoded in unregister msg exceeds limits");
			}
			break;
		}
	case DTA_LOG_DATA:
		{
			/* Versioning changes : Set the msg_fmat_ver field of DTA_LOG_MSG 
			 * according to the message format version from MDS callback. 
			 */
			mm->data.data.msg.msg_fmat_ver = msg_fmat_ver;

			/* Check for any mem failure in dts_log_str_decode */
			if (dts_log_msg_decode(&mm->data.data.msg.log_msg, uba) == NCSCC_RC_FAILURE) {
				m_MMGR_FREE_DTSV_MSG(mm);
				return m_DTS_DBG_SINK(NCSCC_RC_FAILURE,
						      "dts_mds_dec: dts_log_msg_decode returned failure");
			}
			break;
		}

#if (DTA_FLOW == 1)
	case DTA_FLOW_CONTROL:
	case DTS_CONGESTION_HIT:
	case DTS_CONGESTION_CLEAR:
		/* Do Nothing */
		break;
#endif

	default:
		m_MMGR_FREE_DTSV_MSG(mm);
		return m_DTS_DBG_SINK(NCSCC_RC_FAILURE, "dts_mds_dec: Wrong message type is received");
	}

	return NCSCC_RC_SUCCESS;
}
Example #5
0
/****************************************************************************
  Name          : eda_dec_delv_evt_cbk_msg
 
  Description   : This routine decodes a deliver event callback message
 
  Arguments     : NCS_UBAID *msg,
                  EDSV_MSG *msg
                  
  Return Values : uint32_t
 
  Notes         : None.
******************************************************************************/
static uint32_t eda_dec_delv_evt_cbk_msg(NCS_UBAID *uba, EDSV_MSG *msg)
{
	uint8_t *p8;
	uint32_t x;
	uint32_t fake_value;
	uint64_t num_patterns;
	uint32_t total_bytes = 0;
	SaEvtEventPatternT *pattern_ptr;
	EDSV_EDA_EVT_DELIVER_CBK_PARAM *param = &msg->info.cbk_info.param.evt_deliver_cbk;
	uint8_t local_data[1024];

	if (uba == NULL) {
		TRACE_4("uba is NULL");
		return 0;
	}

	/* sub_id, chan_id, chan_open_id */
	p8 = ncs_dec_flatten_space(uba, local_data, 12);
	param->sub_id = ncs_decode_32bit(&p8);
	param->chan_id = ncs_decode_32bit(&p8);
	param->chan_open_id = ncs_decode_32bit(&p8);
	ncs_dec_skip_space(uba, 12);
	total_bytes += 12;

	/* Decode the patterns.
	 * Must allocate space for these.
	 */

	/* patternsNumber */
	p8 = ncs_dec_flatten_space(uba, local_data, 8);
	num_patterns = ncs_decode_64bit(&p8);
	ncs_dec_skip_space(uba, 8);
	total_bytes += 8;

	param->pattern_array = m_MMGR_ALLOC_EVENT_PATTERN_ARRAY;
	if (!param->pattern_array) {
		TRACE_4("malloc failed for pattern array");
		return 0;
	}
	param->pattern_array->patternsNumber = num_patterns;
	if (num_patterns) {
		param->pattern_array->patterns = m_MMGR_ALLOC_EVENT_PATTERNS((uint32_t)num_patterns);
		if (!param->pattern_array->patterns) {
			TRACE_4("malloc failed for patternarray->patterns");
			return 0;
		}
	} else {
		param->pattern_array->patterns = NULL;
	}

	pattern_ptr = param->pattern_array->patterns;
	for (x = 0; x < param->pattern_array->patternsNumber; x++) {
		/* patternSize */
		p8 = ncs_dec_flatten_space(uba, local_data, 8);
		pattern_ptr->patternSize = ncs_decode_64bit(&p8);
		ncs_dec_skip_space(uba, 8);
		total_bytes += 8;

		/* For zero length patterns, fake decode zero */
		if (pattern_ptr->patternSize == 0) {
			p8 = ncs_dec_flatten_space(uba, local_data, 4);
			fake_value = ncs_decode_32bit(&p8);
			TRACE("pattern size: %u", fake_value);
			/* Do so the free routine is happy */
			pattern_ptr->pattern = m_MMGR_ALLOC_EDSV_EVENT_DATA(0);
			ncs_dec_skip_space(uba, 4);
			total_bytes += 4;
		} else {
			/* pattern */
			pattern_ptr->pattern = m_MMGR_ALLOC_EDSV_EVENT_DATA((uint32_t)pattern_ptr->patternSize);
			if (!pattern_ptr->pattern) {
				TRACE_4("malloc failed for event data");
				return 0;
			}
			ncs_decode_n_octets_from_uba(uba, pattern_ptr->pattern, (uint32_t)pattern_ptr->patternSize);
			total_bytes += (uint32_t)pattern_ptr->patternSize;
		}
		pattern_ptr++;
	}

	/* priority */
	p8 = ncs_dec_flatten_space(uba, local_data, 1);
	param->priority = ncs_decode_8bit(&p8);
	ncs_dec_skip_space(uba, 1);
	total_bytes += 1;

	/* publisher_name length */
	p8 = ncs_dec_flatten_space(uba, local_data, 2);
	param->publisher_name.length = ncs_decode_16bit(&p8);
	ncs_dec_skip_space(uba, 2);
	total_bytes += 2;

	/* publisher_name */
	ncs_decode_n_octets_from_uba(uba, param->publisher_name.value, (uint32_t)param->publisher_name.length);
	total_bytes += (uint32_t)param->publisher_name.length;

	/* publish_time, eda_event_id */
	p8 = ncs_dec_flatten_space(uba, local_data, 24);
	param->publish_time = ncs_decode_64bit(&p8);
	param->retention_time = ncs_decode_64bit(&p8);
	param->eda_event_id = ncs_decode_32bit(&p8);
	param->ret_evt_ch_oid = ncs_decode_32bit(&p8);
	ncs_dec_skip_space(uba, 24);
	total_bytes += 24;

	/* data_len */
	p8 = ncs_dec_flatten_space(uba, local_data, 8);
	param->data_len = ncs_decode_64bit(&p8);
	ncs_dec_skip_space(uba, 8);
	total_bytes += 8;

	/* data */
	if ((uint32_t)param->data_len) {
		param->data = m_MMGR_ALLOC_EDSV_EVENT_DATA((uint32_t)param->data_len);
		if (!param->data) {
			TRACE_4("malloc failedi for event data");
			return 0;
		}
		ncs_decode_n_octets_from_uba(uba, param->data, (uint32_t)param->data_len);
	} else
		param->data = NULL;

	total_bytes += (uint32_t)param->data_len;

	return total_bytes;
}
Example #6
0
/**
 * Function to process intranode poll and rcv message
 *
 *
 *
 */
void dtm_intranode_process_poll_rcv_msg(int fd)
{
	DTM_INTRANODE_PID_INFO *node = NULL;

	node = dtm_intranode_get_pid_info_using_fd(fd);

	if (NULL == node) {
		LOG_ER("DTM INTRA : PID info coressponding to fd doesnt exist, database mismatch. fd :%d",fd);
		osafassert(0);
	}
	if (0 == node->bytes_tb_read) {
		if (0 == node->num_by_read_for_len_buff) {
			uint8_t *data;
			int recd_bytes = 0;

			/*******************************************************/
			/* Receive all incoming data on this socket */
			/*******************************************************/

			recd_bytes = recv(fd, node->len_buff, 2, 0);
			if (0 == recd_bytes) {
				TRACE("DTM_INTRA: Socket close: %d  err :%s", fd, strerror(errno));
				dtm_intranode_process_pid_down(fd);
				dtm_intranode_del_poll_fdlist(fd);
				return;
			} else if (2 == recd_bytes) {
				uint16_t local_len_buf = 0;

				data = node->len_buff;
				local_len_buf = ncs_decode_16bit(&data);
				node->buff_total_len = local_len_buf;
				node->num_by_read_for_len_buff = 2;

				if (NULL == (node->buffer = calloc(1, (local_len_buf + 3)))) {
					/* Length + 2 is done to reuse the same buffer 
					   while sending to other nodes */
					LOG_ER("Memory allocation failed in dtm_intranode_processing");
					return;
				}
				recd_bytes = recv(fd, &node->buffer[2], local_len_buf, 0);

				if (recd_bytes < 0) {
					return;
				} else if (0 == recd_bytes) {
					TRACE("DTM_INTRA: Socket close: %d  err :%s", fd, strerror(errno));
					dtm_intranode_process_pid_down(fd);
					dtm_intranode_del_poll_fdlist(fd);
					return;
				} else if (local_len_buf > recd_bytes) {
					/* can happen only in two cases, system call interrupt or half data, */
					TRACE("less data recd, recd bytes = %d, actual len = %d", recd_bytes,
					       local_len_buf);
					node->bytes_tb_read = node->buff_total_len - recd_bytes;
					return;
				} else if (local_len_buf == recd_bytes) {
					/* Call the common rcv function */
					dtm_intranode_process_poll_rcv_msg_common(node);
				} else {
					osafassert(0);
				}
			} else {
				/* we had recd some bytes */
				if (recd_bytes < 0) {
					/* This can happen due to system call interrupt */
					return;
				} else if (1 == recd_bytes) {
					/* We recd one byte of the length part */
					node->num_by_read_for_len_buff = recd_bytes;
				} else {
					osafassert(0);
				}
			}
		} else if (1 == node->num_by_read_for_len_buff) {
			int recd_bytes = 0;

			recd_bytes = recv(fd, &node->len_buff[1], 1, 0);
			if (recd_bytes < 0) {
				/* This can happen due to system call interrupt */
				return;
			} else if (1 == recd_bytes) {
				/* We recd one byte(remaining) of the length part */
				uint8_t *data = node->len_buff;
				node->num_by_read_for_len_buff = 2;
				node->buff_total_len = ncs_decode_16bit(&data);
				return;
			} else if (0 == recd_bytes) {
				TRACE("DTM_INTRA: Socket close: %d  err :%s", fd, strerror(errno));
				dtm_intranode_process_pid_down(fd);
				dtm_intranode_del_poll_fdlist(fd);
				return;
			} else {
				osafassert(0);	/* This should never occur */
			}
		} else if (2 == node->num_by_read_for_len_buff) {
			int recd_bytes = 0;

			if (NULL == (node->buffer = calloc(1, (node->buff_total_len + 3)))) {
				/* Length + 2 is done to reuse the same buffer 
				   while sending to other nodes */
				LOG_ER("\nMemory allocation failed in dtm_internode_processing");
				return;
			}
			recd_bytes = recv(fd, &node->buffer[2], node->buff_total_len, 0);

			if (recd_bytes < 0) {
				return;
			} else if (0 == recd_bytes) {
				TRACE("DTM_INTRA: Socket close: %d  err :%s", fd, strerror(errno));
				dtm_intranode_process_pid_down(fd);
				dtm_intranode_del_poll_fdlist(fd);
				return;
			} else if (node->buff_total_len > recd_bytes) {
				/* can happen only in two cases, system call interrupt or half data, */
				TRACE("less data recd, recd bytes = %d, actual len = %d", recd_bytes,
				       node->buff_total_len);
				node->bytes_tb_read = node->buff_total_len - recd_bytes;
				return;
			} else if (node->buff_total_len == recd_bytes) {
				/* Call the common rcv function */
				dtm_intranode_process_poll_rcv_msg_common(node);
			} else {
				osafassert(0);
			}
		} else {
			osafassert(0);
		}

	} else {
		/* Partial data already read */
		int recd_bytes = 0;

		recd_bytes =
		    recv(fd, &node->buffer[2 + (node->buff_total_len - node->bytes_tb_read)], node->bytes_tb_read, 0);

		if (recd_bytes < 0) {
			return;
		} else if (0 == recd_bytes) {
			TRACE("DTM_INTRA: Socket close: %d  err :%s", fd, strerror(errno));
			/* Close the connection */
			dtm_intranode_process_pid_down(fd);
			dtm_intranode_del_poll_fdlist(fd);
			return;
		} else if (node->bytes_tb_read > recd_bytes) {
			/* can happen only in two cases, system call interrupt or half data, */
			TRACE("less data recd, recd bytes = %d, actual len = %d", recd_bytes, node->bytes_tb_read);
			node->bytes_tb_read = node->bytes_tb_read - recd_bytes;
			return;
		} else if (node->bytes_tb_read == recd_bytes) {
			/* Call the common rcv function */
			dtm_intranode_process_poll_rcv_msg_common(node);
		} else {
			osafassert(0);
		}
	}
	return;
}
Example #7
0
/**
 * Function to handle node discovery process
 *
 * @param args
 *
 * @return NCSCC_RC_SUCCESS
 * @return NCSCC_RC_FAILURE
 *
 */
void node_discovery_process(void *arg)
{
	TRACE_ENTER();

	int poll_ret = 0;
	int end_server = false, compress_array = false;
	int close_conn = false;
	DTM_INTERNODE_CB *dtms_cb = dtms_gl_cb;

	int current_size = 0, i, j;

	/* Data Received */
	uint8_t inbuf[DTM_INTERNODE_RECV_BUFFER_SIZE];
	uint8_t *data1;		/* Used for DATAGRAM decoding */
	uint16_t recd_bytes = 0;
	uint16_t recd_buf_len = 0;
	int node_info_buffer_len = 0;
	uint8_t node_info_hrd[NODE_INFO_PKT_SIZE];
	char node_ip[INET6_ADDRSTRLEN];

	memset(&node_ip, 0, INET6_ADDRSTRLEN);
	/*************************************************************/
	/* Set up the initial bcast or mcast receiver socket */
	/*************************************************************/

	if (dtms_cb->mcast_flag != true) {

		if (NCSCC_RC_SUCCESS != dtm_dgram_bcast_listener(dtms_cb)) {
			LOG_ER("DTM:Set up the initial bcast  receiver socket   failed");
			exit(1);
		}

	} else {

		if (NCSCC_RC_SUCCESS != dtm_dgram_mcast_listener(dtms_cb)) {
			LOG_ER("DTM:Set up the initial mcast  receiver socket   failed");
			exit(1);
		}
	}

	/*************************************************************/
	/* Set up the initial listening socket */
	/*************************************************************/
	if (NCSCC_RC_SUCCESS != dtm_stream_nonblocking_listener(dtms_cb)) {
		LOG_ER("DTM: Set up the initial stream nonblocking serv  failed");
		exit(1);
	}
#if 0

	if (add_self_node(dtms_cb) != NCSCC_RC_SUCCESS) {
		LOG_ER("DTM: add_self_node  failed");
		exit(1);
	}
#endif

	/*************************************************************/
	/* Initialize the pollfd structure */
	/*************************************************************/
	memset(fds, 0, sizeof(fds));

	/*************************************************************/
	/* Set up the initial listening socket */
	/*************************************************************/

	fds[0].fd = dtms_cb->dgram_sock_rcvr;
	fds[0].events = POLLIN;

	/*************************************************************/
	/* Set up the initial listening socket */
	/*************************************************************/

	fds[1].fd = dtms_cb->stream_sock;
	fds[1].events = POLLIN;

	fds[2].fd = dtms_cb->mbx_fd;
	fds[2].events = POLLIN;
	nfds = 3;

	/*************************************************************/
	/* Set up the initial listening socket */
	/*************************************************************/

	if (dtm_construct_node_info_hdr(dtms_cb, node_info_hrd, &node_info_buffer_len) != NCSCC_RC_SUCCESS) {

		LOG_ER("DTM: dtm_construct_node_info_hdr failed"); 
		goto done;

	}

	/*************************************************************/
	/* Loop waiting for incoming connects or for incoming data */
	/* on any of the connected sockets. */
	/*************************************************************/

	do {
		/***********************************************************/
		/* Call poll() and wait . */
		/***********************************************************/
		int fd_check = 0;
		poll_ret = poll(fds, nfds, DTM_TCP_POLL_TIMEOUT);
		/***********************************************************/

		/* Check to see if the poll call failed. */
		/***********************************************************/
		if (poll_ret < 0) {
			LOG_ER(" poll() failed");
			continue;
		}
		/***********************************************************/
		/* Check to see if the 3 minute time out expired. */
		/***********************************************************/
		if (poll_ret == 0) {
			continue;
		}

		/***********************************************************/
		/* One or more descriptors are readable. Need to */
		/* determine which ones they are. */
		/***********************************************************/
		current_size = nfds;
		for (i = 0; i < current_size; i++) {

			/*********************************************************/
			/* Loop through to find the descriptors that returned */
			/* POLLIN and determine whether it's the listening */
			/* or the active connection. */
			/*********************************************************/
			if (POLLIN & fds[i].revents) {

				if (fds[i].fd == dtms_cb->dgram_sock_rcvr) {

					fd_check++;
					/* Data Received */
					memset(inbuf, 0, DTM_INTERNODE_RECV_BUFFER_SIZE);
					recd_bytes = 0;
					recd_buf_len = 0;

					recd_bytes = dtm_dgram_recvfrom_bmcast(dtms_cb, node_ip, inbuf, sizeof(inbuf));

					if (recd_bytes == 0) {
						LOG_ER("DTM: recd bytes=0 on DGRAM sock");
						continue;
					}

					data1 = inbuf;	/* take care of previous address */

					recd_buf_len = ncs_decode_16bit(&data1);

					if (recd_buf_len == recd_bytes) {

						int new_sd = -1;

						new_sd = dtm_process_connect(dtms_cb, node_ip, inbuf, (recd_bytes - 2));

						if (new_sd == -1)
							continue;

					/*****************************************************/
						/* Add the new incoming connection to the */
						/* pollfd structure */
					/*****************************************************/
						LOG_IN("DTM: add New incoming connection to fd : %d\n", new_sd);
						fds[nfds].fd = new_sd;
						fds[nfds].events = POLLIN | POLLERR | POLLHUP | POLLNVAL;
						nfds++;

					} else {
						/* Log message that we are dropping the data */
						LOG_ER("DTM: BRoadcastLEN-MISMATCH: dropping the data");
					}

				} else if (fds[i].fd == dtms_cb->stream_sock) {

					int new_sd = -1;
					uint32_t local_rc = NCSCC_RC_SUCCESS;
					fd_check++;
				/*******************************************************/
					/* Listening descriptor is readable. */
				/*******************************************************/
					TRACE(" DTM :Listening socket is readable");
				/*******************************************************/
					/* Accept all incoming connections that are */
					/* queued up on the listening socket before we */
					/* loop back and call poll again. */
				/*******************************************************/
					/* do { */
				/*****************************************************/
					/* Accept each incoming connection. If */
					/* accept fails with EWOULDBLOCK, then we */
					/* have accepted all of them. Any other */
					/* failure on accept will cause us to end the */
					/* serv. */
				/*****************************************************/
					new_sd = dtm_process_accept(dtms_cb, dtms_cb->stream_sock);
					if (new_sd < 0) {
						LOG_ER("DTM: accept() failed");
						end_server = true;
						break;
					}

		

				/*****************************************************/
					/* Node info data back to the accept with node info  */
				/*****************************************************/

					local_rc = dtm_comm_socket_send(new_sd, node_info_hrd, node_info_buffer_len);
					if (local_rc != NCSCC_RC_SUCCESS) {
						dtm_comm_socket_close(&new_sd);
						LOG_ER("DTM: send() failed ");
						break;
					}
					
				/*****************************************************/
					/* Add the new incoming connection to the */
					/* pollfd structure */
				/*****************************************************/
					TRACE("DTM :add New incoming connection to fd : %d\n", new_sd);
					fds[nfds].fd = new_sd;
					fds[nfds].events = POLLIN | POLLERR | POLLHUP | POLLNVAL;
					nfds++;

				/*****************************************************/
					/* Loop back up and accept another incoming */
					/* connection */
				/*****************************************************/
					/* } while (new_sd != -1); */	/* accept one at a time */

				} else if (fds[i].fd == dtms_cb->mbx_fd) {
					/* MBX fd messages that need to be sent out from this node */
					/* Process the mailbox events */
					DTM_SND_MSG_ELEM *msg_elem = NULL;

					fd_check++;
					msg_elem =
					    (DTM_SND_MSG_ELEM *) (m_NCS_IPC_NON_BLK_RECEIVE(&dtms_cb->mbx, NULL));

					if (NULL == msg_elem) {
						LOG_ER("DTM: Inter Node Mailbox IPC_NON_BLK_RECEIVE Failed");
						continue;
					} else if (DTM_MBX_ADD_DISTR_TYPE == msg_elem->type) {
						dtm_internode_add_to_svc_dist_list(msg_elem->info.svc_event.server_type,
										   msg_elem->info.svc_event.server_inst,
										   msg_elem->info.svc_event.pid);
						free(msg_elem);
						msg_elem = NULL;
					} else if (DTM_MBX_DEL_DISTR_TYPE == msg_elem->type) {
						dtm_internode_del_from_svc_dist_list(msg_elem->info.
										     svc_event.server_type,
										     msg_elem->info.
										     svc_event.server_inst,
										     msg_elem->info.svc_event.pid);
						free(msg_elem);
						msg_elem = NULL;
					} else if (DTM_MBX_DATA_MSG_TYPE == msg_elem->type) {
						dtm_prepare_data_msg(msg_elem->info.data.buffer,
								     msg_elem->info.data.buff_len);
						dtm_internode_snd_msg_to_node(msg_elem->info.data.buffer,
									      msg_elem->info.data.buff_len,
									      msg_elem->info.data.dst_nodeid);
						free(msg_elem);
						msg_elem = NULL;
					} else {
						LOG_ER("DTM Intranode :Invalid evt type from mbx");
						free(msg_elem);
						msg_elem = NULL;
					}
				} else {

			/*********************************************************/
					/* This is not the listening socket, therefore an */
					/* existing connection must be readable */
			/*********************************************************/
					fd_check++;
					dtm_internode_process_poll_rcv_msg(fds[i].fd, &close_conn, node_info_hrd,
									   node_info_buffer_len);

				}
			} else if (fds[i].revents & POLLOUT) {
				fd_check++;
				dtm_internode_process_pollout(fds[i].fd);
			} else if (fds[i].revents & POLLHUP) {
				fd_check++;
				close_conn = true;
			}

		/*******************************************************/
			/* If the close_conn flag was turned on, we need */
			/* to clean up this active connection. This */
			/* clean up process includes removing the */
			/* descriptor. */
		/*******************************************************/
			if (close_conn) {
				dtm_comm_socket_close(&fds[i].fd);
				close_conn = false;
				compress_array = true;
			}
			/* End of existing connection is readable */
			if (poll_ret == fd_check) {
				break;
			}
		}

		/***********************************************************/
		/* If the compress_array flag was turned on, we need */
		/* to squeeze together the array and decrement the number */
		/* of file descriptors. We do not need to move back the */
		/* events and revents fields because the events will always */
		/* be POLLIN in this case, and revents is output. */
		/***********************************************************/

		if (compress_array) {
			compress_array = false;
			for (i = 0; i < nfds; i++) {
				if (fds[i].fd == -1) {
					for (j = i; j < nfds; j++) {
						fds[j].fd = fds[j + 1].fd;
					}
					nfds--;
				}
			}
		}

	} while (end_server == false);

	/* End of serving running. */
	/*************************************************************/
	/* Clean up all of the sockets that are open */
	/*************************************************************/
 done:
	for (i = 0; i < nfds; i++) {
		if (fds[i].fd >= 0)
			dtm_comm_socket_close(&fds[i].fd);
	}
	TRACE_LEAVE();
	return;
}
Example #8
0
/**
 * Function to process internode poll and rcv message
 *
 * @param fd close_conn node_info_hrd node_info_buffer_len
 *
 * @return NCSCC_RC_SUCCESS
 * @return NCSCC_RC_FAILURE
 *
 */
void dtm_internode_process_poll_rcv_msg(int fd, int *close_conn, uint8_t *node_info_hrd, uint16_t node_info_buffer_len)
{
	DTM_NODE_DB *node = NULL;
	TRACE_ENTER();

	node = dtm_node_get_by_comm_socket(fd);

	if (NULL == node) {
		LOG_ER("DTM: database mismatch");
		osafassert(0);
	}
	if (0 == node->bytes_tb_read) {
		if (0 == node->num_by_read_for_len_buff) {
			uint8_t *data;
			int recd_bytes = 0;

			/*******************************************************/
			/* Receive all incoming data on this socket */
			/*******************************************************/

			recd_bytes = recv(fd, node->len_buff, 2, 0);
			if (0 == recd_bytes) {
				*close_conn = true;
				return;
			} else if (2 == recd_bytes) {
				uint16_t local_len_buf = 0;

				data = node->len_buff;
				local_len_buf = ncs_decode_16bit(&data);
				node->buff_total_len = local_len_buf;
				node->num_by_read_for_len_buff = 2;

				if (NULL == (node->buffer = calloc(1, (local_len_buf + 3)))) {
					/* Length + 2 is done to reuse the same buffer 
					   while sending to other nodes */
					LOG_ER("\nMemory allocation failed in dtm_internode_processing");
					return;
				}
				recd_bytes = recv(fd, &node->buffer[2], local_len_buf, 0);

				if (recd_bytes < 0) {
					return;
				} else if (0 == recd_bytes) {
					*close_conn = true;
					return;
				} else if (local_len_buf > recd_bytes) {
					/* can happen only in two cases, system call interrupt or half data, */
					TRACE("DTM: less data recd, recd bytes : %d, actual len : %d", recd_bytes,
					       local_len_buf);
					node->bytes_tb_read = node->buff_total_len - recd_bytes;
					return;
				} else if (local_len_buf == recd_bytes) {
					/* Call the common rcv function */
					dtm_internode_process_poll_rcv_msg_common(node, local_len_buf, node_info_hrd,
										  node_info_buffer_len, fd, close_conn);
				} else {
					LOG_ER("DTM :unknown corrupted data received on this file descriptor \n");
					osafassert(0);
				}
			} else {
				/* we had recd some bytes */
				if (recd_bytes < 0) {
					/* This can happen due to system call interrupt */
					return;
				} else if (1 == recd_bytes) {
					/* We recd one byte of the length part */
					node->num_by_read_for_len_buff = recd_bytes;
				} else {
					LOG_ER("DTM :unknown corrupted data received on this file descriptor \n");
					osafassert(0);
				}
			}
		} else if (1 == node->num_by_read_for_len_buff) {
			int recd_bytes = 0;

			recd_bytes = recv(fd, &node->len_buff[1], 1, 0);
			if (recd_bytes < 0) {
				/* This can happen due to system call interrupt */
				return;
			} else if (1 == recd_bytes) {
				/* We recd one byte(remaining) of the length part */
				uint8_t *data = node->len_buff;
				node->num_by_read_for_len_buff = 2;
				node->buff_total_len = ncs_decode_16bit(&data);
				return;
			} else if (0 == recd_bytes) {
				*close_conn = true;
				return;
			} else {
				LOG_ER("DTM :unknown corrupted data received on this file descriptor \n");
				osafassert(0);	/* This should never occur */
			}
		} else if (2 == node->num_by_read_for_len_buff) {
			int recd_bytes = 0;

			if (NULL == (node->buffer = calloc(1, (node->buff_total_len + 3)))) {
				/* Length + 2 is done to reuse the same buffer 
				   while sending to other nodes */
				LOG_ER("DTM :Memory allocation failed in dtm_internode_processing \n");
				return;
			}
			recd_bytes = recv(fd, &node->buffer[2], node->buff_total_len, 0);

			if (recd_bytes < 0) {
				return;
			} else if (0 == recd_bytes) {
				*close_conn = true;
				return;
			} else if (node->buff_total_len > recd_bytes) {
				/* can happen only in two cases, system call interrupt or half data, */
				TRACE("DTM: less data recd, recd bytes : %d, actual len : %d", recd_bytes,
				       node->buff_total_len);
				node->bytes_tb_read = node->buff_total_len - recd_bytes;
				return;
			} else if (node->buff_total_len == recd_bytes) {
				/* Call the common rcv function */
				dtm_internode_process_poll_rcv_msg_common(node, node->buff_total_len, node_info_hrd,
									  node_info_buffer_len, fd, close_conn);
			} else {
				LOG_ER("DTM :unknown corrupted data received on this file descriptor \n");
				osafassert(0);
			}
		} else {
			LOG_ER("DTM :unknown corrupted data received on this file descriptor \n");
			osafassert(0);
		}

	} else {
		/* Partial data already read */
		int recd_bytes = 0;

		recd_bytes =
		    recv(fd, &node->buffer[2 + (node->buff_total_len - node->bytes_tb_read)], node->bytes_tb_read, 0);

		if (recd_bytes < 0) {
			return;
		} else if (0 == recd_bytes) {
			*close_conn = true;
			return;
		} else if (node->bytes_tb_read > recd_bytes) {
			/* can happen only in two cases, system call interrupt or half data, */
			TRACE("DTM: less data recd, recd bytes : %d, actual len : %d", recd_bytes, node->bytes_tb_read);
			node->bytes_tb_read = node->bytes_tb_read - recd_bytes;
			return;
		} else if (node->bytes_tb_read == recd_bytes) {
			/* Call the common rcv function */
			dtm_internode_process_poll_rcv_msg_common(node, node->buff_total_len, node_info_hrd,
								  node_info_buffer_len, fd, close_conn);
		} else {
			LOG_ER("DTM :unknown corrupted data received on this file descriptor \n");
			osafassert(0);
		}
	}
	TRACE_LEAVE();
	return;
}