/* 
 *  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 */
    if (queue->last != -1)
      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;
}
