/**************************************************************************** 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; }
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; }
/***************************************************************************** * 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; }
/**************************************************************************** * 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; }
/**************************************************************************** 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; }
/** * 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; }
/** * 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; }
/** * 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; }