#define MY_NDKPRI_LOW 3
#define MY_NDKPRI_NORM 5 
#define MY_NDKPRI_HIGH 7
#define MY_NDKPRI_KERN 9

int Network_stack(void)
{
    int     rc;
    HANDLE  hCfg;
    
    Network_init();

    // THIS MUST BE THE ABSOLUTE FIRST THING DONE IN AN APPLICATION!!
    rc = NC_SystemOpen(NET_STACK_TASK_PRIORITY, NC_OPMODE_INTERRUPT);

    if (rc)
    {
        platform_write("NC_SystemOpen Failed (%d)\n", rc);
        for (;;);
    }

    // Print the banner
    platform_write(banner);

    // Create a new configuration
    hCfg = CfgNew();

    if (!hCfg)
    {
        platform_write("Unable to create configuration\n");
        NC_SystemClose();
        return 0;        
    }

    // Do not show debug messages less than WARNINGS
    rc = DBG_WARN;
    CfgAddEntry(hCfg, CFGTAG_OS, CFGITEM_OS_DBGPRINTLEVEL, CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *) &rc, 0);

    // Setup the TCP and UDP buffer sizes (8192 is the default)
    rc = SOCKTCP_TXBUF_SZ;
    CfgAddEntry( hCfg, CFGTAG_IP, CFGITEM_IP_SOCKTCPTXBUF,
                CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 );

    // TCP Receive buffer size (copy mode)
    rc = 8192;
    CfgAddEntry( hCfg, CFGTAG_IP, CFGITEM_IP_SOCKTCPRXBUF,
                CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 );

    // TCP Receive limit (non-copy mode)
    rc = 8192;
    CfgAddEntry( hCfg, CFGTAG_IP, CFGITEM_IP_SOCKTCPRXLIMIT,
                CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 );

    // UDP Receive limit
    rc = 8192;
    CfgAddEntry(hCfg, CFGTAG_IP, CFGITEM_IP_SOCKUDPRXLIMIT, CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *) &rc, 0);

    rc = 4096; // increase stack size
    CfgAddEntry(hCfg, CFGTAG_OS, CFGITEM_OS_TASKSTKBOOT, CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *) &rc, 0);

    /* *********************************************************************** */

    /* add the configuration settings for NDK low priority task level. */
    rc = MY_NDKPRI_LOW;
    CfgAddEntry(hCfg, CFGTAG_OS, CFGITEM_OS_TASKPRILOW,
                 CFG_ADDMODE_UNIQUE, sizeof(uint32_t), (unsigned char *)&rc, 0 );

    /* add the configuration settings for NDK normal priority task level. */
    rc = MY_NDKPRI_NORM;
    CfgAddEntry(hCfg, CFGTAG_OS, CFGITEM_OS_TASKPRINORM,
                 CFG_ADDMODE_UNIQUE, sizeof(uint32_t), (unsigned char *)&rc, 0 );

    /* add the configuration settings for NDK high priority task level. */
    rc = MY_NDKPRI_HIGH;
    CfgAddEntry(hCfg, CFGTAG_OS, CFGITEM_OS_TASKPRIHIGH,
                 CFG_ADDMODE_UNIQUE, sizeof(uint32_t), (unsigned char *)&rc, 0 );

    rc = MY_NDKPRI_KERN;
    CfgAddEntry(hCfg, CFGTAG_OS, CFGITEM_OS_TASKPRIKERN,
                 CFG_ADDMODE_UNIQUE, sizeof(uint32_t), (unsigned char *)&rc, 0 );
    
    /* *********************************************************************** */

    hCfg_  = hCfg;

    // Boot the system using this configuration and keep booting until the function returns 0. 
    // This allows for a "reboot" command.
    do
    {
        rc = NC_NetStart(hCfg, NetworkOpen, NetworkClose, NetworkIPAddr);
    } while (rc > 0);

    // Delete Configuration
    CfgFree(hCfg);

    platform_write("Network_stack: exiting\n");
    NC_SystemClose();

    return 0;
}

// network stack thread:
...
ndkStackTskParams.priority = MY_NDKPRI_NORM;
if (Task_create(networkStack, &ndkStackTskParams, &eb) != NULL) {
...

// TX task
...
tskParams.priority = MY_NDKPRI_NORM;
Task_create(txTask, &xmt_task_stub_, &eb);

// RX task
...
tskParams.priority = MY_NDKPRI_NORM;
Task_create(rxTask, &rcv_task_stub_, &eb);

// repeat for other network task threads
