/*
[SCE CONFIDENTIAL]
$PSDocId$
                  Copyright (C) 2002-4 Sony Computer Entertainment America
                                                     All Rights Reserved
//  ------------------------------------------------------------------------

File: i18n_inet.c

Inet exports a single string for the PPP phase and/or error.
to simplify i18n, reverse map this string into comparable 
ifstat phase/error values defined by libeenet.

Inet PPP phase string => libeenet PPP phase code
-------------------------------------------------------

    o PHASE Starting      => sceEENETCTL_P_PppEstablish
    o PHASE Dialing       => sceEENETCTL_PP_ModemConnecting
    o PHASE Login         => sceEENETCTL_P_PppEstablish
    o PHASE LCP           => sceEENETCTL_P_PppEstablish
    o PHASE Auth          => sceEENETCTL_P_PppAuth
    o PHASE IPCP          => sceEENETCTL_P_PppNetwork
    o PHASE Idle          => sceEENETCTL_P_PppNetwork
    o PHASE Terminate     => sceEENETCTL_P_PppTerminate
    o PHASE Dead          => sceEENETCTL_P_PppDead

Inet PPP error string => libeenet PPP error code
----------------------------------------------------------

    o ABORT BUSY          => sceEENETCTL_EE_ModemBusy
    o ABORT LINE IN USE   => sceEENETCTL_EE_ModemCannotConnect
    o ABORT NO ANSWER     => sceEENETCTL_EE_ModemCannotConnect
    o ABORT NO DIALTONE   => sceEENETCTL_EE_ModemCannotConnect
    o ABORT NO CARRIER    => sceEENETCTL_EE_ModemHangUp
    o ABORT ____          => sceEENETCTL_EE_ModemUnknown
    
    o AUTH Failed         => sceEENETCTL_E_PppAuth
    
    o DISCONNECT ___      => sceEENETCTL_E_Ppp___
    o TIMEOUT ___         => sceEENETCTL_E_Ppp___

//  ------------------------------------------------------------------------
*/

#include <stdio.h>
#include <string.h>

#include "../include/eznetcnf.h"
#include "../include/eznetctl_i18n.h"
#include "internal.h"


/*
 *  DO NOT localize any of the string constants below.
 */

typedef struct {
    const char *token;
    int phase;
    int error;
} pppStatusMap_t;

static const
pppStatusMap_t pppStatusList[] = {
    {   "Starting",
        sceEENETCTL_P_PppEstablish,
        sceEENETCTL_E_PppLinkEstab,
    },
    {   "Dialing",
        sceEENETCTL_PP_ModemConnecting,
        sceEENETCTL_EE_ModemUnknown,
    },
    {   "Login",
        sceEENETCTL_P_PppEstablish,
        sceEENETCTL_E_PppLinkEstab,
    },
    {   "LCP",
        sceEENETCTL_P_PppEstablish,
        sceEENETCTL_E_PppLinkEstab,
    },
    {   "Auth",
        sceEENETCTL_P_PppAuth,
        sceEENETCTL_E_PppAuth,
    },
    {   "IPCP",
        sceEENETCTL_P_PppEstablish,
        sceEENETCTL_E_PppNetwork,
    },
    {   "Idle",
        sceEENETCTL_P_PppNetwork,
        sceEENETCTL_E_PppNetwork,
    },
    {   "Terminate",
        sceEENETCTL_P_PppTerminate,
        sceEENETCTL_E_PppTerminate,
    },
    {   "Dead",
        sceEENETCTL_P_PppDead,
        sceEENETCTL_E_PppTerminate,
    },
    {   NULL, 0, 0 }
};


/*
 *  PUBLIC: ezNetCtlIfstat_u recreation function for Inet
 *
 *  input:  ifstatStrBuf
 *  output: ezNetCtlStatus_t.error
 *          ezNetCtlIfstat_u.[ppp,pppoe] phases and strings
 *
 *  Note: only a limited range phase codes can be recreated.
 *
 *  for ezNetCtlIfstat_t.ppp,   ppp_phase == modem_phase:
 *      { sceEENETCTL_P_Ppp*, sceEENETCTL_PP_ModemConnecting }
 *  for ezNetCtlIfstat_t.pppoe, ppp_phase == pppoe_phase:
 *      { sceEENETCTL_P_Ppp* only }
 */
void
ezNetCtlRecreateIfstat(const char *ifstatStrBuf,
                       ezNetCtlStatus_t *s, 
                       ezNetCtlIfstat_u *ifstat)
{
    const char *t1, *t2;
    const pppStatusMap_t *e;

    memset(ifstat, 0, sizeof(ezNetCtlIfstat_u));

    // token1 is not terminated (use strncmp)
    t1 = ifstatStrBuf;

    if (strlen(t1) > 0) {
        // mark token2
        t2 = strchr(t1, ' ');
        if (t2 != NULL) {
            t2++;
        }

        // hardcoded string offsets, must match irx-src/eznetctl.c
        if (s->iftype == sceEENET_IFTYPE_PPP) {
            strncpy(ifstat->ppp.status_string,  ifstatStrBuf,      80);
            strncpy(ifstat->ppp.phone_number,   ifstatStrBuf+80,   32);
            strncpy(ifstat->ppp.last_string,    ifstatStrBuf+80,   32);
            strncpy(ifstat->ppp.auth_message,   ifstatStrBuf+128, 128);
        } else if (s->iftype == sceEENET_IFTYPE_PPPOE) {
            strncpy(ifstat->pppoe.auth_message, ifstatStrBuf+128, 128);
        }

        // PPP modem error codes
        if (!strncmp(t1, "ABORT", 5)) {
            if (!strcmp(t2, "BUSY")) {
                s->error = sceEENETCTL_EE_ModemBusy;
            } else if (!strcmp(t2, "LINE IN USE")) {
                s->error = sceEENETCTL_EE_ModemCannotConnect;
            } else if (!strcmp(t2, "NO DIALTONE")) {
                s->error = sceEENETCTL_EE_ModemCannotConnect;
            } else if (!strcmp(t2, "NO ANSWER")) {
                s->error = sceEENETCTL_EE_ModemCannotConnect;
            } else if (!strcmp(t2, "NO CARRIER")) {
                s->error = sceEENETCTL_EE_ModemHangUp;
            } else {
                s->error = sceEENETCTL_EE_ModemUnknown;
            }
            ifstat->ppp.ppp_phase = sceEENETCTL_P_PppDead;
            goto done;
        }

        // PPP authentication error code
        if (!strcmp(t1, "AUTH Failed")) {
            s->error = sceEENETCTL_E_PppAuth;
            goto done;
        }

        // PPP phase or error codes
        for (e = pppStatusList; e->token != NULL; e++) {
            if (!strcmp(t2, e->token)) {
                if (!strncmp(t1, "PHASE", 5)) {
                    if (s->iftype == sceEENET_IFTYPE_PPP) {
                        ifstat->ppp.ppp_phase = ifstat->ppp.modem_phase = e->phase;
                    } else {
                        ifstat->pppoe.ppp_phase = ifstat->pppoe.pppoe_phase = e->phase;
                    }
                } else if (!strncmp(t1, "DISCONNECT", 10)) {
                    s->error = e->error;
                } else if (!strncmp(t1, "TIMEOUT", 7)) {
                    s->error = e->error;
                }
                break;
            }
        }
    }

done:
    return;
}

