#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/sctp.h>
#include <arpa/inet.h>
#include "common.h"

int main()
{
  int connSock, in, i, ret, flags;
  struct sockaddr_in servaddr;
  struct sctp_status status;
  struct sctp_sndrcvinfo sndrcvinfo;
  struct sctp_event_subscribe events;
  struct sctp_initmsg initmsg;
  char buffer[MAX_BUFFER+1];
	int exitMsg=0;
  /* Crea SCTP socket */
  connSock = socket( AF_INET, SOCK_STREAM, IPPROTO_SCTP ); // IPPROTO_SCTP

  /* Configuración socket: 5 stream por cada socket */
  memset( &initmsg, 0, sizeof(initmsg) );
  initmsg.sinit_num_ostreams = 5;
  initmsg.sinit_max_instreams = 5;
  initmsg.sinit_max_attempts = 4;
  ret = setsockopt( connSock, IPPROTO_SCTP, SCTP_INITMSG,&initmsg, sizeof(initmsg) );

  // Especificacion del destino:
  bzero( (void *)&servaddr, sizeof(servaddr) );
  servaddr.sin_family = AF_INET;
  servaddr.sin_port = htons(MY_PORT_NUM);
  servaddr.sin_addr.s_addr = inet_addr( "127.0.0.1" ); // IP SERVIDOR

  /* Conexión al servidor */
  ret = connect( connSock, (struct sockaddr *)&servaddr, sizeof(servaddr) );

  /* Enable receipt of SCTP Snd/Rcv Data via sctp_recvmsg */
  memset( (void *)&events, 0, sizeof(events) );
  events.sctp_data_io_event = 1;
  ret = setsockopt( connSock, SOL_SCTP, SCTP_EVENTS,(const void *)&events, sizeof(events) );

  /* Lee y muestra estado de socket */
  in = sizeof(status);
  ret = getsockopt( connSock, SOL_SCTP, SCTP_STATUS,
                     (void *)&status, (socklen_t *)&in );

  
  printf("Id. Asociacion \t\t\t= %d\n", status.sstat_assoc_id ); // Id. de asociacion
  printf("Estado\t\t\t\t= "); // Status
  	  switch (status.sstat_state )
	  {
		  case 0: printf("Empty\n"); break;
		  case 1: printf("Closed\n"); break;
		  case 2: printf("Cookie Wait\n"); break;
		  case 3: printf("Cookie Echoed\n");break;
		  case 4: printf("Established\n");break;
		  case 5: printf("Shutdown Pending\n");break;
		  case 6: printf("Shutdown Sent\n");break;
		  case 7: printf("Shutdown Received\n");break;
		  case 8: printf("Shutdown ACK Sent\n");break;
		  default: printf(" \n");break;
      }
  printf("Streams de entrada \t\t= %d\n", status.sstat_instrms ); // Streams de entrada
  printf("Streams de salida \t\t= %d\n", status.sstat_outstrms ); // Streams de salida


  printf("\n ---------------------------------- \n Datos recibidos \n ---------------------------------- \n");
  
  i=0;exitMsg=0;

	while(1)
	{
		
	    in = sctp_recvmsg( connSock, (void *)buffer, sizeof(buffer),(struct sockaddr *)NULL, 0, &sndrcvinfo, &flags );
	    if (in > 0) {
	      buffer[in] = 0;
	      if(!strcmp("exit\n",buffer)) break;

	      // Imprime en pantalla lo que recibe en cada stream
	      if (sndrcvinfo.sinfo_stream == STREAM_0) {
		printf("(Stream 0) %s\n", buffer);
		printf("(Stream 0) Len: %d\n\n", strlen(buffer));
	      } else if (sndrcvinfo.sinfo_stream == STREAM_1) {
		printf("(Stream 1) %s\n", buffer);
		printf("(Stream 1) Len: %d\n\n", strlen(buffer));
	      } else if (sndrcvinfo.sinfo_stream == STREAM_2) {
		printf("(Stream 2) %s\n", buffer);
		printf("(Stream 2) Len: %d\n\n", strlen(buffer));
	      } else if (sndrcvinfo.sinfo_stream == STREAM_3) {
		printf("(Stream 3) %s\n", buffer);
		printf("(Stream 3) Len: %d\n\n", strlen(buffer));
	      } else if (sndrcvinfo.sinfo_stream == STREAM_4) {
		printf("(Stream 4) %s\n", buffer);
		printf("(Stream 4) Len: %d\n\n", strlen(buffer));
	      }
	    }

	    
	}	
  // Cierra socket, termina programa
  close(connSock);
  printf("\n ---------------------------------- \n Fin de Asociación \n ---------------------------------- \n");
  return 0;
}

