Cem 100962
Cem 100962
Cem 100962
INTRODUCCION ............................................................................................................................................ 12
2 ANTECEDENTES ............................................................................................................................................ 14
12 '
APENDICE D ................................................................................................. ,................................................ 225
Indice de Figuras
Figura 1 Esquema de la Celda de Manufactura del ITESM Campus Estado de México ..................................... 18
Figura 2. Controlador Paralelo y Distribuido .......................................................................................................... 19
Figura 3. Tarjeta IMS 8008 ....................................................................................................................................... 21
Figura 4. Conmutador C004 ...................................................................................................................................... 21
Figura 5Topología de Red propuesta por Salmerón para una Celda Flexibfo ...................................................... 23
Figura 6 Interfaz Controlador-Robot....................................................................................................................... 24
Figura 7 Topología porpuesta para el algoritmo de tolerancia a Fallas ................................................................ 25
Figura 8 Perfil de protocolos para estaciones Foil MAP ......................................................................................... 30
Figura 9 Perfil de protocolos de las estaciones MiniMAP .......................................................................................32
Figura 10 Perfil de los protocolos de las estaciones EPA........................................................................................33
Figura 11 Esquema abstracto del intercambio de Información entre un Cliente y un Servidor MMS ...............36
Figura 12 Diagrama de Estados para la ejecución de una invocación de ser,ricio confirmado ...........................37
Figura 13 La MMSPM y su relación con los objetos MMS y capas Inferiores OSI. ............................................. 38
Figura 14 Dispositivo real, VMDs y sus componentes ............................................................................................. 41
Figura 15 Posibles Configuraciones: a) Cliente Unico (b) Clientes Múltiple:, (c) Cliente Robot. (d) Robots al
mismo nivel. ............................................................................................................................................... 47
Figura 16 Relación entre componentes de Controlador y brazo del robot............................................................48
Figura 17 Ejemplo de la Referencia Remota permitida en Promela ...................................................................... 59
Figura 18 Ejemplo: Implementación del Semáforo de Dijkstra ............................................................................. 61
Figura 19 Modelo del Semáforo de Dijkstra con enunciados assert ...................................................................... 64
Figura 20 Modelo del Semáforo Dijkstra incluyendo una invariante del sistema ................................................ 65
Figura 21 Ejemplo del uso de la etiqueta progress para validar el progreso 1?n el modelo del Semáforo
Dijkstra ...................................................................................................................................................... 67
Figura 22 Ejemplo del uso de never para validar el progreso en el modelo del Semáforo Dijkstra ................... 69
Figura 23 Arquitectura del procesador Transputer................................................................................................ 72
Figura 24 Diferentes Arreglos de Transputers ........................................................................................................ 73
Figura 25 Abstracción de las interfaces Occam - C tipos 1, 2 y 3........................................................................... 79
Figura 26 Esquema del 810232 ................................................................................................................................. 80
Figura 27 Tipos de comunicación en el controlador para la Celda ........................................................................ 83
Figura 28 Comparación de MiniMAP con el Subsistema de Comunicación propuesto para la Celda de
Manufactura ITESM - CEM ................................................................................................................... 84
Figura 29 Esquema del Proceso Controlador de la Interfaz SI0-232 .................................................................... 88
Figura 30 Esquema de la Rutina de Interrupciones del Controlador de la llllterfaz SI0-232 ............................. 89
Figura 31 Protocolo de Mota González..................................................................................................................... 90
Figura 32 Capa de Enlace del Protocolo de Mota: Flujo Aplicación a Capa Física ............................................. 91
Figura 33 Capa de Enlace del Protocolo de Mota: Flujo Capa Física a Aplicación ............................................. 92
Figura 34 Servicios MMS de Asociación y Conclusión de la Asociación............................................................... 94
Figura 35 Servicios MMS de Asociación y Aborto de la Asociación ...................................................................... 95
Figura 36 Servicios MMS Confirmado y Sin Confirmación ................................................................................... 96
Figura 37 Servicio Login para el controlador de la celda ....................................................................................... 97
Figura 38 Servicio Logout para el controlador de la celda ..................................................................................... 98
Figura 39 Esquema General del Modelo de Validación para el protocolo MIYIS ................................................ 107
10
Figura 40 Modelo de Validación General de la MMSPM para la endtidad ,cliente ........................................... 108
Figura 41 Modelo de Validación Cmmspm: Servicios Logout Remoto y Servicio No Confirmado ................. 109
Figura 42 Diagrama de Flujo del Modelo Aplicación Cliente l. ...........................................................................111
Figura 43 Diagrama de Flujo del Modelo Aplicación Cliente 11.......................................................................... 114
Figura 44 Modelo General de Validación SMMSPM ............................................................................................ 115
Figura 45 Modelo de Validación SMMSPM: Servicio de Asociación .................................................................. 117
Figura 46 Modelo de Validación SMMSPM: Servicio de Liberación de Asociación .......................................... 120
Figura 47 Modelo de Validación SMMSPM: Servicio Confirmado ..................................................................... 121
Figura 48 Modelo de Validación SMMSPM: Servicios No Confirmado y de Logout Remoto .......................... 122
Figura 49 Modelo de Validación del Proceso Servidor ......................................................................................... 125
Figura 50 Modelo de Validación del Servidor ........................................................................................................ 126
Figura 51 Código Ejemplo para el Modelado de Pérdida de Mensajes ............................................................... 128
Figura 52 Código Ejemplo para el Modelado de Duplicidad de Mensajes .......................................................... 129
Figura 53 Resultados de la Validación del Modelo para los Estados Finales ...................................................... 131
Figura 54 Resultados de la Validación de Invariantes del Sistema ...................................................................... 132
Figura 55 Resultados de la Validación del progreso del protocolo ...................................................................... 133
Figura 56 Diagrama General de la Aplicación m1S ............................................................................................. 134
Figura 57 Relación entre la Aplicación MMS y las Aplicaciones Wrcmds y RdCmds ....................................... 136
Figura 58 Esquema del Ambiente Servidor MMS ................................................................................................. 137
Figura 59 Esquema del Ambiente Cliente MMS ................................................................................................... 139
Figura 60 Otros Procesos de la Aplicación MMS .................................................................................................. 141
Figura 61 Distribución de la Aplicación MMS según MMS.PGM ....................................................................... 144
Figura 62 Ejemplo de la transmisión y recepción de PDU MMS a través de los canales de los procesos ......... 148
Figura 63 Implementación de Canal con longitud mayor a cero ......................................................................... 150
Figura 64 Procesos Rx y Tx para la implementación del canal de longitud > 0.................................................. 151
Figura 65 Proceso Smmspm en Promela. Oyente simultáneo de dos canales ...................................................... 153
Figura 66 Proceso Smmspm en C paralelo. Oyente simultáneo de dos canafos .................................................. 153
Figura 67 Aplicación Secuencia.exe ........................................................................................................................ 236
11
Indice de Tablas
Tabla 1 Estados Lógicos de un VMD ........................................................................................................................ 39
Tabla 2 Estados Físicos de un VMD ........................................................................................................................... 39
Tabla 3 Atributos de un MVD ................................................................................................................................... 40
Tabla 4 Atributos de un Dominio ............................................................................................................................... 42
Tabla 5 Estados posibles de un Dominio ................................................................................................................... 42
Tabla 6 Estados posibles de una Invocación a Programas ....................................................................................... 43
Tabla 7 Servicios asociados a una Indicación a Programas ..................................................................................... 44
Tabla 8 Parámetros de una petición de Semáforo .................................................................................................... 45
Tabla 9 Estados posibles de una Petición de Semáforo ...........................................................................................45
Tabla 10 Lista de Objetos Estándares para un robot............................................................................................. 52
Tabla 11 Generalidades en la Sintaxis Promela ....................................................................................................... 58
Tabla 12 Clases de Transputers ................................................................................................................................ 74
Tabla 13 Herramientas para el desarrollo de Programas para Transputers ........................................................ 75
Tabla 14. Servicios que provee la máquina de protocolo MMS del controlador .................................................. 98
Tabla 15 Matriz para obtener los tipos de mensajes del protocolo ...................................................................... 103
Tabla 16 Descripción de los archivos de la aplicación MMS ................................................................................ 145
Tabla 17 Descripción de los archivos de las aplicaciones Wrcmds y Rdcomds ................................................... 146
Tabla 18 Descripción de los parámetros relacionados con las indicaciones y p,eticiones MMS ......................... 146
Tabla 19 Descripción de los parámetros relacionados con las Asociaciones MMS ............................................. 147
12
1 INTRODUCCION
El mundo actual no se podría concebir sin la existencia de las máquinas que se utilizan para la
generación de bienes y servicios tan necesarios para la vida cotidiana. El éxito de las industrias de
manufactura depende en muy buena medida en la eficiencia de estas máquinas y del control que
se tiene sobre ellas y automatizar su control y su operación es la tendencia mundial actual en esta
rama de la producción. La automatización requiere que estas máquinas y robots sean
interconectados y que se establezca un lenguaje de comunicación entre ellos. Este arreglo para la
intercomunicación requiere de interfaces y establecimientos de reglas que se tienen que
implementar en todas las máquinas a conectar, lo que ha generado que se diseñen e implementen
un sin número de redes propietarias que inherentemente implican una gran inversión al agregar
cada miembro a la red. Esto se soluciona estableciendo acuerdos entre productores de
dispositivos inteligentes y consumidores de éstos, orientados siempre a mejorar el desempeño de
las unidades de manufactura. Uno de estos esfuerzos lo constituye la especificación de mensajes
de manufactura MMS, (Manufacturing Message Specification).
El objetivo principal del presente trabajo es proponer un protocolo validado para el intercambio
de mensajes de manufactura en un controlador de celda. Dicho protocolo está basado en la
especificación de mensajes de manufactura MMS, por lo mantiene a la celda dentro de los
estándares internacionales de manufactura. Además, en este trabc~o se propone un esquema del
subsistema general de comunicaciones de esta celda.
13
En el Capítulo 2 de esta tesis se destacan los antecedentes que originan este trabajo. Se aborda el
tema de las celdas de manufactura en lo general y de la del ITESM-CEM en particular,
describiendo sus componentes y su sistema de control actual. Se menciona el proyecto Conacyt-
NSF, en el cual se suscribe la tesis, se presenta el nuevo controlador para la celda que en éste se
propone, los trabajos ya terminados y los que están actualmente en desarrollo y, finalmente, se
destaca la importancia que tiene la implementación de un buen protocolo para este nuevo
controlador.
El estado del Arte del entorno del presente trabajo se describe en el Capítulo 3. Se deja en claro la
importancia de los estándares y de los sistemas abiertos mencionando, en especial, los
relacionados a la rama de la manufactura: el protocolo de la automatización de manufactura MAP
(Manufacturing Automation Protocol) y MMS. Así mismo se presenta el concepto de los
protocolos y su papel dentro de los estándares, remarcando la importancia que tiene hacer una
buena validación de ellos antes de implementarlos. Acerca de la validación, se introducen los
métodos y herramientas actuales para llevar a cabo esta tarea. Por último se muestra la
arquitectura del nuevo controlador para celda flexible de manufactura, destacando las
características de la tarjeta madre utilizada, de los procesadores, del lenguaje de programación, de
la interfaz de este controlador con los robots y de la topología de red que se usa.
El Capítulo 4 tiene como objetivo describir en forma general el subsistema de comunicación para
la celda y, en detalle, el diseño del protocolo propuesto en este trabajo. Además, se muestran los
protocolos desarrollados en otros trabajos y que forma parte integral subsistema propuesto.
El Capítulo 6 se dedica a la implementación del protocolo. Se dan a conocer los detalles de cómo
fue implementado el modelo de validación del Capítulo 5 en la plataforma de los transputers. Así
mismo, se describen los procesos y programas generados para la implementación.
Finalmente, en el Capítulo 7, se enumeran las conclusiones del presente trabajo y los trabajos a
futuro que se pueden realizar para complementar el proyecto general.
14
2 ANTECEDENTES
El objetivo principal de la CIM es utilizar las computadoras como herramienta básica para el
diseño, la planeación, el control y el despacho de las distintas etapas de los procesos industriales
[8], ayudando a reducir tiempos e inventarios, incrementando la flexibilidad en la manufactura y
la calidad del producto. Además de la integración de equipos de cómputo, la CIM implica la
integración de gente, organizaciones y procedimientos, abarcando las etapas de diseño,
producción, mercadeo, entrega y soporte de producto [9]. Aunque este concepto es relativamente
reciente, desde hace ya varios años, las computadoras se han ido introduciendo en los ambientes
de manufactura a través de aplicaciones independientes como:
Sin embargo, los desarrollos basados solo en alguna de estas aplicaciones tienden a quedarse
aislados por la incapacidad de interconectarse con otros sistemas. La filosofia CIM trata de dar
una idea globalizada de los distintos niveles que se presentan en el ambiente de la manufactura
para poder homogeneizar las aplicaciones. Existen varios modelos, llamados de información
jerárquica, para este propósito.
Los modelos de información jerárquica de la CIM muestran los distintos niveles de control
encontrados en los sistemas CIM, que van desde los controles de tiempo real, incluyendo
sensores y actuadores, hasta los sistemas de control de aplicación ejecutiva. En estos modelos la
información fluye en dos direcciones. La información de monitoreo, de estado de la producción,
indicadores de excepción y otros datos operativos son pasados t.acia el nivel más alto y en cada
segmento se procesan algunos datos para su uso. En sentido contrario, se transfieren comandos,
puntos de prueba y calendario de operación. Algunos de estos modelos jerárquicos son:
En el modelo AMRF, las funciones de control y planeación han sido divididas en una serie de
niveles que son: Facilidad, Tienda (Shop), Celda, Estación de Trabajo y Equipo [17].
Debajo del nivel Tienda se encuentra el nivel Celda el cual contiene los sistemas de control de la
celda para programar y controlar los trabajos. En este punto, los trabajos se dividen en grupos y
se alojan en celdas de acuerdo a sus semejanzas. Se incluyen funciones adicionales para la
programación de manejo de material y herramientas en la celda.
El nivel Estación de trabajo coordina las actividades de una es'[ación de trabajo. Desde el punto
de vista de AMRF, una estación de trabajo consiste de un robot, una máquina herramienta, un
almacenador de material y una computadora de control. Por lo que, la estación de trabajo arregla
la secuencia de operaciones necesarias para que los trabajos alojados en una celda en particular
sean realizados. El nivel más bajo de esta jerarquía de control y planeación es el nivel Equipo, el
cual consiste en controladores para recursos individuales como: máquinas herramientas, robots o
sistemas de manejo de materiales
16
En este modelo, el nivel celda es el que tiene una mayor relevancia en el diseño de la CIM pues
es a este nivel es donde se tienen que comunicar los equipos que generalmente son de distintos
proveedores.
Una celda de manufactura es la unidad básica en una planta automatizada desde el punto de vista
del control de procesos.
Actualmente no todos los dispositivos de la CIM se comunican con un mismo protocolo. Los
controladores de celda son usados para integrar dispositivos de manufactura de proveedores
distintos y para coordinar las operaciones en una misma celda y entre celdas a un mismo nivel.
Las tareas de un controlador de celda son las siguientes.
Hay módulos globales que deben incluirse en un controlador de celda; por ejemplo, un
configurador para las funciones, un sistema monitor que facilite el control de los módulos de la
celda, sistemas de respaldo y recuperación y sistemas de seguridad, entre otros.
El ITESM Campus Estado de México cuenta con un prototipo de una celda de manufactura [2].
Los elementos de esta celda (ver Figura 1) se describen a continuación.
( Torno) ( Fresa)
B B
a
n
d ~::)~
~~~
a
2
AS/
RS [ Banda 1
( Controlador )
Todos estos elementos de la celda son controlados actualmente por una misma computadora que
coordina los trabajos dando instrucciones directas y montando programas en los diversos robots.
Este sistema de control tiene como desventaja principal que pres,:mta una reducida integración del
sistema. Evolucionar el control de esta celda para la optimización de sus componentes es un
objetivo del proyecto de investigación llamado "Tecnologías de Comunicación Avanzadas en
Robótica y Celdas Flexibles" [l], en el cual se suscribe la presente tesis y se aborda en la
siguiente sección.
19
• Tiempo Real.- El sistema de control debe proporcionar una capacidad de respuesta en tiempo
real para la optimización de la producción de la celda.
• Tolerancia a Fallas. El sistema debe contar con mecanismos de recuperación contra fallas de
hardware y/o software del controlador.
• Reconfigurabilidad. El sistema de ser capaz de cambiar su configuración para manufacturar
nuevos productos o tolerar fallas.
Cincynnati
Banda 2 - - - ; ~ Robot 2
Mesa
Controlador
O Procesador
~ Conmutador G) Interfaz
En esa fase del proyecto se está diseñando y desarrollando un controlador para celda llamado
P ARDICO (P ARallel and Distribuited Intelligent Controller) el cual es mostrado en la Figura 2.
Este controlador [ 12] está basado en una red de procesadores J:1amados transputers (sección 3 .3)
los cuales tienen características óptimas para cubrir los requerimientos de la celda [ 13] y cuenta
con interfaces conmutables de estado sólido [14] que permiten que cada robot esté conectado a la
red a través de más de un punto de acceso.
20
Las tare::is de este proyecto están siendo reali!:ad::is por el lTESM-CEM y por la UJ,iversid,ld de
Texas en Austin de acuerdo a los objetivos que tiene cada institución dentro del referente
proyecto de investigación.
Dentro de este proyecto el ITESM se encarga del estudio las comunicaciones entre los
componentes de la celda de manufactura, específicamente se concentra en el estudio de: ~ 1 ~· '{j mCYi.J
í'\ f\1'> 11l
,_,,
/~;-::"~~\~-'=-~~~~=:-:~~.
• Arquitecturas del controlador de celda. / : \: .} r'/'~;
-t.?~. ,·r,_
• Tecnologías de comunicación en redes configurables.
• Interfaces con robots.
• Software de comunicaciones. ·•·• '¡'
Por su parte la NSF se encarga del problema de las comunicaciones dentro del robot inteligente,
centrando su atención en:
Los transputers (sección 3.3) son procesadores que soportan el procesamiento en paralelo y que
pueden ser usados individualmente o se pueden conectar varios a través de sus enlaces (puertos)
para formar redes [16]. Los enlaces del transputer son conexiones seriales de comunicación que
constan de 2 hilos para transmitir información punto-a-punto, uno en cada sentido, a una
velocidad de hasta 20Mb/s [11]. Existen instrucciones nativas ele los transputers para enviar y
recibir mensajes a través de sus enlaces, las cuales minimizan retardos en la comunicación inter-
transputer [17]. La familia elegida de transputers para este proyecto es la T800 y la tarjeta madre
es una tarjeta IMS B008 [13].
La tarjeta IMS B008 (ver Figura 3) es una tarjeta madre de módulos de transputers, TRAMs
(TRAnsputer Modules). Un TRAM es un módulo electrónico pequeño que consta básicamente de
un transputer y memoria RAM aunque pueden contener otros dispositivos electrónicos. El TRAM
más pequeño, conocido como TRAM tamaño 1, tiene 8 pines y se monta en una de las ranuras de
21
la tarjeta. Existen TRAMs más grandes que son múltiplos en dimensiones del TRAM tamaño 1.
Por ejemplo, el TRAM de tamaño 2 ocupa dos ranuras de la tarjeta. Algunos TRAMs tienen
conectores por encima de ellos de tal forma que se les puede apilar otro TRAM.
jumpers
TRAM slots - - - - - - - - y
1l ~
switch es
J. J.
c::::::::I - c::::::::I e:
1 5 6 2 o 4 7
A la Celda de Manufactura
...
t t t
I / O Switch l /0 .... l /0
k k k ... k
--;
• --; ¡- --; ¡- - ..-
...
... •Ir ,i, ..
C004
El conmutador C004 consta de 32 puertos disponibles para conectar enlaces de transputers. Las
conexiones son llevadas a cabo cuando llega un mensaje de configuración a través de un enlace
especial del C004 llamado ConfigLink. Un transputer IMS T22 adicional está conectado al
ConfigLink con el propósito de controlar y configurar al C004.
Previamente a este trabajo se han desarrollado otras investigaciones dentro del proyecto, las
cuales se describen a continuación.
Este trabajo se desarrolló en el Campus Toluca del ITESM por la M. en C. Sara del Socorro
Mota, con el objetivo principal de implementar un protocolo orientado a byte para una
arquitectura similar a la del controlador de la celda del ITESM-CEM. Esta investigación sirve
como antecedente al desarrollo del presente trabajo por lo que 5.e describe más detalladamente en
el punto O de este documento.
Esta investigación fue desarrollada por la :¡vi. e'n C. Mima Salmerón durante los añ.os 1996 y
1997. Salmerón propone en este trabajo una topología de red de transputers (ver Figura 5) que
permite la recuperación de fallas ·que pudiera tener algún procesador de la red, asegurando que
siempre habrá un segundo que lo sustituya en su trabajo para no interrumpir el proceso de la
celda.
La topología es formada utilizando el interruptor IMS C004 para interconectar los enlaces de los
transputers. Este interruptor es programado antes de cargar el software de aplicación que correrá
en los diferentes procesadores utilizando una herramienta del C-tools de INMOS.
En esta arquitectura se contemplaron además los módulos SI0-232 y SI0-234, (refiérase al punto
3.4) que son las interfaces del controlador propuesto con los robots.
23
o so Al Robot
T1 2 ()
vla RS-232
T805
2
s3
--------12 T2 o
T805
3
o
1 s6,s2 1 s7 1 s8
1
5102 1-2----1 TS -2----1 T4
2
T225 TSOS TSOS
Figura 5Topología de Red propuesta por Salmerón para una Celda Flexible.
En paralelo a este trabajo se están desarrollando otros trabajos que complementan el proyecto
general [ 1]. La importancia de conocer estos trabajos radica en tener la idea general de los
requerimientos y medio ambiente en el que se implementará el protocolo objeto del presente
trabajo.
Esta investigación está siendo desarrollada por el Ing. Edgar Morales en el ITESM-CEM. El
objetivo de esa tesis es desarrollar una interfaz transputers - robots que permita redundancia para
la tolerancia a fallas en una celda flexible de manufactura. Un diagrama general de esta interfaz
se muestra en la Figura 6.
Los transputers del controlador procesan información e intercambian datos entre sí a través de sus
enlaces, sin embargo, el objetivo fundamental del controlador es enviar comandos a los robots y
obtener información de ellos para el monitoreo y control de actividades; debido a que los robots
no cuentan con una interfaz propia para enlaces de transputers es mandatorio su desarrollo. La
interfaz que está en investigación está basada en un módulo TRAM desarrollado por Transtech
Parallel Systems, modelos SI0232 y SI0422 que se detallan más adelante en el punto 3.4 por ser
tema básico para la implementación del protocolo de comJnicación propuesto en el presente
trabajo.
24
r----------------------------------------
Transputer ·.¿] ·•-o:::::,.-.
I Buffer de Tx 1"11 ._...i RS-23~
Controlador
de la Interfaz
~ RS-232•
~-------! Buffer de Rx !i.--~-- Controla~or
1
1
Interfaz Controlador-Robot 1
- -------------------------------------- 1
r-
1 ...-- N
I ci5 ci5
1 "S "S r ,
1
I
I
~
e
e 1-e
1-
~
e
:~~--¡
1 :
1~1
1
I ol
_g I
1 1
j O HobotA ¡ Lo:::J
1
I_ _ _Controlador
_ _ _ _ _ _ _ JI [ _________ .....,
2.3.5.2 Algoritmo de Tolerancia a Fallas para una celda flexible de Manufactura [15]
• Cuatro transputers pueden manejar cuatro elementos de la celda; la interfaz SIO sólo puede
manejar dos canales externos (dos elementos de la celda) y cada elemento requiere de al
menos un procesador, por lo que para usar los dos SIOs disponibles se requiere de cuatro
transputers de la red.
• Un transputer para el monitor. Debido a que el proceso Moni.tor debe ser altamente confiable,
el procesador no debe compartirse con otros procesos de producción.
• Un transputer para la comunicación con la computadora huésped.
Por lo anterior, la red de transputer queda formada por cinco o seis procesadores además de los
SIOs como se muestra en la figura antes mencionada. Los procesadores TI a T4 de tal esquema
se encarga de controlar, cada uno, a un elemento de la celda. T5 se destina para el proceso
principal del Monitor, éste sólo puede intercambiar mensajes d;:rectamente con los procesos que
corren en los procesadores T4 y T2; para coordinar al resto utiliza canales virtuales (refiérase al
punto 3.3.8.2 del presente trabajo). Sin embrago, para tener una red más robusta que coadyuve en
la recuperación de la falla se hace uso del interruptor digital múltiple C004 que esta integrado en
la tarjeta IMS 8008 (refiérase al punto 2.3.3) quedando una red totalmente conectada (ver Figura
7)
~ Rula Alterna 2
o
..
\
s4 s3
2
T3 •------1------12 T2 -o-
1
T805 rsos j
. . . . . . . . 31 3
j Rula Alterna 3
1 s6,s2
5102 1 - 2 - -
"'6225
Este trabajo esta en la etapa final de la implementación y pruebas y forma parte integral de este
proyecto.
27
El nuevo hardware propuesto en [12] es la base para una explotación óptima de la Celda de
Manufactura, pero no es suficiente por sí misma; la eficiencia y efectividad de un sistema
distribuido depende de su sistema de comunicación [8], por lo que se hace necesario implementar
un subsistema que garantice la rapidez y confiabilidad de comunicación que todo sistema
industrial requiere. Es imprescindible, además, que este subsistema siga lineamientos de
estandarización internacional para que sea abierto, siendo éste el principal objetivo del presente
trabajo.
28
Una solución más adecuada es reemplazar las redes propietarias por redes que reconozcan
estándares como, por ejemplo, el modelo de referencia ISO-OSI (International Standardization
Organization - Open System Interconnection). OSI es un conjunto de reglas que especifican
ciertos requerimientos en el diseño de LANs (Local Area Networks) agrupados como protocolos
de capas [4]. Además de ISO, existen muchas organizaciones y grupos cuyos esfuerzos se
centralizan en la estandarización, algunas de las más relevantes son: el Comité Consultivo
Internacional en Telegrafia y Telefonía CCITT, el Instituto Americano de Estándares, ANSI
29
(American National Standards Institute), el NBS (National Bureau of Standards), el Instituto de
Ingenieros Eléctricos y Electrónicos, IEEE (Institute of Electrical and Electronics Engineers) y el
grupo para los protocolos MAP/TOP [10]
El costo y esfuerzo para tener un sistema de manufactura automatizada apropiado es alto debido a
que en el mercado hay esquemas incompatibles de vendedores de equipos automáticos,
compañías de computadoras y proveedores de sistemas de comunicación. Las soluciones
anteriormente practicadas [8] eran:
1. Los mismos usuarios diseñaban interfaces propias para interconectar los equipos de diferentes
marcas, dando como resultado las redes conocidas como de usuario o redes propietarias. El
costo de esta "solución" es alto, ya que para agregar un nuevo dispositivo o computadora a la
red, implicaba el diseño particular, en muchas ocasiones, e implementación de una interfaz, es
decir, este forma de habilitar el intercambio de información con los dispositivos de diferentes
productores no es ni flexible ni abierta.
Se requería de una solución que garantizara la interoperabilidad de los equipos de los diferentes
proveedores, es decir, una estandarización.
En los años 80's se generó un trabajo para la estandarización de las comunicaciones en las
fábricas llamado MAP, así como un protocolo similar para ofü::inas (TOP) [9]. El objetivo
principal de MAP y TOP es especificar técnicas para la implementación de las comunicaciones
en la industria de la manufactura. En la siguiente sección se describe el protocolo MAP y TOP.
Las especificaciones MAP & TOP comprenden una familia de protocolos capaces de soportar un
amplio rango de necesidades de cómputo distribuido [5], incluyendo, para el caso de TOP,
estándares de aplicación en administración, acceso y transferencia de archivos entre máquinas del
ambiente de producción y máquinas del ambiente de oficina.
MAP ha sido orientado específicamente a las necesidades de la CIM desde el punto de vista
operación. Esto es evidente en los estándares de la capa de aplicación de MAP, tal como la
30
especificación de mensajes de manufactura MMS (Manufacturing Message Specification) [5]. La
primera versión de MAP fue sólo una especificación de procedimientos, adoptada en el otoño de
1982. La última versión publicada de MAP (MAP 3.0) data de Junio de 1988.
Las características del protocolo de MAP 3.0 están basadas en los siguientes criterios:
• Adopción del modelo de referencia OSI de ISO, con una selección para cada capa, de
protocolos estándares existentes que se adecuaban a los requerimientos de la automatización
industrial.
• Adopción de nuevos protocolos para estandarización en las áreas donde no existían
protocolos satisfactorios.
Hay tres tipos diferentes de sistemas finales incluidos en la especificación MAP 3.0, de acuerdo a
los roles que juegan en la red, FullMAP, EPA y MiniMAP, los cuales son explicados a
continuación.
3.1.2.1 FullMAP
El primer tipo de sistemas MAP es llamado FullMAP ya que incluye las siete capas completas de
OSI (ver Figura 8). La estación FullMAP no es adecuada para aplicaciones de tiempo real ya que
el número y complejidad de los protocolos usados reducen notablemente la velocidad en la
comunicación. Este tipo de estaciones son útiles para aplicaciones relacionadas a la
administración de la corporación y/o de la planta.
Las estaciones MAP de este tipo son las más apegadas al modelo OSI, sin embargo, las capas 3-6
están desarrolladas teniendo en mente aplicaciones de procesamiento de datos en general más que
aplicaciones industriales y el uso de protocolos de propósitos generales no es por sí mismo una
característica a favor de implementaciones de tiempo real. FullMAP contiene un complemento
muy rico de servicios, probablemente más rico que lo que requiere la mayoría de las aplicaciones
[9], pero implica un procesamiento adicional muy sustancial por lo que los dispositivos de piso
no deben ser de este perfil.
3.1.2.2 MiniMAP
CAPA OSI
Manufacturing Message Specification (MMS)
directory, 7
network management
NULL 6-3
802 class 3 2
802.4 intermediate response
3.1.2.3 EPA
Los nodos MiniMAP y FullMAP no pueden comunicarse directamente entre sí debido a sus
diferencias en cuanto a protocolos. La conexión de subrede~. MiniMAP al backbone FullMAP
bien puede hacerse por medio de un gateway pero implica costo e induce retardo en las
transacciones; otra solución es el sistema EPA (Enhanced Performance Architecture, Figura 1O),
que provee protocolos de 3 y de 7 capas al mismo tiempo [9], distinguiendo los modos de
servicio por sus puntos de acceso a éste.
Los nodos EPA son los idóneos para implementar la interfaz entre el ambiente de producción y el
ambiente de administración de la producción y muy eficiente:; para celdas de manufactura donde
el 70 al 95% del tráfico de las comunicaciones esta localizad.o dentro de ella [22]. Un elemento
importante en la evolución de MAP es el incluir la especificación de opciones para redes que
soportan comunicaciones "tiempo real".
Las ventajas generados por este tipo de arquitectura son los s(¡¡uientes:
Algunas restricciones generadas por la simplificación en la arquitectura que deben ser observadas
son:
CAPA
ACSE, FTAM, MMS, Directory and Management 7
Protocolo selector
Presentation 6
Session 5
Transport 4
Network 3
802.2 class 1 802.2 class 3
2
El modelo más adecuado para una celda como la del ITESM-CEM, es el MiniMAP, ya que sólo
comunica dispositivos del nivel tienda (shop) y la información intercambiada no abandona nunca
la red. Sin embargo, la plataforma elegida para el controlador implica inherentemente la capa
fisica entre nodos de la red, los enlaces de transputers, los cuales se describen en el punto 3.3;
para la capa de enlace se presenta una situación análoga, ya que los transputers cuentan con un
mecanismo de comunicación muy eficiente a través de canales (refiérase al punto 3.3.2). Por
34
supuesto, se podría emular la comunicación a través de los protocolos de la familia 802.4 para
estas capas, pero al hacerlo se atentaría contra las ventajas decisivas que motivaron la elección de
estas herramientas para implementar el controlador.
MMS es un estándar de comunicación de alto nivel desarrollado por EIA (Electronics Industries
Association) para el intercambio de datos en tiempo real y la supervisión del control de la
información entre dispositivos de red y/o aplicaciones de man 11factura, de tal forma que sea
independiente de la aplicación y del creador del dispositivo. Esta especificación elimina la
necesidad de procedimientos propietarios de la aplicación para la interpretación de datos
transferidos a través de la red y permite una programación orientada a la tarea al hacerse cargo de
lo referente a la comunicación de la información. MMS es un estándar internacional (ISO 9506)
que es desarrollado y mantenido por el Comité Técnico Número 184 (TC184) Automatización
Industrial de ISO y su se encuentra en dos documentos:
Además de los servicios generales MMS, que aplican para una amplia variedad de dispositivos de
manufactura, existen extensiones de especificaciones para dispositivos más especializados
conocidos como Anexos MMS y que detallan cómo deben ejecutarse e interpretarse los mensajes
en tales dispositivos y particularidades adicionales de MMS para ellos. Algunos de estos anexos
son:
Existen ya muchas aplicaciones en las industrias de energía eléctrica que están siendo
implementadas adicionadas con MMS, tales como en Unidades Terminales Remotas (RTU),
Sistemas de Administración de Energía (EMS) y otros dispositivos electrónicos inteligentes
(IED) como interruptores inteligentes [23]. La plataforma computacional MMS más popular tiene
conectividad disponible, ya sea implementada por el fabricante directamente o por un tercer
elemento; algunas aplicaciones ya disponibles son Interfaces Programables de Aplicación (API),
sistemas de monitoreo gráfico, compuertas, procesadores de palabras, habilitadores de aplicación
(NEs) y sistemas de administración de bases de datos relacionales (RDBMS). Las
implementaciones MMS soportan una variedad de enlaces de comunicaciones incluyendo
Ethernet, Token bus, RS-323C, OSI, TCP/IP, MiniMAP, FAIS, etc. y pueden conectarse a varios
otros tipos de sistemas usando puentes de red, ruteadores y compuertas [23].
MMSPM solo implementa las funciones que se requieren para el intercambio PDUs entre las dos
unidades comunicantes y no provee ninguna función para la ejecución del servicio; para ello el
servidor debe incluir una tarea o un grupo de tareas de aplicación, referidas como dispositivo
virtual de manufactura VMD (Virtual Manufacturing Device), el cual está encargado de ejecutar
la función solicitada en la petición y preparar una respuesta, que eventualmente envía al cliente a
través a través de las dos MMSPMs.
Cliente Servidor
MMSPM MMSPM
Comando
Respuesta
Las transiciones en las MMSPM para una operación de servicio confirmado se observan en la
Figura 12; el evento mostrado sobre la línea horizontal de cada transición es una operación de
entrada y el que está abajo es operación de salida, las operaciones denotadas con iniciales
mayúsculas corresponden a interacciones con otras MMSPMs mientras las otras se refieren a
interacciones con el usuario local a la MMSPM.
En MMS también existen servicios no confirmados, aunque sólo son un pequeño grupo; en el
caso de éstos, el diagrama de estados de la MMSPM transmisora se reduce a un solo estado con
una transición a sí mismo, que corresponde a las acciones de recepción de la petición y de la
transmisión de los PDUs correspondientes. Un esquema similar se presenta para la MMSPM
receptora.
Cuando un servidor MMS recibe de un cliente una petición de: servicio confirmado se crea un
objeto llamado "objeto de transacción", el cual contiene una estructura de datos con toda la
infom,ación de la petición y todos los modificadores pre-ejecucion y post-ejecución. El objeto de
transición se destruye cuando se responde a la petición.
37
Los formatos de los PDUs y los serv1c1os que se ofrecen según MMS son analizados más a
detalle en la sección 4.3.4 debido a su importancia en este trabajo.
Canc.x
sollcltante
5
{1 l x.reguest 11) Conf.Reg. PDU{xl
Conf. Req. PDU(x) x.lndlcatlon
{5) Canc. Resp. PDU AND Conf. Err. PDU{xl {5) can,:el.response •
cancel.confirm + AND x.conf • Conf. Err. PDU(x)
MMS hace uso de un protocolo orientado a conex1on, por lo que se requiere establecer un
ambiente entre el cliente y el servidor antes de cualquier intercambio de información. Este
ambiente es conocido corno asociación de la aplicación AA (Application Association). La AA
puede ser requerida tanto por el servidor como por el cliente y es en esta fase cuando se negocian
los parámetros con los que trabajaran las MMSPMs de cada entidad. Los parámetros a establecer
al inicio de la AA son:
A diferencia de otros protocolos OSI, MMS no establece solamente el comportamiento de las dos
entidades apareadas por nivel envueltas en el intercambio, sino que además, define parcialmente
el comportamiento externo de las tareas de aplicación colocadas en un nivel más alto a la entidad
MMS. La definición del protocolo sólo cubre las operaciones de transferencia de mensajes,
mientras que la definición del servicio está basada en la descripción del comportamiento de
objetos (como variables, semáforos, eventos y trabajos), que son implementados por las tareas de
aplicación del lado del servidor y agrupados en una abstracción conocida como DVM. Al
establecer el perfil general del DVM se obliga a las aplicaciones a una estandarización en su parte
básica. En la Figura 13 se esquematiza la relación de la máquina del protocolo MMS con sus
objetos locales.
Cliente
Peticiones Confirm. Respuestas Indicaciones
Figura 13 La MMSPM y su relación con los objetos MMS y capas inferiores OSI.
El VMD juega el rol principal en la definición del servicio MMS debido a que la implementación
de un servidor MMS debe mapear el comportamiento externo de un VMD a las funcionalidades
de un dispositivo real de manufactura. Para tener un mapeo fidedigno, el VDM cuenta con un
estado lógico y un estado fisico; el primero relacionado con el modelo de software y el segundo
39
con el hardware de la unidad real. En la Tabla 1 y en Tabla 2 se muestran los valores posibles
para estos estados.
Estado Significado
STATE-CHANGES- El VMD está disponible para ejecutar todos los servicios definidos.
ALLOWED
NO-STA TE-CHANGES- El VMD sólo está disponible para aceptar peticiones de servicio
ALLOWED relacionadas a la iniciación y cierre de AA y aquellas usadas para
obtener los atributos del objeto o leer su contenido; Sólo se pueden
llevar a cabo operaciones de monitoreo pero no es posible controlar
el estado de los objetos MMS.
LIMITED-SERVICE- El VMD sólo soporta los servicios usados para cerrar AA's y para
PERMITIED obtener el estado y la información de identificación del VMD. El
VMD no está disponible para operacione:; de monitoreo.
SUPPORT-SERVICE- Todos los servicios del VMD pueden ejecutarse excepto los
ALLOWED servicios de control de las invocaciones de programas; El VMD
puede participar en aplicaciones de control y monitoreo con la
limitante de no permitir a estaciones remotas activar/desactivar
partes de los programas.
Tabla 1 Estados Lógicos de un VMD.
Estado Significado
OPERATIONAL El VMD es capaz de ejecutar todas las tareas.
PARTIALLY- Existen problemas en el hardware que limitan el número de
OPERA TIONAL operaciones que pueden ejecutarse.
INOPERABLE Los problemas son tan severos que se evita la ejecución de cualquier
trabajo real.
NEEDS- Se requiere una operación local (y probablemente manual) antes de
COMMISSIONING ejecutar cualquier tarea.
Tabla 2 Estados Físicos de un VMD.
Además de un estado físico y un estado lógico, todo VMD cuenta con un grupo de atributos que
ayudan a los clientes solicitantes referirse a éste y sus objetos subordinados; Estos atributos se
enlistan en la Tabla 3.
Es preciso mencionar que MMS no contempla la creación ni destrucción de VMD, por ello la
activación y desactivación de los procesos que implementan un VMD debe llevarse a cabo por
operaciones de administración del sistema sobre el cuál se implemente MMS.
40
Atributo Descripción
Función Ejecutiva. Nombre de la función ejecutiva.
Nombre del vendedor. Nombre del desarrollador del software del dispositivo virtual.
Nombre del modelo. Nombre lógico del modelo virtual.
Revisión. Número de revisión del software.
Sintaxis abstracta soportada. Este parámetro se refiere a las sintaxis abstracta definida en
ASN. l (refiérase a (271)
Estado lógico. Describe el nivel real de funcionalidad de la función ejecutiva
(ver Tabla 1).
Lista de capacidades. Capacidades incluidas en este dispositivos.
Estado Físico. Describe el estado de las capacidade:; en el VMD (ver Tabla 2).
Lista de invocaciones de Descripción de todas las invocaciones a programas definidas
programas. para el VMD.
Lista de dominios. Incluye todos los dominios definidm. en el VMD.
Lista de objetos de transacción. Esta lista es dinámica y crece a medida que lleguen
indicaciones de servicio confumado.
Lista de máquinas de estado de Incluye el estado de todas las máquinas de estado que se están
carga. actualmente cargando.
Información adicional. Atributos definidos en los estándares adicionales
Tabla 3 Atributos de un MVD.
Cada dispositivo real puede requerir implementar más de un VMD según la complejidad de su
operación, sin embargo los dispositivos virtuales siempre se consideran lógicamente
independientes uno del otro y sus direcciones deben estar separadas debido a que cada VMD está
asociado con distintos grupos de puntos de acceso en la capa de presentación; La relación entre el
dispositivo real, el VMD y los objetos de éste se representan en la Figura 14, en la que se observa
que la estructura de un VMD incluye:
La función ejecutiva es la parte del VMD que realmente ejecuta las acciones en los objetos del
VMD relacionados con la petición entrante; la relación entre la función ejecutiva, la MMSPM y
los procesos de aplicación locales se muestra en la Figura 13. La función ejecutiva manipula los
objetos VMD a petición del cliente remoto mientras que los procesos locales cambian el valor de
estos objetos de acuerdo a operaciones locales. El acceso concurrente de la función ejecutiva y de
los procesos locales a estos objetos es controlado generalmente por el sistema operativo local.
41
Servidor MMS
1-VMD-·
VMD l~~- r FE:
p 1 ------------ ~ - -----.
1--------l--~--)
I pI
(pominio ) , Dominio )
---- -----:::
(Óo ini0
_____ -'--:::------ _..-'
('.-~,mi=~--0
\ tip~~s, ~abajos,
(~o~mi~i~
--
c==oº~~~-)
----------
···-·~----
~emaforo/
-------- ------
I FE Función Ejecutiva ;
I IP Invocación a Programa i AA
[ A._A._A._s_oci~~!~~--- - - - - - _____ J
3.1.3.3.2 Capacidades
Una capacidad es un recurso o grupo de recursos de un dispositivo real, que puede asociarse a
una cadena de caracteres. No se da una definición estándar para el comportamiento de las
capacidades ni hay administración ni reglas de definición. Se asume que la función ejecutiva está
alerta de los recursos que le corresponden a cada capacidad y tiene información suficiente para su
administración. Un ejemplo de capacidad es la variable que contiene el valor actual de las
coordenadas (x, y, z) que representan la posición real de un brazo de robot con respecto a su
origen; dicha capacidad puede referirse por el nombre lógico Rea/Pos.
3.1.3.3.3 Dominios
Un dominio es un objeto que incluye todos los recursos requeridos para ejecutar un aspecto
particular de un control coordinado o una aplicación de monitoreo. Un ejemplo de dominio en un
robot es el brazo, que está compuesto por todos los recursos para la operación del brazo real del
robot, incluyendo los datos y código para el programa de control.
• Un grupo de capacidades.
42
• Objetos MMS subordinados que no existen si el dominio no existe, que pueden ser variables,
semáforos o tareas. Por ejemplo el semáforo de control sobre el brazo.
• Información; áreas de código y datos que pueden usarse para la ejecución de un programa.
· Los dominios pueden ser compartidos por diferentes invocaciones a programas pero sus objetos
subordinados no pueden ser compartidos con otros VMDs. Por su ciclo de vida se pueden
clasificar como estáticos, si siempre están presentes en el VMD, o dinámicos, si se pueden crear y
destruir. Para este último caso es posible cargar/descargar el contenido de dominios desde y hacia
otra estación de trabajo. Cuando se crea un dominio, se crean todos los objetos MMS
subordinados y cuando se destruye, se destruyen con él todos esos objetos.
En la Tabla 4 se pueden observar los atributos más relevantes de un dominio y en la Tabla 5 sus
estados posibles.
·: ' ·fl,, ,• u
Atributo ',. . Descripción :f J'
, r,. '
,, ., ' ~
.,···
Estado Significado \·'." •>
Para ejecutar una invocación de programa es necesario que esté relacionada con uno o más
dominios, los cuales deben contener toda la información requerida por la invocación con
excepción de los parámetros de la ejecución que se dan en fom11a separada. Los segmentos de
código y datos para las tareas que componen la invocación están almacenados en áreas de
memoria asociadas con los dominios.
Los estados posibles de una indicación de programas y los serv1c1os que provocan las
transiciones a esos estados se presentan en la Tabla 6 y Tabla 7 respectivamente.
Estado Significado
NON-EXISTENT Estado incluido para indicar que la invo,:ación no ha sido aún
creada.
IDLE La indicación ha sido creada pero aún no esta activa.
RUNNING La indicación se está ejecutando; la ejecllción de una invocación
está asociada con cambios en los dominios subordinados causados
por ella y no implica necesariamente que los programas asociados
se están ejecutando.
STOPPED La invocación ha terminado su ejecución.
UNRUNABLE La invocación ya no puede ejecutarse más; este estado precede a la
destrucción de la invocación.
STARTING Estado transitorio que indica que se ha recibido una
Start.indication pero que no ha llagado el reconocimiento.
STOPPING Estado transitorio que indica que se ha recibido una Stop.indication
pero que no se ha dado el reconocimiento de éste mensaje.
RESETTING Estado transitorio entre STOPPED e IDLE, alcanzado por las
invocaciones especificadas como reusables en su creación. Una
invocación reusable puede ir de STOPPED a IDLE por medio de
RESETTING.
RESUMING La invocación espera cierto tiempo en STOPPED para recibir un
Resume. indication que puede ser generad:1. por el VMD para
continuar con su ejecución.
Tabla 6 Estados posibles de una Invocación a Programas.
Servicio Descripción
CreateProgramlnvocation Crea una nueva invocación.
DeleteProgramlnvocation Elimina una invocación existente, si ésta es borrable; para ejecutar
este servicio se requiere que la invocación se encuentre en estado
44
STOPPED o UNRUNNABLE.
Start Provoca la transición de IDLE a RUNNJNG de una invocación
existente.
Stop Provoca la transición de RUNNING a STOPPED de una
invocación existente. El resultado negativo a este servicio puede
ser no-destructivo (la ejecución de Stop 110 se pudo completar pero
la invocación es resumible ), o destructiva (cuando la invocación no
queda resumible). En el primer caso la invocación se va a
RUNNING y en el segundo se va a UNRUNNABLE.
Resume Provoca la transición de STOPPED a RUNNING a través de
RESUMING.
Kili Causa la transición a UNRUNNABLE de cualquier otro estado
(excepto de NON-EXISTENT y PI-P4), indica una terminación
anormal de la invocación.
GetProgramlnvocationAtri Provee al cliente los valores de los atributos de la invocación
bu tes
Tabla 7 Servicios asociados a una Indicación a Programas.
3.1.3.3.S Variables
Son objetos subordinados a un domino de un VMD que pueden ser de dos tipos básicos,
Nombrada y Sin Nombre, o de una combinación de ellos. Los objetos relacionados con las
variables describen cómo son accesadas, pero ninguno de estos objetos contiene el valor real de
la variable; para accesar el valor real el VMD usa dos operaciones V-PUT y V_ GET, que utilizan
los objetos MMS para escribir o leer la variable respectivamente.
Es posible que una variable MMS no corresponda a una variable re.al sino que su valor se obtenga
como resultado de un procedimiento (esta variable es sólo de lectura). También es posible que la
escritura a una variable corresponda a la activación de una función.
Debido a que es probable tener estructuras complejas de variables, se hace necesario que el
acceso a la variable se declare como completo o fallo; para evitar que la lectura de una parte de la
variable compleja haya cambiado cuando se termino de leerla, es indispensable forzarla a un
acceso de tipo no-interrumpible, característica opcional en MMS y que el fabricante establece si
está o no implementada y bajo qué condiciones.
3.1.3.3.6 Semáforos
Es una entidad MMS que puede usarse para el control de acceso a algún objeto subordinado del
VMD, así como para sincronizar tareas de aplicación.
45
EL VMD no puede establecer la relación entre un semáforo específico y el conjunto de recursos
controlados, como lo hace un sistema operativo; por lo anterior. se debe forzar al cliente a nivel
capa de aplicación para que use el recurso sólo a través del semáforo correspondiente.
Cada semáforo tiene cierto número de tokens que están relacionados directamente con el número
de recursos que se pueden accesar a un mismo tiempo. Cada p1;:tición para tomar el control del
semáforo se registra y si el proceso que requiere el recurso no mcuentra un token vacío espera
hasta que lo haya.
Existen dos tipos de semáforos definidos por MMS: Semáforos de Tokens y Semáforos de Poll;
los tokens de los semáforos del primer tipo son idénticos por lo que las peticiones esperan por
cualquiera de ellos, y los del segundo tipo son nombrados, por lo que las peticiones esperan por la
liberación de un token en particular.
Las peticiones registradas solicitando un token de semáforo tienen parámetros que influyen en el
comportamiento del mismo; estos parámetros se pueden observar en la Tabla 8 y los estados
posibles de una petición en la Tabla 9.
Servicio Descripción
Prioridad La lista de espera está organizada por clase de prioridad y, en la
misma clase, el primero en llegar es el primero en ser atendido.
(Las reglas reales del ordenamiento dependen del VMD)
Tiempo máximo de espera Parámetro opcional que indica el tiempo máximo de espera
después del cual la petición es cancelada y el cliente notificado.
Tiempo máximo de control Parámetro opcional que especifica el tiempo máximo que una
petición ·puede tener el token y se utiliza para prevenir el
monopolio del token.
Restablecer. Parámetro booleano que indica si la petición pierde el token al
perderse la AA involucrada.
Abortar al expirar. Parámetro booleano que indica si se debe abortar la AA cuando
expira el tiempo máximo de control del token.
Tabla 8 Parámetros de una petición de Semáforo.
Estado Significado
NON-EXISTENT Sólo sirve para indicar que la entrada no existe.
QUEUED Si el control del semáforo no se le puede dar a la petición entrante
entonces se genera W1 registro con este estado.
OWNER Este estado se asigna cuando el token se otorgiL a la petición.
HUNO Si estando la petición en OWNER ocurre un evento especial se
marca como HUNO, donde no se suelta token. Con una petición
prioritaria TakeControl se regresa la petición a OWNER.
Tabla 9 Estados posibles de una Petición de Semáforo.
46
Se penniten dos tipos de entradas de semáforo: simple y modificadora. Las entradas simples son
generadas por peticiones nonnales que solicitan el control del semáforo y las modificadoras por
peticiones de algún servicio adicionado con un conjunto de parámetros modificadores. Estas
últimas peticiones no son atendidas cuando llegan ya que su ej,~cución depende del estado del
semáforo; cuando una entrada modificadora toma el control del :;emáforo, se ejecuta la petición
de servicio y, una vez que la respuesta está lista, se libera el token sin necesidad de alguna acción
adicional del cliente. Para las entradas simples se genera una respuesta positiva cuando se otorga
el control del token y se requiere de una petición explícita del cliente para liberarlo.
El modelo provisto por el núcleo MMS es muy general; las caracteri'sticas de MMS la hacen muy
flexible para usarse en muchos tipos de aplicaciones pero esto representa una limitante para la
interoperabilidad de los dispositivos de los diferentes fabricantes ya que una parte de la
especificación queda libre. Para solucionar lo anterior surgen los estándares asociados es
(eompanion Standards) cuyos objetivos principales son:
Debido a que cada área de la manufactura tiene su propia cultura y terminología, los ess se han
estado desarrollando por distintas organizaciones en coordinación con ISO tal y como se
mencionó en el punto 3.1.3.
Cliente
Robot
Robot
(a)
(b)
Robot
Servidor Servidor
(e)
I I I I I I
1 1 1
La segunda está hecha para manejar varios clientes para un mismo robot (ver Figura 15(b)); en
este caso, se permiten operaciones paralelas de monitoreo (lecturas), y es necesario coordinar el
control de operaciones de los distintos clientes, para que sólo uno de ellos pueda tener el control
del robot a la vez a través de semáforos MMS. Adicionalmente a lo anterior, el servidor debe ser
capaz de mantener varias AAs abiertas al mismo tiempo.
En la tercera configuración, Figura 15(c ), el robot es el cliente mientras que los otros
dispositivos (tales como dispositivos de carga/descarga) son los servidores. Esta configuración es
posible pero no se considerará ya que el CS solo trata a los robots actuando como servidores.
El brazo del robot puede estar compuesto por varios tipos de dispositivos. El brazo fisico se
modela como un gmpo de uniones y ligas mecánicas, un par de ligas y su unión asociada es un
eje del robot. Cada unión es manejada por un actuador. Un controlador se asocia con cada brazo
para formar un brazo de robot lógico; de aquí en adelante sólo se hará referencia al brazo lógico
del robot. El controlador incluye dos tipos de dispositivos: el servomecanismo y el planeador de
ruta. Su relación con el brazo fisico se muestra en la Figura 16.
Servo-
Mecanismo
1 ~- - • Herramienta
,1
i, MICS
Servo-
1\
Mecanismo Enlaces',
\ 1
- - - - - - - Uniones
''-'
Existe un servomecanismo asociado con cada unión, el cual controla el movimiento de la ésta
mandando un comando al actuador y recibiendo información de los sensores asociados a la unión.
Las actividades de control de más alto nivel se llevan a cabo por un planeador de trayectoria, el
cual es responsable de traducir una trayectoria final a comandos del se:rvomecanismo. Note que el
planeador controla todo movimiento que se requiera del brazo, así que debe obtener los
comandos específicos para cada servomecanismo. La velocidad y aceleración del efecto final
también son controladas por el planeador, usando la información recibida por los diferentes
servomecanismos.
Se requiere agregar más atributos a los definidos en el núcleo MMS para poder describir las
uniones y la configuración de los servomecanismos. La lista de los atributos específicos del robot
es la siguiente:
Además de la información general, como el estado de calibración, los atributos describen los
parámetros del controlador y el brazo físico agrupados en el atributo servomecanismo. Algunos
atributos pueden ser todo un conjunto de parámetros, esto se indica en la lista anterior por la
indentación.
50
Se asocia un semáforo tipo token con un solo token a cada dominio de brazo, para que solo uno
pueda llevar a cabo las operaciones que generan las transiciones de estado del VMD o de las
invocaciones asociadas con el dominio. Exclusivamente a un usuario se le permiten las peticiones
de servicios como Start, Stop, Resume y Kill. Para obtener esta característica, es extiende la
semántica de algunos servicios del núcleo MMS, como obligar que la implementación del
estándar MMS cheque sí es el propietario del token el generador de la petición antes de servirla.
El semáforo de control asociado con cada dominio de brazo tiene el nombre estándar
R_eONTROL. Además de este objeto, el es robot define otros con nombres estándares que
pueden observarse en la Tabla 1O.
Dominios
Nomhrc Significado
Modelo de bro:,o
lnvocacionc~ a Programas
Nomhn• Signilkado
Tipos
'1omhre Tipo Signiticudo
Scrmíforos
\nmbre Ti¡10 Signi lirado
Condiciones de E,,cnto
51
"liomhr·c Significado
Acciones de Evento
'iomhn· Sl¡¡nilil'Udo
Variables Nombradas
",omhrr Tipo Signilicudo
Además del dominio del brazo R_ARM, se presentan otros dos. dominios estándares: uno relativo
a la calibración y otro a las operaciones y equipo de seguridad. Aunque se pueden adicionar otros
que cuenten con la descripción de sus dispositivos asociados ( sí los hay), tal como un equipo de
carga y descarga.
3.2 PROTOCOLOS
3.2.1 DEFINICIÓN
Un protocolo es un conjunto preciso de reglas que definen la interacción entre los elementos de
un sistema [20]. Es análogo a un lenguaje, ya que:
Los diseñadores de redes de los años 60's aprendieron que el camino dificil de las secuencias
muy improbables de eventos realmente pasan y pueden arruinar los mejores diseños y que redes
complejas se pueden paralizar por protocolos incompletos o erróneos [20], por lo que es
importante considerar desde el diseño todos los comportamientos posibles de las entidades
comunicantes para garantizar un correcto funcionamiento del protocolo. Un requerimiento
escondido en los protocolos es que ''No solo existen reglas para el intercambio de infom1ación,
debe haber un acuerdo entre el transmisor y el receptor de estas :reglas.", según [20].
Estos cinco elementos son las tareas más dificiles de diseñar y de verificar, por lo que se sugiere
seguir siempre un diseño bien estructurado.
Las principales reglas de implementación de protocolos son las capas de software de control y las
estructuras de datos, las cuales deben guardar los siguientes conceptos.
Los principios descritos se pueden lograr si se tienen en consideración las siguientes 1O reglas
[20]:
1. Asegurar que el problema está bien definido. Todos lmi criterios, requerimientos y
restricciones deben enumerarse antes de iniciar el diseñ.o.
2. Definir el servicio que llevará a cabo cada nivel de abstracción antes de decidir qué
estructuras debe usar para realizar esos servicios.
3. Diseñar las funcionalidades externas antes de las internas. Primero se debe considerar la
solución como una caja negra y decidir cómo debe interactuar con el ambiente, para después
decidir cómo debe funcionar internamente.
4. Mantener la simplicidad. Los protocolos de moda son más dificiles de implementar y de
verificar, pero generalmente son menos eficientes que los simples.
5. No conectar lo que es independiente.
6. No introducir lo inmaterial. No se debe restringir lo que es irrelevante. Un buen diseñ.o es
abierto y resuelve una clase de problemas, no un problema en particular.
7. Antes de implementar un diseño, se debe construir un prototipo de alto nivel y verificar que
los criterios de corrección se alcanzan.
8. Implementar el diseño, medir su desempeño y, si es necesario, optimizarlo.
9. Checar que la implementación optimizada sea equivalente al diseño que fue verificado.
1O. No omitir ninguna de regla de la 1 a la 7.
Análogamente a los programas, los protocolos se necesitan probar, ya que al inicio existe una
probabilidad muy alta de que contengan errores; a las pruebas requeridas se les llama validación
y son similares a las pruebas aplicadas a los procesos concurrentes [6]. La validación es una
operación interna en el sentido de encontrar inconsistencias de la especificación y una operación
externa en el sentido de verificar que se cumplan las especificaciones del usuario.
Si el análisis completo no es aplicable por la complejidad del protocolo, se deben usar técnicas de
validación no-exhaustiva. Estos métodos son muy efectivos para localizar errores en sistemas
complejos que pueden ser analizados en subconjuntos tomados al azar, pero la desventaja radica
en que no es completo y, por lo tanto, no es posible demostrar que el sistema está libre de error.
Las dos metodologías mencionadas no pueden ser aplicadas directamente al protocolo, se deben
aplicar a una especificación formal de éste. Estas representaciones son conocidas como Modelos
de Validación de protocolos.
Un modelo de validación es una descripción usualmente formal de un sistema que está sujeto a
validación [7] y define las interacciones de procesos en un sist,:::ma distribuido. No resuelve
detalles de implementación [20), no muestra cómo se transmite, codifica o almacena un mensaje.
Para facilitar el problema se aísla y se concentra en la parte más dificil: el diseño de un conjunto
completo y consistente de reglas que gobiernan las interacciones en un sistema distribuido.
A estos modelos son representados con una técnica de descripción formal para después demostrar
sus características usando alguna herramienta de validación. En el siguiente punto se introduce el
concepto de las técnicas de descripción formal y más adelante se detalla la herramienta de
validación usada para verificar el protocolo diseñado en esta investigación.
Las técnicas de descripción formal FDTs (Formal Description Techniques) son herramientas
importantes para el diseño, análisis y especificación de sistemas de precesamiento de
información. A través de estas técnicas se pueden producir descripciones de sistemas completas,
consistentes, concisas y precisas. Estos es posible solo si la FDT se contiene a sí misma, de tal
manera que la descripción en una FDT no necesita referirse a ningún conocimiento informal del
sistema que se está describiendo. Un aspecto importante de un sistema formal es que permite el
análisis por medio de métodos matemáticos. Una FDT que tiene una base matemática formal
puede usarse para probar el nivel de corrección de especificaciones.
Promela, Process Meta Language, es un lenguaje no determinístico usado para construir modelos
fomiales de protocolos a validar; está inspirado en la notación de lenguaje de comandos de
Dijkstra y en el lenguaje CSP de Hoare, adicionado con otras construcciones más poderosas
Contiene las primitivas para especificar paso de mensajes asíncronos a través de canales. con un
número arbitrario de parámetros. También permite la especificación de sistemas con paso de
mensajes síncronos (rendez-vous) y sistemas que mezclan ambos tipos de comunicación.
El lenguaje puede modelar sistemas de crecimiento y/o contracción dinámica; se pueden crear ,
destruir nuevos procesos y canales en ejecución, los identificador,!s de los nuevos canales pueden
pasarse de un proceso a otro a través de los canales existentes.
Por otro lado, SPIN es un software para verificar formalmente sistemas distribuidos y protocolos
usando Promela como lenguaje de entrada; este software fue desarrollado en los laboratorios Bell
por el grupo de métodos formales y verificación, y se ha usado para detectar errores de diseño en
sistemas distribuidos, tales como sistemas operativos, protocolos de comunicaciones, algoritmos
concurrentes, etc. Spin es la herramienta usada para validar el protocolo propuesto en esta tesis.
En los siguientes puntos se detallan conceptos importantes de Prometa útiles para la validación
hecha al protocolo propuesto.
58
3.2.6.1 Sintaxis de Prometa
( 'unn·ncioncs Léxicas
Identificadores
l'alahra¡, H.c~crrndas
Constantes Simbólicas
I h'l·!:.11 ada~ fhlr 1m:.1 dl' ia!'I do'.'- :,iguit>ntl'~ J'nrma~:
Operadores
&&
I,·,11_¡ .:rnplyl t lll'lllply(i 11rull( 1 1 1111()
l'\ ;¡ lí I 11 ,·v,L111e11
Separadon·s
E ti(¡ UCtllS
( ·orru.•11 tarios
Una facilidad en la sintaxis Promela, muy útil para el análisis de un modelo, es que se pennite
hacer referencia remota a variables y etiquetas de un proceso para :;aber el valor que contienen las
variables o para saber si el proceso está en el estado marcado por la etiqueta. Por ejemplo, en la
Figura 17 se muestra el código de un proceso escritor, el cuál es instanciado dos veces en el
modelo, y un proceso monitor, cuyo objetivo evaluar la condición invariante del sistema (tratada
en el punto 3.2.6.6.2) de que no estén ambos procesos usando el recurso compartido a un mismo
tiempo. La zona crítica esta marcada con la etiqueta "ZonaCrit" y se hace referencia remota
desde el proceso monitor, la instancia del proceso escritor queda r1!ferida por el índice, O y 1, que
esta dentro del los paréntesis"[]".
---i
1
Proclype escritor()
1
do
1
::(loken==true)-> goto ZonaCrit
::( token 1=true)->skip
od 1
r
ZonaCrit
/•Manejo del recurso compartido"/
Proctype monitor()
En Promela se describen reglas procedurales como programas fonnales para un modelo abstracto
de un sistema distribuido. Este modelo está compuesto de diferent,~s objetos.
Aquí, el canal "Transfer" puede almacenar hasta dos mensajes en todo momento; el tipo de
mensaje está indicado entre las llaves "{}" (en este caso cada mensaje consiste de cuatro partes).
"Device" es un arreglo de canales; cada canal es síncrono, es decir, los envíos y transmisiones
deben estar sincronizadas ya que no se pueden almacenar mens~ues. Finalmente, Channel es un
canal no inicializado que puede ser usado hasta que se le haya asignado un canal adecuadamente
inicializado. Se debe notar que un canal puede ser parte de un mensaje.
A cada instancia de proceso se le asigna un número positivo único (pid), se mantiene activa hasta
que el cuerpo del proceso termina completamente (si termina) y tiene asociada una prioridad de
ejecución, ya sea de forma explícita (usando la palabra reservada "priority" en el enunciado
"run") o de forma implícita (en cuyo caso el valor es 1)
Existe un proceso especial, referido como "proceso Init", usado generalmente para la
inicialización del sistema y que tiene la siguiente estructura:
Init {
sentencias de inicialización de variables y/o para instanciar los procesos del sistema
}
#deline p O
#deline v I
chan sema = (O] of ibitJ;
proctype dijkstra ( )
l tod: do
::sema ! p ->serna'! v
od
proclype user( )
l serna'! p;
t•zona critica•/
serna! v
init
I atomic I
run dijkstra( );
run user~ run user: run user:
Finalmente, el proceso "init" instancia tres procesos de tipo "user" y un proceso "dijkstra" de
manera armónica, es decir, no puede ejecutarse ninguna sentencia en el sistema global durante
hasta que no se hayan lanzado los 4 procesos. Los tres procesos "user" son los que compiten por
la zona crítica.
62
3.2.6.5 El Comportamiento del Modelo
Todos los criterios de corrección que se expresan en Promela definen comportamientos que son
exigidos como imposibles. Por ejemplo, si una afirmación de corrección establece que una
condición es invariablemente verdadera, la exigencia de corrección establece que es imposible
violar la afirmación independientemente del comportamiento del sistema.
1. El primer estado de la secuencia es el estado inicial del modelo M, con todas las variables
inicializadas en cero, todos los canales vacíos, con un solo proceso inicial activo y que este
proceso se encuentre en su estado inicial.
2. Si M se coloca en el estado i, hay al menos una instrucción ,ejecutable que lo pueda llevar al
estado i+ l.
• Terminal. Es una secuencia de ejecución donde cada estado se presenta sólo una vez en la
secuencia y M no tiene instrucciones ejecutables al llegar al último estado de la secuencia.
• Cíclica. Es una secuencia de ejecución donde todos los estados, excepto el último, son
distintos, siendo el último estado de la secuencia igual a uno de los estados anteriores. Las
secuencias de este tipo definen ejecuciones potencialmente infinitas
Los tipos de requerimientos de corrección pueden ser diferentes para las secuencias terminales y
para las cíclicas. Un requerimiento importante para una secuencia terminal es, por ejemplo, la
ausencia de deadlocks, aunque no todas carecen de ellos y por ello se tiene que expresar qué
63
propiedades de los estado finales deben hacer que la secuencia sea aceptable como una secuencia
terminal sin deadlock. Para secuencias cíclicas, se debe ser capaz de expresar condiciones
generales como la ausencia de livelocks.
Los requerimientos de corrección en los modelos Promela pueden construirse con proposiciones
simples, donde una proposición es una condición booleana de un estado del sistema. Las
proposiciones definen implícitamente un etiquetado de los estados; en cualquier estado dado una
proposición es verdadera o es falsa. Los criterios de corrección pueden expresarse en términos de
los estados definiendo explícitamente en cuales de ellos se r,equiere mantener verdadera la
proposición, a esto se le conoce como propiedades de los estados. Si se va a usar más de una
proposición, se puede necesitar que los requerimientos de corrección sean expresados como un
orden temporal de proposiciones. El formalismo para soportar esta característica del lenguaje es
conocido como requerimiento temporal y es explicado más adelante en este mismo punto.
Existen varias propiedades de los protocolos que se deberían probar, sin embargo, el problema es
muy complejo por lo que se deben seleccionar un grupo de ellas [20]. A continuación se
mencionan los criterios de corrección que pueden ser expresados ,en Promela.
3.2.6.6.1 Aserciones
Los criterios de corrección pueden expresarse como condiciones booleanas que deben
satisfacerse cuando el proceso alcance un estado dado. Para verificar que este criterio se cumpla,
se utiliza la instrucción assert(condición), que siempre es ejecutable y puede aparecer en
cualquier lugar del modelo Promela. La condición puede ser cualquier expresión booleana
arbitraria; si es verdadera al evaluarse el enunciado entonces no existe efecto alguno, pero si es
falsa la validez del enunciado es violada. Spin reporta automáticamente este error con solo incluir
este tipo de enunciados en el modelo.
Al correr el validador SPIN con este modelo, él buscará todas las secuencias posibles y s1
encuentra al menos una de ellas en que la condición no se cumpla lo reportará inmediatamente.
Una aplicación más general del enunciado assert es formalizar invariantes del sistema, es decir,
condiciones booleanas que, si son verdaderas en el estado inicial del sistema, deben permanecer
64
verdaderas en todo estado alcanzable del sistema. Para expresar esto en Promela, es suficiente
colocar la invariante del sistema en un proceso monitor separado.
! #define p O
, #define v I
1
I sema '! p:
nusers= nusers+ 1;
/•más código de zona critica•/
nusers= nuscrs· l:
sema ! V
1 /•zona no critica•/
! 1
1
¡ proclype monitor( H
, asscrt(nusers> = O && nusers< = 1);
!1
initl alomic jnusers=O;
I run dijkstra( ); run user; run uscr; run user;
, 1
Como ejemplo, se toma nuevamente el modelo mencionado en los dos puntos anteriores donde la
invariante del sistema puede expresarse como: "En todo estado del sistema nusers debe tener un
valor de cero o de uno". El nuevo modelo queda como en la Figura 20.
SPIN se encargará de evaluar la sentencia assert del monitor una vez después de cada estado para
toda secuencia posible del modelo.
En un sistema de estados finito, todas las secuencias de ejecución terminan después de un número
finito de transiciones o se ciclan a un estado previamente vi::;itado; no todas las secuencias
cíclicas son necesariamente deadlocks. Para definir que es un deadlock en Promela, se debe
distinguir primero los estados finales aceptable y los estados finales no esperados ó inválidos. Los
estados finales no esperados no sólo incluirán deadlocks sino también muchos estados de error
que pueden ser resultado de una especificación de protocolo incompleta lógicamente.
65
, #define p O
#define v
chan sema = [O) of lbitJ;
bit nusers;
proctype dijkstra ( ) 1 .. J
proctype user( )
I sema '! p;
/•zona critica•/
nuscrs= nusers+ 1;
proctype monitor( ) 1
assert(nusers> = O && nuscrs< = 1);
!1
initl atomic ¡nusers=O; run monitor();
run dijkstra( ); run user; run user; run uscr;
i I
Figura 20 Modelo del Semáforo Dijkstra incluyendo una invariante del sistema.
El estado final en una secuencia de ejecución terminante debe satisfacer los siguientes dos
criterios para considerarlos un estado final aceptable:
Pero no todos los procesos terminan necesariamente; puede ser perfectamente válido que un
proceso servidor permanezca vivo después de que los procesos del usuario ya han terminado. Se
debe identificar a éstos como estados finales aceptables; en Promela esto se lleva a cabo
anteponiendo a la sentencia terminal una etiqueta con prefijo ''end". Puede existir más de un
estado final aceptable en un mismo proceso pero todas las etiquetas deben ser únicas, por ello
para el validador es suficiente que tales etiquetas inicien con las letras "end".
Con estas nuevas definiciones se puede modificar el primer criterio para un estado final
aceptable:
• Todo proceso que fue iniciado ha finalizado o ha alcanzado un estado etiquetado como un
estado final aceptable.
Cualquier estado final en una secuencia de ejecuc1on que no cumpla los dos criterios
mencionados es considerado como un estado final inválido.
66
Un criterio de corrección implícito en los modelos de validación es que no debe contener estados
finales inválidos.
Retomando el modelo del semáforo de Dijkstra, un estado final aceptable es el del servidor del
semáforo "dijkstra", ya que tal vez todos los procesos "users" terminen pero "dijkstra" puede
quedarse ciclado. Para indicarle a Spin que este estado final es aceptable se le agrega una etiqueta
"end" tal y como se muestra en el código de la Figura 18.
En Prometa se pueden expresar dos propiedades para las secuencias cíclicas, correspondientes a
los dos tipos estándares de requerimientos de corrección. La primi::ra propiedad especifica que:
Las secuencias de ejecución que violan este requerimiento son llamadas ciclos de aceptación o
livelocks.
Un estado requerido para asegurar que el progreso del protocolo en la modelo del semáforo
Dijkstra es el de la recuperación del token por parte del proceso controlador del semáforo; esto es
mostrado en la Figura 21.
Ciclos de aceptación
Suponga que se requiere expresar lo opuesto a una condición de progreso, es decir, que se
requiere formalizar que un comportamiento no puede pasar eternamente; para ello se usan
etiquetas con prefijo "accept". Al checar ciclos de aceptación, el validador verifica que no exista
una ejecución que visite indefinidamente un estado de aceptación.
67
En princ1p10, se hace un mejor uso del estado aceptable si se utiliza para expresar
comportamientos completos que se consideran imposibles, más que solamente la ausencia de un
estado designado en todos los ciclos. Esto se hace precisamente usando las etiquetas para definir
estados aceptables de un autómata especial que modela comportamientos erróneos. Estos
autómatas expresan requerimientos temporales generales.
#define p O
#define v I
chan sema = [O) of I bit!;
proctype dijkstra ( )
Ido
::sema ! p ·>
pro1reu: scma '! v
od
proctype user( )
I sema '! p;
t• zona critica•¡
sema ! v /•zona no critica•/
inil
, 1 atomic I
run dijkstra( );
run user; run user; run user;
Con las herramientas mencionadas en los puntos anteriores se pueden expresar criterios de
corrección más potentes, simplemente utilizando las definiciones de procesos proctype. Suponga
que se necesita expresar el siguiente requerimiento temporal:
"Todo estado donde la propiedad P es verdadera es seguido por un estado donde la propiedad Q
es verdadera".
Hay dos interpretaciones para la palabra "seguido" dependiendo si los estados son
"inmediatamente" o "eventualmente seguidos". Es básico en la semántica Promela que no debe
hacerse asunciones relativas al tiempo del procesamiento así que la única interpretación legitima
es "eventualmente seguido" uno del otro (que incluye el "inmediatamente seguido" como un caso
particular). Esto genera un problema para expresar los otros tipos de propiedades, requiriéndose
otro tipo de primitiva de validación.
68
P->Q
Debido a que todos los criterios de corrección están basados en las propiedades que se consideran
imposibles, los requerimientos temporales deben ser expresados como ordenamientos de
propiedades que deben ser imposibles.
never {do
::p -> break;
::skip;
od;
accept:
do
:: ¡q
od
}
Los requerimientos temporales pueden ser enriquecidos con aserciones, etiquetas de progreso, de
accept para poder obtener más tipos de errores. El requerimiento never puede expresarse como
una máquina especial de estados finita que se cicla en un estado aceptable si el comportamiento
no deseado es detectado.
El requerimiento en sí mismo es una máquina de estados finita, con una proposición definida en
cada estado. Para cada transición en el modelo de validación, la máquina de requerimiento debe
cambiar de estado y moverse a la siguiente proposición. P~ra completar el requerimiento
temporal, en cada estado de la secuencia de estados, la proposición correspondiente al estado de
la máquina de requerimiento debe ser verdadera.
Los requerimientos never en combinación con las etiquetas accept también pueden expresar la
ausencia de ciclos sin progreso. Estos requerimientos son más genéricos que las etiquetas de
progreso "progress". Por ejemplo, en la Figura 22 se muestra el mismo requerimiento de la
69
Figura 21 pero utilizando la estructura never; eventualmente después de que el proceso dijkstra
otorga el token, y el valor de nusuers es actualizado a "1 ", éste es recuperado (nusers regresa a
"O").
#define p O
#define v I
chan sema = (O) of I bit 1;
bit nusers;
proctype dijkstra ( ) 1
do
::sema!v ~>
libera: sema'/p;
odl
proctype user( )1 serna'/ p; /•zona critica•/
nusers~ nusers+ 1; /ºmás código de zona critica•/
nusers= nusers-1; serna ! V; /•zona no critica•/
. 1
never (do ::(nusuers=~l)-> break;
::(nusuers!= 1);
od
do
accept: ::(dijkstra(l!Jlibera);
od)
init I atomic I nusers=O; run dijkstra( ); run userO; run user();
run uscr();I............................... ···································-·· .......................................
Figura 22 Ejemplo del uso de never para validar el progreso en el modelo del
Semáforo Dijkstra.
El proceso básico del validador es recursivo (aunque el algoritmo a validar no lo sea) y empieza
en el estado inicial del sistema; en cada estado del sistema se p:rocesan todas las verificaciones
habilitadas al iniciar el análisis. Si se habilita el requerimiento never en la lista de verificaciones
ésta se convierte en una lista de pares de acciones, una acción del requerimiento never junto con
una del proceso activo. El proceso de recursión regresa, una vez de que ha recorrido toda una
secuencia de estados, a cualquier estado visitado en el cual no esté habilitada la acción (par) o a
alguno que no hayan sido seleccionado previamente. Así, el proceso básico es una generación en
profundidad primero de todos los estados del sistema. Realmente el proceso es más complejo que
un barrido simple de los estados posibles, ya que en cada estado se debe verificar la ausencia de
violaciones a las correcciones.
El tamaño del sistema que puede ser analizado por el validador SPIN está determinado
directamente por la cantidad de memoria RAM disponible, debido a que ésta se requiere por las
siguientes razones:
• Cuando se checan las propiedades de los estados se necesitan almacenar los estados visitados
para poder decidir en cual de ellos continuará el análisis cada vez que la profundidad de una
secuencia ha llegado al máximo, además de que estos estados son accesados aleatoriamente y
no hay otra forma de saber cuales ya han sido visitados más que almacenándolos.
• En cada secuencia parcial se requiere guardar el cálculo aci:ual del algoritmo que debe ser
extendido en términos de la profundidad de la secuencia, lo que genera un crecimiento de la
"pila".
Un enunciado Atomic o d_step causa que los enunciados dentro de su alcance se ejecuten como si
se tratara de uno solo; al disminuir el número de estados en el sistema se reduce notablemente la
memoria requerida. Esto es posible ya que se asegura que durante la ejecución de los enunciados
lo cual puede hacerse debido a que ninguna instancia ha cambiado el estado global del sistema
La reducción de orden parcial es una técnica de búsqueda optimizada que decrementa la memoria
y tiempo necesario para el análisis en un orden de magnitud en la mayoría de los casos y algunas
veces mucho más; nunca genera un incremento de memoria y, en el peor de los casos, sólo
incrementa ligeramente el tiempo de análisis. Esta técnica es invocada al tiempo de compilación
(-DREDUCE o la opción correspondiente en Xspin) y se garantiza que los resultados del análisis
son los mismos que si no se activa la reducción. En forma general, la reducción de orden parcial
trabaja durante el análisis decidiendo en cada estado donde existe no-determinismo, si la
propiedad que esta siendo verificada depende del orden en que se ejecutan las sentencias de los
procesos. Si es independiente de este orden, el validador establece uno y omite las ejecuciones en
que estos pasos tomen diferente sucesión. El efecto de la aplica,cíón de esta técnica es el mismo
que si pequeñas secciones de código Promela se agruparan en sentencias Atomic, pero en forma
dinámica.
La implementación de este método en Spin está estrechamente ligada con las variables globales
compartidas y los canales de longitud mayor a cero. Si un sistema no tiene variables compartidas
y sólo usa canales de longitud cero, no habrá disminución ni de memoria ni de tiempo.
71
El único requerimiento para usar la reducción de orden parcial es de que los requerimientos never
sean oscilantes ("stutter-closed"). Esto significa que la propiedad expresada por el requerimiento
no debe depender del número de pasos en que mantenga verdadera o falsa. Por ejemplo, el never
de la Figura 22 es oscilante mientras que el siguiente no lo es. (ya que depende de que p se
mantenga verdadera por lo menos un paso en la ejecución del sistema):
Never{p;p}
3.3 TRANSPUTERS
En esta sección se presenta los transputers y los modelos de programación que pueden adoptarse
en el diseño de programas para ellos; se describen las principales características de los transputers
y de los sistemas basados en estos procesadores, y se introduce el concepto del modelo de
procesos secuenciales comunicantes CSP (Communicating Sequential Process).
Los transputers son microprocesadores de alto rendimiento que soportan procesamiento paralelo
en el mismo circuito integrado y en canales de comunicación hacia el exterior. Pueden ser usados
como procesadores poderosos dedicados o se pueden conectar uno a uno a través de sus enlaces
seriales (links) en las formas requeridas por la aplicación, para usarse como bloques de redes
complejas de procesamiento paralelo.
Los enlaces de los transputers (links) permiten a los procesos que corren en procesadores
conectados intercambiar datos y sincronizar sus actividades. El soporte para las comunicaciones
es implementado a nivel hardware en cada chip de transputer. Las comunicaciones en los enlaces
72
H
BootFromROM ~
Procesador
32-blt
Analyse ~ Servicios
del
Res et
Error --
Slstena
H Interfaz
Enlace
In
out
H Interfaz
Enlace
In
out
RAM
H Interfaz
Enlace
In
out
H Interfaz
Enlace
In
out
Interfaz
de Apllcaclón
Cada proceso tiene un programador de tareas de alto rendimiento para los procesos de
aplicaciones de usuario que corren en el mismo transputer. Los procesos que esperan por una
entrada o salida, o por un tiempo de procesador, no consumen recursos de CPU, y el proceso de
cambio de contexto es frecuentemente menor a un microsegundo.
Los sistemas multitransputers pueden construirse muy fácilmente usando los cuatro enlaces de
alta velocidad; solo se requiere de dos líneas para conectar dos enlaces. Los circuitos para
manejar cada enlace están en el mismo chip del transputer.
Los transputers pueden conectarse entre sí a través de sus enlaces para formar configuraciones de
red distintas, dependiendo de las necesidades de las aplicaciones. Algunos de los arreglos
posibles se muestran en la Figura 24.
'¡. •i
! ,1 \ .
' 1 '
~
Arbol
1 Malla
Existen varios modelos o tipos de transputers, los cuales se diferencian entre sí por su velocidad
de procesamiento, número de enlaces y capacidad de memoria RAM. Estos tipos son agrupados
en clases, concepto abstracto para clasificar los transputers que coinciden en su grupo de
instrucciones. En la se listan todos los tipos de transputers y la.s clases a las cuales pertenecen,
cabe notar que un mismo tipo de transputer se puede pertenecer a. distintas clases.
El concepto de clases es muy útil para compilar y ligar los programas. A tiempo de compilación y
ligado se indica para que transputers se va a generar el objeto; el objeto solo puede ser usado en
el transputer para el cual fue generado. Se puede indicar la clase de transputer en lugar de indicar
74
el tipo, esto permite que los objetos sean útiles para un mayor número de transputers sin
necesidad de volverlo a generar. Es importante mencionar que el código creado para una clase es
frecuentemente menos eficiente que el que se crea para un tipo específico.
Clase Procesadores
T2 T212, M212, T222, T225
T3 T225
T4 T414, T400, 1'425, T426
T5 T400, T425, T426
T8 T800, T801, T805
T9 T801, 1'805
TA T400, T414, T425, T426, T801, T805
TB T400, T414, T425, T426,
Tabla 12 Clases de Transputers.
Los conjuntos de instrucciones de las clases de los transputers se diferencian por lo siguiente:
• Las clases T2 y T3 soportan los transputers de 16 bits mientras que todas las clases restantes
soportan transputer de 32 bits.
• La clase T3 es la misma que la clase T2 excepto que la T3 time algunas funciones extras para
ejecutar CRC, operaciones de bits y de depuración.
• La clase TS es la misma que la clase T4 excepto que la TS tiene funciones extras para el
CRC, operaciones de bits, de depuración e incluye la función dup.
• La clase T9 es la misma que la T8, excepto porque la T9 contiene funciones especiales para la
depuración.
• Los procesadores T800, T801 y T805 usan un procesador de punto flotante en el mismo chip
para ejecutar las operaciones aritméticas reales; por ello disponen de un mayor número de
instrucciones.
• La implementación de las operaciones aritméticas se hacen vía software para las clases T4 y
T5. Los transputers de estas clases solo cuentan con un número reducido de operaciones de
punto flotante.
En el mercado existen dos herramientas que permiten el diseño, ,::reación y montaje de programas
en los transputers: ANSI C -Tool Set y Occam.
En ANSI C la programación paralela es soportada por librerías extras. Estas funciones permiten
definir y crear procesos para comunicarse unos con otros a través de canales y sincronizarse
usando semáforos.
75
Occam es el lenguaje nativo de los transputers y provee funciones sencillas para el manejo de
canales y la creación de procesos.
3.3.7.1.1 Procesos
Los procesos son los elementos principales del modelo CSP. Un proceso describe el
comportamiento de un componente discreto, separable de una aplicación; puede consistir de otros
procesos, operaciones secuenciales o combinaciones de estos. Las aplicaciones pueden dividirse
en cualquier numero de procesos y cada uno de ellos puede map,!arse a un procesador de la red a
través de un archivo de configuración.
3.3.7.1.2 Canales
Los canales facilitan la comunicación entre procesos, son conexiones unidireccionales punto a
punto y tienen dos funciones principales: proveen una ruta de comunicación independiente de los
procesos ejecutándose y sincronizan sus tareas cooperativas.
3.3.7.1.3 Semáforos
El soporte de semáforos, que no es parte del modelo CSP, se provee en la herramienta C de SGS-
Thompson para los que deseen desarrollar programas paralelos de la forma tradicional.
Los transputers pueden ser unidos fácilmente para formar redes; cada transputer opera como nodo
y se comunica con sus nodos vecinos a través de sus enlaces. La red más simple posible es la que
sólo contiene un transputer que bien puede estar conectado al host o en un sistema aislado el cuál
es iniciado desde una EPROM.
77
Para preparar una red para ejecutar una aplicación, es necesario definir que piezas de la
aplicación van a ser colocadas en que nodos de la red. Este proceso se le conoce como
"configuración" y se lleva a cabo por el configurador de Occam (occonj) y el de C (icconf),
usando un archivo de configuración con terminación "pgm" y "cfs", respectivamente; éstos
archivos contienen información de la red de hardware (descripción de la red), la descripción de
los procesos (descripción del software) e información de cómo está mapeado el software al
hardware.
El configurador lee el archivo de configuración y checa que los procesos han sido compilados
para el tipo de transputer correcto según el nodo donde se colocará. También verifica que la
configuración pueda llevarse a cabo en el hardware descrito y ,::rea una descripción binaria de
configuración, que puede ser leída por la herramienta icol/ect para generar un ejecutable.
Debido a que existen a lo más cuatro enlaces fisicos por transputer, el hardware no puede
configurarse para conectar directamente cada nodo con más de cuatro, sin embargo, este efecto
puede llevarse a cabo agregando algunos procesos especiales para que un proceso en un nodo
pueda comunicarse con varios procesos en otros nodos sin importar la topología de la red, de
hecho no importa si los nodos a comunicar no son adyacentes. El configurador agrega estos
procesos extras automáticamente pero el usuario puede especificar el grado en que esto debe
hacerse; esta técnica es conocida como "ruteo de software".
Para el caso de los archivos de configuración "pgm" el lenguaje usado es una extensión de
Occam y para los archivos "cfs" un lenguaje parecido a C. Para ambos casos, el lenguaje permite
configurar módulos generados por cualquier compilador de INMOS TCOFF (Transputer
Common Object File Format).
Las partes de los archivos de configuración son detalladas en la presentación de los archivos para
las aplicaciones desarrolladas en el presente trabajo (refiérase al punto 6.1.3).
El uso del formato estándar TCOFF permite compilar y ligar módulos creados con distintos
lenguajes fuentes, es decir, se puede mezclar C y Occam en el mismo sistema. Las unidades
ligadas individualmente en formato TCOFF pueden ser mezcladas en cualquier combinación y
colocadas en cualquier procesador de la red.
También es posible la llamada de módulos escritos en otro lenguaje. C puede llamar a Occam
usando una directiva "nolink" que permite que el código Occam sea compilado sin la necesidad
del parámetro static (o se puede declara en el código Occam un parámetro static de relleno).
Occam puede llamar a C usando rutinas de librerías para inicializar y terminar las áreas de pila y
heap.
Además se cuenta con un conjunto de interfaces que permiten llamar desde Occam programas
escritos en C [16). Esto puede Hacerse por varias razones, por ejemplo para usar programa C
llamado desde el configurador occonf Estas interfaces tienen como objetivo principal especificar
adecuadamente el punto de entrada al programa C; el código producido con esta técnica es
conocido como proceso equivalente Occam ya que hace parecer al programa como un proceso
Occam con canales de entrada y salida.
Existen tres tipos de código de interfaz, conocidos como tipos 1, 2 y 3 (ver Figura 25). La
primera interfaz es usada cuando el programa C corre en un único transputer y se comunica solo
con el servidor de archivos del host. Esta interfaz es usada con la versión completa de la
biblioteca C para ejecución (runtime).
El segundo tipo de interfaz se usa cuando el programa C además de comunicarse con el host,
debe interactuar con otros procesos. Esta interfaz también usa con versión completa de la
biblioteca C runtime.
La última interfaz es similar a la interfaz tipo 2, excepto que no requiere de acceso al host. Esta
interfaz debe usarse con la versión reducida de la biblioteca C para tiempo de ejecución, la cual
no contiene ninguna función que requiera acceso al sistema de archivos del host.
Como se puede apreciar en Figura 25, las interfaces del tipo 2 y 3 cuentan con un arreglo de
canales que permiten al programa C comunicarse con otros procesos; estos arreglos son
mapeados directamente a arreglos de canales que forman parte de la lista estándar de parámetros
de la función main de C.
Tales arreglos son realmente arreglos de enteros en las listas de parámetros de Occam; esto
permite pasar a apuntadores a canales al programa C, en el que hay más flexibilidad para mapear
canales a los arreglos. Debido a que Occam no soporta apuntadores directamente, se cuenta con
79
dos procedimientos de biblioteca para asignar apuntadores de canal a los elementos del arreglo
involucrando las direcciones directas de memoria.
La aplicación desarrollada en el presente trabajo utiliza las interfaces mencionadas por lo que en
el punto 6.2.5 se detallan.
fs
:. ts
~AIN.ENT~
Interfaz Tipo I
fs In[] ---0
~OC.ENT~
:4 ts Out[]
-----+<>
Interfaz Tipo 2
In[]
---o
l
PROC.ENTRY.RC
Out[]
-----.a
Interfaz Tipo 3
El SI0-232 y el SI0-422 son TRAMs (ver Figura 26) de tamaño 2 desarrollados por Transtech
Parallel Systems con un transputer de 16 bits de la clase T2, una memoria SRAM de 64Kbytes,
un receptor/transmisor asíncrono universal dual DUART (Dual universal asynchronous
receiver/transmitter) de alto rendimiento, controladores RS-232 con sintetizadores de voltaje DC-
DC y un controlador de interrupciones vía software configurable por el usuario. El DUART
cuenta con diferentes opciones de configuración para la transmisión de datos, velocidad, bits de
paro, paridad y tamaño de palabra [21].
80
Controlador
RS-232
Dual
UART
Transputer Controlador
16 bits RS-232
SRAM
64 Kbytes
Controlador
......._
de
Interrupciones
Estos TRAMs proveen un método de alto rendimiento, flexible y económico para integrar un
DUART y un controlador de dispositivo en una red de transputers sin la necesidad de hardware
adicional.
Cada receptor cuenta con un buffer de 8 caracteres para minimizar la perdida potencial de
recepción por falta de espacio o para reducir la sobrecarga por interrupciones. Además, se provee
una capacidad de control de flujo para deshabilitar un transmisor remoto cuando el receptor está
lleno.
El DUART También provee un puerto de entrada de 7 bits y un puerto de salida de 8 bits, ambos
de propósito general. Se pueden usar como puertos de entrada/salida o pueden asignarse a
81
funciones específicas (como entradas de reloj o como salidas de intenupciones/estado) por un
programa de control.
Los registros del DUART están mapeados a direcciones de memoria del transputer en palabras de
16 bits. Sin embargo, sólo los 8 bits menos significativos de cada 16 son válidos. Los 8 bits de la
parte alta de la palabra deben ignorarse o enmascarse dependiendo del uso específico.
Al momento de escritura del presente trabajo se están estudiando ambos TRAMs para el
desarrollo de interfaces para el controlador de la celda de manufactura [14).
82
4 SUBSISTEMA DE COMUNICACIÓN
En este capítulo se plantea el esquema general del subsistema de comunicación para la celda de
manufactura, así como el modelo de validación del protocolo orientado a MMS que propuesto en
esta investigación, detallando las consideraciones de ambiente que se tomaron en cuenta para su
diseño; este protocolo finalmente es la parte medular del subsistema. Se describen además, otras
partes de este subsistema que fueron desarrollados en otros trabajrn;.
En la arquitectura propuesta por [13] para el controlador de la celda se pueden distinguir tres
tipos de comunicación (ver Figura 27):
La comunicación natural del transputer ofrece grandes ventajas como se mencionó en la sección
3.3:
• Velocidad de comunicación.
• Paralelismo.
• Múltiples canales virtuales en un mismo enlace.
Sin embargo, se debe implementar un protocolo de comunicación que evite pérdidas de mensajes,
duplicidad de mensajes, esperas indefinidas en caso de fallas de proceso y deadlocks, sin que esto
impacte considerablemente en el desempeño de la comunicación del sistema. Estas características
son cubiertas por el protocolo diseñado en este trabajo.
Los robots existentes en la celda cuentan con interfaz RS-232 y éste es un protocolo ampliamente
probado en todo el mundo e inclusive es el más popular en términos de comunicación serial.
83
______ T___________ _
: _T_C_1_____ --------------------- - r TG2 :
3 31
1 ~,1 1
I o so 1
s1 s$ '"""-"'" ~1
, T1 5102" -r-': Al Robot :
: TSOS r 225 o : vla R5-232 :
1 1 1
1 1 1
1 1
ITC3 1
1 ------------'
o
s4 s3
2
T3 --------1 2
T2 o
T805 T805
3
3 o
1 s6,s2 s7 s8
5102 1-2-----1 TS 2 T4 2
T805 T805
rc2: 1
1
1
1
si= i-ésima ranura de la IMS 8008. 1
Ti= i-(:simo Transputer.
1
--------------------~-------------~,1
SIOi= Elemento de Comm. i-ésimo. : TC3 Al Robot I
TCi= Tipo de Comunicación i. 1 ________________________________ vla R5-232 _:
Pero la comunicación entre los diferentes procesos del controlador no tendría sentido si no se
pudiera comunicar con los robots de la celda. Para ello se hace nec-esario un protocolo para que el
controlador pueda enviar comandos y datos al robot, y recibir información y estados de operación
de él; objetivo cubierto con la interfaz que se está desarrollando dentro de este mismo proyecto
[14] basada en el hardware SI0-232 y SI0-422 (refiérase a la sección 3.4). Esta interfaz utiliza
un transputer IMS T212 que se diferencia del resto de los transput1!rs utilizados en el controlador
(IMS T805's) porque es un procesador de 16 bits y no de 32. El principal problema de utilizar un
lMS T212 es que obliga al diseñador de la interfaz a usar Occam para generar sus programas, ya
que las herramientas de C con las que se cuenta sólo pueden generar microcódigo para
transputers de 32 bits.
Por otro lado, los programas de aplicación de la celda requieren de arreglos y funciones no
soportadas por Occam, por lo que se percibe la necesidad de usar el lenguaje C paralelo para
generación de este código. Los programas C y Occam pueden comunicarse entre sí como se
indicó en el punto 3.3.9, sin embargo, su comunicación queda restringida a bytes cuando los
programas se encuentran en transputers de distinta longitud de palabra, lo cual se presenta al
querer comunicar los procesadores del controlador con el procesador de la interfaz. Este
problema se debe a la diferencia en el manejo de tipos de datos en los transputer de 16 y 32 bits.
Considerando estas restricciones en el ambiente de trabajo de la celda y deseando contar con los
múltiples beneficios de un protocolo para manufactura como MiniMAP (ver sección 3.1.2.2), se
propone que el subsistema de comunicación para la celda sea de tres capas; la comparación de
este modelo con el sistema MiniMAP se puede observar en la Figura 28.
Las diferencia en la capa fisica y de enlace del subsistema propuesto con respecto a MiniMAP se
debe a que, en la capa fisica, se trata de explotar al máximo las ventajas que ofrece la
comunicación nativa de los transputers utilizando sus enlaces y, en la capa de enlace, debido a las
restricciones arriba mencionadas se requiere de un protocolo orientado a bytes.
En la capa de aplicación, se adopta MMS para estar dentro de l.a estandarización mundial, en
cuanto a intercambio de mensajes de manufactura se refiere (ver punto 3.1.2.2).
OSI
Protocolo MMS
MMS
7
TxRx a bytes
Link
802.4 5Mbps 1
A nivel capa física se adopta la comunicación de enlaces de transputer (refiérase al punto 3.3.2) si
la comunicación es hacia otro procesador del controlador. Si la comunicación está dirigida hacia
el robot, entonces se hace necesaria la interfaz SIO-Driver, la cual s,;: describe en el punto 4.1.1.
85
A nivel de enlace se adopta el protocolo orientado a bytes propuesto por la M.C. Mota González,
mismo que se describe en el punto O.
A nivel capa de aplicación se implementará un protocolo que esté basado en MMS, el cual es el
objetivo central de la presente tesis, y es tratado desde la sección O y hasta el final del presente
trabajo.
El análisis de esta interfaz está siendo desarrollado dentro del mismo proyecto que esta
investigación por el lng. Edgar Morales [14]. Esta interfaz consi1,te de un módulo TRAM SI0-
232 (refiérase a la sección 3.4) y de un programa que corre en paralelo con los programas de
aplicación de usuario.
El programa que está en diseño es un protocolo para comunicar procesos en los transputers y los
robots; corre en el transputer integrado en el módulo SI0-232 que es de 16 bits, lo que implica
que los datos que se transfieran hacia este TRAM y se reciban de él deben ser de esta longitud de
palabra. Los transputers restantes del controlador son de 32 bits, por lo que para evitar que los
programas del controlador tengan que hacer rutinas adicionales, se propone que las
comunicaciones de y hacia el SI0-232 se hagan en bytes.
Hay dos protocolos básicos de comunicación para el controlador SJ0-232, que son:
Estos protocolos permiten enviar caracteres, cadenas y comandos al proceso SIO-Driver que
corre en el TRAM SIO. Los datos son siempre regresados del controlador como información de
un solo caracter, es decir, en la forma:
Existen comandos del protocolo para habilitar o deshabilitar el handshaking, seleccionar una o
varias velocidades de transmisión preestablecidas y también para configurar velocidades de
transmisión especiales. No todas las velocidades posibles del UART están preestablecidas, pero
la capacidad de programar cualquier velocidad está abierta, inicializando directamente los
registros del UART: ACR (auxilliary control register), MROA (registro modo O) y CSR (clock
select registers ).
86
4.1.1.2 Comandos Preestablecidos del Protocolo
Hay dos etiquetas usadas para indicar al controlador que el siguiente caracter es un comando.
Una de estas etiquetas se usa para indicar las características del puerto A y otra para el puerto B.
Cada etiqueta afecta al puerto correspondiente de manera similar.
sio.cmd.A causa que el siguiente comando afecte las características del puerto A.
sio.cmd.B causa que el siguiente comando afecte las características del puerto B.
El caracter "char" que sigue a los comandos debe ser uno de los siguientes:
Estas constantes normalmente se utilizan en la inicialización del SIO, aunque éste puede ser
configurado dinámicamente.
La infon11ación es enviada en bytes por controlador de la celda hacia el controlador del SIO a
través de un enlace de transputer, para que este último la retrammita por un canal específico
UART usando RS-232; esto se puede realizar de dos formas:
1) Para enviar un caracter de un nodo del transputer hacia el módulo SIO para transferir por el
canal UART A, se ejecuta el siguiente código Occam:
Con estas bases de comunicación hacia el controlador del SIO, se implementa un protocolo que
se describe a continuación.
El controlador del SI0-232 se puede ver de manera abstracta como el conjunto de cuatro
procesos concurrentes: interfaz de recepción, rutina de interrupciones, servidor de transmisión y
servidor de recepción, sincronizados a través de canales y comunicados hacia otros procesos por
medio un canal de entrada IN y uno de salida OUT.
Este proceso (ver Figura 29 etiqueta "IN_RX") es el encargado de recibir los datos que se desean
transmitir por RS-232; utiliza el canal IN y puede atender mensajes con 3 tipos de formatos:
tag::char, tag::wcount::string y tag::cmd, para procesar un caracter "char", una cadena "string" de
longitud "wcount" o un comando de configuración "cmd", respectivamente. En la etiqueta "tag"
además de indicarse el tipo de mensaje de que se trata, se señala a que canal se afectará, al "A" o
al "B".
Si la interfaz recibe un mensaje del tercer tipo, utiliza el comando recibido para configurar el
DUART y regresa al punto "IN_RX" de la Figura 29.
88
r--------------------------------------~ r-----------··---------------------
CASE Tog
o..tlTog;chw> o..tlTog;c:ha"
1---------------------------------------
La última de las acciones de este proceso sucede cuando hay una recepción de información por el
canal de eventos; ésta opción queda libre para el usuario para interactuar con el controlador de
una manera directa.
89
8--
La tarea fundamental de este proceso es la de sincronizar los datos que lee la rutina de
interrupciones con los datos que lee el proceso que esta siendo uso de la interfaz SI0-232, su
esquema operativo puede verse en la Figura 29 en las secciones marcadas con las etiquetas "Rx
A" y "Rx B". Cada vez que está listo, envía un mensaje a la rutina de interrupciones y espera por
la recepción de un dato que ésta última le manda cuando el DUART ha hecho una recepción RS-
232; al recibir el dato lo retransmite al servidor de transmisión a través de los canales mux.
después de lo cual vuelve a indicar que está listo.
Este proceso es el que sirve de enlace hacia los procesos que hacen uno de la interfaz SI0-232,
transmitiéndoles la información que ésta recibe a través del puerto RS-232. Su tarea consiste en
recibir la información del servidor de recepción y retransmitírsela a los procesos externos; el
diagrama operativo de este proceso se puede observar en la figura antes mencionada en la
etiqueta "OUT".
90
4.1.2 PROTOCOLO EN LA CAPA DE ENLACE
• Recibe los comandos del usuario y los transmite hacia el robot a través de las capas de enlace
y física.
• Recibe los datos que envía el Robot a través de las dos capas inferiores para presentarlos al
usuano.
Aplicación
Enlace Enlace
Capa Física
El comando insertado por el usuario es procesado byte a byte detectando su terminación por
medio de un caracter de escape ("\"). La capa de aplicación verifica la entrega del byte enviado
esperando siempre un caracter de reconocimiento positivo (ACK.caracter) o negativo (error). La
espera por este reconocimiento no puede ser indefinida en tiempo por lo que hace uso de un
temporizador. El término de la comunicación por parte de esta capa, se lleva a cabo transmitiendo
un caracter de fin de la transmisión.
En la parte receptora de esta capa, desde el punto de vista del usuario, además de los caracteres
de reconocimiento, se reciben los caracteres de reconocimiento de terminación.
91
La capa de enlace de este protocolo tiene como objetivo asegurar que los mensajes provenientes
de la capa física lleguen eventualmente a la capa superior; para ello, implementa un mecanismo
de reenvío de mensajes. El reenvío se activa cuando no se recibe un reconocimiento de recepción
del mensaje y cuenta con un ciclo finito, delimitado por un número fijo de intentos de transmisión
del mensaje. Así mismo, se considera la implementación de un buffer de mensajes que tiene
como objetivo coordinar las velocidades de consumo de mensajes por parte de la aplicación y el
arribo de mensajes enviados por parte de la capa inferior.
En el otro sentido de la comunicación, esta capa tiene funciones análogas a las mencionadas en el
párrafo anterior, sólo que aquí el consumidor es la capa inferior y el generador de mensajes es la
capa de aplicación. Sin embargo, en esta etapa de enlace no se espera por un reconocimiento de
transmisión, ya que supone una comunicación asíncrona con el robot y que este tipo de falla será
detectado por un módulo externo de tolerancia a fallas. En las figuras 24 y 25 se tiene un
esquema del protocolo de la capa de enlace, en la Figura 32 la comunicación de la Capa
Aplicación a la Física y en la Figura 33 de la Capa Física a la de Aplicación.
La capa física de esta implementación es la comunicación nativa de los sistemas transputers y una
interfaz propietaria Transputer-RS-232 [19) desarrollada en el ITESM-CEM y Toluca.
La capa de enlace del protocolo de Mota cumple con los requis:itos necesarios para la capa de
enlace del subsistema propuesto en este trabajo por lo que se adopta como una fase
completamente validada [ 18).
Rx
Fis ! Car
Figura 32 Capa de Enlace del Protocolo de Mota: Flujo Aplicadón a Capa Física.
92
Rx
Figura 33 Capa de Enlace del Protocolo de Mota: Flujo Capa Física a Aplicación.
MMS se mencionó en forma general en el punto 3.1.3, es tiempo de aterrizar esta filosofia en
nuestra celda. Implementar MMS para la celda es un trabajo complejo porque hay que cumplir
con las especificaciones sin olvidarse de que el protocolo esté correctamente validado.
93
La implementación de MMS en la celda para el presente trabajo consiste en generar un código
que haga las funciones de la máquina de estados MMS, respetando la sintaxis de los tipos de
mensajes que puede enviar y recibir una entidad MMS. Se trata de que la celda esté preparada
para que cuando sean adquiridos robots que manejen este estándar únicamente se tenga que
conectarlos a la red. No se trata de una implementación del protocolo en cada uno de los robots
existentes, ya que éstos no cuentan con un software de adaptación al estándar.
En esta sección se presentan las bases que se consideran :para el diseño del protocolo.
Primeramente se aborda la forma general en la que se intercambia la información, la cuál esta
basada en la filosofia Cliente-Servidor. Después se destacan de los servicios que el protocolo
debe prestar según MMS y los requerimientos del medio ambiente donde se correrá el protocolo,
es decir, los del nuevo controlador de la celda. En los últimos puntos de esta sección se definen
los tipos de mensajes válidos para el protocolo y el formato de éstos.
Lo primero que se requiere para que se pueda intercambiar información es que se establezca una
asociación entre las entidades comunicantes (refiérase al punto 3.1.3.2). En este proceso, además
de reconocer a la entidad que se quiere asociar, se negocian parámetros para el intercambio de
mensajes, tales como:
Cliente Servidor
Asociate.Request
Ai,ociate. lndication
---+
A~.oclate. Response
~
Asociate.Confirm
•
•
•
Conclude.Request
Ccmclude. lndication
---+
C,Jnclude. Respons e
Conclude.Confirm ~
Otra forma de deshacer la asociación es abortarla; este servicie, a diferencia de los dos antes
descritos, es un servicio sin confirmación empleado por la máquina de protocolo cuando por
alguna razón debe terminar expeditamente la asociación. Este Servicio se muestra en la Figura
35.
95
Cliente Servidor
Asociate.Request
Ai;ociate.lndication
---+
,~Asociate. Response
Asociate.Confirm
:
•
•
•
Abort.Request
At,ort. lndication
---+
Una vez hecha la asociación, hay dos tipos básicos de servicios que debe brindar la máquina de
protocolo: el Servicio Confirmado y el Servicio sin Confirmación. La mayoría de los mensajes en
una celda de manufactura tienden a ser confirmados debido a que el controlador generalmente
siempre exige una respuesta sobre la información o comando enviado al robot y depende de será
respuesta la decisión que tomará para la siguiente instrucción. El servicio sin confirmación es
habitualmente usado en el sentido robot hacia el controlador, utilizado principalmente para
transferir datos y estado periódicos de las acciones que el robot está realizando, para que el
controlador pueda así monitorearlos de una manera completa. Las alarmas también son del tipo
no confirmado, pues la entidad que las emite no puede esperar por una respuesta para apagarse o
realizar otra acción ante cualquier contingencia.
•
SConfirm.Request
•
• SC:onfirm.lndication
---+
_sconfirm.Response
SConfirm.Confirm
•
•
SUnconfirm.Reque t •
SLJnconfirm.lndicatlon
---+
•
•
•
Otro servicio propuesto por MMS es el servicio Reject. La máquina del protocolo debe ser capaz
de rechazar cualquier servicio cuando el PDU no sea llenado correctamente, cuando el servicio
solicitado sobrepase las especificaciones negociadas en el estab:lecimiento de la asociación, o
bien, cuando el servicio solicitado no se pueda procesar.
Adicionalmente se requiere un servicio muy particular a esta celda, el cual no está incluido en las
especificaciones MMS. Se trata de un servicio en el cual el proceso (cliente) que intenta hacer la
asociación, verifique que exista el servidor del servicio. Sin este servicio el protocolo supondría
que debe terminar el servidor cuando no haya más asociaciones abiertas y para poder continuar
con la operación de la celda se tendría que reinicializar tanto al cliente como al servidor. Además,
en este proyecto se está proponiendo que el controlador de la celda cuente con un mecanismo de
tolerancia a fallas [15], por lo que sí el cliente llegara a fallar el respaldo de este cliente entraría a
sustituirlo para que el controlador dinámicamente se recupere de la falla. Para poder responder a
este requerimiento de nuestro sistema usaremos el servicio Login.
El cliente solo podrá tratar de hacer asociaciones si se puede firm.ar con el servidor, es decir, su
vida esta condicionada a la existencia del servidor. Por otro lado, el servidor puede vivir aún y si
no existe eventualmente el o los clientes.
En un principio, se podría pensar en que el servicio de crear una asociación se encarga también
del servicio Login, pero esto implicaría alterar el concepto de establecimiento de asociación que
define MMS, lo cual no es conveniente por lo que se agrega como un servicio independiente.
Este servicio es asimétrico y se puede observar en la Figura 37.
97
Cliente Servidor
,- - - - - - - - -----------
ll
1 Login en el
[ Aplicación J 1 [ Aplicación
1 servidor
~ 1 Login.Cent
1 Log;o.Soq
1
1
1
1
1
--------
____ ,. _______
r Login en el
cliente
Login.Req
-
Login.l1d
Login.F:esp :
1
1
1
1
1
1
Login.Cent 1
----------- ---------------- ------·
Finalmente, Login tiene como contraparte el serv1c10 Logout que tiene un comportamiento
distinto dependiendo del estado en que se encuentre la máquina del Protocolo. Los dos estados de
la máquina que hacen diferenciar este servicio son:
• Estado Sin Enlace (Stand Alone). El servidor se encuentra esperando a que se firme algún
cliente. El cliente se ha desconectado del servidor porque este se dio de baja y está esperando
a que la capa superior se desconecte.
Entidad 1 Entidad 2
•
•
---------- •
----------------- ---------- -,
Edo . Enlazado 1
Logout.Req
Logout.Conf
-
Loqout..lnd
L~1out.Resp
r---
-----------
------------ ---------------- --·---------
, Edo . Stand Alone
Logout.Req
'~"d
---------- -1
La Tabla 14 muestra un resumen de los serv1c10s que deberá incluir el protocolo MMS del
controlador de la celda.
99
Teniendo identificados los servicios que debe proveer el protocolo, el siguiente paso es definir las
suposiciones sobre el medio ambiente de trabajo del controlador.
Las bases en las cuales se diseña el presente protocolo obedecen al ambiente de trabajo del
controlador y son:
• Los transputers están montados sobre una misma tarjeta madre, las distancias de
comunicación son muy cortas y la circuitería permite tener un bajo nivel de ruido, por lo que
puede asegurarse la integridad del mensaje transmitido a través de sus enlaces.
• Un enlace puede llegar a fallar e inclusive un mismo procesador tiene esta probabilidad. El
mensaje transmitido puede llegar a perderse.
• La aplicación que llama a la máquina de protocolo sabe llenar el PDU MMS correspondiente
al servicio; sin embargo, puede ser que esa aplicación haya equivocado el PDU o que algún
dato de éste no sea coherente con la negociación que se llevó a cabo en el establecimiento de
la asociación, por lo que el protocolo debe ser capaz de manejar el rechazo de PDU's.
Aunque los servicios presentados en el punto 4.3.2 pueden parecer muy reducidos, la
complejidad de MMS radica en todos los tipos de PDU's que pueden viajar en tales servicios; la
sintaxis MMS se puede consultar en [27]. Para mostrar la manipulación del PDU MMS que debe
hacer la aplicación que usa MMS se supondrá que se quiere escribir un dato en una variable del
servidor.
Este pequeño ejercicio nos permite percatarnos de la complejidad que se presenta cuando no se
tiene experiencia en el entendimiento del llenado del PDU. Sin embargo, para establecer un buen
protocolo MMS no se requiere ser un experto en el manejo de estos PDU's; lo importante es
conocer los tipos de servicio, el sentido en la comunicación y los diferentes tipos de PDU para
poder establecer la colección de mensajes válidos en el protocolo.
La selección de los tipos de mensaje que tiene el modelo de validación del protocolo se hace
teniendo en cuenta que deben ser los menos posibles y que se deben incluir todos aquellos que
causen un cambio en su comportamiento. No basta con elegir solo los Tipos de Servicio que el
protocolo ofrece con sus respectivas primitivas, pues en cada tipo de servicio pueden viajar
diferentes tipos de PDU validos. Para obtener estos mensajes se analizó servicio por servicio
considerando los PDU's que pueden viajar en cada servicio según el estándar MMS. La Tabla 15
muestra la matriz formada para obtener estos tipos de mensajes; en la primera y segunda columna
se encuentran los servicios y sus primitivas correspondientes y, en la fila sombreada de cada
servicio los PDU's válidos.
A manera de ejemplo a continuación se describe la forma de deducir los mensajes válidos para el
servicio Associate:
3. La MMPM remota recibe la indicación del servicio Associate.·· Si esta MMPM puede seguir
procesando el servicio, entonces transmite a la capa de aplicación una indicación con el
i11itiate_RequestPDU, que es el mismo tipo de mensaje que s,e generó en el punto 2. Sí la
MMPM no puede darle seguimiento al servicio entonces genera una respuesta Associate con
un PDU_error, lo que implica un nuevo tipo de mensaje: MAsCf_initiate_ErrorPDU.
6. La MMPM recibe la respuesta de la MMPM remota.- Esta máqu:tna sólo retransmite el tipo
de mensaje.
7. Note que en el punto 3 y 6 nunca se genera un PDU_reject debido a que se supone que la
MMPM de donde proviene el servicio no podrá enviar un PDU mal formado.
Análogamente se analizaron todos los servicios del protocolo y las combinaciones posibles con
los tipos de PDU de la MMS, resultando los mensajes que se listan a continuación:
1. MAsRq_initiate_RequestPDU
2. MAsln_initiate_RequestPDU
3. MAsln_reject_PDU
4. MAsRs_initiate_ ResponsePDU
5. MAsRs- initiate- ErrorPDU
6. MAsCf_initiate_ResponsePDU
7. MAsCf- initiate- ErrorPDU
8. MAsCf_reject_PDU
9. MRIRq_conclude_RequestPDU
I O. MRlln_conclude_RequestPDU
11. MRlln_reject_PDU
102
En la Tabla 15 se muestra la matriz de donde provienen los tipos de mensajes del protocolo.
initiate_RequestPDU X X reject_PDU
C'onlirmed MCtRq_
Service Request Confirmed RequestPDU X X X
El formato de cada mensaje está bien determinado por la especificación de manufactura que se
puede estudiar en [27]. Sin embargo, para el modelado del protocolo se debe incluir solamente
los parámetros que pueden modificar el comportamiento del modelo, todos los parámetros
adicionales son omitidos y únicamente se usarán al tiempo de implementación. El análisis del
formato se plantea por tipo de servicio del protocolo y es detallado a continuación.
En este servicio no hay parámetros adicionales que cambien el ,:omportamiento del protocolo,
debido a que estos servicios traen como consecuencia una acción general para la aplicación que
los ejecuta contra la MMSPM.
Considerando que la aplicación puede solicitar hasta "n" asociaciones a la MMSPM, se debe
adicionar al formato del mensaje un entero que identifique a la asociación a la que se hace
referencia en la MMSPM local. Además, para relacionar la asocic:,ción con el número con la que
es conocida en el sistema remoto, se adiciona el identificador remoto de la asociación. El formato
requerido es:
donde
Este servicio sólo se puede llevar a cabo una vez asociadas las entidades y está siempre
relacionado a una de ellas, por lo que se requiere de los dos identificadores mencionados en el
punto anterior.
Al igual que para el servicio no confirmado, para éste se requiere indicar con qué asociaciones
está ligado; pero además, este servicio puede dejar pendientes hasta "k" peticiones y hasta 'T'
indicaciones, lo que conlleva a agregar al formato un identificador de la petición pendiente a la
105
que corresponde el PDU en la MMSPM local y también el identificador correspondiente a la
indicación en el MMSPM remoto; el formato para este tipo de mensaje es:
donde
TipoMensaje := Cualquier tipo de mensaje relacionado con el Servicio Confirmado
IdAssLoc := número de la asociación en la entidad local.
IdAssRmt := número de la asociación en la entidad remota.
IdReqLoc := número de la petición en la entidad local.
ldlndRmt := número de la indicación en la entidad remota.
4.3.6.5 Reject
Los parámetros para rechazar un PDU dependen de qué tipo sea el PDU a rechazar, pero en el
_peor de los casos se requieren los parámetros mencionados en el punto O.
Aunque en el modelo de validación se puede manejar un formato para cada tipo de mensaje, se
decidió generalizar este formato con el que incluye el mayor número de parámetros para una
comprensión más fácil del lector del modelo del protocolo. Los parámetros no utilizados se llenan
con un valor cualquiera.
donde
Una vez detenninadas las funciones que tiene que desarrollar el protocolo y plantear los
requerimientos que debe satisfacer debido al medio ambiente en ·~l que se va a implementar, el
siguiente paso es validarlo. Para ello es necesario modelar cada una de las funciones del
protocolo y plantearlo a través de un modelo de validación, el cual se describe a continuación y
cuyo código puede ser consultado en el Apéndice B.
El modelo presentado para la validación del protocolo propuesto consiste en cuatro procesos,
además del proceso iniciador init, que define los tipos de mensaje y lanza en paralelo los procesos
principales (refiérase al punto 3.2.6.2).
Los dos procesos más importantes son Smmspm y Cmmspm que modelan las máquinas del
protocolo MMS en el servidor y en el cliente respectivamente. fa.tos son los procesos donde se
centra la validación del protocolo. Los procesos Cupper y Supper modelan el comportamiento
general que tendrán las aplicaciones del cliente y el servidor qu·~ usen el protocolo MMS. El
esquema general de las interacciones de estos procesos se muestra en la Figura 39 y se detallan en
los próximos puntos.
107
-........ -..............c.
Q,j
- -
=
......
...
c. =
......
Q,j
...
Q,j c. c. Q,j
c. ::::1 ::::1 c.
c. 1 c.
::::1
1 E! ª1 ::::1
Q
Q Q el
..... ~ ~ .....
to_link[l]
from_link[O] to_link[O]
El proceso Cmmspm representa y modela las funciones que tiene a cargo la máquina del
protocolo MMS para la entidad cliente. Este proceso recibe información del cliente y, de acuerdo
a las reglas preestablecidas por el protocolo, regresa o no algún tipo de mensaje. En la Figura 40
se aprecia el diagrama general de este proceso y se describe su funcionamiento a continuación.
108
ID_llnlclnJIMUln_XXXPDU
l-----l~_.IJPP8'1n)?MUR~_l()O(P0
m_llnk(nJ?MliCf_)O()(PDU
1-----C)+----I ID_'-'lnJIMUCí_XXXPOU
( ~ L.aca-1
,,.Logo___.ul.... Sen,. Con!. Sen,. NoConf.
m_uppe~nl?MlaRq_XXXPOU
O'\.Jlnk(nJ?MLoln_XXXPDU
G
Figura 40 Modelo de Validación General de la MMSPM para la endtidad cliente
Una vez hecha la inicialización de las variables, el proceso espera por la petición de Login que el
cliente debe enviarle (ver Figura 40); si ésta no llegase por alguna razón y el temporizador se
agotara, la máquina del protocolo terminaría su ejecución.
Recibida la petición de Login, Cmmspm trata de comunicarse con su similar en la entidad del
servidor enviándole una indicación de Login; con esta acción la máquina pasa a un estado
etiquetado con "chk" en la figura antes mencionada, en el cual checa si la máquina remota está
levantada esperando recibir una confirmación de Login.
Si cmmspm recibiera en este estado una petición de Logout por parte de la entidad local, enviaría
una indicación de este servicio a la entidad remota y esperaria por la respuesta de ésta. Este
estado está etiquetado como "ExpLo" en la Figura 41. Si se recibe una indicación de Logout
remoto, cmmspm eliminaría todas las asociaciones que tuviera pendientes y enviaría una
confirmación de Logout a la máquina remota entrando así a un estado StandAlone. Para eliminar
todas las asociaciones, la mmspm sigue el flujo detallado a continuación y mostrado en la figura
antes mencionada.
s N
N
Para eliminar una petición pendiente, la máquina verifica que el estado de ésta sea wait_ conf; si
es así, envía un mensaje de error de servicio confirmado a la capa superior. Posteriormente libera
la petición.
11O
En este estado (Ver Figura 40), la máquina del cliente espera por una confim1ación de Logolll y
al llegar ésta, la retransmite a su capa superior y da por terminada su ejecución. Si el mensa.Je
esperado no llega antes de que se agote el temporizador, cmmspm da como finalizado el servicio
y transmite a la capa superior un e1Tor para que ésta decida si se aborta completamente o no el
l.ogin.
Estando en este estado, cmmspm probablemente recibe otros m~nsajes provenientes de la entidad
remota, debido a que éstos estaban en tránsito; tales mensajes deben ser omitidos y sólo se
responderá a una indicación de Logout remota, si llega.
5.1.1.5 StandAlone
En este estado, la máquina sólo espera que la capa superior genere la petición de Logo111. por lo
que todas las peticiones diferentes a ese servicio serán contestadas inmediatamente con un error
del servicio solicitado. Una vez llegada este tipo de petición, la máquina envía una confirmación
de Logout y tem1ina su ejecución.
El proceso Cupper modela el comportamiento que la aplicación debe guardar para poder
comunicarse adecuadamente con la Máquina del Protocolo MMS Cliente descrita en el punto
5.1.1. El esquema de este proceso se muestra en la Figura 42 y en la Figura 43, descritas en los
siguientes párrafos.
111
1o_upper[n!?ML1Cr_ErrPDU
count ;: O]
1
r-- --- ---8
6 r'J'=;
,- -- ·- _"ºm_-::~nJ•MAsRq_l-on-,-
,1oat_•-_ReQ-u-•s-1PD-U-~ '6g~~ '
to_ u¡:per[nJ ?MA sCf_ in1tiate_ ResponsePOU to_upper¡nj"MAsCf_reiect_PDU . _ _J
Guarda Asociación
Una vez inicializadas las variables locales, Cupper envía un mensaje a la MMSPM local para
indicar que requiere conectarse a la entidad remota, esto es, envía una primitiva LoginRequest y
pasa a un estado "Check".
En este estado Cupper espera por un mensaje tipo LoginConjirm, lo cual indica que la máquina
remota existe y está lista para establecer la comunicación, lo c_ue lleva a este proceso a un estado
Ready. Es importante recordar que esta parte del protocolo es adicional al MMS y tiene como
objetivo verificar únicamente la existencia de la máquina remota.
Al entrar a este estado (etiquetado como "a" en la Figura 42), Cupper inicializa un contador de
asociaciones en O y en este momento, la aplicación es capaz ele hacer cualquiera de las siguientes
' .. V
'
112
acciones: solicitar una asociación, dar de baja una asociación, solicitar un servicio confim1ado,
solicitar un servicio no confirmado o notificar su salida de la red. Además de estas acciones, que
se describen en los párrafos siguientes, se agrega una en la que sólo figura la instrucción SKIP,
esto para simular que la aplicación puede ejecutar cualquier otra instrucción que no tenga
relación con el protocolo pero que implica que está ocupada. Lo anterior es importante para que
el validador pueda encontrar todos los estados posibles más apegados a la realidad.
Este estado está marcado con la etiqueta "b" en la figura mencionada e inicia enviando un
mensaje de PeticionAsociacion. Aunque en la práctica, en este mensaje viajan los valores
negociables de MMS (refiérase a la sección 3.1.3.2) que son determinantes para que las entidades
acuerden si se pueden o no asociar, en el modelo de validación no se requieren ya que las dos
alternativas son simuladas por la entidad remota contestando aleatoriamente con las primitivas
RespuestaAsociacion y RespuestaAsociacionError.
Cupper espera en este estado hasta que recibe un mensaje de su máquina local al que responde
con una acción determinada y va al estado "Ready".
Si recibe una RespuestaAsociacion, significa que la máquina local y la remota han registrado la
asociación exitosamente y puede proceder a solicitar peticiones de servicio confirmado y de
servicio no confümado. La aplicación guarda el identificador de la asociación e incrementa el
número de asociaciones conseguidas count en una unidad. Count le sirve a la máquina para saber
si tiene al menos una asociación establecida para que pueda solicitar los servicios que requieren
que así sea.
Para registrar la salida, el número de asociaciones conseguidas debe ser cero (si se trata de una
salida normal), aunque puede ser que la aplicación requiera finnar la salida sin haber dado de
baja sus asociaciones apropiadamente, esto está contemplado por la MMSPM local (refiérase a la
punto 5.1.1).
113
Para iniciar la salida Cupper envia una PeticionLogout y espera por una Co11.firmacio11Logout,
después de la cual termina su ciclo de vida.
Teniendo al menos una asociación, la aplicación puede solicitar un servicio confirmado (Etiqueta
"d", Figura 43) transmitiendo el mensaje PeticionSen,,Confindicando a través de cuál asociación
será efectuado el servicio. En la implementación este mensaje lleva, además, los datos del
servicio requerido y parámetros de entrada/salida correspondientes.
Si ninguno de los tres mensajes no llega antes de que el temporizador se agote, entonces Cupper
asimila el servicio como un ErrorSen,,Conf Cualquier que sea el caso, Cupper regresa al estado
ready después de tomar las acciones mencionadas.
Como en el caso anterior, la aplicación requiere tener una asociación establecida antes de solicitar
el servicio, si no es así la máquina simplemente omite la solici.tud.
Esta sección del protocolo es muy simple, sólo se envía la PeticionSen,,NoConf a la máquina
local que contiene el identificador de la asociación por donde se desea efectuar el servicio y, en la
implementación, los datos del servicio y parámetros correspondientes. Una vez enviado este
mensaje, Cupper puede regresar inmediatamente al estado Ready ya que este servicio, como su
nombre lo indica, no requiere de confirmación.
114
from_uppe~nJ'MUIRq_unconflrmed_P~
r-,-rom-_-up-pe-~n¡-,M-CIR..._q-_co-nfi-rmed-_R-eq-ue-SIP_D_U- 1 from_u,-,pe-~n-J!M_R...,IR_q___co_ncl_u<f_e_-Req-u-es-,P-DU-
-$--Hr---,
J
.-: lo_uppe~nJ?MCICl_confirmed_ResponseP~ to_upperfn]?MRICf_conc1ue1e_ResponsePDU
lo_uppe~n]?MCICl_confirmed_E~ to_upperjn)?MRICf_conclude_ErrnrPOU I
o_uppertnJ?MRICf_reject_PDU
Esta acción sólo tiene sentido si la asociación existe, es decir, si el número de asociaciones
conseguidas por la aplicación es mayor a cero (count > O), sin embargo, si la aplicación trata de
dar de baja una asociación no existente, la máquina local genera una respuesta positiva que indica
que la asociación ha sido dada de baja, ya que realmente no existe (refiérase a la sección
anterior).
Para dar de baja una asociac1on (etiqueta "f' en la Figura 43), Cupper envía la primitiva
PeticionConclude y espera por la recepción del mensaje RespuestaConclude, el cual indica una
baja exitosa de la asociación, procediendo a eliminarla de sus registros locales y a decrementar el
contador de asociaciones conseguidas.
En este estado también se puede dar el caso de que el PDU de PeticionConclude sea rechazo, lo
que es indicado a Cupper mediante la primitiva RechazoCondusion.
115
5.1.3 MÁQUINA DEL PROTOCOLO MMS SERVIDOR
Smmspm interactúa con su proceso superior, el servidor, y con la máquina MMS de la entidad
remota; atiende las peticiones y respuestas del servidor y las transmite a la máquina remota, o
bien, rechaza estas primitivas regresando una respuesta al servidor. Además, esta máquina
atiende las indicaciones que provienen de la entidad cliente y es encarga de transferir las
confimrnciones de los servicios, cuando esto se requiere.
B
$----)-o.trom_upperfnJ?MLiRq_XX.XPD~ _--,... lo_upper[nJ!MUCf_XXXI~
é om_linkfn)?Mliln_XXXPDU 1-------_.,-,-om-_upperl--n)?-Mlo-Rq___X_XX___,~~
_____
......_rom_uppe~n)?MLoRq__XXXPOU
__, _ _.,~, to_link(nJ!MLoln_XXXPO~>------+o+-------t
Smmspm inicializa las variables locales y espera por una Peticionlogin por parte del proceso
servidor. Si ésta no llega antes de que se agote el temporizado:~ preestablecido correspondiente, la
máquina daría por hecho que no existe el proceso y terminaría su ejecución.
116
En el caso contrario, s1 la petición llega, entonces Smmspm pasa a un estado llamado
StandAlone.
La principal característica de este estado es que Smmspm ha registrado al servidor local, pero
aún no tiene registrado al cliente. Este es un estado final válido (ver 3.2.6.6.3), es decir, el
modelo puede permanecer aquí sin límite de tiempo. Para el validador Xspin esto se debe marcar
con la etiqueta "end" y por ello este estado se puede localizar en la Figura 44 con la etiqueta
"end3".
En este estado, Smmspm está escuchando mensajes que provienen del servidor local y de la
máquina MMS remota. Si llega una Peticiónlogout por parte del servidor, la máquina le responde
inmediatamente con una primitiva ConfirmacionLogout y tennina su ejecución; esto lo puede
hacer sin más acciones ya que no tiene registrado al cliente.
Si recibe una IndicacionLogin por parte de la máquina remota, entonces le envía a ésta una
primitiva ConfirmacionLogin y pasa a un estado conectado.
En este estado Smmspm tiene registrado tanto al servidor como al cliente remoto y está listo para
atender las peticiones de este último; Este estado se encuentra marcado con la etiqueta "end2" y
es un estado final aceptable ya que la máquina puede permanecer indefinidamente aquí. En esta
situación Smmspm puede atender los servicios de Logout por parte del servidor, servicios de
Asociación, servicios de Liberación de Asociación, Servicios No Confirmados y Servicios
Confirmado y además, brinda el servicio de Centinela, todos estos descritos en los párrafos
restantes de esta sección.
Este servicio inicia cuando Smmspm recibe una primitiva del tipo PeticionLogout que genera el
proceso Servidor cuando pretende dar por terminado su ciclo de vida. El primer evento que
genera el Smmspm es el envío de la primitiva lndicacionLogout a la máquina del protocolo del
cliente y después espera en el estado marcado como ExpLo (ver Figura 44). En este estado la
máquina espera por la primitiva ConfirmacionLogout y al llegar ésta, la retransmite al Servidor
para indicarle que puede terminar su ejecución y ella hace lo mismo.
Smmspm puede recibir otras primitivas que la máquina remota pudo generar antes de emitir la
ConfirmacionLogout; si la primitiva es del tipo lndicacionLogout significa que la máquina
remota también pretende terminar su ejecución, por lo que Smmspm envía una
ConfirmacionLogout hacia el Cliente y regresa a su estado füpLo. Si la primitiva es de cualquier
otro tipo, Smmspm simplemente la omite y permanece en ExpLo.
117
Este es el primer servicio MMS que solicita la entidad cliente cuando quiere inicializar
propiamente la conversación con el Servidor. En este mensaje viajan los parámetros negociables
de la asociación por la parte del cliente; el servidor compara estos valores con sus parámetros
correspondientes y determina los valores que serán usados para la asociación. Estos parámetros
de negociación son mencionados en la sección 3.1.3.
--·¡
91 "'-~~~~~~......
1 _>-<f----<:_
l
0--zom_upper(n)"MAsRs_initiate_ResponsePOU I ---.Q-----+l 1o_upper(n) MAsln_reject_P~>---+•8
l
<? - ·~om_upper(n)?MAsRs_init1ate_RasponsePOU I
1
e Res. OK. Asociación )
l
O-------;)*"om_upper(n)?MAsRs_1niliate_ErrorPDU
Por otro lado, si la asociación ya esta registrada y su estado es Associated, entonces Smmspm
responde al cliente que la asociación esta completa con la primitiva ConfirmacionAsociacion. Si
la asociación existe pero aún no está asociada, Smmspm simplemente omite este mensaje. En
cualquiera de los dos casos anteriores, Smmspm regresa al estado estable end2.
Este servicio es solicitado por la capa superior de Smmspm, el proceso Servidor, y lo hace a
través de la primitiva RespuestaAsociacion, lo cual obliga al proceso Smmspm a ir al estado
marcado como "ResOKAsociacion" en la figura antes mencionada. Después de haber recibido
este mensaje, el proceso verifica que la asociación involucrada exista y que su estado sea
Calledlnit. Si es así, la marca como Associated. envía a la entidad solicitante una respuesta
positiva de confirmación usando la primitiva RespuestaConjirmacion y regresa al estado end2. Si
la condición mencionada no se cumple, la máquina omite este mens;~e y va al estado end2.
Este servicio ocurre cuando el servidor no puede atender la asociación y lo indica enviando la
primitiva RespuestaAsociacionError a Smmspm. A la recepción de este mensaje, Smmspm
entra al estado etiquetado como "Resp. Err. Asociación" de la Figura 45 y verifica que la
asociación exista y esté marcada como Calledlnit. Si la condición ~.e cumple, Smmspm elimina
la asociación de la tabla local y envía el mensaje ConjirmacionAsodacionError. Si no se cumple
simplemente omite el mensaje recibido. En ambos casos el proceso regresa al estado final
aceptable end2.
Este servicio modela la situación que no es usual pero puede suceder, cuando el Servidor envía la
respuesta de la asociación, negativa o afirmativa, y Smmspm tncuentra datos erróneos al
procesarla. Smmspm responde a este servicio con la primitiva Jndi'cacionAsociacionRechaza y
regresa al estado end2. Este servicio está etiquetado como "Resp. Asoc. Sim. PDU Defectuoso"
en la figura antes citada.
Este servicio es generado por la entidad cliente para notificar al servidor que requiere dar de baja
una asociación y se lo indica mediante la primitiva JndicacionConclusion. Este servicio está
etiquetado en la Figura 46 como "Ind Liberación", donde se aprecia que el paso siguiente a la
recepción del mensaje citado, es verificar que exista la asociación. Si existe y está asociada,
Smmspm la marca como CalledConc; si existe pero no está asociada, omite el mensaje; por
último, si no existe regresa una confirmación exitosa de la conclusión a la entidad cliente.
Cualquiera que sea el caso, el protocolo regresa al estado de donde partió, el end2.
119
Cuando la Mms del cliente requiere un servicio confirmado (refiérase al punto 5.1.1.3), genera la
primitiva lndicaciónServConf que es procesada por Smmspm como a continuación se describe y
como se puede observar en la Figura 47 en el punto marcado como "Ind. Serv. Conf.".
Primeramente, Smmspm, verifica que exista la asociación y que esté marcada como Associated,
si no es así regresa al cliente un el mensaje ConfirmaciónServConjError; si se cumple la
condición anterior, verifica que no esté registrada la indicación en la tabla local de indicaciones,
si ya está registrada simplemente omite el mensaje. Después de la anterior validación busca
espacio para la indicación, si no hay regresa un mensaje del tipo ConfirmaciónServConjError,
pero si hay espacio registra la indicación con un estado W_Resp. Cualquiera que sea el caso,
Smmspm regresa a end2 después de haber atendido este servicio.
120
? :)Í'rom_hnk[n)?MRlln_a,nclude_RequestPDU I
r-------<
, N
-
'
to_link(n]•MRJCf_conclUCle_ResponsePOU
I
1
1..------------, ~
Z--•~"~"'"-•~•·-~-eeoJ ~---,(
·-
to_upperfnJ!MRlln_reje~
• om_upper[nJ?MRIRs_conclude_ResponsePDU --•
I Res. OK Liberación.
o-.¿"rom_upperfnJ?MRIRs_conctude_ErrorPOUI
------0>()----0>--C::::=-
~1o;_~lin~kjn~)!M~R~ICf~-"'~n~clud~•~-E~~·ro~rP~Dug::::::----! Associated
Este tipo de mensaje es enviado por el servidor y contiene el resultado de la operación solicitada
por el cliente, por ejemplo, el estado de un semáforo, valores de variables, posición de la
herramienta del robot, etc., si es afirmativa y la razón de la falla si es negativa. Al recibir
Smmspm esta primitiva, verifica que la indicación exista en la tabla correspondiente y esté
marcada como W_Resp en la correspondiente tabla (ver Figura 47), si es así, la da de baja y
transmite hacia el cliente el PDU recibido cambiando la primitiva a ConfirmaciónServConf Si
alguna de las condiciones no se cumple, entonces Smmspm omite el mensaje. En todo caso,
Smmspm regresa a end2 al terminar de atender este servicio.
Este servicio emula la situación que se presenta cuando el servidor ha generado un mensaje
RespuestaServConf pero por alguna razón Smmspm no puede procesar el PDU y entonces tiene
que rechazarlo; para hacer esto, genera un mensaje IndicacionServConjRechazo. Refiérase a la
figura mencionada en el párrafo anterior en el punto marcado co::no "Resp. Serv. Conf. PDU
defectuoso".
121
t· :)rom_l,nk(n)?MCfln_confinned_ReoueSIPDU 1 -=--=---.
1o_linklnJ1MCfCf_c:onfirmed_ErrorPOU
f-----Zº"'-upper(n]7MCIRs_confirmed_ResponsePDU 1 ____..,.-,-o_u-ppe-~-n¡,-Mc-nn-_u
¡~- -~.~~:~~-:~·-·-'"! ·~
l
o-zm_uppe~n(?MCIRs_a,nfirmed_ResponsePDi ~
Este servicio sucede cuando el Servidor desea abandonar su operación y lo notifica a Smmspm a
través de la primitiva LogoutRemoto. Para que este servicio s(:a completado exitosamente,
Smmspm debe liberar exitosamente todas las asociaciones existentes; después de cumplir con
esta tarea envía un mensaje Confirmacionlogout hacia el servidor. Para deshacerse de las
asociaciones existentes, Smmspm toma las acciones descritas a continuación e ilustradas en la
Figura 48.
Para cada asociac10n existente, Smmspm verificar que su estado sea Associated, si no lo es
simplemente la libera; si ese es su estado, Smmspm libera todas las peticiones registradas en la
tabla de peticiones de la forma en que se indica en el siguiente párrafo y libera todas las
indicaciones eliminándolas simplemente de su tabla de indicaciones.
122
Cada petición es eliminada de la tabla de peticiones, pero si esta marcada como W_ Conf. (lo que
significa que se espera la confirmación del servicio que representa tal petición), entonces, envía
al servidor un PDU con la primitiva ConfirmaciónServConjError antes de la eliminación.
l 1o_upper!nJ•MUfln_unconfirmed_P9,,..------ end2
N
------+tt:l 10_1ink(nJ1ML0Cf_XX)(PO~
----8
N
~----+
~
N
N
El servicio en el que se requiere que el objeto, asociación, petición o indicación, sea confirmado
por un proceso distinto al que lo está atendiendo antes de regresar una respuesta al solicitante, se
presta marcándolo con un estado, según su máquina de estados. Por ejemplo, en una petición de
asociación, la mmspm local la registra y la marca como Callinglnit y envía una indicación a la
máquina remota, regresando para atender otra petición. Lo anterior es con el objetivo de que la
máquina trabaje de forma asíncrona respecto a su similar remota, lo cuál genera una mayor
optimización en el tiempo de respuesta de las máquinas, sin embargo, la principal desventaja es
que implica la existencia de algún mecanismo de mantenimiento d,~ los estados "pendientes" de
los objetos para evitar que estos se queden en tales tipos de estados. El propósito principal del
proceso Centinela es, precisamente, dicho el encargado de dicho mantenimiento; Centinela es un
proceso paralelo concurrente con la máquina de estados mms y, la mayoría del tiempo está
inhabilitado pero cuando despierta, revisa todos los objetos, los que están esperando una
respuesta son marcados como candidatos a eliminarse y envía una r,~transmisión del mensaje que
dejo al objeto en tal estado de espera. Si Centinela encuentra que el objeto está ya marcado como
candidato a eliminarse cuando hace su revisión, entonces genera el mensaje de error del servicio
123
y los transmite al proceso que esta esperando repuesta, eliminando el objeto de la tabla a la cual
pertenece. Este servicio aplica a ambas máquinas, por ello se explica en una sección
independiente a ellas.
Centinela hace un barrido en la tabla de asociaciones, buscando aquellas que estén en estado
distinto a Associated, es decir, que se encuentren en estado "Callinglnit ", "Calledlnit ",
"Calli11gC011c" o "CalledConc" y hace el mantenimiento de la siguiente manera.
Sí Centinela encuentra una asociación marcada como Calli11glnit, significa que ésta espera una
Co,!firmacionAsociacion de la mmspm remota, y por ello retransmite el mensaje de
lndicacionAsociacion marcando esta asociación como candidata a eliminación. Si ya esta
marcada, entonces la desaloja de la tabla de asociaciones y envía una
Co11firmacio11AsociacionError al proceso de capa superior.
El último de los estados de espera de una asociación es cuando está CalledConc; este implica una
retransmisión del mensaje JndicacionLiberacion a la capa superior si la asociación no ha sido
previamente marcada por Centinela, ya que sí es así, Centinela regresa la asociación a estado
Associated y responde a la máquina remota con ConfirmacionLiberacionError.
Para que la existencia de una petición o indicación tenga sentido alguno, la asociación a la cual
esta ligada debe estar asociada (Associated), por lo que al barrer la tabla de asociaciones,
Centinela se detiene en las marcadas con tal estado y revisa su tabla de peticiones e indicaciones
correspondientes verificando si están en estado pendiente, el cuál corresponde a W_ Conf para las
peticiones y a W_Resp para las indicaciones.
Si la petición esta en estado W_ Conf, significa que la mmspm correspondiente envió previamente
a su análoga remota una lndicacionServConf. Si la petición no ha sido aún marcada por
Centinela, éste retransmite esta primitiva y la marca. De otro modo, la elimina y notifica a la capa
superior el error mediante la primitiva ConfirmacionSeniConfError.
124
La tarea inicial del proceso servidor es firmarse dentro del entorno; el objetivo de esta tarea es la
sincronización de este proceso con el proceso Smmspm y esto se lleva a cabo usando la primitiva
Peticionlogin. Una vez emitida esta primitiva, el proceso Servidor espera en un estado etiquetado
como "Rx" en la Figura 49, donde espera la primitiva ConfirmacionLogin para después pasar al
estado Conectado etiquetado en la figura como "end l ".
Este estado está etiquetado como "end" en la Figura 49 y es el estado fundamental del Servidor,
ya que en este momento está disponible para atender las peticiones generadas por el cliente; estos
pueden ser: Asociación, Liberación de Asociación, Servicios Confirmados y Servicios No
Confirmado; Eventualmente puede pasar al estado Logout. Todos estos servicios se describen en
los siguientes párrafos.
Este servicio es detectado por el servidor al recibir la primitiva JndicacionAsociación la cual llega
con el PDU que contiene los parámetros negociables para una asociación del tipo MMS (refiérase
al punto 3.1.3.2). La respuesta a esta indicación puede ser afirmativa. en cuyo caso se agregan los
parámetros para la asociación, o negativa. Después de responder a la Máquina Smmspm con
cualquiera de las primitivas RespuestaAsociacion ó RespuestaAsociacionError, el Servidor
regresa al estado "end".
125
5.1.5.4 Servicio Indicación de Liberación de Asociación
IO_upperjn]')MLiCr_ErrPDU lo_upperfnJ?MUCf_XXXPDlf
Fin
from_upperfnJ•MAsRs_initiate_ResponsePOU
to_upperfnJ?MRlln_conclude_RequestPOU ~--
trom_upperfnJ 1MRIRs_rondude_ResponsePDU
) to_upper[nJ?MRlln_reject_POU
I from_upperfn)!MRIF~s_conduele_ResponsePOU
C·
Figura 49 Modelo de Validación del Proceso Servidor.
La primitiva JndicacionServConf indica al Server que el cliente soliGita un servicio que requiere
una respuesta; el servicio solicitado y sus parámetros correspondimtes están contenidos en el
PDU recibido y son accesados por Server para ejecutar las tareas correspondientes. Una vez
hechas estas tareas y dependiendo del estado final resultante, Server responde a Smmspm
afirmativa o negativamente usando las primitivas RespuestaServConfo RespuestaServConfError,
respectivamente.
Los Servicios no confirmados no requieren de respuesta alguna por parte de Server, por lo que al
recibir la primitiva lndicacionServNoConf, la cual indica esta clase de servicio, no tiene más que
volver al estado "end", desde el punto de vista del protocolo, ya que en realidad, Server tiene que
126
ejecutar los procedimientos pertinentes para satisfacer la indicación del servicio. Esta parte del
protocolo se puede observar en la Figura 50.
to_upper(n)?MCtln_conllrmed_RequestPOU to_upperfnl?MCtln_rejed_POU
ID_uppe~nJ?MLoCf_XXXPDU
MCfRs_confinned_ErrorPOU
MCfRs_conftrmed_ErrorPDU
from_upper!n)!MCfR.s_ainfinned_ResponsePOU
Una parte importante dentro del modelado del protocolo es la que satisface a la premisa de que
las máquinas del protocolo deben interactuar con cualquier entidad que pueda entender el mismo;
tales entidades, el servidor y los clientes, pueden empacar los PDUs con información errónea, por
lo que las máquinas deben de ser capaces de rechazar este tipo de mensaje. Smmspm modela este
rechazo de PDUs y envía las primitivas adecuadas según el tipo de servicio del que se trate.
Server solo tiene que simular la retransmisión del mensaje en forma correcta. Lo anterior es
aplicable a los cuatro servicios previos a éste y se puede observar en los esquemas de las figuras
antes mencionadas.
El estado "end" del proceso Servidor es un estado final aceptable, ya que teóricamente puede
permanecer brindando servicios a los clientes conectados, pero también existe la posibilidad, y
una posibilidad con probabilidad alta, de que el servidor eventualmente quiera terminar la
conversación con los clientes registrados. Para indicar esto, el servidor emite un mensaje de tipo
PeticionLogout, después de lo cual espera un tiempo determinado por la respuesta por parte de
Smmspm. Si la respuesta recibida es del tipo ConfirmacionLogout, o si el tiempo se agota antes
127
de recibir respuesta alguna, Smmspm termina su ejecución; pero por otro lado, si la respuesta
recibida es una ConfirmacionLogoutError Smmspm regresa al e.5tado final "end", para poder
decir si trata de abandonar su registro de una manera impropia.
Esta sección tiene como propósito el remarcar la forma en como se modelaron los requerimientos
del protocolo para una validación completa.
Se han explicado los cuatro procesos que modelan el comportamiento completo del protocolo
propuesto: Client, Cmmspm, Smmspm y Server, así como también de los diferentes tipos de
mensajes posibles emitidos por cada un estos programas según la especificación MMS. Sin
embargo, el software desarrollado en el presente trabajo correrá en el nuevo controlador y
eventualmente interactuará con programas de control cargados en los robots y en el mismo
controlador que se comunique usando MMS. Existe la posibilidad de que algunos tengan
versiones MMS distintas y/o no soporten algunos servicios, por lo que se hace necesario una
validación de los servicios que viajan usando el protocolo y de los formatos de los PDUs
transmitidos. El anterior problema está muy relacionado con la implementación del protocolo,
pero en la cuestión del tipo de mensajes lo está con el modelo mismo, por lo que se debe validar
El rechazo de PDUs solo puede existir del Client al Cmmspm o del Server al Smmspm, ya que
Cmmspm y Smmspm son producto de un mismo desarrollo, el de esta tesis. Así que para
modelar esta situación, los procesos Cmmspm y Smmspm están preparados para recibir el
mensaje del tipo XXXRechazo, donde XXX representa la primitiva normal especificada en MMS
pero que al pasar una función "ValidatePDU" se convirtió en un rechazo del mismo. La función
"ValidatePDU" no es relevante en el modelo de la validación, por lo que no se incluye, pero sí lo
es el resultado que genera, ya que esto modifica el comportamiento de las entidades. Por otro
lado, Client y Server deben estar preparadas para manejar los mensajes del tipo XXXRechazo, y
a la recepción de éstas deben retransmitir la primitiva modificando el PDU o enviar una primitiva
de error. El detalle de estos servicios se encuentra detallado en la sección 5.1 para cada uno de los
procesos.
Los enlaces de los transputers son un medio de comunicación muy eficaz [13], sin embargo
existe la posibilidad de falla y por lo tanto de pérdidas del mensaje. Además de una falla de los
enlaces, se debe tener presente que los mensajes viajan fuera del controlador a través de
conectores fisicos RS232 donde la probabilidad de mensaje omitidos es mayor. Para modelar esta
situación se sustituyo en el código de los procesos una secuencia if-fi, con dos alternativas (ver
Figura 51 ); la primera de ella es la secuencia original precedente a la recepción del mensaje y la
128
segunda una instrucción skip. Si el proceso elige esta última, se comportara como si no hubiese
recibido tal mensaje, es decir que hubo un error de comunicación. El ejemplo de la Figura 5l(a)
fue extraído del código del proceso Cmmspm usado para la validación del protocolo y
corresponde a la recepción de la primitiva Peticionlogout por parte del proceso Client, a lo que
la máquina responde con una transmisión de una Indicacionlogout hacia la entidad remota y se
va a un estado de expiración local. La parte (b) muestra como se modifica el código para emular
la pérdida del mensaje, Cmmspm recibe la primitiva PeticionLogout y elige entre seguir el
camino descrito o ignorar el mensaje manteniéndose en el estado Asociado.
Para evitar esperas indefinidas se implementan temporizadores, que garantizan que la ejecución
de los procesos sigue adelante aún y si no se recibe el mensaje esperado; después de la expiración
del temporizador generalmente se retransmite el mensaje, porque se asumen que se perdió el
primero. Si esta pérdida no fuera cierta y el mensaje "respuesta" estuviera en camino al tiempo
del agotamiento del tiempo de espera, el proceso receptor recibirá el mismo mensaje dos veces y
debería omitir el segundo. Para ello se implementa un etiquetado en los mensajes, marcando el
número de asociación según la máquina local, el número de asociación según la máquina remota,
el número de petición según la máquina remota y el número de indicación de la máquina local.
Estas etiquetas permiten verificar el estado de la asociación, petición o indicación antes de
responder apropiadamente al servicio aún y cuando se trate de un mensaje duplicado.
129
En la Figura 52 se muestra como ejemplo para este modelado una se,:ción del código del proceso
Smmspm que corresponde a la recepción de una IndicacionAsociacion con la que el cliente
solicita el establecimiento de una asociación. La máquina local del cliente alojó tal asociación y
le otorgó el número "!'', posteriormente envía la indicación (probablemente más de una vez) y
espera por una respuesta por parte Smmspm. En la primera parte del procedimiento, ciclo do-od,
Smmspm checa en su tabla de asociaciones locales para determinar i;i la asociación "l" ha sido o
no registrada previamente, si es así lo indica en la bandera bExiste. En la segunda parte,
estructura fi-if,el procedimiento muestra cuatro alternativas, las dos primeras son válidas cuando
la asociación no ha sido registrada previamente y el comportamiento está determinado por el
cupo o no de otra asociación en la tabla de asociaciones. Las dos alternativas restantes existen
para el caso de que la asociación ya haya sido registrada previamente y seguramente se trata de la
recepción de un mensaje duplicado. Si el estado de la asociación es Associated, Smmspm
responde a la máquina del cliente con una primitiva ConfirmacionAsociacion, para indicar que tal
asociación es totalmente válida. Si su estado es distinto, simplemente hace caso omiso del
mensaJe.
Análogamente a este ejemplo, existen secciones en el código de los procesos para manejar la
recepción de mensajes duplicados.
• Estado Group. (Refiérase a la etiqueta "End2" en el código de:1 proceso Cmmspm incluido en
el Apéndice B). La estancia de este estado por parte Cmmspm significa que tanto el proceso
servidor como el cliente están activos; todas las peticiones generadas por Client y todas las
respuestas generadas por Server son procesadas según el estado de la máquina del protocolo.
Es posible que el proceso se mantenga en este estado permanentemente.
• Estado Group. Cmmspm está en este estado cuando tiene al menos algún cliente registrado y
puede continuar allí indefinidamente ya que es su objetivo primario. Este estado esta marcado
con la etiqueta "End2" en el código de este proceso incluido en el Apéndice B
Para verificar esta propiedad por medido de XSPIN, se marca la opción "In" obteniéndose los
resultados mostrados en la Figura 53.
131
La invariante para este sistema (consulte el pu.nto 3.2.6.6.2), es qu«! el número de asociaciones en
todo momento y en cada máquina siempre debe ser menor o igual al tamaño de los arreglos
hechos con para estos fines. El número de asociaciones en ope,ración es contabilizado en la
variable NCD _ SM para la máquina del servidor y en NCD_ CM para la máquina del cliente; la
variable global MC representa el número de elementos de los arreglos que soportan la
información de las asociaciones en ambas máquinas y por ello el máximo de asociaciones
permitidas para evitar el desborde de los arreglos.
proctype monitor() {
if
::assert(NCD_ SM<=MC);
::assert(NCD_ CM<=MC);
fi
132
Como se puede notar, el proceso básicamente ejecuta una instmcción en toda su existencia.
XSPIN se encarga de correr cada posibilidad del código original del modelo seguida por la
ejecución de este pequeño proceso, buscando alguna que pueda violar cualquiera de las dos
aserciones. El resultado de esta prueba se muestra en la Figura 5-4-, el cual comprueba que esta
invariante es respetada por el protocolo.
Finalmente dentro de las pruebas a las que fue sometido el moddo del protocolo, esta la de
corroborar su avance o progresos (refiérase al punto 3.2.6.6.4), para dio se partió de la hipótesis:
"Si se solicita un servicio a alguna máquina del protocolo, eventualmente esta regresa una
respuesta positiva o negativa."
Esta aseverac1on se verificó con todos los serv1c1os otorgados en e:I protocolo; para efectos de
ejemplificar se toma el servicio de Login. Al igual que en la validación del punto anterior, se
agrega un proceso adicional al modelo, el proceso never (refiérase al punto 3.2.6.6.5); en el cual
se plantea la hipótesis mencionada de la siguiente manera:
133
never:
do
::!from _upper(O]?[MLiRq_ XXXPDU] -> skip;
::from _upper[O]?(MLiRq_ XXXPDU] -> goto acceptO;
od;
acceptO:
do
::!to_upper[O]?[MLiCf_XXXPDU]
&& !to_ upper[O]?[MLiCf_ ErrPDU];
od;
Como se mencionó en el punto antes citado, el proceso never nunca debe llagar a su última línea
para que sea válido la propiedad contenida en su interior para XSPIN. Como resultado de esta
validación se obtuvo la salida mostrada en la Figura 55.
Este capitulo tiene como objetivo el de presentar la implementación del protocolo MMS
propuesto en este trabajo. Primeramente se da un enfoque global de la aplicación y después se
presentan los detalles de ésta; para evitar repeticiones con lo expuesto en el capítulo "Validación
del Protocolo", los algoritmos y procesos sólo se detallan en los puntos que cambian debido a las
herramientas de programación usadas. El código fuente de esta implementación se incluye en el
Apéndice C.
6.1 GENERALIDADES
N2: T805 1
1
1
1
1
1
1
1
1
1
----.._¡_ 1
RxlCmmspm
Adicionalmente a estos dos ambientes, descritos más a detalle en los puntos 6.1.1.1 y 6.1.1.2,
existe un proceso llamado Feeder que se encarga de leer un archivo de comandos y
transmitírselos al proceso Client; un proceso llamado Killer que se encarga de enviar al proceso
Server un mensaje de paro cuando el operador del sistema así se lo indica; y por último un
Monitor que tiene como finalidad presentar en la pantalla de la computadora host la recepción
los mensajes recibidos por los cuatro nodos importantes de la aplicación MMS: Client, Server,
Cmmspm y Smmspm, con el fin de ilustrar el comportamiento interno del protocolo.
136
Aplicación WRCMDS
Generador de archivos
de comandos
Archivo de Comandos
Selección
caplura y
de comandos
¡······································· .. ········:
Aplicación RDCMDS
Lectura (opcional) de archivos
de comandos
Archivo de Comandos
Lectura de
de comandos
6.1.1 PROCESOS
El ambiente MMS del servidor está conformado por los procesos Server, TxServer, RxServer,
Smmspm, SCentinela, Rx2Smmspm, Tx2mmspm, RxlSmmspm, TxlSmmspm, los cuales se
describen en los siguientes párrafos y se muestran en la Figura 58.
137
...... ......
RxScrvcrToScrvcr t...
CJl
><
1--
.------¡
Buffer] 1
1______
t...
CJl
c:1
~mn,spmToRxScrvcr
G)
g
::¡
o
....
~
'!!
-!
t "
~ ,:1
~
L
,2
E
E
Q.
¡g
E
CJl
N
c:1
,------¡
Buffer2 1
1______
E
Q.
¡g
E
r;:¡
1--
~
i
t
E
Q.
¡g
E
~
><
1--
.------.
+-----4 Burfcrl
·------'
E
Q.
¡g
E
CJl
c:1
N
e
~
o
"'
"'
::¡
~
g ,¡J1
::¡
::¡ o
iE o
r;
r; E
o E
l
r; ~
z
V, Q.
...~ ...;!l
Al Proceso Monitor (SmmspmToMon)
"'
E ;!l
,( E
CJl
1 ~o
A K----------,
SmmspmToRxScrvcr
ü
. Al Proceso MMS Remoto (out[2])
'----------i e5 1 - - - - - - ~ ~
e
CJl
6.1.1.1.l Server
Este proceso tiene como finalidad ejecutar todas las actividades relacionadas con los servicios
posibles de la aplicación. Según MMS, la entidad servidor generalmente está representada por los
robots y las máquinas automatizadas aunque también existe la posibilidad que uno ó más
procesadores del controlador haga funciones de cliente y servidor a un mismo tiempo. En el caso
de que el servidor sea un robot, en este proceso se monta la función ejecutiva del robot (refiérase
al punto 3.1.3); para esta aplicación, en este proceso se montaron las rutinas de servicio a las
peticiones que hace el cliente remoto; el código se incluye en el punto 11.1 del Apéndice C. Este
proceso consta de un canal de datos de entrada y uno de salida para intercambiar datos con su
máquina de protocolo MMS. Exclusivamente para detener la ejecución de este proceso, que
realmente puede ser temporalmente indefinida, se adicionó un canal de entrada por donde recibe
la instrucción de paro que le da el proceso Killer. Existe un cuarto canal, que es de salida y sirve
para retransmitir los mensajes recibidos por este proceso al Monitor para que el usuario pueda
enterarse de la actividad realizada por él. Killer, Monitor y sus canales respectivos no forman
parte integral del protocolo MMS implementado en esta tesis, son incluidos como parte de la
aplicación demostrativa de éste.
Estos dos procesos sirven para emular el canal de recepción del servidor con una longitud tres, la
cual puede ser configurada fácilmente modificando el archivo de configuración MMSCONTS.H.
Para más detalles de las funciones de estos procesos refiérase al punto 6.2.3.
138
6.1.1.1.3 Smmspm
Los procesos Smmspm y Cmmspm son los más importantes dentro de esta implementación, ya
que en ellos está contenido toda la esencia del protocolo y su funcionamiento. Este proceso se
auxilia de las funciones, estructuras, variables y constantes incluidas en los archivos
MMSPRMCF.H y MMSPRMCH.H, los cuales se encuentran junto al código del Smmspm en el
Apéndice C. Smmspm consta de cinco canales dos de entrada y tres de salida, dos para la
comunicación con el proceso Servidor, dos para la comunicación con la entidad remota y uno
para indicarle al proceso Monitor del progreso del protocolo; éste último canal no forma parte
básica para la implementación del protocolo solo fue montado para esta aplicación.
Estos procesos están encargados de mantener los canales de entrada al proceso Smmspm con una
capacidad de almacenamiento de hasta 3 mensajes en espera (refiérase al punto 6.2.3). Los
primeros dos procesos reciben la información que proviene de la entidad remota, y los dos
restantes se encargan de recibir los mensajes del proceso Servidor.
El ambiente Cliente MMS lo componen los procesos Client, TxClient, RxClient, Cmmspm,
CCentinela, TxlCmmspm, RxlCmmspm, Rx2Cmmspm y T:{2Cmmspm, los cuales se
detallan a continuación y la relación entre ellos se puede observar en el esquema de la Figura 59.
139
e
(ij----------< g RxC'ln1ToCln1 .§ 1------ 1
_~u_rr!~-'
1
~ ...__ _ _C_mrr_~sp~m_To_Rx_Ct_n1_ _ ------18
!1 i ' .. i "
~1~l - - ·
-~1'
E E
~
íluffer2 E -
2 i
fjit 1 ~
A------<
CmmspmToRxClnt
..
-¡j
.~I Proceso MMS Remoto(out[2))
=
i:•-----~
e
u
En este proceso es el que modifica el usuario para ajustarlo a las necesidades de la aplicación; es
el punto de acceso al Ambiente Cliente MMS. Como demostración, en esta aplicación, este
proceso se dedica a procesar todas las instrucciones que el operador le indica a través de un
archivo. El archivo de comandos realmente es leído por un proceso independiente que corre en el
nodo O de la tarjeta el cual se describe más adelante en esta misma sección. El proceso Client
graba todos los comandos que tiene que procesar en un arreglo de comandos local, después
procesa uno a uno dependiendo del tipo de comando de que se trate. Este proceso consta de
cuatro canales dos de entrada y dos de salida; uno de los canales de entrada lo usa para recibir
mensajes del proceso que lee el archivo de comando, Feeder, el canal de entrada restante y uno
de los canales de salida los utiliza para comunicarse con su máquina de protocolo MMS, el canal
de salida restante es usado para enviarle datos al proceso Monitor. El código fuente para este
programa se encuentra en el punto 11.2 del Apéndice C.
Estos dos procesos desempeñan la función de una canal de longitud> O (ver punto 6.2.3), para el
canal de recepción del proceso Client. Los datos que son manejados por este par de procesos
provienen de la máquina local del protocolo del cliente.
6.1.1.2.3 Cmmspm
140
Cmmspm es el proceso que hace las funciones de la máquina del protocolo MMS para la entidad
cliente, es auxiliado por procedimientos, estructuras, variables y constantes incluidas en los
archivos MMSPRMCH.H y MMSPRMCF.H. Esta máquina consta de cinco canales, dos
dirigidos hacia el Cliente y dos hacia el Servidor; aunque sus mensajes están dirigidos a éstos dos
procesos, realmente los envía a los procesos receptores de éstos. El quinto canal es de salida y
está direccionado al Monitor para informarle de los mensajes que ha recibido, este canal no es
parte esencial de la implementación de MMS sino que está incluido para tener una herramienta
visual del avance del protocolo. El código de este programa está en el archivo CMMSPM.H
agregado a este documento en el Apéndice C.
Es el proceso encargado de dar seguimiento a los servicios pendientes registrados en las tablas de
conexiones, de peticiones e indicaciones (ver punto 6.2.1 ). El proceso CCentinela hace un
barrido de las tablas mencionadas para detectar servicios que estén pendientes; si detecta alguno
lo marca como candidato a eliminación y retransmite el mensaje del cual se espera respuesta para
despachar este servicio. Si el registro ya está marcado como candidato entonces lo elimina de la
tabla, realizando la parte complementaria del servicio para indicar a la entidad correspondiente el
error en el procesamiento del servicio solicitado. El comportamiento de este proceso está
explicado más detalladamente en el capítulo de validación en el punto 5.1.4 mientras que el
código C involucrado se encuentra en el mismo archivo que el proce:so Cmmspm.
Los dos primero procesos emulan un canal de longitud mayor a O para el canal de entrada de los
mensajes que van de la entidad remota a Cmmspm y los dos últimos tienen el mismo objetivo
pero para el canal que comunica al proceso Client con Cmmspm. Para un mayor detalle del
algoritmo seguido por estos proceso refiérase al punto 6.2.3
Además de los dos ambientes existen otros procesos sin ser parte esencial del protocolo MMS
complementan la aplicación; tales procesos son Feeder, Killer, Echol y Echol (ver Figura 60);
son descritos a continuación.
141
1- - - -
I Rnot p
-~ -
-=-=--1 j Del Proceso Server (ServerToMon)
G~v
Simhologia
ée-<
J Del ProccsoSmmspm(Smm!;pmToMon)
r _J._P~! Proceso C'!icnt (flicnlloMon)
_ -·~Proceso Cmmspm (CmmspmToMon)
0
f~odo u,;~J
: Al Proceso Server (FrKiller)
1
1~ 8-- : Al Proceso Client (RxClnlToClnt) ~o
1~
1
r---- 1
1] 1 1 Echol p I
L - - - ~ s:::r ~Wmmspm 10 Echo) 1 Al Clicn1c MMS (E.cho.lo Rr.lC'mmspm)
I~
I íl~--~
>-
1 ~,.,..,.......---,
1i
Del Clicn1c MMS (C'mmspm to Echo) Al Server MMS (E.cho to Rx ISmmspm)
o-
1 1
1 1
L-----
Figura 60 Otros Procesos de la Aplicación MMS.
6.1.1.3.1 Feeder
6.1.1.3.2 Killer
Con el objeto de detener la ejecución del proceso Server de una manera controlada, se incluyó
este proceso que reside en el nodo O debido a que requiere de funciones de entrada/salida. El
funcionamiento de este proceso es muy simple, solamente está monitoreando el dispositivo de
entrada del host y si detecta que el caracter "&" fue introducido por el operador, envía un
mensaje al proceso Server para que este detengan su ejecución. El mensaje enviado por Killer no
forma parte integral del protocolo sino que es requerido por esta aplicación; es un mecanismo
muy fino de detener el funcionamiento del proceso servidor. El código de este programa esta
incluido en el archivo ROOT.C.
Como se mencionó en el punto 4.3.3, uno de los requerimientos de este protocolo debido al
medio de trabajo, es que los mensajes se deben poder transmitir hacia el controlador de la interfaz
SIO 232/422 que corre en un transputer T225. Para asegurar que esta implementación es capaz de
comunicarse con un proceso Occam en un transputer de 16 bits se crearon echol y echo2 que,
teniendo estas características, no hacen más que retransmitir los mensajes que reciban. De esta
forma, cuando el controlador del SIO esté liberado, esta implementación puede ser fácilmente
adaptada para comunicarse a través del protocolo RS232/RS422.
Como se mencionó al inicio del punto 6.1, la forma de interactuar con la Aplicación MMS es a
través de archivos de comandos que contienen PDUs de tipo MMS empacada como cadenas de
caracteres. La razón de que los PDUs estén empacados de tal forma se detalla en el punto 6.2.2.
La aplicación WRCMDS graba un archivo con la secuencia de PDUs que le indique el usuario; el
software registra un PDU a la vez interactuando con el usuario para completar todos los datos
requeridos por el PDU en cuestión. Esta aplicación es muy sencilla y consta del programa
principal WRCMDS.C y de los archivos includes MMSPRIMI.H, MMSTYPES.H y
MMSCTES.H, compartidos con la Aplicación MMS.
La aplicación RDCMDS puede utilizarse opcionalmente para leer el tipo y los datos de los PDUs
que contiene un archivo de comandos MMS grabados por la aplicación WRCMDS; para ejecutar
esta aplicación solo basta dar el nombre del archivo que se quiere consultar. El programa
principal es llamado RDCMDS.C y también comparte con las otras aplicaciones archivos tales
como MMSPRIMI.H, MMSTYPES.H y MMSCTES.H.
Como se planteó en el punto 3.3.8, una de las características más importantes en una aplicación
diseñada para transputers es el archivo de configuración. Para la Aplicación MMS se decidió
utilizar el lenguaje de configuración Occam debido a que se combinan procesos de origen Occam
y C dentro de ésta, y el lenguaje Occam permite hacer paso de canales a ambos tipos de
programas mediante el uso de interfaces incluidas para este propósito, las cuales se detallan en el
punto 6.2.5 de este mismo capítulo.
• root.occ.- Interfaz Occam-C para el ambiente Servidor MMS y los procesos Feeder, Killer y
Monitor.
• client.occ.- Interfaz Occam-C para el ambiente Cliente MMS.
• Echo.- Proceso Echo.
root.occ y client.occ son lanzados en los nodos lógicos root.p y client.p, respectivamente; una
instancia de Echo se corre en el nodo echol.p y otra en echo2.p.
Un buen diseño en una aplicación para transputers es aquél que permite que los procesos
involucrados puedan ser montados en determinados transputers según sea la necesidad de la
aplicación, el número de transputers con que se cuente en la red y la topología de esta última,
cambiando simplemente el mapeo de los nodos lógicos en los transputers adecuados; todo lo
anterior considerando que los procesos que hacen uso de las funciones de comunicación con el
host deben estar forzosamente en el nodo O de la red; lo cual aplica para el objeto root.occ de la
aplicación MMS ya que usa el host como salida del monitoreo de los mensajes que circulan por
las máquinas MMS, por el Server y por el Client, y como entrada del mensaje de terminación del
Servidor MMS ("&"). En realidad, la implementación del protocolo, ni en la parte del cliente ni
en la del servidor, requiere de intercambio de datos con el host, ,~s la aplicación en particular la
que lo necesita.
Los nodos lógicos restantes pueden ser mapeados a cualquiera de los transputers de que estén
definidos en la red sin más acciones que las de crear los objetos según sea el tipo de transputer a
ocupar y modificar el archivo de configuración.
Por otro lado, los archivos de configuración para las aplicaciones WRCMDS y RDCMDS se
llaman WRCMDS.CFS y RDCMDS.CFS y están escritos en C; ·~stos archivos son muy simples
ya que solo requieren de un procesador en el cual corre un único proceso generado con código C.
Los archivos de configuración también se incluyen en el Apéndice E.
144
··································
To/l'rom Host
_ Üjn!LO~ l 1inlli!J1
r T225 1 1- T805
1 1
I (SIO) 1 1 2MB I
6KB I 1 1
..----+---, 1
I roolp I
l 1ink[2
1
1
1
1
_ _ _ _..... 1
1
Simbologia
1~.0~,
I I
Nodo Lógico
~
Can;:il
-----+
Figura 61 Distribución de la Aplicación MMS según MMS.PGM
Los archivos involucrados en cada una de las aplicaciones se presentan en las tablas a manera de
resumen.
Archivo Descripción
Cliente Código fuente en C del ambiente del Cliente MMS, recibe como
parámetros de entrada un canal de salida y dos de entrada. Define las
variables, canales y procesos involucrados en este ambiente y los lanza en
paralelo. Hace uso de los archivos includes siguientes: Mmsprimi.H,
Mmsctes.H, Mmstypes.H, Mmspdu.H, Mmstype2.H, Mmspdutr.H,
Trxbuff.H Y Cnunspm.H
Client o.occ Código fuente en Occam de la interfaz Occam-C: usada para el proceso
Client.
Cnunspm.h Archivo que incluye el código fuente en C para la máquina del protocolo
MMS de la entidad Cliente.
Echo.occ Código fuente en Occam del proceso que emula un eco en los PDUs
transmitidos entre el Servidor MMS y el Cliente MMS.
Feeder.h Archivo que incluye el código fuente en C del proceso alimentador de
comando (Feeder).
Mms.pgm Archivo de configuración de procesos escrito en Occam.
145
Mrnsctcs.h Archivo donde se concentran las constantes usadas relacionadas con esta
implementación el protocolo MMS.
Mmsdccod.h Código fuente en C del proceso que manda los mensajes a pantalla.
Mrnspararn.h Archivo donde se concentran los parámetros de configuración de esta
implementación el protocolo MMS.
Mmspdu.h En este archivo se encuentra la traducción en código C de la especificación
para el PDU de MMS original en ASN. I
Mmspdutr.h Este archivo contiene funciones para convertir el PDU MMS a una cadena
de caracteres y viceversa.
M msprimi .h Aquí se incluyen las macro-definiciones relaciom1das con las primitivas del
protocolo MMS de esta implementación.
MmspnncO.h Funciones de la Máquina del Protocolo MMS.
Mmspm1cl.h Funciones de la Máquina del Protocolo MMS.
Mmsprmc3.h Funciones de la Máquina del Protocolo MMS.
Mmsprmc4.h Funciones de la Máquina del Protocolo MMS.
Mmsp1mcf.h Funciones de la Máquina del Protocolo MMS.
Mmstype2.h En este archivo. junto con Mmstypes.h, se define los tipos internos a esta
implementación.
Mmstypes.h En este archivo, junto con Mmstypes.h, se define los tipos internos a esta
implementación.
Root.c Código fuente en C del ambiente del Servidor MMS, recibe como
parámetros de entrada 2 canales de salida y uno de entrada. Define los
procesos y canales necesarios para la implement~.ción del ambiente
Servidor MMS y, adicionalmente, el proceso KiLer y el Proceso Feeder con
sus respectivos canales. El código del Killer también es incluido en este
archivo y hace referencia a los archivos Mmsprimi.H, Mmsctes.H,
Mmstypes.H, Mmspdu.H, Mmstype2.H, Mmspdutr.H, Trxbuff.H,
Smmspm.H, Feeder.H
Root o.occ Código fuente en Occam de la interfaz Occam-C usada para el proceso
Root.
Smmspm.h Código fuente en C de la máquina del protocolo MMS para la entidad
Servidor.
Trxbuff.h En este archivo se encuentra el código fuente de los procesos que emulan
un canal de longitud >O y que forman parte integral de esta implementación
deMMS.
Tabla 16 Descripción de los archivos de la aplicación MMS.
Archivo Descripción
Rdcmds.C Código fuente de aplicación Rdcmds usada para leer los archivos de trabajo
escritos por la aplicación Wrcmds.btl; incluye los archivos mrnsprimi.h,
mmsctes.h, mmstypes.h, mmspdu.h, mmstype2.h y mmspdutr.h que se
mencionan en la Tabla 16.
Rdcmds.Cfs Código de configuración en C para la aplicación Rdcmds.btl
146
Wrcmds.C Código fuente en C del proceso que escribe commdos MMS a un archivi de
trabajo. Hace referencia a los archivos mmsprimi.h, mmsctes.h,
mmstypes.h, mmspdu.h, mmstype2.h, mmspdutr.h mencionados en la Tabla
16.
Wrcmds.Cfs Código de configuración en C para la aplicación Wrcmds.btl
Tabla 17 Descripción de los archivos de las aplicaciones Wrcmds y Rdcomds.
En esta sección de muestran algunos de los detalles más importantes en la implementación del
modelo de validación del protocolo MMS.
Como se mencionó en la sección 3.1.3 , el protocolo MMS requiere de que se guardan ciertos
parámetros relacionados con las asociaciones, peticiones e indicaciones para el funcionamiento
adecuado del mismo, estos parámetros son descritos en las siguientes tablas.
La base de datos requerida para guardar la información indicada en las tablas anteriores está
implementada como estructuras que se definen en el archivo MrnsprmcO.h (ver Apéndice C) y
que son referidas por los procesos y funciones relacionadas con las máquinas de estados del
protocolo MMS.
148
6.2.2 TRANMISIÓN DE PDUS MMS
El poder del protocolo MMS radica en la estructura estandarizada que conforma todo PDU
intercambiado en el ambiente MMS; esta estructura es muy compleja ya que tratar de incluir
todos tipos posibles de mensajes (refiérase al punto 4.3.4). Esta estructura debe ser convertida a
una cadena de caracteres para poderla transmitirla a través de los canales utilizando las funciones
proporcionadas por la herramienta de programación C.
Para ilustrar la forma en que se transmiten y reciben los PDUs MMS se extrajo una sección del
código del proceso Server que corresponde a la etapa de Logout, el cual se puede observar en la
Figura 62. El proceso recibe la trama haciendo una llamada a la instrucción Chan/n (refiérase al
Apéndice A) en el cuál especifica que el canal por donde desea recibir que en este caso es el
FrClnt, el apuntador de la cadena en donde debe dejar los datos recibidos, sCmd y la longitud de
los datos esperados TRAMA_LEN. Esta instrucción es bloqueante y regresa el control a Server
hasta que se ha recibido una trama de la longitud especificada; sí se requiere que la recepción sea
no bloqueante se debe usar un mecanismo como el que se explica en el punto 6.2.4. La cadena de
caracteres recibida es un PDU MMS empacado por lo que hay que desempacarlo para poder
trabajarlo adecuadamente; esto lo lleva a cabo la función UnpackTrama, la cual deja el PDU
obtenido en la estructura de tipo MMS llamada SMA!eaf Esta es una recepción típica de un PDU
MMS.
1•••••••••••••••••••••••••••••••••••••••••••••••************ 11
••••••••••••••••••/
. while (TRUE) {
Chanl n(FrClnt,sCmd , TRAMA_LEN);
unpackTrama (&SMAleaf,eCmd);
MMSDecod(sCmd,l);
Primi tiva•SMAleaf.Primit i ve;
switch(Primitiva){
case LOGOUT_Indication :
SMAleaf.Primitive•LOGOUT Confirm;
Rdld(&(SMAleaf . Id),l); - /•leo registro i<I•/
PackTrama(&SMAleaf,sCmd);
ChanOut(ToClnt,sCmd,TRAMA_LEN);
break;
}
¡ ... LOFF ***/
La función para empacar un PDU MMS a una cadena plana, y su función complementaria, se
pueden consultar en el archivo Mmspdutr.h para los detalles. Es conveniente mencionar que para
el manejo de las cadenas que representan PDUs MMS no es recomendable usar las funciones
para manejo de cadenas ordinarias incluidas en la librería string.h, ya que al empacar un PDU
puede ser que los caracteres obtenidos sean de control, e inclusive el que indica terminador de
cadena. El archivo Mmspdutr.h se incluye en el Apéndice C al final de este documento
Los canales implementados en los transputers son de tipo síncrono (refiérase a la sección 3.3), es
decir, el proceso que desea transmitir a través de un canal, tiene que esperar en tal instrucción
hasta que exista un proceso que intente recibir datos de este mismo canal; esto es debido a que no
cuentan con una estructura para almacenar mensajes y por ello ~.e les conoce como canales de
longitud cero. Existe un segundo tipo de canales, los del tipo asíncrono, los cuales si cuentan con
una estructura de almacenamiento temporal conocida como buffer:, el número de mensajes que se
pueden almacenar (longitud del canal) determina el número de transmisiones que puede quedar
pendientes antes de bloquear al proceso transmisor.
Uno de los requerimientos que se detectaron en la validación füe la necesidad de contar con
canales con longitud mayor o igual a tres para evitar deadlocks por falta de recursos; este
problema se resolvió sustituyendo dos procesos cooperativos del tipo Productor-Consumidor, un
arreglo compartido y la filosofia de la zona crítica en lugar de un canal de recepción simple [3].
Estos procesos se muestran la Figura 63(8).
150
- Canal de Longitud O
/
~----p-~~~/~~~----~~~---~
(a)
r----------,1
I Canal de Longitud= size(Buffer)
A 1
1 1
1 Rx Tx
1
1
1
1
I Buffer I
1_ _ _ _ _ _ _ _ _ _ _1
( b)
Si el proceso A desea transmitir el mensaje "M" al proceso B de manera asíncrona, es decir, sin
tener que esperar a que B esté disponible para recibir, entonces debe hacerlo a través de la
implementación del canal de longitud mayor a O; por lo que A envía "M" al proceso receptor de
B "Rx" y no a B directamente. El proceso receptor de B, lo guarda en un buffer que comparte con
el proceso transmisor "Tx", cuya tarea es vaciar tal buffer y enviar el contenido a B. El diagrama
detallado de la operación de estos procesos se puede apreciar en d esquema de la Figura 64.
151
Buffe~1ndex).Usado=FALSE
i=(1+ 1)%LEN_CHAN
Buffe~index).Usado=FALSE
i=(i+1 )%LEN_CHAN
Al inicio, Rx verifica si el elemento al que apunta la variable loe.al index está disponible; si no es
así significa que el comando almacenado en ese elemento no ha sido transmitido por Tx por lo
que se duerme por un intervalo predefinido después del cuál verifica nuevamente. Por el
contrario, si el elemento está disponible entonces Rx espera hasta que A le envía un mensaje y lo
guarda en Buffer marcando Usado como verdadero; después Rx verifica si el tipo de comando
que acaba de escribir es del tipo "FIN", si es el caso avisa a Tx que es el último de los mensajes
cambiando bKeepGoing a falso; si el comando no es "FIN", Rx incrementa su apuntador a Buffer
y regresa al punto inicial.
El proceso Tx, por su parte, inicia analizando si el comando al que apunta su apuntador a Buffer
está usado; si no lo está espera a que Rx escriba un mensaje válido en tal posición durmiéndose
por un tiempo limitado. Si el registro está marcado como usado, significa que el comando
referido debe ser transmitido y Tx lo hace siempre y cuando el mensaje no sea del tipo "FIN",
por que si es así, tiene que abandonar su ejecución. En la transmisión del mensaje, Tx TIENE que
esperar a que B esté disponible para recibir el mensaje y se bloquea hasta que así sea; mientras
tanto Rx puede seguir recibiendo mensajes de A sin que éste último se bloquee como
consecuencia de la indisponibilidad de B siempre y cuando haya espacio en Buffer. Una vez
152
transmitido el mensaje "M" a B, Tx libera el registro ocupado por "M", marcando la bandera de
Usado como falso. Tx incrementa su apuntador y vuelve a su estado inicial. Si detecta que debe
detener su ejecución (bKeepGoing=F ALSE), entonces se dirige al siguiente ciclo el cual esta
marcado en la Figura 64 con la etiqueta "cont". Este pequeño bucle funciona de manera similar al
primero y está incluido para evitar que se quede un mensaje en Bu,ffer sin que sea transmitido al
proceso B.
Esta emulación de canal de longitud mayor a cero es muy útil y, como se aprecia en la Figura 56,
es utilizada seis veces en la implementación del protocolo MMS, una para cada canal de
recepción de los procesos principales. El código de estos dos procesos esta incluido en el punto
11.7.
En distintas partes del código del modelo de validación para las máquinas del protocolo MMS del
Cliente y del Servidor se requiere que el proceso involucrado sea capaz de escuchar
simultáneamente del canal conectado al Servidor y del conectado al Cliente y, una vez detectado
un mensaje en alguno de ellos, se tiene que llevar a cabo una mtina de servicio de acuerdo al
canal de donde proviene el mensaje y al tipo de éste; para implementar esto en código C paralelo
se requirió del uso de las instrucciones ProcTimer y ProcWait (Ver Apéndice A).
A manera de ejemplo, se toma un fragmento del código del proceso Smmspm del modelo de
validación Promela en que la máquina del servidor se encuentra StandA/one, es decir, el servidor
se ha registrado y está lista para que un cliente lo haga; en esta situación pueden suceder dos
acontecimientos, por un lado se puede recibir un mensaje del servidor en el que requiera terminar
su ciclo de vida RequerimientoLogout y por otro, el cliente puede enviar una primitiva
IndicaciónLogin; cada mensaje es temporalmente independiente del otro, por lo que Smmspm
debe estar monitoreando ambas posibilidades sin ninguna prioridad. En Promela, esto es
entendido por el validador al incluir las dos alternativas como enunciados dentro de una
instrucción do-od marcado con la etiqueta "end3" de la Figura 65. El proceso se detendrá en esta
línea hasta que alguna de los dos enunciados se vuelva ejecutable, es decir, cuando se reciba
alguno de los dos mensajes posibles.
cnd.1: do 1
•s•1
i•s•,1
::fro111_linkl nj'!M Liln. XXXPL>U., 1. ,2. ,.1. ,4 .,.
to _link[n]!M Li( ·r_ XXXPDU,x l .x2.,.'. ,4:goto cndl:
::from_ upper[n]'!M LoRq_XXXPDU., l .x2.x3.x4->
1
•s•1
1•s•.1
lo_upper[n]!Ml oCf_XXXPDU,, l .,2.x3,x4:golo cnd44: 1•s•1
t•S•i
,...
od;
/••• SALONE ... /
•••¡
1••••···························································•1
1•••············•••*············································,~··············1
/ .. • ESTADO DEL PROCESO: SALONE (end3)
int endJ(Channel •frClnt.Channel •ToClnt.Channel •rrServer,Channel •ToSer,..er) 1
!Trama sCmd:aleafSMAleaf;inl ch:
while(TRUE)i
ch=l'rocAIJ(FrServer.FrCln1,NULL);
switch (ch) 1
case O:
Chanln(FrServer.sC111d.TRAMA_LEN);
l/11packTra111a(&SMAleaf,sC111d):
MMSDecod(sC111d.ch);
i í( SM A lcaf Primitive==LOGOIIT__ Requesl) 1
SMAleaf.Primilive=LOGOUT _Conr.n11;
l'ackTra111a(&SMAleaf,sC111d):
Chanüul(ToServer.sCmd, TRAMA_ LEN):
end44(ToServer.ToClnt); /•golo end44•/
rclum(FALSE); 1
break;
tase 1:
Chanln(FrClnt.sC111d.TRAMA_LEN);
UnpackTrama(&SMAleaf.sCmd);
MMSDecod(sC111d.ch):
i f(SM Aleaf.Primitive==LOGIN _lndication) 1
SMAleaf.Primitive=LOGIN_Continn;
Rdld(&(SMAleaf.ld),1 ); /•leo registro id•/
PackTrama(&SMAleaf.sCmd);
Chanüut(ToClnl.sCmd.TRAMA_LEN);
relum(TRUE); /•gato cnd2•/
l>reak; : 11
1
l ___ _
'"' ........................................................................... .................
SALONE ... /
~ /
Como se mencionó en el punto 6.1.3, para esta implementación se requirió de las interfaces
Occam-C tipo 2 y 3 (refiérase al punto 3.3.9) para lanzar los procesos principales de los
ambientes Servidor MMS y Cliente MMS respectivamente.
La interfaz root_ o.ce es del tipo 2, ya que se requiere que algunos de los procesos que se crean
dentro del ambiente Servidor MMS tengan comunicación con el host. Es el caso del proceso
Feeder, el cual abre un archivo del host, lo lee y lo cierra; Killer también requiere de
comunicación con el host ya que se función estaba basada en el poleo del teclado; por último,
Monitor requiere escribir en pantalla los mensajes enviados p,Jr los procesos supervisados.
Además de estar comunicados hacia el host estos procesos interactuan con otros que se pueden
encontrar en procesadores distintos al suyo.
La interfaz client_o.occ es del tipo 3, ya que los procesos del ambiente cliente se comunican con
procesos que residen en otros procesadores pero no se requiere una comunicación hacia el host.
El código de ambas interfaces es muy sencillo, ya que su tarea se reduce a instanciar a los
procesos cliente y root.c, los cuales son los que realmente realizan la administración de los
recursos; este código se incluye en el Apéndice C al final de este documento.
155
7 CONCLUSIONES.
La Ciencia de la Computación también puede ayudar a que la operación de la celda pueda ser
adaptada rápidamente a nuevos requerimientos de la producción y además, puede reasignar las
tareas de cada elemento de la celda en caso de que alguno de estos falle; estos dos aspectos hacen
que la celda sea flexible y tolerante a fallas; esto se logra ejecutando procesos concurrentes y
comunicantes para el control de la operación de la celda.
Una plataforma que permite que una celda tenga las características mencionadas es el transputer.
Este es un microprocesador de alto rendimiento que soporta el procesamiento paralelo en el
mismo circuito integrado ya que cuentan con un mecanismo de asignación de CPU altamente
eficiente para los procesos que corren en un mismo transputer; el tiempo de cambio de contexto
es menor a un microsegundo. Si los transputers son interconectados a través de sus enlaces, el
procesamiento paralelo se puede llevar a cabo en distintos procesadores; la sincronización de
tareas y el intercambio de información se implementa a través de los enlaces. Existen varias
tarjetas madres de transputers que permiten la creación de redes de estos; una de ellas es la tarjeta
IMS B008 que cuenta con el C004, un múltiple interruptor digital controlado por software.
Además la comunicación de la celda debe estar orientada a los estándares internacionales para
que la integración de nuevos elementos a la celda sea simple y de bajo costo; se debe evitar en la
medida de lo posible las soluciones propietarias. MAP es el estándar en materia de la
comunicación en las aplicaciones de manufactura y MiniMAP específicamente en las celdas; este
último es un modelo de tres capas (aplicación, enlace y fisica) cuyo objetivo es trabajar con los
mensajes más simples para hacer la comunicación más eficiente. MiniMAP establece reglas para
las tres capas pero su importancia radica en la especificación de los mensajes de manufactura
MMS el cual determinar las reglas y formatos validos para los mensajes intercambiados en una
celda de manufactura para la generalidad de los elementos de una celda; aunado a este estándar
existen otras reglas llamadas estándares asociados MMS que son aplicables según la naturaleza
del dispositivo de manufactura: para robots, para máquinas de control numérico y para
controladores programables.
Una fase muy importante en la implantación del protocolo es la verificación de que éste cumpla
con los objetivos para los que fue diseñado; a esto se le conoce como validación. La validación y
el diseño del protocolo no son dos etapas independientes, sino que se deben llevar a cabo a la par,
diseñar, validar, volver a diseñar y a validar y así sucesivamente hasta que el protocolo satisfaga
los requerimientos. Existen dos tipos de validación, la exhaustiva y la no-exhaustiva; con la
primera todas las secuencias del protocolo posibles son sometidas a verificación, la segunda sólo
prueba algunas secuencias, escogidas según una técnica y es muy útil cuando los estados del
protocolo son muchos y la verificación exhaustiva requeriría demasiado poder computacional.
La validación permite garantizar que el protocolo este completameme especificado, sin embargo
una verificación manual sería muy lenta y sujeta a errores humanos, :Jor lo que se hace uso de las
herramientas de validación. Spin es un software muy usado para la validación de protocolos y es
de dominio público. Esta herramienta puede realizar validaciones exhaustivas y no exhaustivas,
probando propiedades diversas como: estados finales inaceptables, ciclos erróneos, aserciones,
invariantes del sistema y requerimientos temporales. La validación del protocolo se hace sobre un
modelo formal, se debe asegurar que la implementación sea una equivalencia total a este modelo.
157
El protocolo diseñado en este trabajo respeta las normas establecidas por MMS y su
implementación fue realizada haciendo uso de las características técnicas de los transputers y sus
redes. Ha sido verificado usando la validación no exhaustiva para verificar la ausencia de estados
finales inaceptables, ausencia de ciclos erróneos y el mantenimiento de las invariantes del
sistema, usando la herramienta Xspin.
• Este software está completo para que los procesos participantes lo usen como un mecanismo
de comunicación; Sin embargo, es conveniente remarcar que esta implementación debe ser
generalizada si se requiere que un proceso servidor tenga más de un cliente en forma
simultánea.
8 BIBLIOGRAFIA.
9 APÉNDICEA
Los canales son un medio de comunicación que sirven para transj:erir datos de un proceso a otro o
para sincronizar las acciones entre procesos paralelos. Si un proceso necesita esperar a que otro
alcance un estado en especial un canal es de suma utilidad; Si un proceso tiene un acceso
exclusivo a un recurso particular y actúa como servidor de otros procesos, los canales pueden
servirle como un mecanismo de atención a peticiones.
Cualquier tipo de dato se puede pasar a través de un canal per,, el usuario debe asegurar que los
procesos comunicantes entiendan el mismo protocolo para q~e los datos sean interpretados
correctamente. Los canales sólo operan en una dirección; 1011 procesos que requieren enviarse
información en ambos sentidos, requieren de dos canales.
Los canales entre procesadores son implementados sobre los er..laces; los canales entre procesos
que corren en un mismo transputer son conocidos como canales soft; los enlaces de los transputers
también son conocidos como canales hard. Los canales pueden ser declarados como variables de
cualquier tipo pero para usarse deben inicializarse correctamente; esto se hace automáticamente
para los canales que son creados por el configurador y para los alojados por un programa C se
debe hacer explícitamente usando una de las siguientes funcione3:
La función ChanAlloc aloja el espacio para un canal e inicializa el canal antes de regresar. Si
el canal ya ha sido alojado en memoria, puede ser inicializado =on la instrucción Chaninit.
El valor inicial de un canal es una constante llamada NotProcE·ss_p, que se define en channel. h.;
este valor indica que el no existe proceso alguno esperando en el canal para escribir ni para
leer. Si un canal se debe pasar como parAmetro a dos procesos entonces se debe inicializar antes
de pasarlo y no dejar que uno de los procesos sea el que lo haga.
Cada una de las funciones de salida representa una sola comunicación; el proceso no continuará
hasta que la transferencia esté completa. Estas funciones tienen sus complementarias para la
lectura de valores de un canal, las cuales son:
Pero debido a que existen muchos casos en los que un procese debe escuchar de varios canales y
desea saber cual de ellos tiene datos listos, se agregan lae. siguientes funciones que ayudan a
determinar que canal alterno está listo para ser leido:
Todas estas funciones utilizan como parAmetros una lista de apuntadores a canal ter111inadas por un
apuntador a NULL; ProcAlt y ProcAltSkip regresan el índice (que e,mpieza en cero) de la lista para
indicar que canal está listo para la transferencia de datos.
El siguiente es un ejemplo simple de un servidor que convierte ,i mayúsculas y regresa los datos
al cliente que envió la solicitud.
p = p;
/•bucle infinito, este proceso nunca ter111ina•/
for (;;)
{
/*Espera por datos de entrada*/
i = ProcAltList (ins);
ProcAl t y ProcAl tList son funciones bloqueantes y regresan hasta que uno de los canales este
listo. Las variantes de estas funciones ProcSkipAl t y ProcSicipAl tList, pueden usarse para
verificar si hay o no un canal listo; regresan el valor (-1) si ninguno de ellos contiene datos,
de otra manera trabajan exactamente como ProcAlt y ProcAltList, respectivamente.
Por otro lado, los transputers cuentan con dos relojes integrados en el mismo chip, uno usado
para los procesos de alta prioridad y uno para los de baja; el de baja velocidad corre a una
razón de 15625 pulsaciones por segundo, el da alta a un millón de, pulsaciones por segundo. Cada
proceso lee el reloj correspondiente según sea su prioridad.
un proceso puede esperara por cierto tiempo (medido en pulsaciones por segundo) , usando las
siguientes funciones:
Ambas funciones esperan por un período después del cual regresan: ProcAfter espera hasta que se
alcance la lectura absoluta del tiempo en el reloj. Si el tiempo indicado no es mayor que el
actual, la función regresa inmediatamente. ProcWait suspende el proceso hasta que ha transcurrido
el intervalo indicado, es decir, retrasa la ejecución por un número especifico de pulsaciones. Si
se especifica un tiempo negativo, la función regresa inmediatament<!.
Existe dos funciones que per,niten que los procesos selecciones ·~n canal de recepción que este
listo dentro de un tiempo especifico. Si ningún canal se hace disponible durante este tiempo,
entonces la función regresa y el proceso sigue con su ejecución. EBtas funciones son:
Estas funciones regresan ( -1) si el tiempo expira antes de que haya datos disponibles en alguno
de los canales incluidos en la lista.
162
10 APÉNDICE B
/••• ***/
/*** MMS_Val ***/
/*** ***/
#define TRUE 1
#define FALSE O
#define QSZ 3 /•tamanio del canal entre app y maq del proto */
#define QSZ2 3 /•tamanio del canal entre maquinas del protocolo*/
rntype={
IdleConn,Callinginit,Calledinit,CallingConc,CalledConc,Associated,
Idle,W_Conf,W_Resp,
MAsRq_initiate_RequestPDU,MAsRq_initiate_XXXPDU,
MAsin initiate RequestPDU,MAsin initiate XXXPDU,MAsin reject PDU,
MAsRs-initiate-ResponsePDU,MAsRs initiate XXXPDU,MAsRs initiate ~rrorPDU,
MAsCf=initiate=ResponsePDU,MAsCf=initiate=XXXPDU,MAsCf=initiate=~rrorPDU,MAsCf_reject_PDU,
MRlRq_conclude_RequestPDU,MRlRq_conclude_XXXPDU,
MRlin_conclude_RequestPDU,MRlin_conclude_XXXPDU,MRlin_reject_PDU,
MRlRs conclude ResponsePDU,MRlRe conclude XXXPDU,MRlRe conclude ~rrorPDU,
MR1Cf=conclude=ReeponeePDU,MR1Cf=conclude=XXXPDU,MR1Cf=conclude=:~rrorPDU,MR1Cf_reject_PDU,
MCfRq confinned RequestPDU,MCfRq confirrned XXXPDU,
MCfin=confirrned=RequeetPDU,MCfin=confinned=XXXPDU,MCfin_reject_PDU,
MCfRs_confinned_ResponsePDU,MCfRe_confinned_XXXPDU,MCfRe_confinn,!d_ErrorPDU,
MCfCf_confinned_ResponsePDU,MCfCf_confinned_XXXPDU,MCfCf_confinn,!d_ErrorPDU,MCfCf_reject_PDU,
MUfRq unconfinned PDU,MUfRq unconfinned XXXPDU,
MUfin=unconfirrned=PDU,MUfin=unconfinned=XXXPDU,MUfin_reject_PDU,
MAbin abort PDU,MAbin abort XXXPDU,
MLiRq=XXXPDU,MLiin_XXXPDU,MLiCf_XXXPDU,MLiCf_ErrPDU,
MLoRq_XXXPDU,MLoin_XXXPDU,MLoCf_XXXPDU
#include "cmrnepnn.pro"
#include "smmspnn.pro"
#include "cupper.pro"
#include "eupper.pro"
/• Para chechar las invariantes del sistema:
llinclude "inv sysl.pro"
*/ -
/* Para checar el progreso en el Login•/
llinclude "nev_lil.pro"
init
atomic{
to_link[O)=from_link[l);
to_link[l)=from_link[O);
run smmspm(O); run cmmsprn(l);
run supper(O); run cupper(l);
/* run monitor(); •/
}
163
10.2 CUPPER.PRO
/••• ***/
/*** CUPPER ***/
/••• •••/
proctype cupper(bit n)
{
/******************************************************************************/
/••• Variables •••/
/******************************************************************************/
byte dummy; /*variable dummy•/
byte xl; /*otra variable dummy*/
byte x2; /•otra variable dummy*/
byte x3; /*otra variable dummy•/
byte x4; /•otra variable dummy*/
byte j ;
byte k; /•assid local •/
byte l; /*assid remota •/
byte Associa[MC]
byte q; /*apuntador a una asociacion a guardar•/
byte p; /•apuntador a una asociacion a concluir*/
byte PetConf; /*apuntador a una asociacion disponible para enviar un ser conf*/
byte pl; /*apuntador a una asociacion a concluir•/
byte count; /•control para dar de baja asociaciones*/
byte AsocCons; /•control para dar de baja asociaciones•/
byte Nevers; /•valor invalido paras•/
1····························································•·t•••·············1
/••• Inicializacion ***/
1··························································•••t••••············1
q=O;
Nevers=255;
do
:(q<MC)->
Associa[q]=Nevers;
q=q+l
: (q>=MC) ->
break;
od;
q=O;
count=O;
/*** Inicializacion ***/
1··············································································1
1··············································································1
/••• Login ***/
/******************************************************************************/
from_upper[n] !MLiRq_XXXPDU,dummy,dummy,dummy,dummy->
do
: :to_upper[n]?MLiCf_XXXPDU,xl,x2,x3,x4->goto cont;
: :to_upper[n]?MLiCf_ErrPDU,xl,x2,x3,x4->goto fin;
od;
/••• Login ***/
/************************************************************i'*****************/
/************************************************************i'*****************/
/••• Ciclo principal ***/
/************************************************************"*****************/
cont: do
/•requiero asociacion•/
:from_upper[n] !MAsRq_initiate_RequestPDU,dummy,dummy,dummy,dummy->
do
:to_upper[n]?MAsCf_initiate_ResponsePDU,xl,x2,x3,x4->
count=count+l;
AsocCons=AsocCons+l;
Associa[q]=xl;
q=(q+l)%MC;
break;
:to upper[n]?MAsCf initiate ErrorPDU,xl,x2,x3,x4->break;
:to=upper[n]?MAsCf=reject_PDU,xl,x2,x3,x4->break;
164
od;
/•enviar servicions confirmados•/
: : (count>O) ->
j=PetConf;
do
: : (j<MC && Associa[j] !=Nevera)->
PetConf=j;
break;
: : (j<MC && Associa[jl==Nevers)->
j= (j+l) \MC;
od;
pl=Associa[PetConf];
from_upper[n] !MCfRq_confirmed_RequestPDU,pl,x2,x3,x4->
if
: :to_upper[n]?MCfCf_confirmed_ResponsePDU,xl,x2,x3,x4;
: :to_upper[n]?MCfCf_confirmed_ErrorPDU,xl,x2,x3,x4;
: :to_upper[n]?MCfCf_reject_PDU,xl,x2,x3,x4;
fi;
do
: :PetConf=(PetConf+l)\MC->break;
: :PetConf=PetConf->break;
od;
/•enviar servicions no confirmados•/
: : (count>O) ->
j=PetConf;
do
: : (j<MC && Associa[j] !=Nevera)->
PetConf=j;
break;
: : (j<MC && Associa[jl==Nevers)->
j=(j+l)IMC;
od;
pl=Associa[PetConf];
from_upper[n] !MUfRq_unconfirmed_PDU,pl,x2,x3,x4->
do
: :PetConf=(PetConf+l)\MC->break;
: :PetConf=PetConf->break;
od;
10.3 CMMSPRM.PRO
/*** ***/
/*** CMMSPM ***/
/*** •••/
#define MC 4 /*No. maximo de conexiones •/
#define MR 1 /•No.max de pet.simultaneas x conex. •/
#define MA 40 /*No. maximo de asociaciones •/
#define MI 200 /•No. maximo del id de la peticion •/
byte NCD_CM; /•numero de conexiones disponibles •/
proctype cmmspm(bit n)
{
/****************••····························································!
/••• Variables •••/
1··············································································1
bool bExiste; /*indica si assid esta registrado •/
byte NRD[MC]; /*# de petciones disp. por conex. */
byte NID [MC]; /*# de indicaciones disp. por conex.•/
byte q; /*apuntador a conexion del timer */
byte i· /*apuntador a conexion libre •/
byte k· /•assid local */
byte 1; /•assid remota •/
byte kl; /•reqid local */
byte 11; /•indid remota */
byte s· /•ase disponible */
byte t; /*id rqt proximo disponible */
byte U; /*id ind proximo disponible */
byte j; /•indice */
byte xl; /•variable dummy */
byte x2; /•variable dummy •/
byte x3; /•variable dummy */
byte x4; /•variable dummy •/
byte Ass!d[MC]; /*buffer para guardar #aes local */
byte AssidRmt[MC]; /*buffer para guardar #aes remota */
byte State[MC]; /*buffer para guardar el edo •/
bool InUse[MC]; /*buffer para guardar #aes remota •/
byte Rqtid[MC]; /•buffer para guardar #pet local */
byte RqtRmtid [MC] ; /•buffer para guardar #pet remota •/
byte Indid[MC]; /*buffer para guardar #ind rmt •/
byte RqtState[MC]; /•buffer para guardar #pet local */
byte IndState[MC]; /•buffer para guardar #pet local */
byte RqtinUse[MC]; /*buffer para guardar #ind rmt •/
byte IndinUse[MC]; /*buffer para guardar #ind rmt */
/• byte NumSerUnC; Numero de Pet de Serv. No COnf•/
/******************************************************************************/
/••• Inicializacion de Variables •••/
/******************************************************************************/
/* j=O;
do
: : (j<MC) ->atomic{
InUse[j]=FALSE;
NRD[j]=MR;
NID[j]=MR;
RgtinUse[j]=FALSE;
IndinUse[j)=FALSE;
j=j+l;
}
: : (j>=MC)->
break;
od;*/
NCD_CM=MC;
S= (13+n*ll);
NRD=MR;
NID=MR;
RgtinUse=FALSE;
IndinUse=FALSE;
/*** INICIA ***/
/*** ***/
/***********************************************************tr******************/
166
1··············································································1
1··············································································1
1··············································································1
/ * • *- ESTADO DEL PROCESO: BEGIN ** */
/*** •••/
from_upper[n]?MLiRq_XXXPDU,xl,x2,x3,x4-> /•c•/
to_link[n] !MLiin_XXXPDU,xl,x2,x3,x4;goto chk; /•c•/
/•••
/••.
BEGIN
...
***/
/******************************************************************************/
/
1··············································································1
1··············································································1
1·····························································~················1
/•
chk:
..
/••• ESTADO DEL PROCESO: CHK
do
...
•••/
/
/****************************************************•••······,~················1
1······························································~················1
/••• ESTADO DEL PROCESO: GROUP
/••.
end2: do
...
•••/
/
/******************************************************************************/
/••• Peticion de Asociacion •••/
!··············································································!
/**Pet. de Asoc, loe. PDU correcto••/
:from_upper[n]?MAsRq_initiate_RequestPDU,xl,x2,x3,x4->
if
: (NCD CM>O)->
atomic{
j=O;
do
: (j<MC && InUse[j]==TRUE)->
j=j+l;
: ( j <MC && InUse [j] ! aTRUE) - >
i=j;
break;
::(j>=MC)->
break;
od;
);
NCD CM=NCD CM-1;
InUse[i]•TRUE;
Assid[iJ•s;
AssidRmt[i]=O;
State[i]=Callinglnit;
to_link[n] !MAsln_initiate_RequestPDU,xl,s,x3,x4;
B=(B+l)%MA
: (NCD_CM<=O) ->
to upper[n] !MAsCf initiate ErrorPDU,xl,x2,x3,x4;
fi - - -
1································*·············································1
/••• Indicacion de Asociacion •••/
167
/******************************************************************************/
1··············································································1
/*** Respuesta de Asociacion ***/
1·····························································-·················1
1·····························································-·················1
/*** Confirmacion de Asociacion ***/
/*************************************************************il****************/
/**Cnf. de Asoc. rmt. PDU correcto Afirmativa**/
: :from_link[n]?MAsCf_initiate_ResponsePDU,k,l,x3,x4 ->
bExiste=FALSE;
j=O;
atomic{
do
::(j<MC && (InUse[j]!=TRUE 11 Assid[j]!=k) )->
j=j+l;
: : ( j <MC && InUse [j l ==TRUE && Assid [j l ==k) - >
bExiste=TRUE;
i=j;
break;
: : (j>=MC) ->break;
od;
};
if
: (bExiste==TRUE && State[i)==Callinginit)->
State[i]=Associated;
AssidRmt[i)=l;
to_upper[n) !MAsCf_initiate_ResponsePDU,k,l,x3,x4;
: : (bExiste==TRUE && State[i) !=Callinginit)->skip;
: : (bExiste!=TRUE)->
to link[n) !MAbin abort PDU,l,k,x3,x4;
fi - - -
/******************************************************************************/
/*** Peticion de Liberacion ***/
1··············································································1
/**Pet. de Libe. loe. PDU correcto**/
: :from_upper[n]?MR1Rq_conclude_RequeetPDU,k,l,x3,x4 ->
bExiste=FALSE;
j=O;
atomic{
do
::(j<MC && (InUee[j]!=TRUE 11 Aeeid[j)l=k) )->
j =j +l;
: (j<MC && InUee[j)=•TRUE && Assid[j)=~k)->
bExiste=TRUE;
i=j;
break;
.. (j>=MC) ->break;
od;
168
);
if
: : (bExiste==TRUE && State [ il ==Associated) - >
State[i]=CallingConc;
l=AssldRmt [i];
to link[n] !MR!In conclude RequestPDU,l,k,x3,x4;
(bExiste==TRUE && State[il==CallingConc)->skip;
(bExiste==TRUE && State[i] !=Associated && State[i] !=CallingC,:mc)->
to_upper[n] !MR1Cf_conclude_ErrorPDU,k,l,x3,x4;
: : (bExiste!=TRUE) ->
to_upper[n] !MR1Cf_conclude_ResponsePDU,k,l,x3,x4;
fi
/******************************************************************************/
/••• Indicacion de Liberacion •••/
/******************************************************************************/
/******************************************************************************/
/••• Respuesta de Liberacion •••/
1··············································································1
/******************************************************************************/
/••• Confirmacion de Liberacion ***/
/******************************************************************************/
/**Cnfs. de Libe. rmt. PDU correcto Afirmativo••/
: :from_link[n]?MR1Cf_conclude_ResponsePDU,k,l,x3,x4->
bExiste=FALSE;
j=O;
atomic{
do
: : (j<MC && (InUse[j] !=TRUE 11 Assid[j] !=k) )->
j=j+l;
: (j<MC && InUse[j]••TRUE && Assid[j]••k)->
bExiste•TRUE;
i=j;
break;
.. (j>•MC)->break;
od;
);
if
: : (bExiste••TRUE && State[il••CallingCone)->
l=AssidRmt[il;
InUse[i]•FALSE;
State[i]•IdleConn;
NCD CM•NCD CM+l;
to_Üpper[n]IMR1Ct_conclude_ReaponaePOU,k,l,xJ,x4;
: : (bExiste--TRUE && State [i] l •CallingCone) - >
InUse[i]·FALSE;
State[i]•IdleConn;
NCD CM•NCD CM+l;
: : (bExistel•TRUE)->Skip;
fi
/•**************************************************************1:**************/
/••• Peticion de Servicio Confirmado ***/
/***************************************************************"**************/
/••Pet. de s.conf. loe. PDU correcto**/
:from_upper[n]?MCfRq_confirmed_RequestPDU,k,l,x3,x4 ->
bExiste=FALSE;
j =0;
atomic{
do
:(j<MC && (InUse[j]!=TRUE 11 Assid[j)!=k 11 State[j)!=Associated))->
j=j+l;
: (j<MC && InUse[j]==TRUE && Assid[j)==k && State[jl==Associated)->
bExiste=TRUE;
i=j;
break;
(j>=MC)->break;
od;
};
if
.. (bExiste==TRUE && NRD[i]>O)->
RqtinUse[i]=TRUE;
NRD[i]=NRD[i]-1;
Rqtid[i]=t;
RqtState[i)=W_Conf;
l=AssidRmt [i);
to_link[n] !MCfin_confirmed_RequestPDU,l,k,x3,t;
t=(t+l)%MI;
: : (bExiste!=TRUE 11 NRD(i]<=O)->
to upper[n) !MCfCf confirmed ErrorPDU,k,l,x3,x4;
fi - - -
/**************************************************************•'***************/
/••• Confirmacion de Servicio Confirmado ***/
/**************************************************************"***************/
/••cnf. de S.Conf. rmt. PDU correcto Afirmativo**/
: :from_link[n]?MCfCf_confirmed_ResponsePDU,k,l,kl,11 ->
bExiste=FALSE;
j =0;
atomic{
do
::(j<MC && (InUse[j)!=TRUE 11 Assid[j)!=k 11 RqtlnUse[i)!=TRUE 11 Rqtid[i)!=kl))->
j =j +l;
: : ( j <MC && InUse [j) ==TRUE && Assld [j) ==k && RqtinUse [i) ==TRIJE && Rqtld [i) =~kl) - >
bExiste=TRUE;
i=j;
break;
(j>=MC)->break;
od;
};
if
: (bExiste==TRUE && RqtState[i)==W_Conf)->
RqtinUse[i)=FALSE;
NRD[i)=NRD[i)+l;
RqtState[i)=Idle;
to upper[n) !MCfCf confirmed ResponsePDU,k,l,kl,11;
: : (bExiste!=TRUE 11-RqtState[i) !=W_Conf)->skip;
fi
/*******************************************************•••••••·t•••••••••••••••/
/*** Peticion de Servicio Sin Confirmacion •••/
/************************************************************••·t••·············/
/**Pet. de s.unconf. loe. PDU correcto••/
:from_upper[n]?MUfRq_unconfirmed_PDU,k,l,x3,x4->
bExiste=FALSE;
j=O;
atomic(
do
( j <MC && ( InUse [j J ! =TRUE 11 Assid [j J ! =k 11 State [j J ! =Associated) l - >
j=j+l;
(j<MC && InUse[j]==TRUE && Assid(jl==k && State[jl==Associated)->
bExiste=TRUE;
i=j;
break;
: (j >=MC) - >break;
od;
);
if
(bExiste==TRUE)->
l=AssidRmt ( i J ;
to link [n] ! MUfln unconfirmed PDU, xl, x2, x3, x4;
(bE~iste!=TRUE)->;kip;
fi
od;
/*** GROUP ***/
/*** •••/
/***********************************************************"******************/
/***********************************************************)'******************/
/***********************************************************"t******************/
/********************************************************•••·t••••··············/
/••• ESTADO DEL PROCESO: SALONE ***/
/•.. • • */
end3: do
, :from_upper[n)?MLoRq_XXXPDU,xl,x2,x3,x4-> /•c•/
to upper(n) !MLoCf XXXPDU,xl,x2,x3,x4;goto end44; /*C*/
:from_upper[n]?MAeRq_initiate_RequeetPDU,xl,x2,x3,x4->
to_upper[n) !MAsCf initiate_ErrorPDU,xl,x2,x3,x4;
od;
171
/••• SALONE •••/
/••• ••• /
/*************************************************************1r****************/
/*************************************************************,'****************/
/*************************************************************1t****************/
1·····························································'.~················1
/••• ESTADO DEL PROCESO: LOFF ***/
/ •.. •• */
ExpLoc: do
: :from_link[n]?MLoln_XXXPDU,xl,x2,x3,x4-> /*C*/
to_link[n] !MLoCf_XXXPDU,xl,x2,x3,x4; /•e•/
: :from_link[n]?MLoCf_XXXPDU,xl,x2,x3,x4-> /•e•/
to_upper[n] !MLoCf_XXXPDU,xl,x2,x3,x4;goto end44; /*C*/
od;
/••• LOFF •••/
/*** •••/
/******************************************************************************/
/******************************************************************************/
1··············································································1
/******************************************************************************/
/••• Rutina de Terminacion Remota •••/
/ •.. • • *I
ExpRmt: q=O;
do /•limpio mis tablas•/
: (q<MC && InUse[q]==TRUE && State[q]z=Callinginit)->
InUse[q]=FALSE;
k=Assld[q);
State[q]=IdleConn;
NCD CM=NCD CM+l;
to_upper[n)!MAsCf_initiate_ErrorPDU,k,x2,x3,x4;
q=q+l;
: (q<MC && InUse[ql==TRUE && State[q)=•CallingConc)->
InUse[q]=FALSE;
k=Assld[q];
l=AssldRmt[q];
State[q]=IdleConn;
NCD_CM=NCD_CM+l;
to_upper[n] !MR1Cf_conclude_ResponsePDU,k,l,x3,x4;
q=q+l;
: (q<MC && InUse[q)==TRUE && State[q)=•Associated && RqtlnUse(q]=•TRUE && RqtState[q]==W_Conf)-
RqtlnUse[i]=FALSE;
RqtState[i]=Idle;
k=Ass!d[q];
l=AssidRmt[q];
kl=Rqtld[i];
NRD[i]=NRD[i]+l;
to_upper[n) IMCfCf_confirmed_ErrorPDU,k,l,kl,x4;
q=q+l;
: (q<MC && InUse[q]==TRUE && State[ql••Associated && IndinUse[il••TRUE && IndState[il==W_Resp)-
IndinUse[i]•FALSE;
IndState[i]•Idle;
kl=Indld[i];
ll=RqtRmtid[i];
k=Assid[q];
l=AssidRmt[q);
NID[i]=NID[i]+l;
, (q<MC && InUse[ql••TRUE && State[ql••ABBOCiated && (RqtinUse[q] !•TRUE 11 RqtState[q] !•W_Conf)
&& (IndlnUse[i] !=TRUE 11 IndState[i] l=W_Resp) )->
q=q+l
: (q<MC && InUse[q] !=TRUE)->
q=q+l
: (q>=MC) ->
q=O;
break;
od;
/*Envio Mensaje de confirmacion de terminacion•/
to link(n] !MLoCf_XXXPDU,xl,l,x3,x4 -> gato end3; /•e•/
/...
/••• ESTADO DEL PROCESO: END
...
•••/
/
10.4 SUPPER.PRO
/••• •••/
/••• Supper ***/
/*** •••/
#define MC 4
proctype supper(bit n)
{
/**********************************************************••··················!
/••• Variables •••/
/*********•••··································································!
byte dummy; /•variable dummy•/
byte xl; /•otra variable dummy•/
byte x2; /*otra variable dummy•/
byte x3; /•otra variable dummy•/
byte x4; /*otra variable dummy•/
byte j;
byte k· /•assid local */
byte l· /•assid remota •/
byte Associa[MC]
byte q; /•apuntador a una asociacion a guardar•/
byte p; /•apuntador a una asociacion a concluir•/
byte pl; /*apuntador a una asociacion a concluir•/
byte count; /•control para dar de baja asociaciones•/
byte AsocCons; /•control para dar de baja asociaciones•/
byte Nevers; /•valor invalido paras•/
1··············································································1
/••• Inicializacion •••/
!··············································································!
q=O;
Nevers=255;
do
:(q<MC)->
Associa[q]=Nevers;
q=q+l
: (q>=MC) ->
break;
od;
q=O;
count=O;
/*** Inicializacion •••/
1··············································································1
1··············································································1
/••• Login •••/
1··············································································1
from_upper[n] !MLiRq_XXXPDU,dummy,dummy,dummy,dummy->
do
:to_upper[n]?MLiCf_XXXPDU,xl,x2,x3,x4->goto cont;
:to_upper[n]?MLiCf_ErrPDU,xl,x2,x3,x4->goto fin;
173
od;
/••• Login •••/
/******************************************************************************/
/******************************************************************************/
/••• Ciclo principal •••/
/******************************************************************************/
cont: do
(count==O)->skip;
(count==O)->goto termina;
/•servicios:•/
:to upper[n]?MAsln initiate RequestPDU,k,l,x3,x4->
fr;m upper[n] !MAsRs initiate ResponsePDU,k,l,dummy,dummy;
:to upper[n]? MAsln reject PDÜ,k,l,x3,x4; /*Retransmite la resp. de ini*/
fr;m_upper[n] !MAsRi_initiite_ResponsePDU,k,l,dummy,dummy;
:to_upper[n]?MR1In_conclude_RequestPDU,k,l,x3,x4->
from upper[n] !MRlRs conclude ResponsePDU,k,l,dummy,dummy;
:to_upper[n]?MR1In_r~ject_PDU-;-k,l,x3,x4; /*Retransmite la resp. de conc•/
from_upper[n] !MRlRs_conclude_ResponsePDU,k,l,dummy,dummy;
:to_upper[n]?MCfln_confirmed_RequestPDU,k,l,x3,x4->
from_upper[n] !MCfRs_confirmed_ResponsePDU,k,l,x3,x4;
:to_upper[n)?MCfln_reject_PDU,xl,x2,x3,x4->
from_upper[n] !MCfRs_confirmed_ResponsePDU,xl,x2,x3,x4;
·to_upper[n]?MUfln_unconfirmed_PDU,xl,x2,x3,x4->skip;
od;
/*********************************************************••·~··················/
/••• Terminacion •••/
/***********************************************************''******************/
:ermina: from_upper[n] !MLoRq_XXXPDU,dummy,dummy,dummy,dummy->
do
:to_upper[n]?MLoCf_XXXPDU,xl,x2,x3,x4-> gato fin;
:to_upper[n)?MAsln_initiate_RequestPDU,xl,x2,x3,x4->skip;
:to_upper[n]?MAsln_reject_PDU,xl,x2,x3,x4->skip;
:to_upper[n]?MR1In_conclude_RequestPDU,xl,x2,x3,x4->skip;
:to upper[n]?MRlln reject PDU,xl,x2,x3,x4->skip;
:to=upper[n]?MCfln=confirmed_RequestPDU,xl,x2,x3,x4->skip;
:to_upper[n]?MCfin_reject_PDU,xl,x2,x3,x4->skip;
:to_upper[n]?MUfln_unconfirmed_PDU,xl,x2,x3,x4->skip;
od;
/*** Terminacion •••/
1···························································,,··················1
fin: skip;
)
10.5 SMMSPRM.PRO
/*** •••/
/••• SMMSPM •••/
/••• •••/
#define MC 4 /•No. maximo de conexiones •/
#define MR 1 /•No.max de pet.simultaneas x conex. •/
#define MA 40 /*No. maximo de asociaciones */
#define MI 200 /*No. maximo del id de la peticion •/
byte NCD_SM;
proctype smmspm(bit n)
{
/····························································~··················!
/••• Variables •••/
/***************·············································~··················!
bool bExiste; /•indica si assid esta registrado •/
byte NRD[MC] /*# de petciones d.lsp. por conex. •/
byte NID[MC] /*# de indicacione:3 disp. por conex.•/
byte q; /•apuntador a cone:<ion del timer •/
byte i; /•apuntador a cone:<ion libre •/
byte k· /•assid local •/
byte l; /•assid remota •/
byte kl; /•reqid local •/
byte 11; /•indid remota •/
174
byte s; /•ase disponible */
byte t; /*id rqt proximo disponible */
byte u; /*id ind proximo disponible */
byte j; /•indice •/
byte xl; /*variable dummy */
byte x2; /•variable dummy */
byte x3; /•variable dummy */
byte x4; /•variable dummy •/
byte Assid[MC] /*buffer para guardar #ass local */
byte AssidRmt [MC] /•buffer para guardar #ass remota */
byte State[MC] /*buffer para guardar el edo */
bool InUse [MC]; /*buffer para guardar #ass remota */
byte Rqtid [MC]; /•buffer para guardar #pet local */
byte RqtRmtid[MC] /*buffer para guardar #pet remota */
byte Indid[MC]; /*buffer para guardar #ind rmt */
byte RqtState[MC] /*buffer para guardar #pet local */
byte IndState[MC] /•buffer para guardar #pet local */
byte RqtinUse [MC] /•buffer para guardar #ind rmt */
byte IndinUse[MC] /*buffer para guardar #ind rmt •/
/******************************************************************************/
/••• Inicializacion de Variables ***/
/******************************************************************************/
j =0;
do
: lj<MC) ->atomic{
InUse[j]=FALSE;
NRD[j]=MR;
NID [j] =MR;
RqtinUse[j]=FALSE;
IndinUse[j]=FALSE;
j=j+l;
}
:(j>=MC)->
break;
od;
NCD_SM=MC;
S= (l3+n*ll)
NRD=MR;
NID=MR;
RqtinUse=FALSE;
IndinUse=FALSE;
/**********************************••······················~····················/
/**********************************************************i"*******************/
/••• ESTADO DEL PROCESO: BEGIN ***/
/*** ***/
from_upper[n]?MLiRq_XXXPDU,xl,x2,x3,x4-> /*S*/
to upper [n] ! MLiCf XXXPDU, xl, x2, x3, x4; /*S* /
/*~* - BEGIN ***/
/••• •••/
/**********************************************************1'*******************/
1··························································~····················1
1··························································~~···················1
/**********************************************************1r*******************/
/*** ESTADO DEL PROCESO: SALONE ***/
/••• ***/
end3: do /*S*/
:from_link[n]?MLiin_XXXPDU,xl,x2,x3,x4 -> /•s•/
to_link[n] !MLiCf_XXXPDU,xl,x2,x3,x4;goto end2; /*S*/
:from_upper[n]?MLoRq_XXXPDU,xl,x2,x3,x4-> /*S*/
to_upper[n] !MLoCf_XXXPDU,xl,x2,x3,x4;goto end44; /*S*/
od; /*S*/
/••• SALONE ***/
/*** •••/
1·························································•·t••·················1
l****************************************************••••••·t•••••••••••••••••••/
/********************••·····································~·················••/
1··························································-~···················1
/••• ESTADO DEL PROCESO: GROUP ***/
/••• ***/
175
end2: do /•S*/
/•Aviso de Expiracion local•/ /*S*/
:from upper[n)?MLoRq XXXPDU,xl,x2,x3,x4-> /•s•/
/•Aq~i va la rutina-de descarga de informacion•/ /•s•/
to 1 ink [n) ! MLoin XXXPDU, xl, x2, x3, x4 - >goto ExpLoc; /•s•/
/•Aviso de Expiracion remota•/ /•s•/
:from_link[n)?MLoln_XXXPDU,xl,x2,x3,x4->goto ExpRmt; /•s•/
/•Aqui va la rutina de descarga de informacion*/ /•s•/
1··············································································1
/••• Peticion de Asociacion •••/
/************************************************••····························/
/******************************************************************************/
/*** Indicacion de Asociacion •••/
/******************************************************************************/
/**Ind. de Asee. rmt. PDU correcto**/
:from_link[n)?MAsln_initiate_RequestPDU,xl,l,x3,x4 ->
atomic{
bExiste=FALSE;
j =Ü;
do
(j<MC && InUse[j)==TRUE && AssidRmt[j)==l)->
bExiste=TRUE;
i=j;
break;
( j <MC && ( InUse [j l ! =TRUE 11 AssidRmt[j)!=l))->
j =j +l;
(j>=MC) ->
break;
od;
};
if
: (bExiste==FALSE && NCD_SM>O)->
atomic(
j=O;
do
: ( j <MC && InUse [j) ==TRUE) - >
j =j +l;
: (j<MC && InUse[j) !=TRUE)->
i=j;
break;
:(j>=MC)->
break;
od;
};
NCD SM=NCD SM-1:
InUse[i)=TRUE;
Assld[i)=s;
AssidRmt[i)=l;
State[i)=Calledinit;
to_upper [n) ! MAsin_initiate_RequestPDU, s, 1, x3, x4;
s=(s+l)\MA
: (bExiste==FALSE && NCD_SM<=Ü) ->
to link [n) !MAsCf initiate ErrorPDU, l, x2, x3, x4;
: (bExiste!=FALSE && State[il==Aeeociated)->
k==Assld[i];
to link[n) !MAsCf initiate ReeponsePDU,l,k,x3,x4;
: (bExiste!=FALSE && State[i) !=Aeeociated)-> ekip;
fi
/******************************************************************************/
/••• Respuesta de Asociacion •••/
/•·············································································!
/**Res. de Asee. rmt. PDU correcto Afirmativa••/
:from_upper(n]?MAsRs_initiate_ReeponsePDU,k,l,x3,x4 ->
bExiste=FALSE;
j=O;
atomic(
do
:(j<MC && (InUse[j)!=TRUE 11 Aeeld[j)!=k))->
j =j +1;
: (j<MC && InUse[j)==TRUE && Aesld[j)==k)->
bExiste=TRUE;
i=j;
176
break;
(j>=MC) ->break;
od;
};
if
(bExiste==TRUE && State[i]==Calledinit)->
l=AssidRmt[i];
State[i]=Associated;
to link[n] !MAsCf initiate ResponsePDU,l,k,x3,x4;
T
: : (bExiste ! =TRUE I Sta te [ i) ! =Calledinit) - >skip;
fi
/*****************•····························································!
/••• Confirmacion de Asociacion •••/
/*************************************************************t****************/
/*********************************************••·······························!
/*** Peticion de Liberacion •••/
1··············································································1
/******************************************************************************/
/*** Indicacion de Liberacion ***/
/******************************************************************************/
/**Ind. de Libe. rmt. PDU correcto••/
: :from_link[n]?MR1In_conclude_RequestPDU,k,l,x3,x4 ->
bExiste=FALSE;
j=O;
atomic{
do
::(j<MC && (InUse[j]!=TRUE 11 Assid[j)!=k) )->
j=j+l;
: : (j<MC && InUse[j]==TRUE && Assid[j)==k)->
bExiste=TRUE;
i=j;
break;
(j>=MC) ->break;
od;
};
if
: : (bExiste==TRUE && State[il==Associated)->
State[i]=CalledConc;
l=AssidRmt [i];
to_upper(n] !MR1In_conclude_RequestPDU,k,l,x3,x4;
(bExiste==TRUE && State[il==CalledConc)->skip;
, (bExiste==TRUE && State[i] !=Associated && State[i] !=CalledConc)->skip;
: : (bExiste ! =TRUE ) - >
to_link[n] !MR1Cf_conclude_ResponsePDU,l,k,x3,x4;
177
fi
/******************************************************************************/
/••• Respuesta de Liberacion •••/
1··············································································1
/ **Res. de Libe . loe. PDU correcto afirmativo••/
:from_upper[n] ?MR1Rs_conclude_ResponsePDU,k,l,x3,x4 ->
bExiste=FALSE;
j=O ;
atomic{
do
: : {j<MC & & (InUse[j] !=TRUE 11 Assld[j] !=k) ) ->
j=j+l;
( j <MC && InUse[j]==TRUE && Assld[j]==k)->
bExiste=TRUE;
i=j;
break;
(j>=MC) ->break;
od;
};
if
: (bExiste==TRUE && State[i]==CalledConc)->
l=AssldRmt [i] ;
InUse[i]=FALSE ;
State[i]=IdleConn ;
NCD_SM=NCD_SM+l ;
to link[n] !MRlCf conclude ReaponsePDU,l , k,x3,x4;
: (bExiste!=TRUE 11 State[i] ! =CalledConc) - > akip;
fi
/••··········································································••/
/••• Confirmacion de Liberacion •••/
1··············································································1
!··············································································!
/ ••• Peticion de Servicio confirmado ***/
1··············································································1
1··············································································1
/ ••• Indicacion de Servicio Confirmado •••/
1··············································································1
/**Ind . de S . Conf . rmt . PDU correcto••/
: from_linkfn]?MCfln_confirmed_RequeatPDU , k,l,x3 , ll ->
bExiste=FALSE;
j=O;
atomic{
do
: ( j <MC && ( InUae [j J ! =TRUE 11 Asa Id [j] ! =k 11 State [j J ! =Aasociated)) - >
j =j +l;
178
: : ( j <MC && InUse [j] ==TRUE && Assld [j] ==k && State [j] ==Assoc:.ated) - >
bExiste=TRUE;
i=j;
break;
: : (j>=MC) ->break;
od;
);
if
(bExiste==TRUE && NID[i)>O)->
IndinUse[i)=TRUE;
NID[i)=NID[i) -1;
RqtRmtld[i)=ll;
Indid[i)=U;
IndState[i)=W Resp;
l=AssidRmt[iJ7
to_upper[n) !MCfin_confirmed_RequestPDU,k,l,u,11;
U= (u+l) \MI;
: : (bExiste==TRUE && NRD[i]<=O)->/*SUPONGO QUE ES MJE REPETIDO*/
skip;
: : (bExiste!=TRUE) ->
to_link[n) !MCfCf confirmed_ErrorPDU,l,k,x3,x4;
fi
/******************************************************************************/
/*** Respuesta de Servicio Confirmado ***/
/******************************************************************************/
/**Res. de S.Conf. loct. PDU correcto Afirmativa••/
: :from_upper[n)?MCfRs_confirmed_ResponsePDU,k,l,kl,11 ->
bExiste=FALSE;
j =0;
atomic{
do
: : ( j <MC && ( InUse [j] ! =TRUE 11 Aes Id [j] l =k 11 IndinUse [i] ! ='I'RUE 11 Indid [i) ! akl) ) - >
j =j +1;
: : (j<MC && InUse[j]==TRUE && Assid[j]=ck && IndinUse[i)uTF:UE && Indid[i] .... kl)->
bExiste=TRUE;
i=j;
break;
: : ( j >=MC) - >break;
od;
};
if
: : (bExiste==TRUE && IndState [i) ==W_Reap) ->
IndState[i)=Idle;
ll=RqtRmtid[i);
l=AssidRmt[i];
IndinUse[i)=FALSE;
NID[i)=NID[i)+l;
to link[n) !MCfCf confirmed ReaponaePDU,l,k,11,kl;
: : (bExiate!=TRUE 11
IndState[i) !=W_Resp)->skip;
fi
/*************************************************************i****************/
/••• Confirmacion de Servicio Confirmado •••/
/*************************************************************•****************/
1··············································································1
/••• Indicacion de Servicio Sin Confirmacion •••/
/***********************************************•·············~················!
/••rnd. de S.UnConf. rmt. PDU correcto••/
: :from_link(n)?MUfin_unconfirmed_PDU,k,l,x3,x4 ->
bExiste=FALSE;
j=O;
atomic{
do
(j<MC && (InUse(j)!=TRUE 11 Assid[j)!=k 11 State(j]!=Associated))->
j=j+l;
(j<MC && InUse(j)==TRUE && Assid[j]==k && State[j]==Associated)->
bExiste=TRUE;
i=j;
break;
: (j>=MC)->break;
od;
};
if
(bExiste==TRUE) ->
l=AssidRmt[i];
to upper(n] !MUfin unconfirmed PDU,k,l,x3,x4
(bE;iste!=TRUE) ->skip; -
fi
od;
/*** GROUP ***/
/*** •••/
1··············································································1
!······································································********/
/******************************************************************************/
/******************************************************************************/
/••• ESTADO DEL PROCESO: LOFF ***/
/*** ***/
ExpLoc: do /*S*/
:from_link(n]?MLoln_XXXPDU,xl,x2,x3,x4-> /*S*/
to link[n) !MLoCf XXXPDU,xl,x2,x3,x4; /•s•/
:from_link[n]?MLoCf_XXXPDU,xl,x2,x3,x4-> /*S*/
to_upper[n] !MLoCf_XXXPDU,xl,x2,x3,x4;goto end44; /•s•/
:from_link[n]?MAsin_initiate_RequestPDU,xl,l,x3,x4 ->
skip;
:from_link[n]?MR1In_conclude_RequestPDU,l,k,x3,x4 ->
skip;
:from_link[n]?MCfln_confirmed_RequestPDU,xl,x2,x3,x4 ->
skip;
:from link[n]?MUfin unconfirmed PDU,xl,x2,x3,x4 ->
skip-;- - -
od; /*S*/
/*** LOFF •••/
/*** •••/
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/
/••• Rutina de Terminacion Remota •••/
/*** ***/
ExpRmt: q=O;
do /*limpio mis tablas•/
180
: : (q<MC && InUse[q]==TRUE && State[q]••Calledinit)->
InUse[q]=FALSE;
k=Assid[q];
l=AssidRmt[q];
State[q]=IdleConn;
NCD_SM=NCD_SM+l;
q=q+l;
: : (q<MC && InUse[ql==TRUE && State[q)==CalledConc)->
InUse[q]=FALSE;
k=Assid[q];
l=AssidRmt[q];
State[q]=IdleConn;
NCD_SM=NCD_SM+l;
q=q+l;
: : (q<MC && InUse[ql==TRUE && State[q)==Associated && RqtinUse[ql==TRUE && RqtState[q]==W_Conf)-
>
RqtinUse[i]=FALSE;
RqtState[i)=Idle;
k=Assid[q];
l=AssidRmt[q);
kl=Rqtid[i];
NRD[i]=NRD[i]+l;
to_upper[n] !MCfCf_confirmed_ErrorPDU,k,l,kl,x4;
q=q+l;
: : (q<MC && InUse[ql==TRUE && State[q]==Associated && IndinUse[i]==TRUE && IndState[il==W_Resp)-
>
IndinUse[i]=FALSE;
IndState[i]=Idle;
kl=Indid[i];
ll=RqtRmtid [i];
k=Assid[q];
l=AssidRmt [q] ;
NID[i]=NID(i]+l;
:: (q<MC && InUse[ql==TRUE && State[q]==Associated && (RqtinUse[q] l=TRUE 11 RqtState[q] !=W_Conf
11 IndinUse(iJ !=TRUE && IndState[i] !=W_Resp))->
q=q+l
:: (q<MC && InUse[q) !=TRUE)->
q=q+l
: : (q>=MC) - >
q=O;
break;
od;
/*Envio Mensaje de confirmacion de terminacion*/
to_link[n) IMLoCf_XXXPDU,xl,l,x3,x4 -> goto endJ; /*C*/
1····························································-··················1
1····························································-··················1
/*** ESTADO DEL PROCESO: END ***/
/*** ***/
end44: skip;
/*** END ***/
/*** ***/
/******************************************************************************/
1··············································································1
181
11 APÉNDICE C
11.1 ROOT.C
tlinclude <channel.h>
#include <Stdio.h>
#include <assert.h>
#include <Stdlib.h>
#include <iocntrl.h>
#include <process.h>
#include <string.h>
#include <Ctype.h>
#include <math.h>
#include 11
mmsprimi.h 11 /• Primitivas MMS •/
#include 11
mmsctes.h 11 /• Constante MMS •/
#include 11
mmstypes.h 11 /• Tipos MMS •/
#include "mmspdu.h" /• Definicion PDU MMS •/
#include "mmstype2 .h" /• Tipos MMS •/
#include "mmspdutr.h" /• Fns de Conversion de MMSPDU a un string •/
#include "TrxBuff.h" /• Procesos p emular canal de lon9. n •/
#include "SMMSPM.h" /• Proceso MAq Edos MMS del servidor •/
#include "feeder.h" /* Proceso que recibe los datos desde TO •/
/****•·······················································•,:•••·············!
/********** KILLER **********/
void Killer_proc(Process • p,Channel •Killer) {
Boolean bStop=TRUE;
int Stop;
char schar[l];
p=p;
while (bStop) {
Stop=pollkey () ;
if (Stop==38) {
ChanOut(Killer,&schar,l);
bStop=FALSE;
return;
1·····························································~·················1
/********** MONITOR **********/
void Monitor_proc(Process * p,Channel *FrClient,Channel *FrCmme1pm,
Channel •FrSmmspm,Channel *FrServer) {
Boolean bMonitoring=TRUE;
char sTmp (11]
char Node[ll];
char sTx[3];
char sVal[2];
tTrama sCmd;
tTrama sPrntCmd,sPrntCmd2;
int ch;
while(bMonitoring) {
ch=ProcAlt(FrClient,FrCmmspm,FrSmmspm,FrServer,NULL);
switch(ch) {
case O:
strcpy(sTmp, "Client");
Chanin(FrClient,sCmd,TRAMA_LEN);
break;
case 1:
strcpy(sTmp, "Cmmspm");
Chanin(FrCmmspm,sCmd,TRAMA_LEN);
break;
182
case 2:
strcpy (sTmp, "Smmspm");
Chanin(FrSmmspm,sCmd,TRAMA_LEN);
break;
case 3:
strcpy(sTmp,"Server");
Chanin(FrServer,sCmd,TRAMA LEN);
if (strncmp(sFIN,sCmd,3)==0) {
bMonitoring=FALSE;
break;
return;
END ***/
1····························································~·················1
void server_proc(Process * p,Channel •e, Channel *d,Channel *Fr,)mKiler,
Channel *ServerToMon)
{
tTrama sCmd;
int bKeepGoing TRUE;
int iPid=l546;
aleaf SAleaf;
Boolean bStop;
int ch;
char sChar[lJ;
1····························································~~···············1
/*** Inicializacion ***/
p = p;
/*** INICIA***/
/************************************************************,r***************/
/************************************************************ir***************/
/ ** • Login ***/
SAleaf.Primitive=LOGIN_Request;
SAleaf.Id.Assid=O;
SAleaf.Id.AssidRmt=O;
SAleaf.Id.Pid=iPid;
SAleaf.Id.PidRmt=O;
PackTrama(&SAleaf,sCmd)
ChanOut(d,sCmd,TRAMA_LEN);
bStop=TRUE;
while (bStop) {
Chanin(c,sCmd,TRAMA_LEN);
SendMonitor(ServerToMon,sCmd,FROMSMMSPM,VALIDO);
UnpackTrama(&SAleaf,sCmd);
switch(SAleaf.Primitive) {
case LOGIN Confirm:
bStop=FALSE;
break; /*goto cent;*/
case LOGIN ConfirmErr:
fin(d,ServerToMon); /•goto fin; */
return;
break;
Login ***/
/•••·························································-················/
/***********************************•••······················-················/
/*** cent Ciclo principal ***/
while (bKeepGoing) {
ch=ProcAlt(c,FromKiler,NULL)
if (ch==O) {
Chanin(c,sCmd,TRAMA LEN);
SendMonitor(ServerToMon,sCmd,FROMSMMSPM,VALIDO)
UnpackTrama(&SAleaf,sCmd);
/• printf("\nRECIBI MSJ :%d-%d",SAleaf.Primitive,SAleaf.Id.Pid) ;*/
switch(SAleaf.Primitive) {
case A_ASSOCIATE_indication:
SAleaf.Primitive=A ASSOCIATE response;
SAleaf.MmsPdu.designator=MMSpdu_initiate_ResponsePDU;
PackTrama(&SAleaf,sCmd);
ChanOut(d,sCmd,TRAMA_LEN)
break;
case A RELEASE indication:
SAleaf .Primitive=A_RELEASE_response; /*Retr.,nsmite la resp. de cene•/
SAleaf.MmsPdu.designator=MMSpdu_conclude_ResponsePDU;
PackTrama(&SAleaf,sCmd);
184
ChanOut(d,sCmd,TRAMA_LEN);
break;
break;
default:
break;
)
else{
Chanin(FromKiler,&sChar,l);
bKeepGoing=FALSE;/•goto termina;•/
/****************************************************************************/
• /••• (termina)
SAleaf.Primitive=LOGOUT_Request;
SAleaf.Id.Assld=O;
SAleaf.Id.AssidRmt=O;
Terminacion •••/
PackTrama(&SAleaf,sCmd);
ChanOut(d,sCmd,TRAMA LEN);
bKeepGoing=TRUE; -
while (bKeepGoing) {
Chanln(c,sCmd,TRAMA_LEN);
SendMonitor(ServerToMon,sCmd,FROMSMMSPM,INVALIDO);
UnpackTrama(&SAleaf,sCmd);
switch(SAleaf.Primitive) {
case LOGOUT_Confirm: /•goto fin;•/
fin(d,ServerToMon);
return;
break;
default: /•skip•/
break;
/******************************************************************************/
/********** Entry Point **********/
/********** **********/
int main (int argc, char •argv[], char •envp[],
Channel •in[], int inlen,
Channel •out[], int outlen)
Process *RxSmmspmFrClnt,•TxSmmspmFrClnt,
•smmspm,•Server,
*RxServer,•TxServer,
*RxSmmspmFrServer,*TxSmmspmFrServer,
*Feeder,*Killer,
*Monitor;
Channel *RxlSmmspmToSmmspm,
*SmmspmToRxServer,*RxServerToServer,
*ServerToRx2Smmspm,•Rx2SmmspmToSmmspm,
*FrKiller,
•smmspmToMon,•ServerToMon;
int i·
int bKeepGoingSmms=TRUE,bKeepGoingl=TRUE,bKeepGoing2=TRUE,bKeepGoing3=TRUE;
ProcRun (Feeder);
ProcJoin(Feeder,NULL);
ProcAllocClean (Feeder);
ProcPar
(Smmspm,Server,RxSmmspmFrClnt,TxSmmspmFrClnt,RxServer,TxServer,RxSmmspmFrServer,TxSmmspmFrServer,
Killer,Monitor,NULL);
ProcAllocClean (Server);
ProcAllocClean (Smmspm);
ProcAllocClean (RxServer);
ProcAllocClean (TxServer);
ProcAllocClean (RxSmmspmFrServer);
ProcAllocClean (TxSmmspmFrServer);
ProcAllocClean (RxSmmspmFrClnt);
ProcAllocClean (TxSmmspmFrClnt);
ProcAllocClean (Killer);
ProcAllocClean (Monitor);
printf("\n Fin");
11.2 CLIENT.C
#include <channel.h>
#include <Stdio.h>
#include <assert.h>
#include <Stdlib.h>
#include <process.h>
#include <string.h>
#include <math.h>
#include 11
mmsprimi.h 11 /• Primitivas MMS •/
#include "mmsctes. h" /• Constante MMS */
#include "mmstypes.h" /• Tipos MMS */
#include 11
mmspdu.h 11 /• Definicion PDU MMS */
#include "mmstype2 .h" /• Tipos MMS */
#include "mmspdutr.h" /• Fns de Conversion de MMSPDU a un string •/
#include "TrxBuff.h" /• Procesos p emular canal de long. n •/
#include 11
cmmspm.h 11 /* Procesos de la maquina de protocolo MMS para el cliente*/
return(iComando) ;
if(i>=icount)
i=-1;
return(i);
/*************************************************************,r****************/
/ **********
/ **********
Proceso Cliente ··········!
**********/
void fin(Channel *ToMmspmJ {
ChanOut (ToMmspm,sFIN , TRAMA_LEN);
return;
1···············································································1
/••• Terminacion •••/
void termina(Channel *FrMmspm, Channel *ToMmspm,tTrama •sCmd) {
/••• Fn. SendLogout Envia la Prim. Logout y espera respuesta ••/
Boolean bStop=TRUE;
aleaf AleafTmp;
ChanOut(ToMmspm, (*sCmdJ ,TRAMA_LEN);
while (bStop) {
Chanin(FrMmspm,sCmd,TRAMA_LEN);
UnpackTrama(&AleafTmp, (*sCmd));
if(AleafTmp . Primitive••LOGOUT Confirm)
break; -
}
fin (ToMmspm) ; /•goto fin•/
return;
/******************************************************************************/
/••• Inicializacion •••/
p = p;
iComando=ListenFeeder (FrFeeder,&sCmdBuff);
/*** Inicializacion ***/
187
/******************************************************************************/
/******************************************************************************/
/••• Login •••/
j = GetLoginPrim (&sCmdBuff,iComando);
Mstrcpy(sCmd,sCmdBuff[j]);
ChanOut(ClientToMon,sCmd,TRAMA_LEN);
ChanOut(ToMmspm,sCmd,TRAMA_LEN);
bStop=TRUE;
while (bStop) {
Chanin(FrMmspm,sCmd,TRAMA_LEN);
UnpackTrama(&CAleaf,sCmd);
switch(CAleaf.Primitive) {
case LOGIN Confirm:
bStop=FALSE;
break; /•gato cont*/
case LOGIN ConfirmErr:
fin (ToMmspm);
return; /•gato fin•/
break;
break;
case A_RELEASE_request: /*dar de baja asociaciones*/
ChanOut(ToMmspm,sCmd,TRAMA_LEN);
bStop=TRUE;
while (bStop) {
Chanin(FrMmspm,sCmd,TRAMA_LEN);
UnpackTrama(&CAleaf,sCmd);
if(CAleaf.Primitive==A_RELEASE_confirm) {
/*AQUI LA APLICACION REAL DEBE EVALUAR EL PDU: ck, ERR, REJECT*/
bStop=FALSE;
break;
case A MMS Request:
if (CAleif.MmsPdu.designator==MMSpdu confirmed RequestPDU) {/•enviar servicions
confirmados•/ - -
ChanOut(ToMmspm,sCmd,TRAMA_LEN);
bStop=TRUE;
while (bStop) {
Chanin(FrMm~pm,sCmd,TRAMA_LEN);
UnpackTrama(&CAleaf,sCmd);
if(CAleaf.Primitive==A_MMS_Confirm) {
/*AQUI LA APLICACION REAL DEBE EVALUAR EL PDU: ok, ERR, REJECT*/
bStop=FALSE;
188
else{ /•enviar servicios NO confirmados•/
ChanOut(ToMmspm,sCmd,TRAMA_LEN);
break;
default:
ChanOut(ToMmspm,sCmd,TRAMA_LEN);
break;
/•···························································:~·················/
/********** Entry Point ··········!
;··········
int main (int argc, char •argv[], char •envp[],
··········!
Channel •in[], int inlen,
Channel •out[], int outlen)
Process *Client,•cmmspM,
*RxCmmspMFrServer,*TxCmmspMFrServer,
*RxClnt,*TxClnt,
*RxCmmspMFrClnt,*TxCmmspMFrClnt;
Channel *ClntToRx2Cmmspm,
*RxlCmmspmToCmmspm,
*CmmspmToRxClnt,•RxClntToClnt,
*Rx2CmmspmToCmmspm;
int i,bKeepGoingCmms=TRUE,bKeepGoingl=TRUE,bKeepGoing2=TRUE,bICeepGoing3=TRUE;
ProcPar(Client,CmmspM,RxCmmspMFrServer,TxCmmspMFrServer,RxClnt:,TxClnt,RxCmmspMFrClnt,TxCmmspMFrCl
nt,NULL);
ProcAllocClean (Client);
ProcAllocClean (CmmspM);
ProcAllocClean (RxCmmspMFrServer);
ProcAllocClean (TxCmmspMFrServer);
ProcAllocClean (RxClnt);
ProcAllocClean (TxClnt);
ProcAllocClean (RxCmmspMFrClnt);
ProcAllocClean (TxCmmspMFrClnt);
}
/*AP:CASO EXCLUSIVO PARA ESTA APLICACION*/
189
11.3 SMMSPM.H
ConnTblType ConnTbl;
UnpackTrama(AleafTmp, (*sCmd));
return ( ch) ;
/******************************************************************************/
/********** Proceso SmmspM **********/
/********** **********/
/******************************************************************************/
/*** ESTADO DEL PROCESO: END ***/
void end44(Channel *ToServer,Channel *ToClnt) {
ChanOut(ToClnt,sFIN,TRAMA_LEN);
ChanOut(ToServer,sFIN,TRAMA_LEN);
return;
/******************************************************************************/
/••• ESTADO DEL PROCESO: SALONE (end3) ***/
int end3(Channel *FrClnt,Channel *ToClnt,Channel *FrServer,Channel *ToServer) {
tTrama sCmd;
aleaf SMAleaf;
int ch;
while (TRUE) (
ch=ProcAlt(FrServer,FrClnt,NULL)
switch (ch) (
case O:
Chanin(FrServer,sCmd,TRAMA_LEN);
UnpackTrama(&SMAleaf,sCmd);
MMSDecod(sCmd,ch);
if(SMAleaf.Primitive==LOGOUT_Request) (
SMAleaf.Primitive=LOGOUT_Confirm;
PackTrama(&SMAleaf,sCmd);
ChanOut(ToServer,sCmd,TRAMA_LEN);
end44(ToServer,ToClnt) /•goto end44*/
return(FALSE)
break;
case l:
Chanin(FrClnt,sCmd,TRAMA_LEN);
UnpackTrama(&SMAleaf,sCmd);
MMSDecod(sCmd,ch);
if(SMAleaf.Primitive==LOGIN_Indication) {
SMAleaf.Primitive=LOGIN_Confirm;
Rdid(&(SMAleaf.Id) ,1); /*leo registro id*/
PackTrama(&SMAleaf,sCmdi;
ChanOut(ToClnt,sCmd,TRAMA_LEN)
return(TRUE); /•goto end2*/
190
break;
while(TRUE) {
Chanin(FrClnt,sCmd,TRAMA_LEN);
UnpackTrama(&SMAleaf,sCmd);
MMSDecod(sCmd,l);
Primitiva=SMAleaf.Primitive;
switch(Primitiva) {
case LOGOUT Indication:
SMAleaf.Primitive=LOGOUT_Confirm;
Rdid(&(SMAleaf.Id) ,1); /•leo registro id•/
PackTrama(&SMAleaf,sCmd);
ChanOut(ToClnt,sCmd,TRAMA_LEN);
break;
case LOGOUT Confirm:
ChanOut(ToServer,sCmd,TRAMA_LEN);
end44(ToServer,ToClnt);
return;
break;
default:
break;
/*************************************************************n****************/
/••• Inicializacion de Variables •••/
p = p;
InitiateConnTbl(&ConnTbl);
/••• Inicializacion de Variables •••/
1·····························································~·················1
/*************************************************************i'****************/
/••• ESTADO DEL PROCESO: BEGIN •••/
bStop=TRUE;
while(bStop) {
Chanin(FrServer,sCmd,TRAMA_LEN);
SendMonitor(SmmspmToMon,sCmd,FROMSERVER,VALIDO)
UnpackTrama(&SMAleaf,sCmd);
MMSDecod(sCmd,0);
if(SMAleaf.Primitive==LOGIN_Request){
Wrid(SMAleaf.Id,O); /•registro el Local id•/
SMAleaf.Primitive=LOGIN_Confirm;
PackTrama(&SMAleaf,sCmd);
ChanOut(ToServer,sCmd,TRAMA_LEN);
break;
191
/••• BEGIN •••/
/****************,r*************************************************************/
/••• ESTADO DEL PROCESO: SALONE •••/
if (end3(FrClnt,ToClnt,FrServer,ToServer)==FALSE)
return;
/******************************************************************************/
/• • • ESTADO DEL PROCESO: GROUP • •• /
while ( (*bKeepGoing)) {
ch=ListenChans(FrServer,FrClnt,&SMAleaf,&sCmd);
MMSDecod ( sCmd, ch) ;
Primitiva=SMAleaf.Primitive;
if(ch==FRCLNT) {
SendMonitor(SmmspmToMon,sCmd,FROMCMMSPM,VALIDO);
switch(Primitiva) {
/******************************************************************************/
/*** Aviso de Expiracion remota •••/
case LOGOUT Indication:
SMAleaf.Primitive=LOGOUT_Confirm; /•goto ExpRmt*/
Rdid (& (SMJ\leaf. Id), 1) ; /•leo registro id•/
PackTrama(&SMAleaf,sCmd);
ChanOut(TcClnt,sCmd,TRAMA_LEN);
if (end3(FrClnt,ToClnt,FrServer,ToServer)==FALSE)
return;
break;
1·······························································~···············1
/*** Indicacion de Asociacion •••/
case A- ASSOCIATE - indication:
GetConnection(&bOk,&ConnTbl,&Cid);
if(bOk==TRUE){ /*Cargo estado.rol y Pid•/
ConnTbl[Cid] .State=Calledinit;
ConnTbl[Cid] .Role=Responder;
/*Identificacion local*/
SMAleaf.Id.Pid=LocalPid;
SMAleaf.Id.Assid=ConnTbl[Cid] .Id.Ass!d;
/*Descar90 datos de identificacion en la tabla de com!xion• /
Wridentity(SMAleaf.Id,&ConnTbl,Cid,0);
/•Completa el pdu para obtener enviar el response•/
BuildiniRspPDU(&SMAleaf);
PackTram,3. ( &SMAleaf, sCmd) ;
ChanOut (ToServer, sCmd, TRAMA_LEN) ;
}
else{
FillErrorPDU(&(SMAleaf.MmsPdu) ,ServiceError_errorClass_t_initiate,ServiceError_errorClass_t_initi
ate t other) ;
-- }
break;
/*****************1~····························································/
/••• Indicacion de Liberacion •••/
case A RELEASE indication:
FindConnection(&bOk,&ConnTbl,&Cid,SMAleaf.Id.Assid);
if (bOk==TRUE) {
if (ConnTbl [Cid] . State==Associated) {
ConnTb:[Cid] .State=CalledConc;
/•Rtx el pdu de indication•/
ChanOut: (ToServer, sCmd, TRAMA_LEN) ;
/•else skip•/
}
else{
/•no ExiE1te - > PDU Conf. OK* /
SMAleaf.Primitive=A_RELEASE_confirm;
SMAleaf.MmsPdu.designator=MMSpdu conclude ResponsePDU;
/•cargo el id en el PDU con el id en la tabla•/
Rdidentity(&(SMAleaf.Id) ,ConnTbl,Cid,1);
/•envio•/
PackTrama, ( &SMAleaf, sCmd) ;
ChanOut ('l'oClnt, sCmd, TRAMA_LEN) ;
break;
case A MMS Indication:
/*************;***;**•*********************************************************/
/*** Indicacion de Servicio Confirmado •••/
if(SMAleaf.MmsPdu.designator==MMSpdu confirmed RequestPDU){
FindConnection(&bOk,&ConnTbl,&Cid,SMAleaf.Id~Assid);
192
if(bOk=ccTRUE && ConnTbl[Cid) .State==Associated) {
bOk=Processindication(&SMAleaf,&(ConnTbl[Cid)));
if (bOk==TRUE) {
/•Rtx el pdu de indication•/
SMAleaf.Primitive=A MMS Indication;
/•Cargo el id en el-PDU-con el id en la tabla•/
Rdidentity(&(SMAleaf.Id) ,ConnTbl,Cid,O);
/*envio•/
PackTrama(&SMAleaf,sCmd);
Char..Out (ToServer, sCmd, TRAMA_LEN) ;
}
else{ /•Error: no se alojar la indicacion•/
SMAleaf.Primitive=A_MMS_Response;
/*Cargo el id en el PDU con el id en la tabla•/
Rdidentity(&(SMAleaf.Id) ,ConnTbl,Cid,l);
}
else{/•error no existe la asociacion, aviso del error al cliente•/
SMAleaf.Primitive=A MMS Response;
/•carg~ el id en el-PDU-con el id en la tabla•/
Rdidentity(&(SMAleaf.Id) ,ConnTbl,Cid,l);
/*************•·····~··························································!
/••• Indicacion de Servicio Sin Confirmacion •••/
else if(SMAleaf.MmsPdu.designator==MMSpdu_Unconfirmed_RequestPDU) {
FindConnection(&bOk,&ConnTbl,&Cid,SMAleaf.Id.Assid);
if(bOk==~RUE && ConnTbl[Cid) .State==Associated) {
/*Rtx el pdu de indication•/
SMAleaf:.Primitive=A MMS Indication;
/*Cargo el id en el-PDU-con el id en la tabla*/
Rdident:ity(&(SMAleaf.Id),ConnTbl,Cid,O);
/•envio•/
PackTrama(&SMAleaf,sCmd);
ChanOut (ToServer, sCmd, TRAMA LEN) ;
)/•No existe la asociacion ->-skip•/
break;
default:
PackTrama(&SMAleaf,sCmd);
ChanOut(ToServer,sCmd,TRAMA_LEN);
break;
}
if(ch==FRSERVER) {
SendMonitor(SmmspmToMon,sCmd,FROMSERVER,VALIDO);
switch(Primitiva) {
1·····························································••t••············1
/*** Aviso de Expiracion Local •••/
case LOGOUT Request:
SMAleaf.Primitive=LOGOUT_Indication; /·•goto ExpLoc• /
Rdid(&(SMAleaf.Id) ,1); /•leo registro id•/
PackTrama(&SMAleaf,sCmd);
ChanOut(ToClnt,sCmd,TRAMA_LEN);
ExpLoc(FrClnt,ToClnt,ToServer);
return;
break;
/***************************************************************"**************/
/••• Respuesta de Asociacion •••/
case A ASSOCI.A.TE response:
if (SMAleaf.Mm;-Pdu.designator!=MMSpdu_initiate_ResponsePDU) {
193
/•if not pdu valido reject•/
}
else{
FindCon1ection(&bOk,&ConnTbl,&Cid,SMAleaf.Id.Assid);
if(bOk••TRUE && ConnTbl[Cid] .State••Calledinit) {
/•cargo estado y parametros de la conexion•/
ConnTbl[Cid] .State•Associated;
ConnTbl[Cid] NegociatedMaxServOutstandingCalling•SMAleaf.MmsPdu.u.MMSpdu_initiate_ResponsePDU.neg
o,·iatedMaxServOut standingCall ing;
break;
/*··············································································/
/••• Respuesta de Liberacion •••/
case A RELEASE response:
if (SMAle.,f.MmsPdu.designator!•MMSpdu conclude ResponsePDU) {
/•if not pdu valido reject•/ - -
}
else{
FindConnection(&bOk,&ConnTbl,&Cid,SMAleaf.Id.Assid);
if(bOk··TRUE && ConnTbl[Cid] .State==CalledConc) {
/•Marco el pdu como un confirmacion de asociacion, transmito•/
SMAleaf.Primitive=A RELEASE confirm;
Rdlder..tity (& (SMAleaf. Id), coñnTbl, Cid, 1);
/*Elimino la asociacion*/
FreeCc,nnection(&bOk,&ConnTbl,Cid,SMAleaf.Id,Assid);
PackTrama(&SMAleaf,sCmd);
Chanou.t (ToClnt' sCmd, TRAMA_LEN) ;
/*else skip*/
break;
1··············································································1
/*•* Respuesta de Servicio Confirmado ***/
case A_MMS_Response:
if (SMAleaf,MmsPdu.designator!=MMSpdu confirmed Respons,~PDU &&
SMAleaf.MmsPdu.designatorl•MMSpdu-confirmed-ErrorPD1J) {
/*if not pdu valido reject, si es reepueuta-afirmat.iva o negativa.es lo mismo*/
}
elee{
FindConnection(&bOk,&ConnTbl,&Cid,SMAleaf.Id.Assid);
if(bOk=•TRUE && ConnTbl[Cid] .State•aAseociated) {
bOk=Processindication(&SMAleaf,&(ConnTbl[Cid]));
if (bOk==TRUE) {
SMAleaf.Primitive•A MMS Confirm;
/*Cargo el id en el-·PDU-con el id en la tabla*/
Rdidentity(&(SMAleaf.Id) ,ConnTbl,Cid,l);
/*envio*/
PackTrama(&SMAleaf,sCmd);
ChanOut(ToClnt,sCmd,TRAMA LEN);
}/*else No existe la ind en-staus W Response ekip*/
}/•else No existe la asociacion ->skip*/
break;
return;
194
/*** GROUP ***/
/*** ***/
11.4 CMMSPM.H
# include "mmsprmcf.h"
# include "mmsprmcO.h"
# include "mmsprmcl .h ..
# include "mmsprmc3 .h ..
# include "mmsparam h"
# include "mmsprmc4 .hn
ConnTblType ConnTbl;
UnpackTrama(AleaETmp, (*sCmd));
return (ch);
/**********k******••·~··························································J
/********** Proceso CmmspM **********/
/********** **********/
/**************•••,~····························································!
/*** Rutina de Terminacion Remota ***/
void ExpRmt() {
while (bStop) {
Chanin(FrClnt,sCmd,TRAMA_LEN);
UnpackTrama ( &AleaETmp, sCmd) ;
Primitiva=AleafTmp.Primitive;
switch(Primitiva) {
case LOGOUT_Request:
195
AleafTmp.Primitive=LOGOUT_Confirm;
PackTrama(&AleafTmp,sCmd);
ChanOut(ToClnt,sCmd,TRAMA_LEN)
end44(ToServer,ToClnt); /*goto end44:*/
return;
break;
default:
break;
1················~·····························································1
/*** ESTADO DEL PROCESO: LOFF ***/
void ExpLoc(Channel *FrServer, Channel *ToServer,Channel *ToClnt) {
tTrama sCmd;
aleaf AleafTmp;
Boolean bStop=TRUE;
while (bStop) {
Chanin(FrServer,sCmd,TRAMA_LEN)
UnpackTrama(&AleeafTmp,sCmd);
switch(AleafTmp.Primitive) {
case LOGOUT Indication:
AleafTmp.Primitive=LOGOUT_Confirm;
Rdid(&(AleafTmp.Id) ,1); /*leo registro id*/
PackTrama(&AleafTmp,sCmd);
ChanOut(ToServer,sCmd,TRAMA_LEN);
break;
case LOGOUT Confirm:
ChanOut(ToClnt,sCmd,TRAMA_LEN);
end44(ToServer,ToClnt); /•goto end44; ·• /
return;
break;
1·················~················~············································1
/••• Inicializacion de Variables ***/
p = p;
InitiateConnTbl(&ConnTbl);
/*** INICIA ***/
/******************************************************************************/
/******************************************************************************/
/ * * * ESTADO DEL PROCESO: BEGIN ***/
bStop=TRUE;
while (bStop) {
Chanin(FrClnt,sCmd,TRAMA_LEN);
ChanOut(CmmspmToMon,sCmd,TRAMA_LEN);
UnpackTrama(&CMAleaf,sCmd);
if(CMAleaf.Primitive==LOGIN_Request) (
CMAleaf.Id.PidRmt=O;
Wrid(CMAleaf.Id,O); /•registro el Local id*/
CMAleaf.Primitive=LOGIN Indication;
Rdid(&(CMAleaf.Id),l); /•leo registro id"/
PackTrama(&CMAleaf,sCmd);
ChanOut(ToServer,sCmd,TRAMA_LEN)
196
break; /*goto chk*/
/*************•••,t••···························································/
/••• ESTADO DEL PROCESO: CHK ***/
while (bStop) {
Chanin(FrServer,sCmd,TRAMA_LEN);
ChanOut(CmmspmToMon,sCmd,TRAMA_LEN);
UnpackTrama(&CMAleaf,sCmd);
if(CMAleaf.Primitive==LOGIN Confirm) {
RmtPid=CMAleaf.Id.PidRmt;-
ChanOut(ToClnt,sCmd,TRAMA_LEN);
break; /•goto end2;*/
FillErrorPDU(&(CMAleaf.MmsPdu) ,ServiceError_errorClass_t_initiate,ServiceError_errorClass_t_initi
ate t other) ;
- - }
break;
1····················~············································~············1
/••• Peticion de Liberacion ***/
case A RELEAS!~ request:
i f (CMAleaf .MmsPdu.designator!=MMSpdu conclude RequestPD'C") {
/*if not pdu valido reject•/ - -
}
else{
FindConnection(&bOk,&ConnTbl,&Cid,CMAleaf.Id.Assid);
if (bOk==TRUE ) {
if(ConnTbl[Cid] .State==Associated){
ConnTbl [Cid] . State=Call ingConc;
/•construye el pdu de indication•/
CMAleaf.Primitive=A RELEASE indication;
/•cargo el id en el-PDU con-el id en la tabla•/
197
Rdidentity(&(CMAleaf.Id) ,ConnTbl,Cid,l);
/•envio•/
PackTrama(&CMAleaf,sCmd);
ChanOut(ToServer,sCmd,TRAMA_LEN);
)
else{ /•bOk==TRUE*/
/*No Existe ->Construye el pdu de confirmacion•/
CMAleaf.Primitive=A_RELEASE_confirm;
CMAleaf.MmsPdu.designator=MMSpdu conclude ResponsePDU;
/•Cargo el id en el PDU con el id en la tibla•/
Rdidentity(&(CMAleaf.Id) ,ConnTbl,Cid,O);
/•envio*/
PackTrama(&CMAleaf,sCmd);
ChanOut(ToClnt,sCmd,TRAMA_LEN);
break;
case A MMS Request:
/•••**************~**********************************************"*************/
/••• Peticion de Servicio Confirmado ***/
if(CMAleaf.MmsPdu.designator==MMSpdu_confirmed_RequestP!lU) {
if (CMAleaf.MmsPdu.designator!=MMSpdu confirmed RequentPDU) {
/•if not pdu valido reject.-sustituir por funcion validadora de pdu•/
)
else{
FindConnection (&bOk, &ConnTbl, &Cld, CMAleaf. Id .Assld);
if(bOk==TRUE && ConnTbl[Cid] .State==Associated) {
bOk=ProcessRequest(&CMAleaf,&(ConnTbl[Cld]));
if (bOk==TRUE) {
/•construye el pdu de indication•/
CMAleaf.Primitive=A MMS Indication;
/*Cargo el id en el-PDU-con el id en la tabla*/
Rdidentity(&(CMAleaf.Id) ,ConnTbl,Cid,l);
/•envio*/
PackTrama(&CMAleaf,sCmd);
ChanOut(ToServer,sCmd,TRAMA_LEN);
)
else{
/• Error: no se pudo alojar la peticion*/
CMAleaf.Primitive=A_MMS_Confirm;
)
else{
/*error no existe la asociacion correspondiente,pdu de conf. de serv.conf
e/error•/
CMAle,af.Primitive=A_MMS_Confirm;
}
/*•***********************************************•·············-··············!
/••• Peticion de Servicio Sin Confirmacion ***/
else if(CMAleaf.MmsPdu.designator==MMSpdu Unconfirmed RequestPDU) {
if (CMAleaf.MmsPdu.designator!=MMSpdu_U;confirmed_Re~~estPDU) {
/•if ~ot pdu valido reject.-sustituir por funcion validadora de pdu•/
}
else{
FindConnection(&bOk,&ConnTbl,&Cid,CMAleaf.Id.Assid);
if(bük==TRUE && ConnTbl[Cld] .State==Associated) {
/•Construye el pdu de indication•/
CMAleaf.Primitive=A MMS Indication;
/•cargo el id en el-PDU-con el id en la tabla•/
Rdidentity(&(CMAleaf.Id) ,ConnTbl,Cid,l);
/*envio•/
PackTrama(&CMAleaf,sCmd);
ChanOut(ToServer,sCmd,TRAMA LEN);
)/•elBe no existe la asociaci;;n -> skip•/
}
else{
/*pdu no valido-> reject•/
break;
/******************************************************************************/
/••• Peticion de Servicio Sin Confirmacion •••/
default:
Rd!d ( & ( CM1,leaf. Id) , 1) ; /•leo registro id*/
PackTramai&CMAleaf,sCmd);
ChanOut(ToServer,sCmd,TRAMA_LEN);
break;
)
if(ch==FRSERVER) {
switch (Primitiva) {
/******************************************************************************/
/••• Aviso de Expiracion remota •••/
case LOGOUT Indication: /*Aviso de Expiracion remota•/
ConnTbl[Cld] .MaxSegmentSize=CMAleaf.MmsPdu.u.MMSpdu_initiate_ResponsePDU.negociatedMaxSegmentSize
ConnTbl[Cld] .NegociatedMaxServOutstandingCalled=CMAleaf.MmsPdu.u.MMSpdu_initiate_ResponsePDU.nego
ciatedMaxServOutstandingCalled;
199
ConnTbl[Cid] .NegociatedDataStructureNestingLevel=CMAleaf.MmsPdu.u.MMSpdu_initiate_ResponsePDU.neg
ociatedDataStructureNestingLevel;
'ilrident ity (CMAleaf. Id, &ConnTbl, Cid, O) ;
/*A'Jiso que ya esta la conexion*/
qdrdentity(&(CMAleaf.Id) ,ConnTbl,Cid,O);
?ackTrama(&CMAleaf,sCmd);
ChanOut(ToClnt,sCmd,TRAMA_LEN);
}
else if(CMAleaf.MmsPdu.designator!=MMSpdu_initiate_ResponsePDU) {
/*Error*/
/*el!le skip;*/
}
else(
/* to_link(n] !MAbin_abort PDU,l,k,x3,x4;*/
)
break;
/*******••······································································!
/*** Confirmacion de Liberacion ***/
case A RELEASE confirm:
if (CMAleaf.MmsPdu.designator!=MMSpdu_conclude_ResponsePDU) (
/*if not pdu valido reject*/
)
else{
FindCoLnection(&bOk,&ConnTbl,&Cid,CMAleaf.Id.Assid);
if (bOk= =TRUE ) {
if(ConnTbl[Cid) .State==CallingConc) {
/*Aviso que ya esta desconectado*/
CMAleaf.Primitive=A_RELEASE_confirm;
CMAleaf. MmsPdu. designator=MMSpdu conclude Response:?DU;
/*Cargo el id en el PDU con el id en la tabla•/
Rdidentity(&(CMAleaf.Id) ,ConnTbl,Cid,0);
/*Libero la conexion*/
FreeConnection(&bOk,&ConnTbl,Cid,CMAleaf.Id.Assid)
/*envio*/
PackTrama(&CMAleaf,sCmd);
ChanOut(ToClnt,sCmd,TRAMA LEN);
}/*Si no es CallingConc skip Nunca debe pasar*/
}/*Sino existe skip*/
break;
/············~··················································~···············/
/*** Confirmacion de Servicio Confirmado ***/
case A MMS :onfirm:
/*No importa si la respuesta es afirmativa o negativa•¡'
if (CMAle.:1.f. MmsPdu. designator ! =MMSpdu confirmed Respone1ePDU &&
CMAleaf. MmsPdu. designator ! =MMSpdu- conf irmed-ErrorPt1U) {
/*if not pdu valido reject*/ - -
}
else{
if(bOk=a:TRUE && ConnTbl[Cid] .State==Associated) {
bOk=P:rocessRequest(&CMAleaf,&(ConnTbl[Cid))):
if (bOk==TRUE) {
/*Aviso que el servicio fue exitoso localmente*/
CMA1eaf.Primitive=A MMS Confirm;
CMAleaf.MmsPdu.designator=MMSpdu_confirmed_Respo11.sePDU;
/*Cargo el id en el PDU con el id en la tabla*/
Rdidentity(&(CMAleaf.Id) ,ConnTbl,Cid,O):
/*envio•/
PackTrama ( &CMAleaf, sCmd) ;
ChanOut(ToClnt,sCmd,TRAMA_LEN);
break;
default:
Rdid ( &(CMJ1leaf. Id) , l) ; /*leo registro id*/
PackTrama ,: &CMAleaf, sCmd) :
200
ChanOut(~oServer,sCmd,TRAMA_LEN);
break;
/*** GROUP
/••·············································································!
MMSPRMCF.H ***/
.... /
/• Unidad de Tiempo•/
int timeunit=l5625; /*15625 es un segundo en procesos de prioridad normal*/
/*** ..... /
/***
/***
MMSPRMCO.H ***/
..... /
/*Definicion y manejo tabla de req e ind de cada asociacion•/
typedef struct
Boolean in use;
unsignedlong in;:;:oke_id;
mmpm_fsm_type mmpm_machine_state;
Timer State type TimerState;
}pending_element_type;
typedef pending_element_type request_pending_table_type[MAX_PENDING_REQUEST_NUMBER];
typedef pending_element_type indication_pending_table_type[MAX_PENDING_INDICATION_NUMBER];
return (TRUE);
for (i=O;i<MAX_PENDING_INDICATION_NUMBER;i++)
{
if ( (*the_table[i]) .in_use==FALSE
return (FALSE) ;
201
return (TRUE);
int i,count=O;
for (i=O;i<MAX_PENDING_REQUEST_NUMBER;i++)
{
if ( (*the_table[i]) .in_use==TRUE
count = count: + l;
return (count);
return (count);
int i ·
return (FALSE);
for (i=O;i<MAX_PENDING_INDICATION_NUMBER;i++)
return (FALSE);
for (i=O;i<MAX_PENDING_REQUEST_NUMBER;i++)
int i·
for (i=O;i<MAX_PENDING_INDICATION_NUMBER;i++)
{
if ( (*the_table[i]) .in_use==FALSE
202
int 1 -
for li=O;i<MAX_PENDING_REQUEST_NUMBER;i++)
int i;
for li=O;i<MAX_PENDING_INDICATION_NUMBER;i++)
{
if ( (*the_table[i]) .invoke_id == invoke id
(*the_table[i]) .in_use = FALSE;
for (i=O;i<MAX_PENDING_REQUEST_NUMBER;i++)
{
(*the_table[i)) .in_use = FALSE;
for (i=O;i<MAX_PENDING_INDICATION_NUMBER;i++)
/*** ***/
/*** MMSPRMCl.H ***/
/*** ***/
ConnType Connitem;
/*****************************************************************************/
/* InitiateConnTbl •/
/ * •/
/* •/
/• •/
/*****************************************************************************/
void InitiateCor.nTbl (ConnTblType •connTbl)
{
int i;
for (i=O;i<MAX_CONNECTIONS;i++)
{
(•ConnTbl) (i]. InUse=FALSE;
/• InitiateConnTbl •/
1·················-···························································1
/• ConnTblisFull: •/
/* •/
/* •/
/* •/
/*****************************************************************************/
Boolean ConnTblisFull(ConnTblType *ConnTbl)
{
int i;
for (i=O;i<MAX_CONNECTIONS;i++)
return (TRUE);
/• ConnTblisFull •/
/*****************w***********************************************************/
/• NextAssid: •/
/* •/
/* •/
/• •/
/*****************************************************************************/
Handle NextAssid(ConnTblType •connTbl)
\
int i;
Handle Topid=O;
for (i=O;i<MAX_CONNECTIONS;i++)
if ( •connTbl) [ i] . InUse==TRUE
{
i f ( (*ConnTbl) [i]. Id.Assid>Topid
Topid= (*ConnTbl) [i]. Id.Aseld;
/*****************************************************************************/
/* AddAss: */
/• */
/• */
/• •/
!·············································································!
int AddAss(ConnTblType •connTbl)
int i·
204
for li=O;i<MAX CONNECTIONS;i++)
{ -
if (•ConnTbl) li] .InUse==FALSE
{
( •connTbl) [ i J . InUse=Connitem. InUse;
(•ConnTbl) [i]. Id.Assid=Connitem.Id.Assid;
( •connTbl) [ i] . TimerState=IdleTimer;
break;
return(i)
/• AddAss •/
/*****************************************************************************/
/• FindAss: •/
/• Encuentra el id de la conexion de la asociacion
•/
/• •/
/• •/
/*****************************************************************************/
int FindAss(ConnTblType •connTbl,Handle Assid)
{
int i;
Boolean Hereis=FALSE;
if(Hereis==TRUE)
return(i);
else
return(-1);
/• FindAss •/
/***************************************************************':*************/
/• GetConnection: obtiene la referencia a una associacion •/
/• bRtn. out: resultado de la funcion. •/
/• Connid: in: out: conexion id •/
/********************************************************•••••••,,•••••••••••••/
void GetConnection(Boolean *bRtn,ConnTblType •connTbl,int •connid)
8oolean Ok=FALSE;
int Cid=-1;
*bRtn=FALSE;
Ok=ConnTblisFull(ConnTbl)
i f (Ok=mFALSE)
Connitem. InUse=,TRUE;
Connitem. Id .Ase1Id=NextAssid (ConnTbl)
Cid=AddAss(ConnTbl);
*bRtn= TRUE;
InitiateRqt (& ( ,: •connTbl) [Cid] . PendRqtTbl));
Initiateind(&( :•connTbl) [Cid] .PendindTbl));
•connid=Cid;
/• GetConnection •/
/*****************************************************************************/
/* FindConnection: obtiene la referencia a una associacion */
/* bRtn. out: resultado de la funcion. */
1·············································································1
void FindConnection(8oolean *bRtn,ConnTblType *ConnTbl,int *Connld,Handle Assld)
{
int Cid=-1;
*bRtn=FALSE;
Cid=FindAss(ConnTbl,Assid);
205
if(Cid>=O)
•bRtn= TRUE;
•connid=Cid;
/* FindConnection•/
/************••••·t••··························································/
/* FreeConnection: libera una conexion */
/• bRtn. out: si existía la asociacion TRUE */
1················~····························································1
void FreeConnection(Boolean *bRtn,CoIUlTblType *CoIUlTbl,int Connid,Handle Assid)
{
*bRtn=FALSE;
i f ( ( •connTbl) [Ccmnid] . Id. Assid==Assid)
{
( •connTbl) [Connid] . InUse=FALSE;
•bRtn= TRUE;
/ * Fr,~eConnect ion*/
1················~·············································-··············1
/• Wridentity : Fn utilizada para bajar la identificacion que viene en el */
/* a la tabla de conexion */
1·······························································-··············1
void Wridentity ( IdType Newid, ConnTbl Type *CoilllTbl, int Coilllid, in Param)
1:
{
/•El id Asociacion Local esta en el AssidRmt del Arreglo Newid*/
i f (Param>O) {
( •connTbl) [Connid] . Id. Pid =Newid. PidRmt;
( •CoIUlTbl) [Connid] . Id. AssidRmt=Newid. Ass!d;
(*CoIUlTbl) [Connid] .Id.PidRmt =Newid.Pid;
}
else{
/*El id Asociacion Local esta en el Ass!d del Arreglo Newid•/
( *CoIUlTbl) [Connid] . Id. Pid =Newid. Pid;
(*ConnTbl) [Connid] .Id.AssidRmt=Newid.AssidRmt;
(*ConnTbl) [Connid] .Id.PidRmt =Newid.PidRmt;
/* Wrlclentity •/
/**************************************************************,r**************/
/• Rdidentity : Fn utilizada para subir la identificacion de la tabla de con-*/
/• xion a aleaf •/
/************************************************************••~,•••*•*********/
void Rdidentity(IdType *Newid,ConnTblType CoIUlTbl,int Connld,int Param)
{
/*El id Asociacion va en el AssidRmt del Arreglo Newld*/
i f ( Param>O) {
(*Newld) .Assid=CoIUlTbl[Connid] .Id.AssidRmt;
(*Newid) .Pid=ConnTbl[CoIUlld] .Id.PidRmt;
(*Newid) .AseidRmt=COilllTbl[COilllld] .Id.Aesld;
(*Newld) .PidRmt=ConnTbl[Connid] .Id.Pid;
}
else{
/*El id Asociacion va en el Assid del Arreglo Newid*/
(*Newld) .Assld=CoIUlTbl[Connid] .Id.Assid;
(*Newld) .Pid=COIUlTbl[COIUlld] .Id.Pld;
(*Newid) .AssidRmt=COIUlTbl[COilllld] .Id.AssidRmt;
(*Newld) .PidRmt=COIUlTbl[CoIUlld] .Id.PidRmt;
/* Rdidentity */
/**************************************************************•**************/
/* Wrid : Fn utilizada para bajar la identificacion de los proce,sos */
/******************•···········································i**************/
void Wrid(IdType Newld,int Param)
{
/*Intercambio Local-remoto•/
i f ( Param>O) {
LocalPid=Newid.PidRmt;
RmtPid=Newid.Pid;
}
else{
/*Local-Local*/
LocalPid=Newid.Pid;
206
RmtPid=Newid.PidRmt;
/• Wrld "/
1·······························································•,,•••·········1
/* Rdld : Fn utilizada para subir la identificacion de los procesos •/
1······························································•·,~············1
void Rdid(IdType *Newld,int Param)
{
/*Intercambio Local-remoto•/
if (Param>O) {
(*Newld) .Pld=RmtPid;
(*Newid) .PidRmt=LocalPid;
}
else(
/*Local-Local•/
(*Newld) .Pld=LocalPid;
(*Newld) .PldRmt=RmtPid;
/• Rdld*/
/••• ***/
/••• MMSPRMC4.H ***/
/••• ***/
/*Llena el MmsPdu con parametros locales•/
void FilliniRqtPDU(aleaf •aleaf)
{
( *aleaf) . MmsPdu. do:signator=MMSpdu_initiate_RequestPDU;
(*aleaf) .MmsPdu.u.MMSpdu_initiate_RequestPDU.proposedMaxSegmentSize
=LocalMaxSegmentSize;
(*aleaf) .MmsPdu.u.MMSpdu_initiate_RequestPDU.proposedMaxSegmentSize_present
=LocalMaxSegmentSize_present;
(*aleaf) .MmsPdu.u.MMSpdu_initiate_RequestPDU.proposedMaxServOutstandingCalling
=LocalMaxServOutstandingCalling;
(*aleaf) .MmsPdu.u.MMSpdu initiate RequestPDU.proposedMaxServOutstandingCalled
=LocalMaxServOutstandingCalled; -
(*aleaf) .MmsPdu.u.MMSpdu initiate RequestPDU.proposedDataStructureNestingLevel
=LocalDataStructureNestingLevel; -
(*aleaf) .MmsPdu.u.MMSpdu_initiate_RequestPDU.proposedDataStructureNestingLevel_present=LocalDataS
tructureNestingLevel present;
} -
(*ErrMMSpdu) .u.MMSpdu_initiate_ErrorPDU.errorClass.u.ServiceErro:r_errorClass_t_initiate=NumErr;
break;
/* BuildiniRspPDU: Construye aleaf de respuesta temporal con los parametros MMS local y remoto•/
/• Para procesar despues la respuesta*/
void BuildiniRspPDU(aleaf *RmAleaf)
{
aleaf RspAleaf;
RspAleaf.MmsPdu.u.MMSpdu_initiate_ReeponsePDU.negociatedMaxSegmentSize=(*RmAleaf) .MmsPdu.u.MMSpdu
initiate RequestPDU.proposedMaxSegmentSize;
- if( (*RmAleaf) .MmsPdu.u.MMSpdu_initiate_RequestPDU.proposedMaxSegmentSize_present >
LocalMaxSegmentSize_present )
RspAleaf.MmsPdu.u.MMSpdu_initiate_ResponsePDU.negociatedMaxSegmentSize_preeent=LocalMaxSegmentSiz
e_present;
else
RspAleaf.MmsPdu.u.MMSpdu_initiate_ResponsePDU.negociatedMaxSegmentSize_preeent=(*RmAleafJ .MmsPdu.
u.MMSpdu_initiate_RequestPDU.proposedMaxSegmentSize_present;
if( (*RmAleaf) .MmsPdu.u.MMSpdu initiate RequeetPDU.proposedMaxServOutstandingCalling >
LocalMaxServOutstandingCalling )- -
RspAleaf.MmePdu.u.MMSpdu_initiate_ResponsePDU.negociatedMaxServOutstandingCalling=LocalMaxServOut
standingCalling;
else
RspAleaf.MmsPdu.u.MMSpdu_initiate_ReeponeePDU.negociatedMaxServOJtstandingCalled=LocalMaxServOuts
tandingCalled;
else
RspAleaf.MmePdu.u.MMSpdu_initiate_ReeponeePDU.negociatedDataStructureNeetingLevel=(*RmAleaf) .MmsP
du.u.MMSpdu_initiate_RequestPDU.propoeedDataStructureNestingLevel;
if((*RmAleaf) .MmsPdu.u.MMSpdu_initiate_RequeetPDU.proposedDataSt:,uctureNestingLevel_present>Local
DataStructureNestingLevel_present)
/*** ***/
/*** MMSPARAM.H •••/
/••• ***/
#define LocalMaxSegmentSize 310
#define LocalMaxSegmentSize_preeent 1
#define LocalMaxServOutstandingCalling 311
#define LocalMaxServOutstandingCalled 312
#define LocalDataStructureNestingLevel 313
#define LocalDataStructureNestingLevel_present 1
11.6 FEEDER.H
/***************************************************************;'**************/
/********** Proceso Feeder **********/
/********** **********/
void feeder_proc(Procese • p,Channel •e)
208
FILE *FComandos;
char sComandos[9];
tTrama sCmd,sTempo;
tStackTrama sCmdBuff;
int i,j,iComando=O;
int nTop,nCountAc,nCount;
p = p;
printf("\nArchivo de Comandos del Cliente: ");
gets(sComandos);
i f ( ( FComandos =f open ( sComandos, "r" ) ) == NULL )
(
printf("\nimposible Abrir Archivo: 'iis",sComandos);
ChanOut(c,sFIN,TRAMA_LEN);
exit(EXIT_FAILURE);
fseek(FComandos,O,SEEK_SET);
while(!feof(FComandos))
(
nCountAc=O;
while(nCountAc<TRAMA LEN) {
if(fscanf(FComandos,"%s%n",sTempo,&nCount)<=0) {
nCountAc=-1;
ncount=O;
break;
}
else{
if(nCountAc+nCount<TRAMA_LEN)
nTop=nCountAc+nCount;
else
nTop=TRAMA LEN;
for(j=nCountAc;j<nTop;j++) {
sCmd[j:=sTempo[j-nCountAc];
nCountAc=nCountAc+nCount;
if (nCountAc<O)
break;
sCmd[TRAMA LEN-1]='\0';
if (iComando<MAX_COMMAND) {
Mstrcpy(sCmdBuff[iComando] ,sCmd);
printf(" \nComando es :");
for(j=O;j<TRAMA_LEN;j++) {
printf ( "'iic", sCmdBuff [iComando] [j 1);
if (iComando==MAX COMMAND){
printf("\nMax.(%d) .Num.Cmds.Alcanzados!",iComando);
break;
iComando++;
fclose(FComandos);
printf ( "Archivo Cerrado\n");
for (i=O;i<iComando;i++){
sCmdBuff [iCcmando] [TRAMA_LEN-1] ='\O';
Mstrcpy(sCmd,sCmdBuff[i]);
ChanOut(c,sCmd,TRAMA_LEN);
ChanOut(c,sFIN,TRAMA_LEN);
11.7 TRXBUFF.H
TxTrama Buffer[LEN_CHAN*3];
/••············································································/
/****'****** Proceso Rx **********/
/•••••••••• Enacargado de emular un canal de longitud n **********/
void RxProc (Process • p,Channel *FrCanall,int TrxNumb,int *bKeepGoing,int imas) {
int index,offset:
209
t.Trama sCmd;
aleaf SMAleaf;
int count=O;
p = p;
offset~(TrxNumb·l)•LEN_CHAN;
index=offset;
while ( (*bKeepGoing)) {
if(Buffer[index] .Usado==TRUE) (
ProcWait(TRX_WTIME);
)
else{
Chanin(FrCanall,sCmd,TRAMA_LEN);
count++;
if (strncmp(sFIN,sCmd,3)==0) {
Mstrcpy(Buffer[index] .Trama,sCmd);
Buffer[index] .Usado=TRUE;
( *bKeepGoing) =FALSE;
)
else{
UnpackTrama(&SMAleaf,sCmd);
SMAleaf.Id.Pid=SMAleaf.Id.Pid+imas;
PackTrama(&SMAleaf,sCmd);
Mstrcpy(Buffer[index] .Trama,sCmd);
Buffer[index] .Usado=TRUE;
index=(index-offset+l)%LEN_CHAN;
index=index+offset;
return;
1·····························································-················1
/********** Proceso Tx **********/
/********** Enacargado de emular un canal de longitud n **********/
void TxProc (Procese* p,Channel *ToCanal2,int TrxNumb,int *bKuepGoing,int imas) {
int index,offset;
tTrama sCmd;
aleaf SMAleaf;
p = p;
offset=(TrxNumb-l)*LEN CHAN;
index=offset; -
while (*bKeepGoing){
if(Buffer[index] .Usado=•TRUE) {
Mstrcpy(sCmd,Buffer[index] .Trama);
UnpackTrama(&SMAleaf,sCmd);
if (strncmp(sFIN,sCmd,3)•=0) (
break;
)
SMAleaf.Id.Pid=SMAleaf.Id.Pid+imas;
PackTrama(&SMAleaf,sCmd);
/* printf("TXl:ld",imas) ;*/
Chan0Ut(ToCanal2,sCmd,TRAMA_LEN);
Buffer[index] .Usado•FALSE;
index•(index-offset+l)%LEN CHAN;
index•index+offset; -
)
else(
ProcWait(TRX_WTIME*4);
11.8 MMSDECOD.H
return;
switch(nEntidad) {
case O:
strcpy(Node, "Server");
break;
case l:
etrcpy(Node,"Client");
break;
Getlnfo(&P.Pdusw,Info);
switch(P.PduSw.Primitive) {
211
case DUMMY Primitive:
printf("\n%s: DUMMY_Primitive\tid= %d\tRid=
%d\n\t%s",Node,P.PduSw.Id.Pid,P.PduSw.Id.PidRmt,Info);
break;
case LOGIN Request:
printf("\n%s: LOGIN_Request\tld= %d\tRid=
%d\n\t%s",Node,P.PduSw.Id.Pid,P.PduSw.Id.PidRmt,Info);
break;
case LOGIN Indication:
printf("\n'!is: LOGIN_Indication\tid= %d\tRid=
%d\n\t%s",Node,P.PduSw.Id.Pid,P.PduSw.Id.PidRmt,Info);
break;
case LOGIN Confirm:
printf("\n'!<s: LOGIN Confirm\tid= 'lrd\tRid=
%d\n\t%s",Node,P.PduSw.Id.Pid,P.PduSw.Id.PidRmt,Info);
break;
case LOGIN ConfirmErr:
printf("\n%s: LOGIN_ConfirmErr\tid= %d\tRid=
%d\n\t%s",Node,P.PduSw.Id.Pid,P.PduSw.Id.PidRmt,Info);
break;
case LOGOUT Request:
printf("\n%s: LOGOUT_Request\tid= %d\tRid=
%d\n\t%s",Node,P.PduSw.Id.Pid,P.PduSw.Id.PidRmt,Info);
break;
case LOGOUT Indication:
printf("\n%-s: LOGOUT_Indication\tid= %d\tRid=
%d\n\t%s",Node,P.PduSw.Id.Pid,P.PduSw.Id.PidRmt,Info);
break;
case LOGOUT Confirm:
printf("\n'ks: LOGOUT_Confirm\tid= %d\tRid=
%d\n\t%s",Node,P.PduSw.Id.Pid,P.PduSw.Id.PidRmt,Info);
break;
case A ASSOCIATE request:
printf("\n%s: A ASSOCIATE request\tid= %d\tRid= %d\tAs= %d\tRAs=
%d\n\t%s",Node,P.PduSw.Id.Pid,P-:-PduSw.Id.PidRmt,
P. Pd,.1Sw. Id. Ass!d, P. Pdusw. Id. AssidRmt, Info) ;
break;
case A- ASSOCIATE - indication:
printf ( "\n%-s: A_ASSOCIATE_indication\tid= %d\tRid= %d\t.A.s= %d\tRAB•
%d\n\t%s",Node,P.PduSw.Id.Pid,P.PduSw.Id.PidRmt,
P.PduSw.Id.Assid,P.PduSw.Id.AssidRmt,Info);
break;
case A ASSOCIATE response:
printf("\n%s: A ASSOCIATE response\tid= %d\tRid= %d\tAs= %d\tRAs=
id\n\t'iís",Node,P.PduSw.Id.Pid,P-:-PduSw.Id.PidRmt,
P.PduSw.Id.Assid,P.PduSw.Id.AssidRmt,Info);
break;
case A- ASSOCIATE - confirm:
printf("\n%s: A ASSOCIATE confirm\tid= %d\tRid= %d\tAs= %d\tRAB=
%d\n\t%s",Node,P.PduSw.Id.Pid,P-:-PduSw.Id.PidRmt,
P.PduSw.Id.Assid,P.PduSw.Id.AssidRmt,Info);
break;
case A RELEASE request:
printf("\n%s-;- A RELEASE request\tid= %d\tRid= 'ird\tAs= %d\tRAa=
%d\n\t%s",Node,P.PduSw.Id.Pid-:-P.PduSw.Id.PidRmt,
P.PduSw.Id.Assid,P.PduSw.Id.AssidRmt,Info);
break;
case A RELEASE indication:
printf("\n%s-;- A RELEASE indication\tid= %d\tRid= %d\tAs" %d\tRAa=
%d\n\t%s",Node,P.PduSw.Id.Pid-:-P.PduSw.Id.PidRmt,
P.PduSw.Id.Assid,P.PduSw.Id.AaaidRmt,Info);
break;
case A RELEASE response:
printf ( "\n%s-;- A_RELEASE_responae\tid= %d\tRid= %d\tAa= 1,d\tRAa=
%d\n\t%s",Node,P.PduSw.Id.Pid,P.PduSw.Id.PidRmt,
P.PduSw.Id.Assid,P.PduSw.Id.AssidRmt,Info);
break;
case A RELEASE confirm:
printf("\n%s-:- A RELEASE confirm\tid= %d\tRid= %d\tAB= %d\tRAB=
%d\n\t%s",Node,P.PduSw.Id.Pid-:-P.PduSw.Id.PidRmt,
P.PduSw.Id.Assid,P.PduSw.Id.AssidRmt,Info);
break;
case A_MMS_Request:
212
printf("\n%s: A MMS Request\tid= %d\tRid= %d\tAB= %d\tRAB=
td\n\t%s",Node,P.PduS;.Id-:-Pid,P.PduSw.Id.PidRmt,
P.PduSw.Id.Assid,P.PduSw.Id.AssidRmt,Info);
break;
case A MMS Indication:
printf("\n%s: A_MMS_Indication\tid= %d\tRid= 'i!d\tAs= 'i!d\tRAs=
%d\n\t%s",Node,P.PduSw.Id.Pid,P.PduSw.Id.PidRmt,
P.PduSw.Id.Assid,P.PduSw.Id.AssidRmt,Info);
break;
case A MMS Response:
printf("\n%s: A_MMS_Response\tid= %d\tRid= 'lld\tAs= %d\tRAs"
%d\n\t%s",Node,P.PáuSw.Id.Pid,P.PduSw.Id.PidRmt,
P. PduS1,,·. Id. Assid, P. Pdusw. Id. AssidRmt, Info) ;
break;
case A MMS Confirm:
printf ( "\n%s: A MMS Confirm\tid= %d\tRid= 'i!d\tAs= %d\tRAs=
%d\n\t%s",Node,P.PduS;.Id-:-Pid,P.PduSw.Id.PidRmt,
P.PduSw.Id.Assid,P.PduSw.Id.AssidRmt,Info);
break;
default:
printf("\n%s: Unknown\tid= %d\tRid= %d",Node,P.PduSw.Id.Picl,P.PduSw.Id.PidRmt);
break;
11.9 MMSPDUTR.H
if(trama[TRAMA_LEN-2]==VALIDO[O]){
strcpy(sVal, "+");
}
else if(trama[TRAMA_LEN-2]==INVALIDO[O]) {
s t rcpy ( sVal, " - " ) ;
else {
strcpy(sVal," ");
PduSwapTra.TramSw[TRAMA_LEN-1]='\0';
•pdu=PduSwapTra.PduSw;
trama[TRAMA_LEN-1]='\0';
•pdu=PduSwapTra.PduSw;
215
11.10 MMSPDU.H
typedef struct
ObjectName Choice designator;
union { -
Identifier ObjectName vmd specific;
etruct { - -
Identifier domainid;
Identifier itemid;
ObjectName_domain_specific;
u;
ObjectName;
t 1 pedef struct {
Identifier programinvocationName;
Stop_Request;
216
typedef Null Start_Response;
typedef struct {
Identifier programinvocationName;
Start_Request;
typedef struct {
VariableSpecific:ation_Choice designator;
union {
ObjectName VariableSpecification_name;
) U;
VariableSpecification;
typedef struct {
VariableSpecification variableSpecificatn;
Values_VariableAccessSpecification_listOfVariable_t;
typedef struct {
VariableAccessSpecification Choice designator;
union { -
struct {
unsignedlong length;
Values VariableAccessSpecification listOfVariable t data[max listOfVariable);
VariableAccessSpecification_listOfVariable; - -
ObjectName VariableAccessSpecification_variableListName;
u;
VariableAccessSpecification;
typedef struct {
Boolean specificationWithResult;
VariableAccessSpecification variableAccessSpecificatn;
Read_Request;
typedef struct {
Values Write Response Choice designator;
union T - -
DataAccessError Values_Write_Response_failure;
Null Values_Write_Response_success;
} u;
Values_Write_Response;
typedef struct {
unsignedlong length;
Values_Write_Response •data;
Write_Response;
typedef struct {
Data Choice designator;
union {
Boolean Data_booleant;
Integer Data_integert;
Integer Data_unsigned;
OctetString Data_octet_string;
VisibleString Data_visible_string;
U;
Data;
typedef struct
VariableAccessSpecification variableAccessSpecificatn;
struct {
unsignedlong length;
Data •data;
listOfData;
Write_Request;
typedef struct {
AccessResult_Choice designator;
union {
DataAccessError AccessResult failure;
Data AccessResult success;
U;
AccessResult;
217
typedef struct {
VariableAccessSpecification variableAccessSpecificatn;
int variableAccessSpecificatn present;
struct { -
unsignedlong length;
AccessResult *data;
listOfAccessResult;
Read_Response;
typedef struct (
OctetString loadData;
Boolean moreFollows;
DownloadSegment_Response;
typedef struct {
Identifier domainName;
Boolean discard;
TerminateDownloadSequence_Request;
typedef struct
Identifier domainName;
struct {
unsignedlong length;
VisibleString *data;
listOfCapabilities;
Boolean sharable;
InitiateDownloadSequence_Request;
typedef struct {
Unsigned32 originalinvokeID;
int originalinvokeID_present;
struct {
RejectPDU rejectReason Choice designator;
union { - -
Integer RejectPDU_rejectReason_confirmed_requestPDU;
Integer RejectPDU rejectReason confirmed responsePDU:
Integer RejectPDU=rejectReason=confirmed=errorPDU;
Integer RejectPDU rejectReason pdu error;
Integer RejectPDU=rejectReason=conclude_requestPDU;
Integer RejectPDU_rejectReason_conclude_responsePDU;
Integer RejectPDU rejectReason conclude errorPDU;
Integer RejectPDU=rejectReason=initiate=requestPDU;
u·
rejectReason;
RejectPDU;
typedef struct
struct {
ServiceError errorClass t Choice designator;
union { - - -
Integer ServiceError errorClass t vmd state;
Integer ServiceError-errorClass-t-application reference;
Integer ServiceError=errorClass=t=definition;-
Integer ServiceError errorClass t resource;
Integer ServiceError=errorClass=t=service;
Integer ServiceError_errorClass_t_service_preempt;
Integer ServiceError_errorClass_t_time_resolution;
Integer ServiceError_errorClass_t_accesst;
Integer ServiceError_errorClass_t_initiate;
Integer ServiceError_errorClass_t_conclude;
Integer ServiceError_errorClass_t_otherst;
u·
} errorClass;
Integer additionalCode;
int additionalCode_present;
VisibleString additionalDescription;
int additionalDescription_present;
218
ServiceError;
typedef struct {
Integer32 negociatedMaxSegmentSize;
int negociatedMaxSegmentSize_present;
Integer16 negociatedMaxServOutstandingCalling;
Integer16 negociatedMaxServOutstandingCalled;
IntegerB negociatedDataStructureNestingLevel;
int negociatedDataStructureNestingLevel_preaent;
Initiate_ResponsePDU;
typedef struct {
Integer32 proposedMaxSegmentSize;
int proposedMaxSegmentSize_present;
Integer16 proposedMaxServOutstandingCalling;
Integer16 proposedMaxServOutstandingCalled;
IntegerB proposedDataStructureNeatingLevel;
int proposedDataStructureNeatingLevel_preaent;
Initiate_RequestPDU;
typedef struct {
ConfirmedServic:eResponse Choice deaignator;
union { -
Read_Response ConfirmedServiceResponae_read;
Write Response ConfirmedServiceReaponae write;
InitiateDownloadSequence Response ConfirmedServiceReaponae initiateDownloadSequence;
DownloadSegment Reaponae-ConfirmedServiceReaponae downloadSegment;
TerminateDownloadSequence_Response ConfirmedServiceResponae_terminateDownloadSequence;
Start Response ConfirmedServiceReaponae atart;
Stop_Response ConfirmedServiceReaponse_stop;
U;
ConfirmedServiceResponse;
typedef struct {
ConfirmedServiceRequest Choice designator;
union { -
Read Request ConfirmedServiceRequest read;
Writ; Request ConfirmedServiceRequest write;
InitiateDownloadSequence Requeat ConfirmedServiceRequeat initiateDownloadSequence;
DownloadSegment Request ConfirmedServiceRequeat downloadSegment;
TerminateDownloadSequence_Request ConfirmedServiceRequeat_terminateDownloadSequence;
Start_Request ConfirmedServiceRequest_atart;
Stop_Request ConfirmedServiceRequest_stop;
U;
ConfirmedServiceRequest;
typedef struct {
Unsigned32 invokeID;
ServiceError serviceError;
Confirmed_ErrorPDU;
typedef struct {
Unsigned32 invokeID;
ConfirmedServiceResponse field_2;
Confirmed_ResponsePDU;
typedef struct {
Unsigned32 invokeID;
ConfirmedServiceRequest field_2;
Confirmed_RequestPDU;
typedef struct {
MMSpdu Choice designator;
union {
Confirmed RequestPDU MMSpdu confirmed RequestPDU;
Confirmed=ResponsePDU MMSpdu_confirmed_ResponaePDU;
219
Confirmed_ErrorPDU MMSpdu_confirmed_ErrorPDU;
RejectPDU MMSpdu reject PDU;
Initiate_RequestPDU MMSpdu_initiate_RequestPDU;
Initiate ResponsePDU MMSpdu initiate ResponeePDU;
Initiate=ErrorPDU MMSpdu_initiate_Er~orPDU;
Conclude_RequestPDU MMSpdu_conclude_RequestPDU;
Conclude_ResponsePDU MMSpdu_conclude_ReeponeePDU;
Conclude ErrorPDU MMSpdu_conclude_ErrorPDU;
U;
MMSpdu;
#endif
11.11 MMSTYPES.H
/•BEGIN MY TYPES•/
typedef char tTrama[TRAMA_LEN]; /*Comando eventualmente MMS
typedef tTrama tStackTrama[MAX_COMMAND]; /*Stack de comandos
•/
typedef struct
int Usado;
tTrama Trama;
}TxTrama;
typedef TxTrama TxBuffer[LEN_CHAN]; /•stack de coma::idoe
*/
/•END MY TYPES*/
11.12 MMSCTES.H
/* BEGIN MY CONSTANTS*/
/••••••••••OJOOJOOJOOJOOJOOJOOJOOJOOJOOJO:cambiar en ECHO.occ LACTE CORRES*/
#define TRAMA LEN 50 /*Longitud de la Trama a tx */
#define FALSE o /•boleano falso */
#define TRUE 1 /*boleano verdero */
#define MAX COMMAND 15 /*Numero máximo de comando a tx */
#define LEN CHAN 3 /*Longitud de Canal •/
#define TRX WTIME 2 /*Tiempo en ticks de espera en la emula- •/
/•cion de canal de longitud LEN CHAN */
220
#define CENT WTIME 20*TRX WTIME /•Tiempo en ticks de espera la e!1pera del */
/•proceso centinela •/
#define sFIN FIN"
11
/•Mensaje para teminar la Tx */
#define FROMSERVER 11g11 /**/
#define FROMSMMSPM IIMII /**/
#define FROMCLIENT .. e" /**/
#define FROMCMMSPM 11p11 /**/
#define VALIDO 11v11 /**/
#define INVALIDO II I II
/**/
/• END MY CONSTANTS*/
11.13 MMSPRIMI.H
/•primitives•/
#define A_MMS_Request A PrimitivePrefix + 31
#define A_MMS_Indication A-PrimitivePrefix + 32
#define A_MMS_Response A-PrimitivePrefix + 33
#define A MMS Confirm A=PrimitivePrefix + 34
/*primitives•7
/• ...........•... MMMS PRIMITIVAS *************** */
/•Peticiones*/
#define M_initiate_request PrimitivePrefix + o
#define M conclude request PrimitivePrefix + 1
#define M-read reqÜest PrimitivePrefix + 2
#define M-write request PrimitivePrefix + 3
#define M-start-request PrimitivePrefix + 4
#define M-stop request PrimitivePrefix + 5
#define MMS_Request PrimitivePrefix + 6
/*Indicaciones•/
#define M initiate indication PrimitivePrefix + 7
#define M=conclude=indication PrimitivePrefix + e
#define M read indication PrimitivePrefix + 9
#define M=write_indication PrimitivePrefix + 10
#define M_start indication PrimitivePrefix + 11
#define M_stop_indication PrimitivePrefix + 12
/•Respuestas•/
223
#define M- initiate __ response PrimitivePrefix + 15
#define M- conclude response PrimitivePrefix + 16
#define M read _response PrimitivePrefix + 17
#define M write _response PrimitivePrefix + 18
#define M- start _response PrimitivePrefix + 19
#define M_stop_response PrimitivePrefix + 20
#define MMS_Response PrimitivePrefix + 21
/• Confirmaciones •/
#define M- initiate - confirm PrimitivePrefix + 22
#define M- conclude- confirm PrimitivePrefix + 23
#define M read confirm PrimitivePrefix + 24
#define M write - confirm PrimitivePrefix + 25
#define M start confirm PrimitivePrefix + 27
#define M_stop_ confirm PrimitivePrefix + 28
11.14 ECHO.OCC
[SO)BYTE string:
INT i:
SEQ
i .- o
WHILE TRUE
SEQ
input? string
wait (10)
output ! string
12 APÉNDICE D
12.1 RDCMDS.C
#include 11
mmsprim.l.h 11 /* Primitivas MMS */
#include 11
mmsctes.h 11 /* Constante MMS */
#include 11
mmstypes. h II
/* Tipos MMS */
#include "mmspdu.h" /* Definicion PDU MMS */
#include "mmetype2 .h" /* Tipos MMS */
#include "mmepdutr.h" /* Fns de Convereion de MMSPDU a un etring */
#include <BtdiO.h>
#include <Btring.h>
#include <Btdlib.h>
int main ()
{
#define sStop "&"
FILE *FCmdCtrl;
char sCmdCtrl[9];
tTrama sCmd;
tTrama sTempo;
aleaf WrtAleaf;
int j,nTop,nCountAc,nCount=O;
printf("\nArchivo de Comandos del Cliente: ");
gets ( sCmdCtrl) ;
if ( (FCmdCtrl=fopen(sCmdCtrl, "r")) == NULL )
{
printf("\nlmposible Abrir Archivo: %s",sCmdCtrl);
exit(EXIT_FAILURE);
fseek(FCmdCtrl,O,SEEK_SET);
while(!feof(FCmdCtrl))
nCountAc=O;
while(nCountAc<TRAMA LEN){
if(fscanf(FCmdCtrl~"%s%n",sTempo,&nCount)<=Ol {
nCountAc=-1;
ncount=O;
break;
}
else{
if(nCountAc+nCount<TRAMA_LEN)
nTop=nCountAc+nCount;
else
nTop=TRAMA LEN;
for(j=nCountAc;j<nTop;j++) (
sCmd[j]=sTempo[j-nCountAc];
}
printf("\ncount:%d\tcountac:%d\tTop%d",nCount,nCountAc:,nTop);
nCountAc=nCountAc+nCount;
if (nCountAc<O)
break;
printf("\tTrama: ");
for(j=O;j<TRAMA_LEN;j++) {
printf ("%e", sCmd [j l);
UnpackTrama(&WrtAleaf,sCmd);
printf("\nNbRx: %d Prim: %d Pid: %d PidRmt: %d Ass: %d AsnRmt: %d PDU: %d",
nCountAc,WrtAleaf.Primitive,
WrtAleaf.Id.Pid,WrtAleaf.Id.PidRmt,
WrtAleaf.Id.Assld,WrtAleaf.Id.AssidRmt,
WrtAleaf.MmsPdu.designatorl;
226
fclose(FCmdCtrl);
printf("\nArchivo Cerrado\n");
exit(EXIT_SUCCESS);
12.2 WRCMDS.C
for (;;) {
printf("\n ");
printf("\n ");
printf(''\n*********************************************' 1 ) ;
printf("\n );
printf ( "\n );
printf ( "\n Manufacturing Message Specification );
printf ( "\n Generador de Archivos de Comandos );
printf("\n );
printf("\n );
printf("\n 1 PeticiondeAsociaci6n. );
printf ("\n 2 Peticion de Liberación. );
printf("\n 3 Peticion de Servicio Confirmado. );
printf("\n 4 Peticion de Serv. No Confirmado. );
printf("\n 9 DummyPrimitiva. );
printf("\n O Salir. );
printf("\n );
printf("\n );
printf( 11 \n********************************************* ) ;
printf("\n ");
printf("\n ");
printf("\n ");
printf("\n ");
printf ( "\nSu Opcion es: ");
gets(sAnswer);
iAnswer=sAnswer[O];
switch(iAnswer) {
case 48:
return(FALSE);
break;
case 49:
WrtAleaf.Primitive=A_ASSOCIATE_request;
WrtAleaf.Id.Assid=O;
WrtAleaf.Id.AssidRmt=O;
WrtAleaf.Id.Pid=iPid~
WrtAleaf.Id.PidRmt=O;
WrtAleaf.MmsPdu.designator=MMSpdu_initiate_RequestPDU;
PackTrama(&WrtAleaf,sCmd);
return (TRUE) ;
break;
case SO:
WrtAleaf.Primitive=A_RELEASE_request;
WrtAleaf.Id.Pid=iPid;
WrtAleaf.Id.PidRmt=O;
WrtAleaf.Id.Assid=l;
227
WrtAleaf.Id.AssidRmt=O;
WrtAleaf.MmsPdu.designator=MMSpdu_conclude_RequestPDU;
PackTrama(&WrtAleaf,sCmd);
return(TRUE);
break;
case 51:
WrtAleaf.Primitive=A_MMS_Request;
WrtAleaf.Id.Pid=iPid;
WrtAleaf.Id.PidRmt=O;
WrtAleaf.Id.Assid=l;
WrtAleaf.Id.AssidRmt=O;
WrtAleaf.MmsPdu.designator=MMSpdu_confirmed_RequestPDU;
PackTrama(&WrtAleaf,sCmd);
return (TRUE) ;
break;
case 52:
WrtAleaf.Primitive=A_MMS_Request;
WrtAleaf.Id.Pid=iPid;
WrtAleaf.Id.PidRmt=O;
WrtAleaf.Id.Assid=l;
WrtAleaf.Id.AssidRmt=O;
WrtAleaf.MmsPdu.designator=MMSpdu_Unconfirmed_RequestPDU;
PackTrama(&WrtAleaf,sCmd);
return (TRUE) ;
break;
case 57:
WrtAleaf.Primi.tive=DUMMY Primitive;
WrtAleaf.Id.Pid=iPid;
WrtAleaf.Id.PldRmt=O;
WrtAleaf.Id.Assid=-1;
WrtAleaf.Id.AssidRmt=-1;
PackTrama(&WrtAleaf,sCmd);
return (TRUE) ;
break;
int main ()
{
#define sStop "&"
FILE *FCmdCtrl;
char sCmdCtrl[9];
tStackTrama sCmdBuff;
aleaf WrtAleaf;
int i=O,iCount=O;
if(MAX_COMMAND<2) {
printf("\nNumero de Comandos de Archivo Insuficiente!!!");
exit(O);
ClrPdu(&WrtAleaf);
for(i=O;i<MAX_COMMAND;i++) {
PackTrama(&WrtAleaf,sCmdBuff[i]);
i=O;
printf("\nArchivo de Comandos del Cliente:");
gets(sCmdCtrl);
print f ( "\nNumero de Proceso: ") ;
scanf("id",&iPid);
WrtAleaf.Primitive=LOGIN_Request;
WrtAleaf.Id.Pid=iPid;
WrtAleaf.Id.PidRmt=O;
WrtAleaf.Id.Assid=O;
WrtAleaf.Id.AssidRmt=O;
PackTrama(&WrtAleaf,sCmdB~ff[i]);
i-i+l;
iCount=i;
while(i<MAX COMMAND-2) {
if(Menu(sCmdBuff[i])){
i=i+l;
iCount=i;
else
break;
228
WrtAleaf.Primitive=LOGOUT_Request;
WrtAleaf.Id.Pid=iPid;
WrtAleaf.Id.PidRmt=O;
WrtAleaf.Id.Assid=O;
WrtAleaf.Id.AssidRmt=O;
PackTrama(&WrtAleaf,sCmdBuff[i]);
i=i+l;
iCount=i;
i f ( (FCmdCtrl=fopen(sCmdCtrl, "w")) NULL)
{
printf("\nimposible Abrir Archivo: 'iss",sCmdCtrl¡;
exit(EXIT_FAILURE);
fseek(FCmdCtrl,O,SEEK SET);
for(i=O;i<iCount;i++){
if (fwrite(sCmdBuff[i] ,TRAMA LEN,l,FCmdCtrl)==O){
print f ( "\nError al escribi~ en el Archivo: 'iss", sCmdCtrl: ;
exit(EXIT_FAILURE);
}
if (fwrite(sFIN,l,l,FCmdCtrl)~•O) {
printf ( 11 \nError al escribir en el Archivo: 'isa", sCmdCtrl:;
exit(EXIT_FAILURE);
}
if ( fprintf (FCmdCtrl, "\n") ==EOF) {
printf("\nError al escribir en el Archivo: 'iss",sCmdCtrl);
exit(EXIT_FAILURE);
}
fclose(FCmdCtrl);
printf("\nArchivo 'isa Cerradot !\nNúmero de PDU's: 'isd",sCmdCtrl,iC:ount);
exit(EXIT_SUCCESS);
229
13 APÉNDICE E
13.1 MMS.PGM
#INCLUDE "occonf.inc"
PROTOCOL TRX IS ANY:
VAL number.of.TBOS IS l:
(number.of.TBOS)NODE TBOS:
NODE t225:
ARC Hostlink:
NETWORK
DO
DO i=O FOR number.of.TBOS
SETTBOS[i) (type, memsize := "TBOS",2*M)
SET t225 (type, memsize : = "T225", 16*K)
CONNECT TBOS(O) [link) [O) TO HOST WITH Hostlink
CONNECT TBOS (O) [link] [2] TO t225 [link] [l]
- -CONNECT t225 [link) (2) TO TBOS (1) [link) (1)
NODE root.p:
NODE client.p:
NODE echol.p:
NODE echo2.p:
MAPPING
DO
MAP root.p ONTO TBOS(O]
MAP client.p ONTO TBOS[O)
MAP echol.p ONTO t225
MAP echo2.p ONTO t225
#INCLUDE "hostio.inc"
#USE "root.lku"
#USE "client.lku"
#USE "echo.lku"
CONFIG
CHAN OF. SP fs, ts :
PLACE fa, ts ON Hostlink
--Relacionados con el Servidor
CHAN OF TRX Echo.tc,.RxlSmmspm,Smmspm.to.Echo:
--Relacionados con el Cliente
CHAN OF TRX Echo.to.RxlCmmapm,Cmmapm.to.Echo: --Ch's Cliente
--Relacionados con el Feeder
CHAN OF TRX Feed.to.Client: --Ch's feeder
--Relacionados con el Monitor
CHAN OF TRX Cmmspm.to.Mon,Client.to.Mon:
PAR
PROCESSOR root.p
root.occ(fs, ta,
Echo.to.RxlSmmspm,Smmspm.to.Echo,
Feed.to.Client,Client.to.Mon,Cmmspm.to.Mon)
PROCESSOR client.p
client.occ(Echo.to.RxlCmmspm,Cmmspm.to.Echo,
Feed.to.Client,Client.to.Mon,Cmmspm.to.Mon)
PROCESSOR echol.p
echo(Smmspm.to.Echo,Ec~o.to.RxlCmmspm)
PROCESSOR echo2.p
echo(Cmmspm.to.Echo,Echo.to.RxlSrmnapm)
230
13.2 RDCMDS.CFS
input Host!nput;
output HostOutput;
/* Mapping description */
13.3 WRCMDS.CFS
input Hoet!nput;
~utput HostOutput;
/* Mapping deecription •/
14 APÉNDICE F
Para generar esta aplicación se requiere tanto del paquete de gener,lción de Código tool c como de
Occam; para su correcto uso se deben establecer las siguientes variables de ambiente según
corresponda.
Opcionalmente puede usar los siguientes archivos por lotes para crear la aplicación:
CO.BAT realiza los pasos 1 a 5 de la lista anterior.
CC.BAT realiza los pasos 7 a 10 de la lista anterior.
CP.BAT realiza los pasos 12 a 14 de la lista anterior.
Esta aplicación es un sencilla y sólo se requiere de C para generarla. Los pasos que se debe
seguir para la obtención del archi~o ejecutable en el procesador transputer son:
Opcionalmente puede usar el archivo por lotes CW.BAT para realizar los pasos 2-6.
Para generar Rdcmds.btl es suficiente contar con el paquete Tool C y seguir los siguientes pasos:
Opcionalmente puede usar el archivo por lotes CR.BAT para realizar los pasos 2-6.
Si se han establecido las variables de ambiente para C teclee la sjguiente linea en el prompt de
DOS para correr el programa mms.btl:
El programa solicita el archivo de comandos MMS a procesar, mostrand,, las siguientes lineas:
C:\TESIS\PROGS\MMS7\PROT02>iserver
Archivo de Comandos 1 del Cliente:
Esta aplicación genera un archivo de comandos con el formato MMS p,ua que las aplicación mms .btl
pueda procesarlo; para ejecutarlo puede teclearse la siguiente linea en el prompt de DOS si se
han establecido las variables de ambiente para C.
Al ejecutarse, el programa solicita el nombre del archivo que se desea generar y el número de
proceso que tendrá el cliente; Como ejemplo se designó el nombre 987 al archivo y 512 para el
identificador del proceso.
l. Numero de Proce110:14
Una vez alimentados estos datos, el sistema muestra·e1 Menú general de los comandos disponibles,
como se muestra a continuación:
*********************************************
Manufacturing Message Specification
Generador de Archivos de Comandos
1 Peticion de 1,sociaci"n.
2 Peticion de I,iberaci"n.
3 Peticion de Servicio Confirm:1.do,.
4 Peticion de ~:erv. No Confirmado.
9 DummyPrimitiva.
o Salir.
*********************************************
Su Opciones: O
El programa solicita el tipo de mensaje que se quiere escribir en el archivo; Existen varios
tipos de mensajes según MMS, sin embargo, para propósito de demostración del protocolo MMS se han
agrupado estos tipos según el tipo de que se trate, por ejemplo, existe el mensaje READ, WRITE
sin embargo su tipo puede ser Servicio Confirma o Servicio Sin Confirmación.
Después de haber seleccionado el tipo de mensaje que se desea grabar, el sistema vuelve a
presentar el Menú principal para que un nuevo comando sea grab:1.do; la operación anterior se
repite hasta que el usuario Teclea O, después de lo cual, el sistE,ma reporta cuantos mensajes se
escribieron en total, en una pantalla parecida a la siguiente:
Esta aplicación es usada opcionalmente para leer los comando grabados con la aplicación wrcmds.
Al igual que mms.btl lee un archivo pero sólo para desplegar su c,::,ntenido; para ejecutarlo puede
teclearse la siguiente linea en el prompt de DOS si se han establ•!Cido las variables de ambiente
para C.
Al ejecutarse, el programa muestra el contenido del archivo de comandos en una pantalla parecida
a:
15 APÉNDICE G
SECUENCIA.EXE
Como se mencionó en el punto 6 .1. 1. 3, los procesos comunicantes envían al proceso monitor los
mensajes que han recibido para que este a su vez los imprima en la pantalla para proporcionar una
visión del intercambio de mensajes generado. Esta salida se puede a.preciar en el Apéndice F.
Este aplicación fue desarrollada en Visual Basic 5 y consta de una sola interfaz gráfica, la cual
se muestra en la Figura 67.
•• Socuenciaa •IMS
987 ,O,LOGIN~Request,O ,O
Client \
"-,
(B)
(A)
917'º·~--
qu-es1
_._
~º·º_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _...:::_:----' Cmmspm li
0,987,LúGINJndication,O,O ( C)
l' - - - -
1~~~~~-~~~---------~--- - - - - - ~ Smmspm
!
15<16,11,LOGIN_Request,O ,O
1~----~----------------------~- Server
La aplicación simplemente lee el archivo de valores separados por coma que genera la aplicación
mms.btl y va mostrando en forma gráfica como se fueron generando ee;tos mensajes; el usuario puede
controlar la ejecución de la secuencia según se requiera.
La ventana de la aplicación muestra cuatro lineas verdes horizontales (A) que representan los
cuatro procesos principales involucrados en el protocolo mms: cli ent, cmmspm, smmspm y server;
una línea vertical (B) que marca la posición actual en el tiempo (eje horizontal) y los mensajes
que se van generando (C). Así mismo, se presenta una barra simple de herramientas, que contiene
los botones siguientes:
Cargar. - (D) Este botón sirve para que la aplicación cargue los datos a memoria del archivo
generado por la aplicación mms. Este archivo tiene el nombre outpi;.t. csv y debe estar en la ruta
donde esta ejecutándose la aplicación Secuencia.
Paso a paso.- (F) Botón para ejecutar la secuencia paso a paso. Se pueden alternar este botón con
el botón Ejecutar para situarse en el "tiempo" en el que se quiera hacer un análisis más
detallado.
Option Explicit
Dim fi_offset(S) As Integer
Dim fi nivelneg(S) As Integer
Dim fi=nivelpos(S) As Integer
Dim fi_gap As Integer
Dim fi_gapTime As Integer
Dim FI_HASTA As Integer
Dim FI_DESDE As Integer
Dim FI PID As Integer
Dim FI_RPID As Integer
Dim FI_PRIMITIVA As Integer
Dim FI_AS As Integer
Dim FI_RAS As Integer
Dim fi_IdSec As Integer
Dim FI MAXITEMS As Integer
Dim FI_WIDTHOFF As Integer
Dim FI lstShowitem As Integer
Dim FI_LastShowitem As Integer
Dim fi_rowpinta As Integer
Dim fi LastX As Integer
Me.BackColor = QBColor(O)
FI MAXITEMS = 3
FI HASTA O
FI_DESDE = 1
FI PID = 2
FI RPID = 3
FI PRIMITIVA 4
FI AS= 5
FI RAS = 6
FI WIDTHOFF = 200
fi_gap = Labell(O) .Height • 0.7
fi_gapTime = 200
Linel(O) .Visible= False
For li counter = 1 To 4
Linel (li counter). Visible True
Next l i counter
For li Hasta= o To 4
fi=offset(li_Hasta) Linel(li_Hasta} .Yl
Next li_Hasta
End Sub
fi IdSee o
Line2.Xl FI WIDTHOFF + pie_In(O) .Width
240
Line2.X2 = Line2.Xl
fi_rowpinta = O
fi LastX = FI WIDTHOFF
grd SecTmp.Cols = FI RAS+ 1
grd=SecTmp.Rows = 2 -
r_LimpiaGrid grd_SecTmp
grd_SecTmp.Rows = 1
li i = o
Open ls_Archivo For Input As #1
Do While Not EOF(l) ' Repite el bucle hasta el final del archivo.
Input #1, fs Hasta, fl Desde, fs Pid, fs_rPid, fs_Primitiva, fs_As, fs_rAs
If li_i > grd_SecTmp.Rows - 1 Then
grd_SecTmp.Rows grd_SecTmp.Rows + 1
End If
grd SecTmp.Row = li i
grd=SecTmp.col = FI=HASTA
grd SecTmp.Text = fs Hasta
grd=SecTmp.col = FI_DESDE
grd SecTmp.Text = fl Desde
grd-SecTmp.col = FI PID
grd-SecTmp.Text = fe Pid
grd=SecTmp.col,. FI_RPID
grd_SecTmp.Text = fs_rPid
grd SecTmp.col = FI PRIMITIVA
grd=SecTmp.Text = fs_Primitiva
grd_SecTmp.col = FI_AS
grd SecTmp.Text = fs As
grd=SecTmp.col = FI_RAS
grd SecTmp.Text., fs rAs
If li_i >= pic_In.Count - 1 Then
MsgBox "No serán Mostados todos los mensajes, El número es mayor al permitido por
esta aplicación", vbExclamation, Me.Caption
Exit Do
End If
lii=lii+l
Loop
Close #1 'Termino Ok la lectura
Screen.MousePointer = vbDefault
Exit Sub
ErrorCarga:
Select Case Err
Case 57
MsgBox "Disquette dañado o sin formatear", vbCritical + vbOK(lnly, Me.Caption
Case 70
MsgBox "Acceso Denegado", vbCritical + vbOKOnly, Me.Caption
Case 71
MsgBox "Inserte el disquette", vbCritical + vbOKOnly, Me.Capt:ion
Case 53
fi IdSec o
Line2.Xl FI WIDTHOFF + pic_In(O) .Width
Line2.X2 Line2.Xl
fi_rowpinta = O
fi LastX = FI_WIDTHOFF
grd_SecTmp.Cols = FI_RAS + 1
grd_SecTmp.Rows = 2
r_LimpiaGrid grd_SecTmp
For li Row = O To 10 'Datal.Recordset.RecordCount
li PseudoRow = li Row Mod 5 '(grd sec.VisibleRows - 1)
If-li Row Mod 5 Then '(grd sec.VisibleRows - 1)) = O And li Row > O Then
'grd_sec.Scroll o, grd=sec.VisibleRows - 1
End If
If li_Row > grd_SecTmp.Row - 1 Then
grd_SecTmp.Rows = grd_SecTmp.Rows + 1
End If
grd_SecTmp.Row = li_Row
For MyCol = o To grd_SecTmp.Cols - 1
grd_SecTmp.col = MyCol
grd_SecTmp.Text = "" 'grd_sec.Text
If grd_SecTmp.col = FI_DESDE Then
If grd_SecTmp.Text = "-1" Then
Exit For
End I f
End If
Next MyCol
If li_Row >= pie In.Count - 1 Then
MsgBox "No serán Mostados todos los mensajes, El número es mayor al permitido por
esta aplicación", vbExclamation, Me.Caption
Exit For
End I f
Next li_Row
End Sub