/* GSport - an Apple //gs Emulator Copyright (C) 2013-2014 by Peter Neubauer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** This module implements queues for storing and transferring packets within the bridge. **/ #include "../defc.h" #include "atalk.h" #include "port.h" void port_init(struct packet_port_t* port) { if (port) { queue_init(&port->in); queue_init(&port->out); } } void port_shutdown(struct packet_port_t* port) { if (port) { queue_shutdown(&port->in); queue_shutdown(&port->out); } } void queue_init(struct packet_queue_t* queue) { if (queue) { queue->head = queue->tail = 0; } } void queue_shutdown(struct packet_queue_t* queue) { if (queue) { struct packet_t* packet = dequeue(queue); while (packet) { if (packet->data) free(packet->data); free(packet); packet = dequeue(queue); } } } void enqueue(struct packet_queue_t* queue, struct at_addr_t dest, struct at_addr_t source, byte type, size_t size, byte data[]) { if (!queue) return; struct packet_t* packet = (struct packet_t*)malloc(sizeof(struct packet_t)); packet->dest.network = dest.network; packet->dest.node = dest.node; packet->source.network = source.network; packet->source.node = source.node; packet->type = type; packet->size = size; packet->data = data; enqueue_packet(queue, packet); } void enqueue_packet(struct packet_queue_t* queue, struct packet_t* packet) { packet->next = 0; if (queue->tail) queue->tail->next = packet; else queue->head = packet; queue->tail = packet; } void insert(struct packet_queue_t* queue, struct at_addr_t dest, struct at_addr_t source, byte type, size_t size, byte data[]) { if (!queue) return; struct packet_t* packet = (struct packet_t*)malloc(sizeof(struct packet_t)); packet->dest.network = dest.network; packet->dest.node = dest.node; packet->source.network = source.network; packet->source.node = source.node; packet->type = type; packet->size = size; packet->data = data; insert_packet(queue, packet); } void insert_packet(struct packet_queue_t* queue, struct packet_t* packet) { packet->next = queue->head; queue->head = packet; if (!queue->tail) queue->tail = queue->head; } struct packet_t* dequeue(struct packet_queue_t* queue) { if (queue && queue->head) { struct packet_t* packet = queue->head; if (queue->tail == queue->head) queue->tail = queue->head = 0; else queue->head = packet->next; return packet; } else return 0; } struct packet_t* queue_peek(struct packet_queue_t* queue) { if (queue) return queue->head; else return 0; }