Sunteți pe pagina 1din 125

- 1 -

- 2 -








Casa abierta al tiempo es la frase que adoptada como lema institucional, expresa con profundo
sentido la visin y el espritu del proyecto acadmico de la Universidad Autnoma Metropolitana.

Convertida la frase el lema, apunta a los propsitos de la Universidad, que es Casa abierta al
tiempo portador de sentido, posibilidad de saber y de dilogo.






- 3 -




SICOTIP: Sistema de comunicacin para aplicaciones distribuidas
(IG's) Cliente con comunicacin a un MainFrame-Host.

Resumen.

El presente trabajo describe la propuesta de desarrollo del sistema de comunicacin con
sockets TCP-IP, entre un sistema distribuido y un equipo central (Mainframe). Se pretende que el
proyecto a desarrollar pueda usarse en alguna empresa financiera, donde los sistemas pequeos
tienen la necesidad de comunicarse con el equipo central o Mainframe.

El tipo de sistema distribuido al cual nos enfocaremos, sern los llamados Call Center, as como los
equipos automticos de audio y respuesta los llamados IVRs. Estos son usados para la atencin
telefnica de clientes de una empresa bancaria. Este tipo de sistemas que tambin tiene la
necesidad de interactuar informacin con el equipo central, pero con la caracterstica adicional que
el tpo de respuesta es un tema crtico, por lo que debe de ser rpido.

El mainframe es el encargado de almacenar y centralizar toda la informacin de la cartera de
clientes, en este tipo de empresas. Los equipos pequeos son los puntos donde se inician las
solicitudes o requerimientos de operaciones bancarias o de servicio, que necesitan los clientes, y
estos equipos retransmiten, informan o solicitan la peticin al equipo central.

Con el desarrollo, se pretende mejorar los tiempos de respuesta que se tiene en la comunicacin
entre los equipos pequeos (Call Centers e IVRs). Donde se ha encontrado que muchas empresas
bancarias manejan protocolos de comunicacin ms lentos y arcaicos. Un ejemplo muy claro es el
uso de sesiones de SNA, en el cual se necesitaba crear un GUI la cual interactuaba a una sesin
de SNA creando una emulacin 3270 y internamente la aplicacin GUI enviaba comandos a la
sesin, tal como si se interaccionaba directamente sobre la emulacin. Por lo que la GUI solo
servio para visualizar la informacin de manera grafica, a este proceso se de denomina screen
scraping. Este proceso de programacin es muy lento y poco practico, debido a que se tiene
realizar doble desarrollo, uno en la aplicacin distribuida, as como su contraparte en el sistema
central, para la creacin de las pantallas que proporcionen la informacin.

Se pretende que el desarrollo tenga como beneficios: disminuir considerablemente el tiempo que
tarda una llamada que realizan los clientes al Banco, por lo que esto se traducir en disminuir
costos; aumento de la satisfaccin del cliente, as como mejorar la atencin del cliente; al contar
con una comunicacin mas rpida, da la oportunidad de ofrecerle mas productos y servicios a los
clientes, los cuales usan el telfono como medio de interaccin con la empresa bancaria.

Otro aspecto a considerar, es cuando el banco realiza la subcontratacin de empresas
(Outsourcing) de servicio de call centers, para que proporcionen parte del servicio de atencin
telefnica. Por lo que parte de la propuesta, en el sistema a construir, es que incluya un servidor
Proxy. El cual servir de entidad intermediaria de conexin entre alguna empresa extrna y la
empresa bancaria, la cual contrata sus servicios.

Tambin, se considera que el sistema cuente con un mdulo de encripcin. Donde se propone que
este mdulo sea implementado en el estndar TDES, con el objetivo de encriptar los datos
sensibles del mensaje que viaje entre la entidad externa y el banco, garantizando la

- 4 -
confidencialidad de la informacin del los clientes. Este mdulo ser configurable para poderse
usar o no, en base a las necesidades del negocio.

El sistema a desarrollar constara de dos componentes principales, el mdulo cliente y el mdulo
servidor TCP-Proxy, los cuales estn fundamentados en el manejo sockets TCP del protocolo TCP-
IP, garantizando un mejor enlace.

La construccin del proyecto estar basado en C++, para garantizar mayor performance, as
tambin nos permita poder tener la capacidad de realizar balanceo de cargas y tener la capacidad
de transportabilidad en otras plataformas.

Es entonces, que el mdulo cliente permitir el envo y recepcin de mensajes en formato PS9
(protocolo lgico de informacin estndar para comunicacin con el MainFrame), dando la
posibilidad de usar o no encripcin.

La parte del modulo de servidor TCP-Proxy, tendr como funcin la retransmisin de mensajes que
reciba del modulo cliente, para las empresas externas de call center. Este componente, contar
con la habilidad de ser multitarea (multithread), tambin se pretende que maneje la programacin
paralela y poder aprovechar la infraestructura del servidor o equipo que lo aloje, ms si cuenta con
procesadores multicore y/o multiprocesador.



















- 5 -





Agradecimientos.
Doy gracias a mis padres, por el apoyo incondicional que siempre me han dado y por que siempre
creyeron en m.
Rodolfo Rosas Rico y Lucia Daz Herrera.
Mi sincero agradecimiento hacia mis hermanos: Maria, Sergio, Rodolfo y Vernica.
Por su apoyo y motivacin en mis estudios.
Agradezco el gran apoyo del Maestro Omar Lucio Cabrera como mi asesor
de proyecto.
Mi reconocimiento y agradecimiento a la Universidad Autnoma Metropolitana, por ser la
institucin de excelencia para la formacin de profesionistas e investigadores de excelencia y de la
cual estoy orgulloso de haber egresado.

Dedicatoria;
Dedico la presente obra a mi hermosa familia: mi esposa Celia, a mi nenita Lilian y al bebe
que estamos esperando.




- 6 -



Contenido
1 Introduccin.
2 Sistemas de Atencin Telefnica.
2.1 Introduccin.
2.2 Arquitectura base. PBX, IVR's y CTI.
3 MainFrame (Host).
3.1 Introduccin.
3.2 Arquitectura sobre Host MainFrame.
3.3 Cics Bridge TCP-IP.
3.4 Protocolo PS-9.
4 Programacin concurrente y paralela.
4.1 Introduccin.
4.2 Programacin Multihilo.
4.3 Modelos y herramientas de programacin paralela.
4.4 Modelo y herramientas usados en el proyecto.
5 Criptografa.
5.1 Introduccin
5.2 TDES y base 64, para el manejado en el proyecto.
6 Sistema de comunicacin TCP-IP para aplicaciones cliente a Mainframe-Host (SICOTIP).
6.1 Requerimientos.
6.2 Anlisis.
6.3 Diseo.
6.4 Construccin.
6.5 Conclusiones y resultados.
7 Referencias
Anexo A. Cdigo fuente.

- 7 -


SICOTIP: Sistema de comunicacin para aplicaciones distribuidas
(IG's) Cliente con comunicacin a un MainFrame-Host.


1 Introduccin.


El presente trabajo describe el desarrollo para la solucin de comunicacin de aplicaciones
distribuidas de atencin telefnica en la industria bancaria por sockets de TCP-IP, hacia el sistema
central (Host OS-390). Esto en base la necesidad de contar de un medio de transmisin seguro de
informacin y as como un medio mucho ms rpido en tiempo de respuesta. Con el objeto de
minimizar el tiempo de las llamadas que realiza los clientes al servicio de atencin telefnica. Este
servicio se proporciona con infraestructura de equipos de audio-respuesta automtico IVR's y/o
atencin por asesores llamados Call Centers.

Muchas empresas que ofrecen de estos servicios, para no invertir en infraestructura de este tipo, o
tener que mejorarla constantemente. Recurren en la subcontratacin de empresas externas
(llamadas Outsourcing), las cuales dan el servicio de call centers. Con esto las empresas
outsourcing pueden proporcionar parte o todo del servicio de atencin telefnica a nombre del la
empresa que contrata.
Para que la empresa financiera pueda operar de manera adecuada con estas empresas se
propone como parte de la solucin el manejo de un Proxy (intermediario o sustituto), vindose para
el banco como un solo punto o nodo, el cual por razones de seguridad ser solo uno punto a
autorizado por el firewall del banco. Esta configuracin permitir que N cantidad de maquinas
cliente se comuniquen con el Proxy y este retransmita el mensaje de manera segura al Banco y
retorne la respuesta al nodo cliente que realizo la peticin original.

Tambin, se contara con un modulo de encripcin en TDES (estndar en muchas de estas
empresas) para encriptar los datos sensibles del mensaje, el cual ser configurable para usarse o
no, en base a las necesidades del negocio.

El sistema desarrollado consta de dos componentes principales, el modulo cliente y el modulo
servidor TCP-Proxy basados en manejo sockets TCP de TCP-IP garantizando un mejor enlace.
Todo el desarrollo se construyo en C++ para garantizar mayor performance, balanceo de cargas y
transportabilidad en diferentes plataformas.

Por lo que, el modulo cliente permitir el envo-recepcin de mensajes en formato PS9 (protocolo
lgico de informacin estndar para comunicacin con el MainFrame) con y sin encripcin.

La parte de mdulo de servidor Proxy TCP, tendr como funcin la de retransmitir los mensajes
que reciba de la aplicacin cliente que provengan de empresas externas que den el servicio de Call
Center. En donde este componente tendr la capacidad de ser multihilo (multithread), as como
ampliando la capacidad de usar las ventajas de la programacin en paralelo. Pudiendo explotar las
ventajas de contar con un servidor que tenga una arquitectura de procesadores multicore y/o
multiprocesador.

Es entonces que el mdulo cliente permitir el envo-recepcin de mensajes en formato PS9
(protocolo lgico de informacin estndar para comunicacin con el MainFrame) con y sin
encripcin.


- 8 -
La parte del modulo de servidor TCP-Proxy, tendr como funcin la retransmisin de mensajes que
reciba del mdulo cliente, para las empresas externas de call center. Este componente contara con
la habilidad de ser multitarea (multithread), as como la posibilidad de usar programacin paralela,
teniendo la posibilidad de aprovechar la existencia de algn servidor con procesadores multicore
y/o multiprocesador.



2 Sistemas de Atencin Telefnica.

2.1 Introduccin.


En cualquier institucin financiera o Banco, es comn que se cuente diferentes medios de
interaccin y atencin de los clientes, por los cuales se ofrecen los servicios de la empresa. Estos
medios pueden ser por ejemplo: el ms comn son las sucursales, el segundo mas comn es por
telfono o denominado como atencin telefnica (que proporcionan el servicio por medio de
equipos automticos llamados IVRs y los llamados Call Centers, los cuales dan la atencin
personalizada por medio de asesores telefnicos). Tambin estn los portales de servicio
financiero, que es un sitio Web el cual se accesa va Internet. Esta tambin los cajeros o ATMs, los
cuales dan muy comnmente el servicio de retiros de dinero y consulta de saldo, a un que mas
recientemente ya dan servicio de depsitos de efectivo, entre otros mas servicios. El servicio
bancario mvil, es un medio que tiene poco tiempo que ha surgido en Mxico, el cual es por medio
de acceso a la banca a travs de un celular o un smartphone, por medio del cual se realizan las
operaciones con el banco. Otro medio es el Kiosco, el cual principalmente sirven para realizar
consultas de saldos y de sus ltimos movimientos en su cuenta, estos dispositivos normalmente se
les ubica en plazas comerciales. Estos son algunos de los ms principales, pero existen cada vez
mas una gama de medios de interaccin del cliente (llmese persona fsica o moral).

Un canal de comunicacin, es una manera de denominar a cada una de las vas por las que la
institucin bancaria ofrece sus servicios financieros a sus clientes e incluso a sus no clientes. Para
el presente trabajo, el sistema a desarrollar surgir como una solucin para la comunicacin ms
rpida, para el canal de comunicacin de atencin telefnica. La atencin telefnica de clientes y
no clientes de algn Banco que requieran una ayuda y/o atencin de cualquiera de los productos
y/o servicios que ofrezca la institucin financiera.

El enfoque estar dado para que los servicio sean proporcionados a nivel nacional por un o varios
Call Center internos y por un o varios Call Center Externos.

Elementos que interviene en un servicio telefnico bancario:

Sistema CTI. Su funcin

Integracin del Programa Producto y desarrollos que permiten tener funciones de screen pop en
los equipos desktops de los asesores telefnicos, permite realizar retornos a puntos exactos en los
IVRs, transferencia de llamadas con voz y datos entre alguno de los supuestos sites de un servicio
telefnico de tipo bancario y otros mas sites de origen externo. Adems permite a los asesores
realizar las funciones telefnicas a travs del CTI integrado a los aplicativos de servicio, esto
permite a su vez poder tener un registro a detalle de todas las acciones que toman los asesores
con los clientes, pudiendo entregar a la operacin y al staff de un servicio telefnico de la empresa
Bancaria los diversos tipos de reportes, que ayudan al monitoreo y el performance de la operacin.


- 9 -

Flujo inicial de la llamada en coordinacin de un CTI, con una infraestructura propuesta.



Continuacin del flujo de la llamada con coordinacin de un CTI.




Interaccin de un CTI en una propuesta de flujo de llamada
Cliente Cliente
Marca
COMPAIA
TELEFONICA
AN
I
AN
I
La llamada llega a
un
La llamada llega a
un Grupo de
Priorizaci
Grupo de
Priorizaci
n
y
n
y Se transfiere al
IVR
Se transfiere al
IVR
PBX informa a CTI
Server
PBX informa a CTI
Server De la
llamada
De la
llamada
SYMPOSIU
M
CTI
Server
CTI Informa CTI Informa Inform
a
Inform
a
a a
IVR Datos de la
llamada
IVR Datos de la
llamada
AN
I
AN
I
IVR Inicia
Interacci
IVR Inicia
Interacci
n con el
Cliente
n con el
Cliente Y aplica Script Programado y valida si es
nueva
Y aplica Script Programado y valida si es
nueva Llamada
.
Llamada
.
Convierte instrucciones del
cliente
Convierte instrucciones del
cliente En Transacciones hacia el
HOST
En Transacciones hacia el
HOST
WA
N
HOS
T
HOST
1 1
2 2
3 3
4 4
5 5
6 6
7 7
PBX
env
PBX
env
a llamada a llamada
Al
IVR
Al
IVR
Cliente Marca Cliente Marca
Compaa que proporciona
el servicio Telefnico
WA
N
HOS
T
Cliente
Solicita
Cliente
Solicita Transferencia
con
Transferencia
con Un
Agente
Un
Agente
IVR Arma cadena con los datos del IVR Arma cadena con los datos del
Cliente y
env
Cliente y
env
a solicitud de transferencia al CTI a solicitud de transferencia al CTI
CTI Recibe Sol.
Transf.
CTI Recibe Sol.
Transf. Asigna Asigna
Prioridad
CTI
Server
Symposiu
CTI Recibe CTI Recibe
confirmaci
n de n de
transferencia En
v
En
v
a Datos de Transf. Al
PBX
a Datos de Transf. Al
PBX
PBX Transfiere
llamada
PBX Transfiere
llamada Al ID
Disponible
Al ID
Disponible
Agente
Agente
Agente Servicio Tipo
1
Agente Servicio Tipo
ACD Phon
ACD Phon
e
R e
d

V o
z


n
e
a
s

D
i
g
it
a
l
e
s

R e
d

E
t
h
e
rn
ACD Phon
e
ACD Phon
8 8
9 9
1
0
10
1 14
1
3
13
1 13
El asesor recibe screen pop del El asesor recibe screen pop del
Cliente y pasa Cliente y pasa info
r
info
r
. A
SDAT
. A SDAT
1
5
15
Termina la llamada Termina la llamada
O transfiere a otro grupo (repite
10
O transfiere a otro grupo (repite
10
- -15
)
15
)
1
6
16
Tabla
CTI
Tabla
CTI Tig045_CT
I
Tig045_CT
I
Se guarda
informaci
Se guarda
informaci
n de
la
n de
la Llamada en
BD.
Llamada en
BD.
1
7
17
Solicita a Solicita a Symposiu
m
Symposiu
m
Real Time tiempos en
colas
Real Time tiempos en
colas En
v
En
v
a tiempos de espera al
IVR
a tiempos de espera al
IVR
1
1
11
Informa al cliente tiempos de
espera
Informa al cliente tiempos de
espera Solicita
confirmaci
Solicita
confirmaci
n de
transferencia
n de
transferencia
1 12
Realiza
Transferencia
Realiza
Transferencia
IV s
PB
Conmutador(es
Interaccin de un CTI en una propuesta de flujo de

- 10 -




I. Interfaces del CTI con otros elementos de la atencin telefnica.


I.I Interfase con aplicaciones de Interfaz Grafica.
Esta interfase integra el CTI con la aplicacin desktop de tipo GUI (Interfaz grafica de
usuario, el cual puede ser desarrollada bajo Java, .Net, etc.), la cual utilizaran los asesores para
atender todos los servicios que proporcionan en el centro de atencin telefnico. As como de
realizar todas las funciones de telefona desde la aplicacin de CTI (transferencia, conferencias,
llamadas de salida).

I.II Interfase con Conmutador
Estas interfases con el conmutador permiten al CTI hacer 4 funciones:

a) DDR: Interfase entre CTI-PBX-IVR encargada de analizar las llamadas que solicitan un
asesor en los IVR para transferirla de manera inteligente, segn el tipo de cliente, servicio
solicitado, antigedad, zona regional, etc. para que se atienda con la prioridad y al grupo
de asesores mejor capacitados segn cada llamada.
Tambin es la encargada de pasar la informacin al los IVR para informarles a los clientes
tiempos aproximados de atencin
b) RolingDnis: Interfase con diferentes conmutadores encargada de pasar las llamadas con
voz y datos entre los diferentes conmutadores.
c) CDN Abandono: Interfase contra el conmutador encargada de almacenar los datos
telefnicos y as como de los datos de los clientes de las llamadas abandonadas, para su
posterior marcacin.
d) CDN Monitor: Interfase contra el conmutador encargada de identificar y poner etiquetas a
las llamadas que no pasan por IVR.

























- 11 -



I.III Interfase con el sistema de grabacin

Esta interfase permite pasar los calificadores de login (clave de firmado del agente en el
conmutador) al sistema de grabacin para que se puedan realizar bsquedas de llamadas por
este valor.



2.2 Arquitectura base. PBX, IVR's y CTI.

Infraestructura Aplicacin IVR de atencin telefnica de algn banco.


En un centro telefnico propuesto se puede contar con ms de 1600 puertos de IVR
distribuidos en 3 sites con cobertura nacional. Bajo este esquema, se podrn recibir en promedio 5
millones de llamadas mensuales, de las cuales se transferir slo el 15% para su atencin con
algn asesor telefnico. Los IVRs sern manejados completamente en tonos.

La comunicacin al Host-MainFrame de una institucin bancaria se propone sea a travs
de sockets de TCP/IP con el protocolo de formato de tramas PS-9. Los IVRs contaran con
licencias de TTS (Text to speech) para la conversin de texto a voz de los nick names que los
clientes le asignan a cada una de sus cuentas de terceros para los traspasos y pagos en el servicio
Interfases de componentes de un CTI.
CT
I
GUI
-
App Distri.
Interfase
Conmutador!
DD
"ollin
CD#$onito
CD#Col%ad
Interfase CTI -Des&to
Interfase
'istema de
Graacn
IV
R
s
Sistem
a de Grabacion
Conmutador(e )


- 12 -
avanzado. Se contara con una interaccin con CTI a travs de una dll para el manejo de sockets
TCP de TCP/IP.









Configuracin propuesta de 3 sites, instalados en tres ciudades principales, que darn servicio a
todo el pas.


Algunos de los servicios ofrecidos en el men de autoservicio de atencin telefnica que
comnmente se ofrecen en una institucin financiera.

Una aplicacin de atencin telefnica puede contar con servicios de nmeros telefnicos, como por
ejemplo: Nmeros locales para cada ciudad principal del pas, un servicio de 01-800 para el resto
del pas.

Aunque existen diferentes nmeros telefnicos para los segmentos de clientes, tambin la
aplicacin configura automticamente las opciones de servicios y productos a ofrecer en los
diferentes mens, los grupos de transferencia e incluso la voz de los mensajes en base a la
informacin del cliente obtenida a partir de su plstico de acceso.

El men principal de acceso telefnico, puede constar de de tres opciones principalmente: de
reporte por robo extravo, men de transaccionalidad y men de servicios:

- 13 -

El men de robo extravo transfiere las llamadas de forma directa con los asesores
para el reporte de plsticos o cheques, que fueron extraviados o robados.
El men de transaccionalidad contiene la mayor parte de la aplicacin, en l se
pueden encontrar diferentes opciones las cuales se presentan en base a los productos
financieros que tenga contratados el cliente. Contamos con alrededor de 100
transacciones diferentes, las cuales se utilizan a travs de sockets de TCP/IP y tienen
el formato PS9. Mensualmente se generan ms de 10 millones de transacciones.
El men de servicios contiene la mayor parte de las opciones de transferencia.
Previo a la transferencia se realizan validaciones en los productos de los clientes, en
algunos casos se evita la transferencia informando al cliente, por ejemplo, el estatus
de una aclaracin, el envo de un plstico a domicilio, entre otros.



Confi%uracin de ejemplo de un ser(icio telefnico ancario!





























CENTRO1
CENTRO2
CONMUTADOR 1
CONMUTADOR 2
CIA TEL

CIA TEL
CIA TEL
CIA TEL
')$P*'IU$
+I#,
'-"VID*"
CTI
IV" '
')$P*'IU$
+I#,
'-"VID*"
CTI
IV" ' AGT'
'-"VID*"
CTI
IV" '
CENTRO3
CALL CENTER
EXTERNO
AGT'
81579111
36690229
9E1
52262663
27E1
562411XX
6E1
CIA TEL
52262663
13E1
.-/
160CH/6E|
11E1
5E1
11E1
27E1
.-/
0-/
')$P*'IU$
+I#,
'-"VID*"
CTI
IV" '
')$P*'IU$
+I#,
012 PT'
/1. PT'
033 PT'
350 AGTES
400 PT'
CALL CENTER
EXTERNO
3E1
.03 AGT-'

- 14 -



3 MainFrame (Host).

3.1 Introduccin.
Un mainframe es una computadora grande, con mucha capacidad, la cual es utilizada
principalmente en empresas que necesitan procesar gran cantidad de datos y/o soportar gran
cantidad de usuarios, muy comn en la industria bancaria. Un mainframe puede funcionar durante
muchos aos sin problemas, ni interrupciones o incluso puede repararse mientras esta
funcionando.
Tambin puede simular el funcionamiento de cientos de computadoras personales (terminadores
virtuales) dentro de una empresa. Un mainframe no es lo mismo que una supercomputadora.
Un mainframe es un repositorio de central de datos o un Hob, en una corporacin con
procesamiento central de datos. Este esta enlazado con los usuarios que cuentan con dispositivos
con menos poder, tales como terminales, estaciones de trabajo o equipos de escritorio. La
presencia de un mainframe frecuentemente implica una forma centralizada de computacin, que es
lo opuesto a una configuracin de computacin distribuida.
Los equipos pequeos distribuidos, han estado creciendo enormemente, tal es el caso que la
brecha de distincin entre estos y un mainframe es cada vez ms confusa. Considerado esto, el
nuevo enfoque de los mainframe, es ahora basado en su interaccin en combinacin de redes de
pequeos servidores (sistemas distribuidos) en una infinidad de configuraciones, en base a las
necesidades de las empresas.
Los nuevos mainframes, deben de contar con una flexibilidad y evolucin natural, la cual subraya la
habilidad que tengan estos de reconfigurarse dinmicamente en aspectos de hardware y/o
software (considerando procesamiento, memoria, disponibilidad de conexiones de dispositivos),
esto mientras las aplicaciones continan ejecutndose simultnea o paralelamente.
El sistema operativo z/OS, es el S.O. usado principalmente en un mainframe. El sistema z/OS que
se instala en un mainframe, esta diseado para ofrecer un estable, seguro, y una continua
disponibilidad de ambiente de aplicaciones en ejecucin. Hoy en da, el z/OS es el resultado de
dcadas de avances tecnolgicos, el cual fue evolucionando de ser un S.O. que solo poda
ejecutar un simple programa a la vez, a un S.O. que puede manejar muchos de miles de
programas a la vez y a su vez, proporcionar una interactiva concurrencia de usuarios.
El Cics, definido por Costumer Information Control System. Es un subsistema de procesamiento
transaccional de propsito general, enfocado principalmente para el z/OS. Donde el Cics provee de
servicios que pueden ser ejecutados en una aplicacin en lnea (en lnea significa, que el sistema
proporciona una interaccin y respuesta inmediata con el usuario), en base al requerimiento del
usuario. Esto permite a muchos usuarios puedan realizar solicitudes de requerimientos al mismos
tiempo. Se cuenta con el enfoque interno de que se puede ejecutar la misma aplicacin, usando
los mismos archivos y programas (denominado cdigo reentrante).
El Cics permite manejar los recursos compartidos, as como la integridad de los datos y priorizacin
de ejecucin, proporcionando una rpida respuesta. Tambin autoriza a los usuarios, alojar los
recursos (almacenamiento real y ciclos de ejecucin), as como, dar pasa a los requerimientos de
base de datos, por la aplicacin, con el apropiado manejador de base de datos (tal como DB2).

- 15 -
Nosotros podemos decir que Cics acta como el z/OS y realiza muchas de las mismas operaciones
que el z/OS sistema operativo.
Una aplicacin Cics, es una coleccin de programas relacionados, los cuales juntos realizan una
operacin de negocio. Unos ejemplos pueden ser, el procesamiento de una solicitud de viaje o la
preparacin de una nmina de una empresa. Las aplicaciones de Cics, son ejecutadas bajo el
control de Cics, usando servicios de Cics y sus interfaces de acceso a programas y de archivos.
Las transacciones de cics son normalmente realizadas por ejecucin de un requerimiento de
transaccin. La transaccin ejecutada consiste en con correr una o mas programas de aplicacin
que implementan la funcin requerida.

3.2 Arquitectura ASTA (Altamira).
La Arquitectura ALTAMIRA es un sistema altamente parametrizado montado sobre Cics. En
esta arquitectura es posible definir las entidades de trabajo, sus entornos y las caractersticas
necesarias para el funcionamiento de tipo on-line, as como del procesamiento en batch.

Una de las utilidades del Sistema de Arquitectura es la gestin de la paginacin de los listados por
pantalla (scroll a izquierda, derecha, arriba, abajo) de manera transparente a las aplicaciones, de
tal manera que se simplifica notablemente el diseo y codificacin de las transacciones de listado.
Una convencin que se tiene entre las diferentes aplicaciones, es que se comunicaran o se
hablarn con la Arquitectura, fundamentalmente a travs del rea de comunicacin CAA (un rea
de memoria estndar).

3.3 Cics Bridge TCP-IP.
El IBM CICS BRIDGE, es un conjunto de programas que forman parte de la interfase CICS
Sockets y que son instalados conjuntamente con los programas dedicados a tal fin en el CSD de la
regin CICS.

El objetivo del CICSBRIDGE es permitir que una aplicacin transaccional sncrona distribuida
pueda conseguir la ejecucin de un programa residente en una regin CICS OS/390 y obtener una
respuesta mediante el uso de MQ, Sockets, etc. sin necesidad de que el programa CICS tenga que
ser modificado para soportar dicha comunicacin.
Debido a las necesidades que se requieren en un banco determinado, es necesaria la
implementacin de una versin modificada de la versin original del Cics Bridge de IBM. En donde
a continuacin se menciona una versin propuesta que se puede usar en una empresa bancaria.
A diferencia del monitor de IBM (Transaccin CSKL), la versin propuesta est orientada al
aprovechamiento de las facilidades transaccionales sobre CICSPLEX, al distribuir la carga
transaccional en los AORes, evitando la concentracin de transacciones en el TOR y evitando
afinidades, y adicionando facilidades de sesiones y validaciones en RACF.








- 16 -



Componentes de una aplicacin donde participa cicsbridge.


En un escenario aplicativo donde participa CICS Bridge pueden identificarse:
1) UN COMPONENTE CLIENTE.
Es el que posee la informacin que debe ser procesada. Al usar CICS BRIDGE,
necesariamente se considera un componente transaccional, es decir que entregar un mensaje y
quedar en espera de la respuesta durante un tiempo preestablecido. El Cliente ser en muchos
de los casos un Distribuido (NT, UNIX, etc.). Se debe tener en cuenta que el mensaje que enven
debe estar en formato PS-9.
2) UN COMPONENTE SERVIDOR.
Es el que puede llamar o efectuar un proceso sobre la informacin contenida en el
mensaje que el cliente enva. Este componente es ejecutado por CICS BRIDGE usando el
comando LINK, por lo que el contenido del mensaje es recibido en COMMAREA, siendo luego
reemplazado por la respuesta o resultado del proceso.
3) CICS BRIDGE.
Son los componentes ARRANQUE, MONITOR, PROCESADOR y SALIDA los que
conforman el modelo de CICS Bridge. El ARRANQUE ejecuta la(s) Transaccin(es) MONITOR(es),
que son las encargadas de recibir mensajes en cualquier momento, tomarlos y mandarlos a
procesar, el PROCESADOR identifica el mensaje y enviar hacia la arquitectura ASTA a ejecutar
la transaccin requerida, al regreso de la arquitectura el procesador enva la respuesta al
componente de SALIDA que es el que restablece la comunicacin con el distribuido y entrega la
respuesta.

D Di ia ag gr ra am ma a d de e F Fl lu uj jo o C Ci ic cs s B Br ri id dg ge e T TC CP P/ /I IP P q qu ue e p pu ue ed de e s se er r u us sa ad do o e en n u un n
M Ma ai in nF Fr ra am me e. .
A Ap pl li ic ca at ti iv vo o
QPTP
QG1CSP
TCP/
IP

Servi
ces
TCP/
IP

Servi
ces
TCP/
IP

Serv
A
R
Q
U
I
T
E
C
T
U
R
A
A
P
L
I
C
A
T
I
V
O
S
QGPARTC
P
C CI IC CS S
TOR
C CI IC CS S
AOR
CICS
Sock
ets

API
XYZ
W
QOxx
DFHMIR
S
'TA"T
U'-"ID G-#-"IC*
'TA"T
U'-"ID G-#-"IC*
+I#, T"A#'ID
5CT+
QG1CS
BP2
+I#,
QTxx
QG1CSER
YMQ
T
'TA"T

- 17 -


A AR RR RA AN NQ QU UE E C CI IC CS S B BR RI ID DG GE E T TC CP P. .
El arranque del CICS Bridge TCP se da mediante la ejecucin de una transaccin
llamada de arranque QPTP ligada al programa QG1CSPTP, que su ejecucin puede estar incluida
al inicio el CICS TOR se puede ejecutar directamente dentro CICS con un usuario que tenga la
autoridad respectiva.
Esta transaccin de arranque tiene por objetivo leer el archivo de parmetros del
Cicsbridge TCP, y realizar un START a cada una de las transacciones monitoras que estn
incluidas para el Cics en donde se esta ejecutando la transaccin de arranque. Los parmetros
para cada aplicacin se envan como commarea de la transaccin monitora ejecutada.
Si en algn momento la transaccin monitora tiene una terminacin anormal (abend),
antes de terminar su ejecucin realizar un START con delay a la transaccin se arranque con los
datos de IP y puerto en donde estaba trabajando, para volver a arrancar el monitor.
M MO ON NI IT TO OR R D DE E C CI IC CS S B BR RI ID DG GE E T TC CP P. .
La transaccin monitor de Cics bridge TCP se ejecuta en el Cics TOR de comunicaciones
que incluya el CICS Sockets API. Una vez arrancada esta transaccin estar monitoreando lo que
fluya en el puerto de la IP con la cual se haya conectado. Cuando reciba un mensaje lo tomar, lo
valida de acuerdo a los parmetros de arranque y en caso de ser aceptado realizar un START a
la transaccin llamada procesadora para atender el requerimiento, en caso contrario se regresar
el cdigo de error correspondiente.
Si esta transaccin tiene una terminacin anormal (ABEND), antes de terminar realizar
un START a la transaccin de arranque con un delay de 60 segundos, con la IP y puerto enviado
para que vuelva a levantar este monitor.























- 18 -




3.4 Protocolo PS-9.
El protocolo de comunicacin entre el distribuido y el host, esta dado por el Cics bridge
TCP debido a su desarrollo, aunque tiene un parmetro de protocolo que puede ser til en caso de
no querer utilizar el protocolo definido.
Teniendo en cuenta que es un sistema de comunicaciones de un cliente ya sea un distribuido o un
host hacia el equipo host de BBVA, atendiendo requerimientos principalmente de aplicaciones que
se encuentran bajo la arquitectura Altamira, el flujo comienza en con el cliente. Antes de comenzar
a describir el protocolo definiremos algunos de los formatos en los cuales se enviara la informacin.
) MESSAGE DESCRIPTOR DE TCP. Formato de informacin de 160 posiciones fijas, en el
cual se incluyen parmetros y datos propios de la aplicacin y del operador, este
formato tendr que ser enviado siempre. Los campos contenidos en este formato
son:

Descripcin del Campo Tipo Valor Default posibles
TAG DE INICIO DEL MESSAGE DESCRIPTOR X(04) <MD>
LA VERSION DEL DISTRIBUIDO X(05) 1.0.0
LONGITUD MAXIMA DEL MENSAJE PS9 9(05) 32584
IDENTIFICACION DEL MENSAJE ENVIADO X(24) Valor que hace msg nico
TIEMPO PARA MONITOREO EN SEG. (WAITINTERVAL) 9(05) 00600
REQUERIMIENTO SOLICITADO de MD X(04) **** , LOGN, LOGF, VERY, LRSS,
CHPW
TIPO DE USUARIO X(08) USERGENE, USERRACF,
USER3270, USERDGPO
TIPO DE VALIDACION DEL USUARIO X(04) **** RACF
CORRESPONDE AL USERID FINAL X(08) USERID de 8 Posiciones
CORRESPONDE AL USERID DE GRUPO X(08) Usuario de grupo si es el caso
PASSWORD ENCRIPTADA (BASE 64) X(12) Password encriptada Base 64
PASSWORD NUEVA ENCRIPTADA (BASE 64) X(12) Nva Password encriptada B64
NUMERO DE SESION 9(08) 00000000 Nmero de sesin
FECHA DE ENVIO X(10) AAAA-MM-DD
HORA DE ENVIO X(08) HH:MM:SS
DISPONIBLE X(30) Espacios
TAG DE FIN DEL MESSAGE DESCRIPTOR X(05) </MD>

Los siguientes formatos son propios del PS-9 Protocolo Informacin.
) INPUT HEADER PS9. Header del Formato PS9 de 65 posiciones fijas. Este ser
inmediato al message descriptor de TCP.

Descripcin del Campo Tipo Valor Default posibles
TAG DE INICIO DEL INPUT HEADER X(04) <IH>
CODIGO DEL PROTOCOLO DE INFORMACION X(02) 26 para formato PS9

- 19 -
TERMINAL LOGICO X(08) Terminal lgico
alfanumrico
TERMINAL CONTABLE X(08) Terminal alfanumrico
contable
USUARIO X(08) User-id que enva la
informacin
NMERO DE SECUENCIA X(08) Nmero de secuencia
CODIGO DE LA TRANSACCION X(08) Transaccin
OPCIN 9(02) Intro=00,F1=01,F2=02
...
LONGITUD TOTAL DEL MENSAJE PS9 9(05) Longitud PS9 desde <IH> a
</ME>
INDICADOR DE COMMIT EN ALTAMIRA 9(01) 0 Sin commit 1 con
commit
TIPO DE MENSAJE 9(01) 1- New Request,
2- Authorization,
3- Conversation Scroll
Info.,
5- Conversation
Continuation,
6- Authorization in a
conversation
TIPO DE PROCESO X(01) O On-line F Off-line
CANAL X(02) Canal de la aplicacin
INDICADOR DE PREFORMATEO X(01) Y Formateo N Sin
Formateo
LENGUAJE X(01) Alfanumrico indicador el
lenguaje
TAG DE FIN DEL INPUT HEADER X(05) </IH>

) INPUT MESSAGE. Este es el formato del mensaje que dependiendo del tipo de mensaje
descrito en el Input Header y dependiendo de la transaccin enviada ser de formato
y longitud variable. El formato ms comn que se utilizar bajo Cics bridge ser el
siguiente. Para mayor informacin sobre otro formato consultar el documento
informacin del protocolo PS-9.

Descripcin del Campo Tipo Valor Default
posibles
TAG DE INICIO DEL INPUT MESSAGE X(04) <ME>
LONGITUD DEL COPY 9(04) Longitud del COPY
TIPO DEL COPY X(01) C si es COPY B
Si es BMS
COPY X(---) Datos del copy
TAG DE FIN DEL INPUT MESSAGE X(05) </ME>



El programa QG1CMTCP monitor bajo Sockets, una vez realizada la conexin a la IP y puerto
correspondiente mediante APIs de Sockets, empieza por validar los tres formatos. Dependiendo
del requerimiento del cliente es como se procesara la informacin.


- 20 -
a) Cuando parmetro de host TIPOREQUER es el valor default (espacios ****), nos indica que el
cliente no requiere de sesiones de Cics bridge. Por lo que por cada peticin del cliente tiene
que enviar la siguiente secuencia de formato:
<MD> </MD><IH> </IH><ME> </ME>
1. El programa leer todo lo que el cliente enve y primeramente tomara la parte de el
message descriptor TCP checando los tags de este formato en la posicin
correspondiente, tambin valida que los campos longitud mxima de ps9, waitinterval y
nmero de sesin sean numricos, en caso de que no sean correctas cualquiera de
estas premisas se enviara el error correspondiente y cerrada el socket asignado.
2. Una vez validado el Message descriptor, el programa toma la segunda parte
correspondiente al Input Header PS9, en esta parte checa los tags del Input Header
que se encuentren en la posicin correcta y se valida que el campo de longitud total del
mensaje PS9 sea numrico. En caso de que no sea satisfactoria la respuesta a estas
validaciones se regresara el error correspondiente.
3. Si hasta este momento todo va bien, se hacen las operaciones correspondientes para
checar la longitud de la commarea a enviar a la transaccin procesadora y se le realiza
el START correspondiente, enviando el socket que se tomar para regresar la
respuesta y cerrando el socket asignado para recibir la informacin.
4. Para este esquema existe una variante si el parmetro TIPOUSUARI es USER RACF,
TIPOVALIDA es RACF y REQUERIMIENTO del Message Descriptor es LRSS, se
tomar el usuario y password que venga en el Message descriptor y se realizar la
validacin en RACF si es correcto se proceder a realizar el START a la transaccin
procesadora correspondiente y en caso contrario se regresar el error correspondiente.
b) Cuando parmetro de host TIPOREQUER es el valor SESI, nos indicar que el cliente requiere
de sesiones de Cics bridge. Bajo un esquema de sesiones primero tiene que firmarse al Cics
bridge haciendo el LOGON y una vez firmado comenzar a enviar las operaciones
correspondientes, una vez terminada su actividad tendr que dejar la sesin haciendo el
correspondiente LOGOFF.
5. Para el requerimiento del MD sea LOGN LOGF correspondiente al LOGON y
LOGOFF solo es necesario enviar el formato del Message Descriptor, mismo que ser
validado como el punto 1. En el LOGN se crear una sesin para el usuario enviado en
el MD. Para el LOGF ser necesario indicar el usuario y nmero de sesin a la cual se
quiere dar de baja.
6. Cuando se requiera operar alguna transaccin se tendr que enviar una trama de la
siguiente forma:
<MD> </MD><IH> </IH><ME> </ME>,
Pero aqu en el MD se tendr que indicar el usuario, nmero de sesin y requerimiento igual a
VERY. El programa realizar el punto 1 posteriormente validar que exista la sesin y contenga
al usuario indicado, de tal forma que si es correcto realizara el punto 2 y 3, en caso de que no
exista la sesin que el usuario no corresponda a la sesin se regresar el error
correspondiente.
7. Para este esquema tambin existe una variante si el parmetro TIPOUSUARI es
USERRACF , TIPOVALIDA es RACF y REQUERIMIENTO del Message Descriptor es
LOGN, se tomar el usuario y password que venga en el Message descriptor y se
realizar la validacin en RACF si es correcto se proceder a generar la sesin y en
caso contrario se regresar el error correspondiente. Esto es solo en el momento del
LOGON ya que de esta forma solo hay una validacin en RACF y no una por cada
peticin.

- 21 -
c) Existe tambin una funcin cuando parmetro de host TIPOUSUARI es USERRACF ,
TIPOVALIDA es RACF y REQUERIMIENTO del Message Descriptor es CHPW. Este
requerimiento es el cambio de password en el cual solo se enva el formato del Message
Descriptor con estos valores adems del user-id password y nuevo password encriptados. El
Host desencriptar el password y new password tomando la llave de Desencripcin
correspondiente y tomando el user-id ejecutar el commando CHANGE PASSWORD
cambiando el password sea correcto o errneo regresar el mensaje correspondiente al
cliente.


- 22 -
F FO OR RM MA AT TO OS S D DE E S SA AL LI ID DA A D DE E C CI IC CS S B BR RI ID DG GE E T TC CP P. .
El formato de salida para cualquiera de las transacciones va ser en el formato PS9 que
utilizamos como estndar. Al igual como el formato de entrada, el formato de salida tambin tiene
un Header y su detalle ya sea de error o respuesta aplicativa. De tal modo que cuando una
respuesta sea satisfactoria para la arquitectura tendr el siguiente formato:
<OH>............</OH><DE>.............</DE><OC>.............</OC>
Y cuando exista un error
<OH>............</OH><ER>.............</ER>
Los Layouts correspondientes a los formatos de salida son los siguientes:
O OU UT TP PU UT T H HE EA AD DE ER R. .
Field Bytes Meaning Possible Values
TTTT 4 Tag Indicating beginning of output header <OH>
PP 2 Protocol Identification 26 PS9 (this protocol)
R 1 Transaction / Service response 1= OK with COMMIT. It means the Front
End should COMMIT the changes (if
the COMMIT indicator had the value
0 Altamira architecture is not
allowed to do so).
2 = NO OK with COMMIT. It means the
Front End should COMMIT the
changes even thougth an error has
ocurred.
3 = CONFIRMATION REQUESTED with
COMMIT (User must confirm an
action. Usually associated to a
Warning Map and a Next
Transaction map to indicate what is
the transaction we want to confirm.
The changes should be commited).
4= OK with ROLLBACK. It means the
Front End should ROLLBACK the
changes.
5 = NO OK with ROLLBACK. It means
the Front End should ROLLBACK
the changes.
6 = CONFIRMATION REQUESTED with
ROLLBACK.
P 1 Process Control 0 Not processing errors detected.
1 Indicates that an architecture error
has ocurred. An output format
espedified in an <OC> map does not
exist (Only applicable in traditional
Altamira architecture).
2 Reserved Use.
'3' Indicates that an architecture error
has ocurred. The output message
has more than 32 Kb. The user
should advise CPD check the LOG.
'4' Indicates that an architecture error
has ocurred. The Output Copy map
or the Preformated Map information
has more than 20 Kb. The user
should advise CPD to check the
LOG.
'5' - Indicates that an architecture error
has ocurred. The application
program informs that the Output
Screen is the same that the Input
Screen and the Input format does
not exist.
The user should advise CPD to check
the LOG. (Only applicable in

- 23 -
traditional Altamira architecture)
'6' - Indicates that an architecture error
has ocurred. The application
program informs that the Output
Screen has been prepared and the
Output format does not exist.
The user should advise CPD to check
the LOG. (Only applicable in
traditional Altamira architecture)
'7' - Indicates that an architecture error
has ocurred. In case of prefortating
indicator, the preformat name
related to the espedified format is
not informed or does not exist. The
user should advise CPD to check
the LOG. (Only applicable in
traditional Altamira architecture)
A Indicates that an Abend Error has
ocurred. The user should advise
CPD to check the LOG.

SSSSSSSS 8 Sequence number Any Alphanumeric set of characters. Front
end or middleware will provide this
number. Altamira will just give it back. It is
used to synchronize back and front end.
NNNNN 5 Output message length. Also needed for
validation purposes and also to identify
the end of the message.
(Output Header Length + Output Data
Length)
Any number between 26 and maximum
output length.
TTTTT 5 Tag Indicating end of output header </OH>
Total de longitud: 26 bytes.

F FO OR RM MA AT TO OS S D DE E M ME EN NS SA AJ JE ES S D DE E S SA AL LI ID DA A. .
<ER> .. </ER> - Error map.
<AV> .. </AV> - Warning map.
<SG> .. </SG> - Next transaction map.
<JO> .. </JO> - Journal map.
<DE> .. </DE> - Destination map.
<OC> .. </OC> - Output Copy map.
<SC> .. </SC> - Scroll Map.
<CA> .. </CA> - Conversational Authorization map.
<UM> .. </UM> - Unexpected Message map.
<PF> .. </PF> - Preformated Data map.

F FO OR RM MA AT TO O D DE E E ER RR RO OR R. .
Field Bytes Meaning Possible Values
TTTT 4 Tag for beginning of error map <ER>
CODERR 7 Error code Any Alphanumeric set of characters
following Altamira standard for error
names
NUMVAR 1 Number of variables Any value >= 0. When NUMVAR is equal
to 0, the Variable fields wont be sent.
ERRVAR1 20 First error variable data Any Alphanumeric set of characters
(if NUMVAR > 0)

ERRVARN 20 Error variable data number N Any Alphanumeric set of characters
(if NUMVAR > 1)
TTTTT 5 Tag for end of error map </ER>
Mxima longitud: ?. Actualmente tenemos un mximo de 2 variables de datos, con 57 bytes.

- 24 -
F FO OR RM MA AT TO O D DE E O OU UT TP PU UT T C CO OP PY Y. .
Field Bytes Meaning Possible Values
TTTT 4 Tag for beginning of destination map. <DE>
ID 1 ID of the Destination Any value among 1,..,5
IND-PANDOC 1 Destination of the format (Screen, Printer, Hard Disk or
Jetform
P Screen
D Printer
NUM-DOCUM 1 Type of document if the output is to document. 1 DIN A-4 Normal
print.
2 DIN A-4
Compressed print.
3 Sheet
5,6,7,8 Savings
books.
9 DIN A-4 in a laser
printer
C Check
B Band (ribbon)
I Amount
J Magnetic Diary
R Pre-printed
document.
PRILIN-DOCUM 2 Position of the first line to be written in the document.
IMPRESO 6 ID of the form to be used
IDIOMA 1 Language ID of the language to
be used.
TTTTT 5 Tag for end of destination map. </DE>
Maxima longitud: 5 x 21 bytes.

Field Bytes Meaning Possible Values
TTTT 4 Tag for beginning of Output copy map <OC>
T 1 Type of copy B BMS
C COPY
Y 1 Number ID of the DE map which
describes the copy destination. 0
means no destination
0
1
2
3
4
5
FFFFFFFF 8 Format name / Output number Format name that will match with copy name
following Altamira Naming Standards, or the
output number for the transaction.
<copy> ? Data Copy of the specified type (BMS or standard
COPY).
TTTTT 5 Tag for end of Output Copy Map </OC>

BMS copy sigue la estructura FILLER [longitud-atributo-campo], con un tamao mximo de 2000
bytes.
En caso de un copy fijo, este consistir de un nmero fijo de campos con contenido alfanumrico.
Esto permite usar diferentes copias para la misma transaccin. El copy usado ser definido por el
nmero de salida.

Si el destinatario es diferente de 0, debe de existir un mapa destino (<DE>) que informe el destino
para la salida.
En el caso de copy fijo el mapa destinatario ser siempre 0, como el front-end conocer el
destinatario.

Puede haber varios mapas <OC> con estructura de copy BMS solo en caso de copy fijo, y ambos
tipos son exclusivos (por ejemplo, el mensaje puede contener varios <OC> de tipo BMS o uno de
tipo copy)

Longitud maxima: 20 Kb.


- 25 -

4 Programacin concurrente y paralela.

4.1 Introduccin.
La programacin en paralelo, es una tcnica de programacin en la que muchas instrucciones se
ejecutan simultneamente o paralelamente. Se basa en el principio de que los problemas grandes
se pueden dividir en partes ms pequeas, las cuales se pueden resolverse de forma paralela (no
es lo mismo que concurrente). Existen varios tipos de programacin en paralelo: paralelismo a nivel
de bit, paralelismo a nivel de instruccin, paralelismo a nivel de datos y paralelismo de tareas.
Durante muchos aos, la programacin en paralelo se ha aplicado en la computacin de altas
prestaciones, pero el inters en ella ha aumentado en los ltimos aos debido a las restricciones
fsicas que impiden escalarlo con frecuencia. La computacin en paralelo se ha convertido en el
paradigma dominante en la arquitectura de computadoras, principalmente en los procesadores
mutincleo. Sin embargo, recientemente, en los equipos paralelos su consumo de energa se ha
convertido en una preocupacin.
Las computadoras paralelas se pueden clasificar segn el nivel de paralelismo que admite su
hardware: las computadoras de multincleo y multiproceso tienen varios elementos de
procesamiento en una sola mquina, mientras que los clusters, los MPP y los grids emplean varias
computadoras para trabajar en la misma tarea.
Los programas de las computadoras en paralelo, son ms difciles de escribir que los normales
secunciales, porque el paralelismo introduce nuevos tipos de errores de software, siendo las rice
condition los ms comunes. La comunicacin y la sincronizacin entre las diferentes subtareas son
tpicamente las grandes barreras para conseguir un buen rendimiento de los programas paralelos.
El incremento de velocidad que consigue un programa como resultado del algoritmo paralelizado
viene dado por la ley de Amdahl, el cual permite observar si mejora el performance del programa
con el paralelismo.

4.2 Programacin Multihilo.
En los sistemas operativos un hilo de ejecucin, hebra o subproceso es la unidad de
procesamiento ms pequea que puede ser planificada por un sistema operativo.
La creacin de un nuevo hilo es una caracterstica que permite a una aplicacin realizar varias
tareas a la vez (concurrentemente). Los distintos hilos de ejecucin comparten una serie de
recursos tales como el espacio de memoria, los archivos abiertos, situacin de autenticacin, etc.
Esta tcnica permite simplificar el diseo de una aplicacin que debe llevar a cabo distintas
funciones simultneamente.
Un hilo es bsicamente una tarea que puede ser ejecutada en paralelo o en el mismo intervalo de
tiempo con otra tarea.
Los hilos de ejecucin que comparten los mismos recursos, sumados a estos recursos, son en
conjunto conocidos como un proceso. El hecho de que los hilos de ejecucin de un mismo proceso
compartan los recursos hace que cualquiera de estos hilos pueda modificar stos. Cuando un hilo
modifica un dato en la memoria, los otros hilos acceden a ese dato modificado inmediatamente.
Lo que es propio de cada hilo es el contador de programa, la pila de ejecucin y el estado del CPU
(incluyendo el valor de los registros).

- 26 -
El proceso sigue en ejecucin mientras, al menos uno de sus hilos de ejecucin siga activo.
Cuando el proceso finaliza, todos sus hilos de ejecucin tambin han terminado. Asimismo en el
momento en el que todos los hilos de ejecucin finalizan, el proceso no existe ms y todos sus
recursos son liberados.
Algunos lenguajes de programacin tienen las caractersticas de diseo expresamente creadas
para permitir a los programadores lidiar con hilos de ejecucin (como Java o Delphi, etc). Otros (la
mayora) desconocen la existencia de hilos de ejecucin y stos deben ser creados mediante
llamadas de biblioteca especiales que dependen del sistema operativo en el que estos lenguajes
estn siendo utilizados (como es el caso del C y de C++).
Un ejemplo de la utilizacin de hilos, es tener un hilo atento a la interfaz grafica de usuario (en los
iconos, botones, ventanas), mientras otro hilo hace una larga operacin internamente. De esta
manera el programa responde de manera ms gil a la interaccin con el usuario. Tambin pueden
ser utilizados por una aplicacin servidora para dar servicio a mltiples clientes.

4.3 Modelos y herramientas de programacin paralela.
Una computadora en paralelo es un sistema computarizado multi-procesador que soporta
programacin en paralelo. Se definen dos importantes categoras de computadoras en paralelo,
multi-computadoras y centralizados multiprocesadores.
Como el nombre lo indica, multi-computadoras es una computadora paralela construida en base de
mltiples computadoras y una interconexin de red. El procesador en diferentes computadoras
interacta pasando mensajes a cada una de las otras.
En contraste, un centralizado multiprocesador (tambin llamado simtrico multiprocesador o SMP)
es un mas alto sistema integrado en el cual todos los CPUs comparten acceso a una simple global
memoria. Esta memoria compartida soporta comunicacin y sincronizacin de procesos alojados.
Paralela programacin es la programacin en un lenguaje que permite explcitamente indicar como
diferentes porciones de la computacin pueden ser ejecutados concurrentemente por diferentes
procesos
OpenMP, es una interfaz de programacin de aplicaciones (API) para la programacin de
multiprocesos y de memoria compartida en mltiples plataformas. Permite aadir concurrencia a
los programas escritos en C, C++ y Fortran sobre la base del modelo de ejecucin fork-join. Est
disponible en muchas arquitecturas, incluidas las plataformas de Unix y de Microsoft Windows. Se
compone de un conjunto de directivas del compilador, rutinas de biblioteca, y variables de entorno
que influyen el comportamiento en tiempo de ejecucin.
El OpenMP, es definido en conjuncin por un grupo de proveedores de hardware y de software de
gran renombre, es un modelo de programacin portable y escalable que proporciona a los
programadores una interfaz simple y flexible para el desarrollo de aplicaciones paralelas para las
plataformas que van desde las computadoras de escritorio hasta las supercomputadoras. Una
aplicacin construida con un modelo de programacin en paralelo hbrido se puede ejecutar en un
cluster de computadoras utilizando ambos OpenMP y MPI, o ms transparentemente a travs de
las extensiones de OpenMP para los sistemas de memoria distribuida.





- 27 -

4.4 Modelo y herramientas usados en el proyecto.
El OpenMP C y C++ APIs permite escribir aplicaciones que efectivamente usen mltiples
procesadores. Visual C++ soporta la versin OpenMP 2.0 Standard, el cual forma parte de Visual
Studio 2008, versin que se genero el cdigo para que la aplicacin soporte paralelismo.
Directive Description
atomic Specifies that a memory location that will be updated atomically.
barrier Synchronizes all threads in a team; all threads pause at the barrier, until all threads execute
the barrier.
critical Specifies that code is only executed on one thread at a time.
flush (OpenMP) Specifies that all threads have the same view of memory for all shared objects.
for (OpenMP) Causes the work done in a for loop inside a parallel region to be divided among threads.
master Specifies that only the master threadshould execute a section of the program.
ordered (OpenMP Directives) Specifies that code under a parallelized for loop should be executed like a sequential loop.
parallel Defines a parallel region, which is code that will be executed by multiple threads in parallel.
sections (OpenMP) Identifies code sections to be divided among all threads.
single Lets you specify that a section of code should be executed on a single thread, not necessarily
the master thread.
threadprivate Specifies that a variable is private to a thread.

parallel. Define una regin paralela, la cual es el cdigo que ser ejecutado por mltiples hilos en
paralelo.
#pragma omp parallel [clauses]
{
block de codigo
}
Donde,
clause (optional)
Cero o mas clausulas.
En seguida se muestran las clusulas soportadas por la directiva parallel.
copyin
default (OpenMP)
firstprivate
if (OpenMP)
num_threads
private (OpenMP)
reduction
shared (OpenMP)

- 28 -

Ejemplo de uso de la directiva parallel:
// omp_parallel.cpp
// compile with: /openmp
#include <stdio.h>
#include <omp.h>

int main! {
#pragma omp parallel num_threads"!
{
int i # omp_get_thread_num!$
print%_s&'ello %rom thread (d)n&* i!$
}
}























- 29 -
5 Criptografa.

5.1 Introduccin
Criptologa (del griego krypto, oculto, y graphos, escribir, literalmente
escritura oculta) tradicionalmente se ha definido como la parte de la criptologa que se ocupa de
las tcnicas, bien sea aplicadas al arte o la ciencia., que alteran las representaciones lingsticas
de mensajes, mediante tcnicas de cifrado y/o codificado, para hacerlos ininteligibles a intrusos
(lectores no autorizados) que intercepten esos mensajes. Por tanto el nico objetivo de la
criptografa era conseguir la confidencialidad de los mensajes. Para ello se diseaban sistemas de
cifrado y cdigos. En esos tiempos la nica criptografa que haba era la llamada criptografa
clsica.
La aparicin de las Tecnologas de la Informacin y comunicacin y el uso masivo de las
comunicaciones digitales han producido un nmero creciente de problemas de seguridad. Las
transacciones que se realizan a travs de la red pueden ser interceptadas. La seguridad de esta
informacin debe garantizarse. Este desafo ha generalizado los objetivos de la criptografa para
ser la parte de la criptografa que se encarga del estudio de los algoritmos, protocolos (se les llama
protocolos criptogrficos) y sistemas que se utilizan para proteger la informacin y dotar de
seguridad a las comunicaciones y a las entidades que se comunican. Para ello los criptgrafos
investigan, desarrollan y aprovechan tcnicas matemticas que les sirven como herramientas para
conseguir sus objetivos.
Los grandes avances que se han producido en el mundo de la criptografa han sido posibles
gracias a los grandes avances que se ha producido en el campo de las matemticas y las ciencias
de la computacin.
Objetivos de la criptografa .La criptografa actualmente se encarga del estudio de los algoritmos,
protocolos y sistemas que se utilizan para dotar de seguridad a las comunicaciones, a la
informacin y a las entidades que se comunican. El objetivo de la criptografa es disear,
implementar, implantar, y hacer uso de sistemas criptogrficos para dotar de alguna forma de
seguridad. Por tanto se ocupa de proporcionar:
Confidencialidad. Es decir garantiza que la informacin est accesible nicamente a
personal autorizado. Para conseguirlo utiliza cdigos y tcnicas de cifrado.
Integridad. Es decir garantiza la correccin y completitud de la informacin. Para
conseguirlo puede usar por ejemplo: funciones de Hash criptogrficas MDC, protocolos de
compromiso de bit, o protocolos de notorizacin electrnica.
No repudio. Es decir proporciona proteccin frente a que alguna de las entidades
implicadas en la comunicacin, pueda negar haber participado en toda o parte de la
comunicacin. Para conseguirlo puede usar por ejemplo firma digital.
Autenticacin. Es decir proporciona mecanismos que permiten verificar la identidad del
comunicante. Para conseguirlo puede usar por ejemplo: funcin hash criptogrfica MAC o
protocolo de conocimiento cero.
Soluciones a problemas de la falta de simultaneidad en la telefirma digital de contratos.
Para conseguirlo puede usar por ejemplo: protocolos de transferencia inconsciente.
Un sistema criptogrfico es seguro respecto a una tareas si un adversario con capacidades
especiales no puede romper esa seguridad, es decir, el atacante no puede realizar esa tarea
especfica.

- 30 -

La criptografa de Triple DES se llama al algoritmo que hace triple cifrado de tipo DES. Tambin es
conocido como TDES o 3DES, fue desarrollado por IBM en 1998.
Algoritmo. No llega a ser un cifrado mltiple, porque no son independientes todas las subclases.
Este hecho se basa en que DES tiene la caracterstica matemtica de no ser un grupo, lo que
implica que si se cifra el mismo bloque dos veces con dos claves diferentes se aumenta el tamao
efectivo de la clave.
La variante ms simple del Triple DES funciona de la siguiente manera:

Donde es el mensaje a cifrar y , y las respectivas claves DES. En la variante 3TDES
las tres claves son diferentes; en la variante 2TDES, la primera y tercera clave son iguales.
Seguridad. Cuando se descubri que una clave de 56 bits no era suficiente para evitar un ataque
de fuerza bruta, TDES fue elegido como forma de agrandar el largo de la clave sin necesidad de
cambiar de algoritmo de cifrado. Este mtodo de cifrado es inmune al ataque por encuentro a
medio camino, doblando la longitud efectiva de la clave (112 bits), pero en cambio es preciso
triplicar el nmero de operaciones de cifrado, haciendo este mtodo de cifrado muchsimo ms
seguro que el DES. Por tanto, la longitud de la clave usada ser de 192 bits, aunque como se ha
dicho su eficacia solo sea de 112 bits.
Usos. El Triple DES est desapareciendo lentamente, siendo reemplazado por el algoritmo AES.
Sin embargo, la mayora de las tarjetas de crdito y otros medios de pago electrnicos tienen como
estndar el algoritmo Triple DES (anteriormente usaban el DES). Por su diseo, el DES y por lo
tanto el TDES son algoritmos lentos. AES puede llegar a ser hasta 6 veces ms rpido y a la fecha
no se ha encontrado ninguna vulnerabilidad.
Base 64, es un sistema de numeracin posicinala que usa el 64 como base. Es la mayor
potencia de dos que puede ser representada usando nicamente los caracteres imprimibles de
ASCII. Esto ha propiciado su uso para codificacin de correos electrnicos, PGP y otras
aplicaciones. Todas las variantes famosas que se conocen con el nombre de Base64 usan el rango
de caracteres A-Z, a-z y 0-9 en este orden para los primeros 62 dgitos, pero los smbolos
escogidos para los ltimos dos dgitos varan considerablemente de unas a otras. Otros mtodos
de codificacin como UUEncode y las ltimas versiones de binhex usan un conjunto diferente de
64 caracteres para representar 6 dgitos binarios, pero stos nunca son llamados Base64.

5.2 TDES y base 64, para el manejado en el proyecto.
Para el proyecto se utilizo el algoritmo TDES con una llave de bits para garantizar la
seguridad de la informacin. Tambin se usa el algoritmo de base 64 para garantizar la conversin
de caracteres entres el sistema distribuido y el Host, debido a que uno usa un mapa de caracteres
ASCII y el otro EBCDIC, respectivamente.




- 31 -

6 Sistema de comunicacin TCP-IP para aplicaciones cliente a Mainframe-Host (SICOTIP).
6.1 Requerimientos.
Antecedentes y situacin actual.
Las aplicaciones de una institucin financiera, en su canal de atencin telefnica, el cual
esta basada su comunicacin con el cliente, en la interaccin va telefnica. Estas aplicaciones
distribuidas denominadas GUIs, IVRs y CTI, las cuales tendrn enlace con el sistema principal
MainFrame, donde se centraliza la informacin de las cuentas de los clientes y toda la informacin
necesaria relacionada con estos.
La aplicacin GUI de atencin telefnica que usaran los asesores, que estarn en los Call Centers
(internos o de origen externo, outsoursing), utilizaran las aplicaciones distribuidas para
proporcionar los servicios requeridos por los clientes, esto cuando a los asesores les llega la
llamada.
Los IVRs son los equipos de audio-respuesta, los cuales dan arribo de atencin a mas del 80% de
las llamadas a nivel nacional de los clientes y no clientes de la empresa Bancaria, los cuales
requieren algn servicio a travs de las llamadas telefnicas.
CTI, es el sistema automtico que monitorea y da seguimiento lgico a la llamada durante su
recorrido en la red de enlace telefnico (integra la telefona y call centres).
Las aplicaciones GUI en muchas variantes, dependiendo la plataforma de implementacin, se
comunican al sistema central a travs de la red interna de un banco. Todava ah empresas que
usan un software de emulacin de terminales 3270 instalado en las PCS y usando la tcnica de
screen scraping para capturar las pantallas tipo Host (24X80 caracteres) y transformarlas a las
ventanas de la IG de los asesores.
Este medio de enlace es lento debido a las diferentes transformaciones de informacin, por lo que
el tiempo de la llamada se incrementa siendo superior a 3 minutos en promedio total, y superior a 5
segundos por solicitud al Host. Estos tiempos incrementen el costo de la llamada, reflejndose en
un gasto excesivo del mismo.
Por lo que la propuesta en este proyecto para algn banco que lo requiera, y que de disminuir los
tiempos de la llamada, donde esto implica disminucin del gasto de la misma. Para esto se realizo
el anlisis y planteando la situacin actual de alguna empresa bancaria, se propone la solucin por
medio de comunicacin de sockets tipo TCP.
En base a esto, se procedi a realizar el anlisis del problema, encontrando de el principal
problema es el medio de comunicacin hacia el Host. Entre las propuestas de solucin se
encontraron las dos siguientes:
MQ Series, software propiedad de IBM el cual proporciona un medio de comunicacin asncrono
entre diferentes plataformas. Actualmente ya es una solucin estndar en unas empresas. El
problema principal es costo de las licencias por equipo, as mismo la incompatibilidad con otras
plataformas de software propietario en los IVRs. Otro punto, es el tiempo de comunicacin, el cual
no disminuye significativamente como para considerarse la solucin ideal.
Uso de Sockets TCP-IP, siendo el medio mas directo de comunicacin entre redes de datos de tipo
TCP-IP. En la arquitectura de ASTA sobre Host, recin se tiene la solucin de comunicacin de
Socket denominado CICS Bridge TCP-IP, donde las pruebas iniciales entre equipos distribuidos y
el MainFrame tienen tiempos de respuesta de 3 segundos por solicitud. Este mismo esquema en

- 32 -
Host ya cuenta con un servicio de encripcin bajo TDES y Base 64, para que garantice un canal
mas seguro.
Estas dos opciones se presentaron al negocio, indicando que la solucin bajo sockets se requiere
un desarrollo de un modulo para las IGs, as como la adecuacin de las mismas para que puedan
comunicarse bajo este protocolo. El rea de negocio estuvo de acuerdo con el desarrollo y
modificacin, procediendo a la creacin del requerimiento requisitazo y autorizado, ya con el
presupuesto necesario para la solucin.
Por lo anterior, se determino que la solucin ms idnea para el problema es implementarla sobre
un esquema tipo Sockets TCP-IP en distribuido y CICS Bridge Sockets TCP-IP en Host ASTA. De
esto se determina la construccin de un modulo que permita a las aplicaciones distribuidas
concertarse por TCP-IP hacia el Host. Por lo que nace la necesidad de crear la aplicacin
SICOTIP.
Presentacin General.
Se requiere mejorar los tiempos de respuesta de las diferentes aplicaciones distribuidas del
canal de Atencin Telefnica de una empresa Financiera, para comunicarse al sistema central y
disminuir el tiempo total de la llamada de los clientes que accedan a este canal. La solucin
necesita poder contar de un medio que garantice la integridad y seguridad de la informacin (canal
seguro), as como un medio para minimizar las adaptaciones de comunicacin con entidades
externas que provean el servicio de atencin telefnica (Call Center externos), cuando las
necesidades del negocio lo requieran.
Cliente.
Canal de comunicacin de acceso de clientes de un Banco, por va telefnica. A travs de
los nmeros locales o del servicio 01800 a nivel nacional.
Metas.
Mejorar el tiempo de respuesta significativamente al que se cuenta actualmente en el
servicio de atencin telefnica. Mejorar la satisfaccin de atencin y servicio de los clientes o no
clientes por el Banco a travs del medio telefnico. Disminuir el costo de las llamadas, para que en
base a esto poder ofrecer ms opciones o promociones de productos a travs de este canal, que
implica mayores ventas.
Seguridad de la informacin de los clientes en el canal de Atencin Telefnica. La solucin debe
soportar la transaccionalidad de llamadas tanto horarios pico y no pico.

Funciones del sistema.
El sistema permitir disminuir el tiempo de respuesta de comunicacin hacia el Host, por lo que
esto implica disminucin de tiempo total de la llamada.
El sistema permitir un canal seguro para la informacin de los clientes, que viaja por este medio.
El sistema contara con un protocolo estndar de comunicacin que permita comunicarse
adecuadamente con el MainFrame o sistema central.




- 33 -
El sistema aprovechara o explotara en la medida de lo posible la infraestructura para manejo de
concurrencia o paralelismo, as como balanceo de cargas. Como beneficio del performance de la
aplicacin.
Facilitar el enlace y reglas de firewall, para nuevas empresas o call centers externos que por
necesidad del negocio necesiten conectarse al Host por este medio y aplicaciones.

Atributos del sistema.

Atributo Detalles
Tiempo de respuesta Meno al actual. Menor a 5 segundos por transaccin.
Uso de los estndares del Banco Manejo de Sockets TCP-IP, uso de protocolo PS9.
Seguridad Encripcin TDES y Base 64
Tolerancia a fallas La solucin contara con time outs mximos, en puntos
finales de Distribuido y host, para que en base a eso se
determine acciones a seguir. En transacciones no criticas,
como consultas, se permitir reenviar 2 o 3 intentos de
peticin, en caso de no xito se dar por terminada la
solicitud informando del error retornado. En transacciones
crticas o contables solo se realizara un intento, en caso de
error o no respuesta se informara y se informara al cliente o
asesor para que se tome a juicio la accin a seguir.
Plataforma Windows XP, 7. para el servicio en las PCs clientes
Windows Server. Para el servicio Proxy
SO-390, ASTA, CICS Bridge TCP-IP. En MainFrame.
Facilidad de enlace a entidades externas Contara con un modulo de Proxy que permita conectar a
cualquier entidad externa comunicarse o adaptarse
fcilmente con el Banco.












- 34 -

6.2 Anlisis.
Casos de Uso.
Diagrama de casos de uso.













Modelo Conceptual inicial.













- 35 -



Casos esenciales de uso.
A continuacin se indica la clasificacin de los casos de uso identificados para el proyecto:
Casos primarios de uso.
Envi de mensajes
Casos secundarios de uso.
Servicio Proxy de envi de mensajes.
Casos opcionales de uso.
Encripcin de mensajes.




















- 36 -
Caso de uso: Envi de mensajes.
Actores: IVR, CTI, Interfaz Grafica de usuario, Call Center Externo.
Propsito: recibir mensajes provenientes de alguna de las aplicaciones de Atencin Telefnica y
enviar este va sockets al destino Host. Esperar la respuesta del Host y regresarla a la aplicacin
origen.
Descripcin: Alguna de las aplicaciones de Atencin Telefnica de una empresa Bancaria genera
un mensaje de solicitud de informacin hacia el Host. El mensaje lo recibe el servicio de
comunicacin tcp-ip, donde el mensaje es validado. Si esta activa la opcin de encripcin,
entonces el mensaje es encriptado con la encripcin Tripe Des. El mensaje resultante es pasado a
la codificacin de base 64. Posteriormente, el mensaje es armado a usar protocolo PS9. El
mensaje resultante es enviado por sockets al Host. En su defecto si el solicitante del mensaje es
una entidad externa (call center outsourcing) entonces el mensaje es pasado primero a servidor
Proxy, el cual tomara el mensaje y lo retransmitir al Host. El mensaje de respuesta es tratado a la
inversa, esto es, se valida el mensaje de salida en PS9. Si esta activo el uso de criptografa, se
valida la salida y se quita la codificacin base 64, posterior se desencripta usando Tripe DES. El
mensaje resultante se retorna a la aplicacin solicitante original.
Tipo: Primario y esencial.
Referencias cruzadas:
Funciones:
Casos de uso: el caso de uso envi de mensajes, usara el caso de uso encriptar mensaje,
en caso necesario. Tambin si el call center es externo, se usara el caso de uso servicio Proxy.
Curso normal de los eventos.
Accin de los actores Respuesta del sistema
La aplicacin GUI/IVR/CTI enva la cadena de la solicitud al
Host al servicio TCP-IP
Recibe el mensaje, realiza validaciones bsicas del formato
de la cadena. Si esta correcta la cadena, y si esta activo la
opcin de encripcin, entonces enva el mensaje al caso de
uso encriptar. Si el mensaje fue encriptado correctamente o
si el mensaje no necesito encripcin, entonces se formatea
el mensaje en protocolo PS9. El mensaje generado se enva
al Host a travs de sockets TCP o si la aplicacin origen es
entidad externa, entonces el mensaje es trasmitido tambin
va sockets a servicio Proxy.
El servicio espera la respuesta, si se recibi el mensaje, se
valida. En caso de ser correcto, se deformatea quitando
PS9.
Si el mensaje esta encriptado se enva a caso de uso
encripcin, del mensaje resultante se regresa a la aplicacin
origen.
LA aplicacin recibe el mensaje de respuesta, donde si la
respuesta es correcta se visualiza. En caso de ser un
mensaje de error, se muestra una descripcin adecuada al
asesor o al cliente

Este mismo proceso se repite tantas veces como
solicitudes realice la aplicacin origen.




- 37 -

Caso de uso: Servicio Proxy de envi de mensajes.
Actores: Call Center Externo usando la GUI.
Propsito: recibir mensajes provenientes de alguna de las aplicaciones de Atencin Telefnica y
retrasmitir los mensajes al destino Host. Esperar la respuesta del Host y regresarla a la aplicacin
origen.
Descripcin: Las aplicaciones GUI que estn instaladas en Call Centers Outsoursing envan el
mensaje con la solicitud al Host al Servicio TCP-IP, este servicio lo procesa y lo reenva al servidor
Proxy, el cual tomara el mensaje y lo retransmitir al Host. Se espera respuesta del Host, en caso
de haber, se retransmite la trama a la Pc cliente origen.
Tipo: Primario y esencial.
Referencias cruzadas:
Funciones:
Casos de uso: el mensaje recibido es originado por el caso de uso envi de
mensajes.
Curso normal de los eventos.
Accin de los actores Respuesta del sistema
La aplicacin GUI enva la cadena de la solicitud al Host al
servicio TCP-IP
Recibe el mensaje, procesa el mensaje y el mensaje
resultante lo retransmite al servicio Proxy.
El servicio Proxy recibe el mensaje del servicio envi de
mensajes TCP-IP y lo retransmite al Host. Espera la
respuesta del Host, esta respuesta es retornada al servicio
envi de mensajes TCPIP original para su validacin e
interpretacin.
LA aplicacin recibe el mensaje de respuesta, donde si la
respuesta es correcta se visualiza. En caso de ser un
mensaje de error, se muestra una descripcin adecuada al
asesor o al cliente

Este mismo proceso se repite tantas veces como
solicitudes realice la aplicacin origen.










- 38 -

Caso de uso: Encripcin de mensajes.
Actores: Servicio envi de mensajes TCP-IP.
Propsito: recibir mensajes provenientes del servicio envi de mensajes TCP-IP, codificarlos en
Tripe DES y al resultado codificarlo a base 64.
Descripcin: recibir mensajes provenientes del servicio envi de mensajes TCP-IP y realizar la
codificacin del mensaje usando el cifrado Tripe DES. Si el resultado es correcto, el mensaje
obtenido se procesa, convirtindolo a base 64. El mensaje resultante es retornado al servicio de
envi de mensajes TCP-IP que origino la solicitud
Tipo: Primario y esencial.
Referencias cruzadas:
Funciones:
Casos de uso: el mensaje recibido es originado por el caso de uso envi de mensajes.
Curso normal de los eventos.
Accin de los actores Respuesta del sistema
La aplicacin SDAT VB o Ncar enva la cadena de la
solicitud al Host al servicio TCP-IP
Recibe el mensaje, se enva el mensaje a caso de uso
encripcin de mensajes.
El mensaje recibido se encripta usando Tripe Des. El
resultado se codifica en base 64. Se retorna el mensaje al
servicio envi de mensajes.
El servicio de envi de mensaje continua el flujo de
trasmisin va sockets
El mensaje se recibe del Host Si el mensaje es valido y en formato PS9, se deformatea.
Del mensaje resultante, si esta encriptado, se enva a
desencriptar. Este mensaje, se quita la codificacin Base 64,
despus se desencripta usando Tripe DES.
El mensaje resultante se regresa al servicio de envi de
mensajes TCP-IP para que continu el flujo de respuesta.










- 39 -

Diagrama de Actividades.





























- 40 -
6.3 Diseo.

Diagrama de secuencia del sistema.








- 41 -


Contratos de operaciones.
Sistema SICOTIP
envioMensaje(mensajeEntrada, tamaoEntrada, mensajeSalida, tamaoSalida)
asignaParametros(IP, Puerto, usoEncripcion)
generaSiguienteTrama(mensajeRespuesta)


Nombre: asignacionParamentros( IP:string, Puerto: entero, usoEncripcion: Boolean)
Responsabilidades: definir y/o inicializar los valores de los atributos: IP, puerto y usoEncripcion,
para su posterior uso.
Tipo: Sistema.
Salida:
Precondiciones:
Se cuenta con los valores a asignar a los atributos de IP, Puerto y usoEncripcion.

Poscondiciones:
Se recibir el valor del atributo IP
Se asignara el valor del atributo Puerto
Se asignara el valor del atributo usoEncripcion.



Nombre: envioMensaje(mensajeEntrada, tamaoEntrada, mensajeSalida, tamaoSalida)
Responsabilidad: recibe el mensaje que se requiere enviar al sistema central Host. Si el atributo
usoEncripcion tiene valor Trae, entonces se encripta el mensaje. El mensaje encriptado o no se
formatea en PS9 y se enva a Host usando sockets.
Tipo: Sistema.

Salida:
Precondiciones:

- 42 -
Se contara con el mensaje a enviar a Host, el cual tambin contara con los datos
necesarios para la solicitud de la informacin al rea central.
Poscondiciones:
Se creara la instancia de la clase sevicioTCP-IP.
Se recibir y validara el mensaje de entrada.
Si el atributo usoEncripcion ser con valor de verdad, entonces se creara instancia de la
clase Cripto, y se relacionara a la instancia de la clase servicioTCP-IP.
Se enviara el mensaje encriptar(mensaje) a la instancia servicioTCP-IP.
Se creara la instancia de las clases TripeDes y Base64.
Se relacionara las instancias de las clases TripeDes y Base64 a la instancia de la clase
Cripto.
Se enviar mensaje generaCripto() a la instancia de la clase TripeDes.
Se enviar mensaje codificar() a la instancia de la clase Base64.
Se crear la instancia de la clase PS9. y se relacionara a la instancia de la clase
servicioTCP-IP.
Se enviara mensaje armaEntrada(trama) a la clase PS9.
Se creara instancia de las clases MD, IH y ME. Se vinculara con la instancia de la clase
PS9.
Se mandara mensaje genera(trama) a las instancias de las clases MD, IH y ME.
Se creara una instancia de la clase Thread. Para la generacin de un hilo de ejecucin. Se
relacionara a la clase servicioTCP-IP.
La instancia de la clase Thread creara una instancia de la clase Socket, y se vinculara a la
primera instancia mencionada.
Se enviara mensaje send(mensaje) a la instancia Socket para enviar la trama por el socket
TCP al Host o al servicio Proxy.
Se esperara resultado del Socket por el mensaje recv().
El mensaje de respuesta se deformateara con la instancia de la clase PS9.
Si el mensaje es de topo encriptado. Se desencriptara el mensaje con la instancia de la
clase Cripto.
El mensaje resultante se retornara a la instancia de la aplicacin origen.





- 43 -
Diagrama de clases.




















- 44 -

Diagrama de interaccin.













- 45 -

Diagrama de componentes
















- 46 -




6.4 Construccin.
Diagrama de Bloque correspondiente a la construccin del los dos mdulos del sistema SICOTIP.












CConexHost
WinSock
Ccliente::obj
cte
CBase64::objB
ase64
Csockbase
CServidor
IConexHost
TDESIVR
Aplicacin Conexion:

- 47 -






Debido a lo extenso de el cdigo fuente del sistema se incluye en el Anexo A.








CParametros
WinSock
Ccliente::objcte
CServerTCPDlgAutoProx
y
Csockbase
CServerTCPDlg
CServerTCPApp
CDialog
CWinApp
CCmdTarget CAboutDlg
CCServidor::servidor
Aplicacin ServerTCP:

- 48 -


6.5 Conclusiones y resultados.
Al finalizar la construccin de los dos mdulos que componen el proyecto, el modulo cliente y el
servidor Proxy-TCP, se procedi a realizar pruebas individuales, despus pruebas nter sistemas.
Posteriormente se realizaron pruebas de volumen en un ambiente de desarrollo ya comunicando
las aplicaciones distribuidas con el Host, se fueron presentando algunas incidencias pero se fueron
resolviendo sin problema.
Para realizar la instalacin e implementacin de las aplicaciones en ambiente de produccin, se
realizo de manera controlada sin presentar algn problema. Inicialmente se realizo un piloto,
integrando sobre este esquema solo una clula, la cual consiste una agrupacin de 10 asesores
telefnicos, sin presentarse algn problema. Posteriormente de un perodo de prueba se fueron
integrando ms clulas, hasta integrar bajo este esquema dos centros de llamada (call centers)
con 300 asesores aproximadamente.
As tambin, se realizo otro piloto para integrar la aplicacin cliente de conexin sockets, para un
IVR, y se fueron integrando mas, hasta integrar los 21 IVRs que se tienen en tres sites, donde cada
IVR cuenta con 90 puertos. Donde cada puerto es equivalente, a una lnea en la cual puede recibir
una llamada, por lo tanto, cada IVR puede recibir simultneamente 90 llamadas al mismo tiempo.
Despus de un par de meses de uso de la aplicacin, en el servidor Proxy, se detecto una
incidencia. La cual ocasionaba que se cruzara la informacin, en la retransmisin de la misma en la
respuesta del Host al servidor Proxy y a su vez del servidor a las aplicaciones cliente donde se
mandaba la peticin original. Despus de un anlisis y la integracin de un log de operaciones de
esta aplicacin, se detecto el problema y en esta ultima versin del cdigo, ya se cuenta con esta
ultima correccin. Donde hasta el momento se sigue trabajando sin problema con las aplicaciones
que estn bajo este esquema.
En la parte del modulo de encripcin, solo se usa para las aplicaciones de Interfaz grafica (Call
Center) debido a que esta pendiente la integracin de este para los IVRs. Para esto, se esta
planeando realizar un piloto, con el fin de determinar el performance y poder medir el tiempo de
respuesta, y saber que no afecte al tiempo actual de respuesta.
En el caso de que se tenga algn problema, o sea, que afecte al performance actual. Entonces, se
tendr que pensar en la alternativa de solucin, como puede ser el Cripto AES. Donde la idea, es
de poder remplazar al de TDES, que en teora es mucho ms rapido y seguro. Se tendra
contemplado desarrollar este modulo, en una siguiente etapa, como un proyecto adoptativo
evolutivo, o sea integrando nueva funcionalidad al sistema actual.









- 49 -

7 Referencias.

Titulo: Introduction to the New Mainframe: z/OS Basics
Autores: Mike Ebbers, Wayne OBrien, Bill Ogden.
Editorial: International Business Machines Corporation 2005, 2006.
Titulo: ASTA. Manual de Usuario, Arquitectura Clsica.
Editorial: Alnova
Titulo: Curso de Formacin de Arquitectura Altamira para desarrolladores
Editorial: Andersen Consulting.
Titulo: MSDN, Visual Studio 2008.
Editorial: Microsoft
Titulo: UML y Patrones. Introduccin al anlisis y diseo orientado a objetos.
Autor: Craig Larman
Editorial: Pearson, Prentice may.
Titulo: Parallel programming in c with MPI and OPENMP
Autor: Michael J. Quinn
Editorial: McGraw Hill, Higher Education.




































- 50 -

Anexo A. Cdigo fuente.
Aplicacin Conexion:
// ConexHost.h : Declaration of the CConexHost

#ifndef __CONEXHOST_H_
#define __CONEXHOST_H_

#include "resource.h" // main symbols

/////////////////////////////////////////////////////////////////////////
////
// CConexHost
class ATL_NO_VTABLE CConexHost :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CConexHost, &CLSID_ConexHost>,
public IConexHost
{
public:
CConexHost()
{
}

DECLARE_REGISTRY_RESOURCEID(IDR_CONEXHOST)

DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CConexHost)
COM_INTERFACE_ENTRY(IConexHost)
END_COM_MAP()

// IConexHost
public:
BOOL InsertSubCadCadena(char *subcad, char *cadena, int posini, int
numcaract);
BOOL ObtenSubCadena(char *cadfuente, char *subcaddestino, int
posini, int numcarateres);
int ProcesaEncripcion(char * msgEntrada, char *MsgSalida, int
TipoSolicitud, int *TamSalida);
BOOL GeneraConsecutivoStr4(char *pcadCosecutivo, int pValorActual);
BOOL CountCadena1(char* cadfuente, int * numcarateres);

//STDMETHOD(EnviaMensajeHost)(/*[out,retval]*/ unsigned char*
nDato, unsigned char* ndirIP, int * nPuerto, int * lpnResultado);
STDMETHOD(EnviaMensajeHost)(/*[out,retval]*/ unsigned char* nDato,
unsigned char* nSalida, int * nLonSal, unsigned char* ndirIP, int *
nPuerto, int nTipo, int * lpnResultado);
STDMETHOD(EnviaMsjHostEncripto)(/*[out,retval]*/ unsigned char*
nDato, unsigned char* nSalida, int * nLonSal, unsigned char* ndirIP, int
* nPuerto, int nTipo, int * lpnResultado);
STDMETHOD(ArmaEnvioMEPseudoConversSG_SC)(/*[out,retval]*/ unsigned
char* nStrEntrada, unsigned char* nStrSalidaME, int * nLongTrama, int *
lpnResultado);
STDMETHOD(CountCadena)(/*[out,retval]*/ unsigned char* cadfuente,
int * numcarateres, int * lpnResultado);

- 51 -
STDMETHOD(Cripto)(/*[out,retval]*/ unsigned char* nDato, unsigned
char* nSalida, int * TipoSolicitud, int *TamSalida, int * lpnResultado);
char mMensaje[32000];
};

#endif //__CONEXHOST_H_

// ConexHost.cpp : Implementation of CConexHost
#include "stdafx.h"
//#include <afxsock.h>
#include "socstr.h"
#include "Conexion.h"
#include "ConexHost.h"
#include "TDESIVR.h"
#include "Base64.h"

/////////////////////////////////////////////////////////////////////////
////
// CConexHost


//typedef ULONG (CALLBACK* LPFNDLLFUNC1)(char*, char*, int*, char*);
//typedef ULONG (CALLBACK* LPFNDLLFUNC1)(char*, char*, int*, char*);


STDMETHODIMP CConexHost::EnviaMensajeHost(unsigned char* nDato, unsigned
char* nSalida, int * nLonSal, unsigned char* ndirIP, int * nPuerto, int
nTipo, int *lpnResultado )
{

// Para Llamar la Dll
//HINSTANCE hDLL; // Handle to DLL
//LPFNDLLFUNC1 lpfnDllFunc1; // Function pointer
//DWORD dwParam1;
//UINT uParam2, uReturnVal;
//char MsgEnt[161], MsgSal[161];


//Implementacion de la conenexion a Host
int Error=0;
int Enviados=0;
int Recibidos=0;
int Longitud=0;
int indice =0;
//int nSocketType = SOCK_STREAM,lintBub;



//DEFINICION DE IP Y PUERTO
LPCTSTR lpszSocketAddress = (char *)ndirIP; //DESARROLLO Y TEST
//LPCTSTR lpszSocketAddress = "150.50.102.15"; //DESARROLLO Y TEST
//LPCTSTR lpszSocketAddress = "150.100.246.44"; //PRODUCCION
//LPCTSTR lpszSocketAddress = "150.50.102.15"; //Desarrollo

UINT nSocketPort=*nPuerto;
//UINT nSocketPort=3550; //Produccion

- 52 -
//UINT nSocketPort=3555; //Produccion

//UINT nSocketPort=3224; //Test

//UINT nSocketPort=3216; //puerto Desarrollo


//char Mensaje[50000]="";
char MensajeRecib[32000]="";
char *pmensaje, *ptrRespuesta=MensajeRecib;
char NumSesion[9]="";
char *lMensajeEntrada=(char *)nDato;
char *lMensajeSalida=(char *)nSalida;
char MensajeError[100]="",lNumError[20]="";
pmensaje=lMensajeEntrada;




//AfxMessageBox(lMensajeEntrada,MB_YESNO);

strcpy((char *)nSalida,"");

WORD wVersionRequested;
WSADATA wsaData;
int err;
BOOL respuesta=false;
wVersionRequested = MAKEWORD( 2, 2 );

//BOOL AfxSocketInit( WSADATA* lpwsaData = NULL );
//respuesta= AfxSocketInit( &wsaData);


err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return S_OK;
}


/* Confirm that the WinSock DLL supports 2.2.*/
/* Note that if the DLL supports versions greater */
/* than 2.2 in addition to 2.2, it will still return */
/* 2.2 in wVersion since that is the version we */
/* requested. */

if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
WSACleanup( );
return S_OK;
}



//************************************
/* The WinSock DLL is acceptable. Proceed. */

- 53 -
//************************************

CCliente objcte(lpszSocketAddress,nSocketPort);

//************Validacion si uso de Encripcion******
char MsgSalCripto[32000]="", MsgSub1[32000]="",
MsgSub2[32000]="",strLongitud[10]="";
int ResultCripto=0, tamCripto=0,i=0, *ptrTamCripto=&tamCripto;
char *ptrSub2=MsgSub2;
char tmpcadena[10]="";

for( i=0; i<32000; i++)
{*(nSalida+i)=' ';
}
if (nTipo==0)//Procesa sin Encriptacion
{
Longitud=strlen(lMensajeEntrada);
//objcte.PedirServicio(pmensaje,lMensajeSalida,&Longitud);
objcte.PedirServicio(pmensaje,lMensajeSalida,&Longitud);
for( i=0; i<Longitud; i++)
{if(*(lMensajeSalida+i)=='\0' || *(lMensajeSalida+i)==128)
*(lMensajeSalida+i)=' ' ;
}

/*
_itoa( Longitud,tmpcadena, 10 );
AfxMessageBox(_T(tmpcadena) ,MB_YESNO);
AfxMessageBox(_T(lMensajeSalida) ,MB_YESNO);
*/
nSalida=(unsigned char*) lMensajeSalida;
*nLonSal=Longitud;
}
else //Procesa con Cripto
{
strcpy(MsgSub1,"");
ObtenSubCadena(pmensaje, MsgSub1, 0, 225);
if(nTipo==1)
pmensaje=pmensaje+225;

tamCripto=strlen(pmensaje);
//AfxMessageBox(_T(pmensaje) ,MB_YESNO);
//Realiza la encripvion de la trama ME

//ResultCripto=ProcesaEncripcion(pmensaje,MsgSalCripto,1,&tamCripto);

//Modificacion para que maneje encripcion y desencripcion

//ResultCripto=ProcesaEncripcion(pmensaje,lMensajeSalida,1,&tamCripto);


ResultCripto=ProcesaEncripcion(pmensaje,lMensajeSalida,nTipo,&tamCripto);
//Para fines de prueba, quitar cuando este ok
//nSalida=(unsigned char*) MsgSalCripto;
//AfxMessageBox(_T(lMensajeSalida) ,MB_YESNO);
return S_OK;
//Prueba directa de cripto


- 54 -


/*
ULONG uReturnVal=0;
//char MsgEnt[10000], MsgSal[10000], MngRetornado[32000],
Servicio[2];
char Servicio[2];
char *ptrServ=Servicio;
int *ptrLMsg, LongMens, tamMsg=0, tamMsgSal=0, i=0;
char tmpcadena[10]="";
ptrLMsg=&LongMens;


strcpy(Servicio,"E");
LongMens=strlen(pmensaje);

uReturnVal= TDESCipher(pmensaje, MsgSalCripto, ptrLMsg, Servicio);

//Realiza la cuenta de caracteres diferentes de blanco y cadena
null
tamCripto=0;
for(i=0;i<32000;i++)
{if(*(MsgSalCripto+i)==' ' || *(MsgSalCripto+i)=='\0')
break;

tamCripto++;
}
*(MsgSalCripto+i)='\0';
*/
//_ultoa( tamCripto,tmpcadena, 10 );
//AfxMessageBox(_T(tmpcadena) ,MB_YESNO);


pmensaje=lMensajeEntrada;

//AfxMessageBox(_T(MsgSalCripto) ,MB_YESNO);

InsertSubCadCadena(MsgSalCripto, MsgSub1, 225, tamCripto);

Longitud=225 + tamCripto;
strcpy(strLongitud,"");
//AfxMessageBox(_T(MsgSub1) ,MB_YESNO);

//Modificar la longitud de salida, anexando lo encriptado
_itoa((Longitud),strLongitud,10);
//AfxMessageBox(_T(strLongitud) ,MB_YESNO);
//char tmpcadena[10]=" ";
if(strlen(strLongitud)==1)
{ strcpy(tmpcadena,"0000");
strcat(tmpcadena,strLongitud);
strcpy(strLongitud,tmpcadena );
}
else
if(strlen(strLongitud)==2)
{
strcpy(tmpcadena,"000");
strcat(tmpcadena,strLongitud);

- 55 -
strcpy(strLongitud,tmpcadena );
}
else
if(strlen(strLongitud)==3)
{ strcpy(tmpcadena,"00");
strcat(tmpcadena,strLongitud);
strcpy(strLongitud,tmpcadena );
}
else
if(strlen(strLongitud)==4)
{ strcpy(tmpcadena,"0");
strcat(tmpcadena,strLongitud);
strcpy(strLongitud,tmpcadena );
}
else
//if(strlen(strLongitud)>5)
{ strcpy(strLongitud,"00000");
//Error de longitud
}
InsertSubCadCadena(strLongitud, MsgSub1, 9, 5);
//_ultoa( tamCripto,tmpcadena, 10 );
//AfxMessageBox(_T(strLongitud) ,MB_YESNO);

//AfxMessageBox(_T(MsgSub1) ,MB_YESNO);
//Envia Mensaje Ya encriptado
objcte.PedirServicio(MsgSub1,MsgSub2,&Longitud);

/*
Respuesta mensaje desencriptado:
Para reconocer que un mensaje viene desencriptado an este
parametrizado
como mensaje de entrada y salida encriptado, se va a reconocer
porque el
septimo caracter trae un 7 un 8. Ejemplos:
"<OH>26700000000900163</OH><OC>0000 SESION ASIGNADA 00005 IDAGRD
</OC>"
"<OH>26800000000900163</OH><ER>3200 ERROR DE SESIONAMIENTO CON EL
OWNER 0000005 IDAGRD
</ER>"
*/


//Valida que la respueta este desencriptada y retorna el mensaje
//if( (MsgSub2[6]=='7') || (MsgSub2[6]=='8') || (MsgSub2[6]=='2'))

if( (*(MsgSub2+6)=='7') || (*(MsgSub2+6)=='8'))
{ //nDato=(unsigned char*) MsgSub1;
//nSalida=(unsigned char*) MsgSub1;
Longitud=strlen(MsgSub2);
for( i=0; i<Longitud; i++)
{if (*(MsgSub2+i)=='/0')
break;
else
*(nSalida+i)=*(MsgSub2+i);
}
*(nSalida+i)='\0';
//nSalida=(unsigned char*) MsgSub2;

- 56 -
*nLonSal=Longitud;
//WSACleanup( );
return S_OK;
}


//Desencripta Respuesta que si este encriptada

strcpy(MsgSalCripto,"");
strcpy(MsgSub1,"");
for(i=0;i<32000;i++)
{MsgSub1[i]=' ';
MsgSalCripto[i]=' ';
}
ObtenSubCadena(MsgSub2, MsgSub1, 0, 26);
tamCripto=0;
ptrSub2=ptrSub2+26;
//AfxMessageBox(_T(MsgSub2) ,MB_YESNO);



ResultCripto=ProcesaEncripcion(ptrSub2,MsgSalCripto,2,&tamCripto);

InsertSubCadCadena(MsgSalCripto,MsgSub1,26,tamCripto);
//Tamao total de la trama de respuesta desencriptada
Longitud=26 + tamCripto;

//AfxMessageBox(_T(MsgSub2) ,MB_YESNO);
//AfxMessageBox(_T(MsgSub1) ,MB_YESNO);
FILE *stream;
char strFileName[100]="logcripto.txt";
if( (stream = fopen(strFileName, "a+" )) == NULL )
AfxMessageBox(_T("The file 'logcripto.txt' was not opened")
,MB_YESNO);
/*else
AfxMessageBox(_T("The file 'logcripto.txt' was opened")
,MB_YESNO);
*/
fprintf( stream, "%s\n\t", ptrSub2);
fprintf( stream, "%s\n\t", MsgSalCripto);


if( fclose( stream ) )
AfxMessageBox(_T("The file 'logcripto.txt' was not closed")
,MB_YESNO);


// nSalida=(unsigned char*) lMensajeSalida;
//for( i=0; i<Longitud; i++)
for( i=0; i<30000; i++)
{if (*(MsgSub1+i)=='/0')
break;
else
*(nSalida+i)=*(MsgSub1+i);
}
*(nSalida+i)='\0';
//Prueba de longitud

- 57 -
strcpy(strLongitud,"");
//_ultoa( tamCripto,strLongitud, 10 );
//AfxMessageBox(_T(strLongitud) ,MB_YESNO);

//nSalida=(unsigned char*) MsgSub1;
*nLonSal=Longitud;

}//************Fin ValidacionProceso de Encripcion**



//WSACleanup( );
return S_OK;
}

STDMETHODIMP CConexHost::EnviaMsjHostEncripto(unsigned char* nDato,
unsigned char* nSalida, int * nLonSal, unsigned char* ndirIP, int *
nPuerto, int nTipo, int *lpnResultado )
{

// Para Llamar la Dll
//HINSTANCE hDLL; // Handle to DLL
//LPFNDLLFUNC1 lpfnDllFunc1; // Function pointer
//DWORD dwParam1;
//UINT uParam2, uReturnVal;
//char MsgEnt[161], MsgSal[161];

/*
hDLL = LoadLibrary("D:\\memo\\PruebasTCPIP\\Cripto\\TDESIVR");
if (hDLL != NULL)
{
lpfnDllFunc1 = (LPFNDLLFUNC1)GetProcAddress(hDLL,
"IVRCipher");
if (!lpfnDllFunc1)
{
// handle the error
FreeLibrary(hDLL);
return 0;
}
else
{
// call the function
uReturnVal = lpfnDllFunc1(MsgEnt, MsgSal,);
}
}
*/

//Implementacion de la conenexion a Host
int Error=0;
int Enviados=0;
int Recibidos=0;
int Longitud=0;
int indice =0;
//int nSocketType = SOCK_STREAM,lintBub;




- 58 -
//DEFINICION DE IP Y PUERTO
LPCTSTR lpszSocketAddress = (char *)ndirIP; //DESARROLLO Y TEST
//LPCTSTR lpszSocketAddress = "150.50.102.15"; //DESARROLLO Y TEST
//LPCTSTR lpszSocketAddress = "150.100.246.44"; //PRODUCCION

UINT nSocketPort=*nPuerto;
//UINT nSocketPort=3550; //Produccion
//UINT nSocketPort=3555; //Produccion

//UINT nSocketPort=3224; //Test
//UINT nSocketPort=3216; //puerto Desarrollo

//LPCTSTR lpszSocketAddress = "150.50.102.15"; //Desarrollo
//char Mensaje[200]="<MD>1.0.000636
00030LOGNUSERGENE****IDAGRD GRD71026 00000000";
//char
Mensaje[2000]="<MD>1.0.000500X1X2X3X4X5X6X7X8X9X0X1X200600LOGNUSERGENE***
*UCQTLBMP 123456789012345678901234000000012006-02-
2010:00:00******************************</MD>";
char Mensaje[50000]="";
char MensajeRecib[10000]="";
char *pmensaje, *ptrRespuesta=MensajeRecib;
char NumSesion[9]="";
char *lMensajeEntrada=(char *)nDato;
char *ptrSalida=(char *)nSalida;
char MensajeError[100]="",lNumError[20]="";
//strcat(Mensaje,"
</MD>");

//pmensaje=Mensaje;
pmensaje=lMensajeEntrada;

//*Para fines de prueba de base 64 y encripcion con triple Des

if (nTipo==1){
CBase64 objBase64;
//objBase64.encodeStr(pmensaje,MensajeRecib,2000);
objBase64.encodeStr(pmensaje,ptrSalida,2000);
AfxMessageBox(_T(pmensaje) ,MB_YESNO);
//AfxMessageBox(_T(ptrSalida) ,MB_YESNO);
FILE *stream;
char strFileName[100]="Logb64.txt";
if( (stream = fopen(strFileName, "a+" )) == NULL )
AfxMessageBox(_T("The file 'Logb64.txt' was not opened")
,MB_YESNO);
/*else
AfxMessageBox(_T("The file 'Logb64.txt' was opened") ,MB_YESNO);
*/
fprintf( stream, "%s\n\t", pmensaje);
fprintf( stream, "%s\n\t", ptrSalida);


if( fclose( stream ) )
AfxMessageBox(_T("The file 'Logb64.txt' was not closed")
,MB_YESNO);

}

- 59 -
else{
CBase64 objBase64;
objBase64.decode(pmensaje,ptrSalida);
//AfxMessageBox(_T(pmensaje) ,MB_YESNO);
//AfxMessageBox(_T(ptrSalida) ,MB_YESNO);
FILE *stream;
char strFileName[100]="Logb64de.txt";
if( (stream = fopen(strFileName, "a+" )) == NULL )
AfxMessageBox(_T("The file 'Logb64.txt' was not opened")
,MB_YESNO);
/*else
AfxMessageBox(_T("The file 'Logb64.txt' was opened") ,MB_YESNO);
*/
fprintf( stream, "%s\n\t", pmensaje);
fprintf( stream, "%s\n\t", ptrSalida);


if( fclose( stream ) )
AfxMessageBox(_T("The file 'Logb64.txt' was not closed")
,MB_YESNO);

}

nSalida=(unsigned char*) MensajeRecib;
return S_OK; //Para fines de prueba
//Fin prueba base 64

//
"<MD>1.0.000500X1X2X3X4X5X6X7X8X9X0X1X200600LOGNUSERGENE****IDAOTA
123456789012345678901234000000022006-02-
2010:00:00******************************</MD>");
//MENSAJE 1, LOGON CON ASTA POR TCP/IP
//strcpy(Mensaje,"<MD>1.0.000500X1X2X3X4X5X6X7X8X9X0X1X200600LOGNUS
ERGENE****UCQTLBT 123456789012345678901234000000012006-02-
2010:00:00******************************</MD>");


CCliente objcte(lpszSocketAddress,nSocketPort);
//CCliente ObjCliente("150.50.102.15",3224);
//Longitud=strlen(Mensaje);
//objcte.PedirServicio(pmensaje, Longitud);

// TODO: Add your control notification handler code here
//CSocket sockClient;
//CCteSocket sockClient;
//CAsyncSocket sockClient;

//AfxMessageBox(lMensajeEntrada,MB_YESNO);


WORD wVersionRequested;
WSADATA wsaData;
int err;

wVersionRequested = MAKEWORD( 2, 2 );

err = WSAStartup( wVersionRequested, &wsaData );

- 60 -
if ( err != 0 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
return S_OK;
}
/* Confirm that the WinSock DLL supports 2.2.*/
/* Note that if the DLL supports versions greater */
/* than 2.2 in addition to 2.2, it will still return */
/* 2.2 in wVersion since that is the version we */
/* requested. */

if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
WSACleanup( );
return S_OK;
}

/* The WinSock DLL is acceptable. Proceed. */

//CCliente objcte(lpszSocketAddress,nSocketPort);
//PRUEBA DE TRANSACCION SIN SESION.
//strcpy(Mensaje,"<MD>1.0.032584
00600****USERGENE****UCQTLBMP
x1x2x3x4x5x6x7x8x9x0x1x2000000012006-02-2010:00:00
</MD><IH>26VMXBL01BL00B UCQTLBMP00000000T2J1
000063611OLBNE</IH><ME>0557C
LINEABAN1111 TC5471550172331772
1234567890123456789012345678901234
123456789012345678901234567890
</ME>");

Longitud=strlen(lMensajeEntrada);
objcte.PedirServicio(pmensaje,ptrRespuesta,&Longitud);
nDato=(unsigned char*) lMensajeEntrada;


WSACleanup( );
return S_OK;
}


STDMETHODIMP CConexHost::ArmaEnvioMEPseudoConversSG_SC(unsigned char*
nStrEntrada, unsigned char* nStrSalidaME, int *nLongTrama, int
*lpnResultado )
{


int Error=0;
int Enviados=0;
int Recibidos=0;
int Longitud=0;
int ind =0;




- 61 -
char Mensaje[320000]="";
char CadComparar[10000]="";
char *pmensaje, *ptrmentmp=Mensaje;
char *ptrRespuesta=(char *)nStrSalidaME;

char *lMensajeEntrada=(char *)nStrEntrada;
char MensajeError[100]="",lNumError[20]="";
char *strTagIniSG="<SG>";
char *strTagFinSG="</SG>";
char *strTagIniSC="<SC>";
char *strTagFinSC="</SC>";

char strNextTrnId[9]="";
int iNextTrnId=0;
char strAbsNumFirstLine[5]="";
int iAbsNumFirstLine=0;
char strNumLines[5]="";
int inumLines=0;
char strLinelength[5]="";
int iLinelength=0;

char strIndWaySendTrn[2]="";
char strTypeCopy[2]="";
char strLenCopy[5]="";
char strConsecutivo[5]="";

char strTmp[20]="";

//strcat(Mensaje,"
</MD>");

pmensaje=lMensajeEntrada;
strcpy(ptrRespuesta,"");
CountCadena(nStrEntrada,&Longitud, &Error);
ind=0;
while(*(pmensaje+ind)!='\0' || ind < Longitud)
{
ObtenSubCadena((pmensaje+ind),CadComparar,0,4);
// AfxMessageBox(_T(CadComparar) ,MB_YESNO);
// break;
//Valida que tipo de Trama es SC o SG
if(strcmp(CadComparar,strTagIniSC)==0)
{
pmensaje=pmensaje+ind;
//AfxMessageBox(_T(pmensaje+4) ,MB_YESNO);
//AfxMessageBox(_T(pmensaje+4+8) ,MB_YESNO);
strcpy(CadComparar,"");
ObtenSubCadena((pmensaje+4),CadComparar,ind,8);
//AfxMessageBox(_T(CadComparar) ,MB_YESNO);
ObtenSubCadena((pmensaje+4),strNextTrnId,0,8);
ObtenSubCadena((pmensaje+4+8),strAbsNumFirstLine,0,4);
ObtenSubCadena((pmensaje+4+8+4),strNumLines,0,4);
ObtenSubCadena((pmensaje+4+8+4+4),strLinelength,0,4);
//ObtenSubCadena((pmensaje+4+8+4+4+4),CadComparar,0,4);
//AfxMessageBox(_T(strNextTrnId) ,MB_YESNO);
//AfxMessageBox(_T(strAbsNumFirstLine) ,MB_YESNO);
//AfxMessageBox(_T(strNumLines) ,MB_YESNO);

- 62 -
//AfxMessageBox(_T(strLinelength) ,MB_YESNO);
pmensaje+=(4+8+4+4+4);

//Registro de log de pruebas
FILE *stream;
char strFileName[100]="LogSC.txt";
if( (stream = fopen(strFileName, "a+" )) == NULL )
AfxMessageBox(_T("The file 'regMens.txt' was not
opened") ,MB_YESNO);
/*else
AfxMessageBox(_T("The file 'regMens.txt' was opened")
,MB_YESNO);
*/
fprintf( stream, "%s\n\t", strNextTrnId);
fprintf( stream, "%s\n\t", strAbsNumFirstLine);
fprintf( stream, "%s\n\t", strNumLines);
fprintf( stream, "%s\n\t", strLinelength);
if( fclose( stream ) )
AfxMessageBox(_T("The file 'regMens.txt' was not
closed") ,MB_YESNO);
//Fin registro log de pruebas
strcat(ptrRespuesta,"<ME>");
strcat(ptrRespuesta,strNumLines);
strcat(ptrRespuesta,strLinelength);
inumLines=atoi(strNumLines);
iLinelength=atoi(strLinelength);

//Pruebas de generacion de consecutivo en cadena de 4
posiciones
/*strcat(ptrRespuesta,Mensaje);
GeneraConsecutivoStr4(strConsecutivo, 1);
AfxMessageBox(_T(strConsecutivo) ,MB_YESNO);
GeneraConsecutivoStr4(strConsecutivo, 10);
AfxMessageBox(_T(strConsecutivo) ,MB_YESNO);
GeneraConsecutivoStr4(strConsecutivo, 100);
AfxMessageBox(_T(strConsecutivo) ,MB_YESNO);
GeneraConsecutivoStr4(strConsecutivo, 1000);
AfxMessageBox(_T(strConsecutivo) ,MB_YESNO);
*/
//armado de lineas que regresa el SC con su consecutivo de
prefijo
/*
int ind2=0;
int i,j=0;
while(*(pmensaje+ind2)!='/0' )
{
strcpy(CadComparar,"");
ObtenSubCadena((pmensaje+ind2),CadComparar,0,5);
if(strcmp(CadComparar,strTagFinSC)==0)
{break;
}
else
{

for(i=0; i < inumLines; i++)
{
for(j=0; j < iLinelength; j++)

- 63 -
{
strcpy(CadComparar,"");

ObtenSubCadena((pmensaje+i+j),CadComparar,0,5);
if(strcmp(CadComparar,strTagFinSC)==0)
{break;
}
else

*(Mensaje+i*iLinelength+j)=*(pmensaje+ind2+i*iLinelength+j);
}
}
}
ind2++;

}
ind2++;
*/
int i=0,j=0;
for(i=0; i < inumLines; i++)
{ GeneraConsecutivoStr4(strConsecutivo, i);
strcat(Mensaje,strConsecutivo);
//AfxMessageBox(_T(Mensaje) ,MB_YESNO);
for(j=0; j < iLinelength; j++)
{


ObtenSubCadena((pmensaje+i+j),CadComparar,0,5);
if(strcmp(CadComparar,strTagFinSC)==0)
{break;
}
else

*(Mensaje+i*iLinelength+j+4*(i+1))=*(pmensaje+i*iLinelength+j);
}
}

//*(Mensaje+i*iLinelength+j+1)='\0';
*(Mensaje+i*iLinelength+j+4*(i+1)+1)='\0';
strcat(Mensaje,"</ME>");
strcat(ptrRespuesta,Mensaje);
//strcat(CadComparar,strNextTrnId);
//strcat(CadComparar,strAbsNumFirstLine);
//strcat(CadComparar,strNumLines);
//strcat(CadComparar,strLinelength);
//AfxMessageBox(_T(CadComparar) ,MB_YESNO);

if( (stream = fopen(strFileName, "a+" )) == NULL )
AfxMessageBox(_T("The file 'regMens.txt' was not
opened") ,MB_YESNO);
/*else
AfxMessageBox(_T("The file 'regMens.txt' was opened")
,MB_YESNO);
*/
fprintf( stream, "%d\n\t", i*iLinelength+j+1);

if( fclose( stream ) )

- 64 -
AfxMessageBox(_T("The file 'regMens.txt' was not
closed") ,MB_YESNO);
Longitud= (iLinelength+4)*inumLines+17;
break;
}
else
if(strcmp(CadComparar,strTagIniSG)==0)
{pmensaje=pmensaje+ind;
//AfxMessageBox(_T(CadComparar) ,MB_YESNO);
strcpy(CadComparar,"");
ObtenSubCadena((pmensaje+4),strNextTrnId,0,8);
ObtenSubCadena((pmensaje+4+8),strIndWaySendTrn,0,1);
ObtenSubCadena((pmensaje+4+8+1),strTypeCopy,0,1);
//AfxMessageBox(_T(strNextTrnId) ,MB_YESNO);
//AfxMessageBox(_T(strIndWaySendTrn) ,MB_YESNO);
//AfxMessageBox(_T(strTypeCopy) ,MB_YESNO);
//Se quita uno debido a que incluye la B de BMS
//pmensaje+=(4+8+1+1);
pmensaje+=(4+8+1);
//AfxMessageBox(_T(pmensaje) ,MB_YESNO);
//ObtenSubCadena((pmensaje+4+8+1+1),,0,1);
//ObtenSubCadena((pmensaje+4+8+4+4+4),CadComparar,0,4);
int ind2=0;
while(*(pmensaje+ind2)!='/0' )
{
strcpy(CadComparar,"");
ObtenSubCadena((pmensaje+ind2),CadComparar,0,5);
if(strcmp(CadComparar,strTagFinSG)==0)
{break;
}
else
{*(Mensaje+ind2)=*(pmensaje+ind2);
}
ind2++;

//break;
}

ind2++;
*(Mensaje+ind2)='/0';
Longitud=strlen(Mensaje);
//Se diminuye 1 para que la longitud del copy no considere
la B del campo tipo copy
Longitud--;
_itoa( Longitud, strLenCopy, 10 );
int lonStrLenCopy=strlen(strLenCopy);
//AfxMessageBox(_T(strLenCopy) ,MB_YESNO);
strcpy(ptrRespuesta,"<ME>0000");
//InsertSubCadCadena(strLenCopy,ptrRespuesta,4+(4-
lonStrLenCopy),4-lonStrLenCopy);
InsertSubCadCadena(strLenCopy,ptrRespuesta,4+(4-
lonStrLenCopy),lonStrLenCopy);
strcat(Mensaje,"</ME>");
//Genera mal la longitud
//Longitud=strlen(Mensaje);
Longitud=Longitud+14;
//CountCadena1(Mensaje, &Longitud);

- 65 -
strcat(ptrRespuesta,Mensaje);
_itoa( Longitud, strTmp, 10 );
//AfxMessageBox(_T(strTmp) ,MB_YESNO);
break;
}

ind++;
}
//Validar si es correcta la validacion
//if(*(pmensaje+ind)=='\0' || ind < Longitud)
// return S_FALSE;

//AfxMessageBox(lMensajeEntrada,MB_YESNO);



//CountCadena((unsigned char *)Mensaje, &Longitud, &Error);
//Longitud=strlen(Mensaje);
*nLongTrama=Longitud;
//objcte.PedirServicio(pmensaje,ptrRespuesta,&Longitud);
//nDato=(unsigned char*) lMensajeEntrada;
nStrSalidaME=(unsigned char*) Mensaje;

//WSACleanup( );
return S_OK;
}





int CConexHost::ProcesaEncripcion(char *msgEntrada, char *MsgSalida, int
TipoSolicitud, int *TamSalida)
{
//**************************************************
//Definicion de Variables para Pruebas de Encripcion.
//**************************************************


ULONG uReturnVal=0;
//char MsgEnt[10000], MsgSal[10000], MngRetornado[32000],
Servicio[2];
char Servicio[2];
char *ptrServ=Servicio;
int *ptrLMsg, LongMens, tamMsg=0, tamMsgSal=0, i=0;
char tmpcadena[10]="";
ptrLMsg=&LongMens;

if(TipoSolicitud==1)
strcpy(Servicio,"E");
else
strcpy(Servicio,"D");
LongMens=strlen(msgEntrada);

uReturnVal= TDESCipher(msgEntrada, MsgSalida, ptrLMsg, Servicio,
&tamMsgSal );
//tamMsgSal=0;

- 66 -
if(*Servicio=='E')
{for(i=0;i<32000;i++)
{if(*(MsgSalida+i)==' ' || *(MsgSalida+i)=='\0')
break;
//tamMsgSal++;
}
*(MsgSalida+i)='\0';
}
else
{
for(i=0;i<tamMsgSal;i++)
{if(*(MsgSalida+i)=='\0')
break;
//tamMsgSal++;
}
*(MsgSalida+i)='\0';
}
_itoa( tamMsgSal,tmpcadena, 10 );
//AfxMessageBox(_T(tmpcadena) ,MB_YESNO);
//AfxMessageBox(_T(MsgSalida) ,MB_YESNO);
*TamSalida=tamMsgSal;
return 0;
}

STDMETHODIMP CConexHost::Cripto(unsigned char* nDato, unsigned char*
nSalida, int* TipoSolicitud, int* TamSalida, int *lpnResultado )
{

ULONG uReturnVal=0;
//char MsgEnt[10000], MsgSal[10000], MngRetornado[32000],
Servicio[2];
char Servicio[2];
char *ptrServ=Servicio;
int *ptrLMsg, LongMens, tamMsg=0, tamMsgSal=0, i=0;
char tmpcadena[10]="";
char *ptrEntrada=(char *)nDato;
char *ptrSalida=(char *)nSalida;
ptrLMsg=&LongMens;

if(*TipoSolicitud==1)
strcpy(Servicio,"E");
else
strcpy(Servicio,"D");
LongMens=strlen(ptrEntrada);

uReturnVal= TDESCipher(ptrEntrada, ptrSalida, ptrLMsg, Servicio,
&tamMsgSal );
//tamMsgSal=0;
if(*Servicio=='E')
{for(i=0;i<32000;i++)
{if(*(ptrSalida+i)==' ' || *(ptrSalida+i)=='\0')
break;
//tamMsgSal++;
}
*(ptrSalida+i)='\0';
}
else

- 67 -
{
for(i=0;i<tamMsgSal;i++)
{if(*(ptrSalida+i)=='\0')
break;
//tamMsgSal++;
}
*(ptrSalida+i)='\0';
}
_itoa( tamMsgSal,tmpcadena, 10 );
//AfxMessageBox(_T(tmpcadena) ,MB_YESNO);
//AfxMessageBox(_T(MsgSalida) ,MB_YESNO);
*TamSalida=tamMsgSal;
return S_OK;
}


BOOL CConexHost::ObtenSubCadena(char *cadfuente, char *subcaddestino, int
posini, int numcarateres)
{ int indice=0;
int longitudcad=0;
longitudcad=strlen(cadfuente);
if(longitudcad < posini || *cadfuente=='\0' )
return FALSE;
for (indice=0; indice < numcarateres ; indice ++)
{ if(*(cadfuente+indice)=='\0')
return FALSE;
*(subcaddestino+indice) = *(cadfuente+posini+indice);
}
*(subcaddestino+(++indice))='\0';
//AfxMessageBox(_T(subcaddestino) ,MB_YESNO);
return TRUE;

}

BOOL CConexHost::InsertSubCadCadena(char *subcad, char *cadena, int
posini, int numcaract)
{ int indice=0;
char tmpcadena[10]="";
for (indice=0; indice <numcaract ; indice ++)
{ //if(*cadena=='\0')
// return FALSE;
//cadena[indice+posini] = *(subcad+indice);
*(cadena + posini + indice) = *(subcad+indice);
}
//*(cadena + posini + indice) ='\0';

//char *_itoa( int value, char *string, int radix );
//_itoa( *numcaract,tmpcadena, 10 );
//AfxMessageBox(_T(tmpcadena) ,MB_YESNO);
return TRUE;

}
BOOL CConexHost::CountCadena1(char* cadfuente, int * numcarateres)
{ int indice=0;
while(cadfuente[indice]!= '\0' )
{ indice++;
}

- 68 -
if(indice==0)
return -1;
indice++;
*numcarateres=indice;
return TRUE;

}


STDMETHODIMP CConexHost::CountCadena(unsigned char* cadfuente, int *
numcarateres, int *lpnResultado )
{ int indice=0;
while(cadfuente[indice]!= '\0' )
{ indice++;
}
if(indice==0)
return -1;
indice++;
*numcarateres=indice;
return 0;

}

BOOL CConexHost::GeneraConsecutivoStr4(char *pcadCosecutivo, int
pValorActual)
{ int indice=0;
char strValor[5]="";
char strconsecutivo[5]="0000";
_itoa( ++pValorActual, strValor, 10 );
if(pValorActual < 10)
{
InsertSubCadCadena(strValor, strconsecutivo, 3, 1);
}
else
if(pValorActual > 9 && pValorActual < 100)
{
InsertSubCadCadena(strValor, strconsecutivo, 2, 2);
}
else
if(pValorActual > 99 && pValorActual < 1000)
{
InsertSubCadCadena(strValor, strconsecutivo, 1,
3);
}
else
if(pValorActual > 999 && pValorActual < 10000)
{
InsertSubCadCadena(strValor, strconsecutivo,
0, 4);
}
else
return FALSE;
strcpy(pcadCosecutivo,strconsecutivo);
/*
for (indice=0; indice <numcaract ; indice ++)
{
*(cadena + posini + indice) = *(subcad+indice);

- 69 -
}
*/

return TRUE;

}

/***************************************************/
/*-------------------------------------------------*/
/* librera: sockstr.lib */
/* Fichero : sockstr.h */
/* Proyecto: sockstrlib.dsp */
/* WorkSpace: SockStream.dsw */
/* Objetivo: */
/* */
/***************************************************/
#ifndef __MC_SEND
#define __MC_SEND
#include <winsock.h>
#include <afxsock.h>
#include <sys/types.h>
#include <stdio.h>

#include <stdlib.h>
#include <string.h>

#include <iostream.h>

const int DefaultTTL=1;

const int ERRBASE=65536;
const int OK=0;
const int ESEND = ERRBASE+1;
const int ERECV = ERRBASE+2;
const int ETIMEOUT = ERRBASE+3;
class Csockbase
{
public:
struct sockaddr_in addr; // direccin
int lenaddr; // longitud de la direccion
int sock; // socket
int err;
int retval;
};
class CCliente : protected Csockbase
{
public:
CCliente(const char *AddressDest,int Port);
~CCliente();
int PedirServicio(char *bufdatos,char *bufsalida, int *numdatos);
int PedirServicioWin(char *bufdatos,char *bufsalida, int *numdatos);
};

class CServidor : protected Csockbase
{
long bytes_recibidos;

- 70 -
struct sockaddr_in addrservicio,addrcliente;
public:
CServidor(const char *SrcIPAddr=0,int IPPort=0);
~CServidor();
int servicio(char *bufdatosIn, char *bufdatosOut,long maxdatos, long
&datosleidos, int timeout);
int GetPort();
char *GetAddr();
int GetPortUltimoServicio();
char *GetAddrUltimoServicio();
int GetPortUltimoCliente();
char *GetAddrUltimoCliente();
};

CCliente::CCliente(const char *AddressDest,int Port)
{


//DWORD optval = SO_SEC_SSL;
//DWORD optval=1000;
//err = setsockopt(Socket,SOL_SOCKET,SO_SECURE,&optval,sizeof(optval));


if((sock = socket( AF_INET, SOCK_STREAM, 0 ))==-1)
{ AfxMessageBox(_T("Error al abrir crear socket") ,MB_OK);
return;
//throw ("Error en socket");
}
//int zero=10000;
//err = setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,&optval,sizeof(optval));
//err = setsockopt( sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&zero,
sizeof(zero) );
//if ( err == SOCKET_ERROR )
//{ AfxMessageBox(_T("Error setsockopt ") ,MB_YESNO);
//LocalFree( lpClientContext );
//closesocket( s );
//closesocket( sListener );
//return FALSE;
//}


memset (&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(AddressDest);
addr.sin_port = htons(Port);
lenaddr=sizeof(addr);
retval=connect(sock,(struct sockaddr *)&addr,lenaddr);
if (retval)
{AfxMessageBox(_T("Error al conectarce al Host") ,MB_OK);
//throw("Error en connect.");
}

}
CCliente::~CCliente()
{
//destruir la conexion si sigue activa y hacer limpieza
closesocket(sock);

- 71 -
}
int CCliente::PedirServicio(char *bufdatos,char *bufsalida, int
*numdatos)
{
int nummaxrecib=32000, logresp=0, i=0;
char strrecibidos[32000]="",strtmp[2];
char tmpcadena[10]="";
char strrecibbis[32000]="";
int logrespbis=0;
char strCodError[20]="";

//Primero se construye la estructura de timeouts
//Un conjunto de sockets a comprobar si tienen peticiones
fd_set set;
FD_ZERO(&set);
FD_SET(sock,&set);
//...y el tiempo mximo a esperar si hay buffer de entrada
struct timeval tval;
//tval.tv_sec=30;
tval.tv_sec=20;
//tval.tv_sec =0;
tval.tv_usec=0;


if ((logresp=send(sock, bufdatos, *numdatos, 0)) <0)
{ *numdatos=logresp;
AfxMessageBox(_T("Error al Enviar TCP-IP...") ,MB_OK);
return OK;
//throw("Error en send. Envindo peticin al servidor");
}
//strcpy(bufdatos,"");
//AfxMessageBox(_T(bufdatos) ,MB_YESNO);


//se suspende la ejecucin hasta que haya peticin o
//se cumpla el tiempo de espera

int result=select(0,&set,0,0,&tval);
if(result==0)
{ AfxMessageBox(_T("Tiempo de Espera Terminado(timeout)...") ,MB_OK);
return OK; //ETIMEOUT; //retornar si cumple tiempo espera
}
//hay peticin y se procesa.
for(long j=0; j<10000000; j++);

//DWORD optval = SO_SEC_SSL;
int optvalpropio=10000;
//optvalpropio=20000;
//int optvalpropio=32000;
int cbOpt = sizeof( optvalpropio ),


err = setsockopt(sock,SOL_SOCKET,SO_RCVBUF,(char *)
&optvalpropio,cbOpt);
if( err==0)
{unsigned int valortmp=optvalpropio;
//itoa( valortmp,tmpcadena, 10 );

- 72 -
//AfxMessageBox(_T(tmpcadena) ,MB_YESNO);
}


if((logresp=recv(sock,strrecibidos,nummaxrecib,0))<0)
{ logresp=0;
logresp=WSAGetLastError ();
*numdatos=logresp;
_itoa(logresp,strCodError,10);
strcat(strCodError, ":Error al recibir trama...");
//AfxMessageBox(_T(strCodError) ,MB_OK);
return OK;
//throw("Error en recv. Recibiendo respuesta del servidor");
}
else
{
long logrespbis=0;
char strrecibbis[32000]="";
while((logrespbis=recv(sock,strrecibbis,nummaxrecib,0)) > 0)
{
for(long j=0; j<logrespbis; j++)
{*(strrecibidos+logresp+j)=*(strrecibbis+j);
}
*(strrecibidos+logresp+j)='\0';

logresp=logresp+logrespbis;
}
}
/*
if(logresp > 8000 && logresp < 15000)
{
int ind=0;
for(ind=0;ind<32000;ind++)
{strrecibbis[ind]=' ';
}
while(logresp < 19049)
{
if((logrespbis=recv(sock,strrecibbis,nummaxrecib,0))<0)
{
*numdatos=logresp;
AfxMessageBox(_T("Error al recibir trama...") ,MB_OK);
return OK;
}
else
if(logrespbis <=0)
{break;
}
for(long j=0; j<logrespbis; j++)
{*(strrecibidos+logresp+j)=*(strrecibbis+j);
}
*(strrecibidos+logresp+j)='\0';

logresp=logresp+logrespbis;
}
}
*/


- 73 -



FILE *stream;
char strFileName[100]="logMens.txt";

*numdatos=logresp;

if( (stream = fopen(strFileName, "a+" )) == NULL )
AfxMessageBox(_T("The file 'LOGMens.txt' was not opened")
,MB_OK);
for(i=0; i<logresp ; i++)
{if(*(strrecibidos+i)=='\0' || *(strrecibidos+i)=='\n'
|| *(strrecibidos+i)=='\r' )
*(strrecibidos+i)=' ';
//if(*(strrecibidos+i) < 35 || *(strrecibidos+i)> 125 ||
*(strrecibidos+i) ==0)

if(*(strrecibidos+i) < 20 || *(strrecibidos+i)> 125 )
{
//char *caracter;
//*caracter= *(strrecibidos+i);
//fprintf( stream, "%s", (strrecibidos+i));
strtmp[0]=*(strrecibidos+i);
strtmp[1]='\0';
fprintf( stream, "%c", strtmp);
//fprintf( stream, "%s\n\t", MensajeRecib);
*(strrecibidos+i)=' ';

}

*(bufsalida+i)=*(strrecibidos+i);
}
*(bufsalida+i)='\0';
fprintf( stream, "\n\t");
if( fclose( stream ) )
AfxMessageBox(_T("The file 'LOGMens.txt' was not closed") ,MB_OK);
//strcpy(bufsalida,strrecibidos);
return OK;
}

int CCliente::PedirServicioWin(char *bufdatos,char *bufsalida, int
*numdatos)
{
int nummaxrecib=32000, logresp=0, i=0;
char strrecibidos[32000]="";
/*
if (send(sock, bufdatos, *numdatos, 0) <0)
throw("Error en send. Envindo peticin al servidor");
//strcpy(bufdatos,"");
if((logresp=recv(sock,strrecibidos,nummaxrecib,0))<0)
{ *numdatos=logresp;
//throw("Error en recv. Recibiendo respuesta del servidor");
}
char tmpcadena[10]="";
_itoa( logresp,tmpcadena, 10 );
AfxMessageBox(_T(tmpcadena) ,MB_YESNO);

- 74 -
*numdatos=logresp;
for(i=0; i<logresp; i++)
{if(*(strrecibidos+i)==0)
*(strrecibidos+i)=' ';
*(bufsalida+i)=*(strrecibidos+i);
}
*(bufsalida+i)='\0';
*/

//strcpy(bufsalida,strrecibidos);
int Error=0;
int Enviados=0;
int Recibidos=0;
int Longitud=0;
int indice =0;
int nSocketType = SOCK_STREAM,lintBub;
BOOL respuesta=FALSE;
//**************************************
//DEFINICION DE IP Y PUERTO por ambiente
//**************************************

LPCTSTR lpszSocketAddress = "150.50.102.15"; //DESARROLLO Y TEST
UINT nSocketPort=3224; //Test

//LPCTSTR lpszSocketAddress = "150.50.102.15"; //Desarrollo
//UINT nSocketPort=3216; //puerto Desarrollo

//LPCTSTR lpszSocketAddress = "150.100.246.44"; //PRODUCCION
//UINT nSocketPort=3550; //Produccion
//UINT nSocketPort=3555; //Produccion

//IP y puerto de prueba
//UINT nSocketPort=3216;
//LPCTSTR lpszSocketAddress = "150.50.102.15";

/*
CSocket sockClient;
if(sockClient.Create() < 0)
{
Error=sockClient.GetLastError ();
}
while(!sockClient.Connect(lpszSocketAddress, nSocketPort))
{
Error=sockClient.GetLastError ();

if (AfxMessageBox("Desea Tratar de conectarse otra ves?..
",MB_YESNO) == IDNO)
{
//delete m_pSocket;
//m_pSocket = NULL;
//'return FALSE;
return FALSE;
}
}


//if ((Enviados=sockClient.Send(bufdatos, *numdatos))<0)

- 75 -
if ((Enviados=sockClient.Send(bufdatos, *numdatos))<0)
{
Error=sockClient.GetLastError ();
}

//Error=sockClient.GetLastError ();
lintBub=32000;
if ((Recibidos=sockClient.Receive(strrecibidos,lintBub)) < 0)
{ Error=sockClient.GetLastError ();

}
Longitud=Recibidos;

char tmpcadena[10]="";
_itoa( Recibidos,tmpcadena, 10 );
//AfxMessageBox(_T(tmpcadena) ,MB_YESNO);
*numdatos=Recibidos;
for(i=0; i<Recibidos; i++)
{if(*(strrecibidos+i)==0)
*(strrecibidos+i)=' ';
*(bufsalida+i)=*(strrecibidos+i);
}
*(bufsalida+i)='\0';

sockClient.Close();

*/



return OK;
}



// Implemenatacion Servidor
CServidor::CServidor(const char *SrcIPAddr,int IPPort)
{


if (( sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
throw("Error creando socket SOCK_STREAM");

memset(&addr, 0, sizeof (addr));
addr.sin_family = AF_INET;
if(!SrcIPAddr)
addr.sin_addr.s_addr = INADDR_ANY;
else
addr.sin_addr.s_addr= inet_addr(SrcIPAddr);
addr.sin_port = htons(IPPort);
lenaddr=sizeof(addr);
//Se asocia el socket TCP a la direccion de recepcion
if (bind (sock, (struct sockaddr *) &addr, lenaddr) == -1 )
throw ("Error en bind");
if(getsockname(sock,(struct sockaddr *)&addr,&lenaddr)==-1)
throw ("error en getsockname");
listen(sock,5);

- 76 -
}
CServidor::~CServidor()
{
//destruir la conexion si sigue activa y hacer limpieza
closesocket(sock);
}
//recibe en bufdatos como maximo maxdatos (si hay mas retorna error)
int CServidor::servicio(char *bufdatosIn, char *bufdatosOut, long
maxdatosInOut,
long &datosleidos, int timeout)
{
//Primero se construye la estructura de timeouts
//Un conjunto de sockets a comprobar si tienen peticiones
fd_set set;
FD_ZERO(&set);
FD_SET(sock,&set);
//...y el tiempo mximo a esperar si hay buffer de entrada
struct timeval tval;
tval.tv_sec=0;
tval.tv_usec=timeout;
//se suspende la ejecucin hasta que haya peticin o
//se cumpla el tiempo de espera
int result=select(0,&set,0,0,&tval);
if(result==0) return ETIMEOUT; //retornar si cumple tiempo espera
//hay peticin y se procesa.
int sockacept=accept(sock,(struct sockaddr *) &addr, (int *) &lenaddr
);
if(sockacept==-1)
throw("Error en accept");
//obtenemos datos del socket creado por el sitema para atender
//el servicio
int lenaddrservicio= sizeof addr;
if( getsockname( sockacept, (struct sockaddr *) &addrservicio,
&lenaddrservicio ) ==-1)
throw("Error averiguando sockaddr_in del socket asignado para el
servicio");

//obtenemos los datos del cliente conectado al socket
int lenaddrcliente= sizeof addrcliente;
if( getpeername( sockacept, (struct sockaddr *) &addrcliente,
&lenaddrcliente ) ==-1)
throw("Error averiguando sockaddr_in del socket cliente conectado
a este");

//printf("Socket port #%d\n", ntohs( server.sin_port));

//Con los datos del cliente se podra decidor si se acepta o no
//la peticin...
//Se reciben los datos.
retval=recv(sockacept,bufdatosIn,maxdatosInOut,0);
if (retval==-1)
throw("Error en recv");
datosleidos=retval;

//se hace el procesamiento de los datos. (convertimos a mayusculas!)
for(int i=0;i<datosleidos;i++)
bufdatosOut[i]=toupper(bufdatosIn[i]);

- 77 -

//devolvemos los resultados
if (send(sockacept,bufdatosOut,datosleidos,0) <0)
throw("Error en send contestando al cliente");
//damos por terminada la comunicacin.

closesocket(sockacept);
return OK;
}
int CServidor::GetPort()
{
return ntohs(addr.sin_port);
}
char *CServidor::GetAddr()
{
return inet_ntoa(addr.sin_addr);
}
int CServidor::GetPortUltimoServicio()
{
return ntohs(addrservicio.sin_port);
}
char *CServidor::GetAddrUltimoServicio()
{
return inet_ntoa(addrservicio.sin_addr);
}
int CServidor::GetPortUltimoCliente()
{
return ntohs(addrcliente.sin_port);
}
char *CServidor::GetAddrUltimoCliente()
{
return inet_ntoa(addrcliente.sin_addr);
}
#endif

// Conexion.idl : IDL source for Conexion.dll
//

// This file will be processed by the MIDL tool to
// produce the type library (Conexion.tlb) and marshalling code.

import "oaidl.idl";
import "ocidl.idl";
[
object,
uuid(17DD582E-4D86-11DB-925D-0001022CD47C),

helpstring("IConexHost Interface"),
pointer_default(unique)
]
interface IConexHost : IUnknown
{[helpstring("method EnviaMensajeHost")]
HRESULT EnviaMensajeHost([in,string] char* nDato,[in,string] char*
nSalida, [in] int* nLonSal,[in,string] char* ndirIP, [in] int* nPuerto,
[in] int nTipo, [out,retval] int* lpnResultado);

- 78 -
//HRESULT EnviaMensajeHost([in,string] char* nDato,[in,string]
char* nSalida, [in,string] char* ndirIP, [in] int* nPuerto, [out,retval]
int* lpnResultado);
//HRESULT EnviaMensajeHost([in,string] char* nDato, [in,string]
char* ndirIP, [in] int* nPuerto, [out,retval] int* lpnResultado);
HRESULT EnviaMsjHostEncripto([in,string] char* nDato, [in,string]
char* nSalida, [in] int* nLonSal, [in,string] char* ndirIP, [in] int*
nPuerto, [in] int nTipo, [out,retval] int* lpnResultado);
HRESULT ArmaEnvioMEPseudoConversSG_SC([in,string] char*
nStrEntrada, [in,string] char* nStrSalidaME, [in] int*
nLongTrama,[out,retval] int* lpnResultado);
HRESULT CountCadena([in,string] char* cadfuente, [in] int*
numcarateres, [out,retval] int* lpnResultado);
HRESULT Cripto([in,string] char* nDato, [in,string] char* nSalida,
[in] int* TipoSolicitud, [in] int* TamSalida, [out,retval] int*
lpnResultado);

//[helpstring("method EnviaMensajeHost")] HRESULT
EnviaMensajeHost([in] BSTR cMensaje, [out,retval] int* lpnResultado);
};

[
uuid(17DD5821-4D86-11DB-925D-0001022CD47C),
version(1.0),
helpstring("Conexion 1.0 Type Library")
]
library CONEXIONLib
{
importlib("stdole32.tlb");
importlib("stdole2.tlb");

[
uuid(17DD582F-4D86-11DB-925D-0001022CD47C),
helpstring("ConexHost Class")
]
coclass ConexHost
{
[default] interface IConexHost;
};
};


/*++


Module Name:

basetsd.h

Abstract:

Type definitions for the basic sized types.

Author:


Revision History:

- 79 -

--*/

#ifndef _BASETSD_H_
#define _BASETSD_H_

#ifdef __cplusplus
extern "C" {
#endif

//
// The following types are guaranteed to be signed and 32 bits wide.
//

typedef int LONG32, *PLONG32;
typedef int INT32, *PINT32;

//
// The following types are guaranteed to be unsigned and 32 bits wide.
//

typedef unsigned int ULONG32, *PULONG32;
typedef unsigned int DWORD32, *PDWORD32;
typedef unsigned int UINT32, *PUINT32;

//
// The INT_PTR is guaranteed to be the same size as a pointer. Its
// size with change with pointer size (32/64). It should be used
// anywhere that a pointer is cast to an integer type. UINT_PTR is
// the unsigned variation.
//
// HALF_PTR is half the size of a pointer it intended for use with
// within strcuture which contain a pointer and two small fields.
// UHALF_PTR is the unsigned variation.
//

#ifdef _WIN64

typedef __int64 INT_PTR, *PINT_PTR;
typedef unsigned __int64 UINT_PTR, *PUINT_PTR;

#define MAXINT_PTR (0x7fffffffffffffffI64)
#define MININT_PTR (0x8000000000000000I64)
#define MAXUINT_PTR (0xffffffffffffffffUI64)

typedef unsigned int UHALF_PTR, *PUHALF_PTR;
typedef int HALF_PTR, *PHALF_PTR;

#define MAXUHALF_PTR (0xffffffffUL)
#define MAXHALF_PTR (0x7fffffffL)
#define MINHALF_PTR (0x80000000L)

#pragma warning(disable:4311) // type cast truncation

#if !defined(__midl)
__inline
unsigned long

- 80 -
HandleToUlong(
void *h
)
{
return((unsigned long) h );
}

__inline
unsigned long
PtrToUlong(
void *p
)
{
return((unsigned long) p );
}

__inline
unsigned short
PtrToUshort(
void *p
)
{
return((unsigned short) p );
}

__inline
long
PtrToLong(
void *p
)
{
return((long) p );
}

__inline
short
PtrToShort(
void *p
)
{
return((short) p );
}
#endif
#pragma warning(3:4311) // type cast truncation

#else


typedef long INT_PTR, *PINT_PTR;
typedef unsigned long UINT_PTR, *PUINT_PTR;

#define MAXINT_PTR (0x7fffffffL)
#define MININT_PTR (0x80000000L)
#define MAXUINT_PTR (0xffffffffUL)

typedef unsigned short UHALF_PTR, *PUHALF_PTR;
typedef short HALF_PTR, *PHALF_PTR;

- 81 -

#define MAXUHALF_PTR 0xffff
#define MAXHALF_PTR 0x7fff
#define MINHALF_PTR 0x8000

#define HandleToUlong( h ) ((ULONG) (h) )
#define PtrToUlong( p ) ((ULONG) (p) )
#define PtrToLong( p ) ((LONG) (p) )
#define PtrToUshort( p ) ((unsigned short) (p) )
#define PtrToShort( p ) ((short) (p) )

#endif

//
// SIZE_T used for counts or ranges which need to span the range of
// of a pointer. SSIZE_T is the signed variation.
//

typedef UINT_PTR SIZE_T, *PSIZE_T;
typedef INT_PTR SSIZE_T, *PSSIZE_T;

//
// The following types are guaranteed to be signed and 64 bits wide.
//

typedef __int64 LONG64, *PLONG64;
typedef __int64 INT64, *PINT64;


//
// The following types are guaranteed to be unsigned and 64 bits wide.
//

typedef unsigned __int64 ULONG64, *PULONG64;
typedef unsigned __int64 DWORD64, *PDWORD64;
typedef unsigned __int64 UINT64, *PUINT64;

#ifdef __cplusplus
}
#endif

#endif // _BASETSD_H_









- 82 -
Aplicacion ServerTCP:
// Cliente.h: interface for the CCliente class.
//
//////////////////////////////////////////////////////////////////////

#if
!defined(AFX_CLIENTE_H__6E3BAC5A_7C8E_4CC0_AB94_188E0F49659D__INCLUDED_)
#define AFX_CLIENTE_H__6E3BAC5A_7C8E_4CC0_AB94_188E0F49659D__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "sockbase.h"

class CCliente : public Csockbase
{
public:
CCliente(const char *AddressDest,int Port);
virtual ~CCliente();
int PedirServicio(char *bufdatos, long numdatos,char *bufsalida, long
*ndatosreciv);
};

#endif //
!defined(AFX_CLIENTE_H__6E3BAC5A_7C8E_4CC0_AB94_188E0F49659D__INCLUDED_)

// Cliente.cpp: implementation of the CCliente class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "ServerTCP.h"
#include "Cliente.h"
#include <time.h>

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CCliente::CCliente(const char *AddressDest,int Port)
{
if((sock = socket( AF_INET, SOCK_STREAM, 0 ))==-1)
AfxMessageBox(_T("Error de socket...") ,MB_OK);
//throw ("Error en socket");

memset (&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(AddressDest);

- 83 -
addr.sin_port = htons(Port);
lenaddr=sizeof(addr);
retval=connect(sock,(struct sockaddr *)&addr,lenaddr);
if (retval)
{ char strTmp[10]="";
char strMensaje[50]="";
strcpy(strMensaje,"Error de connect...Codigo: ");
_itoa((retval),strTmp,10);
strcat(strMensaje,strTmp);
//AfxMessageBox(_T(strMensaje) ,MB_OK);
time_t ltime;
time( &ltime );
char *strtime=ctime(&ltime );
//AfxMessageBox(_T(strtime) ,MB_OK);
strcpy(strTmp,"");

FILE *stream;
char strNameFile[50]="log";
//strncpy( string, "Dogs", 4 );
strncpy(strTmp, strtime,3);
strcat(strNameFile, strTmp);
strncpy(strTmp, strtime+4,3);
strcat(strNameFile, strTmp);
strncpy(strTmp, strtime+8,2);
strcat(strNameFile, strTmp);
strcat(strNameFile, ".txt");

if( (stream = fopen(strNameFile , "a+" )) == NULL )
AfxMessageBox(_T("Error al abrir archivo ") ,MB_OK);

fprintf(stream,"%s ","Error de connect...");
fprintf(stream,"%i\n",retval);
//fscanf(stream,"%s",puerto);
//fscanf(stream,"%s",ip_Host);
//fscanf(stream,"%s",puerto_Host);

fclose(stream);
} //fin if
//throw("Error en connect.");
}

CCliente::~CCliente()
{ //destruir la conexion si sigue activa y hacer limpieza
closesocket(sock);

}

int CCliente::PedirServicio(char *bufdatos, long numdatos, char
*bufsalida, long* ndatosreciv)
{
long dat_maxrecib=32000;
long dat_recib=0;
char buffer[10]="";
int iCodError=0;
fd_set set;
FD_ZERO(&set);
FD_SET(sock,&set);

- 84 -
//...y el tiempo mximo a esperar si hay buffer de entrada
struct timeval tval;
tval.tv_sec=10;
tval.tv_usec=0;
//se suspende la ejecucin hasta que haya peticin o
//se cumpla el tiempo de espera

//ultima validacion de lo que se envia
char strTmp[10]="";
char strMensaje[50]="";
time_t ltime;
time( &ltime );
char *strtime=ctime(&ltime );


FILE *stream;
char strNameFile[50]="log";
strncpy(strTmp, strtime,3);
strcat(strNameFile, strTmp);
strncpy(strTmp, strtime+4,3);
strcat(strNameFile, strTmp);
strncpy(strTmp, strtime+8,2);
strcat(strNameFile, strTmp);
strcat(strNameFile, ".txt");


if( (stream = fopen( strNameFile, "a+" )) == NULL )
return TRUE;
//fprintf(stream,"al enviar: %s\n",bufdatos);
//fprintf(stream,"%s\n",bufsalida);
//fprintf(stream," tam msg envio: %i\n",numdatos);




if(numdatos<=0 || *bufdatos==' ')
{
fprintf(stream," Error de trama: %s\n",bufdatos);

//return -1;
}

if ((iCodError=send(sock, bufdatos, numdatos, 0)) <0)
{
//AfxMessageBox(_T("Error de send de Servidor a Host...") ,MB_OK);
fprintf(stream,"Error de send de Servidor a Host...al enviar:
%s\n",bufdatos);
fprintf(stream,"Codigo de error: %i\n",numdatos);
return -1;
}



int result=select(0,&set,0,0,&tval);
//for(int i=0;i<10000;i++) ;


- 85 -
//Se modifica el parametro de opcion del socket de la longuitud maxima
recibida del mismo.
//DWORD optval = SO_SEC_SSL;
int optvalpropio=10000;
//int optvalpropio=32000;
int cbOpt = sizeof( optvalpropio ),
//optvalpropio=20000;


//optvalpropio=20000;
err = setsockopt(sock,SOL_SOCKET,SO_RCVBUF,(char *)
&optvalpropio,cbOpt);
if( err < 0)
{unsigned int valortmp=optvalpropio;
//itoa( valortmp,tmpcadena, 10 );
//AfxMessageBox(_T(tmpcadena) ,MB_YESNO);
fprintf(stream,"Codigo de error de setsockopt: %i\n",numdatos);
}

err = getsockopt(sock,SOL_SOCKET,SO_RCVBUF,(char *)
&optvalpropio,&cbOpt);
if( err < 0)
{char tmpcadena[20]="";
unsigned int valortmp=optvalpropio;
itoa( valortmp,tmpcadena, 10 );
//AfxMessageBox(_T(tmpcadena) ,MB_YESNO);
fprintf(stream,"Codigo de error de getsockopt: %i\n",numdatos);
}



if((dat_recib=recv(sock,bufsalida,dat_maxrecib,0))<0)
{
//AfxMessageBox(_T("Error de recv de Host a Servidor...") ,MB_OK);
fprintf(stream,"Error de recv de Host a Servidor...:
%i\n",numdatos);
fclose(stream);
return -1;
}
else
{ long logrespbis=0;
char strrecibbis[32000]="";
long j=0;
while((logrespbis=recv(sock,strrecibbis,dat_maxrecib,0)) > 0)
{
for(j=0; j<logrespbis; j++)
{*(bufsalida+dat_recib+j)=*(strrecibbis+j);
}
*(bufsalida+dat_recib+j)='\0';

dat_recib=dat_recib+logrespbis;
}
*(bufsalida+dat_recib)='\0';
}
//Cerramos archivo log
fclose(stream);


- 86 -
/*for(int j=0;j++;j<dat_recib)
{
if(*(bufsalida+j)=='\0' || *(bufsalida+j)=='\n'
|| *(bufsalida+j)=='\r')
{*(bufsalida+j)=' ';
}
}*/


//throw("Error en recv. Recibiendo respuesta del servidor");
//Modificacion para log de errores
/*
char strTmp[10]="";
char strMensaje[50]="";
time_t ltime;
time( &ltime );
char *strtime=ctime(&ltime );


FILE *stream;
char strNameFile[50]="log";
strncpy(strTmp, strtime,3);
strcat(strNameFile, strTmp);
strncpy(strTmp, strtime+4,3);
strcat(strNameFile, strTmp);
strncpy(strTmp, strtime+8,2);
strcat(strNameFile, strTmp);
strcat(strNameFile, ".txt");


if( (stream = fopen( strNameFile, "a+" )) == NULL )
return TRUE;
fprintf(stream,"%s\n",bufdatos);
fprintf(stream,"%s\n",bufsalida);
fprintf(stream," tam msg sal %i\n",dat_recib);


fclose(stream);
*/

//int AfxMessageBox( LPCTSTR lpszText, UINT nType = MB_OK, UINT
nIDHelp = 0 );
*ndatosreciv=dat_recib;
/*ltoa( dat_recib, buffer, 10 );
AfxMessageBox(buffer,MB_OK,0);
AfxMessageBox(bufdatos,MB_OK,0);*/

return OK;
}



// DlgProxy.h : header file

- 87 -
//

#if
!defined(AFX_DLGPROXY_H__93616031_64C9_4AA8_9038_C09957C4D19E__INCLUDED_)
#define AFX_DLGPROXY_H__93616031_64C9_4AA8_9038_C09957C4D19E__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class CServerTCPDlg;

/////////////////////////////////////////////////////////////////////////
////
// CServerTCPDlgAutoProxy command target

class CServerTCPDlgAutoProxy : public CCmdTarget
{
DECLARE_DYNCREATE(CServerTCPDlgAutoProxy)

CServerTCPDlgAutoProxy(); // protected constructor used
by dynamic creation

// Attributes
public:
CServerTCPDlg* m_pDialog;

// Operations
public:

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CServerTCPDlgAutoProxy)
public:
virtual void OnFinalRelease();
//}}AFX_VIRTUAL

// Implementation
protected:
virtual ~CServerTCPDlgAutoProxy();

// Generated message map functions
//{{AFX_MSG(CServerTCPDlgAutoProxy)
// NOTE - the ClassWizard will add and remove member
functions here.
//}}AFX_MSG

DECLARE_MESSAGE_MAP()
DECLARE_OLECREATE(CServerTCPDlgAutoProxy)

// Generated OLE dispatch map functions
//{{AFX_DISPATCH(CServerTCPDlgAutoProxy)
// NOTE - the ClassWizard will add and remove member
functions here.
//}}AFX_DISPATCH
DECLARE_DISPATCH_MAP()
DECLARE_INTERFACE_MAP()

- 88 -
};

/////////////////////////////////////////////////////////////////////////
////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately
before the previous line.

#endif //
!defined(AFX_DLGPROXY_H__93616031_64C9_4AA8_9038_C09957C4D19E__INCLUDED_)

// DlgProxy.cpp : implementation file
//

#include "stdafx.h"
#include "ServerTCP.h"
#include "DlgProxy.h"
#include "ServerTCPDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////
////
// CServerTCPDlgAutoProxy

IMPLEMENT_DYNCREATE(CServerTCPDlgAutoProxy, CCmdTarget)

CServerTCPDlgAutoProxy::CServerTCPDlgAutoProxy()
{
EnableAutomation();

// To keep the application running as long as an automation
// object is active, the constructor calls AfxOleLockApp.
AfxOleLockApp();

// Get access to the dialog through the application's
// main window pointer. Set the proxy's internal pointer
// to point to the dialog, and set the dialog's back pointer to
// this proxy.
ASSERT (AfxGetApp()->m_pMainWnd != NULL);
ASSERT_VALID (AfxGetApp()->m_pMainWnd);
ASSERT_KINDOF(CServerTCPDlg, AfxGetApp()->m_pMainWnd);
m_pDialog = (CServerTCPDlg*) AfxGetApp()->m_pMainWnd;
m_pDialog->m_pAutoProxy = this;
}

CServerTCPDlgAutoProxy::~CServerTCPDlgAutoProxy()
{
// To terminate the application when all objects created with
// with automation, the destructor calls AfxOleUnlockApp.
// Among other things, this will destroy the main dialog

- 89 -
if (m_pDialog != NULL)
m_pDialog->m_pAutoProxy = NULL;
AfxOleUnlockApp();
}

void CServerTCPDlgAutoProxy::OnFinalRelease()
{
// When the last reference for an automation object is released
// OnFinalRelease is called. The base class will automatically
// deletes the object. Add additional cleanup required for your
// object before calling the base class.

CCmdTarget::OnFinalRelease();
}

BEGIN_MESSAGE_MAP(CServerTCPDlgAutoProxy, CCmdTarget)
//{{AFX_MSG_MAP(CServerTCPDlgAutoProxy)
// NOTE - the ClassWizard will add and remove mapping macros
here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

BEGIN_DISPATCH_MAP(CServerTCPDlgAutoProxy, CCmdTarget)
//{{AFX_DISPATCH_MAP(CServerTCPDlgAutoProxy)
// NOTE - the ClassWizard will add and remove mapping macros
here.
//}}AFX_DISPATCH_MAP
END_DISPATCH_MAP()

// Note: we add support for IID_IServerTCP to support typesafe binding
// from VBA. This IID must match the GUID that is attached to the
// dispinterface in the .ODL file.

// {4F07CD07-8179-4624-8EA6-080D1563F8EE}
static const IID IID_IServerTCP =
{ 0x4f07cd07, 0x8179, 0x4624, { 0x8e, 0xa6, 0x8, 0xd, 0x15, 0x63, 0xf8,
0xee } };

BEGIN_INTERFACE_MAP(CServerTCPDlgAutoProxy, CCmdTarget)
INTERFACE_PART(CServerTCPDlgAutoProxy, IID_IServerTCP, Dispatch)
END_INTERFACE_MAP()

// The IMPLEMENT_OLECREATE2 macro is defined in StdAfx.h of this project
// {DA04FF49-EB17-4D98-9CBB-7889A7291471}
IMPLEMENT_OLECREATE2(CServerTCPDlgAutoProxy, "ServerTCP.Application",
0xda04ff49, 0xeb17, 0x4d98, 0x9c, 0xbb, 0x78, 0x89, 0xa7, 0x29, 0x14,
0x71)

/////////////////////////////////////////////////////////////////////////
////
// CServerTCPDlgAutoProxy message handlers
// Parametros.h: interface for the CParametros class.
//
//////////////////////////////////////////////////////////////////////


- 90 -
#if
!defined(AFX_PARAMETROS_H__1B530A4A_C351_47B9_B47D_63ACF2601F44__INCLUDED
_)
#define AFX_PARAMETROS_H__1B530A4A_C351_47B9_B47D_63ACF2601F44__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class CParametros
{
public:
int m_puertoHost;
CString m_ipHost;
long maxDatosEntSal;
long tamSalida;
long tamEntrada;
char * pstrDatosSalida;
char * pstrDatosEntrada;
int SockProc;

CParametros();
virtual ~CParametros();

};

#endif //
!defined(AFX_PARAMETROS_H__1B530A4A_C351_47B9_B47D_63ACF2601F44__INCLUDED
_)

// Parametros.cpp: implementation of the CParametros class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "ServerTCP.h"
#include "Parametros.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CParametros::CParametros()
{

}

CParametros::~CParametros()
{


- 91 -
}

// ServerTCP.h : main header file for the SERVERTCP application
//

#if
!defined(AFX_SERVERTCP_H__1A43E420_B41F_4C7D_BDD4_8A2EC9E53734__INCLUDED_
)
#define AFX_SERVERTCP_H__1A43E420_B41F_4C7D_BDD4_8A2EC9E53734__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#ifndef __AFXWIN_H__
#error include 'stdafx.h' before including this file for PCH
#endif

#include "resource.h" // main symbols

/////////////////////////////////////////////////////////////////////////
////
// CServerTCPApp:
// See ServerTCP.cpp for the implementation of this class
//

class CServerTCPApp : public CWinApp
{
public:
CServerTCPApp();

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CServerTCPApp)
public:
virtual BOOL InitInstance();
//}}AFX_VIRTUAL

// Implementation

//{{AFX_MSG(CServerTCPApp)
// NOTE - the ClassWizard will add and remove member
functions here.
// DO NOT EDIT what you see in these blocks of generated
code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};


/////////////////////////////////////////////////////////////////////////
////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately
before the previous line.

- 92 -

#endif //
!defined(AFX_SERVERTCP_H__1A43E420_B41F_4C7D_BDD4_8A2EC9E53734__INCLUDED_
)

// ServerTCP.cpp : Defines the class behaviors for the application.
//

#include "stdafx.h"
#include "ServerTCP.h"
#include "ServerTCPDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////
////
// CServerTCPApp

BEGIN_MESSAGE_MAP(CServerTCPApp, CWinApp)
//{{AFX_MSG_MAP(CServerTCPApp)
// NOTE - the ClassWizard will add and remove mapping macros
here.
// DO NOT EDIT what you see in these blocks of generated
code!
//}}AFX_MSG
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////
////
// CServerTCPApp construction

CServerTCPApp::CServerTCPApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}

/////////////////////////////////////////////////////////////////////////
////
// The one and only CServerTCPApp object

CServerTCPApp theApp;

/////////////////////////////////////////////////////////////////////////
////
// CServerTCPApp initialization

BOOL CServerTCPApp::InitInstance()
{
if (!AfxSocketInit())
{

- 93 -
AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
return FALSE;
}

// Initialize OLE libraries
if (!AfxOleInit())
{
AfxMessageBox(IDP_OLE_INIT_FAILED);
return FALSE;
}

AfxEnableControlContainer();

// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.

#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a
shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC
statically
#endif

// Parse the command line to see if launched as OLE server
if (RunEmbedded() || RunAutomated())
{
// Register all OLE server (factories) as running. This
enables the
// OLE libraries to create objects from other applications.
COleTemplateServer::RegisterAll();
}
else
{
// When a server application is launched stand-alone, it is a
good idea
// to update the system registry in case it has been
damaged.
COleObjectFactory::UpdateRegistryAll();
}

CServerTCPDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
}


- 94 -
// Since the dialog has been closed, return FALSE so that we exit
the
// application, rather than start the application's message pump.
return FALSE;
}

// ServerTCPDlg.h : header file
//

#if
!defined(AFX_SERVERTCPDLG_H__5D44512B_F398_4187_9C0B_E2592151AC9C__INCLUD
ED_)
#define
AFX_SERVERTCPDLG_H__5D44512B_F398_4187_9C0B_E2592151AC9C__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class CServerTCPDlgAutoProxy;

/////////////////////////////////////////////////////////////////////////
////
// CServerTCPDlg dialog

class CServerTCPDlg : public CDialog
{
DECLARE_DYNAMIC(CServerTCPDlg);
friend class CServerTCPDlgAutoProxy;

// Construction
public:
CServerTCPDlg(CWnd* pParent = NULL); // standard constructor
virtual ~CServerTCPDlg();

// Dialog Data
//{{AFX_DATA(CServerTCPDlg)
enum { IDD = IDD_SERVERTCP_DIALOG };
CString m_ipServer;
CString m_ipHost;
int m_puertoHost;
int m_PuertoServer;
//}}AFX_DATA

// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CServerTCPDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV
support
//}}AFX_VIRTUAL

// Implementation
protected:
CServerTCPDlgAutoProxy* m_pAutoProxy;
HICON m_hIcon;


- 95 -
BOOL CanExit();

// Generated message map functions
//{{AFX_MSG(CServerTCPDlg)
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnClose();
virtual void OnOK();
virtual void OnCancel();
afx_msg void OnEjecuta();
afx_msg void OnFin();
afx_msg void OnSetfocusIpServer();
afx_msg void OnModifconfig();
afx_msg void OnCheckConfig();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately
before the previous line.

#endif //
!defined(AFX_SERVERTCPDLG_H__5D44512B_F398_4187_9C0B_E2592151AC9C__INCLUD
ED_)

// ServerTCPDlg.cpp : implementation file
//

#include "stdafx.h"
#include "ServerTCP.h"
#include "ServerTCPDlg.h"
#include "DlgProxy.h"

#include <afxmt.h>
#include "servidor.h"
#include "Parametros.h"

#include <omp.h>


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////
////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:

- 96 -
CAboutDlg();

// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA

// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV
support
//}}AFX_VIRTUAL

// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////
////
// CServerTCPDlg dialog

IMPLEMENT_DYNAMIC(CServerTCPDlg, CDialog);

CServerTCPDlg::CServerTCPDlg(CWnd* pParent /*=NULL*/)
: CDialog(CServerTCPDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CServerTCPDlg)
m_ipServer = _T("");
m_ipHost = _T("");
m_puertoHost = 0;
m_PuertoServer = 0;
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in
Win32

- 97 -

}

CServerTCPDlg::~CServerTCPDlg()
{
// If there is an automation proxy for this dialog, set
// its back pointer to this dialog to NULL, so it knows
// the dialog has been deleted.
if (m_pAutoProxy != NULL)
m_pAutoProxy->m_pDialog = NULL;
}

void CServerTCPDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CServerTCPDlg)
DDX_Text(pDX, IDC_IP_SERVER, m_ipServer);
DDV_MaxChars(pDX, m_ipServer, 15);
DDX_Text(pDX, IDC_IP_HOST, m_ipHost);
DDV_MaxChars(pDX, m_ipHost, 15);
DDX_Text(pDX, IDC_PUERTO_HOST, m_puertoHost);
DDV_MinMaxInt(pDX, m_puertoHost, 0, 999999);
DDX_Text(pDX, IDC_PUERTO_SERVER, m_PuertoServer);
//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CServerTCPDlg, CDialog)
//{{AFX_MSG_MAP(CServerTCPDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_CLOSE()
ON_BN_CLICKED(IDEJECUTA, OnEjecuta)
ON_BN_CLICKED(IDC_FIN, OnFin)
ON_EN_SETFOCUS(IDC_IP_SERVER, OnSetfocusIpServer)
ON_BN_CLICKED(IDC_MODIFCONFIG, OnModifconfig)
ON_BN_CLICKED(IDC_CHECK1, OnCheckConfig)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////
////
// CServerTCPDlg message handlers
const int MaxLineas=100;
CEvent EvTerminar(FALSE, TRUE);
BOOL banderaProceso = TRUE;

UINT ThreadProc( LPVOID pdialog)
{
EvTerminar.ResetEvent();
CSingleLock slTerminar(&EvTerminar);

CServerTCPDlg *pSDlg=(CServerTCPDlg *)pdialog;
//CParametros *pParam=(CParametros *)pSDlg->GetDlgItem(IDC_EDIT1);
CString ip_server=pSDlg->m_ipServer;
CString ip_host=pSDlg->m_ipHost;
int puerto_server=pSDlg->m_PuertoServer ;

- 98 -
int puerto_host=pSDlg->m_puertoHost;
char DatosEntrada[32000]="";
char DatosSalida[32000]="";
long cuantosLeidos=0;
long datosenviados=0;
CParametros param;
param.m_ipHost =ip_host;
param.m_puertoHost =puerto_host;


banderaProceso=TRUE;
/*
for(int i=0; i<32000; i++)
{*(DatosEntrada+i)=' ';
*(DatosSalida+i)=' ';
}
*/

//CServidor servidor((LPCSTR)pSDlg->m_IPDir,pSDlg->m_IPPuerto);
//CServidor servidor("150.100.102.142",3220);
CServidor servidor(ip_server,puerto_server);
while(1)
{
for(int i=0; i<32000; i++)
{*(DatosEntrada+i)=' ';
*(DatosSalida+i)=' ';
}
cuantosLeidos=0;
datosenviados=0;
*DatosEntrada='\0';
*DatosSalida='\0';


if(servidor.servicio(DatosEntrada,DatosSalida,32000,cuantosLeidos,datosen
viados,100,param)==OK)
{
//DatosEntrada[cuantosLeidos]=0;
//DatosSalida[cuantosLeidos]=0;
}
else
if(banderaProceso==FALSE)
break;

}//fin while

//falta indicar la direccin de loopback si hay problemas.
return 0;
}





BOOL CServerTCPDlg::OnInitDialog()
{ FILE *stream;
char ip[30]="";
char puerto[30]="";

- 99 -
char ip_Host[30]="";
char puerto_Host[30]="";

CDialog::OnInitDialog();

// Add "About..." menu item to system menu.

// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX,
strAboutMenu);
}
}

// Set the icon for this dialog. The framework does this
automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_pAutoProxy = NULL;
CEdit *p_EditIpServer = (CEdit *)GetDlgItem(IDC_IP_SERVER);
p_EditIpServer->EnableWindow(FALSE);
CEdit *p_EditPuertoServer = (CEdit *)GetDlgItem(IDC_PUERTO_SERVER);
p_EditPuertoServer->EnableWindow(FALSE);
CEdit *p_EditIpHost = (CEdit *)GetDlgItem(IDC_IP_HOST);
p_EditIpHost->EnableWindow(FALSE);
CEdit *p_EditPuertoHost = (CEdit *)GetDlgItem(IDC_PUERTO_HOST);
p_EditPuertoHost->EnableWindow(FALSE);
CButton *p_BotonModifica=(CButton *)GetDlgItem(IDC_MODIFCONFIG);
p_BotonModifica->EnableWindow(FALSE);
//Anexar datos de Archivo
//Abre el archivo en la ruta actual del ejecutable, en este caso
del proyecto.
if( (stream = fopen( "ippuerto.txt", "r+" )) == NULL )
return TRUE;
fscanf(stream,"%s",ip);
fscanf(stream,"%s",puerto);
fscanf(stream,"%s",ip_Host);
fscanf(stream,"%s",puerto_Host);

fclose(stream);
//AfxMessageBox(_T(ip) ,MB_OK);
//AfxMessageBox(_T(puerto) ,MB_OK);
//AfxMessageBox(_T(ip_Host) ,MB_OK);

- 100 -
//AfxMessageBox(_T(puerto_Host) ,MB_OK);
m_ipServer = _T(ip);
m_PuertoServer = atoi( puerto );
m_ipHost = _T(ip_Host);
m_puertoHost = atoi(puerto_Host);

UpdateData(FALSE);
return TRUE; // return TRUE unless you set the focus to a control
}

void CServerTCPDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}

// If you add a minimize button to your dialog, you will need the code
below
// to draw the icon. For MFC applications using the document/view
model,
// this is automatically done for you by the framework.

void CServerTCPDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting

SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;

// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}

// The system calls this to obtain the cursor to display while the user
drags
// the minimized window.

- 101 -
HCURSOR CServerTCPDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}

// Automation servers should not exit when a user closes the UI
// if a controller still holds on to one of its objects. These
// message handlers make sure that if the proxy is still in use,
// then the UI is hidden but the dialog remains around if it
// is dismissed.

void CServerTCPDlg::OnClose()
{
if (CanExit())
CDialog::OnClose();
}

void CServerTCPDlg::OnOK()
{
if (CanExit())
CDialog::OnOK();
}

void CServerTCPDlg::OnCancel()
{
if (CanExit())
CDialog::OnCancel();
}

BOOL CServerTCPDlg::CanExit()
{
// If the proxy object is still around, then the automation
// controller is still holding on to this application. Leave
// the dialog around, but hide its UI.
if (m_pAutoProxy != NULL)
{
ShowWindow(SW_HIDE);
return FALSE;
}

return TRUE;
}

void CServerTCPDlg::OnEjecuta()
{
// TODO: Add your control notification handler code here
EvTerminar.SetEvent();
AfxBeginThread(ThreadProc,this);
/*
char DatosEntrada[32000];
char DatosSalida[32000];
long cuantosLeidos;
long datosenviados;


banderaProceso=TRUE;
//CServidor servidor((LPCSTR)pSDlg->m_IPDir,pSDlg->m_IPPuerto);

- 102 -
CServidor servidor("150.100.102.142",3220);
while(1)
{

if(servidor.servicio(DatosEntrada,DatosSalida,32000,cuantosLeidos,datosen
viados,100)==OK)
{

}
else
if(banderaProceso==FALSE)
break;

}//fin while

*/


//Desabilitar control y activar bandera para que posteriormente el
usuario pueda cancerlar el
//Server atravez de otro pushbutton
CButton *p_Boton=(CButton *)GetDlgItem(IDEJECUTA);
p_Boton->EnableWindow(FALSE);

}

void CServerTCPDlg::OnFin()
{
// TODO: Add your control notification handler code here
banderaProceso=FALSE;
CButton *p_Boton=(CButton *)GetDlgItem(IDEJECUTA);
p_Boton->EnableWindow(TRUE);
}

void CServerTCPDlg::OnSetfocusIpServer()
{
// TODO: Add your control notification handler code here

}

void CServerTCPDlg::OnModifconfig()
{
// TODO: Add your control notification handler code here

UpdateData(TRUE);
/*m_ipServer = _T(ip);
m_PuertoServer = _T(puerto);
m_ipHost = _T(ip_Host);
m_puertoHost = _T(puerto_Host);
*/
}

void CServerTCPDlg::OnCheckConfig()
{
// TODO: Add your control notification handler code here
CButton *p_Boton=(CButton *)GetDlgItem(IDC_CHECK1);
if (p_Boton->GetCheck()==1)

- 103 -
{
CEdit *p_EditIpServer = (CEdit *)GetDlgItem(IDC_IP_SERVER);
p_EditIpServer->EnableWindow(TRUE);
CEdit *p_EditPuertoServer = (CEdit
*)GetDlgItem(IDC_PUERTO_SERVER);
p_EditPuertoServer->EnableWindow(TRUE);
CEdit *p_EditIpHost = (CEdit *)GetDlgItem(IDC_IP_HOST);
p_EditIpHost->EnableWindow(TRUE);
CEdit *p_EditPuertoHost = (CEdit
*)GetDlgItem(IDC_PUERTO_HOST);
p_EditPuertoHost->EnableWindow(TRUE);
CButton *p_BotonModifica=(CButton
*)GetDlgItem(IDC_MODIFCONFIG);
p_BotonModifica->EnableWindow(TRUE);
}
else
{ CEdit *p_EditIpServer = (CEdit *)GetDlgItem(IDC_IP_SERVER);
p_EditIpServer->EnableWindow(FALSE);
CEdit *p_EditPuertoServer = (CEdit
*)GetDlgItem(IDC_PUERTO_SERVER);
p_EditPuertoServer->EnableWindow(FALSE);
CEdit *p_EditIpHost = (CEdit *)GetDlgItem(IDC_IP_HOST);
p_EditIpHost->EnableWindow(FALSE);
CEdit *p_EditPuertoHost = (CEdit
*)GetDlgItem(IDC_PUERTO_HOST);
p_EditPuertoHost->EnableWindow(FALSE);
CButton *p_BotonModifica=(CButton
*)GetDlgItem(IDC_MODIFCONFIG);
p_BotonModifica->EnableWindow(FALSE);

}
}

// Servidor.h: interface for the CServidor class.
//
//////////////////////////////////////////////////////////////////////

#if
!defined(AFX_SERVIDOR_H__5B8F2810_EE0F_43E0_B391_8ACCCA49E3E5__INCLUDED_)
#define AFX_SERVIDOR_H__5B8F2810_EE0F_43E0_B391_8ACCCA49E3E5__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "sockbase.h"
#include "Parametros.h"
class CServidor : public Csockbase
{
long bytes_recibidos;
struct sockaddr_in addrservicio,addrcliente;
public:
CServidor(const char *SrcIPAddr=0,int IPPort=0);
virtual ~CServidor();
int servicio(char *bufdatosIn, char *bufdatosOut,long maxdatos, long
&datosleidos, long &datosenviados,int timeout, CParametros parametros);

- 104 -
int GetPort();
char *GetAddr();
int GetPortUltimoServicio();
char *GetAddrUltimoServicio();
int GetPortUltimoCliente();
char *GetAddrUltimoCliente();
};

#endif //
!defined(AFX_SERVIDOR_H__5B8F2810_EE0F_43E0_B391_8ACCCA49E3E5__INCLUDED_)

// Servidor.cpp: implementation of the CServidor class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "ServerTCP.h"
#include "Servidor.h"
#include "Cliente.h"
#include "Parametros.h"
#include <time.h>

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CServidor::CServidor(const char *SrcIPAddr,int IPPort)
{
if (( sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
AfxMessageBox(_T("Error de socket...") ,MB_OK);
//throw("Error creando socket SOCK_STREAM");

memset(&addr, 0, sizeof (addr));
addr.sin_family = AF_INET;
if(!SrcIPAddr)
addr.sin_addr.s_addr = INADDR_ANY;
else
addr.sin_addr.s_addr= inet_addr(SrcIPAddr);
addr.sin_port = htons(IPPort);
lenaddr=sizeof(addr);
//Se asocia el socket TCP a la direccion de recepcion,
//Es la direccion de escucha del Servidor
if (bind (sock, (struct sockaddr *) &addr, lenaddr) == -1 )
AfxMessageBox(_T("Error de bind...") ,MB_OK);
//throw ("Error en bind");
if(getsockname(sock,(struct sockaddr *)&addr,&lenaddr)==-1)
AfxMessageBox(_T("Error de getsockname...") ,MB_OK);
//throw ("error en getsockname");
listen(sock,5);
}

- 105 -

UINT ThreadSockProc( LPVOID pdialog)
{
int iErrorLong=0;
//Manejo de archivo para grabar log de depuracion en produccion.
char strMensajeEnt[32000]="";
char strTmp[10]="";
char strMensaje[50]="";
//AfxMessageBox(_T(strMensaje) ,MB_OK);
time_t ltime;
time( &ltime );
char *strtime=ctime(&ltime );
//AfxMessageBox(_T(strtime) ,MB_OK);
strcpy(strTmp,"");

FILE *stream;
char strNameFile[50]="log";
strncpy(strTmp, strtime,3);
strcat(strNameFile, strTmp);
strncpy(strTmp, strtime+4,3);
strcat(strNameFile, strTmp);
strncpy(strTmp, strtime+8,2);
strcat(strNameFile, strTmp);
strcat(strNameFile, ".txt");

if( (stream = fopen(strNameFile , "a+" )) == NULL )
AfxMessageBox(_T("Error al abrir archivo log*.txt...") ,MB_OK);


CParametros *ptrobjParametros = (CParametros *)pdialog;

//Recibe los datos de entrada del Socket aceptado, en base a los
parametros pasados.
//Se comenta y se modifica para pruebas, y eleminacion de problemas.
//iErrorLong =recv(ptrobjParametros->SockProc ,ptrobjParametros-
>pstrDatosEntrada,ptrobjParametros->maxDatosEntSal ,0);
iErrorLong =recv(ptrobjParametros->SockProc ,strMensajeEnt,32000 ,0);

if (iErrorLong < 0)
{
fprintf(stream,"Tam Ent: %i\n",iErrorLong);
//AfxMessageBox(_T("Error de recv de Cte...") ,MB_OK);
fclose(stream);
return -1;
}

//Se comenta para correccion
//ptrobjParametros->tamEntrada=iErrorLong;
//int tamEnt=ptrobjParametros->tamEntrada;
//char *ptrMsg1=ptrobjParametros->pstrDatosEntrada;
char *ptrMsg1=strMensajeEnt;

//fprintf(stream,"Como es recibida: %s\n",ptrMsg1);
//Meter modificacion para que la trama de entrada se recupere la
longitud de la cadena y atraves de
//esta corta la longitud que debe de ser
char cadTamTrama[6]="";

- 106 -
int j=0;
for( j=0; j < 5;j++)
*(cadTamTrama+j)=*(ptrMsg1+9+j);
*(cadTamTrama+j)='\0';
j=0;
j = atoi(cadTamTrama);
//Modificacion y se comenta para usar la long que viene en el MD
*(ptrMsg1+j)='\0';
//*(ptrMsg1+iErrorLong)='\0';


//Graba cadena acotada por longitud, descomentar para validar problemas
//fprintf(stream,"Trama a enviar y acotada: %s\n",ptrMsg1);
//fprintf(stream,"Tam Ent: %i\n",j);
fclose(stream);
//fprintf(stream,"Trama a enviar y acotada: %s\n",ptrobjParametros-
>pstrDatosEntrada);
//fprintf(stream,"Tam Ent: %i\n",iErrorLong);



//fclose(stream);
//Fin manejo de archivo log
// throw("Error en recv");
//***************************
//Retrasmite la informacion a la IP de Host
CCliente objCte(ptrobjParametros->m_ipHost,ptrobjParametros-
>m_puertoHost);

//CCliente objCte("150.50.102.15",3224);
//comentado para pruebas
//objCte.PedirServicio(ptrobjParametros-
>pstrDatosEntrada,ptrobjParametros->tamEntrada,ptrobjParametros-
>pstrDatosSalida,(long *)&ptrobjParametros->tamSalida );
if( (stream = fopen(strNameFile , "a+" )) == NULL )
AfxMessageBox(_T("Error al abrir archivo log*.txt...") ,MB_OK);

if(*ptrMsg1==' ' || *ptrMsg1=='\0')
{
//AfxMessageBox(_T("Error al recibir trama entrada en servidor")
,MB_OK);
fprintf(stream,"Trama erronea: %s\n",ptrobjParametros-
>pstrDatosEntrada);
fclose(stream);
return -1;
}
fclose(stream);
//Se comenta oara correccion de problema
//objCte.PedirServicio(ptrMsg1,ptrobjParametros-
>tamEntrada,ptrobjParametros->pstrDatosSalida,(long *)&ptrobjParametros-
>tamSalida );
objCte.PedirServicio(ptrMsg1,iErrorLong,ptrobjParametros-
>pstrDatosSalida,(long *)&ptrobjParametros->tamSalida );

//fprintf(stream,"Trama respuesta: %s\n",ptrobjParametros-
>pstrDatosSalida);

- 107 -
//fprintf(stream,"Tam Trama respuesta: %i\n",ptrobjParametros-
>tamSalida);

if( (stream = fopen(strNameFile , "a+" )) == NULL )
AfxMessageBox(_T("Error al abrir archivo log*.txt...") ,MB_OK);

//***************************
//Fin de Retrasmitir la informacion a la IP de Host
//**
//devolvemos los resultados a la maquina Cliente Original.
iErrorLong=0;
if ((iErrorLong=send(ptrobjParametros->SockProc,ptrobjParametros-
>pstrDatosSalida ,ptrobjParametros->tamSalida,0)) < 0)
{ fprintf(stream,"Error de send de Servidor a Cte...:
%i\n",iErrorLong);
fclose(stream);
//AfxMessageBox(_T("Error de send de Servidor a Cte...") ,MB_OK);
}
fclose(stream);
//damos por terminada la comunicacin.
closesocket(ptrobjParametros->SockProc);
delete ptrobjParametros;
return 0;
}

CServidor::~CServidor()
{
//destruir la conexion si sigue activa y hacer limpieza
closesocket(sock);

}


//recibe en bufdatos como maximo maxdatos (si hay mas retorna error)
int CServidor::servicio(char *bufdatosIn, char *bufdatosOut, long
maxdatosInOut,
long &datosleidos,long &datosenviados, int
timeout, CParametros parametros)
{
//Primero se construye la estructura de timeouts
//Un conjunto de sockets a comprobar si tienen peticiones
fd_set set;
FD_ZERO(&set);
FD_SET(sock,&set);
//...y el tiempo mximo a esperar si hay buffer de entrada
struct timeval tval;
tval.tv_sec=10;
tval.tv_usec=timeout;
//se suspende la ejecucin hasta que haya peticin o
//se cumpla el tiempo de espera
//se modifico para validar el tiempo de espera a indefinido.
int result=select(0,&set,0,0,NULL);
//int result=select(0,&set,0,0,&tval);
if(result==0) return ETIMEOUT; //retornar si cumple tiempo espera
//hay peticin y se procesa.
int sockacept=accept(sock,(struct sockaddr *) &addr, (int *) &lenaddr
);

- 108 -
if(sockacept==-1)
{
AfxMessageBox(_T("Error de accept...") ,MB_OK);
return EACCEPT;
}
//throw("Error en accept");

//obtenemos datos del socket creado por el sitema para atender
//el servicio
/*
int lenaddrservicio= sizeof addr;
if( getsockname( sockacept, (struct sockaddr *) &addrservicio,
&lenaddrservicio ) ==-1)
throw("Error averiguando sockaddr_in del socket asignado para el
servicio");

int lenaddrcliente= sizeof addrcliente;
if( getpeername( sockacept, (struct sockaddr *) &addrcliente,
&lenaddrcliente ) ==-1)
throw("Error averiguando sockaddr_in del socket cliente conectado
a este");
*/

//printf("Socket port #%d\n", ntohs( server.sin_port));

//Con los datos del cliente se podra decidor si se acepta o no
//la peticin...

//Se reciben los datos.
//retval=recv(sockacept,bufdatosIn,maxdatosInOut,0);
//if (retval==-1)
// throw("Error en recv");
//xxdatosleidos=retval;
//char cadena[32000]="";



CParametros *ptrObjParam= new CParametros;
ptrObjParam->SockProc=sockacept;
ptrObjParam->pstrDatosEntrada=bufdatosIn;
ptrObjParam->maxDatosEntSal= maxdatosInOut ;
ptrObjParam->pstrDatosSalida=bufdatosOut;
ptrObjParam->m_ipHost =parametros.m_ipHost ;
ptrObjParam->m_puertoHost= parametros.m_puertoHost ;
/*
CParametros *ptrObjParam= &parametros;
ptrObjParam->SockProc=sockacept;
ptrObjParam->pstrDatosEntrada=bufdatosIn;
ptrObjParam->maxDatosEntSal= maxdatosInOut ;
ptrObjParam->pstrDatosSalida=bufdatosOut;
*/
//Modificacion para pruebas
//CWinThread *pThr;
//pThr=AfxBeginThread(ThreadSockProc,ptrObjParam);

#pragma omp parallel
{

- 109 -
//#pragma omp single
//Ahi que cambiar el procedimiento y paso de parametros.
AfxBeginThread(ThreadSockProc,ptrObjParam);

}


//***************************
//Retrasmite la informacion a la IP de Host
//CCliente objCte("150.50.102.15",3224);
//objCte.PedirServicio(bufdatosIn,retval,bufdatosOut,&datosleidos);


//***************************
//Fin de Retrasmite la informacion a la IP de Host

//devolvemos los resultados
//if (send(sockacept,bufdatosOut,datosleidos,0) <0)
// throw("Error en send contestando al cliente");
//damos por terminada la comunicacin.

//closesocket(sockacept);
return OK;
}

int CServidor::GetPort()
{
return ntohs(addr.sin_port);
}
char *CServidor::GetAddr()
{
return inet_ntoa(addr.sin_addr);
}
int CServidor::GetPortUltimoServicio()
{
return ntohs(addrservicio.sin_port);
}
char *CServidor::GetAddrUltimoServicio()
{
return inet_ntoa(addrservicio.sin_addr);
}
int CServidor::GetPortUltimoCliente()
{
return ntohs(addrcliente.sin_port);
}
char *CServidor::GetAddrUltimoCliente()
{
return inet_ntoa(addrcliente.sin_addr);
}








- 110 -
// sockbase.h: interface for the Csockbase class.
//
//////////////////////////////////////////////////////////////////////

#if
!defined(AFX_SOCKBASE_H__9C4836F8_DA0A_4A10_B931_1724EAF90048__INCLUDED_)
#define AFX_SOCKBASE_H__9C4836F8_DA0A_4A10_B931_1724EAF90048__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <Afxsock.h>
#include <winsock.h>
#include <sys/types.h>
#include <stdio.h>

const int DefaultTTL=1;

const int ERRBASE=65536;
const int OK=0;
const int ESEND = ERRBASE+1;
const int ERECV = ERRBASE+2;
const int ETIMEOUT = ERRBASE+3;
const int EACCEPT = ERRBASE+4;

class Csockbase
{
public:
struct sockaddr_in addr; // direccin
int lenaddr; // longitud de la direccion
int sock; // socket
int err;
int retval;
Csockbase();
virtual ~Csockbase();

};

#endif //
!defined(AFX_SOCKBASE_H__9C4836F8_DA0A_4A10_B931_1724EAF90048__INCLUDED_)

// sockbase.cpp: implementation of the Csockbase class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "ServerTCP.h"
#include "sockbase.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif


- 111 -
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

Csockbase::Csockbase()
{

}

Csockbase::~Csockbase()
{

}

// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//

#if
!defined(AFX_STDAFX_H__21013768_D8C6_4A23_9000_9DF0CC1E49B2__INCLUDED_)
#define AFX_STDAFX_H__21013768_D8C6_4A23_9000_9DF0CC1E49B2__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows
headers

#include <afxwin.h> // MFC core and standard components
#include <afxext.h> // MFC extensions
#include <afxdisp.h> // MFC Automation classes
#include <afxdtctl.h> // MFC support for Internet Explorer 4
Common Controls
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // MFC support for Windows Common
Controls
#endif // _AFX_NO_AFXCMN_SUPPORT

#include <afxsock.h> // MFC socket extensions

// This macro is the same as IMPLEMENT_OLECREATE, except it passes TRUE
// for the bMultiInstance parameter to the COleObjectFactory
constructor.
// We want a separate instance of this application to be launched for
// each automation proxy object requested by automation controllers.
#ifndef IMPLEMENT_OLECREATE2
#define IMPLEMENT_OLECREATE2(class_name, external_name, l, w1, w2, b1,
b2, b3, b4, b5, b6, b7, b8) \
AFX_DATADEF COleObjectFactory class_name::factory(class_name::guid,
\
RUNTIME_CLASS(class_name), TRUE, _T(external_name)); \
const AFX_DATADEF GUID class_name::guid = \
{ l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } };
#endif // IMPLEMENT_OLECREATE2

- 112 -

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately
before the previous line.

#endif //
!defined(AFX_STDAFX_H__21013768_D8C6_4A23_9000_9DF0CC1E49B2__INCLUDED_)

// stdafx.cpp : source file that includes just the standard includes
// ServerTCP.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information

#include "stdafx.h"

























- 113 -

Fuentes del cdigo de encripcin
TDESIVR.h
/** HYGATSJ
**********************************************************************************/

// The following ifdef block is the standard way of creating macros which make exporting
// from a DLL simpler. All files within this DLL are compiled with the TDESIVR_EXPORTS
// symbol defined on the command line. this symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see
// TDESIVR_API functions as being imported from a DLL, wheras this DLL sees symbols
// defined with this macro as being exported.

#ifdef TDESIVR_EXPORTS
#define TDESIVR_API __declspec(dllexport)
#else
#define TDESIVR_API __declspec(dllimport)
#endif


TDESIVR_API long IVRCipher(IQVAL line,
PUSERDLLPARAM32 InputMsg,
PUSERDLLPARAM32 OutputMsg,
PUSERDLLPARAM32 Servicio);

TDESIVR_API long TDESCipher(char *InputMsg,
char *OutputMsg,
int *MsgLen,
char *Servicio,
int *OutMsgLen);

long __stdcall VBCipher(char *InputMsg,
char *OutputMsg,
int *MsgLen,
char *Servicio);

/** Fin del header TDESIVR.h
*****************************************************************/













- 114 -

TDESIVR.cpp
// TDESIVR.cpp : Defines the entry point for the DLL application.
//

#include "StdAfx.h"
#define TDESIVR_EXPORTS
#include "TDESIVR.h"
#include "CnvBase64.h"


BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}

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

IQCOMPATIBLE (IQLEVEL_COMPATIBLE)

/** HYGATSJ
**********************************************************************************/

/** Area de redefiniciones
*******************************************************************/

union Vector_Type
{
unsigned char Vector_Chr[4];
unsigned int Vector_Int;
};

/** Area de estructuras
**********************************************************************/

struct find_a_bit
{
int which_Byte;
int which_bit;
};

struct key_type
{
unsigned char KeyVal[6];
};

struct s_type
{
unsigned char s_val[4][16];
};

struct s_RowBit_Type
{
int s_RowByte_H;
int s_RowBit_H;
int s_RowByte_L;
int s_RowBit_L;
};

struct s_ColBit_Type
{
int s_ColByte_1;
int s_ColBit_1;
int s_ColByte_2;
int s_ColBit_2;

- 115 -
int s_ColByte_3;
int s_ColBit_3;
int s_ColByte_4;
int s_ColBit_4;
};

/** Area de definicin de constantes
*********************************************************/

static struct find_a_bit IP_L0 [32] =
{{07,01},{06,01},{05,01},{04,01},{03,01},{02,01},{01,01},{00,01},

{07,03},{06,03},{05,03},{04,03},{03,03},{02,03},{01,03},{00,03},

{07,05},{06,05},{05,05},{04,05},{03,05},{02,05},{01,05},{00,05},

{07,07},{06,07},{05,07},{04,07},{03,07},{02,07},{01,07},{00,07}};

static struct find_a_bit IP_R0 [32] =
{{07,00},{06,00},{05,00},{04,00},{03,00},{02,00},{01,00},{00,00},

{07,02},{06,02},{05,02},{04,02},{03,02},{02,02},{01,02},{00,02},

{07,04},{06,04},{05,04},{04,04},{03,04},{02,04},{01,04},{00,04},

{07,06},{06,06},{05,06},{04,06},{03,06},{02,06},{01,06},{00,06}};

static struct find_a_bit E [48] =
{{03,07},{00,00},{00,01},{00,02},{00,03},{00,04},{00,03},{00,04},

{00,05},{00,06},{00,07},{01,00},{00,07},{01,00},{01,01},{01,02},

{01,03},{01,04},{01,03},{01,04},{01,05},{01,06},{01,07},{02,00},

{01,07},{02,00},{02,01},{02,02},{02,03},{02,04},{02,03},{02,04},

{02,05},{02,06},{02,07},{03,00},{02,07},{03,00},{03,01},{03,02},

{03,03},{03,04},{03,03},{03,04},{03,05},{03,06},{03,07},{00,00}};

static struct find_a_bit P [32] =
{{01,07},{00,06},{02,03},{02,04},{03,04},{01,03},{03,03},{02,00},

{00,00},{01,06},{02,06},{03,01},{00,04},{02,01},{03,06},{01,01},

{00,01},{00,07},{02,07},{01,05},{03,07},{03,02},{00,02},{01,00},

{02,02},{01,04},{03,05},{00,05},{02,05},{01,02},{00,03},{03,00}};

static struct find_a_bit PC_Inv [64] =
{{04,07},{00,07},{05,07},{01,07},{06,07},{02,07},{07,07},{03,07},

{04,06},{00,06},{05,06},{01,06},{06,06},{02,06},{07,06},{03,06},

{04,05},{00,05},{05,05},{01,05},{06,05},{02,05},{07,05},{03,05},

{04,04},{00,04},{05,04},{01,04},{06,04},{02,04},{07,04},{03,04},

{04,03},{00,03},{05,03},{01,03},{06,03},{02,03},{07,03},{03,03},

{04,02},{00,02},{05,02},{01,02},{06,02},{02,02},{07,02},{03,02},

{04,01},{00,01},{05,01},{01,01},{06,01},{02,01},{07,01},{03,01},

{04,00},{00,00},{05,00},{01,00},{06,00},{02,00},{07,00},{03,00}};

static struct s_type s_function [8] =
{0xE0,0x40,0xD0,0x10,0x20,0xF0,0xB0,0x80,0x30,0xA0,0x60,0xC0,0x50,0x90,0x00,0x70,

0x00,0xF0,0x70,0x40,0xE0,0x20,0xD0,0x10,0xA0,0x60,0xC0,0xB0,0x90,0x50,0x30,0x80,

- 116 -

0x40,0x10,0xE0,0x80,0xD0,0x60,0x20,0xB0,0xF0,0xC0,0x90,0x70,0x30,0xA0,0x50,0x00,

0xF0,0xC0,0x80,0x20,0x40,0x90,0x10,0x70,0x50,0xB0,0x30,0xE0,0xA0,0x00,0x60,0xD0,


0x0F,0x01,0x08,0x0E,0x06,0x0B,0x03,0x04,0x09,0x07,0x02,0x0D,0x0C,0x00,0x05,0x0A,

0x03,0x0D,0x04,0x07,0x0F,0x02,0x08,0x0E,0x0C,0x00,0x01,0x0A,0x06,0x09,0x0B,0x05,

0x00,0x0E,0x07,0x0B,0x0A,0x04,0x0D,0x01,0x05,0x08,0x0C,0x06,0x09,0x03,0x02,0x0F,

0x0D,0x08,0x0A,0x01,0x03,0x0F,0x04,0x02,0x0B,0x06,0x07,0x0C,0x00,0x05,0x0E,0x09,


0xA0,0x00,0x90,0xE0,0x60,0x30,0xF0,0x50,0x10,0xD0,0xC0,0x70,0xB0,0x40,0x20,0x80,

0xD0,0x70,0x00,0x90,0x30,0x40,0x60,0xA0,0x20,0x80,0x50,0xE0,0xC0,0xB0,0xF0,0x10,

0xD0,0x60,0x40,0x90,0x80,0xF0,0x30,0x00,0xB0,0x10,0x20,0xC0,0x50,0xA0,0xE0,0x70,

0x10,0xA0,0xD0,0x00,0x60,0x90,0x80,0x70,0x40,0xF0,0xE0,0x30,0xB0,0x50,0x20,0xC0,


0x07,0x0D,0x0E,0x03,0x00,0x06,0x09,0x0A,0x01,0x02,0x08,0x05,0x0B,0x0C,0x04,0x0F,

0x0D,0x08,0x0B,0x05,0x06,0x0F,0x00,0x03,0x04,0x07,0x02,0x0C,0x01,0x0A,0x0E,0x09,

0x0A,0x06,0x09,0x00,0x0C,0x0B,0x07,0x0D,0x0F,0x01,0x03,0x0E,0x05,0x02,0x08,0x04,

0x03,0x0F,0x00,0x06,0x0A,0x01,0x0D,0x08,0x09,0x04,0x05,0x0B,0x0C,0x07,0x02,0x0E,


0x20,0xC0,0x40,0x10,0x70,0xA0,0xB0,0x60,0x80,0x50,0x30,0xF0,0xD0,0x00,0xE0,0x90,

0xE0,0xB0,0x20,0xC0,0x40,0x70,0xD0,0x10,0x50,0x00,0xF0,0xA0,0x30,0x90,0x80,0x60,

0x40,0x20,0x10,0xB0,0xA0,0xD0,0x70,0x80,0xF0,0x90,0xC0,0x50,0x60,0x30,0x00,0xE0,

0xB0,0x80,0xC0,0x70,0x10,0xE0,0x20,0xD0,0x60,0xF0,0x00,0x90,0xA0,0x40,0x50,0x30,


0x0C,0x01,0x0A,0x0F,0x09,0x02,0x06,0x08,0x00,0x0D,0x03,0x04,0x0E,0x07,0x05,0x0B,

0x0A,0x0F,0x04,0x02,0x07,0x0C,0x09,0x05,0x06,0x01,0x0D,0x0E,0x00,0x0B,0x03,0x08,

0x09,0x0E,0x0F,0x05,0x02,0x08,0x0C,0x03,0x07,0x00,0x04,0x0A,0x01,0x0D,0x0B,0x06,

0x04,0x03,0x02,0x0C,0x09,0x05,0x0F,0x0A,0x0B,0x0E,0x01,0x07,0x06,0x00,0x08,0x0D,


0x40,0xB0,0x20,0xE0,0xF0,0x00,0x80,0xD0,0x30,0xC0,0x90,0x70,0x50,0xA0,0x60,0x10,

0xD0,0x00,0xB0,0x70,0x40,0x90,0x10,0xA0,0xE0,0x30,0x50,0xC0,0x20,0xF0,0x80,0x60,

0x10,0x40,0xB0,0xD0,0xC0,0x30,0x70,0xE0,0xA0,0xF0,0x60,0x80,0x00,0x50,0x90,0x20,

0x60,0xB0,0xD0,0x80,0x10,0x40,0xA0,0x70,0x90,0x50,0x00,0xF0,0xE0,0x20,0x30,0xC0,


0x0D,0x02,0x08,0x04,0x06,0x0F,0x0B,0x01,0x0A,0x09,0x03,0x0E,0x05,0x00,0x0C,0x07,

0x01,0x0F,0x0D,0x08,0x0A,0x03,0x07,0x04,0x0C,0x05,0x06,0x0B,0x00,0x0E,0x09,0x02,

0x07,0x0B,0x04,0x01,0x09,0x0C,0x0E,0x02,0x00,0x06,0x0A,0x0D,0x0F,0x03,0x05,0x08,

0x02,0x01,0x0E,0x07,0x04,0x0A,0x08,0x0D,0x0F,0x0C,0x09,0x00,0x03,0x05,0x06,0x0B};

static unsigned char SKE[3] = {'S','K','E'};

static struct key_type TDES_Key[48] = {0x27,0xE4,0x8A,0xDB,0xFF,0xC6,

- 117 -
0xD4,0x33,0xCD,0x5D,0xBB,0x2F,
0x13,0xDE,0x61,0xB6,0x7C,0xFC,
0xC9,0x79,0xE6,0x69,0xBB,0xF7,
0xB0,0xE7,0xCD,0xB7,0xEC,0xBB,
0x51,0x57,0x23,0x6F,0x1F,0x57,
0xE1,0x99,0xF5,0x9F,0xE1,0xFE,
0x95,0xE2,0xC7,0x65,0xDF,0xC5,
0xEC,0x0F,0x5E,0x7E,0xBA,0xD8,
0x66,0xFA,0x09,0xF1,0xF5,0x7F,
0x0B,0xBD,0x72,0x2F,0xBE,0xAA,
0xEC,0x6C,0xDB,0xFC,0x7D,0x77,
0x77,0xE7,0x08,0x2F,0xCA,0xFE,
0x4A,0x9D,0x93,0xD5,0xFD,0xD3,
0x7D,0xA8,0x5F,0xAF,0x86,0x7D,
0x89,0x5F,0xBC,0xF3,0x56,0xFA,
0xB7,0x0D,0x92,0x46,0x4A,0xFB,
0x9C,0xD7,0x4C,0x2F,0xE9,0x64,
0xCA,0x72,0xF8,0x1E,0x75,0x73,
0x9F,0x1E,0x60,0x3F,0x9E,0x8B,
0xA6,0x32,0xB5,0xF0,0xA6,0xFF,
0x85,0x0B,0x3E,0xE4,0xBA,0xC4,
0xB8,0xC0,0x35,0x95,0x61,0x6E,
0x72,0x01,0xEE,0x7F,0x53,0x12,
0xC5,0x3F,0x08,0xA3,0x1F,0x67,
0xA8,0x6E,0x3D,0xA7,0xF0,0xB9,
0x8A,0x29,0x6A,0x49,0x78,0xDF,
0x3E,0xD8,0x2C,0x7C,0x4C,0xBC,
0x4E,0x02,0xDE,0x59,0xBF,0x26,
0x9F,0x94,0x1C,0xA3,0x97,0x78,
0x7E,0x22,0xB1,0xD7,0xB9,0x59,
0x42,0x5B,0x4B,0xE0,0xED,0xD2,
0x6F,0x10,0xA7,0x6A,0x58,0x3E,
0x09,0xB7,0x29,0x8A,0xCD,0xB2,
0xC1,0x1C,0xDB,0x8D,0x6F,0x11,
0x75,0xEA,0xC0,0xFB,0x42,0x50,
0x12,0xFD,0x82,0xD1,0xC3,0x0E,
0x78,0x25,0x57,0x94,0x36,0x8C,
0x65,0xC4,0x0D,0xF8,0x32,0xE5,
0x43,0x81,0xB6,0x32,0xEA,0xAB,
0xD2,0xC6,0x69,0x22,0x6D,0x8F,
0xC9,0xDB,0x02,0xAE,0x11,0x97,
0x20,0xBB,0xCF,0xC7,0x43,0xE3,
0x31,0x74,0x43,0x56,0x8B,0x49,
0x61,0x4D,0xF0,0xD2,0x95,0x5C,
0xD4,0xE1,0x95,0x49,0xB7,0xA8,
0x17,0x87,0x13,0x78,0x7C,0x29,
0xEA,0x6B,0x09,0x3A,0xDC,0x65};

static unsigned char SKD[3] = {'S','K','D'};

static struct key_type unTDES_Key[48] = {0xEA,0x6B,0x09,0x3A,0xDC,0x65,
0x17,0x87,0x13,0x78,0x7C,0x29,
0xD4,0xE1,0x95,0x49,0xB7,0xA8,
0x61,0x4D,0xF0,0xD2,0x95,0x5C,
0x31,0x74,0x43,0x56,0x8B,0x49,
0x20,0xBB,0xCF,0xC7,0x43,0xE3,
0xC9,0xDB,0x02,0xAE,0x11,0x97,
0xD2,0xC6,0x69,0x22,0x6D,0x8F,
0x43,0x81,0xB6,0x32,0xEA,0xAB,
0x65,0xC4,0x0D,0xF8,0x32,0xE5,
0x78,0x25,0x57,0x94,0x36,0x8C,
0x12,0xFD,0x82,0xD1,0xC3,0x0E,
0x75,0xEA,0xC0,0xFB,0x42,0x50,
0xC1,0x1C,0xDB,0x8D,0x6F,0x11,
0x09,0xB7,0x29,0x8A,0xCD,0xB2,
0x6F,0x10,0xA7,0x6A,0x58,0x3E,
0x42,0x5B,0x4B,0xE0,0xED,0xD2,
0x7E,0x22,0xB1,0xD7,0xB9,0x59,
0x9F,0x94,0x1C,0xA3,0x97,0x78,
0x4E,0x02,0xDE,0x59,0xBF,0x26,
0x3E,0xD8,0x2C,0x7C,0x4C,0xBC,

- 118 -
0x8A,0x29,0x6A,0x49,0x78,0xDF,
0xA8,0x6E,0x3D,0xA7,0xF0,0xB9,
0xC5,0x3F,0x08,0xA3,0x1F,0x67,
0x72,0x01,0xEE,0x7F,0x53,0x12,
0xB8,0xC0,0x35,0x95,0x61,0x6E,
0x85,0x0B,0x3E,0xE4,0xBA,0xC4,
0xA6,0x32,0xB5,0xF0,0xA6,0xFF,
0x9F,0x1E,0x60,0x3F,0x9E,0x8B,
0xCA,0x72,0xF8,0x1E,0x75,0x73,
0x9C,0xD7,0x4C,0x2F,0xE9,0x64,
0xB7,0x0D,0x92,0x46,0x4A,0xFB,
0x89,0x5F,0xBC,0xF3,0x56,0xFA,
0x7D,0xA8,0x5F,0xAF,0x86,0x7D,
0x4A,0x9D,0x93,0xD5,0xFD,0xD3,
0x77,0xE7,0x08,0x2F,0xCA,0xFE,
0xEC,0x6C,0xDB,0xFC,0x7D,0x77,
0x0B,0xBD,0x72,0x2F,0xBE,0xAA,
0x66,0xFA,0x09,0xF1,0xF5,0x7F,
0xEC,0x0F,0x5E,0x7E,0xBA,0xD8,
0x95,0xE2,0xC7,0x65,0xDF,0xC5,
0xE1,0x99,0xF5,0x9F,0xE1,0xFE,
0x51,0x57,0x23,0x6F,0x1F,0x57,
0xB0,0xE7,0xCD,0xB7,0xEC,0xBB,
0xC9,0x79,0xE6,0x69,0xBB,0xF7,
0x13,0xDE,0x61,0xB6,0x7C,0xFC,
0xD4,0x33,0xCD,0x5D,0xBB,0x2F,
0x27,0xE4,0x8A,0xDB,0xFF,0xC6};

static struct s_RowBit_Type Row2Use[8] = {0,0,0,5,
0,6,1,3,
1,4,2,1,
2,2,2,7,
3,0,3,5,
3,6,4,3,
4,4,5,1,
5,2,5,7};

static struct s_ColBit_Type Col2Use[8] = {0,1,0,2,0,3,0,4,
0,7,1,0,1,1,1,2,
1,5,1,6,1,7,2,0,
2,3,2,4,2,5,2,6,
3,1,3,2,3,3,3,4,
3,7,4,0,4,1,4,2,
4,5,4,6,4,7,5,0,
5,3,5,4,5,5,5,6};

static unsigned int Ask4Bit[8] = {128,64,32,16,8,4,2,1};

static unsigned int Set_Bit[8] = {128,64,32,16,8,4,2,1};

static unsigned int Clear_Bit[8] = {127,191,223,239,247,251,253,254};

static unsigned int Shifts[16] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};

static char Low_Values[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

/** Area de definicin de funciones
**********************************************************/

void Permuta(char *Ini_Vector,
struct find_a_bit *Perm_Arr,
char *Vector_Fin,
int PosIni,
int PosFin,
int SizeOut);

void ExOr(char *Vector_A,
char *Vector_B,
char *Vector_C,
int BlqSize);


- 119 -
unsigned int GetRow(char *Vector, int S_Grp);

unsigned int GetCol(char *Vector, int S_Grp);

void S_Func(char *Vector_Xor,
char *Vector_S);

void ExecTDES (char *pInputMsg,
char *pOutputMsg,
int MsgSize,
char Servicio,
char *IniCBC);

int ProcTDES(char *InputMsg,
char *OutPutMsg,
int MsgSize,
char Servicio);

void Base256a64(char *OutTDES,
char *OutPutMsg,
int *finalsize);

void Base64a256(char *InputMsg,
char *OutTDES,
int *finalsize);

/** Permutacion: A partir de Ini_Vector generar Vector_Fin con las reglas de Perm_Arr
********/

void Permuta(char *Ini_Vector, struct find_a_bit *Perm_Arr, char *Vector_Fin, int PosIni,
int PosFin, int SizeOut)
{
int Bit2Chk, Byte2Set, Bit2Set;

for (Byte2Set = 0;Byte2Set < SizeOut;Byte2Set++)
{
Vector_Fin[Byte2Set] = 0x00;
};

for (Bit2Chk = PosIni; Bit2Chk < PosFin; Bit2Chk++)
{
if(((unsigned int) Ini_Vector[Perm_Arr[Bit2Chk].which_Byte] &
Ask4Bit[Perm_Arr[Bit2Chk].which_bit]) != 0)
{
Byte2Set = Bit2Chk / 8;
Bit2Set = Bit2Chk % 8;
Vector_Fin[Byte2Set] = Vector_Fin[Byte2Set] | Set_Bit[Bit2Set];
};
};

return;
};

/** Vector_C = Vector_A Xor Vector_B
*********************************************************/

void ExOr(char *Vector_A, char *Vector_B, char *Vector_C, int BlqSize)
{
int Byte2Proc;

for (Byte2Proc=0;Byte2Proc<BlqSize;Byte2Proc++)
{
Vector_C[Byte2Proc] = Vector_A[Byte2Proc] ^ Vector_B[Byte2Proc];
};

return;
};

/** Obtiene el rengln de la funcin S
*******************************************************/


- 120 -
unsigned int GetRow(char *Vector, int S_Grp)
{
int Row2Proc;

Row2Proc = 0;

if (((unsigned int) Vector[Row2Use[S_Grp].s_RowByte_H] &
(unsigned int) Ask4Bit[Row2Use[S_Grp].s_RowBit_H]) != 0)
{
Row2Proc = Row2Proc | Set_Bit[6];
};

if (((unsigned int) Vector[Row2Use[S_Grp].s_RowByte_L] &
(unsigned int) Ask4Bit[Row2Use[S_Grp].s_RowBit_L]) != 0)
{
Row2Proc = Row2Proc | Set_Bit[7];
};

return Row2Proc;

};

/** Obtiene la columna de la funcin S
*******************************************************/

unsigned int GetCol(char *Vector, int S_Grp)
{
int Col2Proc;

Col2Proc = 0;

if (((unsigned int) Vector[Col2Use[S_Grp].s_ColByte_1] &
(unsigned int) Ask4Bit[Col2Use[S_Grp].s_ColBit_1]) != 0)
{
Col2Proc = Col2Proc | Set_Bit[4];
};

if (((unsigned int) Vector[Col2Use[S_Grp].s_ColByte_2] &
(unsigned int) Ask4Bit[Col2Use[S_Grp].s_ColBit_2]) != 0)
{
Col2Proc = Col2Proc | Set_Bit[5];
};

if (((unsigned int) Vector[Col2Use[S_Grp].s_ColByte_3] &
(unsigned int) Ask4Bit[Col2Use[S_Grp].s_ColBit_3]) != 0)
{
Col2Proc = Col2Proc | (int) Set_Bit[6];
};

if (((unsigned int) Vector[Col2Use[S_Grp].s_ColByte_4] &
(unsigned int) Ask4Bit[Col2Use[S_Grp].s_ColBit_4]) != 0)
{
Col2Proc = Col2Proc | (int) Set_Bit[7];
};

return Col2Proc;

};

/** Funcin S
********************************************************************************/

void S_Func(char *Vector_Xor, char *Vector_S)
{
int Row2Proc, Col2Proc, S_In_Prc;

for (S_In_Prc=0;S_In_Prc<4;S_In_Prc++)
{
Vector_S[S_In_Prc] = 0x00;
};


- 121 -
for (S_In_Prc=0;S_In_Prc<8;S_In_Prc++)
{
Row2Proc = GetRow(Vector_Xor,S_In_Prc);
Col2Proc = GetCol(Vector_Xor,S_In_Prc);
Vector_S[(S_In_Prc >> 1)] = Vector_S[(S_In_Prc >> 1)] |
s_function[S_In_Prc].s_val[Row2Proc][Col2Proc];
};

return;
};

/** Ejecuta el cifrado / descifrado de informacin independiente al medio de entrada
*********/

void ExecTDES (char *pInputMsg, char *pOutputMsg, int MsgSize, char Servicio, char *IniCBC)
{
struct key_type *KeyGen;
char Wrk_Key[6];
char *info2TDES;
int infolength;
char *cbc_vec;
char accion;

char blk2Proc[8];
char Vector_S[6];
char Vector_Xor[8];
char *blkTDES;

char Vector_L[4];
char Vector_R[4];
char Vector_E[6];
char Vector_P[4];
char full_vector[8];

int numblks;
int blk_num;
int TDES_In_Proc;
int sub_key;
int i;

cbc_vec = IniCBC;
infolength = MsgSize;

info2TDES = pInputMsg;
blkTDES = pOutputMsg;

accion = Servicio;

numblks = infolength / 8;

for (blk_num=0;blk_num<numblks;blk_num++)
{
if ( accion == 'E' )
{
KeyGen = TDES_Key;
ExOr(cbc_vec, info2TDES, blk2Proc, 8);
}
else
{
KeyGen = unTDES_Key;
for ( i=0; i<8; i++ )
{
blk2Proc[i] = info2TDES[i];
};
};

for (TDES_In_Proc = 0;TDES_In_Proc < 3;TDES_In_Proc++)
{
Permuta(blk2Proc, IP_L0, Vector_L, 0, 32, 4);
Permuta(blk2Proc, IP_R0, Vector_R, 0, 32, 4);


- 122 -
for (sub_key=0; sub_key < 16; sub_key++)
{
Permuta(Vector_R, E, Vector_E, 0, 48, 6);

for (i=0;i<6;i++)
{
Wrk_Key[i] = KeyGen[sub_key].KeyVal[i];
};

ExOr(Vector_E, Wrk_Key, Vector_Xor, 6);
S_Func(Vector_Xor, Vector_S);
Permuta(Vector_S, P, Vector_P, 0, 32, 4);
ExOr(Vector_P, Vector_L, Vector_Xor, 4);

for (i=0; i<4; i++)
{
Vector_L[i] = Vector_R[i];
Vector_R[i] = Vector_Xor[i];
};
};

for (i=0;i<4;i++)
{
full_vector[i] = Vector_R[i];
full_vector[i+4] = Vector_L[i];
};

Permuta(full_vector, PC_Inv, blk2Proc, 0, 64, 8);

KeyGen = KeyGen + 16;
};

if (accion == 'E')
{
cbc_vec = blk2Proc;
}
else
{
ExOr(cbc_vec, blk2Proc, blk2Proc, 8);
cbc_vec = info2TDES;
};

for(i=0;i<8;i++)
{
blkTDES[i] = blk2Proc[i];
};

blkTDES = blkTDES + 8;
info2TDES = info2TDES + 8;
};

return;
};

void Base256a64(char *OutTDES, char *OutPutMsg, int *finalsize)
{
int i;
int ciclos3;
int ciclofin;
char *MsgIn;
char *MsgOut;
char FinalBlq[3] = { 0x000000 };
char FinalB64[4];

ciclos3 = *finalsize / 3;
ciclofin = *finalsize % 3;

*finalsize = ciclos3 * 4;

MsgIn = OutTDES;
MsgOut = OutPutMsg;

- 123 -

for (i=0;i<ciclos3;i++)
{
CnvBase64(MsgIn, MsgOut, 3);
MsgIn += 3;
MsgOut += 4;
};

if (ciclofin > 0)
{
for (i=0;i<ciclofin;i++)
{
FinalBlq[i] = MsgIn[i];
}

CnvBase64(FinalBlq, FinalB64, 3);

for (i=0;i<=ciclofin;i++)
{
MsgOut[i] = FinalB64[i];
}

if (ciclofin == 1)
{
MsgOut += 2;
*MsgOut = '=';
MsgOut += 1;
*MsgOut = '=';
}
else if (ciclofin == 2)
{
MsgOut += 3;
*MsgOut = '=';
}

*finalsize += 4;

}

return;
};

void Base64a256(char *InputMsg, char *OutTDES, int *finalsize)
{
int i;
int ciclos4;
int ciclofin;
char *MsgIn;
char *MsgOut;
int msgSize;
char FinalB256[3];
char FinalBlk[4];

MsgIn = InputMsg;
MsgOut = OutTDES;
msgSize = *finalsize;

MsgIn += msgSize - 1;

while (*MsgIn == '=')
{
msgSize -= 1;
MsgIn -= 1;
}

ciclos4 = msgSize / 4;
ciclofin = msgSize % 4;
MsgIn = InputMsg;

*finalsize = ciclos4 * 3;
*finalsize = *finalsize + (ciclofin * 6/8);

- 124 -

for (i=0;i<ciclos4;i++)
{
CnvBase256(MsgIn, MsgOut, 4);
MsgIn += 4;
MsgOut += 3;
};

if (ciclofin > 0)
{
for (i=0;i<4;i++)
{
FinalBlk[i] = (char) "A";
}

for (i=0;i<ciclofin;i++)
{
FinalBlk[i] = MsgIn[i];
}

CnvBase256(FinalBlk, FinalB256, 4);

ciclofin = (ciclofin * 6) / 8;

for (i=0;i<ciclofin;i++)
{
MsgOut[i] = FinalB256[i];
}
}

return;
};

int ProcTDES(char *InputMsg, char *OutPutMsg, int MsgSize,char Servicio)
{
int lastblksize;
int i;
char *OutTDES;
char lastblock[8];
int B64Size;
int finalsize;

if (Servicio == 'E')
{
finalsize = (MsgSize / 8) * 8;
OutTDES = (char *) malloc(finalsize + 8);

ExecTDES(InputMsg, OutTDES, finalsize, Servicio, Low_Values);

lastblksize = MsgSize & 0x07;

if (lastblksize > 0)
{
for (i=0;i<lastblksize;i++)
{
lastblock[i]= InputMsg[MsgSize-lastblksize+i];
}

for (i=lastblksize;i<8;i++)
{
lastblock[i]= ' ';
}

ExecTDES(lastblock,OutTDES+finalsize,8,Servicio,OutTDES+finalsize-8);

finalsize += 8;
};

Base256a64(OutTDES, OutPutMsg, &finalsize);

}

- 125 -
else
{
B64Size = MsgSize;
finalsize = (B64Size * 6) / 8;
OutTDES = (char *) malloc(finalsize);
Base64a256(InputMsg, OutTDES, &B64Size);
finalsize = B64Size;
ExecTDES(OutTDES,OutPutMsg, finalsize,Servicio,Low_Values);
};

free(OutTDES);

return finalsize;

};

TDESIVR_API long IVRCipher(IQVAL line,
PUSERDLLPARAM32 InputMsg,
PUSERDLLPARAM32 OutputMsg,
PUSERDLLPARAM32 Servicio)
{
int finalsize;

finalsize = ProcTDES(InputMsg->u.ptr,OutputMsg->u.ptr, InputMsg->length,*Servicio-
>u.ptr);

OutputMsg->length = finalsize;

return 0;

};

TDESIVR_API long TDESCipher(char *InputMsg,
char *OutputMsg,
int *MsgLen,
char *Servicio,
int *OutMsgLen)
{

*OutMsgLen = ProcTDES(InputMsg,OutputMsg, *MsgLen,*Servicio);

return 0;

};

long __stdcall VBCipher(char *InputMsg, char *OutputMsg, int *MsgSize, char *Servicio)
{
int finalsize;

finalsize = ProcTDES(InputMsg, OutputMsg, *MsgSize, *Servicio);

return finalsize;

};

S-ar putea să vă placă și