/* 
 *  OpenGGSN - Gateway GPRS Support Node
 *  Copyright (C) 2002 Mondru AB.
 * 
 *  The contents of this file may be used under the terms of the GNU
 *  General Public License Version 2, provided that the above copyright
 *  notice and this permission notice is included in all copies or
 *  substantial portions of the software.
 * 
 *  The initial developer of the original code is
 *  Jens Jakobsen <jj@openggsn.org>
 * 
 *  Contributor(s):
 * 
 */

/*
 * Queue.c
 * Reliable delivery of signalling messages
 */

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <string.h>
#include "pdp.h"
#include "gtp.h"
#include "queue.h"

int queue_print(struct queue_t *queue) {
  int n;
  printf("Queue: %x Next: %d First: %d Last: %d\n", (int) queue, queue->next, queue->first, queue->last);
  printf("# State seq next prev timeout retrans\n");
  for (n=0; n<QUEUE_SIZE; n++) {
    printf("%d %d %d %d %d %d %d\n",
	   n,
	   queue->qmsga[n].state,
	   queue->qmsga[n].seq,
	   queue->qmsga[n].next,
	   queue->qmsga[n].prev,
	   (int) queue->qmsga[n].timeout,
	   queue->qmsga[n].retrans);
  }
  return 0;
}

int queue_seqhash(struct sockaddr_in *peer, uint16_t seq) {
  /* With QUEUE_HASH_SIZE = 2^16 this describes all possible
     seq values. Thus we have perfect hash for the request queue.
     For the response queue we might have collisions, but not very
     often.
     For performance optimisation we should remove the modulus
     operator, but this is only valid for QUEUE_HASH_SIZE = 2^16 */
  return seq % QUEUE_HASH_SIZE;
}

int queue_seqset(struct queue_t *queue, struct qmsg_t *qmsg,
		 struct sockaddr_in *peer, uint16_t seq) {
  int hash = queue_seqhash(peer, seq);
  struct qmsg_t *qmsg2;
  struct qmsg_t *qmsg_prev = NULL;

  if (QUEUE_DEBUG) printf("Begin queue_seqset seq = %d\n", (int) seq);
  if (QUEUE_DEBUG) printf("SIZEOF PEER %d, *PEER %d\n", sizeof(peer), sizeof(*peer));

  qmsg->seq = seq;
  memcpy(&qmsg->peer, peer, sizeof(*peer));

  for (qmsg2 = queue->hashseq[hash]; qmsg2; qmsg2 = qmsg2->seqnext)
    qmsg_prev = qmsg2;
  if (!qmsg_prev) 
    queue->hashseq[hash] = qmsg;
  else
    qmsg_prev->seqnext = qmsg;
  if (QUEUE_DEBUG) printf("End queue_seqset\n");
  return 0;
}
int queue_seqdel(struct queue_t *queue, struct qmsg_t *qmsg) {
  int hash = queue_seqhash(&qmsg->peer, qmsg->seq);
  struct qmsg_t *qmsg2;
  struct qmsg_t *qmsg_prev = NULL;
  if (QUEUE_DEBUG) printf("Begin queue_seqdel seq = %d\n", (int) qmsg->seq);

  for (qmsg2 = queue->hashseq[hash]; qmsg2; qmsg2 = qmsg2->seqnext) {
    if (qmsg == qmsg) {
      if (!qmsg_prev) 
	queue->hashseq[hash] = qmsg2->seqnext;
      else 
	qmsg_prev->seqnext = qmsg2->seqnext;
      if (QUEUE_DEBUG) printf("End queue_seqset: SEQ found\n");
      return 0;
    }
    qmsg_prev = qmsg2;
  }
  printf("End queue_seqset: SEQ not found\n");
  return EOF; /* End of linked list and not found */
}


/*  Allocates and initialises new queue structure */
int queue_new(struct queue_t **queue) {
  if (QUEUE_DEBUG) printf("queue_new\n");
  *queue = calloc(1, sizeof(struct queue_t));
  (*queue)->next = 0;
  (*queue)->first = -1;
  (*queue)->last = -1;

  if (QUEUE_DEBUG) queue_print(*queue);
  if (*queue) return 0;
  else return EOF;
}

/*  Deallocates queue structure */
int queue_free(struct queue_t *queue) {
  if (QUEUE_DEBUG) printf("queue_free\n");
  if (QUEUE_DEBUG) queue_print(queue);
  free(queue);
  return 0;
}

int queue_newmsg(struct queue_t *queue, struct qmsg_t **qmsg,
		 struct sockaddr_in *peer, uint16_t seq) {
  if (QUEUE_DEBUG) printf("queue_newmsg %d\n", (int) seq);
  if (queue->qmsga[queue->next].state == 1) {
    return EOF; /* Queue is full */
  }
  else {
    *qmsg = &queue->qmsga[queue->next];
    queue_seqset(queue, *qmsg, peer, seq);
    (*qmsg)->state = 1;    /* Space taken */
    (*qmsg)->this = queue->next;
    (*qmsg)->next=-1;       /* End of the queue */
    (*qmsg)->prev=queue->last; /* Link to the previous */
    queue->qmsga[queue->last].next=queue->next; /* Link previous to us */
    queue->last = queue->next;                  /* End of queue */
    if (queue->first == -1) queue->first = queue->next;
    queue->next = (queue->next+1) % QUEUE_SIZE;   /* Increment */
    if (QUEUE_DEBUG) queue_print(queue);
    return 0;
  }
}

int queue_freemsg(struct queue_t *queue, struct qmsg_t *qmsg) {
  if (QUEUE_DEBUG) printf("queue_freemsg\n");
  if (qmsg->state != 1) { 
    return EOF; /* Not in queue */
  }

  queue_seqdel(queue, qmsg);

  if (qmsg->next == -1) /* Are we the last in queue? */
    queue->last = qmsg->prev;
  else
    queue->qmsga[qmsg->next].prev = qmsg->prev;
    
  if (qmsg->prev == -1) /* Are we the first in queue? */
    queue->first = qmsg->next;
  else
    queue->qmsga[qmsg->prev].next = qmsg->next;

  memset(qmsg, 0, sizeof(struct qmsg_t)); /* Just to be safe */

  if (QUEUE_DEBUG) queue_print(queue);

  return 0;
}

int queue_back(struct queue_t *queue, struct qmsg_t *qmsg) {
  if (QUEUE_DEBUG) printf("queue_back\n");
  if (qmsg->state != 1) { 
    return EOF; /* Not in queue */
  }

  /* Insert stuff to maintain hash table */

  if (qmsg->next != -1) {/* Only swop if there are others */
    queue->qmsga[qmsg->next].prev = qmsg->prev;
    queue->first = qmsg->next;
    
    qmsg->next = -1;
    qmsg->prev = queue->last;
    if (queue->last != -1) queue->qmsga[queue->last].next = qmsg->this; 
    queue->last = qmsg->this;
  }
  if (QUEUE_DEBUG) queue_print(queue);
  return 0;
}

/* Get the element with a particular sequence number */
int queue_getfirst(struct queue_t *queue, struct qmsg_t **qmsg) {
  /*printf("queue_getfirst\n");*/
  if (queue->first == -1) {
    *qmsg = NULL;
    return EOF; /* End of queue = queue is empty. */
  }
  *qmsg = &queue->qmsga[queue->first];
  if (QUEUE_DEBUG) queue_print(queue);
  return 0;
}

int queue_getseqx(struct queue_t *queue, struct qmsg_t **qmsg,
		 struct sockaddr_in *peer, uint16_t seq) {
  int n;
  if (QUEUE_DEBUG) printf("queue_getseq, %d\n", (int) seq);
  if (QUEUE_DEBUG) queue_print(queue);
  for (n=0; n<QUEUE_SIZE; n++) {
    if ((queue->qmsga[n].seq == seq) &&
	(!memcmp(&queue->qmsga[n].peer, peer, sizeof(*peer)))) {
      *qmsg = &queue->qmsga[n];
      return 0;
    }
  }
  return EOF; /* Not found */
}

int queue_seqget(struct queue_t *queue, struct qmsg_t **qmsg,
		 struct sockaddr_in *peer, uint16_t seq) {
  int hash = queue_seqhash(peer, seq);
  struct qmsg_t *qmsg2;
  if (QUEUE_DEBUG) printf("Begin queue_seqget seq = %d\n", (int) seq);
  for (qmsg2 = queue->hashseq[hash]; qmsg2; qmsg2 = qmsg2->seqnext) {
    if ((qmsg2->seq == seq) && 
	(!memcmp(&qmsg2->peer, peer, sizeof(*peer)))) {
      *qmsg = qmsg2;
      if (QUEUE_DEBUG) printf("End queue_seqget. Found\n");
      return 0;
    }
  }
  if (QUEUE_DEBUG) printf("End queue_seqget. Not found\n");
  return EOF; /* End of linked list and not found */
}

int queue_freemsg_seq(struct queue_t *queue, struct sockaddr_in *peer, 
		      uint16_t seq, uint8_t *type, void **aid) {
  struct qmsg_t *qmsg;
  if (queue_seqget(queue, &qmsg, peer, seq)) {
    *aid = NULL;
    *type = 0;
    return EOF;
  }
  *aid = qmsg->aid;
  *type = qmsg->type;
  if (queue_freemsg(queue, qmsg)) {
    return EOF;
  }
  return 0;
}
