bool event_handler_pdu_send_timeout_check(node_t *node, node_t *outgoing_node, mac_pdu_t *pdu) { if (node->mac_info->error) { /* the message wasn't received */ rs_debug(DEBUG_MAC, "node '%s': a frame wasn't correctly received, destroying it", node->phy_info->name); pdu->sdu = NULL; mac_pdu_destroy(pdu); } node->mac_info->busy = FALSE; return TRUE; }
bool event_handler_pdu_send(node_t *node, node_t *outgoing_node, mac_pdu_t *pdu) { if (node->mac_info->busy) { rs_debug(DEBUG_MAC, "node '%s': MAC layer is busy, dropping frame", node->phy_info->name); return FALSE; } if (!phy_node_send(node, outgoing_node, pdu)) { return FALSE; } rs_system_schedule_event(node, mac_event_pdu_send_timeout_check, outgoing_node, pdu, rs_system->mac_pdu_timeout); node->mac_info->error = TRUE; node->mac_info->busy = TRUE; return TRUE; }
int rs_packet_send (struct rs_packet *pkt, void *user_data) { struct rs_connection *conn = NULL; int err = 0; assert (pkt); assert (pkt->conn); conn = pkt->conn; if (_conn_is_open_p (conn)) packet_do_send (pkt); else if (_conn_open (conn, pkt)) return -1; assert (conn->evb); assert (conn->active_peer); assert (conn->fd >= 0); conn->user_data = user_data; if (conn->bev) /* TCP */ { bufferevent_setcb (conn->bev, NULL, tcp_write_cb, tcp_event_cb, pkt); bufferevent_enable (conn->bev, EV_WRITE); } else /* UDP */ { event_assign (conn->wev, conn->evb, event_get_fd (conn->wev), EV_WRITE, event_get_callback (conn->wev), pkt); err = event_add (conn->wev, NULL); if (err < 0) return rs_err_conn_push_fl (conn, RSE_EVENT, __FILE__, __LINE__, "event_add: %s", evutil_gai_strerror (err)); } /* Do dispatch, unless the user wants to do it herself. */ if (!conn_user_dispatch_p (conn)) { conn->callbacks.sent_cb = _wcb; conn->user_data = pkt; rs_debug (("%s: entering event loop\n", __func__)); err = event_base_dispatch (conn->evb); if (err < 0) return rs_err_conn_push_fl (conn, RSE_EVENT, __FILE__, __LINE__, "event_base_dispatch: %s", evutil_gai_strerror (err)); rs_debug (("%s: event loop done\n", __func__)); conn->callbacks.sent_cb = NULL; conn->user_data = NULL; if ((pkt->flags & RS_PACKET_SENT) == 0) { assert (rs_err_conn_peek_code (conn)); return rs_err_conn_peek_code (conn); } } return RSE_OK; }