/** * Function to process the pollout * * @param fd * * @return NCSCC_RC_SUCCESS * @return NCSCC_RC_FAILURE * */ uint32_t dtm_intranode_process_pollout(int fd) { DTM_INTRANODE_PID_INFO *pid_node = NULL; pid_node = dtm_intranode_get_pid_info_using_fd(fd); if (NULL == pid_node) { LOG_ER("DTM INTRA: PID info coressponding to fd doesnt exist, database mismatch. fd :%d",fd); osafassert(0); return NCSCC_RC_FAILURE; } else { /* Get the unsent messages from the list and send them */ DTM_INTRANODE_UNSENT_MSGS *hdr = pid_node->msgs_hdr; if (NULL == hdr) { /* No messages to be sent, reset the POLLOUT event on this fd */ dtm_intranode_reset_poll_fdlist(fd); } else { dtm_intranode_snd_unsent_msg(pid_node, fd); } } return NCSCC_RC_SUCCESS; }
/** * 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; }