RSS Contact

miércoles, 30 de diciembre de 2009

1 comentarios

Habemus Telecompring

Pues ahora si que parece que esto se acaba.

Finalmente conseguí resolver el problema del refresco del navegador. Inicialmente creí que se producía por una cuestión de tiempos, ya que al depurar el programa paso a paso si que refrescaba, así que me pasé días probando diferentes tiempos de espera, incluso con Timers y la cosa no avanzaba. Incluso cambié las opciones del comando proactivo para ver si así se solucionaba..

Por fin caí: ¿Y no será que lo que devuelve está en caché? BINGO.

Cada vez que mando el comando LAUNCH_BROWSER, le indico como url /ShopServlet?P=D. Por lo visto, si hago esto mismo pero en código html, {a link="/ShopServlet?P=D"} , si que había refresco, pero cuando se trata de comandos proactivos parece que devuelve de caché.

La solución ha sido crear un byte que se incremente cada vez que necesito mandar este comando para añadirselo al final de la petición y así interpretar que son dos peticiones distintas. Es decir:

Petición número 1: /ShopServlet?P=D1
Petición número 2: /ShopServlet?P=D2
.
.
.

Y así...

Cuando llega al caracter 127 se resetea y vuelve al 1. Y la pregunta es, ¿Si vuelvo a hacer la petición número 1 pasados días, devolverá de caché? Espero que no, sino tendré que seguir metiendo bytes de cola hasta un número razonable de ejecuciones...

Un ligero cambio en el servlet ha sido completar la información de número de tarjeta a ceros si el cliente decide no guardarla.

Recepción

En esta parte ha habido bastantes cambios y mejoras. Con respecto a la interfaz swing, al final he añadido de nuevo la funcionalidad 'editar producto' pues vi que no iba a ser muy complicado.


Lleva bastante control de errores ya que hay que hacer operaciones matemáticas (Se controla que lo que se mete es un número y un número válido)

También hay control sobre la tabla: No permite determinadas opciones si no has seleccionado una fila de la tabla, y qué fila, ya que la penúltima es de relleno y la última se utiliza para ver el total de la compra



Por último, la funcionalidad 'guardar pedido' crea un fichero de extensión xls de mismo nombre que el fichero xml con el que se cargaron los datos pero ubicado en ../orders

En él se guarda la información que vemos en la tabla swing: Datos personales y lista de la compra. Supuestamente, si se guardan líneas separadas por comas en el fichero, un programa de procesamiento como excel debería interpretar que cada cadena entre comas va en una celda diferente. De momento no he podido visualizarlo en condiciones en excel. Así que he recurrido a descargar OpenOffice.. :)

Y el resultado es este: Si se ha guardado correctamente el pedido se abrirá OpenOffice mostrandolo.


Los sombreados de las tablas son manuales. Habrá manera de que sea automático? Usando plantillas o algo así?

sábado, 26 de diciembre de 2009

0 comentarios

Cambios y arreglos I

Me complace pensar que 'casi' está. Un profesor nos dijo una vez que abusabamos de la palabra 'casi' porque luego 'nunca' estaba. Y tenía razón. Siempre hay algo que lo retrasa.
Hay días que parece que los astros se han alineado para fastidiarte exclusivamente a tí..

Aquí van una serie de arregos y/o modificaciones que cambié ayer:

1. Lanzar navegador con un html que indique que se ha recibido el pedido:

Esta acción se realizaba (en versiones anteriores del Developer Suite) desde el applet Transfer. Por más que he cambiado el código de lugar, ya que en esta versión parece ser que solo se pueden enviar comandos proactivos desde el método processToolkit, ha sido imposible lanzar el navegador con una página de contenido estático (recibido.html) así que finalmente he pasado de ello y no se mostrará nada.

2. Guardar perfil

Daba errores al guardar mucha información. Al hacer la petición post los datos llegan en un array de bytes llamado temporaryBuffer que únicamente tenía un tamaño de 100 bytes. El error se ha solucionado incrementando este valor.

3. Applet Transfer

Inicialmente se declaró como STK + SCWS + NFC (card emulation mode) pero más adelante se vio que no era necesario que fuera SCWS. Así que he modificado el GDP y he declarado los métodos necesarios para que sea STK + NFC.
No se me ha fastidiado el proyecto como viene siendo habitual. De hecho, funciona también sobre la tarjeta :)

4. Controlar valores numéricos en la información de perfil

Si el usuario guarda en los campos 'Telephone', 'Card' o 'Id' algo que no sea numérico se lanza una página html (errorPerfil.html) pidiendo que lo intente de nuevo. Si se dejan pasar valores no numéricos, más adelante habrá problemas en el lector.

5. Problema con la página noprods.html

En simulación le costaba cargarla, y en tarjeta ni lo reconocía. Era que estaba añadiendo la CABECERA a la respuesta y luego estaba redireccionando a noprods.html

6. CSS

Se reduce el tamaño de la hoja de estilo al haber capas que finalmente no se utilizan. Capas como content y navigation.

7. Diseño html + css

Revisadas páginas 'dinámicas' acorde al css: Subtotal, mostrar perfil, editar producto, mostrar datos leídos.

8. Controlar valores numéricos al editar un producto

Si en cantidad se introduce un valor no numérico se lanzará la página errornum2.html informando de esto.

9. Prueba en tarjeta

Se crean dos productos al pulsar nueva compra y se comprueba que aparecen en la pestaña 'cart'. Las funcionalidades de editar y borrar producto van correctamente, pero no aparecen los nombres de las columnas de la tabla en el navegador del Sagem. Qué novedad.

Tareas futuras

Meter el dichoso Timer a ver si se solventa por fin el error del refresco del navegador
Rediseñar la tabla de la pestaña cart
Diseño en general de las páginas dinámicas
Probar a rellenar los campos ID, nombre, precio y medida y hacer una petición a /ShopServlet?P=D para ver si lo muestra todo correctamente.
Nuevas páginas para controlar errores numéricos -> adaptarlas para real card.

lunes, 21 de diciembre de 2009

0 comentarios

Integración vol. I

Hoy ha sido una mañana muy productiva, y es que si quitamos los 'N' minutos del café, los 'M' momentos de parloteo y demás interrupciones, las cosas avanzan a mayor ritmo.

En una primera prueba de todo el sistema montado (todas las clases y demás) parecía que la comunicación entre la parte lectora y la escritora era imposible. Tras depurar, me percaté de un error de declaración. Y es que acostumbrarse a utilizar el tipo byte no es bueno, sobre todo cuando lo que quieres meter dentro es algo superior al valor 128... Viva.

Al 'traducir' al inglés todo, olvidé cambiar una pequeña comprobación la cual ha sido fácil de detectar. En español, el tipo de pago es Efectivo o Tarjeta. En un punto del programa identifico cuál de las dos opciones está pulsando el usuario con una simple comprobación de la primera letra de la palabra que entra, en este caso, 'E', o 'T'. Pues bien, en inglés, esto se ha traducido como Cash y Card, y como ambas iniciales son las mismas, el comportamiento no era el esperado. La solución ha sido chequear la tercera letra de la palabra, 's' en Cash, y 'r' en Card. Así de simple.

Sigo con el mismo problema del refresco del navegador. Sí, durante dos días no tuve problemas y ahora vuleta a lo mismo. Creo que cambiando el número de vueltas del for que controla la espera entre una ejecución y otra se puede burlar este efecto. El problema va a ser enfrentarse a esto en la tarjeta real...

Se ha modificado el comportamiento a la hora de pulsar 'pagar'. Ahora, aunque el cliente haya pagado, se puede volver atrás pulsando en un enlace (add more products) que reactivará el lector NFC y cargará la última compra. A partir de aquí se pueden seguir leyendo etiquetas.

Con este sistema he ido pagando e introduciendo cada vez un producto más, y con una lista de hasta 6 productos no he tenido problemas para volcar los datos. Sin embargo, el incluir uno más ha ocasionado problemas en la comunicación. Concretamente, todos los datos los envía, pero en la última trama el pc debería cerrar la comunicación (ya que está recibiendo el caracter '%') y no lo hace. No tengo claro que esto sea por el volumen de datos enviado, seguramente será porque el simulador ha empezado a hacer de las suyas, pero esto ya lo comprobaré mañana.

En un principio, la integración está hecha, salvo pequeños detalles que aunque en una presentación se puede 'engañar' al espectador, hay que arreglar.

Al ver que se podía probar todo el sistema de inicio a fin, he querido volcarlo en la tarjeta. Tengo en mi poder 5 de las 10 tarjetas que me enviaron para el SIMagine. Así que he cogido la tarjeta identificada como 'B' y al ver que no tenía nada dentro he cargado el paquete Utility. Mal. Me ha ocasionado un 6982, o un código similar que no recuerdo que significa error de seguridad. Estupendo.

Para la versión de simulación (no se por qué lo hice aquí) creé el applet lector (ShopServlet) con un AID específico, ya que en el wizard me lo indicaba así si quería que funcionase en una tarjeta real. Como el applet escritor (Transfer) se encuentra en el mismo paquete que el anterior, el AID debe ser igual en los N primeros bytes y distintos en los 2 últimos (?). El cambiar los identificadores directamente en el descriptor (gdp) es una guerra perdida. Por mucho que los cambies a mano, saltará un error en este fichero dificilmente de arreglar. Por eso lo más sencillo es crearse un nuevo proyecto. He vuelto a llamarlo Telecompring a secas (ya tenía las versiones de la 2 a la 5...)

Por último, he probado (a lo tonto) a meter una de las tarjetas que aún no había usado (tarjeta 'C') y he cargado el paquete Utility. Perfecto, 90 00.
Siguiente paso, cargar e instalar applets del proyecto Telecompring. También 90 00. No me lo podía creer. Miro el fichero cap y únicamente pesa 33Kb. ¿Qué está pasando? ¿Apenas he borrado código y he bajado 10Kb? ¡Si encima tengo un bucle recorriendo un entero! No importa, es genial.
Mapeo los servlets, cargo el static content, y entonces caigo. Ouch! Mi contenido estático está hecho para simulación! Es decir, el css es externo y para que funcione sobre tarjeta hay que incrustarlo en las páginas web a mostrar.

Lo veo tedioso, seguiré mañana.

jueves, 17 de diciembre de 2009

0 comentarios

Launch Browser

Resulta que en simulación (y es posible que sobre tarjeta) si queremos enviar en repetidas ocasiones el comando lauch browser (lanzar navedgador) se necesita hacer una espera entre cada comando.

A esta conclusión se llegó probando la parte lectora, la cual lanza el navegador con los datos leídos. En simulación el navegador no se lanzaba o el terminal se quedaba colgado, pero en depuración y operando instrucción a instrucción, esto no pasaba.

Cuando ocurren cosas así, todo indica que estamos ante un problema de tiempos. Posiblemente algo que no le da tiempo a refrescar, pero, dónde?

Al observar paso a paso la ejecución en el método process() se podía ver que en mitad del mismo, se saltaba al método processToolkit() al ocurrir evento Proactive_handler_available. Esto era un poco extraño, ya que en ningún momento se estaba registrando dicho evento, por lo que se hicieron los siguientes cambios:

1. Registrar el evento cuando se acaben de recibir todos los datos de la etiqueta. (El developer lo resgistraba cada vez que pasabamos por el método process())
2. Crear una variable booleana para identificar en el escuchador cuándo se quiere lanzar el navegador realmente.
3. Poner esperas entre cada envío de comando.

Se hicieron varias pruebas con diferentes valores y lugares donde poner la espera, y finalmente la mejor forma (o al menos la que funciona) es dejarlo en el processToolkit() y en este lugar:

for(int i = 0; i< 1000000000; i++) {}
proHdlr = ProactiveHandlerSystem.getTheHandler();
proHdlr.init( PRO_CMD_LAUNCH_BROWSER , (byte) 0, DEV_ID_TERMINAL);
proHdlr.appendArray(temporaryBuffer, (short) 0, (short) (2+urlDatos.length));
proHdlr.send();
clearBuffer();
reg.clearEvent((byte) EVENT_PROACTIVE_HANDLER_AVAILABLE);

Sí, la espera es un for de muchas vueltas. En simulación esta clase de cosas se pueden hacer, nadie las va a ver. Pero si realmente hace falta esta espera en la tarjeta, y todo indica que sí, habría que meterse con timers, lo que incrementará el tamaño del proyecto...

PD: Sigo esperando mis etiquetas de TID..

martes, 15 de diciembre de 2009

0 comentarios

Nuevas Pantallas

Y este es el aspecto del nuevo Telecompring: En azul, y en inglés (bueno, en MI inglés..)

Spanglish...






viernes, 4 de diciembre de 2009

1 comentarios

¡ Ahora sí !

Ahora si que si. El lector recibe correctamente los datos desde el terminal.
Tras varias horas de depuracion, llegué al fallo. Una simple confusión entre el caracter 'F' y el byte 0xF. Ya me vale.

En esta captura se ve el intercambio de tramas con la estructura descrita en el post anterior:
1. El lector (tramas de color rosas) envía el AID del applet
2. El applet (tramas de color azul) responde con un código de estado 90 00 (Conclusión satisfactoria)
3. El lector pide datos con el comando 00 70 00 00.
4. El applet envía un primer bloque que representa el número de registros de datos que va a enviar, que en este caso son 0x31 (caracter 1) + el código de estado 90 00
5. El lector pide siguiente dato (Primer y último bloque de datos)
6. El applet envía los datos (Trama más grande, de 249 bytes) + Código de estado 90 00
7. El lector pide el último dato, que será el DNI del cliente
8. El applet responde con el DNI.
9. El lector vuelve a pedir datos.
10. El applet ya no tiene datos para enviar y le responde con el caracter '%'
11. El lector interpreta que ya no hay más datos a enviar y cierra la comunicación.

Con el DNI de cliente y la fecha y hora del sistema actual (que por motivos desconocidos, diciembre le pone el mes número 11) , se genera un fichero xml que será procesado por el sistema receptor para dar lugar a un interfaz swing que permitirá manejar esta información a la persona encargada de este sistema (editar, borrar, guardar en la base de datos...)


Los datos que se mostrarán en esta interfaz swing son los datos personales del cliente, fotografía (opcional, en caso de no tener foto de cliente se mostrará una genérica) y la lista de la compra, que en este caso, ya que he tenido que introducir los datos manualmente, solo hay un producto.


Todo esto funciona en la tarjeta etiquetada como 'A'. He probado en la tarjeta B a cargar un html con css externo y no es posible visualizarlo correctamente como ya me sucedía con otras tarjetas.

Futura sesión: He intentado lanzar el navegador desde el servlet Transfer tanto dentro del método process como creando un método aparte e invocandolo desde el mismo.

byte[] temp1 = new byte[(short)(url1.length + 2)];
temp1[0] = (byte) 0x31;
temp1[1] = (byte)url1.length;
Util.arrayCopy(url1, (short)0, temp1, (short)2, (short) url1.length);
ProactiveHandler proHdlr2 = ProactiveHandlerSystem.getTheHandler(); //No lo coge
proHdlr2.init( PRO_CMD_LAUNCH_BROWSER , (byte) 0, DEV_ID_TERMINAL);
proHdlr2.appendArray(temp1, (short) 0, (short) (2+url1.length));
proHdlr2.send();
Este código ya lo he probado con el proyecto de TID y funciona, pero me temo que es porque no está dentro del método processToolkit, así que tendré que pensar como apañarmelas para lanzarlo de otra manera, si es que existe. Sino habrá que hacer una guarrería del tipo 'pongo enlace que redirija a la página cuando se pulse continuar...'

Además, tengo que hacer lo posible por reducir código ya que el usar el sistema de ficheros me incrementa el tamaño del fichero .cap de forma considerable. Creo que reharé un poco el css para las páginas que no son estáticas, o como última medida, reducir la funcionalidad del sistema.

Y ahora, de puente :)

jueves, 3 de diciembre de 2009

0 comentarios

¿Funciona?

Como ya sabía, de la simulación a la tarjeta real hay un mundo. Y eso es lo que ha protagonizado la sesión de hoy.

Tras comprobar ayer que el lector funciona con las nuevas tarjetas, me dispongo a probar sobre las mismas. Para ello he utilizado el código de acceso a registros que había comentado para poder reducir el tamaño del fichero .cap, que dependiendo del mismo, se podrá o no importar un proyecto en una tarjeta.

Desde el servlet Lector, se escriben los datos a enviar en el fichero de identificador 0x4F99, que es un fichero con estructura de registros (130 registros de 250 bytes/registro). La creación de este fichero, se ha logrado (o eso parece) con un script de extensión ATF debidamente lanzado desde la aplicación JCardManager. Aunque los comandos de creación y/o acceso no devolvían 90 00, según el File System Editor probado sobre la tarjeta, sí están creados.

Puesto que los registros están disponibles, he querido probar el sistema declarando manualmente un fichero xml con las etiquetas necesarias para que el receptor pueda hacer las operaciones pertinentes con los datos. Si una operación de acceso, lectura o escritura fallase, saltaría una excepción y se lanzaría en el navegador una página que indique que un error ha sucedido.

Escritura: Se ha escrito en 3 ficheros. En el primero se indica el número de registros que se han utilizado para datos. En este ejemplo, como los datos tienen un tamaño de 250 bytes, únicamente se ha utilizado un registro para datos. En el segundo, irán los datos. Y en el último el DNI del usuario.

Lo comentado anteriormente sigue la siguiente estructura:

----------------------------------------------
| Nº regs datos | D1 | D2 | ............. | Dn | DNI |
----------------------------------------------

El motivo de incluir el DNI del usuario, es para que el sistema final tenga un identificador único con el que guardar el pedido del cliente. Este identificador único se compone del DNI y de la fecha y hora actual del sistema.

Volviendo a las pruebas, el servlet encargado de grabar los datos en los 3 registros del fichero 0x49FF no presenta ninguna anomalía. No salta ninguna excepción y la ejecución sigue con normalidad.

Al conectar el lector y darle a start, se ve que el applet responde a la selección de su AID pero al pedirle datos (que debería obtener del fichero) se obtiene un código de respuesta de 6F 00.
Normalmente esto ocurre cuando no se están enviando bien los datos de vuelta. No he podido hoy mirar si realmente está leyendo bien de fichero (no se puede depurar una vez está en la tarjeta, ni existen los println) o es algo más grave e irreconocible. Así que será la tarea a resolver mañana.


El SIMagine se acerca, y yo con estos pelos :/