/** @file sys_main.c 
*   @brief Application main file
*   @date 11-Dec-2018
*   @version 04.07.01
*
*   This file contains an empty main function,
*   which can be used for the application.
*/

/* 
* Copyright (C) 2009-2018 Texas Instruments Incorporated - www.ti.com 
* 
* 
*  Redistribution and use in source and binary forms, with or without 
*  modification, are permitted provided that the following conditions 
*  are met:
*
*    Redistributions of source code must retain the above copyright 
*    notice, this list of conditions and the following disclaimer.
*
*    Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in the 
*    documentation and/or other materials provided with the   
*    distribution.
*
*    Neither the name of Texas Instruments Incorporated nor the names of
*    its contributors may be used to endorse or promote products derived
*    from this software without specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
*  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/

/* USER CODE BEGIN (0) */
/* USER CODE END */

/* Include Files */

#include "sys_common.h"

/* USER CODE BEGIN (1) */
/* Include FreeRTOS scheduler files */
#include "FreeRTOS.h"
#include "os_task.h"
#include "os_queue.h"

/* Include HET header file - types, definitions and function declarations for system driver */
#include "het.h"
#include "esm.h"

#include "tcp_client.h"
#include "ping.h"
#include "sci.h"
#include "lwftp.h"



#include "includes.h"

extern void EMAC_LwIP_Main (uint8 * emacAddress);


uint8   emacAddress[6U] =   {0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU};
uint32  emacPhyAddress  =   0U;


/********************************************************************************/

int min(int num1, int num2);

int min(int num1, int num2)
{
    return (num1 > num2 ) ? num2 : num1;
}


static void ftp_retr_callback(void *arg, int result)
{
    lwftp_session_t *s = (lwftp_session_t*)arg;
    sciSend(scilinREG, 3, " 8 ");

    if ( result != LWFTP_RESULT_OK ) {
      //  ////LOG_ERROR("retr failed (%d)", result);
        sciSend(scilinREG, 5, " 8.1 ");

   //     return lwftp_close(s);
    }

    sciSend(scilinREG, 5, " 8.2 ");

    // Test is done
    //lwftp_close(s);
}

static unsigned int data_sink(void *arg, const char* ptr, unsigned int len)
{
    sciSend(scilinREG, 3, " 7 ");
   // static const unsigned int mylen = 12345;
   // static char * const myconfig = (char*)0x20000000;
    static const unsigned int mylen = 10;
    static char * const myconfig = (char*)0x20000000;
    static unsigned int offset = 0;

    if (ptr) {
        len = min( len, mylen-offset );
        memcpy( myconfig+offset, ptr, len );
        offset += len;
    }
    return len;
}

static void ftp_stor_callback(void *arg, int result)
{
    lwftp_session_t *s = (lwftp_session_t*)arg;
    err_t error;
    sciSend(scilinREG, 3, " 6 ");

  //  if ( result != LWFTP_RESULT_OK ) {
     //   ////LOG_ERROR("stor failed (%d)", result);
  //      sciSend(scilinREG, 4, " E6 ");

    //    return lwftp_close(s);
   // }
    // Continue with RETR request
    s->data_sink = data_sink;
    s->done_fn = ftp_retr_callback;       // La llama para cerrar la conexión
    s->remote_path = "configfile";
    error = lwftp_retrieve(s);
    if ( error != LWFTP_RESULT_INPROGRESS ) {
        sciSend(scilinREG, 4, " E7");

      //  ////LOG_ERROR("lwftp_retrieve failed (%d)", error);
    }
    // FTP session will continue with RETR and sink callbacks
}

static unsigned int data_source(void *arg, const char** pptr, unsigned int maxlen)
{
    sciSend(scilinREG, 3, " 5 ");
    static const unsigned int mylen = 150000;
  //  static const char * const mydata = (char*)0x20000000;
    static const char * const mydata = " HOLA ";

    static unsigned int offset = 0;
    unsigned int len = 0;

    // Check for data request or data sent notice
    if (pptr) {
        len = mylen - offset;
        if ( len > maxlen ) len = maxlen;
        *pptr = mydata + offset;
    } else {
        offset += maxlen;
        if ( offset > mylen ) offset = mylen;
    }
    return len;
}

static void ftp_connect_callback(void *arg, int result)
{
    lwftp_session_t *s = (lwftp_session_t*)arg;
    err_t error;
    sciSend(scilinREG, 3, " 1 ");
    if( result == LWFTP_RESULT_INPROGRESS ){
        sciSend(scilinREG, 3, " 2 ");
     return;
    }
    if ( result != LWFTP_RESULT_LOGGED ) {
        sciSend(scilinREG, 3, " E1 ");
        ////LOG_ERROR("login failed (%d)", result);
        return lwftp_close(s);
    }
    // Continue with STOR request
    s->data_source = data_source;
    s->done_fn = ftp_stor_callback;
    s->remote_path = "logfile";
    error = lwftp_store(s);
    if ( error != LWFTP_RESULT_INPROGRESS ) {
        sciSend(scilinREG, 4, " E2 ");

        ////LOG_ERROR("lwftp_store failed (%d)", error);
    }
    // FTP session will continue with STOR and source callbacks
}


/* Fuction to wait a time*/
void delay2 (float time){
    int long c, x_time = (int long) (1.36e7 * time);
    for (c=0; c <= 2 * x_time; c++){
    }
}


static void ftp_test(void)
{
    static lwftp_session_t s;   // static content for the whole FTP session
    err_t error;

    // Initialize session data
    memset(&s, 0, sizeof(s));
    IP4_ADDR(&s.server_ip, 192,168,0,20);
    s.server_port = 21;
    s.done_fn = ftp_connect_callback;
    s.user = "username";
   // s.pass = "UrL!V8IZs6";

 //   s.user = "";
    s.pass = "password";

    // We have no extra user data, simply use the session structure
    s.handle = &s;

    // Start the connection state machine
    error = lwftp_connect(&s);
    if ( error != LWFTP_RESULT_INPROGRESS ) {
        sciSend(scilinREG, 14, " error conec ");
        ////LOG_ERROR("lwftp_connect failed (%d)", error);
    }

    while(1)
    {

       delay2(2000);
      //  lwftp_send_next_data(&s);
     //   SEND(&s);
    }

   // s.done_fn = ftp_connect_callback;
    // FTP session will continue with the connection callback
}




/********************************************************************************/

int main(void)
{
/* USER CODE BEGIN (3) */
    /* Set high end timer GIO port hetPort pin direction to all output */
    gioSetDirection(hetPORT1, 0xFFFFFFFF);
    sciInit();
    static lwftp_session_t s;

    EMAC_LwIP_Main (emacAddress);


    ftp_test();

    /* Run forever */
    while(1)
    {



    }
/* USER CODE END */

    return 0;
}



/* USER CODE END */