[psp] iniciar el modo AD-Hoc (3.71)

Hola buenas.
Neceisto ayuda.


!!!!Alguien sabe como inicializar el modo Ad-hoc.!!!!!!!

Yo he puesto esto (no quiere decir que esté bien)


while (sceWlanGetSwitchState() == 0){
printf("Wlan interruptor: %s\n", sceWlanGetSwitchState() == 0 ? "off":"on");
}
while (sceWlanDevIsPowerOn() == 0){
printf("Wlan corriente (estaria averiada si no le llega corriente: %s\n", sceWlanDevIsPowerOn() == 0 ? "off":"on");
}
retVal = sceWlanGetEtherAddr(mac);
if (retVal == 0){
printf("Direccion Ethernet: %02X:%02X:%02X:%02X:%02X:%02X\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
ok=1;
}
else{
printf("Error con la direccion Ethernet (0x%08X)\n", retVal);
}
}

int ret=0;
printf("[main]: inicializando la red (PSP 3.x)... \n");

ret=sceUtilityLoadNetModule(PSP_NET_MODULE_COMMON);printf("sceUtilityLoadNetModule(PSP_NET_MODULE_COMMON) %i\n",ret);
ret=sceUtilityLoadNetModule(PSP_NET_MODULE_ADHOC);printf("sceUtilityLoadNetModule(PSP_NET_MODULE_ADHOC) %i\n",ret);
ret=pspSdkInetInit();printf("pspSdkInetInit %i\n",ret);
ret=sceNetAdhocInit();printf("sceNetAdhocInit %i\n",ret);


hasta aqui me da 0 en sceNetAdhocInit, o sea , que paraece que lo incializa( aunque la linea ret=pspSdkInetInit();printf("pspSdkInetInit %i\n",ret); me da 0 en ret)

Luego segun he leido (eso cre) tendria que preparar un paquete para enviar :

int pdp = sceNetAdhocPdpCreate(mac, 0x100, 0x400, 0);printf ("pdp= %i\n",pdp);

Pero aqui siempre me da en pdp un numero negativo, y eso significa error.

Alguna ayudaa por favorrrr.
Mirando un poco por ahí, he visto un par de cosas, como te decía con el modo adhoc no usas TCP/IP, y va todo sobre ethernet.

Lo primero te recomendaría que te bajases el código del smsplus 1.2 adhoc de aquí:
http://www.pspbrew.com/?page=fileInfo&cid=&d=867

El problema es que este sistema, esta muy poco documentado y muy poco usado, la poca información que hay fue sacada a través de ingeniería inversa del juego luminies.

Si miras el código del smsplus, en el fichero src/psp/Adhoc/pspadhoc.c tienes la incializacion correcta del modo adhoc.

bool g_NetInit = false;
bool g_NetAdhocInit = false;
bool g_NetAdhocctlInit = false;
bool g_NetAdhocctlConnect = false;
bool g_NetAdhocPdpCreate = false;
bool g_NetAdhocMatchingInit = false;
bool g_NetAdhocMatchingCreate = false;
bool g_NetAdhocMatchingStart = false;

int adhocInit(char *MatchingData)
{
        char mac[6];
        struct productStruct product;

        ClearPspList();

        strcpy(product.product, "ULUS99999");
        product.unknown = 0;

    u32 err;
        printf("sceNetInit()\n");
    err = sceNetInit(0x20000, 0x20, 0x1000, 0x20, 0x1000);
    if (err != 0)
        return err;
        g_NetInit = true;

        printf("sceNetAdhocInit()\n");
    err = sceNetAdhocInit();
    if (err != 0)
        return err;
        g_NetAdhocInit = true;

        printf("sceNetAdhocctlInit()\n");
    err = sceNetAdhocctlInit(0x2000, 0x20, &product);
    if (err != 0)
        return err;
        g_NetAdhocctlInit = true;

    // Connect
    err = sceNetAdhocctlConnect("");
    if (err != 0)
        return err;
        g_NetAdhocctlConnect = true;

    int stateLast = -1;
    printf("Connecting...\n");
    while (1)
    {
        int state;
        err = sceNetAdhocctlGetState(&state);
        if (err != 0)
        {
            printf("sceNetApctlGetState returns $%x\n", err);
            sceKernelDelayThread(10*1000000); // 10sec to read before exit
                        return -1;
        }
        if (state > stateLast)
        {
            printf("  connection state %d of 1\n", state);
            stateLast = state;
        }
        if (state == 1)
            break;  // connected

        // wait a little before polling again
        sceKernelDelayThread(50*1000); // 50ms
    }
    printf("Connected!\n");

        sceWlanGetEtherAddr(mac);

    printf("sceNetAdhocPdpCreate\n");
        pdpId = sceNetAdhocPdpCreate(mac,
                     0x309,             // 0x309 in lumines
                     0x400,     // 0x400 in lumines
                     0);                // 0 in lumines
        if(pdpId <= 0)
        {
                printf("pdpId = %x\n", pdpId);
                return -1;
        }
        g_NetAdhocPdpCreate = true;

        printf("sceNetAdhocMatchingInit()\n");
        err = sceNetAdhocMatchingInit(0x20000);
        if(err != 0)
        {
                printf("error = %x\n", err);
        }
        g_NetAdhocMatchingInit = true;

        printf("sceNetAdhocMatchingCreate()\n");
        matchingId = sceNetAdhocMatchingCreate( 3,
                                                                                        0xa,
                                                                                        0x22b,
                                                                                        0x800,
                                                                                        0x2dc6c0,
                                                                                        0x5b8d80,
                                                                                        3,
                                                                                        0x7a120,
                                                                                        matchingCallback);
        if(matchingId < 0)
        {
                printf("matchingId = %x\n", matchingId);
        }
        g_NetAdhocMatchingCreate = true;

        char tempStr[100];
        tempStr[0] = '\0';

        if(strlen(MatchingData))
        {
                strncpy(tempStr, strrchr(MatchingData, '/')+1, 100);
                strrchr(tempStr, '.')[0] = '\0';
        }

        printf("tempStr=%s\n", tempStr);

        printf("sceNetAdhocMatchingStart()\n");
        err = sceNetAdhocMatchingStart(matchingId,      // 1 in lumines (presuming what is returned from create)
                         0x10,          // 0x10
                         0x2000,                // 0x2000
                         0x10,          // 0x10
                         0x2000,                // 0x2000
                         strlen(tempStr)+1,
                         tempStr);
        if(err != 0)
        {
                printf("error = %x\n", err);
        }
        g_NetAdhocMatchingStart = true;

        // All the init functions have passed
        return 0;
}


De ese programa deberías poder sacar todo lo que necesites sobre el modo adHoc, de todas formas ten en cuenta que esta hecho para el modo 1.50 y se hizo cuando la parte de adHoc todavía no estaba en el PSPSDK, asi que el pavo tira directamente de las direcciones de memoria del modulo.

(Esto no hace falta, es para que veas y sepas, que este código es de las cosas del ejemplo que no necesitas)
# Additional Stubs for sceNet APIs (not yet in the PSPSDK)
# NOTE: require tricky user entry patching when loaded from kernel thread

      .set noreorder

    .include "psp/Adhoc/common.s"

STUB_START "sceNet",0x90000,0x00080005
  STUB_FUNC 0x39af39a6,sceNetInit
  STUB_FUNC 0x281928a9,sceNetTerm
  STUB_FUNC 0x50647530,sceNetFreeThreadinfo
  STUB_FUNC 0xad6844c6,sceNetThreadAbort
  STUB_FUNC 0x89360950,sceNetEtherNtostr
  STUB_FUNC 0xd27961c9,sceNetEtherStrton
  STUB_FUNC 0x0bf0a3ae,sceNetGetLocalEtherAddr
  STUB_FUNC 0xcc393e48,sceNetGetMallocStat
STUB_END

  STUB_START "sceNetInet",0x90000,0x001c0005
    STUB_FUNC 0x17943399,sceNetInetInit
    STUB_FUNC 0xa9ed66b9,sceNetInetTerm
    STUB_FUNC 0xdb094e1b,sceNetInetAccept
    STUB_FUNC 0x1a33f9ae,sceNetInetBind
    STUB_FUNC 0x8d7284ea,sceNetInetClose
    STUB_FUNC 0x805502dd,sceNetInetCloseWithRST
    STUB_FUNC 0x410b34aa,sceNetInetConnect
    STUB_FUNC 0xe247b6d6,sceNetInetGetpeername
    STUB_FUNC 0x162e6fd5,sceNetInetGetsockname
    STUB_FUNC 0x4a114c7c,sceNetInetGetsockopt
    STUB_FUNC 0xd10a1a7a,sceNetInetListen
    STUB_FUNC 0xfaabb1dd,sceNetInetPoll
    STUB_FUNC 0xcda85c99,sceNetInetRecv
    STUB_FUNC 0xc91142e4,sceNetInetRecvfrom
    STUB_FUNC 0xeece61d2,sceNetInetRecvmsg
    STUB_FUNC 0x5be8d595,sceNetInetSelect
    STUB_FUNC 0x7aa671bc,sceNetInetSend
    STUB_FUNC 0x05038fc7,sceNetInetSendto
    STUB_FUNC 0x774e36f4,sceNetInetSendmsg
    STUB_FUNC 0x2fe71fe7,sceNetInetSetsockopt
    STUB_FUNC 0x4cfe4e56,sceNetInetShutdown
    STUB_FUNC 0x8b7b220f,sceNetInetSocket
    STUB_FUNC 0x80a21abd,sceNetInetSocketAbort
    STUB_FUNC 0xfbabe411,sceNetInetGetErrno
    STUB_FUNC 0xb75d5b0a,sceNetInetInetAddr
    STUB_FUNC 0x1bdf5d13,sceNetInetInetAton
    STUB_FUNC 0xd0792666,sceNetInetInetNtop
    STUB_FUNC 0xe30b8c19,sceNetInetInetPton
  STUB_END



Ves probando con eso a ver que pasa. Luego básicamente creo que es mandar y recibir paquetes, primero tendrás que mandar los paquetes a la mac de broadcast FF:FF:FF:FF:FF:FF y una vez que las psps conozcan las macs entre si, podrás mandar los paquetes "directamente".


Crear el PDP, que seria como el descriptor que se usa en una conexión TCP/IP pero para el adHoc de la PSP.
/**
* Create a PDP object.
*
* @param mac - Your MAC address (from sceWlanGetEtherAddr)
* @param port - Port to use, lumines uses 0x309
* @param unk2 - Unknown, lumines sets to 0x400
* @param unk3 - Unknown, lumines sets to 0
*
* @return The ID of the PDP object (< 0 on error)
*/
int sceNetAdhocPdpCreate(unsigned char *mac, unsigned short port, unsigned int unk2, int unk3);



Mandar un paquete usando el descriptor PDP obtenido, si mandas a 0xFF seria la broadcast y lo verían todas las PSPs, si usas una mac destino entonces solo leerá el paquete la psp destino.
/**
* Set a PDP packet to a destination
*
* @param id - The ID as returned by ::sceNetAdhocPdpCreate
* @param destMacAddr - The destination MAC address, can be set to all 0xFF for broadcast
* @param port - The port to send to
* @param data - The data to send
* @param len - The length of the data.
* @param unk6 - Unknown, set to 0
* @param unk7 - Unknown, set to 0
*
* @return Bytes sent, < 0 on error
*/
int sceNetAdhocPdpSend(int id, unsigned char *destMacAddr, unsigned short port, void *data, unsigned int len, int unk6, int unk7);



Leer un paquete del descriptor PDP obtenido.
/**
* Receive a PDP packet
*
* @param id - The ID of the PDP object, as returned by ::sceNetAdhocPdpCreate
* @param srcMacAddr - Buffer to hold the source mac address of the sender
* @param port - Buffer to hold the port number of he received data
* @param data - Data buffer
* @param dataLength - The length of the data buffer
* @param unk6 - Set to 0
* @param unk7 - Set to 0
*
* @return Number of bytes received, < 0 on error.
*/
int sceNetAdhocPdpRecv(int id, unsigned char *srcMacAddr, unsigned short *port, void *data, void *dataLength, int unk6, int unk7);


Tambien puedes mirar el codigo del smsplus para ver como usa estas funciones, ya que como veras tienen opciones no documentadas y que no se sabe para que son.

Bueno ya nos contaras que tal.


P.D.: Seguramente te puedas saltar la parte de la incializacion de "Matching" y hacerla tu mas sencilla, ya que no viene casi documentada...
Primero necesitas cargar los prx`s necesarias de las librerias que uses para ello necesitas un codigo que las cargue y parche por que habia problemas ( esque yo estaba en verano haciendo un programa para pasar archivos con el adhoc solo me faltaba conseguir capturar un paquete enviado hasta que se me jodio el disco duro :\ ) Yo aprendi estudiandome este codigo http://www.gophinx.co.uk/BlackPhoenix/adhoc-examples.rar ( no se si es igual exactamente pero pienso que si )

Te viene con loadutil.c y loadutil.h que te carga y parchea las prx´s

Animo despues de que termine los examenes me voy a poner a rehacer el programa
kYp escribió:Primero necesitas cargar los prx`s necesarias de las librerias que uses para ello necesitas un codigo que las cargue y parche por que habia problemas ( esque yo estaba en verano haciendo un programa para pasar archivos con el adhoc solo me faltaba conseguir capturar un paquete enviado hasta que se me jodio el disco duro :\ ) Yo aprendi estudiandome este codigo http://www.gophinx.co.uk/BlackPhoenix/adhoc-examples.rar ( no se si es igual exactamente pero pienso que si )

Te viene con loadutil.c y loadutil.h que te carga y parchea las prx´s

Animo despues de que termine los examenes me voy a poner a rehacer el programa


Es que eso era para 1.50 y antes de que añadiesen las funciones de adhoc al PSPSDK...

Ahora para cargar los módulos basta con:
sceUtilityLoadNetModule(PSP_NET_MODULE_COMMON);
sceUtilityLoadNetModule(PSP_NET_MODULE_ADHOC);

Así se puede usar en modo usuario para 3.XX, loadutil necesita "kernel mode" y es para usar las funciones de adhoc directamente a través de las "direcciones/referencias" de memoria del modulo las cuales son de los módulos que venían en la 1.50, y repito que era para cuando las funciones no venían en el PSPSDK.
hola turlox y kYp.
Ante todo muchismas gracias.
BUeno, he implementado el codigo que me pusiste en el 2 post,
he llegado hasta la linea:

matchingId = sceNetAdhocMatchingCreate( 3,
0xa,
0x22b,
0x800,
0x2dc6c0,
0x5b8d80,
3,
0x7a120,
matchingCallback);
en esta me da error el compilador

In file included from main.c:53:
conectaAdhoc.h: En la función ‘adhocInit’:
conectaAdhoc.h:119: error: ‘matchingCallback’ undeclared (first use in this function)
conectaAdhoc.h:119: error: (Each undeclared identifier is reported only once
conectaAdhoc.h:119: error: for each function it appears in.)
make: *** [main.o] Error 1


Todas las lineas anteriores me han ido "contestando con 0" ( o sea comando ejecutado correctamente).

Por favor, a un empujoncito mas.
(realmente es que la documntacion es casi nula de todo esto).
Existe un programa que envia fichero de una psp a otra, de un tal minerva (PSP Wi-Fi Adhoc File Transfer), funciona para 3.71, pero no está las fuentes. (ese vendría de perlas).


bueno de nuevo muchisimas graciasss.
Deberías mirar el código de los ejemplos que te hemos pasado e intentar entender que es lo que hace, si no te va a ser jodido porque documentación como que no hay y los códigos existentes son lo que mas te puede ayudar.

Respecto al error, como te dije, yo diría que te puedes saltar toda la sección de matching, es decir todo este código:

printf("sceNetAdhocMatchingInit()\n");
        err = sceNetAdhocMatchingInit(0x20000);
        if(err != 0)
        {
                printf("error = %x\n", err);
        }
        g_NetAdhocMatchingInit = true;

        printf("sceNetAdhocMatchingCreate()\n");
        matchingId = sceNetAdhocMatchingCreate( 3,
                                                                                        0xa,
                                                                                        0x22b,
                                                                                        0x800,
                                                                                        0x2dc6c0,
                                                                                        0x5b8d80,
                                                                                        3,
                                                                                        0x7a120,
                                                                                        matchingCallback);
        if(matchingId < 0)
        {
                printf("matchingId = %x\n", matchingId);
        }
        g_NetAdhocMatchingCreate = true;

        char tempStr[100];
        tempStr[0] = '\0';

        if(strlen(MatchingData))
        {
                strncpy(tempStr, strrchr(MatchingData, '/')+1, 100);
                strrchr(tempStr, '.')[0] = '\0';
        }

        printf("tempStr=%s\n", tempStr);

        printf("sceNetAdhocMatchingStart()\n");
        err = sceNetAdhocMatchingStart(matchingId,      // 1 in lumines (presuming what is returned from create)
                         0x10,          // 0x10
                         0x2000,                // 0x2000
                         0x10,          // 0x10
                         0x2000,                // 0x2000
                         strlen(tempStr)+1,
                         tempStr);
        if(err != 0)
        {
                printf("error = %x\n", err);
        }
        g_NetAdhocMatchingStart = true;


Cuando digo saltar, quiero decir que no lo incluyas en tu programa.

Ese trozo de código y mas partes que necesita, seria para el "matching/emparejamiento" de las PSP es decir, para crear una lista de consolas con las que se esta hablando en la que añadir o quitar o consolas según se unan o salgan de la partida.

Como no esta nada documentado, te sugiero que pases de ello y hagas tu propio código de matching, ya que tu juego es sencillo y solo hablan 2 PSPs.

El emparejamiento es básicamente obtener las macs de las otras PSPs con las que vas a hablar, ya que lo suyo es que cuando mandas un paquete lo mandes a la mac de la PSP destino en vez de a la mac de broadcast (FF:FF:FF:FF:FF:FF).

Como sin usar las funciones de Matching, ya tienes el descriptor PDP para escribir y leer del wireless, ya puedes dedicarte a hacer el código para comunicar las PSPs.

- Una opción un poco fea, es mandar siempre los paquetes a la mac destino FF:FF:FF:FF:FF:FF, así los podrán leer todas las PSPs

- Otra opción es que te hagas tu propio emparejamiento mandando un aviso a FF:FF:FF:FF:FF:FF diciendo que quieres iniciar una partida, lo mandas cada 5 segundos hasta que recibas una respuesta de otra PSP que haya visto el aviso/paquete, entonces te apuntas la mac de la otra PSP y el resto de los paquetes ya los mandas siempre a esa mac.

No se si me he explicado claro, pero es que eso ya son temas de redes, si no estas familiarizado con el protocolo Ethernet te va a ser un poco raro.


De todas formas y resumiendo, que no uses el código que te he dicho, y que sin usarlo ya puedes hacer sceNetAdhocPdpSend y sceNetAdhocPdpRecv, que es lo que querías.
muchismas graciassa turulox.
Esta todo bien explicado y entendido.

Ahora me centro en el envio y recepcion de paquetes.
Muchas gracias de nuevo.
Ya contaré cosas.
----------------------------------------------------------------------
Hola Turulox.
POr fin puedo enviar, ya consigo enviar paquetes, con el
proceso siguiente:

PARA LEER:
Iniciando:
err=sceUtilityLoadNetModule(PSP_NET_MODULE_COMMON);printf("sceUtilityLoadNetModule(PSP_NET_MODULE_COMMON) %i\n",err);
err=sceUtilityLoadNetModule(PSP_NET_MODULE_ADHOC);printf("sceUtilityLoadNetModule(PSP_NET_MODULE_ADHOC) %i\n",err);
err = sceNetInit(0x20000, 0x20, 0x1000, 0x20, 0x1000);printf("sceNetInit %i\n",err);
err = sceNetAdhocInit();printf("sceNetAdhocInit %i\n",err);
err = sceNetAdhocctlInit(0x2000, 0x20, &product);printf("sceNetAdhocctlInit %i\n",err);
err = sceNetAdhocctlConnect(0);printf("sceNetAdhocctlConnect %i\n",err);
Envio:
err = sceWlanGetEtherAddr(mimac);printf("mimac: %02X:%02X:%02X:%02X:%02X:%02X\n",mimac[3],mimac[4],mimac[5],mimac[0],mimac[1],mimac[2]);
int pdpSd= sceNetAdhocPdpCreate(mimac, 0x309 , 0x400, 0);printf ("sceNetAdhocPdpCreate= %i\n",pdpSd);
//----------------------------------------------------------------------

PARA RECIBIR:
Iniciando:
err=sceUtilityLoadNetModule(PSP_NET_MODULE_COMMON);printf("sceUtilityLoadNetModule(PSP_NET_MODULE_COMMON) %i\n",err);
err=sceUtilityLoadNetModule(PSP_NET_MODULE_ADHOC);printf("sceUtilityLoadNetModule(PSP_NET_MODULE_ADHOC) %i\n",err);
err = sceNetInit(0x20000, 0x20, 0x1000, 0x20, 0x1000);printf("sceNetInit %i\n",err);
err = sceNetAdhocInit();printf("sceNetAdhocInit %i\n",err);
err = sceNetAdhocctlInit(0x2000, 0x20, &product);printf("sceNetAdhocctlInit %i\n",err);
err = sceNetAdhocctlConnect(0);printf("sceNetAdhocctlConnect %i\n",err);
Recibiendo:
err = sceNetAdhocPdpRecv(pdpRd, mac2, 0,buffer,&length,0,1);printf("sceNetAdhocPdpRecv%x: \n", pdpRd);// 0,1 in lumines
//----------------------------------------------------------------------

Para enviar paquetes, ya envió bien.
El problema es ahora recibir.
De momento lo he puesto la psp1 (anfitriona) que envia y la psp2 (invitada) recibe.
Te cuento, a ver si me puedes orientar:

psp 1 (solo envia)
He puesto una psp (anfitrion) enviando paquetes continuamente a intervalos de 1 segundo, en un bucle a la direccion broadcast, y por el puerto 0x309. La psp envia paquetes continuamente y se ve como la luz parapadea cada segundo en cada envio.

psp 2 (solo recibe)
En la otra la he puesto a la escucha. La he puesto metida en un bucle, hasta que lea algo.
Dudas:

1) cuando pongo la funcion:
sceNetAdhocPdpRecv(pdpRd, mac2,0,buffer,&length,0,1)
-PdpRd es el id devuelto por sceNetAdhocPdpCreate. Me imagino que antes de recibir hay que usar al funcion sceNetAdhocPdpCreate y de ahi saca el id.
-mac2 al principio será la de broadcast, hasta que el anfitrion le envie la suya en el campo data y pueda saberla el cliente. (¿es asi?)
-este campo es el que me da problemas, solo me admite poner 0, si le pongo el mismo puerto que usa el anfitrion (0x309) me da error el compilador:
main.c: En la función ‘readpkg’:
main.c:225: aviso: el paso del argumento 3 de ‘sceNetAdhocPdpRecv’ crea un puntero desde un entero sin una conversión
-el campo buffer, me supongo que será lo que se lee
-el campo length, me supongo que será el tamaño de lo que se lee. o sea que si quiero leer solo los 4 bytes primeros pues pongo 4 y el buffer sera una cadena de caracteres (yo le puse buffer[200]);
- y los campos 6 y 7 puse 0, 1 (como los lummies)

2) Otra duda: ¿pueda que despues de la funcion:sceNetAdhocPdpRecv tenga que leer datos recibidos con la funcion: sceNetAdhocGetPdpStat?( bueno primero lo mas urgente que me devuelva 0 la funcion: sceNetAdhocPdpRecv)

3)de momento el recibir no me va, no sé si será porque para recibir solo puedo poner 0 en el campo puerto.


METODOS para establecer la conversacion(esto es lo que he pensado) orientame porfa.

A) el anfitrion enviará broadcast con datos determinados (el nombre del juego codificado). La psp invitada leera que esos datos es el mismo juego suyo. Entonces, la psp invitada enviará su mac por broadcast en el campo datos por el mismo puerto y el anfitrion podrá coger la mac. Luego el anfitrion enviará su mac en el campo datos a la direccion del invitado, y el invitado tomará esa direccion y asi ya "hablarán ellos solos".

B) Otro metodo sería que el anfitrion manda por broadcast el nombre del juego y su mac por el puerto (0x309). La psp invitada lee y si pertenece a su juego pues ya sabe la mac del anfitrion. Luego la psp invitada envia su mac anfitrion. El anfitrion lee la mac de la psp invitada y asi hablaran solas.

C) Otro metodo sería las 2 psp lanzan broadcast en el campo datos (el nombre del juego+mac) por el mismo puerto(0x309). A la vez que envian leen, cuando detecten el nombre del juego iguales tambien sabran las mac. Y asi cada uno tendrá la mac del otro y solo "hablaran entre ellas".

Ya creo que me falta poco, por favor ayuda.
(perodna mi pesadez)

Muhismas graciass.
Hola de nuevo,

A ver si consigo contestarte a todo.

edelpuerto escribió:psp 1 (solo envia)
He puesto una psp (anfitrion) enviando paquetes continuamente a intervalos de 1 segundo, en un bucle a la direccion broadcast, y por el puerto 0x309. La psp envia paquetes continuamente y se ve como la luz parapadea cada segundo en cada envio.

Aquí yo pondría un ordenador con un sniffer en el wireless para ver cuando habla cada PSP y debugear un poco la conexión.


edelpuerto escribió:psp 2 (solo recibe)
En la otra la he puesto a la escucha. La he puesto metida en un bucle, hasta que lea algo.
Dudas:

1) cuando pongo la funcion:
sceNetAdhocPdpRecv(pdpRd, mac2,0,buffer,&length,0,1)
-PdpRd es el id devuelto por sceNetAdhocPdpCreate. Me imagino que antes de recibir hay que usar al funcion sceNetAdhocPdpCreate y de ahi saca el id.

Exacto, sin PDP no hay "sitio" (descriptor) del que leer, así que necesitas crearlo antes de llamar a recv.


edelpuerto escribió:-mac2 al principio será la de broadcast, hasta que el anfitrion le envie la suya en el campo data y pueda saberla el cliente. (¿es asi?)

No, en este caso mac2 es un puntero de char en el que se va a almacenar la mac del dispositivo del que se ha recibido el paquete.

Seria como el puntero que le pasas a sceWlanGetEtherAddr(mimac), pero en este caso lo que se almacenara en mac2, sera la dirección mac de la PSP que ha enviado el paquete. La cabecera ethernet lo primero que contiene siempre es mac origen y mac destino.


edelpuerto escribió:-este campo es el que me da problemas, solo me admite poner 0, si le pongo el mismo puerto que usa el anfitrion (0x309) me da error el compilador:
main.c: En la función ‘readpkg’:
main.c:225: aviso: el paso del argumento 3 de ‘sceNetAdhocPdpRecv’ crea un puntero desde un entero sin una conversión

Es que aquí pasa algo parecido a la mac, no tienes que darle un dato definido, si no un puntero en el que al leer se va a almacenar el puerto origen desde el que recibió ese paquete para que cuando le respondas uses ese mismo.

Tu simplemente define:
unsigned short port;

Y le pasas el puntero &port a la función, cuando acabe el read, port contendrá el puerto origen desde el que se envío el paquete.


edelpuerto escribió:-el campo buffer, me supongo que será lo que se lee

Si exacto, ahí le pasas otro puntero de char que es cuando acabe de leer tendrás los datos leídos.


edelpuerto escribió:-el campo length, me supongo que será el tamaño de lo que se lee. o sea que si quiero leer solo los 4 bytes primeros pues pongo 4 y el buffer sera una cadena de caracteres (yo le puse buffer[200]);

Si exacto, pero eso indica el tamaño máximo que se va a leer de una vez, es decir que si recibes solo 4bytes, entonces solo leera 4 bytes aunque le hayas puesto 200 de length, es mas que nada para no desbordar el buffer.

Además normalmente no se sabe cuanto va a ocupar el paquete que vas a recibir ya que variara en base a la información que se este enviando, por lo tanto si en el buffer estas usando buffer[200], en length pon 200.



edelpuerto escribió:- y los campos 6 y 7 puse 0, 1 (como los lummies)

Si eso no esta documentado, puedes probar con 0, 1 o con 0, 0.


De todas formas si sabes ingles, aquí te dejo la descripción de los parámetros de sceNetAdhocPdpRecv según el include del PSPSDK:

/**
* Receive a PDP packet
*
* @param id - The ID of the PDP object, as returned by ::sceNetAdhocPdpCreate
* @param srcMacAddr - Buffer to hold the source mac address of the sender
* @param port - Buffer to hold the port number of he received data
* @param data - Data buffer
* @param dataLength - The length of the data buffer
* @param unk6 - Set to 0
* @param unk7 - Set to 0
*
* @return Number of bytes received, < 0 on error.
*/
int sceNetAdhocPdpRecv(int id, unsigned char *srcMacAddr, unsigned short *port, void *data, void *dataLength, int unk6, int unk7);




edelpuerto escribió:2) Otra duda: ¿pueda que despues de la funcion:sceNetAdhocPdpRecv tenga que leer datos recibidos con la funcion: sceNetAdhocGetPdpStat?( bueno primero lo mas urgente que me devuelva 0 la funcion: sceNetAdhocPdpRecv)

En este caso, devolverá 0 si no ha leído nada, que puede ser y no es malo, devolverá menor que cero en casos de error, y mayor de cero cuando lea algo, en este ultimo caso el valor devuelto positivo es el numero de bytes que ha leído, que como ya te dije antes no se sabe de antemano el tamaño del paquete que va a llegar, así que el valor retornado te indicara la cantidad de bytes leídos.


edelpuerto escribió:3)de momento el recibir no me va, no sé si será porque para recibir solo puedo poner 0 en el campo puerto.

Como te puse antes, no necesita un valor, si no un puntero donde almacenar el puerto origen desde el que se recibió el paquete.


edelpuerto escribió:METODOS para establecer la conversacion(esto es lo que he pensado) orientame porfa.

A) el anfitrion enviará broadcast con datos determinados (el nombre del juego codificado). La psp invitada leera que esos datos es el mismo juego suyo. Entonces, la psp invitada enviará su mac por broadcast en el campo datos por el mismo puerto y el anfitrion podrá coger la mac. Luego el anfitrion enviará su mac en el campo datos a la direccion del invitado, y el invitado tomará esa direccion y asi ya "hablarán ellos solos".

B) Otro metodo sería que el anfitrion manda por broadcast el nombre del juego y su mac por el puerto (0x309). La psp invitada lee y si pertenece a su juego pues ya sabe la mac del anfitrion. Luego la psp invitada envia su mac anfitrion. El anfitrion lee la mac de la psp invitada y asi hablaran solas.

C) Otro metodo sería las 2 psp lanzan broadcast en el campo datos (el nombre del juego+mac) por el mismo puerto(0x309). A la vez que envian leen, cuando detecten el nombre del juego iguales tambien sabran las mac. Y asi cada uno tendrá la mac del otro y solo "hablaran entre ellas".


Como ya te he comentado, el protocolo ethernet siempre incluye en la cabecera la mac origen y la mac destino, no hace falta que tu te preocupes de ello, una secuencia correcta podría ser la siguiente:

1.- El anfitrion enviará broadcast con datos determinados (el nombre del juego codificado).

2.- La PSP invitada lee el paquete y se apunta la mac, que obtiene del campo mac2 en la funcion sceNetAdhocPdpRecv que contiene la mac de la PSP anfitriona (la que mando el paquete)

3.- La PSP invitada manda un paquete a la mac y puerto obtenidos al hacer el sceNetAdhocPdpRecv, informando de que quiere unirse al juego.

4.- La PSP anfitriona se guarda la mac2 obtenida al hacer sceNetAdhocPdpRecv.

5.- Ambas PSPs conocen sus respectivas macs y el puerto de comunicación así que pueden inciar el juego.


A ver si con esto ya puedes empezar a pasarte las posiciones de los barcos :P
Buenas noches Turulox
MUchas gracias joder, me estas dando un master!!!
me pongo masnos a la obra.
Te mantendré informado.

Muchisimas graciass por todo.

casi toda la noche sin dormirr,
consegui leer!!!!!!
seguiré informandooo.
muchas graciassss, graciasss mill.
Enhorabuena, entonces ya solo te queda definir que mensajes y como se van a comunicar las PSPs. Sigue informándonos :)
Hola Turlox.
Joder que alegria.
Ya puedo transeferir lo que quiera de una psp a otra, jajaj.
Bueno, me centro para el juego.
De momento, tengo varias digamos fases en el juego.
Fases:
1.- Cargar partidas o una nueva. (se pueden tener hasta cinco partidas)
2.- Colocar los barcos, cada cual en su psp.
3.- establecer el enlace entre una psp y la otra.
para ello, se entra en una pantalla, donde una psp tiene que elegir que es el anfitrion y la otra psp es el invitado.
El anfitrion envia broadcast con el nombre del juego (codificado), y a su vez "escucha".
El invitado capta el mensaje y coge la mac.
El invitado le envia directamente a la mac del anfitrion que se quiere unir.
El anfitrion recibe del invitado que se quiere unir. Y le pilla su mac.

4.- Se abre una pantalla para lanzar disparos unos a otros. El anfitrion comienza (mientras el visitante tiene descativado el disparo.
El anfitrion elige el cuadro donde quiere disparar y pulsa la x. se envia un mensaje al invitado con las coordenadas. el invitado le envia si es tocado o agua.
Si es agua...

asi sucesivamente...

Y.....todo graciass a tiiiii.
ya que te tengo, te comento 2 dudas
A ver si me explico bien.

1) Si yo lanzo broadcast desde una psp, ella misma no recibe sus mismos broadcast?

2) Pongamos psp1 y psp2. Si la psp1 lanza un mensaje a la mac de la psp2 y la psp2 no esta continuamente escuchando,¿ este mensaje se queda almacenado en el PDP(descriptor) y cuando se le da la orden sceNetAdhocPdpRecv es cuando la psp2"saca" el mensaje del desriptor?

3) cada vez que se envie o reciba, se necesita crear un PDP(descriptor) con sceNetAdhocPdpCreate?

curiosidades:
Puse el tropix con airmon para "monitorizar" la "conversacion de las 2 psp. la curiosidad es que la psp primera que abre la conexion crea un punto de acceso digamos virtual por la que las demas se comunican. y ademas a ese "punto de acceso virutual" cada vez cambia la direccion mac, en cada conexion nueva y tambien le da un nombre a la red: PSP_AULUSP99999_L_

Ahora me quede terminar de lanzar "bombas" y maquillar las imagenes y el diseño( que coneso es lo mas tiempo se pierde).
cuando este "funcional" lo mismo, pongo una beta.

Seguiré informando. Gracias amigoo.
edelpuerto escribió:1) Si yo lanzo broadcast desde una psp, ella misma no recibe sus mismos broadcast?


Aunque vaya a broadcast el paquete lleva como mac origen la tuya, así que tu PSP no lo leerá, o al menos no debería, aunque todo depende siempre de la implementacion que haya echo el sistema, en este caso el de la psp hecho por sony.

edelpuerto escribió:2) Pongamos psp1 y psp2. Si la psp1 lanza un mensaje a la mac de la psp2 y la psp2 no esta continuamente escuchando,¿ este mensaje se queda almacenado en el PDP(descriptor) y cuando se le da la orden sceNetAdhocPdpRecv es cuando la psp2"saca" el mensaje del desriptor?


En principio si, hay un buffer de entrada que tendrá un limite, aunque no he trabajado con las funciones de adhoc de la psp, en un socket normal aunque tu no lo éstes leyendo si llega algo se almacena en el buffer hasta que lo leas.

edelpuerto escribió:3) cada vez que se envie o reciba, se necesita crear un PDP(descriptor) con sceNetAdhocPdpCreate?


Lo suyo es que dejes el PDP creado, para que no tengas que andar abriéndolo y cerrándolo, lo defines como global o lo que veas y fuera.


edelpuerto escribió:curiosidades:
Puse el tropix con airmon para "monitorizar" la "conversacion de las 2 psp. la curiosidad es que la psp primera que abre la conexion crea un punto de acceso digamos virtual por la que las demas se comunican. y ademas a ese "punto de acceso virutual" cada vez cambia la direccion mac, en cada conexion nueva y tambien le da un nombre a la red: PSP_AULUSP99999_L_


Como cualquier conexión adhoc usara un essid para identificar la red, pero no es un punto de acceso, ese essid se crea en base al id del juego, cada uno tiene el suyo como sabrás que utilizan en los savegames, etc.. Por ejemplo el id del tony hawks PAL es ULES00033, seguro que podrás asignarle tu propio ID, pero vamos no es necesario. De la mac, algo había leído en el foro de ps2dev, aunque no me fije mucho, a saber si es cosa de sony o de la implementacion que hace el PSPSDK del modo adhoc.

edelpuerto escribió:Ahora me quede terminar de lanzar "bombas" y maquillar las imagenes y el diseño( que coneso es lo mas tiempo se pierde).
cuando este "funcional" lo mismo, pongo una beta.

Seguiré informando. Gracias amigoo.


Esperamos esa beta con ansia :)
Holaa. Muchas gracias por tu información.
Con esa explicación ya se me asentaron las ideas.
Ya tengo clarito las comunicaciones adhoc.

bueno, ya funcionaaa.
Ya se puede jugarrr.
Tiene algunos fallos que estoy corrigiendo.
Y tambien quiero implementarle "timer" en vez de bucles.

El diseño que tengo es "pensoso", pero bueno eso con tiempo.
Tambien voy a mirar lo de los menus (he visto un post) que tengo menu caseros mios y lo pondré mas llamativos.

te mantendré informado.
Muchas gracias de corazon.
El otro dia me puse a rehacer un codigo que perdi y me puse con iniciar el wifi en modo usuario pero claro el PSPLINK se ejecuta en modo kernel y desde hay si ejecutas el codigo te da error alguien sabe como salvar ese atranco ? es que si hay que ir conectando y desconectando la psp igual me dan las uvas :)
Yo no tuve ningun problema. Yo uso el psplink v3.0. y no me daba error, podia probar sin problemas los modulos de prueba.
Todo ello compilando para 3.71.

No se si me he explicado bien.

Nota.- A decirte la verdad, aun no tengo claro lo que es modo kernel y modo usuario.

(soy un novato con interés).
eldelpuerto Me puedes decir de donde te has bajado ese psplink ¿? esque yo me fui a http://www.pspdev.org para bajarmelo pero es la 2.0 y la 3.0 no se por donde anda
Este es el modulo para la psp:

Adjuntos

Joder que perdido estoy ... como se lanza este psplink ? lo hice metiendolo en game150 para lanzarlo normal y no me lo pillaba el usbhost_pc o el pcterm , despues puse la carpeta en SEplugins y cargue el psplin_user.prx pero no me tira tampoco :/ si me dices como funciona te lo agradezco
para arrancarlo, tienes que tenerlo en modo 3.71 (en el recovery modo 3.71).
Tienes que copiarlo dentro de GAME a secas.

No tienes que arrancar ningun .prx

¿Que usas windows con cgwyn o linux? ¿o usas windows con Vs?
Yo uso GNU/Linux la distro Ubuntu 7.10 y bueno haciendolo asi el pcterm me tira raro :
Opening connection to localhost port 10000
�0x00000000�
�host0:/�./project1.elf
esta como colgado y no responde a ninguna orden , sera que con 3.52 M33 no tira, asi que me tocara actualizar ya depaso sabeis si en la 3.90 M33 tira el psplink 3.0 oe ¿
descargate el psplinkusb de aqui:

http://satyriko.blogspot.com/2007/06/psplinkusb-linux-ver-la-psp-en-la.html

Para hacer lo que quieres, no hace falta que carges ningun .prx
(los .prx es para ver la psp en la pantalla)

Una vez instalado, abres psplinkub 3.0 en tu psp

abres dos consolas (o dos pestañas de consola)

1.consola) sudo /.........../usbhostfs_pc/usbhostfs_pc

2.consola) sudo /.........../pspsh/pspsh

y ya debería estar.

Nota.- a mi me funciona con la version de customfirmware 3.71 m33

Un saludo.
Con eso tenia el problema eso son una aplicacion para el remotejoy ( tambien decir que el link esta caducado parece ser ) ahora mismo voy a dejar un manual de como se usa el psplink 3.0 oe para la gente que tenga problemas y la poca info que hai
te dije que asi funcionaba, que los prx son para el remotejoy.

Nota.- ...de nada.

Para el moderador: Este hilo se puede cerrar.
ya tio te entendí :) simplemente decia que solo era lo necesario para el remotejoy ya puse un hilo explicando como bajar el psplink completo.
Gracias.
23 respuestas